From 62d6e91d243921959981394f2e51e279899782de Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Mon, 3 Aug 2009 09:42:11 +0000 Subject: [PATCH 0001/2592] Note when RELENG_8 branch was created. Approved by: re (implicit) --- UPDATING | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UPDATING b/UPDATING index add10f3a78b..02369b0290a 100644 --- a/UPDATING +++ b/UPDATING @@ -22,6 +22,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW: to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20090803: + RELENG_8 branched. + 20090719: Bump the shared library version numbers for all libraries that do not use symbol versioning as part of the 8.0-RELEASE cycle. From e380e5cfc8b0dc54220c57ad5ef6a3112f8e6c40 Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Wed, 12 Aug 2009 07:08:14 +0000 Subject: [PATCH 0002/2592] Adjust 'make update' to use RELENG_8 branch tag for cvs. Approved by: re (implicit) --- Makefile.inc1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index d05b004d652..eaf5b5728c4 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -93,7 +93,7 @@ CLEANDIR= cleandir .endif CVS?= cvs -CVSFLAGS?= -A -P -d -I! +CVSFLAGS?= -r RELENG_8 -P -d -I! SVN?= svn SVNFLAGS?= -r HEAD SUP?= /usr/bin/csup From b3431b4096e8489f080bd747d85a61875259a1e0 Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Wed, 12 Aug 2009 07:22:12 +0000 Subject: [PATCH 0003/2592] Adjust for RELENG_8. Approved by: re (implicit) --- release/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/Makefile b/release/Makefile index 22f250af064..bb21dbe37b5 100644 --- a/release/Makefile +++ b/release/Makefile @@ -18,7 +18,7 @@ # Set these, release builder! # # Fixed version: -#BUILDNAME=8.0-CURRENT +#BUILDNAME=8.0-STABLE # # Automatic SNAP versioning: DATE != date +%Y%m%d @@ -27,7 +27,7 @@ BUILDNAME?=${BASE}-${DATE}-SNAP # #CHROOTDIR=/junk/release # If this is a -stable snapshot, then set -#RELEASETAG=RELENG_7 +#RELEASETAG=RELENG_8 # # To test a release with a source tree containing patches and # other work. This tree will get copied instead of getting the From 51f8953fbe3266df58446ae0bcfec71006b96881 Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Wed, 12 Aug 2009 07:25:56 +0000 Subject: [PATCH 0004/2592] Update for RELENG_8. Approved by: re (implicit) --- share/examples/cvsup/standard-supfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/examples/cvsup/standard-supfile b/share/examples/cvsup/standard-supfile index 5eb59683394..b60503b0f78 100644 --- a/share/examples/cvsup/standard-supfile +++ b/share/examples/cvsup/standard-supfile @@ -49,7 +49,7 @@ *default host=CHANGE_THIS.FreeBSD.org *default base=/var/db *default prefix=/usr -*default release=cvs tag=. +*default release=cvs tag=RELENG_8 *default delete use-rel-suffix # If you seem to be limited by CPU rather than network or disk bandwidth, try From 357327a0c2948e3c2c59dc159003a00b99d8ffab Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Wed, 12 Aug 2009 07:37:18 +0000 Subject: [PATCH 0005/2592] Prepare for 8.0 package set, adjust for 8-stable, acknowledge 9-current is coming. Approved by: re (implicit) --- usr.sbin/pkg_install/add/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/usr.sbin/pkg_install/add/main.c b/usr.sbin/pkg_install/add/main.c index b2d511ebc7b..eaed0c0c2eb 100644 --- a/usr.sbin/pkg_install/add/main.c +++ b/usr.sbin/pkg_install/add/main.c @@ -82,13 +82,15 @@ struct { { 700000, 700099, "/packages-7.0-release" }, { 701000, 701099, "/packages-7.1-release" }, { 702000, 702099, "/packages-7.2-release" }, + { 800000, 800499, "/packages-8.0-release" }, { 300000, 399000, "/packages-3-stable" }, { 400000, 499000, "/packages-4-stable" }, { 502100, 502128, "/packages-5-current" }, { 503100, 599000, "/packages-5-stable" }, { 600100, 699000, "/packages-6-stable" }, { 700100, 799000, "/packages-7-stable" }, - { 800000, 899000, "/packages-8-current" }, + { 800500, 899000, "/packages-8-stable" }, + { 900000, 999000, "/packages-9-current" }, { 0, 9999999, "/packages-current" }, { 0, 0, NULL } }; From 28a2b3dd5777f9a14f877e0a5050889d8f590cf3 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 12 Aug 2009 10:32:20 +0000 Subject: [PATCH 0006/2592] MFC r196118: Put minimum alignment on the dpcpu and vnet section so that ld when adding the __start_ symbol knows the expected section alignment and can place the __start_ symbol correctly. These sections will not support symbols with super-cache line alignment requirements. For full details, see posting to freebsd-current, 2009-08-10, Message-ID: <20090810133111.C93661@maildrop.int.zabbadoz.net>. Debugging and testing patches by: Kamigishi Rei (spambox haruhiism.net), np, lstewart, jhb, kib, rwatson Tested by: Kamigishi Rei, lstewart Reviewed by: kib Approved by: re --- sys/net/vnet.h | 8 +++++--- sys/sys/pcpu.h | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/sys/net/vnet.h b/sys/net/vnet.h index 01d824d68b2..d441af19970 100644 --- a/sys/net/vnet.h +++ b/sys/net/vnet.h @@ -185,12 +185,14 @@ extern struct sx vnet_sxlock; * Virtual network stack memory allocator, which allows global variables to * be automatically instantiated for each network stack instance. */ +__asm__( #if defined(__arm__) -__asm__(".section " VNET_SETNAME ", \"aw\", %progbits"); + ".section " VNET_SETNAME ", \"aw\", %progbits\n" #else -__asm__(".section " VNET_SETNAME ", \"aw\", @progbits"); + ".section " VNET_SETNAME ", \"aw\", @progbits\n" #endif -__asm__(".previous"); + "\t.p2align " __XSTRING(CACHE_LINE_SHIFT) "\n" + "\t.previous"); #define VNET_NAME(n) vnet_entry_##n #define VNET_DECLARE(t, n) extern t VNET_NAME(n) diff --git a/sys/sys/pcpu.h b/sys/sys/pcpu.h index 8c0e0d55a95..ae6cc0953ba 100644 --- a/sys/sys/pcpu.h +++ b/sys/sys/pcpu.h @@ -56,12 +56,14 @@ struct thread; extern uintptr_t *__start_set_pcpu; extern uintptr_t *__stop_set_pcpu; +__asm__( #if defined(__arm__) -__asm__(".section set_pcpu, \"aw\", %progbits"); + ".section set_pcpu, \"aw\", %progbits\n" #else -__asm__(".section set_pcpu, \"aw\", @progbits"); + ".section set_pcpu, \"aw\", @progbits\n" #endif -__asm__(".previous"); + "\t.p2align " __XSTRING(CACHE_LINE_SHIFT) "\n" + "\t.previous"); /* * Array of dynamic pcpu base offsets. Indexed by id. From 6bf0cb8a7922c33a5a9a3496964b4fb6ca97b6ba Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Wed, 12 Aug 2009 12:00:22 +0000 Subject: [PATCH 0007/2592] Merge r196128 to stable/8. Approved by: re (rwatson) --- usr.sbin/ntp/scripts/mkver | 2 -- 1 file changed, 2 deletions(-) diff --git a/usr.sbin/ntp/scripts/mkver b/usr.sbin/ntp/scripts/mkver index 02c692491f3..a8f51752b60 100755 --- a/usr.sbin/ntp/scripts/mkver +++ b/usr.sbin/ntp/scripts/mkver @@ -23,8 +23,6 @@ case "" in *) ConfStr="${ConfStr}-r" ;; esac -ConfStr="$ConfStr `LC_ALL=C date`" - if [ ! -f .version ]; then echo 0 > .version fi From 3baf84f5872cfcc467f1799e6fca680decc7cf06 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 12 Aug 2009 12:05:07 +0000 Subject: [PATCH 0008/2592] MFC r196129: Update DDB show vnet command to print all used and available information. Reviewed by: rwatson, zec Approved by: re --- sys/net/vnet.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/sys/net/vnet.c b/sys/net/vnet.c index 7866bb98c90..17bcbc6fb51 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -615,14 +615,20 @@ DB_SHOW_COMMAND(vnets, db_show_vnets) { VNET_ITERATOR_DECL(vnet_iter); -#if SIZE_MAX == UINT32_MAX /* 32-bit arch */ - db_printf(" vnet ifs socks\n"); -#else /* 64-bit arch, most probaly... */ - db_printf(" vnet ifs socks\n"); -#endif VNET_FOREACH(vnet_iter) { - db_printf("%p %3d %5d\n", vnet_iter, vnet_iter->vnet_ifcnt, - vnet_iter->vnet_sockcnt); + db_printf("vnet = %p\n", vnet_iter); + db_printf(" vnet_magic_n = 0x%x (%s, orig 0x%x)\n", + vnet_iter->vnet_magic_n, + (vnet_iter->vnet_magic_n == VNET_MAGIC_N) ? + "ok" : "mismatch", VNET_MAGIC_N); + db_printf(" vnet_ifcnt = %u\n", vnet_iter->vnet_ifcnt); + db_printf(" vnet_sockcnt = %u\n", vnet_iter->vnet_sockcnt); + db_printf(" vnet_data_mem = %p\n", vnet_iter->vnet_data_mem); + db_printf(" vnet_data_base = 0x%jx\n", + (uintmax_t)vnet_iter->vnet_data_base); + db_printf("\n"); + if (db_pager_quit) + break; } } #endif From 537791e5846f0918498d4629ed47f2131b2ab1ee Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 12 Aug 2009 12:10:28 +0000 Subject: [PATCH 0009/2592] MFC r196132: Add ddb show dpcpu_off command to ease dpcpu memory debugging. While show pcpu prints pc_dynamic this also prints the original memory address as well as the maths. Once dpcpu goes NUMA this is considered to help debugging as well. Reviewed by: rwatson Approved by: re --- sys/kern/subr_pcpu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sys/kern/subr_pcpu.c b/sys/kern/subr_pcpu.c index c0372b0e12c..5610980eef6 100644 --- a/sys/kern/subr_pcpu.c +++ b/sys/kern/subr_pcpu.c @@ -313,6 +313,18 @@ sysctl_dpcpu_int(SYSCTL_HANDLER_ARGS) } #ifdef DDB +DB_SHOW_COMMAND(dpcpu_off, db_show_dpcpu_off) +{ + int id; + + for (id = 0; id <= mp_maxid; id++) { + if (CPU_ABSENT(id)) + continue; + db_printf("dpcpu_off[%2d] = 0x%jx (+ DPCPU_START = %p)\n", + id, (uintmax_t)dpcpu_off[id], + (void *)(uintptr_t)(dpcpu_off[id] + DPCPU_START)); + } +} static void show_pcpu(struct pcpu *pc) From abff5b8ad900af57835ae8c0e0639bea7d6e3613 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 12 Aug 2009 12:14:30 +0000 Subject: [PATCH 0010/2592] MFC r196135: Make the kernel compile without IP networking by moving a variable under a proper #ifdef. Approved by: re (rwatson) --- sys/kern/kern_jail.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index cf5dfd8b856..282a4d8c95b 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -472,10 +472,11 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) #endif struct vfsopt *opt; struct vfsoptlist *opts; - struct prison *pr, *deadpr, *mypr, *ppr, *tpr, *tppr; + struct prison *pr, *deadpr, *mypr, *ppr, *tpr; struct vnode *root; char *domain, *errmsg, *host, *name, *p, *path, *uuid; #if defined(INET) || defined(INET6) + struct prison *tppr; void *op; #endif unsigned long hid; From 290d3c9f726f004c0fec57c743398a8d0326b39a Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 12 Aug 2009 12:31:29 +0000 Subject: [PATCH 0011/2592] MFC r196137: Do not truncate IPv6 addresses when printing them in the jls -av 7.x multi-IP jail backward compat output. Reported by: ed Tested by: ed Reviewed by: rwatson Approved by: re --- usr.sbin/jls/jls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/jls/jls.c b/usr.sbin/jls/jls.c index 8c8b981d82f..0661ee3fa43 100644 --- a/usr.sbin/jls/jls.c +++ b/usr.sbin/jls/jls.c @@ -359,7 +359,7 @@ print_jail(int pflags, int jflags) ipbuf, sizeof(ipbuf)) == NULL) err(1, "inet_ntop"); else - printf("%6s %-15.15s\n", "", ipbuf); + printf("%6s %s\n", "", ipbuf); } } else if (pflags & PRINT_DEFAULT) printf("%6d %-15.15s %-29.29s %.74s\n", From 0f2cac6379041a8e9178d5802ddf962b209a7106 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Wed, 12 Aug 2009 13:09:24 +0000 Subject: [PATCH 0012/2592] Merge r196141 Add some additional radeon pci ids to drm. Approved by: re (kib) --- sys/dev/drm/drm_pciids.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/dev/drm/drm_pciids.h b/sys/dev/drm/drm_pciids.h index 4562e5f722e..a10469ade08 100644 --- a/sys/dev/drm/drm_pciids.h +++ b/sys/dev/drm/drm_pciids.h @@ -259,9 +259,12 @@ {0x1002, 0x940F, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V7600"}, \ {0x1002, 0x94A0, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4830"}, \ {0x1002, 0x94A1, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4850"}, \ + {0x1002, 0x94A3, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M7740"}, \ {0x1002, 0x94B1, CHIP_RV740|RADEON_NEW_MEMMAP, "ATI RV740"}, \ {0x1002, 0x94B3, CHIP_RV740|RADEON_NEW_MEMMAP, "ATI Radeon HD 4770"}, \ + {0x1002, 0x94B4, CHIP_RV740|RADEON_NEW_MEMMAP, "ATI Radeon HD 4700 Series"}, \ {0x1002, 0x94B5, CHIP_RV740|RADEON_NEW_MEMMAP, "ATI Radeon HD 4770"}, \ + {0x1002, 0x94B9, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M5750"}, \ {0x1002, 0x94C0, CHIP_RV610|RADEON_NEW_MEMMAP, "RV610"}, \ {0x1002, 0x94C1, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 XT"}, \ {0x1002, 0x94C3, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 Pro"}, \ @@ -350,6 +353,7 @@ {0x1002, 0x9487, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon RV730 (AGP)"}, \ {0x1002, 0x948F, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon RV730 (AGP)"}, \ {0x1002, 0x9490, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4670"}, \ + {0x1002, 0x9495, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4600 Series"}, \ {0x1002, 0x9498, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4650"}, \ {0x1002, 0x9480, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4650"}, \ {0x1002, 0x9488, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4670"}, \ @@ -366,6 +370,7 @@ {0x1002, 0x9552, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4300 Series"}, \ {0x1002, 0x9553, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4500 Series"}, \ {0x1002, 0x9555, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4500 Series"}, \ + {0x1002, 0x9557, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro RG220"}, \ {0, 0, 0, NULL} #define r128_PCI_IDS \ From b7f930cb48008d407455c734f0480023ba667482 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Wed, 12 Aug 2009 13:12:09 +0000 Subject: [PATCH 0013/2592] Merge r196142 Add support for radeon RS880 IGP chips to drm. Approved by: re (kib) --- sys/dev/drm/drm_pciids.h | 5 +++++ sys/dev/drm/r600_cp.c | 18 +++++++++++++----- sys/dev/drm/radeon_drv.h | 1 + 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/sys/dev/drm/drm_pciids.h b/sys/dev/drm/drm_pciids.h index a10469ade08..3b2347ed5b6 100644 --- a/sys/dev/drm/drm_pciids.h +++ b/sys/dev/drm/drm_pciids.h @@ -330,6 +330,11 @@ {0x1002, 0x9614, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3300 Graphics"}, \ {0x1002, 0x9615, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3200 Graphics"}, \ {0x1002, 0x9616, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3000 Graphics"}, \ + {0x1002, 0x9710, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon HD 4200"}, \ + {0x1002, 0x9711, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 4100"}, \ + {0x1002, 0x9712, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Mobility Radeon HD 4200"}, \ + {0x1002, 0x9713, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Mobility Radeon 4100"}, \ + {0x1002, 0x9714, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI RS880"}, \ {0x1002, 0x9440, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ {0x1002, 0x9441, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4870 X2"}, \ {0x1002, 0x9442, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ diff --git a/sys/dev/drm/r600_cp.c b/sys/dev/drm/r600_cp.c index 64e98ce41e6..8c33eb6f483 100644 --- a/sys/dev/drm/r600_cp.c +++ b/sys/dev/drm/r600_cp.c @@ -318,7 +318,8 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) pfp = RV670_pfp_microcode; break; case CHIP_RS780: - DRM_INFO("Loading RS780 Microcode\n"); + case CHIP_RS880: + DRM_INFO("Loading RS780/RS880 Microcode\n"); cp = RS780_cp_microcode; pfp = RS780_pfp_microcode; break; @@ -722,6 +723,7 @@ static void r600_gfx_init(struct drm_device *dev, break; case CHIP_RV610: case CHIP_RS780: + case CHIP_RS880: case CHIP_RV620: dev_priv->r600_max_pipes = 1; dev_priv->r600_max_tile_pipes = 1; @@ -856,7 +858,8 @@ static void r600_gfx_init(struct drm_device *dev, ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || ((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_RS780) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE); else RADEON_WRITE(R600_DB_DEBUG, 0); @@ -874,7 +877,8 @@ static void r600_gfx_init(struct drm_device *dev, sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES); 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_RS780) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) | R600_FETCH_FIFO_HIWATER(0xa) | R600_DONE_FIFO_HIWATER(0xe0) | @@ -917,7 +921,8 @@ static void r600_gfx_init(struct drm_device *dev, R600_NUM_ES_STACK_ENTRIES(0)); } else 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_RS780) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { /* no vertex cache */ sq_config &= ~R600_VC_ENABLE; @@ -974,7 +979,8 @@ static void r600_gfx_init(struct drm_device *dev, 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_RS780) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY)); else RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC)); @@ -1017,6 +1023,7 @@ static void r600_gfx_init(struct drm_device *dev, break; case CHIP_RV610: case CHIP_RS780: + case CHIP_RS880: case CHIP_RV620: gs_prim_buffer_depth = 32; break; @@ -1062,6 +1069,7 @@ static void r600_gfx_init(struct drm_device *dev, switch (dev_priv->flags & RADEON_FAMILY_MASK) { case CHIP_RV610: case CHIP_RS780: + case CHIP_RS880: case CHIP_RV620: tc_cntl = R600_TC_L2_SIZE(8); break; diff --git a/sys/dev/drm/radeon_drv.h b/sys/dev/drm/radeon_drv.h index ae1166f023b..5914b13b5dd 100644 --- a/sys/dev/drm/radeon_drv.h +++ b/sys/dev/drm/radeon_drv.h @@ -145,6 +145,7 @@ enum radeon_family { CHIP_RV635, CHIP_RV670, CHIP_RS780, + CHIP_RS880, CHIP_RV770, CHIP_RV740, CHIP_RV730, From badf1a61b37ea7f8bc2d04a6eb4daeb778e910a9 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 12 Aug 2009 14:40:21 +0000 Subject: [PATCH 0014/2592] MFC 196147: Fix references to the kernel distributions to use the correct names (uppercase). Approved by: re (rwatson, kib) --- usr.sbin/sysinstall/install.c | 2 +- usr.sbin/sysinstall/sysinstall.8 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c index d00da3c8d4f..a2979c900b0 100644 --- a/usr.sbin/sysinstall/install.c +++ b/usr.sbin/sysinstall/install.c @@ -939,7 +939,7 @@ installFixupKernel(dialogMenuItem *self, int dists) if (RunningAsInit) { /* * Install something as /boot/kernel. Prefer SMP - * over generic--this should handle the case where + * over GENERIC--this should handle the case where * both SMP and GENERIC are installed (otherwise we * select the one kernel that was installed). * diff --git a/usr.sbin/sysinstall/sysinstall.8 b/usr.sbin/sysinstall/sysinstall.8 index 7cb55aa3808..46a14fc8d9c 100644 --- a/usr.sbin/sysinstall/sysinstall.8 +++ b/usr.sbin/sysinstall/sysinstall.8 @@ -411,9 +411,9 @@ Possible distribution values are: .Bl -tag -width indentxx .It Li base The base binary distribution. -.It Li generic +.It Li GENERIC The GENERIC kernel. -.It Li smp +.It Li SMP A kernel suitable for multiple processor systems. .It Li doc Miscellaneous documentation From 3eced0dd19dc0649b69bb65292226d426afd5e01 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 12 Aug 2009 17:45:55 +0000 Subject: [PATCH 0015/2592] MFC: r196150 Always embed pointer to BPF JIT function in BPF descriptor to avoid inconsistency when opt_bpf.h is not included. Reviewed by: rwatson Approved by: re (rwatson) --- sys/net/bpf.c | 18 ++++++++++++------ sys/net/bpf_buffer.c | 1 - sys/net/bpf_zerocopy.c | 1 - sys/net/bpfdesc.h | 4 +--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 08c9a5eee26..9656a6e7b3d 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -1585,6 +1585,9 @@ void bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen) { struct bpf_d *d; +#ifdef BPF_JITTER + bpf_jit_filter *bf; +#endif u_int slen; int gottime; struct timeval tv; @@ -1601,8 +1604,9 @@ bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen) * the interface pointers on the mbuf to figure it out. */ #ifdef BPF_JITTER - if (bpf_jitter_enable != 0 && d->bd_bfilter != NULL) - slen = (*(d->bd_bfilter->func))(pkt, pktlen, pktlen); + bf = bpf_jitter_enable != 0 ? d->bd_bfilter : NULL; + if (bf != NULL) + slen = (*(bf->func))(pkt, pktlen, pktlen); else #endif slen = bpf_filter(d->bd_rfilter, pkt, pktlen, pktlen); @@ -1634,6 +1638,9 @@ void bpf_mtap(struct bpf_if *bp, struct mbuf *m) { struct bpf_d *d; +#ifdef BPF_JITTER + bpf_jit_filter *bf; +#endif u_int pktlen, slen; int gottime; struct timeval tv; @@ -1655,11 +1662,10 @@ bpf_mtap(struct bpf_if *bp, struct mbuf *m) BPFD_LOCK(d); ++d->bd_rcount; #ifdef BPF_JITTER + bf = bpf_jitter_enable != 0 ? d->bd_bfilter : NULL; /* XXX We cannot handle multiple mbufs. */ - if (bpf_jitter_enable != 0 && d->bd_bfilter != NULL && - m->m_next == NULL) - slen = (*(d->bd_bfilter->func))(mtod(m, u_char *), - pktlen, pktlen); + if (bf != NULL && m->m_next == NULL) + slen = (*(bf->func))(mtod(m, u_char *), pktlen, pktlen); else #endif slen = bpf_filter(d->bd_rfilter, (u_char *)m, pktlen, 0); diff --git a/sys/net/bpf_buffer.c b/sys/net/bpf_buffer.c index 5f740b31fc3..8924c8841fc 100644 --- a/sys/net/bpf_buffer.c +++ b/sys/net/bpf_buffer.c @@ -77,7 +77,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include /* diff --git a/sys/net/bpf_zerocopy.c b/sys/net/bpf_zerocopy.c index 35b27b9c02c..a1dd923a4f5 100644 --- a/sys/net/bpf_zerocopy.c +++ b/sys/net/bpf_zerocopy.c @@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include diff --git a/sys/net/bpfdesc.h b/sys/net/bpfdesc.h index 2ff3d5e9216..5784763ed8a 100644 --- a/sys/net/bpfdesc.h +++ b/sys/net/bpfdesc.h @@ -72,9 +72,7 @@ struct bpf_d { u_long bd_rtout; /* Read timeout in 'ticks' */ struct bpf_insn *bd_rfilter; /* read filter code */ struct bpf_insn *bd_wfilter; /* write filter code */ -#ifdef BPF_JITTER - bpf_jit_filter *bd_bfilter; /* binary filter code */ -#endif + void *bd_bfilter; /* binary filter code */ u_int64_t bd_rcount; /* number of packets received */ u_int64_t bd_dcount; /* number of packets dropped */ From e9200ba65bd52cfb4ab856d56f2d393246ef82a8 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 12 Aug 2009 20:30:27 +0000 Subject: [PATCH 0016/2592] MFC r196149: Add a check for a NULL mbuf ptr at the beginning of xdrmbuf_inline() so that it returns failure instead of crashing when "m->m_len" is executed and m == NULL. The mbuf ptr can be NULL when a call to xdrmbuf_getbytes() gets the bytes it needs, but they are at the end of a short RPC reply. When this happens, xdrmbuf_getbytes() returns success, but advances the mbuf ptr (xdrs->x_private) to m_next, which is NULL. If this is followed by a call to xdrmbuf_getlong(), it calls xdrmbuf_inline(), which would cause a crash by accessing "m->m_len". Approved by: re (rwatson), kib (mentor) --- sys/xdr/xdr_mbuf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/xdr/xdr_mbuf.c b/sys/xdr/xdr_mbuf.c index ab79e19e29a..bcfdb1866c0 100644 --- a/sys/xdr/xdr_mbuf.c +++ b/sys/xdr/xdr_mbuf.c @@ -282,6 +282,8 @@ xdrmbuf_inline(XDR *xdrs, u_int len) size_t available; char *p; + if (!m) + return (0); if (xdrs->x_op == XDR_ENCODE) { available = M_TRAILINGSPACE(m) + (m->m_len - xdrs->x_handy); } else { From 747a32aaea78af983942041d3b893f44e3017ce2 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Wed, 12 Aug 2009 20:48:50 +0000 Subject: [PATCH 0017/2592] MFC r196152 A piece of code was added to install a host route when an IPv6 interface address is configured with a /128 prefix. This is no longer necessary due to r192011. In fact that code conflicts with r192011. This patch removes the host route installation when detecting the /128 prefix, and instead let the code added by r192011 to install the loopback route for that IPv6 interface address. Approved by: re --- sys/netinet6/in6.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index c099da70e89..c4333ed60a6 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1750,21 +1750,12 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, * interface that share the same destination. */ plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */ - if (!(ia->ia_flags & IFA_ROUTE) && plen == 128) { - struct sockaddr *dstaddr; + if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 && + ia->ia_dstaddr.sin6_family == AF_INET6) { int rtflags = RTF_UP | RTF_HOST; - /* - * use the interface address if configuring an - * interface address with a /128 prefix len - */ - if (ia->ia_dstaddr.sin6_family == AF_INET6) - dstaddr = (struct sockaddr *)&ia->ia_dstaddr; - else - dstaddr = (struct sockaddr *)&ia->ia_addr; - error = rtrequest(RTM_ADD, - (struct sockaddr *)dstaddr, + (struct sockaddr *)&ia->ia_dstaddr, (struct sockaddr *)&ia->ia_addr, (struct sockaddr *)&ia->ia_prefixmask, ia->ia_flags | rtflags, NULL); From 49b62b28b27278eee1b7e34287cb8798b63d51f9 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 12 Aug 2009 21:06:37 +0000 Subject: [PATCH 0018/2592] MFC 196155: First (early) draft of net80211 documentation. Note this is focused on driver writers (as opposed to folks adding to net80211). Reviewed by: wkoszek Approved by: re (rwatson) --- share/man/man9/Makefile | 106 ++-- share/man/man9/ieee80211.9 | 731 +++++++++++++++++++-------- share/man/man9/ieee80211_amrr.9 | 194 +++++++ share/man/man9/ieee80211_beacon.9 | 115 +++++ share/man/man9/ieee80211_bmiss.9 | 91 ++++ share/man/man9/ieee80211_crypto.9 | 277 +++++++--- share/man/man9/ieee80211_ddb.9 | 72 +++ share/man/man9/ieee80211_input.9 | 135 ++--- share/man/man9/ieee80211_ioctl.9 | 92 ---- share/man/man9/ieee80211_node.9 | 452 ++++++++--------- share/man/man9/ieee80211_output.9 | 255 ++++++---- share/man/man9/ieee80211_proto.9 | 228 +++++++-- share/man/man9/ieee80211_radiotap.9 | 356 +++++++------ share/man/man9/ieee80211_regdomain.9 | 143 ++++++ share/man/man9/ieee80211_scan.9 | 350 +++++++++++++ share/man/man9/ieee80211_vap.9 | 154 ++++++ 16 files changed, 2746 insertions(+), 1005 deletions(-) create mode 100644 share/man/man9/ieee80211_amrr.9 create mode 100644 share/man/man9/ieee80211_beacon.9 create mode 100644 share/man/man9/ieee80211_bmiss.9 create mode 100644 share/man/man9/ieee80211_ddb.9 delete mode 100644 share/man/man9/ieee80211_ioctl.9 create mode 100644 share/man/man9/ieee80211_regdomain.9 create mode 100644 share/man/man9/ieee80211_scan.9 create mode 100644 share/man/man9/ieee80211_vap.9 diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 844e117eddc..3148d5eed1c 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -121,13 +121,19 @@ MAN= accept_filter.9 \ hashinit.9 \ hexdump.9 \ ieee80211.9 \ + ieee80211_amrr.9 \ + ieee80211_beacon.9 \ + ieee80211_bmiss.9 \ ieee80211_crypto.9 \ + ieee80211_ddb.9 \ ieee80211_input.9 \ - ieee80211_ioctl.9 \ ieee80211_node.9 \ ieee80211_output.9 \ ieee80211_proto.9 \ ieee80211_radiotap.9 \ + ieee80211_regdomain.9 \ + ieee80211_scan.9 \ + ieee80211_vap.9 \ ifnet.9 \ inittodr.9 \ insmntque.9 \ @@ -627,52 +633,62 @@ MLINKS+=hash.9 hash32.9 \ MLINKS+=hashinit.9 hashdestroy.9 \ hashinit.9 hashinit_flags.9 \ hashinit.9 phashinit.9 -MLINKS+=ieee80211.9 ieee80211_attach.9 \ - ieee80211.9 ieee80211_chan2ieee.9 \ - ieee80211.9 ieee80211_chan2mode.9 \ - ieee80211.9 ieee80211_ieee2mhz.9 \ - ieee80211.9 ieee80211_ifattach.9 \ - ieee80211.9 ieee80211_ifdetach.9 \ - ieee80211.9 ieee80211_media2rate.9 \ - ieee80211.9 ieee80211_media_change.9 \ - ieee80211.9 ieee80211_media_init.9 \ - ieee80211.9 ieee80211_media_status.9 \ - ieee80211.9 ieee80211_mhz2ieee.9 \ - ieee80211.9 ieee80211_rate2media.9 \ - ieee80211.9 ieee80211_setmode.9 \ - ieee80211.9 ieee80211_watchdog.9 -MLINKS+=ieee80211_crypto.9 ieee80211_crypto_attach.9 \ - ieee80211_crypto.9 ieee80211_crypto_detach.9 \ - ieee80211_crypto.9 ieee80211_wep_crypt.9 -MLINKS+=ieee80211_input.9 ieee80211_decap.9 \ - ieee80211_input.9 ieee80211_recv_mgmt.9 -MLINKS+=ieee80211_ioctl.9 ieee80211_cfgget.9 \ - ieee80211_ioctl.9 ieee80211_cfgset.9 -MLINKS+=ieee80211_node.9 ieee80211_alloc_node.9 \ - ieee80211_node.9 ieee80211_begin_scan.9 \ - ieee80211_node.9 ieee80211_create_ibss.9 \ - ieee80211_node.9 ieee80211_dup_bss.9 \ - ieee80211_node.9 ieee80211_end_scan.9 \ - ieee80211_node.9 ieee80211_find_node.9 \ - ieee80211_node.9 ieee80211_free_allnodes.9 \ +MLINKS+=ieee80211.9 ieee80211_ifattach.9 \ + ieee80211.9 ieee80211_ifdetach.9 +MLINKS+=ieee80211_amrr.9 ieee80211_amrr_init.9 \ + ieee80211_amrr.9 ieee80211_amrr_cleanup.9 \ + ieee80211_amrr.9 ieee80211_amrr_setinterval.9 \ + ieee80211_amrr.9 ieee80211_amrr_node_init.9 \ + ieee80211_amrr.9 ieee80211_amrr_tx_complete.9 \ + ieee80211_amrr.9 ieee80211_amrr_tx_update.9 +MLINKS+=ieee80211_beacon.9 ieee80211_beacon_alloc.9 \ + ieee80211_beacon.9 ieee80211_beacon_update.9 \ + ieee80211_beacon.9 ieee80211_beacon_notify.9 +MLINKS+=ieee80211_bmiss.9 ieee80211_beacon_miss.9 +MLINKS+=ieee80211_crypto.9 ieee80211_key_update_begin.9 \ + ieee80211_crypto.9 ieee80211_key_update_end.9 \ + ieee80211_crypto.9 ieee80211_crypto_newkey.9 \ + ieee80211_crypto.9 ieee80211_crypto_setkey.9 \ + ieee80211_crypto.9 ieee80211_crypto_delglobalkeys.9 \ + ieee80211_crypto.9 ieee80211_crypto_reload_keys.9 \ + ieee80211_crypto.9 ieee80211_crypto_decap.9 \ + ieee80211_crypto.9 ieee80211_crypto_encap.9 \ + ieee80211_crypto.9 ieee80211_crypto_demic.9 \ + ieee80211_crypto.9 ieee80211_crypto_enmic.9 \ + ieee80211_crypto.9 ieee80211_notify_michael_failure.9 \ + ieee80211_crypto.9 ieee80211_notify_replay_failure.9 \ + ieee80211_crypto.9 ieee80211_crypto_register.9 \ + ieee80211_crypto.9 ieee80211_crypto_unregister.9 \ + ieee80211_crypto.9 ieee80211_crypto_available.9 +MLINKS+=ieee80211_input.9 ieee80211_input_all.9 +MLINKS+=ieee80211_node.9 ieee80211_find_rxnode.9 \ + ieee80211_node.9 ieee80211_find_rxnode_withkey.9 \ + ieee80211_node.9 ieee80211_ref_node.9 \ + ieee80211_node.9 ieee80211_unref_node.9 \ ieee80211_node.9 ieee80211_free_node.9 \ ieee80211_node.9 ieee80211_iterate_nodes.9 \ - ieee80211_node.9 ieee80211_lookup_node.9 \ - ieee80211_node.9 ieee80211_next_scan.9 \ - ieee80211_node.9 ieee80211_node_attach.9 \ - ieee80211_node.9 ieee80211_node_detach.9 \ - ieee80211_node.9 ieee80211_node_lateattach.9 \ - ieee80211_node.9 ieee80211_timeout_nodes.9 -MLINKS+=ieee80211_output.9 ieee80211_add_rates.9 \ - ieee80211_output.9 ieee80211_add_xrates.9 \ - ieee80211_output.9 ieee80211_encap.9 \ - ieee80211_output.9 ieee80211_send_mgmt.9 -MLINKS+=ieee80211_proto.9 ieee80211_dump_pkt.9 \ - ieee80211_proto.9 ieee80211_fix_rate.9 \ - ieee80211_proto.9 ieee80211_print_essid.9 \ - ieee80211_proto.9 ieee80211_proto_attach.9 \ - ieee80211_proto.9 ieee80211_proto_detach.9 -MLINKS+=ieee80211_radiotap.9 radiotap.9 + ieee80211_node.9 ieee80211_dump_node.9 \ + ieee80211_node.9 ieee80211_dump_nodes.9 +MLINKS+=ieee80211_output.9 M_WME_GETAC.9 \ + ieee80211_output.9 M_SEQNO_GET.9 \ + ieee80211_output.9 ieee80211_process_callback.9 +MLINKS+=ieee80211_proto.9 ieee80211_new_state.9 \ + ieee80211_proto.9 ieee80211_start_all.9 \ + ieee80211_proto.9 ieee80211_stop_all.9 \ + ieee80211_proto.9 ieee80211_suspend_all.9 \ + ieee80211_proto.9 ieee80211_resume_all.9 \ + ieee80211_proto.9 ieee80211_waitfor_parent.9 +MLINKS+=ieee80211_radiotap.9 radiotap.9 \ + ieee80211_radiotap.9 ieee80211_radiotap_attach.9 \ + ieee80211_radiotap.9 ieee80211_radiotap_active_vap.9 \ + ieee80211_radiotap.9 ieee80211_radiotap_active.9 \ + ieee80211_radiotap.9 ieee80211_radiotap_tx.9 +MLINKS+=ieee80211_regdomain.9 ieee80211_init_channels.9 \ + ieee80211_regdomain.9 ieee80211_sort_channels.9 \ + ieee80211_regdomain.9 ieee80211_alloc_countryie.9 +MLINKS+=ieee80211_vap.9 ieee80211_vap_setup.9 \ + ieee80211_vap.9 ieee80211_vap_attach.9 \ + ieee80211_vap.9 ieee80211_vap_detach.9 MLINKS+=ifnet.9 ifaddr.9 \ ifnet.9 if_data.9 \ ifnet.9 ifqueue.9 diff --git a/share/man/man9/ieee80211.9 b/share/man/man9/ieee80211.9 index 827daece94d..49fb3ce3487 100644 --- a/share/man/man9/ieee80211.9 +++ b/share/man/man9/ieee80211.9 @@ -1,6 +1,5 @@ .\" -.\" Copyright (c) 2004 Bruce M. Simpson -.\" Copyright (c) 2004 Darron Broad +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -25,236 +24,538 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.\" $Id: ieee80211.9,v 1.5 2004/03/04 12:33:27 bruce Exp $ .\" -.Dd March 2, 2004 -.Dt IEEE80211 9 +.Dd August 4, 2009 +.Dt NET80211 9 .Os .Sh NAME -.Nm ieee80211_ifattach , ieee80211_ifdetach , -.Nm ieee80211_mhz2ieee , ieee80211_chan2ieee , ieee80211_ieee2mhz , -.Nm ieee80211_media_init , ieee80211_media_change , ieee80211_media_status , -.Nm ieee80211_watchdog , -.Nm ieee80211_setmode , ieee80211_chan2mode , -.Nm ieee80211_rate2media , ieee80211_media2rate -.Nd core 802.11 network stack functions +.Nm net80211 +.Nd 802.11 network layer .Sh SYNOPSIS .In net80211/ieee80211_var.h -.In net80211/ieee80211_proto.h .Ft void -.Fn ieee80211_ifattach "struct ifnet *ifp" +.Fn ieee80211_ifattach "struct ieee80211com *ic" "const uint8_t macaddr[IEEE80211_ADDR_LEN]" .Ft void -.Fn ieee80211_ifdetach "struct ifnet *ifp" -.Ft u_int -.Fn ieee80211_mhz2ieee "u_int freq" "u_int flags" -.Ft u_int -.Fn ieee80211_chan2ieee "struct ieee80211com *ic" "struct ieee80211_channel *c" -.Ft u_int -.Fn ieee80211_ieee2mhz "u_int chan" "u_int flags" -.Ft void -.Fo ieee80211_media_init -.Fa "struct ifnet *ifp" "ifm_change_cb_t media_change" -.Fa "ifm_stat_cb_t media_stat" -.Fc -.Fa int -.Fn ieee80211_media_change "struct ifnet *ifp" -.Fa void -.Fn ieee80211_media_status "struct ifnet *ifp" "struct ifmediareq *imr" -.Ft void -.Fn ieee80211_watchdog "struct ifnet *ifp" -.Ft int -.Fn ieee80211_setmode "struct ieee80211com *ic" "enum ieee80211_phymode mode" -.Ft enum ieee80211_phymode -.Fo ieee80211_chan2mode -.Fa "struct ieee80211com *ic" "struct ieee80211_channel *chan" -.Fc -.Ft int -.Fo ieee80211_rate2media -.Fa "struct ieee80211com *ic" "int rate" "enum ieee80211_phymode mode" -.Fc -.Ft int -.Fn ieee80211_media2rate "int mword" +.Fn ieee80211_ifdetach "struct ieee80211com *ic" .Sh DESCRIPTION -The -.Nm ieee80211 -collection of functions are used to manage wireless network interfaces in the -system which use the system's software 802.11 network stack. -Most of these functions require that attachment to the stack is performed -before calling. -Several utility functions are also provided; these are safe to call from -any driver without prior initialization. +IEEE 802.11 device drivers are written to use the infrastructure provided +by the +.Nm +software layer. +This software provides a support framework for drivers that includes +ifnet cloning, state management, and a user management API by which +applications interact with 802.11 devices. +Most drivers depend on the +.Nm +layer for protocol services but devices that off-load functionality +may bypass the layer to connect directly to the device +(e.g. the +.Xr ndis 4 +emulation support does this). .Pp -.\" +A +.Nm +device driver implements a virtual radio API that is exported to +users through network interfaces (aka vaps) that are cloned from the +underlying device. +These interfaces have an operating mode +(station, adhoc, hostap, wds, monitor, etc.) +that is fixed for the lifetime of the interface. +Devices that can support multiple concurrent interfaces allow +multiple vaps to be cloned. +This enables construction of interesting applications such as +an AP vap and one or more WDS vaps +or multiple AP vaps, each with a different security model. The +.Nm +layer virtualizes most 802.11 state +and coordinates vap state changes including scheduling multiple vaps. +State that is not virtualized includes the current channel and +WME/WMM parameters. +Protocol processing is typically handled entirely in the +.Nm +layer with drivers responsible purely for moving data between the host +and device. +Similarly, +.Nm +handles most +.Xr ioctl 2 +requests without entering the driver; +instead drivers are notified of state changes that +require their involvement. +.Pp +The virtual radio interface defined by the +.Nm +layer means that drivers must be structured to follow specific rules. +Drivers that support only a single interface at any time must still +follow these rules. +.Sh DATA STRUCTURES +The virtual radio architecture splits state between a single per-device +.Vt ieee80211com +structure and one or more +.Vt ieee80211vap +structures. +Drivers are expected to setup various shared state in these structures +at device attach and during vap creation but otherwise should treat them +as read-only. +The +.Vt ieee80211com +structure is allocated by the +.Nm +layer as adjunct data to a device's +.Vt ifnet ; +it is accessed through the +.Vt if_l2com +structure member. +The +.Vt ieee80211vap +structure is allocated by the driver in the +.Dq vap create +method +and should be extended with any driver-private state. +This technique of giving the driver control to allocate data structures +is used for other +.Nm +data structures and should be exploited to maintain driver-private state +together with public +.Nm +state. +.Pp +The other main data structures are the station, or node, table +that tracks peers in the local BSS, and the channel table that defines +the current set of available radio channels. +Both tables are bound to the +.Vt ieee80211com +structure and shared by all vaps. +Long-lasting references to a node are counted to guard against +premature reclamation. +In particular every packet sent/received holds a node reference +(either explicitly for transmit or implicitly on receive). +.Pp +The +.Vt ieee80211com +and +.Vt ieee80211vap +structures also hold a collection of method pointers that drivers +fill-in and/or override to take control of certain operations. +These methods are the primary way drivers are bound to the +.Nm +layer and are described below. +.Sh DRIVER ATTACH/DETACH +Drivers attach to the +.Nm +layer with the .Fn ieee80211_ifattach -function attaches the network interface -.Fa ifp -to the 802.11 network stack layer. -This function must be called before using any of the -.Nm ieee80211 -functions which need to store driver state across invocations; +function. +The driver is expected to allocate and setup any device-private +data structures before passing control. The -.Vt struct ifnet -instance pointed to by -.Fa ifp -MUST be an instance of -.Vt struct ieee80211com , -with various fields initialized to tell -.Nm ieee80211 -about its capabilities. -This function performs Ethernet and BPF attachment (by calling -.Fn ether_ifattach -and -.Fn bpfattach2 ) -on behalf of the caller. -It also implements the -.Vt ifmedia -interface. +.Vt ieee80211com +structure must be pre-initialized with state required to setup the +.Nm +layer: +.Bl -tag -width ic_channels +.It Dv ic_ifp +Backpointer to the physical device's ifnet. +.It Dv ic_caps +Device/driver capabilities; see below for a complete description. +.It Dv ic_channels +Table of channels the device is capable of operating on. +This is initially provided by the driver but may be changed +through calls that change the regulatory state. +.It Dv ic_nchan +Number of entries in +.Dv ic_channels . +.El .Pp -.\" -The +On return from +.Fn ieee80211_ifattach +the driver is expected to override default callback functions in the +.Vt ieee80211com +structure to register it's private routines. +Methods marked with a +.Dq * +must be provided by the driver. +.Bl -tag -width ic_channels +.It Dv ic_vap_create* +Create a vap instance of the specified type (operating mode). +Any fixed BSSID and/or MAC address is provided. +Drivers that support multi-bssid operation may honor the requested BSSID +or assign their own. +.It Dv ic_vap_delete* +Destroy a vap instance created with +.Dv ic_vap_create . +.It Dv ic_getradiocaps +Return the list of calibrated channels for the radio. +The default method returns the current list of channels +(space permitting). +.It Dv ic_setregdomain +Process a request to change regulatory state. +The routine may reject a request or constrain changes (e.g. reduce +transmit power caps). +The default method accepts all proposed changes. +.It Dv ic_send_mgmt +Send an 802.11 management frame. +The default method fabricates the frame using +.Nm +state and passes it to the driver through the +.Dv ic_raw_xmit +method. +.It Dv ic_raw_xmit +Transmit a raw 802.11 frame. +The default method drops the frame and generates a message on the console. +.It Dv ic_updateslot +Update hardware state after an 802.11 IFS slot time change, +There is no default method; the pointer may be NULL in which case +it will not be used. +.It Dv ic_update_mcast +Update hardware for a change in the multicast packet filter, +The default method prints a console message. +.It Dv ic_update_promisc +Update hardware for a change in the promiscuous mode setting. +The default method prints a console message. +.It Dv ic_newassoc +Update driver/device state for association to a new AP (in station mode) +or when a new station associates (e.g. in AP mode). +There is no default method; the pointer may be NULL in which case +it will not be used. +.It Dv ic_node_alloc +Allocate and initialize a +.Vt ieee80211_node +structure. +This method cannot sleep. +The default method allocates zero'd memory using +.Xr malloc 9. +Drivers should override this method to allocate extended storage +for their own needs. +Memory allocated by the driver must be tagged with +.Dv M_80211_NODE +to balance the memory allocation statistics. +.It Dv ic_node_free +Reclaim storage of a node allocated by +.Dv ic_node_alloc . +Drivers are expected to +.Em interpose +their own method to cleanup private state but must call through +this method to allow +.Nm +to reclaim it's private state. +.It Dv ic_node_cleanup +Cleanup state in a +.Vt ieee80211_node +created by +.Dv ic_node_alloc . +This operation is distinguished from +.Dv ic_node_free +in that it may be called long before the node is actually reclaimed +to cleanup adjunct state. +This can happen, for example, when a node must not be reclaimed +due to references held by packets in the transmit queue. +Drivers typically interpose +.Dv ic_node_cleanup +instead of +.Dv ic_node_free . +.It Dv ic_node_age +Age, and potentially reclaim, resources associated with a node. +The default method ages frames on the power-save queue (in AP mode) +and pending frames in the receive reorder queues (for stations using A-MPDU). +.It Dv ic_node_drain +Reclaim all optional resources associated with a node. +This call is used to free up resources when they are in short supply, +.It Dv ic_node_getrssi +Return the Receive Signal Strength Indication (RSSI) in .5 dBm units for +the specified node. +This interface returns a subset of the information +returned by +.Dv ic_node_getsignal , +The default method calculates a filtered average over the last ten +samples passed in to +.Xr ieee80211_input 9 +or +.Xr ieee80211_input_all 9 . +.It Dv ic_node_getsignal +Return the RSSI and noise floor (in .5 dBm units) for a station. +The default method calculates RSSI as described above; +the noise floor returned is the last value supplied to +.Xr ieee80211_input 9 +or +.Xr ieee80211_input_all 9 . +.It Dv ic_node_getmimoinfo +Return MIMO radio state for a station in support of the +.Dv IEEE80211_IOC_STA_INFO +ioctl request. +The default method returns nothing. +.It Dv ic_scan_start* +Prepare driver/hardware state for scanning. +This callback is done in a sleepable context. +.It Dv ic_scan_end* +Restore driver/hardware state after scanning completes. +This callback is done in a sleepable context. +.It Dv ic_set_channel* +Set the current radio channel using +.Vt ic_curchan . +This callback is done in a sleepable context. +.It Dv ic_scan_curchan +Start scanning on a channel. +This method is called immediately after each channel change +and must initiate the work to scan a channel and schedule a timer +to advance to the next channel in the scan list. +This callback is done in a sleepable context. +The default method handles active scan work (e.g. sending ProbRequest +frames), and schedules a call to +.Xr ieee80211_scan_next 9 +according to the maximum dwell time for the channel. +Drivers that off-load scan work to firmware typically use this method +to trigger per-channel scan activity. +.It Dv ic_scan_mindwell +Handle reaching the minimum dwell time on a channel when scanning. +This event is triggered when one or more stations have been found on +a channel and the minimum dwell time has been reached. +This callback is done in a sleepable context. +The default method signals the scan machinery to advance +to the next channel as soon as possible. +Drivers can use this method to preempt further work (e.g. if scanning +is handled by firmware) or ignore the request to force maximum dwell time +on a channel. +.It Dv ic_recv_action +Process a received Action frame. +The default method points to +.Xr ieee80211_recv_action 9 +which provides a mechanism for setting up handlers for each Action frame class. +.It Dv ic_send_action +Transmit an Action frame. +The default method points to +.Xr ieee80211_send_action 9 +which provides a mechanism for setting up handlers for each Action frame class. +.It Dv ic_ampdu_enable +Check if transmit A-MPDU should be enabled for the specified station and AC. +The default method checks a per-AC traffic rate against a per-vap +threshold to decide if A-MPDU should be enabled. +This method also rate-limits ADDBA requests so that requests are not +made too frequently when a receiver has limited resources. +.It Dv ic_addba_request +Request A-MPDU transmit aggregation. +The default method sets up local state and issues an +ADDBA Request Action frame. +Drivers may interpose this method if they need to setup private state +for handling transmit A-MPDU. +.It Dv ic_addb_response +Process a received ADDBA Response Action frame and setup resources as +needed for doing transmit A-MPDU, +.It Dv ic_addb_stop +Shutdown an A-MPDU transmit stream for the specified station and AC. +The default method reclaims local state after sending a DelBA Action frame. +.It Dv ic_bar_response +Process a response to a transmitted BAR control frame. +.It Dv ic_ampdu_rx_start +Prepare to receive A-MPDU data from the specified station for the TID. +.It Dv ic_ampdu_rx_stop +Terminate receipt of A-MPDU data from the specified station for the TID. +.El +.Pp +Once the +.Nm +layer is attached to a driver there are two more steps typically done +to complete the work: +.Bl -enum +.It +Setup +.Dq radiotap support +for capturing raw 802.11 packets that pass through the device. +This is done with a call to +.Xr ieee80211_radiotap_attach 9 . +.It +Do any final device setup like enabling interrupts. +.El +.Pp +State is torn down and reclaimed with a call to +.Fn ieee80211_ifdetach . +Note this call may result in multiple callbacks into the driver +so it should be done before any critical driver state is reclaimed. +On return from .Fn ieee80211_ifdetach -function frees any -.Nm ieee80211 -structures associated with the driver, and performs Ethernet and BPF -detachment on behalf of the caller. -.Pp -.\" +all associated vaps and ifnet structures are reclaimed or inaccessible +to user applications so it is safe to teardown driver state without +worry about being re-entered. +The driver is responsible for calling +.Xr if_free 9 +on the ifnet it allocated for the physical device. +.Sh DRIVER CAPABILITIES +Driver/device capabilities are specified using several sets of flags +in the +.Vt ieee80211com +structure. +General capabilities are specified by +.Vt ic_caps . +Hardware cryptographic capabilities are specified by +.Vt ic_cryptocaps . +802.11n capabilities, if any, are specified by +.Vt ic_htcaps . The -.Fn ieee80211_mhz2ieee -utility function converts the frequency -.Fa freq -(specified in MHz) to an IEEE 802.11 channel number. -The -.Fa flags -argument is a hint which specifies whether the frequency is in -the 2GHz ISM band -.Pq Vt IEEE80211_CHAN_2GHZ -or the 5GHz band -.Pq Vt IEEE80211_CHAN_5GHZ ; -appropriate clipping of the result is then performed. -.Pp -.\" -The -.Fn ieee80211_chan2ieee -function converts the channel specified in -.Fa *c -to an IEEE channel number for the driver -.Fa ic . -If the conversion would be invalid, an error message is printed to the -system console. -This function REQUIRES that the driver is hooked up to the -.Nm ieee80211 -subsystem. -.Pp -.\" -The -.Fn ieee80211_ieee2mhz -utility function converts the IEEE channel number -.Ft chan -to a frequency (in MHz). -The -.Fa flags -argument is a hint which specifies whether the frequency is in -the 2GHz ISM band -.Pq Vt IEEE80211_CHAN_2GHZ -or the 5GHz band -.Pq Vt IEEE80211_CHAN_5GHZ ; -appropriate clipping of the result is then performed. -.Pp -.\" -The -.Fn ieee80211_media_init -function initializes media data structures used by the -.Vt ifmedia -interface, for the driver -.Fa ifp . -It must be called by the driver after calling -.Fn ieee80211_attach -and before calling most -.Nm ieee80211 -functions. -The -.Fa media_change +.Nm +layer propagates a subset of these capabilities to each vap through +the equivalent fields: +.Vt iv_caps , +.Vt iv_cryptocaps , and -.Fa media_stat -arguments specify helper functions which will be invoked by the -.Vt ifmedia -framework when the user changes or queries media options, -using a command such as -.Xr ifconfig 8 . +.Vt iv_htcaps . +The following general capabilities are defined: +.Bl -tag -width IEEE80211_C_8023ENCAP +.It Dv IEEE80211_C_STA +Device is capable of operating in station (aka Infrastructure) mode. +.It Dv IEEE80211_C_8023ENCAP +Device requires 802.3-encapsulated frames be passed for transmit. +By default +.Nm +will encapsulate all outbound frames as 802.11 frames (without a PLCP header). +.It Dv IEEE80211_C_FF +Device supports Atheros Fast-Frames. +.It Dv IEEE80211_C_TURBOP +Device supports Atheros Dynamic Turbo mode. +.It Dv IEEE80211_C_IBSS +Device is capable of operating in adhoc/IBSS mode. +.It Dv IEEE80211_C_PMGT +Device supports dynamic power-management (aka power save) in station mode. +.It Dv IEEE80211_C_HOSTAP +Device is capable of operating as an Access Point in Infrastructure mode. +.It Dv IEEE80211_C_AHDEMO +Device is capable of operating in Adhoc Demo mode. +In this mode the device is used purely to send/receive raw 802.11 frames. +.It Dv IEEE80211_C_SWRETRY +Device supports software retry of transmitted frames. +.It Dv IEEE80211_C_TXPMGT +Device support dynamic transmit power changes on transmitted frames; +also known as Transmit Power Control (TPC). +.It Dv IEEE80211_C_SHSLOT +Device supports short slot time operation (for 802.11g). +.It Dv IEEE80211_C_SHPREAMBLE +Device supports short preamble operation (for 802.11g). +.It Dv IEEE80211_C_MONITOR +Device is capable of operating in monitor mode. +.It Dv IEEE80211_C_DFS +Device supports radar detection and/or DFS. +DFS protocol support can be handled by +.Nm +but the device must be capable of detecting radar events. +.It Dv IEEE80211_C_MBSS +Device is capable of operating in MeshBSS (MBSS) mode +(as defined by 802.11s Draft 3.0). +.It Dv IEEE80211_C_WPA1 +Device supports WPA1 operation. +.It Dv IEEE80211_C_WPA2 +Device supports WPA2/802.11i operation. +.It Dv IEEE80211_C_BURST +Device supports frame bursting. +.It Dv IEEE80211_C_WME +Device supports WME/WMM operation +(at the moment this is mostly support for sending and receiving +QoS frames with EDCF). +.It Dv IEEE80211_C_WDS +Device supports transmit/receive of 4-address frames. +.It Dv IEEE80211_C_BGSCAN +Device supports background scanning. +.It Dv IEEE80211_C_TXFRAG +Device supports transmit of fragmented 802.11 frames. +.It Dv IEEE80211_C_TDMA +Device is capable of operating in TDMA mode. +.El .Pp -.\" -The -.Fn ieee80211_media_status -and -.Fn ieee80211_media_change -functions are device-independent handlers for -.Vt ifmedia -commands and are not intended to be called directly. +The follow general crypto capabilities are defined. +In general +.Nm +will fall-back to software support when a device is not capable +of hardware acceleration of a cipher. +This can be done on a per-key basis. +.Nm +can also handle software +.Dv Michael +calculation combined with hardware +.Dv AES +acceleration. +.Bl -tag -width IEEE80211_C_8023ENCAP +.It Dv IEEE80211_CRYPTO_WEP +Device supports hardware WEP cipher. +.It Dv IEEE80211_CRYPTO_TKIP +Device supports hardware TKIP cipher. +.It Dv IEEE80211_CRYPTO_AES_OCB +Device supports hardware AES-OCB cipher. +.It Dv IEEE80211_CRYPTO_AES_CCM +Device supports hardware AES-CCM cipher. +.It Dv IEEE80211_CRYPTO_TKIPMIC +Device supports hardware Michael for use with TKIP. +.It Dv IEEE80211_CRYPTO_CKIP +Devices supports hardware CKIP cipher. +.El .Pp -.\" -The -.Fn ieee80211_watchdog -function is intended to be called from a driver's -.Va if_watchdog -routine. -It is used to perform periodic cleanup of state within the software 802.11 -stack, as well as timing out scans. -.Pp -.\" -The -.Fn ieee80211_setmode -function is called from within the 802.11 stack to change the mode -of the driver's PHY; it is not intended to be called directly. -.Pp -.\" -The -.Fn ieee80211_chan2mode -function returns the PHY mode required for use with the channel -.Fa chan -on the device -.Fa ic . -This is typically used when selecting a rate set, to be advertised in -beacons, for example. -.Pp -.\" -The -.Fn ieee80211_rate2media -function converts the bit rate -.Fa rate -(measured in units of 0.5Mbps) to an -.Vt ifmedia -sub-type, for the device -.Fa ic -running in PHY mode -.Fa mode . -The -.Fn ieee80211_media2rate -performs the reverse of this conversion, returning the bit rate (in 0.5Mbps -units) corresponding to an -.Vt ifmedia -sub-type. -.\" +The follow general 802.11n capabilities are defined. +The first capabilities are defined exactly as they appear in the +802.11n specification. +Capabilities beginning with IEEE80211_HTC_AMPDU are used soley by the +.Nm +layer. +.Bl -tag -width IEEE80211_C_8023ENCAP +.It Dv IEEE80211_HTCAP_CHWIDTH40 +Device supports 20/40 channel width operation. +.It Dv IEEE80211_HTCAP_SMPS_DYNAMIC +Device supports dynamic SM power save operation. +.It Dv IEEE80211_HTCAP_SMPS_ENA +Device supports static SM power save operation. +.It Dv IEEE80211_HTCAP_GREENFIELD +Device supports Greenfield preamble. +.It Dv IEEE80211_HTCAP_SHORTGI20 +Device supports Short Guard Interval on 20MHz channels. +.It Dv IEEE80211_HTCAP_SHORTGI40 +Device supports Short Guard Interval on 40MHz channels. +.It Dv IEEE80211_HTCAP_TXSTBC +Device supports Space Time Block Convolution (STBC) for transmit. +.It Dv IEEE80211_HTCAP_RXSTBC_1STREAM +Device supports 1 spatial stream for STBC receive. +.It Dv IEEE80211_HTCAP_RXSTBC_2STREAM +Device supports 1-2 spatial streams for STBC receive. +.It Dv IEEE80211_HTCAP_RXSTBC_3STREAM +Device supports 1-3 spatial streams for STBC receive. +.It Dv IEEE80211_HTCAP_MAXAMSDU_7935 +Device supports A-MSDU frames up to 7935 octets. +.It Dv IEEE80211_HTCAP_MAXAMSDU_3839 +Device supports A-MSDU frames up to 3839 octets. +.It Dv IEEE80211_HTCAP_DSSSCCK40 +Device supports use of DSSS/CCK on 40MHz channels. +.It Dv IEEE80211_HTCAP_PSMP +Device supports PSMP. +.It Dv IEEE80211_HTCAP_40INTOLERANT +Device is intolerant of 40MHz wide channel use. +.It Dv IEEE80211_HTCAP_LSIGTXOPPROT +Device supports L-SIG TXOP protection. +.It Dv IEEE80211_HTC_AMPDU +Device supports A-MPDU aggregation. +Note that any 802.11n compliant device must support A-MPDU receive +so this implicitly means support for +.Em transmit +of A-MPDU frames. +.It Dv IEEE80211_HTC_AMSDU +Device supports A-MSDU aggregation. +Note that any 802.11n compliant device must support A-MSDU receive +so this implicitly means support for +.Em transmit +of A-MSDU frames. +.It Dv IEEE80211_HTC_HT +Device supports High Throughput (HT) operation. +This capability must be set to enable 802.11n functionality +in +.Nm . +.It Dv IEEE80211_HTC_SMPS +Device supports MIMO Power Save operation. +.It Dv IEEE80211_HTC_RIFS +Device supports Reduced Inter Frame Spacing (RIFS). +.El .Sh SEE ALSO -.Xr ieee80211_crypto 9 , +.Xr ioctl 2 , +.Xr ndis 4 , .Xr ieee80211_input 9 , -.Xr ieee80211_ioctl 9 , -.Xr ieee80211_node 9 , -.Xr ieee80211_output 9 , -.Xr ieee80211_proto 9 , -.Xr ieee80211_radiotap 9 , -.Xr ifnet 9 -.Sh HISTORY -The -.Nm ieee80211 -series of functions first appeared in -.Nx 1.5 , -and were later ported to -.Fx 4.6 . -.Sh AUTHORS -.An -nosplit -This manual page was written by -.An Bruce M. Simpson Aq bms@FreeBSD.org -and -.An Darron Broad Aq darron@kewl.org . +.Xr ieee80211_input_all 9 , +.Xr ieee80211_scan_next 9 , +.Xr ieee80211_recv_action 9 , +.Xr ieee80211_send_action 9 , +.Xr ieee80211_radiotap_attach 9 , +.Xr ifnet 9 , +.Xr malloc 9 . diff --git a/share/man/man9/ieee80211_amrr.9 b/share/man/man9/ieee80211_amrr.9 new file mode 100644 index 00000000000..acd70da3dec --- /dev/null +++ b/share/man/man9/ieee80211_amrr.9 @@ -0,0 +1,194 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" 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 August 4, 2009 +.Dt IEEE8021_AMRR 9 +.Os +.Sh NAME +.Nm ieee80211_amrr +.Nd 802.11 network driver transmit rate control support +.Sh SYNOPSIS +.In net80211/ieee80211_amrr.h +.Ft void +.Fo ieee80211_amrr_init +.Fa "struct ieee80211_amrr *" +.Fa "struct ieee80211vap *" +.Fa "int amin" +.Fa "int amax" +.Fa "int interval" +.Fc +.\" +.Ft void +.Fn ieee80211_amrr_cleanup "struct ieee80211_amrr *" +.\" +.Ft void +.Fn ieee80211_amrr_setinterval "struct ieee80211_amrr *" "int interval" +.\" +.Ft void +.Fo ieee80211_amrr_node_init +.Fa "struct ieee80211_amrr *" +.Fa "struct ieee80211_amrr_node *" +.Fa "struct ieee80211_node *" +.Fc +.\" +.Ft int +.Fo ieee80211_amrr_choose +.Fa "struct ieee80211_node *" +.Fa "struct ieee80211_amrr_node *" +.Fc +.\" +.Ft void +.Fo ieee80211_amrr_tx_complete +.Fa "struct ieee80211_amrr_node *" +.Fa "int ok" +.Fa "int retries" +.Fc +.\" +.Ft void +.Fo ieee80211_amrr_tx_update +.Fa "struct ieee80211_amrr_node *" +.Fa "int txnct" +.Fa "int success" +.Fa "int retrycnt" +.Fc +.Sh DESCRIPTION +.Nm +is an implementation of the AMRR transmit rate control algorithm +for drivers that use the +.Nm net80211 +software layer. +A rate control algorithm is responsible for choosing the transmit +rate for each frame. +To maximize throughput algorithms try to use the highest rate that +is appropriate for the operating conditions. +The rate will vary as conditions change; the distance between two stations +may change, transient noise may be present that affects signal quality, +etc. +.Nm +uses very simple information from a driver to do it's job: +whether a frame was successfully delivered and how many transmit +attempts were made. +While this enables its use with virtually any wireless device it +limits it's effectiveness--do not expect it to function well in +difficult environments and/or respond quickly to changing conditions. +.Pp +.Nm +requires per-vap state and per-node state for each station it is to +select rates for. +The API's are designed for drivers to pre-allocate state in the +driver-private extension areas of each vap and node. +For example the +.Xr ral 4 +driver defines a vap as: +.Bd -literal -offset indent +struct rt2560_vap { + struct ieee80211vap ral_vap; + struct ieee80211_beacon_offsets ral_bo; + struct ieee80211_amrr amrr; + + int (*ral_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +.Ed +.Pp +The +.Vt amrr +structure member holds the per-vap state for +.Nm +and +.Xr ral 4 +initializes it in the vap create method with: +.Bd -literal -offset indent +ieee80211_amrr_init(&rvp->amrr, vap, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, + 500 /* ms */); +.Ed +.Pp +The node is defined as: +.Bd -literal -offset indent +struct rt2560_node { + struct ieee80211_node ni; + struct ieee80211_amrr_node amrr; +}; +.Ed +.Pp +with initialization done in the driver's +.Vt iv_newassoc +method: +.Bd -literal -offset indent +static void +rt2560_newassoc(struct ieee80211_node *ni, int isnew) +{ + struct ieee80211vap *vap = ni->ni_vap; + + ieee80211_amrr_node_init(&RT2560_VAP(vap)->amrr, + &RT2560_NODE(ni)->amrr, ni); +} +.Ed +.Pp +Once +.Nm +state is setup, transmit rates are requested by calling +.Fn ieee80211_amrr_choose +in the transmit path; e.g.: +.Bd -literal -offset indent +tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; +if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { + rate = tp->mcastrate; +} else if (m0->m_flags & M_EAPOL) { + rate = tp->mgmtrate; +} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { + rate = tp->ucastrate; +} else { + (void) ieee80211_amrr_choose(ni, &RT2560_NODE(ni)->amrr); + rate = ni->ni_txrate; +} +.Ed +.Pp +Note a rate is chosen only for unicast data frames when a fixed +transmit rate is not configured; the other cases are handled with +the +.Nm net80211 +transmit parameters. +Note also that +.Fn ieee80211_amrr_choose +writes the chosen rate in +.Vt ni_txrate ; +this eliminates copying the value as it is exported to user applications so +they can display the current transmit rate in status. +.Pp +The remaining work a driver must do is feed status back to +.Nm +when a frame transmit completes using +.Fn ieee80211_amrr_tx_complete . +Drivers that poll a device to retrieve statistics can use +.Fn ieee80211_amrr_tx_update +(instead or in addition). +.Sh SEE ALSO +.Xr ieee80211 9 , +.Xr ieee80211_output 9 , diff --git a/share/man/man9/ieee80211_beacon.9 b/share/man/man9/ieee80211_beacon.9 new file mode 100644 index 00000000000..444c433491a --- /dev/null +++ b/share/man/man9/ieee80211_beacon.9 @@ -0,0 +1,115 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" 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 August 4, 2009 +.Dt IEEE80211_BEACON 9 +.Os +.Sh NAME +.Nm ieee80211_beacon +.Nd 802.11 beacon support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.Pp +.Ft "struct mbuf *" +.Fo ieee80211_beacon_alloc +.Fa "struct ieee80211_node *" +.Fa "struct ieee80211_beacon_offsets *" +.Fc +.\" +.Ft int +.Fo ieee80211_beacon_update +.Fa "struct ieee80211_node *" +.Fa "struct ieee80211_beacon_offsets *" +.Fa "struct mbuf *" +.Fa "int mcast" +.Fc +.\" +.Ft void +.Fn ieee80211_beacon_notify "struct ieee80211vap *" "int what" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides a support framework for drivers that includes +a template-based mechanism for dynamic update of beacon frames transmit +in hostap, adhoc, and mesh operating modes. +Drivers should use +.Fn ieee80211_beacon_alloc +to create an initial beacon frame. +The +.Vt ieee80211_beacon_offsets +structure holds information about the beacon contents that is used +to optimize updates done with +.Fn ieee80211_beacon_update . +.Pp +Update calls should only be done when something changes that +affects the contents of the beacon frame. +When this happens the +.Dv iv_update_beacon +method is invoked and a driver-supplied routine must do the right thing. +For devices that involve the host to transmit each +beacon frame this work may be as simple as marking a bit in the +.Vt ieee80211_beacon_offsets +structure: +.Bd -literal +static void +ath_beacon_update(struct ieee80211vap *vap, int item) +{ + struct ieee80211_beacon_offsets *bo = &ATH_VAP(vap)->av_boff; + setbit(bo->bo_flags, item); +} +.Ed +.Pp +with the +.Fn ieee80211_beacon_update +call done before the next beacon is to be sent. +.Pp +Devices that off-load beacon generation may instead choose to use +this callback to push updates immediately to the device. +Exactly how that is accomplished is unspecified. +One possibility is to update the beacon frame contents and extract +the appropriate information element, but other scenarios are possible. +.Sh MULTI-VAP BEACON SCHEDULING +Drivers that support multiple vaps that can each beacon need to consider +how to schedule beacon frames. +There are two possibilities at the moment: +.Em burst +all beacons at TBTT or +.Em stagger beacons +over the beacon interval. +Bursting beacon frames may result in aperiodic delivery that can affect +power save operation of associated stations. +Applying some jitter (e.g. by randomly ordering burst frames) may be +sufficient to combat this and typically this is not an issue unless +stations are using aggressive power save techniques +such as U-APSD (sometimes employed by VoIP phones). +Staggering frames requires more interrupts and device support that +may not be available. +Staggering beacon frames is usually superior to bursting frames, up to +about eight vaps, at which point the overhead becomes significant and +the channel becomes noticeably busy anyway. +.Sh SEE ALSO +.Xr ieee80211 9 . diff --git a/share/man/man9/ieee80211_bmiss.9 b/share/man/man9/ieee80211_bmiss.9 new file mode 100644 index 00000000000..e227ac07744 --- /dev/null +++ b/share/man/man9/ieee80211_bmiss.9 @@ -0,0 +1,91 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" 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 August 4, 2009 +.Dt IEEE80211_BMISS 9 +.Os +.Sh NAME +.Nm ieee80211_bmiss +.Nd 802.11 beacon miss support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.Pp +.Ft void +.Fn ieee80211_beacon_miss "struct ieee80211com *" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides a support framework for drivers that includes +handling beacon miss events in station mode. +Drivers can dispatch beacon miss events that are recognized in hardware or +.Nm net80211 +can detect beacon miss if the driver dispatches received beacon frames +through the normal receive path. +Software beacon miss support is especially useful when multiple vaps +are operating and any hardware beacon miss support is not available +(e.g. operating as an access point together with one or more station +mode vaps). +.Pp +Drivers should dispatch beacon miss events recognized in the driver with +.Fn ieee80211_beacon_miss . +This causes some number of ProbeRequest frames to be sent to the +access point to check if the association is still alive. +If no response is received and roaming mode is set to +.Dv IEEE80211_ROAMING_AUTO +then +.Nm net80211 +will try to re-associate and if that fails +trigger a scan to look for the access point or another suitable AP. +When the +.Nm net80211 +state machine is being operated manually, e.g. by +.Xr wpa_supplicant 8 , +then applications are notified of the state change and are responsible +for handling the work of scanning for a new access point. +The number of beacon miss events (without a ProbeResponse) is user +settable with the +.Dv IEEE80211_IOC_BMISSTHRESHOLD +request. +.Pp +Software beacon miss detection is enabled per-vap by setting the +.Dv IEEE80211_FEXT_SWBMISS +flag. +Typically this is done when a vap is setup +when the +.Dv IEEE80211_CLONE_NOBEACONS +option is supplied to the clone operation. +But drivers may also force this when they know they need help detecting +beacon miss. +When beacon miss is detected in software the event is dispatched without +driver involvement. +Note that software beacon miss handling is not limited to station mode; +it can be used in any operating mode where beacons from a peer station +are received. +.Sh SEE ALSO +.Xr ieee80211 9 , +.Xr ieee80211_vap 9 , +.Xr wpa_supplicant 8 , diff --git a/share/man/man9/ieee80211_crypto.9 b/share/man/man9/ieee80211_crypto.9 index bf4bb604917..f5a028b64b6 100644 --- a/share/man/man9/ieee80211_crypto.9 +++ b/share/man/man9/ieee80211_crypto.9 @@ -27,76 +27,233 @@ .\" $FreeBSD$ .\" $Id: ieee80211_crypto.9,v 1.3 2004/03/04 10:42:56 bruce Exp $ .\" -.Dd March 2, 2004 +.Dd August 4, 2009 .Dt IEEE80211_CRYPTO 9 .Os .Sh NAME -.Nm ieee80211_crypto_attach , ieee80211_crypto_detach , ieee80211_wep_crypt -.Nd 802.11 WEP encryption functions +.Nm ieee80211_crypto +.Nd 802.11 cryptographic support .Sh SYNOPSIS +.In net80211/ieee80211_var.h +.\" +.Pp .Ft void -.Fn ieee80211_crypto_attach "struct ifnet *ifp" +.Fn ieee80211_crypto_register "const struct ieee80211_cipher *" +.\" .Ft void -.Fn ieee80211_crypto_detach "struct ifnet *ifp" -.Ft struct mbuf * -.Fn ieee80211_wep_crypt "struct ifnet *ifp" "struct mbuf *m0" "int txflag" +.Fn ieee80211_crypto_unregister "const struct ieee80211_cipher *" +.\" +.Ft int +.Fn ieee80211_crypto_available "int cipher" +.\" +.Pp +.Ft void +.Fo ieee80211_notify_replay_failure +.Fa "struct ieee80211vap *" +.Fa "const struct ieee80211_frame *" +.Fa "const struct ieee80211_key *" +.Fa "uint64_t rsc" +.Fa "int tid" +.Fc +.\" +.Ft void +.Fo ieee80211_notify_michael_failure +.Fa "struct ieee80211vap *" +.Fa "const struct ieee80211_frame *" +.Fa "u_int keyix" +.Fc +.\" +.Ft int +.Fo ieee80211_crypto_newkey +.Fa "struct ieee80211vap * +.Fa "int cipher +.Fa "int flags +.Fa "struct ieee80211_key * +.Fc +.\" +.Ft int +.Fn ieee80211_crypto_setkey "struct ieee80211vap *" "struct ieee80211_key *" +.\" +.Ft int +.Fn ieee80211_crypto_delkey "struct ieee80211vap *" "struct ieee80211_key *" +.\" +.Ft void +.Fn ieee80211_key_update_begin "struct ieee80211vap *" +.\" +.Ft void +.Fn ieee80211_key_update_end "struct ieee80211vap *" +.\" +.Ft void +.Fn ieee80211_crypto_delglobalkeys "struct ieee80211vap *" +.\" +.Ft void +.Fn ieee80211_crypto_reload_keys "struct ieee80211com *" +.\" +.Pp +.Ft struct ieee80211_key * +.Fn ieee80211_crypto_encap "struct ieee80211_node *" "struct mbuf *" +.\" +.Ft struct ieee80211_key * +.Fn ieee80211_crypto_decap "struct ieee80211_node *" "struct mbuf *" "int flags" +.\" +.Ft int +.Fo ieee80211_crypto_demic +.Fa "struct ieee80211vap *" +.Fa "struct ieee80211_key *" +.Fa "struct mbuf *" +.Fa "int force" +.Fc +.\" +.Ft int +.Fo ieee80211_crypto_enmic +.Fa "struct ieee80211vap *" +.Fa "struct ieee80211_key *" +.Fa "struct mbuf *" +.Fa "int force" +.Fc .Sh DESCRIPTION -These functions provide software encryption support -for 802.11 device drivers. +The +.Nm net80211 +layer includes comprehensive cryptographic support for 802.11 protocols. +Software implementations of ciphers required by +WPA and 802.11i are provided as well as encap/decap processing of 802.11 frames. +Software ciphers are written as kernel modules and +register with the core crypto support. +The cryptographic framework supports hardware acceleration of ciphers +by drivers with automatic fall-back to software implementations when a +driver is unable to provide necessary hardware services. +.Sh CRYPTO CIPHER MODULES +.Nm net80211 +cipher modules register their services using +.Fn ieee80211_crypto_register +and supply a template that describes their operation. +This +.Vt ieee80211_cipher +structure defines protocol-related state such as the number of bytes +of space in the 802.11 header to reserve/remove during encap/decap +and entry points for setting up keys and doing cryptographic operations. .Pp -.\" -The -.Fn ieee80211_crypto_attach -function initializes crypto support for the interface -.Fa ifp , -and sets the initialization vector (IV) for WEP encryption to -a random number derived from a secure PRNG. +Cipher modules can associate private state to each key through the +.Vt wk_private +structure member. +If state is setup by the module it will be called before a key is destroyed +so it can reclaim resources. .Pp -.\" +Crypto modules can notify the system of two events. +When a packet replay event is recognized +.Fn ieee80111_notify_replay_failure +can be used to signal the event. +When a +.Dv TKIP +Michael failure is detected +.Fn ieee80211_notify_michael_failure +can be invoked. +Drivers may also use these routines to signal events detected by the +hardware. +.Sh CRYPTO KEY MANAGEMENT The -.Fn ieee80211_crypto_detach -function frees data structures associated with crypto support -for the interface -.Fa ifp . +.Nm net80211 +layer implements a per-vap 4-element +.Dq global key table +and a per-station +.Dq unicast key +for protocols such as WPA, 802.1x, and 802.11i. +The global key table is designed to support legacy WEP operation +and Multicast/Group keys, +though some applications also use it to implement WPA in station mode. +Keys in the global table are identified by a key index in the range 0-3. +Per-station keys are identified by the MAC address of the station and +are typically used for unicast PTK bindings. .Pp -.\" +.Nm net80211 +provides +.Xr ioctl 2 +operations for managing both global and per-station keys. +Drivers typically do not participate in software key management; +they are involved only when providing hardware acceleration of +cryptographic operations. +.Pp +.Fn ieee80211_crypto_newkey +is used to allocate a new +.Nm net80211 +key or reconfigure an existing key. +The cipher must be specified along with any fixed key index. The -.Fn ieee80211_wep_crypt -function runs the appropriate WEP encryption algorithm over the 802.11 -encapsulated frame held in the mbuf chain -.Fa m0 , -for transmission or reception on the interface -.Fa ifp . -The -.Fa txflag -argument specifies whether the frame is being received or transmitted. -A value of 0 indicates that the frame is being received and should -therefore be decrypted; a non-zero value indicates that the frame -is being transmitted -and should be encrypted. -.\" -.Sh IMPLEMENTATION NOTES -The -.Fn ieee80211_wep_crypt -function stores its IV in the interface's embedded -.Vt struct ieee80211com -instance. -.Sh SEE ALSO -.Xr awi 4 , -.Xr wi 4 , -.Xr arc4random 9 , -.Xr ieee80211 9 , -.Xr ifnet 9 -.Sh HISTORY -The -.Nm ieee80211 -series of functions first appeared in -.Nx 1.5 , -and were later ported to -.Fx 4.6 . -.Sh AUTHORS -.An -nosplit -This manual page was written by -.An Bruce M. Simpson Aq bms@FreeBSD.org +.Nm net80211 +layer will handle allocating cipher and driver resources to support the key. +.Pp +Once a key is allocated it's contents can be set using +.Fn ieee80211_crypto_setkey +and deleted with +.Fn ieee80211_crypto_delkey +(with any cipher and driver resources reclaimed). +.Pp +.Fn ieee80211_crypto_delglobalkeys +is used to reclaim all keys in the global key table for a vap; it +typically is used only within the +.Nm net80211 +layer. +.Pp +.Fn ieee80211_crypto_reload_keys +handles hardware key state reloading from software key state, such +as required after a suspend/resume cycle. +.Sh DRIVER CRYPTO SUPPORT +Drivers identify ciphers they have hardware support for through the +.Vt ic_cryptocaps +field of the +.Vt ieee80211com +structure. +If hardware support is available then a driver should also fill in the +.Dv iv_key_alloc , +.Dv iv_key_set , and -.An Darron Broad Aq darron@kewl.org . +.Dv iv_key_delete +methods of each +.Vt ieee80211vap +created for use with the device. +In addition the methods +.Dv iv_key_update_begin +and +.Dv iv_key_update_end +can be setup to handle synchronization requirements +for updating hardware key state. +.Pp +When +.Nm net80211 +allocates a software key and the driver can accelerate the +cipher operations the +.Dv iv_key_alloc +method will be invoked. +Drivers may return a token that is associated with outbound traffic +(for use in encrypting frames). +Otherwise, e.g. if hardware resources are not available, the driver will +not return a token and +.Nm net80211 +will arrange to do the work in software and pass frames +to the driver that are already prepared for transmission. +.Pp +For receive, drivers mark frames with the +.Dv M_WEP +mbuf flag to indicate the hardware has decrypted the payload. +If frames have the +.Dv IEEE80211_FC1_WEP +bit marked in their 802.11 header and are not tagged with +.Dv M_WEP +then decryption is done in software. +For more complicated scenarios the software key state is consulted; e.g. +to decide if Michael verification needs to be done in software after +the hardware has handled TKIP decryption. +.Pp +Drivers that manage complicated key data structures, e.g. faulting +software keys into a hardware key cache, can safely manipulate software +key state by bracketing their work with calls to +.Fn ieee80211_key_update_begin +and +.Fn ieee80211_key_update_end . +These calls also synchronize hardware key state update +when receive traffic is active. +.Sh SEE ALSO +.Xr ioctl 2 , +.Xr wlan_ccmp 4 , +.Xr wlan_tkip 4 , +.Xr wlan_wep 4 . diff --git a/share/man/man9/ieee80211_ddb.9 b/share/man/man9/ieee80211_ddb.9 new file mode 100644 index 00000000000..19232a78d34 --- /dev/null +++ b/share/man/man9/ieee80211_ddb.9 @@ -0,0 +1,72 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" 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 August 4, 2009 +.Dt IEEE80211_DDB 9 +.Os +.Sh NAME +.Nm ieee80211_ddb +.Nd 802.11 ddb support +.Sh SYNOPSIS +.Bd -ragged +.Cd options DDB +.Ed +.Pp +.Bd -ragged +.Cd show vap [addr] +.Cd show all vaps +.Cd show com [addr] +.Cd show sta [addr] +.Cd show statab [addr] +.Cd show mesh [addr] +.Ed +.Sh DESCRIPTION +The +.Nm net80211 +layer includes +.Xr ddb 4 +support for displaying important data structures. +This is especially important because wireless applications are often +built for embedded environments where cross-machine or post-mortem +debugging facilities like +.Xr kgdb 1 +infeasible. +.Pp +The most commonly used command is +.Bd -literal -offset indent +show all vaps/a +.Ed +.Pp +which dumps the contents of all +.Vt ieee80211vap , +.Vt ieee80211com , +and +.Vt ieee80211_node +data structures in the system. +.Sh SEE ALSO +.Xr ddb 4 , +.Xr ieee80211 9 . diff --git a/share/man/man9/ieee80211_input.9 b/share/man/man9/ieee80211_input.9 index 21c9f253c2e..a0829eefcce 100644 --- a/share/man/man9/ieee80211_input.9 +++ b/share/man/man9/ieee80211_input.9 @@ -25,89 +25,92 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.\" $Id: ieee80211_input.9,v 1.6 2004/03/04 12:33:27 bruce Exp $ .\" -.Dd March 2, 2004 +.Dd August 4, 2009 .Dt IEEE80211_INPUT 9 .Os .Sh NAME -.Nm ieee80211_input , ieee80211_decap , ieee80211_recv_mgmt +.Nm ieee80211_input .Nd software 802.11 stack input functions .Sh SYNOPSIS .In net80211/ieee80211_var.h -.In net80211/ieee80211_proto.h .Ft void .Fo ieee80211_input -.Fa "struct ifnet *ifp" "struct mbuf *m" "struct ieee80211_node *ni" -.Fa "int rssi" "u_int32_t rstamp" +.Fa "struct ieee80211_node *" +.Fa "struct mbuf *" +.Fa "int rssi" +.Fa "int noise" .Fc -.Ft struct mbuf * -.Fn ieee80211_decap "struct ifnet *ifp" "struct mbuf *m" .Ft void -.Fo ieee80211_recv_mgmt -.Fa "struct ieee80211com *ic" "struct mbuf *m0" "struct ieee80211_node *ni" -.Fa "int subtype" "int rssi" "u_int32_t rstamp" +.Fo ieee80211_input_all +.Fa "struct ieee80211com *" +.Fa "struct mbuf *" +.Fa "int rssi" +.Fa "int noise" .Fc .Sh DESCRIPTION -These -functions process received 802.11 frames. -.Pp -.\" The +.Nm net80211 +layer that supports 802.11 device drivers requires that +receive processing be single-threaded. +Typically this is done using a dedicated driver +.Xr taskqueue 9 +thread. .Fn ieee80211_input -function takes an mbuf chain -.Fa m -containing a complete 802.11 frame from the driver -.Fa ifp -and passes it to the software 802.11 stack for input processing. -The -.Fa ni -argument specifies an instance of -.Vt struct ieee80211_node -(which may be driver-specific) representing the node from which the -frame was received. -The arguments -.Fa rssi and -.Fa stamp -are typically derived from on-card data structures; they are used for -recording the signal strength and time received of the frame respectively. +.Fn ieee80211_input_all +process received 802.11 frames and are designed +for use in that context; e.g. no driver locks may be held. .Pp -.\" -The -.Fn ieee80211_decap -function performs decapsulation of the 802.11 frame in the mbuf chain -.Fa m -received by the device -.Fa ifp , -taking the form of the 802.11 address fields into account; -the structure of 802.11 addresses vary according to the intended -source and destination of the frame. -It is typically called from within -.Fn ieee80211_input . +The frame passed up in the +.Vt mbuf +must have the 802.11 protocol header at the front; all device-specific +information and/or PLCP must be removed. +Any CRC must be stripped from the end of the frame. +The 802.11 protocol header should be 32-bit aligned for +optimal performance but receive processing does not require it. +If the frame holds a payload and that is not aligned to a 32-bit +boundary then the payload will be re-aligned so that it is suitable +for processing by protocols such as +.Xr ip 4 . +.Pp +If a device (such as +.Xr ath 4 ) +inserts padding after the 802.11 header to align +the payload to a 32-bit boundary the +.Dv IEEE80211_C_DATAPAD +capability must be set. +Otherwise header and payload are assumed contiguous in the mbuf chain. +.Pp +If a received frame must pass +through the A-MPDU receive reorder buffer then the mbuf +must be marked with the +.Dv M_AMPDU +flag. +Note that for the moment this is required of all frames received from +a station and TID where a Block ACK stream is active, not just A-MPDU +aggregates. +It is sufficient to check for +.Dv IEEE80211_NODE_HT +in the +.Vt ni_flags +of the station's node table entry, any frames that do not require reorder +processing will be dispatched with only minimal overhead. .Pp -.\" The -.Fn ieee80211_recv_mgmt -performs input processing for 802.11 management frames. -It is typically called from within -.Fn ieee80211_input . -.\" +.Vt rssi +parameter is the Receive Signal Strength Indication of the frame +measured in 0.5dBm units relative to the noise floor. +The +.Vt noise +parameter is the best approximation of the noise floor in +dBm units at the time the frame was received. +RSSI and noise are used by the +.Nm net80211 +layer to make scanning and roaming decisions in station mode +and to do auto channel selection for hostap and similar modes. +Otherwise the values are made available to user applications +(with the rssi presented as a filtered average over the last ten values +and the noise floor the last reported value). .Sh SEE ALSO -.Xr ieee80211 9 , -.Xr ifnet 9 -.Sh HISTORY -The -.Nm ieee80211 -series of functions first appeared in -.Nx 1.5 , -and were later ported to -.Fx 4.6 . -.Sh AUTHORS -.An -nosplit -This manual page was written by -.An Bruce M. Simpson Aq bms@FreeBSD.org -and -.An Darron Broad Aq darron@kewl.org . -.Sh BUGS -There is no netisr queue specifically for the software 802.11 stack yet. +.Xr ieee80211 9 . diff --git a/share/man/man9/ieee80211_ioctl.9 b/share/man/man9/ieee80211_ioctl.9 deleted file mode 100644 index 7f94bceba53..00000000000 --- a/share/man/man9/ieee80211_ioctl.9 +++ /dev/null @@ -1,92 +0,0 @@ -.\" -.\" Copyright (c) 2004 Bruce M. Simpson -.\" Copyright (c) 2004 Darron Broad -.\" 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$ -.\" $Id: ieee80211_ioctl.9,v 1.5 2004/03/04 12:33:27 bruce Exp $ -.\" -.Dd March 2, 2004 -.Dt IEEE80211_IOCTL 9 -.Os -.Sh NAME -.Nm ieee80211_cfgget , ieee80211_cfgset , ieee80211_ioctl -.Nd 802.11 interface ioctl commands -.Sh SYNOPSIS -.In net80211/ieee80211_var.h -.In net80211/ieee80211_proto.h -.In net80211/ieee80211_ioctl.h -.Ft int -.Fn ieee80211_cfgget "struct ifnet *ifp" "u_long cmd" "caddr_t data" -.Ft int -.Fn ieee80211_cfgset "struct ifnet *ifp" "u_long cmd" "caddr_t data" -.Ft int -.Fn ieee80211_ioctl "struct ifnet *ifp" "u_long cmd" "caddr_t data" -.Sh DESCRIPTION -These -functions are typically invoked by drivers in response to requests -for information or to change settings from the userland. -.Pp -.\" -The -.Fn ieee80211_cfgget -and -.Fn ieee80211_cfgset -functions implement a legacy interface for getting and setting 802.11 -interface attributes respectively. -.Pp -.\" -The -.Fn ieee80211_ioctl -function provides a default implementation of the -.Dv SIOCS80211 -and -.Dv SIOCG80211 -ifioctls commands for 802.11 drivers. -The call signature is identical to that of the -.Va if_ioctl -member found in -.Vt struct ifnet , -however, many drivers store attributes such as -.Dv IEEE80211_IOC_STATIONNAME -in the driver's private soft state structure, so driver writers may prefer -to use this as the catch-all in a switch statement to avoid code duplication. -.\" -.Sh SEE ALSO -.Xr ifconfig 8 , -.Xr ieee80211 9 , -.Xr ifnet 9 -.Sh HISTORY -The -.Nm ieee80211 -series of functions first appeared in -.Nx 1.5 , -and were later ported to -.Fx 4.6 . -.Sh AUTHORS -.An -nosplit -This manual page was written by -.An Bruce M. Simpson Aq bms@FreeBSD.org -and -.An Darron Broad Aq darron@kewl.org . diff --git a/share/man/man9/ieee80211_node.9 b/share/man/man9/ieee80211_node.9 index c9d142a31a3..59ae87095cb 100644 --- a/share/man/man9/ieee80211_node.9 +++ b/share/man/man9/ieee80211_node.9 @@ -25,269 +25,227 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.\" $Id: ieee80211_node.9,v 1.6 2004/03/04 12:33:27 bruce Exp $ .\" -.Dd July 4, 2004 +.Dd August 4, 2009 .Dt IEEE80211_NODE 9 .Os .Sh NAME -.Nm ieee80211_node_attach , -.Nm ieee80211_node_lateattach , -.Nm ieee80211_node_detach , -.Nm ieee80211_begin_scan , -.Nm ieee80211_next_scan , -.Nm ieee80211_create_ibss , -.Nm ieee80211_end_scan , -.Nm ieee80211_alloc_node , -.Nm ieee80211_dup_bss , -.Nm ieee80211_find_node , -.Nm ieee80211_lookup_node , -.Nm ieee80211_free_node , -.Nm ieee80211_free_allnodes , -.Nm ieee80211_timeout_nodes , -.Nm ieee80211_iterate_nodes +.Nm ieee80211_node .Nd software 802.11 stack node management functions .Sh SYNOPSIS .In net80211/ieee80211_var.h -.In net80211/ieee80211_proto.h -.In net80211/ieee80211_node.h -.Ft void -.Fn ieee80211_node_attach "struct ifnet *ifp" -.Ft void -.Fn ieee80211_node_lateattach "struct ifnet *ifp" -.Ft void -.Fn ieee80211_node_detach "struct ifnet *ifp" -.Ft void -.Fn ieee80211_begin_scan "struct ifnet *ifp" -.Ft void -.Fn ieee80211_next_scan "struct ifnet *ifp" -.Ft void -.Fo ieee80211_create_ibss -.Fa "struct ieee80211com *ic" "struct ieee80211_channel *chan" +.\" +.Ft struct ieee80211_node * +.Fo ieee80211_find_rxnode +.Fa "struct ieee80211com *" +.Fa "const struct ieee80211_frame_min *" .Fc -.Ft void -.Fn ieee80211_end_scan "struct ifnet *ifp" +.\" .Ft struct ieee80211_node * -.Fn ieee80211_alloc_node "struct ieee80211com *ic" "u_int8_t *macaddr" -.Ft struct ieee80211_node * -.Fn ieee80211_dup_bss "struct ieee80211com *ic" "u_int8_t *macaddr" -.Ft struct ieee80211_node * -.Fn ieee80211_find_node "struct ieee80211com *ic" "u_int8_t *macaddr" -.Ft struct ieee80211_node * -.Fo ieee80211_lookup_node -.Fa "struct ieee80211com *ic" "u_int8_t *macaddr" -.Fa "struct ieee80211_channel *chan" +.Fo ieee80211_find_rxnode_withkey +.Fa "struct ieee80211com *" +.Fa "const struct ieee80211_frame_min *" +.Fa "ieee80211_keyix" .Fc +.\" +.Ft struct ieee80211_node * +.Fn ieee80211_ref_node "struct ieee80211_node *" +.\" .Ft void -.Fn ieee80211_free_node "struct ieee80211com *ic" "struct ieee80211_node *ni" +.Fn ieee80211_unref_node "struct ieee80211_node *" +.\" .Ft void -.Fn ieee80211_free_allnodes "struct ieee80211com *ic" -.Ft void -.Fn ieee80211_timeout_nodes "struct ieee80211com *ic" +.Fn ieee80211_free_node "struct ieee80211_node *" +.\" .Ft void .Fo ieee80211_iterate_nodes -.Fa "struct ieee80211com *ic" "ieee80211_iter_func *f" "void *arg" +.Fa "struct ieee80211_node_table *" +.Fa "ieee80211_iter_func *f" +.Fa "void *arg" .Fc +.\" +.Ft void +.Fo ieee80211_dump_nodes +.Fa "struct ieee80211_node_table *" +.Fc +.\" +.Ft void +.Fo ieee80211_dump_node +.Fa "struct ieee80211_node *" +.Fc .Sh DESCRIPTION -These functions are used to manage node lists within the software -802.11 stack. -These lists are typically used for implementing host-mode AP functionality, -or providing signal quality information about neighbouring nodes. +The +.Nm net80211 +layer that supports 802.11 device drivers maintains a database of +peer stations called the +.Dq node table +in the +.Vt ic_sta +entry of the +.Vt ieee80211com +structure. +Station mode vaps create an entry for the access point +the station is associated to. +AP mode vaps create entries for associated stations. +Adhoc and mesh mode vaps create entries for neighbor stations. +WDS mode vaps create an entry for the peer station. +Stations for all vaps reside in the same table; each node +entry has a +.Vt ni_vap +field that identifies the vap that created it. +In some instances an entry is used by multiple vaps (e.g. for +dynamic WDS a station associated to an ap vap may also be the peer +of a WDS vap). .Pp -.\" +Node table entries are reference counted. +That is, there is a count of all long term references that determines +when an entry may be reclaimed. +References are held by every in-flight frame sent to a station to +insure the entry is not reclaimed while the frame is queued or otherwise +held by a driver. +Routines that lookup a table entry return a +.Dq held reference +(i.e. a pointer to a table entry with the reference count incremented). The -.Fn ieee80211_node_attach -function is called from -.Xr ieee80211_ifattach 9 -to initialize node database management callbacks for the interface -.Fa ifp -(specifically for memory allocation, node copying and node -signal inspection). -These functions may be overridden in special circumstances, -as long as this is done after calling -.Xr ieee80211_ifattach 9 -and prior to any other call which may allocate a node. -.Pp -.\" -The -.Fn ieee80211_node_lateattach -function initialises the -.Va ic_bss -node element of the interface -.Fa ifp -during -.Xr ieee80211_media_init 9 . -This late attachment is to account for certain special cases described under -.Fn ieee80211_node_attach . -.Pp -.\" -The -.Fn ieee80211_node_detach -function destroys all node database state associated with the interface -.Fa ifp , -and is usually called during device detach. -.Pp -.\" -The -.Fn ieee80211_begin_scan -function initialises the node database in preparation of an active -scan for an access point on the interface -.Fa ifp . -The scan begins on the next radio channel by calling -.Fn ieee80211_next_scan -internally. -The actual scanning for an access point is not automated; -the device driver itself only handles setting the radio frequency -of the card and stepping through the channels. -.Pp -.\" -The -.Fn ieee80211_next_scan -function is used to inform the -.Xr ieee80211 9 -layer that the interface -.Fa ifp -is now scanning for an access point on the next radio channel. -A device driver is expected to first call -.Fn ieee80211_begin_scan , -to initialize the node database, -then set the radio channel on the device; -then, after a certain time has elapsed (200ms for example), call -.Fn ieee80211_next_scan -to move to the next channel. -Typically, a callout is used to automate this process; see -.Xr callout_init 9 -for more information on how to use callouts. -.Pp -.\" -The -.Fn ieee80211_create_ibss -function sets up the net80211-specific portion of an interface's softc, -.Fa ic , -for use in IBSS mode. -.Pp -.\" -The -.Fn ieee80211_end_scan -function is called by -.Fn ieee80211_next_scan -when the state machine has peformed a full cycle of scanning on -all available radio channels. -Internally, -.Fn ieee80211_end_scan -will inspect the node cache associated with the interface -.Fa ifp -for suitable access points found during scanning, and associate with one, -should the parameters of the node match those of the configuration -requested from userland. -.Pp -.\" -The -.Fn ieee80211_alloc_node -function allocates an instance of -.Vt "struct ieee80211_node" -for a node having the MAC address -.Fa macaddr , -and associates it with the interface -.Fa ic . -If the allocation is successful, the node structure is initialised by -.Fn ieee80211_setup_node ; -otherwise, -.Dv NULL -is returned. -.Pp -.\" -The -.Fn ieee80211_dup_bss -function is similar to -.Fn ieee80211_alloc_node , -but is instead used to create a node database entry for the BSSID -.Fa macaddr -associated with the interface -.Fa ic . -If the allocation is successful, the node structure is initialised by -.Fn ieee80211_setup_node ; -otherwise, -.Dv NULL -is returned. -.Pp -.\" -The -.Fn ieee80211_find_node -function will iterate through the node list associated with the interface -.Fa ic , -searching for a node entry which matches -.Fa macaddr . -If the entry is found, its reference count is incremented, and -a pointer to the node is returned; otherwise, -.Dv NULL -will be returned. -.Pp -.\" -The -.Fn ieee80211_lookup_node -function is similar to -.Fn ieee80211_find_node , -with an additional argument -.Fa chan -which is used to specify a channel for the match. -If the entry is found, its reference count is incremented, and -a pointer to the node is returned; otherwise, -.Dv NULL -will be returned. -.Pp -.\" -The -.Fn ieee80211_free_node -function will remove the node -.Fa ni -from the node database entries associated with the interface -.Fa ic , -and free any memory associated with the node. -This private method can be overridden in -.Fn ieee80211_node_attach . -.\" -.Pp -The -.Fn ieee80211_free_allnodes -function will iterate through the node list calling -.Fn ieee80211_free_node -for all nodes associated with the interface -.Fa ic . -.Pp -.\" -The -.Fn ieee80211_timeout_nodes -checks if the inactivity timer of each node associated with the interface -.Fa ic -has exceeded the pre-defined constant -.Dv IEEE80211_INACT_MAX . -If so, then the node is freed, after sending a deauthentication message. -.Pp -.\" -The -.Fn ieee80211_iterate_nodes -function will call the user-defined callback function -.Fa f -for all nodes in the node database associated with the interface -.Fa ic . -The callback is invoked with the with the user-supplied value -.Fa arg -and a pointer to the current node. -.\" -.Sh SEE ALSO -.Xr ieee80211 9 , -.Xr ifnet 9 -.Sh HISTORY -The -.Nm ieee80211 -series of functions first appeared in -.Nx 1.5 , -and were later ported to -.Fx 4.6 . -.Sh AUTHORS -.An -nosplit -This manual page was written by -.An Bruce M. Simpson Aq bms@FreeBSD.org +.Fn ieee80211_ref_node and -.An Darron Broad Aq darron@kewl.org . +.Fn ieee80211_unref_node +calls explicitly increment/decrement the reference count of a node, +but are rarely used. +Instead most callers use +.Fn ieee80211_free_node +to release a reference and, if the count goes to zero, reclaim the +table entry. +.Pp +The station table and its entries are exposed to drivers in several ways. +Each frame transmitted to a station includes a reference to the +associated node in the +.Vt m_pkthdr.rcvif +field. +This reference must be reclaimed by the driver when transmit processing +is done. +For each frame received the driver must lookup the table entry to +use in dispatching the frame +.Dq up the stack . +This lookup implicitly obtains a reference to the table entry and +the driver must reclaim the reference when frame processing is completed. +Otherwise drivers frequently inspect the contents of the +.Vt iv_bss +node when handling state machine changes as important information +is maintained in the data structure. +.Pp +The node table is opaque to drivers. +Entries may be looked up using one of the pre-defined API's or the +.Fn ieee80211_iterate_nodes +call may be used to iterate through all entries to do per-node +processing or implement some non-standard search mechanism. +Note that +.Fn ieee80211_iterate_nodes +is single-threaded per-device +and the effort processing involved is fairly +substantial so it should be used carefully. +.Pp +Two routines are provided to print the contents of nodes to the console +for debugging: +.Fn ieee80211_dump_node +displays the contents of a single node while +.Fn ieee80211_dump_nodes +displays the contents of the specified node table. +Nodes may also be displayed using +.Xr ddb 9 +with the +.Dq show node +directive and the station node table can be displayed with +.Dq show statab . +.Sh DRIVER PRIVATE STATE +Node data structures may be extended by the driver to include +driver-private state. +This is done by overriding the +.Vt ic_node_alloc +method used to allocate a node table entry. +The driver method must allocate a structure that is an extension +of the +.Vt ieee80211_node +structure. +For example the +.Xr iwi 4 +driver defines a private node structure as: +.Bd -literal -offset indent +struct iwi_node { + struct ieee80211_node in_node; + int in_station; +}; +.Ed +.Pp +and then provides a private allocation routine that does this: +.Bd -literal -offset indent +static struct ieee80211_node * +iwi_node_alloc(struct ieee80211vap *vap, + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct iwi_node *in; + + in = malloc(sizeof (struct iwi_node), M_80211_NODE, + M_NOWAIT | M_ZERO); + if (in == NULL) + return NULL; + in->in_station = -1; + return &in->in_node; +} +.Ed +.Pp +Note that when reclaiming a node allocated by the driver the +.Dq parent method +must be called to ensure +.Nm net80211 +state is reclaimed; for example: +.Bd -literal -offset indent +static void +iwi_node_free(struct ieee80211_node *ni) +{ + struct ieee80211com *ic = ni->ni_ic; + struct iwi_softc *sc = ic->ic_ifp->if_softc; + struct iwi_node *in = (struct iwi_node *)ni; + + if (in->in_station != -1) + free_unr(sc->sc_unr, in->in_station); + sc->sc_node_free(ni); /* invoke net80211 free handler */ +} +.Ed +.Pp +Beware that care must be taken to avoid holding references that +might cause nodes from being reclaimed. +.Nm net80211 +will reclaim a node when the last reference is reclaimed in +its data structures. +However if a driver holds additional references then +.Nm net80211 +will not recognize this and table entries will not be reclaimed. +Such references should not be needed if the driver overrides the +.Vt ic_node_cleanup +and/or +.Vt ic_node_free +methods. +.Sh KEY TABLE SUPPORT +Node table lookups are typically done using a hash of the stations' +mac address. +When receiving frames this is sufficient to find the node table entry +for the transmitter. +But some devices also identify the sending station in the device +state received with each frame and this data can be used to optimize +lookups on receive using a companion table called the +.Dq keytab . +This table records a separate node table reference that can be fetched +without any locking using the table index. +This logic is handled with the +.Fn ieee80211_find_rxnode_withkey +call: if a keytab entry is found using the specified index then it is +returned directly; otherwise a normal lookup is done and the keytab +entry is written using the specified index. +If the specified index is +.Dv IEEE80211_KEYIX_NONE +then a normal lookup is done without a table update. +.Sh SEE ALSO +.Xr ddb 9 +.Xr ieee80211 9 , +.Xr ieee80211_proto 9 , diff --git a/share/man/man9/ieee80211_output.9 b/share/man/man9/ieee80211_output.9 index f553c4f3783..c2f9667eb4a 100644 --- a/share/man/man9/ieee80211_output.9 +++ b/share/man/man9/ieee80211_output.9 @@ -27,125 +27,168 @@ .\" $FreeBSD$ .\" $Id: ieee80211_output.9,v 1.5 2004/03/04 12:31:18 bruce Exp $ .\" -.Dd March 2, 2004 +.Dd August 4, 2009 .Dt IEEE80211_OUTPUT 9 .Os .Sh NAME -.Nm ieee80211_encap , ieee80211_add_rates , -.Nm ieee80211_add_xrates , ieee80211_send_mgmt +.Nm ieee80211_output .Nd software 802.11 stack output functions .Sh SYNOPSIS .In net80211/ieee80211_var.h -.In net80211/ieee80211_proto.h -.Ft struct mbuf * -.Fo ieee80211_encap -.Fa "struct ifnet *ifp" "struct mbuf *m" "struct ieee80211_node **pni" -.Fc -.Ft u_int8_t * -.Fn ieee80211_add_rates "u_int8_t *frm" "const struct ieee80211_rateset *rs" -.Ft u_int8_t * -.Fn ieee80211_add_xrates "u_int8_t *frm" "const struct ieee80211_rateset *rs" +.\" .Ft int -.Fo ieee80211_send_mgmt -.Fa "struct ieee80211com *ic" "struct ieee80211_node *ni" "int type" "int arg" +.Fn M_WME_GETAC "struct mbuf *" +.\" +.Ft int +.Fn M_SEQNO_GET "struct mbuf *" +.\" +.Ft struct ieee80211_key * +.Fn ieee80211_crypto_encap "struct ieee80211_node *" "struct mbuf *" +.\" +.Ft void +.Fo ieee80211_process_callback +.Fa struct ieee80211_node * +.Fa struct mbuf * +.Fa int .Fc .Sh DESCRIPTION -These functions handle the encapsulation and transmission of 802.11 frames -within the software 802.11 stack. -.Pp The -.Fn ieee80211_encap -function encapsulates an outbound data frame contained within the -mbuf chain -.Fa m -from the interface -.Fa ifp . -The argument -.Fa *pni -is a reference to the destination node. +.Nm net80211 +layer that supports 802.11 device drivers handles most of the +work required to transmit frames. +Drivers usually receive fully-encapsulated 802.11 frames that +have been classified and assigned a transmit priority; +all that is left is to do +crypto encapsulation, +prepare any hardware-specific state, +and +push the packet out to the device. +Outbound frames are either generated by the +.Nm net80211 +layer (e.g. management frames) or are passed down +from upper layers through the +.Xr ifnet 9 +transmit queue. +Data frames passed down for transmit flow through +.Nm net80211 +which handles aggregation, 802.11 encapsulation, and then +dispatches the frames to the driver through it's transmit queue. .Pp -If the function is successful, the mbuf chain is updated with the -802.11 frame header prepended, and a pointer to the head of the chain -is returned. -If an error occurs, -.Dv NULL -will be returned, and -.Fa *pni -is also set to -.Dv NULL . -The caller is responsible for freeing the node reference if -.Fa *pni -is -.Pf non- Dv NULL -on return. -The convention is that -.Va ic_bss -is not reference counted; the caller is responsible for maintaining this -reference count. +There are two control paths by which frames reach a driver for transmit. +Data packets are queued to the device's +.Vt if_snd +queue and the driver's +.Vt if_start +method is called. +Other frames are passed down using the +.Vt ic_raw_xmit +method without queueing (unless done by the driver). +The raw transmit path may include data frames from user applications +that inject them through +.Xr bpf 4 +and NullData frames generated by +.Nm net80211 +to probe for idle stations (when operating as an access point). .Pp -.\" +.Nm net80211 +handles all state-related bookkeeping and management for the handling +of data frames. +Data frames are only transmit for a vap in the +.Dv IEEE80211_S_RUN +state; there is no need, for example, to check for frames sent down +when CAC or CSA is active. +Similarly, +.Nm net80211 +handles activities such as background scanning and power save mode, +frames will not be sent to a driver unless it is operating on the +BSS channel will +.Dq full power . +.Pp +All frames passed to a driver for transmit hold a reference to a +node table entry in the +.Vt m_pkthdr.rcvif +field. +The node is associated with the frame destination. +Typically it is the receiver's entry but in some situations it may be +a placeholder entry or the +.Dq next hop station +(such as in a mesh network). +In all cases the reference must be reclaimed with +.Fn ieee80211_free_node +when the transmit work is completed. +The rule to remember is: +.Nm net80211 +passes responsibility for the +.Vt mbuf +and +.Dq node reference +to the driver with each frame it hands off for transmit. +.Sh PACKET CLASSIFICATION +All frames passed by +.Nm net80211 +for transmit are assigned a priority based on any vlan tag +assigned to the receiving station and/or any Diffserv setting +in an IP or IPv6 header. +If both vlan and Diffserv priority are present the higher of the +two is used. +If WME/WMM is being used then any ACM policy (in station mode) is +also enforced. +The resulting AC is attached to the mbuf and may be read back using the +.Fn M_WME_GETAC +macro. +.Pp +PAE/EAPOL frames are tagged with an +.Dv M_EAPOL +mbuf flag; drivers should transmit them with care, usually by +using the transmit rate for management frames. +Multicast/broadcast frames are marked with the +.Dv M_MCAST +mbuf flag. +Frames coming out of a station's power save queue and that have +more frames immediately following are marked with the +.Dv M_MORE_DATA +mbuf flag. +Such frames will be queued consecutively in the driver's +.Vt if_snd +queue and drivers should preserve the ordering when passing +them to the device. +.Sh FRAGMENTED FRAMES The -.Fn ieee80211_add_rates -utility function is used to add the rate set element -.Fa *rs -to the frame -.Fa frm . -A pointer to the location in the buffer after the addition of the rate set -is returned. -It is typically used when constructing management frames from within the -software 802.11 stack. -.Pp -.\" -The -.Fn ieee80211_add_xrates -utility function is used to add the extended rate set element -.Fa *rs -to the frame -.Fa frm . -A pointer to the location in the buffer after the addition of the rate set -is returned. -It is typically used when constructing management frames from within the -software 802.11 stack in 802.11g mode. -.Pp -.\" -The -.Fn ieee80211_send_mgmt -function transmits a management frame on the interface -.Fa ic -to the destination node -.Fa ni -of type -.Fa type . -.Pp -The argument -.Fa arg -specifies either a sequence number for authentication operations, -a status code for [re]association operations, -or a reason for deauthentication and deassociation operations. -.Pp -Nodes other than -.Va ic_bss -have their reference count incremented to reflect their use for an -indeterminate amount of time. -This reference is freed when the function returns. -.Pp -The function returns 0 if successful; if temporary buffer space is not -available, the function returns -.Er ENOMEM . -.\" +.Nm net80211 +layer will fragment data frames according to the setting of +.Vt iv_fragthreshold +if a driver marks the +.Dv IEEE80211_C_TXFRAG +capability. +Fragmented frames are placed +in the devices transmit queue with the fragments chained together with +.Vt m_nextpkt . +Each frame is marked with the +.Dv M_FRAG +mbuf flag, and the first and last are marked with +.Dv M_FIRSTFRAG +and +.Dv M_LASTFRAG , +respectively. +Drivers are expected to process all fragments or none. +.Sh TRANSMIT CALLBACKS +Frames sent by +.Nm net80211 +may be tagged with the +.Dv M_TXCB +mbuf flag to indicate a callback should be done +when their transmission completes. +The callback is done using +.Fn ieee80211_process_callback +with the last parameter set to a non-zero value if an error occurred +and zero otherwise. +Note +.Nm net80211 +understands that drivers may be incapable of determining status; +a device may not report if an ACK frame is received and/or a device may queue +transmit requests in its hardware and only report status on whether +the frame was successfully queued. .Sh SEE ALSO +.Xr bpf 4 .Xr ieee80211 9 , .Xr ifnet 9 -.Sh HISTORY -The -.Nm ieee80211 -series of functions first appeared in -.Nx 1.5 , -and were later ported to -.Fx 4.6 . -.Sh AUTHORS -.An -nosplit -This manual page was written by -.An Bruce M. Simpson Aq bms@FreeBSD.org -and -.An Darron Broad Aq darron@kewl.org . diff --git a/share/man/man9/ieee80211_proto.9 b/share/man/man9/ieee80211_proto.9 index 0de486451d3..70a3572e8f8 100644 --- a/share/man/man9/ieee80211_proto.9 +++ b/share/man/man9/ieee80211_proto.9 @@ -1,6 +1,5 @@ .\" -.\" Copyright (c) 2004 Bruce M. Simpson -.\" Copyright (c) 2004 Darron Broad +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -25,51 +24,218 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.\" $Id: ieee80211_proto.9,v 1.5 2004/03/04 12:33:27 bruce Exp $ .\" -.Dd March 2, 2004 +.Dd August 4, 2009 .Dt IEEE80211_PROTO 9 .Os .Sh NAME -.Nm ieee80211_proto_attach , -.Nm ieee80211_proto_detach , -.Nm ieee80211_print_essid , -.Nm ieee80211_dump_pkt , -.Nm ieee80211_fix_rate , .Nm ieee80211_proto -.Nd software 802.11 stack protocol helper functions +.Nd 802.11 state machine support .Sh SYNOPSIS .In net80211/ieee80211_var.h -.In net80211/ieee80211_proto.h +.Pp .Ft void -.Fn ieee80211_proto_attach "struct ifnet *ifp" +.Fn ieee80211_start_all "struct ieee80211com *" .Ft void -.Fn ieee80211_proto_detach "struct ifnet *ifp" +.Fn ieee80211_stop_all "struct ieee80211com *" .Ft void -.Fn ieee80211_print_essid "u_int8_t *essid" "int len" +.Fn ieee80211_suspend_all "struct ieee80211com *" .Ft void -.Fn ieee80211_dump_pkt "u_int8_t *buf" "int len" "int rate" "int rssi" +.Fn ieee80211_resume_all "struct ieee80211com *" +.Pp +.Dv enum ieee80211_state ; .Ft int -.Fo ieee80211_fix_rate -.Fa "struct ieee80211com *ic" "struct ieee80211_node *ni" "int flags" -.Fc +.Fn ieee80211_new_state "struct ieee80211vap *" "enum ieee80211_state" "int" +.Pp +.Ft void +.Fn ieee80211_wait_for_parent "struct ieee80211com *" .Sh DESCRIPTION -These -functions are helper functions used throughout the software 802.11 protocol -stack. +The +.Nm net80211 +layer that supports 802.11 device drivers uses a state machine +to control operation of vaps. +These state machines vary according to the vap operating mode. +Station mode state machines follow the 802.11 MLME states +in the protocol specification. +Other state machines are simpler and reflect operational work +such as scanning for a BSS or automatically selecting a channel to +operate on. +When multiple vaps are operational the state machines are used to +coordinate operation such as choosing a channel. +The state machine mechanism also serves to bind the +.Nm net80211 +layer to a driver; this is described more below. +.Pp +The following states are defined for state machines: +.Bl -tag -width IEEE80211_S_ASSOC +.It Dv IEEE80211_S_INIT +Default/initial state. +A vap in this state should not hold any dynamic state (e.g. entries +for associated stations in the node table). +The driver must quiesce the hardware; e.g. there should be no +interrupts firing. +.It Dv IEEE80211_S_SCAN +Scanning for a BSS or choosing a channel to operate on. +Note that scanning can also take place in other states (e.g. when +background scanning is active); this state is entered when +initially bringing a vap to an operational state or after an +event such as a beacon miss (in station mode). +.It Dv IEEE80211_S_AUTH +Authenticating to an access point (in station mode). +This state is normally reached from +.Dv IEEE80211_S_SCAN +after selecting a BSS, but may also be reached from +.Dv IEEE80211_S_ASSOC +or +.Dv IEEE80211_S_RUN +if the authentication handshake fails. +.It Dv IEEE80211_S_ASSOC +Associating to an access point (in station mode). +This state is reached from +.Dv IEEE80211_S_AUTH +after successfully authenticating or from +.Dv IEEE80211_S_RUN +if a DisAssoc frame is received. +.It Dv IEEE80211_S_CAC +Doing Channel Availability Check (CAC). +This state is entered only when DFS is enabled and the channel selected +for operation requires CAC. +.It Dv IEEE80211_S_RUN +Operational. +In this state a vap can transmit data frames, accept requests for +stations associating, etc. +Beware that data traffic is also gated by whether the associated +.Dq port +is authorized. +When WPA/802.11i/802.1x is operational authorization may happen separately; +e.g. in station mode +.Xr wpa_supplicant 8 +must complete the handshakes and plumb the necessary keys before a port +is authorized. +In this state a BSS is operational and associated state is valid and may +be used; e.g. +.Vt ic_bss +and +.Vt ic_bsschan +are guaranteed to be usable. +.It Dv IEEE80211_S_CSA +Channel Switch Annoucememnt (CSA) is pending. +This state is reached only from +.Dv IEEE80211_S_RUN +when either a CSA is received from an access point (in station mode) +or the local station is preparing to change channel. +In this state traffic may be muted depending on the Mute setting in the CSA. +.It Dv IEEE80211_S_SLEEP +Asleep to save power (in station mode). +This state is reached only from +.Dv IEEE80211_S_RUN +when power save operation is enabled and the local station is deemed +sufficiently idle to enter low power mode. +.El +.Pp +Note that states are ordered (as shown above); +e.g. a vap must be in the +.Dv IEEE80211_S_RUN +or +.Dq greater +before it can transmit frames. +Certain +.Nm net80211 +data are valid only in certain states; e.g. the +.Vt iv_bsschan +that specifies the channel for the operating BSS should never be used +except in +.Dv IEEE80211_S_RUN +or greater. +.Sh STATE CHANGES +State machine changes are typically handled internal to the +.Nm net80211 +layer in response to +.Xr ioctl 2 +requests, received frames, or external events such as a beacon miss. +The +.Fn ieee80211_new_state +function is used to initiate a state machine change on a vap. +The new state and an optional argument are supplied. +The request is initially processed to handle coordination of multiple vaps. +For example, only one vap at a time can be scanning, if multiple vaps +request a change to +.Dv IEEE80211_S_SCAN +the first will be permitted to run and the others will be +.Em deferred +until the scan operation completes at which time the selected channel +will be adopted. +Similarly +.Nm net80211 +handles coordination of combinations of vaps such as an AP and station vap +where the station may need to roam to follow the AP it is associated to +(dragging along the AP vap to the new channel). +Another important coordination is the handling of +.Dv IEEE80211_S_CAC +and +.Dv IEEE80211_S_CSA . +No more than one vap can ever be actively changing state at a time. +In fact +.Nm net80211 +single-threads the state machine logic in a dedicated +.Xr taskqueue 9 +thread that is also used to synchronize work such as scanning and +beacon miss handling. +.Pp +After multi-vap scheduling/coordination is done the per-vap +.Vt iv_newstate +method is called to carry out the state change work. +Drivers use this entry to setup private state and then dispatch +the call to the +.Nm net80211 +layer using the previously defined method pointer (in OOP-parlance they +call the +.Dq super method +). +.Pp +.Nm net80211 +handles two state changes specially. +On transition to +.Dv IEEE80211_S_RUN +the +.Dv IFF_DRV_OACTIVE +bit on the vap's transmit queue is cleared so traffic can flow. +On transition to +.Dv IEEE80211_S_INIT +any state in the scan cache associated with the vap is flushed +and any frames pending on the transmit queue are flushed. +.Sh DRIVER INTEGRATION +Drivers are expected to override the +.Vt iv_newstate +method to interpose their own code and handle setup work required +by state changes. +Otherwise drivers must call +.Fn ieee80211_start_all +in response to being marked up through an +.Dv SIOCSIFFLAGS +ioctl request and they should use +.Fn ieee80211_suspend_all +and +.Fn ieee80211_resume_all +to implement suspend/resume support. +.Pp +There is also an +.Fn ieee80211_stop_all +call to force all vaps to an +.Dv IEEE80211_S_INIT +state but this should not be needed by a driver; control is usually +handled by +.Nm net80211 +or, in the case of card eject or vap destroy, +work will be initiated outside the driver. .Sh SEE ALSO +.Xr ioctl 2 .Xr ieee80211 9 , .Xr ifnet 9 +.Xr taskqueue 9 +.Xr wpa_supplicant 8 .Sh HISTORY -The +The state machine concept was part of the original .Nm ieee80211 -series of functions first appeared in +code base that first appeared in .Nx 1.5 , -and were later ported to -.Fx 4.6 . -.Sh AUTHORS -.An -nosplit -This manual page was written by -.An Bruce M. Simpson Aq bms@FreeBSD.org -and -.An Darron Broad Aq darron@kewl.org . diff --git a/share/man/man9/ieee80211_radiotap.9 b/share/man/man9/ieee80211_radiotap.9 index 7375eec9f2d..092912fc39e 100644 --- a/share/man/man9/ieee80211_radiotap.9 +++ b/share/man/man9/ieee80211_radiotap.9 @@ -26,210 +26,280 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.\" $Id: ieee80211_radiotap.9,v 1.3 2004/03/04 11:38:52 bruce Exp $ .\" -.Dd March 17, 2008 +.Dd August 4, 2009 .Dt IEEE80211_RADIOTAP 9 .Os .Sh NAME .Nm ieee80211_radiotap -.Nd software 802.11 stack packet capture definitions +.Nd 802.11 device packet capture support .Sh SYNOPSIS .In net80211/ieee80211_var.h -.In net80211/ieee80211_ioctl.h -.In net80211/ieee80211_radiotap.h -.In net/bpf.h .\" +.Pp +.Ft void +.Fo ieee80211_radiotap_attach +.Fa "struct ieee80211com *" +.Fa "struct ieee80211_radiotap_header *th" +.Fa "int tlen" +.Fa "uint32_t tx_radiotap" +.Fa "struct ieee80211_radiotap_header *rh" +.Fa "int rlen" +.Fa "uint32_t rx_radiotap" +.Fc +.\" +.Ft int +.Fn ieee80211_radiotap_active_vap "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_radiotap_active "struct ieee80211com *" +.\" +.Ft void +.Fn ieee80211_radiotap_tx "struct ieee80211vap *" "struct mbuf *" .Sh DESCRIPTION The -.Nm -definitions provide a device-independent -.Xr bpf 4 -attachment for the -capture of information about 802.11 traffic which is not part of -the 802.11 frame structure. +.Nm net80211 +layer used by 802.11 drivers includes support for a device-independent +packet capture format called +.Nm radiotap +that is understood by tools such as +.Xr tcpdump 1 . +This facility is designed for capturing 802.11 traffic, +including information that is not part of the normal 802.11 frame structure. .Pp -Radiotap was designed to balance the desire for a capture format -that conserved CPU and memory bandwidth on embedded systems, -with the desire for a hardware-independent, extensible format -that would support the diverse capabilities of virtually all -802.11 -radios. -.Pp -These considerations led radiotap to settle on a format consisting of +Radiotap was designed to balance the desire for a hardware-independent, +extensible capture format against the need to +conserve CPU and memory bandwidth on embedded systems. +These considerations led to a format consisting of a standard preamble followed by an extensible bitmap indicating the presence of optional capture fields. +A +.Nm net80211 +device driver supporting +.Vt radiotap +defines two packed structures that it shares with +.Nm net80211 . +These structures embed an instance of a +.Vt ieee80211_radiotap_header +structure at the beginning, +with subsequent fields in the appropriate order, +and macros to set the bits of the +.Va it_present +bitmap to indicate which fields exist and are filled in by the driver. +This information is then supplied through the +.Fn ieee80211_radiotap_attach +call after a successful +.Fn ieee80211_ifattach +request. .Pp -The capture fields were packed into the header as compactly as possible, -modulo the requirements that they had to be packed swiftly, -with suitable alignment, in the same order as the bits indicating -their presence. +With radiotap setup, drivers just need to fill in per-packet +capture state for frames sent/received and dispatch capture state +in the transmit path (since control is not returned to the +.Nm net80211 +layer before the packet is handed to the device). +To minimize overhead this work should be done only when one +or more processes are actively capturing data; +this is checked with one of +.Fn ieee80211_radiotap_active_vap +and +.Fn ieee80211_radiotap_active . +In the transmit path capture work looks like this: .Pp -This typically includes information such as signal quality and -timestamps. -This information may be used by a variety of user agents, including -.Xr tcpdump 1 . -It is requested by using the -.Xr bpf 4 -data-link type -.Dv DLT_IEEE802_11_RADIO . -.Pp -.\" -Each frame using this attachment has the following header prepended to it: .Bd -literal -offset indent -struct ieee80211_radiotap_header { - u_int8_t it_version; /* set to 0 */ - u_int8_t it_pad; - u_int16_t it_len; /* entire length */ - u_int32_t it_present; /* fields present */ -} __attribute__((__packed__)); +if (ieee80211_radiotap_active_vap(vap)) { + ... /* record transmit state */ + ieee80211_radiotap_tx(vap, m); /* capture transmit event */ +} +.Ed +.Pp +While in the receive path capture is handled in +.Nm net80211 +but state must be captured before dispatching a frame: +.Pp +.Bd -literal -offset indent +if (ieee80211_radiotap_active(ic)) { + ... /* record receive state */ +} +\&... +ieee80211_input(...); /* packet capture handled in net80211 */ .Ed .Pp .\" -A device driver implementing -.Vt radiotap -typically defines a packed structure embedding an instance of -.Vt "struct ieee80211_radiotap_header" -at the beginning, -with subsequent fields in the appropriate order, -and a macro to set the bits of the -.Va it_present -bitmap to indicate which fields exist and are filled in by the driver. -.\" -.Pp -Radiotap headers are copied to the userland via a separate bpf attachment. -It is necessary for the driver to create this attachment after calling -.Xr ieee80211_ifattach 9 -by calling -.Fn bpfattach2 -with the data-link type set to -.Dv DLT_IEEE802_11_RADIO . -.Pp -.\" -When the the information is available, -usually immediately before a link-layer transmission or after a receive, -the driver copies it to the bpf layer using the -.Fn bpf_mtap2 -function. -.Pp -.\" -The following extension fields are defined for +The following fields are defined for .Vt radiotap , -in the order in which they should appear in the buffer copied to userland: +in the order in which they should appear in the buffer supplied +to +.Nm net80211 . .Bl -tag -width indent .It Dv IEEE80211_RADIOTAP_TSFT This field contains the unsigned 64-bit value, in microseconds, -of the MAC's 802.11 Time Synchronization Function timer, +of the MAC's 802.11 Time Synchronization Function (TSF). +In theory, for each received frame, this value is recorded when the first bit of the MPDU arrived at the MAC. -This field should be present for received frames only. +In practice, hardware snapshots the TSF otherwise and one cannot assume +this data is accurate without driver adjustment. .It Dv IEEE80211_RADIOTAP_FLAGS -This field contains a single unsigned 8-bit value, containing a bitmap -of flags specifying properties of the frame being transmitted or received. +This field contains a single unsigned 8-bit value, containing one or +more of these bit flags: +.Bl -tag -width indent +.It Dv IEEE80211_RADIOTAP_F_CFP +Frame was sent/received during the Contention Free Period (CFP). +.It Dv IEEE80211_RADIOTAP_F_SHORTPRE +Frame was sent/received with short preamble. +.It Dv IEEE80211_RADIOTAP_F_WEP +Frame was encrypted. +.It Dv IEEE80211_RADIOTAP_F_FRAG +Frame was an 802.11 fragment. +.It Dv IEEE80211_RADIOTAP_F_FCS +Frame contents includes the FCS. +.It Dv IEEE80211_RADIOTAP_F_DATAPAD +Frame contents potentially has padding between the 802.11 header and the +data payload to align the payload to a 32-bit boundary. +.It Dv IEEE80211_RADIOTAP_F_BADFCS +Frame was received with an invalid FCS. +.It Dv IEEE80211_RADIOTAP_F_SHORTGI +Frame was sent/received with Short Guard Interval. +.El .It Dv IEEE80211_RADIOTAP_RATE -This field contains a single unsigned 8-bit value, which is the data rate in -use in units of 500Kbps. +This field contains a single unsigned 8-bit value that is the data rate. +Legacy rates are in units of 500Kbps. +MCS rates (used on 802.11n/HT channels) have the high bit set and +the MCS in the low 7 bits. .It Dv IEEE80211_RADIOTAP_CHANNEL This field contains two unsigned 16-bit values. -The first value is the frequency upon which this PDU was transmitted -or received. -The second value is a bitmap containing flags which specify properties of -the channel in use. -These are documented within the header file, -.In net80211/ieee80211_radiotap.h . -.It Dv IEEE80211_RADIOTAP_FHSS -This field contains two 8-bit values. -This field should be present for frequency-hopping radios only. -The first byte is the hop set. -The second byte is the pattern in use. +The first value is the center frequency for the channel +the frame was sent/received on. +The second value is a bitmap containing flags that specify channel properties. +.Pp +This field is deprecated in favor of +.Dv IEEE80211_RADIOTAP_XCHANNEL +but may be used to save space in the capture file for legacy devices. +.\".It Dv IEEE80211_RADIOTAP_FHSS +.\"This field contains two 8-bit values. +.\"This field should be present only for frequency-hopping radios. +.\"The first byte is the hop set. +.\"The second byte is the pattern in use. .It Dv IEEE80211_RADIOTAP_DBM_ANTSIGNAL -This field contains a single signed 8-bit value, which indicates the +This field contains a single signed 8-bit value that indicates the RF signal power at the antenna, in decibels difference from 1mW. .It Dv IEEE80211_RADIOTAP_DBM_ANTNOISE -This field contains a single signed 8-bit value, which indicates the +This field contains a single signed 8-bit value that indicates the RF noise power at the antenna, in decibels difference from 1mW. -.It Dv IEEE80211_RADIOTAP_LOCK_QUALITY -This field contains a single unsigned 16-bit value, indicating the -quality of the Barker Code lock. -No unit is specified for this field. -There does not appear to be a standard way of measuring this at this time; -this quantity is often referred to as -.Dq "Signal Quality" -in some datasheets. -.It Dv IEEE80211_RADIOTAP_TX_ATTENUATION -This field contains a single unsigned 16-bit value, expressing transmit -power as unitless distance from maximum power set at factory calibration. -0 indicates maximum transmit power. -Monotonically nondecreasing with lower power levels. -.It Dv IEEE80211_RADIOTAP_DB_TX_ATTENUATION -This field contains a single unsigned 16-bit value, expressing transmit -power as decibel distance from maximum power set at factory calibration. -0 indicates maximum transmit power. -Monotonically nondecreasing with lower power levels. +.\".It Dv IEEE80211_RADIOTAP_LOCK_QUALITY +.\"This field contains a single unsigned 16-bit value, indicating the +.\"quality of the Barker Code lock. +.\"No unit is specified for this field. +.\"There does not appear to be a standard way of measuring this at this time; +.\"this quantity is often referred to as +.\".Dq "Signal Quality" +.\"in some datasheets. +.\".It Dv IEEE80211_RADIOTAP_TX_ATTENUATION +.\"This field contains a single unsigned 16-bit value, expressing transmit +.\"power as unitless distance from maximum power set at factory calibration. +.\"0 indicates maximum transmit power. +.\"Monotonically nondecreasing with lower power levels. +\.".It Dv IEEE80211_RADIOTAP_DB_TX_ATTENUATION +\."This field contains a single unsigned 16-bit value, expressing transmit +\."power as decibel distance from maximum power set at factory calibration. +\."0 indicates maximum transmit power. +\."Monotonically nondecreasing with lower power levels. .It Dv IEEE80211_RADIOTAP_DBM_TX_POWER Transmit power expressed as decibels from a 1mW reference. This field is a single signed 8-bit value. This is the absolute power level measured at the antenna port. .It Dv IEEE80211_RADIOTAP_ANTENNA -For radios which support antenna diversity, this field contains a single -unsigned 8-bit value specifying which antenna is being used to transmit -or receive this frame. -The first antenna is antenna 0. +This field contains a single unsigned 8-bit value that specifies +which antenna was used to transmit or receive the frame. +Antenna numbering is device-specific but typically the primary antenna has +the lowest number. +On transmit a value of zero may be seen which typically means +antenna selection is left to the device. .It Dv IEEE80211_RADIOTAP_DB_ANTSIGNAL -This field contains a single unsigned 8-bit value, which indicates the +This field contains a single unsigned 8-bit value that indicates the RF signal power at the antenna, in decibels difference from an arbitrary, fixed reference. .It Dv IEEE80211_RADIOTAP_DB_ANTNOISE -This field contains a single unsigned 8-bit value, which indicates the +This field contains a single unsigned 8-bit value that indicates the RF noise power at the antenna, in decibels difference from an arbitrary, fixed reference. -.It Dv IEEE80211_RADIOTAP_EXT -This bit is reserved for any future extensions to the -.Vt radiotap -structure. -It should not be used at this time. +.It Dv IEEE80211_RADIOTAP_XCHANNEL +This field containts four values: a 32-bit unsigned bitmap of +flags that describe the channel attributes, a 16-bit unsigned +freqeuncy in MHz (typically the channel center), an 8-bit +unsigned IEEE channel number, and a signed 8-bit value that +holds the maximum regulatory transmit power cap in .5 dBm +(8 bytes total). +Channel flags are defined in: +.In net80211/_ieee80211.h +(only a subset are found in +.In net80211/ieee80211_radiotap.h ). +This property supersedes +.Dv IEEE80211_RADIOTAP_CHANNEL +and is the only way to completely express all +channel attributes and the +mapping between channel freqeuncy and IEEE channel number. .El .Sh EXAMPLES -Radiotap header for the Cisco Aironet driver: +Radiotap receive definitions for the Intersil Prims driver: .Bd -literal -offset indent -struct an_rx_radiotap_header { - struct ieee80211_radiotap_header ar_ihdr; - u_int8_t ar_flags; - u_int8_t ar_rate; - u_int16_t ar_chan_freq; - u_int16_t ar_chan_flags; - u_int8_t ar_antsignal; - u_int8_t ar_antnoise; -} __attribute__((__packed__)); +#define WI_RX_RADIOTAP_PRESENT \\ + ((1 << IEEE80211_RADIOTAP_TSFT) \\ + (1 << IEEE80211_RADIOTAP_FLAGS) | \\ + (1 << IEEE80211_RADIOTAP_RATE) | \\ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \\ + (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \\ + (1 << IEEE80211_RADIOTAP_DB_ANTNOISE)) + +struct wi_rx_radiotap_header { + struct ieee80211_radiotap_header wr_ihdr; + uint64_t wr_tsf; + uint8_t wr_flags; + uint8_t wr_rate; + uint16_t wr_chan_freq; + uint16_t wr_chan_flags; + uint8_t wr_antsignal; + uint8_t wr_antnoise; +} __packed; .Ed .Pp -Bitmap indicating which fields are present in the above structure: +and transmit definitions for the Atheros driver: .Bd -literal -offset indent -#define AN_RX_RADIOTAP_PRESENT \\ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \\ - (1 << IEEE80211_RADIOTAP_RATE) | \\ - (1 << IEEE80211_RADIOTAP_CHANNEL) | \\ - (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \\ - (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) +#define ATH_TX_RADIOTAP_PRESENT ( \\ + (1 << IEEE80211_RADIOTAP_TSFT) | \\ + (1 << IEEE80211_RADIOTAP_FLAGS) | \\ + (1 << IEEE80211_RADIOTAP_RATE) | \\ + (1 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \\ + (1 << IEEE80211_RADIOTAP_ANTENNA) | \\ + (1 << IEEE80211_RADIOTAP_XCHANNEL) | \\ + 0) + +struct ath_tx_radiotap_header { + struct ieee80211_radiotap_header wt_ihdr; + uint64_t wt_tsf; + uint8_t wt_flags; + uint8_t wt_rate; + uint8_t wt_txpower; + uint8_t wt_antenna; + uint32_t wt_chan_flags; + uint16_t wt_chan_freq; + uint8_t wt_chan_ieee; + int8_t wt_chan_maxpow; +} __packed; .Ed .Sh SEE ALSO +.Xr tcpdump 1 , .Xr bpf 4 , .Xr ieee80211 9 .Sh HISTORY The .Nm definitions first appeared in -.Nx 1.5 , -and were later ported to -.Fx 4.6 . +.Nx 1.5 . .\" .Sh AUTHORS .An -nosplit -The -.Nm -interface was designed and implemented by -.An David Young Aq dyoung@pobox.com . .Pp -This manual page was written by +The original version of this manual page was written by .An Bruce M. Simpson Aq bms@FreeBSD.org and .An Darron Broad Aq darron@kewl.org . diff --git a/share/man/man9/ieee80211_regdomain.9 b/share/man/man9/ieee80211_regdomain.9 new file mode 100644 index 00000000000..0611ec37cbb --- /dev/null +++ b/share/man/man9/ieee80211_regdomain.9 @@ -0,0 +1,143 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" 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 August 4, 2009 +.Dt IEEE80211_REGDOMAIN 9 +.Os +.Sh NAME +.Nm ieee80211_regdomain +.Nd 802.11 regulatory support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.In net80211/ieee80211_regdomain.h +.Pp +.Ft int +.Fo ieee80211_init_channels +.Fa "struct ieee80211com *" +.Fa "const struct ieee80211_regdomain *" +.Fa "const uint8_t bands[]" +.Fc +.\" +.Ft void +.Fo ieee80211_sort_channels +.Fa "struct ieee80211_channel *" +.Fa "int nchans" +.Fc +.\" +.Ft "struct ieee80211_appie *" +.Fn ieee80211_alloc_countryie "struct ieee80211com *" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides a support framework for drivers that includes +comprehensive regulatory support. +.Nm net80211 +provides mechanisms that enforce +.Em "regulatory policy" +by privileged user applications. +.Pp +Drivers define a device's capabilities and can +intercept and control regulatory changes requested through +.Nm net80211 . +The initial regulatory state, including the channel list, must be +filled in by the driver before calling +.Fn ieee80211_ifattach . +The channel list should reflect the set of channels the device is +.Em calibrated +for use on. +This list may also be requested later through the +.Vt ic_getradiocaps +method in the +.Vt ieee80211com +structure. +The +.Fn ieee80211_init_channels +function is provided as a rudimentary fallback for drivers that do not +(or cannot) fill in a proper channel list. +Default regulatory state is supplied such as the regulatory SKU, +ISO country code, location (e.g. indoor, outdoor), and a set of +frequency bands the device is capable of operating on. +.Nm net80211 +populates the channel table in +.Vt ic_channels +with a default set of channels and capabilities. +Note this mechanism should be used with care as any mismatch between +the channel list created and the device's capabilities can result +in runtime errors (e.g. a request to operate on a channel the device +does not support). +The SKU and country information are used for generating 802.11h protocol +elements and related operation such as for 802.11d; mis-setup by a +driver is not fatal, only potentially confusing. +.Pp +Devices that do not have a fixed/default regulatory state can set +the regulatory SKU to +.Dv SKU_DEBUG +and country code to +.Dv CTRY_DEFAULT +and leave proper setup to user applications. +If default settings are known they can be installed and/or an event +can be dispatched to user space using +.Fn ieee80211_notify_country +so that +.Xr devd 8 +will do the appropriate setup work at system boot (or device insertion). +.Pp +The channel table is sorted to optimize lookups using the +.Fn ieee80211_sort_channels +routine. +This should be done whenever the channel table contents are modified. +.Pp +The +.Fn ieee80211_alloc_countrie +function allocates an information element as specified by 802.11h. +Because this is expensive to generate it is cached in +.Vt ic_countryie +and generated only when regulatory state changes. +Drivers that call +.Fn ieee80211_alloc_countryie +directly should not help with this caching; doing so may confuse the +.Nm net80211 +layer. +.Sh DRIVER REGULATORY CONTROL +Drivers can control regulatory change requests by overriding the +.Vt ic_setregdomain +method that checks change requests. +While drivers can reject any request that does not meet its requirements +it is recommended that one be lenient in what is accepted and, whenever +possible, instead of rejecting a request, alter it to be correct. +For example, if the transmit power cap for a channel is too high the +driver can either reject the request or (better) reduce the cap to be +compliant. +Requests that include unacceptable channels should cause the request +to be rejected as otherwise a mismatch may be created between application +state and the state managed by +.Nm net80211 . +The exact rules by which to operate are still being codified. +.Sh SEE ALSO +.Xr regdomain 5 , +.Xr ifconfig 8 , +.Xr ieee80211 9 . diff --git a/share/man/man9/ieee80211_scan.9 b/share/man/man9/ieee80211_scan.9 new file mode 100644 index 00000000000..8e1897cf1a6 --- /dev/null +++ b/share/man/man9/ieee80211_scan.9 @@ -0,0 +1,350 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" 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 August 4, 2009 +.Dt IEEE80211_SCAN 9 +.Os +.Sh NAME +.Nm ieee80211_scan +.Nd 802.11 scanning support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.Pp +.Ft int +.Fo ieee80211_start_scan +.Fa "struct ieee80211vap *" +.Fa "int flags" +.Fa "u_int duration" +.Fa "u_int mindwell" +.Fa "u_int maxdwell" +.Fa "u_int nssid" +.Fa "const struct ieee80211_scan_ssid ssids[]" +.Fc +.\" +.Ft int +.Fo ieee80211_check_scan +.Fa "struct ieee80211vap *" +.Fa "int flags" +.Fa "u_int duration" +.Fa "u_int mindwell" +.Fa "u_int maxdwell" +.Fa "u_int nssid" +.Fa "const struct ieee80211_scan_ssid ssids[]" +.Fc +.\" +.Ft int +.Fn ieee80211_check_scan_current "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_bg_scan "struct ieee80211vap *" "int" +.\" +.Ft int +.Fn ieee80211_cancel_scan "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_cancel_scan_any "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_scan_next "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_scan_done "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_probe_curchan "struct ieee80211vap *" "int" +.\" +.Ft void +.Fo ieee80211_add_scan +.Fa "struct ieee80211vap *" +.Fa "const struct ieee80211_scanparams *" +.Fa "const struct ieee80211_frame *" +.Fa "int subtype" +.Fa "int rssi" +.Fa "int noise" +.Fc +.\" +.Ft void +.Fn ieee80211_scan_timeout "struct ieee80211com *" +.\" +.Ft void +.Fo ieee80211_scan_assoc_fail +.Fa "struct ieee80211vap *" +.Fa "const uint8_t mac[IEEE80211_ADDR_LEN]" +.Fa "int reason" +.Fc +.\" +.Ft void +.Fn ieee80211_scan_flush "struct ieee80211vap *" +.\" +.Ft void +.Fo ieee80211_scan_iterate +.Fa "struct ieee80211vap *" +.Fa "ieee80211_scan_iter_func" +.Fa "void *" +.Fc +.\" +.Ft void +.Fn ieee80211_scan_dump_channels "const struct ieee80211_scan_state *" +.\" +.Ft void +.Fo ieee80211_scanner_register +.Fa "enum ieee80211_opmode" +.Fa "const struct ieee80211_scanner *" +.Fc +.\" +.Ft void +.Fo ieee80211_scanner_unregister +.Fa "enum ieee80211_opmode" +.Fa "const struct ieee80211_scanner *" +.Fc +.\" +.Ft void +.Fn ieee80211_scanner_unregister_all "const struct ieee80211_scanner *" +.\" +.Ft const struct ieee80211_scanner * +.Fn ieee80211_scanner_get "enum ieee80211_opmode" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides an extensible framework for scanning. +Scanning is the procedure by which a station locates a BSS to join +(in infrastructure and IBSS mode), or a channel to use (when operating +as an AP or an IBSS master). +Scans are either +.Dq active +or +.Dq passive . +An active scan causes one or more ProbeRequest frames to be sent on +visiting each channel. +A passive request causes each channel in the scan set to be visited but +no frames to be transmitted; the station only listens for traffic. +Note that active scanning may still need to listen for traffic before +sending ProbeRequest frames depending on regulatory constraints. +.Pp +A scan operation involves constructing a set of channels to inspect +(the scan set), +visiting each channel and collecting information +(e.g. what BSS are present), +and then analyzing the results to make decisions such as which BSS to join. +This process needs to be as fast as possible so +.Nm net80211 +does things like intelligently construct scan sets and dwell on a channel +only as long as necessary. +Scan results are cached and the scan cache is used to avoid scanning when +possible and to enable roaming between access points when operating +in infrastructure mode. +.Pp +Scanning is handled by pluggable modules that implement +.Em policy +per-operating mode. +The core scanning support provides an infrastructure to support these +modules and exports a common API to the rest of the +.Nm net80211 +layer. +Policy modules decide what channels to visit, what state to record to +make decisions, and selects the final station/channel to return as the +result of a scan. +.Pp +Scanning is done synchronously when initially bringing a vap to +an operational state and optionally in the background to maintain +the scan cache for doing roaming and rogue AP monitoring. +Scanning is not tied to the +.Nm net80211 +state machine that governs vaps except for linkage to the +.Dv IEEE80211_S_SCAN +state. +One one vap at a time may be scanning; this scheduling policy +is handle in +.Fn ieee80211_new_state +and is transparent to scanning code. +.Pp +Scanning is controlled by a set of parameters that (potentially) +constrains the channel set and any desired SSID's and BSSID's. +.Nm net80211 +comes with a standard scanner module that works with all available +operating modes and supports +.Dq background scanning +and +.Dq roaming +operation. +.Sh SCANNER MODULES +Scanning modules use a registration mechanism to hook into the +.Nm net80211 +layer. +Use +.Fn ieee80211_scanner_register +to register a scan module for a particular operating mode and +.Fn ieee80211_scanner_unregister +or +.Fn ieee80211_scanner_unregister_all +to clear entries (typically on module unload). +Only one scanner module can be registered at any time for an operating mode. +.Sh DRIVER SUPPORT +Scanning operations are usually managed by the +.Nm net80211 +layer. +Drivers must provide +.Vt ic_scan_start +and +.Vt ic_scan_stop +methods that are called at the start of a scan and when the +work is done; these should handle work such as enabling receive +of Beacon and ProbeResponse frames and disable any BSSID matching. +The +.Vt ic_set_channel +method is used to change channels while scanning. +.Nm net80211 +will generate ProbeRequest frames and transmit them using the +.Nm ic_raw_xmit +method. +Frames received while scanning are dispatched to +.Nm net80211 +using the normal receive path. +Devices that off-load scan work to firmware most easily mesh with +.Nm net80211 +by operating on a channel-at-a-time basis as this defers control to +.Nm net80211's +scan machine scheduler. +But multi-channel scanning +is supported if the driver manually dispatches results using +.Fn ieee80211_add_scan +routine to enter results into the scan cache. +.Sh SCAN REQUESTS +Scan requests occur by way of the +.Dv IEEE80211_SCAN_REQUEST +ioctl or through a change in a vap's state machine that requires +scanning. +In both cases the scan cache can be checked first and, if it is deemed +suitably +.Dq warm +then it's contents are used without leaving the current channel. +To start a scan without checking the cache +.Fn ieee80211_start_scan +can be called; otherwise +.Fn ieee80211_check_scan +can be used to first check the scan cache, kicking off a scan if +the cache contents are out of date. +There is also +.Fn ieee80211_check_scan_current +which is a shorthand for using previously set scan parameters for +checking the scan cache and then scanning. +.Pp +Background scanning is done using +.Fn ieee80211_bg_scan +in a co-routine fashion. +The first call to this routine will start a background scan that +runs for a limited period of time before returning to the BSS channel. +Subsequent calls advance through the scan set until all channels are +visited. +Typically these later calls are timed to allow receipt of +frames buffered by an access point for the station. +.Pp +A scan operation can be canceled using +.Fn ieee80211_cancel_scan +if it was initiated by the specified vap, or +.Fn ieee80211_cancel_scan_any +to force termination regardless which vap started it. +These requests are mostly used by +.Nm net80211 +in the transmit path to cancel background scans when frames are to be sent. +Drivers should not need to use these calls (or most of the calls described +on this page). +.Pp +The +.Fn ieee80211_scan_next +and +.Fn ieee80211_scan_done +routines do explicit iteration through the scan set and should +not normally be used by drivers. +.Fn ieee80211_probe_curchan +handles the work of transmitting ProbeRequest frames when visiting +a channel during an active scan. +When the channel attributes are marked with +.Dv IEEE80211_CHAN_PASSIVE +this function will arrange that before any frame is transmitted 802.11 +traffic is first received (in order to comply with regulatory constraints). +.Pp +Min/max dwell time parameters are used to constrain time spent visiting +a channel. +The maximum dwell time constrains the time spent listening for traffic. +The minimum dwell time is used to reduce this time--when it is reached +and one or more frames have been received then an immediate channel +change will be done. +Drivers can override this behaviour through the +.Vt iv_scan_mindwell +method. +.Sh SCAN CACHE MANAGEMENT +The scan cache contents are managed by the scan policy module and +are opaque outside this module. +The +.Nm net80211 +scan framework defines API's for interacting. +The validity of the scan cache contents are controlled by +.Vt iv_scanvalid +which is exported to user space through the +.Dv IEEE80211_SCAN_VALID +request. +.Pp +The cache contents can be explicitly flushed with +.Fn ieee80211_scan_flush +or by setting the +.Dv IEEE80211_SCAN_FLUSH +flag when starting a scan operation. +.Pp +Scan cache entries are created with the +.Fn ieee80211_add_scan +routine; usually on receipt of Beacon or ProbeResponse frames. +Existing entries are typically updated based on the latest information +though some information such as RSSI and noise floor readings may be +combined to present an average. +.Pp +The cache contents is aged through +.Fn ieee80211_scan_timeout +calls. +Typically these happen together with other station table activity; every +.Dv IEEE80211_INACT_WAIT +seconds (default 15). +.Pp +Individual cache entries are marked usable with +.Fn ieee80211_scan_assoc_success +and faulty with +.Fn ieee80211_scan_assoc_fail +with the latter taking an argument to identify if there was no response +to Authentication/Association requests or if a negative response was +received (which might hasten cache eviction or blacklist the entry). +.Pp +The cache contents can be viewed using the +.Fn ieee80211_scan_iterate +call. +Cache entries are exported in a public format that is exported to user +applications through the +.Dv IEEE80211_SCAN_RESULTS +request. +.Sh SEE ALSO +.Xr ioctl 2 , +.Xr ieee80211 9 . +.Xr ieee80211_proto 9 . diff --git a/share/man/man9/ieee80211_vap.9 b/share/man/man9/ieee80211_vap.9 new file mode 100644 index 00000000000..fc06fff3b9f --- /dev/null +++ b/share/man/man9/ieee80211_vap.9 @@ -0,0 +1,154 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" 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 August 4, 2009 +.Dt IEEE8021_VAP 9 +.Os +.Sh NAME +.Nm net80211_vap +.Nd 802.11 network layer virtual radio support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.Ft int +.Fo ieee80211_vap_setup +.Fa "struct ieee80211com *" +.Fa "struct ieee80211vap *" +.Fa "const char name[IFNAMSIZ]" +.Fa "int unit" +.Fa "int opmode" +.Fa "int flags" +.Fa "const uint8_t bssid[IEEE80211_ADDR_LEN]" +.Fa "const uint8_t macaddr[IEEE80211_ADDR_LEN]" +.Fc +.\" +.Ft int +.Fo ieee80211_vap_attach +.Fa "struct ieee80211vap *" +.Fa "ifm_change_cb_t media_change" +.Fa "ifm_stat_cb_t media_stat" +.Fc +.\" +.Ft void +.Fn ieee80211_vap_detach "struct ieee80211vap *" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides a support framework for drivers that includes +a virtual radio API that is exported to +users through network interfaces (aka vaps) that are cloned from the +underlying device. +These interfaces have an operating mode +(station, adhoc, hostap, wds, monitor, etc.) +that is fixed for the lifetime of the interface. +Devices that can support multiple concurrent interfaces allow +multiple vaps to be cloned. +.Pp +The virtual radio interface defined by the +.Nm net80211 +layer means that drivers must be structured to follow specific rules. +Drivers that support only a single interface at any time must still +follow these rules. +.Pp +The virtual radio architecture splits state between a single per-device +.Vt ieee80211com +structure and one or more +.Vt ieee80211vap +structures. +Vaps are created with the +.Dv SIOCIFCREATE2 +request. +This results in a call into the driver's +.Vt ic_vap_create +method where the driver can decide if the request should be accepted. +.Pp +The vap creation process is done in three steps. +First the driver allocates the data structure with +.Xr malloc 9 . +This data structure must have an +.Vt ieee80211vap +structure at the front but is usually extended with driver-private state. +Next the vap is setup with a call to +.Fn ieee80211_vap_setup . +This request initializes +.Nm net80211 +state but does not activate the interface. +The driver can then override methods setup by +.Nm net80211 +and setup driver resources before finally calling +.Fn ieee80211_vap_attach +to complete the process. +Both these calls must be done without holding any driver locks as +work may require the process block/sleep. +.Pp +A vap is deleted when an +.Dv SIOCIFDESTROY +ioctl request is made or when the device detaches (causing all +associated vaps to automatically be deleted). +Delete requests cause the +.Vt ic_vap_delete +method to be called. +Drivers must quiesce the device before calling +.Fn ieee80211_vap_detach +to deactivate the vap and isolate it from activities such as requests +from user applications. +The driver can then reclaim resources held by the vap and re-enable +device operation. +The exact procedure for quiesceing a device is unspecified but typically +it involves blocking interrupts and stopping transmit and receive +processing. +.Sh MULTI-VAP OPERATION +Drivers are responsible for deciding if multiple vaps can be created +and how to manage them. +Whether or not multiple concurrent vaps can be supported depends on a +device's capabilities. +For example, multiple hostap vaps can usually be supported but many +devices do not support assigning each vap a unique BSSID. +If a device supports hostap operation it can usually support concurrent +station mode vaps but possibly with limitations such as losing support +for hardware beacon miss support. +Devices that are capable of hostap operation and can send and receive +4-address frames should be able to support WDS vaps together with an +ap vap. +But in contrast some devices cannot support WDS vaps without at least one +ap vap (this however can be finessed by forcing the ap vap to not transmit +beacon frames). +All devices should support the creation of any number of monitor mode vaps +concurrent with other vaps but it is the responsibility of the driver to +allow this. +.Pp +An important consequence of supporting multiple concurrent vaps is that +a driver's +.Vt iv_newstate +method must be written to handle being called for each vap. +Where necessary, drivers must track private state for all vaps +and not just the one whose state is being changed (e.g. for +handling beacon timers the driver may need to know if all vaps +that beacon are stopped before stopping the hardware timers). +.Sh SEE ALSO +.Xr ieee80211 9 , +.Xr ifnet 9 , +.Xr malloc 9 . From a991498ca2724b4198e6b1b10fb85d6e03d99d44 Mon Sep 17 00:00:00 2001 From: "Simon L. B. Nielsen" Date: Wed, 12 Aug 2009 21:23:41 +0000 Subject: [PATCH 0019/2592] MFC 196133: Remove symlinks in OpenSSL's testing framework. These are not required for normal build, and doesn't export well to CVS. If they are needed later a script will be added to recreate the symlinks when needed at build time. Approved by: re (rwatson) --- crypto/openssl/apps/md4.c | 1 - crypto/openssl/test/bftest.c | 1 - crypto/openssl/test/bntest.c | 1 - crypto/openssl/test/casttest.c | 1 - crypto/openssl/test/destest.c | 1 - crypto/openssl/test/dhtest.c | 1 - crypto/openssl/test/dsatest.c | 1 - crypto/openssl/test/ecdhtest.c | 1 - crypto/openssl/test/ecdsatest.c | 1 - crypto/openssl/test/ectest.c | 1 - crypto/openssl/test/enginetest.c | 1 - crypto/openssl/test/evp_test.c | 1 - crypto/openssl/test/exptest.c | 1 - crypto/openssl/test/fips_aesavs.c | 1 - crypto/openssl/test/fips_desmovs.c | 1 - crypto/openssl/test/fips_dsatest.c | 1 - crypto/openssl/test/fips_dssvs.c | 1 - crypto/openssl/test/fips_hmactest.c | 1 - crypto/openssl/test/fips_randtest.c | 1 - crypto/openssl/test/fips_rngvs.c | 1 - crypto/openssl/test/fips_rsagtest.c | 1 - crypto/openssl/test/fips_rsastest.c | 1 - crypto/openssl/test/fips_rsavtest.c | 1 - crypto/openssl/test/fips_shatest.c | 1 - crypto/openssl/test/fips_test_suite.c | 1 - crypto/openssl/test/hmactest.c | 1 - crypto/openssl/test/ideatest.c | 1 - crypto/openssl/test/jpaketest.c | 1 - crypto/openssl/test/md2test.c | 1 - crypto/openssl/test/md4test.c | 1 - crypto/openssl/test/md5test.c | 1 - crypto/openssl/test/mdc2test.c | 1 - crypto/openssl/test/randtest.c | 1 - crypto/openssl/test/rc2test.c | 1 - crypto/openssl/test/rc4test.c | 1 - crypto/openssl/test/rc5test.c | 1 - crypto/openssl/test/rmdtest.c | 1 - crypto/openssl/test/rsa_test.c | 1 - crypto/openssl/test/sha1test.c | 1 - crypto/openssl/test/sha256t.c | 1 - crypto/openssl/test/sha512t.c | 1 - crypto/openssl/test/shatest.c | 1 - crypto/openssl/test/ssltest.c | 1 - 43 files changed, 43 deletions(-) delete mode 120000 crypto/openssl/apps/md4.c delete mode 120000 crypto/openssl/test/bftest.c delete mode 120000 crypto/openssl/test/bntest.c delete mode 120000 crypto/openssl/test/casttest.c delete mode 120000 crypto/openssl/test/destest.c delete mode 120000 crypto/openssl/test/dhtest.c delete mode 120000 crypto/openssl/test/dsatest.c delete mode 120000 crypto/openssl/test/ecdhtest.c delete mode 120000 crypto/openssl/test/ecdsatest.c delete mode 120000 crypto/openssl/test/ectest.c delete mode 120000 crypto/openssl/test/enginetest.c delete mode 120000 crypto/openssl/test/evp_test.c delete mode 120000 crypto/openssl/test/exptest.c delete mode 120000 crypto/openssl/test/fips_aesavs.c delete mode 120000 crypto/openssl/test/fips_desmovs.c delete mode 120000 crypto/openssl/test/fips_dsatest.c delete mode 120000 crypto/openssl/test/fips_dssvs.c delete mode 120000 crypto/openssl/test/fips_hmactest.c delete mode 120000 crypto/openssl/test/fips_randtest.c delete mode 120000 crypto/openssl/test/fips_rngvs.c delete mode 120000 crypto/openssl/test/fips_rsagtest.c delete mode 120000 crypto/openssl/test/fips_rsastest.c delete mode 120000 crypto/openssl/test/fips_rsavtest.c delete mode 120000 crypto/openssl/test/fips_shatest.c delete mode 120000 crypto/openssl/test/fips_test_suite.c delete mode 120000 crypto/openssl/test/hmactest.c delete mode 120000 crypto/openssl/test/ideatest.c delete mode 120000 crypto/openssl/test/jpaketest.c delete mode 120000 crypto/openssl/test/md2test.c delete mode 120000 crypto/openssl/test/md4test.c delete mode 120000 crypto/openssl/test/md5test.c delete mode 120000 crypto/openssl/test/mdc2test.c delete mode 120000 crypto/openssl/test/randtest.c delete mode 120000 crypto/openssl/test/rc2test.c delete mode 120000 crypto/openssl/test/rc4test.c delete mode 120000 crypto/openssl/test/rc5test.c delete mode 120000 crypto/openssl/test/rmdtest.c delete mode 120000 crypto/openssl/test/rsa_test.c delete mode 120000 crypto/openssl/test/sha1test.c delete mode 120000 crypto/openssl/test/sha256t.c delete mode 120000 crypto/openssl/test/sha512t.c delete mode 120000 crypto/openssl/test/shatest.c delete mode 120000 crypto/openssl/test/ssltest.c diff --git a/crypto/openssl/apps/md4.c b/crypto/openssl/apps/md4.c deleted file mode 120000 index 7f457b2ab1e..00000000000 --- a/crypto/openssl/apps/md4.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/md4/md4.c \ No newline at end of file diff --git a/crypto/openssl/test/bftest.c b/crypto/openssl/test/bftest.c deleted file mode 120000 index 78b1749a4d1..00000000000 --- a/crypto/openssl/test/bftest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/bf/bftest.c \ No newline at end of file diff --git a/crypto/openssl/test/bntest.c b/crypto/openssl/test/bntest.c deleted file mode 120000 index 03f54a238ef..00000000000 --- a/crypto/openssl/test/bntest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/bn/bntest.c \ No newline at end of file diff --git a/crypto/openssl/test/casttest.c b/crypto/openssl/test/casttest.c deleted file mode 120000 index ac7ede8d795..00000000000 --- a/crypto/openssl/test/casttest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/cast/casttest.c \ No newline at end of file diff --git a/crypto/openssl/test/destest.c b/crypto/openssl/test/destest.c deleted file mode 120000 index 5988c7303a3..00000000000 --- a/crypto/openssl/test/destest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/des/destest.c \ No newline at end of file diff --git a/crypto/openssl/test/dhtest.c b/crypto/openssl/test/dhtest.c deleted file mode 120000 index 9a67f916288..00000000000 --- a/crypto/openssl/test/dhtest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/dh/dhtest.c \ No newline at end of file diff --git a/crypto/openssl/test/dsatest.c b/crypto/openssl/test/dsatest.c deleted file mode 120000 index 16a1b5a349f..00000000000 --- a/crypto/openssl/test/dsatest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/dsa/dsatest.c \ No newline at end of file diff --git a/crypto/openssl/test/ecdhtest.c b/crypto/openssl/test/ecdhtest.c deleted file mode 120000 index 206d98686d7..00000000000 --- a/crypto/openssl/test/ecdhtest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/ecdh/ecdhtest.c \ No newline at end of file diff --git a/crypto/openssl/test/ecdsatest.c b/crypto/openssl/test/ecdsatest.c deleted file mode 120000 index 441082ba243..00000000000 --- a/crypto/openssl/test/ecdsatest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/ecdsa/ecdsatest.c \ No newline at end of file diff --git a/crypto/openssl/test/ectest.c b/crypto/openssl/test/ectest.c deleted file mode 120000 index df1831f812c..00000000000 --- a/crypto/openssl/test/ectest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/ec/ectest.c \ No newline at end of file diff --git a/crypto/openssl/test/enginetest.c b/crypto/openssl/test/enginetest.c deleted file mode 120000 index 5c74a6f4189..00000000000 --- a/crypto/openssl/test/enginetest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/engine/enginetest.c \ No newline at end of file diff --git a/crypto/openssl/test/evp_test.c b/crypto/openssl/test/evp_test.c deleted file mode 120000 index 074162812a3..00000000000 --- a/crypto/openssl/test/evp_test.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/evp/evp_test.c \ No newline at end of file diff --git a/crypto/openssl/test/exptest.c b/crypto/openssl/test/exptest.c deleted file mode 120000 index 50ccf71cbb7..00000000000 --- a/crypto/openssl/test/exptest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/bn/exptest.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_aesavs.c b/crypto/openssl/test/fips_aesavs.c deleted file mode 120000 index 7d9da0e8856..00000000000 --- a/crypto/openssl/test/fips_aesavs.c +++ /dev/null @@ -1 +0,0 @@ -../fips/aes/fips_aesavs.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_desmovs.c b/crypto/openssl/test/fips_desmovs.c deleted file mode 120000 index dd74966b06b..00000000000 --- a/crypto/openssl/test/fips_desmovs.c +++ /dev/null @@ -1 +0,0 @@ -../fips/des/fips_desmovs.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_dsatest.c b/crypto/openssl/test/fips_dsatest.c deleted file mode 120000 index e43b79b16dc..00000000000 --- a/crypto/openssl/test/fips_dsatest.c +++ /dev/null @@ -1 +0,0 @@ -../fips/dsa/fips_dsatest.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_dssvs.c b/crypto/openssl/test/fips_dssvs.c deleted file mode 120000 index 93e05e687fd..00000000000 --- a/crypto/openssl/test/fips_dssvs.c +++ /dev/null @@ -1 +0,0 @@ -../fips/dsa/fips_dssvs.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_hmactest.c b/crypto/openssl/test/fips_hmactest.c deleted file mode 120000 index b674d16df59..00000000000 --- a/crypto/openssl/test/fips_hmactest.c +++ /dev/null @@ -1 +0,0 @@ -../fips/hmac/fips_hmactest.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_randtest.c b/crypto/openssl/test/fips_randtest.c deleted file mode 120000 index 8b8f4863bf0..00000000000 --- a/crypto/openssl/test/fips_randtest.c +++ /dev/null @@ -1 +0,0 @@ -../fips/rand/fips_randtest.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_rngvs.c b/crypto/openssl/test/fips_rngvs.c deleted file mode 120000 index 0d6c9be190a..00000000000 --- a/crypto/openssl/test/fips_rngvs.c +++ /dev/null @@ -1 +0,0 @@ -../fips/rand/fips_rngvs.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_rsagtest.c b/crypto/openssl/test/fips_rsagtest.c deleted file mode 120000 index 3ed6b5186ba..00000000000 --- a/crypto/openssl/test/fips_rsagtest.c +++ /dev/null @@ -1 +0,0 @@ -../fips/rsa/fips_rsagtest.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_rsastest.c b/crypto/openssl/test/fips_rsastest.c deleted file mode 120000 index 2a5f8b0280d..00000000000 --- a/crypto/openssl/test/fips_rsastest.c +++ /dev/null @@ -1 +0,0 @@ -../fips/rsa/fips_rsastest.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_rsavtest.c b/crypto/openssl/test/fips_rsavtest.c deleted file mode 120000 index f45aa58a8b7..00000000000 --- a/crypto/openssl/test/fips_rsavtest.c +++ /dev/null @@ -1 +0,0 @@ -../fips/rsa/fips_rsavtest.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_shatest.c b/crypto/openssl/test/fips_shatest.c deleted file mode 120000 index 67c47caba4b..00000000000 --- a/crypto/openssl/test/fips_shatest.c +++ /dev/null @@ -1 +0,0 @@ -../fips/sha/fips_shatest.c \ No newline at end of file diff --git a/crypto/openssl/test/fips_test_suite.c b/crypto/openssl/test/fips_test_suite.c deleted file mode 120000 index b538efa4281..00000000000 --- a/crypto/openssl/test/fips_test_suite.c +++ /dev/null @@ -1 +0,0 @@ -../fips/fips_test_suite.c \ No newline at end of file diff --git a/crypto/openssl/test/hmactest.c b/crypto/openssl/test/hmactest.c deleted file mode 120000 index 353ee2c7f98..00000000000 --- a/crypto/openssl/test/hmactest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/hmac/hmactest.c \ No newline at end of file diff --git a/crypto/openssl/test/ideatest.c b/crypto/openssl/test/ideatest.c deleted file mode 120000 index a9bfb3d4804..00000000000 --- a/crypto/openssl/test/ideatest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/idea/ideatest.c \ No newline at end of file diff --git a/crypto/openssl/test/jpaketest.c b/crypto/openssl/test/jpaketest.c deleted file mode 120000 index 49f44f8b69e..00000000000 --- a/crypto/openssl/test/jpaketest.c +++ /dev/null @@ -1 +0,0 @@ -dummytest.c \ No newline at end of file diff --git a/crypto/openssl/test/md2test.c b/crypto/openssl/test/md2test.c deleted file mode 120000 index b0c6e6f8091..00000000000 --- a/crypto/openssl/test/md2test.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/md2/md2test.c \ No newline at end of file diff --git a/crypto/openssl/test/md4test.c b/crypto/openssl/test/md4test.c deleted file mode 120000 index 1509be911da..00000000000 --- a/crypto/openssl/test/md4test.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/md4/md4test.c \ No newline at end of file diff --git a/crypto/openssl/test/md5test.c b/crypto/openssl/test/md5test.c deleted file mode 120000 index 20f4aaf0a4e..00000000000 --- a/crypto/openssl/test/md5test.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/md5/md5test.c \ No newline at end of file diff --git a/crypto/openssl/test/mdc2test.c b/crypto/openssl/test/mdc2test.c deleted file mode 120000 index 49f44f8b69e..00000000000 --- a/crypto/openssl/test/mdc2test.c +++ /dev/null @@ -1 +0,0 @@ -dummytest.c \ No newline at end of file diff --git a/crypto/openssl/test/randtest.c b/crypto/openssl/test/randtest.c deleted file mode 120000 index a2b107a2b0e..00000000000 --- a/crypto/openssl/test/randtest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/rand/randtest.c \ No newline at end of file diff --git a/crypto/openssl/test/rc2test.c b/crypto/openssl/test/rc2test.c deleted file mode 120000 index 5c53ad984a4..00000000000 --- a/crypto/openssl/test/rc2test.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/rc2/rc2test.c \ No newline at end of file diff --git a/crypto/openssl/test/rc4test.c b/crypto/openssl/test/rc4test.c deleted file mode 120000 index 061ac377344..00000000000 --- a/crypto/openssl/test/rc4test.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/rc4/rc4test.c \ No newline at end of file diff --git a/crypto/openssl/test/rc5test.c b/crypto/openssl/test/rc5test.c deleted file mode 120000 index 49f44f8b69e..00000000000 --- a/crypto/openssl/test/rc5test.c +++ /dev/null @@ -1 +0,0 @@ -dummytest.c \ No newline at end of file diff --git a/crypto/openssl/test/rmdtest.c b/crypto/openssl/test/rmdtest.c deleted file mode 120000 index ce66460654d..00000000000 --- a/crypto/openssl/test/rmdtest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/ripemd/rmdtest.c \ No newline at end of file diff --git a/crypto/openssl/test/rsa_test.c b/crypto/openssl/test/rsa_test.c deleted file mode 120000 index aaea20d98ba..00000000000 --- a/crypto/openssl/test/rsa_test.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/rsa/rsa_test.c \ No newline at end of file diff --git a/crypto/openssl/test/sha1test.c b/crypto/openssl/test/sha1test.c deleted file mode 120000 index 8d66e9ee4c2..00000000000 --- a/crypto/openssl/test/sha1test.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/sha/sha1test.c \ No newline at end of file diff --git a/crypto/openssl/test/sha256t.c b/crypto/openssl/test/sha256t.c deleted file mode 120000 index 952a5086766..00000000000 --- a/crypto/openssl/test/sha256t.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/sha/sha256t.c \ No newline at end of file diff --git a/crypto/openssl/test/sha512t.c b/crypto/openssl/test/sha512t.c deleted file mode 120000 index c80d152f1ba..00000000000 --- a/crypto/openssl/test/sha512t.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/sha/sha512t.c \ No newline at end of file diff --git a/crypto/openssl/test/shatest.c b/crypto/openssl/test/shatest.c deleted file mode 120000 index 43cfda78fbf..00000000000 --- a/crypto/openssl/test/shatest.c +++ /dev/null @@ -1 +0,0 @@ -../crypto/sha/shatest.c \ No newline at end of file diff --git a/crypto/openssl/test/ssltest.c b/crypto/openssl/test/ssltest.c deleted file mode 120000 index 40191f0da24..00000000000 --- a/crypto/openssl/test/ssltest.c +++ /dev/null @@ -1 +0,0 @@ -../ssl/ssltest.c \ No newline at end of file From 4904bb1de05099d9a5389a9fe39954ee7ff9b874 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 12 Aug 2009 21:34:57 +0000 Subject: [PATCH 0020/2592] MFC r196159: Drain link state event changes posted during vap destroy. This is a band-aid for the general problem that if_link_state_change can be called between if_detach and if_free leaving a task queued that has been free'd. Reviewed by: rwatson Approved by: re (rwatson) --- sys/net80211/ieee80211.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index 081c6db3b1c..b14f13f90fe 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -573,11 +573,13 @@ ieee80211_vap_detach(struct ieee80211vap *vap) /* * Flush any deferred vap tasks. - * NB: must be before ether_ifdetach() and removal from ic_vaps list */ ieee80211_draintask(ic, &vap->iv_nstate_task); ieee80211_draintask(ic, &vap->iv_swbmiss_task); + /* XXX band-aid until ifnet handles this for us */ + taskqueue_drain(taskqueue_swi, &ifp->if_linktask); + IEEE80211_LOCK(ic); KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running")); TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next); From 7922e083b4188aade09a92d95bf949afec635f4b Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Thu, 13 Aug 2009 01:45:26 +0000 Subject: [PATCH 0021/2592] MFC 196162: Have at least a fallback WWN so cards on sun branded FC cards can configure. Approved by: re --- sys/dev/isp/isp_freebsd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index b6f172b664e..3d20b097e58 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -5280,6 +5280,10 @@ isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn) return (seed); } seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram : FCPARAM(isp, chan)->isp_wwpn_nvram; + if (seed) { + return (seed); + } + return (0x400000007F000009ull); } else { seed = iswwnn ? fc->def_wwnn : fc->def_wwpn; } From eaff962ee1a2a2aeaf0023274ba525c0268760a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 13 Aug 2009 06:13:45 +0000 Subject: [PATCH 0022/2592] merge r196164: update & remove CVS-specific items. Approved by: re (kib) --- contrib/bzip2/FREEBSD-vendor | 2 -- contrib/netcat/FREEBSD-vendor | 2 -- contrib/openpam/FREEBSD-vendor | 2 -- crypto/openssh/FREEBSD-vendor | 4 +--- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/contrib/bzip2/FREEBSD-vendor b/contrib/bzip2/FREEBSD-vendor index 72eb8776ccb..6847c8b9a49 100644 --- a/contrib/bzip2/FREEBSD-vendor +++ b/contrib/bzip2/FREEBSD-vendor @@ -2,6 +2,4 @@ Project: bzip2 ProjectURL: http://www.bzip.org/ Version: 1.0.5 -VendorTag: BZIP2 -VersionTag: v1_0_5 License: BSD diff --git a/contrib/netcat/FREEBSD-vendor b/contrib/netcat/FREEBSD-vendor index 6e31d26c32e..1009e388e2e 100644 --- a/contrib/netcat/FREEBSD-vendor +++ b/contrib/netcat/FREEBSD-vendor @@ -2,6 +2,4 @@ Project: netcat (aka src/usr.bin/nc in OpenBSD) ProjectURL: http://www.openbsd.org/ Version: 4.4 -VendorTag: OPENBSD -VersionTag: OPENBSD_4_4 License: BSD diff --git a/contrib/openpam/FREEBSD-vendor b/contrib/openpam/FREEBSD-vendor index 69a0ade0ef5..51a8bbfa480 100644 --- a/contrib/openpam/FREEBSD-vendor +++ b/contrib/openpam/FREEBSD-vendor @@ -2,7 +2,5 @@ Project: OpenPAM ProjectURL: http://www.openpam.org/ Version: Hydrangea (20071221) -VendorTag: OPENPAM -VersionTag: OPENPAM_HYDRANGEA License: BSD Maintainer: des diff --git a/crypto/openssh/FREEBSD-vendor b/crypto/openssh/FREEBSD-vendor index 6329f5abf05..0fa56d03f5d 100644 --- a/crypto/openssh/FREEBSD-vendor +++ b/crypto/openssh/FREEBSD-vendor @@ -1,8 +1,6 @@ # $FreeBSD$ Project: Portable OpenSSH ProjectURL: http://www.openssh.com/portable.html -Version: 5.1p1 -VendorTag: OPENSSH -VersionTag: OpenSSH_5_1p1 +Version: 5.2p1 License: BSD Maintainer: des From 9c4afd6dbcf59eddaa148f5ddcc6f2bb192d1a0b Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Thu, 13 Aug 2009 09:17:07 +0000 Subject: [PATCH 0023/2592] MFC r196172: Start respecting WITHOUT_INET6. Make regression/priv compile again after the multi-IP jail changes. Note that we are still using the legacy jail(2) rather than the jail_set(2)/jail(3) syscall. Add an IPv4, and an IPv6 loopback address in case we compile with INET6 enabled. Make the priv_vfs_extattr_system compile on amd64 as well using the proper length modifier to printf(3) for ssize_t. Reviewed by: rwatson Approved by: re (kib) --- tools/regression/priv/Makefile | 6 ++++++ tools/regression/priv/main.c | 19 ++++++++++++++++-- tools/regression/priv/priv_netinet_ipsec.c | 20 +++++++++++++++---- .../regression/priv/priv_vfs_extattr_system.c | 2 +- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/tools/regression/priv/Makefile b/tools/regression/priv/Makefile index 6f494a89bd4..814f5c333db 100644 --- a/tools/regression/priv/Makefile +++ b/tools/regression/priv/Makefile @@ -2,6 +2,8 @@ # $FreeBSD$ # +.include + PROG= priv SRCS= main.c \ priv_acct.c \ @@ -49,4 +51,8 @@ WARNS= 3 DPADD+= ${LIBIPSEC} LDADD+= -lipsec +.if ${MK_INET6_SUPPORT} != "no" +CFLAGS+= -DINET6 +.endif + .include diff --git a/tools/regression/priv/main.c b/tools/regression/priv/main.c index 5dd411a22d4..e594c44c4a7 100644 --- a/tools/regression/priv/main.c +++ b/tools/regression/priv/main.c @@ -142,20 +142,24 @@ static struct test tests[] = { priv_netinet_ipsec_policy4_bypass, priv_netinet_ipsec_policy_bypass_cleanup }, +#ifdef INET6 { "priv_netinet_ipsec_policy6_bypass", priv_netinet_ipsec_policy6_bypass_setup, priv_netinet_ipsec_policy6_bypass, priv_netinet_ipsec_policy_bypass_cleanup }, +#endif { "priv_netinet_ipsec_policy4_entrust", priv_netinet_ipsec_policy4_entrust_setup, priv_netinet_ipsec_policy4_entrust, priv_netinet_ipsec_policy_entrust_cleanup }, +#ifdef INET6 { "priv_netinet_ipsec_policy6_entrust", priv_netinet_ipsec_policy6_entrust_setup, priv_netinet_ipsec_policy6_entrust, priv_netinet_ipsec_policy_entrust_cleanup }, +#endif { "priv_netinet_raw", priv_netinet_raw_setup, priv_netinet_raw, priv_netinet_raw_cleanup }, @@ -420,12 +424,23 @@ static void enter_jail(const char *test) { struct jail j; + struct in_addr ia4; +#ifdef INET6 + struct in6_addr ia6 = IN6ADDR_LOOPBACK_INIT; +#endif bzero(&j, sizeof(j)); - j.version = 0; + j.version = JAIL_API_VERSION; j.path = "/"; j.hostname = "test"; - j.ip_number = htonl(INADDR_LOOPBACK); + j.jailname = "regressions/priv"; + ia4.s_addr = htonl(INADDR_LOOPBACK); + j.ip4s = 1; + j.ip4 = &ia4; +#ifdef INET6 + j.ip6s = 1; + j.ip6 = &ia6; +#endif if (jail(&j) < 0) err(-1, "test %s: jail", test); } diff --git a/tools/regression/priv/priv_netinet_ipsec.c b/tools/regression/priv/priv_netinet_ipsec.c index c2014da1d24..a485886b8fe 100644 --- a/tools/regression/priv/priv_netinet_ipsec.c +++ b/tools/regression/priv/priv_netinet_ipsec.c @@ -69,6 +69,7 @@ priv_netinet_ipsec_policy_bypass_setup_af(int asroot, int injail, return (-1); } break; +#ifdef INET6 case AF_INET6: sd = socket(AF_INET6, SOCK_DGRAM, 0); if (sd < 0) { @@ -76,6 +77,7 @@ priv_netinet_ipsec_policy_bypass_setup_af(int asroot, int injail, return (-1); } break; +#endif default: warnx("%s: unexpected address family", __func__); return (-1); @@ -92,6 +94,7 @@ priv_netinet_ipsec_policy4_bypass_setup(int asroot, int injail, AF_INET)); } +#ifdef INET6 int priv_netinet_ipsec_policy6_bypass_setup(int asroot, int injail, struct test *test) @@ -100,7 +103,7 @@ priv_netinet_ipsec_policy6_bypass_setup(int asroot, int injail, return (priv_netinet_ipsec_policy_bypass_setup_af(asroot, injail, test, AF_INET6)); } - +#endif static int @@ -121,6 +124,7 @@ priv_netinet_ipsec_policy_entrust_setup_af(int asroot, int injail, return (-1); } break; +#ifdef INET6 case AF_INET6: sd = socket(AF_INET6, SOCK_DGRAM, 0); if (sd < 0) { @@ -128,6 +132,7 @@ priv_netinet_ipsec_policy_entrust_setup_af(int asroot, int injail, return (-1); } break; +#endif default: warnx("%s: unexpected address family", __func__); return (-1); @@ -144,6 +149,7 @@ priv_netinet_ipsec_policy4_entrust_setup(int asroot, int injail, AF_INET)); } +#ifdef INET6 int priv_netinet_ipsec_policy6_entrust_setup(int asroot, int injail, struct test *test) @@ -152,7 +158,7 @@ priv_netinet_ipsec_policy6_entrust_setup(int asroot, int injail, return (priv_netinet_ipsec_policy_entrust_setup_af(asroot, injail, test, AF_INET6)); } - +#endif void priv_netinet_ipsec_pfkey(int asroot, int injail, struct test *test) @@ -196,10 +202,12 @@ priv_netinet_ipsec_policy_bypass_af(int asroot, int injail, struct test *test, level = IPPROTO_IP; optname = IP_IPSEC_POLICY; break; +#ifdef INET6 case AF_INET6: level = IPPROTO_IPV6; optname = IPV6_IPSEC_POLICY; break; +#endif default: warnx("%s: unexpected address family", __func__); return; @@ -227,13 +235,14 @@ priv_netinet_ipsec_policy4_bypass(int asroot, int injail, struct test *test) priv_netinet_ipsec_policy_bypass_af(asroot, injail, test, AF_INET); } +#ifdef INET6 void priv_netinet_ipsec_policy6_bypass(int asroot, int injail, struct test *test) { priv_netinet_ipsec_policy_bypass_af(asroot, injail, test, AF_INET6); } - +#endif static void priv_netinet_ipsec_policy_entrust_af(int asroot, int injail, struct test *test, @@ -246,10 +255,12 @@ priv_netinet_ipsec_policy_entrust_af(int asroot, int injail, struct test *test, level = IPPROTO_IP; optname = IP_IPSEC_POLICY; break; +#ifdef INET6 case AF_INET6: level = IPPROTO_IPV6; optname = IPV6_IPSEC_POLICY; break; +#endif default: warnx("%s: unexpected address family", __func__); return; @@ -277,13 +288,14 @@ priv_netinet_ipsec_policy4_entrust(int asroot, int injail, struct test *test) priv_netinet_ipsec_policy_entrust_af(asroot, injail, test, AF_INET); } +#ifdef INET6 void priv_netinet_ipsec_policy6_entrust(int asroot, int injail, struct test *test) { priv_netinet_ipsec_policy_entrust_af(asroot, injail, test, AF_INET6); } - +#endif void priv_netinet_ipsec_policy_bypass_cleanup(int asroot, int injail, diff --git a/tools/regression/priv/priv_vfs_extattr_system.c b/tools/regression/priv/priv_vfs_extattr_system.c index 9f8f88718e1..a766a04c793 100644 --- a/tools/regression/priv/priv_vfs_extattr_system.c +++ b/tools/regression/priv/priv_vfs_extattr_system.c @@ -80,7 +80,7 @@ priv_vfs_extattr_system(int asroot, int injail, struct test *test) else if (ret == EA_SIZE) error = 0; else - err(-1, "priv_vfs_extattr_system: set returned %d", ret); + err(-1, "priv_vfs_extattr_system: set returned %zd", ret); if (asroot && injail) expect("priv_vfs_extattr_system(asroot, injail)", error, -1, EPERM); From 9b36fbe976cdec91b4d0aefa7d9008f85ca7b42f Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Thu, 13 Aug 2009 09:32:15 +0000 Subject: [PATCH 0024/2592] MFC r196174: Put multiple instructions into a block when iterating; unbreaks NET_RT_DUMP, which otherwise only returned information of AF_MAX. This was broken in r193232 (save your time - my bug, my fix). Reported by: Larry Baird (lab gta.com) Tested by: Larry Baird (lab gta.com) Reviewed by: zec, lstewart, qing PR: kern/137700 Approved by: re (kib) --- sys/net/rtsock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 645cf7e54eb..8fb889908f9 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1473,7 +1473,7 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS) /* * take care of routing entries */ - for (error = 0; error == 0 && i <= lim; i++) + for (error = 0; error == 0 && i <= lim; i++) { rnh = rt_tables_get_rnh(req->td->td_proc->p_fibnum, i); if (rnh != NULL) { RADIX_NODE_HEAD_LOCK(rnh); @@ -1482,6 +1482,7 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS) RADIX_NODE_HEAD_UNLOCK(rnh); } else if (af != 0) error = EAFNOSUPPORT; + } break; case NET_RT_IFLIST: From da2a30fca10cb0544e711557d1c73cc9fffe8ba9 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Thu, 13 Aug 2009 10:31:02 +0000 Subject: [PATCH 0025/2592] MFC r196176: Make it possible to change the vnet sysctl variables on jails with their own virtual network stack. Jails only inheriting a network stack cannot change anything that cannot be changed from within a prison. Reviewed by: rwatson, zec Approved by: re (kib) --- sys/kern/kern_jail.c | 23 +++++++++++++++++++++++ sys/kern/kern_sysctl.c | 12 ++++++++++-- sys/net/vnet.h | 18 +++++++++++------- sys/sys/jail.h | 1 + sys/sys/sysctl.h | 1 + 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 282a4d8c95b..8f185833e8a 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -88,7 +88,11 @@ struct prison prison0 = { .pr_childmax = JAIL_MAX, .pr_hostuuid = DEFAULT_HOSTUUID, .pr_children = LIST_HEAD_INITIALIZER(&prison0.pr_children), +#ifdef VIMAGE + .pr_flags = PR_HOST|PR_VNET, +#else .pr_flags = PR_HOST, +#endif .pr_allow = PR_ALLOW_ALL, }; MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF); @@ -3308,6 +3312,25 @@ getcredhostid(struct ucred *cred, unsigned long *hostid) mtx_unlock(&cred->cr_prison->pr_mtx); } +#ifdef VIMAGE +/* + * Determine whether the prison represented by cred owns + * its vnet rather than having it inherited. + * + * Returns 1 in case the prison owns the vnet, 0 otherwise. + */ +int +prison_owns_vnet(struct ucred *cred) +{ + + /* + * vnets cannot be added/removed after jail creation, + * so no need to lock here. + */ + return (cred->cr_prison->pr_flags & PR_VNET ? 1 : 0); +} +#endif + /* * Determine whether the subject represented by cred can "see" * status of a mount point. diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index bb5b6a0f3ad..b83502c2f41 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1381,10 +1381,18 @@ sysctl_root(SYSCTL_HANDLER_ARGS) /* Is this sysctl writable by only privileged users? */ if (req->newptr && !(oid->oid_kind & CTLFLAG_ANYBODY)) { + int priv; + if (oid->oid_kind & CTLFLAG_PRISON) - error = priv_check(req->td, PRIV_SYSCTL_WRITEJAIL); + priv = PRIV_SYSCTL_WRITEJAIL; +#ifdef VIMAGE + else if ((oid->oid_kind & CTLFLAG_VNET) && + prison_owns_vnet(req->td->td_ucred)) + priv = PRIV_SYSCTL_WRITEJAIL; +#endif else - error = priv_check(req->td, PRIV_SYSCTL_WRITE); + priv = PRIV_SYSCTL_WRITE; + error = priv_check(req->td, priv); if (error) return (error); } diff --git a/sys/net/vnet.h b/sys/net/vnet.h index d441af19970..91de07a1093 100644 --- a/sys/net/vnet.h +++ b/sys/net/vnet.h @@ -232,21 +232,25 @@ int vnet_sysctl_handle_string(SYSCTL_HANDLER_ARGS); int vnet_sysctl_handle_uint(SYSCTL_HANDLER_ARGS); #define SYSCTL_VNET_INT(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_MPSAFE|(access), \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_INT|CTLFLAG_MPSAFE|CTLFLAG_VNET|(access), \ ptr, val, vnet_sysctl_handle_int, "I", descr) #define SYSCTL_VNET_PROC(parent, nbr, name, access, ptr, arg, handler, \ fmt, descr) \ - SYSCTL_OID(parent, nbr, name, access, ptr, arg, handler, fmt, \ - descr) + SYSCTL_OID(parent, nbr, name, CTLFLAG_VNET|(access), ptr, arg, \ + handler, fmt, descr) #define SYSCTL_VNET_STRING(parent, nbr, name, access, arg, len, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|(access), arg, \ - len, vnet_sysctl_handle_string, "A", descr) + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_STRING|CTLFLAG_VNET|(access), \ + arg, len, vnet_sysctl_handle_string, "A", descr) #define SYSCTL_VNET_STRUCT(parent, nbr, name, access, ptr, type, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), ptr, \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_OPAQUE|CTLFLAG_VNET|(access), ptr, \ sizeof(struct type), vnet_sysctl_handle_opaque, "S," #type, \ descr) #define SYSCTL_VNET_UINT(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_UINT|CTLFLAG_MPSAFE|CTLFLAG_VNET|(access), \ ptr, val, vnet_sysctl_handle_uint, "IU", descr) #define VNET_SYSCTL_ARG(req, arg1) do { \ if (arg1 != NULL) \ diff --git a/sys/sys/jail.h b/sys/sys/jail.h index d7457bfd427..cb26a64ec7d 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -341,6 +341,7 @@ void getcredhostuuid(struct ucred *, char *, size_t); void getcredhostid(struct ucred *, unsigned long *); int prison_allow(struct ucred *, unsigned); int prison_check(struct ucred *cred1, struct ucred *cred2); +int prison_owns_vnet(struct ucred *); int prison_canseemount(struct ucred *cred, struct mount *mp); void prison_enforce_statfs(struct ucred *cred, struct mount *mp, struct statfs *sp); diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 4cab1599dc9..e1ce71889ee 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -85,6 +85,7 @@ struct ctlname { #define CTLMASK_SECURE 0x00F00000 /* Secure level */ #define CTLFLAG_TUN 0x00080000 /* Tunable variable */ #define CTLFLAG_MPSAFE 0x00040000 /* Handler is MP safe */ +#define CTLFLAG_VNET 0x00020000 /* Prisons with vnet can fiddle */ #define CTLFLAG_RDTUN (CTLFLAG_RD|CTLFLAG_TUN) /* From dba91be24481ad8e8bbeeabcef8b9d75a6f03fbd Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Thu, 13 Aug 2009 13:56:05 +0000 Subject: [PATCH 0026/2592] InstaMFC 196179: Remove CDDL warning. Approved by: re (kib), core --- sys/cddl/compat/opensolaris/kern/opensolaris.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris.c b/sys/cddl/compat/opensolaris/kern/opensolaris.c index 443ac0ad79e..54118eb3835 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris.c @@ -49,10 +49,6 @@ opensolaris_load(void *dummy) { int i; - printf("This module (opensolaris) contains code covered by the\n"); - printf("Common Development and Distribution License (CDDL)\n"); - printf("see http://opensolaris.org/os/licensing/opensolaris_license/\n"); - /* * "Enable" all CPUs even though they may not exist just so * that the asserts work. On FreeBSD, if a CPU exists, it is From 7a34e29bc6de21da6911e67c17ad72085702c4ab Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 13 Aug 2009 14:38:09 +0000 Subject: [PATCH 0027/2592] Merge r196120 from head to stable/8: Update procstat(1) for the fact that devfs paths are no longer unsupported. Approved by: re (kib) --- usr.bin/procstat/procstat.1 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1 index a9b32007af8..0fdff9a3c52 100644 --- a/usr.bin/procstat/procstat.1 +++ b/usr.bin/procstat/procstat.1 @@ -351,10 +351,8 @@ may be mechanically parsed. .Pp The display of open file or memory mapping pathnames is implemented using the kernel's name cache. -It therefore does not work for file systems -that do not use the name cache, such as -.Xr devfs 4 , -or if the name is not present in the cache due to removal. +If a file system does not use the name cache, or the path to a file is not in +the cache, a path will not be displayed. .Pp .Nm currently supports extracting data only from a live kernel, and not from From 7e68640f17af133a86a1ea2baf384862c25590a1 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 13 Aug 2009 14:50:39 +0000 Subject: [PATCH 0028/2592] Merge r196121 from head to stable/8: Reverse misordered unlock and lock in at_control for netatalk phase I addresses. Submitted by: Russell Cattelan Approved by: re (kib) --- sys/netatalk/at_control.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netatalk/at_control.c b/sys/netatalk/at_control.c index 5193d668efe..b2d84225c7f 100644 --- a/sys/netatalk/at_control.c +++ b/sys/netatalk/at_control.c @@ -276,7 +276,7 @@ at_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, * If the request is specifying phase 1, then * only look at a phase one address */ - AT_IFADDR_RUNLOCK(); + AT_IFADDR_RLOCK(); for (oaa = aa; aa; aa = TAILQ_NEXT(aa, aa_link)) { if (aa->aa_ifp == ifp && (aa->aa_flags & AFA_PHASE2) == 0) @@ -286,7 +286,7 @@ at_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, ifa_free(&oaa->aa_ifa); if (aa != NULL && oaa != aa) ifa_ref(&aa->aa_ifa); - AT_IFADDR_RLOCK(); + AT_IFADDR_RUNLOCK(); } else { struct at_ifaddr *oaa; From fa1decc4ad08349e8dfc23e3ccd0b2212c72b204 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 13 Aug 2009 15:01:50 +0000 Subject: [PATCH 0029/2592] Merge r196122 from head to stable/8: Correctly audit real gids following changes to the audit record argument interface. Approved by: re (kib) --- sys/security/audit/audit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h index 52bb425b55d..f66f33a4448 100644 --- a/sys/security/audit/audit.h +++ b/sys/security/audit/audit.h @@ -232,7 +232,7 @@ void audit_thread_free(struct thread *td); #define AUDIT_ARG_RGID(rgid) do { \ if (AUDITING_TD(curthread)) \ - audit_arg_gid((rgid)); \ + audit_arg_rgid((rgid)); \ } while (0) #define AUDIT_ARG_RUID(ruid) do { \ From 80ba674cae398779b86ae6debb0e1072fe27aea4 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Thu, 13 Aug 2009 15:02:02 +0000 Subject: [PATCH 0030/2592] MFC r196185: Rather than replicating the maths from the kernel, use the value the kernel calculated directly as we already read it with struct vnet. This will make kvm_vnet.c more resilent in case of possible kernel changes. Reviewed by: rwatson Approved by: re (kib) --- lib/libkvm/kvm_vnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libkvm/kvm_vnet.c b/lib/libkvm/kvm_vnet.c index 1a02cad68d3..d192c67ced0 100644 --- a/lib/libkvm/kvm_vnet.c +++ b/lib/libkvm/kvm_vnet.c @@ -195,7 +195,7 @@ _kvm_vnet_selectpid(kvm_t *kd, pid_t pid) kd->vnet_start = nl[NLIST_START_VNET].n_value; kd->vnet_stop = nl[NLIST_STOP_VNET].n_value; kd->vnet_current = (uintptr_t)prison.pr_vnet; - kd->vnet_base = (uintptr_t)vnet.vnet_data_mem - kd->vnet_start; + kd->vnet_base = vnet.vnet_data_base; return (0); } From 1f9b1ccbd03ace490b42047a3002923def1a0c94 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 13 Aug 2009 15:08:05 +0000 Subject: [PATCH 0031/2592] Merge r196123 from head to stable/8: Update posix1e-related man pages, especially as relates to MAC, to more accurately reflect the last ten years of work. Approved by: re (kib) --- lib/libc/posix1e/Makefile.inc | 4 +- lib/libc/posix1e/mac.3 | 175 ++++++++++++++++------------------ lib/libc/posix1e/mac_free.3 | 9 +- lib/libc/posix1e/mac_get.3 | 1 + lib/libc/posix1e/mac_set.3 | 1 + lib/libc/posix1e/mac_text.3 | 1 + lib/libc/posix1e/posix1e.3 | 116 +++++++++------------- 7 files changed, 140 insertions(+), 167 deletions(-) diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc index de0302bfb52..c9e78bda89d 100644 --- a/lib/libc/posix1e/Makefile.inc +++ b/lib/libc/posix1e/Makefile.inc @@ -106,14 +106,16 @@ MLINKS+=acl_create_entry.3 acl_create_entry_np.3\ mac_get.3 mac_get_fd.3 \ mac_get.3 mac_get_file.3 \ mac_get.3 mac_get_link.3 \ + mac_get.3 mac_get_peer.3 \ mac_get.3 mac_get_pid.3 \ mac_get.3 mac_get_proc.3 \ mac_prepare.3 mac_prepare_file_label.3 \ mac_prepare.3 mac_prepare_ifnet_label.3 \ mac_prepare.3 mac_prepare_process_label.3 \ - mac_set.3 mac_set_link.3 \ + mac_prepare.3 mac_prepare_type.3 \ mac_set.3 mac_set_fd.3 \ mac_set.3 mac_set_file.3 \ + mac_set.3 mac_set_link.3 \ mac_set.3 mac_set_proc.3 \ mac_text.3 mac_from_text.3 \ mac_text.3 mac_to_text.3 diff --git a/lib/libc/posix1e/mac.3 b/lib/libc/posix1e/mac.3 index ac6affd52e5..c570998ba7a 100644 --- a/lib/libc/posix1e/mac.3 +++ b/lib/libc/posix1e/mac.3 @@ -1,4 +1,5 @@ .\" Copyright (c) 2001, 2003 Networks Associates Technology, Inc. +.\" Copyright (c) 2009 Robert N. M. Watson .\" All rights reserved. .\" .\" This software was developed for the FreeBSD Project by Chris @@ -30,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 19, 2003 +.Dd August 7, 2009 .Dt MAC 3 .Os .Sh NAME @@ -44,81 +45,82 @@ In the kernel configuration file: .Cd "options MAC" .Sh DESCRIPTION -.Fx -permits administrators to define Mandatory Access Control labels -defining levels for the privacy and integrity of data, -overriding discretionary policies -for those objects. -Not all objects currently provide support for MAC labels, -and MAC support must be explicitly enabled by the administrator. -The library calls include routines to retrieve, duplicate, -and set MAC labels associated with files and processes. +Mandatory Access Control labels describe confidentiality, integrity, and +other security attributes of operating system objects, overriding +discretionary access control. +Not all system objects support MAC labeling, and MAC policies must be +explicitly enabled by the administrator. +This API, based on POSIX.1e, includes routines to retrieve, manipulate, set, +and convert to and from text the MAC labels on files and processes. .Pp -POSIX.1e describes a set of MAC manipulation routines -to manage the contents of MAC labels, -as well as their relationships with -files and processes; -almost all of these support routines -are implemented in -.Fx . +MAC labels consist of a set of (name, value) tuples, representing security +attributes from MAC policies. +For example, this label contains security labels defined by two policies, +.Xr mac_biba 4 +and +.Xr mac_mls 4 : +.Bd -literal -offset indent +biba/low,mls/low +.Ed .Pp -Available functions, sorted by behavior, include: -.Bl -tag -width indent -.It Fn mac_get_fd -This function is described in -.Xr mac_get 3 , -and may be used to retrieve the -MAC label associated with -a specific file descriptor. -.It Fn mac_get_file -This function is described in -.Xr mac_get 3 , -and may be used to retrieve the -MAC label associated with -a named file. -.It Fn mac_get_proc -This function is described in -.Xr mac_get 3 , -and may be used to retrieve the -MAC label associated with -the calling process. -.It Fn mac_set_fd -This function is described in -.Xr mac_set 3 , -and may be used to set the -MAC label associated with -a specific file descriptor. -.It Fn mac_set_file -This function is described in -.Xr mac_set 3 , -and may be used to set the -MAC label associated with -a named file. -.It Fn mac_set_proc -This function is described in -.Xr mac_set 3 , -and may be used to set the -MAC label associated with -the calling process. -.It Fn mac_free -This function is described in -.Xr mac_free 3 , -and may be used to free -userland working MAC label storage. -.It Fn mac_from_text -This function is described in -.Xr mac_text 3 , -and may be used to convert -a text-form MAC label -into a working -.Vt mac_t . -.It Fn mac_prepare -.It Fn mac_prepare_file_label -.It Fn mac_prepare_ifnet_label -.It Fn mac_prepare_process_label -These functions are described in +Further syntax and semantics of MAC labels may be found in +.Xr maclabel 7 . +.Pp +Applications operate on labels stored in +.Vt mac_t , +but can convert between this internal format and a text format for the +purposes of presentation to uses or external storage. +When querying a label on an object, a +.Vt mac_t +must first be prepared using the interfaces described in .Xr mac_prepare 3 , -and may be used to preallocate storage for MAC label retrieval. +allowing the application to declare which policies it wishes to interogate. +The application writer can also rely on default label names declared in +.Xr mac.conf 5 . +.Pp +When finished with a +.Vt mac_t , +the application must call +.Xr mac_free 3 +to release its storage. +.Pp +The following functions are defined: +.Bl -tag -width indent +.It Fn mac_is_present +This function, described in +.Xr mac_is_present 3 , +allows applications to test whether MAC is configured, as well as whether +specific policies are configured. +.It Fn mac_get_fd , Fn mac_get_file , Fn mac_get_link , Fn mac_get_peer +These functions, described in +.Xr mac_get 3 , +retrieve the MAC labels associated with file descriptors, files, and socket +peers. +.It Fn mac_get_pid , Fn mac_get_proc +These functions, described in +.Xr mac_get 3 , +retrieve the MAC labels associated with processes. +.It Fn mac_set_fd , Fn mac_set_file , Fn mac_set_link +These functions, described in +.Xr mac_set 3 , +set the MAC labels associated with file descriptors and files. +.It Fn mac_set_proc +This function, described in +.Xr mac_set 3 , +sets the MAC label associated with the current process. +.It Fn mac_free +This function, desribed in +.Xr mac_free 3 , +frees working MAC label storage. +.It Fn mac_from_text +This function, described in +.Xr mac_text 3 , +converts a text-form MAC label into working MAC label storage, +.Vt mac_t . +.It Fn mac_prepare , Fn mac_prepare_file_label , Fn mac_prepare_ifnet_label , Fn mac_prepare_process_label , Fn mac_prepare_type +These functions, described in +.Xr mac_prepare 3 , +allocate working storage for MAC label operations. .Xr mac_prepare 3 prepares a label based on caller-specified label names; the other calls rely on the default configuration specified in @@ -130,15 +132,6 @@ and may be used to convert a .Vt mac_t into a text-form MAC label. .El -The behavior of some of these calls is influenced by the configuration -settings found in -.Xr mac.conf 5 , -the MAC library run-time configuration file. -.Sh IMPLEMENTATION NOTES -.Fx Ns 's -support for POSIX.1e interfaces and features -is -.Ud . .Sh FILES .Bl -tag -width ".Pa /etc/mac.conf" -compact .It Pa /etc/mac.conf @@ -150,24 +143,20 @@ system objects, but without policy-specific knowledge. .Sh SEE ALSO .Xr mac_free 3 , .Xr mac_get 3 , +.Xr mac_is_present 3 , .Xr mac_prepare 3 , .Xr mac_set 3 , .Xr mac_text 3 , +.Xr posix1e 3 , .Xr mac 4 , .Xr mac.conf 5 , .Xr mac 9 .Sh STANDARDS -These APIs are loosely based on the APIs described in POSIX.1e. -POSIX.1e is described in IEEE POSIX.1e draft 17. -Discussion of the draft -continues on the cross-platform POSIX.1e implementation mailing list. -To join this list, see the -.Fx -POSIX.1e implementation page -for more information. -However, the resemblance of these APIs to the POSIX APIs is only loose, -as the POSIX APIs were unable to express many notions required for -flexible and extensible access control. +These APIs are loosely based on the APIs described in POSIX.1e, as described +in IEEE POSIX.1e draft 17. +However, the resemblence of these APIS to the POSIX APIs is loose, as the +PSOXI APIS were unable to express some notinos required for flexible and +extensible access control. .Sh HISTORY Support for Mandatory Access Control was introduced in .Fx 5.0 diff --git a/lib/libc/posix1e/mac_free.3 b/lib/libc/posix1e/mac_free.3 index 33ef9ec785a..78118a1efa5 100644 --- a/lib/libc/posix1e/mac_free.3 +++ b/lib/libc/posix1e/mac_free.3 @@ -64,6 +64,7 @@ function. .Xr mac_prepare 3 , .Xr mac_set 3 , .Xr mac_text 3 , +.Xr posix1e 3 , .Xr mac 4 , .Xr mac 9 .Sh STANDARDS @@ -91,8 +92,8 @@ is a complex structure in the .Tn TrustedBSD implementation, .Fn mac_free -is specific to that type, and must not be used to free the character -strings returned from +is specific to +.Vt mac_3 , +and must not be used to free the character strings returned from .Fn mac_to_text . -Doing so may result in undefined behavior, -including application failure. +Doing so may result in undefined behavior. diff --git a/lib/libc/posix1e/mac_get.3 b/lib/libc/posix1e/mac_get.3 index cd498d0e4e7..35fa72b0824 100644 --- a/lib/libc/posix1e/mac_get.3 +++ b/lib/libc/posix1e/mac_get.3 @@ -133,6 +133,7 @@ is not a directory. .Xr mac_prepare 3 , .Xr mac_set 3 , .Xr mac_text 3 , +.Xr posix1e 3 , .Xr mac 4 , .Xr mac 9 .Sh STANDARDS diff --git a/lib/libc/posix1e/mac_set.3 b/lib/libc/posix1e/mac_set.3 index 84a1800412d..0b245a00027 100644 --- a/lib/libc/posix1e/mac_set.3 +++ b/lib/libc/posix1e/mac_set.3 @@ -138,6 +138,7 @@ is not a directory. .Xr mac_is_present 3 , .Xr mac_prepare 3 , .Xr mac_text 3 , +.Xr posix1e 3 , .Xr mac 4 , .Xr mac 9 .Sh HISTORY diff --git a/lib/libc/posix1e/mac_text.3 b/lib/libc/posix1e/mac_text.3 index 66c1e211394..dde6ccf5e23 100644 --- a/lib/libc/posix1e/mac_text.3 +++ b/lib/libc/posix1e/mac_text.3 @@ -98,6 +98,7 @@ to allocate internal storage. .Xr mac_is_present 3 , .Xr mac_prepare 3 , .Xr mac_set 3 , +.Xr posix1e 3 , .Xr mac 4 , .Xr maclabel 7 .Sh STANDARDS diff --git a/lib/libc/posix1e/posix1e.3 b/lib/libc/posix1e/posix1e.3 index 2065523bad9..84ce2ec80d1 100644 --- a/lib/libc/posix1e/posix1e.3 +++ b/lib/libc/posix1e/posix1e.3 @@ -1,5 +1,5 @@ .\"- -.\" Copyright (c) 2000 Robert N. M. Watson +.\" Copyright (c) 2000, 2009 Robert N. M. Watson .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 20, 2009 +.Dd August 7, 2009 .Dt POSIX1E 3 .Os .Sh NAME @@ -36,99 +36,77 @@ .Sh SYNOPSIS .In sys/types.h .In sys/acl.h -.\" .In sys/capability.h .In sys/mac.h .Sh DESCRIPTION -The IEEE POSIX.1e specification never left draft form, but the interfaces -it describes are now widely used despite inherent limitations. -Currently, only a few of the interfaces and features are implemented in -.Fx , -although efforts are underway to complete the integration at this time. +POSIX.1e describes five security extensions to the POSIX.1 API: Access +Control Lists (ACLs), Auditing, Capabilities, Mandatory Access Control, and +Information Flow Labels. +While IEEE POSIX.1e D17 specification has not been standardized, several of +its interfaces are widely used. .Pp -POSIX.1e describes five security extensions to the base POSIX.1 API: -Access Control Lists (ACLs), Auditing, Capabilities, Mandatory Access -Control, and Information Flow Labels. .Fx -supports POSIX.1e ACL interfaces, as well as POSIX.1e-like MAC -interfaces. -The TrustedBSD Project has produced but not integrated an implementation -of POSIX.1e Capabilities. +implements POSIX.1e interface for access control lists, described in +.Xr acl 3 , +and supports ACLs on the +.Xr ffs 7 +file system; ACLs must be administratively enabled using +.Xr tunefs 8 . .Pp -POSIX.1e defines both syntax and semantics for these features, but fairly -substantial changes are required to implement these features in the -operating system. +.Fx +implements a POSIX.1e-like mandatory access control interface, described in +.Xr mac 3 , +although with a number of extensions and important semantic differences. .Pp -As shipped, -.Fx 4.0 -provides API and VFS support for ACLs, but not an implementation on any -native file system. -.Fx 5.0 -includes support for ACLs as part of UFS1 and UFS2, as well as necessary -VFS support for additional file systems to export ACLs as appropriate. -Available API calls relating to ACLs are described in detail in -.Xr acl 3 . -.Pp -As shipped, -.Fx 5.0 -includes support for Mandatory Access Control as well as POSIX.1e-like -APIs for label management. -More information on API calls relating to MAC is available in -.Xr mac 3 . -.Pp -Additional patches supporting POSIX.1e features are provided by the -TrustedBSD project: -.Pp -http://www.TrustedBSD.org/ -.Sh IMPLEMENTATION NOTES -.Fx Ns 's -support for POSIX.1e interfaces and features is still under -development at this time, and many of these features are considered new -or experimental. +.Fx +does not implement the POSIX.1e audit, privilege (capability), or information +flow label APIs. +However, +.Fx +does implement the +.Xr libbsm +audit API. .Sh ENVIRONMENT -POSIX.1e assigns security labels to all objects, extending the security +POSIX.1e assigns security attributes to all objects, extending the security functionality described in POSIX.1. -These additional labels provide -fine-grained discretionary access control, fine-grained capabilities, -and labels necessary for mandatory access control. -POSIX.2c describes -a set of userland utilities for manipulating these labels. +These additional attributes store fine-grained discretionary access control +information and mandatory access control labels; for files, they are stored +in extended attributes, described in +.Xr extattr 3 . .Pp -Many of these services are supported by extended attributes, documented -in -.Xr extattr 2 +POSIX.2c describes +a set of userland utilities for manipulating these attributes, including +.Xr getfacl 1 and -.Xr extattr 9 . -While these APIs are not documented in POSIX.1e, they are similar in -structure. +.Xr setfacl 1 +for access control lists, and +.Xr getfmac 8 +and +.Xr setfmac 8 +for mandatory access control labels. .Sh SEE ALSO +.Xr getfacl 1 , +.Xr setfacl 1 , .Xr extattr 2 , .Xr acl 3 , +.Xr extattr 3 , .Xr libbsm 3 , .Xr mac 3 , +.Xr ffs 7 , +.Xr getfmac 8 , +.Xr setfmac 8 , +.Xr tunefs 8 , .Xr acl 9 , .Xr extattr 9 , .Xr mac 9 .Sh STANDARDS POSIX.1e is described in IEEE POSIX.1e draft 17. -Discussion of the draft continues -on the cross-platform POSIX.1e implementation -mailing list. -To join this list, see the -.Fx -POSIX.1e implementation -page for more information. .Sh HISTORY POSIX.1e support was introduced in .Fx 4.0 ; -most of the features are available as of +most features were available as of .Fx 5.0 . -Development continues. .Sh AUTHORS .An Robert N M Watson .An Chris D. Faulhaber .An Thomas Moestl .An Ilmar S Habibulin -.Sh BUGS -Many of these features are considered new or experimental in -.Fx 5.0 -and should be deployed with appropriate caution. From 60df4aa10399717be4f7e47e9580d02f8af8ac93 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 13 Aug 2009 16:01:19 +0000 Subject: [PATCH 0032/2592] MFC r196193: Use correct wbinv operation in pmap_l2cache_wbinv_range(). Submitted by: Michal Hajduk Reviewed by: stas Approved by: re (kib) Obtained from: Semihalf --- sys/arm/arm/pmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c index 19c7236f173..1b9bf81f174 100644 --- a/sys/arm/arm/pmap.c +++ b/sys/arm/arm/pmap.c @@ -1212,7 +1212,7 @@ pmap_l2cache_wbinv_range(pmap_t pm, vm_offset_t va, vm_size_t len) CTR4(KTR_PMAP, "pmap_l2cache_wbinv_range: pmap %p is_kernel %d " "va 0x%08x len 0x%x ", pm, pm == pmap_kernel(), va, rest); if (pmap_get_pde_pte(pm, va, &pde, &ptep) && l2pte_valid(*ptep)) - cpu_l2cache_wb_range(va, rest); + cpu_l2cache_wbinv_range(va, rest); len -= rest; va += rest; From be1057174e6277ebf114d3edbcb06738da364a13 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Thu, 13 Aug 2009 17:54:11 +0000 Subject: [PATCH 0033/2592] MFC r196196: * Completely remove the option STOP_NMI from the kernel. This option has proven to have a good effect when entering KDB by using a NMI, but it completely violates all the good rules about interrupts disabled while holding a spinlock in other occasions. This can be the cause of deadlocks on events where a normal IPI_STOP is expected. * Add an new IPI called IPI_STOP_HARD on all the supported architectures. This IPI is responsible for sending a stop message among CPUs using a privileged channel when disponible. In other cases it just does match a normal IPI_STOP. Right now the IPI_STOP_HARD functionality uses a NMI on ia32 and amd64 architectures, while on the other has a normal IPI_STOP effect. It is responsibility of maintainers to eventually implement an hard stop when necessary and possible. * Use the new IPI facility in order to implement a new userend SMP kernel function called stop_cpus_hard(). That is specular to stop_cpu() but it does use the privileged channel for the stopping facility. * Let KDB use the newly introduced function stop_cpus_hard() and leave stop_cpus() for all the other cases * Disable interrupts on CPU0 when starting the process of APs suspension. * Style cleanup and comments adding This patch should fix the reboot/shutdown deadlocks many users are constantly reporting on mailing lists. Please don't forget to update your config file with the STOP_NMI option removal Reviewed by: jhb Tested by: pho, bz, rink Approved by: re (kib) --- UPDATING | 6 ++ sys/amd64/amd64/local_apic.c | 13 +++- sys/amd64/amd64/mp_machdep.c | 100 ++++++++++--------------------- sys/amd64/amd64/trap.c | 2 - sys/amd64/conf/GENERIC | 1 - sys/amd64/conf/NOTES | 5 -- sys/amd64/conf/XENHVM | 1 - sys/amd64/include/apicvar.h | 6 +- sys/amd64/include/smp.h | 5 +- sys/conf/options.amd64 | 1 - sys/conf/options.i386 | 1 - sys/conf/options.pc98 | 1 - sys/i386/conf/GENERIC | 1 - sys/i386/conf/NOTES | 1 - sys/i386/i386/local_apic.c | 13 +++- sys/i386/i386/mp_machdep.c | 99 ++++++++++-------------------- sys/i386/i386/trap.c | 2 - sys/i386/include/apicvar.h | 7 +-- sys/i386/include/smp.h | 6 +- sys/i386/xen/mp_machdep.c | 2 - sys/ia64/ia64/interrupt.c | 2 + sys/ia64/include/smp.h | 1 + sys/kern/kern_shutdown.c | 10 +++- sys/kern/subr_kdb.c | 7 ++- sys/kern/subr_smp.c | 25 ++++++-- sys/mips/include/smp.h | 1 + sys/mips/mips/mp_machdep.c | 7 ++- sys/pc98/conf/NOTES | 4 -- sys/powerpc/include/smp.h | 1 + sys/powerpc/powerpc/mp_machdep.c | 8 ++- sys/sparc64/include/smp.h | 1 + sys/sun4v/include/smp.h | 1 + sys/sys/smp.h | 1 + 33 files changed, 148 insertions(+), 194 deletions(-) diff --git a/UPDATING b/UPDATING index 02369b0290a..6dab13884fe 100644 --- a/UPDATING +++ b/UPDATING @@ -22,6 +22,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW: to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20090813: + Remove the option STOP_NMI. The default action is now to use NMI + only for KDB via the newly introduced function stop_cpus_hard() + and maintain stop_cpus() to just use a normal IPI_STOP on ia32 + and amd64. + 20090803: RELENG_8 branched. diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c index 14559f3aa45..cd3073caf99 100644 --- a/sys/amd64/amd64/local_apic.c +++ b/sys/amd64/amd64/local_apic.c @@ -1238,8 +1238,17 @@ lapic_ipi_vectored(u_int vector, int dest) KASSERT((vector & ~APIC_VECTOR_MASK) == 0, ("%s: invalid vector %d", __func__, vector)); - icrlo = vector | APIC_DELMODE_FIXED | APIC_DESTMODE_PHY | - APIC_LEVEL_DEASSERT | APIC_TRIGMOD_EDGE; + icrlo = APIC_DESTMODE_PHY | APIC_TRIGMOD_EDGE; + + /* + * IPI_STOP_HARD is just a "fake" vector used to send a NMI. + * Use special rules regard NMI if passed, otherwise specify + * the vector. + */ + if (vector == IPI_STOP_HARD) + icrlo |= APIC_DELMODE_NMI | APIC_LEVEL_ASSERT; + else + icrlo |= vector | APIC_DELMODE_FIXED | APIC_LEVEL_DEASSERT; destfield = 0; switch (dest) { case APIC_IPI_DEST_SELF: diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 52c209c993a..0ef80173b28 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -114,31 +114,12 @@ volatile int smp_tlb_wait; extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32); -#ifdef STOP_NMI -static volatile cpumask_t ipi_nmi_pending; - -static void ipi_nmi_selected(cpumask_t cpus); -#endif - /* * Local data and functions. */ -#ifdef STOP_NMI -/* - * Provide an alternate method of stopping other CPUs. If another CPU has - * disabled interrupts the conventional STOP IPI will be blocked. This - * NMI-based stop should get through in that case. - */ -static int stop_cpus_with_nmi = 1; -SYSCTL_INT(_debug, OID_AUTO, stop_cpus_with_nmi, CTLTYPE_INT | CTLFLAG_RW, - &stop_cpus_with_nmi, 0, ""); -TUNABLE_INT("debug.stop_cpus_with_nmi", &stop_cpus_with_nmi); -#else -#define stop_cpus_with_nmi 0 -#endif - static u_int logical_cpus; +static volatile cpumask_t ipi_nmi_pending; /* used to hold the AP's until we are ready to release them */ static struct mtx ap_boot_mtx; @@ -1158,12 +1139,14 @@ ipi_selected(cpumask_t cpus, u_int ipi) ipi = IPI_BITMAP_VECTOR; } -#ifdef STOP_NMI - if (ipi == IPI_STOP && stop_cpus_with_nmi) { - ipi_nmi_selected(cpus); - return; - } -#endif + /* + * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit + * of help in order to understand what is the source. + * Set the mask of receiving CPUs for this purpose. + */ + if (ipi == IPI_STOP_HARD) + atomic_set_int(&ipi_nmi_pending, cpus); + CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); while ((cpu = ffs(cpus)) != 0) { cpu--; @@ -1194,64 +1177,43 @@ void ipi_all_but_self(u_int ipi) { - if (IPI_IS_BITMAPED(ipi) || (ipi == IPI_STOP && stop_cpus_with_nmi)) { + if (IPI_IS_BITMAPED(ipi)) { ipi_selected(PCPU_GET(other_cpus), ipi); return; } + + /* + * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit + * of help in order to understand what is the source. + * Set the mask of receiving CPUs for this purpose. + */ + if (ipi == IPI_STOP_HARD) + atomic_set_int(&ipi_nmi_pending, PCPU_GET(other_cpus)); + CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS); } -#ifdef STOP_NMI -/* - * send NMI IPI to selected CPUs - */ - -#define BEFORE_SPIN 1000000 - -static void -ipi_nmi_selected(cpumask_t cpus) -{ - int cpu; - register_t icrlo; - - icrlo = APIC_DELMODE_NMI | APIC_DESTMODE_PHY | APIC_LEVEL_ASSERT - | APIC_TRIGMOD_EDGE; - - CTR2(KTR_SMP, "%s: cpus: %x nmi", __func__, cpus); - - atomic_set_int(&ipi_nmi_pending, cpus); - - while ((cpu = ffs(cpus)) != 0) { - cpu--; - cpus &= ~(1 << cpu); - - KASSERT(cpu_apic_ids[cpu] != -1, - ("IPI NMI to non-existent CPU %d", cpu)); - - /* Wait for an earlier IPI to finish. */ - if (!lapic_ipi_wait(BEFORE_SPIN)) - panic("ipi_nmi_selected: previous IPI has not cleared"); - - lapic_ipi_raw(icrlo, cpu_apic_ids[cpu]); - } -} - int -ipi_nmi_handler(void) +ipi_nmi_handler() { - int cpumask = PCPU_GET(cpumask); + cpumask_t cpumask; - if (!(ipi_nmi_pending & cpumask)) - return 1; + /* + * As long as there is not a simple way to know about a NMI's + * source, if the bitmask for the current CPU is present in + * the global pending bitword an IPI_STOP_HARD has been issued + * and should be handled. + */ + cpumask = PCPU_GET(cpumask); + if ((ipi_nmi_pending & cpumask) == 0) + return (1); atomic_clear_int(&ipi_nmi_pending, cpumask); cpustop_handler(); - return 0; + return (0); } -#endif /* STOP_NMI */ - /* * Handle an IPI_STOP by saving our current context and spinning until we * are resumed. diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index fee3caf6a9d..323e8d1677a 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -239,13 +239,11 @@ trap(struct trapframe *frame) type = frame->tf_trapno; #ifdef SMP -#ifdef STOP_NMI /* Handler for NMI IPIs used for stopping CPUs. */ if (type == T_NMI) { if (ipi_nmi_handler() == 0) goto out; } -#endif /* STOP_NMI */ #endif /* SMP */ #ifdef KDB diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 73a4fb66e4d..a49f7bca10c 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -69,7 +69,6 @@ options P1003_1B_SEMAPHORES # POSIX-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options STOP_NMI # Stop CPUS using NMI instead of IPI options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) options AUDIT # Security event auditing options MAC # TrustedBSD MAC Framework diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index 088a381f177..27fe0680580 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -30,11 +30,6 @@ device mptable # Optional MPSPEC mptable support # options MP_WATCHDOG -# -# Debugging options. -# -options STOP_NMI # Stop CPUS using NMI instead of IPI - ##################################################################### diff --git a/sys/amd64/conf/XENHVM b/sys/amd64/conf/XENHVM index 5e108d51ea2..1536e3c74b6 100644 --- a/sys/amd64/conf/XENHVM +++ b/sys/amd64/conf/XENHVM @@ -68,7 +68,6 @@ options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options STOP_NMI # Stop CPUS using NMI instead of IPI options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) options AUDIT # Security event auditing #options KDTRACE_FRAME # Ensure frames are compiled in diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h index 84ba3b8fa88..73fff6c006f 100644 --- a/sys/amd64/include/apicvar.h +++ b/sys/amd64/include/apicvar.h @@ -102,11 +102,6 @@ * smp_ipi_mtx and waits for the completion of the IPI (Only one IPI user * at a time) The second group uses a single interrupt and a bitmap to avoid * redundant IPI interrupts. - * - * Right now IPI_STOP used by kdb shares the interrupt priority class with - * the two IPI groups mentioned above. As such IPI_STOP may cause a deadlock. - * Eventually IPI_STOP should use NMI IPIs - this would eliminate this and - * other deadlocks caused by IPI_STOP. */ /* Interrupts for local APIC LVT entries other than the timer. */ @@ -134,6 +129,7 @@ #define IPI_STOP (APIC_IPI_INTS + 7) /* Stop CPU until restarted. */ #define IPI_SUSPEND (APIC_IPI_INTS + 8) /* Suspend CPU until restarted. */ +#define IPI_STOP_HARD (APIC_IPI_INTS + 9) /* Stop CPU with a NMI. */ /* * The spurious interrupt can share the priority class with the IPIs since diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index d2957158027..1cc21a447f0 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -52,6 +52,7 @@ void cpu_add(u_int apic_id, char boot_cpu); void cpustop_handler(void); void cpususpend_handler(void); void init_secondary(void); +int ipi_nmi_handler(void); void ipi_selected(cpumask_t cpus, u_int ipi); void ipi_all_but_self(u_int ipi); void ipi_bitmap_handler(struct trapframe frame); @@ -66,10 +67,6 @@ void smp_masked_invlpg_range(cpumask_t mask, vm_offset_t startva, void smp_invltlb(void); void smp_masked_invltlb(cpumask_t mask); -#ifdef STOP_NMI -int ipi_nmi_handler(void); -#endif - #endif /* !LOCORE */ #endif /* SMP */ diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64 index 5247921eb8a..beb97ed7d1e 100644 --- a/sys/conf/options.amd64 +++ b/sys/conf/options.amd64 @@ -52,7 +52,6 @@ PSM_DEBUG opt_psm.h DEV_ATPIC opt_atpic.h # Debugging -STOP_NMI opt_cpu.h KDTRACE_FRAME opt_kdtrace.h # BPF just-in-time compiler diff --git a/sys/conf/options.i386 b/sys/conf/options.i386 index 45a1637fe9e..cd2ab98dafc 100644 --- a/sys/conf/options.i386 +++ b/sys/conf/options.i386 @@ -110,7 +110,6 @@ ASR_COMPAT opt_asr.h # Debugging NPX_DEBUG opt_npx.h -STOP_NMI opt_cpu.h # BPF just-in-time compiler BPF_JITTER opt_bpf.h diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98 index 837169b6ff5..dca3d694ae7 100644 --- a/sys/conf/options.pc98 +++ b/sys/conf/options.pc98 @@ -95,7 +95,6 @@ DEV_NPX opt_npx.h # Debugging NPX_DEBUG opt_npx.h -STOP_NMI opt_cpu.h AGP_DEBUG opt_agp.h # BPF just-in-time compiler diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 02f5a36ddab..ef958af9a14 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -70,7 +70,6 @@ options P1003_1B_SEMAPHORES # POSIX-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options STOP_NMI # Stop CPUS using NMI instead of IPI options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) options AUDIT # Security event auditing options MAC # TrustedBSD MAC Framework diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index f442e2455e1..f772b25584d 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -49,7 +49,6 @@ options MP_WATCHDOG # Debugging options. # -options STOP_NMI # Stop CPUS using NMI instead of IPI options COUNT_XINVLTLB_HITS # Counters for TLB events options COUNT_IPIS # Per-CPU IPI interrupt counters diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c index 6b350e29794..2cc6a450482 100644 --- a/sys/i386/i386/local_apic.c +++ b/sys/i386/i386/local_apic.c @@ -1248,8 +1248,17 @@ lapic_ipi_vectored(u_int vector, int dest) KASSERT((vector & ~APIC_VECTOR_MASK) == 0, ("%s: invalid vector %d", __func__, vector)); - icrlo = vector | APIC_DELMODE_FIXED | APIC_DESTMODE_PHY | - APIC_LEVEL_DEASSERT | APIC_TRIGMOD_EDGE; + icrlo = APIC_DESTMODE_PHY | APIC_TRIGMOD_EDGE; + + /* + * IPI_STOP_HARD is just a "fake" vector used to send a NMI. + * Use special rules regard NMI if passed, otherwise specify + * the vector. + */ + if (vector == IPI_STOP_HARD) + icrlo |= APIC_DELMODE_NMI | APIC_LEVEL_ASSERT; + else + icrlo |= vector | APIC_DELMODE_FIXED | APIC_LEVEL_DEASSERT; destfield = 0; switch (dest) { case APIC_IPI_DEST_SELF: diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 0bfe91d7cff..6729288d69c 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -155,12 +155,6 @@ vm_offset_t smp_tlb_addr1; vm_offset_t smp_tlb_addr2; volatile int smp_tlb_wait; -#ifdef STOP_NMI -static volatile cpumask_t ipi_nmi_pending; - -static void ipi_nmi_selected(cpumask_t cpus); -#endif - #ifdef COUNT_IPIS /* Interrupt counts. */ static u_long *ipi_preempt_counts[MAXCPU]; @@ -177,21 +171,8 @@ u_long *ipi_lazypmap_counts[MAXCPU]; * Local data and functions. */ -#ifdef STOP_NMI -/* - * Provide an alternate method of stopping other CPUs. If another CPU has - * disabled interrupts the conventional STOP IPI will be blocked. This - * NMI-based stop should get through in that case. - */ -static int stop_cpus_with_nmi = 1; -SYSCTL_INT(_debug, OID_AUTO, stop_cpus_with_nmi, CTLTYPE_INT | CTLFLAG_RW, - &stop_cpus_with_nmi, 0, ""); -TUNABLE_INT("debug.stop_cpus_with_nmi", &stop_cpus_with_nmi); -#else -#define stop_cpus_with_nmi 0 -#endif - static u_int logical_cpus; +static volatile cpumask_t ipi_nmi_pending; /* used to hold the AP's until we are ready to release them */ static struct mtx ap_boot_mtx; @@ -1318,12 +1299,14 @@ ipi_selected(cpumask_t cpus, u_int ipi) ipi = IPI_BITMAP_VECTOR; } -#ifdef STOP_NMI - if (ipi == IPI_STOP && stop_cpus_with_nmi) { - ipi_nmi_selected(cpus); - return; - } -#endif + /* + * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit + * of help in order to understand what is the source. + * Set the mask of receiving CPUs for this purpose. + */ + if (ipi == IPI_STOP_HARD) + atomic_set_int(&ipi_nmi_pending, cpus); + CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); while ((cpu = ffs(cpus)) != 0) { cpu--; @@ -1354,64 +1337,42 @@ void ipi_all_but_self(u_int ipi) { - if (IPI_IS_BITMAPED(ipi) || (ipi == IPI_STOP && stop_cpus_with_nmi)) { + if (IPI_IS_BITMAPED(ipi)) { ipi_selected(PCPU_GET(other_cpus), ipi); return; } + + /* + * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit + * of help in order to understand what is the source. + * Set the mask of receiving CPUs for this purpose. + */ + if (ipi == IPI_STOP_HARD) + atomic_set_int(&ipi_nmi_pending, PCPU_GET(other_cpus)); CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS); } -#ifdef STOP_NMI -/* - * send NMI IPI to selected CPUs - */ - -#define BEFORE_SPIN 1000000 - -void -ipi_nmi_selected(cpumask_t cpus) -{ - int cpu; - register_t icrlo; - - icrlo = APIC_DELMODE_NMI | APIC_DESTMODE_PHY | APIC_LEVEL_ASSERT - | APIC_TRIGMOD_EDGE; - - CTR2(KTR_SMP, "%s: cpus: %x nmi", __func__, cpus); - - atomic_set_int(&ipi_nmi_pending, cpus); - - while ((cpu = ffs(cpus)) != 0) { - cpu--; - cpus &= ~(1 << cpu); - - KASSERT(cpu_apic_ids[cpu] != -1, - ("IPI NMI to non-existent CPU %d", cpu)); - - /* Wait for an earlier IPI to finish. */ - if (!lapic_ipi_wait(BEFORE_SPIN)) - panic("ipi_nmi_selected: previous IPI has not cleared"); - - lapic_ipi_raw(icrlo, cpu_apic_ids[cpu]); - } -} - int -ipi_nmi_handler(void) +ipi_nmi_handler() { - int cpumask = PCPU_GET(cpumask); + cpumask_t cpumask; - if (!(ipi_nmi_pending & cpumask)) - return 1; + /* + * As long as there is not a simple way to know about a NMI's + * source, if the bitmask for the current CPU is present in + * the global pending bitword an IPI_STOP_HARD has been issued + * and should be handled. + */ + cpumask = PCPU_GET(cpumask); + if ((ipi_nmi_pending & cpumask) == 0) + return (1); atomic_clear_int(&ipi_nmi_pending, cpumask); cpustop_handler(); - return 0; + return (0); } -#endif /* STOP_NMI */ - /* * Handle an IPI_STOP by saving our current context and spinning until we * are resumed. diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index e9671046060..354d791c6f4 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -211,13 +211,11 @@ trap(struct trapframe *frame) type = frame->tf_trapno; #ifdef SMP -#ifdef STOP_NMI /* Handler for NMI IPIs used for stopping CPUs. */ if (type == T_NMI) { if (ipi_nmi_handler() == 0) goto out; } -#endif /* STOP_NMI */ #endif /* SMP */ #ifdef KDB diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h index a03c083705c..a13766f95f9 100644 --- a/sys/i386/include/apicvar.h +++ b/sys/i386/include/apicvar.h @@ -100,11 +100,6 @@ * smp_ipi_mtx and waits for the completion of the IPI (Only one IPI user * at a time) The second group uses a single interrupt and a bitmap to avoid * redundant IPI interrupts. - * - * Right now IPI_STOP used by kdb shares the interrupt priority class with - * the two IPI groups mentioned above. As such IPI_STOP may cause a deadlock. - * Eventually IPI_STOP should use NMI IPIs - this would eliminate this and - * other deadlocks caused by IPI_STOP. */ /* Interrupts for local APIC LVT entries other than the timer. */ @@ -134,6 +129,7 @@ #define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST) #define IPI_STOP (APIC_IPI_INTS + 7) /* Stop CPU until restarted. */ +#define IPI_STOP_HARD (APIC_IPI_INTS + 8) /* Stop CPU with a NMI. */ #else /* XEN */ /* These are the normal i386 APIC definitions */ @@ -161,6 +157,7 @@ #define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST) #define IPI_STOP (APIC_IPI_INTS + 7) /* Stop CPU until restarted. */ +#define IPI_STOP_HARD (APIC_IPI_INTS + 8) /* Stop CPU with a NMI. */ #endif /* XEN */ /* diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index 917c2851eee..968cdb4f94e 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -60,7 +60,8 @@ inthand_t void cpu_add(u_int apic_id, char boot_cpu); void cpustop_handler(void); void init_secondary(void); -void ipi_selected(u_int cpus, u_int ipi); +int ipi_nmi_handler(void); +void ipi_selected(cpumask_t cpus, u_int ipi); void ipi_all_but_self(u_int ipi); #ifndef XEN void ipi_bitmap_handler(struct trapframe frame); @@ -76,9 +77,6 @@ void smp_masked_invlpg_range(cpumask_t mask, vm_offset_t startva, void smp_invltlb(void); void smp_masked_invltlb(cpumask_t mask); -#ifdef STOP_NMI -int ipi_nmi_handler(void); -#endif #ifdef XEN void ipi_to_irq_init(void); diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index 3aa03cef41f..bae07d4f608 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -90,8 +90,6 @@ __FBSDID("$FreeBSD$"); #include #include -#define stop_cpus_with_nmi 0 - int mp_naps; /* # of Applications processors */ int boot_cpu_id = -1; /* designated BSP */ diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index 0c50b48a88b..b70a807591a 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -145,6 +145,8 @@ interrupt(struct trapframe *tf) /* * Handle ExtINT interrupts by generating an INTA cycle to * read the vector. + * IPI_STOP_HARD is mapped to IPI_STOP so it is not necessary + * to add it to this switch-like construct. */ if (vector == 0) { inta = ib->ib_inta; diff --git a/sys/ia64/include/smp.h b/sys/ia64/include/smp.h index c6d98f7b4f3..4eddf7434fe 100644 --- a/sys/ia64/include/smp.h +++ b/sys/ia64/include/smp.h @@ -21,6 +21,7 @@ #define IPI_AST 4 #define IPI_RENDEZVOUS 5 #define IPI_STOP 6 +#define IPI_STOP_HARD 6 #define IPI_PREEMPT 7 #define IPI_COUNT 8 diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 80dda97f977..0f3a672a299 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -412,9 +412,6 @@ boot(int howto) */ EVENTHANDLER_INVOKE(shutdown_post_sync, howto); - /* XXX This doesn't disable interrupts any more. Reconsider? */ - splhigh(); - if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold && !dumping) doadump(); @@ -488,6 +485,13 @@ static void shutdown_reset(void *junk, int howto) { + /* + * Disable interrupts on CPU0 in order to avoid fast handlers + * to preempt the stopping process and to deadlock against other + * CPUs. + */ + spinlock_enter(); + printf("Rebooting...\n"); DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ /* cpu_boot(howto); */ /* doesn't do anything at the moment */ diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c index e6af53e67b0..3e77db7af83 100644 --- a/sys/kern/subr_kdb.c +++ b/sys/kern/subr_kdb.c @@ -88,7 +88,8 @@ SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code, CTLTYPE_INT | CTLFLAG_RW, NULL, 0, * Flag indicating whether or not to IPI the other CPUs to stop them on * entering the debugger. Sometimes, this will result in a deadlock as * stop_cpus() waits for the other cpus to stop, so we allow it to be - * disabled. + * disabled. In order to maximize the chances of success, use a hard + * stop for that. */ #ifdef SMP static int kdb_stop_cpus = 1; @@ -226,7 +227,7 @@ kdb_panic(const char *msg) { #ifdef SMP - stop_cpus(PCPU_GET(other_cpus)); + stop_cpus_hard(PCPU_GET(other_cpus)); #endif printf("KDB: panic\n"); panic(msg); @@ -518,7 +519,7 @@ kdb_trap(int type, int code, struct trapframe *tf) #ifdef SMP if ((did_stop_cpus = kdb_stop_cpus) != 0) - stop_cpus(PCPU_GET(other_cpus)); + stop_cpus_hard(PCPU_GET(other_cpus)); #endif kdb_active++; diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index d64e80604b3..d28001f7cc7 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -233,18 +233,21 @@ forward_roundrobin(void) * XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs * from executing at same time. */ -int -stop_cpus(cpumask_t map) +static int +generic_stop_cpus(cpumask_t map, u_int type) { int i; + KASSERT(type == IPI_STOP || type == IPI_STOP_HARD, + ("%s: invalid stop type", __func__)); + if (!smp_started) return 0; - CTR1(KTR_SMP, "stop_cpus(%x)", map); + CTR2(KTR_SMP, "stop_cpus(%x) with %u type", map, type); /* send the stop IPI to all CPUs in map */ - ipi_selected(map, IPI_STOP); + ipi_selected(map, type); i = 0; while ((stopped_cpus & map) != map) { @@ -262,6 +265,20 @@ stop_cpus(cpumask_t map) return 1; } +int +stop_cpus(cpumask_t map) +{ + + return (generic_stop_cpus(map, IPI_STOP)); +} + +int +stop_cpus_hard(cpumask_t map) +{ + + return (generic_stop_cpus(map, IPI_STOP_HARD)); +} + #if defined(__amd64__) /* * When called the executing CPU will send an IPI to all other CPUs diff --git a/sys/mips/include/smp.h b/sys/mips/include/smp.h index 798beed245c..d614dd3dbf9 100644 --- a/sys/mips/include/smp.h +++ b/sys/mips/include/smp.h @@ -24,6 +24,7 @@ #define IPI_RENDEZVOUS 0x0002 #define IPI_AST 0x0004 #define IPI_STOP 0x0008 +#define IPI_STOP_HARD 0x0008 #ifndef LOCORE diff --git a/sys/mips/mips/mp_machdep.c b/sys/mips/mips/mp_machdep.c index d688a52b24e..bf323922d72 100644 --- a/sys/mips/mips/mp_machdep.c +++ b/sys/mips/mips/mp_machdep.c @@ -129,7 +129,12 @@ smp_handle_ipi(struct trapframe *frame) break; case IPI_STOP: - CTR0(KTR_SMP, "IPI_STOP"); + + /* + * IPI_STOP_HARD is mapped to IPI_STOP so it is not + * necessary to add it in the switch. + */ + CTR0(KTR_SMP, "IPI_STOP or IPI_STOP_HARD"); atomic_set_int(&stopped_cpus, cpumask); while ((started_cpus & cpumask) == 0) diff --git a/sys/pc98/conf/NOTES b/sys/pc98/conf/NOTES index 02f8d07ecf2..9ab70b9e5d1 100644 --- a/sys/pc98/conf/NOTES +++ b/sys/pc98/conf/NOTES @@ -29,10 +29,6 @@ device apic # I/O apic # options MP_WATCHDOG -# Debugging options. -# -options STOP_NMI # Stop CPUS using NMI instead of IPI - ##################################################################### diff --git a/sys/powerpc/include/smp.h b/sys/powerpc/include/smp.h index 3929b8c7e7e..0e5ec16eb90 100644 --- a/sys/powerpc/include/smp.h +++ b/sys/powerpc/include/smp.h @@ -35,6 +35,7 @@ #define IPI_PREEMPT 1 #define IPI_RENDEZVOUS 2 #define IPI_STOP 3 +#define IPI_STOP_HARD 3 #ifndef LOCORE diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index 2c6d11bef5c..1ae7d6d6f7f 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -281,7 +281,13 @@ powerpc_ipi_handler(void *arg) smp_rendezvous_action(); break; case IPI_STOP: - CTR1(KTR_SMP, "%s: IPI_STOP (stop)", __func__); + + /* + * IPI_STOP_HARD is mapped to IPI_STOP so it is not + * necessary to add such case in the switch. + */ + CTR1(KTR_SMP, "%s: IPI_STOP or IPI_STOP_HARD (stop)", + __func__); self = PCPU_GET(cpumask); savectx(PCPU_GET(curpcb)); atomic_set_int(&stopped_cpus, self); diff --git a/sys/sparc64/include/smp.h b/sys/sparc64/include/smp.h index 8eb5636c939..87355430ca3 100644 --- a/sys/sparc64/include/smp.h +++ b/sys/sparc64/include/smp.h @@ -56,6 +56,7 @@ #define IPI_RENDEZVOUS PIL_RENDEZVOUS #define IPI_PREEMPT PIL_PREEMPT #define IPI_STOP PIL_STOP +#define IPI_STOP_HARD PIL_STOP #define IPI_RETRIES 5000 diff --git a/sys/sun4v/include/smp.h b/sys/sun4v/include/smp.h index 4f5adc53c36..63a8e01bef0 100644 --- a/sys/sun4v/include/smp.h +++ b/sys/sun4v/include/smp.h @@ -44,6 +44,7 @@ #define IPI_AST PIL_AST #define IPI_RENDEZVOUS PIL_RENDEZVOUS #define IPI_STOP PIL_STOP +#define IPI_STOP_HARD PIL_STOP #define IPI_PREEMPT PIL_PREEMPT diff --git a/sys/sys/smp.h b/sys/sys/smp.h index 05c86424720..d80b9e46ef9 100644 --- a/sys/sys/smp.h +++ b/sys/sys/smp.h @@ -123,6 +123,7 @@ void forward_signal(struct thread *); void forward_roundrobin(void); int restart_cpus(cpumask_t); int stop_cpus(cpumask_t); +int stop_cpus_hard(cpumask_t); #if defined(__amd64__) int suspend_cpus(cpumask_t); #endif From f394882d890493c5c1930c0af53a90103ba82b3b Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Fri, 14 Aug 2009 10:25:14 +0000 Subject: [PATCH 0034/2592] MFC of r196201 URL: http://svn.freebsd.org/changeset/base/196201 Fix ipfw crash on uid or gid check. Receiving any ip packet for which there is no existing socket will crash if ipfw has a uid or gid test rule, as the uid/gid of the non existent owner of said non existent socket is tested. Brooks introduced this error as part of his >16 gids patch. It appears to be a cut-n-paste error from similar code a few lines before. The old code used the 'pcb' variable here, but in the new code that switched the 'inp' variable, which is often NULL and what is tested in the code further up. The rest of the multi-gid patch for ipfw seems solid (and cleaner than previous code). p.s. What's up with all the properties changing? It is a fresh checkout. Reviewed by: brooks Approved by: re (rwatson) --- sys/netinet/ipfw/ip_fw2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c index da6593c46ce..31065daa308 100644 --- a/sys/netinet/ipfw/ip_fw2.c +++ b/sys/netinet/ipfw/ip_fw2.c @@ -2057,7 +2057,7 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif, dst_ip, htons(dst_port), wildcard, NULL); if (pcb != NULL) { - *uc = crhold(inp->inp_cred); + *uc = crhold(pcb->inp_cred); *ugid_lookupp = 1; } INP_INFO_RUNLOCK(pi); From 106c3802ff86b21ceb05e97996db4c073e9cc622 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 14 Aug 2009 11:06:58 +0000 Subject: [PATCH 0035/2592] MFC r196203: Correctly handle unlock for !MAKEENTRY case. Approved by: re (rwatson) --- sys/kern/vfs_cache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index f21f4afc881..78548033ea2 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -416,7 +416,8 @@ retry_wlocked: if (dvp->v_cache_dd->nc_flag & NCF_ISDOTDOT) cache_zap(dvp->v_cache_dd); dvp->v_cache_dd = NULL; - goto unlock; + CACHE_WUNLOCK(); + return (0); } if (dvp->v_cache_dd->nc_flag & NCF_ISDOTDOT) *vpp = dvp->v_cache_dd->nc_vp; From b60a1fa9a5ec45c1ac9524b1812385e692d0654d Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 14 Aug 2009 11:13:06 +0000 Subject: [PATCH 0036/2592] MFC r196204: Add the address of the lock to the KTR_LOCK trace. Approved by: re (rwatson) --- sys/sys/lock.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/sys/lock.h b/sys/sys/lock.h index 9e47ab4b41d..01c70ffc66c 100644 --- a/sys/sys/lock.h +++ b/sys/sys/lock.h @@ -155,16 +155,16 @@ struct lock_class { #define LOCK_LOG_LOCK(opname, lo, flags, recurse, file, line) do { \ if (LOCK_LOG_TEST((lo), (flags))) \ - CTR5(KTR_LOCK, opname " (%s) %s r = %d at %s:%d", \ + CTR6(KTR_LOCK, opname " (%s) %s %p r = %d at %s:%d", \ LOCK_CLASS(lo)->lc_name, (lo)->lo_name, \ - (u_int)(recurse), (file), (line)); \ + (lo), (u_int)(recurse), (file), (line)); \ } while (0) #define LOCK_LOG_TRY(opname, lo, flags, result, file, line) do { \ if (LOCK_LOG_TEST((lo), (flags))) \ - CTR5(KTR_LOCK, "TRY_" opname " (%s) %s result=%d at %s:%d",\ + CTR6(KTR_LOCK, "TRY_" opname " (%s) %s %p result=%d at %s:%d",\ LOCK_CLASS(lo)->lc_name, (lo)->lo_name, \ - (u_int)(result), (file), (line)); \ + (lo), (u_int)(result), (file), (line)); \ } while (0) #define LOCK_LOG_INIT(lo, flags) do { \ From b5d2abe26f29727366dce24b703c5ab678af75f8 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 14 Aug 2009 11:17:34 +0000 Subject: [PATCH 0037/2592] MFC r196205: In nfs_upgrade_vnlock(), assert that the vnode is locked. When downgrading, pass LK_RETRY to the vn_lock(), since otherwise vn_lock() unlocks the doomed vnode, causing extra unlock. Approved by: re (rwatson) --- sys/nfsclient/nfs_subs.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index 6f4ef7b5d40..329294bae30 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -409,28 +409,25 @@ int nfs_upgrade_vnlock(struct vnode *vp) { int old_lock; - - if ((old_lock = VOP_ISLOCKED(vp)) != LK_EXCLUSIVE) { - if (old_lock == LK_SHARED) { - /* Upgrade to exclusive lock, this might block */ - vn_lock(vp, LK_UPGRADE | LK_RETRY); - } else { - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - } + + ASSERT_VOP_LOCKED(vp, "nfs_upgrade_vnlock"); + old_lock = VOP_ISLOCKED(vp); + if (old_lock != LK_EXCLUSIVE) { + KASSERT(old_lock == LK_SHARED, + ("nfs_upgrade_vnlock: wrong old_lock %d", old_lock)); + /* Upgrade to exclusive lock, this might block */ + vn_lock(vp, LK_UPGRADE | LK_RETRY); } - return old_lock; + return (old_lock); } void nfs_downgrade_vnlock(struct vnode *vp, int old_lock) { if (old_lock != LK_EXCLUSIVE) { - if (old_lock == LK_SHARED) { - /* Downgrade from exclusive lock, this might block */ - vn_lock(vp, LK_DOWNGRADE); - } else { - VOP_UNLOCK(vp, 0); - } + KASSERT(old_lock == LK_SHARED, ("wrong old_lock %d", old_lock)); + /* Downgrade from exclusive lock. */ + vn_lock(vp, LK_DOWNGRADE | LK_RETRY); } } From 8c5a788279f76f17a290fffa9a8ea7ce3284b41b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 14 Aug 2009 11:22:09 +0000 Subject: [PATCH 0038/2592] MFC r196206: Take the number of allocated freeblks into consideration for softdep_slowdown(), to prevent kernel memory exhaustioni on mass-truncation. Approved by: re (rwatson) --- sys/ufs/ffs/ffs_softdep.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 72522b2594e..5f162806d1e 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -663,6 +663,8 @@ static int req_clear_inodedeps; /* syncer process flush some inodedeps */ static int req_clear_remove; /* syncer process flush some freeblks */ #define FLUSH_REMOVE 2 #define FLUSH_REMOVE_WAIT 3 +static long num_freeblkdep; /* number of freeblks workitems allocated */ + /* * runtime statistics */ @@ -2223,6 +2225,9 @@ softdep_setup_freeblocks(ip, length, flags) freeblks->fb_uid = ip->i_uid; freeblks->fb_previousinum = ip->i_number; freeblks->fb_devvp = ip->i_devvp; + ACQUIRE_LOCK(&lk); + num_freeblkdep++; + FREE_LOCK(&lk); extblocks = 0; if (fs->fs_magic == FS_UFS2_MAGIC) extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize)); @@ -2815,6 +2820,7 @@ handle_workitem_freeblocks(freeblks, flags) ACQUIRE_LOCK(&lk); WORKITEM_FREE(freeblks, D_FREEBLKS); + num_freeblkdep--; FREE_LOCK(&lk); } @@ -5768,7 +5774,8 @@ softdep_slowdown(vp) max_softdeps_hard = max_softdeps * 11 / 10; if (num_dirrem < max_softdeps_hard / 2 && num_inodedep < max_softdeps_hard && - VFSTOUFS(vp->v_mount)->um_numindirdeps < maxindirdeps) { + VFSTOUFS(vp->v_mount)->um_numindirdeps < maxindirdeps && + num_freeblkdep < max_softdeps_hard) { FREE_LOCK(&lk); return (0); } From a429f76be75c4cb0214220818cd65fcf8a4364fb Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Fri, 14 Aug 2009 13:26:50 +0000 Subject: [PATCH 0039/2592] Merge r196213 to stable/8. Approved by: re (rwatson) --- usr.sbin/sysinstall/devices.c | 1 + 1 file changed, 1 insertion(+) diff --git a/usr.sbin/sysinstall/devices.c b/usr.sbin/sysinstall/devices.c index 3ba87325006..b95fdc595a5 100644 --- a/usr.sbin/sysinstall/devices.c +++ b/usr.sbin/sysinstall/devices.c @@ -80,6 +80,7 @@ static struct _devname { CDROM("acd%d", "ATAPI/IDE CDROM", 4), DISK("da%d", "SCSI disk device", 16), DISK("ad%d", "ATA/IDE disk device", 16), + DISK("ada%d", "SATA disk device", 16), DISK("ar%d", "ATA/IDE RAID device", 16), DISK("afd%d", "ATAPI/IDE floppy device", 4), DISK("mlxd%d", "Mylex RAID disk", 4), From c5047621f01b19b6dc0381bb5751313f3f95bba3 Mon Sep 17 00:00:00 2001 From: Remko Lodder Date: Fri, 14 Aug 2009 19:30:59 +0000 Subject: [PATCH 0040/2592] Remove bogus char cast. PR: 118014 Submitted by: Gardner Bell Approved by: re (rwatson), imp (mentor, implicit) MFC after: immediate Approved by: re (rwatson), imp (mentor, implicit) --- usr.sbin/arp/arp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c index e585ba0fecd..8a3410fd8f8 100644 --- a/usr.sbin/arp/arp.c +++ b/usr.sbin/arp/arp.c @@ -120,7 +120,7 @@ main(int argc, char *argv[]) int aflag = 0; /* do it for all entries */ while ((ch = getopt(argc, argv, "andfsSi:")) != -1) - switch((char)ch) { + switch(ch) { case 'a': aflag = 1; break; From 0230cd8e863d0aae1ff0e911be4943f010370983 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 14 Aug 2009 20:42:40 +0000 Subject: [PATCH 0042/2592] MFC 196221: Add the ability to build a release from an SVN checkout instead of a CVS checkout. If SVNROOT is specified, then the source tree will be checked out from that SVN repository instead of using CVS. ports and docs still use CVS. If SVNROOT is not specified, then the source tree will be checked out using CVS. An explicit SVN branch can be specified using SVNBRANCH (e.g. SVNBRANCH=stable/8). If SVNBRANCH is not set but RELEASETAG is set to a CVS branch (such as RELENG_8) the appropriate SVN branch will be inferred from the CVS branch using svnbranch.awk. Note that there are still several open questions about using SVN instead of CVS in the release process. However, this does enable one to build a release from an SVN repository if needed. Approved by: re (kensmith) --- release/Makefile | 55 +++++++++++++++++++++++++++++++++++++++---- release/svnbranch.awk | 28 ++++++++++++++++++++++ 2 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 release/svnbranch.awk diff --git a/release/Makefile b/release/Makefile index bb21dbe37b5..9a0bed4d31f 100644 --- a/release/Makefile +++ b/release/Makefile @@ -1,7 +1,8 @@ # $FreeBSD$ # # make release [BUILDNAME=somename] CHROOTDIR=/some/dir CVSROOT=/cvs/dir \ -# [RELEASETAG=tag] +# [RELEASETAG=tag] [SVNROOT=svn://svn.freebsd.org/base] \ +# [SVNBRANCH=some/branch] # # Where "/some/dir" is the pathname of a directory on a some filesystem with # at least 1000MB of free space, "somename" is what you want the release to @@ -9,6 +10,11 @@ # which CVS "tag" name should be used when checking out the sources to build # the release (default is HEAD). # +# Please note the support for building from SVN is preliminary and there +# are still questions about things like how to handle updates of +# /usr/src on production systems (csup(1) replacement). It is a work +# in progress and may change as the other issues get worked out. +# # Please note: the md(4) driver must be present in the kernel # (either by being compiled in or available as a kld(4) module), # otherwise the target 'release.8' and possibly others will fail. @@ -49,12 +55,25 @@ BUILDNAME?=${BASE}-${DATE}-SNAP # To add other options to the CVS command, set #CVSARGS="-lfq" # -# To prefix the cvs command +# To prefix the CVS command #CVSPREFIX="/usr/bin/time" # # Where the CVS repository is #CVSROOT="/home/ncvs" # +# To add other options to the Subversion subcommands (co,up), set +#SVNCMDARGS="-r '{ 01/01/2002 00:00:00 UTC }'" +# +# To prefix the Subversion command +#SVNPREFIX="/usr/bin/time" +# +# Where the Subversion repository is +#SVNROOT=svn://svn.freebsd.org/base +# +# Subversion branch to build for src. If this is not set then it is +# automatically computed from RELEASETAG. +#SVNBRANCH=stable/7 +# # Non-zero if ${RELEASETAG} is in the form "RELENG_ver_RELEASE"; we # are building an official release. Otherwise, we are building for # a branch. @@ -68,6 +87,16 @@ PORTSRELEASETAG?= ${AUXRELEASETAG} .endif .endif +# Determine the Subversion source branch that corresponds to the requested +# RELEASETAG. +.if !defined(SVNBRANCH) +.if defined(RELEASETAG) +SVNBRANCH!= echo "${RELEASETAG}" | awk -f ${.CURDIR}/svnbranch.awk +.else +SVNBRANCH= head +.endif +.endif + # If you want to pass flags to the world build such as -j X, use # WORLD_FLAGS. Similarly, you can specify make flags for kernel # builds via KERNEL_FLAGS. @@ -341,8 +370,17 @@ CVS_PORTSARGS+= -r ${PORTSRELEASETAG} WORLDDIR?= ${.CURDIR}/.. release rerelease: -.if !defined(CHROOTDIR) || !defined(BUILDNAME) || !defined(CVSROOT) - @echo "To make a release you must set CHROOTDIR, BUILDNAME and CVSROOT" && false +.if !defined(CHROOTDIR) || !defined(BUILDNAME) + @echo "To make a release you must set CHROOTDIR and BUILDNAME" && false +.endif +.if !defined(NOPORTSATALL) && !defined(EXTPORTSDIR) && !defined(CVSROOT) + @echo "Building ports requires CVSROOT or EXTPORTSDIR" && false +.endif +.if !defined(NODOC) && !defined(EXTDOCDIR) && !defined(CVSROOT) + @echo "Building docs requires CVSROOT or EXTDOCDIR" && false +.endif +.if !defined(EXTSRCDIR) && !defined(CVSROOT) && !defined(SVNROOT) + @echo "The source tree requires SVNROOT, CVSROOT, or EXTSRCDIR" && false .endif .if defined(NOPORTSATALL) && !defined(NODOC) @echo "Ports are required for building the release docs. Either set NODOC or" @@ -387,6 +425,10 @@ release rerelease: .if defined(EXTSRCDIR) cd ${CHROOTDIR}/usr && \ cp -R -H ${EXTSRCDIR} src +.elif defined(SVNROOT) + cd ${CHROOTDIR}/usr && \ + ${SVNPREFIX} svn co ${SVNCMDARGS} ${SVNROOT}/${SVNBRANCH} \ + ${RELEASESRCMODULE} .else cd ${CHROOTDIR}/usr && \ ${CVSPREFIX} cvs -R ${CVSARGS} -d ${CVSROOT} \ @@ -432,7 +474,10 @@ release rerelease: .endif .if make(rerelease) .if !defined(RELEASENOUPDATE) && !defined(EXTSRCDIR) -.if !defined(RELEASETAG) +.if defined(SVNROOT) + cd ${CHROOTDIR}/usr/src && ${SVNPREFIX} svn switch ${SVNCMDARGS} \ + ${SVNROOT}/${SVNBRANCH} +.elif !defined(RELEASETAG) cd ${CHROOTDIR}/usr/src && ${CVSPREFIX} cvs -R ${CVSARGS} -q \ update ${CVSCMDARGS} -P -d -A .else diff --git a/release/svnbranch.awk b/release/svnbranch.awk new file mode 100644 index 00000000000..0fc86200c04 --- /dev/null +++ b/release/svnbranch.awk @@ -0,0 +1,28 @@ +# $FreeBSD$ + +BEGIN { + FS = "_" +} + +/RELENG_.*_RELEASE/ { + if (NF == 5) { + printf "release/%s.%s.%s", $2, $3, $4 + exit + } +} + +/RELENG_.*/ { + if (NF == 3) { + printf "releng/%s.%s", $2, $3 + exit + } + + if (NF == 2) { + printf "stable/%s", $2 + exit + } +} + +// { + printf "unknown_branch" +} From 7612087747070b14ecefdc778bc4f10089a0adc7 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 14 Aug 2009 20:57:21 +0000 Subject: [PATCH 0043/2592] Adjust the handling of the local APIC PMC interrupt vector: - Provide lapic_disable_pmc(), lapic_enable_pmc(), and lapic_reenable_pmc() routines in the local APIC code that the hwpmc(4) driver can use to manage the local APIC PMC interrupt vector. - Do not enable the local APIC PMC interrupt vector by default when HWPMC_HOOKS is enabled. Instead, the hwpmc(4) driver explicitly enables the interrupt when it is succesfully initialized and disables the interrupt when it is unloaded. This avoids enabling the interrupt on unsupported CPUs which may result in spurious NMIs. Reported by: rnoland Reviewed by: jkoshy Approved by: re (kib) MFC after: 2 weeks --- sys/amd64/amd64/local_apic.c | 86 ++++++++++++++++++++++++++++++++++-- sys/amd64/include/apicvar.h | 3 ++ sys/amd64/include/pmc_mdep.h | 1 - sys/dev/hwpmc/hwpmc_core.c | 7 ++- sys/dev/hwpmc/hwpmc_piv.c | 5 ++- sys/dev/hwpmc/hwpmc_ppro.c | 5 ++- sys/dev/hwpmc/hwpmc_x86.c | 22 +++------ sys/i386/i386/local_apic.c | 86 ++++++++++++++++++++++++++++++++++-- sys/i386/include/apicvar.h | 3 ++ sys/i386/include/pmc_mdep.h | 1 - 10 files changed, 191 insertions(+), 28 deletions(-) diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c index cd3073caf99..13bd7743cb9 100644 --- a/sys/amd64/amd64/local_apic.c +++ b/sys/amd64/amd64/local_apic.c @@ -123,7 +123,7 @@ static struct lvt lvts[LVT_MAX + 1] = { { 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* LINT1: NMI */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_TIMER_INT }, /* Timer */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */ - { 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* PMC */ + { 1, 1, 1, 1, APIC_LVT_DM_NMI, 0 }, /* PMC */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_THERMAL_INT }, /* Thermal */ }; @@ -305,11 +305,9 @@ lapic_setup(int boot) lapic->lvt_lint0 = lvt_mode(la, LVT_LINT0, lapic->lvt_lint0); lapic->lvt_lint1 = lvt_mode(la, LVT_LINT1, lapic->lvt_lint1); -#ifdef HWPMC_HOOKS /* Program the PMC LVT entry if present. */ if (maxlvt >= LVT_PMC) lapic->lvt_pcint = lvt_mode(la, LVT_PMC, lapic->lvt_pcint); -#endif /* Program timer LVT and setup handler. */ lapic->lvt_timer = lvt_mode(la, LVT_TIMER, lapic->lvt_timer); @@ -332,6 +330,88 @@ lapic_setup(int boot) intr_restore(eflags); } +void +lapic_reenable_pmc(void) +{ +#ifdef HWPMC_HOOKS + uint32_t value; + + value = lapic->lvt_pcint; + value &= ~APIC_LVT_M; + lapic->lvt_pcint = value; +#endif +} + +#ifdef HWPMC_HOOKS +static void +lapic_update_pmc(void *dummy) +{ + struct lapic *la; + + la = &lapics[lapic_id()]; + lapic->lvt_pcint = lvt_mode(la, LVT_PMC, lapic->lvt_pcint); +} +#endif + +int +lapic_enable_pmc(void) +{ +#ifdef HWPMC_HOOKS + u_int32_t maxlvt; + + /* Fail if the local APIC is not present. */ + if (lapic == NULL) + return (0); + + /* Fail if the PMC LVT is not present. */ + maxlvt = (lapic->version & APIC_VER_MAXLVT) >> MAXLVTSHIFT; + if (maxlvt < LVT_PMC) + return (0); + + lvts[LVT_PMC].lvt_masked = 0; + +#ifdef SMP + /* + * If hwpmc was loaded at boot time then the APs may not be + * started yet. In that case, don't forward the request to + * them as they will program the lvt when they start. + */ + if (smp_started) + smp_rendezvous(NULL, lapic_update_pmc, NULL, NULL); + else +#endif + lapic_update_pmc(NULL); + return (1); +#else + return (0); +#endif +} + +void +lapic_disable_pmc(void) +{ +#ifdef HWPMC_HOOKS + u_int32_t maxlvt; + + /* Fail if the local APIC is not present. */ + if (lapic == NULL) + return; + + /* Fail if the PMC LVT is not present. */ + maxlvt = (lapic->version & APIC_VER_MAXLVT) >> MAXLVTSHIFT; + if (maxlvt < LVT_PMC) + return; + + lvts[LVT_PMC].lvt_masked = 1; + +#ifdef SMP + /* The APs should always be started when hwpmc is unloaded. */ + KASSERT(mp_ncpus == 1 || smp_started, ("hwpmc unloaded too early")); +#endif + smp_rendezvous(NULL, lapic_update_pmc, NULL, NULL); +#endif +} + /* * Called by cpu_initclocks() on the BSP to setup the local APIC timer so * that it can drive hardclock, statclock, and profclock. This function diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h index 73fff6c006f..9d6d538de1d 100644 --- a/sys/amd64/include/apicvar.h +++ b/sys/amd64/include/apicvar.h @@ -201,7 +201,9 @@ int ioapic_set_triggermode(void *cookie, u_int pin, int ioapic_set_smi(void *cookie, u_int pin); void lapic_create(u_int apic_id, int boot_cpu); void lapic_disable(void); +void lapic_disable_pmc(void); void lapic_dump(const char *str); +int lapic_enable_pmc(void); void lapic_eoi(void); u_int lapic_error(void); int lapic_id(void); @@ -212,6 +214,7 @@ void lapic_ipi_vectored(u_int vector, int dest); int lapic_ipi_wait(int delay); void lapic_handle_intr(int vector, struct trapframe *frame); void lapic_handle_timer(struct trapframe *frame); +void lapic_reenable_pmc(void); void lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id); int lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked); int lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode); diff --git a/sys/amd64/include/pmc_mdep.h b/sys/amd64/include/pmc_mdep.h index f8c26f2ec90..f233a510d3c 100644 --- a/sys/amd64/include/pmc_mdep.h +++ b/sys/amd64/include/pmc_mdep.h @@ -115,7 +115,6 @@ union pmc_md_pmc { */ void start_exceptions(void), end_exceptions(void); -void pmc_x86_lapic_enable_pmc_interrupt(void); struct pmc_mdep *pmc_amd_initialize(void); void pmc_amd_finalize(struct pmc_mdep *_md); diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index 214e42cb4b0..f84e0f1548c 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -32,10 +32,13 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include +#include +#include #include #include #include @@ -1771,7 +1774,7 @@ core_intr(int cpu, struct trapframe *tf) } if (found_interrupt) - pmc_x86_lapic_enable_pmc_interrupt(); + lapic_reenable_pmc(); atomic_add_int(found_interrupt ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); @@ -1895,7 +1898,7 @@ core2_intr(int cpu, struct trapframe *tf) (uintmax_t) rdmsr(IA_GLOBAL_OVF_CTRL)); if (found_interrupt) - pmc_x86_lapic_enable_pmc_interrupt(); + lapic_reenable_pmc(); atomic_add_int(found_interrupt ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); diff --git a/sys/dev/hwpmc/hwpmc_piv.c b/sys/dev/hwpmc/hwpmc_piv.c index 565be88cfee..8ee851828b1 100644 --- a/sys/dev/hwpmc/hwpmc_piv.c +++ b/sys/dev/hwpmc/hwpmc_piv.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -39,6 +40,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include #include @@ -1537,7 +1540,7 @@ p4_intr(int cpu, struct trapframe *tf) */ if (did_interrupt) - pmc_x86_lapic_enable_pmc_interrupt(); + lapic_reenable_pmc(); atomic_add_int(did_interrupt ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); diff --git a/sys/dev/hwpmc/hwpmc_ppro.c b/sys/dev/hwpmc/hwpmc_ppro.c index 909bfe24897..8da185bf6ab 100644 --- a/sys/dev/hwpmc/hwpmc_ppro.c +++ b/sys/dev/hwpmc/hwpmc_ppro.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -39,6 +40,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include #include @@ -718,7 +721,7 @@ p6_intr(int cpu, struct trapframe *tf) * unmasked after a PMC interrupt. */ if (retval) - pmc_x86_lapic_enable_pmc_interrupt(); + lapic_reenable_pmc(); atomic_add_int(retval ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); diff --git a/sys/dev/hwpmc/hwpmc_x86.c b/sys/dev/hwpmc/hwpmc_x86.c index b48a6b06424..09d04bb713e 100644 --- a/sys/dev/hwpmc/hwpmc_x86.c +++ b/sys/dev/hwpmc/hwpmc_x86.c @@ -39,7 +39,8 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include +#include #include #include @@ -47,18 +48,6 @@ __FBSDID("$FreeBSD$"); #include #include -extern volatile lapic_t *lapic; - -void -pmc_x86_lapic_enable_pmc_interrupt(void) -{ - uint32_t value; - - value = lapic->lvt_pcint; - value &= ~APIC_LVT_M; - lapic->lvt_pcint = value; -} - /* * Attempt to walk a user call stack using a too-simple algorithm. * In the general case we need unwind information associated with @@ -252,16 +241,15 @@ pmc_md_initialize() struct pmc_mdep *md; /* determine the CPU kind */ - md = NULL; if (cpu_vendor_id == CPU_VENDOR_AMD) md = pmc_amd_initialize(); else if (cpu_vendor_id == CPU_VENDOR_INTEL) md = pmc_intel_initialize(); else - KASSERT(0, ("[x86,%d] Unknown vendor", __LINE__)); + return (NULL); /* disallow sampling if we do not have an LAPIC */ - if (md != NULL && lapic == NULL) + if (!lapic_enable_pmc()) for (i = 1; i < md->pmd_nclass; i++) md->pmd_classdep[i].pcd_caps &= ~PMC_CAP_INTERRUPT; @@ -271,6 +259,8 @@ pmc_md_initialize() void pmc_md_finalize(struct pmc_mdep *md) { + + lapic_disable_pmc(); if (cpu_vendor_id == CPU_VENDOR_AMD) pmc_amd_finalize(md); else if (cpu_vendor_id == CPU_VENDOR_INTEL) diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c index 2cc6a450482..5e79aa805c5 100644 --- a/sys/i386/i386/local_apic.c +++ b/sys/i386/i386/local_apic.c @@ -123,7 +123,7 @@ static struct lvt lvts[LVT_MAX + 1] = { { 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* LINT1: NMI */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_TIMER_INT }, /* Timer */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */ - { 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* PMC */ + { 1, 1, 1, 1, APIC_LVT_DM_NMI, 0 }, /* PMC */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_THERMAL_INT }, /* Thermal */ }; @@ -307,11 +307,9 @@ lapic_setup(int boot) lapic->lvt_lint0 = lvt_mode(la, LVT_LINT0, lapic->lvt_lint0); lapic->lvt_lint1 = lvt_mode(la, LVT_LINT1, lapic->lvt_lint1); -#ifdef HWPMC_HOOKS /* Program the PMC LVT entry if present. */ if (maxlvt >= LVT_PMC) lapic->lvt_pcint = lvt_mode(la, LVT_PMC, lapic->lvt_pcint); -#endif /* Program timer LVT and setup handler. */ lapic->lvt_timer = lvt_mode(la, LVT_TIMER, lapic->lvt_timer); @@ -334,6 +332,88 @@ lapic_setup(int boot) intr_restore(eflags); } +void +lapic_reenable_pmc(void) +{ +#ifdef HWPMC_HOOKS + uint32_t value; + + value = lapic->lvt_pcint; + value &= ~APIC_LVT_M; + lapic->lvt_pcint = value; +#endif +} + +#ifdef HWPMC_HOOKS +static void +lapic_update_pmc(void *dummy) +{ + struct lapic *la; + + la = &lapics[lapic_id()]; + lapic->lvt_pcint = lvt_mode(la, LVT_PMC, lapic->lvt_pcint); +} +#endif + +int +lapic_enable_pmc(void) +{ +#ifdef HWPMC_HOOKS + u_int32_t maxlvt; + + /* Fail if the local APIC is not present. */ + if (lapic == NULL) + return (0); + + /* Fail if the PMC LVT is not present. */ + maxlvt = (lapic->version & APIC_VER_MAXLVT) >> MAXLVTSHIFT; + if (maxlvt < LVT_PMC) + return (0); + + lvts[LVT_PMC].lvt_masked = 0; + +#ifdef SMP + /* + * If hwpmc was loaded at boot time then the APs may not be + * started yet. In that case, don't forward the request to + * them as they will program the lvt when they start. + */ + if (smp_started) + smp_rendezvous(NULL, lapic_update_pmc, NULL, NULL); + else +#endif + lapic_update_pmc(NULL); + return (1); +#else + return (0); +#endif +} + +void +lapic_disable_pmc(void) +{ +#ifdef HWPMC_HOOKS + u_int32_t maxlvt; + + /* Fail if the local APIC is not present. */ + if (lapic == NULL) + return; + + /* Fail if the PMC LVT is not present. */ + maxlvt = (lapic->version & APIC_VER_MAXLVT) >> MAXLVTSHIFT; + if (maxlvt < LVT_PMC) + return; + + lvts[LVT_PMC].lvt_masked = 1; + +#ifdef SMP + /* The APs should always be started when hwpmc is unloaded. */ + KASSERT(mp_ncpus == 1 || smp_started, ("hwpmc unloaded too early")); +#endif + smp_rendezvous(NULL, lapic_update_pmc, NULL, NULL); +#endif +} + /* * Called by cpu_initclocks() on the BSP to setup the local APIC timer so * that it can drive hardclock, statclock, and profclock. This function diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h index a13766f95f9..b15452b1d81 100644 --- a/sys/i386/include/apicvar.h +++ b/sys/i386/include/apicvar.h @@ -230,7 +230,9 @@ int ioapic_set_triggermode(void *cookie, u_int pin, int ioapic_set_smi(void *cookie, u_int pin); void lapic_create(u_int apic_id, int boot_cpu); void lapic_disable(void); +void lapic_disable_pmc(void); void lapic_dump(const char *str); +int lapic_enable_pmc(void); void lapic_eoi(void); u_int lapic_error(void); int lapic_id(void); @@ -241,6 +243,7 @@ void lapic_ipi_vectored(u_int vector, int dest); int lapic_ipi_wait(int delay); void lapic_handle_intr(int vector, struct trapframe *frame); void lapic_handle_timer(struct trapframe *frame); +void lapic_reenable_pmc(void); void lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id); int lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked); int lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode); diff --git a/sys/i386/include/pmc_mdep.h b/sys/i386/include/pmc_mdep.h index 63d5f8bf0b6..4389a20c203 100644 --- a/sys/i386/include/pmc_mdep.h +++ b/sys/i386/include/pmc_mdep.h @@ -150,7 +150,6 @@ struct pmc_mdep; */ void start_exceptions(void), end_exceptions(void); -void pmc_x86_lapic_enable_pmc_interrupt(void); struct pmc_mdep *pmc_amd_initialize(void); void pmc_amd_finalize(struct pmc_mdep *_md); From 21845eba48b294aedc25132d4b7877cb3008e445 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 14 Aug 2009 21:50:47 +0000 Subject: [PATCH 0044/2592] MFC r196226: Add a new macro to test that a variable could be loaded atomically. Check that the given variable is at most uintptr_t in size and that it is aligned. Note: ASSERT_ATOMIC_LOAD() uses ALIGN() to check for adequate alignment -- however, the function of ALIGN() is to guarantee alignment, and therefore may lead to stronger alignment enforcement than necessary for types that are smaller than sizeof(uintptr_t). Add checks to mtx, rw and sx locks init functions to detect possible breakage. This was used during debugging of the problem fixed with r196118 where a pointer was on an un-aligned address in the dpcpu area. In collaboration with: rwatson Reviewed by: rwatson Approved by: re (kib) --- sys/kern/kern_mutex.c | 2 ++ sys/kern/kern_rwlock.c | 2 ++ sys/kern/kern_sx.c | 2 ++ sys/sys/systm.h | 4 ++++ 4 files changed, 10 insertions(+) diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index fc342c53ef4..f625098f248 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -783,6 +783,8 @@ mtx_init(struct mtx *m, const char *name, const char *type, int opts) MPASS((opts & ~(MTX_SPIN | MTX_QUIET | MTX_RECURSE | MTX_NOWITNESS | MTX_DUPOK | MTX_NOPROFILE)) == 0); + ASSERT_ATOMIC_LOAD(m->mtx_lock, ("%s: mtx_lock not aligned for %s: %p", + __func__, name, &m->mtx_lock)); #ifdef MUTEX_DEBUG /* Diagnostic and error correction */ diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c index c07f595cb5a..e2342506a0e 100644 --- a/sys/kern/kern_rwlock.c +++ b/sys/kern/kern_rwlock.c @@ -174,6 +174,8 @@ rw_init_flags(struct rwlock *rw, const char *name, int opts) MPASS((opts & ~(RW_DUPOK | RW_NOPROFILE | RW_NOWITNESS | RW_QUIET | RW_RECURSE)) == 0); + ASSERT_ATOMIC_LOAD(rw->rw_lock, ("%s: rw_lock not aligned for %s: %p", + __func__, name, &rw->rw_lock)); flags = LO_UPGRADABLE; if (opts & RW_DUPOK) diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index 04c2c984150..15c1c9bdf16 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -205,6 +205,8 @@ sx_init_flags(struct sx *sx, const char *description, int opts) MPASS((opts & ~(SX_QUIET | SX_RECURSE | SX_NOWITNESS | SX_DUPOK | SX_NOPROFILE | SX_NOADAPTIVE)) == 0); + ASSERT_ATOMIC_LOAD(sx->sx_lock, ("%s: sx_lock not aligned for %s: %p", + __func__, description, &sx->sx_lock)); flags = LO_SLEEPABLE | LO_UPGRADABLE; if (opts & SX_DUPOK) diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 1956a8f122f..2e8b9adb458 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -89,6 +89,10 @@ extern int maxusers; /* system tune hint */ #define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] #endif +#define ASSERT_ATOMIC_LOAD(var,msg) \ + KASSERT(sizeof(var) <= sizeof(uintptr_t) && \ + ALIGN(&(var)) == (uintptr_t)&(var), msg) + /* * XXX the hints declarations are even more misplaced than most declarations * in this file, since they are needed in one file (per arch) and only used From 857e56152376a6f6a3128e883d62adae36c6ba8e Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 14 Aug 2009 22:55:54 +0000 Subject: [PATCH 0045/2592] MFC r196228: Make VNET_DEBUG a standalone compile-time option, i.e. decouple it from INVARIANTS. Reviewed by: bz Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- sys/conf/options | 3 ++- sys/net/vnet.h | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/conf/options b/sys/conf/options index 41c80b5434c..ac2d87c0195 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -821,8 +821,9 @@ TDMA_TXRATE_QUARTER_DEFAULT opt_tdma.h TDMA_TXRATE_11NA_DEFAULT opt_tdma.h TDMA_TXRATE_11NG_DEFAULT opt_tdma.h -# Virtualize the network stack +# Network stack virtualization options VIMAGE opt_global.h +VNET_DEBUG opt_global.h # Common Flash Interface (CFI) options CFI_SUPPORT_STRATAFLASH opt_cfi.h diff --git a/sys/net/vnet.h b/sys/net/vnet.h index 91de07a1093..116d7af3288 100644 --- a/sys/net/vnet.h +++ b/sys/net/vnet.h @@ -107,9 +107,6 @@ void vnet_destroy(struct vnet *vnet); * Various macros -- get and set the current network stack, but also * assertions. */ -#ifdef INVARIANTS -#define VNET_DEBUG -#endif #ifdef VNET_DEBUG #define VNET_ASSERT(condition) \ if (!(condition)) { \ From 0e9c71019b61426a21d93f020f19378f0924cd6f Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 14 Aug 2009 23:01:21 +0000 Subject: [PATCH 0046/2592] MFC r196229: SCTP is not yet compatible with options VIMAGE kernels although it compiles with VIMAGE defined, so explicitly disallow building such kernels. Reviewed by: rrs Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- sys/netinet/sctp_os_bsd.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index f3ccb634d7b..d01879081bd 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -78,6 +78,10 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef VIMAGE +#error "SCTP is not yet compatible with VIMAGE." +#endif + #ifdef IPSEC #include #include From d326ff4914f3d24c4d2fa8e8809350cc900ca7dd Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 14 Aug 2009 23:05:10 +0000 Subject: [PATCH 0047/2592] MFC r196230: Appease VNET_DEBUG - in if_vmove we temporarily switch i.e. recurse from one vnet to another which is OK, so no need to flood the console with warnings here. Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- sys/net/if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/if.c b/sys/net/if.c index 3ac7db05c14..5d108981cdd 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -920,7 +920,7 @@ if_vmove_loan(struct thread *td, struct ifnet *ifp, char *ifname, int jid) /* Make sure the named iface does not exists in the dst. prison/vnet. */ /* XXX Lock interfaces to avoid races. */ - CURVNET_SET(pr->pr_vnet); + CURVNET_SET_QUIET(pr->pr_vnet); difp = ifunit(ifname); CURVNET_RESTORE(); if (difp != NULL) { From 6e12c67559f8fac1a13b9082af9bf68d8662da8d Mon Sep 17 00:00:00 2001 From: Qing Li Date: Sat, 15 Aug 2009 00:04:12 +0000 Subject: [PATCH 0048/2592] MFC 196234 In function ip_output(), the cached route is flushed when there is a mismatch between the cached entry and the intended destination. The cached rtentry{} is flushed but the associated llentry{} is not. This causes the wrong destination MAC address being used in the output packets. The fix is to flush the llentry{} when rtentry{} is cleared. Reviewed by: kmacy, rwatson Approved by: re --- sys/netinet/ip_output.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index bf2a5f8bb53..33ba8383043 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -201,9 +202,12 @@ again: if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || dst->sin_family != AF_INET || dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { - if (!nortfree) + if (!nortfree) { RTFREE(ro->ro_rt); + LLE_FREE(ro->ro_lle); + } ro->ro_rt = (struct rtentry *)NULL; + ro->ro_lle = (struct llentry *)NULL; } #ifdef IPFIREWALL_FORWARD if (ro->ro_rt == NULL && fwd_tag == NULL) { From 09c0ee2663bf7e1ea9e81d36dca8bbf28dbf99c2 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 15 Aug 2009 11:52:40 +0000 Subject: [PATCH 0049/2592] MFC c196242: Add mptutil(8) and mfiutil(1) to 'SEE ALSO' sections in mpt(4) and mfi(4). Approved by: re (rwatson) --- share/man/man4/mfi.4 | 3 ++- share/man/man4/mpt.4 | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/share/man/man4/mfi.4 b/share/man/man4/mfi.4 index 2288ecbbe6e..5025336bfe4 100644 --- a/share/man/man4/mfi.4 +++ b/share/man/man4/mfi.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 17, 2008 +.Dd August 15, 2009 .Dt MFI 4 .Os .Sh NAME @@ -102,6 +102,7 @@ management interface An attempt was made to remove a mounted volume. .El .Sh SEE ALSO +.Xr mfiutil 1 , .Xr amr 4 , .Xr pci 4 .Sh HISTORY diff --git a/share/man/man4/mpt.4 b/share/man/man4/mpt.4 index f9659fd2334..9a38f29e27e 100644 --- a/share/man/man4/mpt.4 +++ b/share/man/man4/mpt.4 @@ -35,7 +35,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 6, 2007 +.Dd August 15, 2009 .Dt MPT 4 .Os .Sh NAME @@ -155,6 +155,7 @@ can take on - no separate compilation is required. .Xr sa 4 , .Xr scsi 4 , .Xr targ 4 , +.Xr mptutil 8 , .Xr gmultipath 8 .Rs .%T "LSI Logic Website" From 81fda6adf03fa232d332c80fbe6f74240174f397 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Sat, 15 Aug 2009 15:12:46 +0000 Subject: [PATCH 0050/2592] - Merge r196244: Avoid overflowing the swap size counters in human-readable mode by introducing the new CONVERT_BLOCKS macro which operates on sizes already converted to number of blocks. With this macro it is not longer needed to perform needless multiplica Approved by: re (kib) --- usr.sbin/pstat/pstat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/usr.sbin/pstat/pstat.c b/usr.sbin/pstat/pstat.c index bf297f5ffba..54351667b27 100644 --- a/usr.sbin/pstat/pstat.c +++ b/usr.sbin/pstat/pstat.c @@ -460,6 +460,7 @@ getfiles(struct xfile **abuf, size_t *alen) */ #define CONVERT(v) ((int64_t)(v) * pagesize / blocksize) +#define CONVERT_BLOCKS(v) ((int64_t)(v) * pagesize) static struct kvm_swap swtot; static int nswdev; @@ -492,10 +493,10 @@ print_swap_line(const char *swdevname, intmax_t nblks, intmax_t bused, printf("%-15s %*jd ", swdevname, hlen, CONVERT(nblks)); if (humanflag) { humanize_number(usedbuf, sizeof(usedbuf), - CONVERT(blocksize * bused), "", + CONVERT_BLOCKS(bused), "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); humanize_number(availbuf, sizeof(availbuf), - CONVERT(blocksize * bavail), "", + CONVERT_BLOCKS(bavail), "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); printf("%8s %8s %5.0f%%\n", usedbuf, availbuf, bpercent); } else { From 3a68500f53c9d7ae00413ca5de9e506a5857e9a3 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Sat, 15 Aug 2009 15:18:29 +0000 Subject: [PATCH 0051/2592] - Merge r196246: Proprely intialize UART parameters at probe stage, so uart(4) will initialize the FIFO memory correctly on attach. Before that this values was intialized in only in at91_usart_bus_attach which is called after the uart(4) memory allocation happens. Approved by: re (kib) MFC after: 1 week --- sys/arm/at91/uart_dev_at91usart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/arm/at91/uart_dev_at91usart.c b/sys/arm/at91/uart_dev_at91usart.c index 0f50fb42612..77ab0ca8c10 100644 --- a/sys/arm/at91/uart_dev_at91usart.c +++ b/sys/arm/at91/uart_dev_at91usart.c @@ -307,6 +307,10 @@ static kobj_method_t at91_usart_methods[] = { int at91_usart_bus_probe(struct uart_softc *sc) { + + sc->sc_txfifosz = USART_BUFFER_SIZE; + sc->sc_rxfifosz = USART_BUFFER_SIZE; + sc->sc_hwiflow = 0; return (0); } @@ -344,10 +348,6 @@ at91_usart_bus_attach(struct uart_softc *sc) atsc->flags |= HAS_TIMEOUT; WR4(&sc->sc_bas, USART_IDR, 0xffffffff); - sc->sc_txfifosz = USART_BUFFER_SIZE; - sc->sc_rxfifosz = USART_BUFFER_SIZE; - sc->sc_hwiflow = 0; - #ifndef SKYEYE_WORKAROUNDS /* * Allocate DMA tags and maps From 1ffdef9f28e04bc73ba74e1d39c30361079c13f4 Mon Sep 17 00:00:00 2001 From: Dima Panov Date: Sat, 15 Aug 2009 16:04:36 +0000 Subject: [PATCH 0052/2592] MFC calendar.freebsd Approved by: re (rwatson) miwi (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 d729acf224d..a2803377309 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/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 09/27 Neil Blakey-Milner born in Port Elizabeth, South Africa, 1978 From ae131b74992b182772b3a6a8464089800ff8ad2c Mon Sep 17 00:00:00 2001 From: Giorgos Keramidas Date: Sat, 15 Aug 2009 18:03:34 +0000 Subject: [PATCH 0053/2592] MFC 196254 - iostat: add a bit of space between tty in/out columns The columns for tty input and output may bump against each other if the tty output needs more than 5 columns. Add a bit of space that pushes everything 1 column to the right, but also avoids the problem. Approved by: re (rwatson) --- usr.sbin/iostat/iostat.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/usr.sbin/iostat/iostat.c b/usr.sbin/iostat/iostat.c index 65a0386a92a..9831f842ed3 100644 --- a/usr.sbin/iostat/iostat.c +++ b/usr.sbin/iostat/iostat.c @@ -586,7 +586,7 @@ main(int argc, char **argv) } if (xflag == 0 && Tflag > 0) - printf("%4.0Lf%5.0Lf", cur.tk_nin / etime, + printf("%4.0Lf %5.0Lf", cur.tk_nin / etime, cur.tk_nout / etime); devstats(hflag, etime, havelast); @@ -674,7 +674,7 @@ phdr(void) return; if (Tflag > 0) - (void)printf(" tty"); + (void)printf(" tty"); for (i = 0, printed=0;(i < num_devices) && (printed < maxshowdevs);i++){ int di; if ((dev_select[i].selected != 0) @@ -696,7 +696,7 @@ phdr(void) (void)printf("\n"); if (Tflag > 0) - (void)printf(" tin tout"); + (void)printf(" tin tout"); for (i=0, printed = 0;(i < num_devices) && (printed < maxshowdevs);i++){ if ((dev_select[i].selected != 0) @@ -741,7 +741,7 @@ devstats(int perf_select, long double etime, int havelast) if (xflag > 0) { printf(" extended device statistics "); if (Tflag > 0) - printf(" tty "); + printf(" tty "); if (Cflag > 0) printf(" cpu "); printf("\n"); @@ -754,7 +754,7 @@ devstats(int perf_select, long double etime, int havelast) "device r/i w/i kr/i kw/i wait svc_t %%b " ); if (Tflag > 0) - printf("tin tout "); + printf("tin tout "); if (Cflag > 0) printf("us ni sy in id "); printf("\n"); @@ -895,7 +895,7 @@ devstats(int perf_select, long double etime, int havelast) */ printf("%52s",""); if (Tflag > 0) - printf("%4.0Lf%5.0Lf", cur.tk_nin / etime, + printf("%4.0Lf %5.0Lf", cur.tk_nin / etime, cur.tk_nout / etime); if (Cflag > 0) cpustats(); From 168346d043609961d17c2d155be4377580fc87f3 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Sat, 15 Aug 2009 18:56:56 +0000 Subject: [PATCH 0054/2592] MFC r196256: Fixup the Xen support in order to match newly introduced enhacements for IPIs. Approved by: re (kib) --- sys/i386/xen/mp_machdep.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index bae07d4f608..92533662b26 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -118,6 +118,7 @@ volatile int smp_tlb_wait; typedef void call_data_func_t(uintptr_t , uintptr_t); static u_int logical_cpus; +static volatile cpumask_t ipi_nmi_pending; /* used to hold the AP's until we are ready to release them */ static struct mtx ap_boot_mtx; @@ -1109,6 +1110,14 @@ ipi_selected(cpumask_t cpus, u_int ipi) ipi = IPI_BITMAP_VECTOR; } + /* + * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit + * of help in order to understand what is the source. + * Set the mask of receiving CPUs for this purpose. + */ + if (ipi == IPI_STOP_HARD) + atomic_set_int(&ipi_nmi_pending, cpus); + CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); while ((cpu = ffs(cpus)) != 0) { cpu--; @@ -1140,10 +1149,39 @@ ipi_selected(cpumask_t cpus, u_int ipi) void ipi_all_but_self(u_int ipi) { + + /* + * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit + * of help in order to understand what is the source. + * Set the mask of receiving CPUs for this purpose. + */ + if (ipi == IPI_STOP_HARD) + atomic_set_int(&ipi_nmi_pending, PCPU_GET(other_cpus)); + CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); ipi_selected(PCPU_GET(other_cpus), ipi); } +int +ipi_nmi_handler() +{ + cpumask_t cpumask; + + /* + * As long as there is not a simple way to know about a NMI's + * source, if the bitmask for the current CPU is present in + * the global pending bitword an IPI_STOP_HARD has been issued + * and should be handled. + */ + cpumask = PCPU_GET(cpumask); + if ((ipi_nmi_pending & cpumask) == 0) + return (1); + + atomic_clear_int(&ipi_nmi_pending, cpumask); + cpustop_handler(); + return (0); +} + /* * Handle an IPI_STOP by saving our current context and spinning until we * are resumed. From ca007251f2520fe998e8de1cb47b04618c686e18 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 15 Aug 2009 21:37:16 +0000 Subject: [PATCH 0055/2592] MFC r196260. * Fix a bug where PR-SCTP settings are ignore when using implicit association setup. * Fix a bug where message with illegal stream ids are not deleted. * Fix a crash when reporting back unsent messages from the send_queue. * Fix a bug related to INIT retransmission when the socket is already closed. * Fix a bug where associations were stalled when partial delivery API was enabled. * Fix a bug where the receive buffer size was smaller than the partial_delivery_point. Approved by: re, rrs (mentor) --- sys/netinet/sctp_indata.c | 33 ++++++++----- sys/netinet/sctp_input.c | 35 +++++++++---- sys/netinet/sctp_output.c | 100 ++++++++++++++++++-------------------- sys/netinet/sctp_pcb.c | 7 ++- sys/netinet/sctp_timer.c | 6 +-- sys/netinet/sctputil.c | 90 +++++++++++++++++++++++++++------- sys/netinet/sctputil.h | 4 -- 7 files changed, 176 insertions(+), 99 deletions(-) diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 7abdd710a47..52d53e1b975 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -900,7 +900,7 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc) { struct sctp_tmit_chunk *chk; uint16_t nxt_todel; - uint32_t tsize; + uint32_t tsize, pd_point; doit_again: chk = TAILQ_FIRST(&asoc->reasmqueue); @@ -920,8 +920,13 @@ doit_again: * Yep the first one is here and its ok to deliver * but should we? */ - if ((sctp_is_all_msg_on_reasm(asoc, &tsize) || - (tsize >= stcb->sctp_ep->partial_delivery_point))) { + if (stcb->sctp_socket) { + pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT, + stcb->sctp_ep->partial_delivery_point); + } else { + pd_point = stcb->sctp_ep->partial_delivery_point; + } + if (sctp_is_all_msg_on_reasm(asoc, &tsize) || (tsize >= pd_point)) { /* * Yes, we setup to start reception, by @@ -2824,7 +2829,7 @@ void sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc) { struct sctp_tmit_chunk *chk; - uint32_t tsize; + uint32_t tsize, pd_point; uint16_t nxt_todel; if (asoc->fragmented_delivery_inprogress) { @@ -2860,8 +2865,13 @@ doit_again: * be here or 1/4 the socket buffer max or nothing on the * delivery queue and something can be delivered. */ - if ((sctp_is_all_msg_on_reasm(asoc, &tsize) || - (tsize >= stcb->sctp_ep->partial_delivery_point))) { + if (stcb->sctp_socket) { + pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT, + stcb->sctp_ep->partial_delivery_point); + } else { + pd_point = stcb->sctp_ep->partial_delivery_point; + } + if (sctp_is_all_msg_on_reasm(asoc, &tsize) || (tsize >= pd_point)) { asoc->fragmented_delivery_inprogress = 1; asoc->tsn_last_delivered = chk->rec.data.TSN_seq - 1; asoc->str_of_pdapi = chk->rec.data.stream_number; @@ -5192,7 +5202,7 @@ skip_segments: /* sa_ignore NO_NULL_CHK */ sctp_free_bufspace(stcb, asoc, tp1, 1); sctp_m_freem(tp1->data); - if (PR_SCTP_BUF_ENABLED(tp1->flags)) { + if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(tp1->flags)) { asoc->sent_queue_cnt_removeable--; } } @@ -6289,10 +6299,11 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, ctl->pdapi_aborted = 1; sv = stcb->asoc.control_pdapi; stcb->asoc.control_pdapi = ctl; - sctp_notify_partial_delivery_indication(stcb, + sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION, + stcb, SCTP_PARTIAL_DELIVERY_ABORTED, - SCTP_HOLDS_LOCK, - str_seq); + (void *)&str_seq, + SCTP_SO_NOT_LOCKED); stcb->asoc.control_pdapi = sv; break; } else if ((ctl->sinfo_stream == stseq->stream) && @@ -7786,7 +7797,7 @@ skip_segments: /* sa_ignore NO_NULL_CHK */ sctp_free_bufspace(stcb, asoc, tp1, 1); sctp_m_freem(tp1->data); - if (PR_SCTP_BUF_ENABLED(tp1->flags)) { + if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(tp1->flags)) { asoc->sent_queue_cnt_removeable--; } } diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 989fd452b5d..4a916265b9e 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -278,18 +278,38 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb, unsigned int newcnt; struct sctp_stream_out *outs; struct sctp_stream_queue_pending *sp; + struct sctp_tmit_chunk *chk, *chk_next; - /* cut back on number of streams */ + /* abandon the upper streams */ newcnt = ntohs(init->num_inbound_streams); - /* This if is probably not needed but I am cautious */ + if (!TAILQ_EMPTY(&asoc->send_queue)) { + chk = TAILQ_FIRST(&asoc->send_queue); + while (chk) { + chk_next = TAILQ_NEXT(chk, sctp_next); + if (chk->rec.data.stream_number >= newcnt) { + TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); + asoc->send_queue_cnt--; + if (chk->data != NULL) { + sctp_free_bufspace(stcb, asoc, chk, 1); + sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, + SCTP_NOTIFY_DATAGRAM_UNSENT, chk, SCTP_SO_NOT_LOCKED); + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; + } + } + sctp_free_a_chunk(stcb, chk); + /* sa_ignore FREED_MEMORY */ + } + chk = chk_next; + } + } if (asoc->strmout) { - /* First make sure no data chunks are trapped */ for (i = newcnt; i < asoc->pre_open_streams; i++) { outs = &asoc->strmout[i]; sp = TAILQ_FIRST(&outs->outqueue); while (sp) { - TAILQ_REMOVE(&outs->outqueue, sp, - next); + TAILQ_REMOVE(&outs->outqueue, sp, next); asoc->stream_queue_cnt--; sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, @@ -301,16 +321,13 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb, sctp_free_remote_addr(sp->net); sp->net = NULL; /* Free the chunk */ - SCTP_PRINTF("sp:%p tcb:%p weird free case\n", - sp, stcb); - sctp_free_a_strmoq(stcb, sp); /* sa_ignore FREED_MEMORY */ sp = TAILQ_FIRST(&outs->outqueue); } } } - /* cut back the count and abandon the upper streams */ + /* cut back the count */ asoc->pre_open_streams = newcnt; } SCTP_TCB_SEND_UNLOCK(stcb); diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 21b8f8f89c0..5cde4d0dd69 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -4200,7 +4200,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked /* place in my tag */ init->init.initiate_tag = htonl(stcb->asoc.my_vtag); /* set up some of the credits. */ - init->init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), + init->init.a_rwnd = htonl(max(inp->sctp_socket ? SCTP_SB_LIMIT_RCV(inp->sctp_socket) : 0, SCTP_MINIMAL_RWND)); init->init.num_outbound_streams = htons(stcb->asoc.pre_open_streams); @@ -4411,7 +4411,6 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked net->port, so_locked, NULL); SCTPDBG(SCTP_DEBUG_OUTPUT4, "lowlevel_output - %d\n", ret); SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks); - sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, net); (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time); } @@ -5786,61 +5785,58 @@ sctp_get_frag_point(struct sctp_tcb *stcb, } static void -sctp_set_prsctp_policy(struct sctp_tcb *stcb, - struct sctp_stream_queue_pending *sp) +sctp_set_prsctp_policy(struct sctp_stream_queue_pending *sp) { sp->pr_sctp_on = 0; - if (stcb->asoc.peer_supports_prsctp) { + /* + * We assume that the user wants PR_SCTP_TTL if the user provides a + * positive lifetime but does not specify any PR_SCTP policy. This + * is a BAD assumption and causes problems at least with the + * U-Vancovers MPI folks. I will change this to be no policy means + * NO PR-SCTP. + */ + if (PR_SCTP_ENABLED(sp->sinfo_flags)) { + sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags); + sp->pr_sctp_on = 1; + } else { + return; + } + switch (PR_SCTP_POLICY(sp->sinfo_flags)) { + case CHUNK_FLAGS_PR_SCTP_BUF: /* - * We assume that the user wants PR_SCTP_TTL if the user - * provides a positive lifetime but does not specify any - * PR_SCTP policy. This is a BAD assumption and causes - * problems at least with the U-Vancovers MPI folks. I will - * change this to be no policy means NO PR-SCTP. + * Time to live is a priority stored in tv_sec when doing + * the buffer drop thing. */ - if (PR_SCTP_ENABLED(sp->sinfo_flags)) { - sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags); - sp->pr_sctp_on = 1; - } else { - return; - } - switch (PR_SCTP_POLICY(sp->sinfo_flags)) { - case CHUNK_FLAGS_PR_SCTP_BUF: - /* - * Time to live is a priority stored in tv_sec when - * doing the buffer drop thing. - */ - sp->ts.tv_sec = sp->timetolive; - sp->ts.tv_usec = 0; - break; - case CHUNK_FLAGS_PR_SCTP_TTL: - { - struct timeval tv; + sp->ts.tv_sec = sp->timetolive; + sp->ts.tv_usec = 0; + break; + case CHUNK_FLAGS_PR_SCTP_TTL: + { + struct timeval tv; - (void)SCTP_GETTIME_TIMEVAL(&sp->ts); - tv.tv_sec = sp->timetolive / 1000; - tv.tv_usec = (sp->timetolive * 1000) % 1000000; - /* - * TODO sctp_constants.h needs alternative - * time macros when _KERNEL is undefined. - */ - timevaladd(&sp->ts, &tv); - } - break; - case CHUNK_FLAGS_PR_SCTP_RTX: + (void)SCTP_GETTIME_TIMEVAL(&sp->ts); + tv.tv_sec = sp->timetolive / 1000; + tv.tv_usec = (sp->timetolive * 1000) % 1000000; /* - * Time to live is a the number or retransmissions - * stored in tv_sec. + * TODO sctp_constants.h needs alternative time + * macros when _KERNEL is undefined. */ - sp->ts.tv_sec = sp->timetolive; - sp->ts.tv_usec = 0; - break; - default: - SCTPDBG(SCTP_DEBUG_USRREQ1, - "Unknown PR_SCTP policy %u.\n", - PR_SCTP_POLICY(sp->sinfo_flags)); - break; + timevaladd(&sp->ts, &tv); } + break; + case CHUNK_FLAGS_PR_SCTP_RTX: + /* + * Time to live is a the number or retransmissions stored in + * tv_sec. + */ + sp->ts.tv_sec = sp->timetolive; + sp->ts.tv_usec = 0; + break; + default: + SCTPDBG(SCTP_DEBUG_USRREQ1, + "Unknown PR_SCTP policy %u.\n", + PR_SCTP_POLICY(sp->sinfo_flags)); + break; } } @@ -5911,7 +5907,7 @@ sctp_msg_append(struct sctp_tcb *stcb, sp->tail_mbuf = NULL; sp->length = 0; at = m; - sctp_set_prsctp_policy(stcb, sp); + sctp_set_prsctp_policy(sp); /* * We could in theory (for sendall) sifa the length in, but we would * still have to hunt through the chain since we need to setup the @@ -7138,7 +7134,7 @@ dont_do_it: } /* We only re-set the policy if it is on */ if (sp->pr_sctp_on) { - sctp_set_prsctp_policy(stcb, sp); + sctp_set_prsctp_policy(sp); asoc->pr_sctp_cnt++; chk->pr_sctp_on = 1; } else { @@ -12285,7 +12281,7 @@ skip_copy: sp->addr_over = 0; } atomic_add_int(&sp->net->ref_count, 1); - sctp_set_prsctp_policy(stcb, sp); + sctp_set_prsctp_policy(sp); } out_now: return (sp); diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 3b16293393e..c5a8ddfc1a6 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -4547,8 +4547,11 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre stcb->asoc.control_pdapi = sq; strseq = (sq->sinfo_stream << 16) | sq->sinfo_ssn; - sctp_notify_partial_delivery_indication(stcb, - SCTP_PARTIAL_DELIVERY_ABORTED, 1, strseq); + sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION, + stcb, + SCTP_PARTIAL_DELIVERY_ABORTED, + (void *)&strseq, + SCTP_SO_LOCKED); stcb->asoc.control_pdapi = NULL; } } diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index 477c0b13e45..b40ef503f61 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -588,7 +588,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb) /* sa_ignore NO_NULL_CHK */ sctp_free_bufspace(stcb, asoc, chk, 1); sctp_m_freem(chk->data); - if (PR_SCTP_BUF_ENABLED(chk->flags)) { + if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(chk->flags)) { asoc->sent_queue_cnt_removeable--; } } @@ -757,7 +757,7 @@ start_again: continue; } } - if (PR_SCTP_TTL_ENABLED(chk->flags)) { + if (stcb->asoc.peer_supports_prsctp && PR_SCTP_TTL_ENABLED(chk->flags)) { /* Is it expired? */ if ((now.tv_sec > chk->rec.data.timetodrop.tv_sec) || ((chk->rec.data.timetodrop.tv_sec == now.tv_sec) && @@ -772,7 +772,7 @@ start_again: continue; } } - if (PR_SCTP_RTX_ENABLED(chk->flags)) { + if (stcb->asoc.peer_supports_prsctp && PR_SCTP_RTX_ENABLED(chk->flags)) { /* Has it been retransmitted tv_sec times? */ if (chk->snd_count > chk->rec.data.timetodrop.tv_sec) { if (chk->data) { diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 420f4a1b4af..53d84b794d3 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1484,6 +1484,7 @@ sctp_timeout_handler(void *t) SCTP_INP_INCR_REF(inp); if ((inp->sctp_socket == 0) && ((tmr->type != SCTP_TIMER_TYPE_INPKILL) && + (tmr->type != SCTP_TIMER_TYPE_INIT) && (tmr->type != SCTP_TIMER_TYPE_SEND) && (tmr->type != SCTP_TIMER_TYPE_RECV) && (tmr->type != SCTP_TIMER_TYPE_HEARTBEAT) && @@ -2984,8 +2985,6 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error, ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb); ssf->ssf_assoc_id = sctp_get_associd(stcb); - SCTP_BUF_NEXT(m_notify) = chk->data; - SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed); if (chk->data) { /* * trim off the sctp chunk header(it should be there) @@ -2996,6 +2995,8 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error, chk->send_size -= sizeof(struct sctp_data_chunk); } } + SCTP_BUF_NEXT(m_notify) = chk->data; + SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed); /* Steal off the mbuf */ chk->data = NULL; /* @@ -3146,9 +3147,13 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb, } /* This always must be called with the read-queue LOCKED in the INP */ -void +static void sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error, - int nolock, uint32_t val) + uint32_t val, int so_locked +#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) + SCTP_UNUSED +#endif +) { struct mbuf *m_notify; struct sctp_pdapi_event *pdapi; @@ -3189,9 +3194,6 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error, control->tail_mbuf = m_notify; control->held_length = 0; control->length = 0; - if (nolock == 0) { - SCTP_INP_READ_LOCK(stcb->sctp_ep); - } sb = &stcb->sctp_socket->so_rcv; if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m_notify)); @@ -3208,12 +3210,30 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error, /* we really should not see this case */ TAILQ_INSERT_TAIL(&stcb->sctp_ep->read_queue, control, next); } - if (nolock == 0) { - SCTP_INP_READ_UNLOCK(stcb->sctp_ep); - } if (stcb->sctp_ep && stcb->sctp_socket) { /* This should always be the case */ +#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + struct socket *so; + + so = SCTP_INP_SO(stcb->sctp_ep); + if (!so_locked) { + atomic_add_int(&stcb->asoc.refcnt, 1); + SCTP_TCB_UNLOCK(stcb); + SCTP_SOCKET_LOCK(so, 1); + SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); + if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { + SCTP_SOCKET_UNLOCK(so, 1); + return; + } + } +#endif sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); +#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + if (!so_locked) { + SCTP_SOCKET_UNLOCK(so, 1); + } +#endif } } @@ -3540,9 +3560,9 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, val = *((uint32_t *) data); - sctp_notify_partial_delivery_indication(stcb, error, 0, val); + sctp_notify_partial_delivery_indication(stcb, error, val, so_locked); + break; } - break; case SCTP_NOTIFY_STRDATA_ERR: break; case SCTP_NOTIFY_ASSOC_ABORTED: @@ -3585,11 +3605,9 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, case SCTP_NOTIFY_STR_RESET_FAILED_OUT: sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), (SCTP_STRRESET_OUTBOUND_STR | SCTP_STRRESET_FAILED)); break; - case SCTP_NOTIFY_STR_RESET_FAILED_IN: sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), (SCTP_STRRESET_INBOUND_STR | SCTP_STRRESET_FAILED)); break; - case SCTP_NOTIFY_ASCONF_ADD_IP: sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data, error); @@ -3671,8 +3689,10 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked sctp_free_bufspace(stcb, asoc, chk, 1); sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_SENT, chk, so_locked); - sctp_m_freem(chk->data); - chk->data = NULL; + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; + } } sctp_free_a_chunk(stcb, chk); /* sa_ignore FREED_MEMORY */ @@ -3689,8 +3709,10 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked sctp_free_bufspace(stcb, asoc, chk, 1); sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk, so_locked); - sctp_m_freem(chk->data); - chk->data = NULL; + if (chk->data) { + sctp_m_freem(chk->data); + chk->data = NULL; + } } sctp_free_a_chunk(stcb, chk); /* sa_ignore FREED_MEMORY */ @@ -5346,6 +5368,38 @@ restart_nosblocks: } goto restart; } + if ((control->length == 0) && + (control->end_added == 1)) { + /* + * Do we also need to check for (control->pdapi_aborted == + * 1)? + */ + if (hold_rlock == 0) { + hold_rlock = 1; + SCTP_INP_READ_LOCK(inp); + } + TAILQ_REMOVE(&inp->read_queue, control, next); + if (control->data) { +#ifdef INVARIANTS + panic("control->data not null but control->length == 0"); +#else + SCTP_PRINTF("Strange, data left in the control buffer. Cleaning up.\n"); + sctp_m_freem(control->data); + control->data = NULL; +#endif + } + if (control->aux_data) { + sctp_m_free(control->aux_data); + control->aux_data = NULL; + } + sctp_free_remote_addr(control->whoFrom); + sctp_free_a_readq(stcb, control); + if (hold_rlock) { + hold_rlock = 0; + SCTP_INP_READ_UNLOCK(inp); + } + goto restart; + } if (control->length == 0) { if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) && (filling_sinfo)) { diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h index 89657e77fb4..f3a731ea1a0 100644 --- a/sys/netinet/sctputil.h +++ b/sys/netinet/sctputil.h @@ -234,10 +234,6 @@ int sctp_cmpaddr(struct sockaddr *, struct sockaddr *); void sctp_print_address(struct sockaddr *); void sctp_print_address_pkt(struct ip *, struct sctphdr *); -void -sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, - uint32_t error, int no_lock, uint32_t strseq); - int sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *, int, int From fd77c45934d3290a05d68f103d51d8e6653cdb08 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 16 Aug 2009 02:12:13 +0000 Subject: [PATCH 0056/2592] MFC rev 196268: Decouple ACPI CPU Ids from FreeBSD's cpuid. The ACPI Ids can be sparse, which causes a kernel assert. Approved by: re (kensmith) --- sys/ia64/ia64/genassym.c | 1 - sys/ia64/ia64/machdep.c | 6 +++++- sys/ia64/ia64/mp_machdep.c | 32 ++++++++++++++------------------ 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c index 8e988b67545..4a192fd79e3 100644 --- a/sys/ia64/ia64/genassym.c +++ b/sys/ia64/ia64/genassym.c @@ -91,7 +91,6 @@ ASSYM(MC_SPECIAL_RNAT, offsetof(mcontext_t, mc_special.rnat)); ASSYM(PAGE_SHIFT, PAGE_SHIFT); ASSYM(PAGE_SIZE, PAGE_SIZE); -ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid)); ASSYM(PC_CURRENT_PMAP, offsetof(struct pcpu, pc_current_pmap)); ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread)); ASSYM(PC_IDLETHREAD, offsetof(struct pcpu, pc_idlethread)); diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index b1e7298fa96..67ca3c28c49 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -424,7 +424,11 @@ void cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) { - pcpu->pc_acpi_id = cpuid; + /* + * Set pc_acpi_id to "uninitialized". + * See sys/dev/acpica/acpi_cpu.c + */ + pcpu->pc_acpi_id = 0xffffffff; } void diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index e94acadd235..92e26216e48 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -208,31 +208,25 @@ cpu_mp_add(u_int acpiid, u_int apicid, u_int apiceid) struct pcpu *pc; u_int64_t lid; void *dpcpu; - - /* Ignore any processor numbers outside our range */ - if (acpiid > mp_maxid) - return; - - KASSERT((all_cpus & (1UL << acpiid)) == 0, - ("%s: cpu%d already in CPU map", __func__, acpiid)); + u_int cpuid; lid = LID_SAPIC_SET(apicid, apiceid); + cpuid = ((ia64_get_lid() & LID_SAPIC_MASK) == lid) ? 0 : smp_cpus++; - if ((ia64_get_lid() & LID_SAPIC_MASK) == lid) { - KASSERT(acpiid == 0, - ("%s: the BSP must be cpu0", __func__)); - } + KASSERT((all_cpus & (1UL << cpuid)) == 0, + ("%s: cpu%d already in CPU map", __func__, acpiid)); - if (acpiid != 0) { + if (cpuid != 0) { pc = (struct pcpu *)malloc(sizeof(*pc), M_SMP, M_WAITOK); + pcpu_init(pc, cpuid, sizeof(*pc)); dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE); - pcpu_init(pc, acpiid, sizeof(*pc)); - dpcpu_init(dpcpu, acpiid); + dpcpu_init(dpcpu, cpuid); } else pc = pcpup; + pc->pc_acpi_id = acpiid; pc->pc_lid = lid; - all_cpus |= (1UL << acpiid); + all_cpus |= (1UL << cpuid); } void @@ -244,8 +238,8 @@ cpu_mp_announce() for (i = 0; i <= mp_maxid; i++) { pc = pcpu_find(i); if (pc != NULL) { - printf("cpu%d: SAPIC Id=%x, SAPIC Eid=%x", i, - LID_SAPIC_ID(pc->pc_lid), + printf("cpu%d: ACPI Id=%x, SAPIC Id=%x, SAPIC Eid=%x", + i, pc->pc_acpi_id, LID_SAPIC_ID(pc->pc_lid), LID_SAPIC_EID(pc->pc_lid)); if (i == 0) printf(" (BSP)\n"); @@ -305,7 +299,9 @@ cpu_mp_unleash(void *dummy) SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { cpus++; if (pc->pc_awake) { - kproc_create(ia64_store_mca_state, (void*)((uintptr_t)pc->pc_cpuid), NULL, 0, 0, "mca %u", pc->pc_cpuid); + kproc_create(ia64_store_mca_state, + (void*)((uintptr_t)pc->pc_cpuid), NULL, 0, 0, + "mca %u", pc->pc_cpuid); smp_cpus++; } } From 7ea9d2977c0ea9f95f2fddf178ad002703c485ff Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 16 Aug 2009 02:21:24 +0000 Subject: [PATCH 0057/2592] MFC revision 196269: Fix misalignment in nvpair_native_embedded() caused by the compiler replacing the bzero(). Approved by: re (kensmith) --- sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c b/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c index e5733344a82..eb824c7ef17 100644 --- a/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c +++ b/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c @@ -2523,14 +2523,15 @@ nvpair_native_embedded(nvstream_t *nvs, nvpair_t *nvp) { if (nvs->nvs_op == NVS_OP_ENCODE) { nvs_native_t *native = (nvs_native_t *)nvs->nvs_private; - nvlist_t *packed = (void *) + char *packed = (void *) (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp)); /* * Null out the pointer that is meaningless in the packed * structure. The address may not be aligned, so we have * to use bzero. */ - bzero(&packed->nvl_priv, sizeof (packed->nvl_priv)); + bzero(packed + offsetof(nvlist_t, nvl_priv), + sizeof(((nvlist_t *)NULL)->nvl_priv)); } return (nvs_embedded(nvs, EMBEDDED_NVL(nvp))); From 1e2c2ea509ef398ff3edef495e3ff3e7acc3e5e0 Mon Sep 17 00:00:00 2001 From: Rink Springer Date: Sun, 16 Aug 2009 10:25:58 +0000 Subject: [PATCH 0058/2592] MFC r196272 Prevent sysinstall from needlessly waiting for confirmation when using an USB device in non-interactive mode. If there are no USB devices, sysinstall gives an error messages, and if there is >1, it'll ask which one is to be used. This change allows a non-interactive install from USB media to succeed without any user interaction if there is exactly one USB disk device in the system it can use. Submitted by: Daniel O'Connor < doconnorat gsoft dot com dot au > Reviewed by: randi Approved by: re (rwatson) --- usr.sbin/sysinstall/media.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr.sbin/sysinstall/media.c b/usr.sbin/sysinstall/media.c index e50b47c8edd..b325323c613 100644 --- a/usr.sbin/sysinstall/media.c +++ b/usr.sbin/sysinstall/media.c @@ -262,7 +262,8 @@ mediaSetUSB(dialogMenuItem *self) mediaDevice = devs[0]; if (mediaDevice) mediaDevice->private = NULL; - msgConfirm("Using USB device: %s", mediaDevice->name); + if (!variable_get(VAR_NONINTERACTIVE)) + msgConfirm("Using USB device: %s", mediaDevice->name); return (mediaDevice ? DITEM_LEAVE_MENU : DITEM_FAILURE); } From a8ff174941028d99dfdba40b14e2ea60e3e1899d Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 16 Aug 2009 14:17:47 +0000 Subject: [PATCH 0059/2592] MFC r196274 Change the usb workers from kernel processes to threads, this is mostly a cosmetic change to reduce cruft in the proc table. Also change the idle wait message to `-` like how taskqueues are. Reviewed by: julian Approved by: re (kib) --- sys/dev/usb/usb_process.c | 12 +++++++----- sys/dev/usb/usb_process.h | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/sys/dev/usb/usb_process.c b/sys/dev/usb/usb_process.c index eb79f166508..5b98a819a8e 100644 --- a/sys/dev/usb/usb_process.c +++ b/sys/dev/usb/usb_process.c @@ -63,10 +63,12 @@ #endif #if (__FreeBSD_version >= 800000) +static struct proc *usbproc; #define USB_THREAD_CREATE(f, s, p, ...) \ - kproc_create((f), (s), (p), RFHIGHPID, 0, __VA_ARGS__) -#define USB_THREAD_SUSPEND(p) kproc_suspend(p,0) -#define USB_THREAD_EXIT(err) kproc_exit(err) + kproc_kthread_add((f), (s), &usbproc, (p), RFHIGHPID, \ + 0, "usb", __VA_ARGS__) +#define USB_THREAD_SUSPEND(p) kthread_suspend(p,0) +#define USB_THREAD_EXIT(err) kthread_exit() #else #define USB_THREAD_CREATE(f, s, p, ...) \ kthread_create((f), (s), (p), RFHIGHPID, 0, __VA_ARGS__) @@ -207,8 +209,8 @@ usb_proc_create(struct usb_process *up, struct mtx *p_mtx, TAILQ_INIT(&up->up_qhead); - cv_init(&up->up_cv, "wmsg"); - cv_init(&up->up_drain, "dmsg"); + cv_init(&up->up_cv, "-"); + cv_init(&up->up_drain, "usbdrain"); if (USB_THREAD_CREATE(&usb_process, up, &up->up_ptr, pmesg)) { diff --git a/sys/dev/usb/usb_process.h b/sys/dev/usb/usb_process.h index c717dc1522b..71432c3bf70 100644 --- a/sys/dev/usb/usb_process.h +++ b/sys/dev/usb/usb_process.h @@ -49,7 +49,11 @@ struct usb_process { struct cv up_cv; struct cv up_drain; +#if (__FreeBSD_version >= 800000) + struct thread *up_ptr; +#else struct proc *up_ptr; +#endif struct thread *up_curtd; struct mtx *up_mtx; From 336b627671be40facd81ac3dee36ff383dac4dcd Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 16 Aug 2009 20:33:16 +0000 Subject: [PATCH 0060/2592] MFC r196276: Fix small style regression introduced by the MPSAFE newbus code. Approved by: re (rwatson) --- sys/kern/subr_bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 67f09182d5f..52cd766296c 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -4131,7 +4131,7 @@ driver_module_handler(module_t mod, int what, void *arg) return (ENOMEM); } - switch (what) { + switch (what) { case MOD_LOAD: if (dmd->dmd_chainevh) error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg); From 75f5a2286dfc40780fb71a3f3846d7b1ddbe2e2f Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 16 Aug 2009 21:32:12 +0000 Subject: [PATCH 0061/2592] MFC change 196278: Emit a proper error message instead of dumping core when 1) GEOM_PART does not exist in the kernel, and 2) the GEOM in question does not exist. Additionally abort in case of programming errors that result in neither the class nor geom not being present in the gctl request. Approved by: re (kib) --- sbin/geom/class/part/geom_part.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index fc179a4cccc..db3c5e9515e 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -274,8 +274,18 @@ gpart_autofill(struct gctl_req *req) error = geom_gettree(&mesh); if (error) return (error); - cp = find_class(&mesh, gctl_get_ascii(req, "class")); - gp = find_geom(cp, gctl_get_ascii(req, "geom")); + s = gctl_get_ascii(req, "class"); + if (s == NULL) + abort(); + cp = find_class(&mesh, s); + if (cp == NULL) + errx(EXIT_FAILURE, "Class %s not found.", s); + s = gctl_get_ascii(req, "geom"); + if (s == NULL) + abort(); + gp = find_geom(cp, s); + if (gp == NULL) + errx(EXIT_FAILURE, "No such geom: %s.", s); first = atoll(find_geomcfg(gp, "first")); last = atoll(find_geomcfg(gp, "last")); grade = ~0ULL; @@ -536,6 +546,8 @@ gpart_write_partcode(struct gctl_req *req, int idx, void *code, ssize_t size) errx(EXIT_FAILURE, "Class %s not found.", s); } s = gctl_get_ascii(req, "geom"); + if (s == NULL) + abort(); gp = find_geom(classp, s); if (gp == NULL) errx(EXIT_FAILURE, "No such geom: %s.", s); From 91fa948790bc2a932345ceebbcd6fc7c16cb5f42 Mon Sep 17 00:00:00 2001 From: Scott Long Date: Mon, 17 Aug 2009 06:21:22 +0000 Subject: [PATCH 0062/2592] Merge r196200. Add firmware definitions needed by mfiutil Approved by: re --- sys/dev/mfi/mfi_ioctl.h | 2 + sys/dev/mfi/mfireg.h | 219 +++++++++++++++++++++++++++++++++------- 2 files changed, 184 insertions(+), 37 deletions(-) diff --git a/sys/dev/mfi/mfi_ioctl.h b/sys/dev/mfi/mfi_ioctl.h index 22973d7f3d2..48e9c7f7ba2 100644 --- a/sys/dev/mfi/mfi_ioctl.h +++ b/sys/dev/mfi/mfi_ioctl.h @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD$"); +#include + #if defined(__amd64__) /* Assume amd64 wants 32 bit Linux */ struct iovec32 { u_int32_t iov_base; diff --git a/sys/dev/mfi/mfireg.h b/sys/dev/mfi/mfireg.h index be56b481079..17ab4b3b5cf 100644 --- a/sys/dev/mfi/mfireg.h +++ b/sys/dev/mfi/mfireg.h @@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$"); #define MFI_ODCR0 0xa0 /* outbound doorbell clear register0 */ #define MFI_OSP0 0xb0 /* outbound scratch pad0 */ #define MFI_1078_EIM 0x80000004 /* 1078 enable intrrupt mask */ -#define MFI_RMI 0x2 /* reply message interrupt */ +#define MFI_RMI 0x2 /* reply message interrupt */ #define MFI_1078_RM 0x80000000 /* reply 1078 message interrupt */ #define MFI_ODC 0x4 /* outbound doorbell change interrupt */ @@ -151,15 +151,41 @@ typedef enum { MFI_DCMD_CTRL_EVENT_GETINFO = 0x01040100, MFI_DCMD_CTRL_EVENT_GET = 0x01040300, MFI_DCMD_CTRL_EVENT_WAIT = 0x01040500, + MFI_DCMD_PR_GET_STATUS = 0x01070100, + MFI_DCMD_PR_GET_PROPERTIES = 0x01070200, + MFI_DCMD_PR_SET_PROPERTIES = 0x01070300, + MFI_DCMD_PR_START = 0x01070400, + MFI_DCMD_PR_STOP = 0x01070500, + MFI_DCMD_TIME_SECS_GET = 0x01080201, + MFI_DCMD_FLASH_FW_OPEN = 0x010f0100, + MFI_DCMD_FLASH_FW_DOWNLOAD = 0x010f0200, + MFI_DCMD_FLASH_FW_FLASH = 0x010f0300, + MFI_DCMD_FLASH_FW_CLOSE = 0x010f0400, + MFI_DCMD_PD_GET_LIST = 0x02010000, + MFI_DCMD_PD_GET_INFO = 0x02020000, + MFI_DCMD_PD_STATE_SET = 0x02030100, + MFI_DCMD_PD_REBUILD_START = 0x02040100, + MFI_DCMD_PD_REBUILD_ABORT = 0x02040200, + MFI_DCMD_PD_CLEAR_START = 0x02050100, + MFI_DCMD_PD_CLEAR_ABORT = 0x02050200, + MFI_DCMD_PD_GET_PROGRESS = 0x02060000, + MFI_DCMD_PD_LOCATE_START = 0x02070100, + MFI_DCMD_PD_LOCATE_STOP = 0x02070200, MFI_DCMD_LD_GET_LIST = 0x03010000, MFI_DCMD_LD_GET_INFO = 0x03020000, MFI_DCMD_LD_GET_PROP = 0x03030000, MFI_DCMD_LD_SET_PROP = 0x03040000, + MFI_DCMD_LD_INIT_START = 0x03060100, MFI_DCMD_LD_DELETE = 0x03090000, MFI_DCMD_CFG_READ = 0x04010000, MFI_DCMD_CFG_ADD = 0x04020000, MFI_DCMD_CFG_CLEAR = 0x04030000, + MFI_DCMD_CFG_MAKE_SPARE = 0x04040000, + MFI_DCMD_CFG_REMOVE_SPARE = 0x04050000, MFI_DCMD_CFG_FOREIGN_IMPORT = 0x04060400, + MFI_DCMD_BBU_GET_STATUS = 0x05010000, + MFI_DCMD_BBU_GET_CAPACITY_INFO =0x05020000, + MFI_DCMD_BBU_GET_DESIGN_INFO = 0x05030000, MFI_DCMD_CLUSTER = 0x08000000, MFI_DCMD_CLUSTER_RESET_ALL = 0x08010100, MFI_DCMD_CLUSTER_RESET_LD = 0x08010200 @@ -245,6 +271,9 @@ typedef enum { MFI_STAT_RESERVATION_IN_PROGRESS, MFI_STAT_I2C_ERRORS_DETECTED, MFI_STAT_PCI_ERRORS_DETECTED, + MFI_STAT_DIAG_FAILED, + MFI_STAT_BOOT_MSG_PENDING, + MFI_STAT_FOREIGN_CONFIG_INCOMPLETE, MFI_STAT_INVALID_STATUS = 0xFF } mfi_status_t; @@ -303,6 +332,17 @@ typedef enum { MR_LD_CACHE_ALLOW_WRITE_CACHE = 0x20, MR_LD_CACHE_ALLOW_READ_CACHE = 0x40 } mfi_ld_cache; +#define MR_LD_CACHE_MASK 0x7f + +#define MR_LD_CACHE_POLICY_READ_AHEAD_NONE 0 +#define MR_LD_CACHE_POLICY_READ_AHEAD_ALWAYS MR_LD_CACHE_READ_AHEAD +#define MR_LD_CACHE_POLICY_READ_AHEAD_ADAPTIVE \ + (MR_LD_CACHE_READ_AHEAD | MR_LD_CACHE_READ_ADAPTIVE) +#define MR_LD_CACHE_POLICY_WRITE_THROUGH 0 +#define MR_LD_CACHE_POLICY_WRITE_BACK MR_LD_CACHE_WRITE_BACK +#define MR_LD_CACHE_POLICY_IO_CACHED \ + (MR_LD_CACHE_ALLOW_WRITE_CACHE | MR_LD_CACHE_ALLOW_READ_CACHE) +#define MR_LD_CACHE_POLICY_IO_DIRECT 0 typedef enum { MR_PD_CACHE_UNCHANGED = 0, @@ -320,6 +360,7 @@ typedef enum { #define MFI_DEFAULT_ID -1 #define MFI_MAX_LUN 8 #define MFI_MAX_LD 64 +#define MFI_MAX_PD 256 #define MFI_FRAME_SIZE 64 #define MFI_MBOX_SIZE 12 @@ -866,12 +907,10 @@ union mfi_pd_ddf_type { } __packed; struct mfi_pd_progress { - struct { - uint32_t rbld : 1; - uint32_t patrol : 1; - uint32_t clear : 1; - uint32_t reserved: 29; - } active; + uint32_t active; +#define MFI_PD_PROGRESS_REBUILD (1<<0) +#define MFI_PD_PROGRESS_PATROL (1<<1) +#define MFI_PD_PROGRESS_CLEAR (1<<2) struct mfi_progress rbld; struct mfi_progress patrol; struct mfi_progress clear; @@ -890,8 +929,8 @@ struct mfi_pd_info { uint32_t other_err_count; uint32_t pred_fail_count; uint32_t last_pred_fail_event_seq_num; - uint16_t fw_state; - uint8_t disable_for_removal; + uint16_t fw_state; /* MFI_PD_STATE_* */ + uint8_t disabled_for_removal; uint8_t link_speed; union mfi_pd_ddf_type state; struct { @@ -918,7 +957,7 @@ struct mfi_pd_address { uint16_t encl_device_id; uint8_t encl_index; uint8_t slot_number; - uint8_t scsi_dev_type; + uint8_t scsi_dev_type; /* 0 = disk */ uint8_t connect_port_bitmap; uint64_t sas_addr[2]; } __packed; @@ -926,12 +965,19 @@ struct mfi_pd_address { struct mfi_pd_list { uint32_t size; uint32_t count; - uint8_t data; - /* - struct mfi_pd_address addr[]; - */ + struct mfi_pd_address addr[0]; } __packed; +enum mfi_pd_state { + MFI_PD_STATE_UNCONFIGURED_GOOD = 0x00, + MFI_PD_STATE_UNCONFIGURED_BAD = 0x01, + MFI_PD_STATE_HOT_SPARE = 0x02, + MFI_PD_STATE_OFFLINE = 0x10, + MFI_PD_STATE_FAILED = 0x11, + MFI_PD_STATE_REBUILD = 0x14, + MFI_PD_STATE_ONLINE = 0x18 +}; + union mfi_ld_ref { struct { uint8_t target_id; @@ -986,6 +1032,9 @@ struct mfi_ld_params { uint8_t span_depth; uint8_t state; uint8_t init_state; +#define MFI_LD_PARAMS_INIT_NO 0 +#define MFI_LD_PARAMS_INIT_QUICK 1 +#define MFI_LD_PARAMS_INIT_FULL 2 uint8_t is_consistent; uint8_t reserved[23]; } __packed; @@ -995,7 +1044,7 @@ struct mfi_ld_progress { #define MFI_LD_PROGRESS_CC (1<<0) #define MFI_LD_PROGRESS_BGI (1<<1) #define MFI_LD_PROGRESS_FGI (1<<2) -#define MFI_LD_PORGRESS_RECON (1<<3) +#define MFI_LD_PROGRESS_RECON (1<<3) struct mfi_progress cc; struct mfi_progress bgi; struct mfi_progress fgi; @@ -1028,26 +1077,18 @@ struct mfi_ld_info { uint8_t reserved2[16]; } __packed; -union mfi_spare_type { - struct { - uint8_t is_dedicate :1; - uint8_t is_revertable :1; - uint8_t is_encl_affinity :1; - uint8_t reserved :5; - } v; - uint8_t type; -} __packed; - #define MAX_ARRAYS 16 struct mfi_spare { union mfi_pd_ref ref; - union mfi_spare_type spare_type; + uint8_t spare_type; +#define MFI_SPARE_DEDICATED (1 << 0) +#define MFI_SPARE_REVERTIBLE (1 << 1) +#define MFI_SPARE_ENCL_AFFINITY (1 << 2) uint8_t reserved[2]; uint8_t array_count; - uint16_t array_refd[MAX_ARRAYS]; + uint16_t array_ref[MAX_ARRAYS]; } __packed; -#define MAX_ROW_SIZE 32 struct mfi_array { uint64_t size; uint8_t num_drives; @@ -1055,13 +1096,13 @@ struct mfi_array { uint16_t array_ref; uint8_t pad[20]; struct { - union mfi_pd_ref ref; - uint16_t fw_state; + union mfi_pd_ref ref; /* 0xffff == missing drive */ + uint16_t fw_state; /* MFI_PD_STATE_* */ struct { uint8_t pd; uint8_t slot; } encl; - } pd[MAX_ROW_SIZE]; + } pd[0]; } __packed; struct mfi_config_data { @@ -1073,14 +1114,118 @@ struct mfi_config_data { uint16_t spares_count; uint16_t spares_size; uint8_t reserved[16]; - uint8_t data; - /* - struct mfi_array array[]; - struct mfi_ld_config ld[]; - struct mfi_spare spare[]; - */ + struct mfi_array array[0]; + struct mfi_ld_config ld[0]; + struct mfi_spare spare[0]; } __packed; +struct mfi_bbu_capacity_info { + uint16_t relative_charge; + uint16_t absolute_charge; + uint16_t remaining_capacity; + uint16_t full_charge_capacity; + uint16_t run_time_to_empty; + uint16_t average_time_to_empty; + uint16_t average_time_to_full; + uint16_t cycle_count; + uint16_t max_error; + uint16_t remaining_capacity_alarm; + uint16_t remaining_time_alarm; + uint8_t reserved[26]; +} __packed; + +struct mfi_bbu_design_info { + uint32_t mfg_date; + uint16_t design_capacity; + uint16_t design_voltage; + uint16_t spec_info; + uint16_t serial_number; + uint16_t pack_stat_config; + uint8_t mfg_name[12]; + uint8_t device_name[8]; + uint8_t device_chemistry[8]; + uint8_t mfg_data[8]; + uint8_t reserved[17]; +} __packed; + +struct mfi_ibbu_state { + uint16_t gas_guage_status; + uint16_t relative_charge; + uint16_t charger_system_state; + uint16_t charger_system_ctrl; + uint16_t charging_current; + uint16_t absolute_charge; + uint16_t max_error; + uint8_t reserved[18]; +} __packed; + +struct mfi_bbu_state { + uint16_t gas_guage_status; + uint16_t relative_charge; + uint16_t charger_status; + uint16_t remaining_capacity; + uint16_t full_charge_capacity; + uint8_t is_SOH_good; + uint8_t reserved[21]; +} __packed; + +union mfi_bbu_status_detail { + struct mfi_ibbu_state ibbu; + struct mfi_bbu_state bbu; +}; + +struct mfi_bbu_status { + uint8_t battery_type; +#define MFI_BBU_TYPE_NONE 0 +#define MFI_BBU_TYPE_IBBU 1 +#define MFI_BBU_TYPE_BBU 2 + uint8_t reserved; + uint16_t voltage; + int16_t current; + uint16_t temperature; + uint32_t fw_status; +#define MFI_BBU_STATE_PACK_MISSING (1 << 0) +#define MFI_BBU_STATE_VOLTAGE_LOW (1 << 1) +#define MFI_BBU_STATE_TEMPERATURE_HIGH (1 << 2) +#define MFI_BBU_STATE_CHARGE_ACTIVE (1 << 0) +#define MFI_BBU_STATE_DISCHARGE_ACTIVE (1 << 0) + uint8_t pad[20]; + union mfi_bbu_status_detail detail; +} __packed; + +enum mfi_pr_state { + MFI_PR_STATE_STOPPED = 0, + MFI_PR_STATE_READY = 1, + MFI_PR_STATE_ACTIVE = 2, + MFI_PR_STATE_ABORTED = 0xff +}; + +struct mfi_pr_status { + uint32_t num_iteration; + uint8_t state; + uint8_t num_pd_done; + uint8_t reserved[10]; +}; + +enum mfi_pr_opmode { + MFI_PR_OPMODE_AUTO = 0, + MFI_PR_OPMODE_MANUAL = 1, + MFI_PR_OPMODE_DISABLED = 2 +}; + +struct mfi_pr_properties { + uint8_t op_mode; + uint8_t max_pd; + uint8_t reserved; + uint8_t exclude_ld_count; + uint16_t excluded_ld[MFI_MAX_LD]; + uint8_t cur_pd_map[MFI_MAX_PD / 8]; + uint8_t last_pd_map[MFI_MAX_PD / 8]; + uint32_t next_exec; + uint32_t exec_freq; + uint32_t clear_freq; +}; + #define MFI_SCSI_MAX_TARGETS 128 #define MFI_SCSI_MAX_LUNS 8 #define MFI_SCSI_INITIATOR_ID 255 From 42eeb00e0b07c39024722fd89a543a24b7ac4663 Mon Sep 17 00:00:00 2001 From: Scott Long Date: Mon, 17 Aug 2009 07:25:12 +0000 Subject: [PATCH 0063/2592] Merge mfiutil Approved by: re --- usr.sbin/Makefile | 1 + usr.sbin/mfiutil/Makefile | 18 + usr.sbin/mfiutil/README | 104 +++ usr.sbin/mfiutil/mfi_cmd.c | 351 ++++++++++ usr.sbin/mfiutil/mfi_config.c | 1164 +++++++++++++++++++++++++++++++++ usr.sbin/mfiutil/mfi_drive.c | 625 ++++++++++++++++++ usr.sbin/mfiutil/mfi_evt.c | 667 +++++++++++++++++++ usr.sbin/mfiutil/mfi_flash.c | 199 ++++++ usr.sbin/mfiutil/mfi_patrol.c | 305 +++++++++ usr.sbin/mfiutil/mfi_show.c | 560 ++++++++++++++++ usr.sbin/mfiutil/mfi_volume.c | 412 ++++++++++++ usr.sbin/mfiutil/mfiutil.1 | 574 ++++++++++++++++ usr.sbin/mfiutil/mfiutil.8 | 566 ++++++++++++++++ usr.sbin/mfiutil/mfiutil.c | 134 ++++ usr.sbin/mfiutil/mfiutil.h | 147 +++++ 15 files changed, 5827 insertions(+) create mode 100644 usr.sbin/mfiutil/Makefile create mode 100644 usr.sbin/mfiutil/README create mode 100644 usr.sbin/mfiutil/mfi_cmd.c create mode 100644 usr.sbin/mfiutil/mfi_config.c create mode 100644 usr.sbin/mfiutil/mfi_drive.c create mode 100644 usr.sbin/mfiutil/mfi_evt.c create mode 100644 usr.sbin/mfiutil/mfi_flash.c create mode 100644 usr.sbin/mfiutil/mfi_patrol.c create mode 100644 usr.sbin/mfiutil/mfi_show.c create mode 100644 usr.sbin/mfiutil/mfi_volume.c create mode 100644 usr.sbin/mfiutil/mfiutil.1 create mode 100644 usr.sbin/mfiutil/mfiutil.8 create mode 100644 usr.sbin/mfiutil/mfiutil.c create mode 100644 usr.sbin/mfiutil/mfiutil.h diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index f57ff3a1daf..37d24f853cc 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -94,6 +94,7 @@ SUBDIR= ${_ac} \ manctl \ memcontrol \ mergemaster \ + mfiutil \ mixer \ ${_mld6query} \ mlxcontrol \ diff --git a/usr.sbin/mfiutil/Makefile b/usr.sbin/mfiutil/Makefile new file mode 100644 index 00000000000..03ded032958 --- /dev/null +++ b/usr.sbin/mfiutil/Makefile @@ -0,0 +1,18 @@ +# $FreeBSD$ +PROG= mfiutil + +SRCS= mfiutil.c mfi_cmd.c mfi_config.c mfi_drive.c mfi_evt.c mfi_flash.c \ + mfi_patrol.c mfi_show.c mfi_volume.c +MAN8= mfiutil.8 + +CFLAGS+= -fno-builtin-strftime +WARNS?=3 + +LDADD= -lutil + +# Here be dragons +.ifdef DEBUG +CFLAGS+= -DDEBUG +.endif + +.include diff --git a/usr.sbin/mfiutil/README b/usr.sbin/mfiutil/README new file mode 100644 index 00000000000..15e16bb0cdd --- /dev/null +++ b/usr.sbin/mfiutil/README @@ -0,0 +1,104 @@ +# $FreeBSD$ + +This package includes a mfiutil command for administering mfi(4) controllers +on FreeBSD. + +Version 1.0.13 + * Cleaned up warnings in preparation for integration with FreeBSD + +Version 1.0.12 + * Add 'drive clear' command to wipe drives with all 0x00 characters + +Version 1.0.11 + * Display serial number for drives + * Display location info for drives with 'show config' + +Version 1.0.10 + * Display min and max stripe size supported by adapters. + * Added support for examining the controller event log. + +Version 1.0.9 + * Display stripe size for volumes. + * Added support for setting the stripe size for new volumes. + * Fix a regression in 1.0.8 that broke creation of RAID-5 and RAID-50 + arrays. + +Version 1.0.8 + * Added support for RAID-60 arrays. + * Added 'flash' command to support firmware flashing. + +Version 1.0.7 + * Renamed 'clear config' to 'clear, 'create volume' to 'create', + 'delete volume' to 'delete', 'create spare' to 'add', and + 'delete spare' to 'remove'. The old names still work. + * Added support for RAID-6 arrays. + +Version 1.0.6 + * Added 'show patrol', 'patrol', 'start patrol', and 'stop patrol' + commands to manage patrol reads. + +Version 1.0.5 + * Added 'create volume' and 'delete volume' commands to manage volumes. + * Added 'clear config' command to clear entire configuration. + * Added more detailed error reporting based on firmware status codes. + * Renamed 'progress' command to 'drive progress'. + * Added 'volume progress' command to display progress of volume-level + activites such as background inits. + * Fixed 'create spare' to properly add global spares. + +Version 1.0.4 + * Added 'create spare' and 'delete spare' commands to manage hot spares. + * Added 'good' command to mark unconfigured bad drives as good. + * Display more information about hot spares in 'show config' + * Allow physical drives to be specified via Exx:Syy similar to megacli + * Display onboard memory size in 'show adapter' + +Version 1.0.3 + * Added 'cache' command to manage cache settings for volumes. + * Added 'name' command to name volumes. + * Added manpage. + +Version 1.0.2 + * Added 'show adapter' and 'show battery' commands. + * Added RAID level of volumes to 'show config' and 'show volumes'. + * Added drive model info to 'show config' and 'show drives'. + * Added package firmware version to 'show firmware'. + * Added read and write cache status to 'show volumes'. + * Map volume IDs to mfidX device names on newer kernels. + +Version 1.0.1 + * Added 'show firmware' command + +Version 1.0.0 + * Initial release + +usage: mfiutil [-u unit] ... + +Commands include: + version + show adapter - display controller information + show battery - display battery information + show config - display RAID configuration + show drives - list physical drives + show firmware - list firmware images + show volumes - list logical volumes + show patrol - display patrol read status + fail - fail a physical drive + good - mark a bad physical drive as good + rebuild - mark failed drive ready for rebuild + drive progress - display status of active operations + start rebuild + abort rebuild + locate - toggle drive LED + cache [command [setting]] + name + volume progress - display status of active operations + clear - clear volume configuration + create [-v] [,[,...]] [[,[,...]] + delete + add [volume] - add a hot spare + remove - remove a hot spare + patrol [interval [start]] + start patrol - start a patrol read + stop patrol - stop a patrol read + flash diff --git a/usr.sbin/mfiutil/mfi_cmd.c b/usr.sbin/mfiutil/mfi_cmd.c new file mode 100644 index 00000000000..abc8312aa22 --- /dev/null +++ b/usr.sbin/mfiutil/mfi_cmd.c @@ -0,0 +1,351 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mfiutil.h" +#include + +static const char *mfi_status_codes[] = { + "Command completed succesfully", + "Invalid command", + "Invalid DMCD opcode", + "Invalid parameter", + "Invalid Sequence Number", + "Abort isn't possible for the requested command", + "Application 'host' code not found", + "Application in use", + "Application not initialized", + "Array index invalid", + "Array row not empty", + "Configuration resource conflict", + "Device not found", + "Drive too small", + "Flash memory allocation failed", + "Flash download already in progress", + "Flash operation failed", + "Bad flash image", + "Incomplete flash image", + "Flash not open", + "Flash not started", + "Flush failed", + "Specified application doesn't have host-resident code", + "Volume consistency check in progress", + "Volume initialization in progress", + "Volume LBA out of range", + "Maximum number of volumes are already configured", + "Volume is not OPTIMAL", + "Volume rebuild in progress", + "Volume reconstruction in progress", + "Volume RAID level is wrong for requested operation", + "Too many spares assigned", + "Scratch memory not available", + "Error writing MFC data to SEEPROM", + "Required hardware is missing", + "Item not found", + "Volume drives are not within an enclosure", + "Drive clear in progress", + "Drive type mismatch (SATA vs SAS)", + "Patrol read disabled", + "Invalid row index", + "SAS Config - Invalid action", + "SAS Config - Invalid data", + "SAS Config - Invalid page", + "SAS Config - Invalid type", + "SCSI command completed with error", + "SCSI I/O request failed", + "SCSI RESERVATION_CONFLICT", + "One or more flush operations during shutdown failed", + "Firmware time is not set", + "Wrong firmware or drive state", + "Volume is offline", + "Peer controller rejected request", + "Unable to inform peer of communication changes", + "Volume reservation already in progress", + "I2C errors were detected", + "PCI errors occurred during XOR/DMA operation", + "Diagnostics failed", + "Unable to process command as boot messages are pending", + "Foreign configuration is incomplete" +}; + +const char * +mfi_status(u_int status_code) +{ + static char buffer[16]; + + if (status_code == MFI_STAT_INVALID_STATUS) + return ("Invalid status"); + if (status_code < sizeof(mfi_status_codes) / sizeof(char *)) + return (mfi_status_codes[status_code]); + snprintf(buffer, sizeof(buffer), "Status: 0x%02x", status_code); + return (buffer); +} + +const char * +mfi_raid_level(uint8_t primary_level, uint8_t secondary_level) +{ + static char buf[16]; + + switch (primary_level) { + case DDF_RAID0: + return ("RAID-0"); + case DDF_RAID1: + if (secondary_level != 0) + return ("RAID-10"); + else + return ("RAID-1"); + case DDF_RAID1E: + return ("RAID-1E"); + case DDF_RAID3: + return ("RAID-3"); + case DDF_RAID5: + if (secondary_level != 0) + return ("RAID-50"); + else + return ("RAID-5"); + case DDF_RAID5E: + return ("RAID-5E"); + case DDF_RAID5EE: + return ("RAID-5EE"); + case DDF_RAID6: + if (secondary_level != 0) + return ("RAID-60"); + else + return ("RAID-6"); + case DDF_JBOD: + return ("JBOD"); + case DDF_CONCAT: + return ("CONCAT"); + default: + sprintf(buf, "LVL 0x%02x", primary_level); + return (buf); + } +} + +static int +mfi_query_disk(int fd, uint8_t target_id, struct mfi_query_disk *info) +{ + + bzero(info, sizeof(*info)); + info->array_id = target_id; + if (ioctl(fd, MFIIO_QUERY_DISK, info) < 0) + return (-1); + if (!info->present) { + errno = ENXIO; + return (-1); + } + return (0); +} + +const char * +mfi_volume_name(int fd, uint8_t target_id) +{ + static struct mfi_query_disk info; + static char buf[4]; + + if (mfi_query_disk(fd, target_id, &info) < 0) { + snprintf(buf, sizeof(buf), "%d", target_id); + return (buf); + } + return (info.devname); +} + +int +mfi_volume_busy(int fd, uint8_t target_id) +{ + struct mfi_query_disk info; + + /* Assume it isn't mounted if we can't get information. */ + if (mfi_query_disk(fd, target_id, &info) < 0) + return (0); + return (info.open != 0); +} + +/* + * Check if the running kernel supports changing the RAID + * configuration of the mfi controller. + */ +int +mfi_reconfig_supported(void) +{ + char mibname[64]; + size_t len; + int dummy; + + len = sizeof(dummy); + snprintf(mibname, sizeof(mibname), "dev.mfi.%d.delete_busy_volumes", + mfi_unit); + return (sysctlbyname(mibname, &dummy, &len, NULL, 0) == 0); +} + +int +mfi_lookup_volume(int fd, const char *name, uint8_t *target_id) +{ + struct mfi_query_disk info; + struct mfi_ld_list list; + char *cp; + long val; + u_int i; + + /* If it's a valid number, treat it as a raw target ID. */ + val = strtol(name, &cp, 0); + if (*cp == '\0') { + *target_id = val; + return (0); + } + + if (mfi_dcmd_command(fd, MFI_DCMD_LD_GET_LIST, &list, sizeof(list), + NULL, 0, NULL) < 0) + return (-1); + + for (i = 0; i < list.ld_count; i++) { + if (mfi_query_disk(fd, list.ld_list[i].ld.v.target_id, + &info) < 0) + continue; + if (strcmp(name, info.devname) == 0) { + *target_id = list.ld_list[i].ld.v.target_id; + return (0); + } + } + errno = EINVAL; + return (-1); +} + +int +mfi_dcmd_command(int fd, uint32_t opcode, void *buf, size_t bufsize, + uint8_t *mbox, size_t mboxlen, uint8_t *statusp) +{ + struct mfi_ioc_passthru ioc; + struct mfi_dcmd_frame *dcmd; + int r; + + if ((mbox != NULL && (mboxlen == 0 || mboxlen > MFI_MBOX_SIZE)) || + (mbox == NULL && mboxlen != 0)) { + errno = EINVAL; + return (-1); + } + + bzero(&ioc, sizeof(ioc)); + dcmd = &ioc.ioc_frame; + if (mbox) + bcopy(mbox, dcmd->mbox, mboxlen); + dcmd->header.cmd = MFI_CMD_DCMD; + dcmd->header.timeout = 0; + dcmd->header.flags = 0; + dcmd->header.data_len = bufsize; + dcmd->opcode = opcode; + + ioc.buf = buf; + ioc.buf_size = bufsize; + r = ioctl(fd, MFIIO_PASSTHRU, &ioc); + if (r < 0) + return (r); + + if (statusp != NULL) + *statusp = dcmd->header.cmd_status; + else if (dcmd->header.cmd_status != MFI_STAT_OK) { + warnx("Command failed: %s", + mfi_status(dcmd->header.cmd_status)); + errno = EIO; + return (-1); + } + return (0); +} + +int +mfi_ctrl_get_info(int fd, struct mfi_ctrl_info *info, uint8_t *statusp) +{ + + return (mfi_dcmd_command(fd, MFI_DCMD_CTRL_GETINFO, info, + sizeof(struct mfi_ctrl_info), NULL, 0, statusp)); +} + +int +mfi_open(int unit) +{ + char path[MAXPATHLEN]; + + snprintf(path, sizeof(path), "/dev/mfi%d", unit); + return (open(path, O_RDWR)); +} + +void +mfi_display_progress(const char *label, struct mfi_progress *prog) +{ + uint seconds; + + printf("%s: %.2f%% complete, after %ds", label, + (float)prog->progress * 100 / 0xffff, prog->elapsed_seconds); + if (prog->elapsed_seconds > 10) { + printf(" finished in "); + seconds = (0x10000 * (uint32_t)prog->elapsed_seconds) / + prog->progress - prog->elapsed_seconds; + if (seconds > 3600) + printf("%u:", seconds / 3600); + if (seconds > 60) { + seconds %= 3600; + printf("%02u:%02u", seconds / 60, seconds % 60); + } else + printf("%us", seconds); + } + printf("\n"); +} + +int +mfi_table_handler(struct mfiutil_command **start, struct mfiutil_command **end, + int ac, char **av) +{ + struct mfiutil_command **cmd; + + if (ac < 2) { + warnx("The %s command requires a sub-command.", av[0]); + return (EINVAL); + } + for (cmd = start; cmd < end; cmd++) { + if (strcmp((*cmd)->name, av[1]) == 0) + return ((*cmd)->handler(ac - 1, av + 1)); + } + + warnx("%s is not a valid sub-command of %s.", av[1], av[0]); + return (ENOENT); +} diff --git a/usr.sbin/mfiutil/mfi_config.c b/usr.sbin/mfiutil/mfi_config.c new file mode 100644 index 00000000000..6152d21f582 --- /dev/null +++ b/usr.sbin/mfiutil/mfi_config.c @@ -0,0 +1,1164 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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$ + */ + +#include +#ifdef DEBUG +#include +#endif +#include +#include +#include +#ifdef DEBUG +#include +#endif +#include +#include +#include +#include +#include "mfiutil.h" + +#ifdef DEBUG +static void dump_config(int fd, struct mfi_config_data *config); +#endif + +static int add_spare(int ac, char **av); +static int remove_spare(int ac, char **av); + +#define powerof2(x) ((((x)-1)&(x))==0) + +static long +dehumanize(const char *value) +{ + char *vtp; + long iv; + + if (value == NULL) + return (0); + iv = strtoq(value, &vtp, 0); + if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) { + return (0); + } + switch (vtp[0]) { + case 't': case 'T': + iv *= 1024; + case 'g': case 'G': + iv *= 1024; + case 'm': case 'M': + iv *= 1024; + case 'k': case 'K': + iv *= 1024; + case '\0': + break; + default: + return (0); + } + return (iv); +} +int +mfi_config_read(int fd, struct mfi_config_data **configp) +{ + struct mfi_config_data *config; + uint32_t config_size; + + /* + * Keep fetching the config in a loop until we have a large enough + * buffer to hold the entire configuration. + */ + config = NULL; + config_size = 1024; +fetch: + config = reallocf(config, config_size); + if (config == NULL) + return (-1); + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_READ, config, + config_size, NULL, 0, NULL) < 0) + return (-1); + + if (config->size > config_size) { + config_size = config->size; + goto fetch; + } + + *configp = config; + return (0); +} + +static struct mfi_array * +mfi_config_lookup_array(struct mfi_config_data *config, uint16_t array_ref) +{ + struct mfi_array *ar; + char *p; + int i; + + p = (char *)config->array; + for (i = 0; i < config->array_count; i++) { + ar = (struct mfi_array *)p; + if (ar->array_ref == array_ref) + return (ar); + p += config->array_size; + } + + return (NULL); +} + +static struct mfi_ld_config * +mfi_config_lookup_volume(struct mfi_config_data *config, uint8_t target_id) +{ + struct mfi_ld_config *ld; + char *p; + int i; + + p = (char *)config->array + config->array_count * config->array_size; + for (i = 0; i < config->log_drv_count; i++) { + ld = (struct mfi_ld_config *)p; + if (ld->properties.ld.v.target_id == target_id) + return (ld); + p += config->log_drv_size; + } + + return (NULL); +} + +static int +clear_config(int ac, char **av) +{ + struct mfi_ld_list list; + int ch, fd; + u_int i; + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (!mfi_reconfig_supported()) { + warnx("The current mfi(4) driver does not support " + "configuration changes."); + return (EOPNOTSUPP); + } + + if (mfi_ld_get_list(fd, &list, NULL) < 0) { + warn("Failed to get volume list"); + return (errno); + } + + for (i = 0; i < list.ld_count; i++) { + if (mfi_volume_busy(fd, list.ld_list[i].ld.v.target_id)) { + warnx("Volume %s is busy and cannot be deleted", + mfi_volume_name(fd, list.ld_list[i].ld.v.target_id)); + return (EBUSY); + } + } + + printf( + "Are you sure you wish to clear the configuration on mfi%u? [y/N] ", + mfi_unit); + ch = getchar(); + if (ch != 'y' && ch != 'Y') { + printf("\nAborting\n"); + return (0); + } + + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_CLEAR, NULL, 0, NULL, 0, NULL) < 0) { + warn("Failed to clear configuration"); + return (errno); + } + + printf("mfi%d: Configuration cleared\n", mfi_unit); + close(fd); + + return (0); +} +MFI_COMMAND(top, clear, clear_config); + +#define MFI_ARRAY_SIZE 288 +#define MAX_DRIVES_PER_ARRAY \ + ((MFI_ARRAY_SIZE - sizeof(struct mfi_array)) / 8) + +#define RT_RAID0 0 +#define RT_RAID1 1 +#define RT_RAID5 2 +#define RT_RAID6 3 +#define RT_JBOD 4 +#define RT_CONCAT 5 +#define RT_RAID10 6 +#define RT_RAID50 7 +#define RT_RAID60 8 + +static int +compare_int(const void *one, const void *two) +{ + int first, second; + + first = *(const int *)one; + second = *(const int *)two; + + return (first - second); +} + +static struct raid_type_entry { + const char *name; + int raid_type; +} raid_type_table[] = { + { "raid0", RT_RAID0 }, + { "raid-0", RT_RAID0 }, + { "raid1", RT_RAID1 }, + { "raid-1", RT_RAID1 }, + { "mirror", RT_RAID1 }, + { "raid5", RT_RAID5 }, + { "raid-5", RT_RAID5 }, + { "raid6", RT_RAID6 }, + { "raid-6", RT_RAID6 }, + { "jbod", RT_JBOD }, + { "concat", RT_CONCAT }, + { "raid10", RT_RAID10 }, + { "raid1+0", RT_RAID10 }, + { "raid-10", RT_RAID10 }, + { "raid-1+0", RT_RAID10 }, + { "raid50", RT_RAID50 }, + { "raid5+0", RT_RAID50 }, + { "raid-50", RT_RAID50 }, + { "raid-5+0", RT_RAID50 }, + { "raid60", RT_RAID60 }, + { "raid6+0", RT_RAID60 }, + { "raid-60", RT_RAID60 }, + { "raid-6+0", RT_RAID60 }, + { NULL, 0 }, +}; + +struct config_id_state { + int array_count; + int log_drv_count; + int *arrays; + int *volumes; + uint16_t array_ref; + uint8_t target_id; +}; + +struct array_info { + int drive_count; + struct mfi_pd_info *drives; + struct mfi_array *array; +}; + +/* Parse a comma-separated list of drives for an array. */ +static int +parse_array(int fd, int raid_type, char *array_str, struct array_info *info) +{ + struct mfi_pd_info *pinfo; + uint16_t device_id; + char *cp; + u_int count; + int error; + + cp = array_str; + for (count = 0; cp != NULL; count++) { + cp = strchr(cp, ','); + if (cp != NULL) { + cp++; + if (*cp == ',') { + warnx("Invalid drive list '%s'", array_str); + return (EINVAL); + } + } + } + + /* Validate the number of drives for this array. */ + if (count >= MAX_DRIVES_PER_ARRAY) { + warnx("Too many drives for a single array: max is %zu", + MAX_DRIVES_PER_ARRAY); + return (EINVAL); + } + switch (raid_type) { + case RT_RAID1: + case RT_RAID10: + if (count % 2 != 0) { + warnx("RAID1 and RAID10 require an even number of " + "drives in each array"); + return (EINVAL); + } + break; + case RT_RAID5: + case RT_RAID50: + if (count < 3) { + warnx("RAID5 and RAID50 require at least 3 drives in " + "each array"); + return (EINVAL); + } + break; + case RT_RAID6: + case RT_RAID60: + if (count < 4) { + warnx("RAID6 and RAID60 require at least 4 drives in " + "each array"); + return (EINVAL); + } + break; + } + + /* Validate each drive. */ + info->drives = calloc(count, sizeof(struct mfi_pd_info)); + info->drive_count = count; + for (pinfo = info->drives; (cp = strsep(&array_str, ",")) != NULL; + pinfo++) { + error = mfi_lookup_drive(fd, cp, &device_id); + if (error) + return (error); + + if (mfi_pd_get_info(fd, device_id, pinfo, NULL) < 0) { + warn("Failed to fetch drive info for drive %s", cp); + return (errno); + } + + if (pinfo->fw_state != MFI_PD_STATE_UNCONFIGURED_GOOD) { + warnx("Drive %u is not available", device_id); + return (EINVAL); + } + } + + return (0); +} + +/* + * Find the next free array ref assuming that 'array_ref' is the last + * one used. 'array_ref' should be 0xffff for the initial test. + */ +static uint16_t +find_next_array(struct config_id_state *state) +{ + int i; + + /* Assume the current one is used. */ + state->array_ref++; + + /* Find the next free one. */ + for (i = 0; i < state->array_count; i++) + if (state->arrays[i] == state->array_ref) + state->array_ref++; + return (state->array_ref); +} + +/* + * Find the next free volume ID assuming that 'target_id' is the last + * one used. 'target_id' should be 0xff for the initial test. + */ +static uint8_t +find_next_volume(struct config_id_state *state) +{ + int i; + + /* Assume the current one is used. */ + state->target_id++; + + /* Find the next free one. */ + for (i = 0; i < state->log_drv_count; i++) + if (state->volumes[i] == state->target_id) + state->target_id++; + return (state->target_id); +} + +/* Populate an array with drives. */ +static void +build_array(int fd, char *arrayp, struct array_info *array_info, + struct config_id_state *state, int verbose) +{ + struct mfi_array *ar = (struct mfi_array *)arrayp; + int i; + + ar->size = array_info->drives[0].coerced_size; + ar->num_drives = array_info->drive_count; + ar->array_ref = find_next_array(state); + for (i = 0; i < array_info->drive_count; i++) { + if (verbose) + printf("Adding drive %u to array %u\n", + array_info->drives[i].ref.v.device_id, + ar->array_ref); + if (ar->size > array_info->drives[i].coerced_size) + ar->size = array_info->drives[i].coerced_size; + ar->pd[i].ref = array_info->drives[i].ref; + ar->pd[i].fw_state = MFI_PD_STATE_ONLINE; + } + array_info->array = ar; +} + +/* + * Create a volume that spans one or more arrays. + */ +static void +build_volume(char *volumep, int narrays, struct array_info *arrays, + int raid_type, long stripe_size, struct config_id_state *state, int verbose) +{ + struct mfi_ld_config *ld = (struct mfi_ld_config *)volumep; + struct mfi_array *ar; + int i; + + /* properties */ + ld->properties.ld.v.target_id = find_next_volume(state); + ld->properties.ld.v.seq = 0; + ld->properties.default_cache_policy = MR_LD_CACHE_ALLOW_WRITE_CACHE | + MR_LD_CACHE_WRITE_BACK; + ld->properties.access_policy = MFI_LD_ACCESS_RW; + ld->properties.disk_cache_policy = MR_PD_CACHE_UNCHANGED; + ld->properties.current_cache_policy = MR_LD_CACHE_ALLOW_WRITE_CACHE | + MR_LD_CACHE_WRITE_BACK; + ld->properties.no_bgi = 0; + + /* params */ + switch (raid_type) { + case RT_RAID0: + case RT_JBOD: + ld->params.primary_raid_level = DDF_RAID0; + ld->params.raid_level_qualifier = 0; + ld->params.secondary_raid_level = 0; + break; + case RT_RAID1: + ld->params.primary_raid_level = DDF_RAID1; + ld->params.raid_level_qualifier = 0; + ld->params.secondary_raid_level = 0; + break; + case RT_RAID5: + ld->params.primary_raid_level = DDF_RAID5; + ld->params.raid_level_qualifier = 3; + ld->params.secondary_raid_level = 0; + break; + case RT_RAID6: + ld->params.primary_raid_level = DDF_RAID6; + ld->params.raid_level_qualifier = 3; + ld->params.secondary_raid_level = 0; + break; + case RT_CONCAT: + ld->params.primary_raid_level = DDF_CONCAT; + ld->params.raid_level_qualifier = 0; + ld->params.secondary_raid_level = 0; + break; + case RT_RAID10: + ld->params.primary_raid_level = DDF_RAID1; + ld->params.raid_level_qualifier = 0; + ld->params.secondary_raid_level = 3; /* XXX? */ + break; + case RT_RAID50: + /* + * XXX: This appears to work though the card's BIOS + * complains that the configuration is foreign. The + * BIOS setup does not allow for creation of RAID-50 + * or RAID-60 arrays. The only nested array + * configuration it allows for is RAID-10. + */ + ld->params.primary_raid_level = DDF_RAID5; + ld->params.raid_level_qualifier = 3; + ld->params.secondary_raid_level = 3; /* XXX? */ + break; + case RT_RAID60: + ld->params.primary_raid_level = DDF_RAID6; + ld->params.raid_level_qualifier = 3; + ld->params.secondary_raid_level = 3; /* XXX? */ + break; + } + + /* + * Stripe size is encoded as (2 ^ N) * 512 = stripe_size. Use + * ffs() to simulate log2(stripe_size). + */ + ld->params.stripe_size = ffs(stripe_size) - 1 - 9; + ld->params.num_drives = arrays[0].array->num_drives; + ld->params.span_depth = narrays; + ld->params.state = MFI_LD_STATE_OPTIMAL; + ld->params.init_state = MFI_LD_PARAMS_INIT_NO; + ld->params.is_consistent = 0; + + /* spans */ + for (i = 0; i < narrays; i++) { + ar = arrays[i].array; + if (verbose) + printf("Adding array %u to volume %u\n", ar->array_ref, + ld->properties.ld.v.target_id); + ld->span[i].start_block = 0; + ld->span[i].num_blocks = ar->size; + ld->span[i].array_ref = ar->array_ref; + } +} + +static int +create_volume(int ac, char **av) +{ + struct mfi_config_data *config; + struct mfi_array *ar; + struct mfi_ld_config *ld; + struct config_id_state state; + size_t config_size; + char *p, *cfg_arrays, *cfg_volumes; + int error, fd, i, raid_type; + int narrays, nvolumes, arrays_per_volume; + struct array_info *arrays; + long stripe_size; +#ifdef DEBUG + int dump; +#endif + int ch, verbose; + + /* + * Backwards compat. Map 'create volume' to 'create' and + * 'create spare' to 'add'. + */ + if (ac > 1) { + if (strcmp(av[1], "volume") == 0) { + av++; + ac--; + } else if (strcmp(av[1], "spare") == 0) { + av++; + ac--; + return (add_spare(ac, av)); + } + } + + if (ac < 2) { + warnx("create volume: volume type required"); + return (EINVAL); + } + + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (!mfi_reconfig_supported()) { + warnx("The current mfi(4) driver does not support " + "configuration changes."); + return (EOPNOTSUPP); + } + + /* Lookup the RAID type first. */ + raid_type = -1; + for (i = 0; raid_type_table[i].name != NULL; i++) + if (strcasecmp(raid_type_table[i].name, av[1]) == 0) { + raid_type = raid_type_table[i].raid_type; + break; + } + + if (raid_type == -1) { + warnx("Unknown or unsupported volume type %s", av[1]); + return (EINVAL); + } + + /* Parse any options. */ + optind = 2; +#ifdef DEBUG + dump = 0; +#endif + verbose = 0; + stripe_size = 64 * 1024; + + while ((ch = getopt(ac, av, "ds:v")) != -1) { + switch (ch) { +#ifdef DEBUG + case 'd': + dump = 1; + break; +#endif + case 's': + stripe_size = dehumanize(optarg); + if ((stripe_size < 512) || (!powerof2(stripe_size))) + stripe_size = 64 * 1024; + break; + case 'v': + verbose = 1; + break; + case '?': + default: + return (EINVAL); + } + } + ac -= optind; + av += optind; + + /* Parse all the arrays. */ + narrays = ac; + if (narrays == 0) { + warnx("At least one drive list is required"); + return (EINVAL); + } + switch (raid_type) { + case RT_RAID0: + case RT_RAID1: + case RT_RAID5: + case RT_RAID6: + case RT_CONCAT: + if (narrays != 1) { + warnx("Only one drive list can be specified"); + return (EINVAL); + } + break; + case RT_RAID10: + case RT_RAID50: + case RT_RAID60: + if (narrays < 1) { + warnx("RAID10, RAID50, and RAID60 require at least " + "two drive lists"); + return (EINVAL); + } + if (narrays > MFI_MAX_SPAN_DEPTH) { + warnx("Volume spans more than %d arrays", + MFI_MAX_SPAN_DEPTH); + return (EINVAL); + } + break; + } + arrays = calloc(narrays, sizeof(*arrays)); + for (i = 0; i < narrays; i++) { + error = parse_array(fd, raid_type, av[i], &arrays[i]); + if (error) + return (error); + } + + switch (raid_type) { + case RT_RAID10: + case RT_RAID50: + case RT_RAID60: + for (i = 1; i < narrays; i++) { + if (arrays[i].drive_count != arrays[0].drive_count) { + warnx("All arrays must contain the same " + "number of drives"); + return (EINVAL); + } + } + break; + } + + /* + * Fetch the current config and build sorted lists of existing + * array and volume identifiers. + */ + if (mfi_config_read(fd, &config) < 0) { + warn("Failed to read configuration"); + return (errno); + } + p = (char *)config->array; + state.array_ref = 0xffff; + state.target_id = 0xff; + state.array_count = config->array_count; + if (config->array_count > 0) { + state.arrays = calloc(config->array_count, sizeof(int)); + for (i = 0; i < config->array_count; i++) { + ar = (struct mfi_array *)p; + state.arrays[i] = ar->array_ref; + p += config->array_size; + } + qsort(state.arrays, config->array_count, sizeof(int), + compare_int); + } else + state.arrays = NULL; + state.log_drv_count = config->log_drv_count; + if (config->log_drv_count) { + state.volumes = calloc(config->log_drv_count, sizeof(int)); + for (i = 0; i < config->log_drv_count; i++) { + ld = (struct mfi_ld_config *)p; + state.volumes[i] = ld->properties.ld.v.target_id; + p += config->log_drv_size; + } + qsort(state.volumes, config->log_drv_count, sizeof(int), + compare_int); + } else + state.volumes = NULL; + free(config); + + /* Determine the size of the configuration we will build. */ + switch (raid_type) { + case RT_RAID0: + case RT_RAID1: + case RT_RAID5: + case RT_RAID6: + case RT_CONCAT: + case RT_JBOD: + /* Each volume spans a single array. */ + nvolumes = narrays; + break; + case RT_RAID10: + case RT_RAID50: + case RT_RAID60: + /* A single volume spans multiple arrays. */ + nvolumes = 1; + break; + default: + /* Pacify gcc. */ + abort(); + } + + config_size = sizeof(struct mfi_config_data) + + sizeof(struct mfi_ld_config) * nvolumes + MFI_ARRAY_SIZE * narrays; + config = calloc(1, config_size); + config->size = config_size; + config->array_count = narrays; + config->array_size = MFI_ARRAY_SIZE; /* XXX: Firmware hardcode */ + config->log_drv_count = nvolumes; + config->log_drv_size = sizeof(struct mfi_ld_config); + config->spares_count = 0; + config->spares_size = 40; /* XXX: Firmware hardcode */ + cfg_arrays = (char *)config->array; + cfg_volumes = cfg_arrays + config->array_size * narrays; + + /* Build the arrays. */ + for (i = 0; i < narrays; i++) { + build_array(fd, cfg_arrays, &arrays[i], &state, verbose); + cfg_arrays += config->array_size; + } + + /* Now build the volume(s). */ + arrays_per_volume = narrays / nvolumes; + for (i = 0; i < nvolumes; i++) { + build_volume(cfg_volumes, arrays_per_volume, + &arrays[i * arrays_per_volume], raid_type, stripe_size, + &state, verbose); + cfg_volumes += config->log_drv_size; + } + +#ifdef DEBUG + if (dump) + dump_config(fd, config); + else +#endif + + /* Send the new config to the controller. */ + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_ADD, config, config_size, + NULL, 0, NULL) < 0) { + warn("Failed to add volume"); + return (errno); + } + + /* Clean up. */ + free(config); + if (state.log_drv_count > 0) + free(state.volumes); + if (state.array_count > 0) + free(state.arrays); + for (i = 0; i < narrays; i++) + free(arrays[i].drives); + free(arrays); + close(fd); + + return (0); +} +MFI_COMMAND(top, create, create_volume); + +static int +delete_volume(int ac, char **av) +{ + struct mfi_ld_info info; + int fd; + uint8_t target_id, mbox[4]; + + /* + * Backwards compat. Map 'delete volume' to 'delete' and + * 'delete spare' to 'remove'. + */ + if (ac > 1) { + if (strcmp(av[1], "volume") == 0) { + av++; + ac--; + } else if (strcmp(av[1], "spare") == 0) { + av++; + ac--; + return (remove_spare(ac, av)); + } + } + + if (ac != 2) { + warnx("delete volume: volume required"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (!mfi_reconfig_supported()) { + warnx("The current mfi(4) driver does not support " + "configuration changes."); + return (EOPNOTSUPP); + } + + if (mfi_lookup_volume(fd, av[1], &target_id) < 0) { + warn("Invalid volume %s", av[1]); + return (errno); + } + + if (mfi_ld_get_info(fd, target_id, &info, NULL) < 0) { + warn("Failed to get info for volume %d", target_id); + return (errno); + } + + if (mfi_volume_busy(fd, target_id)) { + warnx("Volume %s is busy and cannot be deleted", + mfi_volume_name(fd, target_id)); + return (EBUSY); + } + + mbox_store_ldref(mbox, &info.ld_config.properties.ld); + if (mfi_dcmd_command(fd, MFI_DCMD_LD_DELETE, NULL, 0, mbox, + sizeof(mbox), NULL) < 0) { + warn("Failed to delete volume"); + return (errno); + } + + close(fd); + + return (0); +} +MFI_COMMAND(top, delete, delete_volume); + +static int +add_spare(int ac, char **av) +{ + struct mfi_pd_info info; + struct mfi_config_data *config; + struct mfi_array *ar; + struct mfi_ld_config *ld; + struct mfi_spare *spare; + uint16_t device_id; + uint8_t target_id; + char *p; + int error, fd, i; + + if (ac < 2) { + warnx("add spare: drive required"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + error = mfi_lookup_drive(fd, av[1], &device_id); + if (error) + return (error); + + if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) { + warn("Failed to fetch drive info"); + return (errno); + } + + if (info.fw_state != MFI_PD_STATE_UNCONFIGURED_GOOD) { + warnx("Drive %u is not available", device_id); + return (EINVAL); + } + + if (ac > 2) { + if (mfi_lookup_volume(fd, av[2], &target_id) < 0) { + warn("Invalid volume %s", av[2]); + return (errno); + } + } + + if (mfi_config_read(fd, &config) < 0) { + warn("Failed to read configuration"); + return (errno); + } + + spare = malloc(sizeof(struct mfi_spare) + sizeof(uint16_t) * + config->array_count); + bzero(spare, sizeof(struct mfi_spare)); + spare->ref = info.ref; + + if (ac == 2) { + /* Global spare backs all arrays. */ + p = (char *)config->array; + for (i = 0; i < config->array_count; i++) { + ar = (struct mfi_array *)p; + if (ar->size > info.coerced_size) { + warnx("Spare isn't large enough for array %u", + ar->array_ref); + return (EINVAL); + } + p += config->array_size; + } + spare->array_count = 0; + } else { + /* + * Dedicated spares only back the arrays for a + * specific volume. + */ + ld = mfi_config_lookup_volume(config, target_id); + if (ld == NULL) { + warnx("Did not find volume %d", target_id); + return (EINVAL); + } + + spare->spare_type |= MFI_SPARE_DEDICATED; + spare->array_count = ld->params.span_depth; + for (i = 0; i < ld->params.span_depth; i++) { + ar = mfi_config_lookup_array(config, + ld->span[i].array_ref); + if (ar == NULL) { + warnx("Missing array; inconsistent config?"); + return (ENXIO); + } + if (ar->size > info.coerced_size) { + warnx("Spare isn't large enough for array %u", + ar->array_ref); + return (EINVAL); + } + spare->array_ref[i] = ar->array_ref; + } + } + free(config); + + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_MAKE_SPARE, spare, + sizeof(struct mfi_spare) + sizeof(uint16_t) * spare->array_count, + NULL, 0, NULL) < 0) { + warn("Failed to assign spare"); + return (errno); + } + + close(fd); + + return (0); +} +MFI_COMMAND(top, add, add_spare); + +static int +remove_spare(int ac, char **av) +{ + struct mfi_pd_info info; + int error, fd; + uint16_t device_id; + uint8_t mbox[4]; + + if (ac != 2) { + warnx("remove spare: drive required"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + error = mfi_lookup_drive(fd, av[1], &device_id); + if (error) + return (error); + + /* Get the info for this drive. */ + if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) { + warn("Failed to fetch info for drive %u", device_id); + return (errno); + } + + if (info.fw_state != MFI_PD_STATE_HOT_SPARE) { + warnx("Drive %u is not a hot spare", device_id); + return (EINVAL); + } + + mbox_store_pdref(mbox, &info.ref); + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_REMOVE_SPARE, NULL, 0, mbox, + sizeof(mbox), NULL) < 0) { + warn("Failed to delete spare"); + return (errno); + } + + close(fd); + + return (0); +} +MFI_COMMAND(top, remove, remove_spare); + +#ifdef DEBUG +/* Display raw data about a config. */ +static void +dump_config(int fd, struct mfi_config_data *config) +{ + struct mfi_array *ar; + struct mfi_ld_config *ld; + struct mfi_spare *sp; + struct mfi_pd_info pinfo; + uint16_t device_id; + char *p; + int i, j; + + printf( + "mfi%d Configuration (Debug): %d arrays, %d volumes, %d spares\n", + mfi_unit, config->array_count, config->log_drv_count, + config->spares_count); + printf(" array size: %u\n", config->array_size); + printf(" volume size: %u\n", config->log_drv_size); + printf(" spare size: %u\n", config->spares_size); + p = (char *)config->array; + + for (i = 0; i < config->array_count; i++) { + ar = (struct mfi_array *)p; + printf(" array %u of %u drives:\n", ar->array_ref, + ar->num_drives); + printf(" size = %ju\n", (uintmax_t)ar->size); + for (j = 0; j < ar->num_drives; j++) { + device_id = ar->pd[j].ref.device_id; + if (device_id == 0xffff) + printf(" drive MISSING\n"); + else { + printf(" drive %u %s\n", device_id, + mfi_pdstate(ar->pd[j].fw_state)); + if (mfi_pd_get_info(fd, device_id, &pinfo, + NULL) >= 0) { + printf(" raw size: %ju\n", + (uintmax_t)pinfo.raw_size); + printf(" non-coerced size: %ju\n", + (uintmax_t)pinfo.non_coerced_size); + printf(" coerced size: %ju\n", + (uintmax_t)pinfo.coerced_size); + } + } + } + p += config->array_size; + } + + for (i = 0; i < config->log_drv_count; i++) { + ld = (struct mfi_ld_config *)p; + printf(" volume %s ", + mfi_volume_name(fd, ld->properties.ld.v.target_id)); + printf("%s %s", + mfi_raid_level(ld->params.primary_raid_level, + ld->params.secondary_raid_level), + mfi_ldstate(ld->params.state)); + if (ld->properties.name[0] != '\0') + printf(" <%s>", ld->properties.name); + printf("\n"); + printf(" primary raid level: %u\n", + ld->params.primary_raid_level); + printf(" raid level qualifier: %u\n", + ld->params.raid_level_qualifier); + printf(" secondary raid level: %u\n", + ld->params.secondary_raid_level); + printf(" stripe size: %u\n", ld->params.stripe_size); + printf(" num drives: %u\n", ld->params.num_drives); + printf(" init state: %u\n", ld->params.init_state); + printf(" consistent: %u\n", ld->params.is_consistent); + printf(" no bgi: %u\n", ld->properties.no_bgi); + printf(" spans:\n"); + for (j = 0; j < ld->params.span_depth; j++) { + printf(" array %u @ ", ld->span[j].array_ref); + printf("%ju : %ju\n", + (uintmax_t)ld->span[j].start_block, + (uintmax_t)ld->span[j].num_blocks); + } + p += config->log_drv_size; + } + + for (i = 0; i < config->spares_count; i++) { + sp = (struct mfi_spare *)p; + printf(" %s spare %u ", + sp->spare_type & MFI_SPARE_DEDICATED ? "dedicated" : + "global", sp->ref.device_id); + printf("%s", mfi_pdstate(MFI_PD_STATE_HOT_SPARE)); + printf(" backs:\n"); + for (j = 0; j < sp->array_count; j++) + printf(" array %u\n", sp->array_ref[j]); + p += config->spares_size; + } +} + +static int +debug_config(int ac, char **av) +{ + struct mfi_config_data *config; + int fd; + + if (ac != 1) { + warnx("debug: extra arguments"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + /* Get the config from the controller. */ + if (mfi_config_read(fd, &config) < 0) { + warn("Failed to get config"); + return (errno); + } + + /* Dump out the configuration. */ + dump_config(fd, config); + free(config); + close(fd); + + return (0); +} +MFI_COMMAND(top, debug, debug_config); + +static int +dump(int ac, char **av) +{ + struct mfi_config_data *config; + char buf[64]; + size_t len; + int fd; + + if (ac != 1) { + warnx("dump: extra arguments"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + /* Get the stashed copy of the last dcmd from the driver. */ + snprintf(buf, sizeof(buf), "dev.mfi.%d.debug_command", mfi_unit); + if (sysctlbyname(buf, NULL, &len, NULL, 0) < 0) { + warn("Failed to read debug command"); + if (errno == ENOENT) + errno = EOPNOTSUPP; + return (errno); + } + + config = malloc(len); + if (sysctlbyname(buf, config, &len, NULL, 0) < 0) { + warn("Failed to read debug command"); + return (errno); + } + dump_config(fd, config); + free(config); + close(fd); + + return (0); +} +MFI_COMMAND(top, dump, dump); +#endif diff --git a/usr.sbin/mfiutil/mfi_drive.c b/usr.sbin/mfiutil/mfi_drive.c new file mode 100644 index 00000000000..104422814ea --- /dev/null +++ b/usr.sbin/mfiutil/mfi_drive.c @@ -0,0 +1,625 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mfiutil.h" + +MFI_TABLE(top, drive); + +const char * +mfi_pdstate(enum mfi_pd_state state) +{ + static char buf[16]; + + switch (state) { + case MFI_PD_STATE_UNCONFIGURED_GOOD: + return ("UNCONFIGURED GOOD"); + case MFI_PD_STATE_UNCONFIGURED_BAD: + return ("UNCONFIGURED BAD"); + case MFI_PD_STATE_HOT_SPARE: + return ("HOT SPARE"); + case MFI_PD_STATE_OFFLINE: + return ("OFFLINE"); + case MFI_PD_STATE_FAILED: + return ("FAILED"); + case MFI_PD_STATE_REBUILD: + return ("REBUILD"); + case MFI_PD_STATE_ONLINE: + return ("ONLINE"); + default: + sprintf(buf, "PSTATE 0x%04x", state); + return (buf); + } +} + +int +mfi_lookup_drive(int fd, char *drive, uint16_t *device_id) +{ + struct mfi_pd_list *list; + uint8_t encl, slot; + long val; + u_int i; + char *cp; + + /* Look for a raw device id first. */ + val = strtol(drive, &cp, 0); + if (*cp == '\0') { + if (val < 0 || val >= 0xffff) + goto bad; + *device_id = val; + return (0); + } + + /* Support for MegaCli style [Exx]:Syy notation. */ + if (toupper(drive[0]) == 'E' || toupper(drive[0]) == 'S') { + if (drive[1] == '\0') + goto bad; + cp = drive; + if (toupper(drive[0]) == 'E') { + cp++; /* Eat 'E' */ + val = strtol(cp, &cp, 0); + if (val < 0 || val > 0xff || *cp != ':') + goto bad; + encl = val; + cp++; /* Eat ':' */ + if (toupper(*cp) != 'S') + goto bad; + } else + encl = 0xff; + cp++; /* Eat 'S' */ + if (*cp == '\0') + goto bad; + val = strtol(cp, &cp, 0); + if (val < 0 || val > 0xff || *cp != '\0') + goto bad; + slot = val; + + if (mfi_pd_get_list(fd, &list, NULL) < 0) { + warn("Failed to fetch drive list"); + return (errno); + } + + for (i = 0; i < list->count; i++) { + if (list->addr[i].scsi_dev_type != 0) + continue; + + if (((encl == 0xff && + list->addr[i].encl_device_id == 0xffff) || + list->addr[i].encl_index == encl) && + list->addr[i].slot_number == slot) { + *device_id = list->addr[i].device_id; + free(list); + return (0); + } + } + free(list); + warnx("Unknown drive %s", drive); + return (EINVAL); + } + +bad: + warnx("Invalid drive number %s", drive); + return (EINVAL); +} + +static void +mbox_store_device_id(uint8_t *mbox, uint16_t device_id) +{ + + mbox[0] = device_id & 0xff; + mbox[1] = device_id >> 8; +} + +void +mbox_store_pdref(uint8_t *mbox, union mfi_pd_ref *ref) +{ + + mbox[0] = ref->v.device_id & 0xff; + mbox[1] = ref->v.device_id >> 8; + mbox[2] = ref->v.seq_num & 0xff; + mbox[3] = ref->v.seq_num >> 8; +} + +int +mfi_pd_get_list(int fd, struct mfi_pd_list **listp, uint8_t *statusp) +{ + struct mfi_pd_list *list; + uint32_t list_size; + + /* + * Keep fetching the list in a loop until we have a large enough + * buffer to hold the entire list. + */ + list = NULL; + list_size = 1024; +fetch: + list = reallocf(list, list_size); + if (list == NULL) + return (-1); + if (mfi_dcmd_command(fd, MFI_DCMD_PD_GET_LIST, list, list_size, NULL, + 0, statusp) < 0) { + free(list); + return (-1); + } + + if (list->size > list_size) { + list_size = list->size; + goto fetch; + } + + *listp = list; + return (0); +} + +int +mfi_pd_get_info(int fd, uint16_t device_id, struct mfi_pd_info *info, + uint8_t *statusp) +{ + uint8_t mbox[2]; + + mbox_store_device_id(&mbox[0], device_id); + return (mfi_dcmd_command(fd, MFI_DCMD_PD_GET_INFO, info, + sizeof(struct mfi_pd_info), mbox, 2, statusp)); +} + +static void +cam_strvis(char *dst, const char *src, int srclen, int dstlen) +{ + + /* Trim leading/trailing spaces, nulls. */ + while (srclen > 0 && src[0] == ' ') + src++, srclen--; + while (srclen > 0 + && (src[srclen-1] == ' ' || src[srclen-1] == '\0')) + srclen--; + + while (srclen > 0 && dstlen > 1) { + char *cur_pos = dst; + + if (*src < 0x20) { + /* SCSI-II Specifies that these should never occur. */ + /* non-printable character */ + if (dstlen > 4) { + *cur_pos++ = '\\'; + *cur_pos++ = ((*src & 0300) >> 6) + '0'; + *cur_pos++ = ((*src & 0070) >> 3) + '0'; + *cur_pos++ = ((*src & 0007) >> 0) + '0'; + } else { + *cur_pos++ = '?'; + } + } else { + /* normal character */ + *cur_pos++ = *src; + } + src++; + srclen--; + dstlen -= cur_pos - dst; + dst = cur_pos; + } + *dst = '\0'; +} + +/* Borrowed heavily from scsi_all.c:scsi_print_inquiry(). */ +const char * +mfi_pd_inq_string(struct mfi_pd_info *info) +{ + struct scsi_inquiry_data *inq_data; + char vendor[16], product[48], revision[16], rstr[12], serial[SID_VENDOR_SPECIFIC_0_SIZE]; + static char inq_string[64]; + + inq_data = (struct scsi_inquiry_data *)info->inquiry_data; + if (SID_QUAL_IS_VENDOR_UNIQUE(inq_data)) + return (NULL); + if (SID_TYPE(inq_data) != T_DIRECT) + return (NULL); + if (SID_QUAL(inq_data) != SID_QUAL_LU_CONNECTED) + return (NULL); + + cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor), + sizeof(vendor)); + cam_strvis(product, inq_data->product, sizeof(inq_data->product), + sizeof(product)); + cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision), + sizeof(revision)); + cam_strvis(serial, (char *)inq_data->vendor_specific0, sizeof(inq_data->vendor_specific0), + sizeof(serial)); + + /* Hack for SATA disks, no idea how to tell speed. */ + if (strcmp(vendor, "ATA") == 0) { + snprintf(inq_string, sizeof(inq_string), "<%s %s serial=%s> SATA", + product, revision, serial); + return (inq_string); + } + + switch (SID_ANSI_REV(inq_data)) { + case SCSI_REV_CCS: + strcpy(rstr, "SCSI-CCS"); + break; + case 5: + strcpy(rstr, "SAS"); + break; + default: + snprintf(rstr, sizeof (rstr), "SCSI-%d", + SID_ANSI_REV(inq_data)); + break; + } + snprintf(inq_string, sizeof(inq_string), "<%s %s %s serial=%s> %s", vendor, + product, revision, serial, rstr); + return (inq_string); +} + +/* Helper function to set a drive to a given state. */ +static int +drive_set_state(char *drive, uint16_t new_state) +{ + struct mfi_pd_info info; + uint16_t device_id; + uint8_t mbox[6]; + int error, fd; + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + error = mfi_lookup_drive(fd, drive, &device_id); + if (error) + return (error); + + /* Get the info for this drive. */ + if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) { + warn("Failed to fetch info for drive %u", device_id); + return (errno); + } + + /* Try to change the state. */ + if (info.fw_state == new_state) { + warnx("Drive %u is already in the desired state", device_id); + return (EINVAL); + } + + mbox_store_pdref(&mbox[0], &info.ref); + mbox[4] = new_state & 0xff; + mbox[5] = new_state >> 8; + if (mfi_dcmd_command(fd, MFI_DCMD_PD_STATE_SET, NULL, 0, mbox, 6, + NULL) < 0) { + warn("Failed to set drive %u to %s", device_id, + mfi_pdstate(new_state)); + return (errno); + } + + close(fd); + + return (0); +} + +static int +fail_drive(int ac, char **av) +{ + + if (ac != 2) { + warnx("fail: %s", ac > 2 ? "extra arguments" : + "drive required"); + return (EINVAL); + } + + return (drive_set_state(av[1], MFI_PD_STATE_FAILED)); +} +MFI_COMMAND(top, fail, fail_drive); + +static int +good_drive(int ac, char **av) +{ + + if (ac != 2) { + warnx("good: %s", ac > 2 ? "extra arguments" : + "drive required"); + return (EINVAL); + } + + return (drive_set_state(av[1], MFI_PD_STATE_UNCONFIGURED_GOOD)); +} +MFI_COMMAND(top, good, good_drive); + +static int +rebuild_drive(int ac, char **av) +{ + + if (ac != 2) { + warnx("rebuild: %s", ac > 2 ? "extra arguments" : + "drive required"); + return (EINVAL); + } + + return (drive_set_state(av[1], MFI_PD_STATE_REBUILD)); +} +MFI_COMMAND(top, rebuild, rebuild_drive); + +static int +start_rebuild(int ac, char **av) +{ + struct mfi_pd_info info; + uint16_t device_id; + uint8_t mbox[4]; + int error, fd; + + if (ac != 2) { + warnx("start rebuild: %s", ac > 2 ? "extra arguments" : + "drive required"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + error = mfi_lookup_drive(fd, av[1], &device_id); + if (error) + return (error); + + /* Get the info for this drive. */ + if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) { + warn("Failed to fetch info for drive %u", device_id); + return (errno); + } + + /* Check the state, must be REBUILD. */ + if (info.fw_state != MFI_PD_STATE_REBUILD) { + warn("Drive %d is not in the REBUILD state", device_id); + return (EINVAL); + } + + /* Start the rebuild. */ + mbox_store_pdref(&mbox[0], &info.ref); + if (mfi_dcmd_command(fd, MFI_DCMD_PD_REBUILD_START, NULL, 0, mbox, 4, + NULL) < 0) { + warn("Failed to start rebuild on drive %u", device_id); + return (errno); + } + close(fd); + + return (0); +} +MFI_COMMAND(start, rebuild, start_rebuild); + +static int +abort_rebuild(int ac, char **av) +{ + struct mfi_pd_info info; + uint16_t device_id; + uint8_t mbox[4]; + int error, fd; + + if (ac != 2) { + warnx("abort rebuild: %s", ac > 2 ? "extra arguments" : + "drive required"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + error = mfi_lookup_drive(fd, av[1], &device_id); + if (error) + return (error); + + /* Get the info for this drive. */ + if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) { + warn("Failed to fetch info for drive %u", device_id); + return (errno); + } + + /* Check the state, must be REBUILD. */ + if (info.fw_state != MFI_PD_STATE_REBUILD) { + warn("Drive %d is not in the REBUILD state", device_id); + return (EINVAL); + } + + /* Abort the rebuild. */ + mbox_store_pdref(&mbox[0], &info.ref); + if (mfi_dcmd_command(fd, MFI_DCMD_PD_REBUILD_ABORT, NULL, 0, mbox, 4, + NULL) < 0) { + warn("Failed to abort rebuild on drive %u", device_id); + return (errno); + } + close(fd); + + return (0); +} +MFI_COMMAND(abort, rebuild, abort_rebuild); + +static int +drive_progress(int ac, char **av) +{ + struct mfi_pd_info info; + uint16_t device_id; + int error, fd; + + if (ac != 2) { + warnx("drive progress: %s", ac > 2 ? "extra arguments" : + "drive required"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + error = mfi_lookup_drive(fd, av[1], &device_id); + if (error) + return (error); + + /* Get the info for this drive. */ + if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) { + warn("Failed to fetch info for drive %u", device_id); + return (errno); + } + close(fd); + + /* Display any of the active events. */ + if (info.prog_info.active & MFI_PD_PROGRESS_REBUILD) + mfi_display_progress("Rebuild", &info.prog_info.rbld); + if (info.prog_info.active & MFI_PD_PROGRESS_PATROL) + mfi_display_progress("Patrol Read", &info.prog_info.patrol); + if (info.prog_info.active & MFI_PD_PROGRESS_CLEAR) + mfi_display_progress("Clear", &info.prog_info.clear); + if ((info.prog_info.active & (MFI_PD_PROGRESS_REBUILD | + MFI_PD_PROGRESS_PATROL | MFI_PD_PROGRESS_CLEAR)) == 0) + printf("No activity in progress for drive %u.\n", device_id); + + return (0); +} +MFI_COMMAND(drive, progress, drive_progress); + +static int +drive_clear(int ac, char **av) +{ + struct mfi_pd_info info; + uint32_t opcode; + uint16_t device_id; + uint8_t mbox[4]; + char *s1; + int error, fd; + + if (ac != 3) { + warnx("drive clear: %s", ac > 3 ? "extra arguments" : + "drive and action requires"); + return (EINVAL); + } + + for (s1 = av[2]; *s1 != '\0'; s1++) + *s1 = tolower(*s1); + if (strcmp(av[2], "start") == 0) + opcode = MFI_DCMD_PD_CLEAR_START; + else if ((strcmp(av[2], "stop") == 0) || (strcmp(av[2], "abort") == 0)) + opcode = MFI_DCMD_PD_CLEAR_ABORT; + else { + warnx("drive clear: invalid action, must be 'start' or 'stop'\n"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + error = mfi_lookup_drive(fd, av[1], &device_id); + if (error) + return (error); + + /* Get the info for this drive. */ + if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) { + warn("Failed to fetch info for drive %u", device_id); + return (errno); + } + + mbox_store_pdref(&mbox[0], &info.ref); + if (mfi_dcmd_command(fd, opcode, NULL, 0, mbox, 4, NULL) < 0) { + warn("Failed to %s clear on drive %u", + opcode == MFI_DCMD_PD_CLEAR_START ? "start" : "stop", + device_id); + return (errno); + } + + close(fd); + return (0); +} +MFI_COMMAND(drive, clear, drive_clear); + +static int +drive_locate(int ac, char **av) +{ + uint16_t device_id; + uint32_t opcode; + int error, fd; + uint8_t mbox[4]; + + if (ac != 3) { + warnx("locate: %s", ac > 3 ? "extra arguments" : + "drive and state required"); + return (EINVAL); + } + + if (strcasecmp(av[2], "on") == 0 || strcasecmp(av[2], "start") == 0) + opcode = MFI_DCMD_PD_LOCATE_START; + else if (strcasecmp(av[2], "off") == 0 || + strcasecmp(av[2], "stop") == 0) + opcode = MFI_DCMD_PD_LOCATE_STOP; + else { + warnx("locate: invalid state %s", av[2]); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + error = mfi_lookup_drive(fd, av[1], &device_id); + if (error) + return (error); + + + mbox_store_device_id(&mbox[0], device_id); + mbox[2] = 0; + mbox[3] = 0; + if (mfi_dcmd_command(fd, opcode, NULL, 0, mbox, 4, NULL) < 0) { + warn("Failed to %s locate on drive %u", + opcode == MFI_DCMD_PD_LOCATE_START ? "start" : "stop", + device_id); + return (errno); + } + close(fd); + + return (0); +} +MFI_COMMAND(top, locate, drive_locate); diff --git a/usr.sbin/mfiutil/mfi_evt.c b/usr.sbin/mfiutil/mfi_evt.c new file mode 100644 index 00000000000..d553dae086e --- /dev/null +++ b/usr.sbin/mfiutil/mfi_evt.c @@ -0,0 +1,667 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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$ + */ + +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include "mfiutil.h" + +static int +mfi_event_get_info(int fd, struct mfi_evt_log_state *info, uint8_t *statusp) +{ + + return (mfi_dcmd_command(fd, MFI_DCMD_CTRL_EVENT_GETINFO, info, + sizeof(struct mfi_evt_log_state), NULL, 0, statusp)); +} + +static int +mfi_get_events(int fd, struct mfi_evt_list *list, int num_events, + union mfi_evt filter, uint32_t start_seq, uint8_t *statusp) +{ + uint32_t mbox[2]; + size_t size; + + mbox[0] = start_seq; + mbox[1] = filter.word; + size = sizeof(struct mfi_evt_list) + sizeof(struct mfi_evt_detail) * + (num_events - 1); + return (mfi_dcmd_command(fd, MFI_DCMD_CTRL_EVENT_GET, list, size, + (uint8_t *)&mbox, sizeof(mbox), statusp)); +} + +static int +show_logstate(int ac, char **av) +{ + struct mfi_evt_log_state info; + int fd; + + if (ac != 1) { + warnx("show logstate: extra arguments"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_event_get_info(fd, &info, NULL) < 0) { + warn("Failed to get event log info"); + return (errno); + } + + printf("mfi%d Event Log Sequence Numbers:\n", mfi_unit); + printf(" Newest Seq #: %u\n", info.newest_seq_num); + printf(" Oldest Seq #: %u\n", info.oldest_seq_num); + printf(" Clear Seq #: %u\n", info.clear_seq_num); + printf("Shutdown Seq #: %u\n", info.shutdown_seq_num); + printf(" Boot Seq #: %u\n", info.boot_seq_num); + + close(fd); + + return (0); +} +MFI_COMMAND(show, logstate, show_logstate); + +static int +parse_seq(struct mfi_evt_log_state *info, char *arg, uint32_t *seq) +{ + char *cp; + long val; + + if (strcasecmp(arg, "newest") == 0) { + *seq = info->newest_seq_num; + return (0); + } + if (strcasecmp(arg, "oldest") == 0) { + *seq = info->oldest_seq_num; + return (0); + } + if (strcasecmp(arg, "clear") == 0) { + *seq = info->clear_seq_num; + return (0); + } + if (strcasecmp(arg, "shutdown") == 0) { + *seq = info->shutdown_seq_num; + return (0); + } + if (strcasecmp(arg, "boot") == 0) { + *seq = info->boot_seq_num; + return (0); + } + val = strtol(arg, &cp, 0); + if (*cp != '\0' || val < 0) { + errno = EINVAL; + return (-1); + } + *seq = val; + return (0); +} + +static int +parse_locale(char *arg, uint16_t *locale) +{ + char *cp; + long val; + + if (strncasecmp(arg, "vol", 3) == 0 || strcasecmp(arg, "ld") == 0) { + *locale = MFI_EVT_LOCALE_LD; + return (0); + } + if (strncasecmp(arg, "drive", 5) == 0 || strcasecmp(arg, "pd") == 0) { + *locale = MFI_EVT_LOCALE_PD; + return (0); + } + if (strncasecmp(arg, "encl", 4) == 0) { + *locale = MFI_EVT_LOCALE_ENCL; + return (0); + } + if (strncasecmp(arg, "batt", 4) == 0 || + strncasecmp(arg, "bbu", 3) == 0) { + *locale = MFI_EVT_LOCALE_BBU; + return (0); + } + if (strcasecmp(arg, "sas") == 0) { + *locale = MFI_EVT_LOCALE_SAS; + return (0); + } + if (strcasecmp(arg, "ctrl") == 0 || strncasecmp(arg, "cont", 4) == 0) { + *locale = MFI_EVT_LOCALE_CTRL; + return (0); + } + if (strcasecmp(arg, "config") == 0) { + *locale = MFI_EVT_LOCALE_CONFIG; + return (0); + } + if (strcasecmp(arg, "cluster") == 0) { + *locale = MFI_EVT_LOCALE_CLUSTER; + return (0); + } + if (strcasecmp(arg, "all") == 0) { + *locale = MFI_EVT_LOCALE_ALL; + return (0); + } + val = strtol(arg, &cp, 0); + if (*cp != '\0' || val < 0 || val > 0xffff) { + errno = EINVAL; + return (-1); + } + *locale = val; + return (0); +} + +static int +parse_class(char *arg, int8_t *class) +{ + char *cp; + long val; + + if (strcasecmp(arg, "debug") == 0) { + *class = MFI_EVT_CLASS_DEBUG; + return (0); + } + if (strncasecmp(arg, "prog", 4) == 0) { + *class = MFI_EVT_CLASS_PROGRESS; + return (0); + } + if (strncasecmp(arg, "info", 4) == 0) { + *class = MFI_EVT_CLASS_INFO; + return (0); + } + if (strncasecmp(arg, "warn", 4) == 0) { + *class = MFI_EVT_CLASS_WARNING; + return (0); + } + if (strncasecmp(arg, "crit", 4) == 0) { + *class = MFI_EVT_CLASS_CRITICAL; + return (0); + } + if (strcasecmp(arg, "fatal") == 0) { + *class = MFI_EVT_CLASS_FATAL; + return (0); + } + if (strcasecmp(arg, "dead") == 0) { + *class = MFI_EVT_CLASS_DEAD; + return (0); + } + val = strtol(arg, &cp, 0); + if (*cp != '\0' || val < -128 || val > 127) { + errno = EINVAL; + return (-1); + } + *class = val; + return (0); +} + +/* + * The timestamp is the number of seconds since 00:00 Jan 1, 2000. If + * the bits in 24-31 are all set, then it is the number of seconds since + * boot. + */ +static const char * +format_timestamp(uint32_t timestamp) +{ + static char buffer[32]; + static time_t base; + time_t t; + struct tm tm; + + if ((timestamp & 0xff000000) == 0xff000000) { + snprintf(buffer, sizeof(buffer), "boot + %us", timestamp & + 0x00ffffff); + return (buffer); + } + + if (base == 0) { + /* Compute 00:00 Jan 1, 2000 offset. */ + bzero(&tm, sizeof(tm)); + tm.tm_mday = 1; + tm.tm_year = (2000 - 1900); + base = mktime(&tm); + } + if (base == -1) { + snprintf(buffer, sizeof(buffer), "%us", timestamp); + return (buffer); + } + t = base + timestamp; + strftime(buffer, sizeof(buffer), "%+", localtime(&t)); + return (buffer); +} + +static const char * +format_locale(uint16_t locale) +{ + static char buffer[8]; + + switch (locale) { + case MFI_EVT_LOCALE_LD: + return ("VOLUME"); + case MFI_EVT_LOCALE_PD: + return ("DRIVE"); + case MFI_EVT_LOCALE_ENCL: + return ("ENCL"); + case MFI_EVT_LOCALE_BBU: + return ("BATTERY"); + case MFI_EVT_LOCALE_SAS: + return ("SAS"); + case MFI_EVT_LOCALE_CTRL: + return ("CTRL"); + case MFI_EVT_LOCALE_CONFIG: + return ("CONFIG"); + case MFI_EVT_LOCALE_CLUSTER: + return ("CLUSTER"); + case MFI_EVT_LOCALE_ALL: + return ("ALL"); + default: + snprintf(buffer, sizeof(buffer), "0x%04x", locale); + return (buffer); + } +} + +static const char * +format_class(int8_t class) +{ + static char buffer[6]; + + switch (class) { + case MFI_EVT_CLASS_DEBUG: + return ("debug"); + case MFI_EVT_CLASS_PROGRESS: + return ("progress"); + case MFI_EVT_CLASS_INFO: + return ("info"); + case MFI_EVT_CLASS_WARNING: + return ("WARN"); + case MFI_EVT_CLASS_CRITICAL: + return ("CRIT"); + case MFI_EVT_CLASS_FATAL: + return ("FATAL"); + case MFI_EVT_CLASS_DEAD: + return ("DEAD"); + default: + snprintf(buffer, sizeof(buffer), "%d", class); + return (buffer); + } +} + +/* Simulates %D from kernel printf(9). */ +static void +simple_hex(void *ptr, size_t length, const char *separator) +{ + unsigned char *cp; + u_int i; + + if (length == 0) + return; + cp = ptr; + printf("%02x", cp[0]); + for (i = 1; i < length; i++) + printf("%s%02x", separator, cp[i]); +} + +static const char * +pdrive_location(struct mfi_evt_pd *pd) +{ + static char buffer[16]; + + if (pd->enclosure_index == 0) + snprintf(buffer, sizeof(buffer), "%02d(s%d)", pd->device_id, + pd->slot_number); + else + snprintf(buffer, sizeof(buffer), "%02d(e%d/s%d)", pd->device_id, + pd->enclosure_index, pd->slot_number); + return (buffer); +} + +static const char * +volume_name(int fd, struct mfi_evt_ld *ld) +{ + + return (mfi_volume_name(fd, ld->target_id)); +} + +/* Ripped from sys/dev/mfi/mfi.c. */ +static void +mfi_decode_evt(int fd, struct mfi_evt_detail *detail, int verbose) +{ + + printf("%5d (%s/%s/%s) - ", detail->seq, format_timestamp(detail->time), + format_locale(detail->class.members.locale), + format_class(detail->class.members.class)); + switch (detail->arg_type) { + case MR_EVT_ARGS_NONE: + break; + case MR_EVT_ARGS_CDB_SENSE: + if (verbose) { + printf("PD %s CDB ", + pdrive_location(&detail->args.cdb_sense.pd) + ); + simple_hex(detail->args.cdb_sense.cdb, + detail->args.cdb_sense.cdb_len, ":"); + printf(" Sense "); + simple_hex(detail->args.cdb_sense.sense, + detail->args.cdb_sense.sense_len, ":"); + printf(":\n "); + } + break; + case MR_EVT_ARGS_LD: + printf("VOL %s event: ", volume_name(fd, &detail->args.ld)); + break; + case MR_EVT_ARGS_LD_COUNT: + printf("VOL %s", volume_name(fd, &detail->args.ld_count.ld)); + if (verbose) { + printf(" count %lld: ", + (long long)detail->args.ld_count.count); + } + printf(": "); + break; + case MR_EVT_ARGS_LD_LBA: + printf("VOL %s", volume_name(fd, &detail->args.ld_count.ld)); + if (verbose) { + printf(" lba %lld", + (long long)detail->args.ld_lba.lba); + } + printf(": "); + break; + case MR_EVT_ARGS_LD_OWNER: + printf("VOL %s", volume_name(fd, &detail->args.ld_count.ld)); + if (verbose) { + printf(" owner changed: prior %d, new %d", + detail->args.ld_owner.pre_owner, + detail->args.ld_owner.new_owner); + } + printf(": "); + break; + case MR_EVT_ARGS_LD_LBA_PD_LBA: + printf("VOL %s", volume_name(fd, &detail->args.ld_count.ld)); + if (verbose) { + printf(" lba %lld, physical drive PD %s lba %lld", + (long long)detail->args.ld_lba_pd_lba.ld_lba, + pdrive_location(&detail->args.ld_lba_pd_lba.pd), + (long long)detail->args.ld_lba_pd_lba.pd_lba); + } + printf(": "); + break; + case MR_EVT_ARGS_LD_PROG: + printf("VOL %s", volume_name(fd, &detail->args.ld_prog.ld)); + if (verbose) { + printf(" progress %d%% in %ds", + detail->args.ld_prog.prog.progress/655, + detail->args.ld_prog.prog.elapsed_seconds); + } + printf(": "); + break; + case MR_EVT_ARGS_LD_STATE: + printf("VOL %s", volume_name(fd, &detail->args.ld_prog.ld)); + if (verbose) { + printf(" state prior %s new %s", + mfi_ldstate(detail->args.ld_state.prev_state), + mfi_ldstate(detail->args.ld_state.new_state)); + } + printf(": "); + break; + case MR_EVT_ARGS_LD_STRIP: + printf("VOL %s", volume_name(fd, &detail->args.ld_prog.ld)); + if (verbose) { + printf(" strip %lld", + (long long)detail->args.ld_strip.strip); + } + printf(": "); + break; + case MR_EVT_ARGS_PD: + if (verbose) { + printf("PD %s event: ", + pdrive_location(&detail->args.pd)); + } + break; + case MR_EVT_ARGS_PD_ERR: + if (verbose) { + printf("PD %s err %d: ", + pdrive_location(&detail->args.pd_err.pd), + detail->args.pd_err.err); + } + break; + case MR_EVT_ARGS_PD_LBA: + if (verbose) { + printf("PD %s lba %lld: ", + pdrive_location(&detail->args.pd_lba.pd), + (long long)detail->args.pd_lba.lba); + } + break; + case MR_EVT_ARGS_PD_LBA_LD: + if (verbose) { + printf("PD %s lba %lld VOL %s: ", + pdrive_location(&detail->args.pd_lba_ld.pd), + (long long)detail->args.pd_lba.lba, + volume_name(fd, &detail->args.pd_lba_ld.ld)); + } + break; + case MR_EVT_ARGS_PD_PROG: + if (verbose) { + printf("PD %s progress %d%% seconds %ds: ", + pdrive_location(&detail->args.pd_prog.pd), + detail->args.pd_prog.prog.progress/655, + detail->args.pd_prog.prog.elapsed_seconds); + } + break; + case MR_EVT_ARGS_PD_STATE: + if (verbose) { + printf("PD %s state prior %s new %s: ", + pdrive_location(&detail->args.pd_prog.pd), + mfi_pdstate(detail->args.pd_state.prev_state), + mfi_pdstate(detail->args.pd_state.new_state)); + } + break; + case MR_EVT_ARGS_PCI: + if (verbose) { + printf("PCI 0x%04x 0x%04x 0x%04x 0x%04x: ", + detail->args.pci.venderId, + detail->args.pci.deviceId, + detail->args.pci.subVenderId, + detail->args.pci.subDeviceId); + } + break; + case MR_EVT_ARGS_RATE: + if (verbose) { + printf("Rebuild rate %d: ", detail->args.rate); + } + break; + case MR_EVT_ARGS_TIME: + if (verbose) { + printf("Adapter time %s; %d seconds since power on: ", + format_timestamp(detail->args.time.rtc), + detail->args.time.elapsedSeconds); + } + break; + case MR_EVT_ARGS_ECC: + if (verbose) { + printf("Adapter ECC %x,%x: %s: ", + detail->args.ecc.ecar, + detail->args.ecc.elog, + detail->args.ecc.str); + } + break; + default: + if (verbose) { + printf("Type %d: ", detail->arg_type); + } + break; + } + printf("%s\n", detail->description); +} + +static int +show_events(int ac, char **av) +{ + struct mfi_evt_log_state info; + struct mfi_evt_list *list; + union mfi_evt filter; + long val; + char *cp; + ssize_t size; + uint32_t seq, start, stop; + uint8_t status; + int ch, fd, num_events, verbose; + u_int i; + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_event_get_info(fd, &info, NULL) < 0) { + warn("Failed to get event log info"); + return (errno); + } + + /* Default settings. */ + num_events = 15; + filter.members.reserved = 0; + filter.members.locale = MFI_EVT_LOCALE_ALL; + filter.members.class = MFI_EVT_CLASS_WARNING; + start = info.boot_seq_num; + stop = info.newest_seq_num; + verbose = 0; + + /* Parse any options. */ + optind = 1; + while ((ch = getopt(ac, av, "c:l:n:v")) != -1) { + switch (ch) { + case 'c': + if (parse_class(optarg, &filter.members.class) < 0) { + warn("Error parsing event class"); + return (errno); + } + break; + case 'l': + if (parse_locale(optarg, &filter.members.locale) < 0) { + warn("Error parsing event locale"); + return (errno); + } + break; + case 'n': + val = strtol(optarg, &cp, 0); + if (*cp != '\0' || val <= 0) { + warnx("Invalid event count"); + return (EINVAL); + } + num_events = val; + break; + case 'v': + verbose = 1; + break; + case '?': + default: + return (EINVAL); + } + } + ac -= optind; + av += optind; + + /* Determine buffer size and validate it. */ + size = sizeof(struct mfi_evt_list) + sizeof(struct mfi_evt_detail) * + (num_events - 1); + if (size > getpagesize()) { + warnx("Event count is too high"); + return (EINVAL); + } + + /* Handle optional start and stop sequence numbers. */ + if (ac > 2) { + warnx("show events: extra arguments"); + return (EINVAL); + } + if (ac > 0 && parse_seq(&info, av[0], &start) < 0) { + warn("Error parsing starting sequence number"); + return (errno); + } + if (ac > 1 && parse_seq(&info, av[1], &stop) < 0) { + warn("Error parsing ending sequence number"); + return (errno); + } + + list = malloc(size); + for (seq = start;;) { + if (mfi_get_events(fd, list, num_events, filter, seq, + &status) < 0) { + warn("Failed to fetch events"); + return (errno); + } + if (status == MFI_STAT_NOT_FOUND) { + if (seq == start) + warnx("No matching events found"); + break; + } + if (status != MFI_STAT_OK) { + warnx("Error fetching events: %s", mfi_status(status)); + return (EIO); + } + + for (i = 0; i < list->count; i++) { + /* + * If this event is newer than 'stop_seq' then + * break out of the loop. Note that the log + * is a circular buffer so we have to handle + * the case that our stop point is earlier in + * the buffer than our start point. + */ + if (list->event[i].seq >= stop) { + if (start <= stop) + break; + else if (list->event[i].seq < start) + break; + } + mfi_decode_evt(fd, &list->event[i], verbose); + } + + /* + * XXX: If the event's seq # is the end of the buffer + * then this probably won't do the right thing. We + * need to know the size of the buffer somehow. + */ + seq = list->event[list->count - 1].seq + 1; + + } + + free(list); + close(fd); + + return (0); +} +MFI_COMMAND(show, events, show_events); diff --git a/usr.sbin/mfiutil/mfi_flash.c b/usr.sbin/mfiutil/mfi_flash.c new file mode 100644 index 00000000000..5dd93f14f0e --- /dev/null +++ b/usr.sbin/mfiutil/mfi_flash.c @@ -0,0 +1,199 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mfiutil.h" + +#define FLASH_BUF_SIZE (64 * 1024) + +int fw_name_width, fw_version_width, fw_date_width, fw_time_width; + +static void +scan_firmware(struct mfi_info_component *comp) +{ + int len; + + len = strlen(comp->name); + if (fw_name_width < len) + fw_name_width = len; + len = strlen(comp->version); + if (fw_version_width < len) + fw_version_width = len; + len = strlen(comp->build_date); + if (fw_date_width < len) + fw_date_width = len; + len = strlen(comp->build_time); + if (fw_time_width < len) + fw_time_width = len; +} + +static void +display_firmware(struct mfi_info_component *comp) +{ + + printf("%-*s %-*s %-*s %-*s\n", fw_name_width, comp->name, + fw_version_width, comp->version, fw_date_width, comp->build_date, + fw_time_width, comp->build_time); +} + +static void +display_pending_firmware(int fd) +{ + struct mfi_ctrl_info info; + struct mfi_info_component header; + u_int i; + + if (mfi_ctrl_get_info(fd, &info, NULL) < 0) { + warn("Failed to get controller info"); + return; + } + + printf("mfi%d Pending Firmware Images:\n", mfi_unit); + strcpy(header.name, "Name"); + strcpy(header.version, "Version"); + strcpy(header.build_date, "Date"); + strcpy(header.build_time, "Time"); + scan_firmware(&header); + if (info.pending_image_component_count > 8) + info.pending_image_component_count = 8; + for (i = 0; i < info.pending_image_component_count; i++) + scan_firmware(&info.pending_image_component[i]); + display_firmware(&header); + for (i = 0; i < info.pending_image_component_count; i++) + display_firmware(&info.pending_image_component[i]); +} + +static void +mbox_store_word(uint8_t *mbox, uint32_t val) +{ + + mbox[0] = val & 0xff; + mbox[1] = val >> 8 & 0xff; + mbox[2] = val >> 16 & 0xff; + mbox[3] = val >> 24; +} + +static int +flash_adapter(int ac, char **av) +{ + struct mfi_progress dummy; + off_t offset; + size_t nread; + char *buf; + struct stat sb; + int fd, flash; + uint8_t mbox[4], status; + + if (ac != 2) { + warnx("flash: Firmware file required"); + return (EINVAL); + } + + flash = open(av[1], O_RDONLY); + if (flash < 0) { + warn("flash: Failed to open %s", av[1]); + return (errno); + } + + if (fstat(flash, &sb) < 0) { + warn("fstat(%s)", av[1]); + return (errno); + } + if (sb.st_size % 1024 != 0 || sb.st_size > 0x7fffffff) { + warnx("Invalid flash file size"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + /* First, ask the firmware to allocate space for the flash file. */ + mbox_store_word(mbox, sb.st_size); + mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_OPEN, NULL, 0, mbox, 4, &status); + if (status != MFI_STAT_OK) { + warnx("Failed to alloc flash memory: %s", mfi_status(status)); + return (EIO); + } + + /* Upload the file 64k at a time. */ + buf = malloc(FLASH_BUF_SIZE); + offset = 0; + while (sb.st_size > 0) { + nread = read(flash, buf, FLASH_BUF_SIZE); + if (nread <= 0 || nread % 1024 != 0) { + warnx("Bad read from flash file"); + mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_CLOSE, NULL, 0, + NULL, 0, NULL); + return (ENXIO); + } + + mbox_store_word(mbox, offset); + mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_DOWNLOAD, buf, nread, + mbox, 4, &status); + if (status != MFI_STAT_OK) { + warnx("Flash download failed: %s", mfi_status(status)); + mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_CLOSE, NULL, 0, + NULL, 0, NULL); + return (ENXIO); + } + sb.st_size -= nread; + offset += nread; + } + close(flash); + + /* Kick off the flash. */ + printf("WARNING: Firmware flash in progress, do not reboot machine... "); + fflush(stdout); + mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_FLASH, &dummy, sizeof(dummy), + NULL, 0, &status); + if (status != MFI_STAT_OK) { + printf("failed:\n\t%s\n", mfi_status(status)); + return (ENXIO); + } + printf("finished\n"); + display_pending_firmware(fd); + + close(fd); + + return (0); +} +MFI_COMMAND(top, flash, flash_adapter); diff --git a/usr.sbin/mfiutil/mfi_patrol.c b/usr.sbin/mfiutil/mfi_patrol.c new file mode 100644 index 00000000000..b8da2ae4bb9 --- /dev/null +++ b/usr.sbin/mfiutil/mfi_patrol.c @@ -0,0 +1,305 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mfiutil.h" + +static char * +adapter_time(time_t now, uint32_t at_now, uint32_t at) +{ + time_t t; + + t = (now - at_now) + at; + return (ctime(&t)); +} + +static void +mfi_get_time(int fd, uint32_t *at) +{ + + if (mfi_dcmd_command(fd, MFI_DCMD_TIME_SECS_GET, at, sizeof(*at), NULL, + 0, NULL) < 0) { + warn("Couldn't fetch adapter time"); + at = 0; + } +} + +static int +patrol_get_props(int fd, struct mfi_pr_properties *prop) +{ + + if (mfi_dcmd_command(fd, MFI_DCMD_PR_GET_PROPERTIES, prop, + sizeof(*prop), NULL, 0, NULL) < 0) { + warn("Failed to get patrol read properties"); + return (-1); + } + return (0); +} + +static int +show_patrol(int ac, char **av) +{ + struct mfi_pr_properties prop; + struct mfi_pr_status status; + struct mfi_pd_list *list; + struct mfi_pd_info info; + char label[16]; + time_t now; + uint32_t at; + int fd; + u_int i; + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + time(&now); + mfi_get_time(fd, &at); + if (patrol_get_props(fd, &prop) < 0) + return (errno); + printf("Operation Mode: "); + switch (prop.op_mode) { + case MFI_PR_OPMODE_AUTO: + printf("auto\n"); + break; + case MFI_PR_OPMODE_MANUAL: + printf("manual\n"); + break; + case MFI_PR_OPMODE_DISABLED: + printf("disabled\n"); + break; + default: + printf("??? (%02x)\n", prop.op_mode); + break; + } + if (prop.op_mode == MFI_PR_OPMODE_AUTO) { + if (at != 0 && prop.next_exec) + printf(" Next Run Starts: %s", adapter_time(now, at, + prop.next_exec)); + if (prop.exec_freq == 0xffffffff) + printf(" Runs Execute Continuously\n"); + else if (prop.exec_freq != 0) + printf(" Runs Start Every %u seconds\n", + prop.exec_freq); + } + + if (mfi_dcmd_command(fd, MFI_DCMD_PR_GET_STATUS, &status, + sizeof(status), NULL, 0, NULL) < 0) { + warn("Failed to get patrol read properties"); + return (errno); + } + printf("Runs Completed: %u\n", status.num_iteration); + printf("Current State: "); + switch (status.state) { + case MFI_PR_STATE_STOPPED: + printf("stopped\n"); + break; + case MFI_PR_STATE_READY: + printf("ready\n"); + break; + case MFI_PR_STATE_ACTIVE: + printf("active\n"); + break; + case MFI_PR_STATE_ABORTED: + printf("aborted\n"); + break; + default: + printf("??? (%02x)\n", status.state); + break; + } + if (status.state == MFI_PR_STATE_ACTIVE) { + if (mfi_pd_get_list(fd, &list, NULL) < 0) { + warn("Failed to get drive list"); + return (errno); + } + + for (i = 0; i < list->count; i++) { + if (list->addr[i].scsi_dev_type != 0) + continue; + + if (mfi_pd_get_info(fd, list->addr[i].device_id, &info, + NULL) < 0) { + warn("Failed to fetch info for drive %u", + list->addr[i].device_id); + return (errno); + } + if (info.prog_info.active & MFI_PD_PROGRESS_PATROL) { + snprintf(label, sizeof(label), " Drive %u", + list->addr[i].device_id); + mfi_display_progress(label, + &info.prog_info.patrol); + } + } + } + + close(fd); + + return (0); +} +MFI_COMMAND(show, patrol, show_patrol); + +static int +start_patrol(int ac, char **av) +{ + int fd; + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_dcmd_command(fd, MFI_DCMD_PR_START, NULL, 0, NULL, 0, NULL) < + 0) { + warn("Failed to start patrol read"); + return (errno); + } + + close(fd); + + return (0); +} +MFI_COMMAND(start, patrol, start_patrol); + +static int +stop_patrol(int ac, char **av) +{ + int fd; + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_dcmd_command(fd, MFI_DCMD_PR_STOP, NULL, 0, NULL, 0, NULL) < + 0) { + warn("Failed to stop patrol read"); + return (errno); + } + + close(fd); + + return (0); +} +MFI_COMMAND(stop, patrol, stop_patrol); + +static int +patrol_config(int ac, char **av) +{ + struct mfi_pr_properties prop; + long val; + time_t now; + uint32_t at, next_exec, exec_freq; + char *cp; + uint8_t op_mode; + int fd; + + exec_freq = 0; /* GCC too stupid */ + next_exec = 0; + if (ac < 2) { + warnx("patrol: command required"); + return (EINVAL); + } + if (strcasecmp(av[1], "auto") == 0) { + op_mode = MFI_PR_OPMODE_AUTO; + if (ac > 2) { + if (strcasecmp(av[2], "continously") == 0) + exec_freq = 0xffffffff; + else { + val = strtol(av[2], &cp, 0); + if (*cp != '\0') { + warnx("patrol: Invalid interval %s", + av[2]); + return (EINVAL); + } + exec_freq = val; + } + } + if (ac > 3) { + val = strtol(av[3], &cp, 0); + if (*cp != '\0' || val < 0) { + warnx("patrol: Invalid start time %s", av[3]); + return (EINVAL); + } + next_exec = val; + } + } else if (strcasecmp(av[1], "manual") == 0) + op_mode = MFI_PR_OPMODE_MANUAL; + else if (strcasecmp(av[1], "disable") == 0) + op_mode = MFI_PR_OPMODE_DISABLED; + else { + warnx("patrol: Invalid command %s", av[1]); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (patrol_get_props(fd, &prop) < 0) + return (errno); + prop.op_mode = op_mode; + if (op_mode == MFI_PR_OPMODE_AUTO) { + if (ac > 2) + prop.exec_freq = exec_freq; + if (ac > 3) { + time(&now); + mfi_get_time(fd, &at); + if (at == 0) + return (ENXIO); + prop.next_exec = at + next_exec; + printf("Starting next patrol read at %s", + adapter_time(now, at, prop.next_exec)); + } + } + if (mfi_dcmd_command(fd, MFI_DCMD_PR_SET_PROPERTIES, &prop, + sizeof(prop), NULL, 0, NULL) < 0) { + warn("Failed to set patrol read properties"); + return (errno); + } + + close(fd); + + return (0); +} +MFI_COMMAND(top, patrol, patrol_config); diff --git a/usr.sbin/mfiutil/mfi_show.c b/usr.sbin/mfiutil/mfi_show.c new file mode 100644 index 00000000000..abd11107077 --- /dev/null +++ b/usr.sbin/mfiutil/mfi_show.c @@ -0,0 +1,560 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mfiutil.h" + +MFI_TABLE(top, show); + +static void +format_stripe(char *buf, size_t buflen, uint8_t stripe) +{ + + humanize_number(buf, buflen, (1 << stripe) * 512, "", HN_AUTOSCALE, + HN_B | HN_NOSPACE); +} + +static int +show_adapter(int ac, char **av) +{ + struct mfi_ctrl_info info; + char stripe[5]; + int fd, comma; + + if (ac != 1) { + warnx("show adapter: extra arguments"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_ctrl_get_info(fd, &info, NULL) < 0) { + warn("Failed to get controller info"); + return (errno); + } + printf("mfi%d Adapter:\n", mfi_unit); + printf(" Product Name: %.80s\n", info.product_name); + printf(" Serial Number: %.32s\n", info.serial_number); + if (info.package_version[0] != '\0') + printf(" Firmware: %s\n", info.package_version); + printf(" RAID Levels:"); +#ifdef DEBUG + printf(" (%#x)", info.raid_levels); +#endif + comma = 0; + if (info.raid_levels & MFI_INFO_RAID_0) { + printf(" JBOD, RAID0"); + comma = 1; + } + if (info.raid_levels & MFI_INFO_RAID_1) { + printf("%s RAID1", comma ? "," : ""); + comma = 1; + } + if (info.raid_levels & MFI_INFO_RAID_5) { + printf("%s RAID5", comma ? "," : ""); + comma = 1; + } + if (info.raid_levels & MFI_INFO_RAID_1E) { + printf("%s RAID1E", comma ? "," : ""); + comma = 1; + } + if (info.raid_levels & MFI_INFO_RAID_6) { + printf("%s RAID6", comma ? "," : ""); + comma = 1; + } + if ((info.raid_levels & (MFI_INFO_RAID_0 | MFI_INFO_RAID_1)) == + (MFI_INFO_RAID_0 | MFI_INFO_RAID_1)) { + printf("%s RAID10", comma ? "," : ""); + comma = 1; + } + if ((info.raid_levels & (MFI_INFO_RAID_0 | MFI_INFO_RAID_5)) == + (MFI_INFO_RAID_0 | MFI_INFO_RAID_5)) { + printf("%s RAID50", comma ? "," : ""); + comma = 1; + } + printf("\n"); + printf(" Battery Backup: "); + if (info.hw_present & MFI_INFO_HW_BBU) + printf("present\n"); + else + printf("not present\n"); + if (info.hw_present & MFI_INFO_HW_NVRAM) + printf(" NVRAM: %uK\n", info.nvram_size); + printf(" Onboard Memory: %uM\n", info.memory_size); + format_stripe(stripe, sizeof(stripe), info.stripe_sz_ops.min); + printf(" Minimum Stripe: %s\n", stripe); + format_stripe(stripe, sizeof(stripe), info.stripe_sz_ops.max); + printf(" Maximum Stripe: %s\n", stripe); + + close(fd); + + return (0); +} +MFI_COMMAND(show, adapter, show_adapter); + +static int +show_battery(int ac, char **av) +{ + struct mfi_bbu_capacity_info cap; + struct mfi_bbu_design_info design; + uint8_t status; + int fd; + + if (ac != 1) { + warnx("show battery: extra arguments"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_dcmd_command(fd, MFI_DCMD_BBU_GET_CAPACITY_INFO, &cap, + sizeof(cap), NULL, 0, &status) < 0) { + if (status == MFI_STAT_NO_HW_PRESENT) { + printf("mfi%d: No battery present\n", mfi_unit); + return (0); + } + warn("Failed to get capacity info"); + return (errno); + } + + if (mfi_dcmd_command(fd, MFI_DCMD_BBU_GET_DESIGN_INFO, &design, + sizeof(design), NULL, 0, NULL) < 0) { + warn("Failed to get design info"); + return (errno); + } + + printf("mfi%d: Battery State:\n", mfi_unit); + printf(" Manufacture Date: %d/%d/%d\n", design.mfg_date >> 5 & 0x0f, + design.mfg_date & 0x1f, design.mfg_date >> 9 & 0xffff); + printf(" Serial Number: %d\n", design.serial_number); + printf(" Manufacturer: %s\n", design.mfg_name); + printf(" Model: %s\n", design.device_name); + printf(" Chemistry: %s\n", design.device_chemistry); + printf(" Design Capacity: %d mAh\n", design.design_capacity); + printf(" Design Voltage: %d mV\n", design.design_voltage); + printf(" Current Charge: %d%%\n", cap.relative_charge); + + close(fd); + + return (0); +} +MFI_COMMAND(show, battery, show_battery); + +static void +print_ld(struct mfi_ld_info *info, int state_len) +{ + struct mfi_ld_params *params = &info->ld_config.params; + const char *level; + char size[6], stripe[5]; + + humanize_number(size, sizeof(size), info->size * 512, + "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); + format_stripe(stripe, sizeof(stripe), + info->ld_config.params.stripe_size); + level = mfi_raid_level(params->primary_raid_level, + params->secondary_raid_level); + if (state_len > 0) + printf("(%6s) %-8s %6s %-*s", size, level, stripe, state_len, + mfi_ldstate(params->state)); + else + printf("(%s) %s %s %s", size, level, stripe, + mfi_ldstate(params->state)); +} + +static void +print_pd(struct mfi_pd_info *info, int state_len, int location) +{ + const char *s; + char buf[6]; + + humanize_number(buf, sizeof(buf), info->raw_size * 512, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE |HN_DECIMAL); + printf("(%6s) ", buf); + if (state_len > 0) + printf("%-*s", state_len, mfi_pdstate(info->fw_state)); + else + printf("%s", mfi_pdstate(info->fw_state)); + s = mfi_pd_inq_string(info); + if (s != NULL) + printf(" %s", s); + if (!location) + return; + if (info->encl_device_id == 0xffff) + printf(" slot %d", info->slot_number); + else if (info->encl_device_id == info->ref.v.device_id) + printf(" enclosure %d", info->encl_index); + else + printf(" enclosure %d, slot %d", info->encl_index, + info->slot_number); +} + +static int +show_config(int ac, char **av) +{ + struct mfi_config_data *config; + struct mfi_array *ar; + struct mfi_ld_config *ld; + struct mfi_spare *sp; + struct mfi_ld_info linfo; + struct mfi_pd_info pinfo; + uint16_t device_id; + char *p; + int fd, i, j; + + if (ac != 1) { + warnx("show config: extra arguments"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + /* Get the config from the controller. */ + if (mfi_config_read(fd, &config) < 0) { + warn("Failed to get config"); + return (errno); + } + + /* Dump out the configuration. */ + printf("mfi%d Configuration: %d arrays, %d volumes, %d spares\n", + mfi_unit, config->array_count, config->log_drv_count, + config->spares_count); + p = (char *)config->array; + + for (i = 0; i < config->array_count; i++) { + ar = (struct mfi_array *)p; + printf(" array %u of %u drives:\n", ar->array_ref, + ar->num_drives); + for (j = 0; j < ar->num_drives; j++) { + device_id = ar->pd[j].ref.v.device_id; + if (device_id == 0xffff) + printf(" drive MISSING\n"); + else { + printf(" drive %u ", device_id); + if (mfi_pd_get_info(fd, device_id, &pinfo, + NULL) < 0) + printf("%s", + mfi_pdstate(ar->pd[j].fw_state)); + else + print_pd(&pinfo, -1, 1); + printf("\n"); + } + } + p += config->array_size; + } + + for (i = 0; i < config->log_drv_count; i++) { + ld = (struct mfi_ld_config *)p; + printf(" volume %s ", + mfi_volume_name(fd, ld->properties.ld.v.target_id)); + if (mfi_ld_get_info(fd, ld->properties.ld.v.target_id, &linfo, + NULL) < 0) { + printf("%s %s", + mfi_raid_level(ld->params.primary_raid_level, + ld->params.secondary_raid_level), + mfi_ldstate(ld->params.state)); + } else + print_ld(&linfo, -1); + if (ld->properties.name[0] != '\0') + printf(" <%s>", ld->properties.name); + printf(" spans:\n"); + for (j = 0; j < ld->params.span_depth; j++) + printf(" array %u\n", ld->span[j].array_ref); + p += config->log_drv_size; + } + + for (i = 0; i < config->spares_count; i++) { + sp = (struct mfi_spare *)p; + printf(" %s spare %u ", + sp->spare_type & MFI_SPARE_DEDICATED ? "dedicated" : + "global", sp->ref.v.device_id); + if (mfi_pd_get_info(fd, sp->ref.v.device_id, &pinfo, NULL) < 0) + printf("%s", mfi_pdstate(MFI_PD_STATE_HOT_SPARE)); + else + print_pd(&pinfo, -1, 1); + if (sp->spare_type & MFI_SPARE_DEDICATED) { + printf(" backs:\n"); + for (j = 0; j < sp->array_count; j++) + printf(" array %u\n", sp->array_ref[j]); + } else + printf("\n"); + p += config->spares_size; + } + close(fd); + + return (0); +} +MFI_COMMAND(show, config, show_config); + +static int +show_volumes(int ac, char **av) +{ + struct mfi_ld_list list; + struct mfi_ld_info info; + u_int i, len, state_len; + int fd; + + if (ac != 1) { + warnx("show volumes: extra arguments"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + /* Get the logical drive list from the controller. */ + if (mfi_ld_get_list(fd, &list, NULL) < 0) { + warn("Failed to get volume list"); + return (errno); + } + + /* List the volumes. */ + printf("mfi%d Volumes:\n", mfi_unit); + state_len = strlen("State"); + for (i = 0; i < list.ld_count; i++) { + len = strlen(mfi_ldstate(list.ld_list[i].state)); + if (len > state_len) + state_len = len; + } + printf(" Id Size Level Stripe "); + len = state_len - strlen("State"); + for (i = 0; i < (len + 1) / 2; i++) + printf(" "); + printf("State"); + for (i = 0; i < len / 2; i++) + printf(" "); + printf(" Cache Name\n"); + for (i = 0; i < list.ld_count; i++) { + if (mfi_ld_get_info(fd, list.ld_list[i].ld.v.target_id, &info, + NULL) < 0) { + warn("Failed to get info for volume %d", + list.ld_list[i].ld.v.target_id); + return (errno); + } + printf("%6s ", + mfi_volume_name(fd, list.ld_list[i].ld.v.target_id)); + print_ld(&info, state_len); + switch (info.ld_config.properties.current_cache_policy & + (MR_LD_CACHE_ALLOW_WRITE_CACHE | + MR_LD_CACHE_ALLOW_READ_CACHE)) { + case 0: + printf(" Disabled"); + break; + case MR_LD_CACHE_ALLOW_READ_CACHE: + printf(" Reads "); + break; + case MR_LD_CACHE_ALLOW_WRITE_CACHE: + printf(" Writes "); + break; + case MR_LD_CACHE_ALLOW_WRITE_CACHE | + MR_LD_CACHE_ALLOW_READ_CACHE: + printf(" Enabled "); + break; + } + if (info.ld_config.properties.name[0] != '\0') + printf(" <%s>", info.ld_config.properties.name); + printf("\n"); + } + close(fd); + + return (0); +} +MFI_COMMAND(show, volumes, show_volumes); + +static int +show_drives(int ac, char **av) +{ + struct mfi_pd_list *list; + struct mfi_pd_info info; + u_int i, len, state_len; + int fd; + + if (ac != 1) { + warnx("show drives: extra arguments"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_pd_get_list(fd, &list, NULL) < 0) { + warn("Failed to get drive list"); + return (errno); + } + + /* Walk the list of drives to determine width of state column. */ + state_len = 0; + for (i = 0; i < list->count; i++) { + if (list->addr[i].scsi_dev_type != 0) + continue; + + if (mfi_pd_get_info(fd, list->addr[i].device_id, &info, + NULL) < 0) { + warn("Failed to fetch info for drive %u", + list->addr[i].device_id); + return (errno); + } + len = strlen(mfi_pdstate(info.fw_state)); + if (len > state_len) + state_len = len; + } + + /* List the drives. */ + printf("mfi%d Physical Drives:\n", mfi_unit); + for (i = 0; i < list->count; i++) { + + /* Skip non-hard disks. */ + if (list->addr[i].scsi_dev_type != 0) + continue; + + /* Fetch details for this drive. */ + if (mfi_pd_get_info(fd, list->addr[i].device_id, &info, + NULL) < 0) { + warn("Failed to fetch info for drive %u", + list->addr[i].device_id); + return (errno); + } + + print_pd(&info, state_len, 1); + printf("\n"); + } + close(fd); + + return (0); +} +MFI_COMMAND(show, drives, show_drives); + +int fw_name_width, fw_version_width, fw_date_width, fw_time_width; + +static void +scan_firmware(struct mfi_info_component *comp) +{ + int len; + + len = strlen(comp->name); + if (fw_name_width < len) + fw_name_width = len; + len = strlen(comp->version); + if (fw_version_width < len) + fw_version_width = len; + len = strlen(comp->build_date); + if (fw_date_width < len) + fw_date_width = len; + len = strlen(comp->build_time); + if (fw_time_width < len) + fw_time_width = len; +} + +static void +display_firmware(struct mfi_info_component *comp, const char *tag) +{ + + printf("%-*s %-*s %-*s %-*s %s\n", fw_name_width, comp->name, + fw_version_width, comp->version, fw_date_width, comp->build_date, + fw_time_width, comp->build_time, tag); +} + +static int +show_firmware(int ac, char **av) +{ + struct mfi_ctrl_info info; + struct mfi_info_component header; + int fd; + u_int i; + + if (ac != 1) { + warnx("show drives: extra arguments"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_ctrl_get_info(fd, &info, NULL) < 0) { + warn("Failed to get controller info"); + return (errno); + } + + if (info.package_version[0] != '\0') + printf("mfi%d Firmware Package Version: %s\n", mfi_unit, + info.package_version); + printf("mfi%d Firmware Images:\n", mfi_unit); + strcpy(header.name, "Name"); + strcpy(header.version, "Version"); + strcpy(header.build_date, "Date"); + strcpy(header.build_time, "Time"); + scan_firmware(&header); + if (info.image_component_count > 8) + info.image_component_count = 8; + for (i = 0; i < info.image_component_count; i++) + scan_firmware(&info.image_component[i]); + if (info.pending_image_component_count > 8) + info.pending_image_component_count = 8; + for (i = 0; i < info.pending_image_component_count; i++) + scan_firmware(&info.pending_image_component[i]); + display_firmware(&header, "Status"); + for (i = 0; i < info.image_component_count; i++) + display_firmware(&info.image_component[i], "active"); + for (i = 0; i < info.pending_image_component_count; i++) + display_firmware(&info.pending_image_component[i], "pending"); + + close(fd); + + return (0); +} +MFI_COMMAND(show, firmware, show_firmware); diff --git a/usr.sbin/mfiutil/mfi_volume.c b/usr.sbin/mfiutil/mfi_volume.c new file mode 100644 index 00000000000..b3f4a7656c3 --- /dev/null +++ b/usr.sbin/mfiutil/mfi_volume.c @@ -0,0 +1,412 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mfiutil.h" + +MFI_TABLE(top, volume); + +const char * +mfi_ldstate(enum mfi_ld_state state) +{ + static char buf[16]; + + switch (state) { + case MFI_LD_STATE_OFFLINE: + return ("OFFLINE"); + case MFI_LD_STATE_PARTIALLY_DEGRADED: + return ("PARTIALLY DEGRADED"); + case MFI_LD_STATE_DEGRADED: + return ("DEGRADED"); + case MFI_LD_STATE_OPTIMAL: + return ("OPTIMAL"); + default: + sprintf(buf, "LSTATE 0x%02x", state); + return (buf); + } +} + +void +mbox_store_ldref(uint8_t *mbox, union mfi_ld_ref *ref) +{ + + mbox[0] = ref->v.target_id; + mbox[1] = ref->v.reserved; + mbox[2] = ref->v.seq & 0xff; + mbox[3] = ref->v.seq >> 8; +} + +int +mfi_ld_get_list(int fd, struct mfi_ld_list *list, uint8_t *statusp) +{ + + return (mfi_dcmd_command(fd, MFI_DCMD_LD_GET_LIST, list, + sizeof(struct mfi_ld_list), NULL, 0, statusp)); +} + +int +mfi_ld_get_info(int fd, uint8_t target_id, struct mfi_ld_info *info, + uint8_t *statusp) +{ + uint8_t mbox[1]; + + mbox[0] = target_id; + return (mfi_dcmd_command(fd, MFI_DCMD_LD_GET_INFO, info, + sizeof(struct mfi_ld_info), mbox, 1, statusp)); +} + +static int +mfi_ld_get_props(int fd, uint8_t target_id, struct mfi_ld_props *props) +{ + uint8_t mbox[1]; + + mbox[0] = target_id; + return (mfi_dcmd_command(fd, MFI_DCMD_LD_GET_PROP, props, + sizeof(struct mfi_ld_props), mbox, 1, NULL)); +} + +static int +mfi_ld_set_props(int fd, struct mfi_ld_props *props) +{ + uint8_t mbox[4]; + + mbox_store_ldref(mbox, &props->ld); + return (mfi_dcmd_command(fd, MFI_DCMD_LD_SET_PROP, props, + sizeof(struct mfi_ld_props), mbox, 4, NULL)); +} + +static int +update_cache_policy(int fd, struct mfi_ld_props *props, uint8_t new_policy, + uint8_t mask) +{ + uint8_t changes, policy; + + policy = (props->default_cache_policy & ~mask) | new_policy; + if (policy == props->default_cache_policy) + return (0); + changes = policy ^ props->default_cache_policy; + if (changes & MR_LD_CACHE_ALLOW_WRITE_CACHE) + printf("%s caching of I/O writes\n", + policy & MR_LD_CACHE_ALLOW_WRITE_CACHE ? "Enabling" : + "Disabling"); + if (changes & MR_LD_CACHE_ALLOW_READ_CACHE) + printf("%s caching of I/O reads\n", + policy & MR_LD_CACHE_ALLOW_READ_CACHE ? "Enabling" : + "Disabling"); + if (changes & MR_LD_CACHE_WRITE_BACK) + printf("Setting write cache policy to %s\n", + policy & MR_LD_CACHE_WRITE_BACK ? "write-back" : + "write-through"); + if (changes & (MR_LD_CACHE_READ_AHEAD | MR_LD_CACHE_READ_ADAPTIVE)) + printf("Setting read ahead policy to %s\n", + policy & MR_LD_CACHE_READ_AHEAD ? + (policy & MR_LD_CACHE_READ_ADAPTIVE ? + "adaptive" : "always") : "none"); + + props->default_cache_policy = policy; + if (mfi_ld_set_props(fd, props) < 0) { + warn("Failed to set volume properties"); + return (errno); + } + return (0); +} + +static int +volume_cache(int ac, char **av) +{ + struct mfi_ld_props props; + int error, fd; + uint8_t target_id, policy; + + if (ac < 2) { + warnx("cache: volume required"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_lookup_volume(fd, av[1], &target_id) < 0) { + warn("Invalid volume: %s", av[1]); + return (errno); + } + + if (mfi_ld_get_props(fd, target_id, &props) < 0) { + warn("Failed to fetch volume properties"); + return (errno); + } + + if (ac == 2) { + printf("mfi%u volume %s cache settings:\n", mfi_unit, + mfi_volume_name(fd, target_id)); + printf(" I/O caching: "); + switch (props.default_cache_policy & + (MR_LD_CACHE_ALLOW_WRITE_CACHE | + MR_LD_CACHE_ALLOW_READ_CACHE)) { + case 0: + printf("disabled\n"); + break; + case MR_LD_CACHE_ALLOW_WRITE_CACHE: + printf("writes\n"); + break; + case MR_LD_CACHE_ALLOW_READ_CACHE: + printf("reads\n"); + break; + case MR_LD_CACHE_ALLOW_WRITE_CACHE | + MR_LD_CACHE_ALLOW_READ_CACHE: + printf("writes and reads\n"); + break; + } + printf(" write caching: %s\n", + props.default_cache_policy & MR_LD_CACHE_WRITE_BACK ? + "write-back" : "write-through"); + printf(" read ahead: %s\n", + props.default_cache_policy & MR_LD_CACHE_READ_AHEAD ? + (props.default_cache_policy & MR_LD_CACHE_READ_ADAPTIVE ? + "adaptive" : "always") : "none"); + printf("drive write cache: "); + switch (props.disk_cache_policy) { + case MR_PD_CACHE_UNCHANGED: + printf("default\n"); + break; + case MR_PD_CACHE_ENABLE: + printf("enabled\n"); + break; + case MR_PD_CACHE_DISABLE: + printf("disabled\n"); + break; + default: + printf("??? %d\n", props.disk_cache_policy); + break; + } + if (props.default_cache_policy != props.current_cache_policy) + printf("Cache Disabled Due to Dead Battery\n"); + error = 0; + } else { + if (strcmp(av[2], "all") == 0 || strcmp(av[2], "enable") == 0) + error = update_cache_policy(fd, &props, + MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE, + MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE); + else if (strcmp(av[2], "none") == 0 || + strcmp(av[2], "disable") == 0) + error = update_cache_policy(fd, &props, 0, + MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE); + else if (strcmp(av[2], "reads") == 0) + error = update_cache_policy(fd, &props, + MR_LD_CACHE_ALLOW_READ_CACHE, + MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE); + else if (strcmp(av[2], "writes") == 0) + error = update_cache_policy(fd, &props, + MR_LD_CACHE_ALLOW_WRITE_CACHE, + MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE); + else if (strcmp(av[2], "write-back") == 0) + error = update_cache_policy(fd, &props, + MR_LD_CACHE_WRITE_BACK, + MR_LD_CACHE_WRITE_BACK); + else if (strcmp(av[2], "write-through") == 0) + error = update_cache_policy(fd, &props, 0, + MR_LD_CACHE_WRITE_BACK); + else if (strcmp(av[2], "read-ahead") == 0) { + if (ac < 4) { + warnx("cache: read-ahead setting required"); + return (EINVAL); + } + if (strcmp(av[3], "none") == 0) + policy = 0; + else if (strcmp(av[3], "always") == 0) + policy = MR_LD_CACHE_READ_AHEAD; + else if (strcmp(av[3], "adaptive") == 0) + policy = MR_LD_CACHE_READ_AHEAD | + MR_LD_CACHE_READ_ADAPTIVE; + else { + warnx("cache: invalid read-ahead setting"); + return (EINVAL); + } + error = update_cache_policy(fd, &props, policy, + MR_LD_CACHE_READ_AHEAD | + MR_LD_CACHE_READ_ADAPTIVE); + } else if (strcmp(av[2], "write-cache") == 0) { + if (ac < 4) { + warnx("cache: write-cache setting required"); + return (EINVAL); + } + if (strcmp(av[3], "enable") == 0) + policy = MR_PD_CACHE_ENABLE; + else if (strcmp(av[3], "disable") == 0) + policy = MR_PD_CACHE_DISABLE; + else if (strcmp(av[3], "default") == 0) + policy = MR_PD_CACHE_UNCHANGED; + else { + warnx("cache: invalid write-cache setting"); + return (EINVAL); + } + error = 0; + if (policy != props.disk_cache_policy) { + switch (policy) { + case MR_PD_CACHE_ENABLE: + printf("Enabling write-cache on physical drives\n"); + break; + case MR_PD_CACHE_DISABLE: + printf("Disabling write-cache on physical drives\n"); + break; + case MR_PD_CACHE_UNCHANGED: + printf("Using default write-cache setting on physical drives\n"); + break; + } + props.disk_cache_policy = policy; + if (mfi_ld_set_props(fd, &props) < 0) { + warn("Failed to set volume properties"); + error = errno; + } + } + } else { + warnx("cache: Invalid command"); + return (EINVAL); + } + } + close(fd); + + return (error); +} +MFI_COMMAND(top, cache, volume_cache); + +static int +volume_name(int ac, char **av) +{ + struct mfi_ld_props props; + int fd; + uint8_t target_id; + + if (ac != 3) { + warnx("name: volume and name required"); + return (EINVAL); + } + + if (strlen(av[2]) >= sizeof(props.name)) { + warnx("name: new name is too long"); + return (ENOSPC); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_lookup_volume(fd, av[1], &target_id) < 0) { + warn("Invalid volume: %s", av[1]); + return (errno); + } + + if (mfi_ld_get_props(fd, target_id, &props) < 0) { + warn("Failed to fetch volume properties"); + return (errno); + } + + printf("mfi%u volume %s name changed from \"%s\" to \"%s\"\n", mfi_unit, + mfi_volume_name(fd, target_id), props.name, av[2]); + bzero(props.name, sizeof(props.name)); + strcpy(props.name, av[2]); + if (mfi_ld_set_props(fd, &props) < 0) { + warn("Failed to set volume properties"); + return (errno); + } + + close(fd); + + return (0); +} +MFI_COMMAND(top, name, volume_name); + +static int +volume_progress(int ac, char **av) +{ + struct mfi_ld_info info; + int fd; + uint8_t target_id; + + if (ac != 2) { + warnx("volume progress: %s", ac > 2 ? "extra arguments" : + "volume required"); + return (EINVAL); + } + + fd = mfi_open(mfi_unit); + if (fd < 0) { + warn("mfi_open"); + return (errno); + } + + if (mfi_lookup_volume(fd, av[1], &target_id) < 0) { + warn("Invalid volume: %s", av[1]); + return (errno); + } + + /* Get the info for this drive. */ + if (mfi_ld_get_info(fd, target_id, &info, NULL) < 0) { + warn("Failed to fetch info for volume %s", + mfi_volume_name(fd, target_id)); + return (errno); + } + + /* Display any of the active events. */ + if (info.progress.active & MFI_LD_PROGRESS_CC) + mfi_display_progress("Consistency Check", &info.progress.cc); + if (info.progress.active & MFI_LD_PROGRESS_BGI) + mfi_display_progress("Background Init", &info.progress.bgi); + if (info.progress.active & MFI_LD_PROGRESS_FGI) + mfi_display_progress("Foreground Init", &info.progress.fgi); + if (info.progress.active & MFI_LD_PROGRESS_RECON) + mfi_display_progress("Reconstruction", &info.progress.recon); + if ((info.progress.active & (MFI_LD_PROGRESS_CC | MFI_LD_PROGRESS_BGI | + MFI_LD_PROGRESS_FGI | MFI_LD_PROGRESS_RECON)) == 0) + printf("No activity in progress for volume %s.\n", + mfi_volume_name(fd, target_id)); + close(fd); + + return (0); +} +MFI_COMMAND(volume, progress, volume_progress); diff --git a/usr.sbin/mfiutil/mfiutil.1 b/usr.sbin/mfiutil/mfiutil.1 new file mode 100644 index 00000000000..d7860ab06dd --- /dev/null +++ b/usr.sbin/mfiutil/mfiutil.1 @@ -0,0 +1,574 @@ +.\" Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 17, 2008 +.Dt MFIUTIL 1 +.Os +.Sh NAME +.Nm mfiutil +.Nd Utility for managing LSI MegaRAID SAS controllers +.Sh SYNOPSIS +.Nm +.Cm version +.Nm +.Op Fl u Ar unit +.Cm show adapter +.Nm +.Op Fl u Ar unit +.Cm show battery +.Nm +.Op Fl u Ar unit +.Cm show config +.Nm +.Op Fl u Ar unit +.Cm show drives +.Nm +.Op Fl u Ar unit +.Cm show events +.Op Fl c Ar class +.Op Fl l Ar locale +.Op Fl n Ar count +.Op Fl v +.Op Ar start Op Ar stop +.Nm +.Op Fl u Ar unit +.Cm show firmware +.Nm +.Op Fl u Ar unit +.Cm show logstate +.Nm +.Op Fl u Ar unit +.Cm show patrol +.Nm +.Op Fl u Ar unit +.Cm show volumes +.Nm +.Op Fl u Ar unit +.Cm fail Ar drive +.Nm +.Op Fl u Ar unit +.Cm good Ar drive +.Nm +.Op Fl u Ar unit +.Cm rebuild Ar drive +.Nm +.Op Fl u Ar unit +.Cm drive progress Ar drive +.Nm +.Op Fl u Ar unit +.Cm drive clear Ar drive Brq "start | stop" +.Nm +.Op Fl u Ar unit +.Cm start rebuild Ar drive +.Nm +.Op Fl u Ar unit +.Cm abort rebuild Ar drive +.Nm +.Op Fl u Ar unit +.Cm locate Ar drive Brq "on | off" +.Nm +.Op Fl u Ar unit +.Cm cache Ar volume Op Ar setting Op Ar value +.Nm +.Op Fl u Ar unit +.Cm name Ar volume Ar name +.Nm +.Op Fl u Ar unit +.Cm volume progress Ar volume +.Nm +.Op Fl u Ar unit +.Cm clear +.Nm +.Op Fl u Ar unit +.Cm create Ar type +.Op Fl v +.Op Fl s Ar stripe_size +.Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Op Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Nm +.Op Fl u Ar unit +.Cm delete Ar volume +.Nm +.Op Fl u Ar unit +.Cm add Ar drive Op Ar volume +.Nm +.Op Fl u Ar unit +.Cm remove Ar drive +.Nm +.Op Fl u Ar unit +.Cm start patrol +.Nm +.Op Fl u Ar unit +.Cm stop patrol +.Nm +.Op Fl u Ar unit +.Cm patrol Ar command Op Ar interval Op Ar start +.Nm +.Op Fl u Ar unit +.Cm flash Ar file +.Sh DESCRIPTION +The +.Nm +utility can be used to display or modify various parameters on LSI +MegaRAID SAS RAID controllers. +Each invocation of +.Nm +consists of zero or more global options followed by a command. +Commands may support additional optional or required arguments after the +command. +.Pp +Currently one global option is supported: +.Bl -tag -width indent +.It Fl u Ar unit +.Ar unit +specifies the unit of the controller to work with. +If no unit is specified, +then unit 0 is used. +.El +.Pp +Volumes may be specified in two forms. +First, +a volume may be identified by its target ID. +Second, +on the volume may be specified by the corresponding +.Em mfidX +device, +such as +.Em mfid0 . +Note that this second method only works on OS versions +.Dv 6.2-YAHOO-20070510 +and later. +.Pp +Drives may be specified in two forms. +First, +a drive may be identified by its device ID. +The device ID for configured drives can be found in +.Cm show config . +Second, +a drive may be identified by its location as +.Sm off +.Op E Ar xx Ns \&: +.Li S Ns Ar yy +.Sm on +where +.Ar xx +is the enclosure +and +.Ar yy +is the slot for each drive as displayed in +.Cm show drives . +.Pp +The +.Nm +utility supports several different groups of commands. +The first group of commands provide information about the controller, +the volumes it manages, and the drives it controls. +The second group of commands are used to manage the physical drives +attached to the controller. +The third group of commands are used to manage the logical volumes +managed by the controller. +The fourth group of commands are used to manage the drive configuration for +the controller. +The fifth group of commands are used to manage controller-wide operations. +.Pp +The informational commands include: +.Bl -tag -width indent +.It Cm version +Displays the version of +.Nm . +.It Cm show adapter +Displays information about the RAID controller such as the model number. +.It Cm show battery +Displays information about the battery from the battery backup unit. +.It Cm show config +Displays the volume and drive configuration for the controller. +Each array is listed along with the physical drives the array is built from. +Each volume is listed along with the arrays that the volume spans. +If any hot spare drives are configured, then they are listed as well. +.It Cm show drives +Lists all of the physical drives attached to the controller. +.It Xo Cm show events +.Op Fl c Ar class +.Op Fl l Ar locale +.Op Fl n Ar count +.Op Fl v +.Op Ar start Op Ar stop +.Xc +Display entries from the controller's event log. +The controller maintains a circular buffer of events. +Each event is tagged with a class and locale. +.Pp +The +.Ar class +parameter limits the output to entries at the specified class or higher. +The default class is +.Dq warn . +The available classes from lowest priority to highest are: +.Bl -tag -width -indent +.It Cm debug +Debug messages. +.It Cm progress +Periodic progress updates for long-running operations such as background +initializations, array rebuilds, or patrol reads. +.It Cm info +Informational messages such as drive insertions and volume creations. +.It Cm warn +Indicates that some component may be close to failing. +.It Cm crit +A component has failed, but no data is lost. +For example, a volume becoming degraded due to a drive failure. +.It Cm fatal +A component has failed resulting in data loss. +.It Cm dead +The controller itself has died. +.El +.Pp +The +.Ar locale +parameter limits the output to entries for the specified part of the controller. +The default locale is +.Dq all . +The available locales are +.Dq volume , +.Dq drive , +.Dq enclousure , +.Dq battery , +.Dq sas , +.Dq controller , +.Dq config , +.Dq cluster , +and +.Dq all . +.Pp +The +.Ar count +parameter is a debugging aid that specifies the number of events to fetch from +the controller for each low-level request. +The default is 15 events. +.Pp +By default, matching event log entries from the previous shutdown up to the +present are displayed. This range can be adjusted via the +.Ar start +and +.Ar stop +parameters. +Each of these parameters can either be specified as a log entry number or as +one of the following aliases: +.Bl -tag -width -indent +.It Cm newest +The newest entry in the event log. +.It Cm oldest +The oldest entry in the event log. +.It Cm clear +The first entry since the event log was cleared. +.It Cm shutdown +The entry in the event log corresponding to the last time the controller was +cleanly shut down. +.It Cm boot +The entry in the event log corresponding to the most recent boot. +.El +.It Cm show firmware +Lists all of the firmware images present on the controller. +.It Cm show logstate +Display the various sequence numbers associated with the event log. +.It Cm show patrol +Display the status of the controller's patrol read operation. +.It Cm show volumes +Lists all of the logical volumes managed by the controller. +.El +.Pp +The physical drive management commands include: +.Bl -tag -width indent +.It Cm fail Ar drive +Mark +.Ar drive +as failed. +.Ar Drive +must be an online drive that is part of an array. +.It Cm good Ar drive +Mark +.Ar drive +as an unconfigured good drive. +.Ar Drive +must not be part of an existing array. +.It Cm rebuild Ar drive +Mark a failed +.Ar drive +that is still part of an array as a good drive suitable for a rebuild. +The firmware should kick off an array rebuild on its own if a failed drive +is marked as a rebuild drive. +.It Cm drive progress Ar drive +Report the current progress and estimated completion time of drive operations +such as rebuilds or patrol reads. +.It Cm drive clear Ar drive Brq "start | stop" +Start or stop the writing of all 0x00 characters to a drive. +.It Cm start rebuild Ar drive +Manually start a rebuild on +.Ar drive . +.It Cm abort rebuild Ar drive +Abort an in-progress rebuild operation on +.Ar drive . +It can be resumed with the +.Cm start rebuild +command. +.It Cm locate Ar drive Brq "on | off" +Change the state of the external LED associated with +.Ar drive . +.El +.Pp +The logical volume management commands include: +.Bl -tag -width indent +.It Cm cache Ar volume Op Ar setting Op Ar value +If no +.Ar setting +argument is supplied, then the current cache policy for +.Ar volume +is displayed; +otherwise, +the cache policy for +.Ar volume +is modified. +The optional +.Ar setting +argument can be one of the following values: +.Bl -tag -width indent +.It Cm enable +Enable caching for both read and write I/O operations. +.It Cm disable +Disable caching for both read and write I/O operations. +.It Cm reads +Enable caching only for read I/O operations. +.It Cm writes +Enable caching only for write I/O operations. +.It Cm write-back +Use write-back policy for cached writes. +.It Cm write-through +Use write-through policy for cached writes. +.It Cm read-ahead Op Ar value +Set the read ahead policy for cached reads. +The +.Ar value +argument can be set to either +.Dq none , +.Dq adaptive , +or +.Dq always . +.It Cm write-cache Op Ar value +Control the write caches on the physical drives backing +.Ar volume . +The +.Ar value +argument can be set to either +.Dq disable , +.Dq enable , +or +.Dq default . +.Pp +In general this setting should be left disabled to avoid data loss when the +physical drives lose power. +The battery backup of the RAID controller does not save data in the write +caches of the physical drives. +.El +.It Cm name Ar volume Ar name +Sets the name of +.Ar volume +to +.Ar name . +.It Cm volume progress Ar volume +Report the current progress and estimated completion time of volume operations +such as consistency checks and initializations. +.El +.Pp +The configuration commands include: +.Bl -tag -width indent +.It Cm clear +Delete the entire configuration including all volumes, arrays, and spares. +.It Xo Cm create Ar type +.Op Fl v +.Op Fl s Ar stripe_size +.Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Op Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Xc +Create a new volume. +The +.Ar type +specifies the type of volume to create. +Currently supported types include: +.Bl -tag -width indent +.It Cm jbod +Creates a RAID0 volume for each drive specified. +Each drive must be specified as a separate argument. +.It Cm raid0 +Creates one RAID0 volume spanning the drives listed in the single drive list. +.It Cm raid1 +Creates one RAID1 volume spanning the drives listed in the single drive list. +.It Cm raid5 +Creates one RAID5 volume spanning the drives listed in the single drive list. +.It Cm raid6 +Creates one RAID6 volume spanning the drives listed in the single drive list. +.It Cm raid10 +Creates one RAID10 volume spanning multiple RAID1 arrays. +The drives for each RAID1 array are specified as a single drive list. +.It Cm raid50 +Creates one RAID50 volume spanning multiple RAID5 arrays. +The drives for each RAID5 array are specified as a single drive list. +.It Cm raid60 +Creates one RAID60 volume spanning multiple RAID6 arrays. +The drives for each RAID6 array are specified as a single drive list. +.It Cm concat +Creates a single volume by concatenating all of the drives in the single drive +list. +.El +.Pp +.Sy Note: +Not all volume types are supported by all controllers. +.Pp +If the +.Fl v +flag is specified after +.Ar type , +then more verbose output will be enabled. +Currently this just provides notification as drives are added to arrays and +arrays to volumes when building the configuration. +.Pp +The +.Fl s +.Ar stripe_size +parameter allows the stripe size of the array to be set. +By default a stripe size of 64K is used. +Valid values are 512 through 1M, though the MFI firmware may reject some +values. +.It Cm delete Ar volume +Delete the volume +.Ar volume . +.It Cm add Ar drive Op Ar volume +Mark +.Ar drive +as a hot spare. +.Ar Drive +must be in the unconfigured good state. +If +.Ar volume +is specified, +then the hot spare will be dedicated to arrays backing that volume. +Otherwise, +.Ar drive +will be used as a global hot spare backing all arrays for this controller. +Note that +.Ar drive +must be as large as the smallest drive in all of the arrays it is going to +back. +.It Cm remove Ar drive +Remove the hot spare +.Ar drive +from service. +It will be placed in the unconfigured good state. +.El +.Pp +The controller management commands include: +.Bl -tag -width indent +.It Cm patrol Ar command Op Ar interval Op Ar start +Set the patrol read operation mode. +The +.Ar command +argument can be one of the following values: +.Bl -tag -width indent +.It Cm disable +Disable patrol reads. +.It Cm auto +Enable periodic patrol reads initiated by the firmware. +The optional +.Ar interval +argument specifies the interval in seconds between patrol reads. +If patrol reads should be run continously, +then +.Ar interval +should consist of the word +.Dq continuously . +The optional +.Ar start +argument specifies a non-negative, relative start time for the next patrol read. +If an interval or start time is not specified, +then the existing setting will be used. +.It Cm manual +Enable manual patrol reads that are only initiated by the user. +.El +.It Cm start patrol +Start a patrol read operation. +.It Cm stop patrol +Stop a currently running patrol read operation. +.It Cm flash Ar file +Updates the flash on the controller with the firmware stored in +.Ar file . +A reboot is required for the new firmware to take effect. +.El +.Sh EXAMPLES +Configure the cache for volume mfid0 to cache only writes: +.Pp +.Dl Nm Cm cache mfid0 writes +.Dl Nm Cm cache mfid0 write-back +.Pp +Create a RAID5 array spanning the first four disks in the second enclosure: +.Pp +.Dl Nm Cm create raid5 e1:s0,e1:s1,e1:s2,e1:s4 +.Pp +Configure the first three disks on a controller as JBOD: +.Pp +.Dl Nm Cm create jbod 0 1 2 +.Pp +Create a RAID10 volume that spans two arrays each of which contains two disks +from two different enclosures: +.Pp +.Dl Nm Cm create raid10 e1:s0,e1:s1 e2:s0,e2:s1 +.Pp +Add drive with the device ID of 4 as a global hot spare: +.Pp +.Dl Nm Cm add 4 +.Pp +Add the drive in slot 2 in the main chassis as a hot spare for volume mfid0: +.Pp +.Dl Nm Cm add s2 mfid0 +.Pp +Configure the adapter to run periodic patrol reads once a week with the first +patrol read starting in 5 minutes: +.Pp +.Dl Nm Cm patrol auto 604800 300 +.Pp +.Sh SEE ALSO +.Xr mfi 4 +.Sh BUGS +On 64-bit OS versions +.Dv 6.2-YAHOO-20070514 +and earlier, +the +.Xr mfi 4 +driver does not properly report firmware errors to 32-bit versions of +.Nm . +As a result, +some commands may fail even though they do not report any errors. diff --git a/usr.sbin/mfiutil/mfiutil.8 b/usr.sbin/mfiutil/mfiutil.8 new file mode 100644 index 00000000000..e6026d653d4 --- /dev/null +++ b/usr.sbin/mfiutil/mfiutil.8 @@ -0,0 +1,566 @@ +.\" Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" 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 August 16, 2009 +.Dt MFIUTIL 8 +.Os +.Sh NAME +.Nm mfiutil +.Nd Utility for managing LSI MegaRAID SAS controllers +.Sh SYNOPSIS +.Nm +.Cm version +.Nm +.Op Fl u Ar unit +.Cm show adapter +.Nm +.Op Fl u Ar unit +.Cm show battery +.Nm +.Op Fl u Ar unit +.Cm show config +.Nm +.Op Fl u Ar unit +.Cm show drives +.Nm +.Op Fl u Ar unit +.Cm show events +.Op Fl c Ar class +.Op Fl l Ar locale +.Op Fl n Ar count +.Op Fl v +.Op Ar start Op Ar stop +.Nm +.Op Fl u Ar unit +.Cm show firmware +.Nm +.Op Fl u Ar unit +.Cm show logstate +.Nm +.Op Fl u Ar unit +.Cm show patrol +.Nm +.Op Fl u Ar unit +.Cm show volumes +.Nm +.Op Fl u Ar unit +.Cm fail Ar drive +.Nm +.Op Fl u Ar unit +.Cm good Ar drive +.Nm +.Op Fl u Ar unit +.Cm rebuild Ar drive +.Nm +.Op Fl u Ar unit +.Cm drive progress Ar drive +.Nm +.Op Fl u Ar unit +.Cm drive clear Ar drive Brq "start | stop" +.Nm +.Op Fl u Ar unit +.Cm start rebuild Ar drive +.Nm +.Op Fl u Ar unit +.Cm abort rebuild Ar drive +.Nm +.Op Fl u Ar unit +.Cm locate Ar drive Brq "on | off" +.Nm +.Op Fl u Ar unit +.Cm cache Ar volume Op Ar setting Op Ar value +.Nm +.Op Fl u Ar unit +.Cm name Ar volume Ar name +.Nm +.Op Fl u Ar unit +.Cm volume progress Ar volume +.Nm +.Op Fl u Ar unit +.Cm clear +.Nm +.Op Fl u Ar unit +.Cm create Ar type +.Op Fl v +.Op Fl s Ar stripe_size +.Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Op Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Nm +.Op Fl u Ar unit +.Cm delete Ar volume +.Nm +.Op Fl u Ar unit +.Cm add Ar drive Op Ar volume +.Nm +.Op Fl u Ar unit +.Cm remove Ar drive +.Nm +.Op Fl u Ar unit +.Cm start patrol +.Nm +.Op Fl u Ar unit +.Cm stop patrol +.Nm +.Op Fl u Ar unit +.Cm patrol Ar command Op Ar interval Op Ar start +.Nm +.Op Fl u Ar unit +.Cm flash Ar file +.Sh DESCRIPTION +The +.Nm +utility can be used to display or modify various parameters on LSI +MegaRAID SAS RAID controllers. +Each invocation of +.Nm +consists of zero or more global options followed by a command. +Commands may support additional optional or required arguments after the +command. +.Pp +Currently one global option is supported: +.Bl -tag -width indent +.It Fl u Ar unit +.Ar unit +specifies the unit of the controller to work with. +If no unit is specified, +then unit 0 is used. +.El +.Pp +Volumes may be specified in two forms. +First, +a volume may be identified by its target ID. +Second, +on the volume may be specified by the corresponding +.Em mfidX +device, +such as +.Em mfid0 . +.Pp +Drives may be specified in two forms. +First, +a drive may be identified by its device ID. +The device ID for configured drives can be found in +.Cm show config . +Second, +a drive may be identified by its location as +.Sm off +.Op E Ar xx Ns \&: +.Li S Ns Ar yy +.Sm on +where +.Ar xx +is the enclosure +and +.Ar yy +is the slot for each drive as displayed in +.Cm show drives . +.Pp +The +.Nm +utility supports several different groups of commands. +The first group of commands provide information about the controller, +the volumes it manages, and the drives it controls. +The second group of commands are used to manage the physical drives +attached to the controller. +The third group of commands are used to manage the logical volumes +managed by the controller. +The fourth group of commands are used to manage the drive configuration for +the controller. +The fifth group of commands are used to manage controller-wide operations. +.Pp +The informational commands include: +.Bl -tag -width indent +.It Cm version +Displays the version of +.Nm . +.It Cm show adapter +Displays information about the RAID controller such as the model number. +.It Cm show battery +Displays information about the battery from the battery backup unit. +.It Cm show config +Displays the volume and drive configuration for the controller. +Each array is listed along with the physical drives the array is built from. +Each volume is listed along with the arrays that the volume spans. +If any hot spare drives are configured, then they are listed as well. +.It Cm show drives +Lists all of the physical drives attached to the controller. +.It Xo Cm show events +.Op Fl c Ar class +.Op Fl l Ar locale +.Op Fl n Ar count +.Op Fl v +.Op Ar start Op Ar stop +.Xc +Display entries from the controller's event log. +The controller maintains a circular buffer of events. +Each event is tagged with a class and locale. +.Pp +The +.Ar class +parameter limits the output to entries at the specified class or higher. +The default class is +.Dq warn . +The available classes from lowest priority to highest are: +.Bl -tag -width -indent +.It Cm debug +Debug messages. +.It Cm progress +Periodic progress updates for long-running operations such as background +initializations, array rebuilds, or patrol reads. +.It Cm info +Informational messages such as drive insertions and volume creations. +.It Cm warn +Indicates that some component may be close to failing. +.It Cm crit +A component has failed, but no data is lost. +For example, a volume becoming degraded due to a drive failure. +.It Cm fatal +A component has failed resulting in data loss. +.It Cm dead +The controller itself has died. +.El +.Pp +The +.Ar locale +parameter limits the output to entries for the specified part of the controller. +The default locale is +.Dq all . +The available locales are +.Dq volume , +.Dq drive , +.Dq enclousure , +.Dq battery , +.Dq sas , +.Dq controller , +.Dq config , +.Dq cluster , +and +.Dq all . +.Pp +The +.Ar count +parameter is a debugging aid that specifies the number of events to fetch from +the controller for each low-level request. +The default is 15 events. +.Pp +By default, matching event log entries from the previous shutdown up to the +present are displayed. This range can be adjusted via the +.Ar start +and +.Ar stop +parameters. +Each of these parameters can either be specified as a log entry number or as +one of the following aliases: +.Bl -tag -width -indent +.It Cm newest +The newest entry in the event log. +.It Cm oldest +The oldest entry in the event log. +.It Cm clear +The first entry since the event log was cleared. +.It Cm shutdown +The entry in the event log corresponding to the last time the controller was +cleanly shut down. +.It Cm boot +The entry in the event log corresponding to the most recent boot. +.El +.It Cm show firmware +Lists all of the firmware images present on the controller. +.It Cm show logstate +Display the various sequence numbers associated with the event log. +.It Cm show patrol +Display the status of the controller's patrol read operation. +.It Cm show volumes +Lists all of the logical volumes managed by the controller. +.El +.Pp +The physical drive management commands include: +.Bl -tag -width indent +.It Cm fail Ar drive +Mark +.Ar drive +as failed. +.Ar Drive +must be an online drive that is part of an array. +.It Cm good Ar drive +Mark +.Ar drive +as an unconfigured good drive. +.Ar Drive +must not be part of an existing array. +.It Cm rebuild Ar drive +Mark a failed +.Ar drive +that is still part of an array as a good drive suitable for a rebuild. +The firmware should kick off an array rebuild on its own if a failed drive +is marked as a rebuild drive. +.It Cm drive progress Ar drive +Report the current progress and estimated completion time of drive operations +such as rebuilds or patrol reads. +.It Cm drive clear Ar drive Brq "start | stop" +Start or stop the writing of all 0x00 characters to a drive. +.It Cm start rebuild Ar drive +Manually start a rebuild on +.Ar drive . +.It Cm abort rebuild Ar drive +Abort an in-progress rebuild operation on +.Ar drive . +It can be resumed with the +.Cm start rebuild +command. +.It Cm locate Ar drive Brq "on | off" +Change the state of the external LED associated with +.Ar drive . +.El +.Pp +The logical volume management commands include: +.Bl -tag -width indent +.It Cm cache Ar volume Op Ar setting Op Ar value +If no +.Ar setting +argument is supplied, then the current cache policy for +.Ar volume +is displayed; +otherwise, +the cache policy for +.Ar volume +is modified. +The optional +.Ar setting +argument can be one of the following values: +.Bl -tag -width indent +.It Cm enable +Enable caching for both read and write I/O operations. +.It Cm disable +Disable caching for both read and write I/O operations. +.It Cm reads +Enable caching only for read I/O operations. +.It Cm writes +Enable caching only for write I/O operations. +.It Cm write-back +Use write-back policy for cached writes. +.It Cm write-through +Use write-through policy for cached writes. +.It Cm read-ahead Op Ar value +Set the read ahead policy for cached reads. +The +.Ar value +argument can be set to either +.Dq none , +.Dq adaptive , +or +.Dq always . +.It Cm write-cache Op Ar value +Control the write caches on the physical drives backing +.Ar volume . +The +.Ar value +argument can be set to either +.Dq disable , +.Dq enable , +or +.Dq default . +.Pp +In general this setting should be left disabled to avoid data loss when the +physical drives lose power. +The battery backup of the RAID controller does not save data in the write +caches of the physical drives. +.El +.It Cm name Ar volume Ar name +Sets the name of +.Ar volume +to +.Ar name . +.It Cm volume progress Ar volume +Report the current progress and estimated completion time of volume operations +such as consistency checks and initializations. +.El +.Pp +The configuration commands include: +.Bl -tag -width indent +.It Cm clear +Delete the entire configuration including all volumes, arrays, and spares. +.It Xo Cm create Ar type +.Op Fl v +.Op Fl s Ar stripe_size +.Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Op Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Xc +Create a new volume. +The +.Ar type +specifies the type of volume to create. +Currently supported types include: +.Bl -tag -width indent +.It Cm jbod +Creates a RAID0 volume for each drive specified. +Each drive must be specified as a separate argument. +.It Cm raid0 +Creates one RAID0 volume spanning the drives listed in the single drive list. +.It Cm raid1 +Creates one RAID1 volume spanning the drives listed in the single drive list. +.It Cm raid5 +Creates one RAID5 volume spanning the drives listed in the single drive list. +.It Cm raid6 +Creates one RAID6 volume spanning the drives listed in the single drive list. +.It Cm raid10 +Creates one RAID10 volume spanning multiple RAID1 arrays. +The drives for each RAID1 array are specified as a single drive list. +.It Cm raid50 +Creates one RAID50 volume spanning multiple RAID5 arrays. +The drives for each RAID5 array are specified as a single drive list. +.It Cm raid60 +Creates one RAID60 volume spanning multiple RAID6 arrays. +The drives for each RAID6 array are specified as a single drive list. +.It Cm concat +Creates a single volume by concatenating all of the drives in the single drive +list. +.El +.Pp +.Sy Note: +Not all volume types are supported by all controllers. +.Pp +If the +.Fl v +flag is specified after +.Ar type , +then more verbose output will be enabled. +Currently this just provides notification as drives are added to arrays and +arrays to volumes when building the configuration. +.Pp +The +.Fl s +.Ar stripe_size +parameter allows the stripe size of the array to be set. +By default a stripe size of 64K is used. +Valid values are 512 through 1M, though the MFI firmware may reject some +values. +.It Cm delete Ar volume +Delete the volume +.Ar volume . +.It Cm add Ar drive Op Ar volume +Mark +.Ar drive +as a hot spare. +.Ar Drive +must be in the unconfigured good state. +If +.Ar volume +is specified, +then the hot spare will be dedicated to arrays backing that volume. +Otherwise, +.Ar drive +will be used as a global hot spare backing all arrays for this controller. +Note that +.Ar drive +must be as large as the smallest drive in all of the arrays it is going to +back. +.It Cm remove Ar drive +Remove the hot spare +.Ar drive +from service. +It will be placed in the unconfigured good state. +.El +.Pp +The controller management commands include: +.Bl -tag -width indent +.It Cm patrol Ar command Op Ar interval Op Ar start +Set the patrol read operation mode. +The +.Ar command +argument can be one of the following values: +.Bl -tag -width indent +.It Cm disable +Disable patrol reads. +.It Cm auto +Enable periodic patrol reads initiated by the firmware. +The optional +.Ar interval +argument specifies the interval in seconds between patrol reads. +If patrol reads should be run continously, +then +.Ar interval +should consist of the word +.Dq continuously . +The optional +.Ar start +argument specifies a non-negative, relative start time for the next patrol read. +If an interval or start time is not specified, +then the existing setting will be used. +.It Cm manual +Enable manual patrol reads that are only initiated by the user. +.El +.It Cm start patrol +Start a patrol read operation. +.It Cm stop patrol +Stop a currently running patrol read operation. +.It Cm flash Ar file +Updates the flash on the controller with the firmware stored in +.Ar file . +A reboot is required for the new firmware to take effect. +.El +.Sh EXAMPLES +Configure the cache for volume mfid0 to cache only writes: +.Pp +.Dl Nm Cm cache mfid0 writes +.Dl Nm Cm cache mfid0 write-back +.Pp +Create a RAID5 array spanning the first four disks in the second enclosure: +.Pp +.Dl Nm Cm create raid5 e1:s0,e1:s1,e1:s2,e1:s4 +.Pp +Configure the first three disks on a controller as JBOD: +.Pp +.Dl Nm Cm create jbod 0 1 2 +.Pp +Create a RAID10 volume that spans two arrays each of which contains two disks +from two different enclosures: +.Pp +.Dl Nm Cm create raid10 e1:s0,e1:s1 e2:s0,e2:s1 +.Pp +Add drive with the device ID of 4 as a global hot spare: +.Pp +.Dl Nm Cm add 4 +.Pp +Add the drive in slot 2 in the main chassis as a hot spare for volume mfid0: +.Pp +.Dl Nm Cm add s2 mfid0 +.Pp +Configure the adapter to run periodic patrol reads once a week with the first +patrol read starting in 5 minutes: +.Pp +.Dl Nm Cm patrol auto 604800 300 +.Pp +.Sh SEE ALSO +.Xr mfi 4 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 8.0 . diff --git a/usr.sbin/mfiutil/mfiutil.c b/usr.sbin/mfiutil/mfiutil.c new file mode 100644 index 00000000000..d091fb63177 --- /dev/null +++ b/usr.sbin/mfiutil/mfiutil.c @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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$ + */ + +#include +#include +#include +#include +#include +#include +#include "mfiutil.h" + +SET_DECLARE(MFI_DATASET(top), struct mfiutil_command); + +MFI_TABLE(top, start); +MFI_TABLE(top, stop); +MFI_TABLE(top, abort); + +int mfi_unit; + +static void +usage(void) +{ + + fprintf(stderr, "usage: mfiutil [-u unit] ...\n\n"); + fprintf(stderr, "Commands include:\n"); + fprintf(stderr, " version\n"); + fprintf(stderr, " show adapter - display controller information\n"); + fprintf(stderr, " show battery - display battery information\n"); + fprintf(stderr, " show config - display RAID configuration\n"); + fprintf(stderr, " show drives - list physical drives\n"); + fprintf(stderr, " show events - display event log\n"); + fprintf(stderr, " show firmware - list firmware images\n"); + fprintf(stderr, " show volumes - list logical volumes\n"); + fprintf(stderr, " show patrol - display patrol read status\n"); + fprintf(stderr, " fail - fail a physical drive\n"); + fprintf(stderr, " good - mark a bad physical drive as good\n"); + fprintf(stderr, " rebuild - mark failed drive ready for rebuild\n"); + fprintf(stderr, " drive progress - display status of active operations\n"); + fprintf(stderr, " drive clear - clear a drive with all 0x00\n"); + fprintf(stderr, " start rebuild \n"); + fprintf(stderr, " abort rebuild \n"); + fprintf(stderr, " locate - toggle drive LED\n"); + fprintf(stderr, " cache [command [setting]]\n"); + fprintf(stderr, " name \n"); + fprintf(stderr, " volume progress - display status of active operations\n"); + fprintf(stderr, " clear - clear volume configuration\n"); + fprintf(stderr, " create [-v] [,[,...]] [[,[,...]]\n"); + fprintf(stderr, " delete \n"); + fprintf(stderr, " add [volume] - add a hot spare\n"); + fprintf(stderr, " remove - remove a hot spare\n"); + fprintf(stderr, " patrol [interval [start]]\n"); + fprintf(stderr, " start patrol - start a patrol read\n"); + fprintf(stderr, " stop patrol - stop a patrol read\n"); + fprintf(stderr, " flash \n"); +#ifdef DEBUG + fprintf(stderr, " debug - debug 'show config'\n"); + fprintf(stderr, " dump - display 'saved' config\n"); +#endif + exit(1); +} + +static int +version(int ac, char **av) +{ + + printf("mfiutil version 1.0.13"); +#ifdef DEBUG + printf(" (DEBUG)"); +#endif + printf("\n"); + return (0); +} +MFI_COMMAND(top, version, version); + +int +main(int ac, char **av) +{ + struct mfiutil_command **cmd; + int ch; + + while ((ch = getopt(ac, av, "u:")) != -1) { + switch (ch) { + case 'u': + mfi_unit = atoi(optarg); + break; + case '?': + usage(); + } + } + + av += optind; + ac -= optind; + + /* getopt() eats av[0], so we can't use mfi_table_handler() directly. */ + if (ac == 0) + usage(); + + SET_FOREACH(cmd, MFI_DATASET(top)) { + if (strcmp((*cmd)->name, av[0]) == 0) { + (*cmd)->handler(ac, av); + return (0); + } + } + warnx("Unknown command %s.", av[0]); + return (0); +} diff --git a/usr.sbin/mfiutil/mfiutil.h b/usr.sbin/mfiutil/mfiutil.h new file mode 100644 index 00000000000..b080b5004e3 --- /dev/null +++ b/usr.sbin/mfiutil/mfiutil.h @@ -0,0 +1,147 @@ +/*- + * Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 __MFIUTIL_H__ +#define __MFIUTIL_H__ + +#include +#include + +#include + +/* 4.x compat */ +#ifndef SET_DECLARE + +/* */ +#define __used +#define __section(x) __attribute__((__section__(x))) + +/* */ +#undef __MAKE_SET +#undef DATA_SET + +#define __MAKE_SET(set, sym) \ + static void const * const __set_##set##_sym_##sym \ + __section("set_" #set) __used = &sym + +#define DATA_SET(set, sym) __MAKE_SET(set, sym) + +#define SET_DECLARE(set, ptype) \ + extern ptype *__CONCAT(__start_set_,set); \ + extern ptype *__CONCAT(__stop_set_,set) + +#define SET_BEGIN(set) \ + (&__CONCAT(__start_set_,set)) +#define SET_LIMIT(set) \ + (&__CONCAT(__stop_set_,set)) + +#define SET_FOREACH(pvar, set) \ + for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++) + +int humanize_number(char *_buf, size_t _len, int64_t _number, + const char *_suffix, int _scale, int _flags); + +/* humanize_number(3) */ +#define HN_DECIMAL 0x01 +#define HN_NOSPACE 0x02 +#define HN_B 0x04 +#define HN_DIVISOR_1000 0x08 + +#define HN_GETSCALE 0x10 +#define HN_AUTOSCALE 0x20 + +#endif + +/* Constants for DDF RAID levels. */ +#define DDF_RAID0 0x00 +#define DDF_RAID1 0x01 +#define DDF_RAID3 0x03 +#define DDF_RAID5 0x05 +#define DDF_RAID6 0x06 +#define DDF_RAID1E 0x11 +#define DDF_JBOD 0x0f +#define DDF_CONCAT 0x1f +#define DDF_RAID5E 0x15 +#define DDF_RAID5EE 0x25 + +struct mfiutil_command { + const char *name; + int (*handler)(int ac, char **av); +}; + +#define MFI_DATASET(name) mfiutil_ ## name ## _table + +#define MFI_COMMAND(set, name, function) \ + static struct mfiutil_command function ## _mfiutil_command = \ + { #name, function }; \ + DATA_SET(MFI_DATASET(set), function ## _mfiutil_command) + +#define MFI_TABLE(set, name) \ + SET_DECLARE(MFI_DATASET(name), struct mfiutil_command); \ + \ + static int \ + mfiutil_ ## name ## _table_handler(int ac, char **av) \ + { \ + return (mfi_table_handler(SET_BEGIN(MFI_DATASET(name)), \ + SET_LIMIT(MFI_DATASET(name)), ac, av)); \ + } \ + MFI_COMMAND(set, name, mfiutil_ ## name ## _table_handler) + +extern int mfi_unit; + +void mbox_store_ldref(uint8_t *mbox, union mfi_ld_ref *ref); +void mbox_store_pdref(uint8_t *mbox, union mfi_pd_ref *ref); +void mfi_display_progress(const char *label, struct mfi_progress *prog); +int mfi_table_handler(struct mfiutil_command **start, + struct mfiutil_command **end, int ac, char **av); +const char *mfi_raid_level(uint8_t primary_level, uint8_t secondary_level); +const char *mfi_ldstate(enum mfi_ld_state state); +const char *mfi_pdstate(enum mfi_pd_state state); +const char *mfi_pd_inq_string(struct mfi_pd_info *info); +const char *mfi_volume_name(int fd, uint8_t target_id); +int mfi_volume_busy(int fd, uint8_t target_id); +int mfi_config_read(int fd, struct mfi_config_data **configp); +int mfi_lookup_drive(int fd, char *drive, uint16_t *device_id); +int mfi_lookup_volume(int fd, const char *name, uint8_t *target_id); +int mfi_dcmd_command(int fd, uint32_t opcode, void *buf, size_t bufsize, + uint8_t *mbox, size_t mboxlen, uint8_t *statusp); +int mfi_open(int unit); +int mfi_ctrl_get_info(int fd, struct mfi_ctrl_info *info, uint8_t *statusp); +int mfi_ld_get_info(int fd, uint8_t target_id, struct mfi_ld_info *info, + uint8_t *statusp); +int mfi_ld_get_list(int fd, struct mfi_ld_list *list, uint8_t *statusp); +int mfi_pd_get_info(int fd, uint16_t device_id, struct mfi_pd_info *info, + uint8_t *statusp); +int mfi_pd_get_list(int fd, struct mfi_pd_list **listp, uint8_t *statusp); +int mfi_reconfig_supported(void); +const char *mfi_status(u_int status_code); + +#endif /* !__MFIUTIL_H__ */ From 53e7499383aaef5f576f40add38ec67622cc733f Mon Sep 17 00:00:00 2001 From: Scott Long Date: Mon, 17 Aug 2009 07:30:08 +0000 Subject: [PATCH 0064/2592] Merge mptutil Approved by: re --- usr.sbin/Makefile | 1 + usr.sbin/mptutil/Makefile | 19 + usr.sbin/mptutil/mpt_cam.c | 569 ++++++++++++++++ usr.sbin/mptutil/mpt_cmd.c | 639 ++++++++++++++++++ usr.sbin/mptutil/mpt_config.c | 1160 +++++++++++++++++++++++++++++++++ usr.sbin/mptutil/mpt_drive.c | 395 +++++++++++ usr.sbin/mptutil/mpt_evt.c | 155 +++++ usr.sbin/mptutil/mpt_show.c | 559 ++++++++++++++++ usr.sbin/mptutil/mpt_volume.c | 248 +++++++ usr.sbin/mptutil/mptutil.8 | 386 +++++++++++ usr.sbin/mptutil/mptutil.c | 123 ++++ usr.sbin/mptutil/mptutil.h | 178 +++++ 12 files changed, 4432 insertions(+) create mode 100644 usr.sbin/mptutil/Makefile create mode 100644 usr.sbin/mptutil/mpt_cam.c create mode 100644 usr.sbin/mptutil/mpt_cmd.c create mode 100644 usr.sbin/mptutil/mpt_config.c create mode 100644 usr.sbin/mptutil/mpt_drive.c create mode 100644 usr.sbin/mptutil/mpt_evt.c create mode 100644 usr.sbin/mptutil/mpt_show.c create mode 100644 usr.sbin/mptutil/mpt_volume.c create mode 100644 usr.sbin/mptutil/mptutil.8 create mode 100644 usr.sbin/mptutil/mptutil.c create mode 100644 usr.sbin/mptutil/mptutil.h diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 37d24f853cc..160b122571a 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -104,6 +104,7 @@ SUBDIR= ${_ac} \ ${_mount_smbfs} \ ${_moused} \ ${_mptable} \ + mptutil \ mtest \ mtree \ ${_named} \ diff --git a/usr.sbin/mptutil/Makefile b/usr.sbin/mptutil/Makefile new file mode 100644 index 00000000000..4abf66e4657 --- /dev/null +++ b/usr.sbin/mptutil/Makefile @@ -0,0 +1,19 @@ +# $FreeBSD$ + +PROG= mptutil +SRCS= mptutil.c mpt_cam.c mpt_cmd.c mpt_config.c mpt_drive.c mpt_evt.c \ + mpt_show.c mpt_volume.c +# mpt_flash.c +MAN= mptutil.8 + +WARNS?= 3 + +DPADD+= ${LIBCAM} ${LIBUTIL} +LDADD+= -lcam -lutil + +# Here be dragons +.ifdef DEBUG +CFLAGS+= -DDEBUG +.endif + +.include diff --git a/usr.sbin/mptutil/mpt_cam.c b/usr.sbin/mptutil/mpt_cam.c new file mode 100644 index 00000000000..0d20c7db601 --- /dev/null +++ b/usr.sbin/mptutil/mpt_cam.c @@ -0,0 +1,569 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 +__RCSID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mptutil.h" + +static int xptfd; + +static int +xpt_open(void) +{ + + if (xptfd == 0) + xptfd = open(XPT_DEVICE, O_RDWR); + return (xptfd); +} + +int +mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd) +{ + struct bus_match_pattern *b; + struct periph_match_pattern *p; + struct periph_match_result *r; + union ccb ccb; + size_t bufsize; + int i; + + /* mpt(4) only handles devices on bus 0. */ + if (VolumeBus != 0) + return (ENXIO); + + if (xpt_open() < 0) + return (ENXIO); + + bzero(&ccb, sizeof(ccb)); + + ccb.ccb_h.func_code = XPT_DEV_MATCH; + ccb.ccb_h.path_id = CAM_XPT_PATH_ID; + ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; + ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; + + bufsize = sizeof(struct dev_match_result) * 5; + ccb.cdm.num_matches = 0; + ccb.cdm.match_buf_len = bufsize; + ccb.cdm.matches = calloc(1, bufsize); + + bufsize = sizeof(struct dev_match_pattern) * 2; + ccb.cdm.num_patterns = 2; + ccb.cdm.pattern_buf_len = bufsize; + ccb.cdm.patterns = calloc(1, bufsize); + + /* Match mptX bus 0. */ + ccb.cdm.patterns[0].type = DEV_MATCH_BUS; + b = &ccb.cdm.patterns[0].pattern.bus_pattern; + snprintf(b->dev_name, sizeof(b->dev_name), "mpt"); + b->unit_number = mpt_unit; + b->bus_id = 0; + b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID; + + /* Look for a "da" device at the specified target and lun. */ + ccb.cdm.patterns[1].type = DEV_MATCH_PERIPH; + p = &ccb.cdm.patterns[1].pattern.periph_pattern; + snprintf(p->periph_name, sizeof(p->periph_name), "da"); + p->target_id = VolumeID; + p->flags = PERIPH_MATCH_NAME | PERIPH_MATCH_TARGET; + + if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { + i = errno; + free(ccb.cdm.matches); + free(ccb.cdm.patterns); + return (i); + } + free(ccb.cdm.patterns); + + if (((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) || + (ccb.cdm.status != CAM_DEV_MATCH_LAST)) { + warnx("mpt_query_disk got CAM error %#x, CDM error %d\n", + ccb.ccb_h.status, ccb.cdm.status); + free(ccb.cdm.matches); + return (EIO); + } + + /* + * We should have exactly 2 matches, 1 for the bus and 1 for + * the peripheral. However, if we only have 1 match and it is + * for the bus, don't print an error message and return + * ENOENT. + */ + if (ccb.cdm.num_matches == 1 && + ccb.cdm.matches[0].type == DEV_MATCH_BUS) { + free(ccb.cdm.matches); + return (ENOENT); + } + if (ccb.cdm.num_matches != 2) { + warnx("mpt_query_disk got %d matches, expected 2", + ccb.cdm.num_matches); + free(ccb.cdm.matches); + return (EIO); + } + if (ccb.cdm.matches[0].type != DEV_MATCH_BUS || + ccb.cdm.matches[1].type != DEV_MATCH_PERIPH) { + warnx("mpt_query_disk got wrong CAM matches"); + free(ccb.cdm.matches); + return (EIO); + } + + /* Copy out the data. */ + r = &ccb.cdm.matches[1].result.periph_result; + snprintf(qd->devname, sizeof(qd->devname), "%s%d", r->periph_name, + r->unit_number); + free(ccb.cdm.matches); + + return (0); +} + +static int +periph_is_volume(CONFIG_PAGE_IOC_2 *ioc2, struct periph_match_result *r) +{ + CONFIG_PAGE_IOC_2_RAID_VOL *vol; + int i; + + if (ioc2 == NULL) + return (0); + vol = ioc2->RaidVolume; + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { + if (vol->VolumeBus == 0 && vol->VolumeID == r->target_id) + return (1); + } + return (0); +} + +/* Much borrowed from scsireadcapacity() in src/sbin/camcontrol/camcontrol.c. */ +static int +fetch_scsi_capacity(struct cam_device *dev, struct mpt_standalone_disk *disk) +{ + struct scsi_read_capacity_data rcap; + struct scsi_read_capacity_data_long rcaplong; + union ccb *ccb; + int error; + + ccb = cam_getccb(dev); + if (ccb == NULL) + return (ENOMEM); + + /* Zero the rest of the ccb. */ + bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio) - + sizeof(struct ccb_hdr)); + + scsi_read_capacity(&ccb->csio, 1, NULL, MSG_SIMPLE_Q_TAG, &rcap, + SSD_FULL_SIZE, 5000); + + /* Disable freezing the device queue */ + ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; + + if (cam_send_ccb(dev, ccb) < 0) { + error = errno; + cam_freeccb(ccb); + return (error); + } + + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + cam_freeccb(ccb); + return (EIO); + } + cam_freeccb(ccb); + + /* + * A last block of 2^32-1 means that the true capacity is over 2TB, + * and we need to issue the long READ CAPACITY to get the real + * capacity. Otherwise, we're all set. + */ + if (scsi_4btoul(rcap.addr) != 0xffffffff) { + disk->maxlba = scsi_4btoul(rcap.addr); + return (0); + } + + /* Zero the rest of the ccb. */ + bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio) - + sizeof(struct ccb_hdr)); + + scsi_read_capacity_16(&ccb->csio, 1, NULL, MSG_SIMPLE_Q_TAG, 0, 0, 0, + &rcaplong, SSD_FULL_SIZE, 5000); + + /* Disable freezing the device queue */ + ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; + + if (cam_send_ccb(dev, ccb) < 0) { + error = errno; + cam_freeccb(ccb); + return (error); + } + + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + cam_freeccb(ccb); + return (EIO); + } + cam_freeccb(ccb); + + disk->maxlba = scsi_8btou64(rcaplong.addr); + return (0); +} + +/* Borrowed heavily from scsi_all.c:scsi_print_inquiry(). */ +static void +format_scsi_inquiry(struct mpt_standalone_disk *disk, + struct scsi_inquiry_data *inq_data) +{ + char vendor[16], product[48], revision[16], rstr[12]; + + if (SID_QUAL_IS_VENDOR_UNIQUE(inq_data)) + return; + if (SID_TYPE(inq_data) != T_DIRECT) + return; + if (SID_QUAL(inq_data) != SID_QUAL_LU_CONNECTED) + return; + + cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor), + sizeof(vendor)); + cam_strvis(product, inq_data->product, sizeof(inq_data->product), + sizeof(product)); + cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision), + sizeof(revision)); + + /* Hack for SATA disks, no idea how to tell speed. */ + if (strcmp(vendor, "ATA") == 0) { + snprintf(disk->inqstring, sizeof(disk->inqstring), + "<%s %s> SATA", product, revision); + return; + } + + switch (SID_ANSI_REV(inq_data)) { + case SCSI_REV_CCS: + strcpy(rstr, "SCSI-CCS"); + break; + case 5: + strcpy(rstr, "SAS"); + break; + default: + snprintf(rstr, sizeof (rstr), "SCSI-%d", + SID_ANSI_REV(inq_data)); + break; + } + snprintf(disk->inqstring, sizeof(disk->inqstring), "<%s %s %s> %s", + vendor, product, revision, rstr); +} + +/* Much borrowed from scsiinquiry() in src/sbin/camcontrol/camcontrol.c. */ +static int +fetch_scsi_inquiry(struct cam_device *dev, struct mpt_standalone_disk *disk) +{ + struct scsi_inquiry_data *inq_buf; + union ccb *ccb; + int error; + + ccb = cam_getccb(dev); + if (ccb == NULL) + return (ENOMEM); + + /* Zero the rest of the ccb. */ + bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio) - + sizeof(struct ccb_hdr)); + + inq_buf = calloc(1, sizeof(*inq_buf)); + if (inq_buf == NULL) { + cam_freeccb(ccb); + return (ENOMEM); + } + scsi_inquiry(&ccb->csio, 1, NULL, MSG_SIMPLE_Q_TAG, (void *)inq_buf, + SHORT_INQUIRY_LENGTH, 0, 0, SSD_FULL_SIZE, 5000); + + /* Disable freezing the device queue */ + ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; + + if (cam_send_ccb(dev, ccb) < 0) { + error = errno; + free(inq_buf); + cam_freeccb(ccb); + return (error); + } + + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + free(inq_buf); + cam_freeccb(ccb); + return (EIO); + } + + cam_freeccb(ccb); + format_scsi_inquiry(disk, inq_buf); + free(inq_buf); + return (0); +} + +int +mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp) +{ + CONFIG_PAGE_IOC_2 *ioc2; + struct mpt_standalone_disk *disks; + struct bus_match_pattern *b; + struct periph_match_pattern *p; + struct periph_match_result *r; + struct cam_device *dev; + union ccb ccb; + size_t bufsize; + u_int i; + int count; + + if (xpt_open() < 0) + return (ENXIO); + + for (count = 100;; count+= 100) { + /* Try to fetch 'count' disks in one go. */ + bzero(&ccb, sizeof(ccb)); + + ccb.ccb_h.func_code = XPT_DEV_MATCH; + + bufsize = sizeof(struct dev_match_result) * (count + 2); + ccb.cdm.num_matches = 0; + ccb.cdm.match_buf_len = bufsize; + ccb.cdm.matches = calloc(1, bufsize); + + bufsize = sizeof(struct dev_match_pattern) * 2; + ccb.cdm.num_patterns = 2; + ccb.cdm.pattern_buf_len = bufsize; + ccb.cdm.patterns = calloc(1, bufsize); + + /* Match mptX bus 0. */ + ccb.cdm.patterns[0].type = DEV_MATCH_BUS; + b = &ccb.cdm.patterns[0].pattern.bus_pattern; + snprintf(b->dev_name, sizeof(b->dev_name), "mpt"); + b->unit_number = mpt_unit; + b->bus_id = 0; + b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID; + + /* Match any "da" peripherals. */ + ccb.cdm.patterns[1].type = DEV_MATCH_PERIPH; + p = &ccb.cdm.patterns[1].pattern.periph_pattern; + snprintf(p->periph_name, sizeof(p->periph_name), "da"); + p->flags = PERIPH_MATCH_NAME; + + if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { + i = errno; + free(ccb.cdm.matches); + free(ccb.cdm.patterns); + return (i); + } + free(ccb.cdm.patterns); + + /* Check for CCB errors. */ + if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + free(ccb.cdm.matches); + return (EIO); + } + + /* If we need a longer list, try again. */ + if (ccb.cdm.status == CAM_DEV_MATCH_MORE) { + free(ccb.cdm.matches); + continue; + } + + /* If we got an error, abort. */ + if (ccb.cdm.status != CAM_DEV_MATCH_LAST) { + free(ccb.cdm.matches); + return (EIO); + } + break; + } + + /* + * We should have N + 1 matches, 1 for the bus and 1 for each + * "da" device. + */ + if (ccb.cdm.num_matches < 1) { + warnx("mpt_fetch_disks didn't get any matches"); + free(ccb.cdm.matches); + return (EIO); + } + if (ccb.cdm.matches[0].type != DEV_MATCH_BUS) { + warnx("mpt_fetch_disks got wrong CAM matches"); + free(ccb.cdm.matches); + return (EIO); + } + for (i = 1; i < ccb.cdm.num_matches; i++) { + if (ccb.cdm.matches[i].type != DEV_MATCH_PERIPH) { + warnx("mpt_fetch_disks got wrong CAM matches"); + free(ccb.cdm.matches); + return (EIO); + } + } + + /* Shortcut if we don't have any "da" devices. */ + if (ccb.cdm.num_matches == 1) { + free(ccb.cdm.matches); + *ndisks = 0; + *disksp = NULL; + return (0); + } + + /* + * Some of the "da" peripherals may be for RAID volumes, so + * fetch the IOC 2 page (list of RAID volumes) so we can + * exclude them from the list. + */ + ioc2 = mpt_read_ioc_page(fd, 2, NULL); + disks = calloc(ccb.cdm.num_matches, sizeof(*disks)); + count = 0; + for (i = 1; i < ccb.cdm.num_matches; i++) { + r = &ccb.cdm.matches[i].result.periph_result; + if (periph_is_volume(ioc2, r)) + continue; + disks[count].bus = 0; + disks[count].target = r->target_id; + snprintf(disks[count].devname, sizeof(disks[count].devname), + "%s%d", r->periph_name, r->unit_number); + + dev = cam_open_device(disks[count].devname, O_RDWR); + if (dev != NULL) { + fetch_scsi_capacity(dev, &disks[count]); + fetch_scsi_inquiry(dev, &disks[count]); + cam_close_device(dev); + } + count++; + } + free(ccb.cdm.matches); + free(ioc2); + + *ndisks = count; + *disksp = disks; + return (0); +} + +/* + * Instruct the mpt(4) device to rescan its busses to find new devices + * such as disks whose RAID physdisk page was removed or volumes that + * were created. If id is -1, the entire bus is rescanned. + * Otherwise, only devices at the specified ID are rescanned. If bus + * is -1, then all busses are scanned instead of the specified bus. + * Note that currently, only bus 0 is supported. + */ +int +mpt_rescan_bus(int bus, int id) +{ + struct bus_match_pattern *b; + union ccb ccb; + path_id_t path_id; + size_t bufsize; + + /* mpt(4) only handles devices on bus 0. */ + if (bus != -1 && bus != 0) + return (EINVAL); + + if (xpt_open() < 0) + return (ENXIO); + + /* First, find the path id of bus 0 for this mpt controller. */ + bzero(&ccb, sizeof(ccb)); + + ccb.ccb_h.func_code = XPT_DEV_MATCH; + + bufsize = sizeof(struct dev_match_result) * 1; + ccb.cdm.num_matches = 0; + ccb.cdm.match_buf_len = bufsize; + ccb.cdm.matches = calloc(1, bufsize); + + bufsize = sizeof(struct dev_match_pattern) * 1; + ccb.cdm.num_patterns = 1; + ccb.cdm.pattern_buf_len = bufsize; + ccb.cdm.patterns = calloc(1, bufsize); + + /* Match mptX bus 0. */ + ccb.cdm.patterns[0].type = DEV_MATCH_BUS; + b = &ccb.cdm.patterns[0].pattern.bus_pattern; + snprintf(b->dev_name, sizeof(b->dev_name), "mpt"); + b->unit_number = mpt_unit; + b->bus_id = 0; + b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID; + + if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { + free(ccb.cdm.matches); + free(ccb.cdm.patterns); + return (errno); + } + free(ccb.cdm.patterns); + + if (((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) || + (ccb.cdm.status != CAM_DEV_MATCH_LAST)) { + warnx("mpt_rescan_bus got CAM error %#x, CDM error %d\n", + ccb.ccb_h.status, ccb.cdm.status); + free(ccb.cdm.matches); + return (EIO); + } + + /* We should have exactly 1 match for the bus. */ + if (ccb.cdm.num_matches != 1 || + ccb.cdm.matches[0].type != DEV_MATCH_BUS) { + free(ccb.cdm.matches); + return (ENOENT); + } + path_id = ccb.cdm.matches[0].result.bus_result.path_id; + free(ccb.cdm.matches); + + /* Now perform the actual rescan. */ + ccb.ccb_h.path_id = path_id; + if (id == -1) { + ccb.ccb_h.func_code = XPT_SCAN_BUS; + ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; + ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; + ccb.ccb_h.timeout = 5000; + } else { + ccb.ccb_h.func_code = XPT_SCAN_LUN; + ccb.ccb_h.target_id = id; + ccb.ccb_h.target_lun = 0; + } + ccb.crcn.flags = CAM_FLAG_NONE; + + /* Run this at a low priority. */ + ccb.ccb_h.pinfo.priority = 5; + + if (ioctl(xptfd, CAMIOCOMMAND, &ccb) == -1) + return (errno); + + if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + warnx("mpt_rescan_bus rescan got CAM error %#x\n", + ccb.ccb_h.status & CAM_STATUS_MASK); + return (EIO); + } + + return (0); +} diff --git a/usr.sbin/mptutil/mpt_cmd.c b/usr.sbin/mptutil/mpt_cmd.c new file mode 100644 index 00000000000..2d6000c7731 --- /dev/null +++ b/usr.sbin/mptutil/mpt_cmd.c @@ -0,0 +1,639 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 +__RCSID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mptutil.h" + +static const char *mpt_ioc_status_codes[] = { + "Success", /* 0x0000 */ + "Invalid function", + "Busy", + "Invalid scatter-gather list", + "Internal error", + "Reserved", + "Insufficient resources", + "Invalid field", + "Invalid state", /* 0x0008 */ + "Operation state not supported", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 0x0010 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 0x0018 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Invalid configuration action", /* 0x0020 */ + "Invalid configuration type", + "Invalid configuration page", + "Invalid configuration data", + "No configuration defaults", + "Unable to commit configuration change", + NULL, + NULL, + NULL, /* 0x0028 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 0x0030 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 0x0038 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Recovered SCSI error", /* 0x0040 */ + "Invalid SCSI bus", + "Invalid SCSI target ID", + "SCSI device not there", + "SCSI data overrun", + "SCSI data underrun", + "SCSI I/O error", + "SCSI protocol error", + "SCSI task terminated", /* 0x0048 */ + "SCSI residual mismatch", + "SCSI task management failed", + "SCSI I/O controller terminated", + "SCSI external controller terminated", + "EEDP guard error", + "EEDP reference tag error", + "EEDP application tag error", + NULL, /* 0x0050 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 0x0058 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "SCSI target priority I/O", /* 0x0060 */ + "Invalid SCSI target port", + "Invalid SCSI target I/O index", + "SCSI target aborted", + "No connection retryable", + "No connection", + "FC aborted", + "Invalid FC receive ID", + "FC did invalid", /* 0x0068 */ + "FC node logged out", + "Transfer count mismatch", + "STS data not set", + "FC exchange canceled", + "Data offset error", + "Too much write data", + "IU too short", + "ACK NAK timeout", /* 0x0070 */ + "NAK received", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 0x0078 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "LAN device not found", /* 0x0080 */ + "LAN device failure", + "LAN transmit error", + "LAN transmit aborted", + "LAN receive error", + "LAN receive aborted", + "LAN partial packet", + "LAN canceled", + NULL, /* 0x0088 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "SAS SMP request failed", /* 0x0090 */ + "SAS SMP data overrun", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Inband aborted", /* 0x0098 */ + "No inband connection", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Diagnostic released", /* 0x00A0 */ +}; + +static const char *mpt_raid_action_status_codes[] = { + "Success", + "Invalid action", + "Failure", + "Operation in progress", +}; + +const char * +mpt_ioc_status(U16 IOCStatus) +{ + static char buffer[16]; + + IOCStatus &= MPI_IOCSTATUS_MASK; + if (IOCStatus < sizeof(mpt_ioc_status_codes) / sizeof(char *) && + mpt_ioc_status_codes[IOCStatus] != NULL) + return (mpt_ioc_status_codes[IOCStatus]); + snprintf(buffer, sizeof(buffer), "Status: 0x%04x", IOCStatus); + return (buffer); +} + +const char * +mpt_raid_status(U16 ActionStatus) +{ + static char buffer[16]; + + if (ActionStatus < sizeof(mpt_raid_action_status_codes) / + sizeof(char *)) + return (mpt_raid_action_status_codes[ActionStatus]); + snprintf(buffer, sizeof(buffer), "Status: 0x%04x", ActionStatus); + return (buffer); +} + +const char * +mpt_raid_level(U8 VolumeType) +{ + static char buf[16]; + + switch (VolumeType) { + case MPI_RAID_VOL_TYPE_IS: + return ("RAID-0"); + case MPI_RAID_VOL_TYPE_IM: + return ("RAID-1"); + case MPI_RAID_VOL_TYPE_IME: + return ("RAID-1E"); + case MPI_RAID_VOL_TYPE_RAID_5: + return ("RAID-5"); + case MPI_RAID_VOL_TYPE_RAID_6: + return ("RAID-6"); + case MPI_RAID_VOL_TYPE_RAID_10: + return ("RAID-10"); + case MPI_RAID_VOL_TYPE_RAID_50: + return ("RAID-50"); + default: + sprintf(buf, "LVL 0x%02x", VolumeType); + return (buf); + } +} + +const char * +mpt_volume_name(U8 VolumeBus, U8 VolumeID) +{ + static struct mpt_query_disk info; + static char buf[16]; + + if (mpt_query_disk(VolumeBus, VolumeID, &info) != 0) { + /* + * We only print out the bus number if it is non-zero + * since mpt(4) only supports devices on bus zero + * anyway. + */ + if (VolumeBus == 0) + snprintf(buf, sizeof(buf), "%d", VolumeID); + else + snprintf(buf, sizeof(buf), "%d:%d", VolumeBus, + VolumeID); + return (buf); + } + return (info.devname); +} + +int +mpt_lookup_volume(int fd, const char *name, U8 *VolumeBus, U8 *VolumeID) +{ + CONFIG_PAGE_IOC_2 *ioc2; + CONFIG_PAGE_IOC_2_RAID_VOL *vol; + struct mpt_query_disk info; + char *cp; + long bus, id; + int i; + + /* + * Check for a raw [:] string. If the bus is not + * specified, assume bus 0. + */ + bus = strtol(name, &cp, 0); + if (*cp == ':') { + id = strtol(cp + 1, &cp, 0); + if (*cp == '\0') { + if (bus < 0 || bus > 0xff || id < 0 || id > 0xff) { + errno = EINVAL; + return (-1); + } + *VolumeBus = bus; + *VolumeID = id; + return (0); + } + } else if (*cp == '\0') { + if (bus < 0 || bus > 0xff) { + errno = EINVAL; + return (-1); + } + *VolumeBus = 0; + *VolumeID = bus; + return (0); + } + + ioc2 = mpt_read_ioc_page(fd, 2, NULL); + if (ioc2 == NULL) + return (-1); + + vol = ioc2->RaidVolume; + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { + if (mpt_query_disk(vol->VolumeBus, vol->VolumeID, &info) != 0) + continue; + if (strcmp(name, info.devname) == 0) { + *VolumeBus = vol->VolumeBus; + *VolumeID = vol->VolumeID; + free(ioc2); + return (0); + } + } + free(ioc2); + errno = EINVAL; + return (-1); +} + +int +mpt_read_config_page_header(int fd, U8 PageType, U8 PageNumber, U32 PageAddress, + CONFIG_PAGE_HEADER *header, U16 *IOCStatus) +{ + struct mpt_cfg_page_req req; + + if (IOCStatus != NULL) + *IOCStatus = MPI_IOCSTATUS_SUCCESS; + bzero(&req, sizeof(req)); + req.header.PageType = PageType; + req.header.PageNumber = PageNumber; + req.page_address = PageAddress; + if (ioctl(fd, MPTIO_READ_CFG_HEADER, &req) < 0) + return (-1); + if (!IOC_STATUS_SUCCESS(req.ioc_status)) { + if (IOCStatus != NULL) + *IOCStatus = req.ioc_status; + else + warnx("Reading config page header failed: %s", + mpt_ioc_status(req.ioc_status)); + errno = EIO; + return (-1); + } + *header = req.header; + return (0); +} + +void * +mpt_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress, + U16 *IOCStatus) +{ + struct mpt_cfg_page_req req; + void *buf; + int save_errno; + + if (IOCStatus != NULL) + *IOCStatus = MPI_IOCSTATUS_SUCCESS; + bzero(&req, sizeof(req)); + req.header.PageType = PageType; + req.header.PageNumber = PageNumber; + req.page_address = PageAddress; + if (ioctl(fd, MPTIO_READ_CFG_HEADER, &req) < 0) + return (NULL); + if (!IOC_STATUS_SUCCESS(req.ioc_status)) { + if (IOCStatus != NULL) + *IOCStatus = req.ioc_status; + else + warnx("Reading config page header failed: %s", + mpt_ioc_status(req.ioc_status)); + errno = EIO; + return (NULL); + } + req.len = req.header.PageLength * 4; + buf = malloc(req.len); + req.buf = buf; + bcopy(&req.header, buf, sizeof(req.header)); + if (ioctl(fd, MPTIO_READ_CFG_PAGE, &req) < 0) { + save_errno = errno; + free(buf); + errno = save_errno; + return (NULL); + } + if (!IOC_STATUS_SUCCESS(req.ioc_status)) { + if (IOCStatus != NULL) + *IOCStatus = req.ioc_status; + else + warnx("Reading config page failed: %s", + mpt_ioc_status(req.ioc_status)); + free(buf); + errno = EIO; + return (NULL); + } + return (buf); +} + +void * +mpt_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion, + U8 PageNumber, U32 PageAddress, U16 *IOCStatus) +{ + struct mpt_ext_cfg_page_req req; + void *buf; + int save_errno; + + if (IOCStatus != NULL) + *IOCStatus = MPI_IOCSTATUS_SUCCESS; + bzero(&req, sizeof(req)); + req.header.PageVersion = PageVersion; + req.header.PageNumber = PageNumber; + req.header.ExtPageType = ExtPageType; + req.page_address = PageAddress; + if (ioctl(fd, MPTIO_READ_EXT_CFG_HEADER, &req) < 0) + return (NULL); + if (!IOC_STATUS_SUCCESS(req.ioc_status)) { + if (IOCStatus != NULL) + *IOCStatus = req.ioc_status; + else + warnx("Reading extended config page header failed: %s", + mpt_ioc_status(req.ioc_status)); + errno = EIO; + return (NULL); + } + req.len = req.header.ExtPageLength * 4; + buf = malloc(req.len); + req.buf = buf; + bcopy(&req.header, buf, sizeof(req.header)); + if (ioctl(fd, MPTIO_READ_EXT_CFG_PAGE, &req) < 0) { + save_errno = errno; + free(buf); + errno = save_errno; + return (NULL); + } + if (!IOC_STATUS_SUCCESS(req.ioc_status)) { + if (IOCStatus != NULL) + *IOCStatus = req.ioc_status; + else + warnx("Reading extended config page failed: %s", + mpt_ioc_status(req.ioc_status)); + free(buf); + errno = EIO; + return (NULL); + } + return (buf); +} + +int +mpt_write_config_page(int fd, void *buf, U16 *IOCStatus) +{ + CONFIG_PAGE_HEADER *hdr; + struct mpt_cfg_page_req req; + + if (IOCStatus != NULL) + *IOCStatus = MPI_IOCSTATUS_SUCCESS; + bzero(&req, sizeof(req)); + req.buf = buf; + hdr = buf; + req.len = hdr->PageLength * 4; + if (ioctl(fd, MPTIO_WRITE_CFG_PAGE, &req) < 0) + return (-1); + if (!IOC_STATUS_SUCCESS(req.ioc_status)) { + if (IOCStatus != NULL) { + *IOCStatus = req.ioc_status; + return (0); + } + warnx("Writing config page failed: %s", + mpt_ioc_status(req.ioc_status)); + errno = EIO; + return (-1); + } + return (0); +} + +int +mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID, U8 PhysDiskNum, + U32 ActionDataWord, void *buf, int len, RAID_VOL0_STATUS *VolumeStatus, + U32 *ActionData, int datalen, U16 *IOCStatus, U16 *ActionStatus, int write) +{ + struct mpt_raid_action raid_act; + + if (IOCStatus != NULL) + *IOCStatus = MPI_IOCSTATUS_SUCCESS; + if (datalen < 0 || (unsigned)datalen > sizeof(raid_act.action_data)) { + errno = EINVAL; + return (-1); + } + bzero(&raid_act, sizeof(raid_act)); + raid_act.action = Action; + raid_act.volume_bus = VolumeBus; + raid_act.volume_id = VolumeID; + raid_act.phys_disk_num = PhysDiskNum; + raid_act.action_data_word = ActionDataWord; + if (buf != NULL && len != 0) { + raid_act.buf = buf; + raid_act.len = len; + raid_act.write = write; + } + + if (ioctl(fd, MPTIO_RAID_ACTION, &raid_act) < 0) + return (-1); + + if (!IOC_STATUS_SUCCESS(raid_act.ioc_status)) { + if (IOCStatus != NULL) { + *IOCStatus = raid_act.ioc_status; + return (0); + } + warnx("RAID action failed: %s", + mpt_ioc_status(raid_act.ioc_status)); + errno = EIO; + return (-1); + } + + if (ActionStatus != NULL) + *ActionStatus = raid_act.action_status; + if (raid_act.action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS) { + if (ActionStatus != NULL) + return (0); + warnx("RAID action failed: %s", + mpt_raid_status(raid_act.action_status)); + errno = EIO; + return (-1); + } + + if (VolumeStatus != NULL) + *((U32 *)VolumeStatus) = raid_act.volume_status; + if (ActionData != NULL) + bcopy(raid_act.action_data, ActionData, datalen); + return (0); +} + +int +mpt_open(int unit) +{ + char path[MAXPATHLEN]; + + snprintf(path, sizeof(path), "/dev/mpt%d", unit); + return (open(path, O_RDWR)); +} + +int +mpt_table_handler(struct mptutil_command **start, struct mptutil_command **end, + int ac, char **av) +{ + struct mptutil_command **cmd; + + if (ac < 2) { + warnx("The %s command requires a sub-command.", av[0]); + return (EINVAL); + } + for (cmd = start; cmd < end; cmd++) { + if (strcmp((*cmd)->name, av[1]) == 0) + return ((*cmd)->handler(ac - 1, av + 1)); + } + + warnx("%s is not a valid sub-command of %s.", av[1], av[0]); + return (ENOENT); +} + +#ifdef DEBUG +void +hexdump(const void *ptr, int length, const char *hdr, int flags) +{ + int i, j, k; + int cols; + const unsigned char *cp; + char delim; + + if ((flags & HD_DELIM_MASK) != 0) + delim = (flags & HD_DELIM_MASK) >> 8; + else + delim = ' '; + + if ((flags & HD_COLUMN_MASK) != 0) + cols = flags & HD_COLUMN_MASK; + else + cols = 16; + + cp = ptr; + for (i = 0; i < length; i+= cols) { + if (hdr != NULL) + printf("%s", hdr); + + if ((flags & HD_OMIT_COUNT) == 0) + printf("%04x ", i); + + if ((flags & HD_OMIT_HEX) == 0) { + for (j = 0; j < cols; j++) { + k = i + j; + if (k < length) + printf("%c%02x", delim, cp[k]); + else + printf(" "); + } + } + + if ((flags & HD_OMIT_CHARS) == 0) { + printf(" |"); + for (j = 0; j < cols; j++) { + k = i + j; + if (k >= length) + printf(" "); + else if (cp[k] >= ' ' && cp[k] <= '~') + printf("%c", cp[k]); + else + printf("."); + } + printf("|"); + } + printf("\n"); + } +} +#endif diff --git a/usr.sbin/mptutil/mpt_config.c b/usr.sbin/mptutil/mpt_config.c new file mode 100644 index 00000000000..3874df30137 --- /dev/null +++ b/usr.sbin/mptutil/mpt_config.c @@ -0,0 +1,1160 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 +__RCSID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif +#include +#include +#include +#include +#include "mptutil.h" + +#ifdef DEBUG +static void dump_config(CONFIG_PAGE_RAID_VOL_0 *vol); +#endif + +#define powerof2(x) ((((x)-1)&(x))==0) + +static long +dehumanize(const char *value) +{ + char *vtp; + long iv; + + if (value == NULL) + return (0); + iv = strtoq(value, &vtp, 0); + if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) { + return (0); + } + switch (vtp[0]) { + case 't': case 'T': + iv *= 1024; + case 'g': case 'G': + iv *= 1024; + case 'm': case 'M': + iv *= 1024; + case 'k': case 'K': + iv *= 1024; + case '\0': + break; + default: + return (0); + } + return (iv); +} + +/* + * Lock the volume by opening its /dev device read/write. This will + * only work if nothing else has it opened (including mounts). We + * leak the fd on purpose since this application is not long-running. + */ +int +mpt_lock_volume(U8 VolumeBus, U8 VolumeID) +{ + char path[MAXPATHLEN]; + struct mpt_query_disk qd; + int error, vfd; + + error = mpt_query_disk(VolumeBus, VolumeID, &qd); + if (error == ENOENT) + /* + * This means there isn't a CAM device associated with + * the volume, and thus it is already implicitly + * locked, so just return. + */ + return (0); + if (error) { + errno = error; + warn("Unable to lookup volume device name"); + return (-1); + } + snprintf(path, sizeof(path), "%s%s", _PATH_DEV, qd.devname); + vfd = open(path, O_RDWR); + if (vfd < 0) { + warn("Unable to lock volume %s", qd.devname); + return (-1); + } + return (0); +} + +static int +mpt_lock_physdisk(struct mpt_standalone_disk *disk) +{ + char path[MAXPATHLEN]; + int dfd; + + snprintf(path, sizeof(path), "%s%s", _PATH_DEV, disk->devname); + dfd = open(path, O_RDWR); + if (dfd < 0) { + warn("Unable to lock disk %s", disk->devname); + return (-1); + } + return (0); +} + +static int +mpt_lookup_standalone_disk(const char *name, struct mpt_standalone_disk *disks, + int ndisks, int *index) +{ + char *cp; + long bus, id; + int i; + + /* Check for a raw : string. */ + bus = strtol(name, &cp, 0); + if (*cp == ':') { + id = strtol(cp + 1, &cp, 0); + if (*cp == '\0') { + if (bus < 0 || bus > 0xff || id < 0 || id > 0xff) { + errno = EINVAL; + return (-1); + } + for (i = 0; i < ndisks; i++) { + if (disks[i].bus == (U8)bus && + disks[i].target == (U8)id) { + *index = i; + return (0); + } + } + errno = ENOENT; + return (-1); + } + } + + if (name[0] == 'd' && name[1] == 'a') { + for (i = 0; i < ndisks; i++) { + if (strcmp(name, disks[i].devname) == 0) { + *index = i; + return (0); + } + } + errno = ENOENT; + return (-1); + } + + errno = EINVAL; + return (-1); +} + +/* + * Mark a standalone disk as being a physical disk. + */ +static int +mpt_create_physdisk(int fd, struct mpt_standalone_disk *disk, U8 *PhysDiskNum) +{ + CONFIG_PAGE_HEADER header; + CONFIG_PAGE_RAID_PHYS_DISK_0 *config_page; + U32 ActionData; + + if (mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK, + 0, 0, &header, NULL) < 0) + return (-1); + if (header.PageVersion > MPI_RAIDPHYSDISKPAGE0_PAGEVERSION) { + warnx("Unsupported RAID physdisk page 0 version %d", + header.PageVersion); + errno = EOPNOTSUPP; + return (-1); + } + config_page = calloc(1, sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0)); + config_page->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; + config_page->Header.PageNumber = 0; + config_page->Header.PageLength = sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0) / + 4; + config_page->PhysDiskIOC = 0; /* XXX */ + config_page->PhysDiskBus = disk->bus; + config_page->PhysDiskID = disk->target; + + /* XXX: Enclosure info for PhysDiskSettings? */ + if (mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_PHYSDISK, 0, 0, 0, 0, + config_page, sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0), NULL, + &ActionData, sizeof(ActionData), NULL, NULL, 1) < 0) + return (-1); + *PhysDiskNum = ActionData & 0xff; + return (0); +} + +static int +mpt_delete_physdisk(int fd, U8 PhysDiskNum) +{ + + return (mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_PHYSDISK, 0, 0, + PhysDiskNum, 0, NULL, 0, NULL, NULL, 0, NULL, NULL, 0)); +} + +/* + * MPT's firmware does not have a clear command. Instead, we + * implement it by deleting each array and disk by hand. + */ +static int +clear_config(int ac, char **av) +{ + CONFIG_PAGE_IOC_2 *ioc2; + CONFIG_PAGE_IOC_2_RAID_VOL *vol; + CONFIG_PAGE_IOC_3 *ioc3; + IOC_3_PHYS_DISK *disk; + CONFIG_PAGE_IOC_5 *ioc5; + IOC_5_HOT_SPARE *spare; + int ch, fd, i; + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + ioc2 = mpt_read_ioc_page(fd, 2, NULL); + if (ioc2 == NULL) { + warn("Failed to fetch volume list"); + return (errno); + } + + /* Lock all the volumes first. */ + vol = ioc2->RaidVolume; + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { + if (mpt_lock_volume(vol->VolumeBus, vol->VolumeID) < 0) { + warnx("Volume %s is busy and cannot be deleted", + mpt_volume_name(vol->VolumeBus, vol->VolumeID)); + return (EBUSY); + } + } + + printf( + "Are you sure you wish to clear the configuration on mpt%u? [y/N] ", + mpt_unit); + ch = getchar(); + if (ch != 'y' && ch != 'Y') { + printf("\nAborting\n"); + return (0); + } + + /* Delete all the volumes. */ + vol = ioc2->RaidVolume; + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) + if (mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME, + vol->VolumeBus, vol->VolumeID, 0, + MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS | + MPI_RAID_ACTION_ADATA_ZERO_LBA0, NULL, 0, NULL, NULL, 0, + NULL, NULL, 0) < 0) + warn("Failed to delete volume %s", + mpt_volume_name(vol->VolumeBus, vol->VolumeID)); + free(ioc2); + + /* Delete all the spares. */ + ioc5 = mpt_read_ioc_page(fd, 5, NULL); + if (ioc5 == NULL) + warn("Failed to fetch spare list"); + else { + spare = ioc5->HotSpare; + for (i = 0; i < ioc5->NumHotSpares; spare++, i++) + if (mpt_delete_physdisk(fd, spare->PhysDiskNum) < 0) + warn("Failed to delete physical disk %d", + spare->PhysDiskNum); + free(ioc5); + } + + /* Delete any RAID physdisks that may be left. */ + ioc3 = mpt_read_ioc_page(fd, 3, NULL); + if (ioc3 == NULL) + warn("Failed to fetch drive list"); + else { + disk = ioc3->PhysDisk; + for (i = 0; i < ioc3->NumPhysDisks; disk++, i++) + if (mpt_delete_physdisk(fd, disk->PhysDiskNum) < 0) + warn("Failed to delete physical disk %d", + disk->PhysDiskNum); + free(ioc3); + } + + printf("mpt%d: Configuration cleared\n", mpt_unit); + mpt_rescan_bus(-1, -1); + close(fd); + + return (0); +} +MPT_COMMAND(top, clear, clear_config); + +#define RT_RAID0 0 +#define RT_RAID1 1 +#define RT_RAID1E 2 + +static struct raid_type_entry { + const char *name; + int raid_type; +} raid_type_table[] = { + { "raid0", RT_RAID0 }, + { "raid-0", RT_RAID0 }, + { "raid1", RT_RAID1 }, + { "raid-1", RT_RAID1 }, + { "mirror", RT_RAID1 }, + { "raid1e", RT_RAID1E }, + { "raid-1e", RT_RAID1E }, + { NULL, 0 }, +}; + +struct config_id_state { + struct mpt_standalone_disk *sdisks; + struct mpt_drive_list *list; + CONFIG_PAGE_IOC_2 *ioc2; + U8 target_id; + int nsdisks; +}; + +struct drive_info { + CONFIG_PAGE_RAID_PHYS_DISK_0 *info; + struct mpt_standalone_disk *sdisk; +}; + +struct volume_info { + int drive_count; + struct drive_info *drives; +}; + +/* Parse a comma-separated list of drives for a volume. */ +static int +parse_volume(int fd, int raid_type, struct config_id_state *state, + char *volume_str, struct volume_info *info) +{ + struct drive_info *dinfo; + U8 PhysDiskNum; + char *cp; + int count, error, i; + + cp = volume_str; + for (count = 0; cp != NULL; count++) { + cp = strchr(cp, ','); + if (cp != NULL) { + cp++; + if (*cp == ',') { + warnx("Invalid drive list '%s'", volume_str); + return (EINVAL); + } + } + } + + /* Validate the number of drives for this volume. */ + switch (raid_type) { + case RT_RAID0: + if (count < 2) { + warnx("RAID0 requires at least 2 drives in each " + "array"); + return (EINVAL); + } + break; + case RT_RAID1: + if (count != 2) { + warnx("RAID1 requires exactly 2 drives in each " + "array"); + return (EINVAL); + } + break; + case RT_RAID1E: + if (count < 3) { + warnx("RAID1E requires at least 3 drives in each " + "array"); + return (EINVAL); + } + break; + } + + /* Validate each drive. */ + info->drives = calloc(count, sizeof(struct drive_info)); + info->drive_count = count; + for (dinfo = info->drives; (cp = strsep(&volume_str, ",")) != NULL; + dinfo++) { + /* If this drive is already a RAID phys just fetch the info. */ + error = mpt_lookup_drive(state->list, cp, &PhysDiskNum); + if (error == 0) { + dinfo->info = mpt_pd_info(fd, PhysDiskNum, NULL); + if (dinfo->info == NULL) + return (errno); + continue; + } + + /* See if it is a standalone disk. */ + if (mpt_lookup_standalone_disk(cp, state->sdisks, + state->nsdisks, &i) < 0) { + warn("Unable to lookup drive %s", cp); + return (errno); + } + dinfo->sdisk = &state->sdisks[i]; + + /* Lock the disk, we will create phys disk pages later. */ + if (mpt_lock_physdisk(dinfo->sdisk) < 0) + return (errno); + } + + return (0); +} + +/* + * Add RAID physdisk pages for any standalone disks that a volume is + * going to use. + */ +static int +add_drives(int fd, struct volume_info *info, int verbose) +{ + struct drive_info *dinfo; + U8 PhysDiskNum; + int i; + + for (i = 0, dinfo = info->drives; i < info->drive_count; + i++, dinfo++) { + if (dinfo->info == NULL) { + if (mpt_create_physdisk(fd, dinfo->sdisk, + &PhysDiskNum) < 0) { + warn( + "Failed to create physical disk page for %s", + dinfo->sdisk->devname); + return (errno); + } + if (verbose) + printf("Added drive %s with PhysDiskNum %u\n", + dinfo->sdisk->devname, PhysDiskNum); + + dinfo->info = mpt_pd_info(fd, PhysDiskNum, NULL); + if (dinfo->info == NULL) + return (errno); + } + } + return (0); +} + +/* + * Find the next free target ID assuming that 'target_id' is the last + * one used. 'target_id' should be 0xff for the initial test. + */ +static U8 +find_next_volume(struct config_id_state *state) +{ + CONFIG_PAGE_IOC_2_RAID_VOL *vol; + int i; + +restart: + /* Assume the current one is used. */ + state->target_id++; + + /* Search drives first. */ + for (i = 0; i < state->nsdisks; i++) + if (state->sdisks[i].target == state->target_id) + goto restart; + for (i = 0; i < state->list->ndrives; i++) + if (state->list->drives[i]->PhysDiskID == state->target_id) + goto restart; + + /* Seach volumes second. */ + vol = state->ioc2->RaidVolume; + for (i = 0; i < state->ioc2->NumActiveVolumes; vol++, i++) + if (vol->VolumeID == state->target_id) + goto restart; + + return (state->target_id); +} + +/* Create a volume and populate it with drives. */ +static CONFIG_PAGE_RAID_VOL_0 * +build_volume(int fd, struct volume_info *info, int raid_type, long stripe_size, + struct config_id_state *state, int verbose) +{ + CONFIG_PAGE_HEADER header; + CONFIG_PAGE_RAID_VOL_0 *vol; + RAID_VOL0_PHYS_DISK *rdisk; + struct drive_info *dinfo; + U32 MinLBA; + uint64_t MaxLBA; + size_t page_size; + int i; + + if (mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME, + 0, 0, &header, NULL) < 0) + return (NULL); + if (header.PageVersion > MPI_RAIDVOLPAGE0_PAGEVERSION) { + warnx("Unsupported RAID volume page 0 version %d", + header.PageVersion); + errno = EOPNOTSUPP; + return (NULL); + } + page_size = sizeof(CONFIG_PAGE_RAID_VOL_0) + + sizeof(RAID_VOL0_PHYS_DISK) * (info->drive_count - 1); + vol = calloc(1, page_size); + + /* Header */ + vol->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME; + vol->Header.PageNumber = 0; + vol->Header.PageLength = page_size / 4; + + /* Properties */ + vol->VolumeID = find_next_volume(state); + vol->VolumeBus = 0; + vol->VolumeIOC = 0; /* XXX */ + vol->VolumeStatus.Flags = MPI_RAIDVOL0_STATUS_FLAG_ENABLED; + vol->VolumeStatus.State = MPI_RAIDVOL0_STATUS_STATE_OPTIMAL; + vol->VolumeSettings.Settings = MPI_RAIDVOL0_SETTING_USE_DEFAULTS; + vol->VolumeSettings.HotSparePool = MPI_RAID_HOT_SPARE_POOL_0; + vol->NumPhysDisks = info->drive_count; + + /* Find the smallest drive. */ + MinLBA = info->drives[0].info->MaxLBA; + for (i = 1; i < info->drive_count; i++) + if (info->drives[i].info->MaxLBA < MinLBA) + MinLBA = info->drives[i].info->MaxLBA; + + /* + * Now chop off 512MB at the end to leave room for the + * metadata. The controller might only use 64MB, but we just + * chop off the max to be simple. + */ + MinLBA -= (512 * 1024 * 1024) / 512; + + switch (raid_type) { + case RT_RAID0: + vol->VolumeType = MPI_RAID_VOL_TYPE_IS; + vol->StripeSize = stripe_size / 512; + MaxLBA = MinLBA * info->drive_count; + break; + case RT_RAID1: + vol->VolumeType = MPI_RAID_VOL_TYPE_IM; + MaxLBA = MinLBA * (info->drive_count / 2); + break; + case RT_RAID1E: + vol->VolumeType = MPI_RAID_VOL_TYPE_IME; + vol->StripeSize = stripe_size / 512; + MaxLBA = MinLBA * info->drive_count / 2; + break; + default: + /* Pacify gcc. */ + abort(); + } + + /* + * If the controller doesn't support 64-bit addressing and the + * new volume is larger than 2^32 blocks, warn the user and + * truncate the volume. + */ + if (MaxLBA >> 32 != 0 && + !(state->ioc2->CapabilitiesFlags & + MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING)) { + warnx( + "Controller does not support volumes > 2TB, truncating volume."); + MaxLBA = 0xffffffff; + } + vol->MaxLBA = MaxLBA; + vol->MaxLBAHigh = MaxLBA >> 32; + + /* Populate drives. */ + for (i = 0, dinfo = info->drives, rdisk = vol->PhysDisk; + i < info->drive_count; i++, dinfo++, rdisk++) { + if (verbose) + printf("Adding drive %u (%u:%u) to volume %u:%u\n", + dinfo->info->PhysDiskNum, dinfo->info->PhysDiskBus, + dinfo->info->PhysDiskID, vol->VolumeBus, + vol->VolumeID); + if (raid_type == RT_RAID1) { + if (i == 0) + rdisk->PhysDiskMap = + MPI_RAIDVOL0_PHYSDISK_PRIMARY; + else + rdisk->PhysDiskMap = + MPI_RAIDVOL0_PHYSDISK_SECONDARY; + } else + rdisk->PhysDiskMap = i; + rdisk->PhysDiskNum = dinfo->info->PhysDiskNum; + } + + return (vol); +} + +static int +create_volume(int ac, char **av) +{ + CONFIG_PAGE_RAID_VOL_0 *vol; + struct config_id_state state; + struct volume_info *info; + int ch, error, fd, i, raid_type, verbose, quick; + long stripe_size; +#ifdef DEBUG + int dump; +#endif + + if (ac < 2) { + warnx("create: volume type required"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + /* Lookup the RAID type first. */ + raid_type = -1; + for (i = 0; raid_type_table[i].name != NULL; i++) + if (strcasecmp(raid_type_table[i].name, av[1]) == 0) { + raid_type = raid_type_table[i].raid_type; + break; + } + + if (raid_type == -1) { + warnx("Unknown or unsupported volume type %s", av[1]); + return (EINVAL); + } + + /* Parse any options. */ + optind = 2; +#ifdef DEBUG + dump = 0; +#endif + quick = 0; + verbose = 0; + stripe_size = 64 * 1024; + + while ((ch = getopt(ac, av, "dqs:v")) != -1) { + switch (ch) { +#ifdef DEBUG + case 'd': + dump = 1; + break; +#endif + case 'q': + quick = 1; + break; + case 's': + stripe_size = dehumanize(optarg); + if ((stripe_size < 512) || (!powerof2(stripe_size))) { + warnx("Invalid stripe size %s", optarg); + return (EINVAL); + } + break; + case 'v': + verbose = 1; + break; + case '?': + default: + return (EINVAL); + } + } + ac -= optind; + av += optind; + + /* Fetch existing config data. */ + state.ioc2 = mpt_read_ioc_page(fd, 2, NULL); + if (state.ioc2 == NULL) { + warn("Failed to read volume list"); + return (errno); + } + state.list = mpt_pd_list(fd); + if (state.list == NULL) + return (errno); + error = mpt_fetch_disks(fd, &state.nsdisks, &state.sdisks); + if (error) { + warn("Failed to fetch standalone disk list"); + return (error); + } + state.target_id = 0xff; + + /* Parse the drive list. */ + if (ac != 1) { + warnx("Exactly one drive list is required"); + return (EINVAL); + } + info = calloc(1, sizeof(*info)); + error = parse_volume(fd, raid_type, &state, av[0], info); + if (error) + return (error); + + /* Create RAID physdisk pages for standalone disks. */ + error = add_drives(fd, info, verbose); + if (error) + return (error); + + /* Build the volume. */ + vol = build_volume(fd, info, raid_type, stripe_size, &state, verbose); + +#ifdef DEBUG + if (dump) { + dump_config(vol); + goto skip; + } +#endif + + /* Send the new volume to the controller. */ + if (mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_VOLUME, vol->VolumeBus, + vol->VolumeID, 0, quick ? MPI_RAID_ACTION_ADATA_DO_NOT_SYNC : 0, + vol, vol->Header.PageLength * 4, NULL, NULL, 0, NULL, NULL, 1) < + 0) { + warn("Failed to add volume"); + return (errno); + } + +#ifdef DEBUG +skip: +#endif + mpt_rescan_bus(vol->VolumeBus, vol->VolumeID); + + /* Clean up. */ + free(vol); + free(info); + free(state.sdisks); + mpt_free_pd_list(state.list); + free(state.ioc2); + close(fd); + + return (0); +} +MPT_COMMAND(top, create, create_volume); + +static int +delete_volume(int ac, char **av) +{ + U8 VolumeBus, VolumeID; + int fd; + + if (ac != 2) { + warnx("delete: volume required"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { + warn("Invalid volume %s", av[1]); + return (errno); + } + + if (mpt_lock_volume(VolumeBus, VolumeID) < 0) + return (errno); + + if (mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME, VolumeBus, + VolumeID, 0, MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS | + MPI_RAID_ACTION_ADATA_ZERO_LBA0, NULL, 0, NULL, NULL, 0, NULL, + NULL, 0) < 0) { + warn("Failed to delete volume"); + return (errno); + } + + mpt_rescan_bus(-1, -1); + close(fd); + + return (0); +} +MPT_COMMAND(top, delete, delete_volume); + +static int +find_volume_spare_pool(int fd, const char *name, int *pool) +{ + CONFIG_PAGE_RAID_VOL_0 *info; + CONFIG_PAGE_IOC_2 *ioc2; + CONFIG_PAGE_IOC_2_RAID_VOL *vol; + U8 VolumeBus, VolumeID; + int i, j, new_pool, pool_count[7]; + + if (mpt_lookup_volume(fd, name, &VolumeBus, &VolumeID) < 0) { + warn("Invalid volume %s", name); + return (-1); + } + + info = mpt_vol_info(fd, VolumeBus, VolumeID, NULL); + if (info == NULL) + return (-1); + + /* + * Check for an existing pool other than pool 0 (used for + * global spares). + */ + if ((info->VolumeSettings.HotSparePool & ~MPI_RAID_HOT_SPARE_POOL_0) != + 0) { + *pool = 1 << (ffs(info->VolumeSettings.HotSparePool & + ~MPI_RAID_HOT_SPARE_POOL_0) - 1); + return (0); + } + free(info); + + /* + * Try to find a free pool. First, figure out which pools are + * in use. + */ + ioc2 = mpt_read_ioc_page(fd, 2, NULL); + if (ioc2 == NULL) { + warn("Failed to fetch volume list"); + return (-1); + } + bzero(pool_count, sizeof(pool_count)); + vol = ioc2->RaidVolume; + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { + info = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, NULL); + if (info == NULL) + return (-1); + for (j = 0; j < 7; j++) + if (info->VolumeSettings.HotSparePool & (1 << (j + 1))) + pool_count[j]++; + free(info); + } + free(ioc2); + + /* Find the pool with the lowest use count. */ + new_pool = 0; + for (i = 1; i < 7; i++) + if (pool_count[i] < pool_count[new_pool]) + new_pool = i; + new_pool++; + + /* Add this pool to the volume. */ + info = mpt_vol_info(fd, VolumeBus, VolumeID, NULL); + if (info == NULL) + return (-1); + info->VolumeSettings.HotSparePool |= (1 << new_pool); + if (mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS, + VolumeBus, VolumeID, 0, *(U32 *)&info->VolumeSettings, NULL, 0, + NULL, NULL, 0, NULL, NULL, 0) < 0) { + warnx("Failed to add spare pool %d to %s", new_pool, + mpt_volume_name(VolumeBus, VolumeID)); + return (-1); + } + free(info); + + *pool = (1 << new_pool); + return (0); +} + +static int +add_spare(int ac, char **av) +{ + CONFIG_PAGE_RAID_PHYS_DISK_0 *info; + struct mpt_standalone_disk *sdisks; + struct mpt_drive_list *list; + U8 PhysDiskNum; + int error, fd, i, nsdisks, pool; + + if (ac < 2) { + warnx("add spare: drive required"); + return (EINVAL); + } + if (ac > 3) { + warnx("add spare: extra arguments"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + if (ac == 3) { + if (find_volume_spare_pool(fd, av[2], &pool) < 0) + return (errno); + } else + pool = MPI_RAID_HOT_SPARE_POOL_0; + + list = mpt_pd_list(fd); + if (list == NULL) + return (errno); + + error = mpt_lookup_drive(list, av[1], &PhysDiskNum); + if (error) { + error = mpt_fetch_disks(fd, &nsdisks, &sdisks); + if (error != 0) { + warn("Failed to fetch standalone disk list"); + return (error); + } + + if (mpt_lookup_standalone_disk(av[1], sdisks, nsdisks, &i) < + 0) { + warn("Unable to lookup drive %s", av[1]); + return (errno); + } + + if (mpt_lock_physdisk(&sdisks[i]) < 0) + return (errno); + + if (mpt_create_physdisk(fd, &sdisks[i], &PhysDiskNum) < 0) { + warn("Failed to create physical disk page"); + return (errno); + } + free(sdisks); + } + mpt_free_pd_list(list); + + info = mpt_pd_info(fd, PhysDiskNum, NULL); + if (info == NULL) { + warn("Failed to fetch drive info"); + return (errno); + } + + info->PhysDiskSettings.HotSparePool = pool; + error = mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_PHYSDISK_SETTINGS, 0, + 0, PhysDiskNum, *(U32 *)&info->PhysDiskSettings, NULL, 0, NULL, + NULL, 0, NULL, NULL, 0); + if (error) { + warn("Failed to assign spare"); + return (errno); + } + + free(info); + close(fd); + + return (0); +} +MPT_COMMAND(top, add, add_spare); + +static int +remove_spare(int ac, char **av) +{ + CONFIG_PAGE_RAID_PHYS_DISK_0 *info; + struct mpt_drive_list *list; + U8 PhysDiskNum; + int error, fd; + + if (ac != 2) { + warnx("remove spare: drive required"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + list = mpt_pd_list(fd); + if (list == NULL) + return (errno); + + error = mpt_lookup_drive(list, av[1], &PhysDiskNum); + if (error) { + warn("Failed to find drive %s", av[1]); + return (error); + } + mpt_free_pd_list(list); + + + info = mpt_pd_info(fd, PhysDiskNum, NULL); + if (info == NULL) { + warn("Failed to fetch drive info"); + return (errno); + } + + if (info->PhysDiskSettings.HotSparePool == 0) { + warnx("Drive %u is not a hot spare", PhysDiskNum); + return (EINVAL); + } + + if (mpt_delete_physdisk(fd, PhysDiskNum) < 0) { + warn("Failed to delete physical disk page"); + return (errno); + } + + mpt_rescan_bus(info->PhysDiskBus, info->PhysDiskID); + free(info); + close(fd); + + return (0); +} +MPT_COMMAND(top, remove, remove_spare); + +#ifdef DEBUG +MPT_TABLE(top, pd); + +static int +pd_create(int ac, char **av) +{ + struct mpt_standalone_disk *disks; + int error, fd, i, ndisks; + U8 PhysDiskNum; + + if (ac != 2) { + warnx("pd create: drive required"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + error = mpt_fetch_disks(fd, &ndisks, &disks); + if (error != 0) { + warn("Failed to fetch standalone disk list"); + return (error); + } + + if (mpt_lookup_standalone_disk(av[1], disks, ndisks, &i) < 0) { + warn("Unable to lookup drive"); + return (errno); + } + + if (mpt_lock_physdisk(&disks[i]) < 0) + return (errno); + + if (mpt_create_physdisk(fd, &disks[i], &PhysDiskNum) < 0) { + warn("Failed to create physical disk page"); + return (errno); + } + free(disks); + + printf("Added drive %s with PhysDiskNum %u\n", av[1], PhysDiskNum); + + close(fd); + + return (0); +} +MPT_COMMAND(pd, create, pd_create); + +static int +pd_delete(int ac, char **av) +{ + CONFIG_PAGE_RAID_PHYS_DISK_0 *info; + struct mpt_drive_list *list; + int fd; + U8 PhysDiskNum; + + if (ac != 2) { + warnx("pd delete: drive required"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + list = mpt_pd_list(fd); + if (list == NULL) + return (errno); + + if (mpt_lookup_drive(list, av[1], &PhysDiskNum) < 0) { + warn("Failed to find drive %s", av[1]); + return (errno); + } + mpt_free_pd_list(list); + + info = mpt_pd_info(fd, PhysDiskNum, NULL); + if (info == NULL) { + warn("Failed to fetch drive info"); + return (errno); + } + + if (mpt_delete_physdisk(fd, PhysDiskNum) < 0) { + warn("Failed to delete physical disk page"); + return (errno); + } + + mpt_rescan_bus(info->PhysDiskBus, info->PhysDiskID); + free(info); + close(fd); + + return (0); +} +MPT_COMMAND(pd, delete, pd_delete); + +/* Display raw data about a volume config. */ +static void +dump_config(CONFIG_PAGE_RAID_VOL_0 *vol) +{ + int i; + + printf("Volume Configuration (Debug):\n"); + printf( + " Page Header: Type 0x%02x Number 0x%02x Length 0x%02x(%u) Version 0x%02x\n", + vol->Header.PageType, vol->Header.PageNumber, + vol->Header.PageLength, vol->Header.PageLength * 4, + vol->Header.PageVersion); + printf(" Address: %d:%d IOC %d\n", vol->VolumeBus, vol->VolumeID, + vol->VolumeIOC); + printf(" Type: %d (%s)\n", vol->VolumeType, + mpt_raid_level(vol->VolumeType)); + printf(" Status: %s (Flags 0x%02x)\n", + mpt_volstate(vol->VolumeStatus.State), vol->VolumeStatus.Flags); + printf(" Settings: 0x%04x (Spare Pools 0x%02x)\n", + vol->VolumeSettings.Settings, vol->VolumeSettings.HotSparePool); + printf(" MaxLBA: %ju\n", (uintmax_t)vol->MaxLBAHigh << 32 | + vol->MaxLBA); + printf(" Stripe Size: %ld\n", (long)vol->StripeSize * 512); + printf(" %d Disks:\n", vol->NumPhysDisks); + + for (i = 0; i < vol->NumPhysDisks; i++) + printf(" Disk %d: Num 0x%02x Map 0x%02x\n", i, + vol->PhysDisk[i].PhysDiskNum, vol->PhysDisk[i].PhysDiskMap); +} + +static int +debug_config(int ac, char **av) +{ + CONFIG_PAGE_RAID_VOL_0 *vol; + U8 VolumeBus, VolumeID; + int fd; + + if (ac != 2) { + warnx("debug: volume required"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { + warn("Invalid volume: %s", av[1]); + return (errno); + } + + vol = mpt_vol_info(fd, VolumeBus, VolumeID, NULL); + if (vol == NULL) { + warn("Failed to get volume info"); + return (errno); + } + + dump_config(vol); + free(vol); + close(fd); + + return (0); +} +MPT_COMMAND(top, debug, debug_config); +#endif diff --git a/usr.sbin/mptutil/mpt_drive.c b/usr.sbin/mptutil/mpt_drive.c new file mode 100644 index 00000000000..e941b967e5b --- /dev/null +++ b/usr.sbin/mptutil/mpt_drive.c @@ -0,0 +1,395 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 +__RCSID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mptutil.h" + +const char * +mpt_pdstate(CONFIG_PAGE_RAID_PHYS_DISK_0 *info) +{ + static char buf[16]; + + switch (info->PhysDiskStatus.State) { + case MPI_PHYSDISK0_STATUS_ONLINE: + if ((info->PhysDiskStatus.Flags & + MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC) && + info->PhysDiskSettings.HotSparePool == 0) + return ("REBUILD"); + else + return ("ONLINE"); + case MPI_PHYSDISK0_STATUS_MISSING: + return ("MISSING"); + case MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE: + return ("NOT COMPATIBLE"); + case MPI_PHYSDISK0_STATUS_FAILED: + return ("FAILED"); + case MPI_PHYSDISK0_STATUS_INITIALIZING: + return ("INITIALIZING"); + case MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED: + return ("OFFLINE REQUESTED"); + case MPI_PHYSDISK0_STATUS_FAILED_REQUESTED: + return ("FAILED REQUESTED"); + case MPI_PHYSDISK0_STATUS_OTHER_OFFLINE: + return ("OTHER OFFLINE"); + default: + sprintf(buf, "PSTATE 0x%02x", info->PhysDiskStatus.State); + return (buf); + } +} + +/* + * There are several ways to enumerate physical disks. Unfortunately, + * none of them are truly complete, so we have to build a union of all of + * them. Specifically: + * + * - IOC2 : This gives us a list of volumes, and by walking the volumes we + * can enumerate all of the drives attached to volumes including + * online drives and failed drives. + * - IOC3 : This gives us a list of all online physical drives including + * drives that are not part of a volume nor a spare drive. It + * does not include any failed drives. + * - IOC5 : This gives us a list of all spare drives including failed + * spares. + * + * The specific edge cases are that 1) a failed volume member can only be + * found via IOC2, 2) a drive that is neither a volume member nor a spare + * can only be found via IOC3, and 3) a failed spare can only be found via + * IOC5. + * + * To handle this, walk all of the three lists and use the following + * routine to add each drive encountered. It quietly succeeds if the + * drive is already present in the list. It also sorts the list as it + * inserts new drives. + */ +static int +mpt_pd_insert(int fd, struct mpt_drive_list *list, U8 PhysDiskNum) +{ + int i, j; + + /* + * First, do a simple linear search to see if we have already + * seen this drive. + */ + for (i = 0; i < list->ndrives; i++) { + if (list->drives[i]->PhysDiskNum == PhysDiskNum) + return (0); + if (list->drives[i]->PhysDiskNum > PhysDiskNum) + break; + } + + /* + * 'i' is our slot for the 'new' drive. Make room and then + * read the drive info. + */ + for (j = list->ndrives - 1; j >= i; j--) + list->drives[j + 1] = list->drives[j]; + list->drives[i] = mpt_pd_info(fd, PhysDiskNum, NULL); + if (list->drives[i] == NULL) + return (-1); + list->ndrives++; + return (0); +} + +struct mpt_drive_list * +mpt_pd_list(int fd) +{ + CONFIG_PAGE_IOC_2 *ioc2; + CONFIG_PAGE_IOC_2_RAID_VOL *vol; + CONFIG_PAGE_RAID_VOL_0 **volumes; + RAID_VOL0_PHYS_DISK *rdisk; + CONFIG_PAGE_IOC_3 *ioc3; + IOC_3_PHYS_DISK *disk; + CONFIG_PAGE_IOC_5 *ioc5; + IOC_5_HOT_SPARE *spare; + struct mpt_drive_list *list; + int count, i, j; + + ioc2 = mpt_read_ioc_page(fd, 2, NULL); + if (ioc2 == NULL) { + warn("Failed to fetch volume list"); + return (NULL); + } + + ioc3 = mpt_read_ioc_page(fd, 3, NULL); + if (ioc3 == NULL) { + warn("Failed to fetch drive list"); + free(ioc2); + return (NULL); + } + + ioc5 = mpt_read_ioc_page(fd, 5, NULL); + if (ioc5 == NULL) { + warn("Failed to fetch spare list"); + free(ioc3); + free(ioc2); + return (NULL); + } + + /* + * Go ahead and read the info for all the volumes. For this + * pass we figure out how many physical drives there are. + */ + volumes = malloc(sizeof(*volumes) * ioc2->NumActiveVolumes); + count = 0; + vol = ioc2->RaidVolume; + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { + volumes[i] = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, + NULL); + if (volumes[i] == NULL) { + warn("Failed to read volume info"); + return (NULL); + } + count += volumes[i]->NumPhysDisks; + } + count += ioc3->NumPhysDisks; + count += ioc5->NumHotSpares; + + /* Walk the various lists enumerating drives. */ + list = malloc(sizeof(*list) + sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0) * + count); + list->ndrives = 0; + + for (i = 0; i < ioc2->NumActiveVolumes; i++) { + rdisk = volumes[i]->PhysDisk; + for (j = 0; j < volumes[i]->NumPhysDisks; rdisk++, j++) + if (mpt_pd_insert(fd, list, rdisk->PhysDiskNum) < 0) + return (NULL); + free(volumes[i]); + } + free(ioc2); + free(volumes); + + spare = ioc5->HotSpare; + for (i = 0; i < ioc5->NumHotSpares; spare++, i++) + if (mpt_pd_insert(fd, list, spare->PhysDiskNum) < 0) + return (NULL); + free(ioc5); + + disk = ioc3->PhysDisk; + for (i = 0; i < ioc3->NumPhysDisks; disk++, i++) + if (mpt_pd_insert(fd, list, disk->PhysDiskNum) < 0) + return (NULL); + free(ioc3); + + return (list); +} + +void +mpt_free_pd_list(struct mpt_drive_list *list) +{ + int i; + + for (i = 0; i < list->ndrives; i++) + free(list->drives[i]); + free(list); +} + +int +mpt_lookup_drive(struct mpt_drive_list *list, const char *drive, + U8 *PhysDiskNum) +{ + long val; + uint8_t bus, id; + char *cp; + + /* Look for a raw device id first. */ + val = strtol(drive, &cp, 0); + if (*cp == '\0') { + if (val < 0 || val > 0xff) + goto bad; + *PhysDiskNum = val; + return (0); + } + + /* Look for a : string. */ + if (*cp == ':') { + if (val < 0 || val > 0xff) + goto bad; + bus = val; + val = strtol(cp + 1, &cp, 0); + if (*cp != '\0') + goto bad; + if (val < 0 || val > 0xff) + goto bad; + id = val; + + for (val = 0; val < list->ndrives; val++) { + if (list->drives[val]->PhysDiskBus == bus && + list->drives[val]->PhysDiskID == id) { + *PhysDiskNum = list->drives[val]->PhysDiskNum; + return (0); + } + } + errno = ENOENT; + return (-1); + } + +bad: + errno = EINVAL; + return (-1); +} + +/* Borrowed heavily from scsi_all.c:scsi_print_inquiry(). */ +const char * +mpt_pd_inq_string(CONFIG_PAGE_RAID_PHYS_DISK_0 *pd_info) +{ + RAID_PHYS_DISK0_INQUIRY_DATA *inq_data; + u_char vendor[9], product[17], revision[5]; + static char inq_string[64]; + + inq_data = &pd_info->InquiryData; + cam_strvis(vendor, inq_data->VendorID, sizeof(inq_data->VendorID), + sizeof(vendor)); + cam_strvis(product, inq_data->ProductID, sizeof(inq_data->ProductID), + sizeof(product)); + cam_strvis(revision, inq_data->ProductRevLevel, + sizeof(inq_data->ProductRevLevel), sizeof(revision)); + + /* Total hack. */ + if (strcmp(vendor, "ATA") == 0) + snprintf(inq_string, sizeof(inq_string), "<%s %s> SATA", + product, revision); + else + snprintf(inq_string, sizeof(inq_string), "<%s %s %s> SAS", + vendor, product, revision); + return (inq_string); +} + +/* Helper function to set a drive to a given state. */ +static int +drive_set_state(char *drive, U8 Action, U8 State, const char *name) +{ + CONFIG_PAGE_RAID_PHYS_DISK_0 *info; + struct mpt_drive_list *list; + U8 PhysDiskNum; + int fd; + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + list = mpt_pd_list(fd); + if (list == NULL) + return (errno); + + if (mpt_lookup_drive(list, drive, &PhysDiskNum) < 0) { + warn("Failed to find drive %s", drive); + return (errno); + } + mpt_free_pd_list(list); + + /* Get the info for this drive. */ + info = mpt_pd_info(fd, PhysDiskNum, NULL); + if (info == NULL) { + warn("Failed to fetch info for drive %u", PhysDiskNum); + return (errno); + } + + /* Try to change the state. */ + if (info->PhysDiskStatus.State == State) { + warnx("Drive %u is already in the desired state", PhysDiskNum); + return (EINVAL); + } + + if (mpt_raid_action(fd, Action, 0, 0, PhysDiskNum, 0, NULL, 0, NULL, + NULL, 0, NULL, NULL, 0) < 0) { + warn("Failed to set drive %u to %s", PhysDiskNum, name); + return (errno); + } + + free(info); + close(fd); + + return (0); +} + +static int +fail_drive(int ac, char **av) +{ + + if (ac != 2) { + warnx("fail: %s", ac > 2 ? "extra arguments" : + "drive required"); + return (EINVAL); + } + + return (drive_set_state(av[1], MPI_RAID_ACTION_FAIL_PHYSDISK, + MPI_PHYSDISK0_STATUS_FAILED_REQUESTED, "FAILED")); +} +MPT_COMMAND(top, fail, fail_drive); + +static int +online_drive(int ac, char **av) +{ + + if (ac != 2) { + warnx("online: %s", ac > 2 ? "extra arguments" : + "drive required"); + return (EINVAL); + } + + return (drive_set_state(av[1], MPI_RAID_ACTION_PHYSDISK_ONLINE, + MPI_PHYSDISK0_STATUS_ONLINE, "ONLINE")); +} +MPT_COMMAND(top, online, online_drive); + +static int +offline_drive(int ac, char **av) +{ + + if (ac != 2) { + warnx("offline: %s", ac > 2 ? "extra arguments" : + "drive required"); + return (EINVAL); + } + + return (drive_set_state(av[1], MPI_RAID_ACTION_PHYSDISK_OFFLINE, + MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED, "OFFLINE")); +} +MPT_COMMAND(top, offline, offline_drive); diff --git a/usr.sbin/mptutil/mpt_evt.c b/usr.sbin/mptutil/mpt_evt.c new file mode 100644 index 00000000000..4b64352e42d --- /dev/null +++ b/usr.sbin/mptutil/mpt_evt.c @@ -0,0 +1,155 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 +__RCSID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include "mptutil.h" + +static CONFIG_PAGE_LOG_0 * +mpt_get_events(int fd, U16 *IOCStatus) +{ + + return (mpt_read_extended_config_page(fd, MPI_CONFIG_EXTPAGETYPE_LOG, + 0, 0, 0, IOCStatus)); +} + +/* + * 1 2 3 4 5 6 7 + * 1234567890123456789012345678901234567890123456789012345678901234567890 + * < ID> < time > LogSequence, entry->TimeStamp, + entry->LogEntryQualifier); + for (i = 0; i < 14; i++) + printf("%02x ", entry->LogData[i]); + printf("|"); + for (i = 0; i < 14; i++) + printf("%c", isprint(entry->LogData[i]) ? entry->LogData[i] : + '.'); + printf("|\n"); + printf(" "); + for (i = 0; i < 14; i++) + printf("%02x ", entry->LogData[i + 14]); + printf("|"); + for (i = 0; i < 14; i++) + printf("%c", isprint(entry->LogData[i + 14]) ? + entry->LogData[i + 14] : '.'); + printf("|\n"); +} + +static int +event_compare(const void *first, const void *second) +{ + MPI_LOG_0_ENTRY * const *one; + MPI_LOG_0_ENTRY * const *two; + + one = first; + two = second; + return ((*one)->LogSequence - ((*two)->LogSequence)); +} + +static int +show_events(int ac, char **av) +{ + CONFIG_PAGE_LOG_0 *log; + MPI_LOG_0_ENTRY **entries; + int ch, fd, i, num_events, verbose; + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + log = mpt_get_events(fd, NULL); + if (log == NULL) { + warn("Failed to get event log info"); + return (errno); + } + + /* Default settings. */ + verbose = 0; + + /* Parse any options. */ + optind = 1; + while ((ch = getopt(ac, av, "v")) != -1) { + switch (ch) { + case 'v': + verbose = 1; + break; + case '?': + default: + return (EINVAL); + } + } + ac -= optind; + av += optind; + + /* Build a list of valid entries and sort them by sequence. */ + entries = malloc(sizeof(MPI_LOG_0_ENTRY *) * log->NumLogEntries); + num_events = 0; + for (i = 0; i < log->NumLogEntries; i++) { + if (log->LogEntry[i].LogEntryQualifier == + MPI_LOG_0_ENTRY_QUAL_ENTRY_UNUSED) + continue; + entries[num_events] = &log->LogEntry[i]; + num_events++; + } + + qsort(entries, num_events, sizeof(MPI_LOG_0_ENTRY *), event_compare); + + if (num_events == 0) + printf("Event log is empty\n"); + else { + printf(" ID Time Type Log Data\n"); + for (i = 0; i < num_events; i++) + mpt_print_event(entries[i], verbose); + } + + free(entries); + close(fd); + + return (0); +} +MPT_COMMAND(show, events, show_events); diff --git a/usr.sbin/mptutil/mpt_show.c b/usr.sbin/mptutil/mpt_show.c new file mode 100644 index 00000000000..e0b6b74d136 --- /dev/null +++ b/usr.sbin/mptutil/mpt_show.c @@ -0,0 +1,559 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 +__RCSID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mptutil.h" + +MPT_TABLE(top, show); + +#define STANDALONE_STATE "ONLINE" + +static void +format_stripe(char *buf, size_t buflen, U32 stripe) +{ + + humanize_number(buf, buflen, stripe * 512, "", HN_AUTOSCALE, + HN_B | HN_NOSPACE); +} + +static void +display_stripe_map(const char *label, U32 StripeMap) +{ + char stripe[5]; + int comma, i; + + comma = 0; + printf("%s: ", label); + for (i = 0; StripeMap != 0; i++, StripeMap >>= 1) + if (StripeMap & 1) { + format_stripe(stripe, sizeof(stripe), 1 << i); + if (comma) + printf(", "); + printf("%s", stripe); + comma = 1; + } + printf("\n"); +} + +static int +show_adapter(int ac, char **av) +{ + CONFIG_PAGE_MANUFACTURING_0 *man0; + CONFIG_PAGE_IOC_2 *ioc2; + CONFIG_PAGE_IOC_6 *ioc6; + int fd, comma; + + if (ac != 1) { + warnx("show adapter: extra arguments"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + man0 = mpt_read_man_page(fd, 0, NULL); + if (man0 == NULL) { + warn("Failed to get controller info"); + return (errno); + } + if (man0->Header.PageLength < sizeof(*man0) / 4) { + warn("Invalid controller info"); + return (EINVAL); + } + printf("mpt%d Adapter:\n", mpt_unit); + printf(" Board Name: %.16s\n", man0->BoardName); + printf(" Board Assembly: %.16s\n", man0->BoardAssembly); + printf(" Chip Name: %.16s\n", man0->ChipName); + printf(" Chip Revision: %.16s\n", man0->ChipRevision); + + free(man0); + + ioc2 = mpt_read_ioc_page(fd, 2, NULL); + if (ioc2 != NULL) { + printf(" RAID Levels:"); + comma = 0; + if (ioc2->CapabilitiesFlags & + MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT) { + printf(" RAID0"); + comma = 1; + } + if (ioc2->CapabilitiesFlags & + MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT) { + printf("%s RAID1", comma ? "," : ""); + comma = 1; + } + if (ioc2->CapabilitiesFlags & + MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT) { + printf("%s RAID1E", comma ? "," : ""); + comma = 1; + } + if (ioc2->CapabilitiesFlags & + MPI_IOCPAGE2_CAP_FLAGS_RAID_5_SUPPORT) { + printf("%s RAID5", comma ? "," : ""); + comma = 1; + } + if (ioc2->CapabilitiesFlags & + MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT) { + printf("%s RAID6", comma ? "," : ""); + comma = 1; + } + if (ioc2->CapabilitiesFlags & + MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT) { + printf("%s RAID10", comma ? "," : ""); + comma = 1; + } + if (ioc2->CapabilitiesFlags & + MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT) { + printf("%s RAID50", comma ? "," : ""); + comma = 1; + } + if (!comma) + printf(" none"); + printf("\n"); + free(ioc2); + } + + ioc6 = mpt_read_ioc_page(fd, 6, NULL); + if (ioc6 != NULL) { + display_stripe_map(" RAID0 Stripes", + ioc6->SupportedStripeSizeMapIS); + display_stripe_map(" RAID1E Stripes", + ioc6->SupportedStripeSizeMapIME); + printf(" RAID0 Drives/Vol: %u", ioc6->MinDrivesIS); + if (ioc6->MinDrivesIS != ioc6->MaxDrivesIS) + printf("-%u", ioc6->MaxDrivesIS); + printf("\n"); + printf(" RAID1 Drives/Vol: %u", ioc6->MinDrivesIM); + if (ioc6->MinDrivesIM != ioc6->MaxDrivesIM) + printf("-%u", ioc6->MaxDrivesIM); + printf("\n"); + printf("RAID1E Drives/Vol: %u", ioc6->MinDrivesIME); + if (ioc6->MinDrivesIME != ioc6->MaxDrivesIME) + printf("-%u", ioc6->MaxDrivesIME); + printf("\n"); + free(ioc6); + } + + /* TODO: Add an ioctl to fetch IOC_FACTS and print firmware version. */ + + close(fd); + + return (0); +} +MPT_COMMAND(show, adapter, show_adapter); + +static void +print_vol(CONFIG_PAGE_RAID_VOL_0 *info, int state_len) +{ + uint64_t size; + const char *level, *state; + char buf[6], stripe[5]; + + size = ((uint64_t)info->MaxLBAHigh << 32) | info->MaxLBA; + humanize_number(buf, sizeof(buf), (size + 1) * 512, "", HN_AUTOSCALE, + HN_B | HN_NOSPACE | HN_DECIMAL); + if (info->VolumeType == MPI_RAID_VOL_TYPE_IM) + stripe[0] = '\0'; + else + format_stripe(stripe, sizeof(stripe), info->StripeSize); + level = mpt_raid_level(info->VolumeType); + state = mpt_volstate(info->VolumeStatus.State); + if (state_len > 0) + printf("(%6s) %-8s %6s %-*s", buf, level, stripe, state_len, + state); + else if (stripe[0] != '\0') + printf("(%s) %s %s %s", buf, level, stripe, state); + else + printf("(%s) %s %s", buf, level, state); +} + +static void +print_pd(CONFIG_PAGE_RAID_PHYS_DISK_0 *info, int state_len, int location) +{ + const char *inq, *state; + char buf[6]; + + humanize_number(buf, sizeof(buf), ((uint64_t)info->MaxLBA + 1) * 512, + "", HN_AUTOSCALE, HN_B | HN_NOSPACE |HN_DECIMAL); + state = mpt_pdstate(info); + if (state_len > 0) + printf("(%6s) %-*s", buf, state_len, state); + else + printf("(%s) %s", buf, state); + inq = mpt_pd_inq_string(info); + if (inq != NULL) + printf(" %s", inq); + if (!location) + return; + printf(" bus %d id %d", info->PhysDiskBus, info->PhysDiskID); +} + +static void +print_standalone(struct mpt_standalone_disk *disk, int state_len, int location) +{ + char buf[6]; + + humanize_number(buf, sizeof(buf), (disk->maxlba + 1) * 512, + "", HN_AUTOSCALE, HN_B | HN_NOSPACE |HN_DECIMAL); + if (state_len > 0) + printf("(%6s) %-*s", buf, state_len, STANDALONE_STATE); + else + printf("(%s) %s", buf, STANDALONE_STATE); + if (disk->inqstring[0] != '\0') + printf(" %s", disk->inqstring); + if (!location) + return; + printf(" bus %d id %d", disk->bus, disk->target); +} + +static void +print_spare_pools(U8 HotSparePool) +{ + int i; + + if (HotSparePool == 0) { + printf("none"); + return; + } + for (i = 0; HotSparePool != 0; i++) { + if (HotSparePool & 1) { + printf("%d", i); + if (HotSparePool == 1) + break; + printf(", "); + } + HotSparePool >>= 1; + } +} + +static int +show_config(int ac, char **av) +{ + CONFIG_PAGE_IOC_2 *ioc2; + CONFIG_PAGE_IOC_2_RAID_VOL *vol; + CONFIG_PAGE_IOC_5 *ioc5; + IOC_5_HOT_SPARE *spare; + CONFIG_PAGE_RAID_VOL_0 *vinfo; + RAID_VOL0_PHYS_DISK *disk; + CONFIG_PAGE_RAID_VOL_1 *vnames; + CONFIG_PAGE_RAID_PHYS_DISK_0 *pinfo; + struct mpt_standalone_disk *sdisks; + int fd, i, j, nsdisks; + + if (ac != 1) { + warnx("show config: extra arguments"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + /* Get the config from the controller. */ + ioc2 = mpt_read_ioc_page(fd, 2, NULL); + ioc5 = mpt_read_ioc_page(fd, 5, NULL); + if (ioc2 == NULL || ioc5 == NULL) { + warn("Failed to get config"); + return (errno); + } + if (mpt_fetch_disks(fd, &nsdisks, &sdisks) < 0) { + warn("Failed to get standalone drive list"); + return (errno); + } + + /* Dump out the configuration. */ + printf("mpt%d Configuration: %d volumes, %d drives\n", + mpt_unit, ioc2->NumActiveVolumes, ioc2->NumActivePhysDisks + + nsdisks); + vol = ioc2->RaidVolume; + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { + printf(" volume %s ", mpt_volume_name(vol->VolumeBus, + vol->VolumeID)); + vinfo = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, NULL); + if (vinfo == NULL) { + printf("%s UNKNOWN", mpt_raid_level(vol->VolumeType)); + } else + print_vol(vinfo, -1); + vnames = mpt_vol_names(fd, vol->VolumeBus, vol->VolumeID, NULL); + if (vnames != NULL) { + if (vnames->Name[0] != '\0') + printf(" <%s>", vnames->Name); + free(vnames); + } + if (vinfo == NULL) { + printf("\n"); + continue; + } + printf(" spans:\n"); + disk = vinfo->PhysDisk; + for (j = 0; j < vinfo->NumPhysDisks; disk++, j++) { + printf(" drive %u ", disk->PhysDiskNum); + pinfo = mpt_pd_info(fd, disk->PhysDiskNum, NULL); + if (pinfo != NULL) { + print_pd(pinfo, -1, 0); + free(pinfo); + } + printf("\n"); + } + if (vinfo->VolumeSettings.HotSparePool != 0) { + printf(" spare pools: "); + print_spare_pools(vinfo->VolumeSettings.HotSparePool); + printf("\n"); + } + free(vinfo); + } + + spare = ioc5->HotSpare; + for (i = 0; i < ioc5->NumHotSpares; spare++, i++) { + printf(" spare %u ", spare->PhysDiskNum); + pinfo = mpt_pd_info(fd, spare->PhysDiskNum, NULL); + if (pinfo != NULL) { + print_pd(pinfo, -1, 0); + free(pinfo); + } + printf(" backs pool %d\n", ffs(spare->HotSparePool) - 1); + } + for (i = 0; i < nsdisks; i++) { + printf(" drive %s ", sdisks[i].devname); + print_standalone(&sdisks[i], -1, 0); + printf("\n"); + } + free(ioc2); + free(ioc5); + free(sdisks); + close(fd); + + return (0); +} +MPT_COMMAND(show, config, show_config); + +static int +show_volumes(int ac, char **av) +{ + CONFIG_PAGE_IOC_2 *ioc2; + CONFIG_PAGE_IOC_2_RAID_VOL *vol; + CONFIG_PAGE_RAID_VOL_0 **volumes; + CONFIG_PAGE_RAID_VOL_1 *vnames; + int fd, i, len, state_len; + + if (ac != 1) { + warnx("show volumes: extra arguments"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + /* Get the volume list from the controller. */ + ioc2 = mpt_read_ioc_page(fd, 2, NULL); + if (ioc2 == NULL) { + warn("Failed to get volume list"); + return (errno); + } + + /* + * Go ahead and read the info for all the volumes and figure + * out the maximum width of the state field. + */ + volumes = malloc(sizeof(*volumes) * ioc2->NumActiveVolumes); + state_len = strlen("State"); + vol = ioc2->RaidVolume; + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { + volumes[i] = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, + NULL); + if (volumes[i] == NULL) + len = strlen("UNKNOWN"); + else + len = strlen(mpt_volstate( + volumes[i]->VolumeStatus.State)); + if (len > state_len) + state_len = len; + } + printf("mpt%d Volumes:\n", mpt_unit); + printf(" Id Size Level Stripe "); + len = state_len - strlen("State"); + for (i = 0; i < (len + 1) / 2; i++) + printf(" "); + printf("State"); + for (i = 0; i < len / 2; i++) + printf(" "); + printf(" Write-Cache Name\n"); + vol = ioc2->RaidVolume; + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { + printf("%6s ", mpt_volume_name(vol->VolumeBus, vol->VolumeID)); + if (volumes[i] != NULL) + print_vol(volumes[i], state_len); + else + printf(" %-8s %-*s", + mpt_raid_level(vol->VolumeType), state_len, + "UNKNOWN"); + if (volumes[i] != NULL) { + if (volumes[i]->VolumeSettings.Settings & + MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE) + printf(" Enabled "); + else + printf(" Disabled "); + } else + printf(" "); + free(volumes[i]); + vnames = mpt_vol_names(fd, vol->VolumeBus, vol->VolumeID, NULL); + if (vnames != NULL) { + if (vnames->Name[0] != '\0') + printf(" <%s>", vnames->Name); + free(vnames); + } + printf("\n"); + } + free(ioc2); + close(fd); + + return (0); +} +MPT_COMMAND(show, volumes, show_volumes); + +static int +show_drives(int ac, char **av) +{ + struct mpt_drive_list *list; + struct mpt_standalone_disk *sdisks; + int fd, i, len, nsdisks, state_len; + + if (ac != 1) { + warnx("show drives: extra arguments"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + /* Get the drive list. */ + list = mpt_pd_list(fd); + if (list == NULL) { + warn("Failed to get drive list"); + return (errno); + } + + /* Fetch the list of standalone disks for this controller. */ + state_len = 0; + if (mpt_fetch_disks(fd, &nsdisks, &sdisks) != 0) { + nsdisks = 0; + sdisks = NULL; + } + if (nsdisks != 0) + state_len = strlen(STANDALONE_STATE); + + /* Walk the drive list to determine width of state column. */ + for (i = 0; i < list->ndrives; i++) { + len = strlen(mpt_pdstate(list->drives[i])); + if (len > state_len) + state_len = len; + } + + /* List the drives. */ + printf("mpt%d Physical Drives:\n", mpt_unit); + for (i = 0; i < list->ndrives; i++) { + printf("%4u ", list->drives[i]->PhysDiskNum); + print_pd(list->drives[i], state_len, 1); + printf("\n"); + } + mpt_free_pd_list(list); + for (i = 0; i < nsdisks; i++) { + printf("%4s ", sdisks[i].devname); + print_standalone(&sdisks[i], state_len, 1); + printf("\n"); + } + free(sdisks); + + close(fd); + + return (0); +} +MPT_COMMAND(show, drives, show_drives); + +#ifdef DEBUG +static int +show_physdisks(int ac, char **av) +{ + CONFIG_PAGE_RAID_PHYS_DISK_0 *pinfo; + U16 IOCStatus; + int fd, i; + + if (ac != 1) { + warnx("show drives: extra arguments"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + /* Try to find each possible phys disk page. */ + for (i = 0; i <= 0xff; i++) { + pinfo = mpt_pd_info(fd, i, &IOCStatus); + if (pinfo == NULL) { + if (IOCStatus != MPI_IOCSTATUS_CONFIG_INVALID_PAGE) + warnx("mpt_pd_info(%d): %s", i, + mpt_ioc_status(IOCStatus)); + continue; + } + printf("%3u ", i); + print_pd(pinfo, -1, 1); + printf("\n"); + } + + close(fd); + + return (0); +} +MPT_COMMAND(show, pd, show_physdisks); +#endif diff --git a/usr.sbin/mptutil/mpt_volume.c b/usr.sbin/mptutil/mpt_volume.c new file mode 100644 index 00000000000..04adcb7c987 --- /dev/null +++ b/usr.sbin/mptutil/mpt_volume.c @@ -0,0 +1,248 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 +__RCSID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mptutil.h" + +MPT_TABLE(top, volume); + +const char * +mpt_volstate(U8 State) +{ + static char buf[16]; + + switch (State) { + case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL: + return ("OPTIMAL"); + case MPI_RAIDVOL0_STATUS_STATE_DEGRADED: + return ("DEGRADED"); + case MPI_RAIDVOL0_STATUS_STATE_FAILED: + return ("FAILED"); + case MPI_RAIDVOL0_STATUS_STATE_MISSING: + return ("MISSING"); + default: + sprintf(buf, "VSTATE 0x%02x", State); + return (buf); + } +} + +static int +volume_name(int ac, char **av) +{ + CONFIG_PAGE_RAID_VOL_1 *vnames; + U8 VolumeBus, VolumeID; + int fd; + + if (ac != 3) { + warnx("name: volume and name required"); + return (EINVAL); + } + + if (strlen(av[2]) >= sizeof(vnames->Name)) { + warnx("name: new name is too long"); + return (ENOSPC); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { + warn("Invalid volume: %s", av[1]); + return (errno); + } + + vnames = mpt_vol_names(fd, VolumeBus, VolumeID, NULL); + if (vnames == NULL) { + warn("Failed to fetch volume names"); + return (errno); + } + + if (vnames->Header.PageType != MPI_CONFIG_PAGEATTR_CHANGEABLE) { + warnx("Volume name is read only"); + return (EOPNOTSUPP); + } + printf("mpt%u changing volume %s name from \"%s\" to \"%s\"\n", + mpt_unit, mpt_volume_name(VolumeBus, VolumeID), vnames->Name, + av[2]); + bzero(vnames->Name, sizeof(vnames->Name)); + strcpy(vnames->Name, av[2]); + + if (mpt_write_config_page(fd, vnames, NULL) < 0) { + warn("Failed to set volume name"); + return (errno); + } + + free(vnames); + close(fd); + + return (0); +} +MPT_COMMAND(top, name, volume_name); + +static int +volume_status(int ac, char **av) +{ + MPI_RAID_VOL_INDICATOR prog; + RAID_VOL0_STATUS VolumeStatus; + uint64_t total, remaining; + float pct; + U8 VolumeBus, VolumeID; + int fd; + + if (ac != 2) { + warnx("volume status: %s", ac > 2 ? "extra arguments" : + "volume required"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { + warn("Invalid volume: %s", av[1]); + return (errno); + } + + if (mpt_raid_action(fd, MPI_RAID_ACTION_INDICATOR_STRUCT, VolumeBus, + VolumeID, 0, 0, NULL, 0, &VolumeStatus, (U32 *)&prog, sizeof(prog), + NULL, NULL, 0) < 0) { + warn("Fetching volume status failed"); + return (errno); + } + + printf("Volume %s status:\n", mpt_volume_name(VolumeBus, VolumeID)); + printf(" state: %s\n", mpt_volstate(VolumeStatus.State)); + printf(" flags:"); + if (VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) + printf(" ENABLED"); + else + printf(" DISABLED"); + if (VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED) + printf(", QUIESCED"); + if (VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) + printf(", REBUILDING"); + if (VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE) + printf(", INACTIVE"); + if (VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL) + printf(", BAD BLOCK TABLE FULL"); + printf("\n"); + if (VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) { + total = (uint64_t)prog.TotalBlocks.High << 32 | + prog.TotalBlocks.Low; + remaining = (uint64_t)prog.BlocksRemaining.High << 32 | + prog.BlocksRemaining.Low; + pct = (float)(total - remaining) * 100 / total; + printf(" resync: %.2f%% complete\n", pct); + } + + close(fd); + return (0); +} +MPT_COMMAND(volume, status, volume_status); + +static int +volume_cache(int ac, char **av) +{ + CONFIG_PAGE_RAID_VOL_0 *volume; + U32 Settings, NewSettings; + U8 VolumeBus, VolumeID; + char *s1; + int fd; + + if (ac != 3) { + warnx("volume cache: %s", ac > 3 ? "extra arguments" : + "volume required"); + return (EINVAL); + } + + for (s1 = av[2]; *s1 != '\0'; s1++) + *s1 = tolower(*s1); + if ((strcmp(av[2], "enable")) && (strcmp(av[2], "enabled")) && + (strcmp(av[2], "disable")) && (strcmp(av[2], "disabled"))) { + warnx("volume cache: invalid flag, must be 'enable' or 'disable'\n"); + return (EINVAL); + } + + fd = mpt_open(mpt_unit); + if (fd < 0) { + warn("mpt_open"); + return (errno); + } + + if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { + warn("Invalid volume: %s", av[1]); + return (errno); + } + + volume = mpt_vol_info(fd, VolumeBus, VolumeID, NULL); + if (volume == NULL) + return (-1); + + Settings = volume->VolumeSettings.Settings; + + NewSettings = Settings; + if (strncmp(av[2], "enable", sizeof("enable")) == 0) + NewSettings |= 0x01; + if (strncmp(av[2], "disable", sizeof("disable")) == 0) + NewSettings &= ~0x01; + + if (NewSettings == Settings) { + warnx("volume cache unchanged\n"); + close(fd); + return (0); + } + + volume->VolumeSettings.Settings = NewSettings; + if (mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS, + VolumeBus, VolumeID, 0, *(U32 *)&volume->VolumeSettings, NULL, 0, + NULL, NULL, 0, NULL, NULL, 0) < 0) + warnx("volume cache change failed, errno= %d\n", errno); + + close(fd); + return (0); +} +MPT_COMMAND(volume, cache, volume_cache); diff --git a/usr.sbin/mptutil/mptutil.8 b/usr.sbin/mptutil/mptutil.8 new file mode 100644 index 00000000000..7acaf3e90d3 --- /dev/null +++ b/usr.sbin/mptutil/mptutil.8 @@ -0,0 +1,386 @@ +.\" +.\" Copyright (c) 2008 Yahoo!, Inc. +.\" All rights reserved. +.\" Written by: John Baldwin +.\" +.\" 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. Neither the name of the author nor the names of any co-contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" 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 August 16, 2009 +.Dt MPTUTIL 8 +.Os +.Sh NAME +.Nm mptutil +.Nd Utility for managing LSI Fusion-MPT controllers +.Sh SYNOPSIS +.Nm +.Cm version +.Nm +.Op Fl u Ar unit +.Cm show adapter +.Nm +.Op Fl u Ar unit +.Cm show config +.Nm +.Op Fl u Ar unit +.Cm show drives +.Nm +.Op Fl u Ar unit +.Cm show events +.Nm +.Op Fl u Ar unit +.Cm show volumes +.Nm +.Op Fl u Ar unit +.Cm fail Ar drive +.Nm +.Op Fl u Ar unit +.Cm online Ar drive +.Nm +.Op Fl u Ar unit +.Cm offline Ar drive +.Nm +.Op Fl u Ar unit +.Cm name Ar volume Ar name +.Nm +.Op Fl u Ar unit +.Cm volume status Ar volume +.Nm +.Op Fl u Ar unit +.Cm volume cache Ar volume +.Ar enable|disable +.Nm +.Op Fl u Ar unit +.Cm clear +.Nm +.Op Fl u Ar unit +.Cm create Ar type +.Op Fl q +.Op Fl v +.Op Fl s Ar stripe_size +.Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Nm +.Op Fl u Ar unit +.Cm delete Ar volume +.Nm +.Op Fl u Ar unit +.Cm add Ar drive Op Ar volume +.Nm +.Op Fl u Ar unit +.Cm remove Ar drive +.Sh DESCRIPTION +The +.Nm +utility can be used to display or modify various parameters on LSI +Fusion-MPT controllers. +Each invocation of +.Nm +consists of zero or more global options followed by a command. +Commands may support additional optional or required arguments after the +command. +.Pp +Currently one global option is supported: +.Bl -tag -width indent +.It Fl u Ar unit +.Ar unit +specifies the unit of the controller to work with. +If no unit is specified, +then unit 0 is used. +.El +.Pp +Volumes may be specified in two forms. +First, +a volume may be identified by its location as +.Sm off +.Op Ar xx Ns \&: +.Ar yy +.Sm on +where +.Ar xx +is the bus ID and +.Ar yy +is the target ID. +If the bus ID is ommitted, +the volume is assumed to be on bus 0. +Second, +on the volume may be specified by the corresponding +.Em daX +device, +such as +.Em da0 . +.Pp +The +.Xr mpt 4 +controller divides drives up into two categories. +Configured drives belong to a RAID volume either as a member drive or as a hot +spare. +Each configured drive is assigned a unique device ID such as 0 or 1 that is +show in +.Cm show config , +and in the first column of +.Cm show drives . +Any drive not associated with a RAID volume as either a member or a hot spare +is a standalone drive. +Standalone drives are visible to the operating system as SCSI disk devices. +As a result, drives may be specified in three forms. +First, +a configured drive may be identified by its device ID. +Second, +any drive may be identified by its location as +.Sm off +.Ar xx Ns \&: +.Ar yy +.Sm on +where +.Ar xx +is the bus ID and +.Ar yy +is the target ID for each drive as displayed in +.Cm show drives . +Note that unlike volumes, +a drive location always requires the bus ID to avoid confusion with device IDs. +Third, +a standalone drive that is not part of a volume may be identified by its +corresponding +.Em daX +device as displayed in +.Cm show drives . +.Pp +The +.Nm +utility supports several different groups of commands. +The first group of commands provide information about the controller, +the volumes it manages, and the drives it controls. +The second group of commands are used to manage the physical drives +attached to the controller. +The third group of commands are used to manage the logical volumes +managed by the controller. +The fourth group of commands are used to manage the drive configuration for +the controller. +.Pp +The informational commands include: +.Bl -tag -width indent +.It Cm version +Displays the version of +.Nm . +.It Cm show adapter +Displays information about the RAID controller such as the model number. +.It Cm show config +Displays the volume and drive configuration for the controller. +Each volume is listed along with the physical drives that the volume spans. +If any hot spare drives are configured, then they are listed as well. +.It Cm show drives +Lists all of the physical drives attached to the controller. +.It Cm show events +Display all the entries from the controller's event log. +Due to lack of documentation this command isn't very useful currently and +just dumps each log entry in hex. +.It Cm show volumes +Lists all of the logical volumes managed by the controller. +.El +.Pp +The physical drive management commands include: +.Bl -tag -width indent +.It Cm fail Ar drive +Mark +.Ar drive +as +.Dq failed requested . +Note that this state is different from the +.Dq failed +state that is used when the firmware fails a drive. +.Ar Drive +must be a configured drive. +.It Cm online Ar drive +Mark +.Ar drive +as an online drive. +.Ar Drive +must be part a configured drive in either the +.Dq offline +or +.Dq failed requested +states. +.It Cm offline Ar drive +Mark +.Ar drive +as offline. +.Ar Drive +must be a configured, online drive. +.El +.Pp +The logical volume management commands include: +.Bl -tag -width indent +.It Cm name Ar volume Ar name +Sets the name of +.Ar volume +to +.Ar name . +.It Cm volume cache Ar volume Ar enable|disable +Enables or disables the drive write cache for the member drives of +.Ar volume . +.It Cm volume status Ar volume +Display more detailed status about a single volume including the current +progress of a rebuild operation if one is being performed. +.El +.Pp +The configuration commands include: +.Bl -tag -width indent +.It Cm clear +Delete the entire configuration including all volumes and spares. +All drives will become standalone drives. +.It Xo Cm create Ar type +.Op Fl q +.Op Fl v +.Op Fl s Ar stripe_size +.Ar drive Ns Op \&, Ns Ar drive Ns Op ",..." +.Xc +Create a new volume. +The +.Ar type +specifies the type of volume to create. +Currently supported types include: +.Bl -tag -width indent +.It Cm raid0 +Creates one RAID0 volume spanning the drives listed in the single drive list. +.It Cm raid1 +Creates one RAID1 volume spanning the drives listed in the single drive list. +.It Cm raid1e +Creates one RAID1E volume spanning the drives listed in the single drive list. +.El +.Pp +.Sy Note: +Not all volume types are supported by all controllers. +.Pp +If the +.Fl q +flag is specified after +.Ar type , +then a +.Dq quick +initialization of the volume will be done. +This is useful when the drives do not contain any existing data that need +to be preserved. +.Pp +If the +.Fl v +flag is specified after +.Ar type , +then more verbose output will be enabled. +Currently this just provides notification as drives are added to volumes +when building the configuration. +.Pp +The +.Fl s +.Ar stripe_size +parameter allows the stripe size of the array to be set. +By default a stripe size of 64K is used. +The list of valid values for a given +.Ar type +are listed in the output of +.Cm show adapter . +.It Cm delete Ar volume +Delete the volume +.Ar volume . +Member drives will become standalone drives. +.It Cm add Ar drive Op Ar volume +Mark +.Ar drive +as a hot spare. +.Ar Drive +must not be a member of a volume. +If +.Ar volume +is specified, +then the hot spare will be dedicated to that volume. +Otherwise, +.Ar drive +will be used as a global hot spare backing all volumes for this controller. +Note that +.Ar drive +must be as large as the smallest drive in all of the volumes it is going to +back. +.It Cm remove Ar drive +Remove the hot spare +.Ar drive +from service. +It will become a standalone drive. +.El +.Sh EXAMPLES +Mark the drive at bus 0 target 4 as offline: +.Pp +.Dl Nm Cm offline 0:4 +.Pp +Create a RAID1 array from the two standalone drives +.Va da1 +and +.Va da2 : +.Pp +.Dl Nm Cm create raid1 da1,da2 +.Pp +Mark standalone drive +.Va da3 +as a global hot spare: +.Pp +.Dl Nm Cm add da3 +.Sh SEE ALSO +.Xr mpt 4 +.Sh BUGS +.Pp +The handling of spare drives appears to be unreliable. +The +.Xr mpt 4 +firmware manages spares via spare drive +.Dq pools . +There are eight pools numbered 0 through 7. +Each spare drive can only be assigned to a single pool. +Each volume can be backed by any combination of zero or more spare pools. +The +.Nm +utility attempts to use the following algorithm for managing spares. +Global spares are always assigned to pool 0, +and all volumes are always backed by pool 0. +For dedicated spares, +.Nm +assigns one of the remaining 7 pools to each volume and +assigns dedicated drives to that pool. +In practice however, it seems that assigning a drive as a spare does not +take effect until the box has been rebooted. +Also, the firmware renumbers the spare pool assignments after a reboot +which undoes the effects of the algorithm above. +Simple cases such as assigning global spares seem to work ok +.Pq albeit requiring a reboot to take effect +but more +.Dq exotic +configurations may not work reliably. +.Pp +Drive configuration commands result in an excessive flood of messages on the +console. +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 8.0 . diff --git a/usr.sbin/mptutil/mptutil.c b/usr.sbin/mptutil/mptutil.c new file mode 100644 index 00000000000..e7b58060ef1 --- /dev/null +++ b/usr.sbin/mptutil/mptutil.c @@ -0,0 +1,123 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 +__RCSID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include "mptutil.h" + +SET_DECLARE(MPT_DATASET(top), struct mptutil_command); + +int mpt_unit; + +static void +usage(void) +{ + + fprintf(stderr, "usage: mptutil [-u unit] ...\n\n"); + fprintf(stderr, "Commands include:\n"); + fprintf(stderr, " version\n"); + fprintf(stderr, " show adapter - display controller information\n"); + fprintf(stderr, " show config - display RAID configuration\n"); + fprintf(stderr, " show drives - list physical drives\n"); + fprintf(stderr, " show events - display event log\n"); + fprintf(stderr, " show volumes - list logical volumes\n"); + fprintf(stderr, " fail - fail a physical drive\n"); + fprintf(stderr, " online - bring an offline physical drive online\n"); + fprintf(stderr, " offline - mark a physical drive offline\n"); + fprintf(stderr, " name \n"); + fprintf(stderr, " volume status - display volume status\n"); + fprintf(stderr, " volume cache \n"); + fprintf(stderr, " - Enable or disable the volume drive caches\n"); + fprintf(stderr, " clear - clear volume configuration\n"); + fprintf(stderr, " create [-vq] [-s stripe] [,[,...]]\n"); + fprintf(stderr, " delete \n"); + fprintf(stderr, " add [volume] - add a hot spare\n"); + fprintf(stderr, " remove - remove a hot spare\n"); +#ifdef DEBUG + fprintf(stderr, " pd create - create RAID physdisk\n"); + fprintf(stderr, " pd delete - delete RAID physdisk\n"); + fprintf(stderr, " debug - debug 'show config'\n"); +#endif + exit(1); +} + +static int +version(int ac, char **av) +{ + + printf("mptutil version 1.0.3"); +#ifdef DEBUG + printf(" (DEBUG)"); +#endif + printf("\n"); + return (0); +} +MPT_COMMAND(top, version, version); + +int +main(int ac, char **av) +{ + struct mptutil_command **cmd; + int ch; + + while ((ch = getopt(ac, av, "u:")) != -1) { + switch (ch) { + case 'u': + mpt_unit = atoi(optarg); + break; + case '?': + usage(); + } + } + + av += optind; + ac -= optind; + + /* getopt() eats av[0], so we can't use mpt_table_handler() directly. */ + if (ac == 0) + usage(); + + SET_FOREACH(cmd, MPT_DATASET(top)) { + if (strcmp((*cmd)->name, av[0]) == 0) { + (*cmd)->handler(ac, av); + return (0); + } + } + warnx("Unknown command %s.", av[0]); + return (0); +} diff --git a/usr.sbin/mptutil/mptutil.h b/usr.sbin/mptutil/mptutil.h new file mode 100644 index 00000000000..39512359334 --- /dev/null +++ b/usr.sbin/mptutil/mptutil.h @@ -0,0 +1,178 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 __MPTUTIL_H__ +#define __MPTUTIL_H__ + +#include +#include + +#include +#include +#include +#include + +#define IOC_STATUS_SUCCESS(status) \ + (((status) & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) + +struct mpt_query_disk { + char devname[SPECNAMELEN + 1]; +}; + +struct mpt_standalone_disk { + uint64_t maxlba; + char inqstring[64]; + char devname[SPECNAMELEN + 1]; + u_int bus; + u_int target; +}; + +struct mpt_drive_list { + int ndrives; + CONFIG_PAGE_RAID_PHYS_DISK_0 *drives[0]; +}; + +struct mptutil_command { + const char *name; + int (*handler)(int ac, char **av); +}; + +#define MPT_DATASET(name) mptutil_ ## name ## _table + +#define MPT_COMMAND(set, name, function) \ + static struct mptutil_command function ## _mptutil_command = \ + { #name, function }; \ + DATA_SET(MPT_DATASET(set), function ## _mptutil_command) + +#define MPT_TABLE(set, name) \ + SET_DECLARE(MPT_DATASET(name), struct mptutil_command); \ + \ + static int \ + mptutil_ ## name ## _table_handler(int ac, char **av) \ + { \ + return (mpt_table_handler(SET_BEGIN(MPT_DATASET(name)), \ + SET_LIMIT(MPT_DATASET(name)), ac, av)); \ + } \ + MPT_COMMAND(set, name, mptutil_ ## name ## _table_handler) + +extern int mpt_unit; + +#ifdef DEBUG +void hexdump(const void *ptr, int length, const char *hdr, int flags); +#define HD_COLUMN_MASK 0xff +#define HD_DELIM_MASK 0xff00 +#define HD_OMIT_COUNT (1 << 16) +#define HD_OMIT_HEX (1 << 17) +#define HD_OMIT_CHARS (1 << 18) +#endif + +int mpt_table_handler(struct mptutil_command **start, + struct mptutil_command **end, int ac, char **av); +int mpt_read_config_page_header(int fd, U8 PageType, U8 PageNumber, + U32 PageAddress, CONFIG_PAGE_HEADER *header, U16 *IOCStatus); +void *mpt_read_config_page(int fd, U8 PageType, U8 PageNumber, + U32 PageAddress, U16 *IOCStatus); +void *mpt_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion, + U8 PageNumber, U32 PageAddress, U16 *IOCStatus); +int mpt_write_config_page(int fd, void *buf, U16 *IOCStatus); +const char *mpt_ioc_status(U16 IOCStatus); +int mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID, + U8 PhysDiskNum, U32 ActionDataWord, void *buf, int len, + RAID_VOL0_STATUS *VolumeStatus, U32 *ActionData, int datalen, + U16 *IOCStatus, U16 *ActionStatus, int write); +const char *mpt_raid_status(U16 ActionStatus); +int mpt_open(int unit); +const char *mpt_raid_level(U8 VolumeType); +const char *mpt_volstate(U8 State); +const char *mpt_pdstate(CONFIG_PAGE_RAID_PHYS_DISK_0 *info); +const char *mpt_pd_inq_string(CONFIG_PAGE_RAID_PHYS_DISK_0 *pd_info); +struct mpt_drive_list *mpt_pd_list(int fd); +void mpt_free_pd_list(struct mpt_drive_list *list); +int mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd); +const char *mpt_volume_name(U8 VolumeBus, U8 VolumeID); +int mpt_fetch_disks(int fd, int *ndisks, + struct mpt_standalone_disk **disksp); +int mpt_lock_volume(U8 VolumeBus, U8 VolumeID); +int mpt_lookup_drive(struct mpt_drive_list *list, const char *drive, + U8 *PhysDiskNum); +int mpt_lookup_volume(int fd, const char *name, U8 *VolumeBus, + U8 *VolumeID); +int mpt_rescan_bus(int bus, int id); + +static __inline void * +mpt_read_man_page(int fd, U8 PageNumber, U16 *IOCStatus) +{ + + return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_MANUFACTURING, + PageNumber, 0, IOCStatus)); +} + +static __inline void * +mpt_read_ioc_page(int fd, U8 PageNumber, U16 *IOCStatus) +{ + + return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_IOC, PageNumber, + 0, IOCStatus)); +} + +static __inline U32 +mpt_vol_pageaddr(U8 VolumeBus, U8 VolumeID) +{ + + return (VolumeBus << 8 | VolumeID); +} + +static __inline CONFIG_PAGE_RAID_VOL_0 * +mpt_vol_info(int fd, U8 VolumeBus, U8 VolumeID, U16 *IOCStatus) +{ + + return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 0, + mpt_vol_pageaddr(VolumeBus, VolumeID), IOCStatus)); +} + +static __inline CONFIG_PAGE_RAID_VOL_1 * +mpt_vol_names(int fd, U8 VolumeBus, U8 VolumeID, U16 *IOCStatus) +{ + + return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 1, + mpt_vol_pageaddr(VolumeBus, VolumeID), IOCStatus)); +} + +static __inline CONFIG_PAGE_RAID_PHYS_DISK_0 * +mpt_pd_info(int fd, U8 PhysDiskNum, U16 *IOCStatus) +{ + + return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK, 0, + PhysDiskNum, IOCStatus)); +} + +#endif /* !__MPTUTIL_H__ */ From 424c75bfe15ac1222dd1365ba98fec4aa268ac2d Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 07:46:55 +0000 Subject: [PATCH 0065/2592] MFC r196287: Be more precise how to get fsids - 'mount -v' doesn't show fsids unless is run by root. Approved by: re (kib) --- sbin/umount/umount.8 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sbin/umount/umount.8 b/sbin/umount/umount.8 index d19ea9ae7a4..42b55ee724f 100644 --- a/sbin/umount/umount.8 +++ b/sbin/umount/umount.8 @@ -57,7 +57,8 @@ device or remote node (rhost:path), the path to the mount point or by the file system ID .Ar fsid as reported by -.Dq mount -v . +.Dq mount -v +when run by root. .Pp The options are as follows: .Bl -tag -width indent From 9e813d55e3694914d49da14c35894f119999c700 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 08:09:46 +0000 Subject: [PATCH 0066/2592] MFC r196289: Remove files that are no longer used. Discussed with: kmacy Approved by: re (kib) --- cddl/lib/libnvpair/Makefile | 1 + sys/cddl/compat/opensolaris/rpc/xdr.h | 112 ---- .../uts/common/rpc/opensolaris_xdr.c | 621 ----------------- .../uts/common/rpc/opensolaris_xdr_array.c | 114 ---- .../uts/common/rpc/opensolaris_xdr_mem.c | 209 ------ .../contrib/opensolaris/uts/common/rpc/xdr.h | 632 ------------------ 6 files changed, 1 insertion(+), 1688 deletions(-) delete mode 100644 sys/cddl/compat/opensolaris/rpc/xdr.h delete mode 100644 sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr.c delete mode 100644 sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_array.c delete mode 100644 sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_mem.c delete mode 100644 sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.h diff --git a/cddl/lib/libnvpair/Makefile b/cddl/lib/libnvpair/Makefile index 120339002ce..7bf500193dc 100644 --- a/cddl/lib/libnvpair/Makefile +++ b/cddl/lib/libnvpair/Makefile @@ -13,5 +13,6 @@ SRCS= libnvpair.c \ CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common +CFLAGS+= -I${.CURDIR}/../../../sys .include diff --git a/sys/cddl/compat/opensolaris/rpc/xdr.h b/sys/cddl/compat/opensolaris/rpc/xdr.h deleted file mode 100644 index 5802f3f12ba..00000000000 --- a/sys/cddl/compat/opensolaris/rpc/xdr.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * $FreeBSD$ - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * Portions of this source code were derived from Berkeley 4.3 BSD - * under license from the Regents of the University of California. - */ - -#ifndef _OPENSOLARIS_RPC_XDR_H_ -#define _OPENSOLARIS_RPC_XDR_H_ - -#include_next - -#ifndef _KERNEL -#include_next - -/* - * Strangely, my glibc version (2.3.6) doesn't have xdr_control(), so - * we have to hack it in here (source taken from OpenSolaris). - * By the way, it is assumed the xdrmem implementation is used. - */ - -#undef xdr_control -#define xdr_control(a,b,c) xdrmem_control(a,b,c) - -/* - * These are the request arguments to XDR_CONTROL. - * - * XDR_PEEK - returns the contents of the next XDR unit on the XDR stream. - * XDR_SKIPBYTES - skips the next N bytes in the XDR stream. - * XDR_RDMAGET - for xdr implementation over RDMA, gets private flags from - * the XDR stream being moved over RDMA - * XDR_RDMANOCHUNK - for xdr implementaion over RDMA, sets private flags in - * the XDR stream moving over RDMA. - */ -#define XDR_PEEK 2 -#define XDR_SKIPBYTES 3 -#define XDR_RDMAGET 4 -#define XDR_RDMASET 5 - -/* FIXME: probably doesn't work */ -static __inline bool_t -xdrmem_control(XDR *xdrs, int request, void *info) -{ - xdr_bytesrec *xptr; - int32_t *int32p; - int len; - - switch (request) { - - case XDR_GET_BYTES_AVAIL: - xptr = (xdr_bytesrec *)info; - xptr->xc_is_last_record = TRUE; - xptr->xc_num_avail = xdrs->x_handy; - return (TRUE); - - case XDR_PEEK: - /* - * Return the next 4 byte unit in the XDR stream. - */ - if (xdrs->x_handy < sizeof (int32_t)) - return (FALSE); - int32p = (int32_t *)info; - *int32p = (int32_t)ntohl((uint32_t) - (*((int32_t *)(xdrs->x_private)))); - return (TRUE); - - case XDR_SKIPBYTES: - /* - * Skip the next N bytes in the XDR stream. - */ - int32p = (int32_t *)info; - len = RNDUP((int)(*int32p)); - if ((xdrs->x_handy -= len) < 0) - return (FALSE); - xdrs->x_private += len; - return (TRUE); - - } - return (FALSE); -} -#endif /* !_KERNEL */ - -#endif /* !_OPENSOLARIS_RPC_XDR_H_ */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr.c b/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr.c deleted file mode 100644 index b38833afb54..00000000000 --- a/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * Portions of this source code were derived from Berkeley 4.3 BSD - * under license from the Regents of the University of California. - */ - -/* - * xdr.c, generic XDR routines implementation. - * These are the "generic" xdr routines used to serialize and de-serialize - * most common data items. See xdr.h for more info on the interface to - * xdr. - */ - -#include -#include -#include -#include - -#include -#include - -#pragma weak xdr_int32_t = xdr_int -#pragma weak xdr_uint32_t = xdr_u_int -#pragma weak xdr_int64_t = xdr_longlong_t -#pragma weak xdr_uint64_t = xdr_u_longlong_t - -#if defined(sun) -#if !defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) -#error "Exactly one of _BIG_ENDIAN or _LITTLE_ENDIAN must be defined" -#elif defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) -#error "Only one of _BIG_ENDIAN or _LITTLE_ENDIAN may be defined" -#endif -#endif - -/* - * constants specific to the xdr "protocol" - */ -#define XDR_FALSE ((int32_t)0) -#define XDR_TRUE ((int32_t)1) -#define LASTUNSIGNED ((uint_t)0-1) - -/* - * for unit alignment - */ -static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; - -/* - * Free a data structure using XDR - * Not a filter, but a convenient utility nonetheless - */ -void -xdr_free(xdrproc_t proc, char *objp) -{ - XDR x; - - x.x_op = XDR_FREE; - (*proc)(&x, objp); -} - -/* - * XDR nothing - */ -bool_t -xdr_void(void) -{ - return (TRUE); -} - -/* - * XDR integers - * - * PSARC 2003/523 Contract Private Interface - * xdr_int - * Changes must be reviewed by Solaris File Sharing - * Changes must be communicated to contract-2003-523@sun.com - */ -bool_t -xdr_int(XDR *xdrs, int *ip) -{ - if (xdrs->x_op == XDR_ENCODE) - return (XDR_PUTINT32(xdrs, ip)); - - if (xdrs->x_op == XDR_DECODE) - return (XDR_GETINT32(xdrs, ip)); - - if (xdrs->x_op == XDR_FREE) - return (TRUE); - - return (FALSE); -} - -/* - * XDR unsigned integers - * - * PSARC 2003/523 Contract Private Interface - * xdr_u_int - * Changes must be reviewed by Solaris File Sharing - * Changes must be communicated to contract-2003-523@sun.com - */ -bool_t -xdr_u_int(XDR *xdrs, uint_t *up) -{ - if (xdrs->x_op == XDR_ENCODE) - return (XDR_PUTINT32(xdrs, (int32_t *)up)); - - if (xdrs->x_op == XDR_DECODE) - return (XDR_GETINT32(xdrs, (int32_t *)up)); - - if (xdrs->x_op == XDR_FREE) - return (TRUE); - - return (FALSE); -} - - -#if defined(_ILP32) -/* - * xdr_long and xdr_u_long for binary compatability on ILP32 kernels. - * - * No prototypes since new code should not be using these interfaces. - */ -bool_t -xdr_long(XDR *xdrs, long *ip) -{ - return (xdr_int(xdrs, (int *)ip)); -} - -bool_t -xdr_u_long(XDR *xdrs, unsigned long *up) -{ - return (xdr_u_int(xdrs, (uint_t *)up)); -} -#endif /* _ILP32 */ - - -/* - * XDR long long integers - */ -bool_t -xdr_longlong_t(XDR *xdrs, longlong_t *hp) -{ - if (xdrs->x_op == XDR_ENCODE) { -#if BYTE_ORDER == _LITTLE_ENDIAN - if (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp + - BYTES_PER_XDR_UNIT)) == TRUE) { - return (XDR_PUTINT32(xdrs, (int32_t *)hp)); - } -#else - if (XDR_PUTINT32(xdrs, (int32_t *)hp) == TRUE) { - return (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp + - BYTES_PER_XDR_UNIT))); - } -#endif - return (FALSE); - - } - if (xdrs->x_op == XDR_DECODE) { -#if BYTE_ORDER == _LITTLE_ENDIAN - if (XDR_GETINT32(xdrs, (int32_t *)((char *)hp + - BYTES_PER_XDR_UNIT)) == TRUE) { - return (XDR_GETINT32(xdrs, (int32_t *)hp)); - } -#else - if (XDR_GETINT32(xdrs, (int32_t *)hp) == TRUE) { - return (XDR_GETINT32(xdrs, (int32_t *)((char *)hp + - BYTES_PER_XDR_UNIT))); - } -#endif - return (FALSE); - } - return (TRUE); -} - -/* - * XDR unsigned long long integers - */ -bool_t -xdr_u_longlong_t(XDR *xdrs, u_longlong_t *hp) -{ - - if (xdrs->x_op == XDR_ENCODE) { -#if BYTE_ORDER == _LITTLE_ENDIAN - if (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp + - BYTES_PER_XDR_UNIT)) == TRUE) { - return (XDR_PUTINT32(xdrs, (int32_t *)hp)); - } -#else - if (XDR_PUTINT32(xdrs, (int32_t *)hp) == TRUE) { - return (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp + - BYTES_PER_XDR_UNIT))); - } -#endif - return (FALSE); - - } - if (xdrs->x_op == XDR_DECODE) { -#if BYTE_ORDER == _LITTLE_ENDIAN - if (XDR_GETINT32(xdrs, (int32_t *)((char *)hp + - BYTES_PER_XDR_UNIT)) == TRUE) { - return (XDR_GETINT32(xdrs, (int32_t *)hp)); - } -#else - if (XDR_GETINT32(xdrs, (int32_t *)hp) == TRUE) { - return (XDR_GETINT32(xdrs, (int32_t *)((char *)hp + - BYTES_PER_XDR_UNIT))); - } -#endif - return (FALSE); - } - return (TRUE); -} - -/* - * XDR short integers - */ -bool_t -xdr_short(XDR *xdrs, short *sp) -{ - int32_t l; - - switch (xdrs->x_op) { - - case XDR_ENCODE: - l = (int32_t)*sp; - return (XDR_PUTINT32(xdrs, &l)); - - case XDR_DECODE: - if (!XDR_GETINT32(xdrs, &l)) - return (FALSE); - *sp = (short)l; - return (TRUE); - - case XDR_FREE: - return (TRUE); - } - return (FALSE); -} - -/* - * XDR unsigned short integers - */ -bool_t -xdr_u_short(XDR *xdrs, ushort_t *usp) -{ - uint32_t l; - - switch (xdrs->x_op) { - - case XDR_ENCODE: - l = (uint32_t)*usp; - return (XDR_PUTINT32(xdrs, (int32_t *)&l)); - - case XDR_DECODE: - if (!XDR_GETINT32(xdrs, (int32_t *)&l)) { - return (FALSE); - } - *usp = (ushort_t)l; - return (TRUE); - - case XDR_FREE: - return (TRUE); - } - return (FALSE); -} - - -/* - * XDR a char - */ -bool_t -xdr_char(XDR *xdrs, char *cp) -{ - int i; - - i = (*cp); - if (!xdr_int(xdrs, &i)) { - return (FALSE); - } - *cp = (char)i; - return (TRUE); -} - -/* - * XDR booleans - * - * PSARC 2003/523 Contract Private Interface - * xdr_bool - * Changes must be reviewed by Solaris File Sharing - * Changes must be communicated to contract-2003-523@sun.com - */ -bool_t -xdr_bool(XDR *xdrs, bool_t *bp) -{ - int32_t i32b; - - switch (xdrs->x_op) { - - case XDR_ENCODE: - i32b = *bp ? XDR_TRUE : XDR_FALSE; - return (XDR_PUTINT32(xdrs, &i32b)); - - case XDR_DECODE: - if (!XDR_GETINT32(xdrs, &i32b)) { - return (FALSE); - } - *bp = (i32b == XDR_FALSE) ? FALSE : TRUE; - return (TRUE); - - case XDR_FREE: - return (TRUE); - } - return (FALSE); -} - -/* - * XDR enumerations - * - * PSARC 2003/523 Contract Private Interface - * xdr_enum - * Changes must be reviewed by Solaris File Sharing - * Changes must be communicated to contract-2003-523@sun.com - */ -#ifndef lint -enum sizecheck { SIZEVAL } sizecheckvar; /* used to find the size of */ - /* an enum */ -#endif -bool_t -xdr_enum(XDR *xdrs, enum_t *ep) -{ -#ifndef lint - /* - * enums are treated as ints - */ - if (sizeof (sizecheckvar) == sizeof (int32_t)) { - return (xdr_int(xdrs, (int32_t *)ep)); - } else if (sizeof (sizecheckvar) == sizeof (short)) { - return (xdr_short(xdrs, (short *)ep)); - } else { - return (FALSE); - } -#else - (void) (xdr_short(xdrs, (short *)ep)); - return (xdr_int(xdrs, (int32_t *)ep)); -#endif -} - -/* - * XDR opaque data - * Allows the specification of a fixed size sequence of opaque bytes. - * cp points to the opaque object and cnt gives the byte length. - * - * PSARC 2003/523 Contract Private Interface - * xdr_opaque - * Changes must be reviewed by Solaris File Sharing - * Changes must be communicated to contract-2003-523@sun.com - */ -bool_t -xdr_opaque(XDR *xdrs, caddr_t cp, const uint_t cnt) -{ - uint_t rndup; - static char crud[BYTES_PER_XDR_UNIT]; - - /* - * if no data we are done - */ - if (cnt == 0) - return (TRUE); - - /* - * round byte count to full xdr units - */ - rndup = cnt % BYTES_PER_XDR_UNIT; - if (rndup != 0) - rndup = BYTES_PER_XDR_UNIT - rndup; - - if (xdrs->x_op == XDR_DECODE) { - if (!XDR_GETBYTES(xdrs, cp, cnt)) { - return (FALSE); - } - if (rndup == 0) - return (TRUE); - return (XDR_GETBYTES(xdrs, (caddr_t)crud, rndup)); - } - - if (xdrs->x_op == XDR_ENCODE) { - if (!XDR_PUTBYTES(xdrs, cp, cnt)) { - return (FALSE); - } - if (rndup == 0) - return (TRUE); - return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); - } - - if (xdrs->x_op == XDR_FREE) - return (TRUE); - - return (FALSE); -} - -/* - * XDR counted bytes - * *cpp is a pointer to the bytes, *sizep is the count. - * If *cpp is NULL maxsize bytes are allocated - * - * PSARC 2003/523 Contract Private Interface - * xdr_bytes - * Changes must be reviewed by Solaris File Sharing - * Changes must be communicated to contract-2003-523@sun.com - */ -bool_t -xdr_bytes(XDR *xdrs, char **cpp, uint_t *sizep, const uint_t maxsize) -{ - char *sp = *cpp; /* sp is the actual string pointer */ - uint_t nodesize; - - /* - * first deal with the length since xdr bytes are counted - */ - if (!xdr_u_int(xdrs, sizep)) { - return (FALSE); - } - nodesize = *sizep; - if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { - return (FALSE); - } - - /* - * now deal with the actual bytes - */ - switch (xdrs->x_op) { - case XDR_DECODE: - if (nodesize == 0) - return (TRUE); - if (sp == NULL) - *cpp = sp = (char *)mem_alloc(nodesize); - /* FALLTHROUGH */ - - case XDR_ENCODE: - return (xdr_opaque(xdrs, sp, nodesize)); - - case XDR_FREE: - if (sp != NULL) { - mem_free(sp, nodesize); - *cpp = NULL; - } - return (TRUE); - } - return (FALSE); -} - -/* - * Implemented here due to commonality of the object. - */ -bool_t -xdr_netobj(XDR *xdrs, struct netobj *np) -{ - return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); -} - -/* - * XDR a descriminated union - * Support routine for discriminated unions. - * You create an array of xdrdiscrim structures, terminated with - * an entry with a null procedure pointer. The routine gets - * the discriminant value and then searches the array of xdrdiscrims - * looking for that value. It calls the procedure given in the xdrdiscrim - * to handle the discriminant. If there is no specific routine a default - * routine may be called. - * If there is no specific or default routine an error is returned. - */ -bool_t -xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, - const struct xdr_discrim *choices, const xdrproc_t dfault) -{ - enum_t dscm; - - /* - * we deal with the discriminator; it's an enum - */ - if (!xdr_enum(xdrs, dscmp)) { - return (FALSE); - } - dscm = *dscmp; - - /* - * search choices for a value that matches the discriminator. - * if we find one, execute the xdr routine for that value. - */ - for (; choices->proc != NULL_xdrproc_t; choices++) { - if (choices->value == dscm) - return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED)); - } - - /* - * no match - execute the default xdr routine if there is one - */ - return ((dfault == NULL_xdrproc_t) ? FALSE : - (*dfault)(xdrs, unp, LASTUNSIGNED)); -} - - -/* - * Non-portable xdr primitives. - * Care should be taken when moving these routines to new architectures. - */ - - -/* - * XDR null terminated ASCII strings - * xdr_string deals with "C strings" - arrays of bytes that are - * terminated by a NULL character. The parameter cpp references a - * pointer to storage; If the pointer is null, then the necessary - * storage is allocated. The last parameter is the max allowed length - * of the string as specified by a protocol. - */ -bool_t -xdr_string(XDR *xdrs, char **cpp, const uint_t maxsize) -{ - char *sp = *cpp; /* sp is the actual string pointer */ - uint_t size; - uint_t nodesize; - - /* - * first deal with the length since xdr strings are counted-strings - */ - switch (xdrs->x_op) { - case XDR_FREE: - if (sp == NULL) - return (TRUE); /* already free */ - /* FALLTHROUGH */ - case XDR_ENCODE: - size = (sp != NULL) ? (uint_t)strlen(sp) : 0; - break; - case XDR_DECODE: - break; - } - if (!xdr_u_int(xdrs, &size)) { - return (FALSE); - } - if (size > maxsize) { - return (FALSE); - } - nodesize = size + 1; - - /* - * now deal with the actual bytes - */ - switch (xdrs->x_op) { - case XDR_DECODE: - if (nodesize == 0) - return (TRUE); - if (sp == NULL) - sp = (char *)mem_alloc(nodesize); - sp[size] = 0; - if (!xdr_opaque(xdrs, sp, size)) { - /* - * free up memory if allocated here - */ - if (*cpp == NULL) { - mem_free(sp, nodesize); - } - return (FALSE); - } - if (strlen(sp) != size) { - if (*cpp == NULL) { - mem_free(sp, nodesize); - } - return (FALSE); - } - *cpp = sp; - return (TRUE); - - case XDR_ENCODE: - return (xdr_opaque(xdrs, sp, size)); - - case XDR_FREE: - mem_free(sp, nodesize); - *cpp = NULL; - return (TRUE); - } - return (FALSE); -} - -/* - * Wrapper for xdr_string that can be called directly from - * routines like clnt_call - */ -bool_t -xdr_wrapstring(XDR *xdrs, char **cpp) -{ - if (xdr_string(xdrs, cpp, LASTUNSIGNED)) - return (TRUE); - return (FALSE); -} diff --git a/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_array.c b/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_array.c deleted file mode 100644 index d37dda6921a..00000000000 --- a/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_array.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * Portions of this source code were derived from Berkeley 4.3 BSD - * under license from the Regents of the University of California. - */ - -/* - * xdr_array.c, Generic XDR routines impelmentation. - * These are the "non-trivial" xdr primitives used to serialize and de-serialize - * arrays. See xdr.h for more info on the interface to xdr. - */ - -#include -#include -#include -#include - -#include -#include - -#define LASTUNSIGNED ((uint_t)0-1) - -/* - * XDR an array of arbitrary elements - * *addrp is a pointer to the array, *sizep is the number of elements. - * If addrp is NULL (*sizep * elsize) bytes are allocated. - * elsize is the size (in bytes) of each element, and elproc is the - * xdr procedure to call to handle each element of the array. - */ -bool_t -xdr_array(XDR *xdrs, caddr_t *addrp, uint_t *sizep, const uint_t maxsize, - const uint_t elsize, const xdrproc_t elproc) -{ - uint_t i; - caddr_t target = *addrp; - uint_t c; /* the actual element count */ - bool_t stat = TRUE; - uint_t nodesize; - - /* like strings, arrays are really counted arrays */ - if (!xdr_u_int(xdrs, sizep)) { - return (FALSE); - } - c = *sizep; - if ((c > maxsize || LASTUNSIGNED / elsize < c) && - xdrs->x_op != XDR_FREE) { - return (FALSE); - } - nodesize = c * elsize; - - /* - * if we are deserializing, we may need to allocate an array. - * We also save time by checking for a null array if we are freeing. - */ - if (target == NULL) - switch (xdrs->x_op) { - case XDR_DECODE: - if (c == 0) - return (TRUE); - *addrp = target = (char *)mem_alloc(nodesize); - bzero(target, nodesize); - break; - - case XDR_FREE: - return (TRUE); - - case XDR_ENCODE: - break; - } - - /* - * now we xdr each element of array - */ - for (i = 0; (i < c) && stat; i++) { - stat = (*elproc)(xdrs, target, LASTUNSIGNED); - target += elsize; - } - - /* - * the array may need freeing - */ - if (xdrs->x_op == XDR_FREE) { - mem_free(*addrp, nodesize); - *addrp = NULL; - } - return (stat); -} diff --git a/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_mem.c b/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_mem.c deleted file mode 100644 index 32ff32daaa0..00000000000 --- a/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_mem.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * Portions of this source code were derived from Berkeley 4.3 BSD - * under license from the Regents of the University of California. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * xdr_mem.c, XDR implementation using memory buffers. - * - * If you have some data to be interpreted as external data representation - * or to be converted to external data representation in a memory buffer, - * then this is the package for you. - */ - -#include -#include -#include - -#include -#include - -static struct xdr_ops *xdrmem_ops(void); - -/* - * The procedure xdrmem_create initializes a stream descriptor for a - * memory buffer. - */ -void -xdrmem_create(XDR *xdrs, caddr_t addr, uint_t size, enum xdr_op op) -{ - xdrs->x_op = op; - xdrs->x_ops = xdrmem_ops(); - xdrs->x_private = xdrs->x_base = addr; - xdrs->x_handy = size; - xdrs->x_public = NULL; -} - -/* ARGSUSED */ -static void -xdrmem_destroy(XDR *xdrs) -{ -} - -static bool_t -xdrmem_getint32(XDR *xdrs, int32_t *int32p) -{ - if ((xdrs->x_handy -= (int)sizeof (int32_t)) < 0) - return (FALSE); - /* LINTED pointer alignment */ - *int32p = (int32_t)ntohl((uint32_t)(*((int32_t *)(xdrs->x_private)))); - xdrs->x_private += sizeof (int32_t); - return (TRUE); -} - -static bool_t -xdrmem_putint32(XDR *xdrs, int32_t *int32p) -{ - if ((xdrs->x_handy -= (int)sizeof (int32_t)) < 0) - return (FALSE); - /* LINTED pointer alignment */ - *(int32_t *)xdrs->x_private = (int32_t)htonl((uint32_t)(*int32p)); - xdrs->x_private += sizeof (int32_t); - return (TRUE); -} - -static bool_t -xdrmem_getbytes(XDR *xdrs, caddr_t addr, int len) -{ - if ((xdrs->x_handy -= len) < 0) - return (FALSE); - bcopy(xdrs->x_private, addr, len); - xdrs->x_private += len; - return (TRUE); -} - -static bool_t -xdrmem_putbytes(XDR *xdrs, caddr_t addr, int len) -{ - if ((xdrs->x_handy -= len) < 0) - return (FALSE); - bcopy(addr, xdrs->x_private, len); - xdrs->x_private += len; - return (TRUE); -} - -static uint_t -xdrmem_getpos(XDR *xdrs) -{ - return ((uint_t)((uintptr_t)xdrs->x_private - (uintptr_t)xdrs->x_base)); -} - -static bool_t -xdrmem_setpos(XDR *xdrs, uint_t pos) -{ - caddr_t newaddr = xdrs->x_base + pos; - caddr_t lastaddr = xdrs->x_private + xdrs->x_handy; - ptrdiff_t diff; - - if (newaddr > lastaddr) - return (FALSE); - xdrs->x_private = newaddr; - diff = lastaddr - newaddr; - xdrs->x_handy = (int)diff; - return (TRUE); -} - -static rpc_inline_t * -xdrmem_inline(XDR *xdrs, int len) -{ - rpc_inline_t *buf = NULL; - - if (xdrs->x_handy >= len) { - xdrs->x_handy -= len; - /* LINTED pointer alignment */ - buf = (rpc_inline_t *)xdrs->x_private; - xdrs->x_private += len; - } - return (buf); -} - -static bool_t -xdrmem_control(XDR *xdrs, int request, void *info) -{ - xdr_bytesrec *xptr; - int32_t *int32p; - int len; - - switch (request) { - - case XDR_GET_BYTES_AVAIL: - xptr = (xdr_bytesrec *)info; - xptr->xc_is_last_record = TRUE; - xptr->xc_num_avail = xdrs->x_handy; - return (TRUE); - - case XDR_PEEK: - /* - * Return the next 4 byte unit in the XDR stream. - */ - if (xdrs->x_handy < sizeof (int32_t)) - return (FALSE); - int32p = (int32_t *)info; - *int32p = (int32_t)ntohl((uint32_t) - (*((int32_t *)(xdrs->x_private)))); - return (TRUE); - - case XDR_SKIPBYTES: - /* - * Skip the next N bytes in the XDR stream. - */ - int32p = (int32_t *)info; - len = RNDUP((int)(*int32p)); - if ((xdrs->x_handy -= len) < 0) - return (FALSE); - xdrs->x_private += len; - return (TRUE); - - } - return (FALSE); -} - -static struct xdr_ops * -xdrmem_ops(void) -{ - static struct xdr_ops ops; - - if (ops.x_getint32 == NULL) { - ops.x_getbytes = xdrmem_getbytes; - ops.x_putbytes = xdrmem_putbytes; - ops.x_getpostn = xdrmem_getpos; - ops.x_setpostn = xdrmem_setpos; - ops.x_inline = xdrmem_inline; - ops.x_destroy = xdrmem_destroy; - ops.x_control = xdrmem_control; - ops.x_getint32 = xdrmem_getint32; - ops.x_putint32 = xdrmem_putint32; - } - return (&ops); -} diff --git a/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.h b/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.h deleted file mode 100644 index 6cb0c6db392..00000000000 --- a/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.h +++ /dev/null @@ -1,632 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ -/* - * Portions of this source code were derived from Berkeley - * 4.3 BSD under license from the Regents of the University of - * California. - */ - -/* - * xdr.h, External Data Representation Serialization Routines. - * - */ - -#ifndef _RPC_XDR_H -#define _RPC_XDR_H - -#include /* For all ntoh* and hton*() kind of macros */ -#include /* For all ntoh* and hton*() kind of macros */ -#ifndef _KERNEL -#include /* defines FILE *, used in ANSI C function prototypes */ -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * XDR provides a conventional way for converting between C data - * types and an external bit-string representation. Library supplied - * routines provide for the conversion on built-in C data types. These - * routines and utility routines defined here are used to help implement - * a type encode/decode routine for each user-defined type. - * - * Each data type provides a single procedure which takes two arguments: - * - * bool_t - * xdrproc(xdrs, argresp) - * XDR *xdrs; - * *argresp; - * - * xdrs is an instance of a XDR handle, to which or from which the data - * type is to be converted. argresp is a pointer to the structure to be - * converted. The XDR handle contains an operation field which indicates - * which of the operations (ENCODE, DECODE * or FREE) is to be performed. - * - * XDR_DECODE may allocate space if the pointer argresp is null. This - * data can be freed with the XDR_FREE operation. - * - * We write only one procedure per data type to make it easy - * to keep the encode and decode procedures for a data type consistent. - * In many cases the same code performs all operations on a user defined type, - * because all the hard work is done in the component type routines. - * decode as a series of calls on the nested data types. - */ - -/* - * Xdr operations. XDR_ENCODE causes the type to be encoded into the - * stream. XDR_DECODE causes the type to be extracted from the stream. - * XDR_FREE can be used to release the space allocated by an XDR_DECODE - * request. - */ -enum xdr_op { - XDR_ENCODE = 0, - XDR_DECODE = 1, - XDR_FREE = 2 -}; - -/* - * This is the number of bytes per unit of external data. - */ -#define BYTES_PER_XDR_UNIT (4) -#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ - * BYTES_PER_XDR_UNIT) - -/* - * The XDR handle. - * Contains operation which is being applied to the stream, - * an operations vector for the paticular implementation (e.g. see xdr_mem.c), - * and two private fields for the use of the particular impelementation. - * - * PSARC 2003/523 Contract Private Interface - * XDR - * Changes must be reviewed by Solaris File Sharing - * Changes must be communicated to contract-2003-523@sun.com - */ -typedef struct XDR { - enum xdr_op x_op; /* operation; fast additional param */ - struct xdr_ops *x_ops; - caddr_t x_public; /* users' data */ - caddr_t x_private; /* pointer to private data */ - caddr_t x_base; /* private used for position info */ - int x_handy; /* extra private word */ -} XDR; - -/* - * PSARC 2003/523 Contract Private Interface - * xdr_ops - * Changes must be reviewed by Solaris File Sharing - * Changes must be communicated to contract-2003-523@sun.com - */ -#ifndef __FreeBSD__ -struct xdr_ops { -#ifdef __STDC__ -#if !defined(_KERNEL) - bool_t (*x_getlong)(struct XDR *, long *); - /* get a long from underlying stream */ - bool_t (*x_putlong)(struct XDR *, long *); - /* put a long to " */ -#endif /* KERNEL */ - bool_t (*x_getbytes)(struct XDR *, caddr_t, int); - /* get some bytes from " */ - bool_t (*x_putbytes)(struct XDR *, caddr_t, int); - /* put some bytes to " */ - uint_t (*x_getpostn)(struct XDR *); - /* returns bytes off from beginning */ - bool_t (*x_setpostn)(struct XDR *, uint_t); - /* lets you reposition the stream */ - rpc_inline_t *(*x_inline)(struct XDR *, int); - /* buf quick ptr to buffered data */ - void (*x_destroy)(struct XDR *); - /* free privates of this xdr_stream */ - bool_t (*x_control)(struct XDR *, int, void *); -#if defined(_LP64) || defined(_KERNEL) - bool_t (*x_getint32)(struct XDR *, int32_t *); - /* get a int from underlying stream */ - bool_t (*x_putint32)(struct XDR *, int32_t *); - /* put an int to " */ -#endif /* _LP64 || _KERNEL */ -#else -#if !defined(_KERNEL) - bool_t (*x_getlong)(); /* get a long from underlying stream */ - bool_t (*x_putlong)(); /* put a long to " */ -#endif /* KERNEL */ - bool_t (*x_getbytes)(); /* get some bytes from " */ - bool_t (*x_putbytes)(); /* put some bytes to " */ - uint_t (*x_getpostn)(); /* returns bytes off from beginning */ - bool_t (*x_setpostn)(); /* lets you reposition the stream */ - rpc_inline_t *(*x_inline)(); - /* buf quick ptr to buffered data */ - void (*x_destroy)(); /* free privates of this xdr_stream */ - bool_t (*x_control)(); -#if defined(_LP64) || defined(_KERNEL) - bool_t (*x_getint32)(); - bool_t (*x_putint32)(); -#endif /* _LP64 || defined(_KERNEL) */ -#endif -}; - -#else /* FreeBSD */ -struct xdr_ops { - /* get a long from underlying stream */ - bool_t (*x_getint32)(struct XDR *, int32_t *); - /* put a long to " */ - bool_t (*x_putint32)(struct XDR *, const int32_t *); - /* get some bytes from " */ - bool_t (*x_getbytes)(struct XDR *, char *, u_int); - /* put some bytes to " */ - bool_t (*x_putbytes)(struct XDR *, const char *, u_int); - /* returns bytes off from beginning */ - u_int (*x_getpostn)(struct XDR *); - /* lets you reposition the stream */ - bool_t (*x_setpostn)(struct XDR *, u_int); - /* buf quick ptr to buffered data */ - int32_t *(*x_inline)(struct XDR *, u_int); - /* free privates of this xdr_stream */ - void (*x_destroy)(struct XDR *); - bool_t (*x_control)(struct XDR *, int, void *); -}; -#endif - -/* - * Operations defined on a XDR handle - * - * XDR *xdrs; - * long *longp; - * caddr_t addr; - * uint_t len; - * uint_t pos; - */ -#if !defined(_KERNEL) -#define XDR_GETLONG(xdrs, longp) \ - (*(xdrs)->x_ops->x_getlong)(xdrs, longp) -#define xdr_getlong(xdrs, longp) \ - (*(xdrs)->x_ops->x_getlong)(xdrs, longp) - -#define XDR_PUTLONG(xdrs, longp) \ - (*(xdrs)->x_ops->x_putlong)(xdrs, longp) -#define xdr_putlong(xdrs, longp) \ - (*(xdrs)->x_ops->x_putlong)(xdrs, longp) -#endif /* KERNEL */ - - -#if !defined(_LP64) && !defined(_KERNEL) - -/* - * For binary compatability on ILP32 we do not change the shape - * of the XDR structure and the GET/PUTINT32 functions just use - * the get/putlong vectors which operate on identically-sized - * units of data. - */ - -#define XDR_GETINT32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_getlong)(xdrs, (long *)int32p) -#define xdr_getint32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_getlong)(xdrs, (long *)int32p) - -#define XDR_PUTINT32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_putlong)(xdrs, (long *)int32p) -#define xdr_putint32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_putlong)(xdrs, (long *)int32p) - -#else /* !_LP64 && !_KERNEL */ - -#define XDR_GETINT32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_getint32)(xdrs, int32p) -#define xdr_getint32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_getint32)(xdrs, int32p) - -#define XDR_PUTINT32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_putint32)(xdrs, int32p) -#define xdr_putint32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_putint32)(xdrs, int32p) - -#endif /* !_LP64 && !_KERNEL */ - -#define XDR_GETBYTES(xdrs, addr, len) \ - (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) -#define xdr_getbytes(xdrs, addr, len) \ - (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) - -#define XDR_PUTBYTES(xdrs, addr, len) \ - (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) -#define xdr_putbytes(xdrs, addr, len) \ - (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) - -#define XDR_GETPOS(xdrs) \ - (*(xdrs)->x_ops->x_getpostn)(xdrs) -#define xdr_getpos(xdrs) \ - (*(xdrs)->x_ops->x_getpostn)(xdrs) - -#define XDR_SETPOS(xdrs, pos) \ - (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) -#define xdr_setpos(xdrs, pos) \ - (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) - -#define XDR_INLINE(xdrs, len) \ - (*(xdrs)->x_ops->x_inline)(xdrs, len) -#define xdr_inline(xdrs, len) \ - (*(xdrs)->x_ops->x_inline)(xdrs, len) - -#define XDR_DESTROY(xdrs) \ - (*(xdrs)->x_ops->x_destroy)(xdrs) -#define xdr_destroy(xdrs) \ - (*(xdrs)->x_ops->x_destroy)(xdrs) - -#define XDR_CONTROL(xdrs, req, op) \ - (*(xdrs)->x_ops->x_control)(xdrs, req, op) -#define xdr_control(xdrs, req, op) \ - (*(xdrs)->x_ops->x_control)(xdrs, req, op) - -/* - * Support struct for discriminated unions. - * You create an array of xdrdiscrim structures, terminated with - * a entry with a null procedure pointer. The xdr_union routine gets - * the discriminant value and then searches the array of structures - * for a matching value. If a match is found the associated xdr routine - * is called to handle that part of the union. If there is - * no match, then a default routine may be called. - * If there is no match and no default routine it is an error. - */ - - -/* - * A xdrproc_t exists for each data type which is to be encoded or decoded. - * - * The second argument to the xdrproc_t is a pointer to an opaque pointer. - * The opaque pointer generally points to a structure of the data type - * to be decoded. If this pointer is 0, then the type routines should - * allocate dynamic storage of the appropriate size and return it. - * bool_t (*xdrproc_t)(XDR *, void *); - */ -#ifdef __cplusplus -typedef bool_t (*xdrproc_t)(XDR *, void *); -#else -#ifdef __STDC__ -typedef bool_t (*xdrproc_t)(); /* For Backward compatibility */ -#else -typedef bool_t (*xdrproc_t)(); -#endif -#endif - -#define NULL_xdrproc_t ((xdrproc_t)0) - -#if defined(_LP64) || defined(_I32LPx) -#define xdr_rpcvers(xdrs, versp) xdr_u_int(xdrs, versp) -#define xdr_rpcprog(xdrs, progp) xdr_u_int(xdrs, progp) -#define xdr_rpcproc(xdrs, procp) xdr_u_int(xdrs, procp) -#define xdr_rpcprot(xdrs, protp) xdr_u_int(xdrs, protp) -#define xdr_rpcport(xdrs, portp) xdr_u_int(xdrs, portp) -#else -#define xdr_rpcvers(xdrs, versp) xdr_u_long(xdrs, versp) -#define xdr_rpcprog(xdrs, progp) xdr_u_long(xdrs, progp) -#define xdr_rpcproc(xdrs, procp) xdr_u_long(xdrs, procp) -#define xdr_rpcprot(xdrs, protp) xdr_u_long(xdrs, protp) -#define xdr_rpcport(xdrs, portp) xdr_u_long(xdrs, portp) -#endif - -struct xdr_discrim { - int value; - xdrproc_t proc; -}; - -/* - * In-line routines for fast encode/decode of primitve data types. - * Caveat emptor: these use single memory cycles to get the - * data from the underlying buffer, and will fail to operate - * properly if the data is not aligned. The standard way to use these - * is to say: - * if ((buf = XDR_INLINE(xdrs, count)) == NULL) - * return (FALSE); - * <<< macro calls >>> - * where ``count'' is the number of bytes of data occupied - * by the primitive data types. - * - * N.B. and frozen for all time: each data type here uses 4 bytes - * of external representation. - */ - -#define IXDR_GET_INT32(buf) ((int32_t)ntohl((uint32_t)*(buf)++)) -#define IXDR_PUT_INT32(buf, v) (*(buf)++ = (int32_t)htonl((uint32_t)v)) -#define IXDR_GET_U_INT32(buf) ((uint32_t)IXDR_GET_INT32(buf)) -#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32((buf), ((int32_t)(v))) - -#if !defined(_KERNEL) && !defined(_LP64) - -#define IXDR_GET_LONG(buf) ((long)ntohl((ulong_t)*(buf)++)) -#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((ulong_t)v)) -#define IXDR_GET_U_LONG(buf) ((ulong_t)IXDR_GET_LONG(buf)) -#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) - -#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) -#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) -#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) -#define IXDR_GET_U_SHORT(buf) ((ushort_t)IXDR_GET_LONG(buf)) - -#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) -#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) -#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) -#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) - -#else - -#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_INT32(buf)) -#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_INT32(buf)) -#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_INT32(buf)) -#define IXDR_GET_U_SHORT(buf) ((ushort_t)IXDR_GET_INT32(buf)) - -#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_INT32((buf), ((int)(v))) -#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_INT32((buf), ((int)(v))) -#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_INT32((buf), ((int)(v))) -#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_INT32((buf), ((int)(v))) - -#endif - -#if BYTE_ORDER == _LITTLE_ENDIAN -#define IXDR_GET_HYPER(buf, v) { \ - *((int32_t *)(&v)) = ntohl(*(uint32_t *)buf++); \ - *((int32_t *)(((char *)&v) + BYTES_PER_XDR_UNIT)) \ - = ntohl(*(uint32_t *)buf++); \ - } -#define IXDR_PUT_HYPER(buf, v) { \ - *(buf)++ = (int32_t)htonl(*(uint32_t *) \ - ((char *)&v)); \ - *(buf)++ = \ - (int32_t)htonl(*(uint32_t *)(((char *)&v) \ - + BYTES_PER_XDR_UNIT)); \ - } -#else - -#define IXDR_GET_HYPER(buf, v) { \ - *((int32_t *)(((char *)&v) + \ - BYTES_PER_XDR_UNIT)) \ - = ntohl(*(uint32_t *)buf++); \ - *((int32_t *)(&v)) = \ - ntohl(*(uint32_t *)buf++); \ - } - -#define IXDR_PUT_HYPER(buf, v) { \ - *(buf)++ = \ - (int32_t)htonl(*(uint32_t *)(((char *)&v) + \ - BYTES_PER_XDR_UNIT)); \ - *(buf)++ = \ - (int32_t)htonl(*(uint32_t *)((char *)&v)); \ - } -#endif -#define IXDR_GET_U_HYPER(buf, v) IXDR_GET_HYPER(buf, v) -#define IXDR_PUT_U_HYPER(buf, v) IXDR_PUT_HYPER(buf, v) - - -/* - * These are the "generic" xdr routines. - */ -#ifdef __STDC__ -extern bool_t xdr_void(void); -extern bool_t xdr_int(XDR *, int *); -extern bool_t xdr_u_int(XDR *, uint_t *); -extern bool_t xdr_long(XDR *, long *); -extern bool_t xdr_u_long(XDR *, ulong_t *); -extern bool_t xdr_short(XDR *, short *); -extern bool_t xdr_u_short(XDR *, ushort_t *); -extern bool_t xdr_bool(XDR *, bool_t *); -extern bool_t xdr_enum(XDR *, enum_t *); -extern bool_t xdr_array(XDR *, caddr_t *, uint_t *, const uint_t, - const uint_t, const xdrproc_t); -extern bool_t xdr_bytes(XDR *, char **, uint_t *, const uint_t); -extern bool_t xdr_opaque(XDR *, caddr_t, const uint_t); -extern bool_t xdr_string(XDR *, char **, const uint_t); -extern bool_t xdr_union(XDR *, enum_t *, char *, - const struct xdr_discrim *, const xdrproc_t); -extern unsigned int xdr_sizeof(xdrproc_t, void *); - -extern bool_t xdr_hyper(XDR *, longlong_t *); -extern bool_t xdr_longlong_t(XDR *, longlong_t *); -extern bool_t xdr_u_hyper(XDR *, u_longlong_t *); -extern bool_t xdr_u_longlong_t(XDR *, u_longlong_t *); - -extern bool_t xdr_char(XDR *, char *); -extern bool_t xdr_wrapstring(XDR *, char **); -extern bool_t xdr_reference(XDR *, caddr_t *, uint_t, const xdrproc_t); -extern bool_t xdr_pointer(XDR *, char **, uint_t, const xdrproc_t); -extern void xdr_free(xdrproc_t, char *); -extern bool_t xdr_time_t(XDR *, time_t *); - -extern bool_t xdr_int8_t(XDR *, int8_t *); -extern bool_t xdr_uint8_t(XDR *, uint8_t *); -extern bool_t xdr_int16_t(XDR *, int16_t *); -extern bool_t xdr_uint16_t(XDR *, uint16_t *); -extern bool_t xdr_int32_t(XDR *, int32_t *); -extern bool_t xdr_uint32_t(XDR *, uint32_t *); -#if defined(_INT64_TYPE) -extern bool_t xdr_int64_t(XDR *, int64_t *); -extern bool_t xdr_uint64_t(XDR *, uint64_t *); -#endif - -#ifndef _KERNEL -extern bool_t xdr_u_char(XDR *, uchar_t *); -extern bool_t xdr_vector(XDR *, char *, const uint_t, const uint_t, const -xdrproc_t); -extern bool_t xdr_float(XDR *, float *); -extern bool_t xdr_double(XDR *, double *); -extern bool_t xdr_quadruple(XDR *, long double *); -#endif /* !_KERNEL */ -#else -extern bool_t xdr_void(); -extern bool_t xdr_int(); -extern bool_t xdr_u_int(); -extern bool_t xdr_long(); -extern bool_t xdr_u_long(); -extern bool_t xdr_short(); -extern bool_t xdr_u_short(); -extern bool_t xdr_bool(); -extern bool_t xdr_enum(); -extern bool_t xdr_array(); -extern bool_t xdr_bytes(); -extern bool_t xdr_opaque(); -extern bool_t xdr_string(); -extern bool_t xdr_union(); - -extern bool_t xdr_hyper(); -extern bool_t xdr_longlong_t(); -extern bool_t xdr_u_hyper(); -extern bool_t xdr_u_longlong_t(); -extern bool_t xdr_char(); -extern bool_t xdr_reference(); -extern bool_t xdr_pointer(); -extern void xdr_free(); -extern bool_t xdr_wrapstring(); -extern bool_t xdr_time_t(); - -extern bool_t xdr_int8_t(); -extern bool_t xdr_uint8_t(); -extern bool_t xdr_int16_t(); -extern bool_t xdr_uint16_t(); -extern bool_t xdr_int32_t(); -extern bool_t xdr_uint32_t(); -#if defined(_INT64_TYPE) -extern bool_t xdr_int64_t(); -extern bool_t xdr_uint64_t(); -#endif - -#ifndef _KERNEL -extern bool_t xdr_u_char(); -extern bool_t xdr_vector(); -extern bool_t xdr_float(); -extern bool_t xdr_double(); -extern bool_t xdr_quadruple(); -#endif /* !_KERNEL */ -#endif - -/* - * Common opaque bytes objects used by many rpc protocols; - * declared here due to commonality. - */ -#define MAX_NETOBJ_SZ 1024 -struct netobj { - uint_t n_len; - char *n_bytes; -}; -typedef struct netobj netobj; - -#ifdef __STDC__ -extern bool_t xdr_netobj(XDR *, netobj *); -#else -extern bool_t xdr_netobj(); -#endif - -/* - * These are XDR control operators - */ - -#define XDR_GET_BYTES_AVAIL 1 - -struct xdr_bytesrec { - bool_t xc_is_last_record; - size_t xc_num_avail; -}; - -typedef struct xdr_bytesrec xdr_bytesrec; - -/* - * These are the request arguments to XDR_CONTROL. - * - * XDR_PEEK - returns the contents of the next XDR unit on the XDR stream. - * XDR_SKIPBYTES - skips the next N bytes in the XDR stream. - * XDR_RDMAGET - for xdr implementation over RDMA, gets private flags from - * the XDR stream being moved over RDMA - * XDR_RDMANOCHUNK - for xdr implementaion over RDMA, sets private flags in - * the XDR stream moving over RDMA. - */ -#ifdef _KERNEL -#define XDR_PEEK 2 -#define XDR_SKIPBYTES 3 -#define XDR_RDMA_GET_FLAGS 4 -#define XDR_RDMA_SET_FLAGS 5 -#define XDR_RDMA_ADD_CHUNK 6 -#define XDR_RDMA_GET_CHUNK_LEN 7 -#define XDR_RDMA_SET_WLIST 8 -#define XDR_RDMA_GET_WLIST 9 -#define XDR_RDMA_GET_WCINFO 10 -#define XDR_RDMA_GET_RLIST 11 -#endif - -/* - * These are the public routines for the various implementations of - * xdr streams. - */ -#ifndef _KERNEL -#ifdef __STDC__ -extern void xdrmem_create(XDR *, const caddr_t, const uint_t, const enum -xdr_op); - /* XDR using memory buffers */ -extern void xdrrec_create(XDR *, const uint_t, const uint_t, const caddr_t, -int (*) (void *, caddr_t, int), int (*) (void *, caddr_t, int)); -/* XDR pseudo records for tcp */ -extern bool_t xdrrec_endofrecord(XDR *, bool_t); -/* make end of xdr record */ -extern bool_t xdrrec_skiprecord(XDR *); -/* move to beginning of next record */ -extern bool_t xdrrec_eof(XDR *); -extern uint_t xdrrec_readbytes(XDR *, caddr_t, uint_t); -/* true if no more input */ -#else -extern void xdrmem_create(); -extern void xdrstdio_create(); -extern void xdrrec_create(); -extern bool_t xdrrec_endofrecord(); -extern bool_t xdrrec_skiprecord(); -extern bool_t xdrrec_eof(); -extern uint_t xdrrec_readbytes(); -#endif -#else - -extern void xdrmem_create(XDR *, caddr_t, uint_t, enum xdr_op); -extern struct xdr_ops xdrmblk_ops; -extern struct xdr_ops xdrrdmablk_ops; -extern struct xdr_ops xdrrdma_ops; - -struct rpc_msg; -extern bool_t xdr_callmsg(XDR *, struct rpc_msg *); -extern bool_t xdr_replymsg_body(XDR *, struct rpc_msg *); -extern bool_t xdr_replymsg_hdr(XDR *, struct rpc_msg *); - -#include -#ifdef mem_alloc -#undef mem_alloc -#define mem_alloc(size) malloc((size), M_TEMP, M_WAITOK | M_ZERO) -#endif -#ifdef mem_free -#undef mem_free -#define mem_free(ptr, size) free((ptr), M_TEMP) -#endif - -#endif /* !_KERNEL */ - -#ifdef __cplusplus -} -#endif - -#endif /* !_RPC_XDR_H */ From 4aae820003fab650d8095cfba671ca607e5e19cc Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 08:38:41 +0000 Subject: [PATCH 0067/2592] MFC r196291: - Fix a race where /dev/zfs control device is created before ZFS is fully initialized. Also destroy /dev/zfs before doing other deinitializations. - Initialization through taskq is no longer needed and there is a race where one of the zpool/zfs command loads zfs.ko and tries to do some work immediately, but /dev/zfs is not there yet. Reported by: pav Approved by: re (kib) --- .../opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index f2c6e76dca8..ded407e37f7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -3056,44 +3056,35 @@ zfsdev_fini(void) destroy_dev(zfsdev); } -static struct task zfs_start_task; static struct root_hold_token *zfs_root_token; - uint_t zfs_fsyncer_key; extern uint_t rrw_tsd_key; -static void -zfs_start(void *context __unused, int pending __unused) -{ - - zfsdev_init(); - spa_init(FREAD | FWRITE); - zfs_init(); - zvol_init(); - - tsd_create(&zfs_fsyncer_key, NULL); - tsd_create(&rrw_tsd_key, NULL); - - printf("ZFS storage pool version " SPA_VERSION_STRING "\n"); - root_mount_rel(zfs_root_token); -} - static int zfs_modevent(module_t mod, int type, void *unused __unused) { - int error; + int error = 0; - error = EOPNOTSUPP; switch (type) { case MOD_LOAD: zfs_root_token = root_mount_hold("ZFS"); printf("WARNING: ZFS is considered to be an experimental " "feature in FreeBSD.\n"); - TASK_INIT(&zfs_start_task, 0, zfs_start, NULL); - taskqueue_enqueue(taskqueue_thread, &zfs_start_task); + mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL); - error = 0; + + spa_init(FREAD | FWRITE); + zfs_init(); + zvol_init(); + + tsd_create(&zfs_fsyncer_key, NULL); + tsd_create(&rrw_tsd_key, NULL); + + printf("ZFS storage pool version " SPA_VERSION_STRING "\n"); + root_mount_rel(zfs_root_token); + + zfsdev_init(); break; case MOD_UNLOAD: if (spa_busy() || zfs_busy() || zvol_busy() || @@ -3101,14 +3092,19 @@ zfs_modevent(module_t mod, int type, void *unused __unused) error = EBUSY; break; } + + zfsdev_fini(); zvol_fini(); zfs_fini(); spa_fini(); - zfsdev_fini(); + tsd_destroy(&zfs_fsyncer_key); tsd_destroy(&rrw_tsd_key); + mutex_destroy(&zfs_share_lock); - error = 0; + break; + default: + error = EOPNOTSUPP; break; } return (error); From ea5f504fed085eba4540b59651fbd57056995284 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 08:46:47 +0000 Subject: [PATCH 0068/2592] MFC r196293: Because taskqueue_run() can drop tq_mutex, we need to check if the TQ_FLAGS_ACTIVE flag wasn't removed in the meantime, which means we missed a wakeup. Approved by: re (kib) --- sys/kern/subr_taskqueue.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c index bd4f34d9b9b..e49c8024ecf 100644 --- a/sys/kern/subr_taskqueue.c +++ b/sys/kern/subr_taskqueue.c @@ -401,6 +401,13 @@ taskqueue_thread_loop(void *arg) TQ_LOCK(tq); while ((tq->tq_flags & TQ_FLAGS_ACTIVE) != 0) { taskqueue_run(tq); + /* + * Because taskqueue_run() can drop tq_mutex, we need to + * check if the TQ_FLAGS_ACTIVE flag wasn't removed in the + * meantime, which means we missed a wakeup. + */ + if ((tq->tq_flags & TQ_FLAGS_ACTIVE) == 0) + break; TQ_SLEEP(tq, tq, &tq->tq_mutex, 0, "-", 0); } From e43f1736025f4815411d70c690b31e86af0255c6 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 09:03:47 +0000 Subject: [PATCH 0069/2592] MFC r196295: Remove OpenSolaris taskq port (it performs very poorly in our kernel) and replace it with wrappers around our taskqueue(9). To make it possible implement taskqueue_member() function which returns 1 if the given thread was created by the given taskqueue. Approved by: re (kib) --- share/man/man9/taskqueue.9 | 16 +- .../opensolaris/kern/opensolaris_taskq.c | 135 +++ sys/cddl/compat/opensolaris/sys/taskq_impl.h | 137 --- .../uts/common/fs/zfs/sys/zfs_context.h | 1 + .../contrib/opensolaris/uts/common/os/taskq.c | 1041 ----------------- .../opensolaris/uts/common}/sys/taskq.h | 24 +- sys/kern/subr_taskqueue.c | 20 + sys/modules/zfs/Makefile | 2 +- sys/sys/taskqueue.h | 2 + 9 files changed, 188 insertions(+), 1190 deletions(-) create mode 100644 sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c delete mode 100644 sys/cddl/compat/opensolaris/sys/taskq_impl.h delete mode 100644 sys/cddl/contrib/opensolaris/uts/common/os/taskq.c rename sys/cddl/{compat/opensolaris => contrib/opensolaris/uts/common}/sys/taskq.h (83%) diff --git a/share/man/man9/taskqueue.9 b/share/man/man9/taskqueue.9 index 241b20f4869..589c3c644fd 100644 --- a/share/man/man9/taskqueue.9 +++ b/share/man/man9/taskqueue.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 13, 2008 +.Dd August 17, 2009 .Dt TASKQUEUE 9 .Os .Sh NAME @@ -71,6 +71,8 @@ struct task { .Fn taskqueue_run_fast "struct taskqueue *queue" .Ft void .Fn taskqueue_drain "struct taskqueue *queue" "struct task *task" +.Ft int +.Fn taskqueue_member "struct taskqueue *queue" "struct thread *td" .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context" .Fn TASKQUEUE_DECLARE "name" .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" @@ -182,6 +184,18 @@ There is no guarantee that the task will not be enqueued after call to .Fn taskqueue_drain . .Pp +The +.Fn taskqueue_member +function returns +.No 1 +is the given thread +.Fa td +is part of the given taskqeueue +.Fa queue +and +.No 0 +otherwise. +.Pp A convenience macro, .Fn TASK_INIT "task" "priority" "func" "context" is provided to initialise a diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c new file mode 100644 index 00000000000..584be24100e --- /dev/null +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c @@ -0,0 +1,135 @@ +/*- + * Copyright (c) 2009 Pawel Jakub Dawidek + * 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 AUTHORS 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 AUTHORS 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 uma_zone_t taskq_zone; + +struct ostask { + struct task ost_task; + task_func_t *ost_func; + void *ost_arg; +}; + +taskq_t *system_taskq = NULL; + +static void +system_taskq_init(void *arg) +{ + + system_taskq = (taskq_t *)taskqueue_thread; + taskq_zone = uma_zcreate("taskq_zone", sizeof(struct ostask), + NULL, NULL, NULL, NULL, 0, 0); +} +SYSINIT(system_taskq_init, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_init, NULL); + +static void +system_taskq_fini(void *arg) +{ + + uma_zdestroy(taskq_zone); +} +SYSUNINIT(system_taskq_fini, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_fini, NULL); + +taskq_t * +taskq_create(const char *name, int nthreads, pri_t pri, int minalloc __unused, + int maxalloc __unused, uint_t flags) +{ + taskq_t *tq; + + if ((flags & TASKQ_THREADS_CPU_PCT) != 0) { + /* TODO: Calculate number od threads. */ + printf("%s: TASKQ_THREADS_CPU_PCT\n", __func__); + } + + tq = kmem_alloc(sizeof(*tq), KM_SLEEP); + tq->tq_queue = taskqueue_create(name, M_WAITOK, taskqueue_thread_enqueue, + &tq->tq_queue); + (void) taskqueue_start_threads(&tq->tq_queue, nthreads, pri, name); + + return ((taskq_t *)tq); +} + +void +taskq_destroy(taskq_t *tq) +{ + + taskqueue_free(tq->tq_queue); + kmem_free(tq, sizeof(*tq)); +} + +int +taskq_member(taskq_t *tq, kthread_t *thread) +{ + + return (taskqueue_member(tq->tq_queue, thread)); +} + +static void +taskq_run(void *arg, int pending __unused) +{ + struct ostask *task = arg; + + task->ost_func(task->ost_arg); + + uma_zfree(taskq_zone, task); +} + +taskqid_t +taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags) +{ + struct ostask *task; + int mflag; + + if ((flags & (TQ_SLEEP | TQ_NOQUEUE)) == TQ_SLEEP) + mflag = M_WAITOK; + else + mflag = M_NOWAIT; + + task = uma_zalloc(taskq_zone, mflag); + if (task == NULL) + return (0); + + task->ost_func = func; + task->ost_arg = arg; + + TASK_INIT(&task->ost_task, 0, taskq_run, task); + taskqueue_enqueue(tq->tq_queue, &task->ost_task); + + return ((taskqid_t)(void *)task); +} diff --git a/sys/cddl/compat/opensolaris/sys/taskq_impl.h b/sys/cddl/compat/opensolaris/sys/taskq_impl.h deleted file mode 100644 index a9b59bb755e..00000000000 --- a/sys/cddl/compat/opensolaris/sys/taskq_impl.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * $FreeBSD$ - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_TASKQ_IMPL_H -#define _SYS_TASKQ_IMPL_H - -#pragma ident "@(#)taskq_impl.h 1.6 05/06/08 SMI" - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct taskq_bucket taskq_bucket_t; - -typedef struct taskq_ent { - struct taskq_ent *tqent_next; - struct taskq_ent *tqent_prev; - task_func_t *tqent_func; - void *tqent_arg; - taskq_bucket_t *tqent_bucket; - kthread_t *tqent_thread; - kcondvar_t tqent_cv; -} taskq_ent_t; - -/* - * Taskq Statistics fields are not protected by any locks. - */ -typedef struct tqstat { - uint_t tqs_hits; - uint_t tqs_misses; - uint_t tqs_overflow; /* no threads to allocate */ - uint_t tqs_tcreates; /* threads created */ - uint_t tqs_tdeaths; /* threads died */ - uint_t tqs_maxthreads; /* max # of alive threads */ - uint_t tqs_nomem; /* # of times there were no memory */ - uint_t tqs_disptcreates; -} tqstat_t; - -/* - * Per-CPU hash bucket manages taskq_bent_t structures using freelist. - */ -struct taskq_bucket { - kmutex_t tqbucket_lock; - taskq_t *tqbucket_taskq; /* Enclosing taskq */ - taskq_ent_t tqbucket_freelist; - uint_t tqbucket_nalloc; /* # of allocated entries */ - uint_t tqbucket_nfree; /* # of free entries */ - kcondvar_t tqbucket_cv; - ushort_t tqbucket_flags; - hrtime_t tqbucket_totaltime; - tqstat_t tqbucket_stat; -}; - -/* - * Bucket flags. - */ -#define TQBUCKET_CLOSE 0x01 -#define TQBUCKET_SUSPEND 0x02 - -/* - * taskq implementation flags: bit range 16-31 - */ -#define TASKQ_ACTIVE 0x00010000 -#define TASKQ_SUSPENDED 0x00020000 -#define TASKQ_NOINSTANCE 0x00040000 - -struct taskq { - char tq_name[TASKQ_NAMELEN + 1]; - kmutex_t tq_lock; - krwlock_t tq_threadlock; - kcondvar_t tq_dispatch_cv; - kcondvar_t tq_wait_cv; - uint_t tq_flags; - int tq_active; - int tq_nthreads; - int tq_nalloc; - int tq_minalloc; - int tq_maxalloc; - taskq_ent_t *tq_freelist; - taskq_ent_t tq_task; - int tq_maxsize; - pri_t tq_pri; /* Scheduling priority */ - taskq_bucket_t *tq_buckets; /* Per-cpu array of buckets */ - uint_t tq_nbuckets; /* # of buckets (2^n) */ - union { - kthread_t *_tq_thread; - kthread_t **_tq_threadlist; - } tq_thr; - /* - * Statistics. - */ - hrtime_t tq_totaltime; /* Time spent processing tasks */ - int tq_tasks; /* Total # of tasks posted */ - int tq_executed; /* Total # of tasks executed */ - int tq_maxtasks; /* Max number of tasks in the queue */ - int tq_tcreates; - int tq_tdeaths; -}; - -#define tq_thread tq_thr._tq_thread -#define tq_threadlist tq_thr._tq_threadlist - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_TASKQ_IMPL_H */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h index 76fdc0dce7a..0dd8f4f5c50 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h @@ -49,6 +49,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/sys/cddl/contrib/opensolaris/uts/common/os/taskq.c b/sys/cddl/contrib/opensolaris/uts/common/os/taskq.c deleted file mode 100644 index 154ead4b8c2..00000000000 --- a/sys/cddl/contrib/opensolaris/uts/common/os/taskq.c +++ /dev/null @@ -1,1041 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Kernel task queues: general-purpose asynchronous task scheduling. - * - * A common problem in kernel programming is the need to schedule tasks - * to be performed later, by another thread. There are several reasons - * you may want or need to do this: - * - * (1) The task isn't time-critical, but your current code path is. - * - * (2) The task may require grabbing locks that you already hold. - * - * (3) The task may need to block (e.g. to wait for memory), but you - * cannot block in your current context. - * - * (4) Your code path can't complete because of some condition, but you can't - * sleep or fail, so you queue the task for later execution when condition - * disappears. - * - * (5) You just want a simple way to launch multiple tasks in parallel. - * - * Task queues provide such a facility. In its simplest form (used when - * performance is not a critical consideration) a task queue consists of a - * single list of tasks, together with one or more threads to service the - * list. There are some cases when this simple queue is not sufficient: - * - * (1) The task queues are very hot and there is a need to avoid data and lock - * contention over global resources. - * - * (2) Some tasks may depend on other tasks to complete, so they can't be put in - * the same list managed by the same thread. - * - * (3) Some tasks may block for a long time, and this should not block other - * tasks in the queue. - * - * To provide useful service in such cases we define a "dynamic task queue" - * which has an individual thread for each of the tasks. These threads are - * dynamically created as they are needed and destroyed when they are not in - * use. The API for managing task pools is the same as for managing task queues - * with the exception of a taskq creation flag TASKQ_DYNAMIC which tells that - * dynamic task pool behavior is desired. - * - * Dynamic task queues may also place tasks in the normal queue (called "backing - * queue") when task pool runs out of resources. Users of task queues may - * disallow such queued scheduling by specifying TQ_NOQUEUE in the dispatch - * flags. - * - * The backing task queue is also used for scheduling internal tasks needed for - * dynamic task queue maintenance. - * - * INTERFACES: - * - * taskq_t *taskq_create(name, nthreads, pri_t pri, minalloc, maxall, flags); - * - * Create a taskq with specified properties. - * Possible 'flags': - * - * TASKQ_DYNAMIC: Create task pool for task management. If this flag is - * specified, 'nthreads' specifies the maximum number of threads in - * the task queue. Task execution order for dynamic task queues is - * not predictable. - * - * If this flag is not specified (default case) a - * single-list task queue is created with 'nthreads' threads - * servicing it. Entries in this queue are managed by - * taskq_ent_alloc() and taskq_ent_free() which try to keep the - * task population between 'minalloc' and 'maxalloc', but the - * latter limit is only advisory for TQ_SLEEP dispatches and the - * former limit is only advisory for TQ_NOALLOC dispatches. If - * TASKQ_PREPOPULATE is set in 'flags', the taskq will be - * prepopulated with 'minalloc' task structures. - * - * Since non-DYNAMIC taskqs are queues, tasks are guaranteed to be - * executed in the order they are scheduled if nthreads == 1. - * If nthreads > 1, task execution order is not predictable. - * - * TASKQ_PREPOPULATE: Prepopulate task queue with threads. - * Also prepopulate the task queue with 'minalloc' task structures. - * - * TASKQ_CPR_SAFE: This flag specifies that users of the task queue will - * use their own protocol for handling CPR issues. This flag is not - * supported for DYNAMIC task queues. - * - * The 'pri' field specifies the default priority for the threads that - * service all scheduled tasks. - * - * void taskq_destroy(tap): - * - * Waits for any scheduled tasks to complete, then destroys the taskq. - * Caller should guarantee that no new tasks are scheduled in the closing - * taskq. - * - * taskqid_t taskq_dispatch(tq, func, arg, flags): - * - * Dispatches the task "func(arg)" to taskq. The 'flags' indicates whether - * the caller is willing to block for memory. The function returns an - * opaque value which is zero iff dispatch fails. If flags is TQ_NOSLEEP - * or TQ_NOALLOC and the task can't be dispatched, taskq_dispatch() fails - * and returns (taskqid_t)0. - * - * ASSUMES: func != NULL. - * - * Possible flags: - * TQ_NOSLEEP: Do not wait for resources; may fail. - * - * TQ_NOALLOC: Do not allocate memory; may fail. May only be used with - * non-dynamic task queues. - * - * TQ_NOQUEUE: Do not enqueue a task if it can't dispatch it due to - * lack of available resources and fail. If this flag is not - * set, and the task pool is exhausted, the task may be scheduled - * in the backing queue. This flag may ONLY be used with dynamic - * task queues. - * - * NOTE: This flag should always be used when a task queue is used - * for tasks that may depend on each other for completion. - * Enqueueing dependent tasks may create deadlocks. - * - * TQ_SLEEP: May block waiting for resources. May still fail for - * dynamic task queues if TQ_NOQUEUE is also specified, otherwise - * always succeed. - * - * NOTE: Dynamic task queues are much more likely to fail in - * taskq_dispatch() (especially if TQ_NOQUEUE was specified), so it - * is important to have backup strategies handling such failures. - * - * void taskq_wait(tq): - * - * Waits for all previously scheduled tasks to complete. - * - * NOTE: It does not stop any new task dispatches. - * Do NOT call taskq_wait() from a task: it will cause deadlock. - * - * void taskq_suspend(tq) - * - * Suspend all task execution. Tasks already scheduled for a dynamic task - * queue will still be executed, but all new scheduled tasks will be - * suspended until taskq_resume() is called. - * - * int taskq_suspended(tq) - * - * Returns 1 if taskq is suspended and 0 otherwise. It is intended to - * ASSERT that the task queue is suspended. - * - * void taskq_resume(tq) - * - * Resume task queue execution. - * - * int taskq_member(tq, thread) - * - * Returns 1 if 'thread' belongs to taskq 'tq' and 0 otherwise. The - * intended use is to ASSERT that a given function is called in taskq - * context only. - * - * system_taskq - * - * Global system-wide dynamic task queue for common uses. It may be used by - * any subsystem that needs to schedule tasks and does not need to manage - * its own task queues. It is initialized quite early during system boot. - * - * IMPLEMENTATION. - * - * This is schematic representation of the task queue structures. - * - * taskq: - * +-------------+ - * |tq_lock | +---< taskq_ent_free() - * +-------------+ | - * |... | | tqent: tqent: - * +-------------+ | +------------+ +------------+ - * | tq_freelist |-->| tqent_next |--> ... ->| tqent_next | - * +-------------+ +------------+ +------------+ - * |... | | ... | | ... | - * +-------------+ +------------+ +------------+ - * | tq_task | | - * | | +-------------->taskq_ent_alloc() - * +--------------------------------------------------------------------------+ - * | | | tqent tqent | - * | +---------------------+ +--> +------------+ +--> +------------+ | - * | | ... | | | func, arg | | | func, arg | | - * +>+---------------------+ <---|-+ +------------+ <---|-+ +------------+ | - * | tq_taskq.tqent_next | ----+ | | tqent_next | --->+ | | tqent_next |--+ - * +---------------------+ | +------------+ ^ | +------------+ - * +-| tq_task.tqent_prev | +--| tqent_prev | | +--| tqent_prev | ^ - * | +---------------------+ +------------+ | +------------+ | - * | |... | | ... | | | ... | | - * | +---------------------+ +------------+ | +------------+ | - * | ^ | | - * | | | | - * +--------------------------------------+--------------+ TQ_APPEND() -+ - * | | | - * |... | taskq_thread()-----+ - * +-------------+ - * | tq_buckets |--+-------> [ NULL ] (for regular task queues) - * +-------------+ | - * | DYNAMIC TASK QUEUES: - * | - * +-> taskq_bucket[nCPU] taskq_bucket_dispatch() - * +-------------------+ ^ - * +--->| tqbucket_lock | | - * | +-------------------+ +--------+ +--------+ - * | | tqbucket_freelist |-->| tqent |-->...| tqent | ^ - * | +-------------------+<--+--------+<--...+--------+ | - * | | ... | | thread | | thread | | - * | +-------------------+ +--------+ +--------+ | - * | +-------------------+ | - * taskq_dispatch()--+--->| tqbucket_lock | TQ_APPEND()------+ - * TQ_HASH() | +-------------------+ +--------+ +--------+ - * | | tqbucket_freelist |-->| tqent |-->...| tqent | - * | +-------------------+<--+--------+<--...+--------+ - * | | ... | | thread | | thread | - * | +-------------------+ +--------+ +--------+ - * +---> ... - * - * - * Task queues use tq_task field to link new entry in the queue. The queue is a - * circular doubly-linked list. Entries are put in the end of the list with - * TQ_APPEND() and processed from the front of the list by taskq_thread() in - * FIFO order. Task queue entries are cached in the free list managed by - * taskq_ent_alloc() and taskq_ent_free() functions. - * - * All threads used by task queues mark t_taskq field of the thread to - * point to the task queue. - * - * Dynamic Task Queues Implementation. - * - * For a dynamic task queues there is a 1-to-1 mapping between a thread and - * taskq_ent_structure. Each entry is serviced by its own thread and each thread - * is controlled by a single entry. - * - * Entries are distributed over a set of buckets. To avoid using modulo - * arithmetics the number of buckets is 2^n and is determined as the nearest - * power of two roundown of the number of CPUs in the system. Tunable - * variable 'taskq_maxbuckets' limits the maximum number of buckets. Each entry - * is attached to a bucket for its lifetime and can't migrate to other buckets. - * - * Entries that have scheduled tasks are not placed in any list. The dispatch - * function sets their "func" and "arg" fields and signals the corresponding - * thread to execute the task. Once the thread executes the task it clears the - * "func" field and places an entry on the bucket cache of free entries pointed - * by "tqbucket_freelist" field. ALL entries on the free list should have "func" - * field equal to NULL. The free list is a circular doubly-linked list identical - * in structure to the tq_task list above, but entries are taken from it in LIFO - * order - the last freed entry is the first to be allocated. The - * taskq_bucket_dispatch() function gets the most recently used entry from the - * free list, sets its "func" and "arg" fields and signals a worker thread. - * - * After executing each task a per-entry thread taskq_d_thread() places its - * entry on the bucket free list and goes to a timed sleep. If it wakes up - * without getting new task it removes the entry from the free list and destroys - * itself. The thread sleep time is controlled by a tunable variable - * `taskq_thread_timeout'. - * - * There is various statistics kept in the bucket which allows for later - * analysis of taskq usage patterns. Also, a global copy of taskq creation and - * death statistics is kept in the global taskq data structure. Since thread - * creation and death happen rarely, updating such global data does not present - * a performance problem. - * - * NOTE: Threads are not bound to any CPU and there is absolutely no association - * between the bucket and actual thread CPU, so buckets are used only to - * split resources and reduce resource contention. Having threads attached - * to the CPU denoted by a bucket may reduce number of times the job - * switches between CPUs. - * - * Current algorithm creates a thread whenever a bucket has no free - * entries. It would be nice to know how many threads are in the running - * state and don't create threads if all CPUs are busy with existing - * tasks, but it is unclear how such strategy can be implemented. - * - * Currently buckets are created statically as an array attached to task - * queue. On some system with nCPUs < max_ncpus it may waste system - * memory. One solution may be allocation of buckets when they are first - * touched, but it is not clear how useful it is. - * - * SUSPEND/RESUME implementation. - * - * Before executing a task taskq_thread() (executing non-dynamic task - * queues) obtains taskq's thread lock as a reader. The taskq_suspend() - * function gets the same lock as a writer blocking all non-dynamic task - * execution. The taskq_resume() function releases the lock allowing - * taskq_thread to continue execution. - * - * For dynamic task queues, each bucket is marked as TQBUCKET_SUSPEND by - * taskq_suspend() function. After that taskq_bucket_dispatch() always - * fails, so that taskq_dispatch() will either enqueue tasks for a - * suspended backing queue or fail if TQ_NOQUEUE is specified in dispatch - * flags. - * - * NOTE: taskq_suspend() does not immediately block any tasks already - * scheduled for dynamic task queues. It only suspends new tasks - * scheduled after taskq_suspend() was called. - * - * taskq_member() function works by comparing a thread t_taskq pointer with - * the passed thread pointer. - * - * LOCKS and LOCK Hierarchy: - * - * There are two locks used in task queues. - * - * 1) Task queue structure has a lock, protecting global task queue state. - * - * 2) Each per-CPU bucket has a lock for bucket management. - * - * If both locks are needed, task queue lock should be taken only after bucket - * lock. - * - * DEBUG FACILITIES. - * - * For DEBUG kernels it is possible to induce random failures to - * taskq_dispatch() function when it is given TQ_NOSLEEP argument. The value of - * taskq_dmtbf and taskq_smtbf tunables control the mean time between induced - * failures for dynamic and static task queues respectively. - * - * Setting TASKQ_STATISTIC to 0 will disable per-bucket statistics. - * - * TUNABLES - * - * system_taskq_size - Size of the global system_taskq. - * This value is multiplied by nCPUs to determine - * actual size. - * Default value: 64 - * - * taskq_thread_timeout - Maximum idle time for taskq_d_thread() - * Default value: 5 minutes - * - * taskq_maxbuckets - Maximum number of buckets in any task queue - * Default value: 128 - * - * taskq_search_depth - Maximum # of buckets searched for a free entry - * Default value: 4 - * - * taskq_dmtbf - Mean time between induced dispatch failures - * for dynamic task queues. - * Default value: UINT_MAX (no induced failures) - * - * taskq_smtbf - Mean time between induced dispatch failures - * for static task queues. - * Default value: UINT_MAX (no induced failures) - * - * CONDITIONAL compilation. - * - * TASKQ_STATISTIC - If set will enable bucket statistic (default). - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static kmem_cache_t *taskq_ent_cache, *taskq_cache; - -/* Global system task queue for common use */ -taskq_t *system_taskq; - -/* - * Maxmimum number of entries in global system taskq is - * system_taskq_size * max_ncpus - */ -#define SYSTEM_TASKQ_SIZE 1 -int system_taskq_size = SYSTEM_TASKQ_SIZE; - -/* - * Dynamic task queue threads that don't get any work within - * taskq_thread_timeout destroy themselves - */ -#define TASKQ_THREAD_TIMEOUT (60 * 5) -int taskq_thread_timeout = TASKQ_THREAD_TIMEOUT; - -#define TASKQ_MAXBUCKETS 128 -int taskq_maxbuckets = TASKQ_MAXBUCKETS; - -/* - * When a bucket has no available entries another buckets are tried. - * taskq_search_depth parameter limits the amount of buckets that we search - * before failing. This is mostly useful in systems with many CPUs where we may - * spend too much time scanning busy buckets. - */ -#define TASKQ_SEARCH_DEPTH 4 -int taskq_search_depth = TASKQ_SEARCH_DEPTH; - -/* - * Hashing function: mix various bits of x. May be pretty much anything. - */ -#define TQ_HASH(x) ((x) ^ ((x) >> 11) ^ ((x) >> 17) ^ ((x) ^ 27)) - -/* - * We do not create any new threads when the system is low on memory and start - * throttling memory allocations. The following macro tries to estimate such - * condition. - */ -#define ENOUGH_MEMORY() (freemem > throttlefree) - -/* - * Static functions. - */ -static taskq_t *taskq_create_common(const char *, int, int, pri_t, int, - int, uint_t); -static void taskq_thread(void *); -static int taskq_constructor(void *, void *, int); -static void taskq_destructor(void *, void *); -static int taskq_ent_constructor(void *, void *, int); -static void taskq_ent_destructor(void *, void *); -static taskq_ent_t *taskq_ent_alloc(taskq_t *, int); -static void taskq_ent_free(taskq_t *, taskq_ent_t *); - -/* - * Collect per-bucket statistic when TASKQ_STATISTIC is defined. - */ -#define TASKQ_STATISTIC 1 - -#if TASKQ_STATISTIC -#define TQ_STAT(b, x) b->tqbucket_stat.x++ -#else -#define TQ_STAT(b, x) -#endif - -/* - * Random fault injection. - */ -uint_t taskq_random; -uint_t taskq_dmtbf = UINT_MAX; /* mean time between injected failures */ -uint_t taskq_smtbf = UINT_MAX; /* mean time between injected failures */ - -/* - * TQ_NOSLEEP dispatches on dynamic task queues are always allowed to fail. - * - * TQ_NOSLEEP dispatches on static task queues can't arbitrarily fail because - * they could prepopulate the cache and make sure that they do not use more - * then minalloc entries. So, fault injection in this case insures that - * either TASKQ_PREPOPULATE is not set or there are more entries allocated - * than is specified by minalloc. TQ_NOALLOC dispatches are always allowed - * to fail, but for simplicity we treat them identically to TQ_NOSLEEP - * dispatches. - */ -#ifdef DEBUG -#define TASKQ_D_RANDOM_DISPATCH_FAILURE(tq, flag) \ - taskq_random = (taskq_random * 2416 + 374441) % 1771875;\ - if ((flag & TQ_NOSLEEP) && \ - taskq_random < 1771875 / taskq_dmtbf) { \ - return (NULL); \ - } - -#define TASKQ_S_RANDOM_DISPATCH_FAILURE(tq, flag) \ - taskq_random = (taskq_random * 2416 + 374441) % 1771875;\ - if ((flag & (TQ_NOSLEEP | TQ_NOALLOC)) && \ - (!(tq->tq_flags & TASKQ_PREPOPULATE) || \ - (tq->tq_nalloc > tq->tq_minalloc)) && \ - (taskq_random < (1771875 / taskq_smtbf))) { \ - mutex_exit(&tq->tq_lock); \ - return ((taskqid_t)0); \ - } -#else -#define TASKQ_S_RANDOM_DISPATCH_FAILURE(tq, flag) -#define TASKQ_D_RANDOM_DISPATCH_FAILURE(tq, flag) -#endif - -#define IS_EMPTY(l) (((l).tqent_prev == (l).tqent_next) && \ - ((l).tqent_prev == &(l))) - -/* - * Append `tqe' in the end of the doubly-linked list denoted by l. - */ -#define TQ_APPEND(l, tqe) { \ - tqe->tqent_next = &l; \ - tqe->tqent_prev = l.tqent_prev; \ - tqe->tqent_next->tqent_prev = tqe; \ - tqe->tqent_prev->tqent_next = tqe; \ -} - -/* - * Schedule a task specified by func and arg into the task queue entry tqe. - */ -#define TQ_ENQUEUE(tq, tqe, func, arg) { \ - ASSERT(MUTEX_HELD(&tq->tq_lock)); \ - TQ_APPEND(tq->tq_task, tqe); \ - tqe->tqent_func = (func); \ - tqe->tqent_arg = (arg); \ - tq->tq_tasks++; \ - if (tq->tq_tasks - tq->tq_executed > tq->tq_maxtasks) \ - tq->tq_maxtasks = tq->tq_tasks - tq->tq_executed; \ - cv_signal(&tq->tq_dispatch_cv); \ - DTRACE_PROBE2(taskq__enqueue, taskq_t *, tq, taskq_ent_t *, tqe); \ -} - -/* - * Do-nothing task which may be used to prepopulate thread caches. - */ -/*ARGSUSED*/ -void -nulltask(void *unused) -{ -} - - -/*ARGSUSED*/ -static int -taskq_constructor(void *buf, void *cdrarg, int kmflags) -{ - taskq_t *tq = buf; - - bzero(tq, sizeof (taskq_t)); - - mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL); - rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL); - cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL); - cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL); - - tq->tq_task.tqent_next = &tq->tq_task; - tq->tq_task.tqent_prev = &tq->tq_task; - - return (0); -} - -/*ARGSUSED*/ -static void -taskq_destructor(void *buf, void *cdrarg) -{ - taskq_t *tq = buf; - - mutex_destroy(&tq->tq_lock); - rw_destroy(&tq->tq_threadlock); - cv_destroy(&tq->tq_dispatch_cv); - cv_destroy(&tq->tq_wait_cv); -} - -/*ARGSUSED*/ -static int -taskq_ent_constructor(void *buf, void *cdrarg, int kmflags) -{ - taskq_ent_t *tqe = buf; - - tqe->tqent_thread = NULL; - cv_init(&tqe->tqent_cv, NULL, CV_DEFAULT, NULL); - - return (0); -} - -/*ARGSUSED*/ -static void -taskq_ent_destructor(void *buf, void *cdrarg) -{ - taskq_ent_t *tqe = buf; - - ASSERT(tqe->tqent_thread == NULL); - cv_destroy(&tqe->tqent_cv); -} - -/* - * Create global system dynamic task queue. - */ -void -system_taskq_init(void) -{ - system_taskq = taskq_create_common("system_taskq", 0, - system_taskq_size * max_ncpus, minclsyspri, 4, 512, - TASKQ_PREPOPULATE); -} - -void -system_taskq_fini(void) -{ - taskq_destroy(system_taskq); -} - -static void -taskq_init(void *dummy __unused) -{ - taskq_ent_cache = kmem_cache_create("taskq_ent_cache", - sizeof (taskq_ent_t), 0, taskq_ent_constructor, - taskq_ent_destructor, NULL, NULL, NULL, 0); - taskq_cache = kmem_cache_create("taskq_cache", sizeof (taskq_t), - 0, taskq_constructor, taskq_destructor, NULL, NULL, NULL, 0); - system_taskq_init(); -} - -static void -taskq_fini(void *dummy __unused) -{ - system_taskq_fini(); - kmem_cache_destroy(taskq_cache); - kmem_cache_destroy(taskq_ent_cache); -} - -/* - * taskq_ent_alloc() - * - * Allocates a new taskq_ent_t structure either from the free list or from the - * cache. Returns NULL if it can't be allocated. - * - * Assumes: tq->tq_lock is held. - */ -static taskq_ent_t * -taskq_ent_alloc(taskq_t *tq, int flags) -{ - int kmflags = (flags & TQ_NOSLEEP) ? KM_NOSLEEP : KM_SLEEP; - - taskq_ent_t *tqe; - - ASSERT(MUTEX_HELD(&tq->tq_lock)); - - /* - * TQ_NOALLOC allocations are allowed to use the freelist, even if - * we are below tq_minalloc. - */ - if ((tqe = tq->tq_freelist) != NULL && - ((flags & TQ_NOALLOC) || tq->tq_nalloc >= tq->tq_minalloc)) { - tq->tq_freelist = tqe->tqent_next; - } else { - if (flags & TQ_NOALLOC) - return (NULL); - - mutex_exit(&tq->tq_lock); - if (tq->tq_nalloc >= tq->tq_maxalloc) { - if (kmflags & KM_NOSLEEP) { - mutex_enter(&tq->tq_lock); - return (NULL); - } - /* - * We don't want to exceed tq_maxalloc, but we can't - * wait for other tasks to complete (and thus free up - * task structures) without risking deadlock with - * the caller. So, we just delay for one second - * to throttle the allocation rate. - */ - delay(hz); - } - tqe = kmem_cache_alloc(taskq_ent_cache, kmflags); - mutex_enter(&tq->tq_lock); - if (tqe != NULL) - tq->tq_nalloc++; - } - return (tqe); -} - -/* - * taskq_ent_free() - * - * Free taskq_ent_t structure by either putting it on the free list or freeing - * it to the cache. - * - * Assumes: tq->tq_lock is held. - */ -static void -taskq_ent_free(taskq_t *tq, taskq_ent_t *tqe) -{ - ASSERT(MUTEX_HELD(&tq->tq_lock)); - - if (tq->tq_nalloc <= tq->tq_minalloc) { - tqe->tqent_next = tq->tq_freelist; - tq->tq_freelist = tqe; - } else { - tq->tq_nalloc--; - mutex_exit(&tq->tq_lock); - kmem_cache_free(taskq_ent_cache, tqe); - mutex_enter(&tq->tq_lock); - } -} - -/* - * Dispatch a task. - * - * Assumes: func != NULL - * - * Returns: NULL if dispatch failed. - * non-NULL if task dispatched successfully. - * Actual return value is the pointer to taskq entry that was used to - * dispatch a task. This is useful for debugging. - */ -/* ARGSUSED */ -taskqid_t -taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags) -{ - taskq_ent_t *tqe = NULL; - - ASSERT(tq != NULL); - ASSERT(func != NULL); - ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC)); - - /* - * TQ_NOQUEUE flag can't be used with non-dynamic task queues. - */ - ASSERT(! (flags & TQ_NOQUEUE)); - - /* - * Enqueue the task to the underlying queue. - */ - mutex_enter(&tq->tq_lock); - - TASKQ_S_RANDOM_DISPATCH_FAILURE(tq, flags); - - if ((tqe = taskq_ent_alloc(tq, flags)) == NULL) { - mutex_exit(&tq->tq_lock); - return ((taskqid_t)NULL); - } - TQ_ENQUEUE(tq, tqe, func, arg); - mutex_exit(&tq->tq_lock); - return ((taskqid_t)tqe); -} - -/* - * Wait for all pending tasks to complete. - * Calling taskq_wait from a task will cause deadlock. - */ -void -taskq_wait(taskq_t *tq) -{ - - mutex_enter(&tq->tq_lock); - while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0) - cv_wait(&tq->tq_wait_cv, &tq->tq_lock); - mutex_exit(&tq->tq_lock); -} - -/* - * Suspend execution of tasks. - * - * Tasks in the queue part will be suspended immediately upon return from this - * function. Pending tasks in the dynamic part will continue to execute, but all - * new tasks will be suspended. - */ -void -taskq_suspend(taskq_t *tq) -{ - rw_enter(&tq->tq_threadlock, RW_WRITER); - - /* - * Mark task queue as being suspended. Needed for taskq_suspended(). - */ - mutex_enter(&tq->tq_lock); - ASSERT(!(tq->tq_flags & TASKQ_SUSPENDED)); - tq->tq_flags |= TASKQ_SUSPENDED; - mutex_exit(&tq->tq_lock); -} - -/* - * returns: 1 if tq is suspended, 0 otherwise. - */ -int -taskq_suspended(taskq_t *tq) -{ - return ((tq->tq_flags & TASKQ_SUSPENDED) != 0); -} - -/* - * Resume taskq execution. - */ -void -taskq_resume(taskq_t *tq) -{ - ASSERT(RW_WRITE_HELD(&tq->tq_threadlock)); - - mutex_enter(&tq->tq_lock); - ASSERT(tq->tq_flags & TASKQ_SUSPENDED); - tq->tq_flags &= ~TASKQ_SUSPENDED; - mutex_exit(&tq->tq_lock); - - rw_exit(&tq->tq_threadlock); -} - - -int -taskq_member(taskq_t *tq, kthread_t *thread) -{ - if (tq->tq_nthreads == 1) - return (tq->tq_thread == thread); - else { - int i, found = 0; - - mutex_enter(&tq->tq_lock); - for (i = 0; i < tq->tq_nthreads; i++) { - if (tq->tq_threadlist[i] == thread) { - found = 1; - break; - } - } - mutex_exit(&tq->tq_lock); - return (found); - } -} - -/* - * Worker thread for processing task queue. - */ -static void -taskq_thread(void *arg) -{ - taskq_t *tq = arg; - taskq_ent_t *tqe; - callb_cpr_t cprinfo; - hrtime_t start, end; - - CALLB_CPR_INIT(&cprinfo, &tq->tq_lock, callb_generic_cpr, tq->tq_name); - - mutex_enter(&tq->tq_lock); - while (tq->tq_flags & TASKQ_ACTIVE) { - if ((tqe = tq->tq_task.tqent_next) == &tq->tq_task) { - if (--tq->tq_active == 0) - cv_broadcast(&tq->tq_wait_cv); - if (tq->tq_flags & TASKQ_CPR_SAFE) { - cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock); - } else { - CALLB_CPR_SAFE_BEGIN(&cprinfo); - cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock); - CALLB_CPR_SAFE_END(&cprinfo, &tq->tq_lock); - } - tq->tq_active++; - continue; - } - tqe->tqent_prev->tqent_next = tqe->tqent_next; - tqe->tqent_next->tqent_prev = tqe->tqent_prev; - mutex_exit(&tq->tq_lock); - - rw_enter(&tq->tq_threadlock, RW_READER); - start = gethrtime(); - DTRACE_PROBE2(taskq__exec__start, taskq_t *, tq, - taskq_ent_t *, tqe); - tqe->tqent_func(tqe->tqent_arg); - DTRACE_PROBE2(taskq__exec__end, taskq_t *, tq, - taskq_ent_t *, tqe); - end = gethrtime(); - rw_exit(&tq->tq_threadlock); - - mutex_enter(&tq->tq_lock); - tq->tq_totaltime += end - start; - tq->tq_executed++; - - taskq_ent_free(tq, tqe); - } - tq->tq_nthreads--; - cv_broadcast(&tq->tq_wait_cv); - ASSERT(!(tq->tq_flags & TASKQ_CPR_SAFE)); - CALLB_CPR_EXIT(&cprinfo); - thread_exit(); -} - -/* - * Taskq creation. May sleep for memory. - * Always use automatically generated instances to avoid kstat name space - * collisions. - */ - -taskq_t * -taskq_create(const char *name, int nthreads, pri_t pri, int minalloc, - int maxalloc, uint_t flags) -{ - return taskq_create_common(name, 0, nthreads, pri, minalloc, - maxalloc, flags | TASKQ_NOINSTANCE); -} - -static taskq_t * -taskq_create_common(const char *name, int instance, int nthreads, pri_t pri, - int minalloc, int maxalloc, uint_t flags) -{ - taskq_t *tq = kmem_cache_alloc(taskq_cache, KM_SLEEP); - uint_t ncpus = ((boot_max_ncpus == -1) ? max_ncpus : boot_max_ncpus); - uint_t bsize; /* # of buckets - always power of 2 */ - - ASSERT(instance == 0); - ASSERT(flags == TASKQ_PREPOPULATE | TASKQ_NOINSTANCE); - - /* - * TASKQ_CPR_SAFE and TASKQ_DYNAMIC flags are mutually exclusive. - */ - ASSERT((flags & (TASKQ_DYNAMIC | TASKQ_CPR_SAFE)) != - ((TASKQ_DYNAMIC | TASKQ_CPR_SAFE))); - - ASSERT(tq->tq_buckets == NULL); - - bsize = 1 << (highbit(ncpus) - 1); - ASSERT(bsize >= 1); - bsize = MIN(bsize, taskq_maxbuckets); - - tq->tq_maxsize = nthreads; - - (void) strncpy(tq->tq_name, name, TASKQ_NAMELEN + 1); - tq->tq_name[TASKQ_NAMELEN] = '\0'; - /* Make sure the name conforms to the rules for C indentifiers */ - strident_canon(tq->tq_name, TASKQ_NAMELEN); - - tq->tq_flags = flags | TASKQ_ACTIVE; - tq->tq_active = nthreads; - tq->tq_nthreads = nthreads; - tq->tq_minalloc = minalloc; - tq->tq_maxalloc = maxalloc; - tq->tq_nbuckets = bsize; - tq->tq_pri = pri; - - if (flags & TASKQ_PREPOPULATE) { - mutex_enter(&tq->tq_lock); - while (minalloc-- > 0) - taskq_ent_free(tq, taskq_ent_alloc(tq, TQ_SLEEP)); - mutex_exit(&tq->tq_lock); - } - - if (nthreads == 1) { - tq->tq_thread = thread_create(NULL, 0, taskq_thread, tq, - 0, NULL, TS_RUN, pri); - } else { - kthread_t **tpp = kmem_alloc(sizeof (kthread_t *) * nthreads, - KM_SLEEP); - - tq->tq_threadlist = tpp; - - mutex_enter(&tq->tq_lock); - while (nthreads-- > 0) { - *tpp = thread_create(NULL, 0, taskq_thread, tq, - 0, NULL, TS_RUN, pri); - tpp++; - } - mutex_exit(&tq->tq_lock); - } - - return (tq); -} - -/* - * taskq_destroy(). - * - * Assumes: by the time taskq_destroy is called no one will use this task queue - * in any way and no one will try to dispatch entries in it. - */ -void -taskq_destroy(taskq_t *tq) -{ - taskq_bucket_t *b = tq->tq_buckets; - int bid = 0; - - ASSERT(! (tq->tq_flags & TASKQ_CPR_SAFE)); - - /* - * Wait for any pending entries to complete. - */ - taskq_wait(tq); - - mutex_enter(&tq->tq_lock); - ASSERT((tq->tq_task.tqent_next == &tq->tq_task) && - (tq->tq_active == 0)); - - if ((tq->tq_nthreads > 1) && (tq->tq_threadlist != NULL)) - kmem_free(tq->tq_threadlist, sizeof (kthread_t *) * - tq->tq_nthreads); - - tq->tq_flags &= ~TASKQ_ACTIVE; - cv_broadcast(&tq->tq_dispatch_cv); - while (tq->tq_nthreads != 0) - cv_wait(&tq->tq_wait_cv, &tq->tq_lock); - - tq->tq_minalloc = 0; - while (tq->tq_nalloc != 0) - taskq_ent_free(tq, taskq_ent_alloc(tq, TQ_SLEEP)); - - mutex_exit(&tq->tq_lock); - - /* - * Mark each bucket as closing and wakeup all sleeping threads. - */ - for (; (b != NULL) && (bid < tq->tq_nbuckets); b++, bid++) { - taskq_ent_t *tqe; - - mutex_enter(&b->tqbucket_lock); - - b->tqbucket_flags |= TQBUCKET_CLOSE; - /* Wakeup all sleeping threads */ - - for (tqe = b->tqbucket_freelist.tqent_next; - tqe != &b->tqbucket_freelist; tqe = tqe->tqent_next) - cv_signal(&tqe->tqent_cv); - - ASSERT(b->tqbucket_nalloc == 0); - - /* - * At this point we waited for all pending jobs to complete (in - * both the task queue and the bucket and no new jobs should - * arrive. Wait for all threads to die. - */ - while (b->tqbucket_nfree > 0) - cv_wait(&b->tqbucket_cv, &b->tqbucket_lock); - mutex_exit(&b->tqbucket_lock); - mutex_destroy(&b->tqbucket_lock); - cv_destroy(&b->tqbucket_cv); - } - - if (tq->tq_buckets != NULL) { - ASSERT(tq->tq_flags & TASKQ_DYNAMIC); - kmem_free(tq->tq_buckets, - sizeof (taskq_bucket_t) * tq->tq_nbuckets); - - /* Cleanup fields before returning tq to the cache */ - tq->tq_buckets = NULL; - tq->tq_tcreates = 0; - tq->tq_tdeaths = 0; - } else { - ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC)); - } - - tq->tq_totaltime = 0; - tq->tq_tasks = 0; - tq->tq_maxtasks = 0; - tq->tq_executed = 0; - kmem_cache_free(taskq_cache, tq); -} - -SYSINIT(sol_taskq, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, taskq_init, NULL); -SYSUNINIT(sol_taskq, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, taskq_fini, NULL); diff --git a/sys/cddl/compat/opensolaris/sys/taskq.h b/sys/cddl/contrib/opensolaris/uts/common/sys/taskq.h similarity index 83% rename from sys/cddl/compat/opensolaris/sys/taskq.h rename to sys/cddl/contrib/opensolaris/uts/common/sys/taskq.h index 174018a5eea..3878ded5e97 100644 --- a/sys/cddl/compat/opensolaris/sys/taskq.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/taskq.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -18,22 +17,18 @@ * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END - * - * $FreeBSD$ */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_TASKQ_H #define _SYS_TASKQ_H -#pragma ident "@(#)taskq.h 1.5 05/06/08 SMI" - -#include +#include #include -#include +#include #ifdef __cplusplus extern "C" { @@ -41,6 +36,11 @@ extern "C" { #define TASKQ_NAMELEN 31 +struct taskqueue; +struct taskq { + struct taskqueue *tq_queue; +}; + typedef struct taskq taskq_t; typedef uintptr_t taskqid_t; typedef void (task_func_t)(void *); @@ -51,6 +51,7 @@ typedef void (task_func_t)(void *); #define TASKQ_PREPOPULATE 0x0001 /* Prepopulate with threads and data */ #define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */ #define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */ +#define TASKQ_THREADS_CPU_PCT 0x0008 /* number of threads as % of ncpu */ /* * Flags for taskq_dispatch. TQ_SLEEP/TQ_NOSLEEP should be same as @@ -65,6 +66,9 @@ typedef void (task_func_t)(void *); extern taskq_t *system_taskq; +extern void taskq_init(void); +extern void taskq_mp_init(void); + extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); extern taskq_t *taskq_create_instance(const char *, int, int, pri_t, int, int, uint_t); diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c index e49c8024ecf..bec3b566ea3 100644 --- a/sys/kern/subr_taskqueue.c +++ b/sys/kern/subr_taskqueue.c @@ -472,3 +472,23 @@ taskqueue_fast_run(void *dummy) TASKQUEUE_FAST_DEFINE(fast, taskqueue_fast_enqueue, NULL, swi_add(NULL, "Fast task queue", taskqueue_fast_run, NULL, SWI_TQ_FAST, INTR_MPSAFE, &taskqueue_fast_ih)); + +int +taskqueue_member(struct taskqueue *queue, struct thread *td) +{ + int i, j, ret = 0; + + TQ_LOCK(queue); + for (i = 0, j = 0; ; i++) { + if (queue->tq_threads[i] == NULL) + continue; + if (queue->tq_threads[i] == td) { + ret = 1; + break; + } + if (++j >= queue->tq_tcount) + break; + } + TQ_UNLOCK(queue); + return (ret); +} diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index fc7049df56b..c95a8409ed4 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -23,6 +23,7 @@ SRCS+= opensolaris_kstat.c SRCS+= opensolaris_lookup.c SRCS+= opensolaris_policy.c SRCS+= opensolaris_string.c +SRCS+= opensolaris_taskq.c SRCS+= opensolaris_vfs.c SRCS+= opensolaris_zone.c @@ -42,7 +43,6 @@ SRCS+= vnode.c SRCS+= callb.c SRCS+= list.c SRCS+= nvpair_alloc_system.c -SRCS+= taskq.c .PATH: ${SUNW}/uts/common/zmod SRCS+= adler32.c diff --git a/sys/sys/taskqueue.h b/sys/sys/taskqueue.h index 4065a58b3ed..244e3e20de2 100644 --- a/sys/sys/taskqueue.h +++ b/sys/sys/taskqueue.h @@ -37,6 +37,7 @@ #include struct taskqueue; +struct thread; /* * A notification callback function which is called from @@ -60,6 +61,7 @@ void taskqueue_free(struct taskqueue *queue); void taskqueue_run(struct taskqueue *queue); void taskqueue_block(struct taskqueue *queue); void taskqueue_unblock(struct taskqueue *queue); +int taskqueue_member(struct taskqueue *queue, struct thread *td); /* * Functions for dedicated thread taskqueues From f0fb1d62c75c03aa348c9d48187587f7d86b5a54 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 09:14:58 +0000 Subject: [PATCH 0070/2592] MFC r196297: Fix panic in zfs recv code. The last vnode (mountpoint's vnode) can have 0 usecount. Reported by: Thomas Backman Approved by: re (kib) --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index a2bf4608d46..16c6683b7af 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -917,7 +917,7 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) for (zp = list_head(&zfsvfs->z_all_znodes); zp != NULL; zp = list_next(&zfsvfs->z_all_znodes, zp)) if (zp->z_dbuf) { - ASSERT(ZTOV(zp)->v_count > 0); + ASSERT(ZTOV(zp)->v_count >= 0); zfs_znode_dmu_fini(zp); } mutex_exit(&zfsvfs->z_znodes_lock); From 93be9449e4b99571184418c5594bb3c18fdaddf5 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 09:23:27 +0000 Subject: [PATCH 0071/2592] MFC r196299: - We need to recycle vnode instead of freeing znode. Submitted by: avg - Add missing vnode interlock unlock. - Remove redundant znode locking. Approved by: re (kib) --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 8e2f337a7da..ac75cc29679 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 @@ -3709,12 +3709,11 @@ zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) * The fs has been unmounted, or we did a * suspend/resume and this file no longer exists. */ - mutex_enter(&zp->z_lock); VI_LOCK(vp); vp->v_count = 0; /* count arrives as 1 */ - mutex_exit(&zp->z_lock); + VI_UNLOCK(vp); + vrecycle(vp, curthread); rw_exit(&zfsvfs->z_teardown_inactive_lock); - zfs_znode_free(zp); return; } From a64b73573922718fcafab35d194a8c72bb2588b2 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 09:27:10 +0000 Subject: [PATCH 0072/2592] MFC r196301: If z_buf is NULL, we should free znode immediately. Noticed by: avg Approved by: re (kib) --- .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) 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 ac75cc29679..84b365edc07 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 @@ -4350,7 +4350,6 @@ zfs_freebsd_reclaim(ap) { vnode_t *vp = ap->a_vp; znode_t *zp = VTOZ(vp); - zfsvfs_t *zfsvfs; ASSERT(zp != NULL); @@ -4360,13 +4359,18 @@ zfs_freebsd_reclaim(ap) vnode_destroy_vobject(vp); mutex_enter(&zp->z_lock); - ASSERT(zp->z_phys); + ASSERT(zp->z_phys != NULL); ZTOV(zp) = NULL; - if (!zp->z_unlinked) { + mutex_exit(&zp->z_lock); + + if (zp->z_unlinked) + ; /* Do nothing. */ + else if (zp->z_dbuf == NULL) + zfs_znode_free(zp); + else /* if (!zp->z_unlinked && zp->z_dbuf != NULL) */ { + zfsvfs_t *zfsvfs = zp->z_zfsvfs; int locked; - zfsvfs = zp->z_zfsvfs; - mutex_exit(&zp->z_lock); locked = MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id)) ? 2 : ZFS_OBJ_HOLD_TRYENTER(zfsvfs, zp->z_id); if (locked == 0) { @@ -4382,8 +4386,6 @@ zfs_freebsd_reclaim(ap) ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id); zfs_znode_free(zp); } - } else { - mutex_exit(&zp->z_lock); } VI_LOCK(vp); vp->v_data = NULL; From be7e2e42e166892607f5c33d7c1ccca72c9fabc5 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 09:30:31 +0000 Subject: [PATCH 0073/2592] MFC r196303: - Reduce z_teardown_lock lock scope a bit. - The error variable is int, not bool. - Convert spaces to tabs where needed. Approved by: re (kib) --- .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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 84b365edc07..b2a3a16193b 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 @@ -4529,9 +4529,9 @@ vop_getextattr { vp = nd.ni_vp; NDFREE(&nd, NDF_ONLY_PNBUF); if (error != 0) { + ZFS_EXIT(zfsvfs); if (error == ENOENT) error = ENOATTR; - ZFS_EXIT(zfsvfs); return (error); } @@ -4597,9 +4597,9 @@ vop_deleteextattr { vp = nd.ni_vp; NDFREE(&nd, NDF_ONLY_PNBUF); if (error != 0) { + ZFS_EXIT(zfsvfs); if (error == ENOENT) error = ENOATTR; - ZFS_EXIT(zfsvfs); return (error); } error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); @@ -4712,7 +4712,7 @@ vop_listextattr { error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, ap->a_cred, ap->a_td, VREAD); - if (error) + if (error != 0) return (error); error = zfs_create_attrname(ap->a_attrnamespace, "", attrprefix, @@ -4729,13 +4729,13 @@ vop_listextattr { error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, LOOKUP_XATTR); if (error != 0) { + ZFS_EXIT(zfsvfs); /* * ENOATTR means that the EA directory does not yet exist, * i.e. there are no extended attributes there. */ if (error == ENOATTR) error = 0; - ZFS_EXIT(zfsvfs); return (error); } @@ -4825,10 +4825,10 @@ zfs_freebsd_getacl(ap) return (error); error = acl_from_aces(ap->a_aclp, vsecattr.vsa_aclentp, vsecattr.vsa_aclcnt); - if (vsecattr.vsa_aclentp != NULL) - kmem_free(vsecattr.vsa_aclentp, vsecattr.vsa_aclentsz); + if (vsecattr.vsa_aclentp != NULL) + kmem_free(vsecattr.vsa_aclentp, vsecattr.vsa_aclentsz); - return (error); + return (error); } int From 860386c1a48d8fe897170a742cf1a379d3a8d392 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 09:42:34 +0000 Subject: [PATCH 0074/2592] MFC r196305: Fix receive when dataset has no / in its name. Submitted by: James R. Van Artsdalen Approved by: re (kib) --- .../opensolaris/lib/libzfs/common/libzfs_sendrecv.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c index 110fa889dab..5ee17fb8508 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c @@ -1126,7 +1126,7 @@ again: uint64_t originguid = 0; uint64_t stream_originguid = 0; uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid; - char *fsname, *stream_fsname; + char *fsname, *stream_fsname, *p1, *p2; nextfselem = nvlist_next_nvpair(local_nv, fselem); @@ -1295,10 +1295,11 @@ again: "parentfromsnap", &stream_parent_fromsnap_guid)); /* check for rename */ + p1 = strrchr(fsname, '/'); + p2 = strrchr(stream_fsname, '/'); if ((stream_parent_fromsnap_guid != 0 && stream_parent_fromsnap_guid != parent_fromsnap_guid) || - strcmp(strrchr(fsname, '/'), - strrchr(stream_fsname, '/')) != 0) { + (p1 != NULL && p2 != NULL && strcmp (p1, p2) != 0)) { nvlist_t *parent; char tryname[ZFS_MAXNAMELEN]; @@ -1317,7 +1318,7 @@ again: VERIFY(0 == nvlist_lookup_string(parent, "name", &pname)); (void) snprintf(tryname, sizeof (tryname), - "%s%s", pname, strrchr(stream_fsname, '/')); + "%s%s", pname, p2 != NULL ? p2 : ""); } else { tryname[0] = '\0'; if (flags.verbose) { From 5adfc444cf1cc7931f1f9dbcd6d6e85a2086bf70 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 09:55:58 +0000 Subject: [PATCH 0075/2592] MFC r196307: Manage asynchronous vnode release just like Solaris. Discussed with: kmacy Approved by: re (kib) --- sys/cddl/compat/opensolaris/sys/vnode.h | 1 - .../contrib/opensolaris/uts/common/fs/vnode.c | 134 ++---------------- .../opensolaris/uts/common/fs/zfs/dmu.c | 3 - .../opensolaris/uts/common/fs/zfs/dsl_pool.c | 10 ++ .../uts/common/fs/zfs/sys/dsl_pool.h | 3 + .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 9 +- .../opensolaris/uts/common/sys/vnode.h | 22 ++- 7 files changed, 50 insertions(+), 132 deletions(-) diff --git a/sys/cddl/compat/opensolaris/sys/vnode.h b/sys/cddl/compat/opensolaris/sys/vnode.h index bf11e674ea6..7611a3f8201 100644 --- a/sys/cddl/compat/opensolaris/sys/vnode.h +++ b/sys/cddl/compat/opensolaris/sys/vnode.h @@ -75,7 +75,6 @@ vn_is_readonly(vnode_t *vp) #define VN_HOLD(v) vref(v) #define VN_RELE(v) vrele(v) #define VN_URELE(v) vput(v) -#define VN_RELE_ASYNC(v, tq) vn_rele_async(v, tq); #define VOP_REALVP(vp, vpp, ct) (*(vpp) = (vp), 0) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c index bf613e5adb5..f4e2449f018 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,12 +36,10 @@ * contributors. */ - -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include +#include #include /* Extensible attribute (xva) routines. */ @@ -74,15 +72,12 @@ xva_getxoptattr(xvattr_t *xvap) return (xoap); } -static STAILQ_HEAD(, vnode) vn_rele_async_list; -static struct mtx vn_rele_async_lock; -static struct cv vn_rele_async_cv; -static int vn_rele_list_length; -static int vn_rele_async_thread_exit; +static void +vn_rele_inactive(vnode_t *vp) +{ -typedef struct { - struct vnode *stqe_next; -} vnode_link_t; + vrele(vp); +} /* * Like vn_rele() except if we are going to call VOP_INACTIVE() then do it @@ -95,117 +90,16 @@ typedef struct { * This is because taskqs throttle back allocation if too many are created. */ void -vn_rele_async(vnode_t *vp, taskq_t *taskq /* unused */) +vn_rele_async(vnode_t *vp, taskq_t *taskq) { - - KASSERT(vp != NULL, ("vrele: null vp")); - VFS_ASSERT_GIANT(vp->v_mount); + VERIFY(vp->v_count > 0); VI_LOCK(vp); - - if (vp->v_usecount > 1 || ((vp->v_iflag & VI_DOINGINACT) && - vp->v_usecount == 1)) { - vp->v_usecount--; - vdropl(vp); - return; - } - if (vp->v_usecount != 1) { -#ifdef DIAGNOSTIC - vprint("vrele: negative ref count", vp); -#endif + if (vp->v_count == 1 && !(vp->v_iflag & VI_DOINGINACT)) { VI_UNLOCK(vp); - panic("vrele: negative ref cnt"); - } - /* - * We are exiting - */ - if (vn_rele_async_thread_exit != 0) { - vrele(vp); + VERIFY(taskq_dispatch((taskq_t *)taskq, + (task_func_t *)vn_rele_inactive, vp, TQ_SLEEP) != 0); return; } - - mtx_lock(&vn_rele_async_lock); - - /* STAILQ_INSERT_TAIL */ - (*(vnode_link_t *)&vp->v_cstart).stqe_next = NULL; - *vn_rele_async_list.stqh_last = vp; - vn_rele_async_list.stqh_last = - &((vnode_link_t *)&vp->v_cstart)->stqe_next; - - /****************************************/ - vn_rele_list_length++; - if ((vn_rele_list_length % 100) == 0) - cv_signal(&vn_rele_async_cv); - mtx_unlock(&vn_rele_async_lock); - VI_UNLOCK(vp); + vp->v_usecount--; + vdropl(vp); } - -static void -vn_rele_async_init(void *arg) -{ - - mtx_init(&vn_rele_async_lock, "valock", NULL, MTX_DEF); - STAILQ_INIT(&vn_rele_async_list); - - /* cv_init(&vn_rele_async_cv, "vacv"); */ - vn_rele_async_cv.cv_description = "vacv"; - vn_rele_async_cv.cv_waiters = 0; -} - -void -vn_rele_async_fini(void) -{ - - mtx_lock(&vn_rele_async_lock); - vn_rele_async_thread_exit = 1; - cv_signal(&vn_rele_async_cv); - while (vn_rele_async_thread_exit != 0) - cv_wait(&vn_rele_async_cv, &vn_rele_async_lock); - mtx_unlock(&vn_rele_async_lock); - mtx_destroy(&vn_rele_async_lock); -} - - -static void -vn_rele_async_cleaner(void) -{ - STAILQ_HEAD(, vnode) vn_tmp_list; - struct vnode *curvnode; - - STAILQ_INIT(&vn_tmp_list); - mtx_lock(&vn_rele_async_lock); - while (vn_rele_async_thread_exit == 0) { - STAILQ_CONCAT(&vn_tmp_list, &vn_rele_async_list); - vn_rele_list_length = 0; - mtx_unlock(&vn_rele_async_lock); - - while (!STAILQ_EMPTY(&vn_tmp_list)) { - curvnode = STAILQ_FIRST(&vn_tmp_list); - - /* STAILQ_REMOVE_HEAD */ - STAILQ_FIRST(&vn_tmp_list) = - ((vnode_link_t *)&curvnode->v_cstart)->stqe_next; - if (STAILQ_FIRST(&vn_tmp_list) == NULL) - vn_tmp_list.stqh_last = &STAILQ_FIRST(&vn_tmp_list); - /***********************/ - vrele(curvnode); - } - mtx_lock(&vn_rele_async_lock); - if (vn_rele_list_length == 0) - cv_timedwait(&vn_rele_async_cv, &vn_rele_async_lock, - hz/10); - } - - vn_rele_async_thread_exit = 0; - cv_broadcast(&vn_rele_async_cv); - mtx_unlock(&vn_rele_async_lock); - thread_exit(); -} - -static struct proc *vn_rele_async_proc; -static struct kproc_desc up_kp = { - "vaclean", - vn_rele_async_cleaner, - &vn_rele_async_proc -}; -SYSINIT(vaclean, SI_SUB_KTHREAD_UPDATE, SI_ORDER_FIRST, kproc_start, &up_kp); -SYSINIT(vn_rele_async_setup, SI_SUB_VFS, SI_ORDER_FIRST, vn_rele_async_init, NULL); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c index 842677bc4e5..377efb9d105 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c @@ -1199,9 +1199,6 @@ dmu_init(void) void dmu_fini(void) { -#ifdef _KERNEL - vn_rele_async_fini(); -#endif arc_fini(); dnode_fini(); dbuf_fini(); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c index 4585dc805fe..03af3d1583c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c @@ -91,6 +91,9 @@ dsl_pool_open_impl(spa_t *spa, uint64_t txg) mutex_init(&dp->dp_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&dp->dp_scrub_cancel_lock, NULL, MUTEX_DEFAULT, NULL); + dp->dp_vnrele_taskq = taskq_create("zfs_vn_rele_taskq", 1, minclsyspri, + 1, 4, 0); + return (dp); } @@ -228,6 +231,7 @@ dsl_pool_close(dsl_pool_t *dp) rw_destroy(&dp->dp_config_rwlock); mutex_destroy(&dp->dp_lock); mutex_destroy(&dp->dp_scrub_cancel_lock); + taskq_destroy(dp->dp_vnrele_taskq); kmem_free(dp, sizeof (dsl_pool_t)); } @@ -611,3 +615,9 @@ dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx) dsl_dataset_rele(ds, FTAG); rw_exit(&dp->dp_config_rwlock); } + +taskq_t * +dsl_pool_vnrele_taskq(dsl_pool_t *dp) +{ + return (dp->dp_vnrele_taskq); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h index 4dd88fe6fa5..dcf5a4414fd 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h @@ -57,6 +57,7 @@ typedef struct dsl_pool { struct dsl_dir *dp_mos_dir; struct dsl_dataset *dp_origin_snap; uint64_t dp_root_dir_obj; + struct taskq *dp_vnrele_taskq; /* No lock needed - sync context only */ blkptr_t dp_meta_rootbp; @@ -119,6 +120,8 @@ int dsl_pool_scrub_clean(dsl_pool_t *dp); void dsl_pool_scrub_sync(dsl_pool_t *dp, dmu_tx_t *tx); void dsl_pool_scrub_restart(dsl_pool_t *dp); +taskq_t *dsl_pool_vnrele_taskq(dsl_pool_t *dp); + #ifdef __cplusplus } #endif 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 b2a3a16193b..de7c2930eba 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 @@ -924,6 +924,7 @@ zfs_get_done(dmu_buf_t *db, void *vzgd) zgd_t *zgd = (zgd_t *)vzgd; rl_t *rl = zgd->zgd_rl; vnode_t *vp = ZTOV(rl->r_zp); + objset_t *os = rl->r_zp->z_zfsvfs->z_os; int vfslocked; vfslocked = VFS_LOCK_GIANT(vp->v_vfsp); @@ -933,7 +934,7 @@ zfs_get_done(dmu_buf_t *db, void *vzgd) * Release the vnode asynchronously as we currently have the * txg stopped from syncing. */ - VN_RELE_ASYNC(vp, NULL); + VN_RELE_ASYNC(vp, dsl_pool_vnrele_taskq(dmu_objset_pool(os))); zil_add_block(zgd->zgd_zilog, zgd->zgd_bp); kmem_free(zgd, sizeof (zgd_t)); VFS_UNLOCK_GIANT(vfslocked); @@ -968,8 +969,8 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) * Release the vnode asynchronously as we currently have the * txg stopped from syncing. */ - VN_RELE_ASYNC(ZTOV(zp), NULL); - + VN_RELE_ASYNC(ZTOV(zp), + dsl_pool_vnrele_taskq(dmu_objset_pool(os))); return (ENOENT); } @@ -1045,7 +1046,7 @@ out: * Release the vnode asynchronously as we currently have the * txg stopped from syncing. */ - VN_RELE_ASYNC(ZTOV(zp), NULL); + VN_RELE_ASYNC(ZTOV(zp), dsl_pool_vnrele_taskq(dmu_objset_pool(os))); return (error); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h b/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h index a166315160a..a46b7118735 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h @@ -353,6 +353,11 @@ typedef struct caller_context { ulong_t cc_flags; } caller_context_t; +/* + * Structure tags for function prototypes, defined elsewhere. + */ +struct taskq; + /* * Flags for VOP_LOOKUP * @@ -369,6 +374,13 @@ typedef struct caller_context { */ #define V_RDDIR_ENTFLAGS 0x01 /* request dirent flags */ +/* + * Public vnode manipulation functions. + */ +#ifdef _KERNEL + +void vn_rele_async(struct vnode *vp, struct taskq *taskq); + /* * Extensible vnode attribute (xva) routines: * xva_init() initializes an xvattr_t (zero struct, init mapsize, set AT_XATTR) @@ -377,10 +389,12 @@ typedef struct caller_context { void xva_init(xvattr_t *); xoptattr_t *xva_getxoptattr(xvattr_t *); /* Get ptr to xoptattr_t */ -struct taskq; -void vn_rele_async(struct vnode *vp, struct taskq *taskq); -void vn_rele_async_fini(void); - +#define VN_RELE_ASYNC(vp, taskq) { \ + vn_rele_async(vp, taskq); \ +} + +#endif /* _KERNEL */ + /* * Flags to VOP_SETATTR/VOP_GETATTR. */ From 1aefcd39f0244997c3932c0e38950e688bcbdb35 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 10:02:31 +0000 Subject: [PATCH 0076/2592] MFC r196309: getcwd() (when __getcwd() fails) works by stating current directory, going up (..), calling readdir and looking for previous directory inode. In case of .zfs/ directory this doesn't work, because .zfs/ is hidden by default, so it won't be visible in readdir output. Fix this by implementing VPTOCNP for snapshot directories, so __getcwd() doesn't fail and getcwd() doesn't have to use readdir method. This fixes /bin/pwd from within .zfs/snapshot//. Suggested by: kib Approved by: re (rwatson) --- .../uts/common/fs/zfs/zfs_ctldir.c | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c index eef1d21bb97..cf99d68e8bb 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c @@ -1195,6 +1195,48 @@ zfsctl_snapshot_lookup(ap) return (error); } +static int +zfsctl_snapshot_vptocnp(struct vop_vptocnp_args *ap) +{ + zfsvfs_t *zfsvfs = ap->a_vp->v_vfsp->vfs_data; + vnode_t *dvp, *vp; + zfsctl_snapdir_t *sdp; + zfs_snapentry_t *sep; + int error; + + ASSERT(zfsvfs->z_ctldir != NULL); + error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp, + NULL, 0, NULL, kcred, NULL, NULL, NULL); + if (error != 0) + return (error); + sdp = dvp->v_data; + + mutex_enter(&sdp->sd_lock); + sep = avl_first(&sdp->sd_snaps); + while (sep != NULL) { + vp = sep->se_root; + if (vp == ap->a_vp) + break; + sep = AVL_NEXT(&sdp->sd_snaps, sep); + } + if (sep == NULL) { + mutex_exit(&sdp->sd_lock); + error = ENOENT; + } else { + size_t len; + + len = strlen(sep->se_name); + *ap->a_buflen -= len; + bcopy(sep->se_name, ap->a_buf + *ap->a_buflen, len); + mutex_exit(&sdp->sd_lock); + vhold(dvp); + *ap->a_vpp = dvp; + } + VN_RELE(dvp); + + return (error); +} + /* * These VP's should never see the light of day. They should always * be covered. @@ -1206,6 +1248,7 @@ static struct vop_vector zfsctl_ops_snapshot = { .vop_reclaim = zfsctl_common_reclaim, .vop_getattr = zfsctl_snapshot_getattr, .vop_fid = zfsctl_snapshot_fid, + .vop_vptocnp = zfsctl_snapshot_vptocnp, }; int From 22f00f220afb92b2af497efd8e21b6bef633489a Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Aug 2009 10:21:37 +0000 Subject: [PATCH 0077/2592] MFC r196311: Correct typo in the previous commit. Noticed by: pluknet Approved by: re (kib, implicit) --- share/man/man9/taskqueue.9 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man9/taskqueue.9 b/share/man/man9/taskqueue.9 index 589c3c644fd..553010b8042 100644 --- a/share/man/man9/taskqueue.9 +++ b/share/man/man9/taskqueue.9 @@ -188,7 +188,7 @@ The .Fn taskqueue_member function returns .No 1 -is the given thread +if the given thread .Fa td is part of the given taskqeueue .Fa queue From f2d3e43377fee55b54238a0462fb4368d206c7c6 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 17 Aug 2009 13:00:32 +0000 Subject: [PATCH 0078/2592] MFC r196316: Fix a typo in ifdef mesh support. This would make mesh unworkable if TDMA support was compiled out. Approved by: re (kib) --- sys/net80211/ieee80211_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 3c87a3ae34e..e701cb5eba1 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -524,7 +524,7 @@ ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m, case IEEE80211_ELEMID_HTINFO: scan->htinfo = frm; break; -#ifdef IEEE80211_SUPPORT_TDMA +#ifdef IEEE80211_SUPPORT_MESH case IEEE80211_ELEMID_MESHID: scan->meshid = frm; break; From 1d4dc8543f4463978cbae59c58984b666830fd86 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 17 Aug 2009 13:32:56 +0000 Subject: [PATCH 0079/2592] MFC r196318: Correct accounting error when allocating a a page table page to implement a user-space demotion. Approved by: re (rwatson) --- sys/amd64/amd64/pmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 622ed629b01..b9eee49c97c 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -2261,6 +2261,8 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) " in pmap %p", va, pmap); return (FALSE); } + if (va < VM_MAXUSER_ADDRESS) + pmap->pm_stats.resident_count++; } mptepa = VM_PAGE_TO_PHYS(mpte); firstpte = (pt_entry_t *)PHYS_TO_DMAP(mptepa); From ae93ebed7390aa703e8063f02989353640396f3e Mon Sep 17 00:00:00 2001 From: Scott Long Date: Mon, 17 Aug 2009 13:51:19 +0000 Subject: [PATCH 0081/2592] Merge files missed in r196285. SVN is simply horrible. Sorry for the tree breakage. Approved by: re --- etc/mtree/BSD.include.dist | 2 ++ include/Makefile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist index 97d70c1d81e..50fec7a7962 100644 --- a/etc/mtree/BSD.include.dist +++ b/etc/mtree/BSD.include.dist @@ -104,6 +104,8 @@ .. lmc .. + mfi + .. mpt mpilib .. diff --git a/include/Makefile b/include/Makefile index 72d7e728593..08ef6a5c768 100644 --- a/include/Makefile +++ b/include/Makefile @@ -40,7 +40,7 @@ LDIRS= bsm cam geom net net80211 netatalk netgraph netinet netinet6 \ LSUBDIRS= cam/ata cam/scsi \ dev/acpica dev/an dev/bktr dev/firewire dev/hwpmc \ - dev/ic dev/iicbus ${_dev_ieee488} dev/lmc dev/ofw \ + dev/ic dev/iicbus ${_dev_ieee488} dev/lmc dev/mfi dev/ofw \ dev/pbio ${_dev_powermac_nvram} dev/ppbus dev/smbus \ dev/speaker dev/usb dev/utopia dev/vkbd dev/wi \ fs/devfs fs/fdescfs fs/fifofs fs/msdosfs fs/nfs fs/ntfs fs/nullfs \ From c49b5baa652fb8545d9157394bdce70f06f1e0a8 Mon Sep 17 00:00:00 2001 From: John Hay Date: Mon, 17 Aug 2009 15:39:47 +0000 Subject: [PATCH 0083/2592] MFC: 196326 Fix parse() so that the partition to boot (load /boot/loader) from can be set. The syntax as printed in main() is used: 0:ad(0p3)/boot/loader Reviewed by: jhb Approved by: re (kib) --- sys/boot/i386/gptboot/gptboot.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/sys/boot/i386/gptboot/gptboot.c b/sys/boot/i386/gptboot/gptboot.c index 405b92e6286..89df2ecb104 100644 --- a/sys/boot/i386/gptboot/gptboot.c +++ b/sys/boot/i386/gptboot/gptboot.c @@ -466,16 +466,13 @@ parse(void) dsk.type = i; arg += 3; dsk.unit = *arg - '0'; - if (arg[1] != ',' || dsk.unit > 9) + if (arg[1] != 'p' || dsk.unit > 9) return -1; arg += 2; - dsk.part = -1; - if (arg[1] == ',') { - dsk.part = *arg - '0'; - if (dsk.part < 1 || dsk.part > 9) - return -1; - arg += 2; - } + dsk.part = *arg - '0'; + if (dsk.part < 1 || dsk.part > 9) + return -1; + arg++; if (arg[0] != ')') return -1; arg++; From 87b51e539dc7b05f91428a1ed81874c5013c32af Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 17 Aug 2009 16:24:50 +0000 Subject: [PATCH 0085/2592] MFC rev 196333: The start of the EFI GPT partition in the PMBR can always be represented by CHS addressing. Don't define these fields as 0xff, but rather define them correctly. This prevents boot problems on PCs where GPT is being used. PR: 115406 Submitted by: Kent Hauser Approved by: re (kib) --- sys/geom/part/g_part_gpt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c index cfbd897f749..61f9c7aa257 100644 --- a/sys/geom/part/g_part_gpt.c +++ b/sys/geom/part/g_part_gpt.c @@ -409,9 +409,9 @@ g_part_gpt_create(struct g_part_table *basetable, struct g_part_parms *gpp) last = (pp->mediasize / pp->sectorsize) - 1; le16enc(table->mbr + DOSMAGICOFFSET, DOSMAGIC); - table->mbr[DOSPARTOFF + 1] = 0xff; /* shd */ - table->mbr[DOSPARTOFF + 2] = 0xff; /* ssect */ - table->mbr[DOSPARTOFF + 3] = 0xff; /* scyl */ + table->mbr[DOSPARTOFF + 1] = 0x01; /* shd */ + table->mbr[DOSPARTOFF + 2] = 0x01; /* ssect */ + table->mbr[DOSPARTOFF + 3] = 0x00; /* scyl */ table->mbr[DOSPARTOFF + 4] = 0xee; /* typ */ table->mbr[DOSPARTOFF + 5] = 0xff; /* ehd */ table->mbr[DOSPARTOFF + 6] = 0xff; /* esect */ From 7e2d0af9e0062ada2897278bd135119760b1963f Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Mon, 17 Aug 2009 16:33:53 +0000 Subject: [PATCH 0086/2592] MFC r196334: * Change the scope of the ASSERT_ATOMIC_LOAD() from a generic check to a pointer-fetching specific operation check. Consequently, rename the operation ASSERT_ATOMIC_LOAD_PTR(). * Fix the implementation of ASSERT_ATOMIC_LOAD_PTR() by checking directly alignment on the word boundry, for all the given specific architectures. That's a bit too strict for some common case, but it assures safety. * Add a comment explaining the scope of the macro * Add a new stub in the lockmgr specific implementation Tested by: marcel (initial version), marius Reviewed by: rwatson, jhb (comment specific review) Approved by: re (kib) --- sys/kern/kern_lock.c | 3 +++ sys/kern/kern_mutex.c | 5 +++-- sys/kern/kern_rwlock.c | 5 +++-- sys/kern/kern_sx.c | 5 +++-- sys/sys/systm.h | 13 ++++++++++--- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 0affad5f19b..29ae4accfa7 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -334,6 +334,9 @@ lockinit(struct lock *lk, int pri, const char *wmesg, int timo, int flags) int iflags; MPASS((flags & ~LK_INIT_MASK) == 0); + ASSERT_ATOMIC_LOAD_PTR(lk->lk_lock, + ("%s: lockmgr not aligned for %s: %p", __func__, wmesg, + &lk->lk_lock)); iflags = LO_SLEEPABLE | LO_UPGRADABLE; if (flags & LK_CANRECURSE) diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index f625098f248..85ca646370d 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -783,8 +783,9 @@ mtx_init(struct mtx *m, const char *name, const char *type, int opts) MPASS((opts & ~(MTX_SPIN | MTX_QUIET | MTX_RECURSE | MTX_NOWITNESS | MTX_DUPOK | MTX_NOPROFILE)) == 0); - ASSERT_ATOMIC_LOAD(m->mtx_lock, ("%s: mtx_lock not aligned for %s: %p", - __func__, name, &m->mtx_lock)); + ASSERT_ATOMIC_LOAD_PTR(m->mtx_lock, + ("%s: mtx_lock not aligned for %s: %p", __func__, name, + &m->mtx_lock)); #ifdef MUTEX_DEBUG /* Diagnostic and error correction */ diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c index e2342506a0e..be05b39de0a 100644 --- a/sys/kern/kern_rwlock.c +++ b/sys/kern/kern_rwlock.c @@ -174,8 +174,9 @@ rw_init_flags(struct rwlock *rw, const char *name, int opts) MPASS((opts & ~(RW_DUPOK | RW_NOPROFILE | RW_NOWITNESS | RW_QUIET | RW_RECURSE)) == 0); - ASSERT_ATOMIC_LOAD(rw->rw_lock, ("%s: rw_lock not aligned for %s: %p", - __func__, name, &rw->rw_lock)); + ASSERT_ATOMIC_LOAD_PTR(rw->rw_lock, + ("%s: rw_lock not aligned for %s: %p", __func__, name, + &rw->rw_lock)); flags = LO_UPGRADABLE; if (opts & RW_DUPOK) diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index 15c1c9bdf16..4a78444c09c 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -205,8 +205,9 @@ sx_init_flags(struct sx *sx, const char *description, int opts) MPASS((opts & ~(SX_QUIET | SX_RECURSE | SX_NOWITNESS | SX_DUPOK | SX_NOPROFILE | SX_NOADAPTIVE)) == 0); - ASSERT_ATOMIC_LOAD(sx->sx_lock, ("%s: sx_lock not aligned for %s: %p", - __func__, description, &sx->sx_lock)); + ASSERT_ATOMIC_LOAD_PTR(sx->sx_lock, + ("%s: sx_lock not aligned for %s: %p", __func__, description, + &sx->sx_lock)); flags = LO_SLEEPABLE | LO_UPGRADABLE; if (opts & SX_DUPOK) diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 2e8b9adb458..96222da9152 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -89,9 +89,16 @@ extern int maxusers; /* system tune hint */ #define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] #endif -#define ASSERT_ATOMIC_LOAD(var,msg) \ - KASSERT(sizeof(var) <= sizeof(uintptr_t) && \ - ALIGN(&(var)) == (uintptr_t)&(var), msg) +/* + * Assert that a pointer can be loaded from memory atomically. + * + * This assertion enforces stronger alignment than necessary. For example, + * on some architectures, atomicity for unaligned loads will depend on + * whether or not the load spans multiple cache lines. + */ +#define ASSERT_ATOMIC_LOAD_PTR(var, msg) \ + KASSERT(sizeof(var) == sizeof(void *) && \ + ((uintptr_t)&(var) & (sizeof(void *) - 1)) == 0, msg) /* * XXX the hints declarations are even more misplaced than most declarations From 84dbe0452db0efd2778dd4eb8f9705c55550a981 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 17 Aug 2009 17:13:17 +0000 Subject: [PATCH 0087/2592] MFC 196337: Document the newly added SVNCMDARGS, SVNROOT, and SVNBRANCH variables. Approved by: re (kib) --- share/man/man7/release.7 | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/share/man/man7/release.7 b/share/man/man7/release.7 index a026db51d3e..d2174c50671 100644 --- a/share/man/man7/release.7 +++ b/share/man/man7/release.7 @@ -390,6 +390,35 @@ of the CVS tree .It Va SEPARATE_LIVEFS Store the live file system on its own CD-ROM image rather than placing it on the first disc. +.It Va SVNCMDARGS +Additional arguments for svn +.Ic checkout +and +.Ic switch +commands. +.It Va SVNROOT +The location of the FreeBSD SVN source repository. +If this variable is set, +then the source tree will be extracted using Subversion rather than +CVS. +.It Va SVNBRANCH +The branch to check out from a SVN source repository. +It is specified as a path such as +.Pa head +or +.Pa stable/7 . +If this variable is not set, +then the branch that corresponds to the current value of +.Va RELEASETAG +will be used. +If neither +.Va SVNBRANCH +nor +.Va RELEASETAG +are set, +then the +.Pa head +branch will be used. .It Va TARGET_ARCH The target machine processor architecture. This is analogous to the From 8d3f6febcdc358fc885d81954acdf4877872c5a6 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Mon, 17 Aug 2009 18:11:50 +0000 Subject: [PATCH 0088/2592] MFC r196332: Apply the same patch as r196205 for nfs_upgrade_lock() and nfs_downgrade_lock() to the experimental nfs client. Approved by: re (kensmith), kib (mentor) --- sys/fs/nfsclient/nfs_clsubs.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clsubs.c b/sys/fs/nfsclient/nfs_clsubs.c index 7ae2860f380..a217a21513a 100644 --- a/sys/fs/nfsclient/nfs_clsubs.c +++ b/sys/fs/nfsclient/nfs_clsubs.c @@ -129,28 +129,25 @@ int ncl_upgrade_vnlock(struct vnode *vp) { int old_lock; - - if ((old_lock = VOP_ISLOCKED(vp)) != LK_EXCLUSIVE) { - if (old_lock == LK_SHARED) { - /* Upgrade to exclusive lock, this might block */ - vn_lock(vp, LK_UPGRADE | LK_RETRY); - } else { - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - } + + ASSERT_VOP_LOCKED(vp, "ncl_upgrade_vnlock"); + old_lock = VOP_ISLOCKED(vp); + if (old_lock != LK_EXCLUSIVE) { + KASSERT(old_lock == LK_SHARED, + ("ncl_upgrade_vnlock: wrong old_lock %d", old_lock)); + /* Upgrade to exclusive lock, this might block */ + vn_lock(vp, LK_UPGRADE | LK_RETRY); } - return old_lock; + return (old_lock); } void ncl_downgrade_vnlock(struct vnode *vp, int old_lock) { if (old_lock != LK_EXCLUSIVE) { - if (old_lock == LK_SHARED) { - /* Downgrade from exclusive lock, this might block */ - vn_lock(vp, LK_DOWNGRADE); - } else { - VOP_UNLOCK(vp, 0); - } + KASSERT(old_lock == LK_SHARED, ("wrong old_lock %d", old_lock)); + /* Downgrade from exclusive lock. */ + vn_lock(vp, LK_DOWNGRADE | LK_RETRY); } } From bf4e402b83c1b937c4c5575e64dc98673aa1b15f Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Mon, 17 Aug 2009 20:06:00 +0000 Subject: [PATCH 0089/2592] fix netboot issue by disabling flowtable lookups until initialization has been run + mergeinfo garbage Reviewed by: rwatson@ Approved by: re@ --- sys/net/flowtable.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index 4078ae9138e..efdde72a278 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -203,6 +203,7 @@ static VNET_DEFINE(int, flowtable_udp_expire) = UDP_IDLE; static VNET_DEFINE(int, flowtable_fin_wait_expire) = FIN_WAIT_IDLE; static VNET_DEFINE(int, flowtable_tcp_expire) = TCP_IDLE; static VNET_DEFINE(int, flowtable_nmbflows) = 4096; +static VNET_DEFINE(int, flowtable_ready) = 0; #define V_flowtable_enable VNET(flowtable_enable) #define V_flowtable_hits VNET(flowtable_hits) @@ -217,6 +218,7 @@ static VNET_DEFINE(int, flowtable_nmbflows) = 4096; #define V_flowtable_fin_wait_expire VNET(flowtable_fin_wait_expire) #define V_flowtable_tcp_expire VNET(flowtable_tcp_expire) #define V_flowtable_nmbflows VNET(flowtable_nmbflows) +#define V_flowtable_ready VNET(flowtable_ready) SYSCTL_NODE(_net_inet, OID_AUTO, flowtable, CTLFLAG_RD, NULL, "flowtable"); SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, enable, CTLFLAG_RW, @@ -345,7 +347,7 @@ ipv4_flow_lookup_hash_internal(struct mbuf *m, struct route *ro, struct udphdr *uh; struct sctphdr *sh; - if (V_flowtable_enable == 0) + if ((V_flowtable_enable == 0) || (V_flowtable_ready == 0)) return (0); key[1] = key[0] = 0; @@ -799,6 +801,7 @@ flowtable_init(const void *unused __unused) NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET); uma_zone_set_max(V_flow_ipv4_zone, V_flowtable_nmbflows); uma_zone_set_max(V_flow_ipv6_zone, V_flowtable_nmbflows); + V_flowtable_ready = 1; } VNET_SYSINIT(flowtable_init, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, From a7f9e24d619c2e1bd41fd36029593334d01e05c4 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 18 Aug 2009 09:31:00 +0000 Subject: [PATCH 0090/2592] MFC r196352: Fix iSCSI initiator and vpo driver operation, broken by CAM changes. Reviewed by: scottl, Danny Braniss Approved by: re (rwatson) --- sys/cam/cam_ccb.h | 1 + sys/cam/cam_xpt.c | 2 ++ sys/dev/iscsi/initiator/isc_cam.c | 2 ++ sys/dev/ppbus/vpo.c | 2 ++ 4 files changed, 7 insertions(+) diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 61a57e3b2ab..a750d935f43 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -243,6 +243,7 @@ typedef enum { XPORT_ATA, /* AT Attachment */ XPORT_SAS, /* Serial Attached SCSI */ XPORT_SATA, /* Serial AT Attachment */ + XPORT_ISCSI, /* iSCSI */ } cam_xport; #define PROTO_VERSION_UNKNOWN (UINT_MAX - 1) diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index ea259668acf..1c2f61430a6 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -3803,6 +3803,8 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus) case XPORT_SAS: case XPORT_FC: case XPORT_USB: + case XPORT_ISCSI: + case XPORT_PPB: new_bus->xport = scsi_get_xport(); break; case XPORT_ATA: diff --git a/sys/dev/iscsi/initiator/isc_cam.c b/sys/dev/iscsi/initiator/isc_cam.c index fbd5b3d406f..0d8782351c8 100644 --- a/sys/dev/iscsi/initiator/isc_cam.c +++ b/sys/dev/iscsi/initiator/isc_cam.c @@ -190,6 +190,8 @@ _inq(struct cam_sim *sim, union ccb *ccb, int maxluns) strncpy(cpi->hba_vid, "iSCSI", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); + cpi->transport = XPORT_ISCSI; + cpi->transport_version = 0; cpi->ccb_h.status = CAM_REQ_CMP; } diff --git a/sys/dev/ppbus/vpo.c b/sys/dev/ppbus/vpo.c index f63ff49e374..40091787a4f 100644 --- a/sys/dev/ppbus/vpo.c +++ b/sys/dev/ppbus/vpo.c @@ -427,6 +427,8 @@ vpo_action(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->hba_vid, "Iomega", HBA_IDLEN); strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN); cpi->unit_number = sim->unit_number; + cpi->transport = XPORT_PPB; + cpi->transport_version = 0; cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); From 382c5c0df4b7ee7af29e8ef84ad0aeb875a29207 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 18 Aug 2009 09:36:25 +0000 Subject: [PATCH 0091/2592] Fix copy/paste bug, that requests data read during ATA device probe sequence for ATA_SETFEATURES/ATA_SF_SETXFER command which by definition transfers no data. Most of controllers are irrelevant to this bug, but some nVidia's doesn't. Tested on: current@ Approved by: re (kib) --- sys/cam/ata/ata_xpt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 0116b5b7459..0be44fc2b77 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -370,10 +370,10 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) cam_fill_ataio(ataio, 1, probedone, - /*flags*/CAM_DIR_IN, - MSG_SIMPLE_Q_TAG, - /*data_ptr*/(u_int8_t *)ident_buf, - /*dxfer_len*/sizeof(struct ata_params), + /*flags*/CAM_DIR_NONE, + 0, + /*data_ptr*/NULL, + /*dxfer_len*/0, 30 * 1000); ata_36bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, ata_max_mode(ident_buf, ATA_UDMA6, ATA_UDMA6)); From 856d08a08d77978e9bdfb64252ba17ec34159ca9 Mon Sep 17 00:00:00 2001 From: Tom Rhodes Date: Tue, 18 Aug 2009 13:51:51 +0000 Subject: [PATCH 0092/2592] MFC rev 196356: Document MAKE_DVD and xref svn in ports. Approved by: re@ (kib) --- share/man/man7/release.7 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/share/man/man7/release.7 b/share/man/man7/release.7 index d2174c50671..68c431cfded 100644 --- a/share/man/man7/release.7 +++ b/share/man/man7/release.7 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 12, 2006 +.Dd August 17, 2009 .Dt RELEASE 7 .Os .Sh NAME @@ -332,6 +332,10 @@ patch file. A script that will be run in the .Xr chroot 8 environment immediately after any local patches are applied. +.It Va MAKE_DVD +If defined, build a bootable ISO DVD image in the CD-ROM +stage directory. +This option may not be available for all architectures. .It Va MAKE_ISOS If defined, bootable ISO CD-ROM images will be created from the contents of the CD-ROM stage directory. @@ -503,6 +507,7 @@ make release CHROOTDIR=/local3/release BUILDNAME=6.0-CURRENT \\ .Xr install 1 , .Xr make 1 , .Xr patch 1 , +.Xr svn 1 Pq Pa ports/devel/subversion-freebsd , .Xr uname 1 , .Xr md 4 , .Xr make.conf 5 , @@ -540,7 +545,7 @@ effort was spent getting into a shape where it could at least automate most of the tediousness of building a release in a sterile environment. .Pp -With its almost 1000 revisions spread over multiple branches, the +At near 1000 revisions spread over multiple branches, the .Xr cvs 1 log of .Pa src/release/Makefile From 65536ad653cdf3e4e76f046564515cfe0b2dffd6 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Tue, 18 Aug 2009 14:00:25 +0000 Subject: [PATCH 0093/2592] MFC r196358: Remove unused taskqueue_find() function. Reviewed by: dfr Approved by: re (kib) --- share/man/man9/taskqueue.9 | 12 ++--------- sys/kern/subr_taskqueue.c | 43 -------------------------------------- sys/sys/taskqueue.h | 2 -- 3 files changed, 2 insertions(+), 55 deletions(-) diff --git a/share/man/man9/taskqueue.9 b/share/man/man9/taskqueue.9 index 553010b8042..5a6f9200dbe 100644 --- a/share/man/man9/taskqueue.9 +++ b/share/man/man9/taskqueue.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 17, 2009 +.Dd August 18, 2009 .Dt TASKQUEUE 9 .Os .Sh NAME @@ -59,8 +59,6 @@ struct task { .Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context" .Ft void .Fn taskqueue_free "struct taskqueue *queue" -.Ft struct taskqueue * -.Fn taskqueue_find "const char *name" .Ft int .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task" .Ft int @@ -115,16 +113,10 @@ should be used in place of .Pp The function .Fn taskqueue_free -should be used to remove the queue from the global list of queues -and free the memory used by the queue. +should be used to free the memory used by the queue. Any tasks that are on the queue will be executed at this time after which the thread servicing the queue will be signaled that it should exit. .Pp -The system maintains a list of all queues which can be searched using -.Fn taskqueue_find . -The first queue whose name matches is returned, otherwise -.Dv NULL . -.Pp To add a task to the list of tasks queued on a taskqueue, call .Fn taskqueue_enqueue with pointers to the queue and task. diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c index bec3b566ea3..22c1809a8a2 100644 --- a/sys/kern/subr_taskqueue.c +++ b/sys/kern/subr_taskqueue.c @@ -45,11 +45,8 @@ __FBSDID("$FreeBSD$"); static MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues"); static void *taskqueue_giant_ih; static void *taskqueue_ih; -static STAILQ_HEAD(taskqueue_list, taskqueue) taskqueue_queues; -static struct mtx taskqueue_queues_mutex; struct taskqueue { - STAILQ_ENTRY(taskqueue) tq_link; STAILQ_HEAD(, task) tq_queue; const char *tq_name; taskqueue_enqueue_fn tq_enqueue; @@ -84,8 +81,6 @@ TQ_UNLOCK(struct taskqueue *tq) mtx_unlock(&tq->tq_mutex); } -static void init_taskqueue_list(void *data); - static __inline int TQ_SLEEP(struct taskqueue *tq, void *p, struct mtx *m, int pri, const char *wm, int t) @@ -95,16 +90,6 @@ TQ_SLEEP(struct taskqueue *tq, void *p, struct mtx *m, int pri, const char *wm, return (msleep(p, m, pri, wm, t)); } -static void -init_taskqueue_list(void *data __unused) -{ - - mtx_init(&taskqueue_queues_mutex, "taskqueue list", NULL, MTX_DEF); - STAILQ_INIT(&taskqueue_queues); -} -SYSINIT(taskqueue_list, SI_SUB_INTRINSIC, SI_ORDER_ANY, init_taskqueue_list, - NULL); - static struct taskqueue * _taskqueue_create(const char *name, int mflags, taskqueue_enqueue_fn enqueue, void *context, @@ -124,10 +109,6 @@ _taskqueue_create(const char *name, int mflags, queue->tq_flags |= TQ_FLAGS_ACTIVE; mtx_init(&queue->tq_mutex, mtxname, NULL, mtxflags); - mtx_lock(&taskqueue_queues_mutex); - STAILQ_INSERT_TAIL(&taskqueue_queues, queue, tq_link); - mtx_unlock(&taskqueue_queues_mutex); - return queue; } @@ -156,10 +137,6 @@ void taskqueue_free(struct taskqueue *queue) { - mtx_lock(&taskqueue_queues_mutex); - STAILQ_REMOVE(&taskqueue_queues, queue, taskqueue, tq_link); - mtx_unlock(&taskqueue_queues_mutex); - TQ_LOCK(queue); queue->tq_flags &= ~TQ_FLAGS_ACTIVE; taskqueue_run(queue); @@ -169,26 +146,6 @@ taskqueue_free(struct taskqueue *queue) free(queue, M_TASKQUEUE); } -/* - * Returns with the taskqueue locked. - */ -struct taskqueue * -taskqueue_find(const char *name) -{ - struct taskqueue *queue; - - mtx_lock(&taskqueue_queues_mutex); - STAILQ_FOREACH(queue, &taskqueue_queues, tq_link) { - if (strcmp(queue->tq_name, name) == 0) { - TQ_LOCK(queue); - mtx_unlock(&taskqueue_queues_mutex); - return queue; - } - } - mtx_unlock(&taskqueue_queues_mutex); - return NULL; -} - int taskqueue_enqueue(struct taskqueue *queue, struct task *task) { diff --git a/sys/sys/taskqueue.h b/sys/sys/taskqueue.h index 244e3e20de2..bf2e4ee31d0 100644 --- a/sys/sys/taskqueue.h +++ b/sys/sys/taskqueue.h @@ -48,7 +48,6 @@ struct thread; */ typedef void (*taskqueue_enqueue_fn)(void *context); -struct proc; struct taskqueue *taskqueue_create(const char *name, int mflags, taskqueue_enqueue_fn enqueue, void *context); @@ -56,7 +55,6 @@ int taskqueue_start_threads(struct taskqueue **tqp, int count, int pri, const char *name, ...) __printflike(4, 5); int taskqueue_enqueue(struct taskqueue *queue, struct task *task); void taskqueue_drain(struct taskqueue *queue, struct task *task); -struct taskqueue *taskqueue_find(const char *name); void taskqueue_free(struct taskqueue *queue); void taskqueue_run(struct taskqueue *queue); void taskqueue_block(struct taskqueue *queue); From 3da1fd00cf29fc13489ad24e0bead074746b102e Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Tue, 18 Aug 2009 20:06:00 +0000 Subject: [PATCH 0094/2592] Fix a panic when using one-to-one style sockets in non-blocking mode and there is no listening server. PR: 137795 Approved by: re, rrs (mentor) --- sys/netinet/sctp_output.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 5cde4d0dd69..1e768fc5bbe 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -12464,7 +12464,8 @@ sctp_lower_sosend(struct socket *so, error = ENOTCONN; goto out_unlocked; } - hold_tcblock = 0; + SCTP_TCB_LOCK(stcb); + hold_tcblock = 1; SCTP_INP_RUNLOCK(inp); if (addr) { /* Must locate the net structure if addr given */ From f8fb3cc00e8be0c0d61bfec33ce513fa9f9f02b3 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Tue, 18 Aug 2009 20:25:02 +0000 Subject: [PATCH 0095/2592] MFC r196366: Backout r193289. r193289 restored page select bits to previous value instead of blindly resetting it to 0. However, it seems page select bits of some 88E1116 PHY is initialized to invalid one such that restoring page select bits after programming broke MII register access. The correct solution would be reset page select bits to 0 in PHY attach stage but it would require more testing. Since we're in BETA stage such a change would be dangerous so just back it out. This change should fix nfe(4) breakage on NVIDIA MCP55. Reported by: Ryan Rogers < webmaster <> doghouserepair dot com > Sam Fourman Jr. < sfourman <> gmail dot com > Tested by: Ryan Rogers < webmaster <> doghouserepair dot com > Sam Fourman Jr. < sfourman <> gmail dot com > Approved by: re (kib) --- sys/dev/mii/e1000phy.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c index f0d159bbaca..4f2fa66f6e8 100644 --- a/sys/dev/mii/e1000phy.c +++ b/sys/dev/mii/e1000phy.c @@ -240,13 +240,11 @@ e1000phy_reset(struct mii_softc *sc) if (esc->mii_model == MII_MODEL_MARVELL_E1116 || esc->mii_model == MII_MODEL_MARVELL_E1149) { - page = PHY_READ(sc, E1000_EADR); - /* Select page 2, MAC specific control register. */ PHY_WRITE(sc, E1000_EADR, 2); reg = PHY_READ(sc, E1000_SCR); reg |= E1000_SCR_RGMII_POWER_UP; PHY_WRITE(sc, E1000_SCR, reg); - PHY_WRITE(sc, E1000_EADR, page); + PHY_WRITE(sc, E1000_EADR, 0); } } From 670151d0e413b602f6b7643924671b0842ea3534 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Tue, 18 Aug 2009 20:39:35 +0000 Subject: [PATCH 0096/2592] MFC 196368 - change the interface to flowtable_lookup so that we don't rely on the mbuf for obtaining the fib index - check that a cached flow corresponds to the same fib index as the packet for which we are doing the lookup - at interface detach time flush any flows referencing stale rtentrys associated with the interface that is going away (fixes reported panics) - reduce the time between cleans in case the cleaner is running at the time the eventhandler is called and the wakeup is missed less time will elapse before the eventhandler returns - separate per-vnet initialization from global initialization (pointed out by jeli@) Reviewed by: sam@ Approved by: re@ --- sys/net/flowtable.c | 235 +++++++++++++++++++++++++++++++++------- sys/net/flowtable.h | 2 +- sys/netinet/ip_output.c | 2 +- 3 files changed, 196 insertions(+), 43 deletions(-) diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index efdde72a278..e9747277978 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -29,6 +29,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "opt_route.h" #include "opt_mpath.h" +#include "opt_ddb.h" #include __FBSDID("$FreeBSD$"); @@ -36,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -66,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include struct ipv4_tuple { uint16_t ip_sport; /* source port */ @@ -94,8 +97,9 @@ union ipv6_flow { struct flentry { volatile uint32_t f_fhash; /* hash flowing forward */ uint16_t f_flags; /* flow flags */ - uint8_t f_pad; /* alignment */ + uint8_t f_pad; uint8_t f_proto; /* protocol */ + uint32_t f_fibnum; /* fib index */ uint32_t f_uptime; /* uptime at last access */ struct flentry *f_next; /* pointer to collision entry */ volatile struct rtentry *f_rt; /* rtentry for flow */ @@ -173,6 +177,10 @@ static VNET_DEFINE(uma_zone_t, flow_ipv6_zone); #define V_flow_ipv4_zone VNET(flow_ipv4_zone) #define V_flow_ipv6_zone VNET(flow_ipv6_zone) +static struct cv flowclean_cv; +static struct mtx flowclean_lock; +static uint32_t flowclean_cycles; + /* * TODO: * - Make flowtable stats per-cpu, aggregated at sysctl call time, @@ -288,10 +296,10 @@ SYSCTL_VNET_PROC(_net_inet_flowtable, OID_AUTO, nmbflows, #ifndef RADIX_MPATH static void -in_rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fib) +in_rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fibnum) { - rtalloc_ign_fib(ro, 0, fib); + rtalloc_ign_fib(ro, 0, fibnum); } #endif @@ -425,7 +433,7 @@ static bitstr_t * flowtable_mask(struct flowtable *ft) { bitstr_t *mask; - + if (ft->ft_flags & FL_PCPU) mask = ft->ft_masks[curcpu]; else @@ -501,7 +509,7 @@ flowtable_set_hashkey(struct flentry *fle, uint32_t *key) static int flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key, - uint8_t proto, struct route *ro, uint16_t flags) + uint8_t proto, uint32_t fibnum, struct route *ro, uint16_t flags) { struct flentry *fle, *fletail, *newfle, **flep; int depth; @@ -564,6 +572,7 @@ skip: fle->f_rt = ro->ro_rt; fle->f_lle = ro->ro_lle; fle->f_fhash = hash; + fle->f_fibnum = fibnum; fle->f_uptime = time_uptime; FL_ENTRY_UNLOCK(ft, hash); return (0); @@ -591,13 +600,13 @@ flowtable_key_equal(struct flentry *fle, uint32_t *key) } int -flowtable_lookup(struct flowtable *ft, struct mbuf *m, struct route *ro) +flowtable_lookup(struct flowtable *ft, struct mbuf *m, struct route *ro, uint32_t fibnum) { uint32_t key[9], hash; struct flentry *fle; uint16_t flags; uint8_t proto = 0; - int error = 0, fib = 0; + int error = 0; struct rtentry *rt; struct llentry *lle; @@ -640,6 +649,7 @@ keycheck: && fle->f_fhash == hash && flowtable_key_equal(fle, key) && (proto == fle->f_proto) + && (fibnum == fle->f_fibnum) && (rt->rt_flags & RTF_UP) && (rt->rt_ifp != NULL)) { V_flowtable_hits++; @@ -668,10 +678,8 @@ uncached: * of arpresolve with an rt_check variant that expected to * receive the route locked */ - if (m != NULL) - fib = M_GETFIB(m); - ft->ft_rtalloc(ro, hash, fib); + ft->ft_rtalloc(ro, hash, fibnum); if (ro->ro_rt == NULL) error = ENETUNREACH; else { @@ -692,7 +700,7 @@ uncached: ro->ro_rt = NULL; return (ENOENT); } - error = flowtable_insert(ft, hash, key, proto, + error = flowtable_insert(ft, hash, key, proto, fibnum, ro, flags); if (error) { @@ -791,35 +799,6 @@ flowtable_alloc(int nentry, int flags) return (ft); } -static void -flowtable_init(const void *unused __unused) -{ - - V_flow_ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4), - NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET); - V_flow_ipv6_zone = uma_zcreate("ip6flow", sizeof(struct flentry_v6), - NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET); - uma_zone_set_max(V_flow_ipv4_zone, V_flowtable_nmbflows); - uma_zone_set_max(V_flow_ipv6_zone, V_flowtable_nmbflows); - V_flowtable_ready = 1; -} - -VNET_SYSINIT(flowtable_init, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, - flowtable_init, NULL); - -#ifdef VIMAGE -static void -flowtable_uninit(const void *unused __unused) -{ - - uma_zdestroy(V_flow_ipv4_zone); - uma_zdestroy(V_flow_ipv6_zone); -} - -VNET_SYSUNINIT(flowtable_uninit, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, - flowtable_uninit, NULL); -#endif - /* * The rest of the code is devoted to garbage collection of expired entries. * It is a new additon made necessary by the switch to dynamically allocating @@ -973,14 +952,32 @@ flowtable_cleaner(void) } VNET_LIST_RUNLOCK(); + flowclean_cycles++; /* * The 20 second interval between cleaning checks * is arbitrary */ - pause("flowcleanwait", 20*hz); + mtx_lock(&flowclean_lock); + cv_broadcast(&flowclean_cv); + cv_timedwait(&flowclean_cv, &flowclean_lock, 10*hz); + mtx_unlock(&flowclean_lock); } } +static void +flowtable_flush(void *unused __unused) +{ + uint64_t start; + + mtx_lock(&flowclean_lock); + start = flowclean_cycles; + while (start == flowclean_cycles) { + cv_broadcast(&flowclean_cv); + cv_wait(&flowclean_cv, &flowclean_lock); + } + mtx_unlock(&flowclean_lock); +} + static struct kproc_desc flow_kp = { "flowcleaner", flowtable_cleaner, @@ -988,3 +985,159 @@ static struct kproc_desc flow_kp = { }; SYSINIT(flowcleaner, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, kproc_start, &flow_kp); +static void +flowtable_init_vnet(const void *unused __unused) +{ + + V_flow_ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4), + NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET); + V_flow_ipv6_zone = uma_zcreate("ip6flow", sizeof(struct flentry_v6), + NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET); + uma_zone_set_max(V_flow_ipv4_zone, V_flowtable_nmbflows); + uma_zone_set_max(V_flow_ipv6_zone, V_flowtable_nmbflows); +} +VNET_SYSINIT(flowtable_init_vnet, SI_SUB_KTHREAD_INIT, SI_ORDER_MIDDLE, + flowtable_init_vnet, NULL); + +static void +flowtable_init(const void *unused __unused) +{ + + cv_init(&flowclean_cv, "flowcleanwait"); + mtx_init(&flowclean_lock, "flowclean lock", NULL, MTX_DEF); + EVENTHANDLER_REGISTER(ifnet_departure_event, flowtable_flush, NULL, + EVENTHANDLER_PRI_ANY); + V_flowtable_ready = 1; +} +SYSINIT(flowtable_init, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, + flowtable_init, NULL); + + +#ifdef VIMAGE +static void +flowtable_uninit(const void *unused __unused) +{ + + uma_zdestroy(V_flow_ipv4_zone); + uma_zdestroy(V_flow_ipv6_zone); +} + +VNET_SYSUNINIT(flowtable_uninit, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, + flowtable_uninit, NULL); +#endif + +#ifdef DDB +static bitstr_t * +flowtable_mask_pcpu(struct flowtable *ft, int cpuid) +{ + bitstr_t *mask; + + if (ft->ft_flags & FL_PCPU) + mask = ft->ft_masks[cpuid]; + else + mask = ft->ft_masks[0]; + + return (mask); +} + +static struct flentry ** +flowtable_entry_pcpu(struct flowtable *ft, uint32_t hash, int cpuid) +{ + struct flentry **fle; + int index = (hash % ft->ft_size); + + if (ft->ft_flags & FL_PCPU) { + fle = &ft->ft_table.pcpu[cpuid][index]; + } else { + fle = &ft->ft_table.global[index]; + } + + return (fle); +} + +static void +flow_show(struct flowtable *ft, struct flentry *fle) +{ + int idle_time; + int rt_valid; + + idle_time = (int)(time_uptime - fle->f_uptime); + rt_valid = fle->f_rt != NULL; + db_printf("hash=0x%08x idle_time=%03d rt=%p ifp=%p", + fle->f_fhash, idle_time, + fle->f_rt, rt_valid ? fle->f_rt->rt_ifp : NULL); + if (rt_valid && (fle->f_rt->rt_flags & RTF_UP)) + db_printf(" RTF_UP "); + if (fle->f_flags & FL_STALE) + db_printf(" FL_STALE "); + db_printf("\n"); +} + +static void +flowtable_show(struct flowtable *ft, int cpuid) +{ + int curbit = 0; + struct flentry *fle, **flehead; + bitstr_t *mask, *tmpmask; + + db_printf("cpu: %d\n", cpuid); + mask = flowtable_mask_pcpu(ft, cpuid); + tmpmask = ft->ft_tmpmask; + memcpy(tmpmask, mask, ft->ft_size/8); + /* + * XXX Note to self, bit_ffs operates at the byte level + * and thus adds gratuitous overhead + */ + bit_ffs(tmpmask, ft->ft_size, &curbit); + while (curbit != -1) { + if (curbit >= ft->ft_size || curbit < -1) { + db_printf("warning: bad curbit value %d \n", + curbit); + break; + } + + flehead = flowtable_entry_pcpu(ft, curbit, cpuid); + fle = *flehead; + + while (fle != NULL) { + flow_show(ft, fle); + fle = fle->f_next; + continue; + } + bit_clear(tmpmask, curbit); + bit_ffs(tmpmask, ft->ft_size, &curbit); + } +} + +static void +flowtable_show_vnet(void) +{ + struct flowtable *ft; + int i; + + ft = V_flow_list_head; + while (ft != NULL) { + if (ft->ft_flags & FL_PCPU) { + for (i = 0; i <= mp_maxid; i++) { + if (CPU_ABSENT(i)) + continue; + flowtable_show(ft, i); + } + } else { + flowtable_show(ft, 0); + } + ft = ft->ft_next; + } +} + +DB_SHOW_COMMAND(flowtables, db_show_flowtables) +{ + VNET_ITERATOR_DECL(vnet_iter); + + VNET_FOREACH(vnet_iter) { + CURVNET_SET(vnet_iter); + flowtable_show_vnet(); + CURVNET_RESTORE(); + } +} +#endif diff --git a/sys/net/flowtable.h b/sys/net/flowtable.h index 6334d8b42b0..afc8fb77a03 100644 --- a/sys/net/flowtable.h +++ b/sys/net/flowtable.h @@ -49,7 +49,7 @@ struct flowtable *flowtable_alloc(int nentry, int flags); * */ int flowtable_lookup(struct flowtable *ft, struct mbuf *m, - struct route *ro); + struct route *ro, uint32_t fibnum); #endif /* _KERNEL */ #endif diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 33ba8383043..2ce94b5c561 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -157,7 +157,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, * longer than that long for the stability of ro_rt. The * flow ID assignment must have happened before this point. */ - if (flowtable_lookup(V_ip_ft, m, ro) == 0) + if (flowtable_lookup(V_ip_ft, m, ro, M_GETFIB(m)) == 0) nortfree = 1; #endif } From 1daebacca0d4fcd672c37d2ae97abdc9c2e1e906 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Tue, 18 Aug 2009 21:13:00 +0000 Subject: [PATCH 0097/2592] - MFC r196370. Do not try to reevaluate current RX production index on each loop iteration as it can be updated by the card while we process the RX ring forcing us to process RX descriptors for which DMA synchronisation operation has not been performed. This fixes the bug when bge(4) drops packets under high load. Discussed with: yongari, marius Approved by: re (kib) --- sys/dev/bge/if_bge.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 4528762a02d..db65ec2caad 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -3055,12 +3055,14 @@ bge_rxeof(struct bge_softc *sc) { struct ifnet *ifp; int rx_npkts = 0, stdcnt = 0, jumbocnt = 0; + uint16_t rx_prod, rx_cons; BGE_LOCK_ASSERT(sc); + rx_cons = sc->bge_rx_saved_considx; + rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx; /* Nothing to do. */ - if (sc->bge_rx_saved_considx == - sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx) + if (rx_cons == rx_prod) return (rx_npkts); ifp = sc->bge_ifp; @@ -3073,8 +3075,7 @@ bge_rxeof(struct bge_softc *sc) bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTREAD); - while (sc->bge_rx_saved_considx != - sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx) { + while (rx_cons != rx_prod) { struct bge_rx_bd *cur_rx; uint32_t rxidx; struct mbuf *m = NULL; @@ -3089,11 +3090,10 @@ bge_rxeof(struct bge_softc *sc) } #endif - cur_rx = - &sc->bge_ldata.bge_rx_return_ring[sc->bge_rx_saved_considx]; + cur_rx = &sc->bge_ldata.bge_rx_return_ring[rx_cons]; rxidx = cur_rx->bge_idx; - BGE_INC(sc->bge_rx_saved_considx, sc->bge_return_ring_cnt); + BGE_INC(rx_cons, sc->bge_return_ring_cnt); if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING && cur_rx->bge_flags & BGE_RXBDFLAG_VLAN_TAG) { @@ -3207,6 +3207,7 @@ bge_rxeof(struct bge_softc *sc) bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE); + sc->bge_rx_saved_considx = rx_cons; bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx); if (stdcnt) bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std); From 0e7983d1f6d60c902e5bd5a0fa112ca7461ec6fa Mon Sep 17 00:00:00 2001 From: Max Laier Date: Wed, 19 Aug 2009 00:17:00 +0000 Subject: [PATCH 0098/2592] MFC r196372: If we cannot immediately get the pf_consistency_lock in the purge thread, restart the scan after acquiring the lock the hard way. Otherwise we might end up with a dead reference. Approved by: re (kib) --- sys/contrib/pf/net/pf.c | 89 ++++++++++++++++++++++++++++---------- sys/contrib/pf/net/pfvar.h | 5 +++ 2 files changed, 70 insertions(+), 24 deletions(-) diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c index 591ea36b801..e8031ac7dfe 100644 --- a/sys/contrib/pf/net/pf.c +++ b/sys/contrib/pf/net/pf.c @@ -971,6 +971,9 @@ void pf_purge_thread(void *v) { int nloops = 0, s; +#ifdef __FreeBSD__ + int locked; +#endif for (;;) { tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz); @@ -978,14 +981,19 @@ pf_purge_thread(void *v) #ifdef __FreeBSD__ sx_slock(&pf_consistency_lock); PF_LOCK(); + locked = 0; if (pf_end_threads) { - pf_purge_expired_states(pf_status.states); + PF_UNLOCK(); + sx_sunlock(&pf_consistency_lock); + sx_xlock(&pf_consistency_lock); + PF_LOCK(); + pf_purge_expired_states(pf_status.states, 1); pf_purge_expired_fragments(); - pf_purge_expired_src_nodes(0); + pf_purge_expired_src_nodes(1); pf_end_threads++; - sx_sunlock(&pf_consistency_lock); + sx_xunlock(&pf_consistency_lock); PF_UNLOCK(); wakeup(pf_purge_thread); kproc_exit(0); @@ -994,20 +1002,44 @@ pf_purge_thread(void *v) s = splsoftnet(); /* process a fraction of the state table every second */ +#ifdef __FreeBSD__ + if(!pf_purge_expired_states(1 + (pf_status.states + / pf_default_rule.timeout[PFTM_INTERVAL]), 0)) { + PF_UNLOCK(); + sx_sunlock(&pf_consistency_lock); + sx_xlock(&pf_consistency_lock); + PF_LOCK(); + locked = 1; + + pf_purge_expired_states(1 + (pf_status.states + / pf_default_rule.timeout[PFTM_INTERVAL]), 1); + } +#else pf_purge_expired_states(1 + (pf_status.states / pf_default_rule.timeout[PFTM_INTERVAL])); +#endif /* purge other expired types every PFTM_INTERVAL seconds */ if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) { pf_purge_expired_fragments(); - pf_purge_expired_src_nodes(0); + if (!pf_purge_expired_src_nodes(locked)) { + PF_UNLOCK(); + sx_sunlock(&pf_consistency_lock); + sx_xlock(&pf_consistency_lock); + PF_LOCK(); + locked = 1; + pf_purge_expired_src_nodes(1); + } nloops = 0; } splx(s); #ifdef __FreeBSD__ PF_UNLOCK(); - sx_sunlock(&pf_consistency_lock); + if (locked) + sx_xunlock(&pf_consistency_lock); + else + sx_sunlock(&pf_consistency_lock); #endif } } @@ -1056,8 +1088,13 @@ pf_state_expires(const struct pf_state *state) return (state->expire + timeout); } +#ifdef __FreeBSD__ +int +pf_purge_expired_src_nodes(int waslocked) +#else void pf_purge_expired_src_nodes(int waslocked) +#endif { struct pf_src_node *cur, *next; int locked = waslocked; @@ -1068,12 +1105,8 @@ pf_purge_expired_src_nodes(int waslocked) if (cur->states <= 0 && cur->expire <= time_second) { if (! locked) { #ifdef __FreeBSD__ - if (!sx_try_upgrade(&pf_consistency_lock)) { - PF_UNLOCK(); - sx_sunlock(&pf_consistency_lock); - sx_xlock(&pf_consistency_lock); - PF_LOCK(); - } + if (!sx_try_upgrade(&pf_consistency_lock)) + return (0); #else rw_enter_write(&pf_consistency_lock); #endif @@ -1100,6 +1133,10 @@ pf_purge_expired_src_nodes(int waslocked) #else rw_exit_write(&pf_consistency_lock); #endif + +#ifdef __FreeBSD__ + return (1); +#endif } void @@ -1202,12 +1239,21 @@ pf_free_state(struct pf_state *cur) pf_status.states--; } +#ifdef __FreeBSD__ +int +pf_purge_expired_states(u_int32_t maxcheck, int waslocked) +#else void pf_purge_expired_states(u_int32_t maxcheck) +#endif { static struct pf_state *cur = NULL; struct pf_state *next; +#ifdef __FreeBSD__ + int locked = waslocked; +#else int locked = 0; +#endif while (maxcheck--) { /* wrap to start of list when we hit the end */ @@ -1224,12 +1270,8 @@ pf_purge_expired_states(u_int32_t maxcheck) /* free unlinked state */ if (! locked) { #ifdef __FreeBSD__ - if (!sx_try_upgrade(&pf_consistency_lock)) { - PF_UNLOCK(); - sx_sunlock(&pf_consistency_lock); - sx_xlock(&pf_consistency_lock); - PF_LOCK(); - } + if (!sx_try_upgrade(&pf_consistency_lock)) + return (0); #else rw_enter_write(&pf_consistency_lock); #endif @@ -1241,12 +1283,8 @@ pf_purge_expired_states(u_int32_t maxcheck) pf_unlink_state(cur); if (! locked) { #ifdef __FreeBSD__ - if (!sx_try_upgrade(&pf_consistency_lock)) { - PF_UNLOCK(); - sx_sunlock(&pf_consistency_lock); - sx_xlock(&pf_consistency_lock); - PF_LOCK(); - } + if (!sx_try_upgrade(&pf_consistency_lock)) + return (0); #else rw_enter_write(&pf_consistency_lock); #endif @@ -1257,10 +1295,13 @@ pf_purge_expired_states(u_int32_t maxcheck) cur = next; } - if (locked) #ifdef __FreeBSD__ + if (!waslocked && locked) sx_downgrade(&pf_consistency_lock); + + return (1); #else + if (locked) rw_exit_write(&pf_consistency_lock); #endif } diff --git a/sys/contrib/pf/net/pfvar.h b/sys/contrib/pf/net/pfvar.h index 2c176db0299..32e721c5733 100644 --- a/sys/contrib/pf/net/pfvar.h +++ b/sys/contrib/pf/net/pfvar.h @@ -1593,8 +1593,13 @@ extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; extern struct pool pf_state_scrub_pl; #endif extern void pf_purge_thread(void *); +#ifdef __FreeBSD__ +extern int pf_purge_expired_src_nodes(int); +extern int pf_purge_expired_states(u_int32_t, int); +#else extern void pf_purge_expired_src_nodes(int); extern void pf_purge_expired_states(u_int32_t); +#endif extern void pf_unlink_state(struct pf_state *); extern void pf_free_state(struct pf_state *); extern int pf_insert_state(struct pfi_kif *, From a0f9adc73244b61af7c1c8acf34063361686013e Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Wed, 19 Aug 2009 03:58:12 +0000 Subject: [PATCH 0099/2592] - Make note of the update of tzdata from 2008h to 2009j - Make note of the update of tzcode from 2004a to 2009h Add an extra alert that people who update via source or via freebsd-update will have to run the tzsetup(8) utility. Approved by: re (Kostik) --- release/doc/en_US.ISO8859-1/relnotes/article.sgml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.sgml b/release/doc/en_US.ISO8859-1/relnotes/article.sgml index 46819186d9e..68db4f45e8a 100644 --- a/release/doc/en_US.ISO8859-1/relnotes/article.sgml +++ b/release/doc/en_US.ISO8859-1/relnotes/article.sgml @@ -411,6 +411,9 @@ &man.top.1; now supports a flag to provide per-CPU usage statistics. + &man.zdump.8; is now working properly on 64 bit architectures. + + &man.traceroute.8; now has the ability to print the AS number for each hop with the new switch; a new option allows selecting a particular @@ -468,8 +471,15 @@ 8.14.1 to 8.14.3. The timezone database has been updated from - the tzdata2008b release to - the tzdata2008h release. + the tzdata2008h release to + the tzdata2009j release. + + The stdtime part of libc, &man.zdump.8 and &man.zic.8 + have been updated from the tzcode2004a + release to the tzcode2009h release. + If you have upgraded from source or via the &man.freebsd-update.8, + then please run &man.tzsetup.8 to install a new /etc/localtime. + WPA Supplicant has been updated from 0.5.8 to 0.5.10. From d51d92a789d1dea0a8619e858ee18c987ee2a251 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Wed, 19 Aug 2009 12:12:51 +0000 Subject: [PATCH 0100/2592] Fix a bug in the handling of unreliable messages which results in stalled associations. Approved by: re, rrs (mentor) --- sys/netinet/sctputil.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 53d84b794d3..c7bdfb54b5c 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -4667,8 +4667,10 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, stcb->asoc.peers_rwnd += tp1->send_size; stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh); sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1, so_locked); - sctp_m_freem(tp1->data); - tp1->data = NULL; + if (tp1->data) { + sctp_m_freem(tp1->data); + tp1->data = NULL; + } do_wakeup_routine = 1; if (PR_SCTP_BUF_ENABLED(tp1->flags)) { stcb->asoc.sent_queue_cnt_removeable--; @@ -4715,12 +4717,14 @@ next_on_sent: */ chk = tp1; ret_sz += tp1->book_size; - sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1, so_locked); sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1); - sctp_m_freem(tp1->data); + sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1, so_locked); + if (tp1->data) { + sctp_m_freem(tp1->data); + tp1->data = NULL; + } /* No flight involved here book the size to 0 */ tp1->book_size = 0; - tp1->data = NULL; if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { foundeom = 1; } From e047c5fbb68789a7c5ce7659a63112e51490adce Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 19 Aug 2009 14:38:43 +0000 Subject: [PATCH 0101/2592] MFC r196378: Small changes to the warning message generated by pty(4): - Only print the warning once, instead of filling up the screen. - Use the word "legacy" for the pty_warningcnt description, to prevent confusion. - Use log() instead of printf(). Discussed with: rwatson, jhb Approved by: re (kib) --- sys/kern/tty_pty.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index 3bb5b476523..169229d15ec 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -47,10 +48,10 @@ __FBSDID("$FreeBSD$"); * si_drv1 inside the cdev to mark whether the PTY is in use. */ -static unsigned int pty_warningcnt = 10; +static unsigned int pty_warningcnt = 1; SYSCTL_UINT(_kern, OID_AUTO, tty_pty_warningcnt, CTLFLAG_RW, &pty_warningcnt, 0, - "Warnings that will be triggered upon PTY allocation"); + "Warnings that will be triggered upon legacy PTY allocation"); static int ptydev_fdopen(struct cdev *dev, int fflags, struct thread *td, struct file *fp) @@ -74,7 +75,7 @@ ptydev_fdopen(struct cdev *dev, int fflags, struct thread *td, struct file *fp) /* Raise a warning when a legacy PTY has been allocated. */ if (pty_warningcnt > 0) { pty_warningcnt--; - printf("pid %d (%s) is using legacy pty devices%s\n", + log(LOG_INFO, "pid %d (%s) is using legacy pty devices%s\n", td->td_proc->p_pid, td->td_name, pty_warningcnt ? "" : " - not logging anymore"); } From 49d96dc6ddd019ccf216642c2f3dbdb47d2a57fc Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Wed, 19 Aug 2009 14:48:59 +0000 Subject: [PATCH 0102/2592] MFC r196380 Fix USB cache sync operations for platforms with non-coherent DMA. - usb_pc_cpu_invalidate() is called between [consecutive] reads from a device, so a sequence of BUS_DMASYNC_POSTREAD and _PREREAD should be used. Note we cannot use or'ed shorthand ( _POSTREAD | _PREREAD) for BUS_DMASYNC flags, as the low level bus dma sync operation is implementation dependent and we cannot assume the required order of operations to be guaranteed. - usb_pc_cpu_flush() is called before writing to a device, so BUS_DMASYNC_PREWRITE should be used. Submitted by: Grzegorz Bernacki Reviewed by: HPS, arm@, usb@ ML Tested by: HPS, Mike Tancsa Approved by: re (kib) Obtained from: Semihalf --- sys/dev/usb/usb_busdma.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/dev/usb/usb_busdma.c b/sys/dev/usb/usb_busdma.c index e5d6ed7951e..3769102c510 100644 --- a/sys/dev/usb/usb_busdma.c +++ b/sys/dev/usb/usb_busdma.c @@ -679,8 +679,8 @@ usb_pc_cpu_invalidate(struct usb_page_cache *pc) /* nothing has been loaded into this page cache! */ return; } - bus_dmamap_sync(pc->tag, pc->map, - BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD); + bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD); } /*------------------------------------------------------------------------* @@ -693,8 +693,7 @@ usb_pc_cpu_flush(struct usb_page_cache *pc) /* nothing has been loaded into this page cache! */ return; } - bus_dmamap_sync(pc->tag, pc->map, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE); } /*------------------------------------------------------------------------* From 9fdef7744d42c820e0940b1889e471800e4fd2da Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 19 Aug 2009 16:40:45 +0000 Subject: [PATCH 0103/2592] MFC change 196383: Remove the dependency on the kernel -- in particular the gctl request to the GEOM_BSD class -- to translate the absolute offsets in the label to relative ones. This makes bslabel(8) work correctly with GEOM_PART and also when the BSD label is nested under arbitrary partitioning schemes. Inspired by: Eygene Ryabinkin Approved by: re (kib) --- sbin/bsdlabel/bsdlabel.c | 41 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/sbin/bsdlabel/bsdlabel.c b/sbin/bsdlabel/bsdlabel.c index 1cb99950bbd..9a6027c7951 100644 --- a/sbin/bsdlabel/bsdlabel.c +++ b/sbin/bsdlabel/bsdlabel.c @@ -118,7 +118,7 @@ static int installboot; /* non-zero if we should install a boot program */ static int allfields; /* present all fields in edit */ static char const *xxboot; /* primary boot */ -static off_t mbroffset; +static uint32_t lba_offset; #ifndef LABELSECTOR #define LABELSECTOR -1 #endif @@ -403,7 +403,7 @@ writelabel(void) readboot(); for (i = 0; i < lab.d_npartitions; i++) if (lab.d_partitions[i].p_size) - lab.d_partitions[i].p_offset += mbroffset; + lab.d_partitions[i].p_offset += lba_offset; bsd_disklabel_le_enc(bootarea + labeloffset + labelsoffset * secsize, lp); if (alphacksum) { @@ -479,10 +479,9 @@ get_file_parms(int f) static int readlabel(int flag) { + uint32_t lba; int f, i; int error; - struct gctl_req *grq; - char const *errstr; f = open(specname, O_RDONLY); if (f < 0) @@ -510,22 +509,28 @@ readlabel(int flag) if (is_file) return(0); - grq = gctl_get_handle(); - gctl_ro_param(grq, "verb", -1, "read mbroffset"); - gctl_ro_param(grq, "class", -1, "BSD"); - gctl_ro_param(grq, "geom", -1, pname); - gctl_rw_param(grq, "mbroffset", sizeof(mbroffset), &mbroffset); - errstr = gctl_issue(grq); - if (errstr != NULL) { - mbroffset = 0; - gctl_free(grq); - return (error); + + /* + * Compensate for absolute block addressing by finding the + * smallest partition offset and if the offset of the 'c' + * partition is equal to that, subtract it from all offsets. + */ + lba = ~0; + for (i = 0; i < lab.d_npartitions; i++) { + if (lab.d_partitions[i].p_size) + lba = MIN(lba, lab.d_partitions[i].p_offset); } - mbroffset /= lab.d_secsize; - if (lab.d_partitions[RAW_PART].p_offset == mbroffset) - for (i = 0; i < lab.d_npartitions; i++) + if (lba != 0 && lab.d_partitions[RAW_PART].p_offset == lba) { + for (i = 0; i < lab.d_npartitions; i++) { if (lab.d_partitions[i].p_size) - lab.d_partitions[i].p_offset -= mbroffset; + lab.d_partitions[i].p_offset -= lba; + } + /* + * Save the offset so that we can write the label + * back with absolute block addresses. + */ + lba_offset = lba; + } return (error); } From 46208d409cbb82e3c4d15e201d9ece5bd4f45785 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 19 Aug 2009 17:45:58 +0000 Subject: [PATCH 0104/2592] MFC 196382: Explicitly line up the CPU state labels with the calculated starting column that takes into account the width of the largest CPU ID. On systems with > 10 CPUs the labels for the first 10 CPUs were not lined up properly otherwise. Approved by: re (kib) --- contrib/top/display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/top/display.c b/contrib/top/display.c index 0b1226ce03d..3fca57b5fdc 100644 --- a/contrib/top/display.c +++ b/contrib/top/display.c @@ -452,6 +452,7 @@ for (cpu = 0; cpu < num_cpus; cpu++) { lastline++; /* now walk thru the names and print the line */ + Move_to(cpustates_column, y_cpustates + cpu); while ((thisname = *names++) != NULL) { if (*thisname != '\0') @@ -543,6 +544,7 @@ for (cpu = 0; cpu < num_cpus; cpu++) { printf("\nCPU %d: ", cpu); lastline++; + Move_to(cpustates_column, y_cpustates + cpu); while ((thisname = *names++) != NULL) { if (*thisname != '\0') From 67a435347bb7d8299405c199acd4b358314b3e44 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 19 Aug 2009 18:08:50 +0000 Subject: [PATCH 0105/2592] MFC r196386: Temporarily enhance em(4) and igb(4) hack to take account for IFF_NOARP. Without this changeset there will be no way to prevent these NICs from sending ARP, which is harmful in server farms that is configured as "Direct Server Return" behind a load balancer. A better fix would remove the whole hack completely but it would be later than 8.0-RELEASE. Reviewed by: jfv, yongari Approved by: re (kib) --- sys/dev/e1000/if_em.c | 3 ++- sys/dev/e1000/if_igb.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index d1fe7aaa3cb..1def87631db 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1204,7 +1204,8 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) em_init_locked(adapter); EM_CORE_UNLOCK(adapter); } - arp_ifinit(ifp, ifa); + if (!(ifp->if_flags & IFF_NOARP)) + arp_ifinit(ifp, ifa); } else #endif error = ether_ioctl(ifp, command, data); diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index ee19b944e77..4124fa14b92 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -952,7 +952,8 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data) igb_init_locked(adapter); IGB_CORE_UNLOCK(adapter); } - arp_ifinit(ifp, ifa); + if (!(ifp->if_flags & IFF_NOARP)) + arp_ifinit(ifp, ifa); } else #endif error = ether_ioctl(ifp, command, data); From 786f829ddb149cae379480740e0a82ffb0839127 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Wed, 19 Aug 2009 20:17:36 +0000 Subject: [PATCH 0106/2592] This change fixes a comment and addresses a complaint by kib@ by moving a frequently executed flowtable syslog statement from being conditional on bootverbose to conditional on a per-vnet flowtable sysctl. Approved by: re@ --- sys/net/flowtable.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index e9747277978..f6cd77839bc 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -199,6 +199,7 @@ static uint32_t flowclean_cycles; * - idetach() cleanup for options VIMAGE builds. */ VNET_DEFINE(int, flowtable_enable) = 1; +static VNET_DEFINE(int, flowtable_debug); static VNET_DEFINE(int, flowtable_hits); static VNET_DEFINE(int, flowtable_lookups); static VNET_DEFINE(int, flowtable_misses); @@ -214,6 +215,7 @@ static VNET_DEFINE(int, flowtable_nmbflows) = 4096; static VNET_DEFINE(int, flowtable_ready) = 0; #define V_flowtable_enable VNET(flowtable_enable) +#define V_flowtable_debug VNET(flowtable_debug) #define V_flowtable_hits VNET(flowtable_hits) #define V_flowtable_lookups VNET(flowtable_lookups) #define V_flowtable_misses VNET(flowtable_misses) @@ -229,6 +231,8 @@ static VNET_DEFINE(int, flowtable_ready) = 0; #define V_flowtable_ready VNET(flowtable_ready) SYSCTL_NODE(_net_inet, OID_AUTO, flowtable, CTLFLAG_RD, NULL, "flowtable"); +SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, debug, CTLFLAG_RW, + &VNET_NAME(flowtable_debug), 0, "print debug info."); SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, enable, CTLFLAG_RW, &VNET_NAME(flowtable_enable), 0, "enable flowtable caching."); SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, hits, CTLFLAG_RD, @@ -902,7 +906,7 @@ flowtable_free_stale(struct flowtable *ft) V_flowtable_frees++; fle_free(fle); } - if (bootverbose && count) + if (V_flowtable_debug && count) log(LOG_DEBUG, "freed %d flow entries\n", count); } @@ -954,7 +958,7 @@ flowtable_cleaner(void) flowclean_cycles++; /* - * The 20 second interval between cleaning checks + * The 10 second interval between cleaning checks * is arbitrary */ mtx_lock(&flowclean_lock); From f0c46a48f70c9284fed14618312cd497e1ba3314 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 19 Aug 2009 20:44:22 +0000 Subject: [PATCH 0107/2592] MFC r196390: Make the MacBookPro3,1 hardware boot again. Tested by: Patrick Lamaiziere Approved by: re (kib) --- sys/amd64/amd64/machdep.c | 1 + sys/i386/i386/machdep.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 8aee97524f5..2c54be28fdf 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -217,6 +217,7 @@ cpu_startup(dummy) strncmp(sysenv, "MacBook3,1", 10) == 0 || strncmp(sysenv, "MacBookPro1,1", 13) == 0 || strncmp(sysenv, "MacBookPro1,2", 13) == 0 || + strncmp(sysenv, "MacBookPro3,1", 13) == 0 || strncmp(sysenv, "Macmini1,1", 10) == 0) { if (bootverbose) printf("Disabling LEGACY_USB_EN bit on " diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 1b24af39ce2..cba1637746e 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -261,6 +261,7 @@ cpu_startup(dummy) strncmp(sysenv, "MacBook3,1", 10) == 0 || strncmp(sysenv, "MacBookPro1,1", 13) == 0 || strncmp(sysenv, "MacBookPro1,2", 13) == 0 || + strncmp(sysenv, "MacBookPro3,1", 13) == 0 || strncmp(sysenv, "Macmini1,1", 10) == 0) { if (bootverbose) printf("Disabling LEGACY_USB_EN bit on " From 452e49d6019adb0b83fe62cb0b53fec6815d02fe Mon Sep 17 00:00:00 2001 From: "Simon L. B. Nielsen" Date: Wed, 19 Aug 2009 21:01:32 +0000 Subject: [PATCH 0108/2592] MFC 196392: Add support for backing up the old kernel when installing a new kernel using freebsd-update. This applies to using freebsd-update in "upgrade mode" and normal freebsd-update on a security branch. The backup kernel will be written to /boot/kernel.old, if the directory does not exist, or the directory was created by freebsd-update in a previous backup. Otherwise freebsd-update will generate a new directory name for use by the backup. By default symbol files are not backed up to save diskspace and avoid filling up the root partition. This feature is fully configurable in the freebsd-update config file, but defaults to enabled. Reviewed by: cperciva Approved by: re (kib) --- etc/freebsd-update.conf | 11 ++ share/man/man5/freebsd-update.conf.5 | 52 ++++++- usr.sbin/freebsd-update/freebsd-update.sh | 162 +++++++++++++++++++++- 3 files changed, 222 insertions(+), 3 deletions(-) diff --git a/etc/freebsd-update.conf b/etc/freebsd-update.conf index af53be4cb62..44109034b00 100644 --- a/etc/freebsd-update.conf +++ b/etc/freebsd-update.conf @@ -63,3 +63,14 @@ MergeChanges /etc/ /var/named/etc/ /boot/device.hints # which *might* be installed of which FreeBSD Update should figure out # which actually are installed and upgrade those (StrictComponents no)? # StrictComponents no + +# When installing a new kernel perform a backup of the old one first +# so it is possible to boot the old kernel in case of problems. +# BackupKernel yes + +# If BackupKernel is enabled, the backup kernel is saved to this +# directory. +# BackupKernelDir /boot/kernel.old + +# When backing up a kernel also back up debug symbol files? +# BackupKernelSymbolFiles no diff --git a/share/man/man5/freebsd-update.conf.5 b/share/man/man5/freebsd-update.conf.5 index 29775fdb276..d3721028e26 100644 --- a/share/man/man5/freebsd-update.conf.5 +++ b/share/man/man5/freebsd-update.conf.5 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 30, 2006 +.Dd August 19, 2009 .Dt FREEBSD-UPDATE.CONF 5 .Os FreeBSD .Sh NAME @@ -48,7 +48,7 @@ error. .Pp The possible options and their meanings are as follows: .Pp -.Bl -tag -width "KeepModifiedMetadata" +.Bl -tag -width ".Cm BackupKernelSymbolFiles" .It Cm KeyPrint The single parameter following this keyword is the SHA256 hash of the RSA key which will be trusted to sign updates. @@ -171,6 +171,54 @@ command is used ("yes"), or merely as a list of components which might be installed, of which .Cm freebsd-update should identify which in fact are present ("no"). +.It Cm BackupKernel +The single parameter following this keyword must be +.Dq yes +or +.Dq no +and specifies whether +.Cm freebsd-update +will create a backup of the old kernel before installing a new kernel. +This backup kernel can be used to recover a system where the newly +installed kernel somehow did not work. +Note that the backup kernel is not reverted to its original state by +the +.Cm freebsd-update +rollback command. +.It Cm BackupKernelDir +This keyword sets the directory which is used to store a backup +kernel, if the BackupKernel feature is enabled. +If the directory already exist, and it was not created by +.Cm freebsd-update , +the directory is skipped. +In the case of the primary directory name not being usable, a number +starting with +.Sq 1 +is appended to the directory name. +Like with the primary directory name, the constructed directory name is +only used if the path name does not exist, or if the directory was +previously created by +.Cm freebsd-update . +If the constructed directory still exist the appended number is +incremented with 1 and the directory search process restarted. +Should the number increment go above 9, +.Cm freebsd-update +will abort. +.It Cm BackupKernelSymbolFiles +The single parameter following this keyword must be +.Dq yes +or +.Dq no +and specifies whether +.Cm freebsd-update +will also backup kernel symbol files, if they exist. +The kernel symbol files takes up a lot of disk space and are not +needed for recovery purposes. +If the symbol files are needed, after recovering a system using the +backup kernel, the +.Cm freebsd-update +rollback command will recreate the symbol files along with the old +kernel. .El .Sh FILES .Bl -tag -width "/etc/freebsd-update.conf" diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index 331ef101494..2eacca8d2fb 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -88,7 +88,7 @@ EOF CONFIGOPTIONS="KEYPRINT WORKDIR SERVERNAME MAILTO ALLOWADD ALLOWDELETE KEEPMODIFIEDMETADATA COMPONENTS IGNOREPATHS UPDATEIFUNMODIFIED BASEDIR VERBOSELEVEL TARGETRELEASE STRICTCOMPONENTS MERGECHANGES - IDSIGNOREPATHS" + IDSIGNOREPATHS BACKUPKERNEL BACKUPKERNELDIR BACKUPKERNELSYMBOLFILES" # Set all the configuration options to "". nullconfig () { @@ -308,6 +308,70 @@ config_VerboseLevel () { fi } +config_BackupKernel () { + if [ -z ${BACKUPKERNEL} ]; then + case $1 in + [Yy][Ee][Ss]) + BACKUPKERNEL=yes + ;; + [Nn][Oo]) + BACKUPKERNEL=no + ;; + *) + return 1 + ;; + esac + else + return 1 + fi +} + +config_BackupKernelDir () { + if [ -z ${BACKUPKERNELDIR} ]; then + if [ -z "$1" ]; then + echo "BackupKernelDir set to empty dir" + return 1 + fi + + # We check for some paths which would be extremely odd + # to use, but which could cause a lot of problems if + # used. + case $1 in + /|/bin|/boot|/etc|/lib|/libexec|/sbin|/usr|/var) + echo "BackupKernelDir set to invalid path $1" + return 1 + ;; + /*) + BACKUPKERNELDIR=$1 + ;; + *) + echo "BackupKernelDir ($1) is not an absolute path" + return 1 + ;; + esac + else + return 1 + fi +} + +config_BackupKernelSymbolFiles () { + if [ -z ${BACKUPKERNELSYMBOLFILES} ]; then + case $1 in + [Yy][Ee][Ss]) + BACKUPKERNELSYMBOLFILES=yes + ;; + [Nn][Oo]) + BACKUPKERNELSYMBOLFILES=no + ;; + *) + return 1 + ;; + esac + else + return 1 + fi +} + # Handle one line of configuration configline () { if [ $# -eq 0 ]; then @@ -461,6 +525,9 @@ default_params () { config_BaseDir / config_VerboseLevel stats config_StrictComponents no + config_BackupKernel yes + config_BackupKernelDir /boot/kernel.old + config_BackupKernelSymbolFiles no # Merge these defaults into the earlier-configured settings mergeconfig @@ -665,6 +732,14 @@ install_check_params () { echo "Re-run '$0 fetch'." exit 1 fi + + # Figure out what directory contains the running kernel + BOOTFILE=`sysctl -n kern.bootfile` + KERNELDIR=${BOOTFILE%/kernel} + if ! [ -d ${KERNELDIR} ]; then + echo "Cannot identify running kernel" + exit 1 + fi } # Perform sanity checks and set some final parameters in @@ -2494,6 +2569,88 @@ install_unschg () { rm filelist } +# Decide which directory name to use for kernel backups. +backup_kernel_finddir () { + CNT=0 + while true ; do + # Pathname does not exist, so it is OK use that name + # for backup directory. + if [ ! -e $BACKUPKERNELDIR ]; then + return 0 + fi + + # If directory do exist, we only use if it has our + # marker file. + if [ -d $BACKUPKERNELDIR -a \ + -e $BACKUPKERNELDIR/.freebsd-update ]; then + return 0 + fi + + # We could not use current directory name, so add counter to + # the end and try again. + CNT=$((CNT + 1)) + if [ $CNT -gt 9 ]; then + echo "Could not find valid backup dir ($BACKUPKERNELDIR)" + exit 1 + fi + BACKUPKERNELDIR="`echo $BACKUPKERNELDIR | sed -Ee 's/[0-9]\$//'`" + BACKUPKERNELDIR="${BACKUPKERNELDIR}${CNT}" + done +} + +# Backup the current kernel using hardlinks, if not disabled by user. +# Since we delete all files in the directory used for previous backups +# we create a marker file called ".freebsd-update" in the directory so +# we can determine on the next run that the directory was created by +# freebsd-update and we then do not accidentally remove user files in +# the unlikely case that the user has created a directory with a +# conflicting name. +backup_kernel () { + # Only make kernel backup is so configured. + if [ $BACKUPKERNEL != yes ]; then + return 0 + fi + + # Decide which directory name to use for kernel backups. + backup_kernel_finddir + + # Remove old kernel backup files. If $BACKUPKERNELDIR was + # "not ours", backup_kernel_finddir would have exited, so + # deleting the directory content is as safe as we can make it. + if [ -d $BACKUPKERNELDIR ]; then + rm -f $BACKUPKERNELDIR/* + fi + + # Create directory for backup if it doesn't exist. + mkdir -p $BACKUPKERNELDIR + + # Mark the directory as having been created by freebsd-update. + touch $BACKUPKERNELDIR/.freebsd-update + if [ $? -ne 0 ]; then + echo "Could not create kernel backup directory" + exit 1 + fi + + # Disable pathname expansion to be sure *.symbols is not + # expanded. + set -f + + # Use find to ignore symbol files, unless disabled by user. + if [ $BACKUPKERNELSYMBOLFILES = yes ]; then + FINDFILTER="" + else + FINDFILTER=-"a ! -name *.symbols" + fi + + # Backup all the kernel files using hardlinks. + find $KERNELDIR -type f $FINDFILTER | \ + sed -Ee "s,($KERNELDIR)/?(.*),\1/\2 ${BACKUPKERNELDIR}/\2," | \ + xargs -n 2 cp -pl + + # Re-enable patchname expansion. + set +f +} + # Install new files install_from_index () { # First pass: Do everything apart from setting file flags. We @@ -2575,6 +2732,9 @@ install_files () { grep -E '^/boot/' $1/INDEX-OLD > INDEX-OLD grep -E '^/boot/' $1/INDEX-NEW > INDEX-NEW + # Backup current kernel before installing a new one + backup_kernel || return 1 + # Install new files install_from_index INDEX-NEW || return 1 From 8844a1073004c30b1860d22b1e9b627801d9861b Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 20 Aug 2009 00:08:58 +0000 Subject: [PATCH 0109/2592] MFC r196395: Our libc doesn't implement control method for XDR (only kernel does) and it will always return failure. Fix this by bringing userland implementation of xdrmem_control() back. This allow 'zpool import' to work again. Reported by: Thomas Backman Reviewed by: kmacy Approved by: re (kib) --- sys/cddl/compat/opensolaris/rpc/xdr.h | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 sys/cddl/compat/opensolaris/rpc/xdr.h diff --git a/sys/cddl/compat/opensolaris/rpc/xdr.h b/sys/cddl/compat/opensolaris/rpc/xdr.h new file mode 100644 index 00000000000..277e0c338f0 --- /dev/null +++ b/sys/cddl/compat/opensolaris/rpc/xdr.h @@ -0,0 +1,70 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#ifndef _OPENSOLARIS_RPC_XDR_H_ +#define _OPENSOLARIS_RPC_XDR_H_ + +#include_next + +#ifndef _KERNEL + +#include + +/* + * Taken from sys/xdr/xdr_mem.c. + * + * FreeBSD's userland XDR doesn't implement control method (only the kernel), + * but OpenSolaris nvpair still depend on it, so we have to implement it here. + */ +static __inline bool_t +xdrmem_control(XDR *xdrs, int request, void *info) +{ + xdr_bytesrec *xptr; + + switch (request) { + case XDR_GET_BYTES_AVAIL: + xptr = (xdr_bytesrec *)info; + xptr->xc_is_last_record = TRUE; + xptr->xc_num_avail = xdrs->x_handy; + return (TRUE); + default: + assert(!"unexpected request"); + } + return (FALSE); +} + +#undef XDR_CONTROL +#define XDR_CONTROL(xdrs, req, op) \ + (((xdrs)->x_ops->x_control == NULL) ? \ + xdrmem_control((xdrs), (req), (op)) : \ + (*(xdrs)->x_ops->x_control)(xdrs, req, op)) + +#endif /* !_KERNEL */ + +#endif /* !_OPENSOLARIS_RPC_XDR_H_ */ From 566abe95b20b89720df2783aa009973d6465bf7a Mon Sep 17 00:00:00 2001 From: Will Andrews Date: Thu, 20 Aug 2009 02:49:43 +0000 Subject: [PATCH 0110/2592] MFC r196397 from head: Fix CARP memory leaks on carp_if's malloc'd using M_CARP. This occurs when CARP tries to free them using M_IFADDR after the last address for a virtual host is removed and when detaching from the parent interface. Approved by: re (kib), ken (mentor) --- sys/netinet/ip_carp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 18e446f8fc0..e3ffe5a4a6d 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -501,7 +501,7 @@ carpdetach(struct carp_softc *sc, int unlock) ifpromisc(sc->sc_carpdev, 0); sc->sc_carpdev->if_carp = NULL; CARP_LOCK_DESTROY(cif); - free(cif, M_IFADDR); + free(cif, M_CARP); } else if (unlock) CARP_UNLOCK(cif); sc->sc_carpdev = NULL; @@ -1639,7 +1639,7 @@ carp_del_addr(struct carp_softc *sc, struct sockaddr_in *sin) if (!--cif->vhif_nvrs) { sc->sc_carpdev->if_carp = NULL; CARP_LOCK_DESTROY(cif); - free(cif, M_IFADDR); + free(cif, M_CARP); } else { CARP_UNLOCK(cif); } @@ -1843,7 +1843,7 @@ carp_del_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6) if (!--cif->vhif_nvrs) { CARP_LOCK_DESTROY(cif); sc->sc_carpdev->if_carp = NULL; - free(cif, M_IFADDR); + free(cif, M_CARP); } else CARP_UNLOCK(cif); } From 2c68e2fb1e2cb7386b8863b4049198be949161e1 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Thu, 20 Aug 2009 11:04:31 +0000 Subject: [PATCH 0111/2592] MFC 196399: fstat: fix fsid comparison when executed on systems with 64-bit long This affects only fstat on zfs and devfs, only on 64-bit systems and only when fsid is greater than 2^31 - 1. When fstat examines a file via stat(2) it takes uint32_t st_dev and assigns to (signed) (64-bit) long fsid, this results in a positive value. When fstat examines opened files it takes int32_t f_fsid.val[0] and assigns to (signed) (64-bit) long fsid, this results in a negative value. So, while initially st_dev and f_fsid.val[0] have the same bit values they get promoted to different 64-bit values because of the signed-vs-unsigned difference. A fix is to use "more natural" positive numbers by introducing intermediate unsigned cast for f_fsid.val[0]. Reviewed by: jhb, lulf Approved by: re (kib) MFC after: 1 week (to stable/7) --- usr.bin/fstat/fstat.c | 2 +- usr.bin/fstat/zfs.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c index 53561e88e03..f82e964395b 100644 --- a/usr.bin/fstat/fstat.c +++ b/usr.bin/fstat/fstat.c @@ -658,7 +658,7 @@ devfs_filestat(struct vnode *vp, struct filestat *fsp) (void *)devfs_dirent.de_vnode, Pid); return 0; } - fsp->fsid = (long)mount.mnt_stat.f_fsid.val[0]; + fsp->fsid = (long)(uint32_t)mount.mnt_stat.f_fsid.val[0]; fsp->fileid = devfs_dirent.de_inode; fsp->mode = (devfs_dirent.de_mode & ~S_IFMT) | S_IFCHR; fsp->size = 0; diff --git a/usr.bin/fstat/zfs.c b/usr.bin/fstat/zfs.c index 008f1746b0b..96cdff6870a 100644 --- a/usr.bin/fstat/zfs.c +++ b/usr.bin/fstat/zfs.c @@ -117,7 +117,7 @@ zfs_filestat(struct vnode *vp, struct filestat *fsp) goto bad; } - fsp->fsid = (long)mount.mnt_stat.f_fsid.val[0]; + fsp->fsid = (long)(uint32_t)mount.mnt_stat.f_fsid.val[0]; fsp->fileid = *zid; /* * XXX: Shows up wrong in output, but UFS has this error too. Could From 247db0748a75747673b753a6af3e2c39dfae88ed Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 20 Aug 2009 20:23:28 +0000 Subject: [PATCH 0112/2592] MFC 196403: Temporarily revert the new-bus locking for 8.0 release. Approved by: re (kib) --- sys/dev/aac/aac.c | 8 +-- sys/dev/acpica/acpi.c | 14 +++- sys/dev/acpica/acpi_battery.c | 15 ----- sys/dev/acpica/acpi_cpu.c | 2 - sys/dev/acpica/acpi_dock.c | 8 +-- sys/dev/acpica/acpi_thermal.c | 3 - sys/dev/adb/adb_bus.c | 2 - sys/dev/amdtemp/amdtemp.c | 2 - sys/dev/amr/amr.c | 23 +------ sys/dev/ata/ata-all.c | 34 +++++----- sys/dev/atkbdc/psm.c | 4 -- sys/dev/bktr/bktr_os.c | 11 +--- sys/dev/drm/drm_drv.c | 8 --- sys/dev/ips/ips_pci.c | 2 - sys/dev/mfi/mfi.c | 20 ++---- sys/dev/mlx/mlx.c | 2 - sys/dev/mmc/mmc.c | 2 - sys/dev/pccbb/pccbb.c | 11 +++- sys/dev/pst/pst-iop.c | 2 - sys/dev/rp/rp.c | 4 -- sys/dev/sound/pci/hda/hdac.c | 2 - sys/dev/twe/twe.c | 6 -- sys/dev/usb/controller/usb_controller.c | 30 ++++++--- sys/dev/usb/input/ukbd.c | 13 ++-- sys/dev/usb/net/usb_ethernet.c | 11 ++-- sys/dev/usb/usb_compat_linux.c | 27 ++++++-- sys/dev/usb/usb_dev.c | 6 -- sys/dev/usb/usb_handle_request.c | 12 ++-- sys/dev/usb/usb_hub.c | 19 ++---- sys/dev/usb/wlan/if_upgt.c | 4 +- sys/dev/xen/blkback/blkback.c | 4 +- sys/dev/xen/netback/netback.c | 4 +- sys/i386/acpica/acpi_machdep.c | 6 -- sys/i386/bios/smapi.c | 2 - sys/i386/bios/smbios.c | 2 - sys/i386/bios/vpd.c | 2 - sys/kern/subr_bus.c | 87 ++----------------------- sys/pc98/cbus/fdc.c | 6 -- sys/sys/bus.h | 8 --- sys/xen/xenbus/xenbus_probe.c | 4 -- 40 files changed, 130 insertions(+), 302 deletions(-) diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index c576a3584e5..f3d931aaf06 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -3270,10 +3270,10 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) while (co != NULL) { if (co->co_found == 0) { mtx_unlock(&sc->aac_io_lock); - newbus_xlock(); + mtx_lock(&Giant); device_delete_child(sc->aac_dev, co->co_disk); - newbus_xunlock(); + mtx_unlock(&Giant); mtx_lock(&sc->aac_io_lock); co_next = TAILQ_NEXT(co, co_link); mtx_lock(&sc->aac_container_lock); @@ -3291,9 +3291,9 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) /* Attach the newly created containers */ if (added) { mtx_unlock(&sc->aac_io_lock); - newbus_xlock(); + mtx_lock(&Giant); bus_generic_attach(sc->aac_dev); - newbus_xunlock(); + mtx_unlock(&Giant); mtx_lock(&sc->aac_io_lock); } diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index c3e4e521379..63f95d3eb2c 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -675,6 +675,8 @@ acpi_suspend(device_t dev) device_t child, *devlist; int error, i, numdevs, pstate; + GIANT_REQUIRED; + /* First give child devices a chance to suspend. */ error = bus_generic_suspend(dev); if (error) @@ -717,6 +719,8 @@ acpi_resume(device_t dev) int i, numdevs, error; device_t child, *devlist; + GIANT_REQUIRED; + /* * Put all devices in D0 before resuming them. Call _S0D on each one * since some systems expect this. @@ -741,6 +745,8 @@ static int acpi_shutdown(device_t dev) { + GIANT_REQUIRED; + /* Allow children to shutdown first. */ bus_generic_shutdown(dev); @@ -2528,7 +2534,11 @@ acpi_EnterSleepState(struct acpi_softc *sc, int state) thread_unlock(curthread); #endif - newbus_xlock(); + /* + * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE + * drivers need this. + */ + mtx_lock(&Giant); slp_state = ACPI_SS_NONE; @@ -2601,7 +2611,7 @@ backout: if (slp_state >= ACPI_SS_SLEPT) acpi_enable_fixed_events(sc); - newbus_xunlock(); + mtx_unlock(&Giant); #ifdef SMP thread_lock(curthread); diff --git a/sys/dev/acpica/acpi_battery.c b/sys/dev/acpica/acpi_battery.c index 1ec1413d226..dd2b3fa2080 100644 --- a/sys/dev/acpica/acpi_battery.c +++ b/sys/dev/acpica/acpi_battery.c @@ -329,7 +329,6 @@ acpi_battery_find_dev(u_int logical_unit) dev = NULL; found_unit = 0; - newbus_slock(); batt_dc = devclass_find("battery"); maxunit = devclass_get_maxunit(batt_dc); for (i = 0; i < maxunit; i++) { @@ -341,7 +340,6 @@ acpi_battery_find_dev(u_int logical_unit) found_unit++; dev = NULL; } - newbus_sunlock(); return (dev); } @@ -371,17 +369,13 @@ acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg) */ switch (cmd) { case ACPIIO_BATT_GET_UNITS: - newbus_slock(); *(int *)addr = acpi_battery_get_units(); - newbus_sunlock(); error = 0; break; case ACPIIO_BATT_GET_BATTINFO: if (dev != NULL || unit == ACPI_BATTERY_ALL_UNITS) { bzero(&ioctl_arg->battinfo, sizeof(ioctl_arg->battinfo)); - newbus_slock(); error = acpi_battery_get_battinfo(dev, &ioctl_arg->battinfo); - newbus_sunlock(); } break; case ACPIIO_BATT_GET_BIF: @@ -422,11 +416,6 @@ acpi_battery_sysctl(SYSCTL_HANDLER_ARGS) { int val, error; - /* - * Tolerate a race here because newbus lock can't be acquired before - * acpi_battery_get_battinfo() as it can create a LOR with the sysctl - * lock. - */ acpi_battery_get_battinfo(NULL, &acpi_battery_battinfo); val = *(u_int *)oidp->oid_arg1; error = sysctl_handle_int(oidp, &val, 0, req); @@ -438,10 +427,6 @@ acpi_battery_units_sysctl(SYSCTL_HANDLER_ARGS) { int count, error; - /* - * Tolerate a race here in order to avoid a LOR between sysctl lock - * and newbus lock. - */ count = acpi_battery_get_units(); error = sysctl_handle_int(oidp, &count, 0, req); return (error); diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index 37134e23bf9..5d8ad535998 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -732,9 +732,7 @@ acpi_cpu_startup(void *arg) int i; /* Get set of CPU devices */ - newbus_slock(); devclass_get_devices(acpi_cpu_devclass, &cpu_devices, &cpu_ndevices); - newbus_sunlock(); /* * Setup any quirks that might necessary now that we have probed diff --git a/sys/dev/acpica/acpi_dock.c b/sys/dev/acpica/acpi_dock.c index 95b9faec157..b7d2e3e444a 100644 --- a/sys/dev/acpica/acpi_dock.c +++ b/sys/dev/acpica/acpi_dock.c @@ -188,12 +188,12 @@ acpi_dock_attach_later(void *context) dev = (device_t)context; - newbus_xlock(); if (!device_is_enabled(dev)) device_enable(dev); + mtx_lock(&Giant); device_probe_and_attach(dev); - newbus_xunlock(); + mtx_unlock(&Giant); } static ACPI_STATUS @@ -299,11 +299,11 @@ acpi_dock_eject_child(ACPI_HANDLE handle, UINT32 level, void *context, "ejecting device for %s\n", acpi_name(handle)); dev = acpi_get_device(handle); - newbus_xlock(); if (dev != NULL && device_is_attached(dev)) { + mtx_lock(&Giant); device_detach(dev); + mtx_unlock(&Giant); } - newbus_xunlock(); acpi_SetInteger(handle, "_EJ0", 0); out: diff --git a/sys/dev/acpica/acpi_thermal.c b/sys/dev/acpica/acpi_thermal.c index 1e58d529fd0..962fdb7e938 100644 --- a/sys/dev/acpica/acpi_thermal.c +++ b/sys/dev/acpica/acpi_thermal.c @@ -936,8 +936,6 @@ acpi_tz_thread(void *arg) sc = NULL; for (;;) { - newbus_slock(); - /* If the number of devices has changed, re-evaluate. */ if (devclass_get_count(acpi_tz_devclass) != devcount) { if (devs != NULL) { @@ -950,7 +948,6 @@ acpi_tz_thread(void *arg) for (i = 0; i < devcount; i++) sc[i] = device_get_softc(devs[i]); } - newbus_sunlock(); /* Check for temperature events and act on them. */ for (i = 0; i < devcount; i++) { diff --git a/sys/dev/adb/adb_bus.c b/sys/dev/adb/adb_bus.c index c4a9c96ae9e..faab048b52c 100644 --- a/sys/dev/adb/adb_bus.c +++ b/sys/dev/adb/adb_bus.c @@ -113,7 +113,6 @@ adb_bus_enumerate(void *xdev) uint8_t i, next_free; uint16_t r3; - newbus_xlock(); sc->sc_dev = dev; sc->parent = device_get_parent(dev); @@ -188,7 +187,6 @@ adb_bus_enumerate(void *xdev) } bus_generic_attach(dev); - newbus_xunlock(); config_intrhook_disestablish(&sc->enum_hook); } diff --git a/sys/dev/amdtemp/amdtemp.c b/sys/dev/amdtemp/amdtemp.c index ba7436aa57d..fdf087533c5 100644 --- a/sys/dev/amdtemp/amdtemp.c +++ b/sys/dev/amdtemp/amdtemp.c @@ -269,7 +269,6 @@ amdtemp_intrhook(void *arg) /* * dev.cpu.N.temperature. */ - newbus_xlock(); nexus = device_find_child(root_bus, "nexus", 0); acpi = device_find_child(nexus, "acpi", 0); @@ -286,7 +285,6 @@ amdtemp_intrhook(void *arg) "Max of sensor 0 / 1"); } } - newbus_xunlock(); config_intrhook_disestablish(&sc->sc_ich); } diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c index 688b2df63ad..2061fcc801f 100644 --- a/sys/dev/amr/amr.c +++ b/sys/dev/amr/amr.c @@ -90,10 +90,6 @@ __FBSDID("$FreeBSD$"); SYSCTL_NODE(_hw, OID_AUTO, amr, CTLFLAG_RD, 0, "AMR driver parameters"); -/* - * In order to get rid of Giant, amr_state should be protected by - * a proper softc lock for the cdev operations. - */ static d_open_t amr_open; static d_close_t amr_close; static d_ioctl_t amr_ioctl; @@ -316,11 +312,9 @@ amr_startup(void *arg) config_intrhook_disestablish(&sc->amr_ich); sc->amr_ich.ich_func = NULL; - newbus_xlock(); /* get up-to-date drive information */ if (amr_query_controller(sc)) { device_printf(sc->amr_dev, "can't scan controller for drives\n"); - newbus_xunlock(); return; } @@ -353,7 +347,6 @@ amr_startup(void *arg) /* interrupts will be enabled before we do anything more */ sc->amr_state |= AMR_STATE_INTEN; - newbus_xunlock(); /* * Start the timeout routine. @@ -441,11 +434,7 @@ static int amr_open(struct cdev *dev, int flags, int fmt, struct thread *td) { int unit = dev2unit(dev); - struct amr_softc *sc; - - newbus_slock(); - sc = devclass_get_softc(devclass_find("amr"), unit); - newbus_sunlock(); + struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); debug_called(1); @@ -501,11 +490,7 @@ static int amr_close(struct cdev *dev, int flags, int fmt, struct thread *td) { int unit = dev2unit(dev); - struct amr_softc *sc; - - newbus_slock(); - sc = devclass_get_softc(devclass_find("amr"), unit); - newbus_sunlock(); + struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); debug_called(1); @@ -522,7 +507,6 @@ amr_rescan_drives(struct cdev *dev) struct amr_softc *sc = (struct amr_softc *)dev->si_drv1; int i, error = 0; - newbus_xlock(); sc->amr_state |= AMR_STATE_REMAP_LD; while (sc->amr_busyslots) { device_printf(sc->amr_dev, "idle controller\n"); @@ -546,7 +530,6 @@ amr_rescan_drives(struct cdev *dev) sc->amr_drive[i].al_disk = 0; } } - newbus_xunlock(); shutdown_out: amr_startup(sc); @@ -822,9 +805,7 @@ amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct threa struct amr_linux_ioctl ali; int adapter, error; - newbus_slock(); devclass = devclass_find("amr"); - newbus_sunlock(); if (devclass == NULL) return (ENOENT); diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 6696f0cff0c..1460a2117d4 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); static d_ioctl_t ata_ioctl; static struct cdevsw ata_cdevsw = { .d_version = D_VERSION, + .d_flags = D_NEEDGIANT, /* we need this as newbus isn't mpsafe */ .d_ioctl = ata_ioctl, .d_name = "ata", }; @@ -203,9 +204,7 @@ ata_conn_event(void *context, int dummy) { device_t dev = (device_t)context; - newbus_xlock(); ata_reinit(dev); - newbus_xunlock(); } int @@ -247,6 +246,7 @@ ata_reinit(device_t dev) /* reinit the children and delete any that fails */ if (!device_get_children(dev, &children, &nchildren)) { + mtx_lock(&Giant); /* newbus suckage it needs Giant */ for (i = 0; i < nchildren; i++) { /* did any children go missing ? */ if (children[i] && device_is_attached(children[i]) && @@ -269,6 +269,7 @@ ata_reinit(device_t dev) } } free(children, M_TEMP); + mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */ } /* if we still have a good request put it on the queue again */ @@ -394,7 +395,6 @@ ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int *value = (int *)data; int i, nchildren, error = ENOTTY; - newbus_xlock(); switch (cmd) { case IOCATAGMAXCHANNEL: /* In case we have channel 0..n this will return n+1. */ @@ -405,40 +405,32 @@ ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data, case IOCATAREINIT: if (*value >= devclass_get_maxunit(ata_devclass) || !(device = devclass_get_device(ata_devclass, *value)) || - !device_is_attached(device)) { - newbus_xunlock(); + !device_is_attached(device)) return ENXIO; - } error = ata_reinit(device); break; case IOCATAATTACH: if (*value >= devclass_get_maxunit(ata_devclass) || !(device = devclass_get_device(ata_devclass, *value)) || - !device_is_attached(device)) { - newbus_xunlock(); + !device_is_attached(device)) return ENXIO; - } error = DEVICE_ATTACH(device); break; case IOCATADETACH: if (*value >= devclass_get_maxunit(ata_devclass) || !(device = devclass_get_device(ata_devclass, *value)) || - !device_is_attached(device)) { - newbus_xunlock(); + !device_is_attached(device)) return ENXIO; - } error = DEVICE_DETACH(device); break; case IOCATADEVICES: if (devices->channel >= devclass_get_maxunit(ata_devclass) || !(device = devclass_get_device(ata_devclass, devices->channel)) || - !device_is_attached(device)) { - newbus_xunlock(); + !device_is_attached(device)) return ENXIO; - } bzero(devices->name[0], 32); bzero(&devices->params[0], sizeof(struct ata_params)); bzero(devices->name[1], 32); @@ -473,7 +465,6 @@ ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data, if (ata_raid_ioctl_func) error = ata_raid_ioctl_func(cmd, data); } - newbus_xunlock(); return error; } @@ -581,7 +572,7 @@ ata_boot_attach(void) struct ata_channel *ch; int ctlr; - newbus_xlock(); + mtx_lock(&Giant); /* newbus suckage it needs Giant */ /* kick of probe and attach on all channels */ for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) { @@ -596,7 +587,8 @@ ata_boot_attach(void) free(ata_delayed_attach, M_TEMP); ata_delayed_attach = NULL; } - newbus_xunlock(); + + mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */ } @@ -725,6 +717,7 @@ ata_identify(device_t dev) if (bootverbose) device_printf(dev, "Identifying devices: %08x\n", ch->devices); + mtx_lock(&Giant); /* Skip existing devices. */ if (!device_get_children(dev, &children, &nchildren)) { for (i = 0; i < nchildren; i++) { @@ -736,8 +729,10 @@ ata_identify(device_t dev) /* Create new devices. */ if (bootverbose) device_printf(dev, "New devices: %08x\n", n); - if (n == 0) + if (n == 0) { + mtx_unlock(&Giant); return (0); + } for (i = 0; i < ATA_PM; ++i) { if (n & (((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << i))) { int unit = -1; @@ -780,6 +775,7 @@ ata_identify(device_t dev) } bus_generic_probe(dev); bus_generic_attach(dev); + mtx_unlock(&Giant); return 0; } diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index 1fbdee76e25..93c9acb7a9c 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -1488,9 +1488,7 @@ psmopen(struct cdev *dev, int flag, int fmt, struct thread *td) if (sc->state & PSM_OPEN) return (EBUSY); - newbus_xlock(); device_busy(devclass_get_device(psm_devclass, unit)); - newbus_xunlock(); /* Initialize state */ sc->mode.level = sc->dflt_mode.level; @@ -1645,9 +1643,7 @@ psmclose(struct cdev *dev, int flag, int fmt, struct thread *td) /* close is almost always successful */ sc->state &= ~PSM_OPEN; kbdc_lock(sc->kbdc, FALSE); - newbus_xlock(); device_unbusy(devclass_get_device(psm_devclass, unit)); - newbus_xunlock(); return (0); } diff --git a/sys/dev/bktr/bktr_os.c b/sys/dev/bktr/bktr_os.c index 1fd458cd3c1..327c4bbdb95 100644 --- a/sys/dev/bktr/bktr_os.c +++ b/sys/dev/bktr/bktr_os.c @@ -597,9 +597,7 @@ bktr_open( struct cdev *dev, int flags, int fmt, struct thread *td ) return( ENXIO ); /* Record that the device is now busy */ - newbus_xlock(); device_busy(devclass_get_device(bktr_devclass, unit)); - newbus_xunlock(); if (bt848_card != -1) { @@ -670,11 +668,8 @@ bktr_open( struct cdev *dev, int flags, int fmt, struct thread *td ) } /* If there was an error opening the device, undo the busy status */ - if (result != 0) { - newbus_xlock(); + if (result != 0) device_unbusy(devclass_get_device(bktr_devclass, unit)); - newbus_xunlock(); - } return( result ); } @@ -694,7 +689,6 @@ bktr_close( struct cdev *dev, int flags, int fmt, struct thread *td ) /* Get the device data */ bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit); if (bktr == NULL) { - /* the device is no longer valid/functioning */ return (ENXIO); } @@ -711,11 +705,10 @@ bktr_close( struct cdev *dev, int flags, int fmt, struct thread *td ) break; default: return (ENXIO); + break; } - newbus_xlock(); device_unbusy(devclass_get_device(bktr_devclass, unit)); - newbus_xunlock(); return( result ); } diff --git a/sys/dev/drm/drm_drv.c b/sys/dev/drm/drm_drv.c index e12f8cdfa92..561afd5e8fb 100644 --- a/sys/dev/drm/drm_drv.c +++ b/sys/dev/drm/drm_drv.c @@ -614,13 +614,11 @@ int drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) if (!retcode) { atomic_inc(&dev->counts[_DRM_STAT_OPENS]); - newbus_xlock(); DRM_LOCK(); device_busy(dev->device); if (!dev->open_count++) retcode = drm_firstopen(dev); DRM_UNLOCK(); - newbus_xunlock(); } return retcode; @@ -634,11 +632,6 @@ void drm_close(void *data) DRM_DEBUG("open_count = %d\n", dev->open_count); - /* - * We require to lock newbus here for handling device_unbusy() and - * avoid a LOR with DRM_LOCK. - */ - newbus_xlock(); DRM_LOCK(); if (dev->driver->preclose != NULL) @@ -715,7 +708,6 @@ void drm_close(void *data) } DRM_UNLOCK(); - newbus_xunlock(); } /* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. diff --git a/sys/dev/ips/ips_pci.c b/sys/dev/ips/ips_pci.c index 70e7d3be068..9ccaf373b3e 100644 --- a/sys/dev/ips/ips_pci.c +++ b/sys/dev/ips/ips_pci.c @@ -173,12 +173,10 @@ ips_intrhook(void *arg) struct ips_softc *sc = (struct ips_softc *)arg; config_intrhook_disestablish(&sc->ips_ich); - newbus_xlock(); if (ips_adapter_init(sc)) ips_pci_free(sc); else sc->configured = 1; - newbus_xunlock(); } static int ips_pci_free(ips_softc_t *sc) diff --git a/sys/dev/mfi/mfi.c b/sys/dev/mfi/mfi.c index 0ae585e892d..eb18ffe4ce3 100644 --- a/sys/dev/mfi/mfi.c +++ b/sys/dev/mfi/mfi.c @@ -1327,11 +1327,11 @@ mfi_add_ld_complete(struct mfi_command *cm) mfi_release_command(cm); mtx_unlock(&sc->mfi_io_lock); - newbus_xlock(); + mtx_lock(&Giant); if ((child = device_add_child(sc->mfi_dev, "mfid", -1)) == NULL) { device_printf(sc->mfi_dev, "Failed to add logical disk\n"); free(ld_info, M_MFIBUF); - newbus_xunlock(); + mtx_unlock(&Giant); mtx_lock(&sc->mfi_io_lock); return; } @@ -1339,7 +1339,7 @@ mfi_add_ld_complete(struct mfi_command *cm) device_set_ivars(child, ld_info); device_set_desc(child, "MFI Logical Disk"); bus_generic_attach(sc->mfi_dev); - newbus_xunlock(); + mtx_unlock(&Giant); mtx_lock(&sc->mfi_io_lock); } @@ -1805,9 +1805,9 @@ mfi_check_command_post(struct mfi_softc *sc, struct mfi_command *cm) KASSERT(ld != NULL, ("volume dissappeared")); if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) { mtx_unlock(&sc->mfi_io_lock); - newbus_xlock(); + mtx_lock(&Giant); device_delete_child(sc->mfi_dev, ld->ld_dev); - newbus_xunlock(); + mtx_unlock(&Giant); mtx_lock(&sc->mfi_io_lock); } else mfi_disk_enable(ld); @@ -1815,11 +1815,11 @@ mfi_check_command_post(struct mfi_softc *sc, struct mfi_command *cm) case MFI_DCMD_CFG_CLEAR: if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) { mtx_unlock(&sc->mfi_io_lock); - newbus_xlock(); + mtx_lock(&Giant); TAILQ_FOREACH_SAFE(ld, &sc->mfi_ld_tqh, ld_link, ldn) { device_delete_child(sc->mfi_dev, ld->ld_dev); } - newbus_xunlock(); + mtx_unlock(&Giant); mtx_lock(&sc->mfi_io_lock); } else { TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) @@ -1985,9 +1985,7 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td adapter = ioc->mfi_adapter_no; if (device_get_unit(sc->mfi_dev) == 0 && adapter != 0) { - newbus_slock(); devclass = devclass_find("mfi"); - newbus_sunlock(); sc = devclass_get_softc(devclass, adapter); } mtx_lock(&sc->mfi_io_lock); @@ -2175,9 +2173,7 @@ out: struct mfi_linux_ioc_packet l_ioc; int adapter; - newbus_slock(); devclass = devclass_find("mfi"); - newbus_sunlock(); if (devclass == NULL) return (ENOENT); @@ -2198,9 +2194,7 @@ out: struct mfi_linux_ioc_aen l_aen; int adapter; - newbus_slock(); devclass = devclass_find("mfi"); - newbus_sunlock(); if (devclass == NULL) return (ENOENT); diff --git a/sys/dev/mlx/mlx.c b/sys/dev/mlx/mlx.c index 9e74f624573..6087216901f 100644 --- a/sys/dev/mlx/mlx.c +++ b/sys/dev/mlx/mlx.c @@ -772,9 +772,7 @@ mlx_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct threa * Scan the controller to see whether new drives have appeared. */ case MLX_RESCAN_DRIVES: - newbus_xlock(); mlx_startup(sc); - newbus_xunlock(); return(0); /* diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c index 0fd424dbaf4..68726675f81 100644 --- a/sys/dev/mmc/mmc.c +++ b/sys/dev/mmc/mmc.c @@ -1496,9 +1496,7 @@ mmc_delayed_attach(void *xsc) { struct mmc_softc *sc = xsc; - newbus_xlock(); mmc_scan(sc); - newbus_xunlock(); config_intrhook_disestablish(&sc->config_intrhook); } diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index f60118528ff..a0585b00b8e 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -464,7 +464,14 @@ cbb_event_thread(void *arg) sc->flags |= CBB_KTHREAD_RUNNING; while ((sc->flags & CBB_KTHREAD_DONE) == 0) { mtx_unlock(&sc->mtx); - newbus_xlock(); + /* + * We take out Giant here because we need it deep, + * down in the bowels of the vm system for mapping the + * memory we need to read the CIS. In addition, since + * we are adding/deleting devices from the dev tree, + * and that code isn't MP safe, we have to hold Giant. + */ + mtx_lock(&Giant); status = cbb_get(sc, CBB_SOCKET_STATE); DPRINTF(("Status is 0x%x\n", status)); if (!CBB_CARD_PRESENT(status)) { @@ -490,7 +497,7 @@ cbb_event_thread(void *arg) not_a_card = 0; /* We know card type */ cbb_insert(sc); } - newbus_xunlock(); + mtx_unlock(&Giant); /* * First time through we need to tell mountroot that we're diff --git a/sys/dev/pst/pst-iop.c b/sys/dev/pst/pst-iop.c index 3fa37fdbfd3..d4e83f01ecb 100644 --- a/sys/dev/pst/pst-iop.c +++ b/sys/dev/pst/pst-iop.c @@ -152,9 +152,7 @@ iop_attach(void *arg) break; case I2O_CLASS_RANDOM_BLOCK_STORAGE: - newbus_xlock(); pst_add_raid(sc, &sc->lct[i]); - newbus_xunlock(); break; } } diff --git a/sys/dev/rp/rp.c b/sys/dev/rp/rp.c index 45f59d37304..520ca80f930 100644 --- a/sys/dev/rp/rp.c +++ b/sys/dev/rp/rp.c @@ -903,9 +903,7 @@ rpopen(struct tty *tp) rp_callout_handle = timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); - newbus_xlock(); device_busy(rp->rp_ctlp->dev); - newbus_xunlock(); return(0); } @@ -916,9 +914,7 @@ rpclose(struct tty *tp) rp = tty_softc(tp); rphardclose(tp); - newbus_xlock(); device_unbusy(rp->rp_ctlp->dev); - newbus_xunlock(); } static void diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index bf99d54ea1f..9f4264d98ec 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -7435,7 +7435,6 @@ hdac_attach2(void *arg) quirks_on, quirks_off); ); - newbus_xlock(); hdac_lock(sc); /* Remove ourselves from the config hooks */ @@ -7675,7 +7674,6 @@ hdac_attach2(void *arg) SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO, "pindump", CTLTYPE_INT | CTLFLAG_RW, sc->dev, sizeof(sc->dev), sysctl_hdac_pindump, "I", "Dump pin states/data"); - newbus_xunlock(); } /**************************************************************************** diff --git a/sys/dev/twe/twe.c b/sys/dev/twe/twe.c index 2641fae5e85..59b5027adac 100644 --- a/sys/dev/twe/twe.c +++ b/sys/dev/twe/twe.c @@ -294,10 +294,8 @@ twe_init(struct twe_softc *sc) /* * Scan for drives */ - newbus_xlock(); for (i = 0; i < TWE_MAX_UNITS; i++) twe_add_unit(sc, i); - newbus_xunlock(); /* * Initialise connection with controller. @@ -623,15 +621,11 @@ twe_ioctl(struct twe_softc *sc, int ioctlcmd, void *addr) break; case TWEIO_ADD_UNIT: - newbus_xlock(); error = twe_add_unit(sc, td->td_unit); - newbus_xunlock(); break; case TWEIO_DEL_UNIT: - newbus_xlock(); error = twe_del_unit(sc, td->td_unit); - newbus_xunlock(); break; /* XXX implement ATA PASSTHROUGH */ diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c index f6776f01a4c..7a019dcaa7a 100644 --- a/sys/dev/usb/controller/usb_controller.c +++ b/sys/dev/usb/controller/usb_controller.c @@ -143,7 +143,9 @@ usb_attach(device_t dev) } if (usb_post_init_called) { + mtx_lock(&Giant); usb_attach_sub(dev, bus); + mtx_unlock(&Giant); usb_needs_explore(bus, 1); } return (0); /* return success */ @@ -226,13 +228,20 @@ usb_bus_explore(struct usb_proc_msg *pm) } USB_BUS_UNLOCK(bus); + mtx_lock(&Giant); + /* * First update the USB power state! */ usb_bus_powerd(bus); - - /* Explore the Root USB HUB. */ + /* + * Explore the Root USB HUB. This call can sleep, + * exiting Giant, which is actually Giant. + */ (udev->hub->explore) (udev); + + mtx_unlock(&Giant); + USB_BUS_LOCK(bus); } if (bus->bus_roothold != NULL) { @@ -260,7 +269,7 @@ usb_bus_detach(struct usb_proc_msg *pm) device_set_softc(dev, NULL); USB_BUS_UNLOCK(bus); - newbus_xlock(); + mtx_lock(&Giant); /* detach children first */ bus_generic_detach(dev); @@ -272,7 +281,7 @@ usb_bus_detach(struct usb_proc_msg *pm) usb_free_device(udev, USB_UNCFG_FLAG_FREE_EP0); - newbus_xunlock(); + mtx_unlock(&Giant); USB_BUS_LOCK(bus); /* clear bdev variable last */ bus->bdev = NULL; @@ -341,7 +350,7 @@ usb_bus_attach(struct usb_proc_msg *pm) } USB_BUS_UNLOCK(bus); - newbus_xlock(); + mtx_lock(&Giant); /* XXX not required by USB */ /* default power_mask value */ bus->hw_power_state = @@ -374,7 +383,7 @@ usb_bus_attach(struct usb_proc_msg *pm) err = USB_ERR_NOMEM; } - newbus_xunlock(); + mtx_unlock(&Giant); USB_BUS_LOCK(bus); if (err) { @@ -463,7 +472,7 @@ usb_post_init(void *arg) int max; int n; - newbus_xlock(); + mtx_lock(&Giant); usb_devclass_ptr = devclass_find("usbus"); @@ -474,8 +483,11 @@ usb_post_init(void *arg) dev = devclass_get_device(dc, n); if (dev && device_is_attached(dev)) { bus = device_get_ivars(dev); - if (bus) + if (bus) { + mtx_lock(&Giant); usb_attach_sub(dev, bus); + mtx_unlock(&Giant); + } } } } else { @@ -487,7 +499,7 @@ usb_post_init(void *arg) usb_needs_explore_all(); - newbus_xunlock(); + mtx_unlock(&Giant); } SYSINIT(usb_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb_post_init, NULL); diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index 2170b370016..0d09ad43783 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -745,7 +745,7 @@ ukbd_attach(device_t dev) uint16_t n; uint16_t hid_len; - mtx_lock(&Giant); + mtx_assert(&Giant, MA_OWNED); kbd_init_struct(kbd, UKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0); @@ -854,6 +854,9 @@ ukbd_attach(device_t dev) if (bootverbose) { genkbd_diag(kbd, bootverbose); } + /* lock keyboard mutex */ + + mtx_lock(&Giant); /* start the keyboard */ @@ -876,7 +879,7 @@ ukbd_detach(device_t dev) struct ukbd_softc *sc = device_get_softc(dev); int error; - mtx_lock(&Giant); + mtx_assert(&Giant, MA_OWNED); DPRINTF("\n"); @@ -913,8 +916,6 @@ ukbd_detach(device_t dev) usb_callout_drain(&sc->sc_callout); - mtx_unlock(&Giant); - DPRINTF("%s: disconnected\n", device_get_nameunit(dev)); @@ -926,9 +927,9 @@ ukbd_resume(device_t dev) { struct ukbd_softc *sc = device_get_softc(dev); - mtx_lock(&Giant); + mtx_assert(&Giant, MA_OWNED); + ukbd_clear_state(&sc->sc_kbd); - mtx_unlock(&Giant); return (0); } diff --git a/sys/dev/usb/net/usb_ethernet.c b/sys/dev/usb/net/usb_ethernet.c index 427137a92f2..6cf446016e7 100644 --- a/sys/dev/usb/net/usb_ethernet.c +++ b/sys/dev/usb/net/usb_ethernet.c @@ -221,10 +221,10 @@ ue_attach_post_task(struct usb_proc_msg *_task) if (ue->ue_methods->ue_mii_upd != NULL && ue->ue_methods->ue_mii_sts != NULL) { - newbus_xlock(); + mtx_lock(&Giant); /* device_xxx() depends on this */ error = mii_phy_probe(ue->ue_dev, &ue->ue_miibus, ue_ifmedia_upd, ue->ue_methods->ue_mii_sts); - newbus_xunlock(); + mtx_unlock(&Giant); if (error) { device_printf(ue->ue_dev, "MII without any PHY\n"); goto error; @@ -279,12 +279,9 @@ uether_ifdetach(struct usb_ether *ue) /* detach miibus */ if (ue->ue_miibus != NULL) { - - /* - * It is up to the callers to provide the correct - * newbus locking. - */ + mtx_lock(&Giant); /* device_xxx() depends on this */ device_delete_child(ue->ue_dev, ue->ue_miibus); + mtx_unlock(&Giant); } /* detach ethernet */ diff --git a/sys/dev/usb/usb_compat_linux.c b/sys/dev/usb/usb_compat_linux.c index 00fc86bdc98..604ac4d8845 100644 --- a/sys/dev/usb/usb_compat_linux.c +++ b/sys/dev/usb/usb_compat_linux.c @@ -215,12 +215,14 @@ usb_linux_probe(device_t dev) if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } + mtx_lock(&Giant); LIST_FOREACH(udrv, &usb_linux_driver_list, linux_driver_list) { if (usb_linux_lookup_id(udrv->id_table, uaa)) { err = 0; break; } } + mtx_unlock(&Giant); return (err); } @@ -237,7 +239,9 @@ usb_linux_get_usb_driver(struct usb_linux_softc *sc) { struct usb_driver *udrv; + mtx_lock(&Giant); udrv = sc->sc_udrv; + mtx_unlock(&Giant); return (udrv); } @@ -256,11 +260,13 @@ usb_linux_attach(device_t dev) struct usb_driver *udrv; const struct usb_device_id *id = NULL; + mtx_lock(&Giant); LIST_FOREACH(udrv, &usb_linux_driver_list, linux_driver_list) { id = usb_linux_lookup_id(udrv->id_table, uaa); if (id) break; } + mtx_unlock(&Giant); if (id == NULL) { return (ENXIO); @@ -281,7 +287,9 @@ usb_linux_attach(device_t dev) return (ENXIO); } } + mtx_lock(&Giant); LIST_INSERT_HEAD(&usb_linux_attached_list, sc, sc_attached_list); + mtx_unlock(&Giant); /* success */ return (0); @@ -299,12 +307,14 @@ usb_linux_detach(device_t dev) struct usb_linux_softc *sc = device_get_softc(dev); struct usb_driver *udrv = NULL; + mtx_lock(&Giant); if (sc->sc_attached_list.le_prev) { LIST_REMOVE(sc, sc_attached_list); sc->sc_attached_list.le_prev = NULL; udrv = sc->sc_udrv; sc->sc_udrv = NULL; } + mtx_unlock(&Giant); if (udrv && udrv->disconnect) { (udrv->disconnect) (sc->sc_ui); @@ -464,10 +474,13 @@ usb_unlink_bsd(struct usb_xfer *xfer, if (!usbd_transfer_pending(xfer)) return; if (xfer->priv_fifo == (void *)urb) { - if (drain) + if (drain) { + mtx_unlock(&Giant); usbd_transfer_drain(xfer); - else + mtx_lock(&Giant); + } else { usbd_transfer_stop(xfer); + } usbd_transfer_start(xfer); } } @@ -1135,9 +1148,9 @@ usb_linux_register(void *arg) { struct usb_driver *drv = arg; - newbus_xlock(); + mtx_lock(&Giant); LIST_INSERT_HEAD(&usb_linux_driver_list, drv, linux_driver_list); - newbus_xunlock(); + mtx_unlock(&Giant); usb_needs_explore_all(); } @@ -1159,16 +1172,16 @@ usb_linux_deregister(void *arg) struct usb_linux_softc *sc; repeat: - newbus_xlock(); + mtx_lock(&Giant); LIST_FOREACH(sc, &usb_linux_attached_list, sc_attached_list) { if (sc->sc_udrv == drv) { + mtx_unlock(&Giant); device_detach(sc->sc_fbsd_dev); - newbus_xunlock(); goto repeat; } } LIST_REMOVE(drv, linux_driver_list); - newbus_xunlock(); + mtx_unlock(&Giant); } /*------------------------------------------------------------------------* diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c index b7c6553db75..cba8919255c 100644 --- a/sys/dev/usb/usb_dev.c +++ b/sys/dev/usb/usb_dev.c @@ -1040,14 +1040,9 @@ usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* * Performance optimisation: We try to check for IOCTL's that * don't need the USB reference first. Then we grab the USB * reference if we need it! - * Note that some ioctl_post handlers would need to run with the - * newbus lock held. It cannot be acquired later because it can - * introduce a LOR, so acquire it here. */ - newbus_xlock(); err = usb_ref_device(cpd, &refs, 0 /* no uref */ ); if (err) { - newbus_xunlock(); return (ENXIO); } fflags = cpd->fflags; @@ -1081,7 +1076,6 @@ usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* } done: usb_unref_device(cpd, &refs); - newbus_xunlock(); return (err); } diff --git a/sys/dev/usb/usb_handle_request.c b/sys/dev/usb/usb_handle_request.c index 2bc3eefd210..a720919b7d8 100644 --- a/sys/dev/usb/usb_handle_request.c +++ b/sys/dev/usb/usb_handle_request.c @@ -152,7 +152,7 @@ usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no) * attach: */ USB_XFER_UNLOCK(xfer); - newbus_xlock(); + mtx_lock(&Giant); /* XXX */ sx_xlock(udev->default_sx + 1); if (conf_no == USB_UNCONFIG_NO) { @@ -176,8 +176,8 @@ usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no) goto done; } done: + mtx_unlock(&Giant); /* XXX */ sx_unlock(udev->default_sx + 1); - newbus_xunlock(); USB_XFER_LOCK(xfer); return (err); } @@ -236,7 +236,7 @@ usb_handle_iface_request(struct usb_xfer *xfer, * attach: */ USB_XFER_UNLOCK(xfer); - newbus_xlock(); + mtx_lock(&Giant); /* XXX */ sx_xlock(udev->default_sx + 1); error = ENXIO; @@ -353,20 +353,20 @@ tr_repeat: goto tr_stalled; } tr_valid: + mtx_unlock(&Giant); sx_unlock(udev->default_sx + 1); - newbus_xunlock(); USB_XFER_LOCK(xfer); return (0); tr_short: + mtx_unlock(&Giant); sx_unlock(udev->default_sx + 1); - newbus_xunlock(); USB_XFER_LOCK(xfer); return (USB_ERR_SHORT_XFER); tr_stalled: + mtx_unlock(&Giant); sx_unlock(udev->default_sx + 1); - newbus_xunlock(); USB_XFER_LOCK(xfer); return (USB_ERR_STALLED); } diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index a09be96b8e4..0defc97c30c 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -234,10 +234,8 @@ uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up) if (child->driver_added_refcount != refcount) { child->driver_added_refcount = refcount; - newbus_xlock(); err = usb_probe_and_attach(child, USB_IFACE_INDEX_ANY); - newbus_xunlock(); if (err) { goto done; } @@ -320,11 +318,9 @@ repeat: /* detach any existing devices */ if (child) { - newbus_xlock(); usb_free_device(child, USB_UNCFG_FLAG_FREE_SUBDEV | USB_UNCFG_FLAG_FREE_EP0); - newbus_xunlock(); child = NULL; } /* get fresh status */ @@ -432,10 +428,9 @@ repeat: mode = USB_MODE_HOST; /* need to create a new child */ - newbus_xlock(); + child = usb_alloc_device(sc->sc_dev, udev->bus, udev, udev->depth + 1, portno - 1, portno, speed, mode); - newbus_xunlock(); if (child == NULL) { DPRINTFN(0, "could not allocate new device!\n"); goto error; @@ -444,11 +439,9 @@ repeat: error: if (child) { - newbus_xlock(); usb_free_device(child, USB_UNCFG_FLAG_FREE_SUBDEV | USB_UNCFG_FLAG_FREE_EP0); - newbus_xunlock(); child = NULL; } if (err == 0) { @@ -987,6 +980,7 @@ uhub_child_location_string(device_t parent, device_t child, struct usb_hub *hub = sc->sc_udev->hub; struct hub_result res; + mtx_lock(&Giant); uhub_find_iface_index(hub, child, &res); if (!res.udev) { DPRINTF("device not on hub\n"); @@ -998,6 +992,7 @@ uhub_child_location_string(device_t parent, device_t child, snprintf(buf, buflen, "port=%u interface=%u", res.portno, res.iface_index); done: + mtx_unlock(&Giant); return (0); } @@ -1011,6 +1006,7 @@ uhub_child_pnpinfo_string(device_t parent, device_t child, struct usb_interface *iface; struct hub_result res; + mtx_lock(&Giant); uhub_find_iface_index(hub, child, &res); if (!res.udev) { DPRINTF("device not on hub\n"); @@ -1041,6 +1037,7 @@ uhub_child_pnpinfo_string(device_t parent, device_t child, goto done; } done: + mtx_unlock(&Giant); return (0); } @@ -1778,13 +1775,10 @@ usb_dev_resume_peer(struct usb_device *udev) /* always update hardware power! */ (bus->methods->set_hw_power) (bus); } - newbus_xlock(); sx_xlock(udev->default_sx + 1); - /* notify all sub-devices about resume */ err = usb_suspend_resume(udev, 0); sx_unlock(udev->default_sx + 1); - newbus_xunlock(); /* check if peer has wakeup capability */ if (usb_peer_can_wakeup(udev)) { @@ -1850,13 +1844,10 @@ repeat: } } - newbus_xlock(); sx_xlock(udev->default_sx + 1); - /* notify all sub-devices about suspend */ err = usb_suspend_resume(udev, 1); sx_unlock(udev->default_sx + 1); - newbus_xunlock(); if (usb_peer_can_wakeup(udev)) { /* allow device to do remote wakeup */ diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index 8714645450e..ff3220b716f 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -465,7 +465,7 @@ upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) switch (cmd) { case SIOCSIFFLAGS: - newbus_xlock(); + mtx_lock(&Giant); if (ifp->if_flags & IFF_UP) { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { if ((ifp->if_flags ^ sc->sc_if_flags) & @@ -482,7 +482,7 @@ upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sc->sc_if_flags = ifp->if_flags; if (startall) ieee80211_start_all(ic); - newbus_xunlock(); + mtx_unlock(&Giant); break; case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c index 535b1e078bc..259f2f6c041 100644 --- a/sys/dev/xen/blkback/blkback.c +++ b/sys/dev/xen/blkback/blkback.c @@ -1156,7 +1156,7 @@ vbd_add_dev(struct xenbus_device *xdev) devclass_t dc; int err = 0; - newbus_xlock(); + mtx_lock(&Giant); /* We will add a vbd device as a child of nexus0 (for now) */ if (!(dc = devclass_find("nexus")) || @@ -1183,7 +1183,7 @@ vbd_add_dev(struct xenbus_device *xdev) done: - newbus_xunlock(); + mtx_unlock(&Giant); return err; } diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c index cabc4ab7241..a6111e265f5 100644 --- a/sys/dev/xen/netback/netback.c +++ b/sys/dev/xen/netback/netback.c @@ -1388,7 +1388,7 @@ vif_add_dev(struct xenbus_device *xdev) devclass_t dc; int err = 0; - newbus_xlock(); + mtx_lock(&Giant); /* We will add a vif device as a child of nexus0 (for now) */ if (!(dc = devclass_find("nexus")) || @@ -1415,7 +1415,7 @@ vif_add_dev(struct xenbus_device *xdev) done: - newbus_xunlock(); + mtx_unlock(&Giant); return err; } diff --git a/sys/i386/acpica/acpi_machdep.c b/sys/i386/acpica/acpi_machdep.c index 456867123b1..e26cce9a729 100644 --- a/sys/i386/acpica/acpi_machdep.c +++ b/sys/i386/acpica/acpi_machdep.c @@ -164,7 +164,6 @@ acpi_capm_get_info(apm_info_t aip) else aip->ai_acline = acline; /* on/off */ - newbus_slock(); if (acpi_battery_get_battinfo(NULL, &batt) != 0) { aip->ai_batt_stat = APM_UNKNOWN; aip->ai_batt_life = APM_UNKNOWN; @@ -176,7 +175,6 @@ acpi_capm_get_info(apm_info_t aip) aip->ai_batt_time = (batt.min == -1) ? -1 : batt.min * 60; aip->ai_batteries = acpi_battery_get_units(); } - newbus_sunlock(); return (0); } @@ -192,7 +190,6 @@ acpi_capm_get_pwstatus(apm_pwstatus_t app) (app->ap_device < PMDV_BATT0 || app->ap_device > PMDV_BATT_ALL)) return (1); - newbus_slock(); if (app->ap_device == PMDV_ALLDEV) error = acpi_battery_get_battinfo(NULL, &batt); else { @@ -203,7 +200,6 @@ acpi_capm_get_pwstatus(apm_pwstatus_t app) else error = ENXIO; } - newbus_sunlock(); if (error) return (1); @@ -287,9 +283,7 @@ apmopen(struct cdev *dev, int flag, int fmt, struct thread *td) struct acpi_softc *acpi_sc; struct apm_clone_data *clone; - newbus_slock(); acpi_sc = devclass_get_softc(devclass_find("acpi"), 0); - newbus_sunlock(); clone = apm_create_clone(dev, acpi_sc); dev->si_drv1 = clone; diff --git a/sys/i386/bios/smapi.c b/sys/i386/bios/smapi.c index 74cf612182a..e572664e2ac 100644 --- a/sys/i386/bios/smapi.c +++ b/sys/i386/bios/smapi.c @@ -288,12 +288,10 @@ smapi_modevent (module_t mod, int what, void *arg) case MOD_LOAD: break; case MOD_UNLOAD: - newbus_xlock(); devclass_get_devices(smapi_devclass, &devs, &count); for (i = 0; i < count; i++) { device_delete_child(device_get_parent(devs[i]), devs[i]); } - newbus_xunlock(); break; default: break; diff --git a/sys/i386/bios/smbios.c b/sys/i386/bios/smbios.c index 37a3b2cd092..f38d9857399 100644 --- a/sys/i386/bios/smbios.c +++ b/sys/i386/bios/smbios.c @@ -230,12 +230,10 @@ smbios_modevent (mod, what, arg) case MOD_LOAD: break; case MOD_UNLOAD: - newbus_xlock(); devclass_get_devices(smbios_devclass, &devs, &count); for (i = 0; i < count; i++) { device_delete_child(device_get_parent(devs[i]), devs[i]); } - newbus_xunlock(); break; default: break; diff --git a/sys/i386/bios/vpd.c b/sys/i386/bios/vpd.c index f816121260f..246b76d3570 100644 --- a/sys/i386/bios/vpd.c +++ b/sys/i386/bios/vpd.c @@ -248,12 +248,10 @@ vpd_modevent (mod, what, arg) case MOD_LOAD: break; case MOD_UNLOAD: - newbus_xlock(); devclass_get_devices(vpd_devclass, &devs, &count); for (i = 0; i < count; i++) { device_delete_child(device_get_parent(devs[i]), devs[i]); } - newbus_xunlock(); break; default: break; diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 52cd766296c..2964b8c1a22 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -192,54 +191,6 @@ void print_devclass_list(void); #define print_devclass_list() /* nop */ #endif -/* - * Newbus locking facilities. - */ -static struct sx newbus_lock; - -#define NBL_LOCK_INIT() sx_init(&newbus_lock, "newbus") -#define NBL_LOCK_DESTROY() sx_destroy(&newbus_lock) -#define NBL_XLOCK() sx_xlock(&newbus_lock) -#define NBL_SLOCK() sx_slock(&newbus_lock) -#define NBL_XUNLOCK() sx_xunlock(&newbus_lock) -#define NBL_SUNLOCK() sx_sunlock(&newbus_lock) -#ifdef INVARIANTS -#define NBL_ASSERT(what) do { \ - if (cold == 0) \ - sx_assert(&newbus_lock, (what)); \ -} while (0) -#else -#define NBL_ASSERT(what) -#endif - -void -newbus_xlock() -{ - - NBL_XLOCK(); -} - -void -newbus_slock() -{ - - NBL_SLOCK(); -} - -void -newbus_xunlock() -{ - - NBL_XUNLOCK(); -} - -void -newbus_sunlock() -{ - - NBL_SUNLOCK(); -} - /* * dev sysctl tree */ @@ -413,6 +364,7 @@ static d_poll_t devpoll; static struct cdevsw dev_cdevsw = { .d_version = D_VERSION, + .d_flags = D_NEEDGIANT, .d_open = devopen, .d_close = devclose, .d_read = devread, @@ -1109,7 +1061,6 @@ devclass_delete_driver(devclass_t busclass, driver_t *driver) int i; int error; - NBL_ASSERT(SA_XLOCKED); PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass))); if (!dc) @@ -1808,7 +1759,6 @@ device_delete_child(device_t dev, device_t child) int error; device_t grandchild; - NBL_ASSERT(SA_XLOCKED); PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev))); /* remove children first */ @@ -1907,7 +1857,7 @@ device_probe_child(device_t dev, device_t child) int result, pri = 0; int hasclass = (child->devclass != NULL); - NBL_ASSERT(SA_XLOCKED); + GIANT_REQUIRED; dc = dev->devclass; if (!dc) @@ -2558,7 +2508,7 @@ device_probe(device_t dev) { int error; - NBL_ASSERT(SA_XLOCKED); + GIANT_REQUIRED; if (dev->state >= DS_ALIVE && (dev->flags & DF_REBID) == 0) return (-1); @@ -2592,7 +2542,7 @@ device_probe_and_attach(device_t dev) { int error; - NBL_ASSERT(SA_XLOCKED); + GIANT_REQUIRED; error = device_probe(dev); if (error == -1) @@ -2626,8 +2576,6 @@ device_attach(device_t dev) { int error; - NBL_ASSERT(SA_XLOCKED); - device_sysctl_init(dev); if (!device_is_quiet(dev)) device_print_child(dev->parent, dev); @@ -2669,7 +2617,7 @@ device_detach(device_t dev) { int error; - NBL_ASSERT(SA_XLOCKED); + GIANT_REQUIRED; PDEBUG(("%s", DEVICENAME(dev))); if (dev->state == DS_BUSY) @@ -2713,8 +2661,6 @@ int device_quiesce(device_t dev) { - NBL_ASSERT(SA_XLOCKED); - PDEBUG(("%s", DEVICENAME(dev))); if (dev->state == DS_BUSY) return (EBUSY); @@ -2735,7 +2681,6 @@ device_quiesce(device_t dev) int device_shutdown(device_t dev) { - if (dev->state < DS_ATTACHED) return (0); return (DEVICE_SHUTDOWN(dev)); @@ -3151,8 +3096,6 @@ bus_generic_attach(device_t dev) { device_t child; - NBL_ASSERT(SA_XLOCKED); - TAILQ_FOREACH(child, &dev->children, link) { device_probe_and_attach(child); } @@ -3173,8 +3116,6 @@ bus_generic_detach(device_t dev) device_t child; int error; - NBL_ASSERT(SA_XLOCKED); - if (dev->state != DS_ATTACHED) return (EBUSY); @@ -4055,7 +3996,6 @@ root_bus_module_handler(module_t mod, int what, void* arg) switch (what) { case MOD_LOAD: TAILQ_INIT(&bus_data_devices); - NBL_LOCK_INIT(); kobj_class_compile((kobj_class_t) &root_driver); root_bus = make_device(NULL, "root", 0); root_bus->desc = "System root bus"; @@ -4115,28 +4055,14 @@ driver_module_handler(module_t mod, int what, void *arg) kobj_class_t driver; int error, pass; - error = 0; dmd = (struct driver_module_data *)arg; - - /* - * If MOD_SHUTDOWN is passed, return immediately in order to - * avoid unnecessary locking and a LOR with the modules sx lock. - */ - if (what == MOD_SHUTDOWN) - return (EOPNOTSUPP); - NBL_XLOCK(); bus_devclass = devclass_find_internal(dmd->dmd_busname, NULL, TRUE); - if (bus_devclass == NULL) { - NBL_XUNLOCK(); - return (ENOMEM); - } + error = 0; switch (what) { case MOD_LOAD: if (dmd->dmd_chainevh) error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg); - if (error != 0) - break; pass = dmd->dmd_pass; driver = dmd->dmd_driver; @@ -4189,7 +4115,6 @@ driver_module_handler(module_t mod, int what, void *arg) error = EOPNOTSUPP; break; } - NBL_XUNLOCK(); return (error); } diff --git a/sys/pc98/cbus/fdc.c b/sys/pc98/cbus/fdc.c index 294711787a9..8373f45163c 100644 --- a/sys/pc98/cbus/fdc.c +++ b/sys/pc98/cbus/fdc.c @@ -1499,9 +1499,7 @@ fdstrategy(struct bio *bp) bioq_disksort(&fdc->head, bp); untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */ devstat_start_transaction_bio(fd->device_stats, bp); - newbus_xlock(); device_busy(fd->dev); - newbus_xunlock(); fdstart(fdc); splx(s); return; @@ -2180,9 +2178,7 @@ fdstate(fdc_p fdc) fd->skip = 0; bp->bio_resid = 0; fdc->bp = NULL; - newbus_xlock(); device_unbusy(fd->dev); - newbus_xunlock(); biofinish(bp, fd->device_stats, 0); fdc->fd = (fd_p) 0; fdc->fdu = -1; @@ -2343,9 +2339,7 @@ retrier(struct fdc_data *fdc) bp->bio_resid = 0; fdc->bp = NULL; fdc->fd->skip = 0; - newbus_xlock(); device_unbusy(fd->dev); - newbus_xunlock(); biofinish(bp, fdc->fd->device_stats, 0); fdc->state = FINDWORK; fdc->flags |= FDC_NEEDS_RESET; diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 7ed06f4fed9..2362041dad2 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -478,14 +478,6 @@ int resource_set_string(const char *name, int unit, const char *resname, int bus_data_generation_check(int generation); void bus_data_generation_update(void); -/* - * Exported locking facilities. - */ -void newbus_xlock(void); -void newbus_slock(void); -void newbus_xunlock(void); -void newbus_sunlock(void); - /** * Some convenience defines for probe routines to return. These are just * suggested values, and there's nothing magical about them. diff --git a/sys/xen/xenbus/xenbus_probe.c b/sys/xen/xenbus/xenbus_probe.c index f930c8ff71b..f04f8eca463 100644 --- a/sys/xen/xenbus/xenbus_probe.c +++ b/sys/xen/xenbus/xenbus_probe.c @@ -348,9 +348,7 @@ xenbus_devices_changed(struct xenbus_watch *watch, if (p) *p = 0; - newbus_xlock(); xenbus_add_device(dev, bus, type, id); - newbus_xunlock(); taskqueue_enqueue(taskqueue_thread, &sc->xs_probechildren); out: free(node, M_DEVBUF); @@ -363,9 +361,7 @@ xenbus_attach_deferred(void *arg) struct xenbus_softc *sc = device_get_softc(dev); int error; - newbus_xlock(); error = xenbus_enumerate_bus(dev, "device"); - newbus_xunlock(); if (error) return; xenbus_probe_children(dev); From 5c91164df2109db08b208ac11ad6b2622fe814b3 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 20 Aug 2009 20:53:36 +0000 Subject: [PATCH 0113/2592] MFC 196404: Change the 'resid' parameter to sglist_consume_uio() from an int to a size_t to match the recent type change of the uio_resid member of struct uio. Approved by: re (kib) --- share/man/man9/sglist.9 | 2 +- sys/kern/subr_sglist.c | 2 +- sys/sys/sglist.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/share/man/man9/sglist.9 b/share/man/man9/sglist.9 index 8c1c046ad76..a265498148f 100644 --- a/share/man/man9/sglist.9 +++ b/share/man/man9/sglist.9 @@ -70,7 +70,7 @@ .Ft struct sglist * .Fn sglist_clone "struct sglist *sg" "int mflags" .Ft int -.Fn sglist_consume_uio "struct sglist *sg" "struct uio *uio" "int resid" +.Fn sglist_consume_uio "struct sglist *sg" "struct uio *uio" "size_t resid" .Ft int .Fn sglist_count "void *buf" "size_t len" .Ft void diff --git a/sys/kern/subr_sglist.c b/sys/kern/subr_sglist.c index 7f551d99cd8..474f6767294 100644 --- a/sys/kern/subr_sglist.c +++ b/sys/kern/subr_sglist.c @@ -315,7 +315,7 @@ sglist_append_uio(struct sglist *sg, struct uio *uio) * segments, then only the amount that fits is appended. */ int -sglist_consume_uio(struct sglist *sg, struct uio *uio, int resid) +sglist_consume_uio(struct sglist *sg, struct uio *uio, size_t resid) { struct iovec *iov; size_t done; diff --git a/sys/sys/sglist.h b/sys/sys/sglist.h index a1854d885ca..7c17baa8d7e 100644 --- a/sys/sys/sglist.h +++ b/sys/sys/sglist.h @@ -91,7 +91,7 @@ int sglist_append_user(struct sglist *sg, void *buf, size_t len, struct thread *td); struct sglist *sglist_build(void *buf, size_t len, int mflags); struct sglist *sglist_clone(struct sglist *sg, int mflags); -int sglist_consume_uio(struct sglist *sg, struct uio *uio, int resid); +int sglist_consume_uio(struct sglist *sg, struct uio *uio, size_t resid); int sglist_count(void *buf, size_t len); void sglist_free(struct sglist *sg); int sglist_join(struct sglist *first, struct sglist *second); From aeba9e80ffe612b5474745037f3f48b1854be8ee Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 20 Aug 2009 21:14:52 +0000 Subject: [PATCH 0114/2592] Merge r196263 from head to stable/8: Remove unused if_rawoutput() macro; it has been unused since at least FreeBSD 2. Approved by: re (kib) --- sys/net/if_var.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 428645fa206..aa83161cce3 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -235,7 +235,6 @@ typedef void if_init_f_t(void *); #define if_iqdrops if_data.ifi_iqdrops #define if_noproto if_data.ifi_noproto #define if_lastchange if_data.ifi_lastchange -#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL) /* for compatibility with other BSDs */ #define if_addrlist if_addrhead From 708b471c4bce599a2fb21d07d9accd46e731f516 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 20 Aug 2009 21:29:49 +0000 Subject: [PATCH 0115/2592] Merge r196267 from head to stable/8: Rather than fix questionable ifnet list locking in the implementation of the kern.polling.enable sysctl, remove the sysctl. It has been deprecated since FreeBSD 6 in favour of per-ifnet polling flags. Reviewed by: luigi Approved by: re (kib) --- share/man/man4/polling.4 | 19 ++++++++-------- sys/kern/kern_poll.c | 49 ---------------------------------------- 2 files changed, 10 insertions(+), 58 deletions(-) diff --git a/share/man/man4/polling.4 b/share/man/man4/polling.4 index fea0bfb7988..2c711cc7d8d 100644 --- a/share/man/man4/polling.4 +++ b/share/man/man4/polling.4 @@ -87,6 +87,16 @@ feature. It is turned on and off with help of .Xr ifconfig 8 command. +.Pp +The historic +.Va kern.polling.enable , +which enabled polling for all interfaces, can be replaced with the following +code: +.Bd -literal +for i in `ifconfig -l` ; + do ifconfig $i polling; # use -polling to disable +done +.Ed .Ss MIB Variables The operation of .Nm @@ -156,15 +166,6 @@ Default is 20. How many active devices have registered for .Nm . .Pp -.It Va kern.polling.enable -Legacy MIB, that was used to enable or disable polling globally. -Currently if set to 1, -.Nm -is enabled on all capable interfaces. -If set to 0, -.Nm -is disabled on all interfaces. -.Pp .It Va kern.polling.short_ticks .It Va kern.polling.lost_polls .It Va kern.polling.pending_polls diff --git a/sys/kern/kern_poll.c b/sys/kern/kern_poll.c index 5df26bbf089..8441126d1da 100644 --- a/sys/kern/kern_poll.c +++ b/sys/kern/kern_poll.c @@ -46,8 +46,6 @@ __FBSDID("$FreeBSD$"); #include /* for NETISR_POLL */ #include -static int poll_switch(SYSCTL_HANDLER_ARGS); - void hardclock_device_poll(void); /* hook from hardclock */ static struct mtx poll_mtx; @@ -230,10 +228,6 @@ static uint32_t poll_handlers; /* next free entry in pr[]. */ SYSCTL_UINT(_kern_polling, OID_AUTO, handlers, CTLFLAG_RD, &poll_handlers, 0, "Number of registered poll handlers"); -static int polling = 0; -SYSCTL_PROC(_kern_polling, OID_AUTO, enable, CTLTYPE_UINT | CTLFLAG_RW, - 0, sizeof(int), poll_switch, "I", "Switch polling for all interfaces"); - static uint32_t phase; SYSCTL_UINT(_kern_polling, OID_AUTO, phase, CTLFLAG_RD, &phase, 0, "Polling phase"); @@ -538,49 +532,6 @@ ether_poll_deregister(struct ifnet *ifp) return (0); } -/* - * Legacy interface for turning polling on all interfaces at one time. - */ -static int -poll_switch(SYSCTL_HANDLER_ARGS) -{ - struct ifnet *ifp; - int error; - int val = polling; - - error = sysctl_handle_int(oidp, &val, 0, req); - if (error || !req->newptr ) - return (error); - - if (val == polling) - return (0); - - if (val < 0 || val > 1) - return (EINVAL); - - polling = val; - - IFNET_RLOCK(); - TAILQ_FOREACH(ifp, &V_ifnet, if_link) { - if (ifp->if_capabilities & IFCAP_POLLING) { - struct ifreq ifr; - - if (val == 1) - ifr.ifr_reqcap = - ifp->if_capenable | IFCAP_POLLING; - else - ifr.ifr_reqcap = - ifp->if_capenable & ~IFCAP_POLLING; - (void) (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr); - } - } - IFNET_RUNLOCK(); - - log(LOG_ERR, "kern.polling.enable is deprecated. Use ifconfig(8)"); - - return (0); -} - static void poll_idle(void) { From c9482dbb721a3ee9519d3f940458ed7dfa7fdee1 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Thu, 20 Aug 2009 22:56:29 +0000 Subject: [PATCH 0116/2592] MFC r196409: vimage(8) is a legacy CLI interface for managing jails associated with network stack instances, which is provided for compatibility with older applications. This change brings it back to life in a followup to the initial conversion of vimage to use the new jail(4) userland-kernel API: - when creating vimages via "vimage -c", by default turn on a few options expected by legacy applications, such as allow operations on raw sockets, FS mounts etc, and allow jail-related parameters to be optionally configured. - introduce the "-m" modifier which allows for configuring jail parameters of existing vimages / vnet-jails. - make "vimage name command ..." actually work. - when reassigning ifnets to vnets using "vimage -i", attempt to rename the ifnet as "ethXXX" on arrival in the target vnet. Several legacy applications are known to depend heavily on such behavior. - vimage -l lists only jails associated with vnets. The output is sorted using vimage / jail names as keys. - vimage -l by default searches only the current level in the jail hierarchy. Recursive listing can be requested via -r switch. - vimage -l by default prints only jail names on each line, making such output suitable for pipelining to other commands. More verbose output can be obtained via -v switch, and even more jail specific information will be displayed if -j switch is turned on. - there's no need to build vimage as statically linked, so update the Makefile accordingly. - update the vimage.8 man page. Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- tools/tools/vimage/Makefile | 1 - tools/tools/vimage/vimage.8 | 155 +++++++------ tools/tools/vimage/vimage.c | 420 ++++++++++++++++++++++++++---------- 3 files changed, 400 insertions(+), 176 deletions(-) diff --git a/tools/tools/vimage/Makefile b/tools/tools/vimage/Makefile index 82f4f473845..76c76179f76 100644 --- a/tools/tools/vimage/Makefile +++ b/tools/tools/vimage/Makefile @@ -10,6 +10,5 @@ CFLAGS+= -I../../../sys MAN= vimage.8 BINDIR?= /usr/sbin -NO_SHARED?= YES .include diff --git a/tools/tools/vimage/vimage.8 b/tools/tools/vimage/vimage.8 index f012af8d698..517a788cda3 100644 --- a/tools/tools/vimage/vimage.8 +++ b/tools/tools/vimage/vimage.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2002, 2003 Marko Zec +.\" Copyright (c) 2002, 2003 Marko Zec .\" Copyright (c) 2009 University of Zagreb .\" Copyright (c) 2009 FreeBSD Foundation .\" @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 6, 2009 +.Dd August 25, 2009 .Dt VIMAGE 8 .Os .Sh NAME @@ -35,35 +35,46 @@ .Nd manage virtual network stacks .Sh SYNOPSIS .Nm -.Ar vi_name -.Op command -.Nm -.Fl c -.Ar vi_name +.Op Fl c | m +.Ar vname +.Op Ar param=value ... .Nm .Fl d -.Ar vi_name +.Ar vname .Nm .Fl l -.Op Ar vi_name +.Op Fl rvj +.Op Ar vname .Nm .Fl i -.Ar vi_name interface -.Sh DESCRIPTION +.Ar vname ifname +.Op Ar newifname .Nm -command is an interm user interface for controlling the virtual network -stacks in FreeBSD. +.Ar vi_name +.Op command ... +.Sh DESCRIPTION +The +.Nm +utility is an alternative user interface for controlling virtual network +stacks in FreeBSD, aimed primarily at supporting legacy applications +which are not yet converted to using +.Xr jail 8 , +.Xr jexec 8 , +and +.Xr jls 8 . +. .Ss Overview -A virtual image reprepresents an isolated operating environment with its -own independent network stack instance. Every process, socket and network -interface present in the system is always attached to one, and only one, -virtual image i.e. virtual network stack instance. -During the system bootup sequence default virtual image is created to -which all the configured interfaces and user processes are initially -assigned. -Assuming that enough system resources and per virtual image privileges -are provided, the super-user can create and manage a hierarchy of -subordinated virtual images. The +A virtual image or vimage is a jail with its own independent network +stack instance. Every process, socket and network interface present +in the system is always attached to one, and only one, virtual network +stack instance (vnet). +During system bootup sequence a default vnet +is created to which all the configured interfaces and user processes +are initially attached. +Assuming that enough system resources are +are available, a user with sufficient privileges can create and manage +a hierarchy of subordinated virtual images. +The .Nm command allows for creation, deletion and monitoring of virtual images, as well as for execution of arbitrary processes in a targeted virtual @@ -71,59 +82,72 @@ image. .Ss Invocation If invoked with no modifiers, the .Nm -command spawns a new shell process in virtual image -.Ar vi_name . -If provided, the optional arguments following the virtual image name -.Ar vi_name -are interpreted as a standard command line issued at a shell, -otherwise an interactive shell is started in the target virtual image. +command spawns a new interactive shell in virtual image +.Ar vname . +If optional additional arguments following +.Ar vname +are provided, the first of those will be executed in place of the +interactive shell, and the rest of the arguments will be passed as +arguments to the executed command. .Pp -The following parameters are available: +The following modifiers are available: .Bl -tag -width indent .It Fl c Create a new virtual image named -.So -.Ar vi_name -.Sc . +.Ar vname . +Additional arguments, if provided, may be used to specify operating +parameters different from defaults, in format +.Ar param=value . +See +.Xr jail 8 +for an extensive list of available parameters. +.It Fl m +Modify the parameters of a virtual image named +.Ar vname , +using the same syntax as with the -c form of the command. .It Fl d Delete the virtual image -.Ar vi_name . +.Ar vname . No processes and/or sockets should exist in the target virtual image -in order for the delete request to succeed. Non-loopback interfaces +in order for the delete request to succeed. Non-loopback interfaces residing in the target virtual image will be reassigned to the virtual image's parent. .It Fl l List the properties and statistics for virtual images one level below the current one in the hierarchy. If an optional argument -.Ar vi_name +.Ar vname is provided, only the information regarding the target virtual image -.Ar vi_name +.Ar vname is displayed. -.It Fl lr -List the properties and statistics for all virtual images in -the hierarchy of subordinated vimages. If an optional argument -.Ar vi_name -is provided, the hierarchy will be traversed at and below the -.Ar vi_name -level. +With the optional +.Op Ar -r +switch enabled the list will include all virtual images below the +current level in the vimage hierarchy. +Enabling the optional +.Op Ar -v +or +.Op Ar -j +switches results in a more detailed output. .It Fl i -Move the interface -.Ar interface +Move interface +.Ar ifname to the target virtual image -.Ar vi_name . -If the value of -.Ar vi_name -argument is -.So .. +.Ar vname . +Interfaces will be automatically renamed to +.So +ethXX .Sc , -the interface is returned to the parent of the current virtual image. +unless an optional argument specifying the desired interface name +.Op Ar newifname +is provided. .El .Sh EXAMPLES Create a new virtual image named .So v1 -.Sc : +.Sc , +which is allowed to create and manage an own subhierarchy of vimages: .Pp -.Dl vimage -c v1 +.Dl vimage -c v1 children.max=100 .Pp Execute the .So ifconfig @@ -137,28 +161,35 @@ Move the interface .So vlan0 .Sc to the virtual image .So v1 +.Sc while renaming the interface as +.So +ve0 .Sc : .Pp -.Dl vimage -i v1 vlan0 +.Dl vimage -i v1 vlan0 ve0 .Pp Show the status information for virtual image .So v1 .Sc : .Pp -.Dl vimage -l v1 +.Dl vimage -lv v1 .Sh DIAGNOSTICS The .Nm command exits 0 on success, and >0 if an error occurs. .Sh SEE ALSO .Xr jail 8 +.Xr jexec 8 +.Xr jls 8 .Sh BUGS -If memory allocation failure occurs during the vimage creation, it will remain -undetected/ignored in the current implementation, thus latently scheduling -an almost imminent system crash in the future. +Deletion of vimages / vnets is known to leak kernel memory and fail at +stopping various timers, hence may lead to system crashes. .Sh AUTHOR .An "Marko Zec" Aq zec@fer.hr .Sh HISTORY -The -.Nm -facility first appeared as a patch against FreeBSD 4.7-RELEASE in 2002. +Network stack virtualization framework first appeared as a patchset +against the FreeBSD 4.7 kernel in 2002, and was maintained outside +of the main FreeBSD tree. +As a result of a project sponsored by the FreeBSD Foundation and +Stiching NLNet, integrated virtualized network stack first appeared +in FreeBSD 8.0. diff --git a/tools/tools/vimage/vimage.c b/tools/tools/vimage/vimage.c index e4ab584c4a9..b54f9d6224c 100644 --- a/tools/tools/vimage/vimage.c +++ b/tools/tools/vimage/vimage.c @@ -28,142 +28,294 @@ */ #include -#include #include #include #include #include -#include +#include #include #include #include #include #include -#define VI_CREATE 0x00000001 -#define VI_DESTROY 0x00000002 -#define VI_SWITCHTO 0x00000008 -#define VI_IFACE 0x00000010 -#define VI_GET 0x00000100 -#define VI_GETNEXT 0x00000200 +typedef enum { + VI_SWITCHTO, + VI_CREATE, + VI_MODIFY, + VI_DESTROY, + VI_IFMOVE, + VI_GET +} vi_cmd_t; -static int getjail(char *name, int lastjid, int *vnet); +typedef struct vimage_status { + char name[MAXPATHLEN]; /* Must be first field for strcmp(). */ + char path[MAXPATHLEN]; + char hostname[MAXPATHLEN]; + char domainname[MAXPATHLEN]; + int jid; + int parentjid; + int vnet; + int childcnt; + int childmax; + int cpuset; + int rawsock; + int socket_af; + int mount; +} vstat_t; + +#define VST_SIZE_STEP 1024 +#define MAXPARAMS 32 + +static int getjail(vstat_t *, int, int); + +static char *invocname; + +static void +usage(void) +{ + + fprintf(stderr, + "usage: %s [-c | -m] vname [param=value ...]\n" + " %s -d vname\n" + " %s -l[rvj] [vname]\n" + " %s -i vname ifname [newifname]\n" + " %s vname [command ...]\n", + invocname, invocname, invocname, invocname, invocname); + exit(1); +} int main(int argc, char **argv) { - int s; - char *shell; - int cmd; - int jid, vnet; + struct jailparam params[MAXPARAMS]; + char ifname[IFNAMSIZ]; struct ifreq ifreq; - char name[MAXHOSTNAMELEN]; + vi_cmd_t newcmd, cmd; + int recurse = 0; + int verbose = 0; + int jid, i, s, namelen; + int vst_size, vst_last; + vstat_t *vst; + char *str; + char ch; - switch (argc) { + invocname = argv[0]; - case 1: - cmd = 0; - break; - - case 2: - if (strcmp(argv[1], "-l") == 0) - cmd = VI_GETNEXT; - else if (strcmp(argv[1], "-lr") == 0) - cmd = VI_GETNEXT; - else { - strcpy(name, argv[1]); - cmd = VI_SWITCHTO; + newcmd = cmd = VI_SWITCHTO; /* Default if no modifiers specified. */ + while ((ch = getopt(argc, argv, "cdijlmrv")) != -1) { + switch (ch) { + case 'c': + newcmd = VI_CREATE; + break; + case 'm': + newcmd = VI_MODIFY; + break; + case 'd': + newcmd = VI_DESTROY; + break; + case 'l': + newcmd = VI_GET; + break; + case 'i': + newcmd = VI_IFMOVE; + break; + case 'r': + recurse = 1; + break; + case 'v': + verbose++; + break; + case 'j': + verbose = 2; + break; + default: + usage(); } - break; - - case 3: - strcpy(name, argv[2]); - if (strcmp(argv[1], "-l") == 0) - cmd = VI_GET; - if (strcmp(argv[1], "-c") == 0) - cmd = VI_CREATE; - if (strcmp(argv[1], "-d") == 0) - cmd = VI_DESTROY; - break; - - default: - strcpy(name, argv[2]); - if (strcmp(argv[1], "-c") == 0) - cmd = VI_CREATE; - if (strcmp(argv[1], "-i") == 0) - cmd = VI_IFACE; + if (cmd == VI_SWITCHTO || cmd == newcmd) + cmd = newcmd; + else + usage(); } + argc -= optind; + argv += optind; + + if ((cmd != VI_GET && (argc == 0 || recurse != 0 || verbose != 0)) || + (cmd == VI_IFMOVE && (argc < 2 || argc > 3)) || + (cmd == VI_MODIFY && argc < 2) || argc >= MAXPARAMS) + usage(); switch (cmd) { - case VI_GET: - jid = getjail(name, -1, &vnet); - if (jid < 0) - goto abort; - printf("%d: %s%s\n", jid, name, vnet ? "" : " (no vnet)"); - exit(0); - - case VI_GETNEXT: + vst_last = 0; + vst_size = VST_SIZE_STEP; + if ((vst = malloc(vst_size * sizeof(*vst))) == NULL) + break; + if (argc == 1) + namelen = strlen(argv[0]); + else + namelen = 0; jid = 0; - while ((jid = getjail(name, jid, &vnet)) > 0) - printf("%d: %s%s\n", jid, name, - vnet ? "" : " (no vnet)"); + while ((jid = getjail(&vst[vst_last], jid, verbose)) > 0) { + /* Skip jails which do not own vnets. */ + if (vst[vst_last].vnet != 1) + continue; + /* Skip non-matching vnames / hierarchies. */ + if (namelen && + ((strlen(vst[vst_last].name) < namelen || + strncmp(vst[vst_last].name, argv[0], namelen) != 0) + || (strlen(vst[vst_last].name) > namelen && + vst[vst_last].name[namelen] != '.'))) + continue; + /* Skip any sub-trees if -r not requested. */ + if (!recurse && + (strlen(vst[vst_last].name) < namelen || + strchr(&vst[vst_last].name[namelen], '.') != NULL)) + continue; + /* Grow vst table if necessary. */ + if (++vst_last == vst_size) { + vst_size += VST_SIZE_STEP; + vst = realloc(vst, vst_size * sizeof(*vst)); + if (vst == NULL) + break; + } + } + if (vst == NULL) + break; + /* Sort: the key is the 1st field in *vst, i.e. vimage name. */ + qsort(vst, vst_last, sizeof(*vst), (void *) strcmp); + for (i = 0; i < vst_last; i++) { + if (!verbose) { + printf("%s\n", vst[i].name); + continue; + } + + printf("%s:\n", vst[i].name); + printf(" Path: %s\n", vst[i].path); + printf(" Hostname: %s\n", vst[i].hostname); + printf(" Domainname: %s\n", vst[i].domainname); + printf(" Children: %d\n", vst[i].childcnt); + + if (verbose < 2) + continue; + + printf(" Children limit: %d\n", vst[i].childmax); + printf(" CPUsetID: %d\n", vst[i].cpuset); + printf(" JID: %d\n", vst[i].jid); + printf(" PJID: %d\n", vst[i].parentjid); + printf(" Raw sockets allowed: %d\n", vst[i].rawsock); + printf(" All AF allowed: %d\n", vst[i].socket_af); + printf(" Mount allowed: %d\n", vst[i].mount); + } + free(vst); exit(0); - case VI_IFACE: - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s == -1) - goto abort; - jid = jail_getid(name); - if (jid < 0) - goto abort; + case VI_IFMOVE: + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + break; + if ((jid = jail_getid(argv[0])) < 0) + break; ifreq.ifr_jid = jid; - strncpy(ifreq.ifr_name, argv[3], sizeof(ifreq.ifr_name)); + strncpy(ifreq.ifr_name, argv[1], sizeof(ifreq.ifr_name)); if (ioctl(s, SIOCSIFVNET, (caddr_t)&ifreq) < 0) - goto abort; - printf("%s@%s\n", ifreq.ifr_name, name); + break; + close(s); + if (argc == 3) + snprintf(ifname, sizeof(ifname), "%s", argv[2]); + else + snprintf(ifname, sizeof(ifname), "eth0"); + ifreq.ifr_data = ifname; + /* Do we need to rename the ifnet? */ + if (strcmp(ifreq.ifr_name, ifname) != 0) { + /* Switch to the context of the target vimage. */ + if (jail_attach(jid) < 0) + break; + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + break; + for (namelen = 0; isalpha(ifname[namelen]); namelen++); + i = 0; + /* Search for a free ifunit in target vnet. Unsafe. */ + while (ioctl(s, SIOCSIFNAME, (caddr_t)&ifreq) < 0) { + snprintf(&ifname[namelen], + sizeof(ifname) - namelen, "%d", i); + /* Emergency brake. */ + if (i++ == IF_MAXUNIT) + break; + } + } + if (i < IF_MAXUNIT) + printf("%s@%s\n", ifname, argv[0]); + else + printf("%s@%s\n", ifreq.ifr_name, argv[0]); exit(0); case VI_CREATE: - if (jail_setv(JAIL_CREATE, "name", name, "vnet", NULL, - "host", NULL, "persist", NULL, NULL) < 0) - goto abort; + if ((jid = jail_setv(JAIL_CREATE, + "name", argv[0], + "vnet", NULL, + "host", NULL, + "persist", NULL, + "allow.raw_sockets", "true", + "allow.socket_af", "true", + "allow.mount", "true", + NULL)) >= 0) + break; + if (jid < 0) + break; + if (argc == 1) + exit(0); + /* Not done yet, proceed to apply non-default parameters. */ + + case VI_MODIFY: + jailparam_init(¶ms[0], "name"); + jailparam_import(¶ms[0], argv[0]); + for (i = 1; i < argc; i++) { + for (str = argv[i]; *str != '=' && *str != 0; str++) { + /* Do nothing - search for '=' delimeter. */ + } + if (*str == 0) + break; + *str++ = 0; + if (*str == 0) + break; + jailparam_init(¶ms[i], argv[i]); + jailparam_import(¶ms[i], str); + } + if (i != argc) + break; + if (jailparam_set(params, i, JAIL_UPDATE) < 0) + break; + exit(0); + + case VI_DESTROY: + if ((jid = jail_getid(argv[0])) < 0) + break; + if (jail_remove(jid) < 0) + break; exit(0); case VI_SWITCHTO: - jid = jail_getid(name); - if (jid < 0) - goto abort; + if ((jid = jail_getid(argv[0])) < 0) + break; if (jail_attach(jid) < 0) - goto abort; - - if (argc == 2) { - printf("Switched to jail %s\n", argv[1]); - if ((shell = getenv("SHELL")) == NULL) - execlp("/bin/sh", argv[0], NULL); + break; + if (argc == 1) { + printf("Switched to vimage %s\n", argv[0]); + if ((str = getenv("SHELL")) == NULL) + execlp("/bin/sh", invocname, NULL); else - execlp(shell, argv[0], NULL); + execlp(str, invocname, NULL); } else - execvp(argv[2], &argv[2]); + execvp(argv[1], &argv[1]); break; - case VI_DESTROY: - jid = jail_getid(name); - if (jid < 0) - goto abort; - if (jail_remove(jid) < 0) - goto abort; - exit(0); - default: - fprintf(stderr, "usage: %s [-cdilr] vi_name [args]\n", - argv[0]); - exit(1); + /* Should be unreachable. */ + break; } -abort: if (jail_errmsg[0]) fprintf(stderr, "Error: %s\n", jail_errmsg); else @@ -172,27 +324,69 @@ abort: } static int -getjail(char *name, int lastjid, int *vnet) +getjail(vstat_t *vs, int lastjid, int verbose) { - struct jailparam params[3]; - int jid; + struct jailparam params[32]; /* Must be > max(psize). */ + int psize = 0; - if (lastjid < 0) { - jid = jail_getid(name); - if (jid < 0) - return (jid); - jailparam_init(¶ms[0], "jid"); - jailparam_import_raw(¶ms[0], &jid, sizeof jid); - } else { - jailparam_init(¶ms[0], "lastjid"); - jailparam_import_raw(¶ms[0], &lastjid, sizeof lastjid); - } - jailparam_init(¶ms[1], "name"); - jailparam_import_raw(¶ms[1], name, MAXHOSTNAMELEN); - name[0] = 0; - jailparam_init(¶ms[2], "vnet"); - jailparam_import_raw(¶ms[2], vnet, sizeof(*vnet)); - jid = jailparam_get(params, 3, 0); - jailparam_free(params, 3); - return (jid); + bzero(params, sizeof(params)); + bzero(vs, sizeof(*vs)); + + jailparam_init(¶ms[psize], "lastjid"); + jailparam_import_raw(¶ms[psize++], &lastjid, sizeof lastjid); + + jailparam_init(¶ms[psize], "vnet"); + jailparam_import_raw(¶ms[psize++], &vs->vnet, sizeof(vs->vnet)); + + jailparam_init(¶ms[psize], "name"); + jailparam_import_raw(¶ms[psize++], &vs->name, sizeof(vs->name)); + + if (verbose == 0) + goto done; + + jailparam_init(¶ms[psize], "path"); + jailparam_import_raw(¶ms[psize++], &vs->path, sizeof(vs->path)); + + jailparam_init(¶ms[psize], "host.hostname"); + jailparam_import_raw(¶ms[psize++], &vs->hostname, + sizeof(vs->hostname)); + + jailparam_init(¶ms[psize], "host.domainname"); + jailparam_import_raw(¶ms[psize++], &vs->domainname, + sizeof(vs->domainname)); + + jailparam_init(¶ms[psize], "children.cur"); + jailparam_import_raw(¶ms[psize++], &vs->childcnt, + sizeof(vs->childcnt)); + + if (verbose == 1) + goto done; + + jailparam_init(¶ms[psize], "children.max"); + jailparam_import_raw(¶ms[psize++], &vs->childmax, + sizeof(vs->childmax)); + + jailparam_init(¶ms[psize], "cpuset.id"); + jailparam_import_raw(¶ms[psize++], &vs->cpuset, + sizeof(vs->cpuset)); + + jailparam_init(¶ms[psize], "parent"); + jailparam_import_raw(¶ms[psize++], &vs->parentjid, + sizeof(vs->parentjid)); + + jailparam_init(¶ms[psize], "allow.raw_sockets"); + jailparam_import_raw(¶ms[psize++], &vs->rawsock, + sizeof(vs->rawsock)); + + jailparam_init(¶ms[psize], "allow.socket_af"); + jailparam_import_raw(¶ms[psize++], &vs->socket_af, + sizeof(vs->socket_af)); + + jailparam_init(¶ms[psize], "allow.mount"); + jailparam_import_raw(¶ms[psize++], &vs->mount, sizeof(vs->mount)); + +done: + vs->jid = jailparam_get(params, psize, 0); + jailparam_free(params, psize); + return (vs->jid); } From 1cc36da9660fdf1f40814a88020c7cfc63f19e34 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Thu, 20 Aug 2009 23:04:21 +0000 Subject: [PATCH 0117/2592] MFC: r196412 Check whether the SMBIOS reports reasonable amount of memory. If it is less than "avail memory", fall back to Maxmem to avoid user confusion. We use SMBIOS information to display "real memory" since r190599 but some broken SMBIOS implementation reported only half of actual memory. Tested by: bz Approved by: re (kib) --- sys/amd64/amd64/machdep.c | 22 ++++++++++++---------- sys/i386/i386/machdep.c | 22 ++++++++++++---------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 2c54be28fdf..0bfd7ada653 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -236,19 +236,21 @@ cpu_startup(dummy) #ifdef PERFMON perfmon_init(); #endif + realmem = Maxmem; + + /* + * Display physical memory if SMBIOS reports reasonable amount. + */ + memsize = 0; sysenv = getenv("smbios.memory.enabled"); if (sysenv != NULL) { - memsize = (uintmax_t)strtoul(sysenv, (char **)NULL, 10); + memsize = (uintmax_t)strtoul(sysenv, (char **)NULL, 10) << 10; freeenv(sysenv); - } else - memsize = 0; - if (memsize > 0) - printf("real memory = %ju (%ju MB)\n", memsize << 10, - memsize >> 10); - else - printf("real memory = %ju (%ju MB)\n", ptoa((uintmax_t)Maxmem), - ptoa((uintmax_t)Maxmem) / 1048576); - realmem = Maxmem; + } + if (memsize < ptoa((uintmax_t)cnt.v_free_count)) + memsize = ptoa((uintmax_t)Maxmem); + printf("real memory = %ju (%ju MB)\n", memsize, memsize >> 20); + /* * Display any holes after the first chunk of extended memory. */ diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index cba1637746e..9c1ea0b143b 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -280,19 +280,21 @@ cpu_startup(dummy) #ifdef PERFMON perfmon_init(); #endif + realmem = Maxmem; + + /* + * Display physical memory if SMBIOS reports reasonable amount. + */ + memsize = 0; sysenv = getenv("smbios.memory.enabled"); if (sysenv != NULL) { - memsize = (uintmax_t)strtoul(sysenv, (char **)NULL, 10); + memsize = (uintmax_t)strtoul(sysenv, (char **)NULL, 10) << 10; freeenv(sysenv); - } else - memsize = 0; - if (memsize > 0) - printf("real memory = %ju (%ju MB)\n", memsize << 10, - memsize >> 10); - else - printf("real memory = %ju (%ju MB)\n", ptoa((uintmax_t)Maxmem), - ptoa((uintmax_t)Maxmem) / 1048576); - realmem = Maxmem; + } + if (memsize < ptoa((uintmax_t)cnt.v_free_count)) + memsize = ptoa((uintmax_t)Maxmem); + printf("real memory = %ju (%ju MB)\n", memsize, memsize >> 20); + /* * Display any holes after the first chunk of extended memory. */ From 21f6a3982fc1d3fa4de768c6a8e5689cba737942 Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Thu, 20 Aug 2009 23:07:53 +0000 Subject: [PATCH 0118/2592] MFC rev 196410 - deal with 'ticks' going negative after 24 days of uptime with the default 1000hz clock in the timewait expiration code. Approved by: re (kensmith) --- sys/netinet/tcp_timewait.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index 96626fb3fa6..f755fa1eea8 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -603,7 +603,7 @@ tcp_tw_2msl_scan(int reuse) INP_INFO_WLOCK_ASSERT(&V_tcbinfo); for (;;) { tw = TAILQ_FIRST(&V_twq_2msl); - if (tw == NULL || (!reuse && tw->tw_time > ticks)) + if (tw == NULL || (!reuse && (tw->tw_time - ticks) > 0)) break; INP_WLOCK(tw->tw_inpcb); tcp_twclose(tw, reuse); From 31b3c6698681528adda5ec34a44e31a79e6cbac4 Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Fri, 21 Aug 2009 01:12:06 +0000 Subject: [PATCH 0119/2592] MFC r196415: Fix a boot hang for hptrr(4) caused by changes introduced in r195534. It is necessary to make sure cpi->transport is set for xpt_scan_bus() to work properly. Submitted by: Bernhard Schmidt (scb+freebsd-current techwires net) Reviewed by: scottl Approved by: re (kib) --- sys/dev/hptrr/hptrr_osm_bsd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/dev/hptrr/hptrr_osm_bsd.c b/sys/dev/hptrr/hptrr_osm_bsd.c index 3872cde0d16..eae952e1228 100644 --- a/sys/dev/hptrr/hptrr_osm_bsd.c +++ b/sys/dev/hptrr/hptrr_osm_bsd.c @@ -814,6 +814,10 @@ static void hpt_action(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); strncpy(cpi->hba_vid, "HPT ", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; cpi->ccb_h.status = CAM_REQ_CMP; break; } From 18fb1e9a445a7fbd4ffcd3c29e9f2cf96f80daf4 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 21 Aug 2009 03:14:39 +0000 Subject: [PATCH 0120/2592] MFC 196417: This patch fixes two bugs in sglist(9) and improves robustness of the API via better semantics if a request to append an address range to an existing list fails. - When cloning an sglist, properly set the length in the new sglist instead of leaving the new list empty. - Properly compute the amount of data added to an sglist via _sglist_append_buf(). This allows sglist_consume_uio() to properly update uio_resid. - When a request to append an address range to a scatter/gather list fails, restore the sglist to the state it had at the start of the function call instead of resetting it to an empty list. Approved by: re (kib) --- share/man/man9/sglist.9 | 4 ++ sys/kern/subr_sglist.c | 90 +++++++++++++++++++++++++++++++++-------- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/share/man/man9/sglist.9 b/share/man/man9/sglist.9 index a265498148f..e43a04b4d04 100644 --- a/share/man/man9/sglist.9 +++ b/share/man/man9/sglist.9 @@ -191,6 +191,8 @@ Specifically, the family of routines can be used to append the physical address ranges described by an object to the end of a scatter/gather list. All of these routines return 0 on success or an error on failure. +If a request to append an address range to a scatter/gather list fails, +the scatter/gather list will remain unchanged. .Pp The .Nm sglist_append @@ -445,6 +447,7 @@ There are not enough available segments in the scatter/gather list to append the physical address ranges from .Fa second . .El +.Pp The .Nm sglist_slice function returns the following errors on failure: @@ -470,6 +473,7 @@ list in .Fa *slice to describe the requested physical address ranges. .El +.Pp The .Nm sglist_split function returns the following errors on failure: diff --git a/sys/kern/subr_sglist.c b/sys/kern/subr_sglist.c index 474f6767294..ea7716110d7 100644 --- a/sys/kern/subr_sglist.c +++ b/sys/kern/subr_sglist.c @@ -47,6 +47,32 @@ __FBSDID("$FreeBSD$"); static MALLOC_DEFINE(M_SGLIST, "sglist", "scatter/gather lists"); +/* + * Convenience macros to save the state of an sglist so it can be restored + * if an append attempt fails. Since sglist's only grow we only need to + * save the current count of segments and the length of the ending segment. + * Earlier segments will not be changed by an append, and the only change + * that can occur to the ending segment is that it can be extended. + */ +struct sgsave { + u_short sg_nseg; + size_t ss_len; +}; + +#define SGLIST_SAVE(sg, sgsave) do { \ + (sgsave).sg_nseg = (sg)->sg_nseg; \ + if ((sgsave).sg_nseg > 0) \ + (sgsave).ss_len = (sg)->sg_segs[(sgsave).sg_nseg - 1].ss_len; \ + else \ + (sgsave).ss_len = 0; \ +} while (0) + +#define SGLIST_RESTORE(sg, sgsave) do { \ + (sg)->sg_nseg = (sgsave).sg_nseg; \ + if ((sgsave).sg_nseg > 0) \ + (sg)->sg_segs[(sgsave).sg_nseg - 1].ss_len = (sgsave).ss_len; \ +} while (0) + /* * Append a single (paddr, len) to a sglist. sg is the list and ss is * the current segment in the list. If we run out of segments then @@ -62,10 +88,8 @@ _sglist_append_range(struct sglist *sg, struct sglist_seg **ssp, if (ss->ss_paddr + ss->ss_len == paddr) ss->ss_len += len; else { - if (sg->sg_nseg == sg->sg_maxseg) { - sg->sg_nseg = 0; + if (sg->sg_nseg == sg->sg_maxseg) return (EFBIG); - } ss++; ss->ss_paddr = paddr; ss->ss_len = len; @@ -107,26 +131,33 @@ _sglist_append_buf(struct sglist *sg, void *buf, size_t len, pmap_t pmap, ss->ss_paddr = paddr; ss->ss_len = seglen; sg->sg_nseg = 1; - error = 0; } else { ss = &sg->sg_segs[sg->sg_nseg - 1]; error = _sglist_append_range(sg, &ss, paddr, seglen); + if (error) + return (error); } + vaddr += seglen; + len -= seglen; + if (donep) + *donep += seglen; - while (error == 0 && len > seglen) { - vaddr += seglen; - len -= seglen; - if (donep) - *donep += seglen; + while (len > 0) { seglen = MIN(len, PAGE_SIZE); if (pmap != NULL) paddr = pmap_extract(pmap, vaddr); else paddr = pmap_kextract(vaddr); error = _sglist_append_range(sg, &ss, paddr, seglen); + if (error) + return (error); + vaddr += seglen; + len -= seglen; + if (donep) + *donep += seglen; } - return (error); + return (0); } /* @@ -195,10 +226,16 @@ sglist_free(struct sglist *sg) int sglist_append(struct sglist *sg, void *buf, size_t len) { + struct sgsave save; + int error; if (sg->sg_maxseg == 0) return (EINVAL); - return (_sglist_append_buf(sg, buf, len, NULL, NULL)); + SGLIST_SAVE(sg, save); + error = _sglist_append_buf(sg, buf, len, NULL, NULL); + if (error) + SGLIST_RESTORE(sg, save); + return (error); } /* @@ -209,6 +246,8 @@ int sglist_append_phys(struct sglist *sg, vm_paddr_t paddr, size_t len) { struct sglist_seg *ss; + struct sgsave save; + int error; if (sg->sg_maxseg == 0) return (EINVAL); @@ -222,7 +261,11 @@ sglist_append_phys(struct sglist *sg, vm_paddr_t paddr, size_t len) return (0); } ss = &sg->sg_segs[sg->sg_nseg - 1]; - return (_sglist_append_range(sg, &ss, paddr, len)); + SGLIST_SAVE(sg, save); + error = _sglist_append_range(sg, &ss, paddr, len); + if (error) + SGLIST_RESTORE(sg, save); + return (error); } /* @@ -233,6 +276,7 @@ sglist_append_phys(struct sglist *sg, vm_paddr_t paddr, size_t len) int sglist_append_mbuf(struct sglist *sg, struct mbuf *m0) { + struct sgsave save; struct mbuf *m; int error; @@ -240,11 +284,14 @@ sglist_append_mbuf(struct sglist *sg, struct mbuf *m0) return (EINVAL); error = 0; + SGLIST_SAVE(sg, save); for (m = m0; m != NULL; m = m->m_next) { if (m->m_len > 0) { error = sglist_append(sg, m->m_data, m->m_len); - if (error) + if (error) { + SGLIST_RESTORE(sg, save); return (error); + } } } return (0); @@ -258,11 +305,17 @@ sglist_append_mbuf(struct sglist *sg, struct mbuf *m0) int sglist_append_user(struct sglist *sg, void *buf, size_t len, struct thread *td) { + struct sgsave save; + int error; if (sg->sg_maxseg == 0) return (EINVAL); - return (_sglist_append_buf(sg, buf, len, - vmspace_pmap(td->td_proc->p_vmspace), NULL)); + SGLIST_SAVE(sg, save); + error = _sglist_append_buf(sg, buf, len, + vmspace_pmap(td->td_proc->p_vmspace), NULL); + if (error) + SGLIST_RESTORE(sg, save); + return (error); } /* @@ -274,6 +327,7 @@ int sglist_append_uio(struct sglist *sg, struct uio *uio) { struct iovec *iov; + struct sgsave save; size_t resid, minlen; pmap_t pmap; int error, i; @@ -292,6 +346,7 @@ sglist_append_uio(struct sglist *sg, struct uio *uio) pmap = NULL; error = 0; + SGLIST_SAVE(sg, save); for (i = 0; i < uio->uio_iovcnt && resid != 0; i++) { /* * Now at the first iovec to load. Load each iovec @@ -301,8 +356,10 @@ sglist_append_uio(struct sglist *sg, struct uio *uio) if (minlen > 0) { error = _sglist_append_buf(sg, iov[i].iov_base, minlen, pmap, NULL); - if (error) + if (error) { + SGLIST_RESTORE(sg, save); return (error); + } resid -= minlen; } } @@ -397,6 +454,7 @@ sglist_clone(struct sglist *sg, int mflags) new = sglist_alloc(sg->sg_maxseg, mflags); if (new == NULL) return (NULL); + new->sg_nseg = sg->sg_nseg; bcopy(sg->sg_segs, new->sg_segs, sizeof(struct sglist_seg) * sg->sg_nseg); return (new); From 1261248008c5cb06cf69e7421235c707612d10b2 Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Fri, 21 Aug 2009 10:05:26 +0000 Subject: [PATCH 0121/2592] MFC r196419: Don't allow access to the internals until it has all been set up. Specifically, not until the per-vnet parts have been set up. Submitted by: kmacy@ Reviewed by: julian@, zec@ Approved by: re(rwatson) --- sys/net/flowtable.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index f6cd77839bc..98127edd5b2 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -999,6 +999,7 @@ flowtable_init_vnet(const void *unused __unused) NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET); uma_zone_set_max(V_flow_ipv4_zone, V_flowtable_nmbflows); uma_zone_set_max(V_flow_ipv6_zone, V_flowtable_nmbflows); + V_flowtable_ready = 1; } VNET_SYSINIT(flowtable_init_vnet, SI_SUB_KTHREAD_INIT, SI_ORDER_MIDDLE, flowtable_init_vnet, NULL); @@ -1011,7 +1012,6 @@ flowtable_init(const void *unused __unused) mtx_init(&flowclean_lock, "flowclean lock", NULL, MTX_DEF); EVENTHANDLER_REGISTER(ifnet_departure_event, flowtable_flush, NULL, EVENTHANDLER_PRI_ANY); - V_flowtable_ready = 1; } SYSINIT(flowtable_init, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, flowtable_init, NULL); @@ -1022,6 +1022,7 @@ static void flowtable_uninit(const void *unused __unused) { + V_flowtable_ready = 0; uma_zdestroy(V_flow_ipv4_zone); uma_zdestroy(V_flow_ipv6_zone); } From 28444b1ffde49c32c7fb290316f901fe65354b1c Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 21 Aug 2009 11:17:25 +0000 Subject: [PATCH 0122/2592] MFC r196421: Bugfix: all requests for creating vnets via vimage -c were always reported as failures, even if the actual library / system call would succeed, because error message would be reported if the return value from jail_setv() call was >= 0, and if not, then if that same value was < 0, i.e. always. The correct behavior is to abort (only) if jail_setv() returns < 0. Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- tools/tools/vimage/vimage.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/tools/vimage/vimage.c b/tools/tools/vimage/vimage.c index b54f9d6224c..e6655999c50 100644 --- a/tools/tools/vimage/vimage.c +++ b/tools/tools/vimage/vimage.c @@ -252,7 +252,7 @@ main(int argc, char **argv) exit(0); case VI_CREATE: - if ((jid = jail_setv(JAIL_CREATE, + if (jail_setv(JAIL_CREATE, "name", argv[0], "vnet", NULL, "host", NULL, @@ -260,9 +260,7 @@ main(int argc, char **argv) "allow.raw_sockets", "true", "allow.socket_af", "true", "allow.mount", "true", - NULL)) >= 0) - break; - if (jid < 0) + NULL) < 0) break; if (argc == 1) exit(0); From f8f0b70474eca24b6e730b1e54e71f3835f278e5 Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Fri, 21 Aug 2009 11:23:29 +0000 Subject: [PATCH 0123/2592] MFC r196423 Fix ipfw's initialization functions to get the correct order of evaluation to allow vnet and non vnet operation. Move some functions from ip_fw_pfil.c to ip_fw2.c and mode to mostly using the SYSINIT and VNET_SYSINIT handlers instead of the modevent handler. Correct some spelling errors in comments in the affected code. Note this bug fixes a crash in NON VIMAGE kernels when ipfw is unloaded. This patch is a minimal patch for 8.0 I have a much larger patch that actually fixes the underlying problems that will be applied after 8.0 Reviewed by: zec@, rwatson@, bz@(earlier version) Approved by: re (rwatson) --- sys/netinet/ip_fw.h | 6 +- sys/netinet/ipfw/ip_fw2.c | 126 +++++++++++++++++++++++++++++----- sys/netinet/ipfw/ip_fw_pfil.c | 60 +++------------- 3 files changed, 123 insertions(+), 69 deletions(-) diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h index 18920a0242c..9967a29607b 100644 --- a/sys/netinet/ip_fw.h +++ b/sys/netinet/ip_fw.h @@ -645,8 +645,10 @@ int ipfw_check_out(void *, struct mbuf **, struct ifnet *, int, struct inpcb *in int ipfw_chk(struct ip_fw_args *); -int ipfw_init(void); -void ipfw_destroy(void); +int ipfw_hook(void); +int ipfw6_hook(void); +int ipfw_unhook(void); +int ipfw6_unhook(void); #ifdef NOTYET void ipfw_nat_destroy(void); #endif diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c index 31065daa308..a17a64792e8 100644 --- a/sys/netinet/ipfw/ip_fw2.c +++ b/sys/netinet/ipfw/ip_fw2.c @@ -102,6 +102,8 @@ __FBSDID("$FreeBSD$"); #include #endif +static VNET_DEFINE(int, ipfw_vnet_ready) = 0; +#define V_ipfw_vnet_ready VNET(ipfw_vnet_ready) /* * set_disable contains one bit per set value (0..31). * If the bit is set, all rules with the corresponding set @@ -2237,7 +2239,7 @@ ipfw_chk(struct ip_fw_args *args) /* end of ipv6 variables */ int is_ipv4 = 0; - if (m->m_flags & M_SKIP_FIREWALL) + if (m->m_flags & M_SKIP_FIREWALL || (! V_ipfw_vnet_ready)) return (IP_FW_PASS); /* accept */ dst_ip.s_addr = 0; /* make sure it is initialized */ @@ -4579,12 +4581,10 @@ done: CURVNET_RESTORE(); } - - /**************** * Stuff that must be initialised only on boot or module load */ -int +static int ipfw_init(void) { int error = 0; @@ -4623,9 +4623,11 @@ ipfw_init(void) default_to_accept ? "accept" : "deny"); /* - * Note: V_xxx variables can be accessed here but the iattach() - * may not have been called yet for the VIMGE case. - * Tuneables will have been processed. + * Note: V_xxx variables can be accessed here but the vnet specific + * initializer may not have been called yet for the VIMAGE case. + * Tuneables will have been processed. We will print out values for + * the default vnet. + * XXX This should all be rationalized AFTER 8.0 */ if (V_fw_verbose == 0) printf("disabled\n"); @@ -4635,6 +4637,20 @@ 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 a re cuaranteed of success). @@ -4645,8 +4661,8 @@ ipfw_init(void) } /**************** - * Stuff that must be initialised for every instance - * (including the forst of course). + * Stuff that must be initialized for every instance + * (including the first of course). */ static int vnet_ipfw_init(const void *unused) @@ -4726,17 +4742,17 @@ vnet_ipfw_init(const void *unused) #endif /* First set up some values that are compile time options */ + V_ipfw_vnet_ready = 1; /* Open for business */ return (0); } /********************** * Called for the removal of the last instance only on module unload. */ -void +static void ipfw_destroy(void) { - ip_fw_chk_ptr = NULL; - ip_fw_ctl_ptr = NULL; + uma_zdestroy(ipfw_dyn_rule_zone); IPFW_DYN_LOCK_DESTROY(); printf("IP firewall unloaded\n"); @@ -4750,7 +4766,9 @@ 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_WLOCK(&V_layer3_chain); flush_tables(&V_layer3_chain); V_layer3_chain.reap = NULL; @@ -4766,10 +4784,86 @@ vnet_ipfw_uninit(const void *unused) return 0; } -VNET_SYSINIT(vnet_ipfw_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY - 255, - vnet_ipfw_init, NULL); +/* + * Module event handler. + * In general we have the choice of handling most of these events by the + * event handler or by the (VNET_)SYS(UN)INIT handlers. I have chosen to + * use the SYSINIT handlers as they are more capable of expressing the + * flow of control during module and vnet operations, so this is just + * a skeleton. Note there is no SYSINIT equivalent of the module + * SHUTDOWN handler, but we don't have anything to do in that case anyhow. + */ +static int +ipfw_modevent(module_t mod, int type, void *unused) +{ + int err = 0; -VNET_SYSUNINIT(vnet_ipfw_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY - 255, - vnet_ipfw_uninit, NULL); + switch (type) { + case MOD_LOAD: + /* 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 during unload. */ + break; + case MOD_SHUTDOWN: + /* Called during system shutdown. */ + break; + default: + err = EOPNOTSUPP; + break; + } + return err; +} + +static moduledata_t ipfwmod = { + "ipfw", + ipfw_modevent, + 0 +}; + +/* Define startup order. */ +#define IPFW_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN +#define IPFW_MODEVENT_ORDER (SI_ORDER_ANY - 255) /* On boot slot in here. */ +#define IPFW_MODULE_ORDER (IPFW_MODEVENT_ORDER + 1) /* A little later. */ +#define IPFW_VNET_ORDER (IPFW_MODEVENT_ORDER + 2) /* Later still. */ + +DECLARE_MODULE(ipfw, ipfwmod, IPFW_SI_SUB_FIREWALL, IPFW_MODEVENT_ORDER); +MODULE_VERSION(ipfw, 2); +/* should declare some dependencies here */ + +/* + * Starting up. Done in order after ipfwmod() has been called. + * VNET_SYSINIT is also called for each existing vnet and each new vnet. + */ +SYSINIT(ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER, + ipfw_init, NULL); +VNET_SYSINIT(vnet_ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER, + vnet_ipfw_init, NULL); + +/* + * Closing up shop. These are done in REVERSE ORDER, but still + * after ipfwmod() has been called. Not called on reboot. + * VNET_SYSUNINIT is also called for each exiting vnet as it exits. + * or when the module is unloaded. + */ +SYSUNINIT(ipfw_destroy, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER, + ipfw_destroy, NULL); +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 e28d5ca6403..ffffb594546 100644 --- a/sys/netinet/ipfw/ip_fw_pfil.c +++ b/sys/netinet/ipfw/ip_fw_pfil.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -441,7 +442,7 @@ nodivert: return 1; } -static int +int ipfw_hook(void) { struct pfil_head *pfh_inet; @@ -458,7 +459,7 @@ ipfw_hook(void) return 0; } -static int +int ipfw_unhook(void) { struct pfil_head *pfh_inet; @@ -476,7 +477,7 @@ ipfw_unhook(void) } #ifdef INET6 -static int +int ipfw6_hook(void) { struct pfil_head *pfh_inet6; @@ -493,7 +494,7 @@ ipfw6_hook(void) return 0; } -static int +int ipfw6_unhook(void) { struct pfil_head *pfh_inet6; @@ -517,6 +518,10 @@ ipfw_chg_hook(SYSCTL_HANDLER_ARGS) int enable = *(int *)arg1; int error; +#ifdef VIMAGE /* Since enabling is global, only let base do it. */ + if (! IS_DEFAULT_VNET(curvnet)) + return (EPERM); +#endif error = sysctl_handle_int(oidp, &enable, 0, req); if (error) return (error); @@ -549,50 +554,3 @@ ipfw_chg_hook(SYSCTL_HANDLER_ARGS) return (0); } -static int -ipfw_modevent(module_t mod, int type, void *unused) -{ - int err = 0; - - switch (type) { - case MOD_LOAD: - if ((err = ipfw_init()) != 0) { - printf("ipfw_init() error\n"); - break; - } - if ((err = ipfw_hook()) != 0) { - printf("ipfw_hook() error\n"); - break; - } -#ifdef INET6 - if ((err = ipfw6_hook()) != 0) { - printf("ipfw_hook() error\n"); - break; - } -#endif - break; - - case MOD_UNLOAD: - if ((err = ipfw_unhook()) > 0) - break; -#ifdef INET6 - if ((err = ipfw6_unhook()) > 0) - break; -#endif - ipfw_destroy(); - break; - - default: - return EOPNOTSUPP; - break; - } - return err; -} - -static moduledata_t ipfwmod = { - "ipfw", - ipfw_modevent, - 0 -}; -DECLARE_MODULE(ipfw, ipfwmod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY - 256); -MODULE_VERSION(ipfw, 2); From bf6ab6cb36ebcd1eb3c9cd415d250a31fc58909c Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Fri, 21 Aug 2009 17:40:24 +0000 Subject: [PATCH 0124/2592] Ready for 8.0-BETA3 builds. Approved by: re (implicit) --- sys/conf/newvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index f56d20ebbf4..962e092648f 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.0" -BRANCH="BETA2" +BRANCH="BETA3" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi From b9a4add9869b92bbf3ca3affa0d6bdcee1e58985 Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Sun, 23 Aug 2009 06:33:42 +0000 Subject: [PATCH 0125/2592] Update for RELENG_8. Reminded by: dougb Approved by: re (implicit) --- share/examples/cvsup/stable-supfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/examples/cvsup/stable-supfile b/share/examples/cvsup/stable-supfile index 3b0c8e96892..83e96a05ef1 100644 --- a/share/examples/cvsup/stable-supfile +++ b/share/examples/cvsup/stable-supfile @@ -69,7 +69,7 @@ # The following line is for 7-stable. If you want 6-stable, 5-stable, # 4-stable, 3-stable, or 2.2-stable, change to "RELENG_6", "RELENG_5", # "RELENG_4", "RELENG_3", or "RELENG_2_2" respectively. -*default release=cvs tag=RELENG_7 +*default release=cvs tag=RELENG_8 *default delete use-rel-suffix # If you seem to be limited by CPU rather than network or disk bandwidth, try From f9906ce770939236d95eb0f8637efcbf017db93b Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sun, 23 Aug 2009 16:21:49 +0000 Subject: [PATCH 0126/2592] MFC r196472: Enable _DIRENT_HAVE_D_TYPE so wpa_cli scans directories properly for it's unix domain socket. Before this change wpa_cli would take the first file in the directory that was not "." or "..". Approved by: re (rwatson) --- usr.sbin/wpa/wpa_cli/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usr.sbin/wpa/wpa_cli/Makefile b/usr.sbin/wpa/wpa_cli/Makefile index ae16a72a0b9..123485a91fc 100644 --- a/usr.sbin/wpa/wpa_cli/Makefile +++ b/usr.sbin/wpa/wpa_cli/Makefile @@ -11,6 +11,8 @@ MAN= wpa_cli.8 CFLAGS+= -DCONFIG_CTRL_IFACE CFLAGS+= -DCONFIG_CTRL_IFACE_UNIX +# enable use of d_type to identify unix domain sockets +CFLAGS+= -D_DIRENT_HAVE_D_TYPE #CFLAGS+= -DCONFIG_READLINE #LDADD+= -ledit -ltermcap From 48b89c5962b48b1c3a1c9ae512842543ad912e5e Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Mon, 24 Aug 2009 03:49:37 +0000 Subject: [PATCH 0127/2592] Update the comment for RELENG_8 too. Submitted by: Dmitry Morozovsky Approved by: re (implicit) --- share/examples/cvsup/stable-supfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/share/examples/cvsup/stable-supfile b/share/examples/cvsup/stable-supfile index 83e96a05ef1..7f4f0e9c61c 100644 --- a/share/examples/cvsup/stable-supfile +++ b/share/examples/cvsup/stable-supfile @@ -66,9 +66,10 @@ *default host=CHANGE_THIS.FreeBSD.org *default base=/var/db *default prefix=/usr -# The following line is for 7-stable. If you want 6-stable, 5-stable, -# 4-stable, 3-stable, or 2.2-stable, change to "RELENG_6", "RELENG_5", -# "RELENG_4", "RELENG_3", or "RELENG_2_2" respectively. +# The following line is for 8-stable. If you want 7-stable, 6-stable, +# 5-stable, 4-stable, 3-stable, or 2.2-stable, change to "RELENG_7", +# "RELENG_6", "RELENG_5", "RELENG_4", "RELENG_3", or "RELENG_2_2" +# respectively. *default release=cvs tag=RELENG_8 *default delete use-rel-suffix From 215f7aba4928f5d553922126f1f44e19eeb6f30d Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Wed, 26 Aug 2009 20:57:21 +0000 Subject: [PATCH 0128/2592] MFC 196434: Add a script to create the /var/db/mergemaster.mtree file for new releases so that when users subsequently update their source trees they can make use of mergemaster's -U option. Approved by: re (kib) --- release/scripts/mm-mtree.sh | 155 ++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100755 release/scripts/mm-mtree.sh diff --git a/release/scripts/mm-mtree.sh b/release/scripts/mm-mtree.sh new file mode 100755 index 00000000000..d132a34a0e7 --- /dev/null +++ b/release/scripts/mm-mtree.sh @@ -0,0 +1,155 @@ +#!/bin/sh + +# mergemaster mtree database generator + +# This script is intended to be used as part of the release building +# process to generate the /var/db/mergemaster.mtree file relevant to +# the source tree used to create the release so that users can make +# use of mergemaster's -U option to update their files after csup'ing +# to -stable. + +# Copyright 2009 Douglas Barton +# dougb@FreeBSD.org + +# $FreeBSD$ + +PATH=/bin:/usr/bin:/usr/sbin + +display_usage () { + VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4` + echo "${0##*/} version ${VERSION_NUMBER}" + echo "Usage: ${0##*/} [-m /path] [-t /path] [-A arch] [-F ] [-D /path]" + echo "Options:" + echo " -m /path/directory Specify location of source to do the make in" + echo " -t /path/directory Specify temp root directory" + echo " -A architecture Alternative architecture name to pass to make" + echo " -F Specify what to put on the make command line" + echo ' -D /path/directory Specify the destination directory to install files to' + echo '' +} + +# Set the default path for the temporary root environment +# +TEMPROOT='/var/tmp/temproot' + +# Assign the location of the mtree database +# +MTREEDB=${MTREEDB:-/var/db} +MTREEFILE="${MTREEDB}/mergemaster.mtree" + +# Check the command line options +# +while getopts "m:t:A:F:D:h" COMMAND_LINE_ARGUMENT ; do + case "${COMMAND_LINE_ARGUMENT}" in + m) + SOURCEDIR=${OPTARG} + ;; + t) + TEMPROOT=${OPTARG} + ;; + A) + ARCHSTRING='TARGET_ARCH='${OPTARG} + ;; + F) + MM_MAKE_ARGS="${OPTARG}" + ;; + D) + DESTDIR=${OPTARG} + ;; + h) + display_usage + exit 0 + ;; + *) + echo '' + display_usage + exit 1 + ;; + esac +done + +# Assign the source directory +# +SOURCEDIR=${SOURCEDIR:-/usr/src} +if [ ! -f ${SOURCEDIR}/Makefile.inc1 -a \ + -f ${SOURCEDIR}/../Makefile.inc1 ]; then + echo " *** The source directory you specified (${SOURCEDIR})" + echo " will be reset to ${SOURCEDIR}/.." + echo '' + sleep 3 + SOURCEDIR=${SOURCEDIR}/.. +fi + +# Setup make to use system files from SOURCEDIR +MM_MAKE="make ${ARCHSTRING} ${MM_MAKE_ARGS} -m ${SOURCEDIR}/share/mk" + +delete_temproot () { + rm -rf "${TEMPROOT}" 2>/dev/null + chflags -R 0 "${TEMPROOT}" 2>/dev/null + rm -rf "${TEMPROOT}" || exit 1 +} + +[ -d "${TEMPROOT}" ] && delete_temproot + +echo "*** Creating the temporary root environment in ${TEMPROOT}" + +if mkdir -p "${TEMPROOT}"; then + echo " *** ${TEMPROOT} ready for use" +fi + +if [ ! -d "${TEMPROOT}" ]; then + echo '' + echo " *** FATAL ERROR: Cannot create ${TEMPROOT}" + echo '' + exit 1 +fi + +echo " *** Creating and populating directory structure in ${TEMPROOT}" +echo '' + +{ cd ${SOURCEDIR} || { echo "*** Cannot cd to ${SOURCEDIR}" ; exit 1;} + case "${DESTDIR}" in + '') ;; + *) + ${MM_MAKE} DESTDIR=${DESTDIR} distrib-dirs + ;; + esac + od=${TEMPROOT}/usr/obj + ${MM_MAKE} DESTDIR=${TEMPROOT} distrib-dirs && + MAKEOBJDIRPREFIX=$od ${MM_MAKE} _obj SUBDIR_OVERRIDE=etc && + MAKEOBJDIRPREFIX=$od ${MM_MAKE} everything SUBDIR_OVERRIDE=etc && + MAKEOBJDIRPREFIX=$od ${MM_MAKE} DESTDIR=${TEMPROOT} distribution;} || + { echo ''; + echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to"; + echo " the temproot environment"; + echo ''; + exit 1;} + +# We really don't want to have to deal with files like login.conf.db, pwd.db, +# or spwd.db. Instead, we want to compare the text versions, and run *_mkdb. +# Prompt the user to do so below, as needed. +# +rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd + +# We only need to compare things like freebsd.cf once +find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null + +# Delete stuff we do not need to keep the mtree database small, +# and to make the actual comparison faster. +find ${TEMPROOT}/usr -type l -delete 2>/dev/null +find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null +find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null + +# Build the mtree database in a temporary location. +MTREENEW=`mktemp -t mergemaster.mtree` +mtree -ci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null + +if [ -s "${MTREENEW}" ]; then + echo "*** Saving mtree database for future upgrades" + test -e "${DESTDIR}${MTREEFILE}" && unlink ${DESTDIR}${MTREEFILE} + mv ${MTREENEW} ${DESTDIR}${MTREEFILE} +fi + +delete_temproot + +exit 0 From 0c4ef85bfd9b9e7025e9f883268e21d6bfb2ce57 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Wed, 26 Aug 2009 21:08:41 +0000 Subject: [PATCH 0129/2592] MFC 196436; Move is_wired_interface() from rc.d/wpa_supplicant into network.subr, simplify it a bit, and make use of that method to determine if an interface is a candidate for IPv6 rtsol rather than listing all of the possible wireless interfaces that should _not_ get rtsol'ed. This change is only relevant for 8.0+ unless the "wlan mandatory" code gets ported back to RELENG_7. Approved by: re (kib) --- etc/network.subr | 22 +++++++++++++++++++--- etc/rc.d/wpa_supplicant | 12 ------------ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/etc/network.subr b/etc/network.subr index 22bfc7dc8b9..c14985473e9 100644 --- a/etc/network.subr +++ b/etc/network.subr @@ -816,6 +816,17 @@ hexprint() echo ${str} } +is_wired_interface() +{ + local media + + case `ifconfig $1 2>/dev/null` in + *media:?Ethernet*) media=Ethernet ;; + esac + + test "$media" = "Ethernet" +} + # Setup the interfaces for IPv6 network6_interface_setup() { @@ -858,14 +869,19 @@ network6_interface_setup() ifconfig $i inet6 ${ipv6_ifconfig} alias fi + # Wireless NIC cards are virtualized through the wlan interface + if ! is_wired_interface ${i}; then + case "${i}" in + wlan*) rtsol_available=yes ;; + *) rtsol_available=no ;; + esac + fi + if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ] then case ${i} in lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*|pflog[0-9]*|pfsync[0-9]*) ;; - # Wireless NIC cards are virtualized through the wlan interface - an[0-9]*|ath[0-9]*|ipw[0-9]*|iwi[0-9]*|iwn[0-9]*|ral[0-9]*|wi[0-9]*|wl[0-9]*|wpi[0-9]*) - ;; *) rtsol_interfaces="${rtsol_interfaces} ${i}" ;; diff --git a/etc/rc.d/wpa_supplicant b/etc/rc.d/wpa_supplicant index 192ca966aa9..8514efcbbc1 100755 --- a/etc/rc.d/wpa_supplicant +++ b/etc/rc.d/wpa_supplicant @@ -18,18 +18,6 @@ if [ -z "$ifn" ]; then return 1 fi -is_wired_interface() -{ - media=`ifconfig $1 2>/dev/null | while read line; do - case "$line" in - *media:?Ethernet*) - echo Ethernet - ;; - esac - done` - test "$media" = "Ethernet" -} - is_ndis_interface() { case `sysctl -n net.wlan.${1#wlan}.%parent 2>/dev/null` in From 818b5b0e2ab6f62095ddf8fc74232b31361684d9 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Wed, 26 Aug 2009 22:32:14 +0000 Subject: [PATCH 0130/2592] MFC r196435: The svnversion string is only relevant when newvers.sh is called during the kernel build process, the other places that call the script do not make use of that information. So restrict execution of the svnversion-related code to the kernel build context. Approved by: re (kib) --- sys/conf/newvers.sh | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index 962e092648f..25a5a77c2bb 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -87,29 +87,25 @@ touch version v=`cat version` u=${USER:-root} d=`pwd` h=${HOSTNAME:-`hostname`} t=`date` i=`${MAKE:-make} -V KERN_IDENT` -for dir in /bin /usr/bin /usr/local/bin; do - if [ -x "${dir}/svnversion" ]; then - svnversion=${dir}/svnversion - SRCDIR=${d##*obj} - if [ -n "$MACHINE" ]; then - SRCDIR=${SRCDIR##/$MACHINE} +case "$d" in +*/sys/*) + for dir in /bin /usr/bin /usr/local/bin; do + if [ -x "${dir}/svnversion" ]; then + svnversion=${dir}/svnversion + SRCDIR=${d##*obj} + if [ -n "$MACHINE" ]; then + SRCDIR=${SRCDIR##/$MACHINE} + fi + SRCDIR=${SRCDIR%%/sys/*} + break fi - SRCDIR=${SRCDIR%%/sys/*} - break - fi -done + done -if [ -n "$svnversion" -a -d "${SRCDIR}/.svn" ] ; then - # If we are called from the kernel build, limit - # the scope of svnversion to sys/ . - if [ -e "${SRCDIR}/sys/conf/newvers.sh" ] ; then - svn=" r`cd $SRCDIR/sys && $svnversion`" - else - svn=" r`cd $SRCDIR && $svnversion`" + if [ -n "$svnversion" -a -d "${SRCDIR}/sys/.svn" ] ; then + svn=" r`cd ${SRCDIR}/sys && $svnversion`" fi -else - svn="" -fi + ;; +esac cat << EOF > vers.c $COPYRIGHT From ff550a99bde8a54482ecc8d1b7d67c74dca109d3 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Thu, 27 Aug 2009 07:05:46 +0000 Subject: [PATCH 0131/2592] MFC: When realloc()ing device memory for transfer to another ppp process, don't continue to use the realloc()d pointer - it might have changed! Remove some stray diagnostics while I'm here. Approved by: re (kib) --- usr.sbin/ppp/ether.c | 7 ++++--- usr.sbin/ppp/netgraph.c | 8 ++++---- usr.sbin/ppp/tty.c | 9 +++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/usr.sbin/ppp/ether.c b/usr.sbin/ppp/ether.c index e4e154ad7f3..a86f3bd5b19 100644 --- a/usr.sbin/ppp/ether.c +++ b/usr.sbin/ppp/ether.c @@ -193,17 +193,18 @@ static void ether_device2iov(struct device *d, struct iovec *iov, int *niov, int maxiov __unused, int *auxfd, int *nauxfd) { - struct etherdevice *dev = device2ether(d); + struct etherdevice *dev; int sz = physical_MaxDeviceSize(); - iov[*niov].iov_base = realloc(d, sz); - if (iov[*niov].iov_base == NULL) { + iov[*niov].iov_base = d = realloc(d, sz); + if (d == NULL) { log_Printf(LogALERT, "Failed to allocate memory: %d\n", sz); AbortProgram(EX_OSERR); } iov[*niov].iov_len = sz; (*niov)++; + dev = device2ether(d); if (dev->cs >= 0) { *auxfd = dev->cs; (*nauxfd)++; diff --git a/usr.sbin/ppp/netgraph.c b/usr.sbin/ppp/netgraph.c index 471dc0d15f5..23a575b4df3 100644 --- a/usr.sbin/ppp/netgraph.c +++ b/usr.sbin/ppp/netgraph.c @@ -235,7 +235,6 @@ ng_Read(struct physical *p, void *v, size_t n) { char hook[NG_HOOKSIZ]; -log_Printf(LogDEBUG, "ng_Read\n"); switch (p->dl->state) { case DATALINK_DIAL: case DATALINK_LOGIN: @@ -282,17 +281,18 @@ static void ng_device2iov(struct device *d, struct iovec *iov, int *niov, int maxiov __unused, int *auxfd, int *nauxfd) { - struct ngdevice *dev = device2ng(d); + struct ngdevice *dev; int sz = physical_MaxDeviceSize(); - iov[*niov].iov_base = realloc(d, sz); - if (iov[*niov].iov_base == NULL) { + iov[*niov].iov_base = d = realloc(d, sz); + if (d == NULL) { log_Printf(LogALERT, "Failed to allocate memory: %d\n", sz); AbortProgram(EX_OSERR); } iov[*niov].iov_len = sz; (*niov)++; + dev = device2ng(d); *auxfd = dev->cs; (*nauxfd)++; } diff --git a/usr.sbin/ppp/tty.c b/usr.sbin/ppp/tty.c index 8d5d58bac28..ab984cca718 100644 --- a/usr.sbin/ppp/tty.c +++ b/usr.sbin/ppp/tty.c @@ -384,7 +384,6 @@ UnloadLineDiscipline(struct physical *p) struct ttydevice *dev = device2tty(p->handler); if (isngtty(dev)) { -log_Printf(LogPHASE, "back to speed %d\n", dev->real.speed); if (!physical_SetSpeed(p, dev->real.speed)) log_Printf(LogWARN, "Couldn't reset tty speed to %d\n", dev->real.speed); dev->real.speed = 0; @@ -582,17 +581,19 @@ tty_device2iov(struct device *d, struct iovec *iov, int *niov, #endif ) { - struct ttydevice *dev = device2tty(d); + struct ttydevice *dev; int sz = physical_MaxDeviceSize(); - iov[*niov].iov_base = realloc(d, sz); - if (iov[*niov].iov_base == NULL) { + iov[*niov].iov_base = d = realloc(d, sz); + if (d == NULL) { log_Printf(LogALERT, "Failed to allocate memory: %d\n", sz); AbortProgram(EX_OSERR); } iov[*niov].iov_len = sz; (*niov)++; + dev = device2tty(d); + #ifndef NONETGRAPH if (dev->cs >= 0) { *auxfd = dev->cs; From 61a651a452096993be7481eabd5f6a060a3380da Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Thu, 27 Aug 2009 07:07:38 +0000 Subject: [PATCH 0132/2592] MFC: When ``ppp -direct'' is invoked by a program that uses pipe(2) to create stdin and stdout, don't blindly try to use stdin as a bi-directional channel. Instead, detect the pipe and set up a special exec handler that indirects write() calls through stdout. This fixes the problem where ``set device "!ssh -e none host ppp -direct label"'' no longer works with an openssh-5.2 server side as that version of openssh ignores the USE_PIPES config setting and *always* uses pipes (rather than socketpair) for stdin/stdout channels. Approved by: re (kib) --- usr.sbin/ppp/exec.c | 420 ++++++++++++++++++++++++++++------------ usr.sbin/ppp/exec.h | 2 +- usr.sbin/ppp/main.c | 6 +- usr.sbin/ppp/physical.c | 1 + 4 files changed, 304 insertions(+), 125 deletions(-) diff --git a/usr.sbin/ppp/exec.c b/usr.sbin/ppp/exec.c index 7c80034a6ac..a53db37270f 100644 --- a/usr.sbin/ppp/exec.c +++ b/usr.sbin/ppp/exec.c @@ -35,7 +35,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -63,24 +65,106 @@ #include "cbcp.h" #include "datalink.h" #include "id.h" +#include "main.h" #include "exec.h" -static struct device execdevice = { + +struct execdevice { + struct device dev; /* What struct physical knows about */ + int fd_out; /* output descriptor */ +}; + +#define device2exec(d) ((d)->type == EXEC_DEVICE ? (struct execdevice *)d : NULL) + +unsigned +exec_DeviceSize(void) +{ + return sizeof(struct execdevice); +} + +static void +exec_Free(struct physical *p) +{ + struct execdevice *dev = device2exec(p->handler); + + if (dev->fd_out != -1) + close(dev->fd_out); + free(dev); +} + +static void +exec_device2iov(struct device *d, struct iovec *iov, int *niov, + int maxiov __unused, int *auxfd, int *nauxfd) +{ + struct execdevice *dev; + int sz = physical_MaxDeviceSize(); + + iov[*niov].iov_base = d = realloc(d, sz); + if (d == NULL) { + log_Printf(LogALERT, "Failed to allocate memory: %d\n", sz); + AbortProgram(EX_OSERR); + } + iov[*niov].iov_len = sz; + (*niov)++; + + dev = device2exec(d); + if (dev->fd_out >= 0) { + *auxfd = dev->fd_out; + (*nauxfd)++; + } +} + +static int +exec_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e) +{ + struct execdevice *dev = device2exec(p->handler); + int sets; + + p->handler->removefromset = NULL; + sets = physical_RemoveFromSet(p, r, w, e); + p->handler->removefromset = exec_RemoveFromSet; + + if (dev->fd_out >= 0) { + if (w && FD_ISSET(dev->fd_out, w)) { + FD_CLR(dev->fd_out, w); + log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, dev->fd_out); + sets++; + } + if (e && FD_ISSET(dev->fd_out, e)) { + FD_CLR(dev->fd_out, e); + log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, dev->fd_out); + sets++; + } + } + + return sets; +} + +static ssize_t +exec_Write(struct physical *p, const void *v, size_t n) +{ + struct execdevice *dev = device2exec(p->handler); + int fd = dev->fd_out == -1 ? p->fd : dev->fd_out; + + return write(fd, v, n); +} + +static struct device baseexecdevice = { EXEC_DEVICE, "exec", 0, { CD_NOTREQUIRED, 0 }, NULL, + exec_RemoveFromSet, NULL, NULL, NULL, NULL, NULL, + exec_Free, NULL, - NULL, - NULL, - NULL, - NULL, + exec_Write, + exec_device2iov, NULL, NULL, NULL @@ -88,146 +172,238 @@ static struct device execdevice = { struct device * exec_iov2device(int type, struct physical *p, struct iovec *iov, - int *niov, int maxiov __unused, int *auxfd __unused, - int *nauxfd __unused) + int *niov, int maxiov __unused, int *auxfd, int *nauxfd) { if (type == EXEC_DEVICE) { - free(iov[(*niov)++].iov_base); - physical_SetupStack(p, execdevice.name, PHYSICAL_NOFORCE); - return &execdevice; + struct execdevice *dev = (struct execdevice *)iov[(*niov)++].iov_base; + + dev = realloc(dev, sizeof *dev); /* Reduce to the correct size */ + if (dev == NULL) { + log_Printf(LogALERT, "Failed to allocate memory: %d\n", + (int)(sizeof *dev)); + AbortProgram(EX_OSERR); + } + + if (*nauxfd) { + dev->fd_out = *auxfd; + (*nauxfd)--; + } else + dev->fd_out = -1; + + /* Refresh function pointers etc */ + memcpy(&dev->dev, &baseexecdevice, sizeof dev->dev); + + physical_SetupStack(p, dev->dev.name, PHYSICAL_NOFORCE); + return &dev->dev; } return NULL; } +static int +exec_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +{ + struct physical *p = descriptor2physical(d); + struct execdevice *dev = device2exec(p->handler); + int result = 0; + + if (w && dev->fd_out >= 0) { + FD_SET(dev->fd_out, w); + log_Printf(LogTIMER, "%s: fdset(w) %d\n", p->link.name, dev->fd_out); + result++; + w = NULL; + } + + if (e && dev->fd_out >= 0) { + FD_SET(dev->fd_out, e); + log_Printf(LogTIMER, "%s: fdset(e) %d\n", p->link.name, dev->fd_out); + result++; + } + + if (result && *n <= dev->fd_out) + *n = dev->fd_out + 1; + + return result + physical_doUpdateSet(d, r, w, e, n, 0); +} + +static int +exec_IsSet(struct fdescriptor *d, const fd_set *fdset) +{ + struct physical *p = descriptor2physical(d); + struct execdevice *dev = device2exec(p->handler); + int result = dev->fd_out >= 0 && FD_ISSET(dev->fd_out, fdset); + result += physical_IsSet(d, fdset); + + return result; +} + struct device * exec_Create(struct physical *p) { - if (p->fd < 0 && *p->name.full == '!') { - int fids[2], type; + struct execdevice *dev; - p->fd--; /* We own the device but maybe can't use it - change fd */ - type = physical_IsSync(p) ? SOCK_DGRAM : SOCK_STREAM; - - if (socketpair(AF_UNIX, type, PF_UNSPEC, fids) < 0) - log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", - strerror(errno)); - else { - static int child_status; /* This variable is abused ! */ - int stat, argc, i, ret, wret, pidpipe[2]; - pid_t pid, realpid; - char *argv[MAXARGS]; - - stat = fcntl(fids[0], F_GETFL, 0); - if (stat > 0) { - stat |= O_NONBLOCK; - fcntl(fids[0], F_SETFL, stat); + dev = NULL; + if (p->fd < 0) { + if (*p->name.full == '!') { + int fids[2], type; + + if ((dev = malloc(sizeof *dev)) == NULL) { + log_Printf(LogWARN, "%s: Cannot allocate an exec device: %s\n", + p->link.name, strerror(errno)); + return NULL; } - realpid = getpid(); - if (pipe(pidpipe) == -1) { - log_Printf(LogPHASE, "Unable to pipe for line exec: %s\n", + dev->fd_out = -1; + + p->fd--; /* We own the device but maybe can't use it - change fd */ + type = physical_IsSync(p) ? SOCK_DGRAM : SOCK_STREAM; + + if (socketpair(AF_UNIX, type, PF_UNSPEC, fids) < 0) { + log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", strerror(errno)); - close(fids[1]); - } else switch ((pid = fork())) { - case -1: - log_Printf(LogPHASE, "Unable to fork for line exec: %s\n", + free(dev); + dev = NULL; + } else { + static int child_status; /* This variable is abused ! */ + int stat, argc, i, ret, wret, pidpipe[2]; + pid_t pid, realpid; + char *argv[MAXARGS]; + + stat = fcntl(fids[0], F_GETFL, 0); + if (stat > 0) { + stat |= O_NONBLOCK; + fcntl(fids[0], F_SETFL, stat); + } + realpid = getpid(); + if (pipe(pidpipe) == -1) { + log_Printf(LogPHASE, "Unable to pipe for line exec: %s\n", strerror(errno)); - close(pidpipe[0]); - close(pidpipe[1]); close(fids[1]); - break; - - case 0: - close(pidpipe[0]); close(fids[0]); - timer_TermService(); -#ifndef NOSUID - setuid(ID0realuid()); -#endif - - child_status = 0; - switch ((pid = vfork())) { - case 0: - close(pidpipe[1]); - break; - - case -1: - ret = errno; - log_Printf(LogPHASE, "Unable to vfork to drop parent: %s\n", - strerror(errno)); - close(pidpipe[1]); - _exit(ret); - - default: - write(pidpipe[1], &pid, sizeof pid); - close(pidpipe[1]); - _exit(child_status); /* The error from exec() ! */ - } - - log_Printf(LogDEBUG, "Exec'ing ``%s''\n", p->name.base); - - if ((argc = MakeArgs(p->name.base, argv, VECSIZE(argv), - PARSE_REDUCE|PARSE_NOHASH)) < 0) { - log_Printf(LogWARN, "Syntax error in exec command\n"); - _exit(ESRCH); - } - - command_Expand(argv, argc, (char const *const *)argv, - p->dl->bundle, 0, realpid); - - dup2(fids[1], STDIN_FILENO); - dup2(fids[1], STDOUT_FILENO); - dup2(fids[1], STDERR_FILENO); - for (i = getdtablesize(); i > STDERR_FILENO; i--) - fcntl(i, F_SETFD, 1); - - execvp(*argv, argv); - child_status = errno; /* Only works for vfork() */ - printf("execvp failed: %s: %s\r\n", *argv, strerror(child_status)); - _exit(child_status); - break; - - default: - close(pidpipe[1]); - close(fids[1]); - if (read(pidpipe[0], &p->session_owner, sizeof p->session_owner) != - sizeof p->session_owner) - p->session_owner = (pid_t)-1; - close(pidpipe[0]); - while ((wret = waitpid(pid, &stat, 0)) == -1 && errno == EINTR) - ; - if (wret == -1) { - log_Printf(LogWARN, "Waiting for child process: %s\n", + free(dev); + dev = NULL; + } else switch ((pid = fork())) { + case -1: + log_Printf(LogPHASE, "Unable to fork for line exec: %s\n", strerror(errno)); + close(pidpipe[0]); + close(pidpipe[1]); + close(fids[1]); close(fids[0]); - p->session_owner = (pid_t)-1; break; - } else if (WIFSIGNALED(stat)) { - log_Printf(LogWARN, "Child process received sig %d !\n", - WTERMSIG(stat)); + + case 0: + close(pidpipe[0]); close(fids[0]); - p->session_owner = (pid_t)-1; + timer_TermService(); + #ifndef NOSUID + setuid(ID0realuid()); + #endif + + child_status = 0; + switch ((pid = vfork())) { + case 0: + close(pidpipe[1]); + break; + + case -1: + ret = errno; + log_Printf(LogPHASE, "Unable to vfork to drop parent: %s\n", + strerror(errno)); + close(pidpipe[1]); + _exit(ret); + + default: + write(pidpipe[1], &pid, sizeof pid); + close(pidpipe[1]); + _exit(child_status); /* The error from exec() ! */ + } + + log_Printf(LogDEBUG, "Exec'ing ``%s''\n", p->name.base); + + if ((argc = MakeArgs(p->name.base, argv, VECSIZE(argv), + PARSE_REDUCE|PARSE_NOHASH)) < 0) { + log_Printf(LogWARN, "Syntax error in exec command\n"); + _exit(ESRCH); + } + + command_Expand(argv, argc, (char const *const *)argv, + p->dl->bundle, 0, realpid); + + dup2(fids[1], STDIN_FILENO); + dup2(fids[1], STDOUT_FILENO); + dup2(fids[1], STDERR_FILENO); + for (i = getdtablesize(); i > STDERR_FILENO; i--) + fcntl(i, F_SETFD, 1); + + execvp(*argv, argv); + child_status = errno; /* Only works for vfork() */ + printf("execvp failed: %s: %s\r\n", *argv, strerror(child_status)); + _exit(child_status); break; - } else if (WIFSTOPPED(stat)) { - log_Printf(LogWARN, "Child process received stop sig %d !\n", - WSTOPSIG(stat)); - /* I guess that's ok.... */ - } else if ((ret = WEXITSTATUS(stat))) { - log_Printf(LogWARN, "Cannot exec \"%s\": %s\n", p->name.base, - strerror(ret)); - close(fids[0]); - p->session_owner = (pid_t)-1; - break; - } - p->fd = fids[0]; - log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd); - physical_SetupStack(p, execdevice.name, PHYSICAL_NOFORCE); - if (p->cfg.cd.necessity != CD_DEFAULT) - log_Printf(LogWARN, "Carrier settings ignored\n"); - return &execdevice; + + default: + close(pidpipe[1]); + close(fids[1]); + if (read(pidpipe[0], &p->session_owner, sizeof p->session_owner) != + sizeof p->session_owner) + p->session_owner = (pid_t)-1; + close(pidpipe[0]); + while ((wret = waitpid(pid, &stat, 0)) == -1 && errno == EINTR) + ; + if (wret == -1) { + log_Printf(LogWARN, "Waiting for child process: %s\n", + strerror(errno)); + close(fids[0]); + p->session_owner = (pid_t)-1; + break; + } else if (WIFSIGNALED(stat)) { + log_Printf(LogWARN, "Child process received sig %d !\n", + WTERMSIG(stat)); + close(fids[0]); + p->session_owner = (pid_t)-1; + break; + } else if (WIFSTOPPED(stat)) { + log_Printf(LogWARN, "Child process received stop sig %d !\n", + WSTOPSIG(stat)); + /* I guess that's ok.... */ + } else if ((ret = WEXITSTATUS(stat))) { + log_Printf(LogWARN, "Cannot exec \"%s\": %s\n", p->name.base, + strerror(ret)); + close(fids[0]); + p->session_owner = (pid_t)-1; + break; + } + p->fd = fids[0]; + log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd); + } } - close(fids[0]); } + } else { + struct stat st; + + if (fstat(p->fd, &st) != -1 && (st.st_mode & S_IFIFO)) { + if ((dev = malloc(sizeof *dev)) == NULL) + log_Printf(LogWARN, "%s: Cannot allocate an exec device: %s\n", + p->link.name, strerror(errno)); + else if (p->fd == STDIN_FILENO) { + log_Printf(LogPHASE, "%s: Using stdin/stdout to communicate with " + "parent (pipe mode)\n", p->link.name); + dev->fd_out = dup(STDOUT_FILENO); + + /* Hook things up so that we monitor dev->fd_out */ + p->desc.UpdateSet = exec_UpdateSet; + p->desc.IsSet = exec_IsSet; + } else + dev->fd_out = -1; + } + } + + if (dev) { + memcpy(&dev->dev, &baseexecdevice, sizeof dev->dev); + physical_SetupStack(p, dev->dev.name, PHYSICAL_NOFORCE); + if (p->cfg.cd.necessity != CD_DEFAULT) + log_Printf(LogWARN, "Carrier settings ignored\n"); + return &dev->dev; } return NULL; diff --git a/usr.sbin/ppp/exec.h b/usr.sbin/ppp/exec.h index d4b338767fb..32bd748609e 100644 --- a/usr.sbin/ppp/exec.h +++ b/usr.sbin/ppp/exec.h @@ -32,4 +32,4 @@ struct device; extern struct device *exec_Create(struct physical *); extern struct device *exec_iov2device(int, struct physical *, struct iovec *, int *, int, int *, int *); -#define exec_DeviceSize physical_DeviceSize +extern unsigned exec_DeviceSize(void); diff --git a/usr.sbin/ppp/main.c b/usr.sbin/ppp/main.c index b4d5e29517d..fd826d0253a 100644 --- a/usr.sbin/ppp/main.c +++ b/usr.sbin/ppp/main.c @@ -509,9 +509,11 @@ main(int argc, char **argv) if (!sw.fg) setsid(); } else { - /* -direct - STDIN_FILENO gets used by physical_Open */ + /* + * -direct - STDIN_FILENO gets used by physical_Open. STDOUT_FILENO + * *may* get used in exec/pipe mode. + */ prompt_TtyInit(NULL); - close(STDOUT_FILENO); close(STDERR_FILENO); } } else { diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c index ed3ab9c083e..03778006bcb 100644 --- a/usr.sbin/ppp/physical.c +++ b/usr.sbin/ppp/physical.c @@ -1017,6 +1017,7 @@ physical_Open(struct physical *p) p->fd = STDIN_FILENO; for (h = 0; h < NDEVICES && p->handler == NULL && p->fd >= 0; h++) p->handler = (*devices[h].create)(p); + close(STDOUT_FILENO); if (p->fd >= 0) { if (p->handler == NULL) { physical_SetupStack(p, "unknown", PHYSICAL_NOFORCE); From 953e1b6c8dd0750128311fadc88be85a0fb44c31 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 27 Aug 2009 16:34:04 +0000 Subject: [PATCH 0133/2592] MFC 196520: Tweak the way that the ACPI and ISA bus drivers match hint devices to BIOS-enumerated devices: - Assume a device is a match if the memory and I/O ports match even if the IRQ or DRQ is wrong or missing. Some BIOSes don't include an IRQ for the atrtc device for example. - Add a hack to better match floppy controller devices. Many BIOSes do not include the starting port of the floppy controller listed in the hints (0x3f0) in the resources for the device. So far, however, all the BIOS variations encountered do include the 'port + 2' resource (0x3f2), so adjust the matching for "fdc" devices to look for 'port + 2'. Approved by: re (kib) --- sys/dev/acpica/acpi.c | 20 ++++++++++++++++++-- sys/isa/isahint.c | 27 +++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 63f95d3eb2c..a2e58833d25 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -1014,14 +1014,27 @@ acpi_hint_device_unit(device_t acdev, device_t child, const char *name, continue; /* - * Check for matching resources. We must have at least one, - * and all resources specified have to match. + * Check for matching resources. We must have at least one match. + * Since I/O and memory resources cannot be shared, if we get a + * match on either of those, ignore any mismatches in IRQs or DRQs. * * XXX: We may want to revisit this to be more lenient and wire * as long as it gets one match. */ matches = 0; if (resource_long_value(name, unit, "port", &value) == 0) { + /* + * Floppy drive controllers are notorious for having a + * wide variety of resources not all of which include the + * first port that is specified by the hint (typically + * 0x3f0) (see the comment above fdc_isa_alloc_resources() + * in fdc_isa.c). However, they do all seem to include + * port + 2 (e.g. 0x3f2) so for a floppy device, look for + * 'value + 2' in the port resources instead of the hint + * value. + */ + if (strcmp(name, "fdc") == 0) + value += 2; if (acpi_match_resource_hint(child, SYS_RES_IOPORT, value)) matches++; else @@ -1033,6 +1046,8 @@ acpi_hint_device_unit(device_t acdev, device_t child, const char *name, else continue; } + if (matches > 0) + goto matched; if (resource_long_value(name, unit, "irq", &value) == 0) { if (acpi_match_resource_hint(child, SYS_RES_IRQ, value)) matches++; @@ -1046,6 +1061,7 @@ acpi_hint_device_unit(device_t acdev, device_t child, const char *name, continue; } + matched: if (matches > 0) { /* We have a winner! */ *unitp = unit; diff --git a/sys/isa/isahint.c b/sys/isa/isahint.c index e2ce6a4d30b..5eccef85949 100644 --- a/sys/isa/isahint.c +++ b/sys/isa/isahint.c @@ -118,14 +118,30 @@ isa_hint_device_unit(device_t bus, device_t child, const char *name, int *unitp) continue; /* - * Check for matching resources. We must have at least one, - * and all resources specified have to match. + * Check for matching resources. We must have at + * least one match. Since I/O and memory resources + * cannot be shared, if we get a match on either of + * those, ignore any mismatches in IRQs or DRQs. * - * XXX: We may want to revisit this to be more lenient and wire - * as long as it gets one match. + * XXX: We may want to revisit this to be more lenient + * and wire as long as it gets one match. */ matches = 0; if (resource_long_value(name, unit, "port", &value) == 0) { + /* + * Floppy drive controllers are notorious for + * having a wide variety of resources not all + * of which include the first port that is + * specified by the hint (typically 0x3f0) + * (see the comment above + * fdc_isa_alloc_resources() in fdc_isa.c). + * However, they do all seem to include port + + * 2 (e.g. 0x3f2) so for a floppy device, look + * for 'value + 2' in the port resources + * instead of the hint value. + */ + if (strcmp(name, "fdc") == 0) + value += 2; if (isa_match_resource_hint(child, SYS_RES_IOPORT, value)) matches++; @@ -139,6 +155,8 @@ isa_hint_device_unit(device_t bus, device_t child, const char *name, int *unitp) else continue; } + if (matches > 0) + goto matched; if (resource_long_value(name, unit, "irq", &value) == 0) { if (isa_match_resource_hint(child, SYS_RES_IRQ, value)) matches++; @@ -152,6 +170,7 @@ isa_hint_device_unit(device_t bus, device_t child, const char *name, int *unitp) continue; } + matched: if (matches > 0) { /* We have a winner! */ *unitp = unit; From 862ab0643e6ce1d808976208338ddcb603640a7f Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 27 Aug 2009 17:16:23 +0000 Subject: [PATCH 0134/2592] MFC 196521: Fix a few issues with the lib32 dist so that it includes ldd32. - Use a better find invocation to purge empty directories from all the dist trees during a release build. The previous version did not purge directories whose contents were all empty directories. - Explicitly blacklist a few files from the lib32 dist instead of using a whitelist. A better longterm solution is to fix the few offenders to not install data files during a lib32 install. Approved by: re (kib) --- release/Makefile | 2 +- release/scripts/lib32-make.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/release/Makefile b/release/Makefile index 9a0bed4d31f..7ab12405662 100644 --- a/release/Makefile +++ b/release/Makefile @@ -696,7 +696,7 @@ release.5: # Remove all the directories we don't need. -cd ${RD}/trees && \ (find ${OTHER_DISTS} -path '*/var/empty' | xargs chflags noschg; \ - find ${OTHER_DISTS} -depth -type d -empty -print | xargs rmdir) + find ${OTHER_DISTS} -depth -type d -empty -delete) touch ${.TARGET} # diff --git a/release/scripts/lib32-make.sh b/release/scripts/lib32-make.sh index 37e16d4c719..99bbee4172e 100644 --- a/release/scripts/lib32-make.sh +++ b/release/scripts/lib32-make.sh @@ -5,4 +5,4 @@ # Clean the dust. cd ${RD}/trees/lib32 && \ - find . ! -path '*/libexec/*' ! -path '*/usr/lib32/*' -delete + find . '(' -path '*/usr/share/*' -or -path '*/usr/lib/*' ')' -delete From 6f0ccdbcb377edcb3228c5cf9263106e9c9aae3e Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 27 Aug 2009 17:25:58 +0000 Subject: [PATCH 0135/2592] MFC 196522: Invoke the recently added mm-mtree.sh release script to store a pre-built mergemaster mtree database in the 'base' dist. Approved by: re (kib) --- release/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/release/Makefile b/release/Makefile index 7ab12405662..3fa3c8db762 100644 --- a/release/Makefile +++ b/release/Makefile @@ -646,6 +646,7 @@ release.2: cd ${.CURDIR}/.. && ${CROSSMAKE} distrib-dirs DESTDIR=${RD}/trees/base cd ${.CURDIR}/.. && ${CROSSMAKE} ${WORLD_FLAGS} distributeworld \ DISTDIR=${RD}/trees + sh ${.CURDIR}/scripts/mm-mtree.sh -F "${CROSSENV}" -D "${RD}/trees/base" touch ${.TARGET} # Make and install the generic kernel(s). From ac63e409c2ace3a3ca1a228dac1b904d986ee625 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Thu, 27 Aug 2009 17:34:13 +0000 Subject: [PATCH 0136/2592] MFC r196512: Fix handling of .note.ABI-tag section for GNU systems [1]. Handle GNU/Linux according to LSB Core Specification 4.0, Chapter 11. Object Format, 11.8. ABI note tag. Also check the first word of desc, not only name, according to glibc abi-tags specification to distinguish between Linux and kFreeBSD. Add explicit handling for Debian GNU/kFreeBSD, which runs on our kernels as well [2]. In {amd64,i386}/trap.c, when checking osrel of the current process, also check the ABI to not change the signal behaviour for Linux binary processes, now that we save an osrel version for all three from the lists above in struct proc [2]. These changes make it possible to run FreeBSD, Debian GNU/kFreeBSD and Linux binaries on the same machine again for at least i386 and amd64, and no longer break kFreeBSD which was detected as GNU(/Linux). PR: kern/135468 Submitted by: dchagin [1] (initial patch) Suggested by: kib [2] Tested by: Petr Salinger (Petr.Salinger seznam.cz) for kFreeBSD Reviewed by: kib Approved by: re (kensmith) --- sys/amd64/amd64/elf_machdep.c | 17 +++++++++ sys/amd64/amd64/trap.c | 4 +- sys/amd64/linux32/linux32_sysvec.c | 35 ++++++++++++++--- sys/compat/ia32/ia32_sysvec.c | 15 ++++++++ sys/i386/i386/elf_machdep.c | 16 ++++++++ sys/i386/i386/trap.c | 4 +- sys/i386/linux/linux_sysvec.c | 35 ++++++++++++++--- sys/kern/imgact_elf.c | 60 +++++++++++++++++++++++++++--- sys/sys/imgact_elf.h | 6 ++- 9 files changed, 173 insertions(+), 19 deletions(-) diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index c5e19cff797..ea48b252feb 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -108,6 +109,22 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf64_insert_brand_entry, &freebsd_brand_oinfo); +static Elf64_Brandinfo kfreebsd_brand_info = { + .brand = ELFOSABI_FREEBSD, + .machine = EM_X86_64, + .compat_3_brand = "FreeBSD", + .emul_path = NULL, + .interp_path = "/lib/ld-kfreebsd-x86-64.so.1", + .sysvec = &elf64_freebsd_sysvec, + .interp_newpath = NULL, + .brand_note = &elf64_kfreebsd_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE +}; + +SYSINIT(kelf64, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t) elf64_insert_brand_entry, + &kfreebsd_brand_info); + void elf64_dump_thread(struct thread *td __unused, void *dst __unused, diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 323e8d1677a..65f761eaa4a 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -409,7 +409,9 @@ trap(struct trapframe *frame) * This check also covers the images * without the ABI-tag ELF note. */ - if (p->p_osrel >= 700004) { + if (SV_CURPROC_ABI() == + SV_ABI_FREEBSD && + p->p_osrel >= 700004) { i = SIGSEGV; ucode = SEGV_ACCERR; } else { diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 77186a1d37d..54a04eea581 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -127,6 +127,7 @@ static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); static void exec_linux_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings); static void linux32_fixlimit(struct rlimit *rl, int which); +static boolean_t linux32_trans_osrel(const Elf_Note *note, int32_t *osrel); static eventhandler_tag linux_exit_tag; static eventhandler_tag linux_schedtail_tag; @@ -1066,14 +1067,38 @@ struct sysentvec elf_linux_sysvec = { .sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32 }; -static char GNULINUX_ABI_VENDOR[] = "GNU"; +static char GNU_ABI_VENDOR[] = "GNU"; +static int GNULINUX_ABI_DESC = 0; + +static boolean_t +linux32_trans_osrel(const Elf_Note *note, int32_t *osrel) +{ + const Elf32_Word *desc; + uintptr_t p; + + p = (uintptr_t)(note + 1); + p += roundup2(note->n_namesz, sizeof(Elf32_Addr)); + + desc = (const Elf32_Word *)p; + if (desc[0] != GNULINUX_ABI_DESC) + return (FALSE); + + /* + * For linux we encode osrel as follows (see linux_mib.c): + * VVVMMMIII (version, major, minor), see linux_mib.c. + */ + *osrel = desc[1] * 1000000 + desc[2] * 1000 + desc[3]; + + return (TRUE); +} static Elf_Brandnote linux32_brandnote = { - .hdr.n_namesz = sizeof(GNULINUX_ABI_VENDOR), - .hdr.n_descsz = 16, + .hdr.n_namesz = sizeof(GNU_ABI_VENDOR), + .hdr.n_descsz = 16, /* XXX at least 16 */ .hdr.n_type = 1, - .vendor = GNULINUX_ABI_VENDOR, - .flags = 0 + .vendor = GNU_ABI_VENDOR, + .flags = BN_TRANSLATE_OSREL, + .trans_osrel = linux32_trans_osrel }; static Elf32_Brandinfo linux_brand = { diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index af8168e909d..5c2c571f113 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -172,6 +172,21 @@ SYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf32_insert_brand_entry, &ia32_brand_oinfo); +static Elf32_Brandinfo kia32_brand_info = { + .brand = ELFOSABI_FREEBSD, + .machine = EM_386, + .compat_3_brand = "FreeBSD", + .emul_path = NULL, + .interp_path = "/lib/ld.so.1", + .sysvec = &ia32_freebsd_sysvec, + .brand_note = &elf32_kfreebsd_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE +}; + +SYSINIT(kia32, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t) elf32_insert_brand_entry, + &kia32_brand_info); + void elf32_dump_thread(struct thread *td __unused, void *dst __unused, diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index b68a73ec3e6..a4ff9e2160b 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c @@ -108,6 +108,22 @@ SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_oinfo); +static Elf32_Brandinfo kfreebsd_brand_info = { + .brand = ELFOSABI_FREEBSD, + .machine = EM_386, + .compat_3_brand = "FreeBSD", + .emul_path = NULL, + .interp_path = "/lib/ld.so.1", + .sysvec = &elf32_freebsd_sysvec, + .interp_newpath = NULL, + .brand_note = &elf32_kfreebsd_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE +}; + +SYSINIT(kelf32, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t) elf32_insert_brand_entry, + &kfreebsd_brand_info); + void elf32_dump_thread(struct thread *td __unused, void *dst __unused, diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 354d791c6f4..f7064f04a53 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -423,7 +423,9 @@ trap(struct trapframe *frame) * This check also covers the images * without the ABI-tag ELF note. */ - if (p->p_osrel >= 700004) { + if (SV_CURPROC_ABI() == + SV_ABI_FREEBSD && + p->p_osrel >= 700004) { i = SIGSEGV; ucode = SEGV_ACCERR; } else { diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 186e14c421f..d07f65563d3 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -108,6 +108,7 @@ static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); static void exec_linux_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings); static register_t *linux_copyout_strings(struct image_params *imgp); +static boolean_t linux_trans_osrel(const Elf_Note *note, int32_t *osrel); static int linux_szplatform; const char *linux_platform; @@ -1027,14 +1028,38 @@ struct sysentvec elf_linux_sysvec = { .sv_flags = SV_ABI_LINUX | SV_IA32 | SV_ILP32 }; -static char GNULINUX_ABI_VENDOR[] = "GNU"; +static char GNU_ABI_VENDOR[] = "GNU"; +static int GNULINUX_ABI_DESC = 0; + +static boolean_t +linux_trans_osrel(const Elf_Note *note, int32_t *osrel) +{ + const Elf32_Word *desc; + uintptr_t p; + + p = (uintptr_t)(note + 1); + p += roundup2(note->n_namesz, sizeof(Elf32_Addr)); + + desc = (const Elf32_Word *)p; + if (desc[0] != GNULINUX_ABI_DESC) + return (FALSE); + + /* + * For linux we encode osrel as follows (see linux_mib.c): + * VVVMMMIII (version, major, minor), see linux_mib.c. + */ + *osrel = desc[1] * 1000000 + desc[2] * 1000 + desc[3]; + + return (TRUE); +} static Elf_Brandnote linux_brandnote = { - .hdr.n_namesz = sizeof(GNULINUX_ABI_VENDOR), - .hdr.n_descsz = 16, + .hdr.n_namesz = sizeof(GNU_ABI_VENDOR), + .hdr.n_descsz = 16, /* XXX at least 16 */ .hdr.n_type = 1, - .vendor = GNULINUX_ABI_VENDOR, - .flags = 0 + .vendor = GNU_ABI_VENDOR, + .flags = BN_TRANSLATE_OSREL, + .trans_osrel = linux_trans_osrel }; static Elf32_Brandinfo linux_brand = { diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index e2c0a12cb54..68035239136 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -86,6 +86,9 @@ static int __elfN(load_section)(struct vmspace *vmspace, vm_object_t object, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot, size_t pagesize); static int __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp); +static boolean_t __elfN(freebsd_trans_osrel)(const Elf_Note *note, + int32_t *osrel); +static boolean_t kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel); static boolean_t __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *checknote, int32_t *osrel); @@ -116,9 +119,56 @@ Elf_Brandnote __elfN(freebsd_brandnote) = { .hdr.n_descsz = sizeof(int32_t), .hdr.n_type = 1, .vendor = FREEBSD_ABI_VENDOR, - .flags = BN_CAN_FETCH_OSREL + .flags = BN_TRANSLATE_OSREL, + .trans_osrel = __elfN(freebsd_trans_osrel) }; +static boolean_t +__elfN(freebsd_trans_osrel)(const Elf_Note *note, int32_t *osrel) +{ + uintptr_t p; + + p = (uintptr_t)(note + 1); + p += roundup2(note->n_namesz, sizeof(Elf32_Addr)); + *osrel = *(const int32_t *)(p); + + return (TRUE); +} + +static const char GNU_ABI_VENDOR[] = "GNU"; +static int GNU_KFREEBSD_ABI_DESC = 3; + +Elf_Brandnote __elfN(kfreebsd_brandnote) = { + .hdr.n_namesz = sizeof(GNU_ABI_VENDOR), + .hdr.n_descsz = 16, /* XXX at least 16 */ + .hdr.n_type = 1, + .vendor = GNU_ABI_VENDOR, + .flags = BN_TRANSLATE_OSREL, + .trans_osrel = kfreebsd_trans_osrel +}; + +static boolean_t +kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel) +{ + const Elf32_Word *desc; + uintptr_t p; + + p = (uintptr_t)(note + 1); + p += roundup2(note->n_namesz, sizeof(Elf32_Addr)); + + desc = (const Elf32_Word *)p; + if (desc[0] != GNU_KFREEBSD_ABI_DESC) + return (FALSE); + + /* + * Debian GNU/kFreeBSD embed the earliest compatible kernel version + * (__FreeBSD_version: Rxx) in the LSB way. + */ + *osrel = desc[1] * 100000 + desc[2] * 1000 + desc[3]; + + return (TRUE); +} + int __elfN(insert_brand_entry)(Elf_Brandinfo *entry) { @@ -1371,11 +1421,9 @@ __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *checknote, * Fetch the osreldate for binary * from the ELF OSABI-note if necessary. */ - if ((checknote->flags & BN_CAN_FETCH_OSREL) != 0 && - osrel != NULL) - *osrel = *(const int32_t *) (note_name + - roundup2(checknote->hdr.n_namesz, - sizeof(Elf32_Addr))); + if ((checknote->flags & BN_TRANSLATE_OSREL) != 0 && + checknote->trans_osrel != NULL) + return (checknote->trans_osrel(note, osrel)); return (TRUE); nextnote: diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h index 60979d96f12..3eecf85000b 100644 --- a/sys/sys/imgact_elf.h +++ b/sys/sys/imgact_elf.h @@ -58,7 +58,10 @@ typedef struct { Elf_Note hdr; const char * vendor; int flags; -#define BN_CAN_FETCH_OSREL 0x0001 + boolean_t (*trans_osrel)(const Elf_Note *, int32_t *); +#define BN_CAN_FETCH_OSREL 0x0001 /* Deprecated. */ +#define BN_TRANSLATE_OSREL 0x0002 /* Use trans_osrel fetch osrel after */ + /* checking ABI contraint if needed. */ } Elf_Brandnote; typedef struct { @@ -91,6 +94,7 @@ void __elfN(dump_thread)(struct thread *, void *, size_t *); extern int __elfN(fallback_brand); extern Elf_Brandnote __elfN(freebsd_brandnote); +extern Elf_Brandnote __elfN(kfreebsd_brandnote); #endif /* _KERNEL */ #endif /* !_SYS_IMGACT_ELF_H_ */ From 4bff593a8cbc3a59759e590be960df1ade80fd62 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Thu, 27 Aug 2009 17:53:25 +0000 Subject: [PATCH 0137/2592] MFC 196589: In the loop through the list of interfaces in network6_interface_setup() rtsol_interface gets reset to "yes" each time through the loop, but rtsol_available does not. If a user has lo0 first in their list of interfaces rtsol_available will get set to "no" the first time through the loop and subsequent interfaces will not get rtsol'ed when they should. Therefore change the conditional for the is_wired() test to _interface. Approved by: re (kib) --- etc/network.subr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/network.subr b/etc/network.subr index c14985473e9..c0934174716 100644 --- a/etc/network.subr +++ b/etc/network.subr @@ -872,8 +872,8 @@ network6_interface_setup() # Wireless NIC cards are virtualized through the wlan interface if ! is_wired_interface ${i}; then case "${i}" in - wlan*) rtsol_available=yes ;; - *) rtsol_available=no ;; + wlan*) rtsol_interface=yes ;; + *) rtsol_interface=no ;; esac fi From 2025af696e46e0e8eb3a7474ad1c23abbea7c182 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Fri, 28 Aug 2009 10:25:26 +0000 Subject: [PATCH 0138/2592] MFC r196508: Our implementation of granpt(3) could be valid in the future. When I wrote the pseudo-terminal driver for the MPSAFE TTY code, Robert Watson and I agreed the best way to implement this, would be to let posix_openpt() create a pseudo-terminal with proper permissions in place and let grantpt() and unlockpt() be no-ops. This isn't valid behaviour when looking at the spec. Because I thought it was an elegant solution, I filed a bug report at the Austin Group about this. In their last teleconference, they agreed on this subject. This means that future revisions of POSIX may allow grantpt() and unlockpt() to be no-ops if an open() on /dev/ptmx (if the implementation has such a device) and posix_openpt() already do the right thing. I'd rather put this in the manpage, because simply mentioning we don't comply to any standard makes it look worse than it is. Right now we don't, but at least we took care of it. Approved by: re (kib) --- lib/libc/stdlib/ptsname.3 | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/libc/stdlib/ptsname.3 b/lib/libc/stdlib/ptsname.3 index bfa36473ce2..f674a54bd90 100644 --- a/lib/libc/stdlib/ptsname.3 +++ b/lib/libc/stdlib/ptsname.3 @@ -134,14 +134,22 @@ The slave pseudo-terminal device could not be accessed. The .Fn ptsname function conforms to -.St -p1003.1-2001 . +.St -p1003.1-2008 . .Pp This implementation of .Fn grantpt and .Fn unlockpt -does not comply with any standard, because these functions assume the -pseudo-terminal has the correct attributes upon creation. +does not conform to +.St -p1003.1-2008 , +because it depends on +.Xr posix_openpt 2 +to create the pseudo-terminal device with proper permissions in place. +It only validates whether +.Fa fildes +is a valid pseudo-terminal master device. +Future revisions of the specification will likely allow this behaviour, +as stated by the Austin Group. .Sh HISTORY The .Fn grantpt , @@ -150,15 +158,3 @@ and .Fn unlockpt functions appeared in .Fx 5.0 . -.Sh NOTES -The purpose of the -.Fn grantpt -and -.Fn unlockpt -functions has no meaning in -.Fx , -because pseudo-terminals obtained by -.Xr posix_openpt 2 -are created on demand. -Because these devices are created with proper permissions in place, they -are guaranteed to be unused by unprivileged processes. From 83b5def49ae24e2599ca2a0316aa1c4ff33d9221 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 28 Aug 2009 17:34:22 +0000 Subject: [PATCH 0139/2592] MFC r196516: Add RTL8168DP/RTL8111DP device id. While I'm here append "8111D" to the description of RTL8168D as RL_HWREV_8168D can be either RTL8168D or RTL8111D. PR: kern/137672 Approved by: re (kib) --- sys/dev/re/if_re.c | 8 +++++--- sys/pci/if_rlreg.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index 0fc2e899b3d..5a5790d0c25 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -174,8 +174,8 @@ static struct rl_type re_devs[] = { { RT_VENDORID, RT_DEVICEID_8101E, 0, "RealTek 8101E/8102E/8102EL PCIe 10/100baseTX" }, { RT_VENDORID, RT_DEVICEID_8168, 0, - "RealTek 8168/8168B/8168C/8168CP/8168D/8111B/8111C/8111CP PCIe " - "Gigabit Ethernet" }, + "RealTek 8168/8168B/8168C/8168CP/8168D/8168DP/" + "8111B/8111C/8111CP/8111DP PCIe Gigabit Ethernet" }, { RT_VENDORID, RT_DEVICEID_8169, 0, "RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" }, { RT_VENDORID, RT_DEVICEID_8169SC, 0, @@ -217,7 +217,8 @@ static struct rl_hwrev re_hwrevs[] = { { RL_HWREV_8168C, RL_8169, "8168C/8111C"}, { RL_HWREV_8168C_SPIN2, RL_8169, "8168C/8111C"}, { RL_HWREV_8168CP, RL_8169, "8168CP/8111CP"}, - { RL_HWREV_8168D, RL_8169, "8168D"}, + { RL_HWREV_8168D, RL_8169, "8168D/8111D"}, + { RL_HWREV_8168DP, RL_8169, "8168DP/8111DP"}, { 0, 0, NULL } }; @@ -1282,6 +1283,7 @@ re_attach(device_t dev) /* FALLTHROUGH */ case RL_HWREV_8168CP: case RL_HWREV_8168D: + case RL_HWREV_8168DP: sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD; diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h index 9de350c9d9d..d112d024c5a 100644 --- a/sys/pci/if_rlreg.h +++ b/sys/pci/if_rlreg.h @@ -161,6 +161,7 @@ #define RL_HWREV_8102EL 0x24800000 #define RL_HWREV_8102EL_SPIN1 0x24c00000 #define RL_HWREV_8168D 0x28000000 +#define RL_HWREV_8168DP 0x28800000 #define RL_HWREV_8168_SPIN1 0x30000000 #define RL_HWREV_8100E 0x30800000 #define RL_HWREV_8101E 0x34000000 From 180e7945c70b5a7d6d29559026c7c675a01ff138 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 28 Aug 2009 18:01:37 +0000 Subject: [PATCH 0140/2592] MFC r196517: Don't try to power down PHY when alc(4) failed to map the device. This fixes system crash when mapping alc(4) device failed in device attach. Reported by: Jim < stapleton.41 <> gmail DOT com > Approved by: re (kib) --- sys/dev/alc/if_alc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c index f3483b7747c..a53af779b03 100644 --- a/sys/dev/alc/if_alc.c +++ b/sys/dev/alc/if_alc.c @@ -858,7 +858,8 @@ alc_detach(device_t dev) sc->alc_intrhand[i] = NULL; } } - alc_phy_down(sc); + if (sc->alc_res[0] != NULL) + alc_phy_down(sc); bus_release_resources(dev, sc->alc_irq_spec, sc->alc_irq); if ((sc->alc_flags & (ALC_FLAG_MSI | ALC_FLAG_MSIX)) != 0) pci_release_msi(dev); From 939af5009a22b96dc39f560f472fcc3a0f471a7e Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 28 Aug 2009 19:08:56 +0000 Subject: [PATCH 0141/2592] MFC r196501: When registering a protocol to an existing protocol domain via pf_proto_register(), iterate over all existing vnets to call protosw_init() and thus the appropriate .pr_init() handler in the context of each vnet. NB in the future we probably want to separate pr_init() handlers into two, i.e. per-vnet and global, functions. This change has no impact on nooptions VIMAGE builds. Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- sys/kern/uipc_domain.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 257e9fae775..0d5043e3ee7 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -336,6 +336,7 @@ found: int pf_proto_register(int family, struct protosw *npr) { + VNET_ITERATOR_DECL(vnet_iter); struct domain *dp; struct protosw *pr, *fpr; @@ -391,7 +392,13 @@ found: mtx_unlock(&dom_mtx); /* Initialize and activate the protocol. */ - protosw_init(fpr); + VNET_LIST_RLOCK(); + VNET_FOREACH(vnet_iter) { + CURVNET_SET_QUIET(vnet_iter); + protosw_init(fpr); + CURVNET_RESTORE(); + } + VNET_LIST_RUNLOCK(); return (0); } From f04e871efcfb91a08aff48caab81c66459e26cc5 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 28 Aug 2009 19:10:58 +0000 Subject: [PATCH 0142/2592] MFC r196502: Introduce a div_destroy() function which takes over per-vnet cleanup tasks from the existing modevent / MOD_UNLOAD handler, and register div_destroy() in protosw as per-vnet .pr_destroy() handler for options VIMAGE builds. In nooptions VIMAGE builds, div_destroy() will be invoked from the modevent handler, resulting in effectively identical operation as it was prior this change. div_destroy() also tears down hashtables used by ipdivert, which were previously left behind on ipdivert kldunloads. For options VIMAGE builds only, temporarily disable kldunloading of ipdivert, because without introducing additional locking logic it is impossible to atomically check whether all ipdivert instances in all vnets are idle, and proceed with cleanup without opening a race window for a vnet to open an ipdivert socket while ipdivert tear-down is in progress. While here, staticize div_init(), because it is not used outside of ip_divert.c. In cooperation with: julian Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- sys/netinet/ip_divert.c | 35 ++++++++++++++++++++++++++++++----- sys/netinet/ip_divert.h | 1 - 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 31059e9acd7..401c0908de5 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -125,6 +125,8 @@ static VNET_DEFINE(struct inpcbinfo, divcbinfo); static u_long div_sendspace = DIVSNDQ; /* XXX sysctl ? */ static u_long div_recvspace = DIVRCVQ; /* XXX sysctl ? */ +static eventhandler_tag ip_divert_event_tag; + /* * Initialize divert connection block queue. */ @@ -152,7 +154,7 @@ div_inpcb_fini(void *mem, int size) INP_LOCK_DESTROY(inp); } -void +static void div_init(void) { @@ -174,8 +176,17 @@ div_init(void) NULL, NULL, div_inpcb_init, div_inpcb_fini, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); uma_zone_set_max(V_divcbinfo.ipi_zone, maxsockets); - EVENTHANDLER_REGISTER(maxsockets_change, div_zone_change, - NULL, EVENTHANDLER_PRI_ANY); +} + +static void +div_destroy(void) +{ + + INP_INFO_LOCK_DESTROY(&V_divcbinfo); + uma_zdestroy(V_divcbinfo.ipi_zone); + hashdestroy(V_divcbinfo.ipi_hashbase, M_PCB, V_divcbinfo.ipi_hashmask); + hashdestroy(V_divcbinfo.ipi_porthashbase, M_PCB, + V_divcbinfo.ipi_porthashmask); } /* @@ -709,6 +720,9 @@ struct protosw div_protosw = { .pr_ctlinput = div_ctlinput, .pr_ctloutput = ip_ctloutput, .pr_init = div_init, +#ifdef VIMAGE + .pr_destroy = div_destroy, +#endif .pr_usrreqs = &div_usrreqs }; @@ -716,7 +730,9 @@ static int div_modevent(module_t mod, int type, void *unused) { int err = 0; +#ifndef VIMAGE int n; +#endif switch (type) { case MOD_LOAD: @@ -726,7 +742,11 @@ div_modevent(module_t mod, int type, void *unused) * a true IP protocol that goes over the wire. */ err = pf_proto_register(PF_INET, &div_protosw); + if (err != 0) + return (err); ip_divert_ptr = divert_packet; + ip_divert_event_tag = EVENTHANDLER_REGISTER(maxsockets_change, + div_zone_change, NULL, EVENTHANDLER_PRI_ANY); break; case MOD_QUIESCE: /* @@ -737,6 +757,10 @@ div_modevent(module_t mod, int type, void *unused) err = EPERM; break; case MOD_UNLOAD: +#ifdef VIMAGE + err = EPERM; + break; +#else /* * Forced unload. * @@ -758,9 +782,10 @@ div_modevent(module_t mod, int type, void *unused) ip_divert_ptr = NULL; err = pf_proto_unregister(PF_INET, IPPROTO_DIVERT, SOCK_RAW); INP_INFO_WUNLOCK(&V_divcbinfo); - INP_INFO_LOCK_DESTROY(&V_divcbinfo); - uma_zdestroy(V_divcbinfo.ipi_zone); + div_destroy(); + EVENTHANDLER_DEREGISTER(maxsockets_change, ip_divert_event_tag); break; +#endif /* !VIMAGE */ default: err = EOPNOTSUPP; break; diff --git a/sys/netinet/ip_divert.h b/sys/netinet/ip_divert.h index 1bb09447b23..50363554982 100644 --- a/sys/netinet/ip_divert.h +++ b/sys/netinet/ip_divert.h @@ -83,7 +83,6 @@ divert_find_info(struct mbuf *m) typedef void ip_divert_packet_t(struct mbuf *m, int incoming); extern ip_divert_packet_t *ip_divert_ptr; -extern void div_init(void); extern void div_input(struct mbuf *, int); extern void div_ctlinput(int, struct sockaddr *, void *); #endif /* _NETINET_IP_DIVERT_H_ */ From 83864c810e8cc8b15500cdca55de7a962040b7ea Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 28 Aug 2009 19:12:44 +0000 Subject: [PATCH 0143/2592] MFC r196503: Fix NFS panics with options VIMAGE kernels by apropriately setting curvnet context inside the RPC code. Temporarily set td's cred to mount's cred before calling socreate() via __rpc_nconf2socket(). Submitted by: rmacklem (in part) Reviewed by: rmacklem, rwatson Discussed with: dfr, bz Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- sys/fs/nfsclient/nfs_clvnops.c | 4 ++-- sys/nfsclient/nfs_vnops.c | 3 +++ sys/rpc/clnt_dg.c | 5 +++++ sys/rpc/clnt_rc.c | 5 +++-- sys/rpc/clnt_vc.c | 9 ++++++++- sys/rpc/rpc_generic.c | 10 +++++++++- sys/rpc/svc_dg.c | 6 ++++++ sys/rpc/svc_generic.c | 7 +++++++ sys/rpc/svc_vc.c | 21 ++++++++++++++++++--- 9 files changed, 61 insertions(+), 9 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 219c62e8c2f..5dc3a593458 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1405,8 +1405,8 @@ again: } mtx_unlock(&dnp->n_mtx); - CURVNET_SET(P_TO_VNET(&proc0)); #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; @@ -1415,9 +1415,9 @@ again: cverf.lval[0] = create_verf; #ifdef INET IN_IFADDR_RUNLOCK(); + CURVNET_RESTORE(); #endif cverf.lval[1] = ++create_verf; - CURVNET_RESTORE(); 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); diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 165849b399f..7dfd298da6d 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1552,6 +1553,7 @@ again: *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); tl = nfsm_build(u_int32_t *, NFSX_V3CREATEVERF); #ifdef INET + CURVNET_SET(CRED_TO_VNET(cnp->cn_cred)); IN_IFADDR_RLOCK(); if (!TAILQ_EMPTY(&V_in_ifaddrhead)) *tl++ = IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr.s_addr; @@ -1560,6 +1562,7 @@ again: *tl++ = create_verf; #ifdef INET IN_IFADDR_RUNLOCK(); + CURVNET_RESTORE(); #endif *tl = ++create_verf; } else { diff --git a/sys/rpc/clnt_dg.c b/sys/rpc/clnt_dg.c index 0b49375b993..78f4a9a2128 100644 --- a/sys/rpc/clnt_dg.c +++ b/sys/rpc/clnt_dg.c @@ -57,6 +57,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include @@ -197,11 +199,14 @@ clnt_dg_create( return (NULL); } + CURVNET_SET(so->so_vnet); if (!__rpc_socket2sockinfo(so, &si)) { rpc_createerr.cf_stat = RPC_TLIERROR; rpc_createerr.cf_error.re_errno = 0; + CURVNET_RESTORE(); return (NULL); } + CURVNET_RESTORE(); /* * Find the receive and the send size diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c index 217608c4bb3..24fc09a3605 100644 --- a/sys/rpc/clnt_rc.c +++ b/sys/rpc/clnt_rc.c @@ -175,15 +175,16 @@ clnt_reconnect_connect(CLIENT *cl) rc->rc_connecting = TRUE; mtx_unlock(&rc->rc_lock); + oldcred = td->td_ucred; + td->td_ucred = rc->rc_ucred; so = __rpc_nconf2socket(rc->rc_nconf); if (!so) { stat = rpc_createerr.cf_stat = RPC_TLIERROR; rpc_createerr.cf_error.re_errno = 0; + td->td_ucred = oldcred; goto out; } - oldcred = td->td_ucred; - td->td_ucred = rc->rc_ucred; if (rc->rc_privport) bindresvport(so, NULL); diff --git a/sys/rpc/clnt_vc.c b/sys/rpc/clnt_vc.c index 3f15c435c75..85e89abe5c3 100644 --- a/sys/rpc/clnt_vc.c +++ b/sys/rpc/clnt_vc.c @@ -70,6 +70,9 @@ __FBSDID("$FreeBSD$"); #include #include #include + +#include + #include #include @@ -217,8 +220,11 @@ clnt_vc_create( } } - if (!__rpc_socket2sockinfo(so, &si)) + CURVNET_SET(so->so_vnet); + if (!__rpc_socket2sockinfo(so, &si)) { + CURVNET_RESTORE(); goto err; + } if (so->so_proto->pr_flags & PR_CONNREQUIRED) { bzero(&sopt, sizeof(sopt)); @@ -239,6 +245,7 @@ clnt_vc_create( sopt.sopt_valsize = sizeof(one); sosetopt(so, &sopt); } + CURVNET_RESTORE(); ct->ct_closeit = FALSE; diff --git a/sys/rpc/rpc_generic.c b/sys/rpc/rpc_generic.c index d9100b340b1..f15ad28f294 100644 --- a/sys/rpc/rpc_generic.c +++ b/sys/rpc/rpc_generic.c @@ -56,6 +56,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include @@ -822,6 +824,7 @@ bindresvport(struct socket *so, struct sockaddr *sa) sa->sa_len = salen; if (*portp == 0) { + CURVNET_SET(so->so_vnet); bzero(&opt, sizeof(opt)); opt.sopt_dir = SOPT_GET; opt.sopt_level = proto; @@ -829,12 +832,15 @@ bindresvport(struct socket *so, struct sockaddr *sa) opt.sopt_val = &old; opt.sopt_valsize = sizeof(old); error = sogetopt(so, &opt); - if (error) + if (error) { + CURVNET_RESTORE(); goto out; + } opt.sopt_dir = SOPT_SET; opt.sopt_val = &portlow; error = sosetopt(so, &opt); + CURVNET_RESTORE(); if (error) goto out; } @@ -845,7 +851,9 @@ bindresvport(struct socket *so, struct sockaddr *sa) if (error) { opt.sopt_dir = SOPT_SET; opt.sopt_val = &old; + CURVNET_SET(so->so_vnet); sosetopt(so, &opt); + CURVNET_RESTORE(); } } out: diff --git a/sys/rpc/svc_dg.c b/sys/rpc/svc_dg.c index 0747d1d9639..9d7696b0145 100644 --- a/sys/rpc/svc_dg.c +++ b/sys/rpc/svc_dg.c @@ -57,6 +57,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include @@ -101,8 +103,10 @@ svc_dg_create(SVCPOOL *pool, struct socket *so, size_t sendsize, struct sockaddr* sa; int error; + CURVNET_SET(so->so_vnet); if (!__rpc_socket2sockinfo(so, &si)) { printf(svc_dg_str, svc_dg_err1); + CURVNET_RESTORE(); return (NULL); } /* @@ -112,6 +116,7 @@ svc_dg_create(SVCPOOL *pool, struct socket *so, size_t sendsize, recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize); if ((sendsize == 0) || (recvsize == 0)) { printf(svc_dg_str, svc_dg_err2); + CURVNET_RESTORE(); return (NULL); } @@ -124,6 +129,7 @@ svc_dg_create(SVCPOOL *pool, struct socket *so, size_t sendsize, xprt->xp_ops = &svc_dg_ops; error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + CURVNET_RESTORE(); if (error) goto freedata; diff --git a/sys/rpc/svc_generic.c b/sys/rpc/svc_generic.c index 38380f25def..e6e8acdb1d9 100644 --- a/sys/rpc/svc_generic.c +++ b/sys/rpc/svc_generic.c @@ -60,6 +60,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include #include @@ -228,11 +230,14 @@ svc_tli_create( /* * It is an open socket. Get the transport info. */ + CURVNET_SET(so->so_vnet); if (!__rpc_socket2sockinfo(so, &si)) { printf( "svc_tli_create: could not get transport information\n"); + CURVNET_RESTORE(); return (NULL); } + CURVNET_RESTORE(); } /* @@ -259,7 +264,9 @@ svc_tli_create( "svc_tli_create: could not bind to requested address\n"); goto freedata; } + CURVNET_SET(so->so_vnet); solisten(so, (int)bindaddr->qlen, curthread); + CURVNET_RESTORE(); } } diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c index b7da5e22787..85d335fa015 100644 --- a/sys/rpc/svc_vc.c +++ b/sys/rpc/svc_vc.c @@ -58,6 +58,9 @@ __FBSDID("$FreeBSD$"); #include #include #include + +#include + #include #include @@ -151,9 +154,12 @@ svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize, xprt->xp_p2 = NULL; xprt->xp_ops = &svc_vc_rendezvous_ops; + CURVNET_SET(so->so_vnet); error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); - if (error) + if (error) { + CURVNET_RESTORE(); goto cleanup_svc_vc_create; + } memcpy(&xprt->xp_ltaddr, sa, sa->sa_len); free(sa, M_SONAME); @@ -161,6 +167,7 @@ svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize, xprt_register(xprt); solisten(so, SOMAXCONN, curthread); + CURVNET_RESTORE(); SOCKBUF_LOCK(&so->so_rcv); xprt->xp_upcallset = 1; @@ -193,9 +200,12 @@ svc_vc_create_conn(SVCPOOL *pool, struct socket *so, struct sockaddr *raddr) opt.sopt_name = SO_KEEPALIVE; opt.sopt_val = &one; opt.sopt_valsize = sizeof(one); + CURVNET_SET(so->so_vnet); error = sosetopt(so, &opt); - if (error) + if (error) { + CURVNET_RESTORE(); return (NULL); + } if (so->so_proto->pr_protocol == IPPROTO_TCP) { bzero(&opt, sizeof(struct sockopt)); @@ -205,9 +215,12 @@ svc_vc_create_conn(SVCPOOL *pool, struct socket *so, struct sockaddr *raddr) opt.sopt_val = &one; opt.sopt_valsize = sizeof(one); error = sosetopt(so, &opt); - if (error) + if (error) { + CURVNET_RESTORE(); return (NULL); + } } + CURVNET_RESTORE(); cd = mem_alloc(sizeof(*cd)); cd->strm_stat = XPRT_IDLE; @@ -625,8 +638,10 @@ svc_vc_recv(SVCXPRT *xprt, struct rpc_msg *msg, uio.uio_td = curthread; m = NULL; rcvflag = MSG_DONTWAIT; + CURVNET_SET(xprt->xp_socket->so_vnet); error = soreceive(xprt->xp_socket, NULL, &uio, &m, NULL, &rcvflag); + CURVNET_RESTORE(); if (error == EWOULDBLOCK) { /* From 61268392e18b9a5a333da934f1954b8c755a5459 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 28 Aug 2009 19:15:17 +0000 Subject: [PATCH 0144/2592] MFC r196505: When "jail -c vnet" request fails, the current code actually creates and leaves behind an orphaned vnet. This change ensures that such vnets get released. This change affects only options VIMAGE builds. Submitted by: jamie Discussed with: bz Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- sys/kern/kern_jail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 8f185833e8a..892d2111bed 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -2456,7 +2456,7 @@ prison_deref(struct prison *pr, int flags) sx_downgrade(&allprison_lock); #ifdef VIMAGE - if (pr->pr_flags & PR_VNET) + if (pr->pr_vnet != ppr->pr_vnet) vnet_destroy(pr->pr_vnet); #endif if (pr->pr_root != NULL) { From d6976e0558a7468c02ba5c8aedea468adf2a0eca Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 28 Aug 2009 19:18:20 +0000 Subject: [PATCH 0145/2592] MFC r196504: When moving ifnets from one vnet to another, and the ifnet has ifaddresses of AF_LINK type which thus have an embedded if_index "backpointer", we must update that if_index backpointer to reflect the new if_index that our ifnet just got assigned. This change affects only options VIMAGE builds. Submitted by: bz Reviewed by: bz Approved by: re (rwatson), julian (mentor) Approved by: re (rwatson) --- sys/net/if.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sys/net/if.c b/sys/net/if.c index 5d108981cdd..e42dddfadad 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -570,6 +570,21 @@ if_attach_internal(struct ifnet *ifp, int vmove) /* Reliably crash if used uninitialized. */ ifp->if_broadcastaddr = NULL; } +#ifdef VIMAGE + else { + /* + * Update the interface index in the link layer address + * of the interface. + */ + for (ifa = ifp->if_addr; ifa != NULL; + ifa = TAILQ_NEXT(ifa, ifa_link)) { + if (ifa->ifa_addr->sa_family == AF_LINK) { + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + sdl->sdl_index = ifp->if_index; + } + } + } +#endif IFNET_WLOCK(); TAILQ_INSERT_TAIL(&V_ifnet, ifp, if_link); From c291f85f32d4af82e41ff8f6fcaea7593d70df5f Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 28 Aug 2009 19:48:06 +0000 Subject: [PATCH 0146/2592] MFC r196525: Consider flag == 0 as the same of flag == R_NEXT. This change will restore a historical behavior that has been changed by revision 190491, and has seen to break exim. Approved by: re (kib) --- lib/libc/db/hash/hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c index b58b36f1fc3..83d26577740 100644 --- a/lib/libc/db/hash/hash.c +++ b/lib/libc/db/hash/hash.c @@ -711,7 +711,7 @@ hash_seq(const DB *dbp, DBT *key, DBT *data, u_int32_t flag) hashp->cndx = 1; hashp->cpage = NULL; } - next_bucket: +next_bucket: for (bp = NULL; !bp || !bp[0]; ) { if (!(bufp = hashp->cpage)) { for (bucket = hashp->cbucket; @@ -732,7 +732,7 @@ hash_seq(const DB *dbp, DBT *key, DBT *data, u_int32_t flag) } } else { bp = (u_int16_t *)hashp->cpage->page; - if (flag == R_NEXT) { + if (flag == R_NEXT || flag == 0) { hashp->cndx += 2; if (hashp->cndx > bp[0]) { hashp->cpage = NULL; From 3ef94f2b72ac17700f8de8b8fb8d403d15c56da6 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 28 Aug 2009 20:06:02 +0000 Subject: [PATCH 0147/2592] Merge r196481 from head to stable/8: Rework global locks for interface list and index management, correcting several critical bugs, including race conditions and lock order issues: Replace the single rwlock, ifnet_lock, with two locks, an rwlock and an sxlock. Either can be held to stablize the lists and indexes, but both are required to write. This allows the list to be held stable in both network interrupt contexts and sleepable user threads across sleeping memory allocations or device driver interactions. As before, writes to the interface list must occur from sleepable contexts. Reviewed by: bz, julian Approved by: re (kib) --- sys/compat/linux/linux_ioctl.c | 10 ++-- sys/contrib/altq/altq/altq_subr.c | 8 +-- sys/kern/kern_uuid.c | 6 +- sys/net/bridgestp.c | 4 +- sys/net/if.c | 94 +++++++++++++++++++------------ sys/net/if_llatbl.c | 8 +-- sys/net/if_var.h | 42 +++++++++++--- sys/net/if_vlan.c | 4 +- sys/netgraph/ng_gif.c | 4 +- sys/netinet/in.c | 7 +-- sys/netinet6/icmp6.c | 12 ++-- sys/netinet6/in6.c | 11 +--- sys/netinet6/in6_ifattach.c | 6 +- sys/netinet6/nd6.c | 4 +- sys/netipsec/xform_ipip.c | 8 +-- sys/nfsclient/bootp_subr.c | 2 +- 16 files changed, 133 insertions(+), 97 deletions(-) diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 11dc6d5041b..03ac3340749 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -2061,22 +2061,20 @@ linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen) struct ifnet *ifscan; int ethno; + IFNET_RLOCK_ASSERT(); + /* Short-circuit non ethernet interfaces */ if (!IFP_IS_ETH(ifp)) return (strlcpy(buffer, ifp->if_xname, buflen)); /* Determine the (relative) unit number for ethernet interfaces */ ethno = 0; - IFNET_RLOCK(); TAILQ_FOREACH(ifscan, &V_ifnet, if_link) { - if (ifscan == ifp) { - IFNET_RUNLOCK(); + if (ifscan == ifp) return (snprintf(buffer, buflen, "eth%d", ethno)); - } if (IFP_IS_ETH(ifscan)) ethno++; } - IFNET_RUNLOCK(); return (0); } @@ -2177,7 +2175,7 @@ again: valid_len = 0; /* Return all AF_INET addresses of all interfaces */ - IFNET_RLOCK(); /* could sleep XXX */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { int addrs = 0; diff --git a/sys/contrib/altq/altq/altq_subr.c b/sys/contrib/altq/altq/altq_subr.c index 32107e57d36..edacc0d4b1e 100644 --- a/sys/contrib/altq/altq/altq_subr.c +++ b/sys/contrib/altq/altq/altq_subr.c @@ -462,8 +462,8 @@ tbr_timeout(arg) s = splimp(); #endif #if defined(__FreeBSD__) && (__FreeBSD_version >= 500000) - IFNET_RLOCK(); - VNET_LIST_RLOCK(); + IFNET_RLOCK_NOSLEEP(); + VNET_LIST_RLOCK_NOSLEEP(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); #endif @@ -480,8 +480,8 @@ tbr_timeout(arg) #if defined(__FreeBSD__) && (__FreeBSD_version >= 500000) CURVNET_RESTORE(); } - VNET_LIST_RUNLOCK(); - IFNET_RUNLOCK(); + VNET_LIST_RUNLOCK_NOSLEEP(); + IFNET_RUNLOCK_NOSLEEP(); #endif splx(s); if (active > 0) diff --git a/sys/kern/kern_uuid.c b/sys/kern/kern_uuid.c index 5b61ca416ee..8c083f4e109 100644 --- a/sys/kern/kern_uuid.c +++ b/sys/kern/kern_uuid.c @@ -95,7 +95,7 @@ uuid_node(uint16_t *node) int i; CURVNET_SET(TD_TO_VNET(curthread)); - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { /* Walk the address list */ IF_ADDR_LOCK(ifp); @@ -106,14 +106,14 @@ uuid_node(uint16_t *node) /* Got a MAC address. */ bcopy(LLADDR(sdl), node, UUID_NODE_LEN); IF_ADDR_UNLOCK(ifp); - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); CURVNET_RESTORE(); return; } } IF_ADDR_UNLOCK(ifp); } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); for (i = 0; i < (UUID_NODE_LEN>>1); i++) node[i] = (uint16_t)arc4random(); diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c index 3e65113c2d5..2993838ac68 100644 --- a/sys/net/bridgestp.c +++ b/sys/net/bridgestp.c @@ -2019,7 +2019,7 @@ bstp_reinit(struct bstp_state *bs) * not need to be part of the bridge, it just needs to be a unique * value. */ - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_type != IFT_ETHER) continue; @@ -2036,7 +2036,7 @@ bstp_reinit(struct bstp_state *bs) continue; } } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); if (LIST_EMPTY(&bs->bs_bplist) || mif == NULL) { /* Set the bridge and root id (lower bits) to zero */ diff --git a/sys/net/if.c b/sys/net/if.c index e42dddfadad..a1155cd2acc 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -154,14 +154,26 @@ VNET_DEFINE(struct ifgrouphead, ifg_head); VNET_DEFINE(int, if_index); static VNET_DEFINE(int, if_indexlim) = 8; -/* Table of ifnet by index. Locked with ifnet_lock. */ +/* Table of ifnet by index. */ static VNET_DEFINE(struct ifindex_entry *, ifindex_table); #define V_if_indexlim VNET(if_indexlim) #define V_ifindex_table VNET(ifindex_table) int ifqmaxlen = IFQ_MAXLEN; -struct rwlock ifnet_lock; + +/* + * The global network interface list (V_ifnet) and related state (such as + * if_index, if_indexlim, and ifindex_table) are protected by an sxlock and + * an rwlock. Either may be acquired shared to stablize the list, but both + * must be acquired writable to modify the list. This model allows us to + * both stablize the interface list during interrupt thread processing, but + * also to stablize it over long-running ioctls, without introducing priority + * inversions and deadlocks. + */ +struct rwlock ifnet_rwlock; +struct sx ifnet_sxlock; + static if_com_alloc_t *if_com_alloc[256]; static if_com_free_t *if_com_free[256]; @@ -188,9 +200,9 @@ ifnet_byindex(u_short idx) { struct ifnet *ifp; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); ifp = ifnet_byindex_locked(idx); - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (ifp); } @@ -199,19 +211,19 @@ ifnet_byindex_ref(u_short idx) { struct ifnet *ifp; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); ifp = ifnet_byindex_locked(idx); if (ifp == NULL || (ifp->if_flags & IFF_DYING)) { - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (NULL); } if_ref(ifp); - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (ifp); } static void -ifnet_setbyindex(u_short idx, struct ifnet *ifp) +ifnet_setbyindex_locked(u_short idx, struct ifnet *ifp) { IFNET_WLOCK_ASSERT(); @@ -219,16 +231,25 @@ ifnet_setbyindex(u_short idx, struct ifnet *ifp) V_ifindex_table[idx].ife_ifnet = ifp; } +static void +ifnet_setbyindex(u_short idx, struct ifnet *ifp) +{ + + IFNET_WLOCK(); + ifnet_setbyindex_locked(idx, ifp); + IFNET_WUNLOCK(); +} + struct ifaddr * ifaddr_byindex(u_short idx) { struct ifaddr *ifa; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); ifa = ifnet_byindex_locked(idx)->if_addr; if (ifa != NULL) ifa_ref(ifa); - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (ifa); } @@ -361,9 +382,7 @@ if_alloc(u_char type) ifq_init(&ifp->if_snd, ifp); refcount_init(&ifp->if_refcount, 1); /* Index reference. */ - IFNET_WLOCK(); ifnet_setbyindex(ifp->if_index, ifp); - IFNET_WUNLOCK(); return (ifp); } @@ -383,7 +402,7 @@ if_free_internal(struct ifnet *ifp) KASSERT(ifp == ifnet_byindex_locked(ifp->if_index), ("%s: freeing unallocated ifnet", ifp->if_xname)); - ifnet_setbyindex(ifp->if_index, NULL); + ifnet_setbyindex_locked(ifp->if_index, NULL); while (V_if_index > 0 && ifnet_byindex_locked(V_if_index) == NULL) V_if_index--; IFNET_WUNLOCK(); @@ -870,11 +889,14 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet) if_detach_internal(ifp, 1); /* - * Unlink the ifnet from ifindex_table[] in current vnet, - * and shrink the if_index for that vnet if possible. + * Unlink the ifnet from ifindex_table[] in current vnet, and shrink + * the if_index for that vnet if possible. + * + * NOTE: IFNET_WLOCK/IFNET_WUNLOCK() are assumed to be unvirtualized, + * or we'd lock on one vnet and unlock on another. */ IFNET_WLOCK(); - ifnet_setbyindex(ifp->if_index, NULL); + ifnet_setbyindex_locked(ifp->if_index, NULL); while (V_if_index > 0 && ifnet_byindex_locked(V_if_index) == NULL) V_if_index--; IFNET_WUNLOCK(); @@ -901,7 +923,7 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet) V_if_index = ifp->if_index; if (V_if_index >= V_if_indexlim) if_grow(); - ifnet_setbyindex(ifp->if_index, ifp); + ifnet_setbyindex_locked(ifp->if_index, ifp); IFNET_WUNLOCK(); if_attach_internal(ifp, 1); @@ -1383,7 +1405,7 @@ ifa_ifwithaddr_internal(struct sockaddr *addr, int getref) struct ifnet *ifp; struct ifaddr *ifa; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -1410,7 +1432,7 @@ ifa_ifwithaddr_internal(struct sockaddr *addr, int getref) } ifa = NULL; done: - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (ifa); } @@ -1438,7 +1460,7 @@ ifa_ifwithbroadaddr(struct sockaddr *addr) struct ifnet *ifp; struct ifaddr *ifa; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -1457,7 +1479,7 @@ ifa_ifwithbroadaddr(struct sockaddr *addr) } ifa = NULL; done: - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (ifa); } @@ -1471,7 +1493,7 @@ ifa_ifwithdstaddr(struct sockaddr *addr) struct ifnet *ifp; struct ifaddr *ifa; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if ((ifp->if_flags & IFF_POINTOPOINT) == 0) continue; @@ -1490,7 +1512,7 @@ ifa_ifwithdstaddr(struct sockaddr *addr) } ifa = NULL; done: - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (ifa); } @@ -1523,7 +1545,7 @@ ifa_ifwithnet(struct sockaddr *addr) * we find one, as we release the IF_ADDR_LOCK() that kept it stable * when we move onto the next interface. */ - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -1599,7 +1621,7 @@ next: continue; ifa = ifa_maybe; ifa_maybe = NULL; done: - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); if (ifa_maybe != NULL) ifa_free(ifa_maybe); return (ifa); @@ -1878,7 +1900,7 @@ if_slowtimo(void *arg) int s = splimp(); VNET_LIST_RLOCK_NOSLEEP(); - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { @@ -1889,7 +1911,7 @@ if_slowtimo(void *arg) } CURVNET_RESTORE(); } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); VNET_LIST_RUNLOCK_NOSLEEP(); splx(s); timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); @@ -1904,7 +1926,7 @@ ifunit_ref(const char *name) { struct ifnet *ifp; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (strncmp(name, ifp->if_xname, IFNAMSIZ) == 0 && !(ifp->if_flags & IFF_DYING)) @@ -1912,7 +1934,7 @@ ifunit_ref(const char *name) } if (ifp != NULL) if_ref(ifp); - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (ifp); } @@ -1921,12 +1943,12 @@ ifunit(const char *name) { struct ifnet *ifp; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (strncmp(name, ifp->if_xname, IFNAMSIZ) == 0) break; } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (ifp); } @@ -2536,7 +2558,7 @@ again: max_len = 0; valid_len = 0; - IFNET_RLOCK(); /* could sleep XXX */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { int addrs; @@ -2861,13 +2883,13 @@ if_delmulti(struct ifnet *ifp, struct sockaddr *sa) #ifdef INVARIANTS struct ifnet *oifp; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(oifp, &V_ifnet, if_link) if (ifp == oifp) break; if (ifp != oifp) ifp = NULL; - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); KASSERT(ifp != NULL, ("%s: ifnet went away", __func__)); #endif @@ -2910,7 +2932,7 @@ if_delmulti_ifma(struct ifmultiaddr *ifma) } else { struct ifnet *oifp; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(oifp, &V_ifnet, if_link) if (ifp == oifp) break; @@ -2918,7 +2940,7 @@ if_delmulti_ifma(struct ifmultiaddr *ifma) printf("%s: ifnet %p disappeared\n", __func__, ifp); ifp = NULL; } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); } #endif /* diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index a1b574f9f37..a3617f50d65 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -200,14 +200,14 @@ lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask) { struct lltable *llt; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); SLIST_FOREACH(llt, &lltables, llt_link) { if (llt->llt_af != af) continue; llt->llt_prefix_free(llt, prefix, mask); } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); } @@ -300,13 +300,13 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info) } /* XXX linked list may be too expensive */ - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); SLIST_FOREACH(llt, &lltables, llt_link) { if (llt->llt_af == dst->sa_family && llt->llt_ifp == ifp) break; } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n")); if (flags && LLE_CREATE) diff --git a/sys/net/if_var.h b/sys/net/if_var.h index aa83161cce3..0bfd9f19a8a 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -85,6 +85,7 @@ struct vnet; #include /* XXX */ #include /* XXX */ #include /* XXX */ +#include /* XXX */ #include /* XXX */ #include @@ -754,14 +755,39 @@ struct ifmultiaddr { #ifdef _KERNEL -extern struct rwlock ifnet_lock; -#define IFNET_LOCK_INIT() \ - rw_init_flags(&ifnet_lock, "ifnet", RW_RECURSE) -#define IFNET_WLOCK() rw_wlock(&ifnet_lock) -#define IFNET_WUNLOCK() rw_wunlock(&ifnet_lock) -#define IFNET_WLOCK_ASSERT() rw_assert(&ifnet_lock, RA_LOCKED) -#define IFNET_RLOCK() rw_rlock(&ifnet_lock) -#define IFNET_RUNLOCK() rw_runlock(&ifnet_lock) +extern struct rwlock ifnet_rwlock; +extern struct sx ifnet_sxlock; + +#define IFNET_LOCK_INIT() do { \ + rw_init_flags(&ifnet_rwlock, "ifnet_rw", RW_RECURSE); \ + sx_init_flags(&ifnet_sxlock, "ifnet_sx", SX_RECURSE); \ +} while(0) + +#define IFNET_WLOCK() do { \ + sx_xlock(&ifnet_sxlock); \ + rw_wlock(&ifnet_rwlock); \ +} while (0) + +#define IFNET_WUNLOCK() do { \ + rw_wunlock(&ifnet_rwlock); \ + sx_xunlock(&ifnet_sxlock); \ +} while (0) + +/* + * To assert the ifnet lock, you must know not only whether it's for read or + * write, but also whether it was acquired with sleep support or not. + */ +#define IFNET_RLOCK_ASSERT() sx_assert(&ifnet_sxlock, SA_SLOCKED) +#define IFNET_RLOCK_NOSLEEP_ASSERT() rw_assert(&ifnet_rwlock, RA_RLOCKED) +#define IFNET_WLOCK_ASSERT() do { \ + sx_assert(&ifnet_sxlock, SA_XLOCKED); \ + rw_assert(&ifnet_rwlock, RA_WLOCKED); \ +} while (0) + +#define IFNET_RLOCK() sx_slock(&ifnet_sxlock) +#define IFNET_RLOCK_NOSLEEP() rw_rlock(&ifnet_rwlock) +#define IFNET_RUNLOCK() sx_sunlock(&ifnet_sxlock) +#define IFNET_RUNLOCK_NOSLEEP() rw_runlock(&ifnet_rwlock) /* * Look up an ifnet given its index; the _ref variant also acquires a diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 04c2c0dc644..126d83ffb35 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -580,7 +580,7 @@ vlan_clone_match_ethertag(struct if_clone *ifc, const char *name, int *tag) int t = 0; /* Check for . style interface names. */ - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_type != IFT_ETHER) continue; @@ -598,7 +598,7 @@ vlan_clone_match_ethertag(struct if_clone *ifc, const char *name, int *tag) *tag = t; break; } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (ifp); } diff --git a/sys/netgraph/ng_gif.c b/sys/netgraph/ng_gif.c index ccff05a92d0..1790cbd91e5 100644 --- a/sys/netgraph/ng_gif.c +++ b/sys/netgraph/ng_gif.c @@ -560,7 +560,7 @@ ng_gif_mod_event(module_t mod, int event, void *data) ng_gif_input_orphan_p = ng_gif_input_orphan; /* Create nodes for any already-existing gif interfaces */ - VNET_LIST_RLOCK_NOSLEEP(); + VNET_LIST_RLOCK(); IFNET_RLOCK(); VNET_FOREACH(vnet_iter) { CURVNET_SET_QUIET(vnet_iter); /* XXX revisit quiet */ @@ -571,7 +571,7 @@ ng_gif_mod_event(module_t mod, int event, void *data) CURVNET_RESTORE(); } IFNET_RUNLOCK(); - VNET_LIST_RUNLOCK_NOSLEEP(); + VNET_LIST_RUNLOCK(); break; case MOD_UNLOAD: diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 15d38b191b5..8c9984c1c62 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1407,12 +1407,7 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr) } arpc; int error, i; - /* XXXXX - * current IFNET_RLOCK() is mapped to IFNET_WLOCK() - * so it is okay to use this ASSERT, change it when - * IFNET lock is finalized - */ - IFNET_WLOCK_ASSERT(); + IFNET_RLOCK_ASSERT(); error = 0; for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) { diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 7fe63b603cf..6f13c692d0c 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1705,7 +1705,7 @@ ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp, } } - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); for (ifp = TAILQ_FIRST(&V_ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { addrsofif = 0; IF_ADDR_LOCK(ifp); @@ -1762,13 +1762,13 @@ ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp, IF_ADDR_UNLOCK(ifp); if (iffound) { *ifpp = ifp; - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (addrsofif); } addrs += addrsofif; } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (addrs); } @@ -1789,7 +1789,7 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL)) return (0); /* needless to copy */ - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); again: for (; ifp; ifp = TAILQ_NEXT(ifp, if_list)) { @@ -1854,7 +1854,7 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, * Set the truncate flag and return. */ nni6->ni_flags |= NI_NODEADDR_FLAG_TRUNCATE; - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (copied); } @@ -1907,7 +1907,7 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, goto again; } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (copied); } diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index c4333ed60a6..7d9f7e7620a 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2234,7 +2234,7 @@ in6_setmaxmtu(void) unsigned long maxmtu = 0; struct ifnet *ifp; - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); for (ifp = TAILQ_FIRST(&V_ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { /* this function can be called during ifnet initialization */ @@ -2244,7 +2244,7 @@ in6_setmaxmtu(void) IN6_LINKMTU(ifp) > maxmtu) maxmtu = IN6_LINKMTU(ifp); } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); if (maxmtu) /* update only when maxmtu is positive */ V_in6_maxmtu = maxmtu; } @@ -2495,12 +2495,7 @@ in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr) } ndpc; int i, error; - /* XXXXX - * current IFNET_RLOCK() is mapped to IFNET_WLOCK() - * so it is okay to use this ASSERT, change it when - * IFNET lock is finalized - */ - IFNET_WLOCK_ASSERT(); + IFNET_RLOCK_ASSERT(); error = 0; for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) { diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 1fc54c62793..6f9f11dbd33 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -398,7 +398,7 @@ get_ifid(struct ifnet *ifp0, struct ifnet *altifp, } /* next, try to get it from some other hardware interface */ - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); for (ifp = V_ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) { if (ifp == ifp0) continue; @@ -413,11 +413,11 @@ get_ifid(struct ifnet *ifp0, struct ifnet *altifp, nd6log((LOG_DEBUG, "%s: borrow interface identifier from %s\n", if_name(ifp0), if_name(ifp))); - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); goto success; } } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); /* last resort: get from random number source */ if (get_rand_ifid(ifp, in6) == 0) { diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 48635c5b548..acaa87e63a3 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1662,7 +1662,7 @@ nd6_slowtimo(void *arg) callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, nd6_slowtimo, curvnet); - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); for (ifp = TAILQ_FIRST(&V_ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { nd6if = ND_IFINFO(ifp); @@ -1678,7 +1678,7 @@ nd6_slowtimo(void *arg) nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable); } } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); CURVNET_RESTORE(); } diff --git a/sys/netipsec/xform_ipip.c b/sys/netipsec/xform_ipip.c index c9669b16bc2..78ab0978c4a 100644 --- a/sys/netipsec/xform_ipip.c +++ b/sys/netipsec/xform_ipip.c @@ -303,7 +303,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) if ((m->m_pkthdr.rcvif == NULL || !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) && V_ipip_allow != 2) { - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { #ifdef INET @@ -318,7 +318,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) ipo->ip_src.s_addr) { V_ipipstat.ipips_spoof++; m_freem(m); - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return; } } @@ -335,7 +335,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_src)) { V_ipipstat.ipips_spoof++; m_freem(m); - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return; } @@ -343,7 +343,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) #endif /* INET6 */ } } - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); } /* Statistics */ diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index e1096bed2a0..e57b32a1bed 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -389,7 +389,7 @@ bootpboot_p_iflist(void) struct ifaddr *ifa; printf("Interface list:\n"); - IFNET_RLOCK(); /* could sleep, but okay for debugging XXX */ + IFNET_RLOCK(); for (ifp = TAILQ_FIRST(&V_ifnet); ifp != NULL; ifp = TAILQ_NEXT(ifp, if_link)) { From 1b257b0e920f016c571d95a82f734ee76252d098 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 28 Aug 2009 20:07:38 +0000 Subject: [PATCH 0148/2592] Merge r196482 from head to stable/8: Rather than using IFNET_RLOCK() when iterating over (and modifying) the ifnet list during if_ef load, directly acquire the ifnet_sxlock exclusively. That way when if_alloc() recurses the lock, it's a write recursion rather than a read->write recursion. This code structure is arguably a bug, so add a comment indicating that this is the case. Post-8.0, we should fix this, but this commit resolves panic-on-load for if_ef. Discussed with: bz, julian Reported by: phk Approved by: re (kib) --- sys/net/if_ef.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sys/net/if_ef.c b/sys/net/if_ef.c index 7a5fca916d7..2af3a177204 100644 --- a/sys/net/if_ef.c +++ b/sys/net/if_ef.c @@ -492,7 +492,20 @@ ef_load(void) VNET_LIST_RLOCK(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); - IFNET_RLOCK(); + + /* + * XXXRW: The following loop walks the ifnet list while + * modifying it, something not well-supported by ifnet + * locking. To avoid lock upgrade/recursion issues, manually + * acquire a write lock of ifnet_sxlock here, rather than a + * read lock, so that when if_alloc() recurses the lock, we + * don't panic. This structure, in which if_ef automatically + * attaches to all ethernet interfaces, should be replaced + * with a model like that found in if_vlan, in which + * interfaces are explicitly configured, which would avoid + * this (and other) problems. + */ + sx_xlock(&ifnet_sxlock); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_type != IFT_ETHER) continue; EFDEBUG("Found interface %s\n", ifp->if_xname); @@ -523,7 +536,7 @@ ef_load(void) efcount++; SLIST_INSERT_HEAD(&efdev, efl, el_next); } - IFNET_RUNLOCK(); + sx_xunlock(&ifnet_sxlock); CURVNET_RESTORE(); } VNET_LIST_RUNLOCK(); From f2b31d19098b6ede7e4f306bf7e2b66660e9cfbf Mon Sep 17 00:00:00 2001 From: Max Laier Date: Fri, 28 Aug 2009 20:26:00 +0000 Subject: [PATCH 0149/2592] MFC r196551: Fix argument ordering to memcpy as well as the size of the copy in the (theoretical) case that pfi_buffer_cnt should be greater than ~_max. Submitted by: pjd Reviewed by: {krw,sthen,markus}@openbsd.org Approved by: re (kib) --- sys/contrib/pf/net/pf_if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/contrib/pf/net/pf_if.c b/sys/contrib/pf/net/pf_if.c index a78a5452532..156fb22a731 100644 --- a/sys/contrib/pf/net/pf_if.c +++ b/sys/contrib/pf/net/pf_if.c @@ -663,7 +663,7 @@ pfi_address_add(struct sockaddr *sa, int af, int net) "(%d/%d)\n", pfi_buffer_cnt, PFI_BUFFER_MAX); return; } - memcpy(pfi_buffer, p, pfi_buffer_cnt * sizeof(*pfi_buffer)); + memcpy(p, pfi_buffer, pfi_buffer_max * sizeof(*pfi_buffer)); /* no need to zero buffer */ free(pfi_buffer, PFI_MTYPE); pfi_buffer = p; From b569420afa62cbb3ee432f36dfe298611040b692 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 28 Aug 2009 21:07:43 +0000 Subject: [PATCH 0150/2592] Merge r196510 from head to stable/8: Make if_grow static -- it's not used outside of if.c, and with the internals destined to change, it's better if it remains that way. Approved by: re (kib) --- sys/net/if.c | 3 ++- sys/net/if_var.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index a1155cd2acc..6433168895d 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -124,6 +124,7 @@ static void if_attachdomain1(struct ifnet *); static int ifconf(u_long, caddr_t); static void if_freemulti(struct ifmultiaddr *); static void if_init(void *); +static void if_grow(void); static void if_check(void *); static void if_route(struct ifnet *, int flag, int fam); static int if_setflag(struct ifnet *, int, int, int *, int); @@ -297,7 +298,7 @@ VNET_SYSUNINIT(vnet_if_uninit, SI_SUB_INIT_IF, SI_ORDER_FIRST, vnet_if_uninit, NULL); #endif -void +static void if_grow(void) { u_int n; diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 0bfd9f19a8a..3ab620816a4 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -826,7 +826,6 @@ int if_allmulti(struct ifnet *, int); struct ifnet* if_alloc(u_char); void if_attach(struct ifnet *); void if_dead(struct ifnet *); -void if_grow(void); int if_delmulti(struct ifnet *, struct sockaddr *); void if_delmulti_ifma(struct ifmultiaddr *); void if_detach(struct ifnet *); From a0021692f235d51755e711da2d88a2fc715e0ed3 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 28 Aug 2009 21:10:26 +0000 Subject: [PATCH 0151/2592] Merge r196535 from head to stable/8: Use locks specific to the lltable code, rather than borrow the ifnet list/index locks, to protect link layer address tables. This avoids lock order issues during interface teardown, but maintains the bug that sysctl copy routines may be called while a non-sleepable lock is held. Reviewed by: bz, kmacy, qingli Approved by: re (kib) --- sys/net/if_llatbl.c | 29 +++++++++++++++-------------- sys/net/if_llatbl.h | 7 +++++++ sys/netinet/in.c | 2 +- sys/netinet6/in6.c | 2 +- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index a3617f50d65..b66d6e154b2 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -62,6 +62,9 @@ static SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables); extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *, u_char *); +struct rwlock lltable_rwlock; +RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock"); + /* * Dump arp state for a specific address family. */ @@ -71,7 +74,7 @@ lltable_sysctl_dumparp(int af, struct sysctl_req *wr) struct lltable *llt; int error = 0; - IFNET_RLOCK(); + LLTABLE_RLOCK(); SLIST_FOREACH(llt, &lltables, llt_link) { if (llt->llt_af == af) { error = llt->llt_dump(llt, wr); @@ -80,7 +83,7 @@ lltable_sysctl_dumparp(int af, struct sysctl_req *wr) } } done: - IFNET_RUNLOCK(); + LLTABLE_RUNLOCK(); return (error); } @@ -144,8 +147,6 @@ llentry_update(struct llentry **llep, struct lltable *lt, /* * Free all entries from given table and free itself. - * Since lltables collects from all of the intefaces, - * the caller of this function must acquire IFNET_WLOCK(). */ void lltable_free(struct lltable *llt) @@ -155,9 +156,9 @@ lltable_free(struct lltable *llt) KASSERT(llt != NULL, ("%s: llt is NULL", __func__)); - IFNET_WLOCK(); + LLTABLE_WLOCK(); SLIST_REMOVE(&lltables, llt, lltable, llt_link); - IFNET_WUNLOCK(); + LLTABLE_WUNLOCK(); for (i=0; i < LLTBL_HASHTBL_SIZE; i++) { LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { @@ -178,7 +179,7 @@ lltable_drain(int af) struct llentry *lle; register int i; - IFNET_RLOCK(); + LLTABLE_RLOCK(); SLIST_FOREACH(llt, &lltables, llt_link) { if (llt->llt_af != af) continue; @@ -192,7 +193,7 @@ lltable_drain(int af) } } } - IFNET_RUNLOCK(); + LLTABLE_RUNLOCK(); } void @@ -200,14 +201,14 @@ lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask) { struct lltable *llt; - IFNET_RLOCK_NOSLEEP(); + LLTABLE_RLOCK(); SLIST_FOREACH(llt, &lltables, llt_link) { if (llt->llt_af != af) continue; llt->llt_prefix_free(llt, prefix, mask); } - IFNET_RUNLOCK_NOSLEEP(); + LLTABLE_RUNLOCK(); } @@ -230,9 +231,9 @@ lltable_init(struct ifnet *ifp, int af) for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) LIST_INIT(&llt->lle_head[i]); - IFNET_WLOCK(); + LLTABLE_WLOCK(); SLIST_INSERT_HEAD(&lltables, llt, llt_link); - IFNET_WUNLOCK(); + LLTABLE_WUNLOCK(); return (llt); } @@ -300,13 +301,13 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info) } /* XXX linked list may be too expensive */ - IFNET_RLOCK_NOSLEEP(); + LLTABLE_RLOCK(); SLIST_FOREACH(llt, &lltables, llt_link) { if (llt->llt_af == dst->sa_family && llt->llt_ifp == ifp) break; } - IFNET_RUNLOCK_NOSLEEP(); + LLTABLE_RUNLOCK(); KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n")); if (flags && LLE_CREATE) diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h index 4d721efc35f..f54c78ad8a2 100644 --- a/sys/net/if_llatbl.h +++ b/sys/net/if_llatbl.h @@ -41,6 +41,13 @@ struct rt_addrinfo; struct llentry; LIST_HEAD(llentries, llentry); +extern struct rwlock lltable_rwlock; +#define LLTABLE_RLOCK() rw_rlock(&lltable_rwlock) +#define LLTABLE_RUNLOCK() rw_runlock(&lltable_rwlock) +#define LLTABLE_WLOCK() rw_wlock(&lltable_rwlock) +#define LLTABLE_WUNLOCK() rw_wunlock(&lltable_rwlock) +#define LLTABLE_LOCK_ASSERT() rw_assert(&lltable_rwlock, RA_LOCKED) + /* * Code referencing llentry must at least hold * a shared lock diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 8c9984c1c62..203f9e6be25 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1407,7 +1407,7 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr) } arpc; int error, i; - IFNET_RLOCK_ASSERT(); + LLTABLE_LOCK_ASSERT(); error = 0; for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) { diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 7d9f7e7620a..b0b25854027 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2495,7 +2495,7 @@ in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr) } ndpc; int i, error; - IFNET_RLOCK_ASSERT(); + LLTABLE_LOCK_ASSERT(); error = 0; for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) { From 57d231bba66b55d8aab4c86e8d7654ee0877100b Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 28 Aug 2009 21:12:38 +0000 Subject: [PATCH 0152/2592] Merge r196553 from head to stable/8: Break out allocation of new ifindex values from if_alloc() and if_vmove(), and centralize in a single function ifindex_alloc(). Assert the IFNET_WLOCK, and add missing IFNET_WLOCK in if_alloc(). This does not close all known races in this code. Reviewed by: bz Approved by: re (kib) --- sys/net/if.c | 76 +++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index 6433168895d..f2f1c4f86af 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -223,6 +223,37 @@ ifnet_byindex_ref(u_short idx) return (ifp); } +/* + * Allocate an ifindex array entry; return 0 on success or an error on + * failure. + */ +static int +ifindex_alloc(u_short *idxp) +{ + u_short idx; + + IFNET_WLOCK_ASSERT(); + + /* + * Try to find an empty slot below if_index. If we fail, take the + * next slot. + */ + for (idx = 1; idx <= V_if_index; idx++) { + if (ifnet_byindex_locked(idx) == NULL) + break; + } + + /* Catch if_index overflow. */ + if (idx < 1) + return (ENOSPC); + if (idx > V_if_index) + V_if_index = idx; + if (V_if_index >= V_if_indexlim) + if_grow(); + *idxp = idx; + return (0); +} + static void ifnet_setbyindex_locked(u_short idx, struct ifnet *ifp) { @@ -335,32 +366,19 @@ struct ifnet * if_alloc(u_char type) { struct ifnet *ifp; + u_short idx; ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK|M_ZERO); - - /* - * Try to find an empty slot below if_index. If we fail, take - * the next slot. - * - * XXX: should be locked! - */ - for (ifp->if_index = 1; ifp->if_index <= V_if_index; ifp->if_index++) { - if (ifnet_byindex(ifp->if_index) == NULL) - break; - } - /* Catch if_index overflow. */ - if (ifp->if_index < 1) { + IFNET_WLOCK(); + if (ifindex_alloc(&idx) != 0) { + IFNET_WUNLOCK(); free(ifp, M_IFNET); return (NULL); } - if (ifp->if_index > V_if_index) - V_if_index = ifp->if_index; - if (V_if_index >= V_if_indexlim) - if_grow(); - + IFNET_WUNLOCK(); + ifp->if_index = idx; ifp->if_type = type; ifp->if_alloctype = type; - if (if_com_alloc[type] != NULL) { ifp->if_l2com = if_com_alloc[type](type, ifp); if (ifp->if_l2com == NULL) { @@ -882,6 +900,7 @@ if_detach_internal(struct ifnet *ifp, int vmove) void if_vmove(struct ifnet *ifp, struct vnet *new_vnet) { + u_short idx; /* * Detach from current vnet, but preserve LLADDR info, do not @@ -907,23 +926,12 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet) */ CURVNET_SET_QUIET(new_vnet); - /* - * Try to find an empty slot below if_index. If we fail, take - * the next slot. - */ IFNET_WLOCK(); - for (ifp->if_index = 1; ifp->if_index <= V_if_index; ifp->if_index++) { - if (ifnet_byindex_locked(ifp->if_index) == NULL) - break; - } - /* Catch if_index overflow. */ - if (ifp->if_index < 1) + if (ifindex_alloc(&idx) != 0) { + IFNET_WUNLOCK(); panic("if_index overflow"); - - if (ifp->if_index > V_if_index) - V_if_index = ifp->if_index; - if (V_if_index >= V_if_indexlim) - if_grow(); + } + ifp->if_index = idx; ifnet_setbyindex_locked(ifp->if_index, ifp); IFNET_WUNLOCK(); From d6f7f21cac2038a8db2a34ddd9fc2b5e01b0ce22 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 28 Aug 2009 21:14:04 +0000 Subject: [PATCH 0153/2592] Merge r196559 from head to stable/8: Add IFNET_HOLD reserved pointer value for the ifindex ifnet array, which allows an index to be reserved for an ifnet without making the ifnet available for management operations. Use this in if_alloc() while the ifnet lock is released between initial index allocation and completion of ifnet initialization. Add ifindex_free() to centralize the implementation of releasing an ifindex value. Use in if_free() and if_vmove(), as well as when releasing a held index in if_alloc(). Reviewed by: bz Approved by: re (kib) --- sys/net/if.c | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index f2f1c4f86af..36c0d037b9a 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -175,6 +175,13 @@ int ifqmaxlen = IFQ_MAXLEN; struct rwlock ifnet_rwlock; struct sx ifnet_sxlock; +/* + * The allocation of network interfaces is a rather non-atomic affair; we + * need to select an index before we are ready to expose the interface for + * use, so will use this pointer value to indicate reservation. + */ +#define IFNET_HOLD (void *)(uintptr_t)(-1) + static if_com_alloc_t *if_com_alloc[256]; static if_com_free_t *if_com_free[256]; @@ -193,6 +200,8 @@ ifnet_byindex_locked(u_short idx) if (idx > V_if_index) return (NULL); + if (V_ifindex_table[idx].ife_ifnet == IFNET_HOLD) + return (NULL); return (V_ifindex_table[idx].ife_ifnet); } @@ -228,18 +237,18 @@ ifnet_byindex_ref(u_short idx) * failure. */ static int -ifindex_alloc(u_short *idxp) +ifindex_alloc_locked(u_short *idxp) { u_short idx; IFNET_WLOCK_ASSERT(); /* - * Try to find an empty slot below if_index. If we fail, take the + * Try to find an empty slot below V_if_index. If we fail, take the * next slot. */ for (idx = 1; idx <= V_if_index; idx++) { - if (ifnet_byindex_locked(idx) == NULL) + if (V_ifindex_table[idx].ife_ifnet == NULL) break; } @@ -254,6 +263,27 @@ ifindex_alloc(u_short *idxp) return (0); } +static void +ifindex_free_locked(u_short idx) +{ + + IFNET_WLOCK_ASSERT(); + + V_ifindex_table[idx].ife_ifnet = NULL; + while (V_if_index > 0 && + V_ifindex_table[V_if_index].ife_ifnet == NULL) + V_if_index--; +} + +static void +ifindex_free(u_short idx) +{ + + IFNET_WLOCK(); + ifindex_free_locked(idx); + IFNET_WUNLOCK(); +} + static void ifnet_setbyindex_locked(u_short idx, struct ifnet *ifp) { @@ -370,11 +400,12 @@ if_alloc(u_char type) ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK|M_ZERO); IFNET_WLOCK(); - if (ifindex_alloc(&idx) != 0) { + if (ifindex_alloc_locked(&idx) != 0) { IFNET_WUNLOCK(); free(ifp, M_IFNET); return (NULL); } + ifnet_setbyindex_locked(idx, IFNET_HOLD); IFNET_WUNLOCK(); ifp->if_index = idx; ifp->if_type = type; @@ -383,6 +414,7 @@ if_alloc(u_char type) ifp->if_l2com = if_com_alloc[type](type, ifp); if (ifp->if_l2com == NULL) { free(ifp, M_IFNET); + ifindex_free(idx); return (NULL); } } @@ -421,9 +453,7 @@ if_free_internal(struct ifnet *ifp) KASSERT(ifp == ifnet_byindex_locked(ifp->if_index), ("%s: freeing unallocated ifnet", ifp->if_xname)); - ifnet_setbyindex_locked(ifp->if_index, NULL); - while (V_if_index > 0 && ifnet_byindex_locked(V_if_index) == NULL) - V_if_index--; + ifindex_free_locked(ifp->if_index); IFNET_WUNLOCK(); if (if_com_free[ifp->if_alloctype] != NULL) @@ -916,18 +946,14 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet) * or we'd lock on one vnet and unlock on another. */ IFNET_WLOCK(); - ifnet_setbyindex_locked(ifp->if_index, NULL); - while (V_if_index > 0 && ifnet_byindex_locked(V_if_index) == NULL) - V_if_index--; - IFNET_WUNLOCK(); + ifindex_free_locked(ifp->if_index); /* * Switch to the context of the target vnet. */ CURVNET_SET_QUIET(new_vnet); - IFNET_WLOCK(); - if (ifindex_alloc(&idx) != 0) { + if (ifindex_alloc_locked(&idx) != 0) { IFNET_WUNLOCK(); panic("if_index overflow"); } From 6d2e2db1a98f95d4f596e45b6fee8dec14898aa4 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Sat, 29 Aug 2009 04:15:37 +0000 Subject: [PATCH 0154/2592] MFC r196530: Document that ppp handles pipe(2) descriptors specially in -direct mode. Approved by: re (kib) --- usr.sbin/ppp/ppp.8.m4 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4 index 2fc84e4c15b..66637595029 100644 --- a/usr.sbin/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp.8.m4 @@ -27,7 +27,7 @@ changecom(,)dnl .\" .\" $FreeBSD$ .\" -.Dd May 24, 2007 +.Dd August 25, 2009 .Dt PPP 8 .Os .Sh NAME @@ -171,6 +171,17 @@ If callback is configured, will use the .Dq set device information when dialing back. +.Pp +When run in +.Fl direct +mode, +.Nm +will behave slightly differently if descriptor 0 was created by +.Xr pipe 2 . +As pipes are not bi-directional, ppp will redirect all writes to descriptor +1 (standard output), leaving only reads acting on descriptor 0. +No special action is taken if descriptor 0 was created by +.Xr socketpair 2 . .It Fl dedicated This option is designed for machines connected with a dedicated wire. @@ -6055,6 +6066,8 @@ This socket is used to pass links between different instances of .Xr tcpdump 1 , .Xr telnet 1 , .Xr kldload 2 , +.Xr pipe 2 , +.Xr socketpair 2 , ifdef({LOCALNAT},{},{.Xr libalias 3 , })dnl ifdef({LOCALRAD},{},{.Xr libradius 3 , From eb2feeeeb98675d86f98eeba7015386c5e842acc Mon Sep 17 00:00:00 2001 From: "Simon L. B. Nielsen" Date: Sat, 29 Aug 2009 15:21:50 +0000 Subject: [PATCH 0155/2592] MFC r196474: Merge DTLS fixes from vendor-crypto/openssl/dist: - Fix memory consumption bug with "future epoch" DTLS records. - Fix fragment handling memory leak. - Do not access freed data structure. - Fix DTLS fragment bug - out-of-sequence message handling which could result in NULL pointer dereference in dtls1_process_out_of_seq_message(). Note that this will not get FreeBSD Security Advisory as DTLS is experimental in OpenSSL. Security: CVE-2009-1377 CVE-2009-1378 CVE-2009-1379 CVE-2009-1387 Approved by: re (kib) --- crypto/openssl/crypto/pqueue/pqueue.c | 14 ++++++++ crypto/openssl/crypto/pqueue/pqueue.h | 1 + crypto/openssl/ssl/d1_both.c | 47 +++++++++++++++++---------- crypto/openssl/ssl/d1_pkt.c | 4 +++ 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/crypto/openssl/crypto/pqueue/pqueue.c b/crypto/openssl/crypto/pqueue/pqueue.c index 5cc18527f8d..6c89f06fb10 100644 --- a/crypto/openssl/crypto/pqueue/pqueue.c +++ b/crypto/openssl/crypto/pqueue/pqueue.c @@ -234,3 +234,17 @@ pqueue_next(pitem **item) return ret; } + +int +pqueue_size(pqueue_s *pq) +{ + pitem *item = pq->items; + int count = 0; + + while(item != NULL) + { + count++; + item = item->next; + } + return count; +} diff --git a/crypto/openssl/crypto/pqueue/pqueue.h b/crypto/openssl/crypto/pqueue/pqueue.h index 02386d130e9..16c4072681c 100644 --- a/crypto/openssl/crypto/pqueue/pqueue.h +++ b/crypto/openssl/crypto/pqueue/pqueue.h @@ -91,5 +91,6 @@ pitem *pqueue_iterator(pqueue pq); pitem *pqueue_next(piterator *iter); void pqueue_print(pqueue pq); +int pqueue_size(pqueue pq); #endif /* ! HEADER_PQUEUE_H */ diff --git a/crypto/openssl/ssl/d1_both.c b/crypto/openssl/ssl/d1_both.c index 15a201a25cf..01771921061 100644 --- a/crypto/openssl/ssl/d1_both.c +++ b/crypto/openssl/ssl/d1_both.c @@ -519,6 +519,7 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) if ( s->d1->handshake_read_seq == frag->msg_header.seq) { + unsigned long frag_len = frag->msg_header.frag_len; pqueue_pop(s->d1->buffered_messages); al=dtls1_preprocess_fragment(s,&frag->msg_header,max); @@ -536,7 +537,7 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) if (al==0) { *ok = 1; - return frag->msg_header.frag_len; + return frag_len; } ssl3_send_alert(s,SSL3_AL_FATAL,al); @@ -561,7 +562,16 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) goto err; - if (msg_hdr->seq <= s->d1->handshake_read_seq) + /* Try to find item in queue, to prevent duplicate entries */ + pq_64bit_init(&seq64); + pq_64bit_assign_word(&seq64, msg_hdr->seq); + item = pqueue_find(s->d1->buffered_messages, seq64); + pq_64bit_free(&seq64); + + /* Discard the message if sequence number was already there, is + * too far in the future or the fragment is already in the queue */ + if (msg_hdr->seq <= s->d1->handshake_read_seq || + msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL) { unsigned char devnull [256]; @@ -575,30 +585,31 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) } } - frag = dtls1_hm_fragment_new(frag_len); - if ( frag == NULL) - goto err; - - memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); - if (frag_len) - { - /* read the body of the fragment (header has already been read */ + { + frag = dtls1_hm_fragment_new(frag_len); + if ( frag == NULL) + goto err; + + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + + /* read the body of the fragment (header has already been read) */ i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, frag->fragment,frag_len,0); if (i<=0 || (unsigned long)i!=frag_len) goto err; - } - pq_64bit_init(&seq64); - pq_64bit_assign_word(&seq64, msg_hdr->seq); + pq_64bit_init(&seq64); + pq_64bit_assign_word(&seq64, msg_hdr->seq); - item = pitem_new(seq64, frag); - pq_64bit_free(&seq64); - if ( item == NULL) - goto err; + item = pitem_new(seq64, frag); + pq_64bit_free(&seq64); + if ( item == NULL) + goto err; + + pqueue_insert(s->d1->buffered_messages, item); + } - pqueue_insert(s->d1->buffered_messages, item); return DTLS1_HM_FRAGMENT_RETRY; err: diff --git a/crypto/openssl/ssl/d1_pkt.c b/crypto/openssl/ssl/d1_pkt.c index eb56cf987ba..4ae9be54ae6 100644 --- a/crypto/openssl/ssl/d1_pkt.c +++ b/crypto/openssl/ssl/d1_pkt.c @@ -167,6 +167,10 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT priority) DTLS1_RECORD_DATA *rdata; pitem *item; + /* Limit the size of the queue to prevent DOS attacks */ + if (pqueue_size(queue->q) >= 100) + return 0; + rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); item = pitem_new(priority, rdata); if (rdata == NULL || item == NULL) From 59fa5c955f9580a017801be916f92a3d22c385da Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sat, 29 Aug 2009 15:42:06 +0000 Subject: [PATCH 0156/2592] MFC r196547 It is possible for all the kthreads to exit (hci modules unloaded) which in turn ends our usb process. This means the proc pointer becomes invalid and will panic if a new kthread is added. Count the number of threads and clear the proc pointer on the last one. Approved by: re (kib) --- sys/dev/usb/usb_process.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/dev/usb/usb_process.c b/sys/dev/usb/usb_process.c index 5b98a819a8e..3b13f21c222 100644 --- a/sys/dev/usb/usb_process.c +++ b/sys/dev/usb/usb_process.c @@ -64,6 +64,7 @@ #if (__FreeBSD_version >= 800000) static struct proc *usbproc; +static int usb_pcount; #define USB_THREAD_CREATE(f, s, p, ...) \ kproc_kthread_add((f), (s), &usbproc, (p), RFHIGHPID, \ 0, "usb", __VA_ARGS__) @@ -183,6 +184,11 @@ usb_process(void *arg) up->up_ptr = NULL; cv_signal(&up->up_cv); mtx_unlock(up->up_mtx); +#if (__FreeBSD_version >= 800000) + /* Clear the proc pointer if this is the last thread. */ + if (--usb_pcount == 0) + usbproc = NULL; +#endif USB_THREAD_EXIT(0); } @@ -218,6 +224,9 @@ usb_proc_create(struct usb_process *up, struct mtx *p_mtx, up->up_ptr = NULL; goto error; } +#if (__FreeBSD_version >= 800000) + usb_pcount++; +#endif return (0); error: From 72d5a535fa15f499938dbfce3020e416aa66b95c Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 29 Aug 2009 19:45:03 +0000 Subject: [PATCH 0157/2592] MFC 196478: Prior to the dire warning about values of network_interfaces other than AUTO the biggest mistake users made was leaving lo0 off the list. Since lo0 is effectively mandatory, check for it and add it to the list if it's not there. MFC 196523: Improve the case test to detect the presence of lo0 in the list of network_interfaces. Submitted by: Christoph Mallon Approved by: re (kib) --- etc/network.subr | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/etc/network.subr b/etc/network.subr index c0934174716..e794faba2d7 100644 --- a/etc/network.subr +++ b/etc/network.subr @@ -727,6 +727,13 @@ list_net_interfaces() ;; *) _tmplist="${network_interfaces} ${cloned_interfaces}" + + # lo0 is effectively mandatory, so help prevent foot-shooting + # + case "$_tmplist" in + lo0|'lo0 '*|*' lo0'|*' lo0 '*) ;; # This is fine, do nothing + *) _tmplist="lo0 ${_tmplist}" ;; + esac ;; esac From 4090e9b219e6ce293feb0b1b372d90ffaf512026 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Sun, 30 Aug 2009 22:36:46 +0000 Subject: [PATCH 0158/2592] MFC r196569 When multiple interfaces exist in the system, with each interface having an IPv6 address assigned to it, and if an incoming packet received on one interface has a packet destination address that belongs to another interface, the routing table is consulted to determine how to reach this packet destination. Since the packet destination is an interface address, the route table will return a host route with the loopback interface as rt_ifp. The input code must recognize this fact, instead of using the loopback interface, the input code performs a search to find the right interface that owns the given IPv6 address. Reviewed by: bz, gnn, kmacy Approved by: re --- sys/netinet6/ip6_input.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 019d57fea6b..4958d748a89 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -628,8 +628,27 @@ passin: &rt6_key(rin6.ro_rt)->sin6_addr) #endif rin6.ro_rt->rt_ifp->if_type == IFT_LOOP) { - struct in6_ifaddr *ia6 = - (struct in6_ifaddr *)rin6.ro_rt->rt_ifa; + int free_ia6 = 0; + struct in6_ifaddr *ia6; + + /* + * found the loopback route to the interface address + */ + if (rin6.ro_rt->rt_gateway->sa_family == AF_LINK) { + struct sockaddr_in6 dest6; + + bzero(&dest6, sizeof(dest6)); + dest6.sin6_family = AF_INET6; + dest6.sin6_len = sizeof(dest6); + dest6.sin6_addr = ip6->ip6_dst; + ia6 = (struct in6_ifaddr *) + ifa_ifwithaddr((struct sockaddr *)&dest6); + if (ia6 == NULL) + goto bad; + free_ia6 = 1; + } + else + ia6 = (struct in6_ifaddr *)rin6.ro_rt->rt_ifa; /* * record address information into m_tag. @@ -647,6 +666,8 @@ passin: /* Count the packet in the ip address stats */ ia6->ia_ifa.if_ipackets++; ia6->ia_ifa.if_ibytes += m->m_pkthdr.len; + if (ia6 != NULL && free_ia6 != 0) + ifa_free(&ia6->ia_ifa); goto hbhcheck; } else { char ip6bufs[INET6_ADDRSTRLEN]; @@ -657,6 +678,8 @@ passin: ip6_sprintf(ip6bufs, &ip6->ip6_src), ip6_sprintf(ip6bufd, &ip6->ip6_dst))); + if (ia6 != NULL && free_ia6 != 0) + ifa_free(&ia6->ia_ifa); goto bad; } } From d84f95cd4a6554361364b2022a9a847946cd1fcb Mon Sep 17 00:00:00 2001 From: Qing Li Date: Sun, 30 Aug 2009 22:39:49 +0000 Subject: [PATCH 0159/2592] MFC r196608 Do not try to free the rt_lle entry of the cached route in ip_output() if the cached route was not initialized from the flow-table. The rt_lle entry is invalid unless it has been initialized through the flow-table. Reviewed by: kmacy, rwatson Approved by: re --- sys/netinet/ip_output.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 2ce94b5c561..e222cdaaa1f 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -202,10 +202,8 @@ again: if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || dst->sin_family != AF_INET || dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { - if (!nortfree) { + if (!nortfree) RTFREE(ro->ro_rt); - LLE_FREE(ro->ro_lle); - } ro->ro_rt = (struct rtentry *)NULL; ro->ro_lle = (struct llentry *)NULL; } From ba3ae75b3c939488e31e02cbafbdc96f437a9ec3 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Sun, 30 Aug 2009 22:42:32 +0000 Subject: [PATCH 0160/2592] MFC r196609 In ip_output(), the flow-table module must not try to cache L2/L3 information for interface of IFF_POINTOPOINT or IFF_LOOPBACK type. Since the L2 information (rt_lle) is invalid for these interface types, accidental caching attempt will trigger panic when the invalid rt_lle reference is accessed. When installing a new route, or when updating an existing route, the user supplied gateway address may be an interface address (this is particularly true for point-to-point interface related modules such as ppp, if_tun, if_gif). Currently the routing command handler always set the RTF_GATEWAY flag if the gateway address is given as part of the command paramters. Therefore the gateway address must be verified against interface addresses or else the route would be treated as an indirect route, thus making that route unusable. Reviewed by: kmacy, julian, rwatson Approved by: re --- sys/net/flowtable.c | 6 ++++++ sys/net/rtsock.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index 98127edd5b2..22cab54e47a 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -692,6 +692,12 @@ uncached: struct rtentry *rt = ro->ro_rt; struct ifnet *ifp = rt->rt_ifp; + if (ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) { + RTFREE(rt); + ro->ro_rt = NULL; + return (ENOENT); + } + if (rt->rt_flags & RTF_GATEWAY) l3addr = rt->rt_gateway; else diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 8fb889908f9..e48ab9041d0 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -513,6 +513,39 @@ route_output(struct mbuf *m, struct socket *so) senderr(error); } + /* + * The given gateway address may be an interface address. + * For example, issuing a "route change" command on a route + * entry that was created from a tunnel, and the gateway + * address given is the local end point. In this case the + * RTF_GATEWAY flag must be cleared or the destination will + * not be reachable even though there is no error message. + */ + if (info.rti_info[RTAX_GATEWAY] != NULL && + info.rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) { + struct route gw_ro; + + bzero(&gw_ro, sizeof(gw_ro)); + gw_ro.ro_dst = *info.rti_info[RTAX_GATEWAY]; + rtalloc_ign(&gw_ro, 0); + /* + * A host route through the loopback interface is + * installed for each interface adddress. In pre 8.0 + * releases the interface address of a PPP link type + * is not reachable locally. This behavior is fixed as + * part of the new L2/L3 redesign and rewrite work. The + * signature of this interface address route is the + * AF_LINK sa_family type of the rt_gateway, and the + * rt_ifp has the IFF_LOOPBACK flag set. + */ + if (gw_ro.ro_rt != NULL && + gw_ro.ro_rt->rt_gateway->sa_family == AF_LINK && + gw_ro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) + info.rti_flags &= ~RTF_GATEWAY; + if (gw_ro.ro_rt != NULL) + RTFREE(gw_ro.ro_rt); + } + switch (rtm->rtm_type) { struct rtentry *saved_nrt; @@ -714,7 +747,7 @@ route_output(struct mbuf *m, struct socket *so) RT_UNLOCK(rt); senderr(error); } - rt->rt_flags |= RTF_GATEWAY; + rt->rt_flags |= (RTF_GATEWAY & info.rti_flags); } if (info.rti_ifa != NULL && info.rti_ifa != rt->rt_ifa) { From 87d2d9c556b9e510e3ee6e21936701bc7482fe9c Mon Sep 17 00:00:00 2001 From: Qing Li Date: Sun, 30 Aug 2009 22:44:12 +0000 Subject: [PATCH 0161/2592] MFC r196649 Prefix on-link verification is being performed on statically configured prefixes. Since these statically configured prefixes do not have any associated advertising routers, these prefixes are treated as unreachable and those prefix routes are deleted from the routing table. Therefore bypass prefixes that are not learned from router advertisements during prefix on-link check. Reviewed by: hrs Approved by: re --- sys/netinet6/nd6_rtr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 9d1f0d6e8cb..4ec64fbadbd 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1415,6 +1415,9 @@ pfxlist_onlink_check() if (pr->ndpr_raf_onlink == 0) continue; + if (pr->ndpr_raf_auto == 0) + continue; + if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && find_pfxlist_reachable_router(pr) == NULL) pr->ndpr_stateflags |= NDPRF_DETACHED; @@ -1431,6 +1434,9 @@ pfxlist_onlink_check() if (pr->ndpr_raf_onlink == 0) continue; + if (pr->ndpr_raf_auto == 0) + continue; + if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0) pr->ndpr_stateflags &= ~NDPRF_DETACHED; } @@ -1454,6 +1460,9 @@ pfxlist_onlink_check() if (pr->ndpr_raf_onlink == 0) continue; + if (pr->ndpr_raf_auto == 0) + continue; + if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 && (pr->ndpr_stateflags & NDPRF_ONLINK) != 0) { if ((e = nd6_prefix_offlink(pr)) != 0) { From c7276c59ff5351740396abb0c46d31f4c4ffcdea Mon Sep 17 00:00:00 2001 From: Qing Li Date: Mon, 31 Aug 2009 00:18:17 +0000 Subject: [PATCH 0162/2592] As part of r196609, a call to "rtalloc" did not take the fib into account. So call the appropriate "rtalloc_ign_fib()" instead of calling "rtalloc_ign()". Reviewed by: pointed out by bz Approved by: re --- sys/net/rtsock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index e48ab9041d0..4bbd6e32fa9 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -527,7 +527,7 @@ route_output(struct mbuf *m, struct socket *so) bzero(&gw_ro, sizeof(gw_ro)); gw_ro.ro_dst = *info.rti_info[RTAX_GATEWAY]; - rtalloc_ign(&gw_ro, 0); + rtalloc_ign_fib(&gw_ro, 0, so->so_fibnum); /* * A host route through the loopback interface is * installed for each interface adddress. In pre 8.0 From e179d138bac50702d4869c07134c9860d5d49c5d Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 31 Aug 2009 09:08:14 +0000 Subject: [PATCH 0163/2592] MFC r196560: Honor the vfs.timestamp_precision sysctl settings for utimes(path, NULL) and similar calls. Approved by: re (rwatson) --- sys/kern/vfs_syscalls.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index f5705f9ca06..ed7f999ccef 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -3134,8 +3134,7 @@ getutimes(usrtvp, tvpseg, tsp) int error; if (usrtvp == NULL) { - microtime(&tv[0]); - TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); + vfs_timestamp(&tsp[0]); tsp[1] = tsp[0]; } else { if (tvpseg == UIO_SYSSPACE) { From e9cedda84318181734e1aab1867ffc468bf63316 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Mon, 31 Aug 2009 09:44:07 +0000 Subject: [PATCH 0164/2592] MFC r196633: Introduce a separate sx lock for protecting lists of vnet sysinit and sysuninit handlers. Previously, sx_vnet, which is a lock designated for protecting the vnet list, was (ab)used for protecting vnet sysinit / sysuninit handler lists as well. Holding exclusively the sx_vnet lock while invoking sysinit and / or sysuninit handlers turned out to be problematic, since some of the handlers may attempt to wake up another thread and wait for it to walk over the vnet list, hence acquire a shared lock on sx_vnet, which in turn leads to a deadlock. Protecting vnet sysinit / sysuninit lists with a separate lock mitigates this issue, which was first observed with flowtable_flush() / flowtable_cleaner() in sys/net/flowtable.c. Reviewed by: rwatson, jhb MFC after: 3 days Approved by: re (rwatson) --- sys/net/vnet.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/sys/net/vnet.c b/sys/net/vnet.c index 17bcbc6fb51..298ffb28457 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -182,14 +182,21 @@ static VNET_DEFINE(char, modspace[VNET_MODMIN]); /* * Global lists of subsystem constructor and destructors for vnets. They are - * registered via VNET_SYSINIT() and VNET_SYSUNINIT(). The lists are - * protected by the vnet_sxlock global lock. + * registered via VNET_SYSINIT() and VNET_SYSUNINIT(). Both lists are + * protected by the vnet_sysinit_sxlock global lock. */ static TAILQ_HEAD(vnet_sysinit_head, vnet_sysinit) vnet_constructors = TAILQ_HEAD_INITIALIZER(vnet_constructors); static TAILQ_HEAD(vnet_sysuninit_head, vnet_sysinit) vnet_destructors = TAILQ_HEAD_INITIALIZER(vnet_destructors); +struct sx vnet_sysinit_sxlock; + +#define VNET_SYSINIT_WLOCK() sx_xlock(&vnet_sysinit_sxlock); +#define VNET_SYSINIT_WUNLOCK() sx_xunlock(&vnet_sysinit_sxlock); +#define VNET_SYSINIT_RLOCK() sx_slock(&vnet_sysinit_sxlock); +#define VNET_SYSINIT_RUNLOCK() sx_sunlock(&vnet_sysinit_sxlock); + struct vnet_data_free { uintptr_t vnd_start; int vnd_len; @@ -228,12 +235,10 @@ vnet_alloc(void) /* Initialize / attach vnet module instances. */ CURVNET_SET_QUIET(vnet); - - sx_xlock(&vnet_sxlock); vnet_sysinit(); CURVNET_RESTORE(); - rw_wlock(&vnet_rwlock); + VNET_LIST_WLOCK(); LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le); VNET_LIST_WUNLOCK(); @@ -253,7 +258,7 @@ vnet_destroy(struct vnet *vnet) VNET_LIST_WLOCK(); LIST_REMOVE(vnet, vnet_le); - rw_wunlock(&vnet_rwlock); + VNET_LIST_WUNLOCK(); CURVNET_SET_QUIET(vnet); @@ -264,8 +269,6 @@ vnet_destroy(struct vnet *vnet) } vnet_sysuninit(); - sx_xunlock(&vnet_sxlock); - CURVNET_RESTORE(); /* @@ -287,6 +290,7 @@ vnet_init_prelink(void *arg) rw_init(&vnet_rwlock, "vnet_rwlock"); sx_init(&vnet_sxlock, "vnet_sxlock"); + sx_init(&vnet_sysinit_sxlock, "vnet_sysinit_sxlock"); LIST_INIT(&vnet_head); } SYSINIT(vnet_init_prelink, SI_SUB_VNET_PRELINK, SI_ORDER_FIRST, @@ -494,7 +498,7 @@ vnet_register_sysinit(void *arg) KASSERT(vs->subsystem > SI_SUB_VNET, ("vnet sysinit too early")); /* Add the constructor to the global list of vnet constructors. */ - sx_xlock(&vnet_sxlock); + VNET_SYSINIT_WLOCK(); TAILQ_FOREACH(vs2, &vnet_constructors, link) { if (vs2->subsystem > vs->subsystem) break; @@ -515,7 +519,7 @@ vnet_register_sysinit(void *arg) vs->func(vs->arg); CURVNET_RESTORE(); } - sx_xunlock(&vnet_sxlock); + VNET_SYSINIT_WUNLOCK(); } void @@ -526,9 +530,9 @@ vnet_deregister_sysinit(void *arg) vs = arg; /* Remove the constructor from the global list of vnet constructors. */ - sx_xlock(&vnet_sxlock); + VNET_SYSINIT_WLOCK(); TAILQ_REMOVE(&vnet_constructors, vs, link); - sx_xunlock(&vnet_sxlock); + VNET_SYSINIT_WUNLOCK(); } void @@ -539,7 +543,7 @@ vnet_register_sysuninit(void *arg) vs = arg; /* Add the destructor to the global list of vnet destructors. */ - sx_xlock(&vnet_sxlock); + VNET_SYSINIT_WLOCK(); TAILQ_FOREACH(vs2, &vnet_destructors, link) { if (vs2->subsystem > vs->subsystem) break; @@ -550,7 +554,7 @@ vnet_register_sysuninit(void *arg) TAILQ_INSERT_BEFORE(vs2, vs, link); else TAILQ_INSERT_TAIL(&vnet_destructors, vs, link); - sx_xunlock(&vnet_sxlock); + VNET_SYSINIT_WUNLOCK(); } void @@ -565,7 +569,7 @@ vnet_deregister_sysuninit(void *arg) * Invoke the destructor on all the existing vnets when it is * deregistered. */ - sx_xlock(&vnet_sxlock); + VNET_SYSINIT_WLOCK(); VNET_FOREACH(vnet) { CURVNET_SET_QUIET(vnet); vs->func(vs->arg); @@ -574,40 +578,42 @@ vnet_deregister_sysuninit(void *arg) /* Remove the destructor from the global list of vnet destructors. */ TAILQ_REMOVE(&vnet_destructors, vs, link); - sx_xunlock(&vnet_sxlock); + VNET_SYSINIT_WUNLOCK(); } /* * Invoke all registered vnet constructors on the current vnet. Used during * vnet construction. The caller is responsible for ensuring the new vnet is - * the current vnet and that the vnet_sxlock lock is locked. + * the current vnet and that the vnet_sysinit_sxlock lock is locked. */ void vnet_sysinit(void) { struct vnet_sysinit *vs; - sx_assert(&vnet_sxlock, SA_LOCKED); + VNET_SYSINIT_RLOCK(); TAILQ_FOREACH(vs, &vnet_constructors, link) { vs->func(vs->arg); } + VNET_SYSINIT_RUNLOCK(); } /* * Invoke all registered vnet destructors on the current vnet. Used during * vnet destruction. The caller is responsible for ensuring the dying vnet - * is the current vnet and that the vnet_sxlock lock is locked. + * the current vnet and that the vnet_sysinit_sxlock lock is locked. */ void vnet_sysuninit(void) { struct vnet_sysinit *vs; - sx_assert(&vnet_sxlock, SA_LOCKED); + VNET_SYSINIT_RLOCK(); TAILQ_FOREACH_REVERSE(vs, &vnet_destructors, vnet_sysuninit_head, link) { vs->func(vs->arg); } + VNET_SYSINIT_RUNLOCK(); } #ifdef DDB From 962e75a7639d8b35a6e62e13a02125792c3b556f Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Mon, 31 Aug 2009 09:46:09 +0000 Subject: [PATCH 0165/2592] MFC r196635: Fix a few panics in linuxulator + VIMAGE due to curvnet not being set. This change affects only options VIMAGE builds. Reviewed by: julian Approved by: re (rwatson) --- sys/compat/linprocfs/linprocfs.c | 2 ++ sys/compat/linux/linux_ioctl.c | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index dfa80d5ab61..541db2fc8c7 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -1085,6 +1085,7 @@ linprocfs_donetdev(PFS_FILL_ARGS) "bytes packets errs drop fifo frame compressed", "bytes packets errs drop fifo frame compressed"); + CURVNET_SET(TD_TO_VNET(curthread)); IFNET_RLOCK(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { linux_ifname(ifp, ifname, sizeof ifname); @@ -1095,6 +1096,7 @@ linprocfs_donetdev(PFS_FILL_ARGS) 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL); } IFNET_RUNLOCK(); + CURVNET_RESTORE(); return (0); } diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 03ac3340749..8acc5929258 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -2104,6 +2104,7 @@ ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname) return (NULL); index = 0; is_eth = (len == 3 && !strncmp(lxname, "eth", len)) ? 1 : 0; + CURVNET_SET(TD_TO_VNET(td)); IFNET_RLOCK(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { /* @@ -2117,6 +2118,7 @@ ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname) break; } IFNET_RUNLOCK(); + CURVNET_RESTORE(); if (ifp != NULL) strlcpy(bsdname, ifp->if_xname, IFNAMSIZ); return (ifp); @@ -2146,6 +2148,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) max_len = MAXPHYS - 1; + CURVNET_SET(TD_TO_VNET(td)); /* handle the 'request buffer size' case */ if (ifc.ifc_buf == PTROUT(NULL)) { ifc.ifc_len = 0; @@ -2157,11 +2160,14 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) } } error = copyout(&ifc, uifc, sizeof(ifc)); + CURVNET_RESTORE(); return (error); } - if (ifc.ifc_len <= 0) + if (ifc.ifc_len <= 0) { + CURVNET_RESTORE(); return (EINVAL); + } again: /* Keep track of eth interfaces */ @@ -2223,6 +2229,7 @@ again: memcpy(PTRIN(ifc.ifc_buf), sbuf_data(sb), ifc.ifc_len); error = copyout(&ifc, uifc, sizeof(ifc)); sbuf_delete(sb); + CURVNET_RESTORE(); return (error); } From de3a9cf126051d98e5475831f80307482784b5b3 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 31 Aug 2009 12:25:04 +0000 Subject: [PATCH 0166/2592] MFC r196455: Make dev.asmc.N.light.control writable by everyone. Submitted by: Patrick Lamaiziere Approved by: re (rwatson) --- sys/dev/asmc/asmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c index b13f6ddc254..7f7f0314014 100644 --- a/sys/dev/asmc/asmc.c +++ b/sys/dev/asmc/asmc.c @@ -419,7 +419,8 @@ asmc_attach(device_t dev) SYSCTL_ADD_PROC(sysctlctx, SYSCTL_CHILDREN(sc->sc_light_tree), - OID_AUTO, "control", CTLTYPE_INT | CTLFLAG_RW, + OID_AUTO, "control", + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, dev, 0, model->smc_light_control, "I", "Keyboard backlight brightness control"); } From ee1db5ae45738b1bf56e41e65aab948da2ddc0b2 Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Mon, 31 Aug 2009 13:02:21 +0000 Subject: [PATCH 0167/2592] MFC r196558: Don't try to mmap the contents of empty files. This behaviour was harmless prior to r195693, when mmap(2) changed from silently ignoring requests for mapping zero bytes to returning EINVAL; this commit can be seen as adjusting for the change in mmap(2) in order to make look(1) act like it did previously. Reviewed by: jhb Approved by: re (kib) --- usr.bin/look/look.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/usr.bin/look/look.c b/usr.bin/look/look.c index e6fd1b8b9e2..7c590c7de08 100644 --- a/usr.bin/look/look.c +++ b/usr.bin/look/look.c @@ -140,6 +140,10 @@ main(int argc, char *argv[]) err(2, "%s", file); if (sb.st_size > SIZE_T_MAX) errx(2, "%s: %s", file, strerror(EFBIG)); + if (sb.st_size == 0) { + close(fd); + continue; + } if ((front = mmap(NULL, (size_t)sb.st_size, PROT_READ, MAP_SHARED, fd, (off_t)0)) == MAP_FAILED) err(2, "%s", file); back = front + sb.st_size; From f37b0a3db5c54acb3f87d6f12e5f815c228c3957 Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Mon, 31 Aug 2009 14:13:45 +0000 Subject: [PATCH 0168/2592] MFC r196592: Fix a LOR between allprison_lock and vnode locks by releasing allprison_lock before releasing a prison's root vnode. PR: kern/138004 Reviewed by: kib Approved by: re (rwatson), bz (mentor) --- sys/kern/kern_jail.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 892d2111bed..47201d2b8df 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -2453,7 +2453,7 @@ prison_deref(struct prison *pr, int flags) ppr = pr->pr_parent; for (tpr = ppr; tpr != NULL; tpr = tpr->pr_parent) tpr->pr_childcount--; - sx_downgrade(&allprison_lock); + sx_xunlock(&allprison_lock); #ifdef VIMAGE if (pr->pr_vnet != ppr->pr_vnet) @@ -2479,7 +2479,7 @@ prison_deref(struct prison *pr, int flags) /* Removing a prison frees a reference on its parent. */ pr = ppr; mtx_lock(&pr->pr_mtx); - flags = PD_DEREF | PD_LIST_SLOCKED; + flags = PD_DEREF; } } From e4e5ed252d89a8812ed90fc0a28a48a9bc3ecd77 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Mon, 31 Aug 2009 19:16:58 +0000 Subject: [PATCH 0169/2592] Add a temporary workaround which just lets init die instead of causing a panic if it is killed due to a unsolved stack overflow seen very late during shutdown on sparc64 when the gmirror worker process exists, which is a regression introduced in 8.0. Reviewed by: kib Approved by: re (rwatson) --- sys/kern/kern_exit.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 36a074d0ef6..39b48e01bde 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -131,7 +131,12 @@ exit1(struct thread *td, int rv) mtx_assert(&Giant, MA_NOTOWNED); p = td->td_proc; - if (p == initproc) { + /* + * XXX in case we're rebooting we just let init die in order to + * work around an unsolved stack overflow seen very late during + * shutdown on sparc64 when the gmirror worker process exists. + */ + if (p == initproc && rebooting == 0) { printf("init died (signal %d, exit %d)\n", WTERMSIG(rv), WEXITSTATUS(rv)); panic("Going nowhere without my init!"); From 088705a89e95f4aeea312fde556f12ab9ef72882 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 1 Sep 2009 11:13:31 +0000 Subject: [PATCH 0170/2592] MFC r196655: Update siis driver: - Add SNTF support. - Do not report meaningless transport/protocol versions. Approved by: re (ATA-CAM blanket) --- sys/dev/siis/siis.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 92b8b70bb27..31002ebcfce 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -646,6 +646,30 @@ siis_slotsfree(device_t dev) } } +static void +siis_notify_events(device_t dev) +{ + struct siis_channel *ch = device_get_softc(dev); + struct cam_path *dpath; + u_int32_t status; + int i; + + status = ATA_INL(ch->r_mem, SIIS_P_SNTF); + ATA_OUTL(ch->r_mem, SIIS_P_SNTF, status); + if (bootverbose) + device_printf(dev, "SNTF 0x%04x\n", status); + for (i = 0; i < 16; i++) { + if ((status & (1 << i)) == 0) + continue; + if (xpt_create_path(&dpath, NULL, + xpt_path_path_id(ch->path), i, 0) == CAM_REQ_CMP) { + xpt_async(AC_SCSI_AEN, dpath, NULL); + xpt_free_path(dpath); + } + } + +} + static void siis_phy_check_events(device_t dev) { @@ -707,6 +731,9 @@ siis_ch_intr(void *data) /* Process PHY events */ if (istatus & SIIS_P_IX_PHYRDYCHG) siis_phy_check_events(dev); + /* Process NOTIFY events */ + if (istatus & SIIS_P_IX_SDBN) + siis_notify_events(dev); /* Process command errors */ if (istatus & SIIS_P_IX_COMMERR) { estatus = ATA_INL(ch->r_mem, SIIS_P_CMDERR); @@ -1267,7 +1294,6 @@ siis_reset(device_t dev) /* XXX; Commands in loading state. */ siis_end_transaction(&ch->slot[i], SIIS_ERR_INNOCENT); } - ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); /* Reset and reconnect PHY, */ if (!siis_sata_phy_reset(dev)) { ch->devices = 0; @@ -1461,9 +1487,9 @@ siisaction(struct cam_sim *sim, union ccb *ccb) uint32_t status; cts->protocol = PROTO_ATA; - cts->protocol_version = SCSI_REV_2; + cts->protocol_version = PROTO_VERSION_UNSPECIFIED; cts->transport = XPORT_SATA; - cts->transport_version = 2; + cts->transport_version = XPORT_VERSION_UNSPECIFIED; cts->proto_specific.valid = 0; cts->xport_specific.sata.valid = 0; if (cts->type == CTS_TYPE_CURRENT_SETTINGS) @@ -1548,9 +1574,9 @@ siisaction(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); cpi->transport = XPORT_SATA; - cpi->transport_version = 2; + cpi->transport_version = XPORT_VERSION_UNSPECIFIED; cpi->protocol = PROTO_ATA; - cpi->protocol_version = SCSI_REV_2; + cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; cpi->ccb_h.status = CAM_REQ_CMP; cpi->maxio = MAXPHYS; xpt_done(ccb); From 84a08f606f4fd5d9c9e1be9ab72c8aef83fd9af2 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 1 Sep 2009 11:44:30 +0000 Subject: [PATCH 0171/2592] MFC r196656, r196660: Update ahci driver: - Add Command Completion Coalescing support. - Add SNTF support. - Add two more power management modes (4, 5), implemented on driver level. - Fix interface mode setting. - Reduce interface reset time. - Do not report meaningless protocol/transport versions. - Report CAP2 register content. - Some performance optimizations. Approved by: re (ATA-CAM blanket) --- share/man/man4/ahci.4 | 17 +++- sys/dev/ahci/ahci.c | 214 +++++++++++++++++++++++++++++++----------- sys/dev/ahci/ahci.h | 21 +++++ 3 files changed, 196 insertions(+), 56 deletions(-) diff --git a/share/man/man4/ahci.4 b/share/man/man4/ahci.4 index 0173e1e7bc0..46660d3a273 100644 --- a/share/man/man4/ahci.4 +++ b/share/man/man4/ahci.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 26, 2009 +.Dd August 24, 2009 .Dt AHCI 4 .Os .Sh NAME @@ -60,6 +60,13 @@ single MSI vector used, if supported (default); .It 2 multiple MSI vectors used, if supported; .El +.It Va hint.ahci.X.ccc +controls Command Completion Coalescing (CCC) usage by the specified controller. +Non-zero value enables CCC and defines maximum time (in ms), request can wait +for interrupt, if there are some more requests present on controller queue. +CCC reduces number of context switches on systems with many parallel requests, +but it can decrease disk performance on some workloads due to additional +command latency. .It Va hint.ahcich.X.pm_level controls SATA interface Power Management for specified channel, allowing some power to be saved at the cost of additional command @@ -74,7 +81,15 @@ device is allowed to initiate PM state change, host is passive; host initiates PARTIAL PM state transition every time port becomes idle; .It 3 host initiates SLUMBER PM state transition every time port becomes idle. +.It 4 +driver initiates PARTIAL PM state transition 1ms after port becomes idle; +.It 5 +driver initiates SLUMBER PM state transition 125ms after port becomes idle. .El +Some controllers, such as ICH8, do not implement modes 2 and 3 with NCQ used. +Because of artificial entering latency, performance degradation in modes +4 and 5 is much smaller then in modes 2 and 3. +.Pp Note that interface Power Management is not compatible with device presence detection. You will have to reset bus manually on device hot-plug. diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 389648adf8e..189ab121e12 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -63,6 +63,7 @@ static int ahci_suspend(device_t dev); static int ahci_resume(device_t dev); static int ahci_ch_suspend(device_t dev); static int ahci_ch_resume(device_t dev); +static void ahci_ch_pm(void *arg); static void ahci_ch_intr_locked(void *data); static void ahci_ch_intr(void *data); static int ahci_ctlr_reset(device_t dev); @@ -121,9 +122,11 @@ ahci_attach(device_t dev) struct ahci_controller *ctlr = device_get_softc(dev); device_t child; int error, unit, speed; - u_int32_t version, caps; + u_int32_t version; ctlr->dev = dev; + resource_int_value(device_get_name(dev), + device_get_unit(dev), "ccc", &ctlr->ccc); /* if we have a memory BAR(5) we are likely on an AHCI part */ ctlr->r_rid = PCIR_BAR(5); if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -160,41 +163,49 @@ ahci_attach(device_t dev) } /* Announce HW capabilities. */ version = ATA_INL(ctlr->r_mem, AHCI_VS); - caps = ATA_INL(ctlr->r_mem, AHCI_CAP); - speed = (caps & AHCI_CAP_ISS) >> AHCI_CAP_ISS_SHIFT; + ctlr->caps = ATA_INL(ctlr->r_mem, AHCI_CAP); + if (version >= 0x00010020) + ctlr->caps2 = ATA_INL(ctlr->r_mem, AHCI_CAP2); + speed = (ctlr->caps & AHCI_CAP_ISS) >> AHCI_CAP_ISS_SHIFT; device_printf(dev, "AHCI v%x.%02x with %d %sGbps ports, Port Multiplier %s\n", ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f), ((version >> 4) & 0xf0) + (version & 0x0f), - (caps & AHCI_CAP_NPMASK) + 1, + (ctlr->caps & AHCI_CAP_NPMASK) + 1, ((speed == 1) ? "1.5":((speed == 2) ? "3": ((speed == 3) ? "6":"?"))), - (caps & AHCI_CAP_SPM) ? + (ctlr->caps & AHCI_CAP_SPM) ? "supported" : "not supported"); if (bootverbose) { device_printf(dev, "Caps:%s%s%s%s%s%s%s%s %sGbps", - (caps & AHCI_CAP_64BIT) ? " 64bit":"", - (caps & AHCI_CAP_SNCQ) ? " NCQ":"", - (caps & AHCI_CAP_SSNTF) ? " SNTF":"", - (caps & AHCI_CAP_SMPS) ? " MPS":"", - (caps & AHCI_CAP_SSS) ? " SS":"", - (caps & AHCI_CAP_SALP) ? " ALP":"", - (caps & AHCI_CAP_SAL) ? " AL":"", - (caps & AHCI_CAP_SCLO) ? " CLO":"", + (ctlr->caps & AHCI_CAP_64BIT) ? " 64bit":"", + (ctlr->caps & AHCI_CAP_SNCQ) ? " NCQ":"", + (ctlr->caps & AHCI_CAP_SSNTF) ? " SNTF":"", + (ctlr->caps & AHCI_CAP_SMPS) ? " MPS":"", + (ctlr->caps & AHCI_CAP_SSS) ? " SS":"", + (ctlr->caps & AHCI_CAP_SALP) ? " ALP":"", + (ctlr->caps & AHCI_CAP_SAL) ? " AL":"", + (ctlr->caps & AHCI_CAP_SCLO) ? " CLO":"", ((speed == 1) ? "1.5":((speed == 2) ? "3": ((speed == 3) ? "6":"?")))); printf("%s%s%s%s%s%s %dcmd%s%s%s %dports\n", - (caps & AHCI_CAP_SAM) ? " AM":"", - (caps & AHCI_CAP_SPM) ? " PM":"", - (caps & AHCI_CAP_FBSS) ? " FBS":"", - (caps & AHCI_CAP_PMD) ? " PMD":"", - (caps & AHCI_CAP_SSC) ? " SSC":"", - (caps & AHCI_CAP_PSC) ? " PSC":"", - ((caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1, - (caps & AHCI_CAP_CCCS) ? " CCC":"", - (caps & AHCI_CAP_EMS) ? " EM":"", - (caps & AHCI_CAP_SXS) ? " eSATA":"", - (caps & AHCI_CAP_NPMASK) + 1); + (ctlr->caps & AHCI_CAP_SAM) ? " AM":"", + (ctlr->caps & AHCI_CAP_SPM) ? " PM":"", + (ctlr->caps & AHCI_CAP_FBSS) ? " FBS":"", + (ctlr->caps & AHCI_CAP_PMD) ? " PMD":"", + (ctlr->caps & AHCI_CAP_SSC) ? " SSC":"", + (ctlr->caps & AHCI_CAP_PSC) ? " PSC":"", + ((ctlr->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1, + (ctlr->caps & AHCI_CAP_CCCS) ? " CCC":"", + (ctlr->caps & AHCI_CAP_EMS) ? " EM":"", + (ctlr->caps & AHCI_CAP_SXS) ? " eSATA":"", + (ctlr->caps & AHCI_CAP_NPMASK) + 1); + } + if (bootverbose && version >= 0x00010020) { + device_printf(dev, "Caps2:%s%s%s\n", + (ctlr->caps2 & AHCI_CAP2_APST) ? " APST":"", + (ctlr->caps2 & AHCI_CAP2_NVMP) ? " NVMP":"", + (ctlr->caps2 & AHCI_CAP2_BOH) ? " BOH":""); } /* Attach all channels on this controller */ for (unit = 0; unit < ctlr->channels; unit++) { @@ -266,6 +277,21 @@ ahci_ctlr_reset(device_t dev) ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE); /* Clear interrupts */ ATA_OUTL(ctlr->r_mem, AHCI_IS, ATA_INL(ctlr->r_mem, AHCI_IS)); + /* Configure CCC */ + if (ctlr->ccc) { + ATA_OUTL(ctlr->r_mem, AHCI_CCCP, ATA_INL(ctlr->r_mem, AHCI_PI)); + ATA_OUTL(ctlr->r_mem, AHCI_CCCC, + (ctlr->ccc << AHCI_CCCC_TV_SHIFT) | + (4 << AHCI_CCCC_CC_SHIFT) | + AHCI_CCCC_EN); + ctlr->cccv = (ATA_INL(ctlr->r_mem, AHCI_CCCC) & + AHCI_CCCC_INT_MASK) >> AHCI_CCCC_INT_SHIFT; + if (bootverbose) { + device_printf(dev, + "CCC with %dms/4cmd enabled on vector %d\n", + ctlr->ccc, ctlr->cccv); + } + } /* Enable AHCI interrupts */ ATA_OUTL(ctlr->r_mem, AHCI_GHC, ATA_INL(ctlr->r_mem, AHCI_GHC) | AHCI_GHC_IE); @@ -326,7 +352,8 @@ ahci_setup_interrupt(device_t dev) for (i = 0; i < ctlr->numirqs; i++) { ctlr->irqs[i].ctlr = ctlr; ctlr->irqs[i].r_irq_rid = i + (msi ? 1 : 0); - if (ctlr->numirqs == 1 || i >= ctlr->channels) + if (ctlr->numirqs == 1 || i >= ctlr->channels || + (ctlr->ccc && i == ctlr->cccv)) ctlr->irqs[i].mode = AHCI_IRQ_MODE_ALL; else if (i == ctlr->numirqs - 1) ctlr->irqs[i].mode = AHCI_IRQ_MODE_AFTER; @@ -360,11 +387,16 @@ ahci_intr(void *data) void *arg; int unit; - is = ATA_INL(ctlr->r_mem, AHCI_IS); - if (irq->mode == AHCI_IRQ_MODE_ALL) + if (irq->mode == AHCI_IRQ_MODE_ALL) { unit = 0; - else /* AHCI_IRQ_MODE_AFTER */ + if (ctlr->ccc) + is = ctlr->ichannels; + else + is = ATA_INL(ctlr->r_mem, AHCI_IS); + } else { /* AHCI_IRQ_MODE_AFTER */ unit = irq->r_irq_rid - 1; + is = ATA_INL(ctlr->r_mem, AHCI_IS); + } for (; unit < ctlr->channels; unit++) { if ((is & (1 << unit)) != 0 && (arg = ctlr->interrupt[unit].argument)) { @@ -523,10 +555,14 @@ ahci_ch_attach(device_t dev) ch->dev = dev; ch->unit = (intptr_t)device_get_ivars(dev); - ch->caps = ATA_INL(ctlr->r_mem, AHCI_CAP); + ch->caps = ctlr->caps; + ch->caps2 = ctlr->caps2; ch->numslots = ((ch->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1, + mtx_init(&ch->mtx, "AHCI channel lock", NULL, MTX_DEF); resource_int_value(device_get_name(dev), device_get_unit(dev), "pm_level", &ch->pm_level); + if (ch->pm_level > 3) + callout_init_mtx(&ch->pm_timer, &ch->mtx, 0); /* Limit speed for my onboard JMicron external port. * It is not eSATA really. */ if (pci_get_devid(ctlr->dev) == 0x2363197b && @@ -536,7 +572,6 @@ ahci_ch_attach(device_t dev) ch->sata_rev = 1; resource_int_value(device_get_name(dev), device_get_unit(dev), "sata_rev", &ch->sata_rev); - mtx_init(&ch->mtx, "AHCI channel lock", NULL, MTX_DEF); rid = ch->unit; if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE))) @@ -584,6 +619,11 @@ ahci_ch_attach(device_t dev) error = ENXIO; goto err3; } + if (ch->pm_level > 3) { + callout_reset(&ch->pm_timer, + (ch->pm_level == 4) ? hz / 1000 : hz / 8, + ahci_ch_pm, dev); + } mtx_unlock(&ch->mtx); return (0); @@ -610,6 +650,8 @@ ahci_ch_detach(device_t dev) cam_sim_free(ch->sim, /*free_devq*/TRUE); mtx_unlock(&ch->mtx); + if (ch->pm_level > 3) + callout_drain(&ch->pm_timer); bus_teardown_intr(dev, ch->r_irq, ch->ih); bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); @@ -661,7 +703,7 @@ ahci_ch_resume(device_t dev) /* Activate the channel and power/spin up device */ ATA_OUTL(ch->r_mem, AHCI_P_CMD, (AHCI_P_CMD_ACTIVE | AHCI_P_CMD_POD | AHCI_P_CMD_SUD | - ((ch->pm_level > 1) ? AHCI_P_CMD_ALPE : 0) | + ((ch->pm_level == 2 || ch->pm_level == 3) ? AHCI_P_CMD_ALPE : 0) | ((ch->pm_level > 2) ? AHCI_P_CMD_ASP : 0 ))); ahci_start_fr(dev); ahci_start(dev); @@ -815,6 +857,7 @@ ahci_slotsfree(device_t dev) for (i = 0; i < ch->numslots; i++) { struct ahci_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; @@ -847,6 +890,31 @@ ahci_phy_check_events(device_t dev) } } +static void +ahci_notify_events(device_t dev) +{ + struct ahci_channel *ch = device_get_softc(dev); + struct cam_path *dpath; + u_int32_t status; + int i; + + status = ATA_INL(ch->r_mem, AHCI_P_SNTF); + if (status == 0) + return; + ATA_OUTL(ch->r_mem, AHCI_P_SNTF, status); + if (bootverbose) + device_printf(dev, "SNTF 0x%04x\n", status); + for (i = 0; i < 16; i++) { + if ((status & (1 << i)) == 0) + continue; + if (xpt_create_path(&dpath, NULL, + xpt_path_path_id(ch->path), i, 0) == CAM_REQ_CMP) { + xpt_async(AC_SCSI_AEN, dpath, NULL); + xpt_free_path(dpath); + } + } +} + static void ahci_ch_intr_locked(void *data) { @@ -858,6 +926,23 @@ ahci_ch_intr_locked(void *data) mtx_unlock(&ch->mtx); } +static void +ahci_ch_pm(void *arg) +{ + device_t dev = (device_t)arg; + struct ahci_channel *ch = device_get_softc(dev); + uint32_t work; + + if (ch->numrslots != 0) + return; + work = ATA_INL(ch->r_mem, AHCI_P_CMD); + if (ch->pm_level == 4) + work |= AHCI_P_CMD_PARTIAL; + else + work |= AHCI_P_CMD_SLUMBER; + ATA_OUTL(ch->r_mem, AHCI_P_CMD, work); +} + static void ahci_ch_intr(void *data) { @@ -869,6 +954,8 @@ ahci_ch_intr(void *data) /* Read and clear interrupt statuses. */ istatus = ATA_INL(ch->r_mem, AHCI_P_IS); + if (istatus == 0) + return; ATA_OUTL(ch->r_mem, AHCI_P_IS, istatus); /* Read command statuses. */ cstatus = ATA_INL(ch->r_mem, AHCI_P_CI); @@ -884,17 +971,16 @@ ahci_ch_intr(void *data) // ATA_INL(ch->r_mem, AHCI_P_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); /* Kick controller into sane state */ ahci_stop(dev); ahci_start(dev); - ok = ch->rslots & ~(cstatus | sstatus); - err = ch->rslots & (cstatus | sstatus); } else { ccs = 0; - ok = ch->rslots & ~(cstatus | sstatus); err = 0; } /* Complete all successfull commands. */ + ok = ch->rslots & ~(cstatus | sstatus); for (i = 0; i < ch->numslots; i++) { if ((ok >> i) & 1) ahci_end_transaction(&ch->slot[i], AHCI_ERR_NONE); @@ -936,6 +1022,9 @@ ahci_ch_intr(void *data) if (ncq_err) ahci_issue_read_log(dev); } + /* Process NOTIFY events */ + if ((istatus & AHCI_P_IX_SDB) && (ch->caps & AHCI_CAP_SSNTF)) + ahci_notify_events(dev); } /* Must be called with channel locked. */ @@ -980,19 +1069,18 @@ ahci_begin_transaction(device_t dev, union ccb *ccb) /* Choose empty slot. */ tag = ch->lastslot; - do { - tag++; - if (tag >= ch->numslots) + while (ch->slot[tag].state != AHCI_SLOT_EMPTY) { + if (++tag >= ch->numslots) tag = 0; - if (ch->slot[tag].state == AHCI_SLOT_EMPTY) - break; - } while (tag != ch->lastslot); - if (ch->slot[tag].state != AHCI_SLOT_EMPTY) - device_printf(ch->dev, "ALL SLOTS BUSY!\n"); + KASSERT(tag != ch->lastslot, ("ahci: ALL SLOTS BUSY!")); + } ch->lastslot = tag; /* Occupy chosen slot. */ slot = &ch->slot[tag]; slot->ccb = ccb; + /* Stop PM timer. */ + if (ch->numrslots == 0 && ch->pm_level > 3) + callout_stop(&ch->pm_timer); /* Update channel stats. */ ch->numrslots++; if ((ccb->ccb_h.func_code == XPT_ATA_IO) && @@ -1162,6 +1250,10 @@ ahci_timeout(struct ahci_slot *slot) struct ahci_channel *ch = device_get_softc(dev); int i; + /* Check for stale timeout. */ + if (slot->state != AHCI_SLOT_RUNNING) + return; + device_printf(dev, "Timeout on slot %d\n", slot->slot); /* Kick controller into sane state. */ ahci_stop(ch->dev); @@ -1194,8 +1286,6 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) struct ahci_channel *ch = device_get_softc(dev); union ccb *ccb = slot->ccb; - /* 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 @@ -1302,6 +1392,11 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) ahci_begin_transaction(dev, fccb); xpt_release_simq(ch->sim, TRUE); } + /* Start PM timer. */ + if (ch->numrslots == 0 && ch->pm_level > 3) { + callout_schedule(&ch->pm_timer, + (ch->pm_level == 4) ? hz / 1000 : hz / 8); + } } static void @@ -1516,6 +1611,7 @@ static void ahci_reset(device_t dev) { struct ahci_channel *ch = device_get_softc(dev); + struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev)); int i; if (bootverbose) @@ -1562,10 +1658,10 @@ ahci_reset(device_t dev) (AHCI_P_IX_CPD | AHCI_P_IX_TFE | AHCI_P_IX_HBF | AHCI_P_IX_HBD | AHCI_P_IX_IF | AHCI_P_IX_OF | ((ch->pm_level == 0) ? AHCI_P_IX_PRC | AHCI_P_IX_PC : 0) | - AHCI_P_IX_DP | AHCI_P_IX_UF | AHCI_P_IX_SDB | - AHCI_P_IX_DS | AHCI_P_IX_PS | AHCI_P_IX_DHR)); + AHCI_P_IX_DP | AHCI_P_IX_UF | (ctlr->ccc ? 0 : AHCI_P_IX_SDB) | + AHCI_P_IX_DS | AHCI_P_IX_PS | (ctlr->ccc ? 0 : AHCI_P_IX_DHR))); if (bootverbose) - device_printf(dev, "AHCI reset done: devices=%08x\n", ch->devices); + device_printf(dev, "AHCI reset done: device found\n"); /* Tell the XPT about the event */ xpt_async(AC_BUS_RESET, ch->path, NULL); } @@ -1632,6 +1728,13 @@ ahci_sata_connect(struct ahci_channel *ch) ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) break; + if ((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_OFFLINE) { + if (bootverbose) { + device_printf(ch->dev, "SATA offline status=%08x\n", + status); + } + return (0); + } DELAY(1000); } if (timeout >= 100) { @@ -1664,9 +1767,6 @@ ahci_sata_phy_reset(device_t dev, int quick) if (bootverbose) device_printf(dev, "hardware reset ...\n"); - ATA_OUTL(ch->r_mem, AHCI_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) @@ -1675,10 +1775,14 @@ ahci_sata_phy_reset(device_t dev, int quick) val = ATA_SC_SPD_SPEED_GEN3; else val = 0; + ATA_OUTL(ch->r_mem, AHCI_P_SCTL, + ATA_SC_DET_RESET | val | + ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER); + DELAY(5000); ATA_OUTL(ch->r_mem, AHCI_P_SCTL, ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 : (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER))); - DELAY(50000); + DELAY(5000); return (ahci_sata_connect(ch)); } @@ -1739,9 +1843,9 @@ ahciaction(struct cam_sim *sim, union ccb *ccb) uint32_t status; cts->protocol = PROTO_ATA; - cts->protocol_version = SCSI_REV_2; + cts->protocol_version = PROTO_VERSION_UNSPECIFIED; cts->transport = XPORT_SATA; - cts->transport_version = 2; + cts->transport_version = XPORT_VERSION_UNSPECIFIED; cts->proto_specific.valid = 0; cts->xport_specific.sata.valid = 0; if (cts->type == CTS_TYPE_CURRENT_SETTINGS) @@ -1834,9 +1938,9 @@ ahciaction(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); cpi->transport = XPORT_SATA; - cpi->transport_version = 2; + cpi->transport_version = XPORT_VERSION_UNSPECIFIED; cpi->protocol = PROTO_ATA; - cpi->protocol_version = SCSI_REV_2; + cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; cpi->maxio = MAXPHYS; cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index dadbd84f255..9b5726ac805 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -176,6 +176,21 @@ #define AHCI_PI 0x0c #define AHCI_VS 0x10 +#define AHCI_CCCC 0x14 +#define AHCI_CCCC_TV_MASK 0xffff0000 +#define AHCI_CCCC_TV_SHIFT 16 +#define AHCI_CCCC_CC_MASK 0x0000ff00 +#define AHCI_CCCC_CC_SHIFT 8 +#define AHCI_CCCC_INT_MASK 0x000000f8 +#define AHCI_CCCC_INT_SHIFT 3 +#define AHCI_CCCC_EN 0x00000001 +#define AHCI_CCCP 0x18 + +#define AHCI_CAP2 0x24 +#define AHCI_CAP2_BOH 0x00000001 +#define AHCI_CAP2_NVMP 0x00000002 +#define AHCI_CAP2_APST 0x00000004 + #define AHCI_OFFSET 0x100 #define AHCI_STEP 0x80 @@ -336,6 +351,7 @@ struct ahci_channel { struct cam_sim *sim; struct cam_path *path; uint32_t caps; /* Controller capabilities */ + uint32_t caps2; /* Controller capabilities */ int numslots; /* Number of present slots */ int pm_level; /* power management level */ int sata_rev; /* Maximum allowed SATA generation */ @@ -353,6 +369,7 @@ struct ahci_channel { int lastslot; /* Last used slot */ int taggedtarget; /* Last tagged target */ union ccb *frozen; /* Frozen command */ + struct callout pm_timer; /* Power management events */ }; /* structure describing a AHCI controller */ @@ -371,9 +388,13 @@ struct ahci_controller { #define AHCI_IRQ_MODE_AFTER 1 #define AHCI_IRQ_MODE_ONE 2 } irqs[16]; + uint32_t caps; /* Controller capabilities */ + uint32_t caps2; /* Controller capabilities */ int numirqs; int channels; int ichannels; + int ccc; /* CCC timeout */ + int cccv; /* CCC vector */ struct { void (*function)(void *); void *argument; From be5b3af8905970238676efd52266a24f966f18f4 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 1 Sep 2009 12:04:43 +0000 Subject: [PATCH 0172/2592] MFC r196657: ATA_FLUSHCACHE is a 28bit format command, not 48. MFC r196658: Improve camcontrol ATA support: - Tune protocol version reporting, - Add supported DMA/PIO modes reporting. - Fix IDENTIFY request for ATAPI devices. - Remove confusing "-" for NCQ status. MFC r196659: Short ATA command format has 28bit address, not 36bit. Rename ata_36bit_cmd() into ata_28bit_cmd(), while it didn't become legacy. Approved by: re (ATA-CAM blanket) --- sbin/camcontrol/camcontrol.c | 149 ++++++++++++++++++++++++++++------- sys/cam/ata/ata_all.c | 2 +- sys/cam/ata/ata_all.h | 2 +- sys/cam/ata/ata_da.c | 14 ++-- sys/cam/ata/ata_xpt.c | 6 +- 5 files changed, 133 insertions(+), 40 deletions(-) diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index d7bf96a3dad..d3450e0648a 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -206,6 +206,7 @@ static void cts_print(struct cam_device *device, struct ccb_trans_settings *cts); static void cpi_print(struct ccb_pathinq *cpi); static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi); +static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd); static int get_print_cts(struct cam_device *device, int user_settings, int quiet, struct ccb_trans_settings *cts); static int ratecontrol(struct cam_device *device, int retry_count, @@ -1015,17 +1016,18 @@ atacapprint(struct ata_params *parm) ((u_int64_t)parm->lba_size48_4 << 48); printf("\n"); - printf("Protocol "); + printf("protocol "); + printf("ATA/ATAPI-%d", ata_version(parm->version_major)); if (parm->satacapabilities && parm->satacapabilities != 0xffff) { if (parm->satacapabilities & ATA_SATA_GEN2) - printf("SATA revision 2.x\n"); + printf(" SATA 2.x\n"); else if (parm->satacapabilities & ATA_SATA_GEN1) - printf("SATA revision 1.x\n"); + printf(" SATA 1.x\n"); else - printf("Unknown SATA revision\n"); + printf(" SATA x.x\n"); } else - printf("ATA/ATAPI revision %d\n", ata_version(parm->version_major)); + printf("\n"); printf("device model %.40s\n", parm->model); printf("serial number %.20s\n", parm->serial); printf("firmware revision %.8s\n", parm->revision); @@ -1038,22 +1040,74 @@ atacapprint(struct ata_params *parm) (parm->support.command2 & ATA_SUPPORT_CFA)) printf("CFA supported\n"); - printf("lba%ssupported ", + printf("LBA%ssupported ", parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not "); if (lbasize) printf("%d sectors\n", lbasize); else printf("\n"); - printf("lba48%ssupported ", + printf("LBA48%ssupported ", parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not "); if (lbasize48) printf("%ju sectors\n", (uintmax_t)lbasize48); else printf("\n"); - printf("dma%ssupported\n", + printf("PIO supported PIO"); + if (parm->atavalid & ATA_FLAG_64_70) { + if (parm->apiomodes & 0x02) + printf("4"); + else if (parm->apiomodes & 0x01) + printf("3"); + } else if (parm->mwdmamodes & 0x04) + printf("4"); + else if (parm->mwdmamodes & 0x02) + printf("3"); + else if (parm->mwdmamodes & 0x01) + printf("2"); + else if ((parm->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200) + printf("2"); + else if ((parm->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100) + printf("1"); + else + printf("0"); + printf("\n"); + + printf("DMA%ssupported ", parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not "); + if (parm->capabilities1 & ATA_SUPPORT_DMA) { + if (parm->mwdmamodes & 0xff) { + printf("WDMA"); + if (parm->mwdmamodes & 0x04) + printf("2"); + else if (parm->mwdmamodes & 0x02) + printf("1"); + else if (parm->mwdmamodes & 0x01) + printf("0"); + printf(" "); + } + if ((parm->atavalid & ATA_FLAG_88) && + (parm->udmamodes & 0xff)) { + printf("UDMA"); + if (parm->udmamodes & 0x40) + printf("6"); + else if (parm->udmamodes & 0x20) + printf("5"); + else if (parm->udmamodes & 0x10) + printf("4"); + else if (parm->udmamodes & 0x08) + printf("3"); + else if (parm->udmamodes & 0x04) + printf("2"); + else if (parm->udmamodes & 0x02) + printf("1"); + else if (parm->udmamodes & 0x01) + printf("0"); + printf(" "); + } + } + printf("\n"); printf("overlap%ssupported\n", parm->capabilities1 & ATA_SUPPORT_OVERLAP ? " " : " not "); @@ -1070,10 +1124,10 @@ atacapprint(struct ata_params *parm) parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no"); if (parm->satacapabilities && parm->satacapabilities != 0xffff) { - printf("Native Command Queuing (NCQ) %s %s" + printf("Native Command Queuing (NCQ) %s " " %d/0x%02X\n", parm->satacapabilities & ATA_SUPPORT_NCQ ? - "yes" : "no", " -", + "yes" : "no", (parm->satacapabilities & ATA_SUPPORT_NCQ) ? ATA_QUEUE_LEN(parm->queue) : 0, (parm->satacapabilities & ATA_SUPPORT_NCQ) ? @@ -1121,9 +1175,14 @@ ataidentify(struct cam_device *device, int retry_count, int timeout) { union ccb *ccb; struct ata_params *ident_buf; + struct ccb_getdev cgd; u_int i, error = 0; int16_t *ptr; - + + if (get_cgd(device, &cgd) != 0) { + warnx("couldn't get CGD"); + return(1); + } ccb = cam_getccb(device); if (ccb == NULL) { @@ -1152,10 +1211,10 @@ ataidentify(struct cam_device *device, int retry_count, int timeout) /*data_ptr*/(u_int8_t *)ptr, /*dxfer_len*/sizeof(struct ata_params), timeout ? timeout : 30 * 1000); -// if (periph->path->device->protocol == PROTO_ATA) - ata_36bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0); -// else -// ata_36bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0); + if (cgd.protocol == PROTO_ATA) + ata_28bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0); + else + ata_28bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; @@ -2588,46 +2647,71 @@ get_cpi(struct cam_device *device, struct ccb_pathinq *cpi) int retval = 0; ccb = cam_getccb(device); - if (ccb == NULL) { warnx("get_cpi: couldn't allocate CCB"); return(1); } - bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr)); - ccb->ccb_h.func_code = XPT_PATH_INQ; - if (cam_send_ccb(device, ccb) < 0) { warn("get_cpi: error sending Path Inquiry CCB"); - if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); - retval = 1; - goto get_cpi_bailout; } - if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { - if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); - retval = 1; - goto get_cpi_bailout; } - bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq)); get_cpi_bailout: - cam_freeccb(ccb); + return(retval); +} +/* + * Get a get device CCB for the specified device. + */ +static int +get_cgd(struct cam_device *device, struct ccb_getdev *cgd) +{ + union ccb *ccb; + int retval = 0; + + ccb = cam_getccb(device); + if (ccb == NULL) { + warnx("get_cgd: couldn't allocate CCB"); + return(1); + } + bzero(&(&ccb->ccb_h)[1], + sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr)); + ccb->ccb_h.func_code = XPT_GDEV_TYPE; + if (cam_send_ccb(device, ccb) < 0) { + warn("get_cgd: error sending Path Inquiry CCB"); + if (arglist & CAM_ARG_VERBOSE) + cam_error_print(device, ccb, CAM_ESF_ALL, + CAM_EPF_ALL, stderr); + retval = 1; + goto get_cgd_bailout; + } + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + if (arglist & CAM_ARG_VERBOSE) + cam_error_print(device, ccb, CAM_ESF_ALL, + CAM_EPF_ALL, stderr); + retval = 1; + goto get_cgd_bailout; + } + bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev)); + +get_cgd_bailout: + cam_freeccb(ccb); return(retval); } @@ -2673,6 +2757,9 @@ cpi_print(struct ccb_pathinq *cpi) case PI_SOFT_RST: str = "soft reset alternative"; break; + case PI_SATAPM: + str = "SATA Port Multiplier"; + break; default: str = "unknown PI bit set"; break; @@ -2702,6 +2789,12 @@ cpi_print(struct ccb_pathinq *cpi) str = "user has disabled initial BUS RESET or" " controller is in target/mixed mode"; break; + case PIM_NO_6_BYTE: + str = "do not send 6-byte commands"; + break; + case PIM_SEQSCAN: + str = "scan bus sequentially"; + break; default: str = "unknown PIM bit set"; break; diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index 1e6eecec820..e75c109f7ee 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -91,7 +91,7 @@ ata_print_ident(struct ata_params *ident_data) } void -ata_36bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, +ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, uint32_t lba, uint8_t sector_count) { bzero(&ataio->cmd, sizeof(ataio->cmd)); diff --git a/sys/cam/ata/ata_all.h b/sys/cam/ata/ata_all.h index 60129956db7..748035f8602 100644 --- a/sys/cam/ata/ata_all.h +++ b/sys/cam/ata/ata_all.h @@ -83,7 +83,7 @@ struct ata_res { int ata_version(int ver); void ata_print_ident(struct ata_params *ident_data); -void ata_36bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, +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, uint64_t lba, uint16_t sector_count); diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 42ba74566b9..7d7230b154f 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -287,7 +287,7 @@ adaclose(struct disk *dp) if (softc->flags & ADA_FLAG_CAN_48BIT) ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0); else - ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0); + 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); @@ -411,7 +411,7 @@ adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len ata_48bit_cmd(&ccb.ataio, ATA_WRITE_DMA48, 0, lba, count); } else { - ata_36bit_cmd(&ccb.ataio, ATA_WRITE_DMA, + ata_28bit_cmd(&ccb.ataio, ATA_WRITE_DMA, 0, lba, count); } xpt_polled_action(&ccb); @@ -441,7 +441,7 @@ adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len if (softc->flags & ADA_FLAG_CAN_48BIT) ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0); else - ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0); + ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0); xpt_polled_action(&ccb); if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) @@ -856,10 +856,10 @@ adastart(struct cam_periph *periph, union ccb *start_ccb) } } else { if (bp->bio_cmd == BIO_READ) { - ata_36bit_cmd(ataio, ATA_READ_DMA, + ata_28bit_cmd(ataio, ATA_READ_DMA, 0, lba, count); } else { - ata_36bit_cmd(ataio, ATA_WRITE_DMA, + ata_28bit_cmd(ataio, ATA_WRITE_DMA, 0, lba, count); } } @@ -878,7 +878,7 @@ adastart(struct cam_periph *periph, union ccb *start_ccb) if (softc->flags & ADA_FLAG_CAN_48BIT) ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0); else - ata_48bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0); + ata_28bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0); break; } start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO; @@ -1126,7 +1126,7 @@ adashutdown(void * arg, int howto) if (softc->flags & ADA_FLAG_CAN_48BIT) ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0); else - ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0); + ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0); xpt_polled_action(&ccb); if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 0be44fc2b77..5acb9a35d0c 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -357,9 +357,9 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) /*dxfer_len*/sizeof(struct ata_params), 30 * 1000); if (periph->path->device->protocol == PROTO_ATA) - ata_36bit_cmd(ataio, ATA_ATA_IDENTIFY, 0, 0, 0); + ata_28bit_cmd(ataio, ATA_ATA_IDENTIFY, 0, 0, 0); else - ata_36bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0); + ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0); break; } case PROBE_SETMODE: @@ -375,7 +375,7 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) /*data_ptr*/NULL, /*dxfer_len*/0, 30 * 1000); - ata_36bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, + ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, ata_max_mode(ident_buf, ATA_UDMA6, ATA_UDMA6)); break; } From 8a503ad2c98f62562e6343c550729dde1bf0892a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 1 Sep 2009 15:50:07 +0000 Subject: [PATCH 0173/2592] MFC 196637: Mark the fake pages constructed by the OBJT_SG pager valid. This was accidentally lost at one point during the PAT development. Without this fix vm_pager_get_pages() was zeroing each of the pages. Approved by: re (kib) --- sys/vm/sg_pager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/vm/sg_pager.c b/sys/vm/sg_pager.c index 6e3da803295..a17fe82c2ef 100644 --- a/sys/vm/sg_pager.c +++ b/sys/vm/sg_pager.c @@ -204,6 +204,7 @@ sg_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) vm_page_unlock_queues(); vm_page_insert(page, object, offset); m[reqpage] = page; + page->valid = VM_PAGE_BITS_ALL; return (VM_PAGER_OK); } From e2ba743711283aac14dd37fb281817decbb80879 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Tue, 1 Sep 2009 16:41:28 +0000 Subject: [PATCH 0174/2592] MFC 196643 Swap the start/end virtual addresses in pmap_invalidate_cache_range(). This fixes the functionality on non SelfSnoop hardware. Found by: rnoland Submitted by: alc Reviewed by: kib Approved by: re (rwatson) --- sys/amd64/amd64/pmap.c | 4 ++-- sys/i386/i386/pmap.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index b9eee49c97c..f0da536a012 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -943,8 +943,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) * coherence domain. */ mfence(); - for (; eva < sva; eva += cpu_clflush_line_size) - clflush(eva); + for (; sva < eva; sva += cpu_clflush_line_size) + clflush(sva); mfence(); } else { diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index c6f1d5fe2a4..405cbd30cfe 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -967,8 +967,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) * coherence domain. */ mfence(); - for (; eva < sva; eva += cpu_clflush_line_size) - clflush(eva); + for (; sva < eva; sva += cpu_clflush_line_size) + clflush(sva); mfence(); } else { From 33656b91cda2504e2d41759732ada5d6db293e81 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Tue, 1 Sep 2009 20:58:41 +0000 Subject: [PATCH 0175/2592] MFC r196460 Fix the conformance of poll(2) for sockets after r195423 by returning POLLHUP instead of POLLIN for several cases. Now, the tools/regression/poll results for FreeBSD are closer to that of the Solaris and Linux. Also, improve the POSIX conformance by explicitely clearing POLLOUT when POLLHUP is reported in pollscan(), making the fix global. Submitted by: bde Reviewed by: rwatson MFC r196556 Fix poll() on half-closed sockets, while retaining POLLHUP for fifos. This reverts part of r196460, so that sockets only return POLLHUP if both directions are closed/error. Fifos get POLLHUP by closing the unused direction immediately after creating the sockets. The tools/regression/poll/*poll.c tests now pass except for two other things: - if POLLHUP is returned, POLLIN is always returned as well instead of only when there is data left in the buffer to be read - fifo old/new reader distinction does not work the way POSIX specs it Reviewed by: kib, bde MFC r196554 Add some tests for poll(2)/shutdown(2) interaction. Approved by: re (kensmith) --- sys/fs/fifofs/fifo_vnops.c | 3 + sys/kern/sys_generic.c | 7 ++ tools/regression/poll/Makefile | 5 +- tools/regression/poll/sockpoll.c | 202 +++++++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 tools/regression/poll/sockpoll.c diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c index 25436c70f45..5668f751d96 100644 --- a/sys/fs/fifofs/fifo_vnops.c +++ b/sys/fs/fifofs/fifo_vnops.c @@ -193,6 +193,9 @@ fifo_open(ap) goto fail2; fip->fi_writesock = wso; error = soconnect2(wso, rso); + /* Close the direction we do not use, so we can get POLLHUP. */ + if (error == 0) + error = soshutdown(rso, SHUT_WR); if (error) { (void)soclose(wso); fail2: diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index de703483b0c..bd0f2793378 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1228,6 +1228,13 @@ pollscan(td, fds, nfd) selfdalloc(td, fds); fds->revents = fo_poll(fp, fds->events, td->td_ucred, td); + /* + * POSIX requires POLLOUT to be never + * set simultaneously with POLLHUP. + */ + if ((fds->revents & POLLHUP) != 0) + fds->revents &= ~POLLOUT; + if (fds->revents != 0) n++; } diff --git a/tools/regression/poll/Makefile b/tools/regression/poll/Makefile index 71192a948eb..45f743f17ae 100644 --- a/tools/regression/poll/Makefile +++ b/tools/regression/poll/Makefile @@ -3,14 +3,15 @@ # Nothing yet works with gmake for the path to the sources. .PATH: .. -PROG= pipepoll pipeselect +PROG= pipepoll pipeselect sockpoll CFLAGS+= -Werror -Wall all: ${PROG} pipepoll: pipepoll.c pipeselect: pipeselect.c +sockpoll: sockpoll.c -pipepoll pipeselect: +pipepoll pipeselect sockpoll: ${CC} ${CFLAGS} ${LDFLAGS} -o $@ $@.c test: all diff --git a/tools/regression/poll/sockpoll.c b/tools/regression/poll/sockpoll.c new file mode 100644 index 00000000000..4bffd29dc6f --- /dev/null +++ b/tools/regression/poll/sockpoll.c @@ -0,0 +1,202 @@ +/* $FreeBSD$ */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static const char * +decode_events(int events) +{ + char *ncresult; + const char *result; + + switch (events) { + case POLLIN: + result = "POLLIN"; + break; + case POLLOUT: + result = "POLLOUT"; + break; + case POLLIN | POLLOUT: + result = "POLLIN | POLLOUT"; + break; + case POLLHUP: + result = "POLLHUP"; + break; + case POLLIN | POLLHUP: + result = "POLLIN | POLLHUP"; + break; + case POLLOUT | POLLHUP: + result = "POLLOUT | POLLHUP"; + break; + case POLLIN | POLLOUT | POLLHUP: + result = "POLLIN | POLLOUT | POLLHUP"; + break; + default: + asprintf(&ncresult, "%#x", events); + result = ncresult; + break; + } + return (result); +} + +static void +report(int num, const char *state, int expected, int got) +{ + if (expected == got) + printf("ok %-2d ", num); + else + printf("not ok %-2d", num); + printf(" state %s: expected %s; got %s\n", + state, decode_events(expected), decode_events(got)); + fflush(stdout); +} + +static int +set_nonblocking(int sck) +{ + int flags; + + flags = fcntl(sck, F_GETFL, 0); + flags |= O_NONBLOCK; + + if (fcntl(sck, F_SETFL, flags)) + return -1; + + return 0; +} + +static char largeblock[1048576]; /* should be more than AF_UNIX sockbuf size */ +static int fd[2]; +static struct pollfd pfd0; +static struct pollfd pfd1; + +void +setup(void) +{ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) + err(1, "socketpair"); + if (set_nonblocking(fd[0]) == -1) + err(1, "fcntl"); + if (set_nonblocking(fd[1]) == -1) + err(1, "fcntl"); + pfd0.fd = fd[0]; + pfd0.events = POLLIN | POLLOUT; + pfd1.fd = fd[1]; + pfd1.events = POLLIN | POLLOUT; +} + +int +main(void) +{ + int num; + + num = 1; + printf("1..18\n"); + fflush(stdout); + + /* Large write with close */ + setup(); + if (poll(&pfd0, 1, 0) == -1) + err(1, "poll"); + report(num++, "initial 0", POLLOUT, pfd0.revents); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "initial 1", POLLOUT, pfd1.revents); + if (write(fd[0], largeblock, sizeof(largeblock)) == -1) + err(1, "write"); + if (poll(&pfd0, 1, 0) == -1) + err(1, "poll"); + report(num++, "after large write", 0, pfd0.revents); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "other side after large write", POLLIN | POLLOUT, pfd1.revents); + close(fd[0]); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "other side after close", POLLIN | POLLHUP, pfd1.revents); + if (read(fd[1], largeblock, sizeof(largeblock)) == -1) + err(1, "read"); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "other side after reading input", POLLHUP, pfd1.revents); + close(fd[1]); + + /* With shutdown(SHUT_WR) */ + setup(); + if (shutdown(fd[0], SHUT_WR) == -1) + err(1, "shutdown"); + if (poll(&pfd0, 1, 0) == -1) + err(1, "poll"); + report(num++, "after shutdown(SHUT_WR)", POLLOUT, pfd0.revents); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "other side after shutdown(SHUT_WR)", POLLIN | POLLOUT, pfd1.revents); + switch (read(fd[1], largeblock, sizeof(largeblock))) { + case 0: + break; + case -1: + err(1, "read after other side shutdown"); + break; + default: + errx(1, "kernel made up data that was never written"); + } + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "other side after reading EOF", POLLIN | POLLOUT, pfd1.revents); + if (write(fd[1], largeblock, sizeof(largeblock)) == -1) + err(1, "write"); + if (poll(&pfd0, 1, 0) == -1) + err(1, "poll"); + report(num++, "after data from other side", POLLIN | POLLOUT, pfd0.revents); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "after writing", POLLIN, pfd1.revents); + if (shutdown(fd[1], SHUT_WR) == -1) + err(1, "shutdown second"); + if (poll(&pfd0, 1, 0) == -1) + err(1, "poll"); + report(num++, "after second shutdown", POLLIN | POLLHUP, pfd0.revents); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "after second shutdown", POLLHUP, pfd1.revents); + close(fd[0]); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "after close", POLLHUP, pfd1.revents); + close(fd[1]); + + /* + * With shutdown(SHUT_RD) + * Note that shutdown(SHUT_WR) is passed to the peer, but + * shutdown(SHUT_RD) is not. + */ + setup(); + if (shutdown(fd[0], SHUT_RD) == -1) + err(1, "shutdown"); + if (poll(&pfd0, 1, 0) == -1) + err(1, "poll"); + report(num++, "after shutdown(SHUT_RD)", POLLIN | POLLOUT, pfd0.revents); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "other side after shutdown(SHUT_RD)", POLLOUT, pfd1.revents); + if (shutdown(fd[0], SHUT_WR) == -1) + err(1, "shutdown"); + if (poll(&pfd0, 1, 0) == -1) + err(1, "poll"); + report(num++, "after shutdown(SHUT_WR)", POLLHUP, pfd0.revents); + if (poll(&pfd1, 1, 0) == -1) + err(1, "poll"); + report(num++, "other side after shutdown(SHUT_WR)", POLLIN | POLLOUT, pfd1.revents); + close(fd[0]); + close(fd[1]); + + return (0); +} From 42a66b539d9dcae9eba23f5b1e5b7e1412b9a103 Mon Sep 17 00:00:00 2001 From: Alfred Perlstein Date: Wed, 2 Sep 2009 02:12:07 +0000 Subject: [PATCH 0176/2592] MFC: r196489,196498 Critical USB bugfixes for 8.0 Approved by: re --- sys/dev/usb/input/ukbd.c | 83 +++++++++++++++++++------------- sys/dev/usb/usb_dev.c | 19 +++----- sys/dev/usb/usb_device.c | 80 +++++++++++++++++++++--------- sys/dev/usb/usb_device.h | 3 ++ sys/dev/usb/usb_handle_request.c | 30 +++++------- sys/dev/usb/usb_hub.c | 29 ++++++++--- sys/dev/usb/usb_process.c | 26 ++++++++++ sys/dev/usb/usb_process.h | 1 + sys/dev/usb/usb_transfer.c | 4 -- 9 files changed, 180 insertions(+), 95 deletions(-) diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index 0d09ad43783..5816079b3f6 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -96,10 +96,14 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int ukbd_debug = 0; +static int ukbd_no_leds = 0; SYSCTL_NODE(_hw_usb, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB ukbd"); SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, debug, CTLFLAG_RW, &ukbd_debug, 0, "Debug level"); +SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, no_leds, CTLFLAG_RW, + &ukbd_no_leds, 0, "Disables setting of keyboard leds"); + #endif #define UPROTO_BOOT_KEYBOARD 1 @@ -165,6 +169,7 @@ struct ukbd_softc { #define UKBD_FLAG_APPLE_EJECT 0x0040 #define UKBD_FLAG_APPLE_FN 0x0080 #define UKBD_FLAG_APPLE_SWAP 0x0100 +#define UKBD_FLAG_TIMER_RUNNING 0x0200 int32_t sc_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */ int32_t sc_state; /* shift/lock key state */ @@ -279,6 +284,25 @@ static device_attach_t ukbd_attach; static device_detach_t ukbd_detach; static device_resume_t ukbd_resume; +static uint8_t +ukbd_any_key_pressed(struct ukbd_softc *sc) +{ + uint8_t i; + uint8_t j; + + for (j = i = 0; i < UKBD_NKEYCODE; i++) + j |= sc->sc_odata.keycode[i]; + + return (j ? 1 : 0); +} + +static void +ukbd_start_timer(struct ukbd_softc *sc) +{ + sc->sc_flags |= UKBD_FLAG_TIMER_RUNNING; + usb_callout_reset(&sc->sc_callout, hz / 40, &ukbd_timeout, sc); +} + static void ukbd_put_key(struct ukbd_softc *sc, uint32_t key) { @@ -308,11 +332,15 @@ ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait) usbd_transfer_poll(sc->sc_xfer, UKBD_N_TRANSFER); - DELAY(1000); /* delay 1 ms */ + /* Delay-optimised support for repetition of keys */ - sc->sc_time_ms++; + if (ukbd_any_key_pressed(sc)) { + /* a key is pressed - need timekeeping */ + DELAY(1000); - /* support repetition of keys: */ + /* 1 millisecond has passed */ + sc->sc_time_ms += 1; + } ukbd_interrupt(sc); @@ -470,7 +498,11 @@ ukbd_timeout(void *arg) } ukbd_interrupt(sc); - usb_callout_reset(&sc->sc_callout, hz / 40, &ukbd_timeout, sc); + if (ukbd_any_key_pressed(sc)) { + ukbd_start_timer(sc); + } else { + sc->sc_flags &= ~UKBD_FLAG_TIMER_RUNNING; + } } static uint8_t @@ -582,6 +614,12 @@ ukbd_intr_callback(struct usb_xfer *xfer, usb_error_t error) } ukbd_interrupt(sc); + + if (!(sc->sc_flags & UKBD_FLAG_TIMER_RUNNING)) { + if (ukbd_any_key_pressed(sc)) { + ukbd_start_timer(sc); + } + } } case USB_ST_SETUP: tr_setup: @@ -613,6 +651,11 @@ ukbd_set_leds_callback(struct usb_xfer *xfer, usb_error_t error) uint8_t buf[2]; struct ukbd_softc *sc = usbd_xfer_softc(xfer); +#if USB_DEBUG + if (ukbd_no_leds) + return; +#endif + switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: case USB_ST_SETUP: @@ -647,11 +690,11 @@ ukbd_set_leds_callback(struct usb_xfer *xfer, usb_error_t error) usbd_xfer_set_frames(xfer, 2); usbd_transfer_submit(xfer); } - return; + break; default: /* Error */ DPRINTFN(0, "error=%s\n", usbd_errstr(error)); - return; + break; } } @@ -745,8 +788,6 @@ ukbd_attach(device_t dev) uint16_t n; uint16_t hid_len; - mtx_assert(&Giant, MA_OWNED); - kbd_init_struct(kbd, UKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0); kbd->kb_data = (void *)sc; @@ -831,7 +872,7 @@ ukbd_attach(device_t dev) } /* ignore if SETIDLE fails, hence it is not crucial */ - err = usbd_req_set_idle(sc->sc_udev, &Giant, sc->sc_iface_index, 0, 0); + err = usbd_req_set_idle(sc->sc_udev, NULL, sc->sc_iface_index, 0, 0); ukbd_ioctl(kbd, KDSETLED, (caddr_t)&sc->sc_state); @@ -862,9 +903,6 @@ ukbd_attach(device_t dev) usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]); - /* start the timer */ - - ukbd_timeout(sc); mtx_unlock(&Giant); return (0); /* success */ @@ -879,8 +917,6 @@ ukbd_detach(device_t dev) struct ukbd_softc *sc = device_get_softc(dev); int error; - mtx_assert(&Giant, MA_OWNED); - DPRINTF("\n"); if (sc->sc_flags & UKBD_FLAG_POLLING) { @@ -927,8 +963,6 @@ ukbd_resume(device_t dev) { struct ukbd_softc *sc = device_get_softc(dev); - mtx_assert(&Giant, MA_OWNED); - ukbd_clear_state(&sc->sc_kbd); return (0); @@ -945,7 +979,6 @@ ukbd_configure(int flags) static int ukbd__probe(int unit, void *arg, int flags) { - mtx_assert(&Giant, MA_OWNED); return (ENXIO); } @@ -953,7 +986,6 @@ ukbd__probe(int unit, void *arg, int flags) static int ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) { - mtx_assert(&Giant, MA_OWNED); return (ENXIO); } @@ -961,7 +993,6 @@ ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) static int ukbd_test_if(keyboard_t *kbd) { - mtx_assert(&Giant, MA_OWNED); return (0); } @@ -969,7 +1000,6 @@ ukbd_test_if(keyboard_t *kbd) static int ukbd_term(keyboard_t *kbd) { - mtx_assert(&Giant, MA_OWNED); return (ENXIO); } @@ -977,7 +1007,6 @@ ukbd_term(keyboard_t *kbd) static int ukbd_intr(keyboard_t *kbd, void *arg) { - mtx_assert(&Giant, MA_OWNED); return (0); } @@ -985,7 +1014,6 @@ ukbd_intr(keyboard_t *kbd, void *arg) static int ukbd_lock(keyboard_t *kbd, int lock) { - mtx_assert(&Giant, MA_OWNED); return (1); } @@ -1004,7 +1032,6 @@ ukbd_enable(keyboard_t *kbd) mtx_unlock(&Giant); return (retval); } - mtx_assert(&Giant, MA_OWNED); KBD_ACTIVATE(kbd); return (0); } @@ -1021,7 +1048,6 @@ ukbd_disable(keyboard_t *kbd) mtx_unlock(&Giant); return (retval); } - mtx_assert(&Giant, MA_OWNED); KBD_DEACTIVATE(kbd); return (0); } @@ -1050,7 +1076,6 @@ ukbd_check(keyboard_t *kbd) if (!mtx_owned(&Giant)) return (0); } - mtx_assert(&Giant, MA_OWNED); #ifdef UKBD_EMULATE_ATSCANCODE if (sc->sc_buffered_char[0]) { @@ -1086,7 +1111,6 @@ ukbd_check_char(keyboard_t *kbd) if (!mtx_owned(&Giant)) return (0); } - mtx_assert(&Giant, MA_OWNED); if ((sc->sc_composed_char > 0) && (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) { @@ -1125,7 +1149,6 @@ ukbd_read(keyboard_t *kbd, int wait) if (!mtx_owned(&Giant)) return (-1); } - mtx_assert(&Giant, MA_OWNED); #ifdef UKBD_EMULATE_ATSCANCODE if (sc->sc_buffered_char[0]) { @@ -1190,7 +1213,6 @@ ukbd_read_char(keyboard_t *kbd, int wait) if (!mtx_owned(&Giant)) return (NOKEY); } - mtx_assert(&Giant, MA_OWNED); next_code: @@ -1393,7 +1415,6 @@ ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) */ return (EINVAL); } - mtx_assert(&Giant, MA_OWNED); switch (cmd) { case KDGKBMODE: /* get keyboard mode */ @@ -1527,7 +1548,6 @@ ukbd_clear_state(keyboard_t *kbd) if (!mtx_owned(&Giant)) { return; /* XXX */ } - mtx_assert(&Giant, MA_OWNED); sc->sc_flags &= ~(UKBD_FLAG_COMPOSE | UKBD_FLAG_POLLING); sc->sc_state &= LOCK_MASK; /* preserve locking key state */ @@ -1547,7 +1567,6 @@ ukbd_clear_state(keyboard_t *kbd) static int ukbd_get_state(keyboard_t *kbd, void *buf, size_t len) { - mtx_assert(&Giant, MA_OWNED); return (len == 0) ? 1 : -1; } @@ -1555,7 +1574,6 @@ ukbd_get_state(keyboard_t *kbd, void *buf, size_t len) static int ukbd_set_state(keyboard_t *kbd, void *buf, size_t len) { - mtx_assert(&Giant, MA_OWNED); return (EINVAL); } @@ -1572,7 +1590,6 @@ ukbd_poll(keyboard_t *kbd, int on) mtx_unlock(&Giant); return (retval); } - mtx_assert(&Giant, MA_OWNED); if (on) { sc->sc_flags |= UKBD_FLAG_POLLING; diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c index cba8919255c..c828b24057f 100644 --- a/sys/dev/usb/usb_dev.c +++ b/sys/dev/usb/usb_dev.c @@ -217,7 +217,7 @@ usb_ref_device(struct usb_cdev_privdata *cpd, * We need to grab the sx-lock before grabbing the * FIFO refs to avoid deadlock at detach! */ - sx_xlock(cpd->udev->default_sx + 1); + usbd_enum_lock(cpd->udev); mtx_lock(&usb_ref_lock); @@ -275,14 +275,12 @@ usb_ref_device(struct usb_cdev_privdata *cpd, } mtx_unlock(&usb_ref_lock); - if (crd->is_uref) { - mtx_lock(&Giant); /* XXX */ - } return (0); error: if (crd->is_uref) { - sx_unlock(cpd->udev->default_sx + 1); + usbd_enum_unlock(cpd->udev); + if (--(cpd->udev->refcount) == 0) { cv_signal(cpd->udev->default_cv + 1); } @@ -334,10 +332,9 @@ usb_unref_device(struct usb_cdev_privdata *cpd, DPRINTFN(2, "cpd=%p is_uref=%d\n", cpd, crd->is_uref); - if (crd->is_uref) { - mtx_unlock(&Giant); /* XXX */ - sx_unlock(cpd->udev->default_sx + 1); - } + if (crd->is_uref) + usbd_enum_unlock(cpd->udev); + mtx_lock(&usb_ref_lock); if (crd->is_read) { if (--(crd->rxfifo->refcount) == 0) { @@ -1042,9 +1039,9 @@ usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* * reference if we need it! */ err = usb_ref_device(cpd, &refs, 0 /* no uref */ ); - if (err) { + if (err) return (ENXIO); - } + fflags = cpd->fflags; f = NULL; /* set default value */ diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index 2d34017ba33..635a9b1528d 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -402,11 +402,11 @@ usb_unconfigure(struct usb_device *udev, uint8_t flag) uint8_t do_unlock; /* automatic locking */ - if (sx_xlocked(udev->default_sx + 1)) { + if (usbd_enum_is_locked(udev)) { do_unlock = 0; } else { do_unlock = 1; - sx_xlock(udev->default_sx + 1); + usbd_enum_lock(udev); } /* detach all interface drivers */ @@ -442,9 +442,8 @@ usb_unconfigure(struct usb_device *udev, uint8_t flag) udev->curr_config_no = USB_UNCONFIG_NO; udev->curr_config_index = USB_UNCONFIG_INDEX; - if (do_unlock) { - sx_unlock(udev->default_sx + 1); - } + if (do_unlock) + usbd_enum_unlock(udev); } /*------------------------------------------------------------------------* @@ -472,11 +471,11 @@ usbd_set_config_index(struct usb_device *udev, uint8_t index) DPRINTFN(6, "udev=%p index=%d\n", udev, index); /* automatic locking */ - if (sx_xlocked(udev->default_sx + 1)) { + if (usbd_enum_is_locked(udev)) { do_unlock = 0; } else { do_unlock = 1; - sx_xlock(udev->default_sx + 1); + usbd_enum_lock(udev); } usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); @@ -585,9 +584,8 @@ done: if (err) { usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); } - if (do_unlock) { - sx_unlock(udev->default_sx + 1); - } + if (do_unlock) + usbd_enum_unlock(udev); return (err); } @@ -823,11 +821,11 @@ usbd_set_alt_interface_index(struct usb_device *udev, uint8_t do_unlock; /* automatic locking */ - if (sx_xlocked(udev->default_sx + 1)) { + if (usbd_enum_is_locked(udev)) { do_unlock = 0; } else { do_unlock = 1; - sx_xlock(udev->default_sx + 1); + usbd_enum_lock(udev); } if (iface == NULL) { err = USB_ERR_INVAL; @@ -863,9 +861,9 @@ usbd_set_alt_interface_index(struct usb_device *udev, iface->idesc->bAlternateSetting); done: - if (do_unlock) { - sx_unlock(udev->default_sx + 1); - } + if (do_unlock) + usbd_enum_unlock(udev); + return (err); } @@ -1230,11 +1228,11 @@ usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index) return (USB_ERR_INVAL); } /* automatic locking */ - if (sx_xlocked(udev->default_sx + 1)) { + if (usbd_enum_is_locked(udev)) { do_unlock = 0; } else { do_unlock = 1; - sx_xlock(udev->default_sx + 1); + usbd_enum_lock(udev); } if (udev->curr_config_index == USB_UNCONFIG_INDEX) { @@ -1315,9 +1313,9 @@ usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index) } } done: - if (do_unlock) { - sx_unlock(udev->default_sx + 1); - } + if (do_unlock) + usbd_enum_unlock(udev); + return (0); } @@ -1779,7 +1777,8 @@ repeat_set_config: } } else if (usb_test_huawei_autoinst_p(udev, &uaa) == 0) { DPRINTFN(0, "Found Huawei auto-install disk!\n"); - err = USB_ERR_STALLED; /* fake an error */ + /* leave device unconfigured */ + usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); } } else { err = 0; /* set success */ @@ -1902,15 +1901,18 @@ static void usb_cdev_free(struct usb_device *udev) { struct usb_fs_privdata* pd; + struct cdev* pcdev; DPRINTFN(2, "Freeing device nodes\n"); while ((pd = LIST_FIRST(&udev->pd_list)) != NULL) { KASSERT(pd->cdev->si_drv1 == pd, ("privdata corrupt")); - destroy_dev_sched_cb(pd->cdev, usb_cdev_cleanup, pd); + pcdev = pd->cdev; pd->cdev = NULL; LIST_REMOVE(pd, pd_next); + if (pcdev != NULL) + destroy_dev_sched_cb(pcdev, usb_cdev_cleanup, pd); } } @@ -2448,3 +2450,37 @@ usbd_device_attached(struct usb_device *udev) { return (udev->state > USB_STATE_DETACHED); } + +/* The following function locks enumerating the given USB device. */ + +void +usbd_enum_lock(struct usb_device *udev) +{ + sx_xlock(udev->default_sx + 1); + /* + * NEWBUS LOCK NOTE: We should check if any parent SX locks + * are locked before locking Giant. Else the lock can be + * locked multiple times. + */ + mtx_lock(&Giant); +} + +/* The following function unlocks enumerating the given USB device. */ + +void +usbd_enum_unlock(struct usb_device *udev) +{ + mtx_unlock(&Giant); + sx_xunlock(udev->default_sx + 1); +} + +/* + * The following function checks the enumerating lock for the given + * USB device. + */ + +uint8_t +usbd_enum_is_locked(struct usb_device *udev) +{ + return (sx_xlocked(udev->default_sx + 1)); +} diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h index d601c146a21..682e2007e6e 100644 --- a/sys/dev/usb/usb_device.h +++ b/sys/dev/usb/usb_device.h @@ -211,5 +211,8 @@ uint8_t usb_peer_can_wakeup(struct usb_device *udev); struct usb_endpoint *usb_endpoint_foreach(struct usb_device *udev, struct usb_endpoint *ep); void usb_set_device_state(struct usb_device *udev, enum usb_dev_state state); +void usbd_enum_lock(struct usb_device *); +void usbd_enum_unlock(struct usb_device *); +uint8_t usbd_enum_is_locked(struct usb_device *); #endif /* _USB_DEVICE_H_ */ diff --git a/sys/dev/usb/usb_handle_request.c b/sys/dev/usb/usb_handle_request.c index a720919b7d8..92bf8329eb8 100644 --- a/sys/dev/usb/usb_handle_request.c +++ b/sys/dev/usb/usb_handle_request.c @@ -152,8 +152,8 @@ usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no) * attach: */ USB_XFER_UNLOCK(xfer); - mtx_lock(&Giant); /* XXX */ - sx_xlock(udev->default_sx + 1); + + usbd_enum_lock(udev); if (conf_no == USB_UNCONFIG_NO) { conf_no = USB_UNCONFIG_INDEX; @@ -176,8 +176,7 @@ usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no) goto done; } done: - mtx_unlock(&Giant); /* XXX */ - sx_unlock(udev->default_sx + 1); + usbd_enum_unlock(udev); USB_XFER_LOCK(xfer); return (err); } @@ -190,19 +189,19 @@ usb_check_alt_setting(struct usb_device *udev, usb_error_t err = 0; /* automatic locking */ - if (sx_xlocked(udev->default_sx + 1)) { + if (usbd_enum_is_locked(udev)) { do_unlock = 0; } else { do_unlock = 1; - sx_xlock(udev->default_sx + 1); + usbd_enum_lock(udev); } if (alt_index >= usbd_get_no_alts(udev->cdesc, iface->idesc)) err = USB_ERR_INVAL; - if (do_unlock) { - sx_unlock(udev->default_sx + 1); - } + if (do_unlock) + usbd_enum_unlock(udev); + return (err); } @@ -236,8 +235,8 @@ usb_handle_iface_request(struct usb_xfer *xfer, * attach: */ USB_XFER_UNLOCK(xfer); - mtx_lock(&Giant); /* XXX */ - sx_xlock(udev->default_sx + 1); + + usbd_enum_lock(udev); error = ENXIO; @@ -353,20 +352,17 @@ tr_repeat: goto tr_stalled; } tr_valid: - mtx_unlock(&Giant); - sx_unlock(udev->default_sx + 1); + usbd_enum_unlock(udev); USB_XFER_LOCK(xfer); return (0); tr_short: - mtx_unlock(&Giant); - sx_unlock(udev->default_sx + 1); + usbd_enum_unlock(udev); USB_XFER_LOCK(xfer); return (USB_ERR_SHORT_XFER); tr_stalled: - mtx_unlock(&Giant); - sx_unlock(udev->default_sx + 1); + usbd_enum_unlock(udev); USB_XFER_LOCK(xfer); return (USB_ERR_STALLED); } diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 0defc97c30c..2c81d97d126 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -96,6 +96,7 @@ struct uhub_current_state { struct uhub_softc { struct uhub_current_state sc_st;/* current state */ device_t sc_dev; /* base device */ + struct mtx sc_mtx; /* our mutex */ struct usb_device *sc_udev; /* USB device */ struct usb_xfer *sc_xfer[UHUB_N_TRANSFER]; /* interrupt xfer */ uint8_t sc_flags; @@ -428,7 +429,6 @@ repeat: mode = USB_MODE_HOST; /* need to create a new child */ - child = usb_alloc_device(sc->sc_dev, udev->bus, udev, udev->depth + 1, portno - 1, portno, speed, mode); if (child == NULL) { @@ -691,6 +691,8 @@ uhub_attach(device_t dev) sc->sc_udev = udev; sc->sc_dev = dev; + mtx_init(&sc->sc_mtx, "USB HUB mutex", NULL, MTX_DEF); + snprintf(sc->sc_name, sizeof(sc->sc_name), "%s", device_get_nameunit(dev)); @@ -774,7 +776,7 @@ uhub_attach(device_t dev) } else { /* normal HUB */ err = usbd_transfer_setup(udev, &iface_index, sc->sc_xfer, - uhub_config, UHUB_N_TRANSFER, sc, &Giant); + uhub_config, UHUB_N_TRANSFER, sc, &sc->sc_mtx); } if (err) { DPRINTFN(0, "cannot setup interrupt transfer, " @@ -850,9 +852,9 @@ uhub_attach(device_t dev) /* Start the interrupt endpoint, if any */ if (sc->sc_xfer[0] != NULL) { - USB_XFER_LOCK(sc->sc_xfer[0]); + mtx_lock(&sc->sc_mtx); usbd_transfer_start(sc->sc_xfer[0]); - USB_XFER_UNLOCK(sc->sc_xfer[0]); + mtx_unlock(&sc->sc_mtx); } /* Enable automatic power save on all USB HUBs */ @@ -868,6 +870,9 @@ error: free(udev->hub, M_USBDEV); udev->hub = NULL; } + + mtx_destroy(&sc->sc_mtx); + return (ENXIO); } @@ -908,6 +913,9 @@ uhub_detach(device_t dev) free(hub, M_USBDEV); sc->sc_udev->hub = NULL; + + mtx_destroy(&sc->sc_mtx); + return (0); } @@ -1775,10 +1783,13 @@ usb_dev_resume_peer(struct usb_device *udev) /* always update hardware power! */ (bus->methods->set_hw_power) (bus); } - sx_xlock(udev->default_sx + 1); + + usbd_enum_lock(udev); + /* notify all sub-devices about resume */ err = usb_suspend_resume(udev, 0); - sx_unlock(udev->default_sx + 1); + + usbd_enum_unlock(udev); /* check if peer has wakeup capability */ if (usb_peer_can_wakeup(udev)) { @@ -1844,10 +1855,12 @@ repeat: } } - sx_xlock(udev->default_sx + 1); + usbd_enum_lock(udev); + /* notify all sub-devices about suspend */ err = usb_suspend_resume(udev, 1); - sx_unlock(udev->default_sx + 1); + + usbd_enum_unlock(udev); if (usb_peer_can_wakeup(udev)) { /* allow device to do remote wakeup */ diff --git a/sys/dev/usb/usb_process.c b/sys/dev/usb/usb_process.c index 3b13f21c222..eb503fd18c4 100644 --- a/sys/dev/usb/usb_process.c +++ b/sys/dev/usb/usb_process.c @@ -457,3 +457,29 @@ usb_proc_drain(struct usb_process *up) } mtx_unlock(up->up_mtx); } + +/*------------------------------------------------------------------------* + * usb_proc_rewakeup + * + * This function is called to re-wakeup the the given USB + * process. This usually happens after that the USB system has been in + * polling mode, like during a panic. This function must be called + * having "up->up_mtx" locked. + *------------------------------------------------------------------------*/ +void +usb_proc_rewakeup(struct usb_process *up) +{ + /* check if not initialised */ + if (up->up_mtx == NULL) + return; + /* check if gone */ + if (up->up_gone) + return; + + mtx_assert(up->up_mtx, MA_OWNED); + + if (up->up_msleep == 0) { + /* re-wakeup */ + cv_signal(&up->up_cv); + } +} diff --git a/sys/dev/usb/usb_process.h b/sys/dev/usb/usb_process.h index 71432c3bf70..b4159af1bbd 100644 --- a/sys/dev/usb/usb_process.h +++ b/sys/dev/usb/usb_process.h @@ -75,5 +75,6 @@ void usb_proc_drain(struct usb_process *up); void usb_proc_mwait(struct usb_process *up, void *pm0, void *pm1); void usb_proc_free(struct usb_process *up); void *usb_proc_msignal(struct usb_process *up, void *pm0, void *pm1); +void usb_proc_rewakeup(struct usb_process *up); #endif /* _USB_PROCESS_H_ */ diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index 3c466fb72d3..8daf475a4b8 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -2907,13 +2907,9 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max) } /* Make sure cv_signal() and cv_broadcast() is not called */ - udev->bus->control_xfer_proc.up_dsleep = 0; udev->bus->control_xfer_proc.up_msleep = 0; - udev->bus->explore_proc.up_dsleep = 0; udev->bus->explore_proc.up_msleep = 0; - udev->bus->giant_callback_proc.up_dsleep = 0; udev->bus->giant_callback_proc.up_msleep = 0; - udev->bus->non_giant_callback_proc.up_dsleep = 0; udev->bus->non_giant_callback_proc.up_msleep = 0; /* poll USB hardware */ From 914e5afefdf6b2abad8bc299d4bed04b5f31717a Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 2 Sep 2009 10:39:46 +0000 Subject: [PATCH 0177/2592] MFC r196653: Make sure FreeBSD binaries without .note.ABI-tag section work correctly and do not match a colliding Debian GNU/kFreeBSD brandinfo statements. For this mark the Debian GNU/kFreeBSD brandinfo that it must have an .note.ABI-tag section and ignore the old EI_OSABI brandinfo when comparing a possibly colliding set of options. Due to SYSINIT we add the brandinfo in a non-deterministic order, so native FreeBSD is not always first. We may want to consider to force native FreeBSD to come first as well. The only way a problem could currently be noticed is when running an i386 binary without the .note.ABI-tag on amd64 and the Debian GNU/kFreeBSD brandinfo was matched first, as the fallback to ld-elf32.so.1 does not exist in that case. Reported and tested by: ticso In collaboration with: kib MFC after: 3 days Approved by: re (rwatson) --- sys/amd64/amd64/elf_machdep.c | 2 +- sys/compat/ia32/ia32_sysvec.c | 2 +- sys/i386/i386/elf_machdep.c | 2 +- sys/kern/imgact_elf.c | 18 +++++++++++++----- sys/sys/imgact_elf.h | 5 +++-- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index ea48b252feb..d5e7a6ead78 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -118,7 +118,7 @@ static Elf64_Brandinfo kfreebsd_brand_info = { .sysvec = &elf64_freebsd_sysvec, .interp_newpath = NULL, .brand_note = &elf64_kfreebsd_brandnote, - .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE_MANDATORY }; SYSINIT(kelf64, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index 5c2c571f113..46e0b80d270 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -180,7 +180,7 @@ static Elf32_Brandinfo kia32_brand_info = { .interp_path = "/lib/ld.so.1", .sysvec = &ia32_freebsd_sysvec, .brand_note = &elf32_kfreebsd_brandnote, - .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE_MANDATORY }; SYSINIT(kia32, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index a4ff9e2160b..abfe147769b 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c @@ -117,7 +117,7 @@ static Elf32_Brandinfo kfreebsd_brand_info = { .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, .brand_note = &elf32_kfreebsd_brandnote, - .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE_MANDATORY }; SYSINIT(kelf32, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 68035239136..ba5833a5bd6 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -238,8 +238,10 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, /* Look for an ".note.ABI-tag" ELF section */ for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; - if (bi != NULL && hdr->e_machine == bi->machine && - (bi->flags & BI_BRAND_NOTE) != 0) { + if (bi == NULL) + continue; + if (hdr->e_machine == bi->machine && (bi->flags & + (BI_BRAND_NOTE|BI_BRAND_NOTE_MANDATORY)) != 0) { ret = __elfN(check_note)(imgp, bi->brand_note, osrel); if (ret) return (bi); @@ -249,7 +251,9 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, /* If the executable has a brand, search for it in the brand list. */ for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; - if (bi != NULL && hdr->e_machine == bi->machine && + if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY) + continue; + if (hdr->e_machine == bi->machine && (hdr->e_ident[EI_OSABI] == bi->brand || strncmp((const char *)&hdr->e_ident[OLD_EI_BRAND], bi->compat_3_brand, strlen(bi->compat_3_brand)) == 0)) @@ -260,7 +264,9 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, if (interp != NULL) { for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; - if (bi != NULL && hdr->e_machine == bi->machine && + if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY) + continue; + if (hdr->e_machine == bi->machine && strcmp(interp, bi->interp_path) == 0) return (bi); } @@ -269,7 +275,9 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, /* Lacking a recognized interpreter, try the default brand */ for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; - if (bi != NULL && hdr->e_machine == bi->machine && + if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY) + continue; + if (hdr->e_machine == bi->machine && __elfN(fallback_brand) == bi->brand) return (bi); } diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h index 3eecf85000b..4ccee5df082 100644 --- a/sys/sys/imgact_elf.h +++ b/sys/sys/imgact_elf.h @@ -74,8 +74,9 @@ typedef struct { const char *interp_newpath; int flags; Elf_Brandnote *brand_note; -#define BI_CAN_EXEC_DYN 0x0001 -#define BI_BRAND_NOTE 0x0002 +#define BI_CAN_EXEC_DYN 0x0001 +#define BI_BRAND_NOTE 0x0002 /* May have note.ABI-tag section. */ +#define BI_BRAND_NOTE_MANDATORY 0x0004 /* Must have note.ABI-tag section. */ } __ElfN(Brandinfo); __ElfType(Auxargs); From 5b628e0c26d11e34ac50d8f83971db6450c9d872 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 2 Sep 2009 16:35:57 +0000 Subject: [PATCH 0178/2592] MFC r196738: In case an upper layer protocol tries to send a packet but the L2 code does not have the ethernet address for the destination within the broadcast domain in the table, we remember the original mbuf in `la_hold' in arpresolve() and send out a different packet with an arp request. In case there will be more upper layer packets to send we will free an earlier one held in `la_hold' and queue the new one. Once we get a packet in, with which we can perfect our arp table entry we send out the original 'on hold' packet, should there be any. Rather than continuing to process the packet that we received, we returned without freeing the packet that came in, which basically means that we leaked an mbuf for every arp request we sent. Rather than freeing the received packet and returning, continue to process the incoming arp packet as well. This should (a) improve some setups, also proxy-arp, in case it was an incoming arp request and (b) resembles the behaviour FreeBSD had from day 1, which alignes with RFC826 "Packet reception" (merge case). Rename 'm0' to 'hold' to make the code more understandable as well as diffable to earlier versions more easily. Handle the link-layer entry 'la' lock comepletely in the block where needed and release it as early as possible, rather than holding it longer, down to the end of the function. Found by: pointyhat, ns1 Bug hunting session with: erwin, simon, rwatson Tested by: simon on cluster machines Reviewed by: ratson, kmacy, julian Approved by: re (kib) --- sys/netinet/if_ether.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 9d1c13afe86..e118cec0fa3 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -462,11 +462,11 @@ in_arpinput(struct mbuf *m) struct rtentry *rt; struct ifaddr *ifa; struct in_ifaddr *ia; + struct mbuf *hold; struct sockaddr sa; struct in_addr isaddr, itaddr, myaddr; u_int8_t *enaddr = NULL; int op, flags; - struct mbuf *m0; int req_len; int bridged = 0, is_bridge = 0; #ifdef DEV_CARP @@ -631,11 +631,13 @@ match: la->lle_tbl->llt_ifp->if_xname, ifp->if_addrlen, (u_char *)ar_sha(ah), ":", ifp->if_xname); + LLE_WUNLOCK(la); goto reply; } if ((la->la_flags & LLE_VALID) && bcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) { if (la->la_flags & LLE_STATIC) { + LLE_WUNLOCK(la); log(LOG_ERR, "arp: %*D attempts to modify permanent " "entry for %s on %s\n", @@ -655,6 +657,7 @@ match: } if (ifp->if_addrlen != ah->ar_hln) { + LLE_WUNLOCK(la); log(LOG_WARNING, "arp from %*D: addr len: new %d, i/f %d (ignored)", ifp->if_addrlen, (u_char *) ar_sha(ah), ":", @@ -671,15 +674,14 @@ match: } la->la_asked = 0; la->la_preempt = V_arp_maxtries; - if (la->la_hold != NULL) { - m0 = la->la_hold; - la->la_hold = 0; + hold = la->la_hold; + if (hold != NULL) { + la->la_hold = NULL; memcpy(&sa, L3_ADDR(la), sizeof(sa)); - LLE_WUNLOCK(la); - - (*ifp->if_output)(ifp, m0, &sa, NULL); - return; } + LLE_WUNLOCK(la); + if (hold != NULL) + (*ifp->if_output)(ifp, hold, &sa, NULL); } reply: if (op != ARPOP_REQUEST) @@ -750,8 +752,6 @@ reply: #endif } - if (la != NULL) - LLE_WUNLOCK(la); if (itaddr.s_addr == myaddr.s_addr && IN_LINKLOCAL(ntohl(itaddr.s_addr))) { /* RFC 3927 link-local IPv4; always reply by broadcast. */ @@ -777,8 +777,6 @@ reply: return; drop: - if (la != NULL) - LLE_WUNLOCK(la); m_freem(m); } #endif From bf202eb1c6efd6b138dbe4c495b922ea1674fd90 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 3 Sep 2009 13:54:58 +0000 Subject: [PATCH 0179/2592] MFC 196705 and 196707: - Improve pmap_change_attr() on i386 so that it is able to demote a large (2/4MB) page into 4KB pages as needed. This should be fairly rare in practice. - Simplify pmap_change_attr() a bit: - Always calculate the cache bits instead of doing it on-demand. - Always set changed to TRUE rather than only doing it if it is false. Approved by: re (kib) --- sys/amd64/amd64/pmap.c | 22 +--- sys/i386/i386/pmap.c | 228 ++++++++++++++++++++++++++++++---------- sys/i386/include/pmap.h | 4 + 3 files changed, 181 insertions(+), 73 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index f0da536a012..4e35ef4aedb 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -4476,7 +4476,8 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) if (base < DMAP_MIN_ADDRESS) return (EINVAL); - cache_bits_pde = cache_bits_pte = -1; + cache_bits_pde = pmap_cache_bits(mode, 1); + cache_bits_pte = pmap_cache_bits(mode, 0); changed = FALSE; /* @@ -4493,8 +4494,6 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) * memory type, then we need not demote this page. Just * increment tmpva to the next 1GB page frame. */ - if (cache_bits_pde < 0) - cache_bits_pde = pmap_cache_bits(mode, 1); if ((*pdpe & PG_PDE_CACHE) == cache_bits_pde) { tmpva = trunc_1gpage(tmpva) + NBPDP; continue; @@ -4522,8 +4521,6 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) * memory type, then we need not demote this page. Just * increment tmpva to the next 2MB page frame. */ - if (cache_bits_pde < 0) - cache_bits_pde = pmap_cache_bits(mode, 1); if ((*pde & PG_PDE_CACHE) == cache_bits_pde) { tmpva = trunc_2mpage(tmpva) + NBPDR; continue; @@ -4557,12 +4554,9 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) for (tmpva = base; tmpva < base + size; ) { pdpe = pmap_pdpe(kernel_pmap, tmpva); if (*pdpe & PG_PS) { - if (cache_bits_pde < 0) - cache_bits_pde = pmap_cache_bits(mode, 1); if ((*pdpe & PG_PDE_CACHE) != cache_bits_pde) { pmap_pde_attr(pdpe, cache_bits_pde); - if (!changed) - changed = TRUE; + changed = TRUE; } if (tmpva >= VM_MIN_KERNEL_ADDRESS) { if (pa_start == pa_end) { @@ -4588,12 +4582,9 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) } pde = pmap_pdpe_to_pde(pdpe, tmpva); if (*pde & PG_PS) { - if (cache_bits_pde < 0) - cache_bits_pde = pmap_cache_bits(mode, 1); if ((*pde & PG_PDE_CACHE) != cache_bits_pde) { pmap_pde_attr(pde, cache_bits_pde); - if (!changed) - changed = TRUE; + changed = TRUE; } if (tmpva >= VM_MIN_KERNEL_ADDRESS) { if (pa_start == pa_end) { @@ -4616,13 +4607,10 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) } tmpva = trunc_2mpage(tmpva) + NBPDR; } else { - if (cache_bits_pte < 0) - cache_bits_pte = pmap_cache_bits(mode, 0); pte = pmap_pde_to_pte(pde, tmpva); if ((*pte & PG_PTE_CACHE) != cache_bits_pte) { pmap_pte_attr(pte, cache_bits_pte); - if (!changed) - changed = TRUE; + changed = TRUE; } if (tmpva >= VM_MIN_KERNEL_ADDRESS) { if (pa_start == pa_end) { diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 405cbd30cfe..548dbdb2ac6 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -288,12 +288,15 @@ static boolean_t pmap_enter_pde(pmap_t pmap, vm_offset_t va, vm_page_t m, static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte); static void pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); +static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); static boolean_t pmap_is_modified_pvh(struct md_page *pvh); static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); static vm_page_t pmap_lookup_pt_page(pmap_t pmap, vm_offset_t va); +static void pmap_pde_attr(pd_entry_t *pde, int cache_bits); static void pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); static boolean_t pmap_protect_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t sva, vm_prot_t prot); +static void pmap_pte_attr(pt_entry_t *pte, int cache_bits); static void pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva, vm_page_t *free); static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t sva, @@ -2289,32 +2292,62 @@ pmap_pv_insert_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa) } /* - * Tries to demote a 2- or 4MB page mapping. + * Fills a page table page with mappings to consecutive physical pages. + */ +static void +pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte) +{ + pt_entry_t *pte; + + for (pte = firstpte; pte < firstpte + NPTEPG; pte++) { + *pte = newpte; + newpte += PAGE_SIZE; + } +} + +/* + * Tries to demote a 2- or 4MB page mapping. If demotion fails, the + * 2- or 4MB page mapping is invalidated. */ static boolean_t pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) { pd_entry_t newpde, oldpde; pmap_t allpmaps_entry; - pt_entry_t *firstpte, newpte, *pte; + pt_entry_t *firstpte, newpte; vm_paddr_t mptepa; vm_page_t free, mpte; PMAP_LOCK_ASSERT(pmap, MA_OWNED); + oldpde = *pde; + KASSERT((oldpde & (PG_PS | PG_V)) == (PG_PS | PG_V), + ("pmap_demote_pde: oldpde is missing PG_PS and/or PG_V")); mpte = pmap_lookup_pt_page(pmap, va); if (mpte != NULL) pmap_remove_pt_page(pmap, mpte); else { - KASSERT((*pde & PG_W) == 0, + KASSERT((oldpde & PG_W) == 0, ("pmap_demote_pde: page table page for a wired mapping" " is missing")); - free = NULL; - pmap_remove_pde(pmap, pde, trunc_4mpage(va), &free); - pmap_invalidate_page(pmap, trunc_4mpage(va)); - pmap_free_zero_pages(free); - CTR2(KTR_PMAP, "pmap_demote_pde: failure for va %#x" - " in pmap %p", va, pmap); - return (FALSE); + + /* + * Invalidate the 2- or 4MB page mapping and return + * "failure" if the mapping was never accessed or the + * allocation of the new page table page fails. + */ + if ((oldpde & PG_A) == 0 || (mpte = vm_page_alloc(NULL, + va >> PDRSHIFT, VM_ALLOC_NOOBJ | VM_ALLOC_NORMAL | + VM_ALLOC_WIRED)) == NULL) { + free = NULL; + pmap_remove_pde(pmap, pde, trunc_4mpage(va), &free); + pmap_invalidate_page(pmap, trunc_4mpage(va)); + pmap_free_zero_pages(free); + CTR2(KTR_PMAP, "pmap_demote_pde: failure for va %#x" + " in pmap %p", va, pmap); + return (FALSE); + } + if (va < VM_MAXUSER_ADDRESS) + pmap->pm_stats.resident_count++; } mptepa = VM_PAGE_TO_PHYS(mpte); @@ -2348,30 +2381,32 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) } firstpte = PADDR2; } - oldpde = *pde; newpde = mptepa | PG_M | PG_A | (oldpde & PG_U) | PG_RW | PG_V; - KASSERT((oldpde & (PG_A | PG_V)) == (PG_A | PG_V), - ("pmap_demote_pde: oldpde is missing PG_A and/or PG_V")); + KASSERT((oldpde & PG_A) != 0, + ("pmap_demote_pde: oldpde is missing PG_A")); KASSERT((oldpde & (PG_M | PG_RW)) != PG_RW, ("pmap_demote_pde: oldpde is missing PG_M")); - KASSERT((oldpde & PG_PS) != 0, - ("pmap_demote_pde: oldpde is missing PG_PS")); newpte = oldpde & ~PG_PS; if ((newpte & PG_PDE_PAT) != 0) newpte ^= PG_PDE_PAT | PG_PTE_PAT; /* - * If the mapping has changed attributes, update the page table - * entries. - */ + * If the page table page is new, initialize it. + */ + if (mpte->wire_count == 1) { + mpte->wire_count = NPTEPG; + pmap_fill_ptp(firstpte, newpte); + } KASSERT((*firstpte & PG_FRAME) == (newpte & PG_FRAME), ("pmap_demote_pde: firstpte and newpte map different physical" " addresses")); + + /* + * If the mapping has changed attributes, update the page table + * entries. + */ if ((*firstpte & PG_PTE_PROMOTE) != (newpte & PG_PTE_PROMOTE)) - for (pte = firstpte; pte < firstpte + NPTEPG; pte++) { - *pte = newpte; - newpte += PAGE_SIZE; - } + pmap_fill_ptp(firstpte, newpte); /* * Demote the mapping. This pmap is locked. The old PDE has @@ -4426,6 +4461,40 @@ pmap_clear_reference(vm_page_t m) * Miscellaneous support routines follow */ +/* Adjust the cache mode for a 4KB page mapped via a PTE. */ +static __inline void +pmap_pte_attr(pt_entry_t *pte, int cache_bits) +{ + u_int opte, npte; + + /* + * The cache mode bits are all in the low 32-bits of the + * PTE, so we can just spin on updating the low 32-bits. + */ + do { + opte = *(u_int *)pte; + npte = opte & ~PG_PTE_CACHE; + npte |= cache_bits; + } while (npte != opte && !atomic_cmpset_int((u_int *)pte, opte, npte)); +} + +/* Adjust the cache mode for a 2/4MB page mapped via a PDE. */ +static __inline void +pmap_pde_attr(pd_entry_t *pde, int cache_bits) +{ + u_int opde, npde; + + /* + * The cache mode bits are all in the low 32-bits of the + * PDE, so we can just spin on updating the low 32-bits. + */ + do { + opde = *(u_int *)pde; + npde = opde & ~PG_PDE_CACHE; + npde |= cache_bits; + } while (npde != opde && !atomic_cmpset_int((u_int *)pde, opde, npde)); +} + /* * Map a set of physical memory pages into the kernel virtual * address space. Return a pointer to where it is mapped. This @@ -4537,13 +4606,23 @@ pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) } } +/* + * Changes the specified virtual address range's memory type to that given by + * the parameter "mode". The specified virtual address range must be + * completely contained within either the kernel map. + * + * Returns zero if the change completed successfully, and either EINVAL or + * ENOMEM if the change failed. Specifically, EINVAL is returned if some part + * of the virtual address range was not mapped, and ENOMEM is returned if + * there was insufficient memory available to complete the change. + */ int pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) { vm_offset_t base, offset, tmpva; - pt_entry_t *pte; - u_int opte, npte; pd_entry_t *pde; + pt_entry_t *pte; + int cache_bits_pte, cache_bits_pde; boolean_t changed; base = trunc_page(va); @@ -4556,47 +4635,84 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) if (base < VM_MIN_KERNEL_ADDRESS) return (EINVAL); - /* 4MB pages and pages that aren't mapped aren't supported. */ - for (tmpva = base; tmpva < (base + size); tmpva += PAGE_SIZE) { - pde = pmap_pde(kernel_pmap, tmpva); - if (*pde & PG_PS) - return (EINVAL); - if (*pde == 0) - return (EINVAL); - pte = vtopte(tmpva); - if (*pte == 0) - return (EINVAL); - } - + cache_bits_pde = pmap_cache_bits(mode, 1); + cache_bits_pte = pmap_cache_bits(mode, 0); changed = FALSE; /* - * Ok, all the pages exist and are 4k, so run through them updating - * their cache mode. + * Pages that aren't mapped aren't supported. Also break down + * 2/4MB pages into 4KB pages if required. */ - for (tmpva = base; size > 0; ) { - pte = vtopte(tmpva); + PMAP_LOCK(kernel_pmap); + for (tmpva = base; tmpva < base + size; ) { + pde = pmap_pde(kernel_pmap, tmpva); + if (*pde == 0) { + PMAP_UNLOCK(kernel_pmap); + return (EINVAL); + } + if (*pde & PG_PS) { + /* + * If the current 2/4MB page already has + * the required memory type, then we need not + * demote this page. Just increment tmpva to + * the next 2/4MB page frame. + */ + if ((*pde & PG_PDE_CACHE) == cache_bits_pde) { + tmpva = trunc_4mpage(tmpva) + NBPDR; + continue; + } - /* - * The cache mode bits are all in the low 32-bits of the - * PTE, so we can just spin on updating the low 32-bits. - */ - do { - opte = *(u_int *)pte; - npte = opte & ~(PG_PTE_PAT | PG_NC_PCD | PG_NC_PWT); - npte |= pmap_cache_bits(mode, 0); - } while (npte != opte && - !atomic_cmpset_int((u_int *)pte, opte, npte)); - if (npte != opte) - changed = TRUE; + /* + * If the current offset aligns with a 2/4MB + * page frame and there is at least 2/4MB left + * within the range, then we need not break + * down this page into 4KB pages. + */ + if ((tmpva & PDRMASK) == 0 && + tmpva + PDRMASK < base + size) { + tmpva += NBPDR; + continue; + } + if (!pmap_demote_pde(kernel_pmap, pde, tmpva)) { + PMAP_UNLOCK(kernel_pmap); + return (ENOMEM); + } + } + pte = vtopte(tmpva); + if (*pte == 0) { + PMAP_UNLOCK(kernel_pmap); + return (EINVAL); + } tmpva += PAGE_SIZE; - size -= PAGE_SIZE; + } + PMAP_UNLOCK(kernel_pmap); + + /* + * Ok, all the pages exist, so run through them updating their + * cache mode if required. + */ + for (tmpva = base; tmpva < base + size; ) { + pde = pmap_pde(kernel_pmap, tmpva); + if (*pde & PG_PS) { + if ((*pde & PG_PDE_CACHE) != cache_bits_pde) { + pmap_pde_attr(pde, cache_bits_pde); + changed = TRUE; + } + tmpva = trunc_4mpage(tmpva) + NBPDR; + } else { + pte = vtopte(tmpva); + if ((*pte & PG_PTE_CACHE) != cache_bits_pte) { + pmap_pte_attr(pte, cache_bits_pte); + changed = TRUE; + } + tmpva += PAGE_SIZE; + } } /* - * Flush CPU caches to make sure any data isn't cached that shouldn't - * be, etc. - */ + * Flush CPU caches to make sure any data isn't cached that + * shouldn't be, etc. + */ if (changed) { pmap_invalidate_range(kernel_pmap, base, tmpva); pmap_invalidate_cache_range(base, tmpva); diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h index c90f94707e4..54e8c206cd4 100644 --- a/sys/i386/include/pmap.h +++ b/sys/i386/include/pmap.h @@ -81,6 +81,10 @@ #define PG_PROT (PG_RW|PG_U) /* all protection bits . */ #define PG_N (PG_NC_PWT|PG_NC_PCD) /* Non-cacheable */ +/* Page level cache control fields used to determine the PAT type */ +#define PG_PDE_CACHE (PG_PDE_PAT | PG_NC_PWT | PG_NC_PCD) +#define PG_PTE_CACHE (PG_PTE_PAT | PG_NC_PWT | PG_NC_PCD) + /* * Promotion to a 2 or 4MB (PDE) page mapping requires that the corresponding * 4KB (PTE) page mappings have identical settings for the following fields: From fa0dc8bb62cf3a57ba058b290bf177d9f7332bb2 Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Fri, 4 Sep 2009 05:37:49 +0000 Subject: [PATCH 0180/2592] MFC r196809: fix a TX issue on big endian machines like powerpc or sparc64. Now zyd(4) should work on all architectures. Obtained from: OpenBSD Approved by: re (kib) --- sys/dev/usb/wlan/if_zyd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index 9bdb6eaaf16..493c5fad16a 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -2547,7 +2547,7 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) bits = (rate == 11) ? (totlen * 16) + 10 : ((rate == 22) ? (totlen * 8) + 10 : (totlen * 8)); - desc->plcp_length = bits / ratediv[phy]; + desc->plcp_length = htole16(bits / ratediv[phy]); desc->plcp_service = 0; if (rate == 22 && (bits % 11) > 0 && (bits % 11) <= 3) desc->plcp_service |= ZYD_PLCP_LENGEXT; From e181d489f6c14984c1d46556f9edea6de7f1da9f Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Fri, 4 Sep 2009 07:13:07 +0000 Subject: [PATCH 0181/2592] MFC r196450 Add clarifications to the kproc and kthread manpages and link the kthread_create(9) man page to the kproc(9) page as it has migrated and people looking for it may need a hand to find its new name. Approved by: re (kib) --- share/man/man9/Makefile | 1 + share/man/man9/kproc.9 | 22 ++++++++++++++++++++++ share/man/man9/kthread.9 | 21 +++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 3148d5eed1c..86b5838c112 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -713,6 +713,7 @@ MLINKS+=kobj.9 DEFINE_CLASS.9 \ kobj.9 kobj_delete.9 \ kobj.9 kobj_init.9 MLINKS+=kproc.9 kproc_create.9 \ + kproc.9 kthread_create.9 \ kproc.9 kproc_exit.9 \ kproc.9 kproc_resume.9 \ kproc.9 kproc_shutdown.9 \ diff --git a/share/man/man9/kproc.9 b/share/man/man9/kproc.9 index 23ce05c28d6..bb56235453c 100644 --- a/share/man/man9/kproc.9 +++ b/share/man/man9/kproc.9 @@ -64,6 +64,28 @@ .Fa "int flags" "int pages" "char * procname" "const char *fmt" "..." .Fc .Sh DESCRIPTION +In +.Fx 8.0 , +the +.Fn kthread* 9 +family of functions was renamed to be the +.Fn kproc* 9 +family of functions, as they were misnamed +and actually produced kernel processes. +A new family of +.Em different +.Fn kthread_* 9 +functions was added to produce +.Em real +kernel +.Em threads . +See the +.Xr kthread 9 +man page for more information on those calls. +Also note that the +.Fn kproc_kthread_add 9 +function appears in both pages as its functionality is split. +.Pp The function .Fn kproc_start is used to start diff --git a/share/man/man9/kthread.9 b/share/man/man9/kthread.9 index 29d678c66dc..ffb5179614d 100644 --- a/share/man/man9/kthread.9 +++ b/share/man/man9/kthread.9 @@ -65,6 +65,27 @@ .Fa "int flags" "int pages" "char * procname" "const char *fmt" "..." .Fc .Sh DESCRIPTION +In +.Fx 8.0 , +the older family of +.Fn kthread_* 9 +functions was renamed to be the +.Fn kproc_* 9 +family of functions, +as they were previously misnamed +and actually produced kernel processes. +This new family of +.Fn kthread_* 9 +functions was added to produce +.Em real +kernel threads. +See the +.Xr kproc 9 +man page for more information on the renamed calls. +Also note that the +.Fn kproc_kthread_add 9 +function appears in both pages as its functionality is split. +.Pp The function .Fn kthread_start is used to start From 8b3a7204a7c377eac2f2e21fe8b56527bff61cb8 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Fri, 4 Sep 2009 11:32:05 +0000 Subject: [PATCH 0182/2592] - MFC r196568: - Add quirk for Sony DSC digital cameras. This umass devices fail to attach without these quirks applied. Approved by: re (kib) --- sys/cam/scsi/scsi_da.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index f5ec895909b..e331545032a 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -554,6 +554,14 @@ static struct da_quirk_entry da_quirk_table[] = { {T_DIRECT, SIP_MEDIA_REMOVABLE, "Netac", "OnlyDisk*", "2000"}, /*quirks*/ DA_Q_NO_SYNC_CACHE + }, + { + /* + * Sony Cyber-Shot DSC cameras + * PR: usb/137035 + */ + {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Sony DSC", "*"}, + /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_PREVENT } }; From b3d8f9c3fcf1c7bf7fd0a200a38f6e28fde8b1a6 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Fri, 4 Sep 2009 16:41:17 +0000 Subject: [PATCH 0183/2592] MFC r196721: Make sure rx descriptor ring align on 16 bytes. I guess the alignment requirement could be multiple of 4 bytes but I think using descriptor size would make intention clearer. Previously the size of rx descriptor was not power of 2 so it caused panic in bus_dmamem_alloc(9). Reported by: Jeff Blank (jb000003 <> mr-happy dot com) Approved by: re (kib) --- sys/dev/txp/if_txp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/dev/txp/if_txp.c b/sys/dev/txp/if_txp.c index 619b3f71ee6..9396f4d9ecb 100644 --- a/sys/dev/txp/if_txp.c +++ b/sys/dev/txp/if_txp.c @@ -1389,7 +1389,8 @@ txp_alloc_rings(struct txp_softc *sc) /* High priority rx ring. */ error = txp_dma_alloc(sc, "hi priority rx ring", - &sc->sc_cdata.txp_rxhiring_tag, sizeof(struct txp_rx_desc), 0, + &sc->sc_cdata.txp_rxhiring_tag, + roundup(sizeof(struct txp_rx_desc), 16), 0, &sc->sc_cdata.txp_rxhiring_map, (void **)&sc->sc_ldata.txp_rxhiring, sizeof(struct txp_rx_desc) * RX_ENTRIES, &sc->sc_ldata.txp_rxhiring_paddr); @@ -1409,7 +1410,8 @@ txp_alloc_rings(struct txp_softc *sc) /* Low priority rx ring. */ error = txp_dma_alloc(sc, "low priority rx ring", - &sc->sc_cdata.txp_rxloring_tag, sizeof(struct txp_rx_desc), 0, + &sc->sc_cdata.txp_rxloring_tag, + roundup(sizeof(struct txp_rx_desc), 16), 0, &sc->sc_cdata.txp_rxloring_map, (void **)&sc->sc_ldata.txp_rxloring, sizeof(struct txp_rx_desc) * RX_ENTRIES, &sc->sc_ldata.txp_rxloring_paddr); From 0bb40ca3e0009f29079191f1910386c5cda2ddd7 Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Fri, 4 Sep 2009 22:37:03 +0000 Subject: [PATCH 0184/2592] This patch seperates the control of header split from LRO (which it was previously dependent on), LRO gets turned off when bridging but its been found that header split is still a performance win in that case. Secondly, there was some interface specific control in stats code that has been missing, and a logic error that resulted in bogus reporting. Thanks to Manish and John of LineRateSystems for the report and help in this code. Approved by: re --- sys/dev/ixgbe/ixgbe.c | 68 +++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index bd95bdf0a9f..23b185722b2 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -46,7 +46,7 @@ int ixgbe_display_debug_stats = 0; /********************************************************************* * Driver version *********************************************************************/ -char ixgbe_driver_version[] = "1.8.8"; +char ixgbe_driver_version[] = "1.8.9"; /********************************************************************* * PCI Device ID Table @@ -245,6 +245,15 @@ TUNABLE_INT("hw.ixgbe.flow_control", &ixgbe_flow_control); static int ixgbe_enable_msix = 1; TUNABLE_INT("hw.ixgbe.enable_msix", &ixgbe_enable_msix); +/* + * Header split has seemed to be beneficial in + * all circumstances tested, so its on by default + * however this variable will allow it to be disabled + * for some debug purposes. + */ +static bool ixgbe_header_split = TRUE; +TUNABLE_INT("hw.ixgbe.hdr_split", &ixgbe_header_split); + /* * Number of Queues, should normally * be left at 0, it then autoconfigures to @@ -454,7 +463,6 @@ ixgbe_attach(device_t dev) */ if (nmbclusters > 0 ) { int s; - /* Calculate the total RX mbuf needs */ s = (ixgbe_rxd * adapter->num_queues) * ixgbe_total_ports; if (s > nmbclusters) { device_printf(dev, "RX Descriptors exceed " @@ -1459,8 +1467,7 @@ ixgbe_msix_link(void *arg) device_printf(adapter->dev, "\nCRITICAL: ECC ERROR!! " "Please Reboot!!\n"); IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); - } - if (reg_eicr & IXGBE_EICR_GPI_SDP1) { + } else if (reg_eicr & IXGBE_EICR_GPI_SDP1) { /* Clear the interrupt */ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); taskqueue_enqueue(adapter->tq, &adapter->msf_task); @@ -1883,7 +1890,11 @@ ixgbe_set_multi(struct adapter *adapter) IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl); +#if __FreeBSD_version < 800000 + IF_ADDR_LOCK(ifp); +#else if_maddr_rlock(ifp); +#endif TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1892,7 +1903,11 @@ ixgbe_set_multi(struct adapter *adapter) IXGBE_ETH_LENGTH_OF_ADDRESS); mcnt++; } +#if __FreeBSD_version < 800000 + IF_ADDR_UNLOCK(ifp); +#else if_maddr_runlock(ifp); +#endif update_ptr = mta; ixgbe_update_mc_addr_list(&adapter->hw, @@ -3534,7 +3549,10 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) rxr->next_to_check = 0; rxr->last_cleaned = 0; rxr->lro_enabled = FALSE; - rxr->hdr_split = FALSE; + + /* Use header split if configured */ + if (ixgbe_header_split) + rxr->hdr_split = TRUE; bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -3553,7 +3571,6 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) } INIT_DEBUGOUT("RX LRO Initialized\n"); rxr->lro_enabled = TRUE; - rxr->hdr_split = TRUE; lro->ifp = adapter->ifp; } @@ -4457,24 +4474,42 @@ ixgbe_update_stats_counters(struct adapter *adapter) struct ifnet *ifp = adapter->ifp;; struct ixgbe_hw *hw = &adapter->hw; u32 missed_rx = 0, bprc, lxon, lxoff, total; + u64 total_missed_rx = 0; adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); for (int i = 0; i < 8; i++) { - int mp; - mp = IXGBE_READ_REG(hw, IXGBE_MPC(i)); - missed_rx += mp; - adapter->stats.mpc[i] += mp; - adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i)); + /* missed_rx tallies misses for the gprc workaround */ + missed_rx += IXGBE_READ_REG(hw, IXGBE_MPC(i)); + adapter->stats.mpc[i] += missed_rx; + /* Running comprehensive total for stats display */ + total_missed_rx += adapter->stats.mpc[i]; + if (hw->mac.type == ixgbe_mac_82598EB) + adapter->stats.rnbc[i] += + IXGBE_READ_REG(hw, IXGBE_RNBC(i)); } /* Hardware workaround, gprc counts missed packets */ adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC); adapter->stats.gprc -= missed_rx; - adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); - adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); - adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH); + if (hw->mac.type == ixgbe_mac_82599EB) { + adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); + IXGBE_READ_REG(hw, IXGBE_GORCH); /* clears register */ + adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); + IXGBE_READ_REG(hw, IXGBE_GOTCH); /* clears register */ + adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL); + IXGBE_READ_REG(hw, IXGBE_TORH); /* clears register */ + adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + } else { + adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); + adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + /* 82598 only has a counter in the high register */ + adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); + adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GOTCH); + adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH); + } /* * Workaround: mprc hardware is incorrectly counting @@ -4494,9 +4529,6 @@ ixgbe_update_stats_counters(struct adapter *adapter) adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522); adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC); - adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); - adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); - lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC); adapter->stats.lxontxc += lxon; lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); @@ -4532,7 +4564,7 @@ ixgbe_update_stats_counters(struct adapter *adapter) ifp->if_collisions = 0; /* Rx Errors */ - ifp->if_ierrors = missed_rx + adapter->stats.crcerrs + + ifp->if_ierrors = total_missed_rx + adapter->stats.crcerrs + adapter->stats.rlec; } From 9d4abd543383b0ba33908017888a367d32254749 Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Sat, 5 Sep 2009 00:50:08 +0000 Subject: [PATCH 0185/2592] Ready for BETA4. Approved by: re (implicit) --- sys/conf/newvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index 25a5a77c2bb..adf87ba9bcc 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.0" -BRANCH="BETA3" +BRANCH="BETA4" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi From b89c1617934656fef1890e257ca51bc1f3ec066b Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 5 Sep 2009 06:24:28 +0000 Subject: [PATCH 0186/2592] MFC r196777, r196796: ATI SB600 can't handle 256 sectors transfers with FPDMA (NCQ). Approved by: re (ATA-CAM blanket) --- sys/dev/ahci/ahci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 189ab121e12..2d8be431017 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1942,6 +1942,9 @@ ahciaction(struct cam_sim *sim, union ccb *ccb) cpi->protocol = PROTO_ATA; cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; cpi->maxio = MAXPHYS; + /* ATI SB600 can't handle 256 sectors with FPDMA (NCQ). */ + if (pci_get_devid(device_get_parent(dev)) == 0x43801002) + cpi->maxio = min(cpi->maxio, 128 * 512); cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; From 45f395006c009138c727bcad64eec2cc39cbcc80 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 5 Sep 2009 08:03:29 +0000 Subject: [PATCH 0187/2592] MFC r196529: Rather than having enabled/disabled, implement a max queue depth. While usually not an issue, this firewalls bugs in the code that may run us out of memory. Fix a memory exhaustion in the case where devctl was disabled, but the link was bouncing. The check to queue was in the wrong place. Implement a new sysctl hw.bus.devctl_queue to control the depth. Make compatibility hacks for hw.bus.devctl_disable to ease transition. Reviewed by: emaste@ Approved by: re@ (kib) MFC after: asap --- sys/kern/subr_bus.c | 75 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 2964b8c1a22..f202631ce88 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -350,11 +350,18 @@ device_sysctl_fini(device_t dev) * tested since 3.4 or 2.2.8! */ +/* Deprecated way to adjust queue length */ static int sysctl_devctl_disable(SYSCTL_HANDLER_ARGS); -static int devctl_disable = 0; -TUNABLE_INT("hw.bus.devctl_disable", &devctl_disable); +/* XXX Need to support old-style tunable hw.bus.devctl_disable" */ SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_disable, CTLTYPE_INT | CTLFLAG_RW, NULL, - 0, sysctl_devctl_disable, "I", "devctl disable"); + 0, sysctl_devctl_disable, "I", "devctl disable -- deprecated"); + +#define DEVCTL_DEFAULT_QUEUE_LEN 1000 +static int sysctl_devctl_queue(SYSCTL_HANDLER_ARGS); +static int devctl_queue_length = DEVCTL_DEFAULT_QUEUE_LEN; +TUNABLE_INT("hw.bus.devctl_queue", &devctl_queue_length); +SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_queue, CTLTYPE_INT | CTLFLAG_RW, NULL, + 0, sysctl_devctl_queue, "I", "devctl queue length"); static d_open_t devopen; static d_close_t devclose; @@ -385,6 +392,7 @@ static struct dev_softc { int inuse; int nonblock; + int queued; struct mtx mtx; struct cv cv; struct selinfo sel; @@ -423,7 +431,7 @@ devclose(struct cdev *dev, int fflag, int devtype, struct thread *td) mtx_lock(&devsoftc.mtx); cv_broadcast(&devsoftc.cv); mtx_unlock(&devsoftc.mtx); - + devsoftc.async_proc = NULL; return (0); } @@ -458,6 +466,7 @@ devread(struct cdev *dev, struct uio *uio, int ioflag) } n1 = TAILQ_FIRST(&devsoftc.devq); TAILQ_REMOVE(&devsoftc.devq, n1, dei_link); + devsoftc.queued--; mtx_unlock(&devsoftc.mtx); rv = uiomove(n1->dei_data, strlen(n1->dei_data), uio); free(n1->dei_data, M_BUS); @@ -531,21 +540,33 @@ devctl_process_running(void) void devctl_queue_data(char *data) { - struct dev_event_info *n1 = NULL; + struct dev_event_info *n1 = NULL, *n2 = NULL; struct proc *p; - /* - * Do not allow empty strings to be queued, as they - * cause devd to exit prematurely. - */ if (strlen(data) == 0) return; + if (devctl_queue_length == 0) + return; n1 = malloc(sizeof(*n1), M_BUS, M_NOWAIT); if (n1 == NULL) return; n1->dei_data = data; mtx_lock(&devsoftc.mtx); + if (devctl_queue_length == 0) { + free(n1->dei_data, M_BUS); + free(n1, M_BUS); + return; + } + /* Leave at least one spot in the queue... */ + while (devsoftc.queued > devctl_queue_length - 1) { + n2 = TAILQ_FIRST(&devsoftc.devq); + TAILQ_REMOVE(&devsoftc.devq, n2, dei_link); + free(n2->dei_data, M_BUS); + free(n2, M_BUS); + devsoftc.queued--; + } TAILQ_INSERT_TAIL(&devsoftc.devq, n1, dei_link); + devsoftc.queued++; cv_broadcast(&devsoftc.cv); mtx_unlock(&devsoftc.mtx); selwakeup(&devsoftc.sel); @@ -614,7 +635,7 @@ devaddq(const char *type, const char *what, device_t dev) char *pnp = NULL; const char *parstr; - if (devctl_disable) + if (!devctl_queue_length)/* Rare race, but lost races safely discard */ return; data = malloc(1024, M_BUS, M_NOWAIT); if (data == NULL) @@ -731,12 +752,11 @@ sysctl_devctl_disable(SYSCTL_HANDLER_ARGS) struct dev_event_info *n1; int dis, error; - dis = devctl_disable; + dis = devctl_queue_length == 0; error = sysctl_handle_int(oidp, &dis, 0, req); if (error || !req->newptr) return (error); mtx_lock(&devsoftc.mtx); - devctl_disable = dis; if (dis) { while (!TAILQ_EMPTY(&devsoftc.devq)) { n1 = TAILQ_FIRST(&devsoftc.devq); @@ -744,6 +764,35 @@ sysctl_devctl_disable(SYSCTL_HANDLER_ARGS) free(n1->dei_data, M_BUS); free(n1, M_BUS); } + devsoftc.queued = 0; + devctl_queue_length = 0; + } else { + devctl_queue_length = DEVCTL_DEFAULT_QUEUE_LEN; + } + mtx_unlock(&devsoftc.mtx); + return (0); +} + +static int +sysctl_devctl_queue(SYSCTL_HANDLER_ARGS) +{ + struct dev_event_info *n1; + int q, error; + + q = devctl_queue_length; + error = sysctl_handle_int(oidp, &q, 0, req); + if (error || !req->newptr) + return (error); + if (q < 0) + return (EINVAL); + mtx_lock(&devsoftc.mtx); + devctl_queue_length = q; + while (devsoftc.queued > devctl_queue_length) { + n1 = TAILQ_FIRST(&devsoftc.devq); + TAILQ_REMOVE(&devsoftc.devq, n1, dei_link); + free(n1->dei_data, M_BUS); + free(n1, M_BUS); + devsoftc.queued--; } mtx_unlock(&devsoftc.mtx); return (0); @@ -886,7 +935,7 @@ devclass_find_internal(const char *classname, const char *parentname, if (create && !dc) { PDEBUG(("creating %s", classname)); dc = malloc(sizeof(struct devclass) + strlen(classname) + 1, - M_BUS, M_NOWAIT|M_ZERO); + M_BUS, M_NOWAIT | M_ZERO); if (!dc) return (NULL); dc->parent = NULL; From a0ed3d8546a4f75f27d7e2e188ea679367bc5d39 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 5 Sep 2009 13:10:54 +0000 Subject: [PATCH 0188/2592] MFC r196689: Remove spurious pfs_unlock(). Approved by: re (rwatson) --- sys/fs/pseudofs/pseudofs_vnops.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c index e03749b97c1..34ca500c985 100644 --- a/sys/fs/pseudofs/pseudofs_vnops.c +++ b/sys/fs/pseudofs/pseudofs_vnops.c @@ -339,7 +339,6 @@ pfs_getextattr(struct vop_getextattr_args *va) if (proc != NULL) PROC_UNLOCK(proc); - pfs_unlock(pn); PFS_RETURN (error); } From b9d99ec84dda1338bf7ca4a79d4abde5686e6132 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 5 Sep 2009 15:01:56 +0000 Subject: [PATCH 0189/2592] MFC r196740: Fix regression introduced with NFSv4 ACL support - make acl_to_text(3) and acl_calc_mask(3) return error instead of crashing when acl passed to them is NULL. Submitted by: markus Reviewed by: rwatson Approved by: re (kib) --- lib/libc/posix1e/acl_calc_mask.c | 13 +++++++------ lib/libc/posix1e/acl_to_text.c | 10 +++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/libc/posix1e/acl_calc_mask.c b/lib/libc/posix1e/acl_calc_mask.c index 95fd26055fa..a2d15276bf3 100644 --- a/lib/libc/posix1e/acl_calc_mask.c +++ b/lib/libc/posix1e/acl_calc_mask.c @@ -50,12 +50,6 @@ acl_calc_mask(acl_t *acl_p) acl_t acl_new; int i, mask_mode, mask_num; - if (!_acl_brand_may_be(*acl_p, ACL_BRAND_POSIX)) { - errno = EINVAL; - return (-1); - } - _acl_brand_as(*acl_p, ACL_BRAND_POSIX); - /* * (23.4.2.4) requires acl_p to point to a pointer to a valid ACL. * Since one of the primary reasons to use this function would be @@ -67,6 +61,13 @@ acl_calc_mask(acl_t *acl_p) errno = EINVAL; return (-1); } + + if (!_acl_brand_may_be(*acl_p, ACL_BRAND_POSIX)) { + errno = EINVAL; + return (-1); + } + _acl_brand_as(*acl_p, ACL_BRAND_POSIX); + acl_int = &(*acl_p)->ats_acl; if ((acl_int->acl_cnt < 3) || (acl_int->acl_cnt > ACL_MAX_ENTRIES)) { errno = EINVAL; diff --git a/lib/libc/posix1e/acl_to_text.c b/lib/libc/posix1e/acl_to_text.c index 3485b1e7777..79a950a543c 100644 --- a/lib/libc/posix1e/acl_to_text.c +++ b/lib/libc/posix1e/acl_to_text.c @@ -70,11 +70,6 @@ _posix1e_acl_to_text(acl_t acl, ssize_t *len_p, int flags) if (buf == NULL) return(NULL); - if (acl == NULL) { - errno = EINVAL; - return(NULL); - } - acl_int = &acl->ats_acl; mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ @@ -243,6 +238,11 @@ char * acl_to_text_np(acl_t acl, ssize_t *len_p, int flags) { + if (acl == NULL) { + errno = EINVAL; + return(NULL); + } + switch (_acl_brand(acl)) { case ACL_BRAND_POSIX: return (_posix1e_acl_to_text(acl, len_p, flags)); From e0adffb3d55a5100e1996dbbdc371710319342ab Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Sep 2009 17:29:08 +0000 Subject: [PATCH 0190/2592] MFC r196866: In the NEXTADDR macro use SA_SIZE() rather than directly using sizeof(), as introduced in r186119, for advancing the current position into the buffer. See comment in net/route.h for a description of the difference. This makes ndp -s work again. Reviewed by: qingli Approved by: re (kib) --- usr.sbin/ndp/ndp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index 570961a3e9f..17e439ce584 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -116,7 +116,7 @@ #define NEXTADDR(w, s) \ if (rtm->rtm_addrs & (w)) { \ - bcopy((char *)&s, cp, sizeof(s)); cp += sizeof(s);} + bcopy((char *)&s, cp, sizeof(s)); cp += SA_SIZE(&s);} static pid_t pid; From 02642a5729be72108ea0b4255731c877e6b5d116 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Sat, 5 Sep 2009 17:35:31 +0000 Subject: [PATCH 0191/2592] MFC r196865 This patch fixes an address scope violation. Considering the scenario where an anycast address is assigned on one interface, and a global address with the same scope is assigned on another interface. In other words, the interface owns the anycast address has only the link-local address as one other address. Without this patch, "ping6" the anycast address from another station will observe the source address of the returned ICMP6 echo reply has the link-local address, not the global address that exists on the other interface in the same node. Reviewed by: bz Approved by: re --- sys/netinet6/icmp6.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 6f13c692d0c..04810c36273 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -2170,6 +2170,10 @@ icmp6_reflect(struct mbuf *m, size_t off) } } + if ((srcp != NULL) && + (in6_addrscope(srcp) != in6_addrscope(&ip6->ip6_src))) + srcp = NULL; + if (srcp == NULL) { int e; struct sockaddr_in6 sin6; From 3d2a8d364d9f966b48815cca11b4629fe80c4ee2 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Sat, 5 Sep 2009 17:40:27 +0000 Subject: [PATCH 0192/2592] MFC r196864 This patch fixes the following issues: - Interface link-local address is not reachable within the node that owns the interface, this is due to the mismatch in address scope as the result of the installed interface address loopback route. Therefore for each interface address loopback route, the rt_gateway field (of AF_LINK type) will be used to track which interface a given address belongs to. This will aid the address source to use the proper interface for address scope/zone validation. - The loopback address is not reachable. The root cause is the same as the above. - Empty nd6 entries are created for the IPv6 loopback addresses only for validation reason. Doing so will eliminate as much of the special case (loopback addresses) handling code as possible, however, these empty nd6 entries should not be returned to the userland applications such as the "ndp" command. Since both of the above issues contain common files, these files are committed together. Reviewed by: bz Approved by: re --- sys/net/if_llatbl.c | 9 +++++++++ sys/netinet6/in6.c | 11 +++++++---- sys/netinet6/in6_src.c | 30 +++++++++++++++++++----------- sys/netinet6/ip6_output.c | 15 +++++++++------ 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index b66d6e154b2..fb94f735062 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -263,6 +263,15 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info) __func__, dl->sdl_index); return EINVAL; } + if (ifp->if_flags & IFF_LOOPBACK) { + struct ifaddr *ia; + ia = ifa_ifwithaddr(dst); + if (ia != NULL) { + ifp = ia->ifa_ifp; + ifa_free(ia); + } else + return EINVAL; + } switch (rtm->rtm_type) { case RTM_ADD: diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index b0b25854027..9521e8e7a5e 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1201,8 +1201,8 @@ in6_purgeaddr(struct ifaddr *ifa) bzero(&null_sdl, sizeof(null_sdl)); null_sdl.sdl_len = sizeof(null_sdl); null_sdl.sdl_family = AF_LINK; - null_sdl.sdl_type = V_loif->if_type; - null_sdl.sdl_index = V_loif->if_index; + null_sdl.sdl_type = ia->ia_ifp->if_type; + null_sdl.sdl_index = ia->ia_ifp->if_index; bzero(&info, sizeof(info)); info.rti_flags = ia->ia_flags | RTF_HOST | RTF_STATIC; info.rti_info[RTAX_DST] = (struct sockaddr *)&ia->ia_addr; @@ -1782,9 +1782,9 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, if (error == 0 && rt != NULL) { RT_LOCK(rt); ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type = - rt->rt_ifp->if_type; + ifp->if_type; ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index = - rt->rt_ifp->if_index; + ifp->if_index; RT_REMREF(rt); RT_UNLOCK(rt); } else if (error != 0) @@ -2495,6 +2495,9 @@ in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr) } ndpc; int i, error; + if (ifp->if_flags & IFF_LOOPBACK) + return 0; + LLTABLE_LOCK_ASSERT(); error = 0; diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index f087faef539..8e82ef117ae 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -85,6 +85,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #ifdef RADIX_MPATH @@ -697,8 +698,25 @@ selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, if (error == EHOSTUNREACH) V_ip6stat.ip6s_noroute++; - if (retifp != NULL) + if (retifp != NULL) { *retifp = ifp; + + /* + * Adjust the "outgoing" interface. If we're going to loop + * the packet back to ourselves, the ifp would be the loopback + * interface. However, we'd rather know the interface associated + * to the destination address (which should probably be one of + * our own addresses.) + */ + if (rt) { + if ((rt->rt_ifp->if_flags & IFF_LOOPBACK) && + (rt->rt_gateway->sa_family == AF_LINK)) + *retifp = + ifnet_byindex(((struct sockaddr_dl *) + rt->rt_gateway)->sdl_index); + } + } + if (retrt != NULL) *retrt = rt; /* rt may be NULL */ @@ -750,16 +768,6 @@ in6_selectif(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, return (flags); } - /* - * Adjust the "outgoing" interface. If we're going to loop the packet - * back to ourselves, the ifp would be the loopback interface. - * However, we'd rather know the interface associated to the - * destination address (which should probably be one of our own - * addresses.) - */ - if (rt && rt->rt_ifa && rt->rt_ifa->ifa_ifp) - *retifp = rt->rt_ifa->ifa_ifp; - if (ro == &sro && rt && rt == sro.ro_rt) RTFREE(rt); return (0); diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index c48ac7b1594..98875640e7a 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -602,15 +602,12 @@ again: rt->rt_use++; } + /* * The outgoing interface must be in the zone of source and - * destination addresses. We should use ia_ifp to support the - * case of sending packets to an address of our own. + * destination addresses. */ - if (ia != NULL && ia->ia_ifp) - origifp = ia->ia_ifp; - else - origifp = ifp; + origifp = ifp; src0 = ip6->ip6_src; if (in6_setscope(&src0, origifp, &zone)) @@ -634,6 +631,12 @@ again: goto badscope; } + /* We should use ia_ifp to support the case of + * sending packets to an address of our own. + */ + if (ia != NULL && ia->ia_ifp) + ifp = ia->ia_ifp; + /* scope check is done. */ goto routefound; From 69406c163245c81c31f74ddc9442b122aff522cd Mon Sep 17 00:00:00 2001 From: Qing Li Date: Sat, 5 Sep 2009 20:35:18 +0000 Subject: [PATCH 0193/2592] MFC r196871 The addresses that are assigned to the loopback interface should be part of the kernel routing table. Reviewed by: bz Approved by: re --- sys/net/if_llatbl.c | 9 --------- sys/netinet6/in6.c | 11 +++++++---- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index fb94f735062..b66d6e154b2 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -263,15 +263,6 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info) __func__, dl->sdl_index); return EINVAL; } - if (ifp->if_flags & IFF_LOOPBACK) { - struct ifaddr *ia; - ia = ifa_ifwithaddr(dst); - if (ia != NULL) { - ifp = ia->ifa_ifp; - ifa_free(ia); - } else - return EINVAL; - } switch (rtm->rtm_type) { case RTM_ADD: diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 9521e8e7a5e..c832305b162 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1192,9 +1192,10 @@ in6_purgeaddr(struct ifaddr *ifa) /* * Remove the loopback route to the interface address. - * The check for the current setting of "nd6_useloopback" is not needed. + * The check for the current setting of "nd6_useloopback" + * is not needed. */ - if (!(ia->ia_ifp->if_flags & IFF_LOOPBACK)) { + { struct rt_addrinfo info; struct sockaddr_dl null_sdl; @@ -1767,7 +1768,9 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, /* * add a loopback route to self */ - if (V_nd6_useloopback && !(ifp->if_flags & IFF_LOOPBACK)) { + if (!(ia->ia_flags & IFA_ROUTE) + && (V_nd6_useloopback + || (ifp->if_flags & IFF_LOOPBACK))) { struct rt_addrinfo info; struct rtentry *rt = NULL; static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; @@ -1788,7 +1791,7 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, RT_REMREF(rt); RT_UNLOCK(rt); } else if (error != 0) - log(LOG_INFO, "in6_ifinit: insertion failed\n"); + log(LOG_INFO, "in6_ifinit: error = %d, insertion failed\n", error); } /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */ From 9e432c37e04a5d16aad32f87dd8ccd2d77ed5218 Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Sun, 6 Sep 2009 06:05:23 +0000 Subject: [PATCH 0194/2592] MFC of r196477 Don't delete copies of nthread_create(9) we find inthe filesystem. we now link it to kproc_create(9), it's new name. Approved by: re (kib) --- ObsoleteFiles.inc | 2 -- 1 file changed, 2 deletions(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 9bed51f280b..e963f655351 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -803,8 +803,6 @@ OLD_FILES+=rescue/bsdlabel OLD_FILES+=rescue/fdisk OLD_FILES+=rescue/gpt .endif -# 20071026: kthread(9)/kproc(9) API changes -OLD_FILES+=usr/share/man/man9/kthread_create.9.gz # 20071025: rc.d/nfslocking superceeded by rc.d/lockd and rc.d/statd OLD_FILES+=etc/rc.d/nfslocking # 20070930: rename of cached to nscd From 529d72892428e09a85dff7a40937c66cfaa60a4c Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 6 Sep 2009 14:05:01 +0000 Subject: [PATCH 0195/2592] MFC r196831: Add to `camcontrol cmd` support for sending arbitrary ATA commands. It could be used for broad range of tasks, such as configuring drive power management, caching, security and any other features and tasks, not supported by existing drivers. Approved by: re (ATA-CAM blanket) --- sbin/camcontrol/camcontrol.8 | 23 ++++- sbin/camcontrol/camcontrol.c | 170 +++++++++++++++++++++++++---------- 2 files changed, 141 insertions(+), 52 deletions(-) diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8 index 0c994e6d538..b987cad2e07 100644 --- a/sbin/camcontrol/camcontrol.8 +++ b/sbin/camcontrol/camcontrol.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 29, 2009 +.Dd September 4, 2009 .Dt CAMCONTROL 8 .Os .Sh NAME @@ -120,10 +120,12 @@ .Ic cmd .Op device id .Op generic args +.Aq Fl a Ar cmd Op args .Aq Fl c Ar cmd Op args .Op Fl i Ar len Ar fmt .Bk -words .Op Fl o Ar len Ar fmt Op args +.Op Fl r Ar fmt .Ek .Nm .Ic debug @@ -486,12 +488,14 @@ Saved values .El .El .It Ic cmd -Allows the user to send an arbitrary SCSI CDB to any device. +Allows the user to send an arbitrary ATA or SCSI CDB to any device. The .Ic cmd function requires the .Fl c -argument to specify the CDB. +argument to specify SCSI CDB or the +.Fl a +argument to specify ATA Command Block registers values. Other arguments are optional, depending on the command type. The command and data specification syntax is documented @@ -503,9 +507,13 @@ SCSI device in question, you MUST specify either or .Fl o . .Bl -tag -width 17n +.It Fl a Ar cmd Op args +This specifies the content of 12 ATA Command Block registers (command, +features, lba_low, lba_mid, lba_high, device, lba_low_exp, lba_mid_exp. +lba_high_exp, features_exp, sector_count, sector_count_exp). .It Fl c Ar cmd Op args This specifies the SCSI CDB. -CDBs may be 6, 10, 12 or 16 bytes. +SCSI CDBs may be 6, 10, 12 or 16 bytes. .It Fl i Ar len Ar fmt This specifies the amount of data to read, and how it should be displayed. If the format is @@ -519,6 +527,13 @@ If the format is .Sq - , .Ar len bytes of data will be read from standard input and written to the device. +.It Fl r Ar fmt +This specifies that 11 result ATA Command Block registers should be displayed +(status, error, lba_low, lba_mid, lba_high, device, lba_low_exp, lba_mid_exp, +lba_high_exp, sector_count, sector_count_exp), and how. +If the format is +.Sq - , +11 result registers will be written to standard output in hex. .El .It Ic debug Turn on CAM debugging printfs in the kernel. diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index d3450e0648a..1bba49cfbcd 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -120,7 +120,7 @@ struct camcontrol_opts { }; #ifndef MINIMALISTIC -static const char scsicmd_opts[] = "c:i:o:"; +static const char scsicmd_opts[] = "a:c:i:o:r"; static const char readdefect_opts[] = "f:GP"; static const char negotiate_opts[] = "acD:O:qR:T:UW:"; #endif @@ -2078,12 +2078,15 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, u_int32_t flags = CAM_DIR_NONE; u_int8_t *data_ptr = NULL; u_int8_t cdb[20]; + u_int8_t atacmd[12]; struct get_hook hook; int c, data_bytes = 0; int cdb_len = 0; - char *datastr = NULL, *tstr; + int atacmd_len = 0; + int need_res = 0; + char *datastr = NULL, *tstr, *resstr = NULL; int error = 0; - int fd_data = 0; + int fd_data = 0, fd_res = 0; int retval; ccb = cam_getccb(device); @@ -2094,10 +2097,32 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, } bzero(&(&ccb->ccb_h)[1], - sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); + sizeof(union ccb) - sizeof(struct ccb_hdr)); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { + case 'a': + tstr = optarg; + while (isspace(*tstr) && (*tstr != '\0')) + tstr++; + hook.argc = argc - optind; + hook.argv = argv + optind; + hook.got = 0; + atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr, + iget, &hook); + /* + * Increment optind by the number of arguments the + * encoding routine processed. After each call to + * getopt(3), optind points to the argument that + * getopt should process _next_. In this case, + * that means it points to the first command string + * argument, if there is one. Once we increment + * this, it should point to either the next command + * line argument, or it should be past the end of + * the list. + */ + optind += hook.got; + break; case 'c': tstr = optarg; while (isspace(*tstr) && (*tstr != '\0')) @@ -2194,6 +2219,16 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, iget, &hook); optind += hook.got; break; + case 'r': + need_res = 1; + hook.argc = argc - optind; + hook.argv = argv + optind; + hook.got = 0; + resstr = cget(&hook, NULL); + if ((resstr != NULL) && (resstr[0] == '-')) + fd_res = 1; + optind += hook.got; + break; default: break; } @@ -2226,50 +2261,51 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, /* Disable freezing the device queue */ flags |= CAM_DEV_QFRZDIS; - /* - * This is taken from the SCSI-3 draft spec. - * (T10/1157D revision 0.3) - * The top 3 bits of an opcode are the group code. The next 5 bits - * are the command code. - * Group 0: six byte commands - * Group 1: ten byte commands - * Group 2: ten byte commands - * Group 3: reserved - * Group 4: sixteen byte commands - * Group 5: twelve byte commands - * Group 6: vendor specific - * Group 7: vendor specific - */ - switch((cdb[0] >> 5) & 0x7) { - case 0: - cdb_len = 6; - break; - case 1: - case 2: - cdb_len = 10; - break; - case 3: - case 6: - case 7: - /* computed by buff_encode_visit */ - break; - case 4: - cdb_len = 16; - break; - case 5: - cdb_len = 12; - break; - } + if (cdb_len) { + /* + * This is taken from the SCSI-3 draft spec. + * (T10/1157D revision 0.3) + * The top 3 bits of an opcode are the group code. + * The next 5 bits are the command code. + * Group 0: six byte commands + * Group 1: ten byte commands + * Group 2: ten byte commands + * Group 3: reserved + * Group 4: sixteen byte commands + * Group 5: twelve byte commands + * Group 6: vendor specific + * Group 7: vendor specific + */ + switch((cdb[0] >> 5) & 0x7) { + case 0: + cdb_len = 6; + break; + case 1: + case 2: + cdb_len = 10; + break; + case 3: + case 6: + case 7: + /* computed by buff_encode_visit */ + break; + case 4: + cdb_len = 16; + break; + case 5: + cdb_len = 12; + break; + } - /* - * We should probably use csio_build_visit or something like that - * here, but it's easier to encode arguments as you go. The - * alternative would be skipping the CDB argument and then encoding - * it here, since we've got the data buffer argument by now. - */ - bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len); + /* + * We should probably use csio_build_visit or something like that + * here, but it's easier to encode arguments as you go. The + * alternative would be skipping the CDB argument and then encoding + * it here, since we've got the data buffer argument by now. + */ + bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len); - cam_fill_csio(&ccb->csio, + cam_fill_csio(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*flags*/ flags, @@ -2279,6 +2315,21 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, /*sense_len*/ SSD_FULL_SIZE, /*cdb_len*/ cdb_len, /*timeout*/ timeout ? timeout : 5000); + } else { + atacmd_len = 12; + bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len); + if (need_res) + ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; + + cam_fill_ataio(&ccb->ataio, + /*retries*/ retry_count, + /*cbfcnp*/ NULL, + /*flags*/ flags, + /*tag_action*/ 0, + /*data_ptr*/ data_ptr, + /*dxfer_len*/ data_bytes, + /*timeout*/ timeout ? timeout : 5000); + } if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { @@ -2296,6 +2347,28 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, goto scsicmd_bailout; } + if (atacmd_len && need_res) { + if (fd_res == 0) { + buff_decode_visit(&ccb->ataio.res.status, 11, resstr, + arg_put, NULL); + fprintf(stdout, "\n"); + } else { + fprintf(stdout, + "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + ccb->ataio.res.status, + ccb->ataio.res.error, + ccb->ataio.res.lba_low, + ccb->ataio.res.lba_mid, + ccb->ataio.res.lba_high, + ccb->ataio.res.device, + ccb->ataio.res.lba_low_exp, + ccb->ataio.res.lba_mid_exp, + ccb->ataio.res.lba_high_exp, + ccb->ataio.res.sector_count, + ccb->ataio.res.sector_count_exp); + fflush(stdout); + } + } if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) && (arglist & CAM_ARG_CMD_IN) @@ -4029,8 +4102,9 @@ usage(int verbose) " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n" " camcontrol modepage [dev_id][generic args] <-m page | -l>\n" " [-P pagectl][-e | -b][-d]\n" -" camcontrol cmd [dev_id][generic args] <-c cmd [args]>\n" -" [-i len fmt|-o len fmt [args]]\n" +" camcontrol cmd [dev_id][generic args]\n" +" <-a cmd [args] | -c cmd [args]>\n" +" [-i len fmt|-o len fmt [args]] [-r fmt]\n" " camcontrol debug [-I][-P][-T][-S][-X][-c]\n" " \n" " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n" From 07c141a646dc3d416d70e8feb751e2a4089b9e4f Mon Sep 17 00:00:00 2001 From: Remko Lodder Date: Mon, 7 Sep 2009 14:10:55 +0000 Subject: [PATCH 0196/2592] MFC r196787 Do the first step in removing lukemftpd from the base system. Disconnect it from the build. If you are using the FTP daemon, please consider using the port ftp/tnftpd which is the same FTP server, but newer and might have more/better functionality. This results in us providing only one ftp daemon by default. Reviewed by: bz Approved by: imp (mentor, implicit) MFC after: 3 days Silence from: obrien Approved by: re (kib), imp (mentor, implicit) --- ObsoleteFiles.inc | 5 +++++ etc/inetd.conf | 2 -- libexec/Makefile | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index e963f655351..090e4bb56b1 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -14,6 +14,11 @@ # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last. # +# 20090904: remove lukemftpd +OLD_FILES+=usr/libexec/lukemftpd +OLD_FILES+=usr/share/man/man5/ftpd.conf.5.gz +OLD_FILES+=usr/share/man/man5/ftpusers.5.gz +OLD_FILES+=usr/share/man/man8/lukemftpd.8.gz # 20090801: vimage.h removed in favour of vnet.h OLD_FILES+=usr/include/sys/vimage.h # 20090719: library version bump for 8.0 diff --git a/etc/inetd.conf b/etc/inetd.conf index 6f2e234b257..bbc21dfca60 100644 --- a/etc/inetd.conf +++ b/etc/inetd.conf @@ -8,8 +8,6 @@ # #ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l #ftp stream tcp6 nowait root /usr/libexec/ftpd ftpd -l -#ftp stream tcp nowait root /usr/libexec/lukemftpd ftpd -l -r -#ftp stream tcp6 nowait root /usr/libexec/lukemftpd ftpd -l -r #ssh stream tcp nowait root /usr/sbin/sshd sshd -i -4 #ssh stream tcp6 nowait root /usr/sbin/sshd sshd -i -6 #telnet stream tcp nowait root /usr/libexec/telnetd telnetd diff --git a/libexec/Makefile b/libexec/Makefile index 72ec91315af..26a8ff236a2 100644 --- a/libexec/Makefile +++ b/libexec/Makefile @@ -9,7 +9,6 @@ SUBDIR= ${_atrun} \ fingerd \ ftpd \ getty \ - lukemftpd \ ${_mail.local} \ ${_mknetid} \ ${_pppoed} \ From 264a8db4b09e341c3e2a4d524b61758ab70e6c7c Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 7 Sep 2009 16:25:09 +0000 Subject: [PATCH 0197/2592] MFC r196579: Fix an obvious topology lock leak. Approved by: re (kib) --- sys/geom/multipath/g_multipath.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/geom/multipath/g_multipath.c b/sys/geom/multipath/g_multipath.c index ca442bdc6a4..ed7e71e09a2 100644 --- a/sys/geom/multipath/g_multipath.c +++ b/sys/geom/multipath/g_multipath.c @@ -198,6 +198,7 @@ g_multipath_done_error(struct bio *bp) if (sc->cp_active == NULL) { printf("GEOM_MULTIPATH: out of providers for %s\n", sc->sc_name); + g_topology_unlock(); return; } else { printf("GEOM_MULTIPATH: %s now active path in %s\n", From f8083274f09d4b37e42fe959dcd0d334c9deb6f3 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 7 Sep 2009 16:33:27 +0000 Subject: [PATCH 0198/2592] MFC r196785: correct timeout for doing NOL processing; need a ticks-relative value Approved by: re (kensmith) --- sys/net80211/ieee80211_dfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_dfs.c b/sys/net80211/ieee80211_dfs.c index eec819bb8d3..e15445d6a5f 100644 --- a/sys/net80211/ieee80211_dfs.c +++ b/sys/net80211/ieee80211_dfs.c @@ -235,7 +235,7 @@ dfs_timeout(void *arg) } if (oldest != now) { /* arrange to process next channel up for a status change */ - callout_schedule(&dfs->nol_timer, oldest + NOL_TIMEOUT); + callout_schedule(&dfs->nol_timer, oldest + NOL_TIMEOUT - now); } } From d53c6c91b15033c65faf75cecabfd5c853a13614 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 7 Sep 2009 16:41:18 +0000 Subject: [PATCH 0199/2592] MFC r196717: fix beacon timers on resume in sta mode so raoming works Approved by: re (kensmith) --- sys/dev/ath/if_ath.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index a789f5ea298..5628addc33a 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -1236,7 +1236,16 @@ ath_resume(struct ath_softc *sc) if (sc->sc_resume_up) { if (ic->ic_opmode == IEEE80211_M_STA) { ath_init(sc); - ieee80211_beacon_miss(ic); + /* + * Program the beacon registers using the last rx'd + * beacon frame and enable sync on the next beacon + * we see. This should handle the case where we + * wakeup and find the same AP and also the case where + * we wakeup and need to roam. For the latter we + * should get bmiss events that trigger a roam. + */ + ath_beacon_config(sc, NULL); + sc->sc_syncbeacon = 1; } else ieee80211_resume_all(ic); } From c02280f542426eaeaa33d9ed8ba8e23967d04e8a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 8 Sep 2009 14:43:42 +0000 Subject: [PATCH 0200/2592] MFC r196692: Make the mnt_writeopcount and mnt_secondary_writes counters, used by the suspension code, not greater then mnt_ref reference counter value. MFC r196733: Fix mount reference leak when V_XSLEEP is specified to vn_start_write(). Approved by: re (kensmith) --- sys/kern/vfs_vnops.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index f67064613e0..1b77352b1c6 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -999,7 +999,8 @@ vn_start_write(vp, mpp, flags) goto unlock; mp->mnt_writeopcount++; unlock: - MNT_REL(mp); + if (error != 0 || (flags & V_XSLEEP) != 0) + MNT_REL(mp); MNT_IUNLOCK(mp); return (error); } @@ -1049,7 +1050,6 @@ vn_start_secondary_write(vp, mpp, flags) if ((mp->mnt_kern_flag & (MNTK_SUSPENDED | MNTK_SUSPEND2)) == 0) { mp->mnt_secondary_writes++; mp->mnt_secondary_accwrites++; - MNT_REL(mp); MNT_IUNLOCK(mp); return (0); } @@ -1081,6 +1081,7 @@ vn_finished_write(mp) if (mp == NULL) return; MNT_ILOCK(mp); + MNT_REL(mp); mp->mnt_writeopcount--; if (mp->mnt_writeopcount < 0) panic("vn_finished_write: neg cnt"); @@ -1103,6 +1104,7 @@ vn_finished_secondary_write(mp) if (mp == NULL) return; MNT_ILOCK(mp); + MNT_REL(mp); mp->mnt_secondary_writes--; if (mp->mnt_secondary_writes < 0) panic("vn_finished_secondary_write: neg cnt"); From 2af00decb8b198abbcb8c3baf4adfab31e86e05e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 8 Sep 2009 15:31:23 +0000 Subject: [PATCH 0201/2592] MFC r196730: Remove the altkstacks, instead instantiate threads with kernel stack allocated with the right size from the start. For the thread that has kernel stack cached, verify that requested stack size is equial to the actual, and reallocate the stack if sizes differ. Introduce separate kernel stack cache that keeps some limited amount of preallocated kernel stacks to lower the latency of thread allocation. Not a merge: instead of removing td_altkstack* members of struct thread, replace them with placeholders to keep struct thread layout on the stable branch. Also, record r196640, r196644 and r196648 as merged. Approved by: re (kensmith) --- sys/arm/arm/vm_machdep.c | 3 - sys/kern/kern_fork.c | 25 ++++--- sys/kern/kern_kthread.c | 5 +- sys/kern/kern_proc.c | 10 --- sys/kern/kern_thr.c | 2 +- sys/kern/kern_thread.c | 17 +++-- sys/sys/proc.h | 9 +-- sys/vm/vm_extern.h | 2 - sys/vm/vm_glue.c | 140 +++++++++++++++++++++++++++------------ 9 files changed, 131 insertions(+), 82 deletions(-) diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index 1a907cc7577..6bd57999d3a 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -119,9 +119,6 @@ cpu_fork(register struct thread *td1, register struct proc *p2, #ifdef __XSCALE__ #ifndef CPU_XSCALE_CORE3 pmap_use_minicache(td2->td_kstack, td2->td_kstack_pages * PAGE_SIZE); - if (td2->td_altkstack) - pmap_use_minicache(td2->td_altkstack, td2->td_altkstack_pages * - PAGE_SIZE); #endif #endif td2->td_pcb = pcb2; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 4e2eaa98f3a..03d8cbc6bc1 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include "opt_kdtrace.h" #include "opt_ktrace.h" +#include "opt_kstack_pages.h" #include #include @@ -276,25 +277,29 @@ norfproc_fail: mem_charged = 0; vm2 = NULL; + if (pages == 0) + pages = KSTACK_PAGES; /* Allocate new proc. */ newproc = uma_zalloc(proc_zone, M_WAITOK); - if (TAILQ_EMPTY(&newproc->p_threads)) { - td2 = thread_alloc(); + td2 = FIRST_THREAD_IN_PROC(newproc); + if (td2 == NULL) { + td2 = thread_alloc(pages); if (td2 == NULL) { error = ENOMEM; goto fail1; } proc_linkup(newproc, td2); - } else - td2 = FIRST_THREAD_IN_PROC(newproc); - - /* Allocate and switch to an alternate kstack if specified. */ - if (pages != 0) { - if (!vm_thread_new_altkstack(td2, pages)) { - error = ENOMEM; - goto fail1; + } else { + if (td2->td_kstack == 0 || td2->td_kstack_pages != pages) { + if (td2->td_kstack != 0) + vm_thread_dispose(td2); + if (!thread_alloc_stack(td2, pages)) { + error = ENOMEM; + goto fail1; + } } } + if ((flags & RFMEM) == 0) { vm2 = vmspace_fork(p1->p_vmspace, &mem_charged); if (vm2 == NULL) { diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c index 10928321681..3c5248ebbb6 100644 --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -256,7 +256,7 @@ kthread_add(void (*func)(void *), void *arg, struct proc *p, } /* Initialize our new td */ - newtd = thread_alloc(); + newtd = thread_alloc(pages); if (newtd == NULL) return (ENOMEM); @@ -282,9 +282,6 @@ kthread_add(void (*func)(void *), void *arg, struct proc *p, newtd->td_pflags |= TDP_KTHREAD; newtd->td_ucred = crhold(p->p_ucred); - /* Allocate and switch to an alternate kstack if specified. */ - if (pages != 0) - vm_thread_new_altkstack(newtd, pages); /* this code almost the same as create_thread() in kern_thr.c */ PROC_LOCK(p); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index cdbc01207ea..e012a3ed4c0 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -203,14 +203,6 @@ proc_dtor(void *mem, int size, void *arg) #endif /* Free all OSD associated to this thread. */ osd_thread_exit(td); - - /* Dispose of an alternate kstack, if it exists. - * XXX What if there are more than one thread in the proc? - * The first thread in the proc is special and not - * freed, so you gotta do this here. - */ - if (((p->p_flag & P_KTHREAD) != 0) && (td->td_altkstack != 0)) - vm_thread_dispose_altkstack(td); } EVENTHANDLER_INVOKE(process_dtor, p); if (p->p_ksi != NULL) @@ -767,8 +759,6 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp) FOREACH_THREAD_IN_PROC(p, td0) { if (!TD_IS_SWAPPED(td0)) kp->ki_rssize += td0->td_kstack_pages; - if (td0->td_altkstack_obj != NULL) - kp->ki_rssize += td0->td_altkstack_pages; } kp->ki_swrss = vm->vm_swrss; kp->ki_tsize = vm->vm_tsize; diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index c478c63bd9b..630069b5940 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -176,7 +176,7 @@ create_thread(struct thread *td, mcontext_t *ctx, } /* Initialize our td */ - newtd = thread_alloc(); + newtd = thread_alloc(0); if (newtd == NULL) return (ENOMEM); diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index d47bd8cef8b..4f3b32cdd0a 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -283,7 +283,7 @@ thread_reap(void) * Allocate a thread. */ struct thread * -thread_alloc(void) +thread_alloc(int pages) { struct thread *td; @@ -291,7 +291,7 @@ thread_alloc(void) td = (struct thread *)uma_zalloc(thread_zone, M_WAITOK); KASSERT(td->td_kstack == 0, ("thread_alloc got thread with kstack")); - if (!vm_thread_new(td, 0)) { + if (!vm_thread_new(td, pages)) { uma_zfree(thread_zone, td); return (NULL); } @@ -299,6 +299,17 @@ thread_alloc(void) return (td); } +int +thread_alloc_stack(struct thread *td, int pages) +{ + + KASSERT(td->td_kstack == 0, + ("thread_alloc_stack called on a thread with kstack")); + if (!vm_thread_new(td, pages)) + return (0); + cpu_thread_alloc(td); + return (1); +} /* * Deallocate a thread. @@ -312,8 +323,6 @@ thread_free(struct thread *td) cpuset_rel(td->td_cpuset); td->td_cpuset = NULL; cpu_thread_free(td); - if (td->td_altkstack != 0) - vm_thread_dispose_altkstack(td); if (td->td_kstack != 0) vm_thread_dispose(td); uma_zfree(thread_zone, td); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index b65db627a90..adcadba3f48 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -267,9 +267,9 @@ struct thread { struct vm_object *td_kstack_obj;/* (a) Kstack object. */ vm_offset_t td_kstack; /* (a) Kernel VA of kstack. */ int td_kstack_pages; /* (a) Size of the kstack. */ - struct vm_object *td_altkstack_obj;/* (a) Alternate kstack object. */ - vm_offset_t td_altkstack; /* (a) Kernel VA of alternate kstack. */ - int td_altkstack_pages; /* (a) Size of alternate kstack. */ + void *td_space1; + vm_offset_t td_space2; + int td_space3; volatile u_int td_critnest; /* (k*) Critical section nest level. */ struct mdthread td_md; /* (k) Any machine-dependent fields. */ struct td_sched *td_sched; /* (*) Scheduler-specific data. */ @@ -850,7 +850,8 @@ void cpu_thread_exit(struct thread *); void cpu_thread_free(struct thread *); void cpu_thread_swapin(struct thread *); void cpu_thread_swapout(struct thread *); -struct thread *thread_alloc(void); +struct thread *thread_alloc(int pages); +int thread_alloc_stack(struct thread *, int pages); void thread_exit(void) __dead2; void thread_free(struct thread *td); void thread_link(struct thread *td, struct proc *p); diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 53f76947ee8..65b6c8e8e4a 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -80,9 +80,7 @@ int vm_fault_quick(caddr_t v, int prot); struct sf_buf *vm_imgact_map_page(vm_object_t object, vm_ooffset_t offset); void vm_imgact_unmap_page(struct sf_buf *sf); void vm_thread_dispose(struct thread *td); -void vm_thread_dispose_altkstack(struct thread *td); int vm_thread_new(struct thread *td, int pages); -int vm_thread_new_altkstack(struct thread *td, int pages); void vm_thread_swapin(struct thread *td); void vm_thread_swapout(struct thread *td); #endif /* _KERNEL */ diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index 9e43a3fe005..851c73361ee 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -308,6 +309,20 @@ vm_imgact_unmap_page(struct sf_buf *sf) vm_page_unlock_queues(); } +struct kstack_cache_entry { + vm_object_t ksobj; + struct kstack_cache_entry *next_ks_entry; +}; + +static struct kstack_cache_entry *kstack_cache; +static int kstack_cache_size = 128; +static int kstacks; +static struct mtx kstack_cache_mtx; +SYSCTL_INT(_vm, OID_AUTO, kstack_cache_size, CTLFLAG_RW, &kstack_cache_size, 0, + ""); +SYSCTL_INT(_vm, OID_AUTO, kstacks, CTLFLAG_RD, &kstacks, 0, + ""); + #ifndef KSTACK_MAX_PAGES #define KSTACK_MAX_PAGES 32 #endif @@ -323,6 +338,7 @@ vm_thread_new(struct thread *td, int pages) vm_object_t ksobj; vm_offset_t ks; vm_page_t m, ma[KSTACK_MAX_PAGES]; + struct kstack_cache_entry *ks_ce; int i; /* Bounds check */ @@ -330,6 +346,22 @@ vm_thread_new(struct thread *td, int pages) pages = KSTACK_PAGES; else if (pages > KSTACK_MAX_PAGES) pages = KSTACK_MAX_PAGES; + + if (pages == KSTACK_PAGES) { + mtx_lock(&kstack_cache_mtx); + if (kstack_cache != NULL) { + ks_ce = kstack_cache; + kstack_cache = ks_ce->next_ks_entry; + mtx_unlock(&kstack_cache_mtx); + + td->td_kstack_obj = ks_ce->ksobj; + td->td_kstack = (vm_offset_t)ks_ce; + td->td_kstack_pages = KSTACK_PAGES; + return (1); + } + mtx_unlock(&kstack_cache_mtx); + } + /* * Allocate an object for the kstack. */ @@ -345,7 +377,8 @@ vm_thread_new(struct thread *td, int pages) vm_object_deallocate(ksobj); return (0); } - + + atomic_add_int(&kstacks, 1); if (KSTACK_GUARD_PAGES != 0) { pmap_qremove(ks, KSTACK_GUARD_PAGES); ks += KSTACK_GUARD_PAGES * PAGE_SIZE; @@ -376,20 +409,13 @@ vm_thread_new(struct thread *td, int pages) return (1); } -/* - * Dispose of a thread's kernel stack. - */ -void -vm_thread_dispose(struct thread *td) +static void +vm_thread_stack_dispose(vm_object_t ksobj, vm_offset_t ks, int pages) { - vm_object_t ksobj; - vm_offset_t ks; vm_page_t m; - int i, pages; + int i; - pages = td->td_kstack_pages; - ksobj = td->td_kstack_obj; - ks = td->td_kstack; + atomic_add_int(&kstacks, -1); pmap_qremove(ks, pages); VM_OBJECT_LOCK(ksobj); for (i = 0; i < pages; i++) { @@ -405,9 +431,66 @@ vm_thread_dispose(struct thread *td) vm_object_deallocate(ksobj); kmem_free(kernel_map, ks - (KSTACK_GUARD_PAGES * PAGE_SIZE), (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); - td->td_kstack = 0; } +/* + * Dispose of a thread's kernel stack. + */ +void +vm_thread_dispose(struct thread *td) +{ + vm_object_t ksobj; + vm_offset_t ks; + struct kstack_cache_entry *ks_ce; + int pages; + + pages = td->td_kstack_pages; + ksobj = td->td_kstack_obj; + ks = td->td_kstack; + td->td_kstack = 0; + td->td_kstack_pages = 0; + if (pages == KSTACK_PAGES && kstacks <= kstack_cache_size) { + ks_ce = (struct kstack_cache_entry *)ks; + ks_ce->ksobj = ksobj; + mtx_lock(&kstack_cache_mtx); + ks_ce->next_ks_entry = kstack_cache; + kstack_cache = ks_ce; + mtx_unlock(&kstack_cache_mtx); + return; + } + vm_thread_stack_dispose(ksobj, ks, pages); +} + +static void +vm_thread_stack_lowmem(void *nulll) +{ + struct kstack_cache_entry *ks_ce, *ks_ce1; + + mtx_lock(&kstack_cache_mtx); + ks_ce = kstack_cache; + kstack_cache = NULL; + mtx_unlock(&kstack_cache_mtx); + + while (ks_ce != NULL) { + ks_ce1 = ks_ce; + ks_ce = ks_ce->next_ks_entry; + + vm_thread_stack_dispose(ks_ce1->ksobj, (vm_offset_t)ks_ce1, + KSTACK_PAGES); + } +} + +static void +kstack_cache_init(void *nulll) +{ + + EVENTHANDLER_REGISTER(vm_lowmem, vm_thread_stack_lowmem, NULL, + EVENTHANDLER_PRI_ANY); +} + +MTX_SYSINIT(kstack_cache, &kstack_cache_mtx, "kstkch", MTX_DEF); +SYSINIT(vm_kstacks, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, kstack_cache_init, NULL); + /* * Allow a thread's kernel stack to be paged out. */ @@ -467,37 +550,6 @@ vm_thread_swapin(struct thread *td) cpu_thread_swapin(td); } -/* - * Set up a variable-sized alternate kstack. - */ -int -vm_thread_new_altkstack(struct thread *td, int pages) -{ - - td->td_altkstack = td->td_kstack; - td->td_altkstack_obj = td->td_kstack_obj; - td->td_altkstack_pages = td->td_kstack_pages; - - return (vm_thread_new(td, pages)); -} - -/* - * Restore the original kstack. - */ -void -vm_thread_dispose_altkstack(struct thread *td) -{ - - vm_thread_dispose(td); - - td->td_kstack = td->td_altkstack; - td->td_kstack_obj = td->td_altkstack_obj; - td->td_kstack_pages = td->td_altkstack_pages; - td->td_altkstack = 0; - td->td_altkstack_obj = NULL; - td->td_altkstack_pages = 0; -} - /* * Implement fork's actions on an address space. * Here we arrange for the address space to be copied or referenced, From 3c7562c77ec78844315e4bd2938c010f39d4c1dd Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Tue, 8 Sep 2009 19:18:02 +0000 Subject: [PATCH 0202/2592] MFC r196835: Allow a jail's name to be the same as its jid (which is the default if no name is specified), and let a numeric name specify the jid for a new jail when the jid isn't otherwise set. Still disallow other numeric names. Reviewed by: zec Approved by: re (kib), bz (mentor) --- sys/kern/kern_jail.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 47201d2b8df..0cc330cd5ad 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -478,7 +478,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) struct vfsoptlist *opts; struct prison *pr, *deadpr, *mypr, *ppr, *tpr; struct vnode *root; - char *domain, *errmsg, *host, *name, *p, *path, *uuid; + char *domain, *errmsg, *host, *name, *namelc, *p, *path, *uuid; #if defined(INET) || defined(INET6) struct prison *tppr; void *op; @@ -907,6 +907,13 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) goto done_unlock_list; } pr = NULL; + namelc = NULL; + if (cuflags == JAIL_CREATE && jid == 0 && name != NULL) { + namelc = strrchr(name, '.'); + jid = strtoul(namelc != NULL ? namelc + 1 : name, &p, 10); + if (*p != '\0') + jid = 0; + } if (jid != 0) { /* * See if a requested jid already exists. There is an @@ -973,17 +980,19 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) * because that is the jail being updated). */ if (name != NULL) { - p = strrchr(name, '.'); - if (p != NULL) { + namelc = strrchr(name, '.'); + if (namelc == NULL) + namelc = name; + else { /* * This is a hierarchical name. Split it into the * parent and child names, and make sure the parent * exists or matches an already found jail. */ - *p = '\0'; + *namelc = '\0'; if (pr != NULL) { - if (strncmp(name, ppr->pr_name, p - name) || - ppr->pr_name[p - name] != '\0') { + if (strncmp(name, ppr->pr_name, namelc - name) + || ppr->pr_name[namelc - name] != '\0') { mtx_unlock(&pr->pr_mtx); error = EINVAL; vfs_opterror(opts, @@ -1000,7 +1009,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) } mtx_unlock(&ppr->pr_mtx); } - name = p + 1; + name = ++namelc; } if (name[0] != '\0') { namelen = @@ -1412,9 +1421,11 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) /* Give a default name of the jid. */ if (name[0] == '\0') snprintf(name = numbuf, sizeof(numbuf), "%d", jid); - else if (strtoul(name, &p, 10) != jid && *p == '\0') { + else if (*namelc == '0' || (strtoul(namelc, &p, 10) != jid && + *p == '\0')) { error = EINVAL; - vfs_opterror(opts, "name cannot be numeric"); + vfs_opterror(opts, + "name cannot be numeric (unless it is the jid)"); goto done_deref_locked; } /* From bae950f3b385e017a8ef9e44366d9170791cbf2a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 8 Sep 2009 21:50:34 +0000 Subject: [PATCH 0203/2592] MFC 196745: Don't attempt to bind the current thread to the CPU an IRQ is bound to when removing an interrupt handler from an IRQ during shutdown. During shutdown we are already bound to CPU 0 and this was triggering a panic. Approved by: re (kib) --- sys/amd64/amd64/local_apic.c | 21 ++++++++++++--------- sys/i386/i386/local_apic.c | 21 ++++++++++++--------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c index 13bd7743cb9..87bec91b6c4 100644 --- a/sys/amd64/amd64/local_apic.c +++ b/sys/amd64/amd64/local_apic.c @@ -990,18 +990,21 @@ apic_free_vector(u_int apic_id, u_int vector, u_int irq) * we don't lose an interrupt delivery race. */ td = curthread; - thread_lock(td); - if (sched_is_bound(td)) - panic("apic_free_vector: Thread already bound.\n"); - sched_bind(td, apic_cpuid(apic_id)); - thread_unlock(td); + if (!rebooting) { + thread_lock(td); + if (sched_is_bound(td)) + panic("apic_free_vector: Thread already bound.\n"); + sched_bind(td, apic_cpuid(apic_id)); + thread_unlock(td); + } mtx_lock_spin(&icu_lock); lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS] = -1; mtx_unlock_spin(&icu_lock); - thread_lock(td); - sched_unbind(td); - thread_unlock(td); - + if (!rebooting) { + thread_lock(td); + sched_unbind(td); + thread_unlock(td); + } } /* Map an IDT vector (APIC) to an IRQ (interrupt source). */ diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c index 5e79aa805c5..9b1d1b3173e 100644 --- a/sys/i386/i386/local_apic.c +++ b/sys/i386/i386/local_apic.c @@ -994,18 +994,21 @@ apic_free_vector(u_int apic_id, u_int vector, u_int irq) * we don't lose an interrupt delivery race. */ td = curthread; - thread_lock(td); - if (sched_is_bound(td)) - panic("apic_free_vector: Thread already bound.\n"); - sched_bind(td, apic_cpuid(apic_id)); - thread_unlock(td); + if (!rebooting) { + thread_lock(td); + if (sched_is_bound(td)) + panic("apic_free_vector: Thread already bound.\n"); + sched_bind(td, apic_cpuid(apic_id)); + thread_unlock(td); + } mtx_lock_spin(&icu_lock); lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS] = -1; mtx_unlock_spin(&icu_lock); - thread_lock(td); - sched_unbind(td); - thread_unlock(td); - + if (!rebooting) { + thread_lock(td); + sched_unbind(td); + thread_unlock(td); + } } /* Map an IDT vector (APIC) to an IRQ (interrupt source). */ From 6a89c3ede1df004863468a09fc885baa80e82937 Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Tue, 8 Sep 2009 23:25:39 +0000 Subject: [PATCH 0204/2592] Make LRO turned off uncategorically for devices attached to the bridge, rather than just in the case when some device cannot do TSO. Customer tests have shown that even when all devices can do TSO that LRO will cause problems when bridging. Approved by: re --- sys/net/if_bridge.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index f1a79cbf21a..d3a55fd15af 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -170,6 +170,11 @@ __FBSDID("$FreeBSD$"); */ #define BRIDGE_IFCAPS_MASK (IFCAP_TOE|IFCAP_TSO|IFCAP_TXCSUM) +/* + * List of capabilities to strip + */ +#define BRIDGE_IFCAPS_STRIP IFCAP_LRO + /* * Bridge interface list entry. */ @@ -802,16 +807,10 @@ bridge_mutecaps(struct bridge_softc *sc) LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { enabled = bif->bif_ifp->if_capenable; + enabled &= ~BRIDGE_IFCAPS_STRIP; /* strip off mask bits and enable them again if allowed */ enabled &= ~BRIDGE_IFCAPS_MASK; enabled |= mask; - /* - * Receive offload can only be enabled if all members also - * support send offload. - */ - if ((enabled & IFCAP_TSO) == 0) - enabled &= ~IFCAP_LRO; - bridge_set_ifcap(sc, bif, enabled); } From db0c92ce82f76f9aa389bc2b0e76deee6a5009ab Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Wed, 9 Sep 2009 09:17:31 +0000 Subject: [PATCH 0205/2592] MFC r196772: fix adaptive spinning in lockmgr by using correctly GIANT_RESTORE and continue statement and improve adaptive spinning for sx lock by just doing once GIANT_SAVE. Approved by: re (kib) --- sys/kern/kern_lock.c | 13 +++++++++++-- sys/kern/kern_sx.c | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 29ae4accfa7..e6f2f536249 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -467,7 +467,10 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, /* * If the owner is running on another CPU, spin until * the owner stops running or the state of the lock - * changes. + * changes. We need a double-state handle here + * because for a failed acquisition the lock can be + * either held in exclusive mode or shared mode + * (for the writer starvation avoidance technique). */ if (LK_CAN_ADAPT(lk, flags) && (x & LK_SHARE) == 0 && LK_HOLDER(x) != LK_KERNPROC) { @@ -491,8 +494,10 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, while (LK_HOLDER(lk->lk_lock) == (uintptr_t)owner && TD_IS_RUNNING(owner)) cpu_spinwait(); + GIANT_RESTORE(); + continue; } else if (LK_CAN_ADAPT(lk, flags) && - (x & LK_SHARE) !=0 && LK_SHARERS(x) && + (x & LK_SHARE) != 0 && LK_SHARERS(x) && spintries < alk_retries) { if (flags & LK_INTERLOCK) { class->lc_unlock(ilk); @@ -511,6 +516,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, break; cpu_spinwait(); } + GIANT_RESTORE(); if (i != alk_loops) continue; } @@ -704,6 +710,8 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, while (LK_HOLDER(lk->lk_lock) == (uintptr_t)owner && TD_IS_RUNNING(owner)) cpu_spinwait(); + GIANT_RESTORE(); + continue; } else if (LK_CAN_ADAPT(lk, flags) && (x & LK_SHARE) != 0 && LK_SHARERS(x) && spintries < alk_retries) { @@ -727,6 +735,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, break; cpu_spinwait(); } + GIANT_RESTORE(); if (i != alk_loops) continue; } diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index 4a78444c09c..c00b267e5d2 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -531,13 +531,13 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file, continue; } } else if (SX_SHARERS(x) && spintries < asx_retries) { + GIANT_SAVE(); spintries++; for (i = 0; i < asx_loops; i++) { if (LOCK_LOG_TEST(&sx->lock_object, 0)) CTR4(KTR_LOCK, "%s: shared spinning on %p with %u and %u", __func__, sx, spintries, i); - GIANT_SAVE(); x = sx->sx_lock; if ((x & SX_LOCK_SHARED) == 0 || SX_SHARERS(x) == 0) From c90c9ddddb66a3f1c7a282a972155e4527d631b3 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Wed, 9 Sep 2009 09:34:13 +0000 Subject: [PATCH 0206/2592] Adaptive spinning for locking primitives, in read-mode, have some tuning SYSCTLs which are inappropriate for a daily use of the machine (mostly useful only by a developer which wants to run benchmarks on it). Remove them before the release as long as we do not want to ship with them in. Now that the SYSCTLs are gone, instead than use static storage for some constants, use real numeric constants in order to avoid eventual compiler dumbiness and the risk to share a storage (and then a cache-line) among CPUs when doing adaptive spinning together. Pleasse note that the sys/linker_set.h inclusion in lockmgr and sx lock support could have been gone, but re@ preferred them to be in order to minimize the risk of problems on future merging. Please note that this patch is not a MFC, but an 'edge case' as commit directly to stable/8, which creates a diverging from HEAD. Tested by: Giovanni Trematerra Approved by: re (kib) --- sys/kern/kern_lock.c | 25 +++++++++++-------------- sys/kern/kern_rwlock.c | 21 +++++++++------------ sys/kern/kern_sx.c | 19 ++++++++----------- 3 files changed, 28 insertions(+), 37 deletions(-) diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index e6f2f536249..e4edccf5da7 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -62,6 +62,11 @@ CTASSERT(LK_UNLOCKED == (LK_UNLOCKED & #define SQ_EXCLUSIVE_QUEUE 0 #define SQ_SHARED_QUEUE 1 +#ifdef ADAPTIVE_LOCKMGRS +#define ALK_RETRIES 10 +#define ALK_LOOPS 10000 +#endif + #ifndef INVARIANTS #define _lockmgr_assert(lk, what, file, line) #define TD_LOCKS_INC(td) @@ -156,14 +161,6 @@ struct lock_class lock_class_lockmgr = { #endif }; -#ifdef ADAPTIVE_LOCKMGRS -static u_int alk_retries = 10; -static u_int alk_loops = 10000; -SYSCTL_NODE(_debug, OID_AUTO, lockmgr, CTLFLAG_RD, NULL, "lockmgr debugging"); -SYSCTL_UINT(_debug_lockmgr, OID_AUTO, retries, CTLFLAG_RW, &alk_retries, 0, ""); -SYSCTL_UINT(_debug_lockmgr, OID_AUTO, loops, CTLFLAG_RW, &alk_loops, 0, ""); -#endif - static __inline struct thread * lockmgr_xholder(struct lock *lk) { @@ -498,14 +495,14 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, continue; } else if (LK_CAN_ADAPT(lk, flags) && (x & LK_SHARE) != 0 && LK_SHARERS(x) && - spintries < alk_retries) { + spintries < ALK_RETRIES) { if (flags & LK_INTERLOCK) { class->lc_unlock(ilk); flags &= ~LK_INTERLOCK; } GIANT_SAVE(); spintries++; - for (i = 0; i < alk_loops; i++) { + for (i = 0; i < ALK_LOOPS; i++) { if (LOCK_LOG_TEST(&lk->lock_object, 0)) CTR4(KTR_LOCK, "%s: shared spinning on %p with %u and %u", @@ -517,7 +514,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, cpu_spinwait(); } GIANT_RESTORE(); - if (i != alk_loops) + if (i != ALK_LOOPS) continue; } #endif @@ -714,7 +711,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, continue; } else if (LK_CAN_ADAPT(lk, flags) && (x & LK_SHARE) != 0 && LK_SHARERS(x) && - spintries < alk_retries) { + spintries < ALK_RETRIES) { if ((x & LK_EXCLUSIVE_SPINNERS) == 0 && !atomic_cmpset_ptr(&lk->lk_lock, x, x | LK_EXCLUSIVE_SPINNERS)) @@ -725,7 +722,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, } GIANT_SAVE(); spintries++; - for (i = 0; i < alk_loops; i++) { + for (i = 0; i < ALK_LOOPS; i++) { if (LOCK_LOG_TEST(&lk->lock_object, 0)) CTR4(KTR_LOCK, "%s: shared spinning on %p with %u and %u", @@ -736,7 +733,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, cpu_spinwait(); } GIANT_RESTORE(); - if (i != alk_loops) + if (i != ALK_LOOPS) continue; } #endif diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c index be05b39de0a..601af4fefe4 100644 --- a/sys/kern/kern_rwlock.c +++ b/sys/kern/kern_rwlock.c @@ -56,11 +56,8 @@ __FBSDID("$FreeBSD$"); #endif #ifdef ADAPTIVE_RWLOCKS -static int rowner_retries = 10; -static int rowner_loops = 10000; -SYSCTL_NODE(_debug, OID_AUTO, rwlock, CTLFLAG_RD, NULL, "rwlock debugging"); -SYSCTL_INT(_debug_rwlock, OID_AUTO, retry, CTLFLAG_RW, &rowner_retries, 0, ""); -SYSCTL_INT(_debug_rwlock, OID_AUTO, loops, CTLFLAG_RW, &rowner_loops, 0, ""); +#define ROWNER_RETRIES 10 +#define ROWNER_LOOPS 10000 #endif #ifdef DDB @@ -380,15 +377,15 @@ _rw_rlock(struct rwlock *rw, const char *file, int line) } continue; } - } else if (spintries < rowner_retries) { + } else if (spintries < ROWNER_RETRIES) { spintries++; - for (i = 0; i < rowner_loops; i++) { + for (i = 0; i < ROWNER_LOOPS; i++) { v = rw->rw_lock; if ((v & RW_LOCK_READ) == 0 || RW_CAN_READ(v)) break; cpu_spinwait(); } - if (i != rowner_loops) + if (i != ROWNER_LOOPS) continue; } #endif @@ -690,7 +687,7 @@ _rw_wlock_hard(struct rwlock *rw, uintptr_t tid, const char *file, int line) continue; } if ((v & RW_LOCK_READ) && RW_READERS(v) && - spintries < rowner_retries) { + spintries < ROWNER_RETRIES) { if (!(v & RW_LOCK_WRITE_SPINNER)) { if (!atomic_cmpset_ptr(&rw->rw_lock, v, v | RW_LOCK_WRITE_SPINNER)) { @@ -698,15 +695,15 @@ _rw_wlock_hard(struct rwlock *rw, uintptr_t tid, const char *file, int line) } } spintries++; - for (i = 0; i < rowner_loops; i++) { + for (i = 0; i < ROWNER_LOOPS; i++) { if ((rw->rw_lock & RW_LOCK_WRITE_SPINNER) == 0) break; cpu_spinwait(); } #ifdef KDTRACE_HOOKS - spin_cnt += rowner_loops - i; + spin_cnt += ROWNER_LOOPS - i; #endif - if (i != rowner_loops) + if (i != ROWNER_LOOPS) continue; } #endif diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index c00b267e5d2..b7b12d5b2dc 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -72,6 +72,11 @@ CTASSERT((SX_NOADAPTIVE & LO_CLASSFLAGS) == SX_NOADAPTIVE); #define SQ_EXCLUSIVE_QUEUE 0 #define SQ_SHARED_QUEUE 1 +#ifdef ADAPTIVE_SX +#define ASX_RETRIES 10 +#define ASX_LOOPS 10000 +#endif + /* * Variations on DROP_GIANT()/PICKUP_GIANT() for use in this file. We * drop Giant anytime we have to sleep or if we adaptively spin. @@ -134,14 +139,6 @@ struct lock_class lock_class_sx = { #define _sx_assert(sx, what, file, line) #endif -#ifdef ADAPTIVE_SX -static u_int asx_retries = 10; -static u_int asx_loops = 10000; -SYSCTL_NODE(_debug, OID_AUTO, sx, CTLFLAG_RD, NULL, "sxlock debugging"); -SYSCTL_INT(_debug_sx, OID_AUTO, retries, CTLFLAG_RW, &asx_retries, 0, ""); -SYSCTL_INT(_debug_sx, OID_AUTO, loops, CTLFLAG_RW, &asx_loops, 0, ""); -#endif - void assert_sx(struct lock_object *lock, int what) { @@ -530,10 +527,10 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file, } continue; } - } else if (SX_SHARERS(x) && spintries < asx_retries) { + } else if (SX_SHARERS(x) && spintries < ASX_RETRIES) { GIANT_SAVE(); spintries++; - for (i = 0; i < asx_loops; i++) { + for (i = 0; i < ASX_LOOPS; i++) { if (LOCK_LOG_TEST(&sx->lock_object, 0)) CTR4(KTR_LOCK, "%s: shared spinning on %p with %u and %u", @@ -547,7 +544,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file, spin_cnt++; #endif } - if (i != asx_loops) + if (i != ASX_LOOPS) continue; } } From f68591e407c9affcd2293387422e0e3ea9ad2674 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 9 Sep 2009 10:31:09 +0000 Subject: [PATCH 0207/2592] Use traditional td_unusedX names for the padding members. Suggested by: julian Approved by: re (kensmith) --- sys/sys/proc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/sys/proc.h b/sys/sys/proc.h index adcadba3f48..71885fb521d 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -267,9 +267,9 @@ struct thread { struct vm_object *td_kstack_obj;/* (a) Kstack object. */ vm_offset_t td_kstack; /* (a) Kernel VA of kstack. */ int td_kstack_pages; /* (a) Size of the kstack. */ - void *td_space1; - vm_offset_t td_space2; - int td_space3; + void *td_unused1; + vm_offset_t td_unused2; + int td_unused3; volatile u_int td_critnest; /* (k*) Critical section nest level. */ struct mdthread td_md; /* (k) Any machine-dependent fields. */ struct td_sched *td_sched; /* (*) Scheduler-specific data. */ From 3470119d8cd8ff7644ef8cafc2b65e8d2e2ac1fc Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Wed, 9 Sep 2009 12:19:43 +0000 Subject: [PATCH 0208/2592] MFC of r196581 r196582 r197000 Import of tzdata 2009k, 2009l and 2009m - Changes in Mauritius and Bangladesh - No leapsecond at the end of December 2009 - Egypt will go to Wintertime on 21 August 2009 - Samoa will go in DST on 4 October 2009 till 28 March 2010 - Palestine will go back from DST on 4 September 2009 Approved by: re (kostik) --- share/zoneinfo/africa | 49 ++++++++++++++++++++++++++++++++++---- share/zoneinfo/asia | 49 +++++++++++++++++++++++++++++++++++--- share/zoneinfo/australasia | 36 ++++++++++++++++++++++++++-- share/zoneinfo/europe | 4 ++-- share/zoneinfo/leapseconds | 27 +++++++++++---------- 5 files changed, 141 insertions(+), 24 deletions(-) diff --git a/share/zoneinfo/africa b/share/zoneinfo/africa index 3f92eb4745c..ad89bb743c1 100644 --- a/share/zoneinfo/africa +++ b/share/zoneinfo/africa @@ -1,5 +1,5 @@ #
-# @(#)africa	8.21
+# @(#)africa	8.23
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -276,8 +276,27 @@ Rule	Egypt	2007	only	-	Sep	Thu>=1	23:00s	0	-
 # In 2009 (and for the next several years), Ramadan ends before the fourth
 # Thursday in September; Egypt is expected to revert to the last Thursday
 # in September.
+
+# From Steffen Thorsen (2009-08-11):
+# We have been able to confirm the August change with the Egyptian Cabinet 
+# Information and Decision Support Center:
+# 
+# http://www.timeanddate.com/news/time/egypt-dst-ends-2009.html
+# 
+# 
+# The Middle East News Agency
+# 
+# http://www.mena.org.eg/index.aspx
+# 
+# also reports "Egypt starts winter time on August 21"
+# today in article numbered "71, 11/08/2009 12:25 GMT." 
+# Only the title above is available without a subscription to their service,
+# and can be found by searching for "winter" in their search engine
+# (at least today).
+
 Rule	Egypt	2008	only	-	Aug	lastThu	23:00s	0	-
-Rule	Egypt	2009	max	-	Sep	lastThu	23:00s	0	-
+Rule	Egypt	2009	only	-	Aug	20	23:00s	0	-
+Rule	Egypt	2010	max	-	Sep	lastThu	23:00s	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
@@ -502,11 +521,33 @@ Zone Africa/Nouakchott	-1:03:48 -	LMT	1912
 # http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf
 # 
 
+# From Steffen Thorsen (2009-06-05):
+# According to several sources, Mauritius will not continue to observe
+# DST the coming summer...
+#
+# Some sources, in French:
+# 
+# http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-%C2%AB-L%E2%80%99heure-d%E2%80%99%C3%A9t%C3%A9-ne-sera-pas-appliqu%C3%A9e-cette-ann%C3%A9e-%C2%BB
+# 
+# 
+# http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints-
+# 
+#
+# Our wrap-up:
+# 
+# http://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html
+# 
+
+# From Arthur David Olson (2009-07-11):
+# The "mauritius-dst-will-not-repeat" wrapup includes this: 
+# "The trial ended on March 29, 2009, when the clocks moved back by one hour
+# at 2am (or 02:00) local time..."
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule Mauritius	1982	only	-	Oct	10	0:00	1:00	S
 Rule Mauritius	1983	only	-	Mar	21	0:00	0	-
-Rule Mauritius	2008	max	-	Oct	lastSun	2:00s	1:00	S
-Rule Mauritius	2009	max	-	Mar	lastSun	2:00s	0	-
+Rule Mauritius	2008	only	-	Oct	lastSun	2:00	1:00	S
+Rule Mauritius	2009	only	-	Mar	lastSun	2:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Indian/Mauritius	3:50:00 -	LMT	1907		# Port Louis
 			4:00 Mauritius	MU%sT	# Mauritius Time
diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia
index 2262397fa5c..7142b4552f3 100644
--- a/share/zoneinfo/asia
+++ b/share/zoneinfo/asia
@@ -1,5 +1,5 @@
 # 
-# @(#)asia	8.35
+# @(#)asia	8.40
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -172,6 +172,12 @@ 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.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Dhaka	6:01:40 -	LMT	1890
 			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
@@ -180,7 +186,8 @@ 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
+			6:00	1:00	BDST	2010
+			6:00	-	BDT
 
 # Bhutan
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1829,6 +1836,42 @@ Zone	Asia/Karachi	4:28:12 -	LMT	1907
 # http://www.worldtimezone.com/dst_news/dst_news_westbank01.html
 # 
 
+# From Steffen Thorsen (2009-08-31):
+# Palestine's Council of Ministers announced that they will revert back to
+# winter time on Friday, 2009-09-04.
+#
+# One news source:
+# 
+# http://www.safa.ps/ara/?action=showdetail&seid=4158
+# 
+# (Palestinian press agency, Arabic),
+# Google translate: "Decided that the Palestinian government in Ramallah
+# headed by Salam Fayyad, the start of work in time for the winter of
+# 2009, starting on Friday approved the fourth delay Sept. clock sixty
+# minutes per hour as of Friday morning."
+#
+# We are not sure if Gaza will do the same, last year they had a different
+# end date, we will keep this page updated:
+# 
+# http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html
+# 
+
+# From Alexander Krivenyshev (2009-09-02):
+# Seems that Gaza Strip will go back to Winter Time same date as West Bank.
+#
+# According to Palestinian Ministry Of Interior, West Bank and Gaza Strip plan
+# to change time back to Standard time on September 4, 2009.
+#
+# "Winter time unite the West Bank and Gaza"
+# (from Palestinian National Authority):
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
+# 
+
 # The rules for Egypt are stolen from the `africa' file.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
@@ -1847,7 +1890,7 @@ Rule Palestine	2006	only	-	Sep	22	0:00	0	-
 Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
 Rule Palestine	2008	only	-	Aug	lastFri	2:00	0	-
 Rule Palestine	2009	max	-	Mar	lastFri	0:00	1:00	S
-Rule Palestine	2009	max	-	Sep	lastMon	2:00	0	-
+Rule Palestine	2009	max	-	Sep	Fri>=1	2:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
diff --git a/share/zoneinfo/australasia b/share/zoneinfo/australasia
index efcfec74d15..86fac13d98e 100644
--- a/share/zoneinfo/australasia
+++ b/share/zoneinfo/australasia
@@ -1,5 +1,5 @@
 # 
-# @(#)australasia	8.11
+# @(#)australasia	8.13
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -427,10 +427,42 @@ Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
 			-11:00	-	SST			# S=Samoa
 
 # Samoa
+
+# From Alexander Krivenyshev (2008-12-06):
+# The Samoa government (Western Samoa) may implement DST on the first Sunday of 
+# October 2009 (October 4, 2009) until the last Sunday of March 2010 (March 28, 
+# 2010). 
+# 
+# "Selected Committee reports to Cabinet on Daylight Saving Time",
+# Government of Samoa:
+# 
+# http://www.govt.ws/pr_article.cfm?pr_id=560
+# 
+# or
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_samoa01.html
+# 
+
+# From Steffen Thorsen (2009-08-27):
+# Samoa's parliament passed the Daylight Saving Bill 2009, and will start 
+# daylight saving time on the first Sunday of October 2009 and end on the 
+# last Sunday of March 2010. We hope that the full text will be published 
+# soon, but we believe that the bill is only valid for 2009-2010. Samoa's 
+# Daylight Saving Act 2009 will be enforced as soon as the Head of State 
+# executes a proclamation publicizing this Act.
+#
+# Some background information here, which will be updated once we have 
+# more details:
+# 
+# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
+# 
+
 Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
 			-11:26:56 -	LMT	1911
 			-11:30	-	SAMT	1950		# Samoa Time
-			-11:00	-	WST			# Samoa Time
+			-11:00	-	WST	2009 Oct 4
+			-11:00	1:00	WSDT	2010 Mar 28
+			-11:00	-	WST
 
 # Solomon Is
 # excludes Bougainville, for which see Papua New Guinea
diff --git a/share/zoneinfo/europe b/share/zoneinfo/europe
index 3f39215bf64..adf20a2828c 100644
--- a/share/zoneinfo/europe
+++ b/share/zoneinfo/europe
@@ -1,5 +1,5 @@
 # 
-# @(#)europe	8.21
+# @(#)europe	8.22
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -459,7 +459,7 @@ Rule	EU	1979	1995	-	Sep	lastSun	 1:00u	0	-
 Rule	EU	1981	max	-	Mar	lastSun	 1:00u	1:00	S
 Rule	EU	1996	max	-	Oct	lastSun	 1:00u	0	-
 # The most recent directive covers the years starting in 2002.  See:
-# 
+# 
 # Directive 2000/84/EC of the European Parliament and of the Council
 # of 19 January 2001 on summer-time arrangements.
 # 
diff --git a/share/zoneinfo/leapseconds b/share/zoneinfo/leapseconds
index 995c8a019a3..a3c95efb1c8 100644
--- a/share/zoneinfo/leapseconds
+++ b/share/zoneinfo/leapseconds
@@ -1,5 +1,5 @@
 # 
-# @(#)leapseconds	8.8
+# @(#)leapseconds	8.9
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -58,29 +58,30 @@ Leap	2008	Dec	31	23:59:60	+	S
 # 61, Av. de l'Observatoire 75014 PARIS (France)
 # Tel.      : 33 (0) 1 40 51 22 26
 # FAX       : 33 (0) 1 40 51 22 91
-# e-mail    : services.iers@obspm.fr
-# http://hpiers.obspm.fr/eop-pc
+# Internet  : services.iers@obspm.fr
 #
-# Paris, 15 January 2009
+# Paris, 4 July 2009
 #
-# Bulletin C 37
+# Bulletin C 38
 #
 # To authorities responsible
 # for the measurement and
 # distribution of time
 #
-# NO positive leap second will be introduced at the end of June 2009.
-# The difference between Coordinated Universal Time UTC and the 
-# International Atomic Time TAI is :             
-#                
-#     from 2009 January 1, 0h UTC, until further notice : UTC-TAI = -34 s
+# INFORMATION ON UTC - TAI
+#
+# NO positive leap second will be introduced at the end of December 2009.
+# The difference between Coordinated Universal Time UTC and the
+# International Atomic Time TAI is :		
+#
+# from 2009 January 1, 0h UTC, until further notice : UTC-TAI = -34 s
 #
 # Leap seconds can be introduced in UTC at the end of the months of December
-# or June, depending on the evolution of UT1-TAI. Bulletin C is mailed every
-# six months, either to announce a time step in UTC or to confirm that there
+# or June,  depending on the evolution of UT1-TAI. Bulletin C is mailed every
+# six months, either to announce a time step in UTC, or to confirm that there
 # will be no time step at the next possible date.
 #
 # Daniel GAMBIS
-# Head		
+# Director			
 # Earth Orientation Center of IERS
 # Observatoire de Paris, France

From 93566d2a832875da7de83a806c16372ea561805a Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Wed, 9 Sep 2009 13:28:18 +0000
Subject: [PATCH 0209/2592] MFC r196887: In fhopen, vfs_ref() the mount point
 while vnode is unlocked, to prevent vn_start_write(NULL, &mp) from operating
 on potentially freed or reused struct mount *.

Remove unmatched vfs_rel() in cleanup.

Approved by:	re (kensmith)
---
 sys/kern/vfs_syscalls.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index ed7f999ccef..0a8ef463957 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -4439,12 +4439,15 @@ fhopen(td, uap)
 			goto bad;
 	}
 	if (fmode & O_TRUNC) {
+		vfs_ref(mp);
 		VOP_UNLOCK(vp, 0);				/* XXX */
 		if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) {
 			vrele(vp);
+			vfs_rel(mp);
 			goto out;
 		}
 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);	/* XXX */
+		vfs_rel(mp);
 #ifdef MAC
 		/*
 		 * We don't yet have fp->f_cred, so use td->td_ucred, which
@@ -4516,7 +4519,6 @@ fhopen(td, uap)
 
 	VOP_UNLOCK(vp, 0);
 	fdrop(fp, td);
-	vfs_rel(mp);
 	VFS_UNLOCK_GIANT(vfslocked);
 	td->td_retval[0] = indx;
 	return (0);

From 0ebf7e8dfc08e7152f30e8842ba170ed436a380c Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Thu, 10 Sep 2009 11:27:07 +0000
Subject: [PATCH 0210/2592] MFC r196916: Fix a list overrun.

Sponsored by:	Sandvine Incorporated
Approved by:	re (kib)
---
 contrib/gdtoa/gdtoaimp.h |  2 +-
 contrib/gdtoa/misc.c     | 18 ++++++++++++------
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/contrib/gdtoa/gdtoaimp.h b/contrib/gdtoa/gdtoaimp.h
index c550ada8775..9991ffac6e9 100644
--- a/contrib/gdtoa/gdtoaimp.h
+++ b/contrib/gdtoa/gdtoaimp.h
@@ -485,7 +485,7 @@ extern pthread_mutex_t __gdtoa_locks[2];
 		_pthread_mutex_unlock(&__gdtoa_locks[n]);	\
 } while(0)
 
-#define Kmax 15
+#define Kmax 9
 
  struct
 Bigint {
diff --git a/contrib/gdtoa/misc.c b/contrib/gdtoa/misc.c
index b3ce7c9b8a4..8d2888e249f 100644
--- a/contrib/gdtoa/misc.c
+++ b/contrib/gdtoa/misc.c
@@ -55,7 +55,9 @@ Balloc
 #endif
 
 	ACQUIRE_DTOA_LOCK(0);
-	if ( (rv = freelist[k]) !=0) {
+	/* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
+	/* but this case seems very unlikely. */
+	if (k <= Kmax && (rv = freelist[k]) !=0) {
 		freelist[k] = rv->next;
 		}
 	else {
@@ -65,7 +67,7 @@ Balloc
 #else
 		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
 			/sizeof(double);
-		if (pmem_next - private_mem + len <= PRIVATE_mem) {
+		if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
 			rv = (Bigint*)pmem_next;
 			pmem_next += len;
 			}
@@ -89,10 +91,14 @@ Bfree
 #endif
 {
 	if (v) {
-		ACQUIRE_DTOA_LOCK(0);
-		v->next = freelist[v->k];
-		freelist[v->k] = v;
-		FREE_DTOA_LOCK(0);
+		if (v->k > Kmax)
+			free((void*)v);
+		else {
+			ACQUIRE_DTOA_LOCK(0);
+			v->next = freelist[v->k];
+			freelist[v->k] = v;
+			FREE_DTOA_LOCK(0);
+			}
 		}
 	}
 

From b67ca8999b94fe5f4581a0276f943d7a62d70576 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 10 Sep 2009 12:42:36 +0000
Subject: [PATCH 0211/2592] MFC r196920: insmntque_stddtr() clears vp->v_data
 and resets vp->v_op to dead_vnodeops before calling vgone(). Revert r189706
 and corresponding part of the r186560.

Approved by:	re (kensmith)
---
 sys/fs/pseudofs/pseudofs_vncache.c | 1 +
 sys/ufs/ffs/ffs_vfsops.c           | 1 +
 2 files changed, 2 insertions(+)

diff --git a/sys/fs/pseudofs/pseudofs_vncache.c b/sys/fs/pseudofs/pseudofs_vncache.c
index 31458707b58..a92a44614bc 100644
--- a/sys/fs/pseudofs/pseudofs_vncache.c
+++ b/sys/fs/pseudofs/pseudofs_vncache.c
@@ -193,6 +193,7 @@ retry:
 	vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
 	error = insmntque(*vpp, mp);
 	if (error != 0) {
+		free(pvd, M_PFSVNCACHE);
 		*vpp = NULLVP;
 		return (error);
 	}
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 7aae80828c4..d3d7c2c6073 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1467,6 +1467,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
 		vp->v_vflag |= VV_FORCEINSMQ;
 	error = insmntque(vp, mp);
 	if (error != 0) {
+		uma_zfree(uma_inode, ip);
 		*vpp = NULL;
 		return (error);
 	}

From ac7d4c93c61017f96abce6fe2fd9a6baa52c6593 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Thu, 10 Sep 2009 14:04:00 +0000
Subject: [PATCH 0212/2592] Remove extra debugging support that is turned on
 for head but turned off for stable branches:

	- shift to MALLOC_PRODUCTION
	- turn off automatic crash dumps
	- Remove kernel debuggers, INVARIANTS*[1], WITNESS* from
	  GENERIC kernel config files[2]

[1] INVARIANTS* left on for ia64 by request marcel
[2] sun4v was left as-is

Reviewed by:	marcel, kib
Approved by:	re (implicit)
---
 etc/defaults/rc.conf     | 2 +-
 lib/libc/stdlib/malloc.c | 2 +-
 sys/amd64/conf/GENERIC   | 9 ---------
 sys/i386/conf/GENERIC    | 9 ---------
 sys/ia64/conf/GENERIC    | 5 -----
 sys/pc98/conf/GENERIC    | 9 ---------
 sys/powerpc/conf/GENERIC | 8 --------
 sys/sparc64/conf/GENERIC | 9 ---------
 8 files changed, 2 insertions(+), 51 deletions(-)

diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index edeedaeaca7..72c120927da 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -549,7 +549,7 @@ lpd_flags=""		# Flags to lpd (if enabled).
 nscd_enable="NO"	# Run the nsswitch caching daemon.
 chkprintcap_enable="NO"	# Run chkprintcap(8) before running lpd.
 chkprintcap_flags="-d"	# Create missing directories by default.
-dumpdev="AUTO"		# Device to crashdump to (device name, AUTO, or NO).
+dumpdev="NO"		# Device to crashdump to (device name, AUTO, or NO).
 dumpdir="/var/crash"	# Directory where crash dumps are to be stored
 savecore_flags=""	# Used if dumpdev is enabled above, and present.
 crashinfo_enable="YES"	# Automatically generate crash dump summary.
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
index 270d64198fc..e60746a778e 100644
--- a/lib/libc/stdlib/malloc.c
+++ b/lib/libc/stdlib/malloc.c
@@ -114,7 +114,7 @@
  * defaults the A and J runtime options to off.  These settings are appropriate
  * for production systems.
  */
-/* #define	MALLOC_PRODUCTION */
+#define	MALLOC_PRODUCTION
 
 #ifndef MALLOC_PRODUCTION
    /*
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index a49f7bca10c..ddd3035ccdb 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -76,15 +76,6 @@ options		FLOWTABLE		# per-cpu routing cache
 #options 	KDTRACE_FRAME		# Ensure frames are compiled in
 #options 	KDTRACE_HOOKS		# Kernel DTrace hooks
 
-# Debugging for use in -current
-options 	KDB			# Enable kernel debugger support.
-options 	DDB			# Support DDB.
-options 	GDB			# Support remote GDB.
-options 	INVARIANTS		# Enable calls of extra sanity checking
-options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
-options 	WITNESS			# Enable checks to detect deadlocks and cycles
-options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
-
 # Make an SMP-capable kernel by default
 options 	SMP			# Symmetric MultiProcessor Kernel
 
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index ef958af9a14..62fdff78e53 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -76,15 +76,6 @@ options 	MAC			# TrustedBSD MAC Framework
 options		FLOWTABLE		# per-cpu routing cache
 #options 	KDTRACE_HOOKS		# Kernel DTrace hooks
 
-# Debugging for use in -current
-options 	KDB			# Enable kernel debugger support.
-options 	DDB			# Support DDB.
-options 	GDB			# Support remote GDB.
-options 	INVARIANTS		# Enable calls of extra sanity checking
-options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
-options 	WITNESS			# Enable checks to detect deadlocks and cycles
-options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
-
 # To make an SMP kernel, the next two lines are needed
 options 	SMP			# Symmetric MultiProcessor Kernel
 device		apic			# I/O APIC
diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
index b143868870b..10d51d52645 100644
--- a/sys/ia64/conf/GENERIC
+++ b/sys/ia64/conf/GENERIC
@@ -30,15 +30,12 @@ options 	CD9660		# ISO 9660 Filesystem
 options 	COMPAT_43TTY	# BSD 4.3 TTY compat (sgtty)
 options 	COMPAT_FREEBSD6	# Compatible with FreeBSD6
 options 	COMPAT_FREEBSD7	# Compatible with FreeBSD7
-options 	DDB		# Support DDB
 options 	FFS		# Berkeley Fast Filesystem
-options 	GDB		# Support remote GDB
 options 	GEOM_LABEL	# Provides labelization
 options 	INET		# InterNETworking
 options 	INET6		# IPv6 communications protocols
 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 	MD_ROOT		# MD usable as root device
@@ -62,8 +59,6 @@ options 	P1003_1B_SEMAPHORES	# POSIX-style semaphores
 options 	UFS_ACL		# Support for access control lists
 options 	UFS_DIRHASH	# Hash-based directory lookup scheme
 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)
 
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index ef75694ca50..27259895662 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -76,15 +76,6 @@ options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
 options 	AUDIT			# Security event auditing
 options 	MAC			# TrustedBSD MAC Framework
 
-# Debugging for use in -current
-options 	KDB			# Enable kernel debugger support.
-options 	DDB			# Support DDB.
-options 	GDB			# Support remote GDB.
-options 	INVARIANTS		# Enable calls of extra sanity checking
-options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
-options 	WITNESS			# Enable checks to detect deadlocks and cycles
-options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
-
 # To make an SMP kernel, the next two lines are needed
 #options 	SMP			# Symmetric MultiProcessor Kernel
 #device		apic			# I/O APIC
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index 30f6961e1eb..51bf6c7dfef 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -67,14 +67,6 @@ options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
 options 	AUDIT			# Security event auditing
 options 	MAC			# TrustedBSD MAC Framework
 
-# Debugging for use in -current
-options 	KDB			#Enable the kernel debugger
-options 	DDB			#Support DDB
-options 	INVARIANTS		#Enable calls of extra sanity checking
-options 	INVARIANT_SUPPORT	#Extra sanity checks of internal structures, required by INVARIANTS
-options 	WITNESS			#Enable checks to detect deadlocks and cycles
-options 	WITNESS_SKIPSPIN	#Don't run witness on spinlocks for speed
-
 # To make an SMP kernel, the next line is needed
 #options 	SMP			# Symmetric MultiProcessor Kernel
 
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index 95be09ad623..09e56e93ffd 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -72,15 +72,6 @@ options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
 options 	AUDIT			# Security event auditing
 options 	MAC			# TrustedBSD MAC Framework
 
-# Debugging for use in -current
-options 	KDB			# Enable kernel debugger support.
-options 	DDB			# Support DDB.
-options 	GDB			# Support remote GDB.
-options 	INVARIANTS		# Enable calls of extra sanity checking
-options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
-options 	WITNESS			# Enable checks to detect deadlocks and cycles
-options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
-
 # Make an SMP-capable kernel by default
 options 	SMP			# Symmetric MultiProcessor Kernel
 

From 8f0b752891410af934ab8b8392d18a325a177fb9 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Fri, 11 Sep 2009 12:56:13 +0000
Subject: [PATCH 0213/2592] MFC r196966: Lock Giant around vn_open_cred().
 Remove innocent unnecessary call to NDFREE().

Approved by:	re (kensmith)
---
 sys/cddl/compat/opensolaris/kern/opensolaris_kobj.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_kobj.c b/sys/cddl/compat/opensolaris/kern/opensolaris_kobj.c
index c2144888aed..d79434511e5 100644
--- a/sys/cddl/compat/opensolaris/kern/opensolaris_kobj.c
+++ b/sys/cddl/compat/opensolaris/kern/opensolaris_kobj.c
@@ -69,7 +69,7 @@ kobj_open_file_vnode(const char *file)
 	struct thread *td = curthread;
 	struct filedesc *fd;
 	struct nameidata nd;
-	int error, flags;
+	int error, flags, vfslocked;
 
 	fd = td->td_proc->p_fd;
 	FILEDESC_XLOCK(fd);
@@ -86,11 +86,13 @@ kobj_open_file_vnode(const char *file)
 	flags = FREAD | O_NOFOLLOW;
 	NDINIT(&nd, LOOKUP, MPSAFE, UIO_SYSSPACE, file, td);
 	error = vn_open_cred(&nd, &flags, 0, 0, curthread->td_ucred, NULL);
-	NDFREE(&nd, NDF_ONLY_PNBUF);
 	if (error != 0)
 		return (NULL);
+	vfslocked = NDHASGIANT(&nd);
+	NDFREE(&nd, NDF_ONLY_PNBUF);
 	/* We just unlock so we hold a reference. */
 	VOP_UNLOCK(nd.ni_vp, 0);
+	VFS_UNLOCK_GIANT(vfslocked);
 	return (nd.ni_vp);
 }
 

From d8b6f57c831c9871da487355c6ef56563841d920 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Fri, 11 Sep 2009 13:46:28 +0000
Subject: [PATCH 0214/2592] MFC r196942: > Bring the layout of package-split.py
 more in line with where we're going > with packages on the release media.  It
 looks like we'll be putting just > the doc packages on the new "memory stick"
 image as well as disc1.  There > will be no other packages on the CDROM-sized
 media.  The DVD sized media > will include the doc packages plus whatever
 other packages we decide to > make part of the release. > > This commit just
 brings the basic structure in line with being able to > do this.  We still
 need to discuss with various people exactly which > packages will be included
 on the DVD. > > If the environement variable "PKG_DVD" is set a tree suitable
 for the > DVD media is generated.  Otherwise a tree suitable for the "memory
 stick" > and disc1 is generated.

Approved by:	re (kib)
---
 release/scripts/package-split.py | 121 ++++++++++++++-----------------
 1 file changed, 54 insertions(+), 67 deletions(-)

diff --git a/release/scripts/package-split.py b/release/scripts/package-split.py
index 54fdde03abf..6d895297c16 100644
--- a/release/scripts/package-split.py
+++ b/release/scripts/package-split.py
@@ -23,71 +23,14 @@ if 'PKG_VERBOSE' in os.environ:
 else:
     verbose = 0
 
-# List of packages for disc1.  This just includes packages sysinstall can
-# install as a distribution
+if 'PKG_DVD' in os.environ:
+    doing_dvd = 1
+else:
+    doing_dvd = 0
+
+# List of packages for disc1.
 def disc1_packages():
-    pkgs = ['lang/perl5.8']
-    pkgs.extend(['x11/xorg',
-                 'devel/imake'])
-    if arch == 'i386':
-        pkgs.append('emulators/linux_base-fc4')
-    return pkgs
-
-# List of packages for disc2.  This includes packages that the X desktop
-# menu depends on (if it still exists) and other "nice to have" packages.
-# For architectures that use a separate livefs, this is actually disc3.
-def disc2_packages():
-            # X Desktops
-    if arch == 'ia64':
-	pkgs = ['x11/gnome2-lite',
-		'x11/kde-lite']
-    else:
-	pkgs = ['x11/gnome2',
-		'x11/kde3']
-    pkgs.extend(['x11-wm/afterstep',
-            'x11-wm/windowmaker',
-            'x11-wm/fvwm2',
-            # "Nice to have"
-            'archivers/unzip',
-            'astro/xearth',                 
-            'devel/gmake',
-            'editors/emacs',
-            'editors/vim-lite',
-            'emulators/mtools',
-            'graphics/png',
-            'graphics/xv',
-            'irc/xchat',
-            'mail/exim',
-            'mail/fetchmail',
-            'mail/mutt',
-            'mail/pine4',
-            'mail/popd',
-            'mail/xfmail',
-            'mail/postfix',
-            'net/cvsup-without-gui',
-            'net/rsync',
-            'net/samba3',
-            'news/slrn',
-            'news/tin',
-            'ports-mgmt/portupgrade',
-            'print/a2ps-letter',
-            'print/apsfilter',
-            'print/ghostscript-gnu-nox11',
-            'print/gv',
-            'print/psutils-letter',
-            'shells/bash',
-            'shells/pdksh',
-            'shells/zsh',
-            'security/sudo',
-            'www/links',
-            'www/lynx',
-            'x11/rxvt',
-            # Formerly on disc3
-            'ports-mgmt/portaudit'])
-    return pkgs
-
-def docs_packages():
-    pkgs = ['misc/freebsd-doc-bn',
+    pkgs = ['misc/freebsd-doc-bn', 
 	    'misc/freebsd-doc-da',
 	    'misc/freebsd-doc-de',
 	    'misc/freebsd-doc-el',
@@ -106,14 +49,58 @@ def docs_packages():
 	    'misc/freebsd-doc-tr',
 	    'misc/freebsd-doc-zh_cn',
 	    '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',
+	    'astro/xearth',
+	    'devel/gmake',
+	    'editors/emacs',
+	    'editors/vim-lite',
+	    'emulators/mtools',
+	    'graphics/png',
+	    'graphics/xv',
+	    'irc/xchat',
+	    'mail/exim',
+	    'mail/fetchmail',
+	    'mail/mutt',
+	    'mail/alpine',
+	    'mail/popd',
+	    'mail/xfmail',
+	    'mail/postfix',
+	    'net/cvsup-without-gui',
+	    'net/rsync',
+	    'net/samba3',
+	    'news/slrn',
+	    'news/tin',
+	    'ports-mgmt/portupgrade',
+	    'print/a2ps-letter',
+	    'print/apsfilter',
+	    'print/ghostscript7-nox11',
+	    'print/gv',
+	    'print/psutils-letter',
+	    'shells/bash',
+	    'shells/pdksh',
+	    'shells/zsh',
+	    'security/sudo',
+	    'www/links',
+	    'www/lynx',
+	    'x11/rxvt',
+	    'ports-mgmt/portaudit'])
     return pkgs
 
 # The list of desired packages
 def desired_packages():
     disc1 = disc1_packages()
-    disc2 = disc2_packages()
-    docs = docs_packages()
-    return [disc1, disc2, docs]
+    return [disc1]
 
 # Suck the entire INDEX file into a two different dictionaries.  The first
 # dictionary maps port names (origins) to package names.  The second

From d51cecd143c5dae385fe7fcfcac42e53ff3b4f42 Mon Sep 17 00:00:00 2001
From: Shteryana Shopova 
Date: Fri, 11 Sep 2009 15:07:36 +0000
Subject: [PATCH 0215/2592] MFC r196932:

When joining a multicast group, the inp_lookup_mcast_ifp call
does a KASSERT that the group address is multicast, so the
check if this is indeed true and eventually return a EINVAL if not,
should be done before calling inp_lookup_mcast_ifp. This fixes a kernel
crash when calling setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,...)
with invalid group address.

Reviewed by:	bms
Approved by:	re (kib)
---
 sys/netinet/in_mcast.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
index d0e139751e9..9a828210cc6 100644
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -1899,6 +1899,9 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 			ssa->sin.sin_addr = mreqs.imr_sourceaddr;
 		}
 
+		if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
+			return (EINVAL);
+
 		ifp = inp_lookup_mcast_ifp(inp, &gsa->sin,
 		    mreqs.imr_interface);
 		CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p",
@@ -1936,6 +1939,9 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 			ssa->sin.sin_port = 0;
 		}
 
+		if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
+			return (EINVAL);
+
 		if (gsr.gsr_interface == 0 || V_if_index < gsr.gsr_interface)
 			return (EADDRNOTAVAIL);
 		ifp = ifnet_byindex(gsr.gsr_interface);
@@ -1948,9 +1954,6 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 		break;
 	}
 
-	if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
-		return (EINVAL);
-
 	if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0)
 		return (EADDRNOTAVAIL);
 

From b9a65dadc276b35b13ee068de26257ddfc0989d6 Mon Sep 17 00:00:00 2001
From: Jack F Vogel 
Date: Fri, 11 Sep 2009 16:53:12 +0000
Subject: [PATCH 0216/2592] This fixes kern/138516, an mbuf leak in both the em
 and igb driver, when a transmit fails the packet/mbuf was not being requeued.
 Thanks to those that pointed this problem out.

Approved by:  re
---
 sys/dev/e1000/if_em.c  | 15 ++++++++++-----
 sys/dev/e1000/if_igb.c | 20 ++++++++++++++------
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 1def87631db..7a2dbad33de 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -1034,9 +1034,10 @@ em_mq_start_locked(struct ifnet *ifp, struct mbuf *m)
 		return (error);
 	} else if (drbr_empty(ifp, adapter->br) &&
 	    (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) {
-		if (em_xmit(adapter, &m)) {
-			if (m && (error = drbr_enqueue(ifp, adapter->br, m)) != 0)
-				return (error);
+		if ((error = em_xmit(adapter, &m)) != 0) {
+			if (m != NULL)
+				error = drbr_enqueue(ifp, adapter->br, m);
+			return (error);
 		} else {
 			/*
 			 * We've bypassed the buf ring so we need to update
@@ -1063,8 +1064,12 @@ process:
                 next = drbr_dequeue(ifp, adapter->br);
                 if (next == NULL)
                         break;
-                if (em_xmit(adapter, &next))
+                if ((error = em_xmit(adapter, &next)) != 0) {
+			if (next != NULL)
+				error = drbr_enqueue(ifp, adapter->br, next);
                         break;
+		}
+		drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
                 ETHER_BPF_MTAP(ifp, next);
                 /* Set the watchdog */
                 adapter->watchdog_timer = EM_TX_TIMEOUT;
@@ -1073,7 +1078,7 @@ process:
         if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 
-	return (0);
+	return (error);
 }
 
 /*
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index 4124fa14b92..e6ad0fccc87 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -854,9 +854,10 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
 
 	/* If nothing queued go right to xmit */
 	if (drbr_empty(ifp, txr->br)) {
-		if (igb_xmit(txr, &m)) {
-			if (m && (err = drbr_enqueue(ifp, txr->br, m)) != 0)
-                                return (err);
+		if ((err = igb_xmit(txr, &m)) != 0) {
+			if (m != NULL)
+				err = drbr_enqueue(ifp, txr->br, m);
+			return (err);
 		} else {
 			/* Success, update stats */
 			drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags);
@@ -880,8 +881,12 @@ process:
 		next = drbr_dequeue(ifp, txr->br);
 		if (next == NULL)
 			break;
-		if (igb_xmit(txr, &next))
+		if ((err = igb_xmit(txr, &next)) != 0) {
+			if (next != NULL)
+				err = drbr_enqueue(ifp, txr->br, next);
 			break;
+		}
+		drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
 		ETHER_BPF_MTAP(ifp, next);
 		/* Set the watchdog */
 		txr->watchdog_timer = IGB_TX_TIMEOUT;
@@ -1531,8 +1536,11 @@ igb_update_aim(struct rx_ring *rxr)
 	if (olditr != newitr) {
 		/* Change interrupt rate */
 		rxr->eitr_setting = newitr;
-		E1000_WRITE_REG(&adapter->hw, E1000_EITR(rxr->me),
-		    newitr | (newitr << 16));
+		if (adapter->hw.mac.type == e1000_82575)
+			newitr |= newitr << 16;
+		else
+			newitr |= 0x8000000;
+		E1000_WRITE_REG(&adapter->hw, E1000_EITR(rxr->me), newitr);
 	}
 
 	rxr->bytes = 0;

From f222133ab74ddd3a763053e73f0b0f42d367afa7 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sat, 12 Sep 2009 17:58:15 +0000
Subject: [PATCH 0217/2592] This fixes a bug where the value set by
 SCTP_PARTIAL_DELIVERY_POINT was not honored, if the socket buffer size was
 not 4 times that large. MFC of 196509.

Approved by: re, rrs (mentor)`
---
 sys/netinet/sctp_indata.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 52d53e1b975..5914105c147 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -921,7 +921,7 @@ doit_again:
 			 * but should we?
 			 */
 			if (stcb->sctp_socket) {
-				pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
+				pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
 				    stcb->sctp_ep->partial_delivery_point);
 			} else {
 				pd_point = stcb->sctp_ep->partial_delivery_point;
@@ -2862,11 +2862,11 @@ doit_again:
 
 		/*
 		 * Before we start though either all of the message should
-		 * be here or 1/4 the socket buffer max or nothing on the
+		 * be here or the socket buffer max or nothing on the
 		 * delivery queue and something can be delivered.
 		 */
 		if (stcb->sctp_socket) {
-			pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
+			pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
 			    stcb->sctp_ep->partial_delivery_point);
 		} else {
 			pd_point = stcb->sctp_ep->partial_delivery_point;

From 3c9d279b1d864f5276d397e975ae6a996240923f Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sat, 12 Sep 2009 18:02:57 +0000
Subject: [PATCH 0218/2592] MFC r197030: In vfs_mark_atime(9), be resistent
 against reclaimed vnodes. Assert that neccessary locks are taken, since vop
 might not be called.

Approved by:	re (kensmith)
---
 sys/kern/vfs_subr.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 3beb881f3ed..f3ec5650956 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -4269,8 +4269,12 @@ vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off)
 void
 vfs_mark_atime(struct vnode *vp, struct ucred *cred)
 {
+	struct mount *mp;
 
-	if ((vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0)
+	mp = vp->v_mount;
+	VFS_ASSERT_GIANT(mp);
+	ASSERT_VOP_LOCKED(vp, "vfs_mark_atime");
+	if (mp != NULL && (mp->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0)
 		(void)VOP_MARKATIME(vp);
 }
 

From d4c8e5ac7bf67946837a5b60ce82754d914ad002 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sat, 12 Sep 2009 18:05:57 +0000
Subject: [PATCH 0219/2592] MFC r197031: Unlock the image vnode around the call
 of pmc PMC_FN_PROCESS_EXEC hook. The hook calls vn_fullpath(9), that should
 not be executed with a vnode lock held.

Approved by:	re (kensmith)
---
 sys/kern/kern_exec.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index e770d074acd..a90968f0368 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -786,10 +786,12 @@ interpret:
 	 */
 	if (PMC_SYSTEM_SAMPLING_ACTIVE() || PMC_PROC_IS_USING_PMCS(p)) {
 		PROC_UNLOCK(p);
+		VOP_UNLOCK(imgp->vp, 0);
 		pe.pm_credentialschanged = credential_changing;
 		pe.pm_entryaddr = imgp->entry_addr;
 
 		PMC_CALL_HOOK_X(td, PMC_FN_PROCESS_EXEC, (void *) &pe);
+		vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
 	} else
 		PROC_UNLOCK(p);
 #else  /* !HWPMC_HOOKS */

From ceda2d70e45650ce9a84e4e16081e9693a2c143d Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sat, 12 Sep 2009 18:08:44 +0000
Subject: [PATCH 0220/2592] MFC 196610: Fix a bug where vlan interfaces are not
 supported by SCTP.

Approved by: re, rrs (mentor)
---
 sys/netinet/sctp_bsd_addr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c
index 4b857815dc9..792a720b6df 100644
--- a/sys/netinet/sctp_bsd_addr.c
+++ b/sys/netinet/sctp_bsd_addr.c
@@ -175,6 +175,7 @@ sctp_is_desired_interface_type(struct ifaddr *ifa)
 	case IFT_LOOP:
 	case IFT_SLIP:
 	case IFT_GIF:
+	case IFT_L2VLAN:
 	case IFT_IP:
 	case IFT_IPOVERCDLC:
 	case IFT_IPOVERCLAW:

From 72c975651d7e13bd584999a820542a1123b643ab Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sat, 12 Sep 2009 18:11:48 +0000
Subject: [PATCH 0221/2592] MFC r197046: As was done in r196643 for i386 and
 amd64, swap the start/end virtual addresses in pmap_invalidate_cache_range().

Approved by:	re (kensmith)
---
 sys/i386/xen/pmap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index 9dc077f8803..7667142c5d7 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -1010,8 +1010,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
 		 * coherence domain.
 		 */
 		mfence();
-		for (; eva < sva; eva += cpu_clflush_line_size)
-			clflush(eva);
+		for (; sva < eva; sva += cpu_clflush_line_size)
+			clflush(sva);
 		mfence();
 	} else {
 

From 80bc871bdd4a8254ce19a65a54c8c918dd3ddd11 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sat, 12 Sep 2009 18:16:46 +0000
Subject: [PATCH 0222/2592] MFC r196861: Handle zero size for posix_memalign.
 Return NULL or unique address according to the 'V' option.

Approved by:	re (kensmith)
---
 lib/libc/stdlib/malloc.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
index e60746a778e..8b13d1218d9 100644
--- a/lib/libc/stdlib/malloc.c
+++ b/lib/libc/stdlib/malloc.c
@@ -5320,6 +5320,15 @@ posix_memalign(void **memptr, size_t alignment, size_t size)
 			goto RETURN;
 		}
 
+		if (size == 0) {
+			if (opt_sysv == false)
+				size = 1;
+			else {
+				result = NULL;
+				ret = 0;
+				goto RETURN;
+			}
+		}
 		result = ipalloc(alignment, size);
 	}
 

From 87c120a67aa60e3b81f80b1728d636ec22d5a04e Mon Sep 17 00:00:00 2001
From: Norikatsu Shigemura 
Date: Sun, 13 Sep 2009 10:04:08 +0000
Subject: [PATCH 0223/2592] MFC r196889: Change 'dev.cpu.N.temperature', sysctl
 I (degC) to IK (Kelvin), to match acpi_thermal(4) and amdtemp(4).

Approved by:	re (rwatson)
Reviewed by:	rpaulo
Suggested by:	ume
---
 sys/dev/coretemp/coretemp.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/sys/dev/coretemp/coretemp.c b/sys/dev/coretemp/coretemp.c
index d639eec59fd..0226c8f1cd4 100644
--- a/sys/dev/coretemp/coretemp.c
+++ b/sys/dev/coretemp/coretemp.c
@@ -48,6 +48,8 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
+#define	TZ_ZEROC	2732
+
 struct coretemp_softc {
 	device_t	sc_dev;
 	int		sc_tjmax;
@@ -193,8 +195,8 @@ coretemp_attach(device_t dev)
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(pdev)),
 	    OID_AUTO, "temperature",
 	    CTLTYPE_INT | CTLFLAG_RD,
-	    dev, 0, coretemp_get_temp_sysctl, "I",
-	    "Current temperature in degC");
+	    dev, 0, coretemp_get_temp_sysctl, "IK",
+	    "Current temperature");
 
 	return (0);
 }
@@ -283,7 +285,7 @@ coretemp_get_temp_sysctl(SYSCTL_HANDLER_ARGS)
 	device_t dev = (device_t) arg1;
 	int temp;
 
-	temp = coretemp_get_temp(dev);
+	temp = coretemp_get_temp(dev) * 10 + TZ_ZEROC;
 
 	return (sysctl_handle_int(oidp, &temp, 0, req));
 }

From 5858b2fdd2a17950af55b1d8192ea19207fe3b80 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Sun, 13 Sep 2009 11:31:25 +0000
Subject: [PATCH 0224/2592] MFC r196929: Suppress an options line when no bit
 is on.

Approved by:	re (kib)
---
 sbin/ifconfig/ifgif.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sbin/ifconfig/ifgif.c b/sbin/ifconfig/ifgif.c
index f9f3524e98e..aed6382b2fa 100644
--- a/sbin/ifconfig/ifgif.c
+++ b/sbin/ifconfig/ifgif.c
@@ -71,6 +71,8 @@ gif_status(int s)
 	ifr.ifr_data = (caddr_t)&opts;
 	if (ioctl(s, GIFGOPTS, &ifr) == -1)
 		return;
+	if (opts == 0)
+		return;
 
 	printf("\toptions=%d<", opts);
 	for (i=0; i < sizeof(gif_opts)/sizeof(gif_opts[0]); i++) {

From 43ea76c98d13e2575f8c9b4d32467aa44d199717 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Sun, 13 Sep 2009 11:34:33 +0000
Subject: [PATCH 0225/2592] MFC r196475:  - Add AS lookup functionality to
 traceroute6(8) as well.  - Support for IPv6 transport for AS lookup.  -
 Introduce $RA_SERVER to set whois server.  - Support for 4 byte ASN.  -
 ANSIfy function declaration in as.c.

Approved by:	re (kib)
---
 contrib/traceroute/as.c            | 86 +++++++++++++-----------------
 contrib/traceroute/as.h            |  6 +--
 contrib/traceroute/traceroute.c    | 10 ++--
 usr.sbin/traceroute6/Makefile      |  5 ++
 usr.sbin/traceroute6/traceroute6.8 | 11 +++-
 usr.sbin/traceroute6/traceroute6.c | 29 +++++++++-
 6 files changed, 87 insertions(+), 60 deletions(-)

diff --git a/contrib/traceroute/as.c b/contrib/traceroute/as.c
index abb6c710805..689848a89cf 100644
--- a/contrib/traceroute/as.c
+++ b/contrib/traceroute/as.c
@@ -63,55 +63,42 @@ struct aslookup {
 };
 
 void *
-as_setup(server)
-	char *server;
+as_setup(char *server)
 {
 	struct aslookup *asn;
-	struct hostent *he = NULL;
-	struct servent *se;
-	struct sockaddr_in in;
+	struct addrinfo hints, *res0, *res;
 	FILE *f;
-	int s;
+	int s, error;
 
+	if (server == NULL)
+		server = getenv("RA_SERVER");
 	if (server == NULL)
 		server = DEFAULT_AS_SERVER;
 
-	(void)memset(&in, 0, sizeof(in));
-	in.sin_family = AF_INET;
-	in.sin_len = sizeof(in);
-	if ((se = getservbyname("whois", "tcp")) == NULL) {
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	error = getaddrinfo(server, "whois", &hints, &res0);
+	if (error == EAI_SERVICE) {
 		warnx("warning: whois/tcp service not found");
-		in.sin_port = ntohs(43);
-	} else
-		in.sin_port = se->s_port;
-
-	if (inet_aton(server, &in.sin_addr) == 0 && 
-	    ((he = gethostbyname(server)) == NULL ||
-	    he->h_addr == NULL)) {
-		warnx("%s: %s", server, hstrerror(h_errno));
+		error = getaddrinfo(server, "43", &hints, &res0);
+	}
+	if (error != 0) {
+		warnx("%s: %s", server, gai_strerror(error));
 		return (NULL);
 	}
 
-	if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
-		warn("socket");
-		return (NULL);
+	for (res = res0; res; res = res->ai_next) {
+		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+		if (s < 0)
+			continue;
+		if (connect(s, res->ai_addr, res->ai_addrlen) >= 0)
+			break;
+		close(s);
+		s = -1;
 	}
-
-	do {
-		if (he != NULL) {
-			memcpy(&in.sin_addr, he->h_addr, he->h_length);
-			he->h_addr_list++;
-		}
-		if (connect(s, (struct sockaddr *)&in, sizeof(in)) == 0)
-			break;
-		if (he == NULL || he->h_addr == NULL) {
-			close(s);
-			s = -1;
-			break;
-		}
-	} while (1);
-
-	if (s == -1) {
+	freeaddrinfo(res0);
+	if (s < 0) {
 		warn("connect");
 		return (NULL);
 	}
@@ -137,23 +124,23 @@ as_setup(server)
 	return (asn);
 }
 
-int
-as_lookup(_asn, addr)
-	void *_asn;
-	struct in_addr *addr;
+unsigned int
+as_lookup(void *_asn, char *addr, sa_family_t family)
 {
 	struct aslookup *asn = _asn;
 	char buf[1024];
-	int as, rc, dlen;
+	unsigned int as;
+	int rc, dlen, plen;
 
-	as = rc = dlen = 0;
-	(void)fprintf(asn->as_f, "!r%s/32,l\n", inet_ntoa(*addr));
+	as = 0;
+	rc = dlen = 0;
+	plen = (family == AF_INET6) ? 128 : 32;
+	(void)fprintf(asn->as_f, "!r%s/%d,l\n", addr, plen);
 	(void)fflush(asn->as_f);
 
 #ifdef AS_DEBUG_FILE
 	if (asn->as_debug) {
-		(void)fprintf(asn->as_debug, ">> !r%s/32,l\n",
-		     inet_ntoa(*addr));
+		(void)fprintf(asn->as_debug, ">> !r%s/%d,l\n", addr, plen);
 		(void)fflush(asn->as_debug);
 	}
 #endif /* AS_DEBUG_FILE */
@@ -182,7 +169,7 @@ as_lookup(_asn, addr)
 				}
 #endif /* AS_DEBUG_FILE */
 				break;
-			    case 'C':	
+			    case 'C':
 			    case 'D':
 			    case 'E':
 			    case 'F':
@@ -209,7 +196,7 @@ as_lookup(_asn, addr)
 
 		/* origin line is the interesting bit */
 		if (as == 0 && strncasecmp(buf, "origin:", 7) == 0) {
-			sscanf(buf + 7, " AS%d", &as);
+			sscanf(buf + 7, " AS%u", &as);
 #ifdef AS_DEBUG_FILE
 			if (asn->as_debug) {
 				(void)fprintf(asn->as_debug, "as: %d\n", as);
@@ -223,8 +210,7 @@ as_lookup(_asn, addr)
 }
 
 void
-as_shutdown(_asn)
-	void *_asn;
+as_shutdown(void *_asn)
 {
 	struct aslookup *asn = _asn;
 
diff --git a/contrib/traceroute/as.h b/contrib/traceroute/as.h
index 5ed563ded75..3b7d3a660a5 100644
--- a/contrib/traceroute/as.h
+++ b/contrib/traceroute/as.h
@@ -37,6 +37,6 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-void	*as_setup __P((char *));
-int	as_lookup __P((void *, struct in_addr *));
-void	as_shutdown __P((void *));
+void *as_setup(char *);
+unsigned int as_lookup(void *, char *, sa_family_t);
+void as_shutdown(void *);
diff --git a/contrib/traceroute/traceroute.c b/contrib/traceroute/traceroute.c
index a4bce610145..120d1cd9e57 100644
--- a/contrib/traceroute/traceroute.c
+++ b/contrib/traceroute/traceroute.c
@@ -1477,19 +1477,21 @@ print(register u_char *buf, register int cc, register struct sockaddr_in *from)
 {
 	register struct ip *ip;
 	register int hlen;
+	char addr[INET_ADDRSTRLEN];
 
 	ip = (struct ip *) buf;
 	hlen = ip->ip_hl << 2;
 	cc -= hlen;
 
+	strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
+
 	if (as_path)
-		Printf(" [AS%d]", as_lookup(asn, &from->sin_addr));
+		Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
 
 	if (nflag)
-		Printf(" %s", inet_ntoa(from->sin_addr));
+		Printf(" %s", addr);
 	else
-		Printf(" %s (%s)", inetname(from->sin_addr),
-		    inet_ntoa(from->sin_addr));
+		Printf(" %s (%s)", inetname(from->sin_addr), addr);
 
 	if (verbose)
 		Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
diff --git a/usr.sbin/traceroute6/Makefile b/usr.sbin/traceroute6/Makefile
index 6ff72d2bf0c..60618a2ad40 100644
--- a/usr.sbin/traceroute6/Makefile
+++ b/usr.sbin/traceroute6/Makefile
@@ -13,12 +13,17 @@
 # A PARTICULAR PURPOSE.
 # $FreeBSD$
 
+TRACEROUTE_DISTDIR?= ${.CURDIR}/../../contrib/traceroute
+.PATH: ${TRACEROUTE_DISTDIR}
+
 PROG=	traceroute6
 MAN=	traceroute6.8
+SRCS=	as.c traceroute6.c
 BINOWN=	root
 BINMODE= 4555
 
 CFLAGS+= -DIPSEC -DUSE_RFC2292BIS -DHAVE_POLL
+CFLAGS+= -I${.CURDIR} -I${TRACEROUTE_DISTDIR} -I.
 
 DPADD=	${LIBIPSEC}
 LDADD=	-lipsec
diff --git a/usr.sbin/traceroute6/traceroute6.8 b/usr.sbin/traceroute6/traceroute6.8
index b6116f0aa1a..884ad6dc339 100644
--- a/usr.sbin/traceroute6/traceroute6.8
+++ b/usr.sbin/traceroute6/traceroute6.8
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 17, 1998
+.Dd August 24, 2009
 .Dt TRACEROUTE6 8
 .Os
 .\"
@@ -40,7 +40,7 @@
 .Sh SYNOPSIS
 .Nm
 .Bk -words
-.Op Fl dIlnNrvU
+.Op Fl adIlnNrvU
 .Ek
 .Bk -words
 .Op Fl f Ar firsthop
@@ -64,6 +64,9 @@
 .Op Fl w Ar waittime
 .Ek
 .Bk -words
+.Op Fl A Ar as_server
+.Ek
+.Bk -words
 .Ar target
 .Op Ar datalen
 .Ek
@@ -84,6 +87,10 @@ after the destination host name.
 .Pp
 Other options are:
 .Bl -tag -width Ds
+.It Fl a
+Turn on AS# lookups for each hop encountered.
+.It Fl A Ar as_server
+Turn on AS# lookups and use the given server instead of the default.
 .It Fl d
 Debug mode.
 .It Fl f Ar firsthop
diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c
index d06502f076f..699af68c1dd 100644
--- a/usr.sbin/traceroute6/traceroute6.c
+++ b/usr.sbin/traceroute6/traceroute6.c
@@ -282,6 +282,8 @@ static const char rcsid[] =
 #include 
 #endif
 
+#include "as.h"
+
 #define DUMMY_PORT 10010
 
 #define	MAXPACKET	65535	/* max ip packet size */
@@ -359,6 +361,9 @@ int waittime = 5;		/* time to wait for response (in seconds) */
 int nflag;			/* print addresses numerically */
 int useproto = IPPROTO_UDP;	/* protocol to use to send packet */
 int lflag;			/* print both numerical address & hostname */
+int as_path;			/* print as numbers for each hop */
+char *as_server = NULL;
+void *asn;
 
 int
 main(argc, argv)
@@ -411,8 +416,15 @@ main(argc, argv)
 
 	seq = 0;
 
-	while ((ch = getopt(argc, argv, "df:g:Ilm:nNp:q:rs:Uvw:")) != -1)
+	while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:Uvw:")) != -1)
 		switch (ch) {
+		case 'a':
+			as_path = 1;
+			break;
+		case 'A':
+			as_path = 1;
+			as_server = optarg;
+			break;
 		case 'd':
 			options |= SO_DEBUG;
 			break;
@@ -867,6 +879,17 @@ main(argc, argv)
 		srcport = ntohs(Src.sin6_port);
 	}
 
+	if (as_path) {
+		asn = as_setup(as_server);
+		if (asn == NULL) {
+			fprintf(stderr,
+			    "traceroute6: as_setup failed, AS# lookups"
+			    " disabled\n");
+			(void)fflush(stderr);
+			as_path = 0;
+		}
+	}
+
 	/*
 	 * Message to users
 	 */
@@ -948,6 +971,8 @@ main(argc, argv)
 			exit(0);
 		}
 	}
+	if (as_path)
+		as_shutdown(asn);
 
 	exit(0);
 }
@@ -1361,6 +1386,8 @@ print(mhdr, cc)
 	if (getnameinfo((struct sockaddr *)from, from->sin6_len,
 	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
 		strlcpy(hbuf, "invalid", sizeof(hbuf));
+	if (as_path)
+		printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
 	if (nflag)
 		printf(" %s", hbuf);
 	else if (lflag)

From 6d2a1e9fa0f20650bec142fffb2b42d8d72ee2e6 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Sun, 13 Sep 2009 17:00:21 +0000
Subject: [PATCH 0226/2592] MFC r196651: AM/PM date format for ja_JP.eucJP and
 ja_JP.SJIS were localized by r193869.  However, ja_JP.UTF-8 wasn't.  So,
 reflect it to ja_JP.UTF-8 as well.

Approved by:	re (kib)
---
 share/timedef/ja_JP.UTF-8.src | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/share/timedef/ja_JP.UTF-8.src b/share/timedef/ja_JP.UTF-8.src
index f6aecf3f15f..9ee39a5286f 100644
--- a/share/timedef/ja_JP.UTF-8.src
+++ b/share/timedef/ja_JP.UTF-8.src
@@ -68,13 +68,11 @@
 #
 # am
 #
-#åˆå‰
-AM
+åˆå‰
 #
 # pm
 #
-#åˆå¾Œ
-PM
+åˆå¾Œ
 #
 # date_fmt
 #

From 285c40cb988ee51721b47eb87b35c7a63d5d5375 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Sun, 13 Sep 2009 17:01:34 +0000
Subject: [PATCH 0227/2592] MFC r196652: Fix the problem that the entry broke
 into two lines with multi-byte AM/PM date format.

Approved by:	re (kib)
---
 usr.bin/w/extern.h  |  2 +-
 usr.bin/w/pr_time.c | 27 +++++++++++++++++++--------
 usr.bin/w/w.c       |  7 ++++---
 3 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/usr.bin/w/extern.h b/usr.bin/w/extern.h
index 070d055b061..f3c0045bd93 100644
--- a/usr.bin/w/extern.h
+++ b/usr.bin/w/extern.h
@@ -38,6 +38,6 @@
 extern	int use_ampm;
 
 struct kinfo_proc;
-void	pr_attime(time_t *, time_t *);
+int	pr_attime(time_t *, time_t *);
 int	pr_idle(time_t);
 int	proc_compare(struct kinfo_proc *, struct kinfo_proc *);
diff --git a/usr.bin/w/pr_time.c b/usr.bin/w/pr_time.c
index 9fe0b11df8b..4576b5eb042 100644
--- a/usr.bin/w/pr_time.c
+++ b/usr.bin/w/pr_time.c
@@ -52,13 +52,14 @@ static const char sccsid[] = "@(#)pr_time.c	8.2 (Berkeley) 4/4/94";
  * pr_attime --
  *	Print the time since the user logged in.
  */
-void
+int
 pr_attime(time_t *started, time_t *now)
 {
-	static char buf[256];
+	static wchar_t buf[256];
 	struct tm tp, tm;
 	time_t diff;
-	char fmt[20];
+	wchar_t *fmt;
+	int len, width, offset = 0;
 
 	tp = *localtime(started);
 	tm = *localtime(now);
@@ -66,7 +67,7 @@ pr_attime(time_t *started, time_t *now)
 
 	/* If more than a week, use day-month-year. */
 	if (diff > 86400 * 7)
-		(void)strcpy(fmt, "%d%b%y");
+		fmt = L"%d%b%y";
 
 	/* If not today, use day-hour-am/pm. */
 	else if (tm.tm_mday != tp.tm_mday ||
@@ -74,16 +75,26 @@ pr_attime(time_t *started, time_t *now)
 		 tm.tm_year != tp.tm_year) {
 	/* The line below does not take DST into consideration */
 	/* else if (*now / 86400 != *started / 86400) { */
-		(void)strcpy(fmt, use_ampm ? "%a%I%p" : "%a%H");
+		fmt = use_ampm ? L"%a%I%p" : L"%a%H";
 	}
 
 	/* Default is hh:mm{am,pm}. */
 	else {
-		(void)strcpy(fmt, use_ampm ? "%l:%M%p" : "%k:%M");
+		fmt = use_ampm ? L"%l:%M%p" : L"%k:%M";
 	}
 
-	(void)strftime(buf, sizeof(buf), fmt, &tp);
-	(void)wprintf(L"%-7.7s", buf);
+	(void)wcsftime(buf, sizeof(buf), fmt, &tp);
+	len = wcslen(buf);
+	width = wcswidth(buf, len);
+	if (len == width)
+		(void)wprintf(L"%-7.7ls", buf);
+	else if (width < 7)
+		(void)wprintf(L"%ls%.*s", buf, 7 - width, "      ");
+	else {
+		(void)wprintf(L"%ls", buf);
+		offset = width - 7;
+	}
+	return (offset);
 }
 
 /*
diff --git a/usr.bin/w/w.c b/usr.bin/w/w.c
index 379e6a43854..10ec7b04bd2 100644
--- a/usr.bin/w/w.c
+++ b/usr.bin/w/w.c
@@ -137,7 +137,7 @@ main(int argc, char *argv[])
 	struct stat *stp;
 	FILE *ut;
 	time_t touched;
-	int ch, i, nentries, nusers, wcmd, longidle, dropgid;
+	int ch, i, nentries, nusers, wcmd, longidle, longattime, dropgid;
 	const char *memf, *nlistf, *p;
 	char *x_suffix;
 	char buf[MAXHOSTNAMELEN], errbuf[_POSIX2_LINE_MAX];
@@ -406,9 +406,10 @@ main(int argc, char *argv[])
 		    ep->utmp.ut_line : ep->utmp.ut_line + 3,
 		    W_DISPHOSTSIZE, W_DISPHOSTSIZE, *p ? p : "-");
 		t = _time_to_time32(ep->utmp.ut_time);
-		pr_attime(&t, &now);
+		longattime = pr_attime(&t, &now);
 		longidle = pr_idle(ep->idle);
-		(void)printf("%.*s\n", argwidth - longidle, ep->args);
+		(void)printf("%.*s\n", argwidth - longidle - longattime,
+		    ep->args);
 	}
 	(void)kvm_close(kd);
 	exit(0);

From 3f6296aa261a1aa86949050eac1d5440437d26bb Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Mon, 14 Sep 2009 11:01:15 +0000
Subject: [PATCH 0228/2592] MFC r196921: Do not decrement pfs_vncache_entries
 for the vnode that was not in the pfs_vncache list.

Approved by:	re (bz)
---
 sys/fs/pseudofs/pseudofs_vncache.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/sys/fs/pseudofs/pseudofs_vncache.c b/sys/fs/pseudofs/pseudofs_vncache.c
index a92a44614bc..035f2c79dd7 100644
--- a/sys/fs/pseudofs/pseudofs_vncache.c
+++ b/sys/fs/pseudofs/pseudofs_vncache.c
@@ -246,11 +246,13 @@ pfs_vncache_free(struct vnode *vp)
 	KASSERT(pvd != NULL, ("pfs_vncache_free(): no vnode data\n"));
 	if (pvd->pvd_next)
 		pvd->pvd_next->pvd_prev = pvd->pvd_prev;
-	if (pvd->pvd_prev)
+	if (pvd->pvd_prev) {
 		pvd->pvd_prev->pvd_next = pvd->pvd_next;
-	else if (pfs_vncache == pvd)
+		--pfs_vncache_entries;
+	} else if (pfs_vncache == pvd) {
 		pfs_vncache = pvd->pvd_next;
-	--pfs_vncache_entries;
+		--pfs_vncache_entries;
+	}
 	mtx_unlock(&pfs_vncache_mutex);
 
 	free(pvd, M_PFSVNCACHE);

From 8760cb9afb3235c15fe803a191c61ab16cd8e5b2 Mon Sep 17 00:00:00 2001
From: Rick Macklem 
Date: Mon, 14 Sep 2009 15:16:17 +0000
Subject: [PATCH 0229/2592] MFC r197048: Add LK_NOWITNESS to the vn_lock()
 calls done on newly created nfs vnodes, since these nodes are not linked into
 the mount queue and, as such, the vn_lock() cannot cause a deadlock so LORs
 are harmless.

Suggested by: kib
Approved by:	re (kensmith), kib (mentor)
---
 sys/fs/nfsclient/nfs_clnode.c | 2 +-
 sys/fs/nfsclient/nfs_clport.c | 2 +-
 sys/nfsclient/nfs_node.c      | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c
index 14dcf81126f..6b2aa7a5f2a 100644
--- a/sys/fs/nfsclient/nfs_clnode.c
+++ b/sys/fs/nfsclient/nfs_clnode.c
@@ -157,7 +157,7 @@ ncl_nget(struct mount *mntp, u_int8_t *fhp, int fhsize, struct nfsnode **npp)
 	    M_NFSFH, M_WAITOK);
 	bcopy(fhp, np->n_fhp->nfh_fh, fhsize);
 	np->n_fhp->nfh_len = fhsize;
-	lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
+	lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
 	error = insmntque(vp, mntp);
 	if (error != 0) {
 		*npp = NULL;
diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index bed607090ef..548ae410055 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -232,7 +232,7 @@ nfscl_nget(struct mount *mntp, struct vnode *dvp, struct nfsfh *nfhp,
 	 */
 	VN_LOCK_AREC(vp);
 	VN_LOCK_ASHARE(vp);
-	lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
+	lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
 	error = insmntque(vp, mntp);
 	if (error != 0) {
 		*npp = NULL;
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c
index f5361277f55..522bc445c19 100644
--- a/sys/nfsclient/nfs_node.c
+++ b/sys/nfsclient/nfs_node.c
@@ -158,7 +158,7 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp, int
 		np->n_fhp = &np->n_fh;
 	bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
 	np->n_fhsize = fhsize;
-	lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
+	lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
 	error = insmntque(vp, mntp);
 	if (error != 0) {
 		*npp = NULL;

From 3c31e305c095d0d5747681dee4edadc674335e5b Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Mon, 14 Sep 2009 16:13:12 +0000
Subject: [PATCH 0230/2592] MFC 197062: Don't malloc a buffer while holding the
 prison0 mutex.  Instead, use a loop where we figure out the hostname length
 under the lock, malloc the buffer with the lock dropped, then recheck the
 length under the lock and loop again if the buffer is now too small.

Approved by:	re (kib)
---
 sys/dev/syscons/daemon/daemon_saver.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/sys/dev/syscons/daemon/daemon_saver.c b/sys/dev/syscons/daemon/daemon_saver.c
index 3009d31b358..816795e5a45 100644
--- a/sys/dev/syscons/daemon/daemon_saver.c
+++ b/sys/dev/syscons/daemon/daemon_saver.c
@@ -351,11 +351,23 @@ daemon_saver(video_adapter_t *adp, int blank)
 static int
 daemon_init(video_adapter_t *adp)
 {
+	size_t hostlen;
 
 	mtx_lock(&prison0.pr_mtx);
-	messagelen = strlen(prison0.pr_hostname) + 3 + strlen(ostype) + 1 + 
-	    strlen(osrelease);
-	message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK);
+	for (;;) {
+		hostlen = strlen(prison0.pr_hostname);
+		mtx_unlock(&prison0.pr_mtx);
+	
+		messagelen = hostlen + 3 + strlen(ostype) + 1 +
+		    strlen(osrelease);
+		message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK);
+		mtx_lock(&prison0.pr_mtx);
+		if (hostlen < strlen(prison0.pr_hostname)) {
+			free(message, M_DEVBUF);
+			continue;
+		}
+		break;
+	}
 	sprintf(message, "%s - %s %s", prison0.pr_hostname, ostype, osrelease);
 	mtx_unlock(&prison0.pr_mtx);
 	blanked = 0;

From 18713ab67238c4b827dc021fa4b87ceaa795e969 Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Tue, 15 Sep 2009 11:13:40 +0000
Subject: [PATCH 0232/2592] MFC
 r196456,r196457,r196458,r196662,r196702,r196703,r196919,r196927,r196928,
 r196943,r196944,r196947,r196950,r196953,r196954,r196965,r196978,r196979,
 r196980,r196982,r196985,r196992,r197131,r197133,r197150,r197151,r197152,
 r197153,r197167,r197172,r197177,r197200,r197201:

r196456:
- Give minclsyspri and maxclsyspri real values (consulted with kmacy).
- Honour 'pri' argument for thread_create().

r196457:
Set priority of vdev_geom threads and zvol threads to PRIBIO.

r196458:
- Hide ZFS kernel threads under zfskern process.
- Use better (shorter) threads names:
	'zvol:worker zvol/tank/vol00' -> 'zvol tank/vol00'
	'vdev:worker da0' -> 'vdev da0'

r196662:
Add missing mountpoint vnode locking.
This fixes panic on assertion with DEBUG_VFS_LOCKS and vfs.usermount=1 when
regular user tries to mount dataset owned by him.

r196702:
Remove empty directory.

r196703:
Backport the 'dirtying dbuf' panic fix from newer ZFS version.

Reported by:	Thomas Backman 

r196919:
bzero() on-stack argument, so mutex_init() won't misinterpret that the
lock is already initialized if we have some garbage on the stack.

PR:	kern/135480
Reported by:	Emil Mikulic 

r196927:
Changing provider size is not really supported by GEOM, but doing so when
provider is closed should be ok.
When administrator requests to change ZVOL size do it immediately if ZVOL
is closed or do it on last ZVOL close.

PR:	kern/136942
Requested by:	Bernard Buri 

r196928:
Teach zdb(8) how to obtain GEOM provider size.

PR:	kern/133134
Reported by:	Philipp Wuensche 

r196943:
- Avoid holding mutex around M_WAITOK allocations.
- Add locking for mnt_opt field.

r196944:
Don't recheck ownership on update mount. This will eliminate LOR between
vfs_busy() and mount mutex. We check ownership in vfs_domount() anyway.

Noticed by:	kib
Reviewed by:	kib

r196947:
Defer thread start until we set priority.

Reviewed by:	kib

r196950:
Fix detection of file system being shared. Now zfs unshare/destroy/rename
command will properly remove exported file systems.

r196953:
When snapshot mount point is busy (for example we are still in it)
we will fail to unmount it, but it won't be removed from the tree,
so in that case there is no need to reinsert it.

Reported by:	trasz

r196954:
If we have to use avl_find(), optimize a bit and use avl_insert() instead of
avl_add() (the latter is actually a wrapper around avl_find() + avl_insert()).
Fix similar case in the code that is currently commented out.

r196965:
Fix reference count leak for a case where snapshot's mount point is updated.

r196978:
Call ZFS_EXIT() after locking the vnode.

r196979:
On FreeBSD we don't have to look for snapshot's mount point,
because fhtovp method is already called with proper mount point.

r196980:
When we automatically mount snapshot we want to return vnode of the mount point
from the lookup and not covered vnode. This is one of the fixes for using .zfs/
over NFS.

r196982:
We don't export individual snapshots, so mnt_export field in snapshot's
mount point is NULL. That's why when we try to access snapshots over NFS
use mnt_export field from the parent file system.

r196985:
Only log successful commands! Without this fix we log even unsuccessful
commands executed by unprivileged users. Action is not really taken, but it is
logged to pool history, which might be confusing.

Reported by:	Denis Ahrens 

r196992:
Implement __assert() for Solaris-specific code. Until now Solaris code was
using Solaris prototype for __assert(), but FreeBSD's implementation.
Both take different arguments, so we were either core-dumping in assert()
or printing garbage.

Reported by:	avg

r197131:
Tighten up the check for race in zfs_zget() - ZTOV(zp) can not only contain
NULL, but also can point to dead vnode, take that into account.

PR:	kern/132068
Reported by:	Edward Fisk <7ogcg7g02@sneakemail.com>, kris
Fix based on patch from:	Jaakko Heinonen 

r197133:
- Protect reclaim with z_teardown_inactive_lock.
- Be prepared for dbuf to disappear in zfs_reclaim_complete() and check if
  z_dbuf field is NULL - this might happen in case of rollback or forced
  unmount between zfs_freebsd_reclaim() and zfs_reclaim_complete().
- On forced unmount wait for all znodes to be destroyed - destruction can be
  done asynchronously via zfs_reclaim_complete().

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

Reported by:	marck
OpenSolaris bug:	6709336

r197151:
Be sure not to overflow struct fid.

r197152:
Extend scope of the z_teardown_lock lock for consistency and "just in case".

r197153:
When zfs.ko is compiled with debug, make sure that znode and vnode point at
each other.

r197167:
Work-around READDIRPLUS problem with .zfs/ and .zfs/snapshot/ directories
by just returning EOPNOTSUPP. This will allow NFS server to fall back to
regular READDIR.
Note that converting inode number to snapshot's vnode is expensive operation.
Snapshots are stored in AVL tree, but based on their names, not inode numbers,
so to convert inode to snapshot vnode we have to interate over all snalshots.
This is not a problem in OpenSolaris, because in their READDIRPLUS
implementation they use VOP_LOOKUP() on d_name, instead of VFS_VGET() on
d_fileno as we do.

PR:	kern/125149
Reported by:	Weldon Godfrey 
Analysis by:	Jaakko Heinonen 

r197172:
Add missing \n.

Reported by:	marck

r197177:
Support both case: when snapshot is already mounted and when it is not yet
mounted.

r197200:
Modify mount(8) to skip MNT_IGNORE file systems by default, just like df(1)
does. This is not POLA violation, because there is no single file system in the
base that use MNT_IGNORE currently, although ZFS snapshots will be mounted with
MNT_IGNORE after next commit.

Reviewed by:	kib

r197201:
- Mount ZFS snapshots with MNT_IGNORE flag, so they are not visible in regular
  df(1) and mount(8) output. This is a bit smilar to OpenSolaris and follows
  ZFS route of not listing snapshots by default with 'zfs list' command.
- Add UPDATING entry to note that ZFS snapshots are no longer visible in
  mount(8) and df(1) output by default.

Reviewed by:	kib

Approved by:	re (bz)
---
 UPDATING                                      |  4 +
 cddl/compat/opensolaris/include/assert.h      | 55 +++++++++++
 cddl/contrib/opensolaris/cmd/zdb/zdb.c        |  8 ++
 cddl/contrib/opensolaris/head/assert.h        | 81 ---------------
 .../lib/libzfs/common/libzfs_mount.c          |  5 +
 sbin/mount/mount.8                            |  6 ++
 sbin/mount/mount.c                            |  3 +
 .../compat/opensolaris/kern/opensolaris_vfs.c | 99 +++++++++++--------
 sys/cddl/compat/opensolaris/sys/mutex.h       |  2 +-
 sys/cddl/compat/opensolaris/sys/proc.h        | 27 +++--
 sys/cddl/compat/opensolaris/sys/vfs.h         |  4 +-
 .../opensolaris/uts/common/fs/zfs/dmu_send.c  |  7 +-
 .../opensolaris/uts/common/fs/zfs/dnode.c     | 16 +--
 .../uts/common/fs/zfs/dnode_sync.c            | 36 +++++--
 .../uts/common/fs/zfs/dsl_dataset.c           |  1 +
 .../opensolaris/uts/common/fs/zfs/sys/dnode.h |  3 +-
 .../uts/common/fs/zfs/sys/zfs_znode.h         | 19 ++++
 .../opensolaris/uts/common/fs/zfs/vdev_geom.c | 10 +-
 .../opensolaris/uts/common/fs/zfs/zap_micro.c | 21 +++-
 .../uts/common/fs/zfs/zfs_ctldir.c            | 45 ++++++---
 .../opensolaris/uts/common/fs/zfs/zfs_ioctl.c |  7 +-
 .../uts/common/fs/zfs/zfs_vfsops.c            | 84 ++++++++++++++--
 .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 29 ++++--
 .../opensolaris/uts/common/fs/zfs/zfs_znode.c | 16 ++-
 .../opensolaris/uts/common/fs/zfs/zvol.c      | 30 ++++--
 .../opensolaris/uts/common/sys/callb.h        |  2 -
 26 files changed, 411 insertions(+), 209 deletions(-)
 create mode 100644 cddl/compat/opensolaris/include/assert.h
 delete mode 100644 cddl/contrib/opensolaris/head/assert.h

diff --git a/UPDATING b/UPDATING
index 6dab13884fe..d418f2dc3a4 100644
--- a/UPDATING
+++ b/UPDATING
@@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
 	to maximize performance.  (To disable malloc debugging, run
 	ln -s aj /etc/malloc.conf.)
 
+20090915:
+	ZFS snapshots are now mounted with MNT_IGNORE flag. Use -v option for
+	mount(8) and -a option for df(1) to see them.
+
 20090813:
 	Remove the option STOP_NMI.  The default action is now to use NMI
 	only for KDB via the newly introduced function stop_cpus_hard()
diff --git a/cddl/compat/opensolaris/include/assert.h b/cddl/compat/opensolaris/include/assert.h
new file mode 100644
index 00000000000..353f0c9fd81
--- /dev/null
+++ b/cddl/compat/opensolaris/include/assert.h
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2009 Pawel Jakub Dawidek 
+ * 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 AUTHORS 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 AUTHORS 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$
+ */
+
+#undef assert
+#undef _assert
+
+#ifdef NDEBUG
+#define	assert(e)	((void)0)
+#define	_assert(e)	((void)0)
+#else
+#define	_assert(e)	assert(e)
+
+#define	assert(e)	((e) ? (void)0 : __assert(#e, __FILE__, __LINE__))
+#endif /* NDEBUG */
+
+#ifndef _ASSERT_H_
+#define _ASSERT_H_
+#include 
+#include 
+
+static __inline void
+__assert(const char *expr, const char *file, int line)
+{
+
+	(void)fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n",
+	    expr, file, line);
+	abort();
+	/* NOTREACHED */
+}
+#endif /* !_ASSERT_H_ */
diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
index 16b2787704a..9e1e1063544 100644
--- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
@@ -1322,6 +1322,14 @@ dump_label(const char *dev)
 		exit(1);
 	}
 
+	if (S_ISCHR(statbuf.st_mode)) {
+		if (ioctl(fd, DIOCGMEDIASIZE, &statbuf.st_size) == -1) {
+			(void) printf("failed to get size of '%s': %s\n", dev,
+			    strerror(errno));
+			exit(1);
+		}
+	}
+
 	psize = statbuf.st_size;
 	psize = P2ALIGN(psize, (uint64_t)sizeof (vdev_label_t));
 
diff --git a/cddl/contrib/opensolaris/head/assert.h b/cddl/contrib/opensolaris/head/assert.h
deleted file mode 100644
index 394820a2990..00000000000
--- a/cddl/contrib/opensolaris/head/assert.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*	Copyright (c) 1988 AT&T	*/
-/*	  All Rights Reserved  	*/
-
-
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef	_ASSERT_H
-#define	_ASSERT_H
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.6.1.4 */
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-#if defined(__STDC__)
-#if __STDC_VERSION__ - 0 >= 199901L
-extern void __assert(const char *, const char *, int);
-#else
-extern void __assert(const char *, const char *, int);
-#endif /* __STDC_VERSION__ - 0 >= 199901L */
-#else
-extern void _assert();
-#endif
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* _ASSERT_H */
-
-/*
- * Note that the ANSI C Standard requires all headers to be idempotent except
- *  which is explicitly required not to be idempotent (section 4.1.2).
- * Therefore, it is by intent that the header guards (#ifndef _ASSERT_H) do
- * not span this entire file.
- */
-
-#undef	assert
-
-#ifdef	NDEBUG
-
-#define	assert(EX) ((void)0)
-
-#else
-
-#if defined(__STDC__)
-#if __STDC_VERSION__ - 0 >= 199901L
-#define	assert(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
-#else
-#define	assert(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
-#endif /* __STDC_VERSION__ - 0 >= 199901L */
-#else
-#define	assert(EX) (void)((EX) || (_assert("EX", __FILE__, __LINE__), 0))
-#endif	/* __STDC__ */
-
-#endif	/* NDEBUG */
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
index 84a8a576f99..76ab7ac0d35 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
@@ -172,6 +172,7 @@ is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto)
 
 		*tab = '\0';
 		if (strcmp(buf, mountpoint) == 0) {
+#if defined(sun)
 			/*
 			 * the protocol field is the third field
 			 * skip over second field
@@ -194,6 +195,10 @@ is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto)
 					return (0);
 				}
 			}
+#else
+			if (proto == PROTO_NFS)
+				return (SHARED_NFS);
+#endif
 		}
 	}
 
diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8
index 7635d746002..104b248f270 100644
--- a/sbin/mount/mount.8
+++ b/sbin/mount/mount.8
@@ -469,6 +469,12 @@ or
 option.
 .It Fl v
 Verbose mode.
+If the
+.Fl v
+is used alone, show all file systems, including those that were mounted with the
+.Dv MNT_IGNORE
+flag and show additional information about each file system (including fsid
+when run by root).
 .It Fl w
 The file system object is to be read and write.
 .El
diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c
index 40a3e96e9a9..0bd553377bb 100644
--- a/sbin/mount/mount.c
+++ b/sbin/mount/mount.c
@@ -348,6 +348,9 @@ main(int argc, char *argv[])
 				if (checkvfsname(mntbuf[i].f_fstypename,
 				    vfslist))
 					continue;
+				if (!verbose &&
+				    (mntbuf[i].f_flags & MNT_IGNORE) != 0)
+					continue;
 				prmount(&mntbuf[i]);
 			}
 		}
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
index a716b6395fb..8538b540278 100644
--- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
+++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
@@ -45,20 +45,33 @@ vfs_setmntopt(vfs_t *vfsp, const char *name, const char *arg,
 {
 	struct vfsopt *opt;
 	size_t namesize;
+	int locked;
+
+	if (!(locked = mtx_owned(MNT_MTX(vfsp))))
+		MNT_ILOCK(vfsp);
 
 	if (vfsp->mnt_opt == NULL) {
-		vfsp->mnt_opt = malloc(sizeof(*vfsp->mnt_opt), M_MOUNT, M_WAITOK);
-		TAILQ_INIT(vfsp->mnt_opt);
+		void *opts;
+
+		MNT_IUNLOCK(vfsp);
+		opts = malloc(sizeof(*vfsp->mnt_opt), M_MOUNT, M_WAITOK);
+		MNT_ILOCK(vfsp);
+		if (vfsp->mnt_opt == NULL) {
+			vfsp->mnt_opt = opts;
+			TAILQ_INIT(vfsp->mnt_opt);
+		} else {
+			free(opts, M_MOUNT);
+		}
 	}
 
-	opt = malloc(sizeof(*opt), M_MOUNT, M_WAITOK);
+	MNT_IUNLOCK(vfsp);
 
+	opt = malloc(sizeof(*opt), M_MOUNT, M_WAITOK);
 	namesize = strlen(name) + 1;
 	opt->name = malloc(namesize, M_MOUNT, M_WAITOK);
 	strlcpy(opt->name, name, namesize);
 	opt->pos = -1;
 	opt->seen = 1;
-
 	if (arg == NULL) {
 		opt->value = NULL;
 		opt->len = 0;
@@ -67,16 +80,23 @@ vfs_setmntopt(vfs_t *vfsp, const char *name, const char *arg,
 		opt->value = malloc(opt->len, M_MOUNT, M_WAITOK);
 		bcopy(arg, opt->value, opt->len);
 	}
-	/* TODO: Locking. */
+
+	MNT_ILOCK(vfsp);
 	TAILQ_INSERT_TAIL(vfsp->mnt_opt, opt, link);
+	if (!locked)
+		MNT_IUNLOCK(vfsp);
 }
 
 void
 vfs_clearmntopt(vfs_t *vfsp, const char *name)
 {
+	int locked;
 
-	/* TODO: Locking. */
+	if (!(locked = mtx_owned(MNT_MTX(vfsp))))
+		MNT_ILOCK(vfsp);
 	vfs_deleteopt(vfsp->mnt_opt, name);
+	if (!locked)
+		MNT_IUNLOCK(vfsp);
 }
 
 int
@@ -92,12 +112,13 @@ vfs_optionisset(const vfs_t *vfsp, const char *opt, char **argp)
 }
 
 int
-domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
+mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath,
     char *fspec, int fsflags)
 {
 	struct mount *mp;
 	struct vfsconf *vfsp;
 	struct ucred *cr;
+	vnode_t *vp;
 	int error;
 
 	/*
@@ -112,23 +133,28 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
 	if (vfsp == NULL)
 		return (ENODEV);
 
+	vp = *vpp;
 	if (vp->v_type != VDIR)
 		return (ENOTDIR);
+	/*
+	 * We need vnode lock to protect v_mountedhere and vnode interlock
+	 * to protect v_iflag.
+	 */
+	vn_lock(vp, LK_SHARED | LK_RETRY);
 	VI_LOCK(vp);
-	if ((vp->v_iflag & VI_MOUNT) != 0 ||
-	    vp->v_mountedhere != NULL) {
+	if ((vp->v_iflag & VI_MOUNT) != 0 || vp->v_mountedhere != NULL) {
 		VI_UNLOCK(vp);
+		VOP_UNLOCK(vp, 0);
 		return (EBUSY);
 	}
 	vp->v_iflag |= VI_MOUNT;
 	VI_UNLOCK(vp);
+	VOP_UNLOCK(vp, 0);
 
 	/*
 	 * Allocate and initialize the filesystem.
 	 */
-	vn_lock(vp, LK_SHARED | LK_RETRY);
 	mp = vfs_mount_alloc(vp, vfsp, fspath, td->td_ucred);
-	VOP_UNLOCK(vp, 0);
 
 	mp->mnt_optnew = NULL;
 	vfs_setmntopt(mp, "from", fspec, 0);
@@ -138,10 +164,17 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
 	/*
 	 * Set the mount level flags.
 	 */
-	if (fsflags & MNT_RDONLY)
-		mp->mnt_flag |= MNT_RDONLY;
-	mp->mnt_flag &=~ MNT_UPDATEMASK;
+	mp->mnt_flag &= ~MNT_UPDATEMASK;
 	mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE | MNT_ROOTFS);
+	/*
+	 * Snapshots are always read-only.
+	 */
+	mp->mnt_flag |= MNT_RDONLY;
+	/*
+	 * We don't want snapshots to be visible in regular
+	 * mount(8) and df(1) output.
+	 */
+	mp->mnt_flag |= MNT_IGNORE;
 	/*
 	 * Unprivileged user can trigger mounting a snapshot, but we don't want
 	 * him to unmount it, so we switch to privileged of original mount.
@@ -149,11 +182,6 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
 	crfree(mp->mnt_cred);
 	mp->mnt_cred = crdup(vp->v_mount->mnt_cred);
 	mp->mnt_stat.f_owner = mp->mnt_cred->cr_uid;
-	/*
-	 * Mount the filesystem.
-	 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
-	 * get.  No freeing of cn_pnbuf.
-	 */
 	/*
 	 * XXX: This is evil, but we can't mount a snapshot as a regular user.
 	 * XXX: Is is safe when snapshot is mounted from within a jail?
@@ -163,7 +191,7 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
 	error = VFS_MOUNT(mp);
 	td->td_ucred = cr;
 
-	if (!error) {
+	if (error == 0) {
 		if (mp->mnt_opt != NULL)
 			vfs_freeopts(mp->mnt_opt);
 		mp->mnt_opt = mp->mnt_optnew;
@@ -175,42 +203,33 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
 	*/
 	mp->mnt_optnew = NULL;
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-	/*
-	 * Put the new filesystem on the mount list after root.
-	 */
 #ifdef FREEBSD_NAMECACHE
 	cache_purge(vp);
 #endif
-	if (!error) {
+	VI_LOCK(vp);
+	vp->v_iflag &= ~VI_MOUNT;
+	VI_UNLOCK(vp);
+	if (error == 0) {
 		vnode_t *mvp;
 
-		VI_LOCK(vp);
-		vp->v_iflag &= ~VI_MOUNT;
-		VI_UNLOCK(vp);
 		vp->v_mountedhere = mp;
+		/*
+		 * Put the new filesystem on the mount list.
+		 */
 		mtx_lock(&mountlist_mtx);
 		TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
 		mtx_unlock(&mountlist_mtx);
 		vfs_event_signal(NULL, VQ_MOUNT, 0);
 		if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp))
 			panic("mount: lost mount");
-		mountcheckdirs(vp, mvp);
-		vput(mvp);
-		VOP_UNLOCK(vp, 0);
-		if ((mp->mnt_flag & MNT_RDONLY) == 0)
-			error = vfs_allocate_syncvnode(mp);
+		vput(vp);
 		vfs_unbusy(mp);
-		if (error)
-			vrele(vp);
-		else
-			vfs_mountedfrom(mp, fspec);
+		*vpp = mvp;
 	} else {
-		VI_LOCK(vp);
-		vp->v_iflag &= ~VI_MOUNT;
-		VI_UNLOCK(vp);
-		VOP_UNLOCK(vp, 0);
+		vput(vp);
 		vfs_unbusy(mp);
 		vfs_mount_destroy(mp);
+		*vpp = NULL;
 	}
 	return (error);
 }
diff --git a/sys/cddl/compat/opensolaris/sys/mutex.h b/sys/cddl/compat/opensolaris/sys/mutex.h
index 8756cd0534f..f6858a7b161 100644
--- a/sys/cddl/compat/opensolaris/sys/mutex.h
+++ b/sys/cddl/compat/opensolaris/sys/mutex.h
@@ -32,9 +32,9 @@
 #ifdef _KERNEL
 
 #include 
-#include 
 #include 
 #include_next 
+#include 
 #include 
 
 typedef enum {
diff --git a/sys/cddl/compat/opensolaris/sys/proc.h b/sys/cddl/compat/opensolaris/sys/proc.h
index 73fbcdadf1d..e0b7bc5758e 100644
--- a/sys/cddl/compat/opensolaris/sys/proc.h
+++ b/sys/cddl/compat/opensolaris/sys/proc.h
@@ -34,13 +34,17 @@
 #include_next 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 #include 
 
 #ifdef _KERNEL
 
 #define	CPU		curcpu
-#define	minclsyspri	0
-#define	maxclsyspri	0
+#define	minclsyspri	PRIBIO
+#define	maxclsyspri	PVM
 #define	max_ncpus	mp_ncpus
 #define	boot_max_ncpus	mp_ncpus
 
@@ -54,11 +58,13 @@ typedef	struct thread	kthread_t;
 typedef struct thread	*kthread_id_t;
 typedef struct proc	proc_t;
 
+extern struct proc *zfsproc;
+
 static __inline kthread_t *
 thread_create(caddr_t stk, size_t stksize, void (*proc)(void *), void *arg,
     size_t len, proc_t *pp, int state, pri_t pri)
 {
-	proc_t *p;
+	kthread_t *td = NULL;
 	int error;
 
 	/*
@@ -67,13 +73,20 @@ thread_create(caddr_t stk, size_t stksize, void (*proc)(void *), void *arg,
 	ASSERT(stk == NULL);
 	ASSERT(len == 0);
 	ASSERT(state == TS_RUN);
+	ASSERT(pp == &p0);
 
-	error = kproc_create(proc, arg, &p, 0, stksize / PAGE_SIZE,
-	    "solthread %p", proc);
-	return (error == 0 ? FIRST_THREAD_IN_PROC(p) : NULL);
+	error = kproc_kthread_add(proc, arg, &zfsproc, &td, RFSTOPPED,
+	    stksize / PAGE_SIZE, "zfskern", "solthread %p", proc);
+	if (error == 0) {
+		thread_lock(td);
+		sched_prio(td, pri);
+		sched_add(td, SRQ_BORING);
+		thread_unlock(td);
+	}
+	return (td);
 }
 
-#define	thread_exit()	kproc_exit(0)
+#define	thread_exit()	kthread_exit()
 
 #endif	/* _KERNEL */
 
diff --git a/sys/cddl/compat/opensolaris/sys/vfs.h b/sys/cddl/compat/opensolaris/sys/vfs.h
index be3e3cfe5fc..d3a7e38da18 100644
--- a/sys/cddl/compat/opensolaris/sys/vfs.h
+++ b/sys/cddl/compat/opensolaris/sys/vfs.h
@@ -110,8 +110,8 @@ void vfs_setmntopt(vfs_t *vfsp, const char *name, const char *arg,
     int flags __unused);
 void vfs_clearmntopt(vfs_t *vfsp, const char *name);
 int vfs_optionisset(const vfs_t *vfsp, const char *opt, char **argp);
-int domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
-    char *fspec, int fsflags);
+int mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype,
+    char *fspath, char *fspec, int fsflags);
 
 typedef	uint64_t	vfs_feature_t;
 
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
index 1294581a713..15bb65d6a44 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -864,10 +864,11 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 		/* currently allocated, want to be allocated */
 		dmu_tx_hold_bonus(tx, drro->drr_object);
 		/*
-		 * We may change blocksize, so need to
-		 * hold_write
+		 * We may change blocksize and delete old content,
+		 * so need to hold_write and hold_free.
 		 */
 		dmu_tx_hold_write(tx, drro->drr_object, 0, 1);
+		dmu_tx_hold_free(tx, drro->drr_object, 0, DMU_OBJECT_END);
 		err = dmu_tx_assign(tx, TXG_WAIT);
 		if (err) {
 			dmu_tx_abort(tx);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
index 5adbc3c0ff5..604d52d8bb5 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
@@ -415,7 +415,7 @@ void
 dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
     dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
 {
-	int i, old_nblkptr;
+	int i, nblkptr;
 	dmu_buf_impl_t *db = NULL;
 
 	ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
@@ -445,6 +445,8 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
 		dnode_free_range(dn, 0, -1ULL, tx);
 	}
 
+	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
+
 	/* change blocksize */
 	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
 	if (blocksize != dn->dn_datablksz &&
@@ -457,6 +459,8 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
 	dnode_setdirty(dn, tx);
 	dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
 	dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
+	if (dn->dn_nblkptr != nblkptr)
+		dn->dn_next_nblkptr[tx->tx_txg&TXG_MASK] = nblkptr;
 	rw_exit(&dn->dn_struct_rwlock);
 	if (db)
 		dbuf_rele(db, FTAG);
@@ -466,19 +470,15 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
 
 	/* change bonus size and type */
 	mutex_enter(&dn->dn_mtx);
-	old_nblkptr = dn->dn_nblkptr;
 	dn->dn_bonustype = bonustype;
 	dn->dn_bonuslen = bonuslen;
-	dn->dn_nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
+	dn->dn_nblkptr = nblkptr;
 	dn->dn_checksum = ZIO_CHECKSUM_INHERIT;
 	dn->dn_compress = ZIO_COMPRESS_INHERIT;
 	ASSERT3U(dn->dn_nblkptr, <=, DN_MAX_NBLKPTR);
 
-	/* XXX - for now, we can't make nblkptr smaller */
-	ASSERT3U(dn->dn_nblkptr, >=, old_nblkptr);
-
-	/* fix up the bonus db_size if dn_nblkptr has changed */
-	if (dn->dn_bonus && dn->dn_bonuslen != old_nblkptr) {
+	/* fix up the bonus db_size */
+	if (dn->dn_bonus) {
 		dn->dn_bonus->db.db_size =
 		    DN_MAX_BONUSLEN - (dn->dn_nblkptr-1) * sizeof (blkptr_t);
 		ASSERT(dn->dn_bonuslen <= dn->dn_bonus->db.db_size);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
index a46d4e70abc..1b729e391a8 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include 
 #include 
 #include 
@@ -534,18 +532,12 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx)
 			/* XXX shouldn't the phys already be zeroed? */
 			bzero(dnp, DNODE_CORE_SIZE);
 			dnp->dn_nlevels = 1;
+			dnp->dn_nblkptr = dn->dn_nblkptr;
 		}
 
-		if (dn->dn_nblkptr > dnp->dn_nblkptr) {
-			/* zero the new blkptrs we are gaining */
-			bzero(dnp->dn_blkptr + dnp->dn_nblkptr,
-			    sizeof (blkptr_t) *
-			    (dn->dn_nblkptr - dnp->dn_nblkptr));
-		}
 		dnp->dn_type = dn->dn_type;
 		dnp->dn_bonustype = dn->dn_bonustype;
 		dnp->dn_bonuslen = dn->dn_bonuslen;
-		dnp->dn_nblkptr = dn->dn_nblkptr;
 	}
 
 	ASSERT(dnp->dn_nlevels > 1 ||
@@ -605,6 +597,30 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx)
 		return;
 	}
 
+	if (dn->dn_next_nblkptr[txgoff]) {
+		/* this should only happen on a realloc */
+		ASSERT(dn->dn_allocated_txg == tx->tx_txg);
+		if (dn->dn_next_nblkptr[txgoff] > dnp->dn_nblkptr) {
+			/* zero the new blkptrs we are gaining */
+			bzero(dnp->dn_blkptr + dnp->dn_nblkptr,
+			    sizeof (blkptr_t) *
+			    (dn->dn_next_nblkptr[txgoff] - dnp->dn_nblkptr));
+#ifdef ZFS_DEBUG
+		} else {
+			int i;
+			ASSERT(dn->dn_next_nblkptr[txgoff] < dnp->dn_nblkptr);
+			/* the blkptrs we are losing better be unallocated */
+			for (i = dn->dn_next_nblkptr[txgoff];
+			    i < dnp->dn_nblkptr; i++)
+				ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[i]));
+#endif
+		}
+		mutex_enter(&dn->dn_mtx);
+		dnp->dn_nblkptr = dn->dn_next_nblkptr[txgoff];
+		dn->dn_next_nblkptr[txgoff] = 0;
+		mutex_exit(&dn->dn_mtx);
+	}
+
 	if (dn->dn_next_nlevels[txgoff]) {
 		dnode_increase_indirection(dn, tx);
 		dn->dn_next_nlevels[txgoff] = 0;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
index 20d8ec85cc9..a27150b093b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
@@ -1419,6 +1419,7 @@ dsl_dataset_drain_refs(dsl_dataset_t *ds, void *tag)
 {
 	struct refsarg arg;
 
+	bzero(&arg, sizeof(arg));
 	mutex_init(&arg.lock, NULL, MUTEX_DEFAULT, NULL);
 	cv_init(&arg.cv, NULL, CV_DEFAULT, NULL);
 	arg.gone = FALSE;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h
index c79ff48a60c..be9e5690832 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -160,6 +160,7 @@ typedef struct dnode {
 	uint16_t dn_datablkszsec;	/* in 512b sectors */
 	uint32_t dn_datablksz;		/* in bytes */
 	uint64_t dn_maxblkid;
+	uint8_t dn_next_nblkptr[TXG_SIZE];
 	uint8_t dn_next_nlevels[TXG_SIZE];
 	uint8_t dn_next_indblkshift[TXG_SIZE];
 	uint16_t dn_next_bonuslen[TXG_SIZE];
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
index c05ee20b665..bb1c9da6be9 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
@@ -231,8 +231,27 @@ typedef struct znode {
 /*
  * Convert between znode pointers and vnode pointers
  */
+#ifdef DEBUG
+static __inline vnode_t *
+ZTOV(znode_t *zp)
+{
+	vnode_t *vp = zp->z_vnode;
+
+	ASSERT(vp == NULL || vp->v_data == NULL || vp->v_data == zp);
+	return (vp);
+}
+static __inline znode_t *
+VTOZ(vnode_t *vp)
+{
+	znode_t *zp = (znode_t *)vp->v_data;
+
+	ASSERT(zp == NULL || zp->z_vnode == NULL || zp->z_vnode == vp);
+	return (zp);
+}
+#else
 #define	ZTOV(ZP)	((ZP)->z_vnode)
 #define	VTOZ(VP)	((znode_t *)(VP)->v_data)
+#endif
 
 /*
  * ZFS_ENTER() is called on entry to each ZFS vnode and vfs operation.
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 54ba8bd7105..b4bec95f5fb 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
@@ -194,6 +194,10 @@ vdev_geom_worker(void *arg)
 	zio_t *zio;
 	struct bio *bp;
 
+	thread_lock(curthread);
+	sched_prio(curthread, PRIBIO);
+	thread_unlock(curthread);
+
 	ctx = arg;
 	for (;;) {
 		mtx_lock(&ctx->gc_queue_mtx);
@@ -203,7 +207,7 @@ vdev_geom_worker(void *arg)
 				ctx->gc_state = 2;
 				wakeup_one(&ctx->gc_state);
 				mtx_unlock(&ctx->gc_queue_mtx);
-				kproc_exit(0);
+				kthread_exit();
 			}
 			msleep(&ctx->gc_queue, &ctx->gc_queue_mtx,
 			    PRIBIO | PDROP, "vgeom:io", 0);
@@ -530,8 +534,8 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
 	vd->vdev_tsd = ctx;
 	pp = cp->provider;
 
-	kproc_create(vdev_geom_worker, ctx, NULL, 0, 0, "vdev:worker %s",
-	    pp->name);
+	kproc_kthread_add(vdev_geom_worker, ctx, &zfsproc, NULL, 0, 0,
+	    "zfskern", "vdev %s", pp->name);
 
 	/*
 	 * Determine the actual size of the device.
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
index 75b43a6f88d..10d73862da4 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
@@ -181,10 +181,11 @@ mze_compare(const void *arg1, const void *arg2)
 	return (0);
 }
 
-static void
+static int
 mze_insert(zap_t *zap, int chunkid, uint64_t hash, mzap_ent_phys_t *mzep)
 {
 	mzap_ent_t *mze;
+	avl_index_t idx;
 
 	ASSERT(zap->zap_ismicro);
 	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
@@ -194,7 +195,12 @@ mze_insert(zap_t *zap, int chunkid, uint64_t hash, mzap_ent_phys_t *mzep)
 	mze->mze_chunkid = chunkid;
 	mze->mze_hash = hash;
 	mze->mze_phys = *mzep;
-	avl_add(&zap->zap_m.zap_avl, mze);
+	if (avl_find(&zap->zap_m.zap_avl, mze, &idx) != NULL) {
+		kmem_free(mze, sizeof (mzap_ent_t));
+		return (EEXIST);
+	}
+	avl_insert(&zap->zap_m.zap_avl, mze, idx);
+	return (0);
 }
 
 static mzap_ent_t *
@@ -329,10 +335,15 @@ mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
 			if (mze->mze_name[0]) {
 				zap_name_t *zn;
 
-				zap->zap_m.zap_num_entries++;
 				zn = zap_name_alloc(zap, mze->mze_name,
 				    MT_EXACT);
-				mze_insert(zap, i, zn->zn_hash, mze);
+				if (mze_insert(zap, i, zn->zn_hash, mze) == 0)
+					zap->zap_m.zap_num_entries++;
+				else {
+					printf("ZFS WARNING: Duplicated ZAP "
+					    "entry detected (%s).\n",
+					    mze->mze_name);
+				}
 				zap_name_free(zn);
 			}
 		}
@@ -771,7 +782,7 @@ again:
 			if (zap->zap_m.zap_alloc_next ==
 			    zap->zap_m.zap_num_chunks)
 				zap->zap_m.zap_alloc_next = 0;
-			mze_insert(zap, i, zn->zn_hash, mze);
+			VERIFY(0 == mze_insert(zap, i, zn->zn_hash, mze));
 			return;
 		}
 	}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
index cf99d68e8bb..0b034f627ce 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
@@ -669,9 +669,12 @@ zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr,
 	if (sep) {
 		avl_remove(&sdp->sd_snaps, sep);
 		err = zfsctl_unmount_snap(sep, MS_FORCE, cr);
-		if (err)
-			avl_add(&sdp->sd_snaps, sep);
-		else
+		if (err) {
+			avl_index_t where;
+
+			if (avl_find(&sdp->sd_snaps, sep, &where) == NULL)
+				avl_insert(&sdp->sd_snaps, sep, where);
+		} else
 			err = dmu_objset_destroy(snapname);
 	} else {
 		err = ENOENT;
@@ -877,20 +880,20 @@ domount:
 	mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP);
 	(void) snprintf(mountpoint, mountpoint_len, "%s/.zfs/snapshot/%s",
 	    dvp->v_vfsp->mnt_stat.f_mntonname, nm);
-	err = domount(curthread, *vpp, "zfs", mountpoint, snapname, 0);
+	err = mount_snapshot(curthread, vpp, "zfs", mountpoint, snapname, 0);
 	kmem_free(mountpoint, mountpoint_len);
-	/* FreeBSD: This line was moved from below to avoid a lock recursion. */
-	if (err == 0)
-		vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
-	mutex_exit(&sdp->sd_lock);
-	/*
-	 * If we had an error, drop our hold on the vnode and
-	 * zfsctl_snapshot_inactive() will clean up.
-	 */
-	if (err) {
-		VN_RELE(*vpp);
-		*vpp = NULL;
+	if (err == 0) {
+		/*
+		 * Fix up the root vnode mounted on .zfs/snapshot/.
+		 *
+		 * This is where we lie about our v_vfsp in order to
+		 * make .zfs/snapshot/ accessible over NFS
+		 * without requiring manual mounts of .
+		 */
+		ASSERT(VTOZ(*vpp)->z_zfsvfs != zfsvfs);
+		VTOZ(*vpp)->z_zfsvfs->z_parent = zfsvfs;
 	}
+	mutex_exit(&sdp->sd_lock);
 	ZFS_EXIT(zfsvfs);
 	return (err);
 }
@@ -1344,7 +1347,17 @@ zfsctl_umount_snapshots(vfs_t *vfsp, int fflags, cred_t *cr)
 		if (vn_ismntpt(sep->se_root)) {
 			error = zfsctl_unmount_snap(sep, fflags, cr);
 			if (error) {
-				avl_add(&sdp->sd_snaps, sep);
+				avl_index_t where;
+
+				/*
+				 * Before reinserting snapshot to the tree,
+				 * check if it was actually removed. For example
+				 * when snapshot mount point is busy, we will
+				 * have an error here, but there will be no need
+				 * to reinsert snapshot.
+				 */
+				if (avl_find(&sdp->sd_snaps, sep, &where) == NULL)
+					avl_insert(&sdp->sd_snaps, sep, where);
 				break;
 			}
 		}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index ded407e37f7..e25f5494e68 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -3021,8 +3021,10 @@ zfsdev_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
 	if (error == 0)
 		error = zfs_ioc_vec[vec].zvec_func(zc);
 
-	if (zfs_ioc_vec[vec].zvec_his_log == B_TRUE)
-		zfs_log_history(zc);
+	if (error == 0) {
+		if (zfs_ioc_vec[vec].zvec_his_log == B_TRUE)
+			zfs_log_history(zc);
+	}
 
 	return (error);
 }
@@ -3057,6 +3059,7 @@ zfsdev_fini(void)
 }
 
 static struct root_hold_token *zfs_root_token;
+struct proc *zfsproc;
 
 uint_t zfs_fsyncer_key;
 extern uint_t rrw_tsd_key;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 16c6683b7af..34f8378c19f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -97,6 +97,8 @@ static int zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp);
 static int zfs_statfs(vfs_t *vfsp, struct statfs *statp);
 static int zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp);
 static int zfs_sync(vfs_t *vfsp, int waitfor);
+static int zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, int *extflagsp,
+    struct ucred **credanonp, int *numsecflavors, int **secflavors);
 static int zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp);
 static void zfs_objset_close(zfsvfs_t *zfsvfs);
 static void zfs_freevfs(vfs_t *vfsp);
@@ -108,6 +110,7 @@ static struct vfsops zfs_vfsops = {
 	.vfs_statfs =		zfs_statfs,
 	.vfs_vget =		zfs_vget,
 	.vfs_sync =		zfs_sync,
+	.vfs_checkexp =		zfs_checkexp,
 	.vfs_fhtovp =		zfs_fhtovp,
 };
 
@@ -336,6 +339,13 @@ zfs_register_callbacks(vfs_t *vfsp)
 	ASSERT(zfsvfs);
 	os = zfsvfs->z_os;
 
+	/*
+	 * This function can be called for a snapshot when we update snapshot's
+	 * mount point, which isn't really supported.
+	 */
+	if (dmu_objset_is_snapshot(os))
+		return (EOPNOTSUPP);
+
 	/*
 	 * The act of registering our callbacks will destroy any mount
 	 * options we may have.  In order to enable temporary overrides
@@ -719,7 +729,10 @@ zfs_mount(vfs_t *vfsp)
 	error = secpolicy_fs_mount(cr, mvp, vfsp);
 	if (error) {
 		error = dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr);
-		if (error == 0) {
+		if (error != 0)
+			goto out;
+
+		if (!(vfsp->vfs_flag & MS_REMOUNT)) {
 			vattr_t		vattr;
 
 			/*
@@ -729,7 +742,9 @@ zfs_mount(vfs_t *vfsp)
 
 			vattr.va_mask = AT_UID;
 
+			vn_lock(mvp, LK_SHARED | LK_RETRY);
 			if (error = VOP_GETATTR(mvp, &vattr, cr)) {
+				VOP_UNLOCK(mvp, 0);
 				goto out;
 			}
 
@@ -741,18 +756,19 @@ zfs_mount(vfs_t *vfsp)
 			}
 #else
 			if (error = secpolicy_vnode_owner(mvp, cr, vattr.va_uid)) {
+				VOP_UNLOCK(mvp, 0);
 				goto out;
 			}
 
 			if (error = VOP_ACCESS(mvp, VWRITE, cr, td)) {
+				VOP_UNLOCK(mvp, 0);
 				goto out;
 			}
+			VOP_UNLOCK(mvp, 0);
 #endif
-
-			secpolicy_fs_mount_clearopts(cr, vfsp);
-		} else {
-			goto out;
 		}
+
+		secpolicy_fs_mount_clearopts(cr, vfsp);
 	}
 
 	/*
@@ -931,6 +947,18 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
 		zfsvfs->z_unmounted = B_TRUE;
 		rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
 		rw_exit(&zfsvfs->z_teardown_inactive_lock);
+
+#ifdef __FreeBSD__
+		/*
+		 * Some znodes might not be fully reclaimed, wait for them.
+		 */
+		mutex_enter(&zfsvfs->z_znodes_lock);
+		while (list_head(&zfsvfs->z_all_znodes) != NULL) {
+			msleep(zfsvfs, &zfsvfs->z_znodes_lock, 0,
+			    "zteardown", 0);
+		}
+		mutex_exit(&zfsvfs->z_znodes_lock);
+#endif
 	}
 
 	/*
@@ -1086,6 +1114,20 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp)
 	znode_t		*zp;
 	int 		err;
 
+	/*
+	 * XXXPJD: zfs_zget() can't operate on virtual entires like .zfs/ or
+	 * .zfs/snapshot/ directories, so for now just return EOPNOTSUPP.
+	 * This will make NFS to fall back to using READDIR instead of
+	 * READDIRPLUS.
+	 * Also snapshots are stored in AVL tree, but based on their names,
+	 * not inode numbers, so it will be very inefficient to iterate
+	 * over all snapshots to find the right one.
+	 * Note that OpenSolaris READDIRPLUS implementation does LOOKUP on
+	 * d_name, and not VGET on d_fileno as we do.
+	 */
+	if (ino == ZFSCTL_INO_ROOT || ino == ZFSCTL_INO_SNAPDIR)
+		return (EOPNOTSUPP);
+
 	ZFS_ENTER(zfsvfs);
 	err = zfs_zget(zfsvfs, ino, &zp);
 	if (err == 0 && zp->z_unlinked) {
@@ -1102,6 +1144,28 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp)
 	return (err);
 }
 
+static int
+zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, int *extflagsp,
+    struct ucred **credanonp, int *numsecflavors, int **secflavors)
+{
+	zfsvfs_t *zfsvfs = vfsp->vfs_data;
+
+	/*
+	 * If this is regular file system vfsp is the same as
+	 * zfsvfs->z_parent->z_vfs, but if it is snapshot,
+	 * zfsvfs->z_parent->z_vfs represents parent file system
+	 * which we have to use here, because only this file system
+	 * has mnt_export configured.
+	 */
+	vfsp = zfsvfs->z_parent->z_vfs;
+
+	return (vfs_stdcheckexp(zfsvfs->z_parent->z_vfs, nam, extflagsp,
+	    credanonp, numsecflavors, secflavors));
+}
+
+CTASSERT(SHORT_FID_LEN <= sizeof(struct fid));
+CTASSERT(LONG_FID_LEN <= sizeof(struct fid));
+
 static int
 zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp)
 {
@@ -1117,7 +1181,11 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp)
 
 	ZFS_ENTER(zfsvfs);
 
-	if (fidp->fid_len == LONG_FID_LEN) {
+	/*
+	 * On FreeBSD we can get snapshot's mount point or its parent file
+	 * system mount point depending if snapshot is already mounted or not.
+	 */
+	if (zfsvfs->z_parent == zfsvfs && fidp->fid_len == LONG_FID_LEN) {
 		zfid_long_t	*zlfid = (zfid_long_t *)fidp;
 		uint64_t	objsetid = 0;
 		uint64_t	setgen = 0;
@@ -1160,9 +1228,8 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp)
 		} else {
 			VN_HOLD(*vpp);
 		}
-		ZFS_EXIT(zfsvfs);
-		/* XXX: LK_RETRY? */
 		vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
+		ZFS_EXIT(zfsvfs);
 		return (0);
 	}
 
@@ -1184,7 +1251,6 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp)
 	}
 
 	*vpp = ZTOV(zp);
-	/* XXX: LK_RETRY? */
 	vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
 	vnode_create_vobject(*vpp, zp->z_phys->zp_size, curthread);
 	ZFS_EXIT(zfsvfs);
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 de7c2930eba..ae26b888759 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
@@ -1185,8 +1185,6 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp,
 		}
 	}
 
-	ZFS_EXIT(zfsvfs);
-
 	/* Translate errors and add SAVENAME when needed. */
 	if (cnp->cn_flags & ISLASTCN) {
 		switch (nameiop) {
@@ -1217,6 +1215,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp,
 		if (error != 0) {
 			VN_RELE(*vpp);
 			*vpp = NULL;
+			ZFS_EXIT(zfsvfs);
 			return (error);
 		}
 	}
@@ -1238,6 +1237,8 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp,
 	}
 #endif
 
+	ZFS_EXIT(zfsvfs);
+
 	return (error);
 }
 
@@ -4335,11 +4336,20 @@ zfs_reclaim_complete(void *arg, int pending)
 	znode_t	*zp = arg;
 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
 
-	ZFS_LOG(1, "zp=%p", zp);
-	ZFS_OBJ_HOLD_ENTER(zfsvfs, zp->z_id);
-	zfs_znode_dmu_fini(zp);
-	ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id);
+	rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER);
+	if (zp->z_dbuf != NULL) {
+		ZFS_OBJ_HOLD_ENTER(zfsvfs, zp->z_id);
+		zfs_znode_dmu_fini(zp);
+		ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id);
+	}
 	zfs_znode_free(zp);
+	rw_exit(&zfsvfs->z_teardown_inactive_lock);
+	/*
+	 * If the file system is being unmounted, there is a process waiting
+	 * for us, wake it up.
+	 */
+	if (zfsvfs->z_unmounted)
+		wakeup_one(zfsvfs);
 }
 
 static int
@@ -4351,6 +4361,9 @@ zfs_freebsd_reclaim(ap)
 {
 	vnode_t	*vp = ap->a_vp;
 	znode_t	*zp = VTOZ(vp);
+	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
+
+	rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER);
 
 	ASSERT(zp != NULL);
 
@@ -4361,7 +4374,7 @@ zfs_freebsd_reclaim(ap)
 
 	mutex_enter(&zp->z_lock);
 	ASSERT(zp->z_phys != NULL);
-	ZTOV(zp) = NULL;
+	zp->z_vnode = NULL;
 	mutex_exit(&zp->z_lock);
 
 	if (zp->z_unlinked)
@@ -4369,7 +4382,6 @@ zfs_freebsd_reclaim(ap)
 	else if (zp->z_dbuf == NULL)
 		zfs_znode_free(zp);
 	else /* if (!zp->z_unlinked && zp->z_dbuf != NULL) */ {
-		zfsvfs_t *zfsvfs = zp->z_zfsvfs;
 		int locked;
 
 		locked = MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id)) ? 2 :
@@ -4392,6 +4404,7 @@ zfs_freebsd_reclaim(ap)
 	vp->v_data = NULL;
 	ASSERT(vp->v_holdcnt >= 1);
 	VI_UNLOCK(vp);
+	rw_exit(&zfsvfs->z_teardown_inactive_lock);
 	return (0);
 }
 
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 a6172f81a03..082198f63d4 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
@@ -110,7 +110,7 @@ znode_evict_error(dmu_buf_t *dbuf, void *user_ptr)
 		mutex_exit(&zp->z_lock);
 		zfs_znode_free(zp);
 	} else if (vp->v_count == 0) {
-		ZTOV(zp) = NULL;
+		zp->z_vnode = NULL;
 		vhold(vp);
 		mutex_exit(&zp->z_lock);
 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
@@ -890,8 +890,16 @@ again:
 		if (zp->z_unlinked) {
 			err = ENOENT;
 		} else {
-			if (ZTOV(zp) != NULL)
-				VN_HOLD(ZTOV(zp));
+			if ((vp = ZTOV(zp)) != NULL) {
+				VI_LOCK(vp);
+				if ((vp->v_iflag & VI_DOOMED) != 0) {
+					VI_UNLOCK(vp);
+					vp = NULL;
+				} else
+					VI_UNLOCK(vp);
+			}
+			if (vp != NULL)
+				VN_HOLD(vp);
 			else {
 				if (first) {
 					ZFS_LOG(1, "dying znode detected (zp=%p)", zp);
@@ -1525,7 +1533,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
 	ZTOV(rootzp)->v_data = NULL;
 	ZTOV(rootzp)->v_count = 0;
 	ZTOV(rootzp)->v_holdcnt = 0;
-	ZTOV(rootzp) = NULL;
+	rootzp->z_vnode = NULL;
 	VOP_UNLOCK(vp, 0);
 	vdestroy(vp);
 	dmu_buf_rele(rootzp->z_dbuf, NULL);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
index db0ebf29b7c..e9b00cbbb68 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -153,7 +153,22 @@ static int zvol_dump_init(zvol_state_t *zv, boolean_t resize);
 static void
 zvol_size_changed(zvol_state_t *zv, major_t maj)
 {
+	struct g_provider *pp;
 
+	g_topology_assert();
+
+	pp = zv->zv_provider;
+	if (pp == NULL)
+		return;
+	if (zv->zv_volsize == pp->mediasize)
+		return;
+	/*
+	 * Changing provider size is not really supported by GEOM, but it
+	 * should be safe when provider is closed.
+	 */
+	if (zv->zv_total_opens > 0)
+		return;
+	pp->mediasize = zv->zv_volsize;
 }
 
 int
@@ -263,6 +278,7 @@ zvol_access(struct g_provider *pp, int acr, int acw, int ace)
 	}
 
 	zv->zv_total_opens += acr + acw + ace;
+	zvol_size_changed(zv, 0);
 
 	mutex_exit(&zvol_state_lock);
 
@@ -402,6 +418,10 @@ zvol_worker(void *arg)
 	zvol_state_t *zv;
 	struct bio *bp;
 
+	thread_lock(curthread);
+	sched_prio(curthread, PRIBIO);
+	thread_unlock(curthread);
+
 	zv = arg;
 	for (;;) {
 		mtx_lock(&zv->zv_queue_mtx);
@@ -411,7 +431,7 @@ zvol_worker(void *arg)
 				zv->zv_state = 2;
 				wakeup(&zv->zv_state);
 				mtx_unlock(&zv->zv_queue_mtx);
-				kproc_exit(0);
+				kthread_exit();
 			}
 			msleep(&zv->zv_queue, &zv->zv_queue_mtx, PRIBIO | PDROP,
 			    "zvol:io", 0);
@@ -824,7 +844,8 @@ zvol_create_minor(const char *name, major_t maj)
 	bioq_init(&zv->zv_queue);
 	mtx_init(&zv->zv_queue_mtx, "zvol", NULL, MTX_DEF);
 	zv->zv_state = 0;
-	kproc_create(zvol_worker, zv, NULL, 0, 0, "zvol:worker %s", pp->name);
+	kproc_kthread_add(zvol_worker, zv, &zfsproc, NULL, 0, 0, "zfskern",
+	    "zvol %s", pp->name + strlen(ZVOL_DEV_DIR) + 1);
 
 	zvol_minors++;
 end:
@@ -1067,11 +1088,6 @@ zvol_set_volblocksize(const char *name, uint64_t volblocksize)
 		if (error == ENOTSUP)
 			error = EBUSY;
 		dmu_tx_commit(tx);
-		/* XXX: Not supported. */
-#if 0
-		if (error == 0)
-			zv->zv_provider->sectorsize = zc->zc_volblocksize;
-#endif
 	}
 end:
 	mutex_exit(&zvol_state_lock);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/callb.h b/sys/cddl/contrib/opensolaris/uts/common/sys/callb.h
index 54f35ac51ca..2b9ac3f9838 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/callb.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/callb.h
@@ -135,8 +135,6 @@ typedef struct callb_cpr {
 #define	CALLB_CPR_INIT(cp, lockp, func, name)	{			\
 		strlcpy(curthread->td_name, (name),			\
 		    sizeof(curthread->td_name));			\
-		strlcpy(curthread->td_proc->p_comm, (name),		\
-		    sizeof(curthread->td_proc->p_comm));		\
 		bzero((caddr_t)(cp), sizeof (callb_cpr_t));		\
 		(cp)->cc_lockp = lockp;					\
 		(cp)->cc_id = callb_add(func, (void *)(cp),		\

From 055f4e2cf86c0a06b1a0e038c6daac0a27361f56 Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Tue, 15 Sep 2009 11:20:23 +0000
Subject: [PATCH 0233/2592] MFC r197039, r197040:

Fix usecount leak in mknod(2) on file system exported over NFS.

While I'm here, correct typo in comment.

Reviewed by:	kan, kib
Approved by:	re (bz)
---
 sys/nfsserver/nfs_serv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index 00be15e24fd..7b4eacfd8db 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -1686,7 +1686,7 @@ out:
 	if (dirp) {
 		vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
-		VOP_UNLOCK(dirp, 0);
+		vput(dirp);
 	}
 ereply:
 	nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1));
@@ -3825,7 +3825,7 @@ nfsmout:
  *     what the heck.
  *
  * The exception to rule 2 is EPERM. If a file is IMMUTABLE, VOP_ACCESS()
- * will return EPERM instead of EACCESS. EPERM is always an error.
+ * will return EPERM instead of EACCES. EPERM is always an error.
  */
 static int
 nfsrv_access(struct vnode *vp, accmode_t accmode, struct ucred *cred,

From 6bd6f5562142cf4c81b5287d4ad1d5f3fce1be42 Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Tue, 15 Sep 2009 11:23:59 +0000
Subject: [PATCH 0234/2592] MFC r196822, r196823, r196824:

Remove 'ad:' prefix from disk serial number. We don't want serial number
to change when we reconnect the disk in a way that it is accessible through
CAM for example.

Discussed with:	trasz

Simplify g_disk_ident_adjust() function and allow any printable character
in serial number.

Discussed with:	trasz
Obtained from:	Wheel Sp. z o.o. (http://www.wheel.pl)

Make serial numbers of daX disks visible by GEOM.

No objections from:	scottl
Obtained from:	Wheel Sp. z o.o. (http://www.wheel.pl)

Approved by:	re (kib)
---
 sys/cam/scsi/scsi_da.c |  2 ++
 sys/dev/ata/ata-disk.c |  4 ++--
 sys/geom/geom_disk.c   | 41 ++++++++++++++---------------------------
 3 files changed, 18 insertions(+), 29 deletions(-)

diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index e331545032a..e3ad7e1abfa 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -1266,6 +1266,8 @@ daregister(struct cam_periph *periph, void *arg)
 	softc->disk->d_flags = 0;
 	if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
 		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));
 	disk_create(softc->disk, DISK_VERSION);
 	mtx_lock(periph->sim->mtx);
 
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 15b9edc30b2..c699a05f52e 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -136,8 +136,8 @@ ad_attach(device_t dev)
     if ((atadev->param.support.command2 & ATA_SUPPORT_CFA) ||
 	atadev->param.config == ATA_PROTO_CFA)
 	adp->disk->d_flags = DISKFLAG_CANDELETE;
-    snprintf(adp->disk->d_ident, sizeof(adp->disk->d_ident), "ad:%s",
-	atadev->param.serial);
+    strlcpy(adp->disk->d_ident, atadev->param.serial,
+	sizeof(adp->disk->d_ident));
     disk_create(adp->disk, DISK_VERSION);
     device_add_child(dev, "subdisk", device_get_unit(dev));
     ad_firmware_geom_adjust(dev, adp->disk);
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c
index 20998bdd417..4cf3196d406 100644
--- a/sys/geom/geom_disk.c
+++ b/sys/geom/geom_disk.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -400,39 +401,25 @@ g_disk_destroy(void *ptr, int flag)
 }
 
 /*
- * We only allow [a-zA-Z0-9-_@#%.:] characters, the rest is converted to 'x'.
+ * We only allow printable characters in disk ident,
+ * the rest is converted to 'x'.
  */
 static void
 g_disk_ident_adjust(char *ident, size_t size)
 {
-	char newid[DISK_IDENT_SIZE], tmp[4];
-	size_t len;
-	char *p;
+	char *p, tmp[4], newid[DISK_IDENT_SIZE];
 
-	bzero(newid, sizeof(newid));
-	len = 0;
-	for (p = ident; *p != '\0' && len < sizeof(newid) - 1; p++) {
-		switch (*p) {
-		default:
-			if ((*p < 'a' || *p > 'z') &&
-			    (*p < 'A' || *p > 'Z') &&
-			    (*p < '0' || *p > '9')) {
-				snprintf(tmp, sizeof(tmp), "x%02hhx", *p);
-				strlcat(newid, tmp, sizeof(newid));
-				len += 3;
-				break;
-			}
-			/* FALLTHROUGH */
-		case '-':
-		case '_':
-		case '@':
-		case '#':
-		case '%':
-		case '.':
-		case ':':
-			newid[len++] = *p;
-			break;
+	newid[0] = '\0';
+	for (p = ident; *p != '\0'; p++) {
+		if (isprint(*p)) {
+			tmp[0] = *p;
+			tmp[1] = '\0';
+		} else {
+			snprintf(tmp, sizeof(tmp), "x%02hhx",
+			    *(unsigned char *)p);
 		}
+		if (strlcat(newid, tmp, sizeof(newid)) >= sizeof(newid))
+			break;
 	}
 	bzero(ident, size);
 	strlcpy(ident, newid, size);

From 26e71a6c1bba865c2260467617a54d036c29973d Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Tue, 15 Sep 2009 12:19:34 +0000
Subject: [PATCH 0235/2592] MFC r197219:

Forced unmounts work just fine in my tests under heavy load. There might
still be a problem, but it isn't worth a warning.

Approved by:	re (kib)
---
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 34f8378c19f..185d84b4c80 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -994,11 +994,6 @@ zfs_umount(vfs_t *vfsp, int fflag)
 	cred_t *cr = curthread->td_ucred;
 	int ret;
 
-	if (fflag & MS_FORCE) {
-		/* TODO: Force unmount is not well implemented yet, so deny it. */
-		ZFS_LOG(0, "Force unmount is experimental - report any problems.");
-	}
-
 	ret = secpolicy_fs_unmount(cr, vfsp);
 	if (ret) {
 		ret = dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource),

From 9c0bf682995d0891ea61c7537dbcb880f6faac5f Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Tue, 15 Sep 2009 12:21:06 +0000
Subject: [PATCH 0236/2592] MFC r197218:

We believe ZFS is ready for production use. Remove a warning about it being
experimental. :)

Approved by:	re (kib)
---
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index e25f5494e68..080643a94c1 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -3072,8 +3072,6 @@ zfs_modevent(module_t mod, int type, void *unused __unused)
 	switch (type) {
 	case MOD_LOAD:
 		zfs_root_token = root_mount_hold("ZFS");
-		printf("WARNING: ZFS is considered to be an experimental "
-		    "feature in FreeBSD.\n");
 
 		mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
 

From 4dec4ece5a22bc0f75460eb4513a8a2202508797 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 15 Sep 2009 12:51:22 +0000
Subject: [PATCH 0237/2592] MFC r196888: The clear_remove() and
 clear_inodedeps() call vn_start_write(NULL, &mp, V_NOWAIT) on the non-busied
 mount point. Unmount might free ufs-specific mp data, causing ffs_vgetf() to
 access freed memory.

Busy mountpoint before dropping softdep lk.

Approved by:	re (kensmith)
---
 sys/ufs/ffs/ffs_softdep.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 5f162806d1e..4d652c114dd 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -5977,12 +5977,19 @@ clear_remove(td)
 			if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
 				continue;
 			FREE_LOCK(&lk);
-			if ((error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp,
-			     FFSV_FORCEINSMQ))) {
+
+			/*
+			 * Let unmount clear deps
+			 */
+			error = vfs_busy(mp, MBF_NOWAIT);
+			if (error != 0)
+				goto finish_write;
+			error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp,
+			     FFSV_FORCEINSMQ);
+			vfs_unbusy(mp);
+			if (error != 0) {
 				softdep_error("clear_remove: vget", error);
-				vn_finished_write(mp);
-				ACQUIRE_LOCK(&lk);
-				return;
+				goto finish_write;
 			}
 			if ((error = ffs_syncvnode(vp, MNT_NOWAIT)))
 				softdep_error("clear_remove: fsync", error);
@@ -5991,6 +5998,7 @@ clear_remove(td)
 			drain_output(vp);
 			BO_UNLOCK(bo);
 			vput(vp);
+		finish_write:
 			vn_finished_write(mp);
 			ACQUIRE_LOCK(&lk);
 			return;
@@ -6050,13 +6058,21 @@ clear_inodedeps(td)
 		if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
 			continue;
 		FREE_LOCK(&lk);
-		if ((error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp,
-		    FFSV_FORCEINSMQ)) != 0) {
-			softdep_error("clear_inodedeps: vget", error);
+		error = vfs_busy(mp, MBF_NOWAIT); /* Let unmount clear deps */
+		if (error != 0) {
 			vn_finished_write(mp);
 			ACQUIRE_LOCK(&lk);
 			return;
 		}
+		if ((error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp,
+		    FFSV_FORCEINSMQ)) != 0) {
+			softdep_error("clear_inodedeps: vget", error);
+			vfs_unbusy(mp);
+			vn_finished_write(mp);
+			ACQUIRE_LOCK(&lk);
+			return;
+		}
+		vfs_unbusy(mp);
 		if (ino == lastino) {
 			if ((error = ffs_syncvnode(vp, MNT_WAIT)))
 				softdep_error("clear_inodedeps: fsync1", error);

From 9cede8fb41b6a41a7a10d5908dc2030b7d840b5f Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Tue, 15 Sep 2009 19:14:25 +0000
Subject: [PATCH 0238/2592] MFC r197223: Fix sched_switch_migrate() by assuming
 locks cannot be shared and a deadlock between 3 different threads by
 acquiring both runqueue locks when doing the migration.

Please note that this is a special condition as we want this fix in
before RC1 as we assume it is critical and so it has been handled
as an instant-merge.  For the STABLE_7 branch, 1 week before the MFC
is assumed.

Approved by:	re (kib)
---
 sys/kern/sched_ule.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 27e8371dff2..fd14fc4021a 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -1749,19 +1749,19 @@ sched_switch_migrate(struct tdq *tdq, struct thread *td, int flags)
 	 */
 	spinlock_enter();
 	thread_block_switch(td);	/* This releases the lock on tdq. */
-	TDQ_LOCK(tdn);
+
+	/*
+	 * Acquire both run-queue locks before placing the thread on the new
+	 * run-queue to avoid deadlocks created by placing a thread with a
+	 * blocked lock on the run-queue of a remote processor.  The deadlock
+	 * occurs when a third processor attempts to lock the two queues in
+	 * question while the target processor is spinning with its own
+	 * run-queue lock held while waiting for the blocked lock to clear.
+	 */
+	tdq_lock_pair(tdn, tdq);
 	tdq_add(tdn, td, flags);
 	tdq_notify(tdn, td);
-	/*
-	 * After we unlock tdn the new cpu still can't switch into this
-	 * thread until we've unblocked it in cpu_switch().  The lock
-	 * pointers may match in the case of HTT cores.  Don't unlock here
-	 * or we can deadlock when the other CPU runs the IPI handler.
-	 */
-	if (TDQ_LOCKPTR(tdn) != TDQ_LOCKPTR(tdq)) {
-		TDQ_UNLOCK(tdn);
-		TDQ_LOCK(tdq);
-	}
+	TDQ_UNLOCK(tdn);
 	spinlock_exit();
 #endif
 	return (TDQ_LOCKPTR(tdn));

From 623b4aa57ea0dbb3f9d06c548be4fbe257754ae0 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Tue, 15 Sep 2009 19:24:18 +0000
Subject: [PATCH 0239/2592] MFC r197224: Use explicit int values for the device
 states in order to allow, if necessary, in the future, adds of new states
 without breaking ABI between revisions.

Please note that this is a special condition as we want this fix in
before RC1 as we assume it is critical and so it has been handled
as an instant-merge.

Approved by:	re (kib)
---
 lib/libdevinfo/devinfo.h | 8 ++++----
 sys/sys/bus.h            | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/libdevinfo/devinfo.h b/lib/libdevinfo/devinfo.h
index 91930a44008..3e580f20d50 100644
--- a/lib/libdevinfo/devinfo.h
+++ b/lib/libdevinfo/devinfo.h
@@ -41,10 +41,10 @@ typedef __uintptr_t	devinfo_handle_t;
  */
 /* XXX not sure if I want a copy here, or expose sys/bus.h */
 typedef enum devinfo_state {
-	DIS_NOTPRESENT,			/* not probed or probe failed */
-	DIS_ALIVE,			/* probe succeeded */
-	DIS_ATTACHED,			/* attach method called */
-	DIS_BUSY			/* device is open */
+	DIS_NOTPRESENT = 10,		/* not probed or probe failed */
+	DIS_ALIVE = 20,			/* probe succeeded */
+	DIS_ATTACHED = 30,		/* attach method called */
+	DIS_BUSY = 40			/* device is open */
 } devinfo_state_t;
 
 struct devinfo_dev {
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 2362041dad2..794dc47a8f1 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -50,10 +50,10 @@ struct u_businfo {
  * @brief State of the device.
  */
 typedef enum device_state {
-	DS_NOTPRESENT,			/**< @brief not probed or probe failed */
-	DS_ALIVE,			/**< @brief probe succeeded */
-	DS_ATTACHED,			/**< @brief attach method called */
-	DS_BUSY				/**< @brief device is open */
+	DS_NOTPRESENT = 10,		/**< @brief not probed or probe failed */
+	DS_ALIVE = 20,			/**< @brief probe succeeded */
+	DS_ATTACHED = 30,		/**< @brief attach method called */
+	DS_BUSY = 40			/**< @brief device is open */
 } device_state_t;
 
 /**

From 599f45c5dd476d3a75843a065424c6a1f924a14c Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 15 Sep 2009 19:38:29 +0000
Subject: [PATCH 0240/2592] MFC	r197203

Previously local end of point-to-point interface is not reachable
within the system that owns the interface. Packets destined to
the local end point leak to the wire towards the default gateway
if one exists. This behavior is changed as part of the L2/L3
rewrite efforts. The local end point is now reachable within the
system. The inpcb code needs to consider this fact during the
address selection process.

Reviewed by:	bz
Approved by:	re
---
 sys/netinet/in_pcb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 525afefe1de..7a4ac10ad63 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -701,6 +701,8 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
 		ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sain)));
 		if (ia == NULL)
 			ia = ifatoia(ifa_ifwithnet(sintosa(&sain)));
+		if (ia == NULL)
+			ia = ifatoia(ifa_ifwithaddr(sintosa(&sain)));
 
 		if (cred == NULL || !prison_flag(cred, PR_IP4)) {
 			if (ia == NULL) {

From 237cb8d79631d7f64bf01fb6625aa2e689512a99 Mon Sep 17 00:00:00 2001
From: Marc Fonvieille 
Date: Tue, 15 Sep 2009 19:56:35 +0000
Subject: [PATCH 0241/2592] MFC: r196588

Log:
  Update some comments to match the removal of the docset compilation
  during the release build.

Approved by:	re (kib)
---
 release/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/release/Makefile b/release/Makefile
index 3fa3c8db762..f4cfb967b13 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -1163,10 +1163,10 @@ iso.1:
 .endif
 
 #
-# --==## Documentation Project files such as the Handbook and FAQ ##==--
+# --==## Documentation Project tools required to build the release notes ##==--
 #
 doc.1:
-	@echo "Making docs..."
+	@echo "Making docproj tools..."
 	@for i in ${DOCPORTS}; do \
 	    cd /usr/ports/$$i && \
 	    env -i FTP_PASSIVE_MODE=$${FTP_PASSIVE_MODE:-no} PATH=$${PATH} \

From 6d8337ba4920cf44da825242e4c837a38bbb837f Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 15 Sep 2009 19:58:33 +0000
Subject: [PATCH 0242/2592] MFC	r196714

This patch fixes the following issues:

- Routing messages are not generated when adding and removing
  interface address aliases.
- Loopback route installed for an interface address alias is
  not deleted from the routing table when that address alias
  is removed from the associated interface.
- Function in_ifscrub() is called extraneously.

Reviewed by:	gnn, kmacy, sam
Approved by:	re
---
 sys/netinet/in.c | 53 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 5 deletions(-)

diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 203f9e6be25..4edc1dbfb17 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -536,7 +536,6 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
 				hostIsNew = 0;
 		}
 		if (ifra->ifra_mask.sin_len) {
-			in_ifscrub(ifp, ia);
 			ia->ia_sockmask = ifra->ifra_mask;
 			ia->ia_sockmask.sin_family = AF_INET;
 			ia->ia_subnetmask =
@@ -545,7 +544,6 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
 		}
 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
 		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
-			in_ifscrub(ifp, ia);
 			ia->ia_dstaddr = ifra->ifra_dstaddr;
 			maskIsNew  = 1; /* We lie; but the effect's the same */
 		}
@@ -991,6 +989,40 @@ in_addprefix(struct in_ifaddr *target, int flags)
 				IN_IFADDR_RUNLOCK();
 				return (EEXIST);
 			} else {
+				struct route pfx_ro;
+				struct sockaddr_in *pfx_addr;
+				struct rtentry msg_rt;
+
+				/* QL: XXX
+				 * This is a bit questionable because there is no
+				 * additional route entry added for an address alias.
+				 * Therefore this route report is inaccurate. Perhaps
+				 * it's better to supply a empty rtentry as how it
+				 * is done in in_scrubprefix().
+				 */
+				bzero(&pfx_ro, sizeof(pfx_ro));
+				pfx_addr = (struct sockaddr_in *)(&pfx_ro.ro_dst);
+				pfx_addr->sin_len = sizeof(*pfx_addr);
+				pfx_addr->sin_family = AF_INET;
+				pfx_addr->sin_addr = prefix;
+				rtalloc_ign_fib(&pfx_ro, 0, 0);
+				if (pfx_ro.ro_rt != NULL) {
+					msg_rt = *pfx_ro.ro_rt;
+					/* QL: XXX
+					 * Point the gateway to the given interface
+					 * address as if a new prefix route entry has 
+					 * been added through the new address alias. 
+					 * All other parts of the rtentry is accurate, 
+					 * e.g., rt_key, rt_mask, rt_ifp etc.
+					 */
+					msg_rt.rt_gateway = 
+						(struct sockaddr *)&ia->ia_addr;
+					rt_newaddrmsg(RTM_ADD, 
+						      (struct ifaddr *)target,
+						      0, &msg_rt);
+					RTFREE(pfx_ro.ro_rt);
+				}
+
 				IN_IFADDR_RUNLOCK();
 				return (0);
 			}
@@ -1024,9 +1056,6 @@ in_scrubprefix(struct in_ifaddr *target)
 	struct rt_addrinfo info;
 	struct sockaddr_dl null_sdl;
 
-	if ((target->ia_flags & IFA_ROUTE) == 0)
-		return (0);
-
 	/*
 	 * Remove the loopback route to the interface address.
 	 * The "useloopback" setting is not consulted because if the
@@ -1054,6 +1083,20 @@ in_scrubprefix(struct in_ifaddr *target)
 			log(LOG_INFO, "in_scrubprefix: deletion failed\n");
 	}
 
+	if ((target->ia_flags & IFA_ROUTE) == 0) {
+		struct rtentry rt;
+
+		/* QL: XXX
+		 * Report a blank rtentry when a route has not been
+		 * installed for the given interface address.
+		 */
+		bzero(&rt, sizeof(rt));
+		rt_newaddrmsg(RTM_DELETE, 
+			      (struct ifaddr *)target,
+			      0, &rt);
+		return (0);
+	}
+
 	if (rtinitflags(target))
 		prefix = target->ia_dstaddr.sin_addr;
 	else {

From 77eb2069ce7c81c4f0edf2c29c799bcc16168b48 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 15 Sep 2009 22:25:19 +0000
Subject: [PATCH 0243/2592] MFC	r197210, 197212, 197235

The bootp code installs an interface address and the nfs client
module tries to install the same address again. This extra code
is removed, which was discovered by the removal of a call to
in_ifscrub() in r196714. This call to in_ifscrub is put back here
because the SIOCAIFADDR command can be used to change the prefix
length of an existing alias.

r197235 reverts file nfs_vfsops.c

Reviewed by:	kmacy
Approved by:	re
---
 sys/netinet/in.c           | 11 +++++++++++
 sys/nfsclient/nfs_vfsops.c |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 4edc1dbfb17..626f63e2243 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -536,6 +536,16 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
 				hostIsNew = 0;
 		}
 		if (ifra->ifra_mask.sin_len) {
+			/* 
+			 * QL: XXX
+			 * Need to scrub the prefix here in case
+			 * the issued command is SIOCAIFADDR with
+			 * the same address, but with a different
+			 * prefix length. And if the prefix length
+			 * is the same as before, then the call is 
+			 * un-necessarily executed here.
+			 */
+			in_ifscrub(ifp, ia);
 			ia->ia_sockmask = ifra->ifra_mask;
 			ia->ia_sockmask.sin_family = AF_INET;
 			ia->ia_subnetmask =
@@ -544,6 +554,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
 		}
 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
 		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
+			in_ifscrub(ifp, ia);
 			ia->ia_dstaddr = ifra->ifra_dstaddr;
 			maskIsNew  = 1; /* We lie; but the effect's the same */
 		}
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index e43f19618be..17dc5d4b5de 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -463,9 +463,11 @@ nfs_mountroot(struct mount *mp)
 			break;
 	}
 #endif
+
 	error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
 	if (error)
 		panic("nfs_mountroot: SIOCAIFADDR: %d", error);
+
 	if ((cp = getenv("boot.netif.mtu")) != NULL) {
 		ir.ifr_mtu = strtol(cp, NULL, 10);
 		bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);

From bb3b75e86fab32e1e360cd8066ba7730228ad91e Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 15 Sep 2009 22:37:17 +0000
Subject: [PATCH 0244/2592] MFC	r197225

This patch enables the node to respond to ARP requests for
configured proxy ARP entries.

Reviewed by:	bz
Approved by:	re
---
 sys/netinet/if_ether.c | 98 +++++++++++++++++++++++-------------------
 1 file changed, 53 insertions(+), 45 deletions(-)

diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index e118cec0fa3..5aa2c59c88c 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -694,62 +694,70 @@ reply:
 	} else {
 		struct llentry *lle = NULL;
 
-		if (!V_arp_proxyall)
-			goto drop;
-
 		sin.sin_addr = itaddr;
-		/* XXX MRT use table 0 for arp reply  */
-		rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
-		if (!rt)
-			goto drop;
+		IF_AFDATA_LOCK(ifp); 
+		lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
+		IF_AFDATA_UNLOCK(ifp);
 
-		/*
-		 * Don't send proxies for nodes on the same interface
-		 * as this one came out of, or we'll get into a fight
-		 * over who claims what Ether address.
-		 */
-		if (!rt->rt_ifp || rt->rt_ifp == ifp) {
-			RTFREE_LOCKED(rt);
-			goto drop;
-		}
-		IF_AFDATA_LOCK(rt->rt_ifp); 
-		lle = lla_lookup(LLTABLE(rt->rt_ifp), 0, (struct sockaddr *)&sin);
-		IF_AFDATA_UNLOCK(rt->rt_ifp);
-		RTFREE_LOCKED(rt);
-
-		if (lle != NULL) {
+		if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
 			(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
 			(void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln);
 			LLE_RUNLOCK(lle);
-		} else
-			goto drop;
+		} else {
 
-		/*
-		 * Also check that the node which sent the ARP packet
-		 * is on the the interface we expect it to be on. This
-		 * avoids ARP chaos if an interface is connected to the
-		 * wrong network.
-		 */
-		sin.sin_addr = isaddr;
+			if (lle != NULL)
+				LLE_RUNLOCK(lle);
 
-		/* XXX MRT use table 0 for arp checks */
-		rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
-		if (!rt)
-			goto drop;
-		if (rt->rt_ifp != ifp) {
-			log(LOG_INFO, "arp_proxy: ignoring request"
-			    " from %s via %s, expecting %s\n",
-			    inet_ntoa(isaddr), ifp->if_xname,
-			    rt->rt_ifp->if_xname);
+			if (!V_arp_proxyall)
+				goto drop;
+			
+			sin.sin_addr = itaddr;
+			/* XXX MRT use table 0 for arp reply  */
+			rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
+			if (!rt)
+				goto drop;
+
+			/*
+			 * Don't send proxies for nodes on the same interface
+			 * as this one came out of, or we'll get into a fight
+			 * over who claims what Ether address.
+			 */
+			if (!rt->rt_ifp || rt->rt_ifp == ifp) {
+				RTFREE_LOCKED(rt);
+				goto drop;
+			}
+			RTFREE_LOCKED(rt);
+
+			(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
+			(void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
+
+			/*
+			 * Also check that the node which sent the ARP packet
+			 * is on the the interface we expect it to be on. This
+			 * avoids ARP chaos if an interface is connected to the
+			 * wrong network.
+			 */
+			sin.sin_addr = isaddr;
+			
+			/* XXX MRT use table 0 for arp checks */
+			rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
+			if (!rt)
+				goto drop;
+			if (rt->rt_ifp != ifp) {
+				log(LOG_INFO, "arp_proxy: ignoring request"
+				    " from %s via %s, expecting %s\n",
+				    inet_ntoa(isaddr), ifp->if_xname,
+				    rt->rt_ifp->if_xname);
+				RTFREE_LOCKED(rt);
+				goto drop;
+			}
 			RTFREE_LOCKED(rt);
-			goto drop;
-		}
-		RTFREE_LOCKED(rt);
 
 #ifdef DEBUG_PROXY
-		printf("arp: proxying for %s\n",
-		       inet_ntoa(itaddr));
+			printf("arp: proxying for %s\n",
+			       inet_ntoa(itaddr));
 #endif
+		}
 	}
 
 	if (itaddr.s_addr == myaddr.s_addr &&

From 553a7dec4b4e11bbb3257f5daa92ce594740fedc Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 15 Sep 2009 22:46:06 +0000
Subject: [PATCH 0245/2592] MFC	r197227

Self pointing routes are installed for configured interface addresses
and address aliases. After an interface is brought down and brought
back up again, those self pointing routes disappeared. This patch
ensures after an interface is brought back up, the loopback routes
are reinstalled properly.

Reviewed by:	bz
Approved by:	re
---
 sys/net/if.c         | 53 ++++++++++++++++++++++++++++++++++++++++++++
 sys/net/if_var.h     |  3 +++
 sys/netinet/in.c     | 42 +++++------------------------------
 sys/netinet/raw_ip.c |  1 +
 sys/netinet6/in6.c   | 44 +++++-------------------------------
 5 files changed, 67 insertions(+), 76 deletions(-)

diff --git a/sys/net/if.c b/sys/net/if.c
index 36c0d037b9a..c0ff443d6dc 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1414,6 +1414,59 @@ ifa_free(struct ifaddr *ifa)
 	}
 }
 
+int
+ifa_add_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
+{
+	int error = 0;
+	struct rtentry *rt = NULL;
+	struct rt_addrinfo info;
+	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
+
+	bzero(&info, sizeof(info));
+	info.rti_ifp = V_loif;
+	info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC;
+	info.rti_info[RTAX_DST] = ia;
+	info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
+	error = rtrequest1_fib(RTM_ADD, &info, &rt, 0);
+
+	if (error == 0 && rt != NULL) {
+		RT_LOCK(rt);
+		((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
+			rt->rt_ifp->if_type;
+		((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
+			rt->rt_ifp->if_index;
+		RT_REMREF(rt);
+		RT_UNLOCK(rt);
+	} else if (error != 0)
+		log(LOG_INFO, "ifa_add_loopback_route: insertion failed\n");
+
+	return (error);
+}
+
+int
+ifa_del_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
+{
+	int error = 0;
+	struct rt_addrinfo info;
+	struct sockaddr_dl null_sdl;
+
+	bzero(&null_sdl, sizeof(null_sdl));
+	null_sdl.sdl_len = sizeof(null_sdl);
+	null_sdl.sdl_family = AF_LINK;
+	null_sdl.sdl_type = ifa->ifa_ifp->if_type;
+	null_sdl.sdl_index = ifa->ifa_ifp->if_index;
+	bzero(&info, sizeof(info));
+	info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC;
+	info.rti_info[RTAX_DST] = ia;
+	info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
+	error = rtrequest1_fib(RTM_DELETE, &info, NULL, 0);
+
+	if (error != 0)
+		log(LOG_INFO, "ifa_del_loopback_route: deletion failed\n");
+
+	return (error);
+}
+
 /*
  * XXX: Because sockaddr_dl has deeper structure than the sockaddr
  * structs used to represent other address families, it is necessary
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 3ab620816a4..523b9e8a813 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -854,6 +854,9 @@ struct	ifnet *ifunit_ref(const char *);
 void	ifq_init(struct ifaltq *, struct ifnet *ifp);
 void	ifq_delete(struct ifaltq *);
 
+int	ifa_add_loopback_route(struct ifaddr *, struct sockaddr *);
+int	ifa_del_loopback_route(struct ifaddr *, struct sockaddr *);
+
 struct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
 int		ifa_ifwithaddr_check(struct sockaddr *);
 struct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 626f63e2243..b22d2737f92 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -827,9 +827,6 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
 {
 	register u_long i = ntohl(sin->sin_addr.s_addr);
 	struct sockaddr_in oldaddr;
-	struct rtentry *rt = NULL;
-	struct rt_addrinfo info;
-	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
 	int s = splimp(), flags = RTF_UP, error = 0;
 
 	oldaddr = ia->ia_addr;
@@ -927,25 +924,9 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
 	/*
 	 * add a loopback route to self
 	 */
-	if (V_useloopback && !(ifp->if_flags & IFF_LOOPBACK)) {
-		bzero(&info, sizeof(info));
-		info.rti_ifp = V_loif;
-		info.rti_flags = ia->ia_flags | RTF_HOST | RTF_STATIC;
-		info.rti_info[RTAX_DST] = (struct sockaddr *)&ia->ia_addr;
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
-		error = rtrequest1_fib(RTM_ADD, &info, &rt, 0);
-
-		if (error == 0 && rt != NULL) {
-			RT_LOCK(rt);
-			((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
-				rt->rt_ifp->if_type;
-			((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
-				rt->rt_ifp->if_index;
-			RT_REMREF(rt);
-			RT_UNLOCK(rt);
-		} else if (error != 0)
-			log(LOG_INFO, "in_ifinit: insertion failed\n");
-	}
+	if (V_useloopback && !(ifp->if_flags & IFF_LOOPBACK))
+		error = ifa_add_loopback_route((struct ifaddr *)ia, 
+				       (struct sockaddr *)&ia->ia_addr);
 
 	return (error);
 }
@@ -1064,8 +1045,6 @@ in_scrubprefix(struct in_ifaddr *target)
 	struct in_addr prefix, mask, p;
 	int error;
 	struct sockaddr_in prefix0, mask0;
-	struct rt_addrinfo info;
-	struct sockaddr_dl null_sdl;
 
 	/*
 	 * Remove the loopback route to the interface address.
@@ -1079,19 +1058,8 @@ in_scrubprefix(struct in_ifaddr *target)
 	 */
 	if ((target->ia_addr.sin_addr.s_addr != INADDR_ANY) &&
 	    !(target->ia_ifp->if_flags & IFF_LOOPBACK)) {
-		bzero(&null_sdl, sizeof(null_sdl));
-		null_sdl.sdl_len = sizeof(null_sdl);
-		null_sdl.sdl_family = AF_LINK;
-		null_sdl.sdl_type = V_loif->if_type;
-		null_sdl.sdl_index = V_loif->if_index;
-		bzero(&info, sizeof(info));
-		info.rti_flags = target->ia_flags | RTF_HOST | RTF_STATIC;
-		info.rti_info[RTAX_DST] = (struct sockaddr *)&target->ia_addr;
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
-		error = rtrequest1_fib(RTM_DELETE, &info, NULL, 0);
-
-		if (error != 0)
-			log(LOG_INFO, "in_scrubprefix: deletion failed\n");
+		error = ifa_del_loopback_route((struct ifaddr *)target,
+				       (struct sockaddr *)&target->ia_addr);
 	}
 
 	if ((target->ia_flags & IFA_ROUTE) == 0) {
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 3df2ec3562d..b40ceb28b79 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -715,6 +715,7 @@ rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 		err = rtinit(&ia->ia_ifa, RTM_ADD, flags);
 		if (err == 0)
 			ia->ia_flags |= IFA_ROUTE;
+		err = ifa_add_loopback_route((struct ifaddr *)ia, sa);
 		ifa_free(&ia->ia_ifa);
 		break;
 	}
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index c832305b162..aef2908abd2 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$");
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1195,24 +1196,8 @@ in6_purgeaddr(struct ifaddr *ifa)
 	 * The check for the current setting of "nd6_useloopback" 
 	 * is not needed.
 	 */
-	{
-		struct rt_addrinfo info;
-		struct sockaddr_dl null_sdl;
-
-		bzero(&null_sdl, sizeof(null_sdl));
-		null_sdl.sdl_len = sizeof(null_sdl);
-		null_sdl.sdl_family = AF_LINK;
-		null_sdl.sdl_type = ia->ia_ifp->if_type;
-		null_sdl.sdl_index = ia->ia_ifp->if_index;
-		bzero(&info, sizeof(info));
-		info.rti_flags = ia->ia_flags | RTF_HOST | RTF_STATIC;
-		info.rti_info[RTAX_DST] = (struct sockaddr *)&ia->ia_addr;
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
-		error = rtrequest1_fib(RTM_DELETE, &info, NULL, 0);
-
-		if (error != 0)
-			log(LOG_INFO, "in6_purgeaddr: deletion failed\n");
-	}
+	error = ifa_del_loopback_route((struct ifaddr *)ia,
+			       (struct sockaddr *)&ia->ia_addr);
 
 	/* stop DAD processing */
 	nd6_dad_stop(ifa);
@@ -1771,27 +1756,8 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia,
 	if (!(ia->ia_flags & IFA_ROUTE)
 	    && (V_nd6_useloopback
 		|| (ifp->if_flags & IFF_LOOPBACK))) {
-		struct rt_addrinfo info;
-		struct rtentry *rt = NULL;
-		static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
-
-		bzero(&info, sizeof(info));
-		info.rti_ifp = V_loif;
-		info.rti_flags = ia->ia_flags | RTF_HOST | RTF_STATIC;
-		info.rti_info[RTAX_DST] = (struct sockaddr *)&ia->ia_addr;
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
-		error = rtrequest1_fib(RTM_ADD, &info, &rt, 0);
-
-		if (error == 0 && rt != NULL) {
-			RT_LOCK(rt);
-			((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
-				ifp->if_type;
-			((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
-				ifp->if_index;
-			RT_REMREF(rt);
-			RT_UNLOCK(rt);
-		} else if (error != 0)
-			log(LOG_INFO, "in6_ifinit: error = %d, insertion failed\n", error);
+		error = ifa_add_loopback_route((struct ifaddr *)ia,
+				       (struct sockaddr *)&ia->ia_addr);
 	}
 
 	/* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */

From e9667e8ff118a1ab0a9d36fce68a055e8d9aad7f Mon Sep 17 00:00:00 2001
From: Rafal Jaworowski 
Date: Wed, 16 Sep 2009 12:07:58 +0000
Subject: [PATCH 0246/2592] MFC r196531-196534,196536

Clean up Marvell platform code.

Introduce SheevaPlug support.

   - The device is based on Marvell 88F6281 system on chip.
   - More info about the platform at http://www.plugcomputer.org

   - To build the FreeBSD kernel:
     make buildkernel TARGET_ARCH=arm KERNCONF=SHEEVAPLUG

   - Installation notes at: http://wiki.freebsd.org/FreeBSDMarvell

Submitted by:	Michal Hajduk
Approved by:	re (kib)
Obtained from:	Semihalf
---
 sys/arm/conf/SHEEVAPLUG              |  70 ++++++++++++
 sys/arm/mv/common.c                  | 119 +++++++++++++++++++++
 sys/arm/mv/discovery/db78xxx.c       |  15 +--
 sys/arm/mv/kirkwood/db88f6xxx.c      |  15 +--
 sys/arm/mv/kirkwood/files.db88f6xxx  |   3 +-
 sys/arm/mv/kirkwood/files.kirkwood   |   4 +
 sys/arm/mv/kirkwood/files.sheevaplug |   4 +
 sys/arm/mv/kirkwood/sheevaplug.c     | 152 +++++++++++++++++++++++++++
 sys/arm/mv/kirkwood/std.db88f6xxx    |   7 +-
 sys/arm/mv/kirkwood/std.kirkwood     |  15 +++
 sys/arm/mv/kirkwood/std.sheevaplug   |   8 ++
 sys/arm/mv/mv_machdep.c              |   7 +-
 sys/arm/mv/mvreg.h                   |  16 ++-
 sys/arm/mv/mvvar.h                   |   7 +-
 sys/arm/mv/orion/db88f5xxx.c         |  14 +--
 sys/conf/options.arm                 |   1 +
 sys/dev/mge/if_mge.c                 |  11 +-
 17 files changed, 410 insertions(+), 58 deletions(-)
 create mode 100644 sys/arm/conf/SHEEVAPLUG
 create mode 100644 sys/arm/mv/kirkwood/files.kirkwood
 create mode 100644 sys/arm/mv/kirkwood/files.sheevaplug
 create mode 100644 sys/arm/mv/kirkwood/sheevaplug.c
 create mode 100644 sys/arm/mv/kirkwood/std.kirkwood
 create mode 100644 sys/arm/mv/kirkwood/std.sheevaplug

diff --git a/sys/arm/conf/SHEEVAPLUG b/sys/arm/conf/SHEEVAPLUG
new file mode 100644
index 00000000000..d11b34d57b3
--- /dev/null
+++ b/sys/arm/conf/SHEEVAPLUG
@@ -0,0 +1,70 @@
+#
+# Custom kernel for Marvell SheevaPlug devices.
+#
+# $FreeBSD$
+#
+
+ident		SHEEVAPLUG
+include		"../mv/kirkwood/std.sheevaplug"
+
+options 	SOC_MV_KIRKWOOD
+makeoptions	MODULES_OVERRIDE=""
+
+#makeoptions	DEBUG=-g		#Build kernel with gdb(1) debug symbols
+makeoptions	WERROR="-Werror"
+
+options 	SCHED_4BSD		#4BSD scheduler
+options 	INET			#InterNETworking
+options 	INET6			#IPv6 communications protocols
+options 	FFS			#Berkeley Fast Filesystem
+options 	NFSCLIENT		#Network Filesystem Client
+options 	NFSLOCKD		#Network Lock Manager
+options 	NFS_ROOT		#NFS usable as /, requires NFSCLIENT
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=mge0
+
+# Root fs on USB device
+#options 	ROOTDEVNAME=\"ufs:/dev/da0a\"
+
+options 	SYSVSHM			#SYSV-style shared memory
+options 	SYSVMSG			#SYSV-style message queues
+options 	SYSVSEM			#SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging
+options 	ALT_BREAK_TO_DEBUGGER
+options 	DDB
+options 	KDB
+
+# Pseudo devices
+device		random
+device		pty
+device		loop
+
+# Serial ports
+device		uart
+
+# Networking
+device		ether
+device		mge			# Marvell Gigabit Ethernet controller
+device		mii
+device		e1000phy
+device		bpf
+options		HZ=1000
+options		DEVICE_POLLING
+device		vlan
+
+# USB
+device		usb
+device		ehci
+device		umass
+device		scbus
+device		pass
+device		da
+
diff --git a/sys/arm/mv/common.c b/sys/arm/mv/common.c
index b2d13dd5a34..d31e0819762 100644
--- a/sys/arm/mv/common.c
+++ b/sys/arm/mv/common.c
@@ -32,8 +32,10 @@
 #include 
 __FBSDID("$FreeBSD$");
 
+#include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -62,6 +64,76 @@ static void decode_win_usb_dump(void);
 
 static uint32_t used_cpu_wins;
 
+static __inline int
+pm_is_disabled(uint32_t mask)
+{
+
+	return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
+}
+
+static __inline uint32_t
+obio_get_pm_mask(uint32_t base)
+{
+	struct obio_device *od;
+
+	for (od = obio_devices; od->od_name != NULL; od++)
+		if (od->od_base == base)
+			return (od->od_pwr_mask);
+
+	return (CPU_PM_CTRL_NONE);
+}
+
+/*
+ * Disable device using power management register.
+ * 1 - Device Power On
+ * 0 - Device Power Off
+ * Mask can be set in loader.
+ * EXAMPLE:
+ * loader> set hw.pm-disable-mask=0x2
+ *
+ * Common mask:
+ * |-------------------------------|
+ * | Device | Kirkwood | Discovery |
+ * |-------------------------------|
+ * | USB0   | 0x00008  | 0x020000  |
+ * |-------------------------------|
+ * | USB1   |     -    | 0x040000  |
+ * |-------------------------------|
+ * | USB2   |     -    | 0x080000  |
+ * |-------------------------------|
+ * | GE0    | 0x00001  | 0x000002  |
+ * |-------------------------------|
+ * | GE1    |     -    | 0x000004  |
+ * |-------------------------------|
+ * | IDMA   |     -    | 0x100000  |
+ * |-------------------------------|
+ * | XOR    | 0x10000  | 0x200000  |
+ * |-------------------------------|
+ * | CESA   | 0x20000  | 0x400000  |
+ * |-------------------------------|
+ * | SATA   | 0x04000  | 0x004000  |
+ * --------------------------------|
+ * This feature can be used only on Kirkwood and Discovery
+ * machines.
+ */
+static __inline void
+pm_disable_device(int mask)
+{
+#ifdef DIAGNOSTIC
+	uint32_t reg;
+
+	reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
+	printf("Power Management Register: 0%x\n", reg);
+
+	reg &= ~mask;
+	soc_power_ctrl_set(reg);
+	printf("Device %x is disabled\n", mask);
+
+	reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
+	printf("Power Management Register: 0%x\n", reg);
+#endif
+}
+
 uint32_t
 read_cpu_ctrl(uint32_t reg)
 {
@@ -103,14 +175,36 @@ cpu_extra_feat(void)
 	return (ef);
 }
 
+/*
+ * Get the power status of device. This feature is only supported on
+ * Kirkwood and Discovery SoCs.
+ */
 uint32_t
 soc_power_ctrl_get(uint32_t mask)
 {
 
+#ifndef SOC_MV_ORION
 	if (mask != CPU_PM_CTRL_NONE)
 		mask &= read_cpu_ctrl(CPU_PM_CTRL);
 
 	return (mask);
+#else
+	return (mask);
+#endif
+}
+
+/*
+ * Set the power status of device. This feature is only supported on
+ * Kirkwood and Discovery SoCs.
+ */
+void
+soc_power_ctrl_set(uint32_t mask)
+{
+
+#ifndef SOC_MV_ORION
+	if (mask != CPU_PM_CTRL_NONE)
+		write_cpu_ctrl(CPU_PM_CTRL, mask);
+#endif
 }
 
 void
@@ -191,6 +285,13 @@ int
 soc_decode_win(void)
 {
 	uint32_t dev, rev;
+	int mask;
+
+	mask = 0;
+	TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
+
+	if (mask != 0)
+		pm_disable_device(mask);
 
 	/* Retrieve our ID: some windows facilities vary between SoC models */
 	soc_id(&dev, &rev);
@@ -623,8 +724,12 @@ decode_win_usb_setup(void)
 
 	/* Disable and clear all USB windows for all ports */
 	m = usb_max_ports();
+
 	for (p = 0; p < m; p++) {
 
+		if (pm_is_disabled(CPU_PM_CTRL_USB(p)))
+			continue;
+
 		for (i = 0; i < MV_WIN_USB_MAX; i++) {
 			win_usb_cr_write(i, p, 0);
 			win_usb_br_write(i, p, 0);
@@ -710,6 +815,9 @@ decode_win_eth_setup(uint32_t base)
 	uint32_t br, sz;
 	int i, j;
 
+	if (pm_is_disabled(obio_get_pm_mask(base)))
+		return;
+
 	/* Disable, clear and revoke protection for all ETH windows */
 	for (i = 0; i < MV_WIN_ETH_MAX; i++) {
 
@@ -880,6 +988,8 @@ decode_win_idma_setup(void)
 	uint32_t br, sz;
 	int i, j;
 
+	if (pm_is_disabled(CPU_PM_CTRL_IDMA))
+		return;
 	/*
 	 * Disable and clear all IDMA windows, revoke protection for all channels
 	 */
@@ -1172,6 +1282,9 @@ decode_win_xor_setup(void)
 	uint32_t br, sz;
 	int i, j, z, e = 1, m, window;
 
+	if (pm_is_disabled(CPU_PM_CTRL_XOR))
+		return;
+
 	/*
 	 * Disable and clear all XOR windows, revoke protection for all
 	 * channels
@@ -1364,6 +1477,9 @@ decode_win_cesa_setup(void)
 	uint32_t br, cr;
 	int i, j;
 
+	if (pm_is_disabled(CPU_PM_CTRL_CRYPTO))
+		return;
+
 	/* Disable and clear all CESA windows */
 	for (i = 0; i < MV_WIN_CESA_MAX; i++) {
 		win_cesa_cr_write(i, 0);
@@ -1432,6 +1548,9 @@ decode_win_sata_setup(void)
 	uint32_t cr, br;
 	int i, j;
 
+	if (pm_is_disabled(CPU_PM_CTRL_SATA))
+		return;
+
 	for (i = 0; i < MV_WIN_SATA_MAX; i++) {
 		win_sata_cr_write(i, 0);
 		win_sata_br_write(i, 0);
diff --git a/sys/arm/mv/discovery/db78xxx.c b/sys/arm/mv/discovery/db78xxx.c
index 98b2dff86fd..df68f50af68 100644
--- a/sys/arm/mv/discovery/db78xxx.c
+++ b/sys/arm/mv/discovery/db78xxx.c
@@ -68,11 +68,8 @@ __FBSDID("$FreeBSD$");
  * 0xffff_2000 - 0xffff_ffff	: unused (~55KB)
  */
 
-const struct pmap_devmap *pmap_devmap_bootstrap_table;
-vm_offset_t pmap_bootstrap_lastaddr;
-
 /* Static device mappings. */
-static const struct pmap_devmap pmap_devmap[] = {
+const struct pmap_devmap pmap_devmap[] = {
 	/*
 	 * Map the on-board devices VA == PA so that we can access them
 	 * with the MMU on or off.
@@ -105,16 +102,6 @@ const struct gpio_config mv_gpio_config[] = {
 	{ -1, -1, -1 }
 };
 
-int
-platform_pmap_init(void)
-{
-
-	pmap_bootstrap_lastaddr = MV_BASE - ARM_NOCACHE_KVA_SIZE;
-	pmap_devmap_bootstrap_table = &pmap_devmap[0];
-
-	return (0);
-}
-
 void
 platform_mpp_init(void)
 {
diff --git a/sys/arm/mv/kirkwood/db88f6xxx.c b/sys/arm/mv/kirkwood/db88f6xxx.c
index 5f8901062cf..6e41ef84e4f 100644
--- a/sys/arm/mv/kirkwood/db88f6xxx.c
+++ b/sys/arm/mv/kirkwood/db88f6xxx.c
@@ -68,11 +68,8 @@ __FBSDID("$FreeBSD$");
  * 0xffff_2000 - 0xffff_ffff	: unused (~55KB)
  */
 
-const struct pmap_devmap *pmap_devmap_bootstrap_table;
-vm_offset_t pmap_bootstrap_lastaddr;
-
 /* Static device mappings. */
-static const struct pmap_devmap pmap_devmap[] = {
+const struct pmap_devmap pmap_devmap[] = {
 	/*
 	 * Map the on-board devices VA == PA so that we can access them
 	 * with the MMU on or off.
@@ -105,16 +102,6 @@ const struct gpio_config mv_gpio_config[] = {
 	{ -1, -1, -1 }
 };
 
-int
-platform_pmap_init(void)
-{
-
-	pmap_bootstrap_lastaddr = MV_BASE - ARM_NOCACHE_KVA_SIZE;
-	pmap_devmap_bootstrap_table = &pmap_devmap[0];
-
-	return (0);
-}
-
 void
 platform_mpp_init(void)
 {
diff --git a/sys/arm/mv/kirkwood/files.db88f6xxx b/sys/arm/mv/kirkwood/files.db88f6xxx
index c0de03c4f94..7ee367318fa 100644
--- a/sys/arm/mv/kirkwood/files.db88f6xxx
+++ b/sys/arm/mv/kirkwood/files.db88f6xxx
@@ -1,5 +1,4 @@
 # $FreeBSD$
 
-arm/mv/rtc.c			standard
-arm/mv/kirkwood/kirkwood.c	standard
+include "arm/mv/kirkwood/files.kirkwood"
 arm/mv/kirkwood/db88f6xxx.c	standard
diff --git a/sys/arm/mv/kirkwood/files.kirkwood b/sys/arm/mv/kirkwood/files.kirkwood
new file mode 100644
index 00000000000..afcea155578
--- /dev/null
+++ b/sys/arm/mv/kirkwood/files.kirkwood
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+arm/mv/rtc.c			standard
+arm/mv/kirkwood/kirkwood.c	standard
diff --git a/sys/arm/mv/kirkwood/files.sheevaplug b/sys/arm/mv/kirkwood/files.sheevaplug
new file mode 100644
index 00000000000..f56c2abd9f5
--- /dev/null
+++ b/sys/arm/mv/kirkwood/files.sheevaplug
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+include "arm/mv/kirkwood/files.kirkwood"
+arm/mv/kirkwood/sheevaplug.c	standard
diff --git a/sys/arm/mv/kirkwood/sheevaplug.c b/sys/arm/mv/kirkwood/sheevaplug.c
new file mode 100644
index 00000000000..ae8b59201cf
--- /dev/null
+++ b/sys/arm/mv/kirkwood/sheevaplug.c
@@ -0,0 +1,152 @@
+/*-
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * Copyright (C) 2009 Semihalf
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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 
+
+/*
+ * Virtual address space layout:
+ * -----------------------------
+ * 0x0000_0000 - 0x7FFF_FFFF	: User Process (2 GB)
+ * 0x8000_0000 - 0xBBFF_FFFF	: Unused (960 MB)
+ * 0xBC00_0000 - 0xBDFF_FFFF	: Device Bus: CS1 (32 MB)
+ * 0xBE00_0000 - 0xBECF_FFFF	: Unused (13 MB)
+ * 0xBED0_0000 - 0xBEDF_FFFF	: Device Bus: CS2 (1 MB)
+ * 0xBEE0_0000 - 0xBEEF_FFFF	: Device Bus: CS0 (1 MB)
+ * 0xBEF0_0000 - 0xBEFF_FFFF	: Device Bus: BOOT (1 MB)
+ * 0xBF00_0000 - 0xBFFF_FFFF	: Unused (16 MB)
+ * 0xC000_0000 - virtual_avail	: Kernel Reserved (text, data, page tables,
+ * 				: stack etc.)
+ * virtual-avail - 0xEFFF_FFFF	: KVA (virtual_avail is typically < 0xc0a0_0000)
+ * 0xF000_0000 - 0xF0FF_FFFF	: No-Cache allocation area (16 MB)
+ * 0xF100_0000 - 0xF10F_FFFF	: SoC Integrated devices registers range (1 MB)
+ * 0xF110_0000 - 0xF11F_FFFF	: CESA SRAM (1 MB)
+ * 0xF120_0000 - 0xFFFE_FFFF	: Unused (237 MB + 960 kB)
+ * 0xFFFF_0000 - 0xFFFF_0FFF	: 'High' vectors page (4 kB)
+ * 0xFFFF_1000 - 0xFFFF_1FFF	: ARM_TP_ADDRESS/RAS page (4 kB)
+ * 0xFFFF_2000 - 0xFFFF_FFFF	: Unused (56 kB)
+ */
+
+/* Static device mappings. */
+const struct pmap_devmap pmap_devmap[] = {
+	/*
+	 * Map the on-board devices VA == PA so that we can access them
+	 * with the MMU on or off.
+	 */
+	{ /* SoC integrated peripherals registers range */
+		MV_BASE,
+		MV_PHYS_BASE,
+		MV_SIZE,
+		VM_PROT_READ | VM_PROT_WRITE,
+		PTE_NOCACHE,
+	},
+	{ /* CESA SRAM */
+		MV_CESA_SRAM_BASE,
+		MV_CESA_SRAM_PHYS_BASE,
+		MV_CESA_SRAM_SIZE,
+		VM_PROT_READ | VM_PROT_WRITE,
+		PTE_NOCACHE,
+	},
+	{ 0, 0, 0, 0, 0, }
+};
+
+const struct gpio_config mv_gpio_config[] = {
+	{ -1, -1, -1 }
+};
+
+void
+platform_mpp_init(void)
+{
+
+	/*
+	 * MPP configuration for Sheeva Plug
+	 *
+	 * MPP[0]:  NF_IO[2]
+	 * MPP[1]:  NF_IO[3]
+	 * MPP[2]:  NF_IO[4]
+	 * MPP[3]:  NF_IO[5]
+	 * MPP[4]:  NF_IO[6]
+	 * MPP[5]:  NF_IO[7]
+	 * MPP[6]:  SYSRST_OUTn
+	 * MPP[8]:  UA0_RTS
+	 * MPP[9]:  UA0_CTS
+	 * MPP[10]: UA0_TXD
+	 * MPP[11]: UA0_RXD
+	 * MPP[12]: SD_CLK
+	 * MPP[13]: SD_CMD
+	 * MPP[14]: SD_D[0]
+	 * MPP[15]: SD_D[1]
+	 * MPP[16]: SD_D[2]
+	 * MPP[17]: SD_D[3]
+	 * MPP[18]: NF_IO[0]
+	 * MPP[19]: NF_IO[1]
+	 * MPP[29]: TSMP[9]
+	 *
+	 * Others:  GPIO
+	 */
+
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x01111111);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x11113322);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00001111);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00100000);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x00000000);
+}
+
+static void
+platform_identify(void *dummy)
+{
+
+	soc_identify();
+
+	/*
+	 * XXX Board identification e.g. read out from FPGA or similar should
+	 * go here
+	 */
+}
+SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);
diff --git a/sys/arm/mv/kirkwood/std.db88f6xxx b/sys/arm/mv/kirkwood/std.db88f6xxx
index 84af354e507..3a00f967540 100644
--- a/sys/arm/mv/kirkwood/std.db88f6xxx
+++ b/sys/arm/mv/kirkwood/std.db88f6xxx
@@ -1,13 +1,8 @@
 # $FreeBSD$
 
 include	"../mv/std.mv"
+include "../mv/kirkwood/std.kirkwood"
 files	"../mv/kirkwood/files.db88f6xxx"
 
-makeoptions	KERNPHYSADDR=0x00900000
-makeoptions	KERNVIRTADDR=0xc0900000
 
-options		KERNPHYSADDR=0x00900000
-options		KERNVIRTADDR=0xc0900000
-options		PHYSADDR=0x00000000
 options		PHYSMEM_SIZE=0x20000000
-options		STARTUP_PAGETABLE_ADDR=0x00100000
diff --git a/sys/arm/mv/kirkwood/std.kirkwood b/sys/arm/mv/kirkwood/std.kirkwood
new file mode 100644
index 00000000000..6b74920b5f9
--- /dev/null
+++ b/sys/arm/mv/kirkwood/std.kirkwood
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+# kernel gets loaded at 0x00900000 by the loader, but runs at virtual address
+# 0xc0900000.  RAM starts at 0.  We put the pagetable at a reasonable place
+# in memory, but may need to bounce it higher if there's a problem with this.
+# We could paper over this by loading the kernel at 0xc0000000 virtual, but
+# that leads to other complications, so we'll just reclaim the lower region of
+# ram after we're loaded.  Put the page tables for startup at 1MB.
+makeoptions	KERNPHYSADDR=0x00900000
+makeoptions	KERNVIRTADDR=0xc0900000
+
+options		KERNPHYSADDR=0x00900000
+options		KERNVIRTADDR=0xc0900000
+options		PHYSADDR=0x00000000
+options		STARTUP_PAGETABLE_ADDR=0x00100000
diff --git a/sys/arm/mv/kirkwood/std.sheevaplug b/sys/arm/mv/kirkwood/std.sheevaplug
new file mode 100644
index 00000000000..a289914f327
--- /dev/null
+++ b/sys/arm/mv/kirkwood/std.sheevaplug
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+include	"../mv/std.mv"
+include "../mv/kirkwood/std.kirkwood"
+files	"../mv/kirkwood/files.sheevaplug"
+
+options		PHYSMEM_SIZE=0x20000000
+options		MII_ADDR_BASE=0
diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c
index 59836fc8dbf..2dc20ceb08e 100644
--- a/sys/arm/mv/mv_machdep.c
+++ b/sys/arm/mv/mv_machdep.c
@@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$");
 #include 
 
 #include 	/* XXX eventually this should be eliminated */
+#include 
 
 #ifdef  DEBUG
 #define debugf(fmt, args...) printf(fmt, ##args)
@@ -133,7 +134,9 @@ struct pcpu *pcpup = &__pcpu;
 vm_paddr_t phys_avail[10];
 vm_paddr_t dump_avail[4];
 vm_offset_t physical_pages;
+vm_offset_t pmap_bootstrap_lastaddr;
 
+const struct pmap_devmap *pmap_devmap_bootstrap_table;
 struct pv_addr systempage;
 struct pv_addr msgbufpv;
 struct pv_addr irqstack;
@@ -423,8 +426,8 @@ initarm(void *mdp, void *unused __unused)
 		while (1);
 
 	/* Platform-specific initialisation */
-	if (platform_pmap_init() != 0)
-		return (NULL);
+	pmap_bootstrap_lastaddr = MV_BASE - ARM_NOCACHE_KVA_SIZE;
+	pmap_devmap_bootstrap_table = &pmap_devmap[0];
 
 	pcpu_init(pcpup, 0, sizeof(struct pcpu));
 	PCPU_SET(curthread, &thread0);
diff --git a/sys/arm/mv/mvreg.h b/sys/arm/mv/mvreg.h
index 271addc2fc7..28e342adcce 100644
--- a/sys/arm/mv/mvreg.h
+++ b/sys/arm/mv/mvreg.h
@@ -218,6 +218,7 @@
  */
 #define CPU_PM_CTRL		0x1C
 #define CPU_PM_CTRL_NONE	0
+#define CPU_PM_CTRL_ALL		~0x0
 
 #if defined(SOC_MV_KIRKWOOD)
 #define CPU_PM_CTRL_GE0		(1 << 0)
@@ -234,8 +235,11 @@
 #define CPU_PM_CTRL_SATA1	(1 << 15)
 #define CPU_PM_CTRL_XOR1	(1 << 16)
 #define CPU_PM_CTRL_CRYPTO	(1 << 17)
-#define CPU_PM_CTRL_GE1		(1 << 18)
-#define CPU_PM_CTRL_TDM		(1 << 19)
+#define CPU_PM_CTRL_GE1		(1 << 19)
+#define CPU_PM_CTRL_TDM		(1 << 20)
+#define CPU_PM_CTRL_XOR		(CPU_PM_CTRL_XOR0 | CPU_PM_CTRL_XOR1)
+#define CPU_PM_CTRL_USB(u)	(CPU_PM_CTRL_USB0)
+#define CPU_PM_CTRL_SATA	(CPU_PM_CTRL_SATA0 | CPU_PM_CTRL_SATA1)
 #elif defined(SOC_MV_DISCOVERY)
 #define CPU_PM_CTRL_GE0		(1 << 1)
 #define CPU_PM_CTRL_GE1		(1 << 2)
@@ -258,6 +262,14 @@
 #define CPU_PM_CTRL_XOR		(1 << 21)
 #define CPU_PM_CTRL_CRYPTO	(1 << 22)
 #define CPU_PM_CTRL_DEVICE	(1 << 23)
+#define CPU_PM_CTRL_USB(u)	(1 << (17 + (u)))
+#define CPU_PM_CTRL_SATA	(CPU_PM_CTRL_SATA0 | CPU_PM_CTRL_SATA1)
+#else
+#define CPU_PM_CTRL_CRYPTO	(CPU_PM_CTRL_NONE)
+#define CPU_PM_CTRL_IDMA	(CPU_PM_CTRL_NONE)
+#define CPU_PM_CTRL_XOR		(CPU_PM_CTRL_NONE)
+#define CPU_PM_CTRL_SATA	(CPU_PM_CTRL_NONE)
+#define CPU_PM_CTRL_USB(u)	(CPU_PM_CTRL_NONE)
 #endif
 
 /*
diff --git a/sys/arm/mv/mvvar.h b/sys/arm/mv/mvvar.h
index 061f3633d89..7d7de32f7c8 100644
--- a/sys/arm/mv/mvvar.h
+++ b/sys/arm/mv/mvvar.h
@@ -41,6 +41,10 @@
 #define _MVVAR_H_
 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #define	MV_TYPE_PCI		0
 #define	MV_TYPE_PCIE		1
@@ -104,6 +108,7 @@ struct decode_win {
 	int		remap;
 };
 
+extern const struct pmap_devmap pmap_devmap[];
 extern const struct obio_pci mv_pci_info[];
 extern const struct gpio_config mv_gpio_config[];
 extern bus_space_tag_t obio_tag;
@@ -124,13 +129,13 @@ int mv_gpio_configure(uint32_t pin, uint32_t flags, uint32_t mask);
 void mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable);
 uint8_t mv_gpio_in(uint32_t pin);
 
-int platform_pmap_init(void);
 void platform_mpp_init(void);
 int soc_decode_win(void);
 void soc_id(uint32_t *dev, uint32_t *rev);
 void soc_identify(void);
 void soc_dump_decode_win(void);
 uint32_t soc_power_ctrl_get(uint32_t mask);
+void soc_power_ctrl_set(uint32_t mask);
 
 int decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
     int remap);
diff --git a/sys/arm/mv/orion/db88f5xxx.c b/sys/arm/mv/orion/db88f5xxx.c
index 8b40f5447ab..02759bea7f6 100644
--- a/sys/arm/mv/orion/db88f5xxx.c
+++ b/sys/arm/mv/orion/db88f5xxx.c
@@ -70,12 +70,10 @@ __FBSDID("$FreeBSD$");
  * 0xffff_2000 - 0xffff_ffff	: unused (~55KB)
  */
 
-const struct pmap_devmap *pmap_devmap_bootstrap_table;
-vm_offset_t pmap_bootstrap_lastaddr;
 int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin);
 
 /* Static device mappings. */
-static const struct pmap_devmap pmap_devmap[] = {
+const struct pmap_devmap pmap_devmap[] = {
 	/*
 	 * Map the on-board devices VA == PA so that we can access them
 	 * with the MMU on or off.
@@ -184,16 +182,6 @@ const struct gpio_config mv_gpio_config[] = {
 };
 #endif
 
-int
-platform_pmap_init(void)
-{
-
-	pmap_bootstrap_lastaddr = MV_BASE - ARM_NOCACHE_KVA_SIZE;
-	pmap_devmap_bootstrap_table = &pmap_devmap[0];
-
-	return (0);
-}
-
 void
 platform_mpp_init(void)
 {
diff --git a/sys/conf/options.arm b/sys/conf/options.arm
index a3fb7602f40..b3cc09731c8 100644
--- a/sys/conf/options.arm
+++ b/sys/conf/options.arm
@@ -24,6 +24,7 @@ KERNVIRTADDR		opt_global.h
 LOADERRAMADDR		opt_global.h
 PHYSADDR		opt_global.h
 PHYSMEM_SIZE		opt_global.h
+MII_ADDR_BASE		opt_global.h
 SKYEYE_WORKAROUNDS	opt_global.h
 SOC_MV_DISCOVERY	opt_global.h
 SOC_MV_KIRKWOOD		opt_global.h
diff --git a/sys/dev/mge/if_mge.c b/sys/dev/mge/if_mge.c
index ff505e98637..0188ae3b79f 100644
--- a/sys/dev/mge/if_mge.c
+++ b/sys/dev/mge/if_mge.c
@@ -69,7 +69,9 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
-#define	MV_PHY_ADDR_BASE	8
+#ifndef MII_ADDR_BASE
+#define MII_ADDR_BASE 8
+#endif
 
 #include 
 #include 
@@ -1264,14 +1266,15 @@ mge_miibus_readreg(device_t dev, int phy, int reg)
 
 	/*
 	 * We assume static PHY address <=> device unit mapping:
-	 * PHY Address = MV_PHY_ADDR_BASE + devce unit.
+	 * PHY Address = MII_ADDR_BASE + devce unit.
 	 * This is true for most Marvell boards.
 	 * 
 	 * Code below grants proper PHY detection on each device
 	 * unit.
 	 */
 
-	if ((MV_PHY_ADDR_BASE + device_get_unit(dev)) != phy)
+	
+	if ((MII_ADDR_BASE + device_get_unit(dev)) != phy)
 		return (0);
 
 	MGE_WRITE(sc_mge0, MGE_REG_SMI, 0x1fffffff &
@@ -1292,7 +1295,7 @@ mge_miibus_writereg(device_t dev, int phy, int reg, int value)
 {
 	uint32_t retries;
 
-	if ((MV_PHY_ADDR_BASE + device_get_unit(dev)) != phy)
+	if ((MII_ADDR_BASE + device_get_unit(dev)) != phy)
 		return (0);
 
 	MGE_WRITE(sc_mge0, MGE_REG_SMI, 0x1fffffff &

From 9f1fab50644f23b1885ec8ae0b875b824ce85bb4 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Wed, 16 Sep 2009 13:24:37 +0000
Subject: [PATCH 0247/2592] MFC r197049: Calculate the amount of bytes to copy
 for select filedescriptor masks taking into account size of fd_set for the
 current process ABI.

Approved by:	re (kensmith)
---
 sys/compat/freebsd32/freebsd32_misc.c |  3 ++-
 sys/compat/linux/linux_misc.c         |  2 +-
 sys/kern/sys_generic.c                | 14 +++++++++-----
 sys/sys/syscallsubr.h                 |  2 +-
 4 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 466aab4ca28..71b22aa11c2 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -589,7 +589,8 @@ freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
 	 * XXX big-endian needs to convert the fd_sets too.
 	 * XXX Do pointers need PTRIN()?
 	 */
-	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp));
+	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
+	    sizeof(int32_t) * 8));
 }
 
 /*
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 267da07e48f..1d5eaf832ea 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -522,7 +522,7 @@ linux_select(struct thread *td, struct linux_select_args *args)
 		tvp = NULL;
 
 	error = kern_select(td, args->nfds, args->readfds, args->writefds,
-	    args->exceptfds, tvp);
+	    args->exceptfds, tvp, sizeof(l_int) * 8);
 
 #ifdef DEBUG
 	if (ldebug(select))
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index bd0f2793378..6831fe8d8ca 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -774,12 +774,13 @@ select(td, uap)
 	} else
 		tvp = NULL;
 
-	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp));
+	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
+	    NFDBITS));
 }
 
 int
 kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
-    fd_set *fd_ex, struct timeval *tvp)
+    fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits)
 {
 	struct filedesc *fdp;
 	/*
@@ -792,7 +793,7 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
 	fd_mask *ibits[3], *obits[3], *selbits, *sbp;
 	struct timeval atv, rtv, ttv;
 	int error, timo;
-	u_int nbufbytes, ncpbytes, nfdbits;
+	u_int nbufbytes, ncpbytes, ncpubytes, nfdbits;
 
 	if (nd < 0)
 		return (EINVAL);
@@ -806,6 +807,7 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
 	 */
 	nfdbits = roundup(nd, NFDBITS);
 	ncpbytes = nfdbits / NBBY;
+	ncpubytes = roundup(nd, abi_nfdbits) / NBBY;
 	nbufbytes = 0;
 	if (fd_in != NULL)
 		nbufbytes += 2 * ncpbytes;
@@ -832,9 +834,11 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
 			ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp;	\
 			obits[x] = sbp;					\
 			sbp += ncpbytes / sizeof *sbp;			\
-			error = copyin(name, ibits[x], ncpbytes);	\
+			error = copyin(name, ibits[x], ncpubytes);	\
 			if (error != 0)					\
 				goto done;				\
+			bzero((char *)ibits[x] + ncpubytes,		\
+			    ncpbytes - ncpubytes);			\
 		}							\
 	} while (0)
 	getbits(fd_in, 0);
@@ -888,7 +892,7 @@ done:
 	if (error == EWOULDBLOCK)
 		error = 0;
 #define	putbits(name, x) \
-	if (name && (error2 = copyout(obits[x], name, ncpbytes))) \
+	if (name && (error2 = copyout(obits[x], name, ncpubytes))) \
 		error = error2;
 	if (error == 0) {
 		int error2;
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index d0f209cc5b8..e1c83ccebb2 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -170,7 +170,7 @@ int	kern_sched_rr_get_interval(struct thread *td, pid_t pid,
 int	kern_semctl(struct thread *td, int semid, int semnum, int cmd,
 	    union semun *arg, register_t *rval);
 int	kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
-	    fd_set *fd_ex, struct timeval *tvp);
+	    fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits);
 int	kern_sendfile(struct thread *td, struct sendfile_args *uap,
 	    struct uio *hdr_uio, struct uio *trl_uio, int compat);
 int	kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,

From 04a34c6c34fe71434c6648b77f864e72b4682919 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Wed, 16 Sep 2009 13:44:12 +0000
Subject: [PATCH 0248/2592] Fixes two bugs: 1) A lock issue, if we ever had to
 try again    we would double lock the INP lock. 2) We were allowing (at wrap)
 associd 0... which really    we cannot allow since 0 normally means in most
 socket    API calls that we are wishing to effect something on    the INP not
 TCB.

Approved by: re, rrs (mentor)
---
 sys/netinet/sctp_pcb.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index c5a8ddfc1a6..0d1f1e0f847 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -3926,12 +3926,20 @@ sctp_aloc_a_assoc_id(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
 	struct sctpasochead *head;
 	struct sctp_tcb *lstcb;
 
+	SCTP_INP_WLOCK(inp);
 try_again:
 	if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
 		/* TSNH */
+		SCTP_INP_WUNLOCK(inp);
 		return (0);
 	}
-	SCTP_INP_WLOCK(inp);
+	/*
+	 * We don't allow assoc id to be 0, this is needed otherwise if the
+	 * id were to wrap we would have issues with some socket options.
+	 */
+	if (inp->sctp_associd_counter == 0) {
+		inp->sctp_associd_counter++;
+	}
 	id = inp->sctp_associd_counter;
 	inp->sctp_associd_counter++;
 	lstcb = sctp_findasoc_ep_asocid_locked(inp, (sctp_assoc_t) id, 0);

From 6b3c18a020e2a95bc57bbcedd40a932fa8e93663 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Wed, 16 Sep 2009 14:47:50 +0000
Subject: [PATCH 0249/2592] MFC 197257: Fix a bug reported by Daniel Mentz:
 When authenticating DATA chunks some DATA chunks might get stuck when the MTU
 gets decreased via an ICMP message.

Approved by: re, rrs (mentor)
---
 sys/netinet/sctp_usrreq.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index c80cca0cc8f..4442f11befb 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -106,6 +106,7 @@ sctp_pathmtu_adjustment(struct sctp_inpcb *inp,
     uint16_t nxtsz)
 {
 	struct sctp_tmit_chunk *chk;
+	uint16_t overhead;
 
 	/* Adjust that too */
 	stcb->asoc.smallest_mtu = nxtsz;
@@ -114,13 +115,17 @@ sctp_pathmtu_adjustment(struct sctp_inpcb *inp,
 	SCTP_PRINTF("sctp_pathmtu_adjust called inp:%p stcb:%p net:%p nxtsz:%d\n",
 	    inp, stcb, net, nxtsz);
 #endif
+	overhead = IP_HDR_SIZE;
+	if (sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.peer_auth_chunks)) {
+		overhead += sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
+	}
 	TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) {
-		if ((chk->send_size + IP_HDR_SIZE) > nxtsz) {
+		if ((chk->send_size + overhead) > nxtsz) {
 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
 		}
 	}
 	TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
-		if ((chk->send_size + IP_HDR_SIZE) > nxtsz) {
+		if ((chk->send_size + overhead) > nxtsz) {
 			/*
 			 * For this guy we also mark for immediate resend
 			 * since we sent to big of chunk

From 053351cec37100a3558f948b269f8c891ac9cfce Mon Sep 17 00:00:00 2001
From: Scott Long 
Date: Thu, 17 Sep 2009 05:27:32 +0000
Subject: [PATCH 0250/2592] Merge r197260, r197261, r197262

- Prevent a panic on modern controllers by increasing CISS_MAX_PHYSTGT to 256
- Fix MSI and PERFORMANT interrupt programming.  Fixes hang on boot.
- Fix locking bugs in ioctl handler

Most of this has been soaking at Yahoo for several months, if not longer.  The
quick MFC is due to the impending 8.0-RC1 build.

Approved by:	re
Obtained from:	Yahoo!
---
 sys/dev/ciss/ciss.c    | 26 ++++++++++++++++++++------
 sys/dev/ciss/cissreg.h |  3 ++-
 sys/dev/ciss/cissvar.h |  2 +-
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index 8c9ef5adb34..f95b689b7f5 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -736,11 +736,16 @@ setup:
 	ciss_printf(sc, "PERFORMANT Transport\n");
 	if ((ciss_force_interrupt != 1) && (ciss_setup_msix(sc) == 0)) {
 	    intr = ciss_perf_msi_intr;
-	    sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_MSI;
 	} else {
 	    intr = ciss_perf_intr;
-	    sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ;
 	}
+	/* XXX The docs say that the 0x01 bit is only for SAS controllers.
+	 * Unfortunately, there is no good way to know if this is a SAS
+	 * controller.  Hopefully enabling this bit universally will work OK.
+	 * It seems to work fine for SA6i controllers.
+	 */
+        sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ | CISS_TL_PERF_INTR_MSI;
+
     } else {
 	ciss_printf(sc, "SIMPLE Transport\n");
 	/* MSIX doesn't seem to work in SIMPLE mode, only enable if it forced */
@@ -834,7 +839,10 @@ ciss_setup_msix(struct ciss_softc *sc)
 	return (EINVAL);
 
     val = pci_msix_count(sc->ciss_dev);
-    if ((val != CISS_MSI_COUNT) || (pci_alloc_msix(sc->ciss_dev, &val) != 0))
+    if (val < CISS_MSI_COUNT)
+	return (EINVAL);
+    val = MIN(val, CISS_MSI_COUNT);
+    if (pci_alloc_msix(sc->ciss_dev, &val) != 0)
 	return (EINVAL);
 
     sc->ciss_msi = val;
@@ -2559,15 +2567,16 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
     /*
      * Allocate an in-kernel databuffer if required, copy in user data.
      */
+    mtx_unlock(&sc->ciss_mtx);
     cr->cr_length = ioc->buf_size;
     if (ioc->buf_size > 0) {
 	if ((cr->cr_data = malloc(ioc->buf_size, CISS_MALLOC_CLASS, M_NOWAIT)) == NULL) {
 	    error = ENOMEM;
-	    goto out;
+	    goto out_unlocked;
 	}
 	if ((error = copyin(ioc->buf, cr->cr_data, ioc->buf_size))) {
 	    debug(0, "copyin: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
-	    goto out;
+	    goto out_unlocked;
 	}
     }
 
@@ -2578,6 +2587,7 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
     bcopy(&ioc->Request, &cc->cdb, sizeof(cc->cdb));
 
     /* XXX anything else to populate here? */
+    mtx_lock(&sc->ciss_mtx);
 
     /*
      * Run the command.
@@ -2598,15 +2608,19 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
      * Copy the results back to the user.
      */
     bcopy(ce, &ioc->error_info, sizeof(*ce));
+    mtx_unlock(&sc->ciss_mtx);
     if ((ioc->buf_size > 0) &&
 	(error = copyout(cr->cr_data, ioc->buf, ioc->buf_size))) {
 	debug(0, "copyout: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
-	goto out;
+	goto out_unlocked;
     }
 
     /* done OK */
     error = 0;
 
+out_unlocked:
+    mtx_lock(&sc->ciss_mtx);
+
 out:
     if ((cr != NULL) && (cr->cr_data != NULL))
 	free(cr->cr_data, CISS_MALLOC_CLASS);
diff --git a/sys/dev/ciss/cissreg.h b/sys/dev/ciss/cissreg.h
index 196307b6508..9ed631b4ad7 100644
--- a/sys/dev/ciss/cissreg.h
+++ b/sys/dev/ciss/cissreg.h
@@ -736,7 +736,8 @@ struct ciss_bmic_flush_cache {
 #define CISS_TL_PERF_CLEAR_INT(sc)		CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_ODC, CISS_TL_SIMPLE_ODC_CLEAR)
 #define CISS_CYCLE_MASK		0x00000001
 
-#define CISS_MSI_COUNT	4
+/* Only need one MSI/MSI-X vector */
+#define CISS_MSI_COUNT	1
 
 #define CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc) \
 	CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IMR, \
diff --git a/sys/dev/ciss/cissvar.h b/sys/dev/ciss/cissvar.h
index f9f5c6f1049..98e875fbf30 100644
--- a/sys/dev/ciss/cissvar.h
+++ b/sys/dev/ciss/cissvar.h
@@ -176,7 +176,7 @@ struct ciss_pdrive
 
 #define CISS_PHYSICAL_SHIFT	5
 #define CISS_PHYSICAL_BASE	(1 << CISS_PHYSICAL_SHIFT)
-#define CISS_MAX_PHYSTGT	15
+#define CISS_MAX_PHYSTGT	256
 
 #define CISS_IS_PHYSICAL(bus)	(bus >= CISS_PHYSICAL_BASE)
 #define CISS_CAM_TO_PBUS(bus)	(bus - CISS_PHYSICAL_BASE)

From 24048b0cb398d6a4c20e34bad57fb61a58084dba Mon Sep 17 00:00:00 2001
From: Scott Long 
Date: Thu, 17 Sep 2009 05:30:55 +0000
Subject: [PATCH 0251/2592] Merge rev 197263:

- Enable MSI support (MSIX support was already present)
- Performance improvements

Approved by:	re
Obtained from:	Yahoo!
---
 sys/dev/ciss/ciss.c    | 112 +++++++++++++++++++++++------------------
 sys/dev/ciss/cissreg.h |   3 +-
 sys/dev/ciss/cissvar.h |  34 ++++---------
 3 files changed, 75 insertions(+), 74 deletions(-)

diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index f95b689b7f5..39836ea7ea7 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -279,8 +279,10 @@ TUNABLE_INT("hw.ciss.force_interrupt", &ciss_force_interrupt);
  * stick with matching against subvendor/subdevice, and thus have to
  * be updated for every new CISS adapter that appears.
  */
-#define CISS_BOARD_SA5	(1<<0)
-#define CISS_BOARD_SA5B	(1<<1)
+#define CISS_BOARD_UNKNWON	0
+#define CISS_BOARD_SA5		1
+#define CISS_BOARD_SA5B		2
+#define CISS_BOARD_NOMSI	(1<<4)
 
 static struct
 {
@@ -289,10 +291,10 @@ static struct
     int		flags;
     char	*desc;
 } ciss_vendor_data[] = {
-    { 0x0e11, 0x4070, CISS_BOARD_SA5,	"Compaq Smart Array 5300" },
-    { 0x0e11, 0x4080, CISS_BOARD_SA5B,	"Compaq Smart Array 5i" },
-    { 0x0e11, 0x4082, CISS_BOARD_SA5B,	"Compaq Smart Array 532" },
-    { 0x0e11, 0x4083, CISS_BOARD_SA5B,	"HP Smart Array 5312" },
+    { 0x0e11, 0x4070, CISS_BOARD_SA5|CISS_BOARD_NOMSI,	"Compaq Smart Array 5300" },
+    { 0x0e11, 0x4080, CISS_BOARD_SA5B|CISS_BOARD_NOMSI,	"Compaq Smart Array 5i" },
+    { 0x0e11, 0x4082, CISS_BOARD_SA5B|CISS_BOARD_NOMSI,	"Compaq Smart Array 532" },
+    { 0x0e11, 0x4083, CISS_BOARD_SA5B|CISS_BOARD_NOMSI,	"HP Smart Array 5312" },
     { 0x0e11, 0x4091, CISS_BOARD_SA5,	"HP Smart Array 6i" },
     { 0x0e11, 0x409A, CISS_BOARD_SA5,	"HP Smart Array 641" },
     { 0x0e11, 0x409B, CISS_BOARD_SA5,	"HP Smart Array 642" },
@@ -661,7 +663,6 @@ ciss_init_pci(struct ciss_softc *sc)
 	(CISS_TRANSPORT_METHOD_SIMPLE | CISS_TRANSPORT_METHOD_PERF))) {
 	ciss_printf(sc, "No supported transport layers: 0x%x\n",
 	    sc->ciss_cfg->supported_methods);
-	return(ENXIO);
     }
 
     switch (ciss_force_transport) {
@@ -677,7 +678,7 @@ ciss_init_pci(struct ciss_softc *sc)
     }
 
 setup:
-    if (supported_methods & CISS_TRANSPORT_METHOD_PERF) {
+    if ((supported_methods & CISS_TRANSPORT_METHOD_PERF) != 0) {
 	method = CISS_TRANSPORT_METHOD_PERF;
 	sc->ciss_perf = (struct ciss_perf_config *)(cbase + cofs +
 	    sc->ciss_cfg->transport_offset);
@@ -744,7 +745,7 @@ setup:
 	 * controller.  Hopefully enabling this bit universally will work OK.
 	 * It seems to work fine for SA6i controllers.
 	 */
-        sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ | CISS_TL_PERF_INTR_MSI;
+	sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ | CISS_TL_PERF_INTR_MSI;
 
     } else {
 	ciss_printf(sc, "SIMPLE Transport\n");
@@ -792,7 +793,7 @@ setup:
 			   BUS_SPACE_MAXADDR, 		/* highaddr */
 			   NULL, NULL, 			/* filter, filterarg */
 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
-			   CISS_COMMAND_SG_LENGTH,	/* nsegments */
+			   CISS_MAX_SG_ELEMENTS,	/* nsegments */
 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
 			   0,				/* flags */
 			   NULL, NULL,			/* lockfunc, lockarg */
@@ -810,7 +811,7 @@ setup:
 			   BUS_SPACE_MAXADDR,		/* lowaddr */
 			   BUS_SPACE_MAXADDR, 		/* highaddr */
 			   NULL, NULL, 			/* filter, filterarg */
-			   MAXBSIZE, CISS_COMMAND_SG_LENGTH,	/* maxsize, nsegments */
+			   MAXBSIZE, CISS_MAX_SG_ELEMENTS,	/* maxsize, nsegments */
 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
 			   BUS_DMA_ALLOCNOW,		/* flags */
 			   busdma_lock_mutex, &sc->ciss_mtx,	/* lockfunc, lockarg */
@@ -823,32 +824,42 @@ setup:
 
 /************************************************************************
  * Setup MSI/MSIX operation (Performant only)
- * Four interrupts are available, but we only use 1 right now.
+ * Four interrupts are available, but we only use 1 right now.  If MSI-X
+ * isn't avaialble, try using MSI instead.
  */
 static int
 ciss_setup_msix(struct ciss_softc *sc)
 {
-    uint32_t id;
     int val, i;
 
     /* Weed out devices that don't actually support MSI */
-    id = (pci_get_subvendor(sc->ciss_dev) << 16) |
-	pci_get_subdevice(sc->ciss_dev);
-    if ((id == 0x0e114070) || (id == 0x0e114080) || (id == 0x0e114082) ||
-	(id == 0x0e114083))
+    i = ciss_lookup(sc->ciss_dev);
+    if (ciss_vendor_data[i].flags & CISS_BOARD_NOMSI)
 	return (EINVAL);
 
+    /*
+     * Only need to use the minimum number of MSI vectors, as the driver
+     * doesn't support directed MSIX interrupts.
+     */
     val = pci_msix_count(sc->ciss_dev);
-    if (val < CISS_MSI_COUNT)
-	return (EINVAL);
+    if (val < CISS_MSI_COUNT) {
+	val = pci_msi_count(sc->ciss_dev);
+	device_printf(sc->ciss_dev, "got %d MSI messages]\n", val);
+	if (val < CISS_MSI_COUNT)
+	    return (EINVAL);
+    }
     val = MIN(val, CISS_MSI_COUNT);
-    if (pci_alloc_msix(sc->ciss_dev, &val) != 0)
-	return (EINVAL);
+    if (pci_alloc_msix(sc->ciss_dev, &val) != 0) {
+	if (pci_alloc_msi(sc->ciss_dev, &val) != 0)
+	    return (EINVAL);
+    }
 
     sc->ciss_msi = val;
-    ciss_printf(sc, "Using MSIX interrupt\n");
+    if (bootverbose)
+	ciss_printf(sc, "Using %d MSIX interrupt%s\n", val,
+	    (val != 1) ? "s" : "");
 
-    for (i = 0; i < CISS_MSI_COUNT; i++)
+    for (i = 0; i < val; i++)
 	sc->ciss_irq_rid[i] = i + 1;
 
     return (0);
@@ -1031,7 +1042,7 @@ ciss_soft_reset(struct ciss_softc *sc)
 					   NULL, 0)) != 0)
 	    break;
 
-	cc = CISS_FIND_COMMAND(cr);
+	cc = cr->cr_cc;
 	cc->header.address = sc->ciss_controllers[i];
 
 	if ((error = ciss_synch_request(cr, 60 * 1000)) != 0)
@@ -1104,6 +1115,9 @@ ciss_init_requests(struct ciss_softc *sc)
 	cr = &sc->ciss_request[i];
 	cr->cr_sc = sc;
 	cr->cr_tag = i;
+	cr->cr_cc = (struct ciss_command *)((uintptr_t)sc->ciss_command +
+	    CISS_COMMAND_ALLOC_SIZE * i);
+	cr->cr_ccphys = sc->ciss_command_phys + CISS_COMMAND_ALLOC_SIZE * i;
 	bus_dmamap_create(sc->ciss_buffer_dmat, 0, &cr->cr_datamap);
 	ciss_enqueue_free(cr);
     }
@@ -1257,7 +1271,7 @@ ciss_report_luns(struct ciss_softc *sc, int opcode, int nunits)
     /*
      * Build the Report Logical/Physical LUNs command.
      */
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cr->cr_data = cll;
     cr->cr_length = report_size;
     cr->cr_flags = CISS_REQ_DATAIN;
@@ -1582,7 +1596,7 @@ ciss_inquiry_logical(struct ciss_softc *sc, struct ciss_ldrive *ld)
     if ((error = ciss_get_request(sc, &cr)) != 0)
 	goto out;
 
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cr->cr_data = &ld->cl_geometry;
     cr->cr_length = sizeof(ld->cl_geometry);
     cr->cr_flags = CISS_REQ_DATAIN;
@@ -1646,7 +1660,7 @@ ciss_identify_logical(struct ciss_softc *sc, struct ciss_ldrive *ld)
 				       (void **)&ld->cl_ldrive,
 				       sizeof(*ld->cl_ldrive))) != 0)
 	goto out;
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cc->header.address = *ld->cl_controller;	/* target controller */
     cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
     cbc->log_drive = CISS_LUN_TO_TARGET(ld->cl_address.logical.lun);
@@ -1742,7 +1756,7 @@ ciss_get_ldrive_status(struct ciss_softc *sc,  struct ciss_ldrive *ld)
 				       (void **)&ld->cl_lstatus,
 				       sizeof(*ld->cl_lstatus))) != 0)
 	goto out;
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cc->header.address = *ld->cl_controller;	/* target controller */
     cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
     cbc->log_drive = CISS_LUN_TO_TARGET(ld->cl_address.logical.lun);
@@ -1832,7 +1846,7 @@ ciss_accept_media(struct ciss_softc *sc, struct ciss_ldrive *ld)
     if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ACCEPT_MEDIA,
 				       NULL, 0)) != 0)
 	goto out;
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cc->header.address = *ld->cl_controller;	/* target controller */
     cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
     cbc->log_drive = ldrive;
@@ -2000,7 +2014,7 @@ ciss_start(struct ciss_request *cr)
     struct ciss_command	*cc;	/* XXX debugging only */
     int			error;
 
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     debug(2, "post command %d tag %d ", cr->cr_tag, cc->header.host_tag);
 
     /*
@@ -2056,7 +2070,7 @@ ciss_done(struct ciss_softc *sc, cr_qhead_t *qh)
 	    continue;
 	}
 	cr = &(sc->ciss_request[index]);
-	cc = CISS_FIND_COMMAND(cr);
+	cc = cr->cr_cc;
 	cc->header.host_tag = tag;	/* not updated by adapter */
 	ciss_enqueue_complete(cr, qh);
     }
@@ -2085,7 +2099,7 @@ ciss_perf_done(struct ciss_softc *sc, cr_qhead_t *qh)
 	      (tag & CISS_HDR_HOST_TAG_ERROR) ? " with error" : "");
 	if (index < sc->ciss_max_requests) {
 	    cr = &(sc->ciss_request[index]);
-	    cc = CISS_FIND_COMMAND(cr);
+	    cc = cr->cr_cc;
 	    cc->header.host_tag = tag;	/* not updated by adapter */
 	    ciss_enqueue_complete(cr, qh);
 	} else {
@@ -2222,7 +2236,7 @@ _ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_sta
 
     debug_called(2);
 
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     ce = (struct ciss_error_info *)&(cc->sg[0]);
 
     /*
@@ -2369,7 +2383,7 @@ ciss_abort_request(struct ciss_request *ar)
 	return(error);
 
     /* build the abort command */
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cc->header.address.mode.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;	/* addressing? */
     cc->header.address.physical.target = 0;
     cc->header.address.physical.bus = 0;
@@ -2438,12 +2452,12 @@ ciss_preen_command(struct ciss_request *cr)
      * Note that we set up the error_info structure here, since the
      * length can be overwritten by any command.
      */
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cc->header.sg_in_list = 0;		/* kinda inefficient this way */
     cc->header.sg_total = 0;
     cc->header.host_tag = cr->cr_tag << 2;
     cc->header.host_tag_zeroes = 0;
-    cmdphys = CISS_FIND_COMMANDPHYS(cr);
+    cmdphys = cr->cr_ccphys;
     cc->error_info.error_info_address = cmdphys + sizeof(struct ciss_command);
     cc->error_info.error_info_length = CISS_COMMAND_ALLOC_SIZE - sizeof(struct ciss_command);
 }
@@ -2514,7 +2528,7 @@ ciss_get_bmic_request(struct ciss_softc *sc, struct ciss_request **crp,
     if (!dataout)
 	cr->cr_flags = CISS_REQ_DATAIN;
 
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
     cc->header.address.physical.bus = 0;
     cc->header.address.physical.target = 0;
@@ -2562,7 +2576,7 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
      */
     while (ciss_get_request(sc, &cr) != 0)
 	msleep(sc, &sc->ciss_mtx, PPAUSE, "cissREQ", hz);
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
 
     /*
      * Allocate an in-kernel databuffer if required, copy in user data.
@@ -2667,7 +2681,7 @@ ciss_map_request(struct ciss_request *cr)
 	if (sc->ciss_perf)
 	    CISS_TL_PERF_POST_CMD(sc, cr);
 	else
-	    CISS_TL_SIMPLE_POST_CMD(sc, CISS_FIND_COMMANDPHYS(cr));
+	    CISS_TL_SIMPLE_POST_CMD(sc, cr->cr_ccphys);
     }
 
     return(0);
@@ -2685,7 +2699,7 @@ ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 
     cr = (struct ciss_request *)arg;
     sc = cr->cr_sc;
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
 
     for (i = 0; i < nseg; i++) {
 	cc->sg[i].address = segs[i].ds_addr;
@@ -2725,7 +2739,7 @@ ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
     if (sc->ciss_perf)
 	CISS_TL_PERF_POST_CMD(sc, cr);
     else
-	CISS_TL_SIMPLE_POST_CMD(sc, CISS_FIND_COMMANDPHYS(cr));
+	CISS_TL_SIMPLE_POST_CMD(sc, cr->cr_ccphys);
 }
 
 /************************************************************************
@@ -3091,7 +3105,7 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
     /*
      * Build the command.
      */
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cr->cr_data = csio->data_ptr;
     cr->cr_length = csio->dxfer_len;
     cr->cr_complete = ciss_cam_complete;
@@ -3235,7 +3249,7 @@ ciss_cam_complete(struct ciss_request *cr)
     debug_called(2);
 
     sc = cr->cr_sc;
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     ce = (struct ciss_error_info *)&(cc->sg[0]);
     csio = (struct ccb_scsiio *)cr->cr_private;
 
@@ -3414,7 +3428,7 @@ ciss_periodic(void *arg)
      * Send the NOP message and wait for a response.
      */
     if (ciss_nop_message_heartbeat != 0 && (error = ciss_get_request(sc, &cr)) == 0) {
-	cc = CISS_FIND_COMMAND(cr);
+	cc = cr->cr_cc;
 	cr->cr_complete = ciss_nop_complete;
 	cc->cdb.cdb_length = 1;
 	cc->cdb.type = CISS_CDB_TYPE_MESSAGE;
@@ -3484,7 +3498,7 @@ ciss_disable_adapter(struct ciss_softc *sc)
 	if ((cr->cr_flags & CISS_REQ_BUSY) == 0)
 	    continue;
 
-	cc = CISS_FIND_COMMAND(cr);
+	cc = cr->cr_cc;
 	ce = (struct ciss_error_info *)&(cc->sg[0]);
 	ce->command_status = CISS_CMD_STATUS_HARDWARE_ERROR;
 	ciss_enqueue_complete(cr, &qh);
@@ -3561,7 +3575,7 @@ ciss_notify_event(struct ciss_softc *sc)
     ciss_preen_command(cr);
 
     /* (re)build the notify event command */
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
     cc->header.address.physical.bus = 0;
     cc->header.address.physical.target = 0;
@@ -3615,7 +3629,7 @@ ciss_notify_complete(struct ciss_request *cr)
     int			command_status;
     debug_called(1);
 
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cn = (struct ciss_notify *)cr->cr_data;
     sc = cr->cr_sc;
 
@@ -3715,7 +3729,7 @@ ciss_notify_abort(struct ciss_softc *sc)
     cr->cr_length = CISS_NOTIFY_DATA_SIZE;
 
     /* build the CDB */
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
     cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
     cc->header.address.physical.bus = 0;
     cc->header.address.physical.target = 0;
@@ -4174,7 +4188,7 @@ ciss_print_request(struct ciss_request *cr)
     int			i;
 
     sc = cr->cr_sc;
-    cc = CISS_FIND_COMMAND(cr);
+    cc = cr->cr_cc;
 
     ciss_printf(sc, "REQUEST @ %p\n", cr);
     ciss_printf(sc, "  data %p/%d  tag %d  flags %b\n",
diff --git a/sys/dev/ciss/cissreg.h b/sys/dev/ciss/cissreg.h
index 9ed631b4ad7..feae826815f 100644
--- a/sys/dev/ciss/cissreg.h
+++ b/sys/dev/ciss/cissreg.h
@@ -731,7 +731,7 @@ struct ciss_bmic_flush_cache {
 #define CISS_TL_PERF_INTR_OPQ	(CISS_TL_SIMPLE_INTR_OPQ_SA5 | CISS_TL_SIMPLE_INTR_OPQ_SA5B)
 #define CISS_TL_PERF_INTR_MSI	0x01
 
-#define CISS_TL_PERF_POST_CMD(sc, cr)		CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IPQ, CISS_FIND_COMMANDPHYS(cr) | (cr)->cr_sg_tag)
+#define CISS_TL_PERF_POST_CMD(sc, cr)		CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IPQ, cr->cr_ccphys | (cr)->cr_sg_tag)
 #define CISS_TL_PERF_FLUSH_INT(sc)		CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_OSR)
 #define CISS_TL_PERF_CLEAR_INT(sc)		CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_ODC, CISS_TL_SIMPLE_ODC_CLEAR)
 #define CISS_CYCLE_MASK		0x00000001
@@ -747,4 +747,5 @@ struct ciss_bmic_flush_cache {
 			     CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IMR) & ~(sc)->ciss_interrupt_mask)
 
 
+
 #endif /* _KERNEL */
diff --git a/sys/dev/ciss/cissvar.h b/sys/dev/ciss/cissvar.h
index 98e875fbf30..3bad2b3b292 100644
--- a/sys/dev/ciss/cissvar.h
+++ b/sys/dev/ciss/cissvar.h
@@ -103,6 +103,8 @@ struct ciss_request
     void			*cr_data;	/* data buffer */
     u_int32_t			cr_length;	/* data length */
     bus_dmamap_t		cr_datamap;	/* DMA map for data */
+    struct ciss_command		*cr_cc;
+    uint32_t			cr_ccphys;
     int				cr_tag;
     int				cr_flags;
 #define CISS_REQ_MAPPED		(1<<0)		/* data mapped */
@@ -131,18 +133,16 @@ struct ciss_request
  * scatter-gather list, and we also want to avoid having commands
  * cross page boundaries.
  *
- * Note that 512 bytes yields 28 scatter/gather entries, or the
- * ability to map (26 * PAGE_SIZE) + 2 bytes of data.  On x86, this is
- * 104kB.  256 bytes would only yield 12 entries, giving a mere 40kB,
- * too small.
+ * The size of the ciss_command is 52 bytes.  65 s/g elements are reserved
+ * to allow a max i/o size of 256k.  This gives a total command size of
+ * 1120 bytes, including the 32 byte alignment padding.  Modern controllers
+ * seem to saturate nicely at this value.
  */
 
-#define CISS_COMMAND_ALLOC_SIZE		512	/* XXX tune to get sensible s/g list length */
-#define CISS_COMMAND_SG_LENGTH	((CISS_COMMAND_ALLOC_SIZE - sizeof(struct ciss_command)) \
-				 / sizeof(struct ciss_sg_entry))
-
-/* XXX Prep for increasing max i/o */
-#define CISS_MAX_SG_ELEMENTS   17
+#define CISS_MAX_SG_ELEMENTS	65
+#define CISS_COMMAND_ALIGN	32
+#define CISS_COMMAND_SG_LENGTH	(sizeof(struct ciss_sg_entry) * CISS_MAX_SG_ELEMENTS)
+#define CISS_COMMAND_ALLOC_SIZE		(roundup2(sizeof(struct ciss_command) + CISS_COMMAND_SG_LENGTH, CISS_COMMAND_ALIGN))
 
 /*
  * Per-logical-drive data.
@@ -259,20 +259,6 @@ struct ciss_softc
     struct ciss_qstat		ciss_qstat[CISSQ_COUNT];	/* queue statistics */
 };
 
-/*
- * Given a request tag, find the corresponding command in virtual or
- * physical space.
- *
- * The arithmetic here is due to the allocation of ciss_command structures
- * inside CISS_COMMAND_ALLOC_SIZE blocks.  See the comment at the definition
- * of CISS_COMMAND_ALLOC_SIZE above.
- */
-#define CISS_FIND_COMMAND(cr)							\
-	(struct ciss_command *)((u_int8_t *)(cr)->cr_sc->ciss_command +		\
-				((cr)->cr_tag * CISS_COMMAND_ALLOC_SIZE))
-#define CISS_FIND_COMMANDPHYS(cr)	((cr)->cr_sc->ciss_command_phys + \
-					 ((cr)->cr_tag * CISS_COMMAND_ALLOC_SIZE))
-
 /************************************************************************
  * Debugging/diagnostic output.
  */

From 52bd177ff76578c2388819807b5b6f2ce8879c08 Mon Sep 17 00:00:00 2001
From: Tim Kientzle 
Date: Thu, 17 Sep 2009 06:31:59 +0000
Subject: [PATCH 0252/2592] MFC r196962: Fix /usr/bin/unzip: A bug deep in
 libarchive's read-ahead logic (incorrect handling of zero-length reads before
 the copy buffer is allocated) is masked by the iso9660 taster.  Tar and cpio
 both enable that taster so were protected from the bug; unzip is susceptible.

This both fixes the bug and updates the test harness to exercise
this case.

Submitted by: Ed Schouten diagnosed the bug and drafted a patch
Approved by:	re (kib)
---
 lib/libarchive/archive_read.c         | 7 +++++--
 lib/libarchive/test/test_compat_zip.c | 2 +-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c
index 9274d661cc4..fd4f888867b 100644
--- a/lib/libarchive/archive_read.c
+++ b/lib/libarchive/archive_read.c
@@ -928,9 +928,12 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
 	for (;;) {
 
 		/*
-		 * If we can satisfy from the copy buffer, we're done.
+		 * If we can satisfy from the copy buffer (and the
+		 * copy buffer isn't empty), we're done.  In particular,
+		 * note that min == 0 is a perfectly well-defined
+		 * request.
 		 */
-		if (filter->avail >= min) {
+		if (filter->avail >= min && filter->avail > 0) {
 			if (avail != NULL)
 				*avail = filter->avail;
 			return (filter->next);
diff --git a/lib/libarchive/test/test_compat_zip.c b/lib/libarchive/test/test_compat_zip.c
index f60bc4f817a..fefc6fefabd 100644
--- a/lib/libarchive/test/test_compat_zip.c
+++ b/lib/libarchive/test/test_compat_zip.c
@@ -36,7 +36,7 @@ test_compat_zip_1(void)
 
 	assert((a = archive_read_new()) != NULL);
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
-	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
 	extract_reference_file(name);
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
 

From 1fe6ff92670db106ea5ead32ca781df8168d73e1 Mon Sep 17 00:00:00 2001
From: Marko Zec 
Date: Thu, 17 Sep 2009 11:03:37 +0000
Subject: [PATCH 0253/2592] MFC r197176:

  Lock the ifnet list while iterating over it.

  Submitted by: julian
  MFC after:    3 days

Approved by:	re (kensmith)
---
 sys/compat/linux/linux_ioctl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index 8acc5929258..7688fe51db5 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -2152,6 +2152,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc)
 	/* handle the 'request buffer size' case */
 	if (ifc.ifc_buf == PTROUT(NULL)) {
 		ifc.ifc_len = 0;
+		IFNET_RLOCK();
 		TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
 			TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
 				struct sockaddr *sa = ifa->ifa_addr;
@@ -2159,6 +2160,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc)
 					ifc.ifc_len += sizeof(ifr);
 			}
 		}
+		IFNET_RUNLOCK();
 		error = copyout(&ifc, uifc, sizeof(ifc));
 		CURVNET_RESTORE();
 		return (error);

From 04793894d4f0f2e657f7b0c61b850220c5c06281 Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Thu, 17 Sep 2009 12:41:27 +0000
Subject: [PATCH 0254/2592] MFC r197077: pci: remove definitions of duplicate
 constants

Suggested by:	jhb
Reviewed by:	jhb
Approved by:	re (kib)
---
 sys/dev/pci/pcireg.h | 10 +++++-----
 sys/dev/pci/pcivar.h |  7 -------
 2 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index c3521477085..c7a7245bf1d 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -39,11 +39,11 @@
  */
 
 /* some PCI bus constants */
-
-#define	PCI_BUSMAX	255
-#define	PCI_SLOTMAX	31
-#define	PCI_FUNCMAX	7
-#define	PCI_REGMAX	255
+#define	PCI_DOMAINMAX	65535	/* highest supported domain number */
+#define	PCI_BUSMAX	255	/* highest supported bus number */
+#define	PCI_SLOTMAX	31	/* highest supported slot number */
+#define	PCI_FUNCMAX	7	/* highest supported function number */
+#define	PCI_REGMAX	255	/* highest supported config register addr. */
 #define	PCI_MAXHDRTYPE	2
 
 /* PCI config header registers for all devices */
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 36ae2134d3b..d7de96e6562 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -33,13 +33,6 @@
 #include 
 
 /* some PCI bus constants */
-
-#define	PCI_DOMAINMAX	65535	/* highest supported domain number */
-#define	PCI_BUSMAX	255	/* highest supported bus number */
-#define	PCI_SLOTMAX	31	/* highest supported slot number */
-#define	PCI_FUNCMAX	7	/* highest supported function number */
-#define	PCI_REGMAX	255	/* highest supported config register addr. */
-
 #define	PCI_MAXMAPS_0	6	/* max. no. of memory/port maps */
 #define	PCI_MAXMAPS_1	2	/* max. no. of maps for PCI to PCI bridge */
 #define	PCI_MAXMAPS_2	1	/* max. no. of maps for CardBus bridge */

From bfcfe776058bc7aac028a6dfea2efaad30401d51 Mon Sep 17 00:00:00 2001
From: Bruce M Simpson 
Date: Thu, 17 Sep 2009 13:41:59 +0000
Subject: [PATCH 0255/2592] MFC revs 197129,197130,197132:  Fixes to mcast
 userland API. --   Fix an API issue in leave processing for IPv4 multicast
 groups.    * Do not assume that the group lookup performed by
 imo_match_group()      is valid when ifp is NULL in this case.    * Instead,
 return EADDRNOTAVAIL if the ifp cannot be resolved for the      membership we
 are being asked to leave.

  Caveat user:
   * The way IPv4 multicast memberships are implemented in the inpcb layer
     at the moment, has the side-effect that struct ip_moptions will
     still hold the membership, under the old ifp, until ip_freemoptions()
     is called for the parent inpcb.
   * The underlying issue is: the inpcb layer does not get notification
     of ifp being detached going away in a thread-safe manner.
     This is non-trivial to fix.
--
  Fix an obvious logic error in the IPv4 multicast leave processing,
  where the filter mode vector was not updated correctly after the leave.
--
  Tighten input checking in inp_join_group():
   * Don't try to use the source address, when its family is unspecified.
   * If we get a join without a source, on an existing inclusive
     mode group, this is an error, as it would change the filter mode.

  Fix a problem with the handling of in_mfilter for new memberships:
   * Do not rely on imf being NULL; it is explicitly initialized to a
     non-NULL pointer when constructing a membership.
   * Explicitly initialize *imf to EX mode when the source address
     is unspecified.
  This fixes a problem with in_mfilter slot recycling in the join path.
--
  Don't allow joins w/o source on an existing group.
  This is almost always pilot error.

  We don't need to check for group filter UNDEFINED state at t1,
  because we only ever allocate filters with their groups, so we
  unconditionally reject such calls with EINVAL.
  Trying to change the active filter mode w/o going through IP_MSFILTER
  is also disallowed.

  Deals with the case described in PR 137164 upfront, cumulative
  with the fix in svn rev 197132 which only calls imo_match_source()
  if the source address family was not unspecified.
--

Revision 197136 has a text conflict, however it is a comment only change.

PR:		137164, 138689, 138690, 138691
Submitted by:	Stef Walter (with fixups)
Approved by:	re (kib)
---
 sys/netinet/in_mcast.c | 59 ++++++++++++++++++++++++++++++------------
 1 file changed, 42 insertions(+), 17 deletions(-)

diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
index 9a828210cc6..3dd090850e7 100644
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -1957,11 +1957,6 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 	if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0)
 		return (EADDRNOTAVAIL);
 
-	/*
-	 * MCAST_JOIN_SOURCE on an exclusive membership is an error.
-	 * On an existing inclusive membership, it just adds the
-	 * source to the filter list.
-	 */
 	imo = inp_findmoptions(inp);
 	idx = imo_match_group(imo, ifp, &gsa->sa);
 	if (idx == -1) {
@@ -1969,15 +1964,33 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 	} else {
 		inm = imo->imo_membership[idx];
 		imf = &imo->imo_mfilters[idx];
-		if (ssa->ss.ss_family != AF_UNSPEC &&
-		    imf->imf_st[1] != MCAST_INCLUDE) {
-			error = EINVAL;
-			goto out_inp_locked;
-		}
-		lims = imo_match_source(imo, idx, &ssa->sa);
-		if (lims != NULL) {
-			error = EADDRNOTAVAIL;
-			goto out_inp_locked;
+		if (ssa->ss.ss_family != AF_UNSPEC) {
+			/*
+			 * MCAST_JOIN_SOURCE on an exclusive membership
+			 * is an error. On an existing inclusive membership,
+			 * it just adds the source to the filter list.
+			 */
+			if (imf->imf_st[1] != MCAST_INCLUDE) {
+				error = EINVAL;
+				goto out_inp_locked;
+			}
+			/* Throw out duplicates. */
+			lims = imo_match_source(imo, idx, &ssa->sa);
+			if (lims != NULL) {
+				error = EADDRNOTAVAIL;
+				goto out_inp_locked;
+			}
+		} else {
+			/*
+			 * MCAST_JOIN_GROUP on an existing inclusive
+			 * membership is an error; if you want to change
+			 * filter mode, you must use the userland API
+			 * setsourcefilter().
+			 */
+			if (imf->imf_st[1] == MCAST_INCLUDE) {
+				error = EINVAL;
+				goto out_inp_locked;
+			}
 		}
 	}
 
@@ -2010,7 +2023,8 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 	/*
 	 * Graft new source into filter list for this inpcb's
 	 * membership of the group. The in_multi may not have
-	 * been allocated yet if this is a new membership.
+	 * been allocated yet if this is a new membership, however,
+	 * the in_mfilter slot will be allocated and must be initialized.
 	 */
 	if (ssa->ss.ss_family != AF_UNSPEC) {
 		/* Membership starts in IN mode */
@@ -2027,6 +2041,12 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 			error = ENOMEM;
 			goto out_imo_free;
 		}
+	} else {
+		/* No address specified; Membership starts in EX mode */
+		if (is_new) {
+			CTR1(KTR_IGMPV3, "%s: new join w/o source", __func__);
+			imf_init(imf, MCAST_UNDEFINED, MCAST_EXCLUDE);
+		}
 	}
 
 	/*
@@ -2189,6 +2209,9 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
 	if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
 		return (EINVAL);
 
+	if (ifp == NULL)
+		return (EADDRNOTAVAIL);
+
 	/*
 	 * Find the membership in the membership array.
 	 */
@@ -2275,9 +2298,11 @@ out_imf_rollback:
 	imf_reap(imf);
 
 	if (is_final) {
-		/* Remove the gap in the membership array. */
-		for (++idx; idx < imo->imo_num_memberships; ++idx)
+		/* Remove the gap in the membership and filter array. */
+		for (++idx; idx < imo->imo_num_memberships; ++idx) {
 			imo->imo_membership[idx-1] = imo->imo_membership[idx];
+			imo->imo_mfilters[idx-1] = imo->imo_mfilters[idx];
+		}
 		imo->imo_num_memberships--;
 	}
 

From 5895f2dd9fb8af27a6e1e1a0160683629d80e558 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Thu, 17 Sep 2009 14:05:06 +0000
Subject: [PATCH 0256/2592] Get ready for 8.0-RC1 builds.

Approved by:	re (implicit)
---
 sys/conf/newvers.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index adf87ba9bcc..beb37c6febd 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="8.0"
-BRANCH="BETA4"
+BRANCH="RC1"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

From 9febd63ce15e1251f0326e0b060e501495ce6f99 Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Thu, 17 Sep 2009 14:12:21 +0000
Subject: [PATCH 0257/2592] MFC: r197156

  MFi386:

  Move the loader's entry point to 0x200000.  This change is also needed
  for pc98.

Approved by:	re (kensmith)
---
 sys/boot/pc98/Makefile.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/boot/pc98/Makefile.inc b/sys/boot/pc98/Makefile.inc
index 418394a0963..54d4431e936 100644
--- a/sys/boot/pc98/Makefile.inc
+++ b/sys/boot/pc98/Makefile.inc
@@ -4,7 +4,7 @@
 
 BINDIR?=	/boot
 
-LOADER_ADDRESS?=0x100000
+LOADER_ADDRESS?=0x200000
 CFLAGS+=	-ffreestanding -mpreferred-stack-boundary=2 \
 		-mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
 		-Os

From 43eb6aeda0df01428eec21623ec40b797cf72198 Mon Sep 17 00:00:00 2001
From: "Kenneth D. Merry" 
Date: Fri, 18 Sep 2009 20:35:05 +0000
Subject: [PATCH 0258/2592] Merge change r197208 from head to stable/8:

Fix some instances where CAM rescans get hung up or take a long time to
complete.

Also, allow xpt_rescan() to rescan a LUN instead of a full bus.

Sponsored by:	Copan Systems, Inc.
Approved by:	re (kib)
---
 sys/cam/cam_xpt.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 1c2f61430a6..bfa00476d96 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -794,8 +794,9 @@ xpt_scanner_thread(void *dummy)
 		 * processed.
 		 */
 		xpt_lock_buses();
-		msleep(&xsoftc.ccb_scanq, &xsoftc.xpt_topo_lock, PRIBIO,
-		    "ccb_scanq", 0);
+		if (TAILQ_EMPTY(&xsoftc.ccb_scanq))
+			msleep(&xsoftc.ccb_scanq, &xsoftc.xpt_topo_lock, PRIBIO,
+			       "ccb_scanq", 0);
 		TAILQ_INIT(&queue);
 		TAILQ_CONCAT(&queue, &xsoftc.ccb_scanq, sim_links.tqe);
 		xpt_unlock_buses();
@@ -806,9 +807,12 @@ xpt_scanner_thread(void *dummy)
 			sim = ccb->ccb_h.path->bus->sim;
 			CAM_SIM_LOCK(sim);
 
-			ccb->ccb_h.func_code = XPT_SCAN_BUS;
+			if( ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD )
+				ccb->ccb_h.func_code = XPT_SCAN_BUS;
+			else
+				ccb->ccb_h.func_code = XPT_SCAN_LUN;
 			ccb->ccb_h.cbfcnp = xptdone;
-			xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 5);
+			xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 1);
 			cam_periph_runccb(ccb, NULL, 0, 0, NULL);
 			xpt_free_path(ccb->ccb_h.path);
 			xpt_free_ccb(ccb);
@@ -828,6 +832,7 @@ xpt_rescan(union ccb *ccb)
 	xpt_lock_buses();
 	TAILQ_FOREACH(hdr, &xsoftc.ccb_scanq, sim_links.tqe) {
 		if (xpt_path_comp(hdr->path, ccb->ccb_h.path) == 0) {
+			wakeup(&xsoftc.ccb_scanq);
 			xpt_unlock_buses();
 			xpt_print(ccb->ccb_h.path, "rescan already queued\n");
 			xpt_free_path(ccb->ccb_h.path);

From ec468671055a021aa3cbb841d55e7a2e4e886118 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Sat, 19 Sep 2009 01:48:12 +0000
Subject: [PATCH 0259/2592] MFC r196993

Remove some debugging (KTR_VERBOSE) that crept into ppc GENERIC long ago
and is present on no other architectures by default.

Reviewed by:	grehan
Approved by:	re (kib)
---
 sys/powerpc/conf/GENERIC | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index 51bf6c7dfef..2098f28c9df 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -162,7 +162,3 @@ device		pmu
 device		iicbus		# I2C bus code
 device		kiic		# Keywest I2C
 
-options 	KTR
-options 	KTR_COMPILE=0xffffffff
-#options 	KTR_MASK=KTR_SIG
-options 	KTR_VERBOSE

From 3f12b2cdd4f5e2f19589e8b3ace5a0d272c846ae Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Sat, 19 Sep 2009 01:49:36 +0000
Subject: [PATCH 0260/2592] MFC r197080

Add a few SCSI controllers to GENERIC that can be found in Powermacs.
This allows installation onto SCSI disks as shipped, for example,
as an option with the Powermac G3.

PR:		powerpc/138543
Reviewed by:	grehan
Approved by:	re (kib)
Obtained from:	sparc64
---
 sys/powerpc/conf/GENERIC | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index 2098f28c9df..1b941a2ac26 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -83,6 +83,16 @@ device		atapicd		# ATAPI CDROM drives
 #device		atapifd		# ATAPI floppy drives
 #device		atapist		# ATAPI tape drives
 
+# SCSI Controllers
+device		ahc		# AHA2940 and onboard AIC7xxx devices
+options 	AHC_ALLOW_MEMIO	# Attempt to use memory mapped I/O
+options 	AHC_REG_PRETTY_PRINT	# Print register bitfields in debug
+					# output.  Adds ~128k to driver.
+device		isp		# Qlogic family
+device		ispfw		# Firmware module for Qlogic host adapters
+device		mpt		# LSI-Logic MPT-Fusion
+device		sym		# NCR/Symbios/LSI Logic 53C8XX/53C1010/53C1510D
+
 # SCSI peripherals
 device		scbus		# SCSI bus (required for SCSI)
 device		da		# Direct Access (disks)
@@ -119,6 +129,7 @@ device		md		# Memory "disks"
 device		ofwd		# Open Firmware disks
 device		gif		# IPv6 and IPv4 tunneling
 device		faith		# IPv6-to-IPv4 relaying/(translation)
+device		firmware	# firmware assist module
 
 # The `bpf' device enables the Berkeley Packet Filter.
 # Be aware of the administrative consequences of enabling this!

From 1a7268649b0c4e67c3780c9c9aa1305744e7d9b8 Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sat, 19 Sep 2009 08:13:10 +0000
Subject: [PATCH 0261/2592] MFC r197099: pci(4): don't perform maximum register
 number check

Different sub-kinds of PCI buses may have different rules and
thus it is up for the bus backends to do proper input checks.
For example, PCIe allows configuration register numbers < 0x1000,
while for PCI proper the limit is 0x100.
And, in fact, the buses already do the checks.

Reviewed by:	jhb
Approved by:	re (kib)
---
 sys/dev/pci/pci_user.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sys/dev/pci/pci_user.c b/sys/dev/pci/pci_user.c
index ed753539f6d..8ab0a01eb8e 100644
--- a/sys/dev/pci/pci_user.c
+++ b/sys/dev/pci/pci_user.c
@@ -605,9 +605,8 @@ getconfexit:
 		case 4:
 		case 2:
 		case 1:
-			/* Make sure register is in bounds and aligned. */
+			/* Make sure register is not negative and aligned. */
 			if (io->pi_reg < 0 ||
-			    io->pi_reg + io->pi_width > PCI_REGMAX + 1 ||
 			    io->pi_reg & (io->pi_width - 1)) {
 				error = EINVAL;
 				break;

From 8cb7f8f861c9df1ebd8fcc67a4c640acd6d8149e Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Sun, 20 Sep 2009 17:46:56 +0000
Subject: [PATCH 0262/2592] MFC	r197364

A wrong variable is used when setting up the interface
address route, which broke source address selection in
some code paths.

Submitted by:	noted by bz
Reviewed by:	hrs
Approved by:	re (kib)
---
 sys/net/if.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/net/if.c b/sys/net/if.c
index c0ff443d6dc..55de666a636 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1432,9 +1432,9 @@ ifa_add_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
 	if (error == 0 && rt != NULL) {
 		RT_LOCK(rt);
 		((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
-			rt->rt_ifp->if_type;
+			ifa->ifa_ifp->if_type;
 		((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
-			rt->rt_ifp->if_index;
+			ifa->ifa_ifp->if_index;
 		RT_REMREF(rt);
 		RT_UNLOCK(rt);
 	} else if (error != 0)

From d414bb00bb0ae1c5e8d11469062bc77817a87ad5 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Tue, 22 Sep 2009 20:31:32 +0000
Subject: [PATCH 0263/2592] MFC 197190:  Make the sudden motion sensor work on
 older models and add a bit of  debugging.

 Submitted by:	Christoph Langguth 

Approved by:	re (kib)
---
 sys/dev/asmc/asmc.c    | 125 ++++++++++++++++++++++++++++++++++++++++-
 sys/dev/asmc/asmcvar.h |   1 +
 2 files changed, 123 insertions(+), 3 deletions(-)

diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c
index 7f7f0314014..5fc8c4128cb 100644
--- a/sys/dev/asmc/asmc.c
+++ b/sys/dev/asmc/asmc.c
@@ -86,6 +86,10 @@ static void 	asmc_sms_handler(void *arg);
 #endif
 static void 	asmc_sms_printintr(device_t dev, uint8_t);
 static void 	asmc_sms_task(void *arg, int pending);
+#ifdef DEBUG
+void		asmc_dumpall(device_t);
+static int	asmc_key_dump(device_t, int);
+#endif
 
 /*
  * Model functions.
@@ -532,6 +536,17 @@ asmc_detach(device_t dev)
 	return (0);
 }
 
+#ifdef DEBUG
+void asmc_dumpall(device_t dev)
+{
+	int i;
+
+	/* XXX magic number */
+	for (i=0; i < 0x100; i++)
+		asmc_key_dump(dev, i);
+}
+#endif
+
 static int
 asmc_init(device_t dev)
 {
@@ -584,13 +599,17 @@ asmc_init(device_t dev)
 	asmc_key_write(dev, ASMC_KEY_SMS_FLAG, buf, 1);
 	DELAY(100);
 
+	sc->sc_sms_intr_works = 0;
+	
 	/*
-	 * Wait up to 5 seconds for SMS initialization.
+	 * Retry SMS initialization 1000 times
+	 * (takes approx. 2 seconds in worst case)
 	 */
-	for (i = 0; i < 10000; i++) {
+	for (i = 0; i < 1000; i++) {
 		if (asmc_key_read(dev, ASMC_KEY_SMS, buf, 2) == 0 && 
-		    (buf[0] != 0x00 || buf[1] != 0x00)) {
+		    (buf[0] == ASMC_SMS_INIT1 && buf[1] == ASMC_SMS_INIT2)) {
 			error = 0;
+			sc->sc_sms_intr_works = 1;
 			goto out;
 		}
 		buf[0] = ASMC_SMS_INIT1;
@@ -620,6 +639,10 @@ nosms:
 		device_printf(dev, "number of keys: %d\n", buf[3]);
 	}	      
 
+#ifdef DEBUG
+	asmc_dumpall(dev);
+#endif
+
 	return (error);
 }
 
@@ -729,6 +752,100 @@ out:
 	return (error);
 }
 
+#ifdef DEBUG
+static int
+asmc_key_dump(device_t dev, int number)
+{
+	struct asmc_softc *sc = device_get_softc(dev);
+	char key[5] = { 0 };
+	char type[7] = { 0 };
+	uint8_t index[4];
+	uint8_t v[32];
+	uint8_t maxlen;
+	int i, error = 1, try = 0;
+
+	mtx_lock_spin(&sc->sc_mtx);
+
+	index[0] = (number >> 24) & 0xff;
+	index[1] = (number >> 16) & 0xff;
+	index[2] = (number >> 8) & 0xff;
+	index[3] = (number) & 0xff;
+
+begin:
+	if (asmc_command(dev, 0x12))
+		goto out;
+
+	for (i = 0; i < 4; i++) {
+		ASMC_DATAPORT_WRITE(sc, index[i]);
+		if (asmc_wait(dev, 0x04))
+			goto out;
+	}
+
+	ASMC_DATAPORT_WRITE(sc, 4);
+
+	for (i = 0; i < 4; i++) {
+		if (asmc_wait(dev, 0x05))
+			goto out;
+		key[i] = ASMC_DATAPORT_READ(sc);
+	}
+
+	/* get type */
+	if (asmc_command(dev, 0x13))
+		goto out;
+
+	for (i = 0; i < 4; i++) {
+		ASMC_DATAPORT_WRITE(sc, key[i]);
+		if (asmc_wait(dev, 0x04))
+			goto out;
+	}
+
+	ASMC_DATAPORT_WRITE(sc, 6);
+
+	for (i = 0; i < 6; i++) {
+		if (asmc_wait(dev, 0x05))
+			goto out;
+		type[i] = ASMC_DATAPORT_READ(sc);
+	}
+
+	error = 0;
+out:
+	if (error) {
+		if (++try < 10) goto begin;
+		device_printf(dev,"%s for key %s failed %d times, giving up\n",
+			__func__, key, try);
+		mtx_unlock_spin(&sc->sc_mtx);
+	}
+	else {
+		char buf[1024];
+		char buf2[8];
+		mtx_unlock_spin(&sc->sc_mtx);
+		maxlen = type[0];
+		type[0] = ' ';
+		type[5] = 0;
+		if (maxlen > sizeof(v)) {	
+			device_printf(dev,
+			    "WARNING: cropping maxlen from %d to %zu\n",
+			    maxlen, sizeof(v));
+			maxlen = sizeof(v);
+		}
+		for (i = 0; i < sizeof(v); i++) {
+			v[i] = 0;
+		}
+		asmc_key_read(dev, key, v, maxlen);
+		snprintf(buf, sizeof(buf), "key %d is: %s, type %s "
+		    "(len %d), data", number, key, type, maxlen);
+		for (i = 0; i < maxlen; i++) {
+			snprintf(buf2, sizeof(buf), " %02x", v[i]);
+			strlcat(buf, buf2, sizeof(buf));
+		}
+		strlcat(buf, " \n", sizeof(buf));
+		device_printf(dev, buf);
+	}
+
+	return (error);
+}
+#endif
+
 static int
 asmc_key_write(device_t dev, const char *key, uint8_t *buf, uint8_t len)
 {
@@ -945,6 +1062,8 @@ asmc_sms_intrfast(void *arg)
 	uint8_t type;
 	device_t dev = (device_t) arg;
 	struct asmc_softc *sc = device_get_softc(dev);
+	if (!sc->sc_sms_intr_works)
+		return (FILTER_HANDLED);
 
 	mtx_lock_spin(&sc->sc_mtx);
 	type = ASMC_INTPORT_READ(sc);
diff --git a/sys/dev/asmc/asmcvar.h b/sys/dev/asmc/asmcvar.h
index 0a679d7464e..11156d712b0 100644
--- a/sys/dev/asmc/asmcvar.h
+++ b/sys/dev/asmc/asmcvar.h
@@ -49,6 +49,7 @@ struct asmc_softc {
 	int 			sc_sms_intrtype;
 	struct taskqueue 	*sc_sms_tq;
 	struct task 		sc_sms_task;
+	uint8_t			sc_sms_intr_works;
 };
 
 /*

From 24bf98b17be822f186dc98221337454556e870bc Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 23 Sep 2009 10:12:58 +0000
Subject: [PATCH 0264/2592] MFC: r197368

- Update the list of known-working machines based on feedback for 7.2.
- Update the V440 entry regarding added support for the on-board NICs
  in 8.0.

Approved by:	re (kib), blackend
---
 release/doc/en_US.ISO8859-1/hardware/article.sgml | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/release/doc/en_US.ISO8859-1/hardware/article.sgml b/release/doc/en_US.ISO8859-1/hardware/article.sgml
index 93d4d7ab199..53302c66027 100644
--- a/release/doc/en_US.ISO8859-1/hardware/article.sgml
+++ b/release/doc/en_US.ISO8859-1/hardware/article.sgml
@@ -502,6 +502,10 @@
 	  &sun.blade; 2000
 	
 
+	
+	  &sun.blade; 2500
+	
+
 	
 	  &sun.fire; 280R
 	
@@ -511,7 +515,12 @@
 	
 
 	
-	  &sun.fire; V440 (except for the on-board NICs)
+	  &sun.fire; V250
+	
+
+	
+	  &sun.fire; V440 (support for the on-board NICs first
+	    appeared in 8.0-RELEASE)
 	
 
 	

From 2c5f9fbe6af79b7db28765c2aec88e442410914f Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Wed, 23 Sep 2009 13:49:41 +0000
Subject: [PATCH 0265/2592] MFC r197348: For a.out and pre-8 ELF binaries,
 allow the mmap of zero length.

Approved by:	re (kensmith)
---
 sys/vm/vm_mmap.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 2b99e3653df..c8d25ee3a30 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -229,7 +230,8 @@ mmap(td, uap)
 
 	fp = NULL;
 	/* make sure mapping fits into numeric range etc */
-	if (uap->len == 0 ||
+	if ((uap->len == 0 && !SV_CURPROC_FLAG(SV_AOUT) &&
+	     curproc->p_osrel >= 800104) ||
 	    ((flags & MAP_ANON) && uap->fd != -1))
 		return (EINVAL);
 

From 4e36c32793ae7823c2366793663cc90caee41506 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 23 Sep 2009 15:56:09 +0000
Subject: [PATCH 0266/2592] MFC 197350: Re-remove the IBM0057 ID used for PS/2
 mouse controllers.  The asl for the 61p includes the hotkey device as IBM0068
 and the mouse as IBM0057 similar to other systems.

Approved by:	re (kensmith)
---
 sys/dev/acpi_support/acpi_ibm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/acpi_support/acpi_ibm.c b/sys/dev/acpi_support/acpi_ibm.c
index 0bf340dd5ec..072c574acac 100644
--- a/sys/dev/acpi_support/acpi_ibm.c
+++ b/sys/dev/acpi_support/acpi_ibm.c
@@ -288,7 +288,7 @@ static devclass_t acpi_ibm_devclass;
 DRIVER_MODULE(acpi_ibm, acpi, acpi_ibm_driver, acpi_ibm_devclass,
 	      0, 0);
 MODULE_DEPEND(acpi_ibm, acpi, 1, 1, 1);
-static char    *ibm_ids[] = {"IBM0057", "IBM0068", NULL};
+static char    *ibm_ids[] = {"IBM0068", NULL};
 
 static void
 ibm_led(void *softc, int onoff)

From 917c07ca1da7b9a0ab3b31a0d842163c104e8ce5 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Thu, 24 Sep 2009 08:35:17 +0000
Subject: [PATCH 0267/2592] MFC r197445: Let fall down in the hard path (thus
 handling shared waiters wakeup correctly) for the shared waiters also in the
 rwlock held in shared mode as well, fixing possible deadlocks.

Please note that this is a special condition as we want this fix in
before RC2 as we assume it is critical and so it has been handled
as an instant-merge.  For the STABLE_7 branch, 1 week before the MFC
is assumed.

Approved by:	re (kib)
---
 lib/libthr/thread/thr_umtx.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/lib/libthr/thread/thr_umtx.h b/lib/libthr/thread/thr_umtx.h
index 41b5f968678..a6e462e29ca 100644
--- a/lib/libthr/thread/thr_umtx.h
+++ b/lib/libthr/thread/thr_umtx.h
@@ -171,8 +171,11 @@ _thr_rwlock_unlock(struct urwlock *rwlock)
 		for (;;) {
 			if (__predict_false(URWLOCK_READER_COUNT(state) == 0))
 				return (EPERM);
-			if (!((state & URWLOCK_WRITE_WAITERS) && URWLOCK_READER_COUNT(state) == 1)) {
-				if (atomic_cmpset_rel_32(&rwlock->rw_state, state, state-1))
+			if (!((state & (URWLOCK_WRITE_WAITERS |
+			    URWLOCK_READ_WAITERS)) &&
+			    URWLOCK_READER_COUNT(state) == 1)) {
+				if (atomic_cmpset_rel_32(&rwlock->rw_state,
+				    state, state-1))
 					return (0);
 				state = rwlock->rw_state;
 			} else {

From 8b1e4172cb5f70ebdc598b53a3e5349008002b2d Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Thu, 24 Sep 2009 15:34:18 +0000
Subject: [PATCH 0268/2592] MFC: r197322 and r197374

  Revision: 197322
  Log:
    Correct BIOS header sanitizing on pc98.

  Revision: 197374
  Log:
    Disable a check on a disk size because it's too strict.  This change is
    to avoid using incorrect geometry.

   It seems that this is the same problem in g_part_bsd_read()@g_part_bsd.c.

   Reviewed by: rink

Approved by:	re (kib)
---
 lib/libdisk/change.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/lib/libdisk/change.c b/lib/libdisk/change.c
index 297ac11efa9..5f0c9c6a822 100644
--- a/lib/libdisk/change.c
+++ b/lib/libdisk/change.c
@@ -36,17 +36,22 @@ Sanitize_Bios_Geom(struct disk *disk)
 
 	if (disk->bios_cyl >= 65536)
 		sane = 0;
+#ifdef PC98
+	if (disk->bios_hd >= 256)
+		sane = 0;
+	if (disk->bios_sect >= 256)
+		sane = 0;
+#else
 	if (disk->bios_hd > 256)
 		sane = 0;
-#ifdef PC98
-	if (disk->bios_sect >= 256)
-#else
 	if (disk->bios_sect > 63)
-#endif
 		sane = 0;
+#endif
+#if 0	/* Disable a check on a disk size.  It's too strict. */
 	if (disk->bios_cyl * disk->bios_hd * disk->bios_sect !=
 	    disk->chunks->size)
 		sane = 0;
+#endif
 	if (sane)
 		return;
 

From 0c6c8b3e8f6654d41fb5f7206ab3590ccf5a8069 Mon Sep 17 00:00:00 2001
From: "Stephane E. Potvin" 
Date: Thu, 24 Sep 2009 20:43:08 +0000
Subject: [PATCH 0269/2592] MFC r197259

The buffer returned by fgetln is not a "C" string and might not be NUL
terminated. Make sure that it is before using it.

Reviewed by:    marck@
Approved by:	re (kib)
---
 gnu/usr.bin/patch/common.h | 1 +
 gnu/usr.bin/patch/pch.c    | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/usr.bin/patch/common.h b/gnu/usr.bin/patch/common.h
index 7063be68242..aa191054aa1 100644
--- a/gnu/usr.bin/patch/common.h
+++ b/gnu/usr.bin/patch/common.h
@@ -34,6 +34,7 @@
 #define Strcpy (void)strcpy
 #define Strcat (void)strcat
 #define Strlcpy (void)strlcpy
+#define Strncpy (void)strncpy
 #define Strlcat (void)strlcat
 
 /* NeXT declares malloc and realloc incompatibly from us in some of
diff --git a/gnu/usr.bin/patch/pch.c b/gnu/usr.bin/patch/pch.c
index 1638241151a..e4fd8eec6cd 100644
--- a/gnu/usr.bin/patch/pch.c
+++ b/gnu/usr.bin/patch/pch.c
@@ -1152,7 +1152,8 @@ pgets(bool do_indent)
 					indent++;
 			}
 		}
-		Strlcpy(buf, line, len + 1 - skipped);
+		Strncpy(buf, line, len - skipped);
+		buf[len - skipped] = '\0';
 	}
 	return len;
 }

From 7bd26ba4cce14f23cdf1a5932ca5388eb334c3b9 Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Thu, 24 Sep 2009 21:32:56 +0000
Subject: [PATCH 0270/2592] MFC r197269: Allocate space for the group array in
 a static credential used in the quota code.  One case was correctly handled
 in r194498, but this one was missed.

PR:		kern/138657
Tested by:	PR submitter
MFC after:	3 days
Approved by:	re@ (kib)
---
 sys/ufs/ufs/ufs_vnops.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 54902ad6297..08b77ae0729 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1449,6 +1449,7 @@ ufs_mkdir(ap)
 	{
 #ifdef QUOTA
 		struct ucred ucred, *ucp;
+		gid_t ucred_group;
 		ucp = cnp->cn_cred;
 #endif
 		/*
@@ -1476,6 +1477,7 @@ ufs_mkdir(ap)
 				refcount_init(&ucred.cr_ref, 1);
 				ucred.cr_uid = ip->i_uid;
 				ucred.cr_ngroups = 1;
+				ucred.cr_groups = &ucred_group;
 				ucred.cr_groups[0] = dp->i_gid;
 				ucp = &ucred;
 			}

From ad0074901664905974bfc577f9f2b1ee642afa5a Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Thu, 24 Sep 2009 21:35:13 +0000
Subject: [PATCH 0271/2592] MFC r196990: cr_groups is no longer embedded in
 struct ucred and is instead stored in a seperate array.  As such we need to
 use kvm_read rather than bcopy to populate the ki_groups field.

This fixes a crash when running ps -ax on a coredump.

Reported by:	brucec
Tested by:	brucec
MFC after:	3 days
Approved by:	re@ (kib)
---
 lib/libkvm/kvm_proc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index 7fb85a4a261..071f859e002 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -151,7 +151,7 @@ kvm_proclist(kd, what, arg, p, bp, maxcnt)
 				kp->ki_cr_flags |= KI_CRF_GRP_OVERFLOW;
 			}
 				kp->ki_ngroups = ucred.cr_ngroups;
-			bcopy(ucred.cr_groups, kp->ki_groups,
+			kvm_read(kd, (u_long)ucred.cr_groups, kp->ki_groups,
 			    kp->ki_ngroups * sizeof(gid_t));
 			kp->ki_uid = ucred.cr_uid;
 			if (ucred.cr_prison != NULL) {

From b10d205de26db1a2ac02eb9593d029a980dad02a Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 25 Sep 2009 14:58:00 +0000
Subject: [PATCH 0272/2592] MFC 197406: Don't reread the command register to
 see if enabling I/O or memory decoding "took".  Other OS's that I checked do
 not do this and it breaks some amdpm(4) devices.  Prior to 7.2 we did not
 honor the error returned when this failed anyway, so this in effect restores
 previous behavior.

Approved by:	re (kib)
---
 sys/dev/pci/pci.c | 26 +-------------------------
 1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 0b7b26700c5..47aedbde0dd 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -2149,62 +2149,38 @@ pci_disable_busmaster_method(device_t dev, device_t child)
 int
 pci_enable_io_method(device_t dev, device_t child, int space)
 {
-	uint16_t command;
 	uint16_t bit;
-	char *error;
-
-	bit = 0;
-	error = NULL;
 
 	switch(space) {
 	case SYS_RES_IOPORT:
 		bit = PCIM_CMD_PORTEN;
-		error = "port";
 		break;
 	case SYS_RES_MEMORY:
 		bit = PCIM_CMD_MEMEN;
-		error = "memory";
 		break;
 	default:
 		return (EINVAL);
 	}
 	pci_set_command_bit(dev, child, bit);
-	/* Some devices seem to need a brief stall here, what do to? */
-	command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
-	if (command & bit)
-		return (0);
-	device_printf(child, "failed to enable %s mapping!\n", error);
-	return (ENXIO);
+	return (0);
 }
 
 int
 pci_disable_io_method(device_t dev, device_t child, int space)
 {
-	uint16_t command;
 	uint16_t bit;
-	char *error;
-
-	bit = 0;
-	error = NULL;
 
 	switch(space) {
 	case SYS_RES_IOPORT:
 		bit = PCIM_CMD_PORTEN;
-		error = "port";
 		break;
 	case SYS_RES_MEMORY:
 		bit = PCIM_CMD_MEMEN;
-		error = "memory";
 		break;
 	default:
 		return (EINVAL);
 	}
 	pci_clear_command_bit(dev, child, bit);
-	command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
-	if (command & bit) {
-		device_printf(child, "failed to disable %s mapping!\n", error);
-		return (ENXIO);
-	}
 	return (0);
 }
 

From 57a0ee4c0b50834f562793be991012c5a384a7cd Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 25 Sep 2009 15:08:26 +0000
Subject: [PATCH 0273/2592] MFC 197410: - Split the logic to parse an SMAP
 entry out into a separate function on   amd64 similar to i386.  This fixes a
 bug on amd64 where overlapping   entries would not cause the SMAP parsing to
 stop. - Change the SMAP parsing code to do a sorted insertion into physmap[] 
  instead of an append to support systems with out-of-order SMAP entries.

Approved by:	re (kib)
---
 sys/amd64/amd64/machdep.c | 106 ++++++++++++++++++++++++++------------
 sys/i386/i386/machdep.c   |  40 +++++++++++---
 2 files changed, 107 insertions(+), 39 deletions(-)

diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 0bfd7ada653..95db5d2d605 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1192,6 +1192,77 @@ isa_irq_pending(void)
 
 u_int basemem;
 
+static int
+add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
+{
+	int i, insert_idx, physmap_idx;
+
+	physmap_idx = *physmap_idxp;
+
+	if (boothowto & RB_VERBOSE)
+		printf("SMAP type=%02x base=%016lx len=%016lx\n",
+		    smap->type, smap->base, smap->length);
+
+	if (smap->type != SMAP_TYPE_MEMORY)
+		return (1);
+
+	if (smap->length == 0)
+		return (0);
+
+	/*
+	 * Find insertion point while checking for overlap.  Start off by
+	 * assuming the new entry will be added to the end.
+	 */
+	insert_idx = physmap_idx + 2;
+	for (i = 0; i <= physmap_idx; i += 2) {
+		if (smap->base < physmap[i + 1]) {
+			if (smap->base + smap->length <= physmap[i]) {
+				insert_idx = i;
+				break;
+			}
+			if (boothowto & RB_VERBOSE)
+				printf(
+		    "Overlapping memory regions, ignoring second region\n");
+			return (1);
+		}
+	}
+
+	/* See if we can prepend to the next entry. */
+	if (insert_idx <= physmap_idx &&
+	    smap->base + smap->length == physmap[insert_idx]) {
+		physmap[insert_idx] = smap->base;
+		return (1);
+	}
+
+	/* See if we can append to the previous entry. */
+	if (insert_idx > 0 && smap->base == physmap[insert_idx - 1]) {
+		physmap[insert_idx - 1] += smap->length;
+		return (1);
+	}
+
+	physmap_idx += 2;
+	*physmap_idxp = physmap_idx;
+	if (physmap_idx == PHYSMAP_SIZE) {
+		printf(
+		"Too many segments in the physical address map, giving up\n");
+		return (0);
+	}
+
+	/*
+	 * Move the last 'N' entries down to make room for the new
+	 * entry if needed.
+	 */
+	for (i = physmap_idx; i > insert_idx; i -= 2) {
+		physmap[i] = physmap[i - 2];
+		physmap[i + 1] = physmap[i - 1];
+	}
+
+	/* Insert the new entry. */
+	physmap[insert_idx] = smap->base;
+	physmap[insert_idx + 1] = smap->base + smap->length;
+	return (1);
+}
+
 /*
  * Populate the (physmap) array with base/bound pairs describing the
  * available physical memory in the system, then test this memory and
@@ -1235,40 +1306,9 @@ getmemsize(caddr_t kmdp, u_int64_t first)
 	smapsize = *((u_int32_t *)smapbase - 1);
 	smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize);
 
-	for (smap = smapbase; smap < smapend; smap++) {
-		if (boothowto & RB_VERBOSE)
-			printf("SMAP type=%02x base=%016lx len=%016lx\n",
-			    smap->type, smap->base, smap->length);
-
-		if (smap->type != SMAP_TYPE_MEMORY)
-			continue;
-
-		if (smap->length == 0)
-			continue;
-
-		for (i = 0; i <= physmap_idx; i += 2) {
-			if (smap->base < physmap[i + 1]) {
-				if (boothowto & RB_VERBOSE)
-					printf(
-	"Overlapping or non-monotonic memory region, ignoring second region\n");
-				continue;
-			}
-		}
-
-		if (smap->base == physmap[physmap_idx + 1]) {
-			physmap[physmap_idx + 1] += smap->length;
-			continue;
-		}
-
-		physmap_idx += 2;
-		if (physmap_idx == PHYSMAP_SIZE) {
-			printf(
-		"Too many segments in the physical address map, giving up\n");
+	for (smap = smapbase; smap < smapend; smap++)
+		if (!add_smap_entry(smap, physmap, &physmap_idx))
 			break;
-		}
-		physmap[physmap_idx] = smap->base;
-		physmap[physmap_idx + 1] = smap->base + smap->length;
-	}
 
 	/*
 	 * Find the 'base memory' segment for SMP
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 9c1ea0b143b..67a64c98944 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -1946,7 +1946,7 @@ sdtossd(sd, ssd)
 static int
 add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
 {
-	int i, physmap_idx;
+	int i, insert_idx, physmap_idx;
 
 	physmap_idx = *physmap_idxp;
 	
@@ -1968,17 +1968,34 @@ add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
 	}
 #endif
 
+	/*
+	 * Find insertion point while checking for overlap.  Start off by
+	 * assuming the new entry will be added to the end.
+	 */
+	insert_idx = physmap_idx + 2;
 	for (i = 0; i <= physmap_idx; i += 2) {
 		if (smap->base < physmap[i + 1]) {
+			if (smap->base + smap->length <= physmap[i]) {
+				insert_idx = i;
+				break;
+			}
 			if (boothowto & RB_VERBOSE)
 				printf(
-	"Overlapping or non-monotonic memory region, ignoring second region\n");
+		    "Overlapping memory regions, ignoring second region\n");
 			return (1);
 		}
 	}
 
-	if (smap->base == physmap[physmap_idx + 1]) {
-		physmap[physmap_idx + 1] += smap->length;
+	/* See if we can prepend to the next entry. */
+	if (insert_idx <= physmap_idx &&
+	    smap->base + smap->length == physmap[insert_idx]) {
+		physmap[insert_idx] = smap->base;
+		return (1);
+	}
+
+	/* See if we can append to the previous entry. */
+	if (insert_idx > 0 && smap->base == physmap[insert_idx - 1]) {
+		physmap[insert_idx - 1] += smap->length;
 		return (1);
 	}
 
@@ -1989,8 +2006,19 @@ add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
 		"Too many segments in the physical address map, giving up\n");
 		return (0);
 	}
-	physmap[physmap_idx] = smap->base;
-	physmap[physmap_idx + 1] = smap->base + smap->length;
+
+	/*
+	 * Move the last 'N' entries down to make room for the new
+	 * entry if needed.
+	 */
+	for (i = physmap_idx; i > insert_idx; i -= 2) {
+		physmap[i] = physmap[i - 2];
+		physmap[i + 1] = physmap[i - 1];
+	}
+
+	/* Insert the new entry. */
+	physmap[insert_idx] = smap->base;
+	physmap[insert_idx + 1] = smap->base + smap->length;
 	return (1);
 }
 

From 424b2e64a2799aca632f73788043e9a738de1e79 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 25 Sep 2009 15:14:11 +0000
Subject: [PATCH 0274/2592] MFC 197415: The elements in the component arrays
 may be direct Package objects rather than references to objects.  In that
 case, simply use the Package directly.

Approved by:	re (kib)
---
 sys/dev/acpi_support/acpi_aiboost.c | 36 +++++++++++++++--------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/sys/dev/acpi_support/acpi_aiboost.c b/sys/dev/acpi_support/acpi_aiboost.c
index 8fff8720597..a8fe9cc4a45 100644
--- a/sys/dev/acpi_support/acpi_aiboost.c
+++ b/sys/dev/acpi_support/acpi_aiboost.c
@@ -46,7 +46,6 @@ ACPI_MODULE_NAME("AIBOOST")
 
 #define DESCSTRLEN 32
 struct acpi_aiboost_element{
-	ACPI_HANDLE h;
 	uint32_t id;
 	char desc[DESCSTRLEN];
 };
@@ -127,22 +126,23 @@ static ACPI_STATUS acpi_aiboost_getcomponent(device_t dev, char *name, struct  a
 	
 	for(i = 1 ; i < o->Package.Count; i++){
 		elem = &o->Package.Elements[i];
-		if(elem->Type != ACPI_TYPE_ANY){
-			printf("NOREF\n");
-			goto error;
-		}
-		c->elem[ i - 1].h = elem->Reference.Handle;
+		if (elem->Type == ACPI_TYPE_ANY) {
+			buf2.Pointer = NULL;
+			buf2.Length = ACPI_ALLOCATE_BUFFER;
 
-		buf2.Pointer = NULL;
-		buf2.Length = ACPI_ALLOCATE_BUFFER;
-		
-		status = AcpiEvaluateObject(c->elem[i - 1].h, NULL, NULL,
-					    &buf2);
-		if(ACPI_FAILURE(status)){
-			printf("FETCH OBJECT\n");
+			status = AcpiEvaluateObject(elem->Reference.Handle,
+			    NULL, NULL, &buf2);
+			if (ACPI_FAILURE(status)){
+				printf("FETCH OBJECT\n");
+				goto error;
+			}
+			subobj = buf2.Pointer;
+		} else if (elem->Type == ACPI_TYPE_PACKAGE)
+			subobj = elem;
+		else {
+			printf("NO PACKAGE\n");
 			goto error;
 		}
-		subobj = buf2.Pointer;
 		if(ACPI_FAILURE(acpi_PkgInt32(subobj,0, &c->elem[i -1].id))){
 			printf("ID FAILED\n");
 			goto error;
@@ -151,15 +151,17 @@ static ACPI_STATUS acpi_aiboost_getcomponent(device_t dev, char *name, struct  a
 				     sizeof(c->elem[i - 1].desc));
 		if(ACPI_FAILURE(status)){
 			if(status == E2BIG){
-				c->elem[i-1].desc[DESCSTRLEN-1] = 0;
+				c->elem[i - 1].desc[DESCSTRLEN-1] = 0;
 			}else{
 				printf("DESC FAILED %d\n", i-1);
 				goto error;
 			}
 		}
 		
-		if(buf2.Pointer)
-		  AcpiOsFree(buf2.Pointer);
+		if (buf2.Pointer) {
+			AcpiOsFree(buf2.Pointer);
+			buf2.Pointer = NULL;
+		}
 	}
 
 	if(buf.Pointer)

From 54577e2314d00295a56b2c4058bced7fa4199ab6 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 25 Sep 2009 16:45:27 +0000
Subject: [PATCH 0275/2592] - Add missing bus_dmamap_sync(9) calls for the work
 DMA map. Previously   the work area was totally unsynchronized which means
 this driver only   had a chance of working on x86 when no bounce buffers were
 involved,   which isn't that likely given that support for 64-bit DMA is
 currently   broken throughout ata(4). - Add necessary little-endian
 conversion of accesses to the work area,   making this driver work on
 big-endian hosts. While at it, use the   alignment-agnostic byte order
 encoders in order to be on the safe side. - Clear the reserved member of the
 SG list entries in order to be on the   safe side. [1]

Submitted by:	yongari [1]
Reviewed by:	yongari
Approved by:	re (kib)
---
 sys/dev/ata/chipsets/ata-marvell.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index 0544e199ed0..dd6b96fcbf3 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -227,6 +227,8 @@ ata_marvell_edma_ch_attach(device_t dev)
     work = ch->dma.work_bus;
     /* clear work area */
     bzero(ch->dma.work, 1024+256);
+    bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
+	BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
     /* set legacy ATA resources */
     for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
@@ -310,7 +312,11 @@ ata_marvell_edma_ch_attach(device_t dev)
 static int
 ata_marvell_edma_ch_detach(device_t dev)
 {
+    struct ata_channel *ch = device_get_softc(dev);
 
+    if (ch->dma.work_tag && ch->dma.work_map)
+	bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
     ata_dmafini(dev);
     return (0);
 }
@@ -344,8 +350,6 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
     struct ata_channel *ch = device_get_softc(request->parent);
     u_int32_t req_in;
     u_int8_t *bytep;
-    u_int16_t *wordp;
-    u_int32_t *quadp;
     int i;
     int error, slot;
 
@@ -374,13 +378,14 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
     slot = (((req_in & ~0xfffffc00) >> 5) + 0) & 0x1f;
     bytep = (u_int8_t *)(ch->dma.work);
     bytep += (slot << 5);
-    wordp = (u_int16_t *)bytep;
-    quadp = (u_int32_t *)bytep;
 
     /* fill in this request */
-    quadp[0] = (long)request->dma->sg_bus & 0xffffffff;
-    quadp[1] = (u_int64_t)request->dma->sg_bus >> 32;
-    wordp[4] = (request->flags & ATA_R_READ ? 0x01 : 0x00) | (request->tag<<1);
+    le32enc(bytep + 0 * sizeof(u_int32_t),
+	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));
 
     i = 10;
     bytep[i++] = (request->u.ata.count >> 8) & 0xff;
@@ -409,6 +414,9 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
     bytep[i++] = request->u.ata.command;
     bytep[i++] = 0x90 | ATA_COMMAND;
 
+    bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
+	BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
     /* enable EDMA machinery if needed */
     if (!(ATA_INL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch)) & 0x00000001)) {
 	ATA_OUTL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch), 0x00000001);
@@ -451,6 +459,8 @@ ata_marvell_edma_end_transaction(struct ata_request *request)
 	slot = (((rsp_in & ~0xffffff00) >> 3)) & 0x1f;
 	rsp_out &= 0xffffff00;
 	rsp_out += (slot << 3);
+	bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 	response = (struct ata_marvell_response *)
 		   (ch->dma.work + 1024 + (slot << 3));
 
@@ -525,6 +535,7 @@ ata_marvell_edma_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs,
 	prd[i].addrlo = htole32(segs[i].ds_addr);
 	prd[i].count = htole32(segs[i].ds_len);
 	prd[i].addrhi = htole32((u_int64_t)segs[i].ds_addr >> 32);
+	prd[i].reserved = 0;
     }
     prd[i - 1].count |= htole32(ATA_DMA_EOT);
     KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries\n"));

From 3b9790003eb0ddfddb6f4c8ff3e162a5d7d12ed8 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Fri, 25 Sep 2009 17:48:30 +0000
Subject: [PATCH 0276/2592] MFC rev 197449: Don't create more partitions than
 can fit in the table by checking that the index is within bounds.

Approved by:	re (kib)
---
 sys/geom/part/g_part.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 78c36501326..6e81a9c70b6 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -480,6 +480,10 @@ g_part_ctl_add(struct gctl_req *req, struct g_part_parms *gpp)
 		gctl_error(req, "%d index '%d'", EEXIST, gpp->gpp_index);
 		return (EEXIST);
 	}
+	if (index > table->gpt_entries) {
+		gctl_error(req, "%d index '%d'", ENOSPC, index);
+		return (ENOSPC);
+	}
 
 	entry = (delent == NULL) ? g_malloc(table->gpt_scheme->gps_entrysz,
 	    M_WAITOK | M_ZERO) : delent;

From 2adf464fea380dae37165f8691227a1099f6a825 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 25 Sep 2009 18:04:55 +0000
Subject: [PATCH 0277/2592] MFC rev. 197462: Do not call BUS_DRIVER_ADDED() for
 detached buses (attach failed) on driver load. This fixes crash on atapicam
 module load on systems, where some ata channels (usually ata1) was probed,
 but failed to attach.

Reviewed by:    jhb, imp
Tested by:      many
Approved by:    re (kib)
---
 sys/kern/subr_bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index f202631ce88..3f51c5cada8 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -1017,7 +1017,7 @@ devclass_driver_added(devclass_t dc, driver_t *driver)
 	 * Call BUS_DRIVER_ADDED for any existing busses in this class.
 	 */
 	for (i = 0; i < dc->maxunit; i++)
-		if (dc->devices[i])
+		if (dc->devices[i] && device_is_attached(dc->devices[i]))
 			BUS_DRIVER_ADDED(dc->devices[i], driver);
 
 	/*

From b8b5722c5d244992bd54075824b656ebd9b89cc3 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 25 Sep 2009 18:07:23 +0000
Subject: [PATCH 0278/2592] Remove constraint, requiring request data to
 fulfill controller's alignment requirements. It is busdma task, to manage
 proper alignment by loading data to bounce buffers.

PR:		kern/127316
Reviewed by:	current@
Tested by:	Ryan Rogers
Approved by:	re (kib)
---
 sys/dev/ata/ata-dma.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index afc35506b57..770b13f0e3c 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -272,10 +272,10 @@ ata_dmaload(struct ata_request *request, void *addr, int *entries)
 		      "FAILURE - zero length DMA transfer attempted\n");
 	return EIO;
     }
-    if (((uintptr_t)(request->data) & (ch->dma.alignment - 1)) ||
-	(request->bytecount & (ch->dma.alignment - 1))) {
+    if (request->bytecount & (ch->dma.alignment - 1)) {
 	device_printf(request->dev,
-		      "FAILURE - non aligned DMA transfer attempted\n");
+		      "FAILURE - odd-sized DMA transfer attempt %d %% %d\n",
+		      request->bytecount, ch->dma.alignment);
 	return EIO;
     }
     if (request->bytecount > ch->dma.max_iosize) {

From 238bc19306f79c1e7aaeeca62ac292424aaae8af Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 25 Sep 2009 19:59:18 +0000
Subject: [PATCH 0279/2592] MFC: r197401

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

Submitted by:	yongari [1]
Reviewed by:	yongari (superset of what is committed)
Approved by:	re (kib)
---
 sys/dev/sound/pci/t4dwave.c | 96 ++++++++++++++++++++++++++++++-------
 1 file changed, 78 insertions(+), 18 deletions(-)

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

From b57f5ce0bd7fa6b2de2162ba6efc88d62948ff11 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Mon, 28 Sep 2009 11:31:21 +0000
Subject: [PATCH 0280/2592] MFC r197390: Remove forward_roundrobin().

Approved by:	re (kensmith)
---
 sys/kern/subr_smp.c | 33 ---------------------------------
 sys/sys/smp.h       |  1 -
 2 files changed, 34 deletions(-)

diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index d28001f7cc7..f226e3a6e01 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -104,12 +104,6 @@ SYSCTL_INT(_kern_smp, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
 	   &forward_signal_enabled, 0,
 	   "Forwarding of a signal to a process on a different CPU");
 
-/* Enable forwarding of roundrobin to all other cpus */
-static int forward_roundrobin_enabled = 1;
-SYSCTL_INT(_kern_smp, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
-	   &forward_roundrobin_enabled, 0,
-	   "Forwarding of roundrobin to all other CPUs");
-
 /* Variables needed for SMP rendezvous. */
 static volatile int smp_rv_ncpus;
 static void (*volatile smp_rv_setup_func)(void *arg);
@@ -189,33 +183,6 @@ forward_signal(struct thread *td)
 	ipi_selected(1 << id, IPI_AST);
 }
 
-void
-forward_roundrobin(void)
-{
-	struct pcpu *pc;
-	struct thread *td;
-	cpumask_t id, map, me;
-
-	CTR0(KTR_SMP, "forward_roundrobin()");
-
-	if (!smp_started || cold || panicstr)
-		return;
-	if (!forward_roundrobin_enabled)
-		return;
-	map = 0;
-	me = PCPU_GET(cpumask);
-	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
-		td = pc->pc_curthread;
-		id = pc->pc_cpumask;
-		if (id != me && (id & stopped_cpus) == 0 &&
-		    !TD_IS_IDLETHREAD(td)) {
-			td->td_flags |= TDF_NEEDRESCHED;
-			map |= id;
-		}
-	}
-	ipi_selected(map, IPI_AST);
-}
-
 /*
  * When called the executing CPU will send an IPI to all other CPUs
  *  requesting that they halt execution.
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index d80b9e46ef9..782ef74974b 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/smp.h
@@ -120,7 +120,6 @@ void	cpu_mp_setmaxid(void);
 void	cpu_mp_start(void);
 
 void	forward_signal(struct thread *);
-void	forward_roundrobin(void);
 int	restart_cpus(cpumask_t);
 int	stop_cpus(cpumask_t);
 int	stop_cpus_hard(cpumask_t);

From fe36e02918af2075f5472fff4a0eed1ea6a55d19 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Mon, 28 Sep 2009 18:32:28 +0000
Subject: [PATCH 0281/2592] MFC r197341. Fix errnos.

Approved by: re (bz), rrs (mentor)
---
 sys/netinet/sctp_output.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 1e768fc5bbe..b2b2cac97aa 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -12384,8 +12384,8 @@ sctp_lower_sosend(struct socket *so,
 
 	t_inp = inp = (struct sctp_inpcb *)so->so_pcb;
 	if (inp == NULL) {
-		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
-		error = EFAULT;
+		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+		error = EINVAL;
 		if (i_pak) {
 			SCTP_RELEASE_PKT(i_pak);
 		}
@@ -12432,8 +12432,8 @@ sctp_lower_sosend(struct socket *so,
 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
 	    (inp->sctp_socket->so_qlimit)) {
 		/* The listener can NOT send */
-		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
-		error = EFAULT;
+		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
+		error = ENOTCONN;
 		goto out_unlocked;
 	}
 	if ((use_rcvinfo) && srcv) {
@@ -12566,8 +12566,8 @@ sctp_lower_sosend(struct socket *so,
 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
 		    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
 			/* Should I really unlock ? */
-			SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
-			error = EFAULT;
+			SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+			error = EINVAL;
 			goto out_unlocked;
 
 		}
@@ -12596,6 +12596,12 @@ sctp_lower_sosend(struct socket *so,
 		}
 	}
 	if (stcb == NULL) {
+		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
+		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
+			SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
+			error = ENOTCONN;
+			goto out_unlocked;
+		}
 		if (addr == NULL) {
 			SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOENT);
 			error = ENOENT;

From 264d14d30d2679a3e92d55c90b0dd4f6c216ddfe Mon Sep 17 00:00:00 2001
From: Andrew Gallatin 
Date: Mon, 28 Sep 2009 23:48:16 +0000
Subject: [PATCH 0282/2592] MFC 197395: Improve mxge watchdog routine's ability
 to reliably reset a failed NIC

Approved by: re (kib)
---
 sys/dev/mxge/if_mxge.c | 99 ++++++++++++++++++++++++++++++------------
 1 file changed, 72 insertions(+), 27 deletions(-)

diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index 88c3489ee3a..f41fbf6cfb5 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -143,7 +143,7 @@ MODULE_DEPEND(mxge, zlib, 1, 1, 1);
 
 static int mxge_load_firmware(mxge_softc_t *sc, int adopt);
 static int mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data);
-static int mxge_close(mxge_softc_t *sc);
+static int mxge_close(mxge_softc_t *sc, int down);
 static int mxge_open(mxge_softc_t *sc);
 static void mxge_tick(void *arg);
 
@@ -1305,8 +1305,7 @@ mxge_reset(mxge_softc_t *sc, int interrupts_setup)
 		ss->lro_queued = 0;
 		ss->lro_flushed = 0;
 		if (ss->fw_stats != NULL) {
-			ss->fw_stats->valid = 0;
-			ss->fw_stats->send_done_count = 0;
+			bzero(ss->fw_stats, sizeof *ss->fw_stats);
 		}
 	}
 	sc->rdma_tags_available = 15;
@@ -1379,7 +1378,7 @@ mxge_change_lro_locked(mxge_softc_t *sc, int lro_cnt)
 		ifp->if_capenable |= IFCAP_LRO;
 	sc->lro_cnt = lro_cnt;
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		mxge_close(sc);
+		mxge_close(sc, 0);
 		err = mxge_open(sc);
 	}
 	return err;
@@ -1495,6 +1494,10 @@ mxge_add_sysctls(mxge_softc_t *sc)
 		       "read_write_dma_MBs",
 		       CTLFLAG_RD, &sc->read_write_dma,
 		       0, "DMA concurrent Read/Write speed in MB/s");
+	SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
+		       "watchdog_resets",
+		       CTLFLAG_RD, &sc->watchdog_resets,
+		       0, "Number of times NIC was reset");
 
 
 	/* performance related tunables */
@@ -3600,7 +3603,7 @@ abort:
 }
 
 static int
-mxge_close(mxge_softc_t *sc)
+mxge_close(mxge_softc_t *sc, int down)
 {
 	mxge_cmd_t cmd;
 	int err, old_down_cnt;
@@ -3617,21 +3620,23 @@ mxge_close(mxge_softc_t *sc)
 	}
 #endif
 	sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-	old_down_cnt = sc->down_cnt;
-	wmb();
-	err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_DOWN, &cmd);
-	if (err) {
-		device_printf(sc->dev, "Couldn't bring down link\n");
+	if (!down) {
+		old_down_cnt = sc->down_cnt;
+		wmb();
+		err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_DOWN, &cmd);
+		if (err) {
+			device_printf(sc->dev,
+				      "Couldn't bring down link\n");
+		}
+		if (old_down_cnt == sc->down_cnt) {
+			/* wait for down irq */
+			DELAY(10 * sc->intr_coal_delay);
+		}
+		wmb();
+		if (old_down_cnt == sc->down_cnt) {
+			device_printf(sc->dev, "never got down irq\n");
+		}
 	}
-	if (old_down_cnt == sc->down_cnt) {
-		/* wait for down irq */
-		DELAY(10 * sc->intr_coal_delay);
-	}
-	wmb();
-	if (old_down_cnt == sc->down_cnt) {
-		device_printf(sc->dev, "never got down irq\n");
-	}
-
 	mxge_free_mbufs(sc);
 
 	return 0;
@@ -3684,8 +3689,9 @@ static int
 mxge_watchdog_reset(mxge_softc_t *sc, int slice)
 {
 	struct pci_devinfo *dinfo;
+	struct mxge_slice_state *ss;
 	mxge_tx_ring_t *tx;
-	int err;
+	int err, running, s, num_tx_slices = 1;
 	uint32_t reboot;
 	uint16_t cmd;
 
@@ -3719,6 +3725,30 @@ mxge_watchdog_reset(mxge_softc_t *sc, int slice)
 		reboot = mxge_read_reboot(sc);
 		device_printf(sc->dev, "NIC rebooted, status = 0x%x\n",
 			      reboot);
+		running = sc->ifp->if_drv_flags & IFF_DRV_RUNNING;
+		if (running) {
+
+			/* 
+			 * quiesce NIC so that TX routines will not try to
+			 * xmit after restoration of BAR
+			 */
+
+			/* Mark the link as down */
+			if (sc->link_state) {
+				sc->link_state = 0;
+				if_link_state_change(sc->ifp,
+						     LINK_STATE_DOWN);
+			}
+#ifdef IFNET_BUF_RING
+			num_tx_slices = sc->num_slices;
+#endif
+			/* grab all TX locks to ensure no tx  */
+			for (s = 0; s < num_tx_slices; s++) {
+				ss = &sc->ss[s];
+				mtx_lock(&ss->tx.mtx);
+			}
+			mxge_close(sc, 1);
+		}
 		/* restore PCI configuration space */
 		dinfo = device_get_ivars(sc->dev);
 		pci_cfg_restore(sc->dev, dinfo);
@@ -3726,10 +3756,22 @@ mxge_watchdog_reset(mxge_softc_t *sc, int slice)
 		/* and redo any changes we made to our config space */
 		mxge_setup_cfg_space(sc);
 
-		if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) {
-			mxge_close(sc);
-			err = mxge_open(sc);
+		/* reload f/w */
+		err = mxge_load_firmware(sc, 0);
+		if (err) {
+			device_printf(sc->dev,
+				      "Unable to re-load f/w\n");
 		}
+		if (running) {
+			if (!err)
+				err = mxge_open(sc);
+			/* release all TX locks */
+			for (s = 0; s < num_tx_slices; s++) {
+				ss = &sc->ss[s];
+				mtx_unlock(&ss->tx.mtx);
+			}
+		}
+		sc->watchdog_resets++;
 	} else {
 		tx = &sc->ss[slice].tx;
 		device_printf(sc->dev,
@@ -3745,6 +3787,9 @@ mxge_watchdog_reset(mxge_softc_t *sc, int slice)
 			      be32toh(sc->ss->fw_stats->send_done_count));
 		device_printf(sc->dev, "not resetting\n");
 	}
+	if (err)
+		device_printf(sc->dev, "watchdog reset failed\n");
+
 	return (err);
 }
 
@@ -3860,11 +3905,11 @@ mxge_change_mtu(mxge_softc_t *sc, int mtu)
 	old_mtu = ifp->if_mtu;
 	ifp->if_mtu = mtu;
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		mxge_close(sc);
+		mxge_close(sc, 0);
 		err = mxge_open(sc);
 		if (err != 0) {
 			ifp->if_mtu = old_mtu;
-			mxge_close(sc);
+			mxge_close(sc, 0);
 			(void) mxge_open(sc);
 		}
 	}
@@ -3922,7 +3967,7 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 			}
 		} else {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-				mxge_close(sc);
+				mxge_close(sc, 0);
 			}
 		}
 		mtx_unlock(&sc->driver_mtx);
@@ -4645,7 +4690,7 @@ mxge_detach(device_t dev)
 	mtx_lock(&sc->driver_mtx);
 	sc->dying = 1;
 	if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING)
-		mxge_close(sc);
+		mxge_close(sc, 0);
 	mtx_unlock(&sc->driver_mtx);
 	ether_ifdetach(sc->ifp);
 	callout_drain(&sc->co_hdl);

From 01985d688432efdfacc4c0aa028b5b3e10cf882d Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Tue, 29 Sep 2009 10:53:06 +0000
Subject: [PATCH 0283/2592] MFC r197287, r197289, r197351, r197426, r197458,
 r197459, r197497, r197498, r197512, r197513, r197514, r197515, r197525:

r197287:

Purge namecache for the file system being rolled back, so it doesn't point at
invalid vnodes after the rollback resulting in EIO errors when trying to access
files which are in the namecache.

Reported by:	des

r197289:

Purge file system namecache when receiving incremental stream and rolling back
to it.

r197351:

Purge namecache in the same place OpenSolaris does.

r197426:

Restore BSD behaviour - when creating new directory entry use parent directory
gid to set group ownership and not process gid.

This was overlooked during v6 -> v13 switch.

PR:	kern/139076
Reported by:	Sean Winn 

r197458:

Close race in zfs_zget(). We have to increase usecount first and then
check for VI_DOOMED flag. Before this change vnode could be reclaimed
between checking for the flag and increasing usecount.

r197459:

Before calling vflush(FORCECLOSE) mark file system as unmounted so the
following vnops will fail. This is very important, because without this change
vnode could be reclaimed at any point, even if we increased usecount. The only
way to ensure that vnode won't be reclaimed was to lock it, which would be very
hard to do in ZFS without changing a lot of code. With this change simply
increasing usecount is enough to be sure vnode won't be reclaimed from under
us. To be precise it can still be reclaimed but we won't be able to see it,
because every try to enter ZFS through VFS will result in EIO.

The only function that cannot return EIO, because it is needed for vflush() is
zfs_root(). Introduce ZFS_ENTER_NOERROR() macro that only locks
z_teardown_lock and never returns EIO.

r197497:

Switch to fletcher4 as the default checksum algorithm. Fletcher2 was proven to
be a bit weak and OpenSolaris also switched to fletcher4.

r197498:	head/cddl/contrib/opensolaris

Fletcher4 is not the default checksum algorithm.

r197512:

- Don't depend on value returned by gfs_*_inactive(), it doesn't work
  well with forced unmounts when GFS vnodes are referenced.
- Make other preparations to GFS for forced unmounts.

PR:	kern/139062
Reported by:	trasz

r197513:

Use traverse() function to find and return mount point's vnode instead of
covered vnode when snapshot is already mounted.

r197514:

On lookup error VFS expects *vpp to be set to NULL, be sure to do that.

r197515:

Handle cases where virtual (GFS) vnodes are referenced when doing forced
unmount. In that case we cannot depend on the proper order of invalidating
vnodes, so we have to free resources when we have a chance.

PR:	kern/139062
Reported by:	trasz

r197525:

Ensure that tv_sec is between INT32_MIN and INT32_MAX, so ZFS won't object.
This completes the fix from r185586.

PR:	kern/139059
Reported by:	Daniel Braniss 
Submitted by:	Jaakko Heinonen 
Tested by:	Daniel Braniss 

Approved by:	re (kib)
---
 cddl/contrib/opensolaris/cmd/zfs/zfs.8        |   2 +-
 .../contrib/opensolaris/uts/common/fs/gfs.c   |  18 +--
 .../opensolaris/uts/common/fs/zfs/fletcher.c  | 104 +++++++++++++++++-
 .../uts/common/fs/zfs/sys/zfs_znode.h         |   4 +
 .../opensolaris/uts/common/fs/zfs/sys/zio.h   |   2 +-
 .../opensolaris/uts/common/fs/zfs/zfs_acl.c   |   2 +-
 .../uts/common/fs/zfs/zfs_ctldir.c            |  43 +++++---
 .../uts/common/fs/zfs/zfs_vfsops.c            |  19 +++-
 .../opensolaris/uts/common/fs/zfs/zfs_znode.c |  30 +++--
 sys/nfsserver/nfs_serv.c                      |   2 +-
 10 files changed, 179 insertions(+), 47 deletions(-)

diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
index 7217fe8f5ba..39445ea13a8 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
@@ -535,7 +535,7 @@ This property is not inherited.
 .ad
 .sp .6
 .RS 4n
-Controls the checksum used to verify data integrity. The default value is "on", which automatically selects an appropriate algorithm (currently, \fIfletcher2\fR, but this may change in future releases). The value "off" disables integrity
+Controls the checksum used to verify data integrity. The default value is "on", which automatically selects an appropriate algorithm (currently, \fIfletcher4\fR, but this may change in future releases). The value "off" disables integrity
 checking on user data. Disabling checksums is NOT a recommended practice.
 .RE
 
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c b/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c
index cd522bfebbf..269c3ebe75d 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c
@@ -595,7 +595,6 @@ found:
 	if (vp->v_flag & V_XATTRDIR)
 		VI_LOCK(fp->gfs_parent);
 	VI_LOCK(vp);
-	ASSERT(vp->v_count < 2);
 	/*
 	 * Really remove this vnode
 	 */
@@ -607,12 +606,7 @@ found:
 		 */
 		ge->gfse_vnode = NULL;
 	}
-	if (vp->v_count == 1) {
-		vp->v_usecount--;
-		vdropl(vp);
-	} else {
-		VI_UNLOCK(vp);
-	}
+	VI_UNLOCK(vp);
 
 	/*
 	 * Free vnode and release parent
@@ -1084,18 +1078,16 @@ gfs_vop_inactive(ap)
 {
 	vnode_t *vp = ap->a_vp;
 	gfs_file_t *fp = vp->v_data;
-	void *data;
 
 	if (fp->gfs_type == GFS_DIR)
-		data = gfs_dir_inactive(vp);
+		gfs_dir_inactive(vp);
 	else
-		data = gfs_file_inactive(vp);
-
-	if (data != NULL)
-		kmem_free(data, fp->gfs_size);
+		gfs_file_inactive(vp);
 
 	VI_LOCK(vp);
 	vp->v_data = NULL;
 	VI_UNLOCK(vp);
+	kmem_free(fp, fp->gfs_size);
+
 	return (0);
 }
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/fletcher.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/fletcher.c
index edda3c9a9d3..54247d724d4 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/fletcher.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/fletcher.c
@@ -19,11 +19,111 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
+/*
+ * Fletcher Checksums
+ * ------------------
+ *
+ * ZFS's 2nd and 4th order Fletcher checksums are defined by the following
+ * recurrence relations:
+ *
+ *	a  = a    + f
+ *	 i    i-1    i-1
+ *
+ *	b  = b    + a
+ *	 i    i-1    i
+ *
+ *	c  = c    + b		(fletcher-4 only)
+ *	 i    i-1    i
+ *
+ *	d  = d    + c		(fletcher-4 only)
+ *	 i    i-1    i
+ *
+ * Where
+ *	a_0 = b_0 = c_0 = d_0 = 0
+ * and
+ *	f_0 .. f_(n-1) are the input data.
+ *
+ * Using standard techniques, these translate into the following series:
+ *
+ *	     __n_			     __n_
+ *	     \   |			     \   |
+ *	a  =  >     f			b  =  >     i * f
+ *	 n   /___|   n - i		 n   /___|	 n - i
+ *	     i = 1			     i = 1
+ *
+ *
+ *	     __n_			     __n_
+ *	     \   |  i*(i+1)		     \   |  i*(i+1)*(i+2)
+ *	c  =  >     ------- f		d  =  >     ------------- f
+ *	 n   /___|     2     n - i	 n   /___|	  6	   n - i
+ *	     i = 1			     i = 1
+ *
+ * For fletcher-2, the f_is are 64-bit, and [ab]_i are 64-bit accumulators.
+ * Since the additions are done mod (2^64), errors in the high bits may not
+ * be noticed.  For this reason, fletcher-2 is deprecated.
+ *
+ * For fletcher-4, the f_is are 32-bit, and [abcd]_i are 64-bit accumulators.
+ * A conservative estimate of how big the buffer can get before we overflow
+ * can be estimated using f_i = 0xffffffff for all i:
+ *
+ * % bc
+ *  f=2^32-1;d=0; for (i = 1; d<2^64; i++) { d += f*i*(i+1)*(i+2)/6 }; (i-1)*4
+ * 2264
+ *  quit
+ * %
+ *
+ * So blocks of up to 2k will not overflow.  Our largest block size is
+ * 128k, which has 32k 4-byte words, so we can compute the largest possible
+ * accumulators, then divide by 2^64 to figure the max amount of overflow:
+ *
+ * % bc
+ *  a=b=c=d=0; f=2^32-1; for (i=1; i<=32*1024; i++) { a+=f; b+=a; c+=b; d+=c }
+ *  a/2^64;b/2^64;c/2^64;d/2^64
+ * 0
+ * 0
+ * 1365
+ * 11186858
+ *  quit
+ * %
+ *
+ * So a and b cannot overflow.  To make sure each bit of input has some
+ * effect on the contents of c and d, we can look at what the factors of
+ * the coefficients in the equations for c_n and d_n are.  The number of 2s
+ * in the factors determines the lowest set bit in the multiplier.  Running
+ * through the cases for n*(n+1)/2 reveals that the highest power of 2 is
+ * 2^14, and for n*(n+1)*(n+2)/6 it is 2^15.  So while some data may overflow
+ * the 64-bit accumulators, every bit of every f_i effects every accumulator,
+ * even for 128k blocks.
+ *
+ * If we wanted to make a stronger version of fletcher4 (fletcher4c?),
+ * we could do our calculations mod (2^32 - 1) by adding in the carries
+ * periodically, and store the number of carries in the top 32-bits.
+ *
+ * --------------------
+ * Checksum Performance
+ * --------------------
+ *
+ * There are two interesting components to checksum performance: cached and
+ * uncached performance.  With cached data, fletcher-2 is about four times
+ * faster than fletcher-4.  With uncached data, the performance difference is
+ * negligible, since the cost of a cache fill dominates the processing time.
+ * Even though fletcher-4 is slower than fletcher-2, it is still a pretty
+ * efficient pass over the data.
+ *
+ * In normal operation, the data which is being checksummed is in a buffer
+ * which has been filled either by:
+ *
+ *	1. a compression step, which will be mostly cached, or
+ *	2. a bcopy() or copyin(), which will be uncached (because the
+ *	   copy is cache-bypassing).
+ *
+ * For both cached and uncached data, both fletcher checksums are much faster
+ * than sha-256, and slower than 'off', which doesn't touch the data at all.
+ */
 
 #include 
 #include 
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
index bb1c9da6be9..185f7d24636 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
@@ -255,6 +255,7 @@ VTOZ(vnode_t *vp)
 
 /*
  * ZFS_ENTER() is called on entry to each ZFS vnode and vfs operation.
+ * ZFS_ENTER_NOERROR() is called when we can't return EIO.
  * ZFS_EXIT() must be called before exitting the vop.
  * ZFS_VERIFY_ZP() verifies the znode is valid.
  */
@@ -267,6 +268,9 @@ VTOZ(vnode_t *vp)
 		} \
 	}
 
+#define	ZFS_ENTER_NOERROR(zfsvfs) \
+	rrw_enter(&(zfsvfs)->z_teardown_lock, RW_READER, FTAG)
+
 #define	ZFS_EXIT(zfsvfs) rrw_exit(&(zfsvfs)->z_teardown_lock, FTAG)
 
 #define	ZFS_VERIFY_ZP(zp) \
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
index 6331567498b..fbc8c454bdf 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
@@ -76,7 +76,7 @@ enum zio_checksum {
 	ZIO_CHECKSUM_FUNCTIONS
 };
 
-#define	ZIO_CHECKSUM_ON_VALUE	ZIO_CHECKSUM_FLETCHER_2
+#define	ZIO_CHECKSUM_ON_VALUE	ZIO_CHECKSUM_FLETCHER_4
 #define	ZIO_CHECKSUM_DEFAULT	ZIO_CHECKSUM_ON
 
 enum zio_compress {
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
index d46627346a1..a43d85c709e 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
@@ -1841,7 +1841,7 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
 				fgid = zfs_fuid_create_cred(zfsvfs,
 				    ZFS_GROUP, tx, cr, fuidp);
 #ifdef __FreeBSD__
-				gid = parent->z_phys->zp_gid;
+				gid = fgid = parent->z_phys->zp_gid;
 #else
 				gid = crgetgid(cr);
 #endif
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
index 0b034f627ce..7820293f68a 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
@@ -818,7 +818,11 @@ zfsctl_snapdir_lookup(ap)
 	if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) != NULL) {
 		*vpp = sep->se_root;
 		VN_HOLD(*vpp);
-		if ((*vpp)->v_mountedhere == NULL) {
+		err = traverse(vpp, LK_EXCLUSIVE | LK_RETRY);
+		if (err) {
+			VN_RELE(*vpp);
+			*vpp = NULL;
+		} else if (*vpp == sep->se_root) {
 			/*
 			 * The snapshot was unmounted behind our backs,
 			 * try to remount it.
@@ -832,10 +836,9 @@ zfsctl_snapdir_lookup(ap)
 			 */
 			(*vpp)->v_flag &= ~VROOT;
 		}
-		vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
 		mutex_exit(&sdp->sd_lock);
 		ZFS_EXIT(zfsvfs);
-		return (0);
+		return (err);
 	}
 
 	/*
@@ -895,6 +898,8 @@ domount:
 	}
 	mutex_exit(&sdp->sd_lock);
 	ZFS_EXIT(zfsvfs);
+	if (err != 0)
+		*vpp = NULL;
 	return (err);
 }
 
@@ -1002,15 +1007,24 @@ zfsctl_snapdir_inactive(ap)
 {
 	vnode_t *vp = ap->a_vp;
 	zfsctl_snapdir_t *sdp = vp->v_data;
-	void *private;
+	zfs_snapentry_t *sep;
 
-	private = gfs_dir_inactive(vp);
-	if (private != NULL) {
-		ASSERT(avl_numnodes(&sdp->sd_snaps) == 0);
-		mutex_destroy(&sdp->sd_lock);
-		avl_destroy(&sdp->sd_snaps);
-		kmem_free(private, sizeof (zfsctl_snapdir_t));
+	/*
+	 * On forced unmount we have to free snapshots from here.
+	 */
+	mutex_enter(&sdp->sd_lock);
+	while ((sep = avl_first(&sdp->sd_snaps)) != NULL) {
+		avl_remove(&sdp->sd_snaps, sep);
+		kmem_free(sep->se_name, strlen(sep->se_name) + 1);
+		kmem_free(sep, sizeof (zfs_snapentry_t));
 	}
+	mutex_exit(&sdp->sd_lock);
+	gfs_dir_inactive(vp);
+	ASSERT(avl_numnodes(&sdp->sd_snaps) == 0);
+	mutex_destroy(&sdp->sd_lock);
+	avl_destroy(&sdp->sd_snaps);
+	kmem_free(sdp, sizeof (zfsctl_snapdir_t));
+
 	return (0);
 }
 
@@ -1068,6 +1082,9 @@ zfsctl_snapshot_inactive(ap)
 	int locked;
 	vnode_t *dvp;
 
+	if (vp->v_count > 0)
+		goto end;
+
 	VERIFY(gfs_dir_lookup(vp, "..", &dvp, cr, 0, NULL, NULL) == 0);
 	sdp = dvp->v_data;
 	VOP_UNLOCK(dvp, 0);
@@ -1075,11 +1092,6 @@ zfsctl_snapshot_inactive(ap)
 	if (!(locked = MUTEX_HELD(&sdp->sd_lock)))
 		mutex_enter(&sdp->sd_lock);
 
-	if (vp->v_count > 1) {
-		if (!locked)
-			mutex_exit(&sdp->sd_lock);
-		return (0);
-	}
 	ASSERT(!vn_ismntpt(vp));
 
 	sep = avl_first(&sdp->sd_snaps);
@@ -1099,6 +1111,7 @@ zfsctl_snapshot_inactive(ap)
 	if (!locked)
 		mutex_exit(&sdp->sd_lock);
 	VN_RELE(dvp);
+end:
 	VFS_RELE(vp->v_vfsp);
 
 	/*
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 185d84b4c80..08996ee2a5b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -864,7 +864,7 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp)
 	znode_t *rootzp;
 	int error;
 
-	ZFS_ENTER(zfsvfs);
+	ZFS_ENTER_NOERROR(zfsvfs);
 
 	error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
 	if (error == 0) {
@@ -898,6 +898,9 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
 		 * 'z_parent' is self referential for non-snapshots.
 		 */
 		(void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0);
+#ifdef FREEBSD_NAMECACHE
+		cache_purgevfs(zfsvfs->z_parent->z_vfs);
+#endif
 	}
 
 	/*
@@ -1027,6 +1030,17 @@ zfs_umount(vfs_t *vfsp, int fflag)
 		ASSERT(zfsvfs->z_ctldir == NULL);
 	}
 
+	if (fflag & MS_FORCE) {
+		/*
+		 * Mark file system as unmounted before calling
+		 * vflush(FORCECLOSE). This way we ensure no future vnops
+		 * will be called and risk operating on DOOMED vnodes.
+		 */
+		rrw_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG);
+		zfsvfs->z_unmounted = B_TRUE;
+		rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
+	}
+
 	/*
 	 * Flush all the files.
 	 */
@@ -1093,8 +1107,7 @@ zfs_umount(vfs_t *vfsp, int fflag)
 	if (zfsvfs->z_issnap) {
 		vnode_t *svp = vfsp->mnt_vnodecovered;
 
-		ASSERT(svp->v_count == 2 || svp->v_count == 1);
-		if (svp->v_count == 2)
+		if (svp->v_count >= 2)
 			VN_RELE(svp);
 	}
 	zfs_freevfs(vfsp);
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 082198f63d4..c43a8500818 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
@@ -890,17 +890,25 @@ again:
 		if (zp->z_unlinked) {
 			err = ENOENT;
 		} else {
-			if ((vp = ZTOV(zp)) != NULL) {
-				VI_LOCK(vp);
-				if ((vp->v_iflag & VI_DOOMED) != 0) {
-					VI_UNLOCK(vp);
-					vp = NULL;
-				} else
-					VI_UNLOCK(vp);
-			}
-			if (vp != NULL)
-				VN_HOLD(vp);
+			int dying = 0;
+
+			vp = ZTOV(zp);
+			if (vp == NULL)
+				dying = 1;
 			else {
+				VN_HOLD(vp);
+				if ((vp->v_iflag & VI_DOOMED) != 0) {
+					dying = 1;
+					/*
+					 * Don't VN_RELE() vnode here, because
+					 * it can call vn_lock() which creates
+					 * LOR between vnode lock and znode
+					 * lock. We will VN_RELE() the vnode
+					 * after droping znode lock.
+					 */
+				}
+			}
+			if (dying) {
 				if (first) {
 					ZFS_LOG(1, "dying znode detected (zp=%p)", zp);
 					first = 0;
@@ -912,6 +920,8 @@ again:
 				dmu_buf_rele(db, NULL);
 				mutex_exit(&zp->z_lock);
 				ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
+				if (vp != NULL)
+					VN_RELE(vp);
 				tsleep(zp, 0, "zcollide", 1);
 				goto again;
 			}
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index 7b4eacfd8db..3bb9a6a2880 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -1332,7 +1332,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
 			tl = nfsm_dissect_nonblock(u_int32_t *,
 			    NFSX_V3CREATEVERF);
 			/* Unique bytes, endianness is not important. */
-			cverf.tv_sec  = tl[0];
+			cverf.tv_sec  = (int32_t)tl[0];
 			cverf.tv_nsec = tl[1];
 			exclusive_flag = 1;
 			break;

From f785216c4f22686c8a782dc5806dde132b203a3a Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Tue, 29 Sep 2009 12:18:23 +0000
Subject: [PATCH 0284/2592] Update 802.11s mesh support to draft 3.03. This
 includes a revised  frame format for peering and changes to the PERR frames.
 Note that this is incompatible with the previous code.

Reviewed by:	sam
Approved by:	re (kib)
---
 sys/net80211/ieee80211.h      |  10 ++-
 sys/net80211/ieee80211_hwmp.c | 155 +++++++++++++---------------------
 sys/net80211/ieee80211_mesh.c | 112 +++++++++---------------
 sys/net80211/ieee80211_mesh.h |  47 +++++------
 4 files changed, 125 insertions(+), 199 deletions(-)

diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index 5ddca24e69f..712c2a8dcb2 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -708,7 +708,7 @@ enum {
 	IEEE80211_ELEMID_VENDOR		= 221,	/* vendor private */
 
 	/*
-	 * 802.11s IEs based on D3.0 spec and were not assigned by
+	 * 802.11s IEs based on D3.03 spec and were not assigned by
 	 * ANA. Beware changing them because some of them are being
 	 * kept compatible with Linux.
 	 */
@@ -726,10 +726,9 @@ enum {
 	IEEE80211_ELEMID_MESHPREQ	= 68,
 	IEEE80211_ELEMID_MESHPREP	= 69,
 	IEEE80211_ELEMID_MESHPERR	= 70,
-	IEEE80211_ELEMID_MESHPU		= 53,
-	IEEE80211_ELEMID_MESHPUC	= 54,
+	IEEE80211_ELEMID_MESHPXU	= 53,
+	IEEE80211_ELEMID_MESHPXUC	= 54,
 	IEEE80211_ELEMID_MESHAH		= 60, /* Abbreviated Handshake */
-	IEEE80211_ELEMID_MESHPEERVER	= 80, /* Peering Protocol Version */
 };
 
 struct ieee80211_tim_ie {
@@ -925,6 +924,9 @@ enum {
 	IEEE80211_REASON_MESH_INVALID_GTK	= 8,	/* 11s */
 	IEEE80211_REASON_MESH_INCONS_PARAMS	= 9,	/* 11s */
 	IEEE80211_REASON_MESH_INVALID_SECURITY	= 10,	/* 11s */
+	IEEE80211_REASON_MESH_PERR_UNSPEC	= 11,	/* 11s */
+	IEEE80211_REASON_MESH_PERR_NO_FI	= 12,	/* 11s */
+	IEEE80211_REASON_MESH_PERR_DEST_UNREACH	= 13,	/* 11s */
 
 	IEEE80211_STATUS_SUCCESS		= 0,
 	IEEE80211_STATUS_UNSPECIFIED		= 1,
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 040941e8425..2468169122a 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -188,10 +188,7 @@ SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, rannint, CTLTYPE_INT | CTLFLAG_RW,
 
 #define	IEEE80211_HWMP_DEFAULT_MAXHOPS	31
 
-static	ieee80211_recv_action_func hwmp_recv_action_meshpath_preq;
-static	ieee80211_recv_action_func hwmp_recv_action_meshpath_prep;
-static	ieee80211_recv_action_func hwmp_recv_action_meshpath_perr;
-static	ieee80211_recv_action_func hwmp_recv_action_meshpath_rann;
+static	ieee80211_recv_action_func hwmp_recv_action_meshpath;
 
 static struct ieee80211_mesh_proto_path mesh_proto_hwmp = {
 	.mpp_descr	= "HWMP",
@@ -217,16 +214,10 @@ ieee80211_hwmp_init(void)
 	ieee80211_hwmp_rannint = msecs_to_ticks(1*1000);
 
 	/*
-	 * Register action frame handlers.
+	 * Register action frame handler.
 	 */
 	ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
-	    IEEE80211_ACTION_MESHPATH_REQ, hwmp_recv_action_meshpath_preq);
-	ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
-	    IEEE80211_ACTION_MESHPATH_REP, hwmp_recv_action_meshpath_prep);
-	ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
-	    IEEE80211_ACTION_MESHPATH_ERR, hwmp_recv_action_meshpath_perr);
-	ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
-	    IEEE80211_ACTION_MESHPATH_RANN, hwmp_recv_action_meshpath_rann);
+	    IEEE80211_ACTION_MESHPATH_SEL, hwmp_recv_action_meshpath);
 
 	/* NB: default is 5 secs per spec */
 	mesh_proto_hwmp.mpp_inact = msecs_to_ticks(5*1000);
@@ -285,17 +276,23 @@ hwmp_newstate(struct ieee80211vap *vap, enum ieee80211_state ostate, int arg)
 }
 
 static int
-hwmp_recv_action_meshpath_preq(struct ieee80211_node *ni,
+hwmp_recv_action_meshpath(struct ieee80211_node *ni,
 	const struct ieee80211_frame *wh,
 	const uint8_t *frm, const uint8_t *efrm)
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211_meshpreq_ie preq;
+	struct ieee80211_meshprep_ie prep;
+	struct ieee80211_meshperr_ie perr;
+	struct ieee80211_meshrann_ie rann;
 	const uint8_t *iefrm = frm + 2; /* action + code */
+	int found = 0;
 
 	while (efrm - iefrm > 1) {
 		IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
-		if (*iefrm == IEEE80211_ELEMID_MESHPREQ) {
+		switch (*iefrm) {
+		case IEEE80211_ELEMID_MESHPREQ:
+		{
 			const struct ieee80211_meshpreq_ie *mpreq =
 			    (const struct ieee80211_meshpreq_ie *) iefrm;
 			/* XXX > 1 target */
@@ -305,7 +302,7 @@ hwmp_recv_action_meshpath_preq(struct ieee80211_node *ni,
 				    IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
 				    wh, NULL, "%s", "PREQ with wrong len");
 				vap->iv_stats.is_rx_mgtdiscard++;
-				return 1;
+				break;
 			}
 			memcpy(&preq, mpreq, sizeof(preq));
 			preq.preq_id = LE_READ_4(&mpreq->preq_id);
@@ -315,28 +312,11 @@ hwmp_recv_action_meshpath_preq(struct ieee80211_node *ni,
 			preq.preq_targets[0].target_seq =
 			    LE_READ_4(&mpreq->preq_targets[0].target_seq);
 			hwmp_recv_preq(vap, ni, wh, &preq);
-			return 0;
+			found++;
+			break;	
 		}
-		iefrm += iefrm[1] + 2;
-	}
-	IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
-	    wh, NULL, "%s", "PREQ without IE");
-	vap->iv_stats.is_rx_mgtdiscard++;
-	return 0;
-}
-
-static int
-hwmp_recv_action_meshpath_prep(struct ieee80211_node *ni,
-	const struct ieee80211_frame *wh,
-	const uint8_t *frm, const uint8_t *efrm)
-{
-	struct ieee80211vap *vap = ni->ni_vap;
-	struct ieee80211_meshprep_ie prep;
-	const uint8_t *iefrm = frm + 2; /* action + code */
-
-	while (efrm - iefrm > 1) {
-		IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
-		if (*iefrm == IEEE80211_ELEMID_MESHPREP) {
+		case IEEE80211_ELEMID_MESHPREP:
+		{
 			const struct ieee80211_meshprep_ie *mprep =
 			    (const struct ieee80211_meshprep_ie *) iefrm;
 			if (mprep->prep_len !=
@@ -345,7 +325,7 @@ hwmp_recv_action_meshpath_prep(struct ieee80211_node *ni,
 				    IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
 				    wh, NULL, "%s", "PREP with wrong len");
 				vap->iv_stats.is_rx_mgtdiscard++;
-				return 1;
+				break;
 			}
 			memcpy(&prep, mprep, sizeof(prep));
 			prep.prep_targetseq = LE_READ_4(&mprep->prep_targetseq);
@@ -353,28 +333,11 @@ hwmp_recv_action_meshpath_prep(struct ieee80211_node *ni,
 			prep.prep_metric = LE_READ_4(&mprep->prep_metric);
 			prep.prep_origseq = LE_READ_4(&mprep->prep_origseq);
 			hwmp_recv_prep(vap, ni, wh, &prep);
-			return 0;
+			found++;
+			break;
 		}
-		iefrm += iefrm[1] + 2;
-	}
-	IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
-	    wh, NULL, "%s", "PREP without IE");
-	vap->iv_stats.is_rx_mgtdiscard++;
-	return 0;
-}
-
-static int
-hwmp_recv_action_meshpath_perr(struct ieee80211_node *ni,
-	const struct ieee80211_frame *wh,
-	const uint8_t *frm, const uint8_t *efrm)
-{
-	struct ieee80211_meshperr_ie perr;
-	struct ieee80211vap *vap = ni->ni_vap;
-	const uint8_t *iefrm = frm + 2; /* action + code */
-
-	while (efrm - iefrm > 1) {
-		IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
-		if (*iefrm == IEEE80211_ELEMID_MESHPERR) {
+		case IEEE80211_ELEMID_MESHPERR:
+		{
 			const struct ieee80211_meshperr_ie *mperr =
 			    (const struct ieee80211_meshperr_ie *) iefrm;
 			/* XXX > 1 target */
@@ -384,34 +347,17 @@ hwmp_recv_action_meshpath_perr(struct ieee80211_node *ni,
 				    IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
 				    wh, NULL, "%s", "PERR with wrong len");
 				vap->iv_stats.is_rx_mgtdiscard++;
-				return 1;
+				break;
 			}
 			memcpy(&perr, mperr, sizeof(perr));
 			perr.perr_dests[0].dest_seq =
 			    LE_READ_4(&mperr->perr_dests[0].dest_seq);
 			hwmp_recv_perr(vap, ni, wh, &perr);
-			return 0;
+			found++;
+			break;
 		}
-		iefrm += iefrm[1] + 2;
-	}
-	IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
-	    wh, NULL, "%s", "PERR without IE");
-	vap->iv_stats.is_rx_mgtdiscard++;
-	return 0;
-}
-
-static int
-hwmp_recv_action_meshpath_rann(struct ieee80211_node *ni,
-	const struct ieee80211_frame *wh,
-	const uint8_t *frm, const uint8_t *efrm)
-{
-	struct ieee80211vap *vap = ni->ni_vap;
-	struct ieee80211_meshrann_ie rann;
-	const uint8_t *iefrm = frm + 2; /* action + code */
-
-	while (efrm - iefrm > 1) {
-		IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
-		if (*iefrm == IEEE80211_ELEMID_MESHRANN) {
+		case IEEE80211_ELEMID_MESHRANN:
+		{
 			const struct ieee80211_meshrann_ie *mrann =
 			    (const struct ieee80211_meshrann_ie *) iefrm;
 			if (mrann->rann_len !=
@@ -426,13 +372,18 @@ hwmp_recv_action_meshpath_rann(struct ieee80211_node *ni,
 			rann.rann_seq = LE_READ_4(&mrann->rann_seq);
 			rann.rann_metric = LE_READ_4(&mrann->rann_metric);
 			hwmp_recv_rann(vap, ni, wh, &rann);
-			return 0;
+			found++;
+			break;
+		}
 		}
 		iefrm += iefrm[1] + 2;
 	}
-	IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
-	    wh, NULL, "%s", "RANN without IE");
-	vap->iv_stats.is_rx_mgtdiscard++;
+	if (!found) {
+		IEEE80211_DISCARD(vap,
+		    IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
+		    wh, NULL, "%s", "PATH SEL action without IE");
+		vap->iv_stats.is_rx_mgtdiscard++;
+	}
 	return 0;
 }
 
@@ -480,24 +431,21 @@ hwmp_send_action(struct ieee80211_node *ni,
 		return ENOMEM;
 	}
 	*frm++ = IEEE80211_ACTION_CAT_MESHPATH;
+	*frm++ = IEEE80211_ACTION_MESHPATH_SEL;
 	switch (*ie) {
 	case IEEE80211_ELEMID_MESHPREQ:
-		*frm++ = IEEE80211_ACTION_MESHPATH_REQ;
 		frm = hwmp_add_meshpreq(frm,
 		    (struct ieee80211_meshpreq_ie *)ie);
 		break;
 	case IEEE80211_ELEMID_MESHPREP:
-		*frm++ = IEEE80211_ACTION_MESHPATH_REP;
 		frm = hwmp_add_meshprep(frm,
 		    (struct ieee80211_meshprep_ie *)ie);
 		break;
 	case IEEE80211_ELEMID_MESHPERR:
-		*frm++ = IEEE80211_ACTION_MESHPATH_ERR;
 		frm = hwmp_add_meshperr(frm,
 		    (struct ieee80211_meshperr_ie *)ie);
 		break;
 	case IEEE80211_ELEMID_MESHRANN:
-		*frm++ = IEEE80211_ACTION_MESHPATH_RANN;
 		frm = hwmp_add_meshrann(frm,
 		    (struct ieee80211_meshrann_ie *)ie);
 		break;
@@ -528,6 +476,11 @@ hwmp_send_action(struct ieee80211_node *ni,
 	return ic->ic_raw_xmit(ni, m, ¶ms);
 }
 
+#define ADDSHORT(frm, v) do {		\
+	frm[0] = (v) & 0xff;		\
+	frm[1] = (v) >> 8;		\
+	frm += 2;			\
+} while (0)
 #define ADDWORD(frm, v) do {		\
 	LE_WRITE_4(frm, v);		\
 	frm += 4;			\
@@ -592,12 +545,14 @@ hwmp_add_meshperr(uint8_t *frm, const struct ieee80211_meshperr_ie *perr)
 	*frm++ = IEEE80211_ELEMID_MESHPERR;
 	*frm++ = sizeof(struct ieee80211_meshperr_ie) - 2 +
 	    (perr->perr_ndests - 1) * sizeof(*perr->perr_dests);
-	*frm++ = perr->perr_mode;
+	*frm++ = perr->perr_ttl;
 	*frm++ = perr->perr_ndests;
 	for (i = 0; i < perr->perr_ndests; i++) {
+		*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);
+		ADDSHORT(frm, perr->perr_dests[i].dest_rcode);
 	}
 	return frm;
 }
@@ -1138,12 +1093,15 @@ hwmp_send_prep(struct ieee80211_node *ni,
 	    sizeof(struct ieee80211_meshprep_ie));
 }
 
+#define	PERR_DFLAGS(n)	perr.perr_dests[n].dest_flags
 #define	PERR_DADDR(n)	perr.perr_dests[n].dest_addr
 #define	PERR_DSEQ(n)	perr.perr_dests[n].dest_seq
+#define	PERR_DRCODE(n)	perr.perr_dests[n].dest_rcode
 static void
 hwmp_peerdown(struct ieee80211_node *ni)
 {
 	struct ieee80211vap *vap = ni->ni_vap;
+	struct ieee80211_mesh_state *ms = vap->iv_mesh;
 	struct ieee80211_meshperr_ie perr;
 	struct ieee80211_mesh_route *rt;
 	struct ieee80211_hwmp_route *hr;
@@ -1154,19 +1112,27 @@ hwmp_peerdown(struct ieee80211_node *ni)
 	hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
 	IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 	    "%s", "delete route entry");
-	perr.perr_mode = 0;
+	perr.perr_ttl = ms->ms_ttl;
 	perr.perr_ndests = 1;
+	if (hr->hr_seq == 0)
+		PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN;
+	PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC;
 	IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest);
 	PERR_DSEQ(0) = hr->hr_seq;
+	PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH;
 	/* NB: flush everything passing through peer */
 	ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr);
 	hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr);
 }
+#undef	PERR_DFLAGS
 #undef	PERR_DADDR
 #undef	PERR_DSEQ
+#undef	PERR_DRCODE
 
+#define	PERR_DFLAGS(n)	perr->perr_dests[n].dest_flags
 #define	PERR_DADDR(n)	perr->perr_dests[n].dest_addr
 #define	PERR_DSEQ(n)	perr->perr_dests[n].dest_seq
+#define	PERR_DRCODE(n)	perr->perr_dests[n].dest_rcode
 static void
 hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
     const struct ieee80211_frame *wh, const struct ieee80211_meshperr_ie *perr)
@@ -1192,9 +1158,9 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
 		rt = ieee80211_mesh_rt_find(vap, PERR_DADDR(i));
 		if (rt == NULL)
 			continue;
-		hr = IEEE80211_MESH_ROUTE_PRIV(rt,
-		    struct ieee80211_hwmp_route);
-		if (HWMP_SEQ_GEQ(PERR_DSEQ(i), hr->hr_seq)) {
+		hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
+		if (!(PERR_DFLAGS(0) & IEEE80211_MESHPERR_DFLAGS_USN) && 
+		    HWMP_SEQ_GEQ(PERR_DSEQ(i), hr->hr_seq)) {
 			ieee80211_mesh_rt_del(vap, rt->rt_dest);
 			ieee80211_mesh_rt_flush_peer(vap, rt->rt_dest);
 			rt = NULL;
@@ -1205,10 +1171,11 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
 	 * Propagate the PERR if we previously found it on our routing table.
 	 * XXX handle ndest > 1
 	 */
-	if (forward) {
+	if (forward && perr->perr_ttl > 1) {
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 		    "propagate PERR from %s", ether_sprintf(wh->i_addr2));
 		memcpy(&pperr, perr, sizeof(*perr));
+		pperr.perr_ttl--;
 		hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr,
 		    &pperr);
 	}
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 722749576ba..b0bfe8892d0 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -87,10 +87,10 @@ static void	mesh_peer_timeout_backoff(struct ieee80211_node *);
 static void	mesh_peer_timeout_cb(void *);
 static __inline void
 		mesh_peer_timeout_stop(struct ieee80211_node *);
-static int	mesh_verify_meshpeerver(struct ieee80211vap *, const uint8_t *);
 static int	mesh_verify_meshid(struct ieee80211vap *, const uint8_t *);
 static int	mesh_verify_meshconf(struct ieee80211vap *, const uint8_t *);
-static int	mesh_verify_meshpeer(struct ieee80211vap *, const uint8_t *);
+static int	mesh_verify_meshpeer(struct ieee80211vap *, uint8_t,
+    		    const uint8_t *);
 uint32_t	mesh_airtime_calc(struct ieee80211_node *);
 
 /*
@@ -1544,19 +1544,16 @@ static const struct ieee80211_meshpeer_ie *
 mesh_parse_meshpeering_action(struct ieee80211_node *ni,
 	const struct ieee80211_frame *wh,	/* XXX for VERIFY_LENGTH */
 	const uint8_t *frm, const uint8_t *efrm,
-	struct ieee80211_meshpeer_ie *mp)
+	struct ieee80211_meshpeer_ie *mp, uint8_t subtype)
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	const struct ieee80211_meshpeer_ie *mpie;
-	const uint8_t *meshid, *meshconf, *meshpeerver, *meshpeer;
+	const uint8_t *meshid, *meshconf, *meshpeer;
 
-	meshid = meshconf = meshpeerver = meshpeer = NULL;
+	meshid = meshconf = meshpeer = NULL;
 	while (efrm - frm > 1) {
 		IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return NULL);
 		switch (*frm) {
-		case IEEE80211_ELEMID_MESHPEERVER:
-			meshpeerver = frm;
-			break;
 		case IEEE80211_ELEMID_MESHID:
 			meshid = frm;
 			break;
@@ -1567,12 +1564,10 @@ mesh_parse_meshpeering_action(struct ieee80211_node *ni,
 			meshpeer = frm;
 			mpie = (const struct ieee80211_meshpeer_ie *) frm;
 			memset(mp, 0, sizeof(*mp));
-			mp->peer_subtype = mpie->peer_subtype;
 			mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid);
 			/* NB: peer link ID is optional on these frames */
-			if (mpie->peer_subtype ==
-			    IEEE80211_MESH_PEER_LINK_CLOSE &&
-			    mpie->peer_len == 5) {
+			if (subtype == IEEE80211_MESH_PEER_LINK_CLOSE &&
+			    mpie->peer_len == 8) {
 				mp->peer_linkid = 0;
 				mp->peer_rcode = LE_READ_2(&mpie->peer_linkid);
 			} else {
@@ -1589,12 +1584,12 @@ mesh_parse_meshpeering_action(struct ieee80211_node *ni,
 	 * close subtype don't have a Mesh Configuration IE.
 	 * If if fails validation, close the peer link.
 	 */
-	KASSERT(meshpeer != NULL && mp->peer_subtype !=
-	    IEEE80211_ACTION_MESHPEERING_CLOSE, ("parsing close action"));
+	KASSERT(meshpeer != NULL &&
+	    subtype != IEEE80211_ACTION_MESHPEERING_CLOSE,
+	    ("parsing close action"));
 
-	if (mesh_verify_meshpeerver(vap, meshpeerver) ||
-	    mesh_verify_meshid(vap, meshid) ||
-	    mesh_verify_meshpeer(vap, meshpeer) ||
+	if (mesh_verify_meshid(vap, meshid) ||
+	    mesh_verify_meshpeer(vap, subtype, meshpeer) ||
 	    mesh_verify_meshconf(vap, meshconf)) {
 		uint16_t args[3];
 
@@ -1638,7 +1633,8 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni,
 	uint16_t args[3];
 
 	/* +2+2 for action + code + capabilites */
-	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2, efrm, &ie);
+	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2, efrm, &ie,
+	    IEEE80211_ACTION_MESHPEERING_OPEN);
 	if (meshpeer == NULL) {
 		return 0;
 	}
@@ -1770,7 +1766,8 @@ mesh_recv_action_meshpeering_confirm(struct ieee80211_node *ni,
 	uint16_t args[3];
 
 	/* +2+2+2+2 for action + code + capabilites + status code + AID */
-	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2+2+2, efrm, &ie);
+	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2+2+2, efrm, &ie,
+	    IEEE80211_ACTION_MESHPEERING_CONFIRM);
 	if (meshpeer == NULL) {
 		return 0;
 	}
@@ -1933,7 +1930,6 @@ mesh_send_action_meshpeering_open(struct ieee80211_node *ni,
 	    ic->ic_headroom + sizeof(struct ieee80211_frame),
 	    sizeof(uint16_t)	/* action+category */
 	    + sizeof(uint16_t)	/* capabilites */
-	    + sizeof(struct ieee80211_meshpeerver_ie)	 
 	    + 2 + IEEE80211_RATE_SIZE	 
 	    + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)	 
 	    + 2 + IEEE80211_MESHID_LEN
@@ -1946,7 +1942,6 @@ mesh_send_action_meshpeering_open(struct ieee80211_node *ni,
 		 *   [1] category
 		 *   [1] action
 		 *   [2] capabilities
-		 *   [tlv] mesh peer protocol version
 		 *   [tlv] rates
 		 *   [tlv] xrates
 		 *   [tlv] mesh id
@@ -1956,7 +1951,6 @@ mesh_send_action_meshpeering_open(struct ieee80211_node *ni,
 		*frm++ = category;
 		*frm++ = action;
 		ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
-		frm = ieee80211_add_meshpeerver(frm, vap);
 		rs = ieee80211_get_suprates(ic, ic->ic_curchan);
 		frm = ieee80211_add_rates(frm, rs);
 		frm = ieee80211_add_xrates(frm, rs);
@@ -1999,7 +1993,6 @@ mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni,
 	    + sizeof(uint16_t)	/* capabilites */
 	    + sizeof(uint16_t)	/* status code */
 	    + sizeof(uint16_t)	/* AID */
-	    + sizeof(struct ieee80211_meshpeerver_ie)	 
 	    + 2 + IEEE80211_RATE_SIZE	 
 	    + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)	 
 	    + 2 + IEEE80211_MESHID_LEN
@@ -2014,7 +2007,6 @@ mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni,
 		 *   [2] capabilities
 		 *   [2] status code
 		 *   [2] association id (peer ID)
-		 *   [tlv] mesh peer protocol version
 		 *   [tlv] rates
 		 *   [tlv] xrates
 		 *   [tlv] mesh id
@@ -2026,7 +2018,6 @@ mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni,
 		ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
 		ADDSHORT(frm, 0);		/* status code */
 		ADDSHORT(frm, args[1]);		/* AID */
-		frm = ieee80211_add_meshpeerver(frm, vap);
 		rs = ieee80211_get_suprates(ic, ic->ic_curchan);
 		frm = ieee80211_add_rates(frm, rs);
 		frm = ieee80211_add_xrates(frm, rs);
@@ -2067,7 +2058,6 @@ mesh_send_action_meshpeering_close(struct ieee80211_node *ni,
 	    ic->ic_headroom + sizeof(struct ieee80211_frame),
 	    sizeof(uint16_t)	/* action+category */
 	    + sizeof(uint16_t)	/* reason code */
-	    + sizeof(struct ieee80211_meshpeerver_ie)
 	    + 2 + IEEE80211_MESHID_LEN
 	    + sizeof(struct ieee80211_meshpeer_ie) 
 	);
@@ -2077,14 +2067,12 @@ mesh_send_action_meshpeering_close(struct ieee80211_node *ni,
 		 *   [1] category
 		 *   [1] action
 		 *   [2] reason code
-		 *   [tlv] mesh peer protocol version
 		 *   [tlv] mesh id
 		 *   [tlv] mesh peer link mgmt
 		 */
 		*frm++ = category;
 		*frm++ = action;
 		ADDSHORT(frm, args[2]);		/* reason code */
-		frm = ieee80211_add_meshpeerver(frm, vap);
 		frm = ieee80211_add_meshid(frm, vap);
 		frm = ieee80211_add_meshpeer(frm,
 		    IEEE80211_MESH_PEER_LINK_CLOSE,
@@ -2278,19 +2266,6 @@ mesh_peer_timeout_cb(void *arg)
 	}
 }
 
-static int
-mesh_verify_meshpeerver(struct ieee80211vap *vap, const uint8_t *ie)
-{
-	static const uint8_t peer[4] = IEEE80211_MESHPEERVER_PEER;
-	const struct ieee80211_meshpeerver_ie *meshpeerver =
-	    (const struct ieee80211_meshpeerver_ie *) ie;
-
-	if (meshpeerver->peerver_len !=
-	    sizeof(struct ieee80211_meshpeerver_ie) - 2)
-		return 1;
-	return memcmp(meshpeerver->peerver_proto, peer, 4);
-}
-
 static int
 mesh_verify_meshid(struct ieee80211vap *vap, const uint8_t *ie)
 {
@@ -2364,26 +2339,28 @@ mesh_verify_meshconf(struct ieee80211vap *vap, const uint8_t *ie)
 }
 
 static int
-mesh_verify_meshpeer(struct ieee80211vap *vap, const uint8_t *ie)
+mesh_verify_meshpeer(struct ieee80211vap *vap, uint8_t subtype,
+    const uint8_t *ie)
 {
 	const struct ieee80211_meshpeer_ie *meshpeer =
 	    (const struct ieee80211_meshpeer_ie *) ie;
 
-	if (meshpeer == NULL)
+	if (meshpeer == NULL || meshpeer->peer_len < 6 ||
+	    meshpeer->peer_len > 10)
 		return 1;
-	switch (meshpeer->peer_subtype) {
+	switch (subtype) {
 	case IEEE80211_MESH_PEER_LINK_OPEN:
-		if (meshpeer->peer_len != 3)
+		if (meshpeer->peer_len != 6)
 			return 1;
 		break;
 	case IEEE80211_MESH_PEER_LINK_CONFIRM:
-		if (meshpeer->peer_len != 5)
+		if (meshpeer->peer_len != 8)
 			return 1;
 		break;
 	case IEEE80211_MESH_PEER_LINK_CLOSE:
-		if (meshpeer->peer_len < 5)
+		if (meshpeer->peer_len < 8)
 			return 1;
-		if (meshpeer->peer_len == 5 && meshpeer->peer_linkid != 0)
+		if (meshpeer->peer_len == 8 && meshpeer->peer_linkid != 0)
 			return 1;
 		if (meshpeer->peer_rcode == 0)
 			return 1;
@@ -2448,25 +2425,6 @@ ieee80211_add_meshconf(uint8_t *frm, struct ieee80211vap *vap)
 	return frm;
 }
 
-/*
- * Add a Mesh Peer Protocol IE to a frame.
- * XXX: needs to grow support for Abbreviated Handshake
- */
-uint8_t *
-ieee80211_add_meshpeerver(uint8_t *frm, struct ieee80211vap *vap)
-{
-	static struct ieee80211_meshpeerver_ie ie = {
-		.peerver_ie 	= IEEE80211_ELEMID_MESHPEERVER,
-		.peerver_len 	= 4,
-		.peerver_proto	= IEEE80211_MESHPEERVER_PEER,
-	};
-
-	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap"));
-
-	memcpy(frm, &ie, sizeof(ie));
-	return frm + sizeof(ie);
-}
-
 /*
  * Add a Mesh Peer Management IE to a frame.
  */
@@ -2474,28 +2432,34 @@ uint8_t *
 ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid,
     uint16_t peerid, uint16_t reason)
 {
+	/* XXX change for AH */
+	static const uint8_t meshpeerproto[4] = IEEE80211_MESH_PEER_PROTO;
+
 	KASSERT(localid != 0, ("localid == 0"));
 
 	*frm++ = IEEE80211_ELEMID_MESHPEER;
 	switch (subtype) {
 	case IEEE80211_MESH_PEER_LINK_OPEN:
-		*frm++ = 3;		/* length */
-		*frm++ = subtype;
+		*frm++ = 6;		/* length */
+		memcpy(frm, meshpeerproto, 4);
+		frm += 4;
 		ADDSHORT(frm, localid);	/* local ID */
 		break;
 	case IEEE80211_MESH_PEER_LINK_CONFIRM:
 		KASSERT(peerid != 0, ("sending peer confirm without peer id"));
-		*frm++ = 5;		/* length */
-		*frm++ = subtype;
+		*frm++ = 8;		/* length */
+		memcpy(frm, meshpeerproto, 4);
+		frm += 4;
 		ADDSHORT(frm, localid);	/* local ID */
 		ADDSHORT(frm, peerid);	/* peer ID */
 		break;
 	case IEEE80211_MESH_PEER_LINK_CLOSE:
 		if (peerid)
-			*frm++ = 7;	/* length */
+			*frm++ = 10;	/* length */
 		else
-			*frm++ = 5;	/* length */
-		*frm++ = subtype;
+			*frm++ = 8;	/* length */
+		memcpy(frm, meshpeerproto, 4);
+		frm += 4;
 		ADDSHORT(frm, localid);	/* local ID */
 		if (peerid)
 			ADDSHORT(frm, peerid);	/* peer ID */
diff --git a/sys/net80211/ieee80211_mesh.h b/sys/net80211/ieee80211_mesh.h
index b02c257a5e5..e3ce79a4945 100644
--- a/sys/net80211/ieee80211_mesh.h
+++ b/sys/net80211/ieee80211_mesh.h
@@ -34,7 +34,7 @@
 #define	IEEE80211_MESH_DEFAULT_TTL	31
 
 /*
- * NB: all structures are__packed  so sizeof works on arm, et. al.
+ * NB: all structures are __packed  so sizeof works on arm, et. al.
  */
 /*
  * 802.11s Information Elements.
@@ -116,28 +116,11 @@ struct ieee80211_meshcngst_ie {
 					   AC_BE, AC_VI, AC_VO */
 } __packed;
 
-/* Peer Version */
-struct ieee80211_meshpeerver_ie {
-	uint8_t		peerver_ie;	/* IEEE80211_ELEMID_MESHPEERVER */
-	uint8_t		peerver_len;
-	uint8_t		peerver_proto[4];
-} __packed;
-/* Mesh Peering Management Protocol */
-#define	IEEE80211_MESHPEERVER_PEER_OUI		0x00, 0x0f, 0xac
-#define	IEEE80211_MESHPEERVER_PEER_VALUE	0x2a
-#define	IEEE80211_MESHPEERVER_PEER	{ IEEE80211_MESHPEERVER_PEER_OUI, \
-					  IEEE80211_MESHPEERVER_PEER_VALUE }
-/* Abbreviated Handshake Protocol */
-#define	IEEE80211_MESHPEERVER_AH_OUI		0x00, 0x0f, 0xac
-#define	IEEE80211_MESHPEERVER_AH_VALUE		0x2b
-#define	IEEE80211_MESHPEERVER_AH	{ IEEE80211_MESHPEERVER_AH_OUI, \
-					  IEEE80211_MESHPEERVER_AH_VALUE }
-
 /* Peer Link Management */
 struct ieee80211_meshpeer_ie {
 	uint8_t		peer_ie;	/* IEEE80211_ELEMID_MESHPEER */
 	uint8_t		peer_len;
-	uint8_t		peer_subtype;
+	uint8_t		peer_proto[4];	/* Peer Management Protocol */
 	uint16_t	peer_llinkid;	/* Local Link ID */
 	uint16_t	peer_linkid;	/* Peer Link ID */
 	uint16_t	peer_rcode;
@@ -150,6 +133,16 @@ enum {
 	/* values 3-255 are reserved */
 };
 
+/* Mesh Peering Management Protocol */
+#define	IEEE80211_MESH_PEER_PROTO_OUI		0x00, 0x0f, 0xac
+#define	IEEE80211_MESH_PEER_PROTO_VALUE		0x2a
+#define	IEEE80211_MESH_PEER_PROTO	{ IEEE80211_MESH_PEER_PROTO_OUI, \
+					  IEEE80211_MESH_PEER_PROTO_VALUE }
+/* Abbreviated Handshake Protocol */
+#define	IEEE80211_MESH_PEER_PROTO_AH_OUI	0x00, 0x0f, 0xac
+#define	IEEE80211_MESH_PEER_PROTO_AH_VALUE	0x2b
+#define	IEEE80211_MESH_PEER_PROTO_AH	{ IEEE80211_MESH_PEER_PROTO_AH_OUI, \
+					  IEEE80211_MESH_PEER_PROTO_AH_VALUE }
 #ifdef notyet
 /* Mesh Channel Switch Annoucement */
 struct ieee80211_meshcsa_ie {
@@ -256,11 +249,15 @@ struct ieee80211_meshprep_ie {
 struct ieee80211_meshperr_ie {
 	uint8_t		perr_ie;	/* IEEE80211_ELEMID_MESHPERR */
 	uint8_t		perr_len;
-	uint8_t		perr_mode;	/* NB: reserved */
+	uint8_t		perr_ttl;
 	uint8_t		perr_ndests;	/* Number of Destinations */
 	struct {
+		uint8_t		dest_flags;
+#define	IEEE80211_MESHPERR_DFLAGS_USN	0x01
+#define	IEEE80211_MESHPERR_DFLAGS_RC	0x02
 		uint8_t		dest_addr[IEEE80211_ADDR_LEN];
 		uint32_t	dest_seq;	/* HWMP Sequence Number */
+		uint16_t	dest_rcode;
 	} __packed perr_dests[1];		/* NB: variable size */
 } __packed;
 
@@ -310,14 +307,11 @@ enum {
 };
 
 /*
- * Mesh Path Selection Action codes.
+ * Mesh Path Selection Action code.
  */
 enum {
-	IEEE80211_ACTION_MESHPATH_REQ	= 0,
-	IEEE80211_ACTION_MESHPATH_REP	= 1,
-	IEEE80211_ACTION_MESHPATH_ERR	= 2,
-	IEEE80211_ACTION_MESHPATH_RANN	= 3,
-	/* 4-255 reserved */
+	IEEE80211_ACTION_MESHPATH_SEL	= 0,
+	/* 1-255 reserved */
 };
 
 /*
@@ -479,7 +473,6 @@ int		ieee80211_mesh_register_proto_path(const
 int		ieee80211_mesh_register_proto_metric(const
 		    struct ieee80211_mesh_proto_metric *);
 
-uint8_t *	ieee80211_add_meshpeerver(uint8_t *, struct ieee80211vap *);
 uint8_t *	ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
 uint8_t *	ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
 uint8_t *	ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,

From 5c58c682cb9c7f550dc2b8fde20081a60f4da7cd Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Tue, 29 Sep 2009 12:20:10 +0000
Subject: [PATCH 0285/2592] Mention 802.11s D3.03 support.

Approved by:	re (implicit)
---
 UPDATING | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/UPDATING b/UPDATING
index d418f2dc3a4..35bb2dc7e15 100644
--- a/UPDATING
+++ b/UPDATING
@@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
 	to maximize performance.  (To disable malloc debugging, run
 	ln -s aj /etc/malloc.conf.)
 
+20090929:
+	802.11s D3.03 support was committed. This is incompatible with
+	the previous code, which was based on D3.0.
+
 20090915:
 	ZFS snapshots are now mounted with MNT_IGNORE flag. Use -v option for
 	mount(8) and -a option for df(1) to see them.

From d89eb6fc62f2dd5a3d189c570126638ceac9c0d1 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Tue, 29 Sep 2009 18:44:34 +0000
Subject: [PATCH 0286/2592] MFC r197297

Add a knob to show 'Starting foo:' messages when faststart is used,
such as at boot time.

MFC 197619

By popular acclaim, enable "Starting foo:" messages by default

Approved by:	re (bz)
---
 etc/defaults/rc.conf     | 1 +
 etc/rc.subr              | 8 +++++++-
 share/man/man5/rc.conf.5 | 9 ++++++++-
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index 72c120927da..d64a647a49c 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -23,6 +23,7 @@
 
 rc_debug="NO"		# Set to YES to enable debugging output from rc.d
 rc_info="NO"		# Enables display of informational messages at boot.
+rc_startmsgs="YES" 	# Show "Starting foo:" messages at boot
 rcshutdown_timeout="30" # Seconds to wait before terminating rc.shutdown
 early_late_divider="FILESYSTEMS"	# Script that separates early/late
 			# stages of the boot process.  Make sure you know
diff --git a/etc/rc.subr b/etc/rc.subr
index f8e211a4a2a..86e8c7d8f12 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -680,7 +680,13 @@ run_rc_command()
 
 					# setup the full command to run
 					#
-			[ -z "${rc_quiet}" ] && echo "Starting ${name}."
+			_show_startmsgs=1
+			if [ -n "${rc_quiet}" ]; then
+				if ! checkyesno rc_startmsgs; then
+					unset _show_startmsgs
+				fi
+			fi
+			[ -n "$_show_startmsgs" ] && echo "Starting ${name}."
 			if [ -n "$_chroot" ]; then
 				_doit="\
 ${_nice:+nice -n $_nice }\
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 3075a4e7083..5e7e8c8c712 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 10, 2009
+.Dd September 17, 2009
 .Dt RC.CONF 5
 .Os
 .Sh NAME
@@ -95,6 +95,13 @@ disable informational messages from the rc scripts.
 Informational messages are displayed when
 a condition that is not serious enough to warrant a warning or
 an error occurs.
+.It Va rc_startmsgs
+.Pq Vt bool
+If set to
+.Dq Li YES ,
+show
+.Dq Starting foo:
+when faststart is used (e.g., at boot time).
 .It Va early_late_divider
 .Pq Vt str
 The name of the script that should be used as the

From 10d9c2f79519ea081407b83ae4b19e010b546f6c Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Tue, 29 Sep 2009 19:57:06 +0000
Subject: [PATCH 0287/2592] Update description of debugging support.

Submitted by:	ivoras (but heavily modified)
Pointy hat:	me
Approved by:	re (implicit)
---
 UPDATING | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/UPDATING b/UPDATING
index 35bb2dc7e15..e00ea98b1e8 100644
--- a/UPDATING
+++ b/UPDATING
@@ -8,19 +8,12 @@ Items affecting the ports and packages system can be found in
 /usr/ports/UPDATING.  Please read that file before running
 portupgrade.
 
-NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
-	FreeBSD 8.x has many debugging features turned on, in
-	both the kernel and userland.  These features attempt to detect
-	incorrect use of system primitives, and encourage loud failure
-	through extra sanity checking and fail stop semantics.  They
-	also substantially impact system performance.  If you want to
-	do performance measurement, benchmarking, and optimization,
-	you'll want to turn them off.  This includes various WITNESS-
-	related kernel options, INVARIANTS, malloc debugging flags
-	in userland, and various verbose features in the kernel.  Many
-	developers choose to disable these features on build machines
-	to maximize performance.  (To disable malloc debugging, run
-	ln -s aj /etc/malloc.conf.)
+NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
+	For ia64 the INVARIANTS and INVARIANTS_SUPPORT kernel options
+	were left in the GENERIC kernel because the kernel does not
+	work properly without them.  For sun4v all of the normal kernel
+	debugging tools present in HEAD were left in place because
+	sun4v support still needs work to become production ready.
 
 20090929:
 	802.11s D3.03 support was committed. This is incompatible with

From 3c5548d5ccce9138186e4091ec6df3ee06efa85b Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Wed, 30 Sep 2009 12:53:21 +0000
Subject: [PATCH 0288/2592] Remove an extra 'S' that snuck in.

Submitted by:	danfe
Approved by:	re (implicit)
---
 UPDATING | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/UPDATING b/UPDATING
index e00ea98b1e8..2642fb6eaf1 100644
--- a/UPDATING
+++ b/UPDATING
@@ -9,7 +9,7 @@ Items affecting the ports and packages system can be found in
 portupgrade.
 
 NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
-	For ia64 the INVARIANTS and INVARIANTS_SUPPORT kernel options
+	For ia64 the INVARIANTS and INVARIANT_SUPPORT kernel options
 	were left in the GENERIC kernel because the kernel does not
 	work properly without them.  For sun4v all of the normal kernel
 	debugging tools present in HEAD were left in place because

From f24f7ffbd42ed1983cf8916e0eea9beaf6cae1bc Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Thu, 1 Oct 2009 10:06:09 +0000
Subject: [PATCH 0289/2592] MFC r197653:   Improve 802.11s comment.

Approved by:	re (kib)
---
 sys/amd64/conf/GENERIC | 2 +-
 sys/i386/conf/GENERIC  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index ddd3035ccdb..24300bd7ae5 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -248,7 +248,7 @@ device		xe		# Xircom pccard Ethernet
 device		wlan		# 802.11 support
 options 	IEEE80211_DEBUG	# enable debug msgs
 options 	IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
-options 	IEEE80211_SUPPORT_MESH	# enable 802.11s D3.0 support
+options 	IEEE80211_SUPPORT_MESH	# enable 802.11s draft support
 device		wlan_wep	# 802.11 WEP support
 device		wlan_ccmp	# 802.11 CCMP support
 device		wlan_tkip	# 802.11 TKIP support
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 62fdff78e53..f3a14f2215a 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -260,7 +260,7 @@ device		xe		# Xircom pccard Ethernet
 device		wlan		# 802.11 support
 options 	IEEE80211_DEBUG	# enable debug msgs
 options 	IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
-options 	IEEE80211_SUPPORT_MESH	# enable 802.11s D3.0 support
+options 	IEEE80211_SUPPORT_MESH	# enable 802.11s draft support
 device		wlan_wep	# 802.11 WEP support
 device		wlan_ccmp	# 802.11 CCMP support
 device		wlan_tkip	# 802.11 TKIP support

From a301d3226a1fe44396f9d3811b2f619d88bfdf60 Mon Sep 17 00:00:00 2001
From: Jamie Gritton 
Date: Thu, 1 Oct 2009 13:11:45 +0000
Subject: [PATCH 0290/2592] MFC r197581, r197583, r197584:

  Set the prison in NFS anon and GSS SVC creds.

Reviewed by:	marcel
Approved by:	re (kib)
---
 sys/kern/vfs_export.c               | 5 +++++
 sys/rpc/rpcsec_gss/svc_rpcsec_gss.c | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index d898c085adb..4185211ec69 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -122,6 +123,8 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
 		np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
 		crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
 		    argp->ex_anon.cr_groups);
+		np->netc_anon->cr_prison = &prison0;
+		prison_hold(np->netc_anon->cr_prison);
 		np->netc_numsecflavors = argp->ex_numsecflavors;
 		bcopy(argp->ex_secflavors, np->netc_secflavors,
 		    sizeof(np->netc_secflavors));
@@ -206,6 +209,8 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
 	np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
 	crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
 	    np->netc_anon->cr_groups);
+	np->netc_anon->cr_prison = &prison0;
+	prison_hold(np->netc_anon->cr_prison);
 	np->netc_numsecflavors = argp->ex_numsecflavors;
 	bcopy(argp->ex_secflavors, np->netc_secflavors,
 	    sizeof(np->netc_secflavors));
diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
index 2e7f3c8df7f..b6e328e6760 100644
--- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
+++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
@@ -449,6 +449,8 @@ rpc_gss_svc_getcred(struct svc_req *req, struct ucred **crp, int *flavorp)
 	cr->cr_uid = cr->cr_ruid = cr->cr_svuid = uc->uid;
 	cr->cr_rgid = cr->cr_svgid = uc->gid;
 	crsetgroups(cr, uc->gidlen, uc->gidlist);
+	cr->cr_prison = &prison0;
+	prison_hold(cr->cr_prison);
 	*crp = crhold(cr);
 
 	return (TRUE);

From 4d1ed2a5c67850c1cd7961b98ab3f8b8bc856be7 Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Thu, 1 Oct 2009 14:42:55 +0000
Subject: [PATCH 0291/2592] MFC: revision 197535

  Add '#define NFSCLIENT' into opt_nfs.h if the NFSCLIENT variable is 1
  (the default is 1).

  This makes the nfslockd module works for NFS client.

  Reviewed by:	dfr

Approved by:	re (kib)
---
 sys/modules/nfslockd/Makefile | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/sys/modules/nfslockd/Makefile b/sys/modules/nfslockd/Makefile
index c76c2dd5c39..d8255aa7546 100644
--- a/sys/modules/nfslockd/Makefile
+++ b/sys/modules/nfslockd/Makefile
@@ -14,11 +14,18 @@ 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 

From 1040e2e4d1ce65675408850fea2b506586a72669 Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Fri, 2 Oct 2009 05:11:46 +0000
Subject: [PATCH 0292/2592] MFC r197580   Temporarily disable the use of 1GB
 page mappings by the direct map.

Approved by:	re (kib)
---
 sys/amd64/amd64/pmap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 4e35ef4aedb..97de6b6f8ca 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -440,7 +440,7 @@ create_pagetables(vm_paddr_t *firstaddr)
 	if (ndmpdp < 4)		/* Minimum 4GB of dirmap */
 		ndmpdp = 4;
 	DMPDPphys = allocpages(firstaddr, NDMPML4E);
-	if ((amd_feature & AMDID_PAGE1GB) == 0)
+	if (TRUE || (amd_feature & AMDID_PAGE1GB) == 0)
 		DMPDphys = allocpages(firstaddr, ndmpdp);
 	dmaplimit = (vm_paddr_t)ndmpdp << PDPSHIFT;
 
@@ -474,7 +474,7 @@ create_pagetables(vm_paddr_t *firstaddr)
 
 	/* Now set up the direct map space using either 2MB or 1GB pages */
 	/* Preset PG_M and PG_A because demotion expects it */
-	if ((amd_feature & AMDID_PAGE1GB) == 0) {
+	if (TRUE || (amd_feature & AMDID_PAGE1GB) == 0) {
 		for (i = 0; i < NPDEPG * ndmpdp; i++) {
 			((pd_entry_t *)DMPDphys)[i] = (vm_paddr_t)i << PDRSHIFT;
 			((pd_entry_t *)DMPDphys)[i] |= PG_RW | PG_V | PG_PS |

From bc7f0010f1fcc8c3d8a8d17de6b4848a949a9919 Mon Sep 17 00:00:00 2001
From: "Simon L. B. Nielsen" 
Date: Fri, 2 Oct 2009 17:58:47 +0000
Subject: [PATCH 0293/2592] MFC r197711:

Add no zero mapping feature.

NOTE: Unlike in the other branches where this change will be "merged"
to, the 'no zero mapping' is enabled by default in stable/8.

Errata:		FreeBSD-EN-09:05.null
Approved by:	re (kib)
---
 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 abc16e17afe..ce0ea9e6d06 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -492,6 +492,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 721f5d589f6b3f5bc619249ca0034a03cdb98af4 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 2 Oct 2009 18:33:40 +0000
Subject: [PATCH 0294/2592] MFC: r197490

Merge r194204 from amd64/i386:

Enable PRINTF_BUFR_SIZE by default.

PR:		139134
Approved by:	re (kib)
---
 sys/sparc64/conf/GENERIC | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index 09e56e93ffd..99a0e24aa2c 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -68,6 +68,7 @@ options 	SYSVMSG			# SYSV-style message queues
 options 	SYSVSEM			# SYSV-style semaphores
 options 	P1003_1B_SEMAPHORES	# POSIX-style semaphores
 options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	PRINTF_BUFR_SIZE=128	# Prevent printf output being interspersed.
 options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
 options 	AUDIT			# Security event auditing
 options 	MAC			# TrustedBSD MAC Framework

From 485080c4c4d8007e97844728b902d200f263e9d1 Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Sat, 3 Oct 2009 14:38:22 +0000
Subject: [PATCH 0295/2592] MFC: revision 197657

  MFi386: revision 197653

    Improve 802.11s comment.

Approved by:	re (bz)
---
 sys/pc98/conf/GENERIC | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 27259895662..bb33d1ded97 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -214,7 +214,7 @@ device		xe		# Xircom pccard Ethernet
 #device		wlan		# 802.11 support
 #options 	IEEE80211_DEBUG	# enable debug msgs
 #options 	IEEE80211_AMPDU_AGE	# age frames in AMPDU reorder q's
-#options 	IEEE80211_SUPPORT_MESH	# enable 802.11s D3.0 support
+#options 	IEEE80211_SUPPORT_MESH	# enable 802.11s draft support
 #device		wlan_wep	# 802.11 WEP support
 #device		wlan_ccmp	# 802.11 CCMP support
 #device		wlan_tkip	# 802.11 TKIP support

From 9516a85cc34ee9c24b2e94101d724f162bde1e30 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sun, 4 Oct 2009 09:07:29 +0000
Subject: [PATCH 0296/2592] MFC revision 197683:

Return EOPNOTSUPP instead of EINVAL when doing chflags(2) over an old
format ZFS, as defined in the manual page.

Submitted by:	pjd (response of my original patch but bugs are mine)
Approved by:	re (kib)
---
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 4 ++++
 1 file changed, 4 insertions(+)

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 ae26b888759..d3c828b3984 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
@@ -4172,8 +4172,12 @@ zfs_freebsd_setattr(ap)
 	zflags = VTOZ(vp)->z_phys->zp_flags;
 
 	if (vap->va_flags != VNOVAL) {
+		zfsvfs_t *zfsvfs = VTOZ(vp)->z_zfsvfs;
 		int error;
 
+		if (zfsvfs->z_use_fuids == B_FALSE)
+			return (EOPNOTSUPP);
+
 		fflags = vap->va_flags;
 		if ((fflags & ~(SF_IMMUTABLE|SF_APPEND|SF_NOUNLINK|UF_NODUMP)) != 0)
 			return (EOPNOTSUPP);

From 68ee1aac0a05ac1be2dfa34723f0d5abfe2893d9 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sun, 4 Oct 2009 12:11:44 +0000
Subject: [PATCH 0297/2592] MFC r197660: Fix typo.

Approved by:	re (bz, kensmith)
---
 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 cdf757db52f..e11d7998cef 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1888,7 +1888,7 @@ sigtd(struct proc *p, int sig, int prop)
 
 	/*
 	 * Check if current thread can handle the signal without
-	 * switching conetxt to another thread.
+	 * switching context to another thread.
 	 */
 	if (curproc == p && !SIGISMEMBER(curthread->td_sigmask, sig))
 		return (curthread);

From 6832666db46427e200a02c5e9ce19fb7b9270a82 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sun, 4 Oct 2009 12:14:49 +0000
Subject: [PATCH 0298/2592] MFC r197661: Move the annotation for
 vm_map_startup() immediately before the function.

Approved by:	re (bz, kensmith)
---
 sys/vm/vm_map.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index b5651ef99ba..116671294c4 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -116,22 +116,6 @@ __FBSDID("$FreeBSD$");
  *	another, and then marking both regions as copy-on-write.
  */
 
-/*
- *	vm_map_startup:
- *
- *	Initialize the vm_map module.  Must be called before
- *	any other vm_map routines.
- *
- *	Map and entry structures are allocated from the general
- *	purpose memory pool with some exceptions:
- *
- *	- The kernel map and kmem submap are allocated statically.
- *	- Kernel map entries are allocated out of a static pool.
- *
- *	These restrictions are necessary since malloc() uses the
- *	maps and requires map entries.
- */
-
 static struct mtx map_sleep_mtx;
 static uma_zone_t mapentzone;
 static uma_zone_t kmapentzone;
@@ -176,6 +160,22 @@ static void vmspace_zdtor(void *mem, int size, void *arg);
 			start = end;			\
 		}
 
+/*
+ *	vm_map_startup:
+ *
+ *	Initialize the vm_map module.  Must be called before
+ *	any other vm_map routines.
+ *
+ *	Map and entry structures are allocated from the general
+ *	purpose memory pool with some exceptions:
+ *
+ *	- The kernel map and kmem submap are allocated statically.
+ *	- Kernel map entries are allocated out of a static pool.
+ *
+ *	These restrictions are necessary since malloc() uses the
+ *	maps and requires map entries.
+ */
+
 void
 vm_map_startup(void)
 {

From 9072a0309ea8c1e1382614619b08647b45f170a3 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sun, 4 Oct 2009 12:20:59 +0000
Subject: [PATCH 0299/2592] MFC r197663: As a workaround, for Intel CPUs, do
 not use CLFLUSH in pmap_invalidate_cache_range() when self-snoop is
 apparently not reported in cpu features.

Approved by:	re (bz, kensmith)
---
 sys/amd64/amd64/initcpu.c | 6 ++++++
 sys/i386/i386/initcpu.c   | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index c293c1ac00e..0037d66df76 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -165,4 +165,10 @@ initializecpu(void)
 	 */
 	if ((cpu_feature & CPUID_CLFSH) != 0)
 		cpu_clflush_line_size = ((cpu_procinfo >> 8) & 0xff) * 8;
+	/*
+	 * XXXKIB: (temporary) hack to work around traps generated when
+	 * CLFLUSHing APIC registers window.
+	 */
+	if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS))
+		cpu_feature &= ~CPUID_CLFSH;
 }
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index 1ecff1c2504..dc8da0b0f2a 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -717,6 +717,12 @@ initializecpu(void)
 	 */
 	if ((cpu_feature & CPUID_CLFSH) != 0)
 		cpu_clflush_line_size = ((cpu_procinfo >> 8) & 0xff) * 8;
+	/*
+	 * XXXKIB: (temporary) hack to work around traps generated when
+	 * CLFLUSHing APIC registers window.
+	 */
+	if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS))
+		cpu_feature &= ~CPUID_CLFSH;
 
 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
 	/*

From 3a3dfbf8c4c6cc4635b6f4f86fe81b1dfaf9f43b Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 4 Oct 2009 19:03:32 +0000
Subject: [PATCH 0300/2592] MFC r197682

 EHCI Hardware BUG workaround

 The EHCI HW can use the qtd_next field instead of qtd_altnext when a short
 packet is received. This contradicts what is stated in the EHCI datasheet.
 Also the total-bytes field in the status field of the following TD gets
 corrupted upon reception of a short packet!  We work this around in software by
 not queueing more than one job/TD at a time of up to 16Kbytes! The bug has been
 seen on multiple INTEL based EHCI chips.  Other vendors have not been tested
 yet.

 - Applications using /dev/usb/X.Y.Z, where Z is non-zero are affected, but not
   applications using LibUSB v0.1, v1.2 and v2.0.
 - Mass Storage (umass) is affected.

Approved by:	re (kib)
---
 sys/dev/usb/controller/ehci.c | 78 +++++++++++++++++++++++++----------
 1 file changed, 57 insertions(+), 21 deletions(-)

diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c
index 30c9bb967ab..0ab54aafa6b 100644
--- a/sys/dev/usb/controller/ehci.c
+++ b/sys/dev/usb/controller/ehci.c
@@ -131,6 +131,7 @@ struct ehci_std_temp {
 	uint8_t	auto_data_toggle;
 	uint8_t	setup_alt_next;
 	uint8_t	last_frame;
+	uint8_t can_use_next;
 };
 
 void
@@ -1207,11 +1208,6 @@ ehci_non_isoc_done_sub(struct usb_xfer *xfer)
 
 	xfer->td_transfer_cache = td;
 
-	/* update data toggle */
-
-	xfer->endpoint->toggle_next =
-	    (status & EHCI_QTD_TOGGLE_MASK) ? 1 : 0;
-
 #if USB_DEBUG
 	if (status & EHCI_QTD_STATERRS) {
 		DPRINTFN(11, "error, addr=%d, endpt=0x%02x, frame=0x%02x"
@@ -1235,6 +1231,9 @@ ehci_non_isoc_done_sub(struct usb_xfer *xfer)
 static void
 ehci_non_isoc_done(struct usb_xfer *xfer)
 {
+	ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
+	ehci_qh_t *qh;
+	uint32_t status;
 	usb_error_t err = 0;
 
 	DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
@@ -1248,6 +1247,17 @@ ehci_non_isoc_done(struct usb_xfer *xfer)
 	}
 #endif
 
+	/* extract data toggle directly from the QH's overlay area */
+
+	qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
+
+	usb_pc_cpu_invalidate(qh->page_cache);
+
+	status = hc32toh(sc, qh->qh_qtd.qtd_status);
+
+	xfer->endpoint->toggle_next =
+	    (status & EHCI_QTD_TOGGLE_MASK) ? 1 : 0;
+
 	/* reset scanner */
 
 	xfer->td_transfer_cache = xfer->td_transfer_first;
@@ -1348,6 +1358,7 @@ ehci_check_transfer(struct usb_xfer *xfer)
 		}
 	} else {
 		ehci_qtd_t *td;
+		ehci_qh_t *qh;
 
 		/* non-isochronous transfer */
 
@@ -1357,16 +1368,35 @@ ehci_check_transfer(struct usb_xfer *xfer)
 		 */
 		td = xfer->td_transfer_cache;
 
+		qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
+
+		usb_pc_cpu_invalidate(qh->page_cache);
+
+		status = hc32toh(sc, qh->qh_qtd.qtd_status);
+		if (status & EHCI_QTD_ACTIVE) {
+			/* transfer is pending */
+			goto done;
+		}
+
 		while (1) {
 			usb_pc_cpu_invalidate(td->page_cache);
 			status = hc32toh(sc, td->qtd_status);
 
 			/*
-			 * if there is an active TD the transfer isn't done
+			 * Check if there is an active TD which
+			 * indicates that the transfer isn't done.
 			 */
 			if (status & EHCI_QTD_ACTIVE) {
 				/* update cache */
-				xfer->td_transfer_cache = td;
+				if (xfer->td_transfer_cache != td) {
+					xfer->td_transfer_cache = td;
+					if (qh->qh_qtd.qtd_next & 
+					    htohc32(sc, EHCI_LINK_TERMINATE)) {
+						/* XXX - manually advance to next frame */
+						qh->qh_qtd.qtd_next = td->qtd_self;
+						usb_pc_cpu_flush(td->page_cache);
+					}
+				}
 				goto done;
 			}
 			/*
@@ -1545,7 +1575,6 @@ ehci_setup_standard_chain_sub(struct ehci_std_temp *temp)
 	ehci_qtd_t *td;
 	ehci_qtd_t *td_next;
 	ehci_qtd_t *td_alt_next;
-	uint32_t qtd_altnext;
 	uint32_t buf_offset;
 	uint32_t average;
 	uint32_t len_old;
@@ -1554,7 +1583,6 @@ ehci_setup_standard_chain_sub(struct ehci_std_temp *temp)
 	uint8_t precompute;
 
 	terminate = htohc32(temp->sc, EHCI_LINK_TERMINATE);
-	qtd_altnext = terminate;
 	td_alt_next = NULL;
 	buf_offset = 0;
 	shortpkt_old = temp->shortpkt;
@@ -1612,7 +1640,8 @@ restart:
 
 		td->qtd_status =
 		    temp->qtd_status |
-		    htohc32(temp->sc, EHCI_QTD_SET_BYTES(average));
+		    htohc32(temp->sc, EHCI_QTD_IOC |
+			EHCI_QTD_SET_BYTES(average));
 
 		if (average == 0) {
 
@@ -1687,11 +1716,23 @@ restart:
 			td->qtd_buffer_hi[x] = 0;
 		}
 
-		if (td_next) {
-			/* link the current TD with the next one */
-			td->qtd_next = td_next->qtd_self;
+		if (temp->can_use_next) {
+			if (td_next) {
+				/* link the current TD with the next one */
+				td->qtd_next = td_next->qtd_self;
+			}
+		} else {
+			/*
+			 * BUG WARNING: The EHCI HW can use the
+			 * qtd_next field instead of qtd_altnext when
+			 * a short packet is received! We work this
+			 * around in software by not queueing more
+			 * than one job/TD at a time!
+			 */
+			td->qtd_next = terminate;
 		}
-		td->qtd_altnext = qtd_altnext;
+
+		td->qtd_altnext = terminate;
 		td->alt_next = td_alt_next;
 
 		usb_pc_cpu_flush(td->page_cache);
@@ -1703,15 +1744,9 @@ restart:
 		/* setup alt next pointer, if any */
 		if (temp->last_frame) {
 			td_alt_next = NULL;
-			qtd_altnext = terminate;
 		} else {
 			/* we use this field internally */
 			td_alt_next = td_next;
-			if (temp->setup_alt_next) {
-				qtd_altnext = td_next->qtd_self;
-			} else {
-				qtd_altnext = terminate;
-			}
 		}
 
 		/* restore */
@@ -1756,6 +1791,8 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last)
 	temp.qtd_status = 0;
 	temp.last_frame = 0;
 	temp.setup_alt_next = xfer->flags_int.short_frames_ok;
+	temp.can_use_next = (xfer->flags_int.control_xfr ||
+	    (UE_GET_DIR(xfer->endpointno) == UE_DIR_OUT));
 
 	if (xfer->flags_int.control_xfr) {
 		if (xfer->endpoint->toggle_next) {
@@ -1889,7 +1926,6 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last)
 	/* the last TD terminates the transfer: */
 	td->qtd_next = htohc32(temp.sc, EHCI_LINK_TERMINATE);
 	td->qtd_altnext = htohc32(temp.sc, EHCI_LINK_TERMINATE);
-	td->qtd_status |= htohc32(temp.sc, EHCI_QTD_IOC);
 
 	usb_pc_cpu_flush(td->page_cache);
 

From 6c09384ae8978b35f6d2ff9ae207c2ff204c70fd Mon Sep 17 00:00:00 2001
From: Joe Marcus Clarke 
Date: Sun, 4 Oct 2009 21:46:43 +0000
Subject: [PATCH 0301/2592] MFC: rev. 197681

Correct the pthread stub prototype for pthread_mutexattr_settype to allow for
the type argument.  This is known to fix some pthread_mutexattr_settype()
invocations, especially when it comes to pulseaudio.

Approved by:	re (kib)
---
 lib/libc/gen/_pthread_stubs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libc/gen/_pthread_stubs.c b/lib/libc/gen/_pthread_stubs.c
index a3e55b085ee..147235e485f 100644
--- a/lib/libc/gen/_pthread_stubs.c
+++ b/lib/libc/gen/_pthread_stubs.c
@@ -222,7 +222,7 @@ STUB_FUNC1(pthread_mutex_trylock, PJT_MUTEX_TRYLOCK, int, void *)
 STUB_FUNC1(pthread_mutex_unlock, PJT_MUTEX_UNLOCK, int, void *)
 STUB_FUNC1(pthread_mutexattr_destroy, PJT_MUTEXATTR_DESTROY, int, void *)
 STUB_FUNC1(pthread_mutexattr_init, PJT_MUTEXATTR_INIT, int, void *)
-STUB_FUNC1(pthread_mutexattr_settype, PJT_MUTEXATTR_SETTYPE, int, void *)
+STUB_FUNC2(pthread_mutexattr_settype, PJT_MUTEXATTR_SETTYPE, int, void *, int)
 STUB_FUNC2(pthread_once, 	PJT_ONCE, int, void *, void *)
 STUB_FUNC1(pthread_rwlock_destroy, PJT_RWLOCK_DESTROY, int, void *)
 STUB_FUNC2(pthread_rwlock_init,	PJT_RWLOCK_INIT, int, void *, void *)

From ec89a806b843d692b25c8b732a58d8688d04223d Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Mon, 5 Oct 2009 14:03:26 +0000
Subject: [PATCH 0302/2592] MFC: revision 197709

  Fix build nfscl and/or nfsd.

Approved by:	re (kib)
---
 sys/conf/files | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/sys/conf/files b/sys/conf/files
index 0769151a1c5..0a77c0eb905 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2660,12 +2660,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 c005a51c4e357a1de461a016e8685b212e8ac596 Mon Sep 17 00:00:00 2001
From: Andrew Gallatin 
Date: Mon, 5 Oct 2009 14:28:23 +0000
Subject: [PATCH 0303/2592] MFC:197645 Two more mxge watchdog fixes

1) Restore the PCI Express control register after a watchdog
   reset.  This is required because the device will come out
   of watchdog reset with the pectl reg at its default state,
   and important BIOS configuration (like max payload size)
   could be lost.

2) Call mxge_start_locked() for every tx queue before dropping
   the lock in the watchdog handler.   This is required, as
   the queue's buf ring may have filled during the reset.

Approved by:	re (kib)
---
 sys/dev/mxge/if_mxge.c     | 17 +++++++++++++----
 sys/dev/mxge/if_mxge_var.h |  1 +
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index f41fbf6cfb5..e59d10c13c6 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -3653,10 +3653,16 @@ mxge_setup_cfg_space(mxge_softc_t *sc)
 	if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
 		lnk = pci_read_config(dev, reg + 0x12, 2);
 		sc->link_width = (lnk >> 4) & 0x3f;
-		
-		pectl = pci_read_config(dev, reg + 0x8, 2);
-		pectl = (pectl & ~0x7000) | (5 << 12);
-		pci_write_config(dev, reg + 0x8, pectl, 2);
+
+		if (sc->pectl == 0) {
+			pectl = pci_read_config(dev, reg + 0x8, 2);
+			pectl = (pectl & ~0x7000) | (5 << 12);
+			pci_write_config(dev, reg + 0x8, pectl, 2);
+			sc->pectl = pectl;
+		} else {
+			/* restore saved pectl after watchdog reset */
+			pci_write_config(dev, reg + 0x8, sc->pectl, 2);
+		}
 	}
 
 	/* Enable DMA and Memory space access */
@@ -3768,6 +3774,9 @@ mxge_watchdog_reset(mxge_softc_t *sc, int slice)
 			/* release all TX locks */
 			for (s = 0; s < num_tx_slices; s++) {
 				ss = &sc->ss[s];
+#ifdef IFNET_BUF_RING
+				mxge_start_locked(ss);
+#endif
 				mtx_unlock(&ss->tx.mtx);
 			}
 		}
diff --git a/sys/dev/mxge/if_mxge_var.h b/sys/dev/mxge/if_mxge_var.h
index 47c39b5f019..dedb7ba2e47 100644
--- a/sys/dev/mxge/if_mxge_var.h
+++ b/sys/dev/mxge/if_mxge_var.h
@@ -273,6 +273,7 @@ struct mxge_softc {
 	struct sysctl_ctx_list slice_sysctl_ctx;
 	char *mac_addr_string;
 	uint8_t	mac_addr[6];		/* eeprom mac address */
+	uint16_t pectl;			/* save PCIe CTL state */
 	char product_code_string[64];
 	char serial_number_string[64];
 	char cmd_mtx_name[16];

From 0baf4d94503a2c36e9dcec16db44990e56169826 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Mon, 5 Oct 2009 19:29:25 +0000
Subject: [PATCH 0304/2592] MFC r197461:   Use __NO_STRICT_ALIGNMENT to
 determine whether de(4) have to apply   alignment fixup code for received
 frames on strict alignment   architectures.

MFC r197463:
  Consistently use bus_addr_t.

MFC r197464:
  Destroy dmamap in dma cleanup.

MFC r197465:
  Align Tx/Rx descriptors on 32 bytes boundary instead of PAGE_SIZE.
  Also align setup descriptor on 32 bytes boundary. Tx buffer have no
  alignment limitation so create dmamap without alignment
  restriction[1]. Rx buffer still seems to require 4 bytes alignment
  limitation but we can simply use MCLBYTES for size to map the
  buffer instead of TULIP_DATA_PER_DESC as the buffer is allocated
  with m_getcl(9).
  de(4) supports up to TULIP_MAX_TXSEG segments for Tx buffers,
  increase maximum dma segment size to TULIP_MAX_TXSEG * MCLBYTES.
  While I'm here remove TULIP_DATA_PER_DESC as it is not used anymore.

  This should fix de(4) breakage introduced after r176206.
  Submitted by:	jhb [1]
  Reported by:	WATANABE Kazuhiro < CQG00620 <> nifty dot ne dot jp >
  Tested by:	WATANABE Kazuhiro < CQG00620 <> nifty dot ne dot jp >,
		Takahashi Yoshihiro < nyan <> jp dot freebsd dot org >
Approved by:	re (kib)
---
 sys/dev/de/if_de.c    | 37 +++++++++++++++++++------------------
 sys/dev/de/if_devar.h |  8 ++------
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/sys/dev/de/if_de.c b/sys/dev/de/if_de.c
index 2acf1a8a1c9..c3d283988ae 100644
--- a/sys/dev/de/if_de.c
+++ b/sys/dev/de/if_de.c
@@ -160,7 +160,7 @@ static void	tulip_dma_map_rxbuf(void *, bus_dma_segment_t *, int,
 static void
 tulip_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 {
-    u_int32_t *paddr;
+    bus_addr_t *paddr;
 
     if (error)
 	return;
@@ -182,7 +182,7 @@ tulip_dma_map_rxbuf(void *arg, bus_dma_segment_t *segs, int nseg,
     KASSERT(nseg == 1, ("too many DMA segments"));
     KASSERT(segs[0].ds_len >= TULIP_RX_BUFLEN, ("receive buffer too small"));
 
-    desc->d_addr1 = segs[0].ds_addr;
+    desc->d_addr1 = segs[0].ds_addr & 0xffffffff;
     desc->d_length1 = TULIP_RX_BUFLEN;
 #ifdef not_needed
     /* These should already always be zero. */
@@ -3171,8 +3171,8 @@ tulip_reset(tulip_softc_t * const sc)
 	sc->tulip_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
     }
 
-    TULIP_CSR_WRITE(sc, csr_txlist, sc->tulip_txinfo.ri_dma_addr);
-    TULIP_CSR_WRITE(sc, csr_rxlist, sc->tulip_rxinfo.ri_dma_addr);
+    TULIP_CSR_WRITE(sc, csr_txlist, sc->tulip_txinfo.ri_dma_addr & 0xffffffff);
+    TULIP_CSR_WRITE(sc, csr_rxlist, sc->tulip_rxinfo.ri_dma_addr & 0xffffffff);
     TULIP_CSR_WRITE(sc, csr_busmode,
 		    (1 << (3 /*pci_max_burst_len*/ + 8))
 		    |TULIP_BUSMODE_CACHE_ALIGN8
@@ -3488,7 +3488,7 @@ tulip_rx_intr(tulip_softc_t * const sc)
 	    struct mbuf *m0;
 
 	    KASSERT(ms != NULL, ("no packet to accept"));
-#if defined(TULIP_COPY_RXDATA)
+#ifndef	__NO_STRICT_ALIGNMENT
 	    /*
 	     * Copy the data into a new mbuf that is properly aligned.  If
 	     * we fail to allocate a new mbuf, then drop the packet.  We will
@@ -3527,7 +3527,7 @@ tulip_rx_intr(tulip_softc_t * const sc)
 	     */
 	    ms = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
 
-#if defined(TULIP_COPY_RXDATA)
+#ifndef __NO_STRICT_ALIGNMENT
     skip_input:
 #endif
 	if (ms == NULL) {
@@ -4016,9 +4016,9 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m)
 	eop = nextout;
 	eop->di_desc->d_flag   &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
 	eop->di_desc->d_status  = d_status;
-	eop->di_desc->d_addr1   = segs[segcnt].ds_addr;
+	eop->di_desc->d_addr1   = segs[segcnt].ds_addr & 0xffffffff;
 	eop->di_desc->d_length1 = segs[segcnt].ds_len;
-	eop->di_desc->d_addr2   = segs[segcnt+1].ds_addr;
+	eop->di_desc->d_addr2   = segs[segcnt+1].ds_addr & 0xffffffff;
 	eop->di_desc->d_length2 = segs[segcnt+1].ds_len;
 	d_status = TULIP_DSTS_OWNER;
 	if (++nextout == ri->ri_last)
@@ -4028,7 +4028,7 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m)
 	eop = nextout;
 	eop->di_desc->d_flag   &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
 	eop->di_desc->d_status  = d_status;
-	eop->di_desc->d_addr1   = segs[segcnt].ds_addr;
+	eop->di_desc->d_addr1   = segs[segcnt].ds_addr & 0xffffffff;
 	eop->di_desc->d_length1 = segs[segcnt].ds_len;
 	eop->di_desc->d_addr2   = 0;
 	eop->di_desc->d_length2 = 0;
@@ -4194,7 +4194,7 @@ tulip_txput_setup(tulip_softc_t * const sc)
     nextout->d_length2 = 0;
     nextout->d_addr2 = 0;
     nextout->d_length1 = sizeof(sc->tulip_setupdata);
-    nextout->d_addr1 = sc->tulip_setup_dma_addr;
+    nextout->d_addr1 = sc->tulip_setup_dma_addr & 0xffffffff;
     bus_dmamap_sync(sc->tulip_setup_tag, sc->tulip_setup_map,
 	BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
     TULIP_TXDESC_PRESYNC(ri);
@@ -4491,7 +4491,7 @@ tulip_busdma_freering(tulip_ringinfo_t *ri)
 /* Allocate memory for a single descriptor ring. */
 static int
 tulip_busdma_allocring(device_t dev, tulip_softc_t * const sc, size_t count,
-    bus_size_t maxsize, int nsegs, tulip_ringinfo_t *ri, const char *name)
+    bus_size_t align, int nsegs, tulip_ringinfo_t *ri, const char *name)
 {
     size_t size;
     int error, i;
@@ -4499,7 +4499,7 @@ tulip_busdma_allocring(device_t dev, tulip_softc_t * const sc, size_t count,
     /* First, setup a tag. */
     ri->ri_max = count;
     size = count * sizeof(tulip_desc_t);
-    error = bus_dma_tag_create(NULL, PAGE_SIZE, 0, BUS_SPACE_MAXADDR_32BIT,
+    error = bus_dma_tag_create(NULL, 32, 0, BUS_SPACE_MAXADDR_32BIT,
 	BUS_SPACE_MAXADDR, NULL, NULL, size, 1, size, 0, NULL, NULL,
 	&ri->ri_ring_tag);
     if (error) {
@@ -4527,9 +4527,9 @@ tulip_busdma_allocring(device_t dev, tulip_softc_t * const sc, size_t count,
     }
 
     /* Allocate a tag for the data buffers. */
-    error = bus_dma_tag_create(NULL, 4, 0,
+    error = bus_dma_tag_create(NULL, align, 0,
 	BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
-	maxsize, nsegs, TULIP_DATA_PER_DESC, 0, NULL, NULL, &ri->ri_data_tag);
+	MCLBYTES * nsegs, nsegs, MCLBYTES, 0, NULL, NULL, &ri->ri_data_tag);
     if (error) {
 	device_printf(dev, "failed to allocate %s buffer dma tag\n", name);
 	return (error);
@@ -4563,6 +4563,7 @@ tulip_busdma_cleanup(tulip_softc_t * const sc)
     if (sc->tulip_setupbuf != NULL) {
 	bus_dmamem_free(sc->tulip_setup_tag, sc->tulip_setupbuf,
 	    sc->tulip_setup_map);
+	bus_dmamap_destroy(sc->tulip_setup_tag, sc->tulip_setup_map);
 	sc->tulip_setup_map = NULL;
 	sc->tulip_setupbuf = NULL;
     }
@@ -4586,8 +4587,8 @@ tulip_busdma_init(device_t dev, tulip_softc_t * const sc)
     /*
      * Allocate space and dmamap for transmit ring.
      */
-    error = tulip_busdma_allocring(dev, sc, TULIP_TXDESCS, TULIP_DATA_PER_DESC,
-	TULIP_MAX_TXSEG, &sc->tulip_txinfo, "transmit");
+    error = tulip_busdma_allocring(dev, sc, TULIP_TXDESCS, 1, TULIP_MAX_TXSEG,
+	&sc->tulip_txinfo, "transmit");
     if (error)
 	return (error);
 
@@ -4598,7 +4599,7 @@ tulip_busdma_init(device_t dev, tulip_softc_t * const sc)
      * a waste in practice though as an ethernet frame can easily fit
      * in TULIP_RX_BUFLEN bytes.
      */
-    error = tulip_busdma_allocring(dev, sc, TULIP_RXDESCS, MCLBYTES, 1,
+    error = tulip_busdma_allocring(dev, sc, TULIP_RXDESCS, 4, 1,
 	&sc->tulip_rxinfo, "receive");
     if (error)
 	return (error);
@@ -4606,7 +4607,7 @@ tulip_busdma_init(device_t dev, tulip_softc_t * const sc)
     /*
      * Allocate a DMA tag, memory, and map for setup descriptor
      */
-    error = bus_dma_tag_create(NULL, 4, 0,
+    error = bus_dma_tag_create(NULL, 32, 0,
 	BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
 	sizeof(sc->tulip_setupdata), 1, sizeof(sc->tulip_setupdata), 0,
 	NULL, NULL, &sc->tulip_setup_tag);
diff --git a/sys/dev/de/if_devar.h b/sys/dev/de/if_devar.h
index 3fd341047a6..b4feebc12aa 100644
--- a/sys/dev/de/if_devar.h
+++ b/sys/dev/de/if_devar.h
@@ -104,7 +104,7 @@ typedef struct {
 	tulip_descinfo_t *ri_descinfo;
 	bus_dma_tag_t	ri_ring_tag;
 	bus_dmamap_t	ri_ring_map;
-	uint32_t	ri_dma_addr;
+	bus_addr_t	ri_dma_addr;
 	bus_dma_tag_t	ri_data_tag;
 	bus_dmamap_t	*ri_data_maps;
 } tulip_ringinfo_t;
@@ -134,11 +134,7 @@ typedef struct {
  * architecture which can't handle unaligned accesses) because with
  * 100Mb/s cards the copying is just too much of a hit.
  */
-#if !defined(__i386__)
-#define	TULIP_COPY_RXDATA	1
-#endif
 
-#define	TULIP_DATA_PER_DESC	2032
 #define	TULIP_TXTIMER		4
 #define	TULIP_RXDESCS		48
 #define	TULIP_TXDESCS		128
@@ -560,7 +556,7 @@ struct tulip_softc {
 	 */
 	bus_dma_tag_t		tulip_setup_tag;
 	bus_dmamap_t		tulip_setup_map;
-	uint32_t		tulip_setup_dma_addr;
+	bus_addr_t		tulip_setup_dma_addr;
 	u_int32_t		*tulip_setupbuf;
 	u_int32_t		tulip_setupdata[192 / sizeof(u_int32_t)];
 	char			tulip_boardid[24];

From 4718640084534498f1234d59e5d759df7dfcdc64 Mon Sep 17 00:00:00 2001
From: Coleman Kane 
Date: Tue, 6 Oct 2009 16:05:06 +0000
Subject: [PATCH 0305/2592] MFC: r197403, r197644, r197654, and r197659

Fix some unexpected potential NULL de-references in kernel mode due to
usage of pre-8.0 wifi operations with the ndis driver wrapping a Win32/64
wifi driver.

Submitted by:	Paul B Mahol 
Approved by:	re
---
 sys/dev/if_ndis/if_ndis.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index cd239720399..2c8b32455d7 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -1012,7 +1012,12 @@ static void
 ndis_vap_delete(struct ieee80211vap *vap)
 {
 	struct ndis_vap *nvp = NDIS_VAP(vap);
+	struct ieee80211com *ic = vap->iv_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct ndis_softc *sc = ifp->if_softc;
 
+	ndis_stop(sc);
+	callout_drain(&sc->ndis_scan_callout);
 	ieee80211_vap_detach(vap);
 	free(nvp, M_80211_VAP);
 }
@@ -1529,7 +1534,7 @@ ndis_inputtask(dobj, arg)
 		if (m == NULL)
 			break;
 		KeReleaseSpinLock(&sc->ndis_rxlock, irql);
-		if (sc->ndis_80211)
+		if ((sc->ndis_80211 != 0) && (vap != NULL))
 			vap->iv_deliver_data(vap, vap->iv_bss, m);
 		else
 			(*ifp->if_input)(ifp, m);
@@ -1741,7 +1746,7 @@ ndis_ticktask(d, xsc)
 	    sc->ndis_sts == NDIS_STATUS_MEDIA_CONNECT) {
 		sc->ndis_link = 1;
 		NDIS_UNLOCK(sc);
-		if (sc->ndis_80211) {
+		if ((sc->ndis_80211 != 0) && (vap != NULL)) {
 			ndis_getstate_80211(sc);
 			ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
 		}
@@ -1753,7 +1758,7 @@ ndis_ticktask(d, xsc)
 	    sc->ndis_sts == NDIS_STATUS_MEDIA_DISCONNECT) {
 		sc->ndis_link = 0;
 		NDIS_UNLOCK(sc);
-		if (sc->ndis_80211)
+		if ((sc->ndis_80211 != 0) && (vap != NULL))
 			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
 		NDIS_LOCK(sc);
 		if_link_state_change(sc->ifp, LINK_STATE_DOWN);
@@ -2042,9 +2047,6 @@ ndis_init(xsc)
 	/* Setup task offload. */
 	ndis_set_offload(sc);
 
-	if (sc->ndis_80211)
-		ndis_setstate_80211(sc);
-
 	NDIS_LOCK(sc);
 
 	sc->ndis_txidx = 0;
@@ -2292,8 +2294,6 @@ ndis_setstate_80211(sc)
 	ifp = sc->ifp;
 	ic = ifp->if_l2com;
 	vap = TAILQ_FIRST(&ic->ic_vaps);
-	if (vap == NULL)
-		return;
 
 	if (!NDIS_INITIALIZED(sc)) {
 		DPRINTF(("%s: NDIS not initialized\n", __func__));
@@ -2725,8 +2725,6 @@ ndis_getstate_80211(sc)
 	ifp = sc->ifp;
 	ic = ifp->if_l2com;
 	vap = TAILQ_FIRST(&ic->ic_vaps);
-	if (vap == NULL)
-		return;
 	ni = vap->iv_bss;
 
 	if (!NDIS_INITIALIZED(sc))

From e85f0cc52ddf9f04d5b737409a21841fe540203c Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 6 Oct 2009 18:47:02 +0000
Subject: [PATCH 0307/2592] MFC	r197687

The flow-table associates TCP/UDP flows and IP destinations with
specific routes. When the routing table changes, for example,
when a new route with a more specific prefix is inserted into the
routing table, the flow-table is not updated to reflect that change.
As such existing connections cannot take advantage of the new path.
In some cases the path is broken. This patch will update the affected
flow-table entries when a more specific route is added. The route
entry is properly marked when a route is deleted from the table.
In this case, when the flow-table performs a search, the stale
entry is updated automatically. Therefore this patch is not
necessary for route deletion.

Reviewed by:	bz, kmacy
Approved by:	re
---
 sys/net/flowtable.c | 40 +++++++++++++++++++++++++----
 sys/net/flowtable.h |  2 ++
 sys/net/route.c     | 61 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+), 5 deletions(-)

diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c
index 22cab54e47a..b85ae268081 100644
--- a/sys/net/flowtable.c
+++ b/sys/net/flowtable.c
@@ -830,7 +830,7 @@ fle_free(struct flentry *fle)
 }
 
 static void
-flowtable_free_stale(struct flowtable *ft)
+flowtable_free_stale(struct flowtable *ft, struct rtentry *rt)
 {
 	int curbit = 0, count;
 	struct flentry *fle,  **flehead, *fleprev;
@@ -866,8 +866,14 @@ flowtable_free_stale(struct flowtable *ft)
 			    curbit);
 		}
 #endif		
-		while (fle != NULL) {	
-			if (!flow_stale(ft, fle)) {
+		while (fle != NULL) {
+			if (rt != NULL) {
+				if (__DEVOLATILE(struct rtentry *, fle->f_rt) != rt) {
+					fleprev = fle;
+					fle = fle->f_next;
+					continue;
+				}
+			} else if (!flow_stale(ft, fle)) {
 				fleprev = fle;
 				fle = fle->f_next;
 				continue;
@@ -916,6 +922,30 @@ flowtable_free_stale(struct flowtable *ft)
 		log(LOG_DEBUG, "freed %d flow entries\n", count);
 }
 
+void
+flowtable_route_flush(struct flowtable *ft, struct rtentry *rt)
+{
+	int i;
+	if (ft->ft_flags & FL_PCPU) {
+		for (i = 0; i <= mp_maxid; i++) {
+			if (CPU_ABSENT(i))
+				continue;
+
+			thread_lock(curthread);
+			sched_bind(curthread, i);
+			thread_unlock(curthread);
+
+			flowtable_free_stale(ft, rt);
+
+			thread_lock(curthread);
+			sched_unbind(curthread);
+			thread_unlock(curthread);
+		}
+	} else {
+		flowtable_free_stale(ft, rt);
+	}
+}
+
 static void
 flowtable_clean_vnet(void)
 {
@@ -933,14 +963,14 @@ flowtable_clean_vnet(void)
 				sched_bind(curthread, i);
 				thread_unlock(curthread);
 
-				flowtable_free_stale(ft);
+				flowtable_free_stale(ft, NULL);
 
 				thread_lock(curthread);
 				sched_unbind(curthread);
 				thread_unlock(curthread);
 			}
 		} else {
-			flowtable_free_stale(ft);
+			flowtable_free_stale(ft, NULL);
 		}
 		ft = ft->ft_next;
 	}
diff --git a/sys/net/flowtable.h b/sys/net/flowtable.h
index afc8fb77a03..7d7abdfad15 100644
--- a/sys/net/flowtable.h
+++ b/sys/net/flowtable.h
@@ -51,5 +51,7 @@ struct flowtable *flowtable_alloc(int nentry, int flags);
 int flowtable_lookup(struct flowtable *ft, struct mbuf *m,
     struct route *ro, uint32_t fibnum);
 
+void flowtable_route_flush(struct flowtable *ft, struct rtentry *rt);
+
 #endif /* _KERNEL */
 #endif
diff --git a/sys/net/route.c b/sys/net/route.c
index fc76c924c66..1ab039f6d9a 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -56,6 +56,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef RADIX_MPATH
 #include 
@@ -996,6 +997,9 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
 {
 	int error = 0, needlock = 0;
 	register struct rtentry *rt;
+#ifdef FLOWTABLE
+	register struct rtentry *rt0;
+#endif
 	register struct radix_node *rn;
 	register struct radix_node_head *rnh;
 	struct ifaddr *ifa;
@@ -1153,6 +1157,53 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
 		}
 #endif
 
+#ifdef FLOWTABLE
+		rt0 = NULL;
+		/* XXX
+		 * "flow-table" only support IPv4 at the moment.
+		 */
+		if (dst->sa_family == AF_INET) {
+			rn = rnh->rnh_matchaddr(dst, rnh);
+			if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
+				struct sockaddr *mask;
+				u_char *m, *n;
+				int len;
+				
+				/*
+				 * compare mask to see if the new route is
+				 * more specific than the existing one
+				 */
+				rt0 = RNTORT(rn);
+				RT_LOCK(rt0);
+				RT_ADDREF(rt0);
+				RT_UNLOCK(rt0);
+				/*
+				 * A host route is already present, so 
+				 * leave the flow-table entries as is.
+				 */
+				if (rt0->rt_flags & RTF_HOST) {
+					RTFREE(rt0);
+					rt0 = NULL;
+				} else if (!(flags & RTF_HOST) && netmask) {
+					mask = rt_mask(rt0);
+					len = mask->sa_len;
+					m = (u_char *)mask;
+					n = (u_char *)netmask;
+					while (len-- > 0) {
+						if (*n != *m)
+							break;
+						n++;
+						m++;
+					}
+					if (len == 0 || (*n < *m)) {
+						RTFREE(rt0);
+						rt0 = NULL;
+					}
+				}
+			}
+		}
+#endif
+
 		/* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
 		rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
 		/*
@@ -1165,8 +1216,18 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
 			Free(rt_key(rt));
 			RT_LOCK_DESTROY(rt);
 			uma_zfree(V_rtzone, rt);
+#ifdef FLOWTABLE
+			if (rt0 != NULL)
+				RTFREE(rt0);
+#endif
 			senderr(EEXIST);
+		} 
+#ifdef FLOWTABLE
+		else if (rt0 != NULL) {
+			flowtable_route_flush(V_ip_ft, rt0);
+			RTFREE(rt0);
 		}
+#endif
 
 		/*
 		 * If this protocol has something to add to this then

From 7ec99f713d897bea749f308c63acea27a96d3b0f Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 6 Oct 2009 19:44:44 +0000
Subject: [PATCH 0308/2592] MFC	197695

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
Reviewed by:	bz
Approved by:	re
---
 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 b22d2737f92..d058d8f5131 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 c8c92b5491e2d169b12746df6c30a135983a9104 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 6 Oct 2009 20:33:02 +0000
Subject: [PATCH 0309/2592] MFC	r197696

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.

Approved by:	re
---
 sys/netinet/in.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index d058d8f5131..ae8e2f40d3d 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 815fc7356d82279b0c4f13bdeaa1d3d0557fbc12 Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Tue, 6 Oct 2009 21:23:49 +0000
Subject: [PATCH 0310/2592] MFC r197625: Fix using lp(1) without the new -t
 option after r194171.

Approved by:	re (kib)
---
 usr.sbin/lpr/lp/lp.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/usr.sbin/lpr/lp/lp.sh b/usr.sbin/lpr/lp/lp.sh
index 03ad887b54d..dbec0531d71 100644
--- a/usr.sbin/lpr/lp/lp.sh
+++ b/usr.sbin/lpr/lp/lp.sh
@@ -70,7 +70,7 @@ do
 	s)			# (silent option)
 		: ;;
 	t)			# title for banner page
-		title="-J${OPTARG}";;
+		title="${OPTARG}";;
 	*)			# (error msg printed by getopts)
 		exit 2;;
 	esac
@@ -78,4 +78,4 @@ done
 
 shift $(($OPTIND - 1))
 
-exec /usr/bin/lpr "-P${dest}" ${symlink} ${ncopies} ${mailafter} "${title}" "$@"
+exec /usr/bin/lpr "-P${dest}" ${symlink} ${ncopies} ${mailafter} ${title:+-J"${title}"} "$@"

From a3cd0ffc707a64b3499c18429a73a45606fc0721 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Tue, 6 Oct 2009 22:15:12 +0000
Subject: [PATCH 0311/2592] MFC r197725:

The 6bone was decommissioned on 6/6/06, so remove references to it.

Approved by:	re (kib)
---
 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 8fe1fb2047c24fef84ca785f925fbbda784955a8 Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Wed, 7 Oct 2009 14:14:05 +0000
Subject: [PATCH 0312/2592] MFC: revision 197730

  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

Approved by:	re (kensmith)
---
 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 f41dd6dca9808ff82d32c59f65bf64128bcc2f9a Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Thu, 8 Oct 2009 11:07:15 +0000
Subject: [PATCH 0313/2592] Merge r197795 from head to stable/8:

  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.

  Reported by:        Kamigishi Rei 
  Reviewed by:        bz

Approved by:	re (kib)
---
 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 88c45ef724553a136d0ba4c443426b5f2432757a Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 8 Oct 2009 11:28:32 +0000
Subject: [PATCH 0314/2592] MFC r197662: Do not dereference vp->v_mount without
 holding vnode lock and checking that the vnode is not reclaimed.

Approved by:	re (bz)
---
 sys/kern/uipc_syscalls.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 9717679eb43..a3bd58e501d 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -2085,9 +2085,11 @@ retry_space:
 				/*
 				 * Get the page from backing store.
 				 */
-				bsize = vp->v_mount->mnt_stat.f_iosize;
 				vfslocked = VFS_LOCK_GIANT(vp->v_mount);
-				vn_lock(vp, LK_SHARED | LK_RETRY);
+				error = vn_lock(vp, LK_SHARED);
+				if (error != 0)
+					goto after_read;
+				bsize = vp->v_mount->mnt_stat.f_iosize;
 
 				/*
 				 * XXXMAC: Because we don't have fp->f_cred
@@ -2100,6 +2102,7 @@ retry_space:
 				    IO_VMIO | ((MAXBSIZE / bsize) << IO_SEQSHIFT),
 				    td->td_ucred, NOCRED, &resid, td);
 				VOP_UNLOCK(vp, 0);
+			after_read:
 				VFS_UNLOCK_GIANT(vfslocked);
 				VM_OBJECT_LOCK(obj);
 				vm_page_io_finish(pg);

From 67f0b21fa661065fe7245ebc1ae4d0b0df5d460a Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Thu, 8 Oct 2009 20:58:09 +0000
Subject: [PATCH 0315/2592] MFC r197727:   Put #ifdef INET around parts of the
 FLOWTABLE code, to unbreak   nooptions INET kernel builds.

Approved by:	re (kib)
---
 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 3e5cbaa4c72a530acc8ae0f72a68d0af1d2143ae Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Fri, 9 Oct 2009 09:18:22 +0000
Subject: [PATCH 0316/2592] Merge r197814 from head to stable/8:

  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.

Approved by:	re (kib, bz)
---
 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 02704da213dd2d3b3c294bb5b12932b109a750b0 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 9 Oct 2009 13:25:45 +0000
Subject: [PATCH 0317/2592] MFC: r197274

Fix the example, -w is the right switch for write failure probability.

Approved by:	re (kib)
---
 sbin/geom/class/nop/gnop.8 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sbin/geom/class/nop/gnop.8 b/sbin/geom/class/nop/gnop.8
index 83c33232647..892212c9a62 100644
--- a/sbin/geom/class/nop/gnop.8
+++ b/sbin/geom/class/nop/gnop.8
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 8, 2006
+.Dd September 17, 2009
 .Dt GNOP 8
 .Os
 .Sh NAME
@@ -147,9 +147,9 @@ Exit status is 0 on success, and 1 if the command fails.
 .Sh EXAMPLES
 The following example shows how to create a transparent provider for disk
 .Pa /dev/da0
-with 50% failure probability, and how to destroy it.
+with 50% write failure probability, and how to destroy it.
 .Bd -literal -offset indent
-gnop create -v -f 50 da0
+gnop create -v -w 50 da0
 gnop destroy -v da0.nop
 .Ed
 .Pp

From 9281cc517f03c735c9e2c248e1d7f7ecc2c36ce1 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 9 Oct 2009 13:31:36 +0000
Subject: [PATCH 0318/2592] MFC: r197275

Fix an xref.

Approved by:	re (kib)
---
 sbin/mksnap_ffs/mksnap_ffs.8 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sbin/mksnap_ffs/mksnap_ffs.8 b/sbin/mksnap_ffs/mksnap_ffs.8
index 8361722d808..92e59e55ee7 100644
--- a/sbin/mksnap_ffs/mksnap_ffs.8
+++ b/sbin/mksnap_ffs/mksnap_ffs.8
@@ -69,7 +69,7 @@ mount -o ro /dev/md0 /mnt/
 .Sh SEE ALSO
 .Xr chmod 2 ,
 .Xr chown 8 ,
-.Xr mdconfig 8,
+.Xr mdconfig 8 ,
 .Xr mount 8
 .Sh CAVEATS
 The disk full situation is not handled gracefully and may

From 1cf8c54aaf5ca286b696bc6832794a144ee6e21c Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 9 Oct 2009 13:36:14 +0000
Subject: [PATCH 0319/2592] MFC: r197276

Correct a sysctl name.

Approved by:	re (kib)
---
 share/man/man4/acpi_panasonic.4 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/share/man/man4/acpi_panasonic.4 b/share/man/man4/acpi_panasonic.4
index 8a8851ef1b3..5d8c86ae353 100644
--- a/share/man/man4/acpi_panasonic.4
+++ b/share/man/man4/acpi_panasonic.4
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 11, 2004
+.Dd September 17, 2009
 .Dt ACPI_PANASONIC 4 i386
 .Os
 .Sh NAME
@@ -144,7 +144,7 @@ The following MIBs are available:
 The maximum level of brightness.
 The value is read only and
 automatically set according to hardware model.
-.It Va hw.acpi.panasonic.lcd_brightness_max
+.It Va hw.acpi.panasonic.lcd_brightness_min
 The minimum level of brightness.
 The value is read only and
 automatically set according to hardware model.

From b6144d087bf1baecc0aeb8dc9dc9b3354a49617b Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 9 Oct 2009 13:41:53 +0000
Subject: [PATCH 0320/2592] MFC: r197300

Various mdoc, spelling etc fixes.

Approved by:	re (kib)
---
 share/man/man9/ieee80211.9           |  6 +++---
 share/man/man9/ieee80211_amrr.9      |  2 +-
 share/man/man9/ieee80211_beacon.9    |  2 +-
 share/man/man9/ieee80211_bmiss.9     |  4 ++--
 share/man/man9/ieee80211_crypto.9    | 12 ++++++------
 share/man/man9/ieee80211_ddb.9       |  4 ++--
 share/man/man9/ieee80211_input.9     |  2 +-
 share/man/man9/ieee80211_node.9      |  2 +-
 share/man/man9/ieee80211_output.9    |  8 ++++----
 share/man/man9/ieee80211_proto.9     |  8 ++++----
 share/man/man9/ieee80211_radiotap.9  | 19 +++++++++----------
 share/man/man9/ieee80211_regdomain.9 |  4 ++--
 share/man/man9/ieee80211_scan.9      |  2 +-
 share/man/man9/ieee80211_vap.9       |  2 +-
 14 files changed, 38 insertions(+), 39 deletions(-)

diff --git a/share/man/man9/ieee80211.9 b/share/man/man9/ieee80211.9
index 49fb3ce3487..ba0137dec5d 100644
--- a/share/man/man9/ieee80211.9
+++ b/share/man/man9/ieee80211.9
@@ -225,7 +225,7 @@ Allocate and initialize a
 structure.
 This method cannot sleep.
 The default method allocates zero'd memory using
-.Xr malloc 9.
+.Xr malloc 9 .
 Drivers should override this method to allocate extended storage
 for their own needs.
 Memory allocated by the driver must be tagged with
@@ -301,7 +301,7 @@ This method is called immediately after each channel change
 and must initiate the work to scan a channel and schedule a timer
 to advance to the next channel in the scan list.
 This callback is done in a sleepable context.
-The default method handles active scan work (e.g. sending ProbRequest
+The default method handles active scan work (e.g. sending ProbeRequest
 frames), and schedules a call to 
 .Xr ieee80211_scan_next 9
 according to the maximum dwell time for the channel.
@@ -558,4 +558,4 @@ Device supports Reduced Inter Frame Spacing (RIFS).
 .Xr ieee80211_send_action 9 ,
 .Xr ieee80211_radiotap_attach 9 ,
 .Xr ifnet 9 ,
-.Xr malloc 9 .
+.Xr malloc 9
diff --git a/share/man/man9/ieee80211_amrr.9 b/share/man/man9/ieee80211_amrr.9
index acd70da3dec..8206b2da55d 100644
--- a/share/man/man9/ieee80211_amrr.9
+++ b/share/man/man9/ieee80211_amrr.9
@@ -191,4 +191,4 @@ Drivers that poll a device to retrieve statistics can use
 (instead or in addition).
 .Sh SEE ALSO
 .Xr ieee80211 9 ,
-.Xr ieee80211_output 9 ,
+.Xr ieee80211_output 9
diff --git a/share/man/man9/ieee80211_beacon.9 b/share/man/man9/ieee80211_beacon.9
index 444c433491a..87115fcbd60 100644
--- a/share/man/man9/ieee80211_beacon.9
+++ b/share/man/man9/ieee80211_beacon.9
@@ -112,4 +112,4 @@ Staggering beacon frames is usually superior to bursting frames, up to
 about eight vaps, at which point the overhead becomes significant and
 the channel becomes noticeably busy anyway.
 .Sh SEE ALSO
-.Xr ieee80211 9 .
+.Xr ieee80211 9
diff --git a/share/man/man9/ieee80211_bmiss.9 b/share/man/man9/ieee80211_bmiss.9
index e227ac07744..bd82c3c0b4c 100644
--- a/share/man/man9/ieee80211_bmiss.9
+++ b/share/man/man9/ieee80211_bmiss.9
@@ -86,6 +86,6 @@ Note that software beacon miss handling is not limited to station mode;
 it can be used in any operating mode where beacons from a peer station
 are received.
 .Sh SEE ALSO
-.Xr ieee80211 9 ,
-.Xr ieee80211_vap 9 ,
 .Xr wpa_supplicant 8 ,
+.Xr ieee80211 9 ,
+.Xr ieee80211_vap 9
diff --git a/share/man/man9/ieee80211_crypto.9 b/share/man/man9/ieee80211_crypto.9
index f5a028b64b6..92fe6bba995 100644
--- a/share/man/man9/ieee80211_crypto.9
+++ b/share/man/man9/ieee80211_crypto.9
@@ -65,10 +65,10 @@
 .\"
 .Ft int
 .Fo ieee80211_crypto_newkey
-.Fa "struct ieee80211vap *
-.Fa "int cipher
-.Fa "int flags
-.Fa "struct ieee80211_key *
+.Fa "struct ieee80211vap *"
+.Fa "int cipher"
+.Fa "int flags"
+.Fa "struct ieee80211_key *"
 .Fc
 .\"
 .Ft int
@@ -141,7 +141,7 @@ so it can reclaim resources.
 .Pp
 Crypto modules can notify the system of two events.
 When a packet replay event is recognized
-.Fn ieee80111_notify_replay_failure
+.Fn ieee80211_notify_replay_failure
 can be used to signal the event.
 When a
 .Dv TKIP
@@ -256,4 +256,4 @@ when receive traffic is active.
 .Xr ioctl 2 ,
 .Xr wlan_ccmp 4 ,
 .Xr wlan_tkip 4 ,
-.Xr wlan_wep 4 .
+.Xr wlan_wep 4
diff --git a/share/man/man9/ieee80211_ddb.9 b/share/man/man9/ieee80211_ddb.9
index 19232a78d34..93bee7e4c28 100644
--- a/share/man/man9/ieee80211_ddb.9
+++ b/share/man/man9/ieee80211_ddb.9
@@ -54,7 +54,7 @@ This is especially important because wireless applications are often
 built for embedded environments where cross-machine or post-mortem
 debugging facilities like
 .Xr kgdb 1
-infeasible.
+are infeasible.
 .Pp
 The most commonly used command is
 .Bd -literal -offset indent
@@ -69,4 +69,4 @@ and
 data structures in the system.
 .Sh SEE ALSO
 .Xr ddb 4 ,
-.Xr ieee80211 9 .
+.Xr ieee80211 9
diff --git a/share/man/man9/ieee80211_input.9 b/share/man/man9/ieee80211_input.9
index a0829eefcce..61b11a5b3b1 100644
--- a/share/man/man9/ieee80211_input.9
+++ b/share/man/man9/ieee80211_input.9
@@ -113,4 +113,4 @@ Otherwise the values are made available to user applications
 (with the rssi presented as a filtered average over the last ten values 
 and the noise floor the last reported value).
 .Sh SEE ALSO
-.Xr ieee80211 9 .
+.Xr ieee80211 9
diff --git a/share/man/man9/ieee80211_node.9 b/share/man/man9/ieee80211_node.9
index 59ae87095cb..5d9d4adbe55 100644
--- a/share/man/man9/ieee80211_node.9
+++ b/share/man/man9/ieee80211_node.9
@@ -248,4 +248,4 @@ then a normal lookup is done without a table update.
 .Sh SEE ALSO
 .Xr ddb 9
 .Xr ieee80211 9 ,
-.Xr ieee80211_proto 9 ,
+.Xr ieee80211_proto 9
diff --git a/share/man/man9/ieee80211_output.9 b/share/man/man9/ieee80211_output.9
index c2f9667eb4a..61e480034d3 100644
--- a/share/man/man9/ieee80211_output.9
+++ b/share/man/man9/ieee80211_output.9
@@ -47,9 +47,9 @@
 .\"
 .Ft void
 .Fo ieee80211_process_callback
-.Fa struct ieee80211_node *
-.Fa struct mbuf *
-.Fa int
+.Fa "struct ieee80211_node *"
+.Fa "struct mbuf *"
+.Fa "int"
 .Fc
 .Sh DESCRIPTION
 The
@@ -101,7 +101,7 @@ Similarly,
 .Nm net80211
 handles activities such as background scanning and power save mode,
 frames will not be sent to a driver unless it is operating on the
-BSS channel will
+BSS channel with
 .Dq full power .
 .Pp
 All frames passed to a driver for transmit hold a reference to a
diff --git a/share/man/man9/ieee80211_proto.9 b/share/man/man9/ieee80211_proto.9
index 70a3572e8f8..1938d6ec1c0 100644
--- a/share/man/man9/ieee80211_proto.9
+++ b/share/man/man9/ieee80211_proto.9
@@ -119,7 +119,7 @@ and
 .Vt ic_bsschan
 are guaranteed to be usable.
 .It Dv IEEE80211_S_CSA
-Channel Switch Annoucememnt (CSA) is pending.
+Channel Switch Announcement (CSA) is pending.
 This state is reached only from
 .Dv IEEE80211_S_RUN
 when either a CSA is received from an access point (in station mode)
@@ -229,11 +229,11 @@ handled by
 or, in the case of card eject or vap destroy,
 work will be initiated outside the driver.
 .Sh SEE ALSO
-.Xr ioctl 2
+.Xr ioctl 2 ,
+.Xr wpa_supplicant 8 ,
 .Xr ieee80211 9 ,
-.Xr ifnet 9
+.Xr ifnet 9 ,
 .Xr taskqueue 9
-.Xr wpa_supplicant 8
 .Sh HISTORY
 The state machine concept was part of the original
 .Nm ieee80211
diff --git a/share/man/man9/ieee80211_radiotap.9 b/share/man/man9/ieee80211_radiotap.9
index 092912fc39e..f9f6250f945 100644
--- a/share/man/man9/ieee80211_radiotap.9
+++ b/share/man/man9/ieee80211_radiotap.9
@@ -198,11 +198,11 @@ RF noise power at the antenna, in decibels difference from 1mW.
 .\"power as unitless distance from maximum power set at factory calibration.
 .\"0 indicates maximum transmit power.
 .\"Monotonically nondecreasing with lower power levels.
-\.".It Dv IEEE80211_RADIOTAP_DB_TX_ATTENUATION
-\."This field contains a single unsigned 16-bit value, expressing transmit
-\."power as decibel distance from maximum power set at factory calibration.
-\."0 indicates maximum transmit power.
-\."Monotonically nondecreasing with lower power levels.
+.\".It Dv IEEE80211_RADIOTAP_DB_TX_ATTENUATION
+.\"This field contains a single unsigned 16-bit value, expressing transmit
+.\"power as decibel distance from maximum power set at factory calibration.
+.\"0 indicates maximum transmit power.
+.\"Monotonically nondecreasing with lower power levels.
 .It Dv IEEE80211_RADIOTAP_DBM_TX_POWER
 Transmit power expressed as decibels from a 1mW reference.
 This field is a single signed 8-bit value.
@@ -223,9 +223,9 @@ This field contains a single unsigned 8-bit value that indicates the
 RF noise power at the antenna, in decibels difference from an
 arbitrary, fixed reference.
 .It Dv IEEE80211_RADIOTAP_XCHANNEL
-This field containts four values: a 32-bit unsigned bitmap of
+This field contains four values: a 32-bit unsigned bitmap of
 flags that describe the channel attributes, a 16-bit unsigned
-freqeuncy in MHz (typically the channel center), an 8-bit
+frequency in MHz (typically the channel center), an 8-bit
 unsigned IEEE channel number, and a signed 8-bit value that
 holds the maximum regulatory transmit power cap in .5 dBm
 (8 bytes total).
@@ -237,10 +237,10 @@ This property supersedes
 .Dv IEEE80211_RADIOTAP_CHANNEL
 and is the only way to completely express all
 channel attributes and the
-mapping between channel freqeuncy and IEEE channel number.
+mapping between channel frequency and IEEE channel number.
 .El
 .Sh EXAMPLES
-Radiotap receive definitions for the Intersil Prims driver:
+Radiotap receive definitions for the Intersil Prism driver:
 .Bd -literal -offset indent
 #define WI_RX_RADIOTAP_PRESENT \\
         ((1 << IEEE80211_RADIOTAP_TSFT) \\
@@ -298,7 +298,6 @@ definitions first appeared in
 .\"
 .Sh AUTHORS
 .An -nosplit
-.Pp
 The original version of this manual page was written by
 .An Bruce M. Simpson Aq bms@FreeBSD.org
 and
diff --git a/share/man/man9/ieee80211_regdomain.9 b/share/man/man9/ieee80211_regdomain.9
index 0611ec37cbb..527deb51cbd 100644
--- a/share/man/man9/ieee80211_regdomain.9
+++ b/share/man/man9/ieee80211_regdomain.9
@@ -112,7 +112,7 @@ routine.
 This should be done whenever the channel table contents are modified.
 .Pp
 The
-.Fn ieee80211_alloc_countrie
+.Fn ieee80211_alloc_countryie
 function allocates an information element as specified by 802.11h.
 Because this is expensive to generate it is cached in
 .Vt ic_countryie
@@ -140,4 +140,4 @@ The exact rules by which to operate are still being codified.
 .Sh SEE ALSO
 .Xr regdomain 5 ,
 .Xr ifconfig 8 ,
-.Xr ieee80211 9 .
+.Xr ieee80211 9
diff --git a/share/man/man9/ieee80211_scan.9 b/share/man/man9/ieee80211_scan.9
index 8e1897cf1a6..7ac41bdb903 100644
--- a/share/man/man9/ieee80211_scan.9
+++ b/share/man/man9/ieee80211_scan.9
@@ -347,4 +347,4 @@ request.
 .Sh SEE ALSO
 .Xr ioctl 2 ,
 .Xr ieee80211 9 .
-.Xr ieee80211_proto 9 .
+.Xr ieee80211_proto 9
diff --git a/share/man/man9/ieee80211_vap.9 b/share/man/man9/ieee80211_vap.9
index fc06fff3b9f..c5a5c60756c 100644
--- a/share/man/man9/ieee80211_vap.9
+++ b/share/man/man9/ieee80211_vap.9
@@ -151,4 +151,4 @@ that beacon are stopped before stopping the hardware timers).
 .Sh SEE ALSO
 .Xr ieee80211 9 ,
 .Xr ifnet 9 ,
-.Xr malloc 9 .
+.Xr malloc 9

From b19d265fe05f302f2dac40f88ece701c3c52d788 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 9 Oct 2009 13:46:55 +0000
Subject: [PATCH 0321/2592] MFC: r197310

Fix mdoc, typos, contractions.

Approved by:	re (kib)
---
 share/man/man9/fail.9 | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/share/man/man9/fail.9 b/share/man/man9/fail.9
index bd24b8cc555..ce43346b7a1 100644
--- a/share/man/man9/fail.9
+++ b/share/man/man9/fail.9
@@ -37,7 +37,6 @@
 .Nm KFAIL_POINT_GOTO ,
 .Nm fail_point ,
 .Nm DEBUG_FP
-.
 .Nd fail points
 .Sh SYNOPSIS
 .In sys/fail.h
@@ -79,7 +78,7 @@ is derived from the
 .Fn return
 value set in the sysctl MIB.
 See
-.Sx SYSCTL SETTINGS
+.Sx SYSCTL VARIABLES
 below.
 .Pp
 The remaining
@@ -100,7 +99,6 @@ is the equivalent of
 .Sy KFAIL_POINT_CODE(...,
   { error_var = RETURN_VALUE; goto label;})
 .El
-.Pp
 .Sh SYSCTL VARIABLES
 The
 .Fn KFAIL_POINT_*
@@ -108,28 +106,28 @@ macros add sysctl MIBs where specified.
 Many base kernel MIBs can be found in the
 .Sy debug.fail_point
 tree (referenced in code by
-.Sy DEBUG_FP
-).
+.Sy DEBUG_FP ) .
 .Pp
 The sysctl variable may be set using the following grammar:
 .Pp
+.Bd -literal
    ::
        ( "->"  )*
-.Pp
+
    ::
       ( ( "%") | ( "*" ) )*
       
       [ "("  ")" ]
-.Pp
+
    ::
        [ "."  ] |
       "." 
-.Pp
+
    ::
       "off" | "return" | "sleep" | "panic" | "break" | "print"
+.Ed
 .Pp
-The 
-argument specifies which action to take:
+The  argument specifies which action to take:
 .Bl -tag -width ".Dv return"
 .It Sy off
 Take no action (does not trigger fail point code)
@@ -158,13 +156,13 @@ is evaluated before the count, i.e. "2%5*" means "2% of the time,
 but only 5 times total".
 .Pp
 The operator -> can be used to express cascading terms.
-If you specify ->, it means that if  doesn't
-'execute',  is evaluated.
+If you specify ->, it means that if  does not
+.Ql execute ,
+ is evaluated.
 For the purpose of this operator, the return() and print() operators
 are the only types that cascade.
 A return() term only cascades if the code executes, and a print()
 term only cascades when passed a non-zero argument.
-.Pp
 .Sh EXAMPLES
 .Bl -tag
 .It Sy sysctl debug.fail_point.foobar="2.1%return(5)"
@@ -175,7 +173,7 @@ with RETURN_VALUE set to 5.
 2/100ths of the time, execute
 .Fa code
 with RETURN_VALUE set to 5.
-If that doesn't happen, 5% of the time execute
+If that does not happen, 5% of the time execute
 .Fa code
 with RETURN_VALUE set to 22.
 .It Sy sysctl debug.fail_point.foobar="5*return(5)->0.1%return(22)"
@@ -186,9 +184,8 @@ Return 5 for 1 in 1000 executions, but only 5 times total.
 .It Sy sysctl debug.fail_point.foobar="1%*sleep(50)"
 1/100th of the time, sleep 50ms.
 .El
-.Pp
 .Sh CAVEATS
-It's easy to shoot yourself in the foot by setting fail points too
+It is easy to shoot yourself in the foot by setting fail points too
 aggressively or setting too many in combination.
 For example, forcing
 .Fn malloc
@@ -201,7 +198,6 @@ Currently,
 .Fn fail_point_eval
 does not verify whether the context is appropriate for calling
 .Fn msleep .
-.Pp
 .Sh AUTHORS
 .An -nosplit
 This manual page was written by

From 225cdb4e6cf78145df80ed46ab4955d47e44dcfb Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 9 Oct 2009 13:52:49 +0000
Subject: [PATCH 0322/2592] MFC: r197312

Fix setfib(1) section number.

Approved by:	re (kib)
---
 lib/libc/sys/setfib.2 | 4 ++--
 sbin/ipfw/ipfw.8      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/libc/sys/setfib.2 b/lib/libc/sys/setfib.2
index ca082024d24..a65a064e2f6 100644
--- a/lib/libc/sys/setfib.2
+++ b/lib/libc/sys/setfib.2
@@ -67,8 +67,8 @@ if the
 .Fa fib
 argument is greater than the current system maximum.
 .Sh SEE ALSO
-.Xr setsockopt 2 ,
-.Xr setfib 8 
+.Xr setfib 1 ,
+.Xr setsockopt 2
 .Sh STANDARDS
 The
 .Fn setfib
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index 0d0866521f5..f8b0746a25a 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -869,7 +869,7 @@ The packet is tagged so as to use the FIB (routing table)
 .Ar fibnum
 in any subsequent forwarding decisions.
 Initially this is limited to the values 0 through 15, see
-.Xr setfib 8 .
+.Xr setfib 1 .
 Processing continues at the next rule.
 .It Cm reass
 Queue and reassemble ip fragments.

From 879632020a655570c2e441380ea9d800f95e7620 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Sat, 10 Oct 2009 18:24:54 +0000
Subject: [PATCH 0323/2592] MFC change 197721: 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.

Approved by:	re (kib)
---
 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 f6d21b6ed0831ab52150e8b77f7ff65c34de5166 Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Sun, 11 Oct 2009 16:35:12 +0000
Subject: [PATCH 0324/2592] MFC r196483,r196634: sh: Fix crash when undefining
 or redefining a currently executing function

Add a reference count to function definitions.
Memory may leak if a SIGINT arrives in interactive mode at exactly the wrong
time, this will be fixed later by changing SIGINT handling.

PR:		bin/137640
Approved by:	re (kib)
---
 bin/sh/eval.c                             |  7 +++-
 bin/sh/exec.c                             |  8 ++--
 bin/sh/exec.h                             |  3 +-
 bin/sh/mknodes.c                          |  7 +++-
 bin/sh/nodes.c.pat                        | 46 ++++++++++++++++++-----
 tools/regression/bin/sh/execution/func1.0 |  4 ++
 tools/regression/bin/sh/execution/func2.0 | 11 ++++++
 7 files changed, 68 insertions(+), 18 deletions(-)
 create mode 100644 tools/regression/bin/sh/execution/func1.0
 create mode 100644 tools/regression/bin/sh/execution/func2.0

diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 39e16602abf..7978b84f051 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -785,6 +785,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
 		INTOFF;
 		savelocalvars = localvars;
 		localvars = NULL;
+		reffunc(cmdentry.u.func);
 		INTON;
 		savehandler = handler;
 		if (setjmp(jmploc.loc)) {
@@ -794,6 +795,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
 				freeparam(&shellparam);
 				shellparam = saveparam;
 			}
+			unreffunc(cmdentry.u.func);
 			poplocalvars();
 			localvars = savelocalvars;
 			handler = savehandler;
@@ -805,11 +807,12 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
 		funcnest++;
 		exitstatus = oexitstatus;
 		if (flags & EV_TESTED)
-			evaltree(cmdentry.u.func, EV_TESTED);
+			evaltree(getfuncnode(cmdentry.u.func), EV_TESTED);
 		else
-			evaltree(cmdentry.u.func, 0);
+			evaltree(getfuncnode(cmdentry.u.func), 0);
 		funcnest--;
 		INTOFF;
+		unreffunc(cmdentry.u.func);
 		poplocalvars();
 		localvars = savelocalvars;
 		freeparam(&shellparam);
diff --git a/bin/sh/exec.c b/bin/sh/exec.c
index 3dc88954243..810782166a9 100644
--- a/bin/sh/exec.c
+++ b/bin/sh/exec.c
@@ -286,7 +286,7 @@ printentry(struct tblentry *cmdp, int verbose)
 		out1fmt("function %s", cmdp->cmdname);
 		if (verbose) {
 			INTOFF;
-			name = commandtext(cmdp->param.func);
+			name = commandtext(getfuncnode(cmdp->param.func));
 			out1c(' ');
 			out1str(name);
 			ckfree(name);
@@ -583,7 +583,7 @@ deletefuncs(void)
 		while ((cmdp = *pp) != NULL) {
 			if (cmdp->cmdtype == CMDFUNCTION) {
 				*pp = cmdp->next;
-				freefunc(cmdp->param.func);
+				unreffunc(cmdp->param.func);
 				ckfree(cmdp);
 			} else {
 				pp = &cmdp->next;
@@ -670,7 +670,7 @@ addcmdentry(char *name, struct cmdentry *entry)
 	INTOFF;
 	cmdp = cmdlookup(name, 1);
 	if (cmdp->cmdtype == CMDFUNCTION) {
-		freefunc(cmdp->param.func);
+		unreffunc(cmdp->param.func);
 	}
 	cmdp->cmdtype = entry->cmdtype;
 	cmdp->param = entry->u;
@@ -705,7 +705,7 @@ unsetfunc(char *name)
 	struct tblentry *cmdp;
 
 	if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
-		freefunc(cmdp->param.func);
+		unreffunc(cmdp->param.func);
 		delete_cmd_entry();
 		return (0);
 	}
diff --git a/bin/sh/exec.h b/bin/sh/exec.h
index 9f81a6a43df..e3b9acdd84d 100644
--- a/bin/sh/exec.h
+++ b/bin/sh/exec.h
@@ -46,11 +46,12 @@ enum {
 	TYPECMD_TYPE		/* type */
 };
 
+union node;
 struct cmdentry {
 	int cmdtype;
 	union param {
 		int index;
-		union node *func;
+		struct funcdef *func;
 	} u;
 	int special;
 };
diff --git a/bin/sh/mknodes.c b/bin/sh/mknodes.c
index f0afca6800c..1a177f89531 100644
--- a/bin/sh/mknodes.c
+++ b/bin/sh/mknodes.c
@@ -248,8 +248,11 @@ output(char *file)
 	fputs("\tstruct nodelist *next;\n", hfile);
 	fputs("\tunion node *n;\n", hfile);
 	fputs("};\n\n\n", hfile);
-	fputs("union node *copyfunc(union node *);\n", hfile);
-	fputs("void freefunc(union node *);\n", hfile);
+	fputs("struct funcdef;\n", hfile);
+	fputs("struct funcdef *copyfunc(union node *);\n", hfile);
+	fputs("union node *getfuncnode(struct funcdef *);\n", hfile);
+	fputs("void reffunc(struct funcdef *);\n", hfile);
+	fputs("void unreffunc(struct funcdef *);\n", hfile);
 
 	fputs(writer, cfile);
 	while (fgets(line, sizeof line, patfile) != NULL) {
diff --git a/bin/sh/nodes.c.pat b/bin/sh/nodes.c.pat
index 10dab26d2ac..1f5adbbae4a 100644
--- a/bin/sh/nodes.c.pat
+++ b/bin/sh/nodes.c.pat
@@ -35,6 +35,7 @@
 
 #include 
 #include 
+#include 
 /*
  * Routine for dealing with parsed shell commands.
  */
@@ -60,25 +61,40 @@ STATIC struct nodelist *copynodelist(struct nodelist *);
 STATIC char *nodesavestr(char *);
 
 
+struct funcdef {
+	unsigned int refcount;
+	union node n;
+};
 
 /*
  * Make a copy of a parse tree.
  */
 
-union node *
+struct funcdef *
 copyfunc(union node *n)
 {
+	struct funcdef *fn;
+
 	if (n == NULL)
 		return NULL;
-	funcblocksize = 0;
+	funcblocksize = offsetof(struct funcdef, n);
 	funcstringsize = 0;
 	calcsize(n);
-	funcblock = ckmalloc(funcblocksize + funcstringsize);
-	funcstring = (char *)funcblock + funcblocksize;
-	return copynode(n);
+	fn = ckmalloc(funcblocksize + funcstringsize);
+	fn->refcount = 1;
+	funcblock = (char *)fn + offsetof(struct funcdef, n);
+	funcstring = (char *)fn + funcblocksize;
+	copynode(n);
+	return fn;
 }
 
 
+union node *
+getfuncnode(struct funcdef *fn)
+{
+	return fn == NULL ? NULL : &fn->n;
+}
+
 
 STATIC void
 calcsize(union node *n)
@@ -144,14 +160,26 @@ nodesavestr(char *s)
 }
 
 
+void
+reffunc(struct funcdef *fn)
+{
+	if (fn)
+		fn->refcount++;
+}
+
 
 /*
- * Free a parse tree.
+ * Decrement the reference count of a function definition, freeing it
+ * if it falls to 0.
  */
 
 void
-freefunc(union node *n)
+unreffunc(struct funcdef *fn)
 {
-	if (n)
-		ckfree(n);
+	if (fn) {
+		fn->refcount--;
+		if (fn->refcount > 0)
+			return;
+		ckfree(fn);
+	}
 }
diff --git a/tools/regression/bin/sh/execution/func1.0 b/tools/regression/bin/sh/execution/func1.0
new file mode 100644
index 00000000000..317b0058868
--- /dev/null
+++ b/tools/regression/bin/sh/execution/func1.0
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+MALLOC_OPTIONS=J sh -c 'g() { g() { :; }; :; }; g' &&
+MALLOC_OPTIONS=J sh -c 'g() { unset -f g; :; }; g'
diff --git a/tools/regression/bin/sh/execution/func2.0 b/tools/regression/bin/sh/execution/func2.0
new file mode 100644
index 00000000000..affa802a5e2
--- /dev/null
+++ b/tools/regression/bin/sh/execution/func2.0
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+f() { }
+f
+hash -v f >/dev/null
+f() { { }; }
+f
+hash -v f >/dev/null
+f() { { } }
+f
+hash -v f >/dev/null

From 31deab2050df241a61801bbb3fa940247cc4c045 Mon Sep 17 00:00:00 2001
From: "Simon L. B. Nielsen" 
Date: Sun, 11 Oct 2009 16:52:24 +0000
Subject: [PATCH 0325/2592] MFC r197835: - Document that 'Dell PowerEdge R710'
 has bce(4) supported NIC. - Bump document date.

Approved by:	re (kib)
---
 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 931d2a6f9310ed7ba4e404abb95087c869bb8dd6 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sun, 11 Oct 2009 18:14:18 +0000
Subject: [PATCH 0326/2592] MFC r196700:

Manual page for mfiutil(8) is in section 8 now.

Approved by:	re (kib)
---
 share/man/man4/mfi.4 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/share/man/man4/mfi.4 b/share/man/man4/mfi.4
index 5025336bfe4..8ab8d938100 100644
--- a/share/man/man4/mfi.4
+++ b/share/man/man4/mfi.4
@@ -102,9 +102,9 @@ management interface
 An attempt was made to remove a mounted volume.
 .El
 .Sh SEE ALSO
-.Xr mfiutil 1 ,
 .Xr amr 4 ,
-.Xr pci 4
+.Xr pci 4 ,
+.Xr mfiutil 8
 .Sh HISTORY
 The
 .Nm

From 3f4609ac69940b31de532e338fee706036783948 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Mon, 12 Oct 2009 15:32:00 +0000
Subject: [PATCH 0327/2592] MFC r197643, r197735: When releasing a read/shared
 lock we need to use a write memory barrier in order to avoid, on
 architectures which doesn't have strong ordered writes, CPU instructions
 reordering.

Approved by:	re (kib)
---
 sys/kern/kern_lock.c   | 6 +++---
 sys/kern/kern_rwlock.c | 7 ++++---
 sys/kern/kern_sx.c     | 8 ++++----
 sys/sys/rwlock.h       | 7 -------
 sys/sys/sx.h           | 9 +--------
 5 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index e4edccf5da7..3df8cdd6099 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -238,7 +238,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;
@@ -251,7 +251,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;
 		}
@@ -277,7 +277,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;
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index 601af4fefe4..10de56a7773 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -538,7 +538,7 @@ _rw_runlock(struct rwlock *rw, const char *file, int line)
 		 */
 		x = rw->rw_lock;
 		if (RW_READERS(x) > 1) {
-			if (atomic_cmpset_ptr(&rw->rw_lock, x,
+			if (atomic_cmpset_rel_ptr(&rw->rw_lock, x,
 			    x - RW_ONE_READER)) {
 				if (LOCK_LOG_TEST(&rw->lock_object, 0))
 					CTR4(KTR_LOCK,
@@ -556,7 +556,8 @@ _rw_runlock(struct rwlock *rw, const char *file, int line)
 		if (!(x & RW_LOCK_WAITERS)) {
 			MPASS((x & ~RW_LOCK_WRITE_SPINNER) ==
 			    RW_READERS_LOCK(1));
-			if (atomic_cmpset_ptr(&rw->rw_lock, x, RW_UNLOCKED)) {
+			if (atomic_cmpset_rel_ptr(&rw->rw_lock, x,
+			    RW_UNLOCKED)) {
 				if (LOCK_LOG_TEST(&rw->lock_object, 0))
 					CTR2(KTR_LOCK, "%s: %p last succeeded",
 					    __func__, rw);
@@ -594,7 +595,7 @@ _rw_runlock(struct rwlock *rw, const char *file, int line)
 			x |= (v & RW_LOCK_READ_WAITERS);
 		} else
 			queue = TS_SHARED_QUEUE;
-		if (!atomic_cmpset_ptr(&rw->rw_lock, RW_READERS_LOCK(1) | v,
+		if (!atomic_cmpset_rel_ptr(&rw->rw_lock, RW_READERS_LOCK(1) | v,
 		    x)) {
 			turnstile_chain_unlock(&rw->lock_object);
 			continue;
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index b7b12d5b2dc..b15e669b5e8 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -928,7 +928,7 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
 		 * so, just drop one and return.
 		 */
 		if (SX_SHARERS(x) > 1) {
-			if (atomic_cmpset_ptr(&sx->sx_lock, x,
+			if (atomic_cmpset_rel_ptr(&sx->sx_lock, x,
 			    x - SX_ONE_SHARER)) {
 				if (LOCK_LOG_TEST(&sx->lock_object, 0))
 					CTR4(KTR_LOCK,
@@ -946,8 +946,8 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
 		 */
 		if (!(x & SX_LOCK_EXCLUSIVE_WAITERS)) {
 			MPASS(x == SX_SHARERS_LOCK(1));
-			if (atomic_cmpset_ptr(&sx->sx_lock, SX_SHARERS_LOCK(1),
-			    SX_LOCK_UNLOCKED)) {
+			if (atomic_cmpset_rel_ptr(&sx->sx_lock,
+			    SX_SHARERS_LOCK(1), SX_LOCK_UNLOCKED)) {
 				if (LOCK_LOG_TEST(&sx->lock_object, 0))
 					CTR2(KTR_LOCK, "%s: %p last succeeded",
 					    __func__, sx);
@@ -970,7 +970,7 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
 		 * Note that the state of the lock could have changed,
 		 * so if it fails loop back and retry.
 		 */
-		if (!atomic_cmpset_ptr(&sx->sx_lock,
+		if (!atomic_cmpset_rel_ptr(&sx->sx_lock,
 		    SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS,
 		    SX_LOCK_UNLOCKED)) {
 			sleepq_release(&sx->lock_object);
diff --git a/sys/sys/rwlock.h b/sys/sys/rwlock.h
index 50410ffaa0b..ad178261fb9 100644
--- a/sys/sys/rwlock.h
+++ b/sys/sys/rwlock.h
@@ -55,13 +55,6 @@
  *
  * When the lock is not locked by any thread, it is encoded as a read lock
  * with zero waiters.
- *
- * A note about memory barriers.  Write locks need to use the same memory
- * barriers as mutexes: _acq when acquiring a write lock and _rel when
- * releasing a write lock.  Read locks also need to use an _acq barrier when
- * acquiring a read lock.  However, since read locks do not update any
- * locked data (modulo bugs of course), no memory barrier is needed when
- * releasing a read lock.
  */
 
 #define	RW_LOCK_READ		0x01
diff --git a/sys/sys/sx.h b/sys/sys/sx.h
index 4ff693bf14e..67f7d975644 100644
--- a/sys/sys/sx.h
+++ b/sys/sys/sx.h
@@ -63,13 +63,6 @@
  *
  * When the lock is not locked by any thread, it is encoded as a
  * shared lock with zero waiters.
- *
- * A note about memory barriers.  Exclusive locks need to use the same
- * memory barriers as mutexes: _acq when acquiring an exclusive lock
- * and _rel when releasing an exclusive lock.  On the other side,
- * shared lock needs to use an _acq barrier when acquiring the lock
- * but, since they don't update any locked data, no memory barrier is
- * needed when releasing a shared lock.
  */
 
 #define	SX_LOCK_SHARED			0x01
@@ -200,7 +193,7 @@ __sx_sunlock(struct sx *sx, const char *file, int line)
 	uintptr_t x = sx->sx_lock;
 
 	if (x == (SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS) ||
-	    !atomic_cmpset_ptr(&sx->sx_lock, x, x - SX_ONE_SHARER))
+	    !atomic_cmpset_rel_ptr(&sx->sx_lock, x, x - SX_ONE_SHARER))
 		_sx_sunlock_hard(sx, file, line);
 }
 

From dd8eeffea9d30d41c224c2e431c4bf26886e9811 Mon Sep 17 00:00:00 2001
From: Roman Divacky 
Date: Mon, 12 Oct 2009 15:46:17 +0000
Subject: [PATCH 0328/2592] MFC r197812:

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:	re (kib)
---
 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 4dc32a7398a524d5f33c0587d138984e2d83b0b3 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Mon, 12 Oct 2009 16:05:31 +0000
Subject: [PATCH 0329/2592] MFC r197803, r197824, r197910: 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". Not all our memory barriers, right now, clobber
 memory for GCC-like compilers. Fix these cases.

Approved by:	re (kib)
---
 sys/amd64/include/atomic.h | 100 +++++++++++++++++++++----------------
 sys/i386/include/atomic.h  |  94 +++++++++++++++++++---------------
 2 files changed, 113 insertions(+), 81 deletions(-)

diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index d2a3846172d..a2bd93002e8 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
@@ -73,7 +73,8 @@
  */
 #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);
@@ -97,8 +98,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 +109,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
 
@@ -205,18 +216,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 +263,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,44 +344,43 @@ 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_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_int
 #define	atomic_cmpset_rel_int		atomic_cmpset_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_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_long
 #define	atomic_cmpset_rel_long		atomic_cmpset_long
 
diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h
index 8c0b95ce069..b00eb45592f 100644
--- a/sys/i386/include/atomic.h
+++ b/sys/i386/include/atomic.h
@@ -73,7 +73,8 @@
  */
 #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);
 u_int	atomic_fetchadd_int(volatile u_int *p, u_int v);
@@ -95,8 +96,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 +107,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
 
@@ -194,18 +205,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 +252,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
 
@@ -331,44 +348,43 @@ 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_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_int
 #define	atomic_cmpset_rel_int		atomic_cmpset_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_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_long
 #define	atomic_cmpset_rel_long		atomic_cmpset_long
 

From d1c95b4a34b55d34a679de919e9b099d9c2d48fa Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Mon, 12 Oct 2009 20:36:55 +0000
Subject: [PATCH 0330/2592] MFC r197831,r197842,r197843,r197860,r197861:

r197831:

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 

r197842:

Fix white-spaces.

r197843:

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.

r197860:

File system owner is when uid matches and jail matches.

r197861:

Allow file system owner to modify system flags if securelevel permits.

Approved by:	re (kib)
---
 .../opensolaris/kern/opensolaris_policy.c     | 10 +++--
 sys/cddl/compat/opensolaris/sys/policy.h      |  3 +-
 .../opensolaris/uts/common/fs/zfs/vdev_geom.c | 22 +----------
 .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 39 +++++++++++++------
 4 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c b/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c
index cedf335257d..865fba337f5 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);
 }
 
 /*
@@ -359,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/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
index b4bec95f5fb..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
@@ -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;
@@ -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 = {
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 d3c828b3984..a58f76e4b8d 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);
@@ -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;
+			}
+		}
 	}
 
 	/*
@@ -4181,12 +4197,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.
@@ -4197,14 +4207,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 1d93d2aa4f370669154863f6d3355dfde4d09c16 Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Mon, 12 Oct 2009 21:03:07 +0000
Subject: [PATCH 0331/2592] MFC r197896:

Export disk serial numbers for adaX disks.

Reviewed by:	mav
Approved by:	re (kib)
---
 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 69882ff11d6f64b5ec6030b38210535d56b603b6 Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Mon, 12 Oct 2009 21:08:06 +0000
Subject: [PATCH 0332/2592] MFC r197898:

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
Approved by:	re (kib)
---
 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 88b0cad0483..b3261f8bba6 100644
--- a/sys/geom/stripe/g_stripe.c
+++ b/sys/geom/stripe/g_stripe.c
@@ -913,6 +913,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 b509d7d489cf6935903b470224ef098c638ceccf Mon Sep 17 00:00:00 2001
From: Hiroki Sato 
Date: Mon, 12 Oct 2009 21:08:38 +0000
Subject: [PATCH 0333/2592] MFC r197142:

Document accept_rev_ethip_ver and send_rev_ethip_ver flags of
EtherIP (gif(4) + if_bridge(4)).

Approved by:	re (kib)
---
 sbin/ifconfig/ifconfig.8 | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 1d2f0964448..2b0d7d64828 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -2197,6 +2197,24 @@ interfaces previously configured with
 Another name for the
 .Fl tunnel
 parameter.
+.It Cm accept_rev_ethip_ver
+Set a flag to acccept both correct EtherIP packets and ones
+with reversed version field.  Enabled by default.
+This is for backward compatibility with
+.Fx 6.1 ,
+6.2, 6.3, 7.0, and 7.1.
+.It Cm -accept_rev_ethip_ver
+Clear a flag
+.Cm accept_rev_ethip_ver .
+.It Cm send_rev_ethip_ver
+Set a flag to send EtherIP packets with reversed version
+field intentionally.  Disabled by default.
+This is for backward compatibility with
+.Fx 6.1 ,
+6.2, 6.3, 7.0, and 7.1.
+.It Cm -send_rev_ethip_ver
+Clear a flag
+.Cm send_rev_ethip_ver .
 .El
 .Pp
 The following parameters are specific to GRE tunnel interfaces,
@@ -2457,6 +2475,7 @@ tried to alter an interface's configuration.
 .Sh SEE ALSO
 .Xr netstat 1 ,
 .Xr carp 4 ,
+.Xr gif 4 ,
 .Xr netintro 4 ,
 .Xr pfsync 4 ,
 .Xr polling 4 ,

From aba70b5e590d2e3acce46a300640b75afc46c7ee Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 13 Oct 2009 09:24:51 +0000
Subject: [PATCH 0334/2592] MFC r197942: 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.

Approved by:	re (bz)
---
 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 be0ac1601505357fe1fe0ea3557438e6948cb404 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Tue, 13 Oct 2009 13:03:31 +0000
Subject: [PATCH 0335/2592] MFC r197476: In function do_rw_wrlock, when a
 writer got an error and before returning, check if there are readers blocked
 by us via URWLOCK_WRITE_WAITERS flag, and resume the readers. The error must
 be EAGAIN, otherwise there must have memory problem, and nobody can rescue
 the buggy application.

Approved by:	re (kib), davidxu
---
 sys/kern/kern_umtx.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index bcb60edd8d1..2ab099d758f 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -2556,6 +2556,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
 	uint32_t flags;
 	int32_t state, oldstate;
 	int32_t blocked_writers;
+	int32_t blocked_readers;
 	int error;
 
 	uq = td->td_umtxq;
@@ -2564,6 +2565,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
 	if (error != 0)
 		return (error);
 
+	blocked_readers = 0;
 	for (;;) {
 		state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
 		while (!(state & URWLOCK_WRITE_OWNER) && URWLOCK_READER_COUNT(state) == 0) {
@@ -2575,8 +2577,18 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
 			state = oldstate;
 		}
 
-		if (error)
+		if (error) {
+			if (!(state & (URWLOCK_WRITE_OWNER|URWLOCK_WRITE_WAITERS)) &&
+			    blocked_readers != 0) {
+				umtxq_lock(&uq->uq_key);
+				umtxq_busy(&uq->uq_key);
+				umtxq_signal_queue(&uq->uq_key, INT_MAX, UMTX_SHARED_QUEUE);
+				umtxq_unbusy(&uq->uq_key);
+				umtxq_unlock(&uq->uq_key);
+			}
+
 			break;
+		}
 
 		/* grab monitor lock */
 		umtxq_lock(&uq->uq_key);
@@ -2627,7 +2639,9 @@ sleep:
 					break;
 				state = oldstate;
 			}
-		}
+			blocked_readers = fuword32(&rwlock->rw_blocked_readers);
+		} else
+			blocked_readers = 0;
 
 		umtxq_lock(&uq->uq_key);
 		umtxq_unbusy(&uq->uq_key);

From 505c00fa5b7d7bffbec0448ea8b8df78fb68f33c Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Wed, 14 Oct 2009 03:31:37 +0000
Subject: [PATCH 0336/2592] MFC r196439:

Fix the typo mentioned in the PR, and one additional.
Fix caps while I'm here.

PR:		conf/138087
Submitted by:	Chris Petrik 
Approved by:	re (kib)
---
 etc/rc.d/ipsec | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/etc/rc.d/ipsec b/etc/rc.d/ipsec
index 2bb3cf5d63c..0ad54908a14 100755
--- a/etc/rc.d/ipsec
+++ b/etc/rc.d/ipsec
@@ -41,9 +41,9 @@ ipsec_stop()
 {
 	echo "Clearing ipsec manual keys/policies."
 
-	# still not 100% sure if we would like to do this.
-	# it is very questionable to do this during shutdown session, since
-	# it can hang any of remaining IPv4/v6 session.
+	# Still not 100% sure if we would like to do this.
+	# It is very questionable to do this during shutdown session
+	# since it can hang any of the remaining IPv4/v6 sessions.
 	#
 	${ipsec_program} -F
 	${ipsec_program} -FP

From f7bca35675a6e1f1801508485538e999bbf323bc Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Wed, 14 Oct 2009 14:26:19 +0000
Subject: [PATCH 0337/2592] MFC r197958: 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.

Approved by:	re (kensmith)
---
 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 d8e86c4a5d9ce7f0aab10d3d13b6c78ce5c6fca5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ermal=20Lu=C3=A7i?= 
Date: Wed, 14 Oct 2009 15:32:46 +0000
Subject: [PATCH 0338/2592] Fix typo which has survived amazingly long!

Reviewed by:	mlaier(mentor)
Approved by:	re(kib)
---
 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 bef10df88e112610833e4eda54be82d5329e033d Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Wed, 14 Oct 2009 17:26:05 +0000
Subject: [PATCH 0339/2592] MFC r197868. Use correct arguments when calling
 SCTP_RTALLOC(). Approved by: re, rrs (mentor)

---
 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 b2b2cac97aa..4875d22f7a3 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 0dcda942fd0d80eb261330344ffa891498f40a1a Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Thu, 15 Oct 2009 14:39:59 +0000
Subject: [PATCH 0340/2592] Add a MODULE_DEPEND() on the NFS client from
 dtnfsclient so that dtnfsclient can access NFS client symbols.

Discussed with:	kib
Reported by:	markm
Approved by:	re (kib)
---
 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 7a8a5598222de9bf7dee998d45e2badb9fee017d Mon Sep 17 00:00:00 2001
From: Rick Macklem 
Date: Thu, 15 Oct 2009 19:50:00 +0000
Subject: [PATCH 0341/2592] MFC r197298: Change the default transport protocol
 for use by the Mount protocol and the NFS Null RPC done by mount_nfs from UDP
 to TCP, so that it is consistent with the kernel, which already uses NFS over
 TCP by default. Without this change, doing an NFS mount against a server that
 only supports UDP results in an unusable mount point if a transport protocol
 option wasn't specified for the mount.

Approved by:	re (kib)
---
 sbin/mount_nfs/mount_nfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c
index 9451fd763ce..7d4f3f65e1c 100644
--- a/sbin/mount_nfs/mount_nfs.c
+++ b/sbin/mount_nfs/mount_nfs.c
@@ -104,7 +104,7 @@ struct nfhret {
 #define	OF_NOINET6	8
 int retrycnt = -1;
 int opflags = 0;
-int nfsproto = IPPROTO_UDP;
+int nfsproto = IPPROTO_TCP;
 int mnttcp_ok = 1;
 int noconn = 0;
 char *portspec = NULL;	/* Server nfs port; NULL means look up via rpcbind. */

From 888d94cf9b58e44d8bb8f921a7ff79818eef28c1 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Fri, 16 Oct 2009 00:17:09 +0000
Subject: [PATCH 0342/2592] MFC r197947:

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. [Does not apply in RELENG_8]
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

Approved by:	re (kib)
---
 etc/rc.d/bgfsck         |  2 +-
 etc/rc.d/cleartmp       |  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.subr             | 22 +++++++++++++++-------
 15 files changed, 42 insertions(+), 30 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/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 7d79745c91d..582dd45972b 100755
--- a/etc/rc.d/netif
+++ b/etc/rc.d/netif
@@ -141,7 +141,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.subr b/etc/rc.subr
index 86e8c7d8f12..31559fc7a54 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -371,6 +371,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:
@@ -680,13 +694,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 a7261a62d53153a6e3889aa52a20f919a3cb8912 Mon Sep 17 00:00:00 2001
From: Alexander Nedotsukov 
Date: Fri, 16 Oct 2009 09:29:06 +0000
Subject: [PATCH 0343/2592] MFC r197995, 198020:

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).

Approved by:	re (kib)
---
 Makefile.inc1                           | 2 +-
 kerberos5/lib/libgssapi_krb5/Makefile   | 4 ++--
 kerberos5/lib/libgssapi_spnego/Makefile | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Makefile.inc1 b/Makefile.inc1
index eaf5b5728c4..3cc82fa4eae 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
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 596646aee55de5f7baafef3dcdf1f6e1450bb728 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Sat, 17 Oct 2009 13:42:23 +0000
Subject: [PATCH 0344/2592] MFC 197975, 197977, 197980, 198027: 	Update for
 latest 802.11s changes in meshconf format.

Approved by:	re (kib)
---
 sbin/ifconfig/ifieee80211.c   | 36 +++++++++-------
 sys/net80211/ieee80211_hwmp.c |  2 +-
 sys/net80211/ieee80211_mesh.c | 77 +++++++++++++----------------------
 sys/net80211/ieee80211_mesh.h | 52 ++++++++---------------
 4 files changed, 68 insertions(+), 99 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);
 	}
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..a1b594b9286 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)
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 4b94fa783561ea60b0d96563d9b8a964e27d73b9 Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Sun, 18 Oct 2009 15:58:57 +0000
Subject: [PATCH 0345/2592] Merge r198118 from head to stable/8:

  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.

Approved by:	re (bz)
---
 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 a4696825189afd3c35a34d14118766b9ad9cc8c2 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Mon, 19 Oct 2009 08:43:11 +0000
Subject: [PATCH 0346/2592] MFC: r198125

Use our standard section 4 SYNOPSIS.

Approved by:	re (hrs)
---
 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 a9266569b7acd9a8032d3db98c4ae1d0c039fb16 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Mon, 19 Oct 2009 18:31:39 +0000
Subject: [PATCH 0347/2592] MFC 198079: 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.

Approved by:	re (kib)
---
 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 74fb2c91c6f4eca47abdec839f1c87192e268c15 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Mon, 19 Oct 2009 19:40:05 +0000
Subject: [PATCH 0348/2592] MFC 198126: Fix a sign bug in the handling of nice
 priorities when computing the interactive score for a thread.

Approved by:	re (kib)
---
 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 b40a5047279d14e1eb848b62908c7110cba1d723 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Tue, 20 Oct 2009 11:52:39 +0000
Subject: [PATCH 0349/2592] MFC r198189: Check error of dlfunc(3).

Approved by:	re (kib)
---
 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 b6124fac40e3946f52439be7261305c7e874afe2 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 20 Oct 2009 13:26:58 +0000
Subject: [PATCH 0350/2592] MFC r197931: Apply relocations for PIE binary ELF
 data structures pointers in rtld.

Approved by:	re (kensmith)
---
 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 5b15472fe94b1a5393fd51a2bd7710638c248504 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 20 Oct 2009 13:30:06 +0000
Subject: [PATCH 0351/2592] MFC r197932: Do not map elf segments of zero
 length.

Approved by:	re (kensmith)
---
 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..404efe18ada 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -632,7 +632,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;
@@ -761,6 +762,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 9930b1a6ac7cdf2a1af184805bcc62baf4d64cf7 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Tue, 20 Oct 2009 13:32:18 +0000
Subject: [PATCH 0352/2592] MFC r197313: Build a separate livefs CD for
 sparc64.

Approved by:	re (kib)
---
 release/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/release/Makefile b/release/Makefile
index f4cfb967b13..ce70afd0dd8 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -242,6 +242,7 @@ MFSSIZE=		4096
 MFSINODE=		8192
 MFSLABEL=		auto
 MINIROOT=
+SEPARATE_LIVEFS=
 .elif ${TARGET_ARCH} == "ia64"
 DISKLABEL=		""
 MAKE_DVD=

From 55f128de917f24243206ae4cda46bb9dc72b917e Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 20 Oct 2009 13:32:28 +0000
Subject: [PATCH 0353/2592] MFC r197933: Define architectural load bases for
 PIE binaries.

MFC r198203 (by marius):
Change load base for sparc to match default gcc memory layout model.

Approved by:	re (kensmith)
---
 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..2a666705d0f 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 0x100000
+
 #endif /* !_MACHINE_ELF_H_ */
diff --git a/sys/sun4v/include/elf.h b/sys/sun4v/include/elf.h
index c0fcbee5ecd..2a666705d0f 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 0x100000
+
 #endif /* !_MACHINE_ELF_H_ */

From dc68cec603b5a4256c4f104848d2947fbe69d9ed Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 20 Oct 2009 13:34:41 +0000
Subject: [PATCH 0354/2592] MFC r197934: Map PIE binaries at non-zero base
 address.

MFC r198202:
Honour non-zero mapbase for PIE binaries. Inform interpreter-less PIE
binary about its relocbase.

Approved by:	re (kensmith)
---
 sys/kern/imgact_elf.c | 45 ++++++++++++++++++++++++++++++-------------
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 404efe18ada..8d5820b4b16 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -685,9 +685,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, 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;
@@ -716,14 +716,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;
 		}
 	}
 
@@ -733,9 +741,19 @@ __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);
+		/*
+		 * 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;
 	if (interp != NULL && brand_info->interp_newpath != NULL)
 		newinterp = brand_info->interp_newpath;
@@ -783,7 +801,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);
@@ -797,11 +815,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
@@ -823,7 +842,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;
@@ -831,7 +850,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;
@@ -903,7 +922,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 92b52ada7cd26eb88ef9a8c3fe825e1ff6e18d48 Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Tue, 20 Oct 2009 16:22:31 +0000
Subject: [PATCH 0355/2592] Merge r198196 from head to stable/8:

  Rewrap ip_input() comment so that it prints more nicely.

Approved by:	re (kib)
---
 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 7886fa73716..3f4c685d1cb 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 ea95296ce8ac9d8490aa2b09b1a6e4ce208ebeb0 Mon Sep 17 00:00:00 2001
From: Stanislav Sedov 
Date: Tue, 20 Oct 2009 16:41:23 +0000
Subject: [PATCH 0356/2592] - Disable ASF by default in STABLE_8.  This causes
 a lot   of problems on non-DELL branded machines with IPMI   support.  The
 proposed fix was committed to HEAD but has   not received much test coverage
 yet.

Discussed with:	bz
Approved by:	re (kensmith)
---
 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 db65ec2caad..6bf4bb36618 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -446,7 +446,7 @@ static devclass_t bge_devclass;
 DRIVER_MODULE(bge, pci, bge_driver, bge_devclass, 0, 0);
 DRIVER_MODULE(miibus, bge, miibus_driver, miibus_devclass, 0, 0);
 
-static int bge_allow_asf = 1;
+static int bge_allow_asf = 0;
 
 TUNABLE_INT("hw.bge.allow_asf", &bge_allow_asf);
 

From 6f99a646e4ec4d6d84eaad984f308aec561f20b8 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 20 Oct 2009 17:44:50 +0000
Subject: [PATCH 0357/2592] MFC	r198111

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.
4. The return error code was incorrect.

Reviewed by:	kmacy
Approved by:	re
---
 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 5aa2c59c88c..922b5b8d51b 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -87,10 +87,13 @@ 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);
 
 #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)
 
@@ -299,7 +302,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,
@@ -307,7 +310,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));
 
@@ -327,7 +330,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);
@@ -358,12 +361,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,
@@ -668,7 +671,7 @@ match:
 		la->la_flags |= LLE_VALID;
 
 		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 ae8e2f40d3d..1b0a6746e34 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1439,7 +1439,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)
@@ -1471,10 +1471,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 6fb7173c2bfa70974081847a16e9c940fc3b7e1f Mon Sep 17 00:00:00 2001
From: Weongyo Jeong 
Date: Tue, 20 Oct 2009 17:50:36 +0000
Subject: [PATCH 0358/2592] MFC r198098:   fixes a TX hang bug that it could
 happen when if_start callback didn't   be restarted by full of the output
 queue.

  Tested by:      bsduser 

MFC r198099:
  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.

Approved by:	re (kib)
---
 sys/dev/usb/wlan/if_rum.c  | 10 ++++++++--
 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 ++++++
 6 files changed, 31 insertions(+), 4 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 */
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 ff3220b716f..580b3113190 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -2293,6 +2293,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 0cd8d3535a3..425471b6577 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -4071,6 +4071,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 752b1b697126c9f54845cd6c361ecc914ff7dcfa Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Tue, 20 Oct 2009 18:54:51 +0000
Subject: [PATCH 0359/2592] Merge r198218 from head to stable/8:

  Sort function prototypes in pfil.h, clean up white space, and better
  align fields for printing.

Approved by:	re (kensmith)
---
 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 8ed4544ca7c66155063f4b903356e971620293e1 Mon Sep 17 00:00:00 2001
From: Alexander Kabaev 
Date: Tue, 20 Oct 2009 19:05:43 +0000
Subject: [PATCH 0360/2592] MFC Revision 197277:

Make libc.a provide __stack_chk_fail_local weak alias. This is
needed to satisfy static libraries that are compiled with -fpic
and linked into static binary afterwards. Several libraries in
gcc are examples of such static libs.

Approved by: re (kib)
---
 lib/libc/sys/stack_protector.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/libc/sys/stack_protector.c b/lib/libc/sys/stack_protector.c
index 63beebc1c94..14c20eb4f0b 100644
--- a/lib/libc/sys/stack_protector.c
+++ b/lib/libc/sys/stack_protector.c
@@ -108,4 +108,8 @@ __chk_fail(void)
 	__fail("buffer overflow detected; terminated");
 }
 
+#ifdef PIC
 __sym_compat(__stack_chk_fail_local, __stack_chk_fail, FBSD_1.0);
+#else
+__weak_reference(__stack_chk_fail, __stack_chk_fail_local);
+#endif

From 0eb4d28bac3ff3bb7cb25077042ad51f7769d888 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 20 Oct 2009 21:36:56 +0000
Subject: [PATCH 0361/2592] MFC	198301

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
Approved by:	re
Verified by:	rnoland, yongari
---
 sys/netinet/if_ether.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 922b5b8d51b..be1e529bbaf 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -168,17 +168,17 @@ arptimer(void *arg)
 	ifp = lle->lle_tbl->llt_ifp;
 	IF_AFDATA_LOCK(ifp);
 	LLE_WLOCK(lle);
-	if (((lle->la_flags & LLE_DELETED)
-		|| (time_second >= lle->la_expire))
-	    && (!callout_pending(&lle->la_timer) &&
-		callout_active(&lle->la_timer)))
+	if ((!callout_pending(&lle->la_timer) &&
+	    callout_active(&lle->la_timer))) {
 		(void) llentry_free(lle);
-	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);
 }
 
@@ -365,7 +365,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 e0b75e6195bb88911e9134f8c1f0ef4cd95667b1 Mon Sep 17 00:00:00 2001
From: Stanislav Sedov 
Date: Tue, 20 Oct 2009 22:11:17 +0000
Subject: [PATCH 0362/2592] - Note that ASF is now disabled by default in 8.0.

Approved by:	re (kib)
---
 share/man/man4/bge.4 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/share/man/man4/bge.4 b/share/man/man4/bge.4
index d4cc265237b..1d00183c8ac 100644
--- a/share/man/man4/bge.4
+++ b/share/man/man4/bge.4
@@ -31,7 +31,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 19, 2009
+.Dd Oct 21, 2009
 .Dt BGE 4
 .Os
 .Sh NAME
@@ -217,7 +217,7 @@ prompt before booting the kernel, or stored in
 .It Va hw.bge.allow_asf
 Allow the ASF feature for cooperating with IPMI.
 Can cause system lockup problems on a small number of systems.
-Enabled by default.
+Disabled by default.
 .El
 .Sh DIAGNOSTICS
 .Bl -diag

From 304762b138de244056b5c5501ebc441634d70b89 Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Wed, 21 Oct 2009 09:53:55 +0000
Subject: [PATCH 0363/2592] Merge r198219 from head to stable/8:

  Remove unused pfil_flags field in packet_filter_hook.

Approved by:	re (kib)
---
 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 5e2ef9933c143854046088b377f5e4009887e20f Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Wed, 21 Oct 2009 13:11:38 +0000
Subject: [PATCH 0364/2592] Merge r198198 from head to stable/8:

  Line-wrap pfil.c so that it prints more nicely.

Approved by:	re (kensmith)
---
 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 3018eb9a578..1e2629263ec 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(, pfil_head) pfil_head_list =
     LIST_HEAD_INITIALIZER(&pfil_head_list);
@@ -76,7 +78,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;
 		}
@@ -220,8 +223,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;
 
@@ -272,7 +275,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 cbdd92bda4d6f630c198c9df4fab61aed260a36a Mon Sep 17 00:00:00 2001
From: Robert Watson 
Date: Wed, 21 Oct 2009 14:05:51 +0000
Subject: [PATCH 0365/2592] Merge r198233 from head to stable/8:

  Clean up comments, white space, and style in pfil.c (VNET changes not
  MFC'd)

Approved by:	re (kib)
---
 sys/net/pfil.c | 34 +++++++++++++++-------------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/sys/net/pfil.c b/sys/net/pfil.c
index 1e2629263ec..0ae889a6f27 100644
--- a/sys/net/pfil.c
+++ b/sys/net/pfil.c
@@ -85,14 +85,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)
@@ -104,7 +103,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);
@@ -150,7 +149,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);
 }
 
@@ -207,7 +205,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:
@@ -215,12 +213,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,
@@ -229,7 +227,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)
@@ -241,8 +238,7 @@ pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int,
 			ph->ph_nhooks--;
 	}
 	PFIL_WUNLOCK(ph);
-	
-	return err;
+	return (err);
 }
 
 static int
@@ -256,17 +252,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);
 }
 
 /*
@@ -284,7 +280,7 @@ 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);
 }

From 46aaa1ed67f492f792292d2cef553323803fa756 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Wed, 21 Oct 2009 15:07:34 +0000
Subject: [PATCH 0366/2592] MFC r198201: 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.

Approved by:	re (kensmith)
---
 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 3604d6e3d3d578a4af47019667f926d93d9a72ba Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Wed, 21 Oct 2009 17:18:48 +0000
Subject: [PATCH 0367/2592] MFC r198287:   Update package list for 8.0-REL.

Reviewed by:	re@, portmgr@
Approved by:	re (implicit)
---
 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 b1c3c31d58bedbf18442891ff0e8b50631497920 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Wed, 21 Oct 2009 19:48:27 +0000
Subject: [PATCH 0368/2592] MFC r198307

 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.

Approved by:	re (kib)
---
 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 2e412d98ca3..3aa128453df 100644
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -2843,8 +2843,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 8c1851f5a11855415c9e7f68d73828949f6ce4fb Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Thu, 22 Oct 2009 08:34:20 +0000
Subject: [PATCH 0369/2592] MFC: r198232

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.

Approved by:	re (kib)
---
 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 1c7deea4370081ab4cba762f18952363bdab1015 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Thu, 22 Oct 2009 16:26:38 +0000
Subject: [PATCH 0370/2592] MFC r196863:

Improve wording.

MFC r196941:

Prevent the line from wrapping.

Approved by:	re (kib)
---
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 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 df2fc3e01a9..64fded4712e 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
@@ -3557,15 +3557,19 @@ arc_init(void)
 	
 #ifdef __i386__
 	if (prefetch_tunable_set == 0) {
-		printf("ZFS NOTICE: prefetch is disabled by default on i386"
-		    " - add enable to tunable to change.\n" );
+		printf("ZFS NOTICE: Prefetch is disabled by default on i386 "
+		    "-- to enable,\n");
+		printf("            add \"vfs.zfs.prefetch_disable=0\" "
+		    "to /boot/loader.conf.\n");
 		zfs_prefetch_disable=1;
 	}
 #else	
 	if ((((uint64_t)physmem * PAGESIZE) < (1ULL << 32)) &&
 	    prefetch_tunable_set == 0) {
-		printf("ZFS NOTICE: system has less than 4GB and prefetch enable is not set"
-		    "... disabling.\n");
+		printf("ZFS NOTICE: Prefetch is disabled by default if less "
+		    "than 4GB of RAM is present;\n"
+		    "            to enable, add \"vfs.zfs.prefetch_disable=0\" "
+		    "to /boot/loader.conf.\n");
 		zfs_prefetch_disable=1;
 	}
 #endif	

From dbd4bfe3179659737a9ba77ed9eae5331d810229 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Thu, 22 Oct 2009 18:48:25 +0000
Subject: [PATCH 0371/2592] MFC	198306

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
Approved by:	re
---
 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 de411f4cd2b28c94938e2548d6a28ec8785856f1 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Fri, 23 Oct 2009 12:02:01 +0000
Subject: [PATCH 0372/2592] MFC r198376

 Prevent wraparound of the timeout variable.

Submitted by:	HPS
Approved by:	re (kib)
---
 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 1ca0e46fdfb82b931d25332101e5d56289794911 Mon Sep 17 00:00:00 2001
From: Philip Paeps 
Date: Fri, 23 Oct 2009 14:43:17 +0000
Subject: [PATCH 0373/2592] MFC r198352

  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.

Obtained from:	OpenBSD
Reviewed by:	brooks
Approved by:	re (kib)
---
 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 115753ce9eb755279fea668547d1692b4ec06ddf Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 23 Oct 2009 19:52:29 +0000
Subject: [PATCH 0374/2592] MFC 198174: 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.

Approved by:	re (kib)
---
 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 f47552e770ac51134e605d93efd6c534b2809388 Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Sat, 24 Oct 2009 04:55:14 +0000
Subject: [PATCH 0375/2592] MFC r198295:

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 
Approved by:	re (kib)
---
 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 ce0ea9e6d06..668ca1a1c57 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -557,6 +557,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 1e5dd507808c1c5dbfae862cb5b2776659d93598 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Sun, 25 Oct 2009 00:28:01 +0000
Subject: [PATCH 0376/2592] Prepare for 8.0-RC2 builds.

Approved by:	re (implicit)
---
 sys/conf/newvers.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index beb37c6febd..7987ddd4218 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="8.0"
-BRANCH="RC1"
+BRANCH="RC2"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

From 9dfe718b59cd2617c21c14d07f84d5b9a6067c3b Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 28 Oct 2009 16:54:48 +0000
Subject: [PATCH 0377/2592] MFC: r198313

Improve the description of the malofw kernel module installation.
---
 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 ace7829a26ae570e8c972bacd75719e729e8be4d Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 28 Oct 2009 17:46:05 +0000
Subject: [PATCH 0378/2592] MFC: r198363

List more dependencies for these drivers. While here, convert
atapicam(4) to use our standard section 4 SYNOPSIS layout.
---
 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 e76e58bc73763ad97061c1c4664e615d03c58b4a Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Wed, 28 Oct 2009 21:07:42 +0000
Subject: [PATCH 0379/2592] MFC of r197597, r198270, r198515:

MFC of tzdata2009n:
- Pakistan will go out DST on 1 October.
- Headsup for changes in Argentina.

MFC 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

MFC of tzdata2009p:
- Argentina does not go to DST this year.

Approved by:	re (Ken Smith)
---
 share/zoneinfo/asia         | 92 ++++++++++++++++++++++++++++++++-----
 share/zoneinfo/australasia  | 32 ++++++++++++-
 share/zoneinfo/southamerica | 68 +++++++++++++++++++++------
 3 files changed, 166 insertions(+), 26 deletions(-)

diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia
index 7142b4552f3..7f063cb4bff 100644
--- a/share/zoneinfo/asia
+++ b/share/zoneinfo/asia
@@ -1,5 +1,5 @@
 # 
-# @(#)asia	8.40
+# @(#)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]
@@ -1674,16 +1692,66 @@ Zone	Asia/Muscat	3:54:20 -	LMT	1920
 # advance clocks in the country by one hour from April 15 to
 # conserve energy"
 
-# From Arthur David Olson (2009-04-10):
-# Assume for now that Pakistan will end DST in 2009 as it did in 2008.
+# From Steffen Thorsen (2009-09-17):
+# "The News International," Pakistan reports that: "The Federal
+# Government has decided to restore the previous time by moving the
+# clocks backward by one hour from October 1. A formal announcement to
+# this effect will be made after the Prime Minister grants approval in
+# this regard." 
+# 
+# http://www.thenews.com.pk/updates.asp?id=87168
+# 
+
+# 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	-	Nov	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/share/zoneinfo/australasia b/share/zoneinfo/australasia
index 86fac13d98e..a5a4331dc84 100644
--- a/share/zoneinfo/australasia
+++ b/share/zoneinfo/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
diff --git a/share/zoneinfo/southamerica b/share/zoneinfo/southamerica
index 341e57ff907..9c4edcb7ceb 100644
--- a/share/zoneinfo/southamerica
+++ b/share/zoneinfo/southamerica
@@ -1,5 +1,5 @@
 # 
-# @(#)southamerica	8.36
+# @(#)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,15 +403,40 @@ 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 Mariano Absatz (2009-10-16):
+# ...the Province of San Luis is a case in itself.
 #
+# The Law at
+# 
+# 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.
+#
+# This clearly breaks every time the 1st of March or October is a Sunday.
+#
+# 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]
 #
 # Buenos Aires (BA), Capital Federal (CF),
@@ -530,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
@@ -544,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 dce196cf9c1f16b12dc7abff9575b3be2d40d495 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 28 Oct 2009 21:08:20 +0000
Subject: [PATCH 0380/2592] MFC: Remove spurious README and an old version of
 the manpage.

---
 usr.sbin/mfiutil/README    | 104 -------
 usr.sbin/mfiutil/mfiutil.1 | 574 -------------------------------------
 2 files changed, 678 deletions(-)
 delete mode 100644 usr.sbin/mfiutil/README
 delete mode 100644 usr.sbin/mfiutil/mfiutil.1

diff --git a/usr.sbin/mfiutil/README b/usr.sbin/mfiutil/README
deleted file mode 100644
index 15e16bb0cdd..00000000000
--- a/usr.sbin/mfiutil/README
+++ /dev/null
@@ -1,104 +0,0 @@
-# $FreeBSD$
-
-This package includes a mfiutil command for administering mfi(4) controllers
-on FreeBSD.
-
-Version 1.0.13
-	* Cleaned up warnings in preparation for integration with FreeBSD
-
-Version 1.0.12
-	* Add 'drive clear' command to wipe drives with all 0x00 characters
-
-Version 1.0.11
-	* Display serial number for drives
-	* Display location info for drives with 'show config'
-
-Version 1.0.10
-	* Display min and max stripe size supported by adapters.
-	* Added support for examining the controller event log.
-
-Version 1.0.9
-	* Display stripe size for volumes.
-	* Added support for setting the stripe size for new volumes.
-	* Fix a regression in 1.0.8 that broke creation of RAID-5 and RAID-50
-	  arrays.
-
-Version 1.0.8
-	* Added support for RAID-60 arrays.
-	* Added 'flash' command to support firmware flashing.
-
-Version 1.0.7
-	* Renamed 'clear config' to 'clear, 'create volume' to 'create',
-	  'delete volume' to 'delete', 'create spare' to 'add', and
-	  'delete spare' to 'remove'.  The old names still work.
-	* Added support for RAID-6 arrays.
-
-Version 1.0.6
-	* Added 'show patrol', 'patrol', 'start patrol', and 'stop patrol'
-	  commands to manage patrol reads.
-
-Version 1.0.5
-	* Added 'create volume' and 'delete volume' commands to manage volumes.
-	* Added 'clear config' command to clear entire configuration.
-	* Added more detailed error reporting based on firmware status codes.
-	* Renamed 'progress' command to 'drive progress'.
-	* Added 'volume progress' command to display progress of volume-level
-	  activites such as background inits.
-	* Fixed 'create spare' to properly add global spares.
-
-Version 1.0.4
-	* Added 'create spare' and 'delete spare' commands to manage hot spares.
-	* Added 'good' command to mark unconfigured bad drives as good.
-	* Display more information about hot spares in 'show config'
-	* Allow physical drives to be specified via Exx:Syy similar to megacli
-	* Display onboard memory size in 'show adapter'
-
-Version 1.0.3
-	* Added 'cache' command to manage cache settings for volumes.
-	* Added 'name' command to name volumes.
-	* Added manpage.
-
-Version 1.0.2
-	* Added 'show adapter' and 'show battery' commands.
-	* Added RAID level of volumes to 'show config' and 'show volumes'.
-	* Added drive model info to 'show config' and 'show drives'.
-	* Added package firmware version to 'show firmware'.
-	* Added read and write cache status to 'show volumes'.
-	* Map volume IDs to mfidX device names on newer kernels.
-
-Version 1.0.1
-	* Added 'show firmware' command
-
-Version 1.0.0
-	* Initial release
-
-usage: mfiutil [-u unit]  ...
-
-Commands include:
-    version
-    show adapter              - display controller information
-    show battery              - display battery information
-    show config               - display RAID configuration
-    show drives               - list physical drives
-    show firmware             - list firmware images
-    show volumes              - list logical volumes
-    show patrol               - display patrol read status
-    fail               - fail a physical drive
-    good               - mark a bad physical drive as good
-    rebuild            - mark failed drive ready for rebuild
-    drive progress     - display status of active operations
-    start rebuild 
-    abort rebuild 
-    locate     - toggle drive LED
-    cache  [command [setting]]
-    name  
-    volume progress   - display status of active operations
-    clear                     - clear volume configuration
-    create  [-v] [,[,...]] [[,[,...]]
-    delete 
-    add  [volume]      - add a hot spare
-    remove             - remove a hot spare
-    patrol  [interval [start]]
-    start patrol              - start a patrol read
-    stop patrol               - stop a patrol read
-    flash 
diff --git a/usr.sbin/mfiutil/mfiutil.1 b/usr.sbin/mfiutil/mfiutil.1
deleted file mode 100644
index d7860ab06dd..00000000000
--- a/usr.sbin/mfiutil/mfiutil.1
+++ /dev/null
@@ -1,574 +0,0 @@
-.\" Copyright (c) 2008, 2009 Yahoo!, 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. 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. The names of the authors may not be used to endorse or promote
-.\"    products derived from this software without specific prior written
-.\"    permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd June 17, 2008
-.Dt MFIUTIL 1
-.Os
-.Sh NAME
-.Nm mfiutil
-.Nd Utility for managing LSI MegaRAID SAS controllers
-.Sh SYNOPSIS
-.Nm
-.Cm version
-.Nm
-.Op Fl u Ar unit
-.Cm show adapter
-.Nm
-.Op Fl u Ar unit
-.Cm show battery
-.Nm
-.Op Fl u Ar unit
-.Cm show config
-.Nm
-.Op Fl u Ar unit
-.Cm show drives
-.Nm
-.Op Fl u Ar unit
-.Cm show events
-.Op Fl c Ar class
-.Op Fl l Ar locale
-.Op Fl n Ar count
-.Op Fl v
-.Op Ar start Op Ar stop
-.Nm
-.Op Fl u Ar unit
-.Cm show firmware
-.Nm
-.Op Fl u Ar unit
-.Cm show logstate
-.Nm
-.Op Fl u Ar unit
-.Cm show patrol
-.Nm
-.Op Fl u Ar unit
-.Cm show volumes
-.Nm
-.Op Fl u Ar unit
-.Cm fail Ar drive
-.Nm
-.Op Fl u Ar unit
-.Cm good Ar drive
-.Nm
-.Op Fl u Ar unit
-.Cm rebuild Ar drive
-.Nm
-.Op Fl u Ar unit
-.Cm drive progress Ar drive
-.Nm
-.Op Fl u Ar unit
-.Cm drive clear Ar drive Brq "start | stop"
-.Nm
-.Op Fl u Ar unit
-.Cm start rebuild Ar drive
-.Nm
-.Op Fl u Ar unit
-.Cm abort rebuild Ar drive
-.Nm
-.Op Fl u Ar unit
-.Cm locate Ar drive Brq "on | off"
-.Nm
-.Op Fl u Ar unit
-.Cm cache Ar volume Op Ar setting Op Ar value
-.Nm
-.Op Fl u Ar unit
-.Cm name Ar volume Ar name
-.Nm
-.Op Fl u Ar unit
-.Cm volume progress Ar volume
-.Nm
-.Op Fl u Ar unit
-.Cm clear
-.Nm
-.Op Fl u Ar unit
-.Cm create Ar type
-.Op Fl v
-.Op Fl s Ar stripe_size
-.Ar drive Ns Op \&, Ns Ar drive Ns Op ",..."
-.Op Ar drive Ns Op \&, Ns Ar drive Ns Op ",..."
-.Nm
-.Op Fl u Ar unit
-.Cm delete Ar volume
-.Nm
-.Op Fl u Ar unit
-.Cm add Ar drive Op Ar volume
-.Nm
-.Op Fl u Ar unit
-.Cm remove Ar drive
-.Nm
-.Op Fl u Ar unit
-.Cm start patrol
-.Nm
-.Op Fl u Ar unit
-.Cm stop patrol
-.Nm
-.Op Fl u Ar unit
-.Cm patrol Ar command Op Ar interval Op Ar start
-.Nm
-.Op Fl u Ar unit
-.Cm flash Ar file
-.Sh DESCRIPTION
-The
-.Nm
-utility can be used to display or modify various parameters on LSI
-MegaRAID SAS RAID controllers.
-Each invocation of
-.Nm
-consists of zero or more global options followed by a command.
-Commands may support additional optional or required arguments after the
-command.
-.Pp
-Currently one global option is supported:
-.Bl -tag -width indent
-.It Fl u Ar unit
-.Ar unit
-specifies the unit of the controller to work with.
-If no unit is specified,
-then unit 0 is used.
-.El
-.Pp
-Volumes may be specified in two forms.
-First,
-a volume may be identified by its target ID.
-Second,
-on the volume may be specified by the corresponding
-.Em mfidX
-device,
-such as
-.Em mfid0 .
-Note that this second method only works on OS versions
-.Dv 6.2-YAHOO-20070510
-and later.
-.Pp
-Drives may be specified in two forms.
-First,
-a drive may be identified by its device ID.
-The device ID for configured drives can be found in
-.Cm show config .
-Second,
-a drive may be identified by its location as
-.Sm off
-.Op E Ar xx Ns \&:
-.Li S Ns Ar yy
-.Sm on
-where
-.Ar xx
-is the enclosure
-and
-.Ar yy
-is the slot for each drive as displayed in
-.Cm show drives .
-.Pp
-The
-.Nm
-utility supports several different groups of commands.
-The first group of commands provide information about the controller,
-the volumes it manages, and the drives it controls.
-The second group of commands are used to manage the physical drives
-attached to the controller.
-The third group of commands are used to manage the logical volumes
-managed by the controller.
-The fourth group of commands are used to manage the drive configuration for
-the controller.
-The fifth group of commands are used to manage controller-wide operations.
-.Pp
-The informational commands include:
-.Bl -tag -width indent
-.It Cm version
-Displays the version of
-.Nm .
-.It Cm show adapter
-Displays information about the RAID controller such as the model number.
-.It Cm show battery
-Displays information about the battery from the battery backup unit.
-.It Cm show config
-Displays the volume and drive configuration for the controller.
-Each array is listed along with the physical drives the array is built from.
-Each volume is listed along with the arrays that the volume spans.
-If any hot spare drives are configured, then they are listed as well.
-.It Cm show drives
-Lists all of the physical drives attached to the controller.
-.It Xo Cm show events
-.Op Fl c Ar class
-.Op Fl l Ar locale
-.Op Fl n Ar count
-.Op Fl v
-.Op Ar start Op Ar stop
-.Xc
-Display entries from the controller's event log.
-The controller maintains a circular buffer of events.
-Each event is tagged with a class and locale.
-.Pp
-The
-.Ar class
-parameter limits the output to entries at the specified class or higher.
-The default class is
-.Dq warn .
-The available classes from lowest priority to highest are:
-.Bl -tag -width -indent
-.It Cm debug
-Debug messages.
-.It Cm progress
-Periodic progress updates for long-running operations such as background
-initializations, array rebuilds, or patrol reads.
-.It Cm info
-Informational messages such as drive insertions and volume creations.
-.It Cm warn
-Indicates that some component may be close to failing.
-.It Cm crit
-A component has failed, but no data is lost.
-For example, a volume becoming degraded due to a drive failure.
-.It Cm fatal
-A component has failed resulting in data loss.
-.It Cm dead
-The controller itself has died.
-.El
-.Pp
-The
-.Ar locale
-parameter limits the output to entries for the specified part of the controller.
-The default locale is
-.Dq all .
-The available locales are
-.Dq volume ,
-.Dq drive ,
-.Dq enclousure ,
-.Dq battery ,
-.Dq sas ,
-.Dq controller ,
-.Dq config ,
-.Dq cluster ,
-and
-.Dq all .
-.Pp
-The
-.Ar count
-parameter is a debugging aid that specifies the number of events to fetch from
-the controller for each low-level request.
-The default is 15 events.
-.Pp
-By default, matching event log entries from the previous shutdown up to the
-present are displayed.  This range can be adjusted via the
-.Ar start
-and
-.Ar stop
-parameters.
-Each of these parameters can either be specified as a log entry number or as
-one of the following aliases:
-.Bl -tag -width -indent
-.It Cm newest
-The newest entry in the event log.
-.It Cm oldest
-The oldest entry in the event log.
-.It Cm clear
-The first entry since the event log was cleared.
-.It Cm shutdown
-The entry in the event log corresponding to the last time the controller was
-cleanly shut down.
-.It Cm boot
-The entry in the event log corresponding to the most recent boot.
-.El
-.It Cm show firmware
-Lists all of the firmware images present on the controller.
-.It Cm show logstate
-Display the various sequence numbers associated with the event log.
-.It Cm show patrol
-Display the status of the controller's patrol read operation.
-.It Cm show volumes
-Lists all of the logical volumes managed by the controller.
-.El
-.Pp
-The physical drive management commands include:
-.Bl -tag -width indent
-.It Cm fail Ar drive
-Mark
-.Ar drive
-as failed.
-.Ar Drive
-must be an online drive that is part of an array.
-.It Cm good Ar drive
-Mark
-.Ar drive
-as an unconfigured good drive.
-.Ar Drive
-must not be part of an existing array.
-.It Cm rebuild Ar drive
-Mark a failed
-.Ar drive
-that is still part of an array as a good drive suitable for a rebuild.
-The firmware should kick off an array rebuild on its own if a failed drive
-is marked as a rebuild drive.
-.It Cm drive progress Ar drive
-Report the current progress and estimated completion time of drive operations
-such as rebuilds or patrol reads.
-.It Cm drive clear Ar drive Brq "start | stop"
-Start or stop the writing of all 0x00 characters to a drive.
-.It Cm start rebuild Ar drive
-Manually start a rebuild on
-.Ar drive .
-.It Cm abort rebuild Ar drive
-Abort an in-progress rebuild operation on
-.Ar drive .
-It can be resumed with the
-.Cm start rebuild
-command.
-.It Cm locate Ar drive Brq "on | off"
-Change the state of the external LED associated with
-.Ar drive .
-.El
-.Pp
-The logical volume management commands include:
-.Bl -tag -width indent
-.It Cm cache Ar volume Op Ar setting Op Ar value
-If no
-.Ar setting
-argument is supplied, then the current cache policy for
-.Ar volume
-is displayed;
-otherwise,
-the cache policy for
-.Ar volume
-is modified.
-The optional
-.Ar setting
-argument can be one of the following values:
-.Bl -tag -width indent
-.It Cm enable
-Enable caching for both read and write I/O operations.
-.It Cm disable
-Disable caching for both read and write I/O operations.
-.It Cm reads
-Enable caching only for read I/O operations.
-.It Cm writes
-Enable caching only for write I/O operations.
-.It Cm write-back
-Use write-back policy for cached writes.
-.It Cm write-through
-Use write-through policy for cached writes.
-.It Cm read-ahead Op Ar value
-Set the read ahead policy for cached reads.
-The
-.Ar value
-argument can be set to either
-.Dq none ,
-.Dq adaptive ,
-or
-.Dq always .
-.It Cm write-cache Op Ar value
-Control the write caches on the physical drives backing
-.Ar volume .
-The
-.Ar value
-argument can be set to either
-.Dq disable ,
-.Dq enable ,
-or
-.Dq default .
-.Pp
-In general this setting should be left disabled to avoid data loss when the
-physical drives lose power.
-The battery backup of the RAID controller does not save data in the write
-caches of the physical drives.
-.El
-.It Cm name Ar volume Ar name
-Sets the name of
-.Ar volume
-to
-.Ar name .
-.It Cm volume progress Ar volume
-Report the current progress and estimated completion time of volume operations
-such as consistency checks and initializations.
-.El
-.Pp
-The configuration commands include:
-.Bl -tag -width indent
-.It Cm clear
-Delete the entire configuration including all volumes, arrays, and spares.
-.It Xo Cm create Ar type
-.Op Fl v
-.Op Fl s Ar stripe_size
-.Ar drive Ns Op \&, Ns Ar drive Ns Op ",..."
-.Op Ar drive Ns Op \&, Ns Ar drive Ns Op ",..."
-.Xc
-Create a new volume.
-The
-.Ar type
-specifies the type of volume to create.
-Currently supported types include:
-.Bl -tag -width indent
-.It Cm jbod
-Creates a RAID0 volume for each drive specified.
-Each drive must be specified as a separate argument.
-.It Cm raid0
-Creates one RAID0 volume spanning the drives listed in the single drive list.
-.It Cm raid1
-Creates one RAID1 volume spanning the drives listed in the single drive list.
-.It Cm raid5
-Creates one RAID5 volume spanning the drives listed in the single drive list.
-.It Cm raid6
-Creates one RAID6 volume spanning the drives listed in the single drive list.
-.It Cm raid10
-Creates one RAID10 volume spanning multiple RAID1 arrays.
-The drives for each RAID1 array are specified as a single drive list.
-.It Cm raid50
-Creates one RAID50 volume spanning multiple RAID5 arrays.
-The drives for each RAID5 array are specified as a single drive list.
-.It Cm raid60
-Creates one RAID60 volume spanning multiple RAID6 arrays.
-The drives for each RAID6 array are specified as a single drive list.
-.It Cm concat
-Creates a single volume by concatenating all of the drives in the single drive
-list.
-.El
-.Pp
-.Sy Note:
-Not all volume types are supported by all controllers.
-.Pp
-If the
-.Fl v
-flag is specified after
-.Ar type ,
-then more verbose output will be enabled.
-Currently this just provides notification as drives are added to arrays and
-arrays to volumes when building the configuration.
-.Pp
-The
-.Fl s
-.Ar stripe_size
-parameter allows the stripe size of the array to be set.
-By default a stripe size of 64K is used.
-Valid values are 512 through 1M, though the MFI firmware may reject some
-values.
-.It Cm delete Ar volume
-Delete the volume
-.Ar volume .
-.It Cm add Ar drive Op Ar volume
-Mark
-.Ar drive
-as a hot spare.
-.Ar Drive
-must be in the unconfigured good state.
-If
-.Ar volume
-is specified,
-then the hot spare will be dedicated to arrays backing that volume.
-Otherwise,
-.Ar drive
-will be used as a global hot spare backing all arrays for this controller.
-Note that
-.Ar drive
-must be as large as the smallest drive in all of the arrays it is going to
-back.
-.It Cm remove Ar drive
-Remove the hot spare
-.Ar drive
-from service.
-It will be placed in the unconfigured good state.
-.El
-.Pp
-The controller management commands include:
-.Bl -tag -width indent
-.It Cm patrol Ar command Op Ar interval Op Ar start
-Set the patrol read operation mode.
-The
-.Ar command
-argument can be one of the following values:
-.Bl -tag -width indent
-.It Cm disable
-Disable patrol reads.
-.It Cm auto
-Enable periodic patrol reads initiated by the firmware.
-The optional
-.Ar interval
-argument specifies the interval in seconds between patrol reads.
-If patrol reads should be run continously,
-then
-.Ar interval
-should consist of the word
-.Dq continuously .
-The optional
-.Ar start
-argument specifies a non-negative, relative start time for the next patrol read.
-If an interval or start time is not specified,
-then the existing setting will be used.
-.It Cm manual
-Enable manual patrol reads that are only initiated by the user.
-.El
-.It Cm start patrol
-Start a patrol read operation.
-.It Cm stop patrol
-Stop a currently running patrol read operation.
-.It Cm flash Ar file
-Updates the flash on the controller with the firmware stored in
-.Ar file .
-A reboot is required for the new firmware to take effect.
-.El
-.Sh EXAMPLES
-Configure the cache for volume mfid0 to cache only writes:
-.Pp
-.Dl Nm Cm cache mfid0 writes
-.Dl Nm Cm cache mfid0 write-back
-.Pp
-Create a RAID5 array spanning the first four disks in the second enclosure:
-.Pp
-.Dl Nm Cm create raid5 e1:s0,e1:s1,e1:s2,e1:s4
-.Pp
-Configure the first three disks on a controller as JBOD:
-.Pp
-.Dl Nm Cm create jbod 0 1 2
-.Pp
-Create a RAID10 volume that spans two arrays each of which contains two disks
-from two different enclosures:
-.Pp
-.Dl Nm Cm create raid10 e1:s0,e1:s1 e2:s0,e2:s1
-.Pp
-Add drive with the device ID of 4 as a global hot spare:
-.Pp
-.Dl Nm Cm add 4
-.Pp
-Add the drive in slot 2 in the main chassis as a hot spare for volume mfid0:
-.Pp
-.Dl Nm Cm add s2 mfid0
-.Pp
-Configure the adapter to run periodic patrol reads once a week with the first
-patrol read starting in 5 minutes:
-.Pp
-.Dl Nm Cm patrol auto 604800 300
-.Pp
-.Sh SEE ALSO
-.Xr mfi 4
-.Sh BUGS
-On 64-bit OS versions
-.Dv 6.2-YAHOO-20070514
-and earlier,
-the 
-.Xr mfi 4
-driver does not properly report firmware errors to 32-bit versions of
-.Nm .
-As a result,
-some commands may fail even though they do not report any errors.

From 54b7653bd533aa4775854bdcf45816a292228eaa Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Wed, 28 Oct 2009 21:43:16 +0000
Subject: [PATCH 0381/2592] MFC	r198353

Verify "smp_started" is true before calling
sched_bind() and sched_unbind().

Reviewed by:	kmacy
---
 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 f60909e3e262a8d06d29b88fd553b4f735b6f200 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Wed, 28 Oct 2009 21:45:25 +0000
Subject: [PATCH 0382/2592] MFC	r198418

Use the correct option name in the preprocessor command to enable
or disable diagnostic messages.

Reviewed by:	ru
---
 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 be1e529bbaf..15d529db88d 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -172,7 +172,7 @@ arptimer(void *arg)
 	    callout_active(&lle->la_timer))) {
 		(void) llentry_free(lle);
 	}
-#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 1b0a6746e34..e289c931383 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
@@ -1400,7 +1400,7 @@ in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3add
 			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
 		}
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index aef2908abd2..bf511247a28 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -2430,7 +2430,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 9149cb69ab2a21e38e9292f6f65647b0182cf760 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 29 Oct 2009 09:45:48 +0000
Subject: [PATCH 0383/2592] Fix SATA on nVidia MCP55 chipset. It needs some
 short time to allow BAR(5) memory access.

PR:		amd64/128686, amd64/132372, amd64/139156
---
 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 6b7a5f803b8465f4a02ca7538a725c1d1c3c4205 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 29 Oct 2009 09:58:16 +0000
Subject: [PATCH 0384/2592] MFC rev. 198480, 198483: Document new modularised
 ATA kernel modules and options.

PR:             kern/133162, amd64/139859
---
 UPDATING       |  9 +++++++++
 sys/conf/NOTES | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/UPDATING b/UPDATING
index 2642fb6eaf1..d556c75095e 100644
--- a/UPDATING
+++ b/UPDATING
@@ -566,6 +566,15 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
 	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
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index b448f943a12..dde4cd1e8a8 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 e180821780540cd07c335241c09f6f58d0607a62 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 29 Oct 2009 10:05:08 +0000
Subject: [PATCH 0385/2592] MFC rev. 198481, 198482: Add two more VIA SATA chip
 IDs.

PR:		kern/135057
---
 sys/dev/ata/ata-pci.h          | 2 ++
 sys/dev/ata/chipsets/ata-via.c | 4 ++++
 2 files changed, 6 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..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[] =
@@ -103,6 +105,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 963069c15ee34259bcb033bbc4f4bc3c5623bc58 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 29 Oct 2009 10:35:50 +0000
Subject: [PATCH 0386/2592] MFC rev. 198488: 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 cf90c49f7c3..b8711161326 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 f39d3da87ef781753d6a4c518feab8d5656db083 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 29 Oct 2009 10:38:17 +0000
Subject: [PATCH 0387/2592] MFC rev. 198487: 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 b8711161326..84b44c56399 100644
--- a/sys/dev/ata/atapi-cam.c
+++ b/sys/dev/ata/atapi-cam.c
@@ -635,7 +635,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;
 
@@ -738,7 +738,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 9f6aba26bfc6d8f159543008ad5a755294a37b87 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 14:40:21 +0000
Subject: [PATCH 0388/2592] MFC 196555: - Use the headers from ACPI-CA to
 define various constants and structures   for table layouts, etc. rather than
 homerolling our own structures and   constants in acpidump.h. - Verify the
 extended checksum on the RSDP. - Handle new ACPI 3.0 fields in MADT including
 X2APIC entries and   UIDs for local SAPICs. - Add handling for new ACPI 3.0
 flags in the FADT.

---
 usr.sbin/acpi/acpidump/acpi.c      | 826 ++++++++++++++++-------------
 usr.sbin/acpi/acpidump/acpi_user.c |  48 +-
 usr.sbin/acpi/acpidump/acpidump.c  |   6 +-
 usr.sbin/acpi/acpidump/acpidump.h  | 375 ++-----------
 4 files changed, 519 insertions(+), 736 deletions(-)

diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c
index 800655c472c..8a89f108ee4 100644
--- a/usr.sbin/acpi/acpidump/acpi.c
+++ b/usr.sbin/acpi/acpidump/acpi.c
@@ -47,31 +47,36 @@
 #define END_COMMENT	" */\n"
 
 static void	acpi_print_string(char *s, size_t length);
-static void	acpi_print_gas(struct ACPIgas *gas);
-static int	acpi_get_fadt_revision(struct FADTbody *fadt);
-static void	acpi_handle_fadt(struct ACPIsdt *fadt);
+static void	acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
+static int	acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt);
+static void	acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
 static void	acpi_print_cpu(u_char cpu_id);
-static void	acpi_print_local_apic(u_char cpu_id, u_char apic_id,
-				      u_int32_t flags);
-static void	acpi_print_io_apic(u_char apic_id, u_int32_t int_base,
-				   u_int64_t apic_addr);
-static void	acpi_print_mps_flags(u_int16_t flags);
-static void	acpi_print_intr(u_int32_t intr, u_int16_t mps_flags);
-static void	acpi_print_apic(struct MADT_APIC *mp);
-static void	acpi_handle_apic(struct ACPIsdt *sdp);
-static void	acpi_handle_hpet(struct ACPIsdt *sdp);
+static void	acpi_print_cpu_uid(uint32_t uid, char *uid_string);
+static void	acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
+static void	acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
+		    uint64_t apic_addr);
+static void	acpi_print_mps_flags(uint16_t flags);
+static void	acpi_print_intr(uint32_t intr, uint16_t mps_flags);
+static void	acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
+static void	acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
+static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
+static void	acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
+static void	acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
+static void	acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
 static void	acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
 		    uint32_t flags);
-static void	acpi_print_srat_memory(struct SRAT_memory *mp);
-static void	acpi_print_srat(struct SRATentry *srat);
-static void	acpi_handle_srat(struct ACPIsdt *sdp);
-static void	acpi_print_sdt(struct ACPIsdt *sdp);
-static void	acpi_print_fadt(struct ACPIsdt *sdp);
-static void	acpi_print_facs(struct FACSbody *facs);
-static void	acpi_print_dsdt(struct ACPIsdt *dsdp);
-static struct ACPIsdt *acpi_map_sdt(vm_offset_t pa);
-static void	acpi_print_rsd_ptr(struct ACPIrsdp *rp);
-static void	acpi_handle_rsdt(struct ACPIsdt *rsdp);
+static void	acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
+static void	acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
+static void	acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
+static void	acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
+static void	acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
+static void	acpi_print_facs(ACPI_TABLE_FACS *facs);
+static void	acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
+static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
+static void	acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
+static void	acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
+static void	acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
+		    void (*action)(ACPI_SUBTABLE_HEADER *));
 
 /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
 static int addr_size;
@@ -92,41 +97,44 @@ acpi_print_string(char *s, size_t length)
 }
 
 static void
-acpi_print_gas(struct ACPIgas *gas)
+acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
 {
-	switch(gas->address_space_id) {
+	switch(gas->SpaceId) {
 	case ACPI_GAS_MEMORY:
-		printf("0x%08lx:%u[%u] (Memory)", (u_long)gas->address,
-		       gas->bit_offset, gas->bit_width);
+		printf("0x%08lx:%u[%u] (Memory)", (u_long)gas->Address,
+		       gas->BitOffset, gas->BitWidth);
 		break;
 	case ACPI_GAS_IO:
-		printf("0x%02lx:%u[%u] (IO)", (u_long)gas->address,
-		       gas->bit_offset, gas->bit_width);
+		printf("0x%02lx:%u[%u] (IO)", (u_long)gas->Address,
+		       gas->BitOffset, gas->BitWidth);
 		break;
 	case ACPI_GAS_PCI:
-		printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->address >> 32),
-		       (uint16_t)((gas->address >> 16) & 0xffff),
-		       (uint16_t)gas->address);
+		printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32),
+		       (uint16_t)((gas->Address >> 16) & 0xffff),
+		       (uint16_t)gas->Address);
 		break;
 	/* XXX How to handle these below? */
 	case ACPI_GAS_EMBEDDED:
-		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->address,
-		       gas->bit_offset, gas->bit_width);
+		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
+		       gas->BitOffset, gas->BitWidth);
 		break;
 	case ACPI_GAS_SMBUS:
-		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->address,
-		       gas->bit_offset, gas->bit_width);
+		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
+		       gas->BitOffset, gas->BitWidth);
 		break;
+	case ACPI_GAS_CMOS:
+	case ACPI_GAS_PCIBAR:
+	case ACPI_GAS_DATATABLE:
 	case ACPI_GAS_FIXED:
 	default:
-		printf("0x%08lx (?)", (u_long)gas->address);
+		printf("0x%08lx (?)", (u_long)gas->Address);
 		break;
 	}
 }
 
 /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
 static int
-acpi_get_fadt_revision(struct FADTbody *fadt)
+acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt)
 {
 	int fadt_revision;
 
@@ -141,8 +149,8 @@ acpi_get_fadt_revision(struct FADTbody *fadt)
 		 * 32 and 64 bit versions don't match, prefer the 32 bit
 		 * version for all subsequent tables.
 		 */
-		if (fadt->facs_ptr != 0 &&
-		    (fadt->x_facs_ptr & 0xffffffff) != fadt->facs_ptr)
+		if (fadt->Facs != 0 &&
+		    (fadt->XFacs & 0xffffffff) != fadt->Facs)
 			fadt_revision = 1;
 	} else
 		fadt_revision = 1;
@@ -150,34 +158,51 @@ acpi_get_fadt_revision(struct FADTbody *fadt)
 }
 
 static void
-acpi_handle_fadt(struct ACPIsdt *sdp)
+acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
 {
-	struct ACPIsdt	*dsdp;
-	struct FACSbody	*facs;
-	struct FADTbody *fadt;
+	ACPI_TABLE_HEADER *dsdp;
+	ACPI_TABLE_FACS	*facs;
+	ACPI_TABLE_FADT *fadt;
 	int		fadt_revision;
 
-	fadt = (struct FADTbody *)sdp->body;
+	fadt = (ACPI_TABLE_FADT *)sdp;
 	acpi_print_fadt(sdp);
 
 	fadt_revision = acpi_get_fadt_revision(fadt);
 	if (fadt_revision == 1)
-		facs = (struct FACSbody *)acpi_map_sdt(fadt->facs_ptr);
+		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->Facs);
 	else
-		facs = (struct FACSbody *)acpi_map_sdt(fadt->x_facs_ptr);
-	if (memcmp(facs->signature, "FACS", 4) != 0 || facs->len < 64)
+		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->XFacs);
+	if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64)
 		errx(1, "FACS is corrupt");
 	acpi_print_facs(facs);
 
 	if (fadt_revision == 1)
-		dsdp = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr);
+		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
 	else
-		dsdp = (struct ACPIsdt *)acpi_map_sdt(fadt->x_dsdt_ptr);
-	if (acpi_checksum(dsdp, dsdp->len))
+		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
+	if (acpi_checksum(dsdp, dsdp->Length))
 		errx(1, "DSDT is corrupt");
 	acpi_print_dsdt(dsdp);
 }
 
+static void
+acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
+    void (*action)(ACPI_SUBTABLE_HEADER *))
+{
+	ACPI_SUBTABLE_HEADER *subtable;
+	char *end;
+
+	subtable = first;
+	end = (char *)table + table->Length;
+	while ((char *)subtable < end) {
+		printf("\n");
+		action(subtable);
+		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
+		    subtable->Length);
+	}
+}
+
 static void
 acpi_print_cpu(u_char cpu_id)
 {
@@ -190,219 +215,264 @@ acpi_print_cpu(u_char cpu_id)
 }
 
 static void
-acpi_print_local_apic(u_char cpu_id, u_char apic_id, u_int32_t flags)
+acpi_print_cpu_uid(uint32_t uid, char *uid_string)
 {
-	acpi_print_cpu(cpu_id);
+
+	printf("\tUID=%d", uid);
+	if (uid_string != NULL)
+		printf(" (%s)", uid_string);
+	printf("\n");
+}
+
+static void
+acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
+{
+
 	printf("\tFlags={");
-	if (flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED)
+	if (flags & ACPI_MADT_ENABLED)
 		printf("ENABLED");
 	else
 		printf("DISABLED");
 	printf("}\n");
-	printf("\tAPIC ID=%d\n", (u_int)apic_id);
+	printf("\tAPIC ID=%d\n", apic_id);
 }
 
 static void
-acpi_print_io_apic(u_char apic_id, u_int32_t int_base, u_int64_t apic_addr)
+acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
 {
-	printf("\tAPIC ID=%d\n", (u_int)apic_id);
+
+	printf("\tAPIC ID=%d\n", apic_id);
 	printf("\tINT BASE=%d\n", int_base);
-	printf("\tADDR=0x%016jx\n", apic_addr);
+	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
 }
 
 static void
-acpi_print_mps_flags(u_int16_t flags)
+acpi_print_mps_flags(uint16_t flags)
 {
 
 	printf("\tFlags={Polarity=");
-	switch (flags & MPS_INT_FLAG_POLARITY_MASK) {
-	case MPS_INT_FLAG_POLARITY_CONFORM:
+	switch (flags & ACPI_MADT_POLARITY_MASK) {
+	case ACPI_MADT_POLARITY_CONFORMS:
 		printf("conforming");
 		break;
-	case MPS_INT_FLAG_POLARITY_HIGH:
+	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
 		printf("active-hi");
 		break;
-	case MPS_INT_FLAG_POLARITY_LOW:
+	case ACPI_MADT_POLARITY_ACTIVE_LOW:
 		printf("active-lo");
 		break;
 	default:
-		printf("0x%x", flags & MPS_INT_FLAG_POLARITY_MASK);
+		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
 		break;
 	}
 	printf(", Trigger=");
-	switch (flags & MPS_INT_FLAG_TRIGGER_MASK) {
-	case MPS_INT_FLAG_TRIGGER_CONFORM:
+	switch (flags & ACPI_MADT_TRIGGER_MASK) {
+	case ACPI_MADT_TRIGGER_CONFORMS:
 		printf("conforming");
 		break;
-	case MPS_INT_FLAG_TRIGGER_EDGE:
+	case ACPI_MADT_TRIGGER_EDGE:
 		printf("edge");
 		break;
-	case MPS_INT_FLAG_TRIGGER_LEVEL:
+	case ACPI_MADT_TRIGGER_LEVEL:
 		printf("level");
 		break;
 	default:
-		printf("0x%x", (flags & MPS_INT_FLAG_TRIGGER_MASK) >> 2);
+		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
 	}
 	printf("}\n");
 }
 
 static void
-acpi_print_intr(u_int32_t intr, u_int16_t mps_flags)
+acpi_print_intr(uint32_t intr, uint16_t mps_flags)
 {
 
-	printf("\tINTR=%d\n", (u_int)intr);
+	printf("\tINTR=%d\n", intr);
+	acpi_print_mps_flags(mps_flags);
+}
+
+static void
+acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
+{
+
+	printf("\tLINT Pin=%d\n", lint);
 	acpi_print_mps_flags(mps_flags);
 }
 
 const char *apic_types[] = { "Local APIC", "IO APIC", "INT Override", "NMI",
-			     "Local NMI", "Local APIC Override", "IO SAPIC",
-			     "Local SAPIC", "Platform Interrupt" };
-const char *platform_int_types[] = { "PMI", "INIT",
+			     "Local APIC NMI", "Local APIC Override",
+			     "IO SAPIC", "Local SAPIC", "Platform Interrupt",
+			     "Local X2APIC", "Local X2APIC NMI" };
+const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
 				     "Corrected Platform Error" };
 
 static void
-acpi_print_apic(struct MADT_APIC *mp)
+acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
 {
+	ACPI_MADT_LOCAL_APIC *lapic;
+	ACPI_MADT_IO_APIC *ioapic;
+	ACPI_MADT_INTERRUPT_OVERRIDE *over;
+	ACPI_MADT_NMI_SOURCE *nmi;
+	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
+	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
+	ACPI_MADT_IO_SAPIC *iosapic;
+	ACPI_MADT_LOCAL_SAPIC *lsapic;
+	ACPI_MADT_INTERRUPT_SOURCE *isrc;
+	ACPI_MADT_LOCAL_X2APIC *x2apic;
+	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
 
-	if (mp->type < sizeof(apic_types) / sizeof(apic_types[0]))
-		printf("\tType=%s\n", apic_types[mp->type]);
+	if (mp->Type < sizeof(apic_types) / sizeof(apic_types[0]))
+		printf("\tType=%s\n", apic_types[mp->Type]);
 	else
-		printf("\tType=%d (unknown)\n", mp->type);
-	switch (mp->type) {
-	case ACPI_MADT_APIC_TYPE_LOCAL_APIC:
-		acpi_print_local_apic(mp->body.local_apic.cpu_id,
-		    mp->body.local_apic.apic_id, mp->body.local_apic.flags);
+		printf("\tType=%d (unknown)\n", mp->Type);
+	switch (mp->Type) {
+	case ACPI_MADT_TYPE_LOCAL_APIC:
+		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
+		acpi_print_cpu(lapic->ProcessorId);
+		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
 		break;
-	case ACPI_MADT_APIC_TYPE_IO_APIC:
-		acpi_print_io_apic(mp->body.io_apic.apic_id,
-		    mp->body.io_apic.int_base,
-		    mp->body.io_apic.apic_addr);
+	case ACPI_MADT_TYPE_IO_APIC:
+		ioapic = (ACPI_MADT_IO_APIC *)mp;
+		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
+		    ioapic->Address);
 		break;
-	case ACPI_MADT_APIC_TYPE_INT_OVERRIDE:
-		printf("\tBUS=%d\n", (u_int)mp->body.int_override.bus);
-		printf("\tIRQ=%d\n", (u_int)mp->body.int_override.source);
-		acpi_print_intr(mp->body.int_override.intr,
-		    mp->body.int_override.mps_flags);
+	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
+		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
+		printf("\tBUS=%d\n", (u_int)over->Bus);
+		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
+		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
 		break;
-	case ACPI_MADT_APIC_TYPE_NMI:
-		acpi_print_intr(mp->body.nmi.intr, mp->body.nmi.mps_flags);
+	case ACPI_MADT_TYPE_NMI_SOURCE:
+		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
+		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
 		break;
-	case ACPI_MADT_APIC_TYPE_LOCAL_NMI:
-		acpi_print_cpu(mp->body.local_nmi.cpu_id);
-		printf("\tLINT Pin=%d\n", mp->body.local_nmi.lintpin);
-		acpi_print_mps_flags(mp->body.local_nmi.mps_flags);
+	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
+		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
+		acpi_print_cpu(lapic_nmi->ProcessorId);
+		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
 		break;
-	case ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE:
+	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
+		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
 		printf("\tLocal APIC ADDR=0x%016jx\n",
-		    mp->body.local_apic_override.apic_addr);
+		    (uintmax_t)lapic_over->Address);
 		break;
-	case ACPI_MADT_APIC_TYPE_IO_SAPIC:
-		acpi_print_io_apic(mp->body.io_sapic.apic_id,
-		    mp->body.io_sapic.int_base,
-		    mp->body.io_sapic.apic_addr);
+	case ACPI_MADT_TYPE_IO_SAPIC:
+		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
+		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
+		    iosapic->Address);
 		break;
-	case ACPI_MADT_APIC_TYPE_LOCAL_SAPIC:
-		acpi_print_local_apic(mp->body.local_sapic.cpu_id,
-		    mp->body.local_sapic.apic_id, mp->body.local_sapic.flags);
-		printf("\tAPIC EID=%d\n", (u_int)mp->body.local_sapic.apic_eid);
+	case ACPI_MADT_TYPE_LOCAL_SAPIC:
+		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
+		acpi_print_cpu(lsapic->ProcessorId);
+		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
+		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
+		if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
+			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
 		break;
-	case ACPI_MADT_APIC_TYPE_INT_SRC:
-		printf("\tType=%s\n",
-		    platform_int_types[mp->body.int_src.type]);
-		printf("\tCPU ID=%d\n", (u_int)mp->body.int_src.cpu_id);
-		printf("\tCPU EID=%d\n", (u_int)mp->body.int_src.cpu_id);
-		printf("\tSAPIC Vector=%d\n",
-		    (u_int)mp->body.int_src.sapic_vector);
-		acpi_print_intr(mp->body.int_src.intr,
-		    mp->body.int_src.mps_flags);
+	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
+		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
+		if (isrc->Type < sizeof(platform_int_types) /
+		    sizeof(platform_int_types[0]))
+			printf("\tType=%s\n", platform_int_types[isrc->Type]);
+		else
+			printf("\tType=%d (unknown)\n", isrc->Type);
+		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
+		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
+		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
+		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
+		break;
+	case ACPI_MADT_TYPE_LOCAL_X2APIC:
+		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
+		acpi_print_cpu_uid(x2apic->Uid, NULL);
+		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
+		break;
+	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
+		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
+		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
 		break;
 	}
 }
 
 static void
-acpi_handle_apic(struct ACPIsdt *sdp)
+acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
 {
-	struct MADTbody *madtp;
-	struct MADT_APIC *madt_apicp;
+	ACPI_TABLE_MADT *madt;
 
 	printf(BEGIN_COMMENT);
 	acpi_print_sdt(sdp);
-	madtp = (struct MADTbody *) sdp->body;
-	printf("\tLocal APIC ADDR=0x%08x\n", madtp->lapic_addr);
+	madt = (ACPI_TABLE_MADT *)sdp;
+	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
 	printf("\tFlags={");
-	if (madtp->flags & ACPI_APIC_FLAG_PCAT_COMPAT)
+	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
 		printf("PC-AT");
 	printf("}\n");
-	madt_apicp = (struct MADT_APIC *)madtp->body;
-	while (((uintptr_t)madt_apicp) - ((uintptr_t)sdp) < sdp->len) {
-		printf("\n");
-		acpi_print_apic(madt_apicp);
-		madt_apicp = (struct MADT_APIC *) ((char *)madt_apicp +
-		    madt_apicp->len);
-	}
+	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
 	printf(END_COMMENT);
 }
 
 static void
-acpi_handle_hpet(struct ACPIsdt *sdp)
+acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
 {
-	struct HPETbody *hpetp;
+	ACPI_TABLE_HPET *hpet;
 
 	printf(BEGIN_COMMENT);
 	acpi_print_sdt(sdp);
-	hpetp = (struct HPETbody *) sdp->body;
-	printf("\tHPET Number=%d\n", hpetp->hpet_number);
+	hpet = (ACPI_TABLE_HPET *)sdp;
+	printf("\tHPET Number=%d\n", hpet->Sequence);
 	printf("\tADDR=");
-	acpi_print_gas(&hpetp->genaddr);
-	printf("\tHW Rev=0x%x\n", hpetp->block_hwrev);
-	printf("\tComparitors=%d\n", hpetp->block_comparitors);
-	printf("\tCounter Size=%d\n", hpetp->block_counter_size);
+	acpi_print_gas(&hpet->Address);
+	printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
+	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
+	    8);
+	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
+	    1 : 0);
 	printf("\tLegacy IRQ routing capable={");
-	if (hpetp->block_legacy_capable)
+	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
 		printf("TRUE}\n");
 	else
 		printf("FALSE}\n");
-	printf("\tPCI Vendor ID=0x%04x\n", hpetp->block_pcivendor);
-	printf("\tMinimal Tick=%d\n", hpetp->clock_tick);
+	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
+	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
 	printf(END_COMMENT);
 }
 
 static void
-acpi_handle_ecdt(struct ACPIsdt *sdp)
+acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
 {
-	struct ECDTbody *ecdt;
+	ACPI_TABLE_ECDT *ecdt;
 
 	printf(BEGIN_COMMENT);
 	acpi_print_sdt(sdp);
-	ecdt = (struct ECDTbody *) sdp->body;
+	ecdt = (ACPI_TABLE_ECDT *)sdp;
 	printf("\tEC_CONTROL=");
-	acpi_print_gas(&ecdt->ec_control);
+	acpi_print_gas(&ecdt->Control);
 	printf("\n\tEC_DATA=");
-	acpi_print_gas(&ecdt->ec_data);
-	printf("\n\tUID=%#x, ", ecdt->uid);
-	printf("GPE_BIT=%#x\n", ecdt->gpe_bit);
-	printf("\tEC_ID=%s\n", ecdt->ec_id);
+	acpi_print_gas(&ecdt->Data);
+	printf("\n\tUID=%#x, ", ecdt->Uid);
+	printf("GPE_BIT=%#x\n", ecdt->Gpe);
+	printf("\tEC_ID=%s\n", ecdt->Id);
 	printf(END_COMMENT);
 }
 
 static void
-acpi_handle_mcfg(struct ACPIsdt *sdp)
+acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
 {
-	struct MCFGbody *mcfg;
-	u_int i, e;
+	ACPI_TABLE_MCFG *mcfg;
+	ACPI_MCFG_ALLOCATION *alloc;
+	u_int i, entries;
 
 	printf(BEGIN_COMMENT);
 	acpi_print_sdt(sdp);
-	mcfg = (struct MCFGbody *) sdp->body;
-
-	e = (sdp->len - ((caddr_t)&mcfg->s[0] - (caddr_t)sdp)) /
-	    sizeof(*mcfg->s);
-	for (i = 0; i < e; i++, mcfg++) {
+	mcfg = (ACPI_TABLE_MCFG *)sdp;
+	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
+	    sizeof(ACPI_MCFG_ALLOCATION);
+	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
+	for (i = 0; i < entries; i++, alloc++) {
 		printf("\n");
-		printf("\tBase Address=0x%016jx\n", mcfg->s[i].baseaddr);
-		printf("\tSegment Group=0x%04x\n", mcfg->s[i].seg_grp);
-		printf("\tStart Bus=%d\n", mcfg->s[i].start);
-		printf("\tEnd Bus=%d\n", mcfg->s[i].end);
+		printf("\tBase Address=0x%016jx\n", alloc->Address);
+		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
+		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
+		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
 	}
 	printf(END_COMMENT);
 }
@@ -423,108 +493,109 @@ acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
 }
 
 static void
-acpi_print_srat_memory(struct SRAT_memory *mp)
+acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
 {
 
 	printf("\tFlags={");
-	if (mp->flags & ACPI_SRAT_MEM_ENABLED)
+	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
 		printf("ENABLED");
 	else
 		printf("DISABLED");
-	if (mp->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
+	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
 		printf(",HOT_PLUGGABLE");
-	if (mp->flags & ACPI_SRAT_MEM_NON_VOLATILE)
+	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
 		printf(",NON_VOLATILE");
 	printf("}\n");
-	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->base_address);
-	printf("\tLength=0x%016jx\n", (uintmax_t)mp->length);
-	printf("\tProximity Domain=%d\n", mp->proximity_domain);
+	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
+	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
+	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
 }
 
 const char *srat_types[] = { "CPU", "Memory", "X2APIC" };
 
 static void
-acpi_print_srat(struct SRATentry *srat)
+acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
 {
+	ACPI_SRAT_CPU_AFFINITY *cpu;
+	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
 
-	if (srat->type < sizeof(srat_types) / sizeof(srat_types[0]))
-		printf("\tType=%s\n", srat_types[srat->type]);
+	if (srat->Type < sizeof(srat_types) / sizeof(srat_types[0]))
+		printf("\tType=%s\n", srat_types[srat->Type]);
 	else
-		printf("\tType=%d (unknown)\n", srat->type);
-	switch (srat->type) {
+		printf("\tType=%d (unknown)\n", srat->Type);
+	switch (srat->Type) {
 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
-		acpi_print_srat_cpu(srat->body.cpu.apic_id,
-		    srat->body.cpu.proximity_domain_hi[2] << 24 |
-		    srat->body.cpu.proximity_domain_hi[1] << 16 |
-		    srat->body.cpu.proximity_domain_hi[0] << 0 |
-		    srat->body.cpu.proximity_domain_lo, srat->body.cpu.flags);
+		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
+		acpi_print_srat_cpu(cpu->ApicId,
+		    cpu->ProximityDomainHi[2] << 24 |
+		    cpu->ProximityDomainHi[1] << 16 |
+		    cpu->ProximityDomainHi[0] << 0 |
+		    cpu->ProximityDomainLo, cpu->Flags);
 		break;
 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
-		acpi_print_srat_memory(&srat->body.mem);
+		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
 		break;
 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
-		acpi_print_srat_cpu(srat->body.x2apic.apic_id,
-		    srat->body.x2apic.proximity_domain,
-		    srat->body.x2apic.flags);
+		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
+		acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
+		    x2apic->Flags);
 		break;
 	}
 }
 
 static void
-acpi_handle_srat(struct ACPIsdt *sdp)
+acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
 {
-	struct SRATbody *sratp;
-	struct SRATentry *entry;
+	ACPI_TABLE_SRAT *srat;
 
 	printf(BEGIN_COMMENT);
 	acpi_print_sdt(sdp);
-	sratp = (struct SRATbody *)sdp->body;
-	printf("\tTable Revision=%d\n", sratp->table_revision);
-	entry = sratp->body;
-	while (((uintptr_t)entry) - ((uintptr_t)sdp) < sdp->len) {
-		printf("\n");
-		acpi_print_srat(entry);
-		entry = (struct SRATentry *)((char *)entry + entry->len);
-	}
+	srat = (ACPI_TABLE_SRAT *)sdp;
+	printf("\tTable Revision=%d\n", srat->TableRevision);
+	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
 	printf(END_COMMENT);
 }
 
 static void
-acpi_print_sdt(struct ACPIsdt *sdp)
+acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
 {
 	printf("  ");
-	acpi_print_string(sdp->signature, 4);
+	acpi_print_string(sdp->Signature, ACPI_NAME_SIZE);
 	printf(": Length=%d, Revision=%d, Checksum=%d,\n",
-	       sdp->len, sdp->rev, sdp->check);
+	       sdp->Length, sdp->Revision, sdp->Checksum);
 	printf("\tOEMID=");
-	acpi_print_string(sdp->oemid, 6);
+	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
 	printf(", OEM Table ID=");
-	acpi_print_string(sdp->oemtblid, 8);
-	printf(", OEM Revision=0x%x,\n", sdp->oemrev);
+	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
+	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
 	printf("\tCreator ID=");
-	acpi_print_string(sdp->creator, 4);
-	printf(", Creator Revision=0x%x\n", sdp->crerev);
+	acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE);
+	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
 }
 
 static void
-acpi_print_rsdt(struct ACPIsdt *rsdp)
+acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
 {
+	ACPI_TABLE_RSDT *rsdt;
+	ACPI_TABLE_XSDT *xsdt;
 	int	i, entries;
 	u_long	addr;
 
+	rsdt = (ACPI_TABLE_RSDT *)rsdp;
+	xsdt = (ACPI_TABLE_XSDT *)rsdp;
 	printf(BEGIN_COMMENT);
 	acpi_print_sdt(rsdp);
-	entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size;
+	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
 	printf("\tEntries={ ");
 	for (i = 0; i < entries; i++) {
 		if (i > 0)
 			printf(", ");
 		switch (addr_size) {
 		case 4:
-			addr = le32dec((char*)rsdp->body + i * addr_size);
+			addr = le32toh(rsdt->TableOffsetEntry[i]);
 			break;
 		case 8:
-			addr = le64dec((char*)rsdp->body + i * addr_size);
+			addr = le64toh(xsdt->TableOffsetEntry[i]);
 			break;
 		default:
 			addr = 0;
@@ -542,138 +613,147 @@ static const char *acpi_pm_profiles[] = {
 };
 
 static void
-acpi_print_fadt(struct ACPIsdt *sdp)
+acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
 {
-	struct FADTbody *fadt;
+	ACPI_TABLE_FADT *fadt;
 	const char *pm;
 	char	    sep;
 
-	fadt = (struct FADTbody *)sdp->body;
+	fadt = (ACPI_TABLE_FADT *)sdp;
 	printf(BEGIN_COMMENT);
 	acpi_print_sdt(sdp);
-	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->facs_ptr,
-	       fadt->dsdt_ptr);
-	printf("\tINT_MODEL=%s\n", fadt->int_model ? "APIC" : "PIC");
-	if (fadt->pm_profile >= sizeof(acpi_pm_profiles) / sizeof(char *))
+	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
+	       fadt->Dsdt);
+	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
+	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
 		pm = "Reserved";
 	else
-		pm = acpi_pm_profiles[fadt->pm_profile];
-	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->pm_profile);
-	printf("\tSCI_INT=%d\n", fadt->sci_int);
-	printf("\tSMI_CMD=0x%x, ", fadt->smi_cmd);
-	printf("ACPI_ENABLE=0x%x, ", fadt->acpi_enable);
-	printf("ACPI_DISABLE=0x%x, ", fadt->acpi_disable);
-	printf("S4BIOS_REQ=0x%x\n", fadt->s4biosreq);
-	printf("\tPSTATE_CNT=0x%x\n", fadt->pstate_cnt);
+		pm = acpi_pm_profiles[fadt->PreferredProfile];
+	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
+	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
+	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
+	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
+	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
+	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
+	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
-	       fadt->pm1a_evt_blk,
-	       fadt->pm1a_evt_blk + fadt->pm1_evt_len - 1);
-	if (fadt->pm1b_evt_blk != 0)
+	       fadt->Pm1aEventBlock,
+	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
+	if (fadt->Pm1bEventBlock != 0)
 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
-		       fadt->pm1b_evt_blk,
-		       fadt->pm1b_evt_blk + fadt->pm1_evt_len - 1);
+		       fadt->Pm1bEventBlock,
+		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
-	       fadt->pm1a_cnt_blk,
-	       fadt->pm1a_cnt_blk + fadt->pm1_cnt_len - 1);
-	if (fadt->pm1b_cnt_blk != 0)
+	       fadt->Pm1aControlBlock,
+	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
+	if (fadt->Pm1bControlBlock != 0)
 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
-		       fadt->pm1b_cnt_blk,
-		       fadt->pm1b_cnt_blk + fadt->pm1_cnt_len - 1);
-	if (fadt->pm2_cnt_blk != 0)
+		       fadt->Pm1bControlBlock,
+		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
+	if (fadt->Pm2ControlBlock != 0)
 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
-		       fadt->pm2_cnt_blk,
-		       fadt->pm2_cnt_blk + fadt->pm2_cnt_len - 1);
+		       fadt->Pm2ControlBlock,
+		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
 	printf("\tPM_TMR_BLK=0x%x-0x%x\n",
-	       fadt->pm_tmr_blk,
-	       fadt->pm_tmr_blk + fadt->pm_tmr_len - 1);
-	if (fadt->gpe0_blk != 0)
+	       fadt->PmTimerBlock,
+	       fadt->PmTimerBlock + fadt->PmTimerLength - 1);
+	if (fadt->Gpe0Block != 0)
 		printf("\tGPE0_BLK=0x%x-0x%x\n",
-		       fadt->gpe0_blk,
-		       fadt->gpe0_blk + fadt->gpe0_len - 1);
-	if (fadt->gpe1_blk != 0)
+		       fadt->Gpe0Block,
+		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
+	if (fadt->Gpe1Block != 0)
 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
-		       fadt->gpe1_blk,
-		       fadt->gpe1_blk + fadt->gpe1_len - 1,
-		       fadt->gpe1_base);
-	if (fadt->cst_cnt != 0)
-		printf("\tCST_CNT=0x%x\n", fadt->cst_cnt);
+		       fadt->Gpe1Block,
+		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
+		       fadt->Gpe1Base);
+	if (fadt->CstControl != 0)
+		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
-	       fadt->p_lvl2_lat, fadt->p_lvl3_lat);
+	       fadt->C2Latency, fadt->C3Latency);
 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
-	       fadt->flush_size, fadt->flush_stride);
+	       fadt->FlushSize, fadt->FlushStride);
 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
-	       fadt->duty_off, fadt->duty_width);
+	       fadt->DutyOffset, fadt->DutyWidth);
 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
-	       fadt->day_alrm, fadt->mon_alrm, fadt->century);
+	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
 
 #define PRINTFLAG(var, flag) do {			\
-	if ((var) & FADT_FLAG_## flag) {		\
+	if ((var) & ACPI_FADT_## flag) {		\
 		printf("%c%s", sep, #flag); sep = ',';	\
 	}						\
 } while (0)
 
 	printf("\tIAPC_BOOT_ARCH=");
 	sep = '{';
-	PRINTFLAG(fadt->iapc_boot_arch, LEGACY_DEV);
-	PRINTFLAG(fadt->iapc_boot_arch, 8042);
-	if (fadt->iapc_boot_arch != 0)
+	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
+	PRINTFLAG(fadt->BootFlags, 8042);
+	PRINTFLAG(fadt->BootFlags, NO_VGA);
+	PRINTFLAG(fadt->BootFlags, NO_MSI);
+	PRINTFLAG(fadt->BootFlags, NO_ASPM);
+	if (fadt->BootFlags != 0)
 		printf("}");
 	printf("\n");
 
 	printf("\tFlags=");
 	sep = '{';
-	PRINTFLAG(fadt->flags, WBINVD);
-	PRINTFLAG(fadt->flags, WBINVD_FLUSH);
-	PRINTFLAG(fadt->flags, PROC_C1);
-	PRINTFLAG(fadt->flags, P_LVL2_UP);
-	PRINTFLAG(fadt->flags, PWR_BUTTON);
-	PRINTFLAG(fadt->flags, SLP_BUTTON);
-	PRINTFLAG(fadt->flags, FIX_RTC);
-	PRINTFLAG(fadt->flags, RTC_S4);
-	PRINTFLAG(fadt->flags, TMR_VAL_EXT);
-	PRINTFLAG(fadt->flags, DCK_CAP);
-	PRINTFLAG(fadt->flags, RESET_REG);
-	PRINTFLAG(fadt->flags, SEALED_CASE);
-	PRINTFLAG(fadt->flags, HEADLESS);
-	PRINTFLAG(fadt->flags, CPU_SW_SLP);
-	if (fadt->flags != 0)
+	PRINTFLAG(fadt->Flags, WBINVD);
+	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
+	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
+	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
+	PRINTFLAG(fadt->Flags, POWER_BUTTON);
+	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
+	PRINTFLAG(fadt->Flags, FIXED_RTC);
+	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
+	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
+	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
+	PRINTFLAG(fadt->Flags, RESET_REGISTER);
+	PRINTFLAG(fadt->Flags, SEALED_CASE);
+	PRINTFLAG(fadt->Flags, HEADLESS);
+	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
+	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
+	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
+	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
+	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
+	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
+	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
+	if (fadt->Flags != 0)
 		printf("}\n");
 
 #undef PRINTFLAG
 
-	if (fadt->flags & FADT_FLAG_RESET_REG) {
+	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
 		printf("\tRESET_REG=");
-		acpi_print_gas(&fadt->reset_reg);
-		printf(", RESET_VALUE=%#x\n", fadt->reset_value);
+		acpi_print_gas(&fadt->ResetRegister);
+		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
 	}
 	if (acpi_get_fadt_revision(fadt) > 1) {
-		printf("\tX_FACS=0x%08lx, ", (u_long)fadt->x_facs_ptr);
-		printf("X_DSDT=0x%08lx\n", (u_long)fadt->x_dsdt_ptr);
+		printf("\tX_FACS=0x%08lx, ", (u_long)fadt->XFacs);
+		printf("X_DSDT=0x%08lx\n", (u_long)fadt->XDsdt);
 		printf("\tX_PM1a_EVT_BLK=");
-		acpi_print_gas(&fadt->x_pm1a_evt_blk);
-		if (fadt->x_pm1b_evt_blk.address != 0) {
+		acpi_print_gas(&fadt->XPm1aEventBlock);
+		if (fadt->XPm1bEventBlock.Address != 0) {
 			printf("\n\tX_PM1b_EVT_BLK=");
-			acpi_print_gas(&fadt->x_pm1b_evt_blk);
+			acpi_print_gas(&fadt->XPm1bEventBlock);
 		}
 		printf("\n\tX_PM1a_CNT_BLK=");
-		acpi_print_gas(&fadt->x_pm1a_cnt_blk);
-		if (fadt->x_pm1b_cnt_blk.address != 0) {
+		acpi_print_gas(&fadt->XPm1aControlBlock);
+		if (fadt->XPm1bControlBlock.Address != 0) {
 			printf("\n\tX_PM1b_CNT_BLK=");
-			acpi_print_gas(&fadt->x_pm1b_cnt_blk);
+			acpi_print_gas(&fadt->XPm1bControlBlock);
 		}
-		if (fadt->x_pm1b_cnt_blk.address != 0) {
+		if (fadt->XPm2ControlBlock.Address != 0) {
 			printf("\n\tX_PM2_CNT_BLK=");
-			acpi_print_gas(&fadt->x_pm2_cnt_blk);
+			acpi_print_gas(&fadt->XPm2ControlBlock);
 		}
 		printf("\n\tX_PM_TMR_BLK=");
-		acpi_print_gas(&fadt->x_pm_tmr_blk);
-		if (fadt->x_gpe0_blk.address != 0) {
+		acpi_print_gas(&fadt->XPmTimerBlock);
+		if (fadt->XGpe0Block.Address != 0) {
 			printf("\n\tX_GPE0_BLK=");
-			acpi_print_gas(&fadt->x_gpe0_blk);
+			acpi_print_gas(&fadt->XGpe0Block);
 		}
-		if (fadt->x_gpe1_blk.address != 0) {
+		if (fadt->XGpe1Block.Address != 0) {
 			printf("\n\tX_GPE1_BLK=");
-			acpi_print_gas(&fadt->x_gpe1_blk);
+			acpi_print_gas(&fadt->XGpe1Block);
 		}
 		printf("\n");
 	}
@@ -682,38 +762,38 @@ acpi_print_fadt(struct ACPIsdt *sdp)
 }
 
 static void
-acpi_print_facs(struct FACSbody *facs)
+acpi_print_facs(ACPI_TABLE_FACS *facs)
 {
 	printf(BEGIN_COMMENT);
-	printf("  FACS:\tLength=%u, ", facs->len);
-	printf("HwSig=0x%08x, ", facs->hw_sig);
-	printf("Firm_Wake_Vec=0x%08x\n", facs->firm_wake_vec);
+	printf("  FACS:\tLength=%u, ", facs->Length);
+	printf("HwSig=0x%08x, ", facs->HardwareSignature);
+	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
 
 	printf("\tGlobal_Lock=");
-	if (facs->global_lock != 0) {
-		if (facs->global_lock & FACS_FLAG_LOCK_PENDING)
+	if (facs->GlobalLock != 0) {
+		if (facs->GlobalLock & ACPI_GLOCK_PENDING)
 			printf("PENDING,");
-		if (facs->global_lock & FACS_FLAG_LOCK_OWNED)
+		if (facs->GlobalLock & ACPI_GLOCK_OWNED)
 			printf("OWNED");
 	}
 	printf("\n");
 
 	printf("\tFlags=");
-	if (facs->flags & FACS_FLAG_S4BIOS_F)
+	if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
 		printf("S4BIOS");
 	printf("\n");
 
-	if (facs->x_firm_wake_vec != 0) {
+	if (facs->XFirmwareWakingVector != 0) {
 		printf("\tX_Firm_Wake_Vec=%08lx\n",
-		       (u_long)facs->x_firm_wake_vec);
+		       (u_long)facs->XFirmwareWakingVector);
 	}
-	printf("\tVersion=%u\n", facs->version);
+	printf("\tVersion=%u\n", facs->Version);
 
 	printf(END_COMMENT);
 }
 
 static void
-acpi_print_dsdt(struct ACPIsdt *dsdp)
+acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
 {
 	printf(BEGIN_COMMENT);
 	acpi_print_sdt(dsdp);
@@ -723,8 +803,8 @@ acpi_print_dsdt(struct ACPIsdt *dsdp)
 int
 acpi_checksum(void *p, size_t length)
 {
-	u_int8_t	*bp;
-	u_int8_t	sum;
+	uint8_t *bp;
+	uint8_t sum;
 
 	bp = p;
 	sum = 0;
@@ -734,71 +814,77 @@ acpi_checksum(void *p, size_t length)
 	return (sum);
 }
 
-static struct ACPIsdt *
+static ACPI_TABLE_HEADER *
 acpi_map_sdt(vm_offset_t pa)
 {
-	struct	ACPIsdt *sp;
+	ACPI_TABLE_HEADER *sp;
 
-	sp = acpi_map_physical(pa, sizeof(struct ACPIsdt));
-	sp = acpi_map_physical(pa, sp->len);
+	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
+	sp = acpi_map_physical(pa, sp->Length);
 	return (sp);
 }
 
 static void
-acpi_print_rsd_ptr(struct ACPIrsdp *rp)
+acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
 {
 	printf(BEGIN_COMMENT);
 	printf("  RSD PTR: OEM=");
-	acpi_print_string(rp->oem, 6);
-	printf(", ACPI_Rev=%s (%d)\n", rp->revision < 2 ? "1.0x" : "2.0x",
-	       rp->revision);
-	if (rp->revision < 2) {
-		printf("\tRSDT=0x%08x, cksum=%u\n", rp->rsdt_addr, rp->sum);
+	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
+	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
+	       rp->Revision);
+	if (rp->Revision < 2) {
+		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
+		    rp->Checksum);
 	} else {
 		printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n",
-		    (u_long)rp->xsdt_addr, rp->length, rp->xsum);
+		    (u_long)rp->XsdtPhysicalAddress, rp->Length,
+		    rp->ExtendedChecksum);
 	}
 	printf(END_COMMENT);
 }
 
 static void
-acpi_handle_rsdt(struct ACPIsdt *rsdp)
+acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
 {
-	struct ACPIsdt *sdp;
+	ACPI_TABLE_HEADER *sdp;
+	ACPI_TABLE_RSDT *rsdt;
+	ACPI_TABLE_XSDT *xsdt;
 	vm_offset_t addr;
 	int entries, i;
 
 	acpi_print_rsdt(rsdp);
-	entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size;
+	rsdt = (ACPI_TABLE_RSDT *)rsdp;
+	xsdt = (ACPI_TABLE_XSDT *)rsdp;
+	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
 	for (i = 0; i < entries; i++) {
 		switch (addr_size) {
 		case 4:
-			addr = le32dec((char*)rsdp->body + i * addr_size);
+			addr = le32toh(rsdt->TableOffsetEntry[i]);
 			break;
 		case 8:
-			addr = le64dec((char*)rsdp->body + i * addr_size);
+			addr = le64toh(xsdt->TableOffsetEntry[i]);
 			break;
 		default:
 			assert((addr = 0));
 		}
 
-		sdp = (struct ACPIsdt *)acpi_map_sdt(addr);
-		if (acpi_checksum(sdp, sdp->len)) {
+		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
+		if (acpi_checksum(sdp, sdp->Length)) {
 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
-			    sdp->signature);
+			    sdp->Signature);
 			continue;
 		}
-		if (!memcmp(sdp->signature, "FACP", 4))
+		if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
 			acpi_handle_fadt(sdp);
-		else if (!memcmp(sdp->signature, "APIC", 4))
-			acpi_handle_apic(sdp);
-		else if (!memcmp(sdp->signature, "HPET", 4))
+		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
+			acpi_handle_madt(sdp);
+		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
 			acpi_handle_hpet(sdp);
-		else if (!memcmp(sdp->signature, "ECDT", 4))
+		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
 			acpi_handle_ecdt(sdp);
-		else if (!memcmp(sdp->signature, "MCFG", 4))
+		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
 			acpi_handle_mcfg(sdp);
-		else if (!memcmp(sdp->signature, "SRAT", 4))
+		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
 			acpi_handle_srat(sdp);
 		else {
 			printf(BEGIN_COMMENT);
@@ -808,11 +894,11 @@ acpi_handle_rsdt(struct ACPIsdt *rsdp)
 	}
 }
 
-struct ACPIsdt *
+ACPI_TABLE_HEADER *
 sdt_load_devmem(void)
 {
-	struct	ACPIrsdp *rp;
-	struct	ACPIsdt *rsdp;
+	ACPI_TABLE_RSDP *rp;
+	ACPI_TABLE_HEADER *rsdp;
 
 	rp = acpi_find_rsd_ptr();
 	if (!rp)
@@ -820,16 +906,16 @@ sdt_load_devmem(void)
 
 	if (tflag)
 		acpi_print_rsd_ptr(rp);
-	if (rp->revision < 2) {
-		rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr);
-		if (memcmp(rsdp->signature, "RSDT", 4) != 0 ||
-		    acpi_checksum(rsdp, rsdp->len) != 0)
+	if (rp->Revision < 2) {
+		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
+		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
+		    acpi_checksum(rsdp, rsdp->Length) != 0)
 			errx(1, "RSDT is corrupted");
 		addr_size = sizeof(uint32_t);
 	} else {
-		rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->xsdt_addr);
-		if (memcmp(rsdp->signature, "XSDT", 4) != 0 ||
-		    acpi_checksum(rsdp, rsdp->len) != 0)
+		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
+		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
+		    acpi_checksum(rsdp, rsdp->Length) != 0)
 			errx(1, "XSDT is corrupted");
 		addr_size = sizeof(uint64_t);
 	}
@@ -838,37 +924,39 @@ sdt_load_devmem(void)
 
 /* Write the DSDT to a file, concatenating any SSDTs (if present). */
 static int
-write_dsdt(int fd, struct ACPIsdt *rsdt, struct ACPIsdt *dsdt)
+write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
 {
-	struct ACPIsdt sdt;
-	struct ACPIsdt *ssdt;
+	ACPI_TABLE_HEADER sdt;
+	ACPI_TABLE_HEADER *ssdt;
 	uint8_t sum;
 
 	/* Create a new checksum to account for the DSDT and any SSDTs. */
 	sdt = *dsdt;
 	if (rsdt != NULL) {
-		sdt.check = 0;
-		sum = acpi_checksum(dsdt->body, dsdt->len - SIZEOF_SDT_HDR);
-		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
+		sdt.Checksum = 0;
+		sum = acpi_checksum(dsdt + 1, dsdt->Length -
+		    sizeof(ACPI_TABLE_HEADER));
+		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
 		while (ssdt != NULL) {
-			sdt.len += ssdt->len - SIZEOF_SDT_HDR;
-			sum += acpi_checksum(ssdt->body,
-			    ssdt->len - SIZEOF_SDT_HDR);
-			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
+			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
+			sum += acpi_checksum(ssdt + 1,
+			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
+			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
 		}
-		sum += acpi_checksum(&sdt, SIZEOF_SDT_HDR);
-		sdt.check -= sum;
+		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
+		sdt.Checksum -= sum;
 	}
 
 	/* Write out the DSDT header and body. */
-	write(fd, &sdt, SIZEOF_SDT_HDR);
-	write(fd, dsdt->body, dsdt->len - SIZEOF_SDT_HDR);
+	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
+	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
 
 	/* Write out any SSDTs (if present.) */
 	if (rsdt != NULL) {
 		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
 		while (ssdt != NULL) {
-			write(fd, ssdt->body, ssdt->len - SIZEOF_SDT_HDR);
+			write(fd, ssdt + 1, ssdt->Length -
+			    sizeof(ACPI_TABLE_HEADER));
 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
 		}
 	}
@@ -876,7 +964,7 @@ write_dsdt(int fd, struct ACPIsdt *rsdt, struct ACPIsdt *dsdt)
 }
 
 void
-dsdt_save_file(char *outfile, struct ACPIsdt *rsdt, struct ACPIsdt *dsdp)
+dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
 {
 	int	fd;
 	mode_t	mode;
@@ -893,7 +981,7 @@ dsdt_save_file(char *outfile, struct ACPIsdt *rsdt, struct ACPIsdt *dsdp)
 }
 
 void
-aml_disassemble(struct ACPIsdt *rsdt, struct ACPIsdt *dsdp)
+aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
 {
 	char buf[PATH_MAX], tmpstr[PATH_MAX];
 	const char *tmpdir;
@@ -949,40 +1037,44 @@ aml_disassemble(struct ACPIsdt *rsdt, struct ACPIsdt *dsdp)
 }
 
 void
-sdt_print_all(struct ACPIsdt *rsdp)
+sdt_print_all(ACPI_TABLE_HEADER *rsdp)
 {
 	acpi_handle_rsdt(rsdp);
 }
 
 /* Fetch a table matching the given signature via the RSDT. */
-struct ACPIsdt *
-sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig, struct ACPIsdt *last)
+ACPI_TABLE_HEADER *
+sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
 {
-	struct ACPIsdt *sdt;
+	ACPI_TABLE_HEADER *sdt;
+	ACPI_TABLE_RSDT *rsdt;
+	ACPI_TABLE_XSDT *xsdt;
 	vm_offset_t addr;
 	int entries, i;
 
-	entries = (rsdt->len - SIZEOF_SDT_HDR) / addr_size;
+	rsdt = (ACPI_TABLE_RSDT *)rsdp;
+	xsdt = (ACPI_TABLE_XSDT *)rsdp;
+	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
 	for (i = 0; i < entries; i++) {
 		switch (addr_size) {
 		case 4:
-			addr = le32dec((char*)rsdt->body + i * addr_size);
+			addr = le32toh(rsdt->TableOffsetEntry[i]);
 			break;
 		case 8:
-			addr = le64dec((char*)rsdt->body + i * addr_size);
+			addr = le64toh(xsdt->TableOffsetEntry[i]);
 			break;
 		default:
 			assert((addr = 0));
 		}
-		sdt = (struct ACPIsdt *)acpi_map_sdt(addr);
+		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
 		if (last != NULL) {
 			if (sdt == last)
 				last = NULL;
 			continue;
 		}
-		if (memcmp(sdt->signature, sig, strlen(sig)))
+		if (memcmp(sdt->Signature, sig, strlen(sig)))
 			continue;
-		if (acpi_checksum(sdt, sdt->len))
+		if (acpi_checksum(sdt, sdt->Length))
 			errx(1, "RSDT entry %d is corrupt", i);
 		return (sdt);
 	}
@@ -990,17 +1082,17 @@ sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig, struct ACPIsdt *last)
 	return (NULL);
 }
 
-struct ACPIsdt *
-dsdt_from_fadt(struct FADTbody *fadt)
+ACPI_TABLE_HEADER *
+dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
 {
-	struct	ACPIsdt	*sdt;
+	ACPI_TABLE_HEADER	*sdt;
 
-	/* Use the DSDT address if it is version 1, otherwise use X_DSDT. */
+	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
 	if (acpi_get_fadt_revision(fadt) == 1)
-		sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr);
+		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
 	else
-		sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->x_dsdt_ptr);
-	if (acpi_checksum(sdt, sdt->len))
+		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
+	if (acpi_checksum(sdt, sdt->Length))
 		errx(1, "DSDT is corrupt\n");
 	return (sdt);
 }
diff --git a/usr.sbin/acpi/acpidump/acpi_user.c b/usr.sbin/acpi/acpidump/acpi_user.c
index d9d9c2417db..f0c47b41735 100644
--- a/usr.sbin/acpi/acpidump/acpi_user.c
+++ b/usr.sbin/acpi/acpidump/acpi_user.c
@@ -94,40 +94,43 @@ acpi_user_find_mapping(vm_offset_t pa, size_t size)
 	return (map);
 }
 
-static struct ACPIrsdp *
+static ACPI_TABLE_RSDP *
 acpi_get_rsdp(u_long addr)
 {
-	struct ACPIrsdp rsdp;
+	ACPI_TABLE_RSDP 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))
+	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))
+	/* Check the standard checksum. */
+	if (acpi_checksum(&rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0)
+		return (NULL);
+
+	/* Check extended checksum if table version >= 2. */
+	if (rsdp.Revision >= 2 &&
+	    acpi_checksum(&rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)
 		return (NULL);
 
 	/* If the revision is 0, assume a version 1 length. */
-	if (rsdp.revision == 0)
-		len = 20;
+	if (rsdp.Revision == 0)
+		len = ACPI_RSDP_REV0_SIZE;
 	else
-		len = rsdp.length;
-
-	/* XXX Should handle ACPI 2.0 RSDP extended checksum here. */
+		len = rsdp.Length;
 
 	return (acpi_map_physical(addr, len));
 }
 
-static struct ACPIrsdp *
+static ACPI_TABLE_RSDP *
 acpi_scan_rsd_ptr(void)
 {
 #if defined(__amd64__) || defined(__i386__)
-	struct ACPIrsdp *rsdp;
+	ACPI_TABLE_RSDP *rsdp;
 	u_long		addr, end;
 
 	/*
@@ -137,15 +140,15 @@ acpi_scan_rsd_ptr(void)
 	 * 1. EBDA (1 KB area addressed by the 16 bit pointer at 0x40E
 	 * 2. High memory (0xE0000 - 0xFFFFF)
 	 */
-	addr = RSDP_EBDA_PTR;
+	addr = ACPI_EBDA_PTR_LOCATION;
 	pread(acpi_mem_fd, &addr, sizeof(uint16_t), addr);
 	addr <<= 4;
-	end = addr + RSDP_EBDA_SIZE;
+	end = addr + ACPI_EBDA_WINDOW_SIZE;
 	for (; addr < end; addr += 16)
 		if ((rsdp = acpi_get_rsdp(addr)) != NULL)
 			return (rsdp);
-	addr = RSDP_HI_START;
-	end = addr + RSDP_HI_SIZE;
+	addr = ACPI_HI_RSDP_WINDOW_BASE;
+	end = addr + ACPI_HI_RSDP_WINDOW_SIZE;
 	for (; addr < end; addr += 16)
 		if ((rsdp = acpi_get_rsdp(addr)) != NULL)
 			return (rsdp);
@@ -156,10 +159,10 @@ acpi_scan_rsd_ptr(void)
 /*
  * Public interfaces
  */
-struct ACPIrsdp *
+ACPI_TABLE_RSDP *
 acpi_find_rsd_ptr(void)
 {
-	struct ACPIrsdp *rsdp;
+	ACPI_TABLE_RSDP *rsdp;
 	char		buf[20];
 	u_long		addr;
 	size_t		len;
@@ -191,10 +194,10 @@ acpi_map_physical(vm_offset_t pa, size_t size)
 	return (map->va + (pa - map->pa));
 }
 
-struct ACPIsdt *
+ACPI_TABLE_HEADER *
 dsdt_load_file(char *infile)
 {
-	struct ACPIsdt	*sdt;
+	ACPI_TABLE_HEADER *sdt;
 	uint8_t		*dp;
 	struct stat	 sb;
 
@@ -210,8 +213,9 @@ dsdt_load_file(char *infile)
 	if (dp == NULL)
 		errx(1, "mmap %s", infile);
 
-	sdt = (struct ACPIsdt *)dp;
-	if (strncmp(dp, "DSDT", 4) != 0 || acpi_checksum(sdt, sdt->len) != 0)
+	sdt = (ACPI_TABLE_HEADER *)dp;
+	if (strncmp(dp, ACPI_SIG_DSDT, 4) != 0 ||
+	    acpi_checksum(sdt, sdt->Length) != 0)
 		return (NULL);
 
 	return (sdt);
diff --git a/usr.sbin/acpi/acpidump/acpidump.c b/usr.sbin/acpi/acpidump/acpidump.c
index a601ac26163..38844b63873 100644
--- a/usr.sbin/acpi/acpidump/acpidump.c
+++ b/usr.sbin/acpi/acpidump/acpidump.c
@@ -54,9 +54,9 @@ usage(const char *progname)
 int
 main(int argc, char *argv[])
 {
+	ACPI_TABLE_HEADER *rsdt, *sdt;
 	char	c, *progname;
 	char	*dsdt_input_file, *dsdt_output_file;
-	struct	ACPIsdt *rsdt, *sdt;
 
 	dsdt_input_file = dsdt_output_file = NULL;
 	progname = argv[0];
@@ -117,8 +117,8 @@ main(int argc, char *argv[])
 
 	/* Translate RSDT to DSDT pointer */
 	if (dsdt_input_file == NULL) {
-		sdt = sdt_from_rsdt(rsdt, "FACP", NULL);
-		sdt = dsdt_from_fadt((struct FADTbody *)sdt->body);
+		sdt = sdt_from_rsdt(rsdt, ACPI_SIG_FADT, NULL);
+		sdt = dsdt_from_fadt((ACPI_TABLE_FADT *)sdt);
 	} else {
 		sdt = rsdt;
 		rsdt = NULL;
diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h
index 8eca6a8b6bb..c75cabd34f6 100644
--- a/usr.sbin/acpi/acpidump/acpidump.h
+++ b/usr.sbin/acpi/acpidump/acpidump.h
@@ -28,368 +28,55 @@
  */
 
 #ifndef _ACPIDUMP_H_
-#define _ACPIDUMP_H_
+#define	_ACPIDUMP_H_
 
-/* Generic Address structure */
-struct ACPIgas {
-	u_int8_t	address_space_id;
-#define ACPI_GAS_MEMORY		0
-#define ACPI_GAS_IO		1
-#define ACPI_GAS_PCI		2
-#define ACPI_GAS_EMBEDDED	3
-#define ACPI_GAS_SMBUS		4
-#define ACPI_GAS_FIXED		0x7f
-	u_int8_t	bit_width;
-	u_int8_t	bit_offset;
-	u_int8_t	_reserved;
-	u_int64_t	address;
-} __packed;
+#include 
+#include 
+#include 
 
-/* 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;
+/* GAS address space ID constants. */
+#define	ACPI_GAS_MEMORY		0
+#define	ACPI_GAS_IO		1
+#define	ACPI_GAS_PCI		2
+#define	ACPI_GAS_EMBEDDED	3
+#define	ACPI_GAS_SMBUS		4
+#define	ACPI_GAS_CMOS		5
+#define	ACPI_GAS_PCIBAR		6
+#define	ACPI_GAS_DATATABLE	7
+#define	ACPI_GAS_FIXED		0x7f
 
-/* 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;
-
-/* Fixed ACPI Description Table (body) */
-struct FADTbody {
-	u_int32_t	facs_ptr;
-	u_int32_t	dsdt_ptr;
-	u_int8_t	int_model;
-#define ACPI_FADT_INTMODEL_PIC	0	/* Standard PC-AT PIC */
-#define ACPI_FADT_INTMODEL_APIC	1	/* Multiple APIC */
-	u_int8_t	pm_profile;
-	u_int16_t	sci_int;
-	u_int32_t	smi_cmd;
-	u_int8_t	acpi_enable;
-	u_int8_t	acpi_disable;
-	u_int8_t	s4biosreq;
-	u_int8_t	pstate_cnt;
-	u_int32_t	pm1a_evt_blk;
-	u_int32_t	pm1b_evt_blk;
-	u_int32_t	pm1a_cnt_blk;
-	u_int32_t	pm1b_cnt_blk;
-	u_int32_t	pm2_cnt_blk;
-	u_int32_t	pm_tmr_blk;
-	u_int32_t	gpe0_blk;
-	u_int32_t	gpe1_blk;
-	u_int8_t	pm1_evt_len;
-	u_int8_t	pm1_cnt_len;
-	u_int8_t	pm2_cnt_len;
-	u_int8_t	pm_tmr_len;
-	u_int8_t	gpe0_len;
-	u_int8_t	gpe1_len;
-	u_int8_t	gpe1_base;
-	u_int8_t	cst_cnt;
-	u_int16_t	p_lvl2_lat;
-	u_int16_t	p_lvl3_lat;
-	u_int16_t	flush_size;
-	u_int16_t	flush_stride;
-	u_int8_t	duty_off;
-	u_int8_t	duty_width;
-	u_int8_t	day_alrm;
-	u_int8_t	mon_alrm;
-	u_int8_t	century;
-	u_int16_t	iapc_boot_arch;
-#define FADT_FLAG_LEGACY_DEV	1	/* System has legacy devices */
-#define FADT_FLAG_8042		2	/* 8042 keyboard controller */
-	u_char		reserved4[1];
-	u_int32_t	flags;
-#define FADT_FLAG_WBINVD	1	/* WBINVD is correctly supported */
-#define FADT_FLAG_WBINVD_FLUSH	2	/* WBINVD flushes caches */
-#define FADT_FLAG_PROC_C1	4	/* C1 power state supported */
-#define FADT_FLAG_P_LVL2_UP	8	/* C2 power state works on SMP */
-#define FADT_FLAG_PWR_BUTTON	16	/* Power button uses control method */
-#define FADT_FLAG_SLP_BUTTON	32	/* Sleep button uses control method */
-#define FADT_FLAG_FIX_RTC	64	/* RTC wakeup not supported */
-#define FADT_FLAG_RTC_S4	128	/* RTC can wakeup from S4 state */
-#define FADT_FLAG_TMR_VAL_EXT	256	/* TMR_VAL is 32bit */
-#define FADT_FLAG_DCK_CAP	512	/* Can support docking */
-#define FADT_FLAG_RESET_REG	1024	/* Supports RESET_REG */
-#define FADT_FLAG_SEALED_CASE	2048	/* Case cannot be opened */
-#define FADT_FLAG_HEADLESS	4096	/* No monitor */
-#define FADT_FLAG_CPU_SW_SLP	8192	/* Supports CPU software sleep */
-	struct ACPIgas	reset_reg;
-	u_int8_t	reset_value;
-	u_int8_t	reserved5[3];
-	u_int64_t	x_facs_ptr;
-	u_int64_t	x_dsdt_ptr;
-	struct ACPIgas	x_pm1a_evt_blk;
-	struct ACPIgas	x_pm1b_evt_blk;
-	struct ACPIgas	x_pm1a_cnt_blk;
-	struct ACPIgas	x_pm1b_cnt_blk;
-	struct ACPIgas	x_pm2_cnt_blk;
-	struct ACPIgas	x_pm_tmr_blk;
-	struct ACPIgas	x_gpe0_blk;
-	struct ACPIgas	x_gpe1_blk;
-} __packed;
-
-/* Firmware ACPI Control Structure */
-struct FACSbody {
-	u_char		signature[4];
-	u_int32_t	len;
-	u_int32_t	hw_sig;
-	/*
-	 * NOTE This should be filled with physical address below 1MB!!
-	 * sigh....
-	 */
-	u_int32_t	firm_wake_vec;
-	u_int32_t	global_lock;
-#define FACS_FLAG_LOCK_PENDING	1	/* 5.2.6.1 Global Lock */
-#define FACS_FLAG_LOCK_OWNED	2
-	u_int32_t	flags;
-#define FACS_FLAG_S4BIOS_F	1	/* Supports S4BIOS_SEQ */
-	u_int64_t	x_firm_wake_vec;
-	u_int8_t	version;
-	char		reserved[31];
-} __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;
-
-struct HPETbody {
-	u_int32_t	block_hwrev:8,
-			block_comparitors:5,
-			block_counter_size:1,
-			:1,
-			block_legacy_capable:1,
-			block_pcivendor:16;
-	struct ACPIgas  genaddr;
-	u_int8_t	hpet_number;
-	u_int16_t	clock_tick __packed;
-} __packed;
-
-/* Embedded Controller Description Table */
-struct ECDTbody {
-	struct ACPIgas	ec_control;	/* Control register */
-	struct ACPIgas	ec_data;	/* Data register */
-	uint32_t	uid;		/* Same value as _UID in namespace */
-	uint8_t		gpe_bit;	/* GPE bit for the EC */
-	u_char		ec_id[1];	/* Variable length name string */
-} __packed;
-
-/* Memory Mapped PCI config space base allocation structure */
-struct MCFGbody {
-	uint8_t		rsvd[8];
-	struct {
-		uint64_t	baseaddr;	/* Base Address */
-		uint16_t	seg_grp;	/* Segment group number */
-		uint8_t		start;		/* Starting bus number */
-		uint8_t		end;		/* Ending bus number */
-		uint8_t		rsvd[4];	/* Reserved */
-	} s[1] __packed;
-} __packed;
-
-/* System Resource Affinity Table */
-struct SRAT_cpu {
-	uint8_t		proximity_domain_lo;
-	uint8_t		apic_id;
-	uint32_t	flags;
-#define	ACPI_SRAT_CPU_ENABLED		0x00000001
-	uint8_t		sapic_eid;
-	uint8_t		proximity_domain_hi[3];
-	uint32_t	reserved;
-} __packed;
-
-struct SRAT_memory {
-	uint32_t	proximity_domain;
-	uint16_t	reserved;
-	uint64_t	base_address;
-	uint64_t	length;
-	uint32_t	reserved1;
-	uint32_t	flags;
-#define	ACPI_SRAT_MEM_ENABLED		0x00000001
-#define	ACPI_SRAT_MEM_HOT_PLUGGABLE	0x00000002
-#define	ACPI_SRAT_MEM_NON_VOLATILE	0x00000002
-	uint64_t	reserved2;
-} __packed;
-
-struct SRAT_x2apic {
-	uint16_t	reserved;
-	uint32_t	proximity_domain;
-	uint32_t	apic_id;
-	uint32_t	flags;
-} __packed;
-
-struct SRATentry {
-	uint8_t		type;
-#define	ACPI_SRAT_TYPE_CPU_AFFINITY		0
-#define	ACPI_SRAT_TYPE_MEMORY_AFFINITY		1
-#define	ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY	2
-	uint8_t		len;
-	union {
-		struct SRAT_cpu cpu;
-		struct SRAT_memory mem;
-		struct SRAT_x2apic x2apic;
-	} body;
-} __packed;
-
-struct SRATbody {
-	uint32_t	table_revision;
-	uint64_t	reserved;
-	struct SRATentry body[0];
-} __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
+/* Subfields in the HPET Id member. */
+#define	ACPI_HPET_ID_HARDWARE_REV_ID	0x000000ff
+#define	ACPI_HPET_ID_COMPARATORS	0x00001f00
+#define	ACPI_HPET_ID_COUNT_SIZE_CAP	0x00002000
+#define	ACPI_HPET_ID_LEGACY_CAPABLE	0x00008000
+#define	ACPI_HPET_ID_PCI_VENDOR_ID	0xffff0000
 
 /* Find and map the RSD PTR structure and return it for parsing */
-struct ACPIsdt  *sdt_load_devmem(void);
+ACPI_TABLE_HEADER *sdt_load_devmem(void);
 
 /*
  * Load the DSDT from a previous save file.  Note that other tables are
  * not saved (i.e. FADT)
  */
-struct ACPIsdt  *dsdt_load_file(char *);
+ACPI_TABLE_HEADER *dsdt_load_file(char *);
 
 /* Save the DSDT to a file */
-void		 dsdt_save_file(char *, struct ACPIsdt *, struct ACPIsdt *);
+void	 dsdt_save_file(char *, ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER *);
 
 /* Print out as many fixed tables as possible, given the RSD PTR */
-void		 sdt_print_all(struct ACPIsdt *);
+void	 sdt_print_all(ACPI_TABLE_HEADER *);
 
 /* Disassemble the AML in the DSDT */
-void		 aml_disassemble(struct ACPIsdt *, struct ACPIsdt *);
+void	 aml_disassemble(ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER *);
 
 /* Routines for accessing tables in physical memory */
-struct ACPIrsdp	*acpi_find_rsd_ptr(void);
-void		*acpi_map_physical(vm_offset_t, size_t);
-struct ACPIsdt	*sdt_from_rsdt(struct ACPIsdt *, const char *,
-    struct ACPIsdt *);
-struct ACPIsdt	*dsdt_from_fadt(struct FADTbody *);
-int		 acpi_checksum(void *, size_t);
+ACPI_TABLE_RSDP *acpi_find_rsd_ptr(void);
+void	*acpi_map_physical(vm_offset_t, size_t);
+ACPI_TABLE_HEADER *sdt_from_rsdt(ACPI_TABLE_HEADER *, const char *,
+	    ACPI_TABLE_HEADER *);
+ACPI_TABLE_HEADER *dsdt_from_fadt(ACPI_TABLE_FADT *);
+int	 acpi_checksum(void *, size_t);
 
 /* Command line flags */
 extern int	dflag;

From a6fb7268601e0e3f50fecefc6805b74547a68462 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 15:09:54 +0000
Subject: [PATCH 0389/2592] MFC 196615: Extend the device pager to support
 different memory attributes on different pages in an object. - Add a new
 variant of d_mmap() currently called d_mmap2() which accepts   an additional
 in/out parameter that is the memory attribute to use for   the requested
 page. - A driver either uses d_mmap() or d_mmap2() for all requests but not
 both.   The current implementation uses a flag in the cdevsw (D_MMAP2) to
 indicate   that the driver provides a d_mmap2() handler instead of d_mmap(). 
 This   is done to make the change ABI compatible with existing drivers and  
 MFC'able to 7 and 8.

---
 sys/kern/kern_conf.c  | 14 ++++++++++----
 sys/sys/conf.h        | 10 +++++++++-
 sys/sys/types.h       |  1 +
 sys/vm/device_pager.c | 20 +++++++++++++++-----
 sys/vm/vm.h           | 12 ++++++------
 5 files changed, 41 insertions(+), 16 deletions(-)

diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index 8a5577ca274..8504e48d3e5 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -302,7 +302,7 @@ static struct cdevsw dead_cdevsw = {
 #define no_read		(d_read_t *)enodev
 #define no_write	(d_write_t *)enodev
 #define no_ioctl	(d_ioctl_t *)enodev
-#define no_mmap		(d_mmap_t *)enodev
+#define no_mmap		(d_mmap2_t *)enodev
 #define no_kqfilter	(d_kqfilter_t *)enodev
 #define no_mmap_single	(d_mmap_single_t *)enodev
 
@@ -469,7 +469,8 @@ giant_kqfilter(struct cdev *dev, struct knote *kn)
 }
 
 static int
-giant_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
+giant_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot,
+    vm_memattr_t *memattr)
 {
 	struct cdevsw *dsw;
 	int retval;
@@ -478,7 +479,11 @@ giant_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
 	if (dsw == NULL)
 		return (ENXIO);
 	mtx_lock(&Giant);
-	retval = dsw->d_gianttrick->d_mmap(dev, offset, paddr, nprot);
+	if (dsw->d_gianttrick->d_flags & D_MMAP2)
+		retval = dsw->d_gianttrick->d_mmap2(dev, offset, paddr, nprot,
+		    memattr);
+	else
+		retval = dsw->d_gianttrick->d_mmap(dev, offset, paddr, nprot);
 	mtx_unlock(&Giant);
 	dev_relthread(dev);
 	return (retval);
@@ -614,6 +619,7 @@ prep_cdevsw(struct cdevsw *devsw)
 		if (devsw->d_gianttrick == NULL) {
 			memcpy(dsw2, devsw, sizeof *dsw2);
 			devsw->d_gianttrick = dsw2;
+			devsw->d_flags |= D_MMAP2;
 			dsw2 = NULL;
 		}
 	}
@@ -634,7 +640,7 @@ prep_cdevsw(struct cdevsw *devsw)
 	FIXUP(d_write,		no_write,	giant_write);
 	FIXUP(d_ioctl,		no_ioctl,	giant_ioctl);
 	FIXUP(d_poll,		no_poll,	giant_poll);
-	FIXUP(d_mmap,		no_mmap,	giant_mmap);
+	FIXUP(d_mmap2,		no_mmap,	giant_mmap);
 	FIXUP(d_strategy,	no_strategy,	giant_strategy);
 	FIXUP(d_kqfilter,	no_kqfilter,	giant_kqfilter);
 	FIXUP(d_mmap_single,	no_mmap_single,	giant_mmap_single);
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index a41028b8f8e..3df4284fa92 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -137,6 +137,8 @@ typedef int d_poll_t(struct cdev *dev, int events, struct thread *td);
 typedef int d_kqfilter_t(struct cdev *dev, struct knote *kn);
 typedef int d_mmap_t(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr,
    		     int nprot);
+typedef int d_mmap2_t(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr,
+		     int nprot, vm_memattr_t *memattr);
 typedef int d_mmap_single_t(struct cdev *cdev, vm_ooffset_t *offset,
     vm_size_t size, struct vm_object **object, int nprot);
 typedef void d_purge_t(struct cdev *dev);
@@ -170,6 +172,7 @@ typedef int dumper_t(
 #define D_PSEUDO	0x00200000	/* make_dev() can return NULL */
 #define D_NEEDGIANT	0x00400000	/* driver want Giant */
 #define	D_NEEDMINOR	0x00800000	/* driver uses clone_create() */
+#define	D_MMAP2		0x01000000	/* driver uses d_mmap2() */
 
 /*
  * Version numbers.
@@ -198,7 +201,10 @@ struct cdevsw {
 	d_write_t		*d_write;
 	d_ioctl_t		*d_ioctl;
 	d_poll_t		*d_poll;
-	d_mmap_t		*d_mmap;
+	union {
+		d_mmap_t		*old;
+		d_mmap2_t		*new;
+	} __d_mmap;
 	d_strategy_t		*d_strategy;
 	dumper_t		*d_dump;
 	d_kqfilter_t		*d_kqfilter;
@@ -218,6 +224,8 @@ struct cdevsw {
 		SLIST_ENTRY(cdevsw)	postfree_list;
 	} __d_giant;
 };
+#define	d_mmap			__d_mmap.old
+#define	d_mmap2			__d_mmap.new
 #define	d_gianttrick		__d_giant.gianttrick
 #define	d_postfree_list		__d_giant.postfree_list
 
diff --git a/sys/sys/types.h b/sys/sys/types.h
index 66be699d6e0..6696de67091 100644
--- a/sys/sys/types.h
+++ b/sys/sys/types.h
@@ -299,6 +299,7 @@ typedef	__uint32_t	intrmask_t;	/* Interrupt mask (spl, xxx_imask...) */
 
 typedef	__uintfptr_t	uintfptr_t;
 typedef	__uint64_t	uoff_t;
+typedef	char		vm_memattr_t;	/* memory attribute codes */
 typedef	struct vm_page	*vm_page_t;
 
 #define offsetof(type, field) __offsetof(type, field)
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index 0d762de0705..c7f559381fd 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -93,6 +93,17 @@ dev_pager_init()
 	    UMA_ZONE_NOFREE|UMA_ZONE_VM); 
 }
 
+static __inline int
+dev_mmap(struct cdevsw *csw, struct cdev *dev, vm_offset_t offset,
+    vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr)
+{
+
+	if (csw->d_flags & D_MMAP2)
+		return (csw->d_mmap2(dev, offset, paddr, nprot, memattr));
+	else
+		return (csw->d_mmap(dev, offset, paddr, nprot));
+}
+
 /*
  * MPSAFE
  */
@@ -106,6 +117,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
 	unsigned int npages;
 	vm_paddr_t paddr;
 	vm_offset_t off;
+	vm_memattr_t dummy;
 	struct cdevsw *csw;
 
 	/*
@@ -133,7 +145,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
 	 */
 	npages = OFF_TO_IDX(size);
 	for (off = foff; npages--; off += PAGE_SIZE)
-		if ((*csw->d_mmap)(dev, off, &paddr, (int)prot) != 0) {
+		if (dev_mmap(csw, dev, off, &paddr, (int)prot, &dummy) != 0) {
 			dev_relthread(dev);
 			return (NULL);
 		}
@@ -214,7 +226,6 @@ dev_pager_getpages(object, m, count, reqpage)
 	vm_memattr_t memattr;
 	struct cdev *dev;
 	int i, ret;
-	int prot;
 	struct cdevsw *csw;
 	struct thread *td;
 	struct file *fpop;
@@ -228,12 +239,11 @@ dev_pager_getpages(object, m, count, reqpage)
 	csw = dev_refthread(dev);
 	if (csw == NULL)
 		panic("dev_pager_getpage: no cdevsw");
-	prot = PROT_READ;	/* XXX should pass in? */
-
 	td = curthread;
 	fpop = td->td_fpop;
 	td->td_fpop = NULL;
-	ret = (*csw->d_mmap)(dev, (vm_offset_t)offset << PAGE_SHIFT, &paddr, prot);
+	ret = dev_mmap(csw, dev, (vm_offset_t)offset << PAGE_SHIFT, &paddr,
+	    PROT_READ, &memattr);
 	KASSERT(ret == 0, ("dev_pager_getpage: map function returns error"));
 	td->td_fpop = fpop;
 	dev_relthread(dev);
diff --git a/sys/vm/vm.h b/sys/vm/vm.h
index b547514a378..941300a0894 100644
--- a/sys/vm/vm.h
+++ b/sys/vm/vm.h
@@ -63,12 +63,6 @@
 
 #include 
 
-/*
- * The exact set of memory attributes is machine dependent.  However, every
- * machine is required to define VM_MEMATTR_DEFAULT.
- */
-typedef	char vm_memattr_t;	/* memory attribute codes */
-
 typedef char vm_inherit_t;	/* inheritance codes */
 
 #define	VM_INHERIT_SHARE	((vm_inherit_t) 0)
@@ -114,6 +108,12 @@ typedef struct vm_object *vm_object_t;
  */
 typedef int boolean_t;
 
+/*
+ * The exact set of memory attributes is machine dependent.  However, every
+ * machine is required to define VM_MEMATTR_DEFAULT.
+ */
+typedef	char vm_memattr_t;	/* memory attribute codes */
+
 /*
  * This is defined in  for the kernel so that vnode_if.h
  * doesn't have to include .

From 50d356311a28a77c2c30c9928b62484b67461f0c Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 15:13:36 +0000
Subject: [PATCH 0390/2592] MFC 197460: Remove unnecessary locking from
 attach().  This fixes a LOR between the acpi_ibm lock and the sysctl lock.

---
 sys/dev/acpi_support/acpi_ibm.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/sys/dev/acpi_support/acpi_ibm.c b/sys/dev/acpi_support/acpi_ibm.c
index 072c574acac..25db9b0be96 100644
--- a/sys/dev/acpi_support/acpi_ibm.c
+++ b/sys/dev/acpi_support/acpi_ibm.c
@@ -356,8 +356,6 @@ acpi_ibm_attach(device_t dev)
 	}
 	sc->ec_handle = acpi_get_handle(sc->ec_dev);
 
-	ACPI_SERIAL_BEGIN(ibm);
-
 	/* Get the sysctl tree */
 	sc->sysctl_ctx = device_get_sysctl_ctx(dev);
 	sc->sysctl_tree = device_get_sysctl_tree(dev);
@@ -404,8 +402,6 @@ acpi_ibm_attach(device_t dev)
 		    "Thermal zones");
 	}
 
-	ACPI_SERIAL_END(ibm);
-
 	/* Handle notifies */
 	AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY,
 	    acpi_ibm_notify, dev);

From 9e14139d9bae054187d362452ae849d6f96f414f Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 15:17:59 +0000
Subject: [PATCH 0391/2592] MFC 196840: Fill the reverse RSS map with 0xff's so
 that the subsequent loop to calculate the values will work properly.

---
 sys/dev/cxgb/cxgb_main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c
index 21ce96d6ab0..596609b89d9 100644
--- a/sys/dev/cxgb/cxgb_main.c
+++ b/sys/dev/cxgb/cxgb_main.c
@@ -1456,7 +1456,10 @@ setup_rss(adapter_t *adap)
 		rspq_map[i] = nq[0] ? i % nq[0] : 0;
 		rspq_map[i + RSS_TABLE_SIZE / 2] = nq[1] ? i % nq[1] + nq[0] : 0;
 	}
+
 	/* Calculate the reverse RSS map table */
+	for (i = 0; i < SGE_QSETS; ++i)
+		adap->rrss_map[i] = 0xff;
 	for (i = 0; i < RSS_TABLE_SIZE; ++i)
 		if (adap->rrss_map[rspq_map[i]] == 0xff)
 			adap->rrss_map[rspq_map[i]] = i;

From 9ad4b9fbd23f20dfba948ff900e518b43e7f2e70 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 15:24:57 +0000
Subject: [PATCH 0392/2592] MFC 197648: Split the 'video' ACPI lock up into two
 locks to resolve a LOR with the sysctl lock.  The 'video' lock now protects
 the 'bus' of video output devices attached to a graphics adapter.  It is used
 when iterating over the list of outputs, etc.  The 'video_output' lock is
 used to lock the output-specific data similar to a driver lock for the
 individual video outputs.

---
 sys/dev/acpica/acpi_video.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/sys/dev/acpica/acpi_video.c b/sys/dev/acpica/acpi_video.c
index c095a402642..048a45c4d47 100644
--- a/sys/dev/acpica/acpi_video.c
+++ b/sys/dev/acpica/acpi_video.c
@@ -170,7 +170,13 @@ static struct sysctl_oid	*acpi_video_sysctl_tree;
 static struct acpi_video_output_queue crt_units, tv_units,
     ext_units, lcd_units, other_units;
 
+/*
+ * The 'video' lock protects the hierarchy of video output devices
+ * (the video "bus").  The 'video_output' lock protects per-output
+ * data is equivalent to a softc lock for each video output.
+ */
 ACPI_SERIAL_DECL(video, "ACPI video");
+ACPI_SERIAL_DECL(video_output, "ACPI video output");
 MALLOC_DEFINE(M_ACPIVIDEO, "acpivideo", "ACPI video extension");
 
 static int
@@ -236,12 +242,14 @@ acpi_video_attach(device_t dev)
 	acpi_sc = devclass_get_softc(devclass_find("acpi"), 0);
 	if (acpi_sc == NULL)
 		return (ENXIO);
+	ACPI_SERIAL_BEGIN(video);
 	if (acpi_video_sysctl_tree == NULL) {
 		acpi_video_sysctl_tree = SYSCTL_ADD_NODE(&acpi_video_sysctl_ctx,
 				    SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree),
 				    OID_AUTO, "video", CTLFLAG_RD, 0,
 				    "video extension control");
 	}
+	ACPI_SERIAL_END(video);
 
 	sc->device = dev;
 	sc->handle = acpi_get_handle(dev);
@@ -317,6 +325,7 @@ acpi_video_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
 		dss_p = 0;
 		lasthand = NULL;
 		ACPI_SERIAL_BEGIN(video);
+		ACPI_SERIAL_BEGIN(video_output);
 		STAILQ_FOREACH(vo, &sc->vid_outputs, vo_next) {
 			dss = vo_get_graphics_state(vo->handle);
 			dcs = vo_get_device_status(vo->handle);
@@ -332,6 +341,7 @@ acpi_video_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
 		}
 		if (lasthand != NULL)
 			vo_set_device_state(lasthand, dss_p|DSS_COMMIT);
+		ACPI_SERIAL_END(video_output);
 		ACPI_SERIAL_END(video);
 		break;
 	case VID_NOTIFY_REPROBE:
@@ -368,12 +378,14 @@ acpi_video_power_profile(void *context)
 		return;
 
 	ACPI_SERIAL_BEGIN(video);
+	ACPI_SERIAL_BEGIN(video_output);
 	STAILQ_FOREACH(vo, &sc->vid_outputs, vo_next) {
 		if (vo->vo_levels != NULL && vo->vo_brightness == -1)
 			vo_set_brightness(vo->handle,
 			    state == POWER_PROFILE_ECONOMY ?
 			    vo->vo_economy : vo->vo_fullpower);
 	}
+	ACPI_SERIAL_END(video_output);
 	ACPI_SERIAL_END(video);
 }
 
@@ -551,7 +563,7 @@ static void
 acpi_video_vo_bind(struct acpi_video_output *vo, ACPI_HANDLE handle)
 {
 
-	ACPI_SERIAL_ASSERT(video);
+	ACPI_SERIAL_BEGIN(video_output);
 	if (vo->vo_levels != NULL)
 		AcpiOsFree(vo->vo_levels);
 	vo->handle = handle;
@@ -566,6 +578,7 @@ acpi_video_vo_bind(struct acpi_video_output *vo, ACPI_HANDLE handle)
 			/* XXX - see above. */
 			vo->vo_economy = vo->vo_levels[BCL_ECONOMY];
 	}
+	ACPI_SERIAL_END(video_output);
 }
 
 static void
@@ -606,7 +619,7 @@ acpi_video_vo_check_level(struct acpi_video_output *vo, int level)
 {
 	int i;
 
-	ACPI_SERIAL_ASSERT(video);
+	ACPI_SERIAL_ASSERT(video_output);
 	if (vo->vo_levels == NULL)
 		return (ENODEV);
 	for (i = 0; i < vo->vo_numlevels; i++)
@@ -625,7 +638,7 @@ acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS)
 	vo = (struct acpi_video_output *)arg1;
 	if (vo->handle == NULL)
 		return (ENXIO);
-	ACPI_SERIAL_BEGIN(video);
+	ACPI_SERIAL_BEGIN(video_output);
 	state = (vo_get_device_status(vo->handle) & DCS_ACTIVE) ? 1 : 0;
 	err = sysctl_handle_int(oidp, &state, 0, req);
 	if (err != 0 || req->newptr == NULL)
@@ -633,7 +646,7 @@ acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS)
 	vo_set_device_state(vo->handle,
 	    DSS_COMMIT | (state ? DSS_ACTIVE : DSS_INACTIVE));
 out:
-	ACPI_SERIAL_END(video);
+	ACPI_SERIAL_END(video_output);
 	return (err);
 }
 
@@ -645,7 +658,7 @@ acpi_video_vo_bright_sysctl(SYSCTL_HANDLER_ARGS)
 	int level, preset, err;
 
 	vo = (struct acpi_video_output *)arg1;
-	ACPI_SERIAL_BEGIN(video);
+	ACPI_SERIAL_BEGIN(video_output);
 	if (vo->handle == NULL) {
 		err = ENXIO;
 		goto out;
@@ -675,7 +688,7 @@ acpi_video_vo_bright_sysctl(SYSCTL_HANDLER_ARGS)
 	vo_set_brightness(vo->handle, (level == -1) ? preset : level);
 
 out:
-	ACPI_SERIAL_END(video);
+	ACPI_SERIAL_END(video_output);
 	return (err);
 }
 
@@ -687,7 +700,7 @@ acpi_video_vo_presets_sysctl(SYSCTL_HANDLER_ARGS)
 
 	err = 0;
 	vo = (struct acpi_video_output *)arg1;
-	ACPI_SERIAL_BEGIN(video);
+	ACPI_SERIAL_BEGIN(video_output);
 	if (vo->handle == NULL) {
 		err = ENXIO;
 		goto out;
@@ -718,7 +731,7 @@ acpi_video_vo_presets_sysctl(SYSCTL_HANDLER_ARGS)
 	*preset = level;
 
 out:
-	ACPI_SERIAL_END(video);
+	ACPI_SERIAL_END(video_output);
 	return (err);
 }
 
@@ -730,7 +743,7 @@ acpi_video_vo_levels_sysctl(SYSCTL_HANDLER_ARGS)
 	int err;
 
 	vo = (struct acpi_video_output *)arg1;
-	ACPI_SERIAL_BEGIN(video);
+	ACPI_SERIAL_BEGIN(video_output);
 	if (vo->vo_levels == NULL) {
 		err = ENODEV;
 		goto out;
@@ -743,7 +756,7 @@ acpi_video_vo_levels_sysctl(SYSCTL_HANDLER_ARGS)
 	    vo->vo_numlevels * sizeof(*vo->vo_levels), req);
 
 out:
-	ACPI_SERIAL_END(video);
+	ACPI_SERIAL_END(video_output);
 	return (err);
 }
 
@@ -893,6 +906,7 @@ vo_set_brightness(ACPI_HANDLE handle, int level)
 {
 	ACPI_STATUS status;
 
+	ACPI_SERIAL_ASSERT(video_output);
 	status = acpi_SetInteger(handle, "_BCM", level);
 	if (ACPI_FAILURE(status))
 		printf("can't evaluate %s._BCM - %s\n",
@@ -905,6 +919,7 @@ vo_get_device_status(ACPI_HANDLE handle)
 	UINT32 dcs;
 	ACPI_STATUS status;
 
+	ACPI_SERIAL_ASSERT(video_output);
 	dcs = 0;
 	status = acpi_GetInteger(handle, "_DCS", &dcs);
 	if (ACPI_FAILURE(status))
@@ -934,6 +949,7 @@ vo_set_device_state(ACPI_HANDLE handle, UINT32 state)
 {
 	ACPI_STATUS status;
 
+	ACPI_SERIAL_ASSERT(video_output);
 	status = acpi_SetInteger(handle, "_DSS", state);
 	if (ACPI_FAILURE(status))
 		printf("can't evaluate %s._DSS - %s\n",

From 983998573b7dc21ad48b25993ae45e462e19fce4 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 15:28:05 +0000
Subject: [PATCH 0393/2592] MFC 197649: Do not hold the ACPI A/C adapter lock
 when changing the power profile.

---
 sys/dev/acpica/acpi_acad.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sys/dev/acpica/acpi_acad.c b/sys/dev/acpica/acpi_acad.c
index 638c09be635..8153abc4f3b 100644
--- a/sys/dev/acpica/acpi_acad.c
+++ b/sys/dev/acpica/acpi_acad.c
@@ -109,13 +109,14 @@ acpi_acad_get_status(void *context)
     ACPI_SERIAL_BEGIN(acad);
     if (newstatus != -1 && sc->status != newstatus) {
 	sc->status = newstatus;
+	ACPI_SERIAL_END(acad);
 	power_profile_set_state(newstatus ? POWER_PROFILE_PERFORMANCE :
 	    POWER_PROFILE_ECONOMY);
 	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
 	    "%s Line\n", newstatus ? "On" : "Off");
 	acpi_UserNotify("ACAD", h, newstatus);
-    }
-    ACPI_SERIAL_END(acad);
+    } else
+	ACPI_SERIAL_END(acad);
 }
 
 static void

From a74a662b74a467ca6eaa3dc0390190ca28b38c78 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 15:39:18 +0000
Subject: [PATCH 0394/2592] MFC 198085: Add a manual page for BUS_BIND_INTR()
 and bus_bind_intr().

---
 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 86b5838c112..0404a0a6b3d 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 \
@@ -402,6 +403,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 ff5bfa3ef6d8ef4745a0528339010afcd2c4eb9e Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 29 Oct 2009 16:00:27 +0000
Subject: [PATCH 0395/2592] MFC 197439: Extract the code to find and map the
 MADT ACPI table during early kernel startup and genericize it so it can be
 reused to map other tables as well: - Add a routine to walk a list of ACPI
 subtables such as those used in the   APIC and SRAT tables in the MI acpi(4)
 driver. - Move the routines for mapping and unmapping an ACPI table as well
 as   mapping the RSDT or XSDT and searching for a table with a given
 signature   out into acpica_machdep.c for both amd64 and i386.

---
 sys/amd64/acpica/acpi_machdep.c    | 244 +++++++++++++++++++++++++++++
 sys/amd64/acpica/madt.c            | 231 ++-------------------------
 sys/amd64/include/acpica_machdep.h |   3 +
 sys/dev/acpica/acpi.c              |  22 +++
 sys/dev/acpica/acpivar.h           |   5 +
 sys/i386/acpica/acpi_machdep.c     | 240 ++++++++++++++++++++++++++++
 sys/i386/acpica/madt.c             | 230 ++-------------------------
 sys/i386/include/acpica_machdep.h  |   3 +
 8 files changed, 535 insertions(+), 443 deletions(-)

diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c
index b902c12e205..0d866e89832 100644
--- a/sys/amd64/acpica/acpi_machdep.c
+++ b/sys/amd64/acpica/acpi_machdep.c
@@ -32,8 +32,12 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -99,6 +103,246 @@ acpi_cpu_c1()
 	__asm __volatile("sti; hlt");
 }
 
+/*
+ * Support for mapping ACPI tables during early boot.  Currently this
+ * uses the crashdump map to map each table.  However, the crashdump
+ * map is created in pmap_bootstrap() right after the direct map, so
+ * we should be able to just use pmap_mapbios() here instead.
+ *
+ * This makes the following assumptions about how we use this KVA:
+ * pages 0 and 1 are used to map in the header of each table found via
+ * the RSDT or XSDT and pages 2 to n are used to map in the RSDT or
+ * XSDT.  This has to use 2 pages for the table headers in case a
+ * header spans a page boundary.
+ *
+ * XXX: We don't ensure the table fits in the available address space
+ * in the crashdump map.
+ */
+
+/*
+ * Map some memory using the crashdump map.  'offset' is an offset in
+ * pages into the crashdump map to use for the start of the mapping.
+ */
+static void *
+table_map(vm_paddr_t pa, int offset, vm_offset_t length)
+{
+	vm_offset_t va, off;
+	void *data;
+
+	off = pa & PAGE_MASK;
+	length = roundup(length + off, PAGE_SIZE);
+	pa = pa & PG_FRAME;
+	va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
+	    (offset * PAGE_SIZE);
+	data = (void *)(va + off);
+	length -= PAGE_SIZE;
+	while (length > 0) {
+		va += PAGE_SIZE;
+		pa += PAGE_SIZE;
+		length -= PAGE_SIZE;
+		pmap_kenter(va, pa);
+		invlpg(va);
+	}
+	return (data);
+}
+
+/* Unmap memory previously mapped with table_map(). */
+static void
+table_unmap(void *data, vm_offset_t length)
+{
+	vm_offset_t va, off;
+
+	va = (vm_offset_t)data;
+	off = va & PAGE_MASK;
+	length = roundup(length + off, PAGE_SIZE);
+	va &= ~PAGE_MASK;
+	while (length > 0) {
+		pmap_kremove(va);
+		invlpg(va);
+		va += PAGE_SIZE;
+		length -= PAGE_SIZE;
+	}
+}
+
+/*
+ * Map a table at a given offset into the crashdump map.  It first
+ * maps the header to determine the table length and then maps the
+ * entire table.
+ */
+static void *
+map_table(vm_paddr_t pa, int offset, const char *sig)
+{
+	ACPI_TABLE_HEADER *header;
+	vm_offset_t length;
+	void *table;
+
+	header = table_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
+	if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
+		table_unmap(header, sizeof(ACPI_TABLE_HEADER));
+		return (NULL);
+	}
+	length = header->Length;
+	table_unmap(header, sizeof(ACPI_TABLE_HEADER));
+	table = table_map(pa, offset, length);
+	if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
+		if (bootverbose)
+			printf("ACPI: Failed checksum for table %s\n", sig);
+		table_unmap(table, length);
+		return (NULL);
+	}
+	return (table);
+}
+
+/*
+ * See if a given ACPI table is the requested table.  Returns the
+ * length of the able if it matches or zero on failure.
+ */
+static int
+probe_table(vm_paddr_t address, const char *sig)
+{
+	ACPI_TABLE_HEADER *table;
+
+	table = table_map(address, 0, sizeof(ACPI_TABLE_HEADER));
+	if (table == NULL) {
+		if (bootverbose)
+			printf("ACPI: Failed to map table at 0x%jx\n",
+			    (uintmax_t)address);
+		return (0);
+	}
+	if (bootverbose)
+		printf("Table '%.4s' at 0x%jx\n", table->Signature,
+		    (uintmax_t)address);
+
+	if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) {
+		table_unmap(table, sizeof(ACPI_TABLE_HEADER));
+		return (0);
+	}
+	table_unmap(table, sizeof(ACPI_TABLE_HEADER));
+	return (1);
+}
+
+/*
+ * Try to map a table at a given physical address previously returned
+ * by acpi_find_table().
+ */
+void *
+acpi_map_table(vm_paddr_t pa, const char *sig)
+{
+
+	return (map_table(pa, 0, sig));
+}
+
+/* Unmap a table previously mapped via acpi_map_table(). */
+void
+acpi_unmap_table(void *table)
+{
+	ACPI_TABLE_HEADER *header;
+
+	header = (ACPI_TABLE_HEADER *)table;
+	table_unmap(table, header->Length);
+}
+
+/*
+ * Return the physical address of the requested table or zero if one
+ * is not found.
+ */
+vm_paddr_t
+acpi_find_table(const char *sig)
+{
+	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
+	ACPI_TABLE_RSDP *rsdp;
+	ACPI_TABLE_RSDT *rsdt;
+	ACPI_TABLE_XSDT *xsdt;
+	ACPI_TABLE_HEADER *table;
+	vm_paddr_t addr;
+	int i, count;
+
+	if (resource_disabled("acpi", 0))
+		return (0);
+
+	/*
+	 * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
+	 * calls pmap_mapbios() to find the RSDP, we assume that we can use
+	 * pmap_mapbios() to map the RSDP.
+	 */
+	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
+		return (0);
+	rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
+	if (rsdp == NULL) {
+		if (bootverbose)
+			printf("ACPI: Failed to map RSDP\n");
+		return (0);
+	}
+
+	/*
+	 * For ACPI >= 2.0, use the XSDT if it is available.
+	 * Otherwise, use the RSDT.  We map the XSDT or RSDT at page 2
+	 * in the crashdump area.  Pages 0 and 1 are used to map in the
+	 * headers of candidate ACPI tables.
+	 */
+	addr = 0;
+	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
+		/*
+		 * AcpiOsGetRootPointer only verifies the checksum for
+		 * the version 1.0 portion of the RSDP.  Version 2.0 has
+		 * an additional checksum that we verify first.
+		 */
+		if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
+			if (bootverbose)
+				printf("ACPI: RSDP failed extended checksum\n");
+			return (0);
+		}
+		xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
+		if (xsdt == NULL) {
+			if (bootverbose)
+				printf("ACPI: Failed to map XSDT\n");
+			return (0);
+		}
+		count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+		    sizeof(UINT64);
+		for (i = 0; i < count; i++)
+			if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
+				addr = xsdt->TableOffsetEntry[i];
+				break;
+			}
+		acpi_unmap_table(xsdt);
+	} else {
+		rsdt = map_table(rsdp->RsdtPhysicalAddress, 2, ACPI_SIG_RSDT);
+		if (rsdt == NULL) {
+			if (bootverbose)
+				printf("ACPI: Failed to map RSDT\n");
+			return (0);
+		}
+		count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+		    sizeof(UINT32);
+		for (i = 0; i < count; i++)
+			if (probe_table(rsdt->TableOffsetEntry[i], sig)) {
+				addr = rsdt->TableOffsetEntry[i];
+				break;
+			}
+		acpi_unmap_table(rsdt);
+	}
+	pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
+	if (addr == 0) {
+		if (bootverbose)
+			printf("ACPI: No %s table found\n", sig);
+		return (0);
+	}
+	if (bootverbose)
+		printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr);
+
+	/*
+	 * Verify that we can map the full table and that its checksum is
+	 * correct, etc.
+	 */
+	table = map_table(addr, 0, sig);
+	if (table == NULL)
+		return (0);
+	acpi_unmap_table(table);
+
+	return (addr);
+}
+
 /*
  * ACPI nexus(4) driver.
  */
diff --git a/sys/amd64/acpica/madt.c b/sys/amd64/acpica/madt.c
index b27f8e4b26b..a4096820bea 100644
--- a/sys/amd64/acpica/madt.c
+++ b/sys/amd64/acpica/madt.c
@@ -36,27 +36,19 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
-
 #include 
-#include 
 #include 
 
 #include 
-#include 
 #include 
 #include 
-#include 
-#include 
 
 #include 
-#include 
 #include 
 
 #include 
 #include 
 
-typedef	void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg);
-
 /* These two arrays are indexed by APIC IDs. */
 struct ioapic_info {
 	void *io_apic;
@@ -79,8 +71,6 @@ static enum intr_polarity interrupt_polarity(UINT16 IntiFlags, UINT8 Source);
 static enum intr_trigger interrupt_trigger(UINT16 IntiFlags, UINT8 Source);
 static int	madt_find_cpu(u_int acpi_id, u_int *apic_id);
 static int	madt_find_interrupt(int intr, void **apic, u_int *pin);
-static void	*madt_map(vm_paddr_t pa, int offset, vm_offset_t length);
-static void	*madt_map_table(vm_paddr_t pa, int offset, const char *sig);
 static void	madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg);
 static void	madt_parse_interrupt_override(
 		    ACPI_MADT_INTERRUPT_OVERRIDE *intr);
@@ -92,13 +82,10 @@ static int	madt_probe(void);
 static int	madt_probe_cpus(void);
 static void	madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
 		    void *arg __unused);
-static int	madt_probe_table(vm_paddr_t address);
 static void	madt_register(void *dummy);
 static int	madt_setup_local(void);
 static int	madt_setup_io(void);
-static void	madt_unmap(void *data, vm_offset_t length);
-static void	madt_unmap_table(void *table);
-static void	madt_walk_table(madt_entry_handler *handler, void *arg);
+static void	madt_walk_table(acpi_subtable_handler *handler, void *arg);
 
 static struct apic_enumerator madt_enumerator = {
 	"MADT",
@@ -108,214 +95,19 @@ static struct apic_enumerator madt_enumerator = {
 	madt_setup_io
 };
 
-/*
- * Code to abuse the crashdump map to map in the tables for the early
- * probe.  We cheat and make the following assumptions about how we
- * use this KVA: pages 0 and 1 are used to map in the header of each
- * table found via the RSDT or XSDT and pages 2 to n are used to map
- * in the RSDT or XSDT.  We have to use 2 pages for the table headers
- * in case a header spans a page boundary.  The offset is in pages;
- * the length is in bytes.
- */
-static void *
-madt_map(vm_paddr_t pa, int offset, vm_offset_t length)
-{
-	vm_offset_t va, off;
-	void *data;
-
-	off = pa & PAGE_MASK;
-	length = roundup(length + off, PAGE_SIZE);
-	pa = pa & PG_FRAME;
-	va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
-	    (offset * PAGE_SIZE);
-	data = (void *)(va + off);
-	length -= PAGE_SIZE;
-	while (length > 0) {
-		va += PAGE_SIZE;
-		pa += PAGE_SIZE;
-		length -= PAGE_SIZE;
-		pmap_kenter(va, pa);
-		invlpg(va);
-	}
-	return (data);
-}
-
-static void
-madt_unmap(void *data, vm_offset_t length)
-{
-	vm_offset_t va, off;
-
-	va = (vm_offset_t)data;
-	off = va & PAGE_MASK;
-	length = roundup(length + off, PAGE_SIZE);
-	va &= ~PAGE_MASK;
-	while (length > 0) {
-		pmap_kremove(va);
-		invlpg(va);
-		va += PAGE_SIZE;
-		length -= PAGE_SIZE;
-	}
-}
-
-static void *
-madt_map_table(vm_paddr_t pa, int offset, const char *sig)
-{
-	ACPI_TABLE_HEADER *header;
-	vm_offset_t length;
-	void *table;
-
-	header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
-	if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
-		madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
-		return (NULL);
-	}
-	length = header->Length;
-	madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
-	table = madt_map(pa, offset, length);
-	if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
-		if (bootverbose)
-			printf("MADT: Failed checksum for table %s\n", sig);
-		madt_unmap(table, length);
-		return (NULL);
-	}
-	return (table);
-}
-
-static void
-madt_unmap_table(void *table)
-{
-	ACPI_TABLE_HEADER *header;
-
-	header = (ACPI_TABLE_HEADER *)table;
-	madt_unmap(table, header->Length);
-}
-
 /*
  * Look for an ACPI Multiple APIC Description Table ("APIC")
  */
 static int
 madt_probe(void)
 {
-	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
-	ACPI_TABLE_RSDP *rsdp;
-	ACPI_TABLE_RSDT *rsdt;
-	ACPI_TABLE_XSDT *xsdt;
-	int i, count;
 
-	if (resource_disabled("acpi", 0))
+	madt_physaddr = acpi_find_table(ACPI_SIG_MADT);
+	if (madt_physaddr == 0)
 		return (ENXIO);
-
-	/*
-	 * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
-	 * calls pmap_mapbios() to find the RSDP, we assume that we can use
-	 * pmap_mapbios() to map the RSDP.
-	 */
-	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
-		return (ENXIO);
-	rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
-	if (rsdp == NULL) {
-		if (bootverbose)
-			printf("MADT: Failed to map RSDP\n");
-		return (ENXIO);
-	}
-
-	/*
-	 * For ACPI >= 2.0, use the XSDT if it is available.
-	 * Otherwise, use the RSDT.  We map the XSDT or RSDT at page 1
-	 * in the crashdump area.  Page 0 is used to map in the
-	 * headers of candidate ACPI tables.
-	 */
-	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
-		/*
-		 * AcpiOsGetRootPointer only verifies the checksum for
-		 * the version 1.0 portion of the RSDP.  Version 2.0 has
-		 * an additional checksum that we verify first.
-		 */
-		if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
-			if (bootverbose)
-				printf("MADT: RSDP failed extended checksum\n");
-			return (ENXIO);
-		}
-		xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 2,
-		    ACPI_SIG_XSDT);
-		if (xsdt == NULL) {
-			if (bootverbose)
-				printf("MADT: Failed to map XSDT\n");
-			return (ENXIO);
-		}
-		count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
-		    sizeof(UINT64);
-		for (i = 0; i < count; i++)
-			if (madt_probe_table(xsdt->TableOffsetEntry[i]))
-				break;
-		madt_unmap_table(xsdt);
-	} else {
-		rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 2,
-		    ACPI_SIG_RSDT);
-		if (rsdt == NULL) {
-			if (bootverbose)
-				printf("MADT: Failed to map RSDT\n");
-			return (ENXIO);
-		}
-		count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
-		    sizeof(UINT32);
-		for (i = 0; i < count; i++)
-			if (madt_probe_table(rsdt->TableOffsetEntry[i]))
-				break;
-		madt_unmap_table(rsdt);
-	}
-	pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
-	if (madt_physaddr == 0) {
-		if (bootverbose)
-			printf("MADT: No MADT table found\n");
-		return (ENXIO);
-	}
-	if (bootverbose)
-		printf("MADT: Found table at 0x%jx\n",
-		    (uintmax_t)madt_physaddr);
-
-	/*
-	 * Verify that we can map the full table and that its checksum is
-	 * correct, etc.
-	 */
-	madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
-	if (madt == NULL)
-		return (ENXIO);
-	madt_unmap_table(madt);
-	madt = NULL;
-
 	return (0);
 }
 
-/*
- * See if a given ACPI table is the MADT.
- */
-static int
-madt_probe_table(vm_paddr_t address)
-{
-	ACPI_TABLE_HEADER *table;
-
-	table = madt_map(address, 0, sizeof(ACPI_TABLE_HEADER));
-	if (table == NULL) {
-		if (bootverbose)
-			printf("MADT: Failed to map table at 0x%jx\n",
-			    (uintmax_t)address);
-		return (0);
-	}
-	if (bootverbose)
-		printf("Table '%.4s' at 0x%jx\n", table->Signature,
-		    (uintmax_t)address);
-
-	if (strncmp(table->Signature, ACPI_SIG_MADT, ACPI_NAME_SIZE) != 0) {
-		madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
-		return (0);
-	}
-	madt_physaddr = address;
-	madt_length = table->Length;
-	madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
-	return (1);
-}
-
 /*
  * Run through the MP table enumerating CPUs.
  */
@@ -323,10 +115,11 @@ static int
 madt_probe_cpus(void)
 {
 
-	madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
+	madt = acpi_map_table(madt_physaddr, ACPI_SIG_MADT);
+	madt_length = madt->Header.Length;
 	KASSERT(madt != NULL, ("Unable to re-map MADT"));
 	madt_walk_table(madt_probe_cpus_handler, NULL);
-	madt_unmap_table(madt);
+	acpi_unmap_table(madt);
 	madt = NULL;
 	return (0);
 }
@@ -417,17 +210,11 @@ SYSINIT(madt_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST,
  * Call the handler routine for each entry in the MADT table.
  */
 static void
-madt_walk_table(madt_entry_handler *handler, void *arg)
+madt_walk_table(acpi_subtable_handler *handler, void *arg)
 {
-	ACPI_SUBTABLE_HEADER *entry;
-	u_char *p, *end;
 
-	end = (u_char *)(madt) + madt->Header.Length;
-	for (p = (u_char *)(madt + 1); p < end; ) {
-		entry = (ACPI_SUBTABLE_HEADER *)p;
-		handler(entry, arg);
-		p += entry->Length;
-	}
+	acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
+	    handler, arg);
 }
 
 static void
diff --git a/sys/amd64/include/acpica_machdep.h b/sys/amd64/include/acpica_machdep.h
index 76cc69ef568..9943af793f8 100644
--- a/sys/amd64/include/acpica_machdep.h
+++ b/sys/amd64/include/acpica_machdep.h
@@ -77,5 +77,8 @@ extern int	acpi_release_global_lock(uint32_t *lock);
 
 void	acpi_SetDefaultIntrModel(int model);
 void	acpi_cpu_c1(void);
+void	*acpi_map_table(vm_paddr_t pa, const char *sig);
+void	acpi_unmap_table(void *table);
+vm_paddr_t acpi_find_table(const char *sig);
 
 #endif /* __ACPICA_MACHDEP_H__ */
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index a2e58833d25..0ba8f9f6b59 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -2289,6 +2289,28 @@ acpi_SetIntrModel(int model)
     return (acpi_SetInteger(ACPI_ROOT_OBJECT, "_PIC", model));
 }
 
+/*
+ * Walk subtables of a table and call a callback routine for each
+ * subtable.  The caller should provide the first subtable and a
+ * pointer to the end of the table.  This can be used to walk tables
+ * such as MADT and SRAT that use subtable entries.
+ */
+void
+acpi_walk_subtables(void *first, void *end, acpi_subtable_handler *handler,
+    void *arg)
+{
+    ACPI_SUBTABLE_HEADER *entry;
+
+    for (entry = first; (void *)entry < end; ) {
+	/* Avoid an infinite loop if we hit a bogus entry. */
+	if (entry->Length < sizeof(ACPI_SUBTABLE_HEADER))
+	    return;
+
+	handler(entry, arg);
+	entry = ACPI_ADD_PTR(ACPI_SUBTABLE_HEADER, entry, entry->Length);
+    }
+}
+
 /*
  * DEPRECATED.  This interface has serious deficiencies and will be
  * removed.
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index 43f77abf5b1..9141656eb3b 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -307,6 +307,9 @@ void		acpi_EnterDebugger(void);
 	ACPI_DEVINFO_PRESENT(x, ACPI_STA_PRESENT | ACPI_STA_FUNCTIONAL | \
 	    ACPI_STA_BATT_PRESENT)
 
+/* Callback function type for walking subtables within a table. */
+typedef void acpi_subtable_handler(ACPI_SUBTABLE_HEADER *, void *);
+
 BOOLEAN		acpi_DeviceIsPresent(device_t dev);
 BOOLEAN		acpi_BatteryIsPresent(device_t dev);
 ACPI_STATUS	acpi_GetHandleInScope(ACPI_HANDLE parent, char *path,
@@ -340,6 +343,8 @@ void		acpi_UserNotify(const char *subsystem, ACPI_HANDLE h,
 int		acpi_bus_alloc_gas(device_t dev, int *type, int *rid,
 		    ACPI_GENERIC_ADDRESS *gas, struct resource **res,
 		    u_int flags);
+void		acpi_walk_subtables(void *first, void *end,
+		    acpi_subtable_handler *handler, void *arg);
 
 struct acpi_parse_resource_set {
     void	(*set_init)(device_t dev, void *arg, void **context);
diff --git a/sys/i386/acpica/acpi_machdep.c b/sys/i386/acpica/acpi_machdep.c
index e26cce9a729..a1f1a07e03a 100644
--- a/sys/i386/acpica/acpi_machdep.c
+++ b/sys/i386/acpica/acpi_machdep.c
@@ -42,6 +42,8 @@ __FBSDID("$FreeBSD$");
 #include 
 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -554,6 +556,244 @@ acpi_cpu_c1()
 	__asm __volatile("sti; hlt");
 }
 
+/*
+ * Support for mapping ACPI tables during early boot.  This abuses the
+ * crashdump map because the kernel cannot allocate KVA in
+ * pmap_mapbios() when this is used.  This makes the following
+ * assumptions about how we use this KVA: pages 0 and 1 are used to
+ * map in the header of each table found via the RSDT or XSDT and
+ * pages 2 to n are used to map in the RSDT or XSDT.  This has to use
+ * 2 pages for the table headers in case a header spans a page
+ * boundary.
+ *
+ * XXX: We don't ensure the table fits in the available address space
+ * in the crashdump map.
+ */
+
+/*
+ * Map some memory using the crashdump map.  'offset' is an offset in
+ * pages into the crashdump map to use for the start of the mapping.
+ */
+static void *
+table_map(vm_paddr_t pa, int offset, vm_offset_t length)
+{
+	vm_offset_t va, off;
+	void *data;
+
+	off = pa & PAGE_MASK;
+	length = roundup(length + off, PAGE_SIZE);
+	pa = pa & PG_FRAME;
+	va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
+	    (offset * PAGE_SIZE);
+	data = (void *)(va + off);
+	length -= PAGE_SIZE;
+	while (length > 0) {
+		va += PAGE_SIZE;
+		pa += PAGE_SIZE;
+		length -= PAGE_SIZE;
+		pmap_kenter(va, pa);
+		invlpg(va);
+	}
+	return (data);
+}
+
+/* Unmap memory previously mapped with table_map(). */
+static void
+table_unmap(void *data, vm_offset_t length)
+{
+	vm_offset_t va, off;
+
+	va = (vm_offset_t)data;
+	off = va & PAGE_MASK;
+	length = roundup(length + off, PAGE_SIZE);
+	va &= ~PAGE_MASK;
+	while (length > 0) {
+		pmap_kremove(va);
+		invlpg(va);
+		va += PAGE_SIZE;
+		length -= PAGE_SIZE;
+	}
+}
+
+/*
+ * Map a table at a given offset into the crashdump map.  It first
+ * maps the header to determine the table length and then maps the
+ * entire table.
+ */
+static void *
+map_table(vm_paddr_t pa, int offset, const char *sig)
+{
+	ACPI_TABLE_HEADER *header;
+	vm_offset_t length;
+	void *table;
+
+	header = table_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
+	if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
+		table_unmap(header, sizeof(ACPI_TABLE_HEADER));
+		return (NULL);
+	}
+	length = header->Length;
+	table_unmap(header, sizeof(ACPI_TABLE_HEADER));
+	table = table_map(pa, offset, length);
+	if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
+		if (bootverbose)
+			printf("ACPI: Failed checksum for table %s\n", sig);
+		table_unmap(table, length);
+		return (NULL);
+	}
+	return (table);
+}
+
+/*
+ * See if a given ACPI table is the requested table.  Returns the
+ * length of the able if it matches or zero on failure.
+ */
+static int
+probe_table(vm_paddr_t address, const char *sig)
+{
+	ACPI_TABLE_HEADER *table;
+
+	table = table_map(address, 0, sizeof(ACPI_TABLE_HEADER));
+	if (table == NULL) {
+		if (bootverbose)
+			printf("ACPI: Failed to map table at 0x%jx\n",
+			    (uintmax_t)address);
+		return (0);
+	}
+	if (bootverbose)
+		printf("Table '%.4s' at 0x%jx\n", table->Signature,
+		    (uintmax_t)address);
+
+	if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) {
+		table_unmap(table, sizeof(ACPI_TABLE_HEADER));
+		return (0);
+	}
+	table_unmap(table, sizeof(ACPI_TABLE_HEADER));
+	return (1);
+}
+
+/*
+ * Try to map a table at a given physical address previously returned
+ * by acpi_find_table().
+ */
+void *
+acpi_map_table(vm_paddr_t pa, const char *sig)
+{
+
+	return (map_table(pa, 0, sig));
+}
+
+/* Unmap a table previously mapped via acpi_map_table(). */
+void
+acpi_unmap_table(void *table)
+{
+	ACPI_TABLE_HEADER *header;
+
+	header = (ACPI_TABLE_HEADER *)table;
+	table_unmap(table, header->Length);
+}
+
+/*
+ * Return the physical address of the requested table or zero if one
+ * is not found.
+ */
+vm_paddr_t
+acpi_find_table(const char *sig)
+{
+	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
+	ACPI_TABLE_RSDP *rsdp;
+	ACPI_TABLE_RSDT *rsdt;
+	ACPI_TABLE_XSDT *xsdt;
+	ACPI_TABLE_HEADER *table;
+	vm_paddr_t addr;
+	int i, count;
+
+	if (resource_disabled("acpi", 0))
+		return (0);
+
+	/*
+	 * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
+	 * calls pmap_mapbios() to find the RSDP, we assume that we can use
+	 * pmap_mapbios() to map the RSDP.
+	 */
+	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
+		return (0);
+	rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
+	if (rsdp == NULL) {
+		if (bootverbose)
+			printf("ACPI: Failed to map RSDP\n");
+		return (0);
+	}
+
+	/*
+	 * For ACPI >= 2.0, use the XSDT if it is available.
+	 * Otherwise, use the RSDT.  We map the XSDT or RSDT at page 2
+	 * in the crashdump area.  Pages 0 and 1 are used to map in the
+	 * headers of candidate ACPI tables.
+	 */
+	addr = 0;
+	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
+		/*
+		 * AcpiOsGetRootPointer only verifies the checksum for
+		 * the version 1.0 portion of the RSDP.  Version 2.0 has
+		 * an additional checksum that we verify first.
+		 */
+		if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
+			if (bootverbose)
+				printf("ACPI: RSDP failed extended checksum\n");
+			return (0);
+		}
+		xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
+		if (xsdt == NULL) {
+			if (bootverbose)
+				printf("ACPI: Failed to map XSDT\n");
+			return (0);
+		}
+		count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+		    sizeof(UINT64);
+		for (i = 0; i < count; i++)
+			if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
+				addr = xsdt->TableOffsetEntry[i];
+				break;
+			}
+		acpi_unmap_table(xsdt);
+	} else {
+		rsdt = map_table(rsdp->RsdtPhysicalAddress, 2, ACPI_SIG_RSDT);
+		if (rsdt == NULL) {
+			if (bootverbose)
+				printf("ACPI: Failed to map RSDT\n");
+			return (0);
+		}
+		count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+		    sizeof(UINT32);
+		for (i = 0; i < count; i++)
+			if (probe_table(rsdt->TableOffsetEntry[i], sig)) {
+				addr = rsdt->TableOffsetEntry[i];
+				break;
+			}
+		acpi_unmap_table(rsdt);
+	}
+	pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
+	if (addr == 0) {
+		if (bootverbose)
+			printf("ACPI: No %s table found\n", sig);
+		return (0);
+	}
+	if (bootverbose)
+		printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr);
+
+	/*
+	 * Verify that we can map the full table and that its checksum is
+	 * correct, etc.
+	 */
+	table = map_table(addr, 0, sig);
+	if (table == NULL)
+		return (0);
+	acpi_unmap_table(table);
+
+	return (addr);
+}
+
 /*
  * ACPI nexus(4) driver.
  */
diff --git a/sys/i386/acpica/madt.c b/sys/i386/acpica/madt.c
index f9756ec0a77..114fbc78a3e 100644
--- a/sys/i386/acpica/madt.c
+++ b/sys/i386/acpica/madt.c
@@ -36,27 +36,19 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
-
 #include 
-#include 
 #include 
 
 #include 
-#include 
 #include 
 #include 
-#include 
-#include 
 
 #include 
-#include 
 #include 
 
 #include 
 #include 
 
-typedef	void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg);
-
 /* These two arrays are indexed by APIC IDs. */
 struct ioapic_info {
 	void *io_apic;
@@ -79,8 +71,6 @@ static enum intr_polarity interrupt_polarity(UINT16 IntiFlags, UINT8 Source);
 static enum intr_trigger interrupt_trigger(UINT16 IntiFlags, UINT8 Source);
 static int	madt_find_cpu(u_int acpi_id, u_int *apic_id);
 static int	madt_find_interrupt(int intr, void **apic, u_int *pin);
-static void	*madt_map(vm_paddr_t pa, int offset, vm_offset_t length);
-static void	*madt_map_table(vm_paddr_t pa, int offset, const char *sig);
 static void	madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg);
 static void	madt_parse_interrupt_override(
 		    ACPI_MADT_INTERRUPT_OVERRIDE *intr);
@@ -92,13 +82,10 @@ static int	madt_probe(void);
 static int	madt_probe_cpus(void);
 static void	madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
 		    void *arg __unused);
-static int	madt_probe_table(vm_paddr_t address);
 static void	madt_register(void *dummy);
 static int	madt_setup_local(void);
 static int	madt_setup_io(void);
-static void	madt_unmap(void *data, vm_offset_t length);
-static void	madt_unmap_table(void *table);
-static void	madt_walk_table(madt_entry_handler *handler, void *arg);
+static void	madt_walk_table(acpi_subtable_handler *handler, void *arg);
 
 static struct apic_enumerator madt_enumerator = {
 	"MADT",
@@ -108,87 +95,6 @@ static struct apic_enumerator madt_enumerator = {
 	madt_setup_io
 };
 
-/*
- * Code to abuse the crashdump map to map in the tables for the early
- * probe.  We cheat and make the following assumptions about how we
- * use this KVA: pages 0 and 1 are used to map in the header of each
- * table found via the RSDT or XSDT and pages 2 to n are used to map
- * in the RSDT or XSDT.  We have to use 2 pages for the table headers
- * in case a header spans a page boundary.  The offset is in pages;
- * the length is in bytes.
- */
-static void *
-madt_map(vm_paddr_t pa, int offset, vm_offset_t length)
-{
-	vm_offset_t va, off;
-	void *data;
-
-	off = pa & PAGE_MASK;
-	length = roundup(length + off, PAGE_SIZE);
-	pa = pa & PG_FRAME;
-	va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
-	    (offset * PAGE_SIZE);
-	data = (void *)(va + off);
-	length -= PAGE_SIZE;
-	while (length > 0) {
-		va += PAGE_SIZE;
-		pa += PAGE_SIZE;
-		length -= PAGE_SIZE;
-		pmap_kenter(va, pa);
-		invlpg(va);
-	}
-	return (data);
-}
-
-static void
-madt_unmap(void *data, vm_offset_t length)
-{
-	vm_offset_t va, off;
-
-	va = (vm_offset_t)data;
-	off = va & PAGE_MASK;
-	length = roundup(length + off, PAGE_SIZE);
-	va &= ~PAGE_MASK;
-	while (length > 0) {
-		pmap_kremove(va);
-		invlpg(va);
-		va += PAGE_SIZE;
-		length -= PAGE_SIZE;
-	}
-}
-
-static void *
-madt_map_table(vm_paddr_t pa, int offset, const char *sig)
-{
-	ACPI_TABLE_HEADER *header;
-	vm_offset_t length;
-	void *table;
-
-	header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
-	if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
-		madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
-		return (NULL);
-	}
-	length = header->Length;
-	madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
-	table = madt_map(pa, offset, length);
-	if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
-		if (bootverbose)
-			printf("MADT: Failed checksum for table %s\n", sig);
-		madt_unmap(table, length);
-		return (NULL);
-	}
-	return (table);
-}
-
-static void
-madt_unmap_table(void *table)
-{
-	ACPI_TABLE_HEADER *header;
-
-	header = (ACPI_TABLE_HEADER *)table;
-	madt_unmap(table, header->Length);
-}
 
 /*
  * Look for an ACPI Multiple APIC Description Table ("APIC")
@@ -196,126 +102,13 @@ madt_unmap_table(void *table)
 static int
 madt_probe(void)
 {
-	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
-	ACPI_TABLE_RSDP *rsdp;
-	ACPI_TABLE_RSDT *rsdt;
-	ACPI_TABLE_XSDT *xsdt;
-	int i, count;
 
-	if (resource_disabled("acpi", 0))
+	madt_physaddr = acpi_find_table(ACPI_SIG_MADT);
+	if (madt_physaddr == 0)
 		return (ENXIO);
-
-	/*
-	 * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
-	 * calls pmap_mapbios() to find the RSDP, we assume that we can use
-	 * pmap_mapbios() to map the RSDP.
-	 */
-	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
-		return (ENXIO);
-	rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
-	if (rsdp == NULL) {
-		if (bootverbose)
-			printf("MADT: Failed to map RSDP\n");
-		return (ENXIO);
-	}
-
-	/*
-	 * For ACPI >= 2.0, use the XSDT if it is available.
-	 * Otherwise, use the RSDT.  We map the XSDT or RSDT at page 1
-	 * in the crashdump area.  Page 0 is used to map in the
-	 * headers of candidate ACPI tables.
-	 */
-	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
-		/*
-		 * AcpiOsGetRootPointer only verifies the checksum for
-		 * the version 1.0 portion of the RSDP.  Version 2.0 has
-		 * an additional checksum that we verify first.
-		 */
-		if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
-			if (bootverbose)
-				printf("MADT: RSDP failed extended checksum\n");
-			return (ENXIO);
-		}
-		xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 2,
-		    ACPI_SIG_XSDT);
-		if (xsdt == NULL) {
-			if (bootverbose)
-				printf("MADT: Failed to map XSDT\n");
-			return (ENXIO);
-		}
-		count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
-		    sizeof(UINT64);
-		for (i = 0; i < count; i++)
-			if (madt_probe_table(xsdt->TableOffsetEntry[i]))
-				break;
-		madt_unmap_table(xsdt);
-	} else {
-		rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 2,
-		    ACPI_SIG_RSDT);
-		if (rsdt == NULL) {
-			if (bootverbose)
-				printf("MADT: Failed to map RSDT\n");
-			return (ENXIO);
-		}
-		count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
-		    sizeof(UINT32);
-		for (i = 0; i < count; i++)
-			if (madt_probe_table(rsdt->TableOffsetEntry[i]))
-				break;
-		madt_unmap_table(rsdt);
-	}
-	pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
-	if (madt_physaddr == 0) {
-		if (bootverbose)
-			printf("MADT: No MADT table found\n");
-		return (ENXIO);
-	}
-	if (bootverbose)
-		printf("MADT: Found table at 0x%jx\n",
-		    (uintmax_t)madt_physaddr);
-
-	/*
-	 * Verify that we can map the full table and that its checksum is
-	 * correct, etc.
-	 */
-	madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
-	if (madt == NULL)
-		return (ENXIO);
-	madt_unmap_table(madt);
-	madt = NULL;
-
 	return (0);
 }
 
-/*
- * See if a given ACPI table is the MADT.
- */
-static int
-madt_probe_table(vm_paddr_t address)
-{
-	ACPI_TABLE_HEADER *table;
-
-	table = madt_map(address, 0, sizeof(ACPI_TABLE_HEADER));
-	if (table == NULL) {
-		if (bootverbose)
-			printf("MADT: Failed to map table at 0x%jx\n",
-			    (uintmax_t)address);
-		return (0);
-	}
-	if (bootverbose)
-		printf("Table '%.4s' at 0x%jx\n", table->Signature,
-		    (uintmax_t)address);
-
-	if (strncmp(table->Signature, ACPI_SIG_MADT, ACPI_NAME_SIZE) != 0) {
-		madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
-		return (0);
-	}
-	madt_physaddr = address;
-	madt_length = table->Length;
-	madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
-	return (1);
-}
-
 /*
  * Run through the MP table enumerating CPUs.
  */
@@ -323,10 +116,11 @@ static int
 madt_probe_cpus(void)
 {
 
-	madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
+	madt = acpi_map_table(madt_physaddr, ACPI_SIG_MADT);
+	madt_length = madt->Header.Length;
 	KASSERT(madt != NULL, ("Unable to re-map MADT"));
 	madt_walk_table(madt_probe_cpus_handler, NULL);
-	madt_unmap_table(madt);
+	acpi_unmap_table(madt);
 	madt = NULL;
 	return (0);
 }
@@ -416,17 +210,11 @@ SYSINIT(madt_register, SI_SUB_CPU - 1, SI_ORDER_SECOND, madt_register, NULL);
  * Call the handler routine for each entry in the MADT table.
  */
 static void
-madt_walk_table(madt_entry_handler *handler, void *arg)
+madt_walk_table(acpi_subtable_handler *handler, void *arg)
 {
-	ACPI_SUBTABLE_HEADER *entry;
-	u_char *p, *end;
 
-	end = (u_char *)(madt) + madt->Header.Length;
-	for (p = (u_char *)(madt + 1); p < end; ) {
-		entry = (ACPI_SUBTABLE_HEADER *)p;
-		handler(entry, arg);
-		p += entry->Length;
-	}
+	acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
+	    handler, arg);
 }
 
 static void
diff --git a/sys/i386/include/acpica_machdep.h b/sys/i386/include/acpica_machdep.h
index f90b213eb54..d5bfe65e48f 100644
--- a/sys/i386/include/acpica_machdep.h
+++ b/sys/i386/include/acpica_machdep.h
@@ -97,5 +97,8 @@ extern int	acpi_release_global_lock(uint32_t *lock);
 
 void	acpi_SetDefaultIntrModel(int model);
 void	acpi_cpu_c1(void);
+void	*acpi_map_table(vm_paddr_t pa, const char *sig);
+void	acpi_unmap_table(void *table);
+vm_paddr_t acpi_find_table(const char *sig);
 
 #endif /* __ACPICA_MACHDEP_H__ */

From ce8e32de5ccdbe10861b83c22489c6de573a8ca7 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 29 Oct 2009 16:19:58 +0000
Subject: [PATCH 0396/2592] MFC r197428: Add per-process osrel node to the
 procfs, to allow read and set p_osrel value for the process.

---
 sys/conf/files               |  1 +
 sys/fs/procfs/procfs.c       |  5 ++-
 sys/fs/procfs/procfs.h       |  1 +
 sys/fs/procfs/procfs_osrel.c | 68 ++++++++++++++++++++++++++++++++++++
 sys/modules/procfs/Makefile  |  1 +
 5 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 sys/fs/procfs/procfs_osrel.c

diff --git a/sys/conf/files b/sys/conf/files
index 0a77c0eb905..68d3ea1ba93 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1787,6 +1787,7 @@ fs/procfs/procfs_ioctl.c	optional procfs
 fs/procfs/procfs_map.c		optional procfs
 fs/procfs/procfs_mem.c		optional procfs
 fs/procfs/procfs_note.c		optional procfs
+fs/procfs/procfs_osrel.c	optional procfs
 fs/procfs/procfs_regs.c		optional procfs
 fs/procfs/procfs_rlimit.c	optional procfs
 fs/procfs/procfs_status.c	optional procfs
diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c
index 77d1dc62ca4..8b69eb1a0b3 100644
--- a/sys/fs/procfs/procfs.c
+++ b/sys/fs/procfs/procfs.c
@@ -108,7 +108,8 @@ procfs_attr(PFS_ATTR_ARGS)
 	else if (strcmp(pn->pn_name, "mem") == 0 ||
 	    strcmp(pn->pn_name, "regs") == 0 ||
 	    strcmp(pn->pn_name, "dbregs") == 0 ||
-	    strcmp(pn->pn_name, "fpregs") == 0)
+	    strcmp(pn->pn_name, "fpregs") == 0 ||
+	    strcmp(pn->pn_name, "osrel") == 0)
 		vap->va_mode = 0600;
 
 	if (p != NULL) {
@@ -186,6 +187,8 @@ procfs_init(PFS_INIT_ARGS)
 	    NULL, NULL, NULL, PFS_RD);
 	pfs_create_file(dir, "status", procfs_doprocstatus,
 	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(dir, "osrel", procfs_doosrel,
+	    procfs_attr, procfs_candebug, NULL, PFS_RDWR);
 
 	pfs_create_link(dir, "file", procfs_doprocfile,
 	    NULL, procfs_notsystem, NULL, 0);
diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h
index 48d4bca84b4..259822451b0 100644
--- a/sys/fs/procfs/procfs.h
+++ b/sys/fs/procfs/procfs.h
@@ -39,6 +39,7 @@
 #ifdef _KERNEL
 
 int	 procfs_docurproc(PFS_FILL_ARGS);
+int	 procfs_doosrel(PFS_FILL_ARGS);
 int	 procfs_doproccmdline(PFS_FILL_ARGS);
 int	 procfs_doprocctl(PFS_FILL_ARGS);
 int	 procfs_doprocdbregs(PFS_FILL_ARGS);
diff --git a/sys/fs/procfs/procfs_osrel.c b/sys/fs/procfs/procfs_osrel.c
new file mode 100644
index 00000000000..d32bd6d537d
--- /dev/null
+++ b/sys/fs/procfs/procfs_osrel.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2009 Konstantin Belousov
+ * 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 
+
+int
+procfs_doosrel(PFS_FILL_ARGS)
+{
+	const char *pp;
+	int ov, osrel, i;
+
+	if (uio == NULL)
+		return (EOPNOTSUPP);
+	if (uio->uio_rw == UIO_READ) {
+		sbuf_printf(sb, "%d\n", p->p_osrel);
+	} else {
+		sbuf_trim(sb);
+		sbuf_finish(sb);
+		pp = sbuf_data(sb);
+		osrel = 0;
+		i = sbuf_len(sb);
+		while (i--) {
+			if (*pp < '0' || *pp > '9')
+				return (EINVAL);
+			ov = osrel * 10 + *pp++ - '0';
+			if (ov < osrel)
+				return (EINVAL);
+			osrel = ov;
+		}
+		p->p_osrel = osrel;
+	}
+	return (0);
+}
diff --git a/sys/modules/procfs/Makefile b/sys/modules/procfs/Makefile
index 6c840edcfc0..c3b36337f02 100644
--- a/sys/modules/procfs/Makefile
+++ b/sys/modules/procfs/Makefile
@@ -13,6 +13,7 @@ SRCS+=		procfs_ioctl.c
 SRCS+=		procfs_map.c
 SRCS+=		procfs_mem.c
 SRCS+=		procfs_note.c
+SRCS+=		procfs_osrel.c
 SRCS+=		procfs_regs.c
 SRCS+=		procfs_rlimit.c
 SRCS+=		procfs_status.c

From a2ad88175b9238fccb5096f37de4052c2f2dadf8 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 29 Oct 2009 16:21:52 +0000
Subject: [PATCH 0397/2592] MFC r197429: Document osrel node for procfs.

---
 share/man/man5/procfs.5 | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/share/man/man5/procfs.5 b/share/man/man5/procfs.5
index d28f4184c6c..17072732938 100644
--- a/share/man/man5/procfs.5
+++ b/share/man/man5/procfs.5
@@ -2,7 +2,7 @@
 .\" Written by Garrett Wollman
 .\" This file is in the public domain.
 .\"
-.Dd July 9, 2009
+.Dd September 22, 2009
 .Dt PROCFS 5
 .Os
 .Sh NAME
@@ -117,6 +117,12 @@ Not implemented.
 .It Pa notepg
 Used for sending signal to the process group.
 Not implemented.
+.It Pa osrel
+Allows read and write of the kernel osrel value assigned to the process.
+It affects the compatibility shims that are turned on and off
+depending on the value.
+Initial process value is read from the ABI note tag in the executed ELF image,
+and is zero if the tag not supported by binary format or was not found.
 .It Pa regs
 Allows read and write access to the process' register set.
 This file contains a binary data structure
@@ -237,6 +243,8 @@ the complete virtual address space of the process
 used for signaling the process
 .It Pa /proc/curproc/notepg
 used for signaling the process group
+.It Pa /proc/curproc/osrel
+the process osrel value
 .It Pa /proc/curproc/regs
 the process register set
 .It Pa /proc/curproc/rlimit

From c2204c03c87c3626beebb1e17df22a17945ed3fc Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 29 Oct 2009 16:24:39 +0000
Subject: [PATCH 0398/2592] MFC r197389: Do panic regardeless of execution mode
 at the moment of T_RESERVED trap.

---
 sys/amd64/amd64/trap.c | 5 +++++
 sys/i386/i386/trap.c   | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 65f761eaa4a..cfccf3c3ca6 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -253,6 +253,11 @@ trap(struct trapframe *frame)
 	}
 #endif
 
+	if (type == T_RESERVED) {
+		trap_fatal(frame, 0);
+		goto out;
+	}
+
 #ifdef	HWPMC_HOOKS
 	/*
 	 * CPU PMCs interrupt using an NMI.  If the PMC module is
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index f7064f04a53..f4df6687021 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -225,6 +225,11 @@ trap(struct trapframe *frame)
 	}
 #endif
 
+	if (type == T_RESERVED) {
+		trap_fatal(frame, 0);
+		goto out;
+	}
+
 #ifdef	HWPMC_HOOKS
 	/*
 	 * CPU PMCs interrupt using an NMI so we check for that first.

From 5984920662e47d1e5d8b01a78ce1f5728086d3ee Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 29 Oct 2009 16:28:21 +0000
Subject: [PATCH 0399/2592] MFC r197930: Postpone dropping fp till both
 kq_global and kqueue mutexes are unlocked.

---
 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 6603d110c23..e0dd56dfdda 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -909,13 +909,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 51b79b08b8c095936fd590db9390d62ebe769243 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Thu, 29 Oct 2009 16:30:48 +0000
Subject: [PATCH 0400/2592] MFC: r198314

Add empty watchdogd_flags.
---
 etc/defaults/rc.conf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index d64a647a49c..d67ace8c477 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -597,6 +597,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 defb74dce5186403cd58e9817262a5ae537c413c Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Thu, 29 Oct 2009 21:13:57 +0000
Subject: [PATCH 0401/2592] MFC r197371: Mention that NUL characters are not
 allowed in sh(1) input.

I do not consider this a bug because POSIX permits it and argument strings
and environment variables cannot contain '\0' anyway.

PR:		bin/25542
---
 bin/sh/sh.1 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 461c3ca4d97..2739dccdd8e 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -375,6 +375,10 @@ introduces a comment if used at the beginning of a word.
 The word starting with
 .Ql #
 and the rest of the line are ignored.
+.Pp
+.Tn ASCII
+.Dv NUL
+characters (character code 0) are not allowed in shell input.
 .Ss Quoting
 Quoting is used to remove the special meaning of certain characters
 or words to the shell, such as operators, whitespace, keywords,

From 5ad306115b5ec93346bdae5d46a524414306143e Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Thu, 29 Oct 2009 21:25:16 +0000
Subject: [PATCH 0402/2592] MFC r197363: Update find(1) man page for -L/-delete
 interaction.

It is a bit unfortunate that the example to delete broken symlinks now uses
rm(1), but allowing this with -delete would require fixing fts(3) to not
imply FTS_NOCHDIR if FTS_LOGICAL is given (or hacks in the -delete option).

PR:		bin/90687
---
 usr.bin/find/find.1 | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index 824b917a2a5..dee5e046175 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -312,6 +312,7 @@ character in its pathname relative to
 .Dq Pa \&.
 for security reasons.
 Depth-first traversal processing is implied by this option.
+Following symlinks is incompatible with this option.
 .It Ic -depth
 Always true;
 same as the
@@ -920,7 +921,7 @@ recent than the current time minus one minute.
 Use the
 .Xr echo 1
 command to print out a list of all the files.
-.It Li "find -L /usr/ports/packages -type l -delete"
+.It Li "find -L /usr/ports/packages -type l -exec rm -- {} +"
 Delete all broken symbolic links in
 .Pa /usr/ports/packages .
 .It Li "find /usr/src -name CVS -prune -o -depth +6 -print"

From 61908699b5da2c8e05b4d62203f8457986e911de Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:09:02 +0000
Subject: [PATCH 0403/2592] MFC r196488

 - allow disabling "root_mount_hold()" by setting a sysctl/tunable at boot
 - remove some redundant initial explore code
---
 sys/dev/usb/controller/usb_controller.c | 104 +++++++-----------------
 1 file changed, 30 insertions(+), 74 deletions(-)

diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c
index 7a019dcaa7a..a9254443590 100644
--- a/sys/dev/usb/controller/usb_controller.c
+++ b/sys/dev/usb/controller/usb_controller.c
@@ -67,7 +67,6 @@ static device_attach_t usb_attach;
 static device_detach_t usb_detach;
 
 static void	usb_attach_sub(device_t, struct usb_bus *);
-static void	usb_post_init(void *);
 
 /* static variables */
 
@@ -84,8 +83,6 @@ TUNABLE_INT("hw.usb.no_boot_wait", &usb_no_boot_wait);
 SYSCTL_INT(_hw_usb, OID_AUTO, no_boot_wait, CTLFLAG_RDTUN, &usb_no_boot_wait, 0,
     "No device enumerate waiting at boot.");
 
-static uint8_t usb_post_init_called = 0;
-
 static devclass_t usb_devclass;
 
 static device_method_t usb_methods[] = {
@@ -142,12 +139,8 @@ usb_attach(device_t dev)
 		bus->bus_roothold = root_mount_hold(device_get_nameunit(dev));
 	}
 
-	if (usb_post_init_called) {
-		mtx_lock(&Giant);
-		usb_attach_sub(dev, bus);
-		mtx_unlock(&Giant);
-		usb_needs_explore(bus, 1);
-	}
+	usb_attach_sub(dev, bus);
+
 	return (0);			/* return success */
 }
 
@@ -226,22 +219,24 @@ usb_bus_explore(struct usb_proc_msg *pm)
 			/* avoid zero, hence that is memory default */
 			bus->driver_added_refcount = 1;
 		}
-		USB_BUS_UNLOCK(bus);
 
-		mtx_lock(&Giant);
+		/*
+		 * The following three lines of code are only here to
+		 * recover from DDB:
+		 */
+		usb_proc_rewakeup(&bus->control_xfer_proc);
+		usb_proc_rewakeup(&bus->giant_callback_proc);
+		usb_proc_rewakeup(&bus->non_giant_callback_proc);
+
+		USB_BUS_UNLOCK(bus);
 
 		/*
 		 * First update the USB power state!
 		 */
 		usb_bus_powerd(bus);
-		/*
-		 * Explore the Root USB HUB. This call can sleep,
-		 * exiting Giant, which is actually Giant.
-		 */
+
+		 /* Explore the Root USB HUB. */
 		(udev->hub->explore) (udev);
-
-		mtx_unlock(&Giant);
-
 		USB_BUS_LOCK(bus);
 	}
 	if (bus->bus_roothold != NULL) {
@@ -269,10 +264,10 @@ usb_bus_detach(struct usb_proc_msg *pm)
 	device_set_softc(dev, NULL);
 	USB_BUS_UNLOCK(bus);
 
-	mtx_lock(&Giant);
-
 	/* detach children first */
+	mtx_lock(&Giant);
 	bus_generic_detach(dev);
+	mtx_unlock(&Giant);
 
 	/*
 	 * Free USB Root device, but not any sub-devices, hence they
@@ -281,7 +276,6 @@ usb_bus_detach(struct usb_proc_msg *pm)
 	usb_free_device(udev,
 	    USB_UNCFG_FLAG_FREE_EP0);
 
-	mtx_unlock(&Giant);
 	USB_BUS_LOCK(bus);
 	/* clear bdev variable last */
 	bus->bdev = NULL;
@@ -297,6 +291,12 @@ usb_power_wdog(void *arg)
 	usb_callout_reset(&bus->power_wdog,
 	    4 * hz, usb_power_wdog, arg);
 
+	/*
+	 * The following line of code is only here to recover from
+	 * DDB:
+	 */
+	usb_proc_rewakeup(&bus->explore_proc);	/* recover from DDB */
+
 	USB_BUS_UNLOCK(bus);
 
 	usb_bus_power_update(bus);
@@ -350,7 +350,6 @@ usb_bus_attach(struct usb_proc_msg *pm)
 	}
 
 	USB_BUS_UNLOCK(bus);
-	mtx_lock(&Giant);		/* XXX not required by USB */
 
 	/* default power_mask value */
 	bus->hw_power_state =
@@ -383,7 +382,6 @@ usb_bus_attach(struct usb_proc_msg *pm)
 		err = USB_ERR_NOMEM;
 	}
 
-	mtx_unlock(&Giant);
 	USB_BUS_LOCK(bus);
 
 	if (err) {
@@ -401,17 +399,18 @@ usb_bus_attach(struct usb_proc_msg *pm)
 /*------------------------------------------------------------------------*
  *	usb_attach_sub
  *
- * This function creates a thread which runs the USB attach code. It
- * is factored out, hence it can be called at two different places in
- * time. During bootup this function is called from
- * "usb_post_init". During hot-plug it is called directly from the
- * "usb_attach()" method.
+ * This function creates a thread which runs the USB attach code.
  *------------------------------------------------------------------------*/
 static void
 usb_attach_sub(device_t dev, struct usb_bus *bus)
 {
 	const char *pname = device_get_nameunit(dev);
 
+	mtx_lock(&Giant);
+	if (usb_devclass_ptr == NULL)
+		usb_devclass_ptr = devclass_find("usbus");
+	mtx_unlock(&Giant);
+
 	/* Initialise USB process messages */
 	bus->explore_msg[0].hdr.pm_callback = &usb_bus_explore;
 	bus->explore_msg[0].bus = bus;
@@ -454,55 +453,12 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
 			/* ignore */
 		}
 		USB_BUS_UNLOCK(bus);
+
+		/* Do initial explore */
+		usb_needs_explore(bus, 1);
 	}
 }
 
-/*------------------------------------------------------------------------*
- *	usb_post_init
- *
- * This function is called to attach all USB busses that were found
- * during bootup.
- *------------------------------------------------------------------------*/
-static void
-usb_post_init(void *arg)
-{
-	struct usb_bus *bus;
-	devclass_t dc;
-	device_t dev;
-	int max;
-	int n;
-
-	mtx_lock(&Giant);
-
-	usb_devclass_ptr = devclass_find("usbus");
-
-	dc = usb_devclass_ptr;
-	if (dc) {
-		max = devclass_get_maxunit(dc) + 1;
-		for (n = 0; n != max; n++) {
-			dev = devclass_get_device(dc, n);
-			if (dev && device_is_attached(dev)) {
-				bus = device_get_ivars(dev);
-				if (bus) {
-					mtx_lock(&Giant);
-					usb_attach_sub(dev, bus);
-					mtx_unlock(&Giant);
-				}
-			}
-		}
-	} else {
-		DPRINTFN(0, "no devclass\n");
-	}
-	usb_post_init_called = 1;
-
-	/* explore all USB busses in parallell */
-
-	usb_needs_explore_all();
-
-	mtx_unlock(&Giant);
-}
-
-SYSINIT(usb_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb_post_init, NULL);
 SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL);
 
 /*------------------------------------------------------------------------*

From 9fd6caea707788cd68a0aa8c545eb45ebf150ec3 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:09:37 +0000
Subject: [PATCH 0404/2592] MFC r196490

 - FIFO's are always opened separately in read and write direction even if the
   actual device is opened for read and write. Fix fflags check so that the UFM
   and URIO drivers work.
---
 sys/dev/usb/misc/ufm.c     | 15 ++++-----------
 sys/dev/usb/storage/urio.c |  3 ---
 2 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/sys/dev/usb/misc/ufm.c b/sys/dev/usb/misc/ufm.c
index c10166a5bf0..136182a1c3e 100644
--- a/sys/dev/usb/misc/ufm.c
+++ b/sys/dev/usb/misc/ufm.c
@@ -86,11 +86,9 @@ static device_attach_t ufm_attach;
 static device_detach_t ufm_detach;
 
 static usb_fifo_ioctl_t ufm_ioctl;
-static usb_fifo_open_t ufm_open;
 
 static struct usb_fifo_methods ufm_fifo_methods = {
 	.f_ioctl = &ufm_ioctl,
-	.f_open = &ufm_open,
 	.basename[0] = "ufm",
 };
 
@@ -178,15 +176,6 @@ ufm_detach(device_t dev)
 	return (0);
 }
 
-static int
-ufm_open(struct usb_fifo *dev, int fflags)
-{
-	if ((fflags & (FWRITE | FREAD)) != (FWRITE | FREAD)) {
-		return (EACCES);
-	}
-	return (0);
-}
-
 static int
 ufm_do_req(struct ufm_softc *sc, uint8_t request,
     uint16_t value, uint16_t index, uint8_t *retbuf)
@@ -315,6 +304,10 @@ ufm_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr,
 	struct ufm_softc *sc = usb_fifo_softc(fifo);
 	int error = 0;
 
+	if ((fflags & (FWRITE | FREAD)) != (FWRITE | FREAD)) {
+		return (EACCES);
+	}
+
 	switch (cmd) {
 	case FM_SET_FREQ:
 		error = ufm_set_freq(sc, addr);
diff --git a/sys/dev/usb/storage/urio.c b/sys/dev/usb/storage/urio.c
index 6bb2e889e40..403c4c2b216 100644
--- a/sys/dev/usb/storage/urio.c
+++ b/sys/dev/usb/storage/urio.c
@@ -390,9 +390,6 @@ urio_open(struct usb_fifo *fifo, int fflags)
 {
 	struct urio_softc *sc = usb_fifo_softc(fifo);
 
-	if ((fflags & (FWRITE | FREAD)) != (FWRITE | FREAD)) {
-		return (EACCES);
-	}
 	if (fflags & FREAD) {
 		/* clear stall first */
 		mtx_lock(&sc->sc_mtx);

From 0627fc1870a8dd10fd7862c65ad96d3b9b201f74 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:10:11 +0000
Subject: [PATCH 0405/2592] MFC r196491

 We used force all of the GPIO pins low first and then
 enable the ones we want. This has been changed to better
 match the ADMtek's reference design to avoid setting the
 power-down configuration line of the PHY at the same time
 it is reset.
---
 sys/dev/usb/net/if_aue.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/sys/dev/usb/net/if_aue.c b/sys/dev/usb/net/if_aue.c
index 142780f5613..1a2ce70b5ae 100644
--- a/sys/dev/usb/net/if_aue.c
+++ b/sys/dev/usb/net/if_aue.c
@@ -484,7 +484,7 @@ aue_miibus_writereg(device_t dev, int phy, int reg, int data)
 	}
 
 	if (i == AUE_TIMEOUT)
-		device_printf(sc->sc_ue.ue_dev, "MII read timed out\n");
+		device_printf(sc->sc_ue.ue_dev, "MII write timed out\n");
 
 	if (!locked)
 		AUE_UNLOCK(sc);
@@ -603,11 +603,14 @@ aue_reset(struct aue_softc *sc)
 	 * to set the GPIO pins high so that the PHY(s) will
 	 * be enabled.
 	 *
-	 * Note: We force all of the GPIO pins low first, *then*
-	 * enable the ones we want.
+	 * NOTE: We used to force all of the GPIO pins low first and then
+	 * enable the ones we want. This has been changed to better
+	 * match the ADMtek's reference design to avoid setting the
+	 * power-down configuration line of the PHY at the same time
+	 * it is reset.
 	 */
-	aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0);
-	aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0|AUE_GPIO_SEL1);
+	aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_SEL0|AUE_GPIO_SEL1);
+	aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_SEL0|AUE_GPIO_SEL1|AUE_GPIO_OUT0);
 
 	if (sc->sc_flags & AUE_FLAG_LSYS) {
 		/* Grrr. LinkSys has to be different from everyone else. */

From 2bb2691018aaa49a2f56bc443a6db8cc7c3f8651 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:10:41 +0000
Subject: [PATCH 0406/2592] MFC r196492

 - fix CDC ethernet matching order so that the match flags get correct.
---
 sys/dev/usb/net/if_cdce.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c
index 352fcec1f5a..52ea2069311 100644
--- a/sys/dev/usb/net/if_cdce.c
+++ b/sys/dev/usb/net/if_cdce.c
@@ -197,9 +197,6 @@ static const struct usb_ether_methods cdce_ue_methods = {
 };
 
 static const struct usb_device_id cdce_devs[] = {
-	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)},
-	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)},
-
 	{USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)},
 	{USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)},
 	{USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)},
@@ -213,6 +210,9 @@ static const struct usb_device_id cdce_devs[] = {
 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
+
+	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)},
+	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)},
 };
 
 static int

From d51a8c13ead0f9e2102d02eceebb43ec16d77785 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:11:13 +0000
Subject: [PATCH 0407/2592] MFC r196493

 - Fix false positive uipaq probe
---
 sys/dev/usb/serial/uipaq.c | 4 ++++
 sys/dev/usb/usb.h          | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c
index 79fe21e5c2c..89a4cd254ab 100644
--- a/sys/dev/usb/serial/uipaq.c
+++ b/sys/dev/usb/serial/uipaq.c
@@ -1103,6 +1103,10 @@ uipaq_probe(device_t dev)
 	if (uaa->info.bIfaceIndex != UIPAQ_IFACE_INDEX) {
 		return (ENXIO);
 	}
+	if (uaa->info.bInterfaceClass == UICLASS_IAD) {
+		DPRINTF("IAD detected - not UIPAQ serial device\n");
+		return (ENXIO);
+	}
 	return (usbd_lookup_id_by_uaa(uipaq_devs, sizeof(uipaq_devs), uaa));
 }
 
diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h
index 68c3caf6a05..119839831c1 100644
--- a/sys/dev/usb/usb.h
+++ b/sys/dev/usb/usb.h
@@ -484,6 +484,8 @@ typedef struct usb_interface_assoc_descriptor usb_interface_assoc_descriptor_t;
 #define	UISUBCLASS_RF			0x01
 #define	UIPROTO_BLUETOOTH		0x01
 
+#define	UICLASS_IAD		0xEF	/* Interface Association Descriptor */
+
 #define	UICLASS_APPL_SPEC	0xfe
 #define	UISUBCLASS_FIRMWARE_DOWNLOAD	1
 #define	UISUBCLASS_IRDA			2

From d92f7ea655a9d9e09612d5a4f937d51a40d70a6d Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:11:48 +0000
Subject: [PATCH 0408/2592] MFC r196494

 - fix uvisor support, mostly correct buffer sizes used.
 - correct device info flag for SONY Cli NR70V
---
 sys/dev/usb/serial/uvisor.c | 46 ++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c
index c7175e31a63..3f1624bcbf4 100644
--- a/sys/dev/usb/serial/uvisor.c
+++ b/sys/dev/usb/serial/uvisor.c
@@ -95,7 +95,15 @@ SYSCTL_INT(_hw_usb_uvisor, OID_AUTO, debug, CTLFLAG_RW,
 
 #define	UVISOR_CONFIG_INDEX	0
 #define	UVISOR_IFACE_INDEX	0
-#define	UVISOR_BUFSIZE       1024	/* bytes */
+
+/*
+ * The following buffer sizes are hardcoded due to the way the Palm
+ * firmware works. It looks like the device is not short terminating
+ * the data transferred.
+ */
+#define	UVISORIBUFSIZE	       0	/* Use wMaxPacketSize */
+#define	UVISOROBUFSIZE	       32	/* bytes */
+#define	UVISOROFRAMES	       32	/* units */
 
 /* From the Linux driver */
 /*
@@ -208,7 +216,8 @@ static const struct usb_config uvisor_config[UVISOR_N_TRANSFER] = {
 		.type = UE_BULK,
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
-		.bufsize = UVISOR_BUFSIZE,	/* bytes */
+		.bufsize = UVISOROBUFSIZE * UVISOROFRAMES,
+		.frames = UVISOROFRAMES,
 		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
 		.callback = &uvisor_write_callback,
 	},
@@ -217,7 +226,7 @@ static const struct usb_config uvisor_config[UVISOR_N_TRANSFER] = {
 		.type = UE_BULK,
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_IN,
-		.bufsize = UVISOR_BUFSIZE,	/* bytes */
+		.bufsize = UVISORIBUFSIZE,
 		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
 		.callback = &uvisor_read_callback,
 	},
@@ -270,7 +279,7 @@ static const struct usb_device_id uvisor_devs[] = {
 	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE31, UVISOR_FLAG_PALM4)},
 	{USB_VPI(USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_I500, UVISOR_FLAG_PALM4)},
 	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40, 0)},
-	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41, UVISOR_FLAG_PALM4)},
+	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41, 0)},
 	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360, UVISOR_FLAG_PALM4)},
 	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60, UVISOR_FLAG_PALM4)},
 	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_35, UVISOR_FLAG_PALM35)},
@@ -375,7 +384,6 @@ uvisor_init(struct uvisor_softc *sc, struct usb_device *udev, struct usb_config
 	struct uvisor_connection_info coninfo;
 	struct uvisor_palm_connection_info pconinfo;
 	uint16_t actlen;
-	uWord wAvail;
 	uint8_t buffer[256];
 
 	if (sc->sc_flag & UVISOR_FLAG_VISOR) {
@@ -496,6 +504,9 @@ uvisor_init(struct uvisor_softc *sc, struct usb_device *udev, struct usb_config
 			goto done;
 		}
 	}
+#if 0
+	uWord wAvail;
+
 	DPRINTF("getting available bytes\n");
 	req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
 	req.bRequest = UVISOR_REQUEST_BYTES_AVAILABLE;
@@ -507,6 +518,7 @@ uvisor_init(struct uvisor_softc *sc, struct usb_device *udev, struct usb_config
 		goto done;
 	}
 	DPRINTF("avail=%d\n", UGETW(wAvail));
+#endif
 
 	DPRINTF("done\n");
 done:
@@ -579,19 +591,31 @@ uvisor_write_callback(struct usb_xfer *xfer, usb_error_t error)
 	struct uvisor_softc *sc = usbd_xfer_softc(xfer);
 	struct usb_page_cache *pc;
 	uint32_t actlen;
+	uint8_t x;
 
 	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,
-		    UVISOR_BUFSIZE, &actlen)) {
+		for (x = 0; x != UVISOROFRAMES; x++) {
 
-			usbd_xfer_set_frame_len(xfer, 0, actlen);
+			usbd_xfer_set_frame_offset(xfer, 
+			    x * UVISOROBUFSIZE, x);
+
+			pc = usbd_xfer_get_frame(xfer, x);
+			if (ucom_get_data(&sc->sc_ucom, pc, 0,
+			    UVISOROBUFSIZE, &actlen)) {
+				usbd_xfer_set_frame_len(xfer, x, actlen);
+			} else {
+				break;
+			}
+		}
+		/* check for data */
+		if (x != 0) {
+			usbd_xfer_set_frames(xfer, x);
 			usbd_transfer_submit(xfer);
 		}
-		return;
+		break;
 
 	default:			/* Error */
 		if (error != USB_ERR_CANCELLED) {
@@ -599,7 +623,7 @@ tr_setup:
 			usbd_xfer_set_stall(xfer);
 			goto tr_setup;
 		}
-		return;
+		break;
 	}
 }
 

From edd4ee99cfe6ed6990698f7f54887bd69f6168c6 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:12:29 +0000
Subject: [PATCH 0409/2592] MFC r196495

 Add mass storage quirks.

PR:             usb/137138,usb/137226,usb/137789,usb/135372
---
 sys/dev/usb/storage/umass.c | 16 ++++++++++++++++
 sys/dev/usb/usbdevs         | 14 ++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
index 3aa128453df..2801f1cd730 100644
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -412,6 +412,10 @@ static const struct umass_devdescr umass_devdescr[] = {
 		UMASS_PROTO_DEFAULT,
 		NO_SYNCHRONIZE_CACHE
 	},
+	{USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_SDCR_6335, RID_WILDCARD,
+		UMASS_PROTO_DEFAULT,
+		NO_TEST_UNIT_READY | NO_SYNCHRONIZE_CACHE
+	},
 	{USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU6390, RID_WILDCARD,
 		UMASS_PROTO_DEFAULT,
 		NO_SYNCHRONIZE_CACHE
@@ -733,6 +737,10 @@ static const struct umass_devdescr umass_devdescr[] = {
 		UMASS_PROTO_UFI,
 		NO_QUIRKS
 	},
+	{ USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SPE3030CC, RID_WILDCARD,
+		UMASS_PROTO_DEFAULT,
+		NO_SYNCHRONIZE_CACHE
+	},
 	{USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U, RID_WILDCARD,
 		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 		NO_TEST_UNIT_READY
@@ -893,6 +901,10 @@ static const struct umass_devdescr umass_devdescr[] = {
 		UMASS_PROTO_UFI | UMASS_PROTO_CBI,
 		NO_QUIRKS
 	},
+	{USB_VENDOR_TECLAST, USB_PRODUCT_TECLAST_TLC300, RID_WILDCARD,
+		UMASS_PROTO_DEFAULT,
+		NO_TEST_UNIT_READY | NO_SYNCHRONIZE_CACHE
+	},
 	{USB_VENDOR_TREK, USB_PRODUCT_TREK_MEMKEY, RID_WILDCARD,
 		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 		NO_INQUIRY
@@ -965,6 +977,10 @@ static const struct umass_devdescr umass_devdescr[] = {
 		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 		NO_SYNCHRONIZE_CACHE
 	},
+	{USB_VENDOR_ASUS, USB_PRODUCT_ASUS_GMSC, RID_WILDCARD,
+		UMASS_PROTO_DEFAULT,
+		NO_SYNCHRONIZE_CACHE
+	},
 	{VID_EOT, PID_EOT, RID_EOT, 0, 0}
 };
 
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 288750c935e..3cb6a3ae82a 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -360,6 +360,7 @@ vendor SMC		0x0707	Standard Microsystems
 vendor PUTERCOM		0x0708	Putercom
 vendor MCT		0x0711	MCT
 vendor IMATION		0x0718	Imation
+vendor TECLAST		0x071b	Teclast
 vendor SONYERICSSON	0x0731	Sony Ericsson
 vendor EICON		0x0734	Eicon Networks
 vendor SYNTECH		0x0745	Syntech Information
@@ -585,6 +586,7 @@ vendor NETGEAR3		0x1385	Netgear
 vendor BALTECH		0x13ad	Baltech
 vendor CISCOLINKSYS	0x13b1	Cisco-Linksys
 vendor SHARK		0x13d2	Shark
+vendor EMTEC		0x13fe	Emtec
 vendor NOVATEL		0x1410	Novatel Wireless
 vendor MERLIN		0x1416	Merlin
 vendor WISTRONNEWEB	0x1435	Wistron NeWeb
@@ -820,6 +822,7 @@ product AKS USBHASP		0x0001	USB-HASP 0.06
 /* Alcor Micro, Inc. products */
 product ALCOR2 KBD_HUB		0x2802	Kbd Hub
 
+product ALCOR SDCR_6335		0x6335	SD/MMC Card Reader
 product ALCOR TRANSCEND		0x6387	Transcend JetFlash Drive
 product ALCOR MA_KBD_HUB	0x9213	MacAlly Kbd Hub
 product ALCOR AU9814		0x9215	AU9814 Hub
@@ -861,6 +864,12 @@ product APC UPS			0x0002	Uninterruptible Power Supply
 
 /* Apple Computer products */
 product APPLE EXT_KBD		0x020c	Apple Extended USB Keyboard
+product APPLE KBD_TP_ANSI	0x0223	Apple Internal Keyboard/Trackpad (Wellspring/ANSI)
+product APPLE KBD_TP_ISO	0x0224	Apple Internal Keyboard/Trackpad (Wellspring/ISO)
+product APPLE KBD_TP_JIS	0x0225	Apple Internal Keyboard/Trackpad (Wellspring/JIS)
+product APPLE KBD_TP_ANSI2	0x0230	Apple Internal Keyboard/Trackpad (Wellspring2/ANSI)
+product APPLE KBD_TP_ISO2	0x0231	Apple Internal Keyboard/Trackpad (Wellspring2/ISO)
+product APPLE KBD_TP_JIS2	0x0232	Apple Internal Keyboard/Trackpad (Wellspring2/JIS)
 product APPLE OPTMOUSE		0x0302	Optical mouse
 product APPLE MIGHTYMOUSE	0x0304	Mighty Mouse
 product APPLE EXT_KBD_HUB	0x1003	Hub in Apple Extended USB Keyboard
@@ -902,6 +911,7 @@ product ASUS RT2573_1		0x1723	RT2573
 product ASUS RT2573_2		0x1724	RT2573
 product ASUS LCM		0x1726	LCM display
 product ASUS P535		0x420f	ASUS P535 PDA
+product	ASUS GMSC		0x422f	ASUS Generic Mass Storage
 
 /* ATen products */
 product ATEN UC1284		0x2001	Parallel printer
@@ -1971,6 +1981,7 @@ product PHILIPS HUB		0x0201	hub
 product PHILIPS PCA646VC	0x0303	PCA646VC PC Camera
 product PHILIPS PCVC680K	0x0308	PCVC680K Vesta Pro PC Camera
 product PHILIPS DSS150		0x0471	DSS 150 Digital Speaker System
+product PHILIPS SPE3030CC	0x083a	USB 2.0 External Disk
 product PHILIPS SNU5600		0x1236	SNU5600
 product PHILIPS UM10016		0x1552	ISP 1581 Hi-Speed USB MPEG2 Encoder Reference Kit
 product PHILIPS DIVAUSB		0x1801	DIVA USB mp3 player
@@ -2345,6 +2356,9 @@ product SUN KBD_HUB		0x100e	Kbd Hub
 /* Super Top products */
 product	SUPERTOP IDE		0x6600	USB-IDE
 
+/* Teclast products */
+product TECLAST TLC300		0x3203	USB Media Player
+
 /* Supra products */
 product DIAMOND2 SUPRAEXPRESS56K 0x07da	Supra Express 56K modem
 product DIAMOND2 SUPRA2890	0x0b4a	SupraMax 2890 56K Modem

From f18778a473bdcac2a4f25ac2117d46a2ebc5ffbc Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:13:02 +0000
Subject: [PATCH 0410/2592] MFC r196496

 Add a reminder comment to optimize bus_dmamap_sync calls.
---
 sys/dev/usb/usb_busdma.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sys/dev/usb/usb_busdma.c b/sys/dev/usb/usb_busdma.c
index 3769102c510..177b94faceb 100644
--- a/sys/dev/usb/usb_busdma.c
+++ b/sys/dev/usb/usb_busdma.c
@@ -679,6 +679,12 @@ usb_pc_cpu_invalidate(struct usb_page_cache *pc)
 		/* nothing has been loaded into this page cache! */
 		return;
 	}
+
+	/*
+	 * TODO: We currently do XXX_POSTREAD and XXX_PREREAD at the
+	 * same time, but in the future we should try to isolate the
+	 * different cases to optimise the code. --HPS
+	 */
 	bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD);
 	bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD);
 }

From 6536a23656d3749e794e809fff15cbbba04da240 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:13:36 +0000
Subject: [PATCH 0411/2592] MFC r196497

 Remove redundant locking.
---
 sys/dev/usb/wlan/if_upgt.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c
index 580b3113190..67e6980701b 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -465,7 +465,6 @@ upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 
 	switch (cmd) {
 	case SIOCSIFFLAGS:
-		mtx_lock(&Giant);
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				if ((ifp->if_flags ^ sc->sc_if_flags) &
@@ -482,7 +481,6 @@ upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 		sc->sc_if_flags = ifp->if_flags;
 		if (startall)
 			ieee80211_start_all(ic);
-		mtx_unlock(&Giant);
 		break;
 	case SIOCGIFMEDIA:
 		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);

From 6333b36c435bb0fe13fe9370ec430de229e0e5c7 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:14:06 +0000
Subject: [PATCH 0412/2592] MFC r196826

 Make umass(4) pass device USB serial number to CAM, making it possible
 to e.g. retrieve it using camcontrol(8).
---
 sys/dev/usb/storage/umass.c | 46 +++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
index 2801f1cd730..a8aa951f29c 100644
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -124,6 +124,7 @@ __FBSDID("$FreeBSD$");
 
 #include 
 #include 
+#include 
 #include "usbdevs.h"
 
 #include 
@@ -2978,6 +2979,28 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb)
 
 				if (sc->sc_transfer.cmd_data[0] == INQUIRY) {
 
+					/*
+					 * Umass devices don't generally report their serial numbers
+					 * in the usual SCSI way.  Emulate it here.
+					 */
+					if ((sc->sc_transfer.cmd_data[1] & SI_EVPD) &&
+					    sc->sc_transfer.cmd_data[2] == SVPD_UNIT_SERIAL_NUMBER &&
+					    sc->sc_udev != NULL &&
+					    sc->sc_udev->serial != NULL &&
+					    sc->sc_udev->serial[0] != '\0') {
+						struct scsi_vpd_unit_serial_number *vpd_serial;
+
+						vpd_serial = (struct scsi_vpd_unit_serial_number *)ccb->csio.data_ptr;
+						vpd_serial->length = strlen(sc->sc_udev->serial);
+						if (vpd_serial->length > sizeof(vpd_serial->serial_num))
+							vpd_serial->length = sizeof(vpd_serial->serial_num);
+						memcpy(vpd_serial->serial_num, sc->sc_udev->serial, vpd_serial->length);
+						ccb->csio.scsi_status = SCSI_STATUS_OK;
+						ccb->ccb_h.status = CAM_REQ_CMP;
+						xpt_done(ccb);
+						goto done;
+					}
+
 					/*
 					 * Handle EVPD inquiry for broken devices first
 					 * NO_INQUIRY also implies NO_INQUIRY_EVPD
@@ -3194,6 +3217,29 @@ umass_cam_cb(struct umass_softc *sc, union ccb *ccb, uint32_t residue,
 			maxsector = scsi_4btoul(rcap->addr) - 1;
 			scsi_ulto4b(maxsector, rcap->addr);
 		}
+		/*
+		 * We have to add SVPD_UNIT_SERIAL_NUMBER to the list
+		 * of pages supported by the device - otherwise, CAM
+		 * will never ask us for the serial number if the
+		 * device cannot handle that by itself.
+		 */
+		if (ccb->ccb_h.func_code == XPT_SCSI_IO &&
+		    sc->sc_transfer.cmd_data[0] == INQUIRY &&
+		    (sc->sc_transfer.cmd_data[1] & SI_EVPD) &&
+		    sc->sc_transfer.cmd_data[2] == SVPD_SUPPORTED_PAGE_LIST &&
+		    sc->sc_udev != NULL &&
+		    sc->sc_udev->serial != NULL &&
+		    sc->sc_udev->serial[0] != '\0') {
+			struct ccb_scsiio *csio;
+			struct scsi_vpd_supported_page_list *page_list;
+
+			csio = &ccb->csio;
+			page_list = (struct scsi_vpd_supported_page_list *)csio->data_ptr;
+			if (page_list->length + 1 < SVPD_SUPPORTED_PAGES_SIZE) {
+				page_list->list[page_list->length] = SVPD_UNIT_SERIAL_NUMBER;
+				page_list->length++;
+			}
+		}
 		xpt_done(ccb);
 		break;
 

From 1063b450cdee7134c27abed07ec12b8526aae73f Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:14:39 +0000
Subject: [PATCH 0413/2592] MFC r197553

 - clean up USB detach logic. There seems to be some problems detaching multiple
   USB HUBs connected in series from the root.
---
 sys/dev/usb/controller/usb_controller.c |  6 +--
 sys/dev/usb/usb_device.c                | 30 +++++------
 sys/dev/usb/usb_device.h                |  1 -
 sys/dev/usb/usb_hub.c                   | 67 ++++++++++++++++---------
 sys/dev/usb/usb_transfer.c              |  6 +--
 5 files changed, 61 insertions(+), 49 deletions(-)

diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c
index a9254443590..fe59e06ee1d 100644
--- a/sys/dev/usb/controller/usb_controller.c
+++ b/sys/dev/usb/controller/usb_controller.c
@@ -270,11 +270,9 @@ usb_bus_detach(struct usb_proc_msg *pm)
 	mtx_unlock(&Giant);
 
 	/*
-	 * Free USB Root device, but not any sub-devices, hence they
-	 * are freed by the caller of this function:
+	 * Free USB device and all subdevices, if any.
 	 */
-	usb_free_device(udev,
-	    USB_UNCFG_FLAG_FREE_EP0);
+	usb_free_device(udev, 0);
 
 	USB_BUS_LOCK(bus);
 	/* clear bdev variable last */
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 635a9b1528d..d286db08b48 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -478,7 +478,7 @@ usbd_set_config_index(struct usb_device *udev, uint8_t index)
 		usbd_enum_lock(udev);
 	}
 
-	usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV);
+	usb_unconfigure(udev, 0);
 
 	if (index == USB_UNCONFIG_INDEX) {
 		/*
@@ -582,7 +582,7 @@ usbd_set_config_index(struct usb_device *udev, uint8_t index)
 done:
 	DPRINTF("error=%s\n", usbd_errstr(err));
 	if (err) {
-		usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV);
+		usb_unconfigure(udev, 0);
 	}
 	if (do_unlock)
 		usbd_enum_unlock(udev);
@@ -989,18 +989,13 @@ usb_detach_device_sub(struct usb_device *udev, device_t *ppdev,
 	device_t dev;
 	int err;
 
-	if (!(flag & USB_UNCFG_FLAG_FREE_SUBDEV)) {
-
-		*ppdev = NULL;
-
-	} else if (*ppdev) {
-
+	dev = *ppdev;
+	if (dev) {
 		/*
 		 * NOTE: It is important to clear "*ppdev" before deleting
 		 * the child due to some device methods being called late
 		 * during the delete process !
 		 */
-		dev = *ppdev;
 		*ppdev = NULL;
 
 		device_printf(dev, "at %s, port %d, addr %d "
@@ -1778,7 +1773,7 @@ repeat_set_config:
 		} else if (usb_test_huawei_autoinst_p(udev, &uaa) == 0) {
 			DPRINTFN(0, "Found Huawei auto-install disk!\n");
 			/* leave device unconfigured */
-			usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV);
+			usb_unconfigure(udev, 0);
 		}
 	} else {
 		err = 0;		/* set success */
@@ -1803,10 +1798,10 @@ repeat_set_config:
 #endif
 done:
 	if (err) {
-		/* free device  */
-		usb_free_device(udev,
-		    USB_UNCFG_FLAG_FREE_SUBDEV |
-		    USB_UNCFG_FLAG_FREE_EP0);
+		/*
+		 * Free USB device and all subdevices, if any.
+		 */
+		usb_free_device(udev, 0);
 		udev = NULL;
 	}
 	return (udev);
@@ -1926,9 +1921,10 @@ usb_cdev_cleanup(void* arg)
 /*------------------------------------------------------------------------*
  *	usb_free_device
  *
- * This function is NULL safe and will free an USB device.
+ * This function is NULL safe and will free an USB device and its
+ * children devices, if any.
  *
- * Flag values, see "USB_UNCFG_FLAG_XXX".
+ * Flag values: Reserved, set to zero.
  *------------------------------------------------------------------------*/
 void
 usb_free_device(struct usb_device *udev, uint8_t flag)
@@ -1982,7 +1978,7 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
 	}
 
 	/* the following will get the device unconfigured in software */
-	usb_unconfigure(udev, flag);
+	usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_EP0);
 
 	/* unsetup any leftover default USB transfers */
 	usbd_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h
index 682e2007e6e..66f975a5c1f 100644
--- a/sys/dev/usb/usb_device.h
+++ b/sys/dev/usb/usb_device.h
@@ -41,7 +41,6 @@ struct usb_device;		/* linux compat */
 /* "usb_unconfigure()" flags */
 
 #define	USB_UNCFG_FLAG_NONE 0x00
-#define	USB_UNCFG_FLAG_FREE_SUBDEV 0x01		/* subdevices are freed */
 #define	USB_UNCFG_FLAG_FREE_EP0	0x02		/* endpoint zero is freed */
 
 struct usb_clear_stall_msg {
diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c
index 2c81d97d126..07a0970b33b 100644
--- a/sys/dev/usb/usb_hub.c
+++ b/sys/dev/usb/usb_hub.c
@@ -316,12 +316,13 @@ repeat:
 	if (err) {
 		goto error;
 	}
-	/* detach any existing devices */
+	/* check if there is a child */
 
-	if (child) {
-		usb_free_device(child,
-		    USB_UNCFG_FLAG_FREE_SUBDEV |
-		    USB_UNCFG_FLAG_FREE_EP0);
+	if (child != NULL) {
+		/*
+		 * Free USB device and all subdevices, if any.
+		 */
+		usb_free_device(child, 0);
 		child = NULL;
 	}
 	/* get fresh status */
@@ -438,10 +439,11 @@ repeat:
 	return (0);			/* success */
 
 error:
-	if (child) {
-		usb_free_device(child,
-		    USB_UNCFG_FLAG_FREE_SUBDEV |
-		    USB_UNCFG_FLAG_FREE_EP0);
+	if (child != NULL) {
+		/*
+		 * Free USB device and all subdevices, if any.
+		 */
+		usb_free_device(child, 0);
 		child = NULL;
 	}
 	if (err == 0) {
@@ -888,12 +890,14 @@ uhub_detach(device_t dev)
 	struct usb_device *child;
 	uint8_t x;
 
-	/* detach all children first */
-	bus_generic_detach(dev);
-
 	if (hub == NULL) {		/* must be partially working */
 		return (0);
 	}
+
+	/* Make sure interrupt transfer is gone. */
+	usbd_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
+
+	/* Detach all ports */
 	for (x = 0; x != hub->nports; x++) {
 
 		child = usb_bus_port_get_device(sc->sc_udev->bus, hub->ports + x);
@@ -901,15 +905,12 @@ uhub_detach(device_t dev)
 		if (child == NULL) {
 			continue;
 		}
-		/*
-		 * Subdevices are not freed, because the caller of
-		 * uhub_detach() will do that.
-		 */
-		usb_free_device(child,
-		    USB_UNCFG_FLAG_FREE_EP0);
-	}
 
-	usbd_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
+		/*
+		 * Free USB device and all subdevices, if any.
+		 */
+		usb_free_device(child, 0);
+	}
 
 	free(hub, M_USBDEV);
 	sc->sc_udev->hub = NULL;
@@ -984,10 +985,19 @@ static int
 uhub_child_location_string(device_t parent, device_t child,
     char *buf, size_t buflen)
 {
-	struct uhub_softc *sc = device_get_softc(parent);
-	struct usb_hub *hub = sc->sc_udev->hub;
+	struct uhub_softc *sc;
+	struct usb_hub *hub;
 	struct hub_result res;
 
+	if (!device_is_attached(parent)) {
+		if (buflen)
+			buf[0] = 0;
+		return (0);
+	}
+
+	sc = device_get_softc(parent);
+	hub = sc->sc_udev->hub;
+
 	mtx_lock(&Giant);
 	uhub_find_iface_index(hub, child, &res);
 	if (!res.udev) {
@@ -1009,11 +1019,20 @@ static int
 uhub_child_pnpinfo_string(device_t parent, device_t child,
     char *buf, size_t buflen)
 {
-	struct uhub_softc *sc = device_get_softc(parent);
-	struct usb_hub *hub = sc->sc_udev->hub;
+	struct uhub_softc *sc;
+	struct usb_hub *hub;
 	struct usb_interface *iface;
 	struct hub_result res;
 
+	if (!device_is_attached(parent)) {
+		if (buflen)
+			buf[0] = 0;
+		return (0);
+	}
+
+	sc = device_get_softc(parent);
+	hub = sc->sc_udev->hub;
+
 	mtx_lock(&Giant);
 	uhub_find_iface_index(hub, child, &res);
 	if (!res.udev) {
diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c
index 8daf475a4b8..9a063a12a30 100644
--- a/sys/dev/usb/usb_transfer.c
+++ b/sys/dev/usb/usb_transfer.c
@@ -2121,6 +2121,9 @@ usb_dma_delay_done_cb(void *arg)
 
 	DPRINTFN(3, "Completed %p\n", xfer);
 
+	/* only delay once */
+	xfer->flags_int.did_dma_delay = 1;
+
 	/* queue callback for execution, again */
 	usbd_transfer_done(xfer, 0);
 }
@@ -2488,9 +2491,6 @@ usbd_callback_wrapper_sub(struct usb_xfer *xfer)
 
 		usb_timeout_t temp;
 
-		/* only delay once */
-		xfer->flags_int.did_dma_delay = 1;
-
 		/* we can not cancel this delay */
 		xfer->flags_int.can_cancel_immed = 0;
 

From ffa540b7529c11b40a2ef91c685de16a8c3e6d9c Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:15:26 +0000
Subject: [PATCH 0414/2592] MFC r197554

 Import two PCI quirks from Linux

  - Add quirk for ATI SB600 and SB700 to free SMB controller
  - Correct schedule sleep time to 10us on the VIA ehci controller
---
 sys/dev/usb/controller/ehci_pci.c | 70 +++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index 7f8c0a0012d..7978f4facff 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -240,6 +240,50 @@ ehci_pci_probe(device_t self)
 	}
 }
 
+static void
+ehci_pci_ati_quirk(device_t self, uint8_t is_sb700)
+{
+	device_t smbdev;
+	uint32_t val;
+
+	if (is_sb700) {
+		/* Lookup SMBUS PCI device */
+		smbdev = pci_find_device(PCI_EHCI_VENDORID_ATI, 0x4385);
+		if (smbdev == NULL)
+			return;
+		val = pci_get_revid(smbdev);
+		if (val != 0x3a && val != 0x3b)
+			return;
+	}
+
+	/*
+	 * Note: this bit is described as reserved in SB700
+	 * Register Reference Guide.
+	 */
+	val = pci_read_config(self, 0x53, 1);
+	if (!(val & 0x8)) {
+		val |= 0x8;
+		pci_write_config(self, 0x53, val, 1);
+		device_printf(self, "AMD SB600/700 quirk applied\n");
+	}
+}
+
+static void
+ehci_pci_via_quirk(device_t self)
+{
+	uint32_t val;
+
+	if ((pci_get_device(self) == 0x3104) && 
+	    ((pci_get_revid(self) & 0xf0) == 0x60)) {
+		/* Correct schedule sleep time to 10us */
+		val = pci_read_config(self, 0x4b, 1);
+		if (val & 0x20)
+			return;
+		pci_write_config(self, 0x4b, val, 1);
+		device_printf(self, "VIA-quirk applied\n");
+	}
+}
+
 static int
 ehci_pci_attach(device_t self)
 {
@@ -370,6 +414,32 @@ ehci_pci_attach(device_t self)
 		goto error;
 	}
 	ehci_pci_takecontroller(self);
+
+	/* Undocumented quirks taken from Linux */
+
+	switch (pci_get_vendor(self)) {
+	case PCI_EHCI_VENDORID_ATI:
+		/* SB600 and SB700 EHCI quirk */
+		switch (pci_get_device(self)) {
+		case 0x4386:
+			ehci_pci_ati_quirk(self, 0);
+			break;
+		case 0x4396:
+			ehci_pci_ati_quirk(self, 1);
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case PCI_EHCI_VENDORID_VIA:
+		ehci_pci_via_quirk(self);
+		break;
+
+	default:
+		break;
+	}
+
 	err = ehci_init(sc);
 	if (!err) {
 		err = device_probe_and_attach(sc->sc_bus.bdev);

From 320dbc0942cd5d919146a9d8fe9e21a8090e383b Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:16:00 +0000
Subject: [PATCH 0415/2592] MFC r197555

 Simplify logic around setting EHCI_QH_DTC and expand some htohc32(temp.sc, 0)
 statements to zero.
---
 sys/dev/usb/controller/ehci.c | 34 +++++++++++++++-------------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c
index 0ab54aafa6b..7dc5d312121 100644
--- a/sys/dev/usb/controller/ehci.c
+++ b/sys/dev/usb/controller/ehci.c
@@ -1954,18 +1954,15 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last)
 	    EHCI_QH_SET_MPL(xfer->max_packet_size));
 
 	if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
-		qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) |
-		    EHCI_QH_DTC);
+		qh_endp |= EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH);
 		if (methods != &ehci_device_intr_methods)
 			qh_endp |= EHCI_QH_SET_NRL(8);
 	} else {
 
 		if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_FULL) {
-			qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_FULL) |
-			    EHCI_QH_DTC);
+			qh_endp |= EHCI_QH_SET_EPS(EHCI_QH_SPEED_FULL);
 		} else {
-			qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_LOW) |
-			    EHCI_QH_DTC);
+			qh_endp |= EHCI_QH_SET_EPS(EHCI_QH_SPEED_LOW);
 		}
 
 		if (methods == &ehci_device_ctrl_methods) {
@@ -1977,6 +1974,11 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last)
 		}
 	}
 
+	if (temp.auto_data_toggle == 0) {
+		/* software computes the data toggle */
+		qh_endp |= EHCI_QH_DTC;
+	}
+
 	qh->qh_endp = htohc32(temp.sc, qh_endp);
 
 	qh_endphub =
@@ -1987,23 +1989,17 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last)
 	    EHCI_QH_SET_PORT(xfer->xroot->udev->hs_port_no));
 
 	qh->qh_endphub = htohc32(temp.sc, qh_endphub);
-	qh->qh_curqtd = htohc32(temp.sc, 0);
+	qh->qh_curqtd = 0;
 
 	/* fill the overlay qTD */
-	qh->qh_qtd.qtd_status = htohc32(temp.sc, 0);
 
-	if (temp.auto_data_toggle) {
-
-		/* let the hardware compute the data toggle */
-
-		qh->qh_endp &= htohc32(temp.sc, ~EHCI_QH_DTC);
-
-		if (xfer->endpoint->toggle_next) {
-			/* DATA1 is next */
-			qh->qh_qtd.qtd_status |=
-			    htohc32(temp.sc, EHCI_QTD_SET_TOGGLE(1));
-		}
+	if (temp.auto_data_toggle && xfer->endpoint->toggle_next) {
+		/* DATA1 is next */
+		qh->qh_qtd.qtd_status = htohc32(temp.sc, EHCI_QTD_SET_TOGGLE(1));
+	} else {
+		qh->qh_qtd.qtd_status = 0;
 	}
+
 	td = xfer->td_transfer_first;
 
 	qh->qh_qtd.qtd_next = td->qtd_self;

From f23c09d0b0ec175a424638a57c7a667c14e36cf4 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:16:39 +0000
Subject: [PATCH 0416/2592] MFC r197556

 Clear all interrupts rather than just SETUP packet.
---
 sys/dev/usb/controller/atmegadci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c
index 9b60ad7e17b..a864c5765c5 100644
--- a/sys/dev/usb/controller/atmegadci.c
+++ b/sys/dev/usb/controller/atmegadci.c
@@ -301,8 +301,8 @@ atmegadci_setup_rx(struct atmegadci_td *td)
 		sc->sc_dv_addr = 0xFF;
 	}
 
-	/* clear SETUP packet interrupt */
-	ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, ~ATMEGA_UEINTX_RXSTPI);
+	/* Clear SETUP packet interrupt and all other previous interrupts */
+	ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, 0);
 	return (0);			/* complete */
 
 not_complete:

From 9d168176f5a01adb51ed92d1c7ab0b131a7fb44d Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:17:23 +0000
Subject: [PATCH 0417/2592] MFC r197558

 Fix NULL-pointer dereference in usb_endpoint_foreach().

PR:		usb/138389
---
 sys/dev/usb/usb_device.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index d286db08b48..ea864f4287d 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -367,12 +367,14 @@ usb_init_endpoint(struct usb_device *udev, uint8_t iface_index,
 struct usb_endpoint *
 usb_endpoint_foreach(struct usb_device *udev, struct usb_endpoint *ep)
 {
-	struct usb_endpoint *ep_end = udev->endpoints + udev->endpoints_max;
+	struct usb_endpoint *ep_end;
 
 	/* be NULL safe */
 	if (udev == NULL)
 		return (NULL);
 
+	ep_end = udev->endpoints + udev->endpoints_max;
+
 	/* get next endpoint */
 	if (ep == NULL)
 		ep = udev->endpoints;

From 88f788a6c509150b258e254fe5b5d64bcb3e5393 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:17:54 +0000
Subject: [PATCH 0418/2592] MFC r197559

 Add support for USB language selection.

PR:		usb/138563
---
 sys/dev/usb/usb_bus.h    |  6 ++-
 sys/dev/usb/usb_device.c | 84 ++++++++++++++++++++++++++++++----------
 2 files changed, 68 insertions(+), 22 deletions(-)

diff --git a/sys/dev/usb/usb_bus.h b/sys/dev/usb/usb_bus.h
index 8d64199e11e..99e97770665 100644
--- a/sys/dev/usb/usb_bus.h
+++ b/sys/dev/usb/usb_bus.h
@@ -98,10 +98,14 @@ struct usb_bus {
 	uint8_t	devices_max;		/* maximum number of USB devices */
 	uint8_t	do_probe;		/* set if USB BUS should be re-probed */
 
+	/* 
+	 * The scratch area can only be used inside the explore thread
+	 * belonging to the give serial bus.
+	 */
 	union {
 		struct usb_hw_ep_scratch hw_ep_scratch[1];
 		struct usb_temp_setup temp_setup[1];
-		uint8_t	data[128];
+		uint8_t	data[255];
 	}	scratch[1];
 };
 
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index ea864f4287d..b397d35501c 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -105,9 +105,23 @@ static void	usb_cdev_cleanup(void *);
 
 int	usb_template = 0;
 
+TUNABLE_INT("hw.usb.usb_template", &usb_template);
 SYSCTL_INT(_hw_usb, OID_AUTO, template, CTLFLAG_RW,
     &usb_template, 0, "Selected USB device side template");
 
+/* English is default language */
+
+static int usb_lang_id = 0x0009;
+static int usb_lang_mask = 0x00FF;
+
+TUNABLE_INT("hw.usb.usb_lang_id", &usb_lang_id);
+SYSCTL_INT(_hw_usb, OID_AUTO, usb_lang_id, CTLFLAG_RW,
+    &usb_lang_id, 0, "Preferred USB language ID");
+
+TUNABLE_INT("hw.usb.usb_lang_mask", &usb_lang_mask);
+SYSCTL_INT(_hw_usb, OID_AUTO, usb_lang_mask, CTLFLAG_RW,
+    &usb_lang_mask, 0, "Preferred USB language mask");
+
 static const char* statestr[USB_STATE_MAX] = {
 	[USB_STATE_DETACHED]	= "DETACHED",
 	[USB_STATE_ATTACHED]	= "ATTACHED",
@@ -1436,7 +1450,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
 	struct usb_device *adev;
 	struct usb_device *hub;
 	uint8_t *scratch_ptr;
-	uint32_t scratch_size;
+	size_t scratch_size;
 	usb_error_t err;
 	uint8_t device_index;
 
@@ -1682,8 +1696,35 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
 	if (err || (scratch_ptr[0] < 4)) {
 		udev->flags.no_strings = 1;
 	} else {
-		/* pick the first language as the default */
-		udev->langid = UGETW(scratch_ptr + 2);
+		uint16_t langid;
+		uint16_t pref;
+		uint16_t mask;
+		uint8_t x;
+
+		/* load preferred value and mask */
+		pref = usb_lang_id;
+		mask = usb_lang_mask;
+
+		/* align length correctly */
+		scratch_ptr[0] &= ~1;
+
+		/* fix compiler warning */
+		langid = 0;
+
+		/* search for preferred language */
+		for (x = 2; (x < scratch_ptr[0]); x += 2) {
+			langid = UGETW(scratch_ptr + x);
+			if ((langid & mask) == pref)
+				break;
+		}
+		if (x >= scratch_ptr[0]) {
+			/* pick the first language as the default */
+			DPRINTFN(1, "Using first language\n");
+			langid = UGETW(scratch_ptr + 2);
+		}
+
+		DPRINTFN(1, "Language selected: 0x%04x\n", langid);
+		udev->langid = langid;
 	}
 
 	/* assume 100mA bus powered for now. Changed when configured. */
@@ -2149,34 +2190,35 @@ usbd_set_device_strings(struct usb_device *udev)
 #ifdef USB_VERBOSE
 	const struct usb_knowndev *kdp;
 #endif
-	char temp[64];
+	uint8_t *temp_ptr;
+	size_t temp_size;
 	uint16_t vendor_id;
 	uint16_t product_id;
 
+	temp_ptr = udev->bus->scratch[0].data;
+	temp_size = sizeof(udev->bus->scratch[0].data);
+
 	vendor_id = UGETW(udd->idVendor);
 	product_id = UGETW(udd->idProduct);
 
 	/* get serial number string */
-	bzero(temp, sizeof(temp));
-	usbd_req_get_string_any(udev, NULL, temp, sizeof(temp),
+	usbd_req_get_string_any(udev, NULL, temp_ptr, temp_size,
 	    udev->ddesc.iSerialNumber);
-	udev->serial = strdup(temp, M_USB);
+	udev->serial = strdup(temp_ptr, M_USB);
 
 	/* get manufacturer string */
-	bzero(temp, sizeof(temp));
-	usbd_req_get_string_any(udev, NULL, temp, sizeof(temp),
+	usbd_req_get_string_any(udev, NULL, temp_ptr, temp_size,
 	    udev->ddesc.iManufacturer);
-	usb_trim_spaces(temp);
-	if (temp[0] != '\0')
-		udev->manufacturer = strdup(temp, M_USB);
+	usb_trim_spaces(temp_ptr);
+	if (temp_ptr[0] != '\0')
+		udev->manufacturer = strdup(temp_ptr, M_USB);
 
 	/* get product string */
-	bzero(temp, sizeof(temp));
-	usbd_req_get_string_any(udev, NULL, temp, sizeof(temp),
+	usbd_req_get_string_any(udev, NULL, temp_ptr, temp_size,
 	    udev->ddesc.iProduct);
-	usb_trim_spaces(temp);
-	if (temp[0] != '\0')
-		udev->product = strdup(temp, M_USB);
+	usb_trim_spaces(temp_ptr);
+	if (temp_ptr[0] != '\0')
+		udev->product = strdup(temp_ptr, M_USB);
 
 #ifdef USB_VERBOSE
 	if (udev->manufacturer == NULL || udev->product == NULL) {
@@ -2202,12 +2244,12 @@ usbd_set_device_strings(struct usb_device *udev)
 #endif
 	/* Provide default strings if none were found */
 	if (udev->manufacturer == NULL) {
-		snprintf(temp, sizeof(temp), "vendor 0x%04x", vendor_id);
-		udev->manufacturer = strdup(temp, M_USB);
+		snprintf(temp_ptr, temp_size, "vendor 0x%04x", vendor_id);
+		udev->manufacturer = strdup(temp_ptr, M_USB);
 	}
 	if (udev->product == NULL) {
-		snprintf(temp, sizeof(temp), "product 0x%04x", product_id);
-		udev->product = strdup(temp, M_USB);
+		snprintf(temp_ptr, temp_size, "product 0x%04x", product_id);
+		udev->product = strdup(temp_ptr, M_USB);
 	}
 }
 

From d81c7ac0fa75c0c9273aee869068a8b815db0582 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:18:27 +0000
Subject: [PATCH 0419/2592] MFC r197561

 Correct buffer sizes used so that they match. The old code could give the
 impression that a overflow situation existed but was not possible.
---
 sys/dev/usb/usb_device.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index b397d35501c..4339cb24777 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -2355,6 +2355,7 @@ usb_notify_addq(const char *type, struct usb_device *udev)
 {
 	char *data = NULL;
 	struct malloc_type *mt;
+	const size_t buf_size = 512;
 
 	mtx_lock(&malloc_mtx);
 	mt = malloc_desc2type("bus");	/* XXX M_BUS */
@@ -2362,12 +2363,12 @@ usb_notify_addq(const char *type, struct usb_device *udev)
 	if (mt == NULL)
 		return;
 
-	data = malloc(512, mt, M_NOWAIT);
+	data = malloc(buf_size, mt, M_NOWAIT);
 	if (data == NULL)
 		return;
 
 	/* String it all together. */
-	snprintf(data, 1024,
+	snprintf(data, buf_size,
 	    "%s"
 	    "%s "
 	    "vendor=0x%04x "

From 57866e6c932193abfd10e6c54bf467502afac2c2 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:18:59 +0000
Subject: [PATCH 0420/2592] MFC r197562

 Add extra safety locking when clobbering xfer->flags_int.started in start and
 stop functions, because xfer->flags_int is also updated by the USB controller,
 under the controller lock.
---
 sys/dev/usb/usb_transfer.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c
index 9a063a12a30..8031b84597b 100644
--- a/sys/dev/usb/usb_transfer.c
+++ b/sys/dev/usb/usb_transfer.c
@@ -1332,7 +1332,9 @@ usbd_setup_ctrl_transfer(struct usb_xfer *xfer)
 	/* check if there is a length mismatch */
 
 	if (len > xfer->flags_int.control_rem) {
-		DPRINTFN(0, "Length greater than remaining length!\n");
+		DPRINTFN(0, "Length (%d) greater than "
+		    "remaining length (%d)!\n", len,
+		    xfer->flags_int.control_rem);
 		goto error;
 	}
 	/* check if we are doing a short transfer */
@@ -1620,7 +1622,10 @@ usbd_transfer_start(struct usb_xfer *xfer)
 	/* mark the USB transfer started */
 
 	if (!xfer->flags_int.started) {
+		/* lock the BUS lock to avoid races updating flags_int */
+		USB_BUS_LOCK(xfer->xroot->bus);
 		xfer->flags_int.started = 1;
+		USB_BUS_UNLOCK(xfer->xroot->bus);
 	}
 	/* check if the USB transfer callback is already transferring */
 
@@ -1655,14 +1660,21 @@ usbd_transfer_stop(struct usb_xfer *xfer)
 	/* check if the USB transfer was ever opened */
 
 	if (!xfer->flags_int.open) {
-		/* nothing to do except clearing the "started" flag */
-		xfer->flags_int.started = 0;
+		if (xfer->flags_int.started) {
+			/* nothing to do except clearing the "started" flag */
+			/* lock the BUS lock to avoid races updating flags_int */
+			USB_BUS_LOCK(xfer->xroot->bus);
+			xfer->flags_int.started = 0;
+			USB_BUS_UNLOCK(xfer->xroot->bus);
+		}
 		return;
 	}
 	/* try to stop the current USB transfer */
 
 	USB_BUS_LOCK(xfer->xroot->bus);
-	xfer->error = USB_ERR_CANCELLED;/* override any previous error */
+	/* override any previous error */
+	xfer->error = USB_ERR_CANCELLED;
+
 	/*
 	 * Clear "open" and "started" when both private and USB lock
 	 * is locked so that we don't get a race updating "flags_int"
@@ -2121,9 +2133,6 @@ usb_dma_delay_done_cb(void *arg)
 
 	DPRINTFN(3, "Completed %p\n", xfer);
 
-	/* only delay once */
-	xfer->flags_int.did_dma_delay = 1;
-
 	/* queue callback for execution, again */
 	usbd_transfer_done(xfer, 0);
 }
@@ -2193,6 +2202,8 @@ usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error)
 	 */
 	if (!xfer->flags_int.transferring) {
 		DPRINTF("not transferring\n");
+		/* end of control transfer, if any */
+		xfer->flags_int.control_act = 0;
 		return;
 	}
 	/* only set transfer error if not already set */
@@ -2491,6 +2502,9 @@ usbd_callback_wrapper_sub(struct usb_xfer *xfer)
 
 		usb_timeout_t temp;
 
+		/* only delay once */
+		xfer->flags_int.did_dma_delay = 1;
+
 		/* we can not cancel this delay */
 		xfer->flags_int.can_cancel_immed = 0;
 

From d66897e03e2f8112ad96097016508fb1963a1de8 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:19:41 +0000
Subject: [PATCH 0421/2592] MFC r197563

 Add basic support for USB Network Control Model (NCM) v1.0 to if_cdce.c.
---
 sys/dev/usb/net/if_cdce.c    | 592 +++++++++++++++++++++++++++++++++--
 sys/dev/usb/net/if_cdcereg.h |  28 +-
 sys/dev/usb/usb.h            |   5 +-
 sys/dev/usb/usb_cdc.h        | 103 ++++++
 4 files changed, 698 insertions(+), 30 deletions(-)

diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c
index 52ea2069311..86f7a9b99bf 100644
--- a/sys/dev/usb/net/if_cdce.c
+++ b/sys/dev/usb/net/if_cdce.c
@@ -40,6 +40,11 @@
  * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
  */
 
+/*
+ * USB Network Control Model (NCM)
+ * http://www.usb.org/developers/devclass_docs/NCM10.zip
+ */
+
 #include 
 __FBSDID("$FreeBSD$");
 
@@ -89,6 +94,11 @@ static usb_callback_t cdce_bulk_read_callback;
 static usb_callback_t cdce_intr_read_callback;
 static usb_callback_t cdce_intr_write_callback;
 
+#if CDCE_HAVE_NCM
+static usb_callback_t cdce_ncm_bulk_write_callback;
+static usb_callback_t cdce_ncm_bulk_read_callback;
+#endif
+
 static uether_fn_t cdce_attach_post;
 static uether_fn_t cdce_init;
 static uether_fn_t cdce_stop;
@@ -159,6 +169,61 @@ static const struct usb_config cdce_config[CDCE_N_TRANSFER] = {
 	},
 };
 
+#if CDCE_HAVE_NCM
+static const struct usb_config cdce_ncm_config[CDCE_N_TRANSFER] = {
+
+	[CDCE_BULK_RX] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_RX,
+		.if_index = 0,
+		.frames = CDCE_NCM_RX_FRAMES_MAX,
+		.bufsize = (CDCE_NCM_RX_FRAMES_MAX * CDCE_NCM_RX_MAXLEN),
+		.flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,},
+		.callback = cdce_ncm_bulk_read_callback,
+		.timeout = 0,	/* no timeout */
+		.usb_mode = USB_MODE_DUAL,	/* both modes */
+	},
+
+	[CDCE_BULK_TX] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_TX,
+		.if_index = 0,
+		.frames = CDCE_NCM_TX_FRAMES_MAX,
+		.bufsize = (CDCE_NCM_TX_FRAMES_MAX * CDCE_NCM_TX_MAXLEN),
+		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
+		.callback = cdce_ncm_bulk_write_callback,
+		.timeout = 10000,	/* 10 seconds */
+		.usb_mode = USB_MODE_DUAL,	/* both modes */
+	},
+
+	[CDCE_INTR_RX] = {
+		.type = UE_INTERRUPT,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_RX,
+		.if_index = 1,
+		.bufsize = CDCE_IND_SIZE_MAX,
+		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,},
+		.callback = cdce_intr_read_callback,
+		.timeout = 0,
+		.usb_mode = USB_MODE_HOST,
+	},
+
+	[CDCE_INTR_TX] = {
+		.type = UE_INTERRUPT,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_TX,
+		.if_index = 1,
+		.bufsize = CDCE_IND_SIZE_MAX,
+		.flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,},
+		.callback = cdce_intr_write_callback,
+		.timeout = 10000,	/* 10 seconds */
+		.usb_mode = USB_MODE_DEVICE,
+	},
+};
+#endif
+
 static device_method_t cdce_methods[] = {
 	/* USB interface */
 	DEVMETHOD(usb_handle_request, cdce_handle_request),
@@ -213,8 +278,151 @@ static const struct usb_device_id cdce_devs[] = {
 
 	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)},
 	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)},
+	{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_NETWORK_CONTROL_MODEL, 0)},
 };
 
+#if CDCE_HAVE_NCM
+/*------------------------------------------------------------------------*
+ *	cdce_ncm_init
+ *
+ * Return values:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+static uint8_t
+cdce_ncm_init(struct cdce_softc *sc)
+{
+	struct usb_ncm_parameters temp;
+	struct usb_device_request req;
+	uDWord value;
+	int err;
+
+	req.bmRequestType = UT_READ_CLASS_INTERFACE;
+	req.bRequest = UCDC_NCM_GET_NTB_PARAMETERS;
+	USETW(req.wValue, 0);
+	req.wIndex[0] = sc->sc_ifaces_index[1];
+	req.wIndex[1] = 0;
+	USETW(req.wLength, sizeof(temp));
+
+	err = usbd_do_request_flags(sc->sc_ue.ue_udev, NULL, &req,
+	    &temp, 0, NULL, 1000 /* ms */);
+	if (err)
+		return (1);
+
+	/* Read correct set of parameters according to device mode */
+
+	if (usbd_get_mode(sc->sc_ue.ue_udev) == USB_MODE_HOST) {
+		sc->sc_ncm.rx_max = UGETW(temp.dwNtbInMaxSize);
+		sc->sc_ncm.tx_max = UGETW(temp.dwNtbOutMaxSize);
+		sc->sc_ncm.tx_remainder = UGETW(temp.wNdpOutPayloadRemainder);
+		sc->sc_ncm.tx_modulus = UGETW(temp.wNdpOutDivisor);
+		sc->sc_ncm.tx_struct_align = UGETW(temp.wNdpOutAlignment);
+	} else {
+		sc->sc_ncm.rx_max = UGETW(temp.dwNtbOutMaxSize);
+		sc->sc_ncm.tx_max = UGETW(temp.dwNtbInMaxSize);
+		sc->sc_ncm.tx_remainder = UGETW(temp.wNdpInPayloadRemainder);
+		sc->sc_ncm.tx_modulus = UGETW(temp.wNdpInDivisor);
+		sc->sc_ncm.tx_struct_align = UGETW(temp.wNdpInAlignment);
+	}
+
+	/* Verify maximum receive length */
+
+	if (err || (sc->sc_ncm.rx_max < 32) || 
+	    (sc->sc_ncm.rx_max > CDCE_NCM_RX_MAXLEN)) {
+		DPRINTFN(1, "Using default maximum receive length\n");
+		sc->sc_ncm.rx_max = CDCE_NCM_RX_MAXLEN;
+	}
+
+	/* Verify maximum transmit length */
+
+	if (err || (sc->sc_ncm.tx_max < 32) ||
+	    (sc->sc_ncm.tx_max > CDCE_NCM_TX_MAXLEN)) {
+		DPRINTFN(1, "Using default maximum transmit length\n");
+		sc->sc_ncm.tx_max = CDCE_NCM_TX_MAXLEN;
+	}
+
+	/* 
+	 * Verify that the structure alignment is:
+	 * - power of two
+	 * - not greater than the maximum transmit length
+	 * - not less than four bytes
+	 */
+	if (err || (sc->sc_ncm.tx_struct_align < 4) ||
+	    (sc->sc_ncm.tx_struct_align != 
+	     ((-sc->sc_ncm.tx_struct_align) & sc->sc_ncm.tx_struct_align)) ||
+	    (sc->sc_ncm.tx_struct_align >= sc->sc_ncm.tx_max)) {
+		DPRINTFN(1, "Using default other alignment: 4 bytes\n");
+		sc->sc_ncm.tx_struct_align = 4;
+	}
+
+	/* 
+	 * Verify that the payload alignment is:
+	 * - power of two
+	 * - not greater than the maximum transmit length
+	 * - not less than four bytes
+	 */
+	if (err || (sc->sc_ncm.tx_modulus < 4) ||
+	    (sc->sc_ncm.tx_modulus !=
+	     ((-sc->sc_ncm.tx_modulus) & sc->sc_ncm.tx_modulus)) ||
+	    (sc->sc_ncm.tx_modulus >= sc->sc_ncm.tx_max)) {
+		DPRINTFN(1, "Using default transmit modulus: 4 bytes\n");
+		sc->sc_ncm.tx_modulus = 4;
+	}
+
+	/* Verify that the payload remainder */
+
+	if (err || (sc->sc_ncm.tx_remainder >= sc->sc_ncm.tx_modulus)) {
+		DPRINTFN(1, "Using default transmit remainder: 0 bytes\n");
+		sc->sc_ncm.tx_remainder = 0;
+	}
+
+	/* Additional configuration, will fail in device side mode, which is OK. */
+
+	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+	req.bRequest = UCDC_NCM_SET_NTB_INPUT_SIZE;
+	USETW(req.wValue, 0);
+	req.wIndex[0] = sc->sc_ifaces_index[1];
+	req.wIndex[1] = 0;
+	USETW(req.wLength, 4);
+	USETDW(value, sc->sc_ncm.rx_max);
+
+	err = usbd_do_request_flags(sc->sc_ue.ue_udev, NULL, &req,
+	    &value, 0, NULL, 1000 /* ms */);
+	if (err) {
+		DPRINTFN(1, "Setting input size "
+		    "to %u failed.\n", sc->sc_ncm.rx_max);
+	}
+
+	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+	req.bRequest = UCDC_NCM_SET_CRC_MODE;
+	USETW(req.wValue, 0);	/* no CRC */
+	req.wIndex[0] = sc->sc_ifaces_index[1];
+	req.wIndex[1] = 0;
+	USETW(req.wLength, 0);
+
+	err = usbd_do_request_flags(sc->sc_ue.ue_udev, NULL, &req,
+	    NULL, 0, NULL, 1000 /* ms */);
+	if (err) {
+		DPRINTFN(1, "Setting CRC mode to off failed.\n");
+	}
+
+	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+	req.bRequest = UCDC_NCM_SET_NTB_FORMAT;
+	USETW(req.wValue, 0);	/* NTB-16 */
+	req.wIndex[0] = sc->sc_ifaces_index[1];
+	req.wIndex[1] = 0;
+	USETW(req.wLength, 0);
+
+	err = usbd_do_request_flags(sc->sc_ue.ue_udev, NULL, &req,
+	    NULL, 0, NULL, 1000 /* ms */);
+	if (err) {
+		DPRINTFN(1, "Setting NTB format to 16-bit failed.\n");
+	}
+
+	return (0);		/* success */
+}
+#endif
+
 static int
 cdce_probe(device_t dev)
 {
@@ -240,31 +448,31 @@ cdce_attach(device_t dev)
 	const struct usb_cdc_union_descriptor *ud;
 	const struct usb_interface_descriptor *id;
 	const struct usb_cdc_ethernet_descriptor *ued;
+	const struct usb_config *pcfg;
 	int error;
 	uint8_t i;
+	uint8_t data_iface_no;
 	char eaddr_str[5 * ETHER_ADDR_LEN];	/* approx */
 
 	sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
+	sc->sc_ue.ue_udev = uaa->device;
 
 	device_set_usb_desc(dev);
 
 	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
 
-	if (sc->sc_flags & CDCE_FLAG_NO_UNION) {
-		sc->sc_ifaces_index[0] = uaa->info.bIfaceIndex;
-		sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex;
-		sc->sc_data_iface_no = 0;	/* not used */
-		goto alloc_transfers;
-	}
 	ud = usbd_find_descriptor
 	    (uaa->device, NULL, uaa->info.bIfaceIndex,
 	    UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_UNION, 0 - 1);
 
-	if ((ud == NULL) || (ud->bLength < sizeof(*ud))) {
-		device_printf(dev, "no union descriptor!\n");
-		goto detach;
+	if ((ud == NULL) || (ud->bLength < sizeof(*ud)) ||
+	    (sc->sc_flags & CDCE_FLAG_NO_UNION)) {
+		DPRINTFN(1, "No union descriptor!\n");
+		sc->sc_ifaces_index[0] = uaa->info.bIfaceIndex;
+		sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex;
+		goto alloc_transfers;
 	}
-	sc->sc_data_iface_no = ud->bSlaveInterface[0];
+	data_iface_no = ud->bSlaveInterface[0];
 
 	for (i = 0;; i++) {
 
@@ -274,8 +482,7 @@ cdce_attach(device_t dev)
 
 			id = usbd_get_interface_descriptor(iface);
 
-			if (id && (id->bInterfaceNumber ==
-			    sc->sc_data_iface_no)) {
+			if (id && (id->bInterfaceNumber == data_iface_no)) {
 				sc->sc_ifaces_index[0] = i;
 				sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex;
 				usbd_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
@@ -312,24 +519,30 @@ cdce_attach(device_t dev)
 
 alloc_transfers:
 
+	pcfg = cdce_config;	/* Default Configuration */
+
 	for (i = 0; i != 32; i++) {
 
-		error = usbd_set_alt_interface_index
-		    (uaa->device, sc->sc_ifaces_index[0], i);
-
-		if (error) {
-			device_printf(dev, "no valid alternate "
-			    "setting found!\n");
-			goto detach;
-		}
-		error = usbd_transfer_setup
-		    (uaa->device, sc->sc_ifaces_index,
-		    sc->sc_xfer, cdce_config, CDCE_N_TRANSFER,
-		    sc, &sc->sc_mtx);
-
-		if (error == 0) {
+		error = usbd_set_alt_interface_index(uaa->device,
+		    sc->sc_ifaces_index[0], i);
+		if (error)
 			break;
-		}
+#if CDCE_HAVE_NCM
+		if ((i == 0) && (cdce_ncm_init(sc) == 0))
+			pcfg = cdce_ncm_config;
+#endif
+		error = usbd_transfer_setup(uaa->device,
+		    sc->sc_ifaces_index, sc->sc_xfer,
+		    pcfg, CDCE_N_TRANSFER, sc, &sc->sc_mtx);
+
+		if (error == 0)
+			break;
+	}
+
+	if (error || (i == 32)) {
+		device_printf(dev, "No valid alternate "
+		    "setting found!\n");
+		goto detach;
 	}
 
 	ued = usbd_find_descriptor
@@ -768,3 +981,328 @@ cdce_handle_request(device_t dev,
 {
 	return (ENXIO);			/* use builtin handler */
 }
+
+#if CDCE_HAVE_NCM
+static uint8_t
+cdce_ncm_fill_tx_frames(struct usb_xfer *xfer, uint8_t index)
+{
+	struct cdce_softc *sc = usbd_xfer_softc(xfer);
+	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
+	struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, index);
+	struct mbuf *m;
+	uint32_t rem;
+	uint32_t offset;
+	uint32_t last_offset;
+	uint32_t n;
+
+	usbd_xfer_set_frame_offset(xfer, index * CDCE_NCM_TX_MAXLEN, index);
+
+	offset = sizeof(sc->sc_ncm.hdr) +
+	    sizeof(sc->sc_ncm.dpt) + sizeof(sc->sc_ncm.dp);
+
+	/* Store last valid offset before alignment */
+	last_offset = offset;
+
+	/* Align offset correctly */
+	offset = sc->sc_ncm.tx_remainder -
+	    ((0UL - offset) & (0UL - sc->sc_ncm.tx_modulus));
+
+	for (n = 0; n != CDCE_NCM_SUBFRAMES_MAX; n++) {
+
+		/* check if end of transmit buffer is reached */
+
+		if (offset >= sc->sc_ncm.tx_max)
+			break;
+
+		/* compute maximum buffer size */
+
+		rem = sc->sc_ncm.tx_max - offset;
+
+		IFQ_DRV_DEQUEUE(&(ifp->if_snd), m);
+
+		if (m == NULL)
+			break;
+
+		if (m->m_pkthdr.len > rem) {
+			if (n == 0) {
+				/* The frame won't fit in our buffer */
+				DPRINTFN(1, "Frame too big to be transmitted!\n");
+				m_freem(m);
+				ifp->if_oerrors++;
+				n--;
+				continue;
+			}
+			/* Wait till next buffer becomes ready */
+			IFQ_DRV_PREPEND(&(ifp->if_snd), m);
+			break;
+		}
+		usbd_m_copy_in(pc, offset, m, 0, m->m_pkthdr.len);
+
+		USETW(sc->sc_ncm.dp[n].wFrameLength, m->m_pkthdr.len);
+		USETW(sc->sc_ncm.dp[n].wFrameIndex, offset);
+
+		/* Update offset */
+		offset += m->m_pkthdr.len;
+
+		/* Store last valid offset before alignment */
+		last_offset = offset;
+
+		/* Align offset correctly */
+		offset = sc->sc_ncm.tx_remainder - 
+		    ((0UL - offset) & (0UL - sc->sc_ncm.tx_modulus));
+
+		/*
+		 * If there's a BPF listener, bounce a copy
+		 * of this frame to him:
+		 */
+		BPF_MTAP(ifp, m);
+
+		/* Free mbuf */
+
+		m_freem(m);
+
+		/* Pre-increment interface counter */
+
+		ifp->if_opackets++;
+	}
+
+	if (n == 0)
+		return (1);
+
+	rem = (sizeof(sc->sc_ncm.dpt) + (4 * n) + 4);
+
+	USETW(sc->sc_ncm.dpt.wLength, rem);
+
+	/* zero the rest of the data pointer entries */
+	for (; n != CDCE_NCM_SUBFRAMES_MAX; n++) {
+		USETW(sc->sc_ncm.dp[n].wFrameLength, 0);
+		USETW(sc->sc_ncm.dp[n].wFrameIndex, 0);
+	}
+
+	/* set frame length */
+	usbd_xfer_set_frame_len(xfer, index, last_offset);
+
+	/* Fill out 16-bit header */
+	sc->sc_ncm.hdr.dwSignature[0] = 'N';
+	sc->sc_ncm.hdr.dwSignature[1] = 'C';
+	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.wSequence, sc->sc_ncm.tx_seq);
+	USETW(sc->sc_ncm.hdr.wDptIndex, sizeof(sc->sc_ncm.hdr));
+
+	sc->sc_ncm.tx_seq++;
+
+	/* Fill out 16-bit frame table header */
+	sc->sc_ncm.dpt.dwSignature[0] = 'N';
+	sc->sc_ncm.dpt.dwSignature[1] = 'C';
+	sc->sc_ncm.dpt.dwSignature[2] = 'M';
+	sc->sc_ncm.dpt.dwSignature[3] = 'x';
+	USETW(sc->sc_ncm.dpt.wNextNdpIndex, 0);		/* reserved */
+
+	usbd_copy_in(pc, 0, &(sc->sc_ncm.hdr), sizeof(sc->sc_ncm.hdr));
+	usbd_copy_in(pc, sizeof(sc->sc_ncm.hdr), &(sc->sc_ncm.dpt),
+	    sizeof(sc->sc_ncm.dpt));
+	usbd_copy_in(pc, sizeof(sc->sc_ncm.hdr) + sizeof(sc->sc_ncm.dpt),
+	    &(sc->sc_ncm.dp), sizeof(sc->sc_ncm.dp));
+	return (0);
+}
+
+static void
+cdce_ncm_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct cdce_softc *sc = usbd_xfer_softc(xfer);
+	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
+	uint16_t x;
+	int actlen;
+	int aframes;
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+
+		usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL);
+
+		DPRINTFN(10, "transfer complete: "
+		    "%u bytes in %u frames\n", actlen, aframes);
+
+	case USB_ST_SETUP:
+		for (x = 0; x != CDCE_NCM_TX_FRAMES_MAX; x++) {
+			if (cdce_ncm_fill_tx_frames(xfer, x))
+				break;
+		}
+
+		if (x != 0) {
+			usbd_xfer_set_frames(xfer, x);
+			usbd_transfer_submit(xfer);
+		}
+		break;
+
+	default:			/* Error */
+		DPRINTFN(10, "Transfer error: %s\n",
+		    usbd_errstr(error));
+
+		/* update error counter */
+		ifp->if_oerrors += 1;
+
+		if (error != USB_ERR_CANCELLED) {
+			/* try to clear stall first */
+			usbd_xfer_set_stall(xfer);
+			usbd_xfer_set_frames(xfer, 0);
+			usbd_transfer_submit(xfer);
+		}
+		break;
+	}
+}
+
+static void
+cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct cdce_softc *sc = usbd_xfer_softc(xfer);
+	struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, 0);
+	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
+	struct mbuf *m;
+	int sumdata;
+	int sumlen;
+	int actlen;
+	int aframes;
+	int temp;
+	int nframes;
+	int x;
+	int offset;
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+
+		usbd_xfer_status(xfer, &actlen, &sumlen, &aframes, NULL);
+
+		DPRINTFN(1, "received %u bytes in %u frames\n",
+		    actlen, aframes);
+
+		if (actlen < (sizeof(sc->sc_ncm.hdr) +
+		    sizeof(sc->sc_ncm.dpt))) {
+			DPRINTFN(1, "frame too short\n");
+			goto tr_stall;
+		}
+		usbd_copy_out(pc, 0, &(sc->sc_ncm.hdr),
+		    sizeof(sc->sc_ncm.hdr));
+
+		if ((sc->sc_ncm.hdr.dwSignature[0] != 'N') ||
+		    (sc->sc_ncm.hdr.dwSignature[1] != 'C') ||
+		    (sc->sc_ncm.hdr.dwSignature[2] != 'M') ||
+		    (sc->sc_ncm.hdr.dwSignature[3] != 'H')) {
+			DPRINTFN(1, "invalid HDR signature\n");
+			goto tr_stall;
+		}
+		temp = UGETW(sc->sc_ncm.hdr.wBlockLength);
+		if (temp > sumlen) {
+			DPRINTFN(1, "unsupported block length %u/%u\n",
+			    temp, sumlen);
+			goto tr_stall;
+		}
+		temp = UGETW(sc->sc_ncm.hdr.wDptIndex);
+		if ((temp + sizeof(sc->sc_ncm.dpt)) > actlen) {
+			DPRINTFN(1, "invalid DPT index\n");
+			goto tr_stall;
+		}
+		usbd_copy_out(pc, temp, &(sc->sc_ncm.dpt),
+		    sizeof(sc->sc_ncm.dpt));
+
+		if ((sc->sc_ncm.dpt.dwSignature[0] != 'N') ||
+		    (sc->sc_ncm.dpt.dwSignature[1] != 'C') ||
+		    (sc->sc_ncm.dpt.dwSignature[2] != 'M') ||
+		    (sc->sc_ncm.dpt.dwSignature[3] != 'x')) {
+			DPRINTFN(1, "invalid DPT signature\n");
+			goto tr_stall;
+		}
+		nframes = UGETW(sc->sc_ncm.dpt.wLength) / 4;
+
+		/* Subtract size of header and last zero padded entry */
+		if (nframes >= (2 + 1))
+			nframes -= (2 + 1);
+		else
+			nframes = 0;
+
+		DPRINTFN(1, "nframes = %u\n", nframes);
+
+		temp += sizeof(sc->sc_ncm.dpt);
+
+		if ((temp + (4 * nframes)) > actlen)
+			goto tr_stall;
+
+		if (nframes > CDCE_NCM_SUBFRAMES_MAX) {
+			DPRINTFN(1, "Truncating number of frames from %u to %u\n",
+			    nframes, CDCE_NCM_SUBFRAMES_MAX);
+			nframes = CDCE_NCM_SUBFRAMES_MAX;
+		}
+		usbd_copy_out(pc, temp, &(sc->sc_ncm.dp), (4 * nframes));
+
+		sumdata = 0;
+
+		for (x = 0; x != nframes; x++) {
+
+			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);
+				}
+			} else {
+				m = NULL;	/* dump it */
+			}
+
+			DPRINTFN(16, "frame %u, offset = %u, length = %u \n",
+			    x, offset, temp);
+
+			/* check if we have a buffer */
+			if (m) {
+				m_adj(m, ETHER_ALIGN);
+
+				usbd_copy_out(pc, offset, m->m_data, temp);
+
+				/* enqueue */
+				uether_rxmbuf(&sc->sc_ue, m, temp);
+
+				sumdata += temp;
+			} else {
+				ifp->if_ierrors++;
+			}
+		}
+
+		DPRINTFN(1, "Efficiency: %u/%u bytes\n", sumdata, actlen);
+
+	case USB_ST_SETUP:
+		usbd_xfer_set_frame_len(xfer, 0, sc->sc_ncm.rx_max);
+		usbd_xfer_set_frames(xfer, 1);
+		usbd_transfer_submit(xfer);
+		uether_rxflush(&sc->sc_ue);	/* must be last */
+		break;
+
+	default:			/* Error */
+		DPRINTFN(1, "error = %s\n",
+		    usbd_errstr(error));
+
+		if (error != USB_ERR_CANCELLED) {
+tr_stall:
+			/* try to clear stall first */
+			usbd_xfer_set_stall(xfer);
+			usbd_xfer_set_frames(xfer, 0);
+			usbd_transfer_submit(xfer);
+		}
+		break;
+	}
+}
+#endif
diff --git a/sys/dev/usb/net/if_cdcereg.h b/sys/dev/usb/net/if_cdcereg.h
index 367e1677a3e..55931698b63 100644
--- a/sys/dev/usb/net/if_cdcereg.h
+++ b/sys/dev/usb/net/if_cdcereg.h
@@ -38,6 +38,18 @@
 #define	CDCE_FRAMES_MAX	8		/* units */
 #define	CDCE_IND_SIZE_MAX 32            /* bytes */
 
+#define	CDCE_NCM_TX_MAXLEN 2048UL	/* bytes */
+#define	CDCE_NCM_TX_FRAMES_MAX 8	/* units */
+
+#define	CDCE_NCM_RX_MAXLEN (1UL << 14)	/* bytes */
+#define	CDCE_NCM_RX_FRAMES_MAX 1	/* units */
+
+#define	CDCE_NCM_SUBFRAMES_MAX 32	/* units */
+
+#ifndef CDCE_HAVE_NCM
+#define	CDCE_HAVE_NCM 1
+#endif
+
 enum {
 	CDCE_BULK_RX,
 	CDCE_BULK_TX,
@@ -46,9 +58,24 @@ enum {
 	CDCE_N_TRANSFER,
 };
 
+struct cdce_ncm {
+	struct usb_ncm16_hdr hdr;
+	struct usb_ncm16_dpt dpt;
+	struct usb_ncm16_dp dp[CDCE_NCM_SUBFRAMES_MAX];
+	uint32_t rx_max;
+	uint32_t tx_max;
+	uint16_t tx_remainder;
+	uint16_t tx_modulus;
+	uint16_t tx_struct_align;
+	uint16_t tx_seq;
+};
+
 struct cdce_softc {
 	struct usb_ether	sc_ue;
 	struct mtx		sc_mtx;
+#if CDCE_HAVE_NCM
+	struct cdce_ncm		sc_ncm;
+#endif
 	struct usb_xfer	*sc_xfer[CDCE_N_TRANSFER];
 	struct mbuf		*sc_rx_buf[CDCE_FRAMES_MAX];
 	struct mbuf		*sc_tx_buf[CDCE_FRAMES_MAX];
@@ -59,7 +86,6 @@ struct cdce_softc {
 #define	CDCE_FLAG_RX_DATA	0x0010
 
 	uint8_t sc_eaddr_str_index;
-	uint8_t	sc_data_iface_no;
 	uint8_t	sc_ifaces_index[2];
 };
 
diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h
index 119839831c1..8ebaeecb720 100644
--- a/sys/dev/usb/usb.h
+++ b/sys/dev/usb/usb.h
@@ -424,9 +424,9 @@ typedef struct usb_interface_assoc_descriptor usb_interface_assoc_descriptor_t;
 #define	UISUBCLASS_MOBILE_DIRECT_LINE_MODEL 10
 #define	UISUBCLASS_OBEX 11
 #define	UISUBCLASS_ETHERNET_EMULATION_MODEL 12
+#define	UISUBCLASS_NETWORK_CONTROL_MODEL 13
 
 #define	UIPROTO_CDC_AT			1
-#define	UIPROTO_CDC_ETH_512X4 0x76	/* FreeBSD specific */
 
 #define	UICLASS_HID		0x03
 #define	UISUBCLASS_BOOT		1
@@ -461,7 +461,7 @@ typedef struct usb_interface_assoc_descriptor usb_interface_assoc_descriptor_t;
 #define	UIPROTO_HSHUBMTT	1
 
 #define	UICLASS_CDC_DATA	0x0a
-#define	UISUBCLASS_DATA		0
+#define	UISUBCLASS_DATA		0x00
 #define	UIPROTO_DATA_ISDNBRI		0x30	/* Physical iface */
 #define	UIPROTO_DATA_HDLC		0x31	/* HDLC */
 #define	UIPROTO_DATA_TRANSPARENT	0x32	/* Transparent */
@@ -475,6 +475,7 @@ typedef struct usb_interface_assoc_descriptor usb_interface_assoc_descriptor_t;
 #define	UIPROTO_DATA_HOST_BASED		0xfd	/* Host based driver */
 #define	UIPROTO_DATA_PUF		0xfe	/* see Prot. Unit Func. Desc. */
 #define	UIPROTO_DATA_VENDOR		0xff	/* Vendor specific */
+#define	UIPROTO_DATA_NCM		0x01	/* Network Control Model */
 
 #define	UICLASS_SMARTCARD	0x0b
 #define	UICLASS_FIRM_UPD	0x0c
diff --git a/sys/dev/usb/usb_cdc.h b/sys/dev/usb/usb_cdc.h
index f6e312c99a5..7032bf44af0 100644
--- a/sys/dev/usb/usb_cdc.h
+++ b/sys/dev/usb/usb_cdc.h
@@ -188,4 +188,107 @@ struct usb_cdc_notification {
 #define	UCDC_MDM_PARITY_ERR		0x20
 #define	UCDC_MDM_OVERRUN_ERR		0x40
 
+/*
+ * Network Control Model, NCM16 + NCM32, protocol definitions
+ */
+struct usb_ncm16_hdr {
+	uDWord	dwSignature;
+	uWord	wHeaderLength;
+	uWord	wSequence;
+	uWord	wBlockLength;
+	uWord	wDptIndex;
+} __packed;
+
+struct usb_ncm16_dp {
+	uWord	wFrameIndex;
+	uWord	wFrameLength;
+} __packed;
+
+struct usb_ncm16_dpt {
+	uDWord	dwSignature;
+	uWord	wLength;
+	uWord	wNextNdpIndex;
+	struct usb_ncm16_dp dp[0];
+} __packed;
+
+struct usb_ncm32_hdr {
+	uDWord	dwSignature;
+	uWord	wHeaderLength;
+	uWord	wSequence;
+	uDWord	dwBlockLength;
+	uDWord	dwDptIndex;
+} __packed;
+
+struct usb_ncm32_dp {
+	uDWord	dwFrameIndex;
+	uDWord	dwFrameLength;
+} __packed;
+
+struct usb_ncm32_dpt {
+	uDWord	dwSignature;
+	uWord	wLength;
+	uWord	wReserved6;
+	uDWord	dwNextNdpIndex;
+	uDWord	dwReserved12;
+	struct usb_ncm32_dp dp[0];
+} __packed;
+
+/* Communications interface class specific descriptors */
+
+#define	UCDC_NCM_FUNC_DESC_SUBTYPE	0x1A
+
+struct usb_ncm_func_descriptor {
+	uByte	bLength;
+	uByte	bDescriptorType;
+	uByte	bDescriptorSubtype;
+	uByte	bcdNcmVersion[2];
+	uByte	bmNetworkCapabilities;
+#define	UCDC_NCM_CAP_FILTER	0x01
+#define	UCDC_NCM_CAP_MAC_ADDR	0x02
+#define	UCDC_NCM_CAP_ENCAP	0x04
+#define	UCDC_NCM_CAP_MAX_DATA	0x08
+#define	UCDC_NCM_CAP_CRCMODE	0x10
+} __packed;
+
+/* Communications interface specific class request codes */
+
+#define	UCDC_NCM_SET_ETHERNET_MULTICAST_FILTERS			0x40
+#define	UCDC_NCM_SET_ETHERNET_POWER_MGMT_PATTERN_FILTER		0x41
+#define	UCDC_NCM_GET_ETHERNET_POWER_MGMT_PATTERN_FILTER		0x42
+#define	UCDC_NCM_SET_ETHERNET_PACKET_FILTER			0x43
+#define	UCDC_NCM_GET_ETHERNET_STATISTIC				0x44
+#define	UCDC_NCM_GET_NTB_PARAMETERS				0x80
+#define	UCDC_NCM_GET_NET_ADDRESS				0x81
+#define	UCDC_NCM_SET_NET_ADDRESS				0x82
+#define	UCDC_NCM_GET_NTB_FORMAT					0x83
+#define	UCDC_NCM_SET_NTB_FORMAT					0x84
+#define	UCDC_NCM_GET_NTB_INPUT_SIZE				0x85
+#define	UCDC_NCM_SET_NTB_INPUT_SIZE				0x86
+#define	UCDC_NCM_GET_MAX_DATAGRAM_SIZE				0x87
+#define	UCDC_NCM_SET_MAX_DATAGRAM_SIZE				0x88
+#define	UCDC_NCM_GET_CRC_MODE					0x89
+#define	UCDC_NCM_SET_CRC_MODE					0x8A
+
+struct usb_ncm_parameters {
+	uWord	wLength;
+	uWord	bmNtbFormatsSupported;
+#define	UCDC_NCM_FORMAT_NTB16	0x0001
+#define	UCDC_NCM_FORMAT_NTB32	0x0002
+	uDWord	dwNtbInMaxSize;
+	uWord	wNdpInDivisor;
+	uWord	wNdpInPayloadRemainder;
+	uWord	wNdpInAlignment;
+	uWord	wReserved14;
+	uDWord	dwNtbOutMaxSize;
+	uWord	wNdpOutDivisor;
+	uWord	wNdpOutPayloadRemainder;
+	uWord	wNdpOutAlignment;
+	uWord	wReserved26;
+} __packed;
+
+/* Communications interface specific class notification codes */
+#define	UCDC_NCM_NOTIF_NETWORK_CONNECTION	0x00
+#define	UCDC_NCM_NOTIF_RESPONSE_AVAILABLE	0x01
+#define	UCDC_NCM_NOTIF_CONNECTION_SPEED_CHANGE	0x2A
+
 #endif					/* _USB_CDC_H_ */

From 078da8310005b23f1a7fa5a768fa450eac23f347 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:20:15 +0000
Subject: [PATCH 0422/2592] MFC r197564

 Add new usbdev entries for Marvell, FTDI, Option and Western.
---
 sys/dev/usb/usbdevs | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 3cb6a3ae82a..17285b3cec1 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -659,6 +659,7 @@ vendor 3COM2		0x6891	3Com
 vendor INTEL		0x8086	Intel
 vendor SITECOM2		0x9016	Sitecom
 vendor MOSCHIP		0x9710	MosChip Semiconductor
+vendor MARVELL		0x9e88	Marvell Technology Group Ltd.
 vendor 3COM3		0xa727	3Com
 vendor HP2		0xf003	Hewlett Packard
 vendor USRP		0xfffe	GNU Radio USRP
@@ -1336,6 +1337,9 @@ product FTDI CFA_633		0xfc0b	Crystalfontz CFA-633 USB LCD
 product FTDI CFA_631		0xfc0c	Crystalfontz CFA-631 USB LCD
 product FTDI CFA_635		0xfc0d	Crystalfontz CFA-635 USB LCD
 product FTDI SEMC_DSS20		0xfc82	SEMC DSS-20 SyncStation
+/* Commerzielle und Technische Informationssysteme GmbH products */
+product FTDI CTI_USB_NANO_485	0xf60b	CTI USB-Nano 485
+product FTDI CTI_USB_MINI_485	0xf608	CTI USB-Mini 485
 
 /* Fuji photo products */
 product FUJIPHOTO MASS0100	0x0100	Mass Storage
@@ -1691,6 +1695,9 @@ product LUWEN EASYDISK		0x0005	EasyDisc
 /* Macally products */
 product MACALLY MOUSE1		0x0101	mouse
 
+/* Marvell Technology Group, Ltd. products */
+product MARVELL SHEEVAPLUG	0x9e8f	SheevaPlug serial interface
+
 /* MCT Corp. */
 product MCT HUB0100		0x0100	Hub
 product MCT DU_H3SP_USB232	0x0200	D-Link DU-H3SP USB BAY Hub
@@ -1940,6 +1947,8 @@ product OPTION GTICON322	0xd033	GlobeTrotter Icon322 storage
 product OPTION GTMAX36		0x6701	GlobeTrotter Max 3.6 Modem
 product OPTION GTHSDPA		0x6971	GlobeTrotter HSDPA
 product OPTION GTMAXHSUPA	0x7001	GlobeTrotter HSUPA
+product OPTION GTMAXHSUPAE	0x6901	GlobeTrotter HSUPA PCIe
+product OPTION GTMAX380HSUPAE	0x7211	GlobeTrotter 380HSUPA PCIe
 
 /* OQO */
 product OQO WIFI01		0x0002	model 01 WiFi interface
@@ -2504,6 +2513,7 @@ product WESTERN COMBO		0x0200	Firewire USB Combo
 product WESTERN EXTHDD		0x0400	External HDD
 product WESTERN HUB		0x0500	USB HUB
 product WESTERN MYBOOK		0x0901	MyBook External HDD
+product WESTERN MYPASSWORD	0x0704	MyPassword External HDD
 
 /* Windbond Electronics */
 product WINBOND UH104		0x5518	4-port USB Hub

From c21bee0c3645e0d60228f60f5f086181b719f44e Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:20:47 +0000
Subject: [PATCH 0423/2592] MFC r197565

 - Remove SAMSUNG_YP_U2 now that it is in the cam layer
 - Add quirk from Tobias Grosser for Western Mypassword
---
 sys/dev/usb/storage/umass.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
index a8aa951f29c..914a36e9903 100644
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -750,10 +750,6 @@ static const struct umass_devdescr umass_devdescr[] = {
 		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 		IGNORE_RESIDUE | NO_START_STOP
 	},
-	{USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_YP_U2, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		SHUTTLE_INIT | NO_GETMAXLUN
-	},
 	{USB_VENDOR_SAMSUNG_TECHWIN, USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, RID_WILDCARD,
 		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 		NO_INQUIRY
@@ -950,6 +946,10 @@ static const struct umass_devdescr umass_devdescr[] = {
 		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 		NO_INQUIRY_EVPD
 	},
+	{USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSWORD, RID_WILDCARD,
+		UMASS_PROTO_DEFAULT,
+		FORCE_SHORT_INQUIRY
+	},
 	{USB_VENDOR_WINMAXGROUP, USB_PRODUCT_WINMAXGROUP_FLASH64MC, RID_WILDCARD,
 		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 		NO_INQUIRY

From 381882bf15dfde2c8c6fce413dece2499ed85474 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:21:20 +0000
Subject: [PATCH 0424/2592] MFC r197566

 Increase the rx buffer size to 16384 bytes, this increases RX performance from
 50Mbps to 220Mbps on PLANEX GU-1000T.
---
 sys/dev/usb/net/if_axe.c | 55 +++++++++++++++++++---------------------
 1 file changed, 26 insertions(+), 29 deletions(-)

diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c
index ae9d5127ff7..e94154a6975 100644
--- a/sys/dev/usb/net/if_axe.c
+++ b/sys/dev/usb/net/if_axe.c
@@ -205,10 +205,7 @@ static const struct usb_config axe_config[AXE_N_TRANSFER] = {
 		.type = UE_BULK,
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_IN,
-#if (MCLBYTES < 2048)
-#error "(MCLBYTES < 2048)"
-#endif
-		.bufsize = MCLBYTES,
+		.bufsize = 16384,	/* bytes */
 		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
 		.callback = axe_bulk_read_callback,
 		.timeout = 0,	/* no timeout */
@@ -777,7 +774,7 @@ axe_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
 	struct ifnet *ifp = uether_getifp(ue);
 	struct axe_sframe_hdr hdr;
 	struct usb_page_cache *pc;
-	int err, pos, len, adjust;
+	int err, pos, len;
 	int actlen;
 
 	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
@@ -785,50 +782,42 @@ axe_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
 	switch (USB_GET_STATE(xfer)) {
 	case USB_ST_TRANSFERRED:
 		pos = 0;
+		len = 0;
+		err = 0;
+
 		pc = usbd_xfer_get_frame(xfer, 0);
-		while (1) {
-			if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) {
-				if (actlen < sizeof(hdr)) {
+		if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) {
+			while (pos < actlen) {
+				if ((pos + sizeof(hdr)) > actlen) {
 					/* too little data */
+					err = EINVAL;
 					break;
 				}
 				usbd_copy_out(pc, pos, &hdr, sizeof(hdr));
 
 				if ((hdr.len ^ hdr.ilen) != 0xFFFF) {
 					/* we lost sync */
+					err = EINVAL;
 					break;
 				}
-				actlen -= sizeof(hdr);
 				pos += sizeof(hdr);
 
 				len = le16toh(hdr.len);
-				if (len > actlen) {
+				if ((pos + len) > actlen) {
 					/* invalid length */
+					err = EINVAL;
 					break;
 				}
-				adjust = (len & 1);
+				err = uether_rxbuf(ue, pc, pos, len);
 
-			} else {
-				len = actlen;
-				adjust = 0;
+				pos += len + (len % 2);
 			}
-			err = uether_rxbuf(ue, pc, pos, len);
-			if (err)
-				break;
-
-			pos += len;
-			actlen -= len;
-
-			if (actlen <= adjust) {
-				/* we are finished */
-				goto tr_setup;
-			}
-			pos += adjust;
-			actlen -= adjust;
+		} else {
+			err = uether_rxbuf(ue, pc, 0, actlen);
 		}
 
-		/* count an error */
-		ifp->if_ierrors++;
+		if (err != 0)
+			ifp->if_ierrors++;
 
 		/* FALLTHROUGH */
 	case USB_ST_SETUP:
@@ -1011,7 +1000,15 @@ axe_init(struct usb_ether *ue)
 	/* Enable receiver, set RX mode */
 	rxmode = (AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE);
 	if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) {
+#if 0
 		rxmode |= AXE_178_RXCMD_MFB_2048;	/* chip default */
+#else
+		/*
+		 * Default Rx buffer size is too small to get
+		 * maximum performance.
+		 */
+		rxmode |= AXE_178_RXCMD_MFB_16384;
+#endif
 	} else {
 		rxmode |= AXE_172_RXCMD_UNICAST;
 	}

From 9d2344fb86b0f4340fa40464cc2ad7e2015bbd6f Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:21:52 +0000
Subject: [PATCH 0425/2592] MFC r197567

 Allow setting of MAC address for AXE based ethernet adapters.
---
 sys/dev/usb/net/if_axe.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c
index e94154a6975..eca726810fc 100644
--- a/sys/dev/usb/net/if_axe.c
+++ b/sys/dev/usb/net/if_axe.c
@@ -982,10 +982,11 @@ axe_init(struct usb_ether *ue)
 	/* Cancel pending I/O */
 	axe_stop(ue);
 
-#ifdef notdef
-	/* Set MAC address */
-	axe_mac(sc, IF_LLADDR(ifp), 1);
-#endif
+	/* Set MAC address. */
+	if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772))
+		axe_cmd(sc, AXE_178_CMD_WRITE_NODEID, 0, 0, IF_LLADDR(ifp));
+	else
+		axe_cmd(sc, AXE_172_CMD_WRITE_NODEID, 0, 0, IF_LLADDR(ifp));
 
 	/* Set transmitter IPG values */
 	if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) {

From 589c414bdfeebfee1bffd33e154de230760f4230 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:22:23 +0000
Subject: [PATCH 0426/2592] MFC r197568

 add more device IDs
---
 sys/dev/usb/serial/u3g.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index 398d6b1f89f..92eaf1336bd 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -180,6 +180,8 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(OPTION, GTMAX36, 0),
 	U3G_DEV(OPTION, GTHSDPA, 0),
 	U3G_DEV(OPTION, GTMAXHSUPA, 0),
+	U3G_DEV(OPTION, GTMAXHSUPAE, 0),
+	U3G_DEV(OPTION, GTMAX380HSUPAE, 0),
 	U3G_DEV(OPTION, VODAFONEMC3G, 0),
 	/* OEM: Qualcomm, Inc. */
 	U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GFL_SCSI_EJECT),
@@ -204,6 +206,7 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(NOVATEL, X950D, 0),
 	U3G_DEV(NOVATEL, XU870, 0),
 	U3G_DEV(NOVATEL, ZEROCD, U3GFL_SCSI_EJECT),
+	U3G_DEV(NOVATEL, U760, U3GFL_SCSI_EJECT),
 	U3G_DEV(DELL, U740, 0),
 	/* OEM: Merlin */
 	U3G_DEV(MERLIN, V620, 0),

From 6b48cd24449ced5b1ab3214126791212013e1d62 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:22:54 +0000
Subject: [PATCH 0427/2592] MFC r197569

 Add a config number quirk for the ELSA_MODEM1
---
 sys/dev/usb/quirk/usb_quirk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index 92c2ab05ad4..ea63cd64c7a 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -94,6 +94,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	{USB_QUIRK_ENTRY(USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, 0x009, UQ_AU_NO_FRAC, UQ_NONE)},
 	{USB_QUIRK_ENTRY(USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC, UQ_NONE)},
 	{USB_QUIRK_ENTRY(USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B, 0x0000, 0xFFFF, UQ_NO_STRINGS, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1, 0x0000, 0xFFFF, UQ_CFG_INDEX_1, UQ_NONE)},
 
 	/*
 	 * XXX The following quirks should have a more specific revision

From e792954dba149b06f088bfed3a66ed9ab472c5e2 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:23:34 +0000
Subject: [PATCH 0428/2592] MFC r197570

 Add experimental support for usb serial console and polled mode during DDB.
---
 sys/dev/usb/serial/uark.c       |   9 +
 sys/dev/usb/serial/ubsa.c       |  10 ++
 sys/dev/usb/serial/ubser.c      |   9 +
 sys/dev/usb/serial/uchcom.c     |   9 +
 sys/dev/usb/serial/ucycom.c     |   9 +
 sys/dev/usb/serial/ufoma.c      |  11 +-
 sys/dev/usb/serial/uftdi.c      |   9 +
 sys/dev/usb/serial/ugensa.c     |  14 +-
 sys/dev/usb/serial/uipaq.c      |   9 +
 sys/dev/usb/serial/umct.c       |   9 +
 sys/dev/usb/serial/umodem.c     |   9 +
 sys/dev/usb/serial/umoscom.c    |   9 +
 sys/dev/usb/serial/uplcom.c     |   9 +
 sys/dev/usb/serial/usb_serial.c | 295 +++++++++++++++++++++++++++++++-
 sys/dev/usb/serial/usb_serial.h |   6 +-
 sys/dev/usb/serial/uslcom.c     |   9 +
 sys/dev/usb/serial/uvscom.c     |   9 +
 17 files changed, 436 insertions(+), 8 deletions(-)

diff --git a/sys/dev/usb/serial/uark.c b/sys/dev/usb/serial/uark.c
index cff124eb074..492f68bd37c 100644
--- a/sys/dev/usb/serial/uark.c
+++ b/sys/dev/usb/serial/uark.c
@@ -114,6 +114,7 @@ static void	uark_cfg_get_status(struct ucom_softc *, uint8_t *,
 		    uint8_t *);
 static void	uark_cfg_set_break(struct ucom_softc *, uint8_t);
 static void	uark_cfg_write(struct uark_softc *, uint16_t, uint16_t);
+static void	uark_poll(struct ucom_softc *ucom);
 
 static const struct usb_config
 	uark_xfer_config[UARK_N_TRANSFER] = {
@@ -146,6 +147,7 @@ static const struct ucom_callback uark_callback = {
 	.ucom_stop_read = &uark_stop_read,
 	.ucom_start_write = &uark_start_write,
 	.ucom_stop_write = &uark_stop_write,
+	.ucom_poll = &uark_poll,
 };
 
 static device_method_t uark_methods[] = {
@@ -431,3 +433,10 @@ uark_cfg_write(struct uark_softc *sc, uint16_t index, uint16_t value)
 		    "(ignored)\n", usbd_errstr(err));
 	}
 }
+
+static void
+uark_poll(struct ucom_softc *ucom)
+{
+	struct uark_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UARK_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/ubsa.c b/sys/dev/usb/serial/ubsa.c
index 3e8e61b7c6f..32639fcc403 100644
--- a/sys/dev/usb/serial/ubsa.c
+++ b/sys/dev/usb/serial/ubsa.c
@@ -194,6 +194,7 @@ static void	ubsa_start_write(struct ucom_softc *);
 static void	ubsa_stop_write(struct ucom_softc *);
 static void	ubsa_cfg_get_status(struct ucom_softc *, uint8_t *,
 		    uint8_t *);
+static void	ubsa_poll(struct ucom_softc *ucom);
 
 static const struct usb_config ubsa_config[UBSA_N_TRANSFER] = {
 
@@ -236,6 +237,7 @@ static const struct ucom_callback ubsa_callback = {
 	.ucom_stop_read = &ubsa_stop_read,
 	.ucom_start_write = &ubsa_start_write,
 	.ucom_stop_write = &ubsa_stop_write,
+	.ucom_poll = &ubsa_poll,
 };
 
 static const struct usb_device_id ubsa_devs[] = {
@@ -659,3 +661,11 @@ tr_setup:
 
 	}
 }
+
+static void
+ubsa_poll(struct ucom_softc *ucom)
+{
+	struct ubsa_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UBSA_N_TRANSFER);
+
+}
diff --git a/sys/dev/usb/serial/ubser.c b/sys/dev/usb/serial/ubser.c
index a2c29f94b3b..f95f464ad8c 100644
--- a/sys/dev/usb/serial/ubser.c
+++ b/sys/dev/usb/serial/ubser.c
@@ -163,6 +163,7 @@ static void	ubser_start_read(struct ucom_softc *);
 static void	ubser_stop_read(struct ucom_softc *);
 static void	ubser_start_write(struct ucom_softc *);
 static void	ubser_stop_write(struct ucom_softc *);
+static void	ubser_poll(struct ucom_softc *ucom);
 
 static const struct usb_config ubser_config[UBSER_N_TRANSFER] = {
 
@@ -193,6 +194,7 @@ static const struct ucom_callback ubser_callback = {
 	.ucom_stop_read = &ubser_stop_read,
 	.ucom_start_write = &ubser_start_write,
 	.ucom_stop_write = &ubser_stop_write,
+	.ucom_poll = &ubser_poll,
 };
 
 static device_method_t ubser_methods[] = {
@@ -535,3 +537,10 @@ ubser_stop_write(struct ucom_softc *ucom)
 
 	usbd_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_WR]);
 }
+
+static void
+ubser_poll(struct ucom_softc *ucom)
+{
+	struct ubser_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UBSER_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c
index 705d3e6fdf0..9ed63eb1810 100644
--- a/sys/dev/usb/serial/uchcom.c
+++ b/sys/dev/usb/serial/uchcom.c
@@ -230,6 +230,7 @@ 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_poll(struct ucom_softc *ucom);
 
 static device_probe_t uchcom_probe;
 static device_attach_t uchcom_attach;
@@ -280,6 +281,7 @@ static struct ucom_callback uchcom_callback = {
 	.ucom_stop_read = &uchcom_stop_read,
 	.ucom_start_write = &uchcom_start_write,
 	.ucom_stop_write = &uchcom_stop_write,
+	.ucom_poll = &uchcom_poll,
 };
 
 /* ----------------------------------------------------------------------
@@ -888,6 +890,13 @@ tr_setup:
 	}
 }
 
+static void
+uchcom_poll(struct ucom_softc *ucom)
+{
+	struct uchcom_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UCHCOM_N_TRANSFER);
+}
+
 static device_method_t uchcom_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe, uchcom_probe),
diff --git a/sys/dev/usb/serial/ucycom.c b/sys/dev/usb/serial/ucycom.c
index 1eb24608953..0c1619df64b 100644
--- a/sys/dev/usb/serial/ucycom.c
+++ b/sys/dev/usb/serial/ucycom.c
@@ -124,6 +124,7 @@ static void	ucycom_stop_write(struct ucom_softc *);
 static void	ucycom_cfg_write(struct ucycom_softc *, uint32_t, uint8_t);
 static int	ucycom_pre_param(struct ucom_softc *, struct termios *);
 static void	ucycom_cfg_param(struct ucom_softc *, struct termios *);
+static void	ucycom_poll(struct ucom_softc *ucom);
 
 static const struct usb_config ucycom_config[UCYCOM_N_TRANSFER] = {
 
@@ -154,6 +155,7 @@ static const struct ucom_callback ucycom_callback = {
 	.ucom_stop_read = &ucycom_stop_read,
 	.ucom_start_write = &ucycom_start_write,
 	.ucom_stop_write = &ucycom_stop_write,
+	.ucom_poll = &ucycom_poll,
 };
 
 static device_method_t ucycom_methods[] = {
@@ -578,3 +580,10 @@ tr_setup:
 
 	}
 }
+
+static void
+ucycom_poll(struct ucom_softc *ucom)
+{
+	struct ucycom_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UCYCOM_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/ufoma.c b/sys/dev/usb/serial/ufoma.c
index 7c2c7325769..3d015fd7de2 100644
--- a/sys/dev/usb/serial/ufoma.c
+++ b/sys/dev/usb/serial/ufoma.c
@@ -230,13 +230,13 @@ static void	ufoma_start_read(struct ucom_softc *);
 static void	ufoma_stop_read(struct ucom_softc *);
 static void	ufoma_start_write(struct ucom_softc *);
 static void	ufoma_stop_write(struct ucom_softc *);
+static void	ufoma_poll(struct ucom_softc *ucom);
 
 /*sysctl stuff*/
 static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS);
 static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS);
 static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS);
 
-
 static const struct usb_config
 	ufoma_ctrl_config[UFOMA_CTRL_ENDPT_MAX] = {
 
@@ -304,6 +304,7 @@ static const struct ucom_callback ufoma_callback = {
 	.ucom_stop_read = &ufoma_stop_read,
 	.ucom_start_write = &ufoma_start_write,
 	.ucom_stop_write = &ufoma_stop_write,
+	.ucom_poll = &ufoma_poll,
 };
 
 static device_method_t ufoma_methods[] = {
@@ -1241,3 +1242,11 @@ static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS)
 	
 	return EINVAL;
 }
+
+static void
+ufoma_poll(struct ucom_softc *ucom)
+{
+	struct ufoma_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_ctrl_xfer, UFOMA_CTRL_ENDPT_MAX);
+	usbd_transfer_poll(sc->sc_bulk_xfer, UFOMA_BULK_ENDPT_MAX);
+}
diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
index 52a070b7015..05a2818d785 100644
--- a/sys/dev/usb/serial/uftdi.c
+++ b/sys/dev/usb/serial/uftdi.c
@@ -156,6 +156,7 @@ static void	uftdi_stop_read(struct ucom_softc *);
 static void	uftdi_start_write(struct ucom_softc *);
 static void	uftdi_stop_write(struct ucom_softc *);
 static uint8_t	uftdi_8u232am_getrate(uint32_t, uint16_t *);
+static void	uftdi_poll(struct ucom_softc *ucom);
 
 static const struct usb_config uftdi_config[UFTDI_N_TRANSFER] = {
 
@@ -190,6 +191,7 @@ static const struct ucom_callback uftdi_callback = {
 	.ucom_stop_read = &uftdi_stop_read,
 	.ucom_start_write = &uftdi_start_write,
 	.ucom_stop_write = &uftdi_stop_write,
+	.ucom_poll = &uftdi_poll,
 };
 
 static device_method_t uftdi_methods[] = {
@@ -808,3 +810,10 @@ done:
 	*rate = result;
 	return (0);
 }
+
+static void
+uftdi_poll(struct ucom_softc *ucom)
+{
+	struct uftdi_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UFTDI_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/ugensa.c b/sys/dev/usb/serial/ugensa.c
index 86e858638a7..dd6b6f1037a 100644
--- a/sys/dev/usb/serial/ugensa.c
+++ b/sys/dev/usb/serial/ugensa.c
@@ -110,9 +110,9 @@ static void	ugensa_start_read(struct ucom_softc *);
 static void	ugensa_stop_read(struct ucom_softc *);
 static void	ugensa_start_write(struct ucom_softc *);
 static void	ugensa_stop_write(struct ucom_softc *);
+static void	ugensa_poll(struct ucom_softc *ucom);
 
-static const struct usb_config
-	ugensa_xfer_config[UGENSA_N_TRANSFER] = {
+static const struct usb_config ugensa_xfer_config[UGENSA_N_TRANSFER] = {
 
 	[UGENSA_BULK_DT_WR] = {
 		.type = UE_BULK,
@@ -138,6 +138,7 @@ static const struct ucom_callback ugensa_callback = {
 	.ucom_stop_read = &ugensa_stop_read,
 	.ucom_start_write = &ugensa_start_write,
 	.ucom_stop_write = &ugensa_stop_write,
+	.ucom_poll = &ugensa_poll,
 };
 
 static device_method_t ugensa_methods[] = {
@@ -369,3 +370,12 @@ ugensa_stop_write(struct ucom_softc *ucom)
 
 	usbd_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_WR]);
 }
+
+static void
+ugensa_poll(struct ucom_softc *ucom)
+{
+	struct ugensa_softc *sc = ucom->sc_parent;
+	struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno;
+
+	usbd_transfer_poll(ssc->sc_xfer, UGENSA_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c
index 89a4cd254ab..3bdb2307a5f 100644
--- a/sys/dev/usb/serial/uipaq.c
+++ b/sys/dev/usb/serial/uipaq.c
@@ -122,6 +122,7 @@ static void	uipaq_stop_write(struct ucom_softc *);
 static void	uipaq_cfg_set_dtr(struct ucom_softc *, uint8_t);
 static void	uipaq_cfg_set_rts(struct ucom_softc *, uint8_t);
 static void	uipaq_cfg_set_break(struct ucom_softc *, uint8_t);
+static void	uipaq_poll(struct ucom_softc *ucom);
 
 static const struct usb_config uipaq_config_data[UIPAQ_N_TRANSFER] = {
 
@@ -152,6 +153,7 @@ static const struct ucom_callback uipaq_callback = {
 	.ucom_stop_read = &uipaq_stop_read,
 	.ucom_start_write = &uipaq_start_write,
 	.ucom_stop_write = &uipaq_stop_write,
+	.ucom_poll = &uipaq_poll,
 };
 
 /*
@@ -1342,3 +1344,10 @@ tr_setup:
 		return;
 	}
 }
+
+static void
+uipaq_poll(struct ucom_softc *ucom)
+{
+	struct uipaq_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UIPAQ_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/umct.c b/sys/dev/usb/serial/umct.c
index 557a511adc0..c83a2237634 100644
--- a/sys/dev/usb/serial/umct.c
+++ b/sys/dev/usb/serial/umct.c
@@ -142,6 +142,7 @@ static void	umct_start_read(struct ucom_softc *);
 static void	umct_stop_read(struct ucom_softc *);
 static void	umct_start_write(struct ucom_softc *);
 static void	umct_stop_write(struct ucom_softc *);
+static void	umct_poll(struct ucom_softc *ucom);
 
 static const struct usb_config umct_config[UMCT_N_TRANSFER] = {
 
@@ -186,6 +187,7 @@ static const struct ucom_callback umct_callback = {
 	.ucom_stop_read = &umct_stop_read,
 	.ucom_start_write = &umct_start_write,
 	.ucom_stop_write = &umct_stop_write,
+	.ucom_poll = &umct_poll,
 };
 
 static const struct usb_device_id umct_devs[] = {
@@ -603,3 +605,10 @@ tr_setup:
 		return;
 	}
 }
+
+static void
+umct_poll(struct ucom_softc *ucom)
+{
+	struct umct_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UMCT_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c
index fc658c5b664..9b8da420eb2 100644
--- a/sys/dev/usb/serial/umodem.c
+++ b/sys/dev/usb/serial/umodem.c
@@ -196,6 +196,7 @@ static void	umodem_cfg_set_break(struct ucom_softc *, uint8_t);
 static void	*umodem_get_desc(struct usb_attach_arg *, uint8_t, uint8_t);
 static usb_error_t umodem_set_comm_feature(struct usb_device *, uint8_t,
 		    uint16_t, uint16_t);
+static void	umodem_poll(struct ucom_softc *ucom);
 
 static const struct usb_config umodem_config[UMODEM_N_TRANSFER] = {
 
@@ -242,6 +243,7 @@ static const struct ucom_callback umodem_callback = {
 	.ucom_stop_read = &umodem_stop_read,
 	.ucom_start_write = &umodem_start_write,
 	.ucom_stop_write = &umodem_stop_write,
+	.ucom_poll = &umodem_poll,
 };
 
 static device_method_t umodem_methods[] = {
@@ -810,3 +812,10 @@ umodem_detach(device_t dev)
 
 	return (0);
 }
+
+static void
+umodem_poll(struct ucom_softc *ucom)
+{
+	struct umodem_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UMODEM_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/umoscom.c b/sys/dev/usb/serial/umoscom.c
index 47f70f1f4d3..0481b192c8b 100644
--- a/sys/dev/usb/serial/umoscom.c
+++ b/sys/dev/usb/serial/umoscom.c
@@ -210,6 +210,7 @@ static void	umoscom_start_read(struct ucom_softc *);
 static void	umoscom_stop_read(struct ucom_softc *);
 static void	umoscom_start_write(struct ucom_softc *);
 static void	umoscom_stop_write(struct ucom_softc *);
+static void	umoscom_poll(struct ucom_softc *ucom);
 
 static const struct usb_config umoscom_config_data[UMOSCOM_N_TRANSFER] = {
 
@@ -257,6 +258,7 @@ static const struct ucom_callback umoscom_callback = {
 	.ucom_stop_read = &umoscom_stop_read,
 	.ucom_start_write = &umoscom_start_write,
 	.ucom_stop_write = &umoscom_stop_write,
+	.ucom_poll = &umoscom_poll,
 };
 
 static device_method_t umoscom_methods[] = {
@@ -694,3 +696,10 @@ tr_setup:
 		return;
 	}
 }
+
+static void
+umoscom_poll(struct ucom_softc *ucom)
+{
+	struct umoscom_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UMOSCOM_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c
index 399792f1ef1..af6bdbafd07 100644
--- a/sys/dev/usb/serial/uplcom.c
+++ b/sys/dev/usb/serial/uplcom.c
@@ -186,6 +186,7 @@ static void	uplcom_start_write(struct ucom_softc *);
 static void	uplcom_stop_write(struct ucom_softc *);
 static void	uplcom_cfg_get_status(struct ucom_softc *, uint8_t *,
 		    uint8_t *);
+static void	uplcom_poll(struct ucom_softc *ucom);
 
 static device_probe_t uplcom_probe;
 static device_attach_t uplcom_attach;
@@ -239,6 +240,7 @@ static struct ucom_callback uplcom_callback = {
 	.ucom_stop_read = &uplcom_stop_read,
 	.ucom_start_write = &uplcom_start_write,
 	.ucom_stop_write = &uplcom_stop_write,
+	.ucom_poll = &uplcom_poll,
 };
 
 #define	USB_UPL(v,p,rl,rh,t)				\
@@ -862,3 +864,10 @@ tr_setup:
 		return;
 	}
 }
+
+static void
+uplcom_poll(struct ucom_softc *ucom)
+{
+	struct uplcom_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UPLCOM_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c
index f3e3e91adde..ca54712890b 100644
--- a/sys/dev/usb/serial/usb_serial.c
+++ b/sys/dev/usb/serial/usb_serial.c
@@ -86,6 +86,8 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -98,14 +100,40 @@ __FBSDID("$FreeBSD$");
 
 #include 
 
+#include "opt_gdb.h"
+
+SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom");
+
 #if USB_DEBUG
 static int ucom_debug = 0;
 
-SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom");
 SYSCTL_INT(_hw_usb_ucom, OID_AUTO, debug, CTLFLAG_RW,
     &ucom_debug, 0, "ucom debug level");
 #endif
 
+#define	UCOM_CONS_BUFSIZE 1024
+
+static uint8_t ucom_cons_rx_buf[UCOM_CONS_BUFSIZE];
+static uint8_t ucom_cons_tx_buf[UCOM_CONS_BUFSIZE];
+
+static unsigned int ucom_cons_rx_low = 0;
+static unsigned int ucom_cons_rx_high = 0;
+
+static unsigned int ucom_cons_tx_low = 0;
+static unsigned int ucom_cons_tx_high = 0;
+
+static int ucom_cons_unit = -1;
+static int ucom_cons_baud = 9600;
+static struct ucom_softc *ucom_cons_softc = NULL;
+
+TUNABLE_INT("hw.usb.ucom.cons_unit", &ucom_cons_unit);
+SYSCTL_INT(_hw_usb_ucom, OID_AUTO, cons_unit, CTLFLAG_RW,
+    &ucom_cons_unit, 0, "console unit number");
+
+TUNABLE_INT("hw.usb.ucom.cons_baud", &ucom_cons_baud);
+SYSCTL_INT(_hw_usb_ucom, OID_AUTO, cons_baud, CTLFLAG_RW,
+    &ucom_cons_baud, 0, "console baud rate");
+
 static usb_proc_callback_t ucom_cfg_start_transfers;
 static usb_proc_callback_t ucom_cfg_open;
 static usb_proc_callback_t ucom_cfg_close;
@@ -121,6 +149,7 @@ static void	ucom_queue_command(struct ucom_softc *,
 		    usb_proc_callback_t *, struct termios *pt,
 		    struct usb_proc_msg *t0, struct usb_proc_msg *t1);
 static void	ucom_shutdown(struct ucom_softc *);
+static void	ucom_ring(struct ucom_softc *, uint8_t);
 static void	ucom_break(struct ucom_softc *, uint8_t);
 static void	ucom_dtr(struct ucom_softc *, uint8_t);
 static void	ucom_rts(struct ucom_softc *, uint8_t);
@@ -147,7 +176,7 @@ static struct ttydevsw ucom_class = {
 MODULE_DEPEND(ucom, usb, 1, 1, 1);
 MODULE_VERSION(ucom, 1);
 
-#define	UCOM_UNIT_MAX 0x1000		/* exclusive */
+#define	UCOM_UNIT_MAX 0x200		/* exclusive */
 #define	UCOM_SUB_UNIT_MAX 0x100		/* exclusive */
 
 static uint8_t ucom_bitmap[(UCOM_UNIT_MAX + 7) / 8];
@@ -346,6 +375,29 @@ ucom_attach_tty(struct ucom_softc *sc, uint32_t sub_units)
 	DPRINTF("ttycreate: %s\n", buf);
 	cv_init(&sc->sc_cv, "ucom");
 
+	/* Check if this device should be a console */
+	if ((ucom_cons_softc == NULL) && 
+	    (sc->sc_unit == ucom_cons_unit)) {
+
+		struct termios t;
+
+		ucom_cons_softc = sc;
+
+		memset(&t, 0, sizeof(t));
+		t.c_ispeed = ucom_cons_baud;
+		t.c_ospeed = t.c_ispeed;
+		t.c_cflag = CS8;
+
+		mtx_lock(ucom_cons_softc->sc_mtx);
+		ucom_cons_rx_low = 0;
+		ucom_cons_rx_high = 0;
+		ucom_cons_tx_low = 0;
+		ucom_cons_tx_high = 0;
+		sc->sc_flag |= UCOM_FLAG_CONSOLE;
+		ucom_open(ucom_cons_softc->sc_tty);
+		ucom_param(ucom_cons_softc->sc_tty, &t);
+		mtx_unlock(ucom_cons_softc->sc_mtx);
+	}
 done:
 	return (error);
 }
@@ -357,12 +409,18 @@ ucom_detach_tty(struct ucom_softc *sc)
 
 	DPRINTF("sc = %p, tp = %p\n", sc, sc->sc_tty);
 
+	if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
+		mtx_lock(ucom_cons_softc->sc_mtx);
+		ucom_close(ucom_cons_softc->sc_tty);
+		mtx_unlock(ucom_cons_softc->sc_mtx);
+		ucom_cons_softc = NULL;
+	}
+
 	/* the config thread has been stopped when we get here */
 
 	mtx_lock(sc->sc_mtx);
 	sc->sc_flag |= UCOM_FLAG_GONE;
-	sc->sc_flag &= ~(UCOM_FLAG_HL_READY |
-	    UCOM_FLAG_LL_READY);
+	sc->sc_flag &= ~(UCOM_FLAG_HL_READY | UCOM_FLAG_LL_READY);
 	mtx_unlock(sc->sc_mtx);
 	if (tp) {
 		tty_lock(tp);
@@ -588,6 +646,8 @@ ucom_open(struct tty *tp)
 
 	ucom_modem(tp, SER_DTR | SER_RTS, 0);
 
+	ucom_ring(sc, 0);
+
 	ucom_break(sc, 0);
 
 	ucom_status_change(sc);
@@ -653,6 +713,16 @@ ucom_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
 	DPRINTF("cmd = 0x%08lx\n", cmd);
 
 	switch (cmd) {
+#if 0
+	case TIOCSRING:
+		ucom_ring(sc, 1);
+		error = 0;
+		break;
+	case TIOCCRING:
+		ucom_ring(sc, 0);
+		error = 0;
+		break;
+#endif
 	case TIOCSBRK:
 		ucom_break(sc, 1);
 		error = 0;
@@ -751,6 +821,8 @@ ucom_cfg_line_state(struct usb_proc_msg *_task)
 		mask |= UCOM_LS_RTS;
 	if (sc->sc_callback->ucom_cfg_set_break)
 		mask |= UCOM_LS_BREAK;
+	if (sc->sc_callback->ucom_cfg_set_ring)
+		mask |= UCOM_LS_RING;
 
 	/* compute the bits we are to program */
 	notch_bits = (sc->sc_pls_set & sc->sc_pls_clr) & mask;
@@ -773,6 +845,9 @@ ucom_cfg_line_state(struct usb_proc_msg *_task)
 	if (notch_bits & UCOM_LS_BREAK)
 		sc->sc_callback->ucom_cfg_set_break(sc,
 		    (prev_value & UCOM_LS_BREAK) ? 1 : 0);
+	if (notch_bits & UCOM_LS_RING)
+		sc->sc_callback->ucom_cfg_set_ring(sc,
+		    (prev_value & UCOM_LS_RING) ? 1 : 0);
 
 	/* set last value */
 	if (any_bits & UCOM_LS_DTR)
@@ -784,6 +859,9 @@ ucom_cfg_line_state(struct usb_proc_msg *_task)
 	if (any_bits & UCOM_LS_BREAK)
 		sc->sc_callback->ucom_cfg_set_break(sc,
 		    (last_value & UCOM_LS_BREAK) ? 1 : 0);
+	if (any_bits & UCOM_LS_RING)
+		sc->sc_callback->ucom_cfg_set_ring(sc,
+		    (last_value & UCOM_LS_RING) ? 1 : 0);
 }
 
 static void
@@ -810,6 +888,17 @@ ucom_line_state(struct ucom_softc *sc,
 	    &sc->sc_line_state_task[1].hdr);
 }
 
+static void
+ucom_ring(struct ucom_softc *sc, uint8_t onoff)
+{
+	DPRINTF("onoff = %d\n", onoff);
+
+	if (onoff)
+		ucom_line_state(sc, UCOM_LS_RING, 0);
+	else
+		ucom_line_state(sc, 0, UCOM_LS_RING);
+}
+
 static void
 ucom_break(struct ucom_softc *sc, uint8_t onoff)
 {
@@ -895,6 +984,9 @@ ucom_status_change(struct ucom_softc *sc)
 {
 	mtx_assert(sc->sc_mtx, MA_OWNED);
 
+	if (sc->sc_flag & UCOM_FLAG_CONSOLE)
+		return;		/* not supported */
+
 	if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
 		return;
 	}
@@ -1033,6 +1125,38 @@ ucom_get_data(struct ucom_softc *sc, struct usb_page_cache *pc,
 
 	mtx_assert(sc->sc_mtx, MA_OWNED);
 
+	if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
+		unsigned int temp;
+
+		/* get total TX length */
+
+		temp = ucom_cons_tx_high - ucom_cons_tx_low;
+		temp %= UCOM_CONS_BUFSIZE;
+
+		/* limit TX length */
+
+		if (temp > (UCOM_CONS_BUFSIZE - ucom_cons_tx_low))
+			temp = (UCOM_CONS_BUFSIZE - ucom_cons_tx_low);
+
+		if (temp > len)
+			temp = len;
+
+		/* copy in data */
+
+		usbd_copy_in(pc, offset, ucom_cons_tx_buf + ucom_cons_tx_low, temp);
+
+		/* update counters */
+
+		ucom_cons_tx_low += temp;
+		ucom_cons_tx_low %= UCOM_CONS_BUFSIZE;
+
+		/* store actual length */
+
+		*actlen = temp;
+
+		return (temp ? 1 : 0);
+	}
+
 	if (tty_gone(tp) ||
 	    !(sc->sc_flag & UCOM_FLAG_GP_DATA)) {
 		actlen[0] = 0;
@@ -1080,6 +1204,34 @@ ucom_put_data(struct ucom_softc *sc, struct usb_page_cache *pc,
 
 	mtx_assert(sc->sc_mtx, MA_OWNED);
 
+	if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
+		unsigned int temp;
+
+		/* get maximum RX length */
+
+		temp = (UCOM_CONS_BUFSIZE - 1) - ucom_cons_rx_high + ucom_cons_rx_low;
+		temp %= UCOM_CONS_BUFSIZE;
+
+		/* limit RX length */
+
+		if (temp > (UCOM_CONS_BUFSIZE - ucom_cons_rx_high))
+			temp = (UCOM_CONS_BUFSIZE - ucom_cons_rx_high);
+
+		if (temp > len)
+			temp = len;
+
+		/* copy out data */
+
+		usbd_copy_out(pc, offset, ucom_cons_rx_buf + ucom_cons_rx_high, temp);
+
+		/* update counters */
+
+		ucom_cons_rx_high += temp;
+		ucom_cons_rx_high %= UCOM_CONS_BUFSIZE;
+
+		return;
+	}
+
 	if (tty_gone(tp))
 		return;			/* multiport device polling */
 
@@ -1136,3 +1288,138 @@ ucom_free(void *xsc)
 	cv_signal(&sc->sc_cv);
 	mtx_unlock(sc->sc_mtx);
 }
+
+static cn_probe_t ucom_cnprobe;
+static cn_init_t ucom_cninit;
+static cn_term_t ucom_cnterm;
+static cn_getc_t ucom_cngetc;
+static cn_putc_t ucom_cnputc;
+
+CONSOLE_DRIVER(ucom);
+
+static void
+ucom_cnprobe(struct consdev  *cp)
+{
+	cp->cn_pri = CN_NORMAL;
+}
+
+static void
+ucom_cninit(struct consdev  *cp)
+{
+}
+
+static void
+ucom_cnterm(struct consdev  *cp)
+{
+}
+
+static int
+ucom_cngetc(struct consdev *cd)
+{
+	struct ucom_softc *sc = ucom_cons_softc;
+	int c;
+
+	if (sc == NULL)
+		return (-1);
+
+	mtx_lock(sc->sc_mtx);
+
+	if (ucom_cons_rx_low != ucom_cons_rx_high) {
+		c = ucom_cons_rx_buf[ucom_cons_rx_low];
+		ucom_cons_rx_low ++;
+		ucom_cons_rx_low %= UCOM_CONS_BUFSIZE;
+	} else {
+		c = -1;
+	}
+
+	/* start USB transfers */
+	ucom_outwakeup(sc->sc_tty);
+
+	mtx_unlock(sc->sc_mtx);
+
+	/* poll if necessary */
+	if (kdb_active && sc->sc_callback->ucom_poll)
+		(sc->sc_callback->ucom_poll) (sc);
+
+	return (c);
+}
+
+static void
+ucom_cnputc(struct consdev *cd, int c)
+{
+	struct ucom_softc *sc = ucom_cons_softc;
+	unsigned int temp;
+
+	if (sc == NULL)
+		return;
+
+ repeat:
+
+	mtx_lock(sc->sc_mtx);
+
+	/* compute maximum TX length */
+
+	temp = (UCOM_CONS_BUFSIZE - 1) - ucom_cons_tx_high + ucom_cons_tx_low;
+	temp %= UCOM_CONS_BUFSIZE;
+
+	if (temp) {
+		ucom_cons_tx_buf[ucom_cons_tx_high] = c;
+		ucom_cons_tx_high ++;
+		ucom_cons_tx_high %= UCOM_CONS_BUFSIZE;
+	}
+
+	/* start USB transfers */
+	ucom_outwakeup(sc->sc_tty);
+
+	mtx_unlock(sc->sc_mtx);
+
+	/* poll if necessary */
+	if (kdb_active && sc->sc_callback->ucom_poll) {
+		(sc->sc_callback->ucom_poll) (sc);
+		/* simple flow control */
+		if (temp == 0)
+			goto repeat;
+	}
+}
+
+#if defined(GDB)
+
+#include 
+
+static gdb_probe_f ucom_gdbprobe;
+static gdb_init_f ucom_gdbinit;
+static gdb_term_f ucom_gdbterm;
+static gdb_getc_f ucom_gdbgetc;
+static gdb_putc_f ucom_gdbputc;
+
+GDB_DBGPORT(sio, ucom_gdbprobe, ucom_gdbinit, ucom_gdbterm, ucom_gdbgetc, ucom_gdbputc);
+
+static int
+ucom_gdbprobe(void)
+{
+	return ((ucom_cons_softc != NULL) ? 0 : -1);
+}
+
+static void
+ucom_gdbinit(void)
+{
+}
+
+static void
+ucom_gdbterm(void)
+{
+}
+
+static void
+ucom_gdbputc(int c)
+{
+        ucom_cnputc(NULL, c);
+}
+
+static int
+ucom_gdbgetc(void)
+{
+        return (ucom_cngetc(NULL));
+}
+
+#endif
diff --git a/sys/dev/usb/serial/usb_serial.h b/sys/dev/usb/serial/usb_serial.h
index 94f82f1b3fb..ce5f6a9f45f 100644
--- a/sys/dev/usb/serial/usb_serial.h
+++ b/sys/dev/usb/serial/usb_serial.h
@@ -94,6 +94,7 @@ struct ucom_callback {
 	void    (*ucom_cfg_set_dtr) (struct ucom_softc *, uint8_t);
 	void    (*ucom_cfg_set_rts) (struct ucom_softc *, uint8_t);
 	void    (*ucom_cfg_set_break) (struct ucom_softc *, uint8_t);
+	void    (*ucom_cfg_set_ring) (struct ucom_softc *, uint8_t);
 	void    (*ucom_cfg_param) (struct ucom_softc *, struct termios *);
 	void    (*ucom_cfg_open) (struct ucom_softc *);
 	void    (*ucom_cfg_close) (struct ucom_softc *);
@@ -105,6 +106,7 @@ struct ucom_callback {
 	void    (*ucom_start_write) (struct ucom_softc *);
 	void    (*ucom_stop_write) (struct ucom_softc *);
 	void    (*ucom_tty_name) (struct ucom_softc *, char *pbuf, uint16_t buflen, uint16_t local_subunit);
+	void    (*ucom_poll) (struct ucom_softc *);
 };
 
 /* Line status register */
@@ -162,13 +164,14 @@ struct ucom_softc {
 	uint32_t sc_unit;
 	uint32_t sc_local_unit;
 	uint16_t sc_portno;
-	uint8_t	sc_flag;
+	uint16_t sc_flag;
 #define	UCOM_FLAG_RTS_IFLOW	0x01	/* use RTS input flow control */
 #define	UCOM_FLAG_GONE		0x02	/* the device is gone */
 #define	UCOM_FLAG_ATTACHED	0x04	/* set if attached */
 #define	UCOM_FLAG_GP_DATA	0x08	/* set if get and put data is possible */
 #define	UCOM_FLAG_LL_READY	0x20	/* set if low layer is ready */
 #define	UCOM_FLAG_HL_READY	0x40	/* set if high layer is ready */
+#define	UCOM_FLAG_CONSOLE	0x80	/* set if device is a console */
 	uint8_t	sc_lsr;
 	uint8_t	sc_msr;
 	uint8_t	sc_mcr;
@@ -180,6 +183,7 @@ struct ucom_softc {
 #define	UCOM_LS_DTR	0x01
 #define	UCOM_LS_RTS	0x02
 #define	UCOM_LS_BREAK	0x04
+#define	UCOM_LS_RING	0x08
 };
 
 #define	ucom_cfg_do_request(udev,com,req,ptr,flags,timo) \
diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c
index c319dfd74e5..753625f29fc 100644
--- a/sys/dev/usb/serial/uslcom.c
+++ b/sys/dev/usb/serial/uslcom.c
@@ -135,6 +135,7 @@ static void uslcom_start_read(struct ucom_softc *);
 static void uslcom_stop_read(struct ucom_softc *);
 static void uslcom_start_write(struct ucom_softc *);
 static void uslcom_stop_write(struct ucom_softc *);
+static void uslcom_poll(struct ucom_softc *ucom);
 
 static const struct usb_config uslcom_config[USLCOM_N_TRANSFER] = {
 
@@ -170,6 +171,7 @@ static struct ucom_callback uslcom_callback = {
 	.ucom_stop_read = &uslcom_stop_read,
 	.ucom_start_write = &uslcom_start_write,
 	.ucom_stop_write = &uslcom_stop_write,
+	.ucom_poll = &uslcom_poll,
 };
 
 static const struct usb_device_id uslcom_devs[] = {
@@ -562,3 +564,10 @@ uslcom_stop_write(struct ucom_softc *ucom)
 
 	usbd_transfer_stop(sc->sc_xfer[USLCOM_BULK_DT_WR]);
 }
+
+static void
+uslcom_poll(struct ucom_softc *ucom)
+{
+	struct uslcom_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, USLCOM_N_TRANSFER);
+}
diff --git a/sys/dev/usb/serial/uvscom.c b/sys/dev/usb/serial/uvscom.c
index 27f3919b286..4e3ff576422 100644
--- a/sys/dev/usb/serial/uvscom.c
+++ b/sys/dev/usb/serial/uvscom.c
@@ -185,6 +185,7 @@ static void	uvscom_cfg_get_status(struct ucom_softc *, uint8_t *,
 		    uint8_t *);
 static void	uvscom_cfg_write(struct uvscom_softc *, uint8_t, uint16_t);
 static uint16_t	uvscom_cfg_read_status(struct uvscom_softc *);
+static void	uvscom_poll(struct ucom_softc *ucom);
 
 static const struct usb_config uvscom_config[UVSCOM_N_TRANSFER] = {
 
@@ -230,6 +231,7 @@ static const struct ucom_callback uvscom_callback = {
 	.ucom_stop_read = &uvscom_stop_read,
 	.ucom_start_write = &uvscom_start_write,
 	.ucom_stop_write = &uvscom_stop_write,
+	.ucom_poll = &uvscom_poll,
 };
 
 static const struct usb_device_id uvscom_devs[] = {
@@ -734,3 +736,10 @@ uvscom_cfg_read_status(struct uvscom_softc *sc)
 	}
 	return (data[0] | (data[1] << 8));
 }
+
+static void
+uvscom_poll(struct ucom_softc *ucom)
+{
+	struct uvscom_softc *sc = ucom->sc_parent;
+	usbd_transfer_poll(sc->sc_xfer, UVSCOM_N_TRANSFER);
+}

From b56d97e2aff0c6a114633b7910ab295c53365542 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:24:10 +0000
Subject: [PATCH 0429/2592] MFC r197572

 Add new FTDI IDs.
---
 sys/dev/usb/serial/uftdi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
index 05a2818d785..c7442b64270 100644
--- a/sys/dev/usb/serial/uftdi.c
+++ b/sys/dev/usb/serial/uftdi.c
@@ -243,10 +243,13 @@ static struct usb_device_id uftdi_devs[] = {
 	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PCMSFU, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EMCU2H, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MAXSTREAM, UFTDI_TYPE_8U232AM)},
+	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CTI_USB_NANO_485, UFTDI_TYPE_8U232AM)},
+	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CTI_USB_MINI_485, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_SIIG2, USB_PRODUCT_SIIG2_US2308, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_VALUECAN, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_NEOVI, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_BBELECTRONICS, USB_PRODUCT_BBELECTRONICS_USOTL4, UFTDI_TYPE_8U232AM)},
+	{USB_VPI(USB_VENDOR_MARVELL, USB_PRODUCT_MARVELL_SHEEVAPLUG, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_PCOPRS1, UFTDI_TYPE_8U232AM)},
 };
 

From 48bd741396f8b8ceb3d43a7bbfd79c8ae94fce74 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:24:41 +0000
Subject: [PATCH 0430/2592] MFC r197573

 Add back endpoint swap detection that was disabled in an earlier driver
 conversion.
---
 sys/dev/usb/serial/umct.c | 43 ++++++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/sys/dev/usb/serial/umct.c b/sys/dev/usb/serial/umct.c
index c83a2237634..7331a0bf85c 100644
--- a/sys/dev/usb/serial/umct.c
+++ b/sys/dev/usb/serial/umct.c
@@ -115,6 +115,7 @@ struct umct_softc {
 	uint8_t	sc_lcr;
 	uint8_t	sc_mcr;
 	uint8_t	sc_iface_no;
+	uint8_t sc_swap_cb;
 	uint8_t	sc_name[16];
 };
 
@@ -125,8 +126,10 @@ static device_attach_t umct_attach;
 static device_detach_t umct_detach;
 
 static usb_callback_t umct_intr_callback;
-static usb_callback_t umct_write_callback;
+static usb_callback_t umct_intr_callback_sub;
 static usb_callback_t umct_read_callback;
+static usb_callback_t umct_read_callback_sub;
+static usb_callback_t umct_write_callback;
 
 static void	umct_cfg_do_request(struct umct_softc *sc, uint8_t request,
 		    uint16_t len, uint32_t value);
@@ -240,7 +243,7 @@ umct_attach(device_t dev)
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
 	struct umct_softc *sc = device_get_softc(dev);
 	int32_t error;
-	//uint16_t maxp;
+	uint16_t maxp;
 	uint8_t iface_index;
 
 	sc->sc_udev = uaa->device;
@@ -263,13 +266,13 @@ umct_attach(device_t dev)
 		    "transfers failed!\n");
 		goto detach;
 	}
+
 	/*
 	 * The real bulk-in endpoint is also marked as an interrupt.
 	 * The only way to differentiate it from the real interrupt
 	 * endpoint is to look at the wMaxPacketSize field.
 	 */
-#ifdef XXX
-	maxp = UGETW(sc->sc_xfer[UMCT_BULK_DT_RD]->endpoint->edesc->wMaxPacketSize);
+	maxp = usbd_xfer_max_framelen(sc->sc_xfer[UMCT_BULK_DT_RD]);
 	if (maxp == 0x2) {
 
 		/* guessed wrong - switch around endpoints */
@@ -278,11 +281,9 @@ umct_attach(device_t dev)
 
 		sc->sc_xfer[UMCT_INTR_DT_RD] = sc->sc_xfer[UMCT_BULK_DT_RD];
 		sc->sc_xfer[UMCT_BULK_DT_RD] = temp;
-
-		sc->sc_xfer[UMCT_BULK_DT_RD]->callback = &umct_read_callback;
-		sc->sc_xfer[UMCT_INTR_DT_RD]->callback = &umct_intr_callback;
+		sc->sc_swap_cb = 1;
 	}
-#endif
+
 	sc->sc_obufsize = usbd_xfer_max_len(sc->sc_xfer[UMCT_BULK_DT_WR]);
 
 	if (uaa->info.idProduct == USB_PRODUCT_MCT_SITECOM_USB232) {
@@ -342,7 +343,7 @@ umct_cfg_do_request(struct umct_softc *sc, uint8_t request,
 }
 
 static void
-umct_intr_callback(struct usb_xfer *xfer, usb_error_t error)
+umct_intr_callback_sub(struct usb_xfer *xfer, usb_error_t error)
 {
 	struct umct_softc *sc = usbd_xfer_softc(xfer);
 	struct usb_page_cache *pc;
@@ -546,6 +547,28 @@ umct_stop_write(struct ucom_softc *ucom)
 	usbd_transfer_stop(sc->sc_xfer[UMCT_BULK_DT_WR]);
 }
 
+static void
+umct_read_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct umct_softc *sc = usbd_xfer_softc(xfer);
+
+	if (sc->sc_swap_cb)
+		umct_intr_callback_sub(xfer, error);
+	else
+		umct_read_callback_sub(xfer, error);
+}
+
+static void
+umct_intr_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct umct_softc *sc = usbd_xfer_softc(xfer);
+
+	if (sc->sc_swap_cb)
+		umct_read_callback_sub(xfer, error);
+	else
+		umct_intr_callback_sub(xfer, error);
+}
+
 static void
 umct_write_callback(struct usb_xfer *xfer, usb_error_t error)
 {
@@ -577,7 +600,7 @@ tr_setup:
 }
 
 static void
-umct_read_callback(struct usb_xfer *xfer, usb_error_t error)
+umct_read_callback_sub(struct usb_xfer *xfer, usb_error_t error)
 {
 	struct umct_softc *sc = usbd_xfer_softc(xfer);
 	struct usb_page_cache *pc;

From b0deb9099b3d4652ed1a235878f8a12951eae1b8 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:25:13 +0000
Subject: [PATCH 0431/2592] MFC r197999 (hrs)

 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
---
 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 1ea6a20c732a68cfd967db7b602a0c84077e513e Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:25:52 +0000
Subject: [PATCH 0432/2592] MFC r198151

 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.
---
 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 6a8d0ac969649bda0c93b200e5586bfeecb1f7f6 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:26:29 +0000
Subject: [PATCH 0433/2592] MFC r198152

 Only poll ukbd if KDB is active.
---
 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 83c0f67853a8094c033081d0e6ccc853900666cb Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:27:00 +0000
Subject: [PATCH 0434/2592] MFC r198153

 Correct offset calcluation for the NCM implementation.
---
 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 906c96039d65b9e7d625fedf79b4219f81f52458 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:27:40 +0000
Subject: [PATCH 0435/2592] MFC r198257

 Add support for newer WinChipHead CH341 chips, previously in the uch341 driver.
---
 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 17285b3cec1..5ebb2ddbfc5 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
@@ -2506,8 +2507,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 fbcc87cbbcdd706004f72b463ff1ebcd69505b60 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:28:21 +0000
Subject: [PATCH 0436/2592] MFC r198258

 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 bfa1f203df3079ff5db9c565a1a4023439a6b1e1 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 29 Oct 2009 23:28:48 +0000
Subject: [PATCH 0437/2592] MFC r198373

 Allow dumping the USB mouse reports via 'sysctl -b dev.ums.N.parseinfo',
 previously only available via bootverbose.

PR:		usb/137191
---
 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 22c6623dc484915aad52a7d7d4d2106584528ebd Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 30 Oct 2009 12:57:28 +0000
Subject: [PATCH 0438/2592] MFC rev. 197086: Add simple embedded RADIUS server
 support to libradius, by extending existing API, keeping backward
 compatibility.

First consumer for this functionality is going to become forthcoming MPD-5.4,
supporting CoA and DR of RFC 3576: Dynamic Authorization Extensions to RADIUS.
---
 lib/libradius/libradius.3      |  51 ++++-
 lib/libradius/radlib.c         | 346 +++++++++++++++++++++++++--------
 lib/libradius/radlib.h         |  12 ++
 lib/libradius/radlib_private.h |  15 +-
 4 files changed, 334 insertions(+), 90 deletions(-)

diff --git a/lib/libradius/libradius.3 b/lib/libradius/libradius.3
index 095d6e9a58a..9a71521d892 100644
--- a/lib/libradius/libradius.3
+++ b/lib/libradius/libradius.3
@@ -1,4 +1,5 @@
 .\" Copyright 1998 Juniper Networks, Inc.
+.\" Copyright 2009 Alexander Motin .
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -24,12 +25,12 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 27, 2004
+.Dd August 5, 2009
 .Dt LIBRADIUS 3
 .Os
 .Sh NAME
 .Nm libradius
-.Nd RADIUS client library
+.Nd RADIUS client/server library
 .Sh SYNOPSIS
 .In radlib.h
 .Ft "struct rad_handle *"
@@ -46,6 +47,8 @@
 .Fn rad_continue_send_request "struct rad_handle *h" "int selected" "int *fd" "struct timeval *tv"
 .Ft int
 .Fn rad_create_request "struct rad_handle *h" "int code"
+.Ft int
+.Fn rad_create_response "struct rad_handle *h" "int code"
 .Ft "struct in_addr"
 .Fn rad_cvt_addr "const void *data"
 .Ft u_int32_t
@@ -79,7 +82,13 @@
 .Ft ssize_t
 .Fn rad_request_authenticator "struct rad_handle *h" "char *buf" "size_t len"
 .Ft int
+.Fn rad_receive_request "struct rad_handle *h"
+.Ft int
 .Fn rad_send_request "struct rad_handle *h"
+.Ft int
+.Fn rad_send_response "struct rad_handle *h"
+.Ft "struct rad_handle *"
+.Fn rad_server_open "int fd"
 .Ft "const char *"
 .Fn rad_server_secret "struct rad_handle *h"
 .Ft u_char *
@@ -91,16 +100,17 @@
 .Sh DESCRIPTION
 The
 .Nm
-library implements the client side of the Remote Authentication Dial
-In User Service (RADIUS).
+library implements the Remote Authentication Dial In User Service (RADIUS).
 RADIUS, defined in RFCs 2865 and 2866,
 allows clients to perform authentication and accounting by means of
 network requests to remote servers.
 .Ss Initialization
 To use the library, an application must first call
 .Fn rad_auth_open
-or
+,
 .Fn rad_acct_open
+or
+.Fn rad_server_open
 to obtain a
 .Vt "struct rad_handle *" ,
 which provides the context for subsequent operations.
@@ -108,8 +118,10 @@ The former function is used for RADIUS authentication and the
 latter is used for RADIUS accounting.
 Calls to
 .Fn rad_auth_open
-and
+,
 .Fn rad_acct_open
+and
+.Fn rad_server_open
 always succeed unless insufficient virtual memory is available.
 If
 the necessary memory cannot be allocated, the functions return
@@ -451,6 +463,25 @@ subsequent library calls using the same handle.
 .Ss Cleanup
 To free the resources used by the RADIUS library, call
 .Fn rad_close .
+.Ss Server operation
+Server mode operates much alike to client mode, except packet send and receieve
+steps are swapped. To operate as server you should obtain server context with
+.Fn rad_server_open
+function, passing opened and bound UDP socket file descriptor as argument.
+You should define allowed clients and their secrets using
+.Fn rad_add_server
+function. port, timeout and max_tries arguments are ignored in server mode.
+You should call
+.Fn rad_receive_request
+function to receive request from client. If you do not want to block on socket
+read, you are free to use any poll(), select() or non-blocking sockets for
+the socket.
+Received request can be parsed with same parsing functions as for client.
+To respond to the request you should call
+.Fn rad_create_response
+and fill response content with same packet writing functions as for client.
+When packet is ready, it should be sent with
+.Fn rad_send_response
 .Sh RETURN VALUES
 The following functions return a non-negative value on success.
 If
@@ -466,6 +497,8 @@ which can be retrieved using
 .It
 .Fn rad_create_request
 .It
+.Fn rad_create_response
+.It
 .Fn rad_get_attr
 .It
 .Fn rad_put_addr
@@ -483,6 +516,8 @@ which can be retrieved using
 .Fn rad_continue_send_request
 .It
 .Fn rad_send_request
+.It
+.Fn rad_send_response
 .El
 .Pp
 The following functions return a
@@ -499,6 +534,8 @@ without recording an error message.
 .It
 .Fn rad_auth_open
 .It
+.Fn rad_server_open
+.It
 .Fn rad_cvt_string
 .El
 .Pp
@@ -553,3 +590,5 @@ subsequently added the ability to perform RADIUS
 accounting.
 Later additions and changes by
 .An Michael Bretterklieber .
+Server mode support was added by
+.An Alexander Motin .
diff --git a/lib/libradius/radlib.c b/lib/libradius/radlib.c
index b21447ef9c4..8faaf7e12a6 100644
--- a/lib/libradius/radlib.c
+++ b/lib/libradius/radlib.c
@@ -103,7 +103,7 @@ insert_scrambled_password(struct rad_handle *h, int srv)
 	srvp = &h->servers[srv];
 	padded_len = h->pass_len == 0 ? 16 : (h->pass_len+15) & ~0xf;
 
-	memcpy(md5, &h->request[POS_AUTH], LEN_AUTH);
+	memcpy(md5, &h->out[POS_AUTH], LEN_AUTH);
 	for (pos = 0;  pos < padded_len;  pos += 16) {
 		int i;
 
@@ -120,49 +120,55 @@ insert_scrambled_password(struct rad_handle *h, int srv)
 		 * in calculating the scrambler for next time.
 		 */
 		for (i = 0;  i < 16;  i++)
-			h->request[h->pass_pos + pos + i] =
+			h->out[h->pass_pos + pos + i] =
 			    md5[i] ^= h->pass[pos + i];
 	}
 }
 
 static void
-insert_request_authenticator(struct rad_handle *h, int srv)
+insert_request_authenticator(struct rad_handle *h, int resp)
 {
 	MD5_CTX ctx;
 	const struct rad_server *srvp;
 
-	srvp = &h->servers[srv];
+	srvp = &h->servers[h->srv];
 
 	/* Create the request authenticator */
 	MD5Init(&ctx);
-	MD5Update(&ctx, &h->request[POS_CODE], POS_AUTH - POS_CODE);
-	MD5Update(&ctx, memset(&h->request[POS_AUTH], 0, LEN_AUTH), LEN_AUTH);
-	MD5Update(&ctx, &h->request[POS_ATTRS], h->req_len - POS_ATTRS);
+	MD5Update(&ctx, &h->out[POS_CODE], POS_AUTH - POS_CODE);
+	if (resp)
+	    MD5Update(&ctx, &h->in[POS_AUTH], LEN_AUTH);
+	else
+	    MD5Update(&ctx, &h->out[POS_AUTH], LEN_AUTH);
+	MD5Update(&ctx, &h->out[POS_ATTRS], h->out_len - POS_ATTRS);
 	MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
-	MD5Final(&h->request[POS_AUTH], &ctx);
+	MD5Final(&h->out[POS_AUTH], &ctx);
 }
 
 static void
-insert_message_authenticator(struct rad_handle *h, int srv)
+insert_message_authenticator(struct rad_handle *h, int resp)
 {
 #ifdef WITH_SSL
 	u_char md[EVP_MAX_MD_SIZE];
 	u_int md_len;
 	const struct rad_server *srvp;
 	HMAC_CTX ctx;
-	srvp = &h->servers[srv];
+	srvp = &h->servers[h->srv];
 
 	if (h->authentic_pos != 0) {
 		HMAC_CTX_init(&ctx);
 		HMAC_Init(&ctx, srvp->secret, strlen(srvp->secret), EVP_md5());
-		HMAC_Update(&ctx, &h->request[POS_CODE], POS_AUTH - POS_CODE);
-		HMAC_Update(&ctx, &h->request[POS_AUTH], LEN_AUTH);
-		HMAC_Update(&ctx, &h->request[POS_ATTRS],
-		    h->req_len - POS_ATTRS);
+		HMAC_Update(&ctx, &h->out[POS_CODE], POS_AUTH - POS_CODE);
+		if (resp)
+		    HMAC_Update(&ctx, &h->in[POS_AUTH], LEN_AUTH);
+		else
+		    HMAC_Update(&ctx, &h->out[POS_AUTH], LEN_AUTH);
+		HMAC_Update(&ctx, &h->out[POS_ATTRS],
+		    h->out_len - POS_ATTRS);
 		HMAC_Final(&ctx, md, &md_len);
 		HMAC_CTX_cleanup(&ctx);
 		HMAC_cleanup(&ctx);
-		memcpy(&h->request[h->authentic_pos + 2], md, md_len);
+		memcpy(&h->out[h->authentic_pos + 2], md, md_len);
 	}
 #endif
 }
@@ -195,20 +201,20 @@ is_valid_response(struct rad_handle *h, int srv,
 		return 0;
 
 	/* Check the message length */
-	if (h->resp_len < POS_ATTRS)
+	if (h->in_len < POS_ATTRS)
 		return 0;
-	len = h->response[POS_LENGTH] << 8 | h->response[POS_LENGTH+1];
-	if (len > h->resp_len)
+	len = h->in[POS_LENGTH] << 8 | h->in[POS_LENGTH+1];
+	if (len > h->in_len)
 		return 0;
 
 	/* Check the response authenticator */
 	MD5Init(&ctx);
-	MD5Update(&ctx, &h->response[POS_CODE], POS_AUTH - POS_CODE);
-	MD5Update(&ctx, &h->request[POS_AUTH], LEN_AUTH);
-	MD5Update(&ctx, &h->response[POS_ATTRS], len - POS_ATTRS);
+	MD5Update(&ctx, &h->in[POS_CODE], POS_AUTH - POS_CODE);
+	MD5Update(&ctx, &h->out[POS_AUTH], LEN_AUTH);
+	MD5Update(&ctx, &h->in[POS_ATTRS], len - POS_ATTRS);
 	MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
 	MD5Final(md5, &ctx);
-	if (memcmp(&h->response[POS_AUTH], md5, sizeof md5) != 0)
+	if (memcmp(&h->in[POS_AUTH], md5, sizeof md5) != 0)
 		return 0;
 
 #ifdef WITH_SSL
@@ -216,42 +222,111 @@ is_valid_response(struct rad_handle *h, int srv,
 	 * For non accounting responses check the message authenticator,
 	 * if any.
 	 */
-	if (h->response[POS_CODE] != RAD_ACCOUNTING_RESPONSE) {
+	if (h->in[POS_CODE] != RAD_ACCOUNTING_RESPONSE) {
 
-		memcpy(resp, h->response, MSGSIZE);
+		memcpy(resp, h->in, MSGSIZE);
 		pos = POS_ATTRS;
 
 		/* Search and verify the Message-Authenticator */
 		while (pos < len - 2) {
 
-			if (h->response[pos] == RAD_MESSAGE_AUTHENTIC) {
+			if (h->in[pos] == RAD_MESSAGE_AUTHENTIC) {
 				/* zero fill the Message-Authenticator */
 				memset(&resp[pos + 2], 0, MD5_DIGEST_LENGTH);
 
 				HMAC_CTX_init(&hctx);
 				HMAC_Init(&hctx, srvp->secret,
 				    strlen(srvp->secret), EVP_md5());
-				HMAC_Update(&hctx, &h->response[POS_CODE],
+				HMAC_Update(&hctx, &h->in[POS_CODE],
 				    POS_AUTH - POS_CODE);
-				HMAC_Update(&hctx, &h->request[POS_AUTH],
+				HMAC_Update(&hctx, &h->out[POS_AUTH],
 				    LEN_AUTH);
 				HMAC_Update(&hctx, &resp[POS_ATTRS],
-				    h->resp_len - POS_ATTRS);
+				    h->in_len - POS_ATTRS);
 				HMAC_Final(&hctx, md, &md_len);
 				HMAC_CTX_cleanup(&hctx);
 				HMAC_cleanup(&hctx);
-				if (memcmp(md, &h->response[pos + 2],
+				if (memcmp(md, &h->in[pos + 2],
 				    MD5_DIGEST_LENGTH) != 0)
 					return 0;
 				break;
 			}
-			pos += h->response[pos + 1];
+			pos += h->in[pos + 1];
 		}
 	}
 #endif
 	return 1;
 }
 
+/*
+ * Return true if the current request is valid for the specified server.
+ */
+static int
+is_valid_request(struct rad_handle *h)
+{
+	MD5_CTX ctx;
+	unsigned char md5[MD5_DIGEST_LENGTH];
+	const struct rad_server *srvp;
+	int len;
+#ifdef WITH_SSL
+	HMAC_CTX hctx;
+	u_char resp[MSGSIZE], md[EVP_MAX_MD_SIZE];
+	u_int md_len;
+	int pos;
+#endif
+
+	srvp = &h->servers[h->srv];
+
+	/* Check the message length */
+	if (h->in_len < POS_ATTRS)
+		return (0);
+	len = h->in[POS_LENGTH] << 8 | h->in[POS_LENGTH+1];
+	if (len > h->in_len)
+		return (0);
+
+	if (h->in[POS_CODE] != RAD_ACCESS_REQUEST) {
+		uint32_t zeroes[4] = { 0, 0, 0, 0 };
+		/* Check the request authenticator */
+		MD5Init(&ctx);
+		MD5Update(&ctx, &h->in[POS_CODE], POS_AUTH - POS_CODE);
+		MD5Update(&ctx, zeroes, LEN_AUTH);
+		MD5Update(&ctx, &h->in[POS_ATTRS], len - POS_ATTRS);
+		MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
+		MD5Final(md5, &ctx);
+		if (memcmp(&h->in[POS_AUTH], md5, sizeof md5) != 0)
+			return (0);
+	}
+
+#ifdef WITH_SSL
+	/* Search and verify the Message-Authenticator */
+	pos = POS_ATTRS;
+	while (pos < len - 2) {
+		if (h->in[pos] == RAD_MESSAGE_AUTHENTIC) {
+			memcpy(resp, h->in, MSGSIZE);
+			/* zero fill the Request-Authenticator */
+			if (h->in[POS_CODE] != RAD_ACCESS_REQUEST)
+				memset(&resp[POS_AUTH], 0, LEN_AUTH);
+			/* zero fill the Message-Authenticator */
+			memset(&resp[pos + 2], 0, MD5_DIGEST_LENGTH);
+
+			HMAC_CTX_init(&hctx);
+			HMAC_Init(&hctx, srvp->secret,
+			    strlen(srvp->secret), EVP_md5());
+			HMAC_Update(&hctx, resp, h->in_len);
+			HMAC_Final(&hctx, md, &md_len);
+			HMAC_CTX_cleanup(&hctx);
+			HMAC_cleanup(&hctx);
+			if (memcmp(md, &h->in[pos + 2],
+			    MD5_DIGEST_LENGTH) != 0)
+				return (0);
+			break;
+		}
+		pos += h->in[pos + 1];
+	}
+#endif
+	return (1);
+}
+
 static int
 put_password_attr(struct rad_handle *h, int type, const void *value, size_t len)
 {
@@ -273,7 +348,7 @@ put_password_attr(struct rad_handle *h, int type, const void *value, size_t len)
 	 */
 	clear_password(h);
 	put_raw_attr(h, type, h->pass, padded_len);
-	h->pass_pos = h->req_len - padded_len;
+	h->pass_pos = h->out_len - padded_len;
 
 	/* Save the cleartext password, padded as necessary */
 	memcpy(h->pass, value, len);
@@ -289,14 +364,14 @@ put_raw_attr(struct rad_handle *h, int type, const void *value, size_t len)
 		generr(h, "Attribute too long");
 		return -1;
 	}
-	if (h->req_len + 2 + len > MSGSIZE) {
+	if (h->out_len + 2 + len > MSGSIZE) {
 		generr(h, "Maximum message length exceeded");
 		return -1;
 	}
-	h->request[h->req_len++] = type;
-	h->request[h->req_len++] = len + 2;
-	memcpy(&h->request[h->req_len], value, len);
-	h->req_len += len;
+	h->out[h->out_len++] = type;
+	h->out[h->out_len++] = len + 2;
+	memcpy(&h->out[h->out_len], value, len);
+	h->out_len += len;
 	return 0;
 }
 
@@ -523,22 +598,26 @@ rad_continue_send_request(struct rad_handle *h, int selected, int *fd,
 {
 	int n;
 
+	if (h->type == RADIUS_SERVER) {
+		generr(h, "denied function call");
+		return (-1);
+	}
 	if (selected) {
 		struct sockaddr_in from;
 		socklen_t fromlen;
 
 		fromlen = sizeof from;
-		h->resp_len = recvfrom(h->fd, h->response,
+		h->in_len = recvfrom(h->fd, h->in,
 		    MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen);
-		if (h->resp_len == -1) {
+		if (h->in_len == -1) {
 			generr(h, "recvfrom: %s", strerror(errno));
 			return -1;
 		}
 		if (is_valid_response(h, h->srv, &from)) {
-			h->resp_len = h->response[POS_LENGTH] << 8 |
-			    h->response[POS_LENGTH+1];
-			h->resp_pos = POS_ATTRS;
-			return h->response[POS_CODE];
+			h->in_len = h->in[POS_LENGTH] << 8 |
+			    h->in[POS_LENGTH+1];
+			h->in_pos = POS_ATTRS;
+			return h->in[POS_CODE];
 		}
 	}
 
@@ -556,21 +635,22 @@ rad_continue_send_request(struct rad_handle *h, int selected, int *fd,
 		if (++h->srv >= h->num_servers)
 			h->srv = 0;
 
-	if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST)
-		/* Insert the request authenticator into the request */
-		insert_request_authenticator(h, h->srv);
-	else
+	if (h->out[POS_CODE] == RAD_ACCESS_REQUEST) {
 		/* Insert the scrambled password into the request */
 		if (h->pass_pos != 0)
 			insert_scrambled_password(h, h->srv);
-
-	insert_message_authenticator(h, h->srv);
+	}
+	insert_message_authenticator(h, 0);
+	if (h->out[POS_CODE] != RAD_ACCESS_REQUEST) {
+		/* Insert the request authenticator into the request */
+		insert_request_authenticator(h, h->srv);
+	}
 
 	/* Send the request */
-	n = sendto(h->fd, h->request, h->req_len, 0,
+	n = sendto(h->fd, h->out, h->out_len, 0,
 	    (const struct sockaddr *)&h->servers[h->srv].addr,
 	    sizeof h->servers[h->srv].addr);
-	if (n != h->req_len) {
+	if (n != h->out_len) {
 		if (n == -1)
 			generr(h, "sendto: %s", strerror(errno));
 		else
@@ -587,23 +667,118 @@ rad_continue_send_request(struct rad_handle *h, int selected, int *fd,
 	return 0;
 }
 
+int
+rad_receive_request(struct rad_handle *h)
+{
+	struct sockaddr_in from;
+	socklen_t fromlen;
+	int n;
+
+	if (h->type != RADIUS_SERVER) {
+		generr(h, "denied function call");
+		return (-1);
+	}
+	h->srv = -1;
+	fromlen = sizeof(from);
+	h->in_len = recvfrom(h->fd, h->in,
+	    MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen);
+	if (h->in_len == -1) {
+		generr(h, "recvfrom: %s", strerror(errno));
+		return (-1);
+	}
+	for (n = 0; n < h->num_servers; n++) {
+		if (h->servers[n].addr.sin_addr.s_addr == from.sin_addr.s_addr) {
+			h->servers[n].addr.sin_port = from.sin_port;
+			h->srv = n;
+			break;
+		}
+	}
+	if (h->srv == -1)
+		return (-2);
+	if (is_valid_request(h)) {
+		h->in_len = h->in[POS_LENGTH] << 8 |
+		    h->in[POS_LENGTH+1];
+		h->in_pos = POS_ATTRS;
+		return (h->in[POS_CODE]);
+	}
+	return (-3);
+}
+
+int
+rad_send_response(struct rad_handle *h)
+{
+	int n;
+
+	if (h->type != RADIUS_SERVER) {
+		generr(h, "denied function call");
+		return (-1);
+	}
+	/* Fill in the length field in the message */
+	h->out[POS_LENGTH] = h->out_len >> 8;
+	h->out[POS_LENGTH+1] = h->out_len;
+
+	insert_message_authenticator(h,
+	    (h->in[POS_CODE] == RAD_ACCESS_REQUEST) ? 1 : 0);
+	insert_request_authenticator(h, 1);
+
+	/* Send the request */
+	n = sendto(h->fd, h->out, h->out_len, 0,
+	    (const struct sockaddr *)&h->servers[h->srv].addr,
+	    sizeof h->servers[h->srv].addr);
+	if (n != h->out_len) {
+		if (n == -1)
+			generr(h, "sendto: %s", strerror(errno));
+		else
+			generr(h, "sendto: short write");
+		return -1;
+	}
+
+	return 0;
+}
+
 int
 rad_create_request(struct rad_handle *h, int code)
 {
 	int i;
 
-	h->request[POS_CODE] = code;
-	h->request[POS_IDENT] = ++h->ident;
-	/* Create a random authenticator */
-	for (i = 0;  i < LEN_AUTH;  i += 2) {
-		long r;
-		r = random();
-		h->request[POS_AUTH+i] = (u_char)r;
-		h->request[POS_AUTH+i+1] = (u_char)(r >> 8);
+	if (h->type == RADIUS_SERVER) {
+		generr(h, "denied function call");
+		return (-1);
 	}
-	h->req_len = POS_ATTRS;
+	h->out[POS_CODE] = code;
+	h->out[POS_IDENT] = ++h->ident;
+	if (code == RAD_ACCESS_REQUEST) {
+		/* Create a random authenticator */
+		for (i = 0;  i < LEN_AUTH;  i += 2) {
+			long r;
+			r = random();
+			h->out[POS_AUTH+i] = (u_char)r;
+			h->out[POS_AUTH+i+1] = (u_char)(r >> 8);
+		}
+	} else
+		memset(&h->out[POS_AUTH], 0, LEN_AUTH);
+	h->out_len = POS_ATTRS;
 	clear_password(h);
-	h->request_created = 1;
+	h->authentic_pos = 0;
+	h->out_created = 1;
+	return 0;
+}
+
+int
+rad_create_response(struct rad_handle *h, int code)
+{
+
+	if (h->type != RADIUS_SERVER) {
+		generr(h, "denied function call");
+		return (-1);
+	}
+	h->out[POS_CODE] = code;
+	h->out[POS_IDENT] = h->in[POS_IDENT];
+	memset(&h->out[POS_AUTH], 0, LEN_AUTH);
+	h->out_len = POS_ATTRS;
+	clear_password(h);
+	h->authentic_pos = 0;
+	h->out_created = 1;
 	return 0;
 }
 
@@ -647,20 +822,20 @@ rad_get_attr(struct rad_handle *h, const void **value, size_t *len)
 {
 	int type;
 
-	if (h->resp_pos >= h->resp_len)
+	if (h->in_pos >= h->in_len)
 		return 0;
-	if (h->resp_pos + 2 > h->resp_len) {
+	if (h->in_pos + 2 > h->in_len) {
 		generr(h, "Malformed attribute in response");
 		return -1;
 	}
-	type = h->response[h->resp_pos++];
-	*len = h->response[h->resp_pos++] - 2;
-	if (h->resp_pos + (int)*len > h->resp_len) {
+	type = h->in[h->in_pos++];
+	*len = h->in[h->in_pos++] - 2;
+	if (h->in_pos + (int)*len > h->in_len) {
 		generr(h, "Malformed attribute in response");
 		return -1;
 	}
-	*value = &h->response[h->resp_pos];
-	h->resp_pos += *len;
+	*value = &h->in[h->in_pos];
+	h->in_pos += *len;
 	return type;
 }
 
@@ -672,6 +847,10 @@ rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv)
 {
 	int srv;
 
+	if (h->type == RADIUS_SERVER) {
+		generr(h, "denied function call");
+		return (-1);
+	}
 	/* Make sure we have a socket to use */
 	if (h->fd == -1) {
 		struct sockaddr_in sin;
@@ -694,7 +873,7 @@ rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv)
 		}
 	}
 
-	if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) {
+	if (h->out[POS_CODE] != RAD_ACCESS_REQUEST) {
 		/* Make sure no password given */
 		if (h->pass_pos || h->chap_pass) {
 			generr(h, "User or Chap Password"
@@ -718,8 +897,8 @@ rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv)
 	}
 
 	/* Fill in the length field in the message */
-	h->request[POS_LENGTH] = h->req_len >> 8;
-	h->request[POS_LENGTH+1] = h->req_len;
+	h->out[POS_LENGTH] = h->out_len >> 8;
+	h->out[POS_LENGTH+1] = h->out_len;
 
 	/*
 	 * Count the total number of tries we will make, and zero the
@@ -763,7 +942,7 @@ rad_auth_open(void)
 		h->chap_pass = 0;
 		h->authentic_pos = 0;
 		h->type = RADIUS_AUTH;
-		h->request_created = 0;
+		h->out_created = 0;
 		h->eap_msg = 0;
 	}
 	return h;
@@ -780,6 +959,19 @@ rad_acct_open(void)
 	return h;
 }
 
+struct rad_handle *
+rad_server_open(int fd)
+{
+	struct rad_handle *h;
+
+	h = rad_open();
+	if (h != NULL) {
+	        h->type = RADIUS_SERVER;
+	        h->fd = fd;
+	}
+	return h;
+}
+
 struct rad_handle *
 rad_open(void)
 {
@@ -797,13 +989,13 @@ rad_put_attr(struct rad_handle *h, int type, const void *value, size_t len)
 {
 	int result;
 
-	if (!h->request_created) {
+	if (!h->out_created) {
 		generr(h, "Please call rad_create_request()"
 		    " before putting attributes");
 		return -1;
 	}
 
-	if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) {
+	if (h->out[POS_CODE] == RAD_ACCOUNTING_REQUEST) {
 		if (type == RAD_EAP_MESSAGE) {
 			generr(h, "EAP-Message attribute is not valid"
 			    " in accounting requests");
@@ -858,14 +1050,14 @@ rad_put_message_authentic(struct rad_handle *h)
 #ifdef WITH_SSL
 	u_char md_zero[MD5_DIGEST_LENGTH];
 
-	if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) {
+	if (h->out[POS_CODE] == RAD_ACCOUNTING_REQUEST) {
 		generr(h, "Message-Authenticator is not valid"
 		    " in accounting requests");
 		return -1;
 	}
 
 	if (h->authentic_pos == 0) {
-		h->authentic_pos = h->req_len;
+		h->authentic_pos = h->out_len;
 		memset(md_zero, 0, sizeof(md_zero));
 		return (put_raw_attr(h, RAD_MESSAGE_AUTHENTIC, md_zero,
 		    sizeof(md_zero)));
@@ -1041,7 +1233,7 @@ rad_put_vendor_attr(struct rad_handle *h, int vendor, int type,
 	struct vendor_attribute *attr;
 	int res;
 
-	if (!h->request_created) {
+	if (!h->out_created) {
 		generr(h, "Please call rad_create_request()"
 		    " before putting attributes");
 		return -1;
@@ -1088,7 +1280,7 @@ rad_request_authenticator(struct rad_handle *h, char *buf, size_t len)
 {
 	if (len < LEN_AUTH)
 		return (-1);
-	memcpy(buf, h->request + POS_AUTH, LEN_AUTH);
+	memcpy(buf, h->out + POS_AUTH, LEN_AUTH);
 	if (len > LEN_AUTH)
 		buf[LEN_AUTH] = '\0';
 	return (LEN_AUTH);
diff --git a/lib/libradius/radlib.h b/lib/libradius/radlib.h
index 2c42c3a9f40..b26be41d66e 100644
--- a/lib/libradius/radlib.h
+++ b/lib/libradius/radlib.h
@@ -42,6 +42,12 @@
 #define RAD_ACCOUNTING_REQUEST		4
 #define RAD_ACCOUNTING_RESPONSE		5
 #define RAD_ACCESS_CHALLENGE		11
+#define RAD_DISCONNECT_REQUEST		40
+#define RAD_DISCONNECT_ACK		41
+#define RAD_DISCONNECT_NAK		42
+#define RAD_COA_REQUEST			43
+#define RAD_COA_ACK			44
+#define RAD_COA_NAK			45
 
 /* Attribute types and values */
 #define RAD_USER_NAME			1	/* String */
@@ -179,6 +185,8 @@
 #define	RAD_ACCT_MULTI_SESSION_ID	50	/* String */
 #define	RAD_ACCT_LINK_COUNT		51	/* Integer */
 
+#define	RAD_ERROR_CAUSE			101	/* Integer */
+
 struct rad_handle;
 struct timeval;
 
@@ -192,6 +200,7 @@ int			 rad_config(struct rad_handle *, const char *);
 int			 rad_continue_send_request(struct rad_handle *, int,
 			    int *, struct timeval *);
 int			 rad_create_request(struct rad_handle *, int);
+int			 rad_create_response(struct rad_handle *, int);
 struct in_addr		 rad_cvt_addr(const void *);
 u_int32_t		 rad_cvt_int(const void *);
 char			*rad_cvt_string(const void *, size_t);
@@ -209,7 +218,10 @@ int			 rad_put_string(struct rad_handle *, int,
 int			 rad_put_message_authentic(struct rad_handle *);
 ssize_t			 rad_request_authenticator(struct rad_handle *, char *,
 			    size_t);
+int			 rad_receive_request(struct rad_handle *);
 int			 rad_send_request(struct rad_handle *);
+int			 rad_send_response(struct rad_handle *);
+struct rad_handle	*rad_server_open(int fd);
 const char		*rad_server_secret(struct rad_handle *);
 const char		*rad_strerror(struct rad_handle *);
 u_char			*rad_demangle(struct rad_handle *, const void *,
diff --git a/lib/libradius/radlib_private.h b/lib/libradius/radlib_private.h
index d323cbd5fcc..d886c740b3f 100644
--- a/lib/libradius/radlib_private.h
+++ b/lib/libradius/radlib_private.h
@@ -38,6 +38,7 @@
 /* Handle types */
 #define RADIUS_AUTH		0   /* RADIUS authentication, default */
 #define RADIUS_ACCT		1   /* RADIUS accounting */
+#define RADIUS_SERVER		2   /* RADIUS server */
 
 /* Defaults */
 #define MAXTRIES		3
@@ -75,18 +76,18 @@ struct rad_handle {
 	int		 num_servers;	/* Number of valid server entries */
 	int		 ident;		/* Current identifier value */
 	char		 errmsg[ERRSIZE];	/* Most recent error message */
-	unsigned char	 request[MSGSIZE];	/* Request to send */
-	char	 	 request_created; /* rad_create_request() called? */
-	int		 req_len;	/* Length of request */
+	unsigned char	 out[MSGSIZE];	/* Request to send */
+	char		 out_created;	/* rad_create_request() called? */
+	int		 out_len;	/* Length of request */
 	char		 pass[PASSSIZE];	/* Cleartext password */
 	int		 pass_len;	/* Length of cleartext password */
 	int		 pass_pos;	/* Position of scrambled password */
-	char	 	 chap_pass;	/* Have we got a CHAP_PASSWORD ? */
+	char		 chap_pass;	/* Have we got a CHAP_PASSWORD ? */
 	int		 authentic_pos;	/* Position of message authenticator */
 	char		 eap_msg;	/* Are we an EAP Proxy? */
-	unsigned char	 response[MSGSIZE];	/* Response received */
-	int		 resp_len;	/* Length of response */
-	int		 resp_pos;	/* Current position scanning attrs */
+	unsigned char	 in[MSGSIZE];	/* Response received */
+	int		 in_len;	/* Length of response */
+	int		 in_pos;	/* Current position scanning attrs */
 	int		 total_tries;	/* How many requests we'll send */
 	int		 try;		/* How many requests we've sent */
 	int		 srv;		/* Server number we did last */

From e4692ffe5b8d39e89f45fcd48ecb75fb75b1734d Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 30 Oct 2009 13:02:08 +0000
Subject: [PATCH 0439/2592] MFC rev. 197621: Fix bug, when RADIUS client gave
 up after single sendto() error, do not trying backup servers.

PR:		kern/103764, misc/139214
---
 lib/libradius/radlib.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/lib/libradius/radlib.c b/lib/libradius/radlib.c
index 8faaf7e12a6..e4e4a941180 100644
--- a/lib/libradius/radlib.c
+++ b/lib/libradius/radlib.c
@@ -650,17 +650,12 @@ rad_continue_send_request(struct rad_handle *h, int selected, int *fd,
 	n = sendto(h->fd, h->out, h->out_len, 0,
 	    (const struct sockaddr *)&h->servers[h->srv].addr,
 	    sizeof h->servers[h->srv].addr);
-	if (n != h->out_len) {
-		if (n == -1)
-			generr(h, "sendto: %s", strerror(errno));
-		else
-			generr(h, "sendto: short write");
-		return -1;
-	}
-
+	if (n != h->out_len)
+		tv->tv_sec = 1; /* Do not wait full timeout if send failed. */
+	else
+		tv->tv_sec = h->servers[h->srv].timeout;
 	h->try++;
 	h->servers[h->srv].num_tries++;
-	tv->tv_sec = h->servers[h->srv].timeout;
 	tv->tv_usec = 0;
 	*fd = h->fd;
 

From 713444a957016eece080b6779f1ead51d3da90a9 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 15:45:00 +0000
Subject: [PATCH 0440/2592] MFC r198097

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.
---
 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 e7d8e24d0ab3be968c93a4569a0e64b6fdb61fa4 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 16:06:32 +0000
Subject: [PATCH 0441/2592] MFC r196464

Clean up the locking in drm_alloc_resource()
---
 sys/dev/drm/drm_bufs.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/sys/dev/drm/drm_bufs.c b/sys/dev/drm/drm_bufs.c
index 647dee96345..bd31b0ae31a 100644
--- a/sys/dev/drm/drm_bufs.c
+++ b/sys/dev/drm/drm_bufs.c
@@ -45,27 +45,35 @@ __FBSDID("$FreeBSD$");
  */
 static int drm_alloc_resource(struct drm_device *dev, int resource)
 {
+	struct resource *res;
+	int rid;
+
+	DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
 	if (resource >= DRM_MAX_PCI_RESOURCE) {
 		DRM_ERROR("Resource %d too large\n", resource);
 		return 1;
 	}
 
-	DRM_UNLOCK();
 	if (dev->pcir[resource] != NULL) {
-		DRM_LOCK();
 		return 0;
 	}
 
-	dev->pcirid[resource] = PCIR_BAR(resource);
-	dev->pcir[resource] = bus_alloc_resource_any(dev->device,
-	    SYS_RES_MEMORY, &dev->pcirid[resource], RF_SHAREABLE);
+	DRM_UNLOCK();
+	rid = PCIR_BAR(resource);
+	res = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &rid,
+	    RF_SHAREABLE);
 	DRM_LOCK();
-
-	if (dev->pcir[resource] == NULL) {
+	if (res == NULL) {
 		DRM_ERROR("Couldn't find resource 0x%x\n", resource);
 		return 1;
 	}
 
+	if (dev->pcir[resource] == NULL) {
+		dev->pcirid[resource] = rid;
+		dev->pcir[resource] = res;
+	}
+
 	return 0;
 }
 

From 1587b7fc8724cc5f724b2a4a74abc8208e60ac4b Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 16:12:28 +0000
Subject: [PATCH 0442/2592] MFC r196465

Clean up the handling of device minors
---
 sys/dev/drm/drmP.h       | 1 -
 sys/dev/drm/drm_drv.c    | 8 +++-----
 sys/dev/drm/drm_fops.c   | 4 +---
 sys/dev/drm/drm_sysctl.c | 7 ++++---
 4 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h
index e630f861d57..9c5f4a470c6 100644
--- a/sys/dev/drm/drmP.h
+++ b/sys/dev/drm/drmP.h
@@ -416,7 +416,6 @@ struct drm_file {
 	struct drm_device *dev;
 	int		  authenticated;
 	int		  master;
-	int		  minor;
 	pid_t		  pid;
 	uid_t		  uid;
 	drm_magic_t	  magic;
diff --git a/sys/dev/drm/drm_drv.c b/sys/dev/drm/drm_drv.c
index 561afd5e8fb..1fb8342d567 100644
--- a/sys/dev/drm/drm_drv.c
+++ b/sys/dev/drm/drm_drv.c
@@ -53,9 +53,6 @@ static void drm_unload(struct drm_device *dev);
 static drm_pci_id_list_t *drm_find_description(int vendor, int device,
     drm_pci_id_list_t *idlist);
 
-#define DRIVER_SOFTC(unit) \
-	((struct drm_device *)devclass_get_softc(drm_devclass, unit))
-
 MODULE_VERSION(drm, 1);
 MODULE_DEPEND(drm, agp, 1, 1, 1);
 MODULE_DEPEND(drm, pci, 1, 1, 1);
@@ -210,11 +207,12 @@ int drm_attach(device_t kdev, drm_pci_id_list_t *idlist)
 	dev->device = kdev;
 #endif
 	dev->devnode = make_dev(&drm_cdevsw,
-			unit,
+			0,
 			DRM_DEV_UID,
 			DRM_DEV_GID,
 			DRM_DEV_MODE,
 			"dri/card%d", unit);
+	dev->devnode->si_drv1 = dev;
 
 #if __FreeBSD_version >= 700053
 	dev->pci_domain = pci_get_domain(dev->device);
@@ -606,7 +604,7 @@ int drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
 	struct drm_device *dev = NULL;
 	int retcode = 0;
 
-	dev = DRIVER_SOFTC(dev2unit(kdev));
+	dev = kdev->si_drv1;
 
 	DRM_DEBUG("open_count = %d\n", dev->open_count);
 
diff --git a/sys/dev/drm/drm_fops.c b/sys/dev/drm/drm_fops.c
index f766928d651..3f743e04ca9 100644
--- a/sys/dev/drm/drm_fops.c
+++ b/sys/dev/drm/drm_fops.c
@@ -44,14 +44,13 @@ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p,
 		    struct drm_device *dev)
 {
 	struct drm_file *priv;
-	int m = dev2unit(kdev);
 	int retcode;
 
 	if (flags & O_EXCL)
 		return EBUSY; /* No exclusive opens */
 	dev->flags = flags;
 
-	DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m);
+	DRM_DEBUG("pid = %d, device = %s\n", DRM_CURRENTPID, devtoname(kdev));
 
 	priv = malloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO);
 	if (priv == NULL) {
@@ -68,7 +67,6 @@ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p,
 	priv->dev		= dev;
 	priv->uid		= p->td_ucred->cr_svuid;
 	priv->pid		= p->td_proc->p_pid;
-	priv->minor		= m;
 	priv->ioctl_count 	= 0;
 
 	/* for compatibility root is always authenticated */
diff --git a/sys/dev/drm/drm_sysctl.c b/sys/dev/drm/drm_sysctl.c
index 0d59d485a99..cc332833fd6 100644
--- a/sys/dev/drm/drm_sysctl.c
+++ b/sys/dev/drm/drm_sysctl.c
@@ -298,12 +298,13 @@ static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS
 
 	DRM_UNLOCK();
 
-	DRM_SYSCTL_PRINT("\na dev	pid    uid	magic	  ioctls\n");
+	DRM_SYSCTL_PRINT(
+	    "\na dev            pid   uid      magic     ioctls\n");
 	for (i = 0; i < privcount; i++) {
 		priv = &tempprivs[i];
-		DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
+		DRM_SYSCTL_PRINT("%c %-12s %5d %5d %10u %10lu\n",
 			       priv->authenticated ? 'y' : 'n',
-			       priv->minor,
+			       devtoname(priv->dev->devnode),
 			       priv->pid,
 			       priv->uid,
 			       priv->magic,

From d84490b532c8ce9f9c4440d771c2c8ceb77f3ab0 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 16:14:17 +0000
Subject: [PATCH 0443/2592] MFC r196466

Add a read only sysctl tracking the hw.drm.msi tunable.
---
 sys/dev/drm/drmP.h    | 2 ++
 sys/dev/drm/drm_drv.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h
index 9c5f4a470c6..cad2cee623a 100644
--- a/sys/dev/drm/drmP.h
+++ b/sys/dev/drm/drmP.h
@@ -148,6 +148,8 @@ MALLOC_DECLARE(DRM_MEM_CTXBITMAP);
 MALLOC_DECLARE(DRM_MEM_SGLISTS);
 MALLOC_DECLARE(DRM_MEM_DRAWABLE);
 
+SYSCTL_DECL(_hw_drm);
+
 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
 
 				/* Internal types and structures */
diff --git a/sys/dev/drm/drm_drv.c b/sys/dev/drm/drm_drv.c
index 1fb8342d567..c690c34dfa3 100644
--- a/sys/dev/drm/drm_drv.c
+++ b/sys/dev/drm/drm_drv.c
@@ -133,6 +133,9 @@ static struct cdevsw drm_cdevsw = {
 
 static int drm_msi = 1;	/* Enable by default. */
 TUNABLE_INT("hw.drm.msi", &drm_msi);
+SYSCTL_NODE(_hw, OID_AUTO, drm, CTLFLAG_RW, NULL, "DRM device");
+SYSCTL_INT(_hw_drm, OID_AUTO, msi, CTLFLAG_RDTUN, &drm_msi, 1,
+    "Enable MSI interrupts for drm devices");
 
 static struct drm_msi_blacklist_entry drm_msi_blacklist[] = {
 	{0x8086, 0x2772}, /* Intel i945G	*/ \

From 357a8e800b8fc8645897a15ebee343955b53471d Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 16:32:35 +0000
Subject: [PATCH 0444/2592] MFC r196470-196471,197154-197155,197603-197606

Sync radeon drm support

This adds kernel support for r6/7xx 3D.
---
 sys/conf/files                  |    2 +
 sys/dev/drm/drm_pciids.h        |    1 +
 sys/dev/drm/r600_blit.c         | 1990 +++++++++++++++++++++++++++++++
 sys/dev/drm/r600_cp.c           |  135 +++
 sys/dev/drm/radeon_cp.c         |   17 +-
 sys/dev/drm/radeon_cs.c         |  856 +++++++++++++
 sys/dev/drm/radeon_drm.h        |   24 +
 sys/dev/drm/radeon_drv.h        |  124 +-
 sys/dev/drm/radeon_irq.c        |   15 +
 sys/dev/drm/radeon_state.c      |   31 +-
 sys/modules/drm/radeon/Makefile |    4 +-
 11 files changed, 3174 insertions(+), 25 deletions(-)
 create mode 100644 sys/dev/drm/r600_blit.c
 create mode 100644 sys/dev/drm/radeon_cs.c

diff --git a/sys/conf/files b/sys/conf/files
index 68d3ea1ba93..0e418fcac76 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -845,8 +845,10 @@ dev/drm/r128_irq.c		optional r128drm
 dev/drm/r128_state.c		optional r128drm \
 	compile-with "${NORMAL_C} -finline-limit=13500"
 dev/drm/r300_cmdbuf.c		optional radeondrm
+dev/drm/r600_blit.c		optional radeondrm
 dev/drm/r600_cp.c		optional radeondrm
 dev/drm/radeon_cp.c		optional radeondrm
+dev/drm/radeon_cs.c		optional radeondrm
 dev/drm/radeon_drv.c		optional radeondrm
 dev/drm/radeon_irq.c		optional radeondrm
 dev/drm/radeon_mem.c		optional radeondrm
diff --git a/sys/dev/drm/drm_pciids.h b/sys/dev/drm/drm_pciids.h
index 3b2347ed5b6..7cc084c4713 100644
--- a/sys/dev/drm/drm_pciids.h
+++ b/sys/dev/drm/drm_pciids.h
@@ -338,6 +338,7 @@
 	{0x1002, 0x9440, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \
 	{0x1002, 0x9441, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4870 X2"}, \
 	{0x1002, 0x9442, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \
+	{0x1002, 0x9443, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4850 X2"}, \
 	{0x1002, 0x944C, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \
 	{0x1002, 0x9450, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9270"}, \
 	{0x1002, 0x9452, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9250"}, \
diff --git a/sys/dev/drm/r600_blit.c b/sys/dev/drm/r600_blit.c
new file mode 100644
index 00000000000..6443d843f98
--- /dev/null
+++ b/sys/dev/drm/r600_blit.c
@@ -0,0 +1,1990 @@
+/*-
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *     Alex Deucher 
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+
+#include "dev/drm/drmP.h"
+#include "dev/drm/drm.h"
+#include "dev/drm/radeon_drm.h"
+#include "dev/drm/radeon_drv.h"
+
+static u32 r6xx_default_state[] =
+{
+	0xc0002400,
+	0x00000000,
+	0xc0012800,
+	0x80000000,
+	0x80000000,
+	0xc0004600,
+	0x00000016,
+	0xc0016800,
+	0x00000010,
+	0x00028000,
+	0xc0016800,
+	0x00000010,
+	0x00008000,
+	0xc0016800,
+	0x00000542,
+	0x07000003,
+	0xc0016800,
+	0x000005c5,
+	0x00000000,
+	0xc0016800,
+	0x00000363,
+	0x00000000,
+	0xc0016800,
+	0x0000060c,
+	0x82000000,
+	0xc0016800,
+	0x0000060e,
+	0x01020204,
+	0xc0016f00,
+	0x00000000,
+	0x00000000,
+	0xc0016f00,
+	0x00000001,
+	0x00000000,
+	0xc0096900,
+	0x0000022a,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x00000004,
+	0x00000000,
+	0xc0016900,
+	0x0000000a,
+	0x00000000,
+	0xc0016900,
+	0x0000000b,
+	0x00000000,
+	0xc0016900,
+	0x0000010c,
+	0x00000000,
+	0xc0016900,
+	0x0000010d,
+	0x00000000,
+	0xc0016900,
+	0x00000200,
+	0x00000000,
+	0xc0016900,
+	0x00000343,
+	0x00000060,
+	0xc0016900,
+	0x00000344,
+	0x00000040,
+	0xc0016900,
+	0x00000351,
+	0x0000aa00,
+	0xc0016900,
+	0x00000104,
+	0x00000000,
+	0xc0016900,
+	0x0000010e,
+	0x00000000,
+	0xc0046900,
+	0x00000105,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0036900,
+	0x00000109,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0046900,
+	0x0000030c,
+	0x01000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0046900,
+	0x00000048,
+	0x3f800000,
+	0x00000000,
+	0x3f800000,
+	0x3f800000,
+	0xc0016900,
+	0x0000008e,
+	0x0000000f,
+	0xc0016900,
+	0x00000080,
+	0x00000000,
+	0xc0016900,
+	0x00000083,
+	0x0000ffff,
+	0xc0016900,
+	0x00000084,
+	0x00000000,
+	0xc0016900,
+	0x00000085,
+	0x20002000,
+	0xc0016900,
+	0x00000086,
+	0x00000000,
+	0xc0016900,
+	0x00000087,
+	0x20002000,
+	0xc0016900,
+	0x00000088,
+	0x00000000,
+	0xc0016900,
+	0x00000089,
+	0x20002000,
+	0xc0016900,
+	0x0000008a,
+	0x00000000,
+	0xc0016900,
+	0x0000008b,
+	0x20002000,
+	0xc0016900,
+	0x0000008c,
+	0x00000000,
+	0xc0016900,
+	0x00000094,
+	0x80000000,
+	0xc0016900,
+	0x00000095,
+	0x20002000,
+	0xc0026900,
+	0x000000b4,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000096,
+	0x80000000,
+	0xc0016900,
+	0x00000097,
+	0x20002000,
+	0xc0026900,
+	0x000000b6,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000098,
+	0x80000000,
+	0xc0016900,
+	0x00000099,
+	0x20002000,
+	0xc0026900,
+	0x000000b8,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009a,
+	0x80000000,
+	0xc0016900,
+	0x0000009b,
+	0x20002000,
+	0xc0026900,
+	0x000000ba,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009c,
+	0x80000000,
+	0xc0016900,
+	0x0000009d,
+	0x20002000,
+	0xc0026900,
+	0x000000bc,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009e,
+	0x80000000,
+	0xc0016900,
+	0x0000009f,
+	0x20002000,
+	0xc0026900,
+	0x000000be,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a0,
+	0x80000000,
+	0xc0016900,
+	0x000000a1,
+	0x20002000,
+	0xc0026900,
+	0x000000c0,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a2,
+	0x80000000,
+	0xc0016900,
+	0x000000a3,
+	0x20002000,
+	0xc0026900,
+	0x000000c2,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a4,
+	0x80000000,
+	0xc0016900,
+	0x000000a5,
+	0x20002000,
+	0xc0026900,
+	0x000000c4,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a6,
+	0x80000000,
+	0xc0016900,
+	0x000000a7,
+	0x20002000,
+	0xc0026900,
+	0x000000c6,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a8,
+	0x80000000,
+	0xc0016900,
+	0x000000a9,
+	0x20002000,
+	0xc0026900,
+	0x000000c8,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000aa,
+	0x80000000,
+	0xc0016900,
+	0x000000ab,
+	0x20002000,
+	0xc0026900,
+	0x000000ca,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000ac,
+	0x80000000,
+	0xc0016900,
+	0x000000ad,
+	0x20002000,
+	0xc0026900,
+	0x000000cc,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000ae,
+	0x80000000,
+	0xc0016900,
+	0x000000af,
+	0x20002000,
+	0xc0026900,
+	0x000000ce,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000b0,
+	0x80000000,
+	0xc0016900,
+	0x000000b1,
+	0x20002000,
+	0xc0026900,
+	0x000000d0,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000b2,
+	0x80000000,
+	0xc0016900,
+	0x000000b3,
+	0x20002000,
+	0xc0026900,
+	0x000000d2,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000293,
+	0x00004010,
+	0xc0016900,
+	0x00000300,
+	0x00000000,
+	0xc0016900,
+	0x00000301,
+	0x00000000,
+	0xc0016900,
+	0x00000312,
+	0xffffffff,
+	0xc0016900,
+	0x00000307,
+	0x00000000,
+	0xc0016900,
+	0x00000308,
+	0x00000000,
+	0xc0016900,
+	0x00000283,
+	0x00000000,
+	0xc0016900,
+	0x00000292,
+	0x00000000,
+	0xc0066900,
+	0x0000010f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x00000206,
+	0x00000000,
+	0xc0016900,
+	0x00000207,
+	0x00000000,
+	0xc0016900,
+	0x00000208,
+	0x00000000,
+	0xc0046900,
+	0x00000303,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0xc0016900,
+	0x00000205,
+	0x00000004,
+	0xc0016900,
+	0x00000280,
+	0x00000000,
+	0xc0016900,
+	0x00000281,
+	0x00000000,
+	0xc0016900,
+	0x0000037e,
+	0x00000000,
+	0xc0016900,
+	0x00000382,
+	0x00000000,
+	0xc0016900,
+	0x00000380,
+	0x00000000,
+	0xc0016900,
+	0x00000383,
+	0x00000000,
+	0xc0016900,
+	0x00000381,
+	0x00000000,
+	0xc0016900,
+	0x00000282,
+	0x00000008,
+	0xc0016900,
+	0x00000302,
+	0x0000002d,
+	0xc0016900,
+	0x0000037f,
+	0x00000000,
+	0xc0016900,
+	0x000001b2,
+	0x00000000,
+	0xc0016900,
+	0x000001b6,
+	0x00000000,
+	0xc0016900,
+	0x000001b7,
+	0x00000000,
+	0xc0016900,
+	0x000001b8,
+	0x00000000,
+	0xc0016900,
+	0x000001b9,
+	0x00000000,
+	0xc0016900,
+	0x00000225,
+	0x00000000,
+	0xc0016900,
+	0x00000229,
+	0x00000000,
+	0xc0016900,
+	0x00000237,
+	0x00000000,
+	0xc0016900,
+	0x00000100,
+	0x00000800,
+	0xc0016900,
+	0x00000101,
+	0x00000000,
+	0xc0016900,
+	0x00000102,
+	0x00000000,
+	0xc0016900,
+	0x000002a8,
+	0x00000000,
+	0xc0016900,
+	0x000002a9,
+	0x00000000,
+	0xc0016900,
+	0x00000103,
+	0x00000000,
+	0xc0016900,
+	0x00000284,
+	0x00000000,
+	0xc0016900,
+	0x00000290,
+	0x00000000,
+	0xc0016900,
+	0x00000285,
+	0x00000000,
+	0xc0016900,
+	0x00000286,
+	0x00000000,
+	0xc0016900,
+	0x00000287,
+	0x00000000,
+	0xc0016900,
+	0x00000288,
+	0x00000000,
+	0xc0016900,
+	0x00000289,
+	0x00000000,
+	0xc0016900,
+	0x0000028a,
+	0x00000000,
+	0xc0016900,
+	0x0000028b,
+	0x00000000,
+	0xc0016900,
+	0x0000028c,
+	0x00000000,
+	0xc0016900,
+	0x0000028d,
+	0x00000000,
+	0xc0016900,
+	0x0000028e,
+	0x00000000,
+	0xc0016900,
+	0x0000028f,
+	0x00000000,
+	0xc0016900,
+	0x000002a1,
+	0x00000000,
+	0xc0016900,
+	0x000002a5,
+	0x00000000,
+	0xc0016900,
+	0x000002ac,
+	0x00000000,
+	0xc0016900,
+	0x000002ad,
+	0x00000000,
+	0xc0016900,
+	0x000002ae,
+	0x00000000,
+	0xc0016900,
+	0x000002c8,
+	0x00000000,
+	0xc0016900,
+	0x00000206,
+	0x00000100,
+	0xc0016900,
+	0x00000204,
+	0x00010000,
+	0xc0036e00,
+	0x00000000,
+	0x00000012,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x0000008f,
+	0x0000000f,
+	0xc0016900,
+	0x000001e8,
+	0x00000001,
+	0xc0016900,
+	0x00000202,
+	0x00cc0000,
+	0xc0016900,
+	0x00000205,
+	0x00000244,
+	0xc0016900,
+	0x00000203,
+	0x00000210,
+	0xc0016900,
+	0x000001b1,
+	0x00000000,
+	0xc0016900,
+	0x00000185,
+	0x00000000,
+	0xc0016900,
+	0x000001b3,
+	0x00000001,
+	0xc0016900,
+	0x000001b4,
+	0x00000000,
+	0xc0016900,
+	0x00000191,
+	0x00000b00,
+	0xc0016900,
+	0x000001b5,
+	0x00000000,
+};
+
+static u32 r7xx_default_state[] =
+{
+	0xc0012800,
+	0x80000000,
+	0x80000000,
+	0xc0004600,
+	0x00000016,
+	0xc0016800,
+	0x00000010,
+	0x00028000,
+	0xc0016800,
+	0x00000010,
+	0x00008000,
+	0xc0016800,
+	0x00000542,
+	0x07000002,
+	0xc0016800,
+	0x000005c5,
+	0x00000000,
+	0xc0016800,
+	0x00000363,
+	0x00004000,
+	0xc0016800,
+	0x0000060c,
+	0x00000000,
+	0xc0016800,
+	0x0000060e,
+	0x00420204,
+	0xc0016f00,
+	0x00000000,
+	0x00000000,
+	0xc0016f00,
+	0x00000001,
+	0x00000000,
+	0xc0096900,
+	0x0000022a,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x00000004,
+	0x00000000,
+	0xc0016900,
+	0x0000000a,
+	0x00000000,
+	0xc0016900,
+	0x0000000b,
+	0x00000000,
+	0xc0016900,
+	0x0000010c,
+	0x00000000,
+	0xc0016900,
+	0x0000010d,
+	0x00000000,
+	0xc0016900,
+	0x00000200,
+	0x00000000,
+	0xc0016900,
+	0x00000343,
+	0x00000060,
+	0xc0016900,
+	0x00000344,
+	0x00000000,
+	0xc0016900,
+	0x00000351,
+	0x0000aa00,
+	0xc0016900,
+	0x00000104,
+	0x00000000,
+	0xc0016900,
+	0x0000010e,
+	0x00000000,
+	0xc0046900,
+	0x00000105,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0046900,
+	0x0000030c,
+	0x01000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x0000008e,
+	0x0000000f,
+	0xc0016900,
+	0x00000080,
+	0x00000000,
+	0xc0016900,
+	0x00000083,
+	0x0000ffff,
+	0xc0016900,
+	0x00000084,
+	0x00000000,
+	0xc0016900,
+	0x00000085,
+	0x20002000,
+	0xc0016900,
+	0x00000086,
+	0x00000000,
+	0xc0016900,
+	0x00000087,
+	0x20002000,
+	0xc0016900,
+	0x00000088,
+	0x00000000,
+	0xc0016900,
+	0x00000089,
+	0x20002000,
+	0xc0016900,
+	0x0000008a,
+	0x00000000,
+	0xc0016900,
+	0x0000008b,
+	0x20002000,
+	0xc0016900,
+	0x0000008c,
+	0xaaaaaaaa,
+	0xc0016900,
+	0x00000094,
+	0x80000000,
+	0xc0016900,
+	0x00000095,
+	0x20002000,
+	0xc0026900,
+	0x000000b4,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000096,
+	0x80000000,
+	0xc0016900,
+	0x00000097,
+	0x20002000,
+	0xc0026900,
+	0x000000b6,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000098,
+	0x80000000,
+	0xc0016900,
+	0x00000099,
+	0x20002000,
+	0xc0026900,
+	0x000000b8,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009a,
+	0x80000000,
+	0xc0016900,
+	0x0000009b,
+	0x20002000,
+	0xc0026900,
+	0x000000ba,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009c,
+	0x80000000,
+	0xc0016900,
+	0x0000009d,
+	0x20002000,
+	0xc0026900,
+	0x000000bc,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009e,
+	0x80000000,
+	0xc0016900,
+	0x0000009f,
+	0x20002000,
+	0xc0026900,
+	0x000000be,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a0,
+	0x80000000,
+	0xc0016900,
+	0x000000a1,
+	0x20002000,
+	0xc0026900,
+	0x000000c0,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a2,
+	0x80000000,
+	0xc0016900,
+	0x000000a3,
+	0x20002000,
+	0xc0026900,
+	0x000000c2,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a4,
+	0x80000000,
+	0xc0016900,
+	0x000000a5,
+	0x20002000,
+	0xc0026900,
+	0x000000c4,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a6,
+	0x80000000,
+	0xc0016900,
+	0x000000a7,
+	0x20002000,
+	0xc0026900,
+	0x000000c6,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a8,
+	0x80000000,
+	0xc0016900,
+	0x000000a9,
+	0x20002000,
+	0xc0026900,
+	0x000000c8,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000aa,
+	0x80000000,
+	0xc0016900,
+	0x000000ab,
+	0x20002000,
+	0xc0026900,
+	0x000000ca,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000ac,
+	0x80000000,
+	0xc0016900,
+	0x000000ad,
+	0x20002000,
+	0xc0026900,
+	0x000000cc,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000ae,
+	0x80000000,
+	0xc0016900,
+	0x000000af,
+	0x20002000,
+	0xc0026900,
+	0x000000ce,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000b0,
+	0x80000000,
+	0xc0016900,
+	0x000000b1,
+	0x20002000,
+	0xc0026900,
+	0x000000d0,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000b2,
+	0x80000000,
+	0xc0016900,
+	0x000000b3,
+	0x20002000,
+	0xc0026900,
+	0x000000d2,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000293,
+	0x00514000,
+	0xc0016900,
+	0x00000300,
+	0x00000000,
+	0xc0016900,
+	0x00000301,
+	0x00000000,
+	0xc0016900,
+	0x00000312,
+	0xffffffff,
+	0xc0016900,
+	0x00000307,
+	0x00000000,
+	0xc0016900,
+	0x00000308,
+	0x00000000,
+	0xc0016900,
+	0x00000283,
+	0x00000000,
+	0xc0016900,
+	0x00000292,
+	0x00000000,
+	0xc0066900,
+	0x0000010f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x00000206,
+	0x00000000,
+	0xc0016900,
+	0x00000207,
+	0x00000000,
+	0xc0016900,
+	0x00000208,
+	0x00000000,
+	0xc0046900,
+	0x00000303,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0xc0016900,
+	0x00000205,
+	0x00000004,
+	0xc0016900,
+	0x00000280,
+	0x00000000,
+	0xc0016900,
+	0x00000281,
+	0x00000000,
+	0xc0016900,
+	0x0000037e,
+	0x00000000,
+	0xc0016900,
+	0x00000382,
+	0x00000000,
+	0xc0016900,
+	0x00000380,
+	0x00000000,
+	0xc0016900,
+	0x00000383,
+	0x00000000,
+	0xc0016900,
+	0x00000381,
+	0x00000000,
+	0xc0016900,
+	0x00000282,
+	0x00000008,
+	0xc0016900,
+	0x00000302,
+	0x0000002d,
+	0xc0016900,
+	0x0000037f,
+	0x00000000,
+	0xc0016900,
+	0x000001b2,
+	0x00000001,
+	0xc0016900,
+	0x000001b6,
+	0x00000000,
+	0xc0016900,
+	0x000001b7,
+	0x00000000,
+	0xc0016900,
+	0x000001b8,
+	0x00000000,
+	0xc0016900,
+	0x000001b9,
+	0x00000000,
+	0xc0016900,
+	0x00000225,
+	0x00000000,
+	0xc0016900,
+	0x00000229,
+	0x00000000,
+	0xc0016900,
+	0x00000237,
+	0x00000000,
+	0xc0016900,
+	0x00000100,
+	0x00000800,
+	0xc0016900,
+	0x00000101,
+	0x00000000,
+	0xc0016900,
+	0x00000102,
+	0x00000000,
+	0xc0016900,
+	0x000002a8,
+	0x00000000,
+	0xc0016900,
+	0x000002a9,
+	0x00000000,
+	0xc0016900,
+	0x00000103,
+	0x00000000,
+	0xc0016900,
+	0x00000284,
+	0x00000000,
+	0xc0016900,
+	0x00000290,
+	0x00000000,
+	0xc0016900,
+	0x00000285,
+	0x00000000,
+	0xc0016900,
+	0x00000286,
+	0x00000000,
+	0xc0016900,
+	0x00000287,
+	0x00000000,
+	0xc0016900,
+	0x00000288,
+	0x00000000,
+	0xc0016900,
+	0x00000289,
+	0x00000000,
+	0xc0016900,
+	0x0000028a,
+	0x00000000,
+	0xc0016900,
+	0x0000028b,
+	0x00000000,
+	0xc0016900,
+	0x0000028c,
+	0x00000000,
+	0xc0016900,
+	0x0000028d,
+	0x00000000,
+	0xc0016900,
+	0x0000028e,
+	0x00000000,
+	0xc0016900,
+	0x0000028f,
+	0x00000000,
+	0xc0016900,
+	0x000002a1,
+	0x00000000,
+	0xc0016900,
+	0x000002a5,
+	0x00000000,
+	0xc0016900,
+	0x000002ac,
+	0x00000000,
+	0xc0016900,
+	0x000002ad,
+	0x00000000,
+	0xc0016900,
+	0x000002ae,
+	0x00000000,
+	0xc0016900,
+	0x000002c8,
+	0x00000000,
+	0xc0016900,
+	0x00000206,
+	0x00000100,
+	0xc0016900,
+	0x00000204,
+	0x00010000,
+	0xc0036e00,
+	0x00000000,
+	0x00000012,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x0000008f,
+	0x0000000f,
+	0xc0016900,
+	0x000001e8,
+	0x00000001,
+	0xc0016900,
+	0x00000202,
+	0x00cc0000,
+	0xc0016900,
+	0x00000205,
+	0x00000244,
+	0xc0016900,
+	0x00000203,
+	0x00000210,
+	0xc0016900,
+	0x000001b1,
+	0x00000000,
+	0xc0016900,
+	0x00000185,
+	0x00000000,
+	0xc0016900,
+	0x000001b3,
+	0x00000001,
+	0xc0016900,
+	0x000001b4,
+	0x00000000,
+	0xc0016900,
+	0x00000191,
+	0x00000b00,
+	0xc0016900,
+	0x000001b5,
+	0x00000000,
+};
+
+/* same for r6xx/r7xx */
+static u32 r6xx_vs[] =
+{
+	0x00000004,
+	0x81000000,
+	0x0000203c,
+	0x94000b08,
+	0x00004000,
+	0x14200b1a,
+	0x00000000,
+	0x00000000,
+	0x3c000000,
+	0x68cd1000,
+	0x00080000,
+	0x00000000,
+};
+
+static u32 r6xx_ps[] =
+{
+	0x00000002,
+	0x80800000,
+	0x00000000,
+	0x94200688,
+	0x00000010,
+	0x000d1000,
+	0xb0800000,
+	0x00000000,
+};
+
+#define DI_PT_RECTLIST 0x11
+#define DI_INDEX_SIZE_16_BIT 0x0
+#define DI_SRC_SEL_AUTO_INDEX 0x2
+
+#define FMT_8 1
+#define FMT_5_6_5 8
+#define FMT_8_8_8_8 0x1a
+#define COLOR_8 1
+#define COLOR_5_6_5 8
+#define COLOR_8_8_8_8 0x1a
+
+#define R600_CB0_DEST_BASE_ENA (1 << 6)
+#define R600_TC_ACTION_ENA (1 << 23)
+#define R600_VC_ACTION_ENA (1 << 24)
+#define R600_CB_ACTION_ENA (1 << 25)
+#define R600_DB_ACTION_ENA (1 << 26)
+#define R600_SH_ACTION_ENA (1 << 27)
+#define R600_SMX_ACTION_ENA (1 << 28)
+
+#define R600_CB_COLOR0_SIZE 0x28060
+#define R600_CB_COLOR0_VIEW 0x28080
+#define R600_CB_COLOR0_INFO 0x280a0
+#define R600_CB_COLOR0_TILE 0x280c0
+#define R600_CB_COLOR0_FRAG 0x280e0
+#define R600_CB_COLOR0_MASK 0x28100
+
+#define R600_SQ_PGM_START_VS                                   0x28858
+#define R600_SQ_PGM_RESOURCES_VS 0x28868
+#define R600_SQ_PGM_CF_OFFSET_VS 0x288d0
+#define R600_SQ_PGM_START_PS                                   0x28840
+#define R600_SQ_PGM_RESOURCES_PS 0x28850
+#define R600_SQ_PGM_EXPORTS_PS 0x28854
+#define R600_SQ_PGM_CF_OFFSET_PS 0x288cc
+
+#define R600_VGT_PRIMITIVE_TYPE 0x8958
+
+#define R600_PA_SC_SCREEN_SCISSOR_TL 0x28030
+#define R600_PA_SC_GENERIC_SCISSOR_TL 0x28240
+#define R600_PA_SC_WINDOW_SCISSOR_TL 0x28204
+
+#define R600_SQ_TEX_VTX_INVALID_TEXTURE                        0x0
+#define R600_SQ_TEX_VTX_INVALID_BUFFER                         0x1
+#define R600_SQ_TEX_VTX_VALID_TEXTURE                          0x2
+#define R600_SQ_TEX_VTX_VALID_BUFFER                           0x3
+
+/* packet 3 type offsets */
+#define R600_SET_CONFIG_REG_OFFSET                             0x00008000
+#define R600_SET_CONFIG_REG_END                                0x0000ac00
+#define R600_SET_CONTEXT_REG_OFFSET                            0x00028000
+#define R600_SET_CONTEXT_REG_END                               0x00029000
+#define R600_SET_ALU_CONST_OFFSET                              0x00030000
+#define R600_SET_ALU_CONST_END                                 0x00032000
+#define R600_SET_RESOURCE_OFFSET                               0x00038000
+#define R600_SET_RESOURCE_END                                  0x0003c000
+#define R600_SET_SAMPLER_OFFSET                                0x0003c000
+#define R600_SET_SAMPLER_END                                   0x0003cff0
+#define R600_SET_CTL_CONST_OFFSET                              0x0003cff0
+#define R600_SET_CTL_CONST_END                                 0x0003e200
+#define R600_SET_LOOP_CONST_OFFSET                             0x0003e200
+#define R600_SET_LOOP_CONST_END                                0x0003e380
+#define R600_SET_BOOL_CONST_OFFSET                             0x0003e380
+#define R600_SET_BOOL_CONST_END                                0x00040000
+
+/* Packet 3 types */
+#define R600_IT_INDIRECT_BUFFER_END               0x00001700
+#define R600_IT_SET_PREDICATION                   0x00002000
+#define R600_IT_REG_RMW                           0x00002100
+#define R600_IT_COND_EXEC                         0x00002200
+#define R600_IT_PRED_EXEC                         0x00002300
+#define R600_IT_START_3D_CMDBUF                   0x00002400
+#define R600_IT_DRAW_INDEX_2                      0x00002700
+#define R600_IT_CONTEXT_CONTROL                   0x00002800
+#define R600_IT_DRAW_INDEX_IMMD_BE                0x00002900
+#define R600_IT_INDEX_TYPE                        0x00002A00
+#define R600_IT_DRAW_INDEX                        0x00002B00
+#define R600_IT_DRAW_INDEX_AUTO                   0x00002D00
+#define R600_IT_DRAW_INDEX_IMMD                   0x00002E00
+#define R600_IT_NUM_INSTANCES                     0x00002F00
+#define R600_IT_STRMOUT_BUFFER_UPDATE             0x00003400
+#define R600_IT_INDIRECT_BUFFER_MP                0x00003800
+#define R600_IT_MEM_SEMAPHORE                     0x00003900
+#define R600_IT_MPEG_INDEX                        0x00003A00
+#define R600_IT_WAIT_REG_MEM                      0x00003C00
+#define R600_IT_MEM_WRITE                         0x00003D00
+#define R600_IT_INDIRECT_BUFFER                   0x00003200
+#define R600_IT_CP_INTERRUPT                      0x00004000
+#define R600_IT_SURFACE_SYNC                      0x00004300
+#define R600_IT_ME_INITIALIZE                     0x00004400
+#define R600_IT_COND_WRITE                        0x00004500
+#define R600_IT_EVENT_WRITE                       0x00004600
+#define R600_IT_EVENT_WRITE_EOP                   0x00004700
+#define R600_IT_ONE_REG_WRITE                     0x00005700
+#define R600_IT_SET_CONFIG_REG                    0x00006800
+#define R600_IT_SET_CONTEXT_REG                   0x00006900
+#define R600_IT_SET_ALU_CONST                     0x00006A00
+#define R600_IT_SET_BOOL_CONST                    0x00006B00
+#define R600_IT_SET_LOOP_CONST                    0x00006C00
+#define R600_IT_SET_RESOURCE                      0x00006D00
+#define R600_IT_SET_SAMPLER                       0x00006E00
+#define R600_IT_SET_CTL_CONST                     0x00006F00
+#define R600_IT_SURFACE_BASE_UPDATE               0x00007300
+
+static inline void
+set_render_target(drm_radeon_private_t *dev_priv, int format, int w, int h, u64 gpu_addr)
+{
+	u32 cb_color_info;
+	int pitch, slice;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	h = (h + 7) & ~7;
+	if (h < 8)
+		h = 8;
+
+	cb_color_info = ((format << 2) | (1 << 27));
+	pitch = (w / 8) - 1;
+	slice = ((w * h) / 64) - 1;
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600) &&
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) {
+		BEGIN_RING(21 + 2);
+		OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+		OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+		OUT_RING(gpu_addr >> 8);
+		OUT_RING(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0));
+		OUT_RING(2 << 0);
+	} else {
+		BEGIN_RING(21);
+		OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+		OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+		OUT_RING(gpu_addr >> 8);
+	}
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_CB_COLOR0_SIZE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((pitch << 0) | (slice << 10));
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_CB_COLOR0_VIEW - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_CB_COLOR0_INFO - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(cb_color_info);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_CB_COLOR0_TILE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_CB_COLOR0_FRAG - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_CB_COLOR0_MASK - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	ADVANCE_RING();
+}
+
+static inline void
+cp_set_surface_sync(drm_radeon_private_t *dev_priv,
+		    u32 sync_type, u32 size, u64 mc_addr)
+{
+	u32 cp_coher_size;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	if (size == 0xffffffff)
+		cp_coher_size = 0xffffffff;
+	else
+		cp_coher_size = ((size + 255) >> 8);
+
+	BEGIN_RING(5);
+	OUT_RING(CP_PACKET3(R600_IT_SURFACE_SYNC, 3));
+	OUT_RING(sync_type);
+	OUT_RING(cp_coher_size);
+	OUT_RING((mc_addr >> 8));
+	OUT_RING(10); /* poll interval */
+	ADVANCE_RING();
+}
+
+static inline void
+set_shaders(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	u64 gpu_addr;
+	int shader_size, i;
+	u32 *vs, *ps;
+	uint32_t sq_pgm_resources;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	/* load shaders */
+	vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset);
+	ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256);
+
+	shader_size = sizeof(r6xx_vs) / 4;
+	for (i= 0; i < shader_size; i++)
+		vs[i] = r6xx_vs[i];
+	shader_size = sizeof(r6xx_ps) / 4;
+	for (i= 0; i < shader_size; i++)
+		ps[i] = r6xx_ps[i];
+
+	dev_priv->blit_vb->used = 512;
+
+	gpu_addr = dev_priv->gart_buffers_offset + dev_priv->blit_vb->offset;
+
+	/* setup shader regs */
+	sq_pgm_resources = (1 << 0);
+
+	BEGIN_RING(9 + 12);
+	/* VS */
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_SQ_PGM_START_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(gpu_addr >> 8);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_SQ_PGM_RESOURCES_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(sq_pgm_resources);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_SQ_PGM_CF_OFFSET_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	/* PS */
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_SQ_PGM_START_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((gpu_addr + 256) >> 8);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_SQ_PGM_RESOURCES_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(sq_pgm_resources | (1 << 28));
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_SQ_PGM_EXPORTS_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(2);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+        OUT_RING((R600_SQ_PGM_CF_OFFSET_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+	ADVANCE_RING();
+
+	cp_set_surface_sync(dev_priv,
+			    R600_SH_ACTION_ENA, 512, gpu_addr);
+}
+
+static inline void
+set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr)
+{
+	uint32_t sq_vtx_constant_word2;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8));
+
+	BEGIN_RING(9);
+	OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
+	OUT_RING(0x460);
+	OUT_RING(gpu_addr & 0xffffffff);
+	OUT_RING(48 - 1);
+	OUT_RING(sq_vtx_constant_word2);
+	OUT_RING(1 << 0);
+	OUT_RING(0);
+	OUT_RING(0);
+	OUT_RING(R600_SQ_TEX_VTX_VALID_BUFFER << 30);
+	ADVANCE_RING();
+
+	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_RV710))
+		cp_set_surface_sync(dev_priv,
+				    R600_TC_ACTION_ENA, 48, gpu_addr);
+	else
+		cp_set_surface_sync(dev_priv,
+				    R600_VC_ACTION_ENA, 48, gpu_addr);
+}
+
+static inline void
+set_tex_resource(drm_radeon_private_t *dev_priv,
+		 int format, int w, int h, int pitch, u64 gpu_addr)
+{
+	uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	if (h < 1)
+		h = 1;
+
+	sq_tex_resource_word0 = (1 << 0);
+	sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) |
+				  ((w - 1) << 19));
+
+	sq_tex_resource_word1 = (format << 26);
+	sq_tex_resource_word1 |= ((h - 1) << 0);
+
+	sq_tex_resource_word4 = ((1 << 14) |
+				 (0 << 16) |
+				 (1 << 19) |
+				 (2 << 22) |
+				 (3 << 25));
+
+	BEGIN_RING(9);
+	OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
+	OUT_RING(0);
+	OUT_RING(sq_tex_resource_word0);
+	OUT_RING(sq_tex_resource_word1);
+	OUT_RING(gpu_addr >> 8);
+	OUT_RING(gpu_addr >> 8);
+	OUT_RING(sq_tex_resource_word4);
+	OUT_RING(0);
+	OUT_RING(R600_SQ_TEX_VTX_VALID_TEXTURE << 30);
+	ADVANCE_RING();
+
+}
+
+static inline void
+set_scissors(drm_radeon_private_t *dev_priv, int x1, int y1, int x2, int y2)
+{
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	BEGIN_RING(12);
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
+        OUT_RING((R600_PA_SC_SCREEN_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((x1 << 0) | (y1 << 16));
+	OUT_RING((x2 << 0) | (y2 << 16));
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
+        OUT_RING((R600_PA_SC_GENERIC_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31));
+	OUT_RING((x2 << 0) | (y2 << 16));
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
+        OUT_RING((R600_PA_SC_WINDOW_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31));
+	OUT_RING((x2 << 0) | (y2 << 16));
+	ADVANCE_RING();
+}
+
+static inline void
+draw_auto(drm_radeon_private_t *dev_priv)
+{
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	BEGIN_RING(10);
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
+        OUT_RING((R600_VGT_PRIMITIVE_TYPE - R600_SET_CONFIG_REG_OFFSET) >> 2);
+	OUT_RING(DI_PT_RECTLIST);
+
+	OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
+	OUT_RING(DI_INDEX_SIZE_16_BIT);
+
+	OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
+	OUT_RING(1);
+
+	OUT_RING(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
+	OUT_RING(3);
+	OUT_RING(DI_SRC_SEL_AUTO_INDEX);
+
+	ADVANCE_RING();
+	COMMIT_RING();
+}
+
+static inline void
+set_default_state(drm_radeon_private_t *dev_priv)
+{
+	int default_state_dw, i;
+	u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2;
+	u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2;
+	int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs;
+	int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads;
+	int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;
+	RING_LOCALS;
+
+	switch ((dev_priv->flags & RADEON_FAMILY_MASK)) {
+	case CHIP_R600:
+		num_ps_gprs = 192;
+		num_vs_gprs = 56;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 136;
+		num_vs_threads = 48;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 128;
+		num_vs_stack_entries = 128;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	case CHIP_RV630:
+	case CHIP_RV635:
+		num_ps_gprs = 84;
+		num_vs_gprs = 36;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 144;
+		num_vs_threads = 40;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 40;
+		num_vs_stack_entries = 40;
+		num_gs_stack_entries = 32;
+		num_es_stack_entries = 16;
+		break;
+	case CHIP_RV610:
+	case CHIP_RV620:
+	case CHIP_RS780:
+	/*case CHIP_RS880:*/
+	default:
+		num_ps_gprs = 84;
+		num_vs_gprs = 36;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 136;
+		num_vs_threads = 48;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 40;
+		num_vs_stack_entries = 40;
+		num_gs_stack_entries = 32;
+		num_es_stack_entries = 16;
+		break;
+	case CHIP_RV670:
+		num_ps_gprs = 144;
+		num_vs_gprs = 40;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 136;
+		num_vs_threads = 48;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 40;
+		num_vs_stack_entries = 40;
+		num_gs_stack_entries = 32;
+		num_es_stack_entries = 16;
+		break;
+	case CHIP_RV770:
+		num_ps_gprs = 192;
+		num_vs_gprs = 56;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 188;
+		num_vs_threads = 60;
+		num_gs_threads = 0;
+		num_es_threads = 0;
+		num_ps_stack_entries = 256;
+		num_vs_stack_entries = 256;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	case CHIP_RV730:
+	case CHIP_RV740:
+		num_ps_gprs = 84;
+		num_vs_gprs = 36;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 188;
+		num_vs_threads = 60;
+		num_gs_threads = 0;
+		num_es_threads = 0;
+		num_ps_stack_entries = 128;
+		num_vs_stack_entries = 128;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	case CHIP_RV710:
+		num_ps_gprs = 192;
+		num_vs_gprs = 56;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 144;
+		num_vs_threads = 48;
+		num_gs_threads = 0;
+		num_es_threads = 0;
+		num_ps_stack_entries = 128;
+		num_vs_stack_entries = 128;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	}
+
+	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_RV710))
+		sq_config = 0;
+	else
+		sq_config = R600_VC_ENABLE;
+
+	sq_config |= (R600_DX9_CONSTS |
+		      R600_ALU_INST_PREFER_VECTOR |
+		      R600_PS_PRIO(0) |
+		      R600_VS_PRIO(1) |
+		      R600_GS_PRIO(2) |
+		      R600_ES_PRIO(3));
+
+	sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(num_ps_gprs) |
+				  R600_NUM_VS_GPRS(num_vs_gprs) |
+				  R600_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
+	sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(num_gs_gprs) |
+				  R600_NUM_ES_GPRS(num_es_gprs));
+	sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(num_ps_threads) |
+				   R600_NUM_VS_THREADS(num_vs_threads) |
+				   R600_NUM_GS_THREADS(num_gs_threads) |
+				   R600_NUM_ES_THREADS(num_es_threads));
+	sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
+				    R600_NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
+	sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
+				    R600_NUM_ES_STACK_ENTRIES(num_es_stack_entries));
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
+		default_state_dw = sizeof(r7xx_default_state) / 4;
+		BEGIN_RING(default_state_dw + 10);
+		for (i = 0; i < default_state_dw; i++)
+			OUT_RING(r7xx_default_state[i]);
+	} else {
+		default_state_dw = sizeof(r6xx_default_state) / 4;
+		BEGIN_RING(default_state_dw + 10);
+		for (i = 0; i < default_state_dw; i++)
+			OUT_RING(r6xx_default_state[i]);
+	}
+	OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
+	OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
+	/* SQ config */
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6));
+        OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2);
+	OUT_RING(sq_config);
+	OUT_RING(sq_gpr_resource_mgmt_1);
+	OUT_RING(sq_gpr_resource_mgmt_2);
+	OUT_RING(sq_thread_resource_mgmt);
+	OUT_RING(sq_stack_resource_mgmt_1);
+	OUT_RING(sq_stack_resource_mgmt_2);
+	ADVANCE_RING();
+}
+
+static inline uint32_t i2f(uint32_t input)
+{
+	u32 result, i, exponent, fraction;
+
+	if ((input & 0x3fff) == 0)
+		result = 0; /* 0 is a special case */
+	else {
+		exponent = 140; /* exponent biased by 127; */
+		fraction = (input & 0x3fff) << 10; /* cheat and only
+						      handle numbers below 2^^15 */
+		for (i = 0; i < 14; i++) {
+			if (fraction & 0x800000)
+				break;
+			else {
+				fraction = fraction << 1; /* keep
+							     shifting left until top bit = 1 */
+				exponent = exponent -1;
+			}
+		}
+		result = exponent << 23 | (fraction & 0x7fffff); /* mask
+								    off top bit; assumed 1 */
+	}
+	return result;
+}
+
+int
+r600_prepare_blit_copy(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	DRM_DEBUG("\n");
+
+	dev_priv->blit_vb = radeon_freelist_get(dev);
+	if (!dev_priv->blit_vb) {
+		DRM_ERROR("Unable to allocate vertex buffer for blit\n");
+		return -EAGAIN;
+	}
+
+	set_default_state(dev_priv);
+	set_shaders(dev);
+
+	return 0;
+}
+
+void
+r600_done_blit_copy(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	BEGIN_RING(5);
+	OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
+	OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
+	/* wait for 3D idle clean */
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
+	OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2);
+	OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN);
+
+	ADVANCE_RING();
+	COMMIT_RING();
+
+	dev_priv->blit_vb->used = 0;
+	radeon_cp_discard_buffer(dev, dev_priv->blit_vb);
+}
+
+void
+r600_blit_copy(struct drm_device *dev,
+	       uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+	       int size_bytes)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	int max_bytes;
+	u64 vb_addr;
+	u32 *vb;
+
+	vb = (u32 *) ((char *)dev->agp_buffer_map->handle +
+		      dev_priv->blit_vb->offset + dev_priv->blit_vb->used);
+
+	if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
+		max_bytes = 8192;
+
+		while (size_bytes) {
+			int cur_size = size_bytes;
+			int src_x = src_gpu_addr & 255;
+			int dst_x = dst_gpu_addr & 255;
+			int h = 1;
+			src_gpu_addr = src_gpu_addr & ~255;
+			dst_gpu_addr = dst_gpu_addr & ~255;
+
+			if (!src_x && !dst_x) {
+				h = (cur_size / max_bytes);
+				if (h > 8192)
+					h = 8192;
+				if (h == 0)
+					h = 1;
+				else
+					cur_size = max_bytes;
+			} else {
+				if (cur_size > max_bytes)
+					cur_size = max_bytes;
+				if (cur_size > (max_bytes - dst_x))
+					cur_size = (max_bytes - dst_x);
+				if (cur_size > (max_bytes - src_x))
+					cur_size = (max_bytes - src_x);
+			}
+
+			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);
+				dev_priv->blit_vb = radeon_freelist_get(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[0] = i2f(dst_x);
+			vb[1] = 0;
+			vb[2] = i2f(src_x);
+			vb[3] = 0;
+
+			vb[4] = i2f(dst_x);
+			vb[5] = i2f(h);
+			vb[6] = i2f(src_x);
+			vb[7] = i2f(h);
+
+			vb[8] = i2f(dst_x + cur_size);
+			vb[9] = i2f(h);
+			vb[10] = i2f(src_x + cur_size);
+			vb[11] = i2f(h);
+
+			/* src */
+			set_tex_resource(dev_priv, FMT_8,
+					 src_x + cur_size, h, src_x + cur_size,
+					 src_gpu_addr);
+
+			cp_set_surface_sync(dev_priv,
+					    R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
+
+			/* dst */
+			set_render_target(dev_priv, COLOR_8,
+					  dst_x + cur_size, h,
+					  dst_gpu_addr);
+
+			/* scissors */
+			set_scissors(dev_priv, dst_x, 0, dst_x + cur_size, h);
+
+			/* Vertex buffer setup */
+			vb_addr = dev_priv->gart_buffers_offset +
+                                dev_priv->blit_vb->offset +
+				dev_priv->blit_vb->used;
+			set_vtx_resource(dev_priv, vb_addr);
+
+			/* draw */
+			draw_auto(dev_priv);
+
+			cp_set_surface_sync(dev_priv,
+					    R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
+					    cur_size * h, dst_gpu_addr);
+
+			vb += 12;
+			dev_priv->blit_vb->used += 12 * 4;
+
+			src_gpu_addr += cur_size * h;
+			dst_gpu_addr += cur_size * h;
+			size_bytes -= cur_size * h;
+		}
+	} else {
+		max_bytes = 8192 * 4;
+
+		while (size_bytes) {
+			int cur_size = size_bytes;
+			int src_x = (src_gpu_addr & 255);
+			int dst_x = (dst_gpu_addr & 255);
+			int h = 1;
+			src_gpu_addr = src_gpu_addr & ~255;
+			dst_gpu_addr = dst_gpu_addr & ~255;
+
+			if (!src_x && !dst_x) {
+				h = (cur_size / max_bytes);
+				if (h > 8192)
+					h = 8192;
+				if (h == 0)
+					h = 1;
+				else
+					cur_size = max_bytes;
+			} else {
+				if (cur_size > max_bytes)
+				    cur_size = max_bytes;
+				if (cur_size > (max_bytes - dst_x))
+					cur_size = (max_bytes - dst_x);
+				if (cur_size > (max_bytes - src_x))
+					cur_size = (max_bytes - src_x);
+			}
+
+			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);
+				dev_priv->blit_vb = radeon_freelist_get(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[0] = i2f(dst_x / 4);
+			vb[1] = 0;
+			vb[2] = i2f(src_x / 4);
+			vb[3] = 0;
+
+			vb[4] = i2f(dst_x / 4);
+			vb[5] = i2f(h);
+			vb[6] = i2f(src_x / 4);
+			vb[7] = i2f(h);
+
+			vb[8] = i2f((dst_x + cur_size) / 4);
+			vb[9] = i2f(h);
+			vb[10] = i2f((src_x + cur_size) / 4);
+			vb[11] = i2f(h);
+
+			/* src */
+			set_tex_resource(dev_priv, FMT_8_8_8_8,
+					 (src_x + cur_size) / 4,
+					 h, (src_x + cur_size) / 4,
+					 src_gpu_addr);
+
+			cp_set_surface_sync(dev_priv,
+					    R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
+
+			/* dst */
+			set_render_target(dev_priv, COLOR_8_8_8_8,
+					  (dst_x + cur_size) / 4, h,
+					  dst_gpu_addr);
+
+			/* scissors */
+			set_scissors(dev_priv, (dst_x / 4), 0, (dst_x + cur_size / 4), h);
+
+			/* Vertex buffer setup */
+			vb_addr = dev_priv->gart_buffers_offset +
+                                dev_priv->blit_vb->offset +
+				dev_priv->blit_vb->used;
+			set_vtx_resource(dev_priv, vb_addr);
+
+			/* draw */
+			draw_auto(dev_priv);
+
+			cp_set_surface_sync(dev_priv,
+					    R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
+					    cur_size * h, dst_gpu_addr);
+
+			vb += 12;
+			dev_priv->blit_vb->used += 12 * 4;
+
+			src_gpu_addr += cur_size * h;
+			dst_gpu_addr += cur_size * h;
+			size_bytes -= cur_size * h;
+		}
+	}
+}
+
+void
+r600_blit_swap(struct drm_device *dev,
+	       uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+	       int sx, int sy, int dx, int dy,
+	       int w, int h, int src_pitch, int dst_pitch, int cpp)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	int cb_format, tex_format;
+	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);
+		dev_priv->blit_vb = radeon_freelist_get(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);
+	}
+
+	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;
+	}
+
+	vb[0] = i2f(dx);
+	vb[1] = i2f(dy);
+	vb[2] = i2f(sx);
+	vb[3] = i2f(sy);
+
+	vb[4] = i2f(dx);
+	vb[5] = i2f(dy + h);
+	vb[6] = i2f(sx);
+	vb[7] = i2f(sy + h);
+
+	vb[8] = i2f(dx + w);
+	vb[9] = i2f(dy + h);
+	vb[10] = i2f(sx + w);
+	vb[11] = i2f(sy + h);
+
+	/* src */
+	set_tex_resource(dev_priv, tex_format,
+			 src_pitch / cpp,
+			 sy + h, src_pitch / cpp,
+			 src_gpu_addr);
+
+	cp_set_surface_sync(dev_priv,
+			    R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr);
+
+	/* dst */
+	set_render_target(dev_priv, cb_format,
+			  dst_pitch / cpp, dy + h,
+			  dst_gpu_addr);
+
+	/* scissors */
+	set_scissors(dev_priv, dx, dy, dx + w, dy + h);
+
+	/* Vertex buffer setup */
+	vb_addr = dev_priv->gart_buffers_offset +
+		dev_priv->blit_vb->offset +
+		dev_priv->blit_vb->used;
+	set_vtx_resource(dev_priv, vb_addr);
+
+	/* draw */
+	draw_auto(dev_priv);
+
+	cp_set_surface_sync(dev_priv,
+			    R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
+			    dst_pitch * (dy + h), dst_gpu_addr);
+
+	dev_priv->blit_vb->used += 12 * 4;
+}
diff --git a/sys/dev/drm/r600_cp.c b/sys/dev/drm/r600_cp.c
index 8c33eb6f483..2a4a6bd873c 100644
--- a/sys/dev/drm/r600_cp.c
+++ b/sys/dev/drm/r600_cp.c
@@ -1843,6 +1843,7 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
 	 */
 	dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
 
+	dev_priv->do_boxes = 0;
 	dev_priv->cp_mode = init->cp_mode;
 
 	/* We don't support anything other than bus-mastering ring mode,
@@ -2100,6 +2101,8 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
 	r600_do_engine_reset(dev);
 	r600_test_writeback(dev_priv);
 
+	r600_cs_init(dev);
+
 	return 0;
 }
 
@@ -2232,3 +2235,135 @@ int r600_cp_dispatch_indirect(struct drm_device *dev,
 
 	return 0;
 }
+
+void r600_cp_dispatch_swap(struct drm_device * dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+	int nbox = sarea_priv->nbox;
+	struct drm_clip_rect *pbox = sarea_priv->boxes;
+	int i, cpp, src_pitch, dst_pitch;
+	uint64_t src, dst;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	if (dev_priv->color_fmt == RADEON_COLOR_FORMAT_ARGB8888)
+		cpp = 4;
+	else
+		cpp = 2;
+
+	if (dev_priv->sarea_priv->pfCurrentPage == 0) {
+		src_pitch = dev_priv->back_pitch;
+		dst_pitch = dev_priv->front_pitch;
+		src = dev_priv->back_offset + dev_priv->fb_location;
+		dst = dev_priv->front_offset + dev_priv->fb_location;
+	} else {
+		src_pitch = dev_priv->front_pitch;
+		dst_pitch = dev_priv->back_pitch;
+		src = dev_priv->front_offset + dev_priv->fb_location;
+		dst = dev_priv->back_offset + dev_priv->fb_location;
+	}
+
+	if (r600_prepare_blit_copy(dev)) {
+		DRM_ERROR("unable to allocate vertex buffer for swap buffer\n");
+		return;
+	}
+	for (i = 0; i < nbox; i++) {
+		int x = pbox[i].x1;
+		int y = pbox[i].y1;
+		int w = pbox[i].x2 - x;
+		int h = pbox[i].y2 - y;
+
+		DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
+
+		r600_blit_swap(dev,
+			       src, dst,
+			       x, y, x, y, w, h,
+			       src_pitch, dst_pitch, cpp);
+	}
+	r600_done_blit_copy(dev);
+
+	/* Increment the frame counter.  The client-side 3D driver must
+	 * throttle the framerate by waiting for this value before
+	 * performing the swapbuffer ioctl.
+	 */
+	dev_priv->sarea_priv->last_frame++;
+
+	BEGIN_RING(3);
+	R600_FRAME_AGE(dev_priv->sarea_priv->last_frame);
+	ADVANCE_RING();
+}
+
+int r600_cp_dispatch_texture(struct drm_device * dev,
+			     struct drm_file *file_priv,
+			     drm_radeon_texture_t * tex,
+			     drm_radeon_tex_image_t * image)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_buf *buf;
+	u32 *buffer;
+	const u8 __user *data;
+	int size, pass_size;
+	u64 src_offset, dst_offset;
+
+	if (!radeon_check_offset(dev_priv, tex->offset)) {
+		DRM_ERROR("Invalid destination offset\n");
+		return -EINVAL;
+	}
+
+	/* this might fail for zero-sized uploads - are those illegal? */
+	if (!radeon_check_offset(dev_priv, tex->offset + tex->height * tex->pitch - 1)) {
+		DRM_ERROR("Invalid final destination offset\n");
+		return -EINVAL;
+	}
+
+	size = tex->height * tex->pitch;
+
+	if (size == 0)
+		return 0;
+
+	dst_offset = tex->offset;
+
+	r600_prepare_blit_copy(dev);
+	do {
+		data = (const u8 __user *)image->data;
+		pass_size = size;
+
+		buf = radeon_freelist_get(dev);
+		if (!buf) {
+			DRM_DEBUG("EAGAIN\n");
+			if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
+				return -EFAULT;
+			return -EAGAIN;
+		}
+
+		if (pass_size > buf->total)
+			pass_size = buf->total;
+
+		/* Dispatch the indirect buffer.
+		 */
+		buffer =
+		    (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
+
+		if (DRM_COPY_FROM_USER(buffer, data, pass_size)) {
+			DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size);
+			return -EFAULT;
+		}
+
+		buf->file_priv = file_priv;
+		buf->used = pass_size;
+		src_offset = dev_priv->gart_buffers_offset + buf->offset;
+
+		r600_blit_copy(dev, src_offset, dst_offset, pass_size);
+
+		radeon_cp_discard_buffer(dev, buf);
+
+		/* Update the input parameters for next time */
+		image->data = (const u8 __user *)image->data + pass_size;
+		dst_offset += pass_size;
+		size -= pass_size;
+	} while (size > 0);
+	r600_done_blit_copy(dev);
+
+	return 0;
+}
diff --git a/sys/dev/drm/radeon_cp.c b/sys/dev/drm/radeon_cp.c
index 3d8cf9dfecc..734fafa445f 100644
--- a/sys/dev/drm/radeon_cp.c
+++ b/sys/dev/drm/radeon_cp.c
@@ -408,6 +408,15 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
 {
 	uint32_t gb_tile_config, gb_pipe_sel = 0;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) {
+		uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2);
+		if ((z_pipe_sel & 3) == 3)
+			dev_priv->num_z_pipes = 2;
+		else
+			dev_priv->num_z_pipes = 1;
+	} else
+		dev_priv->num_z_pipes = 1;
+
 	/* RS4xx/RS6xx/R4xx/R5xx */
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
 		gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
@@ -2060,6 +2069,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
 	else
 		dev_priv->flags |= RADEON_IS_PCI;
 
+	mtx_init(&dev_priv->cs.cs_mutex, "cs_mtx", NULL, MTX_DEF);
+
 	ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
 			 drm_get_resource_len(dev, 2), _DRM_REGISTERS,
 			 _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio);
@@ -2112,6 +2123,8 @@ int radeon_driver_unload(struct drm_device *dev)
 
 	drm_rmmap(dev, dev_priv->mmio);
 
+	mtx_destroy(&dev_priv->cs.cs_mutex);
+
 	drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
 
 	dev->dev_private = NULL;
@@ -2126,9 +2139,9 @@ void radeon_commit_ring(drm_radeon_private_t *dev_priv)
 
 	/* check if the ring is padded out to 16-dword alignment */
 
-	tail_aligned = dev_priv->ring.tail & 0xf;
+	tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN - 1);
 	if (tail_aligned) {
-		int num_p2 = 16 - tail_aligned;
+		int num_p2 = RADEON_RING_ALIGN - tail_aligned;
 
 		ring = dev_priv->ring.start;
 		/* pad with some CP_PACKET2 */
diff --git a/sys/dev/drm/radeon_cs.c b/sys/dev/drm/radeon_cs.c
new file mode 100644
index 00000000000..b523126b947
--- /dev/null
+++ b/sys/dev/drm/radeon_cs.c
@@ -0,0 +1,856 @@
+/*-
+ * Copyright 2008 Jerome Glisse.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Jerome Glisse 
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+#include "dev/drm/drmP.h"
+#include "dev/drm/radeon_drm.h"
+#include "dev/drm/radeon_drv.h"
+
+/* regs */
+#define AVIVO_D1MODE_VLINE_START_END                           0x6538
+#define AVIVO_D2MODE_VLINE_START_END                           0x6d38
+#define R600_CP_COHER_BASE                                     0x85f8
+#define R600_DB_DEPTH_BASE                                     0x2800c
+#define R600_CB_COLOR0_BASE                                    0x28040
+#define R600_CB_COLOR1_BASE                                    0x28044
+#define R600_CB_COLOR2_BASE                                    0x28048
+#define R600_CB_COLOR3_BASE                                    0x2804c
+#define R600_CB_COLOR4_BASE                                    0x28050
+#define R600_CB_COLOR5_BASE                                    0x28054
+#define R600_CB_COLOR6_BASE                                    0x28058
+#define R600_CB_COLOR7_BASE                                    0x2805c
+#define R600_SQ_PGM_START_FS                                   0x28894
+#define R600_SQ_PGM_START_ES                                   0x28880
+#define R600_SQ_PGM_START_VS                                   0x28858
+#define R600_SQ_PGM_START_GS                                   0x2886c
+#define R600_SQ_PGM_START_PS                                   0x28840
+#define R600_VGT_DMA_BASE                                      0x287e8
+#define R600_VGT_DMA_BASE_HI                                   0x287e4
+#define R600_VGT_STRMOUT_BASE_OFFSET_0                         0x28b10
+#define R600_VGT_STRMOUT_BASE_OFFSET_1                         0x28b14
+#define R600_VGT_STRMOUT_BASE_OFFSET_2                         0x28b18
+#define R600_VGT_STRMOUT_BASE_OFFSET_3                         0x28b1c
+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_0                      0x28b44
+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_1                      0x28b48
+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_2                      0x28b4c
+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_3                      0x28b50
+#define R600_VGT_STRMOUT_BUFFER_BASE_0                         0x28ad8
+#define R600_VGT_STRMOUT_BUFFER_BASE_1                         0x28ae8
+#define R600_VGT_STRMOUT_BUFFER_BASE_2                         0x28af8
+#define R600_VGT_STRMOUT_BUFFER_BASE_3                         0x28b08
+#define R600_VGT_STRMOUT_BUFFER_OFFSET_0                       0x28adc
+#define R600_VGT_STRMOUT_BUFFER_OFFSET_1                       0x28aec
+#define R600_VGT_STRMOUT_BUFFER_OFFSET_2                       0x28afc
+#define R600_VGT_STRMOUT_BUFFER_OFFSET_3                       0x28b0c
+
+/* resource type */
+#define R600_SQ_TEX_VTX_INVALID_TEXTURE                        0x0
+#define R600_SQ_TEX_VTX_INVALID_BUFFER                         0x1
+#define R600_SQ_TEX_VTX_VALID_TEXTURE                          0x2
+#define R600_SQ_TEX_VTX_VALID_BUFFER                           0x3
+
+/* packet 3 type offsets */
+#define R600_SET_CONFIG_REG_OFFSET                             0x00008000
+#define R600_SET_CONFIG_REG_END                                0x0000ac00
+#define R600_SET_CONTEXT_REG_OFFSET                            0x00028000
+#define R600_SET_CONTEXT_REG_END                               0x00029000
+#define R600_SET_ALU_CONST_OFFSET                              0x00030000
+#define R600_SET_ALU_CONST_END                                 0x00032000
+#define R600_SET_RESOURCE_OFFSET                               0x00038000
+#define R600_SET_RESOURCE_END                                  0x0003c000
+#define R600_SET_SAMPLER_OFFSET                                0x0003c000
+#define R600_SET_SAMPLER_END                                   0x0003cff0
+#define R600_SET_CTL_CONST_OFFSET                              0x0003cff0
+#define R600_SET_CTL_CONST_END                                 0x0003e200
+#define R600_SET_LOOP_CONST_OFFSET                             0x0003e200
+#define R600_SET_LOOP_CONST_END                                0x0003e380
+#define R600_SET_BOOL_CONST_OFFSET                             0x0003e380
+#define R600_SET_BOOL_CONST_END                                0x00040000
+
+/* Packet 3 types */
+#define R600_IT_INDIRECT_BUFFER_END               0x00001700
+#define R600_IT_SET_PREDICATION                   0x00002000
+#define R600_IT_REG_RMW                           0x00002100
+#define R600_IT_COND_EXEC                         0x00002200
+#define R600_IT_PRED_EXEC                         0x00002300
+#define R600_IT_START_3D_CMDBUF                   0x00002400
+#define R600_IT_DRAW_INDEX_2                      0x00002700
+#define R600_IT_CONTEXT_CONTROL                   0x00002800
+#define R600_IT_DRAW_INDEX_IMMD_BE                0x00002900
+#define R600_IT_INDEX_TYPE                        0x00002A00
+#define R600_IT_DRAW_INDEX                        0x00002B00
+#define R600_IT_DRAW_INDEX_AUTO                   0x00002D00
+#define R600_IT_DRAW_INDEX_IMMD                   0x00002E00
+#define R600_IT_NUM_INSTANCES                     0x00002F00
+#define R600_IT_STRMOUT_BUFFER_UPDATE             0x00003400
+#define R600_IT_INDIRECT_BUFFER_MP                0x00003800
+#define R600_IT_MEM_SEMAPHORE                     0x00003900
+#define R600_IT_MPEG_INDEX                        0x00003A00
+#define R600_IT_WAIT_REG_MEM                      0x00003C00
+#define R600_IT_MEM_WRITE                         0x00003D00
+#define R600_IT_INDIRECT_BUFFER                   0x00003200
+#define R600_IT_CP_INTERRUPT                      0x00004000
+#define R600_IT_SURFACE_SYNC                      0x00004300
+#define R600_IT_ME_INITIALIZE                     0x00004400
+#define R600_IT_COND_WRITE                        0x00004500
+#define R600_IT_EVENT_WRITE                       0x00004600
+#define R600_IT_EVENT_WRITE_EOP                   0x00004700
+#define R600_IT_ONE_REG_WRITE                     0x00005700
+#define R600_IT_SET_CONFIG_REG                    0x00006800
+#define R600_IT_SET_CONTEXT_REG                   0x00006900
+#define R600_IT_SET_ALU_CONST                     0x00006A00
+#define R600_IT_SET_BOOL_CONST                    0x00006B00
+#define R600_IT_SET_LOOP_CONST                    0x00006C00
+#define R600_IT_SET_RESOURCE                      0x00006D00
+#define R600_IT_SET_SAMPLER                       0x00006E00
+#define R600_IT_SET_CTL_CONST                     0x00006F00
+#define R600_IT_SURFACE_BASE_UPDATE               0x00007300
+
+int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
+{
+	struct drm_radeon_cs_parser parser;
+	struct drm_radeon_private *dev_priv = dev->dev_private;
+	struct drm_radeon_cs *cs = data;
+	uint32_t cs_id;
+	struct drm_radeon_cs_chunk __user **chunk_ptr = NULL;
+	uint64_t *chunk_array;
+	uint64_t *chunk_array_ptr;
+	long size;
+	int r, i;
+
+	mtx_lock(&dev_priv->cs.cs_mutex);
+	/* set command stream id to 0 which is fake id */
+	cs_id = 0;
+	cs->cs_id = cs_id;
+
+	if (dev_priv == NULL) {
+		DRM_ERROR("called with no initialization\n");
+		mtx_unlock(&dev_priv->cs.cs_mutex);
+		return -EINVAL;
+	}
+	if (!cs->num_chunks) {
+		mtx_unlock(&dev_priv->cs.cs_mutex);
+		return 0;
+	}
+
+
+	chunk_array = drm_calloc(cs->num_chunks, sizeof(uint64_t), DRM_MEM_DRIVER);
+	if (!chunk_array) {
+		mtx_unlock(&dev_priv->cs.cs_mutex);
+		return -ENOMEM;
+	}
+
+	chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks);
+
+	if (DRM_COPY_FROM_USER(chunk_array, chunk_array_ptr, sizeof(uint64_t)*cs->num_chunks)) {
+		r = -EFAULT;
+		goto out;
+	}
+
+	parser.dev = dev;
+	parser.file_priv = fpriv;
+	parser.reloc_index = -1;
+	parser.ib_index = -1;
+	parser.num_chunks = cs->num_chunks;
+	/* copy out the chunk headers */
+	parser.chunks = drm_calloc(parser.num_chunks, sizeof(struct drm_radeon_kernel_chunk), DRM_MEM_DRIVER);
+	if (!parser.chunks) {
+		r = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < parser.num_chunks; i++) {
+		struct drm_radeon_cs_chunk user_chunk;
+
+		chunk_ptr = (void __user *)(unsigned long)chunk_array[i];
+
+		if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr, sizeof(struct drm_radeon_cs_chunk))){
+			r = -EFAULT;
+			goto out;
+		}
+		parser.chunks[i].chunk_id = user_chunk.chunk_id;
+
+		if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS)
+			parser.reloc_index = i;
+
+		if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_IB)
+			parser.ib_index = i;
+
+		if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_OLD) {
+			parser.ib_index = i;
+			parser.reloc_index = -1;
+		}
+
+		parser.chunks[i].length_dw = user_chunk.length_dw;
+		parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data;
+
+		parser.chunks[i].kdata = NULL;
+		size = parser.chunks[i].length_dw * sizeof(uint32_t);
+
+		switch(parser.chunks[i].chunk_id) {
+		case RADEON_CHUNK_ID_IB:
+		case RADEON_CHUNK_ID_OLD:
+			if (size == 0) {
+				r = -EINVAL;
+				goto out;
+			}
+		case RADEON_CHUNK_ID_RELOCS:
+			if (size) {
+				parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER);
+				if (!parser.chunks[i].kdata) {
+					r = -ENOMEM;
+					goto out;
+				}
+
+				if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) {
+					r = -EFAULT;
+					goto out;
+				}
+			} else
+				parser.chunks[i].kdata = NULL;
+			break;
+		default:
+			break;
+		}
+		DRM_DEBUG("chunk %d %d %d %p\n", i, parser.chunks[i].chunk_id, parser.chunks[i].length_dw,
+			  parser.chunks[i].chunk_data);
+	}
+
+	if (parser.chunks[parser.ib_index].length_dw > (16 * 1024)) {
+		DRM_ERROR("cs->dwords too big: %d\n", parser.chunks[parser.ib_index].length_dw);
+		r = -EINVAL;
+		goto out;
+	}
+
+	/* get ib */
+	r = dev_priv->cs.ib_get(&parser);
+	if (r) {
+		DRM_ERROR("ib_get failed\n");
+		goto out;
+	}
+
+	/* now parse command stream */
+	r = dev_priv->cs.parse(&parser);
+	if (r) {
+		goto out;
+	}
+
+out:
+	dev_priv->cs.ib_free(&parser, r);
+
+	/* emit cs id sequence */
+	dev_priv->cs.id_emit(&parser, &cs_id);
+
+	cs->cs_id = cs_id;
+
+	mtx_unlock(&dev_priv->cs.cs_mutex);
+
+	for (i = 0; i < parser.num_chunks; i++) {
+		if (parser.chunks[i].kdata)
+			drm_free(parser.chunks[i].kdata, parser.chunks[i].length_dw * sizeof(uint32_t), DRM_MEM_DRIVER);
+	}
+
+	drm_free(parser.chunks, sizeof(struct drm_radeon_kernel_chunk)*parser.num_chunks, DRM_MEM_DRIVER);
+	drm_free(chunk_array, sizeof(uint64_t)*parser.num_chunks, DRM_MEM_DRIVER);
+
+	return r;
+}
+
+/* for non-mm */
+static int r600_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *reloc, uint64_t *offset)
+{
+	struct drm_device *dev = parser->dev;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_radeon_kernel_chunk *reloc_chunk = &parser->chunks[parser->reloc_index];
+	uint32_t offset_dw = reloc[1];
+
+	//DRM_INFO("reloc: 0x%08x 0x%08x\n", reloc[0], reloc[1]);
+	//DRM_INFO("length: %d\n", reloc_chunk->length_dw);
+
+	if (!reloc_chunk->kdata)
+		return -EINVAL;
+
+	if (offset_dw > reloc_chunk->length_dw) {
+		DRM_ERROR("Offset larger than chunk 0x%x %d\n", offset_dw, reloc_chunk->length_dw);
+		return -EINVAL;
+	}
+
+	/* 40 bit addr */
+	*offset = reloc_chunk->kdata[offset_dw + 3];
+	*offset <<= 32;
+	*offset |= reloc_chunk->kdata[offset_dw + 0];
+
+	//DRM_INFO("offset 0x%lx\n", *offset);
+
+	if (!radeon_check_offset(dev_priv, *offset)) {
+		DRM_ERROR("bad offset! 0x%lx\n", (unsigned long)*offset);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline int r600_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t *offset_dw_p)
+{
+	uint32_t hdr, num_dw, reg;
+	int count_dw = 1;
+	int ret = 0;
+	uint32_t offset_dw = *offset_dw_p;
+	int incr = 2;
+
+	hdr = parser->chunks[parser->ib_index].kdata[offset_dw];
+	num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
+	reg = (hdr & 0xffff) << 2;
+
+	while (count_dw < num_dw) {
+		switch (reg) {
+		case AVIVO_D1MODE_VLINE_START_END:
+		case AVIVO_D2MODE_VLINE_START_END:
+			break;
+		default:
+			ret = -EINVAL;
+			DRM_ERROR("bad packet 0 reg: 0x%08x\n", reg);
+			break;
+		}
+		if (ret)
+			break;
+		count_dw++;
+		reg += 4;
+	}
+	*offset_dw_p += incr;
+	return ret;
+}
+
+static inline int r600_cs_packet3(struct drm_radeon_cs_parser *parser, uint32_t *offset_dw_p)
+{
+	struct drm_device *dev = parser->dev;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	uint32_t hdr, num_dw, start_reg, end_reg, reg;
+	uint32_t *reloc;
+	uint64_t offset;
+	int ret = 0;
+	uint32_t offset_dw = *offset_dw_p;
+	int incr = 2;
+	int i;
+	struct drm_radeon_kernel_chunk *ib_chunk;
+
+	ib_chunk = &parser->chunks[parser->ib_index];
+
+	hdr = ib_chunk->kdata[offset_dw];
+	num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
+
+	/* just the ones we use for now, add more later */
+	switch (hdr & 0xff00) {
+	case R600_IT_START_3D_CMDBUF:
+		//DRM_INFO("R600_IT_START_3D_CMDBUF\n");
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+			ret = -EINVAL;
+		if (num_dw != 2)
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad START_3D\n");
+		break;
+	case R600_IT_CONTEXT_CONTROL:
+		//DRM_INFO("R600_IT_CONTEXT_CONTROL\n");
+		if (num_dw != 3)
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad CONTEXT_CONTROL\n");
+		break;
+	case R600_IT_INDEX_TYPE:
+	case R600_IT_NUM_INSTANCES:
+		//DRM_INFO("R600_IT_INDEX_TYPE/R600_IT_NUM_INSTANCES\n");
+		if (num_dw != 2)
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n");
+		break;
+	case R600_IT_DRAW_INDEX:
+		//DRM_INFO("R600_IT_DRAW_INDEX\n");
+		if (num_dw != 5) {
+			ret = -EINVAL;
+			DRM_ERROR("bad DRAW_INDEX\n");
+			break;
+		}
+		reloc = ib_chunk->kdata + offset_dw + num_dw;
+		ret = dev_priv->cs.relocate(parser, reloc, &offset);
+		if (ret) {
+			DRM_ERROR("bad DRAW_INDEX\n");
+			break;
+		}
+		ib_chunk->kdata[offset_dw + 1] += (offset & 0xffffffff);
+		ib_chunk->kdata[offset_dw + 2] += (upper_32_bits(offset) & 0xff);
+		break;
+	case R600_IT_DRAW_INDEX_AUTO:
+		//DRM_INFO("R600_IT_DRAW_INDEX_AUTO\n");
+		if (num_dw != 3)
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad DRAW_INDEX_AUTO\n");
+		break;
+	case R600_IT_DRAW_INDEX_IMMD_BE:
+	case R600_IT_DRAW_INDEX_IMMD:
+		//DRM_INFO("R600_IT_DRAW_INDEX_IMMD\n");
+		if (num_dw < 4)
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad DRAW_INDEX_IMMD\n");
+		break;
+	case R600_IT_WAIT_REG_MEM:
+		//DRM_INFO("R600_IT_WAIT_REG_MEM\n");
+		if (num_dw != 7)
+			ret = -EINVAL;
+		/* bit 4 is reg (0) or mem (1) */
+		if (ib_chunk->kdata[offset_dw + 1] & 0x10) {
+			reloc = ib_chunk->kdata + offset_dw + num_dw;
+			ret = dev_priv->cs.relocate(parser, reloc, &offset);
+			if (ret) {
+				DRM_ERROR("bad WAIT_REG_MEM\n");
+				break;
+			}
+			ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff);
+			ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff);
+		}
+		if (ret)
+			DRM_ERROR("bad WAIT_REG_MEM\n");
+		break;
+	case R600_IT_SURFACE_SYNC:
+		//DRM_INFO("R600_IT_SURFACE_SYNC\n");
+		if (num_dw != 5)
+			ret = -EINVAL;
+		/* 0xffffffff/0x0 is flush all cache flag */
+		else if ((ib_chunk->kdata[offset_dw + 2] == 0xffffffff) &&
+			 (ib_chunk->kdata[offset_dw + 3] == 0))
+			ret = 0;
+		else {
+			reloc = ib_chunk->kdata + offset_dw + num_dw;
+			ret = dev_priv->cs.relocate(parser, reloc, &offset);
+			if (ret) {
+				DRM_ERROR("bad SURFACE_SYNC\n");
+				break;
+			}
+			ib_chunk->kdata[offset_dw + 3] += ((offset >> 8) & 0xffffffff);
+		}
+		break;
+	case R600_IT_EVENT_WRITE:
+		//DRM_INFO("R600_IT_EVENT_WRITE\n");
+		if ((num_dw != 4) && (num_dw != 2))
+			ret = -EINVAL;
+		if (num_dw > 2) {
+			reloc = ib_chunk->kdata + offset_dw + num_dw;
+			ret = dev_priv->cs.relocate(parser, reloc, &offset);
+			if (ret) {
+				DRM_ERROR("bad EVENT_WRITE\n");
+				break;
+			}
+			ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff);
+			ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff);
+		}
+		if (ret)
+			DRM_ERROR("bad EVENT_WRITE\n");
+		break;
+	case R600_IT_EVENT_WRITE_EOP:
+		//DRM_INFO("R600_IT_EVENT_WRITE_EOP\n");
+		if (num_dw != 6) {
+			ret = -EINVAL;
+			DRM_ERROR("bad EVENT_WRITE_EOP\n");
+			break;
+		}
+		reloc = ib_chunk->kdata + offset_dw + num_dw;
+		ret = dev_priv->cs.relocate(parser, reloc, &offset);
+		if (ret) {
+			DRM_ERROR("bad EVENT_WRITE_EOP\n");
+			break;
+		}
+		ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff);
+		ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff);
+		break;
+	case R600_IT_SET_CONFIG_REG:
+		//DRM_INFO("R600_IT_SET_CONFIG_REG\n");
+		start_reg = (ib_chunk->kdata[offset_dw + 1] << 2) + R600_SET_CONFIG_REG_OFFSET;
+		end_reg = 4 * (num_dw - 2) + start_reg - 4;
+		if ((start_reg < R600_SET_CONFIG_REG_OFFSET) ||
+		    (start_reg >= R600_SET_CONFIG_REG_END) ||
+		    (end_reg >= R600_SET_CONFIG_REG_END))
+			ret = -EINVAL;
+		else {
+			for (i = 0; i < (num_dw - 2); i++) {
+				reg = start_reg + (4 * i);
+				switch (reg) {
+				case R600_CP_COHER_BASE:
+					/* use R600_IT_SURFACE_SYNC */
+					ret = -EINVAL;
+					break;
+				default:
+					break;
+				}
+				if (ret)
+					break;
+			}
+		}
+		if (ret)
+			DRM_ERROR("bad SET_CONFIG_REG\n");
+		break;
+	case R600_IT_SET_CONTEXT_REG:
+		//DRM_INFO("R600_IT_SET_CONTEXT_REG\n");
+		start_reg = ib_chunk->kdata[offset_dw + 1] << 2;
+		start_reg += R600_SET_CONTEXT_REG_OFFSET;
+		end_reg = 4 * (num_dw - 2) + start_reg - 4;
+		if ((start_reg < R600_SET_CONTEXT_REG_OFFSET) ||
+		    (start_reg >= R600_SET_CONTEXT_REG_END) ||
+		    (end_reg >= R600_SET_CONTEXT_REG_END))
+			ret = -EINVAL;
+		else {
+			for (i = 0; i < (num_dw - 2); i++) {
+				reg = start_reg + (4 * i);
+				switch (reg) {
+				case R600_DB_DEPTH_BASE:
+				case R600_CB_COLOR0_BASE:
+				case R600_CB_COLOR1_BASE:
+				case R600_CB_COLOR2_BASE:
+				case R600_CB_COLOR3_BASE:
+				case R600_CB_COLOR4_BASE:
+				case R600_CB_COLOR5_BASE:
+				case R600_CB_COLOR6_BASE:
+				case R600_CB_COLOR7_BASE:
+				case R600_SQ_PGM_START_FS:
+				case R600_SQ_PGM_START_ES:
+				case R600_SQ_PGM_START_VS:
+				case R600_SQ_PGM_START_GS:
+				case R600_SQ_PGM_START_PS:
+					//DRM_INFO("reg: 0x%08x\n", reg);
+					reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 2);
+					ret = dev_priv->cs.relocate(parser, reloc, &offset);
+					if (ret) {
+						DRM_ERROR("bad SET_CONTEXT_REG\n");
+						break;
+					}
+					ib_chunk->kdata[offset_dw + 2 + i] +=
+						((offset >> 8) & 0xffffffff);
+					break;
+				case R600_VGT_DMA_BASE:
+				case R600_VGT_DMA_BASE_HI:
+					/* These should be handled by DRAW_INDEX packet 3 */
+				case R600_VGT_STRMOUT_BASE_OFFSET_0:
+				case R600_VGT_STRMOUT_BASE_OFFSET_1:
+				case R600_VGT_STRMOUT_BASE_OFFSET_2:
+				case R600_VGT_STRMOUT_BASE_OFFSET_3:
+				case R600_VGT_STRMOUT_BASE_OFFSET_HI_0:
+				case R600_VGT_STRMOUT_BASE_OFFSET_HI_1:
+				case R600_VGT_STRMOUT_BASE_OFFSET_HI_2:
+				case R600_VGT_STRMOUT_BASE_OFFSET_HI_3:
+				case R600_VGT_STRMOUT_BUFFER_BASE_0:
+				case R600_VGT_STRMOUT_BUFFER_BASE_1:
+				case R600_VGT_STRMOUT_BUFFER_BASE_2:
+				case R600_VGT_STRMOUT_BUFFER_BASE_3:
+				case R600_VGT_STRMOUT_BUFFER_OFFSET_0:
+				case R600_VGT_STRMOUT_BUFFER_OFFSET_1:
+				case R600_VGT_STRMOUT_BUFFER_OFFSET_2:
+				case R600_VGT_STRMOUT_BUFFER_OFFSET_3:
+					/* These should be handled by STRMOUT_BUFFER packet 3 */
+					DRM_ERROR("bad context reg: 0x%08x\n", reg);
+					ret = -EINVAL;
+					break;
+				default:
+					break;
+				}
+				if (ret)
+					break;
+			}
+		}
+		if (ret)
+			DRM_ERROR("bad SET_CONTEXT_REG\n");
+		break;
+	case R600_IT_SET_RESOURCE:
+		//DRM_INFO("R600_IT_SET_RESOURCE\n");
+		if ((num_dw - 2) % 7)
+			ret = -EINVAL;
+		start_reg = ib_chunk->kdata[offset_dw + 1] << 2;
+		start_reg += R600_SET_RESOURCE_OFFSET;
+		end_reg = 4 * (num_dw - 2) + start_reg - 4;
+		if ((start_reg < R600_SET_RESOURCE_OFFSET) ||
+		    (start_reg >= R600_SET_RESOURCE_END) ||
+		    (end_reg >= R600_SET_RESOURCE_END))
+			ret = -EINVAL;
+		else {
+			for (i = 0; i < ((num_dw - 2) / 7); i++) {
+				switch ((ib_chunk->kdata[offset_dw + (i * 7) + 6 + 2] & 0xc0000000) >> 30) {
+				case R600_SQ_TEX_VTX_INVALID_TEXTURE:
+				case R600_SQ_TEX_VTX_INVALID_BUFFER:
+				default:
+					ret = -EINVAL;
+					break;
+				case R600_SQ_TEX_VTX_VALID_TEXTURE:
+					/* tex base */
+					reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 4);
+					ret = dev_priv->cs.relocate(parser, reloc, &offset);
+					if (ret)
+						break;
+					ib_chunk->kdata[offset_dw + (i * 7) + 2 + 2] +=
+						((offset >> 8) & 0xffffffff);
+					/* tex mip base */
+					reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 4) + 2;
+					ret = dev_priv->cs.relocate(parser, reloc, &offset);
+					if (ret)
+						break;
+					ib_chunk->kdata[offset_dw + (i * 7) + 3 + 2] +=
+						((offset >> 8) & 0xffffffff);
+					break;
+				case R600_SQ_TEX_VTX_VALID_BUFFER:
+					/* vtx base */
+					reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 2);
+					ret = dev_priv->cs.relocate(parser, reloc, &offset);
+					if (ret)
+						break;
+					ib_chunk->kdata[offset_dw + (i * 7) + 0 + 2] += (offset & 0xffffffff);
+					ib_chunk->kdata[offset_dw + (i * 7) + 2 + 2] += (upper_32_bits(offset) & 0xff);
+					break;
+				}
+				if (ret)
+					break;
+			}
+		}
+		if (ret)
+			DRM_ERROR("bad SET_RESOURCE\n");
+		break;
+	case R600_IT_SET_ALU_CONST:
+		//DRM_INFO("R600_IT_SET_ALU_CONST\n");
+		start_reg = ib_chunk->kdata[offset_dw + 1] << 2;
+		start_reg += R600_SET_ALU_CONST_OFFSET;
+		end_reg = 4 * (num_dw - 2) + start_reg - 4;
+		if ((start_reg < R600_SET_ALU_CONST_OFFSET) ||
+		    (start_reg >= R600_SET_ALU_CONST_END) ||
+		    (end_reg >= R600_SET_ALU_CONST_END))
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad SET_ALU_CONST\n");
+		break;
+	case R600_IT_SET_BOOL_CONST:
+		//DRM_INFO("R600_IT_SET_BOOL_CONST\n");
+		start_reg = ib_chunk->kdata[offset_dw + 1] << 2;
+		start_reg += R600_SET_BOOL_CONST_OFFSET;
+		end_reg = 4 * (num_dw - 2) + start_reg - 4;
+		if ((start_reg < R600_SET_BOOL_CONST_OFFSET) ||
+		    (start_reg >= R600_SET_BOOL_CONST_END) ||
+		    (end_reg >= R600_SET_BOOL_CONST_END))
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad SET_BOOL_CONST\n");
+		break;
+	case R600_IT_SET_LOOP_CONST:
+		//DRM_INFO("R600_IT_SET_LOOP_CONST\n");
+		start_reg = ib_chunk->kdata[offset_dw + 1] << 2;
+		start_reg += R600_SET_LOOP_CONST_OFFSET;
+		end_reg = 4 * (num_dw - 2) + start_reg - 4;
+		if ((start_reg < R600_SET_LOOP_CONST_OFFSET) ||
+		    (start_reg >= R600_SET_LOOP_CONST_END) ||
+		    (end_reg >= R600_SET_LOOP_CONST_END))
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad SET_LOOP_CONST\n");
+		break;
+	case R600_IT_SET_CTL_CONST:
+		//DRM_INFO("R600_IT_SET_CTL_CONST\n");
+		start_reg = ib_chunk->kdata[offset_dw + 1] << 2;
+		start_reg += R600_SET_CTL_CONST_OFFSET;
+		end_reg = 4 * (num_dw - 2) + start_reg - 4;
+		if ((start_reg < R600_SET_CTL_CONST_OFFSET) ||
+		    (start_reg >= R600_SET_CTL_CONST_END) ||
+		    (end_reg >= R600_SET_CTL_CONST_END))
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad SET_CTL_CONST\n");
+		break;
+	case R600_IT_SET_SAMPLER:
+		//DRM_INFO("R600_IT_SET_SAMPLER\n");
+		if ((num_dw - 2) % 3)
+			ret = -EINVAL;
+		start_reg = ib_chunk->kdata[offset_dw + 1] << 2;
+		start_reg += R600_SET_SAMPLER_OFFSET;
+		end_reg = 4 * (num_dw - 2) + start_reg - 4;
+		if ((start_reg < R600_SET_SAMPLER_OFFSET) ||
+		    (start_reg >= R600_SET_SAMPLER_END) ||
+		    (end_reg >= R600_SET_SAMPLER_END))
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad SET_SAMPLER\n");
+		break;
+	case R600_IT_SURFACE_BASE_UPDATE:
+		//DRM_INFO("R600_IT_SURFACE_BASE_UPDATE\n");
+		if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) ||
+		    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600))
+			ret = -EINVAL;
+		if (num_dw != 2)
+			ret = -EINVAL;
+		if (ret)
+			DRM_ERROR("bad SURFACE_BASE_UPDATE\n");
+		break;
+	case RADEON_CP_NOP:
+		//DRM_INFO("NOP: %d\n", ib_chunk->kdata[offset_dw + 1]);
+		break;
+	default:
+		DRM_ERROR("invalid packet 3 0x%08x\n", 0xff00);
+		ret = -EINVAL;
+		break;
+	}
+
+	*offset_dw_p += incr;
+	return ret;
+}
+
+static int r600_cs_parse(struct drm_radeon_cs_parser *parser)
+{
+	volatile int rb;
+	struct drm_radeon_kernel_chunk *ib_chunk;
+	/* scan the packet for various things */
+	int count_dw = 0, size_dw;
+	int ret = 0;
+
+	ib_chunk = &parser->chunks[parser->ib_index];
+	size_dw = ib_chunk->length_dw;
+
+	while (count_dw < size_dw && ret == 0) {
+		int hdr = ib_chunk->kdata[count_dw];
+		int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
+
+		switch (hdr & RADEON_CP_PACKET_MASK) {
+		case RADEON_CP_PACKET0:
+			ret = r600_cs_packet0(parser, &count_dw);
+			break;
+		case RADEON_CP_PACKET1:
+			ret = -EINVAL;
+			break;
+		case RADEON_CP_PACKET2:
+			DRM_DEBUG("Packet 2\n");
+			num_dw += 1;
+			break;
+		case RADEON_CP_PACKET3:
+			ret = r600_cs_packet3(parser, &count_dw);
+			break;
+		}
+
+		count_dw += num_dw;
+	}
+
+	if (ret)
+		return ret;
+
+
+	/* copy the packet into the IB */
+	memcpy(parser->ib, ib_chunk->kdata, ib_chunk->length_dw * sizeof(uint32_t));
+
+	/* read back last byte to flush WC buffers */
+	rb = readl(((vm_offset_t)parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t)));
+
+	return 0;
+}
+
+static uint32_t radeon_cs_id_get(struct drm_radeon_private *radeon)
+{
+	/* FIXME: protect with a spinlock */
+	/* FIXME: check if wrap affect last reported wrap & sequence */
+	radeon->cs.id_scnt = (radeon->cs.id_scnt + 1) & 0x00FFFFFF;
+	if (!radeon->cs.id_scnt) {
+		/* increment wrap counter */
+		radeon->cs.id_wcnt += 0x01000000;
+		/* valid sequence counter start at 1 */
+		radeon->cs.id_scnt = 1;
+	}
+	return (radeon->cs.id_scnt | radeon->cs.id_wcnt);
+}
+
+static void r600_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id)
+{
+	drm_radeon_private_t *dev_priv = parser->dev->dev_private;
+	RING_LOCALS;
+
+	//dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev);
+
+	*id = radeon_cs_id_get(dev_priv);
+
+	/* SCRATCH 2 */
+	BEGIN_RING(3);
+	R600_CLEAR_AGE(*id);
+	ADVANCE_RING();
+	COMMIT_RING();
+}
+
+static uint32_t r600_cs_id_last_get(struct drm_device *dev)
+{
+	//drm_radeon_private_t *dev_priv = dev->dev_private;
+
+	//return GET_R600_SCRATCH(dev_priv, 2);
+	return 0;
+}
+
+static int r600_ib_get(struct drm_radeon_cs_parser *parser)
+{
+	struct drm_device *dev = parser->dev;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_buf *buf;
+
+	buf = radeon_freelist_get(dev);
+	if (!buf) {
+		dev_priv->cs_buf = NULL;
+		return -EBUSY;
+	}
+	buf->file_priv = parser->file_priv;
+	dev_priv->cs_buf = buf;
+	parser->ib = (void *)((vm_offset_t)dev->agp_buffer_map->handle +
+	    buf->offset);
+
+	return 0;
+}
+
+static void r600_ib_free(struct drm_radeon_cs_parser *parser, int error)
+{
+	struct drm_device *dev = parser->dev;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_buf *buf = dev_priv->cs_buf;
+
+	if (buf) {
+		if (!error)
+			r600_cp_dispatch_indirect(dev, buf, 0,
+						  parser->chunks[parser->ib_index].length_dw * sizeof(uint32_t));
+		radeon_cp_discard_buffer(dev, buf);
+		COMMIT_RING();
+	}
+}
+
+int r600_cs_init(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+
+	dev_priv->cs.ib_get = r600_ib_get;
+	dev_priv->cs.ib_free = r600_ib_free;
+	dev_priv->cs.id_emit = r600_cs_id_emit;
+	dev_priv->cs.id_last_get = r600_cs_id_last_get;
+	dev_priv->cs.parse = r600_cs_parse;
+	dev_priv->cs.relocate = r600_nomm_relocate;
+	return 0;
+}
diff --git a/sys/dev/drm/radeon_drm.h b/sys/dev/drm/radeon_drm.h
index 70d3aaa6fc5..11f2fcb8d8a 100644
--- a/sys/dev/drm/radeon_drm.h
+++ b/sys/dev/drm/radeon_drm.h
@@ -497,6 +497,8 @@ typedef struct {
 #define DRM_RADEON_SURF_ALLOC 0x1a
 #define DRM_RADEON_SURF_FREE  0x1b
 
+#define DRM_RADEON_CS         0x26
+
 #define DRM_IOCTL_RADEON_CP_INIT    DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
 #define DRM_IOCTL_RADEON_CP_START   DRM_IO(  DRM_COMMAND_BASE + DRM_RADEON_CP_START)
 #define DRM_IOCTL_RADEON_CP_STOP    DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t)
@@ -524,6 +526,7 @@ typedef struct {
 #define DRM_IOCTL_RADEON_SETPARAM   DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
 #define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
 #define DRM_IOCTL_RADEON_SURF_FREE  DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
+#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
 
 typedef struct drm_radeon_init {
 	enum {
@@ -685,6 +688,8 @@ typedef struct drm_radeon_indirect {
 #define RADEON_PARAM_VBLANK_CRTC           13   /* VBLANK CRTC */
 #define RADEON_PARAM_FB_LOCATION           14   /* FB location */
 #define RADEON_PARAM_NUM_GB_PIPES          15   /* num GB pipes */
+#define RADEON_PARAM_DEVICE_ID             16
+#define RADEON_PARAM_NUM_Z_PIPES           17   /* num Z pipes */
 
 typedef struct drm_radeon_getparam {
 	int param;
@@ -755,4 +760,23 @@ typedef struct drm_radeon_surface_free {
 #define	DRM_RADEON_VBLANK_CRTC1		1
 #define	DRM_RADEON_VBLANK_CRTC2		2
 
+/* New interface which obsolete all previous interface.
+ */
+#define RADEON_CHUNK_ID_RELOCS 0x01
+#define RADEON_CHUNK_ID_IB     0x02
+#define RADEON_CHUNK_ID_OLD 0xff
+
+struct drm_radeon_cs_chunk {
+	uint32_t chunk_id;
+	uint32_t length_dw;
+	uint64_t chunk_data;
+};
+
+struct drm_radeon_cs {
+	uint32_t        num_chunks;
+	uint32_t        cs_id;
+	uint64_t        chunks; /* this points to uint64_t * which point to
+				   cs chunks */
+};
+
 #endif
diff --git a/sys/dev/drm/radeon_drv.h b/sys/dev/drm/radeon_drv.h
index 5914b13b5dd..d90d7cf048d 100644
--- a/sys/dev/drm/radeon_drv.h
+++ b/sys/dev/drm/radeon_drv.h
@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
 
 #define DRIVER_NAME		"radeon"
 #define DRIVER_DESC		"ATI Radeon"
-#define DRIVER_DATE		"20080528"
+#define DRIVER_DATE		"20080613"
 
 /* Interface history:
  *
@@ -102,9 +102,11 @@ __FBSDID("$FreeBSD$");
  * 1.27- Add support for IGP GART
  * 1.28- Add support for VBL on CRTC2
  * 1.29- R500 3D cmd buffer support
+ * 1.30- Add support for occlusion queries
+ * 1.31- Add support for num Z pipes from GET_PARAM
  */
 #define DRIVER_MAJOR		1
-#define DRIVER_MINOR		29
+#define DRIVER_MINOR		31
 #define DRIVER_PATCHLEVEL	0
 
 /*
@@ -141,15 +143,15 @@ enum radeon_family {
 	CHIP_R600,
 	CHIP_RV610,
 	CHIP_RV630,
+	CHIP_RV670,
 	CHIP_RV620,
 	CHIP_RV635,
-	CHIP_RV670,
 	CHIP_RS780,
 	CHIP_RS880,
 	CHIP_RV770,
-	CHIP_RV740,
 	CHIP_RV730,
 	CHIP_RV710,
+	CHIP_RV740,
 	CHIP_LAST,
 };
 
@@ -236,6 +238,46 @@ struct radeon_virt_surface {
 #define PCIGART_FILE_PRIV	((void *) -1L)
 };
 
+struct drm_radeon_kernel_chunk {
+	uint32_t chunk_id;
+	uint32_t length_dw;
+	uint32_t __user *chunk_data;
+	uint32_t *kdata;
+};
+
+struct drm_radeon_cs_parser {
+	struct drm_device *dev;
+	struct drm_file *file_priv;
+	uint32_t num_chunks;
+	struct drm_radeon_kernel_chunk *chunks;
+	int ib_index;
+	int reloc_index;
+	uint32_t card_offset;
+	void *ib;
+};
+
+/* command submission struct */
+struct drm_radeon_cs_priv {
+	struct mtx cs_mutex;
+	uint32_t id_wcnt;
+	uint32_t id_scnt;
+	uint32_t id_last_wcnt;
+	uint32_t id_last_scnt;
+
+	int (*parse)(struct drm_radeon_cs_parser *parser);
+	void (*id_emit)(struct drm_radeon_cs_parser *parser, uint32_t *id);
+	uint32_t (*id_last_get)(struct drm_device *dev);
+	/* this ib handling callback are for hidding memory manager drm
+	 * from memory manager less drm, free have to emit ib discard
+	 * sequence into the ring */
+	int (*ib_get)(struct drm_radeon_cs_parser *parser);
+	uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib);
+	void (*ib_free)(struct drm_radeon_cs_parser *parser, int error);
+	/* do a relocation either MM or non-MM */
+	int (*relocate)(struct drm_radeon_cs_parser *parser,
+			uint32_t *reloc, uint64_t *offset);
+};
+
 #define RADEON_FLUSH_EMITED	(1 << 0)
 #define RADEON_PURGE_EMITED	(1 << 1)
 
@@ -328,6 +370,7 @@ typedef struct drm_radeon_private {
 	unsigned long fb_aper_offset;
 
 	int num_gb_pipes;
+	int num_z_pipes;
 	int track_flush;
 	drm_local_map_t *mmio;
 
@@ -349,6 +392,12 @@ typedef struct drm_radeon_private {
 	int r700_sc_prim_fifo_size;
 	int r700_sc_hiz_tile_fifo_size;
 	int r700_sc_earlyz_tile_fifo_fize;
+	/* r6xx/r7xx drm blit vertex buffer */
+	struct drm_buf *blit_vb;
+
+	/* CS */
+	struct drm_radeon_cs_priv cs;
+	struct drm_buf *cs_buf;
 
 } drm_radeon_private_t;
 
@@ -379,10 +428,10 @@ extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val);
 static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
 					  u64 off)
 {
-	u32 fb_start = dev_priv->fb_location;
-	u32 fb_end = fb_start + dev_priv->fb_size - 1;
-	u32 gart_start = dev_priv->gart_vm_start;
-	u32 gart_end = gart_start + dev_priv->gart_size - 1;
+	u64 fb_start = dev_priv->fb_location;
+	u64 fb_end = fb_start + dev_priv->fb_size - 1;
+	u64 gart_start = dev_priv->gart_vm_start;
+	u64 gart_end = gart_start + dev_priv->gart_size - 1;
 
 	return ((off >= fb_start && off <= fb_end) ||
 		(off >= gart_start && off <= gart_end));
@@ -476,6 +525,33 @@ extern int r600_cp_dispatch_indirect(struct drm_device *dev,
 				     struct drm_buf *buf, int start, int end);
 extern int r600_page_table_init(struct drm_device *dev);
 extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
+extern void r600_cp_dispatch_swap(struct drm_device * dev);
+extern int r600_cp_dispatch_texture(struct drm_device * dev,
+				    struct drm_file *file_priv,
+				    drm_radeon_texture_t * tex,
+				    drm_radeon_tex_image_t * image);
+
+/* r600_blit.c */
+extern int
+r600_prepare_blit_copy(struct drm_device *dev);
+extern void
+r600_done_blit_copy(struct drm_device *dev);
+extern void
+r600_blit_copy(struct drm_device *dev,
+	       uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+	       int size_bytes);
+extern void
+r600_blit_swap(struct drm_device *dev,
+	       uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+	       int sx, int sy, int dx, int dy,
+	       int w, int h, int src_pitch, int dst_pitch, int cpp);
+
+/* radeon_state.c */
+extern void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf);
+
+/* radeon_cs.c */
+extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
+extern int r600_cs_init(struct drm_device *dev);
 
 /* Flags for stats.boxes
  */
@@ -685,6 +761,7 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga
 
 /* pipe config regs */
 #define R400_GB_PIPE_SELECT             0x402c
+#define RV530_GB_PIPE_SELECT2           0x4124
 #define R500_DYN_SCLK_PWMEM_PIPE        0x000d /* PLL */
 #define R300_GB_TILE_CONFIG             0x4018
 #       define R300_ENABLE_TILING       (1 << 0)
@@ -1827,26 +1904,38 @@ do {									\
  */
 
 #define RADEON_WAIT_UNTIL_2D_IDLE() do {				\
-	OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );			\
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)        \
+		OUT_RING( CP_PACKET0( R600_WAIT_UNTIL, 0 ) );           \
+	else                                                            \
+		OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );         \
 	OUT_RING( (RADEON_WAIT_2D_IDLECLEAN |				\
 		   RADEON_WAIT_HOST_IDLECLEAN) );			\
 } while (0)
 
 #define RADEON_WAIT_UNTIL_3D_IDLE() do {				\
-	OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );			\
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)        \
+		OUT_RING( CP_PACKET0( R600_WAIT_UNTIL, 0 ) );           \
+	else                                                            \
+		OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );         \
 	OUT_RING( (RADEON_WAIT_3D_IDLECLEAN |				\
 		   RADEON_WAIT_HOST_IDLECLEAN) );			\
 } while (0)
 
 #define RADEON_WAIT_UNTIL_IDLE() do {					\
-	OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );			\
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)        \
+		OUT_RING( CP_PACKET0( R600_WAIT_UNTIL, 0 ) );           \
+	else                                                            \
+		OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );         \
 	OUT_RING( (RADEON_WAIT_2D_IDLECLEAN |				\
 		   RADEON_WAIT_3D_IDLECLEAN |				\
 		   RADEON_WAIT_HOST_IDLECLEAN) );			\
 } while (0)
 
 #define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do {				\
-	OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );			\
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)        \
+		OUT_RING( CP_PACKET0( R600_WAIT_UNTIL, 0 ) );           \
+	else                                                            \
+		OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );         \
 	OUT_RING( RADEON_WAIT_CRTC_PFLIP );				\
 } while (0)
 
@@ -1961,14 +2050,17 @@ do {								\
 
 #define RING_LOCALS	int write, _nr, _align_nr; unsigned int mask; u32 *ring;
 
+#define RADEON_RING_ALIGN 16
+
 #define BEGIN_RING( n ) do {						\
 	if ( RADEON_VERBOSE ) {						\
 		DRM_INFO( "BEGIN_RING( %d )\n", (n));			\
 	}								\
-	_align_nr = (n + 0xf) & ~0xf;					\
-	if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) {	\
-                COMMIT_RING();						\
-		radeon_wait_ring( dev_priv, _align_nr * sizeof(u32));	\
+	_align_nr = RADEON_RING_ALIGN - ((dev_priv->ring.tail + n) & (RADEON_RING_ALIGN - 1)); \
+	_align_nr += n;							\
+	if ( dev_priv->ring.space <= (_align_nr) * sizeof(u32) ) {	\
+		COMMIT_RING();						\
+		radeon_wait_ring( dev_priv, (_align_nr) * sizeof(u32) ); \
 	}								\
 	_nr = n; dev_priv->ring.space -= (n) * sizeof(u32);		\
 	ring = dev_priv->ring.start;					\
diff --git a/sys/dev/drm/radeon_irq.c b/sys/dev/drm/radeon_irq.c
index 7f605739679..20b1e6de444 100644
--- a/sys/dev/drm/radeon_irq.c
+++ b/sys/dev/drm/radeon_irq.c
@@ -194,6 +194,9 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
 	u32 r500_disp_int;
 	u32 tmp;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return IRQ_NONE;
+
 	/* Only consider the bits we're interested in - others could be used
 	 * outside the DRM
 	 */
@@ -323,6 +326,9 @@ int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_pr
 	drm_radeon_irq_emit_t *emit = data;
 	int result;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return -EINVAL;
+
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
 	if (!dev_priv) {
@@ -363,6 +369,9 @@ void radeon_driver_irq_preinstall(struct drm_device * dev)
 	    (drm_radeon_private_t *) dev->dev_private;
 	u32 dummy;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return;
+
 	/* Disable *all* interrupts */
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
@@ -380,6 +389,9 @@ int radeon_driver_irq_postinstall(struct drm_device * dev)
 	atomic_set(&dev_priv->swi_emitted, 0);
 	DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return 0;
+
 	radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
 
 	return 0;
@@ -394,6 +406,9 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
 
 	dev_priv->irq_enabled = 0;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return;
+
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
 	/* Disable *all* interrupts */
diff --git a/sys/dev/drm/radeon_state.c b/sys/dev/drm/radeon_state.c
index 39dcd61315f..fd8388ffa59 100644
--- a/sys/dev/drm/radeon_state.c
+++ b/sys/dev/drm/radeon_state.c
@@ -1541,7 +1541,7 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev,
 	} while (i < nbox);
 }
 
-static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_buf *buf)
+void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_buf *buf)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
@@ -2202,7 +2202,10 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f
 	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
 		sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
 
-	radeon_cp_dispatch_swap(dev);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		r600_cp_dispatch_swap(dev);
+	else
+		radeon_cp_dispatch_swap(dev);
 	sarea_priv->ctx_owner = 0;
 
 	COMMIT_RING();
@@ -2399,7 +2402,10 @@ static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file
 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
 	VB_AGE_TEST_WITH_RETURN(dev_priv);
 
-	ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image);
+	else
+		ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
 
 	return ret;
 }
@@ -3018,7 +3024,10 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
 		value = GET_SCRATCH(dev_priv, 2);
 		break;
 	case RADEON_PARAM_IRQ_NR:
-		value = dev->irq;
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			value = 0;
+		else
+			value = dev->irq;
 		break;
 	case RADEON_PARAM_GART_BASE:
 		value = dev_priv->gart_vm_start;
@@ -3072,6 +3081,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
 	case RADEON_PARAM_NUM_GB_PIPES:
 		value = dev_priv->num_gb_pipes;
 		break;
+	case RADEON_PARAM_NUM_Z_PIPES:
+		value = dev_priv->num_z_pipes;
+		break;
 	default:
 		DRM_DEBUG("Invalid parameter %d\n", param->param);
 		return -EINVAL;
@@ -3156,6 +3168,14 @@ void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
 void radeon_driver_lastclose(struct drm_device *dev)
 {
 	radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private);
+	if (dev->dev_private) {
+		drm_radeon_private_t *dev_priv = dev->dev_private;
+
+		if (dev_priv->sarea_priv &&
+		    dev_priv->sarea_priv->pfCurrentPage != 0)
+			radeon_cp_dispatch_flip(dev);
+	}
+
 	radeon_do_release(dev);
 }
 
@@ -3216,7 +3236,8 @@ struct drm_ioctl_desc radeon_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH)
+	DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH)
 };
 
 int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
diff --git a/sys/modules/drm/radeon/Makefile b/sys/modules/drm/radeon/Makefile
index 4b8b7d17842..72c364bdd55 100644
--- a/sys/modules/drm/radeon/Makefile
+++ b/sys/modules/drm/radeon/Makefile
@@ -2,8 +2,8 @@
 
 .PATH:	${.CURDIR}/../../../dev/drm
 KMOD	= radeon
-SRCS	= r300_cmdbuf.c r600_cp.c radeon_cp.c radeon_drv.c radeon_irq.c \
-	radeon_mem.c radeon_state.c
+SRCS	= r300_cmdbuf.c r600_blit.c r600_cp.c radeon_cp.c radeon_cs.c \
+	radeon_drv.c radeon_irq.c radeon_mem.c radeon_state.c
 SRCS	+=device_if.h bus_if.h pci_if.h opt_drm.h
 
 .include 

From 6137518b87e05be4442f580d88975ea9ccb991f2 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 16:37:58 +0000
Subject: [PATCH 0445/2592] MFC r197951

Add support for Intel G41 chipset
---
 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 5a3d86c297c5a84cf4970d73a0741ad5a289c886 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Fri, 30 Oct 2009 16:43:28 +0000
Subject: [PATCH 0446/2592] MFC r197950

Add pci id's for Intel G41 chipset
---
 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 891bfff89da..943244dc06f 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 4ee07662b133f6e5288484dd907cea8f5e6cce5c Mon Sep 17 00:00:00 2001
From: Rong-En Fan 
Date: Fri, 30 Oct 2009 17:28:35 +0000
Subject: [PATCH 0447/2592] MFC r198490

 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
---
 contrib/ncurses/ncurses/base/lib_getch.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/contrib/ncurses/ncurses/base/lib_getch.c b/contrib/ncurses/ncurses/base/lib_getch.c
index a3812bee76e..e7ba0b210e3 100644
--- a/contrib/ncurses/ncurses/base/lib_getch.c
+++ b/contrib/ncurses/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 e22a16d5d30126cdefa97f958dc00766d602b5d8 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Fri, 30 Oct 2009 19:59:50 +0000
Subject: [PATCH 0448/2592] MFC r198230, r198242, r198260, r198346, r198369,
 r198384:

    More mesh fixes to comply with latest draft.
---
 sys/net80211/ieee80211_hwmp.c   | 67 +++++++++++++++++----------------
 sys/net80211/ieee80211_mesh.c   | 18 +++++++--
 sys/net80211/ieee80211_mesh.h   |  2 +
 sys/net80211/ieee80211_output.c | 20 ++++++----
 sys/net80211/ieee80211_proto.h  |  4 +-
 5 files changed, 67 insertions(+), 44 deletions(-)

diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index df988505b7f..ea06b0e3a9d 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 {
@@ -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);
@@ -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;
@@ -733,12 +734,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 +785,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 +849,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 +952,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 +975,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 +985,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 +1016,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 +1042,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++;
 	} 
@@ -1114,6 +1115,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;
@@ -1223,7 +1225,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 +1308,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 +1327,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;
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index a1b594b9286..d42d55db72d 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;
 		}
 	}
@@ -739,10 +735,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) {
@@ -2552,6 +2550,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..9b532c32e21 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
@@ -2763,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;
@@ -2874,6 +2869,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 +2927,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 +2981,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 05edd60be4d7d6ca84139790e90a061945904cd3 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Sat, 31 Oct 2009 06:35:40 +0000
Subject: [PATCH 0449/2592] MFCs of r197764, r197765, r197766, r197847:

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.

Add the comment "(FreeBSD only)" to the altmonth_x keywords
---
 include/langinfo.h            | 14 ++++++++++++++
 lib/libc/locale/nl_langinfo.c |  6 ++++++
 lib/libc/stdtime/localtime.c  | 11 +++++++++--
 usr.bin/locale/locale.1       | 10 ++++++++--
 usr.bin/locale/locale.c       | 35 +++++++++++++++++++++++++++++------
 5 files changed, 66 insertions(+), 10 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/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 = "";
diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c
index e0ed73f7d96..9fc5f3ee99b 100644
--- a/lib/libc/stdtime/localtime.c
+++ b/lib/libc/stdtime/localtime.c
@@ -21,6 +21,7 @@ __FBSDID("$FreeBSD$");
 #include "namespace.h"
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "private.h"
@@ -1413,13 +1414,16 @@ const time_t * const	timep;
 	static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
 	static pthread_key_t localtime_key = -1;
 	struct tm *p_tm;
+	int r;
 
 	if (__isthreaded != 0) {
 		if (localtime_key < 0) {
 			_pthread_mutex_lock(&localtime_mutex);
 			if (localtime_key < 0) {
-				if (_pthread_key_create(&localtime_key, free) < 0) {
+				if ((r = _pthread_key_create(&localtime_key,
+				    free)) != 0) {
 					_pthread_mutex_unlock(&localtime_mutex);
+					errno = r;
 					return(NULL);
 				}
 			}
@@ -1512,13 +1516,16 @@ const time_t * const	timep;
 	static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
 	static pthread_key_t gmtime_key = -1;
 	struct tm *p_tm;
+	int r;
 
 	if (__isthreaded != 0) {
 		if (gmtime_key < 0) {
 			_pthread_mutex_lock(&gmtime_mutex);
 			if (gmtime_key < 0) {
-				if (_pthread_key_create(&gmtime_key, free) < 0) {
+				if ((r = _pthread_key_create(&gmtime_key,
+				    free)) != 0) {
 					_pthread_mutex_unlock(&gmtime_mutex);
+					errno = r;
 					return(NULL);
 				}
 			}
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..cad3afe71bd 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);
 
@@ -190,6 +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, "(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)" },
@@ -217,7 +229,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 +277,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 +302,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 +607,7 @@ showdetails(char *kw)
 		 * invalid keyword specified.
 		 * XXX: any actions?
 		 */
+		fprintf(stderr, "Unknown keyword: `%s'\n", kw);
 		return;
 	}
 
@@ -639,16 +653,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 b7ef6e29a5d184a19fb50b54df72a1aef1fa5f09 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sat, 31 Oct 2009 10:59:53 +0000
Subject: [PATCH 0450/2592] MFC: r198327

Add a missing free() call.
---
 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 ce68852cc29e267db20e89dd1b03a75f02099669 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sat, 31 Oct 2009 11:08:04 +0000
Subject: [PATCH 0451/2592] MFC: r198356

Fix a memory leak in an error case.
---
 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 5a1c285266f8d5c18eaabc24f7ab33da4ac20c79 Mon Sep 17 00:00:00 2001
From: Antoine Brodin 
Date: Sat, 31 Oct 2009 12:26:40 +0000
Subject: [PATCH 0452/2592] MFC r196891 to stable/8:   Change w_notrunning and
 w_stillcold from pointer to array so that sizeof   returns what is expected.

  PR:		kern/138557
  Discussed with:	brucec@
  MFC after:	1 month
---
 sys/kern/subr_witness.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index 799dbccfea5..aa46edb60f0 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -469,8 +469,8 @@ static struct witness_lock_order_data *w_lofree = NULL;
 static struct witness_lock_order_hash w_lohash;
 static int w_max_used_index = 0;
 static unsigned int w_generation = 0;
-static const char *w_notrunning = "Witness not running\n";
-static const char *w_stillcold = "Witness is still cold\n";
+static const char w_notrunning[] = "Witness not running\n";
+static const char w_stillcold[] = "Witness is still cold\n";
 
 
 static struct witness_order_list_entry order_lists[] = {

From 38c15033c7c4ed836e3dbe11827374db0a903fd7 Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sat, 31 Oct 2009 18:18:32 +0000
Subject: [PATCH 0453/2592] MFC r198472   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 ebc91405bdb4587f2434aa552a45c82e5df2231c Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sat, 31 Oct 2009 18:54:26 +0000
Subject: [PATCH 0454/2592] MFC r197316   Add a new sysctl for reporting all of
 the supported page sizes.

---
 sys/amd64/include/param.h   |  2 ++
 sys/arm/include/param.h     |  2 ++
 sys/i386/include/param.h    |  2 ++
 sys/ia64/include/param.h    |  2 ++
 sys/kern/kern_mib.c         | 27 +++++++++++++++++++++++++++
 sys/mips/include/param.h    |  2 ++
 sys/powerpc/include/param.h |  2 ++
 sys/sparc64/include/param.h |  2 ++
 sys/sun4v/include/param.h   |  2 ++
 sys/sys/systm.h             |  1 +
 10 files changed, 44 insertions(+)

diff --git a/sys/amd64/include/param.h b/sys/amd64/include/param.h
index edcf427df3e..10d3ab3d6b2 100644
--- a/sys/amd64/include/param.h
+++ b/sys/amd64/include/param.h
@@ -118,6 +118,8 @@
 #define	NBPML4		(1ul<flags & SCTL_MASK32) {
+		/*
+		 * Recreate the "pagesizes" array with 32-bit elements.  Truncate
+		 * any page size greater than UINT32_MAX to zero.
+		 */
+		for (i = 0; i < MAXPAGESIZES; i++)
+			pagesizes32[i] = (uint32_t)pagesizes[i];
+
+		error = SYSCTL_OUT(req, pagesizes32, sizeof(pagesizes32));
+	} else
+#endif
+		error = SYSCTL_OUT(req, pagesizes, sizeof(pagesizes));
+	return (error);
+}
+SYSCTL_PROC(_hw, OID_AUTO, pagesizes, CTLTYPE_ULONG | CTLFLAG_RD,
+    NULL, 0, sysctl_hw_pagesizes, "LU", "Supported page sizes");
+
 static char	machine_arch[] = MACHINE_ARCH;
 SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD,
     machine_arch, 0, "System architecture");
diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h
index 250de77ba7e..cdc9f3af7fe 100644
--- a/sys/mips/include/param.h
+++ b/sys/mips/include/param.h
@@ -115,6 +115,8 @@
 #define	SEGOFSET	(NBSEG-1)	/* byte offset into segment */
 #define	SEGSHIFT	22		/* LOG2(NBSEG) */
 
+#define	MAXPAGESIZES	1		/* maximum number of supported page sizes */
+
 /* XXXimp: This has moved to vmparam.h */
 /* Also, this differs from the mips2 definition, but likely is better */
 /* since this means the kernel won't chew up TLBs when it is executing */
diff --git a/sys/powerpc/include/param.h b/sys/powerpc/include/param.h
index 9728fe416c0..6234e4860c2 100644
--- a/sys/powerpc/include/param.h
+++ b/sys/powerpc/include/param.h
@@ -98,6 +98,8 @@
 #define	PAGE_MASK	(PAGE_SIZE - 1)
 #define	NPTEPG		(PAGE_SIZE/(sizeof (pt_entry_t)))
 
+#define	MAXPAGESIZES	1		/* maximum number of supported page sizes */
+
 #ifndef KSTACK_PAGES
 #define	KSTACK_PAGES		4		/* includes pcb */
 #endif
diff --git a/sys/sparc64/include/param.h b/sys/sparc64/include/param.h
index 2642a8ac2c4..eac552b4556 100644
--- a/sys/sparc64/include/param.h
+++ b/sys/sparc64/include/param.h
@@ -121,6 +121,8 @@
 #define PAGE_SIZE_MAX	PAGE_SIZE_4M
 #define PAGE_MASK_MAX	PAGE_MASK_4M
 
+#define	MAXPAGESIZES	1		/* maximum number of supported page sizes */
+
 #ifndef KSTACK_PAGES
 #define KSTACK_PAGES		4	/* pages of kernel stack (with pcb) */
 #endif
diff --git a/sys/sun4v/include/param.h b/sys/sun4v/include/param.h
index 4b26748cb98..e10b73111cd 100644
--- a/sys/sun4v/include/param.h
+++ b/sys/sun4v/include/param.h
@@ -116,6 +116,8 @@
 #define PAGE_SIZE_MAX	PAGE_SIZE_4M
 #define PAGE_MASK_MAX	PAGE_MASK_4M
 
+#define	MAXPAGESIZES	1		/* maximum number of supported page sizes */
+
 #ifndef KSTACK_PAGES
 #define KSTACK_PAGES		4	/* pages of kernel stack (with pcb) */
 #endif
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 96222da9152..397976fd564 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -54,6 +54,7 @@ extern int kstack_pages;	/* number of kernel stack pages */
 
 extern int nswap;		/* size of swap space */
 
+extern u_long pagesizes[];	/* supported page sizes */
 extern long physmem;		/* physical memory */
 extern long realmem;		/* 'real' memory */
 

From 13529df13b6290e560970a894aa3cea528466f26 Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sat, 31 Oct 2009 19:02:08 +0000
Subject: [PATCH 0455/2592] MFC r197317   When superpages are enabled, add the
 2 or 4MB page size to the array of   supported page sizes.

---
 sys/amd64/amd64/pmap.c | 5 +++++
 sys/i386/i386/pmap.c   | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 97de6b6f8ca..d3d653d95c7 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -663,6 +663,11 @@ pmap_init(void)
 	 * Are large page mappings enabled?
 	 */
 	TUNABLE_INT_FETCH("vm.pmap.pg_ps_enabled", &pg_ps_enabled);
+	if (pg_ps_enabled) {
+		KASSERT(MAXPAGESIZES > 1 && pagesizes[1] == 0,
+		    ("pmap_init: can't assign to pagesizes[1]"));
+		pagesizes[1] = NBPDR;
+	}
 
 	/*
 	 * Calculate the size of the pv head table for superpages.
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 548dbdb2ac6..0deebc800a8 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -673,6 +673,11 @@ pmap_init(void)
 	 * Are large page mappings enabled?
 	 */
 	TUNABLE_INT_FETCH("vm.pmap.pg_ps_enabled", &pg_ps_enabled);
+	if (pg_ps_enabled) {
+		KASSERT(MAXPAGESIZES > 1 && pagesizes[1] == 0,
+		    ("pmap_init: can't assign to pagesizes[1]"));
+		pagesizes[1] = NBPDR;
+	}
 
 	/*
 	 * Calculate the size of the pv head table for superpages.

From 83613795b2a145ed528eb03d2f556d5dfd2d4625 Mon Sep 17 00:00:00 2001
From: Stacey Son 
Date: Sat, 31 Oct 2009 21:22:18 +0000
Subject: [PATCH 0456/2592] MFC
 197240,197241,197242,197243,197293,197294,197407:

Add EVFILT_USER filter and EV_DISPATCH/EV_RECEIPT flags to kevent(2).

Approved by: rwatson (mentor)
---
 lib/libc/sys/kqueue.2 |  54 +++++++++++-
 sys/kern/kern_event.c | 199 +++++++++++++++++++++++++++++++++---------
 sys/sys/event.h       |  36 +++++++-
 3 files changed, 248 insertions(+), 41 deletions(-)

diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2
index 119ff79bc9f..e899a1befe8 100644
--- a/lib/libc/sys/kqueue.2
+++ b/lib/libc/sys/kqueue.2
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 6, 2007
+.Dd September 15, 2009
 .Dt KQUEUE 2
 .Os
 .Sh NAME
@@ -201,11 +201,25 @@ Disable the event so
 .Fn kevent
 will not return it.
 The filter itself is not disabled.
+.It EV_DISPATCH
+Disable the event source immediately after delivery of an event.
+See 
+.Dv EV_DISABLE
+above.
 .It EV_DELETE
 Removes the event from the kqueue.
 Events which are attached to
 file descriptors are automatically deleted on the last close of
 the descriptor.
+.It EV_RECEIPT
+This flag is useful for making bulk changes to a kqueue without draining
+any pending events.
+When passed as input, it forces
+.Dv EV_ERROR
+to always be returned.
+When a filter is successfully added the 
+.Va data
+field will be zero.
 .It EV_ONESHOT
 Causes the event to return only the first occurrence of the filter
 being triggered.
@@ -441,6 +455,44 @@ The link state is invalid.
 On return,
 .Va fflags
 contains the events which triggered the filter.
+.It Dv EVFILT_USER
+Establishes a user event identified by
+.Va ident
+which is not assosicated with any kernel mechanism but is triggered by
+user level code.
+The lower 24 bits of the 
+.Va fflags
+may be used for user defined flags and manipulated using the following:
+.Bl -tag -width XXNOTE_FFLAGSMASK 
+.It Dv NOTE_FFNOP
+Ignore the input
+.Va fflags .
+.It Dv NOTE_FFAND
+Bitwise AND
+.Va fflags .
+.It Dv NOTE_FFOR
+Bitwise OR
+.Va fflags .
+.It Dv NOTE_COPY
+Copy
+.Va fflags .
+.It Dv NOTE_FFCTRLMASK
+Control mask for
+.Va fflags .
+.It Dv NOTE_FFLAGSMASK
+User defined flag mask for
+.Va fflags .
+.El
+.Pp
+A user event is triggered for output with the following:
+.Bl -tag -width XXNOTE_FFLAGSMASK
+.It Dv NOTE_TRIGGER
+Cause the event to be triggered.
+.El
+.Pp
+On return,
+.Va fflags
+contains the users defined flags in the lower 24 bits.
 .El
 .Sh RETURN VALUES
 The
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index e0dd56dfdda..27eac03eb05 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,6 +1,7 @@
 /*-
  * Copyright (c) 1999,2000,2001 Jonathan Lemon 
  * Copyright 2004 John-Mark Gurney 
+ * Copyright (c) 2009 Apple, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -141,6 +142,11 @@ static void	filt_timerexpire(void *knx);
 static int	filt_timerattach(struct knote *kn);
 static void	filt_timerdetach(struct knote *kn);
 static int	filt_timer(struct knote *kn, long hint);
+static int	filt_userattach(struct knote *kn);
+static void	filt_userdetach(struct knote *kn);
+static int	filt_user(struct knote *kn, long hint);
+static void	filt_usertouch(struct knote *kn, struct kevent *kev,
+		    u_long type);
 
 static struct filterops file_filtops =
 	{ 1, filt_fileattach, NULL, NULL };
@@ -151,6 +157,12 @@ static struct filterops proc_filtops =
 	{ 0, filt_procattach, filt_procdetach, filt_proc };
 static struct filterops timer_filtops =
 	{ 0, filt_timerattach, filt_timerdetach, filt_timer };
+static struct filterops user_filtops = {
+	.f_attach = filt_userattach,
+	.f_detach = filt_userdetach,
+	.f_event = filt_user,
+	.f_touch = filt_usertouch,
+};
 
 static uma_zone_t	knote_zone;
 static int 		kq_ncallouts = 0;
@@ -255,6 +267,7 @@ static struct {
 	{ &file_filtops },			/* EVFILT_NETDEV */
 	{ &fs_filtops },			/* EVFILT_FS */
 	{ &null_filtops },			/* EVFILT_LIO */
+	{ &user_filtops },			/* EVFILT_USER */
 };
 
 /*
@@ -557,6 +570,94 @@ filt_timer(struct knote *kn, long hint)
 	return (kn->kn_data != 0);
 }
 
+static int
+filt_userattach(struct knote *kn)
+{
+
+	/* 
+	 * EVFILT_USER knotes are not attached to anything in the kernel.
+	 */ 
+	kn->kn_hook = NULL;
+	if (kn->kn_fflags & NOTE_TRIGGER)
+		kn->kn_hookid = 1;
+	else
+		kn->kn_hookid = 0;
+	return (0);
+}
+
+static void
+filt_userdetach(__unused struct knote *kn)
+{
+
+	/*
+	 * EVFILT_USER knotes are not attached to anything in the kernel.
+	 */
+}
+
+static int
+filt_user(struct knote *kn, __unused long hint)
+{
+
+	return (kn->kn_hookid);
+}
+
+static void
+filt_usertouch(struct knote *kn, struct kevent *kev, u_long type)
+{
+	u_int ffctrl;
+
+	switch (type) {
+	case EVENT_REGISTER:
+		if (kev->fflags & NOTE_TRIGGER)
+			kn->kn_hookid = 1;
+
+		ffctrl = kev->fflags & NOTE_FFCTRLMASK;
+		kev->fflags &= NOTE_FFLAGSMASK;
+		switch (ffctrl) {
+		case NOTE_FFNOP:
+			break;
+
+		case NOTE_FFAND:
+			kn->kn_sfflags &= kev->fflags;
+			break;
+
+		case NOTE_FFOR:
+			kn->kn_sfflags |= kev->fflags;
+			break;
+
+		case NOTE_FFCOPY:
+			kn->kn_sfflags = kev->fflags;
+			break;
+
+		default:
+			/* XXX Return error? */
+			break;
+		}
+		kn->kn_sdata = kev->data;
+		if (kev->flags & EV_CLEAR) {
+			kn->kn_hookid = 0;
+			kn->kn_data = 0;
+			kn->kn_fflags = 0;
+		}
+		break;
+
+        case EVENT_PROCESS:
+		*kev = kn->kn_kevent;
+		kev->fflags = kn->kn_sfflags;
+		kev->data = kn->kn_sdata;
+		if (kn->kn_flags & EV_CLEAR) {
+			kn->kn_hookid = 0;
+			kn->kn_data = 0;
+			kn->kn_fflags = 0;
+		}
+		break;
+
+	default:
+		panic("filt_usertouch() - invalid type (%ld)", type);
+		break;
+	}
+}
+
 int
 kqueue(struct thread *td, struct kqueue_args *uap)
 {
@@ -717,7 +818,7 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
 				continue;
 			kevp->flags &= ~EV_SYSFLAGS;
 			error = kqueue_register(kq, kevp, td, 1);
-			if (error) {
+			if (error || (kevp->flags & EV_RECEIPT)) {
 				if (nevents != 0) {
 					kevp->flags = EV_ERROR;
 					kevp->data = error;
@@ -919,17 +1020,11 @@ findkn:
 		goto findkn;
 	}
 
-	if (kn == NULL && ((kev->flags & EV_ADD) == 0)) {
-		KQ_UNLOCK(kq);
-		error = ENOENT;
-		goto done;
-	}
-
 	/*
 	 * kn now contains the matching knote, or NULL if no match
 	 */
-	if (kev->flags & EV_ADD) {
-		if (kn == NULL) {
+	if (kn == NULL) {
+		if (kev->flags & EV_ADD) {
 			kn = tkn;
 			tkn = NULL;
 			if (kn == NULL) {
@@ -968,34 +1063,16 @@ findkn:
 				goto done;
 			}
 			KN_LIST_LOCK(kn);
+			goto done_ev_add;
 		} else {
-			/*
-			 * The user may change some filter values after the
-			 * initial EV_ADD, but doing so will not reset any
-			 * filter which has already been triggered.
-			 */
-			kn->kn_status |= KN_INFLUX;
+			/* No matching knote and the EV_ADD flag is not set. */
 			KQ_UNLOCK(kq);
-			KN_LIST_LOCK(kn);
-			kn->kn_sfflags = kev->fflags;
-			kn->kn_sdata = kev->data;
-			kn->kn_kevent.udata = kev->udata;
+			error = ENOENT;
+			goto done;
 		}
-
-		/*
-		 * We can get here with kn->kn_knlist == NULL.
-		 * This can happen when the initial attach event decides that
-		 * the event is "completed" already.  i.e. filt_procattach
-		 * is called on a zombie process.  It will call filt_proc
-		 * which will remove it from the list, and NULL kn_knlist.
-		 */
-		event = kn->kn_fop->f_event(kn, 0);
-		KQ_LOCK(kq);
-		if (event)
-			KNOTE_ACTIVATE(kn, 1);
-		kn->kn_status &= ~KN_INFLUX;
-		KN_LIST_UNLOCK(kn);
-	} else if (kev->flags & EV_DELETE) {
+	}
+	
+	if (kev->flags & EV_DELETE) {
 		kn->kn_status |= KN_INFLUX;
 		KQ_UNLOCK(kq);
 		if (!(kn->kn_status & KN_DETACHED))
@@ -1004,6 +1081,37 @@ findkn:
 		goto done;
 	}
 
+	/*
+	 * The user may change some filter values after the initial EV_ADD,
+	 * but doing so will not reset any filter which has already been
+	 * triggered.
+	 */
+	kn->kn_status |= KN_INFLUX;
+	KQ_UNLOCK(kq);
+	KN_LIST_LOCK(kn);
+	kn->kn_kevent.udata = kev->udata;
+	if (!fops->f_isfd && fops->f_touch != NULL) {
+		fops->f_touch(kn, kev, EVENT_REGISTER);
+	} else {
+		kn->kn_sfflags = kev->fflags;
+		kn->kn_sdata = kev->data;
+	}
+
+	/*
+	 * We can get here with kn->kn_knlist == NULL.  This can happen when
+	 * the initial attach event decides that the event is "completed" 
+	 * already.  i.e. filt_procattach is called on a zombie process.  It
+	 * will call filt_proc which will remove it from the list, and NULL
+	 * kn_knlist.
+	 */
+done_ev_add:
+	event = kn->kn_fop->f_event(kn, 0);
+	KQ_LOCK(kq);
+	if (event)
+		KNOTE_ACTIVATE(kn, 1);
+	kn->kn_status &= ~KN_INFLUX;
+	KN_LIST_UNLOCK(kn);
+
 	if ((kev->flags & EV_DISABLE) &&
 	    ((kn->kn_status & KN_DISABLED) == 0)) {
 		kn->kn_status |= KN_DISABLED;
@@ -1183,7 +1291,7 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
 	struct timeval atv, rtv, ttv;
 	struct knote *kn, *marker;
 	int count, timeout, nkev, error, influx;
-	int haskqglobal;
+	int haskqglobal, touch;
 
 	count = maxevents;
 	nkev = 0;
@@ -1315,12 +1423,25 @@ start:
 				influx = 1;
 				continue;
 			}
-			*kevp = kn->kn_kevent;
+			touch = (!kn->kn_fop->f_isfd &&
+			    kn->kn_fop->f_touch != NULL);
+			if (touch)
+				kn->kn_fop->f_touch(kn, kevp, EVENT_PROCESS);
+			else
+				*kevp = kn->kn_kevent;
 			KQ_LOCK(kq);
 			KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal);
-			if (kn->kn_flags & EV_CLEAR) {
-				kn->kn_data = 0;
-				kn->kn_fflags = 0;
+			if (kn->kn_flags & (EV_CLEAR |  EV_DISPATCH)) {
+				/* 
+				 * Manually clear knotes who weren't 
+				 * 'touch'ed.
+				 */
+				if (touch == 0 && kn->kn_flags & EV_CLEAR) {
+					kn->kn_data = 0;
+					kn->kn_fflags = 0;
+				}
+				if (kn->kn_flags & EV_DISPATCH)
+					kn->kn_status |= KN_DISABLED;
 				kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
 				kq->kq_count--;
 			} else
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 6824152f53e..4365e44e58d 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -41,7 +41,8 @@
 #define EVFILT_NETDEV		(-8)	/* network devices */
 #define EVFILT_FS		(-9)	/* filesystem events */
 #define EVFILT_LIO		(-10)	/* attached to lio requests */
-#define EVFILT_SYSCOUNT		10
+#define EVFILT_USER		(-11)	/* User events */
+#define EVFILT_SYSCOUNT		11
 
 #define EV_SET(kevp_, a, b, c, d, e, f) do {	\
 	struct kevent *kevp = (kevp_);		\
@@ -71,6 +72,8 @@ struct kevent {
 /* flags */
 #define EV_ONESHOT	0x0010		/* only report one occurrence */
 #define EV_CLEAR	0x0020		/* clear event state after reporting */
+#define EV_RECEIPT	0x0040		/* force EV_ERROR on success, data=0 */
+#define EV_DISPATCH	0x0080		/* disable event after reporting */
 
 #define EV_SYSFLAGS	0xF000		/* reserved by system */
 #define EV_FLAG1	0x2000		/* filter-specific flag */
@@ -79,6 +82,25 @@ struct kevent {
 #define EV_EOF		0x8000		/* EOF detected */
 #define EV_ERROR	0x4000		/* error, data contains errno */
 
+ /*
+  * data/hint flags/masks for EVFILT_USER, shared with userspace
+  *
+  * On input, the top two bits of fflags specifies how the lower twenty four
+  * bits should be applied to the stored value of fflags.
+  *
+  * On output, the top two bits will always be set to NOTE_FFNOP and the
+  * remaining twenty four bits will contain the stored fflags value.
+  */
+#define NOTE_FFNOP	0x00000000		/* ignore input fflags */
+#define NOTE_FFAND	0x40000000		/* AND fflags */
+#define NOTE_FFOR	0x80000000		/* OR fflags */
+#define NOTE_FFCOPY	0xc0000000		/* copy fflags */
+#define NOTE_FFCTRLMASK	0xc0000000		/* masks for operations */
+#define NOTE_FFLAGSMASK	0x00ffffff
+
+#define NOTE_TRIGGER	0x01000000		/* Cause the event to be
+						   triggered for output. */
+
 /*
  * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
  */
@@ -154,11 +176,22 @@ MALLOC_DECLARE(M_KQUEUE);
  */
 #define NOTE_SIGNAL	0x08000000
 
+/*
+ * Hint values for the optional f_touch event filter.  If f_touch is not set 
+ * to NULL and f_isfd is zero the f_touch filter will be called with the type
+ * argument set to EVENT_REGISTER during a kevent() system call.  It is also
+ * called under the same conditions with the type argument set to EVENT_PROCESS
+ * when the event has been triggered.
+ */
+#define EVENT_REGISTER	1
+#define EVENT_PROCESS	2
+
 struct filterops {
 	int	f_isfd;		/* true if ident == filedescriptor */
 	int	(*f_attach)(struct knote *kn);
 	void	(*f_detach)(struct knote *kn);
 	int	(*f_event)(struct knote *kn, long hint);
+	void	(*f_touch)(struct knote *kn, struct kevent *kev, u_long type);
 };
 
 /*
@@ -193,6 +226,7 @@ struct knote {
 	} kn_ptr;
 	struct			filterops *kn_fop;
 	void			*kn_hook;
+	int			kn_hookid;
 
 #define kn_id		kn_kevent.ident
 #define kn_filter	kn_kevent.filter

From 5d933cfd98e1cdd3a6e8559505179b447bff3f58 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sun, 1 Nov 2009 10:01:39 +0000
Subject: [PATCH 0457/2592] MFC rev. 198623: Add missing ATA kernel options
 dependencies.

---
 sys/conf/files | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/conf/files b/sys/conf/files
index 0e418fcac76..b448818ea7d 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -517,14 +517,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 f36e7051c71f30bcbb524a7b695813b55c1035dd Mon Sep 17 00:00:00 2001
From: Ed Schouten 
Date: Sun, 1 Nov 2009 10:30:30 +0000
Subject: [PATCH 0458/2592] MFC various commits back to stable/8:

SVN r197174:
  Make sure we never place the cursor outside the screen.

  For some vague reason, it may be possible that scp->cursor_pos exceeds
  scp->ysize * scp->xsize. This means that teken_set_cursor() may get
  called with an invalid position. Just ignore the old cursor position in
  this case.

  Reported by:  Paul B. Mahol 

SVN r198213:
  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

SVN r198215, r198217:
  Fix a typo in the jail(8) manpage.

  Submitted by: Jille Timmermans 

SVN r198216:
  Fix qouting in a comment, to make it look more consistent

  Submitted by: Jille Timmermans 

SVN r198223:
  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
---
 etc/rc.subr                    |  2 +-
 sys/dev/syscons/scterm-teken.c |  9 ++++++---
 sys/kern/tty.c                 | 32 ++++++++++++++++++++++++++++++--
 sys/sys/ttyqueue.h             | 14 ++++++++++++++
 usr.sbin/jail/jail.8           |  4 ++--
 5 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/etc/rc.subr b/etc/rc.subr
index 31559fc7a54..c6f241253c9 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -565,7 +565,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}}
diff --git a/sys/dev/syscons/scterm-teken.c b/sys/dev/syscons/scterm-teken.c
index 36cfbb5d35f..5dd1cbcea97 100644
--- a/sys/dev/syscons/scterm-teken.c
+++ b/sys/dev/syscons/scterm-teken.c
@@ -130,9 +130,12 @@ scteken_init(scr_stat *scp, void **softc, int code)
 		tp.tp_col = scp->xsize;
 		teken_set_winsize(&ts->ts_teken, &tp);
 
-		tp.tp_row = scp->cursor_pos / scp->xsize;
-		tp.tp_col = scp->cursor_pos % scp->xsize;
-		teken_set_cursor(&ts->ts_teken, &tp);
+		if (scp->cursor_pos < scp->ysize * scp->xsize) {
+			/* Valid old cursor position. */
+			tp.tp_row = scp->cursor_pos / scp->xsize;
+			tp.tp_col = scp->cursor_pos % scp->xsize;
+			teken_set_cursor(&ts->ts_teken, &tp);
+		}
 		break;
 	}
 
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index a14f71425b2..9ad25fc3a04 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
@@ -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);
 
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)
 {
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index f3340bd0334..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
@@ -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 d0b37c2f347425c8c7763190131105b2d1ecc5df Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sun, 1 Nov 2009 10:56:03 +0000
Subject: [PATCH 0459/2592] MFC: r198609

Revert part of r198363, there is no "device cam", it is
included in "device scbus".
---
 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 0406cc12b60c1f7affdd78b5d06a57d9859a4488 Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sun, 1 Nov 2009 11:34:13 +0000
Subject: [PATCH 0460/2592] MFC r197128,197325: add support for smbus
 controller found in AMD SB700

---
 sys/pci/intpm.c    | 60 ++++++++++++++++++++++++++++++++++++----------
 sys/pci/intpmreg.h |  2 ++
 2 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/sys/pci/intpm.c b/sys/pci/intpm.c
index 63eb4c4bde8..1cbe75df407 100644
--- a/sys/pci/intpm.c
+++ b/sys/pci/intpm.c
@@ -53,6 +53,8 @@ struct intsmb_softc {
 	void			*irq_hand;
 	device_t		smbus;
 	int			isbusy;
+	int			cfg_irq9;
+	int			poll;
 	struct mtx		lock;
 };
 
@@ -96,6 +98,10 @@ intsmb_probe(device_t dev)
 #endif
 		device_set_desc(dev, "Intel PIIX4 SMBUS Interface");
 		break;
+	case 0x43851002:
+		device_set_desc(dev, "AMD SB600/700/710/750 SMBus Controller");
+		/* XXX Maybe force polling right here? */
+		break;
 	default:
 		return (ENXIO);
 	}
@@ -108,12 +114,24 @@ intsmb_attach(device_t dev)
 {
 	struct intsmb_softc *sc = device_get_softc(dev);
 	int error, rid, value;
+	int intr;
 	char *str;
 
 	sc->dev = dev;
 
 	mtx_init(&sc->lock, device_get_nameunit(dev), "intsmb", MTX_DEF);
 
+	sc->cfg_irq9 = 0;
+#ifndef NO_CHANGE_PCICONF
+	switch (pci_get_devid(dev)) {
+	case 0x71138086:	/* Intel 82371AB */
+	case 0x719b8086:	/* Intel 82443MX */
+		/* Changing configuration is allowed. */
+		sc->cfg_irq9 = 1;
+		break;
+	}
+#endif
+
 	rid = PCI_BASE_ADDR_SMB;
 	sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
 	    RF_ACTIVE);
@@ -123,27 +141,42 @@ intsmb_attach(device_t dev)
 		goto fail;
 	}
 
-#ifndef NO_CHANGE_PCICONF
-	pci_write_config(dev, PCIR_INTLINE, 0x9, 1);
-	pci_write_config(dev, PCI_HST_CFG_SMB,
-	    PCI_INTR_SMB_IRQ9 | PCI_INTR_SMB_ENABLE, 1);
-#endif
+	if (sc->cfg_irq9) {
+		pci_write_config(dev, PCIR_INTLINE, 0x9, 1);
+		pci_write_config(dev, PCI_HST_CFG_SMB,
+		    PCI_INTR_SMB_IRQ9 | PCI_INTR_SMB_ENABLE, 1);
+	}
 	value = pci_read_config(dev, PCI_HST_CFG_SMB, 1);
-	switch (value & 0xe) {
+	sc->poll = (value & PCI_INTR_SMB_ENABLE) == 0;
+	intr = value & PCI_INTR_SMB_MASK;
+	switch (intr) {
 	case PCI_INTR_SMB_SMI:
 		str = "SMI";
 		break;
 	case PCI_INTR_SMB_IRQ9:
 		str = "IRQ 9";
 		break;
+	case PCI_INTR_SMB_IRQ_PCI:
+		str = "PCI IRQ";
+		break;
 	default:
 		str = "BOGUS";
 	}
+
 	device_printf(dev, "intr %s %s ", str,
-	    (value & 1) ? "enabled" : "disabled");
+	    sc->poll == 0 ? "enabled" : "disabled");
 	printf("revision %d\n", pci_read_config(dev, PCI_REVID_SMB, 1));
 
-	if ((value & 0xe) != PCI_INTR_SMB_IRQ9) {
+	if (!sc->poll && intr == PCI_INTR_SMB_SMI) {
+		device_printf(dev,
+		    "using polling mode when configured interrupt is SMI\n");
+		sc->poll = 1;
+	}
+
+	if (sc->poll)
+	    goto no_intr;
+
+	if (intr != PCI_INTR_SMB_IRQ9 && intr != PCI_INTR_SMB_IRQ_PCI) {
 		device_printf(dev, "Unsupported interrupt mode\n");
 		error = ENXIO;
 		goto fail;
@@ -151,7 +184,9 @@ intsmb_attach(device_t dev)
 
 	/* Force IRQ 9. */
 	rid = 0;
-	bus_set_resource(dev, SYS_RES_IRQ, rid, 9, 1);
+	if (sc->cfg_irq9)
+		bus_set_resource(dev, SYS_RES_IRQ, rid, 9, 1);
+
 	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
 	    RF_SHAREABLE | RF_ACTIVE);
 	if (sc->irq_res == NULL) {
@@ -167,6 +202,7 @@ intsmb_attach(device_t dev)
 		goto fail;
 	}
 
+no_intr:
 	sc->isbusy = 0;
 	sc->smbus = device_add_child(dev, "smbus", -1);
 	if (sc->smbus == NULL) {
@@ -361,7 +397,7 @@ intsmb_start(struct intsmb_softc *sc, unsigned char cmd, int nointr)
 	tmp |= PIIX4_SMBHSTCNT_START;
 
 	/* While not in autoconfiguration enable interrupts. */
-	if (!cold && !nointr)
+	if (!sc->poll && !cold && !nointr)
 		tmp |= PIIX4_SMBHSTCNT_INTREN;
 	bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp);
 }
@@ -411,8 +447,6 @@ intsmb_stop_poll(struct intsmb_softc *sc)
 		if (!(status & PIIX4_SMBHSTSTAT_BUSY)) {
 			sc->isbusy = 0;
 			error = intsmb_error(sc->dev, status);
-			if (error == 0 && !(status & PIIX4_SMBHSTSTAT_INTR))
-				device_printf(sc->dev, "unknown cause why?\n");
 			return (error);
 		}
 	}
@@ -434,7 +468,7 @@ intsmb_stop(struct intsmb_softc *sc)
 
 	INTSMB_LOCK_ASSERT(sc);
 
-	if (cold)
+	if (sc->poll || cold)
 		/* So that it can use device during device probe on SMBus. */
 		return (intsmb_stop_poll(sc));
 
diff --git a/sys/pci/intpmreg.h b/sys/pci/intpmreg.h
index 236c737a9bd..eaebcdd6063 100644
--- a/sys/pci/intpmreg.h
+++ b/sys/pci/intpmreg.h
@@ -35,7 +35,9 @@
 #define	PCI_BASE_ADDR_SMB	0x90	/* IO BAR. */
 #define	PCI_BASE_ADDR_PM	0x40
 #define	PCI_HST_CFG_SMB		0xd2	/* Host Configuration */
+#define	PCI_INTR_SMB_MASK	0xe
 #define	PCI_INTR_SMB_SMI	0
+#define	PCI_INTR_SMB_IRQ_PCI	2
 #define	PCI_INTR_SMB_IRQ9	8
 #define	PCI_INTR_SMB_ENABLE	1
 #define	PCI_SLV_CMD_SMB		0xd3 /*SLAVE COMMAND*/

From b8daad66fd24d5b9ebc602e802af1c37404a8a24 Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sun, 1 Nov 2009 17:36:36 +0000
Subject: [PATCH 0461/2592] MFC 197641: print_caddr_t: drop incorrect __unused
 from parameter

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

diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 668ca1a1c57..95006035511 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -284,7 +284,7 @@ restart:
  ***************************************************************************
  */
 static void
-print_caddr_t(void *data __unused)
+print_caddr_t(void *data)
 {
 	printf("%s", (char *)data);
 }

From 33b3442f13b962cba3041f2b3f48058bbf6ab2b9 Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sun, 1 Nov 2009 17:40:05 +0000
Subject: [PATCH 0462/2592] MFC 197658: print machine in kernel boot version
 string

PR:		kern/126926
---
 sys/kern/init_main.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 95006035511..f1508c89737 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -288,11 +288,24 @@ print_caddr_t(void *data)
 {
 	printf("%s", (char *)data);
 }
+
+static void
+print_version(void *data __unused)
+{
+	int len;
+
+	/* Strip a trailing newline from version. */
+	len = strlen(version);
+	while (len > 0 && version[len - 1] == '\n')
+		len--;
+	printf("%.*s %s\n", len, version, machine);
+}
+
 SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t,
     copyright);
 SYSINIT(trademark, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t,
     trademark);
-SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_THIRD, print_caddr_t, version);
+SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_THIRD, print_version, NULL);
 
 #ifdef WITNESS
 static char wit_warn[] =

From f13868d206e859c41fa18052eeba4de62a8dad32 Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sun, 1 Nov 2009 17:45:37 +0000
Subject: [PATCH 0463/2592] MFC 197647: cpufunc.h: unify/correct style of c
 extension names

---
 sys/amd64/include/cpufunc.h | 6 +++---
 sys/i386/include/cpufunc.h  | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index eb264aec77a..dee78cb57a1 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -277,7 +277,7 @@ static __inline void
 mfence(void)
 {
 
-	__asm__ __volatile("mfence" : : : "memory");
+	__asm __volatile("mfence" : : : "memory");
 }
 
 static __inline void
@@ -457,14 +457,14 @@ load_es(u_int sel)
 	__asm __volatile("mov %0,%%es" : : "rm" (sel));
 }
 
-static inline void
+static __inline void
 cpu_monitor(const void *addr, int extensions, int hints)
 {
 	__asm __volatile("monitor;"
 	    : :"a" (addr), "c" (extensions), "d"(hints));
 }
 
-static inline void
+static __inline void
 cpu_mwait(int extensions, int hints)
 {
 	__asm __volatile("mwait;" : :"a" (hints), "c" (extensions));
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index 147040bbcca..78863d1467c 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -132,14 +132,14 @@ enable_intr(void)
 #endif
 }
 
-static inline void
+static __inline void
 cpu_monitor(const void *addr, int extensions, int hints)
 {
 	__asm __volatile("monitor;"
 	    : :"a" (addr), "c" (extensions), "d"(hints));
 }
 
-static inline void
+static __inline void
 cpu_mwait(int extensions, int hints)
 {
 	__asm __volatile("mwait;" : :"a" (hints), "c" (extensions));

From fc06d8191e02e940a5f918349d7bd9cef11e49dc Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sun, 1 Nov 2009 17:53:33 +0000
Subject: [PATCH 0464/2592] MFC 198271: add amdtemp to i386 NOTES

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

diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index f772b25584d..4c71a81941e 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -786,8 +786,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 2df1facbb784586de530e7f905910286dff05bae Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sun, 1 Nov 2009 17:56:45 +0000
Subject: [PATCH 0465/2592] MFC 198279: fix sorting of some amd* entries in
 some makefiles

---
 sys/modules/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 30d21963564..089450acba4 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 2866adee7d13189c44926489c4c568ba55af6cae Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sun, 1 Nov 2009 18:10:38 +0000
Subject: [PATCH 0466/2592] MFC 198279: fix sorting of some amd* entries in
 some makefiles

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

diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 36d89287774..8063f4dafe5 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 \

From 19b7bdf72b671cc1738d3abf2be585daf7e9a5ab Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sun, 1 Nov 2009 18:16:55 +0000
Subject: [PATCH 0467/2592] MFC 198272, 198288: fix watchdogd(8) reference

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

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

From ea9b1909f6a2399700c4092d1f45009d9f4093ec Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Sun, 1 Nov 2009 18:39:26 +0000
Subject: [PATCH 0468/2592] MFC 197450: number of cleanups in i386 and amd64
 pci md code

---
 sys/amd64/pci/pci_cfgreg.c | 16 ++++++++--------
 sys/dev/pci/pcireg.h       |  1 +
 sys/i386/pci/pci_cfgreg.c  | 14 +++++++-------
 3 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c
index be9e40488ee..3e29a585be3 100644
--- a/sys/amd64/pci/pci_cfgreg.c
+++ b/sys/amd64/pci/pci_cfgreg.c
@@ -181,9 +181,9 @@ pci_cfgenable(unsigned bus, unsigned slot, unsigned func, int reg, int bytes)
 {
 	int dataport = 0;
 
-	if (bus <= PCI_BUSMAX && slot < 32 && func <= PCI_FUNCMAX &&
-	    reg <= PCI_REGMAX && bytes != 3 && (unsigned) bytes <= 4 &&
-	    (reg & (bytes - 1)) == 0) {
+	if (bus <= PCI_BUSMAX && slot <= PCI_SLOTMAX && func <= PCI_FUNCMAX &&
+	    (unsigned)reg <= PCI_REGMAX && bytes != 3 &&
+	    (unsigned)bytes <= 4 && (reg & (bytes - 1)) == 0) {
 		outl(CONF1_ADDR_PORT, (1 << 31) | (bus << 16) | (slot << 11) 
 		    | (func << 8) | (reg & ~0x03));
 		dataport = CONF1_DATA_PORT + (reg & 0x03);
@@ -281,7 +281,7 @@ pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus)
 	 * fall back to using type 1 config access instead.
 	 */
 	if (pci_cfgregopen() != 0) {
-		for (slot = 0; slot < 32; slot++) {
+		for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
 			val1 = pcireg_cfgread(0, slot, 0, 0, 4);
 			if (val1 == 0xffffffff)
 				continue;
@@ -309,8 +309,8 @@ pciereg_cfgread(int bus, unsigned slot, unsigned func, unsigned reg,
 	volatile vm_offset_t va;
 	int data = -1;
 
-	if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 ||
-	    func > PCI_FUNCMAX || reg >= 0x1000)
+	if (bus < pcie_minbus || bus > pcie_maxbus || slot > PCI_SLOTMAX ||
+	    func > PCI_FUNCMAX || reg > PCIE_REGMAX)
 		return (-1);
 
 	va = PCIE_VADDR(pcie_base, reg, bus, slot, func);
@@ -336,8 +336,8 @@ pciereg_cfgwrite(int bus, unsigned slot, unsigned func, unsigned reg, int data,
 {
 	volatile vm_offset_t va;
 
-	if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 ||
-	    func > PCI_FUNCMAX || reg >= 0x1000)
+	if (bus < pcie_minbus || bus > pcie_maxbus || slot > PCI_SLOTMAX ||
+	    func > PCI_FUNCMAX || reg > PCIE_REGMAX)
 		return;
 
 	va = PCIE_VADDR(pcie_base, reg, bus, slot, func);
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index c7a7245bf1d..981d1e0cde4 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -44,6 +44,7 @@
 #define	PCI_SLOTMAX	31	/* highest supported slot number */
 #define	PCI_FUNCMAX	7	/* highest supported function number */
 #define	PCI_REGMAX	255	/* highest supported config register addr. */
+#define	PCIE_REGMAX	4095	/* highest supported config register addr. */
 #define	PCI_MAXHDRTYPE	2
 
 /* PCI config header registers for all devices */
diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c
index 20050e6f014..ae56990cd7b 100644
--- a/sys/i386/pci/pci_cfgreg.c
+++ b/sys/i386/pci/pci_cfgreg.c
@@ -299,9 +299,9 @@ pci_cfgenable(unsigned bus, unsigned slot, unsigned func, int reg, int bytes)
 	if (bus <= PCI_BUSMAX
 	    && slot < devmax
 	    && func <= PCI_FUNCMAX
-	    && reg <= PCI_REGMAX
+	    && (unsigned)reg <= PCI_REGMAX
 	    && bytes != 3
-	    && (unsigned) bytes <= 4
+	    && (unsigned)bytes <= 4
 	    && (reg & (bytes - 1)) == 0) {
 		switch (cfgmech) {
 		case CFGMECH_PCIE:
@@ -595,7 +595,7 @@ pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus)
 	 * fall back to using type 1 config access instead.
 	 */
 	if (pci_cfgregopen() != 0) {
-		for (slot = 0; slot < 32; slot++) {
+		for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
 			val1 = pcireg_cfgread(0, slot, 0, 0, 4);
 			if (val1 == 0xffffffff)
 				continue;
@@ -661,8 +661,8 @@ pciereg_cfgread(int bus, unsigned slot, unsigned func, unsigned reg,
 	vm_paddr_t pa, papage;
 	int data = -1;
 
-	if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 ||
-	    func > PCI_FUNCMAX || reg >= 0x1000 || bytes > 4 || bytes == 3)
+	if (bus < pcie_minbus || bus > pcie_maxbus || slot > PCI_SLOTMAX ||
+	    func > PCI_FUNCMAX || reg > PCIE_REGMAX)
 		return (-1);
 
 	critical_enter();
@@ -695,8 +695,8 @@ pciereg_cfgwrite(int bus, unsigned slot, unsigned func, unsigned reg, int data,
 	volatile vm_offset_t va;
 	vm_paddr_t pa, papage;
 
-	if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 ||
-	    func > PCI_FUNCMAX || reg >= 0x1000)
+	if (bus < pcie_minbus || bus > pcie_maxbus || slot > PCI_SLOTMAX ||
+	    func > PCI_FUNCMAX || reg > PCIE_REGMAX)
 		return;
 
 	critical_enter();

From 30aae71b220c11fbb1192c87db9219939c5efafa Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sun, 1 Nov 2009 18:48:06 +0000
Subject: [PATCH 0469/2592] MFC r197393   Add FreeBSD 7.2 and 7.3.

---
 gnu/usr.bin/groff/tmac/mdoc.local | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gnu/usr.bin/groff/tmac/mdoc.local b/gnu/usr.bin/groff/tmac/mdoc.local
index a963b7e7770..8c7392efe5a 100644
--- a/gnu/usr.bin/groff/tmac/mdoc.local
+++ b/gnu/usr.bin/groff/tmac/mdoc.local
@@ -72,6 +72,8 @@
 .ds doc-operating-system-FreeBSD-6.3    6.3
 .ds doc-operating-system-FreeBSD-6.4    6.4
 .ds doc-operating-system-FreeBSD-7.1    7.1
+.ds doc-operating-system-FreeBSD-7.2    7.2
+.ds doc-operating-system-FreeBSD-7.3    7.3
 .ds doc-operating-system-FreeBSD-8.0    8.0
 .
 .\" Definitions not (yet) in doc-syms

From 588b5e6ee8ae83faf087cf97e8db8700b721a32b Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sun, 1 Nov 2009 19:22:07 +0000
Subject: [PATCH 0470/2592] MFC r197331, r197394   Add getpagesizes(3).

---
 lib/libc/gen/Makefile.inc   |  6 +--
 lib/libc/gen/Symbol.map     |  4 ++
 lib/libc/gen/getpagesizes.3 | 99 +++++++++++++++++++++++++++++++++++++
 lib/libc/gen/getpagesizes.c | 78 +++++++++++++++++++++++++++++
 sys/sys/mman.h              |  1 +
 5 files changed, 185 insertions(+), 3 deletions(-)
 create mode 100644 lib/libc/gen/getpagesizes.3
 create mode 100644 lib/libc/gen/getpagesizes.c

diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index 8837038ee09..b06f846dd47 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -15,7 +15,7 @@ SRCS+=  __getosreldate.c __xuname.c \
 	getbootfile.c getbsize.c \
 	getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \
 	gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \
-	getosreldate.c getpagesize.c \
+	getosreldate.c getpagesize.c getpagesizes.c \
 	getpeereid.c getprogname.c getpwent.c getttyent.c \
 	getusershell.c getvfsbyname.c glob.c \
 	initgroups.c isatty.c isinf.c isnan.c jrand48.c lcong48.c \
@@ -51,8 +51,8 @@ MAN+=	alarm.3 arc4random.3 \
 	getbootfile.3 getbsize.3 getcap.3 getcontext.3 getcwd.3 \
 	getdiskbyname.3 getdomainname.3 getfsent.3 \
 	getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \
-	getmntinfo.3 getnetgrent.3 getosreldate.3 \
-	getpagesize.3 getpass.3 getpeereid.3 getprogname.3 getpwent.3 \
+	getmntinfo.3 getnetgrent.3 getosreldate.3 getpagesize.3 \
+	getpagesizes.3 getpass.3 getpeereid.3 getprogname.3 getpwent.3 \
 	getttyent.3 getusershell.3 getvfsbyname.3 \
 	glob.3 initgroups.3 isgreater.3 ldexp.3 lockf.3 makecontext.3 \
 	modf.3 \
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index 4f1efafb360..197430acdda 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -366,6 +366,10 @@ FBSD_1.1 {
 	tcsetsid;
 };
 
+FBSD_1.2 {
+	getpagesizes;
+};
+
 FBSDprivate_1.0 {
 	/* needed by thread libraries */
 	__thr_jtable;
diff --git a/lib/libc/gen/getpagesizes.3 b/lib/libc/gen/getpagesizes.3
new file mode 100644
index 00000000000..959df815586
--- /dev/null
+++ b/lib/libc/gen/getpagesizes.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 2009 Alan L. Cox 
+.\" 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 September 21, 2009
+.Dt GETPAGESIZES 3
+.Os
+.Sh NAME
+.Nm getpagesizes
+.Nd "get system page sizes"
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/mman.h
+.Ft int
+.Fn getpagesizes "size_t pagesize[]" "int nelem"
+.Sh DESCRIPTION
+The
+.Fn getpagesizes
+function retrieves page size information from the system.
+When it is called with
+.Fa pagesize
+specified as
+.Dv NULL
+and
+.Fa nelem
+specified as 0, it returns the number of distinct page sizes that are
+supported by the system.
+Otherwise, it assigns up to
+.Fa nelem
+of the system-supported page sizes to consecutive elements of the
+array referenced by
+.Fa pagesize .
+These page sizes are expressed in bytes.
+In this case,
+.Fn getpagesizes
+returns the number of such page sizes that it assigned to the array. 
+.Sh RETURN VALUES
+If successful, the
+.Fn getpagesizes
+function returns either the number of page sizes that are supported by
+the system or the number of supported page sizes that it assigned to
+the array referenced by
+.Fa pagesize .
+Otherwise, it returns the value\~\-1 and sets
+.Va errno
+to indicate the error.
+.Sh ERRORS
+The
+.Fn getpagesizes
+function will succeed unless:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa pagesize
+argument is
+.Dv NULL
+and the
+.Fa nelem
+argument is non-zero.
+.It Bq Er EINVAL
+The
+.Fa nelem
+argument is less than zero.
+.El
+.Sh SEE ALSO
+.Xr getpagesize 3
+.Sh HISTORY
+The
+.Fn getpagesizes
+function first appeared in Solaris 9.
+This manual page was written in conjunction with a new but compatible
+implementation that was first released in
+.Fx 7.3 .
+.Sh AUTHORS
+This manual page was written by
+.An Alan L. Cox Aq alc@cs.rice.edu .
diff --git a/lib/libc/gen/getpagesizes.c b/lib/libc/gen/getpagesizes.c
new file mode 100644
index 00000000000..b0de9390f88
--- /dev/null
+++ b/lib/libc/gen/getpagesizes.c
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 2009 Alan L. Cox 
+ * 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 
+
+/*
+ * Retrieves page size information from the system.  Specifically, returns the
+ * number of distinct page sizes that are supported by the system, if
+ * "pagesize" is NULL and "nelem" is 0.  Otherwise, assigns up to "nelem" of
+ * the system-supported page sizes to consecutive elements of the array
+ * referenced by "pagesize", and returns the number of such page sizes that it
+ * assigned to the array.  These page sizes are expressed in bytes.
+ *
+ * The implementation of this function does not directly or indirectly call
+ * malloc(3) or any other dynamic memory allocator that may itself call this
+ * function.
+ */
+int
+getpagesizes(size_t pagesize[], int nelem)
+{
+	static u_long ps[MAXPAGESIZES];
+	static int nops;
+	size_t size;
+	int i; 
+
+	if (nelem < 0 || (nelem > 0 && pagesize == NULL)) {
+		errno = EINVAL;
+		return (-1);
+	}
+	/* Cache the result of the sysctl(2). */
+	if (nops == 0) {
+		size = sizeof(ps);
+		if (sysctlbyname("hw.pagesizes", ps, &size, NULL, 0) == -1)
+			return (-1);
+		/* Count the number of page sizes that are supported. */
+		nops = size / sizeof(ps[0]);
+		while (nops > 0 && ps[nops - 1] == 0)
+			nops--;
+	}
+	if (pagesize == NULL)
+		return (nops);
+	/* Return up to "nelem" page sizes from the cached result. */
+	if (nelem > nops)
+		nelem = nops;
+	for (i = 0; i < nelem; i++)
+		pagesize[i] = ps[i];
+	return (nelem);
+}
diff --git a/sys/sys/mman.h b/sys/sys/mman.h
index 6a963c9228c..9b64e8981cc 100644
--- a/sys/sys/mman.h
+++ b/sys/sys/mman.h
@@ -208,6 +208,7 @@ __BEGIN_DECLS
  * posix_typed_mem_open().
  */
 #if __BSD_VISIBLE
+int	getpagesizes(size_t *, int);
 int	madvise(void *, size_t, int);
 int	mincore(const void *, size_t, char *);
 int	minherit(void *, size_t, int);

From 12e8008e6d16eb5fc9805d43b97977443e34eb6d Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sun, 1 Nov 2009 20:24:17 +0000
Subject: [PATCH 0471/2592] MFC r197163   Add the FBSD_1.2 namespace.

Reminded by:	kib
---
 lib/libc/Versions.def | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/lib/libc/Versions.def b/lib/libc/Versions.def
index a17e0a5376a..da0ca6f8063 100644
--- a/lib/libc/Versions.def
+++ b/lib/libc/Versions.def
@@ -1,5 +1,11 @@
 # $FreeBSD$
 
+#
+# Note: Whenever bumping the FBSD version, always make
+#       FBSDprivate_1.0 depend on the new FBSD version.
+#       This will keep it at the end of the dependency chain.
+#
+
 # This is our first version; it depends on no other.
 # This version was first added to 7.0-current.
 FBSD_1.0 {
@@ -9,6 +15,10 @@ FBSD_1.0 {
 FBSD_1.1 {
 } FBSD_1.0;
 
+# This version was first added to 9.0-current.
+FBSD_1.2 {
+} FBSD_1.1;
+
 # This is our private namespace.  Any global interfaces that are
 # strictly for use only by other FreeBSD applications and libraries
 # are listed here.  We use a separate namespace so we can write
@@ -16,4 +26,4 @@ FBSD_1.1 {
 #
 # Please do NOT increment the version of this namespace.
 FBSDprivate_1.0 {
-} FBSD_1.1;
+} FBSD_1.2;

From fd6bbf0435771035098325c24a219e3cc087d921 Mon Sep 17 00:00:00 2001
From: Max Khon 
Date: Mon, 2 Nov 2009 09:47:15 +0000
Subject: [PATCH 0472/2592] MFC: Allow KMOD with hypens and dots.

---
 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 1675ae3b86d66270cdedec49c31d52aeab7e40b7 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Mon, 2 Nov 2009 15:53:32 +0000
Subject: [PATCH 0473/2592] MFC 198691

Fix blitter support for RS880 chips
---
 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 6400e3ac8cd7dd3436016a3ab138e556319a61e2 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Mon, 2 Nov 2009 15:57:03 +0000
Subject: [PATCH 0474/2592] MFC 198692

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 1a4d349290701605419e1b995e1707d2d9f54513 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Mon, 2 Nov 2009 15:59:55 +0000
Subject: [PATCH 0475/2592] MFC 198695

A bit of cleanup work on radeon_freelist_get()

 * Fix the main loop to search all buffers before sleeping.
 * Remove dead code
---
 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 de546efdad2449c2d6e7c5a0ccde9db6e202e340 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Mon, 2 Nov 2009 16:02:16 +0000
Subject: [PATCH 0476/2592] MFC 198696

    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
---
 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 af8e9d942c9bb4c27999f2c624b04dafdfe61121 Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Mon, 2 Nov 2009 16:22:59 +0000
Subject: [PATCH 0477/2592] MFC r198541:

  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 f3d931aaf06..aad4692dc87 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 7c064f68bea8b6f67595c1e50796afd9f7a74c2b Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Mon, 2 Nov 2009 16:27:34 +0000
Subject: [PATCH 0478/2592] MFC r198029:

  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 b561979f8cf4bbfd48a315eaaf95c76e23a1f6f9 Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Mon, 2 Nov 2009 16:32:32 +0000
Subject: [PATCH 0479/2592] MFC r197692:

  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
---
 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 f94d7478f3c867eaaf8e60fa0b5e163ee88f51d9 Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Mon, 2 Nov 2009 16:46:06 +0000
Subject: [PATCH 0480/2592] MFC r197082:

If the pxe client is told to use / as the root path, honour that rather
of trying to mount /pxeroot instead.

PR:		i386/106493
Submitted by:	Andrey Russev
---
 sys/boot/i386/libi386/pxe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/boot/i386/libi386/pxe.c b/sys/boot/i386/libi386/pxe.c
index 4b99c910ba5..5629d90e2cb 100644
--- a/sys/boot/i386/libi386/pxe.c
+++ b/sys/boot/i386/libi386/pxe.c
@@ -282,7 +282,7 @@ pxe_open(struct open_file *f, ...)
 		bootp(pxe_sock, BOOTP_PXE);
 		if (rootip.s_addr == 0)
 			rootip.s_addr = bootplayer.sip;
-		if (!rootpath[1])
+		if (!rootpath[0])
 			strcpy(rootpath, PXENFSROOTPATH);
 
 		for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)

From 55dd54d73fecd7e4b7d2e34b5c802b9db582b769 Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Mon, 2 Nov 2009 16:54:23 +0000
Subject: [PATCH 0481/2592] MFC r197011:

  Increase AAC_CMD_TIMEOUT from 30s to 120s to help avoid spurious
  "COMMAND 0x........ TIMEOUT AFTER .. SECONDS" messages.  Any commands
  that get truly stuck will still trigger the warning and the hardware
  health check, just a little bit later.
---
 sys/dev/aac/aacvar.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h
index d8b527bdabc..7f64371ef86 100644
--- a/sys/dev/aac/aacvar.h
+++ b/sys/dev/aac/aacvar.h
@@ -88,7 +88,7 @@
 /*
  * Timeout for normal commands
  */
-#define AAC_CMD_TIMEOUT		30		/* seconds */
+#define AAC_CMD_TIMEOUT		120		/* seconds */
 
 /*
  * Rate at which we periodically check for timed out commands and kick the

From 225da9692c84acb9effede31c7b3fa9198e90d95 Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Mon, 2 Nov 2009 18:44:01 +0000
Subject: [PATCH 0482/2592] MFC r197524   Make malloc(3) superpage aware.

---
 lib/libc/stdlib/malloc.3 |  6 ++++--
 lib/libc/stdlib/malloc.c | 15 +++++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/lib/libc/stdlib/malloc.3 b/lib/libc/stdlib/malloc.3
index a621a245b40..308ba7b3e12 100644
--- a/lib/libc/stdlib/malloc.3
+++ b/lib/libc/stdlib/malloc.3
@@ -32,7 +32,7 @@
 .\"     @(#)malloc.3	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd August 26, 2008
+.Dd September 26, 2009
 .Dt MALLOC 3
 .Os
 .Sh NAME
@@ -245,7 +245,8 @@ will be initialized to 0x5a.
 This is intended for debugging and will impact performance negatively.
 .It K
 Double/halve the virtual memory chunk size.
-The default chunk size is 1 MB.
+The default chunk size is the maximum of 1 MB and the largest
+page size that is less than or equal to 4 MB.
 .It M
 Use
 .Xr mmap 2
@@ -561,6 +562,7 @@ _malloc_options = "X";
 .Xr alloca 3 ,
 .Xr atexit 3 ,
 .Xr getpagesize 3 ,
+.Xr getpagesizes 3 ,
 .Xr memory 3 ,
 .Xr posix_memalign 3
 .Sh STANDARDS
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
index 8b13d1218d9..80e26e66ec6 100644
--- a/lib/libc/stdlib/malloc.c
+++ b/lib/libc/stdlib/malloc.c
@@ -4795,6 +4795,21 @@ malloc_init_hard(void)
 		}
 	}
 
+	/*
+	 * Increase the chunk size to the largest page size that is greater
+	 * than the default chunk size and less than or equal to 4MB.
+	 */
+	{
+		size_t pagesizes[MAXPAGESIZES];
+		int k, nsizes;
+
+		nsizes = getpagesizes(pagesizes, MAXPAGESIZES);
+		for (k = 0; k < nsizes; k++)
+			if (pagesizes[k] <= (1LU << 22))
+				while ((1LU << opt_chunk_2pow) < pagesizes[k])
+					opt_chunk_2pow++;
+	}
+
 	for (i = 0; i < 3; i++) {
 		unsigned j;
 

From 67de44048a154766f5c2d3717629be4e36fa0e90 Mon Sep 17 00:00:00 2001
From: Max Laier 
Date: Tue, 3 Nov 2009 21:57:00 +0000
Subject: [PATCH 0483/2592] MFC r197334,r197433:     Extract svn and git
 version info from git-svn repos.

---
 sys/conf/newvers.sh | 44 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 9 deletions(-)

diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 7987ddd4218..068bc7b342b 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -89,28 +89,54 @@ i=`${MAKE:-make} -V KERN_IDENT`
 
 case "$d" in
 */sys/*)
+	SRCDIR=${d##*obj}
+	if [ -n "$MACHINE" ]; then
+		SRCDIR=${SRCDIR##/$MACHINE}
+	fi
+	SRCDIR=${SRCDIR%%/sys/*}
+
 	for dir in /bin /usr/bin /usr/local/bin; do
-		if [ -x "${dir}/svnversion" ]; then
+		if [ -d "${SRCDIR}/sys/.svn" -a -x "${dir}/svnversion" ] ; then
 			svnversion=${dir}/svnversion
-			SRCDIR=${d##*obj}
-			if [ -n "$MACHINE" ]; then
-				SRCDIR=${SRCDIR##/$MACHINE}
-			fi
-			SRCDIR=${SRCDIR%%/sys/*}
+			break
+		fi
+		if [ -d "${SRCDIR}/.git" -a -x "${dir}/git" ] ; then
+			git_cmd="${dir}/git --git-dir=${SRCDIR}/.git"
 			break
 		fi
 	done
 
-	if [ -n "$svnversion" -a -d "${SRCDIR}/sys/.svn" ] ; then
+	if [ -n "$svnversion" ] ; then
 		svn=" r`cd ${SRCDIR}/sys && $svnversion`"
 	fi
+	if [ -n "$git_cmd" ] ; then
+		git=`$git_cmd rev-parse --verify --short HEAD 2>/dev/null`
+		svn=`$git_cmd svn find-rev $git 2>/dev/null`
+		if [ -n "$svn" ] ; then
+			svn=" r${svn}"
+			git="=${git}"
+		else
+			svn=`$git_cmd log | fgrep 'git-svn-id:' | head -1 | \
+			     sed -n 's/^.*@\([0-9][0-9]*\).*$/\1/p'`
+			if [ -n $svn ] ; then
+				svn=" r${svn}"
+				git="+${git}"
+			else
+				git=" ${git}"
+			fi
+		fi
+		if $git_cmd --work-tree=${SRCDIR} diff-index \
+		    --name-only HEAD | read dummy; then
+			git="${git}-dirty"
+		fi
+	fi
 	;;
 esac
 
 cat << EOF > vers.c
 $COPYRIGHT
-#define SCCSSTR "@(#)${VERSION} #${v}${svn}: ${t}"
-#define VERSTR "${VERSION} #${v}${svn}: ${t}\\n    ${u}@${h}:${d}\\n"
+#define SCCSSTR "@(#)${VERSION} #${v}${svn}${git}: ${t}"
+#define VERSTR "${VERSION} #${v}${svn}${git}: ${t}\\n    ${u}@${h}:${d}\\n"
 #define RELSTR "${RELEASE}"
 
 char sccs[sizeof(SCCSSTR) > 128 ? sizeof(SCCSSTR) : 128] = SCCSSTR;

From db463c13da8d40e4f032b6c37d3c5a28571e4bca Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Tue, 3 Nov 2009 23:26:31 +0000
Subject: [PATCH 0484/2592] MFC r198581:  Update the route's sequence number
 upon receiving a RANN.

---
 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 b64689e0fbc855bb0a5921e212b35b365638a042 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Wed, 4 Nov 2009 01:50:25 +0000
Subject: [PATCH 0485/2592] MFC r198775

 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
---
 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 4fa864798b55d33753ff221729572060917e2ff6 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Wed, 4 Nov 2009 10:46:55 +0000
Subject: [PATCH 0486/2592] MFC of r198825: 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.
---
 share/zoneinfo/asia     | 99 ++++++++++++++++++++++++++++++++++++++---
 share/zoneinfo/europe   | 38 +++++++++++++++-
 share/zoneinfo/zone.tab |  3 +-
 3 files changed, 130 insertions(+), 10 deletions(-)

diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia
index 7f063cb4bff..1987fc815ba 100644
--- a/share/zoneinfo/asia
+++ b/share/zoneinfo/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/share/zoneinfo/europe b/share/zoneinfo/europe
index adf20a2828c..66ab880e8eb 100644
--- a/share/zoneinfo/europe
+++ b/share/zoneinfo/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/share/zoneinfo/zone.tab b/share/zoneinfo/zone.tab
index c04fb49f221..8b40a34a05a 100644
--- a/share/zoneinfo/zone.tab
+++ b/share/zoneinfo/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 efab19fed7865d9eeb03702d2548b6425698e2cb Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 4 Nov 2009 12:35:35 +0000
Subject: [PATCH 0487/2592] MFC: r198546

Remove spurious `)`
---
 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 e4e76802b8452d9e11740a5e4ff6fd6b5e2179cb Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 4 Nov 2009 13:06:09 +0000
Subject: [PATCH 0488/2592] MFC: r198537

Close a file descriptor leak in an error case.
---
 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 a4f93c10753016fa048f5035f5a5838fc64743a7 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 4 Nov 2009 13:30:32 +0000
Subject: [PATCH 0489/2592] MFC: r198539

Close a stream file descriptor leak.
---
 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 d5c7a9c3d980e1d982443f06111a48b567fd0e1e Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Wed, 4 Nov 2009 13:40:04 +0000
Subject: [PATCH 0490/2592] MFC: r198542

Initialize f_rabuf in the raw device case. A subsequent close()
later on would try to free it, leading to a crash.
---
 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 889239518147c67ef37c1d34eb9c9c847d6d97af Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 4 Nov 2009 16:03:47 +0000
Subject: [PATCH 0491/2592] MFC 198585: When extracting the capture buffer from
 a crashdump, only read the valid portion of the capture buffer.

---
 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 2d7c21427dabe3747ab9d7f0c4ba38e7ce7ed766 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 4 Nov 2009 16:05:09 +0000
Subject: [PATCH 0492/2592] MFC 198586: Include the output of the ddb(4)
 capture buffer.

---
 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 6fd3786837cbda28ee0c01e589ae48dc44d79f9c Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 4 Nov 2009 16:58:26 +0000
Subject: [PATCH 0493/2592] MFC 197772: 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.

---
 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 0b333599d5771704593c6300313b09c17cb17a1a Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Wed, 4 Nov 2009 18:31:43 +0000
Subject: [PATCH 0494/2592] MFC r197586:   It seems some 82559ER controllers do
 not support Rx checksum   offloading. Datasheet said nothing about the
 limitation of 82559ER   except WOL. Explicitly disable Rx checksum offloading
 for   controllers that is known to lack the capability.

  PR:	kern/138135
  Tested by:	Gooderum, Mark < mgooderum <> websense dot com >
---
 sys/dev/fxp/if_fxp.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 4fb890f02b0..a8d961eb0fb 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -631,8 +631,11 @@ fxp_attach(device_t dev)
 	}
 
 	/* For 82559 or later chips, Rx checksum offload is supported. */
-	if (sc->revision >= FXP_REV_82559_A0)
-		sc->flags |= FXP_FLAG_82559_RXCSUM;
+	if (sc->revision >= FXP_REV_82559_A0) {
+		/* 82559ER does not support Rx checksum offloading. */
+		if (sc->ident->devid != 0x1209)
+			sc->flags |= FXP_FLAG_82559_RXCSUM;
+	}
 	/*
 	 * Enable use of extended RFDs and TCBs for 82550
 	 * and later chips. Note: we need extended TXCB support

From dad4753c04985e8953d9bf7133222789d93ab67d Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 4 Nov 2009 20:49:14 +0000
Subject: [PATCH 0495/2592] MFC 198554: 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.

---
 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 9d37c171d74161b58a9db679f5b86f5d710d5c3e Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Thu, 5 Nov 2009 02:27:56 +0000
Subject: [PATCH 0496/2592] MFC r197437:

  Use %zu for size_t, not %zd.
---
 usr.bin/gcore/elfcore.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/usr.bin/gcore/elfcore.c b/usr.bin/gcore/elfcore.c
index a5acaf19a05..6c90708f2cd 100644
--- a/usr.bin/gcore/elfcore.c
+++ b/usr.bin/gcore/elfcore.c
@@ -158,7 +158,7 @@ elf_coredump(int efd __unused, int fd, pid_t pid)
 				err(1, "read from %s", memname);
 			if ((size_t)ngot < nwant)
 				errx(1, "short read from %s:"
-				    " wanted %zd, got %zd", memname,
+				    " wanted %zu, got %zd", memname,
 				    nwant, ngot);
 			ngot = write(fd, buf, nwant);
 			if (ngot == -1)
@@ -414,7 +414,7 @@ readhdrinfo(pid_t pid, prstatus_t *status, prfpregset_t *fpregset,
 	if ((n = read(fd, &status->pr_reg, sizeof status->pr_reg)) == -1)
 		err(1, "read error from %s", name);
 	if ((size_t)n < sizeof(status->pr_reg))
-		errx(1, "short read from %s: wanted %zd, got %d", name,
+		errx(1, "short read from %s: wanted %zu, got %d", name,
 		    sizeof status->pr_reg, n);
 	close(fd);
 
@@ -425,7 +425,7 @@ readhdrinfo(pid_t pid, prstatus_t *status, prfpregset_t *fpregset,
 	if ((n = read(fd, fpregset, sizeof *fpregset)) == -1)
 		err(1, "read error from %s", name);
 	if ((size_t)n < sizeof(*fpregset))
-		errx(1, "short read from %s: wanted %zd, got %d", name,
+		errx(1, "short read from %s: wanted %zu, got %d", name,
 		    sizeof *fpregset, n);
 	close(fd);
 

From c199dd3eaba5fbd3ff81a26f398d84d46b6f17c7 Mon Sep 17 00:00:00 2001
From: Alexander Leidinger 
Date: Thu, 5 Nov 2009 08:31:42 +0000
Subject: [PATCH 0497/2592] MFC r196511:   - Update config to doxygen 1.5.2 (I
 use this with 1.5.9).   - Add linprocfs and linsysfs to the linuxulator dox. 
  - Take the generated includes from the .m files from a subdirectory    
 instead of putting everything into $(.OBJDIR). This imporves the     human
 readbility of the source directory contents a lot, if you do not     create a
 separate OBJDIR.   - Assume UTF-8 encoding for every input file.   - Strip
 the source and dest path from the output, we are not interested     in the
 absolute location on the machine where the docs are created,     relative the
 the root of the FreeBSD source is what interests us.   - Exclude .svn
 directories.   - Switch to alphabetic index.   - Use one line per
 INCLUDE_PATH member in the common dox-config.   - Bump the __FreeBSD__
 version to 9. [here in the MFC: to 8]   - Switch from hardcoded .m files to
 an run-time generated one. Takes     a little bit more time to get started
 with actual work, but at least     is more future-proof. If you generate dox
 for all subsystems, the     time to find all .m files in the source is
 magnitutes lower than     producing the docs.   - Make the *DEST_PATH
 overidable from the environment. This allows to     produce the output
 directly in the docroot of a webserver.   - Fix the path when telling the
 user where he can find the API docs.

---
 tools/kerneldoc/subsys/Dependencies        | 16 ++---
 tools/kerneldoc/subsys/Doxyfile-cam        |  2 +-
 tools/kerneldoc/subsys/Doxyfile-crypto     |  2 +-
 tools/kerneldoc/subsys/Doxyfile-dev_pci    |  2 +-
 tools/kerneldoc/subsys/Doxyfile-dev_sound  |  2 +-
 tools/kerneldoc/subsys/Doxyfile-dev_usb    |  2 +-
 tools/kerneldoc/subsys/Doxyfile-geom       |  2 +-
 tools/kerneldoc/subsys/Doxyfile-kern       |  2 +-
 tools/kerneldoc/subsys/Doxyfile-libkern    |  2 +-
 tools/kerneldoc/subsys/Doxyfile-linux      |  4 +-
 tools/kerneldoc/subsys/Doxyfile-net80211   |  2 +-
 tools/kerneldoc/subsys/Doxyfile-netgraph   |  2 +-
 tools/kerneldoc/subsys/Doxyfile-netinet    |  2 +-
 tools/kerneldoc/subsys/Doxyfile-netinet6   |  2 +-
 tools/kerneldoc/subsys/Doxyfile-netipsec   |  2 +-
 tools/kerneldoc/subsys/Doxyfile-opencrypto |  2 +-
 tools/kerneldoc/subsys/Doxyfile-vm         |  2 +-
 tools/kerneldoc/subsys/Makefile            | 68 +++++-----------------
 tools/kerneldoc/subsys/common-Doxyfile     | 38 +++++++-----
 19 files changed, 63 insertions(+), 93 deletions(-)

diff --git a/tools/kerneldoc/subsys/Dependencies b/tools/kerneldoc/subsys/Dependencies
index 6307b485b48..537bdbaa179 100644
--- a/tools/kerneldoc/subsys/Dependencies
+++ b/tools/kerneldoc/subsys/Dependencies
@@ -6,15 +6,15 @@
 
 $(.OBJDIR)/dev_sound/dev_sound.tag:	$(.OBJDIR)/dev_pci/dev_pci.tag \
 					$(.OBJDIR)/dev_usb/dev_usb.tag \
-					$(.OBJDIR)/ac97_if.h \
-					$(.OBJDIR)/channel_if.h \
-					$(.OBJDIR)/feeder_if.h \
-					$(.OBJDIR)/mixer_if.h
+					$(.OBJDIR)/include/ac97_if.h \
+					$(.OBJDIR)/include/channel_if.h \
+					$(.OBJDIR)/include/feeder_if.h \
+					$(.OBJDIR)/include/mixer_if.h
 
 $(.OBJDIR)/dev_usb/dev_usb.tag:	$(.OBJDIR)/dev_pci/dev_pci.tag \
-				$(.OBJDIR)/usb_if.h
+				$(.OBJDIR)/include/usb_if.h
 
-$(.OBJDIR)/dev_pci/dev_pci.tag:	$(.OBJDIR)/pci_if.h \
-				$(.OBJDIR)/pcib_if.h \
-				$(.OBJDIR)/bus_if.h
+$(.OBJDIR)/dev_pci/dev_pci.tag:	$(.OBJDIR)/include/pci_if.h \
+				$(.OBJDIR)/include/pcib_if.h \
+				$(.OBJDIR)/include/bus_if.h
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-cam b/tools/kerneldoc/subsys/Doxyfile-cam
index 006cdcb12dd..7646cc06d14 100644
--- a/tools/kerneldoc/subsys/Doxyfile-cam
+++ b/tools/kerneldoc/subsys/Doxyfile-cam
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-crypto b/tools/kerneldoc/subsys/Doxyfile-crypto
index f3e6c5a7c08..404993d5171 100644
--- a/tools/kerneldoc/subsys/Doxyfile-crypto
+++ b/tools/kerneldoc/subsys/Doxyfile-crypto
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-dev_pci b/tools/kerneldoc/subsys/Doxyfile-dev_pci
index d8d91a7ca9c..6b6f96460cc 100644
--- a/tools/kerneldoc/subsys/Doxyfile-dev_pci
+++ b/tools/kerneldoc/subsys/Doxyfile-dev_pci
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-dev_sound b/tools/kerneldoc/subsys/Doxyfile-dev_sound
index 5a55398759e..724b6f9396f 100644
--- a/tools/kerneldoc/subsys/Doxyfile-dev_sound
+++ b/tools/kerneldoc/subsys/Doxyfile-dev_sound
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-dev_usb b/tools/kerneldoc/subsys/Doxyfile-dev_usb
index 731a018d82e..ad84bb5fa27 100644
--- a/tools/kerneldoc/subsys/Doxyfile-dev_usb
+++ b/tools/kerneldoc/subsys/Doxyfile-dev_usb
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-geom b/tools/kerneldoc/subsys/Doxyfile-geom
index 374665f3f6e..d7e4041f13c 100644
--- a/tools/kerneldoc/subsys/Doxyfile-geom
+++ b/tools/kerneldoc/subsys/Doxyfile-geom
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-kern b/tools/kerneldoc/subsys/Doxyfile-kern
index 5857465d76a..87f3c5a4e27 100644
--- a/tools/kerneldoc/subsys/Doxyfile-kern
+++ b/tools/kerneldoc/subsys/Doxyfile-kern
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-libkern b/tools/kerneldoc/subsys/Doxyfile-libkern
index 42c53de0d9d..f0f38d6caa9 100644
--- a/tools/kerneldoc/subsys/Doxyfile-libkern
+++ b/tools/kerneldoc/subsys/Doxyfile-libkern
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-linux b/tools/kerneldoc/subsys/Doxyfile-linux
index 3f210479444..a239d55496a 100644
--- a/tools/kerneldoc/subsys/Doxyfile-linux
+++ b/tools/kerneldoc/subsys/Doxyfile-linux
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
@@ -12,6 +12,8 @@ EXTRACT_ALL            = YES    # for undocumented src, no warnings enabled
 # configuration options related to the input files
 #---------------------------------------------------------------------------
 INPUT                  = $(DOXYGEN_SRC_PATH)/compat/linux \
+			 $(DOXYGEN_SRC_PATH)/compat/linprocfs \
+			 $(DOXYGEN_SRC_PATH)/compat/linsysfs \
                          $(DOXYGEN_LINUX_PATH) $(NOTREVIEWED)
 
 GENERATE_TAGFILE       = linux/linux.tag
diff --git a/tools/kerneldoc/subsys/Doxyfile-net80211 b/tools/kerneldoc/subsys/Doxyfile-net80211
index 869f06b4af7..7e622cf937d 100644
--- a/tools/kerneldoc/subsys/Doxyfile-net80211
+++ b/tools/kerneldoc/subsys/Doxyfile-net80211
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-netgraph b/tools/kerneldoc/subsys/Doxyfile-netgraph
index 5641cb08bf9..585725edfb6 100644
--- a/tools/kerneldoc/subsys/Doxyfile-netgraph
+++ b/tools/kerneldoc/subsys/Doxyfile-netgraph
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-netinet b/tools/kerneldoc/subsys/Doxyfile-netinet
index 7fedb3db11b..c9ed7e0df09 100644
--- a/tools/kerneldoc/subsys/Doxyfile-netinet
+++ b/tools/kerneldoc/subsys/Doxyfile-netinet
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-netinet6 b/tools/kerneldoc/subsys/Doxyfile-netinet6
index 2f902d3a00c..0c9e5d2bf0c 100644
--- a/tools/kerneldoc/subsys/Doxyfile-netinet6
+++ b/tools/kerneldoc/subsys/Doxyfile-netinet6
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-netipsec b/tools/kerneldoc/subsys/Doxyfile-netipsec
index b7038f2440c..75f4685e0a6 100644
--- a/tools/kerneldoc/subsys/Doxyfile-netipsec
+++ b/tools/kerneldoc/subsys/Doxyfile-netipsec
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-opencrypto b/tools/kerneldoc/subsys/Doxyfile-opencrypto
index 33f1654d9d8..d27501b5bf0 100644
--- a/tools/kerneldoc/subsys/Doxyfile-opencrypto
+++ b/tools/kerneldoc/subsys/Doxyfile-opencrypto
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Doxyfile-vm b/tools/kerneldoc/subsys/Doxyfile-vm
index 22bb8c56cc9..daa4224db36 100644
--- a/tools/kerneldoc/subsys/Doxyfile-vm
+++ b/tools/kerneldoc/subsys/Doxyfile-vm
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
diff --git a/tools/kerneldoc/subsys/Makefile b/tools/kerneldoc/subsys/Makefile
index f0e2613132c..0153d58a335 100644
--- a/tools/kerneldoc/subsys/Makefile
+++ b/tools/kerneldoc/subsys/Makefile
@@ -10,49 +10,7 @@ TARGET_ARCH?=	${MACHINE_ARCH}
 S?=/usr/src/sys
 LOCALBASE?=/usr/local
 
-MFILES+=dev/acpica/acpi_if.m
-MFILES+=dev/ata/ata_if.m
-MFILES+=dev/eisa/eisa_if.m
-MFILES+=dev/iicbus/iicbb_if.m
-MFILES+=dev/iicbus/iicbus_if.m
-MFILES+=dev/mii/miibus_if.m
-MFILES+=dev/mmc/mmcbr_if.m
-MFILES+=dev/mmc/mmcbus_if.m
-MFILES+=dev/ofw/ofw_bus_if.m
-MFILES+=dev/pccard/card_if.m
-MFILES+=dev/pccard/power_if.m
-MFILES+=dev/pci/pci_if.m
-MFILES+=dev/pci/pcib_if.m
-MFILES+=dev/ppbus/ppbus_if.m
-MFILES+=dev/scc/scc_if.m
-MFILES+=dev/smbus/smbus_if.m
-MFILES+=dev/sound/midi/mpu_if.m
-MFILES+=dev/sound/midi/mpufoi_if.m
-MFILES+=dev/sound/midi/synth_if.m
-MFILES+=dev/sound/pcm/ac97_if.m
-MFILES+=dev/sound/pcm/channel_if.m
-MFILES+=dev/sound/pcm/feeder_if.m
-MFILES+=dev/sound/pcm/mixer_if.m
-MFILES+=dev/spibus/spibus_if.m
-MFILES+=dev/uart/uart_if.m
-MFILES+=dev/usb/usb_if.m
-MFILES+=geom/part/g_part_if.m
-MFILES+=isa/isa_if.m
-MFILES+=kern/bus_if.m
-MFILES+=kern/clock_if.m
-MFILES+=kern/cpufreq_if.m
-MFILES+=kern/device_if.m
-MFILES+=kern/linker_if.m
-MFILES+=kern/serdev_if.m
-MFILES+=libkern/iconv_converter_if.m
-MFILES+=opencrypto/cryptodev_if.m
-MFILES+=pc98/pc98/canbus_if.m
-MFILES+=pci/agp_if.m
-MFILES+=powerpc/powerpc/mmu_if.m
-MFILES+=powerpc/powerpc/pic_if.m
-MFILES+=sparc64/pci/ofw_pci_if.m
-MFILES+=sun4v/mdesc/mdesc_bus_if.m
-
+MFILES!= find ${S} -name \*.m | sed -e 's:${S}/::g'
 HFILES=	${MFILES:T:S/.m$/.h/}
 AWK?=	awk
 
@@ -73,16 +31,16 @@ usage:
 all:	${ALL}
 pdf-all:${PDF_ALL}
 
-mfiles: ${HFILES:S/^/${.OBJDIR}\//}
+mfiles: ${HFILES:S/^/${.OBJDIR}\/include\//}
 
-DOXYGEN_DEST_PATH=	${.OBJDIR}
-DOXYGEN_LATEX_DEST_PATH=${.OBJDIR}
-DOXYGEN_PDF_DEST_PATH=	${.OBJDIR}
+DOXYGEN_DEST_PATH?=	${.OBJDIR}
+DOXYGEN_LATEX_DEST_PATH?=${.OBJDIR}
+DOXYGEN_PDF_DEST_PATH?=	${.OBJDIR}
 
-.if exists{${S}/${TARGET_ARCH}/linux}
+.if exists(${S}/${TARGET_ARCH}/linux)
 DOXYGEN_LINUX_PATH=	${S}/${TARGET_ARCH}/linux
 .endif
-.if exists{${S}/${TARGET_ARCH}/linux32}
+.if exists(${S}/${TARGET_ARCH}/linux32)
 DOXYGEN_LINUX_PATH+=	${S}/${TARGET_ARCH}/linux32
 .endif
 
@@ -98,13 +56,13 @@ ${.OBJDIR}/${target}/${target}.tag:
 		env DOXYGEN_INCLUDE_PATH=${.CURDIR} \
 		    DOXYGEN_SRC_PATH=${S}  \
 		    DOXYGEN_DEST_PATH=${DOXYGEN_DEST_PATH} \
-		    DOXYGEN_SRC_INCLUDE_PATH="${S}/sys ${S}/../include ${S}/${TARGET_ARCH}/include" \
+		    DOXYGEN_SRC_INCLUDE_PATH="${S}/sys ${S}/../include ${S}/${TARGET_ARCH}/include ${.OBJDIR}/include" \
 		    DOXYGEN_TARGET_ARCH=${TARGET_ARCH} \
 		    DOXYGEN_LINUX_PATH=${DOXYGEN_LINUX_PATH} \
 		    NOTREVIEWED=${.CURDIR}/notreviewed.dox \
 		    PATH=${LOCALBASE}/bin:${PATH} \
 			doxygen ${.CURDIR}/Doxyfile-${target}
-	@echo "API docs for ${target} are now available in ${.OBJDIR}/${target}/." | /usr/bin/fmt
+	@echo "API docs for ${target} are now available in ${DOXYGEN_DEST_PATH}/${target}/." | /usr/bin/fmt
 
 pdf-${target}:	${.OBJDIR}/${target}/${target}.tag
 	@cd ${DOXYGEN_LATEX_DEST_PATH}/${target}/latex && ${MAKE} refman.pdf && cp refman.pdf ${DOXYGEN_PDF_DEST_PATH}/${target}.pdf
@@ -117,10 +75,12 @@ clean-${target}:
 	rm -rf ${DOXYGEN_DEST_PATH}/${target} ${.OBJDIR}/${target}
 .endfor
 
+CLEANDIRS+=	${.OBJDIR}/include
 .for file in ${MFILES}
-CLEANDIRS+=     ${.OBJDIR}/${file:T:S/.m$/.h/}
-${.OBJDIR}/${file:T:S/.m$/.h/}: ${S}/${file}
-	cd ${.OBJDIR}; ${AWK} -f $S/tools/makeobjops.awk ${S}/${file} -h
+CLEANFILES+=     ${.OBJDIR}/include/${file:T:S/.m$/.h/}
+${.OBJDIR}/include/${file:T:S/.m$/.h/}: ${S}/${file}
+	@mkdir -p ${.OBJDIR}/include
+	cd ${.OBJDIR}/include && ${AWK} -f $S/tools/makeobjops.awk ${S}/${file} -h
 .endfor
 
 #
diff --git a/tools/kerneldoc/subsys/common-Doxyfile b/tools/kerneldoc/subsys/common-Doxyfile
index 537241877b1..42a37b88d97 100644
--- a/tools/kerneldoc/subsys/common-Doxyfile
+++ b/tools/kerneldoc/subsys/common-Doxyfile
@@ -1,14 +1,14 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.5.2
 
 # $FreeBSD$
 
 #---------------------------------------------------------------------------
 # Project related configuration options
 #---------------------------------------------------------------------------
+DOXYFILE_ENCODING      = UTF-8
 PROJECT_NUMBER         = 
 CREATE_SUBDIRS         = YES
 OUTPUT_LANGUAGE        = English
-USE_WINDOWS_ENCODING   = NO
 BRIEF_MEMBER_DESC      = YES
 REPEAT_BRIEF           = YES
 ABBREVIATE_BRIEF       = "The $name class" \
@@ -25,18 +25,20 @@ ABBREVIATE_BRIEF       = "The $name class" \
 ALWAYS_DETAILED_SEC    = NO
 INLINE_INHERITED_MEMB  = NO
 FULL_PATH_NAMES        = YES
-STRIP_FROM_PATH        = 
+STRIP_FROM_PATH        = $(DOXYGEN_SRC_PATH) $(DOXYGEN_DEST_PATH)
 STRIP_FROM_INC_PATH    = 
 SHORT_NAMES            = NO
 JAVADOC_AUTOBRIEF      = NO
 MULTILINE_CPP_IS_BRIEF = NO
-DETAILS_AT_TOP         = NO
 INHERIT_DOCS           = YES
-DISTRIBUTE_GROUP_DOC   = NO
+SEPARATE_MEMBER_PAGES  = NO
 TAB_SIZE               = 8
 ALIASES                = 
 OPTIMIZE_OUTPUT_FOR_C  = YES
 OPTIMIZE_OUTPUT_JAVA   = NO
+BUILTIN_STL_SUPPORT    = NO
+CPP_CLI_SUPPORT        = NO
+DISTRIBUTE_GROUP_DOC   = NO
 SUBGROUPING            = YES
 #---------------------------------------------------------------------------
 # Build related configuration options
@@ -76,9 +78,11 @@ WARN_IF_DOC_ERROR      = YES
 WARN_NO_PARAMDOC       = NO
 WARN_FORMAT            = "$file:$line: $text"
 WARN_LOGFILE           = 
+
 #---------------------------------------------------------------------------
 # configuration options related to the input files
 #---------------------------------------------------------------------------
+INPUT_ENCODING         = UTF-8
 FILE_PATTERNS          = *.c \
                          *.cc \
                          *.cxx \
@@ -120,7 +124,8 @@ FILE_PATTERNS          = *.c \
 RECURSIVE              = YES
 EXCLUDE                = 
 EXCLUDE_SYMLINKS       = NO
-EXCLUDE_PATTERNS       = */.\#*
+EXCLUDE_PATTERNS       = */.\#* */.svn/*
+EXCLUDE_SYMBOLS        = 
 EXAMPLE_PATH           = 
 EXAMPLE_PATTERNS       = *
 EXAMPLE_RECURSIVE      = NO
@@ -136,11 +141,13 @@ INLINE_SOURCES         = NO
 STRIP_CODE_COMMENTS    = YES
 REFERENCED_BY_RELATION = YES
 REFERENCES_RELATION    = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS              = NO
 VERBATIM_HEADERS       = YES
 #---------------------------------------------------------------------------
 # configuration options related to the alphabetical class index
 #---------------------------------------------------------------------------
-ALPHABETICAL_INDEX     = NO
+ALPHABETICAL_INDEX     = YES
 COLS_IN_ALPHA_INDEX    = 5
 IGNORE_PREFIX          = 
 #---------------------------------------------------------------------------
@@ -220,12 +227,13 @@ ENABLE_PREPROCESSING   = YES
 MACRO_EXPANSION        = YES
 EXPAND_ONLY_PREDEF     = YES
 SEARCH_INCLUDES        = YES
-INCLUDE_PATH           = $(DOXYGEN_SRC_INCLUDE_PATH) .
+INCLUDE_PATH           = $(DOXYGEN_SRC_INCLUDE_PATH) \
+                         .
 INCLUDE_FILE_PATTERNS  = *.h
-PREDEFINED             = "_KERNEL" \
-			 "__FreeBSD__=7" \
-			 "__${TARGET_ARCH}__=1" \
-			 "__${TARGET_ARCH}=1"
+PREDEFINED             = _KERNEL \
+                         __FreeBSD__=8 \
+                         __${TARGET_ARCH}__=1 \
+                         __${TARGET_ARCH}=1
 EXPAND_AS_DEFINED      = 
 SKIP_FUNCTION_MACROS   = YES
 #---------------------------------------------------------------------------
@@ -238,6 +246,7 @@ PERL_PATH              = /usr/bin/perl
 # Configuration options related to the dot tool   
 #---------------------------------------------------------------------------
 CLASS_DIAGRAMS         = NO
+MSCGEN_PATH            = 
 HIDE_UNDOC_RELATIONS   = YES
 HAVE_DOT               = YES
 CLASS_GRAPH            = YES
@@ -248,14 +257,13 @@ TEMPLATE_RELATIONS     = NO
 INCLUDE_GRAPH          = YES
 INCLUDED_BY_GRAPH      = YES
 CALL_GRAPH             = YES
+CALLER_GRAPH           = YES
 GRAPHICAL_HIERARCHY    = YES
 DIRECTORY_GRAPH        = YES
 DOT_IMAGE_FORMAT       = png
 DOT_PATH               = 
 DOTFILE_DIRS           = 
-MAX_DOT_GRAPH_WIDTH    = 1024
-MAX_DOT_GRAPH_HEIGHT   = 1024
-MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_GRAPH_MAX_NODES    = 50
 DOT_TRANSPARENT        = NO
 DOT_MULTI_TARGETS      = YES
 GENERATE_LEGEND        = YES

From 66a48b9837bbd4252584de09871876455c25b414 Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Thu, 5 Nov 2009 13:54:35 +0000
Subject: [PATCH 0498/2592] MFC r198518:

  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 0404a0a6b3d..d9c01d1e9b2 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1215,6 +1215,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 699050d8d5939f3ca78980c9e87fd0b483cda771 Mon Sep 17 00:00:00 2001
From: Matt Jacob 
Date: Thu, 5 Nov 2009 18:25:26 +0000
Subject: [PATCH 0499/2592] 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. This is an MFC of r198822.

---
 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 12fbadae8a22b14235380f6dcf71e960cc8921ec Mon Sep 17 00:00:00 2001
From: Ed Maste 
Date: Thu, 5 Nov 2009 18:34:01 +0000
Subject: [PATCH 0500/2592] MFC r198525:

  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 aad4692dc87..8713cbbee7b 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 c4e480716d607e33ab384b1cf9514b183b57d614 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 6 Nov 2009 06:50:45 +0000
Subject: [PATCH 0501/2592] MFC: r198684

Add support for Adaptec 39320LPE adapters.
---
 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 64af6359308af5d5d21d665f7fcf7c6df0e24a1c Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 6 Nov 2009 08:08:47 +0000
Subject: [PATCH 0502/2592] MFC: r198543

Fix date (1) and SEE ALSO section.
---
 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 6451b27464419634da09e79faa79e967a5dfe801 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Fri, 6 Nov 2009 09:39:35 +0000
Subject: [PATCH 0503/2592] MFC r197789:

Fix ACL support 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 063e24616321bd469d9c16e0745ca5396e098b50 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Fri, 6 Nov 2009 10:15:15 +0000
Subject: [PATCH 0504/2592] MFC r198868, r198950: Opteron rev E family of
 processor expose a bug where acq memory barriers can be broken, resulting in
 random breakages. Printout a warning message if affecred family and model are
 found.

---
 sys/amd64/amd64/identcpu.c | 15 +++++++++++++++
 sys/i386/i386/identcpu.c   | 15 +++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index 2c1b804affd..19ddd96d907 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -607,6 +607,21 @@ 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");
 }
 
 static void
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index af0da5b28b9..cde12eb0ccd 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -1303,6 +1303,21 @@ 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");
 }
 
 static void

From 74c174b9a78a20aae762f6b87362cb7b613fc1ea Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 6 Nov 2009 10:45:37 +0000
Subject: [PATCH 0505/2592] MFC r197783: - 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 cdcdbef48e088722f4a75d823f1542b45e534bc8 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 6 Nov 2009 10:48:44 +0000
Subject: [PATCH 0506/2592] MFC r198407: 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 cf236d24db18f031dc879a24aa8cc8c791bc23b1 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 6 Nov 2009 10:56:43 +0000
Subject: [PATCH 0507/2592] MFC r198700: 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.

MFC r198718:
Allow newly added controllers to use full I/O sizes.
---
 sys/dev/ata/ata-pci.h              |  3 ++
 sys/dev/ata/chipsets/ata-adaptec.c |  2 +
 sys/dev/ata/chipsets/ata-marvell.c | 85 +++++++++++++++++++++---------
 3 files changed, 66 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..2e9b1a7eb3b 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,10 @@ 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;
+    else
+	ch->dma.max_iosize = (ATA_DMA_ENTRIES - 1) * PAGE_SIZE;
 }
 
 ATA_DECLARE_DRIVER(ata_marvell);

From dcf9f13772db52bb90f8cd163216ce6b89d75efc Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Fri, 6 Nov 2009 15:24:48 +0000
Subject: [PATCH 0508/2592] MFC r197070: Consolidate CPUID to CPU family/model
 macros for amd64 and i386 to reduce unnecessary #ifdef's for shared code
 between them.

This MFC should unbreak the kernel build breakage introduced by
r198977.

Reported by:	kib
Pointy hat to:	me
---
 sys/amd64/amd64/identcpu.c     | 14 +++++++-------
 sys/amd64/amd64/initcpu.c      |  4 ++--
 sys/amd64/amd64/msi.c          |  4 ++--
 sys/amd64/include/specialreg.h |  4 ++--
 sys/i386/cpufreq/hwpstate.c    | 10 ++--------
 sys/i386/i386/identcpu.c       | 18 +++++++++---------
 sys/i386/i386/msi.c            |  4 ++--
 sys/i386/i386/pmap.c           |  2 +-
 sys/i386/include/specialreg.h  |  4 ++--
 9 files changed, 29 insertions(+), 35 deletions(-)

diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index 19ddd96d907..420dd03cc76 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -371,21 +371,21 @@ printcpuinfo(void)
 			switch (cpu_vendor_id) {
 			case CPU_VENDOR_AMD:
 				if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
-				    AMD64_CPU_FAMILY(cpu_id) >= 0x10 ||
+				    CPUID_TO_FAMILY(cpu_id) >= 0x10 ||
 				    cpu_id == 0x60fb2)
 					tsc_is_invariant = 1;
 				break;
 			case CPU_VENDOR_INTEL:
 				if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
-				    (AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
-				    AMD64_CPU_MODEL(cpu_id) >= 0xe) ||
-				    (AMD64_CPU_FAMILY(cpu_id) == 0xf &&
-				    AMD64_CPU_MODEL(cpu_id) >= 0x3))
+				    (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+				    CPUID_TO_MODEL(cpu_id) >= 0xe) ||
+				    (CPUID_TO_FAMILY(cpu_id) == 0xf &&
+				    CPUID_TO_MODEL(cpu_id) >= 0x3))
 					tsc_is_invariant = 1;
 				break;
 			case CPU_VENDOR_CENTAUR:
-				if (AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
-				    AMD64_CPU_MODEL(cpu_id) >= 0xf &&
+				if (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+				    CPUID_TO_MODEL(cpu_id) >= 0xf &&
 				    (rdmsr(0x1203) & 0x100000000ULL) == 0)
 					tsc_is_invariant = 1;
 				break;
diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index 0037d66df76..7aaff821463 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -154,8 +154,8 @@ initializecpu(void)
 		pg_nx = PG_NX;
 	}
 	if (cpu_vendor_id == CPU_VENDOR_CENTAUR &&
-	    AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
-	    AMD64_CPU_MODEL(cpu_id) >= 0xf)
+	    CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+	    CPUID_TO_MODEL(cpu_id) >= 0xf)
 		init_via();
 
 	/*
diff --git a/sys/amd64/amd64/msi.c b/sys/amd64/amd64/msi.c
index 736b692e34e..91a8cbbd004 100644
--- a/sys/amd64/amd64/msi.c
+++ b/sys/amd64/amd64/msi.c
@@ -275,8 +275,8 @@ msi_init(void)
 	case CPU_VENDOR_AMD:
 		break;
 	case CPU_VENDOR_CENTAUR:
-		if (AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
-		    AMD64_CPU_MODEL(cpu_id) >= 0xf)
+		if (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+		    CPUID_TO_MODEL(cpu_id) >= 0xf)
 			break;
 		/* FALLTHROUGH */
 	default:
diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
index 88ff734ca11..d1f0c8924ad 100644
--- a/sys/amd64/include/specialreg.h
+++ b/sys/amd64/include/specialreg.h
@@ -168,10 +168,10 @@
 #define	CPUID_FAMILY		0x00000f00
 #define	CPUID_EXT_MODEL		0x000f0000
 #define	CPUID_EXT_FAMILY	0x0ff00000
-#define	AMD64_CPU_MODEL(id) \
+#define	CPUID_TO_MODEL(id) \
     ((((id) & CPUID_MODEL) >> 4) | \
     (((id) & CPUID_EXT_MODEL) >> 12))
-#define	AMD64_CPU_FAMILY(id) \
+#define	CPUID_TO_FAMILY(id) \
     ((((id) & CPUID_FAMILY) >> 8) + \
     (((id) & CPUID_EXT_FAMILY) >> 20))
 
diff --git a/sys/i386/cpufreq/hwpstate.c b/sys/i386/cpufreq/hwpstate.c
index f46080dec00..3790b768cf9 100644
--- a/sys/i386/cpufreq/hwpstate.c
+++ b/sys/i386/cpufreq/hwpstate.c
@@ -83,12 +83,6 @@ __FBSDID("$FreeBSD$");
 #define	AMD_10H_11H_CUR_DID(msr)		(((msr) >> 6) & 0x07)
 #define	AMD_10H_11H_CUR_FID(msr)		((msr) & 0x3F)
 
-#if defined(__amd64__)
-#define CPU_FAMILY(id)	AMD64_CPU_FAMILY(id)
-#elif defined(__i386__)
-#define CPU_FAMILY(id)	I386_CPU_FAMILY(id)
-#endif
-
 #define	HWPSTATE_DEBUG(dev, msg...)			\
 	do{						\
 		if(hwpstate_verbose)			\
@@ -302,7 +296,7 @@ hwpstate_identify(driver_t *driver, device_t parent)
 	if (device_find_child(parent, "hwpstate", -1) != NULL)
 		return;
 
-	if (cpu_vendor_id != CPU_VENDOR_AMD || CPU_FAMILY(cpu_id) < 0x10)
+	if (cpu_vendor_id != CPU_VENDOR_AMD || CPUID_TO_FAMILY(cpu_id) < 0x10)
 		return;
 
 	/*
@@ -405,7 +399,7 @@ hwpstate_get_info_from_msr(device_t dev)
 	uint64_t msr;
 	int family, i, fid, did;
 
-	family = CPU_FAMILY(cpu_id);
+	family = CPUID_TO_FAMILY(cpu_id);
 	sc = device_get_softc(dev);
 	/* Get pstate count */
 	msr = rdmsr(MSR_AMD_10H_11H_LIMIT);
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index cde12eb0ccd..b0bcd094a5a 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -858,21 +858,21 @@ printcpuinfo(void)
 			switch (cpu_vendor_id) {
 			case CPU_VENDOR_AMD:
 				if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
-				    I386_CPU_FAMILY(cpu_id) >= 0x10 ||
+				    CPUID_TO_FAMILY(cpu_id) >= 0x10 ||
 				    cpu_id == 0x60fb2)
 					tsc_is_invariant = 1;
 				break;
 			case CPU_VENDOR_INTEL:
 				if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
-				    (I386_CPU_FAMILY(cpu_id) == 0x6 &&
-				    I386_CPU_MODEL(cpu_id) >= 0xe) ||
-				    (I386_CPU_FAMILY(cpu_id) == 0xf &&
-				    I386_CPU_MODEL(cpu_id) >= 0x3))
+				    (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+				    CPUID_TO_MODEL(cpu_id) >= 0xe) ||
+				    (CPUID_TO_FAMILY(cpu_id) == 0xf &&
+				    CPUID_TO_MODEL(cpu_id) >= 0x3))
 					tsc_is_invariant = 1;
 				break;
 			case CPU_VENDOR_CENTAUR:
-				if (I386_CPU_FAMILY(cpu_id) == 0x6 &&
-				    I386_CPU_MODEL(cpu_id) >= 0xf &&
+				if (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+				    CPUID_TO_MODEL(cpu_id) >= 0xf &&
 				    (rdmsr(0x1203) & 0x100000000ULL) == 0)
 					tsc_is_invariant = 1;
 				break;
@@ -1106,8 +1106,8 @@ finishidentcpu(void)
 	 * XXX This is only done on the BSP package.
 	 */
 	if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_high > 0 && cpu_high < 4 &&
-	    ((I386_CPU_FAMILY(cpu_id) == 0xf && I386_CPU_MODEL(cpu_id) >= 0x3) ||
-	    (I386_CPU_FAMILY(cpu_id) == 0x6 && I386_CPU_MODEL(cpu_id) >= 0xe))) {
+	    ((CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x3) ||
+	    (CPUID_TO_FAMILY(cpu_id) == 0x6 && CPUID_TO_MODEL(cpu_id) >= 0xe))) {
 		uint64_t msr;
 		msr = rdmsr(MSR_IA32_MISC_ENABLE);
 		if ((msr & 0x400000ULL) != 0) {
diff --git a/sys/i386/i386/msi.c b/sys/i386/i386/msi.c
index 6a0a0c991f7..91a8cbbd004 100644
--- a/sys/i386/i386/msi.c
+++ b/sys/i386/i386/msi.c
@@ -275,8 +275,8 @@ msi_init(void)
 	case CPU_VENDOR_AMD:
 		break;
 	case CPU_VENDOR_CENTAUR:
-		if (I386_CPU_FAMILY(cpu_id) == 0x6 &&
-		    I386_CPU_MODEL(cpu_id) >= 0xf)
+		if (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+		    CPUID_TO_MODEL(cpu_id) >= 0xf)
 			break;
 		/* FALLTHROUGH */
 	default:
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 0deebc800a8..f37e45cb776 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -484,7 +484,7 @@ pmap_init_pat(void)
 		return;
 
 	if (cpu_vendor_id != CPU_VENDOR_INTEL ||
-	    (I386_CPU_FAMILY(cpu_id) == 6 && I386_CPU_MODEL(cpu_id) >= 0xe)) {
+	    (CPUID_TO_FAMILY(cpu_id) == 6 && CPUID_TO_MODEL(cpu_id) >= 0xe)) {
 		/*
 		 * Leave the indices 0-3 at the default of WB, WT, UC, and UC-.
 		 * Program 4 and 5 as WP and WC.
diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h
index aeda4c41980..c2030597a06 100644
--- a/sys/i386/include/specialreg.h
+++ b/sys/i386/include/specialreg.h
@@ -165,11 +165,11 @@
 #define	CPUID_FAMILY		0x00000f00
 #define	CPUID_EXT_MODEL		0x000f0000
 #define	CPUID_EXT_FAMILY	0x0ff00000
-#define	I386_CPU_MODEL(id) \
+#define	CPUID_TO_MODEL(id) \
     ((((id) & CPUID_MODEL) >> 4) | \
     ((((id) & CPUID_FAMILY) >= 0x600) ? \
     (((id) & CPUID_EXT_MODEL) >> 12) : 0))
-#define	I386_CPU_FAMILY(id) \
+#define	CPUID_TO_FAMILY(id) \
     ((((id) & CPUID_FAMILY) >> 8) + \
     ((((id) & CPUID_FAMILY) == 0xf00) ? \
     (((id) & CPUID_EXT_FAMILY) >> 20) : 0))

From f6b15c7b77289f2fa0201f76b92fa3cf55df5ca4 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 6 Nov 2009 20:23:16 +0000
Subject: [PATCH 0509/2592] MFC 198367: 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.

---
 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 3f51c5cada8..221e622f3b4 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);
@@ -4117,27 +4126,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 8da42c8a89590e5fac7c8a5b2e8a675649cf4c75 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Fri, 6 Nov 2009 20:33:40 +0000
Subject: [PATCH 0510/2592] MFC 198620: When fetching sum stats (vmstat -s)
 from a crash dump, fetch per-CPU counts and sum them to form the total
 counts.

---
 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 14496b2fd56f5acc8332d38b37a7804a69b5f59f Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Sat, 7 Nov 2009 21:10:48 +0000
Subject: [PATCH 0511/2592] MFC r197797: s/Putluck Pogo/Potluck Pogo/

MFC r198921:
Grammar/formatting fix

MFC 199021:
Remove svn:executable from datfiles/gerrold.limerick
---
 games/fortune/datfiles/fortunes         | 5 +++--
 games/fortune/datfiles/fortunes.sp.ok   | 2 +-
 games/fortune/datfiles/gerrold.limerick | 0
 3 files changed, 4 insertions(+), 3 deletions(-)
 mode change 100755 => 100644 games/fortune/datfiles/gerrold.limerick

diff --git a/games/fortune/datfiles/fortunes b/games/fortune/datfiles/fortunes
index de09c960db7..d9ee0147d42 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.
@@ -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
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
diff --git a/games/fortune/datfiles/gerrold.limerick b/games/fortune/datfiles/gerrold.limerick
old mode 100755
new mode 100644

From 8bec9b9ee19b19c1af6fa0daf3ab85c97de14dda Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Sat, 7 Nov 2009 22:27:34 +0000
Subject: [PATCH 0512/2592] MFC r199023: Move VCS fortune to fortunes-o

MFC 199025:
Sort fortune
---
 games/fortune/datfiles/fortunes        | 58 ++++++++++++--------------
 games/fortune/datfiles/fortunes-o.real |  6 +++
 2 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/games/fortune/datfiles/fortunes b/games/fortune/datfiles/fortunes
index d9ee0147d42..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
@@ -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
@@ -33071,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!
@@ -59770,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
 %
@@ -59810,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
-%
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 715542d57f686ee012bb37e42b447d729f22779d Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Sat, 7 Nov 2009 22:59:04 +0000
Subject: [PATCH 0513/2592] MFC r198162:

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 c6f241253c9..acbf6273734 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -588,7 +588,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 92eb005cae216c04482141abf10c34ecb2c2cff6 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sun, 8 Nov 2009 12:08:42 +0000
Subject: [PATCH 0514/2592] MFC: r198750

Expand DESCRIPTION and add a basic EXAMPLES section.
---
 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 7d767be8c7d127161268dfc9351816d1832d0148 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sun, 8 Nov 2009 14:06:15 +0000
Subject: [PATCH 0515/2592] MFC r198818: 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 7d61312277c0c23416cb97a96aa66ef06665a7ce Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sun, 8 Nov 2009 14:07:58 +0000
Subject: [PATCH 0516/2592] MFC r198983: 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 79144413acea499a83ea9caad957809050f3b1ca Mon Sep 17 00:00:00 2001
From: Rong-En Fan 
Date: Sun, 8 Nov 2009 14:28:23 +0000
Subject: [PATCH 0517/2592] MFC r198948 from HEAD:

 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 2e952b348d6..2d403988c49 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 6ab1fc9fb10d9622a054972ef642738760b4c385 Mon Sep 17 00:00:00 2001
From: Ulf Lilleengen 
Date: Sun, 8 Nov 2009 17:59:55 +0000
Subject: [PATCH 0518/2592] MFC r198475:

- Add support for Marvell Yukon 88E8042 device.

Submitted by:   Mario Lobo 
---
 sys/dev/msk/if_msk.c    | 2 ++
 sys/dev/msk/if_mskreg.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index f5f94baad32..d961f0b924d 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 d345b60b944..69d2527a277 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 c366b7c1e2366fa41ff3e648cb428e76144f278f Mon Sep 17 00:00:00 2001
From: Oleg Bulyzhin 
Date: Mon, 9 Nov 2009 10:13:24 +0000
Subject: [PATCH 0519/2592] MFC r198845: 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 r199073:
style(9): add missing parentheses
---
 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..e961a55e817 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 cbd57efc02ccfef132f199f6893bc74602c58cf3 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Mon, 9 Nov 2009 11:32:18 +0000
Subject: [PATCH 0520/2592] MFC of 198831, tzcode2009q

- Cleanup unnecessary local variables in zdump.
- Fix man-page
---
 usr.sbin/zic/zdump.c | 10 +++++-----
 usr.sbin/zic/zic.8   |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/usr.sbin/zic/zdump.c b/usr.sbin/zic/zdump.c
index 263a5926320..0f61125c7d6 100644
--- a/usr.sbin/zic/zdump.c
+++ b/usr.sbin/zic/zdump.c
@@ -6,7 +6,7 @@
 #ifndef lint
 static const char rcsid[] =
   "$FreeBSD$";
-static char	elsieid[] = "@(#)zdump.c	8.9";
+static char	elsieid[] = "@(#)zdump.c	8.10";
 #endif /* not lint */
 
 /*
@@ -152,7 +152,7 @@ static size_t	longest;
 static char *	progname;
 static int	warned;
 
-static void	usage(const char *progname, FILE *stream, int status);
+static void	usage(FILE *stream, int status);
 static char *	abbr(struct tm * tmp);
 static void	abbrok(const char * abbrp, const char * zone);
 static long	delta(struct tm * newp, struct tm * oldp);
@@ -273,7 +273,7 @@ char *	argv[];
 		if (strcmp(argv[i], "--version") == 0) {
 			errx(EXIT_SUCCESS, "%s", elsieid);
 		} else if (strcmp(argv[i], "--help") == 0) {
-			usage(progname, stdout, EXIT_SUCCESS);
+			usage(stdout, EXIT_SUCCESS);
 		}
 	vflag = 0;
 	cutarg = NULL;
@@ -283,7 +283,7 @@ char *	argv[];
 		else	cutarg = optarg;
 	if ((c != -1) ||
 		(optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
-			usage(progname, stderr, EXIT_FAILURE);
+			usage(stderr, EXIT_FAILURE);
 	}
 	if (vflag) {
 		if (cutarg != NULL) {
@@ -468,7 +468,7 @@ const long	y;
 }
 
 static void
-usage(const char *progname, FILE *stream, int status)
+usage(FILE *stream, int status)
 {
 	fprintf(stream,
 _("usage: %s [--version] [-v] [--help] [-c [loyear,]hiyear] zonename ...\n\
diff --git a/usr.sbin/zic/zic.8 b/usr.sbin/zic/zic.8
index 082ff259908..f7ff815b080 100644
--- a/usr.sbin/zic/zic.8
+++ b/usr.sbin/zic/zic.8
@@ -260,7 +260,7 @@ the variable part is null.
 .El
 .Pp
 A zone line has the form:
-.Dl "Zone	NAME	GMTOFF	RULES/SAVE	FORMAT	[UNTILYEAR [MONTH [DAY [TIME]]]]
+.Dl "Zone	NAME	GMTOFF	RULES/SAVE	FORMAT	[UNTILYEAR [MONTH [DAY [TIME]]]]"
 For example:
 .Dl "Zone	Australia/Adelaide	9:30	Aus	CST	1971 Oct 31 2:00
 The fields that make up a zone line are:

From c303f1eb39e23c0459bd9cf38b0d2f41dd872afd Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Mon, 9 Nov 2009 15:11:37 +0000
Subject: [PATCH 0521/2592] MFC r198976, r198993:  - Don't call LLE_FREE()
 after nd6_free().  - Make nd6_llinfo_timer() does its job, again. 
 ln->la_expire was    greater than time_second, in most cases.

---
 sys/netinet6/nd6.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index acaa87e63a3..29eeb440e00 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -502,12 +502,13 @@ 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;
 	}
 
 	if (ln->la_flags & LLE_DELETED) {
 		(void)nd6_free(ln, 0);
+		ln = NULL;
 		goto done;
 	}
 

From 973e10a816b4f13c8d7b129bb4d49f8f66e74093 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Mon, 9 Nov 2009 18:09:10 +0000
Subject: [PATCH 0523/2592] MFC r198719: > 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.

Requested by:	Stefan Esser (se at freebsd dot org)[1]
Reviewed by:	jhb, scottl

[1] Stefan requested this be part of 8.0 but has been unavailable to do
    the MFC since submitting the request.  We want to get 8.0-RC3 started
    so I'm doing the merges with re@ hat on.
---
 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 006a483528f61e92c43d56dda5d198c25d1ce463 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Mon, 9 Nov 2009 21:30:45 +0000
Subject: [PATCH 0525/2592] Insta-MFC of r199084,199108:    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.

Short MFC requested by re since the problem this fixes breaks CD boot on
most G5 systems, making them uninstallable.

Reported by:	Jacob Lambert
Approved by:	re (kensmith,kib)
Requested by:	re
---
 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 4dad3dc7561..b8147cb06e7 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -270,7 +270,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;
 
@@ -896,6 +896,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 (sz > 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 50aa9510617880ab2e7d302f289ee8b711f89c58 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Mon, 9 Nov 2009 21:39:42 +0000
Subject: [PATCH 0526/2592] Comment out the sbp(4) entry for GENERIC config
 files that contain it. There are known issues with this driver that are
 beyond what can be fixed for 8.0-RELEASE and the bugs can cause boot failure
 on some systems. It's not clear if it impacts all systems and there is
 interest in getting the problem fixed so for now just comment it out instead
 of remove it.

Commit straight to stable/8, this is an 8.0-RELEASE issue.  Head was left
alone so work on it can continue there.

Reviewed by:	Primary misc. architecture maintainers (marcel, marius)
---
 sys/amd64/conf/GENERIC   | 2 +-
 sys/i386/conf/GENERIC    | 2 +-
 sys/ia64/conf/GENERIC    | 2 +-
 sys/powerpc/conf/GENERIC | 2 +-
 sys/sparc64/conf/GENERIC | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 24300bd7ae5..d0f24e297c3 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -313,7 +313,7 @@ device		udav		# Davicom DM9601E USB
 
 # FireWire support
 device		firewire	# FireWire bus code
-device		sbp		# SCSI over FireWire (Requires scbus and da)
+#device		sbp		# SCSI over FireWire (Requires scbus and da)
 device		fwe		# Ethernet over FireWire (non-standard!)
 device		fwip		# IP over FireWire (RFC 2734,3146)
 device		dcons		# Dumb console driver
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index f3a14f2215a..1aa0da3b830 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -327,7 +327,7 @@ device		udav		# Davicom DM9601E USB
 
 # FireWire support
 device		firewire	# FireWire bus code
-device		sbp		# SCSI over FireWire (Requires scbus and da)
+#device		sbp		# SCSI over FireWire (Requires scbus and da)
 device		fwe		# Ethernet over FireWire (non-standard!)
 device		fwip		# IP over FireWire (RFC 2734,3146)
 device		dcons		# Dumb console driver
diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
index 10d51d52645..cec3cd6c891 100644
--- a/sys/ia64/conf/GENERIC
+++ b/sys/ia64/conf/GENERIC
@@ -139,7 +139,7 @@ device		cue		# CATC USB Ethernet
 device		kue		# Kawasaki LSI USB Ethernet
 
 # FireWire support
-device		sbp		# SCSI over FireWire (need scbus & da)
+#device		sbp		# SCSI over FireWire (need scbus & da)
 
 # Various (pseudo) devices
 device		ether		# Ethernet support
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index 1b941a2ac26..a7eca3f70a0 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -157,7 +157,7 @@ device		kue		# Kawasaki LSI USB Ethernet
 
 # FireWire support
 device		firewire	# FireWire bus code
-device		sbp		# SCSI over FireWire (Requires scbus and da)
+#device		sbp		# SCSI over FireWire (Requires scbus and da)
 device		fwe		# Ethernet over FireWire (non-standard!)
 
 # Misc
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index 99a0e24aa2c..75ec10c0a31 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -255,7 +255,7 @@ device		udav		# Davicom DM9601E USB
 
 # FireWire support
 device		firewire	# FireWire bus code
-device		sbp		# SCSI over FireWire (Requires scbus and da)
+#device		sbp		# SCSI over FireWire (Requires scbus and da)
 device		fwe		# Ethernet over FireWire (non-standard!)
 device		fwip		# IP over FireWire (RFC 2734,3146)
 device		dcons		# Dumb console driver

From ce5c80071fbfcb6c685cabe4ee69267f22f251ff Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Tue, 10 Nov 2009 00:34:25 +0000
Subject: [PATCH 0527/2592] MFC revision 199069:

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.

This instant MFC was requested by re@ (kensmith) in preparation for
8.0-RC3.

Reported by:	Jirka Mikulas 
Submitted by:	Erich Chen (Areca)
---
 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 01e195f21db92e40d8dd60896e876a0a70b19669 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Tue, 10 Nov 2009 00:41:22 +0000
Subject: [PATCH 0528/2592] MFC r198846:

  Set umask to 0x077 instead of the default.  This prevents non-root user
  from reading crashinfo output, which could contain some sensitive
  information.
---
 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 58ad43feb10d9c06e68659be993cdd5a01d2cdc3 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 10 Nov 2009 22:37:44 +0000
Subject: [PATCH 0529/2592] MFC r198486, r199050: Increase ATA command
 timeouts. Introduce define and kernel option ATA_REQUEST_TIMEOUT to control
 it.

PR:		kern/111023
---
 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 dde4cd1e8a8..61fca0b7db1 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1716,8 +1716,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 ac2d87c0195..ef22c695846 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 4bb45e48f64..73d4a6ed74f 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -336,6 +336,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 c699a05f52e..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 = 5;
+    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 = 5;
+	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 = 5;
+    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 = 5;
+    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 88568842246..baa3e64fa8e 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -133,9 +133,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 = 5;
+	    request->timeout = ATA_REQUEST_TIMEOUT;
 	}
 	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 = 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 fc6a23c0461..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 = 1;
+	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 = 5;
+    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 941c1018547..1c4b8b5b1ee 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 = ATA_REQUEST_TIMEOUT;
 	ata_queue_request(request);
 	if (!request->error &&
 	    (request->u.atapi.sense.key == 2 ||

From 1110a4604fd22ba8821fe5ef63296e7fbff4feb8 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Wed, 11 Nov 2009 01:27:58 +0000
Subject: [PATCH 0530/2592] MFC r199055

 - 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
---
 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 41de786582e158144e9163a8c1311eed05c66a8f Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Wed, 11 Nov 2009 01:33:06 +0000
Subject: [PATCH 0531/2592] MFC r199058

 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
---
 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 fc2035bd297..347a623924e 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -441,6 +441,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 896fb05783c623370dbc42ed44aaae144d2229c2 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Wed, 11 Nov 2009 02:07:01 +0000
Subject: [PATCH 0532/2592] MFC r198859

 Belatedly add an UPDATING message for the usb ethernet ifnet naming in r188412.
---
 UPDATING | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/UPDATING b/UPDATING
index d556c75095e..cba0fb95f37 100644
--- a/UPDATING
+++ b/UPDATING
@@ -471,6 +471,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
 		# 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 764732044935c06498f28ee82868c1ba9b397d51 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Wed, 11 Nov 2009 14:38:45 +0000
Subject: [PATCH 0533/2592] Shift what stable/8 calls itself to the thing that
 people who tend to complain about such things find, on average, the least
 objectionable.

---
 sys/conf/newvers.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 068bc7b342b..a9b666c0c61 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="8.0"
-BRANCH="RC2"
+BRANCH="PRERELEASE"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

From 1a225ffb6a69bd189d62e4dce4b3d1b1eb04e29a Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Wed, 11 Nov 2009 19:50:52 +0000
Subject: [PATCH 0534/2592] MFC r197833:

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)
---
 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 585be673c5892c468ad350b63c21e63f50dcfa8d Mon Sep 17 00:00:00 2001
From: Navdeep Parhar 
Date: Wed, 11 Nov 2009 22:31:02 +0000
Subject: [PATCH 0535/2592] MFC r197043

---
 sys/dev/cxgb/cxgb_sge.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c
index 544ed6c50be..7565347c040 100644
--- a/sys/dev/cxgb/cxgb_sge.c
+++ b/sys/dev/cxgb/cxgb_sge.c
@@ -1942,7 +1942,6 @@ again:	reclaim_completed_tx_imm(q);
 	if (__predict_false(ret)) {
 		if (ret == 1) {
 			TXQ_UNLOCK(qs);
-			log(LOG_ERR, "no desc available\n");
 			return (ENOSPC);
 		}
 		goto again;
@@ -1955,6 +1954,7 @@ again:	reclaim_completed_tx_imm(q);
 		q->gen ^= 1;
 	}
 	TXQ_UNLOCK(qs);
+	wmb();
 	t3_write_reg(adap, A_SG_KDOORBELL,
 		     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
 	return (0);
@@ -1975,8 +1975,6 @@ restart_ctrlq(void *data, int npending)
 	struct sge_txq *q = &qs->txq[TXQ_CTRL];
 	adapter_t *adap = qs->port->adapter;
 
-	log(LOG_WARNING, "Restart_ctrlq in_use=%d\n", q->in_use);
-	
 	TXQ_LOCK(qs);
 again:	reclaim_completed_tx_imm(q);
 
@@ -2928,9 +2926,9 @@ handle_rsp_cntrl_info(struct sge_qset *qs, uint32_t flags)
 	credits = G_RSPD_TXQ0_CR(flags);
 	if (credits) 
 		qs->txq[TXQ_ETH].processed += credits;
-	
+
 	credits = G_RSPD_TXQ2_CR(flags);
-	if (credits) 
+	if (credits)
 		qs->txq[TXQ_CTRL].processed += credits;
 
 # if USE_GTS
@@ -3133,12 +3131,9 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
 		check_ring_db(adap, qs, sleeping);
 
 	mb();  /* commit Tx queue processed updates */
-	if (__predict_false(qs->txq_stopped > 1)) {
-		printf("restarting tx on %p\n", qs);
-		
+	if (__predict_false(qs->txq_stopped > 1))
 		restart_tx(qs);
-	}
-	
+
 	__refill_fl_lt(adap, &qs->fl[0], 512);
 	__refill_fl_lt(adap, &qs->fl[1], 512);
 	budget -= budget_left;

From bbec3bb5812ad9a4464510d7120c640f7039d376 Mon Sep 17 00:00:00 2001
From: Navdeep Parhar 
Date: Thu, 12 Nov 2009 00:20:31 +0000
Subject: [PATCH 0536/2592] MFC r197791

cxgb(4) updates, including:
- support for the new Gen-2, BT, and LP-CR cards.
- T3 firmware 7.7.0
- shared "common code" updates.
---
 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 b448818ea7d..e1eeb865e09 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -772,6 +772,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 4ab8848ce9c16c80cd4fd51b1cacf0434fb99262 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Thu, 12 Nov 2009 10:44:29 +0000
Subject: [PATCH 0537/2592] MFC of r199107, 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).
---
 share/zoneinfo/antarctica | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/share/zoneinfo/antarctica b/share/zoneinfo/antarctica
index 8511ab207e5..52d604b4aed 100644
--- a/share/zoneinfo/antarctica
+++ b/share/zoneinfo/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 43b4fbd1128e9d3aa20ef5d88f97ee62701a377a Mon Sep 17 00:00:00 2001
From: Alexander Leidinger 
Date: Thu, 12 Nov 2009 13:09:36 +0000
Subject: [PATCH 0538/2592] MFC r198945:   Fix typo in kernel message. The fix
 is based upon the patch in the PR.

  PR:		kern/140279
  Submitted by:	Alexander Best 
---
 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 864fb934d08179a3cef1c5fab45aaf46574a30c3 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Sat, 14 Nov 2009 04:46:24 +0000
Subject: [PATCH 0539/2592] MFC r199173: CURVNET_RESTORE() was not called in
 certain cases.

---
 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 29eeb440e00..e9c15e1658a 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -577,10 +577,10 @@ nd6_llinfo_timer(void *arg)
 		}
 		break;
 	}
-	CURVNET_RESTORE();
 done:
 	if (ln != NULL)
 		LLE_FREE(ln);
+	CURVNET_RESTORE();
 }
 
 

From 5f99f8897523967aea4a686283be802e11036b69 Mon Sep 17 00:00:00 2001
From: Pawel Jakub Dawidek 
Date: Sat, 14 Nov 2009 11:59:59 +0000
Subject: [PATCH 0540/2592] MFC r198703,r199156,r199157:

r198703:

- 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

r199156:

Avoid passing invalid mountpoint to getnewvnode().

Reported by:	rwatson
Tested by:	rwatson

r199157:

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
---
 sys/cddl/compat/opensolaris/sys/vnode.h       |  2 +
 .../uts/common/fs/zfs/zfs_replay.c            | 12 ++++--
 .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 30 +++++++++-----
 .../opensolaris/uts/common/fs/zfs/zfs_znode.c | 39 +++++++++----------
 .../opensolaris/uts/common/sys/vnode.h        |  1 -
 5 files changed, 49 insertions(+), 35 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_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;
 }
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 a58f76e4b8d..564871f6929 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
@@ -3981,21 +3981,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/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);
 }
 
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 1de299257871e2508c3cf0865cb10080de0cdeb3 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Sat, 14 Nov 2009 16:14:51 +0000
Subject: [PATCH 0541/2592] MFC r199241

This patch addresses an overflow in the the zfs boot code and allows
users to boot from zfs raidz volumes.  This has been tested by a number
of users and does not impact those which are not booting from zfs raidz
volumes.

Submitted by:	Matt Reimer 
---
 sys/cddl/boot/zfs/zfssubr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/cddl/boot/zfs/zfssubr.c b/sys/cddl/boot/zfs/zfssubr.c
index fb4444f242e..4013986c18c 100644
--- a/sys/cddl/boot/zfs/zfssubr.c
+++ b/sys/cddl/boot/zfs/zfssubr.c
@@ -550,7 +550,8 @@ vdev_raidz_read(vdev_t *vdev, const blkptr_t *bp, void *buf,
 	uint64_t s = psize >> unit_shift;
 	uint64_t f = b % dcols;
 	uint64_t o = (b / dcols) << unit_shift;
-	int q, r, c, c1, bc, col, acols, coff, devidx, asize, n;
+	uint64_t q, r, coff;
+	int c, c1, bc, col, acols, devidx, asize, n;
 	static raidz_col_t cols[16];
 	raidz_col_t *rc, *rc1;
 

From 5b7c45037d6a776ea44e88fb986f3248c66b93b0 Mon Sep 17 00:00:00 2001
From: Stanislav Sedov 
Date: Sun, 15 Nov 2009 11:30:59 +0000
Subject: [PATCH 0542/2592] - MFC r198320:   Introduce new option
 BCE_JUMBO_HDRSPLIT that allows user to enable header   in bce(4) instead of
 (ab)using ZERO_COPY_SOCKETS that was not   into if_bce.c anyway.  It is
 disabled by default.

---
 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 61fca0b7db1..b74ac72722a 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2023,6 +2023,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 ef22c695846..f73ed162b2f 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 f969a7ac4b105b989d9edcef83cc28677e186a92 Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Sun, 15 Nov 2009 14:11:26 +0000
Subject: [PATCH 0543/2592] MFC r197956:

- 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.
- Remove attempt to clear stdio error indicators. getch() doesn't use
  stdio, making it useless.
- Remove unneeded masking of getch() return value.

PR:		bin/107171
Approved by:	trasz (mentor)
---
 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 43bd82988b32044dd32481917822a9ba5ec96128 Mon Sep 17 00:00:00 2001
From: Rick Macklem 
Date: Sun, 15 Nov 2009 19:26:06 +0000
Subject: [PATCH 0544/2592] MFC: r199053 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 fixes some
 cases of problems w.r.t. reconnecting to a NFS server that drops inactive TCP
 connections.

Tested by:	Olaf Seibert, Daniel Braniss
Reviewed by:	dfr
---
 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 c071b1c638a8485d7fa3cec565ee58c9f7754ac0 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Sun, 15 Nov 2009 23:48:29 +0000
Subject: [PATCH 0545/2592] MFC r199127: 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 

MFC r199152:
s/a default/the default/

Submitted by:	remko

MFC r199299:
In r199127/r199152 I forgot to bump .Dd
---
 share/man/man5/rc.conf.5 | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 5e7e8c8c712..c0c32d58ea3 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 17, 2009
+.Dd November 11, 2009
 .Dt RC.CONF 5
 .Os
 .Sh NAME
@@ -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 the default hostname of
+.Dq Amnesiac.
 .It Va ipv6_enable
 .Pq Vt bool
 Enable support for IPv6 networking.

From 26520868bc1b87bdb3f1eae96141de3c81caf6bc Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Mon, 16 Nov 2009 03:52:18 +0000
Subject: [PATCH 0546/2592] MFC r199080, r199081, r199082: Add ja_JP.UTF-8 and
 ja_JP.eucJP catalogs.

---
 lib/libc/nls/Makefile.inc    |   2 +
 lib/libc/nls/ja_JP.UTF-8.msg | 249 +++++++++++++++++++++++++++++++++++
 lib/libc/nls/ja_JP.eucJP.msg | 249 +++++++++++++++++++++++++++++++++++
 3 files changed, 500 insertions(+)
 create mode 100644 lib/libc/nls/ja_JP.UTF-8.msg
 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 9e19e854eba..8e46470fdd3 100644
--- a/lib/libc/nls/Makefile.inc
+++ b/lib/libc/nls/Makefile.inc
@@ -22,6 +22,8 @@ NLS+=	fi_FI.ISO8859-1
 NLS+=	fr_FR.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.UTF-8.msg b/lib/libc/nls/ja_JP.UTF-8.msg
new file mode 100644
index 00000000000..9ee98d17ae3
--- /dev/null
+++ b/lib/libc/nls/ja_JP.UTF-8.msg
@@ -0,0 +1,249 @@
+$ $FreeBSD$
+$
+$ Message catalog for ja_JP.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 デãƒã‚¤ã‚¹ãŒå¯¾å¿œã—ã¦ã„ãªã„ 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
diff --git a/lib/libc/nls/ja_JP.eucJP.msg b/lib/libc/nls/ja_JP.eucJP.msg
new file mode 100644
index 00000000000..cba0157cb1f
--- /dev/null
+++ b/lib/libc/nls/ja_JP.eucJP.msg
@@ -0,0 +1,249 @@
+$ $FreeBSD$
+$
+$ Message catalog for ja_JP.eucJP 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 ¥Ç¥Ð¥¤¥¹¤¬Âбþ¤·¤Æ¤¤¤Ê¤¤ 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 841de8ae65523bb26fb7c3e39b2401ac38aac9a8 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Mon, 16 Nov 2009 08:26:56 +0000
Subject: [PATCH 0547/2592] MFC: r199046

Fix a copy+paste error by checking the correct variable against MM_NULLACT.
---
 lib/libc/gen/fmtmsg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libc/gen/fmtmsg.c b/lib/libc/gen/fmtmsg.c
index 6caabbbb884..e6b1b960d64 100644
--- a/lib/libc/gen/fmtmsg.c
+++ b/lib/libc/gen/fmtmsg.c
@@ -128,7 +128,7 @@ printfmt(char *msgverb, long class, const char *label, int sev,
 		size += strlen(sevname);
 	if (text != MM_NULLTXT)
 		size += strlen(text);
-	if (text != MM_NULLACT)
+	if (act != MM_NULLACT)
 		size += strlen(act);
 	if (tag != MM_NULLTAG)
 		size += strlen(tag);

From 95d8c745013a719de504ff7fa9cfada04963315a Mon Sep 17 00:00:00 2001
From: Jack F Vogel 
Date: Mon, 16 Nov 2009 18:58:45 +0000
Subject: [PATCH 0548/2592] On a 32 bit kernel the igb driver may cause a page
 fault panic due to a failed bounce page allocation during RX mbuf setup. The
 large demand on bounce pages is due to the alignment requirement in the tag.
 This restriction was removed in the ixgbe driver with no ill effects and so
 is being removed here also.

---
 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 7a04f19803745163897189fa82d71392e321760a Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Tue, 17 Nov 2009 09:35:13 +0000
Subject: [PATCH 0549/2592] MFC r199015: ichwd: don't attach to isa pnp
 device(s) by accident

---
 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 71662a5d83e..a47eccd3d39 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 7ea239483a841801fcbf549122bd8bca76893cfe Mon Sep 17 00:00:00 2001
From: Bruce M Simpson 
Date: Tue, 17 Nov 2009 10:59:51 +0000
Subject: [PATCH 0550/2592] MFC r199287:   Fix a functional regression in
 multicast.

  Userland daemons need to see IGMP traffic regardless of the group;
  omit the imo filter check if the proto is IGMP. The kernel part
  of IGMP will have already filtered appropriately at this point.

Submitted by:   Franz Struwig
Reported by:    Ivor Prebeg, Franz Struwig
---
 sys/netinet/raw_ip.c | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index b40ceb28b79..60824d92697 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -343,17 +343,35 @@ rip_input(struct mbuf *m, int off)
 		 */
 		if (inp->inp_moptions != NULL &&
 		    IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
-			struct sockaddr_in group;
+			/*
+			 * If the incoming datagram is for IGMP, allow it
+			 * through unconditionally to the raw socket.
+			 *
+			 * In the case of IGMPv2, we may not have explicitly
+			 * joined the group, and may have set IFF_ALLMULTI
+			 * on the interface. imo_multi_filter() may discard
+			 * control traffic we actually need to see.
+			 *
+			 * Userland multicast routing daemons should continue
+			 * filter the control traffic appropriately.
+			 */
 			int blocked;
 
-			bzero(&group, sizeof(struct sockaddr_in));
-			group.sin_len = sizeof(struct sockaddr_in);
-			group.sin_family = AF_INET;
-			group.sin_addr = ip->ip_dst;
+			blocked = MCAST_PASS;
+			if (proto != IPPROTO_IGMP) {
+				struct sockaddr_in group;
+
+				bzero(&group, sizeof(struct sockaddr_in));
+				group.sin_len = sizeof(struct sockaddr_in);
+				group.sin_family = AF_INET;
+				group.sin_addr = ip->ip_dst;
+
+				blocked = imo_multi_filter(inp->inp_moptions,
+				    ifp,
+				    (struct sockaddr *)&group,
+				    (struct sockaddr *)&ripsrc);
+			}
 
-			blocked = imo_multi_filter(inp->inp_moptions, ifp,
-			    (struct sockaddr *)&group,
-			    (struct sockaddr *)&ripsrc);
 			if (blocked != MCAST_PASS) {
 				IPSTAT_INC(ips_notmember);
 				continue;

From c3568f6fbdcfe778a9b4fb6e379cca9fc94780d9 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 17 Nov 2009 11:43:53 +0000
Subject: [PATCH 0551/2592] MFC r198853: 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.
---
 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 a3bd58e501d..89e1dd0fc77 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -2036,20 +2036,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 5c3037910ac1b7926828e6805711f24c9efc08d6 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 17 Nov 2009 11:46:55 +0000
Subject: [PATCH 0552/2592] MFC r199137: Detect the slashdot lookup for RENAME
 or REMOVE in lookup(), and return EINVAL.

---
 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 ba0e41c3ccb4c019c11e1019a5a5bd924204793e Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 12:18:14 +0000
Subject: [PATCH 0553/2592] MFC r198519: Don't ignore the return value of
 g_modevent() in acd_modevent().

---
 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 1c4b8b5b1ee..a021e005492 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 3f2bdafd9701191cc5dff0474d05c7bd753fdc76 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 12:23:14 +0000
Subject: [PATCH 0554/2592] MFC r198582: 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.

---
 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 73d4a6ed74f..cd65ee1b469 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 dfa1c364b83d3335ed3e069eea125b105ae47610 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 12:25:34 +0000
Subject: [PATCH 0555/2592] MFC r198583: Add some magic taken from OS X and
 Linux to support early revision K2 SATA controllers, like those found on the
 G5 Xserve.

---
 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 b882e0398e8d16312b7b82bb725d3571a42d7155 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 12:30:06 +0000
Subject: [PATCH 0556/2592] MFC r199074:

Add more ICH10 chip IDs.
---
 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 c8ed0c05c0b..41e9171e5f1 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 cfd3d58f6f546ce1d427b5e1cc7d2e7524159dab Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 12:42:27 +0000
Subject: [PATCH 0557/2592] MFC r197540, r198587, r198865: Add more defines for
 bits from ATA and CF specifications.

---
 sys/sys/ata.h | 70 +++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 10 deletions(-)

diff --git a/sys/sys/ata.h b/sys/sys/ata.h
index f98d4881b63..91e3b534eff 100644
--- a/sys/sys/ata.h
+++ b/sys/sys/ata.h
@@ -67,6 +67,8 @@ struct ata_params {
 /*049*/ u_int16_t       capabilities1;
 #define ATA_SUPPORT_DMA                 0x0100
 #define ATA_SUPPORT_LBA                 0x0200
+#define ATA_SUPPORT_IORDY               0x0400
+#define ATA_SUPPORT_IORDYDIS            0x0800
 #define ATA_SUPPORT_OVERLAP             0x4000
 
 /*050*/ u_int16_t       capabilities2;
@@ -108,22 +110,31 @@ struct ata_params {
 /*075*/ u_int16_t       queue;
 #define ATA_QUEUE_LEN(x)                ((x) & 0x001f)
 
-	u_int16_t       satacapabilities;
+/*76*/  u_int16_t       satacapabilities;
 #define ATA_SATA_GEN1                   0x0002
 #define ATA_SATA_GEN2                   0x0004
+#define ATA_SATA_GEN3                   0x0008
 #define ATA_SUPPORT_NCQ                 0x0100
 #define ATA_SUPPORT_IFPWRMNGTRCV        0x0200
 #define ATA_SUPPORT_PHYEVENTCNT         0x0400
 #define ATA_SUPPORT_NCQ_UNLOAD          0x0800
 #define ATA_SUPPORT_NCQ_PRIO            0x1000
+#define ATA_SUPPORT_HAPST               0x2000
+#define ATA_SUPPORT_DAPST               0x4000
+#define ATA_SUPPORT_READLOGDMAEXT       0x8000
 
-	u_int16_t       reserved77;
-	u_int16_t       satasupport;
+/*77*/  u_int16_t       satacapabilities2;
+#define ATA_SATA_CURR_GEN_MASK          0x0006
+#define ATA_SUPPORT_NCQ_STREAM          0x0010
+#define ATA_SUPPORT_NCQ_QMANAGEMENT     0x0020
+/*78*/  u_int16_t       satasupport;
 #define ATA_SUPPORT_NONZERO             0x0002
 #define ATA_SUPPORT_AUTOACTIVATE        0x0004
 #define ATA_SUPPORT_IFPWRMNGT           0x0008
 #define ATA_SUPPORT_INORDERDATA         0x0010
-	u_int16_t       sataenabled;
+#define ATA_SUPPORT_SOFTSETPRESERVE     0x0040
+/*79*/  u_int16_t       sataenabled;
+#define ATA_ENABLED_DAPST               0x0080
 
 /*080*/ u_int16_t       version_major;
 /*081*/ u_int16_t       version_minor;
@@ -161,8 +172,8 @@ struct ata_params {
 #define ATA_SUPPORT_FLUSHCACHE48        0x2000
 
 /*084/087*/ u_int16_t   extension;
-#define ATA_SUPPORT_SMARTTEST		0x0001
-#define ATA_SUPPORT_SMARTLOG		0x0002
+#define ATA_SUPPORT_SMARTLOG		0x0001
+#define ATA_SUPPORT_SMARTTEST		0x0002
 #define ATA_SUPPORT_MEDIASN		0x0004
 #define ATA_SUPPORT_MEDIAPASS		0x0008
 #define ATA_SUPPORT_STREAMING		0x0010
@@ -170,6 +181,7 @@ struct ata_params {
 #define ATA_SUPPORT_WRITEDMAFUAEXT	0x0040
 #define ATA_SUPPORT_WRITEDMAQFUAEXT	0x0080
 #define ATA_SUPPORT_64BITWWN		0x0100
+#define ATA_SUPPORT_UNLOAD		0x2000
 	} __packed support, enabled;
 
 /*088*/ u_int16_t       udmamodes;              /* UltraDMA modes */
@@ -192,14 +204,52 @@ struct ata_params {
 	u_int16_t       lba_size48_2;
 	u_int16_t       lba_size48_3;
 	u_int16_t       lba_size48_4;
-	u_int16_t       reserved104[23];
+	u_int16_t       reserved104[2];
+/*106*/	u_int16_t       pss;
+#define ATA_PSS_LSPPS			0x000F
+#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];
+/*117*/ u_int16_t       lss_1;
+/*118*/ u_int16_t       lss_2;
+/*119*/ u_int16_t       support2;
+#define ATA_SUPPORT_WRITEREADVERIFY	0x0002
+#define ATA_SUPPORT_WRITEUNCORREXT	0x0004
+#define ATA_SUPPORT_RWLOGDMAEXT		0x0008
+#define ATA_SUPPORT_MICROCODE3		0x0010
+#define ATA_SUPPORT_FREEFALL		0x0020
+/*120*/ u_int16_t       enabled2;
+	u_int16_t       reserved121[6];
 /*127*/ u_int16_t       removable_status;
 /*128*/ u_int16_t       security_status;
 	u_int16_t       reserved129[31];
 /*160*/ u_int16_t       cfa_powermode1;
-	u_int16_t       reserved161[15];
-/*176*/ u_int16_t       media_serial[30];
-	u_int16_t       reserved206[49];
+	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];
+/*209*/ u_int16_t       lbalign;
+/*210*/ u_int16_t       wrv_sectors_m3_1;
+	u_int16_t       wrv_sectors_m3_2;
+/*212*/ u_int16_t       wrv_sectors_m2_1;
+	u_int16_t       wrv_sectors_m2_2;
+/*214*/ u_int16_t       nv_cache_caps;
+/*215*/ u_int16_t       nv_cache_size_1;
+	u_int16_t       nv_cache_size_2;
+/*217*/ u_int16_t       media_rotation_rate;
+	u_int16_t       reserved218;
+/*219*/ u_int16_t       nv_cache_opt;
+/*220*/ u_int16_t       wrv_mode;
+	u_int16_t       reserved221;
+/*222*/ u_int16_t       transport_major;
+/*223*/ u_int16_t       transport_minor;
+	u_int16_t       reserved224[31];
 /*255*/ u_int16_t       integrity;
 } __packed;
 

From b351967560a56a3efde400bcb8774a8ee7473e6b Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 12:58:07 +0000
Subject: [PATCH 0558/2592] MFC r196897: Avoid extra swi_sched() call, if this
 SIM is already queued. It reduces overhead for coalesced command completions.

---
 sys/cam/cam_xpt.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index bfa00476d96..7984103918a 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -4203,12 +4203,12 @@ xpt_done(union ccb *done_ccb)
 				mtx_lock(&cam_simq_lock);
 				TAILQ_INSERT_TAIL(&cam_simq, sim,
 						  links);
-				sim->flags |= CAM_SIM_ON_DONEQ;
 				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);
 			}
-			if ((done_ccb->ccb_h.path->periph->flags &
-			    CAM_PERIPH_POLLED) == 0)
-				swi_sched(cambio_ih, 0);
 			break;
 		default:
 			panic("unknown periph type %d",
@@ -4894,16 +4894,20 @@ camisr(void *dummy)
 
 	mtx_lock(&cam_simq_lock);
 	TAILQ_INIT(&queue);
-	TAILQ_CONCAT(&queue, &cam_simq, links);
-	mtx_unlock(&cam_simq_lock);
+	while (!TAILQ_EMPTY(&cam_simq)) {
+		TAILQ_CONCAT(&queue, &cam_simq, links);
+		mtx_unlock(&cam_simq_lock);
 
-	while ((sim = TAILQ_FIRST(&queue)) != NULL) {
-		TAILQ_REMOVE(&queue, sim, links);
-		CAM_SIM_LOCK(sim);
-		sim->flags &= ~CAM_SIM_ON_DONEQ;
-		camisr_runqueue(&sim->sim_doneq);
-		CAM_SIM_UNLOCK(sim);
+		while ((sim = TAILQ_FIRST(&queue)) != NULL) {
+			TAILQ_REMOVE(&queue, sim, links);
+			CAM_SIM_LOCK(sim);
+			sim->flags &= ~CAM_SIM_ON_DONEQ;
+			camisr_runqueue(&sim->sim_doneq);
+			CAM_SIM_UNLOCK(sim);
+		}
+		mtx_lock(&cam_simq_lock);
 	}
+	mtx_unlock(&cam_simq_lock);
 }
 
 static void

From 05e4022d23eeb3faa6d28867ef862282f8bac93f Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 13:01:17 +0000
Subject: [PATCH 0559/2592] MFC r196898: Report scbusX in xpt_announce_periph()
 to less confuse users by two different bus addressing schemes.

MFC r196900:
s/bus %d/scbus%d/ in some messages to correct terminology.
---
 sys/cam/cam_xpt.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 7984103918a..361ea667cce 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -1038,11 +1038,12 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string)
 	 * To ensure that this is printed in one piece,
 	 * mask out CAM interrupts.
 	 */
-	printf("%s%d at %s%d bus %d target %d lun %d\n",
+	printf("%s%d at %s%d bus %d scbus%d target %d lun %d\n",
 	       periph->periph_name, periph->unit_number,
 	       path->bus->sim->sim_name,
 	       path->bus->sim->unit_number,
 	       path->bus->sim->bus_id,
+	       path->bus->path_id,
 	       path->target->target_id,
 	       path->device->lun_id);
 	printf("%s%d: ", periph->periph_name, periph->unit_number);
@@ -4609,7 +4610,7 @@ xptconfigfunc(struct cam_eb *bus, void *arg)
 					      CAM_TARGET_WILDCARD,
 					      CAM_LUN_WILDCARD)) !=CAM_REQ_CMP){
 			printf("xptconfigfunc: xpt_create_path failed with "
-			       "status %#x for bus %d\n", status, bus->path_id);
+			       "status %#x for scbus%d\n", status, bus->path_id);
 			printf("xptconfigfunc: halting bus configuration\n");
 			xpt_free_ccb(work_ccb);
 			busses_to_config--;
@@ -4620,7 +4621,7 @@ xptconfigfunc(struct cam_eb *bus, void *arg)
 		work_ccb->ccb_h.func_code = XPT_PATH_INQ;
 		xpt_action(work_ccb);
 		if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
-			printf("xptconfigfunc: CPI failed on bus %d "
+			printf("xptconfigfunc: CPI failed on scbus%d "
 			       "with status %d\n", bus->path_id,
 			       work_ccb->ccb_h.status);
 			xpt_finishconfig(xpt_periph, work_ccb);

From f26a262eebc94921a6ac317245400ad43a98a9e0 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 13:04:05 +0000
Subject: [PATCH 0560/2592] MFC r196901: Remove unneeded CAM_SIM_MPSAFE check.

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

diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 361ea667cce..a8250d29f2b 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -4412,10 +4412,7 @@ xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
 		device->tag_delay_count = 0;
 		device->tag_saved_openings = 0;
 		device->refcount = 1;
-		if (bus->sim->flags & CAM_SIM_MPSAFE)
-			callout_init_mtx(&device->callout, bus->sim->mtx, 0);
-		else
-			callout_init_mtx(&device->callout, &Giant, 0);
+		callout_init_mtx(&device->callout, bus->sim->mtx, 0);
 
 		/*
 		 * Hold a reference to our parent target so it

From e8f2b1218b0be695b2f699c9755ef2115a9d2390 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Tue, 17 Nov 2009 13:37:27 +0000
Subject: [PATCH 0561/2592] MFC: r198952

Fix two memory leaks in error cases.
---
 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 028a10f917c2b943d6082e25eee19955cc6f651b Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 13:48:27 +0000
Subject: [PATCH 0562/2592] MFC r196903: Remove duplicate qfrozen_cnt variable
 from struct cam_ed. ccbq.queue.qfrozen_cnt should be used instead.

---
 sys/cam/cam_xpt.c          | 26 +++++++++++++-------------
 sys/cam/cam_xpt_internal.h |  1 -
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index a8250d29f2b..39b25dfa97c 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -2477,7 +2477,7 @@ xpt_action_default(union ccb *start_ccb)
 		path = start_ccb->ccb_h.path;
 
 		cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb);
-		if (path->device->qfrozen_cnt == 0)
+		if (path->device->ccbq.queue.qfrozen_cnt == 0)
 			runq = xpt_schedule_dev_sendq(path->bus, path->device);
 		else
 			runq = 0;
@@ -2936,7 +2936,7 @@ xpt_action_default(union ccb *start_ccb)
 			xpt_release_devq(crs->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		start_ccb->crs.qfrozen_cnt = dev->qfrozen_cnt;
+		start_ccb->crs.qfrozen_cnt = dev->ccbq.queue.qfrozen_cnt;
 		start_ccb->ccb_h.status = CAM_REQ_CMP;
 		break;
 	}
@@ -3232,7 +3232,7 @@ xpt_run_dev_sendq(struct cam_eb *bus)
 		 * If the device has been "frozen", don't attempt
 		 * to run it.
 		 */
-		if (device->qfrozen_cnt > 0) {
+		if (device->ccbq.queue.qfrozen_cnt > 0) {
 			continue;
 		}
 
@@ -3255,7 +3255,7 @@ xpt_run_dev_sendq(struct cam_eb *bus)
 				 * the device queue until we have a slot
 				 * available.
 				 */
-				device->qfrozen_cnt++;
+				device->ccbq.queue.qfrozen_cnt++;
 				STAILQ_INSERT_TAIL(&xsoftc.highpowerq,
 						   &work_ccb->ccb_h,
 						   xpt_links.stqe);
@@ -3287,7 +3287,7 @@ xpt_run_dev_sendq(struct cam_eb *bus)
 			 * The client wants to freeze the queue
 			 * after this CCB is sent.
 			 */
-			device->qfrozen_cnt++;
+			device->ccbq.queue.qfrozen_cnt++;
 		}
 
 		/* In Target mode, the peripheral driver knows best... */
@@ -4036,7 +4036,7 @@ xpt_freeze_devq(struct cam_path *path, u_int count)
 
 	mtx_assert(path->bus->sim->mtx, MA_OWNED);
 
-	path->device->qfrozen_cnt += count;
+	path->device->ccbq.queue.qfrozen_cnt += count;
 
 	/*
 	 * Mark the last CCB in the queue as needing
@@ -4054,7 +4054,7 @@ xpt_freeze_devq(struct cam_path *path, u_int count)
 	ccbh = TAILQ_LAST(&path->device->ccbq.active_ccbs, ccb_hdr_tailq);
 	if (ccbh && ccbh->status == CAM_REQ_INPROG)
 		ccbh->status = CAM_REQUEUE_REQ;
-	return (path->device->qfrozen_cnt);
+	return (path->device->ccbq.queue.qfrozen_cnt);
 }
 
 u_int32_t
@@ -4098,11 +4098,12 @@ xpt_release_devq_device(struct cam_ed *dev, u_int count, int run_queue)
 	int	rundevq;
 
 	rundevq = 0;
-	if (dev->qfrozen_cnt > 0) {
+	if (dev->ccbq.queue.qfrozen_cnt > 0) {
 
-		count = (count > dev->qfrozen_cnt) ? dev->qfrozen_cnt : count;
-		dev->qfrozen_cnt -= count;
-		if (dev->qfrozen_cnt == 0) {
+		count = (count > dev->ccbq.queue.qfrozen_cnt) ?
+		    dev->ccbq.queue.qfrozen_cnt : count;
+		dev->ccbq.queue.qfrozen_cnt -= count;
+		if (dev->ccbq.queue.qfrozen_cnt == 0) {
 
 			/*
 			 * No longer need to wait for a successful
@@ -4407,7 +4408,6 @@ xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
 		SLIST_INIT(&device->periphs);
 		device->generation = 0;
 		device->owner = NULL;
-		device->qfrozen_cnt = 0;
 		device->flags = CAM_DEV_UNCONFIGURED;
 		device->tag_delay_count = 0;
 		device->tag_saved_openings = 0;
@@ -4976,7 +4976,7 @@ camisr_runqueue(void *V_queue)
 				xpt_start_tags(ccb_h->path);
 
 			if ((dev->ccbq.queue.entries > 0)
-			 && (dev->qfrozen_cnt == 0)
+			 && (dev->ccbq.queue.qfrozen_cnt == 0)
 			 && (device_is_send_queued(dev) == 0)) {
 				runq = xpt_schedule_dev_sendq(ccb_h->path->bus,
 							      dev);
diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h
index 12c5c2f556f..e40cde84b57 100644
--- a/sys/cam/cam_xpt_internal.h
+++ b/sys/cam/cam_xpt_internal.h
@@ -106,7 +106,6 @@ struct cam_ed {
 	u_int8_t	 queue_flags;	/* Queue flags from the control page */
 	u_int8_t	 serial_num_len;
 	u_int8_t	*serial_num;
-	u_int32_t	 qfrozen_cnt;
 	u_int32_t	 flags;
 #define CAM_DEV_UNCONFIGURED	 	0x01
 #define CAM_DEV_REL_TIMEOUT_PENDING	0x02

From 72d128fa0b5f9b03aa62c26e9374832dcb26709c Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 14:14:07 +0000
Subject: [PATCH 0563/2592] MFC r196983: Free the correct buffer in an error
 case.

Submitted by:   phk
---
 sys/cam/scsi/scsi_cd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 287c6b626f3..52f73113d64 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -2528,7 +2528,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
 
 			error = cdgetmode(periph, ¶ms, AUDIO_PAGE);
 			if (error) {
-				free(¶ms, M_SCSICD);
+				free(¶ms.mode_buf, M_SCSICD);
 				cam_periph_unlock(periph);
 				break;
 			}

From 422426a5f1be718d4e77c174d61700b60749ef9b Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Tue, 17 Nov 2009 14:30:09 +0000
Subject: [PATCH 0564/2592] MFC r198049:

  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
---
 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 6bf4bb36618..48170a4dd61 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -4218,6 +4218,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.
 	 */
@@ -4257,16 +4267,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 71f045ca3f7c0d7f1c6a11beb5597ad7c313fb9d Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 14:37:20 +0000
Subject: [PATCH 0565/2592] MFC r197421: If on sense request device returns no
 sence, give up and return, or we may loop forever.

---
 sys/cam/cam_periph.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index c4e0b0412ce..9137c55d106 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -1034,8 +1034,13 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
 					cam_error_print(saved_ccb, CAM_ESF_ALL,
 							CAM_EPF_ALL);
 #endif
-					xpt_done_ccb = TRUE;
+				} else {
+					saved_ccb->ccb_h.status &=
+					    ~CAM_STATUS_MASK;
+					saved_ccb->ccb_h.status |=
+					    CAM_AUTOSENSE_FAIL;
 				}
+				xpt_done_ccb = TRUE;
 			}
 		}
 		bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,

From 1987ffda92840e6090befe54825d24e63dd0fe45 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 14:38:47 +0000
Subject: [PATCH 0566/2592] MFC r197541: Report SATA 3.x devices.

---
 sys/cam/ata/ata_all.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c
index e75c109f7ee..b6f8e816f83 100644
--- a/sys/cam/ata/ata_all.c
+++ b/sys/cam/ata/ata_all.c
@@ -80,7 +80,9 @@ ata_print_ident(struct ata_params *ident_data)
 	printf("<%s %s> ATA/ATAPI-%d",
 	    product, revision, ata_version(ident_data->version_major));
 	if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) {
-		if (ident_data->satacapabilities & ATA_SATA_GEN2)
+		if (ident_data->satacapabilities & ATA_SATA_GEN3)
+			printf(" SATA 3.x");
+		else if (ident_data->satacapabilities & ATA_SATA_GEN2)
 			printf(" SATA 2.x");
 		else if (ident_data->satacapabilities & ATA_SATA_GEN1)
 			printf(" SATA 1.x");

From b06be4e00c1a4c9b58ac22925bade468995c5f59 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 14:47:40 +0000
Subject: [PATCH 0567/2592] MFC r196907: To save small bit of CPU time, hide
 part of SNTF register read latency behind other reads.

---
 sys/dev/ahci/ahci.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 2d8be431017..273c276bd2a 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -891,16 +891,12 @@ ahci_phy_check_events(device_t dev)
 }
 
 static void
-ahci_notify_events(device_t dev)
+ahci_notify_events(device_t dev, u_int32_t status)
 {
 	struct ahci_channel *ch = device_get_softc(dev);
 	struct cam_path *dpath;
-	u_int32_t status;
 	int i;
 
-	status = ATA_INL(ch->r_mem, AHCI_P_SNTF);
-	if (status == 0)
-		return;
 	ATA_OUTL(ch->r_mem, AHCI_P_SNTF, status);
 	if (bootverbose)
 		device_printf(dev, "SNTF 0x%04x\n", status);
@@ -948,7 +944,7 @@ ahci_ch_intr(void *data)
 {
 	device_t dev = (device_t)data;
 	struct ahci_channel *ch = device_get_softc(dev);
-	uint32_t istatus, cstatus, sstatus, ok, err;
+	uint32_t istatus, sstatus, cstatus, sntf = 0, ok, err;
 	enum ahci_err_type et;
 	int i, ccs, ncq_err = 0;
 
@@ -958,8 +954,10 @@ ahci_ch_intr(void *data)
 		return;
 	ATA_OUTL(ch->r_mem, AHCI_P_IS, istatus);
 	/* Read command statuses. */
-	cstatus = ATA_INL(ch->r_mem, AHCI_P_CI);
 	sstatus = ATA_INL(ch->r_mem, AHCI_P_SACT);
+	cstatus = ATA_INL(ch->r_mem, AHCI_P_CI);
+	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);
@@ -1023,8 +1021,8 @@ ahci_ch_intr(void *data)
 			ahci_issue_read_log(dev);
 	}
 	/* Process NOTIFY events */
-	if ((istatus & AHCI_P_IX_SDB) && (ch->caps & AHCI_CAP_SSNTF))
-		ahci_notify_events(dev);
+	if (sntf)
+		ahci_notify_events(dev, sntf);
 }
 
 /* Must be called with channel locked. */

From db581aa0e380c0f01c08ceb7c0059926b58ee0fc Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 14:49:35 +0000
Subject: [PATCH 0568/2592] MFC r198322: 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 273c276bd2a..5daa93f3ea7 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -1924,7 +1924,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 31002ebcfce..03d2cf35b7a 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -1564,7 +1564,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 3c6b9b48a0e320316674358337efd79fefe7422b Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 14:56:00 +0000
Subject: [PATCH 0569/2592] MFC r198328: 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 1d686e05d54f9572ccd1f95a0ccc14abb7885b18 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 15:04:58 +0000
Subject: [PATCH 0570/2592] MFC r198331: 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 c6956547fc450d2346ff07b5a38794c2cba9ed34 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 15:08:01 +0000
Subject: [PATCH 0571/2592] MFC r198333: 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 9afd1b3ab3f2a65a3b8bb6fb18f5e538c22d1127 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 15:14:13 +0000
Subject: [PATCH 0572/2592] MFC r198372, r198377: 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_xpt.c   | 2 +-
 2 files changed, 9 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_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 0072eeecbe7d17354b8d8a235cd992f14519e64d Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 15:16:21 +0000
Subject: [PATCH 0573/2592] MFC r198381: 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 9ad2d7369595a8ee399a19fa792e211011adf56d Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 17 Nov 2009 15:28:14 +0000
Subject: [PATCH 0574/2592] MFC 198820: 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.

---
 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 9fff59ab134b3958e2362846f19c4d8509098e87 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 17 Nov 2009 15:30:16 +0000
Subject: [PATCH 0575/2592] MFC 198856: Fix a couple of comment typos.

---
 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 fb5f8c0a4f7e7c45fed2844ac931ccd66a4095b3 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 17 Nov 2009 15:56:45 +0000
Subject: [PATCH 0576/2592] MFC 198043: Move the USB wireless drivers down into
 their own section next to the USB ethernet drivers.

---
 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 d0f24e297c3..f20510664a5 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -288,10 +288,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
@@ -310,6 +306,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 1aa0da3b830..80ad672b2e7 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -301,10 +301,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)
@@ -324,6 +320,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 bb33d1ded97..edb8150317e 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -255,10 +255,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
@@ -278,6 +274,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 75ec10c0a31..d79db515ed9 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -230,10 +230,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
@@ -252,6 +248,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 0e7809163871146c0daace46ba95a10f1f603b01 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Tue, 17 Nov 2009 16:11:53 +0000
Subject: [PATCH 0577/2592] MFC r197286, r197306: V_irtualize the lltables
 list, making ARP and ND reasonably usable again with options VIMAGE kernels.

Discussed with:	hrs
---
 sys/net/if_llatbl.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
index b66d6e154b2..4991c81d92c 100644
--- a/sys/net/if_llatbl.c
+++ b/sys/net/if_llatbl.c
@@ -57,11 +57,14 @@ __FBSDID("$FreeBSD$");
 
 MALLOC_DEFINE(M_LLTABLE, "lltable", "link level address tables");
 
-static	SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables);
+static VNET_DEFINE(SLIST_HEAD(, lltable), lltables);
+#define	V_lltables	VNET(lltables)
 
 extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *,
 	u_char *);
 
+static void vnet_lltable_init(void);
+
 struct rwlock lltable_rwlock;
 RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
 
@@ -75,7 +78,7 @@ lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
 	int error = 0;
 
 	LLTABLE_RLOCK();
-	SLIST_FOREACH(llt, &lltables, llt_link) {
+	SLIST_FOREACH(llt, &V_lltables, llt_link) {
 		if (llt->llt_af == af) {
 			error = llt->llt_dump(llt, wr);
 			if (error != 0)
@@ -157,7 +160,7 @@ lltable_free(struct lltable *llt)
 	KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
 
 	LLTABLE_WLOCK();
-	SLIST_REMOVE(&lltables, llt, lltable, llt_link);
+	SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
 	LLTABLE_WUNLOCK();
 
 	for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
@@ -180,7 +183,7 @@ lltable_drain(int af)
 	register int i;
 
 	LLTABLE_RLOCK();
-	SLIST_FOREACH(llt, &lltables, llt_link) {
+	SLIST_FOREACH(llt, &V_lltables, llt_link) {
 		if (llt->llt_af != af)
 			continue;
 
@@ -202,7 +205,7 @@ lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask)
 	struct lltable *llt;
 
 	LLTABLE_RLOCK();
-	SLIST_FOREACH(llt, &lltables, llt_link) {
+	SLIST_FOREACH(llt, &V_lltables, llt_link) {
 		if (llt->llt_af != af)
 			continue;
 
@@ -232,7 +235,7 @@ lltable_init(struct ifnet *ifp, int af)
 		LIST_INIT(&llt->lle_head[i]);
 
 	LLTABLE_WLOCK();
-	SLIST_INSERT_HEAD(&lltables, llt, llt_link);
+	SLIST_INSERT_HEAD(&V_lltables, llt, llt_link);
 	LLTABLE_WUNLOCK();
 
 	return (llt);
@@ -302,7 +305,7 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
 
 	/* XXX linked list may be too expensive */
 	LLTABLE_RLOCK();
-	SLIST_FOREACH(llt, &lltables, llt_link) {
+	SLIST_FOREACH(llt, &V_lltables, llt_link) {
 		if (llt->llt_af == dst->sa_family &&
 		    llt->llt_ifp == ifp)
 			break;
@@ -367,3 +370,13 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
 
 	return (error);
 }
+
+static void
+vnet_lltable_init()
+{
+
+	SLIST_INIT(&V_lltables);
+}
+VNET_SYSINIT(vnet_lltable_init, SI_SUB_PSEUDO, SI_ORDER_FIRST,
+    vnet_lltable_init, NULL);
+

From 24b458cf34e910dad801337f7832a6f3cb142f7f Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 17 Nov 2009 16:17:11 +0000
Subject: [PATCH 0578/2592] MFC 198990: 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.

---
 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 41f114f1070061c6cf29e473e45dbe4bacc157c4 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 17 Nov 2009 16:50:57 +0000
Subject: [PATCH 0579/2592] MFC 198986: 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.

---
 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 82bccc64650a1e20d5dac8b7e36e557edba3604b Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 17 Nov 2009 18:31:09 +0000
Subject: [PATCH 0580/2592] MFC r198476 (by alc): Simplify the inner loop of
 vm_fault_copy_entry().

Approved by:	alc
---
 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 4a0dfeb299c2254d71969e4d60d8c561e99f741c Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 17 Nov 2009 18:38:00 +0000
Subject: [PATCH 0581/2592] MFC r198505: 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.
---
 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 01007372f25759ce58389d28f17fc2fcf9530885 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 19:36:06 +0000
Subject: [PATCH 0582/2592] MFC r197838: On command timeout handle frozen
 command first, to not run it inside XXX_end_transaction().

---
 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 5daa93f3ea7..b45943e4c2c 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 03d2cf35b7a..6507c26a5a8 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 4956ef3a420ff3280ae00bea17b71af6f882f4cb Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 19:38:19 +0000
Subject: [PATCH 0583/2592] MFC r198382, r198385: 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..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, 1);
+			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);
@@ -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 f1080f05e88..950e23a5ec7 100644
--- a/sys/cam/scsi/scsi_target.c
+++ b/sys/cam/scsi/scsi_target.c
@@ -296,7 +296,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;
 
@@ -387,7 +387,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;
@@ -415,7 +415,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;
@@ -563,7 +563,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;
 		}
@@ -1067,7 +1067,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 8f5dee240e4f96dbf374570cb8944b68d30af645 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 19:40:39 +0000
Subject: [PATCH 0584/2592] MFC r198319: 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 b45943e4c2c..485ac3d5ce4 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 2ab5a453f6f9f2b8291179c7db16d31204c6ad9e Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 19:42:06 +0000
Subject: [PATCH 0585/2592] MFC r198321 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 6507c26a5a8..207713722d0 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 446b7f18f0f0fe868b1d249ef59fe180ce6922e6 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 19:51:39 +0000
Subject: [PATCH 0586/2592] MFC r197419: Reduce code duplication.

---
 sbin/camcontrol/camcontrol.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
index 1bba49cfbcd..7da0200e829 100644
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -1055,23 +1055,22 @@ atacapprint(struct ata_params *parm)
 		printf("\n");
 
 	printf("PIO supported         PIO");
-	if (parm->atavalid & ATA_FLAG_64_70) {
-		if (parm->apiomodes & 0x02)
-			printf("4");
-		else if (parm->apiomodes & 0x01)
-			printf("3");
-	} else if (parm->mwdmamodes & 0x04)
+	switch (ata_max_pmode(parm)) {
+	case ATA_PIO4:
 		printf("4");
-	else if (parm->mwdmamodes & 0x02)
+		break;
+	case ATA_PIO3:
 		printf("3");
-	else if (parm->mwdmamodes & 0x01)
+		break;
+	case ATA_PIO2:
 		printf("2");
-	else if ((parm->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200)
-		printf("2");
-	else if ((parm->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100)
+		break;
+	case ATA_PIO1:
 		printf("1");
-	else
+		break;
+	default:
 		printf("0");
+	}
 	printf("\n");
 
 	printf("DMA%ssupported         ",

From 6b1f25ce56f434febf60bcc62084da143c9e9603 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 19:52:51 +0000
Subject: [PATCH 0587/2592] MFC r197545: Fethch more information from IDENTIFY
 result.

---
 sbin/camcontrol/camcontrol.c | 63 +++++++++++++++++++++++++++---------
 1 file changed, 48 insertions(+), 15 deletions(-)

diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
index 7da0200e829..52316ea6794 100644
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -1019,18 +1019,28 @@ atacapprint(struct ata_params *parm)
 	printf("protocol              ");
 	printf("ATA/ATAPI-%d", ata_version(parm->version_major));
 	if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
-		if (parm->satacapabilities & ATA_SATA_GEN2)
+		if (parm->satacapabilities & ATA_SATA_GEN3)
+			printf(" SATA 3.x\n");
+		else if (parm->satacapabilities & ATA_SATA_GEN2)
 			printf(" SATA 2.x\n");
 		else if (parm->satacapabilities & ATA_SATA_GEN1)
 			printf(" SATA 1.x\n");
 		else
-			printf(" SATA x.x\n");
+			printf(" SATA\n");
 	}
 	else
 		printf("\n");
 	printf("device model          %.40s\n", parm->model);
-	printf("serial number         %.20s\n", parm->serial);
 	printf("firmware revision     %.8s\n", parm->revision);
+	printf("serial number         %.20s\n", parm->serial);
+	if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) {
+		printf("WWN                   %02x%02x%02x%02x\n",
+		    parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]);
+	}
+	if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) {
+		printf("media serial number   %.30s\n",
+		    parm->media_serial);
+	}
 
 	printf("cylinders             %d\n", parm->cylinders);
 	printf("heads                 %d\n", parm->heads);
@@ -1071,6 +1081,8 @@ atacapprint(struct ata_params *parm)
 	default:
 		printf("0");
 	}
+	if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0)
+		printf(" w/o IORDY");
 	printf("\n");
 
 	printf("DMA%ssupported         ",
@@ -1110,18 +1122,25 @@ atacapprint(struct ata_params *parm)
 
 	printf("overlap%ssupported\n",
 		parm->capabilities1 & ATA_SUPPORT_OVERLAP ? " " : " not ");
+	if (parm->media_rotation_rate == 1) {
+		printf("media RPM             non-rotating\n");
+	} else if (parm->media_rotation_rate >= 0x0401 &&
+	    parm->media_rotation_rate <= 0xFFFE) {
+		printf("media RPM             %d\n",
+			parm->media_rotation_rate);
+	}
 
 	printf("\nFeature                      "
 		"Support  Enable    Value           Vendor\n");
-
-	printf("write cache                    %s	%s\n",
-		parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
-		parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
-
 	printf("read ahead                     %s	%s\n",
 		parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
 		parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
-
+	printf("write cache                    %s	%s\n",
+		parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
+		parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
+	printf("flush cache                    %s	%s\n",
+		parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no",
+		parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no");
 	if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
 		printf("Native Command Queuing (NCQ)   %s	"
 			"	%d/0x%02X\n",
@@ -1136,28 +1155,22 @@ atacapprint(struct ata_params *parm)
 		parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
 		parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
 		ATA_QUEUE_LEN(parm->queue), ATA_QUEUE_LEN(parm->queue));
-
 	printf("SMART                          %s	%s\n",
 		parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
 		parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
-
 	printf("microcode download             %s	%s\n",
 		parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
 		parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
-
 	printf("security                       %s	%s\n",
 		parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
 		parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
-
 	printf("power management               %s	%s\n",
 		parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
 		parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
-
 	printf("advanced power management      %s	%s	%d/0x%02X\n",
 		parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
 		parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no",
 		parm->apm_value, parm->apm_value);
-
 	printf("automatic acoustic management  %s	%s	"
 		"%d/0x%02X	%d/0x%02X\n",
 		parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
@@ -1166,6 +1179,22 @@ atacapprint(struct ata_params *parm)
 		ATA_ACOUSTIC_CURRENT(parm->acoustic),
 		ATA_ACOUSTIC_VENDOR(parm->acoustic),
 		ATA_ACOUSTIC_VENDOR(parm->acoustic));
+	printf("media status notification      %s	%s\n",
+		parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no",
+		parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no");
+	printf("power-up in Standby            %s	%s\n",
+		parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no",
+		parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no");
+	printf("write-read-verify              %s	%s	%d/0x%x\n",
+		parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
+		parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no",
+		parm->wrv_mode, parm->wrv_mode);
+	printf("unload                         %s	%s\n",
+		parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
+		parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
+	printf("free-fall                      %s	%s\n",
+		parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
+		parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
 }
 
 
@@ -1261,6 +1290,7 @@ ataidentify(struct cam_device *device, int retry_count, int timeout)
 		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_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial));
 	}
 	ata_btrim(ident_buf->model, sizeof(ident_buf->model));
 	ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
@@ -1268,6 +1298,9 @@ ataidentify(struct cam_device *device, int retry_count, int timeout)
 	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));
+	ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
+	ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
+	    sizeof(ident_buf->media_serial));
 
 	fprintf(stdout, "%s%d: ", device->device_name,
 		device->dev_unit_num);

From 262d12034926e3f8e853b9e5e03381deefd8925f Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:17:48 +0000
Subject: [PATCH 0588/2592] MFC r198389: 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 e1eeb865e09..ba399c9188c 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 47a0c6b4768273a4a284c903608041f6e87775b4 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:19:20 +0000
Subject: [PATCH 0589/2592] MFC r198390: 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 844c81cb6db56220d49b440f91546501d10495b2 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:20:56 +0000
Subject: [PATCH 0590/2592] MFC r198394: 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 e587ad07dcc22ab19278d846540f8220bb789a91 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:35:29 +0000
Subject: [PATCH 0591/2592] MFC r198426: 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 a3a475dfb624096be5de675e476f84a718680c2a Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:41:15 +0000
Subject: [PATCH 0592/2592] MFC r198705: 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 8eea8c79fc8ce0296cad1a9a6ce4c213a91a10d6 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:43:04 +0000
Subject: [PATCH 0593/2592] MFC r198708: - 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 0cfcf828a907f80d2516bfa5f363931460ee233d Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:45:49 +0000
Subject: [PATCH 0594/2592] MFC r198709: 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 0e3aa3c51edea37dfa55265cc8ff7fe81aefbfaa Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:49:26 +0000
Subject: [PATCH 0595/2592] MFC r198748, r198782: Fix reference counting bug,
 when device unreferenced before invalidated. To do it, do not handle validity
 flag as another reference, but explicitly modify reference count each time
 flag is modified. The async callback could free the device. If it is a
 broadcast async, it doesn't hold device reference, so take our own reference.

---
 sys/cam/ata/ata_xpt.c      |  7 ++++-
 sys/cam/cam_xpt.c          | 53 ++++++++++++++++++++++----------------
 sys/cam/cam_xpt_internal.h |  6 ++---
 sys/cam/scsi/scsi_xpt.c    | 22 ++++++++++++----
 4 files changed, 57 insertions(+), 31 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..8c568ecc452 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) {
@@ -4024,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);
 		}
 	}
 
@@ -4375,15 +4379,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 +4474,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 +4495,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 5907c56d56e222bc17211548a2378b1921492013 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:54:52 +0000
Subject: [PATCH 0596/2592] MFC r198832: 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 33e000ff00bbcb66928494fb1327258277542141 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:56:24 +0000
Subject: [PATCH 0597/2592] MFC r198849: 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 bf60b82344f6cfb5f713f6cf4c18107549d7d6d8 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:57:35 +0000
Subject: [PATCH 0598/2592] MFC r198851: - 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 d54c3c6363dd6080355d56e2034d4d8aa0d60f12 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 20:59:00 +0000
Subject: [PATCH 0599/2592] MFC r198852: - 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 ecc2f2f455e0410baba779a23917b4238054e24f Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:00:02 +0000
Subject: [PATCH 0600/2592] MFC r198896: 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 a60c326522edb1104a19ffd62e538f8f2a0b319c Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:08:12 +0000
Subject: [PATCH 0601/2592] MFC r198897: - 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 2c588f53445ebe45161c8b356699859ac9aea3ab Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:09:47 +0000
Subject: [PATCH 0602/2592] MFC r198899: - 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 f6e8afbf7a042a58a86262914287abfef00e1f02 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:14:02 +0000
Subject: [PATCH 0603/2592] MFC r198904, r198905: PMP commands use short
 format. PMP write doesn't return result.

---
 sys/cam/ata/ata_all.c | 14 ++++----------
 sys/cam/ata/ata_all.h |  2 +-
 2 files changed, 5 insertions(+), 11 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
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 6bb752977cb7b769c965027a738d6640c795b183 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:14:58 +0000
Subject: [PATCH 0604/2592] MFC r198947: 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 0b0242c67c640caf31c070d0954c94290a3a4a64 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:17:22 +0000
Subject: [PATCH 0605/2592] MFC r199079, r199101: 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..7d88998a237 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;
+	int 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 f629df5749d69b64b642edec28d336e38adbe39e Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:20:19 +0000
Subject: [PATCH 0606/2592] MFC r199132: 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 4799e6b756ff697de6c186646b6ceb62b4724b6f Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:21:27 +0000
Subject: [PATCH 0607/2592] MFC r199176: 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 99695a07ce87518f67c78d2be4feb96413ed5693 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:23:05 +0000
Subject: [PATCH 0608/2592] MFC r199178: - 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 dbf0a1cd3ec1daa2684c70e284cfc602588241f5 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:26:05 +0000
Subject: [PATCH 0609/2592] MFC r199263: Do not enable tagged queueing if
 controller reports 0 tags support.

---
 sys/cam/ata/ata_xpt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index 6485d265921..24a64fe4908 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -719,7 +719,8 @@ noerror:
 		/* 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) {
+		if (path->device->mintags != 0 &&
+		    path->bus->sim->max_tagged_dev_openings != 0) {
 			xpt_start_tags(path);
 		}
 		ata_device_transport(path);

From c263e776596fe1da3e3baf2a43e71f7a743eda8a Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:27:21 +0000
Subject: [PATCH 0610/2592] MFC r199278: Check SNCQ HBA capability bit when
 reporting NCQ support to CAM.

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

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index c46d0ce495d..fed095bb6b1 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -734,7 +734,9 @@ ahci_ch_attach(device_t dev)
 	/* Construct SIM entry */
 	ch->sim = cam_sim_alloc(ahciaction, ahcipoll, "ahcich", ch,
 	    device_get_unit(dev), &ch->mtx,
-	    min(2, ch->numslots), ch->numslots, devq);
+	    min(2, ch->numslots),
+	    (ch->caps & AHCI_CAP_SNCQ) ? ch->numslots : 0,
+	    devq);
 	if (ch->sim == NULL) {
 		device_printf(dev, "unable to allocate sim\n");
 		error = ENOMEM;
@@ -2119,7 +2121,9 @@ ahciaction(struct cam_sim *sim, union ccb *ccb)
 		struct ccb_pathinq *cpi = &ccb->cpi;
 
 		cpi->version_num = 1; /* XXX??? */
-		cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
+		cpi->hba_inquiry = PI_SDTR_ABLE;
+		if (ch->caps & AHCI_CAP_SNCQ)
+			cpi->hba_inquiry |= PI_TAG_ABLE;
 		if (ch->caps & AHCI_CAP_SPM)
 			cpi->hba_inquiry |= PI_SATAPM;
 		cpi->target_sprt = 0;

From 7c1a88d4f8371992132bdb785f9f85f521e5ebeb Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:28:59 +0000
Subject: [PATCH 0611/2592] MFC r199333: Do not require payload data to be
 aligned. It is not mentioned in datasheet and works fine in practice.

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

diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index 73786f3a613..1693883f3d9 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -579,7 +579,7 @@ siis_dmainit(device_t dev)
 	}
 	ch->dma.work_bus = dcba.maddr;
 	/* Data area. */
-	if (bus_dma_tag_create(bus_get_dma_tag(dev), 2, 0,
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
 	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
 	    NULL, NULL,
 	    SIIS_SG_ENTRIES * PAGE_SIZE * SIIS_MAX_SLOTS,

From 8c184a2d26ef03e45f6132d8183989fe5a38795a Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:42:11 +0000
Subject: [PATCH 0612/2592] MFC r196837: Remove artificial MAX_IO_SIZE
 constant, equal to DFLTPHYS * 2. Use MAXPHYS instead. It is NULL change for
 GENERIC kernel, but allows 'fast' mode to work on systems with increased
 MAXPHYS.

---
 sys/geom/stripe/g_stripe.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/sys/geom/stripe/g_stripe.c b/sys/geom/stripe/g_stripe.c
index b3261f8bba6..81f75610777 100644
--- a/sys/geom/stripe/g_stripe.c
+++ b/sys/geom/stripe/g_stripe.c
@@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
 #include 
 
 
-#define	MAX_IO_SIZE	(DFLTPHYS * 2)
 static MALLOC_DEFINE(M_STRIPE, "stripe_data", "GEOM_STRIPE Data");
 
 static uma_zone_t g_stripe_zone;
@@ -87,7 +86,7 @@ g_sysctl_stripe_fast(SYSCTL_HANDLER_ARGS)
 }
 SYSCTL_PROC(_kern_geom_stripe, OID_AUTO, fast, CTLTYPE_INT | CTLFLAG_RW,
     NULL, 0, g_sysctl_stripe_fast, "I", "Fast, but memory-consuming, mode");
-static u_int g_stripe_maxmem = MAX_IO_SIZE * 100;
+static u_int g_stripe_maxmem = MAXPHYS * 100;
 TUNABLE_INT("kern.geom.stripe.maxmem", &g_stripe_maxmem);
 SYSCTL_UINT(_kern_geom_stripe, OID_AUTO, maxmem, CTLFLAG_RD, &g_stripe_maxmem,
     0, "Maximum memory that can be allocated in \"fast\" mode (in bytes)");
@@ -125,10 +124,10 @@ static void
 g_stripe_init(struct g_class *mp __unused)
 {
 
-	g_stripe_zone = uma_zcreate("g_stripe_zone", MAX_IO_SIZE, NULL, NULL,
+	g_stripe_zone = uma_zcreate("g_stripe_zone", MAXPHYS, NULL, NULL,
 	    NULL, NULL, 0, 0);
-	g_stripe_maxmem -= g_stripe_maxmem % MAX_IO_SIZE;
-	uma_zone_set_max(g_stripe_zone, g_stripe_maxmem / MAX_IO_SIZE);
+	g_stripe_maxmem -= g_stripe_maxmem % MAXPHYS;
+	uma_zone_set_max(g_stripe_zone, g_stripe_maxmem / MAXPHYS);
 }
 
 static void
@@ -613,14 +612,14 @@ g_stripe_start(struct bio *bp)
 	 * Do use "fast" mode when:
 	 * 1. "Fast" mode is ON.
 	 * and
-	 * 2. Request size is less than or equal to MAX_IO_SIZE (128kB),
+	 * 2. Request size is less than or equal to MAXPHYS,
 	 *    which should always be true.
 	 * and
 	 * 3. Request size is bigger than stripesize * ndisks. If it isn't,
 	 *    there will be no need to send more than one I/O request to
 	 *    a provider, so there is nothing to optmize.
 	 */
-	if (g_stripe_fast && bp->bio_length <= MAX_IO_SIZE &&
+	if (g_stripe_fast && bp->bio_length <= MAXPHYS &&
 	    bp->bio_length >= stripesize * sc->sc_ndisks) {
 		fast = 1;
 	}

From 9c4a609c2d0652ffc45c30c7bae1e8c38136cc5a Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:43:42 +0000
Subject: [PATCH 0613/2592] MFC r196904: Remove msleep() timeout from
 g_io_schedule_up/down(). It works fine without it, saving few percents of CPU
 on high request rates without need to rearm callout twice per request.

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

diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c
index 61ca41c97ea..c95840a1a3b 100644
--- a/sys/geom/geom_io.c
+++ b/sys/geom/geom_io.c
@@ -567,7 +567,7 @@ g_io_schedule_down(struct thread *tp __unused)
 		if (bp == NULL) {
 			CTR0(KTR_GEOM, "g_down going to sleep");
 			msleep(&g_wait_down, &g_bio_run_down.bio_queue_lock,
-			    PRIBIO | PDROP, "-", hz/10);
+			    PRIBIO | PDROP, "-", 0);
 			continue;
 		}
 		CTR0(KTR_GEOM, "g_down has work to do");
@@ -672,7 +672,7 @@ g_io_schedule_up(struct thread *tp __unused)
 		}
 		CTR0(KTR_GEOM, "g_up going to sleep");
 		msleep(&g_wait_up, &g_bio_run_up.bio_queue_lock,
-		    PRIBIO | PDROP, "-", hz/10);
+		    PRIBIO | PDROP, "-", 0);
 	}
 }
 

From c4511bef96b6d2f61da677e77c0e7a5bdc6d098f Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 17 Nov 2009 21:45:28 +0000
Subject: [PATCH 0614/2592] MFC r196964: Do not check proper request alignment
 here in geom_dev in production. It will be checked any way later by
 g_io_check() in g_io_schedule_down(). It is only needed here to not trigger
 panic from additional check, when INVARIANTS enabled. So cover it with #ifdef
 INVARIANTS. It saves two 64bit divisions per request.

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

diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index b40dea07fcb..8b560abe37b 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -371,14 +371,14 @@ g_dev_strategy(struct bio *bp)
 	cp = dev->si_drv2;
 	KASSERT(cp->acr || cp->acw,
 	    ("Consumer with zero access count in g_dev_strategy"));
-
+#ifdef INVARIANTS
 	if ((bp->bio_offset % cp->provider->sectorsize) != 0 ||
 	    (bp->bio_bcount % cp->provider->sectorsize) != 0) {
 		bp->bio_resid = bp->bio_bcount;
 		biofinish(bp, NULL, EINVAL);
 		return;
 	}
-
+#endif
 	for (;;) {
 		/*
 		 * XXX: This is not an ideal solution, but I belive it to

From a1a32e5e3183859a32c1ccc20ddc1dc3a464d4f1 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Wed, 18 Nov 2009 14:40:00 +0000
Subject: [PATCH 0615/2592] MFC r199188: ANSIfy.

---
 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 21bd3c552d78b95f84263098510e926a98d30c9b Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Wed, 18 Nov 2009 15:35:03 +0000
Subject: [PATCH 0616/2592] MFC 199477 Fix a bug where the system panics when a
 SHUTDOWN is received with an illegal TSN. This bug was reported by Irene
 Ruengeler.

Approved by: re, rrs (mentor)
---
 sys/netinet/sctp_input.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 4a916265b9e..01b145703e7 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -834,6 +834,9 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
 		return;
 	} else {
 		sctp_update_acked(stcb, cp, net, abort_flag);
+		if (*abort_flag) {
+			return;
+		}
 	}
 	if (asoc->control_pdapi) {
 		/*

From 50324497fb1071819abe3e354fbf1a075b9aa303 Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Thu, 19 Nov 2009 12:07:00 +0000
Subject: [PATCH 0617/2592] MFC: revision 199219

  Fix cpu model for PODP5V83.  It is P24T, not P54T.
  Also remove redundant 'Overdrive' word.
---
 sys/i386/i386/identcpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index b0bcd094a5a..edb861b3c47 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -265,7 +265,7 @@ printcpuinfo(void)
 				        strcat(cpu_model, "/P54C");
 					break;
 				case 0x30:
-				        strcat(cpu_model, "/P54T Overdrive");
+				        strcat(cpu_model, "/P24T");
 					break;
 				case 0x40:
 				        strcat(cpu_model, "/P55C");

From bbe1ae35526bc29a14b5539c11b6e4b261ae9168 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Thu, 19 Nov 2009 15:28:08 +0000
Subject: [PATCH 0618/2592] MFC 199232:    Add a missing check for Apple HFS
 partitions.

---
 sys/geom/part/g_part_gpt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c
index f62b46774f5..5c8823805cc 100644
--- a/sys/geom/part/g_part_gpt.c
+++ b/sys/geom/part/g_part_gpt.c
@@ -708,6 +708,8 @@ g_part_gpt_type(struct g_part_table *basetable, struct g_part_entry *baseentry,
 		return (g_part_alias_name(G_PART_ALIAS_FREEBSD_ZFS));
 	if (EQUUID(type, &gpt_uuid_mbr))
 		return (g_part_alias_name(G_PART_ALIAS_MBR));
+	if (EQUUID(type, &gpt_uuid_apple_hfs))
+		return (g_part_alias_name(G_PART_ALIAS_APPLE_HFS));
 	buf[0] = '!';
 	snprintf_uuid(buf + 1, bufsz - 1, type);
 	return (buf);

From 26032bfa90d2e428b9d7464450c4cf05cb03aa47 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Thu, 19 Nov 2009 20:40:11 +0000
Subject: [PATCH 0619/2592] MFC of r199336 MFV of tzdata2009s, r199334

- Fix (harmless) typo in the definitions of Antarctica/David
- Fiji will go into DST from 29 November 2009 to 25 April 2010.
---
 share/zoneinfo/antarctica  |  4 ++--
 share/zoneinfo/australasia | 23 ++++++++++++++++++++++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/share/zoneinfo/antarctica b/share/zoneinfo/antarctica
index 52d604b4aed..f18ae959e3e 100644
--- a/share/zoneinfo/antarctica
+++ b/share/zoneinfo/antarctica
@@ -1,5 +1,5 @@
 # 
-# @(#)antarctica	8.6
+# @(#)antarctica	8.7
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -106,7 +106,7 @@ Zone Antarctica/Casey	0	-	zzz	1969
 Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
 			7:00	-	DAVT	1964 Nov # Davis Time
 			0	-	zzz	1969 Feb
-			7:00	-	DAVT	2009 Oct 18 2:0
+			7:00	-	DAVT	2009 Oct 18 2:00
 			5:00	-	DAVT
 Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
 			6:00	-	MAWT	2009 Oct 18 2:00
diff --git a/share/zoneinfo/australasia b/share/zoneinfo/australasia
index a5a4331dc84..38123900870 100644
--- a/share/zoneinfo/australasia
+++ b/share/zoneinfo/australasia
@@ -1,5 +1,5 @@
 # 
-# @(#)australasia	8.14
+# @(#)australasia	8.15
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -248,9 +248,30 @@ Zone	Indian/Cocos	6:27:40	-	LMT	1900
 			6:30	-	CCT	# Cocos Islands Time
 
 # Fiji
+# From Alexander Krivenyshev (2009-11-10):
+# According to Fiji Broadcasting Corporation,  Fiji plans to re-introduce DST
+# from November 29th 2009  to April 25th 2010.
+#
+# "Daylight savings to commence this month"
+# 
+# http://www.radiofiji.com.fj/fullstory.php?id=23719
+# 
+# or
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_fiji01.html
+# 
+
+# From Steffen Thorsen (2009-11-10):
+# The Fiji Government has posted some more details about the approved
+# amendments:
+# 
+# http://www.fiji.gov.fj/publish/page_16198.shtml
+# 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Fiji	1998	1999	-	Nov	Sun>=1	2:00	1:00	S
 Rule	Fiji	1999	2000	-	Feb	lastSun	3:00	0	-
+Rule	Fiji	2009	only	-	Nov	29	2:00	1:00	S
+Rule	Fiji	2010	only	-	Apr	25	3:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
 			12:00	Fiji	FJ%sT	# Fiji Time

From 30178759acd404b99bacf1f29af345c78db7f4ed Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Fri, 20 Nov 2009 06:54:47 +0000
Subject: [PATCH 0620/2592] MFC r199225: - We are not guaranteed that we're not
 dropping a reference that   we did not add.  Call LLE_REMREF() only when
 callout_stop()   actually canceled a pending callout. - callout_reset() may
 cancel a pending callout.  When   callout_reset() canceled a pending callout,
 call LLE_REMREF()   to drop a reference for the canceled callout.

---
 sys/netinet6/nd6.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index e9c15e1658a..0297972cd3e 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -434,31 +434,27 @@ skip1:
 void
 nd6_llinfo_settimer_locked(struct llentry *ln, long tick)
 {
+	int canceled;
+
 	if (tick < 0) {
 		ln->la_expire = 0;
 		ln->ln_ntick = 0;
-		callout_stop(&ln->ln_timer_ch);
-		/*
-		 * XXX - do we know that there is
-		 * callout installed? i.e. are we 
-		 * guaranteed that we're not dropping
-		 * a reference that we did not add?
-		 * KMM 
-		 */
-		LLE_REMREF(ln);
+		canceled = callout_stop(&ln->ln_timer_ch);
 	} else {
 		ln->la_expire = time_second + tick / hz;
 		LLE_ADDREF(ln);
 		if (tick > INT_MAX) {
 			ln->ln_ntick = tick - INT_MAX;
-			callout_reset(&ln->ln_timer_ch, INT_MAX,
+			canceled = callout_reset(&ln->ln_timer_ch, INT_MAX,
 			    nd6_llinfo_timer, ln);
 		} else {
 			ln->ln_ntick = 0;
-			callout_reset(&ln->ln_timer_ch, tick,
+			canceled = callout_reset(&ln->ln_timer_ch, tick,
 			    nd6_llinfo_timer, ln);
 		}
 	}
+	if (canceled)
+		LLE_REMREF(ln);
 }
 
 void
@@ -1047,6 +1043,9 @@ nd6_free(struct llentry *ln, int gc)
 			else
 				nd6_llinfo_settimer(ln, (long)V_nd6_gctimer * hz);
 			splx(s);
+			LLE_WLOCK(ln);
+			LLE_REMREF(ln);
+			LLE_WUNLOCK(ln);
 			return (LIST_NEXT(ln, lle_next));
 		}
 

From a154a457ff4d6d504fd20da2730a2ba9be7278bd Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 20 Nov 2009 06:55:35 +0000
Subject: [PATCH 0621/2592] MFC: r199255, r199257

Improved the manpage description.  The committed wording
was provided by jhb.

Remove a note about vfork(4) going to be eliminated, it's here to stay.
---
 lib/libc/sys/vfork.2 | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/lib/libc/sys/vfork.2 b/lib/libc/sys/vfork.2
index 928130b5d78..3cd33686edc 100644
--- a/lib/libc/sys/vfork.2
+++ b/lib/libc/sys/vfork.2
@@ -28,12 +28,12 @@
 .\"     @(#)vfork.2	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd June 4, 1993
+.Dd November 13, 2009
 .Dt VFORK 2
 .Os
 .Sh NAME
 .Nm vfork
-.Nd spawn new process in a virtual memory efficient way
+.Nd create a new process without copying the address space
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
@@ -113,14 +113,6 @@ The
 system call appeared in
 .Bx 2.9 .
 .Sh BUGS
-This system call will be eliminated when proper system sharing
-mechanisms are implemented.
-Users should not depend on the memory
-sharing semantics of
-.Fn vfork
-as it will, in that case, be made synonymous to
-.Xr fork 2 .
-.Pp
 To avoid a possible deadlock situation,
 processes that are children in the middle
 of a

From e15ad56b546836fbe5f929969db6180a2907a0eb Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 20 Nov 2009 07:19:09 +0000
Subject: [PATCH 0622/2592] MFC: r199349

Fix typo.
---
 share/man/man3/queue.3 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3
index 763ae42ed8d..234da680171 100644
--- a/share/man/man3/queue.3
+++ b/share/man/man3/queue.3
@@ -233,7 +233,7 @@ O(1) removal of any entry in the list.
 However:
 .Bl -enum -compact -offset indent
 .It
-Each elements requires two pointers rather than one.
+Each element requires two pointers rather than one.
 .It
 Code size and execution time of operations (except for removal) is about
 twice that of the singly-linked data-structures.

From 28d8e43cf7e349583d882e9b45cea374cbc81fdf Mon Sep 17 00:00:00 2001
From: Bruce M Simpson 
Date: Fri, 20 Nov 2009 11:58:04 +0000
Subject: [PATCH 0623/2592] MFC r199518:   Adapt the fix for IGMPv2 in r199287
 for the IPv6 stack.   Only multicast routing is affected by the issue.

---
 sys/netinet6/raw_ip6.c | 38 ++++++++++++++++++++++++++++++--------
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 108742d55b6..335eff54939 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -213,17 +213,39 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
 		 */
 		if (in6p->in6p_moptions &&
 		    IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
-			struct sockaddr_in6 mcaddr;
+			/*
+			 * If the incoming datagram is for MLD, allow it
+			 * through unconditionally to the raw socket.
+			 *
+			 * Use the M_RTALERT_MLD flag to check for MLD
+			 * traffic without having to inspect the mbuf chain
+			 * more deeply, as all MLDv1/v2 host messages MUST
+			 * contain the Router Alert option.
+			 *
+			 * In the case of MLDv1, we may not have explicitly
+			 * joined the group, and may have set IFF_ALLMULTI
+			 * on the interface. im6o_mc_filter() may discard
+			 * control traffic we actually need to see.
+			 *
+			 * Userland multicast routing daemons should continue
+			 * filter the control traffic appropriately.
+			 */
 			int blocked;
 
-			bzero(&mcaddr, sizeof(struct sockaddr_in6));
-			mcaddr.sin6_len = sizeof(struct sockaddr_in6);
-			mcaddr.sin6_family = AF_INET6;
-			mcaddr.sin6_addr = ip6->ip6_dst;
+			blocked = MCAST_PASS;
+			if ((m->m_flags & M_RTALERT_MLD) == 0) {
+				struct sockaddr_in6 mcaddr;
 
-			blocked = im6o_mc_filter(in6p->in6p_moptions, ifp,
-			    (struct sockaddr *)&mcaddr,
-			    (struct sockaddr *)&fromsa);
+				bzero(&mcaddr, sizeof(struct sockaddr_in6));
+				mcaddr.sin6_len = sizeof(struct sockaddr_in6);
+				mcaddr.sin6_family = AF_INET6;
+				mcaddr.sin6_addr = ip6->ip6_dst;
+
+				blocked = im6o_mc_filter(in6p->in6p_moptions,
+				    ifp,
+				    (struct sockaddr *)&mcaddr,
+				    (struct sockaddr *)&fromsa);
+			}
 			if (blocked != MCAST_PASS) {
 				IP6STAT_INC(ip6s_notmember);
 				continue;

From 025bbb4984ce84b1fe5a29212555dbd6ca685e44 Mon Sep 17 00:00:00 2001
From: Bruce M Simpson 
Date: Fri, 20 Nov 2009 12:30:40 +0000
Subject: [PATCH 0624/2592] MFC r199522..199528:   Pullup IPv6 mcast SSM KPI
 fixes from HEAD, including fix for   filter deallocation from Stef Walter.

---
 sys/netinet/in_mcast.c   |  2 +-
 sys/netinet6/in6_mcast.c | 83 ++++++++++++++++++++++++++++++++--------
 2 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
index 3dd090850e7..11294be72a0 100644
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -1966,7 +1966,7 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 		imf = &imo->imo_mfilters[idx];
 		if (ssa->ss.ss_family != AF_UNSPEC) {
 			/*
-			 * MCAST_JOIN_SOURCE on an exclusive membership
+			 * MCAST_JOIN_SOURCE_GROUP on an exclusive membership
 			 * is an error. On an existing inclusive membership,
 			 * it just adds the source to the filter list.
 			 */
diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c
index eedebb91b48..1438c32030d 100644
--- a/sys/netinet6/in6_mcast.c
+++ b/sys/netinet6/in6_mcast.c
@@ -1814,6 +1814,7 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt)
 
 	ifp = NULL;
 	imf = NULL;
+	lims = NULL;
 	error = 0;
 	is_new = 0;
 
@@ -1917,11 +1918,6 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt)
 	 */
 	(void)in6_setscope(&gsa->sin6.sin6_addr, ifp, NULL);
 
-	/*
-	 * MCAST_JOIN_SOURCE on an exclusive membership is an error.
-	 * On an existing inclusive membership, it just adds the
-	 * source to the filter list.
-	 */
 	imo = in6p_findmoptions(inp);
 	idx = im6o_match_group(imo, ifp, &gsa->sa);
 	if (idx == -1) {
@@ -1929,16 +1925,53 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt)
 	} else {
 		inm = imo->im6o_membership[idx];
 		imf = &imo->im6o_mfilters[idx];
-		if (ssa->ss.ss_family != AF_UNSPEC &&
-		    imf->im6f_st[1] != MCAST_INCLUDE) {
+		if (ssa->ss.ss_family != AF_UNSPEC) {
+			/*
+			 * MCAST_JOIN_SOURCE_GROUP on an exclusive membership
+			 * is an error. On an existing inclusive membership,
+			 * it just adds the source to the filter list.
+			 */
+			if (imf->im6f_st[1] != MCAST_INCLUDE) {
+				error = EINVAL;
+				goto out_in6p_locked;
+			}
+			/*
+			 * Throw out duplicates.
+			 *
+			 * XXX FIXME: This makes a naive assumption that
+			 * even if entries exist for *ssa in this imf,
+			 * they will be rejected as dupes, even if they
+			 * are not valid in the current mode (in-mode).
+			 *
+			 * in6_msource is transactioned just as for anything
+			 * else in SSM -- but note naive use of in6m_graft()
+			 * below for allocating new filter entries.
+			 *
+			 * This is only an issue if someone mixes the
+			 * full-state SSM API with the delta-based API,
+			 * which is discouraged in the relevant RFCs.
+			 */
+			lims = im6o_match_source(imo, idx, &ssa->sa);
+			if (lims != NULL /*&&
+			    lims->im6sl_st[1] == MCAST_INCLUDE*/) {
+				error = EADDRNOTAVAIL;
+				goto out_in6p_locked;
+			}
+		} else {
+			/*
+			 * MCAST_JOIN_GROUP alone, on any existing membership,
+			 * is rejected, to stop the same inpcb tying up
+			 * multiple refs to the in_multi.
+			 * On an existing inclusive membership, this is also
+			 * an error; if you want to change filter mode,
+			 * you must use the userland API setsourcefilter().
+			 * XXX We don't reject this for imf in UNDEFINED
+			 * state at t1, because allocation of a filter
+			 * is atomic with allocation of a membership.
+			 */
 			error = EINVAL;
 			goto out_in6p_locked;
 		}
-		lims = im6o_match_source(imo, idx, &ssa->sa);
-		if (lims != NULL) {
-			error = EADDRNOTAVAIL;
-			goto out_in6p_locked;
-		}
 	}
 
 	/*
@@ -1970,7 +2003,13 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt)
 	/*
 	 * Graft new source into filter list for this inpcb's
 	 * membership of the group. The in6_multi may not have
-	 * been allocated yet if this is a new membership.
+	 * been allocated yet if this is a new membership, however,
+	 * the in_mfilter slot will be allocated and must be initialized.
+	 *
+	 * Note: Grafting of exclusive mode filters doesn't happen
+	 * in this path.
+	 * XXX: Should check for non-NULL lims (node exists but may
+	 * not be in-mode) for interop with full-state API.
 	 */
 	if (ssa->ss.ss_family != AF_UNSPEC) {
 		/* Membership starts in IN mode */
@@ -1987,6 +2026,12 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt)
 			error = ENOMEM;
 			goto out_im6o_free;
 		}
+	} else {
+		/* No address specified; Membership starts in EX mode */
+		if (is_new) {
+			CTR1(KTR_MLD, "%s: new join w/o source", __func__);
+			im6f_init(imf, MCAST_UNDEFINED, MCAST_EXCLUDE);
+		}
 	}
 
 	/*
@@ -2272,8 +2317,10 @@ out_im6f_rollback:
 
 	if (is_final) {
 		/* Remove the gap in the membership array. */
-		for (++idx; idx < imo->im6o_num_memberships; ++idx)
+		for (++idx; idx < imo->im6o_num_memberships; ++idx) {
 			imo->im6o_membership[idx-1] = imo->im6o_membership[idx];
+			imo->im6o_mfilters[idx-1] = imo->im6o_mfilters[idx];
+		}
 		imo->im6o_num_memberships--;
 	}
 
@@ -2340,9 +2387,11 @@ in6p_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
 	if (error)
 		return (error);
 
-	if (msfr.msfr_nsrcs > in6_mcast_maxsocksrc ||
-	    (msfr.msfr_fmode != MCAST_EXCLUDE &&
-	     msfr.msfr_fmode != MCAST_INCLUDE))
+	if (msfr.msfr_nsrcs > in6_mcast_maxsocksrc)
+		return (ENOBUFS);
+
+	if (msfr.msfr_fmode != MCAST_EXCLUDE &&
+	    msfr.msfr_fmode != MCAST_INCLUDE)
 		return (EINVAL);
 
 	if (msfr.msfr_group.ss_family != AF_INET6 ||

From 1c7de26f34acb5bcabd32cf5cd72b4d85dbea0a3 Mon Sep 17 00:00:00 2001
From: Stacey Son 
Date: Sat, 21 Nov 2009 12:38:45 +0000
Subject: [PATCH 0626/2592] Bump __FreeBSD_version to reflect the point when
 EVFILT_USER kevent filter has been implemented.

Approved by: rwatson (co-mentor)
---
 sys/sys/param.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/sys/param.h b/sys/sys/param.h
index 10a1a9a79f9..38c0c04706d 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 800107	/* Master, propagated to newvers */
+#define __FreeBSD_version 800108	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include 

From 4cb9493f3f10be6e549db0f74e3685fba43cab29 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Sat, 21 Nov 2009 14:53:08 +0000
Subject: [PATCH 0627/2592] MFC r199017,199228

Fix handling of GPT headers when size is > 92 bytes.

This should address reading GPT headers written by opensolaris.
---
 sys/geom/part/g_part_gpt.c | 162 ++++++++++++++++++++++---------------
 1 file changed, 95 insertions(+), 67 deletions(-)

diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c
index 5c8823805cc..a7eb899f31f 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,20 @@ 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);
+	/* Allocate space for the header */
+	table->hdr = g_malloc(sizeof(struct gpt_hdr), M_WAITOK | M_ZERO);
 
-	basetable->gpt_first = table->hdr.hdr_lba_start;
-	basetable->gpt_last = table->hdr.hdr_lba_end;
+	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;
 	return (0);
 }
 
@@ -582,7 +602,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 +621,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 +655,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 +675,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 +688,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))
@@ -729,7 +757,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 */
@@ -743,21 +771,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);
@@ -768,7 +796,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. */
@@ -776,7 +804,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,
@@ -793,7 +821,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 262b2ce07603d5390335b5e647577f3cad3a3cc3 Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Sat, 21 Nov 2009 15:02:35 +0000
Subject: [PATCH 0628/2592] MFC 198420

  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
---
 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 9497adf974946fef48a5072dbce604fb7001014b Mon Sep 17 00:00:00 2001
From: Jun Kuriyama 
Date: Sun, 22 Nov 2009 14:32:32 +0000
Subject: [PATCH 0629/2592] - MFC r199067,199215,199253

  - 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.

  - Amd64 init_secondary() calls initializecpu() while curthread is
    still not properly set up. r199067 added the call to
    TUNABLE_INT_FETCH() to initializecpu() that results in hang because
    AP are started when kernel environment is already dynamic and thus
    needs to acquire mutex, that is too early in AP start sequence to
    work.

    Extract the code that should be executed only once, because it sets
    up global variables, from initializecpu() to initializecpucache(),
    and call the later only from hammer_time() executed on BSP. Now,
    TUNABLE_INT_FETCH() is done only once at BSP at the early boot
    stage.
---
 sys/amd64/amd64/initcpu.c  | 22 +++++++++++++++++++++-
 sys/amd64/amd64/machdep.c  |  1 +
 sys/amd64/include/md_var.h |  1 +
 sys/i386/i386/initcpu.c    | 17 ++++++++++++++++-
 4 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index 7aaff821463..c97ad3dbbb1 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -47,6 +47,12 @@ __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;
 
 int	cpu;			/* Are we 386, 386sx, 486, etc? */
 u_int	cpu_feature;		/* Feature flags */
@@ -157,6 +163,11 @@ initializecpu(void)
 	    CPUID_TO_FAMILY(cpu_id) == 0x6 &&
 	    CPUID_TO_MODEL(cpu_id) >= 0xf)
 		init_via();
+}
+
+void
+initializecpucache()
+{
 
 	/*
 	 * CPUID with %eax = 1, %ebx returns
@@ -169,6 +180,15 @@ 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/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 95db5d2d605..e4c51a3bb82 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1667,6 +1667,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
 
 	identify_cpu();		/* Final stage of CPU initialization */
 	initializecpu();	/* Initialize CPU registers */
+	initializecpucache();
 
 	/* make an initial tss so cpu can get interrupt stack on syscall! */
 	common_tss[0].tss_rsp0 = thread0.td_kstack + \
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index c66fc9fdb36..15df851ee31 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -89,6 +89,7 @@ void	gs_load_fault(void) __asm(__STRING(gs_load_fault));
 void	dump_add_page(vm_paddr_t);
 void	dump_drop_page(vm_paddr_t);
 void	initializecpu(void);
+void	initializecpucache(void);
 void	fillw(int /*u_short*/ pat, void *base, size_t cnt);
 void	fpstate_drop(struct thread *td);
 int	is_physical_memory(vm_paddr_t addr);
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index dc8da0b0f2a..dad79197ec0 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -75,6 +75,12 @@ 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;
 
 /* Must *NOT* be BSS or locore will bzero these after setting them */
 int	cpu = 0;		/* Are we 386, 386sx, 486, etc? */
@@ -721,7 +727,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;
 
 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)

From 36a59d030604ce550f4fdc872036671c02500da2 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Sun, 22 Nov 2009 15:53:39 +0000
Subject: [PATCH 0630/2592] MFC r199209: Fix a potential buffer boundaries
 overflow in devclass_add_device() by using all available int lenghts digits
 for storing the information.

Sponsored by:	Sandvine Incorporated
---
 sys/kern/subr_bus.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 221e622f3b4..225ebb61c62 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1584,7 +1585,7 @@ devclass_add_device(devclass_t dc, device_t dev)
 
 	PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
 
-	buflen = snprintf(NULL, 0, "%s%d$", dc->name, dev->unit);
+	buflen = snprintf(NULL, 0, "%s%d$", dc->name, INT_MAX);
 	if (buflen < 0)
 		return (ENOMEM);
 	dev->nameunit = malloc(buflen, M_BUS, M_NOWAIT|M_ZERO);

From ea46ba3475c6bf1faa29fcccda2d8fd08271dc5c Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Sun, 22 Nov 2009 15:57:08 +0000
Subject: [PATCH 0631/2592] MFC r199210: Introduce the new loader compile-time
 option BOOT_PROMPT_123 which allows to enter the loader prompt just after
 entering the sequence "123".

Sponsored by:	Sandvine Incorporated
---
 sys/boot/common/Makefile.inc |  4 ++++
 sys/boot/common/boot.c       | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc
index 9ede3866fb3..1f31aa9b601 100644
--- a/sys/boot/common/Makefile.inc
+++ b/sys/boot/common/Makefile.inc
@@ -38,4 +38,8 @@ MAN+=	../forth/loader.conf.5
 MAN+=	../forth/loader.4th.8
 .endif
 
+.if defined(BOOT_PROMPT_123)
+CFLAGS+=	-DBOOT_PROMPT_123
+.endif
+
 MAN+=	loader.8
diff --git a/sys/boot/common/boot.c b/sys/boot/common/boot.c
index 315c039b466..c6ab6812da7 100644
--- a/sys/boot/common/boot.c
+++ b/sys/boot/common/boot.c
@@ -162,6 +162,9 @@ autoboot(int timeout, char *prompt)
     int		c, yes;
     char	*argv[2], *cp, *ep;
     char	*kernelname;
+#ifdef BOOT_PROMPT_123
+    const char	*seq = "123", *p = seq;
+#endif
 
     autoboot_tried = 1;
 
@@ -192,14 +195,29 @@ autoboot(int timeout, char *prompt)
 
         yes = 0;
 
+#ifdef BOOT_PROMPT_123
+        printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or "
+	    "1 2 3 sequence for command prompt." : prompt);
+#else
         printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt);
+#endif
 
         for (;;) {
 	    if (ischar()) {
 	        c = getchar();
+#ifdef BOOT_PROMPT_123
+		if ((c == '\r') || (c == '\n')) {
+			yes = 1;
+			break;
+		} else if (c != *p++)
+			p = seq;
+		if (*p == 0)
+			break;
+#else
 	        if ((c == '\r') || (c == '\n'))
 		    yes = 1;
 	        break;
+#endif
 	    }
 	    ntime = time(NULL);
 	    if (ntime >= when) {

From a5e831ded986435cfad6a485ebdeaa49280d5d1e Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Sun, 22 Nov 2009 16:04:49 +0000
Subject: [PATCH 0632/2592] MFC r199208, r199223: Move inet_aton() (specular to
 inet_ntoa(), already present in libkern) into libkern in order to made it
 usable by other modules than alias_proxy.

Sponsored by:	Sandvine Incorporated
---
 sys/conf/files                     |   1 +
 sys/contrib/rdma/krping/krping.c   | 103 ----------------------
 sys/libkern/inet_aton.c            | 136 +++++++++++++++++++++++++++++
 sys/netinet/in.h                   |   1 +
 sys/netinet/libalias/alias_proxy.c | 104 ----------------------
 5 files changed, 138 insertions(+), 207 deletions(-)
 create mode 100644 sys/libkern/inet_aton.c

diff --git a/sys/conf/files b/sys/conf/files
index ba399c9188c..0c60646728b 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2162,6 +2162,7 @@ libkern/iconv_converter_if.m	optional libiconv
 libkern/iconv_xlat.c		optional libiconv
 libkern/iconv_xlat16.c		optional libiconv
 libkern/index.c			standard
+libkern/inet_aton.c		standard
 libkern/inet_ntoa.c		standard
 libkern/mcount.c		optional profiling-routine
 libkern/memcmp.c		standard
diff --git a/sys/contrib/rdma/krping/krping.c b/sys/contrib/rdma/krping/krping.c
index db7c524549c..d787965cd84 100644
--- a/sys/contrib/rdma/krping/krping.c
+++ b/sys/contrib/rdma/krping/krping.c
@@ -112,109 +112,6 @@ struct krping_cb_list krping_cbs;
 #define RPING_BUFSIZE 128*1024
 #define RPING_SQ_DEPTH 32
 
-
-/* lifted from netinet/libalias/alias_proxy.c */
-static int inet_aton(const char *cp, struct in_addr *addr);
-static int
-inet_aton(cp, addr)
-        const char *cp;
-        struct in_addr *addr;
-{
-	u_long parts[4];
-	in_addr_t val;
-	const char *c;
-	char *endptr;
-	int gotend, n;
-
-	c = (const char *)cp;
-	n = 0;
-	/*
-	 * Run through the string, grabbing numbers until
-	 * the end of the string, or some error
-	 */
-	gotend = 0;
-	while (!gotend) {
-		unsigned long l;
-
-		l = strtoul(c, &endptr, 0);
-
-		if (l == ULONG_MAX || (l == 0 && endptr == c))
-			return (0);
-
-		val = (in_addr_t)l;
-		/*
-		 * If the whole string is invalid, endptr will equal
-		 * c.. this way we can make sure someone hasn't
-		 * gone '.12' or something which would get past
-		 * the next check.
-		 */
-		if (endptr == c)
-			return (0);
-		parts[n] = val;
-		c = endptr;
-
-		/* Check the next character past the previous number's end */
-		switch (*c) {
-		case '.' :
-			/* Make sure we only do 3 dots .. */
-			if (n == 3)	/* Whoops. Quit. */
-				return (0);
-			n++;
-			c++;
-			break;
-
-		case '\0':
-			gotend = 1;
-			break;
-
-		default:
-			if (isspace((unsigned char)*c)) {
-				gotend = 1;
-				break;
-			} else
-				return (0);	/* Invalid character, so fail */
-		}
-
-	}
-
-	/*
-	 * Concoct the address according to
-	 * the number of parts specified.
-	 */
-
-	switch (n) {
-	case 0:				/* a -- 32 bits */
-		/*
-		 * Nothing is necessary here.  Overflow checking was
-		 * already done in strtoul().
-		 */
-		break;
-	case 1:				/* a.b -- 8.24 bits */
-		if (val > 0xffffff || parts[0] > 0xff)
-			return (0);
-		val |= parts[0] << 24;
-		break;
-
-	case 2:				/* a.b.c -- 8.8.16 bits */
-		if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff)
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16);
-		break;
-
-	case 3:				/* a.b.c.d -- 8.8.8.8 bits */
-		if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff ||
-		    parts[2] > 0xff)
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-		break;
-	}
-
-	if (addr != NULL)
-		addr->s_addr = htonl(val);
-	return (1);
-}
-
-
 static void krping_wait(struct krping_cb *cb, int state)
 {
 	int rc;
diff --git a/sys/libkern/inet_aton.c b/sys/libkern/inet_aton.c
new file mode 100644
index 00000000000..a4625cb4fd1
--- /dev/null
+++ b/sys/libkern/inet_aton.c
@@ -0,0 +1,136 @@
+/*-
+ * Copyright (c) 2001 Charles Mott 
+ * 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 
+
+int
+inet_aton(const char *cp, struct in_addr *addr)
+{
+	u_long parts[4];
+	in_addr_t val;
+	const char *c;
+	char *endptr;
+	int gotend, n;
+
+	c = (const char *)cp;
+	n = 0;
+
+	/*
+	 * Run through the string, grabbing numbers until
+	 * the end of the string, or some error
+	 */
+	gotend = 0;
+	while (!gotend) {
+		unsigned long l;
+
+		l = strtoul(c, &endptr, 0);
+
+		if (l == ULONG_MAX || (l == 0 && endptr == c))
+			return (0);
+
+		val = (in_addr_t)l;
+
+		/*
+		 * If the whole string is invalid, endptr will equal
+		 * c.. this way we can make sure someone hasn't
+		 * gone '.12' or something which would get past
+		 * the next check.
+		 */
+		if (endptr == c)
+			return (0);
+		parts[n] = val;
+		c = endptr;
+
+		/* Check the next character past the previous number's end */
+		switch (*c) {
+		case '.' :
+
+			/* Make sure we only do 3 dots .. */
+			if (n == 3)	/* Whoops. Quit. */
+				return (0);
+			n++;
+			c++;
+			break;
+
+		case '\0':
+			gotend = 1;
+			break;
+
+		default:
+			if (isspace((unsigned char)*c)) {
+				gotend = 1;
+				break;
+			} else {
+
+				/* Invalid character, then fail. */
+				return (0);
+			}
+		}
+
+	}
+
+	/* Concoct the address according to the number of parts specified. */
+	switch (n) {
+	case 0:				/* a -- 32 bits */
+
+		/*
+		 * Nothing is necessary here.  Overflow checking was
+		 * already done in strtoul().
+		 */
+		break;
+	case 1:				/* a.b -- 8.24 bits */
+		if (val > 0xffffff || parts[0] > 0xff)
+			return (0);
+		val |= parts[0] << 24;
+		break;
+
+	case 2:				/* a.b.c -- 8.8.16 bits */
+		if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff)
+			return (0);
+		val |= (parts[0] << 24) | (parts[1] << 16);
+		break;
+
+	case 3:				/* a.b.c.d -- 8.8.8.8 bits */
+		if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff ||
+		    parts[2] > 0xff)
+			return (0);
+		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+		break;
+	}
+
+	if (addr != NULL)
+		addr->s_addr = htonl(val);
+	return (1);
+}
+
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index ad07aba4604..4f9b774ca0d 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -733,6 +733,7 @@ int	 in_broadcast(struct in_addr, struct ifnet *);
 int	 in_canforward(struct in_addr);
 int	 in_localaddr(struct in_addr);
 int	 in_localip(struct in_addr);
+int	 inet_aton(const char *, struct in_addr *); /* in libkern */
 char	*inet_ntoa(struct in_addr); /* in libkern */
 char	*inet_ntoa_r(struct in_addr ina, char *buf); /* in libkern */
 void	 in_ifdetach(struct ifnet *);
diff --git a/sys/netinet/libalias/alias_proxy.c b/sys/netinet/libalias/alias_proxy.c
index 4e11d4d74be..d5b1b81eb36 100644
--- a/sys/netinet/libalias/alias_proxy.c
+++ b/sys/netinet/libalias/alias_proxy.c
@@ -137,9 +137,6 @@ struct proxy_entry {
 				destination of a proxied IP packet
 */
 
-#ifdef	_KERNEL		/* XXX: can it be moved to libkern? */
-static int inet_aton(const char *cp, struct in_addr *addr);
-#endif
 static int	IpMask(int, struct in_addr *);
 static int	IpAddr(char *, struct in_addr *);
 static int	IpPort(char *, int, int *);
@@ -149,107 +146,6 @@ static int	RuleNumberDelete(struct libalias *la, int);
 static void	ProxyEncodeTcpStream(struct alias_link *, struct ip *, int);
 static void	ProxyEncodeIpHeader(struct ip *, int);
 
-#ifdef	_KERNEL
-static int
-inet_aton(cp, addr)
-        const char *cp;
-        struct in_addr *addr;
-{
-	u_long parts[4];
-	in_addr_t val;
-	const char *c;
-	char *endptr;
-	int gotend, n;
-
-	c = (const char *)cp;
-	n = 0;
-	/*
-	 * Run through the string, grabbing numbers until
-	 * the end of the string, or some error
-	 */
-	gotend = 0;
-	while (!gotend) {
-		unsigned long l;
-
-		l = strtoul(c, &endptr, 0);
-
-		if (l == ULONG_MAX || (l == 0 && endptr == c))
-			return (0);
-
-		val = (in_addr_t)l;
-		/*
-		 * If the whole string is invalid, endptr will equal
-		 * c.. this way we can make sure someone hasn't
-		 * gone '.12' or something which would get past
-		 * the next check.
-		 */
-		if (endptr == c)
-			return (0);
-		parts[n] = val;
-		c = endptr;
-
-		/* Check the next character past the previous number's end */
-		switch (*c) {
-		case '.' :
-			/* Make sure we only do 3 dots .. */
-			if (n == 3)	/* Whoops. Quit. */
-				return (0);
-			n++;
-			c++;
-			break;
-
-		case '\0':
-			gotend = 1;
-			break;
-
-		default:
-			if (isspace((unsigned char)*c)) {
-				gotend = 1;
-				break;
-			} else
-				return (0);	/* Invalid character, so fail */
-		}
-
-	}
-
-	/*
-	 * Concoct the address according to
-	 * the number of parts specified.
-	 */
-
-	switch (n) {
-	case 0:				/* a -- 32 bits */
-		/*
-		 * Nothing is necessary here.  Overflow checking was
-		 * already done in strtoul().
-		 */
-		break;
-	case 1:				/* a.b -- 8.24 bits */
-		if (val > 0xffffff || parts[0] > 0xff)
-			return (0);
-		val |= parts[0] << 24;
-		break;
-
-	case 2:				/* a.b.c -- 8.8.16 bits */
-		if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff)
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16);
-		break;
-
-	case 3:				/* a.b.c.d -- 8.8.8.8 bits */
-		if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff ||
-		    parts[2] > 0xff)
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-		break;
-	}
-
-	if (addr != NULL)
-		addr->s_addr = htonl(val);
-	return (1);
-}
-#endif
-
 static int
 IpMask(int nbits, struct in_addr *mask)
 {

From 7f7bb302634cead14f3c195c91b9aa9b8a027471 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Sun, 22 Nov 2009 16:09:27 +0000
Subject: [PATCH 0633/2592] MFC r199007: Fix a memory leak.

---
 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 5668f751d96..224536fb23e 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;
@@ -215,14 +219,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) {
@@ -241,6 +240,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 fbf9555aa08fab0b104af16d904a485c7c57b202 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Sun, 22 Nov 2009 16:11:20 +0000
Subject: [PATCH 0634/2592] MFC r199008: Track lockmgr_disown() in the stack.

---
 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 3df8cdd6099..9557038e680 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -1083,6 +1083,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 fa5f8aabc7d3897ed6410ccf474db49df8104505 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Sun, 22 Nov 2009 16:13:16 +0000
Subject: [PATCH 0635/2592] MFC r199024: Use a safety belt for cases where
 corrupted narg can be passed to the ktrsyscall().

---
 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 b119cf74a1d78f4d81dde5fb9059e65da714f25f Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Sun, 22 Nov 2009 17:05:46 +0000
Subject: [PATCH 0636/2592] MFC r199083: 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 aa2c4cc881a..a8286f14c06 100644
--- a/lib/libc/nls/C.msg
+++ b/lib/libc/nls/C.msg
@@ -247,3 +247,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 1b05fd607416458590b938e665593ef8a80d12e4 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Sun, 22 Nov 2009 17:08:52 +0000
Subject: [PATCH 0637/2592] MFC r199092: 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 ホストåã®ã‚¢ãƒ‰ãƒ¬ã‚¹ãƒ•ァミリーã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“
+$ 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 䏿˜Žãªã‚¨ãƒ©ãƒ¼
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 c2a8874e1af268ee8afd299f840e8e80da14a35f Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Sun, 22 Nov 2009 17:16:37 +0000
Subject: [PATCH 0638/2592] MFC r199242: Use ncursesw to output the date field
 of vmstat display with multi-byte string, correctly.

---
 usr.bin/systat/Makefile | 2 +-
 usr.bin/systat/main.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/usr.bin/systat/Makefile b/usr.bin/systat/Makefile
index 4f5f229725b..49bb9981c0d 100644
--- a/usr.bin/systat/Makefile
+++ b/usr.bin/systat/Makefile
@@ -15,6 +15,6 @@ CFLAGS+= -DINET6
 .endif
 
 DPADD=	${LIBCURSES} ${LIBM} ${LIBDEVSTAT} ${LIBKVM}
-LDADD=	-lcurses -lm -ldevstat -lkvm
+LDADD=	-lcursesw -lm -ldevstat -lkvm
 
 .include 
diff --git a/usr.bin/systat/main.c b/usr.bin/systat/main.c
index 6f6b9940686..d092f10fe19 100644
--- a/usr.bin/systat/main.c
+++ b/usr.bin/systat/main.c
@@ -87,7 +87,7 @@ main(int argc, char **argv)
 	char errbuf[_POSIX2_LINE_MAX], dummy;
 	size_t	size;
 
-	(void) setlocale(LC_TIME, "");
+	(void) setlocale(LC_ALL, "");
 
 	argc--, argv++;
 	while (argc > 0) {

From 3a55f83a23295dce658aad925943af0a27e84ddb Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Sun, 22 Nov 2009 17:25:11 +0000
Subject: [PATCH 0639/2592] MFC r199179, r199271: - Add unit to the short month
 names for Japanese locales.   Without unit, the output of the application
 like ls(1)   is complicated. - Since %b contains unit, %b is not suitable for
 c_fmt,   now.  Use %_m instead.

---
 share/timedef/ja_JP.SJIS.src  | 26 +++++++++++++-------------
 share/timedef/ja_JP.UTF-8.src | 26 +++++++++++++-------------
 share/timedef/ja_JP.eucJP.src | 26 +++++++++++++-------------
 3 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/share/timedef/ja_JP.SJIS.src b/share/timedef/ja_JP.SJIS.src
index 8a1de08bb95..ca6702dc588 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)
 #
@@ -65,7 +65,7 @@
 #
 # just following tradition...
 # %a %b %e %H:%M:%S %Y
-%a %b/%e %T %Y
+%a %_m/%e %T %Y
 #
 # am
 #
diff --git a/share/timedef/ja_JP.UTF-8.src b/share/timedef/ja_JP.UTF-8.src
index 9ee39a5286f..21d0eb50d19 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)
 #
@@ -64,7 +64,7 @@
 #
 # just following tradition...
 # %a %b %e %H:%M:%S %Y
-%a %b/%e %T %Y
+%a %_m/%e %T %Y
 #
 # am
 #
diff --git a/share/timedef/ja_JP.eucJP.src b/share/timedef/ja_JP.eucJP.src
index 299f1a7a32b..155d227c4c5 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)
 #
@@ -64,7 +64,7 @@
 #
 # just following tradition...
 # %a %b %e %H:%M:%S %Y
-%a %b/%e %T %Y
+%a %_m/%e %T %Y
 #
 # am
 #

From 555a8009dd201e72edb2dc12af87e1d11600629f Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 08:45:17 +0000
Subject: [PATCH 0640/2592] MFC r198717: - 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 cd65ee1b469..f832505f36b 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;
 
@@ -368,6 +368,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 */
@@ -393,6 +394,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
@@ -400,6 +402,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
@@ -427,7 +432,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
@@ -453,7 +458,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 */
@@ -487,7 +491,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 baa3e64fa8e..c0487787144 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 41e9171e5f1..a19de8bec5c 100644
--- a/sys/dev/ata/chipsets/ata-intel.c
+++ b/sys/dev/ata/chipsets/ata-intel.c
@@ -470,10 +470,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) |
@@ -482,7 +482,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);
@@ -503,7 +503,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));
 	}
@@ -512,7 +512,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 2e9b1a7eb3b..346fed5ee74 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 0cde70967fabb99fd95b5dea8af3861344691529 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 08:46:26 +0000
Subject: [PATCH 0641/2592] MFC r198752: 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 8f51326c681b03eccecffe8893c7190f0f1e5709 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 08:56:17 +0000
Subject: [PATCH 0642/2592] MFC r199259, r199262, r199322: Change the way in
 which AHCI+PATA combined controllers, such as JMicron are handled. Instead of
 trying to attach two different drivers to single device, wrapping each call,
 make one of them (atajmicron) attach do device solely, but create child
 device for AHCI driver, passing it all required resources. It is quite easy,
 as none of resources are shared, except IRQ. Add support for AHCI SATA parts
 of alike SATA+PATA MArvell controllers. Add IDs of Marvell 88SX6102,
 88SX6111. 88SX6141 controllers.

As result, it:
- makes drivers operation more independent and straitforward,
- allows to use new ahci(4) driver with such devices, adding support for
new features, such as PMP and NCQ, same time keeping legacy PATA support,
- will allow to just drop old ataahci driver, when it's time come.
---
 sys/dev/ahci/ahci.c                | 123 ++++++++++++--
 sys/dev/ahci/ahci.h                |   2 +
 sys/dev/ata/ata-pci.c              | 251 ++++++++++++++++++-----------
 sys/dev/ata/ata-pci.h              |  22 ++-
 sys/dev/ata/chipsets/ata-ahci.c    | 103 ++++++++++--
 sys/dev/ata/chipsets/ata-jmicron.c | 126 +++------------
 sys/dev/ata/chipsets/ata-marvell.c |  77 +++++----
 7 files changed, 434 insertions(+), 270 deletions(-)

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index fed095bb6b1..2d21c0506e1 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -99,7 +99,14 @@ MALLOC_DEFINE(M_AHCI, "AHCI driver", "AHCI driver data buffers");
 static struct {
 	uint32_t	id;
 	const char	*name;
-	int		flags;
+	int		quirks;
+#define AHCI_Q_NOFORCE	1
+#define AHCI_Q_NOPMP	2
+#define AHCI_Q_NONCQ	4
+#define AHCI_Q_1CH	8
+#define AHCI_Q_2CH	16
+#define AHCI_Q_4CH	32
+#define AHCI_Q_EDGEIS	64
 } ahci_ids[] = {
 	{0x43801002, "ATI IXP600",	0},
 	{0x43901002, "ATI IXP700",	0},
@@ -145,6 +152,15 @@ static struct {
 	{0x3b2b8086, "Intel PCH",	0},
 	{0x3b2c8086, "Intel PCH",	0},
 	{0x3b2f8086, "Intel PCH",	0},
+	{0x2361197b, "JMicron JMB361",	AHCI_Q_NOFORCE},
+	{0x2363197b, "JMicron JMB363",	AHCI_Q_NOFORCE},
+	{0x2365197b, "JMicron JMB365",	AHCI_Q_NOFORCE},
+	{0x2366197b, "JMicron JMB366",	AHCI_Q_NOFORCE},
+	{0x2368197b, "JMicron JMB368",	AHCI_Q_NOFORCE},
+	{0x611111ab, "Marvell 88SX6111", AHCI_Q_NOFORCE|AHCI_Q_1CH|AHCI_Q_EDGEIS},
+	{0x612111ab, "Marvell 88SX6121", AHCI_Q_NOFORCE|AHCI_Q_2CH|AHCI_Q_EDGEIS},
+	{0x614111ab, "Marvell 88SX6141", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS},
+	{0x614511ab, "Marvell 88SX6145", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS},
 	{0x044c10de, "NVIDIA MCP65",	0},
 	{0x044d10de, "NVIDIA MCP65",	0},
 	{0x044e10de, "NVIDIA MCP65",	0},
@@ -224,11 +240,41 @@ static struct {
 
 static int
 ahci_probe(device_t dev)
+{
+	char buf[64];
+	int i, valid = 0;
+	uint32_t devid = pci_get_devid(dev);
+
+	/* Is this a possible AHCI candidate? */
+	if (pci_get_class(dev) == PCIC_STORAGE &&
+	    pci_get_subclass(dev) == PCIS_STORAGE_SATA &&
+	    pci_get_progif(dev) == PCIP_STORAGE_SATA_AHCI_1_0)
+		valid = 1;
+	/* Is this a known AHCI chip? */
+	for (i = 0; ahci_ids[i].id != 0; i++) {
+		if (ahci_ids[i].id == devid &&
+		    (valid || !(ahci_ids[i].quirks & AHCI_Q_NOFORCE))) {
+			snprintf(buf, sizeof(buf), "%s AHCI SATA controller",
+			    ahci_ids[i].name);
+			device_set_desc_copy(dev, buf);
+			return (BUS_PROBE_VENDOR);
+		}
+	}
+	if (!valid)
+		return (ENXIO);
+	device_set_desc_copy(dev, "AHCI SATA controller");
+	return (BUS_PROBE_VENDOR);
+}
+
+static int
+ahci_ata_probe(device_t dev)
 {
 	char buf[64];
 	int i;
 	uint32_t devid = pci_get_devid(dev);
 
+	if ((intptr_t)device_get_ivars(dev) >= 0)
+		return (ENXIO);
 	/* Is this a known AHCI chip? */
 	for (i = 0; ahci_ids[i].id != 0; i++) {
 		if (ahci_ids[i].id == devid) {
@@ -238,11 +284,6 @@ ahci_probe(device_t dev)
 			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_progif(dev) != PCIP_STORAGE_SATA_AHCI_1_0)
-		return (ENXIO);
 	device_set_desc_copy(dev, "AHCI SATA controller");
 	return (BUS_PROBE_VENDOR);
 }
@@ -252,10 +293,15 @@ ahci_attach(device_t dev)
 {
 	struct ahci_controller *ctlr = device_get_softc(dev);
 	device_t child;
-	int	error, unit, speed;
+	int	error, unit, speed, i;
+	uint32_t devid = pci_get_devid(dev);
 	u_int32_t version;
 
 	ctlr->dev = dev;
+	i = 0;
+	while (ahci_ids[i].id != 0 && ahci_ids[i].id != devid)
+		i++;
+	ctlr->quirks = ahci_ids[i].quirks;
 	resource_int_value(device_get_name(dev),
 	    device_get_unit(dev), "ccc", &ctlr->ccc);
 	/* if we have a memory BAR(5) we are likely on an AHCI part */
@@ -282,10 +328,32 @@ ahci_attach(device_t dev)
 		rman_fini(&ctlr->sc_iomem);
 		return (error);
 	};
-	/* Get the number of HW channels */
+	/* Get the HW capabilities */
+	version = ATA_INL(ctlr->r_mem, AHCI_VS);
+	ctlr->caps = ATA_INL(ctlr->r_mem, AHCI_CAP);
+	if (version >= 0x00010020)
+		ctlr->caps2 = ATA_INL(ctlr->r_mem, AHCI_CAP2);
 	ctlr->ichannels = ATA_INL(ctlr->r_mem, AHCI_PI);
+	if (ctlr->quirks & AHCI_Q_1CH) {
+		ctlr->caps &= ~AHCI_CAP_NPMASK;
+		ctlr->ichannels &= 0x01;
+	}
+	if (ctlr->quirks & AHCI_Q_2CH) {
+		ctlr->caps &= ~AHCI_CAP_NPMASK;
+		ctlr->caps |= 1;
+		ctlr->ichannels &= 0x03;
+	}
+	if (ctlr->quirks & AHCI_Q_4CH) {
+		ctlr->caps &= ~AHCI_CAP_NPMASK;
+		ctlr->caps |= 3;
+		ctlr->ichannels &= 0x0f;
+	}
 	ctlr->channels = MAX(flsl(ctlr->ichannels),
-	    (ATA_INL(ctlr->r_mem, AHCI_CAP) & AHCI_CAP_NPMASK) + 1);
+	    (ctlr->caps & AHCI_CAP_NPMASK) + 1);
+	if (ctlr->quirks & AHCI_Q_NOPMP)
+		ctlr->caps &= ~AHCI_CAP_SPM;
+	if (ctlr->quirks & AHCI_Q_NONCQ)
+		ctlr->caps &= ~AHCI_CAP_SNCQ;
 	/* Setup interrupts. */
 	if (ahci_setup_interrupt(dev)) {
 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
@@ -293,10 +361,6 @@ ahci_attach(device_t dev)
 		return ENXIO;
 	}
 	/* Announce HW capabilities. */
-	version = ATA_INL(ctlr->r_mem, AHCI_VS);
-	ctlr->caps = ATA_INL(ctlr->r_mem, AHCI_CAP);
-	if (version >= 0x00010020)
-		ctlr->caps2 = ATA_INL(ctlr->r_mem, AHCI_CAP2);
 	speed = (ctlr->caps & AHCI_CAP_ISS) >> AHCI_CAP_ISS_SHIFT;
 	device_printf(dev,
 		    "AHCI v%x.%02x with %d %sGbps ports, Port Multiplier %s\n",
@@ -531,8 +595,15 @@ ahci_intr(void *data)
 	for (; unit < ctlr->channels; unit++) {
 		if ((is & (1 << unit)) != 0 &&
 		    (arg = ctlr->interrupt[unit].argument)) {
-			ctlr->interrupt[unit].function(arg);
-			ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
+			if (ctlr->quirks & AHCI_Q_EDGEIS) {
+				/* Some controller have edge triggered IS. */
+				ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
+				ctlr->interrupt[unit].function(arg);
+			} else {
+				/* but AHCI declares level triggered IS. */
+				ctlr->interrupt[unit].function(arg);
+				ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
+			}
 		}
 	}
 }
@@ -665,6 +736,25 @@ static driver_t ahci_driver = {
         sizeof(struct ahci_controller)
 };
 DRIVER_MODULE(ahci, pci, ahci_driver, ahci_devclass, 0, 0);
+static device_method_t ahci_ata_methods[] = {
+	DEVMETHOD(device_probe,     ahci_ata_probe),
+	DEVMETHOD(device_attach,    ahci_attach),
+	DEVMETHOD(device_detach,    ahci_detach),
+	DEVMETHOD(device_suspend,   ahci_suspend),
+	DEVMETHOD(device_resume,    ahci_resume),
+	DEVMETHOD(bus_print_child,  ahci_print_child),
+	DEVMETHOD(bus_alloc_resource,       ahci_alloc_resource),
+	DEVMETHOD(bus_release_resource,     ahci_release_resource),
+	DEVMETHOD(bus_setup_intr,   ahci_setup_intr),
+	DEVMETHOD(bus_teardown_intr,ahci_teardown_intr),
+	{ 0, 0 }
+};
+static driver_t ahci_ata_driver = {
+        "ahci",
+        ahci_ata_methods,
+        sizeof(struct ahci_controller)
+};
+DRIVER_MODULE(ahci, atapci, ahci_ata_driver, ahci_devclass, 0, 0);
 MODULE_VERSION(ahci, 1);
 MODULE_DEPEND(ahci, cam, 1, 1, 1);
 
@@ -688,6 +778,7 @@ ahci_ch_attach(device_t dev)
 	ch->unit = (intptr_t)device_get_ivars(dev);
 	ch->caps = ctlr->caps;
 	ch->caps2 = ctlr->caps2;
+	ch->quirks = ctlr->quirks;
 	ch->numslots = ((ch->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1,
 	mtx_init(&ch->mtx, "AHCI channel lock", NULL, MTX_DEF);
 	resource_int_value(device_get_name(dev),
@@ -858,7 +949,7 @@ static driver_t ahcich_driver = {
         ahcich_methods,
         sizeof(struct ahci_channel)
 };
-DRIVER_MODULE(ahcich, ahci, ahcich_driver, ahci_devclass, 0, 0);
+DRIVER_MODULE(ahcich, ahci, ahcich_driver, ahcich_devclass, 0, 0);
 
 struct ahci_dc_cb_args {
 	bus_addr_t maddr;
diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h
index 0686f6766c3..cda907812df 100644
--- a/sys/dev/ahci/ahci.h
+++ b/sys/dev/ahci/ahci.h
@@ -352,6 +352,7 @@ struct ahci_channel {
 	struct cam_path		*path;
 	uint32_t		caps;		/* Controller capabilities */
 	uint32_t		caps2;		/* Controller capabilities */
+	int			quirks;
 	int			numslots;	/* Number of present slots */
 	int			pm_level;	/* power management level */
 	int			sata_rev;	/* Maximum allowed SATA generation */
@@ -391,6 +392,7 @@ struct ahci_controller {
 	} irqs[16];
 	uint32_t		caps;		/* Controller capabilities */
 	uint32_t		caps2;		/* Controller capabilities */
+	int			quirks;
 	int			numirqs;
 	int			channels;
 	int			ichannels;
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index 4440bdea292..4a24455d8d8 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -189,91 +189,138 @@ ata_pci_resume(device_t dev)
     return error;
 }
 
+int
+ata_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+
+	return (BUS_READ_IVAR(device_get_parent(dev), dev, which, result));
+}
+
+int
+ata_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+
+	return (BUS_WRITE_IVAR(device_get_parent(dev), dev, which, value));
+}
+
+uint32_t
+ata_pci_read_config(device_t dev, device_t child, int reg, int width)
+{
+
+	return (pci_read_config(dev, reg, width));
+}
+
+void
+ata_pci_write_config(device_t dev, device_t child, int reg, 
+    uint32_t val, int width)
+{
+
+	pci_write_config(dev, reg, val, width);
+}
+
 struct resource *
 ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
 		       u_long start, u_long end, u_long count, u_int flags)
 {
-    struct ata_pci_controller *controller = device_get_softc(dev);
-    int unit = ((struct ata_channel *)device_get_softc(child))->unit;
-    struct resource *res = NULL;
-    int myrid;
+	struct ata_pci_controller *controller = device_get_softc(dev);
+	struct resource *res = NULL;
 
-    if (type == SYS_RES_IOPORT) {
-	switch (*rid) {
-	case ATA_IOADDR_RID:
-	    if (controller->legacy) {
-		start = (unit ? ATA_SECONDARY : ATA_PRIMARY);
-		count = ATA_IOSIZE;
-		end = start + count - 1;
-	    }
-	    myrid = PCIR_BAR(0) + (unit << 3);
-	    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
-				     SYS_RES_IOPORT, &myrid,
-				     start, end, count, flags);
-	    break;
+	if (device_get_devclass(child) == ata_devclass) {
+		int unit = ((struct ata_channel *)device_get_softc(child))->unit;
+		int myrid;
 
-	case ATA_CTLADDR_RID:
-	    if (controller->legacy) {
-		start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_CTLOFFSET;
-		count = ATA_CTLIOSIZE;
-		end = start + count - 1;
-	    }
-	    myrid = PCIR_BAR(1) + (unit << 3);
-	    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
-				     SYS_RES_IOPORT, &myrid,
-				     start, end, count, flags);
-	    break;
-	}
-    }
-    if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) {
-	if (controller->legacy) {
-	    int irq = (unit == 0 ? 14 : 15);
+		if (type == SYS_RES_IOPORT) {
+			switch (*rid) {
+			case ATA_IOADDR_RID:
+			    if (controller->legacy) {
+				start = (unit ? ATA_SECONDARY : ATA_PRIMARY);
+				count = ATA_IOSIZE;
+				end = start + count - 1;
+			    }
+			    myrid = PCIR_BAR(0) + (unit << 3);
+			    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+				SYS_RES_IOPORT, &myrid,
+				start, end, count, flags);
+			    break;
+			case ATA_CTLADDR_RID:
+			    if (controller->legacy) {
+				start = (unit ? ATA_SECONDARY : ATA_PRIMARY) +
+				    ATA_CTLOFFSET;
+				count = ATA_CTLIOSIZE;
+				end = start + count - 1;
+			    }
+			    myrid = PCIR_BAR(1) + (unit << 3);
+			    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+				SYS_RES_IOPORT, &myrid,
+				start, end, count, flags);
+			    break;
+			}
+		}
+		if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) {
+			if (controller->legacy) {
+			    int irq = (unit == 0 ? 14 : 15);
 	    
-	    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
-				     SYS_RES_IRQ, rid, irq, irq, 1, flags);
+			    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+				SYS_RES_IRQ, rid, irq, irq, 1, flags);
+			} else
+			    res = controller->r_irq;
+		}
+	} else {
+		if (type == SYS_RES_IRQ) {
+			if (*rid != ATA_IRQ_RID)
+				return (NULL);
+			res = controller->r_irq;
+		} else {
+			res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+			     type, rid, start, end, count, flags);
+		}
 	}
-	else
-	    res = controller->r_irq;
-    }
-    return res;
+	return (res);
 }
 
 int
 ata_pci_release_resource(device_t dev, device_t child, int type, int rid,
 			 struct resource *r)
 {
-    struct ata_pci_controller *controller = device_get_softc(dev);
-    int unit = ((struct ata_channel *)device_get_softc(child))->unit;
 
-    if (type == SYS_RES_IOPORT) {
-	switch (rid) {
-	case ATA_IOADDR_RID:
-	    return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
-					SYS_RES_IOPORT,
-					PCIR_BAR(0) + (unit << 3), r);
-	    break;
+	if (device_get_devclass(child) == ata_devclass) {
+		struct ata_pci_controller *controller = device_get_softc(dev);
+		int unit = ((struct ata_channel *)device_get_softc(child))->unit;
 
-	case ATA_CTLADDR_RID:
-	    return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
-					SYS_RES_IOPORT,
-					PCIR_BAR(1) + (unit << 3), r);
-	    break;
-	default:
-	    return ENOENT;
+	        if (type == SYS_RES_IOPORT) {
+	    		switch (rid) {
+			case ATA_IOADDR_RID:
+		    	    return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
+				SYS_RES_IOPORT,
+				PCIR_BAR(0) + (unit << 3), r);
+			case ATA_CTLADDR_RID:
+			    return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
+				SYS_RES_IOPORT,
+				PCIR_BAR(1) + (unit << 3), r);
+			default:
+			    return ENOENT;
+			}
+		}
+		if (type == SYS_RES_IRQ) {
+			if (rid != ATA_IRQ_RID)
+				return ENOENT;
+			if (controller->legacy) {
+				return BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+				    SYS_RES_IRQ, rid, r);
+			} else  
+				return 0;
+		}
+	} else {
+		if (type == SYS_RES_IRQ) {
+			if (rid != ATA_IRQ_RID)
+				return (ENOENT);
+			return (0);
+		} else {
+			return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+			    type, rid, r));
+		}
 	}
-    }
-    if (type == SYS_RES_IRQ) {
-	if (rid != ATA_IRQ_RID)
-	    return ENOENT;
-
-	if (controller->legacy) {
-	    return BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
-					SYS_RES_IRQ, rid, r);
-	}
-	else  
-	    return 0;
-    }
-    return EINVAL;
+	return (EINVAL);
 }
 
 int
@@ -281,44 +328,50 @@ ata_pci_setup_intr(device_t dev, device_t child, struct resource *irq,
 		   int flags, driver_filter_t *filter, driver_intr_t *function, 
 		   void *argument, void **cookiep)
 {
-    struct ata_pci_controller *controller = device_get_softc(dev);
-
-    if (controller->legacy) {
-	return BUS_SETUP_INTR(device_get_parent(dev), child, irq,
-			      flags, filter, function, argument, cookiep);
-    }
-    else {
 	struct ata_pci_controller *controller = device_get_softc(dev);
-	int unit = ((struct ata_channel *)device_get_softc(child))->unit;
 
-	if (filter != NULL) {
-		printf("ata-pci.c: we cannot use a filter here\n");
-		return (EINVAL);
+	if (controller->legacy) {
+		return BUS_SETUP_INTR(device_get_parent(dev), child, irq,
+			      flags, filter, function, argument, cookiep);
+	} else {
+		struct ata_pci_controller *controller = device_get_softc(dev);
+		int unit;
+
+	    	if (filter != NULL) {
+			printf("ata-pci.c: we cannot use a filter here\n");
+			return (EINVAL);
+		}
+		if (device_get_devclass(child) == ata_devclass)
+			unit = ((struct ata_channel *)device_get_softc(child))->unit;
+		else
+			unit = ATA_PCI_MAX_CH - 1;
+		controller->interrupt[unit].function = function;
+		controller->interrupt[unit].argument = argument;
+		*cookiep = controller;
+		return 0;
 	}
-	controller->interrupt[unit].function = function;
-	controller->interrupt[unit].argument = argument;
-	*cookiep = controller;
-	return 0;
-    }
 }
 
 int
 ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
 		      void *cookie)
 {
-    struct ata_pci_controller *controller = device_get_softc(dev);
-
-    if (controller->legacy) {
-	return BUS_TEARDOWN_INTR(device_get_parent(dev), child, irq, cookie);
-    }
-    else {
 	struct ata_pci_controller *controller = device_get_softc(dev);
-	int unit = ((struct ata_channel *)device_get_softc(child))->unit;
 
-	controller->interrupt[unit].function = NULL;
-	controller->interrupt[unit].argument = NULL;
-	return 0;
-    }
+        if (controller->legacy) {
+		return BUS_TEARDOWN_INTR(device_get_parent(dev), child, irq, cookie);
+	} else {
+		struct ata_pci_controller *controller = device_get_softc(dev);
+		int unit;
+
+		if (device_get_devclass(child) == ata_devclass)
+			unit = ((struct ata_channel *)device_get_softc(child))->unit;
+		else
+			unit = ATA_PCI_MAX_CH - 1;
+		controller->interrupt[unit].function = NULL;
+		controller->interrupt[unit].argument = NULL;
+		return 0;
+	}
 }
     
 static void
@@ -510,12 +563,16 @@ static device_method_t ata_pci_methods[] = {
     DEVMETHOD(device_shutdown,          bus_generic_shutdown),
 
     /* bus methods */
+    DEVMETHOD(bus_read_ivar,		ata_pci_read_ivar),
+    DEVMETHOD(bus_write_ivar,		ata_pci_write_ivar),
     DEVMETHOD(bus_alloc_resource,       ata_pci_alloc_resource),
     DEVMETHOD(bus_release_resource,     ata_pci_release_resource),
     DEVMETHOD(bus_activate_resource,    bus_generic_activate_resource),
     DEVMETHOD(bus_deactivate_resource,  bus_generic_deactivate_resource),
     DEVMETHOD(bus_setup_intr,           ata_pci_setup_intr),
     DEVMETHOD(bus_teardown_intr,        ata_pci_teardown_intr),
+    DEVMETHOD(pci_read_config,		ata_pci_read_config),
+    DEVMETHOD(pci_write_config,		ata_pci_write_config),
 
     { 0, 0 }
 };
@@ -537,6 +594,8 @@ ata_pcichannel_probe(device_t dev)
 {
     char buffer[32];
 
+    if ((intptr_t)device_get_ivars(dev) < 0)
+	    return (ENXIO);
     sprintf(buffer, "ATA channel %d", (int)(intptr_t)device_get_ivars(dev));
     device_set_desc_copy(dev, buffer);
 
@@ -711,7 +770,7 @@ ata_generic_intr(void *data)
     struct ata_channel *ch;
     int unit;
 
-    for (unit = 0; unit < ctlr->channels; unit++) {
+    for (unit = 0; unit < ATA_PCI_MAX_CH; unit++) {
 	if ((ch = ctlr->interrupt[unit].argument))
 	    ctlr->interrupt[unit].function(ch);
     }
diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index 66a25c4be87..f2a0e1371ff 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -36,6 +36,8 @@ struct ata_chip_id {
     char                *text;
 };
 
+#define ATA_PCI_MAX_CH	8
+
 /* structure describing a PCI ATA controller */
 struct ata_pci_controller {
     device_t            dev;
@@ -65,7 +67,7 @@ struct ata_pci_controller {
     struct {
     void                (*function)(void *);
     void                *argument;
-    } interrupt[8];     /* XXX SOS max ch# for now */
+    } interrupt[ATA_PCI_MAX_CH];
     void                *chipset_data;
 };
 
@@ -225,7 +227,10 @@ struct ata_pci_controller {
 #define ATA_M88SX6081           0x608111ab
 #define ATA_M88SX7042           0x704211ab
 #define ATA_M88SX6101           0x610111ab
+#define ATA_M88SX6102           0x610211ab
+#define ATA_M88SX6111           0x611111ab
 #define ATA_M88SX6121           0x612111ab
+#define ATA_M88SX6141           0x614111ab
 #define ATA_M88SX6145           0x614511ab
 
 #define ATA_MICRON_ID           0x1042
@@ -483,6 +488,11 @@ int ata_pci_attach(device_t dev);
 int ata_pci_detach(device_t dev);
 int ata_pci_suspend(device_t dev);
 int ata_pci_resume(device_t dev);
+int ata_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result);
+int ata_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value);
+uint32_t ata_pci_read_config(device_t dev, device_t child, int reg, int width);
+void ata_pci_write_config(device_t dev, device_t child, int reg, 
+    uint32_t val, int width);
 struct resource * ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags);
 int ata_pci_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r);
 int ata_pci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *function, void *argument, void **cookiep);
@@ -506,12 +516,6 @@ int ata_mode2idx(int mode);
 
 /* global prototypes from chipsets/ata-*.c */
 int ata_ahci_chipinit(device_t);
-int ata_ahci_ch_attach(device_t dev);
-int ata_ahci_ch_detach(device_t dev);
-int ata_ahci_ch_suspend(device_t dev);
-int ata_ahci_ch_resume(device_t dev);
-int ata_ahci_ctlr_reset(device_t dev);
-void ata_ahci_reset(device_t dev);
 int ata_marvell_edma_chipinit(device_t);
 int ata_sii_chipinit(device_t);
 
@@ -527,12 +531,16 @@ static device_method_t __CONCAT(dname,_methods)[] = { \
     DEVMETHOD(device_suspend,   ata_pci_suspend), \
     DEVMETHOD(device_resume,    ata_pci_resume), \
     DEVMETHOD(device_shutdown,  bus_generic_shutdown), \
+    DEVMETHOD(bus_read_ivar,		ata_pci_read_ivar), \
+    DEVMETHOD(bus_write_ivar,		ata_pci_write_ivar), \
     DEVMETHOD(bus_alloc_resource,       ata_pci_alloc_resource), \
     DEVMETHOD(bus_release_resource,     ata_pci_release_resource), \
     DEVMETHOD(bus_activate_resource,    bus_generic_activate_resource), \
     DEVMETHOD(bus_deactivate_resource,  bus_generic_deactivate_resource), \
     DEVMETHOD(bus_setup_intr,           ata_pci_setup_intr), \
     DEVMETHOD(bus_teardown_intr,        ata_pci_teardown_intr), \
+    DEVMETHOD(pci_read_config,		ata_pci_read_config), \
+    DEVMETHOD(pci_write_config,		ata_pci_write_config), \
     { 0, 0 } \
 }; \
 static driver_t __CONCAT(dname,_driver) = { \
diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c
index 9e3f9af94b6..0f76a8dce05 100644
--- a/sys/dev/ata/chipsets/ata-ahci.c
+++ b/sys/dev/ata/chipsets/ata-ahci.c
@@ -52,6 +52,12 @@ __FBSDID("$FreeBSD$");
 #include 
 
 /* local prototypes */
+static int ata_ahci_ch_attach(device_t dev);
+static int ata_ahci_ch_detach(device_t dev);
+static int ata_ahci_ch_suspend(device_t dev);
+static int ata_ahci_ch_resume(device_t dev);
+static int ata_ahci_ctlr_reset(device_t dev);
+static void ata_ahci_reset(device_t dev);
 static int ata_ahci_suspend(device_t dev);
 static int ata_ahci_status(device_t dev);
 static int ata_ahci_begin_transaction(struct ata_request *request);
@@ -97,6 +103,49 @@ ata_ahci_probe(device_t dev)
     return (BUS_PROBE_GENERIC);
 }
 
+static int
+ata_ahci_ata_probe(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(dev);
+
+    if ((intptr_t)device_get_ivars(dev) >= 0)
+	    return (ENXIO);
+    device_set_desc_copy(dev, "AHCI SATA controller");
+    ctlr->chipinit = ata_ahci_chipinit;
+    return (BUS_PROBE_GENERIC);
+}
+
+static int
+ata_ahci_ata_attach(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(dev);
+    device_t child;
+    int unit;
+
+    /* do chipset specific setups only needed once */
+    ctlr->legacy = 0;
+    ctlr->ichannels = -1;
+    ctlr->ch_attach = ata_pci_ch_attach;
+    ctlr->ch_detach = ata_pci_ch_detach;
+    ctlr->dev = dev;
+    if (ctlr->chipinit(dev))
+	return ENXIO;
+    /* attach all channels on this controller */
+    for (unit = 0; unit < ctlr->channels; unit++) {
+	if ((ctlr->ichannels & (1 << unit)) == 0)
+	    continue;
+	child = device_add_child(dev, "ata",
+	    ((unit == 0 || unit == 1) && ctlr->legacy) ?
+	    unit : devclass_find_free_unit(ata_devclass, 2));
+	if (child == NULL)
+	    device_printf(dev, "failed to add ata child device\n");
+	else
+	    device_set_ivars(child, (void *)(intptr_t)unit);
+    }
+    bus_generic_attach(dev);
+    return 0;
+}
+
 int
 ata_ahci_chipinit(device_t dev)
 {
@@ -129,9 +178,15 @@ ata_ahci_chipinit(device_t dev)
 
     /* get the number of HW channels */
     ctlr->ichannels = ATA_INL(ctlr->r_res2, ATA_AHCI_PI);
-    ctlr->channels =
-	MAX(flsl(ctlr->ichannels),
+    ctlr->channels = MAX(flsl(ctlr->ichannels),
 	    (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_NPMASK) + 1);
+    if (pci_get_devid(dev) == ATA_M88SX6111)
+	    ctlr->channels = 1;
+    else if (pci_get_devid(dev) == ATA_M88SX6121)
+	    ctlr->channels = 2;
+    else if (pci_get_devid(dev) == ATA_M88SX6141 ||
+	pci_get_devid(dev) == ATA_M88SX6145)
+	    ctlr->channels = 4;
 
     ctlr->reset = ata_ahci_reset;
     ctlr->ch_attach = ata_ahci_ch_attach;
@@ -183,7 +238,7 @@ ata_ahci_chipinit(device_t dev)
 	return 0;
 }
 
-int
+static int
 ata_ahci_ctlr_reset(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
@@ -228,7 +283,7 @@ ata_ahci_suspend(device_t dev)
     return 0;
 }
 
-int
+static int
 ata_ahci_ch_attach(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
@@ -259,7 +314,7 @@ ata_ahci_ch_attach(device_t dev)
     return 0;
 }
 
-int
+static int
 ata_ahci_ch_detach(device_t dev)
 {
 
@@ -268,7 +323,7 @@ ata_ahci_ch_detach(device_t dev)
     return (0);
 }
 
-int
+static int
 ata_ahci_ch_suspend(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
@@ -293,7 +348,7 @@ ata_ahci_ch_suspend(device_t dev)
     return (0);
 }
 
-int
+static int
 ata_ahci_ch_resume(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
@@ -813,7 +868,7 @@ ata_ahci_softreset(device_t dev, int port)
     return ATA_INL(ctlr->r_res2, ATA_AHCI_P_SIG + offset);
 }
 
-void
+static void
 ata_ahci_reset(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
@@ -845,9 +900,12 @@ ata_ahci_reset(device_t dev)
 	      ((ch->pm_level == 0) ? ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC : 0) |
 	      ATA_AHCI_P_IX_DP | ATA_AHCI_P_IX_UF | ATA_AHCI_P_IX_SDB |
 	      ATA_AHCI_P_IX_DS | ATA_AHCI_P_IX_PS | ATA_AHCI_P_IX_DHR));
-
-    /* only probe for PortMultiplier if HW has support */
-    if (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_SPM) {
+    /*
+     * Only probe for PortMultiplier if HW has support.
+     * Ignore Marvell, which is not working,
+     */
+    if ((ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_SPM) &&
+	    pci_get_vendor(ctlr->dev) != 0x11ab) {
 	signature = ata_ahci_softreset(dev, ATA_PM);
 	/* Workaround for some ATI chips, failing to soft-reset
 	 * when port multiplicator supported, but absent.
@@ -924,3 +982,26 @@ ata_ahci_setup_fis(struct ata_ahci_cmd_tab *ctp, struct ata_request *request)
 }
 
 ATA_DECLARE_DRIVER(ata_ahci);
+static device_method_t ata_ahci_ata_methods[] = {
+    DEVMETHOD(device_probe,     ata_ahci_ata_probe),
+    DEVMETHOD(device_attach,    ata_ahci_ata_attach),
+    DEVMETHOD(device_detach,    ata_pci_detach),
+    DEVMETHOD(device_suspend,   ata_pci_suspend),
+    DEVMETHOD(device_resume,    ata_pci_resume),
+    DEVMETHOD(device_shutdown,  bus_generic_shutdown),
+    DEVMETHOD(bus_read_ivar,		ata_pci_read_ivar),
+    DEVMETHOD(bus_write_ivar,		ata_pci_write_ivar),
+    DEVMETHOD(bus_alloc_resource,       ata_pci_alloc_resource),
+    DEVMETHOD(bus_release_resource,     ata_pci_release_resource),
+    DEVMETHOD(bus_activate_resource,    bus_generic_activate_resource),
+    DEVMETHOD(bus_deactivate_resource,  bus_generic_deactivate_resource),
+    DEVMETHOD(bus_setup_intr,           ata_pci_setup_intr),
+    DEVMETHOD(bus_teardown_intr,        ata_pci_teardown_intr),
+    { 0, 0 }
+};
+static driver_t ata_ahci_ata_driver = {
+        "atapci",
+        ata_ahci_ata_methods,
+        sizeof(struct ata_pci_controller)
+};
+DRIVER_MODULE(ata_ahci_ata, atapci, ata_ahci_ata_driver, ata_pci_devclass, 0, 0);
diff --git a/sys/dev/ata/chipsets/ata-jmicron.c b/sys/dev/ata/chipsets/ata-jmicron.c
index 91108af8093..25310705ecf 100644
--- a/sys/dev/ata/chipsets/ata-jmicron.c
+++ b/sys/dev/ata/chipsets/ata-jmicron.c
@@ -53,11 +53,6 @@ __FBSDID("$FreeBSD$");
 
 /* local prototypes */
 static int ata_jmicron_chipinit(device_t dev);
-static int ata_jmicron_ch_attach(device_t dev);
-static int ata_jmicron_ch_detach(device_t dev);
-static int ata_jmicron_ch_suspend(device_t dev);
-static int ata_jmicron_ch_resume(device_t dev);
-static void ata_jmicron_reset(device_t dev);
 static void ata_jmicron_setmode(device_t dev, int mode);
 
 /*
@@ -70,10 +65,10 @@ ata_jmicron_probe(device_t dev)
     struct ata_chip_id *idx;
     static struct ata_chip_id ids[] =
     {{ ATA_JMB360, 0, 1, 0, ATA_SA300, "JMB360" },
-     { ATA_JMB361, 0, 1, 1, ATA_SA300, "JMB361" },
-     { ATA_JMB363, 0, 2, 1, ATA_SA300, "JMB363" },
-     { ATA_JMB365, 0, 1, 2, ATA_SA300, "JMB365" },
-     { ATA_JMB366, 0, 2, 2, ATA_SA300, "JMB366" },
+     { ATA_JMB361, 0, 1, 1, ATA_UDMA6, "JMB361" },
+     { ATA_JMB363, 0, 2, 1, ATA_UDMA6, "JMB363" },
+     { ATA_JMB365, 0, 1, 2, ATA_UDMA6, "JMB365" },
+     { ATA_JMB366, 0, 2, 2, ATA_UDMA6, "JMB366" },
      { ATA_JMB368, 0, 0, 1, ATA_UDMA6, "JMB368" },
      { 0, 0, 0, 0, 0, 0}};
     char buffer[64];
@@ -101,7 +96,7 @@ static int
 ata_jmicron_chipinit(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
-    int error;
+    device_t child;
 
     if (ata_setup_interrupt(dev, ata_generic_intr))
 	return ENXIO;
@@ -123,116 +118,35 @@ ata_jmicron_chipinit(device_t dev)
 	/* set controller configuration to a combined setup we support */
 	pci_write_config(dev, 0x40, 0x80c0a131, 4);
 	pci_write_config(dev, 0x80, 0x01200000, 4);
-
-	if (ctlr->chip->cfg1 && (error = ata_ahci_chipinit(dev)))
-	    return error;
-
-	ctlr->ch_attach = ata_jmicron_ch_attach;
-	ctlr->ch_detach = ata_jmicron_ch_detach;
-	ctlr->ch_suspend = ata_jmicron_ch_suspend;
-	ctlr->ch_resume = ata_jmicron_ch_resume;
-	ctlr->reset = ata_jmicron_reset;
+	/* Create AHCI subdevice if AHCI part present. */
+	if (ctlr->chip->cfg1) {
+	    	child = device_add_child(dev, NULL, -1);
+		if (child != NULL) {
+		    device_set_ivars(child, (void *)(intptr_t)-1);
+		    bus_generic_attach(dev);
+		}
+	}
+	ctlr->ch_attach = ata_pci_ch_attach;
+	ctlr->ch_detach = ata_pci_ch_detach;
+	ctlr->reset = ata_generic_reset;
 	ctlr->setmode = ata_jmicron_setmode;
-
-	/* set the number of HW channels */ 
-	ctlr->channels = ctlr->chip->cfg1 + ctlr->chip->cfg2;
-	ctlr->ichannels |= ((0xffffffffU >> (32 - ctlr->chip->cfg2))
-	    << ctlr->chip->cfg1);
+	ctlr->channels = ctlr->chip->cfg2;
     }
     return 0;
 }
 
-static int
-ata_jmicron_ch_attach(device_t dev)
-{
-    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
-    struct ata_channel *ch = device_get_softc(dev);
-    int error;
-
-    if (ch->unit >= ctlr->chip->cfg1) {
-	ch->unit -= ctlr->chip->cfg1;
-	error = ata_pci_ch_attach(dev);
-	ch->unit += ctlr->chip->cfg1;
-    }
-    else
-	error = ata_ahci_ch_attach(dev);
-    return error;
-}
-
-static int
-ata_jmicron_ch_detach(device_t dev)
-{
-    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
-    struct ata_channel *ch = device_get_softc(dev);
-    int error;
-
-    if (ch->unit >= ctlr->chip->cfg1) {
-	ch->unit -= ctlr->chip->cfg1;
-	error = ata_pci_ch_detach(dev);
-	ch->unit += ctlr->chip->cfg1;
-    }
-    else
-	error = ata_ahci_ch_detach(dev);
-
-    return (error);
-}
-
-static int
-ata_jmicron_ch_suspend(device_t dev)
-{
-    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
-    struct ata_channel *ch = device_get_softc(dev);
-    int error = 0;
-
-    if (ch->unit < ctlr->chip->cfg1)
-	error = ata_ahci_ch_suspend(dev);
-    return error;
-}
-
-static int
-ata_jmicron_ch_resume(device_t dev)
-{
-    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
-    struct ata_channel *ch = device_get_softc(dev);
-    int error = 0;
-
-    if (ch->unit < ctlr->chip->cfg1)
-	error = ata_ahci_ch_resume(dev);
-    return (error);
-}
-
-static void
-ata_jmicron_reset(device_t dev)
-{
-    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
-    struct ata_channel *ch = device_get_softc(dev);
-
-    if (ch->unit >= ctlr->chip->cfg1)
-	ata_generic_reset(dev);
-    else
-	ata_ahci_reset(dev);
-}
-
 static void
 ata_jmicron_setmode(device_t dev, int mode)
 {
-    struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev));
-    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
-
-    if (pci_read_config(dev, 0xdf, 1) & 0x40 || ch->unit >= ctlr->chip->cfg1) {
 	struct ata_device *atadev = device_get_softc(dev);
 
 	/* check for 80pin cable present */
 	if (pci_read_config(dev, 0x40, 1) & 0x08)
-	    mode = ata_limit_mode(dev, mode, ATA_UDMA2);
+		mode = ata_limit_mode(dev, mode, ATA_UDMA2);
 	else
-	    mode = ata_limit_mode(dev, mode, ATA_UDMA6);
-
+		mode = ata_limit_mode(dev, mode, ATA_UDMA6);
 	if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
-	    atadev->mode = mode;
-    }
-    else
-	ata_sata_setmode(dev, mode);
+		atadev->mode = mode;
 }
 
 ATA_DECLARE_DRIVER(ata_jmicron);
diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index 346fed5ee74..bda1a17e7fa 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -52,9 +52,9 @@ __FBSDID("$FreeBSD$");
 #include 
 
 /* local prototypes */
-static int ata_marvell_pata_chipinit(device_t dev);
-static int ata_marvell_pata_ch_attach(device_t dev);
-static void ata_marvell_pata_setmode(device_t dev, int mode);
+static int ata_marvell_chipinit(device_t dev);
+static int ata_marvell_ch_attach(device_t dev);
+static void ata_marvell_setmode(device_t dev, int mode);
 static int ata_marvell_edma_ch_attach(device_t dev);
 static int ata_marvell_edma_ch_detach(device_t dev);
 static int ata_marvell_edma_status(device_t dev);
@@ -107,9 +107,12 @@ ata_marvell_probe(device_t dev)
      { 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" },
+     { ATA_M88SX6101, 0, 0, MV_61XX, ATA_UDMA6, "88SX6101" },
+     { ATA_M88SX6102, 0, 0, MV_61XX, ATA_UDMA6, "88SX6102" },
+     { ATA_M88SX6111, 0, 1, MV_61XX, ATA_UDMA6, "88SX6111" },
+     { ATA_M88SX6121, 0, 2, MV_61XX, ATA_UDMA6, "88SX6121" },
+     { ATA_M88SX6141, 0, 4, MV_61XX, ATA_UDMA6, "88SX6141" },
+     { ATA_M88SX6145, 0, 4, MV_61XX, ATA_UDMA6, "88SX6145" },
      { 0, 0, 0, 0, 0, 0}};
 
     if (pci_get_vendor(dev) != ATA_MARVELL_ID)
@@ -128,53 +131,59 @@ ata_marvell_probe(device_t dev)
 	ctlr->chipinit = ata_marvell_edma_chipinit;
 	break;
     case MV_61XX:
-	ctlr->chipinit = ata_marvell_pata_chipinit;
+	ctlr->chipinit = ata_marvell_chipinit;
 	break;
     }
     return (BUS_PROBE_DEFAULT);
 }
 
 static int
-ata_marvell_pata_chipinit(device_t dev)
+ata_marvell_chipinit(device_t dev)
 {
-    struct ata_pci_controller *ctlr = device_get_softc(dev);
+	struct ata_pci_controller *ctlr = device_get_softc(dev);
+	device_t child;
 
-    if (ata_setup_interrupt(dev, ata_generic_intr))
-	return ENXIO;
-
-    ctlr->ch_attach = ata_marvell_pata_ch_attach;
-    ctlr->ch_detach = ata_pci_ch_detach;
-    ctlr->setmode = ata_marvell_pata_setmode;
-    ctlr->channels = ctlr->chip->cfg1;
-    return 0;
+	if (ata_setup_interrupt(dev, ata_generic_intr))
+		return ENXIO;
+	/* Create AHCI subdevice if AHCI part present. */
+	if (ctlr->chip->cfg1) {
+	    	child = device_add_child(dev, NULL, -1);
+		if (child != NULL) {
+		    device_set_ivars(child, (void *)(intptr_t)-1);
+		    bus_generic_attach(dev);
+		}
+	}
+        ctlr->ch_attach = ata_marvell_ch_attach;
+	ctlr->ch_detach = ata_pci_ch_detach;
+	ctlr->reset = ata_generic_reset;
+        ctlr->setmode = ata_marvell_setmode;
+        ctlr->channels = 1;
+        return (0);
 }
 
 static int
-ata_marvell_pata_ch_attach(device_t dev)
+ata_marvell_ch_attach(device_t dev)
 {
-    struct ata_channel *ch = device_get_softc(dev);
+	struct ata_channel *ch = device_get_softc(dev);
+	int error;
  
-    /* setup the usual register normal pci style */
-    if (ata_pci_ch_attach(dev))
-	return ENXIO;
- 
-    /* dont use 32 bit PIO transfers */
+	error = ata_pci_ch_attach(dev);
+    	/* dont use 32 bit PIO transfers */
 	ch->flags |= ATA_USE_16BIT;
-
-    return 0;
+	return (error);
 }
 
 static void
-ata_marvell_pata_setmode(device_t dev, int mode)
+ata_marvell_setmode(device_t dev, int mode)
 {
-    device_t gparent = GRANDPARENT(dev);
-    struct ata_pci_controller *ctlr = device_get_softc(gparent);
-    struct ata_device *atadev = device_get_softc(dev);
+	device_t gparent = GRANDPARENT(dev);
+	struct ata_pci_controller *ctlr = device_get_softc(gparent);
+	struct ata_device *atadev = device_get_softc(dev);
 
-    mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-    mode = ata_check_80pin(dev, mode);
-    if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
-	atadev->mode = mode;
+	mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
+	mode = ata_check_80pin(dev, mode);
+	if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
+		atadev->mode = mode;
 }
 
 int

From 234c497e6a6e40dc7202f92c6848281e91d13146 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Mon, 23 Nov 2009 09:10:08 +0000
Subject: [PATCH 0643/2592] MFC: r199317

Fix a memory leak in acl_from_text() in case the conversion succeeded.
---
 lib/libc/posix1e/acl_from_text.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/libc/posix1e/acl_from_text.c b/lib/libc/posix1e/acl_from_text.c
index 98c54261d55..c600987f9f6 100644
--- a/lib/libc/posix1e/acl_from_text.c
+++ b/lib/libc/posix1e/acl_from_text.c
@@ -257,6 +257,7 @@ acl_from_text(const char *buf_p)
 	}
 #endif
 
+	free(mybuf_p);
 	return(acl);
 
 error_label:

From 109d0c5dcd747790c93264e8ed3307e303ad6597 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 09:13:32 +0000
Subject: [PATCH 0644/2592] MFC 199699: Refer more recently added Marvell
 chips.

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

diff --git a/share/man/man4/ata.4 b/share/man/man4/ata.4
index f23a4d2be1a..303e63291bb 100644
--- a/share/man/man4/ata.4
+++ b/share/man/man4/ata.4
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 6, 2009
+.Dd November 23, 2009
 .Dt ATA 4
 .Os
 .Sh NAME
@@ -146,7 +146,7 @@ IT8211F, IT8212F, IT8213F.
 JMB360, JMB361, JMB363, JMB365, JMB366, JMB368.
 .It Marvell
 88SX5040, 88SX5041, 88SX5080, 88SX5081, 88SX6041, 88SX6042, 88SX6081, 88SX6101,
-88SX6141, 88SX7042.
+88SX6102, 88SX6111, 88SX6121, 88SX6141, 88SX6145, 88SX7042.
 .It National:
 SC1100.
 .It NetCell:

From 510e0aaa49a8553794233e67b8183dcc711747c9 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 09:20:33 +0000
Subject: [PATCH 0645/2592] MFC r196762: Improve HDA controller capabilities
 logging.

---
 sys/dev/sound/pci/hda/hdac.c         | 13 +++++++------
 sys/dev/sound/pci/hda/hdac_private.h |  1 +
 sys/dev/sound/pci/hda/hdac_reg.h     |  2 ++
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 9f4264d98ec..4eda8be81a4 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -1520,7 +1520,7 @@ hdac_get_capabilities(struct hdac_softc *sc)
 	sc->num_iss = HDAC_GCAP_ISS(gcap);
 	sc->num_oss = HDAC_GCAP_OSS(gcap);
 	sc->num_bss = HDAC_GCAP_BSS(gcap);
-
+	sc->num_sdo = HDAC_GCAP_NSDO(gcap);
 	sc->support_64bit = HDA_FLAG_MATCH(gcap, HDAC_GCAP_64OK);
 
 	corbsize = HDAC_READ_1(&sc->mem, HDAC_CORBSIZE);
@@ -1555,11 +1555,12 @@ hdac_get_capabilities(struct hdac_softc *sc)
 		return (ENXIO);
 	}
 
-	HDA_BOOTHVERBOSE(
-		device_printf(sc->dev, "    CORB size: %d\n", sc->corb_size);
-		device_printf(sc->dev, "    RIRB size: %d\n", sc->rirb_size);
-		device_printf(sc->dev, "      Streams: ISS=%d OSS=%d BSS=%d\n",
-		    sc->num_iss, sc->num_oss, sc->num_bss);
+	HDA_BOOTVERBOSE(
+		device_printf(sc->dev, "Caps: OSS %d, ISS %d, BSS %d, "
+		    "NSDO %d%s, CORB %d, RIRB %d\n",
+		    sc->num_oss, sc->num_iss, sc->num_bss, 1 << sc->num_sdo,
+		    sc->support_64bit ? ", 64bit" : "",
+		    sc->corb_size, sc->rirb_size);
 	);
 
 	return (0);
diff --git a/sys/dev/sound/pci/hda/hdac_private.h b/sys/dev/sound/pci/hda/hdac_private.h
index bd329675b3c..2369a9a8d1d 100644
--- a/sys/dev/sound/pci/hda/hdac_private.h
+++ b/sys/dev/sound/pci/hda/hdac_private.h
@@ -339,6 +339,7 @@ struct hdac_softc {
 	int		num_iss;
 	int		num_oss;
 	int		num_bss;
+	int		num_sdo;
 	int		support_64bit;
 	int		streamcnt;
 
diff --git a/sys/dev/sound/pci/hda/hdac_reg.h b/sys/dev/sound/pci/hda/hdac_reg.h
index 969471023d3..813af7221a6 100644
--- a/sys/dev/sound/pci/hda/hdac_reg.h
+++ b/sys/dev/sound/pci/hda/hdac_reg.h
@@ -136,6 +136,8 @@
 	(((gcap) & HDAC_GCAP_ISS_MASK) >> HDAC_GCAP_ISS_SHIFT)
 #define HDAC_GCAP_OSS(gcap)						\
 	(((gcap) & HDAC_GCAP_OSS_MASK) >> HDAC_GCAP_OSS_SHIFT)
+#define HDAC_GCAP_NSDO(gcap)						\
+	(((gcap) & HDAC_GCAP_NSDO_MASK) >> HDAC_GCAP_NSDO_SHIFT)
 
 /* GCTL - Global Control */
 #define HDAC_GCTL_CRST			0x00000001

From 95eaf85a776b0d2928dffc5fabc748f17d76c6d7 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 09:21:35 +0000
Subject: [PATCH 0646/2592] MFC r197017: Add Intel 82801JD (one more ICH10) HDA
 controller ID.

---
 sys/dev/sound/pci/hda/hdac.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 4eda8be81a4..cc05da4f0e8 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -146,7 +146,8 @@ SND_DECLARE_FILE("$FreeBSD$");
 #define HDA_INTEL_82801G	HDA_MODEL_CONSTRUCT(INTEL, 0x27d8)
 #define HDA_INTEL_82801H	HDA_MODEL_CONSTRUCT(INTEL, 0x284b)
 #define HDA_INTEL_82801I	HDA_MODEL_CONSTRUCT(INTEL, 0x293e)
-#define HDA_INTEL_82801J	HDA_MODEL_CONSTRUCT(INTEL, 0x3a3e)
+#define HDA_INTEL_82801JI	HDA_MODEL_CONSTRUCT(INTEL, 0x3a3e)
+#define HDA_INTEL_82801JD	HDA_MODEL_CONSTRUCT(INTEL, 0x3a6e)
 #define HDA_INTEL_PCH		HDA_MODEL_CONSTRUCT(INTEL, 0x3b56)
 #define HDA_INTEL_SCH		HDA_MODEL_CONSTRUCT(INTEL, 0x811b)
 #define HDA_INTEL_ALL		HDA_MODEL_CONSTRUCT(INTEL, 0xffff)
@@ -486,7 +487,8 @@ static const struct {
 	{ HDA_INTEL_82801G,  "Intel 82801G",	0 },
 	{ HDA_INTEL_82801H,  "Intel 82801H",	0 },
 	{ HDA_INTEL_82801I,  "Intel 82801I",	0 },
-	{ HDA_INTEL_82801J,  "Intel 82801J",	0 },
+	{ HDA_INTEL_82801JI, "Intel 82801JI",	0 },
+	{ HDA_INTEL_82801JD, "Intel 82801JD",	0 },
 	{ HDA_INTEL_PCH,     "Intel PCH",	0 },
 	{ HDA_INTEL_SCH,     "Intel SCH",	0 },
 	{ HDA_NVIDIA_MCP51,  "NVidia MCP51",	HDAC_NO_MSI },

From c1ebbbc962ffc4fda7679446e26b69fa97dc3ae9 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 09:22:38 +0000
Subject: [PATCH 0647/2592] MFC r197018: Add NVidia MCP89 HDA controller IDs.

---
 sys/dev/sound/pci/hda/hdac.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index cc05da4f0e8..31988a95e5c 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -172,6 +172,10 @@ SND_DECLARE_FILE("$FreeBSD$");
 #define HDA_NVIDIA_MCP79_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac1)
 #define HDA_NVIDIA_MCP79_3	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac2)
 #define HDA_NVIDIA_MCP79_4	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac3)
+#define HDA_NVIDIA_MCP89_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d94)
+#define HDA_NVIDIA_MCP89_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d95)
+#define HDA_NVIDIA_MCP89_3	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d96)
+#define HDA_NVIDIA_MCP89_4	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d97)
 #define HDA_NVIDIA_ALL		HDA_MODEL_CONSTRUCT(NVIDIA, 0xffff)
 
 /* ATI */
@@ -509,6 +513,10 @@ static const struct {
 	{ HDA_NVIDIA_MCP79_2, "NVidia MCP79",	0 },
 	{ HDA_NVIDIA_MCP79_3, "NVidia MCP79",	0 },
 	{ HDA_NVIDIA_MCP79_4, "NVidia MCP79",	0 },
+	{ HDA_NVIDIA_MCP89_1, "NVidia MCP89",	0 },
+	{ HDA_NVIDIA_MCP89_2, "NVidia MCP89",	0 },
+	{ HDA_NVIDIA_MCP89_3, "NVidia MCP89",	0 },
+	{ HDA_NVIDIA_MCP89_4, "NVidia MCP89",	0 },
 	{ HDA_ATI_SB450,     "ATI SB450",	0 },
 	{ HDA_ATI_SB600,     "ATI SB600",	0 },
 	{ HDA_ATI_RS600,     "ATI RS600",	0 },

From 2c5d7e80c6232f27ed05f61c653d47f67a1c3608 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 09:26:30 +0000
Subject: [PATCH 0648/2592] MFC r197611, r197640: - Add some bits of
 HDMI/DisplayPort support from later specification updates. It may be not
 enough to make them work, but at least should give some information about
 these beasts. - Add Realtek ALC887 codec ID.

---
 sys/dev/sound/pci/hda/hda_reg.h | 67 ++++++++++++++++++++++++++++++++-
 sys/dev/sound/pci/hda/hdac.c    | 48 +++++++++++++++++------
 2 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/sys/dev/sound/pci/hda/hda_reg.h b/sys/dev/sound/pci/hda/hda_reg.h
index 3c5757a314a..0eeea64b178 100644
--- a/sys/dev/sound/pci/hda/hda_reg.h
+++ b/sys/dev/sound/pci/hda/hda_reg.h
@@ -660,13 +660,49 @@
 #define HDA_CMD_VERB_GET_STRIPE_CONTROL			0xf24
 #define HDA_CMD_VERB_SET_STRIPE_CONTROL			0x724
 
-#define HDA_CMD_SET_STRIPE_CONTROL(cad, nid)				\
+#define HDA_CMD_GET_STRIPE_CONTROL(cad, nid)				\
     (HDA_CMD_12BIT((cad), (nid),					\
     HDA_CMD_VERB_GET_STRIPE_CONTROL, 0x0))
-#define HDA_CMD_GET_STRIPE_CONTROL(cad, nid, payload)			\
+#define HDA_CMD_SET_STRIPE_CONTROL(cad, nid, payload)			\
     (HDA_CMD_12BIT((cad), (nid),					\
     HDA_CMD_VERB_SET_STRIPE_CONTROL, (payload)))
 
+/* Channel Count Control */
+#define HDA_CMD_VERB_GET_CONV_CHAN_COUNT			0xf2d
+#define HDA_CMD_VERB_SET_CONV_CHAN_COUNT			0x72d 
+
+#define HDA_CMD_GET_CONV_CHAN_COUNT(cad, nid)				\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_GET_CONV_CHAN_COUNT, 0x0))
+#define HDA_CMD_SET_CONV_CHAN_COUNT(cad, nid, payload)			\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_SET_CONV_CHAN_COUNT, (payload)))
+
+#define HDA_CMD_VERB_GET_HDMI_DIP_SIZE			0xf2e 
+#define HDA_CMD_VERB_GET_HDMI_ELDD			0xf2f 
+
+#define HDA_CMD_VERB_GET_HDMI_DIP_INDEX			0xf30 
+#define HDA_CMD_VERB_SET_HDMI_DIP_INDEX			0x730 
+
+#define HDA_CMD_VERB_GET_HDMI_DIP_DATA			0xf31 
+#define HDA_CMD_VERB_SET_HDMI_DIP_DATA			0x731 
+
+#define HDA_CMD_VERB_GET_HDMI_DIP_XMIT			0xf32 
+#define HDA_CMD_VERB_SET_HDMI_DIP_XMIT			0x732 
+
+#define HDA_CMD_VERB_GET_HDMI_CP_CTRL			0xf33 
+#define HDA_CMD_VERB_SET_HDMI_CP_CTRL			0x733 
+
+#define HDA_CMD_VERB_GET_HDMI_CHAN_SLOT			0xf34 
+#define HDA_CMD_VERB_SET_HDMI_CHAN_SLOT			0x734 
+
+#define HDA_CMD_GET_HDMI_CHAN_SLOT(cad, nid)				\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_GET_HDMI_CHAN_SLOT, 0x0))
+#define HDA_CMD_SET_HDMI_CHAN_SLOT(cad, nid, payload)			\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_SET_HDMI_CHAN_SLOT, (payload)))
+
 /* Function Reset */
 #define HDA_CMD_VERB_FUNCTION_RESET			0x7ff
 
@@ -779,6 +815,10 @@
 #define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT		20
 #define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK		0x000f0000
 #define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT		16
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK		0x0000e000
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT		13
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK		0x00001000
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT		12
 #define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK		0x00000800
 #define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT	11
 #define HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_MASK	0x00000400
@@ -810,6 +850,14 @@
 #define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY(param)				\
     (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK) >>		\
     HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT)
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CC(param)				\
+    ((((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK) >>		\
+    (HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT - 1)) |			\
+    (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_MASK) >>		\
+    HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT))
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CP(param)				\
+    (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK) >>			\
+    HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT)
 #define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP(param)			\
     (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK) >>		\
     HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT)
@@ -971,6 +1019,10 @@
 /* Pin Capabilities */
 #define HDA_PARAM_PIN_CAP				0x0c
 
+#define HDA_PARAM_PIN_CAP_HBR_MASK			0x08000000
+#define HDA_PARAM_PIN_CAP_HBR_SHIFT			27
+#define HDA_PARAM_PIN_CAP_DP_MASK			0x01000000
+#define HDA_PARAM_PIN_CAP_DP_SHIFT			24
 #define HDA_PARAM_PIN_CAP_EAPD_CAP_MASK			0x00010000
 #define HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT		16
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_MASK		0x0000ff00
@@ -985,6 +1037,8 @@
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_50_SHIFT		9
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK		0x00000100
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT		8
+#define HDA_PARAM_PIN_CAP_HDMI_MASK			0x00000080
+#define HDA_PARAM_PIN_CAP_HDMI_SHIFT			7
 #define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK		0x00000040
 #define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT	6
 #define HDA_PARAM_PIN_CAP_INPUT_CAP_MASK		0x00000020
@@ -1000,6 +1054,12 @@
 #define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_MASK		0x00000001
 #define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_SHIFT		0
 
+#define HDA_PARAM_PIN_CAP_HBR(param)					\
+    (((param) & HDA_PARAM_PIN_CAP_HBR_MASK) >>				\
+    HDA_PARAM_PIN_CAP_HBR_SHIFT)
+#define HDA_PARAM_PIN_CAP_DP(param)					\
+    (((param) & HDA_PARAM_PIN_CAP_DP_MASK) >>				\
+    HDA_PARAM_PIN_CAP_DP_SHIFT)
 #define HDA_PARAM_PIN_CAP_EAPD_CAP(param)				\
     (((param) & HDA_PARAM_PIN_CAP_EAPD_CAP_MASK) >>			\
     HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT)
@@ -1021,6 +1081,9 @@
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ(param)				\
     (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK) >>		\
     HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT)
+#define HDA_PARAM_PIN_CAP_HDMI(param)					\
+    (((param) & HDA_PARAM_PIN_CAP_HDMI_MASK) >>				\
+    HDA_PARAM_PIN_CAP_HDMI_SHIFT)
 #define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(param)			\
     (((param) & HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK) >>		\
     HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT)
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 31988a95e5c..21cb0a14a7a 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -38,7 +38,6 @@
  *     2) HDA Codecs support, which may include
  *        - HDA
  *        - Modem
- *        - HDMI
  *     3) Widget parser - the real magic of why this driver works on so
  *        many hardwares with minimal vendor specific quirk. The original
  *        parser was written using Ruby and can be found at
@@ -87,7 +86,7 @@
 
 #include "mixer_if.h"
 
-#define HDA_DRV_TEST_REV	"20090624_0136"
+#define HDA_DRV_TEST_REV	"20090929_0137"
 
 SND_DECLARE_FILE("$FreeBSD$");
 
@@ -623,6 +622,7 @@ static const struct {
 #define HDA_CODEC_ALC882	HDA_CODEC_CONSTRUCT(REALTEK, 0x0882)
 #define HDA_CODEC_ALC883	HDA_CODEC_CONSTRUCT(REALTEK, 0x0883)
 #define HDA_CODEC_ALC885	HDA_CODEC_CONSTRUCT(REALTEK, 0x0885)
+#define HDA_CODEC_ALC887	HDA_CODEC_CONSTRUCT(REALTEK, 0x0887)
 #define HDA_CODEC_ALC888	HDA_CODEC_CONSTRUCT(REALTEK, 0x0888)
 #define HDA_CODEC_ALC889	HDA_CODEC_CONSTRUCT(REALTEK, 0x0889)
 #define HDA_CODEC_ALCXXXX	HDA_CODEC_CONSTRUCT(REALTEK, 0xffff)
@@ -808,6 +808,7 @@ static const struct {
 	{ HDA_CODEC_ALC882,    "Realtek ALC882" },
 	{ HDA_CODEC_ALC883,    "Realtek ALC883" },
 	{ HDA_CODEC_ALC885,    "Realtek ALC885" },
+	{ HDA_CODEC_ALC887,    "Realtek ALC887" },
 	{ HDA_CODEC_ALC888,    "Realtek ALC888" },
 	{ HDA_CODEC_ALC889,    "Realtek ALC889" },
 	{ HDA_CODEC_AD1882,    "Analog Devices AD1882" },
@@ -3485,6 +3486,14 @@ hdac_stream_setup(struct hdac_chan *ch)
 		}
 		hdac_command(sc,
 		    HDA_CMD_SET_CONV_STREAM_CHAN(cad, ch->io[i], c), cad);
+#if 0
+		hdac_command(sc,
+		    HDA_CMD_SET_CONV_CHAN_COUNT(cad, ch->io[i], 1), cad);
+		hdac_command(sc,
+		    HDA_CMD_SET_HDMI_CHAN_SLOT(cad, ch->io[i], 0x00), cad);
+		hdac_command(sc,
+		    HDA_CMD_SET_HDMI_CHAN_SLOT(cad, ch->io[i], 0x11), cad);
+#endif
 		chn +=
 		    HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap) ?
 		    2 : 1;
@@ -4492,7 +4501,7 @@ hdac_audio_as_parse(struct hdac_devinfo *devinfo)
 	for (i = 0; i < max; i++) {
 		as[i].hpredir = -1;
 		as[i].chan = -1;
-		as[i].digital = 1;
+		as[i].digital = 0;
 	}
 
 	/* Scan associations skipping as=0. */
@@ -4547,8 +4556,14 @@ hdac_audio_as_parse(struct hdac_devinfo *devinfo)
 				    __func__, w->nid, j);
 				as[cnt].enable = 0;
 			}
-			if (!HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
-				as[cnt].digital = 0;
+			if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
+				if (HDA_PARAM_PIN_CAP_DP(w->wclass.pin.cap))
+					as[cnt].digital = 3;
+				else if (HDA_PARAM_PIN_CAP_HDMI(w->wclass.pin.cap))
+					as[cnt].digital = 2;
+				else
+					as[cnt].digital = 1;
+			}
 			/* Headphones with seq=15 may mean redirection. */
 			if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT &&
 			    seq == 15)
@@ -6548,15 +6563,15 @@ hdac_create_pcms(struct hdac_devinfo *devinfo)
 		devinfo->function.audio.devs[i].devinfo = devinfo;
 		devinfo->function.audio.devs[i].play = -1;
 		devinfo->function.audio.devs[i].rec = -1;
-		devinfo->function.audio.devs[i].digital = 2;
+		devinfo->function.audio.devs[i].digital = 255;
 	}
 	for (i = 0; i < devinfo->function.audio.ascnt; i++) {
 		if (as[i].enable == 0)
 			continue;
 		for (j = 0; j < devinfo->function.audio.num_devs; j++) {
-			if (devinfo->function.audio.devs[j].digital != 2 &&
-			    devinfo->function.audio.devs[j].digital !=
-			    as[i].digital)
+			if (devinfo->function.audio.devs[j].digital != 255 &&
+			    (!devinfo->function.audio.devs[j].digital) !=
+			    (!as[i].digital))
 				continue;
 			if (as[i].dir == HDA_CTL_IN) {
 				if (devinfo->function.audio.devs[j].rec >= 0)
@@ -6732,6 +6747,8 @@ hdac_dump_pin(struct hdac_softc *sc, struct hdac_widget *w)
 		printf(" IN");
 	if (HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(pincap))
 		printf(" BAL");
+	if (HDA_PARAM_PIN_CAP_HDMI(pincap))
+		printf(" HDMI");
 	if (HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)) {
 		printf(" VREF[");
 		if (HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
@@ -6748,6 +6765,10 @@ hdac_dump_pin(struct hdac_softc *sc, struct hdac_widget *w)
 	}
 	if (HDA_PARAM_PIN_CAP_EAPD_CAP(pincap))
 		printf(" EAPD");
+	if (HDA_PARAM_PIN_CAP_DP(pincap))
+		printf(" DP");
+	if (HDA_PARAM_PIN_CAP_HBR(pincap))
+		printf(" HBR");
 	printf("\n");
 	device_printf(sc->dev, "     Pin config: 0x%08x\n",
 	    w->wclass.pin.config);
@@ -6855,8 +6876,11 @@ hdac_dump_nodes(struct hdac_devinfo *devinfo)
 			    printf(" PROC");
 			if (HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(w->param.widget_cap))
 			    printf(" STRIPE");
-			if (HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap))
+			j = HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap);
+			if (j == 1)
 			    printf(" STEREO");
+			else if (j > 1)
+			    printf(" %dCH", j + 1);
 			printf("\n");
 		}
 		if (w->bindas != -1) {
@@ -7957,7 +7981,9 @@ hdac_pcm_probe(device_t dev)
 	snprintf(buf, sizeof(buf), "HDA %s PCM #%d %s",
 	    hdac_codec_name(pdevinfo->devinfo->codec),
 	    pdevinfo->index,
-	    pdevinfo->digital?"Digital":"Analog");
+	    (pdevinfo->digital == 3)?"DisplayPort":
+	    ((pdevinfo->digital == 2)?"HDMI":
+	    ((pdevinfo->digital)?"Digital":"Analog")));
 	device_set_desc_copy(dev, buf);
 	return (0);
 }

From 506ef9edb80474fe7ff030c7ca60a7a10b270515 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 09:28:16 +0000
Subject: [PATCH 0649/2592] MFC r199258: Add more codec IDs.

---
 sys/dev/sound/pci/hda/hdac.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 21cb0a14a7a..c88036955a9 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -86,7 +86,7 @@
 
 #include "mixer_if.h"
 
-#define HDA_DRV_TEST_REV	"20090929_0137"
+#define HDA_DRV_TEST_REV	"20091113_0138"
 
 SND_DECLARE_FILE("$FreeBSD$");
 
@@ -764,6 +764,16 @@ static const struct {
 #define HDA_CODEC_VT1702_5	HDA_CODEC_CONSTRUCT(VIA, 0x5398)
 #define HDA_CODEC_VT1702_6	HDA_CODEC_CONSTRUCT(VIA, 0x6398)
 #define HDA_CODEC_VT1702_7	HDA_CODEC_CONSTRUCT(VIA, 0x7398)
+#define HDA_CODEC_VT1716S_0	HDA_CODEC_CONSTRUCT(VIA, 0x0433)
+#define HDA_CODEC_VT1716S_1	HDA_CODEC_CONSTRUCT(VIA, 0xa721)
+#define HDA_CODEC_VT1718S_0	HDA_CODEC_CONSTRUCT(VIA, 0x0428)
+#define HDA_CODEC_VT1718S_1	HDA_CODEC_CONSTRUCT(VIA, 0x4428)
+#define HDA_CODEC_VT1812	HDA_CODEC_CONSTRUCT(VIA, 0x0448)
+#define HDA_CODEC_VT1818S	HDA_CODEC_CONSTRUCT(VIA, 0x0440)
+#define HDA_CODEC_VT1828S	HDA_CODEC_CONSTRUCT(VIA, 0x4441)
+#define HDA_CODEC_VT2002P_0	HDA_CODEC_CONSTRUCT(VIA, 0x0438)
+#define HDA_CODEC_VT2002P_1	HDA_CODEC_CONSTRUCT(VIA, 0x4438)
+#define HDA_CODEC_VT2020	HDA_CODEC_CONSTRUCT(VIA, 0x0441)
 #define HDA_CODEC_VTXXXX	HDA_CODEC_CONSTRUCT(VIA, 0xffff)
 
 /* ATI */
@@ -786,6 +796,7 @@ static const struct {
 #define HDA_CODEC_INTELG45_2	HDA_CODEC_CONSTRUCT(INTEL, 0x2802)
 #define HDA_CODEC_INTELG45_3	HDA_CODEC_CONSTRUCT(INTEL, 0x2803)
 #define HDA_CODEC_INTELG45_4	HDA_CODEC_CONSTRUCT(INTEL, 0x29fb)
+#define HDA_CODEC_INTELQ57	HDA_CODEC_CONSTRUCT(INTEL, 0x0054)
 #define HDA_CODEC_INTELXXXX	HDA_CODEC_CONSTRUCT(INTEL, 0xffff)
 
 /* Codecs */
@@ -917,6 +928,16 @@ static const struct {
 	{ HDA_CODEC_VT1702_5, "VIA VT1702_5" },
 	{ HDA_CODEC_VT1702_6, "VIA VT1702_6" },
 	{ HDA_CODEC_VT1702_7, "VIA VT1702_7" },
+	{ HDA_CODEC_VT1716S_0, "VIA VT1716S_0" },
+	{ HDA_CODEC_VT1716S_1, "VIA VT1716S_1" },
+	{ HDA_CODEC_VT1718S_0, "VIA VT1718S_0" },
+	{ HDA_CODEC_VT1718S_1, "VIA VT1718S_1" },
+	{ HDA_CODEC_VT1812, "VIA VT1812" },
+	{ HDA_CODEC_VT1818S, "VIA VT1818S" },
+	{ HDA_CODEC_VT1828S, "VIA VT1828S" },
+	{ HDA_CODEC_VT2002P_0, "VIA VT2002P_0" },
+	{ HDA_CODEC_VT2002P_1, "VIA VT2002P_1" },
+	{ HDA_CODEC_VT2020, "VIA VT2020" },
 	{ HDA_CODEC_ATIRS600_1,"ATI RS600 HDMI" },
 	{ HDA_CODEC_ATIRS600_2,"ATI RS600 HDMI" },
 	{ HDA_CODEC_ATIRS690,  "ATI RS690/780 HDMI" },
@@ -930,6 +951,7 @@ static const struct {
 	{ HDA_CODEC_INTELG45_2, "Intel G45 HDMI" },
 	{ HDA_CODEC_INTELG45_3, "Intel G45 HDMI" },
 	{ HDA_CODEC_INTELG45_4, "Intel G45 HDMI" },
+	{ HDA_CODEC_INTELQ57, "Intel Q57 HDMI" },
 	{ HDA_CODEC_SII1390,   "Silicon Image SiI1390 HDMI" },
 	{ HDA_CODEC_SII1392,   "Silicon Image SiI1392 HDMI" },
 	/* Unknown codec */

From 25cf40cbc97ce161e98d10e3d0a4f6581f7a6b8b Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Mon, 23 Nov 2009 09:44:08 +0000
Subject: [PATCH 0650/2592] MFC: r199320

Fix grammar.
---
 lib/libc/locale/nl_langinfo.3 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libc/locale/nl_langinfo.3 b/lib/libc/locale/nl_langinfo.3
index 8de168206c2..789cac24fd1 100644
--- a/lib/libc/locale/nl_langinfo.3
+++ b/lib/libc/locale/nl_langinfo.3
@@ -53,7 +53,7 @@ with a category corresponding to the category of
 or to the
 category
 .Dv LC_ALL ,
-may overwrite buffer pointed by the return value.
+may overwrite the buffer pointed to by the return value.
 .Sh RETURN VALUES
 In a locale where langinfo data is not defined,
 .Fn nl_langinfo

From fbd6bbe74b0d13372c1b8a4a72aaa9a3e8d81bb8 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Mon, 23 Nov 2009 17:54:57 +0000
Subject: [PATCH 0651/2592] MFC r199321: Disable PortMultiplier Async
 Notifications for time of ports reset. They are useless at that time, but
 confuse Marvell AHCI.

Add quirk for SiI57XX Port Multipliers, to hide extra port.
---
 sys/cam/ata/ata_pmp.c | 45 +++++++++++++++++++++++++++++++------------
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c
index ea387909b11..1aa68397e6a 100644
--- a/sys/cam/ata/ata_pmp.c
+++ b/sys/cam/ata/ata_pmp.c
@@ -63,11 +63,12 @@ __FBSDID("$FreeBSD$");
 typedef enum {
 	PMP_STATE_NORMAL,
 	PMP_STATE_PORTS,
-	PMP_STATE_CONFIG,
+	PMP_STATE_PRECONFIG,
 	PMP_STATE_RESET,
 	PMP_STATE_CONNECT,
 	PMP_STATE_CHECK,
 	PMP_STATE_CLEAR,
+	PMP_STATE_CONFIG,
 	PMP_STATE_SCAN
 } pmp_state;
 
@@ -436,7 +437,7 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb)
 		      pmp_default_timeout * 1000);
 		ata_pm_read_cmd(ataio, 2, 15);
 		break;
-	case PMP_STATE_CONFIG:
+	case PMP_STATE_PRECONFIG:
 		cam_fill_ataio(ataio,
 		      pmp_retry_count,
 		      pmpdone,
@@ -445,7 +446,7 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb)
 		      /*data_ptr*/NULL,
 		      /*dxfer_len*/0,
 		      pmp_default_timeout * 1000);
-		ata_pm_write_cmd(ataio, 0x60, 15, 0xf);
+		ata_pm_write_cmd(ataio, 0x60, 15, 0x0);
 		break;
 	case PMP_STATE_RESET:
 		cam_fill_ataio(ataio,
@@ -495,6 +496,17 @@ printf("PM RESET %d%s\n", softc->pm_step,
 		      pmp_default_timeout * 1000);
 		ata_pm_write_cmd(ataio, 1, softc->pm_step, 0xFFFFFFFF);
 		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;
 	default:
 		break;
 	}
@@ -554,24 +566,29 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb)
 		    (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.
+		/* This PMP 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.
+		/* This PMP 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;
+		/* These PMPs declare one more port then actually have,
+		 * for configuration purposes. Hide it for now. */
+		if (softc->pm_pid == 0x57231095 || softc->pm_pid == 0x57331095 ||
+		    softc->pm_pid == 0x57341095 || softc->pm_pid == 0x57441095)
+			softc->pm_ports--;
 		printf("PM ports: %d\n", softc->pm_ports);
-		softc->state = PMP_STATE_CONFIG;
+		softc->state = PMP_STATE_PRECONFIG;
 		xpt_release_ccb(done_ccb);
 		xpt_schedule(periph, priority);
 		return;
-	case PMP_STATE_CONFIG:
+	case PMP_STATE_PRECONFIG:
 		softc->pm_step = 0;
 		softc->state = PMP_STATE_RESET;
 		softc->reset |= ~softc->found;
@@ -658,11 +675,15 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb)
 		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 (softc->found) {
+		if (softc->pm_step >= softc->pm_ports) {
+			softc->state = PMP_STATE_CONFIG;
+			softc->pm_step = 0;
+		}
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
+	case PMP_STATE_CONFIG:
+		if (softc->found) {
 			softc->pm_step = 0;
 			softc->state = PMP_STATE_SCAN;
 			work_ccb = xpt_alloc_ccb_nowait();

From 80f7b7c39e2da3b5c991e1752f18af328d1a0737 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Tue, 24 Nov 2009 03:17:00 +0000
Subject: [PATCH 0652/2592] MFC r198338: 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 374a76c18650045b3e4e0d0c9b088e76d93cbecc Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Tue, 24 Nov 2009 03:23:40 +0000
Subject: [PATCH 0653/2592] MFC r198450: 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 97d630ed47d69c7b159b7dd34b4c35885911d665 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Tue, 24 Nov 2009 03:28:35 +0000
Subject: [PATCH 0654/2592] MFC r198452: 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 cec3cd6c891..937f2f9e93b 100644
--- a/sys/ia64/conf/GENERIC
+++ b/sys/ia64/conf/GENERIC
@@ -37,13 +37,14 @@ options 	INET6		# IPv6 communications protocols
 options 	INVARIANTS	# Enable calls of extra sanity checking
 options 	INVARIANT_SUPPORT # required by INVARIANTS
 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
@@ -60,7 +61,7 @@ options 	UFS_ACL		# Support for access control lists
 options 	UFS_DIRHASH	# Hash-based directory lookup scheme
 options 	UFS_GJOURNAL	# Enable gjournal-based UFS journaling
 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 0d5340f69737c1b3059f2b242f97fa1fec8f2f24 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Tue, 24 Nov 2009 03:32:42 +0000
Subject: [PATCH 0655/2592] MFC r198733: Reimplement the lazy FP context
 switching... ...This change fixes the high FP inconsistency panics.

---
 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 706d64efce8..ad9d8e5ce57 100644
--- a/sys/conf/files.ia64
+++ b/sys/conf/files.ia64
@@ -85,6 +85,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 67ca3c28c49..5a109701922 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -1467,81 +1467,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 564da3e7b424bb1e4493e606cff0b581611f00bb Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Tue, 24 Nov 2009 03:38:42 +0000
Subject: [PATCH 0656/2592] MFC r199274, r199284: Fix an obvious panic by not
 casting from a pointer that is 4-bytes alignment to a type that needs 8-byte
 alignment, and thus causing misaligned memory references.

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

diff --git a/sys/nfsserver/nfs_fha.c b/sys/nfsserver/nfs_fha.c
index 901a0ce512c..0469e4a1880 100644
--- a/sys/nfsserver/nfs_fha.c
+++ b/sys/nfsserver/nfs_fha.c
@@ -206,7 +206,7 @@ fha_extract_info(struct svc_req *req, struct fha_info *i)
 	if (error)
 		goto out;
 
-	i->fh = *(const u_int64_t *)(fh.fh_generic.fh_fid.fid_data);
+	bcopy(fh.fh_generic.fh_fid.fid_data, &i->fh, sizeof(i->fh));
 
 	/* Content ourselves with zero offset for all but reads. */
 	if (procnum != NFSPROC_READ)

From 5f0993cb4006b06a0690bdfd774a20e38e61f2d4 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 24 Nov 2009 09:10:43 +0000
Subject: [PATCH 0657/2592] MFC r199535: Tune CAM ATA kernel options a bit.
 Move PMP support from da to scbus and add ada device option, according to man
 page.

---
 sys/conf/files | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/conf/files b/sys/conf/files
index 0c60646728b..9c6b071546f 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -112,12 +112,12 @@ cam/cam_sim.c			optional scbus
 cam/cam_xpt.c			optional scbus
 cam/ata/ata_all.c		optional scbus
 cam/ata/ata_xpt.c		optional scbus
+cam/ata/ata_pmp.c		optional scbus
 cam/scsi/scsi_xpt.c		optional scbus
 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/ata/ata_da.c		optional ada | 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

From e820e8fbd010d3214d02c6764e789c4bb9de34aa Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 24 Nov 2009 09:13:15 +0000
Subject: [PATCH 0658/2592] MFC r199532: Add ada(4) man page.

---
 share/man/man4/Makefile |   1 +
 share/man/man4/ada.4    | 138 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+)
 create mode 100644 share/man/man4/ada.4

diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 8063f4dafe5..c46f4b9c30a 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -15,6 +15,7 @@ MAN=	aac.4 \
 	${_acpi_toshiba.4} \
 	acpi_video.4 \
 	${_acpi_wmi.4} \
+	ada.4 \
 	adv.4 \
 	adw.4 \
 	ae.4 \
diff --git a/share/man/man4/ada.4 b/share/man/man4/ada.4
new file mode 100644
index 00000000000..8d2cf0e277f
--- /dev/null
+++ b/share/man/man4/ada.4
@@ -0,0 +1,138 @@
+.\" 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.
+.\"
+.\" 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 November 19, 2009
+.Dt ADA 4
+.Os
+.Sh NAME
+.Nm ada
+.Nd ATA Direct Access device driver
+.Sh SYNOPSIS
+.Cd device ada
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for direct access devices, implementing
+.Tn ATA
+command protocol, that are attached to the system through a host adapter
+supported by CAM subsystem.
+.Pp
+Host adapter must also be separately configured into the system before a
+.Tn ATA
+direct access device can be configured.
+.Sh COMMAND QUEUING
+Command queueing allows the device to process multiple transactions
+concurrently, often re-ordering them to reduce the number and length of
+seeks.
+.Tn ATA
+defines two types of queueing:
+.Tn TCQ (Tagged Command Queueing, PATA legacy)
+and
+.Tn NCQ (Native Command Queueing, SATA).
+The
+.Nm
+device driver takes full advantage of the NCQ, when supported.
+To ensure that transactions to distant portions of the media,
+which may be deferred indefinitely by servicing requests nearer the current
+head position, are completed in a timely fashion, an ordered
+transaction is sent every 7 seconds during continuous device operation.
+.Sh CACHE EFFECTS
+Many direct access devices are equipped with read and/or write caches.
+Parameters affecting the device's cache are reported in device IDENTIFY data
+and can be examined and modified via the
+.Xr camcontrol 8
+utility.
+.Pp
+The read cache is used to store data from device-initiated read ahead
+operations as well as frequently used data.
+The read cache is transparent
+to the user and can be enabled without any adverse effect.
+Most devices
+with a read cache come from the factory with it enabled.
+.Pp
+The write cache can greatly decrease the latency of write operations
+and allows the device to reorganize writes to increase efficiency and
+performance.
+This performance gain comes at a price.
+Should the device
+lose power while its cache contains uncommitted write operations, these
+writes will be lost.
+The effect of a loss of write transactions on
+a file system is non-deterministic and can cause corruption.
+Most
+devices age write transactions to limit vulnerability to a few transactions
+recently reported as complete, but it is none-the-less recommended that
+systems with write cache enabled devices reside on an Uninterruptible
+Power Supply (UPS).
+The
+.Nm
+device driver ensures that the cache and media are synchronized upon
+final close of the device or an unexpected shutdown (panic) event.
+This ensures that it is safe to disconnect power once the operating system
+has reported that it has halted.
+.Sh SYSCTL VARIABLES
+The following variables are available as both
+.Xr sysctl 8
+variables and
+.Xr loader 8
+tunables:
+.Bl -tag -width 12
+.It kern.cam.ada.retry_count
+.Pp
+This variable determines how many times the
+.Nm
+driver will retry a READ or WRITE command.
+This does not affect the number of retries used during probe time or for
+the
+.Nm
+driver dump routine.
+This value currently defaults to 4.
+.It kern.cam.ada.default_timeout
+.Pp
+This variable determines how long the
+.Nm
+driver will wait before timing out an outstanding command.
+The units for this value are seconds, and the default is currently 30
+seconds.
+.El
+.Sh FILES
+.Bl -tag -width ".Pa /dev/ada*" -compact
+.It Pa /dev/ada*
+ATA device nodes
+.El
+.Sh SEE ALSO
+.Xr ahci 4 ,
+.Xr siis 4 ,
+.Xr ad 4
+.Xr da 4
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 8.0 .
+.Sh AUTHORS
+.An Alexander Motin Aq mav@FreeBSD.org .

From a37772e8b4c90beb6cf978f66bfe55e8993671e0 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 24 Nov 2009 09:16:47 +0000
Subject: [PATCH 0659/2592] MFC r199247: Remove part that HDMI is not
 implemented. It had different meaning and confuse users. Extend BUGS section.
 Add some supported chipsets.

---
 share/man/man4/snd_hda.4 | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/share/man/man4/snd_hda.4 b/share/man/man4/snd_hda.4
index dacc5146be7..4734f45f5c0 100644
--- a/share/man/man4/snd_hda.4
+++ b/share/man/man4/snd_hda.4
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 7, 2009
+.Dd November 13, 2009
 .Dt SND_HDA 4
 .Os
 .Sh NAME
@@ -59,7 +59,7 @@ driver that allows the generic audio driver,
 to be used with this hardware.
 Only audio functions are supported by
 .Nm .
-Modem, HDMI and other possible functions are not implemented.
+Modem and other possible functions are not implemented.
 .Pp
 The
 .Nm
@@ -500,6 +500,14 @@ nVidia MCP68
 .It
 nVidia MCP69
 .It
+nVidia MCP73
+.It
+nVidia MCP78
+.It
+nVidia MCP79
+.It
+nVidia MCP89
+.It
 SiS 966
 .It
 VIA VT8251/8237A
@@ -626,5 +634,11 @@ trying to fix problem that way, make sure that problem is really exists
 and the PCM audio device you are using really corresponds to expected
 audio connector.
 .Pp
+Some vendors use non-standardized General Purpose I/O (GPIO) pins of codec
+to control external amplifiers. In some cases setting proper combination of
+GPIO bits may be needed to make sound work on specific device.
+.Pp
+HDMI and DisplayPort audio may also require support from video driver.
+.Pp
 Due to OSS limitation multichannel (not multidevice) playback is not
 supported.

From c8cfdb0768ad1f985cb3201291fe3792110f9652 Mon Sep 17 00:00:00 2001
From: Alexander Leidinger 
Date: Tue, 24 Nov 2009 10:46:17 +0000
Subject: [PATCH 0660/2592] MFC r199351:   Fix small resource leak (memory).

  Reviewed by:        gad
---
 bin/ps/keyword.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bin/ps/keyword.c b/bin/ps/keyword.c
index ade8123a0da..f0b30092a69 100644
--- a/bin/ps/keyword.c
+++ b/bin/ps/keyword.c
@@ -330,6 +330,7 @@ findvar(char *p, int user, char **header)
 				errx(1, "malloc failed");
 			snprintf(realfmt, rflen, "%s=%s", v->alias, hp);
 			parsefmt(realfmt, user);
+			free(realfmt);
 		}
 		return ((VAR *)NULL);
 	}

From 8158a254e9e909e4acd50b5b915459c6a964f287 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Tue, 24 Nov 2009 20:04:31 +0000
Subject: [PATCH 0661/2592] MFC: r199442

Unroll copying of the registers in {g,s}et_mcontext() and limit it
to the set actually restored by tl0_ret() instead of using the whole
trapframe. Additionally skip %g7 as that register is used as the
userland TLS pointer.

PR:		140523
---
 sys/sparc64/sparc64/machdep.c | 62 +++++++++++++++++++++++++++++++----
 1 file changed, 56 insertions(+), 6 deletions(-)

diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 49a2bb1c94f..c1610659936 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -696,12 +696,39 @@ get_mcontext(struct thread *td, mcontext_t *mc, int flags)
 
 	tf = td->td_frame;
 	pcb = td->td_pcb;
-	bcopy(tf, mc, sizeof(*tf));
+	/*
+	 * Copy the registers which will be restored by tl0_ret() from the
+	 * trapframe.
+	 * Note that we skip %g7 which is used as the userland TLS register
+	 * and %wstate.
+	 */
+	mc->mc_flags = _MC_VERSION;
+	mc->mc_global[1] = tf->tf_global[1];
+	mc->mc_global[2] = tf->tf_global[2];
+	mc->mc_global[3] = tf->tf_global[3];
+	mc->mc_global[4] = tf->tf_global[4];
+	mc->mc_global[5] = tf->tf_global[5];
+	mc->mc_global[6] = tf->tf_global[6];
 	if (flags & GET_MC_CLEAR_RET) {
 		mc->mc_out[0] = 0;
 		mc->mc_out[1] = 0;
+	} else {
+		mc->mc_out[0] = tf->tf_out[0];
+		mc->mc_out[1] = tf->tf_out[1];
 	}
-	mc->mc_flags = _MC_VERSION;
+	mc->mc_out[2] = tf->tf_out[2];
+	mc->mc_out[3] = tf->tf_out[3];
+	mc->mc_out[4] = tf->tf_out[4];
+	mc->mc_out[5] = tf->tf_out[5];
+	mc->mc_out[6] = tf->tf_out[6];
+	mc->mc_out[7] = tf->tf_out[7];
+	mc->mc_fprs = tf->tf_fprs;
+	mc->mc_fsr = tf->tf_fsr;
+	mc->mc_gsr = tf->tf_gsr;
+	mc->mc_tnpc = tf->tf_tnpc;
+	mc->mc_tpc = tf->tf_tpc;
+	mc->mc_tstate = tf->tf_tstate;
+	mc->mc_y = tf->tf_y;
 	critical_enter();
 	if ((tf->tf_fprs & FPRS_FEF) != 0) {
 		savefpctx(pcb->pcb_ufp);
@@ -721,7 +748,6 @@ set_mcontext(struct thread *td, const mcontext_t *mc)
 {
 	struct trapframe *tf;
 	struct pcb *pcb;
-	uint64_t wstate;
 
 	if (!TSTATE_SECURE(mc->mc_tstate) ||
 	    (mc->mc_flags & ((1L << _MC_VERSION_BITS) - 1)) != _MC_VERSION)
@@ -730,9 +756,33 @@ set_mcontext(struct thread *td, const mcontext_t *mc)
 	pcb = td->td_pcb;
 	/* Make sure the windows are spilled first. */
 	flushw();
-	wstate = tf->tf_wstate;
-	bcopy(mc, tf, sizeof(*tf));
-	tf->tf_wstate = wstate;
+	/*
+	 * Copy the registers which will be restored by tl0_ret() to the
+	 * trapframe.
+	 * Note that we skip %g7 which is used as the userland TLS register
+	 * and %wstate.
+	 */
+	tf->tf_global[1] = mc->mc_global[1];
+	tf->tf_global[2] = mc->mc_global[2];
+	tf->tf_global[3] = mc->mc_global[3];
+	tf->tf_global[4] = mc->mc_global[4];
+	tf->tf_global[5] = mc->mc_global[5];
+	tf->tf_global[6] = mc->mc_global[6];
+	tf->tf_out[0] = mc->mc_out[0];
+	tf->tf_out[1] = mc->mc_out[1];
+	tf->tf_out[2] = mc->mc_out[2];
+	tf->tf_out[3] = mc->mc_out[3];
+	tf->tf_out[4] = mc->mc_out[4];
+	tf->tf_out[5] = mc->mc_out[5];
+	tf->tf_out[6] = mc->mc_out[6];
+	tf->tf_out[7] = mc->mc_out[7];
+	tf->tf_fprs = mc->mc_fprs;
+	tf->tf_fsr = mc->mc_fsr;
+	tf->tf_gsr = mc->mc_gsr;
+	tf->tf_tnpc = mc->mc_tnpc;
+	tf->tf_tpc = mc->mc_tpc;
+	tf->tf_tstate = mc->mc_tstate;
+	tf->tf_y = mc->mc_y;
 	if ((mc->mc_fprs & FPRS_FEF) != 0) {
 		tf->tf_fprs = 0;
 		bcopy(mc->mc_fp, pcb->pcb_ufp, sizeof(pcb->pcb_ufp));

From 0039b950197a9fa968f3fe9d20c9e8d7e6b5922d Mon Sep 17 00:00:00 2001
From: Kip Macy 
Date: Wed, 25 Nov 2009 01:50:17 +0000
Subject: [PATCH 0662/2592] MFC core dump support

---
 sys/dev/xen/blkfront/blkfront.c | 89 ++++++++++++++++++++++++++++++++-
 1 file changed, 87 insertions(+), 2 deletions(-)

diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c
index f73c81239f4..bd82eed9dd2 100644
--- a/sys/dev/xen/blkfront/blkfront.c
+++ b/sys/dev/xen/blkfront/blkfront.c
@@ -16,7 +16,9 @@
  */
 
 /*
- * XenoBSD block device driver
+ * XenBSD block device driver
+ *
+ * Copyright (c) 2009 Frank Suchomel, Citrix
  */
 
 #include 
@@ -122,6 +124,10 @@ static int blkif_ioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct
 static int blkif_queue_request(struct bio *bp);
 static void xb_strategy(struct bio *bp);
 
+// In order to quiesce the device during kernel dumps, outstanding requests to
+// DOM0 for disk reads/writes need to be accounted for.
+static	int	blkif_queued_requests;
+static	int	xb_dump(void *, void *, vm_offset_t, off_t, size_t);
 
 
 /* XXX move to xb_vbd.c when VBD update support is added */
@@ -231,6 +237,7 @@ xlvbd_add(device_t dev, blkif_sector_t capacity,
 	sc->xb_disk->d_close = blkif_close;
 	sc->xb_disk->d_ioctl = blkif_ioctl;
 	sc->xb_disk->d_strategy = xb_strategy;
+	sc->xb_disk->d_dump = xb_dump;
 	sc->xb_disk->d_name = name;
 	sc->xb_disk->d_drv1 = sc;
 	sc->xb_disk->d_sectorsize = sector_size;
@@ -286,9 +293,10 @@ xb_strategy(struct bio *bp)
 	 * Place it in the queue of disk activities for this disk
 	 */
 	mtx_lock(&blkif_io_lock);
-	bioq_disksort(&sc->xb_bioq, bp);
 
+	bioq_disksort(&sc->xb_bioq, bp);
 	xb_startio(sc);
+
 	mtx_unlock(&blkif_io_lock);
 	return;
 
@@ -301,6 +309,81 @@ xb_strategy(struct bio *bp)
 	return;
 }
 
+static void xb_quiesce(struct blkfront_info *info);
+// Quiesce the disk writes for a dump file before allowing the next buffer.
+static void
+xb_quiesce(struct blkfront_info *info)
+{
+	int		mtd;
+
+	// While there are outstanding requests
+	while (blkif_queued_requests) {
+		RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, mtd);
+		if (mtd) {
+			// Recieved request completions, update queue.
+			blkif_int(info);
+		}
+		if (blkif_queued_requests) {
+			// Still pending requests, wait for the disk i/o to complete
+			HYPERVISOR_yield();
+		}
+	}
+}
+
+// Some bio structures for dumping core
+#define DUMP_BIO_NO 16				// 16 * 4KB = 64KB dump block
+static	struct bio		xb_dump_bp[DUMP_BIO_NO];
+
+// Kernel dump function for a paravirtualized disk device
+static int
+xb_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset,
+        size_t length)
+{
+			int				 sbp;
+  			int			     mbp;
+			size_t			 chunk;
+	struct	disk   			*dp = arg;
+	struct	xb_softc		*sc = (struct xb_softc *) dp->d_drv1;
+	        int	    		 rc = 0;
+
+	xb_quiesce(sc->xb_info);		// All quiet on the western front.
+	if (length > 0) {
+		// If this lock is held, then this module is failing, and a successful
+		// kernel dump is highly unlikely anyway.
+		mtx_lock(&blkif_io_lock);
+		// Split the 64KB block into 16 4KB blocks
+		for (sbp=0; length>0 && sbp PAGE_SIZE ? PAGE_SIZE : length;
+			xb_dump_bp[sbp].bio_disk   = dp;
+			xb_dump_bp[sbp].bio_pblkno = offset / dp->d_sectorsize;
+			xb_dump_bp[sbp].bio_bcount = chunk;
+			xb_dump_bp[sbp].bio_resid  = chunk;
+			xb_dump_bp[sbp].bio_data   = virtual;
+			xb_dump_bp[sbp].bio_cmd    = BIO_WRITE;
+			xb_dump_bp[sbp].bio_done   = NULL;
+
+			bioq_disksort(&sc->xb_bioq, &xb_dump_bp[sbp]);
+
+			length -= chunk;
+			offset += chunk;
+			virtual = (char *) virtual + chunk;
+		}
+		// Tell DOM0 to do the I/O
+		xb_startio(sc);
+		mtx_unlock(&blkif_io_lock);
+
+		// Must wait for the completion: the dump routine reuses the same
+		//                               16 x 4KB buffer space.
+		xb_quiesce(sc->xb_info);	// All quite on the eastern front
+		// If there were any errors, bail out...
+		for (mbp=0; mbp RING_SIZE", nfree));
 	info->shadow_free = info->shadow[nfree].req.id;
 	info->shadow[nfree].req.id = 0x0fffffee; /* debug */
+	atomic_add_int(&blkif_queued_requests, 1);
 	return nfree;
 }
 
@@ -655,6 +739,7 @@ ADD_ID_TO_FREELIST(struct blkfront_info *info, unsigned long id)
 	info->shadow[id].req.id  = info->shadow_free;
 	info->shadow[id].request = 0;
 	info->shadow_free = id;
+	atomic_subtract_int(&blkif_queued_requests, 1);
 }
 
 static inline void 

From 7d326ccdfc89e7d25f33ad1246de582e468bef00 Mon Sep 17 00:00:00 2001
From: Kip Macy 
Date: Wed, 25 Nov 2009 01:51:07 +0000
Subject: [PATCH 0663/2592] remove gratuitous comment

---
 sys/dev/xen/console/console.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c
index 68bb0aecf85..44a4fb356a8 100644
--- a/sys/dev/xen/console/console.c
+++ b/sys/dev/xen/console/console.c
@@ -152,7 +152,6 @@ xccncheckc(struct consdev *dev)
 	
 	CN_LOCK(cn_mtx);
 	if ((rp - rc)) {
-		/* if (kdb_active) printf("%s:%d\n", __func__, __LINE__); */
 		/* we need to return only one char */
 		ret = (int)rbuf[RBUF_MASK(rc)];
 		rc++;

From 4956a0d10fb2a6eeb02e2f22d9ef9c9eda95f30f Mon Sep 17 00:00:00 2001
From: Kip Macy 
Date: Wed, 25 Nov 2009 01:52:36 +0000
Subject: [PATCH 0664/2592] MFC xen pmap updates and eflags fixes

---
 sys/i386/i386/vm_machdep.c |   9 +-
 sys/i386/include/cpufunc.h |  20 ++--
 sys/i386/xen/pmap.c        | 186 +++++++++++++++++++------------------
 sys/i386/xen/xen_machdep.c |  44 ++++++---
 4 files changed, 141 insertions(+), 118 deletions(-)

diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index b6fd4b6067c..c68e9f9087b 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 
@@ -270,11 +271,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 +443,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/pmap.c b/sys/i386/xen/pmap.c
index 7667142c5d7..5de5a32ab7b 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -223,6 +223,8 @@ static uma_zone_t pdptzone;
 #endif
 #endif
 
+static int pat_works;			/* Is page attribute table sane? */
+
 /*
  * Data for the pv entry allocation mechanism
  */
@@ -277,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,
@@ -311,6 +313,7 @@ static vm_offset_t pmap_kmem_choose(vm_offset_t addr);
 static boolean_t pmap_is_prefaultable_locked(pmap_t pmap, vm_offset_t addr);
 static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode);
 
+static __inline void pagezero(void *page);
 
 #if defined(PAE) && !defined(XEN)
 static void *pmap_pdpt_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait);
@@ -328,22 +331,6 @@ CTASSERT(KERNBASE % (1 << 24) == 0);
 
 
 
-static __inline void
-pagezero(void *page)
-{
-#if defined(I686_CPU)
-	if (cpu_class == CPUCLASS_686) {
-#if defined(CPU_ENABLE_SSE)
-		if (cpu_feature & CPUID_SSE2)
-			sse2_pagezero(page);
-		else
-#endif
-			i686_pagezero(page);
-	} else
-#endif
-		bzero(page, PAGE_SIZE);
-}
-
 void 
 pd_set(struct pmap *pmap, int ptepindex, vm_paddr_t val, int type)
 {
@@ -529,33 +516,36 @@ pmap_init_pat(void)
 	if (!(cpu_feature & CPUID_PAT))
 		return;
 
-#ifdef PAT_WORKS
-	/*
-	 * Leave the indices 0-3 at the default of WB, WT, UC, and UC-.
-	 * Program 4 and 5 as WP and WC.
-	 * Leave 6 and 7 as UC and UC-.
-	 */
-	pat_msr = rdmsr(MSR_PAT);
-	pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5));
-	pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) |
-	    PAT_VALUE(5, PAT_WRITE_COMBINING);
-#else
-	/*
-	 * Due to some Intel errata, we can only safely use the lower 4
-	 * PAT entries.  Thus, just replace PAT Index 2 with WC instead
-	 * of UC-.
-	 *
-	 *   Intel Pentium III Processor Specification Update
-	 * Errata E.27 (Upper Four PAT Entries Not Usable With Mode B
-	 * or Mode C Paging)
-	 *
-	 *   Intel Pentium IV  Processor Specification Update
-	 * Errata N46 (PAT Index MSB May Be Calculated Incorrectly)
-	 */
-	pat_msr = rdmsr(MSR_PAT);
-	pat_msr &= ~PAT_MASK(2);
-	pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING);
-#endif
+	if (cpu_vendor_id != CPU_VENDOR_INTEL ||
+	    (CPUID_TO_FAMILY(cpu_id) == 6 && CPUID_TO_MODEL(cpu_id) >= 0xe)) {
+		/*
+		 * Leave the indices 0-3 at the default of WB, WT, UC, and UC-.
+		 * Program 4 and 5 as WP and WC.
+		 * Leave 6 and 7 as UC and UC-.
+		 */
+		pat_msr = rdmsr(MSR_PAT);
+		pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5));
+		pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) |
+		    PAT_VALUE(5, PAT_WRITE_COMBINING);
+		pat_works = 1;
+	} else {
+		/*
+		 * Due to some Intel errata, we can only safely use the lower 4
+		 * PAT entries.  Thus, just replace PAT Index 2 with WC instead
+		 * of UC-.
+		 *
+		 *   Intel Pentium III Processor Specification Update
+		 * Errata E.27 (Upper Four PAT Entries Not Usable With Mode B
+		 * or Mode C Paging)
+		 *
+		 *   Intel Pentium IV  Processor Specification Update
+		 * Errata N46 (PAT Index MSB May Be Calculated Incorrectly)
+		 */
+		pat_msr = rdmsr(MSR_PAT);
+		pat_msr &= ~PAT_MASK(2);
+		pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING);
+		pat_works = 0;
+	}
 	wrmsr(MSR_PAT, pat_msr);
 }
 
@@ -784,44 +774,48 @@ pmap_cache_bits(int mode, boolean_t is_pde)
 	}
 	
 	/* Map the caching mode to a PAT index. */
-	switch (mode) {
-#ifdef PAT_WORKS
-	case PAT_UNCACHEABLE:
-		pat_index = 3;
-		break;
-	case PAT_WRITE_THROUGH:
-		pat_index = 1;
-		break;
-	case PAT_WRITE_BACK:
-		pat_index = 0;
-		break;
-	case PAT_UNCACHED:
-		pat_index = 2;
-		break;
-	case PAT_WRITE_COMBINING:
-		pat_index = 5;
-		break;
-	case PAT_WRITE_PROTECTED:
-		pat_index = 4;
-		break;
-#else
-	case PAT_UNCACHED:
-	case PAT_UNCACHEABLE:
-	case PAT_WRITE_PROTECTED:
-		pat_index = 3;
-		break;
-	case PAT_WRITE_THROUGH:
-		pat_index = 1;
-		break;
-	case PAT_WRITE_BACK:
-		pat_index = 0;
-		break;
-	case PAT_WRITE_COMBINING:
-		pat_index = 2;
-		break;
-#endif
-	default:
-		panic("Unknown caching mode %d\n", mode);
+	if (pat_works) {
+		switch (mode) {
+			case PAT_UNCACHEABLE:
+				pat_index = 3;
+				break;
+			case PAT_WRITE_THROUGH:
+				pat_index = 1;
+				break;
+			case PAT_WRITE_BACK:
+				pat_index = 0;
+				break;
+			case PAT_UNCACHED:
+				pat_index = 2;
+				break;
+			case PAT_WRITE_COMBINING:
+				pat_index = 5;
+				break;
+			case PAT_WRITE_PROTECTED:
+				pat_index = 4;
+				break;
+			default:
+				panic("Unknown caching mode %d\n", mode);
+		}
+	} else {
+		switch (mode) {
+			case PAT_UNCACHED:
+			case PAT_UNCACHEABLE:
+			case PAT_WRITE_PROTECTED:
+				pat_index = 3;
+				break;
+			case PAT_WRITE_THROUGH:
+				pat_index = 1;
+				break;
+			case PAT_WRITE_BACK:
+				pat_index = 0;
+				break;
+			case PAT_WRITE_COMBINING:
+				pat_index = 2;
+				break;
+			default:
+				panic("Unknown caching mode %d\n", mode);
+		}
 	}	
 
 	/* Map the 3-bit index value into the PAT, PCD, and PWT bits. */
@@ -1735,7 +1729,7 @@ retry:
  * Deal with a SMP shootdown of other users of the pmap that we are
  * trying to dispose of.  This can be a bit hairy.
  */
-static u_int *lazymask;
+static cpumask_t *lazymask;
 static u_int lazyptd;
 static volatile u_int lazywait;
 
@@ -1744,7 +1738,7 @@ void pmap_lazyfix_action(void);
 void
 pmap_lazyfix_action(void)
 {
-	u_int mymask = PCPU_GET(cpumask);
+	cpumask_t mymask = PCPU_GET(cpumask);
 
 #ifdef COUNT_IPIS
 	(*ipi_lazypmap_counts[PCPU_GET(cpuid)])++;
@@ -1756,7 +1750,7 @@ pmap_lazyfix_action(void)
 }
 
 static void
-pmap_lazyfix_self(u_int mymask)
+pmap_lazyfix_self(cpumask_t mymask)
 {
 
 	if (rcr3() == lazyptd)
@@ -1768,8 +1762,7 @@ pmap_lazyfix_self(u_int mymask)
 static void
 pmap_lazyfix(pmap_t pmap)
 {
-	u_int mymask;
-	u_int mask;
+	cpumask_t mymask, mask;
 	u_int spins;
 
 	while ((mask = pmap->pm_active) != 0) {
@@ -3110,7 +3103,7 @@ pmap_kenter_temporary(vm_paddr_t pa, int i)
 	vm_offset_t va;
 
 	va = (vm_offset_t)crashdumpmap + (i * PAGE_SIZE);
-	pmap_kenter(va, pa);
+	PT_SET_MA(va, (pa & ~PAGE_MASK) | PG_V | pgeflag);
 	invlpg(va);
 	return ((void *)crashdumpmap);
 }
@@ -3343,6 +3336,22 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
 	PMAP_UNLOCK(dst_pmap);
 }	
 
+static __inline void
+pagezero(void *page)
+{
+#if defined(I686_CPU)
+	if (cpu_class == CPUCLASS_686) {
+#if defined(CPU_ENABLE_SSE)
+		if (cpu_feature & CPUID_SSE2)
+			sse2_pagezero(page);
+		else
+#endif
+			i686_pagezero(page);
+	} else
+#endif
+		bzero(page, PAGE_SIZE);
+}
+
 /*
  *	pmap_zero_page zeros the specified hardware page by mapping 
  *	the page into KVM and using bzero to clear its contents.
@@ -4162,7 +4171,6 @@ pmap_activate(struct thread *td)
 	td->td_pcb->pcb_cr3 = cr3;
 	PT_UPDATES_FLUSH();
 	load_cr3(cr3);
-		
 	PCPU_SET(curpmap, pmap);
 	critical_exit();
 }
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 fa178c7b04652f85edcd77da64317b235a9a7bce Mon Sep 17 00:00:00 2001
From: Kip Macy 
Date: Wed, 25 Nov 2009 01:55:34 +0000
Subject: [PATCH 0665/2592] fix UP compilation

---
 sys/i386/include/xen/xen-os.h | 2 +-
 sys/i386/xen/locore.s         | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/sys/i386/include/xen/xen-os.h b/sys/i386/include/xen/xen-os.h
index dac071afce7..4aaeb58e9bb 100644
--- a/sys/i386/include/xen/xen-os.h
+++ b/sys/i386/include/xen/xen-os.h
@@ -34,10 +34,10 @@ void force_evtchn_callback(void);
 #include 
 #endif
 
+extern int gdtset;
 #ifdef SMP
 #include  /* XXX for pcpu.h */
 #include  /* XXX for PCPU_GET */
-extern int gdtset;
 static inline int 
 smp_processor_id(void)  
 {
diff --git a/sys/i386/xen/locore.s b/sys/i386/xen/locore.s
index a2c4a8db7b7..95d2afae841 100644
--- a/sys/i386/xen/locore.s
+++ b/sys/i386/xen/locore.s
@@ -148,9 +148,7 @@ IdlePDPT:	.long	0		/* phys addr of kernel PDPT */
 	.globl	KPTphys
 #endif
 KPTphys:	.long	0		/* phys addr of kernel page tables */
-#ifdef SMP
 	.globl	gdtset
-#endif
 gdtset:		.long	0		/* GDT is valid */	
 
 	.globl	proc0kstack

From c6a4ef661d28bf458dcbb2bbf26661312da1aadc Mon Sep 17 00:00:00 2001
From: Peter Pentchev 
Date: Wed, 25 Nov 2009 10:52:07 +0000
Subject: [PATCH 0666/2592] Merge rev. 199180 to 8.x-STABLE, the change to
 isblank(3): Fix the grammar as in the PR, and then some.

PR:             140454
Submitted by:   Jeremy Huddleston 
---
 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 73d10566b3cd117b4d3cf1d363fdf27e651dc347 Mon Sep 17 00:00:00 2001
From: Peter Pentchev 
Date: Wed, 25 Nov 2009 11:23:44 +0000
Subject: [PATCH 0667/2592] Merge rev. 199181 to 8.x-STABLE:   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 
---
 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 6772a8e0d04c4815dc40585eca5a697cb21cb6b9 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Wed, 25 Nov 2009 14:54:58 +0000
Subject: [PATCH 0668/2592] MFC r199491:  Add WorldB SKU.

---
 sys/dev/ath/ath_hal/ah_regdomain.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/sys/dev/ath/ath_hal/ah_regdomain.c b/sys/dev/ath/ath_hal/ah_regdomain.c
index 814b9ab335d..501ee354030 100644
--- a/sys/dev/ath/ath_hal/ah_regdomain.c
+++ b/sys/dev/ath/ath_hal/ah_regdomain.c
@@ -170,6 +170,7 @@ enum {
 
 	WOR9_WORLD	= 0x69,		/* World9 (WO9 SKU) */	
 	WORA_WORLD	= 0x6A,		/* WorldA (WOA SKU) */	
+	WORB_WORLD	= 0x6B,		/* WorldB (WOB SKU) */
 
 	MKK3_MKKB	= 0x80,		/* Japan UNI-1 even + MKKB */
 	MKK3_MKKA2	= 0x81,		/* Japan UNI-1 even + MKKA2 */
@@ -432,6 +433,7 @@ static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
 	{EU1_WORLD,	EU1_WORLD,	EU1_WORLD,	NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
 	{WOR9_WORLD,	WOR9_WORLD,	WOR9_WORLD,	DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
 	{WORA_WORLD,	WORA_WORLD,	WORA_WORLD,	DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+	{WORB_WORLD,	WORB_WORLD,	WORB_WORLD,	DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
 };
 
 /* 
@@ -1681,6 +1683,31 @@ static REG_DOMAIN regDomains[] = {
 				      WG1_2467_2467),
 	 .chan11g_turbo		= BM1(T3_2437_2437)},
 
+	{.regDmnEnum		= WORB_WORLD,
+	 .conformanceTestLimit	= NO_CTL,
+	 .dfsMask		= DFS_FCC3 | DFS_ETSI,
+	 .pscan			= PSCAN_WWR,
+	 .flags			= DISALLOW_ADHOC_11A,
+	 .chan11a		= BM4(W1_5260_5320,
+				      W1_5180_5240,
+				      W1_5745_5825,
+				      W1_5500_5700),
+	 .chan11b		= BM7(W1_2412_2412,
+				      W1_2437_2442,
+				      W1_2462_2462,
+				      W1_2472_2472,
+				      W1_2417_2432,
+				      W1_2447_2457,
+				      W1_2467_2467),
+	 .chan11g		= BM7(WG1_2412_2412,
+				      WG1_2437_2442,
+				      WG1_2462_2462,
+				      WG1_2472_2472,
+				      WG1_2417_2432,
+				      WG1_2447_2457,
+				      WG1_2467_2467),
+	 .chan11g_turbo		= BM1(T3_2437_2437)},
+
 	{.regDmnEnum		= NULL1,
 	 .conformanceTestLimit	= NO_CTL,
 	}

From f6b36bbd8a490fec1ca3e84349e40b7d0b7d66cb Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 25 Nov 2009 18:31:34 +0000
Subject: [PATCH 0669/2592] MFC: r198502

Sync with the other archs and wrap the prototype of in_cksum_skip(9)
in #ifdef _KERNEL.

Submitted by:	Ulrich Spoerlein
---
 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 70f426fe84a3eaf3825d03ac9c2eb75235127839 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 26 Nov 2009 08:29:02 +0000
Subject: [PATCH 0670/2592] MFC r199717: Do not attach JMicrons with single PCI
 function. They are not working as AHCI for some reason, even when declaring
 so. Let atajmicron configure them for us and provide PATA support.

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

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 2d21c0506e1..459aa64a465 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -254,6 +254,10 @@ ahci_probe(device_t dev)
 	for (i = 0; ahci_ids[i].id != 0; i++) {
 		if (ahci_ids[i].id == devid &&
 		    (valid || !(ahci_ids[i].quirks & AHCI_Q_NOFORCE))) {
+			/* Do not attach JMicrons with single PCI function. */
+			if (pci_get_vendor(dev) == 0x197b &&
+			    (pci_read_config(dev, 0xdf, 1) & 0x40) == 0)
+				return (ENXIO);
 			snprintf(buf, sizeof(buf), "%s AHCI SATA controller",
 			    ahci_ids[i].name);
 			device_set_desc_copy(dev, buf);

From 052c5232f5f1b4a85dfaa0b38aea7cb741a8ee09 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 26 Nov 2009 14:50:01 +0000
Subject: [PATCH 0671/2592] MFC r199749: Use only lower byte of sectors_intr
 IDENTIFY word as sector count. This fixes SET_MULTI error during boot on
 devices supporting less then 16 sectors per interrupt.

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

diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 22be3543c7d..03b10650b82 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -397,7 +397,7 @@ ad_init(device_t dev)
 
     /* use multiple sectors/interrupt if device supports it */
     if (ad_version(atadev->param.version_major)) {
-	int secsperint = max(1, min(atadev->param.sectors_intr, 16));
+	int secsperint = max(1, min(atadev->param.sectors_intr & 0xff, 16));
 
 	if (!ata_controlcmd(dev, ATA_SET_MULTI, 0, 0, secsperint))
 	    atadev->max_iosize = secsperint * DEV_BSIZE;

From 0264833689288e33ed4f102a01a27e84ef7eeea5 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 26 Nov 2009 14:56:58 +0000
Subject: [PATCH 0672/2592] MFC r199645, r199646: Fix Intel PATA UDMA timings
 setting, affecting write performance. Binary divider value 10 specified in
 datasheet is not a hex 0x10. UDMA2 should be 33/2 instead of 66/4, which is
 documented as reverved, UDMA4 should be 66/2 instead of 66/4, which is
 definitely wrong. Release over-agressive WDMA0 mode timings as close to spec
 as chip can.

---
 sys/dev/ata/chipsets/ata-intel.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c
index a19de8bec5c..add18d2d2a5 100644
--- a/sys/dev/ata/chipsets/ata-intel.c
+++ b/sys/dev/ata/chipsets/ata-intel.c
@@ -301,7 +301,7 @@ ata_intel_new_setmode(device_t dev, int mode)
     u_int32_t mask40 = 0, new40 = 0;
     u_int8_t mask44 = 0, new44 = 0;
     int error;
-    u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
+    u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23,
 			   0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
 
     mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
@@ -319,7 +319,7 @@ ata_intel_new_setmode(device_t dev, int mode)
 		      ata_mode2str(mode), ctlr->chip->text);
     if (!error) {
 	if (mode >= ATA_UDMA0) {
-	    u_int8_t utimings[] = { 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10 };
+	    u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
 
 	    pci_write_config(gparent, 0x48, reg48 | (0x0001 << devno), 2);
 	    pci_write_config(gparent, 0x4a,
@@ -331,7 +331,7 @@ ata_intel_new_setmode(device_t dev, int mode)
 	    pci_write_config(gparent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2);
 	}
 	reg54 |= 0x0400;
-	if (mode >= ATA_UDMA2)
+	if (mode >= ATA_UDMA3)
 	    reg54 |= (0x1 << devno);
 	else
 	    reg54 &= ~(0x1 << devno);

From 4fb5bc425904efd6adb58e51c70a5fec68c149dd Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 26 Nov 2009 15:11:19 +0000
Subject: [PATCH 0673/2592] MFC r199268, r199269, r199273: Core2Duo/Core2Quad
 CPUs are unable to control frequency of single CPU core, only pair of them.
 As result, both cores are running on highest one of requested frequencies,
 and that is reported by status register. Such behavior confuses frequency
 validation logic, as it runs on only one core, as SMP is not yet launched,
 making EIST completely unusable.

Disable frequency validation by default, for systems with more then one
CPU, until we can implement it properly. It looks like making more harm
now then benefits. Add 'hw.est.strict' loader tunable to control it.

PR:		amd64/140506
---
 sys/i386/cpufreq/est.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/sys/i386/cpufreq/est.c b/sys/i386/cpufreq/est.c
index 2c6fd2ce618..6a7b514a2c3 100644
--- a/sys/i386/cpufreq/est.c
+++ b/sys/i386/cpufreq/est.c
@@ -96,6 +96,8 @@ struct est_softc {
 
 static int msr_info_enabled = 0;
 TUNABLE_INT("hw.est.msr_info", &msr_info_enabled);
+static int strict = -1;
+TUNABLE_INT("hw.est.strict", &strict);
 
 /* Default bus clock value for Centrino processors. */
 #define INTEL_BUS_CLK		100
@@ -1025,6 +1027,9 @@ est_attach(device_t dev)
 	sc = device_get_softc(dev);
 	sc->dev = dev;
 
+	/* On SMP system we can't guarantie independent freq setting. */
+	if (strict == -1 && mp_ncpus > 1)
+		strict = 0;
 	/* Check CPU for supported settings. */
 	if (est_get_info(dev))
 		return (ENXIO);
@@ -1119,17 +1124,21 @@ est_acpi_info(device_t dev, freq_info **freqs)
 		 */
 		if (sets[i].freq > 0) {
 			error = est_set_id16(dev, sets[i].spec[0], 1);
-			if (error != 0) {
+			if (error != 0 && strict) {
 				if (bootverbose) 
 					device_printf(dev, "Invalid freq %u, "
 					    "ignored.\n", sets[i].freq);
-			} else {
-				table[j].freq = sets[i].freq;
-				table[j].volts = sets[i].volts;
-				table[j].id16 = sets[i].spec[0];
-				table[j].power = sets[i].power;
-				++j;
+				continue;
+			} else if (error != 0 && bootverbose) {
+				device_printf(dev, "Can't check freq %u, "
+				    "it may be invalid\n",
+				    sets[i].freq);
 			}
+			table[j].freq = sets[i].freq;
+			table[j].volts = sets[i].volts;
+			table[j].id16 = sets[i].spec[0];
+			table[j].power = sets[i].power;
+			++j;
 		}
 	}
 	/* restore saved setting */

From c68cd0c40d5ea35be16a0ccb4952349bc43a5a88 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 26 Nov 2009 15:16:03 +0000
Subject: [PATCH 0674/2592] MFC r199043: 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
---
 sys/dev/hptrr/hptrr_osm_bsd.c | 6 ++++++
 1 file changed, 6 insertions(+)

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 fe3bfc62e0fc6be44cf73b0c5d61843ff3ab965e Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Thu, 26 Nov 2009 15:22:42 +0000
Subject: [PATCH 0675/2592] MFC r199043: 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 ++++++++++-
 1 file changed, 10 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

From 0996e132aef9e4cc57e3db3b64ddd434d04a4c11 Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Thu, 26 Nov 2009 18:14:03 +0000
Subject: [PATCH 0676/2592] MFC r198491:

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 26593c36dace1b23152c3f3adc06a74a548ef512 Mon Sep 17 00:00:00 2001
From: Hiroki Sato 
Date: Thu, 26 Nov 2009 20:55:44 +0000
Subject: [PATCH 0677/2592] Add entries of Release Notes for 8.0R temporarily.

Reviewed by:	thompsa, linimon, and brd.
---
 .../doc/en_US.ISO8859-1/relnotes/article.sgml | 2760 ++++++++++++++---
 .../en_US.ISO8859-1/share/sgml/release.dsl    |   11 -
 release/doc/share/sgml/release.dsl            |   49 +-
 release/doc/share/sgml/release.ent            |   31 +-
 4 files changed, 2375 insertions(+), 476 deletions(-)

diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.sgml b/release/doc/en_US.ISO8859-1/relnotes/article.sgml
index 68db4f45e8a..76a6f29ffe5 100644
--- a/release/doc/en_US.ISO8859-1/relnotes/article.sgml
+++ b/release/doc/en_US.ISO8859-1/relnotes/article.sgml
@@ -4,11 +4,6 @@
 
 
 %release;
-
-
-
-
-
 ]>
 
 
@@ -57,7 +52,7 @@ Introduction This document contains the release notes for &os; - &release.current;. It + &release.current;. It describes recently added, changed, or deleted features of &os;. It also provides some notes on upgrading from previous versions of &os;. @@ -66,7 +61,7 @@ The &release.type; distribution to which these release notes apply represents the latest point along the &release.branch; development - branch since &release.branch; was created. Information regarding pre-built, binary + branch since &release.branch; was created. Information regarding pre-built, binary &release.type; distributions along this branch can be found at . @@ -87,7 +82,7 @@ This distribution of &os; &release.current; is a &release.type; distribution. It can be found at or any of its mirrors. More + url="&release.url;"> or any of its mirrors. More information on obtaining this (or other) &release.type; distributions of &os; can be found in the Obtaining @@ -100,455 +95,2340 @@ All users are encouraged to consult the release errata before installing &os;. The errata document is updated with late-breaking information discovered late in the - release cycle or after the release. Typically, it contains + release cycle or after the release. Typically, it contains information on known bugs, security advisories, and corrections to documentation. An up-to-date copy of the errata for &os; &release.current; can be found on the &os; Web site. - - What's New - - This section describes - the most user-visible new or changed features in &os; - since &release.prev;. - In general, changes described here are unique to the &release.branch; - branch unless specifically marked as &merged; features. - - - Typical release note items - document recent security advisories issued after - &release.prev;, - new drivers or hardware support, new commands or options, - major bug fixes, or contributed software upgrades. They may also - list changes to major ports/packages or release engineering - practices. Clearly the release notes cannot list every single - change made to &os; between releases; this document focuses - primarily on security advisories, user-visible changes, and major - architectural improvements. - - - Security Advisories - - - - - - - Kernel Changes - - A new &man.cpuset.2; API has been added - for thread to CPU binding and CPU resource grouping and - assignment. The &man.cpuset.1; userland utility has been added - to allow manipulation of processor sets. - - The &man.ddb.4; kernel debugger now has an output capture - facility. Input and output from &man.ddb.4; can now be captured - to a memory buffer for later inspection using &man.sysctl.8; or - a textdump. The new capture command controls - this feature. - - The &man.ddb.4; debugger now supports a simple scripting - facility, which supports a set of named scripts consisting of a - set of &man.ddb.4; commands. These commands can be managed from - within &man.ddb.4; or with the use of the new &man.ddb.8; - utility. More details can be found in the &man.ddb.4; manual - page. - - The kernel now supports a new textdump format of kernel - dumps. A textdump provides higher-level information via - mechanically generated/extracted debugging output, rather than a - simple memory dump. This facility can be used to generate brief - kernel bug reports that are rich in debugging information, but - are not dependent on kernel symbol tables or precisely - synchronized source code. More information can be found in the - &man.textdump.4; manual page. - - Kernel support for M:N threading has been removed. While - the KSE (Kernel Scheduled Entities) project was quite successful - in bringing threading to FreeBSD, the M:N approach taken by the - KSE library was never developed to its full potential. - Backwards compatibility for applications using KSE threading - will be provided via &man.libmap.conf.5; for dynamically linked - binaries. The &os; Project greatly appreciates the work of - &a.julian;, &a.deischen;, and &a.davidxu; on KSE support. - - The &os; kernel now exports information about certain kernel - features via the kern.features sysctl tree. - The &man.feature.present.3; library call provides a convenient - interface for user applications to test the presence of - features. - - The &os; kernel now has support for large - memory page mappings (superpages). - - The ULE - scheduler is now the default process scheduler - in GENERIC kernels. - - - Boot Loader Changes - - The BTX kernel used by the boot - loader has been changed to invoke BIOS routines from real - mode. This change makes it possible to boot &os; from USB - devices. - - A new gptboot boot loader has - been added to support booting from a GPT labeled disk. A - new boot command has been added to - &man.gpt.8;, which makes a GPT disk bootable by writing the - required bits of the boot loader, creating a new boot - partition if required. - - - - - Hardware Support - - The &man.cmx.4; driver, a driver for Omnikey CardMan 4040 - PCMCIA smartcard readers, has been added. - - The &man.syscons.4; driver now supports Colemak keyboard layout. - - The &man.uslcom.4; driver, a driver for Silicon - Laboratories CP2101/CP2102-based USB serial adapters, has been - imported from OpenBSD. + + What's New + + This section describes the most user-visible new or changed + features in &os; since &release.prev;, and changes shown in + Release Notes for the previous releases are marked as + [7.1R] and [7.2R]. + + Typical release note items document recent security + advisories issued after &release.prev;, new drivers or hardware + support, new commands or options, major bug fixes, or + contributed software upgrades. They may also list changes to + major ports/packages or release engineering practices. Clearly + the release notes cannot list every single change made to &os; + between releases; this document focuses primarily on security + advisories, user-visible changes, and major architectural + improvements. + + + Security Advisories + + Problems described in the following security advisories have + been fixed. For more information, consult the individual + advisories available from + . + + + + + + + + + Advisory + Date + Topic + + + + + + SA-08:05.openssh + 17 April 2008 + OpenSSH X11-forwarding privilege escalation + + + + SA-08:06.bind + 13 July 2008 + DNS cache poisoning + + + + SA-08:07.amd64 + 3 September 2008 + amd64 swapgs local privilege escalation + + + + SA-08:08.nmount + 3 September 2008 + &man.nmount.2; local arbitrary code execution + + + + SA-08:09.icmp6 + 3 September 2008 + Remote kernel panics on IPv6 connections + + + + SA-08:10.nd6 + 1 October 2008 + IPv6 Neighbor Discovery Protocol routing vulnerability + + + + SA-08:11.arc4random + 24 November 2008 + &man.arc4random.9; predictable sequence vulnerability + + + + SA-08:12.ftpd + 23 December 2008 + Cross-site request forgery in &man.ftpd.8; + + + + SA-08:13.protosw + 23 December 2008 + netgraph / bluetooth privilege escalation + + + + SA-09:01.lukemftpd + 07 January 2009 + Cross-site request forgery in + &man.lukemftpd.8; + + + + SA-09:02.openssl + 07 January 2009 + OpenSSL incorrectly checks for malformed + signatures + + + + SA-09:03.ntpd + 13 January 2009 + ntpd cryptographic signature + bypass + + + + SA-09:04.bind + 13 January 2009 + BIND DNSSEC incorrect checks for + malformed signatures + + + + SA-09:05.telnetd + 16 February 2009 + telnetd code execution + vulnerability + + + + SA-09:06.ktimer + 23 March 2009 + Local privilege escalation + + + + SA-09:07.libc + 04 April 2009 + Information leak in &man.db.3; + + + + SA-09:08.openssl + 22 April 2009 + Remotely exploitable crash in + OpenSSL + + + + SA-09:09.pipe + 10 June 2009 + Local information disclosure via direct pipe writes + + + + SA-09:10.ipv6 + 10 June 2009 + Missing permission check on SIOCSIFINFO_IN6 ioctl + + + + SA-09:11.ntpd + 10 June 2009 + ntpd stack-based buffer-overflow vulnerability + + + + SA-09:12.bind + 29 July 2009 + BIND &man.named.8; dynamic update message remote DoS + + + SA-09:14.devfs + 2 Oct 2009 + Devfs / VFS NULL pointer race condition + + + + + + + + Kernel Changes + + The &os; GENERIC kernel now + includes Trusted BSD MAC (Mandatory Access Control) support. + No MAC policy module is loaded by default. + + A loader + tunable hw.clflush_disable has been added + to avoid panic (trap 9) + at map_invalidate_cache_range() even if + Intel CPU is used. This tunable can be set + to -1 (default), 0 and + 1. The -1 is same as + the current behavior, which automatically + disables CLFLUSH on Intel CPUs without + CPUID_SS (this should occurr on Xen + only). You can specify 1 when this panic + happens on non-Intel CPUs (such as AMD's). Because disabling + CLFLUSH can reduce performance, you can try + with setting 0 on Intel CPUs + without SS to + use CLFLUSH feature. + + The &os; newbus subsystem is now MPSAFE. + + The &man.jail.8; subsystem has been updated. Changes include: + + + + A new virtualization container + named vimage has been implemented. This is + not enabled by default. To enable this, add the following + kernel options to your kernel configuration file and + rebuild the kernel: + + options VIMAGE + + Note that options SCTP in the + GENERIC kernel is not compatible with + options VIMAGE. This limitation will + be fixed in the next release. + + The vimage is a jail with a virtualized instance of + the &os; network stack. It can be created by using + &man.jail.8; command like this: + + &prompt.root; jail -c vnet name=vnet1 host.hostname=vnet1.example.net path=/ persist + + The vimage has own loopback interface and a separated + network stack including the L3 routing tables. Network + interfaces on the system can be moved by using + &man.ifconfig.8; option between the + different vimage jails and outside of them. + + Furthermore, the &man.epair.4; pseudo-interface driver + has been added to help communication between vimage jails. + It emulates a pair of back-to-back connected Ethernet + interfaces. For example, the following commands create an + interface pair of &man.epair.4;: + + &prompt.root; ifconfig epair0 create +epair0a +&prompt.root; ifconfig epair0a +epair0a: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 + ether 02:c0:64:00:07:0a +&prompt.root; ifconfig epair0b +epair0b: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 + ether 02:c0:64:00:08:0b + + The &man.epair.4; pseudo-interfaces and any physical + interfaces on the system can be moved between vimage jails + by using &man.ifconfig.8; option as + described above. Even after half of an &man.epair.4; pair + is moved, the back-to-back connection still valid and can + be used for inter-jail communication. + + Note that vimage is still considered as an + experimental feature. + + + + A jail can now have arbitrary named parameters similar + to environmental variables and the fixed jail parameters + in the previous releases have been replaced with them. + The jail name can now be used for identifying the jail in + &man.jexec.8; and &man.killall.1;. + + + + Multiple IPv4 and/or IPv6 addresses per jail are now + supported. It is even possible to have jails without + an IP address at all, which basically gives one a chrooted + environment with restricted process view and no + networking. + + + + SCTP (&man.sctp.4;) with IPv6 in jails has been + implemented. + + + + Specific CPU binding by using &man.cpuset.1; has been + implemented. Note that the current implementation allows + the superuser inside of the jail to change the CPU + bindings specified. + + + + A &man.jail.8; can start with a specific route + FIB now. + + + + The &man.ddb.8; kernel debugger now supports a + show jails subcommand. + + + + Compatibility support which permits 32-bit jail + binaries to be used on 64-bit systems to manage jails has + been added. + + + + Note that both version numbers of + jail and prison in + the &man.jail.8; have been updated for the new + features. + + + + The &man.ksyms.4;, kernel symbol table + interface driver has been added. It creates a character + device /dev/ksyms and provides + read-only access to a snapshot of the kernel symbol + table. + + The &os; Linux emulation + layer has been updated to version 2.6.16 and the default Linux + infrastructure port is + emulators/linux_base-f10 (Fedora + 10). + + The &os; virtual memory + subsystem now supports fully transparent use of + superpages for application memory; + application memory pages are dynamically promoted to or + demoted from superpages without any modification to + application code. This change offers the benefit of large + page sizes such as improved virtual memory efficiency and + reduced TLB (translation lookaside buffer) misses without + downsides like application changes and virtual memory + inflexibility. This can be enabled by setting a loader tunable + vm.pmap.pg_ps_enabled to + 1 and is enabled by default on + &arch.amd64;. + + The &man.ddb.8; kernel debugger now supports a + show mount subcommand. + + The &os; DTrace subsystem now supports a probe for + process execution. + + The &os; kernel virtual address + space has been increased to 6GB. This allows subsystems to use + larger virtual memory space than before. For example, the + &man.zfs.8; adaptive replacement cache (ARC) requires large + kernel memory space to cache file system data, so it benefits + from the increased address space. Note that the ceiling on + the kernel map size is now 60% of the size of physical memory + rather than an absolute quantity. + + The &man.kld.4; now supports installing 32-bit + system calls to the &os; syscall translation layer from kernel + modules. + + The &man.ktr.4; now supports a new KTR tracepoint in the + KTR_CALLOUT class to note when a callout + routine finishes executing. + + Types of variables used to track the amount of allocated + System V shared memory have been changed from + int to size_t. This + makes it possible to use more than 2 GB of memory for shared + memory segments on 64-bit architectures. Please note the new + BUGS section in &man.shmctl.2; and + /usr/src/UPDATING for limitations of this + temporary solution. + + The &man.sysctl.3; leaf nodes have a flag to tag + themselves as MPSAFE now. + + The &os; 32-bit system call translation layer now + supports installing 32-bit system calls for + VFS_AIO. + + The &man.clock.gettime.2; and the related system calls now + support a clock ID CLOCK_THREAD_CPUTIME_ID, + as defined in POSIX. + + The &man.cpuset.2; system call has been added. This is an + API for thread to CPU binding and CPU resource grouping and + assignment. + + The DTrace, a comprehensive dynamic tracing framework and + &man.dtrace.1; userland utility have been imported from + OpenSolaris. DTrace provides a powerful infrastructure to + permit administrators, developers, and service personnel to + concisely answer arbitrary questions about the behavior of the + operating system and user programs. + + The &man.ddb.4; kernel debugger now has an output capture + facility. Input and output from &man.ddb.4; can now be captured + to a memory buffer for later inspection using &man.sysctl.8; or + a textdump. The new capture command controls + this feature. + + The &man.ddb.4; debugger now supports a simple scripting + facility, which supports a set of named scripts consisting of a + set of &man.ddb.4; commands. These commands can be managed from + within &man.ddb.4; or with the use of the new &man.ddb.8; + utility. More details can be found in the &man.ddb.4; manual + page. + + The &man.ddb.4; ex command now supports + an mode which interprets and prints the + value at the requested address as a symbol. For example, + ex /S aio_swake + prints the name of the function currently registered in + via aio_swake hook. + + The &man.ddb.4; show conifhk command has + been added. This lists hooks currently waiting for completion + in run_interrupt_driven_config_hooks(). + + The &man.fcntl.2; system call now supports + F_DUP2FD command. This is equivalent to + &man.dup.2;, and compatible with the Sun Solaris and the IBM + AIX. + + The &os;'s &man.linux.4; ABI support now implements + sched_setaffinity() and + sched_getaffinity() using real CPU affinity + setting primitives. + + The &man.procstat.1; utility has been added. This is a + process inspection utility which provides some of the missing + functionality from &man.procfs.5; and new functionality for monitoring + and debugging specific processes. + + The client side functionality of &man.rpc.lockd.8; has been + implemented in the &os; kernel. This implementation provides the + correct semantics for &man.flock.2; style locks which are used + by the &man.lockf.1; command line tool and the &man.pidfile.3; + library. It also implements recovery from server restarts and + ensures that dirty cache blocks are written to the server before + obtaining locks (allowing multiple clients to use file locking + to safely share data). Also, a new kernel option + options NFSLOCKD has been added and enabled + by default. If the kernel support is enabled, &man.rpc.lockd.8; + automatically detects and uses the functionality. + + The &os; kernel now supports a new textdump format of kernel + dumps. A textdump provides higher-level information via + mechanically generated/extracted debugging output, rather than a + simple memory dump. This facility can be used to generate brief + kernel bug reports that are rich in debugging information, but + are not dependent on kernel symbol tables or precisely + synchronized source code. More information can be found in the + &man.textdump.4; manual page. + + The &man.wait4.2; system call now supports + flag to keep the process whose status + is returned in a waitable state and + which is equivalent to . + + The &os; kernel now has + initial support of binding interrupts to CPUs. + + The &man.sched.ule.4; scheduler is now the default + process scheduler in GENERIC + kernels. + + The sysctl + variables kern.features.compat_freebsd[456] + have been added. These are corresponding to the kernel options + COMPAT_FREEBSD[456]. + + + Boot Loader Changes + + The boot0 boot + loader now preserves volume ID at offset + 0x1b8 used in other operating systems + + The &man.boot0cfg.8; utility now supports a + new option to set the volume ID. + + The &man.boot.8; now supports 4-byte volume ID that + certain versions of &windows; put into the MBR and invoking + PXE by pressing the F6 key on some supported BIOSes. + + The &man.boot.8; BTX loader has been + improved. This fixes several boot issues on recent machines + reported for 7.1-RELEASE and before. + + The &man.loader.8; is now able to obtain DHCP options + from network boot via &man.kenv.2; variables. + + A bug in the &man.loader.8; has been fixed. Now the + following line works as expected: + + loader_conf_files="foo bar ${variable}" + + The BTX kernel used by the boot + loader has been changed to invoke BIOS routines from real + mode. This change makes it possible to boot &os; from USB + devices. + + A new gptboot boot loader has + been added to support booting from a GPT labeled disk. A + new boot command has been added to + &man.gpt.8;, which makes a GPT disk bootable by writing the + required bits of the boot loader, creating a new boot + partition if required. + + + + Hardware Support + + The &os; now includes experimental support + for &arch.mips; platform. + + The &man.acpi.4; subsystem now supports the System + Resource Affinity Table (SRAT) used to describe affinity + relationships between CPUs and memory, ACPI 3.0 fields in + the MADT including X2APIC entries and UIDs for local SAPICs, and + ACPI 3.0 flags in the FADT. + + The &man.cpufreq.4; framework now + supports PowerPC G5, along with a skeleton SMU driver in order to slew + CPU voltage during frequency changes. + + The sec(4) driver has been added to provide + support for the integrated security engine found in + Freescale system-on-chip devices. + + The &os; TTY layer has been replaced with a + new one which has better support for SMP and robust resource + handling. A tty now has own mutex and it is expected to + improve scalability when compared to the old implementation + based on the Giant lock. + + The &man.uart.4; driver is now the + default driver for serial port devices in favor of the + &man.sio.4; driver. Note that the device nodes have been + renamed from + /dev/cuadN and + /dev/ttydN to + /dev/cuauN and + /dev/ttyuN. + + + Users who are upgrading will need to change their + kernel configurations and possibly also + /boot/loader.conf and + /boot/device.hints. + + + The &os; USB subsystem has been reimplemented + to support modern devices and better SMP scalability. The + new implementation includes Giant-lock-free device drivers, + a Linux compatibility layer, &man.usbconfig.8; utility, full + support for split transaction and isochronous transaction, + and more. Device node names for USB devices are now in a + the form + of /dev/usb/bus.dev.endpoint, + and /dev/usbctl is the master device + node. Note that the &man.ugen.4; driver has nodes for each device as /dev/ugenbus.dev for backward compatibility. + + &os; now supports Ultra SPARC III + (Cheetah) processor family. + + The &man.acpi.4; subsystem now supports a &man.sysctl.8; + variable debug.batt.batt_sleep_ms. On + some laptops with smart batteries, enabling battery + monitoring software causes keystrokes from &man.atkbd.4; to + be lost. This sysctl variable adds a delay in millisecond + to the status checking code as a workaround. + + The &man.acpi.asus.4; driver now supports Asus A8Sr + notebooks. + + Support for the AltiVec, a floating point + and integer SIMD instruction set has been added. + + The &man.cpuctl.4; driver, which provides a special + device /dev/cpuctl as an interface to + the system CPU has been added. The &man.cpuctl.4; + functionality includes the ability to retrieve CPUID + information, read/write machine specific registers (MSR), + and perform CPU firmware updates. + + The &man.cpufreq.4; driver now supports an + hw.est.msr_info loader tunable. When + this is set to 1, it attempts to build a + simple list containing just the high and low frequencies if + it cannot obtain a frequency list from either ACPI or the + static tables. This is disabled by default. + + CPU frequency change notifiers are now + disabled when the TSC is P-state invariant. Also, a new + loader tunable + kern.timecounter.invariant_tsc has been + added to force this behavior by setting it to + non-zero. + + The &man.atkbd.4; driver now disables the interrupt + handler which is called from the keyboard callback function + when polled mode is enabled. This fixes the problem of + duplicated/missing characters at the mountroot prompt on + multi CPU systems while &man.kbdmux.4; is enabled. + + In the &man.pci.4; subsystem INTx is now disabled when + MSI/MSIX is enabled. This change fixes interrupt storm + related issues. + + The schizo(4) driver for Schizo + Fireplane/Safari to PCI 2.1 and Tomatillo JBus to PCI 2.2 + bridges has been added. + + The &man.u3g.4; driver for USB based 3G cards and + dongles including Vodafone Mobile Connect Card 3G, Qualcomm + CDMA MSM, Huawei E220, Novatel U740, Sierra MC875U, and more + has been added. This provides support for the multiple + USB-to-serial interfaces exposed by many 3G USB/PC Card + modems, and the device is accessed through the &man.ucom.4; + driver which makes it behave like a &man.tty.4;. + + The &man.sched.ule.4; scheduler now supports + the loader tunable + machdep.hyperthreading_enabled just like + &man.sched.4bsd.4;. Note that it cannot be modified at + run-time. + + The &man.cmx.4; driver, a driver for Omnikey CardMan 4040 + PCMCIA smartcard readers, has been added. + + The &man.kbdmux.4; driver now + supports &arch.sparc64;. The &man.sunkbd.4; driver now + supports &man.atkbd.4; emulation like &man.ukbd.4;. + + The nvram(4) driver is now + MPSAFE. + + An option of the &man.puc.4; + driver, PUC_FASTINTR, is no longer + supported. + + The &man.psm.4; driver now attempts detection of Synaptics + touchpad before IntelliMouse. Some touchpads will pretend to + be IntelliMouse causing the IntelliMouse probe to work and the + Synaptics detection never to be done. + + The &man.uslcom.4; driver, a driver for Silicon + Laboratories CP2101/CP2102-based USB serial adapters, has been + imported from OpenBSD. + + + Multimedia Support + + The &os; audio subsystem has been improved. + The changes include volume per channel, high quality + fixed-point band-limited SINC sampling rate converter, + bit-perfect mode, transparent/adaptive virtual channel, + and exclusive stream. For more details, see the + &man.snd.4; manual page. + + The &man.agp.4; driver now supports Intel G4X series + graphics chipsets. + + The Direct Rendering Manager + (DRM), a kernel module that + gives direct hardware access to DRI clients, has been + updated. Support for AMD/ATI r500, r600, r700, and IGP + based chips, XGI V3XE/V5/V8, and Intel i915 chipsets has + been improved. + + A new loader tunable hw.drm.msi has + been added to control if DRM uses MSI or not. This is set + to 1 (enabled) by default. + + The snd_au88x0(4) driver for Aureal Vortex + 1/2/Advantage PCI has been removed because it has been + broken for a long time. + + The &man.snd.hda.4; driver has been updated. These + changes include support for multiple codecs per HDA bus, + multiple functional groups per codec, multiple audio + devices per functional group, digital (SPDIF/HDMI) audio + input/output, suspend/resume, and part of multichannel + audio. + + Note that due to added HDMI audio and + logical audio devices support, the updated driver often + provides several PCM devices. This means that in some + cases the system default audio device no longer + corresponds to the users's habitual audio connectors. In + such cases the default device can be specified in audio + applications' setup or defined globally via + hw.snd.default_unit sysctl variable, as + described in the &man.sound.4; manual page. + + The &man.agp.4; driver now supports the + Intel G33 and G45. + + The dpms(4) driver has + been added to use the VESA BIOS for DPMS during suspend and + resume. + + The DRM kernel driver now + supports i915 GME devices. + + + + Network Interface Support + + The &man.bwi.4; driver has been added to + provide support for Broadcom BCM43xx IEEE 802.11b/g wireless + network interfaces. + + The &man.cas.4; driver has + been added to provide support for Sun Cassini/Cassini+ and + National Semiconductor DP83065 Saturn Gigabit Ethernet + devices. + + The &man.cxgbtool.8; now supports an + interactive mode for scripting of repeatedly performed + tasks. + + The &man.fxp.4; driver has been improved. Changes include: + + + + The multicast filter re-programming + is now more robust. + + + + The checksum offload feature can be controlled by + &man.ifconfig.8; now. + + + + Rx checksum offload support for 82559 or later + controllers has been added. + + + + TSO (TCP Segmentation Offload) support for 82550 + and 82551 controllers has been added. + + + + WoL (Wake on LAN) support for 82550, 82551, 82558, + and 82559-based controllers has been added. Note that + ICH based controllers are treated as 82559, and 82557, + earlier revisions of 82558, and 82559ER have no WoL + capability. + + + + VLAN hardware tag insertion/stripping support and + Tx/Rx checksum offload for VLAN frames support has + been added. Note that the VLAN hardware assistance is + available only on 82550 or 82551-based + controllers. + + + + The &man.miibus.4; driver now supports + the Marvell 88E3016. + + The &man.msk.4; driver now supports Yukon + FE+ A0 including 88E8040, 88E8040T, 88E8048 and + 88E8070. + + The &man.mwl.4; driver has been added to + provide support for Marvell 88W8363 IEEE 802.11n wireless + network devices. + + The &man.mxge.4; driver now supports some newer + revisions and 10GBASE-LRM and 10GBASE-Twinax media + types. The firmware version has been updated to 1.4.43. + + The &man.nge.4; driver has been improved and + now works on all platforms. + + The &man.uath.4; driver for USB wireless LAN + adapter based on Atheros AR5005UG and AR5005UX chipsets + has been added. The &man.uathload.8; utility, a firmware + loader for the Atheros USB wireless driver has also been + added. + + The &man.urtw.4; driver has been added to + provide support for Realtek RTL8187B/L USB IEEE 802.11b/g + wireless network devices. + + The &man.xl.4; driver now supports TX + checksum offload. + + The &man.ae.4; driver now supports WoL + (Wake on LAN). + + The &man.ale.4; driver is now + included in the GENERIC + kernel. + + The &man.ath.hal.4;, Atheros Hardware Access Layer, + has been updated to the open source version. + + The &man.axe.4; driver has been improved in + performance by eliminating extra context switches and now + supports the Apple USB Ethernet adapter. + + The &man.bce.4; driver's firmware has been updated to + the latest version (4.6.X). + + The ciphy(4) driver now supports Vitesse VSC8211 + PHY. + + The &man.cxgb.4; driver has been updated to firmware + revision 4.7 and now supports hardware MAC + statistics. + + A bug in the &man.igb.4; driver, which prevented the + loader tunable hw.igb.ave_latency from + working, has been fixed. + + The &man.ixgbe.4; driver has been updated to + version 1.7.4. + + The &man.jme.4; driver now supports newer JMicron + JMC250/JMC260 revisions. + + The &man.msk.4; driver has been improved. An issue + which made it hang up in a certain condition has been + fixed. Hardware MAC statistics support has been added + and users can get the information via sysctl variables + named + dev.msk.N.stats. + + The &man.nfe.4; driver now supports hardware MAC + statistics. + + The &man.re.4; driver has been improved. It now + detects the link status. A new loader tunable + hw.re.prefer_iomap has been added, to + disable memory register mapping. This tunable is + 0 for all controllers except RTL8169SC + family. + + The &man.rl.4; driver has been improved. It now + detects the link status and a bug which prevented it from + working on systems with more than 4GB memory has been + fixed. + + A bug in &man.sis.4; on VLAN tagged frame handling has + been fixed. + + The &man.txp.4; driver now works on all supported + architectures. Support has been added for &man.altq.4;, + WoL, checksum offload when VLAN enabled, and link state + change handling has been improved, and new sysctl + variables + dev.txp.N.stats + for MAC statistics have been added. New sysctl variables + dev.txp.N.process_limit + has been added, to control how many received frames should + be served in Rx handler (set to 64 by default and valid + ranges are 16 to 128 in unit of frames). The firmware has + been updated to the latest version. + + The &man.ae.4; driver has been added to provide + support for the Attansic/Atheros L2 FastEthernet + controllers. + + The &man.jme.4; driver has been added to + provide support for PCIe adapters based on JMicron JMC250 + gigabit Ethernet and JMC260 fast Ethernet controllers. + + The &man.age.4; driver has been added to + provide support for Attansic/Atheros L1 gigabit Ethernet + controller. + + The &man.malo.4; driver has been added to + provide support for Marvell Libertas 88W8335 based PCI network + adapters. + + The bm(4) driver has been added to + provide support for Apple Big Mac (BMAC) Ethernet controller, + found on various Apple G3 models. + + The et(4) driver has been added to + provide support for Agere ET1310 10/100/Gigabit Ethernet + controller. + + The &man.glxsb.4; driver has been added + to provide support for the Security Block in AMD Geode LX + processors. + + The &man.ale.4; driver has been added to provide support + for Atheros AR8121/AR8113/AR8114 Gigabit/Fast Ethernet controllers. + This driver is not enabled in GENERIC + kernels for this release. + + The &man.em.4; driver has been split into two drivers + with some common parts. The &man.em.4; driver will continue + to support adapters up to the 82575, as well as new + client/desktop adapters. A new &man.igb.4; driver + will support new server adapters. + + The &man.hme.4; driver has been improved. + + A bug in some of the &man.miibus.4; supported drivers that + IEEE 802.3 auto-negotiation was performed in a wrong order, + has been fixed. Now it chooses the correct technologies + supported by IEEE 802.3 in the order described in Annex + 28B.3. + + A workaround has been added for a bug in TCP/UDP + hardware checksum offload of the &man.msk.4; driver for + short frames. Note that for frames that requires hardware + VLAN tag insertion, the checksum offload workaround does not + work due to changes of checksum offset in mbuf after the + VLAN tag. So disabling hardware checksum offload for the + VLAN interface is needed in such cases. + + The &man.ndis.4; NDIS miniport driver wrapper has been + improved. + + The &man.sf.4; driver has been improved and now supports + checksum offloading. + + The &man.stge.4; driver now supports WOL (Wake on + LAN). + + The &man.vr.4; driver has been improved. + + The &man.wpi.4; driver has + been updated to include a number of stability fixes. + + + + + Network Protocols + + The &os; netisr framework has been + reimplemented for parallel threading support. This is a + kernel network dispatch interface which allows device + drivers (and other packet sources) to direct packets to + protocols for directly dispatched or deferred processing. + The new implementation supports up to one netisr thread per + CPU, and several benchmarks on SMP machines show substantial + performance improvement over the previous version. + + A bug in the &man.gif.4; that EtherIP packets + sent by combination of &man.if.bridge.4; and &man.gif.4; + have a reversed version field has been fixed. If you need + to communicate with older &os; releases via EtherIP, use new + flags accept_rev_ethip_ver + and send_rev_ethip_ver to control + handling the reversed version field. These can be set by + &man.ifconfig.8 utility to &man.gif.4; interfaces. The + EtherIP implementation found on &os; 6.1, 6.2, 6.3, 7.0, + 7.1, and 7.2 had an interoperability issue because it sent + the incorrect EtherIP packets and discarded the correct + ones. For more details, see &man.gif.4; manual page. + + The IGMPv3 and SSM (Source-Specific Multicast) + including IPv6 SSM and MLDv2 have been added. Although the + old KAME MLDv2 hooks have been replaced with the new + implementation, the related kernel programming interfaces have been + preserved. + + The multicast routing code has been improved + and the IPv4 and IPv6 support has been split. + + The &os; now supports the upcoming Wireless + Mesh standard, IEEE 802.11s. The current implementation is + based on the March 2009 D3.0 draft version. + + The wireless network support layer (net80211) + now uses pseudo-interfaces named as + wlanN instead + of a device driver name like em0 + directly. The + wlanN + interface is created by &man.ifconfig.8; as an instance of + the parent interface and used for actual communication + similar to &man.vlan.4, IEEE 802.1Q VLAN network interface. + Note that multiple instances (to realize multiple BSSes with + a single AP device, for example) can be created if the + parent interface supports it. For more details, see + &man.ifconfig.8; manual page. + + The net80211 layer now supports TDMA for long + distance point-to-point links using &man.ath.4; + devices. + + An infrastructure for caching flows as a means + of accelerating L2 and L3 lookups has been added. This is + called flow table and enabled by default on + &arch.amd64 and &arch.i386; platforms. This also provides + stateful load balancing when used + with RADIX_MPATH + + The &os; L2 address translation table has been + reimplemented to reduce lock contention on parallel + processing and simplify the routing logic. The new + implementation has L2 address translation tables for both + ARP (for IPv4) and NDP (for IPv6) which are separated from + the L3 routing tables, and supports flow table caches for both + the routing table and the L2 information. One of the + user-visible changes is that a concept of cloned route (a + route generated by an entry + with RTF_CLONING flag) is deprecated. + This means routing flags RTF_CLONING, + RTF_WASCLONE, + and RTF_LLINFO are obsolete. + + The &man.ipsec.4; subsystem now supports + NAT-Traversal (RFC 3948). This is disabled by default. To + enable this add the following kernel option and rebuild the + kernel: + + device crypto +options IPSEC +options IPSEC_NAT_T + + IPv4 source address selection for unbound sockets has + been implemented as follows: + + + + If we found a route, use the address corresponding + to the outgoing interface. + + + + Otherwise we assume the foreign address is reachable + on a directly connected network and try to find a + corresponding interface to take the source address + from. + + + + As a last resort use the default jail address. + + + + This also changes the semantics of selecting the IP for + processes within a &man.jail.8; as it now uses the same + logic as outside the &man.jail.8;. + + The TCP MD5 Signature Option (RFC 2385) for IPv6 has + been implemented in the same way it has been implemented for + IPv4. + + The &man.ng.netflow.4; Netgraph node now includes + support for generating egress netflow instead or in addition + to ingress. An NGM_NETFLOW_SETCONFIG + control message has been added to control the new + functionality. + + The &man.tap.4; Ethernet tunnel software network + interface now supports a new TAPGIFNAME + character device ioctl. This is a convenient shortcut to + obtain the network interface name using a file descriptor to + a character device. + + The &man.tap.4; now supports + SIOCSIFMTU ioctl to set a higher MTU than + 1500 (ETHERMTU). This allows &man.tap.4; devices to be + added to the same bridge (which requires all interface + members to have the same MTU) with an interface configured + for jumbo frames. + + The domains list for handling the list of supported + domains in the &man.unix.4; (UNIX domain protocol family) + subsystem is now MPSAFE. + + The &man.arp.8; utility now + supports reject + and blackhole keywords. In the entry + marked as reject, traffic to the host will + be discarded and the sender will be notified the host is + unreachable. In the entry marked as blackhole, + traffic is discarded but the sender is not notified. + + The &man.bpf.4; now supports an + ioctl BIOCSETFNR. This is just like + BIOCSETF, but it does not drop all the + packets buffered on the descriptor and reset the + statistics. + + The &man.if.bridge.4; interface can limit the + number of source MACs that can be behind a bridge interface + via ifmaxaddr parameter of + &man.ifconfig.8;. + + A bug in the &man.carp.4; interface configuration which + leads to a system panic has been fixed. + + The &man.dummynet.4; subsystem now supports + fast mode operation which allows certain + packets to bypass the dummynet scheduler. This can achieve + lower latency and lower overhead when the packet flow is under + the pipe bandwidth, and eliminate recursion in the subsystem. + The new sysctl variable + net.inet.ip.dummynet.io_fast has been + added to enable this feature. + + The &man.enc.4; interface now supports sysctl + variables to control whether the firewalls or &man.bpf.4; + will see inner and outer headers or just inner or outer + headers for incoming and outgoing IPsec packets. + + The &man.gre.4; now supports + ioctls GRESKEY + and GREGKEY which allows set or get GRE + key used for outgoing packets. + + A bug in the &man.ipsec.4; subsystem that PMTU was broken + in those cases when there was a route with a lower MTU than + the MTU of the outgoing interface, has been fixed. + + The netatm subsystem has been removed due to + lacking multiprocessor support. + + The &man.ng.nat.4; now supports redirect functionality + in libalias. For more details, see the + manual page. + + The &man.ng.pptpgre.4; now supports multiple hooks like + &man.ng.l2tp.4;, to use one pair of pptpgre and ksocket nodes for all + calls between two peers. + + The &man.resolver.3; now allows underscore in domain + names. Although this is a violation of RFC 1034 [STD 13], it is + accepted by certain name servers as well as other popular operating + systems' resolver library. + + A socket option TCP_CONGESTION for TCP + sockets has been added. This is for setting and retrieving the + congestion control algorithm. The name used is to allow + compatibility with Linux. + + The &man.rwlock.9; has been used throughout + the inpcbinfo and inpcb + infrastructure, and protocols that depend on that + infrastructure, including UDP, TCP, and IP raw sockets to + reduce the lock contentions. + + The &os; now supports multiple routing tables. To + enable this, the following steps are needed: + + + + Add the following kernel configuration option and + rebuild the kernel. The 2 is the number + of FIB (Forward Information Base, synonym for a routing + table here). The maximum value is 16. + + options ROUTETABLES=2 + + The procedure for rebuilding the &os; kernel is + described in the &os; + Handbook. + + This number can be modified on boot time. To do so, add + the following to /boot/loader.conf and + reboot the system: + + net.fibs=6 + + + + Set a loader tunable net.my_fibnum if + needed. This means the default number of routing tables. + If not specified, 0 will be used. + + + + Set a loader tunable + net.add_addr_allfibs if needed. This + enables to add routes to all FIBs for new interfaces by + default. When this is set to 0, it will + only allocate routes on interface changes for the FIB of the + caller when adding a new set of addresses to an interface. + Note that this tunable is set to 1 by + default. + + + + To select one of the FIBs, the new &man.setfib.1; utility + can be used. This set an associated FIB with the process. For + example: + + &prompt.root; setfib -3 ping target.example.com + + The FIB #3 will be used for the &man.ping.8; command. + + The FIB which the packet will be associated with will be + determined in the following rules: + + + + All packets which have a FIB associated with them will + use the FIB. If not, FIB #0 will be used. + + + + A packet received on an interface for forwarding uses + FIB #0. + + + + A TCP listen socket associated with an FIB will generate + accept sockets which are associated with the same FIB. + + + + A packet generated in response to other packet uses the + FIB associated with the packet being responded to. + + + + A packet generated on tunnel interfaces such as + &man.gif.4; and &man.tun.4; will be encapsulated using the + FIB of the process which set up the tunnel. + + + + Routing messages will be associated with the process's + FIB. + + + + Also, the &man.ipfw.8; now supports an action rule + setfib. The following action: + + setfib fibnum + + will make the matched packet use the FIB specified in + fibnum. The rule processing + continues at the next rule. + + + + Disks and Storage + + The &os; CAM SCSI subsystem (&man.cam.4;) now + includes experimental support for ATA/SATA/AHCI-compliant + devices. This is disabled by default. To enable this, + adding the following kernel options to your kernel + configuration file and rebuild the kernel: + + device ahci +device siis + + The current implementation supports + AHCI-compliant controllers and SiliconImage + SiI3124/SiI3132/SiI3531 controllers. The device node of an + ATA drive is ada and an ATAPI + drive is cd. + + The &os; iSCSI initiator implementation has + been improved and supports IPv6. + + A userland utility &man.mfiutil.8; for the + &man.mfi.4; devices has been added. This includes basic + features to monitor controller, array, and drive status, + change basic attributes, create/delete arrays and spares, + and flush the controller firmware. Note that this is a + small utility, not a replacement of MegaCLI in the Ports + Collection which is supported officially and provides more + functionality. + + A userland utility &man.mptutil.8; for the + &man.mpi.4; devices has been added. This includes basic + features to monitor controller, array, and drive status, + change basic attributes, and create/delete arrays and + spares. + + The &man.siis.4; driver has been added to + provide support for SiliconImage SiI3124/3132/3531 SATA2 + controllers. It supports Serial ATA and ATAPI devices, port + multipliers (including FIS-based switching), hardware + command queues (31 commands per port) and Native Command + Queuing. + + The &man.ata.4; driver now supports Marvell PATA M88SX6121. + + The &man.ata.4; driver now recognizes nForce MCP67 and + MCP73 SATA controllers as AHCI. + + The &man.ataraid.4; driver now includes preliminary support + for DDF metadata found on Adaptec HostRAID controllers. + Note that spares and rebuilds are not supported yet. + + The &man.cam.4; SCSI subsystem now supports a new sysctl + variable kern.cam.cd.retry_count. This + controls the number of retries for the CD media. When + trying to read scratched or damaged CDs and DVDs, the + default mechanism is sub-optimal, and programs like + ddrescue do much better if you + turn off the retries entirely since their algorithms do it + by themselves. This value is set to 4 + (for a total of 5 attempts) by default. Setting it to + 0 turns off all retry attempts. + + A bug in the &man.ciss.4; driver which caused low + max device openings count and led to poor + performance has been fixed. + + The &man.glabel.8; GEOM class now supports a new + UFS-based label called ufsid that can be + used to reference UFS-carrying devices by the unique file + system ID. This file system ID is automatically generated + and detected when the &man.glabel.8; GEOM class is enabled. An + example of this new label is: + /dev/ufsid/48e69c8b5c8e1b43. The + benefit of using GEOM labels in general is to avoid problems + of device renaming when shifting drives or + controllers. + + The &man.gjournal.8; GEOM class now supports the root + file system. Previously, an unclean shutdown would make it + impossible to mount the root file system at boot. + + The &man.gpart.8; utility has been updated. The APM + scheme now supports Tivo Series 1 partitions (read only), a + new EBR scheme to support Extended Boot Records has been + added, the BSD scheme now support bootcode, and bugs in the + PC98 and VTOC8 schemes have been fixed. + + An issue in &man.gvinum.8; with access permissions + to underlying disks used by a gvinum plex has been fixed. + If the plex is a raid5 plex and is being written to, parity data might + have to be read from the underlying disks, requiring them to be opened for + reading as well as writing. + + The &man.hptmv.4; driver has been updated to version + 1.16 from HighPoint. + + The &man.mmc.4; and &man.mmcsd.4; drivers now support MMC + and SDHC cards, high speed timing, wide bus, and multiblock + transfers. + + The &man.mpt.4; driver is now in the + GENERIC kernel. + + The &man.sdhci.4; driver has been added. This supports + PCI devices with class 8 and subclass 5 according to the SD + Host Controller Specification. + + The &man.sdhci.4; driver now supports kernel dumping and + a sysctl variable hw.sdhci.debug for debug + level. + + The &man.twa.4; driver now supports 64-bit DMA. + + The &man.mmc.4; &man.mmcsd.4;, and &man.sdhci.4; driver + are now included as kernel modules. + + The &man.aac.4; driver now supports 64-bit array support + for RAIDs larger than 2TB and simultaneous opens of the device + for issuing commands to the controller. + + The &man.ata.4; driver now supports a loader variable + hw.ata.ata_dma_check_80pin. This can be + used to disable the 80pin cable check on broken systems such + as certain laptops and Soekris boards. The default value is + 1. + + A data corruption problem of the &man.ata.4; driver on + ServerWorks HT1000 chipsets has been fixed. + + The &man.ciss.4; driver now supports a loader tunable + hw.ciss.nop_message_heartbeat for + NOP-message polling in ciss_periodic(). + This can be used as a workaround for + ADAPTER HEARTBEAT FAILED issue. + The default value is 0 (disabled). + + The geom_part GEOM class can be built + as a kernel module. + + The geom_linux_lvm GEOM class can be + built as a kernel module. + + The &man.hptrr.4; driver has been updated to version 1.2 + from Highpoint. + + A buffer overflow in the &man.iir.4; driver has been + fixed. This likely fixes a great number of weird problems + that have been reported with this driver. + + The &man.mpt.4; driver now supports mpt_user + personality. + + The &man.rr232x.4; driver has been superseded by + &man.hptrr.4; driver. + + The &man.twa.4; driver has been improved with regard to + stability on machines with a plenty of memory and high CPU + load. + + + + File Systems + + dangerously dedicated mode for + the UFS file system is no longer supported. + + + Such disks will need to be reformatted to work with + this release. + + + The &man.gvinum.8; now supports commands + found in the old vinum implementation including + attach, detach, + start, stop, + concat, mirror, + stripe, and + raid5. + + The &man.gvinum.8; now + supports grow command to make it easier + for users to extend plexes without having to understand all + of the implementation internals. + + The &os; NFS subsystem now + supports RPCSEC_GSS authentication on + both the client and server. This replaces the RPC + implementation of the NFS client and server with the newer + RPC implementation originally developed to support the NFS + Lock Manager. It supports both the new RPC implementation + and the older legacy implementation inherited from the + original NFS codebase and the default is to use the new one. + To use RPCSEC_GSS on either client or + server, you must build a kernel which includes + the KGSSAPI option and the &man.crypto.4; + device. For more details, see &man.gssd.8; manual + page. + + The &os; NFS subsystem now includes a new, + experimental implementation with support for NFSv2, NFSv3, and + NFSv4. This is not enabled by default. To enable this, add + the following kernel options to your kernel configuration + file and rebuild the kernel: + + options NFSCL # for NFS client +options NFSD # for NFS server + + The fstype for &man.mount.8; program is + newnfs, and &man.mount.newnfs.8; program + has also been added. The old, unmaintained NFSv4 client + based on an implementation from the University of Michigan was + removed from the &os; source tree. + + The &os; NFS subsystem now uses TCP as the + default transport. + + The shared vnode locking for pathname lookups + in the &man.VFS.9; subsystem has been improved. This is + enabled by default. Setting a sysctl variable + vfs.lookup_shared to 0 + disables it. Note that the + LOOKUP_SHARED kernel option equivalent to + the sysctl variable has been removed. + + The ZFS file system + has been updated to version 13. The changes include ZFS + operations by a regular user, L2ARC, ZFS Intent Log on + separated disks (slog), sparse volumes, and so on. + + The semantics of &man.acl.3; extended access control + lists has been changed as follows: + + + + The inode modification time (mtime) is not updated + when extended attributes are added, modified, or removed. + + + + The inode access time (atime) is not updated + when extended attributes are queried. + + + + The &os; NFS file system now supports a sysctl variable + vfs.nfs.prime_access_cache to determine + whether or not nfs_getattr() will use + an ACCESS RPC to prime the access cache instead of a simple + GETATTR RPC. This is because on many NFS servers an ACCESS + RPC is much more expensive to service than a GETATTR RPC for + files in an NFSv3 mount. The sysctl variable is enabled by + default to maintain the previous behavior. + + The &os; UDF file system now supports a fifo. + + The &man.fdescfs.5; is now MPSAFE. + + The &man.gpart.8; now supports BSD disklabels (option + GEOM_PART_BSD) and + VTOC8 disklabels (option + GEOM_PART_VTOC8). + + The &man.gvinum.8; now accepts volume + parameter when creating a plex. + + A pathname lookup bug of a UNIX domain socket in the + unionfs(7) has been fixed. + + + + + Userland Changes + + The GCC stack protection (also known as + ProPolice) has been enabled in the &os; base system. + + A BSD-licensed &man.ar.1; utility has been added + in favor of one in GNU binutils and + it is now the default utility for building the &os; base + system. + + The &man.awk.1; utility now supports 64 files. + The upper limit was 20 in prior releases. + + The &man.bsnmpd.1; program now supports OIDs + for ZFS. + + The &man.camcontrol.8; program now supports a + new modularized ATA kernel module and various ATA + commands. + + The &man.cat.1; and &man.cp.1; now use a larger + buffer if the number of pages of the physical memory on the + system is grater than 32k. This reduces the number of context + switches. + + A new BSD-licensed &man.cpio.1; utility has been + added in favor of GNU cpio and it + is now the default utility in the &os; base system. + + A script for the &man.crashinfo.8; utility for + simple analysis of crash dump has been added. It generates a + text file containing the output of several commands run against + the core dump such as &man.kgdb.1; (stack trace), &man.ps.1;, + &man.netstat.1;, + &man.vmstat.8;, + &man.iostat.8;, + &man.dmesg.8;, + and + &man.fstat.1;. + + The &man.df.1; utility's + flag now supports displaying inode counts in a human-readable + format when a flag is specified. + + The &man.df.1; utility now supports + a flag to display file system type in each + entry. + + A bug in the &man.dhclient.8; that can create a + malformed /etc/resolv.conf has been + fixed. + + The &man.dhclient.8; now uses an + flag when invoking &man.route.8; command. + This eliminates a long delay in the case that it gets a lease + but DNS service is not working. + + The &man.dhclient.8; utility now + uses 68 (bootpc) as the source port for + unicast DHCPREQUEST packets instead of + allowing the protocol stack to pick a random source port. + This fixes the behavior where &man.dhclient.8; would never + transition from RENEWING + to BOUND without going + through REBINDING in some networks which + has a tight policy on DHCP spoofing. + + The &man.env.1; utility now supports a + option + that completely unsets the given name instead of setting it to + a null value. + + The &man.find.1; utility now supports a number + of primaries found in GNU find + including , + , + , , + , , + , , + , , + , , + , and . + + The &man.fsck.8; utility now supports a + flag to free up excess unused inodes. + Decreasing the number of preallocated inodes reduces the + running time of future runs of fsck and frees up space that + can allocated to files. This flag is ignored when running in + preen mode. + + The &man.freebsd-update.8; now supports backing + up the old kernel when installing a new kernel. The backup + kernel will be written + to /boot/kernel.old if the directory does + not exist or the directory was created by freebsd-update in a + previous backup. Otherwise the &man.freebsd-update.8; will + generate a new directory name for use by the backup. This is + enabled by default. + + The &man.gpt.8; program has been removed in + favor of &man.gpart.8;. + + The &man.gzip.1; utility now supports + uncompressing files which are created + by pack found in some commercial + UNIX-like systems. + + The &man.i2c.8; utility for diagnostics of I2C has + been added. + + The &man.ifconfig.8; now + supports and + option to allow moving interfaces between jails with + vimage. + + A BSD-licensed libdwarf + library has been added for DTrace clients. + + The libmsun library now supports + acosl(), + asinl(), + atanl(), + atan2l(), + cargl(), + csqrtl(), + fmodl(), + hypotl(), + and + remquol() + functions. + + The libproc + library has been added for DTrace clients. + + The &man.mtest.8; utility now supports IPv6. + + The &man.mount.8; program now supports + an option + to allow an alternative program to be used for mounting a file + system. This is useful for non-&man.nmount.2; based file + systems such as FUSE. + + The &man.nfscbd.8;, &man.nfsuserd.8;, + &man.nfsdumpstate.8;, and &man.nfsrevoke.8; utilities for the + new NFSv4 subsystem has been added. + + The &man.pmcannotate.8; utility has been added. + This prints out sources of a tool (in C or assembly) with + inlined profiling informations retrieved by a prior + &man.pmcstat.8; analysis. + + The &man.route.8; utility now + supports show, + weights, and sticky + commands. For more details, see the &man.route.8; manual + page. + + The &man.rtld.1; now supports a new + environment variable LD_ELF_HINTS_PATH for + overriding the rtld hints file. This environment variable + would be ignored if the process uses setuid and/or setgid. + This feature gives a convenient way to use a custom set of + shared library that is not in the default location. + + The &man.rtld.1; now supports the dynamic + string token substitution in the rpath and soneeded pathes. The + $ORIGIN, + $OSNAME, + $OSREL + and $PLATFORM + tokens are supported. Enabling + the substitution requires DF_ORIGIN + flag in DT_FLAGS or + DF_1_ORIGIN if + DF_FLAGS_1, that may be set + with origin GNU + ld flag. This translation is unconditionally + disabled for setuid/setgid processes. + The $ORIGIN translation relies on + the AT_EXECPATH auxinfo supplied by the + &os; kernel. + + It is no longer possible to create UFS + filesystems in dangerously dedicated mode using + &man.sysinstall.8; since this mode is no longer supported. + + &man.sysinstall.8; menus have been simplified + to reduce confusion and duplication with other parts of the + system. The Xorg window system + should be installed just like any other package. + Configuration of Linux and + OSF/1 emulation should be done via + kernel rebuilds. Support for installation from tape media was + removed as it was believed to be broken. Obsolete code to + support OLDCARD was also + removed. + + &man.sysinstall.8; now understands how to use + unsliced USB drives as installation source media via + /dev/daXa + + &man.sysinstall.8; now recognizes the new + /dev/adaX disk + devices, if compiled into the kernel. + + &man.sysinstall.8; now uses the + freebsd-doc-* + packages for localized documents. + + &man.sysinstall.8; now ejects the CDROM after + installation if it was used as source media. + + The &man.traceroute.8; and &man.traceroute6.8; + now support an + flag to display AS number corresponding to + the lookup IP address on each hop. It will query the number to + WHOIS server specified in option. If + no is + specified, whois.radb.net will be used as the + default value. + + The &man.tzsetup.8; now supports + an flag to skip the question about + adjusting the clock to UTC. + + The &man.wake.8; utility, a tool to send Wake on + LAN frames to hosts on a local Ethernet network has been + added. + + The &man.ypserv.8; program now + supports shadow.byname + and shadow.byuid maps. + + A bug in the &man.atacontrol.8; utility, which prevents it + from working when /usr is not mounted or + invoked from /rescue, has been + fixed. + + The &man.btpand.8; daemon from NetBSD has been added. + This daemon provides support for Bluetooth Network Access + Point (NAP), Group Ad-hoc Network (GN) and Personal Area + Network User (PANU) profiles. + + The &man.cpucontrol.8; utility has been added to + control &man.cpuctl.4; pseudo-device. + + The &man.ncal.1; utility now supports multibyte + characters. + + The &man.newfs.8; utility now supports + operations on a regular file. + + The &man.config.8; utility now supports + multiple makeoption lines. + + The &man.csup.1; utility now supports CVSMode to fetch a + complete CVS repository. Note that the rsync transfer mode is + currently disabled. + + The &man.dirname.1; utility now accepts multiple arguments + in the same way that &man.basename.1; does. + + The &man.du.1; utility now supports an + flag. When specified, the &man.du.1; utility counts a file + with multiple hard links as multiple different files. + + The &man.du.1; utility now supports an flag + to display the apparent size instead of the disk usage. This can be + helpful when operating on compressed volumes or sparse files. + + The &man.du.1; utility now supports a option to + calculate block counts in blocks of + blocksize bytes. This is different + from the or options or + setting BLOCKSIZE and gives an estimate of + how much space the examined file hierarchy would require on a + file system with the given + blocksize. Unless in + mode, blocksize + is rounded up to the next multiple of 512. + + The &man.dumpfs.8; utility now supports an + flag, which causes it to list all free + fragments in the file system by fragment (block) number. This + new mode does the necessary arithmetic to generate absolute + fragment numbers rather than the cg-relative numbers printed + in the default mode. + + If is passed once, contiguous fragment + ranges are collapsed into an X-Y format as free block lists + are currently printed in regular dumpfs output. If specified + twice, all block numbers are printed individually, allowing + both compact and more script-friendly representation. + + The &man.fetch.1; utility now supports an + flag which supports the If-Modified-Since + HTTP 1.1 request. If specified it will cause the file to be + downloaded only if it is more recent than the mtime of the + local file. Also, libfetch now + accepts the mtime in the url structure and a flag to indicate + when this behavior is desired. + + The &man.fsck.8; utility now supports a + flag for check clean + mode. This checks if the file system was dismounted cleanly + first and then skip file system checks if true. Otherwise it + does full checks. + + The &man.fsck.8; utility now supports a + flag for damaged recovery mode, which will + enable certain aggressive operations that can make + &man.fsck.8; to survive with file systems that has very + serious data damage. This is a useful last resort when on + disk data damage is very serious and causes &man.fsck.8; to + crash. + + The &man.getaddrinfo.3; function now supports SCTP. + + A bug was fixed in the &man.ipfw.8; utility which displays + extra messages for a NAT rule even when a + flag is specified. + + The &man.ln.1; utility now supports a + flag to check if the source file actually exists. When the + flag is specified and the file does not exist, &man.ln.1; will + issue a warning message. + + The &man.ln.1; utility now allows creating hard + links to symbolic links because the POSIX.1-2008 requires this + behavior for and + flag. + + The &man.lpr.1; utility now support + an flag to send an email after the job is + completed and a option to set the job + title. + + The &man.make.1; utility now supports a + flag to print the input graph only, + without executing any commands. The output is the same as + . When combined with , only the built-in rules of make are + displayed. + + The &man.make.1; utility now supports a + flag to cause file banners not to be + generated in addition to the same effect of a + flag when a option is + specified. + + The &man.make.1; utility now supports the + .MAKE.JOB.PREFIX variable. If + and are specified, its + output for each target is prefixed with a token --- + target --- the first part + of which can be controlled via the variable. + + The &man.make.1; utility now supports + .MAKE.PID and .MAKE.PPID + variable. These are set to process ID of the &man.make.1; + process and its parent process respectively. + + The &man.makefs.8; utility to create a file system image + from a directory tree has been added. + + The &man.mergemaster.8; utility now supports an + option to automatically install files that + differ only in their version control ID strings. + + The &man.mount.8; utility now supports an + option to force it to use the specified program to mount the + file system instead of calling &man.nmount.2; directly. This + is useful when you want to use third party programs such as + FUSE, for example. + + The &man.netstat.1; utility now reports &man.unix.4; + sockets' listen queue statistics when an + flag is specified. + + A bug in the &man.netstat.1; utility has been fixed. It + crashed with the following options in the previous + versions: + + &prompt.user; netstat -m -N foo + + A bug in the &man.netstat.1; utility has been fixed. The + option now works in the icmp6 section as + expected. + + The &man.pciconf.8; utility now supports a + flag, which lists any base address + registers (BAR) that are assigned resources for each + device. + + The &man.powerd.8; program has been improved. Changes + include reasonable CPU load estimation on SMP systems and a + new mode named as hiadaptive for AC-powered + systems. The hiadaptive mode raises the + CPU frequency twice as fast as adaptive, it + drops the CPU frequency 4 times slower, prefers twice lower + CPU load and has an additional delay before leaving the + highest frequency after the period of maximum load. + + The &man.revoke.1; utility has been added. This + is a wrapper of &man.revoke.2; syscall. + + The &man.stat.1; utility now displays an octal + representation of suid, sgid and sticky bits when the + flag is specified. + + The &man.strndup.3; function has been added. + + The &man.tftpd.8; program now supports + a option. This is almost the same as + a option but will generate unique named + based on the submitted filename, a &man.strftime.3; format + string, and a two digit sequence number. The time format + string can be set by an option. + + The &man.wc.1; utility now supports an + flag to output the number of characters in the longest input + line. + + A bug in the &man.rpc.yppasswdd.8; program, which causes + it to leave a zombie process when a password or default shell + is changed, has been fixed. + + The &man.adduser.8; utility now supports + a option to set the mode of a new user's + home directory. + + The &man.atacontrol.8; utility now supports + a spindown command to set or report timeout + after which the device will be spun down. + + The &man.chflags.1; now supports a flag for + verbose output, a flag to ignore errors, + and to allow setting flags on symbolic links + with the same semantics as (for example) &man.chmod.1;. + + The &man.cp.1; now supports a flag, which is + equivalent to flags. + + A bug in the &man.cp.1; utility which prevents POSIX.1e ACL (see + also &man.acl.3;) from copying properly has been fixed. + + The &man.cron.8; utility now supports flag which + overrides the default mail recipient for cron mails unless explicitly + provided by MAILTO= line in crontab + file. + + The &man.dhclient.8; now supports more options described in + &man.dhcp-options.5;. + + The &man.dhclient.8; now + supports is_default_interface() function + which determines if this interface is one with the default + route. + + A bug in the &man.dhclient.8; that prevents removal of the + default route from working has been fixed. + + The &man.environ.7;, environment array of strings now + supports unsetting a variable by setting the first character to + NULL. This is required by third-party software such as + Dovecot + and Postfix. + + The &man.fdisk.8; now supports a flag to + not display any warnings. + + The &man.fetch.1; program and libfetch + library now supports a NO_PROXY environment + variable. This specifies comma- or whitespace-separated list of + host names for which proxies should not be used. If a single + asterisk is specified, the use of proxies is disabled. + + The &man.ffsll.3; and &man.flsll.3; functions have been added. + These functions are the same as &man.ffs.3; and &man.fls.3; except that + they accept long long as the arguments. + + The &man.fortune.6; program now supports + FORTUNE_PATH environment variable to specify + search path of the fortune files. + + A bug in the &man.fortune.6; program that prevents + option with multiple files from working has + been fixed. + + The &man.freebsd-update.conf.5; now supports + IDSIgnorePaths statement. + + The &man.fwcontrol.8; utility now supports option which specifies + node as the root node on the next bus + reset. + + The &man.gcc.1; now + accepts option properly; it was hardcoded + as . + + The &man.ifconfig.8; command now supports + display of WPS IE (Wireless Provisioning Services Information + Element). + + The &man.kgdb.1; command now supports + an add-kld kld + command to locate a &man.kld.4; and load its symbols. + + The &man.kgdb.1; command now has a shared library backend for kernel + files that treats &man.kld.4; as shared libraries and + auto-loading symbols for &man.kld.4; on startup. + + The &man.kgdb.1; now supports a tid command + and other kernel module related commands even for a remote + target. + + The &man.kvm.getcptime.3; function to obtain the global CPU + time statistics from the kernel has been added. + + The libalias library now supports + PORT and + EPRT + FTP commands in lowercase. + + The &man.man.1; now includes a limited support of + &man.bzip2.1;-compressed manual pages. + + The &man.mdconfig.8; command now supports a + (verbose) flag to + command. It shows size and backing store of all &man.md.4; + devices at one time. + + The &man.memrchr.3; function has been added. This behaves + like &man.memchr.3; except that it locates the last occurrence + of the specified character in the string. + + The incorrect output grammar of &man.morse.6; program has + been fixed. + + The &man.mountd.8; utility now supports option which + specifies IP addresses to bind to for TCP and UDP requests. + This option may be specified multiple times. If no + option is specified, + INADDR_ANY will be used. Note that when + specifying IP addresses with this option, it will + automatically add 127.0.0.1 and if IPv6 is + enabled, ::1 to the list. + + The &man.moused.8; utility now supports + flag which changes the speed of scrolling and changes + option behavior to only affect the scroll + threshold. + + The &man.mv.1; command now support POSIX + specification when moving a directory to an existing directory + across devices. + + The &man.periodic.8; now supports + daily_status_mail_rejects_shorten + configuration variable in &man.periodic.conf.5;. This allows + the rejected mail reports to tally the rejects per blacklist + without providing details about individual sender hosts. The + default configuration keeps the reports in their original + form. + + The &man.ping6.8; now uses exit status of + 0 and 2 in the same manner + as &man.ping.8;. + + The &man.ping6.8; now supports an flag, + which makes &man.ping6.8; exit successfully after receiving one + reply packet. + + The &man.ping6.8; now supports + and flags, which are equivalent to + &man.ping.8;'s and + flags, respectively. + + The minimum allowed interval of &man.ping6.8; has been + decreased to 0.000001 from 0.01. + + The &man.realpath.1; utility now supports + a flag to suppress warnings and + accepts multiple paths on its command line. + + The &man.rfcomm.pppd.8; now supports a + flag to register DUN (Dial-Up Networking) service in addition to + the LAN (LAN Access Using PPP) service. + + The &man.sdpd.8; now supports a NAP, + GN, and PANU + profiles. + + The &man.setkey.8; utility now accepts + esp as a protocol name + for the spdadd command. + + A bug in &man.telnetd.8; that caused it to + attempt authentication even when + option is specified has been fixed. + + The &man.top.1; and &man.vmstat.8; commands now + support flag which displays per-CPU + statistics. + + The &man.uuid.enc.le.3;, &man.uuid.dec.le.3;, + &man.uuid.enc.be.3;, and &man.uuid.dec.be.3; functions have been + added. These functions encode/decode a binary representation of + a UUID. - - Multimedia Support + The &man.watch.8; utility now supports more than 10 + &man.snp.4; devices at a time. - + The &man.ypserv.8; daemon now supports a + option to specify the port number on which + it should listen. - + + <filename>/etc/rc.d</filename> Scripts - - Network Interface Support + The &man.rc.conf.5; now supports + dummynet_enable variable which allow + &man.dummynet.4; kernel module to be loaded when + firewall_enable is YES. - The &man.ale.4; driver has been added to provide support - for Atheros AR8121/AR8113/AR8114 Gigabit/Fast Ethernet controllers. + The ntpd &man.rc.8; script + can work with no configuration file + /etc/ntp.conf now. - The &man.em.4; driver has been split into two drivers - with some common parts. The &man.em.4; driver will continue - to support adapters up to the 82575, as well as new - client/desktop adapters. A new &man.igb.4; driver - will support new server adapters. + The ppp &man.rc.8; + script now supports multiple instances. For more details, + see the description of ppp_profile + variable in &man.rc.conf.5;. - The &man.jme.4; driver has been added to provide support - for PCIe network adapters based on JMicron JMC250 Gigabit - Ethernet and JMC260 Fast Ethernet controllers. - - The &man.malo.4; driver has been added to provide - support for Marvell Libertas 88W8335 based PCI network - adapters. + The sysctl &man.rc.8; script now + supports loading /etc/sysctl.conf.local in + addition to /etc/sysctl.conf. + + The &man.rc.conf.5; now supports configuration of + interfaces and attached networks for firewall rule set by + rc.firewall when + firewall_type is simple or + client. See + firewall_client_net, + firewall_simple_iif, + firewall_simple_inet, + firewall_simple_oif, and + firewall_simple_onet. + + - The firmware for the &man.mxge.4; driver has been - updated from 1.4.25 to 1.4.29. + + Contributed Software + + ISC BIND has been updated to + version 9.6.1rc1. - The &man.sf.4; driver has been overhauled to improve its - performance and to add support for checksum offloading. It - should also work on all architectures. + The ACPI-CA has been + updated to 20090521. - The &man.re.4; driver has been overhauled to fix a - number of issues. This driver now has Wake On LAN (WOL) - support. + The ee (easy editor) has + been updated to 1.5.0. This version is now licensed under a + 2-clause BSD license, instead of the Artistic license. - The &man.vr.4; driver has been overhauled to fix a - number of outstanding issues. It also now works on all - architectures. + The hostapd has been updated to + version 0.6.8 + radius ACL support. + + The less has been updated to + version v436. + + The libarchive library has + been updated to version 2.7.0. + + The libexpat library has + been updated from version 1.95.5 to version 2.0.1. + + The ncurses library has been updated + to version 5.7-20081102. + + OpenBSM 1.1 from + Trusted BSD Project has been merged. + + TCPDUMP has been + updated to 4.0.0. + + The timezone database has been updated + to the tzdata2009f release. + + wpa_supplicant has been updated to + version 0.6.8 + + The ZFS file system + has been updated from version 6 to version 13. + + The am-utils has been updated from + version 6.0.10p1 to version 6.1.5. + + The awk has been updated from 1 May + 2007 release to the 23 October 2007 release. + + The bzip2 has been updated from + version 1.0.4 to version 1.0.5. + + The CVS has been updated to + version 1.11.22.1. + + NTP has been updated to version + 4.2.4p5. + + OpenPAM has been updated from the + Figwort release to the Hydrangea release. + + OpenSSH has been updated from + version 4.5p1 to version 5.1p1. + + The &man.resolver.3; library has been updated to + one of ISC BIND 9.4.3. + + sendmail has been updated from + version 8.14.2 to version 8.14.3. + + + + Ports/Packages Collection Infrastructure + + A bug in the &man.pkg.create.1; utility, which + prevented the flag from working has been + fixed. + + The &os; Ports Collection now supports multiple + &man.make.1; jobs in some supported ports. This is + automatically enabled when a port is marked as + MAKE_JOBS_SAFE and improves CPU utilization + at the build stage by passing an option + to the top + level Makefile from the vendor. The + number X is set to the number of + CPUs by default, and can be set by users via a &man.make.1; + variable MAKE_JOBS_NUMBER. For more + details, see ports/Mk/bsd.port.mk. + + + + Release Engineering and Integration + + The supported version of + the GNOME desktop environment + (x11/gnome2) has been + updated to 2.26.3. - The &man.wpi.4; driver has - been updated to include a number of stability fixes. + The supported version of + the KDE desktop environment + (x11/kde4) has been + updated to 4.3.1. + + - - - - - Network Protocols - - The &man.bpf.4; packet filter and capture facility now - supports a zero-copy mode of operation, in which buffers are - loaned from a user process to the kernel. This feature can - be enabled by setting - the net.bpf.zerocopy_enable sysctl - variable to 1. - - ISDN4BSD(I4B), netatm, and all - related subsystems have been removed due to lack of - multi-processor support. - - A bug in TCP options padding, where the wrong padding - bytes were used, has been fixed. - - - - - Disks and Storage - - The &man.aac.4; driver now supports volumes larger than - 2TB in size. - - The &man.ata.4; driver now supports a spindown command for - disks; after a configurable amount of time, if no requests - have been received for a disk, the disk will be spun down - until the next request. The &man.atacontrol.8; utility now - supports a spindown command to configure - this feature. - - The &man.hptrr.4; driver has been updated to version 1.2 - from Highpoint. - - - - - File Systems - - A problem with using &man.mmap.2; on ZFS filesystems has - been fixed. - - A new kernel-mode NFS lock manager has been added, - improving performance and behavior of NFS locking. A new - &man.clear.locks.8; command has been added to clear locks held - on behalf of an NFS client. - - - - - - Userland Changes - - The &man.adduser.8; utility now supports - a option to set the mode of a new user's - home directory. - - BSD-licensed versions of &man.ar.1; and &man.ranlib.1;, - based on libarchive, have replaced the GNU - Binutils versions of these utilities. - - &man.chflags.1; now supports a flag for - verbose output and a flag to ignore errors - with the same semantics as (for example) - &man.chmod.1;. - - For compatiblity with other implementations, &man.cp.1; now - supports a flag, which is equivalent to - specifying the flags. - - BSD-licensed version of &man.cpio.1; based on - libarchive, has replaced the GNU cpio. - Note that the GNU cpio is still installed as - gcpio. - - The &man.env.1; program now supports - which will completely unset the given variable - name by removing it from the environment, - instead of just setting it to a null value. - - The &man.fdopendir.3; library function has been added. - - The &man.fetch.3; library now support HTTP 1.1 - If-Modified-Since behavior. The &man.fetch.1; program now - supports - which will only download the specified HTTP URL if the content - is newer than filename. - - &man.find.1; has been enhanced by the addition of a number - of primaries that were present in GNU find but not &os; - &man.find.1;. - - &man.jexec.8; now supports option to specify the - jail where the command will be executed. - - &man.kgdb.1; now supports a new add-kld - command to make it easier to debug crash dumps with kernel - modules. - - The &man.ls.1; program now supports a - option to specify a date format string to be used with the long - format () output. - - &man.nc.1; now supports a switch to - disable the use of TCP options. - - The &man.ping6.8; utility now returns 2 - when the packet transmission was successful but no responses - were received (this is the same behavior as &man.ping.8;). - It returned a non-zero value before this change. - - The &man.procstat.1; utility has been added to display - detailed information about processes. - - The &man.realpath.1; utility now supports - a flag to suppress warnings; it now also - accepts multiple paths on its command line. - - The &man.split.1; utility now supports a - flag to split a file into a certain number of chunks. - - The &man.tar.1; utility now supports a - flag to enable &man.compress.1;-style - compression/decompression. - - The &man.tar.1; utility now supports a - flag to ignore user/group names - on create and extract. - - The &man.tar.1; utility now supports an - flag to sparsify files on extraction. - - The &man.tar.1; utility now supports a - flag to substitute filenames based on the specified regular - expression. - - The &man.tcgetsid.3; library function has been added to - return the process group ID for the session leader for the - controlling terminal. It is defined in IEEE Std 1003.1-2001 - (POSIX). - - &man.top.1; now supports a flag to - provide per-CPU usage statistics. - - &man.zdump.8; is now working properly on 64 bit architectures. - - - &man.traceroute.8; now has the ability to print the AS - number for each hop with the new switch; a - new option allows selecting a particular - WHOIS server. - - &man.traceroute6.8; now supports a flag - to send probe packets with no upper-layer protocol, rather than - the usual UDP probe packets. - - - <filename>/etc/rc.d</filename> Scripts - - - - - - - - Contributed Software - - AMD has been updated from 6.0.10 - to 6.1.5. - - awk has been updated from 1 May - 2007 release to the 23 October 2007 release. - - bzip2 has been updated from 1.0.4 - to 1.0.5. - - CVS has been updated from 1.11.17 - to a post-1.11.22 snapshot from 10 March 2008. - - FILE has been updated from 4.23 - to 5.03. - - hostapd has been - updated from 0.5.8 to 0.5.10. - - IPFilter has been updated from - 4.1.23 to 4.1.28. - - less has been updated from - v408 to v429. - - ncurses has been updated from - 5.6-20061217 to 5.6-20080503. - - OpenSSH has been updated - from 4.5p1 to 5.1p1. - - OpenPAM has been updated from the - Figwort release to the Hydrangea release. - - sendmail has been updated from - 8.14.1 to 8.14.3. - - The timezone database has been updated from - the tzdata2008h release to - the tzdata2009j release. - - The stdtime part of libc, &man.zdump.8 and &man.zic.8 - have been updated from the tzcode2004a - release to the tzcode2009h release. - If you have upgraded from source or via the &man.freebsd-update.8, - then please run &man.tzsetup.8 to install a new /etc/localtime. - - - WPA Supplicant has been - updated from 0.5.8 to 0.5.10. - - - - - Ports/Packages Collection Infrastructure - - The &man.pkg.create.1; utility now supports - . When this option is specified and a - package tarball exists, it will not be overwritten. This is - useful when multiple packages are saved with several consecutive - runs of &man.pkg.create.1; with the - options. - - The pkg_sign and pkg_check utilities for cryptographically - signing &os; packages have been removed. They were only useful - for packages compressed using &man.gzip.1;; however - &man.bzip2.1; compression has been the norm for some time - now. - - - - - Release Engineering and Integration - - The supported version of - the GNOME desktop environment - (x11/gnome2) has been - updated from 2.20.1 to 2.22. - - - - - Documentation - - - - - - - - Upgrading from previous releases of &os; - - Beginning with &os; 6.2-RELEASE, - binary upgrades between RELEASE versions (and snapshots of the - various security branches) are supported using the - &man.freebsd-update.8; utility. The binary upgrade procedure will - update unmodified userland utilities, as well as unmodified GENERIC or - SMP kernels distributed as a part of an official &os; release. - The &man.freebsd-update.8; utility requires that the host being - upgraded have Internet connectivity. - - An older form of binary upgrade is supported through the - Upgrade option from the main &man.sysinstall.8; - menu on CDROM distribution media. This type of binary upgrade - may be useful on non-&arch.i386;, non-&arch.amd64; machines - or on systems with no Internet connectivity. - - Source-based upgrades (those based on recompiling the &os; - base system from source code) from previous versions are - supported, according to the instructions in - /usr/src/UPDATING. - - - Upgrading &os; should, of course, only be attempted after - backing up all data and configuration - files. - - + + Upgrading from previous releases of &os; + + Upgrades between RELEASE versions (and + snapshots of the various security branches) are supported using + the &man.freebsd-update.8; utility. The binary upgrade + procedure will update unmodified userland utilities, as well as + unmodified GENERIC or SMP kernels distributed as a part of an + official &os; release. The &man.freebsd-update.8; utility + requires that the host being upgraded has Internet + connectivity. + + An older form of binary upgrade is supported through the + Upgrade option from the main + &man.sysinstall.8; menu on CDROM distribution media. This type + of binary upgrade may be useful on non-&arch.i386;, + non-&arch.amd64; machines or on systems with no Internet + connectivity. + + Source-based upgrades (those based on recompiling the &os; + base system from source code) from previous versions are + supported, according to the instructions in + /usr/src/UPDATING. + + + Upgrading &os; should, of course, only be attempted after + backing up all data and configuration + files. + +
diff --git a/release/doc/en_US.ISO8859-1/share/sgml/release.dsl b/release/doc/en_US.ISO8859-1/share/sgml/release.dsl index 7b1c975fb12..0dee5652284 100644 --- a/release/doc/en_US.ISO8859-1/share/sgml/release.dsl +++ b/release/doc/en_US.ISO8859-1/share/sgml/release.dsl @@ -35,17 +35,6 @@ (list (list "HREF" "mailto:questions@FreeBSD.org")) (literal "questions@FreeBSD.org")) (literal ">."))) - (make element gi: "p" - attributes: (list (list "align" "center")) - (make element gi: "small" - (literal "All users of FreeBSD ") - (literal (entity-text "release.branch")) - (literal " should subscribe to the ") - (literal "<") - (create-link (list (list "HREF" "mailto:current@FreeBSD.org")) - (literal "current@FreeBSD.org")) - (literal "> mailing list."))) - (make element gi: "p" attributes: (list (list "align" "center")) (make element gi: "small" diff --git a/release/doc/share/sgml/release.dsl b/release/doc/share/sgml/release.dsl index dd6ac3e1dfe..4a19a837c6e 100644 --- a/release/doc/share/sgml/release.dsl +++ b/release/doc/share/sgml/release.dsl @@ -121,7 +121,14 @@ ((or (equal? arch #f) (equal? arch "") (equal? arch "all")) - (process-children-trim)) + (make sequence + (if (and (not (null? role)) (equal? role "7.1")) + (literal " [7.1R]") + (empty-sosofo)) + (if (and (not (null? role)) (equal? role "7.2")) + (literal " [7.2R]") + (empty-sosofo)) + (process-children-trim)) (else (make sequence (literal "[") @@ -135,6 +142,12 @@ (loop (car rest) (cdr rest))) (empty-sosofo)))) (literal "] ") + (if (and (not (null? role)) (equal? role "7.1")) + (literal " [7.1R] ") + (empty-sosofo)) + (if (and (not (null? role)) (equal? role "7.2")) + (literal " [7.2R] ") + (empty-sosofo)) (process-children-trim)))) (if (and (not (null? role)) (equal? role "merged")) (literal " [" merged-string "]") @@ -158,7 +171,14 @@ ((or (equal? arch #f) (equal? arch "") (equal? arch "all")) - (process-children-trim)) + (make sequence + (if (and (not (null? role)) (equal? role "7.1")) + (literal " [7.1R] ") + (empty-sosofo)) + (if (and (not (null? role)) (equal? role "7.2")) + (literal " [7.2R] ") + (empty-sosofo)) + (process-children-trim))) (else (make sequence (literal "[") @@ -172,10 +192,16 @@ (loop (car rest) (cdr rest))) (empty-sosofo)))) (literal "] ") + (if (and (not (null? role)) (equal? role "7.1")) + (literal " [7.1R]") + (empty-sosofo)) + (if (and (not (null? role)) (equal? role "7.2")) + (literal " [7.2R]") + (empty-sosofo)) (process-children-trim)))) (if (and (not (null? role)) (equal? role "merged")) (literal " [" merged-string "]") - (empty-sosofo))))))) + (empty-sosofo)))))))) ]]> - + - - - - + - + - + - - + + - + - - - + + - + @@ -54,11 +48,8 @@ - + - - - From 7d9bbacdb426f43f1a2041a1dbf130d8170fe10b Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Thu, 26 Nov 2009 21:14:09 +0000 Subject: [PATCH 0678/2592] Remove newbus MPSAFE entry; it was reverted. Spotted by: attilio --- release/doc/en_US.ISO8859-1/relnotes/article.sgml | 2 -- 1 file changed, 2 deletions(-) diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.sgml b/release/doc/en_US.ISO8859-1/relnotes/article.sgml index 76a6f29ffe5..fd4c9a0294c 100644 --- a/release/doc/en_US.ISO8859-1/relnotes/article.sgml +++ b/release/doc/en_US.ISO8859-1/relnotes/article.sgml @@ -329,8 +329,6 @@ without SS to use CLFLUSH feature. - The &os; newbus subsystem is now MPSAFE. - The &man.jail.8; subsystem has been updated. Changes include: From c2a9d0a20ed4e5ab215d85e23fc29b3b6a5f14eb Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Thu, 26 Nov 2009 22:09:37 +0000 Subject: [PATCH 0679/2592] More items: - U-Boot support library for loader(8) (ARM, PowerPC) - multiprocessor (SMP) (PowerPC) - E500 (Book-E) embedded CPU support (PowerPC) - Freescale PowerQUICCIII MPC85xx system-on-chip support (single- and dual-core) (PowerPC) - Feroceon, Sheeva embedded CPU support - Marvell Orion (88F5281), Kirkwood (88F6281) and Discovery Innovation (MV-78100) systems-on-chip support (ARM) - DS133x and DS1553 RTC support - tsec(4) Gigabit Ethernet driver - mge(4) Gigabit Ethernet driver - kernel core dump support (PowerPC) - mini dump support (ARM) - gdbserver(1) support for (ARM, PowerPC) Submitted by: raj --- .../doc/en_US.ISO8859-1/relnotes/article.sgml | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.sgml b/release/doc/en_US.ISO8859-1/relnotes/article.sgml index fd4c9a0294c..e7d53db18ca 100644 --- a/release/doc/en_US.ISO8859-1/relnotes/article.sgml +++ b/release/doc/en_US.ISO8859-1/relnotes/article.sgml @@ -448,6 +448,12 @@ epair0b: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 emulators/linux_base-f10 (Fedora 10). + The &os;/&arch.arm; now + supports mini dump. + + The &os;/&arch.powerpc; now + supports kernel core dump. + The &os; virtual memory subsystem now supports fully transparent use of superpages for application memory; @@ -603,6 +609,9 @@ epair0b: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 The &man.boot0cfg.8; utility now supports a new option to set the volume ID. + The &man.loader.8; now + supports U-Boot support library. + The &man.boot.8; now supports 4-byte volume ID that certain versions of &windows; put into the MBR and invoking PXE by pressing the F6 key on some supported BIOSes. @@ -638,6 +647,23 @@ epair0b: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 The &os; now includes experimental support for &arch.mips; platform. + Support for RTC on Dallas Semiconductor chips + has been improved. The DS133x and DS1553 are now + supported. + + The &os;/&arch.arm; now supports + Feroceon and Sheeva embedded CPU, Marvell Orion (88F5281), + Kirkwood (88F6281), Discovery Innovation (MV-78100) + systems-on-chip CPU. + + The &os;/&arch.powerpc; now + supports SMP machines + + The &os;/&arch.powerpc; now + supports E500 (Book-E) embedded CPU and Freescale + PowerQUICCIII MPC85xx system-on-chip (including single and + dual-core). + The &man.acpi.4; subsystem now supports the System Resource Affinity Table (SRAT) used to describe affinity relationships between CPUs and memory, ACPI 3.0 fields in @@ -885,6 +911,12 @@ epair0b: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 + The mge(4) driver has + been added to provide support for Marvell Gigabit Ethernet + controllers found on ARM-based SOCs (Orion, Kirkwood, + Discovery), as well as on system controllers for PowerPC + processors (MV64430, MV6446x). + The &man.miibus.4; driver now supports the Marvell 88E3016. @@ -903,6 +935,11 @@ epair0b: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 The &man.nge.4; driver has been improved and now works on all platforms. + The tsec(4) driver has been added to + provide support for Freescale integrated Three-Speed + Ethernet Controller (TSEC). This driver also works with + the enhanced version of the controller (eTSEC). + The &man.uath.4; driver for USB wireless LAN adapter based on Atheros AR5005UG and AR5005UX chipsets has been added. The &man.uathload.8; utility, a firmware @@ -1736,6 +1773,9 @@ options NFSD # for NFS server generate a new directory name for use by the backup. This is enabled by default. + The &man.gdbserver.1; now supports &arch.arm; + and &arch.powerpc; platforms. + The &man.gpt.8; program has been removed in favor of &man.gpart.8;. From 5e542944684b17f3c460d23bbe1da3077575da66 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 26 Nov 2009 22:35:26 +0000 Subject: [PATCH 0680/2592] MFC r199534: Provide an effective (relocated) address when building modules metadata. This lets modules loaded dynamically in loader(8) work for U-Boot-based platforms. --- sys/boot/uboot/common/metadata.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/boot/uboot/common/metadata.c b/sys/boot/uboot/common/metadata.c index 9c8ce94d4f3..e5f4b04c37b 100644 --- a/sys/boot/uboot/common/metadata.c +++ b/sys/boot/uboot/common/metadata.c @@ -231,6 +231,7 @@ md_copymodules(vm_offset_t addr) struct preloaded_file *fp; struct file_metadata *md; int c; + vm_offset_t a; c = addr != 0; /* start with the first module on the list, should be the kernel */ @@ -240,7 +241,8 @@ md_copymodules(vm_offset_t addr) MOD_TYPE(addr, fp->f_type, c); if (fp->f_args) MOD_ARGS(addr, fp->f_args, c); - MOD_ADDR(addr, fp->f_addr, c); + a = fp->f_addr - __elfN(relocation_offset); + MOD_ADDR(addr, a, c); MOD_SIZE(addr, fp->f_size, c); for (md = fp->f_metadata; md != NULL; md = md->md_next) { if (!(md->md_type & MODINFOMD_NOCOPY)) From fac7a2abd8f59501c4b6c1c92335cdfe530725ff Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Fri, 27 Nov 2009 00:21:17 +0000 Subject: [PATCH 0681/2592] 8.0-RELEASE is done, shift stable/8 to -STABLE designation. --- sys/conf/newvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index a9b666c0c61..400dd5682b7 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.0" -BRANCH="PRERELEASE" +BRANCH="STABLE" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi From 9a6d31880270a6bb9a646693d48eec4cd6678493 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Fri, 27 Nov 2009 02:45:50 +0000 Subject: [PATCH 0682/2592] MFC r199227: Add the possibility for vfs.root.mountfrom tunable to accept a list of items rather than a single one. While there fix also a nit in a comment. Sponsored by: Sandvine Incorporated --- sys/kern/vfs_mount.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 15899ce1f0b..a75a019cb53 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -104,13 +104,17 @@ struct vnode *rootvnode; * The root filesystem is detailed in the kernel environment variable * vfs.root.mountfrom, which is expected to be in the general format * - * :[] + * :[][ :[] ...] * vfsname := the name of a VFS known to the kernel and capable * of being mounted as root * path := disk device name or other data used by the filesystem * to locate its physical store * - * The environment variable vfs.root.mountfrom options is a comma delimited + * If the environment variable vfs.root.mountfrom is a space separated list, + * each list element is tried in turn and the root filesystem will be mounted + * from the first one that suceeds. + * + * The environment variable vfs.root.mountfrom.options is a comma delimited * set of string mount options. These mount options must be parseable * by nmount() in the kernel. */ @@ -1643,7 +1647,7 @@ vfs_opterror(struct vfsoptlist *opts, const char *fmt, ...) void vfs_mountroot(void) { - char *cp, *options; + char *cp, *cpt, *options, *tmpdev; int error, i, asked = 0; options = NULL; @@ -1695,10 +1699,15 @@ vfs_mountroot(void) */ cp = getenv("vfs.root.mountfrom"); if (cp != NULL) { - error = vfs_mountroot_try(cp, options); + cpt = cp; + while ((tmpdev = strsep(&cpt, " \t")) != NULL) { + error = vfs_mountroot_try(tmpdev, options); + if (error == 0) { + freeenv(cp); + goto mounted; + } + } freeenv(cp); - if (!error) - goto mounted; } /* From 08742bd2573893f4150145eb2c551e6d26770baf Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Fri, 27 Nov 2009 02:47:49 +0000 Subject: [PATCH 0683/2592] MFC r199260: Add sysctls in ahd(4) in order to keep track of different classes of errors. So far 3 different classes are present (correctable, uncorrectable and fatal) but more can be added easilly. Sponsored by: Sandvine Incorporated --- sys/dev/aic7xxx/ahd_pci.c | 4 ++ sys/dev/aic7xxx/aic79xx.c | 66 ++++++++++++++++++++++- sys/dev/aic7xxx/aic79xx.h | 28 ++++++++++ sys/dev/aic7xxx/aic79xx_osm.c | 99 +++++++++++++++++++++++++++++++++++ sys/dev/aic7xxx/aic79xx_osm.h | 2 + 5 files changed, 197 insertions(+), 2 deletions(-) diff --git a/sys/dev/aic7xxx/ahd_pci.c b/sys/dev/aic7xxx/ahd_pci.c index f077c89d73a..3a011616008 100644 --- a/sys/dev/aic7xxx/ahd_pci.c +++ b/sys/dev/aic7xxx/ahd_pci.c @@ -134,6 +134,7 @@ ahd_pci_attach(device_t dev) return (error); } + ahd_sysctl(ahd); ahd_attach(ahd); return (0); } @@ -198,6 +199,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd) bus_release_resource(ahd->dev_softc, regs_type, regs_id, regs); regs = NULL; + AHD_CORRECTABLE_ERROR(ahd); } else { command &= ~PCIM_CMD_PORTEN; aic_pci_write_config(ahd->dev_softc, @@ -214,6 +216,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd) if (regs == NULL) { device_printf(ahd->dev_softc, "can't allocate register resources\n"); + AHD_UNCORRECTABLE_ERROR(ahd); return (ENOMEM); } ahd->tags[0] = rman_get_bustag(regs); @@ -226,6 +229,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd) if (regs2 == NULL) { device_printf(ahd->dev_softc, "can't allocate register resources\n"); + AHD_UNCORRECTABLE_ERROR(ahd); return (ENOMEM); } ahd->tags[1] = rman_get_bustag(regs2); diff --git a/sys/dev/aic7xxx/aic79xx.c b/sys/dev/aic7xxx/aic79xx.c index aa771af927d..feee494e052 100644 --- a/sys/dev/aic7xxx/aic79xx.c +++ b/sys/dev/aic7xxx/aic79xx.c @@ -401,6 +401,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) if (scb == NULL) { printf("%s: Warning - GSFIFO SCB %d invalid\n", ahd_name(ahd), scbid); + AHD_CORRECTABLE_ERROR(ahd); continue; } /* @@ -525,6 +526,7 @@ rescan_fifos: if (scb == NULL) { printf("%s: Warning - DMA-up and complete " "SCB %d invalid\n", ahd_name(ahd), scbid); + AHD_CORRECTABLE_ERROR(ahd); continue; } hscb_ptr = (uint8_t *)scb->hscb; @@ -546,6 +548,7 @@ rescan_fifos: if (scb == NULL) { printf("%s: Warning - Complete Qfrz SCB %d invalid\n", ahd_name(ahd), scbid); + AHD_CORRECTABLE_ERROR(ahd); continue; } @@ -563,6 +566,7 @@ rescan_fifos: if (scb == NULL) { printf("%s: Warning - Complete SCB %d invalid\n", ahd_name(ahd), scbid); + AHD_CORRECTABLE_ERROR(ahd); continue; } @@ -870,6 +874,7 @@ ahd_run_qoutfifo(struct ahd_softc *ahd) "(cmdcmplt)\nQOUTPOS = %d\n", ahd_name(ahd), scb_index, ahd->qoutfifonext); + AHD_CORRECTABLE_ERROR(ahd); ahd_dump_card_state(ahd); } else if ((completion->sg_status & SG_STATUS_VALID) != 0) { ahd_handle_scb_status(ahd, scb); @@ -897,9 +902,11 @@ ahd_handle_hwerrint(struct ahd_softc *ahd) error = ahd_inb(ahd, ERROR); for (i = 0; i < num_errors; i++) { - if ((error & ahd_hard_errors[i].errno) != 0) + if ((error & ahd_hard_errors[i].errno) != 0) { printf("%s: hwerrint, %s\n", ahd_name(ahd), ahd_hard_errors[i].errmesg); + AHD_UNCORRECTABLE_ERROR(ahd); + } } ahd_dump_card_state(ahd); @@ -990,6 +997,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ahd_name(ahd)); ahd_dump_card_state(ahd); ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + AHD_UNCORRECTABLE_ERROR(ahd); break; case STATUS_OVERRUN: { @@ -1005,6 +1013,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) printf("SCB %d Packetized Status Overrun", scbid); ahd_dump_card_state(ahd); ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); + AHD_UNCORRECTABLE_ERROR(ahd); break; } case CFG4ISTAT_INTR: @@ -1017,6 +1026,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) if (scb == NULL) { ahd_dump_card_state(ahd); printf("CFG4ISTAT: Free SCB %d referenced", scbid); + AHD_FATAL_ERROR(ahd); panic("For safety"); } ahd_outq(ahd, HADDR, scb->sense_busaddr); @@ -1044,6 +1054,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) case P_MESGIN: ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); printf("%s: Issued Bus Reset.\n", ahd_name(ahd)); + AHD_UNCORRECTABLE_ERROR(ahd); break; case P_COMMAND: { @@ -1068,6 +1079,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) scbid = ahd_get_scbptr(ahd); scb = ahd_lookup_scb(ahd, scbid); if (scb == NULL) { + AHD_CORRECTABLE_ERROR(ahd); printf("Invalid phase with no valid SCB. " "Resetting bus.\n"); ahd_reset_channel(ahd, 'A', @@ -1127,6 +1139,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) #ifdef AHD_DEBUG if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { ahd_print_path(ahd, scb); + AHD_CORRECTABLE_ERROR(ahd); printf("Unexpected command phase from " "packetized target\n"); } @@ -1214,6 +1227,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) && bus_phase != P_MESGOUT) { printf("ahd_intr: HOST_MSG_LOOP bad " "phase 0x%x\n", bus_phase); + AHD_CORRECTABLE_ERROR(ahd); /* * Probably transitioned to bus free before * we got here. Just punt the message. @@ -1316,6 +1330,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ahd_name(ahd), 'A', SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)), lastphase, ahd_inb(ahd, SCSISIGI)); + AHD_CORRECTABLE_ERROR(ahd); break; } case MISSED_BUSFREE: @@ -1328,6 +1343,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ahd_name(ahd), 'A', SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)), lastphase, ahd_inb(ahd, SCSISIGI)); + AHD_CORRECTABLE_ERROR(ahd); ahd_restart(ahd); return; } @@ -1387,6 +1403,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) devinfo.lun); scbid = ahd_get_scbptr(ahd); scb = ahd_lookup_scb(ahd, scbid); + AHD_CORRECTABLE_ERROR(ahd); if (scb != NULL && (scb->flags & SCB_RECOVERY_SCB) != 0) /* @@ -1570,11 +1587,13 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) printf("%s: SCSI offset overrun detected. Resetting bus.\n", ahd_name(ahd)); + AHD_CORRECTABLE_ERROR(ahd); ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); } else if ((status & SCSIRSTI) != 0) { printf("%s: Someone reset channel A\n", ahd_name(ahd)); ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE); + AHD_UNCORRECTABLE_ERROR(ahd); } else if ((status & SCSIPERR) != 0) { /* Make sure the sequencer is in a safe location. */ @@ -1619,6 +1638,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) "valid during SELTO scb(0x%x)\n", ahd_name(ahd), scbid); ahd_dump_card_state(ahd); + AHD_UNCORRECTABLE_ERROR(ahd); } else { struct ahd_devinfo devinfo; #ifdef AHD_DEBUG @@ -1654,6 +1674,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) } else if (status3 != 0) { printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n", ahd_name(ahd), status3); + AHD_CORRECTABLE_ERROR(ahd); ahd_outb(ahd, CLRSINT3, status3); } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) { @@ -1712,6 +1733,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) "during unexpected busfree\n", ahd_name(ahd), scbid, mode); packetized = 0; + AHD_CORRECTABLE_ERROR(ahd); } else packetized = (scb->flags & SCB_PACKETIZED) != 0; clear_fifo = 1; @@ -1856,6 +1878,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd) ahd_scsisigi_print(curphase, &cur_col, 50); ahd_perrdiag_print(perrdiag, &cur_col, 50); printf("\n"); + AHD_CORRECTABLE_ERROR(ahd); ahd_dump_card_state(ahd); } @@ -1864,6 +1887,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd) printf("%s: Gross protocol error during incoming " "packet. lqistat1 == 0x%x. Resetting bus.\n", ahd_name(ahd), lqistat1); + AHD_UNCORRECTABLE_ERROR(ahd); } ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); return; @@ -1891,6 +1915,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd) */ ahd_outb(ahd, LQCTL2, LQIRETRY); printf("LQIRetry for LQICRCI_LQ to release ACK\n"); + AHD_CORRECTABLE_ERROR(ahd); } else if ((lqistat1 & LQICRCI_NLQ) != 0) { /* * We detected a CRC error in a NON-LQ packet. @@ -1942,6 +1967,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd) if (scb == NULL) { printf("%s: No SCB valid for LQICRC_NLQ. " "Resetting bus\n", ahd_name(ahd)); + AHD_UNCORRECTABLE_ERROR(ahd); ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); return; } @@ -1999,9 +2025,11 @@ ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1) && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) { if ((lqistat1 & LQIPHASE_LQ) != 0) { printf("LQIRETRY for LQIPHASE_LQ\n"); + AHD_CORRECTABLE_ERROR(ahd); ahd_outb(ahd, LQCTL2, LQIRETRY); } else if ((lqistat1 & LQIPHASE_NLQ) != 0) { printf("LQIRETRY for LQIPHASE_NLQ\n"); + AHD_CORRECTABLE_ERROR(ahd); ahd_outb(ahd, LQCTL2, LQIRETRY); } else panic("ahd_handle_lqiphase_error: No phase errors\n"); @@ -2010,6 +2038,7 @@ ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1) ahd_unpause(ahd); } else { printf("Reseting Channel for LQI Phase error\n"); + AHD_CORRECTABLE_ERROR(ahd); ahd_dump_card_state(ahd); ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); } @@ -2099,6 +2128,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime) ahd_print_path(ahd, scb); printf("Probable outgoing LQ CRC error. " "Retrying command\n"); + AHD_CORRECTABLE_ERROR(ahd); } scb->crc_retry_count++; } else { @@ -2134,6 +2164,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime) scb = ahd_lookup_scb(ahd, scbid); ahd_print_path(ahd, scb); printf("Unexpected PKT busfree condition\n"); + AHD_UNCORRECTABLE_ERROR(ahd); ahd_dump_card_state(ahd); ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A', SCB_GET_LUN(scb), SCB_GET_TAG(scb), @@ -2143,6 +2174,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime) return (1); } printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd)); + AHD_UNCORRECTABLE_ERROR(ahd); ahd_dump_card_state(ahd); /* Restart the sequencer. */ return (1); @@ -2421,6 +2453,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) ahd_lookup_phase_entry(lastphase)->phasemsg, aborted, ahd_inw(ahd, PRGMCNT)); + AHD_UNCORRECTABLE_ERROR(ahd); ahd_dump_card_state(ahd); if (lastphase != P_BUSFREE) ahd_force_renegotiation(ahd, &devinfo); @@ -2456,6 +2489,7 @@ ahd_handle_proto_violation(struct ahd_softc *ahd) ahd_print_devinfo(ahd, &devinfo); printf("Target did not send an IDENTIFY message. " "LASTPHASE = 0x%x.\n", lastphase); + AHD_UNCORRECTABLE_ERROR(ahd); scb = NULL; } else if (scb == NULL) { /* @@ -2464,12 +2498,14 @@ ahd_handle_proto_violation(struct ahd_softc *ahd) */ ahd_print_devinfo(ahd, &devinfo); printf("No SCB found during protocol violation\n"); + AHD_UNCORRECTABLE_ERROR(ahd); goto proto_violation_reset; } else { aic_set_transaction_status(scb, CAM_SEQUENCE_FAIL); if ((seq_flags & NO_CDB_SENT) != 0) { ahd_print_path(ahd, scb); printf("No or incomplete CDB sent to device.\n"); + AHD_UNCORRECTABLE_ERROR(ahd); } else if ((ahd_inb_scbram(ahd, SCB_CONTROL) & STATUS_RCVD) == 0) { /* @@ -2484,6 +2520,7 @@ ahd_handle_proto_violation(struct ahd_softc *ahd) } else { ahd_print_path(ahd, scb); printf("Unknown protocol violation.\n"); + AHD_UNCORRECTABLE_ERROR(ahd); ahd_dump_card_state(ahd); } } @@ -2499,6 +2536,7 @@ proto_violation_reset: found = ahd_reset_channel(ahd, 'A', TRUE); printf("%s: Issued Channel %c Bus Reset. " "%d SCBs aborted\n", ahd_name(ahd), 'A', found); + AHD_UNCORRECTABLE_ERROR(ahd); } else { /* * Leave the selection hardware off in case @@ -2521,6 +2559,7 @@ proto_violation_reset: } printf("Protocol violation %s. Attempting to abort.\n", ahd_lookup_phase_entry(curphase)->phasemsg); + AHD_UNCORRECTABLE_ERROR(ahd); } } @@ -2602,6 +2641,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd) "%s: First Instruction 0x%x now 0x%x\n", ahd_name(ahd), ahd_name(ahd), first_instr, seqaddr); + AHD_FATAL_ERROR(ahd); ahd_dump_card_state(ahd); panic("critical section loop"); } @@ -3566,6 +3606,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, } else if (scb == NULL) { printf("%s: WARNING. No pending message for " "I_T msgin. Issuing NO-OP\n", ahd_name(ahd)); + AHD_CORRECTABLE_ERROR(ahd); ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP; ahd->msgout_len++; ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT; @@ -3596,6 +3637,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, ahd->msgout_len++; ahd_print_path(ahd, scb); printf("Bus Device Reset Message Sent\n"); + AHD_CORRECTABLE_ERROR(ahd); /* * Clear our selection hardware in advance of * the busfree. We may have an entry in the waiting @@ -3615,6 +3657,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, ahd_print_path(ahd, scb); printf("Abort%s Message Sent\n", (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : ""); + AHD_CORRECTABLE_ERROR(ahd); /* * Clear our selection hardware in advance of * the busfree. We may have an entry in the waiting @@ -3638,6 +3681,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, "does not have a waiting message\n"); printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid, devinfo->target_mask); + AHD_FATAL_ERROR(ahd); panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x " "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control, ahd_inb_scbram(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT), @@ -5129,9 +5173,11 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, lun, AC_SENT_BDR, NULL); if (message != NULL - && (verbose_level <= bootverbose)) + && (verbose_level <= bootverbose)) { + AHD_CORRECTABLE_ERROR(ahd); printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), message, devinfo->channel, devinfo->target, found); + } } #ifdef AHD_TARGET_MODE @@ -5509,6 +5555,7 @@ ahd_reset(struct ahd_softc *ahd, int reinit) if (wait == 0) { printf("%s: WARNING - Failed chip reset! " "Trying to initialize anyway.\n", ahd_name(ahd)); + AHD_FATAL_ERROR(ahd); } ahd_outb(ahd, HCNTRL, ahd->pause); @@ -5630,6 +5677,7 @@ ahd_init_scbdata(struct ahd_softc *ahd) scb_data->maxhscbs = ahd_probe_scbs(ahd); if (scb_data->maxhscbs == 0) { printf("%s: No SCB space found\n", ahd_name(ahd)); + AHD_FATAL_ERROR(ahd); return (ENXIO); } @@ -6474,6 +6522,7 @@ ahd_init(struct ahd_softc *ahd) printf("%s: WARNING. Termination is not configured correctly.\n" "%s: WARNING. SCSI bus operations may FAIL.\n", ahd_name(ahd), ahd_name(ahd)); + AHD_CORRECTABLE_ERROR(ahd); } init_done: ahd_restart(ahd); @@ -6830,6 +6879,7 @@ ahd_default_config(struct ahd_softc *ahd) if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) { printf("%s: unable to allocate ahd_tmode_tstate. " "Failing attach\n", ahd_name(ahd)); + AHD_FATAL_ERROR(ahd); return (ENOMEM); } @@ -6909,6 +6959,7 @@ ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc) if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) { printf("%s: unable to allocate ahd_tmode_tstate. " "Failing attach\n", ahd_name(ahd)); + AHD_FATAL_ERROR(ahd); return (ENOMEM); } @@ -7135,6 +7186,7 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) if (maxloops == 0) { printf("Infinite interrupt loop, INTSTAT = %x", ahd_inb(ahd, INTSTAT)); + AHD_FATAL_ERROR(ahd); } ahd->qfreeze_cnt++; ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt); @@ -7440,6 +7492,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, if (scb == NULL) { printf("qinpos = %d, SCB index = %d\n", qinpos, ahd->qinfifo[qinpos]); + AHD_FATAL_ERROR(ahd); panic("Loop 1\n"); } @@ -8195,20 +8248,26 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) switch (SIU_PKTFAIL_CODE(siu)) { case SIU_PFC_NONE: printf("No packet failure found\n"); + AHD_UNCORRECTABLE_ERROR(ahd); break; case SIU_PFC_CIU_FIELDS_INVALID: printf("Invalid Command IU Field\n"); + AHD_UNCORRECTABLE_ERROR(ahd); break; case SIU_PFC_TMF_NOT_SUPPORTED: printf("TMF not supportd\n"); + AHD_UNCORRECTABLE_ERROR(ahd); break; case SIU_PFC_TMF_FAILED: printf("TMF failed\n"); + AHD_UNCORRECTABLE_ERROR(ahd); break; case SIU_PFC_INVALID_TYPE_CODE: printf("Invalid L_Q Type code\n"); + AHD_UNCORRECTABLE_ERROR(ahd); break; case SIU_PFC_ILLEGAL_REQUEST: + AHD_UNCORRECTABLE_ERROR(ahd); printf("Illegal request\n"); default: break; @@ -9281,6 +9340,7 @@ ahd_recover_commands(struct ahd_softc *ahd) printf("%s: Recovery Initiated - Card was %spaused\n", ahd_name(ahd), was_paused ? "" : "not "); + AHD_CORRECTABLE_ERROR(ahd); ahd_dump_card_state(ahd); ahd_pause_and_flushwork(ahd); @@ -9507,6 +9567,7 @@ ahd_other_scb_timeout(struct ahd_softc *ahd, struct scb *scb, (scb->flags & SCB_OTHERTCL_TIMEOUT) != 0 ? " again\n" : "\n"); + AHD_UNCORRECTABLE_ERROR(ahd); newtimeout = aic_get_timeout(scb); scb->flags |= SCB_OTHERTCL_TIMEOUT; found = 0; @@ -9929,6 +9990,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) if (lstate != NULL) { xpt_print_path(ccb->ccb_h.path); printf("Lun already enabled\n"); + AHD_CORRECTABLE_ERROR(ahd); ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; return; } diff --git a/sys/dev/aic7xxx/aic79xx.h b/sys/dev/aic7xxx/aic79xx.h index e9c8847905b..f59d7740a58 100644 --- a/sys/dev/aic7xxx/aic79xx.h +++ b/sys/dev/aic7xxx/aic79xx.h @@ -1061,6 +1061,27 @@ typedef enum { #define AHD_MODE_UNKNOWN_MSK AHD_MK_MSK(AHD_MODE_UNKNOWN) #define AHD_MODE_ANY_MSK (~0) +typedef enum { + AHD_SYSCTL_ROOT, + AHD_SYSCTL_SUMMARY, + AHD_SYSCTL_DEBUG, + AHD_SYSCTL_NUMBER +} ahd_sysctl_types_t; + +typedef enum { + AHD_ERRORS_CORRECTABLE, + AHD_ERRORS_UNCORRECTABLE, + AHD_ERRORS_FATAL, + AHD_ERRORS_NUMBER +} ahd_sysctl_errors_t; + +#define AHD_CORRECTABLE_ERROR(sc) \ + (((sc)->summerr[AHD_ERRORS_CORRECTABLE])++) +#define AHD_UNCORRECTABLE_ERROR(sc) \ + (((sc)->summerr[AHD_ERRORS_UNCORRECTABLE])++) +#define AHD_FATAL_ERROR(sc) \ + (((sc)->summerr[AHD_ERRORS_FATAL])++) + typedef uint8_t ahd_mode_state; typedef void ahd_callback_t (void *); @@ -1158,6 +1179,13 @@ struct ahd_softc { uint32_t cmdcmplt_counts[AHD_STAT_BUCKETS]; uint32_t cmdcmplt_total; + /* + * Errors statistics and printouts. + */ + struct sysctl_ctx_list sysctl_ctx[AHD_SYSCTL_NUMBER]; + struct sysctl_oid *sysctl_tree[AHD_SYSCTL_NUMBER]; + u_int summerr[AHD_ERRORS_NUMBER]; + /* * Card characteristics */ diff --git a/sys/dev/aic7xxx/aic79xx_osm.c b/sys/dev/aic7xxx/aic79xx_osm.c index e375d245056..81eade6d4f7 100644 --- a/sys/dev/aic7xxx/aic79xx_osm.c +++ b/sys/dev/aic7xxx/aic79xx_osm.c @@ -77,6 +77,63 @@ static int ahd_create_path(struct ahd_softc *ahd, char channel, u_int target, u_int lun, struct cam_path **path); +static const char *ahd_sysctl_node_elements[] = { + "root", + "summary", + "debug" +}; + +static const char *ahd_sysctl_node_descriptions[] = { + "root error collection for aic79xx controllers", + "summary collection for aic79xx controllers", + "debug collection for aic79xx controllers" +}; + +static const char *ahd_sysctl_errors_elements[] = { + "Cerrors", + "Uerrors", + "Ferrors" +}; + +static const char *ahd_sysctl_errors_descriptions[] = { + "Correctable errors", + "Uncorrectable errors", + "Fatal errors" +}; + +static int +ahd_set_debugcounters(SYSCTL_HANDLER_ARGS) +{ + struct ahd_softc *sc; + int error, tmpv; + + tmpv = 0; + sc = arg1; + error = sysctl_handle_int(oidp, &tmpv, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (tmpv < 0 || tmpv >= AHD_ERRORS_NUMBER) + return (EINVAL); + sc->summerr[arg2] = tmpv; + return (0); +} + +static int +ahd_clear_allcounters(SYSCTL_HANDLER_ARGS) +{ + struct ahd_softc *sc; + int error, tmpv; + + tmpv = 0; + sc = arg1; + error = sysctl_handle_int(oidp, &tmpv, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (tmpv != 0) + bzero(sc->summerr, sizeof(sc->summerr)); + return (0); +} + static int ahd_create_path(struct ahd_softc *ahd, char channel, u_int target, u_int lun, struct cam_path **path) @@ -88,6 +145,48 @@ ahd_create_path(struct ahd_softc *ahd, char channel, u_int target, path_id, target, lun)); } +void +ahd_sysctl(struct ahd_softc *ahd) +{ + u_int i; + + for (i = 0; i < AHD_SYSCTL_NUMBER; i++) + sysctl_ctx_init(&ahd->sysctl_ctx[i]); + + ahd->sysctl_tree[AHD_SYSCTL_ROOT] = + SYSCTL_ADD_NODE(&ahd->sysctl_ctx[AHD_SYSCTL_ROOT], + SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, + device_get_nameunit(ahd->dev_softc), CTLFLAG_RD, 0, + ahd_sysctl_node_descriptions[AHD_SYSCTL_ROOT]); + SYSCTL_ADD_PROC(&ahd->sysctl_ctx[AHD_SYSCTL_ROOT], + SYSCTL_CHILDREN(ahd->sysctl_tree[AHD_SYSCTL_ROOT]), + OID_AUTO, "clear", CTLTYPE_UINT | CTLFLAG_RW, ahd, + 0, ahd_clear_allcounters, "IU", + "Clear all counters"); + + for (i = AHD_SYSCTL_SUMMARY; i < AHD_SYSCTL_NUMBER; i++) + ahd->sysctl_tree[i] = + SYSCTL_ADD_NODE(&ahd->sysctl_ctx[i], + SYSCTL_CHILDREN(ahd->sysctl_tree[AHD_SYSCTL_ROOT]), + OID_AUTO, ahd_sysctl_node_elements[i], + CTLFLAG_RD, 0, + ahd_sysctl_node_descriptions[i]); + + for (i = AHD_ERRORS_CORRECTABLE; i < AHD_ERRORS_NUMBER; i++) { + SYSCTL_ADD_UINT(&ahd->sysctl_ctx[AHD_SYSCTL_SUMMARY], + SYSCTL_CHILDREN(ahd->sysctl_tree[AHD_SYSCTL_SUMMARY]), + OID_AUTO, ahd_sysctl_errors_elements[i], + CTLFLAG_RD, &ahd->summerr[i], i, + ahd_sysctl_errors_descriptions[i]); + SYSCTL_ADD_PROC(&ahd->sysctl_ctx[AHD_SYSCTL_DEBUG], + SYSCTL_CHILDREN(ahd->sysctl_tree[AHD_SYSCTL_DEBUG]), + OID_AUTO, ahd_sysctl_errors_elements[i], + CTLFLAG_RW | CTLTYPE_UINT, ahd, i, + ahd_set_debugcounters, "IU", + ahd_sysctl_errors_descriptions[i]); + } +} + int ahd_map_int(struct ahd_softc *ahd) { diff --git a/sys/dev/aic7xxx/aic79xx_osm.h b/sys/dev/aic7xxx/aic79xx_osm.h index b786cec2baf..692f3f9eed1 100644 --- a/sys/dev/aic7xxx/aic79xx_osm.h +++ b/sys/dev/aic7xxx/aic79xx_osm.h @@ -51,6 +51,7 @@ #include #include #include +#include #define AIC_PCI_CONFIG 1 #include @@ -259,6 +260,7 @@ void ahd_platform_free(struct ahd_softc *ahd); int ahd_map_int(struct ahd_softc *ahd); int ahd_attach(struct ahd_softc *); int ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd); +void ahd_sysctl(struct ahd_softc *ahd); int ahd_detach(device_t); #define ahd_platform_init(arg) From 9f69cbc0cb8fa2cdfa80063985a8a6b5831cbecd Mon Sep 17 00:00:00 2001 From: Alexander Leidinger Date: Fri, 27 Nov 2009 10:53:46 +0000 Subject: [PATCH 0684/2592] MFC r199582: Fix minor resource leak in a function which was introduced by changing an err() to a return in r106254. --- sbin/fsck/fsck.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sbin/fsck/fsck.c b/sbin/fsck/fsck.c index 13eb9f06e06..24c4e13124a 100644 --- a/sbin/fsck/fsck.c +++ b/sbin/fsck/fsck.c @@ -543,8 +543,10 @@ getfslab(const char *str) if ((fd = open(str, O_RDONLY)) == -1) err(1, "cannot open `%s'", str); - if (ioctl(fd, DIOCGDINFO, &dl) == -1) + if (ioctl(fd, DIOCGDINFO, &dl) == -1) { + (void) close(fd); return(NULL); + } (void) close(fd); From 96b404c963257a2c606e6ab0738271b18daf762a Mon Sep 17 00:00:00 2001 From: Alexander Leidinger Date: Fri, 27 Nov 2009 10:55:28 +0000 Subject: [PATCH 0685/2592] MFC r199584: Fix minor memory leak in a function. --- sbin/mount_cd9660/mount_cd9660.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sbin/mount_cd9660/mount_cd9660.c b/sbin/mount_cd9660/mount_cd9660.c index 9a9bd9d0455..922f6cf7321 100644 --- a/sbin/mount_cd9660/mount_cd9660.c +++ b/sbin/mount_cd9660/mount_cd9660.c @@ -251,8 +251,10 @@ set_charset(struct iovec **iov, int *iovlen, const char *localcs) if ((cs_disk = malloc(ICONV_CSNMAXLEN)) == NULL) return (-1); - if ((cs_local = malloc(ICONV_CSNMAXLEN)) == NULL) + if ((cs_local = malloc(ICONV_CSNMAXLEN)) == NULL) { + free(cs_disk); return (-1); + } strncpy(cs_disk, ENCODING_UNICODE, ICONV_CSNMAXLEN); strncpy(cs_local, kiconv_quirkcs(localcs, KICONV_VENDOR_MICSFT), ICONV_CSNMAXLEN); From 000d6fb9d9e60a2fd9fcb091cba283f5ce57137b Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Fri, 27 Nov 2009 13:38:59 +0000 Subject: [PATCH 0686/2592] MFC r199580: tsec: Use IFQ_DRV macros for managing interface packet queue. This lets tsec(4) work with ALTQ. Submitted by: Marcin Ligenza --- sys/dev/tsec/if_tsec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/tsec/if_tsec.c b/sys/dev/tsec/if_tsec.c index 2fb271019dd..204fce932b2 100644 --- a/sys/dev/tsec/if_tsec.c +++ b/sys/dev/tsec/if_tsec.c @@ -716,9 +716,9 @@ tsec_start_locked(struct ifnet *ifp) bus_dmamap_sync(sc->tsec_tx_dtag, sc->tsec_tx_dmap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - for (;;) { + while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { /* Get packet from the queue */ - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); if (m0 == NULL) break; @@ -755,7 +755,7 @@ tsec_start_locked(struct ifnet *ifp) m0 = mtmp; if (tsec_encap(sc, m0, fcb_inserted)) { - IF_PREPEND(&ifp->if_snd, m0); + IFQ_DRV_PREPEND(&ifp->if_snd, m0); ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } From b478ed7a6baf04b48361eed0e8238ae0d8a11a4e Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sat, 28 Nov 2009 18:34:35 +0000 Subject: [PATCH 0687/2592] MFC r197961,197962: Fix two typos that caused DSISR and CR not to be preserved across context switches. --- sys/powerpc/aim/swtch.S | 2 +- sys/powerpc/aim/trap_subr.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 /* 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 b17e03bd8aecc896d09d17eb191e7e27dd0c3d5a Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sat, 28 Nov 2009 18:36:58 +0000 Subject: [PATCH 0688/2592] MFC r198400: 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 b8147cb06e7..4a3ede9c3e8 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -869,15 +869,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 0b5ac7b6b9c081194bb7f74cfb891630f07b137d Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sat, 28 Nov 2009 19:37:58 +0000 Subject: [PATCH 0689/2592] MFC r198212,198378,198427,198428,198723,198724,198725,198731: SMP support for PowerPC G5 systems. r198724: 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. r198723,198725,198731: Loop on blocked threads when using ULE scheduler, removing an XXX MP comment. r198427: Add some more paranoia to setting HID registers, and update the AIM clock routines to work better with SMP. r198378: Add SMP support on U3-based G5 systems. While here, correct the 64-bit tlbie function to set the CPU to 64-bit mode correctly. r198212: Don't assume that physical addresses are identity mapped. This allows the second processor on G5 systems to start. --- sys/powerpc/aim/clock.c | 16 +-- sys/powerpc/aim/copyinout.c | 15 ++- sys/powerpc/aim/machdep.c | 2 + sys/powerpc/aim/mmu_oea64.c | 81 ++++++++------ sys/powerpc/aim/mp_cpudep.c | 175 ++++++++++++++++++++++++------- sys/powerpc/aim/platform_chrp.c | 13 ++- sys/powerpc/aim/swtch.S | 39 ++++--- 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 +- 13 files changed, 276 insertions(+), 120 deletions(-) diff --git a/sys/powerpc/aim/clock.c b/sys/powerpc/aim/clock.c index 0a5391f7424..b182b01f32d 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. @@ -113,12 +112,15 @@ decr_intr(struct trapframe *frame) tick += ticks_per_intr; mtdec(tick); - 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 +147,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/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; 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/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 4a3ede9c3e8..3d4c42b24e7 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. */ @@ -1259,7 +1258,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); @@ -1432,16 +1431,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); @@ -1584,7 +1582,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); @@ -1972,14 +1970,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; @@ -2015,16 +2028,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); @@ -2045,12 +2056,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); } @@ -2097,8 +2115,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..50f64d79441 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] __aligned(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,118 @@ 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)); + powerpc_sync(); - msr = PSL_FP | PSL_IR | PSL_DR | PSL_ME | PSL_RI; - powerpc_sync(); - isync(); - mtmsr(msr); - isync(); + break; + case MPC7450: + case MPC7455: + case MPC7457: + /* Only MPC745x CPUs have an L3 cache. */ + bsp_state[3] = mfspr(SPR_L3CR); - 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("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; \ + sync; isync" + : "=r"(reg) : "K"(SPR_HID0), "r"(bsp_state)); + __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; isync; \ + mtspr %1, %0; sync; 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 7a8fe3b9464..2258c126e72 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,15 +233,20 @@ 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; + (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/aim/swtch.S b/sys/powerpc/aim/swtch.S index 71d39d0b77f..079705709f5 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,36 +82,36 @@ 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 */ + 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 @@ -118,7 +119,19 @@ 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 */ + 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 */ 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 1abf14215a9a25e79627aa902e3b0db9cb65fc9a Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sat, 28 Nov 2009 20:02:45 +0000 Subject: [PATCH 0690/2592] MFC r199226: Provide a real fix to the too-many-translations problem when booting from CD on 64-bit hardware to replace existing band-aids. This occurred when the preloaded mdroot required too many mappings for the static buffer. Since we only use the translations buffer once, allocate a dynamic buffer on the stack. This early in the boot process, the call chain is quite short and we can be assured of having sufficient stack space. --- sys/powerpc/aim/mmu_oea64.c | 118 +++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 3d4c42b24e7..7a212b05034 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -264,7 +264,6 @@ 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[96]; extern struct pmap ofw_pmap; @@ -708,18 +707,74 @@ moea64_bridge_cpu_bootstrap(mmu_t mmup, int ap) tlbia(); } +static void +moea64_add_ofw_mappings(mmu_t mmup, phandle_t mmu, size_t sz) +{ + struct ofw_map translations[sz/sizeof(struct ofw_map)]; + register_t msr; + vm_offset_t off; + int i, ofw_mappings; + + bzero(translations, sz); + if (OF_getprop(mmu, "translations", translations, sz) == -1) + panic("moea64_bootstrap: can't get ofw translations"); + + CTR0(KTR_PMAP, "moea64_add_ofw_mappings: translations"); + sz /= sizeof(*translations); + qsort(translations, sz, sizeof (*translations), om_cmp); + + for (i = 0, ofw_mappings = 0; i < sz; i++) { + CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x", + (uint32_t)(translations[i].om_pa_lo), translations[i].om_va, + translations[i].om_len); + + if (translations[i].om_pa_lo % PAGE_SIZE) + panic("OFW translation not page-aligned!"); + + if (translations[i].om_pa_hi) + panic("OFW translations above 32-bit boundary!"); + + /* Now enter the pages for this mapping */ + + /* + * Lock the ofw pmap. pmap_kenter(), which we use for the + * pages the kernel also needs, does its own locking. + */ + PMAP_LOCK(&ofw_pmap); + DISABLE_TRANS(msr); + for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) { + struct vm_page m; + + /* Map low memory mappings into the kernel pmap, too. + * These are typically mappings made by the loader, + * so we need them if we want to keep executing. */ + + if (translations[i].om_va + off < SEGMENT_LENGTH) + moea64_kenter(mmup, translations[i].om_va + off, + translations[i].om_va + off); + + m.phys_addr = translations[i].om_pa_lo + off; + moea64_enter_locked(&ofw_pmap, + translations[i].om_va + off, &m, VM_PROT_ALL, 1); + + ofw_mappings++; + } + ENABLE_TRANS(msr); + PMAP_UNLOCK(&ofw_pmap); + } +} + static void moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend) { ihandle_t mmui; phandle_t chosen; phandle_t mmu; - int sz; + size_t sz; int i, j; - int ofw_mappings; vm_size_t size, physsz, hwphyssz; vm_offset_t pa, va, off; - uint32_t msr; + register_t msr; void *dpcpu; /* We don't have a direct map since there is no BAT */ @@ -865,7 +920,6 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele off = (vm_offset_t)(moea64_bpvo_pool); for (pa = off; pa < off + size; pa += PAGE_SIZE) moea64_kenter(mmup, pa, pa); - ENABLE_TRANS(msr); /* * Map certain important things, like ourselves. @@ -876,7 +930,6 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele * address. */ - DISABLE_TRANS(msr); for (pa = kernelstart & ~PAGE_MASK; pa < kernelend; pa += PAGE_SIZE) moea64_kenter(mmup, pa, pa); ENABLE_TRANS(msr); @@ -897,57 +950,10 @@ 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 (sz > sizeof(translations)) - panic("moea64_bootstrap: too many ofw translations (%d)", - sz/sizeof(*translations)); + if (sz > 6144 /* tmpstksz - 2 KB headroom */) + panic("moea64_bootstrap: too many ofw translations"); - bzero(translations, sz); - if (OF_getprop(mmu, "translations", translations, sz) == -1) - panic("moea64_bootstrap: can't get ofw translations"); - - CTR0(KTR_PMAP, "moea64_bootstrap: translations"); - sz /= sizeof(*translations); - qsort(translations, sz, sizeof (*translations), om_cmp); - - for (i = 0, ofw_mappings = 0; i < sz; i++) { - CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x", - (uint32_t)(translations[i].om_pa_lo), translations[i].om_va, - translations[i].om_len); - - if (translations[i].om_pa_lo % PAGE_SIZE) - panic("OFW translation not page-aligned!"); - - if (translations[i].om_pa_hi) - panic("OFW translations above 32-bit boundary!"); - - /* Now enter the pages for this mapping */ - - /* - * Lock the ofw pmap. pmap_kenter(), which we use for the - * pages the kernel also needs, does its own locking. - */ - PMAP_LOCK(&ofw_pmap); - DISABLE_TRANS(msr); - for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) { - struct vm_page m; - - /* Map low memory mappings into the kernel pmap, too. - * These are typically mappings made by the loader, - * so we need them if we want to keep executing. */ - - if (translations[i].om_va + off < SEGMENT_LENGTH) - moea64_kenter(mmup, translations[i].om_va + off, - translations[i].om_va + off); - - m.phys_addr = translations[i].om_pa_lo + off; - moea64_enter_locked(&ofw_pmap, - translations[i].om_va + off, &m, VM_PROT_ALL, 1); - - ofw_mappings++; - } - ENABLE_TRANS(msr); - PMAP_UNLOCK(&ofw_pmap); - } + moea64_add_ofw_mappings(mmup, mmu, sz); } #ifdef SMP From 66b3ab74eb5b7eb96d8481fa6487c2f859761d07 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 29 Nov 2009 18:03:49 +0000 Subject: [PATCH 0691/2592] MFC r199828: Flag controlling origin expansion in DT_FLAGS is DF_ORIGIN, not DF_1_ORIGIN. --- libexec/rtld-elf/rtld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 2eebf220b5c..6073c5089e2 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -898,7 +898,7 @@ digest_dynamic(Obj_Entry *obj, int early) #endif case DT_FLAGS: - if ((dynp->d_un.d_val & DF_1_ORIGIN) && trust) + if ((dynp->d_un.d_val & DF_ORIGIN) && trust) obj->z_origin = true; if (dynp->d_un.d_val & DF_SYMBOLIC) obj->symbolic = true; From e39d8277755b48753be7b1139a472bfa88ed00a4 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 18:51:58 +0000 Subject: [PATCH 0692/2592] MFC r197585. Remove unnecessary device reinitialization. --- sys/dev/jme/if_jme.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sys/dev/jme/if_jme.c b/sys/dev/jme/if_jme.c index 86d9c57ee01..c2e64f02f8c 100644 --- a/sys/dev/jme/if_jme.c +++ b/sys/dev/jme/if_jme.c @@ -306,6 +306,10 @@ jme_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) sc = ifp->if_softc; JME_LOCK(sc); + if ((ifp->if_flags & IFF_UP) == 0) { + JME_UNLOCK(sc); + return; + } mii = device_get_softc(sc->jme_miibus); mii_pollstat(mii); @@ -1585,8 +1589,10 @@ jme_resume(device_t dev) pmc + PCIR_POWER_STATUS, pmstat, 2); } ifp = sc->jme_ifp; - if ((ifp->if_flags & IFF_UP) != 0) + if ((ifp->if_flags & IFF_UP) != 0) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; jme_init_locked(sc); + } JME_UNLOCK(sc); @@ -1861,6 +1867,7 @@ jme_watchdog(struct jme_softc *sc) if ((sc->jme_flags & JME_FLAG_LINK) == 0) { if_printf(sc->jme_ifp, "watchdog timeout (missed link)\n"); ifp->if_oerrors++; + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; jme_init_locked(sc); return; } @@ -1875,6 +1882,7 @@ jme_watchdog(struct jme_softc *sc) if_printf(sc->jme_ifp, "watchdog timeout\n"); ifp->if_oerrors++; + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; jme_init_locked(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) taskqueue_enqueue(sc->jme_tq, &sc->jme_tx_task); @@ -1917,8 +1925,10 @@ jme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) VLAN_CAPABILITIES(ifp); } ifp->if_mtu = ifr->ifr_mtu; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; jme_init_locked(sc); + } JME_UNLOCK(sc); } break; @@ -2642,6 +2652,8 @@ jme_init_locked(struct jme_softc *sc) ifp = sc->jme_ifp; mii = device_get_softc(sc->jme_miibus); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + return; /* * Cancel any pending I/O. */ From ee9449a1453492c2e1b6ff282408688ead6cc781 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 18:59:43 +0000 Subject: [PATCH 0693/2592] MFC 197587. Don't encode model id twice. Reported by: Kristof Provost sigsegv dot be> --- sys/dev/mii/e1000phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c index 4f2fa66f6e8..a4e505fab48 100644 --- a/sys/dev/mii/e1000phy.c +++ b/sys/dev/mii/e1000phy.c @@ -248,7 +248,7 @@ e1000phy_reset(struct mii_softc *sc) } } - switch (MII_MODEL(esc->mii_model)) { + switch (esc->mii_model) { case MII_MODEL_MARVELL_E3082: case MII_MODEL_MARVELL_E1112: case MII_MODEL_MARVELL_E1118: From 5bb9dc0d8fbafc022c90085da41916b832514c56 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:03:20 +0000 Subject: [PATCH 0694/2592] MFC 197588. Some fiber PHY(88E1112) does not seem to set resolved speed so always assume we've got IFM_1000_SX. --- sys/dev/mii/e1000phy.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c index a4e505fab48..39f41fe2943 100644 --- a/sys/dev/mii/e1000phy.c +++ b/sys/dev/mii/e1000phy.c @@ -485,8 +485,11 @@ e1000phy_status(struct mii_softc *sc) return; } } else { - if (ssr & E1000_SSR_1000MBS) - mii->mii_media_active |= IFM_1000_SX; + /* + * Some fiber PHY(88E1112) does not seem to set resolved + * speed so always assume we've got IFM_1000_SX. + */ + mii->mii_media_active |= IFM_1000_SX; } if (ssr & E1000_SSR_DUPLEX) From b76e9c0853d62dbf8b405f0649f8e6fc4823e0e2 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:06:33 +0000 Subject: [PATCH 0695/2592] MFC 197589. Fix MIB statistics clear routine. This should fix alignment errors on sparc64. Reported by: Garrett Damore < gdamore <> opensolaris dot org > --- sys/dev/msk/if_msk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index d961f0b924d..53decddd2f1 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -4190,7 +4190,7 @@ msk_stats_clear(struct msk_if_softc *sc_if) gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_PHY_ADDR); GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac | GM_PAR_MIB_CLR); /* Read all MIB Counters with Clear Mode set. */ - for (i = GM_RXF_UC_OK; i <= GM_TXE_FIFO_UR; i++) + for (i = GM_RXF_UC_OK; i <= GM_TXE_FIFO_UR; i += sizeof(uint32_t)) reg = MSK_READ_MIB32(sc_if->msk_port, i); /* Clear MIB Clear Counter Mode. */ gmac &= ~GM_PAR_MIB_CLR; From 4b4edd61016519b48ab65c27140d21db5532bf29 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:11:03 +0000 Subject: [PATCH 0696/2592] MFC 197590. Add hack to pass controller specific information to phy driver. Unlike most other PHYs there is no easy way to know which media type the PHY supports on Marvell PHYs. MIIF_HAVEFIBER flags is now passed via bus-specific instance variable of a device. While I'm here add 88E1112 specific work around to set SIGDET polarity low. Many thanks "Eugene Perevyazko dnepro dot net>" who kindly gave remote access to system with DGE-560SX. --- sys/dev/mii/e1000phy.c | 22 ++++++++++++++++++++++ sys/dev/mii/e1000phyreg.h | 5 +++++ sys/dev/msk/if_msk.c | 33 +++++++++++++++++++-------------- sys/dev/msk/if_mskreg.h | 7 ++++++- 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c index 39f41fe2943..2ff31d3520e 100644 --- a/sys/dev/mii/e1000phy.c +++ b/sys/dev/mii/e1000phy.c @@ -59,6 +59,9 @@ __FBSDID("$FreeBSD$"); #include "miidevs.h" #include +/* XXX */ +#include +#include #include "miibus_if.h" @@ -68,6 +71,7 @@ static int e1000phy_attach(device_t); struct e1000phy_softc { struct mii_softc mii_sc; int mii_model; + struct msk_mii_data *mmd; }; static device_method_t e1000phy_methods[] = { @@ -130,6 +134,7 @@ e1000phy_attach(device_t dev) struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; + struct ifnet *ifp; esc = device_get_softc(dev); sc = &esc->mii_sc; @@ -145,6 +150,16 @@ e1000phy_attach(device_t dev) mii->mii_instance++; esc->mii_model = MII_MODEL(ma->mii_id2); + ifp = sc->mii_pdata->mii_ifp; + if (strcmp(ifp->if_dname, "msk") == 0) { + /* XXX */ + esc->mmd = device_get_ivars( + device_get_parent(device_get_parent(dev))); + if (esc->mmd != NULL && + (esc->mmd->mii_flags & MIIF_HAVEFIBER) != 0) + sc->mii_flags |= MIIF_HAVEFIBER; + } + switch (esc->mii_model) { case MII_MODEL_MARVELL_E1011: case MII_MODEL_MARVELL_E1112: @@ -199,6 +214,13 @@ e1000phy_reset(struct mii_softc *sc) reg &= ~E1000_SCR_MODE_MASK; reg |= E1000_SCR_MODE_1000BX; PHY_WRITE(sc, E1000_SCR, reg); + if (esc->mmd != NULL && esc->mmd->pmd == 'P') { + /* Set SIGDET polarity low for SFP module. */ + PHY_WRITE(sc, E1000_EADR, 1); + reg = PHY_READ(sc, E1000_SCR); + reg |= E1000_SCR_FIB_SIGDET_POLARITY; + PHY_WRITE(sc, E1000_SCR, reg); + } PHY_WRITE(sc, E1000_EADR, page); } } else { diff --git a/sys/dev/mii/e1000phyreg.h b/sys/dev/mii/e1000phyreg.h index 41b9c0937ec..6894760e77b 100644 --- a/sys/dev/mii/e1000phyreg.h +++ b/sys/dev/mii/e1000phyreg.h @@ -248,6 +248,11 @@ #define E1000_SCR_EN_DETECT_MASK 0x0300 +/* 88E1112 page 1 fiber specific control */ +#define E1000_SCR_FIB_TX_DIS 0x0008 +#define E1000_SCR_FIB_SIGDET_POLARITY 0x0200 +#define E1000_SCR_FIB_FORCE_LINK 0x0400 + /* 88E1112 page 2 */ #define E1000_SCR_MODE_MASK 0x0380 #define E1000_SCR_MODE_AUTO 0x0180 diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 53decddd2f1..bba9e3034c5 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1447,6 +1447,7 @@ msk_attach(device_t dev) struct msk_softc *sc; struct msk_if_softc *sc_if; struct ifnet *ifp; + struct msk_mii_data *mmd; int i, port, error; uint8_t eaddr[6]; @@ -1456,7 +1457,8 @@ msk_attach(device_t dev) error = 0; sc_if = device_get_softc(dev); sc = device_get_softc(device_get_parent(dev)); - port = *(int *)device_get_ivars(dev); + mmd = device_get_ivars(dev); + port = mmd->port; sc_if->msk_if_dev = dev; sc_if->msk_port = port; @@ -1602,7 +1604,8 @@ static int mskc_attach(device_t dev) { struct msk_softc *sc; - int error, msic, msir, *port, reg; + struct msk_mii_data *mmd; + int error, msic, msir, reg; sc = device_get_softc(dev); sc->msk_dev = dev; @@ -1671,10 +1674,6 @@ mskc_attach(device_t dev) CSR_WRITE_2(sc, B0_CTST, CS_RST_SET); CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR); sc->msk_pmd = CSR_READ_1(sc, B2_PMD_TYP); - if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S') - sc->msk_coppertype = 0; - else - sc->msk_coppertype = 1; /* Check number of MACs. */ sc->msk_num_port = 1; if ((CSR_READ_1(sc, B2_Y2_HW_RES) & CFG_DUAL_MAC_MSK) == @@ -1814,15 +1813,18 @@ mskc_attach(device_t dev) error = ENXIO; goto fail; } - port = malloc(sizeof(int), M_DEVBUF, M_WAITOK); - if (port == NULL) { + mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK | M_ZERO); + if (mmd == NULL) { device_printf(dev, "failed to allocate memory for " "ivars of PORT_A\n"); error = ENXIO; goto fail; } - *port = MSK_PORT_A; - device_set_ivars(sc->msk_devs[MSK_PORT_A], port); + mmd->port = MSK_PORT_A; + mmd->pmd = sc->msk_pmd; + if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S' || sc->msk_pmd == 'P') + mmd->mii_flags |= MIIF_HAVEFIBER; + device_set_ivars(sc->msk_devs[MSK_PORT_A], mmd); if (sc->msk_num_port > 1) { sc->msk_devs[MSK_PORT_B] = device_add_child(dev, "msk", -1); @@ -1831,15 +1833,18 @@ mskc_attach(device_t dev) error = ENXIO; goto fail; } - port = malloc(sizeof(int), M_DEVBUF, M_WAITOK); - if (port == NULL) { + mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK | M_ZERO); + if (mmd == NULL) { device_printf(dev, "failed to allocate memory for " "ivars of PORT_B\n"); error = ENXIO; goto fail; } - *port = MSK_PORT_B; - device_set_ivars(sc->msk_devs[MSK_PORT_B], port); + mmd->port = MSK_PORT_B; + mmd->pmd = sc->msk_pmd; + if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S' || sc->msk_pmd == 'P') + mmd->mii_flags |= MIIF_HAVEFIBER; + device_set_ivars(sc->msk_devs[MSK_PORT_B], mmd); } error = bus_generic_attach(dev); diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index 69d2527a277..f7a0809dca1 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -2404,6 +2404,12 @@ struct msk_ring_data { #define MSK_TX_TIMEOUT 5 #define MSK_PUT_WM 10 +struct msk_mii_data { + int port; + uint32_t pmd; + int mii_flags; +}; + /* Forward decl. */ struct msk_if_softc; @@ -2467,7 +2473,6 @@ struct msk_softc { uint8_t msk_num_port; int msk_ramsize; /* amount of SRAM on NIC */ uint32_t msk_pmd; /* physical media type */ - uint32_t msk_coppertype; uint32_t msk_intrmask; uint32_t msk_intrhwemask; uint32_t msk_pflags; From 26ac5ae5da48c6f63b15d4a640826392c70c6524 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:15:08 +0000 Subject: [PATCH 0697/2592] MFC 197591. Add workaround for Yukon XL which has hardware bug that can't flush FIFO. --- sys/dev/msk/if_msk.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index bba9e3034c5..7469f6a2bbf 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -3801,9 +3801,14 @@ msk_init_locked(struct msk_if_softc *sc_if) /* Set receive filter. */ msk_rxfilter(sc_if); - /* Flush Rx MAC FIFO on any flow control or error. */ - CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_MSK), - GMR_FS_ANY_ERR); + if (sc->msk_hw_id == CHIP_ID_YUKON_XL) { + /* Clear flush mask - HW bug. */ + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_MSK), 0); + } else { + /* Flush Rx MAC FIFO on any flow control or error. */ + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_MSK), + GMR_FS_ANY_ERR); + } /* * Set Rx FIFO flush threshold to 64 bytes + 1 FIFO word From 02b6f045fee487f3555ade15ac25518f87289483 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:18:22 +0000 Subject: [PATCH 0698/2592] MFC 197592. Add DGE-560SX(Yukon XL) to the supported device list. Many thanks to "Eugene Perevyazko dnepro dot net>" who kindly gave remote access to system with DGE-560SX. --- sys/dev/msk/if_msk.c | 2 ++ sys/dev/msk/if_mskreg.h | 1 + 2 files changed, 3 insertions(+) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 7469f6a2bbf..912eaeb498c 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -225,6 +225,8 @@ static struct msk_product { "Marvell Yukon 88E8072 Gigabit Ethernet" }, { VENDORID_DLINK, DEVICEID_DLINK_DGE550SX, "D-Link 550SX Gigabit Ethernet" }, + { VENDORID_DLINK, DEVICEID_DLINK_DGE560SX, + "D-Link 560SX Gigabit Ethernet" }, { VENDORID_DLINK, DEVICEID_DLINK_DGE560T, "D-Link 560T Gigabit Ethernet" } }; diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index f7a0809dca1..b42a01fe1a5 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -149,6 +149,7 @@ * D-Link gigabit ethernet device ID */ #define DEVICEID_DLINK_DGE550SX 0x4001 +#define DEVICEID_DLINK_DGE560SX 0x4002 #define DEVICEID_DLINK_DGE560T 0x4b00 #define BIT_31 (1 << 31) From fcd5f788ff059c019c329d59850b829767fbdc29 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:22:44 +0000 Subject: [PATCH 0699/2592] MFC 197593. DGE-560SX 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 d98a5faadf5..7e8e5b305f5 100644 --- a/share/man/man4/msk.4 +++ b/share/man/man4/msk.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 2, 2009 +.Dd September 28, 2009 .Dt MSK 4 .Os .Sh NAME @@ -158,6 +158,8 @@ Yukon II based Gigabit Ethernet controller chips, including: .It D-Link 550SX Gigabit Ethernet .It +D-Link 560SX Gigabit Ethernet +.It D-Link 560T Gigabit Ethernet .It Marvell Yukon 88E8021CU Gigabit Ethernet From 621838143bd7f4b6fbf8da683e313a4d95dd69a8 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:25:15 +0000 Subject: [PATCH 0700/2592] MFC 197600. For AR8132 fast ethernet controller, do not report 1000baseT capability to mii(4). Even though AR8132 uses the same model/ revision number of F1 gigabit PHY, the PHY has no ability to establish 1000baseT link. I have no idea why Atheros use the same device/model id for this PHY. With this change atphy(4) does not report 1000baseT media capability and manual 1000baseT configuration is also disabled which is more desirable behavior for 10/100Mbps PHY. --- sys/dev/alc/if_alc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c index a53af779b03..aeb46213811 100644 --- a/sys/dev/alc/if_alc.c +++ b/sys/dev/alc/if_alc.c @@ -234,6 +234,16 @@ alc_miibus_readreg(device_t dev, int phy, int reg) if (phy != sc->alc_phyaddr) return (0); + /* + * For AR8132 fast ethernet controller, do not report 1000baseT + * capability to mii(4). Even though AR8132 uses the same + * model/revision number of F1 gigabit PHY, the PHY has no + * ability to establish 1000baseT link. + */ + if ((sc->alc_flags & ALC_FLAG_FASTETHER) != 0 && + reg == MII_EXTSR) + return (0); + CSR_WRITE_4(sc, ALC_MDIO, MDIO_OP_EXECUTE | MDIO_OP_READ | MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg)); for (i = ALC_PHY_TIMEOUT; i > 0; i--) { From 4a288ceae972d693d12e4c741ec2128d34191a8c Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:29:11 +0000 Subject: [PATCH 0701/2592] MFC 197627. Fix multicast handling. All Atheros controllers use big-endian form in computing multicast hash. PR: kern/139137 --- sys/dev/ae/if_ae.c | 2 +- sys/dev/age/if_age.c | 2 +- sys/dev/alc/if_alc.c | 2 +- sys/dev/ale/if_ale.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/dev/ae/if_ae.c b/sys/dev/ae/if_ae.c index da26ee79951..33ecfbe48ff 100644 --- a/sys/dev/ae/if_ae.c +++ b/sys/dev/ae/if_ae.c @@ -2077,7 +2077,7 @@ ae_rxfilter(ae_softc_t *sc) TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; - crc = ether_crc32_le(LLADDR((struct sockaddr_dl *) + crc = ether_crc32_be(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), ETHER_ADDR_LEN); mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); } diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c index f2a3725d90d..01d68b2f064 100644 --- a/sys/dev/age/if_age.c +++ b/sys/dev/age/if_age.c @@ -3135,7 +3135,7 @@ age_rxfilter(struct age_softc *sc) TAILQ_FOREACH(ifma, &sc->age_ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; - crc = ether_crc32_le(LLADDR((struct sockaddr_dl *) + crc = ether_crc32_be(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), ETHER_ADDR_LEN); mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); } diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c index aeb46213811..a483f160fa0 100644 --- a/sys/dev/alc/if_alc.c +++ b/sys/dev/alc/if_alc.c @@ -3476,7 +3476,7 @@ alc_rxfilter(struct alc_softc *sc) TAILQ_FOREACH(ifma, &sc->alc_ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; - crc = ether_crc32_le(LLADDR((struct sockaddr_dl *) + crc = ether_crc32_be(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), ETHER_ADDR_LEN); mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); } diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c index 65e068fa5db..305eda4810a 100644 --- a/sys/dev/ale/if_ale.c +++ b/sys/dev/ale/if_ale.c @@ -3060,7 +3060,7 @@ ale_rxfilter(struct ale_softc *sc) TAILQ_FOREACH(ifma, &sc->ale_ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; - crc = ether_crc32_le(LLADDR((struct sockaddr_dl *) + crc = ether_crc32_be(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), ETHER_ADDR_LEN); mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); } From cb08d589ebf40363a213177179dda20ef067bdb7 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:46:15 +0000 Subject: [PATCH 0702/2592] MFC 198813. 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 2ff1d9921923fe0d57f1943eb24bf408fce12ca6 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:49:21 +0000 Subject: [PATCH 0703/2592] MFC 198814. 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 30c8843f6abe62e034e1703d7e2ad16caaa200cf Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:54:32 +0000 Subject: [PATCH 0704/2592] MFC 198996-198997. r198996: Remove unnecessary header file. r198997: 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 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 912eaeb498c..061d8c79d46 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 @@ -3218,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 75c4ab0ae9fb8914fdff77cc6fbb2181541ddbad Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 19:58:35 +0000 Subject: [PATCH 0705/2592] MFC r199012: 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 061d8c79d46..6afd4e04353 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. */ @@ -1646,7 +1651,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); @@ -1745,6 +1751,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 97333ffb74597078d55510f7fb6084357950903a Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 20:06:57 +0000 Subject: [PATCH 0706/2592] MFC r198475: - Add support for Marvell Yukon 88E8042 device. --- share/man/man4/msk.4 | 2 ++ 1 file changed, 2 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 From 44d2845719d17ba8c24257ceeefdacbf80f5fc1b Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 20:11:38 +0000 Subject: [PATCH 0707/2592] MFC r199013: 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 de75e77770cacc290dde49d55d74c71553cdd308 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 29 Nov 2009 20:19:24 +0000 Subject: [PATCH 0708/2592] MFC r199413: It seems generation of link state change of e1000phy(4) is not reliable on some Marvell PHYs. If msk(4) know it still does not have established link check whether msk(4) missed the link state change by looking into polled link state. Reported by: Mel Flynn < mel.flynn+fbsd.current <> mailing.thruhere dot net >, Gleb Kurtsou gmail dot com > Tested by: Gleb Kurtsou gmail dot com > --- sys/dev/msk/if_msk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 6afd4e04353..8fbd5b4a244 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -3200,6 +3200,8 @@ msk_tick(void *xsc_if) mii = device_get_softc(sc_if->msk_miibus); mii_tick(mii); + if ((sc_if->msk_flags & MSK_FLAG_LINK) == 0) + msk_miibus_statchg(sc_if->msk_if_dev); msk_watchdog(sc_if); callout_reset(&sc_if->msk_tick_ch, hz, msk_tick, sc_if); } From 17d1b37db52fc5dcb5446aeb07bbaed3e43d28fc Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Mon, 30 Nov 2009 07:51:37 +0000 Subject: [PATCH 0709/2592] MFC: r199748 Grammar and mdoc improvements. --- share/man/man4/ada.4 | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/share/man/man4/ada.4 b/share/man/man4/ada.4 index 8d2cf0e277f..65cd53fc699 100644 --- a/share/man/man4/ada.4 +++ b/share/man/man4/ada.4 @@ -36,12 +36,12 @@ .Sh DESCRIPTION The .Nm -driver provides support for direct access devices, implementing +driver provides support for direct access devices, implementing the .Tn ATA command protocol, that are attached to the system through a host adapter -supported by CAM subsystem. +supported by the CAM subsystem. .Pp -Host adapter must also be separately configured into the system before a +The host adapter must also be separately configured into the system before an .Tn ATA direct access device can be configured. .Sh COMMAND QUEUING @@ -52,12 +52,12 @@ seeks. defines two types of queueing: .Tn TCQ (Tagged Command Queueing, PATA legacy) and -.Tn NCQ (Native Command Queueing, SATA). +.Tn NCQ (Native Command Queueing, SATA) . The .Nm -device driver takes full advantage of the NCQ, when supported. -To ensure that transactions to distant portions of the media, -which may be deferred indefinitely by servicing requests nearer the current +device driver takes full advantage of NCQ, when supported. +To ensure that transactions to distant parts of the media, +which may be deferred indefinitely by servicing requests closer to the current head position, are completed in a timely fashion, an ordered transaction is sent every 7 seconds during continuous device operation. .Sh CACHE EFFECTS @@ -84,8 +84,8 @@ writes will be lost. The effect of a loss of write transactions on a file system is non-deterministic and can cause corruption. Most -devices age write transactions to limit vulnerability to a few transactions -recently reported as complete, but it is none-the-less recommended that +devices age write transactions to limit the vulnerability to a few transactions +recently reported as complete, but it is nonetheless recommended that systems with write cache enabled devices reside on an Uninterruptible Power Supply (UPS). The @@ -125,14 +125,14 @@ seconds. ATA device nodes .El .Sh SEE ALSO +.Xr ad 4 , .Xr ahci 4 , -.Xr siis 4 , -.Xr ad 4 -.Xr da 4 +.Xr da 4 , +.Xr siis 4 .Sh HISTORY The .Nm driver first appeared in .Fx 8.0 . .Sh AUTHORS -.An Alexander Motin Aq mav@FreeBSD.org . +.An Alexander Motin Aq mav@FreeBSD.org From 90ecb96535e8766e6802fc612ad8e9e6ece9d0e0 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Mon, 30 Nov 2009 07:54:22 +0000 Subject: [PATCH 0710/2592] MFC: r199739, r199825 - LSI MegaRAID 9260 works, sort the hardware list while here. - Add IBM ServeRAID-MR10i to the hardware list. --- share/man/man4/mfi.4 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/share/man/man4/mfi.4 b/share/man/man4/mfi.4 index 8ab8d938100..a2c09ea3efb 100644 --- a/share/man/man4/mfi.4 +++ b/share/man/man4/mfi.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 15, 2009 +.Dd November 26, 2009 .Dt MFI 4 .Os .Sh NAME @@ -79,15 +79,19 @@ driver supports the following hardware: .Pp .Bl -bullet -compact .It +LSI MegaRAID SAS 1078 +.It LSI MegaRAID SAS 8408E .It LSI MegaRAID SAS 8480E .It -LSI MegaRAID SAS 1078 +LSI MegaRAID SAS 9260 .It Dell PERC5 .It Dell PERC6 +.It +IBM ServeRAID-MR10i .El .Sh FILES .Bl -tag -width ".Pa /dev/mfid?" -compact From 0b1a7fea85d7314db290da6365592c33ff3c005d Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Tue, 1 Dec 2009 02:59:22 +0000 Subject: [PATCH 0711/2592] MFC r199979: Fix local root vulnerability. --- libexec/rtld-elf/rtld.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 6073c5089e2..bb0485e07cb 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -366,12 +366,12 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) * future processes to honor the potentially un-safe variables. */ if (!trust) { - unsetenv(LD_ "PRELOAD"); - unsetenv(LD_ "LIBMAP"); - unsetenv(LD_ "LIBRARY_PATH"); - unsetenv(LD_ "LIBMAP_DISABLE"); - unsetenv(LD_ "DEBUG"); - unsetenv(LD_ "ELF_HINTS_PATH"); + if (unsetenv(LD_ "PRELOAD") || unsetenv(LD_ "LIBMAP") || + unsetenv(LD_ "LIBRARY_PATH") || unsetenv(LD_ "LIBMAP_DISABLE") || + unsetenv(LD_ "DEBUG") || unsetenv(LD_ "ELF_HINTS_PATH")) { + _rtld_error("environment corrupt; aborting"); + die(); + } } ld_debug = getenv(LD_ "DEBUG"); libmap_disable = getenv(LD_ "LIBMAP_DISABLE") != NULL; From e9aa44c8001dbbbe1d9181274f7bd3ab48af7237 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 1 Dec 2009 06:11:42 +0000 Subject: [PATCH 0712/2592] MFC r199016: acpi: remove 'magic' ivar Note that the ivar itself is kept in the stable branches, only its use is dropped. --- sys/dev/acpica/acpi_cpu.c | 4 ++-- sys/dev/acpica/acpi_ec.c | 14 ++++++-------- sys/dev/acpica/acpi_hpet.c | 6 +----- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index 5d8ad535998..3c4fd71e84c 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); From f48f29ede91efee7011f7ed9a26fdd31d1313ed8 Mon Sep 17 00:00:00 2001 From: Alexander Leidinger Date: Tue, 1 Dec 2009 12:35:51 +0000 Subject: [PATCH 0713/2592] MFC r199626: Fix minor resource leak in a function. Reviewed by: luigi --- sbin/ipfw/dummynet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c index 147328460eb..41ad48e7246 100644 --- a/sbin/ipfw/dummynet.c +++ b/sbin/ipfw/dummynet.c @@ -650,6 +650,8 @@ load_extra_delays(const char *filename, struct dn_pipe *p) } } + fclose (f); + if (samples == -1) { warnx("'%s' not found, assuming 100", ED_TOK_SAMPLES); samples = 100; From fa860bed4ec69b874dd33617b5561b37f11be4a1 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 1 Dec 2009 22:38:17 +0000 Subject: [PATCH 0714/2592] MFC 199579: Always use 64-bit LBAs for disk addresses in zfsboot and gptzfsboot to fully support booting from large volumes. --- sys/boot/i386/zfsboot/zfsboot.c | 11 ++++++----- sys/boot/i386/zfsboot/zfsldr.S | 17 ++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c index c0dedd7cc86..690d8035bac 100644 --- a/sys/boot/i386/zfsboot/zfsboot.c +++ b/sys/boot/i386/zfsboot/zfsboot.c @@ -138,8 +138,8 @@ struct dsk { unsigned unit; unsigned slice; unsigned part; - unsigned start; int init; + daddr_t start; }; static char cmd[512]; static char kname[1024]; @@ -163,7 +163,7 @@ static int parse(void); static void printf(const char *,...); static void putchar(int); static uint32_t memsize(void); -static int drvread(struct dsk *, void *, unsigned, unsigned); +static int drvread(struct dsk *, void *, daddr_t, unsigned); static int keyhit(unsigned); static int xputc(int); static int xgetc(int); @@ -310,7 +310,8 @@ static int vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes) { char *p; - unsigned int lba, nb; + daddr_t lba; + unsigned int nb; struct dsk *dsk = (struct dsk *) priv; if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1))) @@ -964,7 +965,7 @@ static struct { #endif static int -drvread(struct dsk *dsk, void *buf, unsigned lba, unsigned nblk) +drvread(struct dsk *dsk, void *buf, daddr_t lba, unsigned nblk) { #ifdef GPT static unsigned c = 0x2d5c7c2f; @@ -999,7 +1000,7 @@ drvread(struct dsk *dsk, void *buf, unsigned lba, unsigned nblk) v86.es = VTOPSEG(buf); v86.eax = lba; v86.ebx = VTOPOFF(buf); - v86.ecx = lba >> 16; + v86.ecx = lba >> 32; v86.edx = nblk << 8 | dsk->drive; v86int(); v86.ctl = V86_FLAGS; diff --git a/sys/boot/i386/zfsboot/zfsldr.S b/sys/boot/i386/zfsboot/zfsldr.S index a256d30276d..64e384349e6 100644 --- a/sys/boot/i386/zfsboot/zfsldr.S +++ b/sys/boot/i386/zfsboot/zfsldr.S @@ -83,7 +83,7 @@ ebpb: .byte 0 # BIOS physical drive number (W) * Trampoline used by boot2 to call read to read data from the disk via * the BIOS. Call with: * - * %cx:%ax - long - LBA to read in + * %ecx:%eax - long - LBA to read in * %es:(%bx) - caddr_t - buffer to read data into * %dl - byte - drive to read from * %dh - byte - num sectors to read @@ -94,10 +94,8 @@ xread: push %ss # Address /* * Setup an EDD disk packet and pass it to read */ -xread.1: # Starting - pushl $0x0 # absolute - push %cx # block - push %ax # number +xread.1: pushl %ecx # Starting absolute block + pushl %eax # block number push %es # Address of push %bx # transfer buffer xor %ax,%ax # Number of @@ -195,7 +193,7 @@ main.4: xor %dx,%dx # Partition:drive */ main.5: mov %dx,MEM_ARG # Save args movb $NSECT,%dh # Sector count - movw $1024,%ax # Offset to boot2 + movl $1024,%eax # Offset to boot2 callw nread.1 # Read disk main.6: mov $MEM_BUF,%si # BTX (before reloc) mov 0xa(%si),%bx # Get BTX length and set @@ -245,10 +243,11 @@ seta20.3: sti # Enable interrupts /* * Trampoline used to call read from within boot1. */ -nread: xor %ax,%ax # Sector offset in partition +nread: xor %eax,%eax # Sector offset in partition nread.1: mov $MEM_BUF,%bx # Transfer buffer - add 0x8(%si),%ax # Get - mov 0xa(%si),%cx # LBA + xor %ecx,%ecx # Get + addl 0x8(%si),%eax # LBA + adc $0,%ecx push %cs # Read from callw xread.1 # disk jnc return # If success, return From 7619fb0cbd6891dd3e54abaf0c90b532294064e0 Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Tue, 1 Dec 2009 22:59:37 +0000 Subject: [PATCH 0715/2592] MFC 198343: Handle the case where there is only one PMC in the system. --- 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 482db0edfcf..ee37cc60ac3 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 baa1e3c69afca0f9611398bf2e0a903877060056 Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Tue, 1 Dec 2009 23:06:17 +0000 Subject: [PATCH 0716/2592] MFC 199763: - fix a LOR between process lock and pmc thread mutex - fix a system deadlock on process exit when the sample buffer is full (pmclog_loop blocked in fo_write) and pmcstat exit. --- sys/dev/hwpmc/hwpmc_logging.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c index cfb055b37ab..a36a8dc7e72 100644 --- a/sys/dev/hwpmc/hwpmc_logging.c +++ b/sys/dev/hwpmc/hwpmc_logging.c @@ -240,6 +240,7 @@ pmclog_loop(void *arg) int error; struct pmc_owner *po; struct pmclog_buffer *lb; + struct proc *p; struct ucred *ownercred; struct ucred *mycred; struct thread *td; @@ -248,12 +249,13 @@ pmclog_loop(void *arg) size_t nbytes; po = (struct pmc_owner *) arg; + p = po->po_owner; td = curthread; mycred = td->td_ucred; - PROC_LOCK(po->po_owner); - ownercred = crhold(po->po_owner->p_ucred); - PROC_UNLOCK(po->po_owner); + PROC_LOCK(p); + ownercred = crhold(p->p_ucred); + PROC_UNLOCK(p); PMCDBG(LOG,INI,1, "po=%p kt=%p", po, po->po_kthread); KASSERT(po->po_kthread == curthread->td_proc, @@ -324,16 +326,16 @@ pmclog_loop(void *arg) error = fo_write(po->po_file, &auio, ownercred, 0, td); td->td_ucred = mycred; - mtx_lock(&pmc_kthread_mtx); - if (error) { /* XXX some errors are recoverable */ /* XXX also check for SIGPIPE if a socket */ /* send a SIGIO to the owner and exit */ - PROC_LOCK(po->po_owner); - psignal(po->po_owner, SIGIO); - PROC_UNLOCK(po->po_owner); + PROC_LOCK(p); + psignal(p, SIGIO); + PROC_UNLOCK(p); + + mtx_lock(&pmc_kthread_mtx); po->po_error = error; /* save for flush log */ @@ -342,6 +344,8 @@ pmclog_loop(void *arg) break; } + mtx_lock(&pmc_kthread_mtx); + /* put the used buffer back into the global pool */ PMCLOG_INIT_BUFFER_DESCRIPTOR(lb); @@ -525,15 +529,20 @@ static void pmclog_stop_kthread(struct pmc_owner *po) { /* - * Unset flag, wakeup the helper thread, + * Close the file to force the thread out of fo_write, + * unset flag, wakeup the helper thread, * wait for it to exit */ - mtx_assert(&pmc_kthread_mtx, MA_OWNED); + if (po->po_file != NULL) + fo_close(po->po_file, curthread); + + mtx_lock(&pmc_kthread_mtx); po->po_flags &= ~PMC_PO_OWNS_LOGFILE; wakeup_one(po); if (po->po_kthread) msleep(po->po_kthread, &pmc_kthread_mtx, PPAUSE, "pmckstp", 0); + mtx_unlock(&pmc_kthread_mtx); } /* @@ -602,10 +611,8 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) error: /* shutdown the thread */ - mtx_lock(&pmc_kthread_mtx); if (po->po_kthread) pmclog_stop_kthread(po); - mtx_unlock(&pmc_kthread_mtx); KASSERT(po->po_kthread == NULL, ("[pmclog,%d] po=%p kthread not " "stopped", __LINE__, po)); @@ -641,10 +648,8 @@ pmclog_deconfigure_log(struct pmc_owner *po) ("[pmclog,%d] po=%p no log file", __LINE__, po)); /* stop the kthread, this will reset the 'OWNS_LOGFILE' flag */ - mtx_lock(&pmc_kthread_mtx); if (po->po_kthread) pmclog_stop_kthread(po); - mtx_unlock(&pmc_kthread_mtx); KASSERT(po->po_kthread == NULL, ("[pmclog,%d] po=%p kthread not stopped", __LINE__, po)); From 9e5aec39784a6e0123b653f0852d8076adf7a0fa Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Tue, 1 Dec 2009 23:23:52 +0000 Subject: [PATCH 0717/2592] MFC 198339: Fix the NO_PROXY handling. PR: 139751 --- 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 28f2223875ad9a9be95a15ba343ff89d5743ef0a Mon Sep 17 00:00:00 2001 From: Garrett Wollman Date: Wed, 2 Dec 2009 02:47:29 +0000 Subject: [PATCH 0718/2592] MFC revs 199781,199782,199784,199785,199786: Eliminate dead stores. In __mbsconv(), if prec was zero, nconv could have been used uninitialized. Initialize it to a safe value so that there's no chance of returning an error if stack garbage happens to be equal to (size_t)-1 or (size_t)-2. In svc_raw_reply(), don't leave stat uninitialized if the MSG_ACCEPTED && SUCCESS case succeeds. The stack garbage might be zero. In clnt_raw_create(), avoid minor race condition initializing the file-scope variable clntraw_private. Found by: Clang static analyzer --- lib/libc/gen/getcap.c | 5 ++--- lib/libc/gen/getusershell.c | 2 +- lib/libc/gen/wordexp.c | 2 +- lib/libc/rpc/clnt_raw.c | 11 +++++++---- lib/libc/rpc/getnetconfig.c | 4 ++-- lib/libc/rpc/key_call.c | 2 +- lib/libc/rpc/svc_raw.c | 5 ++--- lib/libc/stdio/fgetws.c | 2 +- lib/libc/stdio/fvwrite.c | 2 +- lib/libc/stdio/vfwprintf.c | 2 +- lib/libc/yp/yplib.c | 2 +- 11 files changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/libc/gen/getcap.c b/lib/libc/gen/getcap.c index 32d66d484f5..2700d3d1031 100644 --- a/lib/libc/gen/getcap.c +++ b/lib/libc/gen/getcap.c @@ -647,7 +647,7 @@ int cgetnext(char **bp, char **db_array) { size_t len; - int done, hadreaderr, i, savederrno, status; + int done, hadreaderr, savederrno, status; char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; u_int dummy; @@ -658,7 +658,7 @@ cgetnext(char **bp, char **db_array) (void)cgetclose(); return (-1); } - for(;;) { + for (;;) { if (toprec && !gottoprec) { gottoprec = 1; line = toprec; @@ -709,7 +709,6 @@ cgetnext(char **bp, char **db_array) /* * Line points to a name line. */ - i = 0; done = 0; np = nbuf; for (;;) { diff --git a/lib/libc/gen/getusershell.c b/lib/libc/gen/getusershell.c index b0da2a1d5cd..d09b50ca6b2 100644 --- a/lib/libc/gen/getusershell.c +++ b/lib/libc/gen/getusershell.c @@ -124,7 +124,7 @@ _local_initshells(rv, cb_data, ap) if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) return NS_UNAVAIL; - sp = cp = line; + cp = line; while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) { while (*cp != '#' && *cp != '/' && *cp != '\0') cp++; diff --git a/lib/libc/gen/wordexp.c b/lib/libc/gen/wordexp.c index a437543bca4..11fb6973dd7 100644 --- a/lib/libc/gen/wordexp.c +++ b/lib/libc/gen/wordexp.c @@ -282,7 +282,7 @@ we_check(const char *words, int flags) if (c == '\0' || level != 0) return (WRDE_SYNTAX); } else - c = *--words; + --words; break; default: break; diff --git a/lib/libc/rpc/clnt_raw.c b/lib/libc/rpc/clnt_raw.c index 9d34a3d445c..cd3a384ea3c 100644 --- a/lib/libc/rpc/clnt_raw.c +++ b/lib/libc/rpc/clnt_raw.c @@ -92,13 +92,13 @@ clnt_raw_create(prog, vers) rpcprog_t prog; rpcvers_t vers; { - struct clntraw_private *clp = clntraw_private; + struct clntraw_private *clp; struct rpc_msg call_msg; - XDR *xdrs = &clp->xdr_stream; - CLIENT *client = &clp->client_object; + XDR *xdrs; + CLIENT *client; mutex_lock(&clntraw_lock); - if (clp == NULL) { + if ((clp = clntraw_private) == NULL) { clp = (struct clntraw_private *)calloc(1, sizeof (*clp)); if (clp == NULL) { mutex_unlock(&clntraw_lock); @@ -110,6 +110,9 @@ clnt_raw_create(prog, vers) clp->_raw_buf = __rpc_rawcombuf; clntraw_private = clp; } + xdrs = &clp->xdr_stream; + client = &clp->client_object; + /* * pre-serialize the static part of the call msg and stash it away */ diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c index 9baa22495c5..e5db51ac3a3 100644 --- a/lib/libc/rpc/getnetconfig.c +++ b/lib/libc/rpc/getnetconfig.c @@ -412,13 +412,13 @@ void *handlep; * Noone needs these entries anymore, then frees them. * Make sure all info in netconfig_info structure has been reinitialized. */ - q = p = ni.head; + q = ni.head; ni.eof = ni.ref = 0; ni.head = NULL; ni.tail = NULL; mutex_unlock(&ni_lock); - while (q) { + while (q != NULL) { p = q->next; if (q->ncp->nc_lookups != NULL) free(q->ncp->nc_lookups); free(q->ncp); diff --git a/lib/libc/rpc/key_call.c b/lib/libc/rpc/key_call.c index 615f24d9e86..6cc1139ab52 100644 --- a/lib/libc/rpc/key_call.c +++ b/lib/libc/rpc/key_call.c @@ -302,7 +302,7 @@ int vers; void *localhandle; struct netconfig *nconf; struct netconfig *tpconf; - struct key_call_private *kcp = key_call_private_main; + struct key_call_private *kcp; struct timeval wait_time; struct utsname u; int main_thread; diff --git a/lib/libc/rpc/svc_raw.c b/lib/libc/rpc/svc_raw.c index 7492046a888..67bcba1c868 100644 --- a/lib/libc/rpc/svc_raw.c +++ b/lib/libc/rpc/svc_raw.c @@ -176,9 +176,8 @@ svc_raw_reply(xprt, msg) msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; msg->acpted_rply.ar_results.where = NULL; - if (!xdr_replymsg(xdrs, msg) || - !SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where)) - stat = FALSE; + stat = xdr_replymsg(xdrs, msg) && + SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where); } else { stat = xdr_replymsg(xdrs, msg); } diff --git a/lib/libc/stdio/fgetws.c b/lib/libc/stdio/fgetws.c index bbc0299d773..550843dff67 100644 --- a/lib/libc/stdio/fgetws.c +++ b/lib/libc/stdio/fgetws.c @@ -89,7 +89,7 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) if (!__mbsinit(&fp->_mbstate)) /* Incomplete character */ goto error; - *wsp++ = L'\0'; + *wsp = L'\0'; FUNLOCKFILE(fp); return (ws); diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c index fd69eb95420..7206676869e 100644 --- a/lib/libc/stdio/fvwrite.c +++ b/lib/libc/stdio/fvwrite.c @@ -60,7 +60,7 @@ __sfvwrite(fp, uio) char *nl; int nlknown, nldist; - if ((len = uio->uio_resid) == 0) + if (uio->uio_resid == 0) return (0); /* make sure we can write */ if (prepwrite(fp) != 0) diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c index f3768de8d19..d34f559a8f3 100644 --- a/lib/libc/stdio/vfwprintf.c +++ b/lib/libc/stdio/vfwprintf.c @@ -293,7 +293,7 @@ __mbsconv(char *mbsarg, int prec) * number of characters to print. */ p = mbsarg; - insize = nchars = 0; + insize = nchars = nconv = 0; mbs = initial_mbs; while (nchars != (size_t)prec) { nconv = mbrlen(p, MB_CUR_MAX, &mbs); diff --git a/lib/libc/yp/yplib.c b/lib/libc/yp/yplib.c index eb5c34c1670..87d16ddece1 100644 --- a/lib/libc/yp/yplib.c +++ b/lib/libc/yp/yplib.c @@ -241,7 +241,7 @@ static bool_t ypmatch_cache_lookup(struct dom_binding *ypdb, char *map, keydat *key, valdat *val) { - struct ypmatch_ent *c = ypdb->cache; + struct ypmatch_ent *c; ypmatch_cache_expire(ypdb); From 7e7ac267c9d95820990dbf395438521bbed8ba2a Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 2 Dec 2009 10:10:37 +0000 Subject: [PATCH 0719/2592] MFC r199279, r199280, r199281: - Fix several device freeze counting bugs. - Remove code that years ago was closing race between request submission to SIM and device/SIM freeze. That race become impossible after moving from spl to mutex locking, while this workaround causes some unexpected effects. --- sys/cam/cam_periph.c | 64 +++++++++++++++++++++++++++--------------- sys/cam/cam_queue.c | 1 - sys/cam/cam_queue.h | 7 +---- sys/cam/cam_xpt.c | 40 ++------------------------ sys/cam/scsi/scsi_cd.c | 6 ++-- sys/cam/scsi/scsi_ch.c | 3 +- 6 files changed, 51 insertions(+), 70 deletions(-) diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 70764c65c14..9bac0f5a82e 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -981,16 +981,21 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) { union ccb *saved_ccb; cam_status status; - int frozen; + int frozen = 0; int sense; struct scsi_start_stop_unit *scsi_cmd; u_int32_t relsim_flags, timeout; - u_int32_t qfrozen_cnt; - int xpt_done_ccb; + int xpt_done_ccb = FALSE; - xpt_done_ccb = FALSE; status = done_ccb->ccb_h.status; - frozen = (status & CAM_DEV_QFRZN) != 0; + if (status & CAM_DEV_QFRZN) { + frozen = 1; + /* + * Clear freeze flag now for case of retry, + * freeze will be dropped later. + */ + done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN; + } sense = (status & CAM_AUTOSNS_VALID) != 0; status &= CAM_STATUS_MASK; @@ -998,17 +1003,6 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) relsim_flags = 0; saved_ccb = (union ccb *)done_ccb->ccb_h.saved_ccb_ptr; - /* - * Unfreeze the queue once if it is already frozen.. - */ - if (frozen != 0) { - qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path, - /*relsim_flags*/0, - /*openings*/0, - /*timeout*/0, - /*getcount_only*/0); - } - switch (status) { case CAM_REQ_CMP: { @@ -1185,14 +1179,33 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) */ if (done_ccb->ccb_h.retry_count > 0) done_ccb->ccb_h.retry_count--; - - qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path, - /*relsim_flags*/relsim_flags, - /*openings*/0, - /*timeout*/timeout, - /*getcount_only*/0); - if (xpt_done_ccb == TRUE) + /* + * Drop freeze taken due to CAM_DEV_QFREEZE flag set on recovery + * request. + */ + cam_release_devq(done_ccb->ccb_h.path, + /*relsim_flags*/relsim_flags, + /*openings*/0, + /*timeout*/timeout, + /*getcount_only*/0); + if (xpt_done_ccb == TRUE) { + /* + * Copy frozen flag from recovery request if it is set there + * for some reason. + */ + if (frozen != 0) + done_ccb->ccb_h.status |= CAM_DEV_QFRZN; (*done_ccb->ccb_h.cbfcnp)(periph, done_ccb); + } else { + /* Drop freeze taken, if this recovery request got error. */ + if (frozen != 0) { + cam_release_devq(done_ccb->ccb_h.path, + /*relsim_flags*/0, + /*openings*/0, + /*timeout*/0, + /*getcount_only*/0); + } + } } /* @@ -1452,6 +1465,11 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, action_string = "No recovery CCB supplied"; goto sense_error_done; } + /* + * Clear freeze flag for original request here, as + * this freeze will be dropped as part of ERESTART. + */ + ccb->ccb_h.status &= ~CAM_DEV_QFRZN; bcopy(ccb, save_ccb, sizeof(*save_ccb)); print_ccb = save_ccb; periph->flags |= CAM_PERIPH_RECOVERY_INPROG; diff --git a/sys/cam/cam_queue.c b/sys/cam/cam_queue.c index 56586be3cf7..328f0b802a7 100644 --- a/sys/cam/cam_queue.c +++ b/sys/cam/cam_queue.c @@ -334,7 +334,6 @@ cam_ccbq_init(struct cam_ccbq *ccbq, int openings) } ccbq->devq_openings = openings; ccbq->dev_openings = openings; - TAILQ_INIT(&ccbq->active_ccbs); return (0); } diff --git a/sys/cam/cam_queue.h b/sys/cam/cam_queue.h index d2990ad26e9..31f9bc238bf 100644 --- a/sys/cam/cam_queue.h +++ b/sys/cam/cam_queue.h @@ -60,7 +60,6 @@ struct cam_ccbq { int dev_openings; int dev_active; int held; - struct ccb_hdr_tailq active_ccbs; }; struct cam_ed; @@ -209,9 +208,6 @@ static __inline void cam_ccbq_send_ccb(struct cam_ccbq *ccbq, union ccb *send_ccb) { - TAILQ_INSERT_TAIL(&ccbq->active_ccbs, - &(send_ccb->ccb_h), - xpt_links.tqe); send_ccb->ccb_h.pinfo.index = CAM_ACTIVE_INDEX; ccbq->dev_active++; ccbq->dev_openings--; @@ -220,8 +216,7 @@ cam_ccbq_send_ccb(struct cam_ccbq *ccbq, union ccb *send_ccb) static __inline void cam_ccbq_ccb_done(struct cam_ccbq *ccbq, union ccb *done_ccb) { - TAILQ_REMOVE(&ccbq->active_ccbs, &done_ccb->ccb_h, - xpt_links.tqe); + ccbq->dev_active--; ccbq->dev_openings++; ccbq->held++; diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index e9133f6a5eb..02d8d20f7dd 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -3273,16 +3273,13 @@ xpt_run_dev_sendq(struct cam_eb *bus) devq->send_queue.qfrozen_cnt++; while ((devq->send_queue.entries > 0) - && (devq->send_openings > 0)) { + && (devq->send_openings > 0) + && (devq->send_queue.qfrozen_cnt <= 1)) { struct cam_ed_qinfo *qinfo; struct cam_ed *device; union ccb *work_ccb; struct cam_sim *sim; - if (devq->send_queue.qfrozen_cnt > 1) { - break; - } - qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->send_queue, CAMQ_HEAD); device = qinfo->device; @@ -3330,9 +3327,7 @@ xpt_run_dev_sendq(struct cam_eb *bus) } mtx_unlock(&xsoftc.xpt_lock); } - devq->active_dev = device; cam_ccbq_remove_ccb(&device->ccbq, work_ccb); - cam_ccbq_send_ccb(&device->ccbq, work_ccb); devq->send_openings--; @@ -3370,8 +3365,6 @@ xpt_run_dev_sendq(struct cam_eb *bus) */ sim = work_ccb->ccb_h.path->bus->sim; (*(sim->sim_action))(sim, work_ccb); - - devq->active_dev = NULL; } devq->send_queue.qfrozen_cnt--; } @@ -4102,45 +4095,18 @@ xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus, u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count) { - struct ccb_hdr *ccbh; mtx_assert(path->bus->sim->mtx, MA_OWNED); - path->device->ccbq.queue.qfrozen_cnt += count; - - /* - * Mark the last CCB in the queue as needing - * to be requeued if the driver hasn't - * changed it's state yet. This fixes a race - * where a ccb is just about to be queued to - * a controller driver when it's interrupt routine - * freezes the queue. To completly close the - * hole, controller drives must check to see - * if a ccb's status is still CAM_REQ_INPROG - * just before they queue - * the CCB. See ahc_action/ahc_freeze_devq for - * an example. - */ - ccbh = TAILQ_LAST(&path->device->ccbq.active_ccbs, ccb_hdr_tailq); - if (ccbh && ccbh->status == CAM_REQ_INPROG) - ccbh->status = CAM_REQUEUE_REQ; return (path->device->ccbq.queue.qfrozen_cnt); } u_int32_t xpt_freeze_simq(struct cam_sim *sim, u_int count) { + mtx_assert(sim->mtx, MA_OWNED); - sim->devq->send_queue.qfrozen_cnt += count; - if (sim->devq->active_dev != NULL) { - struct ccb_hdr *ccbh; - - ccbh = TAILQ_LAST(&sim->devq->active_dev->ccbq.active_ccbs, - ccb_hdr_tailq); - if (ccbh && ccbh->status == CAM_REQ_INPROG) - ccbh->status = CAM_REQUEUE_REQ; - } return (sim->devq->send_queue.qfrozen_cnt); } diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index f2a612b7734..7bd6158f869 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -1570,7 +1570,8 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) bp->bio_resid = bp->bio_bcount; bp->bio_error = error; bp->bio_flags |= BIO_ERROR; - cam_release_devq(done_ccb->ccb_h.path, + 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, @@ -1658,7 +1659,8 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) struct ccb_getdev cgd; /* Don't wedge this device's queue */ - cam_release_devq(done_ccb->ccb_h.path, + 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, diff --git a/sys/cam/scsi/scsi_ch.c b/sys/cam/scsi/scsi_ch.c index 781245a8df8..2829a155d9a 100644 --- a/sys/cam/scsi/scsi_ch.c +++ b/sys/cam/scsi/scsi_ch.c @@ -606,7 +606,8 @@ chdone(struct cam_periph *periph, union ccb *done_ccb) retry_scheduled = 0; /* Don't wedge this device's queue */ - cam_release_devq(done_ccb->ccb_h.path, + 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, From 03b5c37446e98d28424d501baf5fdca99e4d3f62 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 2 Dec 2009 10:32:34 +0000 Subject: [PATCH 0720/2592] MFC r199747, r199799, r199821: - Extend XPT-SIM transfer settings control API. Now it allows to report to SATA SIM number of tags supported by each device, implement ATA mode and SATA revision negotiation for both SATA and PATA SIMs. - Make ahci(4) and siis(4) to use submitted maximum tag number, when scheduling requests. It allows to support NCQ on devices with lower tags count then controller supports. - Make PMP driver to report attached devices connection speeds. - Implement ATA mode negotiation between user settings, device and controller capabilities. - Improve ATA mode/SATA revision control. --- sbin/camcontrol/camcontrol.8 | 3 + sbin/camcontrol/camcontrol.c | 203 ++++++++++++++++++++++++----------- sys/cam/ata/ata_all.c | 141 ++++++++++++++++++++++-- sys/cam/ata/ata_all.h | 8 +- sys/cam/ata/ata_pmp.c | 14 +++ sys/cam/ata/ata_xpt.c | 73 +++++++++++-- sys/cam/cam_ccb.h | 18 ++-- sys/cam/cam_xpt.c | 25 ++++- sys/dev/ahci/ahci.c | 112 ++++++++++++------- sys/dev/ahci/ahci.h | 12 ++- sys/dev/siis/siis.c | 103 ++++++++++++------ sys/dev/siis/siis.h | 13 ++- 12 files changed, 558 insertions(+), 167 deletions(-) diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8 index a0871ac7f3f..0509ef7372c 100644 --- a/sbin/camcontrol/camcontrol.8 +++ b/sbin/camcontrol/camcontrol.8 @@ -149,6 +149,7 @@ .Op generic args .Op Fl c .Op Fl D Ar enable|disable +.Op Fl M Ar mode .Op Fl O Ar offset .Op Fl q .Op Fl R Ar syncrate @@ -705,6 +706,8 @@ Show or set current negotiation settings. This is the default. .It Fl D Ar enable|disable Enable or disable disconnection. +.It Fl M Ar mode +Set ATA mode. .It Fl O Ar offset Set the command delay offset. .It Fl q diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 7d88998a237..1e71ae0caae 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -125,7 +125,7 @@ struct camcontrol_opts { #ifndef MINIMALISTIC static const char scsicmd_opts[] = "a:c:i:o:r"; static const char readdefect_opts[] = "f:GP"; -static const char negotiate_opts[] = "acD:O:qR:T:UW:"; +static const char negotiate_opts[] = "acD:M:O:qR:T:UW:"; #endif struct camcontrol_opts option_table[] = { @@ -226,6 +226,12 @@ static int scsireadcapacity(struct cam_device *device, int argc, char **argv, static int atapm(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); #endif /* MINIMALISTIC */ +#ifndef min +#define min(a,b) (((a)<(b))?(a):(b)) +#endif +#ifndef max +#define max(a,b) (((a)>(b))?(a):(b)) +#endif camcontrol_optret getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum, @@ -950,21 +956,27 @@ camxferrate(struct cam_device *device) if (sas->valid & CTS_SAS_VALID_SPEED) speed = sas->bitrate; + } else if (ccb->cts.transport == XPORT_ATA) { + struct ccb_trans_settings_ata *ata = + &ccb->cts.xport_specific.ata; + + if (ata->valid & CTS_ATA_VALID_MODE) + speed = ata_mode2speed(ata->mode); } else if (ccb->cts.transport == XPORT_SATA) { - struct ccb_trans_settings_sata *sata = + struct ccb_trans_settings_sata *sata = &ccb->cts.xport_specific.sata; - if (sata->valid & CTS_SATA_VALID_SPEED) - speed = sata->bitrate; + if (sata->valid & CTS_SATA_VALID_REVISION) + speed = ata_revision2speed(sata->revision); } mb = speed / 1000; if (mb > 0) { - fprintf(stdout, "%s%d: %d.%03dMB/s transfers ", + 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 ", + fprintf(stdout, "%s%d: %dKB/s transfers", device->device_name, device->dev_unit_num, speed); } @@ -975,7 +987,7 @@ camxferrate(struct cam_device *device) if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) && (spi->sync_offset != 0)) - fprintf(stdout, "(%d.%03dMHz, offset %d", freq / 1000, + fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000, freq % 1000, spi->sync_offset); if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) @@ -995,18 +1007,24 @@ camxferrate(struct cam_device *device) struct ccb_trans_settings_ata *ata = &ccb->cts.xport_specific.ata; - if (ata->valid & CTS_ATA_VALID_BYTECOUNT) { - fprintf(stdout, "(PIO size %dbytes)", - ata->bytecount); - } + printf(" ("); + if (ata->valid & CTS_ATA_VALID_MODE) + printf("%s, ", ata_mode2string(ata->mode)); + if (ata->valid & CTS_ATA_VALID_BYTECOUNT) + printf("PIO size %dbytes", ata->bytecount); + printf(")"); } else if (ccb->cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = &ccb->cts.xport_specific.sata; - if (sata->valid & CTS_SATA_VALID_BYTECOUNT) { - fprintf(stdout, "(PIO size %dbytes)", - sata->bytecount); - } + printf(" ("); + if (sata->valid & CTS_SATA_VALID_REVISION) + printf("SATA %d.x, ", sata->revision); + if (sata->valid & CTS_SATA_VALID_MODE) + printf("%s, ", ata_mode2string(sata->mode)); + if (sata->valid & CTS_SATA_VALID_BYTECOUNT) + printf("PIO size %dbytes", sata->bytecount); + printf(")"); } if (ccb->cts.protocol == PROTO_SCSI) { @@ -2757,7 +2775,44 @@ cts_print(struct cam_device *device, struct ccb_trans_settings *cts) "enabled" : "disabled"); } } + if (cts->transport == XPORT_ATA) { + struct ccb_trans_settings_ata *ata = + &cts->xport_specific.ata; + if ((ata->valid & CTS_ATA_VALID_MODE) != 0) { + fprintf(stdout, "%sATA mode: %s\n", pathstr, + ata_mode2string(ata->mode)); + } + if ((ata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) { + fprintf(stdout, "%sPIO transaction length: %d\n", + pathstr, ata->bytecount); + } + } + if (cts->transport == XPORT_SATA) { + struct ccb_trans_settings_sata *sata = + &cts->xport_specific.sata; + + if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) { + fprintf(stdout, "%sSATA revision: %d.x\n", pathstr, + sata->revision); + } + if ((sata->valid & CTS_SATA_VALID_MODE) != 0) { + fprintf(stdout, "%sATA mode: %s\n", pathstr, + ata_mode2string(sata->mode)); + } + if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) { + fprintf(stdout, "%sPIO transaction length: %d\n", + pathstr, sata->bytecount); + } + if ((sata->valid & CTS_SATA_VALID_PM) != 0) { + fprintf(stdout, "%sPMP presence: %d\n", pathstr, + sata->pm_present); + } + if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) { + fprintf(stdout, "%sNumber of tags: %d\n", pathstr, + sata->tags); + } + } if (cts->protocol == PROTO_SCSI) { struct ccb_trans_settings_scsi *scsi= &cts->proto_specific.scsi; @@ -3057,6 +3112,7 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, int user_settings = 0; int retval = 0; int disc_enable = -1, tag_enable = -1; + int mode = -1; int offset = -1; double syncrate = -1; int bus_width = -1; @@ -3065,12 +3121,10 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, struct ccb_pathinq cpi; ccb = cam_getccb(device); - if (ccb == NULL) { warnx("ratecontrol: error allocating ccb"); return(1); } - while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c){ case 'a': @@ -3091,6 +3145,15 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, } change_settings = 1; break; + case 'M': + mode = ata_string2mode(optarg); + if (mode < 0) { + warnx("unknown mode '%s'", optarg); + retval = 1; + goto ratecontrol_bailout; + } + change_settings = 1; + break; case 'O': offset = strtol(optarg, NULL, 0); if (offset < 0) { @@ -3105,7 +3168,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, break; case 'R': syncrate = atof(optarg); - if (syncrate < 0) { warnx("sync rate %f is < 0", syncrate); retval = 1; @@ -3141,17 +3203,14 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, break; } } - bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr)); - /* * Grab path inquiry information, so we can determine whether * or not the initiator is capable of the things that the user * requests. */ ccb->ccb_h.func_code = XPT_PATH_INQ; - if (cam_send_ccb(device, ccb) < 0) { perror("error sending XPT_PATH_INQ CCB"); if (arglist & CAM_ARG_VERBOSE) { @@ -3161,7 +3220,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, retval = 1; goto ratecontrol_bailout; } - if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { warnx("XPT_PATH_INQ CCB failed"); if (arglist & CAM_ARG_VERBOSE) { @@ -3171,17 +3229,14 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, retval = 1; goto ratecontrol_bailout; } - bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq)); - bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr)); - - if (quiet == 0) - fprintf(stdout, "Current Parameters:\n"); - + if (quiet == 0) { + fprintf(stdout, "%s parameters:\n", + user_settings ? "User" : "Current"); + } retval = get_print_cts(device, user_settings, quiet, &ccb->cts); - if (retval != 0) goto ratecontrol_bailout; @@ -3191,16 +3246,20 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, if (change_settings) { int didsettings = 0; struct ccb_trans_settings_spi *spi = NULL; + struct ccb_trans_settings_ata *ata = NULL; + struct ccb_trans_settings_sata *sata = NULL; struct ccb_trans_settings_scsi *scsi = NULL; - if (ccb->cts.transport == XPORT_SPI) { + if (ccb->cts.transport == XPORT_SPI) spi = &ccb->cts.xport_specific.spi; - spi->valid = 0; - } - if (ccb->cts.protocol == PROTO_SCSI) { + if (ccb->cts.transport == XPORT_ATA) + ata = &ccb->cts.xport_specific.ata; + if (ccb->cts.transport == XPORT_SATA) + sata = &ccb->cts.xport_specific.sata; + if (ccb->cts.protocol == PROTO_SCSI) scsi = &ccb->cts.proto_specific.scsi; - scsi->valid = 0; - } + ccb->cts.xport_specific.valid = 0; + ccb->cts.proto_specific.valid = 0; if (spi && disc_enable != -1) { spi->valid |= CTS_SPI_VALID_DISC; if (disc_enable == 0) @@ -3208,7 +3267,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, else spi->flags |= CTS_SPI_FLAGS_DISC_ENB; } - if (scsi && tag_enable != -1) { if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) { warnx("HBA does not support tagged queueing, " @@ -3216,21 +3274,16 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, retval = 1; goto ratecontrol_bailout; } - scsi->valid |= CTS_SCSI_VALID_TQ; - if (tag_enable == 0) scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; else scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; didsettings++; } - if (spi && offset != -1) { if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { - warnx("HBA at %s%d is not cable of changing " - "offset", cpi.dev_name, - cpi.unit_number); + warnx("HBA is not capable of changing offset"); retval = 1; goto ratecontrol_bailout; } @@ -3238,28 +3291,23 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, spi->sync_offset = offset; didsettings++; } - if (spi && syncrate != -1) { int prelim_sync_period; u_int freq; if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { - warnx("HBA at %s%d is not cable of changing " - "transfer rates", cpi.dev_name, - cpi.unit_number); + warnx("HBA is not capable of changing " + "transfer rates"); retval = 1; goto ratecontrol_bailout; } - spi->valid |= CTS_SPI_VALID_SYNC_RATE; - /* * The sync rate the user gives us is in MHz. * We need to translate it into KHz for this * calculation. */ syncrate *= 1000; - /* * Next, we calculate a "preliminary" sync period * in tenths of a nanosecond. @@ -3268,14 +3316,43 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, prelim_sync_period = 0; else prelim_sync_period = 10000000 / syncrate; - spi->sync_period = scsi_calc_syncparam(prelim_sync_period); - freq = scsi_calc_syncsrate(spi->sync_period); didsettings++; } - + if (sata && syncrate != -1) { + if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { + warnx("HBA is not capable of changing " + "transfer rates"); + retval = 1; + goto ratecontrol_bailout; + } + sata->revision = ata_speed2revision(syncrate * 100); + if (sata->revision < 0) { + warnx("Invalid rate %f", syncrate); + retval = 1; + goto ratecontrol_bailout; + } + sata->valid |= CTS_SATA_VALID_REVISION; + didsettings++; + } + if ((ata || sata) && mode != -1) { + if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { + warnx("HBA is not capable of changing " + "transfer rates"); + retval = 1; + goto ratecontrol_bailout; + } + if (ata) { + ata->mode = mode; + ata->valid |= CTS_ATA_VALID_MODE; + } else { + sata->mode = mode; + sata->valid |= CTS_SATA_VALID_MODE; + } + didsettings++; + } /* * The bus_width argument goes like this: * 0 == 8 bit @@ -3286,7 +3363,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, * number. */ if (spi && bus_width != -1) { - /* * We might as well validate things here with a * decipherable error message, rather than what @@ -3310,17 +3386,19 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, retval = 1; goto ratecontrol_bailout; } - spi->valid |= CTS_SPI_VALID_BUS_WIDTH; spi->bus_width = bus_width >> 4; didsettings++; } - if (didsettings == 0) { goto ratecontrol_bailout; } + if (!user_settings && (ata || sata)) { + warnx("You can modify only user settings for ATA/SATA"); + retval = 1; + goto ratecontrol_bailout; + } ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; - if (cam_send_ccb(device, ccb) < 0) { perror("error sending XPT_SET_TRAN_SETTINGS CCB"); if (arglist & CAM_ARG_VERBOSE) { @@ -3330,7 +3408,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, retval = 1; goto ratecontrol_bailout; } - if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { warnx("XPT_SET_TRANS_SETTINGS CCB failed"); if (arglist & CAM_ARG_VERBOSE) { @@ -3341,11 +3418,9 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, goto ratecontrol_bailout; } } - if (send_tur) { retval = testunitready(device, retry_count, timeout, (arglist & CAM_ARG_VERBOSE) ? 0 : 1); - /* * If the TUR didn't succeed, just bail. */ @@ -3354,7 +3429,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, fprintf(stderr, "Test Unit Ready failed\n"); goto ratecontrol_bailout; } - /* * If the user wants things quiet, there's no sense in * getting the transfer settings, if we're not going @@ -3362,13 +3436,11 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout, */ if (quiet != 0) goto ratecontrol_bailout; - - fprintf(stdout, "New Parameters:\n"); + fprintf(stdout, "New parameters:\n"); retval = get_print_cts(device, user_settings, 0, NULL); } ratecontrol_bailout: - cam_freeccb(ccb); return(retval); } @@ -4255,8 +4327,8 @@ usage(int verbose) " \n" " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n" " camcontrol negotiate [dev_id][generic args] [-a][-c]\n" -" [-D ][-O offset][-q]\n" -" [-R syncrate][-v][-T ]\n" +" [-D ][-M mode][-O offset]\n" +" [-q][-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" @@ -4347,6 +4419,7 @@ usage(int verbose) "-a send a test unit ready after negotiation\n" "-c report/set current negotiation settings\n" "-D \"enable\" or \"disable\" disconnection\n" +"-M mode set ATA mode\n" "-O offset set command delay offset\n" "-q be quiet, don't report anything\n" "-R syncrate synchronization rate in MHz\n" diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index 5863ea84180..5c0c6d9670d 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -491,22 +491,143 @@ ata_max_umode(struct ata_params *ap) } int -ata_max_mode(struct ata_params *ap, int mode, int maxmode) +ata_max_mode(struct ata_params *ap, int maxmode) { - if (maxmode && mode > maxmode) - mode = maxmode; + if (maxmode == 0) + maxmode = ATA_DMA_MAX; + if (maxmode >= ATA_UDMA0 && ata_max_umode(ap) > 0) + return (min(maxmode, ata_max_umode(ap))); + if (maxmode >= ATA_WDMA0 && ata_max_wmode(ap) > 0) + return (min(maxmode, ata_max_wmode(ap))); + return (min(maxmode, ata_max_pmode(ap))); +} - if (mode >= ATA_UDMA0 && ata_max_umode(ap) > 0) - return (min(mode, ata_max_umode(ap))); +char * +ata_mode2string(int mode) +{ + switch (mode) { + case -1: return "UNSUPPORTED"; + case 0: return "NONE"; + case ATA_PIO0: return "PIO0"; + case ATA_PIO1: return "PIO1"; + case ATA_PIO2: return "PIO2"; + case ATA_PIO3: return "PIO3"; + case ATA_PIO4: return "PIO4"; + case ATA_WDMA0: return "WDMA0"; + case ATA_WDMA1: return "WDMA1"; + case ATA_WDMA2: return "WDMA2"; + case ATA_UDMA0: return "UDMA0"; + case ATA_UDMA1: return "UDMA1"; + case ATA_UDMA2: return "UDMA2"; + case ATA_UDMA3: return "UDMA3"; + case ATA_UDMA4: return "UDMA4"; + case ATA_UDMA5: return "UDMA5"; + case ATA_UDMA6: return "UDMA6"; + default: + if (mode & ATA_DMA_MASK) + return "BIOSDMA"; + else + return "BIOSPIO"; + } +} - if (mode >= ATA_WDMA0 && ata_max_wmode(ap) > 0) - return (min(mode, ata_max_wmode(ap))); +int +ata_string2mode(char *str) +{ + if (!strcasecmp(str, "PIO0")) return (ATA_PIO0); + if (!strcasecmp(str, "PIO1")) return (ATA_PIO1); + if (!strcasecmp(str, "PIO2")) return (ATA_PIO2); + if (!strcasecmp(str, "PIO3")) return (ATA_PIO3); + if (!strcasecmp(str, "PIO4")) return (ATA_PIO4); + if (!strcasecmp(str, "WDMA0")) return (ATA_WDMA0); + if (!strcasecmp(str, "WDMA1")) return (ATA_WDMA1); + if (!strcasecmp(str, "WDMA2")) return (ATA_WDMA2); + if (!strcasecmp(str, "UDMA0")) return (ATA_UDMA0); + if (!strcasecmp(str, "UDMA16")) return (ATA_UDMA0); + if (!strcasecmp(str, "UDMA1")) return (ATA_UDMA1); + if (!strcasecmp(str, "UDMA25")) return (ATA_UDMA1); + if (!strcasecmp(str, "UDMA2")) return (ATA_UDMA2); + if (!strcasecmp(str, "UDMA33")) return (ATA_UDMA2); + if (!strcasecmp(str, "UDMA3")) return (ATA_UDMA3); + if (!strcasecmp(str, "UDMA44")) return (ATA_UDMA3); + if (!strcasecmp(str, "UDMA4")) return (ATA_UDMA4); + if (!strcasecmp(str, "UDMA66")) return (ATA_UDMA4); + if (!strcasecmp(str, "UDMA5")) return (ATA_UDMA5); + if (!strcasecmp(str, "UDMA100")) return (ATA_UDMA5); + if (!strcasecmp(str, "UDMA6")) return (ATA_UDMA6); + if (!strcasecmp(str, "UDMA133")) return (ATA_UDMA6); + return (-1); +} - if (mode > ata_max_pmode(ap)) - return (min(mode, ata_max_pmode(ap))); - return (mode); +u_int +ata_mode2speed(int mode) +{ + switch (mode) { + case ATA_PIO0: + default: + return (3300); + case ATA_PIO1: + return (5200); + case ATA_PIO2: + return (8300); + case ATA_PIO3: + return (11100); + case ATA_PIO4: + return (16700); + case ATA_WDMA0: + return (4200); + case ATA_WDMA1: + return (13300); + case ATA_WDMA2: + return (16700); + case ATA_UDMA0: + return (16700); + case ATA_UDMA1: + return (25000); + case ATA_UDMA2: + return (33300); + case ATA_UDMA3: + return (44400); + case ATA_UDMA4: + return (66700); + case ATA_UDMA5: + return (100000); + case ATA_UDMA6: + return (133000); + } +} + +u_int +ata_revision2speed(int revision) +{ + switch (revision) { + case 1: + default: + return (150000); + case 2: + return (300000); + case 3: + return (600000); + } +} + +int +ata_speed2revision(u_int speed) +{ + switch (speed) { + case 0: + return (0); + case 150000: + return (1); + case 300000: + return (2); + case 600000: + return (3); + default: + return (-1); + } } int diff --git a/sys/cam/ata/ata_all.h b/sys/cam/ata/ata_all.h index 13de02de8b5..e64e1a1d24c 100644 --- a/sys/cam/ata/ata_all.h +++ b/sys/cam/ata/ata_all.h @@ -112,7 +112,13 @@ void ata_bpack(int8_t *src, int8_t *dst, int len); int ata_max_pmode(struct ata_params *ap); 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_max_mode(struct ata_params *ap, int maxmode); + +char * ata_mode2string(int mode); +int ata_string2mode(char *str); +u_int ata_mode2speed(int mode); +u_int ata_revision2speed(int revision); +int ata_speed2revision(u_int speed); int ata_identify_match(caddr_t identbuffer, caddr_t table_entry); int ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry); diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c index 1aa68397e6a..e34992b08a2 100644 --- a/sys/cam/ata/ata_pmp.c +++ b/sys/cam/ata/ata_pmp.c @@ -516,6 +516,7 @@ printf("PM RESET %d%s\n", softc->pm_step, static void pmpdone(struct cam_periph *periph, union ccb *done_ccb) { + struct ccb_trans_settings cts; struct pmp_softc *softc; struct ccb_ataio *ataio; union ccb *work_ccb; @@ -635,6 +636,19 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) done_ccb->ataio.res.sector_count; if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) { printf("PM status: %d - %08x\n", softc->pm_step, res); + /* Report device speed. */ + if (xpt_create_path(&dpath, periph, + xpt_path_path_id(periph->path), + softc->pm_step, 0) == CAM_REQ_CMP) { + bzero(&cts, sizeof(cts)); + xpt_setup_ccb(&cts.ccb_h, dpath, CAM_PRIORITY_NORMAL); + cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; + cts.type = CTS_TYPE_CURRENT_SETTINGS; + cts.xport_specific.sata.revision = (res & 0x0f0) >> 4; + cts.xport_specific.sata.valid = CTS_SATA_VALID_REVISION; + xpt_action((union ccb *)&cts); + xpt_free_path(dpath); + } softc->found |= (1 << softc->pm_step); softc->pm_step++; } else { diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 24a64fe4908..89f51538602 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -275,7 +275,7 @@ probeschedule(struct cam_periph *periph) static void probestart(struct cam_periph *periph, union ccb *start_ccb) { - /* Probe the device that our peripheral driver points to */ + struct ccb_trans_settings cts; struct ccb_ataio *ataio; struct ccb_scsiio *csio; probe_softc *softc; @@ -333,6 +333,55 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0); break; case PROBE_SETMODE: + { + int mode, wantmode; + + mode = 0; + /* Fetch user modes from SIM. */ + bzero(&cts, sizeof(cts)); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; + cts.type = CTS_TYPE_USER_SETTINGS; + xpt_action((union ccb *)&cts); + if (path->device->transport == XPORT_ATA) { + if (cts.xport_specific.ata.valid & CTS_ATA_VALID_MODE) + mode = cts.xport_specific.ata.mode; + } else { + if (cts.xport_specific.sata.valid & CTS_SATA_VALID_MODE) + mode = cts.xport_specific.sata.mode; + } +negotiate: + /* Honor device capabilities. */ + wantmode = mode = ata_max_mode(ident_buf, mode); + /* Report modes 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.mode = mode; + cts.xport_specific.ata.valid = CTS_ATA_VALID_MODE; + } else { + cts.xport_specific.sata.mode = mode; + cts.xport_specific.sata.valid = CTS_SATA_VALID_MODE; + } + xpt_action((union ccb *)&cts); + /* Fetch user modes from SIM. */ + bzero(&cts, sizeof(cts)); + 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); + if (path->device->transport == XPORT_ATA) { + if (cts.xport_specific.ata.valid & CTS_ATA_VALID_MODE) + mode = cts.xport_specific.ata.mode; + } else { + if (cts.xport_specific.ata.valid & CTS_SATA_VALID_MODE) + mode = cts.xport_specific.sata.mode; + } + /* If SIM disagree - renegotiate. */ + if (mode != wantmode) + goto negotiate; cam_fill_ataio(ataio, 1, probedone, @@ -341,12 +390,11 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) /*data_ptr*/NULL, /*dxfer_len*/0, 30 * 1000); - ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, - ata_max_mode(ident_buf, ATA_UDMA6, ATA_UDMA6)); + ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); break; + } case PROBE_SET_MULTI: { - struct ccb_trans_settings cts; u_int sectors; sectors = max(1, min(ident_buf->sectors_intr & 0xff, 16)); @@ -564,6 +612,7 @@ proberequestbackoff(struct cam_periph *periph, struct cam_ed *device) static void probedone(struct cam_periph *periph, union ccb *done_ccb) { + struct ccb_trans_settings cts; struct ata_params *ident_buf; probe_softc *softc; struct cam_path *path; @@ -619,9 +668,7 @@ noerror: 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. */ + /* 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; @@ -716,11 +763,17 @@ noerror: 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 && path->bus->sim->max_tagged_dev_openings != 0) { + /* Report SIM which tags are allowed. */ + 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.tags = path->device->maxtags; + cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS; + xpt_action((union ccb *)&cts); + /* Reconfigure queues for tagged queueing. */ xpt_start_tags(path); } ata_device_transport(path); diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 815da9d8815..72de5646725 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -819,19 +819,23 @@ struct ccb_trans_settings_sas { 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; +#define CTS_ATA_VALID_BYTECOUNT 0x02 + int mode; /* 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) */ +#define CTS_SATA_VALID_MODE 0x01 +#define CTS_SATA_VALID_BYTECOUNT 0x02 +#define CTS_SATA_VALID_REVISION 0x04 +#define CTS_SATA_VALID_PM 0x08 +#define CTS_SATA_VALID_TAGS 0x10 + int mode; /* Legacy PATA mode */ u_int bytecount; /* Length of PIO transaction */ + int revision; /* SATA revision */ + u_int pm_present; /* PM is present (XPT->SIM) */ + u_int tags; /* Number of allowed tags */ }; /* Get/Set transfer rate/width/disconnection/tag queueing settings */ diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 02d8d20f7dd..88ee3091675 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -1140,12 +1140,19 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string) if (sas->valid & CTS_SAS_VALID_SPEED) speed = sas->bitrate; } + 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_MODE) + speed = ata_mode2speed(ata->mode); + } 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_SPEED) - speed = sata->bitrate; + if (sata->valid & CTS_SATA_VALID_REVISION) + speed = ata_revision2speed(sata->revision); } mb = speed / 1000; @@ -1195,15 +1202,25 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string) struct ccb_trans_settings_ata *ata = &cts.xport_specific.ata; + printf(" ("); + if (ata->valid & CTS_ATA_VALID_MODE) + printf("%s, ", ata_mode2string(ata->mode)); if (ata->valid & CTS_ATA_VALID_BYTECOUNT) - printf(" (PIO size %dbytes)", ata->bytecount); + printf("PIO size %dbytes", ata->bytecount); + printf(")"); } if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = &cts.xport_specific.sata; + printf(" ("); + if (sata->valid & CTS_SATA_VALID_REVISION) + printf("SATA %d.x, ", sata->revision); + if (sata->valid & CTS_SATA_VALID_MODE) + printf("%s, ", ata_mode2string(sata->mode)); if (sata->valid & CTS_SATA_VALID_BYTECOUNT) - printf(" (PIO size %dbytes)", sata->bytecount); + printf("PIO size %dbytes", sata->bytecount); + printf(")"); } if (path->device->inq_flags & SID_CmdQue || path->device->flags & CAM_DEV_TAG_AFTER_COUNT) { diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 459aa64a465..3f6c9fcdd88 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -72,7 +72,7 @@ static void ahci_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int er static void ahci_execute_transaction(struct ahci_slot *slot); static void ahci_timeout(struct ahci_slot *slot); static void ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et); -static int ahci_setup_fis(struct ahci_cmd_tab *ctp, union ccb *ccb, int tag); +static int ahci_setup_fis(device_t dev, struct ahci_cmd_tab *ctp, union ccb *ccb, int tag); static void ahci_dmainit(device_t dev); static void ahci_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); static void ahci_dmafini(device_t dev); @@ -776,7 +776,7 @@ ahci_ch_attach(device_t dev) struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ahci_channel *ch = device_get_softc(dev); struct cam_devq *devq; - int rid, error; + int rid, error, i, sata_rev = 0; ch->dev = dev; ch->unit = (intptr_t)device_get_ivars(dev); @@ -795,9 +795,16 @@ ahci_ch_attach(device_t dev) pci_get_subvendor(ctlr->dev) == 0x1043 && pci_get_subdevice(ctlr->dev) == 0x81e4 && ch->unit == 0) - ch->sata_rev = 1; + sata_rev = 1; resource_int_value(device_get_name(dev), - device_get_unit(dev), "sata_rev", &ch->sata_rev); + device_get_unit(dev), "sata_rev", &sata_rev); + for (i = 0; i < 16; i++) { + ch->user[i].revision = sata_rev; + ch->user[i].mode = 0; + ch->user[i].bytecount = 8192; + ch->user[i].tags = ch->numslots; + ch->curr[i] = ch->user[i]; + } rid = ch->unit; if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE))) @@ -1275,6 +1282,10 @@ ahci_check_collision(device_t dev, union ccb *ccb) if (ch->numtslots != 0 && ch->taggedtarget != ccb->ccb_h.target_id) return (1); + /* Tagged command while we have no supported tag free. */ + if (((~ch->oslots) & (0xffffffff >> (32 - + ch->curr[ccb->ccb_h.target_id].tags))) == 0) + return (1); } else { /* Untagged command while tagged are active. */ if (ch->numrslots != 0 && ch->numtslots != 0) @@ -1298,15 +1309,21 @@ ahci_begin_transaction(device_t dev, union ccb *ccb) { struct ahci_channel *ch = device_get_softc(dev); struct ahci_slot *slot; - int tag; + int tag, tags; /* Choose empty slot. */ + tags = ch->numslots; + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) + tags = ch->curr[ccb->ccb_h.target_id].tags; tag = ch->lastslot; - while (ch->slot[tag].state != AHCI_SLOT_EMPTY) { - if (++tag >= ch->numslots) + while (1) { + if (tag >= tags) tag = 0; - KASSERT(tag != ch->lastslot, ("ahci: ALL SLOTS BUSY!")); - } + if (ch->slot[tag].state == AHCI_SLOT_EMPTY) + break; + tag++; + }; ch->lastslot = tag; /* Occupy chosen slot. */ slot = &ch->slot[tag]; @@ -1315,6 +1332,7 @@ ahci_begin_transaction(device_t dev, union ccb *ccb) if (ch->numrslots == 0 && ch->pm_level > 3) callout_stop(&ch->pm_timer); /* Update channel stats. */ + ch->oslots |= (1 << slot->slot); ch->numrslots++; if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { @@ -1392,7 +1410,7 @@ ahci_execute_transaction(struct ahci_slot *slot) ctp = (struct ahci_cmd_tab *) (ch->dma.work + AHCI_CT_OFFSET + (AHCI_CT_SIZE * slot->slot)); /* Setup the FIS for this request */ - if (!(fis_size = ahci_setup_fis(ctp, ccb, slot->slot))) { + if (!(fis_size = ahci_setup_fis(dev, ctp, ccb, slot->slot))) { device_printf(ch->dev, "Setting up SATA FIS failed\n"); ahci_end_transaction(slot, AHCI_ERR_INVALID); return; @@ -1635,6 +1653,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) ccb->ccb_h.status |= CAM_REQ_CMP_ERR; } /* Free slot. */ + ch->oslots &= ~(1 << slot->slot); ch->rslots &= ~(1 << slot->slot); ch->aslots &= ~(1 << slot->slot); slot->state = AHCI_SLOT_EMPTY; @@ -1664,7 +1683,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) } else xpt_done(ccb); /* Unfreeze frozen command. */ - if (ch->frozen && ch->numrslots == 0) { + if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) { union ccb *fccb = ch->frozen; ch->frozen = NULL; ahci_begin_transaction(dev, fccb); @@ -1964,8 +1983,9 @@ ahci_reset(device_t dev) } static int -ahci_setup_fis(struct ahci_cmd_tab *ctp, union ccb *ccb, int tag) +ahci_setup_fis(device_t dev, struct ahci_cmd_tab *ctp, union ccb *ccb, int tag) { + struct ahci_channel *ch = device_get_softc(dev); u_int8_t *fis = &ctp->cfis[0]; bzero(ctp->cfis, 64); @@ -1974,7 +1994,8 @@ ahci_setup_fis(struct ahci_cmd_tab *ctp, union ccb *ccb, int tag) if (ccb->ccb_h.func_code == XPT_SCSI_IO) { fis[1] |= 0x80; fis[2] = ATA_PACKET_CMD; - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) + if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && + ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) fis[3] = ATA_F_DMA; else { fis[5] = ccb->csio.dxfer_len; @@ -2054,6 +2075,7 @@ static int ahci_sata_phy_reset(device_t dev, int quick) { struct ahci_channel *ch = device_get_softc(dev); + int sata_rev; uint32_t val; if (quick) { @@ -2064,11 +2086,12 @@ ahci_sata_phy_reset(device_t dev, int quick) if (bootverbose) device_printf(dev, "hardware reset ...\n"); - if (ch->sata_rev == 1) + sata_rev = ch->user[ch->pm_present ? 15 : 0].revision; + if (sata_rev == 1) val = ATA_SC_SPD_SPEED_GEN1; - else if (ch->sata_rev == 2) + else if (sata_rev == 2) val = ATA_SC_SPD_SPEED_GEN2; - else if (ch->sata_rev == 3) + else if (sata_rev == 3) val = ATA_SC_SPD_SPEED_GEN3; else val = 0; @@ -2125,10 +2148,22 @@ ahciaction(struct cam_sim *sim, union ccb *ccb) case XPT_SET_TRAN_SETTINGS: { struct ccb_trans_settings *cts = &ccb->cts; + struct ahci_device *d; - if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) { + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + d = &ch->curr[ccb->ccb_h.target_id]; + else + d = &ch->user[ccb->ccb_h.target_id]; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION) + d->revision = cts->xport_specific.sata.revision; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE) + d->mode = cts->xport_specific.sata.mode; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) + d->bytecount = min(8192, cts->xport_specific.sata.bytecount); + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS) + d->tags = min(ch->numslots, cts->xport_specific.sata.tags); + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) ch->pm_present = cts->xport_specific.sata.pm_present; - } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -2137,36 +2172,41 @@ ahciaction(struct cam_sim *sim, union ccb *ccb) /* Get default/user set transfer settings for the target */ { struct ccb_trans_settings *cts = &ccb->cts; + struct ahci_device *d; uint32_t status; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + d = &ch->curr[ccb->ccb_h.target_id]; + else + d = &ch->user[ccb->ccb_h.target_id]; cts->protocol = PROTO_ATA; cts->protocol_version = PROTO_VERSION_UNSPECIFIED; cts->transport = XPORT_SATA; cts->transport_version = XPORT_VERSION_UNSPECIFIED; cts->proto_specific.valid = 0; cts->xport_specific.sata.valid = 0; - if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + if (cts->type == CTS_TYPE_CURRENT_SETTINGS && + (ccb->ccb_h.target_id == 15 || + (ccb->ccb_h.target_id == 0 && !ch->pm_present))) { status = ATA_INL(ch->r_mem, AHCI_P_SSTS) & ATA_SS_SPD_MASK; - else - status = ATA_INL(ch->r_mem, AHCI_P_SCTL) & ATA_SC_SPD_MASK; - if (status & ATA_SS_SPD_GEN3) { - cts->xport_specific.sata.bitrate = 600000; - cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; - } else if (status & ATA_SS_SPD_GEN2) { - cts->xport_specific.sata.bitrate = 300000; - cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; - } else if (status & ATA_SS_SPD_GEN1) { - cts->xport_specific.sata.bitrate = 150000; - cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; - } - if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { - cts->xport_specific.sata.pm_present = - (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_PMA) ? - 1 : 0; + if (status & 0x0f0) { + cts->xport_specific.sata.revision = + (status & 0x0f0) >> 4; + cts->xport_specific.sata.valid |= + CTS_SATA_VALID_REVISION; + } } else { - cts->xport_specific.sata.pm_present = ch->pm_present; + cts->xport_specific.sata.revision = d->revision; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; } + cts->xport_specific.sata.mode = d->mode; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE; + cts->xport_specific.sata.bytecount = d->bytecount; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT; + cts->xport_specific.sata.pm_present = ch->pm_present; cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; + cts->xport_specific.sata.tags = d->tags; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS; ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index cda907812df..e11f84f489d 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -340,6 +340,13 @@ struct ahci_slot { struct callout timeout; /* Execution timeout */ }; +struct ahci_device { + int revision; + int mode; + u_int bytecount; + u_int tags; +}; + /* structure describing an ATA channel */ struct ahci_channel { device_t dev; /* Device handle */ @@ -355,13 +362,13 @@ struct ahci_channel { int quirks; int numslots; /* Number of present slots */ int pm_level; /* power management level */ - int sata_rev; /* Maximum allowed SATA generation */ struct ahci_slot slot[AHCI_MAX_SLOTS]; union ccb *hold[AHCI_MAX_SLOTS]; struct mtx mtx; /* state lock */ int devices; /* What is present */ int pm_present; /* PM presence reported */ + uint32_t oslots; /* Occupied slots */ uint32_t rslots; /* Running slots */ uint32_t aslots; /* Slots with atomic commands */ int numrslots; /* Number of running slots */ @@ -372,6 +379,9 @@ struct ahci_channel { int taggedtarget; /* Last tagged target */ union ccb *frozen; /* Frozen command */ struct callout pm_timer; /* Power management events */ + + struct ahci_device user[16]; /* User-specified settings */ + struct ahci_device curr[16]; /* Current settings */ }; /* structure describing a AHCI controller */ diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 1693883f3d9..7ee6eb63d06 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -69,7 +69,7 @@ static void siis_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int er static void siis_execute_transaction(struct siis_slot *slot); static void siis_timeout(struct siis_slot *slot); static void siis_end_transaction(struct siis_slot *slot, enum siis_err_type et); -static int siis_setup_fis(struct siis_cmd *ctp, union ccb *ccb, int tag); +static int siis_setup_fis(device_t dev, struct siis_cmd *ctp, union ccb *ccb, int tag); static void siis_dmainit(device_t dev); static void siis_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); static void siis_dmafini(device_t dev); @@ -415,14 +415,21 @@ siis_ch_attach(device_t dev) { struct siis_channel *ch = device_get_softc(dev); struct cam_devq *devq; - int rid, error; + int rid, error, i, sata_rev = 0; ch->dev = dev; ch->unit = (intptr_t)device_get_ivars(dev); resource_int_value(device_get_name(dev), device_get_unit(dev), "pm_level", &ch->pm_level); resource_int_value(device_get_name(dev), - device_get_unit(dev), "sata_rev", &ch->sata_rev); + device_get_unit(dev), "sata_rev", &sata_rev); + for (i = 0; i < 16; i++) { + ch->user[i].revision = sata_rev; + ch->user[i].mode = 0; + ch->user[i].bytecount = 8192; + ch->user[i].tags = SIIS_MAX_SLOTS; + ch->curr[i] = ch->user[i]; + } mtx_init(&ch->mtx, "SIIS channel lock", NULL, MTX_DEF); rid = ch->unit; if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -832,6 +839,13 @@ siis_check_collision(device_t dev, union ccb *ccb) struct siis_channel *ch = device_get_softc(dev); mtx_assert(&ch->mtx, MA_OWNED); + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { + /* Tagged command while we have no supported tag free. */ + if (((~ch->oslots) & (0x7fffffff >> (31 - + ch->curr[ccb->ccb_h.target_id].tags))) == 0) + return (1); + } if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) { /* Atomic command while anything active. */ @@ -850,21 +864,20 @@ siis_begin_transaction(device_t dev, union ccb *ccb) { struct siis_channel *ch = device_get_softc(dev); struct siis_slot *slot; - int tag; + int tag, tags; mtx_assert(&ch->mtx, MA_OWNED); /* Choose empty slot. */ - tag = ch->lastslot; - while (ch->slot[tag].state != SIIS_SLOT_EMPTY) { - if (++tag >= SIIS_MAX_SLOTS) - tag = 0; - KASSERT(tag != ch->lastslot, ("siis: ALL SLOTS BUSY!")); - } - ch->lastslot = tag; + tags = SIIS_MAX_SLOTS; + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) + tags = ch->curr[ccb->ccb_h.target_id].tags; + tag = fls((~ch->oslots) & (0x7fffffff >> (31 - tags))) - 1; /* Occupy chosen slot. */ slot = &ch->slot[tag]; slot->ccb = ccb; /* Update channel stats. */ + ch->oslots |= (1 << slot->slot); ch->numrslots++; if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { @@ -961,7 +974,7 @@ siis_execute_transaction(struct siis_slot *slot) ctp->control |= htole16(SIIS_PRB_PACKET_WRITE); } /* Setup the FIS for this request */ - if (!siis_setup_fis(ctp, ccb, slot->slot)) { + if (!siis_setup_fis(dev, ctp, ccb, slot->slot)) { device_printf(ch->dev, "Setting up SATA FIS failed\n"); if (!ch->readlog) xpt_freeze_simq(ch->sim, 1); @@ -1118,6 +1131,7 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) ccb->ccb_h.status |= CAM_REQ_CMP_ERR; } /* Free slot. */ + ch->oslots &= ~(1 << slot->slot); ch->rslots &= ~(1 << slot->slot); ch->aslots &= ~(1 << slot->slot); if (et != SIIS_ERR_TIMEOUT) { @@ -1143,7 +1157,7 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) } else xpt_done(ccb); /* Unfreeze frozen command. */ - if (ch->frozen && ch->numrslots == 0) { + if (ch->frozen && !siis_check_collision(dev, ch->frozen)) { union ccb *fccb = ch->frozen; ch->frozen = NULL; siis_begin_transaction(dev, fccb); @@ -1332,7 +1346,7 @@ static void siis_reset(device_t dev) { struct siis_channel *ch = device_get_softc(dev); - int i, retry = 0; + int i, retry = 0, sata_rev; uint32_t val; if (bootverbose) @@ -1376,11 +1390,12 @@ siis_reset(device_t dev) /* Disable port interrupts */ ATA_OUTL(ch->r_mem, SIIS_P_IECLR, 0x0000FFFF); /* Set speed limit. */ - if (ch->sata_rev == 1) + sata_rev = ch->user[ch->pm_present ? 15 : 0].revision; + if (sata_rev == 1) val = ATA_SC_SPD_SPEED_GEN1; - else if (ch->sata_rev == 2) + else if (sata_rev == 2) val = ATA_SC_SPD_SPEED_GEN2; - else if (ch->sata_rev == 3) + else if (sata_rev == 3) val = ATA_SC_SPD_SPEED_GEN3; else val = 0; @@ -1432,8 +1447,9 @@ retry: } static int -siis_setup_fis(struct siis_cmd *ctp, union ccb *ccb, int tag) +siis_setup_fis(device_t dev, struct siis_cmd *ctp, union ccb *ccb, int tag) { + struct siis_channel *ch = device_get_softc(dev); u_int8_t *fis = &ctp->fis[0]; bzero(fis, 24); @@ -1442,7 +1458,8 @@ siis_setup_fis(struct siis_cmd *ctp, union ccb *ccb, int tag) if (ccb->ccb_h.func_code == XPT_SCSI_IO) { fis[1] |= 0x80; fis[2] = ATA_PACKET_CMD; - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) + if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && + ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) fis[3] = ATA_F_DMA; else { fis[5] = ccb->csio.dxfer_len; @@ -1554,7 +1571,20 @@ siisaction(struct cam_sim *sim, union ccb *ccb) case XPT_SET_TRAN_SETTINGS: { struct ccb_trans_settings *cts = &ccb->cts; + struct siis_device *d; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + d = &ch->curr[ccb->ccb_h.target_id]; + else + d = &ch->user[ccb->ccb_h.target_id]; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION) + d->revision = cts->xport_specific.sata.revision; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE) + d->mode = cts->xport_specific.sata.mode; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) + d->bytecount = min(8192, cts->xport_specific.sata.bytecount); + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS) + d->tags = min(SIIS_MAX_SLOTS, cts->xport_specific.sata.tags); if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) { ch->pm_present = cts->xport_specific.sata.pm_present; if (ch->pm_present) @@ -1570,30 +1600,41 @@ siisaction(struct cam_sim *sim, union ccb *ccb) /* Get default/user set transfer settings for the target */ { struct ccb_trans_settings *cts = &ccb->cts; + struct siis_device *d; uint32_t status; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + d = &ch->curr[ccb->ccb_h.target_id]; + else + d = &ch->user[ccb->ccb_h.target_id]; cts->protocol = PROTO_ATA; cts->protocol_version = PROTO_VERSION_UNSPECIFIED; cts->transport = XPORT_SATA; cts->transport_version = XPORT_VERSION_UNSPECIFIED; cts->proto_specific.valid = 0; cts->xport_specific.sata.valid = 0; - if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + if (cts->type == CTS_TYPE_CURRENT_SETTINGS && + (ccb->ccb_h.target_id == 15 || + (ccb->ccb_h.target_id == 0 && !ch->pm_present))) { status = ATA_INL(ch->r_mem, SIIS_P_SSTS) & ATA_SS_SPD_MASK; - else - status = ATA_INL(ch->r_mem, SIIS_P_SCTL) & ATA_SC_SPD_MASK; - if (status & ATA_SS_SPD_GEN3) { - cts->xport_specific.sata.bitrate = 600000; - cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; - } else if (status & ATA_SS_SPD_GEN2) { - cts->xport_specific.sata.bitrate = 300000; - cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; - } else if (status & ATA_SS_SPD_GEN1) { - cts->xport_specific.sata.bitrate = 150000; - cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; + if (status & 0x0f0) { + cts->xport_specific.sata.revision = + (status & 0x0f0) >> 4; + cts->xport_specific.sata.valid |= + CTS_SATA_VALID_REVISION; + } + } else { + cts->xport_specific.sata.revision = d->revision; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; } + cts->xport_specific.sata.mode = d->mode; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE; + cts->xport_specific.sata.bytecount = d->bytecount; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT; cts->xport_specific.sata.pm_present = ch->pm_present; cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; + cts->xport_specific.sata.tags = d->tags; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS; ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; diff --git a/sys/dev/siis/siis.h b/sys/dev/siis/siis.h index 20de88fd94d..52332c5ad68 100644 --- a/sys/dev/siis/siis.h +++ b/sys/dev/siis/siis.h @@ -346,6 +346,13 @@ struct siis_slot { struct callout timeout; /* Execution timeout */ }; +struct siis_device { + int revision; + int mode; + u_int bytecount; + u_int tags; +}; + /* structure describing an ATA channel */ struct siis_channel { device_t dev; /* Device handle */ @@ -357,13 +364,13 @@ struct siis_channel { struct cam_sim *sim; struct cam_path *path; int pm_level; /* power management level */ - int sata_rev; /* Maximum allowed SATA generation */ struct siis_slot slot[SIIS_MAX_SLOTS]; union ccb *hold[SIIS_MAX_SLOTS]; struct mtx mtx; /* state lock */ int devices; /* What is present */ int pm_present; /* PM presence reported */ + uint32_t oslots; /* Occupied slots */ uint32_t rslots; /* Running slots */ uint32_t aslots; /* Slots with atomic commands */ uint32_t eslots; /* Slots in error */ @@ -374,8 +381,10 @@ struct siis_channel { int readlog; /* Our READ LOG active */ int fatalerr; /* Fatal error happend */ int recovery; /* Some slots are in error */ - int lastslot; /* Last used slot */ union ccb *frozen; /* Frozen command */ + + struct siis_device user[16]; /* User-specified settings */ + struct siis_device curr[16]; /* Current settings */ }; /* structure describing a SIIS controller */ From 06a7b83b5e85d96d0cd7582019534411dcb91205 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 2 Dec 2009 10:47:11 +0000 Subject: [PATCH 0721/2592] MFC r199822: Drop USB mass storage devices support from ata(4). It is out of the build as long as I remember, and completely superseded by better maintained umass(4). It's main idea was to optionally avoid CAM dependency for such devices, but with move ATA to CAM, it is not actual any more. No objections: hselasky@, thompsa@, arch@ --- sbin/atacontrol/atacontrol.c | 6 - sys/conf/files | 1 - sys/dev/ata/ata-all.c | 3 - sys/dev/ata/ata-usb.c | 1127 ------------------------------- sys/modules/ata/atausb/Makefile | 10 - sys/sys/ata.h | 3 - 6 files changed, 1150 deletions(-) delete mode 100644 sys/dev/ata/ata-usb.c delete mode 100644 sys/modules/ata/atausb/Makefile diff --git a/sbin/atacontrol/atacontrol.c b/sbin/atacontrol/atacontrol.c index f68596c9981..5b5b85ac482 100644 --- a/sbin/atacontrol/atacontrol.c +++ b/sbin/atacontrol/atacontrol.c @@ -56,9 +56,6 @@ mode2str(int mode) case ATA_UDMA6: return "UDMA133"; case ATA_SA150: return "SATA150"; case ATA_SA300: return "SATA300"; - case ATA_USB: return "USB"; - case ATA_USB1: return "USB1"; - case ATA_USB2: return "USB2"; case ATA_DMA: return "BIOSDMA"; default: return "???"; } @@ -84,9 +81,6 @@ str2mode(char *str) if (!strcasecmp(str, "UDMA133")) return ATA_UDMA6; if (!strcasecmp(str, "SATA150")) return ATA_SA150; if (!strcasecmp(str, "SATA300")) return ATA_SA300; - if (!strcasecmp(str, "USB")) return ATA_USB; - if (!strcasecmp(str, "USB1")) return ATA_USB1; - if (!strcasecmp(str, "USB2")) return ATA_USB2; if (!strcasecmp(str, "BIOSDMA")) return ATA_DMA; return -1; } diff --git a/sys/conf/files b/sys/conf/files index 9c6b071546f..70be131559d 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -530,7 +530,6 @@ 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 dev/ata/ata-raid.c optional ataraid -dev/ata/ata-usb.c optional atausb usb dev/ata/atapi-cd.c optional atapicd dev/ata/atapi-fd.c optional atapifd dev/ata/atapi-tape.c optional atapist diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index d0a07c36289..a1a6f27556a 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -942,9 +942,6 @@ ata_mode2str(int mode) case ATA_UDMA6: return "UDMA133"; case ATA_SA150: return "SATA150"; case ATA_SA300: return "SATA300"; - case ATA_USB: return "USB"; - case ATA_USB1: return "USB1"; - case ATA_USB2: return "USB2"; default: if (mode & ATA_DMA_MASK) return "BIOSDMA"; diff --git a/sys/dev/ata/ata-usb.c b/sys/dev/ata/ata-usb.c deleted file mode 100644 index a08b80ad769..00000000000 --- a/sys/dev/ata/ata-usb.c +++ /dev/null @@ -1,1127 +0,0 @@ -/*- - * Copyright (c) 2006 - 2008 Søren Schmidt - * All rights reserved. - * - * Copyright (c) 2006 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, - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "usbdevs.h" -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#define ATAUSB_BULK_SIZE (1<<17) - -/* Command Block Wrapper */ -struct bbb_cbw { - uint8_t signature[4]; -#define CBWSIGNATURE 0x43425355 - - uint8_t tag[4]; - uint8_t transfer_length[4]; - uint8_t flags; -#define CBWFLAGS_OUT 0x00 -#define CBWFLAGS_IN 0x80 - - uint8_t lun; - uint8_t length; -#define CBWCDBLENGTH 16 - - uint8_t cdb[CBWCDBLENGTH]; -} __packed; - -/* Command Status Wrapper */ -struct bbb_csw { - uint8_t signature[4]; -#define CSWSIGNATURE 0x53425355 - - uint8_t tag[4]; - uint8_t residue[4]; - uint8_t status; -#define CSWSTATUS_GOOD 0x0 -#define CSWSTATUS_FAILED 0x1 -#define CSWSTATUS_PHASE 0x2 -} __packed; - -/* USB-ATA 'controller' softc */ -struct atausb2_softc { - struct bbb_cbw cbw; - struct bbb_csw csw; - struct mtx locked_mtx; - - struct ata_channel *locked_ch; - struct ata_channel *restart_ch; - struct ata_request *ata_request; - -#define ATAUSB_T_BBB_RESET1 0 -#define ATAUSB_T_BBB_RESET2 1 -#define ATAUSB_T_BBB_RESET3 2 -#define ATAUSB_T_BBB_COMMAND 3 -#define ATAUSB_T_BBB_DATA_READ 4 -#define ATAUSB_T_BBB_DATA_RD_CS 5 -#define ATAUSB_T_BBB_DATA_WRITE 6 -#define ATAUSB_T_BBB_DATA_WR_CS 7 -#define ATAUSB_T_BBB_STATUS 8 -#define ATAUSB_T_BBB_MAX 9 - -#define ATAUSB_T_MAX ATAUSB_T_BBB_MAX - - struct usb_xfer *xfer[ATAUSB_T_MAX]; - caddr_t ata_data; - device_t dev; - - uint32_t timeout; - uint32_t ata_donecount; - uint32_t ata_bytecount; - - uint8_t last_xfer_no; - uint8_t usb2_speed; - uint8_t intr_stalled; - uint8_t maxlun; - uint8_t iface_no; - uint8_t status_try; -}; - -static const int atausbdebug = 0; - -/* prototypes */ - -static device_probe_t atausb2_probe; -static device_attach_t atausb2_attach; -static device_detach_t atausb2_detach; - -static usb_callback_t atausb2_t_bbb_reset1_callback; -static usb_callback_t atausb2_t_bbb_reset2_callback; -static usb_callback_t atausb2_t_bbb_reset3_callback; -static usb_callback_t atausb2_t_bbb_command_callback; -static usb_callback_t atausb2_t_bbb_data_read_callback; -static usb_callback_t atausb2_t_bbb_data_rd_cs_callback; -static usb_callback_t atausb2_t_bbb_data_write_callback; -static usb_callback_t atausb2_t_bbb_data_wr_cs_callback; -static usb_callback_t atausb2_t_bbb_status_callback; -static usb_callback_t atausb2_tr_error; - -static void atausb2_cancel_request(struct atausb2_softc *sc); -static void atausb2_transfer_start(struct atausb2_softc *sc, uint8_t xfer_no); -static void atausb2_t_bbb_data_clear_stall_callback(struct usb_xfer *xfer, - uint8_t next_xfer, uint8_t stall_xfer, usb_error_t error); -static int ata_usbchannel_begin_transaction(struct ata_request *request); -static int ata_usbchannel_end_transaction(struct ata_request *request); - -static device_probe_t ata_usbchannel_probe; -static device_attach_t ata_usbchannel_attach; -static device_detach_t ata_usbchannel_detach; - -static ata_setmode_t ata_usbchannel_setmode; -static ata_locking_t ata_usbchannel_locking; - -/* - * USB frontend part - */ - -struct usb_config atausb2_config[ATAUSB_T_BBB_MAX] = { - - [ATAUSB_T_BBB_RESET1] = { - .type = UE_CONTROL, - .endpoint = 0x00, /* Control pipe */ - .direction = UE_DIR_ANY, - .bufsize = sizeof(struct usb_device_request), - .flags = {}, - .callback = &atausb2_t_bbb_reset1_callback, - .timeout = 5000, /* 5 seconds */ - .interval = 500, /* 500 milliseconds */ - }, - - [ATAUSB_T_BBB_RESET2] = { - .type = UE_CONTROL, - .endpoint = 0x00, /* Control pipe */ - .direction = UE_DIR_ANY, - .bufsize = sizeof(struct usb_device_request), - .flags = {}, - .callback = &atausb2_t_bbb_reset2_callback, - .timeout = 5000, /* 5 seconds */ - .interval = 50, /* 50 milliseconds */ - }, - - [ATAUSB_T_BBB_RESET3] = { - .type = UE_CONTROL, - .endpoint = 0x00, /* Control pipe */ - .direction = UE_DIR_ANY, - .bufsize = sizeof(struct usb_device_request), - .flags = {}, - .callback = &atausb2_t_bbb_reset3_callback, - .timeout = 5000, /* 5 seconds */ - .interval = 50, /* 50 milliseconds */ - }, - - [ATAUSB_T_BBB_COMMAND] = { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_OUT, - .bufsize = sizeof(struct bbb_cbw), - .flags = {}, - .callback = &atausb2_t_bbb_command_callback, - .timeout = 5000, /* 5 seconds */ - }, - - [ATAUSB_T_BBB_DATA_READ] = { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_IN, - .bufsize = ATAUSB_BULK_SIZE, - .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,}, - .callback = &atausb2_t_bbb_data_read_callback, - .timeout = 0, /* overwritten later */ - }, - - [ATAUSB_T_BBB_DATA_RD_CS] = { - .type = UE_CONTROL, - .endpoint = 0x00, /* Control pipe */ - .direction = UE_DIR_ANY, - .bufsize = sizeof(struct usb_device_request), - .flags = {}, - .callback = &atausb2_t_bbb_data_rd_cs_callback, - .timeout = 5000, /* 5 seconds */ - }, - - [ATAUSB_T_BBB_DATA_WRITE] = { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_OUT, - .bufsize = ATAUSB_BULK_SIZE, - .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,}, - .callback = &atausb2_t_bbb_data_write_callback, - .timeout = 0, /* overwritten later */ - }, - - [ATAUSB_T_BBB_DATA_WR_CS] = { - .type = UE_CONTROL, - .endpoint = 0x00, /* Control pipe */ - .direction = UE_DIR_ANY, - .bufsize = sizeof(struct usb_device_request), - .flags = {}, - .callback = &atausb2_t_bbb_data_wr_cs_callback, - .timeout = 5000, /* 5 seconds */ - }, - - [ATAUSB_T_BBB_STATUS] = { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_IN, - .bufsize = sizeof(struct bbb_csw), - .flags = {.short_xfer_ok = 1,}, - .callback = &atausb2_t_bbb_status_callback, - .timeout = 5000, /* ms */ - }, -}; - -static devclass_t atausb2_devclass; - -static device_method_t atausb2_methods[] = { - DEVMETHOD(device_probe, atausb2_probe), - DEVMETHOD(device_attach, atausb2_attach), - DEVMETHOD(device_detach, atausb2_detach), - {0, 0} -}; - -static driver_t atausb2_driver = { - .name = "atausb", - .methods = atausb2_methods, - .size = sizeof(struct atausb2_softc), -}; - -DRIVER_MODULE(atausb, uhub, atausb2_driver, atausb2_devclass, 0, 0); -MODULE_DEPEND(atausb, usb, 1, 1, 1); -MODULE_VERSION(atausb, 1); - -static int -atausb2_probe(device_t dev) -{ - struct usb_attach_arg *uaa = device_get_ivars(dev); - struct usb_interface_descriptor *id; - - if (uaa->usb_mode != USB_MODE_HOST) { - return (ENXIO); - } - if (uaa->use_generic == 0) { - /* give other drivers a try first */ - return (ENXIO); - } - id = usbd_get_interface_descriptor(uaa->iface); - if ((!id) || (id->bInterfaceClass != UICLASS_MASS)) { - return (ENXIO); - } - switch (id->bInterfaceSubClass) { - case UISUBCLASS_QIC157: - case UISUBCLASS_RBC: - case UISUBCLASS_SCSI: - case UISUBCLASS_SFF8020I: - case UISUBCLASS_SFF8070I: - case UISUBCLASS_UFI: - switch (id->bInterfaceProtocol) { - case UIPROTO_MASS_CBI: - case UIPROTO_MASS_CBI_I: - case UIPROTO_MASS_BBB: - case UIPROTO_MASS_BBB_OLD: - return (0); - default: - return (0); - } - break; - default: - return (0); - } -} - -static int -atausb2_attach(device_t dev) -{ - struct atausb2_softc *sc = device_get_softc(dev); - struct usb_attach_arg *uaa = device_get_ivars(dev); - struct usb_interface_descriptor *id; - const char *proto, *subclass; - struct usb_device_request request; - device_t child; - uint16_t i; - uint8_t maxlun; - uint8_t has_intr; - int err; - - device_set_usb_desc(dev); - - sc->dev = dev; - sc->maxlun = 0; - sc->locked_ch = NULL; - sc->restart_ch = NULL; - sc->usb2_speed = usbd_get_speed(uaa->device); - mtx_init(&sc->locked_mtx, "ATAUSB lock", NULL, (MTX_DEF | MTX_RECURSE)); - - id = usbd_get_interface_descriptor(uaa->iface); - switch (id->bInterfaceProtocol) { - case UIPROTO_MASS_BBB: - case UIPROTO_MASS_BBB_OLD: - proto = "Bulk-Only"; - break; - case UIPROTO_MASS_CBI: - proto = "CBI"; - break; - case UIPROTO_MASS_CBI_I: - proto = "CBI with CCI"; - break; - default: - proto = "Unknown"; - } - - switch (id->bInterfaceSubClass) { - case UISUBCLASS_RBC: - subclass = "RBC"; - break; - case UISUBCLASS_QIC157: - case UISUBCLASS_SFF8020I: - case UISUBCLASS_SFF8070I: - subclass = "ATAPI"; - break; - case UISUBCLASS_SCSI: - subclass = "SCSI"; - break; - case UISUBCLASS_UFI: - subclass = "UFI"; - break; - default: - subclass = "Unknown"; - } - - has_intr = (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I); - sc->iface_no = id->bInterfaceNumber; - - device_printf(dev, "using %s over %s\n", subclass, proto); - if (strcmp(proto, "Bulk-Only") || - (strcmp(subclass, "ATAPI") && strcmp(subclass, "SCSI"))) { - goto detach; - } - err = usbd_transfer_setup(uaa->device, &uaa->info.bIfaceIndex, - sc->xfer, atausb2_config, ATAUSB_T_BBB_MAX, sc, - &sc->locked_mtx); - - /* skip reset first time */ - sc->last_xfer_no = ATAUSB_T_BBB_COMMAND; - - if (err) { - device_printf(sc->dev, "could not setup required " - "transfers, %s\n", usbd_errstr(err)); - goto detach; - } - /* get number of devices so we can add matching channels */ - request.bmRequestType = UT_READ_CLASS_INTERFACE; - request.bRequest = 0xfe; /* GET_MAX_LUN; */ - USETW(request.wValue, 0); - USETW(request.wIndex, sc->iface_no); - USETW(request.wLength, sizeof(maxlun)); - err = usbd_do_request(uaa->device, &Giant, &request, &maxlun); - - if (err) { - if (bootverbose) { - device_printf(sc->dev, "get maxlun not supported %s\n", - usbd_errstr(err)); - } - } else { - sc->maxlun = maxlun; - if (bootverbose) { - device_printf(sc->dev, "maxlun=%d\n", sc->maxlun); - } - } - - /* ata channels are children to this USB control device */ - for (i = 0; i <= sc->maxlun; i++) { - if ((child = device_add_child(sc->dev, "ata", - devclass_find_free_unit(ata_devclass, 2))) == NULL) { - device_printf(sc->dev, "failed to add ata child device\n"); - } else - device_set_ivars(child, (void *)(intptr_t)i); - } - bus_generic_attach(sc->dev); - - return (0); - -detach: - atausb2_detach(dev); - return (ENXIO); -} - -static int -atausb2_detach(device_t dev) -{ - struct atausb2_softc *sc = device_get_softc(dev); - device_t *children; - int nchildren, i; - - /* teardown our statemachine */ - - usbd_transfer_unsetup(sc->xfer, ATAUSB_T_MAX); - - /* detach & delete all children, if any */ - - if (!device_get_children(dev, &children, &nchildren)) { - for (i = 0; i < nchildren; i++) { - device_delete_child(dev, children[i]); - } - free(children, M_TEMP); - } - mtx_destroy(&sc->locked_mtx); - return (0); -} - -static void -atausb2_transfer_start(struct atausb2_softc *sc, uint8_t xfer_no) -{ - if (atausbdebug) { - device_printf(sc->dev, "BBB transfer %d\n", xfer_no); - } - if (sc->xfer[xfer_no]) { - sc->last_xfer_no = xfer_no; - usbd_transfer_start(sc->xfer[xfer_no]); - } else { - atausb2_cancel_request(sc); - } -} - -static void -atausb2_t_bbb_reset1_callback(struct usb_xfer *xfer, usb_error_t error) -{ - struct atausb2_softc *sc = usbd_xfer_softc(xfer); - struct usb_device_request req; - struct usb_page_cache *pc; - - switch (USB_GET_STATE(xfer)) { - case USB_ST_TRANSFERRED: - atausb2_transfer_start(sc, ATAUSB_T_BBB_RESET2); - return; - - case USB_ST_SETUP: - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - req.bRequest = 0xff; /* bulk-only reset */ - USETW(req.wValue, 0); - req.wIndex[0] = sc->iface_no; - req.wIndex[1] = 0; - USETW(req.wLength, 0); - - pc = usbd_xfer_get_frame(xfer, 0); - usbd_copy_in(pc, 0, &req, sizeof(req)); - - usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); - usbd_xfer_set_frames(xfer, 1); - usbd_transfer_submit(xfer); - return; - - default: /* Error */ - atausb2_tr_error(xfer, error); - return; - - } -} - -static void -atausb2_t_bbb_reset2_callback(struct usb_xfer *xfer, usb_error_t error) -{ - atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_RESET3, - ATAUSB_T_BBB_DATA_READ, error); -} - -static void -atausb2_t_bbb_reset3_callback(struct usb_xfer *xfer, usb_error_t error) -{ - atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_COMMAND, - ATAUSB_T_BBB_DATA_WRITE, error); -} - -static void -atausb2_t_bbb_data_clear_stall_callback(struct usb_xfer *xfer, - uint8_t next_xfer, uint8_t stall_xfer, usb_error_t error) -{ - struct atausb2_softc *sc = usbd_xfer_softc(xfer); - - switch (USB_GET_STATE(xfer)) { - case USB_ST_TRANSFERRED: -tr_transferred: - atausb2_transfer_start(sc, next_xfer); - return; - - case USB_ST_SETUP: - if (usbd_clear_stall_callback(xfer, sc->xfer[stall_xfer])) { - goto tr_transferred; - } - return; - - default: /* Error */ - atausb2_tr_error(xfer, error); - return; - - } -} - -static void -atausb2_t_bbb_command_callback(struct usb_xfer *xfer, usb_error_t error) -{ - struct atausb2_softc *sc = usbd_xfer_softc(xfer); - struct ata_request *request = sc->ata_request; - struct ata_channel *ch; - struct usb_page_cache *pc; - uint32_t tag; - - switch (USB_GET_STATE(xfer)) { - case USB_ST_TRANSFERRED: - atausb2_transfer_start - (sc, ((request->flags & ATA_R_READ) ? ATAUSB_T_BBB_DATA_READ : - (request->flags & ATA_R_WRITE) ? ATAUSB_T_BBB_DATA_WRITE : - ATAUSB_T_BBB_STATUS)); - return; - - case USB_ST_SETUP: - - sc->status_try = 0; - - if (request) { - ch = device_get_softc(request->parent); - - sc->timeout = (request->timeout * 1000) + 5000; - - tag = UGETDW(sc->cbw.tag) + 1; - - USETDW(sc->cbw.signature, CBWSIGNATURE); - USETDW(sc->cbw.tag, tag); - USETDW(sc->cbw.transfer_length, request->bytecount); - sc->cbw.flags = (request->flags & ATA_R_READ) ? CBWFLAGS_IN : CBWFLAGS_OUT; - sc->cbw.lun = ch->unit; - sc->cbw.length = 16; - bzero(sc->cbw.cdb, 16); - bcopy(request->u.atapi.ccb, sc->cbw.cdb, 12); /* XXX SOS */ - - pc = usbd_xfer_get_frame(xfer, 0); - usbd_copy_in(pc, 0, &sc->cbw, sizeof(sc->cbw)); - - usbd_xfer_set_frame_len(xfer, 0, sizeof(sc->cbw)); - usbd_transfer_submit(xfer); - } - return; - - default: /* Error */ - atausb2_tr_error(xfer, error); - return; - - } -} - -static void -atausb2_t_bbb_data_read_callback(struct usb_xfer *xfer, usb_error_t error) -{ - struct atausb2_softc *sc = usbd_xfer_softc(xfer); - uint32_t max_bulk = usbd_xfer_max_len(xfer); - struct usb_page_cache *pc; - int actlen, sumlen; - - usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); - - switch (USB_GET_STATE(xfer)) { - case USB_ST_TRANSFERRED: - - pc = usbd_xfer_get_frame(xfer, 0); - usbd_copy_out(pc, 0, sc->ata_data, actlen); - - sc->ata_bytecount -= actlen; - sc->ata_data += actlen; - sc->ata_donecount += actlen; - - if (actlen < sumlen) { - /* short transfer */ - sc->ata_bytecount = 0; - } - case USB_ST_SETUP: - - if (atausbdebug > 1) { - device_printf(sc->dev, "%s: max_bulk=%d, ata_bytecount=%d\n", - __FUNCTION__, max_bulk, sc->ata_bytecount); - } - if (sc->ata_bytecount == 0) { - atausb2_transfer_start(sc, ATAUSB_T_BBB_STATUS); - return; - } - if (max_bulk > sc->ata_bytecount) { - max_bulk = sc->ata_bytecount; - } - usbd_xfer_set_timeout(xfer, sc->timeout); - usbd_xfer_set_frame_len(xfer, 0, max_bulk); - - usbd_transfer_submit(xfer); - return; - - default: /* Error */ - if (error == USB_ERR_CANCELLED) { - atausb2_tr_error(xfer, error); - } else { - atausb2_transfer_start(sc, ATAUSB_T_BBB_DATA_RD_CS); - } - return; - - } -} - -static void -atausb2_t_bbb_data_rd_cs_callback(struct usb_xfer *xfer, usb_error_t error) -{ - atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_STATUS, - ATAUSB_T_BBB_DATA_READ, error); -} - -static void -atausb2_t_bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error) -{ - struct atausb2_softc *sc = usbd_xfer_softc(xfer); - struct usb_page_cache *pc; - uint32_t max_bulk = usbd_xfer_max_len(xfer); - int actlen; - - usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); - - switch (USB_GET_STATE(xfer)) { - case USB_ST_TRANSFERRED: - - sc->ata_bytecount -= actlen; - sc->ata_data += actlen; - sc->ata_donecount += actlen; - - case USB_ST_SETUP: - - if (atausbdebug > 1) { - device_printf(sc->dev, "%s: max_bulk=%d, ata_bytecount=%d\n", - __FUNCTION__, max_bulk, sc->ata_bytecount); - } - if (sc->ata_bytecount == 0) { - atausb2_transfer_start(sc, ATAUSB_T_BBB_STATUS); - return; - } - if (max_bulk > sc->ata_bytecount) { - max_bulk = sc->ata_bytecount; - } - - pc = usbd_xfer_get_frame(xfer, 0); - usbd_copy_in(pc, 0, sc->ata_data, max_bulk); - usbd_xfer_set_frame_len(xfer, 0, max_bulk); - usbd_xfer_set_timeout(xfer, sc->timeout); - - usbd_transfer_submit(xfer); - return; - - default: /* Error */ - if (error == USB_ERR_CANCELLED) { - atausb2_tr_error(xfer, error); - } else { - atausb2_transfer_start(sc, ATAUSB_T_BBB_DATA_WR_CS); - } - return; - - } -} - -static void -atausb2_t_bbb_data_wr_cs_callback(struct usb_xfer *xfer, usb_error_t error) -{ - atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_STATUS, - ATAUSB_T_BBB_DATA_WRITE, error); -} - -static void -atausb2_t_bbb_status_callback(struct usb_xfer *xfer, usb_error_t error) -{ - struct atausb2_softc *sc = usbd_xfer_softc(xfer); - struct ata_request *request = sc->ata_request; - struct usb_page_cache *pc; - uint32_t residue; - int actlen; - - usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); - - switch (USB_GET_STATE(xfer)) { - case USB_ST_TRANSFERRED: - - if (actlen < sizeof(sc->csw)) { - bzero(&sc->csw, sizeof(sc->csw)); - } - pc = usbd_xfer_get_frame(xfer, 0); - usbd_copy_out(pc, 0, &sc->csw, actlen); - - if (request->flags & (ATA_R_READ | ATA_R_WRITE)) { - request->donecount = sc->ata_donecount; - } - residue = UGETDW(sc->csw.residue); - - if (!residue) { - residue = (request->bytecount - request->donecount); - } - if (residue > request->bytecount) { - if (atausbdebug) { - device_printf(sc->dev, "truncating residue from %d " - "to %d bytes\n", residue, - request->bytecount); - } - residue = request->bytecount; - } - /* check CSW and handle eventual error */ - if (UGETDW(sc->csw.signature) != CSWSIGNATURE) { - if (atausbdebug) { - device_printf(sc->dev, "bad CSW signature 0x%08x != 0x%08x\n", - UGETDW(sc->csw.signature), CSWSIGNATURE); - } - goto tr_error; - } else if (UGETDW(sc->csw.tag) != UGETDW(sc->cbw.tag)) { - if (atausbdebug) { - device_printf(sc->dev, "bad CSW tag %d != %d\n", - UGETDW(sc->csw.tag), UGETDW(sc->cbw.tag)); - } - goto tr_error; - } else if (sc->csw.status > CSWSTATUS_PHASE) { - if (atausbdebug) { - device_printf(sc->dev, "bad CSW status %d > %d\n", - sc->csw.status, CSWSTATUS_PHASE); - } - goto tr_error; - } else if (sc->csw.status == CSWSTATUS_PHASE) { - if (atausbdebug) { - device_printf(sc->dev, "phase error residue = %d\n", residue); - } - goto tr_error; - } else if (request->donecount > request->bytecount) { - if (atausbdebug) { - device_printf(sc->dev, "buffer overrun %d > %d\n", - request->donecount, request->bytecount); - } - goto tr_error; - } else if (sc->csw.status == CSWSTATUS_FAILED) { - if (atausbdebug) { - device_printf(sc->dev, "CSWSTATUS_FAILED\n"); - } - request->error = ATA_E_ATAPI_SENSE_MASK; - } - sc->last_xfer_no = ATAUSB_T_BBB_COMMAND; - - sc->ata_request = NULL; - - /* drop the USB transfer lock while doing the ATA interrupt */ - mtx_unlock(&sc->locked_mtx); - - ata_interrupt(device_get_softc(request->parent)); - - mtx_lock(&sc->locked_mtx); - return; - - case USB_ST_SETUP: - usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); - usbd_transfer_submit(xfer); - return; - - default: -tr_error: - if (error == USB_ERR_CANCELLED || sc->status_try) { - atausb2_tr_error(xfer, error); - } else { - sc->status_try = 1; - atausb2_transfer_start(sc, ATAUSB_T_BBB_DATA_RD_CS); - } - return; - - } -} - -static void -atausb2_cancel_request(struct atausb2_softc *sc) -{ - struct ata_request *request; - - mtx_assert(&sc->locked_mtx, MA_OWNED); - - request = sc->ata_request; - sc->ata_request = NULL; - sc->last_xfer_no = ATAUSB_T_BBB_RESET1; - - if (request) { - request->error = ATA_E_ATAPI_SENSE_MASK; - - mtx_unlock(&sc->locked_mtx); - - ata_interrupt(device_get_softc(request->parent)); - - mtx_lock(&sc->locked_mtx); - } -} - -static void -atausb2_tr_error(struct usb_xfer *xfer, usb_error_t error) -{ - struct atausb2_softc *sc = usbd_xfer_softc(xfer); - - if (error != USB_ERR_CANCELLED) { - - if (atausbdebug) { - device_printf(sc->dev, "transfer failed, %s, in state %d " - "-> BULK reset\n", usbd_errstr(error), - sc->last_xfer_no); - } - } - atausb2_cancel_request(sc); -} - -/* - * ATA backend part - */ -struct atapi_inquiry { - uint8_t device_type; - uint8_t device_modifier; - uint8_t version; - uint8_t response_format; - uint8_t length; - uint8_t reserved[2]; - uint8_t flags; - uint8_t vendor[8]; - uint8_t product[16]; - uint8_t revision[4]; - /* uint8_t crap[60]; */ -} __packed; - -static int -ata_usbchannel_begin_transaction(struct ata_request *request) -{ - struct atausb2_softc *sc = - device_get_softc(device_get_parent(request->parent)); - int error; - - if (atausbdebug > 1) { - device_printf(request->dev, "begin_transaction %s\n", - ata_cmd2str(request)); - } - mtx_lock(&sc->locked_mtx); - - /* sanity, just in case */ - if (sc->ata_request) { - device_printf(request->dev, "begin is busy, " - "state = %d\n", sc->last_xfer_no); - request->result = EBUSY; - error = ATA_OP_FINISHED; - goto done; - } - /* - * XXX SOS convert the request into the format used, only BBB for - * now - */ - - /* ATA/ATAPI IDENTIFY needs special treatment */ - if (!(request->flags & ATA_R_ATAPI)) { - if (request->u.ata.command != ATA_ATAPI_IDENTIFY) { - device_printf(request->dev, "%s unsupported\n", - ata_cmd2str(request)); - request->result = EIO; - error = ATA_OP_FINISHED; - goto done; - } - request->flags |= ATA_R_ATAPI; - bzero(request->u.atapi.ccb, 16); - request->u.atapi.ccb[0] = ATAPI_INQUIRY; - request->u.atapi.ccb[4] = 255; /* sizeof(struct - * atapi_inquiry); */ - request->data += 256; /* arbitrary offset into ata_param */ - request->bytecount = 255; /* sizeof(struct - * atapi_inquiry); */ - } - if (sc->xfer[sc->last_xfer_no]) { - - sc->ata_request = request; - sc->ata_bytecount = request->bytecount; - sc->ata_data = request->data; - sc->ata_donecount = 0; - - usbd_transfer_start(sc->xfer[sc->last_xfer_no]); - error = ATA_OP_CONTINUES; - } else { - request->result = EIO; - error = ATA_OP_FINISHED; - } - -done: - mtx_unlock(&sc->locked_mtx); - return (error); -} - -static int -ata_usbchannel_end_transaction(struct ata_request *request) -{ - if (atausbdebug > 1) { - device_printf(request->dev, "end_transaction %s\n", - ata_cmd2str(request)); - } - /* - * XXX SOS convert the request from the format used, only BBB for - * now - */ - - /* ATA/ATAPI IDENTIFY needs special treatment */ - if ((request->flags & ATA_R_ATAPI) && - (request->u.atapi.ccb[0] == ATAPI_INQUIRY)) { - struct ata_device *atadev = device_get_softc(request->dev); - struct atapi_inquiry *inquiry = (struct atapi_inquiry *)request->data; - uint16_t *ptr; - - /* convert inquiry data into simple ata_param like format */ - atadev->param.config = ATA_PROTO_ATAPI | ATA_PROTO_ATAPI_12; - atadev->param.config |= (inquiry->device_type & 0x1f) << 8; - bzero(atadev->param.model, sizeof(atadev->param.model)); - strncpy(atadev->param.model, inquiry->vendor, 8); - strcpy(atadev->param.model, " "); - strncpy(atadev->param.model, inquiry->product, 16); - ptr = (uint16_t *)(atadev->param.model + sizeof(atadev->param.model)); - while (--ptr >= (uint16_t *)atadev->param.model) { - *ptr = ntohs(*ptr); - } - strncpy(atadev->param.revision, inquiry->revision, 4); - ptr = (uint16_t *)(atadev->param.revision + sizeof(atadev->param.revision)); - while (--ptr >= (uint16_t *)atadev->param.revision) { - *ptr = ntohs(*ptr); - } - request->result = 0; - } - return (ATA_OP_FINISHED); -} - -static int -ata_usbchannel_probe(device_t dev) -{ - char buffer[32]; - - snprintf(buffer, sizeof(buffer), "USB lun %d", - (int)(intptr_t)device_get_ivars(dev)); - device_set_desc_copy(dev, buffer); - - return (0); -} - -static int -ata_usbchannel_attach(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - - if (ch->attached) - return (0); - ch->attached = 1; - - /* initialize the softc basics */ - ch->dev = dev; - ch->unit = (intptr_t)device_get_ivars(dev); - ch->state = ATA_IDLE; - ch->hw.begin_transaction = ata_usbchannel_begin_transaction; - ch->hw.end_transaction = ata_usbchannel_end_transaction; - ch->hw.status = NULL; - ch->hw.command = NULL; - bzero(&ch->state_mtx, sizeof(struct mtx)); - mtx_init(&ch->state_mtx, "ATA state lock", NULL, MTX_DEF); - bzero(&ch->queue_mtx, sizeof(struct mtx)); - mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF); - TAILQ_INIT(&ch->ata_queue); - - /* XXX SOS reset the controller HW, the channel and device(s) */ - /* ATA_RESET(dev); */ - - /* probe and attach device on this channel */ - ch->devices = ATA_ATAPI_MASTER; - if (!ata_delayed_attach) { - ata_identify(dev); - } - return (0); -} - -static int -ata_usbchannel_detach(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - device_t *children; - int nchildren, i; - - if (!ch->attached) - return (0); - ch->attached = 0; - - /* detach & delete all children */ - if (!device_get_children(dev, &children, &nchildren)) { - for (i = 0; i < nchildren; i++) - if (children[i]) - device_delete_child(dev, children[i]); - free(children, M_TEMP); - } - mtx_destroy(&ch->state_mtx); - mtx_destroy(&ch->queue_mtx); - return (0); -} - -static void -ata_usbchannel_setmode(device_t parent, device_t dev) -{ - struct atausb2_softc *sc = device_get_softc(GRANDPARENT(dev)); - struct ata_device *atadev = device_get_softc(dev); - - if (sc->usb2_speed == USB_SPEED_HIGH) - atadev->mode = ATA_USB2; - else - atadev->mode = ATA_USB1; -} - -static int -ata_usbchannel_locking(device_t dev, int flags) -{ - struct atausb2_softc *sc = device_get_softc(device_get_parent(dev)); - struct ata_channel *ch = device_get_softc(dev); - int res = -1; - - mtx_lock(&sc->locked_mtx); - switch (flags) { - case ATA_LF_LOCK: - if (sc->locked_ch == NULL) - sc->locked_ch = ch; - if (sc->locked_ch != ch) - sc->restart_ch = ch; - break; - - case ATA_LF_UNLOCK: - if (sc->locked_ch == ch) { - sc->locked_ch = NULL; - if (sc->restart_ch) { - ch = sc->restart_ch; - sc->restart_ch = NULL; - mtx_unlock(&sc->locked_mtx); - ata_start(ch->dev); - return (res); - } - } - break; - - case ATA_LF_WHICH: - break; - } - if (sc->locked_ch) { - res = sc->locked_ch->unit; - } - mtx_unlock(&sc->locked_mtx); - return (res); -} - -static device_method_t ata_usbchannel_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, ata_usbchannel_probe), - DEVMETHOD(device_attach, ata_usbchannel_attach), - DEVMETHOD(device_detach, ata_usbchannel_detach), - - /* ATA methods */ - DEVMETHOD(ata_setmode, ata_usbchannel_setmode), - DEVMETHOD(ata_locking, ata_usbchannel_locking), - /* DEVMETHOD(ata_reset, ata_usbchannel_reset), */ - - {0, 0} -}; - -static driver_t ata_usbchannel_driver = { - "ata", - ata_usbchannel_methods, - sizeof(struct ata_channel), -}; - -DRIVER_MODULE(ata, atausb, ata_usbchannel_driver, ata_devclass, 0, 0); -MODULE_DEPEND(atausb, ata, 1, 1, 1); diff --git a/sys/modules/ata/atausb/Makefile b/sys/modules/ata/atausb/Makefile deleted file mode 100644 index 714adfee5d4..00000000000 --- a/sys/modules/ata/atausb/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../../dev/ata - -KMOD= atausb -SRCS= ata-usb.c -SRCS+= opt_bus.h opt_usb.h opt_ata.h usbdevs.h -SRCS+= ata_if.h device_if.h bus_if.h pci_if.h usb_if.h - -.include diff --git a/sys/sys/ata.h b/sys/sys/ata.h index e6dd2fe22ad..84d23b9c1b6 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -278,9 +278,6 @@ struct ata_params { #define ATA_SA150 0x47 #define ATA_SA300 0x48 #define ATA_DMA_MAX 0x4f -#define ATA_USB 0x80 -#define ATA_USB1 0x81 -#define ATA_USB2 0x82 /* ATA commands */ From ab4ca9d195d37043f9f22ff1262595d8b2beb9b1 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 2 Dec 2009 12:26:26 +0000 Subject: [PATCH 0722/2592] MFC r199644: Add some missing WDMA/UDMA modes. --- sbin/atacontrol/atacontrol.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sbin/atacontrol/atacontrol.c b/sbin/atacontrol/atacontrol.c index 5b5b85ac482..49e4fa231ae 100644 --- a/sbin/atacontrol/atacontrol.c +++ b/sbin/atacontrol/atacontrol.c @@ -49,8 +49,13 @@ mode2str(int mode) case ATA_PIO2: return "PIO2"; case ATA_PIO3: return "PIO3"; case ATA_PIO4: return "PIO4"; + case ATA_WDMA0: return "WDMA0"; + case ATA_WDMA1: return "WDMA1"; case ATA_WDMA2: return "WDMA2"; + case ATA_UDMA0: return "UDMA0"; + case ATA_UDMA1: return "UDMA1"; case ATA_UDMA2: return "UDMA33"; + case ATA_UDMA3: return "UDMA44"; case ATA_UDMA4: return "UDMA66"; case ATA_UDMA5: return "UDMA100"; case ATA_UDMA6: return "UDMA133"; @@ -70,9 +75,15 @@ str2mode(char *str) if (!strcasecmp(str, "PIO2")) return ATA_PIO2; if (!strcasecmp(str, "PIO3")) return ATA_PIO3; if (!strcasecmp(str, "PIO4")) return ATA_PIO4; + if (!strcasecmp(str, "WDMA0")) return ATA_WDMA0; + if (!strcasecmp(str, "WDMA1")) return ATA_WDMA1; if (!strcasecmp(str, "WDMA2")) return ATA_WDMA2; + if (!strcasecmp(str, "UDMA0")) return ATA_UDMA0; + if (!strcasecmp(str, "UDMA1")) return ATA_UDMA1; if (!strcasecmp(str, "UDMA2")) return ATA_UDMA2; if (!strcasecmp(str, "UDMA33")) return ATA_UDMA2; + if (!strcasecmp(str, "UDMA3")) return ATA_UDMA3; + if (!strcasecmp(str, "UDMA44")) return ATA_UDMA3; if (!strcasecmp(str, "UDMA4")) return ATA_UDMA4; if (!strcasecmp(str, "UDMA66")) return ATA_UDMA4; if (!strcasecmp(str, "UDMA5")) return ATA_UDMA5; From cb0593b42cc87229f898698b984e9388a6a30ea8 Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Wed, 2 Dec 2009 15:30:53 +0000 Subject: [PATCH 0723/2592] MFC 199813, 199817, 199842, 199867: Update unifdef to latest upstream version. --- usr.bin/unifdef/unifdef.1 | 123 +++++++++++----- usr.bin/unifdef/unifdef.c | 257 +++++++++++++++++++++++----------- usr.bin/unifdef/unifdefall.sh | 72 +++++++--- 3 files changed, 315 insertions(+), 137 deletions(-) diff --git a/usr.bin/unifdef/unifdef.1 b/usr.bin/unifdef/unifdef.1 index 12a5438553f..80ee7ba12a7 100644 --- a/usr.bin/unifdef/unifdef.1 +++ b/usr.bin/unifdef/unifdef.1 @@ -1,6 +1,6 @@ .\" Copyright (c) 1985, 1991, 1993 .\" The Regents of the University of California. All rights reserved. -.\" Copyright (c) 2002 - 2005 Tony Finch . All rights reserved. +.\" Copyright (c) 2002 - 2009 Tony Finch . All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Dave Yost. It was rewritten to support ANSI C by Tony Finch. @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)unifdef.1 8.2 (Berkeley) 4/1/94 -.\" $dotat: things/unifdef.1,v 1.51 2005/03/08 12:39:01 fanf2 Exp $ +.\" $dotat: unifdef/unifdef.1,v 1.60 2009/11/25 00:11:02 fanf2 Exp $ .\" $FreeBSD$ .\" .Dd September 24, 2002 @@ -41,7 +41,7 @@ .Nd remove preprocessor conditionals from code .Sh SYNOPSIS .Nm -.Op Fl cdeklnst +.Op Fl BbcdeKknst .Op Fl I Ns Ar path .Op Fl D Ns Ar sym Ns Op = Ns Ar val .Op Fl U Ns Ar sym @@ -70,46 +70,85 @@ utility acts on .Ic #if , #ifdef , #ifndef , #elif , #else , and .Ic #endif -lines, -and it understands only the commonly-used subset +lines. +A directive is only processed +if the symbols specified on the command line are sufficient to allow +.Nm +to get a definite value for its control expression. +If the result is false, +the directive and the following lines under its control are removed. +If the result is true, +only the directive is removed. +An +.Ic #ifdef +or +.Ic #ifndef +directive is passed through unchanged +if its controlling symbol is not specified on the command line. +Any +.Ic #if +or +.Ic #elif +control expression that has an unknown value or that +.Nm +cannot parse is passed through unchanged. +By default, +.Nm +ignores +.Ic #if +and +.Ic #elif +lines with constant expressions; +it can be told to process them by specifying the +.Fl k +flag on the command line. +.Pp +It understands a commonly-used subset of the expression syntax for .Ic #if and .Ic #elif -lines. -It handles +lines: +integer constants, integer values of symbols defined on the command line, the .Fn defined -operator applied to symbols defined or undefined on the command line, +operator, the operators .Ic \&! , < , > , <= , >= , == , != , && , || , and parenthesized expressions. -Anything that it does not understand is passed through unharmed. -It only processes -.Ic #ifdef -and -.Ic #ifndef -directives if the symbol is specified on the command line, -otherwise they are also passed through unchanged. -By default, it ignores -.Ic #if -and -.Ic #elif -lines with constant expressions, -or they may be processed by specifying the -.Fl k -flag on the command line. +A kind of +.Dq "short circuit" +evaluation is used for the +.Ic && +operator: +if either operand is definitely false then the result is false, +even if the value of the other operand is unknown. +Similarly, +if either operand of +.Ic || +is definitely true then the result is true. +.Pp +In most cases, the +.Nm +utility does not distinguish between object-like macros +(without arguments) and function-like arguments (with arguments). +If a macro is not explicitly defined, or is defined with the +.Fl D +flag on the command-line, its arguments are ignored. +If a macro is explicitly undefined on the command line with the +.Fl U +flag, it may not have any arguments since this leads to a syntax error. .Pp The .Nm -utility also understands just enough about C +utility understands just enough about C to know when one of the directives is inactive because it is inside a comment, or affected by a backslash-continued line. It spots unusually-formatted preprocessor directives -and knows when the layout is too odd to handle. +and knows when the layout is too odd for it to handle. .Pp A script called .Nm unifdefall @@ -125,8 +164,7 @@ and their definitions (or lack thereof), then invokes .Nm with appropriate arguments to process the file. -.Pp -Available options: +.Sh OPTIONS .Pp .Bl -tag -width indent -compact .It Fl D Ns Ar sym Ns Op = Ns Ar val @@ -143,6 +181,19 @@ Specify that a symbol is undefined. If the same symbol appears in more than one argument, the last occurrence dominates. .Pp +.It Fl B +Compress blank lines around a deleted section. +Mutually exclusive with the +.Fl b +option. +.Pp +.It Fl b +Replace removed lines with blank lines +instead of deleting them. +Mutually exclusive with the +.Fl B +option. +.Pp .It Fl c If the .Fl c @@ -174,6 +225,16 @@ option changes the behaviour so that, where possible, such lines are left unprocessed instead of reporting an error. .Pp +.It Fl K +Always treat the result of +.Ic && +and +.Ic || +operators as unknown if either operand is unknown, +instead of short-circuiting when unknown operands can't affect the result. +This option is for compatibility with older versions of +.Nm . +.Pp .It Fl k Process .Ic #if @@ -186,10 +247,6 @@ because they typically start and are used as a kind of comment to sketch out future or past development. It would be rude to strip them out, just as it would be for normal comments. .Pp -.It Fl l -Replace removed lines with blank lines -instead of deleting them. -.Pp .It Fl n Add .Li #line @@ -235,7 +292,7 @@ comments and line continuations inside those .Ic #ifdef Ns s . -One specifies ignored symbols with +You can specify ignored symbols with .Fl iD Ns Ar sym Ns Oo = Ns Ar val Oc and .Fl iU Ns Ar sym @@ -313,7 +370,7 @@ command appeared in support was added in .Fx 4.7 . .Sh AUTHORS -This implementation was originally written by +The original implementation was written by .An Dave Yost Aq Dave@Yost.com . .An Tony Finch Aq dot@dotat.at rewrote it to support diff --git a/usr.bin/unifdef/unifdef.c b/usr.bin/unifdef/unifdef.c index a8427d150a8..be5b4fc6573 100644 --- a/usr.bin/unifdef/unifdef.c +++ b/usr.bin/unifdef/unifdef.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 - 2008 Tony Finch + * Copyright (c) 2002 - 2009 Tony Finch * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,27 +24,20 @@ */ /* - * This code is derived from software contributed to Berkeley by Dave Yost. + * This code was derived from software contributed to Berkeley by Dave Yost. * It was rewritten to support ANSI C by Tony Finch. The original version * of unifdef carried the 4-clause BSD copyright licence. None of its code * remains in this version (though some of the names remain) so it now * carries a more liberal licence. + * + * The latest version is available from http://dotat.at/prog/unifdef */ #include -#ifndef lint -#if 0 -static const char copyright[] = -"@(#) Copyright (c) 1985, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif #ifdef __IDSTRING -__IDSTRING(Berkeley, "@(#)unifdef.c 8.1 (Berkeley) 6/6/93"); -__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $"); -__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.178 2008/03/02 22:23:32 fanf2 Exp $"); +__IDSTRING(dotat, "$dotat: unifdef/unifdef.c,v 1.190 2009/11/27 17:21:26 fanf2 Exp $"); #endif -#endif /* not lint */ #ifdef __FBSDID __FBSDID("$FreeBSD$"); #endif @@ -88,6 +81,7 @@ typedef enum { LT_DODGY_LAST = LT_DODGY + LT_ENDIF, LT_PLAIN, /* ordinary line */ LT_EOF, /* end of file */ + LT_ERROR, /* unevaluable #if */ LT_COUNT } Linetype; @@ -98,7 +92,7 @@ static char const * const linetype_name[] = { "DODGY IF", "DODGY TRUE", "DODGY FALSE", "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE", "DODGY ELSE", "DODGY ENDIF", - "PLAIN", "EOF" + "PLAIN", "EOF", "ERROR" }; /* state of #if processing */ @@ -166,11 +160,13 @@ static char const * const linestate_name[] = { * Globals. */ +static bool compblank; /* -B: compress blank lines */ +static bool lnblank; /* -b: blank deleted lines */ static bool complement; /* -c: do the complement */ static bool debugging; /* -d: debugging reports */ static bool iocccok; /* -e: fewer IOCCC errors */ +static bool strictlogic; /* -K: keep ambiguous #ifs */ static bool killconsts; /* -k: eval constant #ifs */ -static bool lnblank; /* -l: blank deleted lines */ static bool lnnum; /* -n: add #line directives */ static bool symlist; /* -s: output symbol list */ static bool text; /* -t: this is a text file */ @@ -194,7 +190,9 @@ static bool ignoring[MAXDEPTH]; /* ignore comments state */ static int stifline[MAXDEPTH]; /* start of current #if */ static int depth; /* current #if nesting */ static int delcount; /* count of deleted lines */ -static bool keepthis; /* don't delete constant #if */ +static unsigned blankcount; /* count of blank lines */ +static unsigned blankmax; /* maximum recent blankcount */ +static bool constexpr; /* constant #if expression */ static int exitstat; /* program exit status */ @@ -204,13 +202,14 @@ static void done(void); static void error(const char *); static int findsym(const char *); static void flushline(bool); -static Linetype getline(void); +static Linetype parseline(void); static Linetype ifeval(const char **); static void ignoreoff(void); static void ignoreon(void); static void keywordedit(const char *); static void nest(void); static void process(void); +static const char *skipargs(const char *); static const char *skipcomment(const char *); static const char *skipsym(const char *); static void state(Ifstate); @@ -218,7 +217,7 @@ static int strlcmp(const char *, const char *, size_t); static void unnest(void); static void usage(void); -#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_') +#define endsym(c) (!isalnum((unsigned char)c) && c != '_') /* * The main program. @@ -228,7 +227,7 @@ main(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1) + while ((opt = getopt(argc, argv, "i:D:U:I:BbcdeKklnst")) != -1) switch (opt) { case 'i': /* treat stuff controlled by these symbols as text */ /* @@ -253,6 +252,13 @@ main(int argc, char *argv[]) case 'I': /* no-op for compatibility with cpp */ break; + case 'B': /* compress blank lines around removed section */ + compblank = true; + break; + case 'b': /* blank deleted lines instead of omitting them */ + case 'l': /* backwards compatibility */ + lnblank = true; + break; case 'c': /* treat -D as -U and vice versa */ complement = true; break; @@ -262,12 +268,12 @@ main(int argc, char *argv[]) case 'e': /* fewer errors from dodgy lines */ iocccok = true; break; + case 'K': /* keep ambiguous #ifs */ + strictlogic = true; + break; case 'k': /* process constant #ifs */ killconsts = true; break; - case 'l': /* blank deleted lines instead of omitting them */ - lnblank = true; - break; case 'n': /* add #line directive after deleted lines */ lnnum = true; break; @@ -282,6 +288,8 @@ main(int argc, char *argv[]) } argc -= optind; argv += optind; + if (compblank && lnblank) + errx(2, "-B and -b are mutually exclusive"); if (argc > 1) { errx(2, "can only do one file"); } else if (argc == 1 && strcmp(*argv, "-") != 0) { @@ -300,7 +308,7 @@ main(int argc, char *argv[]) static void usage(void) { - fprintf(stderr, "usage: unifdef [-cdeklnst] [-Ipath]" + fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]" " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n"); exit(2); } @@ -381,46 +389,46 @@ static state_fn * const trans_table[IS_COUNT][LT_COUNT] = { /* IS_OUTSIDE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif, - print, done }, + print, done, abort }, /* IS_FALSE_PREFIX */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc, - drop, Eeof }, + drop, Eeof, abort }, /* IS_TRUE_PREFIX */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, - print, Eeof }, + print, Eeof, abort }, /* IS_PASS_MIDDLE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif, - print, Eeof }, + print, Eeof, abort }, /* IS_FALSE_MIDDLE */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, - drop, Eeof }, + drop, Eeof, abort }, /* IS_TRUE_MIDDLE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif, - print, Eeof }, + print, Eeof, abort }, /* IS_PASS_ELSE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif, - print, Eeof }, + print, Eeof, abort }, /* IS_FALSE_ELSE */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc, - drop, Eeof }, + drop, Eeof, abort }, /* IS_TRUE_ELSE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc, - print, Eeof }, + print, Eeof, abort }, /* IS_FALSE_TRAILER */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc, - drop, Eeof } + drop, Eeof, abort } /*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY) - PLAIN EOF */ + PLAIN EOF ERROR */ }; /* @@ -454,9 +462,11 @@ keywordedit(const char *replacement) static void nest(void) { - depth += 1; - if (depth >= MAXDEPTH) + if (depth > MAXDEPTH-1) + abort(); /* bug */ + if (depth == MAXDEPTH-1) error("Too many levels of nesting"); + depth += 1; stifline[depth] = linenum; } static void @@ -481,15 +491,23 @@ flushline(bool keep) if (symlist) return; if (keep ^ complement) { - if (lnnum && delcount > 0) - printf("#line %d\n", linenum); - fputs(tline, stdout); - delcount = 0; + bool blankline = tline[strspn(tline, " \t\n")] == '\0'; + if (blankline && compblank && blankcount != blankmax) { + delcount += 1; + blankcount += 1; + } else { + if (lnnum && delcount > 0) + printf("#line %d\n", linenum); + fputs(tline, stdout); + delcount = 0; + blankmax = blankcount = blankline ? blankcount + 1 : 0; + } } else { if (lnblank) putc('\n', stdout); exitstat = 1; delcount += 1; + blankcount = 0; } } @@ -501,9 +519,12 @@ process(void) { Linetype lineval; + /* When compressing blank lines, act as if the file + is preceded by a large number of blank lines. */ + blankmax = blankcount = 1000; for (;;) { linenum++; - lineval = getline(); + lineval = parseline(); trans_table[ifstate[depth]][lineval](); debug("process %s -> %s depth %d", linetype_name[lineval], @@ -517,7 +538,7 @@ process(void) * help from skipcomment(). */ static Linetype -getline(void) +parseline(void) { const char *cp; int cursym; @@ -613,17 +634,40 @@ getline(void) /* * These are the binary operators that are supported by the expression - * evaluator. Note that if support for division is added then we also - * need short-circuiting booleans because of divide-by-zero. + * evaluator. */ -static int op_lt(int a, int b) { return (a < b); } -static int op_gt(int a, int b) { return (a > b); } -static int op_le(int a, int b) { return (a <= b); } -static int op_ge(int a, int b) { return (a >= b); } -static int op_eq(int a, int b) { return (a == b); } -static int op_ne(int a, int b) { return (a != b); } -static int op_or(int a, int b) { return (a || b); } -static int op_and(int a, int b) { return (a && b); } +static Linetype op_strict(int *p, int v, Linetype at, Linetype bt) { + if(at == LT_IF || bt == LT_IF) return (LT_IF); + return (*p = v, v ? LT_TRUE : LT_FALSE); +} +static Linetype op_lt(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a < b, at, bt); +} +static Linetype op_gt(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a > b, at, bt); +} +static Linetype op_le(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a <= b, at, bt); +} +static Linetype op_ge(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a >= b, at, bt); +} +static Linetype op_eq(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a == b, at, bt); +} +static Linetype op_ne(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a != b, at, bt); +} +static Linetype op_or(int *p, Linetype at, int a, Linetype bt, int b) { + if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE)) + return (*p = 1, LT_TRUE); + return op_strict(p, a || b, at, bt); +} +static Linetype op_and(int *p, Linetype at, int a, Linetype bt, int b) { + if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE)) + return (*p = 0, LT_FALSE); + return op_strict(p, a && b, at, bt); +} /* * An evaluation function takes three arguments, as follows: (1) a pointer to @@ -632,8 +676,8 @@ static int op_and(int a, int b) { return (a && b); } * value of the expression; and (3) a pointer to a char* that points to the * expression to be evaluated and that is updated to the end of the expression * when evaluation is complete. The function returns LT_FALSE if the value of - * the expression is zero, LT_TRUE if it is non-zero, or LT_IF if the - * expression could not be evaluated. + * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression + * depends on an unknown symbol, or LT_ERROR if there is a parse failure. */ struct ops; @@ -652,7 +696,7 @@ static const struct ops { eval_fn *inner; struct op { const char *str; - int (*fn)(int, int); + Linetype (*fn)(int *, Linetype, int, Linetype, int); } op[5]; } eval_ops[] = { { eval_table, { { "||", op_or } } }, @@ -667,8 +711,8 @@ static const struct ops { /* * Function for evaluating the innermost parts of expressions, - * viz. !expr (expr) defined(symbol) symbol number - * We reset the keepthis flag when we find a non-constant subexpression. + * viz. !expr (expr) number defined(symbol) symbol + * We reset the constexpr flag in the last two cases. */ static Linetype eval_unary(const struct ops *ops, int *valp, const char **cpp) @@ -677,25 +721,34 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) char *ep; int sym; bool defparen; + Linetype lt; cp = skipcomment(*cpp); if (*cp == '!') { debug("eval%d !", ops - eval_ops); cp++; - if (eval_unary(ops, valp, &cp) == LT_IF) - return (LT_IF); - *valp = !*valp; + lt = eval_unary(ops, valp, &cp); + if (lt == LT_ERROR) + return (LT_ERROR); + if (lt != LT_IF) { + *valp = !*valp; + lt = *valp ? LT_TRUE : LT_FALSE; + } } else if (*cp == '(') { cp++; debug("eval%d (", ops - eval_ops); - if (eval_table(eval_ops, valp, &cp) == LT_IF) - return (LT_IF); + lt = eval_table(eval_ops, valp, &cp); + if (lt == LT_ERROR) + return (LT_ERROR); cp = skipcomment(cp); if (*cp++ != ')') - return (LT_IF); + return (LT_ERROR); } else if (isdigit((unsigned char)*cp)) { debug("eval%d number", ops - eval_ops); *valp = strtol(cp, &ep, 0); + if (ep == cp) + return (LT_ERROR); + lt = *valp ? LT_TRUE : LT_FALSE; cp = skipsym(cp); } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) { cp = skipcomment(cp+7); @@ -707,36 +760,43 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) defparen = false; } sym = findsym(cp); - if (sym < 0) - return (LT_IF); - *valp = (value[sym] != NULL); + if (sym < 0) { + lt = LT_IF; + } else { + *valp = (value[sym] != NULL); + lt = *valp ? LT_TRUE : LT_FALSE; + } cp = skipsym(cp); cp = skipcomment(cp); if (defparen && *cp++ != ')') - return (LT_IF); - keepthis = false; + return (LT_ERROR); + constexpr = false; } else if (!endsym(*cp)) { debug("eval%d symbol", ops - eval_ops); sym = findsym(cp); - if (sym < 0) - return (LT_IF); - if (value[sym] == NULL) + cp = skipsym(cp); + if (sym < 0) { + lt = LT_IF; + cp = skipargs(cp); + } else if (value[sym] == NULL) { *valp = 0; - else { + lt = LT_FALSE; + } else { *valp = strtol(value[sym], &ep, 0); if (*ep != '\0' || ep == value[sym]) - return (LT_IF); + return (LT_ERROR); + lt = *valp ? LT_TRUE : LT_FALSE; + cp = skipargs(cp); } - cp = skipsym(cp); - keepthis = false; + constexpr = false; } else { debug("eval%d bad expr", ops - eval_ops); - return (LT_IF); + return (LT_ERROR); } *cpp = cp; debug("eval%d = %d", ops - eval_ops, *valp); - return (*valp ? LT_TRUE : LT_FALSE); + return (lt); } /* @@ -748,11 +808,13 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) const struct op *op; const char *cp; int val; + Linetype lt, rt; debug("eval%d", ops - eval_ops); cp = *cpp; - if (ops->inner(ops+1, valp, &cp) == LT_IF) - return (LT_IF); + lt = ops->inner(ops+1, valp, &cp); + if (lt == LT_ERROR) + return (LT_ERROR); for (;;) { cp = skipcomment(cp); for (op = ops->op; op->str != NULL; op++) @@ -762,14 +824,16 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) break; cp += strlen(op->str); debug("eval%d %s", ops - eval_ops, op->str); - if (ops->inner(ops+1, &val, &cp) == LT_IF) - return (LT_IF); - *valp = op->fn(*valp, val); + rt = ops->inner(ops+1, &val, &cp); + if (rt == LT_ERROR) + return (LT_ERROR); + lt = op->fn(valp, lt, *valp, rt, val); } *cpp = cp; debug("eval%d = %d", ops - eval_ops, *valp); - return (*valp ? LT_TRUE : LT_FALSE); + debug("eval%d lt = %s", ops - eval_ops, linetype_name[lt]); + return (lt); } /* @@ -784,10 +848,10 @@ ifeval(const char **cpp) int val = 0; debug("eval %s", *cpp); - keepthis = killconsts ? false : true; + constexpr = killconsts ? false : true; ret = eval_table(eval_ops, &val, cpp); debug("eval = %d", val); - return (keepthis ? LT_IF : ret); + return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret); } /* @@ -898,6 +962,31 @@ skipcomment(const char *cp) return (cp); } +/* + * Skip macro arguments. + */ +static const char * +skipargs(const char *cp) +{ + const char *ocp = cp; + int level = 0; + cp = skipcomment(cp); + if (*cp != '(') + return (cp); + do { + if (*cp == '(') + level++; + if (*cp == ')') + level--; + cp = skipcomment(cp+1); + } while (level != 0 && *cp != '\0'); + if (level == 0) + return (cp); + else + /* Rewind and re-detect the syntax error later. */ + return (ocp); +} + /* * Skip over an identifier. */ diff --git a/usr.bin/unifdef/unifdefall.sh b/usr.bin/unifdef/unifdefall.sh index bcba08c9712..b443054d8ab 100644 --- a/usr.bin/unifdef/unifdefall.sh +++ b/usr.bin/unifdef/unifdefall.sh @@ -1,29 +1,61 @@ #!/bin/sh # -# remove all the #if's from a source file +# unifdefall: remove all the #if's from a source file # -# $dotat: things/unifdefall.sh,v 1.9 2002/09/24 19:43:57 fanf2 Exp $ +# Copyright (c) 2002 - 2009 Tony Finch . 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 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 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. +# +# $dotat: unifdef/unifdefall.sh,v 1.24 2009/11/26 12:54:39 fanf2 Exp $ # $FreeBSD$ set -e -basename=`basename $0` -tmp=`mktemp -d -t $basename` || exit 2 +basename=$(basename $0) +tmp=$(mktemp -d "${TMPDIR:-/tmp}/$basename.XXXXXXXXXX") || exit 2 +trap 'rm -r "$tmp" || exit 1' EXIT -unifdef -s "$@" | sort | uniq > $tmp/ctrl -cpp -dM "$@" | sort | - sed -Ee 's/^#define[ ]+(.*[^ ])[ ]*$/\1/' > $tmp/hashdefs -sed -Ee 's/^([A-Za-z0-9_]+).*$/\1/' $tmp/hashdefs > $tmp/alldef -comm -23 $tmp/ctrl $tmp/alldef > $tmp/undef -comm -12 $tmp/ctrl $tmp/alldef > $tmp/def +export LC_ALL=C -echo unifdef -k \\ > $tmp/cmd -sed -Ee 's/^(.*)$/-U\1 \\/' $tmp/undef >> $tmp/cmd -while read sym -do sed -Ee '/^('"$sym"')([(][^)]*[)])?([ ]+(.*))?$/!d;s//-D\1=\4/' $tmp/hashdefs -done < $tmp/def | - sed -Ee 's/\\/\\\\/g;s/"/\\"/g;s/^/"/;s/$/" \\/' >> $tmp/cmd -echo '"$@"' >> $tmp/cmd -sh $tmp/cmd "$@" - -rm -r $tmp +# list of all controlling macros +unifdef -s "$@" | sort | uniq >"$tmp/ctrl" +# list of all macro definitions +cpp -dM "$@" | sort | sed 's/^#define //' >"$tmp/hashdefs" +# list of defined macro names +sed 's/[^A-Za-z0-9_].*$//' <"$tmp/hashdefs" >"$tmp/alldef" +# list of undefined and defined controlling macros +comm -23 "$tmp/ctrl" "$tmp/alldef" >"$tmp/undef" +comm -12 "$tmp/ctrl" "$tmp/alldef" >"$tmp/def" +# create a sed script that extracts the controlling macro definitions +# and converts them to unifdef command-line arguments +sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script" +# create the final unifdef command +{ echo unifdef -k \\ + # convert the controlling undefined macros to -U arguments + sed 's/.*/-U& \\/' <"$tmp/undef" + # convert the controlling defined macros to quoted -D arguments + sed -nf "$tmp/script" <"$tmp/hashdefs" | + sed "s/'/'\\\\''/g;s/.*/'&' \\\\/" + echo '"$@"' +} >"$tmp/cmd" +# run the command we just created +sh "$tmp/cmd" "$@" From edc71a91ecb83ec991d70fab7c4c1707d94220d9 Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Wed, 2 Dec 2009 19:28:55 +0000 Subject: [PATCH 0724/2592] MFC 199815: Fix performance bugs in factor(6). --- games/factor/factor.c | 48 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/games/factor/factor.c b/games/factor/factor.c index e3aa90cb8be..1444d0be202 100644 --- a/games/factor/factor.c +++ b/games/factor/factor.c @@ -13,11 +13,7 @@ * 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 University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -35,18 +31,20 @@ */ #ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1989, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)factor.c 8.4 (Berkeley) 5/4/95"; -__RCSID("$NetBSD: factor.c,v 1.13 2002/06/18 23:07:36 simonb Exp $"); +#include +#ifdef __COPYRIGHT +__COPYRIGHT("@(#) Copyright (c) 1989, 1993\ + The Regents of the University of California. All rights reserved."); +#endif +#ifdef __SCCSID +__SCCSID("@(#)factor.c 8.4 (Berkeley) 5/4/95"); +#endif +#ifdef __RCSID +__RCSID("$NetBSD: factor.c,v 1.19 2009/08/12 05:54:31 dholland Exp $"); +#endif +#ifdef __FBSDID +__FBSDID("$FreeBSD$"); #endif -static const char rcsid[] = - "$FreeBSD$"; #endif /* not lint */ /* @@ -63,7 +61,7 @@ static const char rcsid[] = * * number: factor1 factor1 factor2 factor3 factor3 factor3 ... * - * where factor1 < factor2 < factor3 < ... + * where factor1 <= factor2 <= factor3 <= ... * * If no args are given, the list of numbers are read from stdin. */ @@ -214,7 +212,9 @@ pr_fact(BIGNUM *val) bnfact = BN_new(); BN_set_word(bnfact, *(fact - 1)); BN_sqr(bnfact, bnfact, ctx); - if (BN_cmp(bnfact, val) > 0) + if (BN_cmp(bnfact, val) > 0 || + BN_is_prime(val, PRIME_CHECKS, + NULL, NULL, NULL) == 1) pr_print(val); else pollard_pminus1(val); @@ -257,22 +257,28 @@ usage(void) #ifdef HAVE_OPENSSL -/* pollard rho, algorithm from Jim Gillogly, May 2000 */ +/* pollard p-1, algorithm from Jim Gillogly, May 2000 */ static void pollard_pminus1(BIGNUM *val) { - BIGNUM *base, *num, *i, *x; + BIGNUM *base, *rbase, *num, *i, *x; base = BN_new(); + rbase = BN_new(); num = BN_new(); i = BN_new(); x = BN_new(); + BN_set_word(rbase, 1); +newbase: + BN_add_word(rbase, 1); BN_set_word(i, 2); - BN_set_word(base, 2); + BN_copy(base, rbase); for (;;) { BN_mod_exp(base, base, i, val, ctx); + if (BN_is_one(base)) + goto newbase; BN_copy(x, base); BN_sub_word(x, 1); From 23ca7b86bd00eaf18e7331a80cea4bc32e02de0a Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 2 Dec 2009 21:58:00 +0000 Subject: [PATCH 0725/2592] MFC r199066 + 199339: Apply a NetBSD fix (revision 1.12) to handle multi-session bzip2 files as created by pbzip2. --- usr.bin/gzip/unbzip2.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/usr.bin/gzip/unbzip2.c b/usr.bin/gzip/unbzip2.c index e8990d7b984..c744e564ef1 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. @@ -36,7 +36,7 @@ static off_t unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) { - int ret, end_of_file; + int ret, end_of_file, cold = 0; off_t bytes_out = 0; bz_stream bzs; static char *inbuf, *outbuf; @@ -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; @@ -86,9 +86,19 @@ unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) switch (ret) { case BZ_STREAM_END: case BZ_OK: - if (ret == BZ_OK && end_of_file) - maybe_err("read"); - if (!tflag) { + if (ret == BZ_OK && end_of_file) { + /* + * If we hit this after a stream end, consider + * it as the end of the whole file and don't + * bail out. + */ + if (cold == 1) + ret = BZ_STREAM_END; + else + maybe_errx("truncated file"); + } + cold = 0; + if (!tflag && bzs.avail_out != BUFLEN) { ssize_t n; n = write(out, outbuf, BUFLEN - bzs.avail_out); @@ -96,7 +106,14 @@ 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"); + cold = 1; + ret = BZ_OK; + } + break; case BZ_DATA_ERROR: maybe_warnx("bzip2 data integrity error"); @@ -109,7 +126,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 0cd4e30efaac339c812f1cb2d3f6181f587ed455 Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Thu, 3 Dec 2009 09:18:40 +0000 Subject: [PATCH 0726/2592] Disable SSL renegotiation in order to protect against a serious protocol flaw. [09:15] Correctly handle failures from unsetenv resulting from a corrupt environment in rtld-elf. [09:16] Fix permissions in freebsd-update in order to prevent leakage of sensitive files. [09:17] Approved by: so (cperciva) Security: FreeBSD-SA-09:15.ssl Security: FreeBSD-SA-09:16.rtld Security: FreeBSD-SA-09:17.freebsd-udpate --- crypto/openssl/ssl/s3_lib.c | 3 +++ crypto/openssl/ssl/s3_pkt.c | 7 ++----- crypto/openssl/ssl/s3_srvr.c | 7 +++++++ etc/mtree/BSD.var.dist | 2 +- usr.sbin/freebsd-update/freebsd-update.sh | 1 + 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/crypto/openssl/ssl/s3_lib.c b/crypto/openssl/ssl/s3_lib.c index 8916a0b1b3c..1b38f72d086 100644 --- a/crypto/openssl/ssl/s3_lib.c +++ b/crypto/openssl/ssl/s3_lib.c @@ -2592,6 +2592,9 @@ int ssl3_renegotiate(SSL *s) if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) return(0); + if (1) + return(0); + s->s3->renegotiate=1; return(1); } diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c index 9476dcddf6e..1644f19d49c 100644 --- a/crypto/openssl/ssl/s3_pkt.c +++ b/crypto/openssl/ssl/s3_pkt.c @@ -983,9 +983,7 @@ start: if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->s3->handshake_fragment, 4, s, s->msg_callback_arg); - if (SSL_is_init_finished(s) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && - !s->s3->renegotiate) + if (0) { ssl3_renegotiate(s); if (ssl3_renegotiate_check(s)) @@ -1116,8 +1114,7 @@ start: /* Unexpected handshake message (Client Hello, or protocol violation) */ if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) { - if (((s->state&SSL_ST_MASK) == SSL_ST_OK) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) + if (0) { #if 0 /* worked only because C operator preferences are not as expected (and * because this is not really needed for clients except for detecting diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c index 80b45eb86ff..b2ba9ffeb03 100644 --- a/crypto/openssl/ssl/s3_srvr.c +++ b/crypto/openssl/ssl/s3_srvr.c @@ -718,6 +718,13 @@ int ssl3_get_client_hello(SSL *s) #endif STACK_OF(SSL_CIPHER) *ciphers=NULL; + if (s->new_session) + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto f_err; + } + /* We do this so that we will respond with our native type. * If we are TLSv1 and we get SSLv3, we will respond with TLSv1, * This down switching should be handled by a different method. diff --git a/etc/mtree/BSD.var.dist b/etc/mtree/BSD.var.dist index 29b48622199..f55fbbb23b7 100644 --- a/etc/mtree/BSD.var.dist +++ b/etc/mtree/BSD.var.dist @@ -32,7 +32,7 @@ db entropy uname=operator gname=operator mode=0700 .. - freebsd-update + freebsd-update mode=0700 .. ipf mode=0700 .. diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index 2eacca8d2fb..de0c1a5639f 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -600,6 +600,7 @@ fetch_check_params () { echo ${WORKDIR} exit 1 fi + chmod 700 ${WORKDIR} cd ${WORKDIR} || exit 1 # Generate release number. The s/SECURITY/RELEASE/ bit exists From 86032a4158b110caac4bf222fe8d3977b7c6fc13 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 3 Dec 2009 18:42:19 +0000 Subject: [PATCH 0727/2592] MFC r199564: Minimize interface reinitialization by checking IFF_DRV_RUNNING flag. This fixes unnecessary interface UP/DOWNs during getting an IP address via DHCP. --- sys/dev/re/if_re.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index 25d189b7982..ed2b4494dfe 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -753,6 +753,7 @@ re_diag(struct rl_softc *sc) ifp->if_flags |= IFF_PROMISC; sc->rl_testmode = 1; + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; re_init_locked(sc); sc->rl_flags |= RL_FLAG_LINK; if (sc->rl_type == RL_8169) @@ -2145,8 +2146,10 @@ re_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) * XXX check behaviour on receiver stalls. */ - if (status & RL_ISR_SYSTEM_ERR) + if (status & RL_ISR_SYSTEM_ERR) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; re_init_locked(sc); + } } return (rx_npkts); } @@ -2222,8 +2225,10 @@ re_int_task(void *arg, int npending) RL_ISR_TX_ERR|RL_ISR_TX_DESC_UNAVAIL)) re_txeof(sc); - if (status & RL_ISR_SYSTEM_ERR) + if (status & RL_ISR_SYSTEM_ERR) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; re_init_locked(sc); + } if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) taskqueue_enqueue_fast(taskqueue_fast, &sc->rl_txtask); @@ -2539,6 +2544,9 @@ re_init_locked(struct rl_softc *sc) mii = device_get_softc(sc->rl_miibus); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + return; + /* * Cancel pending I/O and free all RX/TX buffers. */ @@ -2793,7 +2801,8 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCADDMULTI: case SIOCDELMULTI: RL_LOCK(sc); - re_set_rxmode(sc); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + re_set_rxmode(sc); RL_UNLOCK(sc); break; case SIOCGIFMEDIA: @@ -2862,8 +2871,10 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if ((mask & IFCAP_WOL_MAGIC) != 0) ifp->if_capenable ^= IFCAP_WOL_MAGIC; } - if (reinit && ifp->if_drv_flags & IFF_DRV_RUNNING) + if (reinit && ifp->if_drv_flags & IFF_DRV_RUNNING) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; re_init(sc); + } VLAN_CAPABILITIES(ifp); } break; @@ -2899,6 +2910,7 @@ re_watchdog(struct rl_softc *sc) ifp->if_oerrors++; re_rxeof(sc, NULL); + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; re_init_locked(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) taskqueue_enqueue_fast(taskqueue_fast, &sc->rl_txtask); From 9b96de9413c2a9bb26c114d514a1b2f96af745c1 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 3 Dec 2009 18:48:32 +0000 Subject: [PATCH 0728/2592] MFC r199565: Move interface reinitialization down after disabling WOL in resume path. --- sys/dev/re/if_re.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index ed2b4494dfe..aeb9cf20d7e 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -3023,15 +3023,16 @@ re_resume(device_t dev) CSR_READ_1(sc, RL_GPIO) | 0x01); } - /* reinitialize interface if necessary */ - if (ifp->if_flags & IFF_UP) - re_init_locked(sc); - /* * Clear WOL matching such that normal Rx filtering * wouldn't interfere with WOL patterns. */ re_clrwol(sc); + + /* reinitialize interface if necessary */ + if (ifp->if_flags & IFF_UP) + re_init_locked(sc); + sc->suspended = 0; RL_UNLOCK(sc); From e043b4c399fbde3e380b7526777bdbcca218d9ce Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Fri, 4 Dec 2009 07:08:15 +0000 Subject: [PATCH 0729/2592] MFC: r199988 Add an .Nm for strncat. --- lib/libc/string/strcat.3 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/libc/string/strcat.3 b/lib/libc/string/strcat.3 index 029099418a7..4c9fec9acbe 100644 --- a/lib/libc/string/strcat.3 +++ b/lib/libc/string/strcat.3 @@ -32,11 +32,12 @@ .\" @(#)strcat.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd December 1, 2009 .Dt STRCAT 3 .Os .Sh NAME -.Nm strcat +.Nm strcat , +.Nm strncat .Nd concatenate strings .Sh LIBRARY .Lb libc From a95336167ee59274d8b0c7bc68bc5f7494c185ec Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Fri, 4 Dec 2009 11:23:37 +0000 Subject: [PATCH 0730/2592] MFC r199529: Extend ddb(4) "show mount" command to print active string mount options. Note that only option names are printed, not values. Approved by: trasz (mentor) --- sys/kern/vfs_subr.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index f3ec5650956..0d38e5cea93 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2761,6 +2761,7 @@ DB_SHOW_COMMAND(vnode, db_show_vnode) DB_SHOW_COMMAND(mount, db_show_mount) { struct mount *mp; + struct vfsopt *opt; struct statfs *sp; struct vnode *vp; char buf[512]; @@ -2866,6 +2867,18 @@ DB_SHOW_COMMAND(mount, db_show_mount) } db_printf(" mnt_kern_flag = %s\n", buf); + db_printf(" mnt_opt = "); + opt = TAILQ_FIRST(mp->mnt_opt); + if (opt != NULL) { + db_printf("%s", opt->name); + opt = TAILQ_NEXT(opt, link); + while (opt != NULL) { + db_printf(", %s", opt->name); + opt = TAILQ_NEXT(opt, link); + } + } + db_printf("\n"); + sp = &mp->mnt_stat; db_printf(" mnt_stat = { version=%u type=%u flags=0x%016jx " "bsize=%ju iosize=%ju blocks=%ju bfree=%ju bavail=%jd files=%ju " From 21148e9257354efeced8a418a1a2eb366b82ee28 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Fri, 4 Dec 2009 11:26:52 +0000 Subject: [PATCH 0731/2592] MFC r199843: Clarify that the value of the fts_info field is different in post-order. Approved by: trasz (mentor) --- lib/libc/gen/fts.3 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3 index 8e1a1e42269..d2473bea132 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 November 25, 2009 .Dt FTS 3 .Os .Sh NAME @@ -198,10 +198,9 @@ A directory being visited in post-order. The contents of the .Vt FTSENT structure will be unchanged from when -it was returned in pre-order, i.e., with the +the directory was visited in pre-order, except for the .Fa fts_info -field set to -.Dv FTS_D . +field. .It Dv FTS_ERR This is an error return, and the .Fa fts_errno From 0800f014ec2de99801e5a9d956fccad186afcd39 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Fri, 4 Dec 2009 18:29:59 +0000 Subject: [PATCH 0732/2592] MFC rev 200051: Make sure bus space accesses use unorder memory loads and stores. --- sys/ia64/ia64/machdep.c | 4 +- sys/ia64/ia64/support.S | 7 ++ sys/ia64/include/bus.h | 152 ++++++++++++++++++------------------ sys/ia64/include/cpufunc.h | 4 +- sys/ia64/include/ia64_cpu.h | 68 ++++++++++++++++ 5 files changed, 155 insertions(+), 80 deletions(-) diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 5a109701922..b1b3b6fc8d7 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -859,14 +859,14 @@ ia64_init(void) return (ret); } -__volatile void * +void * ia64_ioport_address(u_int port) { uint64_t addr; addr = (port > 0xffff) ? IA64_PHYS_TO_RR6((uint64_t)port) : ia64_port_base | ((port & 0xfffc) << 10) | (port & 0xFFF); - return ((__volatile void *)addr); + return ((void *)addr); } uint64_t diff --git a/sys/ia64/ia64/support.S b/sys/ia64/ia64/support.S index ea04276e9ec..8b120290d92 100644 --- a/sys/ia64/ia64/support.S +++ b/sys/ia64/ia64/support.S @@ -775,8 +775,10 @@ ENTRY(copyinstr, 4) ;; br.call.sptk.few rp=copystr // do the copy. st8 [loc2]=r0 // kill the fault handler. + ;; mov ar.pfs=loc0 // restore ar.pfs mov rp=loc1 // restore ra. + ;; br.ret.sptk.few rp // ret0 left over from copystr END(copyinstr) @@ -887,8 +889,10 @@ ENTRY(copyin, 3) ;; br.call.sptk.few rp=bcopy // do the copy. st8 [loc2]=r0 // kill the fault handler. + ;; mov ar.pfs=loc0 // restore ar.pfs mov rp=loc1 // restore ra. + ;; br.ret.sptk.few rp // ret0 left over from bcopy END(copyin) @@ -925,8 +929,10 @@ ENTRY(copyout, 3) ;; br.call.sptk.few rp=bcopy // do the copy. st8 [loc2]=r0 // kill the fault handler. + ;; mov ar.pfs=loc0 // restore ar.pfs mov rp=loc1 // restore ra. + ;; br.ret.sptk.few rp // ret0 left over from bcopy END(copyout) @@ -979,6 +985,7 @@ ENTRY_NOPROFILE(_mcount, 4) ;; 2: mov ar.pfs = r14 + ;; br.sptk b6 ;; END(_mcount) diff --git a/sys/ia64/include/bus.h b/sys/ia64/include/bus.h index 02fe8bee105..80b90cadc65 100644 --- a/sys/ia64/include/bus.h +++ b/sys/ia64/include/bus.h @@ -169,37 +169,37 @@ bus_space_barrier(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, static __inline uint8_t bus_space_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) { - uint8_t __volatile *bsp; + uint8_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - return (*bsp); + return (ia64_ld1(bsp)); } static __inline uint16_t bus_space_read_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) { - uint16_t __volatile *bsp; + uint16_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - return (*bsp); + return (ia64_ld2(bsp)); } static __inline uint32_t bus_space_read_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) { - uint32_t __volatile *bsp; + uint32_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - return (*bsp); + return (ia64_ld4(bsp)); } static __inline uint64_t bus_space_read_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) { - uint64_t __volatile *bsp; + uint64_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - return (*bsp); + return (ia64_ld8(bsp)); } @@ -212,40 +212,40 @@ static __inline void bus_space_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint8_t val) { - uint8_t __volatile *bsp; + uint8_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = val; + ia64_st1(bsp, val); } static __inline void bus_space_write_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint16_t val) { - uint16_t __volatile *bsp; + uint16_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = val; + ia64_st2(bsp, val); } static __inline void bus_space_write_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint32_t val) { - uint32_t __volatile *bsp; + uint32_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = val; + ia64_st4(bsp, val); } static __inline void bus_space_write_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint64_t val) { - uint64_t __volatile *bsp; + uint64_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = val; + ia64_st8(bsp, val); } @@ -258,44 +258,44 @@ static __inline void bus_space_read_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint8_t *bufp, size_t count) { - uint8_t __volatile *bsp; + uint8_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bufp++ = *bsp; + *bufp++ = ia64_ld1(bsp); } static __inline void bus_space_read_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint16_t *bufp, size_t count) { - uint16_t __volatile *bsp; + uint16_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bufp++ = *bsp; + *bufp++ = ia64_ld2(bsp); } static __inline void bus_space_read_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint32_t *bufp, size_t count) { - uint32_t __volatile *bsp; + uint32_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bufp++ = *bsp; + *bufp++ = ia64_ld4(bsp); } static __inline void bus_space_read_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint64_t *bufp, size_t count) { - uint64_t __volatile *bsp; + uint64_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bufp++ = *bsp; + *bufp++ = ia64_ld8(bsp); } @@ -308,44 +308,44 @@ static __inline void bus_space_write_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *bufp, size_t count) { - uint8_t __volatile *bsp; + uint8_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bsp = *bufp++; + ia64_st1(bsp, *bufp++); } static __inline void bus_space_write_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *bufp, size_t count) { - uint16_t __volatile *bsp; + uint16_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bsp = *bufp++; + ia64_st2(bsp, *bufp++); } static __inline void bus_space_write_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *bufp, size_t count) { - uint32_t __volatile *bsp; + uint32_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bsp = *bufp++; + ia64_st4(bsp, *bufp++); } static __inline void bus_space_write_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *bufp, size_t count) { - uint64_t __volatile *bsp; + uint64_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bsp = *bufp++; + ia64_st8(bsp, *bufp++); } @@ -359,11 +359,11 @@ static __inline void bus_space_read_region_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint8_t *bufp, size_t count) { - uint8_t __volatile *bsp; + uint8_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bufp++ = *bsp; + *bufp++ = ia64_ld1(bsp); ofs += 1; } } @@ -372,11 +372,11 @@ static __inline void bus_space_read_region_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint16_t *bufp, size_t count) { - uint16_t __volatile *bsp; + uint16_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bufp++ = *bsp; + *bufp++ = ia64_ld2(bsp); ofs += 2; } } @@ -385,11 +385,11 @@ static __inline void bus_space_read_region_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint32_t *bufp, size_t count) { - uint32_t __volatile *bsp; + uint32_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bufp++ = *bsp; + *bufp++ = ia64_ld4(bsp); ofs += 4; } } @@ -398,11 +398,11 @@ static __inline void bus_space_read_region_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint64_t *bufp, size_t count) { - uint64_t __volatile *bsp; + uint64_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bufp++ = *bsp; + *bufp++ = ia64_ld8(bsp); ofs += 8; } } @@ -418,11 +418,11 @@ static __inline void bus_space_write_region_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *bufp, size_t count) { - uint8_t __volatile *bsp; + uint8_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = *bufp++; + ia64_st1(bsp, *bufp++); ofs += 1; } } @@ -431,11 +431,11 @@ static __inline void bus_space_write_region_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *bufp, size_t count) { - uint16_t __volatile *bsp; + uint16_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = *bufp++; + ia64_st2(bsp, *bufp++); ofs += 2; } } @@ -444,11 +444,11 @@ static __inline void bus_space_write_region_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *bufp, size_t count) { - uint32_t __volatile *bsp; + uint32_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = *bufp++; + ia64_st4(bsp, *bufp++); ofs += 4; } } @@ -457,11 +457,11 @@ static __inline void bus_space_write_region_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *bufp, size_t count) { - uint64_t __volatile *bsp; + uint64_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = *bufp++; + ia64_st8(bsp, *bufp++); ofs += 8; } } @@ -476,44 +476,44 @@ static __inline void bus_space_set_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t count) { - uint8_t __volatile *bsp; + uint8_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bsp = val; + ia64_st1(bsp, val); } static __inline void bus_space_set_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t count) { - uint16_t __volatile *bsp; + uint16_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bsp = val; + ia64_st2(bsp, val); } static __inline void bus_space_set_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t count) { - uint32_t __volatile *bsp; + uint32_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bsp = val; + ia64_st4(bsp, val); } static __inline void bus_space_set_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t count) { - uint64_t __volatile *bsp; + uint64_t *bsp; bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); while (count-- > 0) - *bsp = val; + ia64_st8(bsp, val); } @@ -527,11 +527,11 @@ static __inline void bus_space_set_region_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t count) { - uint8_t __volatile *bsp; + uint8_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = val; + ia64_st1(bsp, val); ofs += 1; } } @@ -540,11 +540,11 @@ static __inline void bus_space_set_region_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t count) { - uint16_t __volatile *bsp; + uint16_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = val; + ia64_st2(bsp, val); ofs += 2; } } @@ -553,11 +553,11 @@ static __inline void bus_space_set_region_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t count) { - uint32_t __volatile *bsp; + uint32_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = val; + ia64_st4(bsp, val); ofs += 4; } } @@ -566,11 +566,11 @@ static __inline void bus_space_set_region_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t count) { - uint64_t __volatile *bsp; + uint64_t *bsp; while (count-- > 0) { bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : __MEMIO_ADDR(bsh + ofs); - *bsp = val; + ia64_st8(bsp, val); ofs += 8; } } @@ -588,7 +588,7 @@ bus_space_copy_region_1(bus_space_tag_t bst, bus_space_handle_t bsh1, bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count) { bus_addr_t dst, src; - uint8_t __volatile *dstp, *srcp; + uint8_t *dstp, *srcp; src = bsh1 + ofs1; dst = bsh2 + ofs2; if (dst > src) { @@ -602,7 +602,7 @@ bus_space_copy_region_1(bus_space_tag_t bst, bus_space_handle_t bsh1, srcp = __MEMIO_ADDR(src); dstp = __MEMIO_ADDR(dst); } - *dstp = *srcp; + ia64_st1(dstp, ia64_ld1(srcp)); src -= 1; dst -= 1; } @@ -615,7 +615,7 @@ bus_space_copy_region_1(bus_space_tag_t bst, bus_space_handle_t bsh1, srcp = __MEMIO_ADDR(src); dstp = __MEMIO_ADDR(dst); } - *dstp = *srcp; + ia64_st1(dstp, ia64_ld1(srcp)); src += 1; dst += 1; } @@ -627,7 +627,7 @@ bus_space_copy_region_2(bus_space_tag_t bst, bus_space_handle_t bsh1, bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count) { bus_addr_t dst, src; - uint16_t __volatile *dstp, *srcp; + uint16_t *dstp, *srcp; src = bsh1 + ofs1; dst = bsh2 + ofs2; if (dst > src) { @@ -641,7 +641,7 @@ bus_space_copy_region_2(bus_space_tag_t bst, bus_space_handle_t bsh1, srcp = __MEMIO_ADDR(src); dstp = __MEMIO_ADDR(dst); } - *dstp = *srcp; + ia64_st2(dstp, ia64_ld2(srcp)); src -= 2; dst -= 2; } @@ -654,7 +654,7 @@ bus_space_copy_region_2(bus_space_tag_t bst, bus_space_handle_t bsh1, srcp = __MEMIO_ADDR(src); dstp = __MEMIO_ADDR(dst); } - *dstp = *srcp; + ia64_st2(dstp, ia64_ld2(srcp)); src += 2; dst += 2; } @@ -666,7 +666,7 @@ bus_space_copy_region_4(bus_space_tag_t bst, bus_space_handle_t bsh1, bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count) { bus_addr_t dst, src; - uint32_t __volatile *dstp, *srcp; + uint32_t *dstp, *srcp; src = bsh1 + ofs1; dst = bsh2 + ofs2; if (dst > src) { @@ -680,7 +680,7 @@ bus_space_copy_region_4(bus_space_tag_t bst, bus_space_handle_t bsh1, srcp = __MEMIO_ADDR(src); dstp = __MEMIO_ADDR(dst); } - *dstp = *srcp; + ia64_st4(dstp, ia64_ld4(srcp)); src -= 4; dst -= 4; } @@ -693,7 +693,7 @@ bus_space_copy_region_4(bus_space_tag_t bst, bus_space_handle_t bsh1, srcp = __MEMIO_ADDR(src); dstp = __MEMIO_ADDR(dst); } - *dstp = *srcp; + ia64_st4(dstp, ia64_ld4(srcp)); src += 4; dst += 4; } @@ -705,7 +705,7 @@ bus_space_copy_region_8(bus_space_tag_t bst, bus_space_handle_t bsh1, bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count) { bus_addr_t dst, src; - uint64_t __volatile *dstp, *srcp; + uint64_t *dstp, *srcp; src = bsh1 + ofs1; dst = bsh2 + ofs2; if (dst > src) { @@ -719,7 +719,7 @@ bus_space_copy_region_8(bus_space_tag_t bst, bus_space_handle_t bsh1, srcp = __MEMIO_ADDR(src); dstp = __MEMIO_ADDR(dst); } - *dstp = *srcp; + ia64_st8(dstp, ia64_ld8(srcp)); src -= 8; dst -= 8; } @@ -732,7 +732,7 @@ bus_space_copy_region_8(bus_space_tag_t bst, bus_space_handle_t bsh1, srcp = __MEMIO_ADDR(src); dstp = __MEMIO_ADDR(dst); } - *dstp = *srcp; + ia64_st8(dstp, ia64_ld8(srcp)); src += 8; dst += 8; } diff --git a/sys/ia64/include/cpufunc.h b/sys/ia64/include/cpufunc.h index 339bd95801a..694f8833a47 100644 --- a/sys/ia64/include/cpufunc.h +++ b/sys/ia64/include/cpufunc.h @@ -54,8 +54,8 @@ breakpoint(void) #define HAVE_INLINE_FFS #define ffs(x) __builtin_ffs(x) -#define __MEMIO_ADDR(x) (__volatile void*)(IA64_PHYS_TO_RR6(x)) -extern __volatile void *ia64_ioport_address(u_int); +#define __MEMIO_ADDR(x) (void*)(IA64_PHYS_TO_RR6(x)) +extern void *ia64_ioport_address(u_int); #define __PIO_ADDR(x) ia64_ioport_address(x) /* diff --git a/sys/ia64/include/ia64_cpu.h b/sys/ia64/include/ia64_cpu.h index 3d6c725c150..0a5a1154aeb 100644 --- a/sys/ia64/include/ia64_cpu.h +++ b/sys/ia64/include/ia64_cpu.h @@ -281,6 +281,74 @@ ia64_ptc_l(u_int64_t va, u_int64_t log2size) __asm __volatile("ptc.l %0,%1;; srlz.i;;" :: "r"(va), "r"(log2size)); } +/* + * Unordered memory load. + */ + +static __inline uint8_t +ia64_ld1(uint8_t *p) +{ + uint8_t v; + + __asm __volatile("ld1 %0=[%1];;" : "=r"(v) : "r"(p)); + return (v); +} + +static __inline uint16_t +ia64_ld2(uint16_t *p) +{ + uint16_t v; + + __asm __volatile("ld2 %0=[%1];;" : "=r"(v) : "r"(p)); + return (v); +} + +static __inline uint32_t +ia64_ld4(uint32_t *p) +{ + uint32_t v; + + __asm __volatile("ld4 %0=[%1];;" : "=r"(v) : "r"(p)); + return (v); +} + +static __inline uint64_t +ia64_ld8(uint64_t *p) +{ + uint64_t v; + + __asm __volatile("ld8 %0=[%1];;" : "=r"(v) : "r"(p)); + return (v); +} + +/* + * Unordered memory store. + */ + +static __inline void +ia64_st1(uint8_t *p, uint8_t v) +{ + __asm __volatile("st1 [%0]=%1;;" :: "r"(p), "r"(v)); +} + +static __inline void +ia64_st2(uint16_t *p, uint16_t v) +{ + __asm __volatile("st2 [%0]=%1;;" :: "r"(p), "r"(v)); +} + +static __inline void +ia64_st4(uint32_t *p, uint32_t v) +{ + __asm __volatile("st4 [%0]=%1;;" :: "r"(p), "r"(v)); +} + +static __inline void +ia64_st8(uint64_t *p, uint64_t v) +{ + __asm __volatile("st8 [%0]=%1;;" :: "r"(p), "r"(v)); +} + /* * Read the value of psr. */ From fa0b65d1517f2acee5f36ae8cd16972b702397fc Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Fri, 4 Dec 2009 18:35:02 +0000 Subject: [PATCH 0733/2592] Revert unintentional change in revision 200103. --- sys/ia64/ia64/support.S | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sys/ia64/ia64/support.S b/sys/ia64/ia64/support.S index 8b120290d92..ea04276e9ec 100644 --- a/sys/ia64/ia64/support.S +++ b/sys/ia64/ia64/support.S @@ -775,10 +775,8 @@ ENTRY(copyinstr, 4) ;; br.call.sptk.few rp=copystr // do the copy. st8 [loc2]=r0 // kill the fault handler. - ;; mov ar.pfs=loc0 // restore ar.pfs mov rp=loc1 // restore ra. - ;; br.ret.sptk.few rp // ret0 left over from copystr END(copyinstr) @@ -889,10 +887,8 @@ ENTRY(copyin, 3) ;; br.call.sptk.few rp=bcopy // do the copy. st8 [loc2]=r0 // kill the fault handler. - ;; mov ar.pfs=loc0 // restore ar.pfs mov rp=loc1 // restore ra. - ;; br.ret.sptk.few rp // ret0 left over from bcopy END(copyin) @@ -929,10 +925,8 @@ ENTRY(copyout, 3) ;; br.call.sptk.few rp=bcopy // do the copy. st8 [loc2]=r0 // kill the fault handler. - ;; mov ar.pfs=loc0 // restore ar.pfs mov rp=loc1 // restore ra. - ;; br.ret.sptk.few rp // ret0 left over from bcopy END(copyout) @@ -985,7 +979,6 @@ ENTRY_NOPROFILE(_mcount, 4) ;; 2: mov ar.pfs = r14 - ;; br.sptk b6 ;; END(_mcount) From c0afc53a8fa9055de5e233b581b015e94494bf6b Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 5 Dec 2009 08:44:55 +0000 Subject: [PATCH 0734/2592] MFC r200008: Add CAM_ATAIO_DMA ATA command flag to mark DMA protocol commands. It is not needed for SATA controllers, but required for PATA. --- sys/cam/ata/ata_all.c | 20 +++++++++++++++++--- sys/cam/ata/ata_all.h | 1 + sys/sys/ata.h | 10 ++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index 5c0c6d9670d..588ef097496 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -93,8 +93,8 @@ ata_op_string(struct ata_cmd *cmd) 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 0x3d: return ("WRITE_DMA_FUA48"); + case 0x3e: return ("WRITE_DMA_QUEUED_FUA48"); case 0x3f: return ("WRITE_LOG_EXT"); case 0x40: return ("READ_VERIFY"); case 0x42: return ("READ_VERIFY48"); @@ -119,7 +119,7 @@ ata_op_string(struct ata_cmd *cmd) 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 0xce: return ("WRITE_MUL_FUA48"); case 0xd1: return ("CHECK_MEDIA_CARD_TYPE"); case 0xda: return ("GET_MEDIA_STATUS"); case 0xde: return ("MEDIA_LOCK"); @@ -309,6 +309,11 @@ ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, { bzero(&ataio->cmd, sizeof(ataio->cmd)); ataio->cmd.flags = 0; + if (cmd == ATA_READ_DMA || + cmd == ATA_READ_DMA_QUEUED || + cmd == ATA_WRITE_DMA || + cmd == ATA_WRITE_DMA_QUEUED) + ataio->cmd.flags |= CAM_ATAIO_DMA; ataio->cmd.command = cmd; ataio->cmd.features = features; ataio->cmd.lba_low = lba; @@ -324,6 +329,15 @@ ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features, { bzero(&ataio->cmd, sizeof(ataio->cmd)); ataio->cmd.flags = CAM_ATAIO_48BIT; + if (cmd == ATA_READ_DMA48 || + cmd == ATA_READ_DMA_QUEUED48 || + cmd == ATA_READ_STREAM_DMA48 || + cmd == ATA_WRITE_DMA48 || + cmd == ATA_WRITE_DMA_FUA48 || + cmd == ATA_WRITE_DMA_QUEUED48 || + cmd == ATA_WRITE_DMA_QUEUED_FUA48 || + cmd == ATA_WRITE_STREAM_DMA48) + ataio->cmd.flags |= CAM_ATAIO_DMA; ataio->cmd.command = cmd; ataio->cmd.features = features; ataio->cmd.lba_low = lba; diff --git a/sys/cam/ata/ata_all.h b/sys/cam/ata/ata_all.h index e64e1a1d24c..2e838fdc7b4 100644 --- a/sys/cam/ata/ata_all.h +++ b/sys/cam/ata/ata_all.h @@ -41,6 +41,7 @@ struct ata_cmd { #define CAM_ATAIO_FPDMA 0x02 /* FPDMA command */ #define CAM_ATAIO_CONTROL 0x04 /* Control, not a command */ #define CAM_ATAIO_NEEDRESULT 0x08 /* Request requires result. */ +#define CAM_ATAIO_DMA 0x10 /* DMA command */ u_int8_t command; u_int8_t features; diff --git a/sys/sys/ata.h b/sys/sys/ata.h index 84d23b9c1b6..91afb529b28 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -291,12 +291,21 @@ struct ata_params { #define ATA_READ_DMA_QUEUED48 0x26 /* read DMA QUEUED 48bit LBA */ #define ATA_READ_NATIVE_MAX_ADDRESS48 0x27 /* read native max addr 48bit */ #define ATA_READ_MUL48 0x29 /* read multi 48bit LBA */ +#define ATA_READ_STREAM_DMA48 0x2a /* read DMA stream 48bit LBA */ +#define ATA_READ_STREAM48 0x2b /* read stream 48bit LBA */ #define ATA_WRITE 0x30 /* write */ #define ATA_WRITE48 0x34 /* write 48bit LBA */ #define ATA_WRITE_DMA48 0x35 /* write DMA 48bit LBA */ #define ATA_WRITE_DMA_QUEUED48 0x36 /* write DMA QUEUED 48bit LBA*/ #define ATA_SET_MAX_ADDRESS48 0x37 /* set max address 48bit */ #define ATA_WRITE_MUL48 0x39 /* write multi 48bit LBA */ +#define ATA_WRITE_STREAM_DMA48 0x3a +#define ATA_WRITE_STREAM48 0x3b +#define ATA_WRITE_DMA_FUA48 0x3d +#define ATA_WRITE_DMA_QUEUED_FUA48 0x3e +#define ATA_WRITE_LOG_EXT 0x3f +#define ATA_READ_VERIFY 0x40 +#define ATA_READ_VERIFY48 0x42 #define ATA_READ_FPDMA_QUEUED 0x60 /* read DMA NCQ */ #define ATA_WRITE_FPDMA_QUEUED 0x61 /* write DMA NCQ */ #define ATA_SEEK 0x70 /* seek */ @@ -312,6 +321,7 @@ struct ata_params { #define ATA_READ_DMA 0xc8 /* read DMA */ #define ATA_WRITE_DMA 0xca /* write DMA */ #define ATA_WRITE_DMA_QUEUED 0xcc /* write DMA QUEUED */ +#define ATA_WRITE_MUL_FUA48 0xce #define ATA_STANDBY_IMMEDIATE 0xe0 /* standby immediate */ #define ATA_IDLE_IMMEDIATE 0xe1 /* idle immediate */ #define ATA_STANDBY_CMD 0xe2 /* standby */ From 3cdcbc48859da2a04424f8c7e10007eae9e5b2ff Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Sat, 5 Dec 2009 12:51:51 +0000 Subject: [PATCH 0735/2592] some simple MFC: r200020: change the type of the opcode from enum *:8 to u_int8_t so the size and alignment of the ipfw_insn is not compiler dependent. No changes in the code generated by gcc. r200023: Add new sockopt names for ipfw and dummynet. This commit is just grabbing entries for the new names that will be used in the future, so you don't need to rebuild anything now. r200034 Dispatch sockopt calls to ipfw and dummynet using the new option numbers, IP_FW3 and IP_DUMMYNET3. Right now the modules return an error if called with those arguments so there is no danger of unwanted behaviour. r200040 - initialize src_ip in the main loop to prevent a compiler warning (gcc 4.x under linux, not sure how real is the complaint). - rename a macro argument to prevent name clashes. - add the macro name on a couple of #endif - add a blank line for readability. --- sys/netinet/in.h | 8 ++++++++ sys/netinet/ip_fw.h | 2 +- sys/netinet/ipfw/ip_fw2.c | 13 ++++++++----- sys/netinet/raw_ip.c | 4 ++++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 4f9b774ca0d..7aa16453e15 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -443,12 +443,20 @@ __END_DECLS #define IP_ONESBCAST 23 /* bool: send all-ones broadcast */ #define IP_BINDANY 24 /* bool: allow bind to any address */ +/* + * Options for controlling the firewall and dummynet. + * Historical options (from 40 to 64) will eventually be + * replaced by only two options, IP_FW3 and IP_DUMMYNET3. + */ #define IP_FW_TABLE_ADD 40 /* add entry */ #define IP_FW_TABLE_DEL 41 /* delete entry */ #define IP_FW_TABLE_FLUSH 42 /* flush table */ #define IP_FW_TABLE_GETSIZE 43 /* get table size */ #define IP_FW_TABLE_LIST 44 /* list table contents */ +#define IP_FW3 48 /* generic ipfw v.3 sockopts */ +#define IP_DUMMYNET3 49 /* generic dummynet v.3 sockopts */ + #define IP_FW_ADD 50 /* add a firewall rule to chain */ #define IP_FW_DEL 51 /* delete a firewall rule from chain */ #define IP_FW_FLUSH 52 /* flush firewall rule chain */ diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h index 9967a29607b..1e6feb4d3c1 100644 --- a/sys/netinet/ip_fw.h +++ b/sys/netinet/ip_fw.h @@ -237,7 +237,7 @@ enum ipfw_opcodes { /* arguments (4 byte each) */ * */ typedef struct _ipfw_insn { /* template for instructions */ - enum ipfw_opcodes opcode:8; + u_int8_t opcode; u_int8_t len; /* number of 32-bit words */ #define F_NOT 0x80 #define F_OR 0x40 diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c index a17a64792e8..d5d49ca80e2 100644 --- a/sys/netinet/ipfw/ip_fw2.c +++ b/sys/netinet/ipfw/ip_fw2.c @@ -185,6 +185,7 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN, &default_to_accept, 0, "Make the default rule accept all packets."); TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept); + #ifdef INET6 SYSCTL_DECL(_net_inet6_ip6); SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall"); @@ -194,8 +195,9 @@ SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_AUTO, enable, SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs, CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_deny_unknown_exthdrs), 0, "Deny packets with unknown IPv6 Extension Headers"); -#endif -#endif +#endif /* INET6 */ + +#endif /* SYSCTL_NODE */ /* * Description of dynamic rules. @@ -2243,6 +2245,7 @@ ipfw_chk(struct ip_fw_args *args) return (IP_FW_PASS); /* accept */ dst_ip.s_addr = 0; /* make sure it is initialized */ + src_ip.s_addr = 0; /* make sure it is initialized */ pktlen = m->m_pkthdr.len; args->f_id.fib = M_GETFIB(m); /* note mbuf not altered) */ proto = args->f_id.proto = 0; /* mark f_id invalid */ @@ -2254,15 +2257,15 @@ ipfw_chk(struct ip_fw_args *args) * pointer might become stale after other pullups (but we never use it * this way). */ -#define PULLUP_TO(len, p, T) \ +#define PULLUP_TO(_len, p, T) \ do { \ - int x = (len) + sizeof(T); \ + int x = (_len) + sizeof(T); \ if ((m)->m_len < x) { \ args->m = m = m_pullup(m, x); \ if (m == NULL) \ goto pullup_failed; \ } \ - p = (mtod(m, char *) + (len)); \ + p = (mtod(m, char *) + (_len)); \ } while (0) /* diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 60824d92697..15a8fe4360b 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -535,6 +535,7 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) error = sooptcopyout(sopt, &optval, sizeof optval); break; + case IP_FW3: /* generic ipfw v.3 functions */ case IP_FW_ADD: /* ADD actually returns the body... */ case IP_FW_GET: case IP_FW_TABLE_GETSIZE: @@ -547,6 +548,7 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) error = ENOPROTOOPT; break; + case IP_DUMMYNET3: /* generic dummynet v.3 functions */ case IP_DUMMYNET_GET: if (ip_dn_ctl_ptr != NULL) error = ip_dn_ctl_ptr(sopt); @@ -592,6 +594,7 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) inp->inp_flags &= ~INP_HDRINCL; break; + case IP_FW3: /* generic ipfw v.3 functions */ case IP_FW_ADD: case IP_FW_DEL: case IP_FW_FLUSH: @@ -608,6 +611,7 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) error = ENOPROTOOPT; break; + case IP_DUMMYNET3: /* generic dummynet v.3 functions */ case IP_DUMMYNET_CONFIGURE: case IP_DUMMYNET_DEL: case IP_DUMMYNET_FLUSH: From 4816ae8d04ebb9908663d309c0a466c138d63afd Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Sat, 5 Dec 2009 17:07:43 +0000 Subject: [PATCH 0736/2592] MFC r200001: Fix parenthesis typo -- copy full frame pointer for userland callchain, not just one byte. Submitted by: Ryan Stone rysto32 at gmail dot com --- sys/dev/hwpmc/hwpmc_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/hwpmc/hwpmc_x86.c b/sys/dev/hwpmc/hwpmc_x86.c index 09d04bb713e..6df47d32fec 100644 --- a/sys/dev/hwpmc/hwpmc_x86.c +++ b/sys/dev/hwpmc/hwpmc_x86.c @@ -101,7 +101,7 @@ pmc_save_user_callchain(uintptr_t *cc, int nframes, struct trapframe *tf) if (copyin((void *) sp, &pc, sizeof(pc)) != 0) return (n); } else if (copyin((void *) r, &pc, sizeof(pc)) != 0 || - copyin((void *) fp, &fp, sizeof(fp) != 0)) + copyin((void *) fp, &fp, sizeof(fp)) != 0) return (n); for (; n < nframes;) { From cc8eb5c3a4a97b10d368daac48cc9838504500d0 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 18:17:15 +0000 Subject: [PATCH 0737/2592] MFC r199894: Correct a typo. --- sys/netipsec/ipsec_mbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netipsec/ipsec_mbuf.c b/sys/netipsec/ipsec_mbuf.c index 97f97142d6b..ffbe6649b34 100644 --- a/sys/netipsec/ipsec_mbuf.c +++ b/sys/netipsec/ipsec_mbuf.c @@ -69,7 +69,7 @@ m_makespace(struct mbuf *m0, int skip, int hlen, int *off) * At this point skip is the offset into the mbuf m * where the new header should be placed. Figure out * if there's space to insert the new header. If so, - * and copying the remainder makese sense then do so. + * and copying the remainder makes sense then do so. * Otherwise insert a new mbuf in the chain, splitting * the contents of m as needed. */ From 4cc7ec350055af813908b2bba32f67f149aa3485 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 18:54:21 +0000 Subject: [PATCH 0738/2592] MFC r199883: Add SDT_PROBE[1-5] in the same way we have SDT_PROBE_DEFINE[1-5] to avoid having to add all the unused trailing arguments as zeros. --- sys/sys/sdt.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/sys/sys/sdt.h b/sys/sys/sdt.h index 8d212c8a96f..eeae665c141 100644 --- a/sys/sys/sdt.h +++ b/sys/sys/sdt.h @@ -59,6 +59,12 @@ #define SDT_PROBE_DEFINE4(prov, mod, func, name, arg0, arg1, arg2, arg3) #define SDT_PROBE_DEFINE5(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) +#define SDT_PROBE1(prov, mod, func, name, arg0) +#define SDT_PROBE2(prov, mod, func, name, arg0, arg1) +#define SDT_PROBE3(prov, mod, func, name, arg0, arg1, arg2) +#define SDT_PROBE4(prov, mod, func, name, arg0, arg1, arg2, arg3) +#define SDT_PROBE5(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) + #else /* @@ -192,6 +198,17 @@ struct sdt_provider { SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3); \ SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4) +#define SDT_PROBE1(prov, mod, func, name, arg0) \ + SDT_PROBE(prov, mod, func, name, arg0, 0, 0, 0, 0) +#define SDT_PROBE2(prov, mod, func, name, arg0, arg1) \ + SDT_PROBE(prov, mod, func, name, arg0, arg1, 0, 0, 0) +#define SDT_PROBE3(prov, mod, func, name, arg0, arg1, arg2) \ + SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, 0, 0) +#define SDT_PROBE4(prov, mod, func, name, arg0, arg1, arg2, arg3) \ + SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, 0) +#define SDT_PROBE5(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) \ + SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) + typedef int (*sdt_argtype_listall_func_t)(struct sdt_argtype *, void *); typedef int (*sdt_probe_listall_func_t)(struct sdt_probe *, void *); typedef int (*sdt_provider_listall_func_t)(struct sdt_provider *, void *); From c8ce7b587b335a1bfec7342a331ad4ae125e30d1 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 18:55:54 +0000 Subject: [PATCH 0739/2592] MFC r199884: Define an SDT provider for "opencrypto". --- sys/opencrypto/crypto.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c index 0637c86411b..58107802fd7 100644 --- a/sys/opencrypto/crypto.c +++ b/sys/opencrypto/crypto.c @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #define CRYPTO_TIMING /* enable timing support */ #include "opt_ddb.h" +#include "opt_kdtrace.h" #include #include @@ -68,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -80,6 +82,8 @@ __FBSDID("$FreeBSD$"); #include #include "cryptodev_if.h" +SDT_PROVIDER_DEFINE(opencrypto); + /* * Crypto drivers register themselves by allocating a slot in the * crypto_drivers table with crypto_get_driverid() and then registering From 5aef8fdf1199bb31ee2ef91e66a1bce3ff5ae1f7 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 18:57:32 +0000 Subject: [PATCH 0740/2592] MFC r199885: Add SDT probes for opencrypto:deflate:deflate_gobal:*. They are not nice but they were helpful. --- sys/opencrypto/deflate.c | 68 +++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/sys/opencrypto/deflate.c b/sys/opencrypto/deflate.c index f4b4f48ff43..239435e06fa 100644 --- a/sys/opencrypto/deflate.c +++ b/sys/opencrypto/deflate.c @@ -35,16 +35,30 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_kdtrace.h" + #include #include #include #include +#include +#include #include #include #include #include +SDT_PROVIDER_DECLARE(opencrypto); +SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, entry, + "int", "u_int32_t"); +SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, bad, + "int", "int", "int", "int", "int"); +SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, iter, + "int", "int", "int", "int", "int"); +SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, return, + "int", "u_int32_t"); + int window_inflate = -1 * MAX_WBITS; int window_deflate = -12; @@ -68,6 +82,8 @@ deflate_global(data, size, decomp, out) int error, i = 0, j; struct deflate_buf buf[ZBUF]; + SDT_PROBE2(opencrypto, deflate, deflate_global, entry, decomp, size); + bzero(&zbuf, sizeof(z_stream)); for (j = 0; j < ZBUF; j++) buf[j].flag = 0; @@ -81,8 +97,11 @@ deflate_global(data, size, decomp, out) if (!decomp) { buf[i].out = malloc((u_long) size, M_CRYPTO_DATA, M_NOWAIT); - if (buf[i].out == NULL) + if (buf[i].out == NULL) { + SDT_PROBE3(opencrypto, deflate, deflate_global, bad, + decomp, 0, __LINE__); goto bad; + } buf[i].size = size; buf[i].flag = 1; i++; @@ -96,8 +115,11 @@ deflate_global(data, size, decomp, out) buf[i].out = malloc((u_long) (size * 4), M_CRYPTO_DATA, M_NOWAIT); - if (buf[i].out == NULL) + if (buf[i].out == NULL) { + SDT_PROBE3(opencrypto, deflate, deflate_global, bad, + decomp, 0, __LINE__); goto bad; + } buf[i].size = size * 4; buf[i].flag = 1; i++; @@ -110,36 +132,67 @@ deflate_global(data, size, decomp, out) deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD, window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY); - if (error != Z_OK) + if (error != Z_OK) { + SDT_PROBE3(opencrypto, deflate, deflate_global, bad, + decomp, error, __LINE__); goto bad; + } for (;;) { error = decomp ? inflate(&zbuf, Z_PARTIAL_FLUSH) : deflate(&zbuf, Z_PARTIAL_FLUSH); - if (error != Z_OK && error != Z_STREAM_END) + if (error != Z_OK && error != Z_STREAM_END) { + /* + * Unfortunately we are limited to 5 arguments, + * thus use two probes. + */ + SDT_PROBE5(opencrypto, deflate, deflate_global, bad, + decomp, error, __LINE__, + zbuf.avail_in, zbuf.avail_out); + SDT_PROBE5(opencrypto, deflate, deflate_global, bad, + decomp, error, __LINE__, + zbuf.state->dummy, zbuf.total_out); goto bad; + } else if (zbuf.avail_in == 0 && zbuf.avail_out != 0) goto end; else if (zbuf.avail_out == 0 && i < (ZBUF - 1)) { /* we need more output space, allocate size */ buf[i].out = malloc((u_long) size, M_CRYPTO_DATA, M_NOWAIT); - if (buf[i].out == NULL) + if (buf[i].out == NULL) { + SDT_PROBE3(opencrypto, deflate, deflate_global, + bad, decomp, 0, __LINE__); goto bad; + } zbuf.next_out = buf[i].out; buf[i].size = size; buf[i].flag = 1; zbuf.avail_out = buf[i].size; i++; - } else + } else { + /* + * Unfortunately we are limited to 5 arguments, + * thus, again, use two probes. + */ + SDT_PROBE5(opencrypto, deflate, deflate_global, bad, + decomp, error, __LINE__, + zbuf.avail_in, zbuf.avail_out); + SDT_PROBE5(opencrypto, deflate, deflate_global, bad, + decomp, error, __LINE__, + zbuf.state->dummy, zbuf.total_out); goto bad; + } } end: result = count = zbuf.total_out; *out = malloc((u_long) result, M_CRYPTO_DATA, M_NOWAIT); - if (*out == NULL) + if (*out == NULL) { + SDT_PROBE3(opencrypto, deflate, deflate_global, bad, + decomp, 0, __LINE__); goto bad; + } if (decomp) inflateEnd(&zbuf); else @@ -160,6 +213,7 @@ end: } } *out = output; + SDT_PROBE2(opencrypto, deflate, deflate_global, return, decomp, result); return result; bad: From 7a955dbf6b2251578a20f944f63c16507bfc3e3e Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 18:59:58 +0000 Subject: [PATCH 0741/2592] MFC r199887: Z_PARTIAL_FLUSH is marked deprecated. Z_SYNC_FLUSH is the suggested replacement but only use it for inflate. For deflate use Z_FINISH as Z_SYNC_FLUSH adds a trailing marker in some cases that inflate(), despite the comment in zlib, does npt seem to cope well with, resulting in errors when uncompressing exactly fills the outbut buffer without a Z_STREAM_END and a successive call returns an error. --- sys/opencrypto/deflate.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/sys/opencrypto/deflate.c b/sys/opencrypto/deflate.c index 239435e06fa..852b66aa26d 100644 --- a/sys/opencrypto/deflate.c +++ b/sys/opencrypto/deflate.c @@ -138,8 +138,8 @@ deflate_global(data, size, decomp, out) goto bad; } for (;;) { - error = decomp ? inflate(&zbuf, Z_PARTIAL_FLUSH) : - deflate(&zbuf, Z_PARTIAL_FLUSH); + error = decomp ? inflate(&zbuf, Z_SYNC_FLUSH) : + deflate(&zbuf, Z_FINISH); if (error != Z_OK && error != Z_STREAM_END) { /* * Unfortunately we are limited to 5 arguments, @@ -153,9 +153,13 @@ deflate_global(data, size, decomp, out) zbuf.state->dummy, zbuf.total_out); goto bad; } - else if (zbuf.avail_in == 0 && zbuf.avail_out != 0) - goto end; - else if (zbuf.avail_out == 0 && i < (ZBUF - 1)) { + if (decomp && zbuf.avail_in == 0 && error == Z_STREAM_END) { + /* Done. */ + break; + } else if (!decomp && error == Z_STREAM_END) { + /* Done. */ + break; + } else if (zbuf.avail_out == 0) { /* we need more output space, allocate size */ buf[i].out = malloc((u_long) size, M_CRYPTO_DATA, M_NOWAIT); @@ -170,6 +174,7 @@ deflate_global(data, size, decomp, out) zbuf.avail_out = buf[i].size; i++; } else { + /* Unexpect result. */ /* * Unfortunately we are limited to 5 arguments, * thus, again, use two probes. @@ -184,7 +189,6 @@ deflate_global(data, size, decomp, out) } } -end: result = count = zbuf.total_out; *out = malloc((u_long) result, M_CRYPTO_DATA, M_NOWAIT); From 8d6960d085835fd7bb4baf2881997e0cacf4b8a2 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:01:50 +0000 Subject: [PATCH 0742/2592] MFC r199895: Change memory managment from a fixed size array to a list. This is needed to avoid running into out of buffer situations where we cannot alloc a new buffer because we hit the array size limit (ZBUF). Use a combined allocation for the struct and the actual data buffer to not increase the number of malloc calls. [1] Defer initialization of zbuf until we actually need it. Make sure the output buffer will be large enough in all cases. Details discussed with: kib [1] Reviewed by: kib [1] --- sys/opencrypto/deflate.c | 125 +++++++++++++++++++++------------------ sys/opencrypto/deflate.h | 10 +++- 2 files changed, 74 insertions(+), 61 deletions(-) diff --git a/sys/opencrypto/deflate.c b/sys/opencrypto/deflate.c index 852b66aa26d..2066eb56f63 100644 --- a/sys/opencrypto/deflate.c +++ b/sys/opencrypto/deflate.c @@ -79,64 +79,59 @@ deflate_global(data, size, decomp, out) z_stream zbuf; u_int8_t *output; u_int32_t count, result; - int error, i = 0, j; - struct deflate_buf buf[ZBUF]; + int error, i; + struct deflate_buf *bufh, *bufp; SDT_PROBE2(opencrypto, deflate, deflate_global, entry, decomp, size); - bzero(&zbuf, sizeof(z_stream)); - for (j = 0; j < ZBUF; j++) - buf[j].flag = 0; - - zbuf.next_in = data; /* data that is going to be processed */ - zbuf.zalloc = z_alloc; - zbuf.zfree = z_free; - zbuf.opaque = Z_NULL; - zbuf.avail_in = size; /* Total length of data to be processed */ - + bufh = bufp = NULL; if (!decomp) { - buf[i].out = malloc((u_long) size, M_CRYPTO_DATA, - M_NOWAIT); - if (buf[i].out == NULL) { - SDT_PROBE3(opencrypto, deflate, deflate_global, bad, - decomp, 0, __LINE__); - goto bad; - } - buf[i].size = size; - buf[i].flag = 1; - i++; + i = 1; } else { /* * Choose a buffer with 4x the size of the input buffer * for the size of the output buffer in the case of * decompression. If it's not sufficient, it will need to be - * updated while the decompression is going on + * updated while the decompression is going on. */ - - buf[i].out = malloc((u_long) (size * 4), - M_CRYPTO_DATA, M_NOWAIT); - if (buf[i].out == NULL) { - SDT_PROBE3(opencrypto, deflate, deflate_global, bad, - decomp, 0, __LINE__); - goto bad; - } - buf[i].size = size * 4; - buf[i].flag = 1; - i++; + i = 4; } + /* + * Make sure we do have enough output space. Repeated calls to + * deflate need at least 6 bytes of output buffer space to avoid + * repeated markers. We will always provide at least 16 bytes. + */ + while ((size * i) < 16) + i++; - zbuf.next_out = buf[0].out; - zbuf.avail_out = buf[0].size; + bufh = bufp = malloc(sizeof(*bufp) + (size_t)(size * i), + M_CRYPTO_DATA, M_NOWAIT); + if (bufp == NULL) { + SDT_PROBE3(opencrypto, deflate, deflate_global, bad, + decomp, 0, __LINE__); + goto bad2; + } + bufp->next = NULL; + bufp->size = size * i; + + bzero(&zbuf, sizeof(z_stream)); + zbuf.zalloc = z_alloc; + zbuf.zfree = z_free; + zbuf.opaque = Z_NULL; + zbuf.next_in = data; /* Data that is going to be processed. */ + zbuf.avail_in = size; /* Total length of data to be processed. */ + zbuf.next_out = bufp->data; + zbuf.avail_out = bufp->size; error = decomp ? inflateInit2(&zbuf, window_inflate) : deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD, window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY); - if (error != Z_OK) { SDT_PROBE3(opencrypto, deflate, deflate_global, bad, decomp, error, __LINE__); goto bad; } + for (;;) { error = decomp ? inflate(&zbuf, Z_SYNC_FLUSH) : deflate(&zbuf, Z_FINISH); @@ -160,19 +155,22 @@ deflate_global(data, size, decomp, out) /* Done. */ break; } else if (zbuf.avail_out == 0) { - /* we need more output space, allocate size */ - buf[i].out = malloc((u_long) size, + struct deflate_buf *p; + + /* We need more output space for another iteration. */ + p = malloc(sizeof(*p) + (size_t)(size * i), M_CRYPTO_DATA, M_NOWAIT); - if (buf[i].out == NULL) { + if (p == NULL) { SDT_PROBE3(opencrypto, deflate, deflate_global, bad, decomp, 0, __LINE__); goto bad; } - zbuf.next_out = buf[i].out; - buf[i].size = size; - buf[i].flag = 1; - zbuf.avail_out = buf[i].size; - i++; + p->next = NULL; + p->size = size * i; + bufp->next = p; + bufp = p; + zbuf.next_out = bufp->data; + zbuf.avail_out = bufp->size; } else { /* Unexpect result. */ /* @@ -191,7 +189,7 @@ deflate_global(data, size, decomp, out) result = count = zbuf.total_out; - *out = malloc((u_long) result, M_CRYPTO_DATA, M_NOWAIT); + *out = malloc(result, M_CRYPTO_DATA, M_NOWAIT); if (*out == NULL) { SDT_PROBE3(opencrypto, deflate, deflate_global, bad, decomp, 0, __LINE__); @@ -202,17 +200,22 @@ deflate_global(data, size, decomp, out) else deflateEnd(&zbuf); output = *out; - for (j = 0; buf[j].flag != 0; j++) { - if (count > buf[j].size) { - bcopy(buf[j].out, *out, buf[j].size); - *out += buf[j].size; - free(buf[j].out, M_CRYPTO_DATA); - count -= buf[j].size; + for (bufp = bufh; bufp != NULL; ) { + if (count > bufp->size) { + struct deflate_buf *p; + + bcopy(bufp->data, *out, bufp->size); + *out += bufp->size; + count -= bufp->size; + p = bufp; + bufp = bufp->next; + free(p, M_CRYPTO_DATA); } else { - /* it should be the last buffer */ - bcopy(buf[j].out, *out, count); + /* It should be the last buffer. */ + bcopy(bufp->data, *out, count); *out += count; - free(buf[j].out, M_CRYPTO_DATA); + free(bufp, M_CRYPTO_DATA); + bufp = NULL; count = 0; } } @@ -221,13 +224,19 @@ deflate_global(data, size, decomp, out) return result; bad: - *out = NULL; - for (j = 0; buf[j].flag != 0; j++) - free(buf[j].out, M_CRYPTO_DATA); if (decomp) inflateEnd(&zbuf); else deflateEnd(&zbuf); + for (bufp = bufh; bufp != NULL; ) { + struct deflate_buf *p; + + p = bufp; + bufp = bufp->next; + free(p, M_CRYPTO_DATA); + } +bad2: + *out = NULL; return 0; } diff --git a/sys/opencrypto/deflate.h b/sys/opencrypto/deflate.h index 5c8ebd41e8d..dcf7a844135 100644 --- a/sys/opencrypto/deflate.h +++ b/sys/opencrypto/deflate.h @@ -47,10 +47,14 @@ u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **); void *z_alloc(void *, u_int, u_int); void z_free(void *, void *); +/* + * We are going to use a combined allocation to hold the metadata + * from the struct immediately followed by the real application data. + */ struct deflate_buf { - u_int8_t *out; - u_int32_t size; - int flag; + struct deflate_buf *next; + uint32_t size; + uint8_t data[]; }; #endif /* _CRYPTO_DEFLATE_H_ */ From eee2ee2ac7dd0c7919cd48f8c851f0306062ed00 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:03:20 +0000 Subject: [PATCH 0743/2592] MFC r199896: Directly send data uncompressed if the packet payload size is lower than the compression algorithm threshold. --- sys/netipsec/xform_ipcomp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c index 4049154ac3e..93a157e77ca 100644 --- a/sys/netipsec/xform_ipcomp.c +++ b/sys/netipsec/xform_ipcomp.c @@ -343,6 +343,17 @@ ipcomp_output( ipcompx = sav->tdb_compalgxform; IPSEC_ASSERT(ipcompx != NULL, ("null compression xform")); + /* + * Do not touch the packet in case our payload to compress + * is lower than the minimal threshold of the compression + * alogrithm. We will just send out the data uncompressed. + * See RFC 3173, 2.2. Non-Expansion Policy. + */ + if (m->m_pkthdr.len <= ipcompx->minlen) { + /* XXX-BZ V_ipcompstat.threshold++; */ + return ipsec_process_done(m, isr); + } + ralen = m->m_pkthdr.len - skip; /* Raw payload length before comp. */ hlen = IPCOMP_HLENGTH; From bc05a8e0202ca526e05a24ab94cca599da06c5bb Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:06:03 +0000 Subject: [PATCH 0744/2592] MFC r199897: Remove whitespace. --- sys/netipsec/xform_ipcomp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c index 93a157e77ca..9b4e475f032 100644 --- a/sys/netipsec/xform_ipcomp.c +++ b/sys/netipsec/xform_ipcomp.c @@ -363,12 +363,12 @@ ipcomp_output( switch (sav->sah->saidx.dst.sa.sa_family) { #ifdef INET case AF_INET: - maxpacketsize = IP_MAXPACKET; + maxpacketsize = IP_MAXPACKET; break; #endif /* INET */ #ifdef INET6 case AF_INET6: - maxpacketsize = IPV6_MAXPACKET; + maxpacketsize = IPV6_MAXPACKET; break; #endif /* INET6 */ default: @@ -565,7 +565,7 @@ ipcomp_output_cb(struct cryptop *crp) DPRINTF(("%s: unknown/unsupported protocol " "family %d, IPCA %s/%08lx\n", __func__, sav->sah->saidx.dst.sa.sa_family, - ipsec_address(&sav->sah->saidx.dst), + ipsec_address(&sav->sah->saidx.dst), (u_long) ntohl(sav->spi))); error = EPFNOSUPPORT; goto bad; From 0b845b93220575be6493b76c8104c28b69cb9988 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:07:28 +0000 Subject: [PATCH 0745/2592] MFC r199899: Only add the IPcomp header if crypto reported success and we have a lower payload size. Before we had always added the header, no matter if we actually send out compressed data or not. With this, after the opencrypto/deflate changes, IPcomp starts to work apart from edge cases. Leave it disabled by default until those are fixed as well. PR: kern/123587 --- sys/netipsec/xform_ipcomp.c | 104 ++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c index 9b4e475f032..5a5f018bafa 100644 --- a/sys/netipsec/xform_ipcomp.c +++ b/sys/netipsec/xform_ipcomp.c @@ -330,13 +330,10 @@ ipcomp_output( { struct secasvar *sav; struct comp_algo *ipcompx; - int error, ralen, hlen, maxpacketsize, roff; - u_int8_t prot; + int error, ralen, maxpacketsize; struct cryptodesc *crdc; struct cryptop *crp; struct tdb_crypto *tc; - struct mbuf *mo; - struct ipcomp *ipcomp; sav = isr->sav; IPSEC_ASSERT(sav != NULL, ("null SA")); @@ -355,8 +352,6 @@ ipcomp_output( } ralen = m->m_pkthdr.len - skip; /* Raw payload length before comp. */ - hlen = IPCOMP_HLENGTH; - V_ipcompstat.ipcomps_output++; /* Check for maximum packet size violations. */ @@ -381,13 +376,13 @@ ipcomp_output( error = EPFNOSUPPORT; goto bad; } - if (skip + hlen + ralen > maxpacketsize) { + if (ralen + skip + IPCOMP_HLENGTH > maxpacketsize) { V_ipcompstat.ipcomps_toobig++; DPRINTF(("%s: packet in IPCA %s/%08lx got too big " "(len %u, max len %u)\n", __func__, ipsec_address(&sav->sah->saidx.dst), (u_long) ntohl(sav->spi), - skip + hlen + ralen, maxpacketsize)); + ralen + skip + IPCOMP_HLENGTH, maxpacketsize)); error = EMSGSIZE; goto bad; } @@ -405,40 +400,7 @@ ipcomp_output( goto bad; } - /* Inject IPCOMP header */ - mo = m_makespace(m, skip, hlen, &roff); - if (mo == NULL) { - V_ipcompstat.ipcomps_wrap++; - DPRINTF(("%s: IPCOMP header inject failed for IPCA %s/%08lx\n", - __func__, ipsec_address(&sav->sah->saidx.dst), - (u_long) ntohl(sav->spi))); - error = ENOBUFS; - goto bad; - } - ipcomp = (struct ipcomp *)(mtod(mo, caddr_t) + roff); - - /* Initialize the IPCOMP header */ - /* XXX alignment always correct? */ - switch (sav->sah->saidx.dst.sa.sa_family) { -#ifdef INET - case AF_INET: - ipcomp->comp_nxt = mtod(m, struct ip *)->ip_p; - break; -#endif /* INET */ -#ifdef INET6 - case AF_INET6: - ipcomp->comp_nxt = mtod(m, struct ip6_hdr *)->ip6_nxt; - break; -#endif - } - ipcomp->comp_flags = 0; - ipcomp->comp_cpi = htons((u_int16_t) ntohl(sav->spi)); - - /* Fix Next Protocol in IPv4/IPv6 header */ - prot = IPPROTO_IPCOMP; - m_copyback(m, protoff, sizeof(u_int8_t), (u_char *) &prot); - - /* Ok now, we can pass to the crypto processing */ + /* Ok now, we can pass to the crypto processing. */ /* Get crypto descriptors */ crp = crypto_getreq(1); @@ -451,10 +413,10 @@ ipcomp_output( crdc = crp->crp_desc; /* Compression descriptor */ - crdc->crd_skip = skip + hlen; - crdc->crd_len = m->m_pkthdr.len - (skip + hlen); + crdc->crd_skip = skip; + crdc->crd_len = ralen; crdc->crd_flags = CRD_F_COMP; - crdc->crd_inject = skip + hlen; + crdc->crd_inject = skip; /* Compression operation */ crdc->crd_alg = ipcompx->type; @@ -474,7 +436,8 @@ ipcomp_output( tc->tc_spi = sav->spi; tc->tc_dst = sav->sah->saidx.dst; tc->tc_proto = sav->sah->saidx.proto; - tc->tc_skip = skip + hlen; + tc->tc_protoff = protoff; + tc->tc_skip = skip; /* Crypto operation descriptor */ crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ @@ -501,13 +464,12 @@ ipcomp_output_cb(struct cryptop *crp) struct ipsecrequest *isr; struct secasvar *sav; struct mbuf *m; - int error, skip, rlen; + int error, skip; tc = (struct tdb_crypto *) crp->crp_opaque; IPSEC_ASSERT(tc != NULL, ("null opaque data area!")); m = (struct mbuf *) crp->crp_buf; skip = tc->tc_skip; - rlen = crp->crp_ilen - skip; isr = tc->tc_isr; IPSECREQUEST_LOCK(isr); @@ -529,8 +491,7 @@ ipcomp_output_cb(struct cryptop *crp) if (crp->crp_etype == EAGAIN) { KEY_FREESAV(&sav); IPSECREQUEST_UNLOCK(isr); - error = crypto_dispatch(crp); - return error; + return crypto_dispatch(crp); } V_ipcompstat.ipcomps_noxform++; DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype)); @@ -546,7 +507,46 @@ ipcomp_output_cb(struct cryptop *crp) } V_ipcompstat.ipcomps_hist[sav->alg_comp]++; - if (rlen > crp->crp_olen) { + if (crp->crp_ilen - skip > crp->crp_olen) { + struct mbuf *mo; + struct ipcomp *ipcomp; + int roff; + uint8_t prot; + + /* Compression helped, inject IPCOMP header. */ + mo = m_makespace(m, skip, IPCOMP_HLENGTH, &roff); + if (mo == NULL) { + V_ipcompstat.ipcomps_wrap++; + DPRINTF(("%s: IPCOMP header inject failed for IPCA %s/%08lx\n", + __func__, ipsec_address(&sav->sah->saidx.dst), + (u_long) ntohl(sav->spi))); + error = ENOBUFS; + goto bad; + } + ipcomp = (struct ipcomp *)(mtod(mo, caddr_t) + roff); + + /* Initialize the IPCOMP header */ + /* XXX alignment always correct? */ + switch (sav->sah->saidx.dst.sa.sa_family) { +#ifdef INET + case AF_INET: + ipcomp->comp_nxt = mtod(m, struct ip *)->ip_p; + break; +#endif /* INET */ +#ifdef INET6 + case AF_INET6: + ipcomp->comp_nxt = mtod(m, struct ip6_hdr *)->ip6_nxt; + break; +#endif + } + ipcomp->comp_flags = 0; + ipcomp->comp_cpi = htons((u_int16_t) ntohl(sav->spi)); + + /* Fix Next Protocol in IPv4/IPv6 header */ + prot = IPPROTO_IPCOMP; + m_copyback(m, tc->tc_protoff, sizeof(u_int8_t), + (u_char *)&prot); + /* Adjust the length in the IP header */ switch (sav->sah->saidx.dst.sa.sa_family) { #ifdef INET @@ -573,6 +573,8 @@ ipcomp_output_cb(struct cryptop *crp) } else { /* compression was useless, we have lost time */ /* XXX add statistic */ + /* XXX remember state to not compress the next couple + * of packets, RFC 3173, 2.2. Non-Expansion Policy */ } /* Release the crypto descriptor */ From d0b0b1b85aff681069c2725f2e1d9c98ff83d52d Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:09:26 +0000 Subject: [PATCH 0746/2592] MFC r199904: Add SDT iter probes forgotten in r199885 (r200138 for stable/8). --- sys/opencrypto/deflate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/opencrypto/deflate.c b/sys/opencrypto/deflate.c index 2066eb56f63..2113611ae0d 100644 --- a/sys/opencrypto/deflate.c +++ b/sys/opencrypto/deflate.c @@ -148,6 +148,12 @@ deflate_global(data, size, decomp, out) zbuf.state->dummy, zbuf.total_out); goto bad; } + SDT_PROBE5(opencrypto, deflate, deflate_global, iter, + decomp, error, __LINE__, + zbuf.avail_in, zbuf.avail_out); + SDT_PROBE5(opencrypto, deflate, deflate_global, iter, + decomp, error, __LINE__, + zbuf.state->dummy, zbuf.total_out); if (decomp && zbuf.avail_in == 0 && error == Z_STREAM_END) { /* Done. */ break; From 99808bdf69dba2f5d0d20a399475648d31540529 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:11:02 +0000 Subject: [PATCH 0747/2592] MFC r199905: Assimilate very similar input and output code paths (no real functional change). --- sys/netipsec/xform_ipcomp.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c index 5a5f018bafa..2dc18de6a6b 100644 --- a/sys/netipsec/xform_ipcomp.c +++ b/sys/netipsec/xform_ipcomp.c @@ -249,10 +249,8 @@ ipcomp_input_cb(struct cryptop *crp) if (crp->crp_etype == EAGAIN) { KEY_FREESAV(&sav); - error = crypto_dispatch(crp); - return error; + return crypto_dispatch(crp); } - V_ipcompstat.ipcomps_noxform++; DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype)); error = crp->crp_etype; @@ -484,7 +482,7 @@ ipcomp_output_cb(struct cryptop *crp) /* Check for crypto errors */ if (crp->crp_etype) { - /* Reset session ID */ + /* Reset the session ID */ if (sav->tdb_cryptoid != 0) sav->tdb_cryptoid = crp->crp_sid; From e55ea9c811cb9d323d9220cc1d26bcf286e0a22a Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:12:35 +0000 Subject: [PATCH 0748/2592] MFC r199906: In case the compression result is the same size as the orignal version, the compression was useless as well. Make sure to not update the data and return, else we would waste resources when decompressing. This also avoids the copyback() changing data other consumers like xform_ipcomp.c would have ignored because of no win and sent out without noting that compression was used, resulting in invalid packets at the receiver. --- sys/opencrypto/cryptosoft.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index 2769be6672d..97b73a214f4 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -552,7 +552,7 @@ swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw, sw->sw_size = result; /* Check the compressed size when doing compression */ if (crd->crd_flags & CRD_F_COMP) { - if (result > crd->crd_len) { + if (result >= crd->crd_len) { /* Compression was useless, we lost time */ free(out, M_CRYPTO_DATA); return 0; From 87d7d0abb53f0073a92ca2d7956be0a0112021f0 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:21:58 +0000 Subject: [PATCH 0749/2592] MFC r199946: Add more statistics variables for IPcomp. Try to version the struct in a backward compatible way. People asked for the versioning of the stats structs in general before. Note: old netstat binaries, as only consumer, continue to work as they are still using kvm but will not display the new stats. [1] Discussed with: rwatson [1] --- sys/netipsec/ipcomp_var.h | 4 ++++ sys/netipsec/xform_ipcomp.c | 18 +++++++++++++++--- usr.bin/netstat/ipsec.c | 10 ++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/sys/netipsec/ipcomp_var.h b/sys/netipsec/ipcomp_var.h index a9dbe86f6e1..78f18488221 100644 --- a/sys/netipsec/ipcomp_var.h +++ b/sys/netipsec/ipcomp_var.h @@ -41,6 +41,7 @@ */ #define IPCOMP_ALG_MAX 8 +#define IPCOMPSTAT_VERSION 1 struct ipcompstat { u_int32_t ipcomps_hdrops; /* Packet shorter than header shows */ u_int32_t ipcomps_nopf; /* Protocol family not supported */ @@ -58,6 +59,9 @@ struct ipcompstat { u_int32_t ipcomps_pdrops; /* Packet blocked due to policy */ u_int32_t ipcomps_crypto; /* "Crypto" processing failure */ u_int32_t ipcomps_hist[IPCOMP_ALG_MAX];/* Per-algorithm op count */ + u_int32_t version; /* Version of this structure. */ + u_int32_t ipcomps_threshold; /* Packet < comp. algo. threshold. */ + u_int32_t ipcomps_uncompr; /* Compression was useles. */ }; #ifdef _KERNEL diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c index 2dc18de6a6b..4d21e381ba2 100644 --- a/sys/netipsec/xform_ipcomp.c +++ b/sys/netipsec/xform_ipcomp.c @@ -345,7 +345,7 @@ ipcomp_output( * See RFC 3173, 2.2. Non-Expansion Policy. */ if (m->m_pkthdr.len <= ipcompx->minlen) { - /* XXX-BZ V_ipcompstat.threshold++; */ + V_ipcompstat.ipcomps_threshold++; return ipsec_process_done(m, isr); } @@ -569,8 +569,10 @@ ipcomp_output_cb(struct cryptop *crp) goto bad; } } else { - /* compression was useless, we have lost time */ - /* XXX add statistic */ + /* Compression was useless, we have lost time. */ + V_ipcompstat.ipcomps_uncompr++; + DPRINTF(("%s: compressions was useless %d - %d <= %d\n", + __func__, crp->crp_ilen, skip, crp->crp_olen)); /* XXX remember state to not compress the next couple * of packets, RFC 3173, 2.2. Non-Expansion Policy */ } @@ -609,3 +611,13 @@ ipcomp_attach(void) } SYSINIT(ipcomp_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ipcomp_attach, NULL); + +static void +vnet_ipcomp_attach(const void *unused __unused) +{ + + V_ipcompstat.version = IPCOMPSTAT_VERSION; +} + +VNET_SYSINIT(vnet_ipcomp_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, + vnet_ipcomp_attach, NULL); diff --git a/usr.bin/netstat/ipsec.c b/usr.bin/netstat/ipsec.c index bfd8ce01ee8..d3276bf2761 100644 --- a/usr.bin/netstat/ipsec.c +++ b/usr.bin/netstat/ipsec.c @@ -418,6 +418,7 @@ esp_stats(u_long off, const char *name, int family __unused, int proto __unused) static void print_ipcompstats(const struct ipcompstat *ipcompstat) { + uint32_t version; #define p32(f, m) if (ipcompstat->f || sflag <= 1) \ printf("\t%u" m, (unsigned int)ipcompstat->f, plural(ipcompstat->f)) #define p64(f, m) if (ipcompstat->f || sflag <= 1) \ @@ -425,6 +426,11 @@ print_ipcompstats(const struct ipcompstat *ipcompstat) #define hist(f, n, t) \ ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t)); +#ifndef IPCOMPSTAT_VERSION + version = 0; +#else + version = ipcompstat->version; +#endif p32(ipcomps_hdrops, " packet%s shorter than header shows\n"); p32(ipcomps_nopf, " packet%s dropped; protocol family not supported\n"); p32(ipcomps_notdb, " packet%s dropped; no TDB\n"); @@ -441,6 +447,10 @@ print_ipcompstats(const struct ipcompstat *ipcompstat) p32(ipcomps_pdrops, " packet%s blocked due to policy\n"); p32(ipcomps_crypto, " crypto processing failure%s\n"); hist(ipcompstat->ipcomps_hist, ipsec_compnames, "COMP output"); + if (version >= 1) { + p32(ipcomps_threshold, " packet%s sent uncompressed; size < compr. algo. threshold\n"); + p32(ipcomps_uncompr, " packet%s sent uncompressed; compression was useless\n"); + } #undef p32 #undef p64 From 3b558c96ce35d39e105be3bb6f42718bea3dbea9 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:25:29 +0000 Subject: [PATCH 0750/2592] MFC r199947, 199950: Enable IPcomp by default. PR: kern/123587 --- share/man/man4/ipsec.4 | 8 +++++--- sys/netipsec/xform_ipcomp.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/share/man/man4/ipsec.4 b/share/man/man4/ipsec.4 index 47ccdb1082b..112fadb9522 100644 --- a/share/man/man4/ipsec.4 +++ b/share/man/man4/ipsec.4 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 23, 2009 +.Dd November 29, 2009 .Dt IPSEC 4 .Os .Sh NAME @@ -215,7 +215,7 @@ To selectively enable/disable protocols, use .It Sy "Name Default" .It "net.inet.esp.esp_enable On" .It "net.inet.ah.ah_enable On" -.It "net.inet.ipcomp.ipcomp_enable Off" +.It "net.inet.ipcomp.ipcomp_enable On" .El .Pp In addition the following variables are accessible via @@ -408,6 +408,8 @@ size may alleviate this problem. .Pp The .Tn IPcomp -protocol support is currently broken. +protocol may occasionally error because of +.Xr zlib 3 +problems. .Pp This documentation needs more review. diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c index 4d21e381ba2..d528d2abd60 100644 --- a/sys/netipsec/xform_ipcomp.c +++ b/sys/netipsec/xform_ipcomp.c @@ -68,7 +68,7 @@ #include #include -VNET_DEFINE(int, ipcomp_enable) = 0; +VNET_DEFINE(int, ipcomp_enable) = 1; VNET_DEFINE(struct ipcompstat, ipcompstat); SYSCTL_DECL(_net_inet_ipcomp); From 4fe9cf96e9aff564e2c7e5316aa4b1b897fbaa7e Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:42:42 +0000 Subject: [PATCH 0751/2592] MFC r198076: Explicitly compare to a return code. Discussed with: philip (after we both misread the logic there the 1st time) --- 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 b4e227f473887325e5613962feed02925667bbca Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 19:44:16 +0000 Subject: [PATCH 0752/2592] MFC r198050: Compare pointer to NULL rather than 0. --- 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 a1778929b71307eb238df4f027d92d221a292045 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 20:37:46 +0000 Subject: [PATCH 0753/2592] MFC r197518: lindev(4) [1] is supposed to be a collection of linux-specific pseudo devices that we also support, just not by default (thus only LINT or module builds by default). While currently there is only "/dev/full" [2], we are planning to see more in the future. We may decide to change the module/dependency logic in the future should the list grow too long. This is not part of linux.ko as also non-linux binaries like kFreeBSD userland or ports can make use of this as well. Suggested by: rwatson [1] (name) Submitted by: ed [2] Discussed with: markm, ed, rwatson, kib (weeks ago) Reviewed by: rwatson, brueffer (prev. version) PR: kern/68961 --- share/man/man4/Makefile | 4 ++ share/man/man4/lindev.4 | 73 +++++++++++++++++++++++++ sys/amd64/conf/NOTES | 3 ++ sys/boot/forth/loader.conf | 1 + sys/conf/files.amd64 | 2 + sys/conf/files.i386 | 2 + sys/conf/files.pc98 | 2 + sys/dev/lindev/full.c | 103 ++++++++++++++++++++++++++++++++++++ sys/dev/lindev/lindev.c | 73 +++++++++++++++++++++++++ sys/dev/lindev/lindev.h | 34 ++++++++++++ sys/i386/conf/NOTES | 3 ++ sys/modules/Makefile | 3 ++ sys/modules/lindev/Makefile | 8 +++ sys/pc98/conf/NOTES | 3 ++ 14 files changed, 314 insertions(+) create mode 100644 share/man/man4/lindev.4 create mode 100644 sys/dev/lindev/full.c create mode 100644 sys/dev/lindev/lindev.c create mode 100644 sys/dev/lindev/lindev.h create mode 100644 sys/modules/lindev/Makefile diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index c46f4b9c30a..50b707c3284 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -173,6 +173,7 @@ MAN= aac.4 \ le.4 \ led.4 \ lge.4 \ + ${_lindev.4} \ ${_linux.4} \ lmc.4 \ lo.4 \ @@ -624,6 +625,7 @@ _if_urtw.4= if_urtw.4 _if_wpi.4= if_wpi.4 _ipmi.4= ipmi.4 _io.4= io.4 +_lindev.4= lindev.4 _linux.4= linux.4 _ndis.4= ndis.4 _nfe.4= nfe.4 @@ -635,6 +637,8 @@ _speaker.4= speaker.4 _spkr.4= spkr.4 _urtw.4= urtw.4 _wpi.4= wpi.4 + +MLINKS+=lindev.4 full.4 .endif .if exists(${.CURDIR}/man4.${MACHINE_ARCH}) diff --git a/share/man/man4/lindev.4 b/share/man/man4/lindev.4 new file mode 100644 index 00000000000..b2dc60efc80 --- /dev/null +++ b/share/man/man4/lindev.4 @@ -0,0 +1,73 @@ +.\"- +.\" Copyright (c) 2009 "Bjoern A. Zeeb" +.\" 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 September 26, 2009 +.Dt LINDEV 4 +.Os +.Sh NAME +.Nm lindev +.Nd the lindev module +.Sh SYNOPSIS +To compile this collection of linux-specific pseudo devices into the kernel, +place the following line in your kernel configuration file: +.Bd -ragged -offset indent +.Cd "device lindev" +.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 +lindev_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +module provides a collection of linux-specific pseudo devices. +.Sh DEVICES +.Bl -tag -width /dev/full +.It Pa /dev/full +The +.Xr full +device always returns +.Er ENOSPC +on write attempts. +For reads it emulates +.Xr zero 4 . +.El +.Sh FILES +.Bl -tag -width /dev/full +.It Pa /dev/full +.El +.Sh SEE ALSO +.Xr null 4 , +.Xr zero 4 +.Sh HISTORY +The +.Nm +module first appeared in +.Fx 9.0 . diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index 27fe0680580..536122451af 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -503,3 +503,6 @@ options VM_KMEM_SIZE_SCALE # Enable NDIS binary driver support options NDISAPI device ndis + +# Linux-specific pseudo devices support +device lindev diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index 862e86ffa21..44eef5fb9b1 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -179,6 +179,7 @@ screensave_name="green_saver" # Set to the name of the screensaver module ibcs2_load="NO" # IBCS2 (SCO) emulation ibcs2_coff_load="NO" linux_load="NO" # Linux emulation +lindev_load="NO" # Linux-specific pseudo devices (see lindev(4)) svr4_load="NO" # SystemV R4 emulation streams_load="NO" # System V streams module diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index be1aff5801d..c22a213c4e8 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -205,6 +205,8 @@ dev/hwpmc/hwpmc_piv.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc dev/kbd/kbd.c optional atkbd | sc | ukbd | usb2_input_kbd +dev/lindev/full.c optional lindev +dev/lindev/lindev.c optional lindev dev/mem/memutil.c optional mem dev/nfe/if_nfe.c optional nfe pci dev/nve/if_nve.c optional nve pci diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 88bd1f148f7..91d42a10bd0 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -198,6 +198,8 @@ dev/ipmi/ipmi_pci.c optional ipmi pci dev/ipmi/ipmi_linux.c optional ipmi compat_linux dev/kbd/kbd.c optional atkbd | sc | ukbd | usb2_input_kbd dev/le/if_le_isa.c optional le isa +dev/lindev/full.c optional lindev +dev/lindev/lindev.c optional lindev dev/mem/memutil.c optional mem dev/mse/mse.c optional mse dev/mse/mse_isa.c optional mse isa diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 7aedb38517a..7f2afc5059c 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -107,6 +107,8 @@ dev/hwpmc/hwpmc_x86.c optional hwpmc dev/io/iodev.c optional io dev/kbd/kbd.c optional pckbd | sc | ukbd | usb2_input_kbd dev/le/if_le_cbus.c optional le isa +dev/lindev/full.c optional lindev +dev/lindev/lindev.c optional lindev dev/mem/memutil.c optional mem dev/mse/mse.c optional mse dev/mse/mse_cbus.c optional mse isa diff --git a/sys/dev/lindev/full.c b/sys/dev/lindev/full.c new file mode 100644 index 00000000000..294094c075d --- /dev/null +++ b/sys/dev/lindev/full.c @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 2009 Ed Schouten + * 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 + +static struct cdev *full_dev; + +static d_read_t full_read; +static d_write_t full_write; + +static struct cdevsw full_cdevsw = { + .d_version = D_VERSION, + .d_read = full_read, + .d_write = full_write, + .d_name = "full", +}; + +static void *zbuf; + +/* ARGSUSED */ +static int +full_read(struct cdev *dev __unused, struct uio *uio, int flags __unused) +{ + int error = 0; + + while (uio->uio_resid > 0 && error == 0) + error = uiomove(zbuf, MIN(uio->uio_resid, PAGE_SIZE), uio); + + return (error); +} + +/* ARGSUSED */ +static int +full_write(struct cdev *dev __unused, struct uio *uio __unused, + int flags __unused) +{ + + return (ENOSPC); +} + +/* ARGSUSED */ +int +lindev_modevent_full(module_t mod __unused, int type, void *data __unused) +{ + + switch(type) { + case MOD_LOAD: + zbuf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK | M_ZERO); + full_dev = make_dev(&full_cdevsw, 0, UID_ROOT, GID_WHEEL, + 0666, "full"); + if (bootverbose) + printf("full: \n"); + break; + + case MOD_UNLOAD: + destroy_dev(full_dev); + free(zbuf, M_TEMP); + break; + + case MOD_SHUTDOWN: + break; + + default: + return (EOPNOTSUPP); + } + + return (0); +} + diff --git a/sys/dev/lindev/lindev.c b/sys/dev/lindev/lindev.c new file mode 100644 index 00000000000..cf876042ae9 --- /dev/null +++ b/sys/dev/lindev/lindev.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2009 "Bjoern A. Zeeb" + * 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. + */ + +/* + * "lindev" is supposed to be a collection of linux-specific devices + * that we also support, just not by default. + * While currently there is only "/dev/full", we are planning to see + * more in the future. + * This file is only the container to load/unload all supported devices; + * the implementation of each should go into its own file. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include + +/* ARGSUSED */ +static int +lindev_modevent(module_t mod, int type, void *data) +{ + int error; + + switch(type) { + case MOD_LOAD: + error = lindev_modevent_full(mod, type, data); + break; + + case MOD_UNLOAD: + error = lindev_modevent_full(mod, type, data); + break; + + case MOD_SHUTDOWN: + error = lindev_modevent_full(mod, type, data); + break; + + default: + return (EOPNOTSUPP); + } + + return (error); +} + +DEV_MODULE(lindev, lindev_modevent, NULL); +MODULE_VERSION(lindev, 1); diff --git a/sys/dev/lindev/lindev.h b/sys/dev/lindev/lindev.h new file mode 100644 index 00000000000..9b0be8250a0 --- /dev/null +++ b/sys/dev/lindev/lindev.h @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2009 "Bjoern A. Zeeb" + * 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 _DEV_LINDEV_LINDEV_H +#define _DEV_LINDEV_LINDEV_H + +int lindev_modevent_full(module_t, int, void *); + +#endif /* _DEV_LINDEV_LINDEV_H */ diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 4c71a81941e..b7f240930cc 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -876,6 +876,9 @@ device streams # STREAMS network driver (required for svr4). options NDISAPI device ndis +# Linux-specific pseudo devices support +device lindev + ##################################################################### # VM OPTIONS diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 089450acba4..eca7b6b6f4a 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -150,6 +150,7 @@ SUBDIR= ${_3dfx} \ libiconv \ libmbpool \ libmchain \ + ${_lindev} \ ${_linprocfs} \ ${_linsysfs} \ ${_linux} \ @@ -370,6 +371,7 @@ _ie= ie _if_ndis= if_ndis _igb= igb _io= io +_lindev= lindev _linprocfs= linprocfs _linsysfs= linsysfs _linux= linux @@ -505,6 +507,7 @@ _ipwfw= ipwfw _iwn= iwn _iwnfw= iwnfw _ixgb= ixgb +_lindev= lindev _linprocfs= linprocfs _linsysfs= linsysfs _linux= linux diff --git a/sys/modules/lindev/Makefile b/sys/modules/lindev/Makefile new file mode 100644 index 00000000000..704cac331dc --- /dev/null +++ b/sys/modules/lindev/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/lindev + +KMOD= lindev +SRCS= full.c lindev.c + +.include diff --git a/sys/pc98/conf/NOTES b/sys/pc98/conf/NOTES index 9ab70b9e5d1..990fc94a2ea 100644 --- a/sys/pc98/conf/NOTES +++ b/sys/pc98/conf/NOTES @@ -565,6 +565,9 @@ options COMPAT_SVR4 # build emulator statically options DEBUG_SVR4 # enable verbose debugging device streams # STREAMS network driver (required for svr4). +# Linux-specific pseudo devices support +device lindev + ##################################################################### # VM OPTIONS From 8cb7f89dbb123553deaab2afe117a0fa5bfe1346 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 20:40:28 +0000 Subject: [PATCH 0754/2592] MFC r197726: Print a warning in case we cannot add more brandinfo because we would overflow the MAX_BRANDS sized array. Reviewed by: kib --- 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 8d5820b4b16..56cd66f254f 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 c4de0a57f3db2d160c9f5fdfa6bdcb1c166748a5 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 5 Dec 2009 20:43:15 +0000 Subject: [PATCH 0755/2592] MFC r197729: 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 --- 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 3b3920bc3cb75ffa3f821c8fa69527b168bd2181 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Sun, 6 Dec 2009 01:45:55 +0000 Subject: [PATCH 0756/2592] MFC r199237, r199238, r199239, r199240, r200003 r199237: sc->rev and is_offload(sc) will always be 0 during probe. Wait till attach to get correct values. r199238: Make sure *some* edc is setup even for an unknown transceiver (assume it is optical). r199239: The 10GBASE-T card should use an IPG of 1. Also enable the check for low power startup on this card. r199240: Don't disable the XGMAC's tx on ifconfig down. It is unnecessary and can cause false backpressure in the chip. Fix a us/ms mixup while here. r200003: T3 firmware 7.8.0 for cxgb(4) --- sys/dev/cxgb/common/cxgb_ael1002.c | 4 +- sys/dev/cxgb/common/cxgb_aq100x.c | 2 - sys/dev/cxgb/common/cxgb_common.h | 2 +- sys/dev/cxgb/common/cxgb_xgmac.c | 2 +- sys/dev/cxgb/cxgb_main.c | 6 +- sys/dev/cxgb/cxgb_t3fw.h | 1459 ++++++++++++++-------------- 6 files changed, 745 insertions(+), 730 deletions(-) diff --git a/sys/dev/cxgb/common/cxgb_ael1002.c b/sys/dev/cxgb/common/cxgb_ael1002.c index d7bb3869831..ec5ffe7aedb 100644 --- a/sys/dev/cxgb/common/cxgb_ael1002.c +++ b/sys/dev/cxgb/common/cxgb_ael1002.c @@ -1270,7 +1270,7 @@ static int ael2005_reset(struct cphy *phy, int wait) return err; phy->modtype = (u8)err; - if (err == phy_modtype_none || err == phy_modtype_unknown) + if (err == phy_modtype_none) err = 0; else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) err = ael2005_setup_twinax_edc(phy, err); @@ -1981,7 +1981,7 @@ static int ael2020_reset(struct cphy *phy, int wait) if (err < 0) return err; phy->modtype = (u8)err; - if (err == phy_modtype_none || err == phy_modtype_unknown) + if (err == phy_modtype_none) err = 0; else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) err = ael2020_setup_twinax_edc(phy, err); diff --git a/sys/dev/cxgb/common/cxgb_aq100x.c b/sys/dev/cxgb/common/cxgb_aq100x.c index abb93c4055f..46f07ca1530 100644 --- a/sys/dev/cxgb/common/cxgb_aq100x.c +++ b/sys/dev/cxgb/common/cxgb_aq100x.c @@ -515,13 +515,11 @@ t3_aq100x_phy_prep(pinfo_t *pinfo, int phy_addr, 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. diff --git a/sys/dev/cxgb/common/cxgb_common.h b/sys/dev/cxgb/common/cxgb_common.h index 1aa3642ea9d..2f55e9fec66 100644 --- a/sys/dev/cxgb/common/cxgb_common.h +++ b/sys/dev/cxgb/common/cxgb_common.h @@ -97,7 +97,7 @@ enum { enum { FW_VERSION_MAJOR = 7, - FW_VERSION_MINOR = 7, + FW_VERSION_MINOR = 8, FW_VERSION_MICRO = 0 }; diff --git a/sys/dev/cxgb/common/cxgb_xgmac.c b/sys/dev/cxgb/common/cxgb_xgmac.c index e323c9b2685..853da35ddfe 100644 --- a/sys/dev/cxgb/common/cxgb_xgmac.c +++ b/sys/dev/cxgb/common/cxgb_xgmac.c @@ -508,7 +508,7 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) thres /= 10; thres = mtu > thres ? (mtu - thres + 7) / 8 : 0; thres = max(thres, 8U); /* need at least 8 */ - ipg = (adap->params.rev == T3_REV_C) ? 0 : 1; + ipg = (port_type == 9 || adap->params.rev != T3_REV_C) ? 1 : 0; t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset, V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG), V_TXFIFOTHRESH(thres) | V_TXIPG(ipg)); diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 26d4b508c0a..5c763400c2d 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -1989,14 +1989,14 @@ cxgb_uninit_synchronized(struct port_info *pi) t3_set_reg_field(sc, A_XGM_RXFIFO_CFG + pi->mac.offset, V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM), 0); - DELAY(100); + DELAY(100 * 1000); /* Wait for TXFIFO empty */ t3_wait_op_done(sc, A_XGM_TXFIFO_CFG + pi->mac.offset, F_TXFIFO_EMPTY, 1, 20, 5); - DELAY(100); - t3_mac_disable(&pi->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); + DELAY(100 * 1000); + t3_mac_disable(&pi->mac, MAC_DIRECTION_RX); pi->phy.ops->power_down(&pi->phy, 1); diff --git a/sys/dev/cxgb/cxgb_t3fw.h b/sys/dev/cxgb/cxgb_t3fw.h index 6af06191f99..66c86ce6b82 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 = 30772; -static unsigned char t3fw[30772] = { +static unsigned int t3fw_length = 30840; +static unsigned char t3fw[30840] = { 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[30772] = { 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 0x6B, U 0xE8, + U 0x20, U 0x00, U 0x6C, U 0x34, U 0x1F, U 0xFF, U 0xC2, U 0x90, - U 0x20, U 0x00, U 0x6C, U 0x30, + U 0x20, U 0x00, U 0x6C, U 0x7C, U 0x1F, U 0xFF, U 0xC2, U 0x94, - U 0x20, U 0x00, U 0x6C, U 0x70, + U 0x20, U 0x00, U 0x6C, U 0xBC, U 0x1F, U 0xFF, U 0xC2, U 0x98, - U 0x20, U 0x00, U 0x6C, U 0xE4, + U 0x20, U 0x00, U 0x6D, U 0x30, U 0x1F, U 0xFF, U 0xC2, U 0x9C, U 0x20, U 0x00, U 0x03, U 0xC0, U 0xC0, U 0x00, U 0x00, U 0xE4, @@ -396,11 +396,11 @@ static unsigned char t3fw[30772] = { U 0x20, U 0x00, U 0x03, U 0xB0, U 0xE3, U 0x00, U 0x0D, U 0x3C, U 0x20, U 0x00, U 0x03, U 0xB0, - U 0x20, U 0x00, U 0x6E, U 0x08, + U 0x20, U 0x00, U 0x6E, U 0x54, 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 0x20, U 0x00, U 0x6E, U 0x54, + U 0x20, U 0x00, U 0x6E, U 0x54, + U 0xE3, U 0x00, U 0x77, U 0xE0, 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[30772] = { 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 0x6E, U 0x08, - U 0x20, U 0x00, U 0x6E, U 0x08, + U 0x20, U 0x00, U 0x6E, U 0x58, + U 0x20, U 0x00, U 0x6E, U 0x58, U 0xDE, U 0xFF, U 0xFE, U 0x00, U 0x00, U 0x00, U 0x08, U 0x0C, U 0xDE, U 0xAD, U 0xBE, U 0xEF, @@ -616,47 +616,47 @@ static unsigned char t3fw[30772] = { 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 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 0x20, U 0x00, U 0x55, U 0x54, + U 0x20, U 0x00, U 0x54, U 0x24, + U 0x20, U 0x00, U 0x55, U 0x54, + U 0x20, U 0x00, U 0x55, U 0x54, + U 0x20, U 0x00, U 0x53, U 0x60, + U 0x20, U 0x00, U 0x53, U 0x60, + U 0x20, U 0x00, U 0x53, U 0x60, + U 0x20, U 0x00, U 0x51, U 0xA0, + U 0x20, U 0x00, U 0x51, U 0xA0, + U 0x20, U 0x00, U 0x51, U 0x98, + U 0x20, U 0x00, U 0x51, U 0x04, + U 0x20, U 0x00, U 0x4F, U 0xAC, + U 0x20, U 0x00, U 0x4D, U 0x8C, + U 0x20, U 0x00, U 0x4B, U 0x60, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, - 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 0x20, U 0x00, U 0x55, U 0x24, + U 0x20, U 0x00, U 0x53, U 0xF0, + U 0x20, U 0x00, U 0x54, U 0x94, + U 0x20, U 0x00, U 0x54, U 0x94, + U 0x20, U 0x00, U 0x52, U 0x48, + U 0x20, U 0x00, U 0x52, U 0x48, + U 0x20, U 0x00, U 0x52, U 0x48, + U 0x20, U 0x00, U 0x52, U 0x48, + U 0x20, U 0x00, U 0x52, U 0x48, + U 0x20, U 0x00, U 0x51, U 0x90, + U 0x20, U 0x00, U 0x52, U 0x48, + U 0x20, U 0x00, U 0x4E, U 0xCC, + U 0x20, U 0x00, U 0x4D, U 0x3C, + U 0x20, U 0x00, U 0x4B, U 0x0C, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, 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 0x46, U 0xFC, 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 0x46, U 0xBC, + U 0x20, U 0x00, U 0x4A, U 0xE8, U 0x20, U 0x00, U 0x3E, U 0xCC, U 0x20, U 0x00, U 0x3D, U 0xE8, U 0x20, U 0x00, U 0x3A, U 0x24, @@ -666,7 +666,7 @@ static unsigned char t3fw[30772] = { 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 0x67, U 0xD8, U 0x20, U 0x00, U 0x23, U 0xD0, U 0x20, U 0x00, U 0x20, U 0xB0, U 0x20, U 0x00, U 0x20, U 0x5C, @@ -851,22 +851,22 @@ static unsigned char t3fw[30772] = { 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 0x6B, U 0xC4, + U 0x20, U 0x00, U 0x6C, U 0x10, U 0x10, U 0xFF, U 0xFF, U 0x0A, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x20, U 0x00, U 0x6B, U 0xE8, + U 0x20, U 0x00, U 0x6C, U 0x34, 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 0x6C, U 0x30, + U 0x20, U 0x00, U 0x6C, U 0x7C, 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 0x6C, U 0x70, + U 0x20, U 0x00, U 0x6C, U 0xBC, 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 0x6C, U 0xE4, + U 0x20, U 0x00, U 0x6D, U 0x30, U 0x00, U 0xD5, U 0x31, U 0x10, U 0xFF, U 0xFE, U 0x0A, U 0x00, U 0x00, U 0x00, U 0x00, U 0x00, @@ -893,8 +893,8 @@ static unsigned char t3fw[30772] = { 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 0xD3, - U 0x54, U 0x1A, U 0x7E, U 0x0F, + U 0xF8, U 0x54, U 0x15, U 0xE6, + U 0x54, U 0x1A, U 0x91, 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, @@ -1107,7 +1107,7 @@ static unsigned char t3fw[30772] = { 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 0x19, U 0x91, + U 0x50, U 0x58, U 0x19, U 0xA4, U 0xC0, U 0xD0, U 0xC0, U 0x90, U 0x2E, U 0x5C, U 0xF4, U 0x2C, U 0x12, U 0x17, U 0x28, U 0x12, @@ -1345,7 +1345,7 @@ static unsigned char t3fw[30772] = { U 0xFC, U 0x2A, U 0x00, U 0x00, U 0x64, U 0x50, U 0xC0, U 0xDA, U 0x20, U 0xDB, U 0xC0, U 0x58, - U 0x16, U 0x65, U 0xC0, U 0x20, + U 0x16, U 0x78, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xC0, U 0x91, U 0x63, U 0xFD, U 0x7A, U 0x00, U 0xC0, U 0x91, U 0x63, U 0xFA, @@ -1354,7 +1354,7 @@ static unsigned char t3fw[30772] = { U 0x0A, U 0x80, U 0xC0, U 0x9A, U 0x29, U 0x24, U 0x68, U 0x2C, U 0x70, U 0x07, U 0x58, U 0x15, - U 0x55, U 0xD2, U 0xA0, U 0xD1, + U 0x68, 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, @@ -1362,7 +1362,7 @@ static unsigned char t3fw[30772] = { U 0xF8, U 0xD9, U 0xB0, U 0x63, U 0xFA, U 0x61, U 0x00, U 0x00, U 0x2A, U 0x2C, U 0x74, U 0xDB, - U 0x40, U 0x58, U 0x0E, U 0xD1, + U 0x40, U 0x58, U 0x0E, U 0xE3, U 0x63, U 0xFA, U 0xE4, U 0x00, U 0x00, U 0x29, U 0x22, U 0x1D, U 0x2D, U 0x25, U 0x02, U 0x7B, @@ -1386,7 +1386,7 @@ static unsigned char t3fw[30772] = { 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 0x07, U 0x58, U 0x15, U 0x47, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xC0, U 0x94, U 0x63, U 0xFB, U 0xC9, U 0xC0, U 0x96, U 0x63, @@ -1472,7 +1472,7 @@ static unsigned char t3fw[30772] = { 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 0x0E, U 0x64, U 0xD2, U 0xA0, + U 0x0E, U 0x76, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, U 0x29, U 0xCC, U 0xF9, @@ -1497,26 +1497,26 @@ static unsigned char t3fw[30772] = { 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 0x15, U 0x3A, + U 0x40, U 0x58, U 0x15, U 0x4D, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x15, U 0xC9, + U 0xB6, U 0x58, U 0x15, U 0xDC, U 0x63, U 0xFF, U 0xE5, U 0x00, U 0xDA, U 0x20, U 0x58, U 0x15, - U 0xC7, U 0x63, U 0xFF, U 0xDC, + U 0xDA, 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 0x16, U 0x55, + U 0x50, U 0x58, U 0x16, U 0x68, 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 0xBA, 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 0x14, U 0x53, U 0x1D, U 0xEC, + U 0x14, U 0x66, 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, @@ -1527,7 +1527,7 @@ static unsigned char t3fw[30772] = { 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 0x5B, 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, @@ -1535,7 +1535,7 @@ static unsigned char t3fw[30772] = { 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 0x14, U 0x53, 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, @@ -1574,7 +1574,7 @@ static unsigned char t3fw[30772] = { U 0xAC, U 0xFD, U 0x65, U 0xA0, U 0xC2, U 0xCC, U 0x5F, U 0xDB, U 0x30, U 0xDA, U 0x20, U 0x8C, - U 0x11, U 0x58, U 0x14, U 0xED, + U 0x11, U 0x58, U 0x15, U 0x00, U 0xC0, U 0x51, U 0x9A, U 0x13, U 0xC7, U 0xBF, U 0x9B, U 0xA9, U 0x8E, U 0x13, U 0x2E, U 0xE2, @@ -1613,19 +1613,19 @@ static unsigned char t3fw[30772] = { 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 0x15, U 0x58, U 0xC9, + U 0x58, U 0x15, U 0x6B, 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 0xB6, U 0x58, U 0x15, U 0x68, U 0x60, U 0x00, U 0x0C, U 0x00, U 0xC0, U 0x90, U 0x63, U 0xFF, U 0xB5, U 0x00, U 0x00, U 0xDA, - U 0x20, U 0x58, U 0x15, U 0x51, + U 0x20, U 0x58, U 0x15, U 0x64, 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 0x51, U 0x58, U 0x13, U 0xD6, U 0x9A, U 0x13, U 0x64, U 0xA1, U 0xCE, U 0xC7, U 0x5F, U 0x8F, U 0xA1, U 0x95, U 0xA9, U 0xC0, @@ -1643,7 +1643,7 @@ static unsigned char t3fw[30772] = { U 0x09, U 0x9D, U 0x02, U 0x64, U 0x81, U 0x59, U 0xC9, U 0xD3, U 0x8A, U 0x10, U 0x2B, U 0x21, - U 0x04, U 0x58, U 0x13, U 0xD3, + U 0x04, U 0x58, U 0x13, U 0xE6, U 0x8A, U 0x13, U 0xC0, U 0xB0, U 0x2B, U 0x24, U 0x66, U 0x2E, U 0xA2, U 0x09, U 0x2A, U 0xA0, @@ -1700,7 +1700,7 @@ static unsigned char t3fw[30772] = { 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 0x11, U 0x58, U 0x0D, U 0x7F, + U 0x11, U 0x58, U 0x0D, U 0x91, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x28, U 0x20, U 0x3D, U 0xC0, U 0xE0, U 0x7C, U 0x87, U 0x7F, @@ -1734,14 +1734,14 @@ static unsigned char t3fw[30772] = { U 0xF0, U 0x63, U 0xFE, U 0x95, U 0x00, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x8C, U 0x11, U 0xDD, - U 0x50, U 0x58, U 0x15, U 0x71, + U 0x50, U 0x58, U 0x15, U 0x84, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0xE1, U 0x63, U 0xFF, 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 0xD1, + U 0x20, U 0x58, U 0x13, U 0xE4, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x06, U 0x29, @@ -1851,19 +1851,19 @@ static unsigned char t3fw[30772] = { 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 0xD8, + U 0x40, U 0x58, U 0x13, U 0xEB, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x58, U 0x14, - U 0x68, U 0x63, U 0xFF, U 0xE8, + U 0x7B, 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 0x14, U 0x64, + U 0xB6, U 0x58, U 0x14, U 0x77, U 0x63, U 0xFF, U 0xD9, U 0x00, U 0xDB, U 0x40, U 0x2A, U 0x2C, - U 0x74, U 0x58, U 0x0C, U 0xDF, + U 0x74, U 0x58, U 0x0C, U 0xF1, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x8A, U 0x10, U 0x2B, U 0x21, - U 0x04, U 0x58, U 0x12, U 0xF7, + U 0x04, U 0x58, U 0x13, U 0x0A, U 0x1E, U 0xEB, U 0x46, U 0xC0, U 0xD0, U 0x2D, U 0x24, U 0x66, U 0x63, U 0xFE, U 0xB1, U 0x00, @@ -1893,14 +1893,14 @@ static unsigned char t3fw[30772] = { 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 0x14, U 0x40, + U 0xB6, U 0x58, U 0x14, U 0x53, U 0xC8, U 0x5A, U 0x60, U 0x01, U 0x0F, U 0x00, U 0xDA, U 0x60, - U 0x58, U 0x14, U 0x3D, U 0x65, + U 0x58, U 0x14, U 0x50, 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 0xB0, + U 0x51, U 0x58, U 0x12, U 0xC3, U 0xD3, U 0xA0, U 0x64, U 0xA0, U 0xF3, U 0x84, U 0xA1, U 0xC0, U 0x51, U 0x04, U 0x04, U 0x47, @@ -1911,7 +1911,7 @@ static unsigned char t3fw[30772] = { 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 0xC7, U 0xC0, + U 0x58, U 0x12, U 0xDA, 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, @@ -1961,7 +1961,7 @@ static unsigned char t3fw[30772] = { 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 0xA5, + U 0x40, U 0x58, U 0x12, U 0xB8, U 0xC0, U 0xB0, U 0x63, U 0xFF, U 0x63, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, @@ -2013,7 +2013,7 @@ static unsigned char t3fw[30772] = { 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 0xC8, + U 0xB6, U 0x58, U 0x13, U 0xDB, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x06, U 0x2A, U 0x20, U 0x06, U 0x94, U 0x10, @@ -2024,7 +2024,7 @@ static unsigned char t3fw[30772] = { 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 0x3F, 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, @@ -2154,37 +2154,37 @@ static unsigned char t3fw[30772] = { U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xCC, U 0x57, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x8C, - U 0x10, U 0x58, U 0x12, U 0xA9, + U 0x10, U 0x58, U 0x12, U 0xBC, 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 0x13, U 0x37, + U 0xB6, U 0x58, U 0x13, U 0x4A, U 0x63, U 0xFF, U 0xE1, U 0x00, U 0xDA, U 0x20, U 0x58, U 0x13, - U 0x35, U 0x63, U 0xFF, U 0xD8, + U 0x48, U 0x63, U 0xFF, U 0xD8, U 0x2B, U 0x21, U 0x04, U 0x58, - U 0x11, U 0xCC, U 0x1E, U 0xEA, + U 0x11, U 0xDF, 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 0xD1, 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 0xB9, 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 0xCE, 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 0x58, U 0x13, U 0x30, 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, @@ -2192,7 +2192,7 @@ static unsigned char t3fw[30772] = { 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 0xC2, 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, @@ -2376,7 +2376,7 @@ static unsigned char t3fw[30772] = { U 0xCF, U 0x0B, U 0x4B, U 0x0B, U 0x2B, U 0xC6, U 0x85, U 0xC0, U 0xB0, U 0x8C, U 0x15, U 0x58, - U 0x11, U 0x9C, U 0xD2, U 0xA0, + U 0x11, U 0xAF, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x8A, U 0x35, U 0x6F, U 0xA5, U 0x46, U 0xD8, U 0x30, U 0x8B, U 0xD5, U 0x6D, @@ -2388,7 +2388,7 @@ static unsigned char t3fw[30772] = { U 0x08, U 0x0B, U 0x47, U 0x65, U 0xB1, U 0x0B, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x2C, U 0x12, - U 0x05, U 0x58, U 0x11, U 0xBF, + U 0x05, U 0x58, U 0x11, U 0xD2, U 0xD3, U 0xA0, U 0xC0, U 0xC1, U 0xC0, U 0xD0, U 0x2D, U 0xA4, U 0x03, U 0x9C, U 0x14, U 0x63, @@ -2401,25 +2401,25 @@ static unsigned char t3fw[30772] = { 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 0xC6, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x12, U 0x42, + U 0xB6, U 0x58, U 0x12, U 0x55, U 0x63, U 0xFF, U 0xE4, U 0x00, U 0x00, U 0xDA, U 0x20, U 0x8B, - U 0x10, U 0x58, U 0x12, U 0x3F, + U 0x10, U 0x58, U 0x12, U 0x52, 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 0xD5, U 0x8E, U 0x17, + U 0x10, U 0xE8, 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 0x06, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x8C, U 0x15, U 0xDD, - U 0x50, U 0x58, U 0x12, U 0xC7, + U 0x50, U 0x58, U 0x12, U 0xDA, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x58, U 0x12, - U 0x33, U 0x63, U 0xFF, U 0xA7, + U 0x46, 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, @@ -2427,7 +2427,7 @@ static unsigned char t3fw[30772] = { 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 0x17, U 0x58, U 0x10, U 0xD6, U 0x8E, U 0x17, U 0x63, U 0xFD, U 0xF3, U 0x2D, U 0x21, U 0x38, U 0x2D, U 0xDC, U 0xFF, U 0x0D, @@ -2458,7 +2458,7 @@ static unsigned char t3fw[30772] = { 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 0x18, 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, @@ -2483,7 +2483,7 @@ static unsigned char t3fw[30772] = { U 0x0C, U 0x47, U 0x2C, U 0x24, U 0x66, U 0xC9, U 0xC0, U 0x9E, U 0x17, U 0x8A, U 0x12, U 0x58, - U 0x10, U 0x8C, U 0x8E, U 0x17, + U 0x10, U 0x9F, 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, @@ -2493,7 +2493,7 @@ static unsigned char t3fw[30772] = { 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 0x10, U 0x95, 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, @@ -2578,13 +2578,13 @@ static unsigned char t3fw[30772] = { U 0xCD, U 0x2D, U 0x25, U 0x23, U 0xC8, U 0x55, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x58, U 0x10, - U 0x7B, U 0x29, U 0x21, U 0x02, + U 0x8E, 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 0xFC, U 0xC0, U 0x20, U 0xD1, + U 0xDC, U 0x40, U 0x58, U 0x11, + U 0x0F, 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, @@ -2694,28 +2694,28 @@ static unsigned char t3fw[30772] = { 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 0x11, U 0x20, U 0x63, U 0xFE, + U 0x11, U 0x33, U 0x63, U 0xFE, U 0x38, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x11, U 0x1D, + U 0xB6, U 0x58, U 0x11, U 0x30, 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 0x70, U 0x58, U 0x10, U 0xEC, 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 0xAA, + U 0x04, U 0x58, U 0x0F, U 0xBD, 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 0x8B, + U 0x74, U 0x58, U 0x09, U 0x9D, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x58, U 0x0F, - U 0xAF, U 0x63, U 0xFC, U 0xF7, + U 0xC2, 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, @@ -2744,7 +2744,7 @@ static unsigned char t3fw[30772] = { 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 0x91, + U 0x02, U 0x58, U 0x0F, U 0xA4, U 0x89, U 0x37, U 0x1B, U 0xE7, U 0xD7, U 0xC8, U 0x91, U 0x64, U 0x52, U 0x0E, U 0x2A, U 0x21, @@ -2787,7 +2787,7 @@ static unsigned char t3fw[30772] = { 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 0x11, U 0x03, U 0x9A, U 0x18, + U 0x11, U 0x16, 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, @@ -2802,7 +2802,7 @@ static unsigned char t3fw[30772] = { 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 0x9D, + U 0x20, U 0x58, U 0x10, U 0xB0, U 0x8C, U 0x26, U 0x8B, U 0x27, U 0x9A, U 0x16, U 0x0C, U 0xBB, U 0x0C, U 0x7A, U 0xB3, U 0x34, @@ -2820,7 +2820,7 @@ static unsigned char t3fw[30772] = { 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 0x10, U 0x63, + U 0x16, U 0x58, U 0x10, U 0x76, U 0x65, U 0xA1, U 0x38, U 0x63, U 0xFF, U 0xBD, U 0xC0, U 0x81, U 0xC0, U 0x90, U 0x8F, U 0x18, @@ -2829,7 +2829,7 @@ static unsigned char t3fw[30772] = { 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 0x10, U 0x07, U 0xC0, U 0x51, + U 0x10, U 0x1A, 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, @@ -2854,7 +2854,7 @@ static unsigned char t3fw[30772] = { 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 0x11, U 0x11, + U 0x50, U 0x58, U 0x11, U 0x24, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0x30, U 0x2C, U 0x20, U 0x66, U 0x89, U 0x61, U 0xB1, @@ -2877,7 +2877,7 @@ static unsigned char t3fw[30772] = { 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 0xA6, + U 0x13, U 0x58, U 0x0F, U 0xB9, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x00, U 0x28, U 0x20, U 0x3D, U 0x08, U 0x48, U 0x40, U 0x65, @@ -2902,28 +2902,28 @@ static unsigned char t3fw[30772] = { 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 0xBD, + U 0x40, U 0x58, U 0x0F, U 0xD0, 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 0x10, U 0x4B, + U 0xB6, U 0x58, U 0x10, U 0x5E, 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 0x0F, U 0x3E, + U 0xE0, U 0x58, U 0x0F, U 0x51, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x8A, U 0x15, U 0x2B, U 0x21, - U 0x04, U 0x58, U 0x0E, U 0xDB, + U 0x04, U 0x58, U 0x0E, U 0xEE, 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 0x10, - U 0x3E, U 0x63, U 0xFF, U 0xAB, + U 0x51, U 0x63, U 0xFF, U 0xAB, U 0xC8, U 0x58, U 0xDB, U 0x30, U 0xDA, U 0x20, U 0x58, U 0x0F, - U 0x22, U 0x2A, U 0x21, U 0x02, + U 0x35, 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, @@ -2932,11 +2932,11 @@ static unsigned char t3fw[30772] = { U 0xC0, U 0xA3, U 0x2E, U 0x0A, U 0x80, U 0x2A, U 0x24, U 0x68, U 0xDA, U 0x20, U 0x58, U 0x0F, - U 0x2B, U 0xD2, U 0xA0, U 0xD1, + U 0x3E, 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 0x10, - U 0x53, U 0x63, U 0xFF, U 0x6B, + U 0x66, 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, @@ -3007,7 +3007,7 @@ static unsigned char t3fw[30772] = { 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 0x0E, U 0x15, + U 0x02, U 0x58, U 0x0E, U 0x28, U 0x1C, U 0xE6, U 0xFB, U 0x9C, U 0xA0, U 0x8B, U 0x20, U 0x08, U 0xBB, U 0x11, U 0x06, U 0xBB, @@ -3017,10 +3017,10 @@ static unsigned char t3fw[30772] = { 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 0x10, U 0x6F, U 0xD2, U 0xA0, + U 0x10, U 0x82, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x2B, U 0x20, U 0x0C, U 0x58, - U 0x0F, U 0xDA, U 0xC0, U 0x20, + U 0x0F, U 0xED, 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, @@ -3239,7 +3239,7 @@ static unsigned char t3fw[30772] = { 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 0x00, U 0x58, U 0x0F, U 0x2A, U 0x64, U 0xA3, U 0xB9, U 0x17, U 0xE5, U 0xE6, U 0x8E, U 0x38, U 0x9A, U 0x16, U 0x64, U 0xE3, @@ -3248,11 +3248,11 @@ static unsigned char t3fw[30772] = { 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 0x0F, U 0x49, 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 0x0F, U 0x0A, + U 0x0C, U 0x58, U 0x0F, U 0x1D, U 0xD7, U 0xA0, U 0x64, U 0xA4, U 0x86, U 0x2F, U 0x21, U 0x2E, U 0x8B, U 0x68, U 0x0F, U 0xBF, @@ -3264,7 +3264,7 @@ static unsigned char t3fw[30772] = { 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 0xE3, 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, @@ -3291,11 +3291,11 @@ static unsigned char t3fw[30772] = { 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 0xA0, 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 0x0E, U 0x48, 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, @@ -3346,12 +3346,12 @@ static unsigned char t3fw[30772] = { 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 0x0C, U 0x58, U 0x0E, U 0xBF, 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 0xBB, 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, @@ -3360,7 +3360,7 @@ static unsigned char t3fw[30772] = { 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 0x83, 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, @@ -3442,7 +3442,7 @@ static unsigned char t3fw[30772] = { 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 0x14, U 0x58, U 0x0D, U 0x84, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDC, U 0x70, U 0xDF, U 0x50, U 0xDB, U 0x60, U 0x2D, U 0x6C, @@ -3467,20 +3467,20 @@ static unsigned char t3fw[30772] = { 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 0x15, U 0x58, U 0x0D, U 0x88, + U 0x15, U 0x58, U 0x0D, U 0x9B, U 0xC0, U 0x20, U 0xC0, U 0x90, U 0x29, U 0xA4, U 0x03, U 0xD1, 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 0xC2, 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 0xFD, U 0xDA, - U 0x20, U 0x58, U 0x0C, U 0xB4, + U 0x20, U 0x58, U 0x0C, U 0xC7, 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 0xB6, U 0x58, U 0x0E, U 0x20, U 0x63, U 0xFF, U 0xBA, U 0x00, U 0x2B, U 0x20, U 0x0C, U 0x0C, U 0xBE, U 0x11, U 0xA7, U 0xEE, @@ -3500,7 +3500,7 @@ static unsigned char t3fw[30772] = { U 0xC6, U 0x02, U 0x70, U 0x96, U 0x0C, U 0x8A, U 0x16, U 0x2B, U 0x21, U 0x04, U 0x58, U 0x0C, - U 0x93, U 0xC0, U 0xD0, U 0x2D, + U 0xA6, 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, @@ -3528,7 +3528,7 @@ static unsigned char t3fw[30772] = { 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 0x02, U 0x58, U 0x0C, U 0xD7, U 0x2A, U 0x21, U 0x02, U 0x65, U 0xAE, U 0xF7, U 0xC0, U 0xD8, U 0x0D, U 0xAD, U 0x02, U 0x2D, @@ -3536,38 +3536,38 @@ static unsigned char t3fw[30772] = { 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 0xBD, U 0x2A, U 0x21, U 0x02, + U 0xD0, 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 0x14, U 0x58, U 0x0E, U 0x74, 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 0x0C, U 0x58, U 0x0D, U 0xDF, 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 0x0C, U 0x58, U 0x0E, U 0x01, 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 0x68, U 0x58, U 0x0C, U 0xCF, 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 0xC0, U 0x89, U 0x14, U 0xCD, + U 0xD3, 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 0x0D, U 0x3E, 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 0x47, 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, @@ -3804,15 +3804,15 @@ static unsigned char t3fw[30772] = { U 0xC0, U 0x90, U 0x63, U 0xFF, U 0x5E, U 0xCC, U 0x57, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0x8C, - U 0x11, U 0x58, U 0x0C, U 0x37, + U 0x11, U 0x58, U 0x0C, U 0x4A, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x0C, U 0xC6, + U 0xB6, U 0x58, U 0x0C, U 0xD9, U 0x63, U 0xFF, U 0xE5, U 0x00, U 0xDA, U 0x20, U 0x58, U 0x0C, - U 0xC4, U 0x63, U 0xFF, U 0xDC, + U 0xD7, U 0x63, U 0xFF, U 0xDC, U 0x2A, U 0x2C, U 0x74, U 0x8B, - U 0x11, U 0x58, U 0x05, U 0x3F, + U 0x11, U 0x58, U 0x05, U 0x51, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x06, U 0x28, U 0x20, U 0x06, U 0x8A, U 0x33, @@ -3946,7 +3946,7 @@ static unsigned char t3fw[30772] = { 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 0x8E, + U 0xB0, U 0x58, U 0x0C, U 0xA1, U 0x64, U 0xAF, U 0x18, U 0xC0, U 0xF1, U 0x63, U 0xFE, U 0xEF, U 0x9F, U 0x27, U 0x63, U 0xFF, @@ -4041,7 +4041,7 @@ static unsigned char t3fw[30772] = { 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 0x86, U 0x89, U 0x40, + U 0x0A, U 0x99, U 0x89, U 0x40, U 0xC0, U 0x80, U 0x63, U 0xFE, U 0xE3, U 0x06, U 0x6E, U 0x02, U 0x02, U 0x2A, U 0x02, U 0xDB, @@ -4049,7 +4049,7 @@ static unsigned char t3fw[30772] = { 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 0x65, 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 0xE2, U 0xC6, @@ -4149,7 +4149,7 @@ static unsigned char t3fw[30772] = { 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 0xB0, + U 0x20, U 0x58, U 0x0B, U 0xC3, U 0x8C, U 0x14, U 0x8D, U 0x13, U 0xDB, U 0xA0, U 0xCE, U 0xAC, U 0x60, U 0x01, U 0xC4, U 0x00, @@ -4178,13 +4178,13 @@ static unsigned char t3fw[30772] = { 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 0x15, + U 0x70, U 0x58, U 0x0B, U 0x28, 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 0xBB, + U 0x40, U 0x58, U 0x0A, U 0xCE, U 0xD6, U 0xA0, U 0x8B, U 0x15, U 0xC0, U 0x51, U 0xDE, U 0x70, U 0xDA, U 0x20, U 0xDC, U 0x60, @@ -4207,13 +4207,13 @@ static unsigned char t3fw[30772] = { 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 0x36, + U 0x20, U 0x58, U 0x0B, U 0x49, 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 0xA7, + U 0x02, U 0x58, U 0x09, U 0xBA, U 0xD6, U 0xA0, U 0x64, U 0xA0, U 0xD5, U 0x84, U 0xA1, U 0x83, U 0xA0, U 0x04, U 0x04, U 0x47, @@ -4267,7 +4267,7 @@ static unsigned char t3fw[30772] = { 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 0x1F, + U 0x0C, U 0x58, U 0x0B, U 0x32, U 0x64, U 0x5F, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xC0, U 0x20, U 0xD1, U 0x0F, @@ -4385,8 +4385,8 @@ static unsigned char t3fw[30772] = { U 0x2C, U 0x0A, U 0x01, U 0x58, 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 0xF2, U 0x29, U 0xA0, U 0x11, + U 0xDC, U 0x40, U 0x58, U 0x0A, + U 0x05, 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, @@ -4397,7 +4397,7 @@ static unsigned char t3fw[30772] = { 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 0x72, U 0xD2, U 0xA0, U 0xD1, + U 0x85, 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 0x5F, U 0x1C, U 0xE1, @@ -4428,26 +4428,26 @@ static unsigned char t3fw[30772] = { U 0x2A, U 0x21, U 0x04, U 0x19, 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 0x20, U 0x58, U 0x08, U 0x81, 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 0xB6, U 0x58, U 0x08, U 0x7C, 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 0x58, U 0x0A, U 0x60, 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 0x5E, 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 0x51, U 0x58, U 0x08, U 0xD0, U 0x1C, U 0xE1, U 0x30, U 0xD3, U 0xA0, U 0x64, U 0xA0, U 0xC8, U 0xC0, U 0x51, U 0x84, U 0xA1, @@ -4463,7 +4463,7 @@ static unsigned char t3fw[30772] = { 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 0xCF, + U 0x10, U 0x58, U 0x08, U 0xE2, U 0x8D, U 0x10, U 0x27, U 0x24, U 0x66, U 0x94, U 0xD1, U 0x1E, U 0xE1, U 0x33, U 0xB8, U 0xDC, @@ -4492,7 +4492,7 @@ static unsigned char t3fw[30772] = { 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 0xC2, + U 0x02, U 0x58, U 0x08, U 0xD5, U 0x2F, U 0x20, U 0x0C, U 0x12, U 0xE1, U 0x09, U 0x0C, U 0xF9, U 0x11, U 0xA6, U 0x99, U 0xA2, @@ -4574,13 +4574,13 @@ static unsigned char t3fw[30772] = { 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 0xF6, + U 0x40, U 0x58, U 0x08, U 0x09, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x60, U 0x58, U 0x09, - U 0xC5, U 0x63, U 0xFF, U 0xE7, + U 0xD8, 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 0x6A, + U 0x70, U 0x58, U 0x08, U 0x7D, U 0x2E, U 0x30, U 0x08, U 0x8B, U 0x10, U 0x00, U 0xEE, U 0x32, U 0x2E, U 0x74, U 0x00, U 0x28, @@ -4643,7 +4643,7 @@ static unsigned char t3fw[30772] = { 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 0x7C, U 0xD2, U 0xA0, U 0xD1, + U 0x8F, 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 0x74, @@ -4717,10 +4717,10 @@ static unsigned char t3fw[30772] = { 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 0xA6, + U 0x40, U 0x58, U 0x08, U 0xB9, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x60, U 0x58, U 0x09, - U 0x36, U 0x63, U 0xFF, U 0xE8, + U 0x49, U 0x63, U 0xFF, U 0xE8, U 0x00, U 0x28, U 0x22, U 0x1E, U 0x29, U 0x22, U 0x1D, U 0xD3, U 0x0F, U 0x78, U 0x99, U 0x01, @@ -4776,16 +4776,16 @@ static unsigned char t3fw[30772] = { 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 0xBA, 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 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 0x50, U 0x58, U 0x08, U 0x03, U 0xD2, U 0xA0, U 0xD1, U 0x0F, - U 0xDA, U 0x60, U 0x58, U 0x08, - U 0xF5, U 0x63, U 0xFE, U 0xE4, + U 0xDA, U 0x60, U 0x58, U 0x09, + U 0x08, 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, @@ -4793,7 +4793,7 @@ static unsigned char t3fw[30772] = { 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 0x40, U 0x58, U 0x01, U 0x7C, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x06, U 0x2B, @@ -4887,23 +4887,23 @@ static unsigned char t3fw[30772] = { U 0x90, U 0x65, U 0x2A, U 0x21, U 0x04, U 0x19, U 0xDF, U 0xB9, U 0x7A, U 0x9B, U 0x22, U 0xDA, - U 0x20, U 0x58, U 0x06, U 0xA3, + U 0x20, U 0x58, U 0x06, U 0xB6, U 0x60, U 0x00, U 0x29, U 0x00, U 0x2C, U 0x21, U 0x04, U 0x1B, U 0xDF, U 0xB5, U 0x7C, U 0xBB, U 0x18, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x06, U 0x9E, + U 0xB6, U 0x58, U 0x06, U 0xB1, 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 0x85, U 0x60, + U 0x58, U 0x08, U 0x98, U 0x60, U 0x00, U 0x06, U 0xDA, U 0x20, U 0xC0, U 0xB6, U 0x58, U 0x08, - U 0x83, U 0x65, U 0x51, U 0x35, + U 0x96, 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 0xF6, U 0xC0, U 0xD0, + U 0x07, U 0x09, 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, @@ -4921,7 +4921,7 @@ static unsigned char t3fw[30772] = { 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 0x06, U 0x8E, U 0x14, U 0x8F, + U 0x19, 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, @@ -4974,191 +4974,209 @@ static unsigned char t3fw[30772] = { 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 0xE1, U 0x8E, U 0x14, + U 0x06, U 0xF4, U 0x8E, U 0x14, U 0xC0, U 0xD0, U 0x1B, U 0xDF, 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 0x21, U 0x02, U 0x17, U 0xDF, 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 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, - U 0x0F, U 0x27, U 0x62, U 0x9D, - U 0xC0, U 0xCC, U 0x64, U 0x72, - U 0x07, U 0x2B, U 0x21, U 0x04, - U 0x8E, U 0x31, U 0xC0, U 0xA0, - U 0xDD, U 0xA0, U 0x0E, U 0xFE, - U 0x50, U 0x0E, U 0xCD, U 0x38, - U 0x6E, U 0xB8, U 0x10, U 0x2C, - U 0x20, U 0x66, U 0xB1, U 0xCC, - U 0x0C, U 0x0C, U 0x47, U 0x2C, - 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 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, - U 0x02, U 0x68, U 0x92, U 0x13, - U 0x64, U 0x50, U 0x88, U 0x2A, + U 0x65, U 0x82, U 0x49, U 0x29, + U 0x72, U 0x9E, U 0x6F, U 0x98, + U 0x02, U 0x60, U 0x02, U 0x50, + U 0x19, U 0xDF, U 0x15, U 0x2A, + U 0x92, U 0x26, U 0x68, U 0xA0, + U 0x07, U 0x8B, U 0x20, U 0x0A, + U 0xBB, U 0x0C, U 0x65, U 0xB2, + U 0x3F, U 0x2A, U 0x72, U 0x9D, + U 0xC0, U 0xCC, U 0x64, U 0xA2, + U 0x37, U 0x1D, U 0xDF, U 0x11, + U 0xC0, U 0x60, U 0x2B, U 0x30, + U 0x08, U 0xC0, U 0xF1, U 0x64, + U 0xB0, U 0x71, U 0x2E, U 0x0A, + U 0xFF, U 0xB0, U 0xB8, U 0x64, + U 0x81, U 0x51, U 0x2D, U 0xBC, + U 0xFE, U 0x64, U 0xD0, U 0xF3, + U 0x64, U 0x50, U 0x5C, U 0x2A, U 0x2C, U 0x74, U 0x04, U 0x4B, - U 0x02, U 0x58, U 0x00, U 0x93, + U 0x02, U 0x58, U 0x00, U 0xAD, U 0x0A, U 0xA2, U 0x02, U 0x06, U 0x00, U 0x00, U 0x00, U 0x00, - U 0x2B, U 0x20, U 0x0C, U 0x27, - U 0x21, U 0x04, U 0x0C, U 0xBC, - U 0x11, U 0xA6, U 0xCC, U 0x29, - 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 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 0x00, - U 0x6E, U 0x7B, U 0x02, U 0x60, - 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, - U 0x02, U 0x98, U 0xE2, U 0x2F, - U 0x90, U 0x80, U 0x2A, U 0x94, - 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 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, + U 0x00, U 0x1A, U 0xDF, U 0x15, + U 0x2C, U 0x20, U 0x07, U 0x6E, + U 0xBB, U 0x02, U 0x60, U 0x02, + U 0x22, U 0x18, U 0xDF, U 0x0B, + U 0x13, U 0xDF, U 0x15, U 0x1B, + U 0xDF, U 0x41, U 0xC0, U 0xE2, + U 0x29, U 0x20, U 0x0A, U 0x9A, + U 0xD0, U 0x9E, U 0xD1, U 0xAB, + U 0xCB, U 0x03, U 0x99, U 0x02, + U 0x99, U 0xD2, U 0x23, U 0xB0, + U 0x80, U 0x26, U 0xB4, U 0x80, + U 0xB1, U 0x33, U 0x08, U 0x33, + U 0x02, U 0x93, U 0xD3, U 0x18, + U 0xDE, U 0xFF, U 0x0C, U 0xFD, + U 0x11, U 0xA7, U 0xDD, U 0x2C, + U 0xD2, U 0x85, U 0xA8, U 0xF8, + U 0x26, U 0x84, U 0xCF, U 0x0C, + U 0xEC, U 0x0B, U 0x2C, U 0xD6, + U 0x85, U 0x65, U 0x5F, U 0xA2, U 0xC0, U 0x20, U 0xD1, U 0x0F, - U 0x28, U 0x30, U 0x10, U 0x29, - U 0x30, U 0x11, U 0x2E, U 0x30, - 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 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 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 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 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, - U 0xB0, U 0x2E, U 0x27, U 0x84, - U 0x8C, U 0x03, U 0xEE, U 0x01, - U 0x0F, U 0xEE, U 0x02, U 0x2E, - U 0xB4, U 0x2E, U 0x58, U 0x01, - U 0x8F, U 0x63, U 0xFE, U 0xFF, + U 0x2B, U 0x21, U 0x04, U 0x88, + U 0x31, U 0xDE, U 0x60, U 0x08, + U 0xF8, U 0x50, U 0x08, U 0xCE, + U 0x38, U 0x6E, U 0xB8, U 0x10, + U 0x2C, U 0x20, U 0x66, U 0xB1, + U 0xCC, U 0x0C, U 0x0C, U 0x47, + U 0x2C, U 0x24, U 0x66, U 0x7C, + U 0xEB, U 0x02, U 0x60, U 0x01, + U 0xAF, U 0x2E, U 0x30, U 0x10, + U 0x29, U 0x30, U 0x11, U 0x2C, + U 0x30, U 0x13, U 0x00, U 0x99, + U 0x32, U 0x00, U 0xCB, U 0x32, + U 0x64, U 0xE1, U 0x45, U 0x2A, + U 0x30, U 0x14, U 0x1E, U 0xDF, + U 0x25, U 0x00, U 0xAA, U 0x32, + U 0x78, U 0xCF, U 0x05, U 0x0E, + U 0x9C, U 0x09, U 0x2B, U 0xC4, + U 0x7F, U 0x1C, U 0xDF, U 0x22, + U 0x66, U 0xA0, U 0x05, U 0x0E, + U 0x98, U 0x09, U 0x2A, U 0x84, + U 0x80, U 0xB4, U 0xA7, U 0x18, + U 0xDF, U 0x20, U 0xC7, U 0x6F, + U 0x00, U 0x91, U 0x04, U 0xAC, + U 0x9C, U 0xDB, U 0xC0, U 0x00, + U 0xAE, U 0x1A, U 0x00, U 0xF3, + U 0x1A, U 0x6E, U 0xC1, U 0x04, + U 0x8B, U 0xD0, U 0x0B, U 0xCB, + U 0x0C, U 0x1C, U 0xDF, U 0x1A, + U 0x08, U 0xB8, U 0x1C, U 0x06, + U 0x33, U 0x03, U 0xAC, U 0x88, + U 0x2A, U 0x84, U 0x8B, U 0x2C, + U 0xD0, U 0x2E, U 0x27, U 0x84, + U 0x8C, U 0x03, U 0xCC, U 0x01, + U 0x0E, U 0xCC, U 0x02, U 0x2C, + U 0xD4, U 0x2E, U 0x58, U 0x01, + U 0xAD, U 0x63, U 0xFF, U 0x0B, + U 0x2F, U 0x20, U 0x0C, U 0x0C, + U 0xFB, U 0x11, U 0xA7, U 0xBB, + U 0x2D, U 0xB2, U 0x86, U 0xC0, + U 0x98, U 0x7D, U 0x93, U 0x02, + U 0x60, U 0x01, U 0x21, U 0x19, + U 0xDE, U 0xC8, U 0x09, U 0xF9, + U 0x0A, U 0x29, U 0x92, U 0xA3, + U 0x68, U 0x90, U 0x08, U 0x2D, + U 0x22, U 0x00, U 0x09, U 0xDD, + U 0x0C, U 0x65, U 0xD1, U 0x0C, + U 0x2D, U 0xB2, U 0x85, U 0xDE, + U 0x60, U 0x64, U 0xD1, U 0x04, + U 0x88, U 0x31, U 0x2B, U 0x21, + U 0x04, U 0x08, U 0xF8, U 0x50, + U 0x08, U 0xCE, U 0x38, U 0x6F, + U 0xB8, U 0x02, U 0x63, U 0xFE, + U 0xDF, U 0x2C, U 0x20, U 0x66, + U 0xB1, U 0xCC, U 0x0C, U 0x0C, + U 0x47, U 0x2C, U 0x24, U 0x66, + U 0x7C, U 0xE3, U 0x02, U 0x63, + U 0xFE, U 0xCE, U 0x9D, U 0x10, + U 0x60, U 0x01, U 0x31, U 0x00, U 0x29, U 0x31, U 0x08, U 0x29, U 0x25, U 0x04, U 0x28, U 0x30, - U 0x14, U 0x2E, U 0x31, U 0x09, - U 0xB0, U 0x88, U 0x64, U 0x80, - U 0xA3, U 0x2E, U 0x24, U 0x0A, - U 0xC0, U 0x81, U 0x2E, U 0x30, - U 0x16, U 0x2C, U 0xB4, U 0x23, - U 0x2E, U 0x24, U 0x0B, U 0xB4, - U 0xEF, U 0x2F, U 0x24, U 0x0C, - U 0x8C, U 0x37, U 0x8B, U 0x36, + U 0x14, U 0xB0, U 0x88, U 0x64, + U 0x80, U 0xA6, U 0x2B, U 0x31, + U 0x09, U 0x2B, U 0x24, U 0x0A, + U 0xC0, U 0x81, U 0x2B, U 0x30, + U 0x16, U 0x2F, U 0xD4, U 0x23, + U 0x2B, U 0x24, U 0x0B, U 0xB4, + U 0xBC, U 0x2C, U 0x24, U 0x0C, + U 0x8D, U 0x37, U 0x8B, U 0x36, U 0x29, U 0x25, U 0x04, U 0xDE, - U 0xB0, U 0xDF, U 0xC0, U 0x0C, - U 0x8F, U 0x39, U 0x0B, U 0x8E, - U 0x39, U 0x0F, U 0xEE, U 0x02, - U 0x64, U 0xEE, U 0xC4, U 0x08, - U 0x9F, U 0x11, U 0x01, U 0xC4, - U 0x04, U 0x8D, U 0x38, U 0x0C, - U 0xB8, U 0x18, U 0x00, U 0xC4, - U 0x04, U 0x0C, U 0xBE, U 0x18, - 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 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 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 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, - U 0xD0, U 0x05, U 0x0B, U 0x9A, - U 0x0B, U 0x2D, U 0xA4, U 0x80, + U 0xD0, U 0x0D, U 0x8E, U 0x39, + U 0xDC, U 0xB0, U 0x0B, U 0x8C, + U 0x39, U 0x0E, U 0xCC, U 0x02, + U 0x64, U 0xCE, U 0x78, U 0x08, + U 0x9C, U 0x11, U 0x01, U 0xC4, + U 0x04, U 0x8F, U 0x38, U 0x0D, + U 0xBE, U 0x18, U 0x00, U 0xC4, + U 0x04, U 0x0D, U 0xB8, U 0x18, + U 0x00, U 0x88, U 0x11, U 0x08, + U 0xFF, U 0x02, U 0xC0, U 0x83, + U 0x08, U 0xCC, U 0x02, U 0x18, + U 0xDE, U 0xD8, U 0x9C, U 0xA1, + U 0x98, U 0xA0, U 0x18, U 0xDE, + U 0xD7, U 0x8C, U 0x20, U 0x9E, + U 0xA3, U 0x9F, U 0xA4, U 0x05, + U 0xCC, U 0x11, U 0x0B, U 0xCF, + U 0x53, U 0xC1, U 0xE0, U 0x9E, + U 0xA5, U 0x0C, U 0xFF, U 0x02, + U 0x08, U 0xFF, U 0x02, U 0x9F, + U 0xA2, U 0x18, U 0xDE, U 0x96, + U 0x26, U 0x24, U 0x66, U 0x2C, + U 0x72, U 0x9D, U 0x26, U 0x84, + U 0xA2, U 0x2C, U 0xCC, U 0x18, + U 0x2C, U 0x76, U 0x9D, U 0x63, + U 0xFE, U 0x25, U 0x00, U 0x00, + U 0x00, U 0x2D, U 0x30, U 0x12, + U 0x1C, U 0xDE, U 0xD8, U 0x00, + U 0xDA, U 0x32, U 0x78, U 0xDF, + U 0x05, U 0x0C, U 0x9E, U 0x0B, + U 0x2A, U 0xE4, U 0x7F, U 0x66, + U 0xB0, U 0x05, U 0x0C, U 0x9F, + U 0x0B, U 0x2B, U 0xF4, U 0x80, U 0x2A, U 0x30, U 0x11, U 0x00, - U 0xAA, U 0x32, U 0x63, U 0xFF, - U 0x44, U 0x2F, U 0x24, U 0x0A, - U 0x9E, U 0x2B, U 0x63, U 0xFF, - U 0x56, U 0xCC, U 0x57, U 0xDA, + U 0xAA, U 0x32, U 0x63, U 0xFE, + U 0xEC, U 0x2E, U 0x24, U 0x0A, + U 0x2B, U 0x31, U 0x09, U 0x9B, + U 0x2B, U 0x63, U 0xFF, U 0x53, + U 0x00, U 0xCC, U 0x57, U 0xDA, U 0x20, U 0xDB, U 0x30, U 0xDC, - U 0x40, U 0x58, U 0x07, U 0x14, + U 0x40, U 0x58, U 0x07, U 0x1B, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0xDA, U 0x20, U 0xC0, - U 0xB6, U 0x58, U 0x07, U 0xA3, + U 0xB6, U 0x58, U 0x07, U 0xAA, U 0x63, U 0xFF, U 0xE5, U 0x00, - U 0xDA, U 0x70, U 0x58, U 0x06, - 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 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, - U 0x11, U 0x29, U 0x24, U 0x07, - U 0x98, U 0x10, U 0x7F, U 0x81, - 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 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 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, - U 0x8F, U 0x9F, U 0xE5, U 0x0D, - U 0x99, U 0x02, U 0x99, U 0xE2, - U 0x04, U 0x7F, U 0x11, U 0xC0, - U 0xD4, U 0x9D, U 0xE1, U 0x08, - U 0xFF, U 0x02, U 0x9F, U 0xE4, - U 0x63, U 0xFF, U 0xD0, U 0x00, + U 0x00, U 0xDB, U 0xF0, U 0xDA, + U 0x20, U 0x58, U 0x07, U 0xA7, + U 0x63, U 0xFF, U 0xD9, U 0x00, + U 0x00, U 0x58, U 0x06, U 0x3E, + U 0x1D, U 0xDE, U 0x7D, U 0xC0, + U 0xF1, U 0x26, U 0x24, U 0x66, + U 0x63, U 0xFE, U 0x41, U 0x00, + U 0x8B, U 0x20, U 0x28, U 0x0A, + U 0xFF, U 0xB1, U 0xCE, U 0x23, + U 0x20, U 0x0A, U 0x2C, U 0x21, + U 0x04, U 0x0E, U 0x0E, U 0x47, + U 0x2E, U 0x24, U 0x07, U 0x78, + U 0x31, U 0x35, U 0x9A, U 0xD0, + U 0x2C, U 0xD5, U 0x0A, U 0x96, + U 0xD3, U 0x19, U 0xDE, U 0xB1, + U 0x2E, U 0xD4, U 0x16, U 0xC0, + U 0x83, U 0x98, U 0xD1, U 0xC0, + U 0xE3, U 0x09, U 0xB8, U 0x02, + U 0x98, U 0xD4, U 0x09, U 0x39, + U 0x02, U 0x99, U 0xD2, U 0x26, + U 0x24, U 0x07, U 0x63, U 0xFD, + U 0xC9, U 0x58, U 0x06, U 0x2C, + U 0x8D, U 0x10, U 0x26, U 0x24, + U 0x66, U 0x2B, U 0x21, U 0x04, + U 0x2F, U 0x20, U 0x0C, U 0x63, + U 0xFD, U 0x86, U 0x00, U 0x00, + U 0x08, U 0xB8, U 0x11, U 0x19, + U 0xDE, U 0x75, U 0x08, U 0xEE, + U 0x02, U 0x88, U 0x2B, U 0x9E, + U 0xD5, U 0x9A, U 0xD0, U 0xC0, + U 0xEF, U 0x09, U 0x88, U 0x02, + U 0x98, U 0xD2, U 0x04, U 0xC9, + U 0x11, U 0x0E, U 0x99, U 0x02, + U 0x99, U 0xD4, U 0xC0, U 0xE4, + U 0x9E, U 0xD1, U 0x63, U 0xFF, + U 0xC1, U 0x00, 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 0x85, U 0x21, U 0x0D, U 0x38, U 0x11, - U 0x14, U 0xDE, U 0x66, U 0x86, + U 0x14, U 0xDE, U 0x54, 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, @@ -5172,12 +5190,12 @@ static unsigned char t3fw[30772] = { 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 0x5B, U 0xD9, U 0x30, + U 0xDE, U 0x49, 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 0x56, U 0xC0, U 0xE1, U 0xD2, U 0xE0, U 0x2E, U 0x61, U 0x02, - U 0x1D, U 0xDE, U 0x58, U 0x0E, + U 0x1D, U 0xDE, U 0x46, 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, @@ -5186,19 +5204,19 @@ static unsigned char t3fw[30772] = { 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 0xDE, U 0x95, U 0xB0, U 0xFF, + U 0xDE, U 0x83, 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 0xDE, U 0x92, + U 0xCE, U 0x18, U 0xDE, U 0x80, U 0x8C, U 0x60, U 0xA8, U 0xCC, U 0xC0, U 0xB1, U 0x19, U 0xDE, - U 0x46, U 0x28, U 0x60, U 0x0B, + U 0x34, 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 0xDE, U 0x88, + U 0x38, U 0x1B, U 0xDE, U 0x76, U 0x0C, U 0xA9, U 0x0A, U 0x29, U 0x92, U 0x94, U 0x7B, U 0x9B, U 0x02, U 0x60, U 0x00, U 0x8C, @@ -5207,28 +5225,28 @@ static unsigned char t3fw[30772] = { 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 0x38, + U 0xD2, U 0x19, U 0xDE, U 0x26, 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 0x7C, + U 0xA5, U 0x1A, U 0xDE, U 0x6A, U 0x84, U 0x18, U 0x0A, U 0xEE, U 0x01, U 0xCA, U 0x98, U 0x1B, - U 0xDE, U 0x2F, U 0x8C, U 0x19, + U 0xDE, U 0x1D, 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 0x2C, U 0x0C, + U 0x1D, U 0xDE, U 0x1A, 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 0x6E, + U 0x00, U 0x18, U 0xDE, U 0x5C, U 0x8C, U 0x60, U 0xA8, U 0xCC, U 0xC0, U 0xB1, U 0x19, U 0xDE, - U 0x22, U 0x28, U 0x60, U 0x0B, + U 0x10, 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, @@ -5238,16 +5256,16 @@ static unsigned char t3fw[30772] = { 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 0x2F, + U 0xBA, U 0x58, U 0x07, U 0x30, U 0x64, U 0x50, U 0x73, U 0x60, - U 0x02, U 0x66, U 0x00, U 0x00, - U 0x1A, U 0xDE, U 0x15, U 0x8C, + U 0x02, U 0x6A, U 0x00, U 0x00, + U 0x1A, U 0xDE, U 0x03, 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 0x11, + U 0x1A, U 0x18, U 0xDD, U 0xFF, U 0x0C, U 0x1C, U 0x52, U 0x08, U 0xCC, U 0x0B, U 0x18, U 0xDE, - U 0x58, U 0x2B, U 0xC2, U 0x95, + U 0x46, 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, @@ -5256,25 +5274,25 @@ static unsigned char t3fw[30772] = { 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 0x06, U 0x6E, U 0xB8, + U 0xDD, U 0xF4, 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 0x19, U 0x60, U 0x00, U 0x17, + U 0x1A, 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 0x12, - U 0x65, U 0x51, U 0xF5, U 0x8D, + U 0xB6, U 0x58, U 0x07, U 0x13, + U 0x65, U 0x51, U 0xF9, 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 0x84, + U 0x51, U 0x58, U 0x05, U 0x85, U 0xD3, U 0xA0, U 0x9A, U 0x14, - U 0x64, U 0xA1, U 0xDD, U 0x82, + U 0x64, U 0xA1, U 0xE1, U 0x82, U 0xA0, U 0x85, U 0xA1, U 0xB8, U 0xAF, U 0x9F, U 0x19, U 0x05, U 0x05, U 0x47, U 0x02, U 0x02, @@ -5290,12 +5308,13 @@ static unsigned char t3fw[30772] = { 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 0x95, U 0x8E, U 0x1B, U 0x8F, + U 0x96, 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, - U 0x12, U 0x03, U 0x28, U 0x12, - U 0x09, U 0x6D, U 0xF9, U 0x17, + U 0x64, U 0xF0, U 0xE5, U 0x89, + U 0x13, U 0x88, U 0x19, U 0x0F, + U 0xFD, U 0x02, U 0x2E, U 0x0A, + U 0x00, U 0x6D, U 0xD9, U 0x17, U 0x2F, U 0x81, U 0x03, U 0x00, U 0x90, U 0x8D, U 0xAE, U 0xFE, U 0x00, U 0x80, U 0x88, U 0x9F, @@ -5304,35 +5323,35 @@ static unsigned char t3fw[30772] = { 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 0xDD, U 0xE8, + U 0x30, U 0x1F, U 0xDD, U 0xD5, 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 0x12, U 0xAC, U 0x9C, + U 0xDD, U 0xFF, 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 0xDD, - U 0xD1, U 0x0C, U 0xE8, U 0x11, + U 0xBE, 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, U 0x0B, U 0x22, U 0x86, U 0x85, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x8E, U 0x30, U 0x0E, U 0x0E, - U 0x47, U 0x63, U 0xFD, U 0xA6, + U 0x47, U 0x63, U 0xFD, U 0xA2, U 0xA2, U 0x9C, U 0x0C, U 0x0C, U 0x47, U 0x2C, U 0x64, U 0x07, U 0x7A, U 0xB6, U 0xCD, U 0x8B, 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 0xDD, U 0xFB, + U 0x0E, U 0x18, U 0xDD, U 0xE8, U 0x83, U 0x16, U 0x82, U 0x13, U 0xB3, U 0x39, U 0x02, U 0x33, U 0x0B, U 0x2C, U 0x34, U 0x16, @@ -5344,7 +5363,7 @@ static unsigned char t3fw[30772] = { 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 0xDD, U 0xB6, + U 0xA0, U 0x1C, U 0xDD, U 0xA3, U 0x0C, U 0xBE, U 0x11, U 0xA7, U 0xEE, U 0x2D, U 0xE2, U 0x85, U 0xAC, U 0xBB, U 0x28, U 0xB4, @@ -5364,15 +5383,15 @@ static unsigned char t3fw[30772] = { 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 0xDD, U 0x97, U 0x19, - U 0xDD, U 0x98, U 0x29, U 0xB6, + U 0x1B, U 0xDD, U 0x84, U 0x19, + U 0xDD, U 0x85, 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 0xDD, U 0xA8, U 0x28, + U 0x1D, U 0xDD, U 0x95, 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, @@ -5383,13 +5402,13 @@ static unsigned char t3fw[30772] = { 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 0xDD, U 0x90, U 0x2B, U 0xD6, + U 0xDD, U 0x7D, 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, U 0x85, U 0x1A, U 0x2A, U 0x6C, U 0x74, U 0x8B, U 0x18, U 0x5B, - U 0xFF, U 0x17, U 0x8E, U 0x1B, + U 0xFF, U 0x16, U 0x8E, U 0x1B, U 0x63, U 0xFE, U 0xA3, U 0x00, U 0xC0, U 0x87, U 0xC0, U 0x90, U 0x0A, U 0xF9, U 0x38, U 0x79, @@ -5405,7 +5424,7 @@ static unsigned char t3fw[30772] = { 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 0xDD, U 0x83, U 0x9F, U 0x20, + U 0xDD, U 0x70, 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, @@ -5413,7 +5432,7 @@ static unsigned char t3fw[30772] = { 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 0x71, + U 0x07, U 0x1C, U 0xDD, U 0x5E, U 0x0C, U 0xBE, U 0x11, U 0xA7, U 0xEE, U 0x2D, U 0xE2, U 0x85, U 0xAC, U 0xBB, U 0x28, U 0xB4, @@ -5432,16 +5451,16 @@ static unsigned char t3fw[30772] = { 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 0x59, U 0x1B, - U 0xDD, U 0xA1, U 0xC7, U 0x9F, + U 0x1C, U 0xDD, U 0x46, U 0x1B, + U 0xDD, U 0x8E, 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 0x50, U 0x00, U 0x02, U 0x00, + U 0x3D, U 0x00, U 0x02, U 0x00, U 0x2B, U 0xD2, U 0x82, U 0x1E, - U 0xDD, U 0x9A, U 0x2A, U 0xC1, + U 0xDD, U 0x87, 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, @@ -5452,17 +5471,17 @@ static unsigned char t3fw[30772] = { 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 0x45, U 0x1A, - U 0xDD, U 0x42, U 0x00, U 0x02, + U 0x12, U 0xDD, U 0x32, U 0x1A, + U 0xDD, U 0x2F, U 0x00, U 0x02, U 0x00, U 0x29, U 0xA2, U 0x82, - U 0x18, U 0xDD, U 0x8E, U 0x1B, - U 0xDD, U 0x8C, U 0x26, U 0x21, + U 0x18, U 0xDD, U 0x7B, U 0x1B, + U 0xDD, U 0x79, 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 0xDD, U 0x89, U 0x15, - U 0xDD, U 0x84, U 0x23, U 0x6A, + U 0x14, U 0xDD, U 0x76, U 0x15, + U 0xDD, U 0x71, 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, @@ -5471,12 +5490,12 @@ static unsigned char t3fw[30772] = { 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 0x2F, U 0x0D, U 0x23, - U 0x11, U 0x1C, U 0xDD, U 0x30, + U 0xDD, U 0x1C, U 0x0D, U 0x23, + U 0x11, U 0x1C, U 0xDD, U 0x1D, 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 0x7B, U 0xAC, U 0x55, U 0xA8, + U 0x68, 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, @@ -5488,7 +5507,7 @@ static unsigned char t3fw[30772] = { U 0x08, U 0xAA, U 0x1C, U 0x28, U 0x8C, U 0x08, U 0x28, U 0x16, U 0x04, U 0x58, U 0x08, U 0x61, - U 0x14, U 0xDD, U 0x21, U 0x0A, + U 0x14, U 0xDD, U 0x0E, 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, @@ -5498,9 +5517,9 @@ static unsigned char t3fw[30772] = { 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 0x58, U 0x94, + U 0x16, U 0xDD, U 0x45, U 0x94, U 0x12, U 0xC0, U 0x50, U 0xC0, - U 0xD0, U 0x17, U 0xDD, U 0x14, + U 0xD0, U 0x17, U 0xDD, U 0x01, U 0x9D, U 0x15, U 0xD3, U 0x70, U 0xD4, U 0x10, U 0x2F, U 0x60, U 0x80, U 0x2E, U 0x60, U 0x82, @@ -5532,16 +5551,16 @@ static unsigned char t3fw[30772] = { U 0x21, U 0xD1, U 0x0F, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x27, 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 0xE0, U 0x1F, U 0xDC, U 0xF1, + U 0x1E, U 0xDC, U 0xF4, U 0x1D, + U 0xDC, U 0xDD, U 0x1A, U 0xDD, + U 0x1F, U 0x1B, U 0xDD, U 0x2D, 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 0xDC, U 0xEB, + U 0x04, U 0x15, U 0xDC, U 0xD8, U 0xC0, U 0x31, U 0x25, U 0x50, U 0x2E, U 0x00, U 0x36, U 0x1A, U 0x06, U 0x55, U 0x01, U 0x05, @@ -5551,10 +5570,10 @@ static unsigned char t3fw[30772] = { 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 0x24, U 0x02, U 0x42, + U 0xDD, U 0x11, U 0x02, U 0x42, U 0x08, U 0x72, U 0x99, U 0x3B, U 0x23, U 0x62, U 0x95, U 0x12, - U 0xDC, U 0xE8, U 0xCB, U 0x34, + U 0xDC, U 0xD5, 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, @@ -5570,41 +5589,41 @@ static unsigned char t3fw[30772] = { 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 0xDC, U 0xCC, U 0x2A, U 0xA0, + U 0xDC, U 0xB9, 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 0xDC, U 0xCA, U 0xC9, + U 0x1B, U 0xDC, U 0xB7, 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 0xDC, U 0xC0, + U 0x31, U 0x18, U 0xDC, U 0xAD, U 0x00, U 0x02, U 0x00, U 0x2F, U 0x82, U 0x82, U 0x19, U 0xDC, - U 0xD3, U 0x2E, U 0xB1, U 0x02, + U 0xC0, 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 0xDC, U 0xBA, U 0x16, - U 0xDC, U 0xB7, U 0x00, U 0x02, + U 0x14, U 0xDC, U 0xA7, U 0x16, + U 0xDC, U 0xA4, 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 0x04, - U 0x1A, U 0xDD, U 0x03, U 0x28, + U 0x0F, U 0x19, U 0xDC, U 0xF1, + U 0x1A, U 0xDC, U 0xF0, 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 0xDC, U 0xFA, - U 0x12, U 0xDC, U 0xFF, U 0x25, + U 0x31, U 0x15, U 0xDC, U 0xE7, + U 0x12, U 0xDC, U 0xEC, 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, @@ -5619,20 +5638,20 @@ static unsigned char t3fw[30772] = { 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 0xDC, U 0x9C, U 0x0C, U 0xBC, + U 0xDC, U 0x89, U 0x0C, U 0xBC, U 0x11, U 0xAE, U 0xCC, U 0x28, U 0xC2, U 0x86, U 0x19, U 0xDC, - U 0x9A, U 0x78, U 0xF3, U 0x02, + U 0x87, 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 0xDC, U 0xA4, U 0x64, + U 0x1F, U 0xDC, U 0x91, U 0x64, U 0x90, U 0x92, U 0x9F, U 0x90, U 0xC0, U 0xE4, U 0x1F, U 0xDC, - U 0xB0, U 0x9E, U 0x91, U 0x28, + U 0x9D, 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, @@ -5644,7 +5663,7 @@ static unsigned char t3fw[30772] = { 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 0xDC, U 0x8B, U 0x28, U 0x8C, + U 0xDC, U 0x78, 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, @@ -5657,12 +5676,12 @@ static unsigned char t3fw[30772] = { 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 0x78, U 0x2D, U 0x20, + U 0xDC, U 0x65, 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 0x79, U 0x28, + U 0x12, U 0xDC, U 0x66, 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, @@ -5671,9 +5690,9 @@ static unsigned char t3fw[30772] = { U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x26, U 0x0A, U 0x00, U 0x1B, U 0xDC, - U 0xBD, U 0x15, U 0xDC, U 0x69, + U 0xAA, U 0x15, U 0xDC, U 0x56, U 0x28, U 0x20, U 0x65, U 0x17, - U 0xDC, U 0x66, U 0x28, U 0x8C, + U 0xDC, U 0x53, 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, @@ -5714,27 +5733,27 @@ static unsigned char t3fw[30772] = { 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 0xDC, U 0x92, U 0x64, + U 0x1B, U 0xDC, U 0x7F, 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 0x50, + U 0x82, U 0x18, U 0xDC, U 0x3D, 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 0x30, U 0x15, - U 0xDC, U 0x31, U 0x00, U 0x02, + U 0x16, U 0xDC, U 0x1D, U 0x15, + U 0xDC, U 0x1E, U 0x00, U 0x02, U 0x00, U 0x24, U 0x62, U 0x82, U 0x74, U 0x47, U 0x21, U 0x18, - U 0xDC, U 0x82, U 0x87, U 0x5A, + U 0xDC, U 0x6F, U 0x87, U 0x5A, U 0x08, U 0x48, U 0x01, U 0x28, U 0x66, U 0x82, U 0xCD, U 0x73, - U 0x19, U 0xDC, U 0x80, U 0x0C, + U 0x19, U 0xDC, U 0x6D, 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, @@ -5742,22 +5761,22 @@ static unsigned char t3fw[30772] = { 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 0x79, U 0x2E, + U 0x1F, U 0xDC, U 0x66, 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 0x74, + U 0x5A, U 0x12, U 0xDC, U 0x61, 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 0x17, U 0x1E, U 0xDC, - U 0x19, U 0x22, U 0xB0, U 0x00, - U 0x1A, U 0xDC, U 0x70, U 0x6F, + U 0xDC, U 0x04, U 0x1E, U 0xDC, + U 0x06, U 0x22, U 0xB0, U 0x00, + U 0x1A, U 0xDC, U 0x5D, U 0x6F, U 0x23, U 0x72, U 0x1D, U 0xDC, - 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 0x44, U 0xC0, U 0x48, U 0x18, + U 0xDC, U 0x5C, U 0x1F, U 0xDC, + U 0x5A, 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, @@ -5783,13 +5802,13 @@ static unsigned char t3fw[30772] = { 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 0x54, - U 0x13, U 0xDC, U 0x55, U 0x27, + U 0x0F, U 0x1C, U 0xDC, U 0x41, + U 0x13, U 0xDC, U 0x42, 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 0x53, U 0x15, - U 0xDC, U 0x51, U 0xC0, U 0x40, + U 0x16, U 0xDC, U 0x40, U 0x15, + U 0xDC, U 0x3E, 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, @@ -5813,11 +5832,11 @@ static unsigned char t3fw[30772] = { 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 0x3B, U 0x00, + U 0x15, U 0xDC, U 0x28, U 0x00, U 0x02, U 0x00, U 0x88, U 0x50, - U 0x13, U 0xDC, U 0x3A, U 0xCB, + U 0x13, U 0xDC, U 0x27, U 0xCB, U 0x81, U 0x5B, U 0xFF, U 0xBD, - U 0x1C, U 0xDC, U 0x39, U 0x0C, + U 0x1C, U 0xDC, U 0x26, 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, @@ -5829,7 +5848,7 @@ static unsigned char t3fw[30772] = { 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 0xDB, U 0xCC, U 0x2A, + U 0x15, U 0xDB, U 0xB9, 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, @@ -5839,7 +5858,7 @@ static unsigned char t3fw[30772] = { 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 0xDB, U 0xC0, U 0x00, U 0x02, + U 0xDB, U 0xAD, 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, @@ -5851,13 +5870,13 @@ static unsigned char t3fw[30772] = { 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 0x18, U 0xC0, U 0xD1, + U 0xDC, U 0x05, 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 0xDB, - U 0xAF, U 0x1B, U 0xDB, U 0xB0, - U 0x17, U 0xDC, U 0x11, U 0x0C, + U 0x9C, U 0x1B, U 0xDB, U 0x9D, + U 0x17, U 0xDB, U 0xFE, 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, @@ -5894,7 +5913,7 @@ static unsigned char t3fw[30772] = { 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 0xDB, U 0x88, U 0x28, U 0x0A, + U 0xDB, U 0x75, 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, @@ -5902,7 +5921,7 @@ static unsigned char t3fw[30772] = { 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 0xDB, U 0x81, + U 0xE6, U 0x1A, U 0xDB, U 0x6E, U 0x0A, U 0x4A, U 0x0A, U 0x29, U 0xA2, U 0xA3, U 0xC7, U 0xBF, U 0x76, U 0x91, U 0x01, U 0xD1, @@ -5910,8 +5929,8 @@ static unsigned char t3fw[30772] = { 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 0x7B, U 0x19, U 0xDB, - U 0x78, U 0x17, U 0xDB, U 0x76, + U 0xDB, U 0x68, U 0x19, U 0xDB, + U 0x65, U 0x17, U 0xDB, U 0x63, U 0x0C, U 0x28, U 0x11, U 0xA8, U 0x77, U 0x86, U 0x75, U 0x85, U 0x74, U 0xC0, U 0xA0, U 0x76, @@ -5945,16 +5964,16 @@ static unsigned char t3fw[30772] = { U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x29, 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 0x69, U 0x1F, U 0xDB, U 0x69, + U 0x1C, U 0xDB, U 0x42, 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 0x78, - U 0x14, U 0xDB, U 0x77, U 0x18, - U 0xDB, U 0x75, U 0x2A, U 0xB2, + U 0x70, U 0x13, U 0xDB, U 0x65, + U 0x14, U 0xDB, U 0x64, U 0x18, + U 0xDB, U 0x62, 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, @@ -5963,20 +5982,20 @@ static unsigned char t3fw[30772] = { 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 0xDB, U 0xA9, U 0x0C, U 0x2A, + U 0xDB, U 0x96, 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 0xDB, - U 0x97, U 0xAB, U 0xAC, U 0x2A, + U 0x84, 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 0x61, U 0x68, + U 0x19, U 0xDB, U 0x4E, U 0x68, U 0xC0, U 0x07, U 0x1D, U 0xDB, - U 0x9D, U 0xD3, U 0x0F, U 0x7D, + U 0x8A, 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, @@ -5987,9 +6006,9 @@ static unsigned char t3fw[30772] = { 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 0x93, U 0x03, + U 0x13, U 0xDB, U 0x80, U 0x03, U 0xA3, U 0x01, U 0x8C, U 0x31, - U 0x1D, U 0xDB, U 0x33, U 0x0C, + U 0x1D, U 0xDB, U 0x20, 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, @@ -6000,20 +6019,20 @@ static unsigned char t3fw[30772] = { 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 0x1E, U 0xDA, U 0x20, + U 0xDB, U 0x0B, 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 0x19, U 0x0C, + U 0x1B, U 0xDB, U 0x06, 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 0x12, - U 0x17, U 0xDB, U 0x14, U 0x0C, + U 0x41, U 0x18, U 0xDA, U 0xFF, + U 0x17, U 0xDB, U 0x01, 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, @@ -6021,17 +6040,17 @@ static unsigned char t3fw[30772] = { 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 0x34, U 0x02, U 0x32, U 0x0B, + U 0x21, U 0x02, U 0x32, U 0x0B, U 0xC9, U 0x22, U 0x88, U 0x21, - U 0x17, U 0xDB, U 0x11, U 0x08, + U 0x17, U 0xDA, U 0xFE, 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 0x68, U 0xC0, U 0xB2, + U 0xDB, U 0x55, U 0xC0, U 0xB2, U 0x8E, U 0x20, U 0x1F, U 0xDA, - U 0xFF, U 0x0E, U 0x0E, U 0x43, + U 0xEC, 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, @@ -6041,55 +6060,55 @@ static unsigned char t3fw[30772] = { 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 0xDA, U 0xF5, U 0xDA, U 0x20, + U 0xDA, U 0xE2, 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 0xDA, - U 0xEF, U 0x0C, U 0x4A, U 0x11, + U 0xDC, 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 0xDA, - U 0xEA, U 0xC0, U 0xA1, U 0x2F, + U 0xD7, 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 0xDA, U 0xE4, U 0x0C, U 0x4D, + U 0xDA, U 0xD1, 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 0xDA, U 0xE1, U 0xB8, + U 0x1F, U 0xDA, U 0xCE, 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 0xDA, U 0xD9, U 0x0C, U 0x4C, + U 0xDA, U 0xC6, 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 0xDA, U 0xD1, U 0xDA, U 0x20, + U 0xDA, U 0xBE, 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 0xDA, U 0xCC, + U 0x00, U 0x1C, U 0xDA, U 0xB9, 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 0xDA, U 0xC6, - U 0x16, U 0xDA, U 0xC8, U 0x0C, + U 0x41, U 0x18, U 0xDA, U 0xB3, + U 0x16, U 0xDA, U 0xB5, 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, @@ -6100,7 +6119,7 @@ static unsigned char t3fw[30772] = { 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 0x23, U 0x02, U 0x49, + U 0xDB, U 0x10, 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, @@ -6116,8 +6135,8 @@ static unsigned char t3fw[30772] = { 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 0xDA, U 0xFB, U 0x16, - U 0xDB, U 0x12, U 0xC0, U 0x40, + U 0x13, U 0xDA, U 0xE8, U 0x16, + U 0xDA, U 0xFF, 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, @@ -6139,7 +6158,7 @@ static unsigned char t3fw[30772] = { 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 0xDA, U 0xFD, U 0x63, + U 0x15, U 0xDA, U 0xEA, 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, @@ -6159,9 +6178,9 @@ static unsigned char t3fw[30772] = { 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 0xDA, U 0x82, U 0x19, U 0xDA, - U 0x7F, U 0x1C, U 0xDA, U 0xE8, - U 0x1B, U 0xDA, U 0xE9, U 0xC0, + U 0xDA, U 0x6F, U 0x19, U 0xDA, + U 0x6C, U 0x1C, U 0xDA, U 0xD5, + U 0x1B, U 0xDA, U 0xD6, 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, @@ -6191,18 +6210,18 @@ static unsigned char t3fw[30772] = { 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 0x60, U 0x27, + U 0x1E, U 0xDA, U 0x4D, 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 0x5B, U 0x1A, U 0xDA, - U 0x57, U 0x13, U 0xDA, U 0xC3, + U 0xDA, U 0x48, U 0x1A, U 0xDA, + U 0x44, U 0x13, U 0xDA, U 0xB0, U 0x2A, U 0xA0, U 0x00, U 0x23, U 0x32, U 0x2D, U 0x19, U 0xDA, - U 0xBD, U 0x2B, U 0xAC, U 0xFE, + U 0xAA, 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, @@ -6210,8 +6229,8 @@ static unsigned char t3fw[30772] = { 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 0xDA, U 0xB9, - U 0x1A, U 0xDA, U 0xB3, U 0x2B, + U 0x9E, U 0x15, U 0xDA, U 0xA6, + U 0x1A, U 0xDA, U 0xA0, U 0x2B, U 0x3A, U 0xE8, U 0x0A, U 0x3A, U 0x01, U 0x58, U 0x05, U 0x8B, U 0x2B, U 0x21, U 0x16, U 0x0A, @@ -6220,7 +6239,7 @@ static unsigned char t3fw[30772] = { 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 0xA1, U 0x15, U 0xDA, U 0xB0, + U 0xA1, U 0x15, U 0xDA, U 0x9D, U 0x2D, U 0x21, U 0x02, U 0x2C, U 0x3A, U 0xE8, U 0x0C, U 0x3C, U 0x28, U 0x04, U 0xDD, U 0x02, @@ -6228,10 +6247,10 @@ static unsigned char t3fw[30772] = { 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 0x99, U 0x1C, U 0xDA, U 0xA9, + U 0x99, U 0x1C, U 0xDA, U 0x96, U 0x2D, U 0x21, U 0x02, U 0x0C, U 0x3C, U 0x28, U 0x06, U 0xDD, - U 0x02, U 0x13, U 0xDA, U 0xA7, + U 0x02, U 0x13, U 0xDA, U 0x94, U 0x2D, U 0x25, U 0x02, U 0x9C, U 0x30, U 0x58, U 0x05, U 0x91, U 0x8B, U 0x30, U 0xAA, U 0xBB, @@ -6244,12 +6263,12 @@ static unsigned char t3fw[30772] = { 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 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 0x18, U 0xDA, U 0x8C, U 0x1C, + U 0xDA, U 0x88, U 0x19, U 0xDA, + U 0x89, U 0x1B, U 0xDA, U 0x87, + U 0x17, U 0xDA, U 0x5A, U 0x85, U 0x20, U 0x2E, U 0x0A, U 0xFD, - U 0x1F, U 0xDA, U 0x9B, U 0x2D, + U 0x1F, U 0xDA, U 0x88, 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, @@ -6278,14 +6297,14 @@ static unsigned char t3fw[30772] = { 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 0x71, U 0xC3, + U 0x12, U 0xDA, U 0x5E, 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 0x04, U 0x2A, U 0xA0, + U 0xD9, U 0xF1, 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, @@ -6316,24 +6335,24 @@ static unsigned char t3fw[30772] = { 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 0x58, + U 0x17, U 0x1D, U 0xDA, U 0x45, 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 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 0xDA, U 0x0E, U 0x1B, U 0xD9, + U 0xF9, U 0x18, U 0xDA, U 0x3F, + U 0x17, U 0xDA, U 0x40, U 0x16, + U 0xDA, U 0x40, U 0x15, U 0xDA, + U 0x40, U 0xC0, U 0xE0, U 0xC0, + U 0xD4, U 0x14, U 0xDA, U 0x0A, + U 0x1F, U 0xD9, U 0xC6, 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 0x17, U 0x0C, + U 0x1C, U 0xDA, U 0x04, 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, @@ -6344,13 +6363,13 @@ static unsigned char t3fw[30772] = { 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 0xD9, U 0xF6, - U 0x1B, U 0xDA, U 0x41, U 0xC0, + U 0xAC, U 0x1C, U 0xD9, U 0xE3, + U 0x1B, U 0xDA, U 0x2E, 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 0x06, U 0x0C, U 0x9C, U 0x28, + U 0xC9, U 0x0C, U 0x1C, U 0xD9, + U 0xF3, 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, @@ -6361,13 +6380,13 @@ static unsigned char t3fw[30772] = { U 0x2C, U 0x36, U 0x9E, U 0x2C, U 0x36, U 0x9D, U 0xB1, U 0xAC, 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 0xE3, U 0x1B, U 0xDA, U 0x20, + U 0x13, U 0xDA, U 0x1E, U 0x1A, + U 0xDA, U 0x1E, U 0x18, U 0xDA, + U 0x1F, U 0x14, U 0xD9, U 0xE4, + U 0x16, U 0xDA, U 0x1F, U 0x04, U 0xF4, U 0x28, U 0x12, U 0xDA, - U 0x31, U 0x04, U 0x66, U 0x0C, + U 0x1E, 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, @@ -6375,12 +6394,12 @@ static unsigned char t3fw[30772] = { 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 0x2A, - U 0x18, U 0xDA, U 0x29, U 0xA7, + U 0x8B, U 0x17, U 0xDA, U 0x17, + U 0x18, U 0xDA, U 0x16, 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 0x27, U 0x13, U 0xDA, U 0x27, + U 0x14, U 0x13, U 0xDA, U 0x14, U 0xA6, U 0x55, U 0x04, U 0x33, U 0x0C, U 0x28, U 0x26, U 0xC8, U 0x2E, U 0x75, U 0x00, U 0x2D, @@ -6390,40 +6409,40 @@ static unsigned char t3fw[30772] = { 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 0x05, U 0x17, U 0xDA, - U 0x00, U 0x24, U 0x72, U 0x3D, + U 0xD9, U 0xF2, U 0x17, U 0xD9, + U 0xED, 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 0xD9, - U 0x93, U 0xC0, U 0x51, U 0xD9, + U 0x80, 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 0xD9, U 0x8E, U 0xDD, U 0xB0, + U 0xD9, U 0x7B, 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 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 0xD9, U 0xFB, U 0x19, U 0xD9, + U 0xEB, U 0x18, U 0xD9, U 0xEB, + U 0x16, U 0xD9, U 0xED, U 0x1D, + U 0xD9, U 0xF9, U 0x94, U 0x10, U 0x2A, U 0x72, U 0x45, U 0x17, - U 0xD9, U 0xC9, U 0x6D, U 0xA9, + U 0xD9, U 0xB6, 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 0xD9, U 0x80, + U 0x07, U 0x1F, U 0xD9, U 0x6D, U 0x8F, U 0xF0, U 0x0F, U 0x5F, - U 0x0C, U 0x12, U 0xD9, U 0xC1, + U 0x0C, U 0x12, U 0xD9, U 0xAE, U 0x02, U 0xF2, U 0x28, U 0xAE, U 0x22, U 0x22, U 0xD6, U 0x81, 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 0xAB, U 0x74, U 0x6B, U 0x07, + U 0x15, U 0xD9, U 0x67, 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, @@ -6432,73 +6451,73 @@ static unsigned char t3fw[30772] = { 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 0xD9, U 0xDA, + U 0x8C, U 0x14, U 0xD9, U 0xC7, 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 0x67, U 0xC4, + U 0x15, U 0xD9, U 0x54, U 0xC4, U 0x40, U 0x00, U 0x31, U 0x04, - U 0x1A, U 0xD9, U 0x68, U 0xC0, + U 0x1A, U 0xD9, U 0x55, 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 0xD9, U 0xCE, U 0x2B, + U 0x18, U 0xD9, U 0xBB, 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 0x5D, U 0x2F, U 0x21, U 0x1D, + U 0x4A, 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 0xD9, U 0xBD, U 0x88, U 0x80, + U 0xD9, U 0xAA, 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 0x53, U 0x2A, U 0xB1, + U 0xD9, U 0x40, 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 0x4C, + U 0x0F, U 0x1B, U 0xD9, U 0x39, 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 0x46, U 0x2B, + U 0x1C, U 0xD9, U 0x33, 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 0x3F, U 0x14, U 0xD9, - U 0xA4, U 0x12, U 0xD9, U 0xA7, - U 0x15, U 0xD9, U 0xC2, U 0xC7, + U 0xD9, U 0x2C, U 0x14, U 0xD9, + U 0x91, U 0x12, U 0xD9, U 0x94, + U 0x15, U 0xD9, U 0xAF, 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 0x65, U 0xDB, U 0x10, U 0x1C, - U 0xD9, U 0xBC, U 0xC0, U 0xD4, + U 0x52, U 0xDB, U 0x10, U 0x1C, + U 0xD9, U 0xA9, 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 0x2F, U 0x0B, U 0x5B, + U 0xD9, U 0x1C, 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, @@ -6510,8 +6529,8 @@ static unsigned char t3fw[30772] = { 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 0x22, - U 0x1C, U 0xD9, U 0x80, U 0x2A, + U 0xB0, U 0x1D, U 0xD9, U 0x0F, + U 0x1C, U 0xD9, U 0x6D, 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, @@ -6519,8 +6538,8 @@ static unsigned char t3fw[30772] = { 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 0x18, U 0x14, U 0xD9, - U 0x20, U 0x17, U 0xD9, U 0x90, + U 0xD9, U 0x05, U 0x14, U 0xD9, + U 0x0D, U 0x17, U 0xD9, U 0x7D, U 0xC0, U 0xC0, U 0xC7, U 0x3E, U 0x93, U 0x12, U 0x2C, U 0x26, U 0x2D, U 0xC0, U 0x30, U 0x60, @@ -6530,7 +6549,7 @@ static unsigned char t3fw[30772] = { 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 0x0C, U 0xDA, + U 0x18, U 0xD8, U 0xF9, 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, @@ -6544,7 +6563,7 @@ static unsigned char t3fw[30772] = { 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 0x18, U 0xD8, U 0xEB, 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, @@ -6556,13 +6575,13 @@ static unsigned char t3fw[30772] = { 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 0x08, U 0x1D, U 0xD8, U 0xE1, 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 0x19, U 0xD8, U 0xDC, U 0x1A, + U 0xD9, U 0x21, U 0x88, U 0x13, U 0x0A, U 0xDA, U 0x28, U 0xDC, - U 0x80, U 0x1D, U 0xD9, U 0x72, + U 0x80, U 0x1D, U 0xD9, U 0x5F, U 0x09, U 0x88, U 0x0A, U 0x28, U 0x82, U 0x3C, U 0x0D, U 0xAA, U 0x08, U 0x0B, U 0x80, U 0x00, @@ -6574,13 +6593,13 @@ static unsigned char t3fw[30772] = { 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 0xD8, U 0xD0, U 0x2A, U 0xA2, U 0x00, U 0x0A, U 0xBA, U 0x0C, - U 0x1B, U 0xD9, U 0x24, U 0x8C, + U 0x1B, U 0xD9, U 0x11, 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 0xD9, U 0x4F, U 0xAC, U 0xBB, + U 0x1C, U 0xD9, U 0x4F, 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, @@ -6590,15 +6609,15 @@ static unsigned char t3fw[30772] = { 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 0xD8, U 0xD1, U 0x00, U 0x02, + U 0xD8, U 0xBE, U 0x00, U 0x02, U 0x00, U 0x2A, U 0xB2, U 0x82, - U 0x19, U 0xD8, U 0xD1, U 0x00, + U 0x19, U 0xD8, U 0xBE, 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 0x2C, U 0x0C, U 0x38, + U 0xD9, U 0x19, 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, @@ -6614,8 +6633,8 @@ static unsigned char t3fw[30772] = { 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 0xD8, U 0xB4, - U 0x1C, U 0xD8, U 0xB6, U 0x0D, + U 0xE7, U 0x1D, U 0xD8, U 0xA1, + U 0x1C, U 0xD8, U 0xA3, 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, @@ -6623,7 +6642,7 @@ static unsigned char t3fw[30772] = { 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 0xA3, U 0x1F, U 0xD8, U 0xAC, + U 0xA3, U 0x1F, U 0xD8, U 0x99, U 0xA2, U 0x98, U 0xAF, U 0x7B, U 0x78, U 0xB3, U 0x34, U 0xC9, U 0x3D, U 0xC0, U 0x81, U 0xC0, @@ -6712,7 +6731,7 @@ static unsigned char t3fw[30772] = { U 0x69, U 0x51, U 0x1D, U 0xC0, U 0xE0, U 0x82, U 0x24, U 0x2A, U 0x60, U 0x0F, U 0x18, U 0xD8, - U 0xE0, U 0x2A, U 0x24, U 0x03, + U 0xCD, 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, @@ -6720,12 +6739,12 @@ static unsigned char t3fw[30772] = { 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 0xD8, U 0xD8, + U 0x23, U 0x19, U 0xD8, U 0xC5, 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 0x4B, U 0x9A, U 0x21, U 0x16, - U 0xD8, U 0x49, U 0xC0, U 0x50, + U 0x38, U 0x9A, U 0x21, U 0x16, + U 0xD8, U 0x36, 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, @@ -6737,7 +6756,7 @@ static unsigned char t3fw[30772] = { U 0xD1, U 0x0F, U 0x00, U 0x00, 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 0x28, 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, @@ -6745,8 +6764,8 @@ static unsigned char t3fw[30772] = { 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 0x53, U 0x1C, U 0xD8, U 0x20, + U 0x1D, U 0xD8, U 0x1E, 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, @@ -6768,7 +6787,7 @@ static unsigned char t3fw[30772] = { 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 0x19, U 0xD8, U 0x09, 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, @@ -6798,7 +6817,7 @@ static unsigned char t3fw[30772] = { 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 0xD7, U 0xFA, 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, @@ -6829,7 +6848,7 @@ static unsigned char t3fw[30772] = { 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 0x0E, + U 0x02, U 0x5B, U 0xF7, U 0xFB, U 0x64, U 0x50, U 0x74, U 0x2D, U 0x21, U 0x02, U 0x0D, U 0x0D, U 0x4C, U 0xC9, U 0xD3, U 0xC0, @@ -6838,8 +6857,8 @@ static unsigned char t3fw[30772] = { 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 0xD7, U 0xD9, U 0x1C, - U 0xD7, U 0xD7, U 0x29, U 0xA2, + U 0x1A, U 0xD7, U 0xC6, U 0x1C, + U 0xD7, U 0xC4, 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, @@ -6847,11 +6866,11 @@ static unsigned char t3fw[30772] = { 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 0xD7, U 0xE9, U 0x2E, U 0x21, + U 0xD7, U 0xD6, 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 0xD7, U 0xE5, + U 0x91, U 0x18, U 0xD7, U 0xD2, U 0xC0, U 0xE5, U 0x27, U 0xC4, U 0xA2, U 0x2E, U 0x24, U 0x06, U 0x2B, U 0xA2, U 0x9D, U 0x2F, @@ -6892,7 +6911,7 @@ static unsigned char t3fw[30772] = { 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 0x37, + U 0x74, U 0x5B, U 0xF9, U 0x36, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x04, U 0xD8, U 0x20, U 0xD7, U 0x30, U 0x82, @@ -6900,7 +6919,7 @@ static unsigned char t3fw[30772] = { 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 0xD7, U 0x98, U 0xD4, U 0x20, + U 0xD7, U 0x85, 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, @@ -6914,12 +6933,12 @@ static unsigned char t3fw[30772] = { 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 0x18, U 0xC0, + U 0x1B, U 0xD8, U 0x05, 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 0xD7, U 0x85, U 0x1C, - U 0xD7, U 0x86, U 0x2C, U 0xD6, + U 0x1D, U 0xD7, U 0x72, U 0x1C, + U 0xD7, U 0x73, 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, @@ -6933,8 +6952,8 @@ static unsigned char t3fw[30772] = { 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 0x75, - U 0x1B, U 0xD7, U 0x77, U 0x0D, + U 0xD7, U 0x1C, U 0xD7, U 0x62, + U 0x1B, U 0xD7, U 0x64, 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, @@ -6944,7 +6963,7 @@ static unsigned char t3fw[30772] = { 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 0xD7, U 0x7B, U 0xA2, U 0x9E, + U 0xD7, U 0x68, 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, @@ -6962,7 +6981,7 @@ static unsigned char t3fw[30772] = { 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 0x68, + U 0xCD, U 0x15, U 0xD7, U 0x55, U 0x02, U 0x7E, U 0x0C, U 0xA5, U 0xEE, U 0x64, U 0x30, U 0x51, U 0xC0, U 0xA1, U 0x25, U 0x0A, @@ -7018,7 +7037,7 @@ static unsigned char t3fw[30772] = { 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 0x26, + U 0x16, U 0x14, U 0xD7, U 0x13, U 0x0A, U 0x99, U 0x0C, U 0xCB, U 0x9D, U 0x2E, U 0x20, U 0x0B, U 0x04, U 0xED, U 0x09, U 0x2B, @@ -7081,15 +7100,15 @@ static unsigned char t3fw[30772] = { 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 0xD6, U 0xE6, U 0x00, U 0x02, + U 0xD6, U 0xD3, U 0x00, U 0x02, U 0x00, U 0x2C, U 0xD2, U 0x82, - U 0x1B, U 0xD6, U 0xE6, U 0x00, + U 0x1B, U 0xD6, U 0xD3, 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 0x6A, U 0x0C, U 0x3A, + U 0xD7, U 0x57, 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, @@ -7104,11 +7123,11 @@ static unsigned char t3fw[30772] = { 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 0xD6, U 0xBC, 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 0x13, U 0x15, U 0xD6, U 0xB8, U 0x05, U 0x22, U 0x0A, U 0x22, U 0x22, U 0xA3, U 0x68, U 0x20, U 0x02, U 0x74, U 0x29, U 0x04, @@ -7116,18 +7135,18 @@ static unsigned char t3fw[30772] = { 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 0xD6, U 0xCE, U 0x27, U 0x22, + U 0xD6, U 0xBB, 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 0xD6, U 0xBF, + U 0x31, U 0x1D, U 0xD6, U 0xAC, U 0x00, U 0x02, U 0x00, U 0x2C, U 0xD2, U 0x82, U 0x1B, U 0xD6, - U 0xBF, U 0x00, U 0x31, U 0x04, + U 0xAC, 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 0x43, + U 0x31, U 0x19, U 0xD7, U 0x30, U 0x0C, U 0x3A, U 0x11, U 0xAA, U 0x93, U 0x28, U 0x32, U 0x82, U 0x97, U 0x80, U 0x25, U 0x32, @@ -7143,12 +7162,12 @@ static unsigned char t3fw[30772] = { 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 0xD6, U 0xA8, U 0x0C, U 0x2A, + U 0xD6, U 0x95, 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 0xD6, U 0xA5, U 0x19, U 0xD6, - U 0xCB, U 0x0B, U 0x2B, U 0x0A, + U 0xD6, U 0x92, U 0x19, U 0xD6, + U 0xB8, 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, @@ -7159,11 +7178,11 @@ static unsigned char t3fw[30772] = { U 0xD1, U 0x0F, U 0xC8, U 0x92, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x5B, U 0xEE, - U 0xA7, U 0xC0, U 0x20, U 0xD1, + U 0x94, U 0xC0, U 0x20, U 0xD1, U 0x0F, U 0x00, U 0x00, U 0x00, U 0x6C, U 0x10, U 0x04, U 0x14, - U 0xD6, U 0x95, U 0x28, U 0x42, - U 0x9E, U 0x19, U 0xD6, U 0x92, + U 0xD6, U 0x82, U 0x28, U 0x42, + U 0x9E, U 0x19, U 0xD6, U 0x7F, U 0x6F, U 0x88, U 0x02, U 0x60, U 0x00, U 0xBA, U 0x29, U 0x92, U 0x26, U 0x68, U 0x90, U 0x07, @@ -7172,7 +7191,7 @@ static unsigned char t3fw[30772] = { 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 0xD6, U 0x8C, U 0x0C, U 0xBC, + U 0xD6, U 0x79, 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, @@ -7187,16 +7206,16 @@ static unsigned char t3fw[30772] = { 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 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 0x7B, U 0x1C, U 0xD6, U 0xF5, + U 0x18, U 0xD6, U 0x7F, U 0x1A, + U 0xD6, U 0x76, U 0x19, U 0xD6, + U 0x86, U 0x1D, U 0xD6, U 0x7B, 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 0xD6, U 0xA9, + U 0x02, U 0x1A, U 0xD6, U 0x96, U 0x9F, U 0x52, U 0x88, U 0x26, U 0x9F, U 0x5A, U 0x9E, U 0x59, U 0x9D, U 0x58, U 0x93, U 0x5E, @@ -7204,7 +7223,7 @@ static unsigned char t3fw[30772] = { 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 0xD6, U 0x73, U 0x0C, + U 0x1F, U 0xD6, U 0x60, 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, @@ -7235,17 +7254,17 @@ static unsigned char t3fw[30772] = { 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 0x4C, U 0x0C, U 0xEF, + U 0xD6, U 0x39, 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 0x79, U 0x1A, - U 0xD6, U 0x49, U 0x0A, U 0xEA, + U 0xD6, U 0x36, 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 0x68, U 0x23, U 0xF2, U 0x85, U 0x64, U 0x30, U 0x62, U 0x1B, U 0xD6, - U 0x53, U 0x29, U 0x0A, U 0x80, + U 0x40, 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, @@ -7253,7 +7272,7 @@ static unsigned char t3fw[30772] = { 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 0x02, U 0x1D, U 0xD6, U 0x38, U 0x98, U 0x31, U 0x9D, U 0x30, U 0x8A, U 0x2B, U 0x99, U 0x37, U 0x9C, U 0x34, U 0x0B, U 0xAA, @@ -7265,7 +7284,7 @@ static unsigned char t3fw[30772] = { 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 0xD6, U 0x23, 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, @@ -7289,14 +7308,14 @@ static unsigned char t3fw[30772] = { 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 0x16, U 0x64, U 0x83, U 0x6B, + U 0x03, 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 0x11, U 0xC9, U 0xFB, U 0x28, + U 0x8F, U 0x67, U 0x18, U 0xD5, + U 0xFE, 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, @@ -7307,7 +7326,7 @@ static unsigned char t3fw[30772] = { 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 0x04, + U 0x86, U 0x1D, U 0xD5, U 0xF1, U 0x7C, U 0x9B, U 0x3E, U 0x0D, U 0xBD, U 0x0A, U 0x2D, U 0xD2, U 0xA3, U 0x68, U 0xD0, U 0x04, @@ -7375,15 +7394,15 @@ static unsigned char t3fw[30772] = { 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 0x4D, + U 0x02, U 0x1B, U 0xD6, U 0x3A, 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 0xD5, U 0xCD, U 0x1D, - U 0xD6, U 0x47, U 0x09, U 0x88, + U 0x19, U 0xD5, U 0xBA, U 0x1D, + U 0xD6, U 0x34, 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, @@ -7400,11 +7419,11 @@ static unsigned char t3fw[30772] = { 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 0xD5, U 0xA7, U 0x0C, + U 0x1E, U 0xD5, U 0x94, 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 0xD5, U 0xAB, U 0xC0, + U 0x17, U 0xD5, U 0x98, 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, @@ -7427,7 +7446,7 @@ static unsigned char t3fw[30772] = { 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 0xD5, U 0x9F, + U 0x02, U 0x18, U 0xD5, U 0x8C, U 0x09, U 0x29, U 0x14, U 0x03, U 0xAA, U 0x02, U 0x2B, U 0x21, U 0x25, U 0x83, U 0x20, U 0x0B, @@ -7445,16 +7464,16 @@ static unsigned char t3fw[30772] = { 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 0x09, U 0x0B, + U 0x18, U 0xD5, U 0xF6, 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 0x06, U 0x0C, U 0xBC, U 0x02, + U 0x98, U 0x44, U 0x18, U 0xD5, + U 0xF3, 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 0xD5, U 0x71, - U 0x1C, U 0xD5, U 0x79, U 0x0C, + U 0x80, U 0x1F, U 0xD5, U 0x5E, + U 0x1C, U 0xD5, U 0x66, 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, @@ -7475,10 +7494,10 @@ static unsigned char t3fw[30772] = { 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 0x5D, + U 0x0A, U 0x1C, U 0xD5, U 0x4A, U 0x2C, U 0xC0, U 0x22, U 0xC0, U 0x81, U 0x0C, U 0x87, U 0x38, - U 0x1C, U 0xD5, U 0xEA, U 0x0B, + U 0x1C, U 0xD5, U 0xD7, 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, @@ -7494,7 +7513,7 @@ static unsigned char t3fw[30772] = { 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 0x48, U 0x2C, + U 0x13, U 0xD5, U 0x35, 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, @@ -7529,7 +7548,7 @@ static unsigned char t3fw[30772] = { 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 0xBA, + U 0x11, U 0x5B, U 0xF6, U 0xB9, U 0xD2, U 0xA0, U 0xD1, U 0x0F, U 0xDA, U 0x20, U 0x5B, U 0xFE, U 0x3A, U 0x63, U 0xFF, U 0x38, @@ -7542,63 +7561,63 @@ static unsigned char t3fw[30772] = { 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 0x12, U 0xD5, U 0x98, U 0x82, U 0x20, U 0x02, U 0x82, U 0x57, U 0xC8, U 0x21, U 0x63, U 0xFF, - U 0xFC, U 0x12, U 0xD5, U 0xA7, + U 0xFC, U 0x12, U 0xD5, U 0x94, 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 0xD5, U 0xA3, U 0x91, + U 0x10, U 0xD5, U 0x90, U 0x91, U 0x00, U 0x92, U 0x01, U 0x93, U 0x02, U 0x94, U 0x03, U 0x11, - U 0xD5, U 0x7A, U 0x82, U 0x10, + U 0xD5, U 0x67, 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 0xD5, U 0x9C, U 0x82, + U 0x11, U 0xD5, U 0x89, 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 0x65, + U 0x10, U 0x11, U 0xD5, U 0x52, 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 0xD5, U 0x93, U 0x91, + U 0x10, U 0xD5, U 0x80, U 0x91, U 0x00, U 0x92, U 0x01, U 0x93, U 0x02, U 0x94, U 0x03, U 0x11, - U 0xD5, U 0x69, U 0x82, U 0x10, + U 0xD5, U 0x56, 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 0xD5, U 0x8A, U 0x82, - U 0x10, U 0x13, U 0xD5, U 0x0E, + U 0x11, U 0xD5, U 0x77, U 0x82, + U 0x10, U 0x13, U 0xD4, U 0xFB, 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 0xD5, U 0x84, U 0x91, + U 0x10, U 0xD5, U 0x71, 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 0x57, + U 0x03, U 0x11, U 0xD5, U 0x44, 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 0xD5, - U 0x76, U 0x82, U 0x10, U 0x13, - U 0xD4, U 0xF6, U 0x03, U 0x22, + U 0x63, U 0x82, U 0x10, U 0x13, + U 0xD4, U 0xE3, 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, @@ -7606,7 +7625,7 @@ static unsigned char t3fw[30772] = { 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 0x25, U 0xC0, + U 0x12, U 0xD5, U 0x12, 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, @@ -7614,19 +7633,19 @@ static unsigned char t3fw[30772] = { 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 0x68, U 0x91, + U 0x10, U 0xD5, U 0x55, U 0x91, U 0x00, U 0x92, U 0x01, U 0x93, U 0x02, U 0x94, U 0x03, U 0x11, - U 0xD5, U 0x66, U 0x82, U 0x10, + U 0xD5, U 0x53, U 0x82, U 0x10, U 0x92, U 0x10, U 0x11, U 0xD5, - U 0x17, U 0x83, U 0x10, U 0x03, + U 0x04, U 0x83, U 0x10, U 0x03, U 0x22, U 0x02, U 0x92, U 0x10, - U 0x11, U 0xD5, U 0x63, U 0x12, - U 0xD5, U 0x29, U 0x92, U 0x10, + U 0x11, U 0xD5, U 0x50, U 0x12, + U 0xD5, U 0x16, 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 0x5A, U 0x82, - U 0x10, U 0x13, U 0xD5, U 0x10, + U 0x11, U 0xD5, U 0x47, U 0x82, + U 0x10, U 0x13, U 0xD4, U 0xFD, U 0x03, U 0x22, U 0x02, U 0x92, U 0x10, U 0x04, U 0xE4, U 0x31, U 0x84, U 0x03, U 0x83, U 0x02, @@ -7687,44 +7706,42 @@ static unsigned char t3fw[30772] = { U 0x02, U 0x00, U 0xD1, U 0x0F, U 0x6C, U 0x10, U 0x02, U 0x02, U 0xE4, U 0x31, U 0xD1, U 0x0F, - U 0x0A, U 0x00, U 0x00, U 0x00, - U 0x43, U 0x68, U 0x65, U 0x6C, - U 0x73, U 0x69, U 0x6F, U 0x20, - U 0x46, U 0x57, U 0x20, U 0x44, - 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 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 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 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 0x0A, U 0x00, U 0x43, U 0x68, + U 0x65, U 0x6C, U 0x73, U 0x69, + U 0x6F, U 0x20, U 0x46, U 0x57, + U 0x20, U 0x44, 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 0x54, U 0x75, U 0x65, U 0x20, + U 0x4E, U 0x6F, U 0x76, U 0x20, + U 0x20, U 0x33, U 0x20, U 0x30, + U 0x36, U 0x3A, U 0x30, U 0x35, + U 0x3A, U 0x31, U 0x31, U 0x20, + U 0x50, U 0x53, U 0x54, U 0x20, + U 0x32, U 0x30, 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 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 0x37, 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 0x37, U 0x2E, U 0x30, + U 0x30, U 0x38, U 0x2E, U 0x30, U 0x30, U 0x20, U 0x2D, U 0x20, U 0x31, U 0x30, U 0x30, U 0x37, - U 0x30, U 0x37, U 0x30, U 0x30, - U 0x10, U 0x07, U 0x07, U 0x00, - U 0xE5, U 0xF4, U 0xC5, U 0x92, + U 0x30, U 0x38, U 0x30, U 0x30, + U 0x10, U 0x07, U 0x08, U 0x00, + U 0x4F, U 0x43, U 0x3A, U 0x10, }; From 1dc03a9fc564f93e095b89c67eb8b627c159746b Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Sun, 6 Dec 2009 01:59:06 +0000 Subject: [PATCH 0757/2592] MFC r199237: sc->rev and is_offload(sc) will always be 0 during probe. Wait till attach to get correct values. (missed this one in r200175) --- sys/dev/cxgb/cxgb_main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 5c763400c2d..02942b98d8d 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -355,7 +355,6 @@ cxgb_controller_probe(device_t dev) const struct adapter_info *ai; char *ports, buf[80]; int nports; - struct adapter *sc = device_get_softc(dev); ai = cxgb_get_adapter_info(dev); if (ai == NULL) @@ -367,9 +366,7 @@ cxgb_controller_probe(device_t dev) else ports = "ports"; - snprintf(buf, sizeof(buf), "%s %sNIC, rev: %d nports: %d %s", - ai->desc, is_offload(sc) ? "R" : "", - sc->params.rev, nports, ports); + snprintf(buf, sizeof(buf), "%s, %d %s", ai->desc, nports, ports); device_set_desc_copy(dev, buf); return (BUS_PROBE_DEFAULT); } @@ -665,8 +662,8 @@ cxgb_controller_attach(device_t dev) G_FW_VERSION_MAJOR(vers), G_FW_VERSION_MINOR(vers), G_FW_VERSION_MICRO(vers)); - snprintf(buf, sizeof(buf), "%s\t E/C: %s S/N: %s", - ai->desc, + snprintf(buf, sizeof(buf), "%s %sNIC\t E/C: %s S/N: %s", + ai->desc, is_offload(sc) ? "R" : "", sc->params.vpd.ec, sc->params.vpd.sn); device_set_desc_copy(dev, buf); From bba81f6fbde2888321fcf431a8f2347e542f99c5 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sun, 6 Dec 2009 09:36:11 +0000 Subject: [PATCH 0758/2592] MFC r198467: 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 --- 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 3a5ce93470cb7f75ad3396c9f1343076c6134172 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Sun, 6 Dec 2009 19:01:33 +0000 Subject: [PATCH 0759/2592] mfc r200056 use qsort_r instead of heapsort; staticize two functions. --- sbin/ipfw/dummynet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c index 41ad48e7246..9e68e659dd4 100644 --- a/sbin/ipfw/dummynet.c +++ b/sbin/ipfw/dummynet.c @@ -78,7 +78,7 @@ static struct _s_x dummynet_params[] = { }; static int -sort_q(const void *pa, const void *pb) +sort_q(void *arg, const void *pa, const void *pb) { int rev = (co.do_sort < 0); int field = rev ? -co.do_sort : co.do_sort; @@ -121,7 +121,7 @@ list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q) return; if (co.do_sort != 0) - heapsort(q, fs->rq_elements, sizeof *q, sort_q); + qsort_r(q, fs->rq_elements, sizeof *q, NULL, sort_q); /* Print IPv4 flows */ index_printed = 0; @@ -486,7 +486,7 @@ is_valid_number(const char *s) * and return the numeric bandwidth value. * set clocking interface or bandwidth value */ -void +static void read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen) { if (*bandwidth != -1) @@ -530,7 +530,7 @@ struct point { double delay; }; -int +static int compare_points(const void *vp1, const void *vp2) { const struct point *p1 = vp1; From 0b1ab65e97c95aac35db8148dbece781a8b64a18 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Sun, 6 Dec 2009 21:07:47 +0000 Subject: [PATCH 0760/2592] MFC of r199642 The output of perror(1) is now showing local messages for locales supported by libc/nls PR: bin/140499 Approved by: gnn@ --- usr.bin/perror/perror.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usr.bin/perror/perror.c b/usr.bin/perror/perror.c index 6d852a7a371..ef3db35b64b 100644 --- a/usr.bin/perror/perror.c +++ b/usr.bin/perror/perror.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include static void usage(void); @@ -43,6 +44,7 @@ main(int argc, char **argv) char *errstr; long errnum; + (void) setlocale(LC_MESSAGES, ""); if (argc != 2) usage(); From 7635c69726bfc2e91dcf71e970b237c2ced52ef4 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 6 Dec 2009 22:01:45 +0000 Subject: [PATCH 0761/2592] MFC r198963: sh: Fix memory leak when using a variable in arithmetic like $((x)). --- 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 2ffbb2cea1676fe6524adc6bde37073ca8e44be4 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 6 Dec 2009 22:14:58 +0000 Subject: [PATCH 0762/2592] MFC r198406: 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 --- 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 11fb6973dd7..bcab1f5e815 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 28769e8539ca281930574971231b3d1c31e80a35 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Mon, 7 Dec 2009 06:05:36 +0000 Subject: [PATCH 0763/2592] MFC: r197138: - The ifconfig(8) command now supports NDP flags which are handled by ndp(8). r198006: - Use printb() to display the "nd6 options=" line. --- sbin/ifconfig/Makefile | 1 + sbin/ifconfig/af_inet6.c | 13 +++ sbin/ifconfig/af_nd6.c | 229 +++++++++++++++++++++++++++++++++++++++ sbin/ifconfig/ifconfig.8 | 34 +++++- 4 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 sbin/ifconfig/af_nd6.c diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile index e5b78af3d83..367ad9c3bc1 100644 --- a/sbin/ifconfig/Makefile +++ b/sbin/ifconfig/Makefile @@ -18,6 +18,7 @@ SRCS+= af_link.c # LLC support SRCS+= af_inet.c # IPv4 support SRCS+= af_inet6.c # IPv6 support SRCS+= af_atalk.c # AppleTalk support +SRCS+= af_nd6.c # ND6 support SRCS+= ifclone.c # clone device support SRCS+= ifmac.c # MAC support diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c index 13789dc7494..e091ac75fab 100644 --- a/sbin/ifconfig/af_inet6.c +++ b/sbin/ifconfig/af_inet6.c @@ -67,6 +67,9 @@ static int prefix(void *, int); static char *sec2str(time_t); static int explicit_prefix = 0; +extern void setnd6flags(const char *, int, int, const struct afswtch *); +extern void setnd6defif(const char *, int, int, const struct afswtch *); + static char addr_buf[MAXHOSTNAMELEN *2 + 1]; /*for getnameinfo()*/ static void @@ -493,6 +496,16 @@ static struct cmd inet6_cmds[] = { DEF_CMD("-deprecated", -IN6_IFF_DEPRECATED, setip6flags), DEF_CMD("autoconf", IN6_IFF_AUTOCONF, setip6flags), DEF_CMD("-autoconf", -IN6_IFF_AUTOCONF, setip6flags), + DEF_CMD("accept_rtadv", ND6_IFF_ACCEPT_RTADV, setnd6flags), + DEF_CMD("-accept_rtadv",-ND6_IFF_ACCEPT_RTADV, setnd6flags), + DEF_CMD("defaultif", 1, setnd6defif), + DEF_CMD("-defaultif", -1, setnd6defif), + DEF_CMD("ifdisabled", ND6_IFF_IFDISABLED, setnd6flags), + DEF_CMD("-ifdisabled", -ND6_IFF_IFDISABLED, setnd6flags), + DEF_CMD("nud", ND6_IFF_PERFORMNUD, setnd6flags), + DEF_CMD("-nud", -ND6_IFF_PERFORMNUD, setnd6flags), + DEF_CMD("prefer_source",ND6_IFF_PREFER_SOURCE, setnd6flags), + DEF_CMD("-prefer_source",-ND6_IFF_PREFER_SOURCE,setnd6flags), DEF_CMD_ARG("pltime", setip6pltime), DEF_CMD_ARG("vltime", setip6vltime), DEF_CMD("eui64", 0, setip6eui64), diff --git a/sbin/ifconfig/af_nd6.c b/sbin/ifconfig/af_nd6.c new file mode 100644 index 00000000000..e6b920af7bd --- /dev/null +++ b/sbin/ifconfig/af_nd6.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2009 Hiroki Sato. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include "ifconfig.h" + +#define MAX_SYSCTL_TRY 5 +#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 *); +void setnd6defif(const char *, int, int, const struct afswtch *); + +void +setnd6flags(const char *dummyaddr __unused, + int d, int s, + const struct afswtch *afp) +{ + struct in6_ndireq nd; + int error; + + memset(&nd, 0, sizeof(nd)); + strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); + error = ioctl(s, SIOCGIFINFO_IN6, &nd); + if (error) { + warn("ioctl(SIOCGIFINFO_IN6)"); + return; + } + if (d < 0) + nd.ndi.flags &= ~(-d); + else + nd.ndi.flags |= d; + error = ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&nd); + if (error) + warn("ioctl(SIOCSIFINFO_IN6)"); +} + +void +setnd6defif(const char *dummyaddr __unused, + int d, int s, + const struct afswtch *afp) +{ + struct in6_ndifreq ndifreq; + int ifindex; + int error; + + memset(&ndifreq, 0, sizeof(ndifreq)); + strncpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname)); + + if (d < 0) { + if (isnd6defif(s)) { + /* ifindex = 0 means to remove default if */ + ifindex = 0; + } else + return; + } else if ((ifindex = if_nametoindex(ndifreq.ifname)) == 0) { + warn("if_nametoindex(%s)", ndifreq.ifname); + return; + } + + ndifreq.ifindex = ifindex; + error = ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq); + if (error) + warn("ioctl(SIOCSDEFIFACE_IN6)"); +} + +static int +isnd6defif(int s) +{ + struct in6_ndifreq ndifreq; + unsigned int ifindex; + int error; + + memset(&ndifreq, 0, sizeof(ndifreq)); + strncpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname)); + + ifindex = if_nametoindex(ndifreq.ifname); + error = ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq); + if (error) { + warn("ioctl(SIOCGDEFIFACE_IN6)"); + return (error); + } + return (ndifreq.ifindex == ifindex); +} + +static void +nd6_status(int s) +{ + struct in6_ndireq nd; + struct rt_msghdr *rtm; + size_t needed; + char *buf, *next; + int mib[6], ntry; + int s6; + int error; + int isinet6, isdefif; + + /* Check if the interface has at least one IPv6 address. */ + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = AF_INET6; + mib[4] = NET_RT_IFLIST; + mib[5] = if_nametoindex(ifr.ifr_name); + + /* Try to prevent a race between two sysctls. */ + ntry = 0; + do { + error = sysctl(mib, 6, NULL, &needed, NULL, 0); + if (error) { + warn("sysctl(NET_RT_IFLIST)/estimate"); + return; + } + buf = malloc(needed); + if (buf == NULL) { + warn("malloc for sysctl(NET_RT_IFLIST) failed"); + return; + } + if ((error = sysctl(mib, 6, buf, &needed, NULL, 0)) < 0) { + if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { + warn("sysctl(NET_RT_IFLIST)/get"); + free(buf); + return; + } + free(buf); + buf = NULL; + } + } while (buf == NULL); + + isinet6 = 0; + for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)next; + + if (rtm->rtm_version != RTM_VERSION) + continue; + if (rtm->rtm_type == RTM_NEWADDR) { + isinet6 = 1; + break; + } + } + free(buf); + if (!isinet6) + return; + + memset(&nd, 0, sizeof(nd)); + strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); + if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + warn("socket(AF_INET6, SOCK_DGRAM)"); + return; + } + error = ioctl(s6, SIOCGIFINFO_IN6, &nd); + if (error) { + warn("ioctl(SIOCGIFINFO_IN6)"); + close(s6); + return; + } + isdefif = isnd6defif(s6); + close(s6); + if (nd.ndi.flags == 0 && !isdefif) + return; + printb("\tnd6 options", + (unsigned int)(nd.ndi.flags | (isdefif << 15)), ND6BITS); + putchar('\n'); +} + +static struct afswtch af_nd6 = { + .af_name = "nd6", + .af_af = AF_LOCAL, + .af_other_status= nd6_status, +}; + +static __constructor void +nd6_ctor(void) +{ + af_register(&af_nd6); +} diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 2b0d7d64828..c372a08ddd5 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 July 8, 2009 +.Dd December 7, 2009 .Dt IFCONFIG 8 .Os .Sh NAME @@ -598,6 +598,38 @@ If the interface was reset when previously marked down, the hardware will be re-initialized. .El .Pp +The following parameters are for ICMPv6 Neightbor Discovery Protocol: +.Bl -tag -width indent +.It Cm accept_rtadv +Set a flag to enable accepting ICMPv6 Router Advertisement messages. +.It Cm -accept_rtadv +Clear a flag +.Cm accept_rtadv . +.It Cm defaultif +Set the specified interface as the default route when there is no +default router. +.It Cm -defaultif +Clear a flag +.Cm defaultif . +.It Cm ifdisabled +Set a flag to disable all of IPv6 network communications on the +specified interface. +.It Cm -ifdisabled +Clear a flag +.Cm ifdisabled . +.It Cm nud +Set a flag to enable Neighbor Unreachability Detection. +.It Cm -nud +Clear a flag +.Cm nud . +.It Cm prefer_source +Set a flag to prefer addesses on the interface as candidates of the +source address for outgoing packets. +.It Cm -prefer_source +Clear a flag +.Cm prefer_source . +.El +.Pp The following parameters are specific to cloning IEEE 802.11 wireless interfaces with the .Cm create From a1c3a99ce5e291150a3db85e73dc9102d580af12 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Mon, 7 Dec 2009 06:25:19 +0000 Subject: [PATCH 0764/2592] MFC: r197144: - Add an extension of set_rcvar(), a new function set_rcvar_obsolete(), and $desc. The set_rcvar_obsolete() is to mark a variable as obsolete and define the new one. More specifically, a warning is displayed when a variable is removed or changed in the source tree and the user still defines the old one. --- etc/rc.subr | 153 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 124 insertions(+), 29 deletions(-) diff --git a/etc/rc.subr b/etc/rc.subr index acbf6273734..04166749eb8 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -72,37 +72,63 @@ esac # functions # --------- +# set_rcvar [var] [defval] [desc] # -# set_rcvar base_var -# Set the variable name enabling a specific service. -# FreeBSD uses ${service}_enable, while NetBSD uses -# just the name of the service. For example: -# FreeBSD: sendmail_enable="YES" -# NetBSD : sendmail="YES" -# $1 - if $name is not the base to work of off, specify -# a different one +# Echo or define a rc.conf(5) variable name. Global variable +# $rcvars is used. +# +# If no argument is specified, echo "${name}_enable". +# +# If only a var is specified, echo "${var}_enable". +# +# If var and defval are specified, the ${var} is defined as +# rc.conf(5) variable and the default value is ${defvar}. An +# optional argument $desc can also be specified to add a +# description for that. # set_rcvar() { - if [ -z "$1" ]; then - base_var=${name} - else - base_var="$1" - fi - - case ${OSTYPE} in - FreeBSD) - echo ${base_var}_enable + case $# in + 0) + echo ${name}_enable ;; - NetBSD) - echo ${base_var} + 1) + echo ${1}_enable ;; *) - echo 'XXX' + debug "rcvar_define: \$$1=$2 is added" \ + " as a rc.conf(5) variable." + + local _var + _var=$1 + rcvars="${rcvars# } $_var" + eval ${_var}_defval=\"$2\" + shift 2 + # encode multiple lines of _desc + for l in "$@"; do + eval ${_var}_desc=\"\${${_var}_desc#^^}^^$l\" + done + eval ${_var}_desc=\"\${${_var}_desc#^^}\" ;; esac } +# set_rcvar_obsolete oldvar [newvar] [msg] +# Define obsolete variable. +# Global variable $rcvars_obsolete is used. +# +set_rcvar_obsolete() +{ + local _var + _var=$1 + debug "rcvar_obsolete: \$$1(old) -> \$$2(new) is defined" + + rcvars_obsolete="${rcvars_obsolete# } $1" + eval ${1}_newvar=\"$2\" + shift 2 + eval ${_var}_obsolete_msg=\"$*\" +} + # # force_depend script # Force a service to start. Intended for use by services @@ -415,6 +441,8 @@ check_startmsgs() # command_interpreter n If not empty, command is interpreted, so # call check_{pidfile,process}() appropriately. # +# desc n Description of script. +# # extra_commands n List of extra commands supported. # # pidfile n If set, use check_pidfile $pidfile $command, @@ -588,7 +616,7 @@ run_rc_command() esac eval _override_command=\$${name}_program - command=${_override_command:-$command} + command=${command:-${_override_command}} _keywords="start stop restart rcvar $extra_commands" rc_pid= @@ -792,14 +820,49 @@ $command $rc_flags $command_args" ;; rcvar) - echo "# $name" - if [ -n "$rcvar" ]; then - if checkyesno ${rcvar}; then - echo "${rcvar}=YES" - else - echo "${rcvar}=NO" - fi + echo -n "# $name" + if [ -n "$desc" ]; then + echo " : $desc" + else + echo "" fi + echo "#" + # Get unique vars in $rcvar $rcvars + for _v in $rcvar $rcvars; do + case $v in + $_v\ *|\ *$_v|*\ $_v\ *) ;; + *) v="${v# } $_v" ;; + esac + done + + # Display variables. + for _v in $v; do + if [ -z "$_v" ]; then + continue + fi + + eval _desc=\$${_v}_desc + eval _defval=\$${_v}_defval + _h="-" + + eval echo \"$_v=\\\"\$$_v\\\"\" + # decode multiple lines of _desc + while [ -n "$_desc" ]; do + case $_desc in + *^^*) + echo "# $_h ${_desc%%^^*}" + _desc=${_desc#*^^} + _h=" " + ;; + *) + echo "# $_h ${_desc}" + break + ;; + esac + done + echo "# (default: \"$_defval\")" + done + echo "" ;; *) @@ -910,7 +973,8 @@ run_rc_script() unset name command command_args command_interpreter \ extra_commands pidfile procname \ - rcvar required_dirs required_files required_vars + rcvar rcvars rcvars_obsolete required_dirs required_files \ + required_vars eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd case "$_file" in @@ -941,6 +1005,7 @@ run_rc_script() # load_rc_config() { + local _name _var _defval _v _msg _new _name=$1 if [ -z "$_name" ]; then err 3 'USAGE: load_rc_config name' @@ -967,6 +1032,36 @@ load_rc_config() # Old variable names support # [ -n "$enable_quotas" ] && quota_enable="$enable_quotas" + + # Set defaults if defined. + for _var in $rcvar $rcvars; do + _defval=`eval echo "\\\$${_var}_defval"` + if [ -n "$_defval" ]; then + eval : \${$_var:=\$${_var}_defval} + fi + done + + # check obsolete rc.conf variables + for _var in $rcvars_obsolete; do + _v=`eval echo \\$$_var` + _msg=`eval echo \\$${_var}_obsolete_msg` + _new=`eval echo \\$${_var}_newvar` + case $_v in + "") + ;; + *) + if [ -z "$_new" ]; then + _msg="Ignored." + else + eval $_new=\"\$$_var\" + if [ -z "$_msg" ]; then + _msg="Use \$$_new instead." + fi + fi + warn "\$$_var is obsolete. $_msg" + ;; + esac + done } # From cf19fced1795078cc635b0b4a151f3c191e1501e Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Mon, 7 Dec 2009 07:33:51 +0000 Subject: [PATCH 0765/2592] MFC 197288,197326,197327,197328,197342,197914,197929, 197955,199365,199370,199371,199373,199866 This MFCs all SCTP/VNET relevant fixes from head. Approved by: rrs (mentor) --- sys/kern/uipc_syscalls.c | 9 +++ sys/net/route.c | 4 ++ sys/netinet/in_proto.c | 59 ++++++++++--------- sys/netinet/sctp_asconf.c | 2 +- sys/netinet/sctp_bsd_addr.c | 15 +++-- sys/netinet/sctp_constants.h | 5 +- sys/netinet/sctp_input.c | 2 +- sys/netinet/sctp_os_bsd.h | 29 ++++----- sys/netinet/sctp_output.c | 18 +++--- sys/netinet/sctp_pcb.c | 111 ++++++++++++++++++++++------------- sys/netinet/sctp_pcb.h | 2 +- sys/netinet/sctp_structs.h | 1 + sys/netinet/sctp_sysctl.c | 2 +- sys/netinet/sctp_timer.c | 2 +- sys/netinet/sctp_usrreq.c | 2 +- sys/netinet/sctputil.c | 10 ++++ sys/netinet6/sctp6_usrreq.c | 8 +-- 17 files changed, 168 insertions(+), 113 deletions(-) diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 89e1dd0fc77..2e2e4f77592 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -2311,6 +2312,7 @@ sctp_peeloff(td, uap) goto done; td->td_retval[0] = fd; + CURVNET_SET(head->so_vnet); so = sonewconn(head, SS_ISCONNECTED); if (so == NULL) goto noconnection; @@ -2350,6 +2352,7 @@ noconnection: /* * Release explicitly held references before returning. */ + CURVNET_RESTORE(); done: if (nfp != NULL) fdrop(nfp, td); @@ -2428,9 +2431,11 @@ sctp_generic_sendmsg (td, uap) auio.uio_offset = 0; /* XXX */ auio.uio_resid = 0; len = auio.uio_resid = uap->mlen; + CURVNET_SET(so->so_vnet); error = sctp_lower_sosend(so, to, &auio, (struct mbuf *)NULL, (struct mbuf *)NULL, uap->flags, use_rcvinfo, u_sinfo, td); + CURVNET_RESTORE(); if (error) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) @@ -2538,9 +2543,11 @@ sctp_generic_sendmsg_iov(td, uap) } } len = auio.uio_resid; + CURVNET_SET(so->so_vnet); error = sctp_lower_sosend(so, to, &auio, (struct mbuf *)NULL, (struct mbuf *)NULL, uap->flags, use_rcvinfo, u_sinfo, td); + CURVNET_RESTORE(); if (error) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) @@ -2660,9 +2667,11 @@ sctp_generic_recvmsg(td, uap) if (KTRPOINT(td, KTR_GENIO)) ktruio = cloneuio(&auio); #endif /* KTRACE */ + CURVNET_SET(so->so_vnet); error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL, fromsa, fromlen, &msg_flags, (struct sctp_sndrcvinfo *)&sinfo, 1); + CURVNET_RESTORE(); if (error) { if (auio.uio_resid != (int)len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) diff --git a/sys/net/route.c b/sys/net/route.c index 2fc53af45be..20875380118 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1497,7 +1497,11 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index = rt->rt_ifp->if_index; } + RT_ADDREF(rt); + RT_UNLOCK(rt); rt_newaddrmsg(cmd, ifa, error, rt); + RT_LOCK(rt); + RT_REMREF(rt); if (cmd == RTM_DELETE) { /* * If we are deleting, and we found an entry, diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index f1f5adef3ab..2bc6ca9632e 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -150,39 +150,42 @@ struct protosw inetsw[] = { }, #ifdef SCTP { - .pr_type = SOCK_DGRAM, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, - .pr_input = sctp_input, - .pr_ctlinput = sctp_ctlinput, - .pr_ctloutput = sctp_ctloutput, - .pr_init = sctp_init, - .pr_drain = sctp_drain, - .pr_usrreqs = &sctp_usrreqs + .pr_type = SOCK_DGRAM, + .pr_domain = &inetdomain, + .pr_protocol = IPPROTO_SCTP, + .pr_flags = PR_WANTRCVD, + .pr_input = sctp_input, + .pr_ctlinput = sctp_ctlinput, + .pr_ctloutput = sctp_ctloutput, + .pr_init = sctp_init, +#ifdef VIMAGE + .pr_destroy = sctp_finish, +#endif + .pr_drain = sctp_drain, + .pr_usrreqs = &sctp_usrreqs }, { - .pr_type = SOCK_SEQPACKET, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, - .pr_input = sctp_input, - .pr_ctlinput = sctp_ctlinput, - .pr_ctloutput = sctp_ctloutput, - .pr_drain = sctp_drain, - .pr_usrreqs = &sctp_usrreqs + .pr_type = SOCK_SEQPACKET, + .pr_domain = &inetdomain, + .pr_protocol = IPPROTO_SCTP, + .pr_flags = PR_WANTRCVD, + .pr_input = sctp_input, + .pr_ctlinput = sctp_ctlinput, + .pr_ctloutput = sctp_ctloutput, + .pr_drain = sctp_drain, + .pr_usrreqs = &sctp_usrreqs }, { - .pr_type = SOCK_STREAM, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, - .pr_input = sctp_input, - .pr_ctlinput = sctp_ctlinput, - .pr_ctloutput = sctp_ctloutput, - .pr_drain = sctp_drain, - .pr_usrreqs = &sctp_usrreqs + .pr_type = SOCK_STREAM, + .pr_domain = &inetdomain, + .pr_protocol = IPPROTO_SCTP, + .pr_flags = PR_WANTRCVD, + .pr_input = sctp_input, + .pr_ctlinput = sctp_ctlinput, + .pr_ctloutput = sctp_ctloutput, + .pr_drain = sctp_drain, + .pr_usrreqs = &sctp_usrreqs }, #endif /* SCTP */ { diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index c38c344fcf2..404b5ad0aa7 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -881,7 +881,7 @@ send_reply: /* we probably don't need these operations */ (void)sa6_recoverscope(from6); sa6_embedscope(from6, - MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)); + MODULE_GLOBAL(ip6_use_defzone)); break; } diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c index 792a720b6df..e508a4ab986 100644 --- a/sys/netinet/sctp_bsd_addr.c +++ b/sys/netinet/sctp_bsd_addr.c @@ -89,6 +89,7 @@ sctp_wakeup_iterator(void) static void sctp_iterator_thread(void *v) { + CURVNET_SET((struct vnet *)v); SCTP_IPI_ITERATOR_WQ_LOCK(); SCTP_BASE_INFO(iterator_running) = 0; while (1) { @@ -96,10 +97,12 @@ 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(); } + CURVNET_RESTORE(); } void @@ -108,7 +111,7 @@ sctp_startup_iterator(void) int ret; ret = kproc_create(sctp_iterator_thread, - (void *)NULL, + (void *)curvnet, &SCTP_BASE_INFO(thread_proc), RFPROC, SCTP_KTHREAD_PAGES, @@ -126,7 +129,7 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa) ifa6 = (struct in6_ifaddr *)ifa->ifa; ifa->flags = ifa6->ia6_flags; - if (!MODULE_GLOBAL(MOD_INET6, ip6_use_deprecated)) { + if (!MODULE_GLOBAL(ip6_use_deprecated)) { if (ifa->flags & IN6_IFF_DEPRECATED) { ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE; @@ -206,7 +209,8 @@ sctp_init_ifns_for_vrf(int vrfid) struct sctp_ifa *sctp_ifa; uint32_t ifa_flags; - TAILQ_FOREACH(ifn, &MODULE_GLOBAL(MOD_NET, ifnet), if_list) { + IFNET_RLOCK(); + TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) { IF_ADDR_LOCK(ifn); TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { if (ifa->ifa_addr == NULL) { @@ -251,6 +255,7 @@ sctp_init_ifns_for_vrf(int vrfid) } IF_ADDR_UNLOCK(ifn); } + IFNET_RUNLOCK(); } void @@ -336,7 +341,8 @@ void struct ifnet *ifn; struct ifaddr *ifa; - TAILQ_FOREACH(ifn, &MODULE_GLOBAL(MOD_NET, ifnet), if_list) { + IFNET_RLOCK(); + TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) { if (!(*pred) (ifn)) { continue; } @@ -344,6 +350,7 @@ void sctp_addr_change(ifa, add ? RTM_ADD : RTM_DELETE); } } + IFNET_RUNLOCK(); } struct mbuf * diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index 8df34909634..2b17cbc214f 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -87,10 +87,13 @@ __FBSDID("$FreeBSD$"); /* #define SCTP_AUDITING_ENABLED 1 used for debug/auditing */ #define SCTP_AUDIT_SIZE 256 +/* temporary disabled since it does not work with VNET. */ +#if 0 #define SCTP_USE_THREAD_BASED_ITERATOR 1 +#endif #define SCTP_KTRHEAD_NAME "sctp_iterator" -#define SCTP_KTHREAD_PAGES 2 +#define SCTP_KTHREAD_PAGES 0 /* If you support Multi-VRF how big to diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 01b145703e7..18b7d557e7b 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -5876,7 +5876,7 @@ sctp_skip_csum_4: * idea, so I will leave it in place. */ if (inp && ipsec4_in_reject(m, &inp->ip_inp.inp)) { - MODULE_GLOBAL(MOD_IPSEC, ipsec4stat).in_polvio++; + MODULE_GLOBAL(ipsec4stat).in_polvio++; SCTP_STAT_INCR(sctps_hdrops); goto bad; } diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index d01879081bd..b77c9143eb2 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -78,10 +78,6 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef VIMAGE -#error "SCTP is not yet compatible with VIMAGE." -#endif - #ifdef IPSEC #include #include @@ -137,25 +133,21 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT); #define SCTP_CTR6 CTR6 #endif -#define SCTP_BASE_INFO(__m) system_base_info.sctppcbinfo.__m -#define SCTP_BASE_STATS system_base_info.sctpstat -#define SCTP_BASE_STAT(__m) system_base_info.sctpstat.__m -#define SCTP_BASE_SYSCTL(__m) system_base_info.sctpsysctl.__m -#define SCTP_BASE_VAR(__m) system_base_info.__m - /* * Macros to expand out globals defined by various modules * to either a real global or a virtualized instance of one, * depending on whether VIMAGE is defined. */ -/* first define modules that supply us information */ -#define MOD_NET net -#define MOD_INET inet -#define MOD_INET6 inet6 -#define MOD_IPSEC ipsec - /* then define the macro(s) that hook into the vimage macros */ -#define MODULE_GLOBAL(__MODULE, __SYMBOL) V_ ## __SYMBOL +#define MODULE_GLOBAL(__SYMBOL) V_##__SYMBOL + +#define V_system_base_info VNET(system_base_info) +#define SCTP_BASE_INFO(__m) V_system_base_info.sctppcbinfo.__m +#define SCTP_BASE_STATS V_system_base_info.sctpstat +#define SCTP_BASE_STATS_SYSCTL VNET_NAME(system_base_info.sctpstat) +#define SCTP_BASE_STAT(__m) V_system_base_info.sctpstat.__m +#define SCTP_BASE_SYSCTL(__m) VNET_NAME(system_base_info.sctpsysctl.__m) +#define SCTP_BASE_VAR(__m) V_system_base_info.__m /* * @@ -263,10 +255,9 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT); /* SCTP_ZONE_INIT: initialize the zone */ typedef struct uma_zone *sctp_zone_t; -#define UMA_ZFLAG_FULL 0x0020 #define SCTP_ZONE_INIT(zone, name, size, number) { \ zone = uma_zcreate(name, size, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,\ - UMA_ZFLAG_FULL); \ + 0); \ uma_zone_set_max(zone, number); \ } diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 4875d22f7a3..96057e559a0 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -3829,7 +3829,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, sin6 = &tmp; /* KAME hack: embed scopeid */ - if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) { + if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) { SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL); return (EINVAL); } @@ -3883,7 +3883,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, if (net->src_addr_selected == 0) { sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; /* KAME hack: embed scopeid */ - if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) { + if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) { SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL); return (EINVAL); } @@ -3906,7 +3906,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, } else { sin6 = (struct sockaddr_in6 *)&ro->ro_dst; /* KAME hack: embed scopeid */ - if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) { + if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) { SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL); return (EINVAL); } @@ -5143,7 +5143,7 @@ do_a_abort: */ (void)sa6_recoverscope(sin6); stc.scope_id = sin6->sin6_scope_id; - sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)); + sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)); stc.loopback_scope = 1; stc.local_scope = 0; stc.site_scope = 1; @@ -5179,7 +5179,7 @@ do_a_abort: */ (void)sa6_recoverscope(sin6); stc.scope_id = sin6->sin6_scope_id; - sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)); + sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)); } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { /* * If the new destination is @@ -10768,7 +10768,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh, /* Fill in the IPv6 header for the ABORT */ ip6_out->ip6_flow = ip6->ip6_flow; - ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim); + ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim); if (port) { ip6_out->ip6_nxt = IPPROTO_UDP; } else { @@ -11787,7 +11787,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag, /* Fill in the IP6 header for the ABORT */ ip6_out->ip6_flow = ip6->ip6_flow; - ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim); + ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim); if (port) { ip6_out->ip6_nxt = IPPROTO_UDP; } else { @@ -12014,7 +12014,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag, /* Fill in the IP6 header for the ABORT */ ip6_out->ip6_flow = ip6->ip6_flow; - ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim); + ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim); if (port) { ip6_out->ip6_nxt = IPPROTO_UDP; } else { @@ -13765,7 +13765,7 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro) return (0); /* get prefix entry of address */ - LIST_FOREACH(pfx, &MODULE_GLOBAL(MOD_INET6, nd_prefix), ndpr_entry) { + LIST_FOREACH(pfx, &MODULE_GLOBAL(nd_prefix), ndpr_entry) { if (pfx->ndpr_stateflags & NDPRF_DETACHED) continue; if (IN6_ARE_MASKED_ADDR_EQUAL(&pfx->ndpr_prefix.sin6_addr, diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 0d1f1e0f847..8370dcc4c96 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$"); #include -struct sctp_base_info system_base_info; +VNET_DEFINE(struct sctp_base_info, system_base_info); /* FIX: we don't handle multiple link local scopes */ /* "scopeless" replacement IN6_ARE_ADDR_EQUAL */ @@ -59,11 +59,11 @@ SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b) struct sockaddr_in6 tmp_a, tmp_b; memcpy(&tmp_a, a, sizeof(struct sockaddr_in6)); - if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) { + if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(ip6_use_defzone)) != 0) { return 0; } memcpy(&tmp_b, b, sizeof(struct sockaddr_in6)); - if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) { + if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(ip6_use_defzone)) != 0) { return 0; } return (IN6_ARE_ADDR_EQUAL(&tmp_a.sin6_addr, &tmp_b.sin6_addr)); @@ -2008,7 +2008,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset, /* Get the scopes in properly to the sin6 addr's */ /* we probably don't need these operations */ (void)sa6_recoverscope(from6); - sa6_embedscope(from6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)); + sa6_embedscope(from6, MODULE_GLOBAL(ip6_use_defzone)); break; } #endif @@ -2049,7 +2049,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset, /* Get the scopes in properly to the sin6 addr's */ /* we probably don't need these operations */ (void)sa6_recoverscope(to6); - sa6_embedscope(to6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)); + sa6_embedscope(to6, MODULE_GLOBAL(ip6_use_defzone)); break; } #endif @@ -2316,7 +2316,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) } #endif /* IPSEC */ SCTP_INCR_EP_COUNT(); - inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl); + inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl); SCTP_INP_INFO_WUNLOCK(); so->so_pcb = (caddr_t)inp; @@ -2688,7 +2688,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { bindall = 0; /* KAME hack: embed scopeid */ - if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) { + if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL); return (EINVAL); } @@ -2814,8 +2814,8 @@ continue_anyway: int done; if (ip_inp->inp_flags & INP_HIGHPORT) { - first = MODULE_GLOBAL(MOD_INET, ipport_hifirstauto); - last = MODULE_GLOBAL(MOD_INET, ipport_hilastauto); + first = MODULE_GLOBAL(ipport_hifirstauto); + last = MODULE_GLOBAL(ipport_hilastauto); } else if (ip_inp->inp_flags & INP_LOWPORT) { if (p && (error = priv_check(p, PRIV_NETINET_RESERVEDPORT) @@ -2826,11 +2826,11 @@ continue_anyway: SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error); return (error); } - first = MODULE_GLOBAL(MOD_INET, ipport_lowfirstauto); - last = MODULE_GLOBAL(MOD_INET, ipport_lowlastauto); + first = MODULE_GLOBAL(ipport_lowfirstauto); + last = MODULE_GLOBAL(ipport_lowlastauto); } else { - first = MODULE_GLOBAL(MOD_INET, ipport_firstauto); - last = MODULE_GLOBAL(MOD_INET, ipport_lastauto); + first = MODULE_GLOBAL(ipport_firstauto); + last = MODULE_GLOBAL(ipport_lastauto); } if (first > last) { uint16_t temp; @@ -3756,7 +3756,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; - (void)sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)); + (void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)); sin6->sin6_scope_id = 0; } #endif @@ -5558,36 +5558,54 @@ sctp_pcb_finish(void) struct sctp_ifa *ifa; struct sctpvtaghead *chain; struct sctp_tagblock *twait_block, *prev_twait_block; + struct sctp_laddr *wi; + struct sctp_iterator *it; int i; +#if defined(SCTP_USE_THREAD_BASED_ITERATOR) + SCTP_BASE_INFO(threads_must_exit) = 1; + /* Wake the thread up so it will exit now */ + sctp_wakeup_iterator(); + +#endif + SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer)); + SCTP_IPI_ITERATOR_WQ_LOCK(); + while ((wi = LIST_FIRST(&SCTP_BASE_INFO(addr_wq))) != NULL) { + LIST_REMOVE(wi, sctp_nxt_addr); + SCTP_DECR_LADDR_COUNT(); + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi); + } + SCTP_IPI_ITERATOR_WQ_UNLOCK(); + while ((it = TAILQ_FIRST(&SCTP_BASE_INFO(iteratorhead))) != NULL) { + if (it->function_atend != NULL) { + (*it->function_atend) (it->pointer, it->val); + } + TAILQ_REMOVE(&SCTP_BASE_INFO(iteratorhead), it, sctp_nxt_itr); + SCTP_FREE(it, SCTP_M_ITER); + } + /* * free the vrf/ifn/ifa lists and hashes (be sure address monitor is * destroyed first). */ vrf_bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(SCTP_DEFAULT_VRFID & SCTP_BASE_INFO(hashvrfmark))]; - vrf = LIST_FIRST(vrf_bucket); - while (vrf) { - ifn = LIST_FIRST(&vrf->ifnlist); - while (ifn) { - ifa = LIST_FIRST(&ifn->ifalist); - while (ifa) { + while ((vrf = LIST_FIRST(vrf_bucket)) != NULL) { + while ((ifn = LIST_FIRST(&vrf->ifnlist)) != NULL) { + while ((ifa = LIST_FIRST(&ifn->ifalist)) != NULL) { /* free the ifa */ LIST_REMOVE(ifa, next_bucket); LIST_REMOVE(ifa, next_ifa); SCTP_FREE(ifa, SCTP_M_IFA); - ifa = LIST_FIRST(&ifn->ifalist); } /* free the ifn */ LIST_REMOVE(ifn, next_bucket); LIST_REMOVE(ifn, next_ifn); SCTP_FREE(ifn, SCTP_M_IFN); - ifn = LIST_FIRST(&vrf->ifnlist); } SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark); /* free the vrf */ LIST_REMOVE(vrf, next_vrf); SCTP_FREE(vrf, SCTP_M_VRF); - vrf = LIST_FIRST(vrf_bucket); } /* free the vrf hashes */ SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_vrfhash), SCTP_BASE_INFO(hashvrfmark)); @@ -5614,9 +5632,7 @@ sctp_pcb_finish(void) /* free the locks and mutexes */ #ifdef SCTP_PACKET_LOGGING SCTP_IP_PKTLOG_DESTROY(); - #endif - SCTP_IPI_ITERATOR_WQ_DESTROY(); SCTP_IPI_ADDR_DESTROY(); SCTP_ITERATOR_LOCK_DESTROY(); SCTP_STATLOG_DESTROY(); @@ -6422,10 +6438,6 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb) /* We look for anything larger than the cum-ack + 1 */ - SCTP_STAT_INCR(sctps_protocol_drain_calls); - if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) { - return; - } asoc = &stcb->asoc; if (asoc->cumulative_tsn == asoc->highest_tsn_inside_map) { /* none we can reneg on. */ @@ -6588,22 +6600,37 @@ sctp_drain() * is LOW on MBUF's and needs help. This is where reneging will * occur. We really hope this does NOT happen! */ - struct sctp_inpcb *inp; - struct sctp_tcb *stcb; + VNET_ITERATOR_DECL(vnet_iter); + VNET_LIST_RLOCK_NOSLEEP(); + VNET_FOREACH(vnet_iter) { + CURVNET_SET(vnet_iter); + struct sctp_inpcb *inp; + struct sctp_tcb *stcb; - SCTP_INP_INFO_RLOCK(); - LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) { - /* For each endpoint */ - SCTP_INP_RLOCK(inp); - LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { - /* For each association */ - SCTP_TCB_LOCK(stcb); - sctp_drain_mbufs(inp, stcb); - SCTP_TCB_UNLOCK(stcb); + SCTP_STAT_INCR(sctps_protocol_drain_calls); + if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) { +#ifdef VIMAGE + continue; +#else + return; +#endif } - SCTP_INP_RUNLOCK(inp); + SCTP_INP_INFO_RLOCK(); + LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) { + /* For each endpoint */ + SCTP_INP_RLOCK(inp); + LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { + /* For each association */ + SCTP_TCB_LOCK(stcb); + sctp_drain_mbufs(inp, stcb); + SCTP_TCB_UNLOCK(stcb); + } + SCTP_INP_RUNLOCK(inp); + } + SCTP_INP_INFO_RUNLOCK(); + CURVNET_RESTORE(); } - SCTP_INP_INFO_RUNLOCK(); + VNET_LIST_RUNLOCK_NOSLEEP(); } /* diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h index 684ed5ae17d..d9e1db6dc05 100644 --- a/sys/netinet/sctp_pcb.h +++ b/sys/netinet/sctp_pcb.h @@ -462,7 +462,7 @@ struct sctp_tcb { * goes with the base info. sctp_pcb.c has * the real definition. */ -extern struct sctp_base_info system_base_info; +VNET_DECLARE(struct sctp_base_info, system_base_info); #ifdef INET6 int SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b); diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index 59725f5d992..595c37c3e7a 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -51,6 +51,7 @@ struct sctp_timer { void *ep; void *tcb; void *net; + void *vnet; /* for sanity checking */ void *self; diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c index b5c5f6c4795..ceb4622ab8a 100644 --- a/sys/netinet/sctp_sysctl.c +++ b/sys/netinet/sctp_sysctl.c @@ -930,7 +930,7 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, output_unlocked, CTLTYPE_INT | CTLFLAG_RW, #endif SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW, - &SCTP_BASE_STATS, sctpstat, + &SCTP_BASE_STATS_SYSCTL, sctpstat, "SCTP statistics (struct sctp_stat)"); SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD, diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index b40ef503f61..334401838e1 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -1773,7 +1773,7 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp, struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; /* KAME hack: embed scopeid */ - (void)sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)); + (void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)); } #endif diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 4442f11befb..a8ea998a3b3 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -544,7 +544,7 @@ sctp_attach(struct socket *so, int proto, struct thread *p) inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; /* I'm not v6! */ ip_inp = &inp->ip_inp.inp; ip_inp->inp_vflag |= INP_IPV4; - ip_inp->inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl); + ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl); #ifdef IPSEC error = ipsec_init_policy(so, &ip_inp->inp_sp); #ifdef SCTP_LOG_CLOSING diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index c7bdfb54b5c..94dea3fa73d 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1446,6 +1446,7 @@ sctp_timeout_handler(void *t) inp = (struct sctp_inpcb *)tmr->ep; stcb = (struct sctp_tcb *)tmr->tcb; net = (struct sctp_nets *)tmr->net; + CURVNET_SET((struct vnet *)tmr->vnet); did_output = 1; #ifdef SCTP_AUDITING_ENABLED @@ -1459,6 +1460,7 @@ sctp_timeout_handler(void *t) * SCTP_PRINTF("Stale SCTP timer fired (%p), ignoring...\n", * tmr); */ + CURVNET_RESTORE(); return; } tmr->stopped_from = 0xa001; @@ -1467,10 +1469,12 @@ sctp_timeout_handler(void *t) * SCTP_PRINTF("SCTP timer fired with invalid type: 0x%x\n", * tmr->type); */ + CURVNET_RESTORE(); return; } tmr->stopped_from = 0xa002; if ((tmr->type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL)) { + CURVNET_RESTORE(); return; } /* if this is an iterator timeout, get the struct and clear inp */ @@ -1494,6 +1498,7 @@ sctp_timeout_handler(void *t) (tmr->type != SCTP_TIMER_TYPE_ASOCKILL)) ) { SCTP_INP_DECR_REF(inp); + CURVNET_RESTORE(); return; } } @@ -1505,6 +1510,7 @@ sctp_timeout_handler(void *t) if (inp) { SCTP_INP_DECR_REF(inp); } + CURVNET_RESTORE(); return; } } @@ -1517,6 +1523,7 @@ sctp_timeout_handler(void *t) if (stcb) { atomic_add_int(&stcb->asoc.refcnt, -1); } + CURVNET_RESTORE(); return; } tmr->stopped_from = 0xa006; @@ -1531,6 +1538,7 @@ sctp_timeout_handler(void *t) if (inp) { SCTP_INP_DECR_REF(inp); } + CURVNET_RESTORE(); return; } } @@ -1903,6 +1911,7 @@ out_decr: out_no_decr: SCTPDBG(SCTP_DEBUG_TIMER1, "Timer now complete (type %d)\n", type); + CURVNET_RESTORE(); } void @@ -2263,6 +2272,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, tmr->tcb = (void *)stcb; tmr->net = (void *)net; tmr->self = (void *)tmr; + tmr->vnet = (void *)curvnet; tmr->ticks = sctp_get_tick_count(); (void)SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr); return; diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index 9597528b7d0..50f5ef83746 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -223,7 +223,7 @@ sctp_skip_csum: */ if (in6p_ip && (ipsec6_in_reject(m, in6p_ip))) { /* XXX */ - MODULE_GLOBAL(MOD_IPSEC, ipsec6stat).in_polvio++; + MODULE_GLOBAL(ipsec6stat).in_polvio++; goto bad; } #endif /* IPSEC */ @@ -695,7 +695,7 @@ sctp6_attach(struct socket *so, int proto, struct thread *p) * socket as well, because the socket may be bound to an IPv6 * wildcard address, which may match an IPv4-mapped IPv6 address. */ - inp6->inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl); + inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl); #endif /* * Hmm what about the IPSEC stuff that is missing here but in @@ -859,7 +859,7 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, } } if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { - if (!MODULE_GLOBAL(MOD_INET6, ip6_v6only)) { + if (!MODULE_GLOBAL(ip6_v6only)) { struct sockaddr_in sin; /* convert v4-mapped into v4 addr and send */ @@ -990,7 +990,7 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p) } } if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { - if (!MODULE_GLOBAL(MOD_INET6, ip6_v6only)) { + if (!MODULE_GLOBAL(ip6_v6only)) { /* convert v4-mapped into v4 addr */ in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6); addr = (struct sockaddr *)&ss; From 3cec660ea4028bfbf640a63145fe9c51105ff46c Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Mon, 7 Dec 2009 07:41:29 +0000 Subject: [PATCH 0766/2592] MFC: r197139 - Add afexists() to check if the specified address family exists on the system or not. r197697 - Add AF_IPX and AF_NATM to afexists(). --- etc/network.subr | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/etc/network.subr b/etc/network.subr index e794faba2d7..36bfa54cef4 100644 --- a/etc/network.subr +++ b/etc/network.subr @@ -276,6 +276,37 @@ wpaif() return 1 } +# afexists af +# Returns 0 if the address family is enabled in the kernel +# 1 otherwise. +afexists() +{ + local _af + _af=$1 + + case ${_af} in + inet) + ${SYSCTL_N} net.inet > /dev/null 2>&1 + ;; + 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" + ;; + esac +} + # ipv6if if # Returns 0 if the interface should be configured for IPv6 and # 1 otherwise. From 4d672d94c1fc0dabb2d1a15e31cae47307c8b05f Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Mon, 7 Dec 2009 08:36:49 +0000 Subject: [PATCH 0767/2592] MFC: r197900 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 02a7ccf7463892f2164d5022ef4f26bbcfe87f79 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Mon, 7 Dec 2009 08:38:44 +0000 Subject: [PATCH 0768/2592] MFC: r200019 Fix the dprintf() prototype. --- lib/libc/stdio/printf.3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3 index 27d5bf0d7e0..2587aa2f0d9 100644 --- a/lib/libc/stdio/printf.3 +++ b/lib/libc/stdio/printf.3 @@ -32,7 +32,7 @@ .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd March 3, 2009 +.Dd December 2, 2009 .Dt PRINTF 3 .Os .Sh NAME @@ -55,7 +55,7 @@ .Ft int .Fn asprintf "char **ret" "const char *format" ... .Ft int -.Fn dprintf "int" "const char * restrict format" ... +.Fn dprintf "int fd" "const char * restrict format" ... .In stdarg.h .Ft int .Fn vprintf "const char * restrict format" "va_list ap" From c9ab55149b92ec6dab1f27a648f95f680d51f6b1 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Mon, 7 Dec 2009 16:37:02 +0000 Subject: [PATCH 0769/2592] MFC 199714 Create a seperate ZFS enabled loader. This adds zfsloader which will be called by zfsboot/gptzfsboot code rather than the tradional loader. This eliminates the need to set the LOADER_ZFS_SUPPORT variable in order to get a ZFS enabled loader. Note however, that you must reinstall your bootcode (zfsboot/gptzfsboot) in order for the boot process to use the new loader. New installations will no longer be required to build a ZFS enabled loader for a working ZFS boot system. Installing zfsboot/gptzfsboot is sufficient for acknowledging the use of CDDL code and therefore the ZFS enabled loader. --- sys/boot/Makefile | 2 +- sys/boot/i386/Makefile | 2 +- sys/boot/i386/loader/Makefile | 32 +++++++++++++++++++------------- sys/boot/i386/zfsboot/zfsboot.c | 2 +- sys/boot/i386/zfsloader/Makefile | 12 ++++++++++++ 5 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 sys/boot/i386/zfsloader/Makefile diff --git a/sys/boot/Makefile b/sys/boot/Makefile index 02c767df0d2..056dc68d6c4 100644 --- a/sys/boot/Makefile +++ b/sys/boot/Makefile @@ -22,7 +22,7 @@ SUBDIR+= ofw SUBDIR+= uboot .endif -.if defined(LOADER_ZFS_SUPPORT) +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE} == "i386" SUBDIR+= zfs .endif diff --git a/sys/boot/i386/Makefile b/sys/boot/i386/Makefile index 912714fe2a2..789722cae95 100644 --- a/sys/boot/i386/Makefile +++ b/sys/boot/i386/Makefile @@ -1,7 +1,7 @@ # $FreeBSD$ SUBDIR= mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot zfsboot \ - gptzfsboot kgzldr libi386 libfirewire loader + gptzfsboot kgzldr libi386 libfirewire loader zfsloader # special boot programs, 'self-extracting boot2+loader' SUBDIR+= pxeldr diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile index 8f3480ae241..719e28dd73a 100644 --- a/sys/boot/i386/loader/Makefile +++ b/sys/boot/i386/loader/Makefile @@ -3,9 +3,10 @@ .include MK_SSP= no -PROG= loader.sym +LOADER?= loader +PROG= ${LOADER}.sym INTERNALPROG= -NEWVERSWHAT= "bootstrap loader" i386 +NEWVERSWHAT?= "bootstrap loader" i386 # architecture-specific loader code SRCS= main.c conf.c vers.c @@ -16,7 +17,7 @@ CFLAGS+= -DLOADER_FIREWIRE_SUPPORT LIBFIREWIRE= ${.OBJDIR}/../libfirewire/libfirewire.a .endif -# Put LOADER_ZFS_SUPPORT=yes in /etc/make.conf for ZFS support +# Set by zfsloader Makefile .if defined(LOADER_ZFS_SUPPORT) CFLAGS+= -DLOADER_ZFS_SUPPORT LIBZFS= ${.OBJDIR}/../../zfs/libzfsboot.a @@ -61,7 +62,7 @@ CFLAGS+= -DLOADER_GPT_SUPPORT CFLAGS+= -I${.CURDIR}/../../common CFLAGS+= -I. -CLEANFILES= vers.c loader loader.bin loader.help +CLEANFILES= vers.c ${LOADER} ${LOADER}.bin loader.help CFLAGS+= -Wall LDFLAGS= -static -Ttext 0x0 @@ -80,30 +81,35 @@ CFLAGS+= -I${.CURDIR}/../btx/lib # Pick up ../Makefile.inc early. .include -vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version - sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} +vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../loader/version + sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../loader/version \ + ${NEWVERSWHAT} -loader: loader.bin ${BTXLDR} ${BTXKERN} +${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN} btxld -v -f aout -e ${LOADER_ADDRESS} -o ${.TARGET} -l ${BTXLDR} \ - -b ${BTXKERN} loader.bin + -b ${BTXKERN} ${LOADER}.bin -loader.bin: loader.sym +${LOADER}.bin: ${LOADER}.sym cp ${.ALLSRC} ${.TARGET} strip -R .comment -R .note ${.TARGET} loader.help: help.common help.i386 cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} -.PATH: ${.CURDIR}/../../forth -FILES= loader loader.help loader.4th support.4th loader.conf -FILES+= screen.4th frames.4th beastie.4th +FILES= ${LOADER} # XXX INSTALLFLAGS_loader= -b -FILESMODE_loader= ${BINMODE} -b +FILESMODE_${LOADER}= ${BINMODE} -b + +.if !defined(LOADER_ONLY) +.PATH: ${.CURDIR}/../../forth +FILES+= loader.help loader.4th support.4th loader.conf +FILES+= screen.4th frames.4th beastie.4th FILESDIR_loader.conf= /boot/defaults .if !exists(${DESTDIR}/boot/loader.rc) FILES+= loader.rc .endif +.endif # XXX crt0.o needs to be first for pxeboot(8) to work OBJS= ${BTXCRT} diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c index 690d8035bac..ca2c90e3e3f 100644 --- a/sys/boot/i386/zfsboot/zfsboot.c +++ b/sys/boot/i386/zfsboot/zfsboot.c @@ -84,7 +84,7 @@ __FBSDID("$FreeBSD$"); #define KARGS_FLAGS_ZFS 0x4 #define PATH_CONFIG "/boot.config" -#define PATH_BOOT3 "/boot/loader" +#define PATH_BOOT3 "/boot/zfsloader" #define PATH_KERNEL "/boot/kernel/kernel" #define ARGS 0x900 diff --git a/sys/boot/i386/zfsloader/Makefile b/sys/boot/i386/zfsloader/Makefile new file mode 100644 index 00000000000..51338e17f82 --- /dev/null +++ b/sys/boot/i386/zfsloader/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../loader + +LOADER= zfsloader +NEWVERSWHAT= "ZFS enabled bootstrap loader" i386 +LOADER_ZFS_SUPPORT=yes +LOADER_ONLY= yes +NO_MAN= yes + +.include "${.CURDIR}/../loader/Makefile" + From 42e9dd5cad7cc051b8fe186ef5ef3a9775deb1ed Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 7 Dec 2009 17:18:52 +0000 Subject: [PATCH 0770/2592] MFC 199974: Remove extra parantheses from usb_ethernet.c and usb_serial.c lines. config(8) doesn't parse parantheses and instead treated them as being part of the device driver name (e.g. '(u3g' vs 'u3g'). While here, fix the style of these long lines to match the wrapping used for other long lines in this file. --- sys/conf/files | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sys/conf/files b/sys/conf/files index 70be131559d..e7afc91906e 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1624,8 +1624,8 @@ dev/usb/net/if_cue.c optional cue dev/usb/net/if_kue.c optional kue dev/usb/net/if_rue.c optional rue dev/usb/net/if_udav.c optional udav -dev/usb/net/usb_ethernet.c \ - optional (aue | axe | cdce | cue | kue | rue | udav) +dev/usb/net/usb_ethernet.c optional aue | axe | cdce | cue | kue | rue | \ + udav # # USB WLAN drivers # @@ -1656,8 +1656,11 @@ dev/usb/serial/uplcom.c optional uplcom 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 | uchcom | ucycom | ufoma | uftdi | ugensa | uipaq | ulpt | umct | umodem | umoscom | uplcom | uslcom | uvisor | uvscom) +dev/usb/serial/usb_serial.c optional ucom | u3g | uark | ubsa | ubser | \ + uchcom | ucycom | ufoma | uftdi | \ + ugensa | uipaq | ulpt | umct | \ + umodem | umoscom | uplcom | uslcom | \ + uvisor | uvscom # # USB misc drivers # From cd6d7a15cfd3f60cc5fdd21d6506e477149f78ac Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 7 Dec 2009 19:07:45 +0000 Subject: [PATCH 0771/2592] MFC 200061: The fd_mask type is an unsigned long, not an int, so treat the mask as a long instead of an int when examining the results of select() to look for RPC requests. Previously this routine would ignore RPC requests to sockets whose file descriptor mod 64 was greater than 31 on a 64-bit platform. --- lib/libc/rpc/svc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/rpc/svc.c b/lib/libc/rpc/svc.c index d2051218f49..282c2be2e19 100644 --- a/lib/libc/rpc/svc.c +++ b/lib/libc/rpc/svc.c @@ -627,8 +627,8 @@ svc_getreqset(readfds) maskp = readfds->fds_bits; for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) { - for (mask = *maskp++; (bit = ffs(mask)) != 0; - mask ^= (1 << (bit - 1))) { + for (mask = *maskp++; (bit = ffsl(mask)) != 0; + mask ^= (1ul << (bit - 1))) { /* sock has input waiting */ fd = sock + bit - 1; svc_getreq_common(fd); From 931d13672c6ca2cd8c0b8a74767bd900cd7ca43a Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 7 Dec 2009 19:59:28 +0000 Subject: [PATCH 0772/2592] MFC revision 197579 and 199617: Add two new fcntls to enable/disable read-ahead: - F_READAHEAD: specify the amount for sequential access. The amount is specified in bytes and is rounded up to nearest block size. - F_RDAHEAD: Darwin compatible version that use 128KB as the sequential access size. A third argument of zero disables the read-ahead behavior. Please note that the read-ahead amount is also constrainted by sysctl variable, vfs.read_max, which may need to be raised in order to better utilize this feature. Thanks Igor Sysoev for proposing the feature and submitting the original version, and kib@ for his valuable comments. --- lib/libc/sys/fcntl.2 | 18 ++++++++++++++++- sys/kern/kern_descrip.c | 45 +++++++++++++++++++++++++++++++++++++++++ sys/kern/vfs_vnops.c | 3 +++ sys/sys/fcntl.h | 9 +++++++-- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/lib/libc/sys/fcntl.2 b/lib/libc/sys/fcntl.2 index a16724c9e0b..250cef46d5d 100644 --- a/lib/libc/sys/fcntl.2 +++ b/lib/libc/sys/fcntl.2 @@ -28,7 +28,7 @@ .\" @(#)fcntl.2 8.2 (Berkeley) 1/12/94 .\" $FreeBSD$ .\" -.Dd March 8, 2008 +.Dd September 28, 2009 .Dt FCNTL 2 .Os .Sh NAME @@ -241,6 +241,22 @@ will be interrupted if the signal handler has not specified the .Dv SA_RESTART (see .Xr sigaction 2 ) . +.It Dv F_READAHEAD +Set or clear the read ahead amount for sequential access to the third +argument, +.Fa arg , +which is rounded up to the nearest block size. +A zero value in +.Fa arg +turns off read ahead. +.It Dv F_RDAHEAD +Equivalent to Darwin counterpart which sets read ahead amount of 128KB +when the third argument, +.Fa arg +is non-zero. +A zero value in +.Fa arg +turns off read ahead. .El .Pp When a shared lock has been set on a segment of a file, diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 91733db35d7..676de650524 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -421,6 +421,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) struct vnode *vp; int error, flg, tmp; int vfslocked; + u_int old, new; + uint64_t bsize; vfslocked = 0; error = 0; @@ -686,6 +688,49 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) vfslocked = 0; fdrop(fp, td); break; + + case F_RDAHEAD: + arg = arg ? 128 * 1024: 0; + /* FALLTHROUGH */ + case F_READAHEAD: + FILEDESC_SLOCK(fdp); + if ((fp = fdtofp(fd, fdp)) == NULL) { + FILEDESC_SUNLOCK(fdp); + error = EBADF; + break; + } + if (fp->f_type != DTYPE_VNODE) { + FILEDESC_SUNLOCK(fdp); + error = EBADF; + break; + } + fhold(fp); + FILEDESC_SUNLOCK(fdp); + if (arg != 0) { + vp = fp->f_vnode; + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + error = vn_lock(vp, LK_SHARED); + if (error != 0) + goto readahead_vnlock_fail; + bsize = fp->f_vnode->v_mount->mnt_stat.f_iosize; + VOP_UNLOCK(vp, 0); + fp->f_seqcount = (arg + bsize - 1) / bsize; + do { + new = old = fp->f_flag; + new |= FRDAHEAD; + } while (!atomic_cmpset_rel_int(&fp->f_flag, old, new)); +readahead_vnlock_fail: + VFS_UNLOCK_GIANT(vfslocked); + vfslocked = 0; + } else { + do { + new = old = fp->f_flag; + new &= ~FRDAHEAD; + } while (!atomic_cmpset_rel_int(&fp->f_flag, old, new)); + } + fdrop(fp, td); + break; + default: error = EINVAL; break; diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 1b77352b1c6..03e8d938bac 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -312,6 +312,9 @@ static int sequential_heuristic(struct uio *uio, struct file *fp) { + if (atomic_load_acq_int(&(fp->f_flag)) & FRDAHEAD) + return (fp->f_seqcount << IO_SEQSHIFT); + /* * Offset 0 is handled specially. open() sets f_seqcount to 1 so * that the first I/O is normally considered to be slightly diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h index 893bbcd677c..ef394a3fe66 100644 --- a/sys/sys/fcntl.h +++ b/sys/sys/fcntl.h @@ -140,7 +140,7 @@ typedef __pid_t pid_t; /* bits to save after open */ #define FMASK (FREAD|FWRITE|FAPPEND|FASYNC|FFSYNC|FNONBLOCK|O_DIRECT|FEXEC) /* bits settable by fcntl(F_SETFL, ...) */ -#define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|O_DIRECT) +#define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FRDAHEAD|O_DIRECT) #if defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD6) || \ defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) @@ -151,7 +151,8 @@ typedef __pid_t pid_t; */ #define FPOSIXSHM O_NOFOLLOW #undef FCNTLFLAGS -#define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FPOSIXSHM|O_DIRECT) +#define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FPOSIXSHM|FRDAHEAD| \ + O_DIRECT) #endif #endif @@ -176,6 +177,8 @@ typedef __pid_t pid_t; * different meaning for fcntl(2). */ #if __BSD_VISIBLE +/* Read ahead */ +#define FRDAHEAD O_CREAT #endif /* Defined by POSIX Extended API Set Part 2 */ @@ -218,6 +221,8 @@ typedef __pid_t pid_t; #define F_SETLK 12 /* set record locking information */ #define F_SETLKW 13 /* F_SETLK; wait if blocked */ #define F_SETLK_REMOTE 14 /* debugging support for remote locks */ +#define F_READAHEAD 15 /* read ahead */ +#define F_RDAHEAD 16 /* Darwin compatible read ahead */ /* file descriptor flags (F_GETFD, F_SETFD) */ #define FD_CLOEXEC 1 /* close-on-exec flag */ From 29439ac7a116c717becb000517d1a1b552ff234a Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Mon, 7 Dec 2009 20:40:48 +0000 Subject: [PATCH 0773/2592] MFC 198432: 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. --- 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 f84e0f1548c..6ae18fe3fe9 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -1954,11 +1954,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 d7fbf69d9667de852983ca85d0599948d55f6bc1 Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Mon, 7 Dec 2009 20:44:43 +0000 Subject: [PATCH 0774/2592] MFC 198433: 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. --- 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 86cff089e71c766a2e1f57155c3086370e228757 Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Mon, 7 Dec 2009 20:49:49 +0000 Subject: [PATCH 0775/2592] MFC 200060: Use a better check for a valid kernel stack address when capturing kernel call chains. --- sys/dev/hwpmc/hwpmc_x86.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_x86.c b/sys/dev/hwpmc/hwpmc_x86.c index 6df47d32fec..8c98983b571 100644 --- a/sys/dev/hwpmc/hwpmc_x86.c +++ b/sys/dev/hwpmc/hwpmc_x86.c @@ -176,7 +176,8 @@ pmc_save_kernel_callchain(uintptr_t *cc, int nframes, struct trapframe *tf) stackend = (uintptr_t) td->td_kstack + td->td_kstack_pages * PAGE_SIZE; if (PMC_IN_TRAP_HANDLER(pc) || - !PMC_IN_KERNEL(pc) || !PMC_IN_KERNEL(r) || + !PMC_IN_KERNEL(pc) || + !PMC_IN_KERNEL_STACK(r, stackstart, stackend) || !PMC_IN_KERNEL_STACK(sp, stackstart, stackend) || !PMC_IN_KERNEL_STACK(fp, stackstart, stackend)) return (1); @@ -221,7 +222,7 @@ pmc_save_kernel_callchain(uintptr_t *cc, int nframes, struct trapframe *tf) r = fp + sizeof(uintptr_t); if (!PMC_IN_KERNEL_STACK(fp, stackstart, stackend) || - !PMC_IN_KERNEL(r)) + !PMC_IN_KERNEL_STACK(r, stackstart, stackend)) break; pc = *(uintptr_t *) r; fp = *(uintptr_t *) fp; From 9ad8053be531f0f4d0c70fb99212ebae8b053650 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Tue, 8 Dec 2009 05:18:59 +0000 Subject: [PATCH 0776/2592] MFC r200070: Add manpages for ams(4), akbd(4), adb(4), and cuda(4), which describe various drivers for Apple Desktop Bus controllers and peripherals. --- share/man/man4/man4.powerpc/Makefile | 6 +- share/man/man4/man4.powerpc/adb.4 | 70 ++++++++++++++++++++++ share/man/man4/man4.powerpc/akbd.4 | 76 ++++++++++++++++++++++++ share/man/man4/man4.powerpc/ams.4 | 87 ++++++++++++++++++++++++++++ share/man/man4/man4.powerpc/cuda.4 | 79 +++++++++++++++++++++++++ share/man/man4/man4.powerpc/pmu.4 | 3 +- 6 files changed, 319 insertions(+), 2 deletions(-) create mode 100644 share/man/man4/man4.powerpc/adb.4 create mode 100644 share/man/man4/man4.powerpc/akbd.4 create mode 100644 share/man/man4/man4.powerpc/ams.4 create mode 100644 share/man/man4/man4.powerpc/cuda.4 diff --git a/share/man/man4/man4.powerpc/Makefile b/share/man/man4/man4.powerpc/Makefile index 8d9977186c0..d213d83fe68 100644 --- a/share/man/man4/man4.powerpc/Makefile +++ b/share/man/man4/man4.powerpc/Makefile @@ -1,6 +1,10 @@ # $FreeBSD$ -MAN= bm.4 \ +MAN= adb.4 \ + akbd.4 \ + ams.4 \ + bm.4 \ + cuda.4 \ pmu.4 \ powermac_nvram.4 \ snd_ai2s.4 \ diff --git a/share/man/man4/man4.powerpc/adb.4 b/share/man/man4/man4.powerpc/adb.4 new file mode 100644 index 00000000000..eb34ecaf0c4 --- /dev/null +++ b/share/man/man4/man4.powerpc/adb.4 @@ -0,0 +1,70 @@ +.\"- +.\" Copyright (c) 2009 Nathan Whitehorn +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 3, 2009 +.Dt ADB 4 +.Os +.Sh NAME +.Nm adb +.Nd Apple Desktop Bus +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device adb" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides support for the Apple Desktop Bus, which is a simple +multi-drop bus used in general for input peripherals in older Apple +Macintosh hardware. +.Pp +The Apple Desktop Bus provides attachment for up to 16 devices, +including multiple devices of a single type, but not does support +hot-plugging. +.Sh SEE ALSO +Apple Tech Note HW01: ADB - The Untold Story: Space Aliens Ate My Mouse: +.Pa http://developer.apple.com/legacy/mac/library/technotes/hw/hw_01.html +.Pp +.Xr akbd 4 , +.Xr ams 4 , +.Xr cuda 4 , +.Xr pmu 4 +.Sh HISTORY +The +.Nm +device driver appeared in +.Fx 8.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Nathan Whitehorn +.Aq nwhitehorn@FreeBSD.org . diff --git a/share/man/man4/man4.powerpc/akbd.4 b/share/man/man4/man4.powerpc/akbd.4 new file mode 100644 index 00000000000..aea2fa01f50 --- /dev/null +++ b/share/man/man4/man4.powerpc/akbd.4 @@ -0,0 +1,76 @@ +.\"- +.\" Copyright (c) 2009 Nathan Whitehorn +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 3, 2009 +.Dt AKBD 4 +.Os +.Sh NAME +.Nm akbd +.Nd ADB Keyboard Driver +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device adb" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides support for all keyboards attached to the Apple Desktop +Bus (ADB). +.Sh HARDWARE +Devices supported by the +.Nm +driver include: +.Pp +.Bl -bullet -compact +.It +Apple Extended Keyboard +.It +Apple Keyboard II +.It +Apple iBook Keyboard +.It +Apple PowerBook Keyboard +.El +.Sh SEE ALSO +.Xr adb 4 , +.Xr cuda 4 , +.Xr pmu 4 +.Sh HISTORY +The +.Nm +device driver appeared in +.Fx 8.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Nathan Whitehorn +.Aq nwhitehorn@FreeBSD.org . diff --git a/share/man/man4/man4.powerpc/ams.4 b/share/man/man4/man4.powerpc/ams.4 new file mode 100644 index 00000000000..15560cf3d9e --- /dev/null +++ b/share/man/man4/man4.powerpc/ams.4 @@ -0,0 +1,87 @@ +.\"- +.\" Copyright (c) 2009 Nathan Whitehorn +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 3, 2009 +.Dt AMS 4 +.Os +.Sh NAME +.Nm ams +.Nd ADB Mouse Driver +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device adb" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides support for mice and trackpads attached to the Apple Desktop +Bus (ADB) implementing both the base and extended ADB mouse protocols. +.Sh HARDWARE +Devices supported by the +.Nm +driver include: +.Pp +.Bl -bullet -compact +.It +Apple Mouse +.It +ADB Extended Mouse +.It +MacAlly 2-Button Mouse +.It +Apple iBook Trackpad +.It +Apple PowerBook Trackpad +.El +.Sh SYSCTL VARIABLES +.Bl -tag -width indent +.It Va dev.ams.%d.tapping +On ADB trackpads, setting this sysctl to 1 causes taps on the trackpad to +be interpreted as button clicks. +.El +.Sh SEE ALSO +Apple Tech Note HW01: ADB - The Untold Story: Space Aliens Ate My Mouse: +.Pa http://developer.apple.com/legacy/mac/library/technotes/hw/hw_01.html +.Pp +.Xr adb 4 , +.Xr cuda 4 , +.Xr pmu 4 +.Sh HISTORY +The +.Nm +device driver appeared in +.Fx 8.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Nathan Whitehorn +.Aq nwhitehorn@FreeBSD.org . diff --git a/share/man/man4/man4.powerpc/cuda.4 b/share/man/man4/man4.powerpc/cuda.4 new file mode 100644 index 00000000000..4b4b2180cce --- /dev/null +++ b/share/man/man4/man4.powerpc/cuda.4 @@ -0,0 +1,79 @@ +.\"- +.\" Copyright (c) 2009 Nathan Whitehorn +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 3, 2009 +.Dt CUDA 4 +.Os +.Sh NAME +.Nm cuda +.Nd Apple CUDA I/O Controller Driver +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device adb" +.Cd "device cuda" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides support for the CUDA VIA (Versatile Interface Attachment) +chip found in pre-Core99 Apple hardware, such as the Power Macintosh G3. +.Pp +The Apple CUDA controller is a multi-purpose ASIC that provides power +control and an +.Xr adb 4 +interface. +.Sh HARDWARE +Chips supported by the +.Nm +driver include: +.Pp +.Bl -bullet -compact +.It +Apple CUDA I/O Controller +.El +.Sh SEE ALSO +.Xr adb 4 +.Sh HISTORY +The +.Nm +device driver appeared in +.Nx 4.0 , +and then in +.Fx 8.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Michael Lorenz +.Aq macallan@NetBSD.org +and ported to FreeBSD by +.An Nathan Whitehorn +.Aq nwhitehorn@FreeBSD.org . diff --git a/share/man/man4/man4.powerpc/pmu.4 b/share/man/man4/man4.powerpc/pmu.4 index 872f8ac3d9c..ab998772a6f 100644 --- a/share/man/man4/man4.powerpc/pmu.4 +++ b/share/man/man4/man4.powerpc/pmu.4 @@ -95,7 +95,8 @@ Current fraction of the battery's maximum charge, in percent. .El .Sh SEE ALSO .Xr acpi 4 , -.Xr adb 4 +.Xr adb 4 , +.Xr led 4 .Sh HISTORY The .Nm From 3958967343ecb31deadabfa5728d87151f9cb7c5 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Tue, 8 Dec 2009 05:23:07 +0000 Subject: [PATCH 0777/2592] MFC r198444: 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 e9962146c697ab9b8ef2b296ba7129d6f7091d75 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Tue, 8 Dec 2009 05:27:06 +0000 Subject: [PATCH 0778/2592] MFC r198445: 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. MFC r198968: Unbreak E500 builds. The inline assembly for the 970 CPUs is invalid when compiling for BookE. MFC r199533: Fix cpuid output on E500 core. --- sys/powerpc/include/hid.h | 7 ++ sys/powerpc/powerpc/cpu.c | 255 ++++++++++++++++++++++++-------------- 2 files changed, 170 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..61630a4c3c8 100644 --- a/sys/powerpc/powerpc/cpu.c +++ b/sys/powerpc/powerpc/cpu.c @@ -114,16 +114,21 @@ 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); +#ifndef E500 +static void cpu_970_setup(int cpuid, uint16_t vers); +#endif 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 +175,8 @@ cpu_setup(u_int cpuid) break; } - hid0 = mfspr(SPR_HID0); - /* - * Configure power-saving mode. + * Configure CPU */ switch (vers) { case MPC603: @@ -184,102 +187,36 @@ 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; +#ifndef E500 case IBM970: case IBM970FX: + case IBM970GX: case IBM970MP: - cpu_print_speed(); - printf("\n"); + cpu_970_setup(cpuid, vers); break; +#endif + + 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 +283,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 +423,46 @@ 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; + + printf("\n"); + + hid0 = mfspr(SPR_HID0); + printf("cpu%d: HID0 %b", cpuid, (int)hid0, HID0_E500_BITMASK); +} + +#ifndef E500 +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); +} +#endif From 3c2ef7963485084f2813709f92a88dfa5aeb6ed6 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Tue, 8 Dec 2009 05:32:44 +0000 Subject: [PATCH 0779/2592] MFC r198678: ake 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 496ef31252e9c0c18981292a7bc230935973b4b7 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Tue, 8 Dec 2009 05:37:08 +0000 Subject: [PATCH 0780/2592] MFC r199886: Add a CPU features framework on PowerPC and simplify CPU setup a little more. This provides three new sysctls to user space: hw.cpu_features - A bitmask of available CPU features hw.floatingpoint - Whether or not there is hardware FP support hw.altivec - Whether or not Altivec is available PR: powerpc/139154 --- sys/powerpc/aim/machdep.c | 9 +- sys/powerpc/aim/ofw_machdep.c | 3 +- sys/powerpc/booke/machdep.c | 1 - sys/powerpc/include/cpu.h | 21 ++++ sys/powerpc/include/md_var.h | 1 - sys/powerpc/powerpc/cpu.c | 195 ++++++++++++++++++---------------- 6 files changed, 131 insertions(+), 99 deletions(-) diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index da73dfab3ff..b5202e77b36 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -130,7 +130,6 @@ extern vm_offset_t ksym_start, ksym_end; int cold = 1; int cacheline_size = 32; -int ppc64 = 0; int hw_direct_map = 1; struct pcpu __pcpu[MAXCPU]; @@ -256,6 +255,7 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) char *env; uint32_t msr, scratch; uint8_t *cache_check; + int ppc64; end = 0; kmdp = NULL; @@ -405,12 +405,15 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) mfsprg2 %1;" : "=r"(scratch), "=r"(ppc64)); + if (ppc64) + cpu_features |= PPC_FEATURE_64; + /* * Now copy restorebridge into all the handlers, if necessary, * and set up the trap tables. */ - if (ppc64) { + if (cpu_features & PPC_FEATURE_64) { /* Patch the two instances of rfi -> rfid */ bcopy(&rfid_patch,&rfi_patch1,4); #ifdef KDB @@ -489,7 +492,7 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) * in case the platform module had a better idea of what we * should do. */ - if (ppc64) + if (cpu_features & PPC_FEATURE_64) pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); else pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c index 773d229d3a2..6e276970edd 100644 --- a/sys/powerpc/aim/ofw_machdep.c +++ b/sys/powerpc/aim/ofw_machdep.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -336,7 +337,7 @@ openfirmware(void *args) /* * Clear battable[] translations */ - if (!ppc64) { + if (!(cpu_features & PPC_FEATURE_64)) { __asm __volatile("mtdbatu 2, %0\n" "mtdbatu 3, %0" : : "r" (0)); } diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index 87870985ac8..72ff977c6b5 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -179,7 +179,6 @@ SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, CTLFLAG_RD, &cacheline_size, 0, ""); int hw_direct_map = 0; -int ppc64 = 0; static void cpu_e500_startup(void *); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_e500_startup, NULL); diff --git a/sys/powerpc/include/cpu.h b/sys/powerpc/include/cpu.h index 9856ab0588e..16cabe7887c 100644 --- a/sys/powerpc/include/cpu.h +++ b/sys/powerpc/include/cpu.h @@ -39,6 +39,27 @@ #include #include +/* + * CPU Feature Attributes + * + * These are defined in the PowerPC ELF ABI for the AT_HWCAP vector, + * and are exported to userland via the machdep.cpu_features + * sysctl. + */ + +extern int cpu_features; + +#define PPC_FEATURE_32 0x80000000 /* Always true */ +#define PPC_FEATURE_64 0x40000000 /* Defined on a 64-bit CPU */ +#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 +#define PPC_FEATURE_HAS_FPU 0x08000000 +#define PPC_FEATURE_HAS_MMU 0x04000000 +#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 + +#define PPC_FEATURE_BITMASK \ + "\20" \ + "\040PPC32\037PPC64\035ALTIVEC\034FPU\033MMU\031UNIFIEDCACHE" + #define TRAPF_USERMODE(frame) (((frame)->srr1 & PSL_PR) != 0) #define TRAPF_PC(frame) ((frame)->srr0) diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h index d1785adfbe0..bfe5ed23829 100644 --- a/sys/powerpc/include/md_var.h +++ b/sys/powerpc/include/md_var.h @@ -46,7 +46,6 @@ extern u_long ns_per_tick; extern int powerpc_pow_enabled; extern int cacheline_size; -extern int ppc64; extern int hw_direct_map; void __syncicache(void *, int); diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c index 61630a4c3c8..ebf36ee161b 100644 --- a/sys/powerpc/powerpc/cpu.c +++ b/sys/powerpc/powerpc/cpu.c @@ -67,6 +67,7 @@ #include #include +#include #include #include #include @@ -74,59 +75,102 @@ int powerpc_pow_enabled; +static void cpu_6xx_setup(int cpuid, uint16_t vers); +static void cpu_e500_setup(int cpuid, uint16_t vers); +static void cpu_970_setup(int cpuid, uint16_t vers); + struct cputab { const char *name; uint16_t version; uint16_t revfmt; + int features; /* Do not include PPC_FEATURE_32 or + * PPC_FEATURE_HAS_MMU */ + void (*cpu_setup)(int cpuid, uint16_t vers); }; #define REVFMT_MAJMIN 1 /* %u.%u */ #define REVFMT_HEX 2 /* 0x%04x */ #define REVFMT_DEC 3 /* %u */ static const struct cputab models[] = { - { "Motorola PowerPC 601", MPC601, REVFMT_DEC }, - { "Motorola PowerPC 602", MPC602, REVFMT_DEC }, - { "Motorola PowerPC 603", MPC603, REVFMT_MAJMIN }, - { "Motorola PowerPC 603e", MPC603e, REVFMT_MAJMIN }, - { "Motorola PowerPC 603ev", MPC603ev, REVFMT_MAJMIN }, - { "Motorola PowerPC 604", MPC604, REVFMT_MAJMIN }, - { "Motorola PowerPC 604ev", MPC604ev, REVFMT_MAJMIN }, - { "Motorola PowerPC 620", MPC620, REVFMT_HEX }, - { "Motorola PowerPC 750", MPC750, REVFMT_MAJMIN }, - { "IBM PowerPC 750FX", IBM750FX, REVFMT_MAJMIN }, - { "IBM PowerPC 970", IBM970, REVFMT_MAJMIN }, - { "IBM PowerPC 970FX", IBM970FX, REVFMT_MAJMIN }, - { "IBM PowerPC 970GX", IBM970GX, REVFMT_MAJMIN }, - { "IBM PowerPC 970MP", IBM970MP, REVFMT_MAJMIN }, - { "Motorola PowerPC 7400", MPC7400, REVFMT_MAJMIN }, - { "Motorola PowerPC 7410", MPC7410, REVFMT_MAJMIN }, - { "Motorola PowerPC 7450", MPC7450, REVFMT_MAJMIN }, - { "Motorola PowerPC 7455", MPC7455, REVFMT_MAJMIN }, - { "Motorola PowerPC 7457", MPC7457, REVFMT_MAJMIN }, - { "Motorola PowerPC 7447A", MPC7447A, REVFMT_MAJMIN }, - { "Motorola PowerPC 7448", MPC7448, REVFMT_MAJMIN }, - { "Motorola PowerPC 8240", MPC8240, REVFMT_MAJMIN }, - { "Freescale e500v1 core", FSL_E500v1, REVFMT_MAJMIN }, - { "Freescale e500v2 core", FSL_E500v2, REVFMT_MAJMIN }, - { "Unknown PowerPC CPU", 0, REVFMT_HEX } + { "Motorola PowerPC 601", MPC601, REVFMT_DEC, + PPC_FEATURE_HAS_FPU | PPC_FEATURE_UNIFIED_CACHE, cpu_6xx_setup }, + { "Motorola PowerPC 602", MPC602, REVFMT_DEC, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 603", MPC603, REVFMT_MAJMIN, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 603e", MPC603e, REVFMT_MAJMIN, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 603ev", MPC603ev, REVFMT_MAJMIN, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 604", MPC604, REVFMT_MAJMIN, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 604ev", MPC604ev, REVFMT_MAJMIN, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 620", MPC620, REVFMT_HEX, + PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL }, + { "Motorola PowerPC 750", MPC750, REVFMT_MAJMIN, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "IBM PowerPC 750FX", IBM750FX, REVFMT_MAJMIN, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "IBM PowerPC 970", IBM970, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, + cpu_970_setup }, + { "IBM PowerPC 970FX", IBM970FX, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, + cpu_970_setup }, + { "IBM PowerPC 970GX", IBM970GX, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, + cpu_970_setup }, + { "IBM PowerPC 970MP", IBM970MP, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, + cpu_970_setup }, + { "Motorola PowerPC 7400", MPC7400, REVFMT_MAJMIN, + PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 7410", MPC7410, REVFMT_MAJMIN, + PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 7450", MPC7450, REVFMT_MAJMIN, + PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 7455", MPC7455, REVFMT_MAJMIN, + PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 7457", MPC7457, REVFMT_MAJMIN, + PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 7447A", MPC7447A, REVFMT_MAJMIN, + PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 7448", MPC7448, REVFMT_MAJMIN, + PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 8240", MPC8240, REVFMT_MAJMIN, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Motorola PowerPC 8245", MPC8245, REVFMT_MAJMIN, + PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, + { "Freescale e500v1 core", FSL_E500v1, REVFMT_MAJMIN, + 0, cpu_e500_setup }, + { "Freescale e500v2 core", FSL_E500v2, REVFMT_MAJMIN, + 0, cpu_e500_setup }, + { "Unknown PowerPC CPU", 0, REVFMT_HEX, 0, NULL }, }; +static void cpu_6xx_print_cacheinfo(u_int, uint16_t); +static int cpu_feature_bit(SYSCTL_HANDLER_ARGS); + static char model[64]; SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, ""); -static void cpu_print_speed(void); +int cpu_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU; +SYSCTL_OPAQUE(_hw, OID_AUTO, cpu_features, CTLTYPE_INT | CTLFLAG_RD, + &cpu_features, sizeof(cpu_features), "IX", "PowerPC CPU features"); -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 +/* Provide some user-friendly aliases for bits in cpu_features */ +SYSCTL_PROC(_hw, OID_AUTO, floatingpoint, CTLTYPE_INT | CTLFLAG_RD, + 0, PPC_FEATURE_HAS_FPU, cpu_feature_bit, "I", + "Floating point instructions executed in hardware"); +SYSCTL_PROC(_hw, OID_AUTO, altivec, CTLTYPE_INT | CTLFLAG_RD, + 0, PPC_FEATURE_HAS_ALTIVEC, cpu_feature_bit, "I", "CPU supports Altivec"); void cpu_setup(u_int cpuid) { u_int pvr, maj, min; uint16_t vers, rev, revfmt; + uint64_t cps; const struct cputab *cp; const char *name; @@ -175,57 +219,19 @@ cpu_setup(u_int cpuid) break; } + if (cpu_est_clockrate(0, &cps) == 0) + printf(", %lld.%02lld MHz", cps / 1000000, (cps / 10000) % 100); + printf("\n"); + + cpu_features |= cp->features; + printf("cpu%d: Features %b\n", cpuid, cpu_features, + PPC_FEATURE_BITMASK); + /* * Configure CPU */ - switch (vers) { - case MPC603: - case MPC603e: - case MPC603ev: - case MPC604ev: - case MPC750: - case IBM750FX: - case MPC7400: - case MPC7410: - case MPC7447A: - case MPC7448: - case MPC7450: - case MPC7455: - case MPC7457: - case MPC8240: - case MPC8245: - 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: - cpu_e500_setup(cpuid, vers); - break; - - default: - /* HID setup is unknown */ - break; - } - - printf("\n"); -} - -void -cpu_print_speed(void) -{ - uint64_t cps; - - if (cpu_est_clockrate(0, &cps) == 0) - printf(", %lld.%02lld MHz", cps / 1000000, (cps / 10000) % 100); + if (cp->cpu_setup != NULL) + cp->cpu_setup(cpuid, vers); } /* Get current clock frequency for the given cpu id. */ @@ -351,9 +357,6 @@ cpu_6xx_setup(int cpuid, uint16_t vers) mtspr(SPR_HID0, hid0); - cpu_print_speed(); - printf("\n"); - if (bootverbose) cpu_6xx_print_cacheinfo(cpuid, vers); @@ -370,7 +373,7 @@ cpu_6xx_setup(int cpuid, uint16_t vers) break; } - printf("cpu%d: HID0 %b", cpuid, (int)hid0, bitmask); + printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, bitmask); } @@ -429,16 +432,14 @@ cpu_e500_setup(int cpuid, uint16_t vers) { register_t hid0; - printf("\n"); - hid0 = mfspr(SPR_HID0); - printf("cpu%d: HID0 %b", cpuid, (int)hid0, HID0_E500_BITMASK); + printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, HID0_E500_BITMASK); } -#ifndef E500 static void cpu_970_setup(int cpuid, uint16_t vers) { +#ifdef AIM uint32_t hid0_hi, hid0_lo; __asm __volatile ("mfspr %0,%2; clrldi %1,%0,32; srdi %0,%0,32;" @@ -458,11 +459,19 @@ cpu_970_setup(int cpuid, uint16_t vers) 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); -} + printf("cpu%d: HID0 %b\n", cpuid, (int)(hid0_hi), HID0_970_BITMASK); #endif +} + +static int +cpu_feature_bit(SYSCTL_HANDLER_ARGS) +{ + int result; + + result = (cpu_features & arg2) ? 1 : 0; + + return (sysctl_handle_int(oidp, &result, 0, req)); +} + From 66d19b85791a45251c5d121efd799f5b7b1b31d0 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 8 Dec 2009 15:14:55 +0000 Subject: [PATCH 0781/2592] MFC r200052: ichsmb: add pci ids for some newer supported hardware --- sys/dev/ichsmb/ichsmb_pci.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sys/dev/ichsmb/ichsmb_pci.c b/sys/dev/ichsmb/ichsmb_pci.c index b6d11df94ff..ee544b43666 100644 --- a/sys/dev/ichsmb/ichsmb_pci.c +++ b/sys/dev/ichsmb/ichsmb_pci.c @@ -75,6 +75,9 @@ __FBSDID("$FreeBSD$"); #define ID_82801EB 0x24D38086 #define ID_82801FB 0x266A8086 #define ID_82801GB 0x27da8086 +#define ID_82801H 0x283e8086 +#define ID_82801I 0x29308086 +#define ID_82801JI 0x3a308086 #define ID_6300ESB 0x25a48086 #define ID_631xESB 0x269b8086 @@ -152,6 +155,15 @@ ichsmb_pci_probe(device_t dev) case ID_82801GB: device_set_desc(dev, "Intel 82801GB (ICH7) SMBus controller"); break; + case ID_82801H: + device_set_desc(dev, "Intel 82801H (ICH8) SMBus controller"); + break; + case ID_82801I: + device_set_desc(dev, "Intel 82801I (ICH9) SMBus controller"); + break; + case ID_82801JI: + device_set_desc(dev, "Intel 82801JI (ICH10) SMBus controller"); + break; case ID_6300ESB: device_set_desc(dev, "Intel 6300ESB (ICH) SMBus controller"); break; From 3ed91d6a6d39d998cf03562b989ce3b95e73c53a Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 8 Dec 2009 15:21:39 +0000 Subject: [PATCH 0782/2592] MFC r199184: reflect that pg_ps_enabled is a tunable --- sys/amd64/amd64/pmap.c | 2 +- sys/i386/i386/pmap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d3d653d95c7..70fc04115b0 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -181,7 +181,7 @@ pt_entry_t pg_nx; 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 f37e45cb776..2a8bb1111c1 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -217,7 +217,7 @@ static int pat_works; /* 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?"); /* From 2cd46f059b715bf8ebf2a147b07501f3d648a145 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 8 Dec 2009 15:27:06 +0000 Subject: [PATCH 0783/2592] MFC r199968: x86 cpu features: add MOVBE reporting and flag --- sys/amd64/amd64/identcpu.c | 2 +- sys/amd64/include/specialreg.h | 1 + sys/i386/i386/identcpu.c | 2 +- sys/i386/include/specialreg.h | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c index 420dd03cc76..3cd2f5e4ba8 100644 --- a/sys/amd64/amd64/identcpu.c +++ b/sys/amd64/amd64/identcpu.c @@ -259,7 +259,7 @@ printcpuinfo(void) "\024SSE4.1" "\025SSE4.2" "\026x2APIC" /* xAPIC Extensions */ - "\027" + "\027MOVBE" "\030POPCNT" "\031" "\032" diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h index d1f0c8924ad..8cadbcd22f6 100644 --- a/sys/amd64/include/specialreg.h +++ b/sys/amd64/include/specialreg.h @@ -129,6 +129,7 @@ #define CPUID2_SSE41 0x00080000 #define CPUID2_SSE42 0x00100000 #define CPUID2_X2APIC 0x00200000 +#define CPUID2_MOVBE 0x00400000 #define CPUID2_POPCNT 0x00800000 /* diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c index edb861b3c47..62c27abca47 100644 --- a/sys/i386/i386/identcpu.c +++ b/sys/i386/i386/identcpu.c @@ -746,7 +746,7 @@ printcpuinfo(void) "\024SSE4.1" "\025SSE4.2" "\026x2APIC" /* xAPIC Extensions */ - "\027" + "\027MOVBE" "\030POPCNT" "\031" "\032" diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h index c2030597a06..d51da6d59fe 100644 --- a/sys/i386/include/specialreg.h +++ b/sys/i386/include/specialreg.h @@ -126,6 +126,7 @@ #define CPUID2_SSE41 0x00080000 #define CPUID2_SSE42 0x00100000 #define CPUID2_X2APIC 0x00200000 +#define CPUID2_MOVBE 0x00400000 #define CPUID2_POPCNT 0x00800000 /* From a1b9e5fa76774ab942c56a77686ce41b16a44c36 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 8 Dec 2009 18:23:51 +0000 Subject: [PATCH 0784/2592] MFC revisions 196550 and 196552: Add a new rc.d script, static_arp, which enables the administrator to statically bind IPv4 <-> MAC address at boot time. In order to use this, the administrator needs to configure the following rc.conf(5) variable: - static_arp_pairs: A list of names for static bind pairs, and, - a series of static_arp_(name): the arguments that is being passed to ``arp -S'' operation. Example: static_arp_pairs="gw" static_arp_gw="192.168.1.1 00:01:02:03:04:05" See the rc.conf(5) manual page for more details. --- etc/defaults/rc.conf | 1 + etc/rc.d/Makefile | 2 +- etc/rc.d/static_arp | 73 ++++++++++++++++++++++++++++++++++++++++ share/man/man5/rc.conf.5 | 16 +++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 etc/rc.d/static_arp diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index d67ace8c477..c1dc00078bf 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -358,6 +358,7 @@ bsnmpd_flags="" # Flags for bsnmpd. ### Network routing options: ### defaultrouter="NO" # Set to default gateway (or NO). +static_arp_pairs="" # Set to static ARP list (or leave empty). static_routes="" # Set to static route list (or leave empty). natm_static_routes="" # Set to static route list for NATM (or leave empty). gateway_enable="NO" # Set to YES if this host will be a gateway. diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 24ae3ae5ec2..110f3d783a2 100755 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -32,7 +32,7 @@ FILES= DAEMON FILESYSTEMS LOGIN NETWORKING SERVERS \ random rarpd resolv rfcomm_pppd_server root \ route6d routed routing rpcbind rtadvd rwho \ savecore sdpd securelevel sendmail \ - serial sppp statd swap1 \ + serial sppp statd static_arp swap1 \ syscons sysctl syslogd \ timed tmp \ ugidfw \ diff --git a/etc/rc.d/static_arp b/etc/rc.d/static_arp new file mode 100644 index 00000000000..582518fe97e --- /dev/null +++ b/etc/rc.d/static_arp @@ -0,0 +1,73 @@ +#!/bin/sh +# +# Copyright (c) 2009 Xin LI +# 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. +# +# Configure static ARP table +# +# $FreeBSD$ +# + +# PROVIDE: static_arp +# REQUIRE: netif +# KEYWORD: nojail + +. /etc/rc.subr + +name="static_arp" +start_cmd="static_arp_start" +stop_cmd="static_arp_stop" + +static_arp_start() +{ + local e arp_args + + if [ -n "${static_arp_pairs}" ]; then + echo -n 'Binding static ARP pair(s):' + for e in ${static_arp_pairs}; do + echo -n " ${e}" + eval arp_args=\$static_arp_${e} + arp -S ${arp_args} >/dev/null 2>&1 + done + echo '.' + fi +} + +static_arp_stop() +{ + local e arp_args + + if [ -n "${static_arp_pairs}" ]; then + echo -n 'Unbinding static ARP pair(s):' + for e in ${static_arp_pairs}; do + echo -n " ${e}" + eval arp_args=\$static_arp_${e} + arp -d ${arp_args%%[ ]*} > /dev/null 2>&1 + done + echo '.' + fi +} + +load_rc_config $name +run_rc_command "$1" diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index c0c32d58ea3..06823235d8b 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -2237,6 +2237,22 @@ name server!). .Pq Vt str The IPv6 equivalent of .Va defaultrouter . +.It Va static_arp_pairs +.Pq Vt str +Set to the list of static ARP pairs that are to be added at system +boot time. +For each whitespace separated +.Ar element +in the value, a +.Va static_arp_ Ns Aq Ar element +variable is assumed to exist whose contents will later be passed to a +.Dq Nm arp Cm -S +operation. +For example +.Bd -literal +static_arp_pairs="gw" +static_arp_gw="192.168.1.1 00:01:02:03:04:05" +.Ed .It Va static_routes .Pq Vt str Set to the list of static routes that are to be added at system From f8abda828bb5a2f7e79c176b55a013a008dbfdf8 Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Tue, 8 Dec 2009 18:23:52 +0000 Subject: [PATCH 0785/2592] MFC 198464: Inform hwpmc(4) of a thread's impending demise prior to invoking sched_throw(). --- 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 52b239b02998e00acea718eb677c67d6c2e81325 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 8 Dec 2009 22:28:55 +0000 Subject: [PATCH 0786/2592] MFC: r199616 Patch the experimental NFS server is a manner analagous to r197525, so that the creation verifier is handled correctly in va_atime for 64bit architectures. There were two problems. One was that the code incorrectly assumed that sizeof (struct timespec) == 8 and the other was that the tv_sec field needs to be assigned from a signed 32bit integer, so that sign extension occurs on 64bit architectures. This is required for correct operation when exporting ZFS volumes. Tested by: gerrit at pmp.uni-hannover.de Reviewed by: pjd --- sys/fs/nfs/nfs_var.h | 4 ++-- sys/fs/nfsserver/nfs_nfsdport.c | 13 ++++++------- sys/fs/nfsserver/nfs_nfsdserv.c | 31 +++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 2556e354910..72e65c7a4d9 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -529,7 +529,7 @@ int nfsvno_read(vnode_t, off_t, int, struct ucred *, NFSPROC_T *, int nfsvno_write(vnode_t, off_t, int, int, int, mbuf_t, char *, struct ucred *, NFSPROC_T *); int nfsvno_createsub(struct nfsrv_descript *, struct nameidata *, - vnode_t *, struct nfsvattr *, int *, u_char *, NFSDEV_T, NFSPROC_T *, + vnode_t *, struct nfsvattr *, int *, int32_t *, NFSDEV_T, NFSPROC_T *, struct nfsexstuff *); int nfsvno_mknod(struct nameidata *, struct nfsvattr *, struct ucred *, NFSPROC_T *); @@ -552,7 +552,7 @@ int nfsvno_fsync(vnode_t, u_int64_t, int, struct ucred *, NFSPROC_T *); int nfsvno_statfs(vnode_t, struct statfs *); void nfsvno_getfs(struct nfsfsinfo *, int); void nfsvno_open(struct nfsrv_descript *, struct nameidata *, nfsquad_t, - nfsv4stateid_t *, struct nfsstate *, int *, struct nfsvattr *, u_char *, + nfsv4stateid_t *, struct nfsstate *, int *, struct nfsvattr *, int32_t *, int, NFSACL_T *, nfsattrbit_t *, struct ucred *, NFSPROC_T *, struct nfsexstuff *, vnode_t *); void nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct ucred *, diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 0cebc21ce7b..1e875236557 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -720,7 +720,7 @@ nfsvno_write(struct vnode *vp, off_t off, int retlen, int cnt, int stable, int nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp, struct vnode **vpp, struct nfsvattr *nvap, int *exclusive_flagp, - u_char *cverf, NFSDEV_T rdev, struct thread *p, struct nfsexstuff *exp) + int32_t *cverf, NFSDEV_T rdev, struct thread *p, struct nfsexstuff *exp) { u_quad_t tempsize; int error; @@ -737,8 +737,8 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp, if (*exclusive_flagp) { *exclusive_flagp = 0; NFSVNO_ATTRINIT(nvap); - NFSBCOPY(cverf,(caddr_t)&nvap->na_atime, - NFSX_VERF); + nvap->na_atime.tv_sec = cverf[0]; + nvap->na_atime.tv_nsec = cverf[1]; error = VOP_SETATTR(ndp->ni_vp, &nvap->na_vattr, nd->nd_cred); } @@ -1285,7 +1285,7 @@ nfsvno_statfs(struct vnode *vp, struct statfs *sf) void nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp, nfsquad_t clientid, nfsv4stateid_t *stateidp, struct nfsstate *stp, - int *exclusive_flagp, struct nfsvattr *nvap, u_char *cverf, int create, + int *exclusive_flagp, struct nfsvattr *nvap, int32_t *cverf, int create, NFSACL_T *aclp, nfsattrbit_t *attrbitp, struct ucred *cred, struct thread *p, struct nfsexstuff *exp, struct vnode **vpp) { @@ -1307,9 +1307,8 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp, if (*exclusive_flagp) { *exclusive_flagp = 0; NFSVNO_ATTRINIT(nvap); - NFSBCOPY(cverf, - (caddr_t)&nvap->na_atime, - NFSX_VERF); + nvap->na_atime.tv_sec = cverf[0]; + nvap->na_atime.tv_nsec = cverf[1]; nd->nd_repstat = VOP_SETATTR(ndp->ni_vp, &nvap->na_vattr, cred); } else { diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 668c7fb585b..c0ac41dbbda 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -865,11 +865,11 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram, int how = NFSCREATE_UNCHECKED, exclusive_flag = 0; NFSDEV_T rdev = 0; vnode_t vp = NULL, dirp = NULL; - u_char cverf[NFSX_VERF], *cp; fhandle_t fh; char *bufp; u_long *hashp; enum vtype vtyp; + int32_t cverf[2], tverf[2] = { 0, 0 }; if (nd->nd_repstat) { nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft); @@ -920,8 +920,9 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram, goto nfsmout; break; case NFSCREATE_EXCLUSIVE: - NFSM_DISSECT(cp, u_char *, NFSX_VERF); - NFSBCOPY(cp, cverf, NFSX_VERF); + NFSM_DISSECT(tl, u_int32_t *, NFSX_VERF); + cverf[0] = *tl++; + cverf[1] = *tl; exclusive_flag = 1; break; }; @@ -988,6 +989,10 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram, nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p); vput(vp); + if (!nd->nd_repstat) { + tverf[0] = nva.na_atime.tv_sec; + tverf[1] = nva.na_atime.tv_nsec; + } } if (nd->nd_flag & ND_NFSV2) { if (!nd->nd_repstat) { @@ -995,8 +1000,8 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram, nfsrv_fillattr(nd, &nva); } } else { - if (exclusive_flag && !nd->nd_repstat && - NFSBCMP(cverf, (caddr_t)&nva.na_atime, NFSX_VERF)) + if (exclusive_flag && !nd->nd_repstat && (cverf[0] != tverf[0] + || cverf[1] != tverf[1])) nd->nd_repstat = EEXIST; diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p); vrele(dirp); @@ -2406,7 +2411,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, int error = 0, create, claim, exclusive_flag = 0; u_int32_t rflags = NFSV4OPEN_LOCKTYPEPOSIX, acemask; int how = NFSCREATE_UNCHECKED; - u_char cverf[NFSX_VERF]; + int32_t cverf[2], tverf[2] = { 0, 0 }; vnode_t vp = NULL, dirp = NULL; struct nfsvattr nva, dirfor, diraft; struct nameidata named; @@ -2517,7 +2522,8 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, break; case NFSCREATE_EXCLUSIVE: NFSM_DISSECT(tl, u_int32_t *, NFSX_VERF); - NFSBCOPY((caddr_t)tl, cverf, NFSX_VERF); + cverf[0] = *tl++; + cverf[1] = *tl; break; default: nd->nd_repstat = NFSERR_BADXDR; @@ -2677,10 +2683,15 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, NFSACCCHK_VPISLOCKED); } - if (!nd->nd_repstat) + if (!nd->nd_repstat) { nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p); - if (!nd->nd_repstat && exclusive_flag && - NFSBCMP(cverf, (caddr_t)&nva.na_atime, NFSX_VERF)) + if (!nd->nd_repstat) { + tverf[0] = nva.na_atime.tv_sec; + tverf[1] = nva.na_atime.tv_nsec; + } + } + if (!nd->nd_repstat && exclusive_flag && (cverf[0] != tverf[0] || + cverf[1] != tverf[1])) nd->nd_repstat = EEXIST; /* * Do the open locking/delegation stuff. From 6d54ecd38fea6eaf7b3dbb91555159f0ff1e817a Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 8 Dec 2009 22:41:37 +0000 Subject: [PATCH 0787/2592] MFC: r199715 Modify the experimental nfs server so that it falls back to using VOP_LOOKUP() when VFS_VGET() returns EOPNOTSUPP in the ReaddirPlus RPC. This patch is based upon one by pjd@ for the regular nfs server which has not yet been committed. It is needed when a ZFS volume is exported and ReaddirPlus (which almost always happens for NFSv4) is performed by a client. The patch also simplifies vnode lock handling somewhat. Tested by: gerrit at pmp.uni-hannover.de --- sys/fs/nfsserver/nfs_nfsdport.c | 82 ++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 1e875236557..ca80fde358f 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -1675,7 +1675,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, struct nfsvattr nva, at, *nvap = &nva; struct mbuf *mb0, *mb1; struct nfsreferral *refp; - int nlen, r, error = 0, getret = 1, vgetret; + int nlen, r, error = 0, getret = 1, usevget = 1; int siz, cnt, fullsiz, eofflag, ncookies, entrycnt; caddr_t bpos0, bpos1; u_int64_t off, toff, verf; @@ -1683,6 +1683,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, nfsattrbit_t attrbits, rderrbits, savbits; struct uio io; struct iovec iv; + struct componentname cn; if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &at); @@ -1761,8 +1762,6 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, return (0); } - NFSVOPUNLOCK(vp, 0, p); - MALLOC(rbuf, caddr_t, siz, M_TEMP, M_WAITOK); again: eofflag = 0; @@ -1780,10 +1779,8 @@ again: io.uio_segflg = UIO_SYSSPACE; io.uio_rw = UIO_READ; io.uio_td = NULL; - NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, p); nd->nd_repstat = VOP_READDIR(vp, &io, nd->nd_cred, &eofflag, &ncookies, &cookies); - NFSVOPUNLOCK(vp, 0, p); off = (u_int64_t)io.uio_offset; if (io.uio_resid) siz -= io.uio_resid; @@ -1795,7 +1792,7 @@ again: if (!nd->nd_repstat) nd->nd_repstat = getret; if (nd->nd_repstat) { - vrele(vp); + vput(vp); if (cookies) free((caddr_t)cookies, M_TEMP); free((caddr_t)rbuf, M_TEMP); @@ -1808,7 +1805,7 @@ again: * rpc reply */ if (siz == 0) { - vrele(vp); + vput(vp); if (nd->nd_flag & ND_NFSV3) nfsrv_postopattr(nd, getret, &at); NFSM_BUILD(tl, u_int32_t *, 4 * NFSX_UNSIGNED); @@ -1853,33 +1850,7 @@ again: toff = off; goto again; } - - /* - * Probe one of the directory entries to see if the filesystem - * supports VGET for NFSv3. For NFSv4, it will return an - * error later, if attributes are required. - * (To be honest, most if not all NFSv4 clients will require - * attributes, but??) - */ - if ((nd->nd_flag & ND_NFSV3)) { - vgetret = VFS_VGET(vp->v_mount, dp->d_fileno, LK_EXCLUSIVE, - &nvp); - if (vgetret != 0) { - if (vgetret == EOPNOTSUPP) - nd->nd_repstat = NFSERR_NOTSUPP; - else - nd->nd_repstat = NFSERR_SERVERFAULT; - vrele(vp); - if (cookies) - free((caddr_t)cookies, M_TEMP); - free((caddr_t)rbuf, M_TEMP); - nfsrv_postopattr(nd, getret, &at); - return (0); - } - if (!vgetret) - vput(nvp); - nvp = NULL; - } + NFSVOPUNLOCK(vp, 0, p); /* * Save this position, in case there is an error before one entry @@ -1937,9 +1908,41 @@ again: if (nd->nd_flag & ND_NFSV4) refp = nfsv4root_getreferral(NULL, vp, dp->d_fileno); - if (refp == NULL) - r = VFS_VGET(vp->v_mount, dp->d_fileno, - LK_EXCLUSIVE, &nvp); + if (refp == NULL) { + if (usevget) + r = VFS_VGET(vp->v_mount, + dp->d_fileno, LK_EXCLUSIVE, + &nvp); + else + r = EOPNOTSUPP; + if (r == EOPNOTSUPP) { + if (usevget) { + usevget = 0; + cn.cn_nameiop = LOOKUP; + cn.cn_lkflags = + LK_EXCLUSIVE | + LK_RETRY; + cn.cn_cred = + nd->nd_cred; + cn.cn_thread = p; + } + cn.cn_nameptr = dp->d_name; + cn.cn_namelen = nlen; + cn.cn_flags = ISLASTCN | + NOFOLLOW | LOCKLEAF | + MPSAFE; + if (nlen == 2 && + dp->d_name[0] == '.' && + dp->d_name[1] == '.') + cn.cn_flags |= + ISDOTDOT; + if (!VOP_ISLOCKED(vp)) + vn_lock(vp, + LK_EXCLUSIVE | + LK_RETRY); + r = VOP_LOOKUP(vp, &nvp, &cn); + } + } if (!r) { if (refp == NULL && ((nd->nd_flag & ND_NFSV3) || @@ -2018,7 +2021,10 @@ again: cookiep++; ncookies--; } - vrele(vp); + if (!usevget && VOP_ISLOCKED(vp)) + vput(vp); + else + vrele(vp); /* * If dirlen > cnt, we must strip off the last entry. If that From e99e819fed27518eef0cab2a8a0515a8e838d3be Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 8 Dec 2009 23:15:48 +0000 Subject: [PATCH 0788/2592] MFC r196879: Add support for changing providers priority. --- sbin/geom/class/mirror/geom_mirror.c | 9 ++-- sbin/geom/class/mirror/gmirror.8 | 19 ++++++-- sys/geom/mirror/g_mirror_ctl.c | 71 ++++++++++++++++++++++++---- 3 files changed, 81 insertions(+), 18 deletions(-) diff --git a/sbin/geom/class/mirror/geom_mirror.c b/sbin/geom/class/mirror/geom_mirror.c index 38912a34958..6ac4fb9a775 100644 --- a/sbin/geom/class/mirror/geom_mirror.c +++ b/sbin/geom/class/mirror/geom_mirror.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * Copyright (c) 2004-2009 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,13 +41,12 @@ __FBSDID("$FreeBSD$"); #include #include - uint32_t lib_version = G_LIB_VERSION; uint32_t version = G_MIRROR_VERSION; static char label_balance[] = "split", configure_balance[] = "none"; static intmax_t label_slice = 4096, configure_slice = -1; -static intmax_t insert_priority = 0; +static intmax_t insert_priority = 0, configure_priority = -1; static void mirror_main(struct gctl_req *req, unsigned flags); static void mirror_activate(struct gctl_req *req); @@ -71,10 +70,12 @@ struct g_command class_commands[] = { { 'F', "nofailsync", NULL, G_TYPE_BOOL }, { 'h', "hardcode", NULL, G_TYPE_BOOL }, { 'n', "noautosync", NULL, G_TYPE_BOOL }, + { 'p', "priority", &configure_priority, G_TYPE_NUMBER }, { 's', "slice", &configure_slice, G_TYPE_NUMBER }, G_OPT_SENTINEL }, - NULL, "[-adfFhnv] [-b balance] [-s slice] name" + NULL, "[-adfFhnv] [-b balance] [-s slice] name\n" + "[-v] -p priority name prov" }, { "deactivate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS, NULL, "[-v] name prov ..." diff --git a/sbin/geom/class/mirror/gmirror.8 b/sbin/geom/class/mirror/gmirror.8 index 185b3d3838c..78baf0b3592 100644 --- a/sbin/geom/class/mirror/gmirror.8 +++ b/sbin/geom/class/mirror/gmirror.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2004-2005 Pawel Jakub Dawidek +.\" Copyright (c) 2004-2009 Pawel Jakub Dawidek .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 1, 2006 +.Dd August 1, 2009 .Dt GMIRROR 8 .Os .Sh NAME @@ -49,6 +49,12 @@ .Op Fl s Ar slice .Ar name .Nm +.Cm configure +.Op Fl v +.Fl p Ar priority +.Ar name +.Ar prov +.Nm .Cm rebuild .Op Fl v .Ar name @@ -115,8 +121,8 @@ indicates an action to be performed: .It Cm label Create a mirror. The order of components is important, because a component's priority is based on its position -(starting from 0). -The component with the biggest priority is used by the +(starting from 0 to 255). +The component with the biggest priority (the lowest number) is used by the .Cm prefer balance algorithm and is also used as a master component when resynchronization is needed, @@ -159,7 +165,7 @@ Clear metadata on the given providers. Configure the given device. .Pp Additional options include: -.Bl -tag -width ".Fl b Ar balance" +.Bl -tag -width ".Fl p Ar priority" .It Fl a Turn on autosynchronization of stale components. .It Fl b Ar balance @@ -175,6 +181,9 @@ Assumes device is in consistent state. Hardcode providers' names in metadata. .It Fl n Turn off autosynchronization of stale components. +.It Fl p Ar priority +Specifies priority for the given component +.Ar prov . .It Fl s Ar slice Specifies slice size for .Cm split diff --git a/sys/geom/mirror/g_mirror_ctl.c b/sys/geom/mirror/g_mirror_ctl.c index 27e58ceb31c..4524a90d8dd 100644 --- a/sys/geom/mirror/g_mirror_ctl.c +++ b/sys/geom/mirror/g_mirror_ctl.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004-2006 Pawel Jakub Dawidek + * Copyright (c) 2004-2009 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -93,19 +93,19 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp) { struct g_mirror_softc *sc; struct g_mirror_disk *disk; - const char *name, *balancep; - intmax_t *slicep; + const char *name, *balancep, *prov; + intmax_t *slicep, *priority; uint32_t slice; uint8_t balance; int *autosync, *noautosync, *failsync, *nofailsync, *hardcode, *dynamic; - int *nargs, do_sync = 0, dirty = 1; + int *nargs, do_sync = 0, dirty = 1, do_priority = 0; nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); if (nargs == NULL) { gctl_error(req, "No '%s' argument.", "nargs"); return; } - if (*nargs != 1) { + if (*nargs != 1 && *nargs != 2) { gctl_error(req, "Invalid number of arguments."); return; } @@ -149,6 +149,29 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp) gctl_error(req, "No '%s' argument.", "dynamic"); return; } + priority = gctl_get_paraml(req, "priority", sizeof(*priority)); + if (priority == NULL) { + gctl_error(req, "No '%s' argument.", "priority"); + return; + } + if (*priority < -1 || *priority > 255) { + gctl_error(req, "Priority range is 0 to 255, %jd given", + *priority); + return; + } + /* + * Since we have a priority, we also need a provider now. + * Note: be WARNS safe, by always assigning prov and only throw an + * error if *priority != -1. + */ + prov = gctl_get_asciiparam(req, "arg1"); + if (*priority > -1) { + if (prov == NULL) { + gctl_error(req, "Priority needs a disk name"); + return; + } + do_priority = 1; + } if (*autosync && *noautosync) { gctl_error(req, "'%s' and '%s' specified.", "autosync", "noautosync"); @@ -189,19 +212,32 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp) slice = sc->sc_slice; else slice = *slicep; - if (g_mirror_ndisks(sc, -1) < sc->sc_ndisks) { + /* Enforce usage() of -p not allowing any other options. */ + if (do_priority && (*autosync || *noautosync || *failsync || + *nofailsync || *hardcode || *dynamic || *slicep != -1 || + strcmp(balancep, "none") != 0)) { sx_xunlock(&sc->sc_lock); - gctl_error(req, "Not all disks connected. Try 'forget' command " - "first."); + gctl_error(req, "only -p accepted when setting priority"); return; } if (sc->sc_balance == balance && sc->sc_slice == slice && !*autosync && !*noautosync && !*failsync && !*nofailsync && !*hardcode && - !*dynamic) { + !*dynamic && !do_priority) { sx_xunlock(&sc->sc_lock); gctl_error(req, "Nothing has changed."); return; } + if ((!do_priority && *nargs != 1) || (do_priority && *nargs != 2)) { + sx_xunlock(&sc->sc_lock); + gctl_error(req, "Invalid number of arguments."); + return; + } + if (g_mirror_ndisks(sc, -1) < sc->sc_ndisks) { + sx_xunlock(&sc->sc_lock); + gctl_error(req, "Not all disks connected. Try 'forget' command " + "first."); + return; + } sc->sc_balance = balance; sc->sc_slice = slice; if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOAUTOSYNC) != 0) { @@ -223,6 +259,23 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp) } } LIST_FOREACH(disk, &sc->sc_disks, d_next) { + /* + * Handle priority first, since we only need one disk, do one + * operation on it and then we're done. No need to check other + * flags, as usage doesn't allow it. + */ + if (do_priority) { + if (strcmp(disk->d_name, prov) == 0) { + if (disk->d_priority == *priority) + gctl_error(req, "Nothing has changed."); + else { + disk->d_priority = *priority; + g_mirror_update_metadata(disk); + } + break; + } + continue; + } if (do_sync) { if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC; From 417f9726016438458084e0398e3ca55222a34763 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 8 Dec 2009 23:23:45 +0000 Subject: [PATCH 0789/2592] MFC r200086: Change 'load' balancing mode algorithm: - Instead of measuring last request execution time for each drive and choosing one with smallest time, use averaged number of requests, running on each drive. This information is more accurate and timely. It allows to distribute load between drives in more even and predictable way. - For each drive track offset of the last submitted request. If new request offset matches previous one or close for some drive, prefer that drive. It allows to significantly speedup simultaneous sequential reads. PR: kern/113885 --- sys/geom/mirror/g_mirror.c | 52 ++++++++++++++++++-------------------- sys/geom/mirror/g_mirror.h | 4 +-- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 13ff6eaabb6..973e10b9b2e 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -451,9 +451,6 @@ g_mirror_init_disk(struct g_mirror_softc *sc, struct g_provider *pp, disk->d_id = md->md_did; disk->d_state = G_MIRROR_DISK_STATE_NONE; disk->d_priority = md->md_priority; - disk->d_delay.sec = 0; - disk->d_delay.frac = 0; - binuptime(&disk->d_last_used); disk->d_flags = md->md_dflags; if (md->md_provider[0] != '\0') disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED; @@ -862,16 +859,6 @@ bintime_cmp(struct bintime *bt1, struct bintime *bt2) return (0); } -static void -g_mirror_update_delay(struct g_mirror_disk *disk, struct bio *bp) -{ - - if (disk->d_softc->sc_balance != G_MIRROR_BALANCE_LOAD) - return; - binuptime(&disk->d_delay); - bintime_sub(&disk->d_delay, &bp->bio_t0); -} - static void g_mirror_done(struct bio *bp) { @@ -904,8 +891,6 @@ g_mirror_regular_request(struct bio *bp) g_topology_lock(); g_mirror_kill_consumer(sc, bp->bio_from); g_topology_unlock(); - } else { - g_mirror_update_delay(disk, bp); } pbp->bio_inbed++; @@ -1465,30 +1450,35 @@ g_mirror_request_round_robin(struct g_mirror_softc *sc, struct bio *bp) g_io_request(cbp, cp); } +#define TRACK_SIZE (1 * 1024 * 1024) +#define LOAD_SCALE 256 +#define ABS(x) (((x) >= 0) ? (x) : (-(x))) + static void g_mirror_request_load(struct g_mirror_softc *sc, struct bio *bp) { struct g_mirror_disk *disk, *dp; struct g_consumer *cp; struct bio *cbp; - struct bintime curtime; + int prio, best; - binuptime(&curtime); - /* - * Find a disk which the smallest load. - */ + /* Find a disk with the smallest load. */ disk = NULL; + best = INT_MAX; LIST_FOREACH(dp, &sc->sc_disks, d_next) { if (dp->d_state != G_MIRROR_DISK_STATE_ACTIVE) continue; - /* If disk wasn't used for more than 2 sec, use it. */ - if (curtime.sec - dp->d_last_used.sec >= 2) { - disk = dp; - break; - } - if (disk == NULL || - bintime_cmp(&dp->d_delay, &disk->d_delay) < 0) { + prio = dp->load; + /* If disk head is precisely in position - highly prefer it. */ + if (dp->d_last_offset == bp->bio_offset) + prio -= 2 * LOAD_SCALE; + else + /* If disk head is close to position - prefer it. */ + if (ABS(dp->d_last_offset - bp->bio_offset) < TRACK_SIZE) + prio -= 1 * LOAD_SCALE; + if (prio <= best) { disk = dp; + best = prio; } } KASSERT(disk != NULL, ("NULL disk for %s.", sc->sc_name)); @@ -1505,12 +1495,18 @@ g_mirror_request_load(struct g_mirror_softc *sc, struct bio *bp) cp = disk->d_consumer; cbp->bio_done = g_mirror_done; cbp->bio_to = cp->provider; - binuptime(&disk->d_last_used); G_MIRROR_LOGREQ(3, cbp, "Sending request."); KASSERT(cp->acr >= 1 && cp->acw >= 1 && cp->ace >= 1, ("Consumer %s not opened (r%dw%de%d).", cp->provider->name, cp->acr, cp->acw, cp->ace)); cp->index++; + /* Remember last head position */ + disk->d_last_offset = bp->bio_offset + bp->bio_length; + /* Update loads. */ + LIST_FOREACH(dp, &sc->sc_disks, d_next) { + dp->load = (dp->d_consumer->index * LOAD_SCALE + + dp->load * 7) / 8; + } g_io_request(cbp, cp); } diff --git a/sys/geom/mirror/g_mirror.h b/sys/geom/mirror/g_mirror.h index eb67b6e08ba..8cd9a691e40 100644 --- a/sys/geom/mirror/g_mirror.h +++ b/sys/geom/mirror/g_mirror.h @@ -133,8 +133,8 @@ struct g_mirror_disk { struct g_mirror_softc *d_softc; /* Back-pointer to softc. */ int d_state; /* Disk state. */ u_int d_priority; /* Disk priority. */ - struct bintime d_delay; /* Disk delay. */ - struct bintime d_last_used; /* When disk was last used. */ + u_int load; /* Averaged queue length */ + off_t d_last_offset; /* Last read offset */ uint64_t d_flags; /* Additional flags. */ u_int d_genid; /* Disk's generation ID. */ struct g_mirror_disk_sync d_sync;/* Sync information. */ From 240d980d7c493c23a4c03175ec1a6cc9beaa8bfa Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 9 Dec 2009 13:27:06 +0000 Subject: [PATCH 0790/2592] MFC r200196: Add Asynchronous Notification support for controllers without SNTF capability by snooping SDB FIS receive area. It should be even faster then regular way, but less reliable. --- sys/dev/ahci/ahci.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 3f6c9fcdd88..84a16306e2f 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1129,7 +1129,8 @@ ahci_notify_events(device_t dev, u_int32_t status) struct cam_path *dpath; int i; - ATA_OUTL(ch->r_mem, AHCI_P_SNTF, status); + if (ch->caps & AHCI_CAP_SSNTF) + ATA_OUTL(ch->r_mem, AHCI_P_SNTF, status); if (bootverbose) device_printf(dev, "SNTF 0x%04x\n", status); for (i = 0; i < 16; i++) { @@ -1188,8 +1189,16 @@ ahci_ch_intr(void *data) /* Read command statuses. */ sstatus = ATA_INL(ch->r_mem, AHCI_P_SACT); cstatus = ATA_INL(ch->r_mem, AHCI_P_CI); - if ((istatus & AHCI_P_IX_SDB) && (ch->caps & AHCI_CAP_SSNTF)) - sntf = ATA_INL(ch->r_mem, AHCI_P_SNTF); + if (istatus & AHCI_P_IX_SDB) { + if (ch->caps & AHCI_CAP_SSNTF) + sntf = ATA_INL(ch->r_mem, AHCI_P_SNTF); + else { + u_int8_t *fis = ch->dma.rfis + 0x58; + + if (fis[1] & 0x80) + sntf = (1 << (fis[1] & 0x0f)); + } + } /* Process PHY events */ 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)) { From 0d8f2099fa8939afa25731e1f2c44b0a784d0ecd Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 9 Dec 2009 13:30:11 +0000 Subject: [PATCH 0791/2592] MFC r200217: SiI3124 has no SNotification register. Handle Asynchronous Notifications there without it as good as possible. --- sys/dev/siis/siis.c | 37 +++++++++++++++++++++++++------------ sys/dev/siis/siis.h | 2 ++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 7ee6eb63d06..813753f8272 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -93,15 +93,17 @@ static struct { uint32_t id; const char *name; int ports; + int quirks; +#define SIIS_Q_SNTF 1 } 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} + {0x31241095, "SiI3124", 4, 0}, + {0x31248086, "SiI3124", 4, 0}, + {0x31321095, "SiI3132", 2, SIIS_Q_SNTF}, + {0x02421095, "SiI3132", 2, SIIS_Q_SNTF}, + {0x02441095, "SiI3132", 2, SIIS_Q_SNTF}, + {0x31311095, "SiI3131", 1, SIIS_Q_SNTF}, + {0x35311095, "SiI3531", 1, SIIS_Q_SNTF}, + {0, NULL, 0, 0} }; static int @@ -113,7 +115,7 @@ siis_probe(device_t dev) for (i = 0; siis_ids[i].id != 0; i++) { if (siis_ids[i].id == devid) { - snprintf(buf, sizeof(buf), "%s SATA2 controller", + snprintf(buf, sizeof(buf), "%s SATA controller", siis_ids[i].name); device_set_desc_copy(dev, buf); return (BUS_PROBE_VENDOR); @@ -130,11 +132,12 @@ siis_attach(device_t dev) device_t child; int error, i, unit; + ctlr->dev = dev; for (i = 0; siis_ids[i].id != 0; i++) { if (siis_ids[i].id == devid) break; } - ctlr->dev = dev; + ctlr->quirks = siis_ids[i].quirks; /* Global memory */ ctlr->r_grid = PCIR_BAR(0); if (!(ctlr->r_gmem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -413,12 +416,14 @@ siis_ch_probe(device_t dev) static int siis_ch_attach(device_t dev) { + struct siis_controller *ctlr = device_get_softc(device_get_parent(dev)); struct siis_channel *ch = device_get_softc(dev); struct cam_devq *devq; int rid, error, i, sata_rev = 0; ch->dev = dev; ch->unit = (intptr_t)device_get_ivars(dev); + ch->quirks = ctlr->quirks; resource_int_value(device_get_name(dev), device_get_unit(dev), "pm_level", &ch->pm_level); resource_int_value(device_get_name(dev), @@ -680,8 +685,16 @@ siis_notify_events(device_t dev) u_int32_t status; int i; - status = ATA_INL(ch->r_mem, SIIS_P_SNTF); - ATA_OUTL(ch->r_mem, SIIS_P_SNTF, status); + if (ch->quirks & SIIS_Q_SNTF) { + status = ATA_INL(ch->r_mem, SIIS_P_SNTF); + ATA_OUTL(ch->r_mem, SIIS_P_SNTF, status); + } else { + /* + * Without SNTF we have no idea which device sent notification. + * If PMP is connected, assume it, else - device. + */ + status = (ch->pm_present) ? 0x8000 : 0x0001; + } if (bootverbose) device_printf(dev, "SNTF 0x%04x\n", status); for (i = 0; i < 16; i++) { diff --git a/sys/dev/siis/siis.h b/sys/dev/siis/siis.h index 52332c5ad68..097f7ff5a42 100644 --- a/sys/dev/siis/siis.h +++ b/sys/dev/siis/siis.h @@ -363,6 +363,7 @@ struct siis_channel { struct ata_dma dma; /* DMA data */ struct cam_sim *sim; struct cam_path *path; + int quirks; int pm_level; /* power management level */ struct siis_slot slot[SIIS_MAX_SLOTS]; @@ -400,6 +401,7 @@ struct siis_controller { void *handle; int r_irq_rid; } irq; + int quirks; int channels; struct { void (*function)(void *); From 67c3bd268176576bcc0bfef68ed84eb2bd22e84b Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 9 Dec 2009 13:32:49 +0000 Subject: [PATCH 0792/2592] MFC r200223: Explicitly acknowledge MSI completion, as required by SiI3124 datasheet. It makes MSI working there. Later (and cheaper) PCIe chips (3132/3531) still randomly crashing system in few seconds of high MSI rates, generating something inaporopriate, like NMI or "Fatal trap 30". --- sys/dev/siis/siis.c | 16 +++++++++++++--- sys/dev/siis/siis.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 813753f8272..a47ce2cebb1 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -143,6 +143,7 @@ siis_attach(device_t dev) if (!(ctlr->r_gmem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &ctlr->r_grid, RF_ACTIVE))) return (ENXIO); + ctlr->gctl = ATA_INL(ctlr->r_gmem, SIIS_GCTL); /* Channels memory */ ctlr->r_rid = PCIR_BAR(2); if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -221,7 +222,8 @@ siis_suspend(device_t dev) bus_generic_suspend(dev); /* Put controller into reset state. */ - ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, SIIS_GCTL_GRESET); + ctlr->gctl |= SIIS_GCTL_GRESET; + ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl); return 0; } @@ -231,10 +233,13 @@ siis_resume(device_t dev) struct siis_controller *ctlr = device_get_softc(dev); /* Put controller into reset state. */ - ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, SIIS_GCTL_GRESET); + ctlr->gctl |= SIIS_GCTL_GRESET; + ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl); DELAY(10000); /* Get controller out of reset state and enable port interrupts. */ - ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, 0x0000000f); + ctlr->gctl &= ~(SIIS_GCTL_GRESET | SIIS_GCTL_I2C_IE); + ctlr->gctl |= 0x0000000f; + ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl); return (bus_generic_resume(dev)); } @@ -288,6 +293,11 @@ siis_intr(void *data) ctlr->interrupt[unit].function(arg); } } + /* Acknowledge interrupt, if MSI enabled. */ + if (ctlr->irq.r_irq_rid) { + ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, + ctlr->gctl | SIIS_GCTL_MSIACK); + } } static struct resource * diff --git a/sys/dev/siis/siis.h b/sys/dev/siis/siis.h index 097f7ff5a42..2f8c046d7ce 100644 --- a/sys/dev/siis/siis.h +++ b/sys/dev/siis/siis.h @@ -403,6 +403,7 @@ struct siis_controller { } irq; int quirks; int channels; + uint32_t gctl; struct { void (*function)(void *); void *argument; From 3ca1ec74eddc12d9c0060ef9bce95280f7c3a539 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 9 Dec 2009 17:11:09 +0000 Subject: [PATCH 0793/2592] MFC r200117: On Soft Reset, read device signature from FIS receive area, instead of PxSIG register. It works better for NVidia chipsets. ahci(4) does the same. PR: kern/140472, i386/138668 --- sys/dev/ata/chipsets/ata-ahci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c index 0f76a8dce05..e4a7cd165ad 100644 --- a/sys/dev/ata/chipsets/ata-ahci.c +++ b/sys/dev/ata/chipsets/ata-ahci.c @@ -824,11 +824,10 @@ ata_ahci_hardreset(device_t dev, int port, uint32_t *signature) static u_int32_t ata_ahci_softreset(device_t dev, int port) { - struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); - int offset = ch->unit << 7; struct ata_ahci_cmd_tab *ctp = (struct ata_ahci_cmd_tab *)(ch->dma.work + ATA_AHCI_CT_OFFSET); + u_int8_t *fis = ch->dma.work + ATA_AHCI_FB_OFFSET + 0x40; if (bootverbose) device_printf(dev, "software reset port %d...\n", port); @@ -865,7 +864,10 @@ ata_ahci_softreset(device_t dev, int port) return (-1); } - return ATA_INL(ctlr->r_res2, ATA_AHCI_P_SIG + offset); + return (((u_int32_t)fis[6] << 24) | + ((u_int32_t)fis[5] << 16) | + ((u_int32_t)fis[4] << 8) | + (u_int32_t)fis[12]); } static void From 26952f96e55242cc4bd0fc1ca37e30bd0bd0d1ec Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 9 Dec 2009 17:20:10 +0000 Subject: [PATCH 0794/2592] MFC r200121: Do not ignore device interrupt if bus mastering is still active. It is normal in case of media read error and some ATAPI cases, when transfer size is unknown beforehand. PCI ATA BM specification tells that in case of such underrun driver should just manually stop DMA engine. DMA engine should same time guarantie that all bus mastering transfers completed at the moment of driver reads interrupt flag asserted. This change fixes interrupt storms and command timeouts in many cases. PR: kern/103602, sparc64/121539, kern/133122, kern/139654 --- sys/dev/ata/ata-pci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index 4a24455d8d8..ce21926cb3e 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -462,8 +462,7 @@ ata_pci_status(device_t dev) (ch->dma.flags & ATA_DMA_ACTIVE))) { int bmstat = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; - if ((bmstat & (ATA_BMSTAT_ACTIVE | ATA_BMSTAT_INTERRUPT)) != - ATA_BMSTAT_INTERRUPT) + if ((bmstat & ATA_BMSTAT_INTERRUPT) == 0) return 0; ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, bmstat & ~ATA_BMSTAT_ERROR); DELAY(1); From 4b56fe67b6aedfae4e2d2ef74cf2decb2820dab8 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 21:34:38 +0000 Subject: [PATCH 0795/2592] MFC r199575 - fix a transfer cancelling bug/segfault [1] - correct a return code in the transfer cancel function. - add new API function, libusb20_tr_bulk_intr_sync(). Submitted by: HPS Reported by: Robert Jenssen [1] --- lib/libusb/libusb10.c | 41 +++++++++++++++---- lib/libusb/libusb10.h | 4 +- lib/libusb/libusb20.3 | 27 ++++++++++++- lib/libusb/libusb20.c | 91 ++++++++++++++++++++++++++++++++++++++++++- lib/libusb/libusb20.h | 3 +- 5 files changed, 155 insertions(+), 11 deletions(-) diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c index 55ee1c509e7..9a5154e7e5f 100644 --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -833,8 +833,12 @@ libusb10_complete_transfer(struct libusb20_transfer *pxfer, if (pxfer != NULL) libusb20_tr_set_priv_sc1(pxfer, NULL); + /* set transfer status */ uxfer->status = status; + /* update super transfer state */ + sxfer->state = LIBUSB_SUPER_XFER_ST_NONE; + dev = libusb_get_device(uxfer->dev_handle); TAILQ_INSERT_TAIL(&dev->ctx->tr_done, sxfer, entry); @@ -1111,6 +1115,8 @@ libusb10_submit_transfer_sub(struct libusb20_device *pdev, uint8_t endpoint) return; case 2: sxfer = libusb20_tr_get_priv_sc1(pxfer1); + if (sxfer == NULL) + return; /* cancelling */ if (sxfer->rem_len) return; /* cannot queue another one */ /* swap transfers */ @@ -1118,6 +1124,8 @@ libusb10_submit_transfer_sub(struct libusb20_device *pdev, uint8_t endpoint) break; case 1: sxfer = libusb20_tr_get_priv_sc1(pxfer0); + if (sxfer == NULL) + return; /* cancelling */ if (sxfer->rem_len) return; /* cannot queue another one */ /* swap transfers */ @@ -1229,12 +1237,18 @@ libusb_submit_transfer(struct libusb_transfer *uxfer) if (pxfer0 == NULL || pxfer1 == NULL) { err = LIBUSB_ERROR_OTHER; } else if ((sxfer->entry.tqe_prev != NULL) || - (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) || + (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) || (libusb20_tr_get_priv_sc1(pxfer1) == sxfer)) { err = LIBUSB_ERROR_BUSY; } else { + + /* set pending state */ + sxfer->state = LIBUSB_SUPER_XFER_ST_PEND; + + /* insert transfer into transfer head list */ TAILQ_INSERT_TAIL(&dev->tr_head, sxfer, entry); + /* start work transfers */ libusb10_submit_transfer_sub( uxfer->dev_handle, endpoint); @@ -1258,12 +1272,14 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer) struct libusb_super_transfer *sxfer; struct libusb_device *dev; uint32_t endpoint; + int retval; if (uxfer == NULL) return (LIBUSB_ERROR_INVALID_PARAM); + /* check if not initialised */ if (uxfer->dev_handle == NULL) - return (LIBUSB_ERROR_INVALID_PARAM); + return (LIBUSB_ERROR_NOT_FOUND); endpoint = uxfer->endpoint; @@ -1277,39 +1293,50 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer) sxfer = (struct libusb_super_transfer *)( (uint8_t *)uxfer - sizeof(*sxfer)); + retval = 0; + CTX_LOCK(dev->ctx); pxfer0 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 0); pxfer1 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 1); - if (sxfer->entry.tqe_prev != NULL) { + if (sxfer->state != LIBUSB_SUPER_XFER_ST_PEND) { + /* only update the transfer status */ + uxfer->status = LIBUSB_TRANSFER_CANCELLED; + retval = LIBUSB_ERROR_NOT_FOUND; + } else if (sxfer->entry.tqe_prev != NULL) { /* we are lucky - transfer is on a queue */ TAILQ_REMOVE(&dev->tr_head, sxfer, entry); sxfer->entry.tqe_prev = NULL; - libusb10_complete_transfer(NULL, sxfer, LIBUSB_TRANSFER_CANCELLED); + libusb10_complete_transfer(NULL, + sxfer, LIBUSB_TRANSFER_CANCELLED); } else if (pxfer0 == NULL || pxfer1 == NULL) { /* not started */ + retval = LIBUSB_ERROR_NOT_FOUND; } else if (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) { - libusb10_complete_transfer(pxfer0, sxfer, LIBUSB_TRANSFER_CANCELLED); + libusb10_complete_transfer(pxfer0, + sxfer, LIBUSB_TRANSFER_CANCELLED); libusb20_tr_stop(pxfer0); /* make sure the queue doesn't stall */ libusb10_submit_transfer_sub( uxfer->dev_handle, endpoint); } else if (libusb20_tr_get_priv_sc1(pxfer1) == sxfer) { - libusb10_complete_transfer(pxfer1, sxfer, LIBUSB_TRANSFER_CANCELLED); + libusb10_complete_transfer(pxfer1, + sxfer, LIBUSB_TRANSFER_CANCELLED); libusb20_tr_stop(pxfer1); /* make sure the queue doesn't stall */ libusb10_submit_transfer_sub( uxfer->dev_handle, endpoint); } else { /* not started */ + retval = LIBUSB_ERROR_NOT_FOUND; } CTX_UNLOCK(dev->ctx); DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave"); - return (0); + return (retval); } UNEXPORTED void diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h index 338c2aab888..d2a2bd7c150 100644 --- a/lib/libusb/libusb10.h +++ b/lib/libusb/libusb10.h @@ -65,7 +65,9 @@ struct libusb_super_transfer { uint8_t *curr_data; uint32_t rem_len; uint32_t last_len; - uint8_t flags; + uint8_t state; +#define LIBUSB_SUPER_XFER_ST_NONE 0 +#define LIBUSB_SUPER_XFER_ST_PEND 1 }; struct libusb_context { diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3 index f902883107b..5404013ee99 100644 --- a/lib/libusb/libusb20.3 +++ b/lib/libusb/libusb20.3 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 22, 2009 +.Dd November 18, 2009 .Dt LIBUSB20 3 .Os .Sh NAME @@ -98,6 +98,8 @@ USB access library (libusb -lusb) .Fn libusb20_tr_setup_intr "struct libusb20_transfer *xfer" "void *pbuf" "uint32_t length" "uint32_t timeout" .Ft void .Fn libusb20_tr_setup_isoc "struct libusb20_transfer *xfer" "void *pbuf" "uint32_t length" "uint61_t fr_index" +.Ft uint8_t +.Fn libusb20_tr_bulk_intr_sync "struct libusb20_transfer *xfer" "void *pbuf" "uint32_t length" "uint32_t *pactlen" "uint32_t timeout" .Ft void .Fn libusb20_tr_start "struct libusb20_transfer *xfer" .Ft void @@ -451,6 +453,29 @@ is a helper function for setting up a multi frame USB ISOCHRONOUS transfer. . .Pp . +.Fn libusb20_tr_bulk_intr_sync +will perform a synchronous BULK or INTERRUPT transfer having length given by the +.Fa length +argument and buffer pointer given by the +.Fa pbuf +argument on the USB transfer given by the +.Fa xfer +argument. +. +If the +.Fa pactlen +argument is non-NULL the actual transfer length will be stored at the given pointer destination. +. +If the +.Fa timeout +argument is non-zero the transfer will timeout after the given value in milliseconds. +. +This function does not change the transfer flags, like short packet not ok. +. +This function returns zero on success else a LIBUSB20_TRANSFER_XXX value is returned. +. +.Pp +. .Fn libusb20_tr_start will get the USB transfer started, if not already started. diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c index 1a338052c93..41f9ac72de6 100644 --- a/lib/libusb/libusb20.c +++ b/lib/libusb/libusb20.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /*- - * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2008-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 @@ -263,6 +263,10 @@ libusb20_tr_get_priv_sc1(struct libusb20_transfer *xfer) void libusb20_tr_stop(struct libusb20_transfer *xfer) { + if (!xfer->is_opened) { + /* transfer is not opened */ + return; + } if (!xfer->is_pending) { /* transfer not pending */ return; @@ -280,6 +284,10 @@ libusb20_tr_stop(struct libusb20_transfer *xfer) void libusb20_tr_drain(struct libusb20_transfer *xfer) { + if (!xfer->is_opened) { + /* transfer is not opened */ + return; + } /* make sure that we are cancelling */ libusb20_tr_stop(xfer); @@ -415,9 +423,79 @@ libusb20_tr_setup_isoc(struct libusb20_transfer *xfer, void *pBuf, uint32_t leng return; } +uint8_t +libusb20_tr_bulk_intr_sync(struct libusb20_transfer *xfer, + void *pbuf, uint32_t length, uint32_t *pactlen, + uint32_t timeout) +{ + struct libusb20_device *pdev = xfer->pdev; + uint32_t transfer_max; + uint32_t transfer_act; + uint8_t retval; + + /* set some sensible default value */ + if (pactlen != NULL) + *pactlen = 0; + + /* check for error condition */ + if (libusb20_tr_pending(xfer)) + return (LIBUSB20_ERROR_OTHER); + + do { + /* compute maximum transfer length */ + transfer_max = + libusb20_tr_get_max_total_length(xfer); + + if (transfer_max > length) + transfer_max = length; + + /* setup bulk or interrupt transfer */ + libusb20_tr_setup_bulk(xfer, pbuf, + transfer_max, timeout); + + /* start the transfer */ + libusb20_tr_start(xfer); + + /* wait for transfer completion */ + while (libusb20_dev_process(pdev) == 0) { + + if (libusb20_tr_pending(xfer) == 0) + break; + + libusb20_dev_wait_process(pdev, -1); + } + + transfer_act = libusb20_tr_get_actual_length(xfer); + + /* update actual length, if any */ + if (pactlen != NULL) + pactlen[0] += transfer_act; + + /* check transfer status */ + retval = libusb20_tr_get_status(xfer); + if (retval) + break; + + /* check for short transfer */ + if (transfer_act != transfer_max) + break; + + /* update buffer pointer and length */ + pbuf = ((uint8_t *)pbuf) + transfer_max; + length = length - transfer_max; + + } while (length != 0); + + return (retval); +} + void libusb20_tr_submit(struct libusb20_transfer *xfer) { + if (!xfer->is_opened) { + /* transfer is not opened */ + return; + } if (xfer->is_pending) { /* should not happen */ return; @@ -433,6 +511,10 @@ libusb20_tr_submit(struct libusb20_transfer *xfer) void libusb20_tr_start(struct libusb20_transfer *xfer) { + if (!xfer->is_opened) { + /* transfer is not opened */ + return; + } if (xfer->is_pending) { if (xfer->is_cancel) { /* cancelling - restart */ @@ -461,7 +543,14 @@ libusb20_dev_close(struct libusb20_device *pdev) for (x = 0; x != pdev->nTransfer; x++) { xfer = pdev->pTransfer + x; + if (!xfer->is_opened) { + /* transfer is not opened */ + continue; + } + libusb20_tr_drain(xfer); + + libusb20_tr_close(xfer); } if (pdev->pTransfer != NULL) { diff --git a/lib/libusb/libusb20.h b/lib/libusb/libusb20.h index 9f45861f738..bb7d8a4ab3d 100644 --- a/lib/libusb/libusb20.h +++ b/lib/libusb/libusb20.h @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /*- - * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2008-2009 Hans Petter Selasky. All rights reserved. * Copyright (c) 2007-2008 Daniel Drake. All rights reserved. * Copyright (c) 2001 Johannes Erdfelt. All rights reserved. * @@ -226,6 +226,7 @@ void libusb20_tr_setup_bulk(struct libusb20_transfer *xfer, void *pbuf, uint32_t void libusb20_tr_setup_control(struct libusb20_transfer *xfer, void *psetup, void *pbuf, uint32_t timeout); void libusb20_tr_setup_intr(struct libusb20_transfer *xfer, void *pbuf, uint32_t length, uint32_t timeout); void libusb20_tr_setup_isoc(struct libusb20_transfer *xfer, void *pbuf, uint32_t length, uint16_t fr_index); +uint8_t libusb20_tr_bulk_intr_sync(struct libusb20_transfer *xfer, void *pbuf, uint32_t length, uint32_t *pactlen, uint32_t timeout); void libusb20_tr_start(struct libusb20_transfer *xfer); void libusb20_tr_stop(struct libusb20_transfer *xfer); void libusb20_tr_submit(struct libusb20_transfer *xfer); From 310ce38f75e06d2d052793bb9869bfc9a91bfc26 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 21:47:42 +0000 Subject: [PATCH 0796/2592] MFC r199086,199151,199680,199948,200241 Driver for the Apple Touchpad present on MacBook (non-Pro & Pro). Submitted by: Rohit Grover --- sys/conf/files | 1 + sys/dev/usb/input/atp.c | 2224 ++++++++++++++++++++++++++++++++++ sys/modules/usb/Makefile | 2 +- sys/modules/usb/atp/Makefile | 11 + 4 files changed, 2237 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 e7afc91906e..104c631891a 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1669,6 +1669,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..6c0ce2c7036 --- /dev/null +++ b/sys/dev/usb/input/atp.c @@ -0,0 +1,2224 @@ +/*- + * 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"); + +/* 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, + .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 + }, +}; + +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) }, + + /* 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) }, + +}; + +/* + * 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_RESET, + 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 +#define ATP_VALID 0x08 + + 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 void atp_reset_callback(struct usb_xfer *, usb_error_t); +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, 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 *); + +/* movement detection */ +static boolean_t atp_match_stroke_component(atp_stroke_component *, + const atp_pspan *, atp_stroke_type); +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 *); +static void atp_convert_to_slide(struct atp_softc *, atp_stroke *); + +/* 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); +} + +void +atp_reset_callback(struct usb_xfer *xfer, usb_error_t error) +{ + usb_device_request_t req; + struct usb_page_cache *pc; + struct atp_softc *sc = usbd_xfer_softc(xfer); + + switch (USB_GET_STATE(xfer)) { + case USB_ST_SETUP: + sc->sc_mode_bytes[0] = RAW_SENSOR_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); + + pc = usbd_xfer_get_frame(xfer, 0); + usbd_copy_in(pc, 0, &req, sizeof(req)); + pc = usbd_xfer_get_frame(xfer, 1); + usbd_copy_in(pc, 0, sc->sc_mode_bytes, MODE_LENGTH); + + usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); + usbd_xfer_set_frame_len(xfer, 1, MODE_LENGTH); + usbd_xfer_set_frames(xfer, 2); + usbd_transfer_submit(xfer); + break; + + case USB_ST_TRANSFERRED: + default: + break; + } +} + +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 | ATP_VALID); + 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'. + * 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, atp_axis axis, + int *arr, atp_protocol prot) +{ + u_int i; + u_int di; /* index into sensor data */ + + 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; + } +} + +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, atp_stroke_type stroke_type) +{ + int delta_mickeys; + u_int min_pressure; + + 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; + + /* + * A sudden and significant increase in a pspan's cumulative + * pressure indicates the incidence of a new finger + * contact. This usually revises the pspan's + * centre-of-gravity, and hence the location of any/all + * matching stroke component(s). But such a change should + * *not* be interpreted as a movement. + */ + if (pspan->cum > ((3 * component->cum_pressure) >> 1)) + delta_mickeys = 0; + + component->cum_pressure = pspan->cum; + if (pspan->cum > component->max_cum_pressure) + component->max_cum_pressure = pspan->cum; + + /* + * Disregard the component's movement if its cumulative + * pressure drops below a fraction of the maximum; this + * fraction is determined based on the stroke's type. + */ + if (stroke_type == ATP_STROKE_TOUCH) + min_pressure = (3 * component->max_cum_pressure) >> 2; + else + min_pressure = component->max_cum_pressure >> 2; + if (component->cum_pressure < min_pressure) + 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], + stroke->type)) { + /* 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,cum:%d,max:%d,mv:%d%c" + ",%clc:%u,dm:%d,pnd:%d,cum:%d,max:%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].cum_pressure, + stroke->components[X].max_cum_pressure, + 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].cum_pressure, + stroke->components[Y].max_cum_pressure, + 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; + + if (stroke->type != ATP_STROKE_TOUCH) + return; + + /* Convert touch strokes to slides upon detecting movement or age. */ + if (stroke->cum_movement >= atp_slide_min_movement) { + atp_convert_to_slide(sc, stroke); + } else { + /* If a touch stroke is found to be older than the + * touch-timeout threshold, it should be converted to + * a slide; except if there is a co-incident sibling + * with a later creation time. + * + * When multiple fingers make contact with the + * touchpad, they are likely to be separated in their + * times of incidence. During a multi-finger tap, + * therefore, the last finger to make + * contact--i.e. the one with the latest + * 'ctime'--should be used to determine how the + * touch-siblings get treated; otherwise older + * siblings may lapse the touch-timeout and get + * converted into slides prematurely. The following + * loop determines if there exists another touch + * stroke with a larger 'ctime' than the current + * stroke (NOTE: zombies with a larger 'ctime' are + * also considered) . + */ + + u_int i; + for (i = 0; i < sc->sc_n_strokes; i++) { + if ((&sc->sc_strokes[i] == stroke) || + (sc->sc_strokes[i].type != ATP_STROKE_TOUCH)) + continue; + + if (timevalcmp(&sc->sc_strokes[i].ctime, + &stroke->ctime, >)) + break; + } + if (i == sc->sc_n_strokes) { + /* Found no other touch stroke with a larger 'ctime'. */ + 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 % 1000000)))) + atp_convert_to_slide(sc, stroke); + } + } +} + +/* Switch a given touch stroke to being a slide. */ +void +atp_convert_to_slide(struct atp_softc *sc, atp_stroke *stroke) +{ + 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, + }, + [ATP_RESET] = { + .type = UE_CONTROL, + .endpoint = 0, /* Control pipe */ + .direction = UE_DIR_ANY, + .bufsize = sizeof(struct usb_device_request) + MODE_LENGTH, + .callback = &atp_reset_callback, + .interval = 0, /* no pre-delay */ + }, +}; + +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); + + return (usbd_lookup_id_by_uaa(atp_devs, sizeof(atp_devs), uaa)); +} + +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; + + 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; + + 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); + + 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 < sc->sc_params->data_len) + 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, X, sc->cur_x, + sc->sc_params->prot); + atp_interpret_sensor_data(sc->sensor_data, + sc->sc_params->n_ysensors, Y, sc->cur_y, + sc->sc_params->prot); + + /* + * 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 ((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; + } + + /* 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"); + + /* + * Use the last frame before we go idle for + * calibration on pads which do not send + * calibration frames. + */ + if (sc->sc_params->prot < ATP_PROT_GEYSER3) { + 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_idlecount = 0; + usbd_transfer_start(sc->sc_xfer[ATP_RESET]); + } + } 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, + sc->sc_params->data_len); + 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 a4ca38642583978c2bdb1ae897791be724f5cf28 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Wed, 9 Dec 2009 21:56:55 +0000 Subject: [PATCH 0797/2592] MFC r199169: 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. --- 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 c15901d48b667211a4fbf301d29d9f000a8f7b88 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Wed, 9 Dec 2009 21:58:39 +0000 Subject: [PATCH 0798/2592] MFC r199949: Add atp(4) to powerpc GENERIC. Most late-generation Apple PowerPC laptops have trackpads that do not work at all without this driver. --- sys/powerpc/conf/GENERIC | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC index a7eca3f70a0..db6d0cd8370 100644 --- a/sys/powerpc/conf/GENERIC +++ b/sys/powerpc/conf/GENERIC @@ -147,6 +147,7 @@ options KBD_INSTALL_CDEV # install a CDEV entry in /dev device ulpt # Printer device umass # Disks/Mass storage - Requires scbus and da0 device ums # Mouse +device atp # Apple USB touchpad device urio # Diamond Rio 500 MP3 player # USB Ethernet device aue # ADMtek USB Ethernet From c39d541d9f82528b1e12572a86a7e5557a6c73cf Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:10:45 +0000 Subject: [PATCH 0799/2592] MFC r197761,r198194,r198862 updates device entries supported with the product name not magic numbers and sorts entries. WUSB54GCV2 is added. 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. --- sys/dev/usb/usbdevs | 10 + sys/dev/usb/wlan/if_urtw.c | 887 ++++++++++++++++++++-------------- sys/dev/usb/wlan/if_urtwreg.h | 159 +++++- sys/dev/usb/wlan/if_urtwvar.h | 8 +- 4 files changed, 681 insertions(+), 383 deletions(-) diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 5ebb2ddbfc5..9281462036d 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -909,6 +909,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 @@ -976,6 +977,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 @@ -1657,6 +1659,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 @@ -1877,6 +1880,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 @@ -2102,6 +2106,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 @@ -2271,6 +2278,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 @@ -2376,6 +2385,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 425471b6577..00789b89acc 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 { \ @@ -102,23 +103,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 @@ -325,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 }, @@ -477,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] = { @@ -491,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, @@ -702,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); @@ -712,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) @@ -756,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) { @@ -844,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; @@ -877,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); @@ -1013,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; @@ -1035,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; @@ -1067,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; @@ -1170,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 @@ -1309,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) @@ -1366,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) { @@ -1533,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); } @@ -1732,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], @@ -1747,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); @@ -1779,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[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; + } 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; @@ -2053,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); @@ -2071,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); @@ -2089,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); @@ -2106,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)); @@ -2122,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)); @@ -2138,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)); @@ -2403,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; @@ -2436,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" : @@ -2761,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); @@ -2770,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); } @@ -3038,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); @@ -3048,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); } @@ -3271,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 @@ -3326,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); @@ -3336,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); } @@ -3818,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); } @@ -3843,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); } @@ -3928,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); @@ -3945,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); @@ -3992,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; @@ -4006,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); } @@ -4071,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: @@ -4092,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) { @@ -4213,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 975199a5acb06ebd1d9ced18f2cc03ebfe7a789e Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:31:45 +0000 Subject: [PATCH 0800/2592] MFC r198774 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 2265c34554a39702d31dc2b3cc72210a4183dfc7 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:32:36 +0000 Subject: [PATCH 0801/2592] MFC r198776 - 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 653a3d45c4f3285e513843feb3c27ed522b7a6a2 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:33:22 +0000 Subject: [PATCH 0802/2592] MFC r199057 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 347a623924e..ec6f3f73fce 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 1250e0e32171adfd60c6b8b05f65d250d8cdb9f6 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:34:11 +0000 Subject: [PATCH 0803/2592] MFC r199059 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 2785d01590edadc667e9b2492fb0b0a5755bc3a0 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:35:08 +0000 Subject: [PATCH 0804/2592] MFC r199061 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 62460f64ff5955c09e10daaf7210dc229d9ae7dc Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:36:16 +0000 Subject: [PATCH 0805/2592] MFC r199062 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 b7167d5d0dd29985387f9c91684dca4bedc784fe Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:37:06 +0000 Subject: [PATCH 0806/2592] MFC r199672 Improve High Speed slot allocation mechanism by moving the computation to the endpoint rather than per xfer and provide functions around get/free of resources. Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/ehci.c | 59 +++-------- sys/dev/usb/usb_core.h | 3 - sys/dev/usb/usb_device.c | 2 +- sys/dev/usb/usb_hub.c | 181 +++++++++++++++++++++++++++++++--- sys/dev/usb/usb_hub.h | 4 +- sys/dev/usb/usb_transfer.c | 20 +++- sys/dev/usb/usbdi.h | 11 ++- 7 files changed, 209 insertions(+), 71 deletions(-) diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index 5cc9b29aea7..d665b89077c 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -2016,8 +2016,8 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last) qh_endphub = (EHCI_QH_SET_MULT(xfer->max_packet_count & 3) | - EHCI_QH_SET_CMASK(xfer->usb_cmask) | - EHCI_QH_SET_SMASK(xfer->usb_smask) | + EHCI_QH_SET_CMASK(xfer->endpoint->usb_cmask) | + EHCI_QH_SET_SMASK(xfer->endpoint->usb_smask) | EHCI_QH_SET_HUBA(xfer->xroot->udev->hs_hub_addr) | EHCI_QH_SET_PORT(xfer->xroot->udev->hs_port_no)); @@ -2162,7 +2162,7 @@ ehci_isoc_hs_done(ehci_softc_t *sc, struct usb_xfer *xfer) DPRINTFN(2, "status=0x%08x, len=%u\n", status, len); - if (xfer->usb_smask & (1 << td_no)) { + if (xfer->endpoint->usb_smask & (1 << td_no)) { if (*plen >= len) { /* @@ -2348,22 +2348,8 @@ ehci_device_intr_open(struct usb_xfer *xfer) uint16_t best; uint16_t bit; uint16_t x; - uint8_t slot; - /* Allocate a microframe slot first: */ - - slot = usb_intr_schedule_adjust - (xfer->xroot->udev, xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX); - - if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) { - xfer->usb_uframe = slot; - xfer->usb_smask = (1 << slot) & 0xFF; - xfer->usb_cmask = 0; - } else { - xfer->usb_uframe = slot; - xfer->usb_smask = (1 << slot) & 0x3F; - xfer->usb_cmask = (-(4 << slot)) & 0xFE; - } + usb_hs_bandwidth_alloc(xfer); /* * Find the best QH position corresponding to the given interval: @@ -2399,12 +2385,12 @@ ehci_device_intr_close(struct usb_xfer *xfer) { ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); - usb_intr_schedule_adjust(xfer->xroot->udev, - -(xfer->max_frame_size), xfer->usb_uframe); - sc->sc_intr_stat[xfer->qh_pos]--; ehci_device_done(xfer, USB_ERR_CANCELLED); + + /* bandwidth must be freed after device done */ + usb_hs_bandwidth_free(xfer); } static void @@ -2726,28 +2712,8 @@ 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; - } + usb_hs_bandwidth_alloc(xfer); /* initialize all TD's */ @@ -2791,11 +2757,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); + + /* bandwidth must be freed after device done */ + usb_hs_bandwidth_free(xfer); } static void @@ -2905,7 +2870,7 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer) *plen = xfer->max_frame_size; } - if (xfer->usb_smask & (1 << td_no)) { + if (xfer->endpoint->usb_smask & (1 << td_no)) { status = (EHCI_ITD_SET_LEN(*plen) | EHCI_ITD_ACTIVE | EHCI_ITD_SET_PG(0)); diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h index 7541adbc703..3dfd0d1ab6c 100644 --- a/sys/dev/usb/usb_core.h +++ b/sys/dev/usb/usb_core.h @@ -161,9 +161,6 @@ struct usb_xfer { uint8_t address; /* physical USB address */ uint8_t endpointno; /* physical USB endpoint */ uint8_t max_packet_count; - uint8_t usb_smask; - uint8_t usb_cmask; - uint8_t usb_uframe; uint8_t usb_state; uint8_t fps_shift; /* down shift of FPS, 0..3 */ diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index 4339cb24777..ae71f7da598 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -665,7 +665,7 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd) /* look for matching endpoints */ if ((iface_index == USB_IFACE_INDEX_ANY) || (iface_index == ep->iface_index)) { - if (ep->refcount != 0) { + if (ep->refcount_alloc != 0) { /* * This typically indicates a * more serious error. diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 07a0970b33b..08090864c72 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -1106,43 +1106,62 @@ done: * The best Transaction Translation slot for an interrupt endpoint. *------------------------------------------------------------------------*/ static uint8_t -usb_intr_find_best_slot(usb_size_t *ptr, uint8_t start, uint8_t end) +usb_intr_find_best_slot(usb_size_t *ptr, uint8_t start, + uint8_t end, uint8_t mask) { - usb_size_t max = 0 - 1; + usb_size_t min = 0 - 1; + usb_size_t sum; uint8_t x; uint8_t y; + uint8_t z; y = 0; /* find the last slot with lesser used bandwidth */ for (x = start; x < end; x++) { - if (max >= ptr[x]) { - max = ptr[x]; + + sum = 0; + + /* compute sum of bandwidth */ + for (z = x; z < end; z++) { + if (mask & (1U << (z - x))) + sum += ptr[z]; + } + + /* check if the current multi-slot is more optimal */ + if (min >= sum) { + min = sum; y = x; } + + /* check if the mask is about to be shifted out */ + if (mask & (1U << (end - 1 - x))) + break; } return (y); } /*------------------------------------------------------------------------* - * usb_intr_schedule_adjust + * usb_hs_bandwidth_adjust * * This function will update the bandwith usage for the microframe * having index "slot" by "len" bytes. "len" can be negative. If the * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX" * the "slot" argument will be replaced by the slot having least used - * bandwidth. + * bandwidth. The "mask" argument is used for multi-slot allocations. * * Returns: - * The slot on which the bandwidth update was done. + * The slot in which the bandwidth update was done: 0..7 *------------------------------------------------------------------------*/ -uint8_t -usb_intr_schedule_adjust(struct usb_device *udev, int16_t len, uint8_t slot) +static uint8_t +usb_hs_bandwidth_adjust(struct usb_device *udev, int16_t len, + uint8_t slot, uint8_t mask) { struct usb_bus *bus = udev->bus; struct usb_hub *hub; enum usb_dev_speed speed; + uint8_t x; USB_BUS_LOCK_ASSERT(bus, MA_OWNED); @@ -1164,22 +1183,156 @@ usb_intr_schedule_adjust(struct usb_device *udev, int16_t len, uint8_t slot) hub = udev->parent_hs_hub->hub; if (slot >= USB_HS_MICRO_FRAMES_MAX) { slot = usb_intr_find_best_slot(hub->uframe_usage, - USB_FS_ISOC_UFRAME_MAX, 6); + USB_FS_ISOC_UFRAME_MAX, 6, mask); + } + for (x = slot; x < 8; x++) { + if (mask & (1U << (x - slot))) { + hub->uframe_usage[x] += len; + bus->uframe_usage[x] += len; + } } - hub->uframe_usage[slot] += len; - bus->uframe_usage[slot] += len; break; default: if (slot >= USB_HS_MICRO_FRAMES_MAX) { slot = usb_intr_find_best_slot(bus->uframe_usage, 0, - USB_HS_MICRO_FRAMES_MAX); + USB_HS_MICRO_FRAMES_MAX, mask); + } + for (x = slot; x < 8; x++) { + if (mask & (1U << (x - slot))) { + bus->uframe_usage[x] += len; + } } - bus->uframe_usage[slot] += len; break; } return (slot); } +/*------------------------------------------------------------------------* + * usb_hs_bandwidth_alloc + * + * This function is a wrapper function for "usb_hs_bandwidth_adjust()". + *------------------------------------------------------------------------*/ +void +usb_hs_bandwidth_alloc(struct usb_xfer *xfer) +{ + struct usb_device *udev; + uint8_t slot; + uint8_t mask; + uint8_t speed; + + udev = xfer->xroot->udev; + + if (udev->flags.usb_mode != USB_MODE_HOST) + return; /* not supported */ + + xfer->endpoint->refcount_bw++; + if (xfer->endpoint->refcount_bw != 1) + return; /* already allocated */ + + speed = usbd_get_speed(udev); + + switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) { + case UE_INTERRUPT: + /* allocate a microframe slot */ + + mask = 0x01; + slot = usb_hs_bandwidth_adjust(udev, + xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX, mask); + + xfer->endpoint->usb_uframe = slot; + xfer->endpoint->usb_smask = mask << slot; + + if ((speed != USB_SPEED_FULL) && + (speed != USB_SPEED_LOW)) { + xfer->endpoint->usb_cmask = 0x00 ; + } else { + xfer->endpoint->usb_cmask = (-(0x04 << slot)) & 0xFE; + } + break; + + case UE_ISOCHRONOUS: + switch (usbd_xfer_get_fps_shift(xfer)) { + case 0: + mask = 0xFF; + break; + case 1: + mask = 0x55; + break; + case 2: + mask = 0x11; + break; + default: + mask = 0x01; + break; + } + + /* allocate a microframe multi-slot */ + + slot = usb_hs_bandwidth_adjust(udev, + xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX, mask); + + xfer->endpoint->usb_uframe = slot; + xfer->endpoint->usb_cmask = 0; + xfer->endpoint->usb_smask = mask << slot; + break; + + default: + xfer->endpoint->usb_uframe = 0; + xfer->endpoint->usb_cmask = 0; + xfer->endpoint->usb_smask = 0; + break; + } + + DPRINTFN(11, "slot=%d, mask=0x%02x\n", + xfer->endpoint->usb_uframe, + xfer->endpoint->usb_smask >> xfer->endpoint->usb_uframe); +} + +/*------------------------------------------------------------------------* + * usb_hs_bandwidth_free + * + * This function is a wrapper function for "usb_hs_bandwidth_adjust()". + *------------------------------------------------------------------------*/ +void +usb_hs_bandwidth_free(struct usb_xfer *xfer) +{ + struct usb_device *udev; + uint8_t slot; + uint8_t mask; + + udev = xfer->xroot->udev; + + if (udev->flags.usb_mode != USB_MODE_HOST) + return; /* not supported */ + + xfer->endpoint->refcount_bw--; + if (xfer->endpoint->refcount_bw != 0) + return; /* still allocated */ + + switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) { + case UE_INTERRUPT: + case UE_ISOCHRONOUS: + + slot = xfer->endpoint->usb_uframe; + mask = xfer->endpoint->usb_smask; + + /* free microframe slot(s): */ + usb_hs_bandwidth_adjust(udev, + -xfer->max_frame_size, slot, mask >> slot); + + DPRINTFN(11, "slot=%d, mask=0x%02x\n", + slot, mask >> slot); + + xfer->endpoint->usb_uframe = 0; + xfer->endpoint->usb_cmask = 0; + xfer->endpoint->usb_smask = 0; + break; + + default: + break; + } +} + /*------------------------------------------------------------------------* * usbd_fs_isoc_schedule_init_sub * diff --git a/sys/dev/usb/usb_hub.h b/sys/dev/usb/usb_hub.h index ceb0cc2283d..5b8dedf6e64 100644 --- a/sys/dev/usb/usb_hub.h +++ b/sys/dev/usb/usb_hub.h @@ -66,8 +66,8 @@ struct usb_hub { /* function prototypes */ -uint8_t usb_intr_schedule_adjust(struct usb_device *udev, int16_t len, - uint8_t slot); +void usb_hs_bandwidth_alloc(struct usb_xfer *xfer); +void usb_hs_bandwidth_free(struct usb_xfer *xfer); void usbd_fs_isoc_schedule_init_all(struct usb_fs_isoc_schedule *fss); void usb_bus_port_set_device(struct usb_bus *bus, struct usb_port *up, struct usb_device *udev, uint8_t device_index); diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index 4169ac8b5af..c434703ad01 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -942,10 +942,18 @@ usbd_transfer_setup(struct usb_device *udev, * configuration and alternate setting * when USB transfers are in use on * the given interface. Search the USB - * code for "endpoint->refcount" if you + * code for "endpoint->refcount_alloc" if you * want more information. */ - xfer->endpoint->refcount++; + USB_BUS_LOCK(info->bus); + if (xfer->endpoint->refcount_alloc >= USB_EP_REF_MAX) + parm.err = USB_ERR_INVAL; + + xfer->endpoint->refcount_alloc++; + + if (xfer->endpoint->refcount_alloc == 0) + panic("usbd_transfer_setup(): Refcount wrapped to zero\n"); + USB_BUS_UNLOCK(info->bus); /* * Whenever we set ppxfer[] then we @@ -960,6 +968,10 @@ usbd_transfer_setup(struct usb_device *udev, */ ppxfer[n] = xfer; } + + /* check for error */ + if (parm.err) + goto done; } if (buf || parm.err) { @@ -1179,7 +1191,9 @@ usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup) * NOTE: default endpoint does not have an * interface, even if endpoint->iface_index == 0 */ - xfer->endpoint->refcount--; + USB_BUS_LOCK(info->bus); + xfer->endpoint->refcount_alloc--; + USB_BUS_UNLOCK(info->bus); usb_callout_drain(&xfer->timeout_handle); diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 46747d7baf0..1a6665227be 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -130,13 +130,22 @@ struct usb_endpoint { struct usb_pipe_methods *methods; /* set by HC driver */ uint16_t isoc_next; - uint16_t refcount; uint8_t toggle_next:1; /* next data toggle value */ uint8_t is_stalled:1; /* set if endpoint is stalled */ uint8_t is_synced:1; /* set if we a synchronised */ uint8_t unused:5; uint8_t iface_index; /* not used by "default endpoint" */ + + uint8_t refcount_alloc; /* allocation refcount */ + uint8_t refcount_bw; /* bandwidth refcount */ +#define USB_EP_REF_MAX 0x3f + + /* High-Speed resource allocation (valid if "refcount_bw" > 0) */ + + uint8_t usb_smask; /* USB start mask */ + uint8_t usb_cmask; /* USB complete mask */ + uint8_t usb_uframe; /* USB microframe */ }; /* From 4cd01f77501f2b08a2c6d02b91882da4da3b2cb7 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:38:02 +0000 Subject: [PATCH 0807/2592] MFC r199673 Initialise variable before use. Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/at91dci.c | 1 + sys/dev/usb/controller/atmegadci.c | 1 + sys/dev/usb/controller/avr32dci.c | 1 + sys/dev/usb/controller/musb_otg.c | 1 + sys/dev/usb/controller/uss820dci.c | 1 + 5 files changed, 5 insertions(+) diff --git a/sys/dev/usb/controller/at91dci.c b/sys/dev/usb/controller/at91dci.c index d9f8e4066c3..fc0db86a3b8 100644 --- a/sys/dev/usb/controller/at91dci.c +++ b/sys/dev/usb/controller/at91dci.c @@ -894,6 +894,7 @@ at91dci_setup_standard_chain(struct usb_xfer *xfer) /* setup temp */ + temp.pc = NULL; temp.td = NULL; temp.td_next = xfer->td_start[0]; temp.offset = 0; diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c index a864c5765c5..1ee8423d2b2 100644 --- a/sys/dev/usb/controller/atmegadci.c +++ b/sys/dev/usb/controller/atmegadci.c @@ -797,6 +797,7 @@ atmegadci_setup_standard_chain(struct usb_xfer *xfer) /* setup temp */ + temp.pc = NULL; temp.td = NULL; temp.td_next = xfer->td_start[0]; temp.offset = 0; diff --git a/sys/dev/usb/controller/avr32dci.c b/sys/dev/usb/controller/avr32dci.c index f251f9109ae..36980adde9a 100644 --- a/sys/dev/usb/controller/avr32dci.c +++ b/sys/dev/usb/controller/avr32dci.c @@ -767,6 +767,7 @@ avr32dci_setup_standard_chain(struct usb_xfer *xfer) /* setup temp */ + temp.pc = NULL; temp.td = NULL; temp.td_next = xfer->td_start[0]; temp.offset = 0; diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index 60d29dd690b..e811cae7380 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -1144,6 +1144,7 @@ musbotg_setup_standard_chain(struct usb_xfer *xfer) /* setup temp */ + temp.pc = NULL; temp.td = NULL; temp.td_next = xfer->td_start[0]; temp.offset = 0; diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c index 62fa8df4b61..fe14d513c8b 100644 --- a/sys/dev/usb/controller/uss820dci.c +++ b/sys/dev/usb/controller/uss820dci.c @@ -858,6 +858,7 @@ uss820dci_setup_standard_chain(struct usb_xfer *xfer) /* setup temp */ + temp.pc = NULL; temp.td = NULL; temp.td_next = xfer->td_start[0]; temp.offset = 0; From c7838bf992f923309131a3939ee2e4c3d3448903 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:39:09 +0000 Subject: [PATCH 0808/2592] MFC r199675 Provide tunables for some of the usb sysctls that affect boot behaviour. Submitted by: Andriy Gapon --- sys/dev/usb/controller/ehci.c | 3 +++ sys/dev/usb/controller/ohci.c | 3 +++ sys/dev/usb/controller/uhci.c | 4 ++++ sys/dev/usb/input/ukbd.c | 2 ++ sys/dev/usb/storage/umass.c | 2 ++ sys/dev/usb/usb_debug.c | 2 ++ sys/dev/usb/usb_dev.c | 2 ++ sys/dev/usb/usb_generic.c | 2 ++ sys/dev/usb/usb_hub.c | 2 ++ sys/dev/usb/usb_process.c | 2 ++ 10 files changed, 24 insertions(+) diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index d665b89077c..69507b0505f 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -99,6 +99,9 @@ SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW, SYSCTL_INT(_hw_usb_ehci, OID_AUTO, no_hs, CTLFLAG_RW, &ehcinohighspeed, 0, "Disable High Speed USB"); +TUNABLE_INT("hw.usb.ehci.debug", &ehcidebug); +TUNABLE_INT("hw.usb.ehci.no_hs", &ehcinohighspeed); + static void ehci_dump_regs(ehci_softc_t *sc); static void ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *sqh); diff --git a/sys/dev/usb/controller/ohci.c b/sys/dev/usb/controller/ohci.c index 637b639e3f6..fa7f23ac196 100644 --- a/sys/dev/usb/controller/ohci.c +++ b/sys/dev/usb/controller/ohci.c @@ -84,6 +84,9 @@ static int ohcidebug = 0; SYSCTL_NODE(_hw_usb, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci"); SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RW, &ohcidebug, 0, "ohci debug level"); + +TUNABLE_INT("hw.usb.ohci.debug", &ohcidebug); + static void ohci_dumpregs(ohci_softc_t *); static void ohci_dump_tds(ohci_td_t *); static uint8_t ohci_dump_td(ohci_td_t *); diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c index 4e2659cdc83..918855bf5aa 100644 --- a/sys/dev/usb/controller/uhci.c +++ b/sys/dev/usb/controller/uhci.c @@ -91,6 +91,10 @@ SYSCTL_INT(_hw_usb_uhci, OID_AUTO, debug, CTLFLAG_RW, &uhcidebug, 0, "uhci debug level"); SYSCTL_INT(_hw_usb_uhci, OID_AUTO, loop, CTLFLAG_RW, &uhcinoloop, 0, "uhci noloop"); + +TUNABLE_INT("hw.usb.uhci.debug", &uhcidebug); +TUNABLE_INT("hw.usb.uhci.loop", &uhcinoloop); + static void uhci_dumpregs(uhci_softc_t *sc); static void uhci_dump_tds(uhci_td_t *td); diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index 26ed8bce19c..a419f95e288 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -105,6 +105,8 @@ SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, debug, CTLFLAG_RW, SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, no_leds, CTLFLAG_RW, &ukbd_no_leds, 0, "Disables setting of keyboard leds"); +TUNABLE_INT("hw.usb.ukbd.debug", &ukbd_debug); +TUNABLE_INT("hw.usb.ukbd.no_leds", &ukbd_no_leds); #endif #define UPROTO_BOOT_KEYBOARD 1 diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index 18756c97cf9..f2430dc17e7 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -175,6 +175,8 @@ static int umass_debug = 0; SYSCTL_NODE(_hw_usb, OID_AUTO, umass, CTLFLAG_RW, 0, "USB umass"); SYSCTL_INT(_hw_usb_umass, OID_AUTO, debug, CTLFLAG_RW, &umass_debug, 0, "umass debug level"); + +TUNABLE_INT("hw.usb.umass.debug", &umass_debug); #else #define DIF(...) do { } while (0) #define DPRINTF(...) do { } while (0) diff --git a/sys/dev/usb/usb_debug.c b/sys/dev/usb/usb_debug.c index 7f1e4e921a0..64c3a08b412 100644 --- a/sys/dev/usb/usb_debug.c +++ b/sys/dev/usb/usb_debug.c @@ -67,6 +67,8 @@ SYSCTL_NODE(_hw, OID_AUTO, usb, CTLFLAG_RW, 0, "USB debugging"); SYSCTL_INT(_hw_usb, OID_AUTO, debug, CTLFLAG_RW, &usb_debug, 0, "Debug level"); +TUNABLE_INT("hw.usb.debug", &usb_debug); + /*------------------------------------------------------------------------* * usb_dump_iface * diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c index c828b24057f..63615332dea 100644 --- a/sys/dev/usb/usb_dev.c +++ b/sys/dev/usb/usb_dev.c @@ -85,6 +85,8 @@ static int usb_fifo_debug = 0; SYSCTL_NODE(_hw_usb, OID_AUTO, dev, CTLFLAG_RW, 0, "USB device"); SYSCTL_INT(_hw_usb_dev, OID_AUTO, debug, CTLFLAG_RW, &usb_fifo_debug, 0, "Debug Level"); + +TUNABLE_INT("hw.usb.dev.debug", &usb_fifo_debug); #endif #if ((__FreeBSD_version >= 700001) || (__FreeBSD_version == 0) || \ diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c index 5990cd5ff94..9fc0cc7eef2 100644 --- a/sys/dev/usb/usb_generic.c +++ b/sys/dev/usb/usb_generic.c @@ -130,6 +130,8 @@ static int ugen_debug = 0; SYSCTL_NODE(_hw_usb, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB generic"); SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RW, &ugen_debug, 0, "Debug level"); + +TUNABLE_INT("hw.usb.ugen.debug", &ugen_debug); #endif diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 08090864c72..a116ab4861f 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -79,6 +79,8 @@ static int uhub_debug = 0; SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB"); SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0, "Debug level"); + +TUNABLE_INT("hw.usb.uhub.debug", &uhub_debug); #endif #if USB_HAVE_POWERD diff --git a/sys/dev/usb/usb_process.c b/sys/dev/usb/usb_process.c index eb503fd18c4..5b4b749ff34 100644 --- a/sys/dev/usb/usb_process.c +++ b/sys/dev/usb/usb_process.c @@ -83,6 +83,8 @@ static int usb_proc_debug; SYSCTL_NODE(_hw_usb, OID_AUTO, proc, CTLFLAG_RW, 0, "USB process"); SYSCTL_INT(_hw_usb_proc, OID_AUTO, debug, CTLFLAG_RW, &usb_proc_debug, 0, "Debug level"); + +TUNABLE_INT("hw.usb.proc.debug", &usb_proc_debug); #endif /*------------------------------------------------------------------------* From 0ae254cb36d4e8ac5d409def82cbaa415616d450 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:40:27 +0000 Subject: [PATCH 0809/2592] MFC r199676 Correct register access for USB device side operation on the musb controller. Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/musb_otg.c | 67 ++++++++++++++++++++++++++----- sys/dev/usb/controller/musb_otg.h | 2 +- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index e811cae7380..00fc7cc385c 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -1539,18 +1539,18 @@ musbotg_clear_stall_sub(struct musbotg_softc *sc, uint16_t wMaxPacket, /* Configure endpoint */ switch (ep_type) { case UE_INTERRUPT: - MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket); + MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket); MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH, MUSB2_MASK_CSRH_TXMODE | temp); break; case UE_ISOCHRONOUS: - MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket); + MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket); MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH, MUSB2_MASK_CSRH_TXMODE | MUSB2_MASK_CSRH_TXISO | temp); break; case UE_BULK: - MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket); + MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket); MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH, MUSB2_MASK_CSRH_TXMODE | temp); break; @@ -1600,18 +1600,18 @@ musbotg_clear_stall_sub(struct musbotg_softc *sc, uint16_t wMaxPacket, /* Configure endpoint */ switch (ep_type) { case UE_INTERRUPT: - MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket); + MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket); MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, MUSB2_MASK_CSRH_RXNYET | temp); break; case UE_ISOCHRONOUS: - MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket); + MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket); MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, MUSB2_MASK_CSRH_RXNYET | MUSB2_MASK_CSRH_RXISO | temp); break; case UE_BULK: - MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket); + MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket); MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, temp); break; default: @@ -1688,12 +1688,14 @@ usb_error_t musbotg_init(struct musbotg_softc *sc) { struct usb_hw_ep_profile *pf; + uint16_t offset; uint8_t nrx; uint8_t ntx; uint8_t temp; uint8_t fsize; uint8_t frx; uint8_t ftx; + uint8_t dynfifo; DPRINTFN(1, "start\n"); @@ -1776,11 +1778,20 @@ musbotg_init(struct musbotg_softc *sc) DPRINTFN(2, "Config Data: 0x%02x\n", sc->sc_conf_data); + dynfifo = (sc->sc_conf_data & MUSB2_MASK_CD_DYNFIFOSZ) ? 1 : 0; + + if (dynfifo) { + DPRINTFN(0, "Dynamic FIFO sizing detected! " + "Assuming 16Kbytes of FIFO RAM\n"); + } + DPRINTFN(2, "HW version: 0x%04x\n", MUSB2_READ_1(sc, MUSB2_REG_HWVERS)); /* initialise endpoint profiles */ + offset = 0; + for (temp = 1; temp <= sc->sc_ep_max; temp++) { pf = sc->sc_hw_ep_profile + temp; @@ -1791,9 +1802,45 @@ musbotg_init(struct musbotg_softc *sc) frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16;; ftx = (fsize & MUSB2_MASK_TX_FSIZE); - DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u\n", - temp, pf->max_in_frame_size, - pf->max_out_frame_size); + DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u, DYN=%d\n", + temp, ftx, frx, dynfifo); + + if (dynfifo) { + if (frx && (temp <= nrx)) { + if (temp < 8) { + frx = 10; /* 1K */ + MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ, + MUSB2_VAL_FIFOSZ_512 | + MUSB2_MASK_FIFODB); + } else { + frx = 7; /* 128 bytes */ + MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ, + MUSB2_VAL_FIFOSZ_128); + } + + MUSB2_WRITE_2(sc, MUSB2_REG_RXFIFOADD, + offset >> 3); + + offset += (1 << frx); + } + if (ftx && (temp <= ntx)) { + if (temp < 8) { + ftx = 10; /* 1K */ + MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ, + MUSB2_VAL_FIFOSZ_512 | + MUSB2_MASK_FIFODB); + } else { + ftx = 7; /* 128 bytes */ + MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ, + MUSB2_VAL_FIFOSZ_128); + } + + MUSB2_WRITE_2(sc, MUSB2_REG_TXFIFOADD, + offset >> 3); + + offset += (1 << ftx); + } + } if (frx && ftx && (temp <= nrx) && (temp <= ntx)) { pf->max_in_frame_size = 1 << ftx; @@ -1824,6 +1871,8 @@ musbotg_init(struct musbotg_softc *sc) } } + DPRINTFN(2, "Dynamic FIFO size = %d bytes\n", offset); + /* turn on default interrupts */ MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, diff --git a/sys/dev/usb/controller/musb_otg.h b/sys/dev/usb/controller/musb_otg.h index 0e843c910e4..e8eafca6fb1 100644 --- a/sys/dev/usb/controller/musb_otg.h +++ b/sys/dev/usb/controller/musb_otg.h @@ -191,7 +191,7 @@ #define MUSB2_REG_EPFIFO(n) (0x0020 + (4*(n))) -#define MUSB2_REG_CONFDATA 0x000F /* EPN=0 */ +#define MUSB2_REG_CONFDATA (0x000F + MUSB2_REG_INDEXED_CSR) /* EPN=0 */ #define MUSB2_MASK_CD_UTMI_DW 0x01 #define MUSB2_MASK_CD_SOFTCONE 0x02 #define MUSB2_MASK_CD_DYNFIFOSZ 0x04 From 044745556ccdae536ddca647e8e8e4cc1c4e2547 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:41:11 +0000 Subject: [PATCH 0810/2592] MFC r199718 Actually disable interrupts in ehci_detach(). --- sys/dev/usb/controller/ehci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index 69507b0505f..952dd983edd 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -528,7 +528,7 @@ ehci_detach(ehci_softc_t *sc) usb_callout_stop(&sc->sc_tmo_pcd); usb_callout_stop(&sc->sc_tmo_poll); - EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); + EOWRITE4(sc, EHCI_USBINTR, 0); USB_BUS_UNLOCK(&sc->sc_bus); if (ehci_hcreset(sc)) { From fd29c5e00e8377a26c56457473a67371f8126fa8 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:41:50 +0000 Subject: [PATCH 0811/2592] MFC r199814 Disable interrupts after doing early takeover of the usb controller in case usb isnt actually compiled in (or kldloaded) as the controller could cause spurious interrupts. --- sys/dev/pci/pci.c | 17 +++++++++++++++++ sys/dev/usb/controller/uhci_pci.c | 2 -- sys/dev/usb/controller/uhcireg.h | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index e60ee234c85..b76e2e7103b 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -2610,6 +2610,8 @@ ohci_early_takeover(device_t self) "SMM does not respond, resetting\n"); bus_write_4(res, OHCI_CONTROL, OHCI_HCFS_RESET); } + /* Disable interrupts */ + bus_write_4(res, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); } bus_release_resource(self, SYS_RES_MEMORY, rid, res); @@ -2619,6 +2621,9 @@ ohci_early_takeover(device_t self) static void uhci_early_takeover(device_t self) { + struct resource *res; + int rid; + /* * 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 @@ -2626,6 +2631,14 @@ uhci_early_takeover(device_t self) * to the ports of the root hub? */ pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2); + + /* Disable interrupts */ + rid = PCI_UHCI_BASE_REG; + res = bus_alloc_resource_any(self, SYS_RES_IOPORT, &rid, RF_ACTIVE); + if (res != NULL) { + bus_write_2(res, UHCI_INTR, 0); + bus_release_resource(self, SYS_RES_IOPORT, rid, res); + } } /* Perform early EHCI takeover from SMM. */ @@ -2637,6 +2650,7 @@ ehci_early_takeover(device_t self) uint32_t eec; uint8_t eecp; uint8_t bios_sem; + uint8_t offs; int rid; int i; @@ -2676,6 +2690,9 @@ ehci_early_takeover(device_t self) printf("ehci early: " "SMM does not respond\n"); } + /* Disable interrupts */ + offs = bus_read_1(res, EHCI_CAPLENGTH); + bus_write_4(res, offs + EHCI_USBINTR, 0); } bus_release_resource(self, SYS_RES_MEMORY, rid, res); } diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c index 3956eada423..7609b0fd153 100644 --- a/sys/dev/usb/controller/uhci_pci.c +++ b/sys/dev/usb/controller/uhci_pci.c @@ -88,8 +88,6 @@ __FBSDID("$FreeBSD$"); /* PIIX4E has no separate stepping */ -#define PCI_UHCI_BASE_REG 0x20 - static device_probe_t uhci_pci_probe; static device_attach_t uhci_pci_attach; static device_detach_t uhci_pci_detach; diff --git a/sys/dev/usb/controller/uhcireg.h b/sys/dev/usb/controller/uhcireg.h index eeabbf0eedc..993b73cd4ea 100644 --- a/sys/dev/usb/controller/uhcireg.h +++ b/sys/dev/usb/controller/uhcireg.h @@ -39,6 +39,8 @@ #ifndef _UHCIREG_H_ #define _UHCIREG_H_ +#define PCI_UHCI_BASE_REG 0x20 + /* PCI config registers */ #define PCI_USBREV 0x60 /* USB protocol revision */ #define PCI_USB_REV_MASK 0xff From c1b5138fc1170e57442a3430ba06b67ff66e9620 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 22:42:40 +0000 Subject: [PATCH 0812/2592] MFC r199816 Remove overuse of exclamation marks in kernel printfs, there mere fact a message has been printed is enough to get someones attention. Also remove the line number for DPRINTF/DPRINTFN, it already prints the funtion name and a unique message. --- sys/dev/usb/controller/atmegadci.c | 6 ++++-- sys/dev/usb/controller/avr32dci.c | 5 +++-- sys/dev/usb/controller/musb_otg.c | 4 ++-- sys/dev/usb/controller/usb_controller.c | 6 +++--- sys/dev/usb/input/ukbd.c | 2 +- sys/dev/usb/net/if_aue.c | 2 +- sys/dev/usb/net/if_axe.c | 2 +- sys/dev/usb/net/if_cdce.c | 4 ++-- sys/dev/usb/net/if_cue.c | 2 +- sys/dev/usb/net/if_kue.c | 4 ++-- sys/dev/usb/net/if_rue.c | 4 ++-- sys/dev/usb/net/if_udav.c | 2 +- sys/dev/usb/serial/u3g.c | 4 ---- sys/dev/usb/serial/uark.c | 2 +- sys/dev/usb/serial/ubser.c | 2 +- sys/dev/usb/serial/ucycom.c | 4 ++-- sys/dev/usb/serial/ufoma.c | 6 +++--- sys/dev/usb/serial/uftdi.c | 2 +- sys/dev/usb/serial/ugensa.c | 4 ++-- sys/dev/usb/serial/umct.c | 2 +- sys/dev/usb/serial/umodem.c | 4 ++-- sys/dev/usb/serial/uplcom.c | 4 ++-- sys/dev/usb/storage/umass.c | 2 +- sys/dev/usb/template/usb_template.c | 6 +++--- sys/dev/usb/usb_busdma.c | 6 +++--- sys/dev/usb/usb_debug.h | 10 ++++----- sys/dev/usb/usb_dev.c | 4 ++-- sys/dev/usb/usb_device.c | 22 +++++++++---------- sys/dev/usb/usb_hid.c | 8 +++---- sys/dev/usb/usb_hub.c | 20 +++++++++--------- sys/dev/usb/usb_msctest.c | 2 +- sys/dev/usb/usb_process.c | 2 +- sys/dev/usb/usb_request.c | 4 ++-- sys/dev/usb/usb_transfer.c | 20 +++++++++--------- sys/dev/usb/wlan/if_upgt.c | 28 ++++++++++++------------- 35 files changed, 105 insertions(+), 106 deletions(-) diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c index 1ee8423d2b2..adbd972db6d 100644 --- a/sys/dev/usb/controller/atmegadci.c +++ b/sys/dev/usb/controller/atmegadci.c @@ -1192,7 +1192,8 @@ atmegadci_clear_stall_sub(struct atmegadci_softc *sc, uint8_t ep_no, temp = ATMEGA_READ_1(sc, ATMEGA_UESTA0X); if (!(temp & ATMEGA_UESTA0X_CFGOK)) { - DPRINTFN(0, "Chip rejected configuration\n"); + device_printf(sc->sc_bus.bdev, + "Chip rejected configuration\n"); } } while (0); } @@ -1914,7 +1915,8 @@ tr_handle_clear_port_feature: /* check valid config */ temp = ATMEGA_READ_1(sc, ATMEGA_UESTA0X); if (!(temp & ATMEGA_UESTA0X_CFGOK)) { - DPRINTFN(0, "Chip rejected EP0 configuration\n"); + device_printf(sc->sc_bus.bdev, + "Chip rejected EP0 configuration\n"); } break; case UHF_C_PORT_SUSPEND: diff --git a/sys/dev/usb/controller/avr32dci.c b/sys/dev/usb/controller/avr32dci.c index 36980adde9a..8abe46c4a6c 100644 --- a/sys/dev/usb/controller/avr32dci.c +++ b/sys/dev/usb/controller/avr32dci.c @@ -1160,7 +1160,7 @@ avr32dci_clear_stall_sub(struct avr32dci_softc *sc, uint8_t ep_no, temp = AVR32_READ_4(sc, AVR32_EPTCFG(ep_no)); if (!(temp & AVR32_EPTCFG_EPT_MAPD)) { - DPRINTFN(0, "Chip rejected configuration\n"); + device_printf(sc->sc_bus.bdev, "Chip rejected configuration\n"); } else { AVR32_WRITE_4(sc, AVR32_EPTCTLENB(ep_no), AVR32_EPTCTL_EPT_ENABL); @@ -1840,7 +1840,8 @@ tr_handle_clear_port_feature: temp = AVR32_READ_4(sc, AVR32_EPTCFG(0)); if (!(temp & AVR32_EPTCFG_EPT_MAPD)) { - DPRINTFN(0, "Chip rejected configuration\n"); + device_printf(sc->sc_bus.bdev, + "Chip rejected configuration\n"); } else { AVR32_WRITE_4(sc, AVR32_EPTCTLENB(0), AVR32_EPTCTL_EPT_ENABL); diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index 00fc7cc385c..987d3f65462 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -1781,8 +1781,8 @@ musbotg_init(struct musbotg_softc *sc) dynfifo = (sc->sc_conf_data & MUSB2_MASK_CD_DYNFIFOSZ) ? 1 : 0; if (dynfifo) { - DPRINTFN(0, "Dynamic FIFO sizing detected! " - "Assuming 16Kbytes of FIFO RAM\n"); + device_printf(sc->sc_bus.bdev, "Dynamic FIFO sizing detected, " + "assuming 16Kbytes of FIFO RAM\n"); } DPRINTFN(2, "HW version: 0x%04x\n", diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c index fe59e06ee1d..eb961fcb945 100644 --- a/sys/dev/usb/controller/usb_controller.c +++ b/sys/dev/usb/controller/usb_controller.c @@ -130,7 +130,7 @@ usb_attach(device_t dev) DPRINTF("\n"); if (bus == NULL) { - DPRINTFN(0, "USB device has no ivars\n"); + device_printf(dev, "USB device has no ivars\n"); return (ENXIO); } @@ -343,7 +343,7 @@ usb_bus_attach(struct usb_proc_msg *pm) break; default: - device_printf(bus->bdev, "Unsupported USB revision!\n"); + device_printf(bus->bdev, "Unsupported USB revision\n"); return; } @@ -530,7 +530,7 @@ usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat, (bus->devices_max < USB_MIN_DEVICES) || (bus->devices == NULL)) { DPRINTFN(0, "Devices field has not been " - "initialised properly!\n"); + "initialised properly\n"); bus->alloc_failed = 1; /* failure */ } #if USB_HAVE_BUSDMA diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index a419f95e288..d7bc2cd1a86 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -926,7 +926,7 @@ ukbd_detach(device_t dev) DPRINTF("\n"); if (sc->sc_flags & UKBD_FLAG_POLLING) { - panic("cannot detach polled keyboard!\n"); + panic("cannot detach polled keyboard\n"); } sc->sc_flags |= UKBD_FLAG_GONE; diff --git a/sys/dev/usb/net/if_aue.c b/sys/dev/usb/net/if_aue.c index 1a2ce70b5ae..44b0145aa21 100644 --- a/sys/dev/usb/net/if_aue.c +++ b/sys/dev/usb/net/if_aue.c @@ -692,7 +692,7 @@ aue_attach(device_t dev) sc->sc_xfer, aue_config, AUE_N_TRANSFER, sc, &sc->sc_mtx); if (error) { - device_printf(dev, "allocating USB transfers failed!\n"); + device_printf(dev, "allocating USB transfers failed\n"); goto detach; } diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c index eca726810fc..d5313b2da8a 100644 --- a/sys/dev/usb/net/if_axe.c +++ b/sys/dev/usb/net/if_axe.c @@ -706,7 +706,7 @@ axe_attach(device_t dev) error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, axe_config, AXE_N_TRANSFER, sc, &sc->sc_mtx); if (error) { - device_printf(dev, "allocating USB transfers failed!\n"); + device_printf(dev, "allocating USB transfers failed\n"); goto detach; } diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c index cb33249c8b8..e950517453f 100644 --- a/sys/dev/usb/net/if_cdce.c +++ b/sys/dev/usb/net/if_cdce.c @@ -489,7 +489,7 @@ cdce_attach(device_t dev) break; } } else { - device_printf(dev, "no data interface found!\n"); + device_printf(dev, "no data interface found\n"); goto detach; } } @@ -541,7 +541,7 @@ alloc_transfers: if (error || (i == 32)) { device_printf(dev, "No valid alternate " - "setting found!\n"); + "setting found\n"); goto detach; } diff --git a/sys/dev/usb/net/if_cue.c b/sys/dev/usb/net/if_cue.c index dcbef616dfc..6e257d84715 100644 --- a/sys/dev/usb/net/if_cue.c +++ b/sys/dev/usb/net/if_cue.c @@ -404,7 +404,7 @@ cue_attach(device_t dev) error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, cue_config, CUE_N_TRANSFER, sc, &sc->sc_mtx); if (error) { - device_printf(dev, "allocating USB transfers failed!\n"); + device_printf(dev, "allocating USB transfers failed\n"); goto detach; } diff --git a/sys/dev/usb/net/if_kue.c b/sys/dev/usb/net/if_kue.c index 281d54f919a..673c8219acb 100644 --- a/sys/dev/usb/net/if_kue.c +++ b/sys/dev/usb/net/if_kue.c @@ -480,14 +480,14 @@ kue_attach(device_t dev) error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, kue_config, KUE_N_TRANSFER, sc, &sc->sc_mtx); if (error) { - device_printf(dev, "allocating USB transfers failed!\n"); + device_printf(dev, "allocating USB transfers failed\n"); goto detach; } sc->sc_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, M_USBDEV, M_WAITOK); if (sc->sc_mcfilters == NULL) { - device_printf(dev, "failed allocating USB memory!\n"); + device_printf(dev, "failed allocating USB memory\n"); goto detach; } diff --git a/sys/dev/usb/net/if_rue.c b/sys/dev/usb/net/if_rue.c index 7b92bc553e3..3e77305aa97 100644 --- a/sys/dev/usb/net/if_rue.c +++ b/sys/dev/usb/net/if_rue.c @@ -535,7 +535,7 @@ rue_reset(struct rue_softc *sc) break; } if (i == RUE_TIMEOUT) - device_printf(sc->sc_ue.ue_dev, "reset never completed!\n"); + device_printf(sc->sc_ue.ue_dev, "reset never completed\n"); uether_pause(&sc->sc_ue, hz / 100); } @@ -591,7 +591,7 @@ rue_attach(device_t dev) sc->sc_xfer, rue_config, RUE_N_TRANSFER, sc, &sc->sc_mtx); if (error) { - device_printf(dev, "allocating USB transfers failed!\n"); + device_printf(dev, "allocating USB transfers failed\n"); goto detach; } diff --git a/sys/dev/usb/net/if_udav.c b/sys/dev/usb/net/if_udav.c index 20853e0d8bf..ae30b142da6 100644 --- a/sys/dev/usb/net/if_udav.c +++ b/sys/dev/usb/net/if_udav.c @@ -254,7 +254,7 @@ udav_attach(device_t dev) error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, udav_config, UDAV_N_TRANSFER, sc, &sc->sc_mtx); if (error) { - device_printf(dev, "allocating USB transfers failed!\n"); + device_printf(dev, "allocating USB transfers failed\n"); goto detach; } diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 92eaf1336bd..4930d641144 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -249,8 +249,6 @@ u3g_sierra_init(struct usb_device *udev) { struct usb_device_request req; - DPRINTFN(0, "\n"); - req.bmRequestType = UT_VENDOR; req.bRequest = UR_SET_INTERFACE; USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP); @@ -269,8 +267,6 @@ u3g_huawei_init(struct usb_device *udev) { struct usb_device_request req; - DPRINTFN(0, "\n"); - req.bmRequestType = UT_WRITE_DEVICE; req.bRequest = UR_SET_FEATURE; USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP); diff --git a/sys/dev/usb/serial/uark.c b/sys/dev/usb/serial/uark.c index 492f68bd37c..7dfb0f83f6e 100644 --- a/sys/dev/usb/serial/uark.c +++ b/sys/dev/usb/serial/uark.c @@ -211,7 +211,7 @@ uark_attach(device_t dev) if (error) { device_printf(dev, "allocating control USB " - "transfers failed!\n"); + "transfers failed\n"); goto detach; } /* clear stall at first run */ diff --git a/sys/dev/usb/serial/ubser.c b/sys/dev/usb/serial/ubser.c index f95f464ad8c..06c96c026e5 100644 --- a/sys/dev/usb/serial/ubser.c +++ b/sys/dev/usb/serial/ubser.c @@ -282,7 +282,7 @@ ubser_attach(device_t dev) sc->sc_tx_size = usbd_xfer_max_len(sc->sc_xfer[UBSER_BULK_DT_WR]); if (sc->sc_tx_size == 0) { - DPRINTFN(0, "invalid tx_size!\n"); + DPRINTFN(0, "invalid tx_size\n"); goto detach; } /* initialize port numbers */ diff --git a/sys/dev/usb/serial/ucycom.c b/sys/dev/usb/serial/ucycom.c index 0c1619df64b..1cce28eb580 100644 --- a/sys/dev/usb/serial/ucycom.c +++ b/sys/dev/usb/serial/ucycom.c @@ -266,7 +266,7 @@ ucycom_attach(device_t dev) sc, &sc->sc_mtx); if (error) { device_printf(dev, "allocating USB " - "transfers failed!\n"); + "transfers failed\n"); goto detach; } error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc, @@ -555,7 +555,7 @@ ucycom_intr_read_callback(struct usb_xfer *xfer, usb_error_t error) break; default: - DPRINTFN(0, "unsupported model number!\n"); + DPRINTFN(0, "unsupported model number\n"); goto tr_setup; } diff --git a/sys/dev/usb/serial/ufoma.c b/sys/dev/usb/serial/ufoma.c index 3d015fd7de2..b1a73494945 100644 --- a/sys/dev/usb/serial/ufoma.c +++ b/sys/dev/usb/serial/ufoma.c @@ -401,7 +401,7 @@ ufoma_attach(device_t dev) if (error) { device_printf(dev, "allocating control USB " - "transfers failed!\n"); + "transfers failed\n"); goto detach; } mad = ufoma_get_intconf(cd, id, UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM); @@ -1060,7 +1060,7 @@ ufoma_modem_setup(device_t dev, struct ufoma_softc *sc, break; } } else { - device_printf(dev, "no data interface!\n"); + device_printf(dev, "no data interface\n"); return (EINVAL); } } @@ -1071,7 +1071,7 @@ ufoma_modem_setup(device_t dev, struct ufoma_softc *sc, if (error) { device_printf(dev, "allocating BULK USB " - "transfers failed!\n"); + "transfers failed\n"); return (EINVAL); } return (0); diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c index c7442b64270..ae0c939ec38 100644 --- a/sys/dev/usb/serial/uftdi.c +++ b/sys/dev/usb/serial/uftdi.c @@ -307,7 +307,7 @@ uftdi_attach(device_t dev) if (error) { device_printf(dev, "allocating USB " - "transfers failed!\n"); + "transfers failed\n"); goto detach; } sc->sc_ucom.sc_portno = FTDI_PIT_SIOA + uaa->info.bIfaceNum; diff --git a/sys/dev/usb/serial/ugensa.c b/sys/dev/usb/serial/ugensa.c index dd6b6f1037a..99656dde46f 100644 --- a/sys/dev/usb/serial/ugensa.c +++ b/sys/dev/usb/serial/ugensa.c @@ -210,7 +210,7 @@ ugensa_attach(device_t dev) } if (cnt == 0) { - device_printf(dev, "No interfaces!\n"); + device_printf(dev, "No interfaces\n"); goto detach; } for (x = 0; x < cnt; x++) { @@ -229,7 +229,7 @@ ugensa_attach(device_t dev) if (error) { device_printf(dev, "allocating USB " - "transfers failed!\n"); + "transfers failed\n"); goto detach; } /* clear stall at first run */ diff --git a/sys/dev/usb/serial/umct.c b/sys/dev/usb/serial/umct.c index 7331a0bf85c..524f8c4f4c0 100644 --- a/sys/dev/usb/serial/umct.c +++ b/sys/dev/usb/serial/umct.c @@ -263,7 +263,7 @@ umct_attach(device_t dev) if (error) { device_printf(dev, "allocating USB " - "transfers failed!\n"); + "transfers failed\n"); goto detach; } diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c index 9b8da420eb2..6a6d3951a2b 100644 --- a/sys/dev/usb/serial/umodem.c +++ b/sys/dev/usb/serial/umodem.c @@ -311,7 +311,7 @@ umodem_attach(device_t dev) 0 - 1, UDESCSUB_CDC_UNION, 0 - 1); if ((cud == NULL) || (cud->bLength < sizeof(*cud))) { - device_printf(dev, "no CM or union descriptor!\n"); + device_printf(dev, "no CM or union descriptor\n"); goto detach; } @@ -344,7 +344,7 @@ umodem_attach(device_t dev) break; } } else { - device_printf(dev, "no data interface!\n"); + device_printf(dev, "no data interface\n"); goto detach; } } diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c index af6bdbafd07..ef5db403358 100644 --- a/sys/dev/usb/serial/uplcom.c +++ b/sys/dev/usb/serial/uplcom.c @@ -377,7 +377,7 @@ uplcom_attach(device_t dev) if (iface) { id = usbd_get_interface_descriptor(iface); if (id == NULL) { - device_printf(dev, "no interface descriptor (2)!\n"); + device_printf(dev, "no interface descriptor (2)\n"); goto detach; } sc->sc_data_iface_no = id->bInterfaceNumber; @@ -420,7 +420,7 @@ uplcom_attach(device_t dev) */ if (sc->sc_chiptype == TYPE_PL2303X) { if (uplcom_pl2303x_init(uaa->device)) { - device_printf(dev, "init failed!\n"); + device_printf(dev, "init failed\n"); goto detach; } } diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index f2430dc17e7..36ed09cc1bb 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -2847,7 +2847,7 @@ umass_cam_detach_sim(struct umass_softc *sc) sc->sc_sim->softc = UMASS_GONE; cam_sim_free(sc->sc_sim, /* free_devq */ TRUE); } else { - panic("%s: CAM layer is busy!\n", + panic("%s: CAM layer is busy\n", sc->sc_name); } sc->sc_sim = NULL; diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c index d9e0dc16751..d3271b24f74 100644 --- a/sys/dev/usb/template/usb_template.c +++ b/sys/dev/usb/template/usb_template.c @@ -727,7 +727,7 @@ handle_endpoint_desc: if ((pf->max_in_frame_size < wMaxPacketSize) || (pf->max_out_frame_size < wMaxPacketSize)) { DPRINTFN(0, "Endpoint profile %u " - "has too small buffer!\n", ep_no); + "has too small buffer\n", ep_no); return (1); } } else if (ed->bEndpointAddress & UE_DIR_IN) { @@ -735,7 +735,7 @@ handle_endpoint_desc: (1 << (ep_no % 8)); if (pf->max_in_frame_size < wMaxPacketSize) { DPRINTFN(0, "Endpoint profile %u " - "has too small buffer!\n", ep_no); + "has too small buffer\n", ep_no); return (1); } } else { @@ -743,7 +743,7 @@ handle_endpoint_desc: (1 << (ep_no % 8)); if (pf->max_out_frame_size < wMaxPacketSize) { DPRINTFN(0, "Endpoint profile %u " - "has too small buffer!\n", ep_no); + "has too small buffer\n", ep_no); return (1); } } diff --git a/sys/dev/usb/usb_busdma.c b/sys/dev/usb/usb_busdma.c index 177b94faceb..45482e25da7 100644 --- a/sys/dev/usb/usb_busdma.c +++ b/sys/dev/usb/usb_busdma.c @@ -445,7 +445,7 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs, /* * This check verifies that the physical address is correct: */ - DPRINTFN(0, "Page offset was not preserved!\n"); + DPRINTFN(0, "Page offset was not preserved\n"); error = 1; goto done; } @@ -764,8 +764,8 @@ usb_dma_tag_find(struct usb_dma_parent_tag *udpt, struct usb_dma_tag *udt; uint8_t nudt; - USB_ASSERT(align > 0, ("Invalid parameter align = 0!\n")); - USB_ASSERT(size > 0, ("Invalid parameter size = 0!\n")); + USB_ASSERT(align > 0, ("Invalid parameter align = 0\n")); + USB_ASSERT(size > 0, ("Invalid parameter size = 0\n")); udt = udpt->utag_first; nudt = udpt->utag_max; diff --git a/sys/dev/usb/usb_debug.h b/sys/dev/usb/usb_debug.h index dfe2edf55df..b6bfbcfca1a 100644 --- a/sys/dev/usb/usb_debug.h +++ b/sys/dev/usb/usb_debug.h @@ -35,11 +35,11 @@ extern int usb_debug; /* Check if USB debugging is enabled. */ #ifdef USB_DEBUG_VAR #if (USB_DEBUG != 0) -#define DPRINTFN(n,fmt,...) do { \ - if ((USB_DEBUG_VAR) >= (n)) { \ - printf("%s:%u: " fmt, \ - __FUNCTION__, __LINE__,## __VA_ARGS__); \ - } \ +#define DPRINTFN(n,fmt,...) do { \ + if ((USB_DEBUG_VAR) >= (n)) { \ + printf("%s: " fmt, \ + __FUNCTION__,## __VA_ARGS__); \ + } \ } while (0) #define DPRINTF(...) DPRINTFN(1, __VA_ARGS__) #else diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c index 63615332dea..dffabad29b9 100644 --- a/sys/dev/usb/usb_dev.c +++ b/sys/dev/usb/usb_dev.c @@ -575,7 +575,7 @@ usb_fifo_free(struct usb_fifo *f) (f->udev->fifo[f->fifo_index] == f)) { f->udev->fifo[f->fifo_index] = NULL; } else { - DPRINTFN(0, "USB FIFO %p has not been linked!\n", f); + DPRINTFN(0, "USB FIFO %p has not been linked\n", f); } /* decrease refcount */ @@ -952,7 +952,7 @@ usb_dev_init_post(void *arg) usb_dev = make_dev(&usb_static_devsw, 0, UID_ROOT, GID_OPERATOR, 0644, USB_DEVICE_NAME); if (usb_dev == NULL) { - DPRINTFN(0, "Could not create usb bus device!\n"); + DPRINTFN(0, "Could not create usb bus device\n"); } } diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index ae71f7da598..6787fa6ead1 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -1023,7 +1023,7 @@ usb_detach_device_sub(struct usb_device *udev, device_t *ppdev, if (udev->flags.peer_suspended) { err = DEVICE_RESUME(dev); if (err) { - device_printf(dev, "Resume failed!\n"); + device_printf(dev, "Resume failed\n"); } } if (device_detach(dev)) { @@ -1038,7 +1038,7 @@ usb_detach_device_sub(struct usb_device *udev, device_t *ppdev, error: /* Detach is not allowed to fail in the USB world */ - panic("An USB driver would not detach!\n"); + panic("A USB driver would not detach\n"); } /*------------------------------------------------------------------------* @@ -1131,7 +1131,7 @@ usb_probe_and_attach_sub(struct usb_device *udev, * to device_detach(). USB devices should * never fail on detach! */ - panic("device_delete_child() failed!\n"); + panic("device_delete_child() failed\n"); } } if (uaa->temp_dev == NULL) { @@ -1140,7 +1140,7 @@ usb_probe_and_attach_sub(struct usb_device *udev, uaa->temp_dev = device_add_child(udev->parent_dev, NULL, -1); if (uaa->temp_dev == NULL) { device_printf(udev->parent_dev, - "Device creation failed!\n"); + "Device creation failed\n"); return (1); /* failure */ } device_set_ivars(uaa->temp_dev, uaa); @@ -1320,7 +1320,7 @@ usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index) /* remove the last created child; it is unused */ if (device_delete_child(udev->parent_dev, uaa.temp_dev)) { - DPRINTFN(0, "device delete child failed!\n"); + DPRINTFN(0, "device delete child failed\n"); } } done: @@ -1353,7 +1353,7 @@ usb_suspend_resume_sub(struct usb_device *udev, device_t dev, uint8_t do_suspend err = DEVICE_RESUME(dev); } if (err) { - device_printf(dev, "%s failed!\n", + device_printf(dev, "%s failed\n", do_suspend ? "Suspend" : "Resume"); } } @@ -1473,13 +1473,13 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus, if (device_index == bus->devices_max) { device_printf(bus->bdev, - "No free USB device index for new device!\n"); + "No free USB device index for new device\n"); return (NULL); } if (depth > 0x10) { device_printf(bus->bdev, - "Invalid device depth!\n"); + "Invalid device depth\n"); return (NULL); } udev = malloc(sizeof(*udev), M_USB, M_WAITOK | M_ZERO); @@ -1631,7 +1631,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus, USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0); if (err) { DPRINTFN(0, "getting device descriptor " - "at addr %d failed, %s!\n", udev->address, + "at addr %d failed, %s\n", udev->address, usbd_errstr(err)); /* XXX try to re-enumerate the device */ err = usbd_req_re_enumerate(udev, NULL); @@ -1797,7 +1797,7 @@ repeat_set_config: (usbd_get_no_descriptors(udev->cdesc, UDESC_ENDPOINT) == 0)) { DPRINTFN(0, "Found no endpoints " - "(trying next config)!\n"); + "(trying next config)\n"); config_index++; goto repeat_set_config; } @@ -1814,7 +1814,7 @@ repeat_set_config: } } } else if (usb_test_huawei_autoinst_p(udev, &uaa) == 0) { - DPRINTFN(0, "Found Huawei auto-install disk!\n"); + DPRINTFN(0, "Found Huawei auto-install disk\n"); /* leave device unconfigured */ usb_unconfigure(udev, 0); } diff --git a/sys/dev/usb/usb_hid.c b/sys/dev/usb/usb_hid.c index b9d61c91c39..f13bbf1b1b4 100644 --- a/sys/dev/usb/usb_hid.c +++ b/sys/dev/usb/usb_hid.c @@ -450,7 +450,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) c = &s->cur[s->pushlevel]; } else { DPRINTFN(0, "Cannot push " - "item @ %d!\n", s->pushlevel); + "item @ %d\n", s->pushlevel); } break; case 11: /* Pop */ @@ -468,7 +468,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) c->loc.count = 0; } else { DPRINTFN(0, "Cannot pop " - "item @ %d!\n", s->pushlevel); + "item @ %d\n", s->pushlevel); } break; default: @@ -490,7 +490,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) s->usages_max[s->nusage] = dval; s->nusage ++; } else { - DPRINTFN(0, "max usage reached!\n"); + DPRINTFN(0, "max usage reached\n"); } /* clear any pending usage sets */ @@ -525,7 +525,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) c->usage_maximum; s->nusage ++; } else { - DPRINTFN(0, "Usage set dropped!\n"); + DPRINTFN(0, "Usage set dropped\n"); } s->susage = 0; break; diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index a116ab4861f..97797963269 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -385,7 +385,7 @@ repeat: (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))) { if (timeout) { DPRINTFN(0, "giving up port reset " - "- device vanished!\n"); + "- device vanished\n"); goto error; } timeout = 1; @@ -435,7 +435,7 @@ repeat: child = usb_alloc_device(sc->sc_dev, udev->bus, udev, udev->depth + 1, portno - 1, portno, speed, mode); if (child == NULL) { - DPRINTFN(0, "could not allocate new device!\n"); + DPRINTFN(0, "could not allocate new device\n"); goto error; } return (0); /* success */ @@ -711,14 +711,14 @@ uhub_attach(device_t dev) parent_hub->flags.self_powered : 0); if (udev->depth > USB_HUB_MAX_DEPTH) { - DPRINTFN(0, "hub depth, %d, exceeded. HUB ignored!\n", + DPRINTFN(0, "hub depth, %d, exceeded. HUB ignored\n", USB_HUB_MAX_DEPTH); goto error; } if (!udev->flags.self_powered && parent_hub && (!parent_hub->flags.self_powered)) { DPRINTFN(0, "bus powered HUB connected to " - "bus powered HUB. HUB ignored!\n"); + "bus powered HUB. HUB ignored\n"); goto error; } /* get HUB descriptor */ @@ -740,11 +740,11 @@ uhub_attach(device_t dev) goto error; } if (hubdesc.bNbrPorts != nports) { - DPRINTFN(0, "number of ports changed!\n"); + DPRINTFN(0, "number of ports changed\n"); goto error; } if (nports == 0) { - DPRINTFN(0, "portless HUB!\n"); + DPRINTFN(0, "portless HUB\n"); goto error; } hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports), @@ -784,7 +784,7 @@ uhub_attach(device_t dev) } if (err) { DPRINTFN(0, "cannot setup interrupt transfer, " - "errstr=%s!\n", usbd_errstr(err)); + "errstr=%s\n", usbd_errstr(err)); goto error; } /* wait with power off for a while */ @@ -1924,7 +1924,7 @@ usb_dev_resume_peer(struct usb_device *udev) err = usbd_req_clear_port_feature(udev->parent_hub, NULL, udev->port_no, UHF_PORT_SUSPEND); if (err) { - DPRINTFN(0, "Resuming port failed!\n"); + DPRINTFN(0, "Resuming port failed\n"); return; } /* resume settle time */ @@ -1972,7 +1972,7 @@ usb_dev_resume_peer(struct usb_device *udev) NULL, UF_DEVICE_REMOTE_WAKEUP); if (err) { DPRINTFN(0, "Clearing device " - "remote wakeup failed: %s!\n", + "remote wakeup failed: %s\n", usbd_errstr(err)); } } @@ -2042,7 +2042,7 @@ repeat: NULL, UF_DEVICE_REMOTE_WAKEUP); if (err) { DPRINTFN(0, "Setting device " - "remote wakeup failed!\n"); + "remote wakeup failed\n"); } } USB_BUS_LOCK(udev->bus); diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c index 4af0766eb18..61df5f1925d 100644 --- a/sys/dev/usb/usb_msctest.c +++ b/sys/dev/usb/usb_msctest.c @@ -284,7 +284,7 @@ bbb_command_callback(struct usb_xfer *xfer, usb_error_t error) sc->cbw.bCDBLength = sc->cmd_len; if (sc->cbw.bCDBLength > sizeof(sc->cbw.CBWCDB)) { sc->cbw.bCDBLength = sizeof(sc->cbw.CBWCDB); - DPRINTFN(0, "Truncating long command!\n"); + DPRINTFN(0, "Truncating long command\n"); } usbd_xfer_set_frame_data(xfer, 0, &sc->cbw, sizeof(sc->cbw)); usbd_transfer_submit(xfer); diff --git a/sys/dev/usb/usb_process.c b/sys/dev/usb/usb_process.c index 5b4b749ff34..53461d21502 100644 --- a/sys/dev/usb/usb_process.c +++ b/sys/dev/usb/usb_process.c @@ -444,7 +444,7 @@ usb_proc_drain(struct usb_process *up) if (cold) { USB_THREAD_SUSPEND(up->up_ptr); printf("WARNING: A USB process has " - "been left suspended!\n"); + "been left suspended\n"); break; } cv_wait(&up->up_cv, up->up_mtx); diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c index 8ccaa14f7a5..03745faa7a5 100644 --- a/sys/dev/usb/usb_request.c +++ b/sys/dev/usb/usb_request.c @@ -1549,7 +1549,7 @@ retry: USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0); if (err) { DPRINTFN(0, "getting device descriptor " - "at addr %d failed, %s!\n", udev->address, + "at addr %d failed, %s\n", udev->address, usbd_errstr(err)); goto done; } @@ -1557,7 +1557,7 @@ retry: err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); if (err) { DPRINTFN(0, "addr=%d, getting device " - "descriptor failed, %s!\n", old_addr, + "descriptor failed, %s\n", old_addr, usbd_errstr(err)); goto done; } diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index c434703ad01..e7cb202aef5 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -201,9 +201,9 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm, usb_size_t r; usb_size_t z; - USB_ASSERT(align > 1, ("Invalid alignment, 0x%08x!\n", + USB_ASSERT(align > 1, ("Invalid alignment, 0x%08x\n", align)); - USB_ASSERT(size > 0, ("Invalid size = 0!\n")); + USB_ASSERT(size > 0, ("Invalid size = 0\n")); if (count == 0) { return (0); /* nothing to allocate */ @@ -1200,7 +1200,7 @@ usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup) USB_BUS_LOCK(info->bus); USB_ASSERT(info->setup_refcount != 0, ("Invalid setup " - "reference count!\n")); + "reference count\n")); info->setup_refcount--; @@ -1353,7 +1353,7 @@ usbd_setup_ctrl_transfer(struct usb_xfer *xfer) if (len > xfer->flags_int.control_rem) { DPRINTFN(0, "Length (%d) greater than " - "remaining length (%d)!\n", len, + "remaining length (%d)\n", len, xfer->flags_int.control_rem); goto error; } @@ -1366,7 +1366,7 @@ usbd_setup_ctrl_transfer(struct usb_xfer *xfer) (len != xfer->flags_int.control_rem) && (xfer->nframes != 1)) { DPRINTFN(0, "Short control transfer without " - "force_short_xfer set!\n"); + "force_short_xfer set\n"); goto error; } xfer->flags_int.control_rem -= len; @@ -1927,7 +1927,7 @@ usbd_xfer_set_frame_offset(struct usb_xfer *xfer, usb_frlength_t offset, usb_frcount_t frindex) { KASSERT(!xfer->flags.ext_buffer, ("Cannot offset data frame " - "when the USB buffer is external!\n")); + "when the USB buffer is external\n")); KASSERT(frindex < xfer->max_frame_count, ("frame index overflow")); /* set virtual address to load */ @@ -2437,7 +2437,7 @@ usbd_pipe_start(struct usb_xfer_queue *pq) &udev->cs_msg[0], &udev->cs_msg[1]); } else { /* should not happen */ - DPRINTFN(0, "No stall handler!\n"); + DPRINTFN(0, "No stall handler\n"); } /* * Check if we should stall. Some USB hardware @@ -2580,7 +2580,7 @@ usbd_callback_wrapper_sub(struct usb_xfer *xfer) if (xfer->aframes > xfer->nframes) { if (xfer->error == 0) { panic("%s: actual number of frames, %d, is " - "greater than initial number of frames, %d!\n", + "greater than initial number of frames, %d\n", __FUNCTION__, xfer->aframes, xfer->nframes); } else { /* just set some valid value */ @@ -2607,7 +2607,7 @@ usbd_callback_wrapper_sub(struct usb_xfer *xfer) if (xfer->actlen > xfer->sumlen) { if (xfer->error == 0) { panic("%s: actual length, %d, is greater than " - "initial length, %d!\n", + "initial length, %d\n", __FUNCTION__, xfer->actlen, xfer->sumlen); } else { /* just set some valid value */ @@ -2809,7 +2809,7 @@ repeat: udev->default_xfer, usb_control_ep_cfg, USB_DEFAULT_XFER_MAX, NULL, udev->default_mtx)) { DPRINTFN(0, "could not setup default " - "USB transfer!\n"); + "USB transfer\n"); } else { goto repeat; } diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index 67e6980701b..20f06c6ddea 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -292,7 +292,7 @@ upgt_attach(device_t dev) /* Calculate device memory space. */ if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) { device_printf(dev, - "could not find memory space addresses on FW!\n"); + "could not find memory space addresses on FW\n"); error = EIO; goto fail5; } @@ -732,7 +732,7 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state) break; default: device_printf(sc->sc_dev, - "MAC filter does not know that state!\n"); + "MAC filter does not know that state\n"); break; } @@ -1181,7 +1181,7 @@ upgt_eeprom_parse(struct upgt_softc *sc) break; case UPGT_EEPROM_TYPE_OFF: DPRINTF(sc, UPGT_DEBUG_FW, - "%s: EEPROM off without end option!\n", __func__); + "%s: EEPROM off without end option\n", __func__); return (EIO); default: DPRINTF(sc, UPGT_DEBUG_FW, @@ -1356,7 +1356,7 @@ upgt_eeprom_read(struct upgt_softc *sc) error = mtx_sleep(sc, &sc->sc_mtx, 0, "eeprom_request", hz); if (error != 0) { device_printf(sc->sc_dev, - "timeout while waiting for EEPROM data!\n"); + "timeout while waiting for EEPROM data\n"); UPGT_UNLOCK(sc); return (EIO); } @@ -1490,7 +1490,7 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi) ("A current mbuf storage is small (%d)", pkglen + ETHER_ALIGN)); m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); if (m == NULL) { - device_printf(sc->sc_dev, "could not create RX mbuf!\n"); + device_printf(sc->sc_dev, "could not create RX mbuf\n"); return (NULL); } m_adj(m, ETHER_ALIGN); @@ -1587,7 +1587,7 @@ upgt_mem_free(struct upgt_softc *sc, uint32_t addr) } device_printf(sc->sc_dev, - "could not free memory address 0x%08x!\n", addr); + "could not free memory address 0x%08x\n", addr); } static int @@ -1602,7 +1602,7 @@ upgt_fw_load(struct upgt_softc *sc) fw = firmware_get(upgt_fwname); if (fw == NULL) { - device_printf(sc->sc_dev, "could not read microcode %s!\n", + device_printf(sc->sc_dev, "could not read microcode %s\n", upgt_fwname); return (EIO); } @@ -1676,7 +1676,7 @@ upgt_fw_load(struct upgt_softc *sc) usbd_transfer_start(sc->sc_xfer[UPGT_BULK_RX]); error = mtx_sleep(sc, &sc->sc_mtx, 0, "upgtfw", 2 * hz); if (error != 0) { - device_printf(sc->sc_dev, "firmware load failed!\n"); + device_printf(sc->sc_dev, "firmware load failed\n"); error = EIO; } @@ -1782,7 +1782,7 @@ upgt_fw_verify(struct upgt_softc *sc) fw = firmware_get(upgt_fwname); if (fw == NULL) { - device_printf(sc->sc_dev, "could not read microcode %s!\n", + device_printf(sc->sc_dev, "could not read microcode %s\n", upgt_fwname); return EIO; } @@ -1802,7 +1802,7 @@ upgt_fw_verify(struct upgt_softc *sc) } if (offset == fw->datasize) { device_printf(sc->sc_dev, - "firmware Boot Record Area not found!\n"); + "firmware Boot Record Area not found\n"); error = EIO; goto fail; } @@ -1827,7 +1827,7 @@ upgt_fw_verify(struct upgt_softc *sc) if (bra_option_len != UPGT_BRA_FWTYPE_SIZE) { device_printf(sc->sc_dev, - "wrong UPGT_BRA_TYPE_FW len!\n"); + "wrong UPGT_BRA_TYPE_FW len\n"); error = EIO; goto fail; } @@ -1842,7 +1842,7 @@ upgt_fw_verify(struct upgt_softc *sc) break; } device_printf(sc->sc_dev, - "unsupported firmware type!\n"); + "unsupported firmware type\n"); error = EIO; goto fail; case UPGT_BRA_TYPE_VERSION: @@ -1946,7 +1946,7 @@ upgt_alloc_tx(struct upgt_softc *sc) data->buf = malloc(MCLBYTES, M_USBDEV, M_NOWAIT | M_ZERO); if (data->buf == NULL) { device_printf(sc->sc_dev, - "could not allocate TX buffer!\n"); + "could not allocate TX buffer\n"); return (ENOMEM); } STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); @@ -1970,7 +1970,7 @@ upgt_alloc_rx(struct upgt_softc *sc) data->buf = malloc(MCLBYTES, M_USBDEV, M_NOWAIT | M_ZERO); if (data->buf == NULL) { device_printf(sc->sc_dev, - "could not allocate RX buffer!\n"); + "could not allocate RX buffer\n"); return (ENOMEM); } STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); From 40e55da3d121565a92efa09b7dc3ec66cdc98fd0 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 23:10:32 +0000 Subject: [PATCH 0813/2592] MFC r196487 Remove redundant Giant reference. Giant will be dropped automatically when the mutex argument is NULL. --- sys/dev/sound/usb/uaudio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index fe63e0d38b5..f5d47406391 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -2958,7 +2958,7 @@ uaudio_mixer_get(struct usb_device *udev, uint8_t what, USETW(req.wIndex, mc->wIndex); USETW(req.wLength, len); - err = usbd_do_request(udev, &Giant, &req, data); + err = usbd_do_request(udev, NULL, &req, data); if (err) { DPRINTF("err=%s\n", usbd_errstr(err)); return (0); @@ -3081,7 +3081,7 @@ uaudio_set_speed(struct usb_device *udev, uint8_t endpt, uint32_t speed) data[1] = speed >> 8; data[2] = speed >> 16; - return (usbd_do_request(udev, &Giant, &req, data)); + return (usbd_do_request(udev, NULL, &req, data)); } static int From 9d294893a4d31ae0630bc30395c9fe808879b953 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 23:11:27 +0000 Subject: [PATCH 0814/2592] MFC r199060 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 e4f658cee0d7db8d64eeadeb70e1c8a1b9a78517 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 23:12:14 +0000 Subject: [PATCH 0815/2592] MFC r199576 remove volume alignment (was previously not correctly implemented) --- sys/dev/sound/usb/uaudio.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 2ac8766e828..7701c3ce675 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -118,7 +118,6 @@ struct uaudio_mixer_node { int32_t maxval; #define MIX_MAX_CHAN 8 int32_t wValue[MIX_MAX_CHAN]; /* using nchan */ - uint32_t mod; /* modulus */ uint32_t mul; uint32_t ctl; @@ -1318,6 +1317,11 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b, ch->pcm_cap.minspeed = ch->sample_rate; ch->pcm_cap.maxspeed = ch->sample_rate; + /* setup mutex and PCM channel */ + + ch->pcm_ch = c; + ch->pcm_mtx = c->lock; + if (ch->p_asf1d->bNrChannels >= 2) ch->pcm_cap.fmtlist[0] = SND_FORMAT(ch->p_fmt->freebsd_fmt, 2, 0); @@ -1391,8 +1395,6 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b, 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) { @@ -1570,9 +1572,7 @@ uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct uaudio_mixer_node *mc) 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 */ @@ -1600,11 +1600,8 @@ uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct uaudio_mixer_node *mc) /* compute value alignment */ res = uaudio_mixer_get(sc->sc_udev, GET_RES, mc); - if (res == 0) - res = 1; - mc->mod = mc->mul / res; - if (mc->mod == 0) - mc->mod = 1; + + DPRINTF("Resolution = %d\n", (int)res); } uaudio_mixer_add_ctl_sub(sc, mc); @@ -3097,9 +3094,6 @@ uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, int32_t val) /* compute actual volume */ val = (val * mc->mul) / 255; - /* align volume level */ - val = val - (val % mc->mod); - /* add lower offset */ val = val + mc->minval; From c9e072d09001b3fd16588a8941f6343ee1163e9f Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 23:12:52 +0000 Subject: [PATCH 0816/2592] MFC r199677 add support for MIDI devices without audio control stream. Submitted by: Hans Petter Selasky --- sys/dev/sound/usb/uaudio.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 7701c3ce675..ddae8c380c4 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -559,6 +559,13 @@ uaudio_probe(device_t dev) else return (0); } + + /* check for MIDI stream */ + + if ((uaa->info.bInterfaceClass == UICLASS_AUDIO) && + (uaa->info.bInterfaceSubClass == UISUBCLASS_MIDISTREAM)) { + return (0); + } return (ENXIO); } From a785df36d1fefe0de6975f4c14af383138bd2e14 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 9 Dec 2009 23:14:53 +0000 Subject: [PATCH 0817/2592] MFC r198833 Add more verbose output when dumping the configuration descriptor. --- 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 d87439e7b65d0bfad1b6f4e32947e5cd7aaec62b Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 10 Dec 2009 05:45:40 +0000 Subject: [PATCH 0818/2592] MFC rev 200230: Add support for the NetMos NM9865 family of Serial/Parallel ports. --- sys/dev/puc/pucdata.c | 42 ++++++++++++++++++++++++++++++++++--- sys/dev/uart/uart_bus_pci.c | 1 + 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c index 36183b75b52..b74574d2c3c 100644 --- a/sys/dev/puc/pucdata.c +++ b/sys/dev/puc/pucdata.c @@ -168,10 +168,10 @@ const struct puc_cfg puc_pci_devices[] = { { 0x10e8, 0x818e, 0xffff, 0, "Applied Micro Circuits 8 Port UART", - DEFAULT_RCLK, - PUC_PORT_8S, 0x14, -1, -1, + DEFAULT_RCLK, + PUC_PORT_8S, 0x14, -1, -1, .config_function = puc_config_amc - }, + }, { 0x11fe, 0x8010, 0xffff, 0, "Comtrol RocketPort 550/8 RJ11 part A", @@ -808,6 +808,42 @@ const struct puc_cfg puc_pci_devices[] = { PUC_PORT_4S1P, 0x10, 4, 0, }, + { 0x9710, 0x9865, 0xa000, 0x3002, + "NetMos NM9865 Dual UART", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x9710, 0x9865, 0xa000, 0x3003, + "NetMos NM9865 Triple UART", + DEFAULT_RCLK, + PUC_PORT_3S, 0x10, 4, 0, + }, + + { 0x9710, 0x9865, 0xa000, 0x3004, + "NetMos NM9865 Quad UART", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 4, 0,0 + }, + + { 0x9710, 0x9865, 0xa000, 0x3011, + "NetMos NM9865 Single UART and 1284 Printer port", + DEFAULT_RCLK, + PUC_PORT_1S1P, 0x10, 4, 0, + }, + + { 0x9710, 0x9865, 0xa000, 0x3012, + "NetMos NM9865 Dual UART and 1284 Printer port", + DEFAULT_RCLK, + PUC_PORT_2S1P, 0x10, 4, 0, + }, + + { 0x9710, 0x9865, 0xa000, 0x3020, + "NetMos NM9865 Dual 1284 Printer port", + DEFAULT_RCLK, + PUC_PORT_2P, 0x10, 4, 0, + }, + { 0xb00c, 0x021c, 0xffff, 0, "IC Book Labs Gunboat x4 Lite", DEFAULT_RCLK, diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c index 7a01e77a06a..06c6138b4af 100644 --- a/sys/dev/uart/uart_bus_pci.c +++ b/sys/dev/uart/uart_bus_pci.c @@ -111,6 +111,7 @@ static struct pci_id pci_ns8250_ids[] = { 0x10, 16384000 }, { 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 }, { 0x9710, 0x9835, 0x1000, 1, "NetMos NM9835 Serial Port", 0x10 }, +{ 0x9710, 0x9865, 0xa000, 0x1000, "NetMos NM9865 Serial Port", 0x10 }, { 0xdeaf, 0x9051, 0xffff, 0, "Middle Digital PC Weasel Serial Port", 0x10 }, { 0xffff, 0, 0xffff, 0, NULL, 0, 0} }; From 08f0b3c52ff77f65d703fa206354af4beb87aea4 Mon Sep 17 00:00:00 2001 From: Shteryana Shopova Date: Thu, 10 Dec 2009 11:52:16 +0000 Subject: [PATCH 0819/2592] MFC r200063 Fix a problem with high CPU consumption (up to 30%) by bsnmpd on a loaded system. Instead of constantly calling the mibII_idle function when the server is not busy call the function only once every 10 seconds to avoid bsnmpd constantly doing gettimeofday syscalls. Make the idle polling interval confugurable via begemotIfDataPoll. --- contrib/bsnmp/snmp_mibII/BEGEMOT-MIB2-MIB.txt | 18 +++++++++- contrib/bsnmp/snmp_mibII/mibII.c | 36 +++++++++++++++++-- contrib/bsnmp/snmp_mibII/mibII.h | 8 +++++ contrib/bsnmp/snmp_mibII/mibII_begemot.c | 17 +++++++++ contrib/bsnmp/snmp_mibII/mibII_tree.def | 1 + 5 files changed, 77 insertions(+), 3 deletions(-) diff --git a/contrib/bsnmp/snmp_mibII/BEGEMOT-MIB2-MIB.txt b/contrib/bsnmp/snmp_mibII/BEGEMOT-MIB2-MIB.txt index 32cf7a63385..fa0dba37a2b 100644 --- a/contrib/bsnmp/snmp_mibII/BEGEMOT-MIB2-MIB.txt +++ b/contrib/bsnmp/snmp_mibII/BEGEMOT-MIB2-MIB.txt @@ -39,7 +39,7 @@ IMPORTS FROM BEGEMOT-IP-MIB; begemotMib2 MODULE-IDENTITY - LAST-UPDATED "200602130000Z" + LAST-UPDATED "200908030000Z" ORGANIZATION "German Aerospace Center" CONTACT-INFO " Hartmut Brandt @@ -54,6 +54,12 @@ begemotMib2 MODULE-IDENTITY E-mail: harti@freebsd.org" DESCRIPTION "The MIB for private mib2 stuff." + REVISION "200908030000Z" + DESCRIPTION + "Second edition adds begemotIfDataPoll object." + REVISION "200602130000Z" + DESCRIPTION + "Initial revision." ::= { begemotIp 1 } begemotIfMaxspeed OBJECT-TYPE @@ -87,4 +93,14 @@ begemotIfForcePoll OBJECT-TYPE bit rate in its MIB." ::= { begemotMib2 3 } +begemotIfDataPoll OBJECT-TYPE + SYNTAX TimeTicks + UNITS "deciseconds" + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The rate at which the mib2 module will poll interface data." + DEFVAL { 100 } + ::= { begemotMib2 4 } + END diff --git a/contrib/bsnmp/snmp_mibII/mibII.c b/contrib/bsnmp/snmp_mibII/mibII.c index cd4caacdd5e..87146951844 100644 --- a/contrib/bsnmp/snmp_mibII/mibII.c +++ b/contrib/bsnmp/snmp_mibII/mibII.c @@ -117,6 +117,15 @@ u_int mibif_hc_update_interval; /* HC update timer handle */ static void *hc_update_timer; +/* Idle poll timer */ +static void *mibII_poll_timer; + +/* interfaces' data poll interval */ +u_int mibII_poll_ticks; + +/* Idle poll hook */ +static void mibII_idle(void *arg __unused); + /*****************************/ static const struct asn_oid oid_ifMIB = OIDX_ifMIB; @@ -410,6 +419,20 @@ mibif_reset_hc_timer(void) mibif_hc_update_interval = ticks; } +/** + * Restart the idle poll timer. + */ +void +mibif_restart_mibII_poll_timer(void) +{ + if (mibII_poll_timer != NULL) + timer_stop(mibII_poll_timer); + + if ((mibII_poll_timer = timer_start_repeat(mibII_poll_ticks * 10, + mibII_poll_ticks * 10, mibII_idle, NULL, module)) == NULL) + syslog(LOG_ERR, "timer_start(%u): %m", mibII_poll_ticks); +} + /* * Fetch new MIB data. */ @@ -1553,7 +1576,7 @@ get_cloners(void) * Idle function */ static void -mibII_idle(void) +mibII_idle(void *arg __unused) { struct mibifa *ifa; @@ -1608,6 +1631,10 @@ mibII_start(void) ipForward_reg = or_register(&oid_ipForward, "The MIB module for the display of CIDR multipath IP Routes.", module); + + mibII_poll_timer = NULL; + mibII_poll_ticks = MIBII_POLL_TICKS; + mibif_restart_mibII_poll_timer(); } /* @@ -1651,6 +1678,11 @@ mibII_init(struct lmodule *mod, int argc __unused, char *argv[] __unused) static int mibII_fini(void) { + if (mibII_poll_timer != NULL ) { + timer_stop(mibII_poll_timer); + mibII_poll_timer = NULL; + } + if (route_fd != NULL) fd_deselect(route_fd); if (route != -1) @@ -1690,7 +1722,7 @@ const struct snmp_module config = { "This module implements the interface and ip groups.", mibII_init, mibII_fini, - mibII_idle, /* idle */ + NULL, /* idle */ NULL, /* dump */ NULL, /* config */ mibII_start, diff --git a/contrib/bsnmp/snmp_mibII/mibII.h b/contrib/bsnmp/snmp_mibII/mibII.h index a21e023be5c..0ebde9a9f9e 100644 --- a/contrib/bsnmp/snmp_mibII/mibII.h +++ b/contrib/bsnmp/snmp_mibII/mibII.h @@ -211,6 +211,14 @@ extern u_int mibif_hc_update_interval; /* re-compute update interval */ void mibif_reset_hc_timer(void); +/* interfaces' data poll interval */ +extern u_int mibII_poll_ticks; + +/* restart the data poll timer */ +void mibif_restart_mibII_poll_timer(void); + +#define MIBII_POLL_TICKS 100 + /* get interfaces and interface addresses. */ void mib_fetch_interfaces(void); diff --git a/contrib/bsnmp/snmp_mibII/mibII_begemot.c b/contrib/bsnmp/snmp_mibII/mibII_begemot.c index 5841b814413..b502e954778 100644 --- a/contrib/bsnmp/snmp_mibII/mibII_begemot.c +++ b/contrib/bsnmp/snmp_mibII/mibII_begemot.c @@ -59,6 +59,11 @@ op_begemot_mibII(struct snmp_context *ctx __unused, struct snmp_value *value, ctx->scratch->int1 = mibif_force_hc_update_interval; mibif_force_hc_update_interval = value->v.uint32; return (SNMP_ERR_NOERROR); + + case LEAF_begemotIfDataPoll: + ctx->scratch->int1 = mibII_poll_ticks; + mibII_poll_ticks = value->v.uint32; + return (SNMP_ERR_NOERROR); } abort(); @@ -68,6 +73,10 @@ op_begemot_mibII(struct snmp_context *ctx __unused, struct snmp_value *value, case LEAF_begemotIfForcePoll: mibif_force_hc_update_interval = ctx->scratch->int1; return (SNMP_ERR_NOERROR); + + case LEAF_begemotIfDataPoll: + mibII_poll_ticks = ctx->scratch->int1; + return (SNMP_ERR_NOERROR); } abort(); @@ -78,6 +87,10 @@ op_begemot_mibII(struct snmp_context *ctx __unused, struct snmp_value *value, mibif_force_hc_update_interval = ctx->scratch->int1; mibif_reset_hc_timer(); return (SNMP_ERR_NOERROR); + + case LEAF_begemotIfDataPoll: + mibif_restart_mibII_poll_timer(); + return (SNMP_ERR_NOERROR); } abort(); } @@ -98,6 +111,10 @@ op_begemot_mibII(struct snmp_context *ctx __unused, struct snmp_value *value, case LEAF_begemotIfForcePoll: value->v.uint32 = mibif_force_hc_update_interval; return (SNMP_ERR_NOERROR); + + case LEAF_begemotIfDataPoll: + value->v.uint32 = mibII_poll_ticks; + return (SNMP_ERR_NOERROR); } abort(); } diff --git a/contrib/bsnmp/snmp_mibII/mibII_tree.def b/contrib/bsnmp/snmp_mibII/mibII_tree.def index 90fbb03ae21..d3775389933 100644 --- a/contrib/bsnmp/snmp_mibII/mibII_tree.def +++ b/contrib/bsnmp/snmp_mibII/mibII_tree.def @@ -240,6 +240,7 @@ (1 begemotIfMaxspeed COUNTER64 op_begemot_mibII GET) (2 begemotIfPoll TIMETICKS op_begemot_mibII GET) (3 begemotIfForcePoll TIMETICKS op_begemot_mibII GET SET) + (4 begemotIfDataPoll TIMETICKS op_begemot_mibII GET SET) ) ) ) From f142f57c04dd0c5fe36eb4e930a0acbfc123878c Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 10 Dec 2009 18:38:40 +0000 Subject: [PATCH 0820/2592] MFC r200124,r200126, r200124: Avoid using additional variable for storing an error if we are not going to do anything with it. r200126: Fix deadlock when ZVOLs are present and we are replacing dead component or calling scrub when pool is in a degraded state. It will try to taste ZVOLs, which will lead to deadlock, as ZVOL will try to acquire the same locks as replace/scrub is holding already. We can't simply skip provider based on their GEOM class, because ZVOL can have providers build on top of it and we need to skip those as well. We do it by asking for ZFS::iszvol attribute. Any ZVOL-based provider will give us positive answer and we have to skip those providers. This way we remove possibility to create ZFS pools on top of ZVOLs, but it is not very useful anyway. I believe deadlock is still possible in some very complex situations like when we have MD provider on top of UFS file on top of ZVOL. When we try to replace dead component in the pool mentioned ZVOL is based on, there might be a deadlock when ZFS will try to taste MD provider. There is no easy way to detect that, but it isn't very common. r200125,r200158: Fix order of looking for providers. Before r200125 the order of looking for providers was wrong. It was: 1. Find provider by name. 2. Find provider by guid. 3. Find provider by name and guid. Where it should have been: 1. Find provider by name and guid. 2. Find provider by guid. 3. Find provider by name. --- .../opensolaris/uts/common/fs/zfs/vdev_geom.c | 14 +++++++++----- .../contrib/opensolaris/uts/common/fs/zfs/zvol.c | 5 ++++- 2 files changed, 13 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 f0f9c6fa693..4c41f90253e 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 @@ -293,11 +293,16 @@ vdev_geom_read_guid(struct g_consumer *cp) uint64_t psize; off_t offset, size; uint64_t guid; - int error, l, len; + int error, l, len, iszvol; g_topology_assert_not(); pp = cp->provider; + ZFS_LOG(1, "Reading guid from %s...", pp->name); + if (g_getattr("ZFS::iszvol", cp, &iszvol) == 0 && iszvol) { + ZFS_LOG(1, "Skipping ZVOL-based provider %s.", pp->name); + return (0); + } psize = pp->mediasize; psize = P2ALIGN(psize, (uint64_t)sizeof(vdev_label_t)); @@ -316,8 +321,7 @@ vdev_geom_read_guid(struct g_consumer *cp) if ((offset % pp->sectorsize) != 0) continue; - error = vdev_geom_io(cp, BIO_READ, label, offset, size); - if (error != 0) + if (vdev_geom_io(cp, BIO_READ, label, offset, size) != 0) continue; buf = label->vl_vdev_phys.vp_nvlist; @@ -502,7 +506,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) if ((owned = mtx_owned(&Giant))) mtx_unlock(&Giant); - cp = vdev_geom_open_by_path(vd, 0); + cp = vdev_geom_open_by_path(vd, 1); if (cp == NULL) { /* * The device at vd->vdev_path doesn't have the expected guid. @@ -512,7 +516,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) cp = vdev_geom_open_by_guid(vd); } if (cp == NULL) - cp = vdev_geom_open_by_path(vd, 1); + cp = vdev_geom_open_by_path(vd, 0); if (cp == NULL) { ZFS_LOG(1, "Provider %s not found.", vd->vdev_path); vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c index e9b00cbbb68..b07a8c11da4 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c @@ -335,8 +335,11 @@ zvol_start(struct bio *bp) wakeup_one(&zv->zv_queue); mtx_unlock(&zv->zv_queue_mtx); break; - case BIO_DELETE: case BIO_GETATTR: + if (g_handleattr_int(bp, "ZFS::iszvol", 1)) + break; + /* FALLTHROUGH */ + case BIO_DELETE: default: g_io_deliver(bp, EOPNOTSUPP); break; From b6eb79852ea1f7f1e8e9c5aa848d5ef67eec4084 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 10 Dec 2009 23:46:37 +0000 Subject: [PATCH 0821/2592] MFC r197044: Actually component with the greatest priority is used by the prefer balance algorithm. --- sbin/geom/class/mirror/gmirror.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/geom/class/mirror/gmirror.8 b/sbin/geom/class/mirror/gmirror.8 index 78baf0b3592..ea0cb9a865a 100644 --- a/sbin/geom/class/mirror/gmirror.8 +++ b/sbin/geom/class/mirror/gmirror.8 @@ -122,7 +122,7 @@ indicates an action to be performed: Create a mirror. The order of components is important, because a component's priority is based on its position (starting from 0 to 255). -The component with the biggest priority (the lowest number) is used by the +The component with the biggest priority is used by the .Cm prefer balance algorithm and is also used as a master component when resynchronization is needed, From 1fea06a08177ebe551ad6b3e843e9ebfe58e1f6b Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 10 Dec 2009 23:51:24 +0000 Subject: [PATCH 0822/2592] MFC r200282, r200290: Change gmirror default balance algorithm from "split" to improved "load". "split" is very ineffective for devices with rotating media as HDDs. To be effective, it needs that transfer time reduction due to block splitting was bigger then access time increase due to non-sequential access. For modern HDDs I was able to reproduce it only with read sizes of 2MB and above, which is almost not applicable in real life. "load" algorithm same time is more universal and effective now. --- sbin/geom/class/mirror/geom_mirror.c | 2 +- sbin/geom/class/mirror/gmirror.8 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sbin/geom/class/mirror/geom_mirror.c b/sbin/geom/class/mirror/geom_mirror.c index 6ac4fb9a775..cf15c60af9d 100644 --- a/sbin/geom/class/mirror/geom_mirror.c +++ b/sbin/geom/class/mirror/geom_mirror.c @@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$"); uint32_t lib_version = G_LIB_VERSION; uint32_t version = G_MIRROR_VERSION; -static char label_balance[] = "split", configure_balance[] = "none"; +static char label_balance[] = "load", configure_balance[] = "none"; static intmax_t label_slice = 4096, configure_slice = -1; static intmax_t insert_priority = 0, configure_priority = -1; diff --git a/sbin/geom/class/mirror/gmirror.8 b/sbin/geom/class/mirror/gmirror.8 index ea0cb9a865a..baaa827daf2 100644 --- a/sbin/geom/class/mirror/gmirror.8 +++ b/sbin/geom/class/mirror/gmirror.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 1, 2009 +.Dd December 8, 2009 .Dt GMIRROR 8 .Os .Sh NAME @@ -135,6 +135,7 @@ Specifies balance algorithm to use, one of: .Bl -tag -width ".Cm round-robin" .It Cm load Read from the component with the lowest load. +This is the default balance algorithm. .It Cm prefer Read from the component with the biggest priority. .It Cm round-robin @@ -142,7 +143,6 @@ Use round-robin algorithm when choosing component to read. .It Cm split Split read requests, which are bigger than or equal to slice size on N pieces, where N is the number of active components. -This is the default balance algorithm. .El .It Fl F Do not synchronize after a power failure or system crash. From 151681ac532f401cffc51bd0df8de6fb182423bb Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 11 Dec 2009 01:06:30 +0000 Subject: [PATCH 0823/2592] MFC r199846: Add two Cirrus Logic codec IDs. Add GPIO setting quirk for Apple MacBookPro5,5. Submitted by: ed --- sys/dev/sound/pci/hda/hdac.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index c88036955a9..61bc646a035 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -315,6 +315,7 @@ SND_DECLARE_FILE("$FreeBSD$"); * (see HDA_CODEC_STAC9221 below). */ #define APPLE_INTEL_MAC 0x76808384 +#define APPLE_MACBOOKPRO55 0xcb7910de /* LG Electronics */ #define LG_VENDORID 0x1854 @@ -605,6 +606,11 @@ static const struct { #define HDA_CODEC_CONSTRUCT(vendor, id) \ (((uint32_t)(vendor##_VENDORID) << 16) | ((id) & 0xffff)) +/* Cirrus Logic */ +#define CIRRUSLOGIC_VENDORID 0x1013 +#define HDA_CODEC_CS4206 HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4206) +#define HDA_CODEC_CS4207 HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4207) + /* Realtek */ #define REALTEK_VENDORID 0x10ec #define HDA_CODEC_ALC260 HDA_CODEC_CONSTRUCT(REALTEK, 0x0260) @@ -804,6 +810,8 @@ static const struct { uint32_t id; char *name; } hdac_codecs[] = { + { HDA_CODEC_CS4206, "Cirrus Logic CS4206" }, + { HDA_CODEC_CS4207, "Cirrus Logic CS4207" }, { HDA_CODEC_ALC260, "Realtek ALC260" }, { HDA_CODEC_ALC262, "Realtek ALC262" }, { HDA_CODEC_ALC267, "Realtek ALC267" }, @@ -4667,6 +4675,8 @@ static const struct { HDA_QUIRK_GPIO0 | HDA_QUIRK_OVREF50, 0}, { APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDA_QUIRK_GPIO0 | HDA_QUIRK_GPIO1, 0 }, + { APPLE_MACBOOKPRO55, HDA_CODEC_CS4206, + HDA_QUIRK_GPIO1 | HDA_QUIRK_GPIO3, 0 }, { DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_QUIRK_GPIO0, 0 }, { DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, From 391a9677beb2adced4640345729273775974aedc Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Fri, 11 Dec 2009 01:23:58 +0000 Subject: [PATCH 0824/2592] MFC r199958: Update to BIND 9.6.1-P2. The vulnerability this is designed to fix is related to DNSSEC validation on a resolving name server that allows access to untrusted users. If your system does not fall into all 3 of these categories you do not need to update immediately. --- contrib/bind9/CHANGES | 6 ++ contrib/bind9/bin/named/query.c | 68 +++++++++++++++++++---- contrib/bind9/lib/dns/api | 4 +- contrib/bind9/lib/dns/include/dns/types.h | 34 ++++++++---- contrib/bind9/lib/dns/masterdump.c | 5 +- contrib/bind9/lib/dns/rbtdb.c | 6 +- contrib/bind9/lib/dns/resolver.c | 35 ++++++++++-- contrib/bind9/lib/dns/validator.c | 12 ++-- contrib/bind9/version | 4 +- lib/bind/config.h | 4 ++ 10 files changed, 134 insertions(+), 44 deletions(-) diff --git a/contrib/bind9/CHANGES b/contrib/bind9/CHANGES index 1f2c35a1411..fd065d0da2b 100644 --- a/contrib/bind9/CHANGES +++ b/contrib/bind9/CHANGES @@ -1,3 +1,9 @@ + --- 9.6.1-P2 released --- + +2772. [security] When validating, track whether pending data was from + the additional section or not and only return it if + validates as secure. [RT #20438] + --- 9.6.1-P1 released --- 2640. [security] A specially crafted update packet will cause named diff --git a/contrib/bind9/bin/named/query.c b/contrib/bind9/bin/named/query.c index ffd9b3554a7..602948497a4 100644 --- a/contrib/bind9/bin/named/query.c +++ b/contrib/bind9/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.313.20.7 2009/03/13 01:38:51 marka Exp $ */ +/* $Id: query.c,v 1.313.20.7.12.1 2009/11/18 23:58:04 marka Exp $ */ /*! \file */ @@ -116,6 +116,8 @@ #define DNS_GETDB_NOLOG 0x02U #define DNS_GETDB_PARTIAL 0x04U +#define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0) + typedef struct client_additionalctx { ns_client_t *client; dns_rdataset_t *rdataset; @@ -1761,8 +1763,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { */ if (result == ISC_R_SUCCESS && additionaltype == dns_rdatasetadditional_fromcache && - (rdataset->trust == dns_trust_pending || - rdataset->trust == dns_trust_glue) && + (DNS_TRUST_PENDING(rdataset->trust) || + DNS_TRUST_GLUE(rdataset->trust)) && !validate(client, db, fname, rdataset, sigrdataset)) { dns_rdataset_disassociate(rdataset); if (dns_rdataset_isassociated(sigrdataset)) @@ -1801,8 +1803,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { */ if (result == ISC_R_SUCCESS && additionaltype == dns_rdatasetadditional_fromcache && - (rdataset->trust == dns_trust_pending || - rdataset->trust == dns_trust_glue) && + (DNS_TRUST_PENDING(rdataset->trust) || + DNS_TRUST_GLUE(rdataset->trust)) && !validate(client, db, fname, rdataset, sigrdataset)) { dns_rdataset_disassociate(rdataset); if (dns_rdataset_isassociated(sigrdataset)) @@ -2601,14 +2603,14 @@ query_addbestns(ns_client_t *client) { /* * Attempt to validate RRsets that are pending or that are glue. */ - if ((rdataset->trust == dns_trust_pending || - (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending)) + if ((DNS_TRUST_PENDING(rdataset->trust) || + (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust))) && !validate(client, db, fname, rdataset, sigrdataset) && - (client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0) + !PENDINGOK(client->query.dboptions)) goto cleanup; - if ((rdataset->trust == dns_trust_glue || - (sigrdataset != NULL && sigrdataset->trust == dns_trust_glue)) && + if ((DNS_TRUST_GLUE(rdataset->trust) || + (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) && !validate(client, db, fname, rdataset, sigrdataset) && SECURE(client) && WANTDNSSEC(client)) goto cleanup; @@ -3716,6 +3718,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) dns_rdataset_t *noqname; isc_boolean_t resuming; int line = -1; + dns_rdataset_t tmprdataset; + unsigned int dboptions; CTRACE("query_find"); @@ -3933,9 +3937,49 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) /* * Now look for an answer in the database. */ + dboptions = client->query.dboptions; + if (sigrdataset == NULL && client->view->enablednssec) { + /* + * If the client doesn't want DNSSEC we still want to + * look for any data pending validation to save a remote + * lookup if possible. + */ + dns_rdataset_init(&tmprdataset); + sigrdataset = &tmprdataset; + dboptions |= DNS_DBFIND_PENDINGOK; + } + refind: result = dns_db_find(db, client->query.qname, version, type, - client->query.dboptions, client->now, - &node, fname, rdataset, sigrdataset); + dboptions, client->now, &node, fname, + rdataset, sigrdataset); + /* + * If we have found pending data try to validate it. + * If the data does not validate as secure and we can't + * use the unvalidated data requery the database with + * pending disabled to prevent infinite looping. + */ + if (result != ISC_R_SUCCESS || !DNS_TRUST_PENDING(rdataset->trust)) + goto validation_done; + if (validate(client, db, fname, rdataset, sigrdataset)) + goto validation_done; + if (rdataset->trust != dns_trust_pending_answer || + !PENDINGOK(client->query.dboptions)) { + dns_rdataset_disassociate(rdataset); + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + if (sigrdataset == &tmprdataset) + sigrdataset = NULL; + dns_db_detachnode(db, &node); + dboptions &= ~DNS_DBFIND_PENDINGOK; + goto refind; + } + validation_done: + if (sigrdataset == &tmprdataset) { + if (dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + sigrdataset = NULL; + } resume: CTRACE("query_find: resume"); diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api index af155ca8f5f..4bcf883246c 100644 --- a/contrib/bind9/lib/dns/api +++ b/contrib/bind9/lib/dns/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 52 +LIBINTERFACE = 53 LIBREVISION = 0 -LIBAGE = 2 +LIBAGE = 0 diff --git a/contrib/bind9/lib/dns/include/dns/types.h b/contrib/bind9/lib/dns/include/dns/types.h index e07a7965bff..8c7773c3160 100644 --- a/contrib/bind9/lib/dns/include/dns/types.h +++ b/contrib/bind9/lib/dns/include/dns/types.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.130.50.3 2009/01/29 22:40:35 jinmei Exp $ */ +/* $Id: types.h,v 1.130.50.3.12.1 2009/11/18 23:58:04 marka Exp $ */ #ifndef DNS_TYPES_H #define DNS_TYPES_H 1 @@ -258,40 +258,52 @@ enum { dns_trust_none = 0, #define dns_trust_none ((dns_trust_t)dns_trust_none) - /*% Subject to DNSSEC validation but has not yet been validated */ - dns_trust_pending = 1, -#define dns_trust_pending ((dns_trust_t)dns_trust_pending) + /*% + * Subject to DNSSEC validation but has not yet been validated + * dns_trust_pending_additional (from the additional section). + */ + dns_trust_pending_additional = 1, +#define dns_trust_pending_additional \ + ((dns_trust_t)dns_trust_pending_additional) + + dns_trust_pending_answer = 2, +#define dns_trust_pending_answer ((dns_trust_t)dns_trust_pending_answer) /*% Received in the additional section of a response. */ - dns_trust_additional = 2, + dns_trust_additional = 3, #define dns_trust_additional ((dns_trust_t)dns_trust_additional) /* Received in a referral response. */ - dns_trust_glue = 3, + dns_trust_glue = 4, #define dns_trust_glue ((dns_trust_t)dns_trust_glue) /* Answer from a non-authoritative server */ - dns_trust_answer = 4, + dns_trust_answer = 5, #define dns_trust_answer ((dns_trust_t)dns_trust_answer) /* Received in the authority section as part of an authoritative response */ - dns_trust_authauthority = 5, + dns_trust_authauthority = 6, #define dns_trust_authauthority ((dns_trust_t)dns_trust_authauthority) /* Answer from an authoritative server */ - dns_trust_authanswer = 6, + dns_trust_authanswer = 7, #define dns_trust_authanswer ((dns_trust_t)dns_trust_authanswer) /* Successfully DNSSEC validated */ - dns_trust_secure = 7, + dns_trust_secure = 8, #define dns_trust_secure ((dns_trust_t)dns_trust_secure) /* This server is authoritative */ - dns_trust_ultimate = 8 + dns_trust_ultimate = 9 #define dns_trust_ultimate ((dns_trust_t)dns_trust_ultimate) }; +#define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \ + (x) == dns_trust_pending_additional) +#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue) + + /*% * Name checking severities. */ diff --git a/contrib/bind9/lib/dns/masterdump.c b/contrib/bind9/lib/dns/masterdump.c index 5eac96ff280..1dbb1e615e8 100644 --- a/contrib/bind9/lib/dns/masterdump.c +++ b/contrib/bind9/lib/dns/masterdump.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: masterdump.c,v 1.94.50.2 2009/01/18 23:47:40 tbox Exp $ */ +/* $Id: masterdump.c,v 1.94.50.2.12.1 2009/11/18 23:58:04 marka Exp $ */ /*! \file */ @@ -775,7 +775,8 @@ dump_order_compare(const void *a, const void *b) { static const char *trustnames[] = { "none", - "pending", + "pending-additional", + "pending-answer", "additional", "glue", "answer", diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c index 9741c157f78..b163441d43b 100644 --- a/contrib/bind9/lib/dns/rbtdb.c +++ b/contrib/bind9/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.270.12.6 2009/05/06 23:34:30 jinmei Exp $ */ +/* $Id: rbtdb.c,v 1.270.12.6.10.1 2009/11/18 23:58:04 marka Exp $ */ /*! \file */ @@ -4005,7 +4005,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { } if (dname_header != NULL && - (dname_header->trust != dns_trust_pending || + (!DNS_TRUST_PENDING(dname_header->trust) || (search->options & DNS_DBFIND_PENDINGOK) != 0)) { /* * We increment the reference count on node to ensure that @@ -4548,7 +4548,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, if (found == NULL || (found->trust == dns_trust_glue && ((options & DNS_DBFIND_GLUEOK) == 0)) || - (found->trust == dns_trust_pending && + (DNS_TRUST_PENDING(found->trust) && ((options & DNS_DBFIND_PENDINGOK) == 0))) { /* * If there is an NS rdataset at this node, then this is the diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c index a5d7c2500f8..3b90af4400c 100644 --- a/contrib/bind9/lib/dns/resolver.c +++ b/contrib/bind9/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.384.14.14 2009/06/02 23:47:13 tbox Exp $ */ +/* $Id: resolver.c,v 1.384.14.14.8.1 2009/11/18 23:58:04 marka Exp $ */ /*! \file */ @@ -4293,6 +4293,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, * for it, unless it is glue. */ if (secure_domain && rdataset->trust != dns_trust_glue) { + dns_trust_t trust; /* * RRSIGs are validated as part of validating the * type they cover. @@ -4329,12 +4330,34 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, } /* - * Cache this rdataset/sigrdataset pair as - * pending data. + * Reject out of bailiwick additional records + * without RRSIGs as they can't possibly validate + * as "secure" and as we will never never want to + * store these as "answers" after validation. */ - rdataset->trust = dns_trust_pending; + if (rdataset->trust == dns_trust_additional && + sigrdataset == NULL && EXTERNAL(rdataset)) + continue; + + /* + * XXXMPA: If we store as "answer" after validating + * then we need to do bailiwick processing and + * also need to track whether RRsets are in or + * out of bailiwick. This will require a another + * pending trust level. + * + * Cache this rdataset/sigrdataset pair as + * pending data. Track whether it was additional + * or not. + */ + if (rdataset->trust == dns_trust_additional) + trust = dns_trust_pending_additional; + else + trust = dns_trust_pending_answer; + + rdataset->trust = trust; if (sigrdataset != NULL) - sigrdataset->trust = dns_trust_pending; + sigrdataset->trust = trust; if (!need_validation || !ANSWER(rdataset)) { addedrdataset = ardataset; result = dns_db_addrdataset(fctx->cache, node, @@ -4682,7 +4705,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, for (trdataset = ISC_LIST_HEAD(tname->list); trdataset != NULL; trdataset = ISC_LIST_NEXT(trdataset, link)) - trdataset->trust = dns_trust_pending; + trdataset->trust = dns_trust_pending_answer; result = dns_message_nextname(fctx->rmessage, DNS_SECTION_AUTHORITY); } diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c index c62b714162b..46a74919c82 100644 --- a/contrib/bind9/lib/dns/validator.c +++ b/contrib/bind9/lib/dns/validator.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.164.12.9 2009/05/07 23:47:12 tbox Exp $ */ +/* $Id: validator.c,v 1.164.12.9.8.1 2009/11/18 23:58:04 marka Exp $ */ #include @@ -1607,7 +1607,7 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) { * We have an rrset for the given keyname. */ val->keyset = &val->frdataset; - if (val->frdataset.trust == dns_trust_pending && + if (DNS_TRUST_PENDING(val->frdataset.trust) && dns_rdataset_isassociated(&val->fsigrdataset)) { /* @@ -1622,7 +1622,7 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) { if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); - } else if (val->frdataset.trust == dns_trust_pending) { + } else if (DNS_TRUST_PENDING(val->frdataset.trust)) { /* * Having a pending key with no signature means that * something is broken. @@ -2243,7 +2243,7 @@ validatezonekey(dns_validator_t *val) { * We have DS records. */ val->dsset = &val->frdataset; - if (val->frdataset.trust == dns_trust_pending && + if (DNS_TRUST_PENDING(val->frdataset.trust) && dns_rdataset_isassociated(&val->fsigrdataset)) { result = create_validator(val, @@ -2256,7 +2256,7 @@ validatezonekey(dns_validator_t *val) { if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); - } else if (val->frdataset.trust == dns_trust_pending) { + } else if (DNS_TRUST_PENDING(val->frdataset.trust)) { /* * There should never be an unsigned DS. */ @@ -3337,7 +3337,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume) * There is no DS. If this is a delegation, * we maybe done. */ - if (val->frdataset.trust == dns_trust_pending) { + if (DNS_TRUST_PENDING(val->frdataset.trust)) { result = create_fetch(val, tname, dns_rdatatype_ds, dsfetched2, diff --git a/contrib/bind9/version b/contrib/bind9/version index 3245f02d3fd..ccb7b87efb2 100644 --- a/contrib/bind9/version +++ b/contrib/bind9/version @@ -1,4 +1,4 @@ -# $Id: version,v 1.43.12.5.8.1 2009/07/28 14:18:08 marka Exp $ +# $Id: version,v 1.43.12.5.8.2 2009/11/18 23:58:04 marka Exp $ # # This file must follow /bin/sh rules. It is imported directly via # configure. @@ -7,4 +7,4 @@ MAJORVER=9 MINORVER=6 PATCHVER=1 RELEASETYPE=-P -RELEASEVER=1 +RELEASEVER=2 diff --git a/lib/bind/config.h b/lib/bind/config.h index 8e524266918..1d68450eafb 100644 --- a/lib/bind/config.h +++ b/lib/bind/config.h @@ -277,6 +277,10 @@ int sigwait(const unsigned int *set, int *sig); /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + /* Defined if extern char *optarg is not declared. */ /* #undef NEED_OPTARG */ From 3919e322129e8fecdac580248e110fab9abceda0 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Fri, 11 Dec 2009 01:26:26 +0000 Subject: [PATCH 0825/2592] MFC rev 200240: In exception_save, write-back ar.rnat after switching the backing-store. PR: ia64/120315 --- sys/ia64/ia64/exception.S | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S index 1f076020f77..2cf3aaf4411 100644 --- a/sys/ia64/ia64/exception.S +++ b/sys/ia64/ia64/exception.S @@ -219,43 +219,42 @@ exception_save_restart: (p13) dep r20=r20,r21,0,9 // align dirty registers ;; } - // r20=bspstore, r22=iip, r23=ipsr + // r19=rnat, r20=bspstore, r22=iip, r23=ipsr { .mmi st8 [r31]=r23,16 // psr (p13) mov ar.bspstore=r20 nop 0 ;; } -{ .mmi +{ .mmb +(p13) mov ar.rnat=r19 mov r18=ar.bsp + nop 0 ;; +} +{ .mmi mov r19=cr.ifs + st8.spill [r30]=gp,16 // gp sub r18=r18,r20 ;; -} -{ .mmi - st8.spill [r30]=gp,16 // gp - st8 [r31]=r18,16 // ndirty - nop 0 - ;; } // r19=ifs, r22=iip -{ .mmi +{ .mmb + st8 [r31]=r18,16 // ndirty st8 [r30]=r19,16 // cfm - st8 [r31]=r22,16 // iip nop 0 ;; } { .mmi - st8 [r30]=r17 // ifa mov r18=cr.isr + st8 [r31]=r22,16 // iip add r29=16,r30 ;; } -{ .mmi - st8 [r31]=r18 // isr - add r30=8,r29 - add r31=16,r29 +{ .mmb + st8 [r30]=r17,24 // ifa + st8 [r31]=r18,24 // isr + nop 0 ;; } { .mmi From 117384a792559c5b066acb6708ee3fde1598099e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 11 Dec 2009 11:07:05 +0000 Subject: [PATCH 0826/2592] MFC r200111: Add several syscall compat32 entries for acl manipulation. --- sys/compat/freebsd32/syscalls.master | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 0628571bbb1..43db906dac0 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -740,10 +740,14 @@ struct freebsd32_ucontext *oucp, \ const struct freebsd32_ucontext *ucp); } 424 AUE_SWAPOFF UNIMPL swapoff -425 AUE_NULL UNIMPL __acl_get_link -426 AUE_NULL UNIMPL __acl_set_link -427 AUE_NULL UNIMPL __acl_delete_link -428 AUE_NULL UNIMPL __acl_aclcheck_link +425 AUE_NULL NOPROTO { int __acl_get_link(const char *path, \ + acl_type_t type, struct acl *aclp); } +426 AUE_NULL NOPROTO { int __acl_set_link(const char *path, \ + acl_type_t type, struct acl *aclp); } +427 AUE_NULL NOPROTO { int __acl_delete_link(const char *path, \ + acl_type_t type); } +428 AUE_NULL NOPROTO { int __acl_aclcheck_link(const char *path, \ + acl_type_t type, struct acl *aclp); } 429 AUE_SIGWAIT NOPROTO { int sigwait(const sigset_t *set, \ int *sig); } 430 AUE_NULL UNIMPL thr_create; From 3f6a1b3c176b2a12a45c79a7600db5b03b21c557 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 11 Dec 2009 11:07:48 +0000 Subject: [PATCH 0827/2592] Regen --- sys/compat/freebsd32/freebsd32_proto.h | 2 +- sys/compat/freebsd32/freebsd32_syscall.h | 6 +++++- sys/compat/freebsd32/freebsd32_syscalls.c | 10 +++++----- sys/compat/freebsd32/freebsd32_sysent.c | 10 +++++----- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index d957b7cd0ba..498aaac5e6e 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 195468 2009-07-08 16:26:43Z trasz + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200404 2009-12-11 11:07:05Z kib */ #ifndef _FREEBSD32_SYSPROTO_H_ diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index 6ff55df1f82..7297dbb559b 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 195468 2009-07-08 16:26:43Z trasz + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200404 2009-12-11 11:07:05Z kib */ #define FREEBSD32_SYS_syscall 0 @@ -311,6 +311,10 @@ #define FREEBSD32_SYS_freebsd32_getcontext 421 #define FREEBSD32_SYS_freebsd32_setcontext 422 #define FREEBSD32_SYS_freebsd32_swapcontext 423 +#define FREEBSD32_SYS___acl_get_link 425 +#define FREEBSD32_SYS___acl_set_link 426 +#define FREEBSD32_SYS___acl_delete_link 427 +#define FREEBSD32_SYS___acl_aclcheck_link 428 #define FREEBSD32_SYS_sigwait 429 #define FREEBSD32_SYS_thr_exit 431 #define FREEBSD32_SYS_thr_self 432 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index 4cd91746f2a..08bdccbb04a 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 195468 2009-07-08 16:26:43Z trasz + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200404 2009-12-11 11:07:05Z kib */ const char *freebsd32_syscallnames[] = { @@ -432,10 +432,10 @@ const char *freebsd32_syscallnames[] = { "freebsd32_setcontext", /* 422 = freebsd32_setcontext */ "freebsd32_swapcontext", /* 423 = freebsd32_swapcontext */ "#424", /* 424 = swapoff */ - "#425", /* 425 = __acl_get_link */ - "#426", /* 426 = __acl_set_link */ - "#427", /* 427 = __acl_delete_link */ - "#428", /* 428 = __acl_aclcheck_link */ + "__acl_get_link", /* 425 = __acl_get_link */ + "__acl_set_link", /* 426 = __acl_set_link */ + "__acl_delete_link", /* 427 = __acl_delete_link */ + "__acl_aclcheck_link", /* 428 = __acl_aclcheck_link */ "sigwait", /* 429 = sigwait */ "#430", /* 430 = thr_create; */ "thr_exit", /* 431 = thr_exit */ diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index e5fa6ae4fea..f331b315750 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 195468 2009-07-08 16:26:43Z trasz + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200404 2009-12-11 11:07:05Z kib */ #include "opt_compat.h" @@ -469,10 +469,10 @@ struct sysent freebsd32_sysent[] = { { AS(freebsd32_setcontext_args), (sy_call_t *)freebsd32_setcontext, AUE_NULL, NULL, 0, 0, 0 }, /* 422 = freebsd32_setcontext */ { AS(freebsd32_swapcontext_args), (sy_call_t *)freebsd32_swapcontext, AUE_NULL, NULL, 0, 0, 0 }, /* 423 = freebsd32_swapcontext */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 424 = swapoff */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 425 = __acl_get_link */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 426 = __acl_set_link */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 427 = __acl_delete_link */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 428 = __acl_aclcheck_link */ + { AS(__acl_get_link_args), (sy_call_t *)__acl_get_link, AUE_NULL, NULL, 0, 0, 0 }, /* 425 = __acl_get_link */ + { AS(__acl_set_link_args), (sy_call_t *)__acl_set_link, AUE_NULL, NULL, 0, 0, 0 }, /* 426 = __acl_set_link */ + { AS(__acl_delete_link_args), (sy_call_t *)__acl_delete_link, AUE_NULL, NULL, 0, 0, 0 }, /* 427 = __acl_delete_link */ + { AS(__acl_aclcheck_link_args), (sy_call_t *)__acl_aclcheck_link, AUE_NULL, NULL, 0, 0, 0 }, /* 428 = __acl_aclcheck_link */ { AS(sigwait_args), (sy_call_t *)sigwait, AUE_SIGWAIT, NULL, 0, 0, 0 }, /* 429 = sigwait */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 430 = thr_create; */ { AS(thr_exit_args), (sy_call_t *)thr_exit, AUE_NULL, NULL, 0, 0, 0 }, /* 431 = thr_exit */ From 68d2ef77eb3795733f819822ecd701b847c9b581 Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Fri, 11 Dec 2009 12:36:02 +0000 Subject: [PATCH 0828/2592] MFC 196739: Add counters for the i7 architecture which were accidentally left out of the original commit of i7 support. These are all the counters on pages A-32 and A-33 of the _Intel(R) 64 and IA32 Architectures Software Developer's Manual Vol 3B_, June 2009. Almost all of these counters relate to operations on the L2 cache. --- sys/dev/hwpmc/hwpmc_core.c | 23 ++++++++++++++ sys/dev/hwpmc/pmc_events.h | 62 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index 6ae18fe3fe9..b6de04dfce8 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -1182,6 +1182,29 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(DBH_01H, 0xDB, 0x01, IAP_F_FM | IAP_F_I7), IAPDESCR(E4H_01H, 0xE4, 0x01, IAP_F_FM | IAP_F_I7), IAPDESCR(E5H_01H, 0xE5, 0x01, IAP_F_FM | IAP_F_I7), + IAPDESCR(E6H_01H, 0xE6, 0x01, IAP_F_FM | IAP_F_I7), + IAPDESCR(E6H_02H, 0xE6, 0x02, IAP_F_FM | IAP_F_I7), + IAPDESCR(E8H_01H, 0xE8, 0x01, IAP_F_FM | IAP_F_I7), + IAPDESCR(E8H_02H, 0xE8, 0x02, IAP_F_FM | IAP_F_I7), + IAPDESCR(E8H_03H, 0xE8, 0x03, IAP_F_FM | IAP_F_I7), + IAPDESCR(F0H_01H, 0xF0, 0x01, IAP_F_FM | IAP_F_I7), + IAPDESCR(F0H_02H, 0xF0, 0x02, IAP_F_FM | IAP_F_I7), + IAPDESCR(F0H_04H, 0xF0, 0x04, IAP_F_FM | IAP_F_I7), + IAPDESCR(F0H_08H, 0xF0, 0x08, IAP_F_FM | IAP_F_I7), + IAPDESCR(F0H_10H, 0xF0, 0x10, IAP_F_FM | IAP_F_I7), + IAPDESCR(F0H_20H, 0xF0, 0x20, IAP_F_FM | IAP_F_I7), + IAPDESCR(F0H_40H, 0xF0, 0x40, IAP_F_FM | IAP_F_I7), + IAPDESCR(F0H_80H, 0xF0, 0x80, IAP_F_FM | IAP_F_I7), + IAPDESCR(F1H_02H, 0xF1, 0x02, IAP_F_FM | IAP_F_I7), + IAPDESCR(F1H_04H, 0xF1, 0x04, IAP_F_FM | IAP_F_I7), + IAPDESCR(F1H_07H, 0xF1, 0x07, IAP_F_FM | IAP_F_I7), + IAPDESCR(F2H_01H, 0xF2, 0x01, IAP_F_FM | IAP_F_I7), + IAPDESCR(F2H_02H, 0xF2, 0x02, IAP_F_FM | IAP_F_I7), + IAPDESCR(F2H_04H, 0xF2, 0x04, IAP_F_FM | IAP_F_I7), + IAPDESCR(F2H_08H, 0xF2, 0x08, IAP_F_FM | IAP_F_I7), + IAPDESCR(F2H_0FH, 0xF2, 0x0F, IAP_F_FM | IAP_F_I7), + IAPDESCR(F3H_01H, 0xF3, 0x01, IAP_F_FM | IAP_F_I7), + IAPDESCR(F3H_02H, 0xF3, 0x02, IAP_F_FM | IAP_F_I7), IAPDESCR(F3H_04H, 0xF3, 0x04, IAP_F_FM | IAP_F_I7), IAPDESCR(F3H_08H, 0xF3, 0x08, IAP_F_FM | IAP_F_I7), IAPDESCR(F3H_10H, 0xF3, 0x10, IAP_F_FM | IAP_F_I7), diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h index 05078afc8f1..e7bc3497af2 100644 --- a/sys/dev/hwpmc/pmc_events.h +++ b/sys/dev/hwpmc/pmc_events.h @@ -29,8 +29,18 @@ #ifndef _DEV_HWPMC_PMC_EVENTS_H_ #define _DEV_HWPMC_PMC_EVENTS_H_ -/* - * PMC event codes. +/* + * Note: Documentation on adding events can be found both in + * the source tree at src/share/doc/papers/hwpmc/hwpmc.ms + * as well as on-line at: + * + * http://wiki.freebsd.org/PmcTools/PmcHardwareHowTo + * + * Please refer to those resources before you attempt to modify + * this file or the hwpmc driver/subsystem. + */ + +/* * PMC event codes. * * __PMC_EV(CLASS, SYMBOLIC-NAME) * @@ -973,7 +983,30 @@ __PMC_EV(IAP, EVENT_FDH_04H) \ __PMC_EV(IAP, EVENT_FDH_08H) \ __PMC_EV(IAP, EVENT_FDH_10H) \ __PMC_EV(IAP, EVENT_FDH_20H) \ -__PMC_EV(IAP, EVENT_FDH_40H) +__PMC_EV(IAP, EVENT_FDH_40H) \ +__PMC_EV(IAP, EVENT_E6H_02H) \ +__PMC_EV(IAP, EVENT_E8H_01H) \ +__PMC_EV(IAP, EVENT_E8H_02H) \ +__PMC_EV(IAP, EVENT_E8H_03H) \ +__PMC_EV(IAP, EVENT_F0H_01H) \ +__PMC_EV(IAP, EVENT_F0H_02H) \ +__PMC_EV(IAP, EVENT_F0H_04H) \ +__PMC_EV(IAP, EVENT_F0H_08H) \ +__PMC_EV(IAP, EVENT_F0H_10H) \ +__PMC_EV(IAP, EVENT_F0H_20H) \ +__PMC_EV(IAP, EVENT_F0H_40H) \ +__PMC_EV(IAP, EVENT_F0H_80H) \ +__PMC_EV(IAP, EVENT_F1H_02H) \ +__PMC_EV(IAP, EVENT_F1H_04H) \ +__PMC_EV(IAP, EVENT_F1H_07H) \ +__PMC_EV(IAP, EVENT_F2H_01H) \ +__PMC_EV(IAP, EVENT_F2H_02H) \ +__PMC_EV(IAP, EVENT_F2H_04H) \ +__PMC_EV(IAP, EVENT_F2H_08H) \ +__PMC_EV(IAP, EVENT_F2H_0FH) \ +__PMC_EV(IAP, EVENT_F3H_01H) \ +__PMC_EV(IAP, EVENT_F3H_02H) + #define PMC_EV_IAP_FIRST PMC_EV_IAP_EVENT_02H_81H #define PMC_EV_IAP_LAST PMC_EV_IAP_EVENT_FDH_40H @@ -1894,6 +1927,29 @@ __PMC_EV_ALIAS("UOP_UNFUSION", IAP_EVENT_DBH_01H) \ __PMC_EV_ALIAS("BR_INST_DECODED", IAP_EVENT_E0H_01H) \ __PMC_EV_ALIAS("BOGUS_BR", IAP_EVENT_E4H_01H) \ __PMC_EV_ALIAS("BPU_MISSED_CALL_RET", IAP_EVENT_E5H_01H) \ +__PMC_EV_ALIAS("BACLEAR.CLEAR", IAP_EVENT_E6H_01H) \ +__PMC_EV_ALIAS("BACLEAR.BAD_TARGET", IAP_EVENT_E6H_02H) \ +__PMC_EV_ALIAS("BPU_CLEARS.EARLY", IAP_EVENT_E8H_01H) \ +__PMC_EV_ALIAS("BPU_CLEARS.LATE", IAP_EVENT_E8H_02H) \ +__PMC_EV_ALIAS("BPU_CLEARS.ANY", IAP_EVENT_E8H_03H) \ +__PMC_EV_ALIAS("L2_TRANSACTIONS.LOAD", IAP_EVENT_F0H_01H) \ +__PMC_EV_ALIAS("L2_TRANSACTIONS.RFO", IAP_EVENT_F0H_02H) \ +__PMC_EV_ALIAS("L2_TRANSACTIONS.IFETCH", IAP_EVENT_F0H_04H) \ +__PMC_EV_ALIAS("L2_TRANSACTIONS.PREFETCH", IAP_EVENT_F0H_08H) \ +__PMC_EV_ALIAS("L2_TRANSACTIONS.L1D_WB", IAP_EVENT_F0H_10H) \ +__PMC_EV_ALIAS("L2_TRANSACTIONS.FILL", IAP_EVENT_F0H_20H) \ +__PMC_EV_ALIAS("L2_TRANSACTIONS.WB", IAP_EVENT_F0H_40H) \ +__PMC_EV_ALIAS("L2_TRANSACTIONS.ANY", IAP_EVENT_F0H_80H) \ +__PMC_EV_ALIAS("L2_LINES_IN.S_STATE", IAP_EVENT_F1H_02H) \ +__PMC_EV_ALIAS("L2_LINES_IN.E_STATE", IAP_EVENT_F1H_04H) \ +__PMC_EV_ALIAS("L2_LINES_IN.ANY", IAP_EVENT_F1H_07H) \ +__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_CLEAN", IAP_EVENT_F2H_01H) \ +__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_02H) \ +__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_CLEAN", IAP_EVENT_F2H_04H) \ +__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_DIRTY", IAP_EVENT_F2H_08H) \ +__PMC_EV_ALIAS("L2_LINES_OUT.ANY", IAP_EVENT_F2H_0FH) \ +__PMC_EV_ALIAS("L2_HW_PREFETCH.HIT", IAP_EVENT_F3H_01H) \ +__PMC_EV_ALIAS("L2_HW_PREFETCH.ALLOC", IAP_EVENT_F3H_02H) \ __PMC_EV_ALIAS("L2_HW_PREFETCH.DATA_TRIGGER", IAP_EVENT_F3H_04H) \ __PMC_EV_ALIAS("L2_HW_PREFETCH.CODE_TRIGGER", IAP_EVENT_F3H_08H) \ __PMC_EV_ALIAS("L2_HW_PREFETCH.DCA_TRIGGER", IAP_EVENT_F3H_10H) \ From 248e8fd706428af82cde6729c8be4846c0a5851f Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 11 Dec 2009 12:44:44 +0000 Subject: [PATCH 0829/2592] MFC r200353: Limit maximum I/O size, depending on command set supported by device. It is required to suppot non-LBA48 devices with MAXPHYS above 128K. Same is done in ada(4). --- sys/dev/ata/ata-disk.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 03b10650b82..ea427e574ec 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -126,6 +126,10 @@ ad_attach(device_t dev) adp->disk->d_name = "ad"; adp->disk->d_drv1 = dev; adp->disk->d_maxsize = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS; + if (atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) + adp->disk->d_maxsize = min(adp->disk->d_maxsize, 65536 * DEV_BSIZE); + else /* 28bit ATA command limit */ + adp->disk->d_maxsize = min(adp->disk->d_maxsize, 256 * DEV_BSIZE); adp->disk->d_sectorsize = DEV_BSIZE; adp->disk->d_mediasize = DEV_BSIZE * (off_t)adp->total_secs; adp->disk->d_fwsectors = adp->sectors; From cee2de6c2aac2076fde0838fda2a92a8d5ead6c0 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 11 Dec 2009 12:53:09 +0000 Subject: [PATCH 0830/2592] MFC r200180: If we panicked with SIM lock held, do not try to flush caches. Extra lock recursing will not make debugging easier. --- sys/cam/ata/ata_da.c | 3 +++ sys/cam/cam_periph.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 4a9a9c3d715..f62af46d46b 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -1040,6 +1040,9 @@ adashutdown(void * arg, int howto) TAILQ_FOREACH(periph, &adadriver.units, unit_links) { union ccb ccb; + /* If we paniced with lock held - not recurse here. */ + if (cam_periph_owned(periph)) + continue; cam_periph_lock(periph); softc = (struct ada_softc *)periph->softc; /* diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h index 07caf52d08a..e207b1925ab 100644 --- a/sys/cam/cam_periph.h +++ b/sys/cam/cam_periph.h @@ -190,5 +190,11 @@ cam_periph_unlock(struct cam_periph *periph) mtx_unlock(periph->sim->mtx); } +static __inline int +cam_periph_owned(struct cam_periph *periph) +{ + return (mtx_owned(periph->sim->mtx)); +} + #endif /* _KERNEL */ #endif /* _CAM_CAM_PERIPH_H */ From b75ed345f891fdf0ed4f034c439e3fd2fd65e50e Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sat, 12 Dec 2009 02:31:16 +0000 Subject: [PATCH 0831/2592] MFC r200083: The first argument of dcbz interprets r0 as a literal zero, not the second. This worked before by accident. --- sys/powerpc/aim/machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index b5202e77b36..a29866c8aa2 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -374,7 +374,7 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++) cache_check[cacheline_size] = 0xff; - __asm __volatile("dcbz %0,0":: "r" (cache_check) : "memory"); + __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory"); /* Find the first byte dcbz did not zero to get the cache line size */ for (cacheline_size = 0; cacheline_size < 0x100 && From a8fb2bf194f2c510f5428fa7e393c2a56744dc99 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sat, 12 Dec 2009 02:34:00 +0000 Subject: [PATCH 0832/2592] MFC r199888: Add support for interpreting taps on ADB touchpads as a button click. Submitted by: Andreas Tobler --- sys/dev/adb/adb.h | 1 + sys/dev/adb/adb_bus.c | 18 ++++++ sys/dev/adb/adb_mouse.c | 131 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 149 insertions(+), 1 deletion(-) diff --git a/sys/dev/adb/adb.h b/sys/dev/adb/adb.h index 10c3db23590..acb5ae27d4c 100644 --- a/sys/dev/adb/adb.h +++ b/sys/dev/adb/adb.h @@ -69,6 +69,7 @@ uint8_t adb_get_device_handler(device_t dev); uint8_t adb_set_device_handler(device_t dev, uint8_t newhandler); size_t adb_read_register(device_t dev, u_char reg, void *data); +size_t adb_write_register(device_t dev, u_char reg, size_t len, void *data); /* Bits for implementing ADB host bus adapters */ extern devclass_t adb_devclass; diff --git a/sys/dev/adb/adb_bus.c b/sys/dev/adb/adb_bus.c index faab048b52c..fd46f27e963 100644 --- a/sys/dev/adb/adb_bus.c +++ b/sys/dev/adb/adb_bus.c @@ -402,3 +402,21 @@ adb_read_register(device_t dev, u_char reg, void *data) return (result); } +size_t +adb_write_register(device_t dev, u_char reg, size_t len, void *data) +{ + struct adb_softc *sc; + struct adb_devinfo *dinfo; + size_t result; + + dinfo = device_get_ivars(dev); + sc = device_get_softc(device_get_parent(dev)); + + result = adb_send_raw_packet_sync(sc->sc_dev,dinfo->address, + ADB_COMMAND_LISTEN, reg, len, (u_char *)data, NULL); + + result = adb_send_raw_packet_sync(sc->sc_dev,dinfo->address, + ADB_COMMAND_TALK, reg, 0, NULL, NULL); + + return (result); +} diff --git a/sys/dev/adb/adb_mouse.c b/sys/dev/adb/adb_mouse.c index f602f1cd08d..7eecb7ad761 100644 --- a/sys/dev/adb/adb_mouse.c +++ b/sys/dev/adb/adb_mouse.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,8 @@ static int adb_mouse_probe(device_t dev); static int adb_mouse_attach(device_t dev); static int adb_mouse_detach(device_t dev); +static void adb_init_trackpad(device_t dev); +static int adb_tapping_sysctl(SYSCTL_HANDLER_ARGS); static d_open_t ams_open; static d_close_t ams_close; @@ -77,6 +80,8 @@ struct adb_mouse_softc { u_char id[4]; int buttons; + u_int sc_tapping; + int button_buf; int last_buttons; int xdelta, ydelta; @@ -167,6 +172,8 @@ adb_mouse_attach(device_t dev) sc->mode.packetsize = 5; sc->buttons = 0; + sc->sc_tapping = 0; + sc->button_buf = 0; sc->last_buttons = 0; sc->packet_read_len = 0; @@ -205,6 +212,7 @@ adb_mouse_attach(device_t dev) case 3: sc->flags |= AMS_TOUCHPAD; sc->hw.type = MOUSE_PAD; + adb_init_trackpad(dev); description = "Touchpad"; break; } @@ -259,6 +267,70 @@ adb_mouse_detach(device_t dev) return (0); } +static void +adb_init_trackpad(device_t dev) +{ + struct adb_mouse_softc *sc; + struct sysctl_ctx_list *ctx; + struct sysctl_oid *tree; + + size_t r1_len; + u_char r1[8]; + u_char r2[8]; + + sc = device_get_softc(dev); + + r1_len = adb_read_register(dev, 1, r1); + + /* An Extended Mouse register1 must return 8 bytes. */ + if (r1_len != 8) + return; + + if((r1[6] != 0x0d)) + { + r1[6] = 0x0d; + + adb_write_register(dev, 1, 8, r1); + + r1_len = adb_read_register(dev, 1, r1); + + if (r1[6] != 0x0d) + { + device_printf(dev, "ADB Mouse = 0x%x " + "(non-Extended Mode)\n", r1[6]); + return; + } else { + device_printf(dev, "ADB Mouse = 0x%x " + "(Extended Mode)\n", r1[6]); + + /* Set ADB Extended Features to default values, + enabled. */ + r2[0] = 0x19; /* Clicking: 0x19 disabled 0x99 enabled */ + r2[1] = 0x94; /* Dragging: 0x14 disabled 0x94 enabled */ + r2[2] = 0x19; + r2[3] = 0xff; /* DragLock: 0xff disabled 0xb2 enabled */ + r2[4] = 0xb2; + r2[5] = 0x8a; + r2[6] = 0x1b; + + r2[7] = 0x57; /* 0x57 bits 3:0 for W mode */ + + adb_write_register(dev, 2, 8, r2); + + } + } + + /* + * Set up sysctl + */ + ctx = device_get_sysctl_ctx(dev); + tree = device_get_sysctl_tree(dev); + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tapping", + CTLTYPE_INT | CTLFLAG_RW, sc, 0, adb_tapping_sysctl, + "I", "Tapping the pad causes button events"); + return; +} + static u_int adb_mouse_receive_packet(device_t dev, u_char status, u_char command, u_char reg, int len, u_char *data) @@ -266,7 +338,7 @@ adb_mouse_receive_packet(device_t dev, u_char status, u_char command, struct adb_mouse_softc *sc; int i = 0; int xdelta, ydelta; - int buttons; + int buttons, tmp_buttons; sc = device_get_softc(dev); @@ -298,6 +370,30 @@ adb_mouse_receive_packet(device_t dev, u_char status, u_char command, if (ydelta & (0x40 << 3*(len-2))) ydelta |= 0xffffffc0 << 3*(len - 2); + if ((sc->flags & AMS_TOUCHPAD) && (sc->sc_tapping == 1)) { + tmp_buttons = buttons; + if (buttons == 0x12) { + /* Map a double tap on button 3. + Keep the button state for the next sequence. + A double tap sequence is followed by a single tap + sequence. + */ + tmp_buttons = 0x3; + sc->button_buf = tmp_buttons; + } else if (buttons == 0x2) { + /* Map a single tap on button 2. But only if it is + not a successor from a double tap. + */ + if (sc->button_buf != 0x3) + tmp_buttons = 0x2; + else + tmp_buttons = 0; + + sc->button_buf = 0; + } + buttons = tmp_buttons; + } + /* * Some mice report high-numbered buttons on the wrong button number, * so set the highest-numbered real button as pressed if there are @@ -554,3 +650,36 @@ ams_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, return (0); } +static int +adb_tapping_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct adb_mouse_softc *sc = arg1; + device_t dev; + int error; + u_char r2[8]; + u_int tapping; + + dev = sc->sc_dev; + tapping = sc->sc_tapping; + + error = sysctl_handle_int(oidp, &tapping, 0, req); + + if (error || !req->newptr) + return (error); + + if (tapping == 1) { + adb_read_register(dev, 2, r2); + r2[0] = 0x99; /* enable tapping. */ + adb_write_register(dev, 2, 8, r2); + sc->sc_tapping = 1; + } else if (tapping == 0) { + adb_read_register(dev, 2, r2); + r2[0] = 0x19; /* disable tapping. */ + adb_write_register(dev, 2, 8, r2); + sc->sc_tapping = 0; + } + else + return (EINVAL); + + return (0); +} From f695ba479e7aedb7b8a40c347a2c35df119001f1 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 12 Dec 2009 04:34:22 +0000 Subject: [PATCH 0833/2592] MFC rev 200045: Include , to get the declarations of ostype and osrelease. Remove the duplicate declarations from this file. --- sys/dev/iir/iir_ctrl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/dev/iir/iir_ctrl.c b/sys/dev/iir/iir_ctrl.c index 51ef0434a48..5f9f3d597ce 100644 --- a/sys/dev/iir/iir_ctrl.c +++ b/sys/dev/iir/iir_ctrl.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -83,8 +84,6 @@ static int iir_devsw_installed = 0; static int sdev_made = 0; #endif extern int gdt_cnt; -extern char ostype[]; -extern char osrelease[]; extern gdt_statist_t gdt_stat; /* From 5b574e433fd15f53ee06c8b17e74a0c2a63f4d49 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 12 Dec 2009 05:14:40 +0000 Subject: [PATCH 0834/2592] MFC rev 199893, 199941, 200200 and 200207: o Eliminate MAXCPU. o Revamp the PCPU structure. --- sys/ia64/ia64/clock.c | 6 +- sys/ia64/ia64/genassym.c | 2 +- sys/ia64/ia64/interrupt.c | 53 +++++-------- sys/ia64/ia64/machdep.c | 71 +++++++++++++++++- sys/ia64/ia64/mp_machdep.c | 30 +++++--- sys/ia64/ia64/pmap.c | 148 +++++++++++++++++-------------------- sys/ia64/include/kdb.h | 2 +- sys/ia64/include/param.h | 2 +- sys/ia64/include/pcpu.h | 37 ++++++++-- sys/ia64/include/pmap.h | 1 + 10 files changed, 210 insertions(+), 142 deletions(-) diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c index 22fcf9bf452..6f2e2d86683 100644 --- a/sys/ia64/ia64/clock.c +++ b/sys/ia64/ia64/clock.c @@ -64,9 +64,9 @@ void pcpu_initclock(void) { - PCPU_SET(clockadj, 0); - PCPU_SET(clock, ia64_get_itc()); - ia64_set_itm(PCPU_GET(clock) + ia64_clock_reload); + PCPU_SET(md.clockadj, 0); + PCPU_SET(md.clock, ia64_get_itc()); + ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload); ia64_set_itv(CLOCK_VECTOR); /* highest priority class */ ia64_srlz_d(); } diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c index 4a192fd79e3..9f7625279d9 100644 --- a/sys/ia64/ia64/genassym.c +++ b/sys/ia64/ia64/genassym.c @@ -91,7 +91,7 @@ ASSYM(MC_SPECIAL_RNAT, offsetof(mcontext_t, mc_special.rnat)); ASSYM(PAGE_SHIFT, PAGE_SHIFT); ASSYM(PAGE_SIZE, PAGE_SIZE); -ASSYM(PC_CURRENT_PMAP, offsetof(struct pcpu, pc_current_pmap)); +ASSYM(PC_CURRENT_PMAP, offsetof(struct pcpu, pc_md.current_pmap)); ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread)); ASSYM(PC_IDLETHREAD, offsetof(struct pcpu, pc_idlethread)); diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index a2b1ec5cd0d..1b5344d54cc 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -84,28 +84,6 @@ dummy_perf(unsigned long vector, struct trapframe *tf) void (*perf_irq)(unsigned long, struct trapframe *) = dummy_perf; -static unsigned int ints[MAXCPU]; -SYSCTL_OPAQUE(_debug, OID_AUTO, ints, CTLFLAG_RW, &ints, sizeof(ints), "IU", - ""); - -static unsigned int clks[MAXCPU]; -#ifdef SMP -SYSCTL_OPAQUE(_debug, OID_AUTO, clks, CTLFLAG_RW, &clks, sizeof(clks), "IU", - ""); -#else -SYSCTL_INT(_debug, OID_AUTO, clks, CTLFLAG_RW, clks, 0, ""); -#endif - -#ifdef SMP -static unsigned int asts[MAXCPU]; -SYSCTL_OPAQUE(_debug, OID_AUTO, asts, CTLFLAG_RW, &asts, sizeof(asts), "IU", - ""); - -static unsigned int rdvs[MAXCPU]; -SYSCTL_OPAQUE(_debug, OID_AUTO, rdvs, CTLFLAG_RW, &rdvs, sizeof(rdvs), "IU", - ""); -#endif - SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics"); static int adjust_edges = 0; @@ -139,6 +117,8 @@ interrupt(struct trapframe *tf) td = curthread; + PCPU_INC(cnt.v_intr); + vector = tf->tf_special.ifa; next: @@ -149,33 +129,35 @@ interrupt(struct trapframe *tf) * to add it to this switch-like construct. */ if (vector == 0) { + PCPU_INC(md.stats.pcs_nextints); inta = ib->ib_inta; - printf("ExtINT interrupt: vector=%u\n", (int)inta); if (inta == 15) { + PCPU_INC(md.stats.pcs_nstrays); __asm __volatile("mov cr.eoi = r0;; srlz.d"); goto stray; } vector = (int)inta; - } else if (vector == 15) + } else if (vector == 15) { + PCPU_INC(md.stats.pcs_nstrays); goto stray; + } if (vector == CLOCK_VECTOR) {/* clock interrupt */ /* CTR0(KTR_INTR, "clock interrupt"); */ itc = ia64_get_itc(); - PCPU_INC(cnt.v_intr); + PCPU_INC(md.stats.pcs_nclks); #ifdef EVCNT_COUNTERS clock_intr_evcnt.ev_count++; #else intrcnt[INTRCNT_CLOCK]++; #endif - clks[PCPU_GET(cpuid)]++; critical_enter(); - adj = PCPU_GET(clockadj); - clk = PCPU_GET(clock); + adj = PCPU_GET(md.clockadj); + clk = PCPU_GET(md.clock); delta = itc - clk; count = 0; while (delta >= ia64_clock_reload) { @@ -206,33 +188,36 @@ interrupt(struct trapframe *tf) adj = 0; adjust_excess++; } - PCPU_SET(clock, clk); - PCPU_SET(clockadj, adj); + PCPU_SET(md.clock, clk); + PCPU_SET(md.clockadj, adj); critical_exit(); ia64_srlz_d(); #ifdef SMP } else if (vector == ipi_vector[IPI_AST]) { - asts[PCPU_GET(cpuid)]++; + PCPU_INC(md.stats.pcs_nasts); CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid)); } else if (vector == ipi_vector[IPI_HIGH_FP]) { + PCPU_INC(md.stats.pcs_nhighfps); ia64_highfp_save_ipi(); } else if (vector == ipi_vector[IPI_RENDEZVOUS]) { - rdvs[PCPU_GET(cpuid)]++; + PCPU_INC(md.stats.pcs_nrdvs); CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid)); enable_intr(); smp_rendezvous_action(); disable_intr(); } else if (vector == ipi_vector[IPI_STOP]) { + PCPU_INC(md.stats.pcs_nstops); cpumask_t mybit = PCPU_GET(cpumask); - savectx(PCPU_PTR(pcb)); + savectx(PCPU_PTR(md.pcb)); atomic_set_int(&stopped_cpus, mybit); while ((started_cpus & mybit) == 0) cpu_spinwait(); atomic_clear_int(&started_cpus, mybit); atomic_clear_int(&stopped_cpus, mybit); } else if (vector == ipi_vector[IPI_PREEMPT]) { + PCPU_INC(md.stats.pcs_npreempts); CTR1(KTR_SMP, "IPI_PREEMPT, cpuid=%d", PCPU_GET(cpuid)); __asm __volatile("mov cr.eoi = r0;; srlz.d"); enable_intr(); @@ -241,7 +226,7 @@ interrupt(struct trapframe *tf) goto stray; #endif } else { - ints[PCPU_GET(cpuid)]++; + PCPU_INC(md.stats.pcs_nhwints); atomic_add_int(&td->td_intr_nesting_level, 1); ia64_dispatch_intr(tf, vector); atomic_subtract_int(&td->td_intr_nesting_level, 1); diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index b1b3b6fc8d7..0cfe95deb45 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -101,6 +101,8 @@ __FBSDID("$FreeBSD$"); #include +SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RD, 0, ""); + u_int64_t processor_frequency; u_int64_t bus_frequency; u_int64_t itc_frequency; @@ -139,8 +141,6 @@ SYSCTL_STRING(_hw, OID_AUTO, family, CTLFLAG_RD, cpu_family, 0, extern vm_offset_t ksym_start, ksym_end; #endif -static void cpu_startup(void *); -SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); struct msgbuf *msgbufp = NULL; @@ -247,9 +247,11 @@ identifycpu(void) } static void -cpu_startup(dummy) - void *dummy; +cpu_startup(void *dummy) { + char nodename[16]; + struct pcpu *pc; + struct pcpu_stats *pcs; /* * Good {morning,afternoon,evening,night}. @@ -302,7 +304,68 @@ cpu_startup(dummy) */ ia64_probe_sapics(); ia64_mca_init(); + + /* + * Create sysctl tree for per-CPU information. + */ + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + snprintf(nodename, sizeof(nodename), "%u", pc->pc_cpuid); + sysctl_ctx_init(&pc->pc_md.sysctl_ctx); + pc->pc_md.sysctl_tree = SYSCTL_ADD_NODE(&pc->pc_md.sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_machdep_cpu), OID_AUTO, nodename, + CTLFLAG_RD, NULL, ""); + if (pc->pc_md.sysctl_tree == NULL) + continue; + + pcs = &pc->pc_md.stats; + + SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, + SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, + "nasts", CTLFLAG_RD, &pcs->pcs_nasts, + "Number of IPI_AST interrupts"); + + SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, + SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, + "nclks", CTLFLAG_RD, &pcs->pcs_nclks, + "Number of clock interrupts"); + + SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, + SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, + "nextints", CTLFLAG_RD, &pcs->pcs_nextints, + "Number of ExtINT interrupts"); + + SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, + SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, + "nhighfps", CTLFLAG_RD, &pcs->pcs_nhighfps, + "Number of IPI_HIGH_FP interrupts"); + + SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, + SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, + "nhwints", CTLFLAG_RD, &pcs->pcs_nhwints, + "Number of hardware (device) interrupts"); + + SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, + SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, + "npreempts", CTLFLAG_RD, &pcs->pcs_npreempts, + "Number of IPI_PREEMPT interrupts"); + + SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, + SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, + "nrdvs", CTLFLAG_RD, &pcs->pcs_nrdvs, + "Number of IPI_RENDEZVOUS interrupts"); + + SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, + SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, + "nstops", CTLFLAG_RD, &pcs->pcs_nstops, + "Number of IPI_STOP interrupts"); + + SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, + SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, + "nstrays", CTLFLAG_RD, &pcs->pcs_nstrays, + "Number of stray vectors"); + } } +SYSINIT(cpu_startup, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); void cpu_boot(int howto) diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index 92e26216e48..020c71b0f83 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -76,7 +76,6 @@ void ia64_ap_startup(void); /* Variables used by os_boot_rendez and ia64_ap_startup */ struct pcpu *ap_pcpu; void *ap_stack; -uint64_t ap_vhpt; volatile int ap_delay; volatile int ap_awake; volatile int ap_spin; @@ -116,13 +115,15 @@ void ia64_ap_startup(void) { volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK; + uint64_t vhpt; int vector; pcpup = ap_pcpu; ia64_set_k4((intptr_t)pcpup); - map_vhpt(ap_vhpt); - ia64_set_pta(ap_vhpt + (1 << 8) + (pmap_vhpt_log2size << 2) + 1); + vhpt = PCPU_GET(md.vhpt); + map_vhpt(vhpt); + ia64_set_pta(vhpt + (1 << 8) + (pmap_vhpt_log2size << 2) + 1); ia64_srlz_i(); ap_awake = 1; @@ -225,7 +226,7 @@ cpu_mp_add(u_int acpiid, u_int apicid, u_int apiceid) pc = pcpup; pc->pc_acpi_id = acpiid; - pc->pc_lid = lid; + pc->pc_md.lid = lid; all_cpus |= (1UL << cpuid); } @@ -239,8 +240,8 @@ cpu_mp_announce() pc = pcpu_find(i); if (pc != NULL) { printf("cpu%d: ACPI Id=%x, SAPIC Id=%x, SAPIC Eid=%x", - i, pc->pc_acpi_id, LID_SAPIC_ID(pc->pc_lid), - LID_SAPIC_EID(pc->pc_lid)); + i, pc->pc_acpi_id, LID_SAPIC_ID(pc->pc_md.lid), + LID_SAPIC_EID(pc->pc_md.lid)); if (i == 0) printf(" (BSP)\n"); else @@ -257,13 +258,18 @@ cpu_mp_start() ap_spin = 1; SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { - pc->pc_current_pmap = kernel_pmap; + pc->pc_md.current_pmap = kernel_pmap; pc->pc_other_cpus = all_cpus & ~pc->pc_cpumask; if (pc->pc_cpuid > 0) { ap_pcpu = pc; + pc->pc_md.vhpt = pmap_alloc_vhpt(); + if (pc->pc_md.vhpt == 0) { + printf("SMP: WARNING: unable to allocate VHPT" + " for cpu%d", pc->pc_cpuid); + continue; + } ap_stack = malloc(KSTACK_PAGES * PAGE_SIZE, M_SMP, M_WAITOK); - ap_vhpt = pmap_vhpt_base[pc->pc_cpuid]; ap_delay = 2000; ap_awake = 0; @@ -275,13 +281,13 @@ cpu_mp_start() do { DELAY(1000); } while (--ap_delay > 0); - pc->pc_awake = ap_awake; + pc->pc_md.awake = ap_awake; if (!ap_awake) printf("SMP: WARNING: cpu%d did not wake up\n", pc->pc_cpuid); } else - pc->pc_awake = 1; + pc->pc_md.awake = 1; } } @@ -298,7 +304,7 @@ cpu_mp_unleash(void *dummy) smp_cpus = 0; SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { cpus++; - if (pc->pc_awake) { + if (pc->pc_md.awake) { kproc_create(ia64_store_mca_state, (void*)((uintptr_t)pc->pc_cpuid), NULL, 0, 0, "mca %u", pc->pc_cpuid); @@ -361,7 +367,7 @@ ipi_send(struct pcpu *cpu, int ipi) uint64_t vector; pipi = __MEMIO_ADDR(ia64_lapic_address | - ((cpu->pc_lid & LID_SAPIC_MASK) >> 12)); + ((cpu->pc_md.lid & LID_SAPIC_MASK) >> 12)); vector = (uint64_t)(ipi_vector[ipi] & 0xff); KASSERT(vector != 0, ("IPI %d is not assigned a vector", ipi)); *pipi = vector; diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index a5a2bc3f989..c738ea3e5fb 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -217,8 +217,6 @@ int pmap_vhpt_nbuckets; SYSCTL_INT(_machdep_vhpt, OID_AUTO, nbuckets, CTLFLAG_RD, &pmap_vhpt_nbuckets, 0, ""); -uint64_t pmap_vhpt_base[MAXCPU]; - int pmap_vhpt_log2size = 0; TUNABLE_INT("machdep.vhpt.log2size", &pmap_vhpt_log2size); SYSCTL_INT(_machdep_vhpt, OID_AUTO, log2size, CTLFLAG_RD, @@ -277,6 +275,40 @@ pmap_steal_memory(vm_size_t size) return va; } +static void +pmap_initialize_vhpt(vm_offset_t vhpt) +{ + struct ia64_lpte *pte; + u_int i; + + pte = (struct ia64_lpte *)vhpt; + for (i = 0; i < pmap_vhpt_nbuckets; i++) { + pte[i].pte = 0; + pte[i].itir = 0; + pte[i].tag = 1UL << 63; /* Invalid tag */ + pte[i].chain = (uintptr_t)(pmap_vhpt_bucket + i); + } +} + +#ifdef SMP +MALLOC_DECLARE(M_SMP); + +vm_offset_t +pmap_alloc_vhpt(void) +{ + vm_offset_t vhpt; + vm_size_t size; + + size = 1UL << pmap_vhpt_log2size; + vhpt = (uintptr_t)contigmalloc(size, M_SMP, 0, 0UL, ~0UL, size, 0UL); + if (vhpt != 0) { + vhpt = IA64_PHYS_TO_RR7(ia64_tpa(vhpt)); + pmap_initialize_vhpt(vhpt); + } + return (vhpt); +} +#endif + /* * Bootstrap the system enough to run with virtual memory. */ @@ -284,8 +316,7 @@ void pmap_bootstrap() { struct ia64_pal_result res; - struct ia64_lpte *pte; - vm_offset_t base, limit; + vm_offset_t base; size_t size; int i, j, count, ridbits; @@ -365,94 +396,52 @@ pmap_bootstrap() ; count = i+2; - /* - * Figure out a useful size for the VHPT, based on the size of - * physical memory and try to locate a region which is large - * enough to contain the VHPT (which must be a power of two in - * size and aligned to a natural boundary). - * We silently bump up the VHPT size to the minimum size if the - * user has set the tunable too small. Likewise, the VHPT size - * is silently capped to the maximum allowed. - */ TUNABLE_INT_FETCH("machdep.vhpt.log2size", &pmap_vhpt_log2size); - if (pmap_vhpt_log2size == 0) { + if (pmap_vhpt_log2size == 0) + pmap_vhpt_log2size = 20; + else if (pmap_vhpt_log2size < 15) pmap_vhpt_log2size = 15; - size = 1UL << pmap_vhpt_log2size; - while (size < Maxmem * 32) { - pmap_vhpt_log2size++; - size <<= 1; - } - } else if (pmap_vhpt_log2size < 15) - pmap_vhpt_log2size = 15; - if (pmap_vhpt_log2size > 61) + else if (pmap_vhpt_log2size > 61) pmap_vhpt_log2size = 61; - pmap_vhpt_base[0] = 0; - base = limit = 0; + base = 0; size = 1UL << pmap_vhpt_log2size; - while (pmap_vhpt_base[0] == 0) { - if (bootverbose) - printf("Trying VHPT size 0x%lx\n", size); - for (i = 0; i < count; i += 2) { - base = (phys_avail[i] + size - 1) & ~(size - 1); - limit = base + MAXCPU * size; - if (limit <= phys_avail[i+1]) - /* - * VHPT can fit in this region - */ - break; - } - if (!phys_avail[i]) { - /* Can't fit, try next smaller size. */ - pmap_vhpt_log2size--; - size >>= 1; - } else - pmap_vhpt_base[0] = IA64_PHYS_TO_RR7(base); + for (i = 0; i < count; i += 2) { + base = (phys_avail[i] + size - 1) & ~(size - 1); + if (base + size <= phys_avail[i+1]) + break; } - if (pmap_vhpt_log2size < 15) - panic("Can't find space for VHPT"); - - if (bootverbose) - printf("Putting VHPT at 0x%lx\n", base); + if (!phys_avail[i]) + panic("Unable to allocate VHPT"); if (base != phys_avail[i]) { /* Split this region. */ - if (bootverbose) - printf("Splitting [%p-%p]\n", (void *)phys_avail[i], - (void *)phys_avail[i+1]); for (j = count; j > i; j -= 2) { phys_avail[j] = phys_avail[j-2]; phys_avail[j+1] = phys_avail[j-2+1]; } phys_avail[i+1] = base; - phys_avail[i+2] = limit; + phys_avail[i+2] = base + size; } else - phys_avail[i] = limit; + phys_avail[i] = base + size; + + base = IA64_PHYS_TO_RR7(base); + PCPU_SET(md.vhpt, base); + if (bootverbose) + printf("VHPT: address=%#lx, size=%#lx\n", base, size); pmap_vhpt_nbuckets = size / sizeof(struct ia64_lpte); - pmap_vhpt_bucket = (void *)pmap_steal_memory(pmap_vhpt_nbuckets * sizeof(struct ia64_bucket)); - pte = (struct ia64_lpte *)pmap_vhpt_base[0]; for (i = 0; i < pmap_vhpt_nbuckets; i++) { - pte[i].pte = 0; - pte[i].itir = 0; - pte[i].tag = 1UL << 63; /* Invalid tag */ - pte[i].chain = (uintptr_t)(pmap_vhpt_bucket + i); - /* Stolen memory is zeroed! */ + /* Stolen memory is zeroed. */ mtx_init(&pmap_vhpt_bucket[i].mutex, "VHPT bucket lock", NULL, MTX_NOWITNESS | MTX_SPIN); } - for (i = 1; i < MAXCPU; i++) { - pmap_vhpt_base[i] = pmap_vhpt_base[i - 1] + size; - bcopy((void *)pmap_vhpt_base[i - 1], (void *)pmap_vhpt_base[i], - size); - } - - map_vhpt(pmap_vhpt_base[0]); - ia64_set_pta(pmap_vhpt_base[0] + (1 << 8) + - (pmap_vhpt_log2size << 2) + 1); + pmap_initialize_vhpt(base); + map_vhpt(base); + ia64_set_pta(base + (1 << 8) + (pmap_vhpt_log2size << 2) + 1); ia64_srlz_i(); virtual_avail = VM_MIN_KERNEL_ADDRESS; @@ -466,7 +455,7 @@ pmap_bootstrap() kernel_pmap->pm_rid[i] = 0; kernel_pmap->pm_active = 1; TAILQ_INIT(&kernel_pmap->pm_pvlist); - PCPU_SET(current_pmap, kernel_pmap); + PCPU_SET(md.current_pmap, kernel_pmap); /* * Region 5 is mapped via the vhpt. @@ -551,15 +540,16 @@ static void pmap_invalidate_page(pmap_t pmap, vm_offset_t va) { struct ia64_lpte *pte; - int i, vhpt_ofs; + struct pcpu *pc; + u_int vhpt_ofs; - KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)), + KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)), ("invalidating TLB for non-current pmap")); - vhpt_ofs = ia64_thash(va) - pmap_vhpt_base[PCPU_GET(cpuid)]; + vhpt_ofs = ia64_thash(va) - PCPU_GET(md.vhpt); critical_enter(); - for (i = 0; i < MAXCPU; i++) { - pte = (struct ia64_lpte *)(pmap_vhpt_base[i] + vhpt_ofs); + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + pte = (struct ia64_lpte *)(pc->pc_md.vhpt + vhpt_ofs); if (pte->tag == ia64_ttag(va)) pte->tag = 1UL << 63; } @@ -591,7 +581,7 @@ static void pmap_invalidate_all(pmap_t pmap) { - KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)), + KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)), ("invalidating TLB for non-current pmap")); #ifdef SMP @@ -1172,7 +1162,7 @@ pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte, vm_offset_t va, int error; vm_page_t m; - KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)), + KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)), ("removing pte for non-current pmap")); /* @@ -1340,7 +1330,7 @@ pmap_remove_page(pmap_t pmap, vm_offset_t va) { struct ia64_lpte *pte; - KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)), + KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)), ("removing page for non-current pmap")); pte = pmap_find_vhpt(va); @@ -2251,7 +2241,7 @@ pmap_switch(pmap_t pm) int i; critical_enter(); - prevpm = PCPU_GET(current_pmap); + prevpm = PCPU_GET(md.current_pmap); if (prevpm == pm) goto out; if (prevpm != NULL) @@ -2268,7 +2258,7 @@ pmap_switch(pmap_t pm) } atomic_set_32(&pm->pm_active, PCPU_GET(cpumask)); } - PCPU_SET(current_pmap, pm); + PCPU_SET(md.current_pmap, pm); ia64_srlz_d(); out: diff --git a/sys/ia64/include/kdb.h b/sys/ia64/include/kdb.h index d8a12e037b4..8a9cc3a1e3b 100644 --- a/sys/ia64/include/kdb.h +++ b/sys/ia64/include/kdb.h @@ -33,7 +33,7 @@ #include #include -#define KDB_STOPPEDPCB(pc) (&(pc)->pc_pcb) +#define KDB_STOPPEDPCB(pc) (&(pc)->pc_md.pcb) static __inline void kdb_cpu_clear_singlestep(void) diff --git a/sys/ia64/include/param.h b/sys/ia64/include/param.h index b844a84ca58..d868dfcf42a 100644 --- a/sys/ia64/include/param.h +++ b/sys/ia64/include/param.h @@ -70,7 +70,7 @@ #endif #if defined(SMP) || defined(KLD_MODULE) -#define MAXCPU 4 +#define MAXCPU 32 #else #define MAXCPU 1 #endif diff --git a/sys/ia64/include/pcpu.h b/sys/ia64/include/pcpu.h index c63573b9992..bc9fe0813d7 100644 --- a/sys/ia64/include/pcpu.h +++ b/sys/ia64/include/pcpu.h @@ -30,16 +30,39 @@ #ifndef _MACHINE_PCPU_H_ #define _MACHINE_PCPU_H_ +#include #include +struct pcpu_stats { + u_long pcs_nasts; /* IPI_AST counter. */ + u_long pcs_nclks; /* Clock interrupt counter. */ + u_long pcs_nextints; /* ExtINT counter. */ + u_long pcs_nhighfps; /* IPI_HIGH_FP counter. */ + u_long pcs_nhwints; /* Hardware int. counter. */ + u_long pcs_npreempts; /* IPI_PREEMPT counter. */ + u_long pcs_nrdvs; /* IPI_RENDEZVOUS counter. */ + u_long pcs_nstops; /* IPI_STOP counter. */ + u_long pcs_nstrays; /* Stray interrupt counter. */ +}; + +struct pcpu_md { + struct pcb pcb; /* Used by IPI_STOP */ + struct pmap *current_pmap; /* active pmap */ + vm_offset_t vhpt; /* Address of VHPT */ + uint64_t lid; /* local CPU ID */ + uint64_t clock; /* Clock counter. */ + uint64_t clockadj; /* Clock adjust. */ + uint32_t awake:1; /* CPU is awake? */ + struct pcpu_stats stats; /* Interrupt stats. */ +#ifdef _KERNEL + struct sysctl_ctx_list sysctl_ctx; + struct sysctl_oid *sysctl_tree; +#endif +}; + #define PCPU_MD_FIELDS \ - struct pcb pc_pcb; /* Used by IPI_STOP */ \ - struct pmap *pc_current_pmap; /* active pmap */ \ - uint64_t pc_lid; /* local CPU ID */ \ - uint64_t pc_clock; /* Clock counter. */ \ - uint64_t pc_clockadj; /* Clock adjust. */ \ - uint32_t pc_awake:1; /* CPU is awake? */ \ - uint32_t pc_acpi_id /* ACPI CPU id. */ + uint32_t pc_acpi_id; /* ACPI CPU id. */ \ + struct pcpu_md pc_md /* MD fields. */ #ifdef _KERNEL diff --git a/sys/ia64/include/pmap.h b/sys/ia64/include/pmap.h index c6b975477a7..f878d279c5f 100644 --- a/sys/ia64/include/pmap.h +++ b/sys/ia64/include/pmap.h @@ -125,6 +125,7 @@ extern int pmap_vhpt_log2size; #define pmap_unmapbios(va, sz) pmap_unmapdev(va, sz) vm_offset_t pmap_steal_memory(vm_size_t); +vm_offset_t pmap_alloc_vhpt(void); void pmap_bootstrap(void); void pmap_kenter(vm_offset_t va, vm_offset_t pa); vm_paddr_t pmap_kextract(vm_offset_t va); From 71e7360ed94d5ffb14ab957e0bfb620760c841e7 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 12 Dec 2009 10:37:31 +0000 Subject: [PATCH 0835/2592] MFC r200171, r200182, r200275, r200295, r200359: Introduce ATA_CAM kernel option, turning ata(4) controller drivers into cam(4) interface modules. When enabled, this option deprecates all ata(4) peripheral drivers (ad, acd, ...) and interfaces and allows cam(4) drivers (ada, cd, ...) and interfaces to be natively used instead. As side effect of this, ata(4) mode setting code was completely rewritten to make controller API more strict and permit above change. While doing this, SATA revision was separated from PATA mode. It allows DMA-incapable SATA devices to operate and makes hw.ata.(ata|atapi)_dma tunable work again. Also allow ata(4) controller drivers (except some specific or broken ones) to handle larger data transfers. Previous constraint of 64K was artificial and is not really required by PCI ATA BM specification or hardware. Submitted by: nwitehorn (powerpc part) --- sbin/atacontrol/atacontrol.c | 23 +- sys/arm/mv/mv_sata.c | 25 +- sys/cam/ata/ata_xpt.c | 76 +++- sys/cam/scsi/scsi_cd.c | 9 +- sys/conf/NOTES | 6 + sys/conf/options | 1 + sys/dev/ata/ata-all.c | 574 +++++++++++++++++++++++- sys/dev/ata/ata-all.h | 33 +- sys/dev/ata/ata-disk.c | 7 +- sys/dev/ata/ata-dma.c | 2 +- sys/dev/ata/ata-lowlevel.c | 9 + sys/dev/ata/ata-pci.c | 68 +-- sys/dev/ata/ata-pci.h | 7 +- sys/dev/ata/ata-queue.c | 11 +- sys/dev/ata/ata-sata.c | 39 +- sys/dev/ata/ata_if.m | 19 +- sys/dev/ata/atapi-cd.c | 12 +- sys/dev/ata/atapi-fd.c | 9 +- sys/dev/ata/atapi-tape.c | 12 +- sys/dev/ata/chipsets/ata-acard.c | 92 ++-- sys/dev/ata/chipsets/ata-acerlabs.c | 94 ++-- sys/dev/ata/chipsets/ata-ahci.c | 3 + sys/dev/ata/chipsets/ata-amd.c | 67 ++- sys/dev/ata/chipsets/ata-ati.c | 91 ++-- sys/dev/ata/chipsets/ata-cenatek.c | 30 +- sys/dev/ata/chipsets/ata-cypress.c | 31 +- sys/dev/ata/chipsets/ata-cyrix.c | 77 ++-- sys/dev/ata/chipsets/ata-highpoint.c | 87 ++-- sys/dev/ata/chipsets/ata-intel.c | 179 ++++---- sys/dev/ata/chipsets/ata-ite.c | 219 +++++---- sys/dev/ata/chipsets/ata-jmicron.c | 46 +- sys/dev/ata/chipsets/ata-marvell.c | 28 +- sys/dev/ata/chipsets/ata-micron.c | 33 +- sys/dev/ata/chipsets/ata-national.c | 74 +-- sys/dev/ata/chipsets/ata-netcell.c | 17 +- sys/dev/ata/chipsets/ata-nvidia.c | 52 +-- sys/dev/ata/chipsets/ata-promise.c | 66 ++- sys/dev/ata/chipsets/ata-serverworks.c | 97 ++-- sys/dev/ata/chipsets/ata-siliconimage.c | 180 +++----- sys/dev/ata/chipsets/ata-sis.c | 67 ++- sys/dev/ata/chipsets/ata-via.c | 117 +++-- sys/powerpc/powermac/ata_dbdma.c | 3 +- sys/powerpc/powermac/ata_kauai.c | 41 +- sys/powerpc/powermac/ata_macio.c | 40 +- sys/powerpc/psim/ata_iobus.c | 10 +- 45 files changed, 1610 insertions(+), 1173 deletions(-) diff --git a/sbin/atacontrol/atacontrol.c b/sbin/atacontrol/atacontrol.c index 49e4fa231ae..29599eb3dc4 100644 --- a/sbin/atacontrol/atacontrol.c +++ b/sbin/atacontrol/atacontrol.c @@ -42,7 +42,7 @@ static const char * mode2str(int mode) { - switch (mode) { + switch (mode & 0xff) { case ATA_PIO: return "BIOSPIO"; case ATA_PIO0: return "PIO0"; case ATA_PIO1: return "PIO1"; @@ -59,13 +59,23 @@ mode2str(int mode) case ATA_UDMA4: return "UDMA66"; case ATA_UDMA5: return "UDMA100"; case ATA_UDMA6: return "UDMA133"; - case ATA_SA150: return "SATA150"; - case ATA_SA300: return "SATA300"; case ATA_DMA: return "BIOSDMA"; default: return "???"; } } +static const char * +satarev2str(int mode) +{ + switch ((mode & 0xff00) >> 8) { + case 0: return ""; + case 1: return "SATA 1.5Gb/s"; + case 2: return "SATA 3Gb/s"; + case 3: return "SATA 6Gb/s"; + default: return "???"; + } +} + static int str2mode(char *str) { @@ -79,7 +89,9 @@ str2mode(char *str) if (!strcasecmp(str, "WDMA1")) return ATA_WDMA1; if (!strcasecmp(str, "WDMA2")) return ATA_WDMA2; if (!strcasecmp(str, "UDMA0")) return ATA_UDMA0; + if (!strcasecmp(str, "UDMA16")) return ATA_UDMA0; if (!strcasecmp(str, "UDMA1")) return ATA_UDMA1; + if (!strcasecmp(str, "UDMA25")) return ATA_UDMA1; if (!strcasecmp(str, "UDMA2")) return ATA_UDMA2; if (!strcasecmp(str, "UDMA33")) return ATA_UDMA2; if (!strcasecmp(str, "UDMA3")) return ATA_UDMA3; @@ -90,8 +102,6 @@ str2mode(char *str) if (!strcasecmp(str, "UDMA100")) return ATA_UDMA5; if (!strcasecmp(str, "UDMA6")) return ATA_UDMA6; if (!strcasecmp(str, "UDMA133")) return ATA_UDMA6; - if (!strcasecmp(str, "SATA150")) return ATA_SA150; - if (!strcasecmp(str, "SATA300")) return ATA_SA300; if (!strcasecmp(str, "BIOSDMA")) return ATA_DMA; return -1; } @@ -382,7 +392,8 @@ main(int argc, char **argv) if (argc == 3 || argc == 4) { if (ioctl(fd, IOCATAGMODE, &mode) < 0) err(1, "ioctl(IOCATAGMODE)"); - printf("current mode = %s\n", mode2str(mode)); + printf("current mode = %s %s\n", + mode2str(mode), satarev2str(mode)); } exit(EX_OK); } diff --git a/sys/arm/mv/mv_sata.c b/sys/arm/mv/mv_sata.c index 35939563c50..01713daa27c 100644 --- a/sys/arm/mv/mv_sata.c +++ b/sys/arm/mv/mv_sata.c @@ -136,7 +136,8 @@ static int sata_channel_detach(device_t dev); static int sata_channel_begin_transaction(struct ata_request *request); static int sata_channel_end_transaction(struct ata_request *request); static int sata_channel_status(device_t dev); -static void sata_channel_setmode(device_t parent, device_t dev); +static int sata_channel_setmode(device_t dev, int target, int mode); +static int sata_channel_getrev(device_t dev, int target); static void sata_channel_reset(device_t dev); static void sata_channel_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); @@ -423,7 +424,7 @@ sata_channel_attach(device_t dev) ch->dev = dev; ch->unit = device_get_unit(dev); - ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE; + ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE | ATA_SATA; /* Set legacy ATA resources. */ for (i = ATA_DATA; i <= ATA_COMMAND; i++) { @@ -748,19 +749,22 @@ sata_channel_reset(device_t dev) SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF); } -static void -sata_channel_setmode(device_t parent, device_t dev) +static int +sata_channel_setmode(device_t parent, int target, int mode) { - struct ata_device *atadev; - - atadev = device_get_softc(dev); /* Disable EDMA before using legacy registers */ sata_edma_ctrl(parent, 0); + return (ata_sata_setmode(parent, target, mode)); +} - ata_sata_setmode(dev, ATA_PIO_MAX); - if (atadev->mode >= ATA_DMA) - ata_sata_setmode(dev, atadev->mode); +static int +sata_channel_getrev(device_t parent, int target) +{ + + /* Disable EDMA before using legacy registers */ + sata_edma_ctrl(parent, 0); + return (ata_sata_getrev(parent, target)); } static void @@ -849,6 +853,7 @@ static device_method_t sata_channel_methods[] = { /* ATA channel interface */ DEVMETHOD(ata_reset, sata_channel_reset), DEVMETHOD(ata_setmode, sata_channel_setmode), + DEVMETHOD(ata_getrev, sata_channel_getrev), { 0, 0 } }; diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 89f51538602..a162623547b 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -366,7 +366,7 @@ negotiate: cts.xport_specific.sata.valid = CTS_SATA_VALID_MODE; } xpt_action((union ccb *)&cts); - /* Fetch user modes from SIM. */ + /* Fetch current modes from SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; @@ -395,10 +395,25 @@ negotiate: } case PROBE_SET_MULTI: { - u_int sectors; - - sectors = max(1, min(ident_buf->sectors_intr & 0xff, 16)); + u_int sectors, bytecount; + bytecount = 8192; /* SATA maximum */ + /* Fetch user bytecount from SIM. */ + bzero(&cts, sizeof(cts)); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; + cts.type = CTS_TYPE_USER_SETTINGS; + xpt_action((union ccb *)&cts); + if (path->device->transport == XPORT_ATA) { + if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) + bytecount = cts.xport_specific.ata.bytecount; + } else { + if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) + bytecount = cts.xport_specific.sata.bytecount; + } + /* Honor device capabilities. */ + sectors = max(1, min(ident_buf->sectors_intr & 0xff, + bytecount / ata_logical_sector_size(ident_buf))); /* Report bytecount to SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); @@ -414,6 +429,20 @@ negotiate: cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT; } xpt_action((union ccb *)&cts); + /* Fetch current bytecount from SIM. */ + bzero(&cts, sizeof(cts)); + 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); + if (path->device->transport == XPORT_ATA) { + if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) + bytecount = cts.xport_specific.ata.bytecount; + } else { + if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) + bytecount = cts.xport_specific.sata.bytecount; + } + sectors = bytecount / ata_logical_sector_size(ident_buf); cam_fill_ataio(ataio, 1, @@ -427,6 +456,45 @@ negotiate: break; } case PROBE_INQUIRY: + { + u_int bytecount; + + bytecount = 8192; /* SATA maximum */ + /* Fetch user bytecount from SIM. */ + bzero(&cts, sizeof(cts)); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; + cts.type = CTS_TYPE_USER_SETTINGS; + xpt_action((union ccb *)&cts); + if (path->device->transport == XPORT_ATA) { + if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) + bytecount = cts.xport_specific.ata.bytecount; + } else { + if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) + bytecount = cts.xport_specific.sata.bytecount; + } + /* Honor device capabilities. */ + bytecount &= ~1; + bytecount = max(2, min(65534, bytecount)); + if (ident_buf->satacapabilities != 0x0000 && + ident_buf->satacapabilities != 0xffff) { + bytecount = min(8192, bytecount); + } + /* 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 = bytecount; + cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT; + } else { + cts.xport_specific.sata.bytecount = bytecount; + cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT; + } + xpt_action((union ccb *)&cts); + /* FALLTHROUGH */ + } case PROBE_FULL_INQUIRY: { u_int inquiry_len; diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index 7bd6158f869..a6dabc2e96c 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -673,6 +673,7 @@ cdregister(struct cam_periph *periph, void *arg) softc->quirks = CD_Q_NONE; /* Check if the SIM does not want 6 byte 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); @@ -726,6 +727,12 @@ cdregister(struct cam_periph *periph, void *arg) softc->disk->d_name = "cd"; softc->disk->d_unit = periph->unit_number; softc->disk->d_drv1 = periph; + if (cpi.maxio == 0) + softc->disk->d_maxsize = DFLTPHYS; /* traditional default */ + else if (cpi.maxio > MAXPHYS) + softc->disk->d_maxsize = MAXPHYS; /* for safety */ + else + softc->disk->d_maxsize = cpi.maxio; softc->disk->d_flags = 0; disk_create(softc->disk, DISK_VERSION); cam_periph_lock(periph); @@ -2768,7 +2775,6 @@ cdcheckmedia(struct cam_periph *periph) softc = (struct cd_softc *)periph->softc; cdprevent(periph, PR_PREVENT); - softc->disk->d_maxsize = DFLTPHYS; softc->disk->d_sectorsize = 2048; softc->disk->d_mediasize = 0; @@ -2870,7 +2876,6 @@ cdcheckmedia(struct cam_periph *periph) } softc->flags |= CD_FLAG_VALID_TOC; - softc->disk->d_maxsize = DFLTPHYS; softc->disk->d_sectorsize = softc->params.blksize; softc->disk->d_mediasize = (off_t)softc->params.blksize * softc->params.disksize; diff --git a/sys/conf/NOTES b/sys/conf/NOTES index b74ac72722a..57f2dfd6186 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1718,9 +1718,15 @@ hint.ata.1.irq="15" # else the device numbers are dynamically allocated. # ATA_REQUEST_TIMEOUT: the number of seconds to wait for an ATA request # before timing out. +# ATA_CAM: Turn ata(4) subsystem controller drivers into cam(4) +# interface modules. This deprecates all ata(4) +# peripheral device drivers (atadisk, ataraid, atapicd, +# atapifd. atapist, atapicam) and all user-level APIs. +# cam(4) drivers and APIs will be connected instead. options ATA_STATIC_ID #options ATA_REQUEST_TIMEOUT=10 +#options ATA_CAM # # Standard floppy disk controllers and floppy tapes, supports diff --git a/sys/conf/options b/sys/conf/options index f73ed162b2f..5405559567e 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -351,6 +351,7 @@ ISCSI_INITIATOR_DEBUG opt_iscsi_initiator.h ATA_STATIC_ID opt_ata.h ATA_NOPCI opt_ata.h ATA_REQUEST_TIMEOUT opt_ata.h +ATA_CAM opt_ata.h # Net stuff. ACCEPT_FILTER_DATA diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index a1a6f27556a..2fc59879840 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -50,6 +50,16 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef ATA_CAM +#include +#include +#include +#include +#include +#include +#endif + +#ifndef ATA_CAM /* device structure */ static d_ioctl_t ata_ioctl; static struct cdevsw ata_cdevsw = { @@ -58,14 +68,21 @@ static struct cdevsw ata_cdevsw = { .d_ioctl = ata_ioctl, .d_name = "ata", }; +#endif /* prototypes */ +#ifndef ATA_CAM static void ata_boot_attach(void); static device_t ata_add_child(device_t, struct ata_device *, int); +#else +static void ataaction(struct cam_sim *sim, union ccb *ccb); +static void atapoll(struct cam_sim *sim); +#endif static void ata_conn_event(void *, int); static void bswap(int8_t *, int); static void btrim(int8_t *, int); static void bpack(int8_t *, int8_t *, int); +static void ata_interrupt_locked(void *data); /* global vars */ MALLOC_DEFINE(M_ATA, "ata_generic", "ATA driver generic layer"); @@ -115,6 +132,10 @@ ata_attach(device_t dev) { struct ata_channel *ch = device_get_softc(dev); int error, rid; +#ifdef ATA_CAM + struct cam_devq *devq; + int i; +#endif /* check that we have a virgin channel to attach */ if (ch->r_irq) @@ -129,11 +150,23 @@ ata_attach(device_t dev) mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF); TAILQ_INIT(&ch->ata_queue); TASK_INIT(&ch->conntask, 0, ata_conn_event, dev); +#ifdef ATA_CAM + for (i = 0; i < 16; i++) { + ch->user[i].mode = 0; + if (ch->flags & ATA_SATA) + ch->user[i].bytecount = 8192; + else + ch->user[i].bytecount = MAXPHYS; + ch->curr[i] = ch->user[i]; + } +#endif /* reset the controller HW, the channel and device(s) */ while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit) pause("ataatch", 1); +#ifndef ATA_CAM ATA_RESET(dev); +#endif ATA_LOCKING(dev, ATA_LF_UNLOCK); /* allocate DMA resources if DMA HW present*/ @@ -154,18 +187,61 @@ ata_attach(device_t dev) return error; } +#ifndef ATA_CAM /* probe and attach devices on this channel unless we are in early boot */ if (!ata_delayed_attach) ata_identify(dev); - return 0; + return (0); +#else + mtx_lock(&ch->state_mtx); + /* Create the device queue for our SIM. */ + devq = cam_simq_alloc(1); + if (devq == NULL) { + device_printf(dev, "Unable to allocate simq\n"); + error = ENOMEM; + goto err1; + } + /* Construct SIM entry */ + ch->sim = cam_sim_alloc(ataaction, atapoll, "ata", ch, + device_get_unit(dev), &ch->state_mtx, 1, 0, devq); + if (ch->sim == NULL) { + device_printf(dev, "unable to allocate sim\n"); + error = ENOMEM; + goto err2; + } + if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) { + device_printf(dev, "unable to register xpt bus\n"); + error = ENXIO; + goto err2; + } + if (xpt_create_path(&ch->path, /*periph*/NULL, cam_sim_path(ch->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + device_printf(dev, "unable to create path\n"); + error = ENXIO; + goto err3; + } + mtx_unlock(&ch->state_mtx); + return (0); + +err3: + xpt_bus_deregister(cam_sim_path(ch->sim)); +err2: + cam_sim_free(ch->sim, /*free_devq*/TRUE); +err1: + bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); + mtx_unlock(&ch->state_mtx); + return (error); +#endif } int ata_detach(device_t dev) { struct ata_channel *ch = device_get_softc(dev); +#ifndef ATA_CAM device_t *children; int nchildren, i; +#endif /* check that we have a valid channel to detach */ if (!ch->r_irq) @@ -176,6 +252,7 @@ ata_detach(device_t dev) ch->state |= ATA_STALL_QUEUE; mtx_unlock(&ch->state_mtx); +#ifndef ATA_CAM /* detach & delete all children */ if (!device_get_children(dev, &children, &nchildren)) { for (i = 0; i < nchildren; i++) @@ -183,8 +260,18 @@ ata_detach(device_t dev) device_delete_child(dev, children[i]); free(children, M_TEMP); } +#endif taskqueue_drain(taskqueue_thread, &ch->conntask); +#ifdef ATA_CAM + mtx_lock(&ch->state_mtx); + xpt_async(AC_LOST_DEVICE, ch->path, NULL); + xpt_free_path(ch->path); + xpt_bus_deregister(cam_sim_path(ch->sim)); + cam_sim_free(ch->sim, /*free_devq*/TRUE); + mtx_unlock(&ch->state_mtx); +#endif + /* release resources */ bus_teardown_intr(dev, ch->r_irq, ch->ih); bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); @@ -203,8 +290,11 @@ static void ata_conn_event(void *context, int dummy) { device_t dev = (device_t)context; + struct ata_channel *ch = device_get_softc(dev); + mtx_lock(&ch->state_mtx); ata_reinit(dev); + mtx_unlock(&ch->state_mtx); } int @@ -212,6 +302,7 @@ ata_reinit(device_t dev) { struct ata_channel *ch = device_get_softc(dev); struct ata_request *request; +#ifndef ATA_CAM device_t *children; int nchildren, i; @@ -298,7 +389,23 @@ ata_reinit(device_t dev) /* kick off requests on the queue */ ata_start(dev); - return 0; +#else + if ((request = ch->running)) { + ch->running = NULL; + if (ch->state == ATA_ACTIVE) + ch->state = ATA_IDLE; + callout_stop(&request->callout); + if (ch->dma.unload) + ch->dma.unload(request); + request->result = ERESTART; + ata_cam_end_transaction(dev, request); + } + /* reset the controller HW, the channel and device(s) */ + ATA_RESET(dev); + /* Tell the XPT about the event */ + xpt_async(AC_BUS_RESET, ch->path, NULL); +#endif + return(0); } int @@ -310,6 +417,7 @@ ata_suspend(device_t dev) if (!dev || !(ch = device_get_softc(dev))) return ENXIO; +#ifndef ATA_CAM /* wait for the channel to be IDLE or detached before suspending */ while (ch->r_irq) { mtx_lock(&ch->state_mtx); @@ -322,7 +430,8 @@ ata_suspend(device_t dev) tsleep(ch, PRIBIO, "atasusp", hz/10); } ATA_LOCKING(dev, ATA_LF_UNLOCK); - return 0; +#endif + return(0); } int @@ -337,18 +446,36 @@ ata_resume(device_t dev) /* reinit the devices, we dont know what mode/state they are in */ error = ata_reinit(dev); +#ifndef ATA_CAM /* kick off requests on the queue */ ata_start(dev); +#endif return error; } void ata_interrupt(void *data) +{ +#ifdef ATA_CAM + struct ata_channel *ch = (struct ata_channel *)data; + + mtx_lock(&ch->state_mtx); +#endif + ata_interrupt_locked(data); +#ifdef ATA_CAM + mtx_unlock(&ch->state_mtx); +#endif +} + +static void +ata_interrupt_locked(void *data) { struct ata_channel *ch = (struct ata_channel *)data; struct ata_request *request; +#ifndef ATA_CAM mtx_lock(&ch->state_mtx); +#endif do { /* ignore interrupt if its not for us */ if (ch->hw.status && !ch->hw.status(ch->dev)) @@ -374,18 +501,71 @@ ata_interrupt(void *data) ch->running = NULL; if (ch->state == ATA_ACTIVE) ch->state = ATA_IDLE; +#ifdef ATA_CAM + ata_cam_end_transaction(ch->dev, request); +#else mtx_unlock(&ch->state_mtx); ATA_LOCKING(ch->dev, ATA_LF_UNLOCK); ata_finish(request); +#endif return; } } while (0); +#ifndef ATA_CAM mtx_unlock(&ch->state_mtx); +#endif +} + +void +ata_print_cable(device_t dev, u_int8_t *who) +{ + device_printf(dev, + "DMA limited to UDMA33, %s found non-ATA66 cable\n", who); +} + +int +ata_check_80pin(device_t dev, int mode) +{ + struct ata_device *atadev = device_get_softc(dev); + + if (!ata_dma_check_80pin) { + if (bootverbose) + device_printf(dev, "Skipping 80pin cable check\n"); + return mode; + } + + if (mode > ATA_UDMA2 && !(atadev->param.hwres & ATA_CABLE_ID)) { + ata_print_cable(dev, "device"); + mode = ATA_UDMA2; + } + return mode; +} + +void +ata_setmode(device_t dev) +{ + struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + struct ata_device *atadev = device_get_softc(dev); + int error, mode, pmode; + + mode = atadev->mode; + do { + pmode = mode = ata_limit_mode(dev, mode, ATA_DMA_MAX); + mode = ATA_SETMODE(device_get_parent(dev), atadev->unit, mode); + if ((ch->flags & (ATA_CHECKS_CABLE | ATA_SATA)) == 0) + mode = ata_check_80pin(dev, mode); + } while (pmode != mode); /* Interate till successfull negotiation. */ + error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); + if (bootverbose) + device_printf(dev, "%ssetting %s\n", + (error) ? "FAILURE " : "", ata_mode2str(mode)); + atadev->mode = mode; } /* * device related interfaces */ +#ifndef ATA_CAM static int ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int32_t flag, struct thread *td) @@ -467,6 +647,7 @@ ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data, } return error; } +#endif int ata_device_ioctl(device_t dev, u_long cmd, caddr_t data) @@ -549,11 +730,12 @@ ata_device_ioctl(device_t dev, u_long cmd, caddr_t data) case IOCATASMODE: atadev->mode = *mode; - ATA_SETMODE(device_get_parent(dev), dev); + ata_setmode(dev); return 0; case IOCATAGMODE: - *mode = atadev->mode; + *mode = atadev->mode | + (ATA_GETREV(device_get_parent(dev), atadev->unit) << 8); return 0; case IOCATASSPINDOWN: atadev->spindown = *mode; @@ -566,6 +748,7 @@ ata_device_ioctl(device_t dev, u_long cmd, caddr_t data) } } +#ifndef ATA_CAM static void ata_boot_attach(void) { @@ -590,11 +773,12 @@ ata_boot_attach(void) mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */ } - +#endif /* * misc support functions */ +#ifndef ATA_CAM static device_t ata_add_child(device_t parent, struct ata_device *atadev, int unit) { @@ -609,6 +793,7 @@ ata_add_child(device_t parent, struct ata_device *atadev, int unit) } return child; } +#endif int ata_getparam(struct ata_device *atadev, int init) @@ -705,6 +890,7 @@ ata_getparam(struct ata_device *atadev, int init) return error; } +#ifndef ATA_CAM int ata_identify(device_t dev) { @@ -778,6 +964,7 @@ ata_identify(device_t dev) mtx_unlock(&Giant); return 0; } +#endif void ata_default_registers(device_t dev) @@ -920,7 +1107,7 @@ ata_unit2str(struct ata_device *atadev) return str; } -char * +const char * ata_mode2str(int mode) { switch (mode) { @@ -950,6 +1137,18 @@ ata_mode2str(int mode) } } +const char * +ata_satarev2str(int rev) +{ + switch (rev) { + case 0: return ""; + case 1: return "SATA 1.5Gb/s"; + case 2: return "SATA 3Gb/s"; + case 3: return "SATA 6Gb/s"; + default: return "???"; + } +} + int ata_atapi(device_t dev) { @@ -1081,6 +1280,358 @@ bpack(int8_t *src, int8_t *dst, int len) dst[j] = 0x00; } +#ifdef ATA_CAM +void +ata_cam_begin_transaction(device_t dev, union ccb *ccb) +{ + struct ata_channel *ch = device_get_softc(dev); + struct ata_request *request; + + if (!(request = ata_alloc_request())) { + device_printf(dev, "FAILURE - out of memory in start\n"); + ccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(ccb); + return; + } + bzero(request, sizeof(*request)); + + /* setup request */ + request->dev = NULL; + request->parent = dev; + request->unit = ccb->ccb_h.target_id; + if (ccb->ccb_h.func_code == XPT_ATA_IO) { + request->data = ccb->ataio.data_ptr; + request->bytecount = ccb->ataio.dxfer_len; + request->u.ata.command = ccb->ataio.cmd.command; + request->u.ata.feature = ((uint16_t)ccb->ataio.cmd.features_exp << 8) | + (uint16_t)ccb->ataio.cmd.features; + request->u.ata.count = ((uint16_t)ccb->ataio.cmd.sector_count_exp << 8) | + (uint16_t)ccb->ataio.cmd.sector_count; + if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) { + request->flags |= ATA_R_48BIT; + request->u.ata.lba = + ((uint64_t)ccb->ataio.cmd.lba_high_exp << 40) | + ((uint64_t)ccb->ataio.cmd.lba_mid_exp << 32) | + ((uint64_t)ccb->ataio.cmd.lba_low_exp << 24); + } else { + request->u.ata.lba = + ((uint64_t)(ccb->ataio.cmd.device & 0x0f) << 24); + } + request->u.ata.lba |= ((uint64_t)ccb->ataio.cmd.lba_high << 16) | + ((uint64_t)ccb->ataio.cmd.lba_mid << 8) | + (uint64_t)ccb->ataio.cmd.lba_low; + if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && + ccb->ataio.cmd.flags & CAM_ATAIO_DMA) + request->flags |= ATA_R_DMA; + if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) + request->flags |= ATA_R_READ; + if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) + request->flags |= ATA_R_WRITE; + } else { + request->data = ccb->csio.data_ptr; + request->bytecount = ccb->csio.dxfer_len; + bcopy((ccb->ccb_h.flags & CAM_CDB_POINTER) ? + ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes, + request->u.atapi.ccb, ccb->csio.cdb_len); + request->flags |= ATA_R_ATAPI; + if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && + ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) + request->flags |= ATA_R_DMA; + if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) + request->flags |= ATA_R_READ; + if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) + request->flags |= ATA_R_WRITE; + } + request->transfersize = min(request->bytecount, + ch->curr[ccb->ccb_h.target_id].bytecount); +// request->callback = ad_done; + request->retries = 0; + request->timeout = (ccb->ccb_h.timeout + 999) / 1000; + callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED); + request->ccb = ccb; + + ch->running = request; + ch->state = ATA_ACTIVE; + if (ch->hw.begin_transaction(request) == ATA_OP_FINISHED) { + ch->running = NULL; + ch->state = ATA_IDLE; + ata_cam_end_transaction(dev, request); + return; + } +} + +void +ata_cam_end_transaction(device_t dev, struct ata_request *request) +{ + struct ata_channel *ch = device_get_softc(dev); + union ccb *ccb = request->ccb; + int fatalerr = 0; + + ccb->ccb_h.status &= ~CAM_STATUS_MASK; + if (request->flags & ATA_R_TIMEOUT) { + xpt_freeze_simq(ch->sim, 1); + ccb->ccb_h.status &= ~CAM_STATUS_MASK; + ccb->ccb_h.status |= CAM_CMD_TIMEOUT | CAM_RELEASE_SIMQ; + fatalerr = 1; + } else if (request->status & ATA_S_ERROR) { + if (ccb->ccb_h.func_code == XPT_ATA_IO) { + ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR; + } else { + ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; + ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; + } + } else if (request->result == ERESTART) + ccb->ccb_h.status |= CAM_REQUEUE_REQ; + else if (request->result != 0) + ccb->ccb_h.status |= CAM_REQ_CMP_ERR; + else + ccb->ccb_h.status |= CAM_REQ_CMP; + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP && + !(ccb->ccb_h.status & CAM_DEV_QFRZN)) { + xpt_freeze_devq(ccb->ccb_h.path, 1); + ccb->ccb_h.status |= CAM_DEV_QFRZN; + } + if (ccb->ccb_h.func_code == XPT_ATA_IO && + ((request->status & ATA_S_ERROR) || + (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT))) { + struct ata_res *res = &ccb->ataio.res; + res->status = request->status; + res->error = request->error; + res->lba_low = request->u.ata.lba; + res->lba_mid = request->u.ata.lba >> 8; + res->lba_high = request->u.ata.lba >> 16; + res->device = request->u.ata.lba >> 24; + res->lba_low_exp = request->u.ata.lba >> 24; + res->lba_mid_exp = request->u.ata.lba >> 32; + res->lba_high_exp = request->u.ata.lba >> 40; + res->sector_count = request->u.ata.count; + res->sector_count_exp = request->u.ata.count >> 8; + } + ata_free_request(request); + xpt_done(ccb); + /* Do error recovery if needed. */ + if (fatalerr) + ata_reinit(dev); +} + +static void +ataaction(struct cam_sim *sim, union ccb *ccb) +{ + device_t dev; + struct ata_channel *ch; + + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ataaction func_code=%x\n", + ccb->ccb_h.func_code)); + + ch = (struct ata_channel *)cam_sim_softc(sim); + dev = ch->dev; + switch (ccb->ccb_h.func_code) { + /* Common cases first */ + case XPT_ATA_IO: /* Execute the requested I/O operation */ + case XPT_SCSI_IO: + if ((ch->devices & ((ATA_ATA_MASTER | ATA_ATAPI_MASTER) + << ccb->ccb_h.target_id)) == 0) { + ccb->ccb_h.status = CAM_SEL_TIMEOUT; + xpt_done(ccb); + break; + } + if (ch->running) + device_printf(dev, "already running!\n"); + if (ccb->ccb_h.func_code == XPT_ATA_IO && + (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && + (ccb->ataio.cmd.control & ATA_A_RESET)) { + struct ata_res *res = &ccb->ataio.res; + + bzero(res, sizeof(*res)); + if (ch->devices & (ATA_ATA_MASTER << ccb->ccb_h.target_id)) { + res->lba_high = 0; + res->lba_mid = 0; + } else { + res->lba_high = 0xeb; + res->lba_mid = 0x14; + } + ccb->ccb_h.status = CAM_REQ_CMP; + xpt_done(ccb); + break; + } + ata_cam_begin_transaction(dev, ccb); + break; + case XPT_EN_LUN: /* Enable LUN as a target */ + case XPT_TARGET_IO: /* Execute target I/O request */ + case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ + case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ + case XPT_ABORT: /* Abort the specified CCB */ + /* XXX Implement */ + ccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(ccb); + break; + case XPT_SET_TRAN_SETTINGS: + { + struct ccb_trans_settings *cts = &ccb->cts; + struct ata_cam_device *d; + + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + d = &ch->curr[ccb->ccb_h.target_id]; + else + d = &ch->user[ccb->ccb_h.target_id]; + if ((ch->flags & ATA_SATA) && (ch->flags & ATA_NO_SLAVE)) { + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION) + d->revision = cts->xport_specific.sata.revision; + if (cts->xport_specific.ata.valid & CTS_SATA_VALID_MODE) { + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + d->mode = ATA_SETMODE(ch->dev, + ccb->ccb_h.target_id, + cts->xport_specific.sata.mode); + } else + d->mode = cts->xport_specific.sata.mode; + } + if (cts->xport_specific.ata.valid & CTS_SATA_VALID_BYTECOUNT) + d->bytecount = min(8192, cts->xport_specific.sata.bytecount); + } else { + if (cts->xport_specific.ata.valid & CTS_ATA_VALID_MODE) { + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + d->mode = ATA_SETMODE(ch->dev, + ccb->ccb_h.target_id, + cts->xport_specific.ata.mode); + } else + d->mode = cts->xport_specific.ata.mode; + } + if (cts->xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) + d->bytecount = cts->xport_specific.ata.bytecount; + if (ch->flags & ATA_SATA) + d->bytecount = min(8192, d->bytecount); + } + ccb->ccb_h.status = CAM_REQ_CMP; + xpt_done(ccb); + break; + } + case XPT_GET_TRAN_SETTINGS: + { + struct ccb_trans_settings *cts = &ccb->cts; + struct ata_cam_device *d; + + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + d = &ch->curr[ccb->ccb_h.target_id]; + else + d = &ch->user[ccb->ccb_h.target_id]; + cts->protocol = PROTO_ATA; + cts->protocol_version = PROTO_VERSION_UNSPECIFIED; + if ((ch->flags & ATA_SATA) && (ch->flags & ATA_NO_SLAVE)) { + cts->transport = XPORT_SATA; + cts->transport_version = XPORT_VERSION_UNSPECIFIED; + cts->xport_specific.sata.mode = d->mode; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE; + cts->xport_specific.sata.bytecount = d->bytecount; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + cts->xport_specific.sata.revision = + ATA_GETREV(dev, ccb->ccb_h.target_id); + } else + cts->xport_specific.sata.revision = d->revision; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; + } else { + cts->transport = XPORT_ATA; + cts->transport_version = XPORT_VERSION_UNSPECIFIED; + cts->xport_specific.ata.mode = d->mode; + cts->xport_specific.ata.valid |= CTS_ATA_VALID_MODE; + cts->xport_specific.ata.bytecount = d->bytecount; + cts->xport_specific.ata.valid |= CTS_ATA_VALID_BYTECOUNT; + } + ccb->ccb_h.status = CAM_REQ_CMP; + xpt_done(ccb); + break; + } +#if 0 + case XPT_CALC_GEOMETRY: + { + struct ccb_calc_geometry *ccg; + uint32_t size_mb; + uint32_t secs_per_cylinder; + + ccg = &ccb->ccg; + size_mb = ccg->volume_size + / ((1024L * 1024L) / ccg->block_size); + if (size_mb >= 1024 && (aha->extended_trans != 0)) { + if (size_mb >= 2048) { + ccg->heads = 255; + ccg->secs_per_track = 63; + } else { + ccg->heads = 128; + ccg->secs_per_track = 32; + } + } else { + ccg->heads = 64; + ccg->secs_per_track = 32; + } + secs_per_cylinder = ccg->heads * ccg->secs_per_track; + ccg->cylinders = ccg->volume_size / secs_per_cylinder; + ccb->ccb_h.status = CAM_REQ_CMP; + xpt_done(ccb); + break; + } +#endif + case XPT_RESET_BUS: /* Reset the specified SCSI bus */ + case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ + ata_reinit(dev); + ccb->ccb_h.status = CAM_REQ_CMP; + xpt_done(ccb); + break; + case XPT_TERM_IO: /* Terminate the I/O process */ + /* XXX Implement */ + ccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(ccb); + break; + case XPT_PATH_INQ: /* Path routing inquiry */ + { + struct ccb_pathinq *cpi = &ccb->cpi; + + cpi->version_num = 1; /* XXX??? */ + cpi->hba_inquiry = PI_SDTR_ABLE; + cpi->target_sprt = 0; + cpi->hba_misc = PIM_SEQSCAN; + cpi->hba_eng_cnt = 0; + if (ch->flags & ATA_NO_SLAVE) + cpi->max_target = 0; + else + cpi->max_target = 1; + cpi->max_lun = 0; + cpi->initiator_id = 0; + cpi->bus_id = cam_sim_bus(sim); + if (ch->flags & ATA_SATA) + cpi->base_transfer_speed = 150000; + else + cpi->base_transfer_speed = 3300; + strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); + strncpy(cpi->hba_vid, "ATA", HBA_IDLEN); + strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); + cpi->unit_number = cam_sim_unit(sim); + if ((ch->flags & ATA_SATA) && (ch->flags & ATA_NO_SLAVE)) + cpi->transport = XPORT_SATA; + else + cpi->transport = XPORT_ATA; + cpi->transport_version = XPORT_VERSION_UNSPECIFIED; + cpi->protocol = PROTO_ATA; + cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; + cpi->maxio = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS; + cpi->ccb_h.status = CAM_REQ_CMP; + xpt_done(ccb); + break; + } + default: + ccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(ccb); + break; + } +} + +static void +atapoll(struct cam_sim *sim) +{ + struct ata_channel *ch = (struct ata_channel *)cam_sim_softc(sim); + + ata_interrupt_locked(ch); +} +#endif /* * module handeling @@ -1088,10 +1639,13 @@ bpack(int8_t *src, int8_t *dst, int len) static int ata_module_event_handler(module_t mod, int what, void *arg) { +#ifndef ATA_CAM static struct cdev *atacdev; +#endif switch (what) { case MOD_LOAD: +#ifndef ATA_CAM /* register controlling device */ atacdev = make_dev(&ata_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600, "ata"); @@ -1109,11 +1663,14 @@ ata_module_event_handler(module_t mod, int what, void *arg) free(ata_delayed_attach, M_TEMP); } } +#endif return 0; case MOD_UNLOAD: +#ifndef ATA_CAM /* deregister controlling device */ destroy_dev(atacdev); +#endif return 0; default: @@ -1124,6 +1681,9 @@ ata_module_event_handler(module_t mod, int what, void *arg) static moduledata_t ata_moduledata = { "ata", ata_module_event_handler, NULL }; DECLARE_MODULE(ata, ata_moduledata, SI_SUB_CONFIGURE, SI_ORDER_SECOND); MODULE_VERSION(ata, 1); +#ifdef ATA_CAM +MODULE_DEPEND(ata, cam, 1, 1, 1); +#endif static void ata_init(void) diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index f832505f36b..32f095ec4ee 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -425,6 +425,9 @@ struct ata_request { struct ata_composite *composite; /* for composite atomic ops */ void *driver; /* driver specific */ TAILQ_ENTRY(ata_request) chain; /* list management */ +#ifdef ATA_CAM + union ccb *ccb; +#endif }; /* define this for debugging request processing */ @@ -531,6 +534,14 @@ struct ata_resource { int offset; }; +#ifdef ATA_CAM +struct ata_cam_device { + u_int revision; + int mode; + u_int bytecount; +}; +#endif + /* structure describing an ATA channel */ struct ata_channel { device_t dev; /* device handle */ @@ -547,6 +558,9 @@ struct ata_channel { #define ATA_ATAPI_DMA_RO 0x04 #define ATA_NO_48BIT_DMA 0x08 #define ATA_ALWAYS_DMASTAT 0x10 +#define ATA_CHECKS_CABLE 0x20 +#define ATA_NO_ATAPI_DMA 0x40 +#define ATA_SATA 0x80 int pm_level; /* power management level */ int devices; /* what is present */ @@ -567,6 +581,12 @@ struct ata_channel { struct ata_request *freezepoint; /* composite freezepoint */ struct ata_request *running; /* currently running request */ struct task conntask; /* PHY events handling task */ +#ifdef ATA_CAM + struct cam_sim *sim; + struct cam_path *path; + struct ata_cam_device user[16]; /* User-specified settings */ + struct ata_cam_device curr[16]; /* Current settings */ +#endif }; /* disk bay/enclosure related */ @@ -600,12 +620,20 @@ void ata_default_registers(device_t dev); void ata_modify_if_48bit(struct ata_request *request); void ata_udelay(int interval); char *ata_unit2str(struct ata_device *atadev); -char *ata_mode2str(int mode); +const char *ata_mode2str(int mode); +const char *ata_satarev2str(int rev); int ata_atapi(device_t dev); int ata_pmode(struct ata_params *ap); int ata_wmode(struct ata_params *ap); int ata_umode(struct ata_params *ap); int ata_limit_mode(device_t dev, int mode, int maxmode); +void ata_setmode(device_t dev); +void ata_print_cable(device_t dev, u_int8_t *who); +int ata_check_80pin(device_t dev, int mode); +#ifdef ATA_CAM +void ata_cam_begin_transaction(device_t dev, union ccb *ccb); +void ata_cam_end_transaction(device_t dev, struct ata_request *request); +#endif /* ata-queue.c: */ int ata_controlcmd(device_t dev, u_int8_t command, u_int16_t feature, u_int64_t lba, u_int16_t count); @@ -635,7 +663,8 @@ void ata_sata_phy_check_events(device_t dev); int ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val); int ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val); int ata_sata_phy_reset(device_t dev, int port, int quick); -void ata_sata_setmode(device_t dev, int mode); +int ata_sata_setmode(device_t dev, int target, int mode); +int ata_sata_getrev(device_t dev, int target); int ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis); void ata_pm_identify(device_t dev); diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index ea427e574ec..0cd0a0f95c7 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -385,7 +385,7 @@ ad_init(device_t dev) { struct ata_device *atadev = device_get_softc(dev); - ATA_SETMODE(device_get_parent(dev), dev); + ata_setmode(dev); /* enable readahead caching */ if (atadev->param.support.command1 & ATA_SUPPORT_LOOKAHEAD) @@ -537,12 +537,13 @@ ad_describe(device_t dev) strncpy(product, atadev->param.model, 40); } - device_printf(dev, "%juMB <%s%s %.8s> at ata%d-%s %s%s\n", + device_printf(dev, "%juMB <%s%s %.8s> at ata%d-%s %s%s %s\n", adp->total_secs / (1048576 / DEV_BSIZE), vendor, product, atadev->param.revision, device_get_unit(ch->dev), ata_unit2str(atadev), (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "", - ata_mode2str(atadev->mode)); + ata_mode2str(atadev->mode), + ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); if (bootverbose) { device_printf(dev, "%ju sectors [%juC/%dH/%dS] " "%d sectors/interrupt %d depth queue\n", adp->total_secs, diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index eae43483346..478693dd759 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -76,7 +76,7 @@ ata_dmainit(device_t dev) ch->dma.alignment = 2; ch->dma.boundary = 65536; ch->dma.segsize = 65536; - ch->dma.max_iosize = 128 * DEV_BSIZE; + ch->dma.max_iosize = MIN((ATA_DMA_ENTRIES - 1) * PAGE_SIZE, MAXPHYS); ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT; ch->dma.dma_slots = 1; diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index 2dbb9862d0e..566b8f676a5 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -82,6 +82,9 @@ ata_begin_transaction(struct ata_request *request) ATA_DEBUG_RQ(request, "begin transaction"); /* disable ATAPI DMA writes if HW doesn't support it */ + if ((ch->flags & ATA_NO_ATAPI_DMA) && + (request->flags & ATA_R_ATAPI) == ATA_R_ATAPI) + request->flags &= ~ATA_R_DMA; if ((ch->flags & ATA_ATAPI_DMA_RO) && ((request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)) == (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE))) @@ -757,7 +760,9 @@ static void ata_tf_write(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); +#ifndef ATA_CAM struct ata_device *atadev = device_get_softc(request->dev); +#endif if (request->flags & ATA_R_48BIT) { ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8); @@ -775,6 +780,7 @@ ata_tf_write(struct ata_request *request) else { ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); +#ifndef ATA_CAM if (atadev->flags & ATA_D_USE_CHS) { int heads, sectors; @@ -797,13 +803,16 @@ ata_tf_write(struct ata_request *request) sectors) & 0xf)); } else { +#endif ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); 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(request->unit) | ((request->u.ata.lba >> 24) & 0x0f)); +#ifndef ATA_CAM } +#endif } } diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index ce21926cb3e..cd877284085 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -55,10 +55,6 @@ static MALLOC_DEFINE(M_ATAPCI, "ata_pci", "ATA driver PCI"); /* misc defines */ #define IOMASK 0xfffffffc -/* local prototypes */ -static int ata_generic_chipinit(device_t dev); -static void ata_generic_setmode(device_t dev, int mode); - /* * generic PCI ATA device probe */ @@ -374,18 +370,14 @@ ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq, } } -static void -ata_generic_setmode(device_t dev, int mode) +int +ata_generic_setmode(device_t dev, int target, int mode) { - struct ata_device *atadev = device_get_softc(dev); - mode = ata_limit_mode(dev, mode, ATA_UDMA2); - mode = ata_check_80pin(dev, mode); - if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - atadev->mode = mode; + return (min(mode, ATA_UDMA2)); } -static int +int ata_generic_chipinit(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); @@ -707,16 +699,26 @@ ata_pcichannel_reset(device_t dev) ata_generic_reset(dev); } -static void -ata_pcichannel_setmode(device_t parent, device_t dev) +static int +ata_pcichannel_setmode(device_t dev, int target, int mode) { - struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev)); - struct ata_device *atadev = device_get_softc(dev); - int mode = atadev->mode; + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); - ctlr->setmode(dev, ATA_PIO_MAX); - if (mode >= ATA_DMA) - ctlr->setmode(dev, mode); + if (ctlr->setmode) + return (ctlr->setmode(dev, target, mode)); + else + return (ata_generic_setmode(dev, target, mode)); +} + +static int +ata_pcichannel_getrev(device_t dev, int target) +{ + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + + if (ctlr->getrev) + return (ctlr->getrev(dev, target)); + else + return (0); } static device_method_t ata_pcichannel_methods[] = { @@ -730,6 +732,7 @@ static device_method_t ata_pcichannel_methods[] = { /* ATA methods */ DEVMETHOD(ata_setmode, ata_pcichannel_setmode), + DEVMETHOD(ata_getrev, ata_pcichannel_getrev), DEVMETHOD(ata_locking, ata_pcichannel_locking), DEVMETHOD(ata_reset, ata_pcichannel_reset), @@ -858,31 +861,6 @@ ata_find_chip(device_t dev, struct ata_chip_id *index, int slot) return (NULL); } -void -ata_print_cable(device_t dev, u_int8_t *who) -{ - device_printf(dev, - "DMA limited to UDMA33, %s found non-ATA66 cable\n", who); -} - -int -ata_check_80pin(device_t dev, int mode) -{ - struct ata_device *atadev = device_get_softc(dev); - - if (!ata_dma_check_80pin) { - if (bootverbose) - device_printf(dev, "Skipping 80pin cable check\n"); - return mode; - } - - if (mode > ATA_UDMA2 && !(atadev->param.hwres & ATA_CABLE_ID)) { - ata_print_cable(dev, "device"); - mode = ATA_UDMA2; - } - return mode; -} - char * ata_pcivendor2str(device_t dev) { diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index f2a0e1371ff..7bfb7a25990 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -63,7 +63,8 @@ struct ata_pci_controller { int (*ch_resume)(device_t); int (*locking)(device_t, int); void (*reset)(device_t); - void (*setmode)(device_t, int); + int (*setmode)(device_t, int, int); + int (*getrev)(device_t, int); struct { void (*function)(void *); void *argument; @@ -506,12 +507,12 @@ void ata_pci_dmafini(device_t dev); char *ata_pcivendor2str(device_t dev); int ata_legacy(device_t); void ata_generic_intr(void *data); +int ata_generic_chipinit(device_t dev); +int ata_generic_setmode(device_t dev, int target, int mode); int ata_setup_interrupt(device_t dev, void *intr_func); void ata_set_desc(device_t dev); struct ata_chip_id *ata_match_chip(device_t dev, struct ata_chip_id *index); struct ata_chip_id *ata_find_chip(device_t dev, struct ata_chip_id *index, int slot); -void ata_print_cable(device_t dev, u_int8_t *who); -int ata_check_80pin(device_t dev, int mode); int ata_mode2idx(int mode); /* global prototypes from chipsets/ata-*.c */ diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c index c0487787144..a3b1c4e4435 100644 --- a/sys/dev/ata/ata-queue.c +++ b/sys/dev/ata/ata-queue.c @@ -511,11 +511,18 @@ ata_timeout(struct ata_request *request) */ if (ch->state == ATA_ACTIVE) { request->flags |= ATA_R_TIMEOUT; - mtx_unlock(&ch->state_mtx); - ATA_LOCKING(ch->dev, ATA_LF_UNLOCK); if (ch->dma.unload) ch->dma.unload(request); +#ifdef ATA_CAM + ch->running = NULL; + ch->state = ATA_IDLE; + ata_cam_end_transaction(ch->dev, request); +#endif + mtx_unlock(&ch->state_mtx); + ATA_LOCKING(ch->dev, ATA_LF_UNLOCK); +#ifndef ATA_CAM ata_finish(request); +#endif } else { mtx_unlock(&ch->state_mtx); diff --git a/sys/dev/ata/ata-sata.c b/sys/dev/ata/ata-sata.c index 5f5daa48f3f..9e3f7e8de06 100644 --- a/sys/dev/ata/ata-sata.c +++ b/sys/dev/ata/ata-sata.c @@ -209,38 +209,21 @@ ata_sata_phy_reset(device_t dev, int port, int quick) return 0; } -void -ata_sata_setmode(device_t dev, int mode) +int +ata_sata_setmode(device_t dev, int target, int mode) { - struct ata_device *atadev = device_get_softc(dev); - /* - * if we detect that the device isn't a real SATA device we limit - * the transfer mode to UDMA5/ATA100. - * this works around the problems some devices has with the - * Marvell 88SX8030 SATA->PATA converters and UDMA6/ATA133. - */ - if (atadev->param.satacapabilities != 0x0000 && - atadev->param.satacapabilities != 0xffff) { - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + return (min(mode, ATA_UDMA5)); +} - /* on some drives we need to set the transfer mode */ - ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, - ata_limit_mode(dev, mode, ATA_UDMA6)); +int +ata_sata_getrev(device_t dev, int target) +{ + struct ata_channel *ch = device_get_softc(dev); - /* query SATA STATUS for the speed */ - if (ch->r_io[ATA_SSTATUS].res && - ((ATA_IDX_INL(ch, ATA_SSTATUS) & ATA_SS_CONWELL_MASK) == - ATA_SS_CONWELL_GEN2)) - atadev->mode = ATA_SA300; - else - atadev->mode = ATA_SA150; - } - else { - mode = ata_limit_mode(dev, mode, ATA_UDMA5); - if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - atadev->mode = mode; - } + if (ch->r_io[ATA_SSTATUS].res) + return ((ATA_IDX_INL(ch, ATA_SSTATUS) & 0x0f0) >> 4); + return (0); } int diff --git a/sys/dev/ata/ata_if.m b/sys/dev/ata/ata_if.m index 8fcc3f26759..a1775ac6ee7 100644 --- a/sys/dev/ata/ata_if.m +++ b/sys/dev/ata/ata_if.m @@ -57,17 +57,24 @@ HEADER { }; CODE { - static void ata_null_setmode(device_t parent, device_t dev) + static int ata_null_setmode(device_t dev, int target, int mode) { - struct ata_device *atadev = device_get_softc(dev); - atadev->mode = ata_limit_mode(dev, atadev->mode, ATA_PIO_MAX); + if (mode > ATA_PIO_MAX) + return (ATA_PIO_MAX); + return (mode); } }; -METHOD void setmode { - device_t channel; +METHOD int setmode { device_t dev; -} DEFAULT ata_null_setmode;; + int target; + int mode; +} DEFAULT ata_null_setmode; + +METHOD int getrev { + device_t dev; + int target; +}; METHOD void reset { device_t channel; diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index a021e005492..5d0c0f70476 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -126,7 +126,7 @@ acd_attach(device_t dev) } cdp->block_size = 2048; device_set_ivars(dev, cdp); - ATA_SETMODE(device_get_parent(dev), dev); + ata_setmode(dev); ata_controlcmd(dev, ATA_DEVICE_RESET, 0, 0, 0); acd_get_cap(dev); g_post_event(acd_geom_attach, dev, M_WAITOK, NULL); @@ -163,7 +163,7 @@ acd_reinit(device_t dev) if (!(ch->devices & (ATA_ATAPI_MASTER << atadev->unit))) return 1; - ATA_SETMODE(device_get_parent(dev), dev); + ata_setmode(dev); return 0; } @@ -1724,7 +1724,8 @@ acd_describe(device_t dev) printf("%s %dKB buffer", comma ? "," : "", cdp->cap.buf_size); comma = 1; } - printf("%s %s\n", comma ? "," : "", ata_mode2str(atadev->mode)); + printf("%s %s %s\n", comma ? "," : "", ata_mode2str(atadev->mode), + ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); device_printf(dev, "Reads:"); comma = 0; @@ -1874,10 +1875,11 @@ acd_describe(device_t dev) "CDROM"); if (cdp->changer_info) printf("with %d CD changer ", cdp->changer_info->slots); - printf("<%.40s/%.8s> at ata%d-%s %s\n", + printf("<%.40s/%.8s> at ata%d-%s %s %s\n", atadev->param.model, atadev->param.revision, device_get_unit(ch->dev), ata_unit2str(atadev), - ata_mode2str(atadev->mode) ); + ata_mode2str(atadev->mode), + ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); } } diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index 5baeab9a7ee..5572d1c2794 100644 --- a/sys/dev/ata/atapi-fd.c +++ b/sys/dev/ata/atapi-fd.c @@ -85,7 +85,7 @@ afd_attach(device_t dev) return ENOMEM; } device_set_ivars(dev, fdp); - ATA_SETMODE(device_get_parent(dev), dev); + ata_setmode(dev); if (afd_sense(dev)) { device_set_ivars(dev, NULL); @@ -152,7 +152,7 @@ afd_reinit(device_t dev) if (!(ch->devices & (ATA_ATAPI_MASTER << atadev->unit))) return 1; - ATA_SETMODE(device_get_parent(dev), dev); + ata_setmode(dev); return 0; } @@ -400,10 +400,11 @@ afd_describe(device_t dev) else strcpy(sizestring, "(no media)"); - device_printf(dev, "%s <%.40s %.8s> at ata%d-%s %s\n", + device_printf(dev, "%s <%.40s %.8s> at ata%d-%s %s %s\n", sizestring, atadev->param.model, atadev->param.revision, device_get_unit(ch->dev), ata_unit2str(atadev), - ata_mode2str(atadev->mode)); + ata_mode2str(atadev->mode), + ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); if (bootverbose) { device_printf(dev, "%ju sectors [%juC/%dH/%dS]\n", fdp->mediasize / fdp->sectorsize, diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index 5b4da81dc1b..b6ca4ad6e68 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.c @@ -111,7 +111,7 @@ ast_attach(device_t dev) return ENOMEM; } device_set_ivars(dev, stp); - ATA_SETMODE(device_get_parent(dev), dev); + ata_setmode(dev); if (ast_sense(dev)) { device_set_ivars(dev, NULL); @@ -193,7 +193,7 @@ ast_reinit(device_t dev) if (!(ch->devices & (ATA_ATAPI_MASTER << atadev->unit))) return 1; - ATA_SETMODE(device_get_parent(dev), dev); + ata_setmode(dev); return 0; } @@ -673,7 +673,8 @@ ast_describe(device_t dev) printf("transfer limit %d blk%s, ", stp->cap.ctl, (stp->cap.ctl > 1) ? "s" : ""); printf("%dKB buffer, ", (stp->cap.buffer_size * DEV_BSIZE) / 1024); - printf("%s\n", ata_mode2str(atadev->mode)); + printf("%s %s\n", ata_mode2str(atadev->mode), + ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); device_printf(dev, "Medium: "); switch (stp->cap.medium_type) { case 0x00: @@ -704,10 +705,11 @@ ast_describe(device_t dev) printf("\n"); } else { - device_printf(dev, "TAPE <%.40s/%.8s> at ata%d-%s %s\n", + device_printf(dev, "TAPE <%.40s/%.8s> at ata%d-%s %s %s\n", atadev->param.model, atadev->param.revision, device_get_unit(ch->dev), ata_unit2str(atadev), - ata_mode2str(atadev->mode)); + ata_mode2str(atadev->mode), + ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); } } diff --git a/sys/dev/ata/chipsets/ata-acard.c b/sys/dev/ata/chipsets/ata-acard.c index c52c2cbc088..bb81c48dc4c 100644 --- a/sys/dev/ata/chipsets/ata-acard.c +++ b/sys/dev/ata/chipsets/ata-acard.c @@ -61,8 +61,8 @@ struct ata_serialize { static int ata_acard_chipinit(device_t dev); static int ata_acard_ch_attach(device_t dev); static int ata_acard_status(device_t dev); -static void ata_acard_850_setmode(device_t dev, int mode); -static void ata_acard_86X_setmode(device_t dev, int mode); +static int ata_acard_850_setmode(device_t dev, int target, int mode); +static int ata_acard_86X_setmode(device_t dev, int target, int mode); static int ata_serialize(device_t dev, int flags); static void ata_serialize_init(struct ata_serialize *serial); @@ -130,6 +130,7 @@ ata_acard_ch_attach(device_t dev) return ENXIO; ch->hw.status = ata_acard_status; + ch->flags |= ATA_NO_ATAPI_DMA; return 0; } @@ -162,79 +163,52 @@ ata_acard_status(device_t dev) return 1; } -static void -ata_acard_850_setmode(device_t dev, int mode) +static int +ata_acard_850_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int error; - - mode = ata_limit_mode(dev, mode, - ata_atapi(dev) ? ATA_PIO_MAX : ctlr->chip->max_dma); + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + mode = min(mode, ctlr->chip->max_dma); /* XXX SOS missing WDMA0+1 + PIO modes */ if (mode >= ATA_WDMA2) { - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { - u_int8_t reg54 = pci_read_config(gparent, 0x54, 1); + u_int8_t reg54 = pci_read_config(parent, 0x54, 1); reg54 &= ~(0x03 << (devno << 1)); if (mode >= ATA_UDMA0) reg54 |= (((mode & ATA_MODE_MASK) + 1) << (devno << 1)); - pci_write_config(gparent, 0x54, reg54, 1); - pci_write_config(gparent, 0x4a, 0xa6, 1); - pci_write_config(gparent, 0x40 + (devno << 1), 0x0301, 2); - atadev->mode = mode; - return; - } + pci_write_config(parent, 0x54, reg54, 1); + pci_write_config(parent, 0x4a, 0xa6, 1); + pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2); } /* we could set PIO mode timings, but we assume the BIOS did that */ + return (mode); } -static void -ata_acard_86X_setmode(device_t dev, int mode) +static int +ata_acard_86X_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int error; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; - - mode = ata_limit_mode(dev, mode, - ata_atapi(dev) ? ATA_PIO_MAX : ctlr->chip->max_dma); - - mode = ata_check_80pin(dev, mode); - - /* XXX SOS missing WDMA0+1 + PIO modes */ - if (mode >= ATA_WDMA2) { - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { - u_int16_t reg44 = pci_read_config(gparent, 0x44, 2); + mode = min(mode, ctlr->chip->max_dma); + /* XXX SOS missing WDMA0+1 + PIO modes */ + if (mode >= ATA_WDMA2) { + u_int16_t reg44 = pci_read_config(parent, 0x44, 2); - reg44 &= ~(0x000f << (devno << 2)); - if (mode >= ATA_UDMA0) - reg44 |= (((mode & ATA_MODE_MASK) + 1) << (devno << 2)); - pci_write_config(gparent, 0x44, reg44, 2); - pci_write_config(gparent, 0x4a, 0xa6, 1); - pci_write_config(gparent, 0x40 + devno, 0x31, 1); - atadev->mode = mode; - return; + reg44 &= ~(0x000f << (devno << 2)); + if (mode >= ATA_UDMA0) + reg44 |= (((mode & ATA_MODE_MASK) + 1) << (devno << 2)); + pci_write_config(parent, 0x44, reg44, 2); + pci_write_config(parent, 0x4a, 0xa6, 1); + pci_write_config(parent, 0x40 + devno, 0x31, 1); } - } - /* we could set PIO mode timings, but we assume the BIOS did that */ + /* we could set PIO mode timings, but we assume the BIOS did that */ + return (mode); } static void diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c index cf503c591b2..e74b2105f41 100644 --- a/sys/dev/ata/chipsets/ata-acerlabs.c +++ b/sys/dev/ata/chipsets/ata-acerlabs.c @@ -56,7 +56,7 @@ static int ata_ali_chipinit(device_t dev); static int ata_ali_ch_attach(device_t dev); static int ata_ali_sata_ch_attach(device_t dev); static void ata_ali_reset(device_t dev); -static void ata_ali_setmode(device_t dev, int mode); +static int ata_ali_setmode(device_t dev, int target, int mode); /* misc defines */ #define ALI_OLD 0x01 @@ -113,6 +113,7 @@ ata_ali_chipinit(device_t dev) ctlr->ch_attach = ata_ali_sata_ch_attach; ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; /* AHCI mode is correctly supported only on the ALi 5288. */ if ((ctlr->chip->chipid == ATA_ALI_5288) && @@ -176,6 +177,7 @@ ata_ali_ch_attach(device_t dev) if (ata_pci_ch_attach(dev)) return ENXIO; + ch->flags |= ATA_CHECKS_CABLE; /* older chips can't do 48bit DMA transfers */ if (ctlr->chip->chiprev <= 0xc4) ch->flags |= ATA_NO_48BIT_DMA; @@ -218,6 +220,7 @@ ata_ali_sata_ch_attach(device_t dev) } } ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; /* XXX SOS PHY handling awkward in ALI chip not supported yet */ ata_pci_hw(dev); @@ -257,67 +260,56 @@ ata_ali_reset(device_t dev) } } -static void -ata_ali_setmode(device_t dev, int mode) +static int +ata_ali_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int error; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int piomode; + u_int32_t piotimings[] = + { 0x006d0003, 0x00580002, 0x00440001, 0x00330001, + 0x00310001, 0x006d0003, 0x00330001, 0x00310001 }; + u_int8_t udma[] = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0d}; + u_int32_t word54; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); + mode = min(mode, ctlr->chip->max_dma); - if (ctlr->chip->cfg2 & ALI_NEW) { - if (mode > ATA_UDMA2 && - pci_read_config(gparent, 0x4a, 1) & (1 << ch->unit)) { - ata_print_cable(dev, "controller"); - mode = ATA_UDMA2; + if (ctlr->chip->cfg2 & ALI_NEW) { + if (mode > ATA_UDMA2 && + pci_read_config(parent, 0x4a, 1) & (1 << ch->unit)) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; + } } - } - else - mode = ata_check_80pin(dev, mode); - - if (ctlr->chip->cfg2 & ALI_OLD) { - /* doesn't support ATAPI DMA on write */ - ch->flags |= ATA_ATAPI_DMA_RO; - if (ch->devices & ATA_ATAPI_MASTER && ch->devices & ATA_ATAPI_SLAVE) { - /* doesn't support ATAPI DMA on two ATAPI devices */ - device_printf(dev, "two atapi devices on this channel, no DMA\n"); - mode = ata_limit_mode(dev, mode, ATA_PIO_MAX); + if (ctlr->chip->cfg2 & ALI_OLD) { + /* doesn't support ATAPI DMA on write */ + ch->flags |= ATA_ATAPI_DMA_RO; + if (ch->devices & ATA_ATAPI_MASTER && + ch->devices & ATA_ATAPI_SLAVE) { + /* doesn't support ATAPI DMA on two ATAPI devices */ + device_printf(dev, "two atapi devices on this channel," + " no DMA\n"); + mode = min(mode, ATA_PIO_MAX); + } } - } - - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { + /* Set UDMA mode */ + word54 = pci_read_config(parent, 0x54, 4); if (mode >= ATA_UDMA0) { - u_int8_t udma[] = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0d}; - u_int32_t word54 = pci_read_config(gparent, 0x54, 4); - word54 &= ~(0x000f000f << (devno << 2)); word54 |= (((udma[mode&ATA_MODE_MASK]<<16)|0x05)<<(devno<<2)); - pci_write_config(gparent, 0x54, word54, 4); - pci_write_config(gparent, 0x58 + (ch->unit << 2), - 0x00310001, 4); + piomode = ATA_PIO4; } else { - u_int32_t piotimings[] = - { 0x006d0003, 0x00580002, 0x00440001, 0x00330001, - 0x00310001, 0x00440001, 0x00330001, 0x00310001}; - - pci_write_config(gparent, 0x54, pci_read_config(gparent, 0x54, 4) & - ~(0x0008000f << (devno << 2)), 4); - pci_write_config(gparent, 0x58 + (ch->unit << 2), - piotimings[ata_mode2idx(mode)], 4); + word54 &= ~(0x0008000f << (devno << 2)); + piomode = mode; } - atadev->mode = mode; - } + pci_write_config(parent, 0x54, word54, 4); + /* Set PIO/WDMA mode */ + pci_write_config(parent, 0x58 + (ch->unit << 2), + piotimings[ata_mode2idx(piomode)], 4); + return (mode); } ATA_DECLARE_DRIVER(ata_ali); diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c index e4a7cd165ad..39c51523e76 100644 --- a/sys/dev/ata/chipsets/ata-ahci.c +++ b/sys/dev/ata/chipsets/ata-ahci.c @@ -194,6 +194,7 @@ ata_ahci_chipinit(device_t dev) ctlr->ch_suspend = ata_ahci_ch_suspend; ctlr->ch_resume = ata_ahci_ch_resume; ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; ctlr->suspend = ata_ahci_suspend; ctlr->resume = ata_ahci_ctlr_reset; @@ -309,6 +310,8 @@ ata_ahci_ch_attach(device_t dev) ch->hw.softreset = ata_ahci_softreset; ch->hw.pm_read = ata_ahci_pm_read; ch->hw.pm_write = ata_ahci_pm_write; + ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; ata_ahci_ch_resume(dev); return 0; diff --git a/sys/dev/ata/chipsets/ata-amd.c b/sys/dev/ata/chipsets/ata-amd.c index 9c14e99cba4..1cf9ac073c4 100644 --- a/sys/dev/ata/chipsets/ata-amd.c +++ b/sys/dev/ata/chipsets/ata-amd.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_amd_chipinit(device_t dev); -static void ata_amd_setmode(device_t dev, int mode); +static int ata_amd_setmode(device_t dev, int target, int mode); /* misc defines */ #define AMD_BUG 0x01 @@ -104,46 +104,37 @@ ata_amd_chipinit(device_t dev) return 0; } -static void -ata_amd_setmode(device_t dev, int mode) +static int +ata_amd_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; - int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }; - int devno = (ch->unit << 1) + atadev->unit; - int reg = 0x53 - devno; - int error; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int piomode; + u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 }; + int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }; + int reg = 0x53 - devno; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - - if (ctlr->chip->cfg1 & AMD_CABLE) { - if (mode > ATA_UDMA2 && - !(pci_read_config(gparent, 0x42, 1) & (1 << devno))) { - ata_print_cable(dev, "controller"); - mode = ATA_UDMA2; + mode = min(mode, ctlr->chip->max_dma); + if (ctlr->chip->cfg1 & AMD_CABLE) { + if (mode > ATA_UDMA2 && + !(pci_read_config(parent, 0x42, 1) & (1 << devno))) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; + } } - } - else - mode = ata_check_80pin(dev, mode); - - - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", ata_mode2str(mode), - ctlr->chip->text); - if (!error) { - pci_write_config(gparent, reg - 0x08, timings[ata_mode2idx(mode)], 1); - if (mode >= ATA_UDMA0) - pci_write_config(gparent, reg, modes[mode & ATA_MODE_MASK], 1); - else - pci_write_config(gparent, reg, 0x8b, 1); - atadev->mode = mode; - } + /* Set UDMA timings. */ + if (mode >= ATA_UDMA0) { + pci_write_config(parent, reg, modes[mode & ATA_MODE_MASK], 1); + piomode = ATA_PIO4; + } else { + pci_write_config(parent, reg, 0x8b, 1); + piomode = mode; + } + /* Set WDMA/PIO timings. */ + pci_write_config(parent, reg - 0x08, timings[ata_mode2idx(piomode)], 1); + return (mode); } ATA_DECLARE_DRIVER(ata_amd); diff --git a/sys/dev/ata/chipsets/ata-ati.c b/sys/dev/ata/chipsets/ata-ati.c index 4436c7f53c9..d464897243d 100644 --- a/sys/dev/ata/chipsets/ata-ati.c +++ b/sys/dev/ata/chipsets/ata-ati.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_ati_chipinit(device_t dev); -static void ata_ati_setmode(device_t dev, int mode); +static int ata_ati_setmode(device_t dev, int target, int mode); /* misc defines */ #define ATI_PATA 0x01 @@ -160,68 +160,61 @@ ata_ati_chipinit(device_t dev) return 0; } -static void -ata_ati_setmode(device_t dev, int mode) +static int +ata_ati_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int offset = (devno ^ 0x01) << 3; - int error; - u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; - u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 }; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int offset = (devno ^ 0x01) << 3; + int piomode; + u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; + u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 }; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - - mode = ata_check_80pin(dev, mode); - - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { + mode = min(mode, ctlr->chip->max_dma); if (mode >= ATA_UDMA0) { - pci_write_config(gparent, 0x56, - (pci_read_config(gparent, 0x56, 2) & + /* Set UDMA mode, enable UDMA, set WDMA2/PIO4 */ + pci_write_config(parent, 0x56, + (pci_read_config(parent, 0x56, 2) & ~(0xf << (devno << 2))) | ((mode & ATA_MODE_MASK) << (devno << 2)), 2); - pci_write_config(gparent, 0x54, - pci_read_config(gparent, 0x54, 1) | + pci_write_config(parent, 0x54, + pci_read_config(parent, 0x54, 1) | (0x01 << devno), 1); - pci_write_config(gparent, 0x44, - (pci_read_config(gparent, 0x44, 4) & + pci_write_config(parent, 0x44, + (pci_read_config(parent, 0x44, 4) & ~(0xff << offset)) | (dmatimings[2] << offset), 4); - } - else if (mode >= ATA_WDMA0) { - pci_write_config(gparent, 0x54, - pci_read_config(gparent, 0x54, 1) & + piomode = ATA_PIO4; + } else if (mode >= ATA_WDMA0) { + /* Disable UDMA, set WDMA mode and timings, calculate PIO. */ + pci_write_config(parent, 0x54, + pci_read_config(parent, 0x54, 1) & ~(0x01 << devno), 1); - pci_write_config(gparent, 0x44, - (pci_read_config(gparent, 0x44, 4) & + pci_write_config(parent, 0x44, + (pci_read_config(parent, 0x44, 4) & ~(0xff << offset)) | (dmatimings[mode & ATA_MODE_MASK] << offset), 4); - } - else - pci_write_config(gparent, 0x54, - pci_read_config(gparent, 0x54, 1) & + piomode = (mode == ATA_WDMA0) ? ATA_PIO0 : + (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4; + } else { + /* Disable UDMA, set requested PIO. */ + pci_write_config(parent, 0x54, + pci_read_config(parent, 0x54, 1) & ~(0x01 << devno), 1); - - pci_write_config(gparent, 0x4a, - (pci_read_config(gparent, 0x4a, 2) & + piomode = mode; + } + /* Set PIO mode and timings, calculated above. */ + pci_write_config(parent, 0x4a, + (pci_read_config(parent, 0x4a, 2) & ~(0xf << (devno << 2))) | - (((mode - ATA_PIO0) & ATA_MODE_MASK) << (devno<<2)),2); - pci_write_config(gparent, 0x40, - (pci_read_config(gparent, 0x40, 4) & + ((piomode - ATA_PIO0) << (devno<<2)),2); + pci_write_config(parent, 0x40, + (pci_read_config(parent, 0x40, 4) & ~(0xff << offset)) | - (piotimings[ata_mode2idx(mode)] << offset), 4); - atadev->mode = mode; - } + (piotimings[ata_mode2idx(piomode)] << offset), 4); + return (mode); } ATA_DECLARE_DRIVER(ata_ati); diff --git a/sys/dev/ata/chipsets/ata-cenatek.c b/sys/dev/ata/chipsets/ata-cenatek.c index 8f6474cc57a..cc54d2bbc20 100644 --- a/sys/dev/ata/chipsets/ata-cenatek.c +++ b/sys/dev/ata/chipsets/ata-cenatek.c @@ -51,11 +51,6 @@ __FBSDID("$FreeBSD$"); #include #include -/* local prototypes */ -static int ata_cenatek_chipinit(device_t dev); -static void ata_cenatek_setmode(device_t dev, int mode); - - /* * Cenatek chipset support functions */ @@ -67,32 +62,9 @@ ata_cenatek_probe(device_t dev) if (pci_get_devid(dev) != ATA_CENATEK_ROCKET) return ENXIO; - ctlr->chipinit = ata_cenatek_chipinit; + ctlr->chipinit = ata_generic_chipinit; device_set_desc(dev, "Cenatek Rocket Drive controller"); return (BUS_PROBE_DEFAULT); } -static int -ata_cenatek_chipinit(device_t dev) -{ - struct ata_pci_controller *ctlr = device_get_softc(dev); - - if (ata_setup_interrupt(dev, ata_generic_intr)) - return ENXIO; - - ctlr->setmode = ata_cenatek_setmode; - return 0; -} - -static void -ata_cenatek_setmode(device_t dev, int mode) -{ - struct ata_device *atadev = device_get_softc(dev); - - mode = ata_limit_mode(dev, mode, ATA_UDMA2); - mode = ata_check_80pin(dev, mode); - if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - atadev->mode = mode; -} - ATA_DECLARE_DRIVER(ata_cenatek); diff --git a/sys/dev/ata/chipsets/ata-cypress.c b/sys/dev/ata/chipsets/ata-cypress.c index ffa9782fa8b..e4c1a93d034 100644 --- a/sys/dev/ata/chipsets/ata-cypress.c +++ b/sys/dev/ata/chipsets/ata-cypress.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_cypress_chipinit(device_t dev); -static void ata_cypress_setmode(device_t dev, int mode); +static int ata_cypress_setmode(device_t dev, int target, int mode); /* @@ -93,29 +93,20 @@ ata_cypress_chipinit(device_t dev) return 0; } -static void -ata_cypress_setmode(device_t dev, int mode) +static int +ata_cypress_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int error; + device_t parent = device_get_parent(dev); + struct ata_channel *ch = device_get_softc(dev); - mode = ata_limit_mode(dev, mode, ATA_WDMA2); + mode = min(mode, ATA_WDMA2); - /* XXX SOS missing WDMA0+1 + PIO modes */ - if (mode == ATA_WDMA2) { - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - if (bootverbose) - device_printf(dev, "%ssetting WDMA2 on Cypress chip\n", - error ? "FAILURE " : ""); - if (!error) { - pci_write_config(gparent, ch->unit ? 0x4e : 0x4c, 0x2020, 2); - atadev->mode = mode; - return; + /* XXX SOS missing WDMA0+1 + PIO modes */ + if (mode == ATA_WDMA2) { + pci_write_config(parent, ch->unit ? 0x4e : 0x4c, 0x2020, 2); } - } - /* we could set PIO mode timings, but we assume the BIOS did that */ + /* we could set PIO mode timings, but we assume the BIOS did that */ + return (mode); } ATA_DECLARE_DRIVER(ata_cypress); diff --git a/sys/dev/ata/chipsets/ata-cyrix.c b/sys/dev/ata/chipsets/ata-cyrix.c index ddfa56245b7..5a008562147 100644 --- a/sys/dev/ata/chipsets/ata-cyrix.c +++ b/sys/dev/ata/chipsets/ata-cyrix.c @@ -53,7 +53,8 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_cyrix_chipinit(device_t dev); -static void ata_cyrix_setmode(device_t dev, int mode); +static int ata_cyrix_ch_attach(device_t dev); +static int ata_cyrix_setmode(device_t dev, int target, int mode); /* @@ -79,53 +80,57 @@ ata_cyrix_chipinit(device_t dev) if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; - + ctlr->ch_attach = ata_cyrix_ch_attach; ctlr->setmode = ata_cyrix_setmode; return 0; } -static void -ata_cyrix_setmode(device_t dev, int mode) +static int +ata_cyrix_ch_attach(device_t dev) { - struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev)); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - u_int32_t piotiming[] = - { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 }; - u_int32_t dmatiming[] = { 0x00077771, 0x00012121, 0x00002020 }; - u_int32_t udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 }; - int error; + struct ata_channel *ch = device_get_softc(dev); + int error; + + error = ata_pci_ch_attach(dev); + ch->dma.alignment = 16; + ch->dma.max_iosize = 64 * DEV_BSIZE; + return (error); +} - mode = ata_limit_mode(dev, mode, ATA_UDMA2); - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); +static int +ata_cyrix_setmode(device_t dev, int target, int mode) +{ + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int piomode; + u_int32_t piotiming[] = + { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 }; + u_int32_t dmatiming[] = { 0x00077771, 0x00012121, 0x00002020 }; + u_int32_t udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 }; - if (bootverbose) - device_printf(dev, "%ssetting %s on Cyrix chip\n", - (error) ? "FAILURE " : "", ata_mode2str(mode)); - - if (!error) { + mode = min(mode, ATA_UDMA2); /* dont try to set the mode if we dont have the resource */ if (ctlr->r_res1) { - ch->dma.alignment = 16; - ch->dma.max_iosize = 64 * DEV_BSIZE; - - if (mode >= ATA_UDMA0) { + if (mode >= ATA_UDMA0) { + /* Set UDMA timings, and PIO4. */ + ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res, + 0x24 + (devno << 3), udmatiming[mode & ATA_MODE_MASK]); + piomode = ATA_PIO4; + } else if (mode >= ATA_WDMA0) { + /* Set WDMA timings, and respective PIO mode. */ + ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res, + 0x24 + (devno << 3), dmatiming[mode & ATA_MODE_MASK]); + piomode = (mode == ATA_WDMA0) ? ATA_PIO0 : + (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4; + } else + piomode = mode; + /* Set PIO mode calculated above. */ ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res, - 0x24 + (devno << 3), udmatiming[mode & ATA_MODE_MASK]); - } - else if (mode >= ATA_WDMA0) { - ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res, - 0x24 + (devno << 3), dmatiming[mode & ATA_MODE_MASK]); - } - else { - ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res, - 0x20 + (devno << 3), piotiming[mode & ATA_MODE_MASK]); - } + 0x20 + (devno << 3), piotiming[ata_mode2idx(piomode)]); } - atadev->mode = mode; - } + return (mode); } ATA_DECLARE_DRIVER(ata_cyrix); diff --git a/sys/dev/ata/chipsets/ata-highpoint.c b/sys/dev/ata/chipsets/ata-highpoint.c index 101b054f483..511366a78e1 100644 --- a/sys/dev/ata/chipsets/ata-highpoint.c +++ b/sys/dev/ata/chipsets/ata-highpoint.c @@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_highpoint_chipinit(device_t dev); static int ata_highpoint_ch_attach(device_t dev); -static void ata_highpoint_setmode(device_t dev, int mode); +static int ata_highpoint_setmode(device_t dev, int target, int mode); static int ata_highpoint_check_80pin(device_t dev, int mode); /* misc defines */ @@ -143,26 +143,27 @@ ata_highpoint_chipinit(device_t dev) static int ata_highpoint_ch_attach(device_t dev) { - struct ata_channel *ch = device_get_softc(dev); + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + struct ata_channel *ch = device_get_softc(dev); - /* setup the usual register normal pci style */ - if (ata_pci_ch_attach(dev)) - return ENXIO; - - ch->flags |= ATA_ALWAYS_DMASTAT; - return 0; + /* setup the usual register normal pci style */ + if (ata_pci_ch_attach(dev)) + return (ENXIO); + ch->flags |= ATA_ALWAYS_DMASTAT; + ch->flags |= ATA_CHECKS_CABLE; + if (ctlr->chip->cfg1 == HPT_366) + ch->flags |= ATA_NO_ATAPI_DMA; + return (0); } -static void -ata_highpoint_setmode(device_t dev, int mode) +static int +ata_highpoint_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int error; - u_int32_t timings33[][4] = { + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + u_int32_t timings33[][4] = { /* HPT366 HPT370 HPT372 HPT374 mode */ { 0x40d0a7aa, 0x06914e57, 0x0d029d5e, 0x0ac1f48a }, /* PIO 0 */ { 0x40d0a7a3, 0x06914e43, 0x0d029d26, 0x0ac1f465 }, /* PIO 1 */ @@ -179,51 +180,41 @@ ata_highpoint_setmode(device_t dev, int mode) { 0x10c9a731, 0x16454e31, 0x1c8a9c62, 0x12ac8242 }, /* UDMA 4 */ { 0, 0x16454e31, 0x1c8a9c62, 0x12848242 }, /* UDMA 5 */ { 0, 0, 0x1c869c62, 0x12808242 } /* UDMA 6 */ - }; + }; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - - if (ctlr->chip->cfg1 == HPT_366 && ata_atapi(dev)) - mode = ata_limit_mode(dev, mode, ATA_PIO_MAX); - - mode = ata_highpoint_check_80pin(dev, mode); - - /* - * most if not all HPT chips cant really handle that the device is - * running at ATA_UDMA6/ATA133 speed, so we cheat at set the device to - * a max of ATA_UDMA5/ATA100 to guard against suboptimal performance - */ - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, - ata_limit_mode(dev, mode, ATA_UDMA5)); - if (bootverbose) - device_printf(dev, "%ssetting %s on HighPoint chip\n", - (error) ? "FAILURE " : "", ata_mode2str(mode)); - if (!error) - pci_write_config(gparent, 0x40 + (devno << 2), + mode = min(mode, ctlr->chip->max_dma); + mode = ata_highpoint_check_80pin(dev, mode); + /* + * most if not all HPT chips cant really handle that the device is + * running at ATA_UDMA6/ATA133 speed, so we cheat at set the device to + * a max of ATA_UDMA5/ATA100 to guard against suboptimal performance + */ + mode = min(mode, ATA_UDMA5); + pci_write_config(parent, 0x40 + (devno << 2), timings33[ata_mode2idx(mode)][ctlr->chip->cfg1], 4); - atadev->mode = mode; + return (mode); } static int ata_highpoint_check_80pin(device_t dev, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); u_int8_t reg, val, res; - if (ctlr->chip->cfg1 == HPT_374 && pci_get_function(gparent) == 1) { + if (ctlr->chip->cfg1 == HPT_374 && pci_get_function(parent) == 1) { reg = ch->unit ? 0x57 : 0x53; - val = pci_read_config(gparent, reg, 1); - pci_write_config(gparent, reg, val | 0x80, 1); + val = pci_read_config(parent, reg, 1); + pci_write_config(parent, reg, val | 0x80, 1); } else { reg = 0x5b; - val = pci_read_config(gparent, reg, 1); - pci_write_config(gparent, reg, val & 0xfe, 1); + val = pci_read_config(parent, reg, 1); + pci_write_config(parent, reg, val & 0xfe, 1); } - res = pci_read_config(gparent, 0x5a, 1) & (ch->unit ? 0x1:0x2); - pci_write_config(gparent, reg, val, 1); + res = pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x1:0x2); + pci_write_config(parent, reg, val, 1); if (mode > ATA_UDMA2 && res) { ata_print_cable(dev, "controller"); diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c index add18d2d2a5..95e40c1e3fc 100644 --- a/sys/dev/ata/chipsets/ata-intel.c +++ b/sys/dev/ata/chipsets/ata-intel.c @@ -55,9 +55,9 @@ __FBSDID("$FreeBSD$"); static int ata_intel_chipinit(device_t dev); static int ata_intel_ch_attach(device_t dev); static void ata_intel_reset(device_t dev); -static void ata_intel_old_setmode(device_t dev, int mode); -static void ata_intel_new_setmode(device_t dev, int mode); -static void ata_intel_sata_setmode(device_t dev, int mode); +static int ata_intel_old_setmode(device_t dev, int target, int mode); +static int ata_intel_new_setmode(device_t dev, int target, int mode); +static int ata_intel_sata_getrev(device_t dev, int target); static int ata_intel_31244_ch_attach(device_t dev); static int ata_intel_31244_ch_detach(device_t dev); static int ata_intel_31244_status(device_t dev); @@ -181,6 +181,7 @@ ata_intel_chipinit(device_t dev) ctlr->reset = ata_intel_31244_reset; } ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; } /* non SATA intel chips goes here */ @@ -214,9 +215,8 @@ ata_intel_chipinit(device_t dev) ctlr->r_rid2 = PCIR_BAR(5); if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, &ctlr->r_rid2, RF_ACTIVE))) - ctlr->setmode = ata_intel_sata_setmode; - else - ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_intel_sata_getrev; + ctlr->setmode = ata_sata_setmode; } return 0; } @@ -240,6 +240,13 @@ ata_intel_ch_attach(device_t dev) } ch->flags |= ATA_ALWAYS_DMASTAT; + if (ctlr->chip->max_dma >= ATA_SA150) { + if (ctlr->chip->cfg1 == 0 && + (pci_read_config(device_get_parent(dev), 0x90, 1) & 0x04) == 0) + ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; + } else + ch->flags |= ATA_CHECKS_CABLE; return 0; } @@ -259,11 +266,8 @@ ata_intel_reset(device_t dev) /* ICH5 in compat mode has SATA ports as master/slave on 1 channel */ if (pci_read_config(parent, 0x90, 1) & 0x04) mask = 0x0003; - else { + else mask = (0x0001 << ch->unit); - /* XXX SOS should be in intel_ch_attach if we grow it */ - ch->flags |= ATA_NO_SLAVE; - } } pci_write_config(parent, 0x92, pci_read_config(parent, 0x92, 2) & ~mask, 2); DELAY(10); @@ -279,80 +283,70 @@ ata_intel_reset(device_t dev) ata_generic_reset(dev); } -static void -ata_intel_old_setmode(device_t dev, int mode) +static int +ata_intel_old_setmode(device_t dev, int target, int mode) { - /* NOT YET */ + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + + mode = min(mode, ctlr->chip->max_dma); + return (mode); } -static void -ata_intel_new_setmode(device_t dev, int mode) +static int +ata_intel_new_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - u_int32_t reg40 = pci_read_config(gparent, 0x40, 4); - u_int8_t reg44 = pci_read_config(gparent, 0x44, 1); - u_int8_t reg48 = pci_read_config(gparent, 0x48, 1); - u_int16_t reg4a = pci_read_config(gparent, 0x4a, 2); - u_int16_t reg54 = pci_read_config(gparent, 0x54, 2); - u_int32_t mask40 = 0, new40 = 0; - u_int8_t mask44 = 0, new44 = 0; - int error; - u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23, - 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 }; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int piomode; + u_int32_t reg40 = pci_read_config(parent, 0x40, 4); + u_int8_t reg44 = pci_read_config(parent, 0x44, 1); + u_int8_t reg48 = pci_read_config(parent, 0x48, 1); + u_int16_t reg4a = pci_read_config(parent, 0x4a, 2); + u_int16_t reg54 = pci_read_config(parent, 0x54, 2); + u_int32_t mask40 = 0, new40 = 0; + u_int8_t mask44 = 0, new44 = 0; + u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23 }; + u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 }; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - - if ( mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) { - ata_print_cable(dev, "controller"); - mode = ATA_UDMA2; - } - - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { - if (mode >= ATA_UDMA0) { - u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 }; - - pci_write_config(gparent, 0x48, reg48 | (0x0001 << devno), 2); - pci_write_config(gparent, 0x4a, - (reg4a & ~(0x3 << (devno << 2))) | - (utimings[mode & ATA_MODE_MASK] << (devno<<2)), 2); + mode = min(mode, ctlr->chip->max_dma); + if (mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; } - else { - pci_write_config(gparent, 0x48, reg48 & ~(0x0001 << devno), 2); - pci_write_config(gparent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2); + /* Enable/disable UDMA and set timings. */ + if (mode >= ATA_UDMA0) { + pci_write_config(parent, 0x48, reg48 | (0x0001 << devno), 2); + pci_write_config(parent, 0x4a, + (reg4a & ~(0x3 << (devno << 2))) | + (utimings[mode & ATA_MODE_MASK] << (devno<<2)), 2); + piomode = ATA_PIO4; + } else { + pci_write_config(parent, 0x48, reg48 & ~(0x0001 << devno), 2); + pci_write_config(parent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2); + piomode = mode; } reg54 |= 0x0400; - if (mode >= ATA_UDMA3) - reg54 |= (0x1 << devno); - else - reg54 &= ~(0x1 << devno); + /* Set UDMA reference clock (33/66/133MHz). */ + reg54 &= ~(0x1001 << devno); if (mode >= ATA_UDMA5) reg54 |= (0x1000 << devno); - else - reg54 &= ~(0x1000 << devno); - - pci_write_config(gparent, 0x54, reg54, 2); - + else if (mode >= ATA_UDMA3) + reg54 |= (0x1 << devno); + pci_write_config(parent, 0x54, reg54, 2); + /* Allow PIO/WDMA timing controls. */ reg40 &= ~0x00ff00ff; reg40 |= 0x40774077; - - if (atadev->unit == ATA_MASTER) { + /* Set PIO/WDMA timings. */ + if (target == 0) { mask40 = 0x3300; - new40 = timings[ata_mode2idx(mode)] << 8; - } - else { + new40 = timings[ata_mode2idx(piomode)] << 8; + } else { mask44 = 0x0f; - new44 = ((timings[ata_mode2idx(mode)] & 0x30) >> 2) | - (timings[ata_mode2idx(mode)] & 0x03); + new44 = ((timings[ata_mode2idx(piomode)] & 0x30) >> 2) | + (timings[ata_mode2idx(piomode)] & 0x03); } if (ch->unit) { mask40 <<= 16; @@ -360,43 +354,21 @@ ata_intel_new_setmode(device_t dev, int mode) mask44 <<= 4; new44 <<= 4; } - pci_write_config(gparent, 0x40, (reg40 & ~mask40) | new40, 4); - pci_write_config(gparent, 0x44, (reg44 & ~mask44) | new44, 1); - - atadev->mode = mode; - } + pci_write_config(parent, 0x40, (reg40 & ~mask40) | new40, 4); + pci_write_config(parent, 0x44, (reg44 & ~mask44) | new44, 1); + return (mode); } -static void -ata_intel_sata_setmode(device_t dev, int mode) +static int +ata_intel_sata_getrev(device_t dev, int target) { - struct ata_device *atadev = device_get_softc(dev); - - if (atadev->param.satacapabilities != 0x0000 && - atadev->param.satacapabilities != 0xffff) { - - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - int devno = (ch->unit << 1) + atadev->unit; - - /* on some drives we need to set the transfer mode */ - ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, - ata_limit_mode(dev, mode, ATA_UDMA6)); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; /* set ATA_SSTATUS register offset */ ATA_IDX_OUTL(ch, ATA_IDX_ADDR, devno * 0x100); - /* query SATA STATUS for the speed */ - if ((ATA_IDX_INL(ch, ATA_IDX_DATA) & ATA_SS_CONWELL_MASK) == - ATA_SS_CONWELL_GEN2) - atadev->mode = ATA_SA300; - else - atadev->mode = ATA_SA150; - } - else { - mode = ata_limit_mode(dev, mode, ATA_UDMA5); - if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - atadev->mode = mode; - } + return ((ATA_IDX_INL(ch, ATA_IDX_DATA) & 0x0f0) >> 4); } static int @@ -439,6 +411,7 @@ ata_intel_31244_ch_attach(device_t dev) ch->r_io[ATA_BMDTP_PORT].offset = ch_offset + 0x74; ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; ata_pci_hw(dev); ch->hw.status = ata_intel_31244_status; ch->hw.tf_write = ata_intel_31244_tf_write; @@ -471,7 +444,9 @@ static void ata_intel_31244_tf_write(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); +#ifndef ATA_CAM struct ata_device *atadev = device_get_softc(request->dev); +#endif if (request->flags & ATA_R_48BIT) { ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); @@ -487,6 +462,7 @@ ata_intel_31244_tf_write(struct ata_request *request) else { ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); +#ifndef ATA_CAM if (atadev->flags & ATA_D_USE_CHS) { int heads, sectors; @@ -508,13 +484,16 @@ ata_intel_31244_tf_write(struct ata_request *request) sectors) & 0xf)); } else { +#endif ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); 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(request->unit) | ((request->u.ata.lba >> 24) & 0x0f)); +#ifndef ATA_CAM } +#endif } } diff --git a/sys/dev/ata/chipsets/ata-ite.c b/sys/dev/ata/chipsets/ata-ite.c index 61879172aeb..250ca648eb5 100644 --- a/sys/dev/ata/chipsets/ata-ite.c +++ b/sys/dev/ata/chipsets/ata-ite.c @@ -53,8 +53,9 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_ite_chipinit(device_t dev); -static void ata_ite_821x_setmode(device_t dev, int mode); -static void ata_ite_8213_setmode(device_t dev, int mode); +static int ata_ite_ch_attach(device_t dev); +static int ata_ite_821x_setmode(device_t dev, int target, int mode); +static int ata_ite_8213_setmode(device_t dev, int target, int mode); /* @@ -105,143 +106,125 @@ ata_ite_chipinit(device_t dev) ctlr->setmode = ata_ite_821x_setmode; } - + ctlr->ch_attach = ata_ite_ch_attach; return 0; } - -static void -ata_ite_821x_setmode(device_t dev, int mode) + +static int +ata_ite_ch_attach(device_t dev) { - device_t gparent = GRANDPARENT(dev); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int error; - - /* correct the mode for what the HW supports */ - mode = ata_limit_mode(dev, mode, ATA_UDMA6); - - /* check the CBLID bits for 80 conductor cable detection */ - if (mode > ATA_UDMA2 && (pci_read_config(gparent, 0x40, 2) & - (ch->unit ? (1<<3) : (1<<2)))) { - ata_print_cable(dev, "controller"); - mode = ATA_UDMA2; - } - - /* set the wanted mode on the device */ - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%s setting %s on ITE8212F chip\n", - (error) ? "failed" : "success", ata_mode2str(mode)); - - /* if the device accepted the mode change, setup the HW accordingly */ - if (!error) { - if (mode >= ATA_UDMA0) { - u_int8_t udmatiming[] = - { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 }; - - /* enable UDMA mode */ - pci_write_config(gparent, 0x50, - pci_read_config(gparent, 0x50, 1) & - ~(1 << (devno + 3)), 1); - - /* set UDMA timing */ - pci_write_config(gparent, - 0x56 + (ch->unit << 2) + atadev->unit, - udmatiming[mode & ATA_MODE_MASK], 1); - } - else { - u_int8_t chtiming[] = - { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 }; - - /* disable UDMA mode */ - pci_write_config(gparent, 0x50, - pci_read_config(gparent, 0x50, 1) | - (1 << (devno + 3)), 1); - - /* set active and recover timing (shared between master & slave) */ - if (pci_read_config(gparent, 0x54 + (ch->unit << 2), 1) < - chtiming[ata_mode2idx(mode)]) - pci_write_config(gparent, 0x54 + (ch->unit << 2), - chtiming[ata_mode2idx(mode)], 1); - } - atadev->mode = mode; - } + struct ata_channel *ch = device_get_softc(dev); + int error; + + error = ata_pci_ch_attach(dev); + ch->flags |= ATA_CHECKS_CABLE; + return (error); } -static void -ata_ite_8213_setmode(device_t dev, int mode) +static int +ata_ite_821x_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_device *atadev = device_get_softc(dev); - u_int16_t reg40 = pci_read_config(gparent, 0x40, 2); - u_int8_t reg44 = pci_read_config(gparent, 0x44, 1); - u_int8_t reg48 = pci_read_config(gparent, 0x48, 1); - u_int16_t reg4a = pci_read_config(gparent, 0x4a, 2); - u_int16_t reg54 = pci_read_config(gparent, 0x54, 2); - u_int16_t mask40 = 0, new40 = 0; - u_int8_t mask44 = 0, new44 = 0; - int devno = atadev->unit; - int error; - u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23, - 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 }; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int piomode; + u_int8_t udmatiming[] = + { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 }; + u_int8_t chtiming[] = + { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 }; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - - if (mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) { - ata_print_cable(dev, "controller"); - mode = ATA_UDMA2; - } - - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { + mode = min(mode, ctlr->chip->max_dma); + /* check the CBLID bits for 80 conductor cable detection */ + if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x40, 2) & + (ch->unit ? (1<<3) : (1<<2)))) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; + } if (mode >= ATA_UDMA0) { - u_int8_t utimings[] = { 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10 }; + /* enable UDMA mode */ + pci_write_config(parent, 0x50, + pci_read_config(parent, 0x50, 1) & + ~(1 << (devno + 3)), 1); + /* set UDMA timing */ + pci_write_config(parent, + 0x56 + (ch->unit << 2) + target, + udmatiming[mode & ATA_MODE_MASK], 1); + piomode = ATA_PIO4; + } else { + /* disable UDMA mode */ + pci_write_config(parent, 0x50, + pci_read_config(parent, 0x50, 1) | + (1 << (devno + 3)), 1); + piomode = mode; + } + /* set active and recover timing (shared between master & slave) */ + if (pci_read_config(parent, 0x54 + (ch->unit << 2), 1) < + chtiming[ata_mode2idx(piomode)]) + pci_write_config(parent, 0x54 + (ch->unit << 2), + chtiming[ata_mode2idx(piomode)], 1); + return (mode); +} - pci_write_config(gparent, 0x48, reg48 | (0x0001 << devno), 2); - pci_write_config(gparent, 0x4a, - (reg4a & ~(0x3 << (devno << 2))) | - (utimings[mode & ATA_MODE_MASK] << (devno<<2)), 2); +static int +ata_ite_8213_setmode(device_t dev, int target, int mode) +{ + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + int piomode; + u_int16_t reg40 = pci_read_config(parent, 0x40, 2); + u_int8_t reg44 = pci_read_config(parent, 0x44, 1); + u_int8_t reg48 = pci_read_config(parent, 0x48, 1); + u_int16_t reg4a = pci_read_config(parent, 0x4a, 2); + u_int16_t reg54 = pci_read_config(parent, 0x54, 2); + u_int16_t mask40 = 0, new40 = 0; + u_int8_t mask44 = 0, new44 = 0; + u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23 }; + u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 }; + + mode = min(mode, ctlr->chip->max_dma); + + if (mode > ATA_UDMA2 && !(reg54 & (0x10 << target))) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; } - else { - pci_write_config(gparent, 0x48, reg48 & ~(0x0001 << devno), 2); - pci_write_config(gparent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2); + /* Enable/disable UDMA and set timings. */ + if (mode >= ATA_UDMA0) { + pci_write_config(parent, 0x48, reg48 | (0x0001 << target), 2); + pci_write_config(parent, 0x4a, + (reg4a & ~(0x3 << (target << 2))) | + (utimings[mode & ATA_MODE_MASK] << (target<<2)), 2); + piomode = ATA_PIO4; + } else { + pci_write_config(parent, 0x48, reg48 & ~(0x0001 << target), 2); + pci_write_config(parent, 0x4a, (reg4a & ~(0x3 << (target << 2))),2); + piomode = mode; } - if (mode >= ATA_UDMA2) - reg54 |= (0x1 << devno); - else - reg54 &= ~(0x1 << devno); + /* Set UDMA reference clock (33/66/133MHz). */ + reg54 &= ~(0x1001 << target); if (mode >= ATA_UDMA5) - reg54 |= (0x1000 << devno); - else - reg54 &= ~(0x1000 << devno); - pci_write_config(gparent, 0x54, reg54, 2); - + reg54 |= (0x1000 << target); + else if (mode >= ATA_UDMA3) + reg54 |= (0x1 << target); + pci_write_config(parent, 0x54, reg54, 2); + /* Allow PIO/WDMA timing controls. */ reg40 &= 0xff00; reg40 |= 0x4033; - if (atadev->unit == ATA_MASTER) { + /* Set PIO/WDMA timings. */ + if (target == 0) { reg40 |= (ata_atapi(dev) ? 0x04 : 0x00); mask40 = 0x3300; - new40 = timings[ata_mode2idx(mode)] << 8; + new40 = timings[ata_mode2idx(piomode)] << 8; } else { reg40 |= (ata_atapi(dev) ? 0x40 : 0x00); mask44 = 0x0f; - new44 = ((timings[ata_mode2idx(mode)] & 0x30) >> 2) | - (timings[ata_mode2idx(mode)] & 0x03); + new44 = ((timings[ata_mode2idx(piomode)] & 0x30) >> 2) | + (timings[ata_mode2idx(piomode)] & 0x03); } - pci_write_config(gparent, 0x40, (reg40 & ~mask40) | new40, 4); - pci_write_config(gparent, 0x44, (reg44 & ~mask44) | new44, 1); - - atadev->mode = mode; - } + pci_write_config(parent, 0x40, (reg40 & ~mask40) | new40, 4); + pci_write_config(parent, 0x44, (reg44 & ~mask44) | new44, 1); + return (mode); } ATA_DECLARE_DRIVER(ata_ite); diff --git a/sys/dev/ata/chipsets/ata-jmicron.c b/sys/dev/ata/chipsets/ata-jmicron.c index 25310705ecf..13524f1e7c6 100644 --- a/sys/dev/ata/chipsets/ata-jmicron.c +++ b/sys/dev/ata/chipsets/ata-jmicron.c @@ -53,7 +53,8 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_jmicron_chipinit(device_t dev); -static void ata_jmicron_setmode(device_t dev, int mode); +static int ata_jmicron_ch_attach(device_t dev); +static int ata_jmicron_setmode(device_t dev, int target, int mode); /* * JMicron chipset support functions @@ -79,13 +80,8 @@ ata_jmicron_probe(device_t dev) if (!(idx = ata_match_chip(dev, ids))) return ENXIO; - if ((pci_read_config(dev, 0xdf, 1) & 0x40) && - (pci_get_function(dev) == (pci_read_config(dev, 0x40, 1) & 0x02 >> 1))) - sprintf(buffer, "JMicron %s %s controller", - idx->text, ata_mode2str(ATA_UDMA6)); - else - sprintf(buffer, "JMicron %s %s controller", - idx->text, ata_mode2str(idx->max_dma)); + sprintf(buffer, "JMicron %s %s controller", + idx->text, ata_mode2str(idx->max_dma)); device_set_desc_copy(dev, buffer); ctlr->chip = idx; ctlr->chipinit = ata_jmicron_chipinit; @@ -108,7 +104,7 @@ ata_jmicron_chipinit(device_t dev) return 0; /* otherwise we are on the PATA part */ - ctlr->ch_attach = ata_pci_ch_attach; + ctlr->ch_attach = ata_jmicron_ch_attach; ctlr->ch_detach = ata_pci_ch_detach; ctlr->reset = ata_generic_reset; ctlr->setmode = ata_jmicron_setmode; @@ -126,7 +122,7 @@ ata_jmicron_chipinit(device_t dev) bus_generic_attach(dev); } } - ctlr->ch_attach = ata_pci_ch_attach; + ctlr->ch_attach = ata_jmicron_ch_attach; ctlr->ch_detach = ata_pci_ch_detach; ctlr->reset = ata_generic_reset; ctlr->setmode = ata_jmicron_setmode; @@ -135,18 +131,30 @@ ata_jmicron_chipinit(device_t dev) return 0; } -static void -ata_jmicron_setmode(device_t dev, int mode) +static int +ata_jmicron_ch_attach(device_t dev) { - struct ata_device *atadev = device_get_softc(dev); + struct ata_channel *ch = device_get_softc(dev); + int error; + + error = ata_pci_ch_attach(dev); + ch->flags |= ATA_CHECKS_CABLE; + return (error); +} +static int +ata_jmicron_setmode(device_t dev, int target, int mode) +{ + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + + mode = min(mode, ctlr->chip->max_dma); /* check for 80pin cable present */ - if (pci_read_config(dev, 0x40, 1) & 0x08) - mode = ata_limit_mode(dev, mode, ATA_UDMA2); - else - mode = ata_limit_mode(dev, mode, ATA_UDMA6); - if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - atadev->mode = mode; + if (mode > ATA_UDMA2 && pci_read_config(dev, 0x40, 1) & 0x08) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; + } + /* Nothing to do to setup mode, the controller snoop SET_FEATURE cmd. */ + return (mode); } ATA_DECLARE_DRIVER(ata_jmicron); diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c index bda1a17e7fa..0d11266aa2b 100644 --- a/sys/dev/ata/chipsets/ata-marvell.c +++ b/sys/dev/ata/chipsets/ata-marvell.c @@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_marvell_chipinit(device_t dev); static int ata_marvell_ch_attach(device_t dev); -static void ata_marvell_setmode(device_t dev, int mode); +static int ata_marvell_setmode(device_t dev, int target, int mode); static int ata_marvell_edma_ch_attach(device_t dev); static int ata_marvell_edma_ch_detach(device_t dev); static int ata_marvell_edma_status(device_t dev); @@ -170,20 +170,24 @@ ata_marvell_ch_attach(device_t dev) error = ata_pci_ch_attach(dev); /* dont use 32 bit PIO transfers */ ch->flags |= ATA_USE_16BIT; + ch->flags |= ATA_CHECKS_CABLE; return (error); } -static void -ata_marvell_setmode(device_t dev, int mode) +static int +ata_marvell_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_device *atadev = device_get_softc(dev); + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + struct ata_channel *ch = device_get_softc(dev); - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - mode = ata_check_80pin(dev, mode); - if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - atadev->mode = mode; + mode = min(mode, ctlr->chip->max_dma); + /* Check for 80pin cable present. */ + if (mode > ATA_UDMA2 && ATA_IDX_INB(ch, ATA_BMDEVSPEC_0) & 0x01) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; + } + /* Nothing to do to setup mode, the controller snoop SET_FEATURE cmd. */ + return (mode); } int @@ -210,6 +214,7 @@ ata_marvell_edma_chipinit(device_t dev) ctlr->ch_detach = ata_marvell_edma_ch_detach; ctlr->reset = ata_marvell_edma_reset; ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; ctlr->channels = ctlr->chip->cfg1; /* clear host controller interrupts */ @@ -281,6 +286,7 @@ ata_marvell_edma_ch_attach(device_t dev) ch->flags |= ATA_NO_SLAVE; ch->flags |= ATA_USE_16BIT; /* XXX SOS needed ? */ + ch->flags |= ATA_SATA; ata_generic_hw(dev); ch->hw.begin_transaction = ata_marvell_edma_begin_transaction; ch->hw.end_transaction = ata_marvell_edma_end_transaction; @@ -601,8 +607,6 @@ 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; - else - ch->dma.max_iosize = (ATA_DMA_ENTRIES - 1) * PAGE_SIZE; } ATA_DECLARE_DRIVER(ata_marvell); diff --git a/sys/dev/ata/chipsets/ata-micron.c b/sys/dev/ata/chipsets/ata-micron.c index ce758743040..2b74a330588 100644 --- a/sys/dev/ata/chipsets/ata-micron.c +++ b/sys/dev/ata/chipsets/ata-micron.c @@ -51,11 +51,6 @@ __FBSDID("$FreeBSD$"); #include #include -/* local prototypes */ -static int ata_micron_chipinit(device_t dev); -static void ata_micron_setmode(device_t dev, int mode); - - /* * Cenatek chipset support functions */ @@ -68,34 +63,10 @@ ata_micron_probe(device_t dev) pci_get_devid(dev) == ATA_MICRON_RZ1001) { device_set_desc(dev, "RZ 100? ATA controller !WARNING! data loss/corruption risk"); - ctlr->chipinit = ata_micron_chipinit; + ctlr->chipinit = ata_generic_chipinit; return (BUS_PROBE_DEFAULT); } - else - return ENXIO; -} - -static int -ata_micron_chipinit(device_t dev) -{ - struct ata_pci_controller *ctlr = device_get_softc(dev); - - if (ata_setup_interrupt(dev, ata_generic_intr)) - return ENXIO; - - ctlr->setmode = ata_micron_setmode; - return 0; -} - -static void -ata_micron_setmode(device_t dev, int mode) -{ - struct ata_device *atadev = device_get_softc(dev); - - mode = ata_limit_mode(dev, mode, ATA_UDMA2); - mode = ata_check_80pin(dev, mode); - if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - atadev->mode = mode; + return (ENXIO); } ATA_DECLARE_DRIVER(ata_micron); diff --git a/sys/dev/ata/chipsets/ata-national.c b/sys/dev/ata/chipsets/ata-national.c index 840360ad2b6..20cafa533a8 100644 --- a/sys/dev/ata/chipsets/ata-national.c +++ b/sys/dev/ata/chipsets/ata-national.c @@ -53,8 +53,8 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_national_chipinit(device_t dev); -static void ata_national_setmode(device_t dev, int mode); - +static int ata_national_ch_attach(device_t dev); +static int ata_national_setmode(device_t dev, int target, int mode); /* * National chipset support functions @@ -81,53 +81,55 @@ ata_national_chipinit(device_t dev) if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; + ctlr->ch_attach = ata_national_ch_attach; ctlr->setmode = ata_national_setmode; return 0; } -static void -ata_national_setmode(device_t dev, int mode) +static int +ata_national_ch_attach(device_t dev) { - device_t gparent = GRANDPARENT(dev); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - u_int32_t piotiming[] = - { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010, - 0x00803020, 0x20102010, 0x00100010, - 0x00100010, 0x00100010, 0x00100010 }; - u_int32_t dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 }; - u_int32_t udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 }; - int error; + struct ata_channel *ch = device_get_softc(dev); + int error; + + error = ata_pci_ch_attach(dev); + ch->dma.alignment = 16; + ch->dma.max_iosize = 64 * DEV_BSIZE; + return (error); +} - ch->dma.alignment = 16; - ch->dma.max_iosize = 64 * DEV_BSIZE; +static int +ata_national_setmode(device_t dev, int target, int mode) +{ + device_t parent = device_get_parent(dev); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int piomode; + u_int32_t piotiming[] = + { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010, + 0x9172d132, 0x20102010, 0x00100010 }; + u_int32_t dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 }; + u_int32_t udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 }; - mode = ata_limit_mode(dev, mode, ATA_UDMA2); + mode = min(mode, ATA_UDMA2); - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%s setting %s on National chip\n", - (error) ? "failed" : "success", ata_mode2str(mode)); - if (!error) { if (mode >= ATA_UDMA0) { - pci_write_config(gparent, 0x44 + (devno << 3), + pci_write_config(parent, 0x44 + (devno << 3), udmatiming[mode & ATA_MODE_MASK], 4); - } - else if (mode >= ATA_WDMA0) { - pci_write_config(gparent, 0x44 + (devno << 3), + piomode = ATA_PIO4; + } else if (mode >= ATA_WDMA0) { + pci_write_config(parent, 0x44 + (devno << 3), dmatiming[mode & ATA_MODE_MASK], 4); - } - else { - pci_write_config(gparent, 0x44 + (devno << 3), - pci_read_config(gparent, 0x44 + (devno << 3), 4) | + piomode = mode; + } else { + pci_write_config(parent, 0x44 + (devno << 3), + pci_read_config(parent, 0x44 + (devno << 3), 4) | 0x80000000, 4); + piomode = mode; } - pci_write_config(gparent, 0x40 + (devno << 3), - piotiming[ata_mode2idx(mode)], 4); - atadev->mode = mode; - } + pci_write_config(parent, 0x40 + (devno << 3), + piotiming[ata_mode2idx(piomode)], 4); + return (mode); } ATA_DECLARE_DRIVER(ata_national); diff --git a/sys/dev/ata/chipsets/ata-netcell.c b/sys/dev/ata/chipsets/ata-netcell.c index c07df0ea2a5..f6a75451cea 100644 --- a/sys/dev/ata/chipsets/ata-netcell.c +++ b/sys/dev/ata/chipsets/ata-netcell.c @@ -54,8 +54,6 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_netcell_chipinit(device_t dev); static int ata_netcell_ch_attach(device_t dev); -static void ata_netcell_setmode(device_t dev, int mode); - /* * NetCell chipset support functions @@ -82,8 +80,7 @@ ata_netcell_chipinit(device_t dev) return ENXIO; ctlr->ch_attach = ata_netcell_ch_attach; - ctlr->ch_detach = ata_pci_ch_detach; - ctlr->setmode = ata_netcell_setmode; + ctlr->setmode = ata_generic_setmode; return 0; } @@ -98,19 +95,7 @@ ata_netcell_ch_attach(device_t dev) /* the NetCell only supports 16 bit PIO transfers */ ch->flags |= ATA_USE_16BIT; - return 0; } -static void -ata_netcell_setmode(device_t dev, int mode) -{ - struct ata_device *atadev = device_get_softc(dev); - - mode = ata_limit_mode(dev, mode, ATA_UDMA2); - mode = ata_check_80pin(dev, mode); - if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - atadev->mode = mode; -} - ATA_DECLARE_DRIVER(ata_netcell); diff --git a/sys/dev/ata/chipsets/ata-nvidia.c b/sys/dev/ata/chipsets/ata-nvidia.c index cdff8259876..79064f883a3 100644 --- a/sys/dev/ata/chipsets/ata-nvidia.c +++ b/sys/dev/ata/chipsets/ata-nvidia.c @@ -56,7 +56,7 @@ static int ata_nvidia_chipinit(device_t dev); static int ata_nvidia_ch_attach(device_t dev); static int ata_nvidia_status(device_t dev); static void ata_nvidia_reset(device_t dev); -static void ata_nvidia_setmode(device_t dev, int mode); +static int ata_nvidia_setmode(device_t dev, int target, int mode); /* misc defines */ #define NV4 0x01 @@ -231,6 +231,7 @@ ata_nvidia_chipinit(device_t dev) } } ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; } else { /* disable prefetch, postwrite */ @@ -259,7 +260,7 @@ ata_nvidia_ch_attach(device_t dev) ch->hw.status = ata_nvidia_status; ch->flags |= ATA_NO_SLAVE; - + ch->flags |= ATA_SATA; return 0; } @@ -299,36 +300,29 @@ ata_nvidia_reset(device_t dev) ata_generic_reset(dev); } -static void -ata_nvidia_setmode(device_t dev, int mode) +static int +ata_nvidia_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; - int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }; - int devno = (ch->unit << 1) + atadev->unit; - int reg = 0x63 - devno; - int error; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int piomode; + u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 }; + int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }; + int reg = 0x63 - devno; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - mode = ata_check_80pin(dev, mode); + mode = min(mode, ctlr->chip->max_dma); - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", ata_mode2str(mode), - ctlr->chip->text); - if (!error) { - pci_write_config(gparent, reg - 0x08, timings[ata_mode2idx(mode)], 1); - if (mode >= ATA_UDMA0) - pci_write_config(gparent, reg, modes[mode & ATA_MODE_MASK], 1); - else - pci_write_config(gparent, reg, 0x8b, 1); - atadev->mode = mode; - } + if (mode >= ATA_UDMA0) { + pci_write_config(parent, reg, modes[mode & ATA_MODE_MASK], 1); + piomode = ATA_PIO4; + } else { + pci_write_config(parent, reg, 0x8b, 1); + piomode = mode; + } + pci_write_config(parent, reg - 0x08, timings[ata_mode2idx(piomode)], 1); + return (mode); } ATA_DECLARE_DRIVER(ata_nvidia); diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c index ca3243adb74..2f79a46ba1e 100644 --- a/sys/dev/ata/chipsets/ata-promise.c +++ b/sys/dev/ata/chipsets/ata-promise.c @@ -58,7 +58,7 @@ static int ata_promise_status(device_t dev); static int ata_promise_dmastart(struct ata_request *request); static int ata_promise_dmastop(struct ata_request *request); static void ata_promise_dmareset(device_t dev); -static void ata_promise_setmode(device_t dev, int mode); +static int ata_promise_setmode(device_t dev, int target, int mode); static int ata_promise_tx2_ch_attach(device_t dev); static int ata_promise_tx2_status(device_t dev); static int ata_promise_mio_ch_attach(device_t dev); @@ -72,7 +72,7 @@ static int ata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t r static u_int32_t ata_promise_mio_softreset(device_t dev, int port); static void ata_promise_mio_dmainit(device_t dev); static void ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); -static void ata_promise_mio_setmode(device_t dev, int mode); +static int ata_promise_mio_setmode(device_t dev, int target, int mode); static void ata_promise_sx4_intr(void *data); static int ata_promise_sx4_command(struct ata_request *request); static int ata_promise_apkt(u_int8_t *bytep, struct ata_request *request); @@ -369,6 +369,8 @@ ata_promise_ch_attach(device_t dev) } ch->hw.status = ata_promise_status; + ch->flags |= ATA_NO_ATAPI_DMA; + ch->flags |= ATA_CHECKS_CABLE; return 0; } @@ -438,15 +440,13 @@ ata_promise_dmareset(device_t dev) ch->flags &= ~ATA_DMA_ACTIVE; } -static void -ata_promise_setmode(device_t dev, int mode) +static int +ata_promise_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int error; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; u_int32_t timings[][2] = { /* PR_OLD PR_NEW mode */ { 0x004ff329, 0x004fff2f }, /* PIO 0 */ @@ -465,18 +465,16 @@ ata_promise_setmode(device_t dev, int mode) { 0, 0x004127f3 } /* UDMA 5 */ }; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); + mode = min(mode, ctlr->chip->max_dma); switch (ctlr->chip->cfg1) { case PR_OLD: case PR_NEW: - if (mode > ATA_UDMA2 && (pci_read_config(gparent, 0x50, 2) & + if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x50, 2) & (ch->unit ? 1 << 11 : 1 << 10))) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } - if (ata_atapi(dev) && mode > ATA_PIO_MAX) - mode = ata_limit_mode(dev, mode, ATA_PIO_MAX); break; case PR_TX: @@ -499,19 +497,10 @@ ata_promise_setmode(device_t dev, int mode) break; } - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { if (ctlr->chip->cfg1 < PR_TX) - pci_write_config(gparent, 0x60 + (devno << 2), + pci_write_config(parent, 0x60 + (devno << 2), timings[ata_mode2idx(mode)][ctlr->chip->cfg1], 4); - atadev->mode = mode; - } - return; + return (mode); } static int @@ -523,6 +512,7 @@ ata_promise_tx2_ch_attach(device_t dev) return ENXIO; ch->hw.status = ata_promise_tx2_status; + ch->flags |= ATA_CHECKS_CABLE; return 0; } @@ -565,8 +555,10 @@ ata_promise_mio_ch_attach(device_t dev) ch->r_io[ATA_SCONTROL].res = ctlr->r_res2; ch->r_io[ATA_SCONTROL].offset = 0x408 + (ch->unit << 8); ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; } ch->flags |= ATA_USE_16BIT; + ch->flags |= ATA_CHECKS_CABLE; ata_generic_hw(dev); if (ctlr->chip->cfg2 & PR_SX4X) { @@ -997,20 +989,20 @@ ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) args->nsegs = nsegs; } -static void -ata_promise_mio_setmode(device_t dev, int mode) +static int +ata_promise_mio_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + struct ata_channel *ch = device_get_softc(dev); - if ( (ctlr->chip->cfg2 == PR_SATA) || - ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) || - (ctlr->chip->cfg2 == PR_SATA2) || - ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) - ata_sata_setmode(dev, mode); - else - ata_promise_setmode(dev, mode); + if ( (ctlr->chip->cfg2 == PR_SATA) || + ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) || + (ctlr->chip->cfg2 == PR_SATA2) || + ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) + mode = ata_sata_setmode(dev, target, mode); + else + mode = ata_promise_setmode(dev, target, mode); + return (mode); } static void diff --git a/sys/dev/ata/chipsets/ata-serverworks.c b/sys/dev/ata/chipsets/ata-serverworks.c index 886282ebb37..b5a3fc2e532 100644 --- a/sys/dev/ata/chipsets/ata-serverworks.c +++ b/sys/dev/ata/chipsets/ata-serverworks.c @@ -60,7 +60,7 @@ static int ata_serverworks_ch_attach(device_t dev); static int ata_serverworks_ch_detach(device_t dev); static void ata_serverworks_tf_read(struct ata_request *request); static void ata_serverworks_tf_write(struct ata_request *request); -static void ata_serverworks_setmode(device_t dev, int mode); +static int ata_serverworks_setmode(device_t dev, int target, int mode); #ifdef __powerpc__ static int ata_serverworks_status(device_t dev); #endif @@ -147,6 +147,7 @@ ata_serverworks_chipinit(device_t dev) ctlr->ch_attach = ata_serverworks_ch_attach; ctlr->ch_detach = ata_serverworks_ch_detach; ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; return 0; } else if (ctlr->chip->cfg1 == SWKS_33) { @@ -213,6 +214,7 @@ ata_serverworks_ch_attach(device_t dev) ch->r_io[ATA_SCONTROL].offset = ch_offset + 0x48; ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; ata_pci_hw(dev); ch->hw.tf_read = ata_serverworks_tf_read; ch->hw.tf_write = ata_serverworks_tf_write; @@ -287,7 +289,9 @@ static void ata_serverworks_tf_write(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); +#ifndef ATA_CAM struct ata_device *atadev = device_get_softc(request->dev); +#endif if (request->flags & ATA_R_48BIT) { ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); @@ -303,6 +307,7 @@ ata_serverworks_tf_write(struct ata_request *request) else { ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count); +#ifndef ATA_CAM if (atadev->flags & ATA_D_USE_CHS) { int heads, sectors; @@ -324,74 +329,74 @@ ata_serverworks_tf_write(struct ata_request *request) sectors) & 0xf)); } else { +#endif ATA_IDX_OUTW(ch, ATA_SECTOR, request->u.ata.lba); 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(request->unit) | ((request->u.ata.lba >> 24) & 0x0f)); +#ifndef ATA_CAM } +#endif } } -static void -ata_serverworks_setmode(device_t dev, int mode) +static int +ata_serverworks_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int offset = (devno ^ 0x01) << 3; - int error; - u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; - u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 }; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int offset = (devno ^ 0x01) << 3; + int piomode; + u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; + u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 }; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - - mode = ata_check_80pin(dev, mode); - - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { + mode = min(mode, ctlr->chip->max_dma); if (mode >= ATA_UDMA0) { - pci_write_config(gparent, 0x56, - (pci_read_config(gparent, 0x56, 2) & + /* Set UDMA mode, enable UDMA, set WDMA2/PIO4 */ + pci_write_config(parent, 0x56, + (pci_read_config(parent, 0x56, 2) & ~(0xf << (devno << 2))) | ((mode & ATA_MODE_MASK) << (devno << 2)), 2); - pci_write_config(gparent, 0x54, - pci_read_config(gparent, 0x54, 1) | + pci_write_config(parent, 0x54, + pci_read_config(parent, 0x54, 1) | (0x01 << devno), 1); - pci_write_config(gparent, 0x44, - (pci_read_config(gparent, 0x44, 4) & + pci_write_config(parent, 0x44, + (pci_read_config(parent, 0x44, 4) & ~(0xff << offset)) | (dmatimings[2] << offset), 4); - } - else if (mode >= ATA_WDMA0) { - pci_write_config(gparent, 0x54, - pci_read_config(gparent, 0x54, 1) & + piomode = ATA_PIO4; + } else if (mode >= ATA_WDMA0) { + /* Disable UDMA, set WDMA mode and timings, calculate PIO. */ + pci_write_config(parent, 0x54, + pci_read_config(parent, 0x54, 1) & ~(0x01 << devno), 1); - pci_write_config(gparent, 0x44, - (pci_read_config(gparent, 0x44, 4) & + pci_write_config(parent, 0x44, + (pci_read_config(parent, 0x44, 4) & ~(0xff << offset)) | (dmatimings[mode & ATA_MODE_MASK] << offset), 4); - } - else - pci_write_config(gparent, 0x54, - pci_read_config(gparent, 0x54, 1) & + piomode = (mode == ATA_WDMA0) ? ATA_PIO0 : + (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4; + } else { + /* Disable UDMA, set requested PIO. */ + pci_write_config(parent, 0x54, + pci_read_config(parent, 0x54, 1) & ~(0x01 << devno), 1); - - pci_write_config(gparent, 0x40, - (pci_read_config(gparent, 0x40, 4) & + piomode = mode; + } + /* Set PIO mode and timings, calculated above. */ + pci_write_config(parent, 0x4a, + (pci_read_config(parent, 0x4a, 2) & + ~(0xf << (devno << 2))) | + ((piomode - ATA_PIO0) << (devno<<2)),2); + pci_write_config(parent, 0x40, + (pci_read_config(parent, 0x40, 4) & ~(0xff << offset)) | - (piotimings[ata_mode2idx(mode)] << offset), 4); - atadev->mode = mode; - } + (piotimings[ata_mode2idx(piomode)] << offset), 4); + return (mode); } ATA_DECLARE_DRIVER(ata_serverworks); diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c index 34bd92f57c5..066e9280e5d 100644 --- a/sys/dev/ata/chipsets/ata-siliconimage.c +++ b/sys/dev/ata/chipsets/ata-siliconimage.c @@ -54,12 +54,12 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_cmd_ch_attach(device_t dev); static int ata_cmd_status(device_t dev); -static void ata_cmd_setmode(device_t dev, int mode); +static int ata_cmd_setmode(device_t dev, int target, int mode); static int ata_sii_ch_attach(device_t dev); static int ata_sii_ch_detach(device_t dev); static int ata_sii_status(device_t dev); static void ata_sii_reset(device_t dev); -static void ata_sii_setmode(device_t dev, int mode); +static int ata_sii_setmode(device_t dev, int target, int mode); static int ata_siiprb_ch_attach(device_t dev); static int ata_siiprb_ch_detach(device_t dev); static int ata_siiprb_status(device_t dev); @@ -145,6 +145,7 @@ ata_sii_chipinit(device_t dev) ctlr->ch_detach = ata_siiprb_ch_detach; ctlr->reset = ata_siiprb_reset; ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; ctlr->channels = (ctlr->chip->cfg2 == SII_4CH) ? 4 : 2; /* reset controller */ @@ -193,6 +194,7 @@ ata_sii_chipinit(device_t dev) if (ctlr->chip->max_dma >= ATA_SA150) { ctlr->reset = ata_sii_reset; ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; } else ctlr->setmode = ata_sii_setmode; @@ -246,59 +248,37 @@ ata_cmd_status(device_t dev) return 0; } -static void -ata_cmd_setmode(device_t dev, int mode) +static int +ata_cmd_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int error; - - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - - mode = ata_check_80pin(dev, mode); - - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; int treg = 0x54 + ((devno < 3) ? (devno << 1) : 7); int ureg = ch->unit ? 0x7b : 0x73; - - if (mode >= ATA_UDMA0) { - int udmatimings[][2] = { { 0x31, 0xc2 }, { 0x21, 0x82 }, + int piomode; + uint8_t piotimings[] = { 0xa9, 0x57, 0x44, 0x32, 0x3f, 0x87, 0x32, 0x3f }; + uint8_t udmatimings[][2] = { { 0x31, 0xc2 }, { 0x21, 0x82 }, { 0x11, 0x42 }, { 0x25, 0x8a }, { 0x15, 0x4a }, { 0x05, 0x0a } }; - u_int8_t umode = pci_read_config(gparent, ureg, 1); + mode = min(mode, ctlr->chip->max_dma); + if (mode >= ATA_UDMA0) { + u_int8_t umode = pci_read_config(parent, ureg, 1); - umode &= ~(atadev->unit == ATA_MASTER ? 0x35 : 0xca); - umode |= udmatimings[mode & ATA_MODE_MASK][atadev->unit]; - pci_write_config(gparent, ureg, umode, 1); + umode &= ~(target == 0 ? 0x35 : 0xca); + umode |= udmatimings[mode & ATA_MODE_MASK][target]; + pci_write_config(parent, ureg, umode, 1); + piomode = ATA_PIO4; + } else { + pci_write_config(parent, ureg, + pci_read_config(parent, ureg, 1) & + ~(target == 0 ? 0x35 : 0xca), 1); + piomode = mode; } - else if (mode >= ATA_WDMA0) { - int dmatimings[] = { 0x87, 0x32, 0x3f }; - - pci_write_config(gparent, treg, dmatimings[mode & ATA_MODE_MASK],1); - pci_write_config(gparent, ureg, - pci_read_config(gparent, ureg, 1) & - ~(atadev->unit == ATA_MASTER ? 0x35 : 0xca), 1); - } - else { - int piotimings[] = { 0xa9, 0x57, 0x44, 0x32, 0x3f }; - pci_write_config(gparent, treg, - piotimings[(mode & ATA_MODE_MASK) - ATA_PIO0], 1); - pci_write_config(gparent, ureg, - pci_read_config(gparent, ureg, 1) & - ~(atadev->unit == ATA_MASTER ? 0x35 : 0xca), 1); - } - atadev->mode = mode; - } + pci_write_config(parent, treg, piotimings[ata_mode2idx(piomode)], 1); + return (mode); } static int @@ -335,12 +315,12 @@ ata_sii_ch_attach(device_t dev) ch->r_io[ATA_SCONTROL].res = ctlr->r_res2; ch->r_io[ATA_SCONTROL].offset = 0x100 + (unit01 << 7) + (unit10 << 8); ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; /* enable PHY state change interrupt */ 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; @@ -349,6 +329,8 @@ ata_sii_ch_attach(device_t dev) ata_pci_hw(dev); ch->hw.status = ata_sii_status; + if (ctlr->chip->cfg2 & SII_SETCLK) + ch->flags |= ATA_CHECKS_CABLE; return 0; } @@ -386,69 +368,53 @@ ata_sii_reset(device_t dev) ata_generic_reset(dev); } -static void -ata_sii_setmode(device_t dev, int mode) +static int +ata_sii_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int rego = (ch->unit << 4) + (atadev->unit << 1); - int mreg = ch->unit ? 0x84 : 0x80; - int mask = 0x03 << (atadev->unit << 2); - int mval = pci_read_config(gparent, mreg, 1) & ~mask; - int error; - - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - - if (ctlr->chip->cfg2 & SII_SETCLK) { - if (mode > ATA_UDMA2 && (pci_read_config(gparent, 0x79, 1) & - (ch->unit ? 0x02 : 0x01))) { - ata_print_cable(dev, "controller"); - mode = ATA_UDMA2; - } - } - else - mode = ata_check_80pin(dev, mode); - - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (error) - return; - - if (mode >= ATA_UDMA0) { - u_int8_t udmatimings[] = { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 }; - u_int8_t ureg = 0xac + rego; - - pci_write_config(gparent, mreg, - mval | (0x03 << (atadev->unit << 2)), 1); - pci_write_config(gparent, ureg, - (pci_read_config(gparent, ureg, 1) & ~0x3f) | - udmatimings[mode & ATA_MODE_MASK], 1); - - } - else if (mode >= ATA_WDMA0) { - u_int8_t dreg = 0xa8 + rego; - u_int16_t dmatimings[] = { 0x2208, 0x10c2, 0x10c1 }; - - pci_write_config(gparent, mreg, - mval | (0x02 << (atadev->unit << 2)), 1); - pci_write_config(gparent, dreg, dmatimings[mode & ATA_MODE_MASK], 2); - - } - else { + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int rego = (ch->unit << 4) + (target << 1); + int mreg = ch->unit ? 0x84 : 0x80; + int mask = 0x03 << (target << 2); + int mval = pci_read_config(parent, mreg, 1) & ~mask; + int piomode; u_int8_t preg = 0xa4 + rego; + u_int8_t dreg = 0xa8 + rego; + u_int8_t ureg = 0xac + rego; u_int16_t piotimings[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; + u_int16_t dmatimings[] = { 0x2208, 0x10c2, 0x10c1 }; + u_int8_t udmatimings[] = { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 }; - pci_write_config(gparent, mreg, - mval | (0x01 << (atadev->unit << 2)), 1); - pci_write_config(gparent, preg, piotimings[mode & ATA_MODE_MASK], 2); - } - atadev->mode = mode; + mode = min(mode, ctlr->chip->max_dma); + + if (ctlr->chip->cfg2 & SII_SETCLK) { + if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x79, 1) & + (ch->unit ? 0x02 : 0x01))) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; + } + } + if (mode >= ATA_UDMA0) { + pci_write_config(parent, mreg, + mval | (0x03 << (target << 2)), 1); + pci_write_config(parent, ureg, + (pci_read_config(parent, ureg, 1) & ~0x3f) | + udmatimings[mode & ATA_MODE_MASK], 1); + piomode = ATA_PIO4; + } else if (mode >= ATA_WDMA0) { + pci_write_config(parent, mreg, + mval | (0x02 << (target << 2)), 1); + pci_write_config(parent, dreg, dmatimings[mode & ATA_MODE_MASK], 2); + piomode = (mode == ATA_WDMA0) ? ATA_PIO0 : + (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4; + } else { + pci_write_config(parent, mreg, + mval | (0x01 << (target << 2)), 1); + piomode = mode; + } + pci_write_config(parent, preg, piotimings[ata_mode2idx(piomode)], 2); + return (mode); } diff --git a/sys/dev/ata/chipsets/ata-sis.c b/sys/dev/ata/chipsets/ata-sis.c index 5c74e56edf2..80225053c4d 100644 --- a/sys/dev/ata/chipsets/ata-sis.c +++ b/sys/dev/ata/chipsets/ata-sis.c @@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$"); static int ata_sis_chipinit(device_t dev); static int ata_sis_ch_attach(device_t dev); static void ata_sis_reset(device_t dev); -static void ata_sis_setmode(device_t dev, int mode); +static int ata_sis_setmode(device_t dev, int target, int mode); /* misc defines */ #define SIS_33 1 @@ -191,6 +191,7 @@ ata_sis_chipinit(device_t dev) ctlr->reset = ata_sis_reset; } ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; return 0; default: return ENXIO; @@ -217,6 +218,7 @@ ata_sis_ch_attach(device_t dev) ch->r_io[ATA_SCONTROL].res = ctlr->r_res2; ch->r_io[ATA_SCONTROL].offset = 0x08 + offset; ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; /* XXX SOS PHY hotplug handling missing in SiS chip ?? */ /* XXX SOS unknown how to enable PHY state change interrupt */ @@ -230,40 +232,30 @@ ata_sis_reset(device_t dev) ata_generic_reset(dev); } -static void -ata_sis_setmode(device_t dev, int mode) +static int +ata_sis_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int devno = (ch->unit << 1) + atadev->unit; - int error; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); + mode = min(mode, ctlr->chip->max_dma); - if (ctlr->chip->cfg1 == SIS_133NEW) { - if (mode > ATA_UDMA2 && - pci_read_config(gparent, ch->unit ? 0x52 : 0x50,2) & 0x8000) { - ata_print_cable(dev, "controller"); - mode = ATA_UDMA2; - } - } - else { - if (mode > ATA_UDMA2 && - pci_read_config(gparent, 0x48, 1)&(ch->unit ? 0x20 : 0x10)) { - ata_print_cable(dev, "controller"); - mode = ATA_UDMA2; - } - } + if (ctlr->chip->cfg1 == SIS_133NEW) { + if (mode > ATA_UDMA2 && + pci_read_config(parent, ch->unit ? 0x52 : 0x50,2) & 0x8000) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; + } + } else { + if (mode > ATA_UDMA2 && + pci_read_config(parent, 0x48, 1)&(ch->unit ? 0x20 : 0x10)) { + ata_print_cable(dev, "controller"); + mode = ATA_UDMA2; + } + } - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", - ata_mode2str(mode), ctlr->chip->text); - if (!error) { switch (ctlr->chip->cfg1) { case SIS_133NEW: { u_int32_t timings[] = @@ -272,8 +264,8 @@ ata_sis_setmode(device_t dev, int mode) 0x0509347c, 0x0509325c, 0x0509323c, 0x0509322c, 0x0509321c}; u_int32_t reg; - reg = (pci_read_config(gparent, 0x57, 1)&0x40?0x70:0x40)+(devno<<2); - pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 4); + reg = (pci_read_config(parent, 0x57, 1)&0x40?0x70:0x40)+(devno<<2); + pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 4); break; } case SIS_133OLD: { @@ -283,7 +275,7 @@ ata_sis_setmode(device_t dev, int mode) u_int16_t reg = 0x40 + (devno << 1); - pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 2); + pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2); break; } case SIS_100NEW: { @@ -292,7 +284,7 @@ ata_sis_setmode(device_t dev, int mode) 0x0031, 0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131 }; u_int16_t reg = 0x40 + (devno << 1); - pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 2); + pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2); break; } case SIS_100OLD: @@ -303,12 +295,11 @@ ata_sis_setmode(device_t dev, int mode) 0x0301, 0xf301, 0xd301, 0xb301, 0xa301, 0x9301, 0x8301 }; u_int16_t reg = 0x40 + (devno << 1); - pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 2); + pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2); break; } } - atadev->mode = mode; - } + return (mode); } ATA_DECLARE_DRIVER(ata_sis); diff --git a/sys/dev/ata/chipsets/ata-via.c b/sys/dev/ata/chipsets/ata-via.c index 47ebd0a15d8..9aea45d9a9f 100644 --- a/sys/dev/ata/chipsets/ata-via.c +++ b/sys/dev/ata/chipsets/ata-via.c @@ -56,9 +56,9 @@ static int ata_via_chipinit(device_t dev); static int ata_via_ch_attach(device_t dev); static int ata_via_ch_detach(device_t dev); static void ata_via_reset(device_t dev); -static void ata_via_old_setmode(device_t dev, int mode); +static int ata_via_old_setmode(device_t dev, int target, int mode); static void ata_via_southbridge_fixup(device_t dev); -static void ata_via_new_setmode(device_t dev, int mode); +static int ata_via_new_setmode(device_t dev, int target, int mode); /* misc defines */ #define VIA33 0 @@ -152,9 +152,9 @@ ata_via_chipinit(device_t dev) if (ctlr->chip->cfg2 & VIABAR) { ctlr->channels = 3; ctlr->setmode = ata_via_new_setmode; - } - else + } else ctlr->setmode = ata_sata_setmode; + ctlr->getrev = ata_sata_getrev; return 0; } @@ -233,6 +233,7 @@ ata_via_ch_attach(device_t dev) ch->r_io[ATA_SCONTROL].res = ctlr->r_res2; ch->r_io[ATA_SCONTROL].offset = 0x08 + (ch->unit << ctlr->chip->cfg1); ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; /* XXX SOS PHY hotplug handling missing in VIA chip ?? */ /* XXX SOS unknown how to enable PHY state change interrupt */ @@ -277,75 +278,63 @@ ata_via_reset(device_t dev) ata_generic_reset(dev); } -static void -ata_via_new_setmode(device_t dev, int mode) +static int +ata_via_new_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int error; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); - if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1)) { - u_int8_t pio_timings[] = { 0xa8, 0x65, 0x65, 0x32, 0x20, - 0x65, 0x32, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; - u_int8_t dma_timings[] = { 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 }; + if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1)) { + int piomode; + u_int8_t pio_timings[] = { 0xa8, 0x65, 0x65, 0x32, 0x20 }; + u_int8_t dma_timings[] = { 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 }; - mode = ata_check_80pin(dev, ata_limit_mode(dev, mode, ATA_UDMA6)); - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", ata_mode2str(mode), - ctlr->chip->text); - if (!error) { - pci_write_config(gparent, 0xab, pio_timings[ata_mode2idx(mode)], 1); - if (mode >= ATA_UDMA0) - pci_write_config(gparent, 0xb3, + /* This chip can't do WDMA. */ + if (mode >= ATA_WDMA0 && mode < ATA_UDMA0) + mode = ATA_PIO4; + if (mode >= ATA_UDMA0) { + pci_write_config(parent, 0xb3, dma_timings[mode & ATA_MODE_MASK], 1); - atadev->mode = mode; - } - } - else - ata_sata_setmode(dev, mode); + piomode = ATA_PIO4; + } else + piomode = mode; + pci_write_config(parent, 0xab, pio_timings[ata_mode2idx(piomode)], 1); + } else + mode = ata_sata_setmode(dev, target, mode); + return (mode); } -static void -ata_via_old_setmode(device_t dev, int mode) +static int +ata_via_old_setmode(device_t dev, int target, int mode) { - device_t gparent = GRANDPARENT(dev); - struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; - int modes[][7] = { - { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* VIA ATA33 */ - { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 }, /* VIA ATA66 */ - { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 }, /* VIA ATA100 */ - { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 } }; /* VIA ATA133 */ - int devno = (ch->unit << 1) + atadev->unit; - int reg = 0x53 - devno; - int error; + device_t parent = device_get_parent(dev); + struct ata_pci_controller *ctlr = device_get_softc(parent); + struct ata_channel *ch = device_get_softc(dev); + int devno = (ch->unit << 1) + target; + int reg = 0x53 - devno; + int piomode; + uint8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 }; + uint8_t modes[][7] = { + { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* VIA ATA33 */ + { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 }, /* VIA ATA66 */ + { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 }, /* VIA ATA100 */ + { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 } }; /* VIA ATA133 */ - mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); - mode = ata_check_80pin(dev, mode); - - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - if (bootverbose) - device_printf(dev, "%ssetting %s on %s chip\n", - (error) ? "FAILURE " : "", ata_mode2str(mode), - ctlr->chip->text); - if (!error) { - if (ctlr->chip->cfg1 != VIA133) - pci_write_config(gparent, reg - 0x08,timings[ata_mode2idx(mode)],1); - if (mode >= ATA_UDMA0) - pci_write_config(gparent, reg, + mode = min(mode, ctlr->chip->max_dma); + /* Set UDMA timings */ + if (mode >= ATA_UDMA0) { + pci_write_config(parent, reg, modes[ctlr->chip->cfg1][mode & ATA_MODE_MASK], 1); - else - pci_write_config(gparent, reg, 0x8b, 1); - atadev->mode = mode; - } + piomode = ATA_PIO4; + } else { + pci_write_config(parent, reg, 0x8b, 1); + piomode = mode; + } + /* Set WDMA/PIO timings */ + if (ctlr->chip->cfg1 != VIA133) + pci_write_config(parent, reg - 0x08,timings[ata_mode2idx(piomode)], 1); + return (mode); } static void diff --git a/sys/powerpc/powermac/ata_dbdma.c b/sys/powerpc/powermac/ata_dbdma.c index b08ade6bc07..c8f37581b42 100644 --- a/sys/powerpc/powermac/ata_dbdma.c +++ b/sys/powerpc/powermac/ata_dbdma.c @@ -204,7 +204,6 @@ static int ata_dbdma_load(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_dbdma_dmaload_args args; int error; @@ -230,7 +229,7 @@ ata_dbdma_load(struct ata_request *request, void *addr, int *entries) return EIO; } - request->dma = &ch->dma.slot[atadev->unit]; + request->dma = &ch->dma.slot[0]; if ((error = bus_dmamap_load(request->dma->data_tag, request->dma->data_map, request->data, request->bytecount, diff --git a/sys/powerpc/powermac/ata_kauai.c b/sys/powerpc/powermac/ata_kauai.c index 415d0fb0e69..f7b6daa5a7b 100644 --- a/sys/powerpc/powermac/ata_kauai.c +++ b/sys/powerpc/powermac/ata_kauai.c @@ -85,7 +85,7 @@ __FBSDID("$FreeBSD$"); */ static int ata_kauai_probe(device_t dev); static int ata_kauai_attach(device_t dev); -static void ata_kauai_setmode(device_t parent, device_t dev); +static int ata_kauai_setmode(device_t dev, int target, int mode); static int ata_kauai_begin_transaction(struct ata_request *request); static device_method_t ata_kauai_methods[] = { @@ -307,34 +307,26 @@ ata_kauai_attach(device_t dev) return ata_attach(dev); } -static void -ata_kauai_setmode(device_t parent, device_t dev) +static int +ata_kauai_setmode(device_t dev, int target, int mode) { - struct ata_device *atadev = device_get_softc(dev); - struct ata_kauai_softc *sc = device_get_softc(parent); - uint32_t mode; + struct ata_kauai_softc *sc = device_get_softc(dev); - mode = ata_limit_mode(dev,atadev->mode, - (sc->shasta) ? ATA_UDMA6 : ATA_UDMA5); - - if (ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - return; - - atadev->mode = mode; + mode = min(mode,sc->shasta ? ATA_UDMA6 : ATA_UDMA5); if (sc->shasta) { switch (mode & ATA_DMA_MASK) { case ATA_UDMA0: - sc->udmaconf[atadev->unit] + sc->udmaconf[target] = udma_timing_shasta[mode & ATA_MODE_MASK]; break; case ATA_WDMA0: - sc->udmaconf[atadev->unit] = 0; - sc->wdmaconf[atadev->unit] + sc->udmaconf[target] = 0; + sc->wdmaconf[target] = dma_timing_shasta[mode & ATA_MODE_MASK]; break; default: - sc->pioconf[atadev->unit] + sc->pioconf[target] = pio_timing_shasta[(mode & ATA_MODE_MASK) - ATA_PIO0]; break; @@ -342,32 +334,33 @@ ata_kauai_setmode(device_t parent, device_t dev) } else { switch (mode & ATA_DMA_MASK) { case ATA_UDMA0: - sc->udmaconf[atadev->unit] + sc->udmaconf[target] = udma_timing_kauai[mode & ATA_MODE_MASK]; break; case ATA_WDMA0: - sc->udmaconf[atadev->unit] = 0; - sc->wdmaconf[atadev->unit] + sc->udmaconf[target] = 0; + sc->wdmaconf[target] = dma_timing_kauai[mode & ATA_MODE_MASK]; break; default: - sc->pioconf[atadev->unit] + sc->pioconf[target] = pio_timing_kauai[(mode & ATA_MODE_MASK) - ATA_PIO0]; break; } } + + return (mode); } static int ata_kauai_begin_transaction(struct ata_request *request) { - struct ata_device *atadev = device_get_softc(request->dev); struct ata_kauai_softc *sc = device_get_softc(request->parent); - bus_write_4(sc->sc_memr, UDMA_CONFIG_REG, sc->udmaconf[atadev->unit]); + bus_write_4(sc->sc_memr, UDMA_CONFIG_REG, sc->udmaconf[request->unit]); bus_write_4(sc->sc_memr, PIO_CONFIG_REG, - sc->wdmaconf[atadev->unit] | sc->pioconf[atadev->unit]); + sc->wdmaconf[request->unit] | sc->pioconf[request->unit]); return ata_begin_transaction(request); } diff --git a/sys/powerpc/powermac/ata_macio.c b/sys/powerpc/powermac/ata_macio.c index 320e86e3381..447009da7ea 100644 --- a/sys/powerpc/powermac/ata_macio.c +++ b/sys/powerpc/powermac/ata_macio.c @@ -111,7 +111,7 @@ static const struct ide_timings udma_timings[5] = { * Define the macio ata bus attachment. */ static int ata_macio_probe(device_t dev); -static void ata_macio_setmode(device_t parent, device_t dev); +static int ata_macio_setmode(device_t dev, int target, int mode); static int ata_macio_attach(device_t dev); static int ata_macio_begin_transaction(struct ata_request *request); @@ -193,7 +193,7 @@ ata_macio_probe(device_t dev) ata_default_registers(dev); ch->unit = 0; - ch->flags |= ATA_USE_16BIT; + ch->flags |= ATA_USE_16BIT | ATA_NO_ATAPI_DMA; ata_generic_hw(dev); return (ata_probe(dev)); @@ -247,26 +247,15 @@ ata_macio_attach(device_t dev) return ata_attach(dev); } -static void -ata_macio_setmode(device_t parent, device_t dev) +static int +ata_macio_setmode(device_t dev, int target, int mode) { - struct ata_device *atadev = device_get_softc(dev); - struct ata_macio_softc *sc = device_get_softc(parent); - int mode = atadev->mode; + struct ata_macio_softc *sc = device_get_softc(dev); int min_cycle = 0, min_active = 0; int cycle_tick = 0, act_tick = 0, inact_tick = 0, half_tick; - mode = ata_limit_mode(dev, mode, sc->max_mode); - - /* XXX Some controllers don't work correctly with ATAPI DMA */ - if (atadev->param.config & ATA_PROTO_ATAPI) - mode = ata_limit_mode(dev, mode, ATA_PIO_MAX); - - if (ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) - return; - - atadev->mode = mode; + mode = min(mode, sc->max_mode); if ((mode & ATA_DMA_MASK) == ATA_UDMA0) { min_cycle = udma_timings[mode & ATA_MODE_MASK].cycle; @@ -276,7 +265,7 @@ ata_macio_setmode(device_t parent, device_t dev) act_tick = ATA_TIME_TO_TICK(sc->rev,min_active); /* mask: 0x1ff00000 */ - sc->udmaconf[atadev->unit] = + sc->udmaconf[target] = (cycle_tick << 21) | (act_tick << 25) | 0x100000; } else if ((mode & ATA_DMA_MASK) == ATA_WDMA0) { min_cycle = dma_timings[mode & ATA_MODE_MASK].cycle; @@ -288,7 +277,7 @@ ata_macio_setmode(device_t parent, device_t dev) if (sc->rev == 4) { inact_tick = cycle_tick - act_tick; /* mask: 0x001ffc00 */ - sc->wdmaconf[atadev->unit] = + sc->wdmaconf[target] = (act_tick << 10) | (inact_tick << 15); } else { inact_tick = cycle_tick - act_tick - DMA_REC_OFFSET; @@ -297,7 +286,7 @@ ata_macio_setmode(device_t parent, device_t dev) half_tick = 0; /* XXX */ /* mask: 0xfffff800 */ - sc->wdmaconf[atadev->unit] = (half_tick << 21) + sc->wdmaconf[target] = (half_tick << 21) | (inact_tick << 16) | (act_tick << 11); } } else { @@ -313,7 +302,7 @@ ata_macio_setmode(device_t parent, device_t dev) inact_tick = cycle_tick - act_tick; /* mask: 0x000003ff */ - sc->pioconf[atadev->unit] = + sc->pioconf[target] = (inact_tick << 5) | act_tick; } else { if (act_tick < PIO_ACT_MIN) @@ -324,21 +313,22 @@ ata_macio_setmode(device_t parent, device_t dev) inact_tick = PIO_REC_MIN; /* mask: 0x000007ff */ - sc->pioconf[atadev->unit] = + sc->pioconf[target] = (inact_tick << 5) | act_tick; } } + + return (mode); } static int ata_macio_begin_transaction(struct ata_request *request) { - struct ata_device *atadev = device_get_softc(request->dev); struct ata_macio_softc *sc = device_get_softc(request->parent); bus_write_4(sc->sc_mem, ATA_MACIO_TIMINGREG, - sc->udmaconf[atadev->unit] | sc->wdmaconf[atadev->unit] - | sc->pioconf[atadev->unit]); + sc->udmaconf[request->unit] | sc->wdmaconf[request->unit] + | sc->pioconf[request->unit]); return ata_begin_transaction(request); } diff --git a/sys/powerpc/psim/ata_iobus.c b/sys/powerpc/psim/ata_iobus.c index a70d0087a87..60f6c508870 100644 --- a/sys/powerpc/psim/ata_iobus.c +++ b/sys/powerpc/psim/ata_iobus.c @@ -210,7 +210,7 @@ ata_iobus_release_resource(device_t dev, device_t child, int type, int rid, */ static int ata_iobus_sub_probe(device_t dev); -static void ata_iobus_sub_setmode(device_t parent, device_t dev); +static int ata_iobus_sub_setmode(device_t dev, int target, int mode); static device_method_t ata_iobus_sub_methods[] = { /* Device interface */ @@ -245,11 +245,9 @@ ata_iobus_sub_probe(device_t dev) return ata_probe(dev); } -static void -ata_iobus_sub_setmode(device_t parent, device_t dev) +static int +ata_iobus_sub_setmode(device_t parent, int target, int mode) { - struct ata_device *atadev = device_get_softc(dev); - /* Only ever PIO mode here... */ - atadev->mode = ATA_PIO; + return (ATA_PIO); } From 1488409373ba2694b4c5cb05691e2731829f00c7 Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sat, 12 Dec 2009 12:31:11 +0000 Subject: [PATCH 0836/2592] MFC r199186 to stable/8: Fix off by one in ieee80211_send_action_register Found by: phk's FlexeLint in September Reviewed by: rpaulo@ --- 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 a329f4db8a11c1c88af99351713a48f60ab72339 Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sat, 12 Dec 2009 12:34:20 +0000 Subject: [PATCH 0837/2592] MFC r199187 to stable/8: Remove trailing ";" in struct ieee80211_beacon_offsets declaration Found by: phk's FlexeLint in September Reviewed by: rpaulo@ --- 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 59cdac432feea410684bc4ee148689541e98056d Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sat, 12 Dec 2009 12:36:41 +0000 Subject: [PATCH 0838/2592] MFC r199193 to stable/8: - Remove trailing ";" after if statement - Remove #if 0 section that was never needed/used Reviewed by: raj@ --- 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 9562e7e533674d982b203b3f55a75de351962a05 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 12 Dec 2009 14:44:04 +0000 Subject: [PATCH 0839/2592] MFC r200162: Change VOP_FSYNC for zfs vnode from VOP_PANIC to zfs_freebsd_fsync(). --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 2 +- 1 file changed, 1 insertion(+), 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 564871f6929..a8649704213 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 @@ -4983,7 +4983,7 @@ struct vop_vector zfs_vnodeops = { struct vop_vector zfs_fifoops = { .vop_default = &fifo_specops, - .vop_fsync = VOP_PANIC, + .vop_fsync = zfs_freebsd_fsync, .vop_access = zfs_freebsd_access, .vop_getattr = zfs_freebsd_getattr, .vop_inactive = zfs_freebsd_inactive, From f0087a7a3c1f921606121c0e6435b72492574a1a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 12 Dec 2009 20:06:25 +0000 Subject: [PATCH 0840/2592] MFC r199135: Extract the code that records syscall results in the frame into MD function cpu_set_syscall_retval(). --- 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 | 35 ++++++++++++++++++++ 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, 417 insertions(+), 303 deletions(-) diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index cfccf3c3ca6..5583c824143 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -1004,39 +1004,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 c68e9f9087b..2948eb7e000 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -381,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 0ab58f3830f..532f7476ab5 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -417,43 +417,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 71885fb521d..29722944cb3 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -839,7 +839,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 084c5269a8e52e77102c5a978a41fb8017225cda Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sat, 12 Dec 2009 20:24:12 +0000 Subject: [PATCH 0841/2592] MFC: r200215 Add missed in r199135 (MFC'ed in r200443). --- sys/sparc64/sparc64/trap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c index 0c07eafd4f7..1e58351e9f5 100644 --- a/sys/sparc64/sparc64/trap.c +++ b/sys/sparc64/sparc64/trap.c @@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include From 49b7e6f5804dc0f18b6e4fa36f95c35349e9ecf9 Mon Sep 17 00:00:00 2001 From: Shteryana Shopova Date: Sat, 12 Dec 2009 20:26:11 +0000 Subject: [PATCH 0842/2592] MFC r200122 Make sure enough memory is allocated for a struct pft_entry when refreshing the list of pf tables. --- usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c index 919e5d48cbd..4e554c00866 100644 --- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c +++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c @@ -1104,7 +1104,7 @@ pft_refresh(void) } for (i = 0; i < numtbls; i++) { - e = malloc(sizeof(struct pfr_tstats)); + e = malloc(sizeof(struct pft_entry)); if (e == NULL) goto err1; e->index = i + 1; From 5cba3b218f332467a81263e2b9914f4f39c19958 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 13 Dec 2009 14:55:50 +0000 Subject: [PATCH 0843/2592] MFC 198332 Check pointer for NULL before dereferencing it, not after. Originally committed by: brueffer --- 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 cb9f09f87365d497e77c19a41f3310eba008729c Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 13 Dec 2009 15:03:54 +0000 Subject: [PATCH 0844/2592] MFC r198694,r198697 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 --- sys/dev/drm/drm_scatter.c | 71 ++++++++++++++------------------------- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/sys/dev/drm/drm_scatter.c b/sys/dev/drm/drm_scatter.c index 5f8b29b001b..b3ab63b630c 100644 --- a/sys/dev/drm/drm_scatter.c +++ b/sys/dev/drm/drm_scatter.c @@ -47,79 +47,50 @@ 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 */ 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); 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 cd6eecd4c7caad096a0ccf049df4be72f366e254 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sun, 13 Dec 2009 23:56:46 +0000 Subject: [PATCH 0845/2592] MFC r200377: Update to the December 12, 2008 version of this file. The one substantive change is to add the IPv6 address of L. The other changes are all CAPS LOCK related. --- etc/namedb/named.root | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/etc/namedb/named.root b/etc/namedb/named.root index 274a3eefd55..1c41c0e3fec 100644 --- a/etc/namedb/named.root +++ b/etc/namedb/named.root @@ -13,8 +13,8 @@ ; on server FTP.INTERNIC.NET ; -OR- RS.INTERNIC.NET ; -; last update: Feb 04, 2008 -; related version of root zone: 2008020400 +; last update: Dec 12, 2008 +; related version of root zone: 2008121200 ; ; formerly NS.INTERNIC.NET ; @@ -22,68 +22,69 @@ A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4 A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:BA3E::2:30 ; -; formerly NS1.ISI.EDU +; FORMERLY NS1.ISI.EDU ; . 3600000 NS B.ROOT-SERVERS.NET. B.ROOT-SERVERS.NET. 3600000 A 192.228.79.201 ; -; formerly C.PSI.NET +; FORMERLY C.PSI.NET ; . 3600000 NS C.ROOT-SERVERS.NET. C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12 ; -; formerly TERP.UMD.EDU +; FORMERLY TERP.UMD.EDU ; . 3600000 NS D.ROOT-SERVERS.NET. D.ROOT-SERVERS.NET. 3600000 A 128.8.10.90 ; -; formerly NS.NASA.GOV +; FORMERLY NS.NASA.GOV ; . 3600000 NS E.ROOT-SERVERS.NET. E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10 ; -; formerly NS.ISC.ORG +; FORMERLY NS.ISC.ORG ; . 3600000 NS F.ROOT-SERVERS.NET. F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241 -F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2f::f +F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2F::F ; -; formerly NS.NIC.DDN.MIL +; FORMERLY NS.NIC.DDN.MIL ; . 3600000 NS G.ROOT-SERVERS.NET. G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4 ; -; formerly AOS.ARL.ARMY.MIL +; FORMERLY AOS.ARL.ARMY.MIL ; . 3600000 NS H.ROOT-SERVERS.NET. H.ROOT-SERVERS.NET. 3600000 A 128.63.2.53 -H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::803f:235 +H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::803F:235 ; -; formerly NIC.NORDU.NET +; FORMERLY NIC.NORDU.NET ; . 3600000 NS I.ROOT-SERVERS.NET. I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17 ; -; operated by VeriSign, Inc. +; OPERATED BY VERISIGN, INC. ; . 3600000 NS J.ROOT-SERVERS.NET. J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30 J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:C27::2:30 ; -; operated by RIPE NCC +; OPERATED BY RIPE NCC ; . 3600000 NS K.ROOT-SERVERS.NET. K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129 -K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fd::1 +K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7FD::1 ; -; operated by ICANN +; OPERATED BY ICANN ; . 3600000 NS L.ROOT-SERVERS.NET. L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42 +L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:3::42 ; -; operated by WIDE +; OPERATED BY WIDE ; . 3600000 NS M.ROOT-SERVERS.NET. M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33 -M.ROOT-SERVERS.NET. 3600000 AAAA 2001:dc3::35 +M.ROOT-SERVERS.NET. 3600000 AAAA 2001:DC3::35 ; End of File From 8c7e8169eb8fe7e63f2f4f55eafccf4e5dcd35b9 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 00:15:56 +0000 Subject: [PATCH 0846/2592] Merge r197624 from head to stable/8: Add audit events for process descriptor system calls, which will appear in a future OpenBSM release. Sponsored by: Google Obtained from: TrustedBSD Project --- sys/bsm/audit_kevents.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h index 495ae2358d5..f4f77a55163 100644 --- a/sys/bsm/audit_kevents.h +++ b/sys/bsm/audit_kevents.h @@ -598,6 +598,10 @@ #define AUE_FSCTL 43194 /* Darwin. */ #define AUE_FFSCTL 43195 /* Darwin. */ #define AUE_LPATHCONF 43196 /* FreeBSD. */ +#define AUE_PDFORK 43197 /* FreeBSD. */ +#define AUE_PDKILL 43198 /* FreeBSD. */ +#define AUE_PDGETPID 43199 /* FreeBSD. */ +#define AUE_PDWAIT 43200 /* FreeBSD. */ /* * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the From 304e9b147b1570136269d856f14b73f25ff62529 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 00:19:31 +0000 Subject: [PATCH 0847/2592] Merge r197636 from head to stable/8: Reserve system call numbers for Capsicum security framework capabilities, capability mode, and process descriptors: cap_new, cap_getrights, cap_enter, cap_getmode, pdfork, pdkill, pdgetpid, and pdwait. Obtained from: TrustedBSD Project Sponsored by: Google --- sys/compat/freebsd32/syscalls.master | 8 ++++++++ sys/kern/syscalls.master | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 43db906dac0..f5a7455c103 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -905,3 +905,11 @@ 512 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \ struct shmid_ds32 *buf); } 513 AUE_LPATHCONF NOPROTO { int lpathconf(char *path, int name); } +514 AUE_CAP_NEW UNIMPL cap_new +515 AUE_CAP_GETRIGHTS UNIMPL cap_getrights +516 AUE_CAP_ENTER UNIMPL cap_enter +517 AUE_CAP_GETMODE UNIMPL cap_getmode +518 AUE_PDFORK UNIMPL pdfork +519 AUE_PDKILL UNIMPL pdkill +520 AUE_PDGETPID UNIMPL pdgetpid +521 AUE_PDWAIT UNIMPL pdwait diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 4e2e99c09a5..f96ed790afb 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -911,5 +911,13 @@ 512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \ struct shmid_ds *buf); } 513 AUE_LPATHCONF STD { int lpathconf(char *path, int name); } +514 AUE_CAP_NEW UNIMPL cap_new +515 AUE_CAP_GETRIGHTS UNIMPL cap_getrights +516 AUE_CAP_ENTER UNIMPL cap_enter +517 AUE_CAP_GETMODE UNIMPL cap_getmode +518 AUE_PDFORK UNIMPL pdfork +519 AUE_PDKILL UNIMPL pdkill +520 AUE_PDGETPID UNIMPL pdgetpid +521 AUE_PDWAIT UNIMPL pdwait ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master From a43ee308b5da2a4cd2dccfdcee01184e5170e614 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 00:20:48 +0000 Subject: [PATCH 0848/2592] Regenerate sysent files after r200491. --- sys/compat/freebsd32/freebsd32_proto.h | 2 +- sys/compat/freebsd32/freebsd32_syscall.h | 4 ++-- sys/compat/freebsd32/freebsd32_syscalls.c | 10 +++++++++- sys/compat/freebsd32/freebsd32_sysent.c | 10 +++++++++- sys/kern/init_sysent.c | 10 +++++++++- sys/kern/syscalls.c | 10 +++++++++- sys/sys/syscall.h | 4 ++-- sys/sys/syscall.mk | 2 +- sys/sys/sysproto.h | 2 +- 9 files changed, 43 insertions(+), 11 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index 498aaac5e6e..ec3fdc9b62e 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: stable/8/sys/compat/freebsd32/syscalls.master 200404 2009-12-11 11:07:05Z kib + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200491 2009-12-14 00:19:31Z rwatson */ #ifndef _FREEBSD32_SYSPROTO_H_ diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index 7297dbb559b..15f29882d62 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: stable/8/sys/compat/freebsd32/syscalls.master 200404 2009-12-11 11:07:05Z kib + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200491 2009-12-14 00:19:31Z rwatson */ #define FREEBSD32_SYS_syscall 0 @@ -386,4 +386,4 @@ #define FREEBSD32_SYS_freebsd32_msgctl 511 #define FREEBSD32_SYS_freebsd32_shmctl 512 #define FREEBSD32_SYS_lpathconf 513 -#define FREEBSD32_SYS_MAXSYSCALL 514 +#define FREEBSD32_SYS_MAXSYSCALL 522 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index 08bdccbb04a..38eae92812e 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: stable/8/sys/compat/freebsd32/syscalls.master 200404 2009-12-11 11:07:05Z kib + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200491 2009-12-14 00:19:31Z rwatson */ const char *freebsd32_syscallnames[] = { @@ -521,4 +521,12 @@ const char *freebsd32_syscallnames[] = { "freebsd32_msgctl", /* 511 = freebsd32_msgctl */ "freebsd32_shmctl", /* 512 = freebsd32_shmctl */ "lpathconf", /* 513 = lpathconf */ + "#514", /* 514 = cap_new */ + "#515", /* 515 = cap_getrights */ + "#516", /* 516 = cap_enter */ + "#517", /* 517 = cap_getmode */ + "#518", /* 518 = pdfork */ + "#519", /* 519 = pdkill */ + "#520", /* 520 = pdgetpid */ + "#521", /* 521 = pdwait */ }; diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index f331b315750..079a58161cb 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: stable/8/sys/compat/freebsd32/syscalls.master 200404 2009-12-11 11:07:05Z kib + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200491 2009-12-14 00:19:31Z rwatson */ #include "opt_compat.h" @@ -558,4 +558,12 @@ struct sysent freebsd32_sysent[] = { { AS(freebsd32_msgctl_args), (sy_call_t *)freebsd32_msgctl, AUE_MSGCTL, NULL, 0, 0, 0 }, /* 511 = freebsd32_msgctl */ { AS(freebsd32_shmctl_args), (sy_call_t *)freebsd32_shmctl, AUE_SHMCTL, NULL, 0, 0, 0 }, /* 512 = freebsd32_shmctl */ { AS(lpathconf_args), (sy_call_t *)lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0 }, /* 513 = lpathconf */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 514 = cap_new */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 515 = cap_getrights */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 516 = cap_enter */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 517 = cap_getmode */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 518 = pdfork */ + { 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 */ }; diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index bad34c1cbce..3db2956e887 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 195458 2009-07-08 15:23:18Z trasz + * created from FreeBSD: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson */ #include "opt_compat.h" @@ -548,4 +548,12 @@ struct sysent sysent[] = { { AS(msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 511 = msgctl */ { AS(shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 }, /* 512 = shmctl */ { AS(lpathconf_args), (sy_call_t *)lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0 }, /* 513 = lpathconf */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 514 = cap_new */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 515 = cap_getrights */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 516 = cap_enter */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 517 = cap_getmode */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 518 = pdfork */ + { 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 */ }; diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index dbe9e791c2a..9be29fd79a1 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 195458 2009-07-08 15:23:18Z trasz + * created from FreeBSD: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson */ const char *syscallnames[] = { @@ -521,4 +521,12 @@ const char *syscallnames[] = { "msgctl", /* 511 = msgctl */ "shmctl", /* 512 = shmctl */ "lpathconf", /* 513 = lpathconf */ + "#514", /* 514 = cap_new */ + "#515", /* 515 = cap_getrights */ + "#516", /* 516 = cap_enter */ + "#517", /* 517 = cap_getmode */ + "#518", /* 518 = pdfork */ + "#519", /* 519 = pdkill */ + "#520", /* 520 = pdgetpid */ + "#521", /* 521 = pdwait */ }; diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 8e67fdb481c..719093442e9 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 195458 2009-07-08 15:23:18Z trasz + * created from FreeBSD: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson */ #define SYS_syscall 0 @@ -428,4 +428,4 @@ #define SYS_msgctl 511 #define SYS_shmctl 512 #define SYS_lpathconf 513 -#define SYS_MAXSYSCALL 514 +#define SYS_MAXSYSCALL 522 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index dc6ea5e59ed..a50bd5667a8 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 195458 2009-07-08 15:23:18Z trasz +# created from FreeBSD: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson MIASM = \ syscall.o \ exit.o \ diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 7c654bffcb8..2744a7371ee 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 195458 2009-07-08 15:23:18Z trasz + * created from FreeBSD: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson */ #ifndef _SYS_SYSPROTO_H_ From 82c0fd73d4da6f33596f0c9f231566242fd20d01 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 14 Dec 2009 01:05:40 +0000 Subject: [PATCH 0849/2592] MFC r200392: Apply two vendor fixes for CVE-2009-3720. Security: CVE-2009-3720 --- contrib/expat/lib/xmlparse.c | 1 - contrib/expat/lib/xmltok_impl.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/contrib/expat/lib/xmlparse.c b/contrib/expat/lib/xmlparse.c index 94e31de9da3..e111460d0a3 100644 --- a/contrib/expat/lib/xmlparse.c +++ b/contrib/expat/lib/xmlparse.c @@ -3725,7 +3725,6 @@ doProlog(XML_Parser parser, return XML_ERROR_NO_ELEMENTS; default: tok = -tok; - next = end; break; } } diff --git a/contrib/expat/lib/xmltok_impl.c b/contrib/expat/lib/xmltok_impl.c index 12688192522..16dfb85f031 100644 --- a/contrib/expat/lib/xmltok_impl.c +++ b/contrib/expat/lib/xmltok_impl.c @@ -1744,7 +1744,7 @@ PREFIX(updatePosition)(const ENCODING *enc, const char *end, POSITION *pos) { - while (ptr != end) { + while (ptr < end) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \ From b5a12d46d6d4ca271b3dee8f84111d1e4d2ff77e Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 14 Dec 2009 01:10:05 +0000 Subject: [PATCH 0850/2592] MFC rev 200202: Fix Read-After-Write (RAW) dependency violation for ar.ccv in isc_atomic_xadd() and isc_atomic_cmpxchg(). Approved by: dougb@ --- contrib/bind9/lib/isc/ia64/include/isc/atomic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/bind9/lib/isc/ia64/include/isc/atomic.h b/contrib/bind9/lib/isc/ia64/include/isc/atomic.h index 275741bee33..0fac76f3be2 100644 --- a/contrib/bind9/lib/isc/ia64/include/isc/atomic.h +++ b/contrib/bind9/lib/isc/ia64/include/isc/atomic.h @@ -41,7 +41,7 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) { swapped = prev + val; __asm__ volatile( - "mov ar.ccv=%2;" + "mov ar.ccv=%2;;" "cmpxchg4.acq %0=%4,%3,ar.ccv" : "=r" (swapped), "=m" (*p) : "r" (prev), "r" (swapped), "m" (*p) @@ -84,7 +84,7 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) isc_int32_t ret; __asm__ volatile( - "mov ar.ccv=%2;" + "mov ar.ccv=%2;;" "cmpxchg4.acq %0=%4,%3,ar.ccv" : "=r" (ret), "=m" (*p) : "r" (cmpval), "r" (val), "m" (*p) From 7078509346279c368a6a069afa80efeb5f04b5a7 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 10:48:19 +0000 Subject: [PATCH 0851/2592] Merge r197720 from head to stable/8: Don't comment on stream socket handling in sosend_dgram, since that's not handled. --- 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 2f4dd92736a..acccc54cf50 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -961,9 +961,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 ec610c212b6ccf49cc9061fb604b7cb48be32402 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 11:15:47 +0000 Subject: [PATCH 0852/2592] Merge r198393 from head to stable/8: Improve grammar in ip_input comment while attempting to maintain what might be its meaning. (Note, merge of the revision correcting a spelling error in this commit will follow as well!) --- 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 3f4c685d1cb..8798f0c3d2a 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 19c576c8b20902ff1ce86fa239cfc014f814b6f6 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 11:45:53 +0000 Subject: [PATCH 0853/2592] Merge r198417 from head to stable/8: Remove unneeded blank line from bpf_drvinit(). --- sys/net/bpf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 9656a6e7b3d..e0265ec1415 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -2035,7 +2035,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 1120ce6b6964a9abb64de10460f47742de6f1054 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 11:53:02 +0000 Subject: [PATCH 0854/2592] Merge r198438 from head to stable/8: Correct spelling typo in ip_input comment. Pointed out by: N.J. Mann , John Nielsen , julian (!), lstewart --- 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 8798f0c3d2a..d6915d7bf95 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 8b2c0bec3b9c6ac9617c4b20e6756385f148e095 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 12:19:21 +0000 Subject: [PATCH 0855/2592] Merge r197808 from head to stable/8: 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. 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 f7000239aa9991270fa094a4f4ce25990ee3f2d0 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 13:13:43 +0000 Subject: [PATCH 0856/2592] Merge r197841 from head to stable/8: 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. 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 7338f8b0f52..1138483ad2a 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 38420804a67894de3e56f9b308af7e3139894a05 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 13:16:50 +0000 Subject: [PATCH 0857/2592] Merge r199270 from head to stable/8: Fix white space in rtld runtime error printf. --- libexec/rtld-elf/rtld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index bb0485e07cb..7fae418a01b 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -3425,7 +3425,7 @@ locate_dependency(const Obj_Entry *obj, const char *name) if (object_match_name(needed->obj, name)) return needed->obj; } - _rtld_error("%s: Unexpected inconsistency: dependency %s not found", + _rtld_error("%s: Unexpected inconsistency: dependency %s not found", obj->path, name); die(); } From d9adc7058d087c041bd69d36a8c9ab474e7e15c8 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 14 Dec 2009 13:23:33 +0000 Subject: [PATCH 0858/2592] Merge r199798 from head to stable/8: Fix comment typo. Submitted by: Marc Balmer --- sys/dev/fe/if_fe_pccard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/fe/if_fe_pccard.c b/sys/dev/fe/if_fe_pccard.c index e1cb10d6476..ee101c641ca 100644 --- a/sys/dev/fe/if_fe_pccard.c +++ b/sys/dev/fe/if_fe_pccard.c @@ -306,7 +306,7 @@ fe_pccard_xircom_mac(const struct pccard_tuple *tuple, void *argp) * Probe and initialization for TDK/CONTEC PCMCIA Ethernet interface. * by MASUI Kenji * - * (Contec uses TDK Ethenet chip -- hosokawa) + * (Contec uses TDK Ethernet chip -- hosokawa) * * This version of fe_probe_tdk has been rewrote to handle * *generic* PC Card implementation of Fujitsu MB8696x family. The From e88e64d392a28e4b47978dc52e53e85e46fa0976 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 14 Dec 2009 17:42:40 +0000 Subject: [PATCH 0859/2592] MFC rev 200397: Fix interrupt handling. PR: kern/140947 --- sys/dev/puc/puc.c | 114 ++++++++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 49 deletions(-) diff --git a/sys/dev/puc/puc.c b/sys/dev/puc/puc.c index 39e7a19a611..b6fa3c5e560 100644 --- a/sys/dev/puc/puc.c +++ b/sys/dev/puc/puc.c @@ -129,62 +129,78 @@ puc_intr(void *arg) { struct puc_port *port; struct puc_softc *sc = arg; - u_long dev, devs; - int i, idx, ipend, isrc; + u_long ds, dev, devs; + int i, idx, ipend, isrc, nints; uint8_t ilr; - devs = sc->sc_serdevs; - if (sc->sc_ilr == PUC_ILR_DIGI) { - idx = 0; - while (devs & (0xfful << idx)) { - ilr = ~bus_read_1(sc->sc_port[idx].p_rres, 7); - devs &= ~0ul ^ ((u_long)ilr << idx); - idx += 8; - } - } else if (sc->sc_ilr == PUC_ILR_QUATECH) { + nints = 0; + while (1) { /* - * Don't trust the value if it's the same as the option - * register. It may mean that the ILR is not active and - * we're reading the option register instead. This may - * lead to false positives on 8-port boards. + * Obtain the set of devices with pending interrupts. */ - ilr = bus_read_1(sc->sc_port[0].p_rres, 7); - if (ilr != (sc->sc_cfg_data & 0xff)) - devs &= (u_long)ilr; - } - - ipend = 0; - idx = 0, dev = 1UL; - while (devs != 0UL) { - while ((devs & dev) == 0UL) - idx++, dev <<= 1; - devs &= ~dev; - port = &sc->sc_port[idx]; - port->p_ipend = SERDEV_IPEND(port->p_dev); - ipend |= port->p_ipend; - } - - i = 0, isrc = SER_INT_OVERRUN; - while (ipend) { - while (i < PUC_ISRCCNT && !(ipend & isrc)) - i++, isrc <<= 1; - KASSERT(i < PUC_ISRCCNT, ("%s", __func__)); - ipend &= ~isrc; - idx = 0, dev = 1UL; devs = sc->sc_serdevs; - while (devs != 0UL) { - while ((devs & dev) == 0UL) - idx++, dev <<= 1; - devs &= ~dev; - port = &sc->sc_port[idx]; - if (!(port->p_ipend & isrc)) - continue; - if (port->p_ihsrc[i] != NULL) - (*port->p_ihsrc[i])(port->p_iharg); + if (sc->sc_ilr == PUC_ILR_DIGI) { + idx = 0; + while (devs & (0xfful << idx)) { + ilr = ~bus_read_1(sc->sc_port[idx].p_rres, 7); + devs &= ~0ul ^ ((u_long)ilr << idx); + idx += 8; + } + } else if (sc->sc_ilr == PUC_ILR_QUATECH) { + /* + * Don't trust the value if it's the same as the option + * register. It may mean that the ILR is not active and + * we're reading the option register instead. This may + * lead to false positives on 8-port boards. + */ + ilr = bus_read_1(sc->sc_port[0].p_rres, 7); + if (ilr != (sc->sc_cfg_data & 0xff)) + devs &= (u_long)ilr; + } + if (devs == 0UL) + break; + + /* + * Obtain the set of interrupt sources from those devices + * that have pending interrupts. + */ + ipend = 0; + idx = 0, dev = 1UL; + ds = devs; + while (ds != 0UL) { + while ((ds & dev) == 0UL) + idx++, dev <<= 1; + ds &= ~dev; + port = &sc->sc_port[idx]; + port->p_ipend = SERDEV_IPEND(port->p_dev); + ipend |= port->p_ipend; + } + if (ipend == 0) + break; + + i = 0, isrc = SER_INT_OVERRUN; + while (ipend) { + while (i < PUC_ISRCCNT && !(ipend & isrc)) + i++, isrc <<= 1; + KASSERT(i < PUC_ISRCCNT, ("%s", __func__)); + ipend &= ~isrc; + idx = 0, dev = 1UL; + ds = devs; + while (ds != 0UL) { + while ((ds & dev) == 0UL) + idx++, dev <<= 1; + ds &= ~dev; + port = &sc->sc_port[idx]; + if (!(port->p_ipend & isrc)) + continue; + if (port->p_ihsrc[i] != NULL) + (*port->p_ihsrc[i])(port->p_iharg); + nints++; + } } - return (FILTER_HANDLED); } - return (FILTER_STRAY); + + return ((nints > 0) ? FILTER_HANDLED : FILTER_STRAY); } int From 3a6f842965ae5f238a217fcd8c366b945770e5ca Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Mon, 14 Dec 2009 21:50:34 +0000 Subject: [PATCH 0860/2592] 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 a6b1019578138b23bfd35c07947883040af10dbe Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 14 Dec 2009 22:38:51 +0000 Subject: [PATCH 0861/2592] MFC r199123: 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 PR: bin/137707 --- 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 070bb9781fe..40c08ca98f2 100755 --- a/contrib/ee/ee.c +++ b/contrib/ee/ee.c @@ -1993,7 +1993,7 @@ char *cmd_str; int number; int i; char *ptr; - char *direction = NULL; + char *direction = "d"; struct text *t_line; ptr = cmd_str; From deeab3c4448612f03640a92f985569408beebe25 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Tue, 15 Dec 2009 00:26:42 +0000 Subject: [PATCH 0862/2592] sync with head --- release/picobsd/bridge/PICOBSD | 7 +++++-- release/picobsd/bridge/crunch.conf | 5 ++++- release/picobsd/build/picobsd | 8 ++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/release/picobsd/bridge/PICOBSD b/release/picobsd/bridge/PICOBSD index 150a44d38e7..07e3bc2d53c 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 @@ -43,7 +46,7 @@ options IPDIVERT # divert (for natd) # Support for bridging and bandwidth limiting options DUMMYNET device if_bridge -options HZ=1000 +#options HZ=1000 device random # used by ssh device pci diff --git a/release/picobsd/bridge/crunch.conf b/release/picobsd/bridge/crunch.conf index 39c1b1f51a3..c81d00f7877 100644 --- a/release/picobsd/bridge/crunch.conf +++ b/release/picobsd/bridge/crunch.conf @@ -98,13 +98,15 @@ progs cat tail tee progs test ln test [ +progs less +ln less more progs mount progs minigzip ln minigzip gzip progs kill progs df progs ps -progs ns # this is the +progs ns # this is the picobsd version ln ns netstat progs vm progs hostname @@ -178,3 +180,4 @@ libs_so -lkvm libs_so -lz libs_so -lbsdxml libs_so -lsbuf +libs_so -ljail # used by ifconfig diff --git a/release/picobsd/build/picobsd b/release/picobsd/build/picobsd index 9bc08df947f..0549b0c6e69 100755 --- a/release/picobsd/build/picobsd +++ b/release/picobsd/build/picobsd @@ -167,7 +167,7 @@ create_includes_and_libraries2() { # opt_dir opt_target local no log "create_includes_and_libraries2() for ${SRC}" if [ ${OSVERSION} -ge 600000 ] ; then - no="-DNO_CLEAN -DNO_PROFILE -DNO_GAMES -DNO_LIBC_R" + no="-DNO_CLEAN -DNO_PROFILE -DNO_GAMES -DNO_LIBC_R" # WITOUT_CDDL=1" else no="-DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R" fi @@ -587,8 +587,9 @@ find_progs() { # programs local i u_progs="`find_progs_helper $*`" local o=${o_objdir:-${_SHLIBDIRPREFIX}} + log "looking for libs for $u_progs in $_SHLIBDIRPREFIX" [ -z "${u_progs}" ] && return 1 # not found, error - i="`ldd ${u_progs} | grep -v '^/' | awk '{print $1}' | sort | uniq`" + i="`LD_LIBRARY_PATH=$o/lib ldd ${u_progs} | grep -v '^/' | awk '{print $1}' | sort | uniq`" u_libs="`find_progs_helper $i`" return 0 } @@ -719,8 +720,7 @@ populate_mfs_tree() { (cd ${dst}; chown -R root . ) fi - # If we are building a shared 'crunch', take the libraries - # and the dynamic loader as well + log "for a shared 'crunch' take libraries and dynamic loader as well" find_progs ${dst}/stand/crunch if [ -n "${u_libs}" ] ; then mkdir -p ${dst}/lib && cp -p ${u_libs} ${dst}/lib From 205c44d9cd28a5a72ffd59f1a91d2c20ee93996d Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 15 Dec 2009 01:14:33 +0000 Subject: [PATCH 0863/2592] MFC r200287: Allow using IPv6 in nfsrvd_sentcache() callback. PR: kern/141289 Submitted by: Petr Lampa --- sys/fs/nfsserver/nfs_nfsdcache.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdcache.c b/sys/fs/nfsserver/nfs_nfsdcache.c index a83510e73cc..2598fb83b3a 100644 --- a/sys/fs/nfsserver/nfs_nfsdcache.c +++ b/sys/fs/nfsserver/nfs_nfsdcache.c @@ -522,8 +522,9 @@ nfsrvd_sentcache(struct nfsrvcache *rp, struct socket *so, int err) if (!(rp->rc_flag & RC_LOCKED)) panic("nfsrvd_sentcache not locked"); if (!err) { - if (so->so_proto->pr_domain->dom_family != AF_INET || - so->so_proto->pr_protocol != IPPROTO_TCP) + if ((so->so_proto->pr_domain->dom_family != AF_INET && + so->so_proto->pr_domain->dom_family != AF_INET6) || + so->so_proto->pr_protocol != IPPROTO_TCP) panic("nfs sent cache"); if (nfsrv_getsockseqnum(so, &rp->rc_tcpseq)) rp->rc_flag |= RC_TCPSEQ; From b16d0f5d509a0df754e26964299c6fc73617fb66 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Tue, 15 Dec 2009 07:32:08 +0000 Subject: [PATCH 0864/2592] MFC: expose only bio_cmd and bio_flags values to userland --- sys/sys/bio.h | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/sys/sys/bio.h b/sys/sys/bio.h index 5af902bdae6..8b6ff0ec696 100644 --- a/sys/sys/bio.h +++ b/sys/sys/bio.h @@ -40,6 +40,22 @@ #include +/* bio_cmd */ +#define BIO_READ 0x01 +#define BIO_WRITE 0x02 +#define BIO_DELETE 0x04 +#define BIO_GETATTR 0x08 +#define BIO_FLUSH 0x10 +#define BIO_CMD0 0x20 /* Available for local hacks */ +#define BIO_CMD1 0x40 /* Available for local hacks */ +#define BIO_CMD2 0x80 /* Available for local hacks */ + +/* bio_flags */ +#define BIO_ERROR 0x01 +#define BIO_DONE 0x02 +#define BIO_ONQUEUE 0x04 + +#ifdef _KERNEL struct disk; struct bio; @@ -95,23 +111,6 @@ struct bio { daddr_t bio_pblkno; /* physical block number */ }; -/* bio_cmd */ -#define BIO_READ 0x01 -#define BIO_WRITE 0x02 -#define BIO_DELETE 0x04 -#define BIO_GETATTR 0x08 -#define BIO_FLUSH 0x10 -#define BIO_CMD0 0x20 /* Available for local hacks */ -#define BIO_CMD1 0x40 /* Available for local hacks */ -#define BIO_CMD2 0x80 /* Available for local hacks */ - -/* bio_flags */ -#define BIO_ERROR 0x01 -#define BIO_DONE 0x02 -#define BIO_ONQUEUE 0x04 - -#ifdef _KERNEL - struct uio; struct devstat; From abc1e8de6ce3f5e8e3f2e385c05fb870ac241865 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Tue, 15 Dec 2009 10:00:00 +0000 Subject: [PATCH 0865/2592] - MFC r197832, r197834, r197837: - 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. --- share/man/man4/bge.4 | 8 +- sys/dev/bge/if_bge.c | 82 ++++++++++++++++---- sys/dev/bge/if_bgereg.h | 168 +++++++++++++++++++++++++--------------- 3 files changed, 179 insertions(+), 79 deletions(-) diff --git a/share/man/man4/bge.4 b/share/man/man4/bge.4 index 1d00183c8ac..1a98ffb8934 100644 --- a/share/man/man4/bge.4 +++ b/share/man/man4/bge.4 @@ -31,12 +31,12 @@ .\" .\" $FreeBSD$ .\" -.Dd Oct 21, 2009 +.Dd December 15, 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 diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 48170a4dd61..18db5590a8d 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,9 +1788,8 @@ 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) - val |= 1 << 29; + if (BGE_IS_5755_PLUS(sc)) + val |= BGE_WDMAMODE_STATUS_TAG_FIX; /* Turn on write DMA state machine */ CSR_WRITE_4(sc, BGE_WDMA_MODE, val); @@ -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..ab336f44627 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 @@ -1409,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 @@ -2101,6 +2124,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 +2139,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 +2162,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 +2215,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 +2603,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 +2614,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 8e11fcdb916303807b90cb74132cccbb41022e56 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Tue, 15 Dec 2009 10:16:57 +0000 Subject: [PATCH 0866/2592] MFC r198318: - 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. --- 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 18db5590a8d..251f5b5e08e 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 49040676828ecd04bd9aed3a55973fdc47b94718 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Tue, 15 Dec 2009 15:01:52 +0000 Subject: [PATCH 0867/2592] MFC r199995: Don't try to bind to an anycast address. The KAME IPv6 stack doesn't allow bind to an anycast address. It does away with an annoying message. --- contrib/ntp/ntpd/ntp_io.c | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/contrib/ntp/ntpd/ntp_io.c b/contrib/ntp/ntpd/ntp_io.c index faa46461f48..d3e909d063d 100644 --- a/contrib/ntp/ntpd/ntp_io.c +++ b/contrib/ntp/ntpd/ntp_io.c @@ -65,6 +65,12 @@ #endif /* IPV6 Multicast Support */ #endif /* IPv6 Support */ +#ifdef INCLUDE_IPV6_SUPPORT +#include +#include +#include +#endif /* !INCLUDE_IPV6_SUPPORT */ + extern int listen_to_virtual_ips; extern const char *specific_interface; @@ -1137,6 +1143,36 @@ set_wildcard_reuse(int family, int on) } #endif /* OS_NEEDS_REUSEADDR_FOR_IFADDRBIND */ +#ifdef INCLUDE_IPV6_SUPPORT +static isc_boolean_t +is_anycast(struct sockaddr *sa, char *name) +{ +#if defined(SIOCGIFAFLAG_IN6) && defined(IN6_IFF_ANYCAST) + struct in6_ifreq ifr6; + int fd; + u_int32_t flags6; + + if (sa->sa_family != AF_INET6) + return ISC_FALSE; + if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) + return ISC_FALSE; + memset(&ifr6, 0, sizeof(ifr6)); + memcpy(&ifr6.ifr_addr, (struct sockaddr_in6 *)sa, + sizeof(struct sockaddr_in6)); + strlcpy(ifr6.ifr_name, name, IF_NAMESIZE); + if (ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) < 0) { + close(fd); + return ISC_FALSE; + } + close(fd); + flags6 = ifr6.ifr_ifru.ifru_flags6; + if ((flags6 & IN6_IFF_ANYCAST) != 0) + return ISC_TRUE; +#endif /* !SIOCGIFAFLAG_IN6 || !IN6_IFF_ANYCAST */ + return ISC_FALSE; +} +#endif /* !INCLUDE_IPV6_SUPPORT */ + /* * update_interface strategy * @@ -1276,6 +1312,11 @@ update_interfaces( if (is_wildcard_addr(&interface.sin)) continue; +#ifdef INCLUDE_IPV6_SUPPORT + if (is_anycast((struct sockaddr *)&interface.sin, isc_if.name)) + continue; +#endif /* !INCLUDE_IPV6_SUPPORT */ + /* * map to local *address* in order * to map all duplicate interfaces to an interface structure From b7fc89b74b7213ab8b669c6bf8205938540690e8 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 15 Dec 2009 20:00:34 +0000 Subject: [PATCH 0868/2592] MFC: r200272 Add additional checks of the kernel stack addresses in order to ensure we don't overrun the beginning of the call chain. --- sys/sparc64/sparc64/stack_machdep.c | 14 +++++++++++--- sys/sun4v/sun4v/stack_machdep.c | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/sys/sparc64/sparc64/stack_machdep.c b/sys/sparc64/sparc64/stack_machdep.c index f05ad6b7f49..a4309ef45c4 100644 --- a/sys/sparc64/sparc64/stack_machdep.c +++ b/sys/sparc64/sparc64/stack_machdep.c @@ -36,15 +36,20 @@ __FBSDID("$FreeBSD$"); #include #include -static void stack_capture(struct stack *st, struct frame *fp); +static void stack_capture(struct stack *st, struct frame *frame); static void -stack_capture(struct stack *st, struct frame *fp) +stack_capture(struct stack *st, struct frame *frame) { + struct frame *fp; vm_offset_t callpc; stack_zero(st); - while (1) { + fp = frame; + for (;;) { + if (!INKERNEL((vm_offset_t)fp) || + !ALIGNED_POINTER(fp, uint64_t)) + break; callpc = fp->fr_pc; if (!INKERNEL(callpc)) break; @@ -56,6 +61,9 @@ stack_capture(struct stack *st, struct frame *fp) break; if (stack_put(st, callpc) == -1) break; + if (v9next_frame(fp) <= fp || + v9next_frame(fp) >= frame + KSTACK_PAGES * PAGE_SIZE) + break; fp = v9next_frame(fp); } } diff --git a/sys/sun4v/sun4v/stack_machdep.c b/sys/sun4v/sun4v/stack_machdep.c index e29ce88ef73..6b91dc1d52f 100644 --- a/sys/sun4v/sun4v/stack_machdep.c +++ b/sys/sun4v/sun4v/stack_machdep.c @@ -36,20 +36,28 @@ __FBSDID("$FreeBSD$"); #include #include -static void stack_capture(struct stack *st, struct frame *fp); +static void stack_capture(struct stack *st, struct frame *frame); static void -stack_capture(struct stack *st, struct frame *fp) +stack_capture(struct stack *st, struct frame *frame) { + struct frame *fp; vm_offset_t callpc; stack_zero(st); - while (1) { + fp = frame; + for (;;) { + if (!INKERNEL((vm_offset_t)fp) || + !ALIGNED_POINTER(fp, uint64_t)) + break; callpc = fp->fr_pc; if (!INKERNEL(callpc)) break; if (stack_put(st, callpc) == -1) break; + if (v9next_frame(fp) <= fp || + v9next_frame(fp) >= frame + KSTACK_PAGES * PAGE_SIZE) + break; fp = v9next_frame(fp); } } From 83374e070cffb136f8105d97620210e814297a7e Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 15 Dec 2009 20:47:51 +0000 Subject: [PATCH 0869/2592] Add SA-09:15.ssl, SA-09:16.rtld and SA-09:17.freebsd-update. --- .../doc/en_US.ISO8859-1/errata/article.sgml | 77 ++++++++++--------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/release/doc/en_US.ISO8859-1/errata/article.sgml b/release/doc/en_US.ISO8859-1/errata/article.sgml index a765881d722..32a6bdac435 100644 --- a/release/doc/en_US.ISO8859-1/errata/article.sgml +++ b/release/doc/en_US.ISO8859-1/errata/article.sgml @@ -16,7 +16,7 @@ %release; - + ]>
@@ -40,12 +40,7 @@ $FreeBSD$ - 2000 - 2001 - 2002 - 2003 - 2004 - 2005 + 2009 The &os; Documentation Project @@ -130,51 +125,59 @@ Security Advisories -No advisories. -]]> + The following security advisories pertain to &os; &release.bugfix;. + For more information, consult the individual advisories available from + . -No advisories. -]]> + + + + + + + + Advisory + Date + Topic + + -No advisories. -]]> + + + SA-09:17.freebsd-update + 03 December 2009 + Inappropriate directory permissions in freebsd-update(8) + + + SA-09:16.rtld + 03 December 2009 + Improper environment sanitization in rtld(1) + + + SA-09:15.ssl + 03 December 2009 + SSL protocol flaw + + + + Open Issues -No open issues. -]]> - -No open issues. -]]> - -No open issues. -]]> - Late-Breaking News + Late-Breaking News and Corrections -No news. -]]> - -No news. -]]> - -No news. -]]>
From c08a53d0ad3ecf739d0db1f5793992c7f43e0414 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Tue, 15 Dec 2009 23:05:16 +0000 Subject: [PATCH 0870/2592] Re-apply the fix from r199029 (MFC from r198162) to allow $name_program to override $command. PR: conf//141642 Submitted by: Petr Lampa --- etc/rc.subr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc.subr b/etc/rc.subr index 04166749eb8..23811af7451 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=${_override_command:-$command} _keywords="start stop restart rcvar $extra_commands" rc_pid= From 2750344277f28e42d90b100a2b6af6e1997e44d6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 16 Dec 2009 17:48:26 +0000 Subject: [PATCH 0871/2592] MFC r200607: Large I/Os on Promise controllers reported to cause UDMA ICRC errors and subsequent timeouts. Restore previous limit for now, at least until I will have hardware to experiment. PR: kern/141438 --- sys/dev/ata/chipsets/ata-promise.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c index 2f79a46ba1e..3dad5d01f4f 100644 --- a/sys/dev/ata/chipsets/ata-promise.c +++ b/sys/dev/ata/chipsets/ata-promise.c @@ -957,6 +957,7 @@ ata_promise_mio_dmainit(device_t dev) ata_dmainit(dev); /* note start and stop are not used here */ ch->dma.setprd = ata_promise_mio_setprd; + ch->dma.max_iosize = 65536; } From 23c703cfc8b325c2699988fba0031d11783c967f Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Wed, 16 Dec 2009 18:39:32 +0000 Subject: [PATCH 0872/2592] MFC: r200459 Unbreak the ata_atapi() usage. Since r200171 (MFC'ed in r200432) the mode setting functions get a ata_device type device passed instead of a ata_channel one, thus ata_atapi() has to be adjusted accordingly. Reviewed by: mav --- sys/dev/ata/ata-all.c | 7 +++---- sys/dev/ata/ata-all.h | 2 +- sys/dev/ata/chipsets/ata-ite.c | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 2fc59879840..6bbff47a945 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -1150,12 +1150,11 @@ ata_satarev2str(int rev) } int -ata_atapi(device_t dev) +ata_atapi(device_t dev, int target) { - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); + struct ata_channel *ch = device_get_softc(dev); - return (ch->devices & (ATA_ATAPI_MASTER << atadev->unit)); + return (ch->devices & (ATA_ATAPI_MASTER << target)); } int diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 32f095ec4ee..23dc458c697 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -622,7 +622,7 @@ void ata_udelay(int interval); char *ata_unit2str(struct ata_device *atadev); const char *ata_mode2str(int mode); const char *ata_satarev2str(int rev); -int ata_atapi(device_t dev); +int ata_atapi(device_t dev, int target); int ata_pmode(struct ata_params *ap); int ata_wmode(struct ata_params *ap); int ata_umode(struct ata_params *ap); diff --git a/sys/dev/ata/chipsets/ata-ite.c b/sys/dev/ata/chipsets/ata-ite.c index 250ca648eb5..f8bc57dff9b 100644 --- a/sys/dev/ata/chipsets/ata-ite.c +++ b/sys/dev/ata/chipsets/ata-ite.c @@ -212,12 +212,12 @@ ata_ite_8213_setmode(device_t dev, int target, int mode) reg40 |= 0x4033; /* Set PIO/WDMA timings. */ if (target == 0) { - reg40 |= (ata_atapi(dev) ? 0x04 : 0x00); + reg40 |= (ata_atapi(dev, target) ? 0x04 : 0x00); mask40 = 0x3300; new40 = timings[ata_mode2idx(piomode)] << 8; } else { - reg40 |= (ata_atapi(dev) ? 0x40 : 0x00); + reg40 |= (ata_atapi(dev, target) ? 0x40 : 0x00); mask44 = 0x0f; new44 = ((timings[ata_mode2idx(piomode)] & 0x30) >> 2) | (timings[ata_mode2idx(piomode)] & 0x03); From 2f3d68cd094257653be865d20bbdf0bf839dfa57 Mon Sep 17 00:00:00 2001 From: Ivan Voras Date: Wed, 16 Dec 2009 21:48:27 +0000 Subject: [PATCH 0873/2592] MFC r199764: Make ULE process usage (%CPU) accounting usable again Approved by: gnn (mentor) (implicitly) --- sys/kern/sched_ule.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index e0cff5f3647..593652f7571 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -103,6 +103,7 @@ struct td_sched { u_int ts_slptime; /* Number of ticks we vol. slept */ u_int ts_runtime; /* Number of ticks we were running */ int ts_ltick; /* Last tick that we were running on */ + int ts_incrtick; /* Last tick that we incremented on */ int ts_ftick; /* First tick that we were running on */ int ts_ticks; /* Tick count */ #ifdef KTR @@ -1991,6 +1992,7 @@ sched_fork_thread(struct thread *td, struct thread *child) */ ts2->ts_ticks = ts->ts_ticks; ts2->ts_ltick = ts->ts_ltick; + ts2->ts_incrtick = ts->ts_incrtick; ts2->ts_ftick = ts->ts_ftick; child->td_user_pri = td->td_user_pri; child->td_base_user_pri = td->td_base_user_pri; @@ -2182,11 +2184,12 @@ sched_tick(void) * Ticks is updated asynchronously on a single cpu. Check here to * avoid incrementing ts_ticks multiple times in a single tick. */ - if (ts->ts_ltick == ticks) + if (ts->ts_incrtick == ticks) return; /* Adjust ticks for pctcpu */ ts->ts_ticks += 1 << SCHED_TICK_SHIFT; ts->ts_ltick = ticks; + ts->ts_incrtick = ticks; /* * Update if we've exceeded our desired tick threshhold by over one * second. From 83fe91c2f03b9ad8440f2b94cc677a7e0583c310 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 17 Dec 2009 02:06:07 +0000 Subject: [PATCH 0874/2592] MFC rev 200498: Work-around a race condition on ia64 while unlocking a contested lock. --- lib/libthr/thread/thr_umtx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/libthr/thread/thr_umtx.c b/lib/libthr/thread/thr_umtx.c index 7c59bb78ccb..5af923dce4f 100644 --- a/lib/libthr/thread/thr_umtx.c +++ b/lib/libthr/thread/thr_umtx.c @@ -112,10 +112,13 @@ __thr_umutex_timedlock(struct umutex *mtx, uint32_t id, int __thr_umutex_unlock(struct umutex *mtx, uint32_t id) { +#ifndef __ia64__ + /* XXX this logic has a race-condition on ia64. */ if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) { atomic_cmpset_rel_32(&mtx->m_owner, id | UMUTEX_CONTESTED, UMUTEX_CONTESTED); return _umtx_op_err(mtx, UMTX_OP_MUTEX_WAKE, 0, 0, 0); } +#endif /* __ia64__ */ return _umtx_op_err(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0); } From 2709ebf1a5d40596d3d16a52b4aaa0b6c99a330c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 17 Dec 2009 18:43:34 +0000 Subject: [PATCH 0875/2592] MFC r200450: Document PBDRY and SLEEPQ_STOP_ON_BDRY. --- share/man/man9/sleep.9 | 14 +++++++++++++- share/man/man9/sleepqueue.9 | 11 +++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/share/man/man9/sleep.9 b/share/man/man9/sleep.9 index a9f08735151..8fb7f88a320 100644 --- a/share/man/man9/sleep.9 +++ b/share/man/man9/sleep.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 4, 2008 +.Dd December 12, 2009 .Os .Dt SLEEP 9 .Sh NAME @@ -97,6 +97,7 @@ when it resumes. should never be used, as it is for compatibility only. A new priority of 0 means to use the thread's current priority when it is made runnable again. +.Pp If .Fa priority includes the @@ -113,6 +114,17 @@ possible, and is returned if the system call should be interrupted by the signal (return .Er EINTR ) . +If +.Dv PBDRY +flag is specified in addition to +.Dv PCATCH , +then the sleeping thread is not stopped while sleeping upon delivery of +.Dv SIGSTOP +or other stop action. +Instead, it is waken up, assuming that stop occurs on reaching a stop +point when returning to usermode. +The flag should be used when sleeping thread owns resources, for instance +vnode locks, that should be freed timely. .Pp The parameter .Fa wmesg diff --git a/share/man/man9/sleepqueue.9 b/share/man/man9/sleepqueue.9 index e2e3a4b4150..144bdc0706e 100644 --- a/share/man/man9/sleepqueue.9 +++ b/share/man/man9/sleepqueue.9 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 13, 2007 +.Dd December 12, 2009 .Dt SLEEPQUEUE 9 .Os .Sh NAME @@ -195,12 +195,19 @@ A sleep queue used to implement .Xr pause 9 . .El .Pp -There is currently only one optional flag: +There are currently two optional flag: .Pp .Bl -tag -width ".Dv SLEEPQ_INTERRUPTIBLE" -compact .It Dv SLEEPQ_INTERRUPTIBLE The current thread is entering an interruptible sleep. .El +.Bl -tag -width ".Dv SLEEPQ_STOP_ON_BDRY" -compact +.It Dv SLEEPQ_STOP_ON_BDRY +When thread is entering an interruptible sleep, do not stop it upon +arrival of stop action, like +.Dv SIGSTOP . +Wake it up instead. +.El .Pp A timeout on the sleep may be specified by calling .Fn sleepq_set_timeout From b6050120dbf1316983af928c232bca8bece5aa5b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 17 Dec 2009 18:56:52 +0000 Subject: [PATCH 0876/2592] MFC r199826: sigset() is the name of function specified by SUSv4. Replace it to avoid conflict. --- lib/libutil/pw_util.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/libutil/pw_util.c b/lib/libutil/pw_util.c index 69232fb512c..75459e338b1 100644 --- a/lib/libutil/pw_util.c +++ b/lib/libutil/pw_util.c @@ -289,7 +289,7 @@ int pw_edit(int notsetuid) { struct sigaction sa, sa_int, sa_quit; - sigset_t oldsigset, sigset; + sigset_t oldsigset, nsigset; struct stat st1, st2; const char *editor; int pstat; @@ -303,9 +303,9 @@ pw_edit(int notsetuid) sa.sa_flags = 0; sigaction(SIGINT, &sa, &sa_int); sigaction(SIGQUIT, &sa, &sa_quit); - sigemptyset(&sigset); - sigaddset(&sigset, SIGCHLD); - sigprocmask(SIG_BLOCK, &sigset, &oldsigset); + sigemptyset(&nsigset); + sigaddset(&nsigset, SIGCHLD); + sigprocmask(SIG_BLOCK, &nsigset, &oldsigset); switch ((editpid = fork())) { case -1: return (-1); From 1eea4693c3246a7cb6313f15f75e0e48dc5d2f56 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 17 Dec 2009 19:53:16 +0000 Subject: [PATCH 0877/2592] MFC r199829: Implement rtld part of the support for -z nodlopen (see ld(1)). MFC r199877: Allow to load not-openable dso when tracing. This fixes ldd on such dso or dso linked to non-openable object. Remove '\n' at the end of error message. End comments with dot. --- libexec/rtld-elf/rtld.c | 43 +++++++++++++++++++++++++++-------------- libexec/rtld-elf/rtld.h | 6 ++++++ sys/sys/elf_common.h | 1 + 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 7fae418a01b..cab8c87d86f 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -87,7 +87,7 @@ static void die(void) __dead2; static void digest_dynamic(Obj_Entry *, int); static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *); static Obj_Entry *dlcheck(void *); -static Obj_Entry *do_load_object(int, const char *, char *, struct stat *); +static Obj_Entry *do_load_object(int, const char *, char *, struct stat *, int); static int do_search_info(const Obj_Entry *obj, int, struct dl_serinfo *); static bool donelist_check(DoneList *, const Obj_Entry *); static void errmsg_restore(char *); @@ -103,7 +103,7 @@ static void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *); static bool is_exported(const Elf_Sym *); static void linkmap_add(Obj_Entry *); static void linkmap_delete(Obj_Entry *); -static int load_needed_objects(Obj_Entry *); +static int load_needed_objects(Obj_Entry *, int); static int load_preload_objects(void); static Obj_Entry *load_object(const char *, const Obj_Entry *, int); static Obj_Entry *obj_from_addr(const void *); @@ -485,7 +485,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) preload_tail = obj_tail; dbg("loading needed objects"); - if (load_needed_objects(obj_main) == -1) + if (load_needed_objects(obj_main, 0) == -1) die(); /* Make a list of all objects loaded at startup. */ @@ -932,6 +932,8 @@ digest_dynamic(Obj_Entry *obj, int early) #endif case DT_FLAGS_1: + if (dynp->d_un.d_val & DF_1_NOOPEN) + obj->z_noopen = true; if ((dynp->d_un.d_val & DF_1_ORIGIN) && trust) obj->z_origin = true; if (dynp->d_un.d_val & DF_1_GLOBAL) @@ -1425,7 +1427,7 @@ is_exported(const Elf_Sym *def) * returns -1 on failure. */ static int -load_needed_objects(Obj_Entry *first) +load_needed_objects(Obj_Entry *first, int flags) { Obj_Entry *obj, *obj1; @@ -1434,7 +1436,7 @@ load_needed_objects(Obj_Entry *first) for (needed = obj->needed; needed != NULL; needed = needed->next) { obj1 = needed->obj = load_object(obj->strtab + needed->name, obj, - false); + flags & ~RTLD_LO_NOLOAD); if (obj1 == NULL && !ld_tracing) return -1; if (obj1 != NULL && obj1->z_nodelete && !obj1->ref_nodel) { @@ -1465,7 +1467,7 @@ load_preload_objects(void) savech = p[len]; p[len] = '\0'; - if (load_object(p, NULL, false) == NULL) + if (load_object(p, NULL, 0) == NULL) return -1; /* XXX - cleanup */ p[len] = savech; p += len; @@ -1482,7 +1484,7 @@ load_preload_objects(void) * on failure. */ static Obj_Entry * -load_object(const char *name, const Obj_Entry *refobj, int noload) +load_object(const char *name, const Obj_Entry *refobj, int flags) { Obj_Entry *obj; int fd = -1; @@ -1528,11 +1530,11 @@ load_object(const char *name, const Obj_Entry *refobj, int noload) close(fd); return obj; } - if (noload) + if (flags & RTLD_LO_NOLOAD) return (NULL); /* First use of this object, so we must map it in */ - obj = do_load_object(fd, name, path, &sb); + obj = do_load_object(fd, name, path, &sb, flags); if (obj == NULL) free(path); close(fd); @@ -1541,7 +1543,8 @@ load_object(const char *name, const Obj_Entry *refobj, int noload) } static Obj_Entry * -do_load_object(int fd, const char *name, char *path, struct stat *sbp) +do_load_object(int fd, const char *name, char *path, struct stat *sbp, + int flags) { Obj_Entry *obj; struct statfs fs; @@ -1568,6 +1571,14 @@ do_load_object(int fd, const char *name, char *path, struct stat *sbp) object_add_name(obj, name); obj->path = path; digest_dynamic(obj, 0); + if (obj->z_noopen && (flags & (RTLD_LO_DLOPEN | RTLD_LO_TRACE)) == + RTLD_LO_DLOPEN) { + dbg("refusing to load non-loadable \"%s\"", obj->path); + _rtld_error("Cannot dlopen non-loadable %s", obj->path); + munmap(obj->mapbase, obj->mapsize); + obj_free(obj); + return (NULL); + } *obj_tail = obj; obj_tail = &obj->next; @@ -1986,14 +1997,18 @@ dlopen(const char *name, int mode) Obj_Entry **old_obj_tail; Obj_Entry *obj; Objlist initlist; - int result, lockstate, nodelete, noload; + int result, lockstate, nodelete, lo_flags; LD_UTRACE(UTRACE_DLOPEN_START, NULL, NULL, 0, mode, name); ld_tracing = (mode & RTLD_TRACE) == 0 ? NULL : "1"; if (ld_tracing != NULL) environ = (char **)*get_program_var_addr("environ"); nodelete = mode & RTLD_NODELETE; - noload = mode & RTLD_NOLOAD; + lo_flags = RTLD_LO_DLOPEN; + if (mode & RTLD_NOLOAD) + lo_flags |= RTLD_LO_NOLOAD; + if (ld_tracing != NULL) + lo_flags |= RTLD_LO_TRACE; objlist_init(&initlist); @@ -2006,7 +2021,7 @@ dlopen(const char *name, int mode) obj = obj_main; obj->refcount++; } else { - obj = load_object(name, obj_main, noload); + obj = load_object(name, obj_main, lo_flags); } if (obj) { @@ -2016,7 +2031,7 @@ dlopen(const char *name, int mode) mode &= RTLD_MODEMASK; if (*old_obj_tail != NULL) { /* We loaded something new. */ assert(*old_obj_tail == obj); - result = load_needed_objects(obj); + result = load_needed_objects(obj, RTLD_LO_DLOPEN); init_dag(obj); if (result != -1) result = rtld_verify_versions(&obj->dagmembers); diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index 06086b4b92e..875e84bc7e6 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -218,6 +218,7 @@ typedef struct Struct_Obj_Entry { bool phdr_alloc : 1; /* Phdr is allocated and needs to be freed. */ bool z_origin : 1; /* Process rpath and soname tokens */ bool z_nodelete : 1; /* Do not unload the object and dependencies */ + bool z_noopen : 1; /* Do not load on dlopen */ bool ref_nodel : 1; /* Refcount increased to prevent dlclose */ bool init_scanned: 1; /* Object is already on init list. */ bool on_fini_list: 1; /* Object is already on fini list. */ @@ -240,6 +241,11 @@ typedef struct Struct_Obj_Entry { #define SYMLOOK_DLSYM 0x02 /* Return newes versioned symbol. Used by dlsym. */ +/* Flags for load_object(). */ +#define RTLD_LO_NOLOAD 0x01 /* dlopen() specified RTLD_NOLOAD. */ +#define RTLD_LO_DLOPEN 0x02 /* Load_object() called from dlopen(). */ +#define RTLD_LO_TRACE 0x04 /* Only tracing. */ + /* * Symbol cache entry used during relocation to avoid multiple lookups * of the same symbol. diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h index f642c710c8c..39f6d347b7a 100644 --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -471,6 +471,7 @@ typedef struct { #define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */ #define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */ #define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */ +#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */ #define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */ /* Values for n_type. Used in core files. */ From 5ff95453ccdf27240d470a7b6a2eb6ecc9935e37 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 17 Dec 2009 20:41:27 +0000 Subject: [PATCH 0878/2592] MFC 199606, 199614: Add an internal _once() method. This works identical to pthread_once(3) with the additional property that it is safe for routines in libc to use in both single-threaded and multi-threaded processes. Multi-threaded processes use the pthread_once() implementation from the threading library while single-threaded processes use a simplified "stub" version internal to libc. --- lib/libc/gen/Makefile.inc | 3 +- lib/libc/gen/_once_stub.c | 64 +++++++++++++++++++++++++++++++++ lib/libc/include/libc_private.h | 7 ++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 lib/libc/gen/_once_stub.c diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index b06f846dd47..903fa220cf6 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -5,7 +5,8 @@ .PATH: ${.CURDIR}/${MACHINE_ARCH}/gen ${.CURDIR}/gen SRCS+= __getosreldate.c __xuname.c \ - _pthread_stubs.c _rand48.c _spinlock_stub.c _thread_init.c \ + _once_stub.c _pthread_stubs.c _rand48.c _spinlock_stub.c \ + _thread_init.c \ alarm.c arc4random.c assert.c basename.c check_utility_compat.c \ clock.c closedir.c confstr.c \ crypt.c ctermid.c daemon.c devname.c dirname.c disklabel.c \ diff --git a/lib/libc/gen/_once_stub.c b/lib/libc/gen/_once_stub.c new file mode 100644 index 00000000000..d2acc29f32c --- /dev/null +++ b/lib/libc/gen/_once_stub.c @@ -0,0 +1,64 @@ +/*- + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +/* This implements pthread_once() for the single-threaded case. */ +static int +_libc_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + + if (once_control->state == PTHREAD_DONE_INIT) + return (0); + init_routine(); + once_control->state = PTHREAD_DONE_INIT; + return (0); +} + +/* + * This is the internal interface provided to libc. It will use + * pthread_once() from the threading library in a multi-threaded + * process and _libc_once() for a single-threaded library. Because + * _libc_once() uses the same ABI for the values in the pthread_once_t + * structure as the threading library, it is safe for a process to + * switch from _libc_once() to pthread_once() when threading is + * enabled. + */ +int +_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + + if (__isthreaded) + return (_pthread_once(once_control, init_routine)); + return (_libc_once(once_control, init_routine)); +} diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index 50903f3c74f..052eb13003b 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -34,6 +34,7 @@ #ifndef _LIBC_PRIVATE_H_ #define _LIBC_PRIVATE_H_ +#include /* * This global flag is non-zero when a process has created one @@ -146,6 +147,12 @@ int _yp_check(char **); */ void _init_tls(void); +/* + * Provides pthread_once()-like functionality for both single-threaded + * and multi-threaded applications. + */ +int _once(pthread_once_t *, void (*)(void)); + /* * Set the TLS thread pointer */ From c1dde08ce2c0d8186165ce09bdbffba0c0a17727 Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Fri, 18 Dec 2009 06:09:43 +0000 Subject: [PATCH 0879/2592] MFC r200366 Add a missing else that negated the truncation of ki_ngroups to NGROUPS. Submitted by: Dmitry Pryanishnikov --- lib/libkvm/kvm_proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c index 071f859e002..f8f84830d0a 100644 --- a/lib/libkvm/kvm_proc.c +++ b/lib/libkvm/kvm_proc.c @@ -149,7 +149,7 @@ kvm_proclist(kd, what, arg, p, bp, maxcnt) if (ucred.cr_ngroups > KI_NGROUPS) { kp->ki_ngroups = KI_NGROUPS; kp->ki_cr_flags |= KI_CRF_GRP_OVERFLOW; - } + } else kp->ki_ngroups = ucred.cr_ngroups; kvm_read(kd, (u_long)ucred.cr_groups, kp->ki_groups, kp->ki_ngroups * sizeof(gid_t)); From 5fe2bb8a58c45e43beee839af87a374be89b02e4 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 18 Dec 2009 18:30:49 +0000 Subject: [PATCH 0880/2592] MFC 200037: ndis_scan_results() can sleep if the scan results are not ready when ndis_scan() is called. However, ndis_scan() is invoked from softclock() and cannot sleep. Move ndis_scan_results() to the ndis driver's scan_end hook instead. --- sys/dev/if_ndis/if_ndis.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 2c8b32455d7..a1af3e982e7 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -3278,14 +3278,8 @@ ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) static void ndis_scan(void *arg) { - struct ndis_softc *sc = arg; - struct ieee80211com *ic; - struct ieee80211vap *vap; + struct ieee80211vap *vap = arg; - ic = sc->ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); - - ndis_scan_results(sc); ieee80211_scan_done(vap); } @@ -3434,7 +3428,7 @@ ndis_scan_start(struct ieee80211com *ic) return; } /* Set a timer to collect the results */ - callout_reset(&sc->ndis_scan_callout, hz * 3, ndis_scan, sc); + callout_reset(&sc->ndis_scan_callout, hz * 3, ndis_scan, vap); } static void @@ -3458,6 +3452,8 @@ ndis_scan_mindwell(struct ieee80211_scan_state *ss) static void ndis_scan_end(struct ieee80211com *ic) { - /* ignore */ + struct ndis_softc *sc = ic->ic_ifp->if_softc; + + ndis_scan_results(sc); } From f8aa319ba0f07e4acb23e6dc98ebf71c7d657f3d Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 18 Dec 2009 18:55:15 +0000 Subject: [PATCH 0881/2592] MFC r199463: rc.early(8) was removed as of 20090530 so remove manual page reference to it. --- ObsoleteFiles.inc | 10 ++++++++++ share/man/man8/Makefile | 1 - share/man/man8/rc.8 | 16 +--------------- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 090e4bb56b1..650f84b0c09 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -14,6 +14,16 @@ # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last. # +# 20091218: removal of rc.early(8) link +OLD_FILES+=usr/share/man/man8/rc.early.8.gz +# 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 +# 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 # 20090904: remove lukemftpd OLD_FILES+=usr/libexec/lukemftpd OLD_FILES+=usr/share/man/man5/ftpd.conf.5.gz diff --git a/share/man/man8/Makefile b/share/man/man8/Makefile index 0b1654443fb..279a87403ef 100644 --- a/share/man/man8/Makefile +++ b/share/man/man8/Makefile @@ -16,7 +16,6 @@ MAN= crash.8 \ MLINKS= rc.8 rc.atm.8 \ rc.8 rc.d.8 \ - rc.8 rc.early.8 \ rc.8 rc.firewall.8 \ rc.8 rc.local.8 \ rc.8 rc.network.8 \ diff --git a/share/man/man8/rc.8 b/share/man/man8/rc.8 index aa607beb554..4f24a363980 100644 --- a/share/man/man8/rc.8 +++ b/share/man/man8/rc.8 @@ -35,7 +35,7 @@ .\" @(#)rc.8 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd May 18, 2007 +.Dd November 17, 2009 .Dt RC 8 .Os .Sh NAME @@ -394,20 +394,6 @@ is not set, when going from single-user to multi-user mode for example, the script does not do anything. .Pp The -.Nm rc.early -script is run very early in the startup process, immediately before the -file system check. -The -.Nm rc.early -script is deprecated. -Any commands in this -file should be separated out into -.Nm rc.d/ -style scripts and integrated into the -.Nm -system. -.Pp -The .Pa /etc/rc.d/local script can execute scripts from multiple .Nm rc.d/ From e84ca6158d15492d6606e9eace892342657eb2de Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 18 Dec 2009 19:16:44 +0000 Subject: [PATCH 0882/2592] MFC r199464: Add a missing .Ed tag. --- share/man/man4/wi.4 | 1 + 1 file changed, 1 insertion(+) diff --git a/share/man/man4/wi.4 b/share/man/man4/wi.4 index 68479aeea11..e6f5a485597 100644 --- a/share/man/man4/wi.4 +++ b/share/man/man4/wi.4 @@ -253,6 +253,7 @@ Join a specific BSS network with network name .Bd -literal -offset indent ifconfig wlan create wlandev wi0 inet 192.168.0.20 \e netmask 0xffffff00 ssid my_net +.Ed .Pp Join a specific BSS network with WEP encryption: .Bd -literal -offset indent From 24ca088da73da1660f21bbc83b2e94936a096935 Mon Sep 17 00:00:00 2001 From: Benedict Reuschling Date: Fri, 18 Dec 2009 19:26:16 +0000 Subject: [PATCH 0883/2592] MFC r200415: Reference the correct man page for firmware(9). PR: docs/140985 Submitted by: Glen Barber (glen dot j dot barber at gmail dot com) Reviewed by: rpaulo Approved by: rpaulo, jkois (mentor) Merged with: user/des/fmerge --- share/man/man4/iwnfw.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/iwnfw.4 b/share/man/man4/iwnfw.4 index 1f9faa9c89c..72021ea2429 100644 --- a/share/man/man4/iwnfw.4 +++ b/share/man/man4/iwnfw.4 @@ -49,4 +49,4 @@ It may be statically linked into the kernel, or loaded as a module. .Sh SEE ALSO .Xr iwn 4 , -.Xr firmware 8 +.Xr firmware 9 From f6007c00817ca2e4d937462b1e2a374abb6922e5 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 18 Dec 2009 19:43:44 +0000 Subject: [PATCH 0884/2592] MFC 200084: Properly return an error reply if an NFS remove or link operation fails. Previously the failing operation would allocate an mbuf and construct an error reply, but because the function did not return 0, the NFS server assumed it had failed to generate a reply and would leak the reply mbuf as well as not sending the reply to the NFS client. --- sys/nfsserver/nfs_serv.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c index 3bb9a6a2880..d1be5e55333 100644 --- a/sys/nfsserver/nfs_serv.c +++ b/sys/nfsserver/nfs_serv.c @@ -1810,10 +1810,9 @@ out: } ereply: nfsm_reply(NFSX_WCCDATA(v3)); - if (v3) { + if (v3) nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - error = 0; - } + error = 0; nfsmout: NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_dvp) { @@ -2187,8 +2186,8 @@ ereply: if (v3) { nfsm_srvpostop_attr(getret, &at); nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - error = 0; } + error = 0; /* fall through */ nfsmout: From 08c59cc33e2ab071496d41c250a686de58b552f6 Mon Sep 17 00:00:00 2001 From: Sean Farley Date: Fri, 18 Dec 2009 20:05:10 +0000 Subject: [PATCH 0885/2592] Merge from head to stable/8: r200423: Remove a dead store. --- lib/libutil/gr_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libutil/gr_util.c b/lib/libutil/gr_util.c index 77e06531f70..633f435eea2 100644 --- a/lib/libutil/gr_util.c +++ b/lib/libutil/gr_util.c @@ -117,8 +117,8 @@ gr_make(const struct group *gr) /* Create the group line and fill it. */ if ((line = malloc(line_size)) == NULL) return (NULL); - line_size = snprintf(line, line_size, group_line_format, gr->gr_name, - gr->gr_passwd, (uintmax_t)gr->gr_gid); + snprintf(line, line_size, group_line_format, gr->gr_name, gr->gr_passwd, + (uintmax_t)gr->gr_gid); if (gr->gr_mem != NULL) for (ndx = 0; gr->gr_mem[ndx] != NULL; ndx++) { strcat(line, gr->gr_mem[ndx]); From 5f0cb0c9cd41b07a32d1cd39b82dcea1eb5ad97b Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 18 Dec 2009 20:28:04 +0000 Subject: [PATCH 0886/2592] MFC 200216,200219: - Various small whitespace and style fixes. - Improve the algorithm the loader uses to choose a memory range for its heap when using a range above 1MB. --- sys/boot/i386/libi386/biosmem.c | 40 ++++++++++++++++++++++++++++++--- sys/boot/i386/libi386/libi386.h | 17 ++++++++------ sys/boot/i386/loader/main.c | 19 ++++++++++------ 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/sys/boot/i386/libi386/biosmem.c b/sys/boot/i386/libi386/biosmem.c index 3c2205ed46c..bae68131b87 100644 --- a/sys/boot/i386/libi386/biosmem.c +++ b/sys/boot/i386/libi386/biosmem.c @@ -35,14 +35,20 @@ __FBSDID("$FreeBSD$"); #include "libi386.h" #include "btxv86.h" -vm_offset_t memtop, memtop_copyin; -u_int32_t bios_basemem, bios_extmem; +vm_offset_t memtop, memtop_copyin, high_heap_base; +uint32_t bios_basemem, bios_extmem, high_heap_size; static struct bios_smap smap; +/* + * The minimum amount of memory to reserve in bios_extmem for the heap. + */ +#define HEAP_MIN (3 * 1024 * 1024) + void bios_getmem(void) { + uint64_t size; /* Parse system memory map */ v86.ebx = 0; @@ -65,6 +71,26 @@ bios_getmem(void) if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) { bios_extmem = smap.length; } + + /* + * Look for the largest segment in 'extended' memory beyond + * 1MB but below 4GB. + */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && + (smap.base < 0x100000000ull)) { + size = smap.length; + + /* + * If this segment crosses the 4GB boundary, truncate it. + */ + if (smap.base + size > 0x100000000ull) + size = 0x100000000ull - smap.base; + + if (size > high_heap_size) { + high_heap_size = size; + high_heap_base = smap.base; + } + } } while (v86.ebx != 0); /* Fall back to the old compatibility function for base memory */ @@ -97,5 +123,13 @@ bios_getmem(void) /* Set memtop to actual top of memory */ memtop = memtop_copyin = 0x100000 + bios_extmem; + /* + * If we have extended memory and did not find a suitable heap + * region in the SMAP, use the last 3MB of 'extended' memory as a + * high heap candidate. + */ + if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { + high_heap_size = HEAP_MIN; + high_heap_base = memtop - HEAP_MIN; + } } - diff --git a/sys/boot/i386/libi386/libi386.h b/sys/boot/i386/libi386/libi386.h index 4ac5cb569fb..ebf1b4ce949 100644 --- a/sys/boot/i386/libi386/libi386.h +++ b/sys/boot/i386/libi386/libi386.h @@ -78,9 +78,9 @@ int bc_add(int biosdev); /* Register CD booted from. */ int bc_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */ int bc_bios2unit(int biosdev); /* xlate BIOS device -> bioscd unit */ int bc_unit2bios(int unit); /* xlate bioscd unit -> BIOS device */ -u_int32_t bd_getbigeom(int bunit); /* return geometry in bootinfo format */ -int bd_bios2unit(int biosdev); /* xlate BIOS device -> biosdisk unit */ -int bd_unit2bios(int unit); /* xlate biosdisk unit -> BIOS device */ +uint32_t bd_getbigeom(int bunit); /* return geometry in bootinfo format */ +int bd_bios2unit(int biosdev); /* xlate BIOS device -> biosdisk unit */ +int bd_unit2bios(int unit); /* xlate biosdisk unit -> BIOS device */ int bd_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */ ssize_t i386_copyin(const void *src, vm_offset_t dest, const size_t len); @@ -92,12 +92,15 @@ void bios_addsmapdata(struct preloaded_file *); void bios_getsmap(void); void bios_getmem(void); -extern u_int32_t bios_basemem; /* base memory in bytes */ -extern u_int32_t bios_extmem; /* extended memory in bytes */ +extern uint32_t bios_basemem; /* base memory in bytes */ +extern uint32_t bios_extmem; /* extended memory in bytes */ extern vm_offset_t memtop; /* last address of physical memory + 1 */ extern vm_offset_t memtop_copyin; /* memtop less heap size for the cases */ - /* when heap is at the top of extended memory */ - /* for other cases - just the same as memtop */ + /* when heap is at the top of */ + /* extended memory; for other cases */ + /* just the same as memtop */ +extern uint32_t high_heap_size; /* extended memory region available */ +extern vm_offset_t high_heap_base; /* for use as the heap */ int biospci_find_devclass(uint32_t class, int index, uint32_t *locator); int biospci_write_config(uint32_t locator, int offset, int width, uint32_t val); diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c index 701dd3a1222..75d5dbcb6ec 100644 --- a/sys/boot/i386/loader/main.c +++ b/sys/boot/i386/loader/main.c @@ -102,14 +102,19 @@ main(void) */ bios_getmem(); -#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT) - heap_top = PTOV(memtop_copyin); - memtop_copyin -= 0x300000; - heap_bottom = PTOV(memtop_copyin); -#else - heap_top = (void *)bios_basemem; - heap_bottom = (void *)end; +#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || \ + defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT) + if (high_heap_size > 0) { + heap_top = PTOV(high_heap_base + high_heap_size); + heap_bottom = PTOV(high_heap_base); + if (high_heap_base < memtop_copyin) + memtop_copyin = high_heap_base; + } else #endif + { + heap_top = (void *)PTOV(bios_basemem); + heap_bottom = (void *)end; + } setheap(heap_bottom, heap_top); /* From 5e05dbe9bd0c045c0f6272ce1d96943e851e84a7 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 18 Dec 2009 21:01:56 +0000 Subject: [PATCH 0887/2592] MFC 200309: - Port bios_getmem() from libi386 to {gpt,}zfsboot() and use it to safely allocate a heap region above 1MB. This enables {gpt,}zfsboot() to allocate much larger buffers than before. - Use a larger buffer (1MB instead of 128K) for temporary ZFS buffers. This allows more reliable reading of compressed files in a raidz/raidz2 pool. --- sys/boot/i386/zfsboot/zfsboot.c | 131 +++++++++++++++++++++++++++----- sys/boot/zfs/zfsimpl.c | 2 +- 2 files changed, 112 insertions(+), 21 deletions(-) diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c index ca2c90e3e3f..966a00b4f03 100644 --- a/sys/boot/i386/zfsboot/zfsboot.c +++ b/sys/boot/i386/zfsboot/zfsboot.c @@ -27,6 +27,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -90,8 +91,6 @@ __FBSDID("$FreeBSD$"); #define ARGS 0x900 #define NOPT 14 #define NDEV 3 -#define MEM_BASE 0x12 -#define MEM_EXT 0x15 #define V86_CY(x) ((x) & 1) #define V86_ZR(x) ((x) & 0x40) @@ -149,6 +148,19 @@ static struct bootinfo bootinfo; static uint32_t bootdev; static uint8_t ioctrl = IO_KEYBOARD; +vm_offset_t high_heap_base; +uint32_t bios_basemem, bios_extmem, high_heap_size; + +static struct bios_smap smap; + +/* + * The minimum amount of memory to reserve in bios_extmem for the heap. + */ +#define HEAP_MIN (3 * 1024 * 1024) + +static char *heap_next; +static char *heap_end; + /* Buffers that must not span a 64k boundary. */ #define READ_BUF_SIZE 8192 struct dmadat { @@ -162,7 +174,7 @@ static void load(void); static int parse(void); static void printf(const char *,...); static void putchar(int); -static uint32_t memsize(void); +static void bios_getmem(void); static int drvread(struct dsk *, void *, daddr_t, unsigned); static int keyhit(unsigned); static int xputc(int); @@ -237,14 +249,6 @@ memset(void *p, char val, size_t n) static void * malloc(size_t n) { - static char *heap_next; - static char *heap_end; - - if (!heap_next) { - heap_next = (char *) dmadat + sizeof(*dmadat); - heap_end = (char *) (640*1024); - } - char *p = heap_next; if (p + n > heap_end) { printf("malloc failure\n"); @@ -344,14 +348,91 @@ xfsread(const dnode_phys_t *dnode, off_t *offp, void *buf, size_t nbyte) return 0; } -static inline uint32_t -memsize(void) +static void +bios_getmem(void) { - v86.addr = MEM_EXT; - v86.eax = 0x8800; - v86int(); - return v86.eax; -} + uint64_t size; + + /* Parse system memory map */ + v86.ebx = 0; + do { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe820*/ + v86.eax = 0xe820; + v86.ecx = sizeof(struct bios_smap); + v86.edx = SMAP_SIG; + v86.es = VTOPSEG(&smap); + v86.edi = VTOPOFF(&smap); + v86int(); + if ((v86.efl & 1) || (v86.eax != SMAP_SIG)) + break; + /* look for a low-memory segment that's large enough */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && + (smap.length >= (512 * 1024))) + bios_basemem = smap.length; + /* look for the first segment in 'extended' memory */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) { + bios_extmem = smap.length; + } + + /* + * Look for the largest segment in 'extended' memory beyond + * 1MB but below 4GB. + */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && + (smap.base < 0x100000000ull)) { + size = smap.length; + + /* + * If this segment crosses the 4GB boundary, truncate it. + */ + if (smap.base + size > 0x100000000ull) + size = 0x100000000ull - smap.base; + + if (size > high_heap_size) { + high_heap_size = size; + high_heap_base = smap.base; + } + } + } while (v86.ebx != 0); + + /* Fall back to the old compatibility function for base memory */ + if (bios_basemem == 0) { + v86.ctl = 0; + v86.addr = 0x12; /* int 0x12 */ + v86int(); + + bios_basemem = (v86.eax & 0xffff) * 1024; + } + + /* Fall back through several compatibility functions for extended memory */ + if (bios_extmem == 0) { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe801*/ + v86.eax = 0xe801; + v86int(); + if (!(v86.efl & 1)) { + bios_extmem = ((v86.ecx & 0xffff) + ((v86.edx & 0xffff) * 64)) * 1024; + } + } + if (bios_extmem == 0) { + v86.ctl = 0; + v86.addr = 0x15; /* int 0x15 function 0x88*/ + v86.eax = 0x8800; + v86int(); + bios_extmem = (v86.eax & 0xffff) * 1024; + } + + /* + * If we have extended memory and did not find a suitable heap + * region in the SMAP, use the last 3MB of 'extended' memory as a + * high heap candidate. + */ + if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { + high_heap_size = HEAP_MIN; + high_heap_base = bios_extmem + 0x100000 - HEAP_MIN; + } +} static inline void getstr(void) @@ -536,6 +617,16 @@ main(void) off_t off; struct dsk *dsk; + bios_getmem(); + + if (high_heap_size > 0) { + heap_end = PTOV(high_heap_base + high_heap_size); + heap_next = PTOV(high_heap_base); + } else { + heap_next = (char *) dmadat + sizeof(*dmadat); + heap_end = (char *) PTOV(bios_basemem); + } + dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); v86.ctl = V86_FLAGS; @@ -550,8 +641,8 @@ main(void) bootinfo.bi_version = BOOTINFO_VERSION; bootinfo.bi_size = sizeof(bootinfo); - bootinfo.bi_basemem = 0; /* XXX will be filled by loader or kernel */ - bootinfo.bi_extmem = memsize(); + bootinfo.bi_basemem = bios_basemem / 1024; + bootinfo.bi_extmem = bios_extmem / 1024; bootinfo.bi_memsizes_valid++; bootinfo.bi_bios_dev = dsk->drive; diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c index 497fd7c94be..adddb6a4f2a 100644 --- a/sys/boot/zfs/zfsimpl.c +++ b/sys/boot/zfs/zfsimpl.c @@ -51,7 +51,7 @@ static char *dnode_cache_buf; static char *zap_scratch; static char *zfs_temp_buf, *zfs_temp_end, *zfs_temp_ptr; -#define TEMP_SIZE (1*SPA_MAXBLOCKSIZE) +#define TEMP_SIZE (1024 * 1024) static int zio_read(spa_t *spa, const blkptr_t *bp, void *buf); From f70478c04dfcca72278b2478f36fd80818d5e349 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 18 Dec 2009 21:21:14 +0000 Subject: [PATCH 0888/2592] MFC 200310: Fix a confusing typo in the EDD packet structure used in gptboot and gptzfsboot. I got the segment and offset fields reversed in the structure, but I also succeeded in crossing the assignments so the actual EDD packet ended up correct. --- sys/boot/i386/gptboot/gptboot.c | 6 +++--- sys/boot/i386/zfsboot/zfsboot.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/boot/i386/gptboot/gptboot.c b/sys/boot/i386/gptboot/gptboot.c index 89df2ecb104..96efea6a1d5 100644 --- a/sys/boot/i386/gptboot/gptboot.c +++ b/sys/boot/i386/gptboot/gptboot.c @@ -642,8 +642,8 @@ bcmp(const void *b1, const void *b2, size_t length) static struct { uint16_t len; uint16_t count; - uint16_t seg; uint16_t off; + uint16_t seg; uint64_t lba; } packet; @@ -656,8 +656,8 @@ drvread(void *buf, daddr_t lba, unsigned nblk) printf("%c\b", c = c << 8 | c >> 24); packet.len = 0x10; packet.count = nblk; - packet.seg = VTOPOFF(buf); - packet.off = VTOPSEG(buf); + packet.off = VTOPOFF(buf); + packet.seg = VTOPSEG(buf); packet.lba = lba; v86.ctl = V86_FLAGS; v86.addr = 0x13; diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c index 966a00b4f03..07ade3ac61d 100644 --- a/sys/boot/i386/zfsboot/zfsboot.c +++ b/sys/boot/i386/zfsboot/zfsboot.c @@ -1049,8 +1049,8 @@ putchar(int c) static struct { uint16_t len; uint16_t count; - uint16_t seg; uint16_t off; + uint16_t seg; uint64_t lba; } packet; #endif @@ -1065,8 +1065,8 @@ drvread(struct dsk *dsk, void *buf, daddr_t lba, unsigned nblk) printf("%c\b", c = c << 8 | c >> 24); packet.len = 0x10; packet.count = nblk; - packet.seg = VTOPOFF(buf); - packet.off = VTOPSEG(buf); + packet.off = VTOPOFF(buf); + packet.seg = VTOPSEG(buf); packet.lba = lba + dsk->start; v86.ctl = V86_FLAGS; v86.addr = 0x13; From 823e5012b0770a12d47558d57f603be30c2cadb8 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 18 Dec 2009 22:23:27 +0000 Subject: [PATCH 0889/2592] MFC 200357: Don't warn about an RSDP with a corrupt checksum. The kernel does a better job about warning about these things later and this message can be confusing. --- sys/boot/i386/libi386/biosacpi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/boot/i386/libi386/biosacpi.c b/sys/boot/i386/libi386/biosacpi.c index 081598394ea..e9e2436b47c 100644 --- a/sys/boot/i386/libi386/biosacpi.c +++ b/sys/boot/i386/libi386/biosacpi.c @@ -125,10 +125,8 @@ biosacpi_search_rsdp(char *base, int length) sum = 0; for (idx = 0; idx < RSDP_CHECKSUM_LENGTH; idx++) sum += *(cp + idx); - if (sum != 0) { - printf("acpi: bad RSDP checksum (%d)\n", sum); + if (sum != 0) continue; - } return(rsdp); } } From abe32331b651d5d5fcbab3f1b9b254f9cf79e225 Mon Sep 17 00:00:00 2001 From: Yoshihiro Takahashi Date: Sat, 19 Dec 2009 04:25:19 +0000 Subject: [PATCH 0890/2592] MFC: r200253 and r200255 Reduce diffs against i386. --- sys/boot/pc98/libpc98/biosmem.c | 18 +++++++++++++++--- sys/boot/pc98/loader/main.c | 18 +++++++++++------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/sys/boot/pc98/libpc98/biosmem.c b/sys/boot/pc98/libpc98/biosmem.c index b450922e3d2..a25d8c2d9e9 100644 --- a/sys/boot/pc98/libpc98/biosmem.c +++ b/sys/boot/pc98/libpc98/biosmem.c @@ -34,8 +34,13 @@ __FBSDID("$FreeBSD$"); #include "libi386.h" #include "btxv86.h" -vm_offset_t memtop, memtop_copyin; -u_int32_t bios_basemem, bios_extmem; +vm_offset_t memtop, memtop_copyin, high_heap_base; +uint32_t bios_basemem, bios_extmem, high_heap_size; + +/* + * The minimum amount of memory to reserve in bios_extmem for the heap. + */ +#define HEAP_MIN (3 * 1024 * 1024) void bios_getmem(void) @@ -48,5 +53,12 @@ bios_getmem(void) /* Set memtop to actual top of memory */ memtop = memtop_copyin = 0x100000 + bios_extmem; + /* + * If we have extended memory, use the last 3MB of 'extended' memory + * as a high heap candidate. + */ + if (bios_extmem >= HEAP_MIN) { + high_heap_size = HEAP_MIN; + high_heap_base = memtop - HEAP_MIN; + } } - diff --git a/sys/boot/pc98/loader/main.c b/sys/boot/pc98/loader/main.c index 6573990faa3..e10b1e7217e 100644 --- a/sys/boot/pc98/loader/main.c +++ b/sys/boot/pc98/loader/main.c @@ -96,14 +96,18 @@ main(void) */ bios_getmem(); -#ifdef LOADER_BZIP2_SUPPORT - heap_top = PTOV(memtop_copyin); - memtop_copyin -= 0x300000; - heap_bottom = PTOV(memtop_copyin); -#else - heap_top = (void *)bios_basemem; - heap_bottom = (void *)end; +#if defined(LOADER_BZIP2_SUPPORT) + if (high_heap_size > 0) { + heap_top = PTOV(high_heap_base + high_heap_size); + heap_bottom = PTOV(high_heap_base); + if (high_heap_base < memtop_copyin) + memtop_copyin = high_heap_base; + } else #endif + { + heap_top = (void *)PTOV(bios_basemem); + heap_bottom = (void *)end; + } setheap(heap_bottom, heap_top); /* From a3ff6f1def93c4961e2295d273974f4b42dc0009 Mon Sep 17 00:00:00 2001 From: Yoshihiro Takahashi Date: Sat, 19 Dec 2009 04:43:25 +0000 Subject: [PATCH 0891/2592] MFC: r200254 MFi386: Use real mode instead of v86 mode. --- sys/boot/pc98/btx/btx/btx.S | 765 +++++++++++++++++------------------- 1 file changed, 358 insertions(+), 407 deletions(-) diff --git a/sys/boot/pc98/btx/btx/btx.S b/sys/boot/pc98/btx/btx/btx.S index 7d22b27fbdb..95788d4f8fa 100644 --- a/sys/boot/pc98/btx/btx/btx.S +++ b/sys/boot/pc98/btx/btx/btx.S @@ -21,11 +21,11 @@ .set MEM_BTX,0x1000 # Start of BTX memory .set MEM_ESP0,0x1800 # Supervisor stack .set MEM_BUF,0x1800 # Scratch buffer - .set MEM_ESP1,0x1e00 # Link stack - .set MEM_IDT,0x1e00 # IDT - .set MEM_TSS,0x1f98 # TSS - .set MEM_MAP,0x2000 # I/O bit map - .set MEM_TSS_END,0x3fff # Page directory + .set MEM_ESPR,0x5e00 # Real mode stack + .set MEM_IDT,0x5e00 # IDT + .set MEM_TSS,0x5f98 # TSS + .set MEM_MAP,0x6000 # I/O bit map + .set MEM_TSS_END,0x7fff # End of TSS .set MEM_ORG,0x9000 # BTX code .set MEM_USR,0xa000 # Start of user memory /* @@ -33,6 +33,14 @@ */ .set PAG_SIZ,0x1000 # Page size .set PAG_CNT,0x1000 # Pages to map +/* + * Fields in %eflags. + */ + .set PSL_RESERVED_DEFAULT,0x00000002 + .set PSL_T,0x00000100 # Trap flag + .set PSL_I,0x00000200 # Interrupt enable flag + .set PSL_VM,0x00020000 # Virtual 8086 mode flag + .set PSL_AC,0x00040000 # Alignment check flag /* * Segment selectors. */ @@ -48,7 +56,6 @@ */ .set TSS_ESP0,0x4 # PL 0 ESP .set TSS_SS0,0x8 # PL 0 SS - .set TSS_ESP1,0xc # PL 1 ESP .set TSS_MAP,0x66 # I/O bit map base /* * System calls. @@ -56,10 +63,20 @@ .set SYS_EXIT,0x0 # Exit .set SYS_EXEC,0x1 # Exec /* - * V86 constants. + * Fields in V86 interface structure. */ - .set V86_FLG,0x208eff # V86 flag mask - .set V86_STK,0x400 # V86 stack allowance + .set V86_CTL,0x0 # Control flags + .set V86_ADDR,0x4 # Int number/address + .set V86_ES,0x8 # V86 ES + .set V86_DS,0xc # V86 DS + .set V86_FS,0x10 # V86 FS + .set V86_GS,0x14 # V86 GS +/* + * V86 control flags. + */ + .set V86F_ADDR,0x10000 # Segment:offset address + .set V86F_CALLF,0x20000 # Emulate far call + .set V86F_FLAGS,0x40000 # Return flags /* * Dump format control bytes. */ @@ -77,13 +94,11 @@ * BIOS Data Area locations. */ .set BDA_MEM,0x501 # Free memory - .set BDA_KEYFLAGS,0x53a # Keyboard shift-state flags .set BDA_POS,0x53e # Cursor position /* * Derivations, for brevity. */ .set _ESP0H,MEM_ESP0>>0x8 # Byte 1 of ESP0 - .set _ESP1H,MEM_ESP1>>0x8 # Byte 1 of ESP1 .set _TSSIO,MEM_MAP-MEM_TSS # TSS I/O base .set _TSSLM,MEM_TSS_END-MEM_TSS # TSS limit .set _IDTLM,MEM_TSS-MEM_IDT-1 # IDT limit @@ -100,7 +115,7 @@ btx_hdr: .byte 0xeb # Machine ID .byte 0xe # Header size .ascii "BTX" # Magic .byte 0x1 # Major version - .byte 0x1 # Minor version + .byte 0x2 # Minor version .byte BTX_FLAGS # Flags .word PAG_CNT-MEM_ORG>>0xc # Paging control .word break-start # Text size @@ -121,13 +136,24 @@ init: cli # Disable interrupts */ mov $MEM_IDT,%di # Memory to initialize mov $(MEM_ORG-MEM_IDT)/2,%cx # Words to zero - push %di # Save rep # Zero-fill stosw # memory - pop %di # Restore +/* + * Update real mode IDT for reflecting hardware interrupts. + */ + mov $intr20,%bx # Address first handler + mov $0x10,%cx # Number of handlers + mov $0x20*4,%di # First real mode IDT entry +init.0: mov %bx,(%di) # Store IP + inc %di # Address next + inc %di # entry + stosw # Store CS + add $4,%bx # Next handler + loop init.0 # Next IRQ /* * Create IDT. */ + mov $MEM_IDT,%di mov $idtctl,%si # Control string init.1: lodsb # Get entry cbw # count @@ -153,7 +179,6 @@ init.3: lea 0x8(%di),%di # Next entry */ init.4: movb $_ESP0H,TSS_ESP0+1(%di) # Set ESP0 movb $SEL_SDATA,TSS_SS0(%di) # Set SS0 - movb $_ESP1H,TSS_ESP1+1(%di) # Set ESP1 movb $_TSSIO,TSS_MAP(%di) # Set I/O bit map base /* * Bring up the system. @@ -253,8 +278,8 @@ exit.2: xor %ax,%ax # Real mode segment exit.3: jz exit.3 # No movb $0xa0,%al outb %al,$0x35 - movb 0,%al - outb %al,$0xf0 + movb $0x00,%al + outb %al,$0xf0 # reboot the machine exit.4: jmp exit.4 /* * Set IRQ offsets by reprogramming 8259A PICs. @@ -284,10 +309,6 @@ setpic: in $0x02,%al # Save master outb %al,$0x02 # IMR retw # To caller .code32 -/* - * Initiate return from V86 mode to user mode. - */ -inthlt: hlt # To supervisor mode /* * Exception jump table. */ @@ -314,17 +335,11 @@ intx00: push $0x0 # Int 0x0: #DE push $0xc # Int 0xc: #SS jmp except # Stack segment fault push $0xd # Int 0xd: #GP - jmp ex_v86 # General protection + jmp except # General protection push $0xe # Int 0xe: #PF jmp except # Page fault intx10: push $0x10 # Int 0x10: #MF jmp ex_noc # Floating-point error -/* - * Handle #GP exception. - */ -ex_v86: testb $0x2,0x12(%esp,1) # V86 mode? - jz except # No - jmp v86mon # To monitor /* * Save a zero error code. */ @@ -337,24 +352,17 @@ except: cld # String ops inc pushl %ds # Save pushl %es # most pusha # registers - movb $0x6,%al # Push loop count - testb $0x2,0x3a(%esp,1) # V86 mode? - jnz except.1 # Yes pushl %gs # Set GS pushl %fs # Set FS pushl %ds # Set DS pushl %es # Set ES - movb $0x2,%al # Push loop count cmpw $SEL_SCODE,0x44(%esp,1) # Supervisor mode? jne except.1 # No pushl %ss # Set SS - leal 0x50(%esp,1),%eax # Set - pushl %eax # ESP jmp except.2 # Join common code -except.1: pushl 0x50(%esp,1) # Set GS, FS, DS, ES - decb %al # (if V86 mode), and - jne except.1 # SS, ESP -except.2: push $SEL_SDATA # Set up +except.1: pushl 0x50(%esp,1) # Set SS +except.2: pushl 0x50(%esp,1) # Set ESP + push $SEL_SDATA # Set up popl %ds # to pushl %ds # address popl %es # data @@ -363,14 +371,12 @@ except.2: push $SEL_SDATA # Set up movl $MEM_BUF,%edi # Buffer pushl %eax pushl %edx -wait.1: - inb $0x60,%al +wait.1: inb $0x60,%al testb $0x04,%al jz wait.1 movb $0xe0,%al outb %al,$0x62 -wait.2: - inb $0x60,%al +wait.2: inb $0x60,%al testb $0x01,%al jz wait.2 xorl %edx,%edx @@ -399,237 +405,11 @@ wait.2: je except.3 # Yes cmpb $0x1,(%esp,1) # Debug? jne except.2a # No - testl $0x100,0x10(%esp,1) # Trap flag set? + testl $PSL_T,0x10(%esp,1) # Trap flag set? jnz except.3 # Yes except.2a: jmp exit # Exit except.3: leal 0x8(%esp,1),%esp # Discard err, int no iret # From interrupt -/* - * Return to user mode from V86 mode. - */ -intrtn: cld # String ops inc - pushl %ds # Address - popl %es # data - leal 0x3c(%ebp),%edx # V86 Segment registers - movl MEM_TSS+TSS_ESP1,%esi # Link stack pointer - lodsl # INT_V86 args pointer - movl %esi,%ebx # Saved exception frame - testl %eax,%eax # INT_V86 args? - jz intrtn.2 # No - movl $MEM_USR,%edi # User base - movl 0x1c(%esi),%ebx # User ESP - movl %eax,(%edi,%ebx,1) # Restore to user stack - leal 0x8(%edi,%eax,1),%edi # Arg segment registers - testb $0x4,-0x6(%edi) # Return flags? - jz intrtn.1 # No - movl 0x30(%ebp),%eax # Get V86 flags - movw %ax,0x18(%esi) # Set user flags -intrtn.1: leal 0x10(%esi),%ebx # Saved exception frame - xchgl %edx,%esi # Segment registers - movb $0x4,%cl # Update seg regs - rep # in INT_V86 - movsl # args -intrtn.2: xchgl %edx,%esi # Segment registers - leal 0x28(%ebp),%edi # Set up seg - movb $0x4,%cl # regs for - rep # later - movsl # pop - xchgl %ebx,%esi # Restore exception - movb $0x5,%cl # frame to - rep # supervisor - movsl # stack - movl %esi,MEM_TSS+TSS_ESP1 # Link stack pointer - popa # Restore - leal 0x8(%esp,1),%esp # Discard err, int no - popl %es # Restore - popl %ds # user - popl %fs # segment - popl %gs # registers - iret # To user mode -/* - * V86 monitor. - */ -v86mon: cld # String ops inc - pushl $SEL_SDATA # Set up for - popl %ds # flat addressing - pusha # Save registers - movl %esp,%ebp # Address stack frame - movzwl 0x2c(%ebp),%edi # Load V86 CS - shll $0x4,%edi # To linear - movl 0x28(%ebp),%esi # Load V86 IP - addl %edi,%esi # Code pointer - xorl %ecx,%ecx # Zero - movb $0x2,%cl # 16-bit operands - xorl %eax,%eax # Zero -v86mon.1: lodsb # Get opcode - cmpb $0x66,%al # Operand size prefix? - jne v86mon.2 # No - movb $0x4,%cl # 32-bit operands - jmp v86mon.1 # Continue -v86mon.2: cmpb $0xf4,%al # HLT? - jne v86mon.3 # No - cmpl $inthlt+0x1,%esi # Is inthlt? - jne v86mon.7 # No (ignore) - jmp intrtn # Return to user mode -v86mon.3: cmpb $0xf,%al # Prefixed instruction? - jne v86mon.4 # No - cmpb $0x09,(%esi) # Is it a WBINVD? - je v86wbinvd # Yes - cmpb $0x30,(%esi) # Is it a WRMSR? - je v86wrmsr # Yes - cmpb $0x32,(%esi) # Is it a RDMSR? - je v86rdmsr # Yes - cmpb $0x20,(%esi) # Is this a MOV reg,CRx? - je v86mov # Yes -v86mon.4: cmpb $0xfa,%al # CLI? - je v86cli # Yes - cmpb $0xfb,%al # STI? - je v86sti # Yes - movzwl 0x38(%ebp),%ebx # Load V86 SS - shll $0x4,%ebx # To offset - pushl %ebx # Save - addl 0x34(%ebp),%ebx # Add V86 SP - movl 0x30(%ebp),%edx # Load V86 flags - cmpb $0x9c,%al # PUSHF/PUSHFD? - je v86pushf # Yes - cmpb $0x9d,%al # POPF/POPFD? - je v86popf # Yes - cmpb $0xcd,%al # INT imm8? - je v86intn # Yes - cmpb $0xcf,%al # IRET/IRETD? - je v86iret # Yes - popl %ebx # Restore - popa # Restore - jmp except # Handle exception -v86mon.5: movl %edx,0x30(%ebp) # Save V86 flags -v86mon.6: popl %edx # V86 SS adjustment - subl %edx,%ebx # Save V86 - movl %ebx,0x34(%ebp) # SP -v86mon.7: subl %edi,%esi # From linear - movl %esi,0x28(%ebp) # Save V86 IP - popa # Restore - leal 0x8(%esp,1),%esp # Discard int no, error - iret # To V86 mode -/* - * Emulate MOV reg,CRx. - */ -v86mov: movb 0x1(%esi),%bl # Fetch Mod R/M byte - testb $0x10,%bl # Read CR2 or CR3? - jnz v86mov.1 # Yes - movl %cr0,%eax # Read CR0 - testb $0x20,%bl # Read CR4 instead? - jz v86mov.2 # No - movl %cr4,%eax # Read CR4 - jmp v86mov.2 -v86mov.1: movl %cr2,%eax # Read CR2 - testb $0x08,%bl # Read CR3 instead? - jz v86mov.2 # No - movl %cr3,%eax # Read CR3 -v86mov.2: andl $0x7,%ebx # Compute offset in - shl $2,%ebx # frame of destination - neg %ebx # register - movl %eax,0x1c(%ebp,%ebx,1) # Store CR to reg - incl %esi # Adjust IP -/* - * Return from emulating a 0x0f prefixed instruction - */ -v86preret: incl %esi # Adjust IP - jmp v86mon.7 # Finish up -/* - * Emulate WBINVD - */ -v86wbinvd: wbinvd # Write back and invalidate - # cache - jmp v86preret # Finish up -/* - * Emulate WRMSR - */ -v86wrmsr: movl 0x18(%ebp),%ecx # Get user's %ecx (MSR to write) - movl 0x14(%ebp),%edx # Load the value - movl 0x1c(%ebp),%eax # to write - wrmsr # Write MSR - jmp v86preret # Finish up -/* - * Emulate RDMSR - */ -v86rdmsr: movl 0x18(%ebp),%ecx # MSR to read - rdmsr # Read the MSR - movl %eax,0x1c(%ebp) # Return the value of - movl %edx,0x14(%ebp) # the MSR to the user - jmp v86preret # Finish up -/* - * Emulate CLI. - */ -v86cli: andb $~0x2,0x31(%ebp) # Clear IF - jmp v86mon.7 # Finish up -/* - * Emulate STI. - */ -v86sti: orb $0x2,0x31(%ebp) # Set IF - jmp v86mon.7 # Finish up -/* - * Emulate PUSHF/PUSHFD. - */ -v86pushf: subl %ecx,%ebx # Adjust SP - cmpb $0x4,%cl # 32-bit - je v86pushf.1 # Yes - data16 # 16-bit -v86pushf.1: movl %edx,(%ebx) # Save flags - jmp v86mon.6 # Finish up -/* - * Emulate IRET/IRETD. - */ -v86iret: movzwl (%ebx),%esi # Load V86 IP - movzwl 0x2(%ebx),%edi # Load V86 CS - leal 0x4(%ebx),%ebx # Adjust SP - movl %edi,0x2c(%ebp) # Save V86 CS - xorl %edi,%edi # No ESI adjustment -/* - * Emulate POPF/POPFD (and remainder of IRET/IRETD). - */ -v86popf: cmpb $0x4,%cl # 32-bit? - je v86popf.1 # Yes - movl %edx,%eax # Initialize - data16 # 16-bit -v86popf.1: movl (%ebx),%eax # Load flags - addl %ecx,%ebx # Adjust SP - andl $V86_FLG,%eax # Merge - andl $~V86_FLG,%edx # the - orl %eax,%edx # flags - jmp v86mon.5 # Finish up -/* - * trap int 15, function 87 - * reads %es:%si from saved registers on stack to find a GDT containing - * source and destination locations - * reads count of words from saved %cx - * returns success by setting %ah to 0 - */ -int15_87: pushl %esi # Save - pushl %edi # registers - movl 0x3C(%ebp),%edi # Load ES - movzwl 0x4(%ebp),%eax # Load user's SI - shll $0x4,%edi # EDI = (ES << 4) + - addl %eax,%edi # SI - movl 0x11(%edi),%eax # Read base of - movb 0x17(%edi),%al # GDT entry - ror $8,%eax # for source - xchgl %eax,%esi # into %esi - movl 0x19(%edi),%eax # Read base of - movb 0x1f(%edi),%al # GDT entry for - ror $8,%eax # destination - xchgl %eax,%edi # into %edi - pushl %ds # Make: - popl %es # es = ds - movzwl 0x18(%ebp),%ecx # Get user's CX - shll $0x1,%ecx # Convert count from words - rep # repeat... - movsb # perform copy. - popl %edi # Restore - popl %esi # registers - movb $0x0,0x1d(%ebp) # set ah = 0 to indicate - # success - andb $0xfe,%dl # clear CF - jmp v86mon.5 # Finish up /* * Reboot the machine by setting the reboot flag and exiting @@ -638,36 +418,7 @@ reboot: orb $0x1,btx_hdr+0x7 # Set the reboot flag jmp exit # Terminate BTX and reboot /* - * Emulate INT imm8... also make sure to check if it's int 15/87 - */ -v86intn: lodsb # Get int no - cmpb $0x19,%al # is it int 19? - je reboot # yes, reboot the machine - cmpb $0x15,%al # is it int 15? - jne v86intn.1 # no, skip parse - cmpb $0x87,0x1d(%ebp) # is it the memcpy subfunction? - je int15_87 # yes - cmpw $0x4f53,0x1c(%ebp) # is it the delete key callout? - jne v86intn.1 # no, handle the int normally - movb BDA_KEYFLAGS,%ch # get the shift key state - andb $0x18,%ch # mask off just Ctrl and Alt - cmpb $0x18,%ch # are both Ctrl and Alt down? - je reboot # yes, reboot the machine -v86intn.1: subl %edi,%esi # From - shrl $0x4,%edi # linear - movw %dx,-0x2(%ebx) # Save flags - movw %di,-0x4(%ebx) # Save CS - leal -0x6(%ebx),%ebx # Adjust SP - movw %si,(%ebx) # Save IP - shll $0x2,%eax # Scale - movzwl (%eax),%esi # Load IP - movzwl 0x2(%eax),%edi # Load CS - movl %edi,0x2c(%ebp) # Save CS - xorl %edi,%edi # No ESI adjustment - andb $~0x1,%dh # Clear TF - jmp v86mon.5 # Finish up -/* - * Hardware interrupt jump table. + * Protected Mode Hardware interrupt jump table. */ intx20: push $0x8 # Int 0x20: IRQ0 jmp int_hw # V86 int 0x8 @@ -701,127 +452,267 @@ intx20: push $0x8 # Int 0x20: IRQ0 jmp int_hw # V86 int 0x16 push $0x17 # Int 0x2f: IRQ15 jmp int_hw # V86 int 0x17 + /* - * Reflect hardware interrupts. + * Invoke real mode interrupt/function call from user mode with arguments. */ -int_hw: testb $0x2,0xe(%esp,1) # V86 mode? - jz intusr # No - pushl $SEL_SDATA # Address - popl %ds # data - xchgl %eax,(%esp,1) # Swap EAX, int no - pushl %ebp # Address - movl %esp,%ebp # stack frame - pushl %ebx # Save - shll $0x2,%eax # Get int - movl (%eax),%eax # vector - subl $0x6,0x14(%ebp) # Adjust V86 ESP - movzwl 0x18(%ebp),%ebx # V86 SS - shll $0x4,%ebx # * 0x10 - addl 0x14(%ebp),%ebx # + V86 ESP - xchgw %ax,0x8(%ebp) # Swap V86 IP - rorl $0x10,%eax # Swap words - xchgw %ax,0xc(%ebp) # Swap V86 CS - roll $0x10,%eax # Swap words - movl %eax,(%ebx) # CS:IP for IRET - movl 0x10(%ebp),%eax # V86 flags - movw %ax,0x4(%ebx) # Flags for IRET - andb $~0x3,0x11(%ebp) # Clear IF, TF - popl %ebx # Restore - popl %ebp # saved - popl %eax # registers - iret # To V86 mode +intx31: pushl $-1 # Dummy int no for btx_v86 /* - * Invoke V86 interrupt from user mode, with arguments. + * Invoke real mode interrupt/function call from protected mode. + * + * We place a trampoline on the user stack that will return to rret_tramp + * which will reenter protected mode and then finally return to the user + * client. + * + * Kernel frame %esi points to: Real mode stack frame at MEM_ESPR: + * + * -0x00 user %ss -0x04 kernel %esp (with full frame) + * -0x04 user %esp -0x08 btx_v86 pointer + * -0x08 user %eflags -0x0c flags (only used if interrupt) + * -0x0c user %cs -0x10 real mode CS:IP return trampoline + * -0x10 user %eip -0x12 real mode flags + * -0x14 int no -0x16 real mode CS:IP (target) + * -0x18 %eax + * -0x1c %ecx + * -0x20 %edx + * -0x24 %ebx + * -0x28 %esp + * -0x2c %ebp + * -0x30 %esi + * -0x34 %edi + * -0x38 %gs + * -0x3c %fs + * -0x40 %ds + * -0x44 %es + * -0x48 zero %eax (hardware int only) + * -0x4c zero %ecx (hardware int only) + * -0x50 zero %edx (hardware int only) + * -0x54 zero %ebx (hardware int only) + * -0x58 zero %esp (hardware int only) + * -0x5c zero %ebp (hardware int only) + * -0x60 zero %esi (hardware int only) + * -0x64 zero %edi (hardware int only) + * -0x68 zero %gs (hardware int only) + * -0x6c zero %fs (hardware int only) + * -0x70 zero %ds (hardware int only) + * -0x74 zero %es (hardware int only) */ -intx31: stc # Have btx_v86 - pushl %eax # Missing int no -/* - * Invoke V86 interrupt from user mode. - */ -intusr: std # String ops dec - pushl %eax # Expand - pushl %eax # stack - pushl %eax # frame - pusha # Save +int_hw: cld # String ops inc + pusha # Save gp regs pushl %gs # Save - movl %esp,%eax # seg regs - pushl %fs # and - pushl %ds # point - pushl %es # to them + pushl %fs # seg + pushl %ds # regs + pushl %es push $SEL_SDATA # Set up popl %ds # to pushl %ds # address popl %es # data + leal 0x44(%esp,1),%esi # Base of frame + movl %esp,MEM_ESPR-0x04 # Save kernel stack pointer + movl -0x14(%esi),%eax # Get Int no + cmpl $-1,%eax # Hardware interrupt? + jne intusr.1 # Yes +/* + * v86 calls save the btx_v86 pointer on the real mode stack and read + * the address and flags from the btx_v86 structure. For interrupt + * handler invocations (VM86 INTx requests), disable interrupts, + * tracing, and alignment checking while the handler runs. + */ movl $MEM_USR,%ebx # User base movl %ebx,%edx # address - jc intusr.1 # If btx_v86 - xorl %edx,%edx # Control flags - xorl %ebp,%ebp # btx_v86 pointer -intusr.1: leal 0x50(%esp,1),%esi # Base of frame - pushl %esi # Save addl -0x4(%esi),%ebx # User ESP - movl MEM_TSS+TSS_ESP1,%edi # Link stack pointer - leal -0x4(%edi),%edi # Adjust for push - xorl %ecx,%ecx # Zero - movb $0x5,%cl # Push exception - rep # frame on - movsl # link stack - xchgl %eax,%esi # Saved seg regs - movl 0x40(%esp,1),%eax # Get int no - testl %edx,%edx # Have btx_v86? - jz intusr.2 # No movl (%ebx),%ebp # btx_v86 pointer - movb $0x4,%cl # Count - addl %ecx,%ebx # Adjust for pop - rep # Push saved seg regs - movsl # on link stack addl %ebp,%edx # Flatten btx_v86 ptr - leal 0x14(%edx),%esi # Seg regs pointer - movl 0x4(%edx),%eax # Get int no/address - movzwl 0x2(%edx),%edx # Get control flags -intusr.2: movl %ebp,(%edi) # Push btx_v86 and - movl %edi,MEM_TSS+TSS_ESP1 # save link stack ptr - popl %edi # Base of frame - xchgl %eax,%ebp # Save intno/address - movl 0x48(%esp,1),%eax # Get flags - testb $0x2,%dl # Simulate CALLF? - jnz intusr.3 # Yes - decl %ebx # Push flags - decl %ebx # on V86 - movw %ax,(%ebx) # stack -intusr.3: movb $0x4,%cl # Count - subl %ecx,%ebx # Push return address - movl $inthlt,(%ebx) # on V86 stack - rep # Copy seg regs to - movsl # exception frame - xchgl %eax,%ecx # Save flags - movl %ebx,%eax # User ESP - subl $V86_STK,%eax # Less bytes - ja intusr.4 # to - xorl %eax,%eax # keep -intusr.4: shrl $0x4,%eax # Gives segment - stosl # Set SS - shll $0x4,%eax # To bytes - xchgl %eax,%ebx # Swap - subl %ebx,%eax # Gives offset - stosl # Set ESP - xchgl %eax,%ecx # Get flags - btsl $0x11,%eax # Set VM - andb $~0x1,%ah # Clear TF - stosl # Set EFL - xchgl %eax,%ebp # Get int no/address - testb $0x1,%dl # Address? - jnz intusr.5 # Yes - shll $0x2,%eax # Scale + movl %edx,MEM_ESPR-0x08 # Save btx_v86 ptr + movl V86_ADDR(%edx),%eax # Get int no/address + movl V86_CTL(%edx),%edx # Get control flags + movl -0x08(%esi),%ebx # Save user flags in %ebx + testl $V86F_ADDR,%edx # Segment:offset? + jnz intusr.4 # Yes + andl $~(PSL_I|PSL_T|PSL_AC),%ebx # Disable interrupts, tracing, + # and alignment checking for + # interrupt handler + jmp intusr.3 # Skip hardware interrupt +/* + * Hardware interrupts store a NULL btx_v86 pointer and use the + * address (interrupt number) from the stack with empty flags. Also, + * push a dummy frame of zeros onto the stack for all the general + * purpose and segment registers and clear %eflags. This gives the + * hardware interrupt handler a clean slate. + */ +intusr.1: xorl %edx,%edx # Control flags + movl %edx,MEM_ESPR-0x08 # NULL btx_v86 ptr + movl $12,%ecx # Frame is 12 dwords +intusr.2: pushl $0x0 # Fill frame + loop intusr.2 # with zeros + movl $PSL_RESERVED_DEFAULT,%ebx # Set clean %eflags +/* + * Look up real mode IDT entry for hardware interrupts and VM86 INTx + * requests. + */ +intusr.3: shll $0x2,%eax # Scale movl (%eax),%eax # Load int vector -intusr.5: movl %eax,%ecx # Save - shrl $0x10,%eax # Gives segment - stosl # Set CS - movw %cx,%ax # Restore - stosl # Set EIP - leal 0x10(%esp,1),%esp # Discard seg regs - popa # Restore - iret # To V86 mode + jmp intusr.5 # Skip CALLF test +/* + * Panic if V86F_CALLF isn't set with V86F_ADDR. + */ +intusr.4: testl $V86F_CALLF,%edx # Far call? + jnz intusr.5 # Ok + movl %edx,0x30(%esp,1) # Place VM86 flags in int no + movl $badvm86,%esi # Display bad + call putstr # VM86 call + popl %es # Restore + popl %ds # seg + popl %fs # regs + popl %gs + popal # Restore gp regs + jmp ex_noc # Panic +/* + * %eax now holds the segment:offset of the function. + * %ebx now holds the %eflags to pass to real mode. + * %edx now holds the V86F_* flags. + */ +intusr.5: movw %bx,MEM_ESPR-0x12 # Pass user flags to real mode + # target +/* + * If this is a v86 call, copy the seg regs out of the btx_v86 structure. + */ + movl MEM_ESPR-0x08,%ecx # Get btx_v86 ptr + jecxz intusr.6 # Skip for hardware ints + leal -0x44(%esi),%edi # %edi => kernel stack seg regs + pushl %esi # Save + leal V86_ES(%ecx),%esi # %esi => btx_v86 seg regs + movl $4,%ecx # Copy seg regs + rep # from btx_v86 + movsl # to kernel stack + popl %esi # Restore +intusr.6: movl -0x08(%esi),%ebx # Copy user flags to real + movl %ebx,MEM_ESPR-0x0c # mode return trampoline + movl $rret_tramp,%ebx # Set return trampoline + movl %ebx,MEM_ESPR-0x10 # CS:IP + movl %eax,MEM_ESPR-0x16 # Real mode target CS:IP + ljmpw $SEL_RCODE,$intusr.7 # Change to 16-bit segment + .code16 +intusr.7: movl %cr0,%eax # Leave + dec %al # protected + movl %eax,%cr0 # mode + ljmpw $0x0,$intusr.8 +intusr.8: xorw %ax,%ax # Reset %ds + movw %ax,%ds # and + movw %ax,%ss # %ss + lidt ivtdesc # Set IVT + popl %es # Restore + popl %ds # seg + popl %fs # regs + popl %gs + popal # Restore gp regs + movw $MEM_ESPR-0x16,%sp # Switch to real mode stack + iret # Call target routine +/* + * For the return to real mode we setup a stack frame like this on the real + * mode stack. Note that callf calls won't pop off the flags, but we just + * ignore that by repositioning %sp to be just above the btx_v86 pointer + * so it is aligned. The stack is relative to MEM_ESPR. + * + * -0x04 kernel %esp + * -0x08 btx_v86 + * -0x0c %eax + * -0x10 %ecx + * -0x14 %edx + * -0x18 %ebx + * -0x1c %esp + * -0x20 %ebp + * -0x24 %esi + * -0x28 %edi + * -0x2c %gs + * -0x30 %fs + * -0x34 %ds + * -0x38 %es + * -0x3c %eflags + */ +rret_tramp: movw $MEM_ESPR-0x08,%sp # Reset stack pointer + pushal # Save gp regs + pushl %gs # Save + pushl %fs # seg + pushl %ds # regs + pushl %es + pushfl # Save %eflags + cli # Disable interrupts + std # String ops dec + xorw %ax,%ax # Reset seg + movw %ax,%ds # regs + movw %ax,%es # (%ss is already 0) + lidt idtdesc # Set IDT + lgdt gdtdesc # Set GDT + mov %cr0,%eax # Switch to protected + inc %ax # mode + mov %eax,%cr0 # + ljmp $SEL_SCODE,$rret_tramp.1 # To 32-bit code + .code32 +rret_tramp.1: xorl %ecx,%ecx # Zero + movb $SEL_SDATA,%cl # Setup + movw %cx,%ss # 32-bit + movw %cx,%ds # seg + movw %cx,%es # regs + movl MEM_ESPR-0x04,%esp # Switch to kernel stack + leal 0x44(%esp,1),%esi # Base of frame + andb $~0x2,tss_desc+0x5 # Clear TSS busy + movb $SEL_TSS,%cl # Set task + ltr %cx # register +/* + * Now we are back in protected mode. The kernel stack frame set up + * before entering real mode is still intact. For hardware interrupts, + * leave the frame unchanged. + */ + cmpl $0,MEM_ESPR-0x08 # Leave saved regs unchanged + jz rret_tramp.3 # for hardware ints +/* + * For V86 calls, copy the registers off of the real mode stack onto + * the kernel stack as we want their updated values. Also, initialize + * the segment registers on the kernel stack. + * + * Note that the %esp in the kernel stack after this is garbage, but popa + * ignores it, so we don't have to fix it up. + */ + leal -0x18(%esi),%edi # Kernel stack GP regs + pushl %esi # Save + movl $MEM_ESPR-0x0c,%esi # Real mode stack GP regs + movl $8,%ecx # Copy GP regs from + rep # real mode stack + movsl # to kernel stack + movl $SEL_UDATA,%eax # Selector for data seg regs + movl $4,%ecx # Initialize %ds, + rep # %es, %fs, and + stosl # %gs +/* + * For V86 calls, copy the saved seg regs on the real mode stack back + * over to the btx_v86 structure. Also, conditionally update the + * saved eflags on the kernel stack based on the flags from the user. + */ + movl MEM_ESPR-0x08,%ecx # Get btx_v86 ptr + leal V86_GS(%ecx),%edi # %edi => btx_v86 seg regs + leal MEM_ESPR-0x2c,%esi # %esi => real mode seg regs + xchgl %ecx,%edx # Save btx_v86 ptr + movl $4,%ecx # Copy seg regs + rep # from real mode stack + movsl # to btx_v86 + popl %esi # Restore + movl V86_CTL(%edx),%edx # Read V86 control flags + testl $V86F_FLAGS,%edx # User wants flags? + jz rret_tramp.3 # No + movl MEM_ESPR-0x3c,%eax # Read real mode flags + movw %ax,-0x08(%esi) # Update user flags (low 16) +/* + * Return to the user task + */ +rret_tramp.3: popl %es # Restore + popl %ds # seg + popl %fs # regs + popl %gs + popal # Restore gp regs + addl $4,%esp # Discard int no + iret # Return to user mode + /* * System Call. */ @@ -869,7 +760,7 @@ dump.1: testb $DMP_X32,%ch # Dump long? dump.2: testb $DMP_MEM,%ch # Dump memory? jz dump.8 # No pushl %ds # Save - testb $0x2,0x52(%ebx) # V86 mode? + testl $PSL_VM,0x50(%ebx) # V86 mode? jnz dump.3 # Yes verr 0x4(%esi) # Readable selector? jnz dump.3 # No @@ -1060,6 +951,61 @@ putchr.4: movw %dx,(%ebx) # Update position ret # To caller #endif + .code16 +/* + * Real Mode Hardware interrupt jump table. + */ +intr20: push $0x8 # Int 0x20: IRQ0 + jmp int_hwr # V86 int 0x8 + push $0x9 # Int 0x21: IRQ1 + jmp int_hwr # V86 int 0x9 + push $0xa # Int 0x22: IRQ2 + jmp int_hwr # V86 int 0xa + push $0xb # Int 0x23: IRQ3 + jmp int_hwr # V86 int 0xb + push $0xc # Int 0x24: IRQ4 + jmp int_hwr # V86 int 0xc + push $0xd # Int 0x25: IRQ5 + jmp int_hwr # V86 int 0xd + push $0xe # Int 0x26: IRQ6 + jmp int_hwr # V86 int 0xe + push $0xf # Int 0x27: IRQ7 + jmp int_hwr # V86 int 0xf + push $0x10 # Int 0x28: IRQ8 + jmp int_hwr # V86 int 0x10 + push $0x11 # Int 0x29: IRQ9 + jmp int_hwr # V86 int 0x11 + push $0x12 # Int 0x2a: IRQ10 + jmp int_hwr # V86 int 0x12 + push $0x13 # Int 0x2b: IRQ11 + jmp int_hwr # V86 int 0x13 + push $0x14 # Int 0x2c: IRQ12 + jmp int_hwr # V86 int 0x14 + push $0x15 # Int 0x2d: IRQ13 + jmp int_hwr # V86 int 0x15 + push $0x16 # Int 0x2e: IRQ14 + jmp int_hwr # V86 int 0x16 + push $0x17 # Int 0x2f: IRQ15 + jmp int_hwr # V86 int 0x17 +/* + * Reflect hardware interrupts in real mode. + */ +int_hwr: push %ax # Save + push %ds # Save + push %bp # Save + mov %sp,%bp # Address stack frame + xchg %bx,6(%bp) # Swap BX, int no + xor %ax,%ax # Set %ds:%bx to + shl $2,%bx # point to + mov %ax,%ds # IDT entry + mov (%bx),%ax # Load IP + mov 2(%bx),%bx # Load CS + xchg %ax,4(%bp) # Swap saved %ax,%bx with + xchg %bx,6(%bp) # CS:IP of handler + pop %bp # Restore + pop %ds # Restore + lret # Jump to handler + .p2align 4 /* * Global descriptor table. @@ -1071,7 +1017,7 @@ gdt: .word 0x0,0x0,0x0,0x0 # Null entry .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA .word 0xffff,MEM_USR,0xfa00,0xcf# SEL_UCODE .word 0xffff,MEM_USR,0xf200,0xcf# SEL_UDATA - .word _TSSLM,MEM_TSS,0x8900,0x0 # SEL_TSS +tss_desc: .word _TSSLM,MEM_TSS,0x8900,0x0 # SEL_TSS gdt.1: /* * Pseudo-descriptors. @@ -1139,6 +1085,11 @@ dmpfmt: .byte '\n' # "\n" .ascii "ss:esp" # "ss:esp=" .byte 0x80|DMP_MEM|DMP_EOL,0x0 # "00 00 ... 00 00\n" .asciz "BTX halted\n" # End +/* + * Bad VM86 call panic + */ +badvm86: .asciz "Invalid VM86 Request\n" + /* * End of BTX memory. */ From 39fb869679127012a938e9a8f77024fdf03c9a73 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 19 Dec 2009 10:28:24 +0000 Subject: [PATCH 0892/2592] MFC r200444: For ia32 syscall(), call cpu_set_syscall_retval(). --- sys/amd64/amd64/vm_machdep.c | 6 +++++- sys/amd64/ia32/ia32_syscall.c | 30 +----------------------------- 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 6e567400355..a99fdaaf634 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -330,10 +330,14 @@ cpu_set_syscall_retval(struct thread *td, int error) case ERESTART: /* - * Reconstruct pc, we know that 'syscall' is 2 bytes. + * Reconstruct pc, we know that 'syscall' is 2 bytes, + * lcall $X,y is 7 bytes, int 0x80 is 2 bytes. + * We saved this in tf_err. * We have to do a full context restore so that %r10 * (which was holding the value of %rcx) is restored * for the next iteration. + * r10 restore is only required for freebsd/amd64 processes, + * but shall be innocent for any ia32 ABI. */ td->td_frame->tf_rip -= td->td_frame->tf_err; td->td_frame->tf_r10 = td->td_frame->tf_rcx; diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c index 48072486406..5e2087607d4 100644 --- a/sys/amd64/ia32/ia32_syscall.c +++ b/sys/amd64/ia32/ia32_syscall.c @@ -183,35 +183,7 @@ ia32_syscall(struct trapframe *frame) AUDIT_SYSCALL_EXIT(error, td); } - 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, assuming lcall $X,y is 7 bytes, - * int 0x80 is 2 bytes. We saved this in tf_err. - */ - frame->tf_rip -= 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_rax = error; - frame->tf_rflags |= PSL_C; - break; - } + cpu_set_syscall_retval(td, error); /* * Traced syscall. From c9ac7946d7e6d71e1df350b44e23f55ed4210b31 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 19 Dec 2009 10:38:28 +0000 Subject: [PATCH 0893/2592] MFC r200033: mca: improve status checking, recording and reporting --- sys/amd64/amd64/mca.c | 111 ++++++++++++++++++++++------------------ sys/amd64/include/mca.h | 1 + sys/i386/i386/mca.c | 111 ++++++++++++++++++++++------------------ sys/i386/include/mca.h | 1 + 4 files changed, 126 insertions(+), 98 deletions(-) diff --git a/sys/amd64/amd64/mca.c b/sys/amd64/amd64/mca.c index d291d009ee2..7014f75e6fc 100644 --- a/sys/amd64/amd64/mca.c +++ b/sys/amd64/amd64/mca.c @@ -117,48 +117,6 @@ sysctl_mca_records(SYSCTL_HANDLER_ARGS) return (SYSCTL_OUT(req, &record, sizeof(record))); } -static struct mca_record * -mca_record_entry(int bank) -{ - struct mca_internal *rec; - uint64_t status; - u_int p[4]; - - status = rdmsr(MSR_MC_STATUS(bank)); - if (!(status & MC_STATUS_VAL)) - return (NULL); - - rec = malloc(sizeof(*rec), M_MCA, M_NOWAIT | M_ZERO); - if (rec == NULL) { - printf("MCA: Unable to allocate space for an event.\n"); - return (NULL); - } - - /* Save exception information. */ - rec->rec.mr_status = status; - if (status & MC_STATUS_ADDRV) - rec->rec.mr_addr = rdmsr(MSR_MC_ADDR(bank)); - if (status & MC_STATUS_MISCV) - rec->rec.mr_misc = rdmsr(MSR_MC_MISC(bank)); - rec->rec.mr_tsc = rdtsc(); - rec->rec.mr_apic_id = PCPU_GET(apic_id); - - /* - * Clear machine check. Don't do this for uncorrectable - * errors so that the BIOS can see them. - */ - if (!(rec->rec.mr_status & (MC_STATUS_PCC | MC_STATUS_UC))) { - wrmsr(MSR_MC_STATUS(bank), 0); - do_cpuid(0, p); - } - - mtx_lock_spin(&mca_lock); - STAILQ_INSERT_TAIL(&mca_records, rec, link); - mca_count++; - mtx_unlock_spin(&mca_lock); - return (&rec->rec); -} - static const char * mca_error_ttype(uint16_t mca_error) { @@ -219,11 +177,13 @@ mca_error_request(uint16_t mca_error) } /* Dump details about a single machine check. */ -static void -mca_log(struct mca_record *rec) +static void __nonnull(1) +mca_log(const struct mca_record *rec) { uint16_t mca_error; + printf("MCA: bank %d, status 0x%016llx\n", rec->mr_bank, + (long long)rec->mr_status); printf("MCA: CPU %d ", rec->mr_apic_id); if (rec->mr_status & MC_STATUS_UC) printf("UNCOR "); @@ -329,6 +289,59 @@ mca_log(struct mca_record *rec) printf("MCA: Address 0x%llx\n", (long long)rec->mr_addr); } +static int __nonnull(2) +mca_check_status(int bank, struct mca_record *rec) +{ + uint64_t status; + u_int p[4]; + + status = rdmsr(MSR_MC_STATUS(bank)); + if (!(status & MC_STATUS_VAL)) + return (0); + + /* Save exception information. */ + rec->mr_status = status; + rec->mr_bank = bank; + rec->mr_addr = 0; + if (status & MC_STATUS_ADDRV) + rec->mr_addr = rdmsr(MSR_MC_ADDR(bank)); + rec->mr_misc = 0; + if (status & MC_STATUS_MISCV) + rec->mr_misc = rdmsr(MSR_MC_MISC(bank)); + rec->mr_tsc = rdtsc(); + rec->mr_apic_id = PCPU_GET(apic_id); + + /* + * Clear machine check. Don't do this for uncorrectable + * errors so that the BIOS can see them. + */ + if (!(rec->mr_status & (MC_STATUS_PCC | MC_STATUS_UC))) { + wrmsr(MSR_MC_STATUS(bank), 0); + do_cpuid(0, p); + } + return (1); +} + +static void __nonnull(1) +mca_record_entry(const struct mca_record *record) +{ + struct mca_internal *rec; + + rec = malloc(sizeof(*rec), M_MCA, M_NOWAIT); + if (rec == NULL) { + printf("MCA: Unable to allocate space for an event.\n"); + mca_log(record); + return; + } + + rec->rec = *record; + rec->logged = 0; + mtx_lock_spin(&mca_lock); + STAILQ_INSERT_TAIL(&mca_records, rec, link); + mca_count++; + mtx_unlock_spin(&mca_lock); +} + /* * This scans all the machine check banks of the current CPU to see if * there are any machine checks. Any non-recoverable errors are @@ -341,7 +354,7 @@ mca_log(struct mca_record *rec) static int mca_scan(int mcip) { - struct mca_record *rec; + struct mca_record rec; uint64_t mcg_cap, ucmask; int count, i, recoverable; @@ -354,13 +367,13 @@ mca_scan(int mcip) ucmask |= MC_STATUS_OVER; mcg_cap = rdmsr(MSR_MCG_CAP); for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { - rec = mca_record_entry(i); - if (rec != NULL) { + if (mca_check_status(i, &rec)) { count++; - if (rec->mr_status & ucmask) { + if (rec.mr_status & ucmask) { recoverable = 0; - mca_log(rec); + mca_log(&rec); } + mca_record_entry(&rec); } } return (mcip ? recoverable : count); diff --git a/sys/amd64/include/mca.h b/sys/amd64/include/mca.h index c43d98953e4..ddc3aeb649a 100644 --- a/sys/amd64/include/mca.h +++ b/sys/amd64/include/mca.h @@ -36,6 +36,7 @@ struct mca_record { uint64_t mr_misc; uint64_t mr_tsc; int mr_apic_id; + int mr_bank; }; #ifdef _KERNEL diff --git a/sys/i386/i386/mca.c b/sys/i386/i386/mca.c index 5e7e4ffea26..8af209160dd 100644 --- a/sys/i386/i386/mca.c +++ b/sys/i386/i386/mca.c @@ -117,48 +117,6 @@ sysctl_mca_records(SYSCTL_HANDLER_ARGS) return (SYSCTL_OUT(req, &record, sizeof(record))); } -static struct mca_record * -mca_record_entry(int bank) -{ - struct mca_internal *rec; - uint64_t status; - u_int p[4]; - - status = rdmsr(MSR_MC_STATUS(bank)); - if (!(status & MC_STATUS_VAL)) - return (NULL); - - rec = malloc(sizeof(*rec), M_MCA, M_NOWAIT | M_ZERO); - if (rec == NULL) { - printf("MCA: Unable to allocate space for an event.\n"); - return (NULL); - } - - /* Save exception information. */ - rec->rec.mr_status = status; - if (status & MC_STATUS_ADDRV) - rec->rec.mr_addr = rdmsr(MSR_MC_ADDR(bank)); - if (status & MC_STATUS_MISCV) - rec->rec.mr_misc = rdmsr(MSR_MC_MISC(bank)); - rec->rec.mr_tsc = rdtsc(); - rec->rec.mr_apic_id = PCPU_GET(apic_id); - - /* - * Clear machine check. Don't do this for uncorrectable - * errors so that the BIOS can see them. - */ - if (!(rec->rec.mr_status & (MC_STATUS_PCC | MC_STATUS_UC))) { - wrmsr(MSR_MC_STATUS(bank), 0); - do_cpuid(0, p); - } - - mtx_lock_spin(&mca_lock); - STAILQ_INSERT_TAIL(&mca_records, rec, link); - mca_count++; - mtx_unlock_spin(&mca_lock); - return (&rec->rec); -} - static const char * mca_error_ttype(uint16_t mca_error) { @@ -219,11 +177,13 @@ mca_error_request(uint16_t mca_error) } /* Dump details about a single machine check. */ -static void -mca_log(struct mca_record *rec) +static void __nonnull(1) +mca_log(const struct mca_record *rec) { uint16_t mca_error; + printf("MCA: bank %d, status 0x%016llx\n", rec->mr_bank, + (long long)rec->mr_status); printf("MCA: CPU %d ", rec->mr_apic_id); if (rec->mr_status & MC_STATUS_UC) printf("UNCOR "); @@ -329,6 +289,59 @@ mca_log(struct mca_record *rec) printf("MCA: Address 0x%llx\n", (long long)rec->mr_addr); } +static int __nonnull(2) +mca_check_status(int bank, struct mca_record *rec) +{ + uint64_t status; + u_int p[4]; + + status = rdmsr(MSR_MC_STATUS(bank)); + if (!(status & MC_STATUS_VAL)) + return (0); + + /* Save exception information. */ + rec->mr_status = status; + rec->mr_bank = bank; + rec->mr_addr = 0; + if (status & MC_STATUS_ADDRV) + rec->mr_addr = rdmsr(MSR_MC_ADDR(bank)); + rec->mr_misc = 0; + if (status & MC_STATUS_MISCV) + rec->mr_misc = rdmsr(MSR_MC_MISC(bank)); + rec->mr_tsc = rdtsc(); + rec->mr_apic_id = PCPU_GET(apic_id); + + /* + * Clear machine check. Don't do this for uncorrectable + * errors so that the BIOS can see them. + */ + if (!(rec->mr_status & (MC_STATUS_PCC | MC_STATUS_UC))) { + wrmsr(MSR_MC_STATUS(bank), 0); + do_cpuid(0, p); + } + return (1); +} + +static void __nonnull(1) +mca_record_entry(const struct mca_record *record) +{ + struct mca_internal *rec; + + rec = malloc(sizeof(*rec), M_MCA, M_NOWAIT); + if (rec == NULL) { + printf("MCA: Unable to allocate space for an event.\n"); + mca_log(record); + return; + } + + rec->rec = *record; + rec->logged = 0; + mtx_lock_spin(&mca_lock); + STAILQ_INSERT_TAIL(&mca_records, rec, link); + mca_count++; + mtx_unlock_spin(&mca_lock); +} + /* * This scans all the machine check banks of the current CPU to see if * there are any machine checks. Any non-recoverable errors are @@ -341,7 +354,7 @@ mca_log(struct mca_record *rec) static int mca_scan(int mcip) { - struct mca_record *rec; + struct mca_record rec; uint64_t mcg_cap, ucmask; int count, i, recoverable; @@ -354,13 +367,13 @@ mca_scan(int mcip) ucmask |= MC_STATUS_OVER; mcg_cap = rdmsr(MSR_MCG_CAP); for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { - rec = mca_record_entry(i); - if (rec != NULL) { + if (mca_check_status(i, &rec)) { count++; - if (rec->mr_status & ucmask) { + if (rec.mr_status & ucmask) { recoverable = 0; - mca_log(rec); + mca_log(&rec); } + mca_record_entry(&rec); } } return (mcip ? recoverable : count); diff --git a/sys/i386/include/mca.h b/sys/i386/include/mca.h index c43d98953e4..ddc3aeb649a 100644 --- a/sys/i386/include/mca.h +++ b/sys/i386/include/mca.h @@ -36,6 +36,7 @@ struct mca_record { uint64_t mr_misc; uint64_t mr_tsc; int mr_apic_id; + int mr_bank; }; #ifdef _KERNEL From 176c4e55085630892d0f3d8f8a2bd79c15da1a82 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 19 Dec 2009 10:44:26 +0000 Subject: [PATCH 0894/2592] MFC r200064: mca: small enhancements related to cpu quirks --- sys/amd64/amd64/mca.c | 30 ++++++++++++++++++++++-------- sys/i386/i386/mca.c | 30 ++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/sys/amd64/amd64/mca.c b/sys/amd64/amd64/mca.c index 7014f75e6fc..0403de4c47b 100644 --- a/sys/amd64/amd64/mca.c +++ b/sys/amd64/amd64/mca.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -478,6 +479,8 @@ void mca_init(void) { uint64_t mcg_cap; + uint64_t ctl; + int skip; int i; /* MCE is required. */ @@ -495,15 +498,26 @@ mca_init(void) wrmsr(MSR_MCG_CTL, MCG_CTL_ENABLE); for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { - /* - * Enable logging of all errors. For P6 - * processors, MC0_CTL is always enabled. - * - * XXX: Better CPU test needed here? - */ - if (!(i == 0 && (cpu_id & 0xf00) == 0x600)) - wrmsr(MSR_MC_CTL(i), 0xffffffffffffffffUL); + /* By default enable logging of all errors. */ + ctl = 0xffffffffffffffffUL; + skip = 0; + if (cpu_vendor_id == CPU_VENDOR_INTEL) { + /* + * For P6 models before Nehalem MC0_CTL is + * always enabled and reserved. + */ + if (i == 0 && CPUID_TO_FAMILY(cpu_id) == 0x6 + && CPUID_TO_MODEL(cpu_id) < 0x1a) + skip = 1; + } else if (cpu_vendor_id == CPU_VENDOR_AMD) { + /* BKDG for Family 10h: unset GartTblWkEn. */ + if (i == 4 && CPUID_TO_FAMILY(cpu_id) >= 0xf) + ctl &= ~(1UL << 10); + } + + if (!skip) + wrmsr(MSR_MC_CTL(i), ctl); /* Clear all errors. */ wrmsr(MSR_MC_STATUS(i), 0); } diff --git a/sys/i386/i386/mca.c b/sys/i386/i386/mca.c index 8af209160dd..eaa78b86262 100644 --- a/sys/i386/i386/mca.c +++ b/sys/i386/i386/mca.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -478,6 +479,8 @@ void mca_init(void) { uint64_t mcg_cap; + uint64_t ctl; + int skip; int i; /* MCE is required. */ @@ -495,15 +498,26 @@ mca_init(void) wrmsr(MSR_MCG_CTL, MCG_CTL_ENABLE); for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { - /* - * Enable logging of all errors. For P6 - * processors, MC0_CTL is always enabled. - * - * XXX: Better CPU test needed here? - */ - if (!(i == 0 && (cpu_id & 0xf00) == 0x600)) - wrmsr(MSR_MC_CTL(i), 0xffffffffffffffffUL); + /* By default enable logging of all errors. */ + ctl = 0xffffffffffffffffUL; + skip = 0; + if (cpu_vendor_id == CPU_VENDOR_INTEL) { + /* + * For P6 models before Nehalem MC0_CTL is + * always enabled and reserved. + */ + if (i == 0 && CPUID_TO_FAMILY(cpu_id) == 0x6 + && CPUID_TO_MODEL(cpu_id) < 0x1a) + skip = 1; + } else if (cpu_vendor_id == CPU_VENDOR_AMD) { + /* BKDG for Family 10h: unset GartTblWkEn. */ + if (i == 4 && CPUID_TO_FAMILY(cpu_id) >= 0xf) + ctl &= ~(1UL << 10); + } + + if (!skip) + wrmsr(MSR_MC_CTL(i), ctl); /* Clear all errors. */ wrmsr(MSR_MC_STATUS(i), 0); } From 416d0d62ae4c60663e48cfe8ff1990b0bfa6409f Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 19 Dec 2009 10:52:32 +0000 Subject: [PATCH 0895/2592] MFC r200602: ichsmb: add another pci id --- sys/dev/ichsmb/ichsmb_pci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/dev/ichsmb/ichsmb_pci.c b/sys/dev/ichsmb/ichsmb_pci.c index ee544b43666..c060b2ae2ac 100644 --- a/sys/dev/ichsmb/ichsmb_pci.c +++ b/sys/dev/ichsmb/ichsmb_pci.c @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); #define ID_82801H 0x283e8086 #define ID_82801I 0x29308086 #define ID_82801JI 0x3a308086 +#define ID_PCH 0x3b308086 #define ID_6300ESB 0x25a48086 #define ID_631xESB 0x269b8086 @@ -164,6 +165,9 @@ ichsmb_pci_probe(device_t dev) case ID_82801JI: device_set_desc(dev, "Intel 82801JI (ICH10) SMBus controller"); break; + case ID_PCH: + device_set_desc(dev, "Intel PCH SMBus controller"); + break; case ID_6300ESB: device_set_desc(dev, "Intel 6300ESB (ICH) SMBus controller"); break; From 6ddf1cd2400d1547e93f40de7cf9d8367461f6f7 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 19 Dec 2009 10:54:29 +0000 Subject: [PATCH 0896/2592] MFC r197963: Put process-directed signals to the process queue unconditionally, selecting the thread to deliver the signal only by the thread returning to usermode. Change cursig() and postsig() to look both into the thread and process signal queues. MFC r197976: Fix typo. MFC r200082: Remove wrong assertion. Debugee is allowed to lose a signal --- sys/kern/kern_sig.c | 128 +++++++++++++++++++++++++++++++++---------- sys/kern/kern_thr.c | 2 +- sys/kern/subr_trap.c | 11 +++- sys/sys/signalvar.h | 8 ++- 4 files changed, 116 insertions(+), 33 deletions(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index e11d7998cef..da3cc48222e 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -216,6 +216,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) { @@ -577,20 +579,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; @@ -972,24 +965,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); @@ -997,10 +994,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: @@ -1008,7 +1008,20 @@ kern_sigprocmask(td, how, set, oset, old) break; } } - PROC_UNLOCK(td->td_proc); + + /* + * 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 + * 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); } @@ -1981,17 +1994,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; @@ -2388,6 +2393,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. @@ -2405,6 +2466,7 @@ issignal(struct thread *td, int stop_allowed) { struct proc *p; struct sigacts *ps; + struct sigqueue *queue; sigset_t sigpending; int sig, prop, newsig; @@ -2416,6 +2478,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) @@ -2436,6 +2499,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) { @@ -2448,12 +2512,17 @@ 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; + sigqueue_get(queue, sig, &ksi); + } /* * If parent wants us to take the signal, @@ -2468,7 +2537,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); @@ -2563,6 +2632,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 */ } @@ -2609,7 +2679,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 4f1d01f565d4a97783817d9e001eab0c2158143b Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 19 Dec 2009 11:05:42 +0000 Subject: [PATCH 0897/2592] MFC r200053,200091: ichsmb: drop default attachment to generic smbus hw Note that r200091 completely overrides r200053 and the merge of the former is recorded for bookkeeping only. r200091 won't be merged to 'more stable' branche(s) because of the POLA. --- sys/dev/ichsmb/ichsmb_pci.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/ichsmb/ichsmb_pci.c b/sys/dev/ichsmb/ichsmb_pci.c index c060b2ae2ac..0843afe40cf 100644 --- a/sys/dev/ichsmb/ichsmb_pci.c +++ b/sys/dev/ichsmb/ichsmb_pci.c @@ -175,12 +175,6 @@ ichsmb_pci_probe(device_t dev) device_set_desc(dev, "Intel 631xESB/6321ESB (ESB2) SMBus controller"); break; default: - if (pci_get_class(dev) == PCIC_SERIALBUS - && pci_get_subclass(dev) == PCIS_SERIALBUS_SMBUS - && pci_get_progif(dev) == PCIS_SERIALBUS_SMBUS_PROGIF) { - device_set_desc(dev, "SMBus controller"); - return (BUS_PROBE_DEFAULT); /* XXX */ - } return (ENXIO); } From 9fe2c7cecdd9d3cceecab5e7f0d73fdf5d39aa9d Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sat, 19 Dec 2009 11:11:57 +0000 Subject: [PATCH 0898/2592] Fix inappropriate merge. Pointed out by: kib Pointy hat to: delphij --- ObsoleteFiles.inc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 650f84b0c09..a08f72944d7 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -16,14 +16,6 @@ # 20091218: removal of rc.early(8) link OLD_FILES+=usr/share/man/man8/rc.early.8.gz -# 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 -# 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 # 20090904: remove lukemftpd OLD_FILES+=usr/libexec/lukemftpd OLD_FILES+=usr/share/man/man5/ftpd.conf.5.gz From 3134e1153f0e054bfbbd732cb3f69975f1d8c693 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 19 Dec 2009 11:13:59 +0000 Subject: [PATCH 0899/2592] MFC r198506: In kern_sigsuspend(), manipulate thread signal mask using kern_sigprocmask(). Also, 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. MFC r199136: Use cpu_set_syscall_retval(9) to set syscall result, and return EJUSTRETURN from kern_sigsuspend() to prevent syscall return code from modifying wrong frame. Take care of possibility that pending SIGCONT might be cancelled by SIGSTOP, causing postsig() not to deliver any catched signal. --- sys/compat/freebsd32/freebsd32_misc.c | 13 +----- sys/kern/kern_sig.c | 58 +++++++++++++++------------ sys/sys/signalvar.h | 9 ++++- sys/sys/syscallsubr.h | 2 - 4 files changed, 40 insertions(+), 42 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 da3cc48222e..38bae18da7a 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -966,14 +966,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; @@ -995,7 +996,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; @@ -1021,7 +1022,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); } @@ -1454,6 +1456,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 @@ -1463,16 +1466,29 @@ 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. + */ + 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) + 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 */ @@ -1491,21 +1507,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 */ @@ -2662,7 +2667,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; { @@ -2681,7 +2686,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); @@ -2747,6 +2752,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 b39f2bfd4c4..604d8220388 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: */ @@ -325,7 +329,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); @@ -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 43ba78037b11cbdbf8e3114536cf35bb57ad7bc6 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 19 Dec 2009 11:31:28 +0000 Subject: [PATCH 0900/2592] MFC r198507: Use kern_sigprocmask() instead of direct manipulation of td_sigmask to reschedule newly blocked signals. MFC r198590: Trapsignal() calls kern_sigprocmask() when delivering catched signal with proc lock held. MFC r198670: For trapsignal() and postsig(), kern_sigprocmask() is called with both process lock and curproc->p_sigacts->ps_mtx locked. Prevent lock recursion on ps_mtx in reschedule_signals(). --- 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 | 50 +++++++++++++-------------- 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 +--- sys/sys/signalvar.h | 1 + 17 files changed, 80 insertions(+), 190 deletions(-) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index e4c51a3bb82..c4130a453f9 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 67a64c98944..801af7c97f4 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 0cfe95deb45..6d34e4d26d8 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -1119,11 +1119,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; /* @@ -1135,17 +1133,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 38bae18da7a..768270a5412 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -216,7 +216,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) @@ -1020,7 +1020,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); @@ -1392,15 +1392,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); } @@ -1414,16 +1410,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 */ @@ -1839,6 +1830,7 @@ void trapsignal(struct thread *td, ksiginfo_t *ksi) { struct sigacts *ps; + sigset_t mask; struct proc *p; int sig; int code; @@ -1861,9 +1853,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)]); + mask = ps->ps_catchmask[_SIG_IDX(sig)]; if (!SIGISMEMBER(ps->ps_signodefer, sig)) - SIGADDSET(td->td_sigmask, sig); + SIGADDSET(mask, sig); + 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. @@ -2399,7 +2393,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; @@ -2417,12 +2411,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); } } @@ -2450,7 +2446,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); } @@ -2676,7 +2672,7 @@ postsig(sig) struct sigacts *ps; sig_t action; ksiginfo_t ksi; - sigset_t returnmask; + sigset_t returnmask, mask; KASSERT(sig != 0, ("postsig")); @@ -2731,9 +2727,11 @@ postsig(sig) } else returnmask = td->td_sigmask; - SIGSETOR(td->td_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]); + mask = ps->ps_catchmask[_SIG_IDX(sig)]; if (!SIGISMEMBER(ps->ps_signodefer, sig)) - SIGADDSET(td->td_sigmask, sig); + SIGADDSET(mask, sig); + kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, + SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_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 a29866c8aa2..4be11b52eaa 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -695,7 +695,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; @@ -710,12 +709,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 72ff977c6b5..9f5960b6daa 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -664,7 +664,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; @@ -679,12 +678,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 c1610659936..244928a81e3 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); diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 604d8220388..65d9cf53ef3 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 7e76751181fc12c96c0da29c12f0ee4d34c9e56a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 19 Dec 2009 11:47:00 +0000 Subject: [PATCH 0901/2592] MFC r198508, r198509: Reimplement pselect() in kernel, making change of sigmask and sleep atomic. MFC r198538: Move pselect(3) man page to section 2. --- lib/libc/gen/Makefile.inc | 4 +- lib/libc/gen/Symbol.map | 2 - lib/libc/gen/pselect.c | 78 ----------------------- lib/libc/sys/Makefile.inc | 3 +- lib/libc/sys/Symbol.map | 3 + lib/libc/{gen/pselect.3 => sys/pselect.2} | 11 +--- 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 + 13 files changed, 116 insertions(+), 95 deletions(-) delete mode 100644 lib/libc/gen/pselect.c rename lib/libc/{gen/pselect.3 => sys/pselect.2} (95%) diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index 903fa220cf6..d04dd750205 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -22,7 +22,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 \ @@ -63,7 +63,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/gen/Symbol.map b/lib/libc/gen/Symbol.map index 197430acdda..4c19a3de26a 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; @@ -453,7 +452,6 @@ FBSDprivate_1.0 { __opendir2; __pause; _pause; - __pselect; __pw_scan; /* Used by (at least) libutil */ __raise; _raise; 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/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/sys/Symbol.map b/lib/libc/sys/Symbol.map index 56d8aaaa464..7ff42da3118 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; @@ -779,6 +780,8 @@ FBSDprivate_1.0 { __sys_preadv; _profil; __sys_profil; + _pselect; + __sys_pselect; _ptrace; __sys_ptrace; _pwritev; diff --git a/lib/libc/gen/pselect.3 b/lib/libc/sys/pselect.2 similarity index 95% rename from lib/libc/gen/pselect.3 rename to lib/libc/sys/pselect.2 index a56a0a80a88..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 @@ -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 @@ -121,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 . diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c index 698c0c3f115..31af6fadd3e 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 *); @@ -366,7 +368,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 f5a7455c103..485f7a6d816 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -913,3 +913,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 0ae9845d9b96ff8a3a52e4bbc6d5e2493c35fdc2 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 19 Dec 2009 11:50:04 +0000 Subject: [PATCH 0902/2592] Regen --- 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 +- sys/kern/init_sysent.c | 3 +- sys/kern/syscalls.c | 3 +- sys/kern/systrace_args.c | 37 +++++++++++++++++++++++ sys/sys/syscall.h | 5 +-- sys/sys/syscall.mk | 5 +-- sys/sys/sysproto.h | 12 +++++++- 10 files changed, 76 insertions(+), 12 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index ec3fdc9b62e..551d9011bd7 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: stable/8/sys/compat/freebsd32/syscalls.master 200491 2009-12-14 00:19:31Z rwatson + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200725 2009-12-19 11:47:00Z 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 15f29882d62..dfa1f5c5509 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: stable/8/sys/compat/freebsd32/syscalls.master 200491 2009-12-14 00:19:31Z rwatson + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200725 2009-12-19 11:47:00Z kib */ #define FREEBSD32_SYS_syscall 0 @@ -386,4 +386,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 38eae92812e..c823c048a65 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: stable/8/sys/compat/freebsd32/syscalls.master 200491 2009-12-14 00:19:31Z rwatson + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200725 2009-12-19 11:47:00Z 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 079a58161cb..c82cec852fb 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: stable/8/sys/compat/freebsd32/syscalls.master 200491 2009-12-14 00:19:31Z rwatson + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200725 2009-12-19 11:47:00Z 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 */ }; diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 3db2956e887..1954dda7c82 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: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson + * created from FreeBSD: stable/8/sys/kern/syscalls.master 200725 2009-12-19 11:47:00Z 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 9be29fd79a1..57e2e1dc5e8 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: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson + * created from FreeBSD: stable/8/sys/kern/syscalls.master 200725 2009-12-19 11:47:00Z 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; }; diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 719093442e9..251399a0c12 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: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson + * created from FreeBSD: stable/8/sys/kern/syscalls.master 200725 2009-12-19 11:47:00Z 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 a50bd5667a8..c591d622b1f 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: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson +# created from FreeBSD: stable/8/sys/kern/syscalls.master 200725 2009-12-19 11:47:00Z 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 2744a7371ee..cde83c75536 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: stable/8/sys/kern/syscalls.master 200491 2009-12-14 00:19:31Z rwatson + * created from FreeBSD: stable/8/sys/kern/syscalls.master 200725 2009-12-19 11:47:00Z 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 fb70e2f700326a1e92d79970fdcb05ccd8ffa5b3 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 19 Dec 2009 12:06:12 +0000 Subject: [PATCH 0903/2592] MFC r199355: Add SI_KERNEL. MFC r199418: Fix pgsignal() call after signature change in r199355. --- sys/ddb/db_command.c | 2 +- sys/dev/syscons/scvidctl.c | 6 ++- sys/kern/kern_sig.c | 82 ++++++++++++++++++++++++-------------- sys/kern/tty.c | 16 +++++++- sys/sys/signal.h | 1 + sys/sys/signalvar.h | 8 ++-- 6 files changed, 79 insertions(+), 36 deletions(-) diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index 1e3401601d8..73de0c50240 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -652,7 +652,7 @@ db_kill(dummy1, dummy2, dummy3, dummy4) if (PROC_TRYLOCK(p) == 0) DB_ERROR(("Can't lock process with pid %ld\n", (long) pid)); else { - psignal(p, sig); + pksignal(p, sig, NULL); PROC_UNLOCK(p); } diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c index 045f79f25e7..d69e0a8fc36 100644 --- a/sys/dev/syscons/scvidctl.c +++ b/sys/dev/syscons/scvidctl.c @@ -321,6 +321,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, return ENODEV; #else video_info_t info; + ksiginfo_t ksi; u_char *font; int prev_ysize; int error; @@ -454,8 +455,11 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, tp->t_winsize.ws_col = scp->xsize; tp->t_winsize.ws_row = scp->ysize; if (tp->t_pgrp != NULL) { + ksiginfo_init(&ksi); + ksi.ksi_signo = SIGWINCH; + ksi.ksi_code = SI_KERNEL; PGRP_LOCK(tp->t_pgrp); - pgsignal(tp->t_pgrp, SIGWINCH, 1); + pgsignal(tp->t_pgrp, SIGWINCH, 1, &ksi); PGRP_UNLOCK(tp->t_pgrp); } } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 768270a5412..9c74bc6ca6a 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -99,7 +99,8 @@ SDT_PROBE_ARGTYPE(proc, kernel, , signal_discard, 2, "int"); static int coredump(struct thread *); static char *expand_name(const char *, uid_t, pid_t); -static int killpg1(struct thread *td, int sig, int pgid, int all); +static int killpg1(struct thread *td, int sig, int pgid, int all, + ksiginfo_t *ksi); static int issignal(struct thread *td, int stop_allowed); static int sigprop(int sig); static void tdsigwakeup(struct thread *, int, sig_t, int); @@ -377,7 +378,8 @@ sigqueue_add(sigqueue_t *sq, int signo, ksiginfo_t *si) ksi->ksi_sigq = sq; } - if ((si->ksi_flags & KSI_TRAP) != 0) { + if ((si->ksi_flags & KSI_TRAP) != 0 || + (si->ksi_flags & KSI_SIGQ) == 0) { if (ret != 0) SIGADDSET(sq->sq_kill, signo); ret = 0; @@ -1607,11 +1609,9 @@ kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss) * cp is calling process. */ static int -killpg1(td, sig, pgid, all) - register struct thread *td; - int sig, pgid, all; +killpg1(struct thread *td, int sig, int pgid, int all, ksiginfo_t *ksi) { - register struct proc *p; + struct proc *p; struct pgrp *pgrp; int nfound = 0; @@ -1630,7 +1630,7 @@ killpg1(td, sig, pgid, all) if (p_cansignal(td, p, sig) == 0) { nfound++; if (sig) - psignal(p, sig); + pksignal(p, sig, ksi); } PROC_UNLOCK(p); } @@ -1661,7 +1661,7 @@ killpg1(td, sig, pgid, all) if (p_cansignal(td, p, sig) == 0) { nfound++; if (sig) - psignal(p, sig); + pksignal(p, sig, ksi); } PROC_UNLOCK(p); } @@ -1678,11 +1678,10 @@ struct kill_args { #endif /* ARGSUSED */ int -kill(td, uap) - register struct thread *td; - register struct kill_args *uap; +kill(struct thread *td, struct kill_args *uap) { - register struct proc *p; + ksiginfo_t ksi; + struct proc *p; int error; AUDIT_ARG_SIGNUM(uap->signum); @@ -1690,6 +1689,12 @@ kill(td, uap) if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); + ksiginfo_init(&ksi); + ksi.ksi_signo = uap->signum; + ksi.ksi_code = SI_USER; + ksi.ksi_pid = td->td_proc->p_pid; + ksi.ksi_uid = td->td_ucred->cr_ruid; + if (uap->pid > 0) { /* kill single process */ if ((p = pfind(uap->pid)) == NULL) { @@ -1699,17 +1704,17 @@ kill(td, uap) AUDIT_ARG_PROCESS(p); error = p_cansignal(td, p, uap->signum); if (error == 0 && uap->signum) - psignal(p, uap->signum); + pksignal(p, uap->signum, &ksi); PROC_UNLOCK(p); return (error); } switch (uap->pid) { case -1: /* broadcast signal */ - return (killpg1(td, uap->signum, 0, 1)); + return (killpg1(td, uap->signum, 0, 1, &ksi)); case 0: /* signal own process group */ - return (killpg1(td, uap->signum, 0, 0)); + return (killpg1(td, uap->signum, 0, 0, &ksi)); default: /* negative explicit process group */ - return (killpg1(td, uap->signum, -uap->pid, 0)); + return (killpg1(td, uap->signum, -uap->pid, 0, &ksi)); } /* NOTREACHED */ } @@ -1723,17 +1728,21 @@ struct okillpg_args { #endif /* ARGSUSED */ int -okillpg(td, uap) - struct thread *td; - register struct okillpg_args *uap; +okillpg(struct thread *td, struct okillpg_args *uap) { + ksiginfo_t ksi; AUDIT_ARG_SIGNUM(uap->signum); AUDIT_ARG_PID(uap->pgid); if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); - return (killpg1(td, uap->signum, uap->pgid, 0)); + ksiginfo_init(&ksi); + ksi.ksi_signo = uap->signum; + ksi.ksi_code = SI_USER; + ksi.ksi_pid = td->td_proc->p_pid; + ksi.ksi_uid = td->td_ucred->cr_ruid; + return (killpg1(td, uap->signum, uap->pgid, 0, &ksi)); } #endif /* COMPAT_43 */ @@ -1768,6 +1777,7 @@ sigqueue(struct thread *td, struct sigqueue_args *uap) error = p_cansignal(td, p, uap->signum); if (error == 0 && uap->signum != 0) { ksiginfo_init(&ksi); + ksi.ksi_flags = KSI_SIGQ; ksi.ksi_signo = uap->signum; ksi.ksi_code = SI_QUEUE; ksi.ksi_pid = td->td_proc->p_pid; @@ -1783,8 +1793,7 @@ sigqueue(struct thread *td, struct sigqueue_args *uap) * Send a signal to a process group. */ void -gsignal(pgid, sig) - int pgid, sig; +gsignal(int pgid, int sig, ksiginfo_t *ksi) { struct pgrp *pgrp; @@ -1793,7 +1802,7 @@ gsignal(pgid, sig) pgrp = pgfind(pgid); sx_sunlock(&proctree_lock); if (pgrp != NULL) { - pgsignal(pgrp, sig, 0); + pgsignal(pgrp, sig, 0, ksi); PGRP_UNLOCK(pgrp); } } @@ -1804,18 +1813,16 @@ gsignal(pgid, sig) * limit to members which have a controlling terminal. */ void -pgsignal(pgrp, sig, checkctty) - struct pgrp *pgrp; - int sig, checkctty; +pgsignal(struct pgrp *pgrp, int sig, int checkctty, ksiginfo_t *ksi) { - register struct proc *p; + struct proc *p; if (pgrp) { PGRP_LOCK_ASSERT(pgrp, MA_OWNED); LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { PROC_LOCK(p); if (checkctty == 0 || p->p_flag & P_CONTROLT) - psignal(p, sig); + pksignal(p, sig, ksi); PROC_UNLOCK(p); } } @@ -1936,7 +1943,19 @@ sigtd(struct proc *p, int sig, int prop) void psignal(struct proc *p, int sig) { - (void) tdsignal(p, NULL, sig, NULL); + ksiginfo_t ksi; + + ksiginfo_init(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_code = SI_KERNEL; + (void) tdsignal(p, NULL, sig, &ksi); +} + +void +pksignal(struct proc *p, int sig, ksiginfo_t *ksi) +{ + + (void) tdsignal(p, NULL, sig, ksi); } int @@ -3138,8 +3157,13 @@ pgsigio(sigiop, sig, checkctty) struct sigio **sigiop; int sig, checkctty; { + ksiginfo_t ksi; struct sigio *sigio; + ksiginfo_init(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_code = SI_KERNEL; + SIGIO_LOCK(); sigio = *sigiop; if (sigio == NULL) { diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 9ad25fc3a04..34f8ddbdcb0 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -355,6 +355,7 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig) { struct proc *p = td->td_proc; struct pgrp *pg; + ksiginfo_t ksi; int error; MPASS(sig == SIGTTIN || sig == SIGTTOU); @@ -396,8 +397,14 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig) * Send the signal and sleep until we're the new * foreground process group. */ + if (sig != 0) { + ksiginfo_init(&ksi); + ksi.ksi_code = SI_KERNEL; + ksi.ksi_signo = sig; + sig = 0; + } PGRP_LOCK(pg); - pgsignal(pg, sig, 1); + pgsignal(pg, ksi.ksi_signo, 1, &ksi); PGRP_UNLOCK(pg); error = tty_wait(tp, &tp->t_bgwait); @@ -1223,6 +1230,8 @@ tty_signal_sessleader(struct tty *tp, int sig) void tty_signal_pgrp(struct tty *tp, int sig) { + ksiginfo_t ksi; + tty_lock_assert(tp, MA_OWNED); MPASS(sig >= 1 && sig < NSIG); @@ -1232,8 +1241,11 @@ tty_signal_pgrp(struct tty *tp, int sig) if (sig == SIGINFO && !(tp->t_termios.c_lflag & NOKERNINFO)) tty_info(tp); if (tp->t_pgrp != NULL) { + ksiginfo_init(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_code = SI_KERNEL; PGRP_LOCK(tp->t_pgrp); - pgsignal(tp->t_pgrp, sig, 1); + pgsignal(tp->t_pgrp, sig, 1, &ksi); PGRP_UNLOCK(tp->t_pgrp); } } diff --git a/sys/sys/signal.h b/sys/sys/signal.h index e90b107d170..81d45a9cc42 100644 --- a/sys/sys/signal.h +++ b/sys/sys/signal.h @@ -338,6 +338,7 @@ struct sigaction { /* an asynchronous I/O request.*/ #define SI_MESGQ 0x10005 /* Signal generated by arrival of a */ /* message on an empty message queue. */ +#define SI_KERNEL 0x10006 #endif #if __BSD_VISIBLE #define SI_UNDEFINED 0 diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 65d9cf53ef3..fd0fac3d3a4 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -233,7 +233,8 @@ typedef struct ksiginfo { #define KSI_TRAP 0x01 /* Generated by trap. */ #define KSI_EXT 0x02 /* Externally managed ksi. */ #define KSI_INS 0x04 /* Directly insert ksi, not the copy */ -#define KSI_COPYMASK KSI_TRAP +#define KSI_SIGQ 0x08 /* Generated by sigqueue, might ret EGAIN. */ +#define KSI_COPYMASK (KSI_TRAP|KSI_SIGQ) #define KSI_ONQ(ksi) ((ksi)->ksi_sigq != NULL) @@ -326,10 +327,11 @@ extern int kern_logsigexit; /* Sysctl variable kern.logsigexit */ */ int cursig(struct thread *td, int stop_allowed); void execsigs(struct proc *p); -void gsignal(int pgid, int sig); +void gsignal(int pgid, int sig, ksiginfo_t *ksi); void killproc(struct proc *p, char *why); +void pksignal(struct proc *p, int sig, ksiginfo_t *ksi); void pgsigio(struct sigio **, int signum, int checkctty); -void pgsignal(struct pgrp *pgrp, int sig, int checkctty); +void pgsignal(struct pgrp *pgrp, int sig, int checkctty, ksiginfo_t *ksi); int postsig(int sig); void psignal(struct proc *p, int sig); int psignal_event(struct proc *p, struct sigevent *, ksiginfo_t *); From 9a46c76970934889a8cd0c518975635b342e9b86 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Sat, 19 Dec 2009 19:22:09 +0000 Subject: [PATCH 0904/2592] MFC r199801: Fix a socket leak. Sponsored by: Sandvine Incorporated --- lib/libfetch/ftp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c index d0d597f0f9e..a0ba5108d82 100644 --- a/lib/libfetch/ftp.c +++ b/lib/libfetch/ftp.c @@ -1122,17 +1122,19 @@ ftp_request(struct url *url, const char *op, struct url_stat *us, /* change directory */ if (ftp_cwd(conn, url->doc) == -1) - return (NULL); + goto errsock; /* stat file */ if (us && ftp_stat(conn, url->doc, us) == -1 && fetchLastErrCode != FETCH_PROTO && fetchLastErrCode != FETCH_UNAVAIL) - return (NULL); + goto errsock; /* just a stat */ - if (strcmp(op, "STAT") == 0) + if (strcmp(op, "STAT") == 0) { + ftp_disconnect(conn); return (FILE *)1; /* bogus return value */ + } if (strcmp(op, "STOR") == 0 || strcmp(op, "APPE") == 0) oflag = O_WRONLY; else @@ -1140,6 +1142,10 @@ ftp_request(struct url *url, const char *op, struct url_stat *us, /* initiate the transfer */ return (ftp_transfer(conn, op, url->doc, oflag, url->offset, flags)); + +errsock: + ftp_disconnect(conn); + return (NULL); } /* From 9853fc7d633cae77502b3ad2ca246665e9963d1d Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Sat, 19 Dec 2009 19:23:25 +0000 Subject: [PATCH 0905/2592] MFC r199802: Fix handling of empty attributes. Sponsored by: Sandvine Incorporated --- lib/libtacplus/taclib.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/libtacplus/taclib.c b/lib/libtacplus/taclib.c index 6ac3c72501c..a44e83476e8 100644 --- a/lib/libtacplus/taclib.c +++ b/lib/libtacplus/taclib.c @@ -1263,8 +1263,13 @@ tac_get_av_value(struct tac_handle *h, const char *attribute) * h->srvr_avs[0] = "foobie=var1" * h->srvr_avs[1] = "foo=var2" * is handled. + * + * Note that for empty string attribute values a + * 0-length string is returned in order to distinguish + * against unset values. + * dump_str() will handle srvr.len == 0 correctly. */ - if (found_seperator == 1 && ch != end) { + if (found_seperator == 1) { srvr.len = end - ch; srvr.data = ch; return dup_str(h, &srvr, NULL); From 2df3481531765ccec9ef214cebf334932f9f1100 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Sat, 19 Dec 2009 19:25:35 +0000 Subject: [PATCH 0906/2592] MFC r199803: Add the possibility to show informations about dropped packets on the input path when showing interfaces informations. Sponsored by: Sandvine Incorporated --- usr.bin/netstat/if.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c index aa28a6fa265..e9e77b9a9d8 100644 --- a/usr.bin/netstat/if.c +++ b/usr.bin/netstat/if.c @@ -198,6 +198,7 @@ intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) u_long imcasts; u_long oerrors; u_long ierrors; + u_long idrops; u_long collisions; short timer; int drops; @@ -225,8 +226,8 @@ intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) printf("%-7.7s", "Name"); else printf("%-5.5s", "Name"); - printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s", - "Mtu", "Network", "Address", "Ipkts", "Ierrs"); + printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s", + "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop"); if (bflag) printf(" %10.10s","Ibytes"); printf(" %8.8s %5.5s", "Opkts", "Oerrs"); @@ -285,6 +286,7 @@ intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) imcasts = ifnet.if_imcasts; oerrors = ifnet.if_oerrors; ierrors = ifnet.if_ierrors; + idrops = ifnet.if_iqdrops; collisions = ifnet.if_collisions; timer = ifnet.if_timer; drops = ifnet.if_snd.ifq_drops; @@ -423,6 +425,7 @@ intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) show_stat("lu", 8, ipackets, link_layer|network_layer); show_stat("lu", 5, ierrors, link_layer); + show_stat("lu", 5, idrops, link_layer); if (bflag) show_stat("lu", 10, ibytes, link_layer|network_layer); @@ -513,6 +516,7 @@ struct iftot { char ift_name[IFNAMSIZ]; /* interface name */ u_long ift_ip; /* input packets */ u_long ift_ie; /* input errors */ + u_long ift_id; /* input drops */ u_long ift_op; /* output packets */ u_long ift_oe; /* output errors */ u_long ift_co; /* collisions */ @@ -598,8 +602,9 @@ banner: printf("%17s %14s %16s", "input", interesting ? interesting->ift_name : "(Total)", "output"); putchar('\n'); - printf("%10s %5s %10s %10s %5s %10s %5s", - "packets", "errs", "bytes", "packets", "errs", "bytes", "colls"); + printf("%10s %5s %5s %10s %10s %5s %10s %5s", + "packets", "errs", "idrops", "bytes", "packets", "errs", "bytes", + "colls"); if (dflag) printf(" %5.5s", "drops"); putchar('\n'); @@ -615,6 +620,7 @@ loop: if (!first) { show_stat("lu", 10, ifnet.if_ipackets - ip->ift_ip, 1); show_stat("lu", 5, ifnet.if_ierrors - ip->ift_ie, 1); + show_stat("lu", 5, ifnet.if_iqdrops - ip->ift_id, 1); show_stat("lu", 10, ifnet.if_ibytes - ip->ift_ib, 1); show_stat("lu", 10, ifnet.if_opackets - ip->ift_op, 1); show_stat("lu", 5, ifnet.if_oerrors - ip->ift_oe, 1); @@ -636,6 +642,7 @@ loop: } else { sum->ift_ip = 0; sum->ift_ie = 0; + sum->ift_id = 0; sum->ift_ib = 0; sum->ift_op = 0; sum->ift_oe = 0; @@ -651,6 +658,7 @@ loop: } sum->ift_ip += ifnet.if_ipackets; sum->ift_ie += ifnet.if_ierrors; + sum->ift_id += ifnet.if_iqdrops; sum->ift_ib += ifnet.if_ibytes; sum->ift_op += ifnet.if_opackets; sum->ift_oe += ifnet.if_oerrors; @@ -662,6 +670,7 @@ loop: if (!first) { show_stat("lu", 10, sum->ift_ip - total->ift_ip, 1); show_stat("lu", 5, sum->ift_ie - total->ift_ie, 1); + show_stat("lu", 5, sum->ift_id - total->ift_id, 1); show_stat("lu", 10, sum->ift_ib - total->ift_ib, 1); show_stat("lu", 10, sum->ift_op - total->ift_op, 1); show_stat("lu", 5, sum->ift_oe - total->ift_oe, 1); From ebc5dece54faced5f8546348e2ef8a1f7cfe86f9 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Sat, 19 Dec 2009 19:30:27 +0000 Subject: [PATCH 0907/2592] MFC r199805: Change gcore in order to get rid of the procfs support and use FreeBSD's specific interfaces. Main changes: - now gcore recognizes threads within the the process and handle dumps on a thread scope - the process to be analyzed should be stopped while gcore runs - gcore may not work with processes that are being debugged with gdb or truss - ptrace may let interruptible calls to return EINTR, thus dirtying signals handling within the process Sponsored by: Sandvine Incorporated --- usr.bin/gcore/Makefile | 1 + usr.bin/gcore/elfcore.c | 337 +++++++++++++++++++--------------------- usr.bin/gcore/gcore.1 | 22 ++- usr.bin/gcore/gcore.c | 17 +- 4 files changed, 182 insertions(+), 195 deletions(-) diff --git a/usr.bin/gcore/Makefile b/usr.bin/gcore/Makefile index 5ab51cf5c7e..199d195baf2 100644 --- a/usr.bin/gcore/Makefile +++ b/usr.bin/gcore/Makefile @@ -1,6 +1,7 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +LDADD+= -lutil PROG= gcore SRCS= elfcore.c gcore.c diff --git a/usr.bin/gcore/elfcore.c b/usr.bin/gcore/elfcore.c index 6c90708f2cd..73d92b45577 100644 --- a/usr.bin/gcore/elfcore.c +++ b/usr.bin/gcore/elfcore.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2007 Sandvine Incorporated * Copyright (c) 1998 John D. Polstra * All rights reserved. * @@ -29,8 +30,12 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include +#include +#include +#include #include #include #include @@ -44,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "extern.h" @@ -69,16 +75,15 @@ static void cb_put_phdr(vm_map_entry_t, void *); static void cb_size_segment(vm_map_entry_t, void *); static void each_writable_segment(vm_map_entry_t, segment_callback, void *closure); -static void elf_corehdr(int fd, pid_t, vm_map_entry_t, int numsegs, - void *hdr, size_t hdrsize); -static void elf_puthdr(vm_map_entry_t, void *, size_t *, - const prstatus_t *, const prfpregset_t *, const prpsinfo_t *, int numsegs); +static void elf_detach(void); /* atexit() handler. */ +static void elf_puthdr(pid_t, vm_map_entry_t, void *, size_t *, int numsegs); static void elf_putnote(void *dst, size_t *off, const char *name, int type, const void *desc, size_t descsz); static void freemap(vm_map_entry_t); -static void readhdrinfo(pid_t, prstatus_t *, prfpregset_t *, prpsinfo_t *); static vm_map_entry_t readmap(pid_t); +static pid_t g_pid; /* Pid being dumped, global for elf_detach */ + static int elf_ident(int efd, pid_t pid __unused, char *binfile __unused) { @@ -93,6 +98,14 @@ elf_ident(int efd, pid_t pid __unused, char *binfile __unused) return (0); } +static void +elf_detach(void) +{ + + if (g_pid != 0) + ptrace(PT_DETACH, g_pid, (caddr_t)1, 0); +} + /* * Write an ELF coredump for the given pid to the given fd. */ @@ -103,11 +116,20 @@ elf_coredump(int efd __unused, int fd, pid_t pid) struct sseg_closure seginfo; void *hdr; size_t hdrsize; - char memname[64]; - int memfd; Elf_Phdr *php; int i; + /* Attach to process to dump. */ + g_pid = pid; + if (atexit(elf_detach) != 0) + err(1, "atexit"); + errno = 0; + ptrace(PT_ATTACH, pid, NULL, 0); + if (errno) + err(1, "PT_ATTACH"); + if (waitpid(pid, NULL, 0) == -1) + err(1, "waitpid"); + /* Get the program's memory map. */ map = readmap(pid); @@ -122,28 +144,31 @@ elf_coredump(int efd __unused, int fd, pid_t pid) * size is calculated. */ hdrsize = 0; - elf_puthdr(map, (void *)NULL, &hdrsize, - (const prstatus_t *)NULL, (const prfpregset_t *)NULL, - (const prpsinfo_t *)NULL, seginfo.count); + elf_puthdr(pid, map, NULL, &hdrsize, seginfo.count); /* * Allocate memory for building the header, fill it up, * and write it out. */ - if ((hdr = malloc(hdrsize)) == NULL) + if ((hdr = calloc(1, hdrsize)) == NULL) errx(1, "out of memory"); - elf_corehdr(fd, pid, map, seginfo.count, hdr, hdrsize); + + /* Fill in the header. */ + hdrsize = 0; + elf_puthdr(pid, map, hdr, &hdrsize, seginfo.count); + + /* Write it to the core file. */ + if (write(fd, hdr, hdrsize) == -1) + err(1, "write"); /* Write the contents of all of the writable segments. */ - snprintf(memname, sizeof memname, "/proc/%d/mem", pid); - if ((memfd = open(memname, O_RDONLY)) == -1) - err(1, "cannot open %s", memname); - php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1; for (i = 0; i < seginfo.count; i++) { + struct ptrace_io_desc iorequest; uintmax_t nleft = php->p_filesz; - lseek(memfd, (off_t)php->p_vaddr, SEEK_SET); + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (caddr_t)php->p_vaddr; while (nleft > 0) { char buf[8*1024]; size_t nwant; @@ -153,12 +178,12 @@ elf_coredump(int efd __unused, int fd, pid_t pid) nwant = sizeof buf; else nwant = nleft; - ngot = read(memfd, buf, nwant); - if (ngot == -1) - err(1, "read from %s", memname); + iorequest.piod_addr = buf; + iorequest.piod_len = nwant; + ptrace(PT_IO, pid, (caddr_t)&iorequest, 0); + ngot = iorequest.piod_len; if ((size_t)ngot < nwant) - errx(1, "short read from %s:" - " wanted %zu, got %zd", memname, + errx(1, "short read wanted %d, got %d", nwant, ngot); ngot = write(fd, buf, nwant); if (ngot == -1) @@ -166,10 +191,10 @@ elf_coredump(int efd __unused, int fd, pid_t pid) if ((size_t)ngot != nwant) errx(1, "short write"); nleft -= nwant; + iorequest.piod_offs += ngot; } php++; } - close(memfd); free(hdr); freemap(map); } @@ -231,30 +256,25 @@ each_writable_segment(vm_map_entry_t map, segment_callback func, void *closure) (*func)(entry, closure); } -/* - * Write the core file header to the file, including padding up to - * the page boundary. - */ static void -elf_corehdr(int fd, pid_t pid, vm_map_entry_t map, int numsegs, void *hdr, - size_t hdrsize) +elf_getstatus(pid_t pid, prpsinfo_t *psinfo) { - size_t off; - prstatus_t status; - prfpregset_t fpregset; - prpsinfo_t psinfo; + struct kinfo_proc kobj; + int name[4]; + size_t len; - /* Gather the information for the header. */ - readhdrinfo(pid, &status, &fpregset, &psinfo); + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PID; + name[3] = pid; - /* Fill in the header. */ - memset(hdr, 0, hdrsize); - off = 0; - elf_puthdr(map, hdr, &off, &status, &fpregset, &psinfo, numsegs); - - /* Write it to the core file. */ - if (write(fd, hdr, hdrsize) == -1) - err(1, "write"); + len = sizeof(kobj); + if (sysctl(name, 4, &kobj, &len, NULL, 0) == -1) + err(1, "error accessing kern.proc.pid.%u sysctl", pid); + if (kobj.ki_pid != pid) + err(1, "error accessing kern.proc.pid.%u sysctl datas", pid); + strncpy(psinfo->pr_fname, kobj.ki_comm, MAXCOMLEN); + strncpy(psinfo->pr_psargs, psinfo->pr_fname, PRARGSZ); } /* @@ -262,13 +282,24 @@ elf_corehdr(int fd, pid_t pid, vm_map_entry_t map, int numsegs, void *hdr, * be NULL, in which case the header is sized but not actually generated. */ static void -elf_puthdr(vm_map_entry_t map, void *dst, size_t *off, const prstatus_t *status, - const prfpregset_t *fpregset, const prpsinfo_t *psinfo, int numsegs) +elf_puthdr(pid_t pid, vm_map_entry_t map, void *dst, size_t *off, int numsegs) { + struct { + prstatus_t status; + prfpregset_t fpregset; + prpsinfo_t psinfo; + } *tempdata; size_t ehoff; size_t phoff; size_t noteoff; size_t notesz; + size_t threads; + lwpid_t *tids; + int i; + + prstatus_t *status; + prfpregset_t *fpregset; + prpsinfo_t *psinfo; ehoff = *off; *off += sizeof(Elf_Ehdr); @@ -277,14 +308,68 @@ elf_puthdr(vm_map_entry_t map, void *dst, size_t *off, const prstatus_t *status, *off += (numsegs + 1) * sizeof(Elf_Phdr); noteoff = *off; - elf_putnote(dst, off, "FreeBSD", NT_PRSTATUS, status, - sizeof *status); - elf_putnote(dst, off, "FreeBSD", NT_FPREGSET, fpregset, - sizeof *fpregset); + + if (dst != NULL) { + if ((tempdata = calloc(1, sizeof(*tempdata))) == NULL) + errx(1, "out of memory"); + status = &tempdata->status; + fpregset = &tempdata->fpregset; + psinfo = &tempdata->psinfo; + } else { + tempdata = NULL; + status = NULL; + fpregset = NULL; + psinfo = NULL; + } + + errno = 0; + threads = ptrace(PT_GETNUMLWPS, pid, NULL, 0); + if (errno) + err(1, "PT_GETNUMLWPS"); + + if (dst != NULL) { + psinfo->pr_version = PRPSINFO_VERSION; + psinfo->pr_psinfosz = sizeof(prpsinfo_t); + elf_getstatus(pid, psinfo); + + } elf_putnote(dst, off, "FreeBSD", NT_PRPSINFO, psinfo, sizeof *psinfo); + + if (dst != NULL) { + tids = malloc(threads * sizeof(*tids)); + if (tids == NULL) + errx(1, "out of memory"); + errno = 0; + ptrace(PT_GETLWPLIST, pid, (void *)tids, threads); + if (errno) + err(1, "PT_GETLWPLIST"); + } + for (i = 0; i < threads; ++i) { + if (dst != NULL) { + status->pr_version = PRSTATUS_VERSION; + status->pr_statussz = sizeof(prstatus_t); + status->pr_gregsetsz = sizeof(gregset_t); + status->pr_fpregsetsz = sizeof(fpregset_t); + status->pr_osreldate = __FreeBSD_version; + status->pr_pid = tids[i]; + + ptrace(PT_GETREGS, tids[i], (void *)&status->pr_reg, 0); + ptrace(PT_GETFPREGS, tids[i], (void *)fpregset, 0); + } + elf_putnote(dst, off, "FreeBSD", NT_PRSTATUS, status, + sizeof *status); + elf_putnote(dst, off, "FreeBSD", NT_FPREGSET, fpregset, + sizeof *fpregset); + } + notesz = *off - noteoff; + if (dst != NULL) { + free(tids); + free(tempdata); + } + /* Align up to a page boundary for the program segments. */ *off = round_page(*off); @@ -381,70 +466,7 @@ freemap(vm_map_entry_t map) } /* - * Read the process information necessary to fill in the core file's header. - */ -static void -readhdrinfo(pid_t pid, prstatus_t *status, prfpregset_t *fpregset, - prpsinfo_t *psinfo) -{ - char name[64]; - char line[256]; - int fd; - int i; - int n; - - memset(status, 0, sizeof *status); - status->pr_version = PRSTATUS_VERSION; - status->pr_statussz = sizeof(prstatus_t); - status->pr_gregsetsz = sizeof(gregset_t); - status->pr_fpregsetsz = sizeof(fpregset_t); - status->pr_osreldate = __FreeBSD_version; - status->pr_pid = pid; - - memset(fpregset, 0, sizeof *fpregset); - - memset(psinfo, 0, sizeof *psinfo); - psinfo->pr_version = PRPSINFO_VERSION; - psinfo->pr_psinfosz = sizeof(prpsinfo_t); - - /* Read the general registers. */ - snprintf(name, sizeof name, "/proc/%d/regs", pid); - if ((fd = open(name, O_RDONLY)) == -1) - err(1, "cannot open %s", name); - if ((n = read(fd, &status->pr_reg, sizeof status->pr_reg)) == -1) - err(1, "read error from %s", name); - if ((size_t)n < sizeof(status->pr_reg)) - errx(1, "short read from %s: wanted %zu, got %d", name, - sizeof status->pr_reg, n); - close(fd); - - /* Read the floating point registers. */ - snprintf(name, sizeof name, "/proc/%d/fpregs", pid); - if ((fd = open(name, O_RDONLY)) == -1) - err(1, "cannot open %s", name); - if ((n = read(fd, fpregset, sizeof *fpregset)) == -1) - err(1, "read error from %s", name); - if ((size_t)n < sizeof(*fpregset)) - errx(1, "short read from %s: wanted %zu, got %d", name, - sizeof *fpregset, n); - close(fd); - - /* Read and parse the process status. */ - snprintf(name, sizeof name, "/proc/%d/status", pid); - if ((fd = open(name, O_RDONLY)) == -1) - err(1, "cannot open %s", name); - if ((n = read(fd, line, sizeof line - 1)) == -1) - err(1, "read error from %s", name); - if (n > MAXCOMLEN) - n = MAXCOMLEN; - for (i = 0; i < n && line[i] != ' '; i++) - psinfo->pr_fname[i] = line[i]; - strncpy(psinfo->pr_psargs, psinfo->pr_fname, PRARGSZ); - close(fd); -} - -/* - * Read the process's memory map using procfs, and return a list of + * Read the process's memory map using kinfo_getvmmap(), and return a list of * VM map entries. Only the non-device read/writable segments are * returned. The map entries in the list aren't fully filled in; only * the items we need are present. @@ -452,83 +474,44 @@ readhdrinfo(pid_t pid, prstatus_t *status, prfpregset_t *fpregset, static vm_map_entry_t readmap(pid_t pid) { - char mapname[64]; - int mapfd; - ssize_t mapsize; - size_t bufsize; - char *mapbuf; - int pos; - vm_map_entry_t map; - vm_map_entry_t *linkp; + vm_map_entry_t ent, *linkp, map; + struct kinfo_vmentry *vmentl, *kve; + int i, nitems; - snprintf(mapname, sizeof mapname, "/proc/%d/map", pid); - if ((mapfd = open(mapname, O_RDONLY)) == -1) - err(1, "cannot open %s", mapname); + vmentl = kinfo_getvmmap(pid, &nitems); + if (vmentl == NULL) + err(1, "cannot retrieve mappings for %u process", pid); - /* - * Procfs requires (for consistency) that the entire memory map - * be read with a single read() call. Start with a reasonably sized - * buffer, and double it until it is big enough. - */ - bufsize = 8 * 1024; - mapbuf = NULL; - for ( ; ; ) { - if ((mapbuf = realloc(mapbuf, bufsize + 1)) == NULL) - errx(1, "out of memory"); - mapsize = read(mapfd, mapbuf, bufsize); - if (mapsize != -1 || errno != EFBIG) - break; - bufsize *= 2; - /* This lseek shouldn't be necessary, but it is. */ - lseek(mapfd, (off_t)0, SEEK_SET); - } - if (mapsize == -1) - err(1, "read error from %s", mapname); - if (mapsize == 0) - errx(1, "empty map file %s", mapname); - mapbuf[mapsize] = 0; - close(mapfd); - - pos = 0; map = NULL; linkp = ↦ - while (pos < mapsize) { - vm_map_entry_t ent; - u_long start; - u_long end; - char prot[4]; - char type[16]; - int n; - int len; + for (i = 0; i < nitems; i++) { + kve = &vmentl[i]; - len = 0; - n = sscanf(mapbuf + pos, "%lx %lx %*d %*d %*x %3[-rwx]" - " %*d %*d %*x %*s %*s %16s %*s%*[\n]%n", - &start, &end, prot, type, &len); - if (n != 4 || len == 0) - errx(1, "ill-formed line in %s starting at character %d", mapname, pos + 1); - pos += len; - - /* Ignore segments of the wrong kind, and unwritable ones */ - if (strncmp(prot, "rw", 2) != 0 || - (strcmp(type, "default") != 0 && - strcmp(type, "vnode") != 0 && - strcmp(type, "swap") != 0)) + /* + * Ignore segments of the wrong kind and ones which are not + * readable and writable. + */ + if ((kve->kve_protection & KVME_PROT_WRITE) == 0 || + (kve->kve_protection & KVME_PROT_READ) == 0 || + (kve->kve_type != KVME_TYPE_DEFAULT && + kve->kve_type != KVME_TYPE_VNODE && + kve->kve_type != KVME_TYPE_SWAP)) continue; - if ((ent = (vm_map_entry_t)calloc(1, sizeof *ent)) == NULL) + ent = calloc(1, sizeof(*ent)); + if (ent == NULL) errx(1, "out of memory"); - ent->start = start; - ent->end = end; + ent->start = (vm_offset_t)kve->kve_start; + ent->end = (vm_offset_t)kve->kve_end; ent->protection = VM_PROT_READ | VM_PROT_WRITE; - if (prot[2] == 'x') - ent->protection |= VM_PROT_EXECUTE; + if ((kve->kve_protection & KVME_PROT_EXEC) != 0) + ent->protection |= VM_PROT_EXECUTE; *linkp = ent; linkp = &ent->next; } - free(mapbuf); - return map; + free(vmentl); + return (map); } struct dumpers elfdump = { elf_ident, elf_coredump }; diff --git a/usr.bin/gcore/gcore.1 b/usr.bin/gcore/gcore.1 index 981e0be3b34..a5be26a3f4d 100644 --- a/usr.bin/gcore/gcore.1 +++ b/usr.bin/gcore/gcore.1 @@ -32,7 +32,7 @@ .\" @(#)gcore.1 8.2 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd April 18, 1994 +.Dd November 18, 2009 .Dt GCORE 1 .Os .Sh NAME @@ -55,11 +55,6 @@ By default, the core is written to the file The process identifier, .Ar pid , must be given on the command line. -If no executable image is -specified, -.Nm -will use -.Dq Pa /proc//file . .Pp The following options are available: .Bl -tag -width indent @@ -80,8 +75,6 @@ The same effect can be achieved manually with .Bl -tag -width /var/log/messages -compact .It Pa core. the core image -.It Pa /proc//file -the executable image .El .Sh HISTORY A @@ -89,12 +82,15 @@ A utility appeared in .Bx 4.2 . .Sh BUGS -Context switches or paging activity that occur while +Because of the +.Xr ptrace 2 +usage .Nm -is running may cause the program to become confused. -For best results, use -.Fl s -to temporarily stop the target process. +may not work with processes which are actively investigated with +.Xr truss 1 +or +.Xr gdb 1 . +Additionally, interruptable sleeps may exit with EINTR. .Pp The .Nm diff --git a/usr.bin/gcore/gcore.c b/usr.bin/gcore/gcore.c index 7005e834ff9..35d5363f143 100644 --- a/usr.bin/gcore/gcore.c +++ b/usr.bin/gcore/gcore.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -83,10 +84,11 @@ SET_DECLARE(dumpset, struct dumpers); int main(int argc, char *argv[]) { - int ch, efd, fd, sflag; + int ch, efd, fd, name[4], sflag; char *binfile, *corefile; - char fname[MAXPATHLEN]; + char passpath[MAXPATHLEN], fname[MAXPATHLEN]; struct dumpers **d, *dumper; + size_t len; sflag = 0; corefile = NULL; @@ -109,9 +111,14 @@ main(int argc, char *argv[]) switch (argc) { case 1: pid = atoi(argv[0]); - asprintf(&binfile, "/proc/%d/file", pid); - if (binfile == NULL) - errx(1, "allocation failure"); + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PATHNAME; + name[3] = pid; + len = sizeof(passpath); + if (sysctl(name, 4, passpath, &len, NULL, 0) == -1) + errx(1, "kern.proc.pathname failure"); + binfile = passpath; break; case 2: pid = atoi(argv[1]); From acd3c01512155cf09c7cad3d9527d3e5fa9a11a6 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Sat, 19 Dec 2009 19:35:53 +0000 Subject: [PATCH 0908/2592] MFC r199804: Avoid sshd, crond, inetd and syslogd to be killed in an high-pressure swapping environment. Sponsored by: Sandvine Incorporated --- crypto/openssh/sshd.c | 5 +++++ usr.sbin/cron/cron/cron.c | 4 ++++ usr.sbin/inetd/inetd.c | 4 ++++ usr.sbin/syslogd/syslogd.c | 4 ++++ 4 files changed, 17 insertions(+) diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 75ab86ccf12..1d44fc8d9b9 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -47,6 +47,7 @@ __RCSID("$FreeBSD$"); #include #include +#include #include #ifdef HAVE_SYS_STAT_H # include @@ -1292,6 +1293,10 @@ main(int ac, char **av) /* Initialize configuration options to their default values. */ initialize_server_options(&options); + /* Avoid killing the process in high-pressure swapping environments. */ + if (madvise(NULL, 0, MADV_PROTECT) != 0) + debug("madvise(): %.200s", strerror(errno)); + /* Parse command-line arguments. */ while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) { switch (opt) { diff --git a/usr.sbin/cron/cron/cron.c b/usr.sbin/cron/cron/cron.c index 101989c45d2..52cdcc8612a 100644 --- a/usr.sbin/cron/cron/cron.c +++ b/usr.sbin/cron/cron/cron.c @@ -24,6 +24,7 @@ static const char rcsid[] = #include "cron.h" +#include #include #if SYS_TIME_H # include @@ -134,6 +135,9 @@ main(argc, argv) } } + if (madvise(NULL, 0, MADV_PROTECT) != 0) + log_it("CRON", getpid(), "WARNING", "madvise() failed"); + pidfile_write(pfh); database.head = NULL; database.tail = NULL; diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c index 6bcbac61bad..e8d34f46283 100644 --- a/usr.sbin/inetd/inetd.c +++ b/usr.sbin/inetd/inetd.c @@ -110,6 +110,7 @@ __FBSDID("$FreeBSD$"); */ #include #include +#include #include #include #include @@ -497,6 +498,9 @@ main(int argc, char **argv) } } + if (madvise(NULL, 0, MADV_PROTECT) != 0) + syslog(LOG_WARNING, "madvise() failed: %s", strerror(errno)); + for (i = 0; i < PERIPSIZE; ++i) LIST_INIT(&proctable[i]); diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index 3e628a24ed2..5cb0af9186c 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -352,6 +353,9 @@ main(int argc, char *argv[]) pid_t ppid = 1, spid; socklen_t len; + if (madvise(NULL, 0, MADV_PROTECT) != 0) + dprintf("madvise() failed: %s\n", strerror(errno)); + bindhostname = NULL; while ((ch = getopt(argc, argv, "468Aa:b:cCdf:kl:m:nop:P:sS:Tuv")) != -1) From fd7408ec16eae93b729b38b8c65bf3e8f3a2920e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 19 Dec 2009 20:50:48 +0000 Subject: [PATCH 0909/2592] MFC r198538: Move pselect(3) man page to section 2. --- ObsoleteFiles.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index a08f72944d7..6a1d0cf1248 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -16,6 +16,8 @@ # 20091218: removal of rc.early(8) link OLD_FILES+=usr/share/man/man8/rc.early.8.gz +# 20091027: pselect.3 implemented as syscall +OLD_FILES+=usr/share/man/man3/pselect.3.gz # 20090904: remove lukemftpd OLD_FILES+=usr/libexec/lukemftpd OLD_FILES+=usr/share/man/man5/ftpd.conf.5.gz From 3759df8ec67b85fb3ac5d3df8fef992dc9b4bfa3 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sun, 20 Dec 2009 01:38:01 +0000 Subject: [PATCH 0910/2592] MFC: r200481 Specify the capability and media bits of the capabilities page in native, i.e. big-endian, format and convert as appropriate like we also do with the multibyte fields of the other pages. This fixes the output of acd_describe() to match reality on big-endian machines without breaking it on little-endian ones. While at it, also convert the remaining multibyte fields of the pages read although they are currently unused for consistency and in order to prevent possible similar bugs in the future. --- sys/dev/ata/atapi-cd.c | 10 ++++++-- sys/dev/ata/atapi-cd.h | 52 +++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 5d0c0f70476..7e470ea26f6 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -1206,6 +1206,7 @@ acd_read_track_info(device_t dev, int32_t lba, struct acd_track_info *info) if ((error = ata_atapicmd(dev, ccb, (caddr_t)info, sizeof(*info), ATA_R_READ, 30))) return error; + info->data_length = ntohs(info->data_length); info->track_start_addr = ntohl(info->track_start_addr); info->next_writeable_addr = ntohl(info->next_writeable_addr); info->free_blocks = ntohl(info->free_blocks); @@ -1644,12 +1645,17 @@ acd_get_cap(device_t dev) for (count = 0 ; count < 5 ; count++) { if (!ata_atapicmd(dev, ccb, (caddr_t)&cdp->cap, sizeof(cdp->cap), ATA_R_READ | ATA_R_QUIET, 5)) { + cdp->cap.data_length = ntohs(cdp->cap.data_length); + cdp->cap.blk_desc_len = ntohs(cdp->cap.blk_desc_len); + cdp->cap.media = ntohs(cdp->cap.media); + cdp->cap.capabilities = ntohs(cdp->cap.capabilities); cdp->cap.max_read_speed = ntohs(cdp->cap.max_read_speed); + cdp->cap.max_vol_levels = ntohs(cdp->cap.max_vol_levels); + cdp->cap.buf_size = ntohs(cdp->cap.buf_size); cdp->cap.cur_read_speed = ntohs(cdp->cap.cur_read_speed); cdp->cap.max_write_speed = ntohs(cdp->cap.max_write_speed); cdp->cap.cur_write_speed = max(ntohs(cdp->cap.cur_write_speed),177); - cdp->cap.max_vol_levels = ntohs(cdp->cap.max_vol_levels); - cdp->cap.buf_size = ntohs(cdp->cap.buf_size); + cdp->cap.copy_protect_rev = ntohs(cdp->cap.copy_protect_rev); } } } diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h index d78771a29aa..74ce82e4f13 100644 --- a/sys/dev/ata/atapi-cd.h +++ b/sys/dev/ata/atapi-cd.h @@ -112,34 +112,34 @@ struct cappage { u_int8_t param_len; u_int16_t media; -#define MST_READ_CDR 0x0001 -#define MST_READ_CDRW 0x0002 -#define MST_READ_PACKET 0x0004 -#define MST_READ_DVDROM 0x0008 -#define MST_READ_DVDR 0x0010 -#define MST_READ_DVDRAM 0x0020 -#define MST_WRITE_CDR 0x0100 -#define MST_WRITE_CDRW 0x0200 -#define MST_WRITE_TEST 0x0400 -#define MST_WRITE_DVDR 0x1000 -#define MST_WRITE_DVDRAM 0x2000 +#define MST_READ_CDR 0x0100 +#define MST_READ_CDRW 0x0200 +#define MST_READ_PACKET 0x0400 +#define MST_READ_DVDROM 0x0800 +#define MST_READ_DVDR 0x1000 +#define MST_READ_DVDRAM 0x2000 +#define MST_WRITE_CDR 0x0001 +#define MST_WRITE_CDRW 0x0002 +#define MST_WRITE_TEST 0x0004 +#define MST_WRITE_DVDR 0x0010 +#define MST_WRITE_DVDRAM 0x0020 u_int16_t capabilities; -#define MST_AUDIO_PLAY 0x0001 -#define MST_COMPOSITE 0x0002 -#define MST_AUDIO_P1 0x0004 -#define MST_AUDIO_P2 0x0008 -#define MST_MODE2_f1 0x0010 -#define MST_MODE2_f2 0x0020 -#define MST_MULTISESSION 0x0040 -#define MST_BURNPROOF 0x0080 -#define MST_READ_CDDA 0x0100 -#define MST_CDDA_STREAM 0x0200 -#define MST_COMBINED_RW 0x0400 -#define MST_CORRECTED_RW 0x0800 -#define MST_SUPPORT_C2 0x1000 -#define MST_ISRC 0x2000 -#define MST_UPC 0x4000 +#define MST_AUDIO_PLAY 0x0100 +#define MST_COMPOSITE 0x0200 +#define MST_AUDIO_P1 0x0400 +#define MST_AUDIO_P2 0x0800 +#define MST_MODE2_f1 0x1000 +#define MST_MODE2_f2 0x2000 +#define MST_MULTISESSION 0x4000 +#define MST_BURNPROOF 0x8000 +#define MST_READ_CDDA 0x0001 +#define MST_CDDA_STREAM 0x0002 +#define MST_COMBINED_RW 0x0004 +#define MST_CORRECTED_RW 0x0008 +#define MST_SUPPORT_C2 0x0010 +#define MST_ISRC 0x0020 +#define MST_UPC 0x0040 u_int8_t mechanism; #define MST_LOCKABLE 0x01 From b4aa1acbfb69123e8a2b73ddd5fa5190243c501b Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sun, 20 Dec 2009 01:44:47 +0000 Subject: [PATCH 0911/2592] MFC: r200482, r200485 o Properly support M5229 revision 0xc7 and 0xc8: - These revisions no longer have cable detection capability. - The UDMA support bit of register 0x4b has been dropped without an replacement. - According to Linux it's crucial for working ATAPI DMA support to also set the reserved bit 1 of regsiter 0x53 with these revisions. o Only set ATA_CHECKS_CABLE for chip versions that actually support cable detection, i.e. neither for ALI_OLD nor for ALI_NEW revisions >= 0xc7. --- sys/dev/ata/chipsets/ata-acerlabs.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c index e74b2105f41..b5036d77cd4 100644 --- a/sys/dev/ata/chipsets/ata-acerlabs.c +++ b/sys/dev/ata/chipsets/ata-acerlabs.c @@ -141,11 +141,14 @@ ata_ali_chipinit(device_t dev) /* use device interrupt as byte count end */ pci_write_config(dev, 0x4a, pci_read_config(dev, 0x4a, 1) | 0x20, 1); - /* enable cable detection and UDMA support on newer chips */ - pci_write_config(dev, 0x4b, pci_read_config(dev, 0x4b, 1) | 0x09, 1); + /* enable cable detection and UDMA support on revisions < 0xc7 */ + if (ctlr->chip->chiprev < 0xc7) + pci_write_config(dev, 0x4b, pci_read_config(dev, 0x4b, 1) | + 0x09, 1); - /* enable ATAPI UDMA mode */ - pci_write_config(dev, 0x53, pci_read_config(dev, 0x53, 1) | 0x01, 1); + /* enable ATAPI UDMA mode (even if we are going to do PIO) */ + pci_write_config(dev, 0x53, pci_read_config(dev, 0x53, 1) | + (ctlr->chip->chiprev >= 0xc7 ? 0x03 : 0x01), 1); /* only chips with revision > 0xc4 can do 48bit DMA */ if (ctlr->chip->chiprev <= 0xc4) @@ -177,7 +180,8 @@ ata_ali_ch_attach(device_t dev) if (ata_pci_ch_attach(dev)) return ENXIO; - ch->flags |= ATA_CHECKS_CABLE; + if (ctlr->chip->cfg2 & ALI_NEW && ctlr->chip->chiprev < 0xc7) + ch->flags |= ATA_CHECKS_CABLE; /* older chips can't do 48bit DMA transfers */ if (ctlr->chip->chiprev <= 0xc4) ch->flags |= ATA_NO_48BIT_DMA; @@ -276,7 +280,7 @@ ata_ali_setmode(device_t dev, int target, int mode) mode = min(mode, ctlr->chip->max_dma); - if (ctlr->chip->cfg2 & ALI_NEW) { + if (ctlr->chip->cfg2 & ALI_NEW && ctlr->chip->chiprev < 0xc7) { if (mode > ATA_UDMA2 && pci_read_config(parent, 0x4a, 1) & (1 << ch->unit)) { ata_print_cable(dev, "controller"); From 489a1b93581181f969c4a8270de43b8a9c507daf Mon Sep 17 00:00:00 2001 From: Alexander Kabaev Date: Sun, 20 Dec 2009 02:35:10 +0000 Subject: [PATCH 0912/2592] MFC r198471. Log: 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 af4411db7e59363a9eb57d12346a01d17d9b1ea0 Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Sun, 20 Dec 2009 04:45:32 +0000 Subject: [PATCH 0913/2592] MFC r200449: Don't free jail parameter values after printing them - jail_param_get expects them to be there for the next jail in the list. PR: bin/141359 --- usr.sbin/jls/jls.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/usr.sbin/jls/jls.c b/usr.sbin/jls/jls.c index 0661ee3fa43..3f4800cb5a4 100644 --- a/usr.sbin/jls/jls.c +++ b/usr.sbin/jls/jls.c @@ -425,11 +425,6 @@ print_jail(int pflags, int jflags) if (params[i].jp_flags & JP_USER) free(param_values[i]); } - for (i = 0; i < nparams; i++) - if (!(params[i].jp_flags & JP_RAWVALUE)) { - free(params[i].jp_value); - params[i].jp_value = NULL; - } return (jid); } From 19022f2808d72f70db11c276e8368c91d37b4d49 Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Sun, 20 Dec 2009 04:49:29 +0000 Subject: [PATCH 0914/2592] MFC r200623: Add a null pointer check so "name" can be used as a key parameter in jailparam_get. PR: bin/141692 Submitted by: delphij --- lib/libjail/jail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libjail/jail.c b/lib/libjail/jail.c index 9411b88bdf6..39c88d098ed 100644 --- a/lib/libjail/jail.c +++ b/lib/libjail/jail.c @@ -532,7 +532,7 @@ jailparam_get(struct jailparam *jp, unsigned njp, int flags) } jp_key = jp_lastjid ? jp_lastjid : jp_jid && jp_jid->jp_valuelen == sizeof(int) && - *(int *)jp_jid->jp_value ? jp_jid : jp_name; + jp_jid->jp_value && *(int *)jp_jid->jp_value ? jp_jid : jp_name; if (jp_key == NULL || jp_key->jp_value == NULL) { strlcpy(jail_errmsg, "no jail specified", JAIL_ERRMSGLEN); errno = ENOENT; From 86a2af8fd4178ba19f049a50a1a0fa1e6a59e600 Mon Sep 17 00:00:00 2001 From: Sean Farley Date: Sun, 20 Dec 2009 18:57:43 +0000 Subject: [PATCH 0915/2592] Merge from head to stable/8: r200424: Fix libusb_open_device_with_vid_pid() to return a NULL if no device is found instead of the last device in its search list. Reviewed by: thompsa --- lib/libusb/libusb10.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c index 9a5154e7e5f..25520d2ab5e 100644 --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -379,8 +379,6 @@ libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, if ((i = libusb_get_device_list(ctx, &devs)) < 0) return (NULL); - pdev = NULL; - for (j = 0; j < i; j++) { pdev = devs[j]->os_priv; pdesc = libusb20_dev_get_device_desc(pdev); @@ -396,6 +394,8 @@ libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, break; } } + if (j == i) + pdev = NULL; libusb_free_device_list(devs, 1); DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave"); From 088e699c182acf62e96bbdc23e7f44425e256471 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 20 Dec 2009 20:51:20 +0000 Subject: [PATCH 0916/2592] MFC r198173: sh: show more info 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 54a80a715d0..b898d7a3990 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -1310,6 +1310,7 @@ parsebackq: { struct jmploc *const savehandler = handler; int savelen; int saveprompt; + const int bq_startlinno = plinno; savepbq = parsebackquote; if (setjmp(jmploc.loc)) { @@ -1317,6 +1318,10 @@ parsebackq: { ckfree(str); parsebackquote = 0; handler = savehandler; + if (exception == EXERROR) { + startlinno = bq_startlinno; + synerror("Error in command substitution"); + } longjmp(handler->loc, 1); } INTOFF; From 5e860e7b2f4bb72a8988d7e14f7e6a8ee1e65488 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Mon, 21 Dec 2009 05:58:55 +0000 Subject: [PATCH 0917/2592] MFC r199969: amdsbwd: new driver for AMD SB600/SB7xx watchdog timer --- sys/amd64/conf/NOTES | 2 + sys/conf/files.amd64 | 1 + sys/conf/files.i386 | 1 + sys/dev/amdsbwd/amdsbwd.c | 431 +++++++++++++++++++++++++++++++++++ sys/i386/conf/NOTES | 2 + sys/modules/Makefile | 3 + sys/modules/amdsbwd/Makefile | 8 + 7 files changed, 448 insertions(+) create mode 100644 sys/dev/amdsbwd/amdsbwd.c create mode 100644 sys/modules/amdsbwd/Makefile diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index 536122451af..a231d333bac 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -385,8 +385,10 @@ device asmc # Hardware watchdog timers: # # ichwd: Intel ICH watchdog timer +# amdsbwd: AMD SB7xx watchdog timer # device ichwd +device amdsbwd # # Temperature sensors: diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index c22a213c4e8..15b4a98e2eb 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -151,6 +151,7 @@ dev/agp/agp_amd64.c optional agp dev/agp/agp_i810.c optional agp dev/agp/agp_intel.c optional agp dev/agp/agp_via.c optional agp +dev/amdsbwd/amdsbwd.c optional amdsbwd dev/amdtemp/amdtemp.c optional amdtemp dev/arcmsr/arcmsr.c optional arcmsr pci dev/asmc/asmc.c optional asmc isa diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 91d42a10bd0..9ac3951a3ad 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -127,6 +127,7 @@ dev/agp/agp_nvidia.c optional agp dev/agp/agp_sis.c optional agp dev/agp/agp_via.c optional agp dev/aic/aic_isa.c optional aic isa +dev/amdsbwd/amdsbwd.c optional amdsbwd dev/amdtemp/amdtemp.c optional amdtemp dev/arcmsr/arcmsr.c optional arcmsr pci dev/asmc/asmc.c optional asmc isa diff --git a/sys/dev/amdsbwd/amdsbwd.c b/sys/dev/amdsbwd/amdsbwd.c new file mode 100644 index 00000000000..418e1941f2a --- /dev/null +++ b/sys/dev/amdsbwd/amdsbwd.c @@ -0,0 +1,431 @@ +/*- + * Copyright (c) 2009 Andriy Gapon + * 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. + */ + +/* + * This is a driver for watchdog timer present in AMD SB600/SB7xx + * south bridges and other watchdog timers advertised via WDRT ACPI table. + * Please see the following specifications for the descriptions of the + * registers and flags: + * - AMD SB600 Register Reference Guide, Public Version, Rev. 3.03 (SB600 RRG) + * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/46155_sb600_rrg_pub_3.03.pdf + * - AMD SB700/710/750 Register Reference Guide (RRG) + * http://developer.amd.com/assets/43009_sb7xx_rrg_pub_1.00.pdf + * - AMD SB700/710/750 Register Programming Requirements (RPR) + * http://developer.amd.com/assets/42413_sb7xx_rpr_pub_1.00.pdf + * Please see the following for Watchdog Resource Table specification: + * - Watchdog Timer Hardware Requirements for Windows Server 2003 (WDRT) + * http://www.microsoft.com/whdc/system/sysinternals/watchdog.mspx + * AMD SB600/SB7xx watchdog hardware seems to conform to the above, + * but my system doesn't provide the table. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* RRG 2.3.3.1.1, page 161. */ +#define AMDSB_PMIO_INDEX 0xcd6 +#define AMDSB_PMIO_DATA (PMIO_INDEX + 1) +#define AMDSB_PMIO_WIDTH 2 +/* RRG 2.3.3.2, page 181. */ +#define AMDSB_PM_RESET_STATUS0 0x44 +#define AMDSB_PM_RESET_STATUS1 0x45 +#define AMDSB_WD_RST_STS 0x02 +/* RRG 2.3.3.2, page 188; RPR 2.36, page 30. */ +#define AMDSB_PM_WDT_CTRL 0x69 +#define AMDSB_WDT_DISABLE 0x01 +#define AMDSB_WDT_RES_MASK (0x02 | 0x04) +#define AMDSB_WDT_RES_32US 0x00 +#define AMDSB_WDT_RES_10MS 0x02 +#define AMDSB_WDT_RES_100MS 0x04 +#define AMDSB_WDT_RES_1S 0x06 +#define AMDSB_PM_WDT_BASE_LSB 0x6c +#define AMDSB_PM_WDT_BASE_MSB 0x6f +/* RRG 2.3.4, page 223, WDRT. */ +#define AMDSB_WD_CTRL 0x00 +#define AMDSB_WD_RUN 0x01 +#define AMDSB_WD_FIRED 0x02 +#define AMDSB_WD_SHUTDOWN 0x04 +#define AMDSB_WD_DISABLE 0x08 +#define AMDSB_WD_RESERVED 0x70 +#define AMDSB_WD_RELOAD 0x80 +#define AMDSB_WD_COUNT 0x04 +#define AMDSB_WD_COUNT_MASK 0xffff +#define AMDSB_WDIO_REG_WIDTH 4 +/* WDRT */ +#define MAXCOUNT_MIN_VALUE 511 +/* RRG 2.3.1.1, page 122; SB600 RRG 2.3.1.1, page 97. */ +#define AMDSB7xx_SMBUS_DEVID 0x43851002 + +#define amdsbwd_verbose_printf(dev, ...) \ + do { \ + if (bootverbose) \ + device_printf(dev, __VA_ARGS__);\ + } while (0) + +struct amdsbwd_softc { + device_t dev; + eventhandler_tag ev_tag; + struct resource *res_ctrl; + struct resource *res_count; + int rid_ctrl; + int rid_count; + int ms_per_tick; + int max_ticks; + int active; + unsigned int timeout; +}; + +static void amdsbwd_identify(driver_t *driver, device_t parent); +static int amdsbwd_probe(device_t dev); +static int amdsbwd_attach(device_t dev); +static int amdsbwd_detach(device_t dev); + +static device_method_t amdsbwd_methods[] = { + DEVMETHOD(device_identify, amdsbwd_identify), + DEVMETHOD(device_probe, amdsbwd_probe), + DEVMETHOD(device_attach, amdsbwd_attach), + DEVMETHOD(device_detach, amdsbwd_detach), +#if 0 + DEVMETHOD(device_shutdown, amdsbwd_detach), +#endif + {0, 0} +}; + +static devclass_t amdsbwd_devclass; +static driver_t amdsbwd_driver = { + "amdsbwd", + amdsbwd_methods, + sizeof(struct amdsbwd_softc) +}; + +DRIVER_MODULE(amdsbwd, isa, amdsbwd_driver, amdsbwd_devclass, NULL, NULL); + + +static uint8_t +pmio_read(struct resource *res, uint8_t reg) +{ + bus_write_1(res, 0, reg); /* Index */ + return (bus_read_1(res, 1)); /* Data */ +} + +static void +pmio_write(struct resource *res, uint8_t reg, uint8_t val) +{ + bus_write_1(res, 0, reg); /* Index */ + bus_write_1(res, 1, val); /* Data */ +} + +static uint32_t +wdctrl_read(struct amdsbwd_softc *sc) +{ + return (bus_read_4(sc->res_ctrl, 0)); +} + +static void +wdctrl_write(struct amdsbwd_softc *sc, uint32_t val) +{ + bus_write_4(sc->res_ctrl, 0, val); +} + +static __unused uint32_t +wdcount_read(struct amdsbwd_softc *sc) +{ + return (bus_read_4(sc->res_count, 0)); +} + +static void +wdcount_write(struct amdsbwd_softc *sc, uint32_t val) +{ + bus_write_4(sc->res_count, 0, val); +} + +static void +amdsbwd_tmr_enable(struct amdsbwd_softc *sc) +{ + uint32_t val; + + val = wdctrl_read(sc); + val |= AMDSB_WD_RUN; + wdctrl_write(sc, val); + sc->active = 1; + amdsbwd_verbose_printf(sc->dev, "timer enabled\n"); +} + +static void +amdsbwd_tmr_disable(struct amdsbwd_softc *sc) +{ + uint32_t val; + + val = wdctrl_read(sc); + val &= ~AMDSB_WD_RUN; + wdctrl_write(sc, val); + sc->active = 0; + amdsbwd_verbose_printf(sc->dev, "timer disabled\n"); +} + +static void +amdsbwd_tmr_reload(struct amdsbwd_softc *sc) +{ + uint32_t val; + + val = wdctrl_read(sc); + val |= AMDSB_WD_RELOAD; + wdctrl_write(sc, val); +} + +static void +amdsbwd_tmr_set(struct amdsbwd_softc *sc, uint16_t timeout) +{ + + timeout &= AMDSB_WD_COUNT_MASK; + wdcount_write(sc, timeout); + sc->timeout = timeout; + amdsbwd_verbose_printf(sc->dev, "timeout set to %u ticks\n", timeout); +} + +static void +amdsbwd_event(void *arg, unsigned int cmd, int *error) +{ + struct amdsbwd_softc *sc = arg; + unsigned int timeout; + + /* convert from power-of-two-ns to WDT ticks */ + cmd &= WD_INTERVAL; + if (cmd < WD_TO_1SEC) + cmd = 0; + timeout = ((uint64_t)1 << (cmd - WD_TO_1MS)) / sc->ms_per_tick; + if (timeout > sc->max_ticks) + timeout = sc->max_ticks; + if (cmd) { + if (timeout != sc->timeout) { + amdsbwd_tmr_set(sc, timeout); + if (!sc->active) + amdsbwd_tmr_enable(sc); + } + amdsbwd_tmr_reload(sc); + *error = 0; + } else { + if (sc->active) + amdsbwd_tmr_disable(sc); + } +} + +static void +amdsbwd_identify(driver_t *driver, device_t parent) +{ + device_t child; + device_t smb_dev; + + if (resource_disabled("amdsbwd", 0)) + return; + if (device_find_child(parent, "amdsbwd", -1) != NULL) + return; + + /* + * Try to identify SB600/SB7xx by PCI Device ID of SMBus device + * that should be present at bus 0, device 20, function 0. + */ + smb_dev = pci_find_bsf(0, 20, 0); + if (smb_dev == NULL) + return; + if (pci_get_devid(smb_dev) != AMDSB7xx_SMBUS_DEVID) + return; + + child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "amdsbwd", -1); + if (child == NULL) + device_printf(parent, "add amdsbwd child failed\n"); +} + +static int +amdsbwd_probe(device_t dev) +{ + struct resource *res; + uint32_t addr; + uint32_t val; + int rid; + int rc; + int i; + + /* Do not claim some ISA PnP device by accident. */ + if (isa_get_logicalid(dev) != 0) + return (ENXIO); + + rc = bus_set_resource(dev, SYS_RES_IOPORT, 0, AMDSB_PMIO_INDEX, + AMDSB_PMIO_WIDTH); + if (rc != 0) { + device_printf(dev, "bus_set_resource for IO failed\n"); + return (ENXIO); + } + rid = 0; + res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul, + AMDSB_PMIO_WIDTH, RF_ACTIVE | RF_SHAREABLE); + if (res == NULL) { + device_printf(dev, "bus_alloc_resource for IO failed\n"); + return (ENXIO); + } + + /* Report cause of previous reset for user's convenience. */ + val = pmio_read(res, AMDSB_PM_RESET_STATUS0); + if (val != 0) + amdsbwd_verbose_printf(dev, "ResetStatus0 = %#04x\n", val); + val = pmio_read(res, AMDSB_PM_RESET_STATUS1); + if (val != 0) + amdsbwd_verbose_printf(dev, "ResetStatus1 = %#04x\n", val); + if ((val & AMDSB_WD_RST_STS) != 0) + device_printf(dev, "Previous Reset was caused by Watchdog\n"); + + /* Find base address of memory mapped WDT registers. */ + for (addr = 0, i = 0; i < 4; i++) { + addr <<= 8; + addr |= pmio_read(res, AMDSB_PM_WDT_BASE_MSB - i); + } + amdsbwd_verbose_printf(dev, "memory base address = %#010x\n", addr); + rc = bus_set_resource(dev, SYS_RES_MEMORY, 0, addr + AMDSB_WD_CTRL, + AMDSB_WDIO_REG_WIDTH); + if (rc != 0) { + device_printf(dev, "bus_set_resource for control failed\n"); + return (ENXIO); + } + rc = bus_set_resource(dev, SYS_RES_MEMORY, 1, addr + AMDSB_WD_COUNT, + AMDSB_WDIO_REG_WIDTH); + if (rc != 0) { + device_printf(dev, "bus_set_resource for count failed\n"); + return (ENXIO); + } + + /* Set watchdog timer tick to 10ms. */ + val = pmio_read(res, AMDSB_PM_WDT_CTRL); + val &= ~AMDSB_WDT_RES_MASK; + val |= AMDSB_WDT_RES_10MS; + pmio_write(res, AMDSB_PM_WDT_CTRL, val); + + /* Enable watchdog device (in stopped state). */ + val = pmio_read(res, AMDSB_PM_WDT_CTRL); + val &= ~AMDSB_WDT_DISABLE; + pmio_write(res, AMDSB_PM_WDT_CTRL, val); + + /* + * XXX TODO: Ensure that watchdog decode is enabled + * (register 0x41, bit 3). + */ + bus_release_resource(dev, SYS_RES_IOPORT, rid, res); + bus_delete_resource(dev, SYS_RES_IOPORT, rid); + + device_set_desc(dev, "AMD SB600/SB7xx Watchdog Timer"); + return (0); +} + +static int +amdsbwd_attach_sb(device_t dev, struct amdsbwd_softc *sc) +{ + sc->max_ticks = UINT16_MAX; + sc->ms_per_tick = 10; + sc->rid_ctrl = 0; + sc->rid_count = 1; + + sc->res_ctrl = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->rid_ctrl, RF_ACTIVE); + if (sc->res_ctrl == NULL) { + device_printf(dev, "bus_alloc_resource for ctrl failed\n"); + return (ENXIO); + } + sc->res_count = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->rid_count, RF_ACTIVE); + if (sc->res_count == NULL) { + device_printf(dev, "bus_alloc_resource for count failed\n"); + return (ENXIO); + } + return (0); +} + +static int +amdsbwd_attach(device_t dev) +{ + struct amdsbwd_softc *sc; + int rc; + + sc = device_get_softc(dev); + sc->dev = dev; + + rc = amdsbwd_attach_sb(dev, sc); + if (rc != 0) + goto fail; + + /* Setup initial state of Watchdog Control. */ + wdctrl_write(sc, AMDSB_WD_FIRED); + + if (wdctrl_read(sc) & AMDSB_WD_DISABLE) { + device_printf(dev, "watchdog hardware is disabled\n"); + goto fail; + } + + sc->ev_tag = EVENTHANDLER_REGISTER(watchdog_list, amdsbwd_event, sc, + EVENTHANDLER_PRI_ANY); + + return (0); + +fail: + amdsbwd_detach(dev); + return (ENXIO); +} + +static int +amdsbwd_detach(device_t dev) +{ + struct amdsbwd_softc *sc; + + sc = device_get_softc(dev); + if (sc->ev_tag != NULL) + EVENTHANDLER_DEREGISTER(watchdog_list, sc->ev_tag); + + if (sc->active) + amdsbwd_tmr_disable(sc); + + if (sc->res_ctrl != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ctrl, + sc->res_ctrl); + + if (sc->res_count != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_count, + sc->res_count); + + return (0); +} + diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index b7f240930cc..cd5951b6db2 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -779,8 +779,10 @@ hint.pcf.0.irq="5" # Hardware watchdog timers: # # ichwd: Intel ICH watchdog timer +# amdsbwd: AMD SB7xx watchdog timer # device ichwd +device amdsbwd # # Temperature sensors: diff --git a/sys/modules/Makefile b/sys/modules/Makefile index eca7b6b6f4a..841941b5055 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -21,6 +21,7 @@ SUBDIR= ${_3dfx} \ alc \ ale \ ${_amd} \ + ${_amdsbwd} \ ${_amdtemp} \ amr \ ${_an} \ @@ -413,6 +414,7 @@ _zfs= zfs _aac= aac _acpi= acpi _ahb= ahb +_amdsbwd= amdsbwd _amdtemp= amdtemp _arcmsr= arcmsr _asmc= asmc @@ -468,6 +470,7 @@ _aac= aac _acpi= acpi _agp= agp _an= an +_amdsbwd= amdsbwd _amdtemp= amdtemp _arcmsr= arcmsr _asmc= asmc diff --git a/sys/modules/amdsbwd/Makefile b/sys/modules/amdsbwd/Makefile new file mode 100644 index 00000000000..56f9ab79b87 --- /dev/null +++ b/sys/modules/amdsbwd/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/amdsbwd +KMOD = amdsbwd +SRCS = amdsbwd.c +SRCS += device_if.h bus_if.h pci_if.h isa_if.h + +.include From b065c165037f961bec21c0cd7efa9f71f88b1585 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 21 Dec 2009 11:06:41 +0000 Subject: [PATCH 0918/2592] MFC r200667: Return earlier from linux_do_tkill() when supplied signal number is 0. --- sys/compat/linux/linux_signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c index 5910d627d8d..9cc05ed99b8 100644 --- a/sys/compat/linux/linux_signal.c +++ b/sys/compat/linux/linux_signal.c @@ -565,7 +565,7 @@ linux_do_tkill(struct thread *td, l_int tgid, l_int pid, l_int signum) AUDIT_ARG_PROCESS(p); error = p_cansignal(td, p, signum); - if (error) + if (error != 0 || signum == 0) goto out; error = ESRCH; From 3135744c5976a1aa11db5fe8c4e9c8c905cd84e0 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Mon, 21 Dec 2009 13:53:33 +0000 Subject: [PATCH 0919/2592] MFC r200666: Fixed incorrect watchdog timeout setting. PR: kern/130512 --- sys/dev/ipmi/ipmi.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sys/dev/ipmi/ipmi.c b/sys/dev/ipmi/ipmi.c index 8e53d01f388..da024fc767c 100644 --- a/sys/dev/ipmi/ipmi.c +++ b/sys/dev/ipmi/ipmi.c @@ -588,12 +588,15 @@ ipmi_polled_enqueue_request(struct ipmi_softc *sc, struct ipmi_request *req) * Watchdog event handler. */ -static void -ipmi_set_watchdog(struct ipmi_softc *sc, int sec) +static int +ipmi_set_watchdog(struct ipmi_softc *sc, unsigned int sec) { struct ipmi_request *req; int error; + if (sec > 0xffff / 10) + return (EINVAL); + req = ipmi_alloc_driver_request(IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_SET_WDOG, 6, 0); @@ -604,7 +607,7 @@ ipmi_set_watchdog(struct ipmi_softc *sc, int sec) req->ir_request[2] = 0; req->ir_request[3] = 0; /* Timer use */ req->ir_request[4] = (sec * 10) & 0xff; - req->ir_request[5] = (sec * 10) / 2550; + req->ir_request[5] = (sec * 10) >> 8; } else { req->ir_request[0] = IPMI_SET_WD_TIMER_SMS_OS; req->ir_request[1] = 0; @@ -617,8 +620,7 @@ ipmi_set_watchdog(struct ipmi_softc *sc, int sec) error = ipmi_submit_driver_request(sc, req, 0); if (error) device_printf(sc->ipmi_dev, "Failed to set watchdog\n"); - - if (error == 0 && sec) { + else if (sec) { ipmi_free_request(req); req = ipmi_alloc_driver_request(IPMI_ADDR(IPMI_APP_REQUEST, 0), @@ -631,6 +633,7 @@ ipmi_set_watchdog(struct ipmi_softc *sc, int sec) } ipmi_free_request(req); + return (error); /* dump_watchdog(sc); */ @@ -641,14 +644,22 @@ ipmi_wd_event(void *arg, unsigned int cmd, int *error) { struct ipmi_softc *sc = arg; unsigned int timeout; + int e; cmd &= WD_INTERVAL; if (cmd > 0 && cmd <= 63) { - timeout = ((uint64_t)1 << cmd) / 1800000000; - ipmi_set_watchdog(sc, timeout); - *error = 0; + timeout = ((uint64_t)1 << cmd) / 1000000000; + if (timeout == 0) + timeout = 1; + e = ipmi_set_watchdog(sc, timeout); + if (e == 0) + *error = 0; + else + (void)ipmi_set_watchdog(sc, 0); } else { - ipmi_set_watchdog(sc, 0); + e = ipmi_set_watchdog(sc, 0); + if (e != 0 && cmd == 0) + *error = EOPNOTSUPP; } } From 3e05e771bdcdde5dcd2ee4e018aa9a1183892dd4 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 21 Dec 2009 18:07:15 +0000 Subject: [PATCH 0920/2592] MFC r199548: Remove complex macros that were used to compute bits values. Although these macros may have its own strength, its complex definition make hard to read the code. Approved by: delphij --- sys/dev/et/if_et.c | 87 ++++++------ sys/dev/et/if_etreg.h | 308 +++++++++++++++++++----------------------- sys/dev/et/if_etvar.h | 24 ++-- 3 files changed, 198 insertions(+), 221 deletions(-) diff --git a/sys/dev/et/if_et.c b/sys/dev/et/if_et.c index 1e28f0be112..302e51a02ef 100644 --- a/sys/dev/et/if_et.c +++ b/sys/dev/et/if_et.c @@ -404,8 +404,8 @@ et_miibus_readreg(device_t dev, int phy, int reg) /* Stop any pending operations */ CSR_WRITE_4(sc, ET_MII_CMD, 0); - val = __SHIFTIN(phy, ET_MII_ADDR_PHY) | - __SHIFTIN(reg, ET_MII_ADDR_REG); + val = (phy << ET_MII_ADDR_PHY_SHIFT) & ET_MII_ADDR_PHY_MASK; + val |= (reg << ET_MII_ADDR_REG_SHIFT) & ET_MII_ADDR_REG_MASK; CSR_WRITE_4(sc, ET_MII_ADDR, val); /* Start reading */ @@ -429,7 +429,7 @@ et_miibus_readreg(device_t dev, int phy, int reg) #undef NRETRY val = CSR_READ_4(sc, ET_MII_STAT); - ret = __SHIFTOUT(val, ET_MII_STAT_VALUE); + ret = val & ET_MII_STAT_VALUE_MASK; back: /* Make sure that the current operation is stopped */ @@ -447,12 +447,13 @@ et_miibus_writereg(device_t dev, int phy, int reg, int val0) /* Stop any pending operations */ CSR_WRITE_4(sc, ET_MII_CMD, 0); - val = __SHIFTIN(phy, ET_MII_ADDR_PHY) | - __SHIFTIN(reg, ET_MII_ADDR_REG); + val = (phy << ET_MII_ADDR_PHY_SHIFT) & ET_MII_ADDR_PHY_MASK; + val |= (reg << ET_MII_ADDR_REG_SHIFT) & ET_MII_ADDR_REG_MASK; CSR_WRITE_4(sc, ET_MII_ADDR, val); /* Start writing */ - CSR_WRITE_4(sc, ET_MII_CTRL, __SHIFTIN(val0, ET_MII_CTRL_VALUE)); + CSR_WRITE_4(sc, ET_MII_CTRL, + (val0 << ET_MII_CTRL_VALUE_SHIFT) & ET_MII_CTRL_VALUE_MASK); #define NRETRY 100 @@ -601,8 +602,13 @@ et_bus_config(device_t dev) /* * Set L0s and L1 latency timer to 2us */ - val = ET_PCIV_L0S_LATENCY(2) | ET_PCIV_L1_LATENCY(2); - pci_write_config(dev, ET_PCIR_L0S_L1_LATENCY, val, 1); + val = pci_read_config(dev, ET_PCIR_L0S_L1_LATENCY, 4); + val &= ~(PCIM_LINK_CAP_L0S_EXIT | PCIM_LINK_CAP_L1_EXIT); + /* L0s exit latency : 2us */ + val |= 0x00005000; + /* L1 exit latency : 2us */ + val |= 0x00028000; + pci_write_config(dev, ET_PCIR_L0S_L1_LATENCY, val, 4); /* * Set max read request size to 2048 bytes @@ -1021,10 +1027,10 @@ et_chip_attach(struct et_softc *sc) /* * Setup half duplex mode */ - val = __SHIFTIN(10, ET_MAC_HDX_ALT_BEB_TRUNC) | - __SHIFTIN(15, ET_MAC_HDX_REXMIT_MAX) | - __SHIFTIN(55, ET_MAC_HDX_COLLWIN) | - ET_MAC_HDX_EXC_DEFER; + val = (10 << ET_MAC_HDX_ALT_BEB_TRUNC_SHIFT) | + (15 << ET_MAC_HDX_REXMIT_MAX_SHIFT) | + (55 << ET_MAC_HDX_COLLWIN_SHIFT) | + ET_MAC_HDX_EXC_DEFER; CSR_WRITE_4(sc, ET_MAC_HDX, val); /* Clear MAC control */ @@ -1655,19 +1661,19 @@ et_init_mac(struct et_softc *sc) /* * Setup inter packet gap */ - val = __SHIFTIN(56, ET_IPG_NONB2B_1) | - __SHIFTIN(88, ET_IPG_NONB2B_2) | - __SHIFTIN(80, ET_IPG_MINIFG) | - __SHIFTIN(96, ET_IPG_B2B); + val = (56 << ET_IPG_NONB2B_1_SHIFT) | + (88 << ET_IPG_NONB2B_2_SHIFT) | + (80 << ET_IPG_MINIFG_SHIFT) | + (96 << ET_IPG_B2B_SHIFT); CSR_WRITE_4(sc, ET_IPG, val); /* * Setup half duplex mode */ - val = __SHIFTIN(10, ET_MAC_HDX_ALT_BEB_TRUNC) | - __SHIFTIN(15, ET_MAC_HDX_REXMIT_MAX) | - __SHIFTIN(55, ET_MAC_HDX_COLLWIN) | - ET_MAC_HDX_EXC_DEFER; + val = (10 << ET_MAC_HDX_ALT_BEB_TRUNC_SHIFT) | + (15 << ET_MAC_HDX_REXMIT_MAX_SHIFT) | + (55 << ET_MAC_HDX_COLLWIN_SHIFT) | + ET_MAC_HDX_EXC_DEFER; CSR_WRITE_4(sc, ET_MAC_HDX, val); /* Clear MAC control */ @@ -1738,7 +1744,7 @@ et_init_rxmac(struct et_softc *sc) * since this is the size of the PCI-Express TLP's * that the ET1310 uses. */ - val = __SHIFTIN(ET_RXMAC_SEGSZ(256), ET_RXMAC_MC_SEGSZ_MAX) | + val = (ET_RXMAC_SEGSZ(256) & ET_RXMAC_MC_SEGSZ_MAX_MASK) | ET_RXMAC_MC_SEGSZ_ENABLE; } else { val = 0; @@ -1761,7 +1767,9 @@ et_init_rxmac(struct et_softc *sc) /* * Configure runt filtering (may not work on certain chip generation) */ - val = __SHIFTIN(ETHER_MIN_LEN, ET_PKTFILT_MINLEN) | ET_PKTFILT_FRAG; + val = (ETHER_MIN_LEN << ET_PKTFILT_MINLEN_SHIFT) & + ET_PKTFILT_MINLEN_MASK; + val |= ET_PKTFILT_FRAG; CSR_WRITE_4(sc, ET_PKTFILT, val); /* Enable RX MAC but leave WOL disabled */ @@ -1793,11 +1801,9 @@ et_start_rxdma(struct et_softc *sc) { uint32_t val = 0; - val |= __SHIFTIN(sc->sc_rx_data[0].rbd_bufsize, - ET_RXDMA_CTRL_RING0_SIZE) | + val |= (sc->sc_rx_data[0].rbd_bufsize & ET_RXDMA_CTRL_RING0_SIZE_MASK) | ET_RXDMA_CTRL_RING0_ENABLE; - val |= __SHIFTIN(sc->sc_rx_data[1].rbd_bufsize, - ET_RXDMA_CTRL_RING1_SIZE) | + val |= (sc->sc_rx_data[1].rbd_bufsize & ET_RXDMA_CTRL_RING1_SIZE_MASK) | ET_RXDMA_CTRL_RING1_ENABLE; CSR_WRITE_4(sc, ET_RXDMA_CTRL, val); @@ -1892,7 +1898,8 @@ et_rxeof(struct et_softc *sc) rxs_stat_ring = rxsd->rxsd_status->rxs_stat_ring; rxst_wrap = (rxs_stat_ring & ET_RXS_STATRING_WRAP) ? 1 : 0; - rxst_index = __SHIFTOUT(rxs_stat_ring, ET_RXS_STATRING_INDEX); + rxst_index = (rxs_stat_ring & ET_RXS_STATRING_INDEX_MASK) >> + ET_RXS_STATRING_INDEX_SHIFT; while (rxst_index != rxst_ring->rsr_index || rxst_wrap != rxst_ring->rsr_wrap) { @@ -1906,16 +1913,18 @@ et_rxeof(struct et_softc *sc) MPASS(rxst_ring->rsr_index < ET_RX_NSTAT); st = &rxst_ring->rsr_stat[rxst_ring->rsr_index]; - buflen = __SHIFTOUT(st->rxst_info2, ET_RXST_INFO2_LEN); - buf_idx = __SHIFTOUT(st->rxst_info2, ET_RXST_INFO2_BUFIDX); - ring_idx = __SHIFTOUT(st->rxst_info2, ET_RXST_INFO2_RINGIDX); + buflen = (st->rxst_info2 & ET_RXST_INFO2_LEN_MASK) >> + ET_RXST_INFO2_LEN_SHIFT; + buf_idx = (st->rxst_info2 & ET_RXST_INFO2_BUFIDX_MASK) >> + ET_RXST_INFO2_BUFIDX_SHIFT; + ring_idx = (st->rxst_info2 & ET_RXST_INFO2_RINGIDX_MASK) >> + ET_RXST_INFO2_RINGIDX_SHIFT; if (++rxst_ring->rsr_index == ET_RX_NSTAT) { rxst_ring->rsr_index = 0; rxst_ring->rsr_wrap ^= 1; } - rxstat_pos = __SHIFTIN(rxst_ring->rsr_index, - ET_RXSTAT_POS_INDEX); + rxstat_pos = rxst_ring->rsr_index & ET_RXSTAT_POS_INDEX_MASK; if (rxst_ring->rsr_wrap) rxstat_pos |= ET_RXSTAT_POS_WRAP; CSR_WRITE_4(sc, ET_RXSTAT_POS, rxstat_pos); @@ -1968,7 +1977,7 @@ et_rxeof(struct et_softc *sc) rx_ring->rr_index = 0; rx_ring->rr_wrap ^= 1; } - rxring_pos = __SHIFTIN(rx_ring->rr_index, ET_RX_RING_POS_INDEX); + rxring_pos = rx_ring->rr_index & ET_RX_RING_POS_INDEX_MASK; if (rx_ring->rr_wrap) rxring_pos |= ET_RX_RING_POS_WRAP; CSR_WRITE_4(sc, rx_ring->rr_posreg, rxring_pos); @@ -2056,7 +2065,7 @@ et_encap(struct et_softc *sc, struct mbuf **m0) td = &tx_ring->tr_desc[idx]; td->td_addr_hi = ET_ADDR_HI(segs[i].ds_addr); td->td_addr_lo = ET_ADDR_LO(segs[i].ds_addr); - td->td_ctrl1 = __SHIFTIN(segs[i].ds_len, ET_TDCTRL1_LEN); + td->td_ctrl1 = segs[i].ds_len & ET_TDCTRL1_LEN_MASK; if (i == ctx.nsegs - 1) { /* Last frag */ td->td_ctrl2 = last_td_ctrl2; @@ -2083,8 +2092,7 @@ et_encap(struct et_softc *sc, struct mbuf **m0) bus_dmamap_sync(tx_ring->tr_dtag, tx_ring->tr_dmap, BUS_DMASYNC_PREWRITE); - tx_ready_pos = __SHIFTIN(tx_ring->tr_ready_index, - ET_TX_READY_POS_INDEX); + tx_ready_pos = tx_ring->tr_ready_index & ET_TX_READY_POS_INDEX_MASK; if (tx_ring->tr_ready_wrap) tx_ready_pos |= ET_TX_READY_POS_WRAP; CSR_WRITE_4(sc, ET_TX_READY_POS, tx_ready_pos); @@ -2119,7 +2127,7 @@ et_txeof(struct et_softc *sc) return; tx_done = CSR_READ_4(sc, ET_TX_DONE_POS); - end = __SHIFTOUT(tx_done, ET_TX_DONE_POS_INDEX); + end = tx_done & ET_TX_DONE_POS_INDEX_MASK; wrap = (tx_done & ET_TX_DONE_POS_WRAP) ? 1 : 0; while (tbd->tbd_start_index != end || tbd->tbd_start_wrap != wrap) { @@ -2352,7 +2360,8 @@ et_setmedia(struct et_softc *sc) cfg2 &= ~(ET_MAC_CFG2_MODE_MII | ET_MAC_CFG2_MODE_GMII | ET_MAC_CFG2_FDX | ET_MAC_CFG2_BIGFRM); cfg2 |= ET_MAC_CFG2_LENCHK | ET_MAC_CFG2_CRC | ET_MAC_CFG2_PADCRC | - __SHIFTIN(7, ET_MAC_CFG2_PREAMBLE_LEN); + ((7 << ET_MAC_CFG2_PREAMBLE_LEN_SHIFT) & + ET_MAC_CFG2_PREAMBLE_LEN_MASK); ctrl = CSR_READ_4(sc, ET_MAC_CTRL); ctrl &= ~(ET_MAC_CTRL_GHDX | ET_MAC_CTRL_MODE_MII); @@ -2384,7 +2393,7 @@ et_setup_rxdesc(struct et_rxbuf_data *rbd, int buf_idx, bus_addr_t paddr) desc->rd_addr_hi = ET_ADDR_HI(paddr); desc->rd_addr_lo = ET_ADDR_LO(paddr); - desc->rd_ctrl = __SHIFTIN(buf_idx, ET_RDCTRL_BUFIDX); + desc->rd_ctrl = buf_idx & ET_RDCTRL_BUFIDX_MASK; bus_dmamap_sync(rx_ring->rr_dtag, rx_ring->rr_dmap, BUS_DMASYNC_PREWRITE); diff --git a/sys/dev/et/if_etreg.h b/sys/dev/et/if_etreg.h index 136f6fbf584..637c1941627 100644 --- a/sys/dev/et/if_etreg.h +++ b/sys/dev/et/if_etreg.h @@ -73,50 +73,6 @@ #ifndef _IF_ETREG_H #define _IF_ETREG_H -/* - * __BIT(n): Return a bitmask with bit n set, where the least - * significant bit is bit 0. - * - * __BITS(m, n): Return a bitmask with bits m through n, inclusive, - * set. It does not matter whether m>n or m<=n. The - * least significant bit is bit 0. - * - * A "bitfield" is a span of consecutive bits defined by a bitmask, - * where 1s select the bits in the bitfield. __SHIFTIN, __SHIFTOUT, - * and __SHIFTOUT_MASK help read and write bitfields from device - * registers. - * - * __SHIFTIN(v, mask): Left-shift bits `v' into the bitfield - * defined by `mask', and return them. No - * side-effects. - * - * __SHIFTOUT(v, mask): Extract and return the bitfield selected - * by `mask' from `v', right-shifting the - * bits so that the rightmost selected bit - * is at bit 0. No side-effects. - * - * __SHIFTOUT_MASK(mask): Right-shift the bits in `mask' so that - * the rightmost non-zero bit is at bit - * 0. This is useful for finding the - * greatest unsigned value that a bitfield - * can hold. No side-effects. Note that - * __SHIFTOUT_MASK(m) = __SHIFTOUT(m, m). - */ - -/* __BIT(n): nth bit, where __BIT(0) == 0x1. */ -#define __BIT(__n) (((__n) == 32) ? 0 : ((uint32_t)1 << (__n))) - -/* __BITS(m, n): bits m through n, m < n. */ -#define __BITS(__m, __n) \ - ((__BIT(MAX((__m), (__n)) + 1) - 1) ^ (__BIT(MIN((__m), (__n))) - 1)) - -/* Find least significant bit that is set */ -#define __LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) - -#define __SHIFTOUT(__x, __mask) (((__x) & (__mask)) / __LOWEST_SET_BIT(__mask)) -#define __SHIFTIN(__x, __mask) ((__x) * __LOWEST_SET_BIT(__mask)) -#define __SHIFTOUT_MASK(__mask) __SHIFTOUT((__mask), (__mask)) - #define ET_MEM_TXSIZE_EX 182 #define ET_MEM_RXSIZE_MIN 608 #define ET_MEM_RXSIZE_DEFAULT 11216 @@ -159,10 +115,6 @@ #define ET_PCIV_REPLAY_TIMER_256 (1248 + ET_REPLAY_TIMER_RX_L0S_ADJ) #define ET_PCIR_L0S_L1_LATENCY 0xcf -#define ET_PCIM_L0S_LATENCY __BITS(2, 0) -#define ET_PCIM_L1_LATENCY __BITS(5, 3) -#define ET_PCIV_L0S_LATENCY(l) __SHIFTIN((l) - 1, ET_PCIM_L0S_LATENCY) -#define ET_PCIV_L1_LATENCY(l) __SHIFTIN((l) - 1, ET_PCIM_L1_LATENCY) /* * CSR @@ -176,22 +128,22 @@ #define ET_QUEUE_ADDR_END ET_QUEUE_ADDR(ET_MEM_SIZE) #define ET_PM 0x0010 -#define ET_PM_SYSCLK_GATE __BIT(3) -#define ET_PM_TXCLK_GATE __BIT(4) -#define ET_PM_RXCLK_GATE __BIT(5) +#define ET_PM_SYSCLK_GATE 0x00000008 +#define ET_PM_TXCLK_GATE 0x00000010 +#define ET_PM_RXCLK_GATE 0x00000020 #define ET_INTR_STATUS 0x0018 #define ET_INTR_MASK 0x001c #define ET_SWRST 0x0028 -#define ET_SWRST_TXDMA __BIT(0) -#define ET_SWRST_RXDMA __BIT(1) -#define ET_SWRST_TXMAC __BIT(2) -#define ET_SWRST_RXMAC __BIT(3) -#define ET_SWRST_MAC __BIT(4) -#define ET_SWRST_MAC_STAT __BIT(5) -#define ET_SWRST_MMC __BIT(6) -#define ET_SWRST_SELFCLR_DISABLE __BIT(31) +#define ET_SWRST_TXDMA 0x00000001 +#define ET_SWRST_RXDMA 0x00000002 +#define ET_SWRST_TXMAC 0x00000004 +#define ET_SWRST_RXMAC 0x00000008 +#define ET_SWRST_MAC 0x00000010 +#define ET_SWRST_MAC_STAT 0x00000020 +#define ET_SWRST_MMC 0x00000040 +#define ET_SWRST_SELFCLR_DISABLE 0x80000000 #define ET_MSI_CFG 0x0030 @@ -200,9 +152,9 @@ #define ET_TIMER 0x0038 #define ET_TXDMA_CTRL 0x1000 -#define ET_TXDMA_CTRL_HALT __BIT(0) -#define ET_TXDMA_CTRL_CACHE_THR __BITS(7, 4) -#define ET_TXDMA_CTRL_SINGLE_EPKT __BIT(8) /* ??? */ +#define ET_TXDMA_CTRL_HALT 0x00000001 +#define ET_TXDMA_CTRL_CACHE_THR_MASK 0x000000F0 +#define ET_TXDMA_CTRL_SINGLE_EPKT 0x00000100 /* ??? */ #define ET_TX_RING_HI 0x1004 #define ET_TX_RING_LO 0x1008 @@ -212,28 +164,28 @@ #define ET_TX_STATUS_LO 0x1020 #define ET_TX_READY_POS 0x1024 -#define ET_TX_READY_POS_INDEX __BITS(9, 0) -#define ET_TX_READY_POS_WRAP __BIT(10) +#define ET_TX_READY_POS_INDEX_MASK 0x000003FF +#define ET_TX_READY_POS_WRAP 0x00000400 #define ET_TX_DONE_POS 0x1060 -#define ET_TX_DONE_POS_INDEX __BITS(9, 0) -#define ET_TX_DONE_POS_WRAP __BIT(10) +#define ET_TX_DONE_POS_INDEX_MASK 0x0000003FF +#define ET_TX_DONE_POS_WRAP 0x000000400 #define ET_RXDMA_CTRL 0x2000 -#define ET_RXDMA_CTRL_HALT __BIT(0) -#define ET_RXDMA_CTRL_RING0_SIZE __BITS(9, 8) -#define ET_RXDMA_CTRL_RING0_128 0 /* 127 */ -#define ET_RXDMA_CTRL_RING0_256 1 /* 255 */ -#define ET_RXDMA_CTRL_RING0_512 2 /* 511 */ -#define ET_RXDMA_CTRL_RING0_1024 3 /* 1023 */ -#define ET_RXDMA_CTRL_RING0_ENABLE __BIT(10) -#define ET_RXDMA_CTRL_RING1_SIZE __BITS(12, 11) -#define ET_RXDMA_CTRL_RING1_2048 0 /* 2047 */ -#define ET_RXDMA_CTRL_RING1_4096 1 /* 4095 */ -#define ET_RXDMA_CTRL_RING1_8192 2 /* 8191 */ -#define ET_RXDMA_CTRL_RING1_16384 3 /* 16383 (9022?) */ -#define ET_RXDMA_CTRL_RING1_ENABLE __BIT(13) -#define ET_RXDMA_CTRL_HALTED __BIT(17) +#define ET_RXDMA_CTRL_HALT 0x00000001 +#define ET_RXDMA_CTRL_RING0_SIZE_MASK 0x00000300 +#define ET_RXDMA_CTRL_RING0_128 0x00000000 /* 127 */ +#define ET_RXDMA_CTRL_RING0_256 0x00000100 /* 255 */ +#define ET_RXDMA_CTRL_RING0_512 0x00000200 /* 511 */ +#define ET_RXDMA_CTRL_RING0_1024 0x00000300 /* 1023 */ +#define ET_RXDMA_CTRL_RING0_ENABLE 0x00000400 +#define ET_RXDMA_CTRL_RING1_SIZE_MASK 0x00001800 +#define ET_RXDMA_CTRL_RING1_2048 0x00000000 /* 2047 */ +#define ET_RXDMA_CTRL_RING1_4096 0x00000800 /* 4095 */ +#define ET_RXDMA_CTRL_RING1_8192 0x00001000 /* 8191 */ +#define ET_RXDMA_CTRL_RING1_16384 0x00001800 /* 16383 (9022?) */ +#define ET_RXDMA_CTRL_RING1_ENABLE 0x00002000 +#define ET_RXDMA_CTRL_HALTED 0x00020000 #define ET_RX_STATUS_LO 0x2004 #define ET_RX_STATUS_HI 0x2008 @@ -246,8 +198,8 @@ #define ET_RXSTAT_CNT 0x2028 #define ET_RXSTAT_POS 0x2030 -#define ET_RXSTAT_POS_INDEX __BITS(11, 0) -#define ET_RXSTAT_POS_WRAP __BIT(12) +#define ET_RXSTAT_POS_INDEX_MASK 0x00000FFF +#define ET_RXSTAT_POS_WRAP 0x00001000 #define ET_RXSTAT_MINCNT 0x2038 @@ -256,8 +208,8 @@ #define ET_RX_RING0_CNT 0x2044 #define ET_RX_RING0_POS 0x204c -#define ET_RX_RING0_POS_INDEX __BITS(9, 0) -#define ET_RX_RING0_POS_WRAP __BIT(10) +#define ET_RX_RING0_POS_INDEX_MASK 0x000003FF +#define ET_RX_RING0_POS_WRAP 0x00000400 #define ET_RX_RING0_MINCNT 0x2054 @@ -266,21 +218,21 @@ #define ET_RX_RING1_CNT 0x2060 #define ET_RX_RING1_POS 0x2068 -#define ET_RX_RING1_POS_INDEX __BITS(9, 0) -#define ET_RX_RING1_POS_WRAP __BIT(10) +#define ET_RX_RING1_POS_INDEX 0x000003FF +#define ET_RX_RING1_POS_WRAP 0x00000400 #define ET_RX_RING1_MINCNT 0x2070 #define ET_TXMAC_CTRL 0x3000 -#define ET_TXMAC_CTRL_ENABLE __BIT(0) -#define ET_TXMAC_CTRL_FC_DISABLE __BIT(3) +#define ET_TXMAC_CTRL_ENABLE 0x00000001 +#define ET_TXMAC_CTRL_FC_DISABLE 0x00000008 #define ET_TXMAC_FLOWCTRL 0x3010 #define ET_RXMAC_CTRL 0x4000 -#define ET_RXMAC_CTRL_ENABLE __BIT(0) -#define ET_RXMAC_CTRL_NO_PKTFILT __BIT(2) -#define ET_RXMAC_CTRL_WOL_DISABLE __BIT(3) +#define ET_RXMAC_CTRL_ENABLE 0x00000001 +#define ET_RXMAC_CTRL_NO_PKTFILT 0x00000004 +#define ET_RXMAC_CTRL_WOL_DISABLE 0x00000008 #define ET_WOL_CRC 0x4004 #define ET_WOL_SA_LO 0x4010 @@ -294,16 +246,17 @@ #define ET_MULTI_HASH 0x4074 #define ET_PKTFILT 0x4084 -#define ET_PKTFILT_BCAST __BIT(0) -#define ET_PKTFILT_MCAST __BIT(1) -#define ET_PKTFILT_UCAST __BIT(2) -#define ET_PKTFILT_FRAG __BIT(3) -#define ET_PKTFILT_MINLEN __BITS(22, 16) +#define ET_PKTFILT_BCAST 0x00000001 +#define ET_PKTFILT_MCAST 0x00000002 +#define ET_PKTFILT_UCAST 0x00000004 +#define ET_PKTFILT_FRAG 0x00000008 +#define ET_PKTFILT_MINLEN_MASK 0x007F0000 +#define ET_PKTFILT_MINLEN_SHIFT 16 #define ET_RXMAC_MC_SEGSZ 0x4088 -#define ET_RXMAC_MC_SEGSZ_ENABLE __BIT(0) -#define ET_RXMAC_MC_SEGSZ_FC __BIT(1) -#define ET_RXMAC_MC_SEGSZ_MAX __BITS(9, 2) +#define ET_RXMAC_MC_SEGSZ_ENABLE 0x00000001 +#define ET_RXMAC_MC_SEGSZ_FC 0x00000002 +#define ET_RXMAC_MC_SEGSZ_MAX_MASK 0x000003FC #define ET_RXMAC_SEGSZ(segsz) ((segsz) / ET_MEM_UNIT) #define ET_RXMAC_CUT_THRU_FRMLEN 8074 @@ -311,110 +264,121 @@ #define ET_RXMAC_SPACE_AVL 0x4094 #define ET_RXMAC_MGT 0x4098 -#define ET_RXMAC_MGT_PASS_ECRC __BIT(4) -#define ET_RXMAC_MGT_PASS_ELEN __BIT(5) -#define ET_RXMAC_MGT_PASS_ETRUNC __BIT(16) -#define ET_RXMAC_MGT_CHECK_PKT __BIT(17) +#define ET_RXMAC_MGT_PASS_ECRC 0x00000010 +#define ET_RXMAC_MGT_PASS_ELEN 0x00000020 +#define ET_RXMAC_MGT_PASS_ETRUNC 0x00010000 +#define ET_RXMAC_MGT_CHECK_PKT 0x00020000 #define ET_MAC_CFG1 0x5000 -#define ET_MAC_CFG1_TXEN __BIT(0) -#define ET_MAC_CFG1_SYNC_TXEN __BIT(1) -#define ET_MAC_CFG1_RXEN __BIT(2) -#define ET_MAC_CFG1_SYNC_RXEN __BIT(3) -#define ET_MAC_CFG1_TXFLOW __BIT(4) -#define ET_MAC_CFG1_RXFLOW __BIT(5) -#define ET_MAC_CFG1_LOOPBACK __BIT(8) -#define ET_MAC_CFG1_RST_TXFUNC __BIT(16) -#define ET_MAC_CFG1_RST_RXFUNC __BIT(17) -#define ET_MAC_CFG1_RST_TXMC __BIT(18) -#define ET_MAC_CFG1_RST_RXMC __BIT(19) -#define ET_MAC_CFG1_SIM_RST __BIT(30) -#define ET_MAC_CFG1_SOFT_RST __BIT(31) +#define ET_MAC_CFG1_TXEN 0x00000001 +#define ET_MAC_CFG1_SYNC_TXEN 0x00000002 +#define ET_MAC_CFG1_RXEN 0x00000004 +#define ET_MAC_CFG1_SYNC_RXEN 0x00000008 +#define ET_MAC_CFG1_TXFLOW 0x00000010 +#define ET_MAC_CFG1_RXFLOW 0x00000020 +#define ET_MAC_CFG1_LOOPBACK 0x00000100 +#define ET_MAC_CFG1_RST_TXFUNC 0x00010000 +#define ET_MAC_CFG1_RST_RXFUNC 0x00020000 +#define ET_MAC_CFG1_RST_TXMC 0x00040000 +#define ET_MAC_CFG1_RST_RXMC 0x00080000 +#define ET_MAC_CFG1_SIM_RST 0x40000000 +#define ET_MAC_CFG1_SOFT_RST 0x80000000 #define ET_MAC_CFG2 0x5004 -#define ET_MAC_CFG2_FDX __BIT(0) -#define ET_MAC_CFG2_CRC __BIT(1) -#define ET_MAC_CFG2_PADCRC __BIT(2) -#define ET_MAC_CFG2_LENCHK __BIT(4) -#define ET_MAC_CFG2_BIGFRM __BIT(5) -#define ET_MAC_CFG2_MODE_MII __BIT(8) -#define ET_MAC_CFG2_MODE_GMII __BIT(9) -#define ET_MAC_CFG2_PREAMBLE_LEN __BITS(15, 12) +#define ET_MAC_CFG2_FDX 0x00000001 +#define ET_MAC_CFG2_CRC 0x00000002 +#define ET_MAC_CFG2_PADCRC 0x00000004 +#define ET_MAC_CFG2_LENCHK 0x00000010 +#define ET_MAC_CFG2_BIGFRM 0x00000020 +#define ET_MAC_CFG2_MODE_MII 0x00000100 +#define ET_MAC_CFG2_MODE_GMII 0x00000200 +#define ET_MAC_CFG2_PREAMBLE_LEN_MASK 0x0000F000 +#define ET_MAC_CFG2_PREAMBLE_LEN_SHIFT 12 #define ET_IPG 0x5008 -#define ET_IPG_B2B __BITS(6, 0) -#define ET_IPG_MINIFG __BITS(15, 8) -#define ET_IPG_NONB2B_2 __BITS(22, 16) -#define ET_IPG_NONB2B_1 __BITS(30, 24) +#define ET_IPG_B2B_MASK 0x0000007F +#define ET_IPG_MINIFG_MASK 0x0000FF00 +#define ET_IPG_NONB2B_2_MASK 0x007F0000 +#define ET_IPG_NONB2B_1_MASK 0x7F000000 +#define ET_IPG_B2B_SHIFT 0 +#define ET_IPG_MINIFG_SHIFT 8 +#define ET_IPG_NONB2B_2_SHIFT 16 +#define ET_IPG_NONB2B_1_SHIFT 24 #define ET_MAC_HDX 0x500c -#define ET_MAC_HDX_COLLWIN __BITS(9, 0) -#define ET_MAC_HDX_REXMIT_MAX __BITS(15, 12) -#define ET_MAC_HDX_EXC_DEFER __BIT(16) -#define ET_MAC_HDX_NOBACKOFF __BIT(17) -#define ET_MAC_HDX_BP_NOBACKOFF __BIT(18) -#define ET_MAC_HDX_ALT_BEB __BIT(19) -#define ET_MAC_HDX_ALT_BEB_TRUNC __BITS(23, 20) +#define ET_MAC_HDX_COLLWIN_MASK 0x000003FF +#define ET_MAC_HDX_REXMIT_MAX_MASK 0x0000F000 +#define ET_MAC_HDX_EXC_DEFER 0x00010000 +#define ET_MAC_HDX_NOBACKOFF 0x00020000 +#define ET_MAC_HDX_BP_NOBACKOFF 0x00040000 +#define ET_MAC_HDX_ALT_BEB 0x00080000 +#define ET_MAC_HDX_ALT_BEB_TRUNC_MASK 0x00F00000 +#define ET_MAC_HDX_COLLWIN_SHIFT 0 +#define ET_MAC_HDX_REXMIT_MAX_SHIFT 12 +#define ET_MAC_HDX_ALT_BEB_TRUNC_SHIFT 20 #define ET_MAX_FRMLEN 0x5010 #define ET_MII_CFG 0x5020 -#define ET_MII_CFG_CLKRST __BITS(2, 0) -#define ET_MII_CFG_PREAMBLE_SUP __BIT(4) -#define ET_MII_CFG_SCAN_AUTOINC __BIT(5) -#define ET_MII_CFG_RST __BIT(31) +#define ET_MII_CFG_CLKRST 0x00000007 +#define ET_MII_CFG_PREAMBLE_SUP 0x00000010 +#define ET_MII_CFG_SCAN_AUTOINC 0x00000020 +#define ET_MII_CFG_RST 0x80000000 #define ET_MII_CMD 0x5024 -#define ET_MII_CMD_READ __BIT(0) +#define ET_MII_CMD_READ 0x00000001 #define ET_MII_ADDR 0x5028 -#define ET_MII_ADDR_REG __BITS(4, 0) -#define ET_MII_ADDR_PHY __BITS(12, 8) +#define ET_MII_ADDR_REG_MASK 0x0000001F +#define ET_MII_ADDR_PHY_MASK 0x00001F00 +#define ET_MII_ADDR_REG_SHIFT 0 +#define ET_MII_ADDR_PHY_SHIFT 8 #define ET_MII_CTRL 0x502c -#define ET_MII_CTRL_VALUE __BITS(15, 0) +#define ET_MII_CTRL_VALUE_MASK 0x0000FFFF +#define ET_MII_CTRL_VALUE_SHIFT 0 #define ET_MII_STAT 0x5030 -#define ET_MII_STAT_VALUE __BITS(15, 0) +#define ET_MII_STAT_VALUE_MASK 0x0000FFFF #define ET_MII_IND 0x5034 -#define ET_MII_IND_BUSY __BIT(0) -#define ET_MII_IND_INVALID __BIT(2) +#define ET_MII_IND_BUSY 0x00000001 +#define ET_MII_IND_INVALID 0x00000004 #define ET_MAC_CTRL 0x5038 -#define ET_MAC_CTRL_MODE_MII __BIT(24) -#define ET_MAC_CTRL_LHDX __BIT(25) -#define ET_MAC_CTRL_GHDX __BIT(26) +#define ET_MAC_CTRL_MODE_MII 0x01000000 +#define ET_MAC_CTRL_LHDX 0x02000000 +#define ET_MAC_CTRL_GHDX 0x04000000 #define ET_MAC_ADDR1 0x5040 #define ET_MAC_ADDR2 0x5044 #define ET_MMC_CTRL 0x7000 -#define ET_MMC_CTRL_ENABLE __BIT(0) -#define ET_MMC_CTRL_ARB_DISABLE __BIT(1) -#define ET_MMC_CTRL_RXMAC_DISABLE __BIT(2) -#define ET_MMC_CTRL_TXMAC_DISABLE __BIT(3) -#define ET_MMC_CTRL_TXDMA_DISABLE __BIT(4) -#define ET_MMC_CTRL_RXDMA_DISABLE __BIT(5) -#define ET_MMC_CTRL_FORCE_CE __BIT(6) +#define ET_MMC_CTRL_ENABLE 0x00000001 +#define ET_MMC_CTRL_ARB_DISABLE 0x00000002 +#define ET_MMC_CTRL_RXMAC_DISABLE 0x00000004 +#define ET_MMC_CTRL_TXMAC_DISABLE 0x00000008 +#define ET_MMC_CTRL_TXDMA_DISABLE 0x00000010 +#define ET_MMC_CTRL_RXDMA_DISABLE 0x00000020 +#define ET_MMC_CTRL_FORCE_CE 0x00000040 /* * Interrupts */ -#define ET_INTR_TXEOF __BIT(3) -#define ET_INTR_TXDMA_ERROR __BIT(4) -#define ET_INTR_RXEOF __BIT(5) -#define ET_INTR_RXRING0_LOW __BIT(6) -#define ET_INTR_RXRING1_LOW __BIT(7) -#define ET_INTR_RXSTAT_LOW __BIT(8) -#define ET_INTR_RXDMA_ERROR __BIT(9) -#define ET_INTR_TIMER __BIT(14) -#define ET_INTR_WOL __BIT(15) -#define ET_INTR_PHY __BIT(16) -#define ET_INTR_TXMAC __BIT(17) -#define ET_INTR_RXMAC __BIT(18) -#define ET_INTR_MAC_STATS __BIT(19) -#define ET_INTR_SLAVE_TO __BIT(20) +#define ET_INTR_TXEOF 0x00000008 +#define ET_INTR_TXDMA_ERROR 0x00000010 +#define ET_INTR_RXEOF 0x00000020 +#define ET_INTR_RXRING0_LOW 0x00000040 +#define ET_INTR_RXRING1_LOW 0x00000080 +#define ET_INTR_RXSTAT_LOW 0x00000100 +#define ET_INTR_RXDMA_ERROR 0x00000200 +#define ET_INTR_TIMER 0x00004000 +#define ET_INTR_WOL 0x00008000 +#define ET_INTR_PHY 0x00010000 +#define ET_INTR_TXMAC 0x00020000 +#define ET_INTR_RXMAC 0x00040000 +#define ET_INTR_MAC_STATS 0x00080000 +#define ET_INTR_SLAVE_TO 0x00100000 #define ET_INTRS (ET_INTR_TXEOF | \ ET_INTR_RXEOF | \ @@ -423,8 +387,8 @@ /* * RX ring position uses same layout */ -#define ET_RX_RING_POS_INDEX __BITS(9, 0) -#define ET_RX_RING_POS_WRAP __BIT(10) +#define ET_RX_RING_POS_INDEX_MASK 0x000003FF +#define ET_RX_RING_POS_WRAP 0x00000400 /* * PCI IDs diff --git a/sys/dev/et/if_etvar.h b/sys/dev/et/if_etvar.h index 9fdf775d8fd..2c092ab83ce 100644 --- a/sys/dev/et/if_etvar.h +++ b/sys/dev/et/if_etvar.h @@ -106,11 +106,11 @@ struct et_txdesc { uint32_t td_ctrl2; /* ET_TDCTRL2_ */ } __packed; -#define ET_TDCTRL1_LEN __BITS(15, 0) +#define ET_TDCTRL1_LEN_MASK 0x0000FFFF -#define ET_TDCTRL2_LAST_FRAG __BIT(0) -#define ET_TDCTRL2_FIRST_FRAG __BIT(1) -#define ET_TDCTRL2_INTR __BIT(2) +#define ET_TDCTRL2_LAST_FRAG 0x00000001 +#define ET_TDCTRL2_FIRST_FRAG 0x00000002 +#define ET_TDCTRL2_INTR 0x00000004 struct et_rxdesc { uint32_t rd_addr_lo; @@ -118,24 +118,28 @@ struct et_rxdesc { uint32_t rd_ctrl; /* ET_RDCTRL_ */ } __packed; -#define ET_RDCTRL_BUFIDX __BITS(9, 0) +#define ET_RDCTRL_BUFIDX_MASK 0x000003FF struct et_rxstat { uint32_t rxst_info1; uint32_t rxst_info2; /* ET_RXST_INFO2_ */ } __packed; -#define ET_RXST_INFO2_LEN __BITS(15, 0) -#define ET_RXST_INFO2_BUFIDX __BITS(25, 16) -#define ET_RXST_INFO2_RINGIDX __BITS(27, 26) +#define ET_RXST_INFO2_LEN_MASK 0x0000FFFF +#define ET_RXST_INFO2_LEN_SHIFT 0 +#define ET_RXST_INFO2_BUFIDX_MASK 0x03FF0000 +#define ET_RXST_INFO2_BUFIDX_SHIFT 16 +#define ET_RXST_INFO2_RINGIDX_MASK 0x0C000000 +#define ET_RXST_INFO2_RINGIDX_SHIFT 26 struct et_rxstatus { uint32_t rxs_ring; uint32_t rxs_stat_ring; /* ET_RXS_STATRING_ */ } __packed; -#define ET_RXS_STATRING_INDEX __BITS(27, 16) -#define ET_RXS_STATRING_WRAP __BIT(28) +#define ET_RXS_STATRING_INDEX_MASK 0x0FFF0000 +#define ET_RXS_STATRING_INDEX_SHIFT 16 +#define ET_RXS_STATRING_WRAP 0x10000000 struct et_dmamap_ctx { int nsegs; From 73e0051db9ef9f22f1e63035538121d96af3259d Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 21 Dec 2009 18:16:07 +0000 Subject: [PATCH 0921/2592] MFC r199550-199552: r199550: Remove support code for FreeBSD 6.x versions. r199551: Destroy driver mutex in device detach. r199552: Add MSI support. --- sys/dev/et/if_et.c | 55 ++++++++++++++++++++++++++++++++----------- sys/dev/et/if_etvar.h | 7 ++++-- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/sys/dev/et/if_et.c b/sys/dev/et/if_et.c index 302e51a02ef..e6e5d60e618 100644 --- a/sys/dev/et/if_et.c +++ b/sys/dev/et/if_et.c @@ -76,6 +76,10 @@ MODULE_DEPEND(et, pci, 1, 1, 1); MODULE_DEPEND(et, ether, 1, 1, 1); MODULE_DEPEND(et, miibus, 1, 1, 1); +/* Tunables. */ +static int msi_disable = 0; +TUNABLE_INT("hw.re.msi_disable", &msi_disable); + static int et_probe(device_t); static int et_attach(device_t); static int et_detach(device_t); @@ -230,7 +234,7 @@ et_attach(device_t dev) struct et_softc *sc; struct ifnet *ifp; uint8_t eaddr[ETHER_ADDR_LEN]; - int error; + int cap, error, msic; sc = device_get_softc(dev); sc->dev = dev; @@ -268,13 +272,38 @@ et_attach(device_t dev) sc->sc_mem_bt = rman_get_bustag(sc->sc_mem_res); sc->sc_mem_bh = rman_get_bushandle(sc->sc_mem_res); + msic = 0; + if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) == 0) { + sc->sc_expcap = cap; + sc->sc_flags |= ET_FLAG_PCIE; + msic = pci_msi_count(dev); + if (bootverbose) + device_printf(dev, "MSI count : %d\n", msic); + } + if (msic > 0 && msi_disable == 0) { + msic = 1; + if (pci_alloc_msi(dev, &msic) == 0) { + if (msic == 1) { + device_printf(dev, "Using %d MSI message\n", + msic); + sc->sc_flags |= ET_FLAG_MSI; + } else + pci_release_msi(dev); + } + } + /* * Allocate IRQ */ - sc->sc_irq_rid = 0; - sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, - &sc->sc_irq_rid, - RF_SHAREABLE | RF_ACTIVE); + if ((sc->sc_flags & ET_FLAG_MSI) == 0) { + sc->sc_irq_rid = 0; + sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &sc->sc_irq_rid, RF_SHAREABLE | RF_ACTIVE); + } else { + sc->sc_irq_rid = 1; + sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &sc->sc_irq_rid, RF_ACTIVE); + } if (sc->sc_irq_res == NULL) { device_printf(dev, "can't allocate irq\n"); error = ENXIO; @@ -322,14 +351,8 @@ et_attach(device_t dev) ether_ifattach(ifp, eaddr); callout_init_mtx(&sc->sc_tick, &sc->sc_mtx, 0); -#if __FreeBSD_version > 700030 error = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, et_intr, sc, &sc->sc_irq_handle); -#else - error = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_NET | INTR_MPSAFE, - et_intr, sc, &sc->sc_irq_handle); -#endif - + NULL, et_intr, sc, &sc->sc_irq_handle); if (error) { ether_ifdetach(ifp); device_printf(dev, "can't setup intr\n"); @@ -368,6 +391,8 @@ et_detach(device_t dev) bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid, sc->sc_irq_res); } + if ((sc->sc_flags & ET_FLAG_MSI) != 0) + pci_release_msi(dev); if (sc->sc_mem_res != NULL) { bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid, @@ -378,7 +403,8 @@ et_detach(device_t dev) if_free(sc->ifp); et_dma_free(dev); - /* XXX Destroy lock here */ + + mtx_destroy(&sc->sc_mtx); return 0; } @@ -1437,7 +1463,8 @@ et_chip_init(struct et_softc *sc) CSR_WRITE_4(sc, ET_LOOPBACK, 0); /* Clear MSI configure */ - CSR_WRITE_4(sc, ET_MSI_CFG, 0); + if ((sc->sc_flags & ET_FLAG_MSI) == 0) + CSR_WRITE_4(sc, ET_MSI_CFG, 0); /* Disable timer */ CSR_WRITE_4(sc, ET_TIMER, 0); diff --git a/sys/dev/et/if_etvar.h b/sys/dev/et/if_etvar.h index 2c092ab83ce..5077745d9de 100644 --- a/sys/dev/et/if_etvar.h +++ b/sys/dev/et/if_etvar.h @@ -238,6 +238,7 @@ struct et_softc { struct arpcom arpcom; int sc_if_flags; uint32_t sc_flags; /* ET_FLAG_ */ + int sc_expcap; int sc_mem_rid; @@ -277,7 +278,9 @@ struct et_softc { #define ET_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) #define ET_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) -#define ET_FLAG_TXRX_ENABLED 0x1 -#define ET_FLAG_JUMBO 0x2 +#define ET_FLAG_PCIE 0x0001 +#define ET_FLAG_MSI 0x0002 +#define ET_FLAG_TXRX_ENABLED 0x0100 +#define ET_FLAG_JUMBO 0x0200 #endif /* !_IF_ETVAR_H */ From d44acd73111bf3796a142ca2656b8d6f3c879f7b Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 21 Dec 2009 18:28:37 +0000 Subject: [PATCH 0922/2592] MFC r199553,199556 r199553: Remove extra spce at the EOL. r199556: style(9) --- sys/dev/et/if_et.c | 120 +++++++++++++++++++++--------------------- sys/dev/et/if_etreg.h | 10 ++-- sys/dev/et/if_etvar.h | 12 ++--- 3 files changed, 71 insertions(+), 71 deletions(-) diff --git a/sys/dev/et/if_et.c b/sys/dev/et/if_et.c index e6e5d60e618..0e11fd89a8c 100644 --- a/sys/dev/et/if_et.c +++ b/sys/dev/et/if_et.c @@ -222,10 +222,10 @@ et_probe(device_t dev) for (d = et_devices; d->desc != NULL; ++d) { if (vid == d->vid && did == d->did) { device_set_desc(dev, d->desc); - return 0; + return (0); } } - return ENXIO; + return (ENXIO); } static int @@ -267,7 +267,7 @@ et_attach(device_t dev) &sc->sc_mem_rid, RF_ACTIVE); if (sc->sc_mem_res == NULL) { device_printf(dev, "can't allocate IO memory\n"); - return ENXIO; + return (ENXIO); } sc->sc_mem_bt = rman_get_bustag(sc->sc_mem_res); sc->sc_mem_bh = rman_get_bushandle(sc->sc_mem_res); @@ -361,10 +361,10 @@ et_attach(device_t dev) et_add_sysctls(sc); - return 0; + return (0); fail: et_detach(dev); - return error; + return (error); } static int @@ -406,7 +406,7 @@ et_detach(device_t dev) mtx_destroy(&sc->sc_mtx); - return 0; + return (0); } static int @@ -417,7 +417,7 @@ et_shutdown(device_t dev) ET_LOCK(sc); et_stop(sc); ET_UNLOCK(sc); - return 0; + return (0); } static int @@ -460,7 +460,7 @@ et_miibus_readreg(device_t dev, int phy, int reg) back: /* Make sure that the current operation is stopped */ CSR_WRITE_4(sc, ET_MII_CMD, 0); - return ret; + return (ret); } static int @@ -499,7 +499,7 @@ et_miibus_writereg(device_t dev, int phy, int reg, int val0) /* Make sure that the current operation is stopped */ CSR_WRITE_4(sc, ET_MII_CMD, 0); - return 0; + return (0); } static void @@ -522,7 +522,7 @@ et_ifmedia_upd_locked(struct ifnet *ifp) } mii_mediachg(mii); - return 0; + return (0); } static int @@ -535,7 +535,7 @@ et_ifmedia_upd(struct ifnet *ifp) res = et_ifmedia_upd_locked(ifp); ET_UNLOCK(sc); - return res; + return (res); } static void @@ -590,7 +590,7 @@ et_bus_config(device_t dev) val = pci_read_config(dev, ET_PCIR_EEPROM_STATUS, 1); if (val & ET_PCIM_EEPROM_STATUS_ERROR) { device_printf(dev, "EEPROM status error 0x%02x\n", val); - return ENXIO; + return (ENXIO); } /* TODO: LED */ @@ -644,7 +644,7 @@ et_bus_config(device_t dev) val |= ET_PCIV_DEVICE_CTRL_RRSZ_2K; pci_write_config(dev, ET_PCIR_DEVICE_CTRL, val, 2); - return 0; + return (0); } static void @@ -716,7 +716,7 @@ et_dma_alloc(device_t dev) 0, NULL, NULL, &sc->sc_dtag); if (error) { device_printf(dev, "can't create DMA tag\n"); - return error; + return (error); } /* @@ -727,7 +727,7 @@ et_dma_alloc(device_t dev) &tx_ring->tr_paddr, &tx_ring->tr_dmap); if (error) { device_printf(dev, "can't create TX ring DMA stuffs\n"); - return error; + return (error); } /* @@ -738,7 +738,7 @@ et_dma_alloc(device_t dev) &txsd->txsd_paddr, &txsd->txsd_dmap); if (error) { device_printf(dev, "can't create TX status DMA stuffs\n"); - return error; + return (error); } /* @@ -758,7 +758,7 @@ et_dma_alloc(device_t dev) if (error) { device_printf(dev, "can't create DMA stuffs for " "the %d RX ring\n", i); - return error; + return (error); } rx_ring->rr_posreg = rx_ring_posreg[i]; } @@ -772,7 +772,7 @@ et_dma_alloc(device_t dev) &rxst_ring->rsr_paddr, &rxst_ring->rsr_dmap); if (error) { device_printf(dev, "can't create RX stat ring DMA stuffs\n"); - return error; + return (error); } /* @@ -784,7 +784,7 @@ et_dma_alloc(device_t dev) &rxsd->rxsd_paddr, &rxsd->rxsd_dmap); if (error) { device_printf(dev, "can't create RX status DMA stuffs\n"); - return error; + return (error); } /* @@ -792,9 +792,9 @@ et_dma_alloc(device_t dev) */ error = et_dma_mbuf_create(dev); if (error) - return error; + return (error); - return 0; + return (0); } static void @@ -873,7 +873,7 @@ et_dma_mbuf_create(device_t dev) BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_mbuf_dtag); if (error) { device_printf(dev, "can't create mbuf DMA tag\n"); - return error; + return (error); } /* @@ -884,7 +884,7 @@ et_dma_mbuf_create(device_t dev) device_printf(dev, "can't create spare mbuf DMA map\n"); bus_dma_tag_destroy(sc->sc_mbuf_dtag); sc->sc_mbuf_dtag = NULL; - return error; + return (error); } /* @@ -903,7 +903,7 @@ et_dma_mbuf_create(device_t dev) "for %d RX ring\n", j, i); rx_done[i] = j; et_dma_mbuf_destroy(dev, 0, rx_done); - return error; + return (error); } } rx_done[i] = ET_RX_NDESC; @@ -922,11 +922,11 @@ et_dma_mbuf_create(device_t dev) device_printf(dev, "can't create %d TX mbuf " "DMA map\n", i); et_dma_mbuf_destroy(dev, i, rx_done); - return error; + return (error); } } - return 0; + return (0); } static void @@ -991,7 +991,7 @@ et_dma_mem_create(device_t dev, bus_size_t size, bus_dma_tag_t *dtag, 0, NULL, NULL, dtag); if (error) { device_printf(dev, "can't create DMA tag\n"); - return error; + return (error); } error = bus_dmamem_alloc(*dtag, addr, BUS_DMA_WAITOK | BUS_DMA_ZERO, @@ -1000,7 +1000,7 @@ et_dma_mem_create(device_t dev, bus_size_t size, bus_dma_tag_t *dtag, device_printf(dev, "can't allocate DMA mem\n"); bus_dma_tag_destroy(*dtag); *dtag = NULL; - return error; + return (error); } error = bus_dmamap_load(*dtag, *dmap, *addr, size, @@ -1010,9 +1010,9 @@ et_dma_mem_create(device_t dev, bus_size_t size, bus_dma_tag_t *dtag, bus_dmamem_free(*dtag, *addr, *dmap); bus_dma_tag_destroy(*dtag); *dtag = NULL; - return error; + return (error); } - return 0; + return (0); } static void @@ -1230,7 +1230,7 @@ et_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) error = ether_ioctl(ifp, cmd, data); break; } - return error; + return (error); } static void @@ -1309,9 +1309,9 @@ et_stop_rxdma(struct et_softc *sc) DELAY(5); if ((CSR_READ_4(sc, ET_RXDMA_CTRL) & ET_RXDMA_CTRL_HALTED) == 0) { if_printf(sc->ifp, "can't stop RX DMA engine\n"); - return ETIMEDOUT; + return (ETIMEDOUT); } - return 0; + return (0); } static int @@ -1319,7 +1319,7 @@ et_stop_txdma(struct et_softc *sc) { CSR_WRITE_4(sc, ET_TXDMA_CTRL, ET_TXDMA_CTRL_HALT | ET_TXDMA_CTRL_SINGLE_EPKT); - return 0; + return (0); } static void @@ -1358,7 +1358,7 @@ et_free_rx_ring(struct et_softc *sc) struct et_rxbuf *rb = &rbd->rbd_buf[i]; if (rb->rb_mbuf != NULL) { - bus_dmamap_unload(sc->sc_mbuf_dtag, + bus_dmamap_unload(sc->sc_mbuf_dtag, rb->rb_dmap); m_freem(rb->rb_mbuf); rb->rb_mbuf = NULL; @@ -1484,14 +1484,14 @@ et_chip_init(struct et_softc *sc) /* Initialize RX DMA engine */ error = et_init_rxdma(sc); if (error) - return error; + return (error); /* Initialize TX DMA engine */ error = et_init_txdma(sc); if (error) - return error; + return (error); - return 0; + return (0); } static int @@ -1512,7 +1512,7 @@ et_init_tx_ring(struct et_softc *sc) bzero(txsd->txsd_status, sizeof(uint32_t)); bus_dmamap_sync(txsd->txsd_dtag, txsd->txsd_dmap, BUS_DMASYNC_PREWRITE); - return 0; + return (0); } static int @@ -1531,7 +1531,7 @@ et_init_rx_ring(struct et_softc *sc) if (error) { if_printf(sc->ifp, "%d ring %d buf, " "newbuf failed: %d\n", n, i, error); - return error; + return (error); } } } @@ -1544,7 +1544,7 @@ et_init_rx_ring(struct et_softc *sc) bus_dmamap_sync(rxst_ring->rsr_dtag, rxst_ring->rsr_dmap, BUS_DMASYNC_PREWRITE); - return 0; + return (0); } static void @@ -1578,7 +1578,7 @@ et_init_rxdma(struct et_softc *sc) error = et_stop_rxdma(sc); if (error) { if_printf(sc->ifp, "can't init RX DMA engine\n"); - return error; + return (error); } /* @@ -1634,7 +1634,7 @@ et_init_rxdma(struct et_softc *sc) CSR_WRITE_4(sc, ET_RX_INTR_NPKTS, sc->sc_rx_intr_npkts); CSR_WRITE_4(sc, ET_RX_INTR_DELAY, sc->sc_rx_intr_delay); - return 0; + return (0); } static int @@ -1647,7 +1647,7 @@ et_init_txdma(struct et_softc *sc) error = et_stop_txdma(sc); if (error) { if_printf(sc->ifp, "can't init TX DMA engine\n"); - return error; + return (error); } /* @@ -1669,7 +1669,7 @@ et_init_txdma(struct et_softc *sc) tx_ring->tr_ready_index = 0; tx_ring->tr_ready_wrap = 0; - return 0; + return (0); } static void @@ -1839,16 +1839,16 @@ et_start_rxdma(struct et_softc *sc) if (CSR_READ_4(sc, ET_RXDMA_CTRL) & ET_RXDMA_CTRL_HALTED) { if_printf(sc->ifp, "can't start RX DMA engine\n"); - return ETIMEDOUT; + return (ETIMEDOUT); } - return 0; + return (0); } static int et_start_txdma(struct et_softc *sc) { CSR_WRITE_4(sc, ET_TXDMA_CTRL, ET_TXDMA_CTRL_SINGLE_EPKT); - return 0; + return (0); } static int @@ -1881,7 +1881,7 @@ et_enable_txrx(struct et_softc *sc, int media_upd) } if (i == NRETRY) { if_printf(ifp, "can't enable RX/TX\n"); - return 0; + return (0); } sc->sc_flags |= ET_FLAG_TXRX_ENABLED; @@ -1892,13 +1892,13 @@ et_enable_txrx(struct et_softc *sc, int media_upd) */ error = et_start_rxdma(sc); if (error) - return error; + return (error); error = et_start_txdma(sc); if (error) - return error; + return (error); - return 0; + return (0); } static void @@ -2130,7 +2130,7 @@ back: m_freem(m); *m0 = NULL; } - return error; + return (error); } static void @@ -2218,13 +2218,13 @@ et_tick(void *xsc) static int et_newbuf_cluster(struct et_rxbuf_data *rbd, int buf_idx, int init) { - return et_newbuf(rbd, buf_idx, init, MCLBYTES); + return (et_newbuf(rbd, buf_idx, init, MCLBYTES)); } static int et_newbuf_hdr(struct et_rxbuf_data *rbd, int buf_idx, int init) { - return et_newbuf(rbd, buf_idx, init, MHLEN); + return (et_newbuf(rbd, buf_idx, init, MHLEN)); } static int @@ -2248,7 +2248,7 @@ et_newbuf(struct et_rxbuf_data *rbd, int buf_idx, int init, int len0) if (init) { if_printf(sc->ifp, "m_getl failed, size %d\n", len0); - return error; + return (error); } else { goto back; } @@ -2275,7 +2275,7 @@ et_newbuf(struct et_rxbuf_data *rbd, int buf_idx, int init, int len0) if (init) { if_printf(sc->ifp, "can't load RX mbuf\n"); - return error; + return (error); } else { goto back; } @@ -2299,7 +2299,7 @@ et_newbuf(struct et_rxbuf_data *rbd, int buf_idx, int init, int len0) error = 0; back: et_setup_rxdesc(rbd, buf_idx, rb->rb_paddr); - return error; + return (error); } /* @@ -2349,7 +2349,7 @@ et_sysctl_rx_intr_npkts(SYSCTL_HANDLER_ARGS) sc->sc_rx_intr_npkts = v; } back: - return error; + return (error); } static int @@ -2374,7 +2374,7 @@ et_sysctl_rx_intr_delay(SYSCTL_HANDLER_ARGS) sc->sc_rx_intr_delay = v; } back: - return error; + return (error); } static void diff --git a/sys/dev/et/if_etreg.h b/sys/dev/et/if_etreg.h index 637c1941627..1f6f48fec1a 100644 --- a/sys/dev/et/if_etreg.h +++ b/sys/dev/et/if_etreg.h @@ -1,13 +1,13 @@ /*- * Copyright (c) 2007 The DragonFly Project. All rights reserved. - * + * * This code is derived from software contributed to The DragonFly Project * by Sepherosa Ziehau - * + * * 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 @@ -17,7 +17,7 @@ * 3. Neither the name of The DragonFly Project 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 @@ -30,7 +30,7 @@ * 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. - * + * * $DragonFly: src/sys/dev/netif/et/if_etreg.h,v 1.3 2007/10/23 14:28:42 sephe Exp $ * $FreeBSD$ */ diff --git a/sys/dev/et/if_etvar.h b/sys/dev/et/if_etvar.h index 5077745d9de..198d20cb28b 100644 --- a/sys/dev/et/if_etvar.h +++ b/sys/dev/et/if_etvar.h @@ -1,13 +1,13 @@ /*- * Copyright (c) 2007 The DragonFly Project. All rights reserved. - * + * * This code is derived from software contributed to The DragonFly Project * by Sepherosa Ziehau - * + * * 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 @@ -17,7 +17,7 @@ * 3. Neither the name of The DragonFly Project 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 @@ -30,7 +30,7 @@ * 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. - * + * * $DragonFly: src/sys/dev/netif/et/if_etvar.h,v 1.4 2007/10/23 14:28:42 sephe Exp $ * $FreeBSD$ */ @@ -40,7 +40,7 @@ /* DragonFly compatibility */ #define EVL_ENCAPLEN ETHER_VLAN_ENCAP_LEN - + /* * Allocate the right type of mbuf for the desired total length. */ From a7053a556886f6bcfa6bf1cda04ad0c432ec0e0c Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 21 Dec 2009 18:34:18 +0000 Subject: [PATCH 0923/2592] MFC r199558,199561 r199558: Use bus_{read,write}_4 rather than bus_space_{read,write}_4. r199561: Use capability pointer to access PCIe registers rather than directly access them at fixed address. Frequently the register offset could be changed if additional PCI capabilities are added to controller. One odd thing is ET_PCIR_L0S_L1_LATENCY register. I think it's PCIe link capabilities register but the location of the register does not match with PCIe capability pointer + offset. I'm not sure it's shadow register of PCIe link capabilities register. --- sys/dev/et/if_et.c | 46 ++++++++++++++++++++++++------------------- sys/dev/et/if_etvar.h | 6 ++---- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/sys/dev/et/if_et.c b/sys/dev/et/if_et.c index 0e11fd89a8c..b75d3e01f70 100644 --- a/sys/dev/et/if_et.c +++ b/sys/dev/et/if_et.c @@ -142,7 +142,7 @@ static int et_stop_rxdma(struct et_softc *); static int et_stop_txdma(struct et_softc *); static int et_enable_txrx(struct et_softc *, int); static void et_reset(struct et_softc *); -static int et_bus_config(device_t); +static int et_bus_config(struct et_softc *); static void et_get_eaddr(device_t, uint8_t[]); static void et_setmulti(struct et_softc *); static void et_tick(void *); @@ -269,8 +269,6 @@ et_attach(device_t dev) device_printf(dev, "can't allocate IO memory\n"); return (ENXIO); } - sc->sc_mem_bt = rman_get_bustag(sc->sc_mem_res); - sc->sc_mem_bh = rman_get_bushandle(sc->sc_mem_res); msic = 0; if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) == 0) { @@ -310,7 +308,7 @@ et_attach(device_t dev) goto fail; } - error = et_bus_config(dev); + error = et_bus_config(sc); if (error) goto fail; @@ -577,7 +575,7 @@ et_stop(struct et_softc *sc) } static int -et_bus_config(device_t dev) +et_bus_config(struct et_softc *sc) { uint32_t val, max_plsz; uint16_t ack_latency, replay_timer; @@ -586,21 +584,25 @@ et_bus_config(device_t dev) * Test whether EEPROM is valid * NOTE: Read twice to get the correct value */ - pci_read_config(dev, ET_PCIR_EEPROM_STATUS, 1); - val = pci_read_config(dev, ET_PCIR_EEPROM_STATUS, 1); + pci_read_config(sc->dev, ET_PCIR_EEPROM_STATUS, 1); + val = pci_read_config(sc->dev, ET_PCIR_EEPROM_STATUS, 1); if (val & ET_PCIM_EEPROM_STATUS_ERROR) { - device_printf(dev, "EEPROM status error 0x%02x\n", val); + device_printf(sc->dev, "EEPROM status error 0x%02x\n", val); return (ENXIO); } /* TODO: LED */ + if ((sc->sc_flags & ET_FLAG_PCIE) == 0) + return (0); + /* * Configure ACK latency and replay timer according to * max playload size */ - val = pci_read_config(dev, ET_PCIR_DEVICE_CAPS, 4); - max_plsz = val & ET_PCIM_DEVICE_CAPS_MAX_PLSZ; + val = pci_read_config(sc->dev, + sc->sc_expcap + PCIR_EXPRESS_DEVICE_CAP, 4); + max_plsz = val & PCIM_EXP_CAP_MAX_PAYLOAD; switch (max_plsz) { case ET_PCIV_DEVICE_CAPS_PLSZ_128: @@ -614,35 +616,39 @@ et_bus_config(device_t dev) break; default: - ack_latency = pci_read_config(dev, ET_PCIR_ACK_LATENCY, 2); - replay_timer = pci_read_config(dev, ET_PCIR_REPLAY_TIMER, 2); - device_printf(dev, "ack latency %u, replay timer %u\n", + ack_latency = pci_read_config(sc->dev, ET_PCIR_ACK_LATENCY, 2); + replay_timer = pci_read_config(sc->dev, + ET_PCIR_REPLAY_TIMER, 2); + device_printf(sc->dev, "ack latency %u, replay timer %u\n", ack_latency, replay_timer); break; } if (ack_latency != 0) { - pci_write_config(dev, ET_PCIR_ACK_LATENCY, ack_latency, 2); - pci_write_config(dev, ET_PCIR_REPLAY_TIMER, replay_timer, 2); + pci_write_config(sc->dev, ET_PCIR_ACK_LATENCY, ack_latency, 2); + pci_write_config(sc->dev, ET_PCIR_REPLAY_TIMER, replay_timer, + 2); } /* * Set L0s and L1 latency timer to 2us */ - val = pci_read_config(dev, ET_PCIR_L0S_L1_LATENCY, 4); + val = pci_read_config(sc->dev, ET_PCIR_L0S_L1_LATENCY, 4); val &= ~(PCIM_LINK_CAP_L0S_EXIT | PCIM_LINK_CAP_L1_EXIT); /* L0s exit latency : 2us */ val |= 0x00005000; /* L1 exit latency : 2us */ val |= 0x00028000; - pci_write_config(dev, ET_PCIR_L0S_L1_LATENCY, val, 4); + pci_write_config(sc->dev, ET_PCIR_L0S_L1_LATENCY, val, 4); /* * Set max read request size to 2048 bytes */ - val = pci_read_config(dev, ET_PCIR_DEVICE_CTRL, 2); - val &= ~ET_PCIM_DEVICE_CTRL_MAX_RRSZ; + val = pci_read_config(sc->dev, + sc->sc_expcap + PCIR_EXPRESS_DEVICE_CTL, 2); + val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST; val |= ET_PCIV_DEVICE_CTRL_RRSZ_2K; - pci_write_config(dev, ET_PCIR_DEVICE_CTRL, val, 2); + pci_write_config(sc->dev, + sc->sc_expcap + PCIR_EXPRESS_DEVICE_CTL, val, 2); return (0); } diff --git a/sys/dev/et/if_etvar.h b/sys/dev/et/if_etvar.h index 198d20cb28b..10c0e50559f 100644 --- a/sys/dev/et/if_etvar.h +++ b/sys/dev/et/if_etvar.h @@ -92,9 +92,9 @@ m_getl(int len, int how, int type, int flags, int *psize) #define ET_JUMBO_MEM_SIZE (ET_JSLOTS * ET_JLEN) #define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4((sc)->sc_mem_bt, (sc)->sc_mem_bh, (reg), (val)) + bus_write_4((sc)->sc_mem_res, (reg), (val)) #define CSR_READ_4(sc, reg) \ - bus_space_read_4((sc)->sc_mem_bt, (sc)->sc_mem_bh, (reg)) + bus_read_4((sc)->sc_mem_res, (reg)) #define ET_ADDR_HI(addr) ((uint64_t) (addr) >> 32) #define ET_ADDR_LO(addr) ((uint64_t) (addr) & 0xffffffff) @@ -229,8 +229,6 @@ struct et_softc { device_t dev; struct mtx sc_mtx; device_t sc_miibus; - bus_space_handle_t sc_mem_bh; - bus_space_tag_t sc_mem_bt; void *sc_irq_handle; struct resource *sc_irq_res; struct resource *sc_mem_res; From 83e8bd69b3aa39576eb277f6f8a924b9d98c76bf Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 21 Dec 2009 18:52:38 +0000 Subject: [PATCH 0924/2592] MFC r199563,199608-199613 r199563: Fix copy & paste error and remove extra space before colon. r199608: Remove unnecessary structure packing. r199609: Add initial endianness support. It seems the controller supports both big-endian and little-endian format in descriptors for Rx path but I couldn't find equivalent feature in Tx path. So just stick to little-endian for now. r199610: Because we know received bytes including CRC there is no reason to call m_adj(9). The controller also seems to have a capability to strip CRC bytes but I failed to activate this feature except for loopback traffic. r199611: Add IPv4/TCP/UDP Tx checksum offloading support. It seems the controller also has support for IP/TCP checksum offloading for Rx path. But I failed to find to way to enable Rx MAC to compute the checksum of received frames. r199612: Add __FBSDID. r199613: Only Tx checksum offloading is supported now. Remove experimental code sneaked in r199611. --- sys/dev/et/if_et.c | 77 ++++++++++++++++++++++++++++--------------- sys/dev/et/if_etvar.h | 20 ++++++++--- 2 files changed, 67 insertions(+), 30 deletions(-) diff --git a/sys/dev/et/if_et.c b/sys/dev/et/if_et.c index b75d3e01f70..77ee4ab8d49 100644 --- a/sys/dev/et/if_et.c +++ b/sys/dev/et/if_et.c @@ -32,9 +32,11 @@ * SUCH DAMAGE. * * $DragonFly: src/sys/dev/netif/et/if_et.c,v 1.10 2008/05/18 07:47:14 sephe Exp $ - * $FreeBSD$ */ +#include +__FBSDID("$FreeBSD$"); + #include #include #include @@ -78,7 +80,9 @@ MODULE_DEPEND(et, miibus, 1, 1, 1); /* Tunables. */ static int msi_disable = 0; -TUNABLE_INT("hw.re.msi_disable", &msi_disable); +TUNABLE_INT("hw.et.msi_disable", &msi_disable); + +#define ET_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP) static int et_probe(device_t); static int et_attach(device_t); @@ -276,7 +280,7 @@ et_attach(device_t dev) sc->sc_flags |= ET_FLAG_PCIE; msic = pci_msi_count(dev); if (bootverbose) - device_printf(dev, "MSI count : %d\n", msic); + device_printf(dev, "MSI count: %d\n", msic); } if (msic > 0 && msi_disable == 0) { msic = 1; @@ -332,7 +336,7 @@ et_attach(device_t dev) ifp->if_ioctl = et_ioctl; ifp->if_start = et_start; ifp->if_mtu = ETHERMTU; - ifp->if_capabilities = IFCAP_VLAN_MTU; + ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_MTU; ifp->if_capenable = ifp->if_capabilities; IFQ_SET_MAXLEN(&ifp->if_snd, ET_TX_NDESC); IFQ_SET_READY(&ifp->if_snd); @@ -1175,7 +1179,7 @@ et_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct et_softc *sc = ifp->if_softc; struct mii_data *mii = device_get_softc(sc->sc_miibus); struct ifreq *ifr = (struct ifreq *)data; - int error = 0, max_framelen; + int error = 0, mask, max_framelen; /* XXX LOCKSUSED */ switch (cmd) { @@ -1232,6 +1236,20 @@ et_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } break; + case SIOCSIFCAP: + ET_LOCK(sc); + mask = ifr->ifr_reqcap ^ ifp->if_capenable; + if ((mask & IFCAP_TXCSUM) != 0 && + (IFCAP_TXCSUM & ifp->if_capabilities) != 0) { + ifp->if_capenable ^= IFCAP_TXCSUM; + if ((IFCAP_TXCSUM & ifp->if_capenable) != 0) + ifp->if_hwassist |= ET_CSUM_FEATURES; + else + ifp->if_hwassist &= ~ET_CSUM_FEATURES; + } + ET_UNLOCK(sc); + break; + default: error = ether_ioctl(ifp, cmd, data); break; @@ -1913,7 +1931,7 @@ et_rxeof(struct et_softc *sc) struct ifnet *ifp; struct et_rxstatus_data *rxsd; struct et_rxstat_ring *rxst_ring; - uint32_t rxs_stat_ring; + uint32_t rxs_stat_ring, rxst_info2; int rxst_wrap, rxst_index; ET_LOCK_ASSERT(sc); @@ -1929,7 +1947,7 @@ et_rxeof(struct et_softc *sc) bus_dmamap_sync(rxst_ring->rsr_dtag, rxst_ring->rsr_dmap, BUS_DMASYNC_POSTREAD); - rxs_stat_ring = rxsd->rxsd_status->rxs_stat_ring; + rxs_stat_ring = le32toh(rxsd->rxsd_status->rxs_stat_ring); rxst_wrap = (rxs_stat_ring & ET_RXS_STATRING_WRAP) ? 1 : 0; rxst_index = (rxs_stat_ring & ET_RXS_STATRING_INDEX_MASK) >> ET_RXS_STATRING_INDEX_SHIFT; @@ -1945,12 +1963,12 @@ et_rxeof(struct et_softc *sc) MPASS(rxst_ring->rsr_index < ET_RX_NSTAT); st = &rxst_ring->rsr_stat[rxst_ring->rsr_index]; - - buflen = (st->rxst_info2 & ET_RXST_INFO2_LEN_MASK) >> + rxst_info2 = le32toh(st->rxst_info2); + buflen = (rxst_info2 & ET_RXST_INFO2_LEN_MASK) >> ET_RXST_INFO2_LEN_SHIFT; - buf_idx = (st->rxst_info2 & ET_RXST_INFO2_BUFIDX_MASK) >> + buf_idx = (rxst_info2 & ET_RXST_INFO2_BUFIDX_MASK) >> ET_RXST_INFO2_BUFIDX_SHIFT; - ring_idx = (st->rxst_info2 & ET_RXST_INFO2_RINGIDX_MASK) >> + ring_idx = (rxst_info2 & ET_RXST_INFO2_RINGIDX_MASK) >> ET_RXST_INFO2_RINGIDX_SHIFT; if (++rxst_ring->rsr_index == ET_RX_NSTAT) { @@ -1982,11 +2000,9 @@ et_rxeof(struct et_softc *sc) m = NULL; ifp->if_ierrors++; } else { - m->m_pkthdr.len = m->m_len = buflen; + m->m_pkthdr.len = m->m_len = + buflen - ETHER_CRC_LEN; m->m_pkthdr.rcvif = ifp; - - m_adj(m, -ETHER_CRC_LEN); - ifp->if_ipackets++; ET_UNLOCK(sc); ifp->if_input(ifp, m); @@ -2028,7 +2044,7 @@ et_encap(struct et_softc *sc, struct mbuf **m0) struct et_txdesc *td; bus_dmamap_t map; int error, maxsegs, first_idx, last_idx, i; - uint32_t tx_ready_pos, last_td_ctrl2; + uint32_t csum_flags, tx_ready_pos, last_td_ctrl2; maxsegs = ET_TX_NDESC - tbd->tbd_used; if (maxsegs > ET_NSEG_MAX) @@ -2090,20 +2106,29 @@ et_encap(struct et_softc *sc, struct mbuf **m0) last_td_ctrl2 |= ET_TDCTRL2_INTR; } + csum_flags = 0; + if ((m->m_pkthdr.csum_flags & ET_CSUM_FEATURES) != 0) { + if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0) + csum_flags |= ET_TDCTRL2_CSUM_IP; + if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0) + csum_flags |= ET_TDCTRL2_CSUM_UDP; + else if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0) + csum_flags |= ET_TDCTRL2_CSUM_TCP; + } last_idx = -1; for (i = 0; i < ctx.nsegs; ++i) { int idx; idx = (first_idx + i) % ET_TX_NDESC; td = &tx_ring->tr_desc[idx]; - td->td_addr_hi = ET_ADDR_HI(segs[i].ds_addr); - td->td_addr_lo = ET_ADDR_LO(segs[i].ds_addr); - td->td_ctrl1 = segs[i].ds_len & ET_TDCTRL1_LEN_MASK; - + td->td_addr_hi = htole32(ET_ADDR_HI(segs[i].ds_addr)); + td->td_addr_lo = htole32(ET_ADDR_LO(segs[i].ds_addr)); + td->td_ctrl1 = htole32(segs[i].ds_len & ET_TDCTRL1_LEN_MASK); if (i == ctx.nsegs - 1) { /* Last frag */ - td->td_ctrl2 = last_td_ctrl2; + td->td_ctrl2 = htole32(last_td_ctrl2 | csum_flags); last_idx = idx; - } + } else + td->td_ctrl2 = htole32(csum_flags); MPASS(tx_ring->tr_ready_index < ET_TX_NDESC); if (++tx_ring->tr_ready_index == ET_TX_NDESC) { @@ -2112,7 +2137,7 @@ et_encap(struct et_softc *sc, struct mbuf **m0) } } td = &tx_ring->tr_desc[first_idx]; - td->td_ctrl2 |= ET_TDCTRL2_FIRST_FRAG; /* First frag */ + td->td_ctrl2 |= htole32(ET_TDCTRL2_FIRST_FRAG); /* First frag */ MPASS(last_idx >= 0); tbd->tbd_buf[first_idx].tb_dmap = tbd->tbd_buf[last_idx].tb_dmap; @@ -2424,9 +2449,9 @@ et_setup_rxdesc(struct et_rxbuf_data *rbd, int buf_idx, bus_addr_t paddr) MPASS(buf_idx < ET_RX_NDESC); desc = &rx_ring->rr_desc[buf_idx]; - desc->rd_addr_hi = ET_ADDR_HI(paddr); - desc->rd_addr_lo = ET_ADDR_LO(paddr); - desc->rd_ctrl = buf_idx & ET_RDCTRL_BUFIDX_MASK; + desc->rd_addr_hi = htole32(ET_ADDR_HI(paddr)); + desc->rd_addr_lo = htole32(ET_ADDR_LO(paddr)); + desc->rd_ctrl = htole32(buf_idx & ET_RDCTRL_BUFIDX_MASK); bus_dmamap_sync(rx_ring->rr_dtag, rx_ring->rr_dmap, BUS_DMASYNC_PREWRITE); diff --git a/sys/dev/et/if_etvar.h b/sys/dev/et/if_etvar.h index 10c0e50559f..54932ca1501 100644 --- a/sys/dev/et/if_etvar.h +++ b/sys/dev/et/if_etvar.h @@ -104,26 +104,38 @@ struct et_txdesc { uint32_t td_addr_lo; uint32_t td_ctrl1; /* ET_TDCTRL1_ */ uint32_t td_ctrl2; /* ET_TDCTRL2_ */ -} __packed; +}; #define ET_TDCTRL1_LEN_MASK 0x0000FFFF #define ET_TDCTRL2_LAST_FRAG 0x00000001 #define ET_TDCTRL2_FIRST_FRAG 0x00000002 #define ET_TDCTRL2_INTR 0x00000004 +#define ET_TDCTRL2_CTRL_WORD 0x00000008 +#define ET_TDCTRL2_HDX_BACKP 0x00000010 +#define ET_TDCTRL2_XMIT_PAUSE 0x00000020 +#define ET_TDCTRL2_FRAME_ERR 0x00000040 +#define ET_TDCTRL2_NO_CRC 0x00000080 +#define ET_TDCTRL2_MAC_OVRRD 0x00000100 +#define ET_TDCTRL2_PAD_PACKET 0x00000200 +#define ET_TDCTRL2_JUMBO_PACKET 0x00000400 +#define ET_TDCTRL2_INS_VLAN 0x00000800 +#define ET_TDCTRL2_CSUM_IP 0x00001000 +#define ET_TDCTRL2_CSUM_TCP 0x00002000 +#define ET_TDCTRL2_CSUM_UDP 0x00004000 struct et_rxdesc { uint32_t rd_addr_lo; uint32_t rd_addr_hi; uint32_t rd_ctrl; /* ET_RDCTRL_ */ -} __packed; +}; #define ET_RDCTRL_BUFIDX_MASK 0x000003FF struct et_rxstat { uint32_t rxst_info1; uint32_t rxst_info2; /* ET_RXST_INFO2_ */ -} __packed; +}; #define ET_RXST_INFO2_LEN_MASK 0x0000FFFF #define ET_RXST_INFO2_LEN_SHIFT 0 @@ -135,7 +147,7 @@ struct et_rxstat { struct et_rxstatus { uint32_t rxs_ring; uint32_t rxs_stat_ring; /* ET_RXS_STATRING_ */ -} __packed; +}; #define ET_RXS_STATRING_INDEX_MASK 0x0FFF0000 #define ET_RXS_STATRING_INDEX_SHIFT 16 From 9624f980b175df471eafa6bde9556b75e130a00b Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Mon, 21 Dec 2009 20:17:34 +0000 Subject: [PATCH 0925/2592] MFC: r200544 Set ATA_CHECKS_CABLE when appropriate. Reviewed by: mav --- sys/dev/ata/chipsets/ata-amd.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/sys/dev/ata/chipsets/ata-amd.c b/sys/dev/ata/chipsets/ata-amd.c index 1cf9ac073c4..22ca546786f 100644 --- a/sys/dev/ata/chipsets/ata-amd.c +++ b/sys/dev/ata/chipsets/ata-amd.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include /* local prototypes */ +static int ata_amd_ch_attach(device_t dev); static int ata_amd_chipinit(device_t dev); static int ata_amd_setmode(device_t dev, int target, int mode); @@ -59,7 +60,6 @@ static int ata_amd_setmode(device_t dev, int target, int mode); #define AMD_BUG 0x01 #define AMD_CABLE 0x02 - /* * American Micro Devices (AMD) chipset support functions */ @@ -100,6 +100,7 @@ ata_amd_chipinit(device_t dev) else pci_write_config(dev, 0x41, pci_read_config(dev, 0x41, 1) | 0xf0, 1); + ctlr->ch_attach = ata_amd_ch_attach; ctlr->setmode = ata_amd_setmode; return 0; } @@ -137,4 +138,19 @@ ata_amd_setmode(device_t dev, int target, int mode) return (mode); } +static int +ata_amd_ch_attach(device_t dev) +{ + struct ata_pci_controller *ctlr; + struct ata_channel *ch; + int error; + + ctlr = device_get_softc(device_get_parent(dev)); + ch = device_get_softc(dev); + error = ata_pci_ch_attach(dev); + if (ctlr->chip->cfg1 & AMD_CABLE) + ch->flags |= ATA_CHECKS_CABLE; + return (error); +} + ATA_DECLARE_DRIVER(ata_amd); From eb058880c458690c212e2557d0176855c0ea7d58 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Tue, 22 Dec 2009 13:45:29 +0000 Subject: [PATCH 0926/2592] MFC r200589: cpuset(2): fix a typo and a markup error in the man page --- lib/libc/sys/cpuset.2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/sys/cpuset.2 b/lib/libc/sys/cpuset.2 index c07f8d9a781..fb9a7709cd2 100644 --- a/lib/libc/sys/cpuset.2 +++ b/lib/libc/sys/cpuset.2 @@ -96,7 +96,7 @@ The .Fa which argument may have the following values: .Bl -column CPU_WHICH_CPUSET -offset indent -.It Dv CPU_WHICH_TID Ta "id is lpwid_t (thread id)" +.It Dv CPU_WHICH_TID Ta "id is lwpid_t (thread id)" .It Dv CPU_WHICH_PID Ta "id is pid_t (process id)" .It Dv CPU_WHICH_CPUSET Ta "id is a cpusetid_t (cpuset id)" .It Dv CPU_WHICH_IRQ Ta "id is an irq number" @@ -209,7 +209,7 @@ The calling process did not have the credentials required to complete the operation. .It Bq Er ENFILE There was no free -.Fn cpusetid_t +.Ft cpusetid_t for allocation. .El .Sh SEE ALSO From 262cd96817d660c6ad032458288c7a514374d051 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 22 Dec 2009 14:58:23 +0000 Subject: [PATCH 0927/2592] MFC 200514: Remove comment claiming that building acpi into the kernel is deprecated. --- sys/i386/conf/NOTES | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index cd5951b6db2..c4d24d71016 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -463,9 +463,6 @@ device tdfx_linux # Enable Linuxulator support # kernel environment variables to select initial debugging levels for the # Intel ACPICA code. (Note that the Intel code must also have USE_DEBUGGER # defined when it is built). -# -# Note that building ACPI into the kernel is deprecated; the module is -# normally loaded automatically by the loader. device acpi options ACPI_DEBUG From e87bb38419d38e9a221d7ae84bfd6e8a90f06624 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 22 Dec 2009 19:56:35 +0000 Subject: [PATCH 0928/2592] MFC r200218: - Cleanup kernel messages, mostly PMP. - Took references on devices, while PMP reinitializes them, to not let them go and distort freeze reference counting. --- sys/cam/ata/ata_all.c | 6 ++++-- sys/cam/ata/ata_pmp.c | 26 +++++++++++++++++--------- sys/cam/ata/ata_xpt.c | 5 ++--- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index 588ef097496..c433f02b114 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -256,8 +256,10 @@ ata_print_ident(struct ata_params *ident_data) sizeof(product)); cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision), sizeof(revision)); - printf("<%s %s> ATA/ATAPI-%d", - product, revision, ata_version(ident_data->version_major)); + printf("<%s %s> %s-%d", + product, revision, + (ident_data->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA", + ata_version(ident_data->version_major)); if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) { if (ident_data->satacapabilities & ATA_SATA_GEN3) printf(" SATA 3.x"); diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c index e34992b08a2..8c2e1bff3a2 100644 --- a/sys/cam/ata/ata_pmp.c +++ b/sys/cam/ata/ata_pmp.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -176,8 +177,8 @@ pmpfreeze(struct cam_periph *periph, int mask) 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); + xpt_acquire_device(dpath->device); cam_freeze_devq(dpath); xpt_free_path(dpath); } @@ -198,9 +199,9 @@ pmprelease(struct cam_periph *periph, int mask) 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_release_device(dpath->device); xpt_free_path(dpath); } } @@ -228,6 +229,7 @@ pmponinvalidate(struct cam_periph *periph) xpt_free_path(dpath); } } + pmprelease(periph, -1); xpt_print(periph->path, "lost device\n"); } @@ -459,8 +461,6 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb) 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, @@ -584,7 +584,9 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) if (softc->pm_pid == 0x57231095 || softc->pm_pid == 0x57331095 || softc->pm_pid == 0x57341095 || softc->pm_pid == 0x57441095) softc->pm_ports--; - printf("PM ports: %d\n", softc->pm_ports); + printf("%s%d: %d fan-out ports\n", + periph->periph_name, periph->unit_number, + softc->pm_ports); softc->state = PMP_STATE_PRECONFIG; xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); @@ -606,7 +608,6 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) /*reduction*/0, /*timeout*/5, /*getcount_only*/0); - printf("PM reset done\n"); softc->state = PMP_STATE_CONNECT; } xpt_release_ccb(done_ccb); @@ -623,7 +624,6 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) /*reduction*/0, /*timeout*/10, /*getcount_only*/0); - printf("PM connect done\n"); softc->state = PMP_STATE_CHECK; } xpt_release_ccb(done_ccb); @@ -635,7 +635,11 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) (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); + if (bootverbose) { + printf("%s%d: port %d status: %08x\n", + periph->periph_name, periph->unit_number, + softc->pm_step, res); + } /* Report device speed. */ if (xpt_create_path(&dpath, periph, xpt_path_path_id(periph->path), @@ -661,7 +665,11 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) /*getcount_only*/0); softc->pm_try++; } else { - printf("PM status: %d - %08x\n", softc->pm_step, res); + if (bootverbose) { + printf("%s%d: port %d status: %08x\n", + periph->periph_name, periph->unit_number, + softc->pm_step, res); + } softc->found &= ~(1 << softc->pm_step); if (xpt_create_path(&dpath, periph, done_ccb->ccb_h.path_id, diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index a162623547b..f3f90af1dbd 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -729,7 +729,8 @@ noerror: { int sign = (done_ccb->ataio.res.lba_high << 8) + done_ccb->ataio.res.lba_mid; - xpt_print(path, "SIGNATURE: %04x\n", sign); + if (bootverbose) + xpt_print(path, "SIGNATURE: %04x\n", sign); if (sign == 0x0000 && done_ccb->ccb_h.target_id != 15) { path->device->protocol = PROTO_ATA; @@ -921,7 +922,6 @@ noerror: (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); @@ -934,7 +934,6 @@ noerror: (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; From 989435a380db9797121c1b2df777a860feea4b5d Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 22 Dec 2009 20:00:20 +0000 Subject: [PATCH 0929/2592] MFC r200414: CFA support doesn't exclude FLUSH support. --- sys/dev/ata/ata-disk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 0cd0a0f95c7..c6b50ddeb43 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -136,10 +136,10 @@ ad_attach(device_t dev) adp->disk->d_fwheads = adp->heads; adp->disk->d_unit = device_get_unit(dev); if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) - adp->disk->d_flags = DISKFLAG_CANFLUSHCACHE; + adp->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; if ((atadev->param.support.command2 & ATA_SUPPORT_CFA) || atadev->param.config == ATA_PROTO_CFA) - adp->disk->d_flags = DISKFLAG_CANDELETE; + adp->disk->d_flags |= DISKFLAG_CANDELETE; strlcpy(adp->disk->d_ident, atadev->param.serial, sizeof(adp->disk->d_ident)); disk_create(adp->disk, DISK_VERSION); From b57c18c4edea6518299cc089e44cd82af24384b7 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 22 Dec 2009 20:17:03 +0000 Subject: [PATCH 0930/2592] MFC r200375: Add one more set of codec IDs. --- sys/dev/sound/pci/hda/hdac.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 61bc646a035..7a9dd82a2c7 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -610,6 +610,7 @@ static const struct { #define CIRRUSLOGIC_VENDORID 0x1013 #define HDA_CODEC_CS4206 HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4206) #define HDA_CODEC_CS4207 HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4207) +#define HDA_CODEC_CSXXXX HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0xffff) /* Realtek */ #define REALTEK_VENDORID 0x10ec @@ -683,7 +684,9 @@ static const struct { #define HDA_CODEC_IDT92HD700D HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7639) #define HDA_CODEC_IDT92HD206X HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7645) #define HDA_CODEC_IDT92HD206D HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7646) +#define HDA_CODEC_CXD9872RDK HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7661) #define HDA_CODEC_STAC9872AK HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7662) +#define HDA_CODEC_CXD9872AKD HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7664) #define HDA_CODEC_STAC9221 HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7680) #define HDA_CODEC_STAC922XD HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7681) #define HDA_CODEC_STAC9221_A2 HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7682) @@ -731,6 +734,7 @@ static const struct { #define HDA_CODEC_CX20549 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5045) #define HDA_CODEC_CX20551 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5047) #define HDA_CODEC_CX20561 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5051) +#define HDA_CODEC_CX20582 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5066) #define HDA_CODEC_CXXXXX HDA_CODEC_CONSTRUCT(CONEXANT, 0xffff) /* VIA */ @@ -846,6 +850,8 @@ static const struct { { HDA_CODEC_AD1988B, "Analog Devices AD1988B" }, { HDA_CODEC_AD1989B, "Analog Devices AD1989B" }, { HDA_CODEC_CMI9880, "CMedia CMI9880" }, + { HDA_CODEC_CXD9872RDK, "Sigmatel CXD9872RD/K" }, + { HDA_CODEC_CXD9872AKD, "Sigmatel CXD9872AKD" }, { HDA_CODEC_STAC9200D, "Sigmatel STAC9200D" }, { HDA_CODEC_STAC9204X, "Sigmatel STAC9204X" }, { HDA_CODEC_STAC9204D, "Sigmatel STAC9204D" }, @@ -900,6 +906,7 @@ static const struct { { HDA_CODEC_CX20549, "Conexant CX20549 (Venice)" }, { HDA_CODEC_CX20551, "Conexant CX20551 (Waikiki)" }, { HDA_CODEC_CX20561, "Conexant CX20561 (Hermosa)" }, + { HDA_CODEC_CX20582, "Conexant CX20582 (Pebble)" }, { HDA_CODEC_VT1708_8, "VIA VT1708_8" }, { HDA_CODEC_VT1708_9, "VIA VT1708_9" }, { HDA_CODEC_VT1708_A, "VIA VT1708_A" }, @@ -965,6 +972,7 @@ static const struct { /* Unknown codec */ { HDA_CODEC_ALCXXXX, "Realtek (Unknown)" }, { HDA_CODEC_ADXXXX, "Analog Devices (Unknown)" }, + { HDA_CODEC_CSXXXX, "Cirrus Logic (Unknown)" }, { HDA_CODEC_CMIXXXX, "CMedia (Unknown)" }, { HDA_CODEC_STACXXXX, "Sigmatel (Unknown)" }, { HDA_CODEC_SIIXXXX, "Silicon Image (Unknown)" }, From 27466e91ffd0c04a5309ba4bf1f2872ff35f76bd Mon Sep 17 00:00:00 2001 From: Bruce M Simpson Date: Tue, 22 Dec 2009 20:33:27 +0000 Subject: [PATCH 0931/2592] MFC r200572: Add missing #include . Submitted by: Hideki Yamamoto --- sys/netinet6/mld6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index 172a8d6eb8a..8759ade17e8 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include From 48c7a876968b0ab4418bf0c511e260d032410cc8 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Wed, 23 Dec 2009 11:35:25 +0000 Subject: [PATCH 0932/2592] MFC r198520, r198857: fdc(4) module unload fixes PR: kern/104079 Approved by: trasz (mentor) --- sys/dev/fdc/fdc.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index a207bfcbc02..578204a985a 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); @@ -2068,8 +2079,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 299e7b88fe1cc4f2d66c728589acf17cecb27110 Mon Sep 17 00:00:00 2001 From: Benedict Reuschling Date: Wed, 23 Dec 2009 16:30:39 +0000 Subject: [PATCH 0933/2592] MFC r200731: Reference the correct man page for firmware(9). PR: docs/140986 Submitted by: Glen Barber (glen dot j dot barber at gmail dot com) Reviewed by: sam Approved by: sam, jkois (mentor) --- share/man/man4/mwlfw.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/mwlfw.4 b/share/man/man4/mwlfw.4 index e2a9c5362ef..5e557bfc307 100644 --- a/share/man/man4/mwlfw.4 +++ b/share/man/man4/mwlfw.4 @@ -49,4 +49,4 @@ It may be statically linked into the kernel, or loaded as a module. .Sh SEE ALSO .Xr mwl 4 , -.Xr firmware 8 +.Xr firmware 9 From 7a8c242784f273ada25abffe467b60da5122859d Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Wed, 23 Dec 2009 22:59:03 +0000 Subject: [PATCH 0934/2592] MFC r199458: Add pwait utility, which waits for any process to terminate. This is similar to the Solaris utility of the same name. Some use cases: * rc.subr's wait_for_pids * interactive use, e.g. to shut down the computer when some task is done even if the task is already running --- bin/Makefile | 1 + bin/pwait/Makefile | 5 ++ bin/pwait/pwait.1 | 78 ++++++++++++++++++++++++ bin/pwait/pwait.c | 145 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 229 insertions(+) create mode 100644 bin/pwait/Makefile create mode 100644 bin/pwait/pwait.1 create mode 100644 bin/pwait/pwait.c diff --git a/bin/Makefile b/bin/Makefile index 7491be9fc46..3114e670097 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -27,6 +27,7 @@ SUBDIR= cat \ pax \ pkill \ ps \ + pwait \ pwd \ ${_rcp} \ realpath \ diff --git a/bin/pwait/Makefile b/bin/pwait/Makefile new file mode 100644 index 00000000000..cdf322e27a8 --- /dev/null +++ b/bin/pwait/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +PROG= pwait + +.include diff --git a/bin/pwait/pwait.1 b/bin/pwait/pwait.1 new file mode 100644 index 00000000000..132d83c98ce --- /dev/null +++ b/bin/pwait/pwait.1 @@ -0,0 +1,78 @@ +.\" +.\" Copyright (c) 2004-2009, Jilles Tjoelker +.\" 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 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. +.\" +.\" $FreeBSD$ +.\" +.Dd November 1, 2009 +.Os +.Dt PWAIT 1 +.Sh NAME +.Nm pwait +.Nd wait for processes to terminate +.Sh SYNOPSIS +.Nm +.Op Fl v +.Ar pid +\&... +.Sh DESCRIPTION +The +.Nm +utility will wait until each of the given processes has terminated. +.Pp +The following option is available: +.Bl -tag -width indent +.It Fl v +Print the exit status when each process terminates. +.El +.Sh DIAGNOSTICS +.Pp +The +.Nm +utility returns 0 on success, and >0 if an error occurs. +.Pp +Invalid pids elicit a warning message but are otherwise ignored. +.Sh SEE ALSO +.Xr kill 1 , +.Xr pkill 1 , +.Xr ps 1 , +.Xr wait 1 , +.Xr kqueue 2 +.Sh NOTES +.Nm +is not a substitute for the +.Xr wait 1 +builtin +as it will not clean up any zombies or state in the parent process. +.Sh HISTORY +A +.Nm +command first appeared in SunOS 5.8. diff --git a/bin/pwait/pwait.c b/bin/pwait/pwait.c new file mode 100644 index 00000000000..26cf1bd8970 --- /dev/null +++ b/bin/pwait/pwait.c @@ -0,0 +1,145 @@ +/*- + * Copyright (c) 2004-2009, Jilles Tjoelker + * 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 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void +usage(void) +{ + + fprintf(stderr, "usage: pwait [-v] pid ...\n"); + exit(EX_USAGE); +} + +/* + * pwait - wait for processes to terminate + */ +int +main(int argc, char *argv[]) +{ + int kq; + struct kevent *e; + int verbose = 0; + int opt, nleft, n, i, duplicate, status; + long pid; + char *s, *end; + + while ((opt = getopt(argc, argv, "v")) != -1) { + switch (opt) { + case 'v': + verbose = 1; + break; + default: + usage(); + /* NOTREACHED */ + } + } + + argc -= optind; + argv += optind; + + if (argc == 0) + usage(); + + kq = kqueue(); + if (kq == -1) + err(1, "kqueue"); + + e = malloc(argc * sizeof(struct kevent)); + if (e == NULL) + err(1, "malloc"); + nleft = 0; + for (n = 0; n < argc; n++) { + s = argv[n]; + if (!strncmp(s, "/proc/", 6)) /* Undocumented Solaris compat */ + s += 6; + errno = 0; + pid = strtol(s, &end, 10); + if (pid < 0 || *end != '\0' || errno != 0) { + warnx("%s: bad process id", s); + continue; + } + duplicate = 0; + for (i = 0; i < nleft; i++) + if (e[i].ident == (uintptr_t)pid) + duplicate = 1; + if (!duplicate) { + EV_SET(e + nleft, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, + 0, NULL); + if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1) + warn("%ld", pid); + else + nleft++; + } + } + + while (nleft > 0) { + n = kevent(kq, NULL, 0, e, nleft, NULL); + if (n == -1) + err(1, "kevent"); + if (verbose) + for (i = 0; i < n; i++) { + status = e[i].data; + if (WIFEXITED(status)) + printf("%ld: exited with status %d.\n", + (long)e[i].ident, + WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + printf("%ld: killed by signal %d.\n", + (long)e[i].ident, + WTERMSIG(status)); + else + printf("%ld: terminated.\n", + (long)e[i].ident); + } + nleft -= n; + } + + return 0; +} From 85f5f3b435dd7ed3b5a1ba97cd70ac692354c353 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Thu, 24 Dec 2009 01:28:26 +0000 Subject: [PATCH 0935/2592] MFC of r200650, r200624 Add Australian, New Zealand and Ukraian calendars to the "all" target". Nationalise Easter -> Pasen in calendar.dutch --- usr.bin/calendar/calendars/calendar.all | 5 +++- usr.bin/calendar/calendars/calendar.dutch | 31 ++++++++++++----------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/usr.bin/calendar/calendars/calendar.all b/usr.bin/calendar/calendars/calendar.all index b46dcb46f0e..545c0e4e868 100644 --- a/usr.bin/calendar/calendars/calendar.all +++ b/usr.bin/calendar/calendars/calendar.all @@ -8,13 +8,16 @@ #define _calendar_all_ #include +#include #include #include #include #include #include -#include +#include #include +#include +#include #include #endif /* !_calendar_all_ */ diff --git a/usr.bin/calendar/calendars/calendar.dutch b/usr.bin/calendar/calendars/calendar.dutch index 3094ddd0578..47b1bf520a4 100644 --- a/usr.bin/calendar/calendars/calendar.dutch +++ b/usr.bin/calendar/calendars/calendar.dutch @@ -5,6 +5,7 @@ */ LANG=nl_NL.ISO8859-15 +Easter=Pasen /* * Feestdagen @@ -32,21 +33,21 @@ LANG=nl_NL.ISO8859-15 /* * Pasen gerelateerd */ -Easter-50 Carnaval -Easter-49 Carnaval -Easter-48 Carnaval -Easter-47 Carnaval (Vastenavond) -Easter-46 Aswoensdag -Easter-7 Palmzondag -Easter-3 Witte Donderdag -Easter-2 Goede vrijdag -Easter-1 Stille zaterdag -Easter Eerste paasdag -Easter+1 Tweede paasdag -Easter+39 Hemelvaartsdag -Easter+49 Eerste Pinksterdag -Easter+50 Tweede Pinksterdag -Easter+56 Trinitatis +Pasen-50 Carnaval +Pasen-49 Carnaval +Pasen-48 Carnaval +Pasen-47 Carnaval (Vastenavond) +Pasen-46 Aswoensdag +Pasen-7 Palmzondag +Pasen-3 Witte Donderdag +Pasen-2 Goede vrijdag +Pasen-1 Stille zaterdag +Pasen Eerste paasdag +Pasen+1 Tweede paasdag +Pasen+39 Hemelvaartsdag +Pasen+49 Eerste Pinksterdag +Pasen+50 Tweede Pinksterdag +Pasen+56 Trinitatis /* * Misc From 2fce833cd1469a5ca7f6b33313fde682eaed75e5 Mon Sep 17 00:00:00 2001 From: Yoshihiro Takahashi Date: Thu, 24 Dec 2009 12:19:52 +0000 Subject: [PATCH 0936/2592] MFC: revision 200631 Fix debug messages of bd_io(). --- sys/boot/i386/libi386/biosdisk.c | 8 ++++---- sys/boot/pc98/libpc98/biosdisk.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/boot/i386/libi386/biosdisk.c b/sys/boot/i386/libi386/biosdisk.c index 7e1fa19369d..cf0b03353ea 100644 --- a/sys/boot/i386/libi386/biosdisk.c +++ b/sys/boot/i386/libi386/biosdisk.c @@ -1266,11 +1266,11 @@ bd_io(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest, int write) } if (write) - DEBUG("%d sectors from %lld to %p (0x%x) %s", x, dblk, p, VTOP(p), - result ? "failed" : "ok"); + DEBUG("Write %d sector(s) from %p (0x%x) to %lld %s", x, + p, VTOP(p), dblk, result ? "failed" : "ok"); else - DEBUG("%d sectors from %p (0x%x) to %lld %s", x, p, VTOP(p), dblk, - result ? "failed" : "ok"); + DEBUG("Read %d sector(s) from %lld to %p (0x%x) %s", x, + dblk, p, VTOP(p), result ? "failed" : "ok"); if (result) { return(-1); } diff --git a/sys/boot/pc98/libpc98/biosdisk.c b/sys/boot/pc98/libpc98/biosdisk.c index 2f18285a50d..c2e7d6618cd 100644 --- a/sys/boot/pc98/libpc98/biosdisk.c +++ b/sys/boot/pc98/libpc98/biosdisk.c @@ -906,11 +906,11 @@ bd_io(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest, int write) } if (write) - DEBUG("%d sectors from %lld to %p (0x%x) %s", x, dblk, p, VTOP(p), - result ? "failed" : "ok"); + DEBUG("Write %d sector(s) from %p (0x%x) to %lld %s", x, + p, VTOP(p), dblk, result ? "failed" : "ok"); else - DEBUG("%d sectors from %p (0x%x) to %lld %s", x, p, VTOP(p), dblk, - result ? "failed" : "ok"); + DEBUG("Read %d sector(s) from %lld to %p (0x%x) %s", x, + dblk, p, VTOP(p), result ? "failed" : "ok"); if (result) { return(-1); } From 2ba8aab7859d54a8160325536fbdc1caed23341c Mon Sep 17 00:00:00 2001 From: Peter Pentchev Date: Thu, 24 Dec 2009 20:29:58 +0000 Subject: [PATCH 0937/2592] MFC r199863: Fix the cross-reference to sctp_opt_info in the text - section 3, not 2. PR: 140938 Submitted by: Bruce Cran --- share/man/man4/sctp.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/sctp.4 b/share/man/man4/sctp.4 index d5f4d3c5b31..226fc3cefc7 100644 --- a/share/man/man4/sctp.4 +++ b/share/man/man4/sctp.4 @@ -179,7 +179,7 @@ supports a number of socket options which can be set with and tested with .Xr getsockopt 2 or -.Xr sctp_opt_info 2 : +.Xr sctp_opt_info 3 : .Bl -tag -width ".Dv SCTP_SET_PEER_PRIMARY_ADDR" .It Dv SCTP_NODELAY Under most circumstances, From 29b0c308e2ef3cf3a00b324471f056eb32fa5957 Mon Sep 17 00:00:00 2001 From: Peter Pentchev Date: Thu, 24 Dec 2009 20:35:01 +0000 Subject: [PATCH 0938/2592] MFC r199244: Fix the grammar in the isgraph(3) description, almost as per the PR. PR: 140455 Submitted by: Jeremy Huddleston --- lib/libc/locale/isgraph.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/locale/isgraph.3 b/lib/libc/locale/isgraph.3 index 4ba78e3c4d9..5e06e2e498d 100644 --- a/lib/libc/locale/isgraph.3 +++ b/lib/libc/locale/isgraph.3 @@ -50,7 +50,7 @@ The function tests for any printing character except space .Pq Ql "\ " and other -locale specific space-like characters. +locale-specific space-like characters. The value of the argument must be representable as an .Vt "unsigned char" or the value of From f0e624adf8dcec7b531f644d3b961cfc37258cc3 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 25 Dec 2009 08:06:35 +0000 Subject: [PATCH 0939/2592] MFC r200668: Remove duplicate devstat_start_transaction_bio() call. It is already called from geom_disk. Dulicate call causes wrong queue depth and busy accounting. --- sys/cam/scsi/scsi_cd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index a6dabc2e96c..4a501f109f8 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -1464,8 +1464,6 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) } else { bioq_remove(&softc->bio_queue, bp); - devstat_start_transaction_bio(softc->disk->d_devstat, bp); - scsi_read_write(&start_ccb->csio, /*retries*/cd_retry_count, /* cbfcnp */ cddone, From 5bdc00a5d177b707eb8eeb44b56b35be349822a5 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 26 Dec 2009 04:29:38 +0000 Subject: [PATCH 0940/2592] MFC rev 200889: Export the bus, cpu and itc frequencies under the hw.freq sysctl node. --- sys/ia64/ia64/clock.c | 9 +++--- sys/ia64/ia64/machdep.c | 59 ++++++++++++++++++++++++--------------- sys/ia64/include/clock.h | 1 - sys/ia64/include/md_var.h | 1 + 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c index 6f2e2d86683..a9c39fce359 100644 --- a/sys/ia64/ia64/clock.c +++ b/sys/ia64/ia64/clock.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include uint64_t ia64_clock_reload; @@ -78,15 +79,15 @@ pcpu_initclock(void) void cpu_initclocks() { + u_long itc_freq; - if (itc_frequency == 0) - panic("Unknown clock frequency"); + itc_freq = (u_long)ia64_itc_freq() * 1000000ul; stathz = hz; - ia64_clock_reload = (itc_frequency + hz/2) / hz; + ia64_clock_reload = (itc_freq + hz/2) / hz; #ifndef SMP - ia64_timecounter.tc_frequency = itc_frequency; + ia64_timecounter.tc_frequency = itc_freq; tc_init(&ia64_timecounter); #endif diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 6d34e4d26d8..684bf2623ee 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -101,11 +101,21 @@ __FBSDID("$FreeBSD$"); #include +SYSCTL_NODE(_hw, OID_AUTO, freq, CTLFLAG_RD, 0, ""); SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RD, 0, ""); -u_int64_t processor_frequency; -u_int64_t bus_frequency; -u_int64_t itc_frequency; +static u_int bus_freq; +SYSCTL_UINT(_hw_freq, OID_AUTO, bus, CTLFLAG_RD, &bus_freq, 0, + "Bus clock frequency"); + +static u_int cpu_freq; +SYSCTL_UINT(_hw_freq, OID_AUTO, cpu, CTLFLAG_RD, &cpu_freq, 0, + "CPU clock frequency"); + +static u_int itc_freq; +SYSCTL_UINT(_hw_freq, OID_AUTO, itc, CTLFLAG_RD, &itc_freq, 0, + "ITC frequency"); + int cold = 1; u_int64_t pa_bootinfo; @@ -203,9 +213,7 @@ identifycpu(void) * (i.e. the clock frequency) to identify those. * Allow for roughly 1% error margin. */ - tmp = processor_frequency >> 7; - if ((processor_frequency - tmp) < 1*Ghz && - (processor_frequency + tmp) >= 1*Ghz) + if (cpu_freq > 990 && cpu_freq < 1010) model_name = "Deerfield"; else model_name = "Madison"; @@ -232,11 +240,8 @@ identifycpu(void) features = ia64_get_cpuid(4); printf("CPU: %s (", model_name); - if (processor_frequency) { - printf("%ld.%02ld-Mhz ", - (processor_frequency + 4999) / Mhz, - ((processor_frequency + 4999) / (Mhz/100)) % 100); - } + if (cpu_freq) + printf("%u Mhz ", cpu_freq); printf("%s)\n", family_name); printf(" Origin = \"%s\" Revision = %d\n", vendor, revision); printf(" Features = 0x%b\n", (u_int32_t) features, @@ -396,7 +401,7 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate) if (pcpu_find(cpu_id) == NULL || rate == NULL) return (EINVAL); - *rate = processor_frequency; + *rate = (u_long)cpu_freq * 1000000ul; return (0); } @@ -600,6 +605,15 @@ map_gateway_page(void) ia64_set_k5(VM_MAX_ADDRESS); } +static u_int +freq_ratio(u_long base, u_long ratio) +{ + u_long f; + + f = (base * (ratio >> 32)) / (ratio & 0xfffffffful); + return ((f + 500000) / 1000000); +} + static void calculate_frequencies(void) { @@ -622,15 +636,9 @@ calculate_frequencies(void) pal.pal_result[2] >> 32, pal.pal_result[2] & ((1L << 32) - 1)); } - processor_frequency = - sal.sal_result[0] * (pal.pal_result[0] >> 32) - / (pal.pal_result[0] & ((1L << 32) - 1)); - bus_frequency = - sal.sal_result[0] * (pal.pal_result[1] >> 32) - / (pal.pal_result[1] & ((1L << 32) - 1)); - itc_frequency = - sal.sal_result[0] * (pal.pal_result[2] >> 32) - / (pal.pal_result[2] & ((1L << 32) - 1)); + cpu_freq = freq_ratio(sal.sal_result[0], pal.pal_result[0]); + bus_freq = freq_ratio(sal.sal_result[0], pal.pal_result[1]); + itc_freq = freq_ratio(sal.sal_result[0], pal.pal_result[2]); } } @@ -971,6 +979,13 @@ bzero(void *buf, size_t len) } } +u_int +ia64_itc_freq(void) +{ + + return (itc_freq); +} + void DELAY(int n) { @@ -979,7 +994,7 @@ DELAY(int n) sched_pin(); start = ia64_get_itc(); - end = start + (itc_frequency * n) / 1000000; + end = start + itc_freq * n; /* printf("DELAY from 0x%lx to 0x%lx\n", start, end); */ do { now = ia64_get_itc(); diff --git a/sys/ia64/include/clock.h b/sys/ia64/include/clock.h index aa4220aa128..772fc2a29ed 100644 --- a/sys/ia64/include/clock.h +++ b/sys/ia64/include/clock.h @@ -14,7 +14,6 @@ #define CLOCK_VECTOR 254 extern uint64_t ia64_clock_reload; -extern uint64_t itc_frequency; #endif diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h index 6ee4cb4ee5c..7fdcb2de539 100644 --- a/sys/ia64/include/md_var.h +++ b/sys/ia64/include/md_var.h @@ -90,6 +90,7 @@ 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); +u_int ia64_itc_freq(void); void ia64_probe_sapics(void); void ia64_sync_icache(vm_offset_t, vm_size_t); void interrupt(struct trapframe *); From f939f049f3b0f8e6e2a5579cb9ef2ddf85c1e3ab Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 26 Dec 2009 04:31:18 +0000 Subject: [PATCH 0941/2592] MFC rev 200891: Calculate the average CPU clock frequency and export that through the hw.freq.cpu sysctl variable. --- sys/sparc64/sparc64/identcpu.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sys/sparc64/sparc64/identcpu.c b/sys/sparc64/sparc64/identcpu.c index 020dc924fb3..cdb09e65806 100644 --- a/sys/sparc64/sparc64/identcpu.c +++ b/sys/sparc64/sparc64/identcpu.c @@ -27,6 +27,13 @@ static char cpu_model[128]; SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "Machine model"); +SYSCTL_NODE(_hw, OID_AUTO, freq, CTLFLAG_RD, 0, ""); + +static u_int cpu_count; +static u_int cpu_freq; +SYSCTL_UINT(_hw_freq, OID_AUTO, cpu, CTLFLAG_RD, &cpu_freq, 0, + "CPU clock frequency"); + int cpu_impl; void @@ -104,4 +111,11 @@ cpu_identify(u_long vers, u_int freq, u_int id) printf(" mask=0x%lx maxtl=%ld maxwin=%ld\n", VER_MASK(vers), VER_MAXTL(vers), VER_MAXWIN(vers)); } + + /* + * Calculate the average CPU frequency. + */ + freq = (freq + 500000ul) / 1000000ul; + cpu_freq = (cpu_freq * cpu_count + freq) / (cpu_count + 1); + cpu_count++; } From 91e379a2a88cd30a0e9e8af4a7d4885aaa9a17e6 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sat, 26 Dec 2009 18:23:21 +0000 Subject: [PATCH 0942/2592] MFC r198366: Don't use BUS_DMA_ALLOCNOW as that causes the attachment to fail on Cambria boards. --- 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 ea5454c58616d901885af51583a54953946514b8 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sat, 26 Dec 2009 18:25:52 +0000 Subject: [PATCH 0943/2592] MFC r200524: Pass all IEs to net80211. PR: 141376 Submitted by: Paul --- sys/dev/if_ndis/if_ndis.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index a1af3e982e7..1688a309279 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -3355,24 +3355,11 @@ ndis_scan_results(struct ndis_softc *sc) efrm = frm + wb->nwbx_ielen; if (efrm - frm < 12) goto done; - sp.tstamp = frm; - frm += 8; - sp.bintval = le16toh(*(uint16_t *)frm); - frm += 2; - sp.capinfo = le16toh(*(uint16_t *)frm); - frm += 2; - - /* Grab variable length ies */ - while (efrm - frm > 1) { - if (efrm - frm < frm[1] + 2) - break; - switch (*frm) { - case IEEE80211_ELEMID_RSN: - sp.rsn = frm; - break; - } - frm += frm[1] + 2; - } + sp.tstamp = frm; frm += 8; + sp.bintval = le16toh(*(uint16_t *)frm); frm += 2; + sp.capinfo = le16toh(*(uint16_t *)frm); frm += 2; + sp.ies = frm; + sp.ies_len = efrm - frm; } done: DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n", From 143dcf0b47cc295b2a22e01dbc3bd1c3f3973556 Mon Sep 17 00:00:00 2001 From: Maxim Konovalov Date: Sat, 26 Dec 2009 20:52:47 +0000 Subject: [PATCH 0944/2592] MFC r197799: fix typo. --- 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 8f923cfaf1af9d4303e032731fd30c1a42104395 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sun, 27 Dec 2009 07:04:27 +0000 Subject: [PATCH 0945/2592] Explicitly say that this is an internal library which is intended to be used within FreeBSD base system only, and discourage user applications from using it. User applications should use the expat version from the ports/package collection. Reviewed by: simon (earlier version) --- lib/libexpat/libbsdxml.3 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/libexpat/libbsdxml.3 b/lib/libexpat/libbsdxml.3 index 7d7b0e71909..f687518517b 100644 --- a/lib/libexpat/libbsdxml.3 +++ b/lib/libexpat/libbsdxml.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\"/ -.Dd May 5, 2008 +.Dd December 12, 2009 .Dt LIBBSDXML 3 .Os .Sh NAME @@ -38,6 +38,15 @@ The .Nm library is a verbatim copy of the eXpat XML library version 2.0.1. .Pp +The +.Nm +library is intended to use within the +.Fx +base system only. +Use of the +.Nm +library for other purposes is not supported and discouraged. +.Pp To avoid version and autoconfiguration issues, the library has been renamed to .Nm From e2b7b47402a3b60f806f0376d8aa90dbb409441a Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Sun, 27 Dec 2009 10:13:31 +0000 Subject: [PATCH 0946/2592] explicitly define HZ for picosd images --- release/picobsd/bridge/PICOBSD | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/release/picobsd/bridge/PICOBSD b/release/picobsd/bridge/PICOBSD index 07e3bc2d53c..3d206efb2a0 100644 --- a/release/picobsd/bridge/PICOBSD +++ b/release/picobsd/bridge/PICOBSD @@ -46,7 +46,9 @@ options IPDIVERT # divert (for natd) # Support for bridging and bandwidth limiting options DUMMYNET device if_bridge -#options HZ=1000 +# Running with less than 1000 seems to give poor timing on +# qemu, so we set HZ explicitly. +options HZ=1000 device random # used by ssh device pci From 5300f787acc4252f571ce848f760f2d17b39201b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 27 Dec 2009 20:39:58 +0000 Subject: [PATCH 0947/2592] MFC r200038: Properly support -fPIE by linking PIE binaries with specially-built Scrt1.o instead of crt1.o, since the later is built as non-PIC. Separate i386-elf crt1.c into the pure assembler part and C code, supplying all data extracted by assembler stub as explicit parameters. Hide and localize _start1 symbol used as an interface between asm and C code. --- contrib/gcc/config/freebsd-spec.h | 8 ++--- lib/csu/amd64/Makefile | 5 ++- lib/csu/arm/Makefile | 5 ++- lib/csu/i386-elf/Makefile | 24 ++++++++++++--- lib/csu/i386-elf/{crt1.c => crt1_c.c} | 30 ++++-------------- lib/csu/i386-elf/crt1_s.S | 44 +++++++++++++++++++++++++++ lib/csu/ia64/Makefile | 5 ++- lib/csu/mips/Makefile | 5 ++- lib/csu/powerpc/Makefile | 5 ++- lib/csu/sparc64/Makefile | 5 ++- 10 files changed, 97 insertions(+), 39 deletions(-) rename lib/csu/i386-elf/{crt1.c => crt1_c.c} (83%) create mode 100644 lib/csu/i386-elf/crt1_s.S diff --git a/contrib/gcc/config/freebsd-spec.h b/contrib/gcc/config/freebsd-spec.h index 06735c8874e..5cd57b0bf61 100644 --- a/contrib/gcc/config/freebsd-spec.h +++ b/contrib/gcc/config/freebsd-spec.h @@ -103,9 +103,10 @@ Boston, MA 02110-1301, USA. */ %{p:gcrt1.o%s} \ %{!p: \ %{profile:gcrt1.o%s} \ - %{!profile:crt1.o%s}}}} \ + %{!profile: \ + %{pie: Scrt1.o%s;:crt1.o%s}}}}} \ crti.o%s \ - %{static:crtbeginT.o%s;shared:crtbeginS.o%s;:crtbegin.o%s}" + %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}" /* Provide an ENDFILE_SPEC appropriate for FreeBSD/i386. Here we tack on our own magical crtend.o file (see crtstuff.c) which provides part of @@ -113,8 +114,7 @@ Boston, MA 02110-1301, USA. */ entering `main', followed by the normal "finalizer" file, `crtn.o'. */ #define FBSD_ENDFILE_SPEC "\ - %{!shared:crtend.o%s} \ - %{shared:crtendS.o%s} \ + %{shared|pie:crtendS.o%s;:crtend.o%s} \ crtn.o%s " /* Provide a LIB_SPEC appropriate for FreeBSD as configured and as diff --git a/lib/csu/amd64/Makefile b/lib/csu/amd64/Makefile index 71ccd675b31..1a74efcbcab 100644 --- a/lib/csu/amd64/Makefile +++ b/lib/csu/amd64/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include CFLAGS+= -fno-omit-frame-pointer @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.CURDIR}/crt1.c +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.CURDIR}/crt1.c + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/arm/Makefile b/lib/csu/arm/Makefile index 23954e840f3..097f82df1f9 100644 --- a/lib/csu/arm/Makefile +++ b/lib/csu/arm/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -Wall -Wno-unused \ -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/i386-elf/Makefile b/lib/csu/i386-elf/Makefile index 8598ce8552f..c2af118fe4f 100644 --- a/lib/csu/i386-elf/Makefile +++ b/lib/csu/i386-elf/Makefile @@ -2,8 +2,8 @@ .PATH: ${.CURDIR}/../common -SRCS= crt1.c crti.S crtn.S -FILES= ${SRCS:N*.h:R:S/$/.o/g} gcrt1.o +SRCS= crti.S crtn.S +FILES= ${SRCS:N*.h:R:S/$/.o/g} gcrt1.o crt1.o Scrt1.o FILESOWN= ${LIBOWN} FILESGRP= ${LIBGRP} FILESMODE= ${LIBMODE} @@ -11,9 +11,23 @@ FILESDIR= ${LIBDIR} WARNS?= 6 CFLAGS+= -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include -CLEANFILES= ${FILES} +CLEANFILES= ${FILES} crt1_c.o crt1_s.o gcrt1_c.o Scrt1_c.o -gcrt1.o: crt1.c - ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.CURDIR}/crt1.c +gcrt1_c.o: crt1_c.c + ${CC} ${CFLAGS} -DGCRT -c -o gcrt1_c.o ${.CURDIR}/crt1_c.c + +gcrt1.o: gcrt1_c.o crt1_s.o + ${LD} ${LDFLAGS} -o gcrt1.o -r crt1_s.o gcrt1_c.o + +crt1.o: crt1_c.o crt1_s.o + ${LD} ${LDFLAGS} -o crt1.o -r crt1_s.o crt1_c.o + objcopy --localize-symbol _start1 crt1.o + +Scrt1_c.o: crt1_c.c + ${CC} ${CFLAGS} -DGCRT -fPIC -DPIC -c -o Scrt1_c.o ${.CURDIR}/crt1_c.c + +Scrt1.o: Scrt1_c.o crt1_s.o + ${LD} ${LDFLAGS} -o Scrt1.o -r crt1_s.o Scrt1_c.o + objcopy --localize-symbol _start1 Scrt1.o .include diff --git a/lib/csu/i386-elf/crt1.c b/lib/csu/i386-elf/crt1_c.c similarity index 83% rename from lib/csu/i386-elf/crt1.c rename to lib/csu/i386-elf/crt1_c.c index 093433330e3..c38f267c8e3 100644 --- a/lib/csu/i386-elf/crt1.c +++ b/lib/csu/i386-elf/crt1_c.c @@ -22,6 +22,8 @@ * 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 lint @@ -55,35 +57,15 @@ extern int etext; char **environ; const char *__progname = ""; -static __inline fptr -get_rtld_cleanup(void) -{ - fptr retval; +void _start1(fptr, int, char *[]) __dead2; -#ifdef __GNUC__ - __asm__("movl %%edx,%0" : "=rm"(retval)); -#else - retval = (fptr)0; /* XXXX Fix this for other compilers */ -#endif - return(retval); -} - -/* The entry function. */ +/* The entry function, C part. */ void -_start(char *ap, ...) +_start1(fptr cleanup, int argc, char *argv[]) { - fptr cleanup; - int argc; - char **argv; char **env; const char *s; -#ifdef __GNUC__ - __asm__("and $0xfffffff0,%esp"); -#endif - cleanup = get_rtld_cleanup(); - argv = ≈ - argc = *(long *)(void *)(argv - 1); env = argv + argc + 1; environ = env; if (argc > 0 && argv[0] != NULL) { @@ -110,4 +92,4 @@ __asm__("eprol:"); exit( main(argc, argv, env) ); } -__asm__(".ident\t\"$FreeBSD$\""); +__asm(".hidden _start1"); diff --git a/lib/csu/i386-elf/crt1_s.S b/lib/csu/i386-elf/crt1_s.S new file mode 100644 index 00000000000..2af8a1bc83a --- /dev/null +++ b/lib/csu/i386-elf/crt1_s.S @@ -0,0 +1,44 @@ +/*- + * Copyright 2009 Konstantin Belousov. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + + + .text + .align 4 + .globl _start + .type _start, @function +_start: xorl %ebp,%ebp + pushl %ebp + movl %esp,%ebp + andl $0xfffffff0,%esp # align stack + leal 8(%ebp),%eax + pushl %eax # argv + pushl 4(%ebp) # argc + pushl %edx # rtld cleanup + call _start1 + .size _start, . - _start + + .ident "$FreeBSD$" diff --git a/lib/csu/ia64/Makefile b/lib/csu/ia64/Makefile index c906c094267..d79510399db 100644 --- a/lib/csu/ia64/Makefile +++ b/lib/csu/ia64/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.S crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -Wall -Wno-unused \ -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.S ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.S + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/mips/Makefile b/lib/csu/mips/Makefile index 23954e840f3..097f82df1f9 100644 --- a/lib/csu/mips/Makefile +++ b/lib/csu/mips/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -Wall -Wno-unused \ -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/powerpc/Makefile b/lib/csu/powerpc/Makefile index 23954e840f3..097f82df1f9 100644 --- a/lib/csu/powerpc/Makefile +++ b/lib/csu/powerpc/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -Wall -Wno-unused \ -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/sparc64/Makefile b/lib/csu/sparc64/Makefile index 2e1d03f9cb6..7f8dd7a5483 100644 --- a/lib/csu/sparc64/Makefile +++ b/lib/csu/sparc64/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR}/../common -I${.CURDIR}/../../libc/include all: ${OBJS} @@ -14,6 +14,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} From fc946fd0265c2db92c017c95695e541675d3bbc2 Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Sun, 27 Dec 2009 22:49:34 +0000 Subject: [PATCH 0948/2592] MFC 200620,200621: fix argument order to mtx_init call. --- sys/dev/ips/ips_pci.c | 2 +- sys/kern/uipc_syscalls.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/ips/ips_pci.c b/sys/dev/ips/ips_pci.c index 9ccaf373b3e..9781087891d 100644 --- a/sys/dev/ips/ips_pci.c +++ b/sys/dev/ips/ips_pci.c @@ -154,7 +154,7 @@ static int ips_pci_attach(device_t dev) } sc->ips_ich.ich_func = ips_intrhook; sc->ips_ich.ich_arg = sc; - mtx_init(&sc->queue_mtx, "IPS bioqueue lock", MTX_DEF, 0); + mtx_init(&sc->queue_mtx, "IPS bioqueue lock", NULL, MTX_DEF); sema_init(&sc->cmd_sema, 0, "IPS Command Semaphore"); bioq_init(&sc->queue); if (config_intrhook_establish(&sc->ips_ich) != 0) { diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 2e2e4f77592..a4857ced2d7 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1886,7 +1886,7 @@ kern_sendfile(struct thread *td, struct sendfile_args *uap, if (uap->flags & SF_SYNC) { sfs = malloc(sizeof *sfs, M_TEMP, M_WAITOK); memset(sfs, 0, sizeof *sfs); - mtx_init(&sfs->mtx, "sendfile", MTX_DEF, 0); + mtx_init(&sfs->mtx, "sendfile", NULL, MTX_DEF); cv_init(&sfs->cv, "sendfile"); } From 82d11b03016e508ef7100da9ba6d0287bc6dfae9 Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Sun, 27 Dec 2009 22:50:25 +0000 Subject: [PATCH 0949/2592] MFC of 198329: Check pointer for NULL before dereferencing it, not after. --- 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 4326aa4855382a733acd4c8669da3ccea9491a16 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 28 Dec 2009 14:39:21 +0000 Subject: [PATCH 0950/2592] MFC r200471, r201044: Add a few more V_hacks to nfsclient to allow machines with a VIMAGE kernel to boot from NFS. [1] Note: this is not a full virtualization of nfsclient. It is only does what advertised above and nothing more. --- sys/nfsclient/bootp_subr.c | 7 +++++++ sys/nfsclient/krpc_subr.c | 6 ++++++ sys/nfsclient/nfs_vfsops.c | 5 +++++ sys/nfsclient/nfs_vnops.c | 16 ++++++++++++---- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index e57b32a1bed..4377f74367b 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -584,6 +584,8 @@ bootpc_call(struct bootpc_globalcontext *gctx, struct thread *td) int retry; const char *s; + CURVNET_SET(TD_TO_VNET(td)); + /* * Create socket and set its recieve timeout. */ @@ -960,6 +962,7 @@ gotreply: out: soclose(so); out0: + CURVNET_RESTORE(); return error; } @@ -974,6 +977,8 @@ bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, struct ifaddr *ifa; struct sockaddr_dl *sdl; + CURVNET_SET(TD_TO_VNET(td)); + error = socreate(AF_INET, &ifctx->so, SOCK_DGRAM, 0, td->td_ucred, td); if (error != 0) panic("nfs_boot: socreate, error=%d", error); @@ -1048,6 +1053,8 @@ bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, ifctx->ireq.ifr_name); ifctx->sdl = sdl; + CURVNET_RESTORE(); + return error; } diff --git a/sys/nfsclient/krpc_subr.c b/sys/nfsclient/krpc_subr.c index 996cb050bd7..c2a84506390 100644 --- a/sys/nfsclient/krpc_subr.c +++ b/sys/nfsclient/krpc_subr.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -55,6 +56,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include @@ -213,6 +216,8 @@ krpc_call(struct sockaddr_in *sa, u_int prog, u_int vers, u_int func, nam = mhead = NULL; from = NULL; + CURVNET_SET(TD_TO_VNET(td)); + /* * Create socket and set its recieve timeout. */ @@ -425,6 +430,7 @@ krpc_call(struct sockaddr_in *sa, u_int prog, u_int vers, u_int func, if (mhead) m_freem(mhead); if (from) free(from, M_SONAME); soclose(so); + CURVNET_RESTORE(); return error; } diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index 17dc5d4b5de..0e100935f14 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -64,6 +64,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include @@ -825,6 +827,8 @@ nfs_mount(struct mount *mp) has_fh_opt = 0; has_hostname_opt = 0; + CURVNET_SET(CRED_TO_VNET(curthread->td_ucred)); + if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { error = EINVAL; goto out; @@ -1124,6 +1128,7 @@ out: mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED); MNT_IUNLOCK(mp); } + CURVNET_RESTORE(); return (error); } diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index dc619275aea..b3c28a3cdd0 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -1555,14 +1555,21 @@ nfs_create(struct vop_create_args *ap) struct vattr vattr; int v3 = NFS_ISV3(dvp); + CURVNET_SET(CRED_TO_VNET(curthread->td_ucred)); + /* * Oops, not for me.. */ - if (vap->va_type == VSOCK) - return (nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap)); - - if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0) + if (vap->va_type == VSOCK) { + error = nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap); + CURVNET_RESTORE(); return (error); + } + + if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0) { + CURVNET_RESTORE(); + return (error); + } if (vap->va_vaflags & VA_EXCLUSIVE) fmode |= O_EXCL; again: @@ -1658,6 +1665,7 @@ nfsmout: KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp); } mtx_unlock(&(VTONFS(dvp))->n_mtx); + CURVNET_RESTORE(); return (error); } From 950cde5085c260d1c22c265f94fb0ae002403cd3 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 28 Dec 2009 14:40:58 +0000 Subject: [PATCH 0951/2592] MFC r200473: Throughout the network stack we have a few places of if (jailed(cred)) left. If you are running with a vnet (virtual network stack) those will return true and defer you to classic IP-jails handling and thus things will be "denied" or returned with an error. Work around this problem by introducing another "jailed()" function, jailed_without_vnet(), that also takes vnets into account, and permits the calls, should the jail from the given cred have its own virtual network stack. We cannot change the classic jailed() call to do that, as it is used outside the network stack as well. Discussed with: julian, zec, jamie, rwatson (back in Sept) --- sys/kern/kern_jail.c | 25 ++++++++++++++++++++++++- sys/net/rtsock.c | 4 ++-- sys/netinet/raw_ip.c | 4 ++-- sys/netinet6/raw_ip6.c | 2 +- sys/sys/jail.h | 1 + 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 0cc330cd5ad..0900541f2cc 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3161,7 +3161,7 @@ prison_check_af(struct ucred *cred, int af) pr = cred->cr_prison; #ifdef VIMAGE /* Prisons with their own network stack are not limited. */ - if (pr->pr_flags & PR_VNET) + if (prison_owns_vnet(cred)) return (0); #endif @@ -3222,6 +3222,11 @@ prison_if(struct ucred *cred, struct sockaddr *sa) KASSERT(cred != NULL, ("%s: cred is NULL", __func__)); KASSERT(sa != NULL, ("%s: sa is NULL", __func__)); +#ifdef VIMAGE + if (prison_owns_vnet(cred)) + return (0); +#endif + error = 0; switch (sa->sa_family) { @@ -3278,6 +3283,24 @@ jailed(struct ucred *cred) return (cred->cr_prison != &prison0); } +/* + * Return 1 if the passed credential is in a jail and that jail does not + * have its own virtual network stack, otherwise 0. + */ +int +jailed_without_vnet(struct ucred *cred) +{ + + if (!jailed(cred)) + return (0); +#ifdef VIMAGE + if (prison_owns_vnet(cred)) + return (0); +#endif + + return (1); +} + /* * Return the correct hostname (domainname, et al) for the passed credential. */ diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 4bbd6e32fa9..a0677ec1dfc 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -651,7 +651,7 @@ route_output(struct mbuf *m, struct socket *so) report: RT_LOCK_ASSERT(rt); if ((rt->rt_flags & RTF_HOST) == 0 - ? jailed(curthread->td_ucred) + ? jailed_without_vnet(curthread->td_ucred) : prison_if(curthread->td_ucred, rt_key(rt)) != 0) { RT_UNLOCK(rt); @@ -1312,7 +1312,7 @@ sysctl_dumpentry(struct radix_node *rn, void *vw) if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) return 0; if ((rt->rt_flags & RTF_HOST) == 0 - ? jailed(w->w_req->td->td_ucred) + ? jailed_without_vnet(w->w_req->td->td_ucred) : prison_if(w->w_req->td->td_ucred, rt_key(rt)) != 0) return (0); bzero((caddr_t)&info, sizeof(info)); diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 15a8fe4360b..aba1f5f4a11 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -291,7 +291,7 @@ rip_input(struct mbuf *m, int off) continue; if (inp->inp_faddr.s_addr != ip->ip_src.s_addr) continue; - if (jailed(inp->inp_cred)) { + if (jailed_without_vnet(inp->inp_cred)) { /* * XXX: If faddr was bound to multicast group, * jailed raw socket will drop datagram. @@ -325,7 +325,7 @@ rip_input(struct mbuf *m, int off) if (!in_nullhost(inp->inp_faddr) && !in_hosteq(inp->inp_faddr, ip->ip_src)) continue; - if (jailed(inp->inp_cred)) { + if (jailed_without_vnet(inp->inp_cred)) { /* * Allow raw socket in jail to receive multicast; * assume process had PRIV_NETINET_RAW at attach, diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 335eff54939..9f1236ab1bd 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -184,7 +184,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto) if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) continue; - if (jailed(in6p->inp_cred)) { + if (jailed_without_vnet(in6p->inp_cred)) { /* * Allow raw socket in jail to receive multicast; * assume process had PRIV_NETINET_RAW at attach, diff --git a/sys/sys/jail.h b/sys/sys/jail.h index cb26a64ec7d..2c5d1787786 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -335,6 +335,7 @@ struct mount; struct sockaddr; struct statfs; int jailed(struct ucred *cred); +int jailed_without_vnet(struct ucred *); void getcredhostname(struct ucred *, char *, size_t); void getcreddomainname(struct ucred *, char *, size_t); void getcredhostuuid(struct ucred *, char *, size_t); From 8aeffdc3b99d5f252a6325aa3846f329429cea04 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 28 Dec 2009 14:44:22 +0000 Subject: [PATCH 0952/2592] MFC r200995: Remove an unused global. --- sys/kern/kern_proc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index f931245fda4..353a4e667c6 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -140,7 +140,6 @@ struct sx allproc_lock; struct sx proctree_lock; struct mtx ppeers_lock; uma_zone_t proc_zone; -uma_zone_t ithread_zone; int kstack_pages = KSTACK_PAGES; SYSCTL_INT(_kern, OID_AUTO, kstack_pages, CTLFLAG_RD, &kstack_pages, 0, ""); From 58caa1cc76e73c195e3d90d728ec70355be71de6 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 28 Dec 2009 14:47:25 +0000 Subject: [PATCH 0953/2592] MFC r201000: Remove extra spaces (no functional change). --- sys/kern/kern_rmlock.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/kern/kern_rmlock.c b/sys/kern/kern_rmlock.c index b56de666a32..940604ac7cf 100644 --- a/sys/kern/kern_rmlock.c +++ b/sys/kern/kern_rmlock.c @@ -147,7 +147,7 @@ rm_tracker_add(struct pcpu *pc, struct rm_priotracker *tracker) next->rmq_prev = &tracker->rmp_cpuQueue; /* Update pointer to first element. */ - pc->pc_rm_queue.rmq_next = &tracker->rmp_cpuQueue; + pc->pc_rm_queue.rmq_next = &tracker->rmp_cpuQueue; } static void inline @@ -278,7 +278,7 @@ _rm_rlock_hard(struct rmlock *rm, struct rm_priotracker *tracker) * for this lock on the per cpu queue. */ for (queue = pc->pc_rm_queue.rmq_next; - queue != &pc->pc_rm_queue; queue = queue->rmq_next) { + queue != &pc->pc_rm_queue; queue = queue->rmq_next) { atracker = (struct rm_priotracker *)queue; if ((atracker->rmp_rmlock == rm) && (atracker->rmp_thread == tracker->rmp_thread)) { @@ -337,7 +337,7 @@ _rm_rlock(struct rmlock *rm, struct rm_priotracker *tracker) * Fast path to combine two common conditions into a single * conditional jump. */ - if (0 == (td->td_owepreempt | rm->rm_noreadtoken)) + if (0 == (td->td_owepreempt | rm->rm_noreadtoken)) return; /* We do not have a read token and need to acquire one. */ @@ -413,7 +413,7 @@ _rm_wlock(struct rmlock *rm) * before rm_cleanIPI is called. */ #ifdef SMP - smp_rendezvous(smp_no_rendevous_barrier, + smp_rendezvous(smp_no_rendevous_barrier, rm_cleanIPI, smp_no_rendevous_barrier, rm); @@ -487,7 +487,7 @@ _rm_rlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, } void -_rm_runlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, +_rm_runlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, const char *file, int line) { @@ -526,7 +526,7 @@ _rm_rlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, } void -_rm_runlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, +_rm_runlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, const char *file, int line) { From eaf52f2239e5cd254ea0b97f34a07e21c694c5e0 Mon Sep 17 00:00:00 2001 From: Yoshihiro Takahashi Date: Tue, 29 Dec 2009 04:23:46 +0000 Subject: [PATCH 0954/2592] MFC: revision 200776 Move cursor position after putting a character. --- sys/boot/pc98/kgzldr/crt.s | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/boot/pc98/kgzldr/crt.s b/sys/boot/pc98/kgzldr/crt.s index e028bc8e672..35c1fc2dfe7 100644 --- a/sys/boot/pc98/kgzldr/crt.s +++ b/sys/boot/pc98/kgzldr/crt.s @@ -75,5 +75,15 @@ crt_putchr.3: cmpw $SCR_ROW*SCR_COL*2,%dx stosw # line movw $(SCR_ROW-1)*SCR_COL*2,%dx crt_putchr.4: movw %dx,(%ebx) # Update position + shrw $1,%dx +crt_putchr.5: inb $0x60,%al # Move cursor + testb $0x04,%al + jz crt_putchr.5 + movb $0x49,%al + outb %al,$0x62 + movb %dl,%al + outb %al,$0x60 + movb %dh,%al + outb %al,$0x60 popa # Restore ret # To caller From be0d315238c9e1ff1ebf1f6310d343ff50fd6907 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Tue, 29 Dec 2009 05:35:25 +0000 Subject: [PATCH 0955/2592] MFC r200594: Add INCLUDE_CONFIG_FILE, and a note in comments about how to also include the comments with CONFIGARGS --- sys/amd64/conf/DEFAULTS | 6 ++++++ sys/arm/conf/DEFAULTS | 7 +++++++ sys/i386/conf/DEFAULTS | 7 +++++++ sys/ia64/conf/DEFAULTS | 7 +++++++ sys/mips/conf/DEFAULTS | 7 +++++++ sys/pc98/conf/DEFAULTS | 7 +++++++ sys/powerpc/conf/DEFAULTS | 7 +++++++ sys/sparc64/conf/DEFAULTS | 7 +++++++ sys/sun4v/conf/DEFAULTS | 7 +++++++ 9 files changed, 62 insertions(+) diff --git a/sys/amd64/conf/DEFAULTS b/sys/amd64/conf/DEFAULTS index 78952eef63b..d6d39b6c769 100644 --- a/sys/amd64/conf/DEFAULTS +++ b/sys/amd64/conf/DEFAULTS @@ -21,3 +21,9 @@ options GEOM_PART_EBR options GEOM_PART_EBR_COMPAT options GEOM_PART_MBR +# Store the plain version of the configuration file in the kernel itself. +# To store the entire file, including comments, put this in /etc/src.conf: +# CONFIGARGS= -C +# See config(8) for more details. +# +options INCLUDE_CONFIG_FILE # Include this file in kernel diff --git a/sys/arm/conf/DEFAULTS b/sys/arm/conf/DEFAULTS index 591a0a14c8d..4052ef3e500 100644 --- a/sys/arm/conf/DEFAULTS +++ b/sys/arm/conf/DEFAULTS @@ -9,3 +9,10 @@ device mem options GEOM_PART_BSD options GEOM_PART_MBR + +# Store the plain version of the configuration file in the kernel itself. +# To store the entire file, including comments, put this in /etc/src.conf: +# CONFIGARGS= -C +# See config(8) for more details. +# +options INCLUDE_CONFIG_FILE # Include this file in kernel diff --git a/sys/i386/conf/DEFAULTS b/sys/i386/conf/DEFAULTS index 32e77e41979..eb3ed17b81b 100644 --- a/sys/i386/conf/DEFAULTS +++ b/sys/i386/conf/DEFAULTS @@ -28,3 +28,10 @@ options GEOM_PART_MBR # enable support for native hardware options NATIVE device atpic + +# Store the plain version of the configuration file in the kernel itself. +# To store the entire file, including comments, put this in /etc/src.conf: +# CONFIGARGS= -C +# See config(8) for more details. +# +options INCLUDE_CONFIG_FILE # Include this file in kernel diff --git a/sys/ia64/conf/DEFAULTS b/sys/ia64/conf/DEFAULTS index 625ff90955c..58eaaf4b591 100644 --- a/sys/ia64/conf/DEFAULTS +++ b/sys/ia64/conf/DEFAULTS @@ -17,3 +17,10 @@ device uart_ns8250 options GEOM_PART_BSD options GEOM_PART_GPT options GEOM_PART_MBR + +# Store the plain version of the configuration file in the kernel itself. +# To store the entire file, including comments, put this in /etc/src.conf: +# CONFIGARGS= -C +# See config(8) for more details. +# +options INCLUDE_CONFIG_FILE # Include this file in kernel diff --git a/sys/mips/conf/DEFAULTS b/sys/mips/conf/DEFAULTS index dc480cea27a..98337445e59 100644 --- a/sys/mips/conf/DEFAULTS +++ b/sys/mips/conf/DEFAULTS @@ -11,3 +11,10 @@ device uart_ns8250 options GEOM_PART_BSD options GEOM_PART_MBR + +# Store the plain version of the configuration file in the kernel itself. +# To store the entire file, including comments, put this in /etc/src.conf: +# CONFIGARGS= -C +# See config(8) for more details. +# +options INCLUDE_CONFIG_FILE # Include this file in kernel diff --git a/sys/pc98/conf/DEFAULTS b/sys/pc98/conf/DEFAULTS index 0002cf0a30c..bd0afd6ca80 100644 --- a/sys/pc98/conf/DEFAULTS +++ b/sys/pc98/conf/DEFAULTS @@ -24,3 +24,10 @@ device uart_ns8250 # Default partitioning schemes options GEOM_PART_BSD options GEOM_PART_PC98 + +# Store the plain version of the configuration file in the kernel itself. +# To store the entire file, including comments, put this in /etc/src.conf: +# CONFIGARGS= -C +# See config(8) for more details. +# +options INCLUDE_CONFIG_FILE # Include this file in kernel diff --git a/sys/powerpc/conf/DEFAULTS b/sys/powerpc/conf/DEFAULTS index 7c981d147ba..30b54291c7d 100644 --- a/sys/powerpc/conf/DEFAULTS +++ b/sys/powerpc/conf/DEFAULTS @@ -14,3 +14,10 @@ device uart_z8530 options GEOM_PART_APM options GEOM_PART_MBR + +# Store the plain version of the configuration file in the kernel itself. +# To store the entire file, including comments, put this in /etc/src.conf: +# CONFIGARGS= -C +# See config(8) for more details. +# +options INCLUDE_CONFIG_FILE # Include this file in kernel diff --git a/sys/sparc64/conf/DEFAULTS b/sys/sparc64/conf/DEFAULTS index 38b2408bf44..32a79b105f8 100644 --- a/sys/sparc64/conf/DEFAULTS +++ b/sys/sparc64/conf/DEFAULTS @@ -19,3 +19,10 @@ options GEOM_PART_VTOC8 # Let sunkbd emulate an AT keyboard by default. options SUNKBD_EMULATE_ATKBD + +# Store the plain version of the configuration file in the kernel itself. +# To store the entire file, including comments, put this in /etc/src.conf: +# CONFIGARGS= -C +# See config(8) for more details. +# +options INCLUDE_CONFIG_FILE # Include this file in kernel diff --git a/sys/sun4v/conf/DEFAULTS b/sys/sun4v/conf/DEFAULTS index 610d65333a0..a610d779a5f 100644 --- a/sys/sun4v/conf/DEFAULTS +++ b/sys/sun4v/conf/DEFAULTS @@ -11,3 +11,10 @@ device mem # Memory and kernel memory devices # Default partitioning schemes options GEOM_PART_BSD options GEOM_PART_VTOC8 + +# Store the plain version of the configuration file in the kernel itself. +# To store the entire file, including comments, put this in /etc/src.conf: +# CONFIGARGS= -C +# See config(8) for more details. +# +options INCLUDE_CONFIG_FILE # Include this file in kernel From 79a07a2e0cd3456de5075ba8ee1831655c1a1953 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Tue, 29 Dec 2009 07:08:48 +0000 Subject: [PATCH 0956/2592] MFC r200448: Since the change to rc.subr in r198162 it's not necessary to specify command in the rc.d script if we have a corresponding ${name}_program entry, which we do for named. Rename named_precmd to named_prestart to make it more clear and match convention. Move the command_args definition related to -u up into _prestart(). It (and the associated $named_uid value) are only used there, and unlike required_* and pidfile don't need to be used until this stage. Fix a silly bug that would only have affected people who were using the new named_wait or named_auto_forward features, AND had set up an rndc.conf file instead of using the automatically generated rndc.key. For named_conf: Add "-c $named_conf" to command_args if it's not set to the default. If it is set to the default and we're using the base BIND it's not necessary. If we're using BIND from the ports the user is likely to have included it in _flags (due to long necessity for doing so) so don't duplicate that if it's set. Add $named_conf to required_files MFC r200563: The named process needs to have a "working directory" that it can write to. This is specified in "options { directory }" in named.conf. So, create /etc/namedb/working with appropriate permissions, and update the entry in named.conf to match. In addition to specifying the working directory, file and path names in named.conf can be specified relative to the directory listed. However, since that directory is now different from /etc/namedb (where the configuration, zone, rndc.*, and other files are located) further update named.conf to specify all file names with fully qualified paths. Also update the comment about file and path names so users know this should be done for all file/path names in the file. This change will eliminate the 'working directory is not writable' messages at boot time without sacrificing security. It will also allow for features in newer versions of BIND (9.7+) to work as designed. --- etc/mtree/BIND.chroot.dist | 2 + etc/namedb/named.conf | 190 ++++++++++++++++++------------------- etc/rc.d/named | 23 +++-- 3 files changed, 113 insertions(+), 102 deletions(-) diff --git a/etc/mtree/BIND.chroot.dist b/etc/mtree/BIND.chroot.dist index e41a369a426..95423db5cd2 100644 --- a/etc/mtree/BIND.chroot.dist +++ b/etc/mtree/BIND.chroot.dist @@ -15,6 +15,8 @@ .. slave uname=bind .. + working uname=bind + .. .. .. /set type=dir uname=bind gname=wheel mode=0755 diff --git a/etc/namedb/named.conf b/etc/namedb/named.conf index c9b09cba7ce..2fb72d8fce1 100644 --- a/etc/namedb/named.conf +++ b/etc/namedb/named.conf @@ -9,8 +9,9 @@ // or cause huge amounts of useless Internet traffic. options { - // Relative to the chroot directory, if any - directory "/etc/namedb"; + // All file and path names are relative to the chroot directory, + // if any, and should be fully qualified. + directory "/etc/namedb/working"; pid-file "/var/run/named/pid"; dump-file "/var/dump/named_dump.db"; statistics-file "/var/stats/named.stats"; @@ -74,7 +75,7 @@ options { // Also, make sure to enable it in /etc/rc.conf. // The traditional root hints mechanism. Use this, OR the slave zones below. -zone "." { type hint; file "named.root"; }; +zone "." { type hint; file "/etc/namedb/named.root"; }; /* Slaving the following zones from the root name servers has some significant advantages: @@ -94,7 +95,7 @@ zone "." { type hint; file "named.root"; }; /* zone "." { type slave; - file "slave/root.slave"; + file "/etc/namedb/slave/root.slave"; masters { 192.5.5.241; // F.ROOT-SERVERS.NET. }; @@ -102,7 +103,7 @@ zone "." { }; zone "arpa" { type slave; - file "slave/arpa.slave"; + file "/etc/namedb/slave/arpa.slave"; masters { 192.5.5.241; // F.ROOT-SERVERS.NET. }; @@ -110,7 +111,7 @@ zone "arpa" { }; zone "in-addr.arpa" { type slave; - file "slave/in-addr.arpa.slave"; + file "/etc/namedb/slave/in-addr.arpa.slave"; masters { 192.5.5.241; // F.ROOT-SERVERS.NET. }; @@ -125,116 +126,116 @@ zone "in-addr.arpa" { 2. No spurious traffic will be sent from your network to the roots */ // RFC 1912 -zone "localhost" { type master; file "master/localhost-forward.db"; }; -zone "127.in-addr.arpa" { type master; file "master/localhost-reverse.db"; }; -zone "255.in-addr.arpa" { type master; file "master/empty.db"; }; +zone "localhost" { type master; file "/etc/namedb/master/localhost-forward.db"; }; +zone "127.in-addr.arpa" { type master; file "/etc/namedb/master/localhost-reverse.db"; }; +zone "255.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // RFC 1912-style zone for IPv6 localhost address -zone "0.ip6.arpa" { type master; file "master/localhost-reverse.db"; }; +zone "0.ip6.arpa" { type master; file "/etc/namedb/master/localhost-reverse.db"; }; // "This" Network (RFCs 1912 and 3330) -zone "0.in-addr.arpa" { type master; file "master/empty.db"; }; +zone "0.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // Private Use Networks (RFC 1918) -zone "10.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "16.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "17.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "18.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "19.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "20.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "21.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "22.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "23.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "24.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "25.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "26.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "27.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "28.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "29.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "30.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "31.172.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "168.192.in-addr.arpa" { type master; file "master/empty.db"; }; +zone "10.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "16.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "17.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "18.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "19.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "20.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "21.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "22.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "23.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "24.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "25.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "26.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "27.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "28.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "29.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "30.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "31.172.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "168.192.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // Link-local/APIPA (RFCs 3330 and 3927) -zone "254.169.in-addr.arpa" { type master; file "master/empty.db"; }; +zone "254.169.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // TEST-NET for Documentation (RFC 3330) -zone "2.0.192.in-addr.arpa" { type master; file "master/empty.db"; }; +zone "2.0.192.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // Router Benchmark Testing (RFC 3330) -zone "18.198.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "19.198.in-addr.arpa" { type master; file "master/empty.db"; }; +zone "18.198.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "19.198.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // IANA Reserved - Old Class E Space -zone "240.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "241.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "242.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "243.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "244.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "245.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "246.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "247.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "248.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "249.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "250.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "251.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "252.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "253.in-addr.arpa" { type master; file "master/empty.db"; }; -zone "254.in-addr.arpa" { type master; file "master/empty.db"; }; +zone "240.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "241.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "242.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "243.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "244.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "245.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "246.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "247.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "248.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "249.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "250.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "251.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "252.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "253.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "254.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // IPv6 Unassigned Addresses (RFC 4291) -zone "1.ip6.arpa" { type master; file "master/empty.db"; }; -zone "3.ip6.arpa" { type master; file "master/empty.db"; }; -zone "4.ip6.arpa" { type master; file "master/empty.db"; }; -zone "5.ip6.arpa" { type master; file "master/empty.db"; }; -zone "6.ip6.arpa" { type master; file "master/empty.db"; }; -zone "7.ip6.arpa" { type master; file "master/empty.db"; }; -zone "8.ip6.arpa" { type master; file "master/empty.db"; }; -zone "9.ip6.arpa" { type master; file "master/empty.db"; }; -zone "a.ip6.arpa" { type master; file "master/empty.db"; }; -zone "b.ip6.arpa" { type master; file "master/empty.db"; }; -zone "c.ip6.arpa" { type master; file "master/empty.db"; }; -zone "d.ip6.arpa" { type master; file "master/empty.db"; }; -zone "e.ip6.arpa" { type master; file "master/empty.db"; }; -zone "0.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "1.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "2.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "3.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "4.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "5.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "6.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "7.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "8.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "9.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "a.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "b.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "0.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "1.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "2.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "3.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "4.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "5.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "6.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "7.e.f.ip6.arpa" { type master; file "master/empty.db"; }; +zone "1.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "3.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "4.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "5.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "6.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "7.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "8.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "9.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "a.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "b.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "c.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "d.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "e.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "0.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "1.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "2.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "3.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "4.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "5.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "6.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "7.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "8.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "9.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "a.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "b.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "0.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "1.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "2.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "3.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "4.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "5.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "6.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "7.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // IPv6 ULA (RFC 4193) -zone "c.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "d.f.ip6.arpa" { type master; file "master/empty.db"; }; +zone "c.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "d.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // IPv6 Link Local (RFC 4291) -zone "8.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "9.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "a.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "b.e.f.ip6.arpa" { type master; file "master/empty.db"; }; +zone "8.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "9.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "a.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "b.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // IPv6 Deprecated Site-Local Addresses (RFC 3879) -zone "c.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "d.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "e.e.f.ip6.arpa" { type master; file "master/empty.db"; }; -zone "f.e.f.ip6.arpa" { type master; file "master/empty.db"; }; +zone "c.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "d.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "e.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; +zone "f.e.f.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; }; // IP6.INT is Deprecated (RFC 4159) -zone "ip6.int" { type master; file "master/empty.db"; }; +zone "ip6.int" { type master; file "/etc/namedb/master/empty.db"; }; // NB: Do not use the IP addresses below, they are faked, and only // serve demonstration/documentation purposes! @@ -265,17 +266,16 @@ zone "example.org" { allow-update { key "exampleorgkey"; }; - file "dynamic/example.org"; + file "/etc/namedb/dynamic/example.org"; }; */ /* Example of a slave reverse zone zone "1.168.192.in-addr.arpa" { type slave; - file "slave/1.168.192.in-addr.arpa"; + file "/etc/namedb/slave/1.168.192.in-addr.arpa"; masters { 192.168.1.1; }; }; */ - diff --git a/etc/rc.d/named b/etc/rc.d/named index 65a13a54eb9..6e03a2c857d 100755 --- a/etc/rc.d/named +++ b/etc/rc.d/named @@ -12,10 +12,9 @@ name="named" rcvar=named_enable -command="/usr/sbin/named" extra_commands="reload" -start_precmd="named_precmd" +start_precmd="named_prestart" start_postcmd="named_poststart" reload_cmd="named_reload" stop_cmd="named_stop" @@ -155,8 +154,17 @@ create_file () { chmod 644 $1 } -named_precmd() +named_prestart() { + command_args="-u ${named_uid:=root}" + + if [ ! "$named_conf" = '/etc/namedb/named.conf' ]; then + case "$named_flags" in + -c*|*' -c'*) ;; # No need to add it + *) command_args="-c $named_conf $command_args" ;; + esac + fi + local line nsip firstns # Is the user using a sandbox? @@ -170,11 +178,11 @@ named_precmd() # Create an rndc.key file for the user if none exists # - if [ -s "${named_chrootdir}/etc/namedb/rndc.conf" ]; then - return 0 - fi confgen_command="${command%/named}/rndc-confgen -a -b256 -u $named_uid \ -c ${named_chrootdir}/etc/namedb/rndc.key" + if [ -s "${named_chrootdir}/etc/namedb/rndc.conf" ]; then + unset confgen_command + fi if [ -s "${named_chrootdir}/etc/namedb/rndc.key" ]; then case `stat -f%Su ${named_chrootdir}/etc/namedb/rndc.key` in root|$named_uid) ;; @@ -260,10 +268,11 @@ named_precmd() } load_rc_config $name + # Updating the following variables requires that rc.conf be loaded first # required_dirs="$named_chrootdir" # if it is set, it must exist +required_files="${named_conf:=/etc/namedb/named.conf}" pidfile="${named_pidfile:-/var/run/named/pid}" -command_args="-u ${named_uid:=root}" run_rc_command "$1" From dd1c9c3da432e42685fd7aac70b125e6ebcf2019 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Tue, 29 Dec 2009 10:05:20 +0000 Subject: [PATCH 0957/2592] MFC of r200832, tzdata2009t zic: - Fix URL / reference to Calendrical Calculations: Third Edition libc/stdtime: - Fix typo in tzfile.5 (no changes in our part) --- lib/libc/stdtime/tzfile.5 | 2 +- usr.sbin/zic/Theory | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/libc/stdtime/tzfile.5 b/lib/libc/stdtime/tzfile.5 index 15625d273c9..1606b5ae8c4 100644 --- a/lib/libc/stdtime/tzfile.5 +++ b/lib/libc/stdtime/tzfile.5 @@ -147,6 +147,6 @@ such instants). .Xr ctime 3 , .Xr time2posix 3 , .Xr zic 8 -.\" @(#)tzfile.5 8.2 +.\" @(#)tzfile.5 8.3 .\" This file is in the public domain, so clarified as of .\" 1996-06-05 by Arthur David Olson. diff --git a/usr.sbin/zic/Theory b/usr.sbin/zic/Theory index 8e933659a46..752125c95a5 100644 --- a/usr.sbin/zic/Theory +++ b/usr.sbin/zic/Theory @@ -1,4 +1,4 @@ -@(#)Theory 8.3 +@(#)Theory 8.4 This file is in the public domain, so clarified as of 2009-05-17 by Arthur David Olson. $FreeBSD$ @@ -361,10 +361,10 @@ abbreviations like `EST'; this avoids the ambiguity. Calendrical issues are a bit out of scope for a time zone database, but they indicate the sort of problems that we would run into if we extended the time zone database further into the past. An excellent -resource in this area is Edward M. Reingold and Nachum Dershowitz, - -Calendrical Calculations: The Millennium Edition -, Cambridge University Press (2001). Other information and +resource in this area is Nachum Dershowitz and Edward M. Reingold, + +Calendrical Calculations: Third Edition +, Cambridge University Press (2008). Other information and sources are given below. They sometimes disagree. From 85e1d32e21b0c912a115e16a209aa2adfd697406 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Tue, 29 Dec 2009 10:07:09 +0000 Subject: [PATCH 0958/2592] MFC of r200835, tzcode2009t Comment only, no data changes. --- share/zoneinfo/asia | 69 +++++++++++++++++++++++++++++++++++++++-- share/zoneinfo/europe | 26 +++++++++++----- share/zoneinfo/zone.tab | 2 +- 3 files changed, 86 insertions(+), 11 deletions(-) diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia index 1987fc815ba..a95a934b56e 100644 --- a/share/zoneinfo/asia +++ b/share/zoneinfo/asia @@ -1,4 +1,4 @@ -# @(#)asia 8.44 +# @(#)asia 8.48 # This file is in the public domain, so clarified as of # 2009-05-17 by Arthur David Olson. @@ -363,6 +363,69 @@ Zone Asia/Urumqi 5:50:20 - LMT 1928 # or Urumchi # West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke, # Zhaosu, Tekesi, Gongliu, Chabuchaer, Huocheng, Bole, Pishan, Suiding, # and Yarkand. + +# From Luther Ma (2009-10-17): +# Almost all (>99.9%) ethnic Chinese (properly ethnic Han) living in +# Xinjiang use Chinese Standard Time. Some are aware of Xinjiang time, +# but have no need of it. All planes, trains, and schools function on +# what is called "Beijing time." When Han make an appointment in Chinese +# they implicitly use Beijing time. +# +# On the other hand, ethnic Uyghurs, who make up about half the +# population of Xinjiang, typically use "Xinjiang time" which is two +# hours behind Beijing time, or UTC +0600. The government of the Xinjiang +# Uyghur Autonomous Region, (XAUR, or just Xinjiang for short) as well as +# local governments such as the Urumqi city government use both times in +# publications, referring to what is popularly called Xinjiang time as +# "Urumqi time." When Uyghurs make an appointment in the Uyghur language +# they almost invariably use Xinjiang time. +# +# (Their ethnic Han compatriots would typically have no clue of its +# widespread use, however, because so extremely few of them are fluent in +# Uyghur, comparable to the number of Anglo-Americans fluent in Navajo.) +# +# (...As with the rest of China there was a brief interval ending in 1990 +# or 1991 when summer time was in use. The confusion was severe, with +# the province not having dual times but four times in use at the same +# time. Some areas remained on standard Xinjiang time or Beijing time and +# others moving their clocks ahead.) +# +# ...an example of an official website using of Urumqi time. +# +# The first few lines of the Google translation of +# +# http://www.fjysgl.gov.cn/show.aspx?id=2379&cid=39 +# +# (retrieved 2009-10-13) +# > Urumqi fire seven people are missing the alleged losses of at least +# > 500 million yuan +# > +# > (Reporter Dong Liu) the day before 20:20 or so (Urumqi Time 18:20), +# > Urumqi City Department of International Plaza Luther Qiantang River +# > burst fire. As of yesterday, 18:30, Urumqi City Fire officers and men +# > have worked continuously for 22 hours... + +# From Luther Ma (2009-11-19): +# With the risk of being redundant to previous answers these are the most common +# English "transliterations" (w/o using non-English symbols): +# +# 1. Wulumuqi... +# 2. Kashi... +# 3. Urumqi... +# 4. Kashgar... +# ... +# 5. It seems that Uyghurs in Urumqi has been using Xinjiang since at least the +# 1960's. I know of one Han, now over 50, who grew up in the surrounding +# countryside and used Xinjiang time as a child. +# +# 6. Likewise for Kashgar and the rest of south Xinjiang I don't know of any +# start date for Xinjiang time. +# +# Without having access to local historical records, nor the ability to legally +# publish them, I would go with October 1, 1949, when Xinjiang became the Uyghur +# Autonomous Region under the PRC. (Before that Uyghurs, of course, would also +# not be using Beijing time, but some local time.) + Zone Asia/Kashgar 5:03:56 - LMT 1928 # or Kashi or Kaxgar 5:30 - KAST 1940 # Kashgar Time 5:00 - KAST 1980 May @@ -370,8 +433,8 @@ Zone Asia/Kashgar 5:03:56 - LMT 1928 # or Kashi or Kaxgar # 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, +# I found there are some mistakes for the...DST rule for Hong +# Kong. [According] 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 diff --git a/share/zoneinfo/europe b/share/zoneinfo/europe index 66ab880e8eb..05e3caec3ae 100644 --- a/share/zoneinfo/europe +++ b/share/zoneinfo/europe @@ -1,5 +1,5 @@ #
-# @(#)europe	8.24
+# @(#)europe	8.25
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -2130,12 +2130,20 @@ Zone Asia/Irkutsk	 6:57:20 -	LMT	1880
 # From Oscar van Vlijmen (2003-10-18): [This region consists of]
 # Aginskij Buryatskij avtonomnyj okrug, Amurskaya oblast',
 # [parts of] Respublika Sakha (Yakutiya), Chitinskaya oblast'.
+
+# From Oscar van Vlijmen (2009-11-29):
+# ...some regions of RUssia were merged with others since 2005...
+# Some names were changed, no big deal, except for one instance: a new name.
+# YAK/YAKST: UTC+9 Zabajkal'skij kraj.
+
+# From Oscar van Vlijmen (2009-11-29):
 # The Sakha districts are: Aldanskij, Amginskij, Anabarskij,
-# Bulunskij, Verkhnekolymskij, Verkhnevilyujskij, Vilyujskij, Gornyj,
+# Verkhnevilyujskij, Vilyujskij, Gornyj,
 # Zhiganskij, Kobyajskij, Lenskij, Megino-Kangalasskij, Mirninskij,
-# Namskij, Nyurbinskij, Olenekskij, Olekminskij, Srednekolymskij,
+# Namskij, Nyurbinskij, Olenyokskij, Olyokminskij,
 # Suntarskij, Tattinskij, Ust'-Aldanskij, Khangalasskij,
-# Churapchinskij, Eveno-Bytantajskij.
+# Churapchinskij, Eveno-Bytantajskij Natsional'nij.
+
 Zone Asia/Yakutsk	 8:38:40 -	LMT	1919 Dec 15
 			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
 			 9:00	Russia	YAK%sT	1991 Mar 31 2:00s
@@ -2145,7 +2153,9 @@ Zone Asia/Yakutsk	 8:38:40 -	LMT	1919 Dec 15
 # From Oscar van Vlijmen (2003-10-18): [This region consists of]
 # Evrejskaya avtonomnaya oblast', Khabarovskij kraj, Primorskij kraj,
 # [parts of] Respublika Sakha (Yakutiya).
-# The Sakha districts are: Verkhoyanskij, Tomponskij, Ust'-Majskij,
+
+# From Oscar van Vlijmen (2009-11-29):
+# The Sakha districts are: Bulunskij, Verkhoyanskij, Tomponskij, Ust'-Majskij,
 # Ust'-Yanskij.
 Zone Asia/Vladivostok	 8:47:44 -	LMT	1922 Nov 15
 			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
@@ -2166,8 +2176,10 @@ Zone Asia/Sakhalin	 9:30:48 -	LMT	1905 Aug 23
 # From Oscar van Vlijmen (2003-10-18): [This region consists of]
 # Magadanskaya oblast', Respublika Sakha (Yakutiya).
 # Probably also: Kuril Islands.
-# The Sakha districts are: Abyjskij, Allaikhovskij, Momskij,
-# Nizhnekolymskij, Ojmyakonskij.
+
+# From Oscar van Vlijmen (2009-11-29):
+# The Sakha districts are: Abyjskij, Allaikhovskij, Verkhhhnekolymskij, Momskij,
+# Nizhnekolymskij, Ojmyakonskij, Srednekolymskij.
 Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
 			10:00	-	MAGT	1930 Jun 21 # Magadan Time
 			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
diff --git a/share/zoneinfo/zone.tab b/share/zoneinfo/zone.tab
index 8b40a34a05a..dab18c318d1 100644
--- a/share/zoneinfo/zone.tab
+++ b/share/zoneinfo/zone.tab
@@ -1,5 +1,5 @@
 # 
-# @(#)zone.tab	8.29
+# @(#)zone.tab	8.31
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 #

From d4b8091dc36aa3bfc680187ad492c17ea3e0d512 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Tue, 29 Dec 2009 10:15:11 +0000
Subject: [PATCH 0959/2592] MFC of tzdata2009u, 201189

Bangladesh will change its clock back to Standard Time on Dec 31, 2009.
---
 share/zoneinfo/asia | 41 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia
index a95a934b56e..b7aa43a6b55 100644
--- a/share/zoneinfo/asia
+++ b/share/zoneinfo/asia
@@ -1,4 +1,4 @@
-# @(#)asia	8.48
+# @(#)asia	8.50
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -196,6 +196,41 @@ Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al Manamah
 # http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html
 # 
 
+# From Alexander Krivenyshev (2009-12-24):
+# According to Bangladesh newspaper "The Daily Star,"
+# Bangladesh will change its clock back to Standard Time on Dec 31, 2009.
+#
+# Clock goes back 1-hr on Dec 31 night.
+# 
+# http://www.thedailystar.net/newDesign/news-details.php?nid=119228
+# 
+# and
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh05.html
+# 
+#
+# "...The government yesterday decided to put the clock back by one hour
+# on December 31 midnight and the new time will continue until March 31,
+# 2010 midnight. The decision came at a cabinet meeting at the Prime
+# Minister's Office last night..."
+
+# From Danvin Ruangchan (2009-12-24):
+# ...the news mentions DST will be turned off again 7 months after March
+# 31st on Oct 31, 2010.
+
+# From Arthur David Olson (2009-12-26):
+# Indeed, "The government will advance again the Banglasdesh Standard
+# Time by one one hour on March 31 next year by enforcing the Daylight
+# Saving Time (DST) for seven months. It will continue till October 31
+# until further notice." I take that last sentence as the
+# establishment of a rule.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Dhaka	2009	only	-	Jun	29	23:00	1	S
+Rule	Dhaka	2010	only	-	Jan	1	0:00	-	-
+Rule	Dhaka	2010	max	-	Mar	31	23:00	1	S
+Rule	Dhaka	2010	max	-	Nov	1	0:00	-	-
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Dhaka	6:01:40 -	LMT	1890
 			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
@@ -203,8 +238,8 @@ Zone	Asia/Dhaka	6:01:40 -	LMT	1890
 			5:30	-	IST	1942 Sep
 			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
+			6:00	-	BDT	2009
+			6:00	Dhaka	BD%sT
 
 # Bhutan
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]

From 1a7528a780e33e7c8b6cc918332ed66e37227d31 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 29 Dec 2009 21:23:18 +0000
Subject: [PATCH 0960/2592] MFC r200821: Make graid3 fallback to malloc() when
 component request size is bigger then maximal prepared UMA zone size. This
 fixes crash with MAXPHYS > 128K.

---
 sys/geom/raid3/g_raid3.c | 20 ++++++++++++--------
 sys/geom/raid3/g_raid3.h |  4 +++-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c
index 1cbce257b59..0feca0c8482 100644
--- a/sys/geom/raid3/g_raid3.c
+++ b/sys/geom/raid3/g_raid3.c
@@ -183,15 +183,17 @@ static void *
 g_raid3_alloc(struct g_raid3_softc *sc, size_t size, int flags)
 {
 	void *ptr;
+	enum g_raid3_zones zone;
 
-	if (g_raid3_use_malloc)
+	if (g_raid3_use_malloc ||
+	    (zone = g_raid3_zone(size)) == G_RAID3_NUM_ZONES)
 		ptr = malloc(size, M_RAID3, flags);
 	else {
-		ptr = uma_zalloc_arg(sc->sc_zones[g_raid3_zone(size)].sz_zone,
-		   &sc->sc_zones[g_raid3_zone(size)], flags);
-		sc->sc_zones[g_raid3_zone(size)].sz_requested++;
+		ptr = uma_zalloc_arg(sc->sc_zones[zone].sz_zone,
+		   &sc->sc_zones[zone], flags);
+		sc->sc_zones[zone].sz_requested++;
 		if (ptr == NULL)
-			sc->sc_zones[g_raid3_zone(size)].sz_failed++;
+			sc->sc_zones[zone].sz_failed++;
 	}
 	return (ptr);
 }
@@ -199,12 +201,14 @@ g_raid3_alloc(struct g_raid3_softc *sc, size_t size, int flags)
 static void
 g_raid3_free(struct g_raid3_softc *sc, void *ptr, size_t size)
 {
+	enum g_raid3_zones zone;
 
-	if (g_raid3_use_malloc)
+	if (g_raid3_use_malloc ||
+	    (zone = g_raid3_zone(size)) == G_RAID3_NUM_ZONES)
 		free(ptr, M_RAID3);
 	else {
-		uma_zfree_arg(sc->sc_zones[g_raid3_zone(size)].sz_zone,
-		    ptr, &sc->sc_zones[g_raid3_zone(size)]);
+		uma_zfree_arg(sc->sc_zones[zone].sz_zone,
+		    ptr, &sc->sc_zones[zone]);
 	}
 }
 
diff --git a/sys/geom/raid3/g_raid3.h b/sys/geom/raid3/g_raid3.h
index a3759999935..5daf16d2077 100644
--- a/sys/geom/raid3/g_raid3.h
+++ b/sys/geom/raid3/g_raid3.h
@@ -183,7 +183,9 @@ enum g_raid3_zones {
 
 static __inline enum g_raid3_zones
 g_raid3_zone(size_t nbytes) {
-	if (nbytes > 16384)
+	if (nbytes > 65536)
+		return (G_RAID3_NUM_ZONES);
+	else if (nbytes > 16384)
 		return (G_RAID3_ZONE_64K);
 	else if (nbytes > 4096)
 		return (G_RAID3_ZONE_16K);

From 0900fee4fb49d451bb2f27bf4a201f0d3034677a Mon Sep 17 00:00:00 2001
From: Markus Brueffer 
Date: Wed, 30 Dec 2009 16:37:58 +0000
Subject: [PATCH 0961/2592] MFC r200992:

Use a local copy of entry_d for finding matches. Otherwise, if entry_d pointed
to an entry of 'acl', all ACL entries starting with entry_d would be deleted.

Approved by:	emax (mentor)
---
 lib/libc/posix1e/acl_delete_entry.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/libc/posix1e/acl_delete_entry.c b/lib/libc/posix1e/acl_delete_entry.c
index 7dd60b82182..09b450729aa 100644
--- a/lib/libc/posix1e/acl_delete_entry.c
+++ b/lib/libc/posix1e/acl_delete_entry.c
@@ -75,6 +75,7 @@ int
 acl_delete_entry(acl_t acl, acl_entry_t entry_d)
 {
 	struct acl *acl_int;
+	struct acl_entry entry_int;
 	int i, j, found = 0;
 
 	if (acl == NULL || entry_d == NULL) {
@@ -94,8 +95,12 @@ acl_delete_entry(acl_t acl, acl_entry_t entry_d)
 		errno = EINVAL;
 		return (-1);
 	}
+
+	/* Use a local copy to prevent deletion of more than this entry */
+	entry_int = *entry_d;
+
 	for (i = 0; i < acl->ats_acl.acl_cnt;) {
-		if (_entry_matches(&(acl->ats_acl.acl_entry[i]), entry_d)) {
+		if (_entry_matches(&(acl->ats_acl.acl_entry[i]), &entry_int)) {
 			/* ...shift the remaining entries... */
 			for (j = i; j < acl->ats_acl.acl_cnt - 1; ++j)
 				acl->ats_acl.acl_entry[j] =

From 694faf6751058a68851e1a2c29fc90933b09854c Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Wed, 30 Dec 2009 17:22:00 +0000
Subject: [PATCH 0962/2592] MFC r199844:

Reset path name back to original correctly in fts_build() when
FTS_NOCHDIR option is used. fts_build() could strip a trailing slash
from path name in post-order visit if a path pointing to an empty
directory was given for fts_open().

PR:		bin/133907, kern/134513
Approved by:	trasz (mentor)
---
 lib/libc/gen/fts.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c
index 41443c5795c..88f1a2315b8 100644
--- a/lib/libc/gen/fts.c
+++ b/lib/libc/gen/fts.c
@@ -836,11 +836,8 @@ mem1:				saved_errno = errno;
 	 * If not changing directories, reset the path back to original
 	 * state.
 	 */
-	if (ISSET(FTS_NOCHDIR)) {
-		if (len == sp->fts_pathlen || nitems == 0)
-			--cp;
-		*cp = '\0';
-	}
+	if (ISSET(FTS_NOCHDIR))
+		sp->fts_path[cur->fts_pathlen] = '\0';
 
 	/*
 	 * If descended after called from fts_children or after called from

From 58f48e4ba685d068fad50e9c5eb9cefd6974e3a8 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 30 Dec 2009 17:42:41 +0000
Subject: [PATCH 0963/2592] MFC 200872: Don't build zfsboot, gptzfsboot, and
 zfsloader if WITHOUT_ZFS is enabled.

---
 sys/boot/i386/Makefile | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/sys/boot/i386/Makefile b/sys/boot/i386/Makefile
index 789722cae95..3c05759fcf0 100644
--- a/sys/boot/i386/Makefile
+++ b/sys/boot/i386/Makefile
@@ -1,9 +1,15 @@
 # $FreeBSD$
 
-SUBDIR=		mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot zfsboot \
-		gptzfsboot kgzldr libi386 libfirewire loader zfsloader
+.include 
+
+SUBDIR=		mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot kgzldr \
+		libi386 libfirewire loader
 
 # special boot programs, 'self-extracting boot2+loader'
 SUBDIR+=	pxeldr
 
+.if ${MK_ZFS} != "no"
+SUBDIR+=	zfsboot gptzfsboot zfsloader
+.endif
+
 .include 

From abd97995f5f6f8a723fe6c8499ddd1267b9e33a2 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 30 Dec 2009 17:53:07 +0000
Subject: [PATCH 0964/2592] MFC 200919: Fix a bug in gzipfs that prevented
 lseek() from working and add lseek() support to bzip2fs.  This fixes problems
 with loading compressed amd64 kernel modules containing debug symbols.

---
 lib/libstand/bzipfs.c | 67 +++++++++++++++++++++++++++++++++++++------
 lib/libstand/gzipfs.c | 16 +++++------
 2 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/lib/libstand/bzipfs.c b/lib/libstand/bzipfs.c
index 47c799f5734..46a151bc1cd 100644
--- a/lib/libstand/bzipfs.c
+++ b/lib/libstand/bzipfs.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
 #ifndef REGRESSION
 #include "stand.h"
 #else
+#include 
 #include 
 #include 
 #include 
@@ -42,7 +43,7 @@ struct open_file {
 };
 #define F_READ          0x0001  /* file opened for reading */
 #define EOFFSET (ELAST+8)       /* relative seek not supported */
-static inline u_int min(u_int a, u_int b) { return (a < b ? a : b); }
+static inline u_int min(u_int a, u_int b) { return(a < b ? a : b); }
 #define panic(x, y) abort()
 #endif
 
@@ -174,6 +175,8 @@ bzf_open(const char *fname, struct open_file *f)
 
     /* Construct new name */
     bzfname = malloc(strlen(fname) + 5);
+    if (bzfname == NULL)
+	return(ENOMEM);
     sprintf(bzfname, "%s.bz2", fname);
 
     /* Try to open the compressed datafile */
@@ -195,13 +198,14 @@ bzf_open(const char *fname, struct open_file *f)
 
     /* Allocate a bz_file structure, populate it */
     bzf = malloc(sizeof(struct bz_file));
+    if (bzf == NULL)
+	return(ENOMEM);
     bzero(bzf, sizeof(struct bz_file));
     bzf->bzf_rawfd = rawfd;
 
-    /* Verify that the file is bzipped (XXX why do this afterwards?) */
+    /* Verify that the file is bzipped */
     if (check_header(bzf)) {
 	close(bzf->bzf_rawfd);
-	BZ2_bzDecompressEnd(&(bzf->bzf_bzstream));
 	free(bzf);
 	return(EFTYPE);
     }
@@ -247,7 +251,7 @@ bzf_read(struct open_file *f, void *buf, size_t size, size_t *resid)
 	if (bzf->bzf_bzstream.avail_in == 0) {		/* oops, unexpected EOF */
 	    printf("bzf_read: unexpected EOF\n");
 	    if (bzf->bzf_bzstream.avail_out == size)
-		return (EIO);
+		return(EIO);
 	    break;
 	}
 
@@ -266,6 +270,50 @@ bzf_read(struct open_file *f, void *buf, size_t size, size_t *resid)
     return(0);
 }
 
+static int
+bzf_rewind(struct open_file *f)
+{
+    struct bz_file	*bzf = (struct bz_file *)f->f_fsdata;
+    struct bz_file	*bzf_tmp;
+
+    /*
+     * Since bzip2 does not have an equivalent inflateReset function a crude
+     * one needs to be provided.  The functions all called in such a way that
+     * at any time an error occurs a role back can be done (effectively making
+     * this rewind 'atomic', either the reset occurs successfully or not at all,
+     * with no 'undefined' state happening).
+     */
+
+    /* Allocate a bz_file structure, populate it */
+    bzf_tmp = malloc(sizeof(struct bz_file));
+    if (bzf_tmp == NULL)
+	return(-1);
+    bzero(bzf_tmp, sizeof(struct bz_file));
+    bzf_tmp->bzf_rawfd = bzf->bzf_rawfd;
+
+    /* Initialise the inflation engine */
+    if (BZ2_bzDecompressInit(&(bzf_tmp->bzf_bzstream), 0, 1) != BZ_OK) {
+	free(bzf_tmp);
+	return(-1);
+    }
+
+    /* Seek back to the beginning of the file */
+    if (lseek(bzf->bzf_rawfd, 0, SEEK_SET) == -1) {
+	BZ2_bzDecompressEnd(&(bzf_tmp->bzf_bzstream));
+	free(bzf_tmp);
+	return(-1);
+    }
+
+    /* Free old bz_file data */
+    BZ2_bzDecompressEnd(&(bzf->bzf_bzstream));
+    free(bzf);
+
+    /* Use the new bz_file data */
+    f->f_fsdata = bzf_tmp;
+
+    return(0);
+}
+
 static off_t
 bzf_seek(struct open_file *f, off_t offset, int where)
 {
@@ -284,14 +332,17 @@ bzf_seek(struct open_file *f, off_t offset, int where)
 	target = -1;
     default:
 	errno = EINVAL;
-	return (-1);
+	return(-1);
     }
 
     /* Can we get there from here? */
-    if (target < bzf->bzf_bzstream.total_out_lo32) {
+    if (target < bzf->bzf_bzstream.total_out_lo32 && bzf_rewind(f) != 0) {
 	errno = EOFFSET;
 	return -1;
-    } 
+    }
+
+    /* if bzf_rewind was called then bzf has changed */
+    bzf = (struct bz_file *)f->f_fsdata;
 
     /* skip forwards if required */
     while (target > bzf->bzf_bzstream.total_out_lo32) {
@@ -301,7 +352,7 @@ bzf_seek(struct open_file *f, off_t offset, int where)
 	    return(-1);
     }
     /* This is where we are (be honest if we overshot) */
-    return (bzf->bzf_bzstream.total_out_lo32);
+    return(bzf->bzf_bzstream.total_out_lo32);
 }
 
 static int
diff --git a/lib/libstand/gzipfs.c b/lib/libstand/gzipfs.c
index 4f40a4ae3b3..9ff7985636b 100644
--- a/lib/libstand/gzipfs.c
+++ b/lib/libstand/gzipfs.c
@@ -212,10 +212,9 @@ zf_open(const char *fname, struct open_file *f)
     bzero(zf, sizeof(struct z_file));
     zf->zf_rawfd = rawfd;
 
-    /* Verify that the file is gzipped (XXX why do this afterwards?) */
+    /* Verify that the file is gzipped */
     if (check_header(zf)) {
 	close(zf->zf_rawfd);
-	inflateEnd(&(zf->zf_zstream));
 	free(zf);
 	return(EFTYPE);
     }
@@ -261,7 +260,7 @@ zf_read(struct open_file *f, void *buf, size_t size, size_t *resid)
 	if (zf->zf_zstream.avail_in == 0) {		/* oops, unexpected EOF */
 	    printf("zf_read: unexpected EOF\n");
 	    if (zf->zf_zstream.avail_out == size)
-		return (EIO);
+		return(EIO);
 	    break;
 	}
 
@@ -286,12 +285,13 @@ zf_rewind(struct open_file *f)
     struct z_file	*zf = (struct z_file *)f->f_fsdata;
 
     if (lseek(zf->zf_rawfd, zf->zf_dataoffset, SEEK_SET) == -1)
-	return -1;
+	return(-1);
     zf->zf_zstream.avail_in = 0;
     zf->zf_zstream.next_in = NULL;
+    zf->zf_endseen = 0;
     (void)inflateReset(&zf->zf_zstream);
 
-    return 0;
+    return(0);
 }
 
 static off_t
@@ -312,12 +312,12 @@ zf_seek(struct open_file *f, off_t offset, int where)
 	target = -1;
     default:
 	errno = EINVAL;
-	return (-1);
+	return(-1);
     }
 
     /* rewind if required */
     if (target < zf->zf_zstream.total_out && zf_rewind(f) != 0)
-	return -1;
+	return(-1);
 
     /* skip forwards if required */
     while (target > zf->zf_zstream.total_out) {
@@ -327,7 +327,7 @@ zf_seek(struct open_file *f, off_t offset, int where)
 	    return(-1);
     }
     /* This is where we are (be honest if we overshot) */
-    return (zf->zf_zstream.total_out);
+    return(zf->zf_zstream.total_out);
 }
 
 

From 1950852fcf5821540edee5c242631f421e14133e Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Wed, 30 Dec 2009 19:25:40 +0000
Subject: [PATCH 0965/2592] MFC r201036:

Delete some trailing whitespace
---
 etc/rc.subr | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/etc/rc.subr b/etc/rc.subr
index 23811af7451..cfb2942965c 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -738,7 +738,7 @@ $command $rc_flags $command_args"
 				if [ -n "$_nice" ]; then
 					if [ -z "$_user" ]; then
 						_doit="sh -c \"$_doit\""
-					fi	
+					fi
 					_doit="nice -n $_nice $_doit"
 				fi
 			fi
@@ -1063,7 +1063,7 @@ load_rc_config()
 		esac
 	done
 }
-  
+
 #
 # load_rc_config_var name var
 #	Read the rc.conf(5) var for name and set in the

From ac4cfa6dbb8bad1a43d2a5474cea721394723543 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Wed, 30 Dec 2009 19:36:40 +0000
Subject: [PATCH 0966/2592] MFC r200743:

The service command is an easy interface to the rc.d system.
Its primary purpose is to start and stop services provided by
the rc.d scripts, however it can also be used to list the scripts
using various criteria.

MFC r200809, r200980, r201035, r201069, 201070:

Updates/fixes suggested after the initial introducition
---
 usr.sbin/Makefile           |   1 +
 usr.sbin/service/Makefile   |   7 ++
 usr.sbin/service/service.8  | 131 ++++++++++++++++++++++++++++++++++++
 usr.sbin/service/service.sh | 120 +++++++++++++++++++++++++++++++++
 4 files changed, 259 insertions(+)
 create mode 100644 usr.sbin/service/Makefile
 create mode 100644 usr.sbin/service/service.8
 create mode 100755 usr.sbin/service/service.sh

diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 160b122571a..99a06208262 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -167,6 +167,7 @@ SUBDIR=	${_ac} \
 	${_sa} \
 	${_sade} \
 	${_sendmail} \
+	service \
 	setfib \
 	setfmac \
 	setpmac \
diff --git a/usr.sbin/service/Makefile b/usr.sbin/service/Makefile
new file mode 100644
index 00000000000..a03714dc6f9
--- /dev/null
+++ b/usr.sbin/service/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+SCRIPTS=service.sh
+MAN=	service.8
+
+.include 
+
diff --git a/usr.sbin/service/service.8 b/usr.sbin/service/service.8
new file mode 100644
index 00000000000..a7f31353f4f
--- /dev/null
+++ b/usr.sbin/service/service.8
@@ -0,0 +1,131 @@
+.\" Copyright (c) 2009 Douglas Barton
+.\" 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 December 26, 2009
+.Dt service 8
+.Os
+.Sh NAME
+.Nm service
+.Nd "control (start/stop/etc.) or list system services"
+.Sh SYNOPSIS
+.Nm
+.Fl e
+.Nm
+.Op Fl v
+.Fl l | r
+.Nm
+.Op Fl v
+.Ar  start|stop|etc.
+.Sh DESCRIPTION
+The
+.Nm
+command is an easy interface to the rc.d system.
+Its primary purpose is to start and stop services provided
+by the rc.d scripts.
+When used for this purpose it will set the same restricted
+environment that is in use at boot time (see below).
+It can also be used to list
+the scripts using various criteria.
+.Pp
+The options are as follows:
+.Bl -tag -width F1
+.It Fl e
+List services that are enabled.
+The list of scripts to check is compiled using
+.Xr rcorder 8
+the same way that it is done in
+.Xr rc 8 ,
+then that list of scripts is checked for an
+.Qq rcvar
+assignment.
+If present the script is checked to see if it is enabled.
+.It Fl l
+List all files in
+.Pa /etc/rc.d
+and the local startup directories.
+As described in
+.Xr rc.conf 5
+this is usually
+.Pa /usr/local/etc/rc.d .
+All files will be listed whether they are an actual
+rc.d script or not.
+.It Fl r
+Generate the
+.Xr rcorder 8
+as in
+.Fl e
+above, but list all of the files, not just what is enabled.
+.It Fl v
+Be slightly more verbose
+.El
+.Sh ENVIRONMENT
+When used to run rc.d scripts the
+.Nm
+command sets
+.Ev HOME
+to
+.Pa /
+and
+.Ev PATH
+to
+.Pa /sbin:/bin:/usr/sbin:/usr/bin
+which is how they are set in
+.Pa /etc/rc
+at boot time.
+.Sh EXIT STATUS
+.Ex -std
+.Sh EXAMPLES
+The following are examples of typical usage of the
+.Nm
+command:
+.Pp
+.Dl "service named status"
+.Dl "service -rv"
+.Pp
+The following programmable completion entry can be use in
+.Xr bash 1
+for the names of the rc.d scripts:
+.Dl "_service () {"
+.Dl "	local cur"
+.Dl "	cur=${COMP_WORDS[COMP_CWORD]}"
+.Dl "	COMPREPLY=( $( compgen -W '$( service -l )' -- $cur ) )"
+.Dl "	return 0"
+.Dl "}"
+.Dl "complete -F _service service"
+.Sh SEE ALSO
+.Xr bash 1 Pq Pa ports/shells/bash ,
+.Xr rc.conf 5 ,
+.Xr rc 8 ,
+.Xr rcorder 8
+.Sh HISTORY
+The
+.Nm
+manual page service first appeared in
+.Fx 7.3 .
+.Sh AUTHORS
+This
+manual page was written by
+.An Douglas Barton  .
diff --git a/usr.sbin/service/service.sh b/usr.sbin/service/service.sh
new file mode 100755
index 00000000000..1794315fb73
--- /dev/null
+++ b/usr.sbin/service/service.sh
@@ -0,0 +1,120 @@
+#!/bin/sh
+
+# $FreeBSD$
+
+#  Copyright (c) 2009 Douglas Barton
+#  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.
+
+. /etc/rc.subr
+load_rc_config 'XXX'
+
+usage () {
+	echo ''
+	echo 'Usage:'
+	echo "${0##*/} -e"
+	echo "${0##*/} [-v] -l | -r"
+	echo "${0##*/} [-v]  start|stop|etc."
+	echo "${0##*/} -h"
+	echo ''
+	echo '-e	Show services that are enabled'
+	echo "-l	List all scripts in /etc/rc.d and $local_startup"
+	echo '-r	Show the results of boot time rcorder'
+	echo '-v	Verbose'
+	echo ''
+}
+
+while getopts 'ehlrv' COMMAND_LINE_ARGUMENT ; do
+	case "${COMMAND_LINE_ARGUMENT}" in
+	e)	ENABLED=eopt ;;
+	h)	usage ; exit 0 ;;
+	l)	LIST=lopt ;;
+	r)	RCORDER=ropt ;;
+	v)	VERBOSE=vopt ;;
+	*)	usage ; exit 1 ;;
+	esac
+done
+shift $(( $OPTIND - 1 ))
+
+if [ -n "$ENABLED" -o -n "$RCORDER" ]; then
+	# Copied from /etc/rc
+	skip="-s nostart"
+	if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then
+		skip="$skip -s nojail"
+	fi
+	[ -n "$local_startup" ] && find_local_scripts_new
+	files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null`
+fi
+
+if [ -n "$ENABLED" ]; then
+	for file in $files; do
+		if grep -q ^rcvar $file; then
+			eval `grep ^name= $file`
+			eval `grep ^rcvar $file`
+			checkyesno $rcvar 2>/dev/null && echo $file
+		fi
+	done
+	exit 0
+fi
+
+if [ -n "$LIST" ]; then
+	for dir in /etc/rc.d $local_startup; do
+		[ -n "$VERBOSE" ] && echo "From ${dir}:"
+		cd $dir && for file in *; do echo $file; done
+	done
+	exit 0
+fi
+
+if [ -n "$RCORDER" ]; then
+	for file in $files; do
+		echo $file
+		if [ -n "$VERBOSE" ]; then
+			case "$file" in
+			*/${early_late_divider})
+				echo '========= Early/Late Divider =========' ;;
+			esac
+		fi
+	done
+	exit 0
+fi
+
+if [ $# -gt 1 ]; then
+	script=$1
+	shift
+else
+	usage
+	exit 1
+fi
+
+cd /
+for dir in /etc/rc.d $local_startup; do
+	if [ -x "$dir/$script" ]; then
+		[ -n "$VERBOSE" ] && echo "$script is located in $dir"
+		exec env -i HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin $dir/$script $*
+	fi
+done
+
+# If the script was not found
+echo "$script does not exist in /etc/rc.d or the local startup"
+echo "directories (${local_startup})"
+exit 1

From 0208cd85e59ffdd1103b721dc8fcb7985783b6f2 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Wed, 30 Dec 2009 21:00:54 +0000
Subject: [PATCH 0967/2592] MFC rev 201032: Use unordered memory loads and
 stores for the in* and out* family of functions.

---
 sys/ia64/include/cpufunc.h | 30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/sys/ia64/include/cpufunc.h b/sys/ia64/include/cpufunc.h
index 694f8833a47..fe469110a45 100644
--- a/sys/ia64/include/cpufunc.h
+++ b/sys/ia64/include/cpufunc.h
@@ -64,11 +64,10 @@ extern void *ia64_ioport_address(u_int);
 static __inline uint8_t
 inb(unsigned int port)
 {
-	__volatile uint8_t *p;
 	uint8_t v;
-	p = __PIO_ADDR(port);
+
 	ia64_mf();
-	v = *p;
+	v = ia64_ld1(__PIO_ADDR(port));
 	ia64_mf_a();
 	ia64_mf();
 	return (v);
@@ -77,11 +76,10 @@ inb(unsigned int port)
 static __inline uint16_t
 inw(unsigned int port)
 {
-	__volatile uint16_t *p;
 	uint16_t v;
-	p = __PIO_ADDR(port);
+
 	ia64_mf();
-	v = *p;
+	v = ia64_ld2(__PIO_ADDR(port));
 	ia64_mf_a();
 	ia64_mf();
 	return (v);
@@ -90,11 +88,10 @@ inw(unsigned int port)
 static __inline uint32_t
 inl(unsigned int port)
 {
-	volatile uint32_t *p;
 	uint32_t v;
-	p = __PIO_ADDR(port);
+
 	ia64_mf();
-	v = *p;
+	v = ia64_ld4(__PIO_ADDR(port));
 	ia64_mf_a();
 	ia64_mf();
 	return (v);
@@ -127,10 +124,9 @@ insl(unsigned int port, void *addr, size_t count)
 static __inline void
 outb(unsigned int port, uint8_t data)
 {
-	volatile uint8_t *p;
-	p = __PIO_ADDR(port);
+
 	ia64_mf();
-	*p = data;
+	ia64_st1(__PIO_ADDR(port), data);
 	ia64_mf_a();
 	ia64_mf();
 }
@@ -138,10 +134,9 @@ outb(unsigned int port, uint8_t data)
 static __inline void
 outw(unsigned int port, uint16_t data)
 {
-	volatile uint16_t *p;
-	p = __PIO_ADDR(port);
+
 	ia64_mf();
-	*p = data;
+	ia64_st2(__PIO_ADDR(port), data);
 	ia64_mf_a();
 	ia64_mf();
 }
@@ -149,10 +144,9 @@ outw(unsigned int port, uint16_t data)
 static __inline void
 outl(unsigned int port, uint32_t data)
 {
-	volatile uint32_t *p;
-	p = __PIO_ADDR(port);
+
 	ia64_mf();
-	*p = data;
+	ia64_st4(__PIO_ADDR(port), data);
 	ia64_mf_a();
 	ia64_mf();
 }

From 1749b203330ff8fc2220303c2736d4a47617ea64 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:03:29 +0000
Subject: [PATCH 0968/2592] MFC r199332

 Sort ID list by vendor.
---
 sys/dev/usb/serial/u3g.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index 4930d641144..ea40ea6fa10 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -173,6 +173,10 @@ MODULE_DEPEND(u3g, usb, 1, 1, 1);
 
 static const struct usb_device_id u3g_devs[] = {
 #define	U3G_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+	/* OEM: Huawei */
+	U3G_DEV(HUAWEI, MOBILE, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E180V, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E220, U3GFL_HUAWEI_INIT),
 	/* OEM: Option */
 	U3G_DEV(OPTION, GT3G, 0),
 	U3G_DEV(OPTION, GT3GQUAD, 0),
@@ -186,10 +190,8 @@ static const struct usb_device_id u3g_devs[] = {
 	/* OEM: Qualcomm, Inc. */
 	U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GFL_SCSI_EJECT),
 	U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GFL_SCSI_EJECT),
-	/* OEM: Huawei */
-	U3G_DEV(HUAWEI, MOBILE, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E180V, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E220, U3GFL_HUAWEI_INIT),
+	/* OEM: Merlin */
+	U3G_DEV(MERLIN, V620, 0),
 	/* OEM: Novatel */
 	U3G_DEV(NOVATEL, CDMA_MODEM, 0),
 	U3G_DEV(NOVATEL, ES620, 0),
@@ -208,8 +210,6 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(NOVATEL, ZEROCD, U3GFL_SCSI_EJECT),
 	U3G_DEV(NOVATEL, U760, U3GFL_SCSI_EJECT),
 	U3G_DEV(DELL, U740, 0),
-	/* OEM: Merlin */
-	U3G_DEV(MERLIN, V620, 0),
 	/* OEM: Sierra Wireless: */
 	U3G_DEV(SIERRA, AIRCARD580, 0),
 	U3G_DEV(SIERRA, AIRCARD595, 0),

From eed2c0622f1d685417579461078fd718900e8610 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:04:05 +0000
Subject: [PATCH 0969/2592] MFC r200087

 Add uhci/ehci controller ids.

Submitted by:	mitya_cabletv.dp.ua
---
 sys/dev/usb/controller/ehci_pci.c |  4 ++++
 sys/dev/usb/controller/uhci_pci.c | 12 ++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index ec6f3f73fce..20cbf58831a 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -193,6 +193,10 @@ ehci_pci_match(device_t self)
 		return "Intel 82801I (ICH9) USB 2.0 controller";
 	case 0x293c8086:
 		return "Intel 82801I (ICH9) USB 2.0 controller";
+	case 0x3a3a8086:
+		return "Intel 82801IJ (ICH10) USB 2.0 controller USB-A";
+	case 0x3a3c8086:
+		return "Intel 82801IJ (ICH10) USB 2.0 controller USB-B";
 
 	case 0x00e01033:
 		return ("NEC uPD 720100 USB 2.0 controller");
diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c
index 7609b0fd153..4c4e861e198 100644
--- a/sys/dev/usb/controller/uhci_pci.c
+++ b/sys/dev/usb/controller/uhci_pci.c
@@ -230,6 +230,18 @@ uhci_pci_match(device_t self)
 		return ("Intel 82801I (ICH9) USB controller");
 	case 0x29398086:
 		return ("Intel 82801I (ICH9) USB controller");
+	case 0x3a348086:
+		return ("Intel 82801IJ (ICH10) USB controller USB-A");
+	case 0x3a358086:
+		return ("Intel 82801IJ (ICH10) USB controller USB-B");
+	case 0x3a368086:
+		return ("Intel 82801IJ (ICH10) USB controller USB-C");
+	case 0x3a378086:
+		return ("Intel 82801IJ (ICH10) USB controller USB-D");
+	case 0x3a388086:
+		return ("Intel 82801IJ (ICH10) USB controller USB-E");
+	case 0x3a398086:
+		return ("Intel 82801IJ (ICH10) USB controller USB-F");
 
 	case 0x719a8086:
 		return ("Intel 82443MX USB controller");

From cd3192b39a7e4807304e1eafc1fdebdc166471cc Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:04:48 +0000
Subject: [PATCH 0970/2592] MFC r200304

 If the ID byte is non zero then we allow descriptors having multiple sizes.
---
 sys/dev/usb/input/uhid.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c
index 63972e43665..be356a5e49d 100644
--- a/sys/dev/usb/input/uhid.c
+++ b/sys/dev/usb/input/uhid.c
@@ -173,12 +173,21 @@ uhid_intr_callback(struct usb_xfer *xfer, usb_error_t error)
 		DPRINTF("transferred!\n");
 
 		pc = usbd_xfer_get_frame(xfer, 0);
-		if (actlen >= sc->sc_isize) {
+
+		/* 
+		 * If the ID byte is non zero we allow descriptors
+		 * having multiple sizes:
+		 */
+		if ((actlen >= sc->sc_isize) ||
+		    ((actlen > 0) && (sc->sc_iid != 0))) {
+			/* limit report length to the maximum */
+			if (actlen > sc->sc_isize)
+				actlen = sc->sc_isize;
 			usb_fifo_put_data(sc->sc_fifo.fp[USB_FIFO_RX], pc,
-			    0, sc->sc_isize, 1);
+			    0, actlen, 1);
 		} else {
 			/* ignore it */
-			DPRINTF("ignored short transfer, %d bytes\n", actlen);
+			DPRINTF("ignored transfer, %d bytes\n", actlen);
 		}
 
 	case USB_ST_SETUP:

From 2510f6c6dfd6ea7e9c92f2e1ce0e1f182aa77125 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:05:28 +0000
Subject: [PATCH 0971/2592] MFC r200305

 Correct name, 82801IJ -> 82801JI
---
 sys/dev/usb/controller/ehci_pci.c |  4 ++--
 sys/dev/usb/controller/uhci_pci.c | 12 ++++++------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index 20cbf58831a..e68df3e7dda 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -194,9 +194,9 @@ ehci_pci_match(device_t self)
 	case 0x293c8086:
 		return "Intel 82801I (ICH9) USB 2.0 controller";
 	case 0x3a3a8086:
-		return "Intel 82801IJ (ICH10) USB 2.0 controller USB-A";
+		return "Intel 82801JI (ICH10) USB 2.0 controller USB-A";
 	case 0x3a3c8086:
-		return "Intel 82801IJ (ICH10) USB 2.0 controller USB-B";
+		return "Intel 82801JI (ICH10) USB 2.0 controller USB-B";
 
 	case 0x00e01033:
 		return ("NEC uPD 720100 USB 2.0 controller");
diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c
index 4c4e861e198..81421e3e7a3 100644
--- a/sys/dev/usb/controller/uhci_pci.c
+++ b/sys/dev/usb/controller/uhci_pci.c
@@ -231,17 +231,17 @@ uhci_pci_match(device_t self)
 	case 0x29398086:
 		return ("Intel 82801I (ICH9) USB controller");
 	case 0x3a348086:
-		return ("Intel 82801IJ (ICH10) USB controller USB-A");
+		return ("Intel 82801JI (ICH10) USB controller USB-A");
 	case 0x3a358086:
-		return ("Intel 82801IJ (ICH10) USB controller USB-B");
+		return ("Intel 82801JI (ICH10) USB controller USB-B");
 	case 0x3a368086:
-		return ("Intel 82801IJ (ICH10) USB controller USB-C");
+		return ("Intel 82801JI (ICH10) USB controller USB-C");
 	case 0x3a378086:
-		return ("Intel 82801IJ (ICH10) USB controller USB-D");
+		return ("Intel 82801JI (ICH10) USB controller USB-D");
 	case 0x3a388086:
-		return ("Intel 82801IJ (ICH10) USB controller USB-E");
+		return ("Intel 82801JI (ICH10) USB controller USB-E");
 	case 0x3a398086:
-		return ("Intel 82801IJ (ICH10) USB controller USB-F");
+		return ("Intel 82801JI (ICH10) USB controller USB-F");
 
 	case 0x719a8086:
 		return ("Intel 82443MX USB controller");

From bb1fb02ae295dc5909ce00680d4fa52fdd1ee133 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:06:12 +0000
Subject: [PATCH 0972/2592] MFC r200306

 Add new device ids.

PR:		usb/140951, usb/140923
Submitted by:	Romain Tartiere, Brett Glass
---
 sys/dev/usb/net/if_axe.c   | 1 +
 sys/dev/usb/serial/uftdi.c | 1 +
 sys/dev/usb/usbdevs        | 2 ++
 3 files changed, 4 insertions(+)

diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c
index d5313b2da8a..a5cffe5eba0 100644
--- a/sys/dev/usb/net/if_axe.c
+++ b/sys/dev/usb/net/if_axe.c
@@ -141,6 +141,7 @@ static const struct usb_device_id axe_devs[] = {
 	{USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172, 0)},
 	{USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178, AXE_FLAG_178)},
 	{USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772, AXE_FLAG_772)},
+	{USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772A, AXE_FLAG_772)},
 	{USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T, 0)},
 	{USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055, AXE_FLAG_178)},
 	{USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR, 0)},
diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
index ae0c939ec38..309f82c8746 100644
--- a/sys/dev/usb/serial/uftdi.c
+++ b/sys/dev/usb/serial/uftdi.c
@@ -221,6 +221,7 @@ static struct usb_device_id uftdi_devs[] = {
 	{USB_VPI(USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_WIRELESSHANDHELDTERMINAL, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U100AX, UFTDI_TYPE_SIO)},
 	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232C, UFTDI_TYPE_8U232AM)},
+	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232D, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM4, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SEMC_DSS20, UFTDI_TYPE_8U232AM)},
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 9281462036d..002b9d429b8 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -904,6 +904,7 @@ product ASANTE EA		0x1427	Ethernet
 product ASIX AX88172		0x1720	10/100 Ethernet
 product ASIX AX88178		0x1780	AX88178
 product ASIX AX88772		0x7720	AX88772
+product ASIX AX88772A		0x772a	AX88772A USB 2.0 10/100 Ethernet
 
 /* ASUS products */
 product ASUS WL167G		0x1707	WL-167g Wireless Adapter
@@ -1319,6 +1320,7 @@ product FTDI SERIAL_8U100AX	0x8372	8U100AX Serial
 product FTDI SERIAL_8U232AM	0x6001	8U232AM Serial
 product FTDI SERIAL_8U232AM4	0x6004	8U232AM Serial
 product FTDI SERIAL_2232C	0x6010	FT2232C Dual port Serial
+product FTDI SERIAL_2232D	0x9e90	FT2232D Dual port Serial
 /* Gude Analog- und Digitalsysteme products also uses FTDI's id: */
 product FTDI TACTRIX_OPENPORT_13M 0xcc48 OpenPort 1.3 Mitsubishi
 product FTDI TACTRIX_OPENPORT_13S 0xcc49 OpenPort 1.3 Subaru

From 3656a8fb15117746e711b2ca9883c50a76f420bc Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:06:52 +0000
Subject: [PATCH 0973/2592] MFC r200307

 Fix dwSignature for NCM mode and add extra debug output.
---
 sys/dev/usb/net/if_cdce.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c
index e950517453f..2fcb0ff0b5b 100644
--- a/sys/dev/usb/net/if_cdce.c
+++ b/sys/dev/usb/net/if_cdce.c
@@ -1098,7 +1098,7 @@ cdce_ncm_fill_tx_frames(struct usb_xfer *xfer, uint8_t index)
 	sc->sc_ncm.dpt.dwSignature[0] = 'N';
 	sc->sc_ncm.dpt.dwSignature[1] = 'C';
 	sc->sc_ncm.dpt.dwSignature[2] = 'M';
-	sc->sc_ncm.dpt.dwSignature[3] = 'x';
+	sc->sc_ncm.dpt.dwSignature[3] = '0';
 	USETW(sc->sc_ncm.dpt.wNextNdpIndex, 0);		/* reserved */
 
 	usbd_copy_in(pc, 0, &(sc->sc_ncm.hdr), sizeof(sc->sc_ncm.hdr));
@@ -1182,7 +1182,7 @@ cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
 		if (actlen < (sizeof(sc->sc_ncm.hdr) +
 		    sizeof(sc->sc_ncm.dpt))) {
 			DPRINTFN(1, "frame too short\n");
-			goto tr_stall;
+			goto tr_setup;
 		}
 		usbd_copy_out(pc, 0, &(sc->sc_ncm.hdr),
 		    sizeof(sc->sc_ncm.hdr));
@@ -1191,7 +1191,12 @@ cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
 		    (sc->sc_ncm.hdr.dwSignature[1] != 'C') ||
 		    (sc->sc_ncm.hdr.dwSignature[2] != 'M') ||
 		    (sc->sc_ncm.hdr.dwSignature[3] != 'H')) {
-			DPRINTFN(1, "invalid HDR signature\n");
+			DPRINTFN(1, "invalid HDR signature: "
+			    "0x%02x:0x%02x:0x%02x:0x%02x\n",
+			    sc->sc_ncm.hdr.dwSignature[0],
+			    sc->sc_ncm.hdr.dwSignature[1],
+			    sc->sc_ncm.hdr.dwSignature[2],
+			    sc->sc_ncm.hdr.dwSignature[3]);
 			goto tr_stall;
 		}
 		temp = UGETW(sc->sc_ncm.hdr.wBlockLength);
@@ -1202,7 +1207,7 @@ cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
 		}
 		temp = UGETW(sc->sc_ncm.hdr.wDptIndex);
 		if ((temp + sizeof(sc->sc_ncm.dpt)) > actlen) {
-			DPRINTFN(1, "invalid DPT index\n");
+			DPRINTFN(1, "invalid DPT index: 0x%04x\n", temp);
 			goto tr_stall;
 		}
 		usbd_copy_out(pc, temp, &(sc->sc_ncm.dpt),
@@ -1211,8 +1216,13 @@ cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
 		if ((sc->sc_ncm.dpt.dwSignature[0] != 'N') ||
 		    (sc->sc_ncm.dpt.dwSignature[1] != 'C') ||
 		    (sc->sc_ncm.dpt.dwSignature[2] != 'M') ||
-		    (sc->sc_ncm.dpt.dwSignature[3] != 'x')) {
-			DPRINTFN(1, "invalid DPT signature\n");
+		    (sc->sc_ncm.dpt.dwSignature[3] != '0')) {
+			DPRINTFN(1, "invalid DPT signature"
+			    "0x%02x:0x%02x:0x%02x:0x%02x\n",
+			    sc->sc_ncm.dpt.dwSignature[0],
+			    sc->sc_ncm.dpt.dwSignature[1],
+			    sc->sc_ncm.dpt.dwSignature[2],
+			    sc->sc_ncm.dpt.dwSignature[3]);
 			goto tr_stall;
 		}
 		nframes = UGETW(sc->sc_ncm.dpt.wLength) / 4;
@@ -1284,6 +1294,7 @@ cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
 		DPRINTFN(1, "Efficiency: %u/%u bytes\n", sumdata, actlen);
 
 	case USB_ST_SETUP:
+tr_setup:
 		usbd_xfer_set_frame_len(xfer, 0, sc->sc_ncm.rx_max);
 		usbd_xfer_set_frames(xfer, 1);
 		usbd_transfer_submit(xfer);

From 65701ca05f5b5bf294a4b3660e6951e4f9a445bc Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:07:37 +0000
Subject: [PATCH 0974/2592] MFC r200308

 Fix hardware issue with FTDI chips: avoid sending a zero length packet due to
 hardware sending garbage on ZLPs.

Reported by:	Corey Smith
Submitted by:	HPS
---
 sys/dev/usb/serial/uftdi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
index 309f82c8746..8a2ef6d28d1 100644
--- a/sys/dev/usb/serial/uftdi.c
+++ b/sys/dev/usb/serial/uftdi.c
@@ -165,7 +165,7 @@ static const struct usb_config uftdi_config[UFTDI_N_TRANSFER] = {
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
 		.bufsize = UFTDI_OBUFSIZE,
-		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
+		.flags = {.pipe_bof = 1,},
 		.callback = &uftdi_write_callback,
 	},
 

From a1028b88ba0bbbd3d7b4cfa9989ac4de14c5b25e Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:08:17 +0000
Subject: [PATCH 0975/2592] MFC r200395

 Add a quirk for the Curitel UM175 where setting multiplexing for call
 management over the data endpoint causes communication to die.

 Take this one step further and model it on the existing NetBSD quirk and import
 other device IDs from them.

Obtained from:	NetBSD
---
 sys/dev/usb/quirk/usb_quirk.c | 19 +++++++++++++++++++
 sys/dev/usb/quirk/usb_quirk.h |  1 +
 sys/dev/usb/serial/umodem.c   | 23 ++++++++++++++---------
 sys/dev/usb/usbdevs           |  4 ++++
 4 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index ea63cd64c7a..cdfcce8ff45 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -125,6 +125,24 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	/* MS keyboards do weird things */
 	{USB_QUIRK_ENTRY(USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE, 0x0000, 0xFFFF, UQ_MS_LEADING_BYTE, UQ_NONE)},
 	{USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X, 0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
+	/* umodem(4) device quirks */
+	{USB_QUIRK_ENTRY(USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS,
+	    0x100, 0x100, UQ_ASSUME_CM_OVER_DATA)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SANYO, USB_PRODUCT_SANYO_SCP4900,
+	    0x000, 0x000, UQ_ASSUME_CM_OVER_DATA)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_T720C,
+	    0x001, 0x001, UQ_ASSUME_CM_OVER_DATA)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_EICON, USB_PRODUCT_EICON_DIVA852,
+	    0x100, 0x100, UQ_ASSUME_CM_OVER_DATA)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_ES75,
+	    0x000, 0x000, UQ_ASSUME_CM_OVER_DATA)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_CDMA_MSM,
+	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_CDMA_MSM,
+	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_UM175,
+	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
+
 };
 
 static const char *usb_quirk_str[USB_QUIRK_MAX] = {
@@ -152,6 +170,7 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
 	[UQ_CFG_INDEX_3]	= "UQ_CFG_INDEX_3",
 	[UQ_CFG_INDEX_4]	= "UQ_CFG_INDEX_4",
 	[UQ_CFG_INDEX_0]	= "UQ_CFG_INDEX_0",
+	[UQ_ASSUME_CM_OVER_DATA]= "UQ_ASSUME_CM_OVER_DATA",
 };
 
 /*------------------------------------------------------------------------*
diff --git a/sys/dev/usb/quirk/usb_quirk.h b/sys/dev/usb/quirk/usb_quirk.h
index f4fb9b9fdc9..ee40c2fb3b9 100644
--- a/sys/dev/usb/quirk/usb_quirk.h
+++ b/sys/dev/usb/quirk/usb_quirk.h
@@ -53,6 +53,7 @@ enum {	/* keep in sync with usb_quirk_str table */
 	UQ_CFG_INDEX_3,		/* select configuration index 3 by default */
 	UQ_CFG_INDEX_4,		/* select configuration index 4 by default */
 	UQ_CFG_INDEX_0,		/* select configuration index 0 by default */
+	UQ_ASSUME_CM_OVER_DATA,	/* modem device breaks on cm over data */
 	USB_QUIRK_MAX
 };
 
diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c
index 6a6d3951a2b..6945e79e430 100644
--- a/sys/dev/usb/serial/umodem.c
+++ b/sys/dev/usb/serial/umodem.c
@@ -112,6 +112,7 @@ __FBSDID("$FreeBSD$");
 #define	USB_DEBUG_VAR umodem_debug
 #include 
 #include 
+#include 
 
 #include 
 
@@ -349,16 +350,20 @@ umodem_attach(device_t dev)
 		}
 	}
 
-	if (sc->sc_cm_cap & USB_CDC_CM_OVER_DATA) {
-		if (sc->sc_acm_cap & USB_CDC_ACM_HAS_FEATURE) {
-
-			error = umodem_set_comm_feature
-			    (uaa->device, sc->sc_ctrl_iface_no,
-			    UCDC_ABSTRACT_STATE, UCDC_DATA_MULTIPLEXED);
-
-			/* ignore any errors */
-		}
+	if (usb_test_quirk(uaa, UQ_ASSUME_CM_OVER_DATA)) {
 		sc->sc_cm_over_data = 1;
+	} else {
+		if (sc->sc_cm_cap & USB_CDC_CM_OVER_DATA) {
+			if (sc->sc_acm_cap & USB_CDC_ACM_HAS_FEATURE) {
+
+				error = umodem_set_comm_feature
+				(uaa->device, sc->sc_ctrl_iface_no,
+				 UCDC_ABSTRACT_STATE, UCDC_DATA_MULTIPLEXED);
+
+				/* ignore any errors */
+			}
+			sc->sc_cm_over_data = 1;
+		}
 	}
 	error = usbd_transfer_setup(uaa->device,
 	    sc->sc_iface_index, sc->sc_xfer,
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 002b9d429b8..64009858a1b 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1212,6 +1212,9 @@ product DRESDENELEKTRONIK WIRELESSHANDHELDTERMINAL  0x0004 Wireless Handheld Ter
 /* Dynastream Innovations */
 product DYNASTREAM ANTDEVBOARD	0x1003	ANT dev board
 
+/* Eicon Networks */
+product EICON DIVA852		0x4905	Diva 852 ISDN TA
+
 /* EIZO products */
 product EIZO HUB		0x0000	hub
 product EIZO MONITOR		0x0001	monitor
@@ -1826,6 +1829,7 @@ product MOSCHIP MCS7830		0x7830	MCS7830 Ethernet
 /* Motorola products */
 product MOTOROLA MC141555	0x1555	MC141555 hub controller
 product MOTOROLA SB4100		0x4100	SB4100 USB Cable Modem
+product MOTOROLA2 T720C		0x2822	T720c
 product MOTOROLA2 A41XV32X	0x2a22	A41x/V32x Mobile Phones
 product MOTOROLA2 E398		0x4810	E398 Mobile Phone
 product MOTOROLA2 USBLAN	0x600c	USBLAN

From e065c35e2ad5145097ad6b11072d48834ab36c64 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:08:59 +0000
Subject: [PATCH 0976/2592] MFC r200396

 Wrap long lines.
---
 sys/dev/usb/quirk/usb_quirk.c | 114 +++++++++++++++++++++++-----------
 1 file changed, 77 insertions(+), 37 deletions(-)

diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index cdfcce8ff45..005a0588536 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -80,51 +80,91 @@ struct usb_quirk_entry {
 static struct mtx usb_quirk_mtx;
 
 static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
-	{USB_QUIRK_ENTRY(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_LCM, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4, 0x094, 0x094, UQ_SWAP_UNICODE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, 0x0a2, UQ_BAD_ADC, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, 0x0a2, UQ_AU_NO_XU, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, 0x103, 0x103, UQ_BAD_ADC, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, 0x000, 0x000, UQ_BAD_AUDIO, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, 0x110, 0x110, UQ_SPUR_BUT_UP, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB, 0x001, 0x001, UQ_SPUR_BUT_UP, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100, 0x102, 0x102, UQ_BUS_POWERED, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0x102, 0x102, UQ_BUS_POWERED, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0x110, 0x110, UQ_POWER_CLAIM, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, 0x009, UQ_AU_NO_FRAC, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B, 0x0000, 0xFFFF, UQ_NO_STRINGS, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1, 0x0000, 0xFFFF, UQ_CFG_INDEX_1, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_LCM,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4,
+	    0x094, 0x094, UQ_SWAP_UNICODE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502,
+	    0x0a2, 0x0a2, UQ_BAD_ADC, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502,
+	    0x0a2, 0x0a2, UQ_AU_NO_XU, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70,
+	    0x103, 0x103, UQ_BAD_ADC, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495,
+	    0x000, 0x000, UQ_BAD_AUDIO, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N,
+	    0x110, 0x110, UQ_SPUR_BUT_UP, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB,
+	    0x001, 0x001, UQ_SPUR_BUT_UP, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100,
+	    0x102, 0x102, UQ_BUS_POWERED, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232,
+	    0x102, 0x102, UQ_BUS_POWERED, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41,
+	    0x110, 0x110, UQ_POWER_CLAIM, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1,
+	    0x009, 0x009, UQ_AU_NO_FRAC, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SILICONPORTALS,
+	    USB_PRODUCT_SILICONPORTALS_YAPPHONE,
+	    0x100, 0x100, UQ_AU_INP_ASYNC, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B,
+	    0x0000, 0xFFFF, UQ_NO_STRINGS, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1,
+	    0x0000, 0xFFFF, UQ_CFG_INDEX_1, UQ_NONE)},
 
 	/*
 	 * XXX The following quirks should have a more specific revision
 	 * number:
 	 */
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_895C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_880C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_815C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_810C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_830C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_1220C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_XEROX, USB_PRODUCT_XEROX_WCM15, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_895C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_880C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_815C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_810C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_830C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_1220C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_XEROX, USB_PRODUCT_XEROX_WCM15,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
 	/* Devices which should be ignored by uhid */
-	{USB_QUIRK_ENTRY(USB_VENDOR_APC, USB_PRODUCT_APC_UPS, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_1500CAVRLCD, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD2X20, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD4X20, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_APC, USB_PRODUCT_APC_UPS,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_CYBERPOWER,
+	    USB_PRODUCT_CYBERPOWER_1500CAVRLCD,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD2X20,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD4X20,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
 	/* Devices which should be ignored by both ukbd and uhid */
-	{USB_QUIRK_ENTRY(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_WISPY1A, 0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY1B, 0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TENX, USB_PRODUCT_TENX_UAUDIO0, 0x0101, 0x0101, UQ_AUDIO_SWAP_LR, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_WISPY1A,
+	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY1B,
+	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TENX, USB_PRODUCT_TENX_UAUDIO0,
+	    0x0101, 0x0101, UQ_AUDIO_SWAP_LR, UQ_NONE)},
 	/* MS keyboards do weird things */
-	{USB_QUIRK_ENTRY(USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE, 0x0000, 0xFFFF, UQ_MS_LEADING_BYTE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X, 0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MICROSOFT,
+	    USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE,
+	    0x0000, 0xFFFF, UQ_MS_LEADING_BYTE, UQ_NONE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X,
+	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
 	/* umodem(4) device quirks */
 	{USB_QUIRK_ENTRY(USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS,
 	    0x100, 0x100, UQ_ASSUME_CM_OVER_DATA)},

From 2478604ee7dfc69b39e559c6037c5a2556094825 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:09:47 +0000
Subject: [PATCH 0977/2592] MFC r200652

 If the runcount is non-zero in eventhandler_deregister() then one or more
 threads are executing the eventhandler, sleep in this case to make it safe for
 module unload. If the runcount was up then an entry would have been marked
 EHE_DEAD_PRIORITY so use this as a trigger to do the wakeup in
 eventhandler_prune_list().
---
 sys/kern/subr_eventhandler.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c
index f9c8eadaf4e..37c482cbd7f 100644
--- a/sys/kern/subr_eventhandler.c
+++ b/sys/kern/subr_eventhandler.c
@@ -178,6 +178,8 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
 		ep->ee_priority = EHE_DEAD_PRIORITY;
 	}
     }
+    while (list->el_runcount > 0)
+	    mtx_sleep(list, &list->el_lock, 0, "evhrm", 0);
     EHL_UNLOCK(list);
 }
 
@@ -225,16 +227,17 @@ void
 eventhandler_prune_list(struct eventhandler_list *list)
 {
     struct eventhandler_entry *ep, *en;
+    int pruned = 0;
 
     CTR2(KTR_EVH, "%s: pruning list \"%s\"", __func__, list->el_name);
     EHL_LOCK_ASSERT(list, MA_OWNED);
-    ep = TAILQ_FIRST(&list->el_entries);
-    while (ep != NULL) {
-	en = TAILQ_NEXT(ep, ee_link);
+    TAILQ_FOREACH_SAFE(ep, &list->el_entries, ee_link, en) {
 	if (ep->ee_priority == EHE_DEAD_PRIORITY) {
 	    TAILQ_REMOVE(&list->el_entries, ep, ee_link);
 	    free(ep, M_EVENTHANDLER);
+	    pruned++;
 	}
-	ep = en;
     }
+    if (pruned > 0)
+	    wakeup(list);
 }

From ee4e4d544fbe52847fc1e7fa5bf722cfbbc8ffda Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:10:26 +0000
Subject: [PATCH 0978/2592] MFC r200653

 Use the EVENTHANDLER system to hook into the usb device configuration and
 perform a function such as ejecting a 3G autoinstaller disk. The eventhandler
 system properly tracks threads and is safe to unload, remove the
 setting/clearing of a function pointer in the kernel by u3g(4) which included a
 tsleep for safety.
---
 sys/dev/usb/serial/u3g.c  |  54 +++++++-------
 sys/dev/usb/usb_device.c  | 151 +++++++++++++++++++-------------------
 sys/dev/usb/usb_dynamic.c |  23 ------
 sys/dev/usb/usb_dynamic.h |   4 -
 sys/dev/usb/usbdi.h       |  12 +++
 5 files changed, 112 insertions(+), 132 deletions(-)

diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index ea40ea6fa10..cb00671ce48 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -122,8 +122,13 @@ static void u3g_stop_read(struct ucom_softc *ucom);
 static void u3g_start_write(struct ucom_softc *ucom);
 static void u3g_stop_write(struct ucom_softc *ucom);
 
+
+static void u3g_test_autoinst(void *, struct usb_device *,
+		struct usb_attach_arg *);
 static int u3g_driver_loaded(struct module *mod, int what, void *arg);
 
+static eventhandler_tag u3g_etag;
+
 static const struct usb_config u3g_config[U3G_N_TRANSFER] = {
 
 	[U3G_BULK_WR] = {
@@ -360,58 +365,48 @@ u3g_sael_m460_init(struct usb_device *udev)
 	}
 }
 
-static int
-u3g_lookup_huawei(struct usb_attach_arg *uaa)
-{
-	/* Calling the lookup function will also set the driver info! */
-	return (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa));
-}
-
 /*
  * The following function handles 3G modem devices (E220, Mobile,
  * etc.) with auto-install flash disks for Windows/MacOSX on the first
  * interface.  After some command or some delay they change appearance
  * to a modem.
  */
-static usb_error_t
-u3g_test_huawei_autoinst(struct usb_device *udev,
+static void
+u3g_test_autoinst(void *arg, struct usb_device *udev,
     struct usb_attach_arg *uaa)
 {
 	struct usb_interface *iface;
 	struct usb_interface_descriptor *id;
 	uint32_t flags;
 
-	if (udev == NULL) {
-		return (USB_ERR_INVAL);
-	}
+	if (uaa->dev_state != UAA_DEV_READY)
+		return;
+
 	iface = usbd_get_iface(udev, 0);
-	if (iface == NULL) {
-		return (USB_ERR_INVAL);
-	}
+	if (iface == NULL)
+		return;
 	id = iface->idesc;
-	if (id == NULL) {
-		return (USB_ERR_INVAL);
-	}
-	if (id->bInterfaceClass != UICLASS_MASS) {
-		return (USB_ERR_INVAL);
-	}
-	if (u3g_lookup_huawei(uaa)) {
+	if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
+		return;
+	if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa)) {
 		/* no device match */
-		return (USB_ERR_INVAL);
+		return;
 	}
 	flags = USB_GET_DRIVER_INFO(uaa);
 
 	if (flags & U3GFL_HUAWEI_INIT) {
 		u3g_huawei_init(udev);
 	} else if (flags & U3GFL_SCSI_EJECT) {
-		return (usb_test_autoinstall(udev, 0, 1));
+		if (usb_test_autoinstall(udev, 0, 1) != 0)
+			return;
 	} else if (flags & U3GFL_SIERRA_INIT) {
 		u3g_sierra_init(udev);
 	} else {
 		/* no quirks */
-		return (USB_ERR_INVAL);
+		return;
 	}
-	return (0);			/* success */
+	uaa->dev_state = UAA_DEV_EJECTING;
+	return;		/* success */
 }
 
 static int
@@ -420,10 +415,11 @@ u3g_driver_loaded(struct module *mod, int what, void *arg)
 	switch (what) {
 	case MOD_LOAD:
 		/* register our autoinstall handler */
-		usb_test_huawei_autoinst_p = &u3g_test_huawei_autoinst;
+		u3g_etag = EVENTHANDLER_REGISTER(usb_dev_configured,
+		    u3g_test_autoinst, NULL, EVENTHANDLER_PRI_ANY);
 		break;
 	case MOD_UNLOAD:
-		usb_test_huawei_unload(NULL);
+		EVENTHANDLER_DEREGISTER(usb_dev_configured, u3g_etag);
 		break;
 	default:
 		return (EOPNOTSUPP);
@@ -445,7 +441,7 @@ u3g_probe(device_t self)
 	if (uaa->info.bInterfaceClass != UICLASS_VENDOR) {
 		return (ENXIO);
 	}
-	return (u3g_lookup_huawei(uaa));
+	return (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa));
 }
 
 static int
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 6787fa6ead1..7fdb7e4a2c2 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -1204,6 +1204,7 @@ usb_init_attach_arg(struct usb_device *udev,
 	uaa->device = udev;
 	uaa->usb_mode = udev->flags.usb_mode;
 	uaa->port = udev->port_no;
+	uaa->dev_state = UAA_DEV_READY;
 
 	uaa->info.idVendor = UGETW(udev->ddesc.idVendor);
 	uaa->info.idProduct = UGETW(udev->ddesc.idProduct);
@@ -1453,6 +1454,9 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
 	size_t scratch_size;
 	usb_error_t err;
 	uint8_t device_index;
+	uint8_t config_index;
+	uint8_t config_quirk;
+	uint8_t set_config_failed;
 
 	DPRINTF("parent_dev=%p, bus=%p, parent_hub=%p, depth=%u, "
 	    "port_index=%u, port_no=%u, speed=%u, usb_mode=%u\n",
@@ -1732,96 +1736,91 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
 	/* fetch the vendor and product strings from the device */
 	usbd_set_device_strings(udev);
 
-	if (udev->flags.usb_mode == USB_MODE_HOST) {
-		uint8_t config_index;
-		uint8_t config_quirk;
-		uint8_t set_config_failed = 0;
+	if (udev->flags.usb_mode == USB_MODE_DEVICE) {
+		/* USB device mode setup is complete */
+		err = 0;
+		goto config_done;
+	}
 
-		/*
-		 * Most USB devices should attach to config index 0 by
-		 * default
-		 */
-		if (usb_test_quirk(&uaa, UQ_CFG_INDEX_0)) {
-			config_index = 0;
-			config_quirk = 1;
-		} else if (usb_test_quirk(&uaa, UQ_CFG_INDEX_1)) {
-			config_index = 1;
-			config_quirk = 1;
-		} else if (usb_test_quirk(&uaa, UQ_CFG_INDEX_2)) {
-			config_index = 2;
-			config_quirk = 1;
-		} else if (usb_test_quirk(&uaa, UQ_CFG_INDEX_3)) {
-			config_index = 3;
-			config_quirk = 1;
-		} else if (usb_test_quirk(&uaa, UQ_CFG_INDEX_4)) {
-			config_index = 4;
-			config_quirk = 1;
-		} else {
-			config_index = 0;
-			config_quirk = 0;
-		}
+	/*
+	 * Most USB devices should attach to config index 0 by
+	 * default
+	 */
+	if (usb_test_quirk(&uaa, UQ_CFG_INDEX_0)) {
+		config_index = 0;
+		config_quirk = 1;
+	} else if (usb_test_quirk(&uaa, UQ_CFG_INDEX_1)) {
+		config_index = 1;
+		config_quirk = 1;
+	} else if (usb_test_quirk(&uaa, UQ_CFG_INDEX_2)) {
+		config_index = 2;
+		config_quirk = 1;
+	} else if (usb_test_quirk(&uaa, UQ_CFG_INDEX_3)) {
+		config_index = 3;
+		config_quirk = 1;
+	} else if (usb_test_quirk(&uaa, UQ_CFG_INDEX_4)) {
+		config_index = 4;
+		config_quirk = 1;
+	} else {
+		config_index = 0;
+		config_quirk = 0;
+	}
 
+	set_config_failed = 0;
 repeat_set_config:
 
-		DPRINTF("setting config %u\n", config_index);
+	DPRINTF("setting config %u\n", config_index);
 
-		/* get the USB device configured */
-		err = usbd_set_config_index(udev, config_index);
-		if (err) {
-			if (udev->ddesc.bNumConfigurations != 0) {
-				if (!set_config_failed) {
-					set_config_failed = 1;
-					/* XXX try to re-enumerate the device */
-					err = usbd_req_re_enumerate(
-					    udev, NULL);
-					if (err == 0)
-					    goto repeat_set_config;
-				}
-				DPRINTFN(0, "Failure selecting "
-				    "configuration index %u: %s, port %u, "
-				    "addr %u (ignored)\n",
-				    config_index, usbd_errstr(err), udev->port_no,
-				    udev->address);
+	/* get the USB device configured */
+	err = usbd_set_config_index(udev, config_index);
+	if (err) {
+		if (udev->ddesc.bNumConfigurations != 0) {
+			if (!set_config_failed) {
+				set_config_failed = 1;
+				/* XXX try to re-enumerate the device */
+				err = usbd_req_re_enumerate(udev, NULL);
+				if (err == 0)
+					goto repeat_set_config;
 			}
+			DPRINTFN(0, "Failure selecting configuration index %u:"
+			    "%s, port %u, addr %u (ignored)\n",
+			    config_index, usbd_errstr(err), udev->port_no,
+			    udev->address);
+		}
+		/*
+		 * Some USB devices do not have any configurations. Ignore any
+		 * set config failures!
+		 */
+		err = 0;
+		goto config_done;
+	}
+	if (!config_quirk && config_index + 1 < udev->ddesc.bNumConfigurations) {
+		if ((udev->cdesc->bNumInterface < 2) &&
+		    usbd_get_no_descriptors(udev->cdesc, UDESC_ENDPOINT) == 0) {
+			DPRINTFN(0, "Found no endpoints, trying next config\n");
+			config_index++;
+			goto repeat_set_config;
+		}
+		if (config_index == 0) {
 			/*
-			 * Some USB devices do not have any
-			 * configurations. Ignore any set config
-			 * failures!
+			 * Try to figure out if we have an
+			 * auto-install disk there:
 			 */
-			err = 0;
-		} else if (config_quirk) {
-			/* user quirk selects configuration index */
-		} else if ((config_index + 1) < udev->ddesc.bNumConfigurations) {
-
-			if ((udev->cdesc->bNumInterface < 2) &&
-			    (usbd_get_no_descriptors(udev->cdesc,
-			    UDESC_ENDPOINT) == 0)) {
-				DPRINTFN(0, "Found no endpoints "
-				    "(trying next config)\n");
+			if (usb_test_autoinstall(udev, 0, 0) == 0) {
+				DPRINTFN(0, "Found possible auto-install "
+				    "disk (trying next config)\n");
 				config_index++;
 				goto repeat_set_config;
 			}
-			if (config_index == 0) {
-				/*
-				 * Try to figure out if we have an
-				 * auto-install disk there:
-				 */
-				if (usb_test_autoinstall(udev, 0, 0) == 0) {
-					DPRINTFN(0, "Found possible auto-install "
-					    "disk (trying next config)\n");
-					config_index++;
-					goto repeat_set_config;
-				}
-			}
-		} else if (usb_test_huawei_autoinst_p(udev, &uaa) == 0) {
-			DPRINTFN(0, "Found Huawei auto-install disk\n");
-			/* leave device unconfigured */
-			usb_unconfigure(udev, 0);
 		}
-	} else {
-		err = 0;		/* set success */
+	}
+	EVENTHANDLER_INVOKE(usb_dev_configured, udev, &uaa);
+	if (uaa.dev_state != UAA_DEV_READY) {
+		/* leave device unconfigured */
+		usb_unconfigure(udev, 0);
 	}
 
+config_done:
 	DPRINTF("new dev (addr %d), udev=%p, parent_hub=%p\n",
 	    udev->address, udev, udev->parent_hub);
 
diff --git a/sys/dev/usb/usb_dynamic.c b/sys/dev/usb/usb_dynamic.c
index b64712fc340..add01ce282c 100644
--- a/sys/dev/usb/usb_dynamic.c
+++ b/sys/dev/usb/usb_dynamic.c
@@ -57,7 +57,6 @@ static usb_handle_req_t usb_temp_get_desc_w;
 static usb_temp_setup_by_index_t usb_temp_setup_by_index_w;
 static usb_temp_unsetup_t usb_temp_unsetup_w;
 static usb_test_quirk_t usb_test_quirk_w;
-static usb_test_huawei_autoinst_t usb_test_huawei_autoinst_w;
 static usb_quirk_ioctl_t usb_quirk_ioctl_w;
 
 /* global variables */
@@ -65,7 +64,6 @@ usb_handle_req_t *usb_temp_get_desc_p = &usb_temp_get_desc_w;
 usb_temp_setup_by_index_t *usb_temp_setup_by_index_p = &usb_temp_setup_by_index_w;
 usb_temp_unsetup_t *usb_temp_unsetup_p = &usb_temp_unsetup_w;
 usb_test_quirk_t *usb_test_quirk_p = &usb_test_quirk_w;
-usb_test_huawei_autoinst_t *usb_test_huawei_autoinst_p = &usb_test_huawei_autoinst_w;
 usb_quirk_ioctl_t *usb_quirk_ioctl_p = &usb_quirk_ioctl_w;
 devclass_t usb_devclass_ptr = NULL;
 
@@ -105,13 +103,6 @@ usb_temp_unsetup_w(struct usb_device *udev)
 	}
 }
 
-static usb_error_t
-usb_test_huawei_autoinst_w(struct usb_device *udev,
-    struct usb_attach_arg *uaa)
-{
-	return (USB_ERR_INVAL);
-}
-
 void
 usb_quirk_unload(void *arg)
 {
@@ -156,17 +147,3 @@ usb_bus_unload(void *arg)
 
 	pause("WAIT", hz);
 }
-
-void
-usb_test_huawei_unload(void *arg)
-{
-	/* reset function pointers */
-
-	usb_test_huawei_autoinst_p = &usb_test_huawei_autoinst_w;
-
-	/* wait for CPU to exit the loaded functions, if any */
-
-	/* XXX this is a tradeoff */
-
-	pause("WAIT", 16*hz);
-}
diff --git a/sys/dev/usb/usb_dynamic.h b/sys/dev/usb/usb_dynamic.h
index f8b7caf69f3..568494204c1 100644
--- a/sys/dev/usb/usb_dynamic.h
+++ b/sys/dev/usb/usb_dynamic.h
@@ -37,8 +37,6 @@ struct usb_device_request;
 
 typedef usb_error_t	(usb_temp_setup_by_index_t)(struct usb_device *udev,
 			    uint16_t index);
-typedef usb_error_t	(usb_test_huawei_autoinst_t)(struct usb_device *udev, 
-			    struct usb_attach_arg *uaa);
 typedef uint8_t		(usb_test_quirk_t)(const struct usbd_lookup_info *info,
 			    uint16_t quirk);
 typedef int		(usb_quirk_ioctl_t)(unsigned long cmd, caddr_t data,
@@ -51,13 +49,11 @@ extern usb_handle_req_t *usb_temp_get_desc_p;
 extern usb_temp_setup_by_index_t *usb_temp_setup_by_index_p;
 extern usb_temp_unsetup_t *usb_temp_unsetup_p;
 extern usb_test_quirk_t *usb_test_quirk_p;
-extern usb_test_huawei_autoinst_t *usb_test_huawei_autoinst_p;
 extern usb_quirk_ioctl_t *usb_quirk_ioctl_p;
 extern devclass_t usb_devclass_ptr;
 
 /* function prototypes */
 
-void	usb_test_huawei_unload(void *);
 void	usb_temp_unload(void *);
 void	usb_quirk_unload(void *);
 void	usb_bus_unload(void *);
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
index 1a6665227be..9adf39adc77 100644
--- a/sys/dev/usb/usbdi.h
+++ b/sys/dev/usb/usbdi.h
@@ -29,6 +29,7 @@
 struct usb_fifo;
 struct usb_xfer;
 struct usb_device;
+struct usb_attach_arg;
 struct usb_interface;
 struct usb_endpoint;
 struct usb_page_cache;
@@ -98,6 +99,13 @@ typedef int (usb_fifo_ioctl_t)(struct usb_fifo *fifo, u_long cmd, void *addr, in
 typedef void (usb_fifo_cmd_t)(struct usb_fifo *fifo);
 typedef void (usb_fifo_filter_t)(struct usb_fifo *fifo, struct usb_mbuf *m);
 
+
+/* USB events */
+#include 
+typedef void (*usb_dev_configured_t)(void *, struct usb_device *,
+    struct usb_attach_arg *);
+EVENTHANDLER_DECLARE(usb_dev_configured, usb_dev_configured_t);
+
 /*
  * The following macros are used used to convert milliseconds into
  * HZ. We use 1024 instead of 1000 milliseconds per second to save a
@@ -338,6 +346,10 @@ struct usb_attach_arg {
 	enum usb_hc_mode usb_mode;	/* host or device mode */
 	uint8_t	port;
 	uint8_t	use_generic;		/* hint for generic drivers */
+	uint8_t dev_state;
+#define UAA_DEV_READY		0
+#define UAA_DEV_DISABLED	1
+#define UAA_DEV_EJECTING	2
 };
 
 /*

From 71db0b97656ec0fcfc0a01599d9d084ee8baff66 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:12:38 +0000
Subject: [PATCH 0979/2592] MFC r200657

 Add a bunch of new 3G ids obtained from from various operating systems and
 Internet sources.
---
 sys/dev/usb/serial/u3g.c | 312 +++++++++++++++++++++++++++++++++++----
 sys/dev/usb/usbdevs      | 303 ++++++++++++++++++++++++++++++++++---
 2 files changed, 566 insertions(+), 49 deletions(-)

diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index cb00671ce48..b7b8636c834 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -178,33 +178,123 @@ MODULE_DEPEND(u3g, usb, 1, 1, 1);
 
 static const struct usb_device_id u3g_devs[] = {
 #define	U3G_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
-	/* OEM: Huawei */
-	U3G_DEV(HUAWEI, MOBILE, U3GFL_HUAWEI_INIT),
+	U3G_DEV(ACERP, H10, 0),
+	U3G_DEV(AIRPLUS, MCD650, 0),
+	U3G_DEV(AIRPRIME, PC5220, 0),
+	U3G_DEV(ALINK, 3G, 0),
+	U3G_DEV(ALINK, 3GU, 0),
+	U3G_DEV(ALINK, DWM652U5, 0),
+	U3G_DEV(AMOI, H01, 0),
+	U3G_DEV(AMOI, H01A, 0),
+	U3G_DEV(AMOI, H02, 0),
+	U3G_DEV(ANYDATA, ADU_620UW, 0),
+	U3G_DEV(ANYDATA, ADU_500A, 0),
+	U3G_DEV(ANYDATA, ADU_E100X, 0),
+	U3G_DEV(AXESSTEL, DATAMODEM, 0),
+	U3G_DEV(CMOTECH, CDMA_MODEM1, 0),
+	U3G_DEV(DELL, U5500, 0),
+	U3G_DEV(DELL, U5505, 0),
+	U3G_DEV(DELL, U5510, 0),
+	U3G_DEV(DELL, U5520, 0),
+	U3G_DEV(DELL, U5520_2, 0),
+	U3G_DEV(DELL, U5520_3, 0),
+	U3G_DEV(DELL, U5700, 0),
+	U3G_DEV(DELL, U5700_2, 0),
+	U3G_DEV(DELL, U5700_3, 0),
+	U3G_DEV(DELL, U5700_4, 0),
+	U3G_DEV(DELL, U5720, 0),
+	U3G_DEV(DELL, U5720_2, 0),
+	U3G_DEV(DELL, U5730, 0),
+	U3G_DEV(DELL, U5730_2, 0),
+	U3G_DEV(DELL, U5730_3, 0),
+	U3G_DEV(DELL, U740, 0),
+	U3G_DEV(DLINK3, DWM652, 0),
+	U3G_DEV(HP, EV2200, 0),
+	U3G_DEV(HP, HS2300, 0),
+	U3G_DEV(HUAWEI, E220BIS, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1401, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1402, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1403, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1404, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1405, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1406, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1407, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1408, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1409, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E140A, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E140B, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E140D, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E140E, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E140F, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1410, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1411, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1412, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1413, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1414, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1415, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1416, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1417, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1418, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1419, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E141A, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E141B, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E141C, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E141D, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E141E, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E141F, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1420, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1421, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1422, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1423, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1424, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1425, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1426, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1427, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1428, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1429, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E142A, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E142B, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E142C, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E142D, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E142E, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E142F, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1430, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1431, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1432, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1433, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1434, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1435, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1436, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1437, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1438, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1439, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E143A, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E143B, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E143C, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E143D, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E143E, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E143F, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E14AC, U3GFL_HUAWEI_INIT),
 	U3G_DEV(HUAWEI, E180V, U3GFL_HUAWEI_INIT),
 	U3G_DEV(HUAWEI, E220, U3GFL_HUAWEI_INIT),
-	/* OEM: Option */
-	U3G_DEV(OPTION, GT3G, 0),
-	U3G_DEV(OPTION, GT3GQUAD, 0),
-	U3G_DEV(OPTION, GT3GPLUS, 0),
-	U3G_DEV(OPTION, GTMAX36, 0),
-	U3G_DEV(OPTION, GTHSDPA, 0),
-	U3G_DEV(OPTION, GTMAXHSUPA, 0),
-	U3G_DEV(OPTION, GTMAXHSUPAE, 0),
-	U3G_DEV(OPTION, GTMAX380HSUPAE, 0),
-	U3G_DEV(OPTION, VODAFONEMC3G, 0),
-	/* OEM: Qualcomm, Inc. */
-	U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GFL_SCSI_EJECT),
-	U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GFL_SCSI_EJECT),
-	/* OEM: Merlin */
+	U3G_DEV(HUAWEI, MOBILE, U3GFL_HUAWEI_INIT),
+	U3G_DEV(KYOCERA2, KPC680, 0),
+	U3G_DEV(KYOCERA2, CDMA_MSM_K, 0),
 	U3G_DEV(MERLIN, V620, 0),
-	/* OEM: Novatel */
-	U3G_DEV(NOVATEL, CDMA_MODEM, 0),
+	U3G_DEV(NOVATEL, E725, 0),
 	U3G_DEV(NOVATEL, ES620, 0),
+	U3G_DEV(NOVATEL, ES620_2, 0),
+	U3G_DEV(NOVATEL, EU730, 0),
+	U3G_DEV(NOVATEL, EU740, 0),
+	U3G_DEV(NOVATEL, EU870D, 0),
+	U3G_DEV(NOVATEL, MC760, 0),
 	U3G_DEV(NOVATEL, MC950D, 0),
 	U3G_DEV(NOVATEL, U720, 0),
 	U3G_DEV(NOVATEL, U727, 0),
+	U3G_DEV(NOVATEL, U727_2, 0),
 	U3G_DEV(NOVATEL, U740, 0),
 	U3G_DEV(NOVATEL, U740_2, 0),
+	U3G_DEV(NOVATEL, U760, U3GFL_SCSI_EJECT),
 	U3G_DEV(NOVATEL, U870, 0),
 	U3G_DEV(NOVATEL, V620, 0),
 	U3G_DEV(NOVATEL, V640, 0),
@@ -212,41 +302,199 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(NOVATEL, V740, 0),
 	U3G_DEV(NOVATEL, X950D, 0),
 	U3G_DEV(NOVATEL, XU870, 0),
-	U3G_DEV(NOVATEL, ZEROCD, U3GFL_SCSI_EJECT),
-	U3G_DEV(NOVATEL, U760, U3GFL_SCSI_EJECT),
-	U3G_DEV(DELL, U740, 0),
-	/* OEM: Sierra Wireless: */
-	U3G_DEV(SIERRA, AIRCARD580, 0),
-	U3G_DEV(SIERRA, AIRCARD595, 0),
+	U3G_DEV(OPTION, GT3G_1, 0),
+	U3G_DEV(OPTION, GT3G_2, 0),
+	U3G_DEV(OPTION, GT3G_3, 0),
+	U3G_DEV(OPTION, GT3G_4, 0),
+	U3G_DEV(OPTION, GT3G_5, 0),
+	U3G_DEV(OPTION, GT3G_6, 0),
+	U3G_DEV(OPTION, E6500, 0),
+	U3G_DEV(OPTION, E6501, 0),
+	U3G_DEV(OPTION, E6601, 0),
+	U3G_DEV(OPTION, E6721, 0),
+	U3G_DEV(OPTION, E6741, 0),
+	U3G_DEV(OPTION, E6761, 0),
+	U3G_DEV(OPTION, E6800, 0),
+	U3G_DEV(OPTION, E7021, 0),
+	U3G_DEV(OPTION, E7041, 0),
+	U3G_DEV(OPTION, E7061, 0),
+	U3G_DEV(OPTION, E7100, 0),
+	U3G_DEV(OPTION, GTM380, 0),
+	U3G_DEV(OPTION, GT3G, 0),
+	U3G_DEV(OPTION, GT3GPLUS, 0),
+	U3G_DEV(OPTION, GT3GQUAD, 0),
+	U3G_DEV(OPTION, GTHSDPA, 0),
+	U3G_DEV(OPTION, GTMAX36, 0),
+	U3G_DEV(OPTION, GTMAX380HSUPAE, 0),
+	U3G_DEV(OPTION, GTMAXHSUPA, 0),
+	U3G_DEV(OPTION, GTMAXHSUPAE, 0),
+	U3G_DEV(OPTION, VODAFONEMC3G, 0),
+	U3G_DEV(QISDA, H21_1, 0),
+	U3G_DEV(QISDA, H21_2, 0),
+	U3G_DEV(QISDA, H20_1, 0),
+	U3G_DEV(QISDA, H20_2, 0),
+	U3G_DEV(QUALCOMM2, AC8700, 0),
+	U3G_DEV(QUALCOMM2, MF330, 0),
+	U3G_DEV(QUALCOMMINC, E0002, 0),
+	U3G_DEV(QUALCOMMINC, E0003, 0),
+	U3G_DEV(QUALCOMMINC, E0004, 0),
+	U3G_DEV(QUALCOMMINC, E0005, 0),
+	U3G_DEV(QUALCOMMINC, E0006, 0),
+	U3G_DEV(QUALCOMMINC, E0007, 0),
+	U3G_DEV(QUALCOMMINC, E0008, 0),
+	U3G_DEV(QUALCOMMINC, E0009, 0),
+	U3G_DEV(QUALCOMMINC, E000A, 0),
+	U3G_DEV(QUALCOMMINC, E000B, 0),
+	U3G_DEV(QUALCOMMINC, E000C, 0),
+	U3G_DEV(QUALCOMMINC, E000D, 0),
+	U3G_DEV(QUALCOMMINC, E000E, 0),
+	U3G_DEV(QUALCOMMINC, E000F, 0),
+	U3G_DEV(QUALCOMMINC, E0010, 0),
+	U3G_DEV(QUALCOMMINC, E0011, 0),
+	U3G_DEV(QUALCOMMINC, E0012, 0),
+	U3G_DEV(QUALCOMMINC, E0013, 0),
+	U3G_DEV(QUALCOMMINC, E0014, 0),
+	U3G_DEV(QUALCOMMINC, MF628, 0),
+	U3G_DEV(QUALCOMMINC, E0016, 0),
+	U3G_DEV(QUALCOMMINC, E0017, 0),
+	U3G_DEV(QUALCOMMINC, E0018, 0),
+	U3G_DEV(QUALCOMMINC, E0019, 0),
+	U3G_DEV(QUALCOMMINC, E0020, 0),
+	U3G_DEV(QUALCOMMINC, E0021, 0),
+	U3G_DEV(QUALCOMMINC, E0022, 0),
+	U3G_DEV(QUALCOMMINC, E0023, 0),
+	U3G_DEV(QUALCOMMINC, E0024, 0),
+	U3G_DEV(QUALCOMMINC, E0025, 0),
+	U3G_DEV(QUALCOMMINC, E0026, 0),
+	U3G_DEV(QUALCOMMINC, E0027, 0),
+	U3G_DEV(QUALCOMMINC, E0028, 0),
+	U3G_DEV(QUALCOMMINC, E0029, 0),
+	U3G_DEV(QUALCOMMINC, E0030, 0),
+	U3G_DEV(QUALCOMMINC, MF626, 0),
+	U3G_DEV(QUALCOMMINC, E0032, 0),
+	U3G_DEV(QUALCOMMINC, E0033, 0),
+	U3G_DEV(QUALCOMMINC, E0037, 0),
+	U3G_DEV(QUALCOMMINC, E0039, 0),
+	U3G_DEV(QUALCOMMINC, E0042, 0),
+	U3G_DEV(QUALCOMMINC, E0043, 0),
+	U3G_DEV(QUALCOMMINC, E0048, 0),
+	U3G_DEV(QUALCOMMINC, E0049, 0),
+	U3G_DEV(QUALCOMMINC, E0051, 0),
+	U3G_DEV(QUALCOMMINC, E0052, 0),
+	U3G_DEV(QUALCOMMINC, E0054, 0),
+	U3G_DEV(QUALCOMMINC, E0055, 0),
+	U3G_DEV(QUALCOMMINC, E0057, 0),
+	U3G_DEV(QUALCOMMINC, E0058, 0),
+	U3G_DEV(QUALCOMMINC, E0059, 0),
+	U3G_DEV(QUALCOMMINC, E0060, 0),
+	U3G_DEV(QUALCOMMINC, E0061, 0),
+	U3G_DEV(QUALCOMMINC, E0062, 0),
+	U3G_DEV(QUALCOMMINC, E0063, 0),
+	U3G_DEV(QUALCOMMINC, E0064, 0),
+	U3G_DEV(QUALCOMMINC, E0066, 0),
+	U3G_DEV(QUALCOMMINC, E0069, 0),
+	U3G_DEV(QUALCOMMINC, E0070, 0),
+	U3G_DEV(QUALCOMMINC, E0073, 0),
+	U3G_DEV(QUALCOMMINC, E0076, 0),
+	U3G_DEV(QUALCOMMINC, E0078, 0),
+	U3G_DEV(QUALCOMMINC, E0082, 0),
+	U3G_DEV(QUALCOMMINC, E0086, 0),
+	U3G_DEV(QUALCOMMINC, E2002, 0),
+	U3G_DEV(QUALCOMMINC, E2003, 0),
+	U3G_DEV(QUALCOMMINC, AC8710, 0),
+	U3G_DEV(QUALCOMMINC, AC2726, 0),
+	U3G_DEV(QUALCOMMINC, AC8700, 0),
+	U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GFL_SCSI_EJECT),
+	U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GFL_SCSI_EJECT),
+	U3G_DEV(QUANTA, Q101, 0),
+	U3G_DEV(QUANTA, Q111, 0),
+	U3G_DEV(QUANTA, GLX, 0),
+	U3G_DEV(QUANTA, GKE, 0),
+	U3G_DEV(QUANTA, GLE, 0),
+	U3G_DEV(SIERRA, AC402, 0),
 	U3G_DEV(SIERRA, AC595U, 0),
 	U3G_DEV(SIERRA, AC597E, 0),
-	U3G_DEV(SIERRA, C597, 0),
+	U3G_DEV(SIERRA, AC875E, 0),
+	U3G_DEV(SIERRA, AC875U, 0),
+	U3G_DEV(SIERRA, AC875U_2, 0),
 	U3G_DEV(SIERRA, AC880, 0),
 	U3G_DEV(SIERRA, AC880E, 0),
 	U3G_DEV(SIERRA, AC880U, 0),
 	U3G_DEV(SIERRA, AC881, 0),
 	U3G_DEV(SIERRA, AC881E, 0),
 	U3G_DEV(SIERRA, AC881U, 0),
+	U3G_DEV(SIERRA, AC885E, 0),
+	U3G_DEV(SIERRA, AC885E_2, 0),
 	U3G_DEV(SIERRA, AC885U, 0),
+	U3G_DEV(SIERRA, AIRCARD580, 0),
+	U3G_DEV(SIERRA, AIRCARD595, 0),
+	U3G_DEV(SIERRA, AIRCARD875, 0),
+	U3G_DEV(SIERRA, C22, 0),
+	U3G_DEV(SIERRA, C597, 0),
+	U3G_DEV(SIERRA, C888, 0),
+	U3G_DEV(SIERRA, E0029, 0),
+	U3G_DEV(SIERRA, E6892, 0),
+	U3G_DEV(SIERRA, E6893, 0),
 	U3G_DEV(SIERRA, EM5625, 0),
+	U3G_DEV(SIERRA, EM5725, 0),
 	U3G_DEV(SIERRA, MC5720, 0),
 	U3G_DEV(SIERRA, MC5720_2, 0),
 	U3G_DEV(SIERRA, MC5725, 0),
-	U3G_DEV(SIERRA, MINI5725, 0),
-	U3G_DEV(SIERRA, AIRCARD875, 0),
+	U3G_DEV(SIERRA, MC5727, 0),
+	U3G_DEV(SIERRA, MC5727_2, 0),
+	U3G_DEV(SIERRA, MC5728, 0),
 	U3G_DEV(SIERRA, MC8755, 0),
 	U3G_DEV(SIERRA, MC8755_2, 0),
 	U3G_DEV(SIERRA, MC8755_3, 0),
+	U3G_DEV(SIERRA, MC8755_4, 0),
 	U3G_DEV(SIERRA, MC8765, 0),
-	U3G_DEV(SIERRA, AC875U, 0),
+	U3G_DEV(SIERRA, MC8765_2, 0),
+	U3G_DEV(SIERRA, MC8765_3, 0),
+	U3G_DEV(SIERRA, MC8775, 0),
 	U3G_DEV(SIERRA, MC8775_2, 0),
 	U3G_DEV(SIERRA, MC8780, 0),
+	U3G_DEV(SIERRA, MC8780_2, 0),
+	U3G_DEV(SIERRA, MC8780_3, 0),
 	U3G_DEV(SIERRA, MC8781, 0),
-	U3G_DEV(HP, HS2300, 0),
-	/* Sierra TruInstaller device ID */
-	U3G_DEV(SIERRA, TRUINSTALL, U3GFL_SIERRA_INIT),
-	/* PRUEBA SILABS */
+	U3G_DEV(SIERRA, MC8781_2, 0),
+	U3G_DEV(SIERRA, MC8781_3, 0),
+	U3G_DEV(SIERRA, MC8785, 0),
+	U3G_DEV(SIERRA, MC8785_2, 0),
+	U3G_DEV(SIERRA, MC8790, 0),
+	U3G_DEV(SIERRA, MC8791, 0),
+	U3G_DEV(SIERRA, MC8792, 0),
+	U3G_DEV(SIERRA, MINI5725, 0),
+	U3G_DEV(SIERRA, T11, 0),
+	U3G_DEV(SIERRA, T598, 0),
 	U3G_DEV(SILABS, SAEL, U3GFL_SAEL_M460_INIT),
+	U3G_DEV(STELERA, C105, 0),
+	U3G_DEV(STELERA, E1003, 0),
+	U3G_DEV(STELERA, E1004, 0),
+	U3G_DEV(STELERA, E1005, 0),
+	U3G_DEV(STELERA, E1006, 0),
+	U3G_DEV(STELERA, E1007, 0),
+	U3G_DEV(STELERA, E1008, 0),
+	U3G_DEV(STELERA, E1009, 0),
+	U3G_DEV(STELERA, E100A, 0),
+	U3G_DEV(STELERA, E100B, 0),
+	U3G_DEV(STELERA, E100C, 0),
+	U3G_DEV(STELERA, E100D, 0),
+	U3G_DEV(STELERA, E100E, 0),
+	U3G_DEV(STELERA, E100F, 0),
+	U3G_DEV(STELERA, E1010, 0),
+	U3G_DEV(STELERA, E1011, 0),
+	U3G_DEV(STELERA, E1012, 0),
+	U3G_DEV(TCTMOBILE, X060S, 0),
+	U3G_DEV(TELIT, UC864E, 0),
+	U3G_DEV(TELIT, UC864G, 0),
+	U3G_DEV(TLAYTECH, TEU800, 0),
+	U3G_DEV(TOSHIBA, G450, 0),
+	U3G_DEV(TOSHIBA, HSDPA, 0),
+	U3G_DEV(YISO, C893, 0),
+	/* Autoinstallers */
+	U3G_DEV(NOVATEL, ZEROCD, U3GFL_SCSI_EJECT),
+	U3G_DEV(SIERRA, TRUINSTALL, U3GFL_SIERRA_INIT),
+#undef	U3G_DEV
 };
 
 static void
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 64009858a1b..29d09a386e4 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -554,6 +554,7 @@ vendor PLX		0x10b5	PLX
 vendor ASANTE		0x10bd	Asante
 vendor SILABS		0x10c4	Silicon Labs
 vendor ACTIONS		0x10d6  Actions
+vendor AIRPLUS		0x1011  Airplus
 vendor ANALOG		0x1110	Analog Devices
 vendor TENX		0x1130	Ten X Technology, Inc.
 vendor ISSC		0x1131	Integrated System Solution Corp.
@@ -561,6 +562,7 @@ vendor JRC		0x1145	Japan Radio Company
 vendor SPHAIRON		0x114b	Sphairon Access Systems GmbH
 vendor DELORME		0x1163	DeLorme
 vendor SERVERWORKS	0x1166	ServerWorks
+vendor DLINK3		0x1186	Dlink
 vendor ACERCM		0x1189	Acer Communications & Multimedia
 vendor SIERRA		0x1199	Sierra Wireless
 vendor TOPFIELD		0x11db	Topfield Co., Ltd
@@ -609,6 +611,7 @@ vendor SPARKLAN		0x15a9	SparkLAN
 vendor SOHOWARE		0x15e8	SOHOware
 vendor UMAX		0x1606	UMAX Data Systems
 vendor INSIDEOUT	0x1608	Inside Out Networks
+vendor AMOI		0x1614	Amoi Electronics
 vendor GOODWAY		0x1631	Good Way Technology
 vendor ENTREGA		0x1645	Entrega
 vendor ACTIONTEC	0x1668	Actiontec Electronics
@@ -628,10 +631,15 @@ vendor LINKSYS3		0x1915	Linksys
 vendor QUALCOMMINC	0x19d2	Qualcomm, Incorporated
 vendor WCH2		0x1a86	QinHeng Electronics
 vendor STELERA		0x1a8d	Stelera Wireless
+vendor TCTMOBILE	0x1bbb  TCT Mobile
+vendor TELIT		0x1bc7  Telit
 vendor MPMAN		0x1cae	MpMan
 vendor DRESDENELEKTRONIK 0x1cf1 dresden elektronik
+vendor QISDA		0x1da5  Qisda
+vendor ALINK		0x1e0e  Alink
 vendor DLINK		0x2001	D-Link
 vendor PLANEX2		0x2019	Planex Communications
+vendor TLAYTECH		0x20b9	Tlay Tech
 vendor ERICSSON		0x2282	Ericsson
 vendor MOTOROLA2	0x22b8	Motorola
 vendor TRIPPLITE	0x2478	Tripp-Lite
@@ -739,6 +747,7 @@ product ACERP ACERSCAN_620U	0x2060	Acerscan 620U
 product ACERP ACERSCAN_4300U	0x20b0	Benq 3300U/4300U
 product ACERP ACERSCAN_640BT	0x20be	Acerscan 640BT
 product ACERP ACERSCAN_1240U	0x20c0	Acerscan 1240U
+product ACERP H10		0x4068	AWL400 Wireless Adapter
 product ACERP ATAPI		0x6003	ATA/ATAPI Adapter
 product ACERP AWL300		0x9000	AWL300 Wireless Adapter
 product ACERP AWL400		0x9001	AWL400 Wireless Adapter
@@ -815,6 +824,9 @@ product AIPTEK POCKETCAM3M	0x2011	PocketCAM 3Mega
 product AIPTEK2 PENCAM_MEGA_1_3 0x504a	PenCam Mega 1.3
 product AIPTEK2 SUNPLUS_TECH	0x0c15	Sunplus Technology Inc.
 
+/* AirPlis products */
+product AIRPLUS MCD650		0x3198	MCD650 modem
+
 /* AirPrime products */
 product AIRPRIME PC5220		0x0112	CDMA Wireless PC Card
 
@@ -833,6 +845,11 @@ product ALCOR SM_KBD		0x9410	MicroConnectors/StrongMan Keyboard
 product ALCOR NEC_KBD_HUB	0x9472	NEC Kbd Hub
 product ALCOR AU6390	0x6390	AU6390 USB-IDE converter
 
+/* Alink products */
+product ALINK DWM652U5		0xce16	DWM-652
+product ALINK 3G		0x9000	3G modem
+product ALINK 3GU		0x9200	3G modem
+
 /* Altec Lansing products */
 product ALTEC ADA70		0x0070	ADA70 Speakers
 product ALTEC ASC495		0xff05	ASC495 Speakers
@@ -840,6 +857,11 @@ product ALTEC ASC495		0xff05	ASC495 Speakers
 /* Allied Telesyn International products */
 product ALLIEDTELESYN ATUSB100	0xb100	AT-USB100
 
+/* Amoi products */
+product AMOI H01		0x0800	H01 3G modem
+product AMOI H01A		0x7002	H01A 3G modem
+product AMOI H02		0x0802	H02 3G modem
+
 /* American Power Conversion products */
 product APC UPS			0x0002	Uninterruptible Power Supply
 
@@ -855,6 +877,7 @@ product ANCHOR EZUSB		0x2131	EZUSB
 product ANCHOR EZLINK		0x2720	EZLINK
 
 /* AnyData products */
+product ANYDATA ADU_620UW	0x6202	CDMA 2000 EV-DO USB Modem
 product ANYDATA ADU_E100X	0x6501	CDMA 2000 1xRTT/EV-DO USB Modem
 product ANYDATA ADU_500A	0x6502	CDMA 2000 EV-DO USB Modem
 
@@ -1149,7 +1172,22 @@ product DELL BC02		0x8000	BC02 Bluetooth USB Adapter
 product DELL PRISM_GT_1		0x8102	PrismGT USB 2.0 WLAN
 product DELL TM350		0x8103	TrueMobile 350 Bluetooth USB Adapter
 product DELL PRISM_GT_2		0x8104	PrismGT USB 2.0 WLAN
+product DELL U5700		0x8114	Dell 5700 3G
+product DELL U5500		0x8115	Dell 5500 3G
+product DELL U5505		0x8116	Dell 5505 3G
+product DELL U5700_2		0x8117	Dell 5700 3G
+product DELL U5510		0x8118	Dell 5510 3G
+product DELL U5700_3		0x8128	Dell 5700 3G
+product DELL U5700_4		0x8129	Dell 5700 3G
+product DELL U5720		0x8133	Dell 5720 3G
+product DELL U5720_2		0x8134	Dell 5720 3G
 product DELL U740		0x8135	Dell U740 CDMA
+product DELL U5520		0x8136	Dell 5520 3G
+product DELL U5520_2		0x8137	Dell 5520 3G
+product DELL U5520_3		0x8138	Dell 5520 3G
+product DELL U5730		0x8180	Dell 5730 3G
+product DELL U5730_2		0x8181	Dell 5730 3G
+product DELL U5730_3		0x8182	Dell 5730 3G
 
 /* Delorme Paublishing products */
 product DELORME EARTHMATE	0x0100	Earthmate GPS
@@ -1198,6 +1236,7 @@ product DLINK2 DWLG122C1	0x3c03	DWL-G122 c1
 product DLINK2 WUA1340		0x3c04	WUA-1340
 product DLINK2 DWA111		0x3c06	DWA-111
 product DLINK2 DWA110		0x3c07	DWA-110
+product DLINK3 DWM652		0x3e04	DWM-652
 
 /* DMI products */
 product DMI CFSM_RW		0xa109	CF/SM Reader/Writer
@@ -1489,6 +1528,7 @@ product HP P1100		0x3102	Photosmart P1100
 product HP OJ4215		0x3d11	OfficeJet 4215
 product HP HN210E		0x811c	Ethernet HN210E
 product HP2 C500		0x6002	PhotoSmart C500
+product HP EV2200		0x1b1d  ev2200 HSDPA (aka MC5720)
 product HP HS2300		0x1e1d  hs2300 HSDPA (aka MC8775)
 
 /* HTC products */
@@ -1499,7 +1539,71 @@ product HTC SMARTPHONE		0x0a51	SmartPhone USB Sync
 /* HUAWEI products */
 product HUAWEI MOBILE		0x1001	Huawei Mobile
 product HUAWEI E220		0x1003	Huawei HSDPA modem
+product HUAWEI E220BIS		0x1004	Huawei HSDPA modem
+product HUAWEI E1401		0x1401	3G modem
+product HUAWEI E1402		0x1402	3G modem
+product HUAWEI E1403		0x1403	3G modem
+product HUAWEI E1404		0x1404	3G modem
+product HUAWEI E1405		0x1405	3G modem
+product HUAWEI E1406		0x1406	3G modem
+product HUAWEI E1407		0x1407	3G modem
+product HUAWEI E1408		0x1408	3G modem
+product HUAWEI E1409		0x1409	3G modem
+product HUAWEI E140A		0x140a	3G modem
+product HUAWEI E140B		0x140b	3G modem
 product HUAWEI E180V		0x140c	Huawei Mobile E180V
+product HUAWEI E140D		0x140d	3G modem
+product HUAWEI E140E		0x140e	3G modem
+product HUAWEI E140F		0x140f	3G modem
+product HUAWEI E1410		0x1410	3G modem
+product HUAWEI E1411		0x1411	3G modem
+product HUAWEI E1412		0x1412	3G modem
+product HUAWEI E1413		0x1413	3G modem
+product HUAWEI E1414		0x1414	3G modem
+product HUAWEI E1415		0x1415	3G modem
+product HUAWEI E1416		0x1416	3G modem
+product HUAWEI E1417		0x1417	3G modem
+product HUAWEI E1418		0x1418	3G modem
+product HUAWEI E1419		0x1419	3G modem
+product HUAWEI E141A		0x141a	3G modem
+product HUAWEI E141B		0x141b	3G modem
+product HUAWEI E141C		0x141c	3G modem
+product HUAWEI E141D		0x141d	3G modem
+product HUAWEI E141E		0x141e	3G modem
+product HUAWEI E141F		0x141f	3G modem
+product HUAWEI E1420		0x1420	3G modem
+product HUAWEI E1421		0x1421	3G modem
+product HUAWEI E1422		0x1422	3G modem
+product HUAWEI E1423		0x1423	3G modem
+product HUAWEI E1424		0x1424	3G modem
+product HUAWEI E1425		0x1425	3G modem
+product HUAWEI E1426		0x1426	3G modem
+product HUAWEI E1427		0x1427	3G modem
+product HUAWEI E1428		0x1428	3G modem
+product HUAWEI E1429		0x1429	3G modem
+product HUAWEI E142A		0x142a	3G modem
+product HUAWEI E142B		0x142b	3G modem
+product HUAWEI E142C		0x142c	3G modem
+product HUAWEI E142D		0x142d	3G modem
+product HUAWEI E142E		0x142e	3G modem
+product HUAWEI E142F		0x142f	3G modem
+product HUAWEI E1430		0x1430	3G modem
+product HUAWEI E1431		0x1431	3G modem
+product HUAWEI E1432		0x1432	3G modem
+product HUAWEI E1433		0x1433	3G modem
+product HUAWEI E1434		0x1434	3G modem
+product HUAWEI E1435		0x1435	3G modem
+product HUAWEI E1436		0x1436	3G modem
+product HUAWEI E1437		0x1437	3G modem
+product HUAWEI E1438		0x1438	3G modem
+product HUAWEI E1439		0x1439	3G modem
+product HUAWEI E143A		0x143a	3G modem
+product HUAWEI E143B		0x143b	3G modem
+product HUAWEI E143C		0x143c	3G modem
+product HUAWEI E143D		0x143d	3G modem
+product HUAWEI E143E		0x143e	3G modem
+product HUAWEI E143F		0x143f	3G modem
+product HUAWEI E14AC		0x14ac	3G modem
 
 /* HUAWEI 3com products */
 product HUAWEI3COM WUB320G	0x0009	Aolynk WUB320g
@@ -1640,6 +1744,7 @@ product KYOCERA FINECAM_S5	0x0103	Finecam S5
 product KYOCERA FINECAM_L3	0x0105	Finecam L3
 product KYOCERA AHK3001V	0x0203	AH-K3001V
 product KYOCERA2 CDMA_MSM_K	0x17da	Qualcomm Kyocera CDMA Technologies MSM
+product KYOCERA2 KPC680		0x180a	Qualcomm Kyocera CDMA Technologies MSM
 
 /* LaCie products */
 product LACIE HD		0xa601	Hard Disk
@@ -1908,7 +2013,6 @@ product NOVATECH RT2573		0x9021	RT2573
 
 /* Novatel Wireless products */
 product NOVATEL V640		0x1100	Merlin V620
-product NOVATEL CDMA_MODEM	0x1110	Novatel Wireless Merlin CDMA
 product NOVATEL V620		0x1110	Merlin V620
 product NOVATEL V740		0x1120	Merlin V740
 product NOVATEL V720		0x1130	Merlin V720
@@ -1917,13 +2021,20 @@ product NOVATEL U740_2		0x1410	Merlin U740
 product NOVATEL U870		0x1420	Merlin U870
 product NOVATEL XU870		0x1430	Merlin XU870
 product NOVATEL X950D		0x1450	Merlin X950D
-product NOVATEL ES620		0x2100	ES620 CDMA
+product NOVATEL ES620		0x2100	Expedite ES620
+product NOVATEL E725		0x2120	Expedite E725
+product NOVATEL ES620_2		0x2130	Expedite ES620
 product NOVATEL U720		0x2110	Merlin U720
+product NOVATEL EU730		0x2400	Expedite EU730
+product NOVATEL EU740		0x2410	Expedite EU740
+product NOVATEL EU870D		0x2420	Expedite EU870D
 product NOVATEL U727		0x4100	Merlin U727 CDMA
 product NOVATEL MC950D		0x4400	Novatel MC950D HSUPA
 product NOVATEL ZEROCD		0x5010	Novatel ZeroCD
 product NOVATEL ZEROCD2		0x5030	Novatel ZeroCD
+product NOVATEL U727_2		0x5100	Merlin U727 CDMA
 product NOVATEL U760		0x6000	Novatel U760
+product NOVATEL MC760		0x6002	Novatel MC760
 product NOVATEL2 FLEXPACKGPS	0x0100	NovAtel FlexPack GPS receiver
 
 /* Merlin products */
@@ -1960,6 +2071,24 @@ product OPTION GTHSDPA		0x6971	GlobeTrotter HSDPA
 product OPTION GTMAXHSUPA	0x7001	GlobeTrotter HSUPA
 product OPTION GTMAXHSUPAE	0x6901	GlobeTrotter HSUPA PCIe
 product OPTION GTMAX380HSUPAE	0x7211	GlobeTrotter 380HSUPA PCIe
+product OPTION GT3G_1		0x6050	3G modem
+product OPTION GT3G_2		0x6100	3G modem
+product OPTION GT3G_3		0x6150	3G modem
+product OPTION GT3G_4		0x6200	3G modem
+product OPTION GT3G_5		0x6250	3G modem
+product OPTION GT3G_6		0x6350	3G modem
+product OPTION E6500		0x6500	3G modem
+product OPTION E6501		0x6501	3G modem
+product OPTION E6601		0x6601	3G modem
+product OPTION E6721		0x6721	3G modem
+product OPTION E6741		0x6741	3G modem
+product OPTION E6761		0x6761	3G modem
+product OPTION E6800		0x6800	3G modem
+product OPTION E7021		0x7021	3G modem
+product OPTION E7041		0x7041	3G modem
+product OPTION E7061		0x7061	3G modem
+product OPTION E7100		0x7100	3G modem
+product OPTION GTM380		0x7201	3G modem
 
 /* OQO */
 product OQO WIFI01		0x0002	model 01 WiFi interface
@@ -2080,13 +2209,96 @@ product QCOM RT2573		0x6196	RT2573
 product QCOM RT2573_2		0x6229	RT2573
 product QCOM RT2573_3		0x6238	RT2573
 
+/* Qisda products */
+product QISDA H21_1		0x4512	3G modem
+product QISDA H21_2		0x4523	3G modem
+product QISDA H20_1		0x4515	3G modem
+product QISDA H20_2		0x4519	3G modem
+
 /* Qualcomm products */
 product QUALCOMM CDMA_MSM	0x6000	CDMA Technologies MSM phone
 product QUALCOMM2 RWT_FCT	0x3100	RWT FCT-CDMA 2000 1xRTT modem
 product QUALCOMM2 CDMA_MSM	0x3196	CDMA Technologies MSM modem
+product QUALCOMM2 AC8700	0x6000	AC8700
+product QUALCOMM2 MF330		0x6613	MF330
 product QUALCOMMINC CDMA_MSM	0x0001	CDMA Technologies MSM modem
 product QUALCOMMINC ZTE_STOR	0x2000	USB ZTE Storage
+product QUALCOMMINC AC8710	0xfff1	3G modem
+product QUALCOMMINC AC2726	0xfff5	3G modem
 product QUALCOMMINC AC8700	0xfffe	CDMA 1xEVDO USB modem
+product QUALCOMMINC E0002	0x0002	3G modem
+product QUALCOMMINC E0003	0x0003	3G modem
+product QUALCOMMINC E0004	0x0004	3G modem
+product QUALCOMMINC E0005	0x0005	3G modem
+product QUALCOMMINC E0006	0x0006	3G modem
+product QUALCOMMINC E0007	0x0007	3G modem
+product QUALCOMMINC E0008	0x0008	3G modem
+product QUALCOMMINC E0009	0x0009	3G modem
+product QUALCOMMINC E000A	0x000a	3G modem
+product QUALCOMMINC E000B	0x000b	3G modem
+product QUALCOMMINC E000C	0x000c	3G modem
+product QUALCOMMINC E000D	0x000d	3G modem
+product QUALCOMMINC E000E	0x000e	3G modem
+product QUALCOMMINC E000F	0x000f	3G modem
+product QUALCOMMINC E0010	0x0010	3G modem
+product QUALCOMMINC E0011	0x0011	3G modem
+product QUALCOMMINC E0012	0x0012	3G modem
+product QUALCOMMINC E0013	0x0013	3G modem
+product QUALCOMMINC E0014	0x0014	3G modem
+product QUALCOMMINC MF628	0x0015	3G modem
+product QUALCOMMINC E0016	0x0016	3G modem
+product QUALCOMMINC E0017	0x0017	3G modem
+product QUALCOMMINC E0018	0x0018	3G modem
+product QUALCOMMINC E0019	0x0019	3G modem
+product QUALCOMMINC E0020	0x0020	3G modem
+product QUALCOMMINC E0021	0x0021	3G modem
+product QUALCOMMINC E0022	0x0022	3G modem
+product QUALCOMMINC E0023	0x0023	3G modem
+product QUALCOMMINC E0024	0x0024	3G modem
+product QUALCOMMINC E0025	0x0025	3G modem
+product QUALCOMMINC E0026	0x0026	3G modem
+product QUALCOMMINC E0027	0x0027	3G modem
+product QUALCOMMINC E0028	0x0028	3G modem
+product QUALCOMMINC E0029	0x0029	3G modem
+product QUALCOMMINC E0030	0x0030	3G modem
+product QUALCOMMINC MF626	0x0031	3G modem
+product QUALCOMMINC E0032	0x0032	3G modem
+product QUALCOMMINC E0033	0x0033	3G modem
+product QUALCOMMINC E0037	0x0037	3G modem
+product QUALCOMMINC E0039	0x0039	3G modem
+product QUALCOMMINC E0042	0x0042	3G modem
+product QUALCOMMINC E0043	0x0043	3G modem
+product QUALCOMMINC E0048	0x0048	3G modem
+product QUALCOMMINC E0049	0x0049	3G modem
+product QUALCOMMINC E0051	0x0051	3G modem
+product QUALCOMMINC E0052	0x0052	3G modem
+product QUALCOMMINC E0054	0x0054	3G modem
+product QUALCOMMINC E0055	0x0055	3G modem
+product QUALCOMMINC E0057	0x0057	3G modem
+product QUALCOMMINC E0058	0x0058	3G modem
+product QUALCOMMINC E0059	0x0059	3G modem
+product QUALCOMMINC E0060	0x0060	3G modem
+product QUALCOMMINC E0061	0x0061	3G modem
+product QUALCOMMINC E0062	0x0062	3G modem
+product QUALCOMMINC E0063	0x0063	3G modem
+product QUALCOMMINC E0064	0x0064	3G modem
+product QUALCOMMINC E0066	0x0066	3G modem
+product QUALCOMMINC E0069	0x0069	3G modem
+product QUALCOMMINC E0070	0x0070	3G modem
+product QUALCOMMINC E0073	0x0073	3G modem
+product QUALCOMMINC E0076	0x0076	3G modem
+product QUALCOMMINC E0078	0x0078	3G modem
+product QUALCOMMINC E0082	0x0082	3G modem
+product QUALCOMMINC E0086	0x0086	3G modem
+product QUALCOMMINC E2002	0x2002	3G modem
+product QUALCOMMINC E2003	0x2003	3G modem
+
+/* Quanta products */
+product QUANTA Q101		0xea02	HSDPA modem
+product QUANTA Q111		0xea03	HSDPA modem
+product QUANTA GLX		0xea04	HSDPA modem
+product QUANTA GKE		0xea05	HSDPA modem
+product QUANTA GLE		0xea06	HSDPA modem
 
 /* Qtronix products */
 product QTRONIX 980N		0x2011	Scorpion-980N keyboard
@@ -2210,33 +2422,62 @@ product SIEMENS3 X65		0x0003	X65
 product SIEMENS3 X75		0x0004	X75
 
 /* Sierra Wireless products */
-product SIERRA AIRCARD580	0x0112	Sierra Wireless AirCard 580
+product SIERRA EM5625		0x0017	EM5625
+product SIERRA MC5720_2		0x0018	MC5720
+product SIERRA MC5725		0x0020	MC5725
 product SIERRA AIRCARD595	0x0019	Sierra Wireless AirCard 595
-product SIERRA AC595U		0x0120	Sierra Wireless AirCard 595U
 product SIERRA AC597E		0x0021	Sierra Wireless AirCard 597E
+product SIERRA EM5725		0x0022	EM5725
 product SIERRA C597		0x0023	Sierra Wireless Compass 597
+product SIERRA MC5727		0x0024	MC5727
+product SIERRA T598		0x0025	T598
+product SIERRA T11		0x0026	T11
+product SIERRA AC402		0x0027	AC402
+product SIERRA MC5728		0x0028	MC5728
+product SIERRA E0029		0x0029	E0029
+product SIERRA AIRCARD580	0x0112	Sierra Wireless AirCard 580
+product SIERRA AC595U		0x0120	Sierra Wireless AirCard 595U
+product SIERRA MC5720		0x0218	MC5720 Wireless Modem
+product SIERRA MINI5725		0x0220	Sierra Wireless miniPCI 5275
+product SIERRA MC5727_2		0x0224	MC5727
+product SIERRA MC8755_2		0x6802	MC8755
+product SIERRA MC8765		0x6803	MC8765
+product SIERRA MC8755		0x6804	MC8755
+product SIERRA MC8765_2		0x6805	MC8765
+product SIERRA MC8755_4		0x6808	MC8755
+product SIERRA MC8765_3		0x6809	MC8765
+product SIERRA AC875U		0x6812	AC875U HSDPA USB Modem
+product SIERRA MC8755_3		0x6813	MC8755 HSDPA
+product SIERRA MC8775_2		0x6815	MC8775
+product SIERRA MC8775		0x6816	MC8775
 product SIERRA AC875		0x6820	Sierra Wireless AirCard 875
+product SIERRA AC875U_2		0x6821	AC875U
+product SIERRA AC875E		0x6822	AC875E
+product SIERRA MC8780		0x6832	MC8780
+product SIERRA MC8781		0x6833	MC8781
+product SIERRA MC8780_2		0x6834	MC8780
+product SIERRA MC8781_2		0x6835	MC8781
+product SIERRA MC8780_3		0x6838	MC8780
+product SIERRA MC8781_3		0x6839	MC8781
+product SIERRA MC8785		0x683A	MC8785
+product SIERRA MC8785_2		0x683B	MC8785
+product SIERRA MC8790		0x683C	MC8790
+product SIERRA MC8791		0x683D	MC8791
+product SIERRA MC8792		0x683E	MC8792
 product SIERRA AC880		0x6850	Sierra Wireless AirCard 880
 product SIERRA AC881		0x6851	Sierra Wireless AirCard 881
 product SIERRA AC880E		0x6852	Sierra Wireless AirCard 880E
 product SIERRA AC881E		0x6853	Sierra Wireless AirCard 881E
 product SIERRA AC880U		0x6855	Sierra Wireless AirCard 880U
 product SIERRA AC881U		0x6856	Sierra Wireless AirCard 881U
+product SIERRA AC885E		0x6859	AC885E
+product SIERRA AC885E_2		0x685A	AC885E
 product SIERRA AC885U		0x6880	Sierra Wireless AirCard 885U
-product SIERRA EM5625		0x0017	EM5625
-product SIERRA MC5720		0x0218	MC5720 Wireless Modem
-product SIERRA MC5720_2		0x0018	MC5720
-product SIERRA MC5725		0x0020	MC5725
-product SIERRA MINI5725		0x0220	Sierra Wireless miniPCI 5275
-product SIERRA MC8755_2		0x6802	MC8755
-product SIERRA MC8765		0x6803	MC8765
-product SIERRA MC8755		0x6804	MC8755
-product SIERRA AC875U		0x6812	AC875U HSDPA USB Modem
-product SIERRA MC8755_3		0x6813	MC8755 HSDPA
-product SIERRA MC8775_2		0x6815	MC8775
+product SIERRA C888		0x6890	C888
+product SIERRA C22		0x6891	C22
+product SIERRA E6892		0x6892	E6892
+product SIERRA E6893		0x6893	E6893
 product SIERRA AIRCARD875	0x6820	Aircard 875 HSDPA
-product SIERRA MC8780		0x6832	MC8780
-product SIERRA MC8781		0x6833	MC8781
 product SIERRA TRUINSTALL	0x0fff	Aircard Tru Installer
 
 /* Sigmatel products */
@@ -2351,6 +2592,22 @@ product SPHAIRON UB801R		0x0110	UB801R
 /* Stelera Wireless products */
 product STELERA ZEROCD		0x1000	Zerocd Installer
 product STELERA C105		0x1002	Stelera/Bandrish C105 USB
+product STELERA E1003		0x1003	3G modem
+product STELERA E1004		0x1004	3G modem
+product STELERA E1005		0x1005	3G modem
+product STELERA E1006		0x1006	3G modem
+product STELERA E1007		0x1007	3G modem
+product STELERA E1008		0x1008	3G modem
+product STELERA E1009		0x1009	3G modem
+product STELERA E100A		0x100a	3G modem
+product STELERA E100B		0x100b	3G modem
+product STELERA E100C		0x100c	3G modem
+product STELERA E100D		0x100d	3G modem
+product STELERA E100E		0x100e	3G modem
+product STELERA E100F		0x100f	3G modem
+product STELERA E1010		0x1010	3G modem
+product STELERA E1011		0x1011	3G modem
+product STELERA E1012		0x1012	3G modem
 
 /* MpMan products */
 product MPMAN MPF400_1		0x36d0	MPF400 Music Player 1Go
@@ -2407,6 +2664,9 @@ product TAPWAVE ZODIAC		0x0100	Zodiac
 /* Taugagreining products */
 product TAUGA CAMERAMATE	0x0005	CameraMate (DPCM_USB)
 
+/* TCTMobile products */
+product TCTMOBILE X060S		0x0000	X060S 3G modem
+
 /* TDK products */
 product TDK UPA9664		0x0115	USB-PDC Adapter UPA9664
 product TDK UCA1464		0x0116	USB-cdmaOne Adapter UCA1464
@@ -2425,6 +2685,10 @@ product TEKRAM ZD1211_2		0x6630	ZD1211
 /* Telex Communications products */
 product TELEX MIC1		0x0001	Enhanced USB Microphone
 
+/* Telit products */
+product TELIT UC864E		0x1003	UC864E 3G modem
+product TELIT UC864G		0x1004	UC864G 3G modem
+
 /* Ten X Technology, Inc. */
 product TENX UAUDIO0		0xf211	USB audio headset
 
@@ -2435,11 +2699,16 @@ product TI TUSB2046		0x2046	TUSB2046 hub
 /* Thrustmaster products */
 product THRUST FUSION_PAD	0xa0a3	Fusion Digital Gamepad
 
+/* TLayTech products */
+product TLAYTECH TEU800		0x1682	TEU800 3G modem
+
 /* Topre Corporation products */
 product TOPRE HHKB		0x0100	HHKB Professional
 
 /* Toshiba Corporation products */
 product TOSHIBA POCKETPC_E740	0x0706	PocketPC e740
+product TOSHIBA G450		0x0d45	G450 modem
+product TOSHIBA HSDPA		0x1302	G450 modem
 
 /* Trek Technology products */
 product TREK THUMBDRIVE		0x1111	ThumbDrive

From 9d774551fcde2a1db1498dac1a51a3e5e6b20f9c Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:13:24 +0000
Subject: [PATCH 0980/2592] MFC r200658

 Keep list sorted.
---
 sys/dev/usb/serial/u3g.c | 42 ++++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index b7b8636c834..5b61948279a 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -187,8 +187,8 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(AMOI, H01, 0),
 	U3G_DEV(AMOI, H01A, 0),
 	U3G_DEV(AMOI, H02, 0),
-	U3G_DEV(ANYDATA, ADU_620UW, 0),
 	U3G_DEV(ANYDATA, ADU_500A, 0),
+	U3G_DEV(ANYDATA, ADU_620UW, 0),
 	U3G_DEV(ANYDATA, ADU_E100X, 0),
 	U3G_DEV(AXESSTEL, DATAMODEM, 0),
 	U3G_DEV(CMOTECH, CDMA_MODEM1, 0),
@@ -211,7 +211,6 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(DLINK3, DWM652, 0),
 	U3G_DEV(HP, EV2200, 0),
 	U3G_DEV(HP, HS2300, 0),
-	U3G_DEV(HUAWEI, E220BIS, U3GFL_HUAWEI_INIT),
 	U3G_DEV(HUAWEI, E1401, U3GFL_HUAWEI_INIT),
 	U3G_DEV(HUAWEI, E1402, U3GFL_HUAWEI_INIT),
 	U3G_DEV(HUAWEI, E1403, U3GFL_HUAWEI_INIT),
@@ -277,9 +276,10 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(HUAWEI, E14AC, U3GFL_HUAWEI_INIT),
 	U3G_DEV(HUAWEI, E180V, U3GFL_HUAWEI_INIT),
 	U3G_DEV(HUAWEI, E220, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E220BIS, U3GFL_HUAWEI_INIT),
 	U3G_DEV(HUAWEI, MOBILE, U3GFL_HUAWEI_INIT),
-	U3G_DEV(KYOCERA2, KPC680, 0),
 	U3G_DEV(KYOCERA2, CDMA_MSM_K, 0),
+	U3G_DEV(KYOCERA2, KPC680, 0),
 	U3G_DEV(MERLIN, V620, 0),
 	U3G_DEV(NOVATEL, E725, 0),
 	U3G_DEV(NOVATEL, ES620, 0),
@@ -302,12 +302,6 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(NOVATEL, V740, 0),
 	U3G_DEV(NOVATEL, X950D, 0),
 	U3G_DEV(NOVATEL, XU870, 0),
-	U3G_DEV(OPTION, GT3G_1, 0),
-	U3G_DEV(OPTION, GT3G_2, 0),
-	U3G_DEV(OPTION, GT3G_3, 0),
-	U3G_DEV(OPTION, GT3G_4, 0),
-	U3G_DEV(OPTION, GT3G_5, 0),
-	U3G_DEV(OPTION, GT3G_6, 0),
 	U3G_DEV(OPTION, E6500, 0),
 	U3G_DEV(OPTION, E6501, 0),
 	U3G_DEV(OPTION, E6601, 0),
@@ -319,22 +313,32 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(OPTION, E7041, 0),
 	U3G_DEV(OPTION, E7061, 0),
 	U3G_DEV(OPTION, E7100, 0),
-	U3G_DEV(OPTION, GTM380, 0),
 	U3G_DEV(OPTION, GT3G, 0),
 	U3G_DEV(OPTION, GT3GPLUS, 0),
 	U3G_DEV(OPTION, GT3GQUAD, 0),
+	U3G_DEV(OPTION, GT3G_1, 0),
+	U3G_DEV(OPTION, GT3G_2, 0),
+	U3G_DEV(OPTION, GT3G_3, 0),
+	U3G_DEV(OPTION, GT3G_4, 0),
+	U3G_DEV(OPTION, GT3G_5, 0),
+	U3G_DEV(OPTION, GT3G_6, 0),
 	U3G_DEV(OPTION, GTHSDPA, 0),
+	U3G_DEV(OPTION, GTM380, 0),
 	U3G_DEV(OPTION, GTMAX36, 0),
 	U3G_DEV(OPTION, GTMAX380HSUPAE, 0),
 	U3G_DEV(OPTION, GTMAXHSUPA, 0),
 	U3G_DEV(OPTION, GTMAXHSUPAE, 0),
 	U3G_DEV(OPTION, VODAFONEMC3G, 0),
-	U3G_DEV(QISDA, H21_1, 0),
-	U3G_DEV(QISDA, H21_2, 0),
 	U3G_DEV(QISDA, H20_1, 0),
 	U3G_DEV(QISDA, H20_2, 0),
+	U3G_DEV(QISDA, H21_1, 0),
+	U3G_DEV(QISDA, H21_2, 0),
 	U3G_DEV(QUALCOMM2, AC8700, 0),
 	U3G_DEV(QUALCOMM2, MF330, 0),
+	U3G_DEV(QUALCOMMINC, AC2726, 0),
+	U3G_DEV(QUALCOMMINC, AC8700, 0),
+	U3G_DEV(QUALCOMMINC, AC8710, 0),
+	U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GFL_SCSI_EJECT),
 	U3G_DEV(QUALCOMMINC, E0002, 0),
 	U3G_DEV(QUALCOMMINC, E0003, 0),
 	U3G_DEV(QUALCOMMINC, E0004, 0),
@@ -354,7 +358,6 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(QUALCOMMINC, E0012, 0),
 	U3G_DEV(QUALCOMMINC, E0013, 0),
 	U3G_DEV(QUALCOMMINC, E0014, 0),
-	U3G_DEV(QUALCOMMINC, MF628, 0),
 	U3G_DEV(QUALCOMMINC, E0016, 0),
 	U3G_DEV(QUALCOMMINC, E0017, 0),
 	U3G_DEV(QUALCOMMINC, E0018, 0),
@@ -370,7 +373,6 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(QUALCOMMINC, E0028, 0),
 	U3G_DEV(QUALCOMMINC, E0029, 0),
 	U3G_DEV(QUALCOMMINC, E0030, 0),
-	U3G_DEV(QUALCOMMINC, MF626, 0),
 	U3G_DEV(QUALCOMMINC, E0032, 0),
 	U3G_DEV(QUALCOMMINC, E0033, 0),
 	U3G_DEV(QUALCOMMINC, E0037, 0),
@@ -401,16 +403,14 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(QUALCOMMINC, E0086, 0),
 	U3G_DEV(QUALCOMMINC, E2002, 0),
 	U3G_DEV(QUALCOMMINC, E2003, 0),
-	U3G_DEV(QUALCOMMINC, AC8710, 0),
-	U3G_DEV(QUALCOMMINC, AC2726, 0),
-	U3G_DEV(QUALCOMMINC, AC8700, 0),
-	U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GFL_SCSI_EJECT),
+	U3G_DEV(QUALCOMMINC, MF626, 0),
+	U3G_DEV(QUALCOMMINC, MF628, 0),
 	U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GFL_SCSI_EJECT),
-	U3G_DEV(QUANTA, Q101, 0),
-	U3G_DEV(QUANTA, Q111, 0),
-	U3G_DEV(QUANTA, GLX, 0),
 	U3G_DEV(QUANTA, GKE, 0),
 	U3G_DEV(QUANTA, GLE, 0),
+	U3G_DEV(QUANTA, GLX, 0),
+	U3G_DEV(QUANTA, Q101, 0),
+	U3G_DEV(QUANTA, Q111, 0),
 	U3G_DEV(SIERRA, AC402, 0),
 	U3G_DEV(SIERRA, AC595U, 0),
 	U3G_DEV(SIERRA, AC597E, 0),

From 3a1f0cab5d96f215125473dcb59644d4872e55df Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:14:02 +0000
Subject: [PATCH 0981/2592] MFC r200822

 Add more EHCI pci ids.
---
 sys/dev/usb/controller/ehci_pci.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index e68df3e7dda..17ec65a512c 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -197,6 +197,10 @@ ehci_pci_match(device_t self)
 		return "Intel 82801JI (ICH10) USB 2.0 controller USB-A";
 	case 0x3a3c8086:
 		return "Intel 82801JI (ICH10) USB 2.0 controller USB-B";
+	case 0x3b348086:
+		return ("Intel PCH USB 2.0 controller USB-A");
+	case 0x3b3c8086:
+		return ("Intel PCH USB 2.0 controller USB-B");
 
 	case 0x00e01033:
 		return ("NEC uPD 720100 USB 2.0 controller");
@@ -213,6 +217,12 @@ ehci_pci_match(device_t self)
 		return "NVIDIA nForce4 USB 2.0 controller";
 	case 0x03f210de:
 		return "NVIDIA nForce MCP61 USB 2.0 controller";
+	case 0x0aa610de:
+		return "NVIDIA nForce MCP79 USB 2.0 controller";
+	case 0x0aa910de:
+		return "NVIDIA nForce MCP79 USB 2.0 controller";
+	case 0x0aaa10de:
+		return "NVIDIA nForce MCP79 USB 2.0 controller";
 
 	case 0x15621131:
 		return "Philips ISP156x USB 2.0 controller";

From afc2c8aef95608bbc05af17e924673b23ffefa4f Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:14:37 +0000
Subject: [PATCH 0982/2592] MFC r200823

 Add more OHCI pci ids.
---
 sys/dev/usb/controller/ohci_pci.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sys/dev/usb/controller/ohci_pci.c b/sys/dev/usb/controller/ohci_pci.c
index 71891586f94..395947174e5 100644
--- a/sys/dev/usb/controller/ohci_pci.c
+++ b/sys/dev/usb/controller/ohci_pci.c
@@ -175,6 +175,12 @@ ohci_pci_match(device_t self)
 
 	case 0x03f110de:
 		return ("nVidia nForce MCP61 USB Controller");
+	case 0x0aa510de:
+		return ("nVidia nForce MCP79 USB Controller");
+	case 0x0aa710de:
+		return ("nVidia nForce MCP79 USB Controller");
+	case 0x0aa810de:
+		return ("nVidia nForce MCP79 USB Controller");
 
 	case 0x70011039:
 		return ("SiS 5571 USB controller");

From a33c9e723636c7f681557544ae4d4b7397f7e520 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:15:36 +0000
Subject: [PATCH 0983/2592] MFC r200825

 - add support for more than 2 audio channels. [1]
 - add support for more sample rates

Submitted by:	[1] ariff (earlier version), Hans Petter Selasky
---
 sys/dev/sound/usb/uaudio.c | 216 +++++++++++++++++++++++++------------
 1 file changed, 146 insertions(+), 70 deletions(-)

diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index ddae8c380c4..dfbeb02c36e 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -87,20 +87,27 @@
 #include 
 #include "feeder_if.h"
 
-static int uaudio_default_rate = 96000;
+static int uaudio_default_rate = 0;		/* use rate list */
 static int uaudio_default_bits = 32;
-static int uaudio_default_channels = 2;
+static int uaudio_default_channels = 0;		/* use default */
 
 #if USB_DEBUG
 static int uaudio_debug = 0;
 
 SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
+
 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW,
     &uaudio_debug, 0, "uaudio debug level");
+
+TUNABLE_INT("hw.usb.uaudio.default_rate", &uaudio_default_rate);
 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_rate, CTLFLAG_RW,
     &uaudio_default_rate, 0, "uaudio default sample rate");
+
+TUNABLE_INT("hw.usb.uaudio.default_bits", &uaudio_default_bits);
 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_bits, CTLFLAG_RW,
     &uaudio_default_bits, 0, "uaudio default sample bits");
+
+TUNABLE_INT("hw.usb.uaudio.default_channels", &uaudio_default_channels);
 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_channels, CTLFLAG_RW,
     &uaudio_default_channels, 0, "uaudio default sample channels");
 #endif
@@ -169,10 +176,16 @@ struct uaudio_chan {
 	uint32_t intr_size;		/* in bytes */
 	uint32_t intr_frames;		/* in units */
 	uint32_t sample_rate;
+	uint32_t frames_per_second;
+	uint32_t sample_rem;
+	uint32_t sample_curr;
+
 	uint32_t format;
 	uint32_t pcm_format[2];
 
-	uint16_t bytes_per_frame;
+	uint16_t bytes_per_frame[2];
+
+	uint16_t sample_size;
 
 	uint8_t	valid;
 	uint8_t	iface_index;
@@ -330,7 +343,7 @@ static usb_callback_t umidi_write_clear_stall_callback;
 static usb_callback_t umidi_bulk_write_callback;
 
 static void	uaudio_chan_fill_info_sub(struct uaudio_softc *,
-		    struct usb_device *, uint32_t, uint16_t, uint8_t, uint8_t);
+		    struct usb_device *, uint32_t, uint8_t, uint8_t);
 static void	uaudio_chan_fill_info(struct uaudio_softc *,
 		    struct usb_device *);
 static void	uaudio_mixer_add_ctl_sub(struct uaudio_softc *,
@@ -787,8 +800,7 @@ uaudio_chan_dump_ep_desc(const usb2_endpoint_descriptor_audio_t *ed)
 
 static void
 uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
-    uint32_t rate, uint16_t fps, uint8_t channels,
-    uint8_t bit_resolution)
+    uint32_t rate, uint8_t channels, uint8_t bit_resolution)
 {
 	struct usb_descriptor *desc = NULL;
 	const struct usb2_audio_streaming_interface_descriptor *asid = NULL;
@@ -811,7 +823,6 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
 	uint8_t bBitResolution;
 	uint8_t x;
 	uint8_t audio_if = 0;
-	uint8_t sample_size;
 
 	while ((desc = usb_desc_foreach(cd, desc))) {
 
@@ -1040,16 +1051,10 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
 						chan->usb2_cfg =
 						    uaudio_cfg_play;
 
-					sample_size = ((
+					chan->sample_size = ((
 					    UAUDIO_MAX_CHAN(chan->p_asf1d->bNrChannels) *
 					    chan->p_asf1d->bBitResolution) / 8);
 
-					/*
-					 * NOTE: "chan->bytes_per_frame"
-					 * should not be zero!
-					 */
-					chan->bytes_per_frame = ((rate / fps) * sample_size);
-
 					if (sc->sc_sndstat_valid) {
 						sbuf_printf(&sc->sc_sndstat, "\n\t"
 						    "mode %d.%d:(%s) %dch, %d/%dbit, %s, %dHz",
@@ -1067,12 +1072,32 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
 	}
 }
 
+/* This structure defines all the supported rates. */
+
+static const uint32_t uaudio_rate_list[] = {
+	96000,
+	88000,
+	80000,
+	72000,
+	64000,
+	56000,
+	48000,
+	44100,
+	40000,
+	32000,
+	24000,
+	22050,
+	16000,
+	11025,
+	8000,
+	0
+};
+
 static void
 uaudio_chan_fill_info(struct uaudio_softc *sc, struct usb_device *udev)
 {
 	uint32_t rate = uaudio_default_rate;
-	uint32_t z;
-	uint16_t fps = usbd_get_isoc_fps(udev);
+	uint8_t z;
 	uint8_t bits = uaudio_default_bits;
 	uint8_t y;
 	uint8_t channels = uaudio_default_channels;
@@ -1083,14 +1108,24 @@ uaudio_chan_fill_info(struct uaudio_softc *sc, struct usb_device *udev)
 		/* set a valid value */
 		bits = 32;
 	}
-	rate -= (rate % fps);
-	if ((rate == 0) || (rate > 192000)) {
-		/* set a valid value */
-		rate = 192000 - (192000 % fps);
-	}
-	if ((channels == 0) || (channels > 2)) {
-		/* set a valid value */
-		channels = 2;
+	if (channels == 0) {
+		switch (usbd_get_speed(udev)) {
+		case USB_SPEED_LOW:
+		case USB_SPEED_FULL:
+			/*
+			 * Due to high bandwidth usage and problems
+			 * with HIGH-speed split transactions we
+			 * disable surround setups on FULL-speed USB
+			 * by default
+			 */
+			channels = 2;
+			break;
+		default:
+			channels = 16;
+			break;
+		}
+	} else if (channels > 16) {
+		channels = 16;
 	}
 	if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND)) {
 		sc->sc_sndstat_valid = 1;
@@ -1099,8 +1134,14 @@ uaudio_chan_fill_info(struct uaudio_softc *sc, struct usb_device *udev)
 
 	for (x = channels; x; x--) {
 		for (y = bits; y; y -= 8) {
-			for (z = rate; z; z -= fps) {
-				uaudio_chan_fill_info_sub(sc, udev, z, fps, x, y);
+
+			/* try user defined rate, if any */
+			if (rate != 0)
+				uaudio_chan_fill_info_sub(sc, udev, rate, x, y);
+
+			/* try find a matching rate, if any */
+			for (z = 0; uaudio_rate_list[z]; z++) {
+				uaudio_chan_fill_info_sub(sc, udev, uaudio_rate_list[z], x, y);
 
 				if (sc->sc_rec_chan.valid &&
 				    sc->sc_play_chan.valid) {
@@ -1116,18 +1157,6 @@ done:
 	}
 }
 
-/*
- * The following function sets up data size and block count for the
- * next audio transfer.
- */
-static void
-uaudio_setup_blockcount(struct uaudio_chan *ch,
-    uint32_t *total, uint32_t *blockcount)
-{
-	*total = ch->intr_size;
-	*blockcount = ch->intr_frames;
-}
-
 static void
 uaudio_chan_play_callback(struct usb_xfer *xfer, usb_error_t error)
 {
@@ -1137,12 +1166,11 @@ uaudio_chan_play_callback(struct usb_xfer *xfer, usb_error_t error)
 	uint32_t blockcount;
 	uint32_t n;
 	uint32_t offset;
-	int actlen, sumlen;
+	int actlen;
+	int sumlen;
 
 	usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
 
-	uaudio_setup_blockcount(ch, &total, &blockcount);
-
 	if (ch->end == ch->start) {
 		DPRINTF("no buffer!\n");
 		return;
@@ -1153,22 +1181,39 @@ uaudio_chan_play_callback(struct usb_xfer *xfer, usb_error_t error)
 tr_transferred:
 		if (actlen < sumlen) {
 			DPRINTF("short transfer, "
-			    "%d of %d bytes\n", actlen, total);
+			    "%d of %d bytes\n", actlen, sumlen);
 		}
 		chn_intr(ch->pcm_ch);
 
 	case USB_ST_SETUP:
-		if (ch->bytes_per_frame > usbd_xfer_max_framelen(xfer)) {
+		if (ch->bytes_per_frame[1] > usbd_xfer_max_framelen(xfer)) {
 			DPRINTF("bytes per transfer, %d, "
 			    "exceeds maximum, %d!\n",
-			    ch->bytes_per_frame,
+			    ch->bytes_per_frame[1],
 			    usbd_xfer_max_framelen(xfer));
 			break;
 		}
-		/* setup frame length */
+
+		blockcount = ch->intr_frames;
+
+		/* setup number of frames */
 		usbd_xfer_set_frames(xfer, blockcount);
-		for (n = 0; n != blockcount; n++)
-			usbd_xfer_set_frame_len(xfer, n, ch->bytes_per_frame);
+
+		/* reset total length */
+		total = 0;
+
+		/* setup frame lengths */
+		for (n = 0; n != blockcount; n++) {
+			ch->sample_curr += ch->sample_rem;
+			if (ch->sample_curr >= ch->frames_per_second) {
+				ch->sample_curr -= ch->frames_per_second;
+				usbd_xfer_set_frame_len(xfer, n, ch->bytes_per_frame[1]);
+				total += ch->bytes_per_frame[1];
+			} else {
+				usbd_xfer_set_frame_len(xfer, n, ch->bytes_per_frame[0]);
+				total += ch->bytes_per_frame[0];
+			}
+		}
 
 		DPRINTFN(6, "transfer %d bytes\n", total);
 
@@ -1210,7 +1255,6 @@ uaudio_chan_record_callback(struct usb_xfer *xfer, usb_error_t error)
 	struct usb_page_cache *pc;
 	uint32_t n;
 	uint32_t m;
-	uint32_t total;
 	uint32_t blockcount;
 	uint32_t offset0;
 	uint32_t offset1;
@@ -1222,8 +1266,6 @@ uaudio_chan_record_callback(struct usb_xfer *xfer, usb_error_t error)
 	usbd_xfer_status(xfer, &actlen, NULL, NULL, &nframes);
 	mfl = usbd_xfer_max_framelen(xfer);
 
-	uaudio_setup_blockcount(ch, &total, &blockcount);
-
 	if (ch->end == ch->start) {
 		DPRINTF("no buffer!\n");
 		return;
@@ -1231,12 +1273,8 @@ uaudio_chan_record_callback(struct usb_xfer *xfer, usb_error_t error)
 
 	switch (USB_GET_STATE(xfer)) {
 	case USB_ST_TRANSFERRED:
-		if (actlen < total) {
-			DPRINTF("short transfer, "
-			    "%d of %d bytes\n", actlen, total);
-		} else {
-			DPRINTFN(6, "transferred %d bytes\n", actlen);
-		}
+
+		DPRINTFN(6, "transferred %d bytes\n", actlen);
 
 		offset0 = 0;
 		pc = usbd_xfer_get_frame(xfer, 0);
@@ -1271,6 +1309,8 @@ uaudio_chan_record_callback(struct usb_xfer *xfer, usb_error_t error)
 
 	case USB_ST_SETUP:
 tr_setup:
+		blockcount = ch->intr_frames;
+
 		usbd_xfer_set_frames(xfer, blockcount);
 		for (n = 0; n < blockcount; n++) {
 			usbd_xfer_set_frame_len(xfer, n, mfl);
@@ -1295,6 +1335,8 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b,
 	    &sc->sc_play_chan : &sc->sc_rec_chan);
 	uint32_t buf_size;
 	uint32_t frames;
+	uint32_t format;
+	uint16_t fps;
 	uint8_t endpoint;
 	uint8_t blocks;
 	uint8_t iface_index;
@@ -1302,7 +1344,9 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b,
 	uint8_t fps_shift;
 	usb_error_t err;
 
-	if (usbd_get_isoc_fps(sc->sc_udev) < 8000) {
+	fps = usbd_get_isoc_fps(sc->sc_udev);
+
+	if (fps < 8000) {
 		/* FULL speed USB */
 		frames = 8;
 	} else {
@@ -1310,10 +1354,6 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b,
 		frames = UAUDIO_NFRAMES;
 	}
 
-	/* compute required buffer size */
-
-	buf_size = (ch->bytes_per_frame * frames);
-
 	/* setup play/record format */
 
 	ch->pcm_cap.fmtlist = ch->pcm_format;
@@ -1329,15 +1369,34 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b,
 	ch->pcm_ch = c;
 	ch->pcm_mtx = c->lock;
 
-	if (ch->p_asf1d->bNrChannels >= 2)
-		ch->pcm_cap.fmtlist[0] =
-		    SND_FORMAT(ch->p_fmt->freebsd_fmt, 2, 0);
-	else
-		ch->pcm_cap.fmtlist[0] =
-		    SND_FORMAT(ch->p_fmt->freebsd_fmt, 1, 0);
+	format = ch->p_fmt->freebsd_fmt;
 
+	switch (ch->p_asf1d->bNrChannels) {
+	case 2:
+		/* stereo */
+		format = SND_FORMAT(format, 2, 0);
+		break;
+	case 1:
+		/* mono */
+		format = SND_FORMAT(format, 1, 0);
+		break;
+	default:
+		/* surround and more */
+		format = feeder_matrix_default_format(
+		    SND_FORMAT(format, ch->p_asf1d->bNrChannels, 0));
+		break;
+	}
+
+	ch->pcm_cap.fmtlist[0] = format;
 	ch->pcm_cap.fmtlist[1] = 0;
 
+	/* check if format is not supported */
+
+	if (format == 0) {
+		DPRINTF("The selected audio format is not supported\n");
+		goto error;
+	}
+
 	/* set alternate interface corresponding to the mode */
 
 	endpoint = ch->p_ed1->bEndpointAddress;
@@ -1377,10 +1436,27 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b,
 
 	fps_shift = usbd_xfer_get_fps_shift(ch->xfer[0]);
 
-	/* setup frame sizes */
+	/* down shift number of frames per second, if any */
+	fps >>= fps_shift;
+	frames >>= fps_shift;
+
+	/* bytes per frame should not be zero */
+	ch->bytes_per_frame[0] = ((ch->sample_rate / fps) * ch->sample_size);
+	ch->bytes_per_frame[1] = (((ch->sample_rate + fps - 1) / fps) * ch->sample_size);
+
+	/* setup data rate dithering, if any */
+	ch->frames_per_second = fps;
+	ch->sample_rem = ch->sample_rate % fps;
+	ch->sample_curr = 0;
+	ch->frames_per_second = fps;
+
+	/* compute required buffer size */
+	buf_size = (ch->bytes_per_frame[1] * frames);
+
 	ch->intr_size = buf_size;
-	ch->intr_frames = (frames >> fps_shift);
-	ch->bytes_per_frame <<= fps_shift;
+	ch->intr_frames = frames;
+
+	DPRINTF("fps=%d sample_rem=%d\n", fps, ch->sample_rem);
 
 	if (ch->intr_frames == 0) {
 		DPRINTF("frame shift is too high!\n");

From ba0bb08c53f8982e990982d8eaba1273c47e9d52 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:17:09 +0000
Subject: [PATCH 0984/2592] MFC r200826

 add new ID to UFTDI driver.

Submitted by:	YAMAMOTO, Shigeru
---
 sys/dev/usb/serial/uftdi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
index 8a2ef6d28d1..44322c7e7a7 100644
--- a/sys/dev/usb/serial/uftdi.c
+++ b/sys/dev/usb/serial/uftdi.c
@@ -252,6 +252,7 @@ static struct usb_device_id uftdi_devs[] = {
 	{USB_VPI(USB_VENDOR_BBELECTRONICS, USB_PRODUCT_BBELECTRONICS_USOTL4, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_MARVELL, USB_PRODUCT_MARVELL_SHEEVAPLUG, UFTDI_TYPE_8U232AM)},
 	{USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_PCOPRS1, UFTDI_TYPE_8U232AM)},
+	{USB_VPI(USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60F, UFTDI_TYPE_8U232AM)},
 };
 
 static int

From c13e3621841efbb5d7a6e2c388d2f5634e781377 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:17:59 +0000
Subject: [PATCH 0985/2592] MFC r200827

 Add missed usb product define in r200826.
---
 sys/dev/usb/usbdevs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 29d09a386e4..565b2eaf458 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -2346,6 +2346,7 @@ product ROCKFIRE GAMEPAD	0x2033	gamepad 203USB
 
 /* RATOC Systems products */
 product RATOC REXUSB60		0xb000	REX-USB60
+product RATOC REXUSB60F		0xb020	REX-USB60F
 
 /* Sagem products */
 product SAGEM USBSERIAL		0x0027	USB-Serial Controller

From d5b8cd836625c60069f43740e9a8e8d2abdc34d3 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:18:38 +0000
Subject: [PATCH 0986/2592] MFC r200885

 Sync usb vendor/product defines to p4
---
 sys/dev/usb/usbdevs | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 565b2eaf458..1b8315a9927 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -328,6 +328,7 @@ vendor AVISION		0x0638	Avision
 vendor TEAC		0x0644	TEAC
 vendor SGI		0x065e	Silicon Graphics
 vendor SANWASUPPLY	0x0663	Sanwa Supply
+vendor MEGATEC		0x0665	Megatec
 vendor LINKSYS		0x066b	Linksys
 vendor ACERSA		0x066e	Acer Semiconductor America
 vendor SIGMATEL		0x066f	Sigmatel
@@ -666,6 +667,7 @@ vendor SITECOM		0x6189	Sitecom
 vendor ARKMICRO		0x6547	Arkmicro Technologies Inc.
 vendor 3COM2		0x6891	3Com
 vendor INTEL		0x8086	Intel
+vendor INTEL2		0x8087	Intel
 vendor SITECOM2		0x9016	Sitecom
 vendor MOSCHIP		0x9710	MosChip Semiconductor
 vendor MARVELL		0x9e88	Marvell Technology Group Ltd.
@@ -1062,6 +1064,7 @@ product CHIC CYPRESS		0x0003	Cypress USB Mouse
 
 /* Chicony products */
 product CHICONY KB8933		0x0001	KB-8933 keyboard
+product CHICONY CNF7129		0xb071	Notebook Web Camera
 product CHICONY2 TWINKLECAM	0x600d	TwinkleCam USB camera
 
 /* CH Products */
@@ -1628,6 +1631,7 @@ product INSYSTEM STORAGE_V2	0x5701	USB Storage Adapter V2
 /* Intel products */
 product INTEL EASYPC_CAMERA	0x0110	Easy PC Camera
 product INTEL TESTBOARD		0x9890	82930 test board
+product INTEL2 IRMH        	0x0020	Integrated Rate Matching Hub
 
 /* Intersil products */
 product INTERSIL PRISM_GT	0x1000	PrismGT USB 2.0 WLAN
@@ -2136,7 +2140,10 @@ product PHILIPS UM10016		0x1552	ISP 1581 Hi-Speed USB MPEG2 Encoder Reference Ki
 product PHILIPS DIVAUSB		0x1801	DIVA USB mp3 player
 
 /* Philips Semiconductor products */
-product PHILIPSSEMI HUB1122	0x1122	hub
+product PHILIPSSEMI HUB1122	0x1122	HUB
+
+/* Megatec */
+product MEGATEC UPS		0x5161	Protocol based UPS
 
 /* P.I. Engineering products */
 product PIENGINEERING PS2USB	0x020b	PS2 to Mac USB Adapter

From 596828bab24192b893c6c0e27f81656458753db9 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:19:16 +0000
Subject: [PATCH 0987/2592] MFC r200886

 Move all Mass Storage Quirks over to the USB quirk module.

Submitted by:	Hans Petter Selasky
---
 sys/dev/usb/quirk/usb_quirk.c | 425 ++++++++++++++++++-
 sys/dev/usb/quirk/usb_quirk.h |  30 ++
 sys/dev/usb/storage/umass.c   | 767 ++++------------------------------
 3 files changed, 534 insertions(+), 688 deletions(-)

diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index 005a0588536..e2a0c778b15 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -66,7 +66,7 @@ MODULE_VERSION(usb_quirk, 1);
 #define	USB_QUIRK_ENTRY(v,p,l,h,...) \
   .vid = (v), .pid = (p), .lo_rev = (l), .hi_rev = (h), .quirks = { __VA_ARGS__ }
 
-#define	USB_DEV_QUIRKS_MAX 128
+#define	USB_DEV_QUIRKS_MAX 256
 #define	USB_SUB_QUIRKS_MAX 8
 
 struct usb_quirk_entry {
@@ -183,10 +183,396 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	{USB_QUIRK_ENTRY(USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_UM175,
 	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
 
+	/* USB Mass Storage Class Quirks */
+	{USB_QUIRK_ENTRY(USB_VENDOR_ASAHIOPTICAL, 0,
+	    0x0000, 0xFFFF, UQ_MSC_NO_RS_CLEAR_UA, UQ_MATCH_VENDOR_ONLY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_ATTACHE, 0x0000,
+	    0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_A256MB,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_DISKPRO512,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_CABLE_205,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_AIPTEK, USB_PRODUCT_AIPTEK_POCKETCAM3M,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_AIPTEK2, USB_PRODUCT_AIPTEK2_SUNPLUS_TECH,
+	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_SDCR_6335,
+	    0x0000, 0xFFFF, UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU6390,
+	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_UMCR_9361,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_TRANSCEND,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO330,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2SCSI,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV_DIGICAM,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_CCYU, USB_PRODUCT_CCYU_ED1064,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_CENTURY, USB_PRODUCT_CENTURY_EX35QUAT,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_XX6830XX,
+	    0x0000, 0xFFFF, UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_DESKNOTE, USB_PRODUCT_DESKNOTE_UCR_61S2B,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_DMI, USB_PRODUCT_DMI_CFSM_RW,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_875DC,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_895,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_FEIYA, USB_PRODUCT_FEIYA_5IN1,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_RS_CLEAR_UA)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE,
+	    UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE_2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB_2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_WRONG_CSWSIG)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_DZ_MV100A,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_CDW4E,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_ATAPI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_IMAGINATION, USB_PRODUCT_IMAGINATION_DBX1,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_WRONG_CSWSIG)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP, UQ_MSC_ALT_IFACE_1)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_STORAGE_V2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_IU_CD2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_DVR_UEH8,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_TEST_UNIT_READY)}, /* XXX ZIP drives can also use ATAPI */
+	{USB_QUIRK_ENTRY(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_L3,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S3X,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S4,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S5,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_LACIE, USB_PRODUCT_LACIE_HD,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_CF_READER,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPSHOT,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443SU2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443U2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIHD50,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_E223,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_F300,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI | UQ_MSC_FORCE_PROTO_ATAPI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_FDD,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_E398,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_INQUIRY_EVPD, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MPMAN, 0,
+	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_RS_CLEAR_UA)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN,
+	    0x0000, 0xFFFF, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN_8813,
+	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_STARREADER,
+	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_FORCE_SHORT_INQ)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_NETAC, USB_PRODUCT_NETAC_CF_CARD,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_NETAC, USB_PRODUCT_NETAC_ONLYDISK,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK_40,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_NIKON, USB_PRODUCT_NIKON_D300,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_WRONG_CSWSIG)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700,
+	    0x0000, 0xFFFF, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_COMBO,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFE_B_CF_READER,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDSM_B_READER,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_READER,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_UCF100,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_INQUIRY | UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC2, USB_PRODUCT_ONSPEC2_IMAGEMATE_SDDR55,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXL840AN,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB20AN,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB35AN,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_LS120CAM,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_UFI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SPE3030CC,
+	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_TEST_UNIT_READY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_PNY, USB_PRODUCT_PNY_ATTACHE2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_START_STOP)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SAMSUNG_TECHWIN, USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_READ_CAP_OFFBY1, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_READ_CAP_OFFBY1, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_128,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_256,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_READ_CAP_OFFBY1)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP, UQ_MSC_SHUTTLE_INIT)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBCFSM,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_SHUTTLE_INIT)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SIIG, USB_PRODUCT_SIIG_WINTERREADER,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_MD_7425,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_SX_520Z,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM,
+	    0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC,
+	    UQ_MSC_RBC_PAD_TO_12)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
+	    0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC,
+	    UQ_MSC_RBC_PAD_TO_12)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
+	    0x0600, 0x0600, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC,
+	    UQ_MSC_RBC_PAD_TO_12)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_MSC_U03,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_NW_MS7,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_PEG_N760C,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_PORTABLE_HDD_V2,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDE,
+	    0x0000, 0xFFFF, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TECLAST, USB_PRODUCT_TECLAST_TLC300,
+	    0x0000, 0xFFFF, UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TREK, USB_PRODUCT_TREK_MEMKEY,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_C3310,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_MP3,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_RBC)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_T33520,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_MDIV,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_VIA, USB_PRODUCT_VIA_USB2IDEBRIDGE,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_VIVITAR, USB_PRODUCT_VIVITAR_35XX,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_EXTHDD,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYBOOK,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY_EVPD)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSWORD,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_SHORT_INQ)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_WINMAXGROUP, USB_PRODUCT_WINMAXGROUP_FLASH64MC,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_YANO, USB_PRODUCT_YANO_FW800HD,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_FORCE_SHORT_INQ)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
+	    0x0000, 0x007F, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI,
+	    UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED,
+	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
+	    0x0080, 0x0080, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_UFI,
+	    UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED,
+	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
+	    0x0081, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_UFI,
+	    UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED, UQ_MSC_NO_GETMAXLUN)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ZORAN, USB_PRODUCT_ZORAN_EX20DSC,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_INQUIRY, UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ACTIONS, USB_PRODUCT_ACTIONS_MP4,
+	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_SYNC_CACHE)},
+	{USB_QUIRK_ENTRY(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_GMSC,
+	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
 };
 
 static const char *usb_quirk_str[USB_QUIRK_MAX] = {
 	[UQ_NONE]		= "UQ_NONE",
+	[UQ_MATCH_VENDOR_ONLY]	= "UQ_MATCH_VENDOR_ONLY",
 	[UQ_AUDIO_SWAP_LR]	= "UQ_AUDIO_SWAP_LR",
 	[UQ_AU_INP_ASYNC]	= "UQ_AU_INP_ASYNC",
 	[UQ_AU_NO_FRAC]		= "UQ_AU_NO_FRAC",
@@ -210,7 +596,29 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
 	[UQ_CFG_INDEX_3]	= "UQ_CFG_INDEX_3",
 	[UQ_CFG_INDEX_4]	= "UQ_CFG_INDEX_4",
 	[UQ_CFG_INDEX_0]	= "UQ_CFG_INDEX_0",
-	[UQ_ASSUME_CM_OVER_DATA]= "UQ_ASSUME_CM_OVER_DATA",
+	[UQ_ASSUME_CM_OVER_DATA]	= "UQ_ASSUME_CM_OVER_DATA",
+	[UQ_MSC_NO_TEST_UNIT_READY]	= "UQ_MSC_NO_TEST_UNIT_READY",
+	[UQ_MSC_NO_RS_CLEAR_UA]		= "UQ_MSC_NO_RS_CLEAR_UA",
+	[UQ_MSC_NO_START_STOP]		= "UQ_MSC_NO_START_STOP",
+	[UQ_MSC_NO_GETMAXLUN]		= "UQ_MSC_NO_GETMAXLUN",
+	[UQ_MSC_NO_INQUIRY]		= "UQ_MSC_NO_INQUIRY",
+	[UQ_MSC_NO_INQUIRY_EVPD]	= "UQ_MSC_NO_INQUIRY_EVPD",
+	[UQ_MSC_NO_SYNC_CACHE]		= "UQ_MSC_NO_SYNC_CACHE",
+	[UQ_MSC_SHUTTLE_INIT]		= "UQ_MSC_SHUTTLE_INIT",
+	[UQ_MSC_ALT_IFACE_1]		= "UQ_MSC_ALT_IFACE_1",
+	[UQ_MSC_FLOPPY_SPEED]		= "UQ_MSC_FLOPPY_SPEED",
+	[UQ_MSC_IGNORE_RESIDUE]		= "UQ_MSC_IGNORE_RESIDUE",
+	[UQ_MSC_WRONG_CSWSIG]		= "UQ_MSC_WRONG_CSWSIG",
+	[UQ_MSC_RBC_PAD_TO_12]		= "UQ_MSC_RBC_PAD_TO_12",
+	[UQ_MSC_READ_CAP_OFFBY1]	= "UQ_MSC_READ_CAP_OFFBY1",
+	[UQ_MSC_FORCE_SHORT_INQ]	= "UQ_MSC_FORCE_SHORT_INQ",
+	[UQ_MSC_FORCE_WIRE_BBB]		= "UQ_MSC_FORCE_WIRE_BBB",
+	[UQ_MSC_FORCE_WIRE_CBI]		= "UQ_MSC_FORCE_WIRE_CBI",
+	[UQ_MSC_FORCE_WIRE_CBI_I]	= "UQ_MSC_FORCE_WIRE_CBI_I",
+	[UQ_MSC_FORCE_PROTO_SCSI]	= "UQ_MSC_FORCE_PROTO_SCSI",
+	[UQ_MSC_FORCE_PROTO_ATAPI]	= "UQ_MSC_FORCE_PROTO_ATAPI",
+	[UQ_MSC_FORCE_PROTO_UFI]	= "UQ_MSC_FORCE_PROTO_UFI",
+	[UQ_MSC_FORCE_PROTO_RBC]	= "UQ_MSC_FORCE_PROTO_RBC",
 };
 
 /*------------------------------------------------------------------------*
@@ -246,11 +654,22 @@ usb_test_quirk_by_info(const struct usbd_lookup_info *info, uint16_t quirk)
 	for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) {
 		/* see if quirk information does not match */
 		if ((usb_quirks[x].vid != info->idVendor) ||
-		    (usb_quirks[x].pid != info->idProduct) ||
 		    (usb_quirks[x].lo_rev > info->bcdDevice) ||
 		    (usb_quirks[x].hi_rev < info->bcdDevice)) {
 			continue;
 		}
+		/* see if quirk only should match vendor ID */
+		if (usb_quirks[x].pid != info->idProduct) {
+			if (usb_quirks[x].pid != 0)
+				continue;
+
+			for (y = 0; y != USB_SUB_QUIRKS_MAX; y++) {
+				if (usb_quirks[x].quirks[y] == UQ_MATCH_VENDOR_ONLY)
+					break;
+			}
+			if (y == USB_SUB_QUIRKS_MAX)
+				continue;
+		}
 		/* lookup quirk */
 		for (y = 0; y != USB_SUB_QUIRKS_MAX; y++) {
 			if (usb_quirks[x].quirks[y] == quirk) {
diff --git a/sys/dev/usb/quirk/usb_quirk.h b/sys/dev/usb/quirk/usb_quirk.h
index ee40c2fb3b9..3187bcacc2c 100644
--- a/sys/dev/usb/quirk/usb_quirk.h
+++ b/sys/dev/usb/quirk/usb_quirk.h
@@ -30,6 +30,11 @@
 /* NOTE: UQ_NONE is not a valid quirk */
 enum {	/* keep in sync with usb_quirk_str table */
 	UQ_NONE,
+
+	UQ_MATCH_VENDOR_ONLY,
+
+	/* Various quirks */
+
 	UQ_AUDIO_SWAP_LR,	/* left and right sound channels are swapped */
 	UQ_AU_INP_ASYNC,	/* input is async despite claim of adaptive */
 	UQ_AU_NO_FRAC,		/* don't adjust for fractional samples */
@@ -54,6 +59,31 @@ enum {	/* keep in sync with usb_quirk_str table */
 	UQ_CFG_INDEX_4,		/* select configuration index 4 by default */
 	UQ_CFG_INDEX_0,		/* select configuration index 0 by default */
 	UQ_ASSUME_CM_OVER_DATA,	/* modem device breaks on cm over data */
+
+	/* USB Mass Storage Quirks. See "storage/umass.c" for a detailed description. */
+	UQ_MSC_NO_TEST_UNIT_READY,
+	UQ_MSC_NO_RS_CLEAR_UA,
+	UQ_MSC_NO_START_STOP,
+	UQ_MSC_NO_GETMAXLUN,
+	UQ_MSC_NO_INQUIRY,
+	UQ_MSC_NO_INQUIRY_EVPD,
+	UQ_MSC_NO_SYNC_CACHE,
+	UQ_MSC_SHUTTLE_INIT,
+	UQ_MSC_ALT_IFACE_1,
+	UQ_MSC_FLOPPY_SPEED,
+	UQ_MSC_IGNORE_RESIDUE,
+	UQ_MSC_WRONG_CSWSIG,
+	UQ_MSC_RBC_PAD_TO_12,
+	UQ_MSC_READ_CAP_OFFBY1,
+	UQ_MSC_FORCE_SHORT_INQ,
+	UQ_MSC_FORCE_WIRE_BBB,
+	UQ_MSC_FORCE_WIRE_CBI,
+	UQ_MSC_FORCE_WIRE_CBI_I,
+	UQ_MSC_FORCE_PROTO_SCSI,
+	UQ_MSC_FORCE_PROTO_ATAPI,
+	UQ_MSC_FORCE_PROTO_UFI,
+	UQ_MSC_FORCE_PROTO_RBC,
+
 	USB_QUIRK_MAX
 };
 
diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
index 36ed09cc1bb..0b6ceffa536 100644
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -127,6 +127,8 @@ __FBSDID("$FreeBSD$");
 #include 
 #include "usbdevs.h"
 
+#include 
+
 #include 
 #include 
 #include 
@@ -311,32 +313,18 @@ typedef void (umass_callback_t)(struct umass_softc *sc, union ccb *ccb,
 typedef uint8_t (umass_transform_t)(struct umass_softc *sc, uint8_t *cmd_ptr,
     	uint8_t cmd_len);
 
-struct umass_devdescr {
-	uint32_t vid;
-#define	VID_WILDCARD	0xffffffff
-#define	VID_EOT		0xfffffffe
-	uint32_t pid;
-#define	PID_WILDCARD	0xffffffff
-#define	PID_EOT		0xfffffffe
-	uint32_t rid;
-#define	RID_WILDCARD	0xffffffff
-#define	RID_EOT		0xfffffffe
-
-	/* wire and command protocol */
-	uint16_t proto;
-#define	UMASS_PROTO_DEFAULT	0x0000	/* use protocol indicated by USB descriptors */
+/* Wire and command protocol */
 #define	UMASS_PROTO_BBB		0x0001	/* USB wire protocol */
 #define	UMASS_PROTO_CBI		0x0002
 #define	UMASS_PROTO_CBI_I	0x0004
-#define	UMASS_PROTO_WIRE		0x00ff	/* USB wire protocol mask */
-#define	UMASS_PROTO_SCSI		0x0100	/* command protocol */
+#define	UMASS_PROTO_WIRE	0x00ff	/* USB wire protocol mask */
+#define	UMASS_PROTO_SCSI	0x0100	/* command protocol */
 #define	UMASS_PROTO_ATAPI	0x0200
 #define	UMASS_PROTO_UFI		0x0400
 #define	UMASS_PROTO_RBC		0x0800
 #define	UMASS_PROTO_COMMAND	0xff00	/* command protocol mask */
 
-	/* Device specific quirks */
-	uint16_t quirks;
+/* Device specific quirks */
 #define	NO_QUIRKS		0x0000
 	/*
 	 * The drive does not support Test Unit Ready. Convert to Start Unit
@@ -384,608 +372,6 @@ struct umass_devdescr {
 	 * result.
 	 */
 #define	NO_SYNCHRONIZE_CACHE	0x4000
-};
-
-static const struct umass_devdescr umass_devdescr[] = {
-	{USB_VENDOR_ASAHIOPTICAL, PID_WILDCARD, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		RS_NO_CLEAR_UA
-	},
-	{USB_VENDOR_ADDON, USB_PRODUCT_ADDON_ATTACHE, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE
-	},
-	{USB_VENDOR_ADDON, USB_PRODUCT_ADDON_A256MB, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE
-	},
-	{USB_VENDOR_ADDON, USB_PRODUCT_ADDON_DISKPRO512, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE
-	},
-	{USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_CABLE_205, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_AIPTEK, USB_PRODUCT_AIPTEK_POCKETCAM3M, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_AIPTEK2, USB_PRODUCT_AIPTEK2_SUNPLUS_TECH, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_SDCR_6335, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_TEST_UNIT_READY | NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU6390, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_UMCR_9361, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_TRANSCEND, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO330, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2SCSI, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV_DIGICAM, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_CCYU, USB_PRODUCT_CCYU_ED1064, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_CENTURY, USB_PRODUCT_CENTURY_EX35QUAT, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
-	},
-	{USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_XX6830XX, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_DESKNOTE, USB_PRODUCT_DESKNOTE_UCR_61S2B, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_DMI, USB_PRODUCT_DMI_CFSM_RW, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_875DC, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_895, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_FEIYA, USB_PRODUCT_FEIYA_5IN1, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
-		RS_NO_CLEAR_UA
-	},
-	{USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
-		    | NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE_2, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
-	},
-	{USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
-	},
-	{USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB_2, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		WRONG_CSWSIG
-	},
-	{USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_DZ_MV100A, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_HP, USB_PRODUCT_HP_CDW4E, RID_WILDCARD,
-		UMASS_PROTO_ATAPI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
-		NO_TEST_UNIT_READY | NO_START_STOP
-	},
-	{USB_VENDOR_IMAGINATION, USB_PRODUCT_IMAGINATION_DBX1, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		WRONG_CSWSIG
-	},
-	{USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
-		NO_TEST_UNIT_READY | NO_START_STOP | ALT_IFACE_1
-	},
-	{USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI, RID_WILDCARD,
-		UMASS_PROTO_RBC | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_STORAGE_V2, RID_WILDCARD,
-		UMASS_PROTO_RBC | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_IODATA, USB_PRODUCT_IODATA_IU_CD2, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_IODATA, USB_PRODUCT_IODATA_DVR_UEH8, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100, RID_WILDCARD,
-		/*
-		 * XXX This is not correct as there are Zip drives that use
-		 * ATAPI.
-		 */
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_TEST_UNIT_READY
-	},
-	{USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_L3, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S3X, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S4, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S5, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_LACIE, USB_PRODUCT_LACIE_HD, RID_WILDCARD,
-		UMASS_PROTO_RBC | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_CF_READER, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPSHOT, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443SU2, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443U2, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
-	},
-	{USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
-		NO_TEST_UNIT_READY | NO_START_STOP
-	},
-	{USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIHD50, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_E223, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_F300, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_FDD, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_E398, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY | NO_INQUIRY_EVPD | NO_GETMAXLUN
-	},
-	{USB_VENDOR_MPMAN, PID_WILDCARD, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE | NO_GETMAXLUN | RS_NO_CLEAR_UA
-	},
-	{USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		IGNORE_RESIDUE | NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN_8813, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_MYSON, USB_PRODUCT_MYSON_STARREADER, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY
-	},
-	{USB_VENDOR_NETAC, USB_PRODUCT_NETAC_CF_CARD, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_NETAC, USB_PRODUCT_NETAC_ONLYDISK, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE
-	},
-	{USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK_40, RID_WILDCARD,
-		UMASS_PROTO_ATAPI,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_NIKON, USB_PRODUCT_NIKON_D300, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		WRONG_CSWSIG
-	},
-	{USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_COMBO, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER2, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFE_B_CF_READER, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDSM_B_READER, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_READER, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_UCF100, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
-		NO_INQUIRY | NO_GETMAXLUN
-	},
-	{USB_VENDOR_ONSPEC2, USB_PRODUCT_ONSPEC2_IMAGEMATE_SDDR55, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXL840AN, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB20AN, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB35AN, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_LS120CAM, RID_WILDCARD,
-		UMASS_PROTO_UFI,
-		NO_QUIRKS
-	},
-	{ USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SPE3030CC, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_TEST_UNIT_READY
-	},
-	{USB_VENDOR_PNY, USB_PRODUCT_PNY_ATTACHE2, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE | NO_START_STOP
-	},
-	{USB_VENDOR_SAMSUNG_TECHWIN, USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
-		READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
-	},
-	{USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
-	},
-	{USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
-		READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
-	},
-	{USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE
-	},
-	{USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_128, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE
-	},
-	{USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_256, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE
-	},
-	{USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		READ_CAPACITY_OFFBY1
-	},
-	{USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
-		NO_TEST_UNIT_READY | NO_START_STOP | SHUTTLE_INIT
-	},
-	{USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBCFSM, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		SHUTTLE_INIT
-	},
-	{USB_VENDOR_SIIG, USB_PRODUCT_SIIG_WINTERREADER, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE
-	},
-	{USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_MD_7425, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_SX_520Z, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM, 0x0500,
-		UMASS_PROTO_RBC | UMASS_PROTO_CBI,
-		RBC_PAD_TO_12
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, 0x0500,
-		UMASS_PROTO_RBC | UMASS_PROTO_CBI,
-		RBC_PAD_TO_12
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, 0x0600,
-		UMASS_PROTO_RBC | UMASS_PROTO_CBI,
-		RBC_PAD_TO_12
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, RID_WILDCARD,
-		UMASS_PROTO_RBC | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM, RID_WILDCARD,
-		UMASS_PROTO_RBC | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC, RID_WILDCARD,
-		UMASS_PROTO_RBC | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_MSC_U03, RID_WILDCARD,
-		UMASS_PROTO_UFI | UMASS_PROTO_CBI,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_NW_MS7, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_PEG_N760C, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_SONY, USB_PRODUCT_SONY_PORTABLE_HDD_V2, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDE, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		IGNORE_RESIDUE | NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB, RID_WILDCARD,
-		UMASS_PROTO_UFI | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_TECLAST, USB_PRODUCT_TECLAST_TLC300, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_TEST_UNIT_READY | NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_TREK, USB_PRODUCT_TREK_MEMKEY, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
-		IGNORE_RESIDUE
-	},
-	{USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_C3310, RID_WILDCARD,
-		UMASS_PROTO_UFI | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_MP3, RID_WILDCARD,
-		UMASS_PROTO_RBC,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_T33520, RID_WILDCARD,
-		UMASS_PROTO_SCSI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_MDIV, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_VIA, USB_PRODUCT_VIA_USB2IDEBRIDGE, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_VIVITAR, USB_PRODUCT_VIVITAR_35XX, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
-	},
-	{USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_EXTHDD, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
-	},
-	{USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYBOOK, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY_EVPD
-	},
-	{USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSWORD, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		FORCE_SHORT_INQUIRY
-	},
-	{USB_VENDOR_WINMAXGROUP, USB_PRODUCT_WINMAXGROUP_FLASH64MC, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY
-	},
-	{USB_VENDOR_YANO, USB_PRODUCT_YANO_FW800HD, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
-	},
-	{USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
-		FORCE_SHORT_INQUIRY
-	},
-	{USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
-		NO_GETMAXLUN
-	},
-	{USB_VENDOR_ZORAN, USB_PRODUCT_ZORAN_EX20DSC, RID_WILDCARD,
-		UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
-		NO_QUIRKS
-	},
-	{USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_INQUIRY | NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_ACTIONS, USB_PRODUCT_ACTIONS_MP4, RID_WILDCARD,
-		UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
-		NO_SYNCHRONIZE_CACHE
-	},
-	{USB_VENDOR_ASUS, USB_PRODUCT_ASUS_GMSC, RID_WILDCARD,
-		UMASS_PROTO_DEFAULT,
-		NO_SYNCHRONIZE_CACHE
-	},
-	{VID_EOT, PID_EOT, RID_EOT, 0, 0}
-};
 
 struct umass_softc {
 
@@ -1027,9 +413,8 @@ struct umass_softc {
 	umass_transform_t *sc_transform;
 
 	uint32_t sc_unit;
-
-	uint16_t sc_proto;		/* wire and cmd protocol */
-	uint16_t sc_quirks;		/* they got it almost right */
+	uint32_t sc_quirks;		/* they got it almost right */
+	uint32_t sc_proto;		/* wire and cmd protocol */
 
 	uint8_t	sc_name[16];
 	uint8_t	sc_iface_no;		/* interface number */
@@ -1039,10 +424,10 @@ struct umass_softc {
 };
 
 struct umass_probe_proto {
-	uint16_t quirks;
-	uint16_t proto;
+	uint32_t quirks;
+	uint32_t proto;
 
-	int32_t	error;
+	int	error;
 };
 
 /* prototypes */
@@ -1366,7 +751,6 @@ umass_get_proto(struct usb_interface *iface)
 		retval |= UMASS_PROTO_ATAPI;
 		break;
 	default:
-		retval = 0;
 		goto done;
 	}
 
@@ -1382,7 +766,6 @@ umass_get_proto(struct usb_interface *iface)
 		retval |= UMASS_PROTO_BBB;
 		break;
 	default:
-		retval = 0;
 		goto done;
 	}
 done:
@@ -1390,78 +773,92 @@ done:
 }
 
 /*
- * Match the device we are seeing with the
- * devices supported.
+ * Match the device we are seeing with the devices supported.
  */
 static struct umass_probe_proto
 umass_probe_proto(device_t dev, struct usb_attach_arg *uaa)
 {
-	const struct umass_devdescr *udd = umass_devdescr;
 	struct umass_probe_proto ret;
+	uint32_t quirks = NO_QUIRKS;
+	uint32_t proto = umass_get_proto(uaa->iface);
 
 	memset(&ret, 0, sizeof(ret));
 
-	/*
-	 * An entry specifically for Y-E Data devices as they don't fit in
-	 * the device description table.
-	 */
-	if ((uaa->info.idVendor == USB_VENDOR_YEDATA) &&
-	    (uaa->info.idProduct == USB_PRODUCT_YEDATA_FLASHBUSTERU)) {
+	/* Search for protocol enforcement */
 
-		/*
-		 * Revisions < 1.28 do not handle the interrupt endpoint
-		 * very well.
-		 */
-		if (uaa->info.bcdDevice < 0x128) {
-			ret.proto = UMASS_PROTO_UFI | UMASS_PROTO_CBI;
-		} else {
-			ret.proto = UMASS_PROTO_UFI | UMASS_PROTO_CBI_I;
-		}
+	if (usb_test_quirk(uaa, UQ_MSC_FORCE_WIRE_BBB)) {
+		proto &= ~UMASS_PROTO_WIRE;
+		proto |= UMASS_PROTO_BBB;
+	} else if (usb_test_quirk(uaa, UQ_MSC_FORCE_WIRE_CBI)) {
+		proto &= ~UMASS_PROTO_WIRE;
+		proto |= UMASS_PROTO_CBI;
+	} else if (usb_test_quirk(uaa, UQ_MSC_FORCE_WIRE_CBI_I)) {
+		proto &= ~UMASS_PROTO_WIRE;
+		proto |= UMASS_PROTO_CBI_I;
+	}
 
-		/*
-		 * Revisions < 1.28 do not have the TEST UNIT READY command
-		 * Revisions == 1.28 have a broken TEST UNIT READY
-		 */
-		if (uaa->info.bcdDevice <= 0x128) {
-			ret.quirks |= NO_TEST_UNIT_READY;
-		}
-		ret.quirks |= RS_NO_CLEAR_UA | FLOPPY_SPEED;
+	if (usb_test_quirk(uaa, UQ_MSC_FORCE_PROTO_SCSI)) {
+		proto &= ~UMASS_PROTO_COMMAND;
+		proto |= UMASS_PROTO_SCSI;
+	} else if (usb_test_quirk(uaa, UQ_MSC_FORCE_PROTO_ATAPI)) {
+		proto &= ~UMASS_PROTO_COMMAND;
+		proto |= UMASS_PROTO_ATAPI;
+	} else if (usb_test_quirk(uaa, UQ_MSC_FORCE_PROTO_UFI)) {
+		proto &= ~UMASS_PROTO_COMMAND;
+		proto |= UMASS_PROTO_UFI;
+	} else if (usb_test_quirk(uaa, UQ_MSC_FORCE_PROTO_RBC)) {
+		proto &= ~UMASS_PROTO_COMMAND;
+		proto |= UMASS_PROTO_RBC;
+	}
+
+	/* Check if the protocol is invalid */
+
+	if ((proto & UMASS_PROTO_COMMAND) == 0) {
+		ret.error = ENXIO;
 		goto done;
 	}
-	/*
-	 * Check the list of supported devices for a match. While looking,
-	 * check for wildcarded and fully matched. First match wins.
-	 */
-	for (; udd->vid != VID_EOT; udd++) {
-		if (((udd->vid == uaa->info.idVendor) ||
-		    (udd->vid == VID_WILDCARD)) &&
-		    ((udd->pid == uaa->info.idProduct) ||
-		    (udd->pid == PID_WILDCARD))) {
-			if (udd->rid == RID_WILDCARD) {
-				ret.proto = udd->proto;
-				ret.quirks = udd->quirks;
-				if (ret.proto == UMASS_PROTO_DEFAULT)
-					goto default_proto;
-				else
-					goto done;
-			} else if (udd->rid == uaa->info.bcdDevice) {
-				ret.proto = udd->proto;
-				ret.quirks = udd->quirks;
-				if (ret.proto == UMASS_PROTO_DEFAULT)
-					goto default_proto;
-				else
-					goto done;
-			}		/* else RID does not match */
-		}
+
+	if ((proto & UMASS_PROTO_WIRE) == 0) {
+		ret.error = ENXIO;
+		goto done;
 	}
 
-default_proto:
-	ret.proto = umass_get_proto(uaa->iface);
-	if (ret.proto == 0)
-		ret.error = ENXIO;
-	else
-		ret.error = 0;
+	/* Search for quirks */
+
+	if (usb_test_quirk(uaa, UQ_MSC_NO_TEST_UNIT_READY))
+		quirks |= NO_TEST_UNIT_READY;
+	if (usb_test_quirk(uaa, UQ_MSC_NO_RS_CLEAR_UA))
+		quirks |= RS_NO_CLEAR_UA;
+	if (usb_test_quirk(uaa, UQ_MSC_NO_START_STOP))
+		quirks |= NO_START_STOP;
+	if (usb_test_quirk(uaa, UQ_MSC_NO_GETMAXLUN))
+		quirks |= NO_GETMAXLUN;
+	if (usb_test_quirk(uaa, UQ_MSC_NO_INQUIRY))
+		quirks |= NO_INQUIRY;
+	if (usb_test_quirk(uaa, UQ_MSC_NO_INQUIRY_EVPD))
+		quirks |= NO_INQUIRY_EVPD;
+	if (usb_test_quirk(uaa, UQ_MSC_NO_SYNC_CACHE))
+		quirks |= NO_SYNCHRONIZE_CACHE;
+	if (usb_test_quirk(uaa, UQ_MSC_SHUTTLE_INIT))
+		quirks |= SHUTTLE_INIT;
+	if (usb_test_quirk(uaa, UQ_MSC_ALT_IFACE_1))
+		quirks |= ALT_IFACE_1;
+	if (usb_test_quirk(uaa, UQ_MSC_FLOPPY_SPEED))
+		quirks |= FLOPPY_SPEED;
+	if (usb_test_quirk(uaa, UQ_MSC_IGNORE_RESIDUE))
+		quirks |= IGNORE_RESIDUE;
+	if (usb_test_quirk(uaa, UQ_MSC_WRONG_CSWSIG))
+		quirks |= WRONG_CSWSIG;
+	if (usb_test_quirk(uaa, UQ_MSC_RBC_PAD_TO_12))
+		quirks |= RBC_PAD_TO_12;
+	if (usb_test_quirk(uaa, UQ_MSC_READ_CAP_OFFBY1))
+		quirks |= READ_CAPACITY_OFFBY1;
+	if (usb_test_quirk(uaa, UQ_MSC_FORCE_SHORT_INQ))
+		quirks |= FORCE_SHORT_INQUIRY;
+
 done:
+	ret.quirks = quirks;
+	ret.proto = proto;
 	return (ret);
 }
 

From 4ab13ae19c39c384792dfed17633c0d0be128872 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:19:52 +0000
Subject: [PATCH 0988/2592] MFC r200887

 Shorten the USB_QUIRK_ENTRY macro and undef it at the end, its only internal.
---
 sys/dev/usb/quirk/usb_quirk.c | 473 +++++++++++++++++-----------------
 1 file changed, 235 insertions(+), 238 deletions(-)

diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index e2a0c778b15..0a6dca3558b 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -60,12 +60,6 @@
 MODULE_DEPEND(usb_quirk, usb, 1, 1, 1);
 MODULE_VERSION(usb_quirk, 1);
 
-/*
- * The following macro adds one or more quirks for a USB device:
- */
-#define	USB_QUIRK_ENTRY(v,p,l,h,...) \
-  .vid = (v), .pid = (p), .lo_rev = (l), .hi_rev = (h), .quirks = { __VA_ARGS__ }
-
 #define	USB_DEV_QUIRKS_MAX 256
 #define	USB_SUB_QUIRKS_MAX 8
 
@@ -79,496 +73,499 @@ struct usb_quirk_entry {
 
 static struct mtx usb_quirk_mtx;
 
+#define	USB_QUIRK(v,p,l,h,...) \
+  .vid = (v), .pid = (p), .lo_rev = (l), .hi_rev = (h), .quirks = { __VA_ARGS__ }
 static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
-	{USB_QUIRK_ENTRY(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_LCM,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4,
-	    0x094, 0x094, UQ_SWAP_UNICODE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502,
-	    0x0a2, 0x0a2, UQ_BAD_ADC, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502,
-	    0x0a2, 0x0a2, UQ_AU_NO_XU, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70,
-	    0x103, 0x103, UQ_BAD_ADC, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495,
-	    0x000, 0x000, UQ_BAD_AUDIO, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N,
-	    0x110, 0x110, UQ_SPUR_BUT_UP, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB,
-	    0x001, 0x001, UQ_SPUR_BUT_UP, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100,
-	    0x102, 0x102, UQ_BUS_POWERED, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232,
-	    0x102, 0x102, UQ_BUS_POWERED, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41,
-	    0x110, 0x110, UQ_POWER_CLAIM, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1,
-	    0x009, 0x009, UQ_AU_NO_FRAC, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SILICONPORTALS,
+	{USB_QUIRK(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_LCM,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4,
+	    0x094, 0x094, UQ_SWAP_UNICODE)},
+	{USB_QUIRK(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502,
+	    0x0a2, 0x0a2, UQ_BAD_ADC)},
+	{USB_QUIRK(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502,
+	    0x0a2, 0x0a2, UQ_AU_NO_XU)},
+	{USB_QUIRK(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70,
+	    0x103, 0x103, UQ_BAD_ADC)},
+	{USB_QUIRK(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495,
+	    0x000, 0x000, UQ_BAD_AUDIO)},
+	{USB_QUIRK(USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N,
+	    0x110, 0x110, UQ_SPUR_BUT_UP)},
+	{USB_QUIRK(USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB,
+	    0x001, 0x001, UQ_SPUR_BUT_UP)},
+	{USB_QUIRK(USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100,
+	    0x102, 0x102, UQ_BUS_POWERED)},
+	{USB_QUIRK(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232,
+	    0x102, 0x102, UQ_BUS_POWERED)},
+	{USB_QUIRK(USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41,
+	    0x110, 0x110, UQ_POWER_CLAIM)},
+	{USB_QUIRK(USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1,
+	    0x009, 0x009, UQ_AU_NO_FRAC)},
+	{USB_QUIRK(USB_VENDOR_SILICONPORTALS,
 	    USB_PRODUCT_SILICONPORTALS_YAPPHONE,
-	    0x100, 0x100, UQ_AU_INP_ASYNC, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B,
-	    0x0000, 0xFFFF, UQ_NO_STRINGS, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1,
-	    0x0000, 0xFFFF, UQ_CFG_INDEX_1, UQ_NONE)},
+	    0x100, 0x100, UQ_AU_INP_ASYNC)},
+	{USB_QUIRK(USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B,
+	    0x0000, 0xFFFF, UQ_NO_STRINGS)},
+	{USB_QUIRK(USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1,
+	    0x0000, 0xFFFF, UQ_CFG_INDEX_1)},
 
 	/*
 	 * XXX The following quirks should have a more specific revision
 	 * number:
 	 */
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_895C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_880C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_815C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_810C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_830C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_1220C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_XEROX, USB_PRODUCT_XEROX_WCM15,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
+	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_895C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
+	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_880C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
+	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_815C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
+	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_810C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
+	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_830C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
+	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_1220C,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
+	{USB_QUIRK(USB_VENDOR_XEROX, USB_PRODUCT_XEROX_WCM15,
+	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
 	/* Devices which should be ignored by uhid */
-	{USB_QUIRK_ENTRY(USB_VENDOR_APC, USB_PRODUCT_APC_UPS,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_CYBERPOWER,
+	{USB_QUIRK(USB_VENDOR_APC, USB_PRODUCT_APC_UPS,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_CYBERPOWER,
 	    USB_PRODUCT_CYBERPOWER_1500CAVRLCD,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD2X20,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD4X20,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD2X20,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD4X20,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G,
+	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
 	/* Devices which should be ignored by both ukbd and uhid */
-	{USB_QUIRK_ENTRY(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_WISPY1A,
-	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY1B,
-	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TENX, USB_PRODUCT_TENX_UAUDIO0,
-	    0x0101, 0x0101, UQ_AUDIO_SWAP_LR, UQ_NONE)},
+	{USB_QUIRK(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_WISPY1A,
+	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY1B,
+	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE)},
+	{USB_QUIRK(USB_VENDOR_TENX, USB_PRODUCT_TENX_UAUDIO0,
+	    0x0101, 0x0101, UQ_AUDIO_SWAP_LR)},
 	/* MS keyboards do weird things */
-	{USB_QUIRK_ENTRY(USB_VENDOR_MICROSOFT,
+	{USB_QUIRK(USB_VENDOR_MICROSOFT,
 	    USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE,
-	    0x0000, 0xFFFF, UQ_MS_LEADING_BYTE, UQ_NONE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X,
-	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
+	    0x0000, 0xFFFF, UQ_MS_LEADING_BYTE)},
+	{USB_QUIRK(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X,
+	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE)},
 	/* umodem(4) device quirks */
-	{USB_QUIRK_ENTRY(USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS,
+	{USB_QUIRK(USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS,
 	    0x100, 0x100, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SANYO, USB_PRODUCT_SANYO_SCP4900,
+	{USB_QUIRK(USB_VENDOR_SANYO, USB_PRODUCT_SANYO_SCP4900,
 	    0x000, 0x000, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_T720C,
+	{USB_QUIRK(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_T720C,
 	    0x001, 0x001, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_EICON, USB_PRODUCT_EICON_DIVA852,
+	{USB_QUIRK(USB_VENDOR_EICON, USB_PRODUCT_EICON_DIVA852,
 	    0x100, 0x100, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_ES75,
+	{USB_QUIRK(USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_ES75,
 	    0x000, 0x000, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_CDMA_MSM,
+	{USB_QUIRK(USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_CDMA_MSM,
 	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_CDMA_MSM,
+	{USB_QUIRK(USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_CDMA_MSM,
 	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_UM175,
+	{USB_QUIRK(USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_UM175,
 	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
 
 	/* USB Mass Storage Class Quirks */
-	{USB_QUIRK_ENTRY(USB_VENDOR_ASAHIOPTICAL, 0,
+	{USB_QUIRK(USB_VENDOR_ASAHIOPTICAL, 0,
 	    0x0000, 0xFFFF, UQ_MSC_NO_RS_CLEAR_UA, UQ_MATCH_VENDOR_ONLY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_ATTACHE, 0x0000,
+	{USB_QUIRK(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_ATTACHE, 0x0000,
 	    0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_A256MB,
+	{USB_QUIRK(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_A256MB,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_DISKPRO512,
+	{USB_QUIRK(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_DISKPRO512,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_CABLE_205,
+	{USB_QUIRK(USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_CABLE_205,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_AIPTEK, USB_PRODUCT_AIPTEK_POCKETCAM3M,
+	{USB_QUIRK(USB_VENDOR_AIPTEK, USB_PRODUCT_AIPTEK_POCKETCAM3M,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_AIPTEK2, USB_PRODUCT_AIPTEK2_SUNPLUS_TECH,
+	{USB_QUIRK(USB_VENDOR_AIPTEK2, USB_PRODUCT_AIPTEK2_SUNPLUS_TECH,
 	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_SDCR_6335,
+	{USB_QUIRK(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_SDCR_6335,
 	    0x0000, 0xFFFF, UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU6390,
+	{USB_QUIRK(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU6390,
 	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_UMCR_9361,
+	{USB_QUIRK(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_UMCR_9361,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_TRANSCEND,
+	{USB_QUIRK(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_TRANSCEND,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230,
+	{USB_QUIRK(USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO330,
+	{USB_QUIRK(USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO330,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2SCSI,
+	{USB_QUIRK(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2SCSI,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV_DIGICAM,
+	{USB_QUIRK(USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV_DIGICAM,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_CCYU, USB_PRODUCT_CCYU_ED1064,
+	{USB_QUIRK(USB_VENDOR_CCYU, USB_PRODUCT_CCYU_ED1064,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_CENTURY, USB_PRODUCT_CENTURY_EX35QUAT,
+	{USB_QUIRK(USB_VENDOR_CENTURY, USB_PRODUCT_CENTURY_EX35QUAT,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_XX6830XX,
+	{USB_QUIRK(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_XX6830XX,
 	    0x0000, 0xFFFF, UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_DESKNOTE, USB_PRODUCT_DESKNOTE_UCR_61S2B,
+	{USB_QUIRK(USB_VENDOR_DESKNOTE, USB_PRODUCT_DESKNOTE_UCR_61S2B,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_DMI, USB_PRODUCT_DMI_CFSM_RW,
+	{USB_QUIRK(USB_VENDOR_DMI, USB_PRODUCT_DMI_CFSM_RW,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_875DC,
+	{USB_QUIRK(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_875DC,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_895,
+	{USB_QUIRK(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_895,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_FEIYA, USB_PRODUCT_FEIYA_5IN1,
+	{USB_QUIRK(USB_VENDOR_FEIYA, USB_PRODUCT_FEIYA_5IN1,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD,
+	{USB_QUIRK(USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100,
+	{USB_QUIRK(USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_RS_CLEAR_UA)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE,
+	{USB_QUIRK(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE,
 	    UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE_2,
+	{USB_QUIRK(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE_2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB,
+	{USB_QUIRK(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB_2,
+	{USB_QUIRK(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB_2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_WRONG_CSWSIG)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG,
+	{USB_QUIRK(USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM,
+	{USB_QUIRK(USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_DZ_MV100A,
+	{USB_QUIRK(USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_DZ_MV100A,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB,
+	{USB_QUIRK(USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_CDW4E,
+	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_CDW4E,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200,
+	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_IMAGINATION, USB_PRODUCT_IMAGINATION_DBX1,
+	{USB_QUIRK(USB_VENDOR_IMAGINATION, USB_PRODUCT_IMAGINATION_DBX1,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_WRONG_CSWSIG)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE,
+	{USB_QUIRK(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP, UQ_MSC_ALT_IFACE_1)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI,
+	{USB_QUIRK(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_STORAGE_V2,
+	{USB_QUIRK(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_STORAGE_V2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_IU_CD2,
+	{USB_QUIRK(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_IU_CD2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_DVR_UEH8,
+	{USB_QUIRK(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_DVR_UEH8,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100,
+	{USB_QUIRK(USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_TEST_UNIT_READY)}, /* XXX ZIP drives can also use ATAPI */
-	{USB_QUIRK_ENTRY(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_L3,
+	{USB_QUIRK(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_L3,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S3X,
+	{USB_QUIRK(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S3X,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S4,
+	{USB_QUIRK(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S4,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S5,
+	{USB_QUIRK(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S5,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_LACIE, USB_PRODUCT_LACIE_HD,
+	{USB_QUIRK(USB_VENDOR_LACIE, USB_PRODUCT_LACIE_HD,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_CF_READER,
+	{USB_QUIRK(USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_CF_READER,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPSHOT,
+	{USB_QUIRK(USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPSHOT,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443SU2,
+	{USB_QUIRK(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443SU2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443U2,
+	{USB_QUIRK(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443U2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG,
+	{USB_QUIRK(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM,
+	{USB_QUIRK(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25,
+	{USB_QUIRK(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIHD50,
+	{USB_QUIRK(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIHD50,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_E223,
+	{USB_QUIRK(USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_E223,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_F300,
+	{USB_QUIRK(USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_F300,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW,
+	{USB_QUIRK(USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI | UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_FDD,
+	{USB_QUIRK(USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_FDD,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_E398,
+	{USB_QUIRK(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_E398,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_INQUIRY_EVPD, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MPMAN, 0,
+	{USB_QUIRK(USB_VENDOR_MPMAN, 0,
 	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY,
+	{USB_QUIRK(USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_RS_CLEAR_UA)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2,
+	{USB_QUIRK(USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN,
+	{USB_QUIRK(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN,
 	    0x0000, 0xFFFF, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN_8813,
+	{USB_QUIRK(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN_8813,
 	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_STARREADER,
+	{USB_QUIRK(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_STARREADER,
 	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260,
+	{USB_QUIRK(USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_FORCE_SHORT_INQ)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_NETAC, USB_PRODUCT_NETAC_CF_CARD,
+	{USB_QUIRK(USB_VENDOR_NETAC, USB_PRODUCT_NETAC_CF_CARD,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_NETAC, USB_PRODUCT_NETAC_ONLYDISK,
+	{USB_QUIRK(USB_VENDOR_NETAC, USB_PRODUCT_NETAC_ONLYDISK,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK_40,
+	{USB_QUIRK(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK_40,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_NIKON, USB_PRODUCT_NIKON_D300,
+	{USB_QUIRK(USB_VENDOR_NIKON, USB_PRODUCT_NIKON_D300,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1,
+	{USB_QUIRK(USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_WRONG_CSWSIG)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700,
+	{USB_QUIRK(USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700,
 	    0x0000, 0xFFFF, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D,
+	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW,
+	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_COMBO,
+	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_COMBO,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER,
+	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER2,
+	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFE_B_CF_READER,
+	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFE_B_CF_READER,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDSM_B_READER,
+	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDSM_B_READER,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_READER,
+	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_READER,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_UCF100,
+	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_UCF100,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_INQUIRY | UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ONSPEC2, USB_PRODUCT_ONSPEC2_IMAGEMATE_SDDR55,
+	{USB_QUIRK(USB_VENDOR_ONSPEC2, USB_PRODUCT_ONSPEC2_IMAGEMATE_SDDR55,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXL840AN,
+	{USB_QUIRK(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXL840AN,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB20AN,
+	{USB_QUIRK(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB20AN,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB35AN,
+	{USB_QUIRK(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB35AN,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_LS120CAM,
+	{USB_QUIRK(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_LS120CAM,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_UFI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SPE3030CC,
+	{USB_QUIRK(USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SPE3030CC,
 	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U,
+	{USB_QUIRK(USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_TEST_UNIT_READY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_PNY, USB_PRODUCT_PNY_ATTACHE2,
+	{USB_QUIRK(USB_VENDOR_PNY, USB_PRODUCT_PNY_ATTACHE2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_START_STOP)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SAMSUNG_TECHWIN, USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410,
+	{USB_QUIRK(USB_VENDOR_SAMSUNG_TECHWIN, USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A,
+	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_READ_CAP_OFFBY1, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09,
+	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12,
+	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_READ_CAP_OFFBY1, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256,
+	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_128,
+	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_128,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_256,
+	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_256,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31,
+	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_READ_CAP_OFFBY1)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R,
+	{USB_QUIRK(USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB,
+	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP, UQ_MSC_SHUTTLE_INIT)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW,
+	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF,
+	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI,
+	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBCFSM,
+	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBCFSM,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI,
+	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD,
+	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09,
+	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC,
+	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100,
+	{USB_QUIRK(USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_SHUTTLE_INIT)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SIIG, USB_PRODUCT_SIIG_WINTERREADER,
+	{USB_QUIRK(USB_VENDOR_SIIG, USB_PRODUCT_SIIG_WINTERREADER,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_MD_7425,
+	{USB_QUIRK(USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_MD_7425,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_SX_520Z,
+	{USB_QUIRK(USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_SX_520Z,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM,
 	    0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC,
 	    UQ_MSC_RBC_PAD_TO_12)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
 	    0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC,
 	    UQ_MSC_RBC_PAD_TO_12)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
 	    0x0600, 0x0600, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC,
 	    UQ_MSC_RBC_PAD_TO_12)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_MSC_U03,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_MSC_U03,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_NW_MS7,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_NW_MS7,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_PEG_N760C,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_PEG_N760C,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SONY, USB_PRODUCT_SONY_PORTABLE_HDD_V2,
+	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_PORTABLE_HDD_V2,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDE,
+	{USB_QUIRK(USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDE,
 	    0x0000, 0xFFFF, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE,
+	{USB_QUIRK(USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB,
+	{USB_QUIRK(USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TECLAST, USB_PRODUCT_TECLAST_TLC300,
+	{USB_QUIRK(USB_VENDOR_TECLAST, USB_PRODUCT_TECLAST_TLC300,
 	    0x0000, 0xFFFF, UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TREK, USB_PRODUCT_TREK_MEMKEY,
+	{USB_QUIRK(USB_VENDOR_TREK, USB_PRODUCT_TREK_MEMKEY,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB,
+	{USB_QUIRK(USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_C3310,
+	{USB_QUIRK(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_C3310,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_MP3,
+	{USB_QUIRK(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_MP3,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_T33520,
+	{USB_QUIRK(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_T33520,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_MDIV,
+	{USB_QUIRK(USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_MDIV,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_VIA, USB_PRODUCT_VIA_USB2IDEBRIDGE,
+	{USB_QUIRK(USB_VENDOR_VIA, USB_PRODUCT_VIA_USB2IDEBRIDGE,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_VIVITAR, USB_PRODUCT_VIVITAR_35XX,
+	{USB_QUIRK(USB_VENDOR_VIVITAR, USB_PRODUCT_VIVITAR_35XX,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO,
+	{USB_QUIRK(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_EXTHDD,
+	{USB_QUIRK(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_EXTHDD,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYBOOK,
+	{USB_QUIRK(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYBOOK,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY_EVPD)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSWORD,
+	{USB_QUIRK(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSWORD,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_SHORT_INQ)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_WINMAXGROUP, USB_PRODUCT_WINMAXGROUP_FLASH64MC,
+	{USB_QUIRK(USB_VENDOR_WINMAXGROUP, USB_PRODUCT_WINMAXGROUP_FLASH64MC,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_YANO, USB_PRODUCT_YANO_FW800HD,
+	{USB_QUIRK(USB_VENDOR_YANO, USB_PRODUCT_YANO_FW800HD,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO,
+	{USB_QUIRK(USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_FORCE_SHORT_INQ)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
+	{USB_QUIRK(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
 	    0x0000, 0x007F, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI,
 	    UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED,
 	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
+	{USB_QUIRK(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
 	    0x0080, 0x0080, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_UFI,
 	    UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED,
 	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
+	{USB_QUIRK(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
 	    0x0081, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_UFI,
 	    UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ZORAN, USB_PRODUCT_ZORAN_EX20DSC,
+	{USB_QUIRK(USB_VENDOR_ZORAN, USB_PRODUCT_ZORAN_EX20DSC,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL,
+	{USB_QUIRK(USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_INQUIRY, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ACTIONS, USB_PRODUCT_ACTIONS_MP4,
+	{USB_QUIRK(USB_VENDOR_ACTIONS, USB_PRODUCT_ACTIONS_MP4,
 	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK_ENTRY(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_GMSC,
+	{USB_QUIRK(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_GMSC,
 	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
 };
+#undef USB_QUIRK
 
 static const char *usb_quirk_str[USB_QUIRK_MAX] = {
 	[UQ_NONE]		= "UQ_NONE",

From dc72f7b46cae58c2bdd8663aa109c5f022da3f82 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:20:54 +0000
Subject: [PATCH 0989/2592] MFC r201028

 Use macros to strip off USB_VENDOR_ and USB_PRODUCT_ from some id tables to make
 them more compact and readable.
---
 sys/dev/usb/net/if_aue.c    | 138 ++++++++++++++++++------------------
 sys/dev/usb/net/if_axe.c    |  54 +++++++-------
 sys/dev/usb/net/if_cue.c    |   8 ++-
 sys/dev/usb/net/if_kue.c    |  69 +++++++++---------
 sys/dev/usb/serial/uftdi.c  |  77 ++++++++++----------
 sys/dev/usb/serial/uplcom.c |  54 +++++++-------
 sys/dev/usb/serial/uslcom.c |  38 +++++-----
 sys/dev/usb/serial/uvisor.c |  54 +++++++-------
 sys/dev/usb/usbdevs         |   1 +
 sys/dev/usb/wlan/if_rum.c   |  98 ++++++++++++-------------
 sys/dev/usb/wlan/if_ural.c  |  60 ++++++++--------
 11 files changed, 335 insertions(+), 316 deletions(-)

diff --git a/sys/dev/usb/net/if_aue.c b/sys/dev/usb/net/if_aue.c
index 44b0145aa21..b508474e468 100644
--- a/sys/dev/usb/net/if_aue.c
+++ b/sys/dev/usb/net/if_aue.c
@@ -112,74 +112,76 @@ SYSCTL_INT(_hw_usb_aue, OID_AUTO, debug, CTLFLAG_RW, &aue_debug, 0,
  * Various supported device vendors/products.
  */
 static const struct usb_device_id aue_devs[] = {
-    {USB_VPI(USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA, 0)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000, AUE_FLAG_LSYS)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10, 0)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1, AUE_FLAG_PNA | AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4, AUE_FLAG_PNA)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5, AUE_FLAG_PNA)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9, AUE_FLAG_PNA)},
-    {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC, 0)},
-    {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_4, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS, AUE_FLAG_PNA | AUE_FLAG_DUAL_PHY)},
-    {USB_VPI(USB_VENDOR_AEI, USB_PRODUCT_AEI_FASTETHERNET, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_ATUSB100, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC110T, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2LAN, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100, 0)},
-    {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBE100, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBEL100, 0)},
-    {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100, AUE_FLAG_PNA)},
-    {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXS, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX, 0)},
-    {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX1, AUE_FLAG_LSYS)},
-    {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2, AUE_FLAG_LSYS | AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3, AUE_FLAG_LSYS | AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4, AUE_FLAG_LSYS | AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA, AUE_FLAG_PNA)},
-    {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX, AUE_FLAG_LSYS)},
-    {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650, AUE_FLAG_LSYS)},
-    {USB_VPI(USB_VENDOR_ELCON, USB_PRODUCT_ELCON_PLAN, AUE_FLAG_PNA | AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSB20, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0, 0)},
-    {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1, AUE_FLAG_LSYS)},
-    {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2, 0)},
-    {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3, AUE_FLAG_LSYS)},
-    {USB_VPI(USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET, 0)},
-    {USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNBR402W, 0)},
-    {USB_VPI(USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_HN210E, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTXS, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX, 0)},
-    {USB_VPI(USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_KNU101TX, 0)},
-    {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1, AUE_FLAG_LSYS | AUE_FLAG_PNA)},
-    {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX, AUE_FLAG_LSYS)},
-    {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA, AUE_FLAG_LSYS)},
-    {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX1, AUE_FLAG_LSYS | AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2, AUE_FLAG_LSYS | AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T, AUE_FLAG_LSYS)},
-    {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1, 0)},
-    {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5, 0)},
-    {USB_VPI(USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_SIIG2, USB_PRODUCT_SIIG2_USBTOETHER, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB, 0)},
-    {USB_VPI(USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB, AUE_FLAG_PII)},
-    {USB_VPI(USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100, 0)},
-    {USB_VPI(USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB110, AUE_FLAG_PII)},
+#define	AUE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+    AUE_DEV(3COM, 3C460B, AUE_FLAG_PII),
+    AUE_DEV(ABOCOM, DSB650TX_PNA, 0),
+    AUE_DEV(ABOCOM, UFE1000, AUE_FLAG_LSYS),
+    AUE_DEV(ABOCOM, XX10, 0),
+    AUE_DEV(ABOCOM, XX1, AUE_FLAG_PNA | AUE_FLAG_PII),
+    AUE_DEV(ABOCOM, XX2, AUE_FLAG_PII),
+    AUE_DEV(ABOCOM, XX4, AUE_FLAG_PNA),
+    AUE_DEV(ABOCOM, XX5, AUE_FLAG_PNA),
+    AUE_DEV(ABOCOM, XX6, AUE_FLAG_PII),
+    AUE_DEV(ABOCOM, XX7, AUE_FLAG_PII),
+    AUE_DEV(ABOCOM, XX8, AUE_FLAG_PII),
+    AUE_DEV(ABOCOM, XX9, AUE_FLAG_PNA),
+    AUE_DEV(ACCTON, SS1001, AUE_FLAG_PII),
+    AUE_DEV(ACCTON, USB320_EC, 0),
+    AUE_DEV(ADMTEK, PEGASUSII_2, AUE_FLAG_PII),
+    AUE_DEV(ADMTEK, PEGASUSII_3, AUE_FLAG_PII),
+    AUE_DEV(ADMTEK, PEGASUSII_4, AUE_FLAG_PII),
+    AUE_DEV(ADMTEK, PEGASUSII, AUE_FLAG_PII),
+    AUE_DEV(ADMTEK, PEGASUS, AUE_FLAG_PNA | AUE_FLAG_DUAL_PHY),
+    AUE_DEV(AEI, FASTETHERNET, AUE_FLAG_PII),
+    AUE_DEV(ALLIEDTELESYN, ATUSB100, AUE_FLAG_PII),
+    AUE_DEV(ATEN, UC110T, AUE_FLAG_PII),
+    AUE_DEV(BELKIN, USB2LAN, AUE_FLAG_PII),
+    AUE_DEV(BILLIONTON, USB100, 0),
+    AUE_DEV(BILLIONTON, USBE100, AUE_FLAG_PII),
+    AUE_DEV(BILLIONTON, USBEL100, 0),
+    AUE_DEV(BILLIONTON, USBLP100, AUE_FLAG_PNA),
+    AUE_DEV(COREGA, FETHER_USB_TXS, AUE_FLAG_PII),
+    AUE_DEV(COREGA, FETHER_USB_TX, 0),
+    AUE_DEV(DLINK, DSB650TX1, AUE_FLAG_LSYS),
+    AUE_DEV(DLINK, DSB650TX2, AUE_FLAG_LSYS | AUE_FLAG_PII),
+    AUE_DEV(DLINK, DSB650TX3, AUE_FLAG_LSYS | AUE_FLAG_PII),
+    AUE_DEV(DLINK, DSB650TX4, AUE_FLAG_LSYS | AUE_FLAG_PII),
+    AUE_DEV(DLINK, DSB650TX_PNA, AUE_FLAG_PNA),
+    AUE_DEV(DLINK, DSB650TX, AUE_FLAG_LSYS),
+    AUE_DEV(DLINK, DSB650, AUE_FLAG_LSYS),
+    AUE_DEV(ELCON, PLAN, AUE_FLAG_PNA | AUE_FLAG_PII),
+    AUE_DEV(ELECOM, LDUSB20, AUE_FLAG_PII),
+    AUE_DEV(ELECOM, LDUSBLTX, AUE_FLAG_PII),
+    AUE_DEV(ELECOM, LDUSBTX0, 0),
+    AUE_DEV(ELECOM, LDUSBTX1, AUE_FLAG_LSYS),
+    AUE_DEV(ELECOM, LDUSBTX2, 0),
+    AUE_DEV(ELECOM, LDUSBTX3, AUE_FLAG_LSYS),
+    AUE_DEV(ELSA, USB2ETHERNET, 0),
+    AUE_DEV(GIGABYTE, GNBR402W, 0),
+    AUE_DEV(HAWKING, UF100, AUE_FLAG_PII),
+    AUE_DEV(HP, HN210E, AUE_FLAG_PII),
+    AUE_DEV(IODATA, USBETTXS, AUE_FLAG_PII),
+    AUE_DEV(IODATA, USBETTX, 0),
+    AUE_DEV(KINGSTON, KNU101TX, 0),
+    AUE_DEV(LINKSYS, USB100H1, AUE_FLAG_LSYS | AUE_FLAG_PNA),
+    AUE_DEV(LINKSYS, USB100TX, AUE_FLAG_LSYS),
+    AUE_DEV(LINKSYS, USB10TA, AUE_FLAG_LSYS),
+    AUE_DEV(LINKSYS, USB10TX1, AUE_FLAG_LSYS | AUE_FLAG_PII),
+    AUE_DEV(LINKSYS, USB10TX2, AUE_FLAG_LSYS | AUE_FLAG_PII),
+    AUE_DEV(LINKSYS, USB10T, AUE_FLAG_LSYS),
+    AUE_DEV(MELCO, LUA2TX5, AUE_FLAG_PII),
+    AUE_DEV(MELCO, LUATX1, 0),
+    AUE_DEV(MELCO, LUATX5, 0),
+    AUE_DEV(MICROSOFT, MN110, AUE_FLAG_PII),
+    AUE_DEV(NETGEAR, FA101, AUE_FLAG_PII),
+    AUE_DEV(SIEMENS, SPEEDSTREAM, AUE_FLAG_PII),
+    AUE_DEV(SIIG2, USBTOETHER, AUE_FLAG_PII),
+    AUE_DEV(SMARTBRIDGES, SMARTNIC, AUE_FLAG_PII),
+    AUE_DEV(SMC, 2202USB, 0),
+    AUE_DEV(SMC, 2206USB, AUE_FLAG_PII),
+    AUE_DEV(SOHOWARE, NUB100, 0),
+    AUE_DEV(SOHOWARE, NUB110, AUE_FLAG_PII),
+#undef AUE_DEV
 };
 
 /* prototypes */
diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c
index a5cffe5eba0..9772f401b68 100644
--- a/sys/dev/usb/net/if_axe.c
+++ b/sys/dev/usb/net/if_axe.c
@@ -135,32 +135,34 @@ SYSCTL_INT(_hw_usb_axe, OID_AUTO, debug, CTLFLAG_RW, &axe_debug, 0,
  * Various supported device vendors/products.
  */
 static const struct usb_device_id axe_devs[] = {
-	{USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200, 0)},
-	{USB_VPI(USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2, 0)},
-	{USB_VPI(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET, AXE_FLAG_772)},
-	{USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172, 0)},
-	{USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178, AXE_FLAG_178)},
-	{USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772, AXE_FLAG_772)},
-	{USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772A, AXE_FLAG_772)},
-	{USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T, 0)},
-	{USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055, AXE_FLAG_178)},
-	{USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR, 0)},
-	{USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2, AXE_FLAG_772)},
-	{USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX, 0)},
-	{USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100, 0)},
-	{USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1, AXE_FLAG_772)},
-	{USB_VPI(USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E, 0)},
-	{USB_VPI(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2, AXE_FLAG_178)},
-	{USB_VPI(USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1, 0)},
-	{USB_VPI(USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M, 0)},
-	{USB_VPI(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000, AXE_FLAG_178)},
-	{USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX, 0)},
-	{USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120, 0)},
-	{USB_VPI(USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS, AXE_FLAG_772)},
-	{USB_VPI(USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T, AXE_FLAG_178)},
-	{USB_VPI(USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029, 0)},
-	{USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028, AXE_FLAG_178)},
-	{USB_VPI(USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL, 0)},
+#define	AXE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+	AXE_DEV(ABOCOM, UF200, 0),
+	AXE_DEV(ACERCM, EP1427X2, 0),
+	AXE_DEV(APPLE, ETHERNET, AXE_FLAG_772),
+	AXE_DEV(ASIX, AX88172, 0),
+	AXE_DEV(ASIX, AX88178, AXE_FLAG_178),
+	AXE_DEV(ASIX, AX88772, AXE_FLAG_772),
+	AXE_DEV(ASIX, AX88772A, AXE_FLAG_772),
+	AXE_DEV(ATEN, UC210T, 0),
+	AXE_DEV(BELKIN, F5D5055, AXE_FLAG_178),
+	AXE_DEV(BILLIONTON, USB2AR, 0),
+	AXE_DEV(CISCOLINKSYS, USB200MV2, AXE_FLAG_772),
+	AXE_DEV(COREGA, FETHER_USB2_TX, 0),
+	AXE_DEV(DLINK, DUBE100, 0),
+	AXE_DEV(DLINK, DUBE100B1, AXE_FLAG_772),
+	AXE_DEV(GOODWAY, GWUSB2E, 0),
+	AXE_DEV(IODATA, ETGUS2, AXE_FLAG_178),
+	AXE_DEV(JVC, MP_PRX1, 0),
+	AXE_DEV(LINKSYS2, USB200M, 0),
+	AXE_DEV(LINKSYS4, USB1000, AXE_FLAG_178),
+	AXE_DEV(MELCO, LUAU2KTX, 0),
+	AXE_DEV(NETGEAR, FA120, 0),
+	AXE_DEV(OQO, ETHER01PLUS, AXE_FLAG_772),
+	AXE_DEV(PLANEX3, GU1000T, AXE_FLAG_178),
+	AXE_DEV(SITECOM, LN029, 0),
+	AXE_DEV(SITECOMEU, LN028, AXE_FLAG_178),
+	AXE_DEV(SYSTEMTALKS, SGCX2UL, 0),
+#undef AXE_DEV
 };
 
 static device_probe_t axe_probe;
diff --git a/sys/dev/usb/net/if_cue.c b/sys/dev/usb/net/if_cue.c
index 6e257d84715..05ff1a54a88 100644
--- a/sys/dev/usb/net/if_cue.c
+++ b/sys/dev/usb/net/if_cue.c
@@ -90,9 +90,11 @@ __FBSDID("$FreeBSD$");
 /* Belkin F5U111 adapter covered by NETMATE entry */
 
 static const struct usb_device_id cue_devs[] = {
-	{USB_VPI(USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE, 0)},
-	{USB_VPI(USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2, 0)},
-	{USB_VPI(USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK, 0)},
+#define	CUE_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
+	CUE_DEV(CATC, NETMATE),
+	CUE_DEV(CATC, NETMATE2),
+	CUE_DEV(SMARTBRIDGES, SMARTLINK),
+#undef CUE_DEV
 };
 
 /* prototypes */
diff --git a/sys/dev/usb/net/if_kue.c b/sys/dev/usb/net/if_kue.c
index 673c8219acb..5d35da40bd5 100644
--- a/sys/dev/usb/net/if_kue.c
+++ b/sys/dev/usb/net/if_kue.c
@@ -102,40 +102,41 @@ __FBSDID("$FreeBSD$");
  * Various supported device vendors/products.
  */
 static const struct usb_device_id kue_devs[] = {
-	{USB_VPI(USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250, 0)},
-	{USB_VPI(USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460, 0)},
-	{USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450, 0)},
-	{USB_VPI(USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT, 0)},
-	{USB_VPI(USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX, 0)},
-	{USB_VPI(USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101, 0)},
-	{USB_VPI(USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA, 0)},
-	{USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C, 0)},
-	{USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T, 0)},
-	{USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T, 0)},
-	{USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C, 0)},
-	{USB_VPI(USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45, 0)},
-	{USB_VPI(USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1, 0)},
-	{USB_VPI(USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2, 0)},
-	{USB_VPI(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT, 0)},
-	{USB_VPI(USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA, 0)},
-	{USB_VPI(USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1, 0)},
-	{USB_VPI(USB_VENDOR_KLSI, USB_PRODUCT_AOX_USB101, 0)},
-	{USB_VPI(USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT, 0)},
-	{USB_VPI(USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN, 0)},
-	{USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T, 0)},
-	{USB_VPI(USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA, 0)},
-	{USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101, 0)},
-	{USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X, 0)},
-	{USB_VPI(USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET, 0)},
-	{USB_VPI(USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2, 0)},
-	{USB_VPI(USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3, 0)},
-	{USB_VPI(USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8, 0)},
-	{USB_VPI(USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9, 0)},
-	{USB_VPI(USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA, 0)},
-	{USB_VPI(USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA, 0)},
-	{USB_VPI(USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_GPE, 0)},
-	{USB_VPI(USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E, 0)},
-	{USB_VPI(USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB, 0)},
+#define	KUE_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
+	KUE_DEV(3COM, 3C19250),
+	KUE_DEV(3COM, 3C460),
+	KUE_DEV(ABOCOM, URE450),
+	KUE_DEV(ADS, UBS10BT),
+	KUE_DEV(ADS, UBS10BTX),
+	KUE_DEV(AOX, USB101),
+	KUE_DEV(ASANTE, EA),
+	KUE_DEV(ATEN, DSB650C),
+	KUE_DEV(ATEN, UC10T),
+	KUE_DEV(COREGA, ETHER_USB_T),
+	KUE_DEV(DLINK, DSB650C),
+	KUE_DEV(ENTREGA, E45),
+	KUE_DEV(ENTREGA, XX1),
+	KUE_DEV(ENTREGA, XX2),
+	KUE_DEV(IODATA, USBETT),
+	KUE_DEV(JATON, EDA),
+	KUE_DEV(KINGSTON, XX1),
+	KUE_DEV(KLSI, DUH3E10BT),
+	KUE_DEV(KLSI, DUH3E10BTN),
+	KUE_DEV(LINKSYS, USB10T),
+	KUE_DEV(MOBILITY, EA),
+	KUE_DEV(NETGEAR, EA101),
+	KUE_DEV(NETGEAR, EA101X),
+	KUE_DEV(PERACOM, ENET),
+	KUE_DEV(PERACOM, ENET2),
+	KUE_DEV(PERACOM, ENET3),
+	KUE_DEV(PORTGEAR, EA8),
+	KUE_DEV(PORTGEAR, EA9),
+	KUE_DEV(PORTSMITH, EEA),
+	KUE_DEV(SHARK, PA),
+	KUE_DEV(SILICOM, GPE),
+	KUE_DEV(SILICOM, U2E),
+	KUE_DEV(SMC, 2102USB),
+#undef KUE_DEV
 };
 
 /* prototypes */
diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
index 44322c7e7a7..e6eca43c57d 100644
--- a/sys/dev/usb/serial/uftdi.c
+++ b/sys/dev/usb/serial/uftdi.c
@@ -216,43 +216,46 @@ MODULE_DEPEND(uftdi, ucom, 1, 1, 1);
 MODULE_DEPEND(uftdi, usb, 1, 1, 1);
 
 static struct usb_device_id uftdi_devs[] = {
-	{USB_VPI(USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_STK541, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_WIRELESSHANDHELDTERMINAL, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U100AX, UFTDI_TYPE_SIO)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232C, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232D, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM4, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SEMC_DSS20, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_631, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_632, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_633, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_634, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_635, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_USBSERIAL, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MX2_3, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MX4_5, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LK202, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LK204, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13M, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13S, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13U, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EISCOU, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_UOPTBR, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EMCU2D, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PCMSFU, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EMCU2H, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MAXSTREAM, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CTI_USB_NANO_485, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CTI_USB_MINI_485, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_SIIG2, USB_PRODUCT_SIIG2_US2308, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_VALUECAN, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_NEOVI, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_BBELECTRONICS, USB_PRODUCT_BBELECTRONICS_USOTL4, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_MARVELL, USB_PRODUCT_MARVELL_SHEEVAPLUG, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_PCOPRS1, UFTDI_TYPE_8U232AM)},
-	{USB_VPI(USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60F, UFTDI_TYPE_8U232AM)},
+#define	UFTDI_DEV(v,p,t) \
+  { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, UFTDI_TYPE_##t) }
+	UFTDI_DEV(ATMEL, STK541, 8U232AM),
+	UFTDI_DEV(DRESDENELEKTRONIK, SENSORTERMINALBOARD, 8U232AM),
+	UFTDI_DEV(DRESDENELEKTRONIK, WIRELESSHANDHELDTERMINAL, 8U232AM),
+	UFTDI_DEV(FTDI, SERIAL_8U100AX, SIO),
+	UFTDI_DEV(FTDI, SERIAL_2232C, 8U232AM),
+	UFTDI_DEV(FTDI, SERIAL_2232D, 8U232AM),
+	UFTDI_DEV(FTDI, SERIAL_8U232AM, 8U232AM),
+	UFTDI_DEV(FTDI, SERIAL_8U232AM4, 8U232AM),
+	UFTDI_DEV(FTDI, SEMC_DSS20, 8U232AM),
+	UFTDI_DEV(FTDI, CFA_631, 8U232AM),
+	UFTDI_DEV(FTDI, CFA_632, 8U232AM),
+	UFTDI_DEV(FTDI, CFA_633, 8U232AM),
+	UFTDI_DEV(FTDI, CFA_634, 8U232AM),
+	UFTDI_DEV(FTDI, CFA_635, 8U232AM),
+	UFTDI_DEV(FTDI, USBSERIAL, 8U232AM),
+	UFTDI_DEV(FTDI, MX2_3, 8U232AM),
+	UFTDI_DEV(FTDI, MX4_5, 8U232AM),
+	UFTDI_DEV(FTDI, LK202, 8U232AM),
+	UFTDI_DEV(FTDI, LK204, 8U232AM),
+	UFTDI_DEV(FTDI, TACTRIX_OPENPORT_13M, 8U232AM),
+	UFTDI_DEV(FTDI, TACTRIX_OPENPORT_13S, 8U232AM),
+	UFTDI_DEV(FTDI, TACTRIX_OPENPORT_13U, 8U232AM),
+	UFTDI_DEV(FTDI, EISCOU, 8U232AM),
+	UFTDI_DEV(FTDI, UOPTBR, 8U232AM),
+	UFTDI_DEV(FTDI, EMCU2D, 8U232AM),
+	UFTDI_DEV(FTDI, PCMSFU, 8U232AM),
+	UFTDI_DEV(FTDI, EMCU2H, 8U232AM),
+	UFTDI_DEV(FTDI, MAXSTREAM, 8U232AM),
+	UFTDI_DEV(FTDI, CTI_USB_NANO_485, 8U232AM),
+	UFTDI_DEV(FTDI, CTI_USB_MINI_485, 8U232AM),
+	UFTDI_DEV(SIIG2, US2308, 8U232AM),
+	UFTDI_DEV(INTREPIDCS, VALUECAN, 8U232AM),
+	UFTDI_DEV(INTREPIDCS, NEOVI, 8U232AM),
+	UFTDI_DEV(BBELECTRONICS, USOTL4, 8U232AM),
+	UFTDI_DEV(MARVELL, SHEEVAPLUG, 8U232AM),
+	UFTDI_DEV(MELCO, PCOPRS1, 8U232AM),
+	UFTDI_DEV(RATOC, REXUSB60F, 8U232AM),
+#undef UFTDI_DEV
 };
 
 static int
diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c
index ef5db403358..c5d58e46dcb 100644
--- a/sys/dev/usb/serial/uplcom.c
+++ b/sys/dev/usb/serial/uplcom.c
@@ -243,57 +243,57 @@ static struct ucom_callback uplcom_callback = {
 	.ucom_poll = &uplcom_poll,
 };
 
-#define	USB_UPL(v,p,rl,rh,t)				\
-  USB_VENDOR(v), USB_PRODUCT(p), USB_DEV_BCD_GTEQ(rl),	\
-  USB_DEV_BCD_LTEQ(rh), USB_DRIVER_INFO(t)
+#define	UPLCOM_DEV(v,p,rl,rh,t)				\
+  { USB_VENDOR(USB_VENDOR_##v), USB_PRODUCT(USB_PRODUCT_##v##_##p), \
+    USB_DEV_BCD_GTEQ(rl), USB_DEV_BCD_LTEQ(rh), USB_DRIVER_INFO(TYPE_##t) }
 
 static const struct usb_device_id uplcom_devs[] = {
 	/* Belkin F5U257 */
-	{USB_UPL(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U257, 0, 0xFFFF, TYPE_PL2303X)},
+	UPLCOM_DEV(BELKIN, F5U257, 0, 0xFFFF, PL2303X),
 	/* I/O DATA USB-RSAQ */
-	{USB_UPL(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(IODATA, USBRSAQ, 0, 0xFFFF, PL2303),
 	/* I/O DATA USB-RSAQ2 */
-	{USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(PROLIFIC, RSAQ2, 0, 0xFFFF, PL2303),
 	/* I/O DATA USB-RSAQ3 */
-	{USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ3, 0, 0xFFFF, TYPE_PL2303X)},
+	UPLCOM_DEV(PROLIFIC, RSAQ3, 0, 0xFFFF, PL2303X),
 	/* PLANEX USB-RS232 URS-03 */
-	{USB_UPL(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC232A, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(ATEN, UC232A, 0, 0xFFFF, PL2303),
 	/* TrendNet TU-S9 */
-	{USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, 0x0400, 0xFFFF, TYPE_PL2303X)},
+	UPLCOM_DEV(PROLIFIC, PL2303, 0x0400, 0xFFFF, PL2303X),
 	/* ST Lab USB-SERIAL-4 */
-	{USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, 0x0300, 0x03FF, TYPE_PL2303X)},
+	UPLCOM_DEV(PROLIFIC, PL2303, 0x0300, 0x03FF, PL2303X),
 	/* IOGEAR/ATEN UC-232A (also ST Lab USB-SERIAL-1) */
-	{USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, 0, 0x02FF, TYPE_PL2303)},
+	UPLCOM_DEV(PROLIFIC, PL2303, 0, 0x02FF, PL2303),
 	/* TDK USB-PHS Adapter UHA6400 */
-	{USB_UPL(USB_VENDOR_TDK, USB_PRODUCT_TDK_UHA6400, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(TDK, UHA6400, 0, 0xFFFF, PL2303),
 	/* RATOC REX-USB60 */
-	{USB_UPL(USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(RATOC, REXUSB60, 0, 0xFFFF, PL2303),
 	/* ELECOM UC-SGT */
-	{USB_UPL(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT, 0, 0xFFFF, TYPE_PL2303)},
-	{USB_UPL(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT0, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(ELECOM, UCSGT, 0, 0xFFFF, PL2303),
+	UPLCOM_DEV(ELECOM, UCSGT0, 0, 0xFFFF, PL2303),
 	/* Sagem USB-Serial Controller */
-	{USB_UPL(USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_USBSERIAL, 0, 0xFFFF, TYPE_PL2303X)},
+	UPLCOM_DEV(SAGEM, USBSERIAL, 0, 0xFFFF, PL2303X),
 	/* Sony Ericsson USB Cable */
-	{USB_UPL(USB_VENDOR_SONYERICSSON, USB_PRODUCT_SONYERICSSON_DCU10, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(SONYERICSSON, DCU10, 0, 0xFFFF, PL2303),
 	/* SOURCENEXT KeikaiDenwa 8 */
-	{USB_UPL(USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(SOURCENEXT, KEIKAI8, 0, 0xFFFF, PL2303),
 	/* SOURCENEXT KeikaiDenwa 8 with charger */
-	{USB_UPL(USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG, 0, 0, TYPE_PL2303)},
+	UPLCOM_DEV(SOURCENEXT, KEIKAI8_CHG, 0, 0, PL2303),
 	/* HAL Corporation Crossam2+USB */
-	{USB_UPL(USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(HAL, IMR001, 0, 0xFFFF, PL2303),
 	/* Sitecom USB to Serial */
-	{USB_UPL(USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_SERIAL, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(SITECOM, SERIAL, 0, 0xFFFF, PL2303),
 	/* Tripp-Lite U209-000-R */
-	{USB_UPL(USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209, 0, 0xFFFF, TYPE_PL2303X)},
-	{USB_UPL(USB_VENDOR_RADIOSHACK, USB_PRODUCT_RADIOSHACK_USBCABLE, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(TRIPPLITE, U209, 0, 0xFFFF, PL2303X),
+	UPLCOM_DEV(RADIOSHACK, USBCABLE, 0, 0xFFFF, PL2303),
 	/* Prolific Pharos */
-	{USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PHAROS, 0, 0xFFFF, TYPE_PL2303)},
+	UPLCOM_DEV(PROLIFIC, PHAROS, 0, 0xFFFF, PL2303),
 	/* Willcom W-SIM */
-	{USB_UPL(USB_VENDOR_PROLIFIC2, USB_PRODUCT_PROLIFIC2_WSIM, 0, 0xFFFF, TYPE_PL2303X)},
+	UPLCOM_DEV(PROLIFIC2, WSIM, 0, 0xFFFF, PL2303X),
 	/* Mobile Action MA-620 Infrared Adapter */
-	{USB_UPL(USB_VENDOR_MOBILEACTION, USB_PRODUCT_MOBILEACTION_MA620, 0, 0xFFFF, TYPE_PL2303X)},
-
+	UPLCOM_DEV(MOBILEACTION, MA620, 0, 0xFFFF, PL2303X),
 };
+#undef UPLCOM_DEV
 
 static device_method_t uplcom_methods[] = {
 	DEVMETHOD(device_probe, uplcom_probe),
diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c
index 753625f29fc..d97cc2c542c 100644
--- a/sys/dev/usb/serial/uslcom.c
+++ b/sys/dev/usb/serial/uslcom.c
@@ -175,24 +175,26 @@ static struct ucom_callback uslcom_callback = {
 };
 
 static const struct usb_device_id uslcom_devs[] = {
-    { USB_VPI(USB_VENDOR_BALTECH,	USB_PRODUCT_BALTECH_CARDREADER, 0) },
-    { USB_VPI(USB_VENDOR_DYNASTREAM,	USB_PRODUCT_DYNASTREAM_ANTDEVBOARD, 0) },
-    { USB_VPI(USB_VENDOR_JABLOTRON,	USB_PRODUCT_JABLOTRON_PC60B, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_ARGUSISP, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_CRUMB128, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_DEGREE, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_BURNSIDE, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_HELICOM, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_LIPOWSKY_HARP, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_LIPOWSKY_JTAG, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_LIPOWSKY_LIN, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_POLOLU, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_CP2102, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_CP210X_2, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_SUUNTO, 0) },
-    { USB_VPI(USB_VENDOR_SILABS,	USB_PRODUCT_SILABS_TRAQMATE, 0) },
-    { USB_VPI(USB_VENDOR_SILABS2,	USB_PRODUCT_SILABS2_DCU11CLONE, 0) },
-    { USB_VPI(USB_VENDOR_USI,		USB_PRODUCT_USI_MC60, 0) },
+#define	USLCOM_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
+    USLCOM_DEV(BALTECH, CARDREADER),
+    USLCOM_DEV(DYNASTREAM, ANTDEVBOARD),
+    USLCOM_DEV(JABLOTRON, PC60B),
+    USLCOM_DEV(SILABS, ARGUSISP),
+    USLCOM_DEV(SILABS, CRUMB128),
+    USLCOM_DEV(SILABS, DEGREE),
+    USLCOM_DEV(SILABS, BURNSIDE),
+    USLCOM_DEV(SILABS, HELICOM),
+    USLCOM_DEV(SILABS, LIPOWSKY_HARP),
+    USLCOM_DEV(SILABS, LIPOWSKY_JTAG),
+    USLCOM_DEV(SILABS, LIPOWSKY_LIN),
+    USLCOM_DEV(SILABS, POLOLU),
+    USLCOM_DEV(SILABS, CP2102),
+    USLCOM_DEV(SILABS, CP210X_2),
+    USLCOM_DEV(SILABS, SUUNTO),
+    USLCOM_DEV(SILABS, TRAQMATE),
+    USLCOM_DEV(SILABS2, DCU11CLONE),
+    USLCOM_DEV(USI, MC60),
+#undef USLCOM_DEV
 };
 
 static device_method_t uslcom_methods[] = {
diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c
index 3f1624bcbf4..9e6daa97cfa 100644
--- a/sys/dev/usb/serial/uvisor.c
+++ b/sys/dev/usb/serial/uvisor.c
@@ -261,32 +261,34 @@ MODULE_DEPEND(uvisor, ucom, 1, 1, 1);
 MODULE_DEPEND(uvisor, usb, 1, 1, 1);
 
 static const struct usb_device_id uvisor_devs[] = {
-	{USB_VPI(USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_IQUE_3600, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_FOSSIL, USB_PRODUCT_FOSSIL_WRISTPDA, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR, UVISOR_FLAG_VISOR)},
-	{USB_VPI(USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M500, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M505, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M515, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_I705, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M125, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M130, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE31, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_I500, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40, 0)},
-	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41, 0)},
-	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60, UVISOR_FLAG_PALM4)},
-	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_35, UVISOR_FLAG_PALM35)},
-/*  {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_25, UVISOR_FLAG_PALM4 )}, */
-	{USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TJ37, UVISOR_FLAG_PALM4)},
-/*  {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TH55, UVISOR_FLAG_PALM4 )}, See PR 80935 */
-	{USB_VPI(USB_VENDOR_TAPWAVE, USB_PRODUCT_TAPWAVE_ZODIAC, UVISOR_FLAG_PALM4)},
+#define	UVISOR_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+	UVISOR_DEV(ACEECA, MEZ1000, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(GARMIN, IQUE_3600, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(FOSSIL, WRISTPDA, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(HANDSPRING, VISOR, UVISOR_FLAG_VISOR),
+	UVISOR_DEV(HANDSPRING, TREO, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(HANDSPRING, TREO600, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, M500, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, M505, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, M515, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, I705, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, M125, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, M130, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, TUNGSTEN_Z, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, TUNGSTEN_T, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, ZIRE, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(PALM, ZIRE31, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(SAMSUNG, I500, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(SONY, CLIE_40, 0),
+	UVISOR_DEV(SONY, CLIE_41, 0),
+	UVISOR_DEV(SONY, CLIE_S360, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(SONY, CLIE_NX60, UVISOR_FLAG_PALM4),
+	UVISOR_DEV(SONY, CLIE_35, UVISOR_FLAG_PALM35),
+/*  UVISOR_DEV(SONY, CLIE_25, UVISOR_FLAG_PALM4 ), */
+	UVISOR_DEV(SONY, CLIE_TJ37, UVISOR_FLAG_PALM4),
+/*  UVISOR_DEV(SONY, CLIE_TH55, UVISOR_FLAG_PALM4 ), See PR 80935 */
+	UVISOR_DEV(TAPWAVE, ZODIAC, UVISOR_FLAG_PALM4),
+#undef UVISOR_DEV
 };
 
 static int
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 1b8315a9927..c617b9e10da 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -941,6 +941,7 @@ product ASUS RT2573_2		0x1724	RT2573
 product ASUS LCM		0x1726	LCM display
 product ASUS P535		0x420f	ASUS P535 PDA
 product	ASUS GMSC		0x422f	ASUS Generic Mass Storage
+product ASUS RT2570		0x1706	RT2500USB Wireless Adapter
 
 /* ATen products */
 product ATEN UC1284		0x2001	Parallel printer
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index e7c387c5fa7..316bbec881e 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -86,54 +86,56 @@ SYSCTL_INT(_hw_usb_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0,
 #endif
 
 static const struct usb_device_id rum_devs[] = {
-    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_HWU54DM) },
-    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_2) },
-    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_3) },
-    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_4) },
-    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_WUG2700) },
-    { USB_VP(USB_VENDOR_AMIT,		USB_PRODUCT_AMIT_CGWLUSB2GO) },
-    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2573_1) },
-    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2573_2) },
-    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D7050A) },
-    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D9050V3) },
-    { USB_VP(USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GC) },
-    { USB_VP(USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GR) },
-    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_C54RU2) },
-    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB2GL) },
-    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB2GPX) },
-    { USB_VP(USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_CWD854F) },
-    { USB_VP(USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_RT2573) },
-    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWLG122C1) },
-    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_WUA1340) },
-    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA111) },
-    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA110) },
-    { USB_VP(USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_GNWB01GS) },
-    { USB_VP(USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_GNWI05GS) },
-    { USB_VP(USB_VENDOR_GIGASET,	USB_PRODUCT_GIGASET_RT2573) },
-    { USB_VP(USB_VENDOR_GOODWAY,	USB_PRODUCT_GOODWAY_RT2573) },
-    { USB_VP(USB_VENDOR_GUILLEMOT,	USB_PRODUCT_GUILLEMOT_HWGUSB254LB) },
-    { USB_VP(USB_VENDOR_GUILLEMOT,	USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP) },
-    { USB_VP(USB_VENDOR_HUAWEI3COM,	USB_PRODUCT_HUAWEI3COM_WUB320G) },
-    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_G54HP) },
-    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_SG54HP) },
-    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_1) },
-    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_2) },
-    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_3) },
-    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_4) },
-    { USB_VP(USB_VENDOR_NOVATECH,	USB_PRODUCT_NOVATECH_RT2573) },
-    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUS54HP) },
-    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUS54MINI2) },
-    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUSMM) },
-    { USB_VP(USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2573) },
-    { USB_VP(USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2573_2) },
-    { USB_VP(USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2573_3) },
-    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2573) },
-    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2573_2) },
-    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2671) },
-    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_WL113R2) },
-    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_WL172) },
-    { USB_VP(USB_VENDOR_SPARKLAN,	USB_PRODUCT_SPARKLAN_RT2573) },
-    { USB_VP(USB_VENDOR_SURECOM,	USB_PRODUCT_SURECOM_RT2573) },
+#define	RUM_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
+    RUM_DEV(ABOCOM, HWU54DM),
+    RUM_DEV(ABOCOM, RT2573_2),
+    RUM_DEV(ABOCOM, RT2573_3),
+    RUM_DEV(ABOCOM, RT2573_4),
+    RUM_DEV(ABOCOM, WUG2700),
+    RUM_DEV(AMIT, CGWLUSB2GO),
+    RUM_DEV(ASUS, RT2573_1),
+    RUM_DEV(ASUS, RT2573_2),
+    RUM_DEV(BELKIN, F5D7050A),
+    RUM_DEV(BELKIN, F5D9050V3),
+    RUM_DEV(CISCOLINKSYS, WUSB54GC),
+    RUM_DEV(CISCOLINKSYS, WUSB54GR),
+    RUM_DEV(CONCEPTRONIC2, C54RU2),
+    RUM_DEV(COREGA, CGWLUSB2GL),
+    RUM_DEV(COREGA, CGWLUSB2GPX),
+    RUM_DEV(DICKSMITH, CWD854F),
+    RUM_DEV(DICKSMITH, RT2573),
+    RUM_DEV(DLINK2, DWLG122C1),
+    RUM_DEV(DLINK2, WUA1340),
+    RUM_DEV(DLINK2, DWA111),
+    RUM_DEV(DLINK2, DWA110),
+    RUM_DEV(GIGABYTE, GNWB01GS),
+    RUM_DEV(GIGABYTE, GNWI05GS),
+    RUM_DEV(GIGASET, RT2573),
+    RUM_DEV(GOODWAY, RT2573),
+    RUM_DEV(GUILLEMOT, HWGUSB254LB),
+    RUM_DEV(GUILLEMOT, HWGUSB254V2AP),
+    RUM_DEV(HUAWEI3COM, WUB320G),
+    RUM_DEV(MELCO, G54HP),
+    RUM_DEV(MELCO, SG54HP),
+    RUM_DEV(MSI, RT2573_1),
+    RUM_DEV(MSI, RT2573_2),
+    RUM_DEV(MSI, RT2573_3),
+    RUM_DEV(MSI, RT2573_4),
+    RUM_DEV(NOVATECH, RT2573),
+    RUM_DEV(PLANEX2, GWUS54HP),
+    RUM_DEV(PLANEX2, GWUS54MINI2),
+    RUM_DEV(PLANEX2, GWUSMM),
+    RUM_DEV(QCOM, RT2573),
+    RUM_DEV(QCOM, RT2573_2),
+    RUM_DEV(QCOM, RT2573_3),
+    RUM_DEV(RALINK, RT2573),
+    RUM_DEV(RALINK, RT2573_2),
+    RUM_DEV(RALINK, RT2671),
+    RUM_DEV(SITECOMEU, WL113R2),
+    RUM_DEV(SITECOMEU, WL172),
+    RUM_DEV(SPARKLAN, RT2573),
+    RUM_DEV(SURECOM, RT2573),
+#undef RUM_DEV
 };
 
 MODULE_DEPEND(rum, wlan, 1, 1, 1);
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index c2e6d75a68d..25fb86fafa5 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -92,35 +92,37 @@ SYSCTL_INT(_hw_usb_ural, OID_AUTO, debug, CTLFLAG_RW, &ural_debug, 0,
 
 /* various supported device vendors/products */
 static const struct usb_device_id ural_devs[] = {
-	{ USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL167G) },
-	{ USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_RALINK_RT2570) },
-	{ USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050) },
-	{ USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7051) },
-	{ USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_HU200TS) },
-	{ USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54G) },
-	{ USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GP) },
-	{ USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU) },
-	{ USB_VP(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122) },
-	{ USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GN54G) },
-	{ USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWBKG) },
-	{ USB_VP(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254) },
-	{ USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54) },
-	{ USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54AI) },
-	{ USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54YB) },
-	{ USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_NINWIFI) },
-	{ USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570) },
-	{ USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_2) },
-	{ USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_3) },
-	{ USB_VP(USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_NV902) },
-	{ USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570) },
-	{ USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_2) },
-	{ USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_3) },
-	{ USB_VP(USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WL54G) },
-	{ USB_VP(USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG) },
-	{ USB_VP(USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_UB801R) },
-	{ USB_VP(USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2570) },
-	{ USB_VP(USB_VENDOR_VTECH, USB_PRODUCT_VTECH_RT2570) },
-	{ USB_VP(USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2570) },
+#define	URAL_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
+	URAL_DEV(ASUS, WL167G),
+	URAL_DEV(ASUS, RT2570),
+	URAL_DEV(BELKIN, F5D7050),
+	URAL_DEV(BELKIN, F5D7051),
+	URAL_DEV(CISCOLINKSYS, HU200TS),
+	URAL_DEV(CISCOLINKSYS, WUSB54G),
+	URAL_DEV(CISCOLINKSYS, WUSB54GP),
+	URAL_DEV(CONCEPTRONIC2, C54RU),
+	URAL_DEV(DLINK, DWLG122),
+	URAL_DEV(GIGABYTE, GN54G),
+	URAL_DEV(GIGABYTE, GNWBKG),
+	URAL_DEV(GUILLEMOT, HWGUSB254),
+	URAL_DEV(MELCO, KG54),
+	URAL_DEV(MELCO, KG54AI),
+	URAL_DEV(MELCO, KG54YB),
+	URAL_DEV(MELCO, NINWIFI),
+	URAL_DEV(MSI, RT2570),
+	URAL_DEV(MSI, RT2570_2),
+	URAL_DEV(MSI, RT2570_3),
+	URAL_DEV(NOVATECH, NV902),
+	URAL_DEV(RALINK, RT2570),
+	URAL_DEV(RALINK, RT2570_2),
+	URAL_DEV(RALINK, RT2570_3),
+	URAL_DEV(SIEMENS2, WL54G),
+	URAL_DEV(SMC, 2862WG),
+	URAL_DEV(SPHAIRON, UB801R),
+	URAL_DEV(SURECOM, RT2570),
+	URAL_DEV(VTECH, RT2570),
+	URAL_DEV(ZINWELL, RT2570),
+#undef URAL_DEV
 };
 
 static usb_callback_t ural_bulk_read_callback;

From 10280e6d17ef4c0a508aa15d9176cdaaa16b350b Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 00:30:45 +0000
Subject: [PATCH 0990/2592] MFC r201071

 Compact USB_VENDOR_X and USB_PRODUCT_Y in the quirk tables.
---
 sys/dev/usb/quirk/usb_quirk.c | 829 +++++++++++++++-------------------
 1 file changed, 352 insertions(+), 477 deletions(-)

diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index 0a6dca3558b..9a18dee556d 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -73,498 +73,373 @@ struct usb_quirk_entry {
 
 static struct mtx usb_quirk_mtx;
 
+#define	USB_QUIRK_VP(v,p,l,h,...) \
+  { .vid = (v), .pid = (p), .lo_rev = (l), .hi_rev = (h), \
+    .quirks = { __VA_ARGS__ } }
 #define	USB_QUIRK(v,p,l,h,...) \
-  .vid = (v), .pid = (p), .lo_rev = (l), .hi_rev = (h), .quirks = { __VA_ARGS__ }
+  USB_QUIRK_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, l, h, __VA_ARGS__)
+
 static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
-	{USB_QUIRK(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_LCM,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4,
-	    0x094, 0x094, UQ_SWAP_UNICODE)},
-	{USB_QUIRK(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502,
-	    0x0a2, 0x0a2, UQ_BAD_ADC)},
-	{USB_QUIRK(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502,
-	    0x0a2, 0x0a2, UQ_AU_NO_XU)},
-	{USB_QUIRK(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70,
-	    0x103, 0x103, UQ_BAD_ADC)},
-	{USB_QUIRK(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495,
-	    0x000, 0x000, UQ_BAD_AUDIO)},
-	{USB_QUIRK(USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N,
-	    0x110, 0x110, UQ_SPUR_BUT_UP)},
-	{USB_QUIRK(USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB,
-	    0x001, 0x001, UQ_SPUR_BUT_UP)},
-	{USB_QUIRK(USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100,
-	    0x102, 0x102, UQ_BUS_POWERED)},
-	{USB_QUIRK(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232,
-	    0x102, 0x102, UQ_BUS_POWERED)},
-	{USB_QUIRK(USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41,
-	    0x110, 0x110, UQ_POWER_CLAIM)},
-	{USB_QUIRK(USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1,
-	    0x009, 0x009, UQ_AU_NO_FRAC)},
-	{USB_QUIRK(USB_VENDOR_SILICONPORTALS,
-	    USB_PRODUCT_SILICONPORTALS_YAPPHONE,
-	    0x100, 0x100, UQ_AU_INP_ASYNC)},
-	{USB_QUIRK(USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B,
-	    0x0000, 0xFFFF, UQ_NO_STRINGS)},
-	{USB_QUIRK(USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1,
-	    0x0000, 0xFFFF, UQ_CFG_INDEX_1)},
+	USB_QUIRK(ASUS, LCM, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(INSIDEOUT, EDGEPORT4, 0x094, 0x094, UQ_SWAP_UNICODE),
+	USB_QUIRK(DALLAS, J6502, 0x0a2, 0x0a2, UQ_BAD_ADC),
+	USB_QUIRK(DALLAS, J6502, 0x0a2, 0x0a2, UQ_AU_NO_XU),
+	USB_QUIRK(ALTEC, ADA70, 0x103, 0x103, UQ_BAD_ADC),
+	USB_QUIRK(ALTEC, ASC495, 0x000, 0x000, UQ_BAD_AUDIO),
+	USB_QUIRK(QTRONIX, 980N, 0x110, 0x110, UQ_SPUR_BUT_UP),
+	USB_QUIRK(ALCOR2, KBD_HUB, 0x001, 0x001, UQ_SPUR_BUT_UP),
+	USB_QUIRK(MCT, HUB0100, 0x102, 0x102, UQ_BUS_POWERED),
+	USB_QUIRK(MCT, USB232, 0x102, 0x102, UQ_BUS_POWERED),
+	USB_QUIRK(TI, UTUSB41, 0x110, 0x110, UQ_POWER_CLAIM),
+	USB_QUIRK(TELEX, MIC1, 0x009, 0x009, UQ_AU_NO_FRAC),
+	USB_QUIRK(SILICONPORTALS, YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC),
+	USB_QUIRK(LOGITECH, UN53B, 0x0000, 0xffff, UQ_NO_STRINGS),
+	USB_QUIRK(ELSA, MODEM1, 0x0000, 0xffff, UQ_CFG_INDEX_1),
 
 	/*
 	 * XXX The following quirks should have a more specific revision
 	 * number:
 	 */
-	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_895C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
-	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_880C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
-	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_815C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
-	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_810C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
-	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_830C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
-	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_1220C,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
-	{USB_QUIRK(USB_VENDOR_XEROX, USB_PRODUCT_XEROX_WCM15,
-	    0x0000, 0xFFFF, UQ_BROKEN_BIDIR)},
+	USB_QUIRK(HP, 895C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
+	USB_QUIRK(HP, 880C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
+	USB_QUIRK(HP, 815C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
+	USB_QUIRK(HP, 810C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
+	USB_QUIRK(HP, 830C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
+	USB_QUIRK(HP, 1220C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
+	USB_QUIRK(XEROX, WCM15, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
 	/* Devices which should be ignored by uhid */
-	{USB_QUIRK(USB_VENDOR_APC, USB_PRODUCT_APC_UPS,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_CYBERPOWER,
-	    USB_PRODUCT_CYBERPOWER_1500CAVRLCD,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD2X20,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD4X20,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G,
-	    0x0000, 0xFFFF, UQ_HID_IGNORE)},
+	USB_QUIRK(APC, UPS, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(BELKIN, F6C550AVR, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(CYBERPOWER, 1500CAVRLCD, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(DELORME, EARTHMATE, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(ITUNERNET, USBLCD2X20, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(ITUNERNET, USBLCD4X20, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(MGE, UPS1, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(MGE, UPS2, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(APPLE, IPHONE, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(APPLE, IPHONE_3G, 0x0000, 0xffff, UQ_HID_IGNORE),
 	/* Devices which should be ignored by both ukbd and uhid */
-	{USB_QUIRK(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_WISPY1A,
-	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY1B,
-	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE)},
-	{USB_QUIRK(USB_VENDOR_TENX, USB_PRODUCT_TENX_UAUDIO0,
-	    0x0101, 0x0101, UQ_AUDIO_SWAP_LR)},
+	USB_QUIRK(CYPRESS, WISPY1A, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE),
+	USB_QUIRK(METAGEEK, WISPY1B, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE),
+	USB_QUIRK(TENX, UAUDIO0, 0x0101, 0x0101, UQ_AUDIO_SWAP_LR),
 	/* MS keyboards do weird things */
-	{USB_QUIRK(USB_VENDOR_MICROSOFT,
-	    USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE,
-	    0x0000, 0xFFFF, UQ_MS_LEADING_BYTE)},
-	{USB_QUIRK(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X,
-	    0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE)},
+	USB_QUIRK(MICROSOFT, WLINTELLIMOUSE, 0x0000, 0xffff, UQ_MS_LEADING_BYTE),
+	USB_QUIRK(METAGEEK, WISPY24X, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE),
 	/* umodem(4) device quirks */
-	{USB_QUIRK(USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS,
-	    0x100, 0x100, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK(USB_VENDOR_SANYO, USB_PRODUCT_SANYO_SCP4900,
-	    0x000, 0x000, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_T720C,
-	    0x001, 0x001, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK(USB_VENDOR_EICON, USB_PRODUCT_EICON_DIVA852,
-	    0x100, 0x100, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK(USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_ES75,
-	    0x000, 0x000, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK(USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_CDMA_MSM,
-	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK(USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_CDMA_MSM,
-	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
-	{USB_QUIRK(USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_UM175,
-	    0x0000, 0xFFFF, UQ_ASSUME_CM_OVER_DATA)},
+	USB_QUIRK(METRICOM, RICOCHET_GS, 0x100, 0x100, UQ_ASSUME_CM_OVER_DATA),
+	USB_QUIRK(SANYO, SCP4900, 0x000, 0x000, UQ_ASSUME_CM_OVER_DATA),
+	USB_QUIRK(MOTOROLA2, T720C, 0x001, 0x001, UQ_ASSUME_CM_OVER_DATA),
+	USB_QUIRK(EICON, DIVA852, 0x100, 0x100, UQ_ASSUME_CM_OVER_DATA),
+	USB_QUIRK(SIEMENS2, ES75, 0x000, 0x000, UQ_ASSUME_CM_OVER_DATA),
+	USB_QUIRK(QUALCOMM, CDMA_MSM, 0x0000, 0xffff, UQ_ASSUME_CM_OVER_DATA),
+	USB_QUIRK(QUALCOMM2, CDMA_MSM, 0x0000, 0xffff, UQ_ASSUME_CM_OVER_DATA),
+	USB_QUIRK(CURITEL, UM175, 0x0000, 0xffff, UQ_ASSUME_CM_OVER_DATA),
 
 	/* USB Mass Storage Class Quirks */
-	{USB_QUIRK(USB_VENDOR_ASAHIOPTICAL, 0,
-	    0x0000, 0xFFFF, UQ_MSC_NO_RS_CLEAR_UA, UQ_MATCH_VENDOR_ONLY)},
-	{USB_QUIRK(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_ATTACHE, 0x0000,
-	    0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_A256MB,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_ADDON, USB_PRODUCT_ADDON_DISKPRO512,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_CABLE_205,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_AIPTEK, USB_PRODUCT_AIPTEK_POCKETCAM3M,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_AIPTEK2, USB_PRODUCT_AIPTEK2_SUNPLUS_TECH,
-	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_SDCR_6335,
-	    0x0000, 0xFFFF, UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU6390,
-	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_UMCR_9361,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_TRANSCEND,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO330,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2SCSI,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV_DIGICAM,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_CCYU, USB_PRODUCT_CCYU_ED1064,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_CENTURY, USB_PRODUCT_CENTURY_EX35QUAT,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
+	USB_QUIRK_VP(USB_VENDOR_ASAHIOPTICAL, 0, UQ_MSC_NO_RS_CLEAR_UA,
+	    UQ_MATCH_VENDOR_ONLY),
+	USB_QUIRK(ADDON, ATTACHE, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(ADDON, A256MB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(ADDON, DISKPRO512, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(ADDONICS2, CABLE_205, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(AIPTEK, POCKETCAM3M, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(AIPTEK2, SUNPLUS_TECH, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(ALCOR, SDCR_6335, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY,
+	    UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(ALCOR, AU6390, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(ALCOR, UMCR_9361, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(ALCOR, TRANSCEND, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(ASAHIOPTICAL, OPTIO230, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(ASAHIOPTICAL, OPTIO330, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(BELKIN, USB2SCSI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(CASIO, QV_DIGICAM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(CCYU, ED1064, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(CENTURY, EX35QUAT, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
+	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(CYPRESS, XX6830XX, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN,
+	    UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(DESKNOTE, UCR_61S2B, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(DMI, CFSM_RW, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(EPSON, STYLUS_875DC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(EPSON, STYLUS_895, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(FEIYA, 5IN1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(FREECOM, DVD, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(FUJIPHOTO, MASS0100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_RS_CLEAR_UA),
+	USB_QUIRK(GENESYS, GL641USB2IDE, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
+	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(GENESYS, GL641USB2IDE_2, 0x0000, 0xffff,
+	    UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_XX6830XX,
-	    0x0000, 0xFFFF, UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_DESKNOTE, USB_PRODUCT_DESKNOTE_UCR_61S2B,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_DMI, USB_PRODUCT_DMI_CFSM_RW,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_875DC,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_895,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_FEIYA, USB_PRODUCT_FEIYA_5IN1,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_RS_CLEAR_UA)},
-	{USB_QUIRK(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE,
-	    UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE_2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB_2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_WRONG_CSWSIG)},
-	{USB_QUIRK(USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_DZ_MV100A,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_CDW4E,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK(USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP)},
-	{USB_QUIRK(USB_VENDOR_IMAGINATION, USB_PRODUCT_IMAGINATION_DBX1,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_WRONG_CSWSIG)},
-	{USB_QUIRK(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP, UQ_MSC_ALT_IFACE_1)},
-	{USB_QUIRK(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK(USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_STORAGE_V2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_IU_CD2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_DVR_UEH8,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_TEST_UNIT_READY)}, /* XXX ZIP drives can also use ATAPI */
-	{USB_QUIRK(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_L3,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S3X,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S4,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S5,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_LACIE, USB_PRODUCT_LACIE_HD,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK(USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_CF_READER,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPSHOT,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443SU2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443U2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,)},
-	{USB_QUIRK(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP)},
-	{USB_QUIRK(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIHD50,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_E223,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_F300,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI | UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK(USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_FDD,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_E398,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_INQUIRY_EVPD, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_MPMAN, 0,
-	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY)},
-	{USB_QUIRK(USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_RS_CLEAR_UA)},
-	{USB_QUIRK(USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN,
-	    0x0000, 0xFFFF, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN_8813,
-	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_MYSON, USB_PRODUCT_MYSON_STARREADER,
-	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_FORCE_SHORT_INQ)},
-	{USB_QUIRK(USB_VENDOR_NETAC, USB_PRODUCT_NETAC_CF_CARD,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_NETAC, USB_PRODUCT_NETAC_ONLYDISK,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK_40,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_NIKON, USB_PRODUCT_NIKON_D300,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_WRONG_CSWSIG)},
-	{USB_QUIRK(USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700,
-	    0x0000, 0xFFFF, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_COMBO,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFE_B_CF_READER,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDSM_B_READER,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_READER,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_UCF100,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_INQUIRY | UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_ONSPEC2, USB_PRODUCT_ONSPEC2_IMAGEMATE_SDDR55,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXL840AN,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB20AN,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB35AN,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_LS120CAM,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_UFI)},
-	{USB_QUIRK(USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SPE3030CC,
-	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_TEST_UNIT_READY)},
-	{USB_QUIRK(USB_VENDOR_PNY, USB_PRODUCT_PNY_ATTACHE2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_START_STOP)},
-	{USB_QUIRK(USB_VENDOR_SAMSUNG_TECHWIN, USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_READ_CAP_OFFBY1, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_READ_CAP_OFFBY1, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_128,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_256,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_READ_CAP_OFFBY1)},
-	{USB_QUIRK(USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_START_STOP, UQ_MSC_SHUTTLE_INIT)},
-	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBCFSM,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_SHUTTLE_INIT)},
-	{USB_QUIRK(USB_VENDOR_SIIG, USB_PRODUCT_SIIG_WINTERREADER,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_MD_7425,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_SX_520Z,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM,
-	    0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC,
-	    UQ_MSC_RBC_PAD_TO_12)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
-	    0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC,
-	    UQ_MSC_RBC_PAD_TO_12)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
-	    0x0600, 0x0600, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC,
-	    UQ_MSC_RBC_PAD_TO_12)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_MSC_U03,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_NW_MS7,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_PEG_N760C,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_SONY, USB_PRODUCT_SONY_PORTABLE_HDD_V2,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDE,
-	    0x0000, 0xFFFF, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI)},
-	{USB_QUIRK(USB_VENDOR_TECLAST, USB_PRODUCT_TECLAST_TLC300,
-	    0x0000, 0xFFFF, UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_TREK, USB_PRODUCT_TREK_MEMKEY,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_C3310,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI)},
-	{USB_QUIRK(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_MP3,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_RBC)},
-	{USB_QUIRK(USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_T33520,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_MDIV,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI)},
-	{USB_QUIRK(USB_VENDOR_VIA, USB_PRODUCT_VIA_USB2IDEBRIDGE,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_VIVITAR, USB_PRODUCT_VIVITAR_35XX,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_EXTHDD,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYBOOK,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY_EVPD)},
-	{USB_QUIRK(USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSWORD,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_SHORT_INQ)},
-	{USB_QUIRK(USB_VENDOR_WINMAXGROUP, USB_PRODUCT_WINMAXGROUP_FLASH64MC,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY)},
-	{USB_QUIRK(USB_VENDOR_YANO, USB_PRODUCT_YANO_FW800HD,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_FORCE_SHORT_INQ, UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE)},
-	{USB_QUIRK(USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_ATAPI,
-	    UQ_MSC_FORCE_SHORT_INQ)},
-	{USB_QUIRK(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
-	    0x0000, 0x007F, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI,
-	    UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED,
-	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
-	    0x0080, 0x0080, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_UFI,
-	    UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED,
-	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU,
-	    0x0081, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I, UQ_MSC_FORCE_PROTO_UFI,
-	    UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED, UQ_MSC_NO_GETMAXLUN)},
-	{USB_QUIRK(USB_VENDOR_ZORAN, USB_PRODUCT_ZORAN_EX20DSC,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_ATAPI)},
-	{USB_QUIRK(USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_INQUIRY, UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_ACTIONS, USB_PRODUCT_ACTIONS_MP4,
-	    0x0000, 0xFFFF, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,
-	    UQ_MSC_NO_SYNC_CACHE)},
-	{USB_QUIRK(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_GMSC,
-	    0x0000, 0xFFFF, UQ_MSC_NO_SYNC_CACHE)},
+	    UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(GENESYS, GL641USB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
+	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(GENESYS, GL641USB_2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_WRONG_CSWSIG),
+	USB_QUIRK(HAGIWARA, FG, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(HAGIWARA, FGSM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(HITACHI, DVDCAM_DZ_MV100A, 0x0000, 0xffff,
+	    UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(HITACHI, DVDCAM_USB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(HP, CDW4E, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_ATAPI),
+	USB_QUIRK(HP, CDW8200, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_TEST_UNIT_READY,
+	    UQ_MSC_NO_START_STOP),
+	USB_QUIRK(IMAGINATION, DBX1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_WRONG_CSWSIG),
+	USB_QUIRK(INSYSTEM, USBCABLE, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_TEST_UNIT_READY,
+	    UQ_MSC_NO_START_STOP, UQ_MSC_ALT_IFACE_1),
+	USB_QUIRK(INSYSTEM, ATAPI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_RBC),
+	USB_QUIRK(INSYSTEM, STORAGE_V2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_RBC),
+	USB_QUIRK(IODATA, IU_CD2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(IODATA, DVR_UEH8, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(IOMEGA, ZIP100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_TEST_UNIT_READY), /* XXX ZIP drives can also use ATAPI */
+	USB_QUIRK(KYOCERA, FINECAM_L3, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(KYOCERA, FINECAM_S3X, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(KYOCERA, FINECAM_S4, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(KYOCERA, FINECAM_S5, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(LACIE, HD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_RBC),
+	USB_QUIRK(LEXAR, CF_READER, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(LEXAR, JUMPSHOT, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(LOGITEC, LDR_H443SU2, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(LOGITEC, LDR_H443U2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI,),
+	USB_QUIRK(MELCO, DUBPXXG, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
+	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(MICROTECH, DPCM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_TEST_UNIT_READY,
+	    UQ_MSC_NO_START_STOP),
+	USB_QUIRK(MICROTECH, SCSIDB25, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(MICROTECH, SCSIHD50, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(MINOLTA, E223, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(MINOLTA, F300, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(MITSUMI, CDRRW, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI |
+	    UQ_MSC_FORCE_PROTO_ATAPI),
+	USB_QUIRK(MITSUMI, FDD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(MOTOROLA2, E398, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
+	    UQ_MSC_NO_INQUIRY_EVPD, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK_VP(USB_VENDOR_MPMAN, 0, UQ_MSC_NO_SYNC_CACHE,
+	    UQ_MATCH_VENDOR_ONLY),
+	USB_QUIRK(MSYSTEMS, DISKONKEY, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_GETMAXLUN,
+	    UQ_MSC_NO_RS_CLEAR_UA),
+	USB_QUIRK(MSYSTEMS, DISKONKEY2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_ATAPI),
+	USB_QUIRK(MYSON, HEDEN, 0x0000, 0xffff, UQ_MSC_IGNORE_RESIDUE,
+	    UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(MYSON, HEDEN_8813, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(MYSON, STARREADER, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(NEODIO, ND3260, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ),
+	USB_QUIRK(NETAC, CF_CARD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(NETAC, ONLYDISK, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(NETCHIP, CLIK_40, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_ATAPI,
+	    UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(NIKON, D300, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(OLYMPUS, C1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_WRONG_CSWSIG),
+	USB_QUIRK(OLYMPUS, C700, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(ONSPEC, SDS_HOTFIND_D, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(ONSPEC, CFMS_RW, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(ONSPEC, CFSM_COMBO, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(ONSPEC, CFSM_READER, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(ONSPEC, CFSM_READER2, 0x0000, 0xffff,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(ONSPEC, MDCFE_B_CF_READER, 0x0000, 0xffff,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(ONSPEC, MDSM_B_READER, 0x0000, 0xffff,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(ONSPEC, READER, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(ONSPEC, UCF100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY | UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(ONSPEC2, IMAGEMATE_SDDR55, 0x0000, 0xffff,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(PANASONIC, KXL840AN, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(PANASONIC, KXLCB20AN, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(PANASONIC, KXLCB35AN, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(PANASONIC, LS120CAM, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_UFI),
+	USB_QUIRK(PHILIPS, SPE3030CC, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(PLEXTOR, 40_12_40U, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_TEST_UNIT_READY),
+	USB_QUIRK(PNY, ATTACHE2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE,
+	    UQ_MSC_NO_START_STOP),
+	USB_QUIRK_VP(USB_VENDOR_SAMSUNG_TECHWIN,
+	    USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(SANDISK, SDDR05A, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1,
+	    UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SANDISK, SDDR09, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_READ_CAP_OFFBY1, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SANDISK, SDDR12, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1,
+	    UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SANDISK, SDCZ2_256, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(SANDISK, SDCZ4_128, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(SANDISK, SDCZ4_256, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(SANDISK, SDDR31, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1),
+	USB_QUIRK(SCANLOGIC, SL11R, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(SHUTTLE, EUSB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_TEST_UNIT_READY,
+	    UQ_MSC_NO_START_STOP, UQ_MSC_SHUTTLE_INIT),
+	USB_QUIRK(SHUTTLE, CDRW, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_ATAPI),
+	USB_QUIRK(SHUTTLE, CF, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_ATAPI),
+	USB_QUIRK(SHUTTLE, EUSBATAPI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_ATAPI),
+	USB_QUIRK(SHUTTLE, EUSBCFSM, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(SHUTTLE, EUSCSI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(SHUTTLE, HIFD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SHUTTLE, SDDR09, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SHUTTLE, ZIOMMC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SIGMATEL, I_BEAD100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_SHUTTLE_INIT),
+	USB_QUIRK(SIIG, WINTERREADER, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(SKANHEX, MD_7425, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(SKANHEX, SX_520Z, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(SONY, HANDYCAM, 0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_RBC, UQ_MSC_RBC_PAD_TO_12),
+	USB_QUIRK(SONY, CLIE_40_MS, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(SONY, DSC, 0x0500, 0x0500, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_RBC, UQ_MSC_RBC_PAD_TO_12),
+	USB_QUIRK(SONY, DSC, 0x0600, 0x0600, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_RBC, UQ_MSC_RBC_PAD_TO_12),
+	USB_QUIRK(SONY, DSC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_RBC),
+	USB_QUIRK(SONY, HANDYCAM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_RBC),
+	USB_QUIRK(SONY, MSC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_RBC),
+	USB_QUIRK(SONY, MS_MSC_U03, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_UFI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SONY, MS_NW_MS7, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SONY, MS_PEG_N760C, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(SONY, MSACUS1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SONY, PORTABLE_HDD_V2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(SUPERTOP, IDE, 0x0000, 0xffff, UQ_MSC_IGNORE_RESIDUE,
+	    UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(TAUGA, CAMERAMATE, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(TEAC, FD05PUB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_UFI),
+	USB_QUIRK(TECLAST, TLC300, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY,
+	    UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(TREK, MEMKEY, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(TREK, THUMBDRIVE_8MB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(TRUMPION, C3310, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_UFI),
+	USB_QUIRK(TRUMPION, MP3, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_RBC),
+	USB_QUIRK(TRUMPION, T33520, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(TWINMOS, MDIV, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI),
+	USB_QUIRK(VIA, USB2IDEBRIDGE, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(VIVITAR, 35XX, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(WESTERN, COMBO, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
+	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(WESTERN, EXTHDD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
+	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(WESTERN, MYBOOK, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY_EVPD),
+	USB_QUIRK(WESTERN, MYPASSWORD, 0x0000, 0xffff, UQ_MSC_FORCE_SHORT_INQ),
+	USB_QUIRK(WINMAXGROUP, FLASH64MC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(YANO, FW800HD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
+	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE),
+	USB_QUIRK(YANO, U640MO, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I,
+	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_FORCE_SHORT_INQ),
+	USB_QUIRK(YEDATA, FLASHBUSTERU, 0x0000, 0x007F, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_UFI, UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED,
+	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(YEDATA, FLASHBUSTERU, 0x0080, 0x0080, UQ_MSC_FORCE_WIRE_CBI_I,
+	    UQ_MSC_FORCE_PROTO_UFI, UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED,
+	    UQ_MSC_NO_TEST_UNIT_READY, UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(YEDATA, FLASHBUSTERU, 0x0081, 0xFFFF, UQ_MSC_FORCE_WIRE_CBI_I,
+	    UQ_MSC_FORCE_PROTO_UFI, UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_FLOPPY_SPEED,
+	    UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(ZORAN, EX20DSC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
+	    UQ_MSC_FORCE_PROTO_ATAPI),
+	USB_QUIRK(MEIZU, M6_SL, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(ACTIONS, MP4, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(ASUS, GMSC, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 };
+#undef USB_QUIRK_VP
 #undef USB_QUIRK
 
 static const char *usb_quirk_str[USB_QUIRK_MAX] = {

From c774a6224ac36bd385057ddf552727dc4c2c6a72 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Thu, 31 Dec 2009 06:59:15 +0000
Subject: [PATCH 0991/2592] Sync usbdevs to fix the build.

Pointy hat:	me
---
 sys/dev/usb/usbdevs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index c617b9e10da..e4ee8a9ab59 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1144,6 +1144,7 @@ product CTX EX1300		0x9999	Ex1300 hub
 product CURITEL HX550C		0x1101	CDMA 2000 1xRTT USB modem (HX-550C)
 product CURITEL HX57XB		0x2101	CDMA 2000 1xRTT USB modem (HX-570/575B/PR-600)
 product CURITEL PC5740		0x3701	Broadband Wireless modem
+product CURITEL UM175		0x3714	EVDO modem
 
 /* CyberPower products */
 product CYBERPOWER 1500CAVRLCD	0x0501	1500CAVRLCD

From d2129b50301b1339fde16f5d40166e9396258bc2 Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Thu, 31 Dec 2009 07:28:43 +0000
Subject: [PATCH 0992/2592] MFC r198289:

Fix comment typos.

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 44aa9b63f6dde685058fa080a51c3a62e9fca38e Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Thu, 31 Dec 2009 07:32:04 +0000
Subject: [PATCH 0993/2592] MFC r198290:

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().

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 e15f9ffcb08b36c43795f38e96750ebc42b55c2a Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Thu, 31 Dec 2009 07:34:38 +0000
Subject: [PATCH 0994/2592] MFC r198291:

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.

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 486998560101df3a51989cfadb08181fa5fc1d33 Mon Sep 17 00:00:00 2001
From: "David E. O'Brien" 
Date: Thu, 31 Dec 2009 10:00:49 +0000
Subject: [PATCH 0995/2592] Happy New Year 2010! :-)

---
 COPYRIGHT | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/COPYRIGHT b/COPYRIGHT
index d13e662330d..24e9a70fe72 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -4,7 +4,7 @@
 The compilation of software known as FreeBSD is distributed under the
 following terms:
 
-Copyright (c) 1992-2009 The FreeBSD Project. All rights reserved.
+Copyright (c) 1992-2010 The FreeBSD Project. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions

From 35e0c29fdf511ba961d96cffffc9346085b35218 Mon Sep 17 00:00:00 2001
From: Ed Schouten 
Date: Thu, 31 Dec 2009 10:53:04 +0000
Subject: [PATCH 0996/2592] MFC r198185:

  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.

I totally forgot to MFC this, because the 8.0 freeze took a little
longer than I expected.

Reminded by:	koitsu
---
 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 debaa1cc1e9..c61fa02d72d 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 e6b37c3a7f61eb56d1190833d01f1b6ec2ccce44 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 31 Dec 2009 11:49:13 +0000
Subject: [PATCH 0997/2592] MFC r201134: Add a knob to allow reclaim of the
 directory vnodes that are source of the namecache records.

---
 sys/kern/vfs_subr.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 0d38e5cea93..a43b955f1bc 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -152,6 +152,10 @@ SYSCTL_LONG(_vfs, OID_AUTO, wantfreevnodes, CTLFLAG_RW, &wantfreevnodes, 0, "");
 static u_long freevnodes;
 SYSCTL_LONG(_vfs, OID_AUTO, freevnodes, CTLFLAG_RD, &freevnodes, 0, "");
 
+static int vlru_allow_cache_src;
+SYSCTL_INT(_vfs, OID_AUTO, vlru_allow_cache_src, CTLFLAG_RW,
+    &vlru_allow_cache_src, 0, "Allow vlru to reclaim source vnode");
+
 /*
  * Various variables used for debugging the new implementation of
  * reassignbuf().
@@ -643,7 +647,9 @@ vlrureclaim(struct mount *mp)
 		 * If it's been deconstructed already, it's still
 		 * referenced, or it exceeds the trigger, skip it.
 		 */
-		if (vp->v_usecount || !LIST_EMPTY(&(vp)->v_cache_src) ||
+		if (vp->v_usecount ||
+		    (!vlru_allow_cache_src &&
+			!LIST_EMPTY(&(vp)->v_cache_src)) ||
 		    (vp->v_iflag & VI_DOOMED) != 0 || (vp->v_object != NULL &&
 		    vp->v_object->resident_page_count > trigger)) {
 			VI_UNLOCK(vp);
@@ -668,7 +674,9 @@ vlrureclaim(struct mount *mp)
 		 * interlock, the other thread will be unable to drop the
 		 * vnode lock before our VOP_LOCK() call fails.
 		 */
-		if (vp->v_usecount || !LIST_EMPTY(&(vp)->v_cache_src) ||
+		if (vp->v_usecount ||
+		    (!vlru_allow_cache_src &&
+			!LIST_EMPTY(&(vp)->v_cache_src)) ||
 		    (vp->v_object != NULL &&
 		    vp->v_object->resident_page_count > trigger)) {
 			VOP_UNLOCK(vp, LK_INTERLOCK);

From d36f5405ca1a94cb870499e42ee91f2f1924f758 Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Thu, 31 Dec 2009 12:58:08 +0000
Subject: [PATCH 0998/2592] MFC 200637:

Don't panic due to unlocking an unowned mutex if we fail during attach.

PR:		kern/139053
Reviewed by:	scottl
Approved by:	ed (mentor)
---
 sys/dev/ciss/ciss.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index 39836ea7ea7..c5ad417e70c 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -418,6 +418,7 @@ ciss_attach(device_t dev)
 
     sc = device_get_softc(dev);
     sc->ciss_dev = dev;
+    mtx_init(&sc->ciss_mtx, "cissmtx", NULL, MTX_DEF);
 
     /*
      * Do PCI-specific init.
@@ -430,7 +431,6 @@ ciss_attach(device_t dev)
      */
     ciss_initq_free(sc);
     ciss_initq_notify(sc);
-    mtx_init(&sc->ciss_mtx, "cissmtx", NULL, MTX_DEF);
     callout_init_mtx(&sc->ciss_periodic, &sc->ciss_mtx, 0);
 
     /*
@@ -496,8 +496,11 @@ ciss_attach(device_t dev)
 
     error = 0;
  out:
-    if (error != 0)
+    if (error != 0) {
+	/* ciss_free() expects the mutex to be held */
+	mtx_lock(&sc->ciss_mtx);
 	ciss_free(sc);
+    }
     return(error);
 }
 

From 92bfafd31b7ba692be57fa3de5d080a3c756ff6a Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Fri, 1 Jan 2010 11:43:09 +0000
Subject: [PATCH 0999/2592] MFC r201201: Document CLOCK_SECOND, add
 cross-reference from time(3) to clock_gettime(2).

MFC r201204:
Document _FAST and _PRECISE clocks.
---
 lib/libc/gen/time.3          |  1 +
 lib/libc/sys/clock_gettime.2 | 55 ++++++++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/lib/libc/gen/time.3 b/lib/libc/gen/time.3
index 2770e49f386..d022e0611c4 100644
--- a/lib/libc/gen/time.3
+++ b/lib/libc/gen/time.3
@@ -66,6 +66,7 @@ The
 function may fail for any of the reasons described in
 .Xr gettimeofday 2 .
 .Sh SEE ALSO
+.Xr clock_gettime 2 ,
 .Xr gettimeofday 2 ,
 .Xr ctime 3
 .Sh STANDARDS
diff --git a/lib/libc/sys/clock_gettime.2 b/lib/libc/sys/clock_gettime.2
index 242af1c702f..a2fa62490ec 100644
--- a/lib/libc/sys/clock_gettime.2
+++ b/lib/libc/sys/clock_gettime.2
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 4, 2006
+.Dd December 29, 2009
 .Dt CLOCK_GETTIME 2
 .Os
 .Sh NAME
@@ -59,21 +59,43 @@ used by a clock which is specified by
 The
 .Fa clock_id
 argument
-can be one of five values:
-.Dv CLOCK_REALTIME
+can be one of the following values:
+.Dv CLOCK_REALTIME ,
+.Dv CLOCK_REALTIME_PRECISE ,
+.Dv CLOCK_REALTIME_FAST
 for time that increments as
-a wall clock should,
-.Dv CLOCK_MONOTONIC
-which increments in SI seconds,
-.Dv CLOCK_UPTIME
+a wall clock should;
+.Dv CLOCK_MONOTONIC ,
+.Dv CLOCK_MONOTONIC_PRECISE ,
+.Dv CLOCK_MONOTONIC_FAST
+which increments in SI seconds;
+.Dv CLOCK_UPTIME ,
+.Dv CLOCK_UPTIME_PRECISE ,
+.Dv CLOCK_UPTIME_FAST
 which starts at zero when the kernel boots and increments
-monotonically in SI seconds while the machine is running,
+monotonically in SI seconds while the machine is running;
 .Dv CLOCK_VIRTUAL
 for time that increments only when
-the CPU is running in user mode on behalf of the calling process, or
+the CPU is running in user mode on behalf of the calling process;
 .Dv CLOCK_PROF
 for time that increments when the CPU is running in user or
-kernel mode.
+kernel mode; or
+.Dv CLOCK_SECOND
+which returns the current second without performing a full time counter
+query, using in-kernel cached value of current second.
+.Pp
+The clock IDs
+.Fa CLOCK_REALTIME_FAST ,
+.Fa CLOCK_MONOTONIC_FAST ,
+.Fa CLOCK_UPTIME_FAST
+are analogs of corresponding IDs without _FAST suffix but do not perform
+a full time counter query, so their accuracy is one timer tick.
+Similarly,
+.Fa CLOCK_REALTIME_PRECISE ,
+.Fa CLOCK_MONOTONIC_PRECISE ,
+.Fa CLOCK_UPTIME_PRECISE
+are used to get the most exact value as possible, at the expense of
+execution time.
 .Pp
 The structure pointed to by
 .Fa tp
@@ -88,7 +110,8 @@ struct timespec {
 };
 .Ed
 .Pp
-Only the super-user may set the time of day.
+Only the super-user may set the time of day, using only
+.Fa CLOCK_REALTIME .
 If the system securelevel is greater than 1 (see
 .Xr init 8 ) ,
 the time may only be advanced.
@@ -134,3 +157,13 @@ and
 .Fn clock_getres
 system calls conform to
 .St -p1003.1b-93 .
+The clock IDs
+.Fa CLOCK_REALTIME_FAST ,
+.Fa CLOCK_REALTIME_PRECISE ,
+.Fa CLOCK_MONOTONIC_FAST ,
+.Fa CLOCK_MONOTONIC_PRECISE ,
+.Fa CLOCK_UPTIME ,
+.Fa CLOCK_UPTIME_FAST ,
+.Fa CLOCK_UPTIME_PRECISE ,
+.Fa CLOCK_SECOND
+are FreeBSD extensions to the POSIX interface.

From 91de5836345813cd948a8ac45b71651949efca48 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 1 Jan 2010 17:30:42 +0000
Subject: [PATCH 1000/2592] MFC: r201126

Account for firmware versions which include the CDMA interrupts in
the OFW device tree.
---
 sys/sparc64/pci/schizo.c | 51 +++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 19 deletions(-)

diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index 70851718863..0eedd91917f 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -628,31 +628,44 @@ schizo_attach(device_t dev)
 	/*
 	 * According to the Schizo Errata I-13, consistent DMA flushing/
 	 * syncing is FUBAR in version < 5 (i.e. revision < 2.3) bridges,
-	 * so we can't use it and need to live with the consequences.
-	 * With Schizo version >= 5, CDMA flushing/syncing is usable
-	 * but requires the the workaround described in Schizo Errata
-	 * I-23.  With Tomatillo and XMITS, CDMA flushing/syncing works
-	 * as expected, Tomatillo version <= 4 (i.e. revision <= 2.3)
-	 * bridges additionally require a block store after a write to
-	 * TOMXMS_PCI_DMA_SYNC_PEND though.
+	 * so we can't use it and need to live with the consequences.  With
+	 * Schizo version >= 5, CDMA flushing/syncing is usable but requires
+	 * the workaround described in Schizo Errata I-23.  With Tomatillo
+	 * and XMITS, CDMA flushing/syncing works as expected, Tomatillo
+	 * version <= 4 (i.e. revision <= 2.3) bridges additionally require
+	 * a block store after a write to TOMXMS_PCI_DMA_SYNC_PEND though.
 	 */
 	if ((sc->sc_mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 5) ||
 	    sc->sc_mode == SCHIZO_MODE_TOM || sc->sc_mode == SCHIZO_MODE_XMS) {
 		sc->sc_flags |= SCHIZO_FLAGS_CDMA;
 		if (sc->sc_mode == SCHIZO_MODE_SCZ) {
-			n = STX_CDMA_A_INO + sc->sc_half;
-			if (bus_set_resource(dev, SYS_RES_IRQ, 5,
-			    INTMAP_VEC(sc->sc_ign, n), 1) != 0)
-				panic("%s: failed to add CDMA interrupt",
-				    __func__);
-			i = schizo_intr_register(sc, n);
-			if (i != 0)
-				panic("%s: could not register interrupt "
-				    "controller for CDMA (%d)", __func__, i);
-			(void)schizo_get_intrmap(sc, n, NULL,
-			   &sc->sc_cdma_clr);
 			sc->sc_cdma_state = SCHIZO_CDMA_STATE_DONE;
-			schizo_set_intr(sc, 5, n, schizo_cdma);
+			/*
+			 * Some firmware versions include the CDMA interrupt
+			 * at RID 4 but most don't.  With the latter we add
+			 * it ourselves at the spare RID 5.
+			 */
+			n = INTINO(bus_get_resource_start(dev, SYS_RES_IRQ,
+			    4));
+			if (n == STX_CDMA_A_INO || n == STX_CDMA_B_INO) {
+				(void)schizo_get_intrmap(sc, n, NULL,
+				   &sc->sc_cdma_clr);
+				schizo_set_intr(sc, 4, n, schizo_cdma);
+			} else {
+				n = STX_CDMA_A_INO + sc->sc_half;
+				if (bus_set_resource(dev, SYS_RES_IRQ, 5,
+				    INTMAP_VEC(sc->sc_ign, n), 1) != 0)
+					panic("%s: failed to add CDMA "
+					    "interrupt", __func__);
+				i = schizo_intr_register(sc, n);
+				if (i != 0)
+					panic("%s: could not register "
+					    "interrupt controller for CDMA "
+					    "(%d)", __func__, i);
+				(void)schizo_get_intrmap(sc, n, NULL,
+				   &sc->sc_cdma_clr);
+				schizo_set_intr(sc, 5, n, schizo_cdma);
+			}
 		}
 		if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4)
 			sc->sc_flags |= SCHIZO_FLAGS_BSWAR;

From dfb1009882b885e28fa6c62ce8eb0789a74c6835 Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Sat, 2 Jan 2010 13:07:14 +0000
Subject: [PATCH 1001/2592] MFC r200993:  Small spelling fix, "Ethetnet" ->
 "Ethernet"

Approved by:	ed (mentor)
---
 sys/dev/ae/if_ae.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/ae/if_ae.c b/sys/dev/ae/if_ae.c
index 33ecfbe48ff..d3e95ef1eb8 100644
--- a/sys/dev/ae/if_ae.c
+++ b/sys/dev/ae/if_ae.c
@@ -1047,7 +1047,7 @@ ae_get_reg_eaddr(ae_softc_t *sc, uint32_t *eaddr)
 	if (AE_CHECK_EADDR_VALID(eaddr) != 0) {
 		if (bootverbose)
 			device_printf(sc->dev,
-			    "Ethetnet address registers are invalid.\n");
+			    "Ethernet address registers are invalid.\n");
 		return (EINVAL);
 	}
 	return (0);

From 47cc17a5a7611e2ddefce1064e71b362a37019ea Mon Sep 17 00:00:00 2001
From: Warner Losh 
Date: Sat, 2 Jan 2010 20:34:13 +0000
Subject: [PATCH 1002/2592] Welcome to 2010.

---
 sys/sys/copyright.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/sys/copyright.h b/sys/sys/copyright.h
index 1b0b96a5b98..62a4ac9d920 100644
--- a/sys/sys/copyright.h
+++ b/sys/sys/copyright.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (C) 1992-2009 The FreeBSD Project. All rights reserved.
+ * Copyright (C) 1992-2010 The FreeBSD Project. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
   
 /* FreeBSD */
 #define COPYRIGHT_FreeBSD \
-	"Copyright (c) 1992-2009 The FreeBSD Project.\n"
+	"Copyright (c) 1992-2010 The FreeBSD Project.\n"
 
 /* Foundation */
 #define	TRADEMARK_Foundation \

From 7b88770e933806f451bf54bcbebc1b45a3d9e841 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sun, 3 Jan 2010 00:27:35 +0000
Subject: [PATCH 1003/2592] MFC r200516:

Add an option to specify that the received ZFS should not be automatically
mounted (receive -u).

Obtained from:	OpenSolaris (onnv revision 8584:327a1b6dd944)
Approved by:	pjd
---
 cddl/contrib/opensolaris/cmd/zfs/zfs_main.c                | 7 +++++--
 cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h        | 5 ++++-
 .../opensolaris/lib/libzfs/common/libzfs_sendrecv.c        | 4 ++--
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
index 6f5f92ebc4e..d6bc6e129af 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -2457,7 +2457,7 @@ zfs_do_receive(int argc, char **argv)
 
 	bzero(&flags, sizeof (recvflags_t));
 	/* check options */
-	while ((c = getopt(argc, argv, ":dnvF")) != -1) {
+	while ((c = getopt(argc, argv, ":dnuvF")) != -1) {
 		switch (c) {
 		case 'd':
 			flags.isprefix = B_TRUE;
@@ -2465,6 +2465,9 @@ zfs_do_receive(int argc, char **argv)
 		case 'n':
 			flags.dryrun = B_TRUE;
 			break;
+		case 'u':
+			flags.nomount = B_TRUE;
+			break;
 		case 'v':
 			flags.verbose = B_TRUE;
 			break;
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
index 4e8efb4e73a..9a13bbbf542 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -457,6 +457,9 @@ typedef struct recvflags {
 
 	/* byteswap flag is used internally; callers need not specify */
 	int byteswap : 1;
+
+	/* do not mount file systems as they are extracted (private) */
+	int nomount : 1;
 } recvflags_t;
 
 extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t,
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
index 5ee17fb8508..3516f6d60bd 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -2080,7 +2080,7 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags,
 
 	err = zfs_receive_impl(hdl, tosnap, flags, infd, stream_avl, &top_zfs);
 
-	if (err == 0 && top_zfs) {
+	if (err == 0 && !flags.nomount && top_zfs) {
 		zfs_handle_t *zhp;
 		prop_changelist_t *clp;
 

From 66be3718aa0ddfdec3989d78cf1e3512d89aaef6 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sun, 3 Jan 2010 02:58:05 +0000
Subject: [PATCH 1004/2592] MFC r200724:

Apply fix for Solaris bug  6462803 zfs snapshot -r failed because
filesystem was busy.

PR:		kern/141387
Submitted by:	mm
Approved by:	pjd
Obtained from:	OpenSolaris (onnv 8989:cfce31f4eebf)
---
 cddl/contrib/opensolaris/cmd/zdb/zdb_il.c     | 10 ++--
 .../opensolaris/uts/common/fs/zfs/sys/zil.h   | 10 +++-
 .../opensolaris/uts/common/fs/zfs/zil.c       | 57 ++++++++++++-------
 3 files changed, 49 insertions(+), 28 deletions(-)

diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c b/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
index 02d35a05033..cc08ef51485 100644
--- a/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Print intent log header and statistics.
  */
@@ -345,8 +343,10 @@ dump_intent_log(zilog_t *zilog)
 	if (zh->zh_log.blk_birth == 0 || verbose < 2)
 		return;
 
-	(void) printf("\n    ZIL header: claim_txg %llu, seq %llu\n",
-	    (u_longlong_t)zh->zh_claim_txg, (u_longlong_t)zh->zh_replay_seq);
+	(void) printf("\n    ZIL header: claim_txg %llu, claim_seq %llu",
+	    (u_longlong_t)zh->zh_claim_txg, (u_longlong_t)zh->zh_claim_seq);
+	(void) printf(" replay_seq %llu, flags 0x%llx\n",
+	    (u_longlong_t)zh->zh_replay_seq, (u_longlong_t)zh->zh_flags);
 
 	if (verbose >= 4)
 		print_log_bp(&zh->zh_log, "\n\tfirst block: ");
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
index 4d02d14f707..5212aafceae 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -56,9 +56,15 @@ typedef struct zil_header {
 	uint64_t zh_replay_seq;	/* highest replayed sequence number */
 	blkptr_t zh_log;	/* log chain */
 	uint64_t zh_claim_seq;	/* highest claimed sequence number */
-	uint64_t zh_pad[5];
+	uint64_t zh_flags;	/* header flags */
+	uint64_t zh_pad[4];
 } zil_header_t;
 
+/*
+ * zh_flags bit settings
+ */
+#define	ZIL_REPLAY_NEEDED 0x1	/* replay needed - internal only */
+
 /*
  * Log block trailer - structure at the end of the header and each log block
  *
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
index a7c2b377ebc..4455fb86bd1 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
@@ -502,6 +502,25 @@ zil_rollback_destroy(zilog_t *zilog, dmu_tx_t *tx)
 	    tx, zh->zh_claim_txg);
 }
 
+/*
+ * return true if the initial log block is not valid
+ */
+static boolean_t
+zil_empty(zilog_t *zilog)
+{
+	const zil_header_t *zh = zilog->zl_header;
+	arc_buf_t *abuf = NULL;
+
+	if (BP_IS_HOLE(&zh->zh_log))
+		return (B_TRUE);
+
+	if (zil_read_log_block(zilog, &zh->zh_log, &abuf) != 0)
+		return (B_TRUE);
+
+	VERIFY(arc_buf_remove_ref(abuf, &abuf) == 1);
+	return (B_FALSE);
+}
+
 int
 zil_claim(char *osname, void *txarg)
 {
@@ -521,6 +540,21 @@ zil_claim(char *osname, void *txarg)
 	zilog = dmu_objset_zil(os);
 	zh = zil_header_in_syncing_context(zilog);
 
+	/*
+	 * Record here whether the zil has any records to replay.
+	 * If the header block pointer is null or the block points
+	 * to the stubby then we know there are no valid log records.
+	 * We use the header to store this state as the the zilog gets
+	 * freed later in dmu_objset_close().
+	 * The flags (and the rest of the header fields) are cleared in
+	 * zil_sync() as a result of a zil_destroy(), after replaying the log.
+	 *
+	 * Note, the intent log can be empty but still need the
+	 * stubby to be claimed.
+	 */
+	if (!zil_empty(zilog))
+		zh->zh_flags |= ZIL_REPLAY_NEEDED;
+
 	/*
 	 * Claim all log blocks if we haven't already done so, and remember
 	 * the highest claimed sequence number.  This ensures that if we can
@@ -1344,25 +1378,6 @@ zil_free(zilog_t *zilog)
 	kmem_free(zilog, sizeof (zilog_t));
 }
 
-/*
- * return true if the initial log block is not valid
- */
-static boolean_t
-zil_empty(zilog_t *zilog)
-{
-	const zil_header_t *zh = zilog->zl_header;
-	arc_buf_t *abuf = NULL;
-
-	if (BP_IS_HOLE(&zh->zh_log))
-		return (B_TRUE);
-
-	if (zil_read_log_block(zilog, &zh->zh_log, &abuf) != 0)
-		return (B_TRUE);
-
-	VERIFY(arc_buf_remove_ref(abuf, &abuf) == 1);
-	return (B_FALSE);
-}
-
 /*
  * Open an intent log.
  */
@@ -1418,7 +1433,7 @@ zil_suspend(zilog_t *zilog)
 	const zil_header_t *zh = zilog->zl_header;
 
 	mutex_enter(&zilog->zl_lock);
-	if (zh->zh_claim_txg != 0) {		/* unplayed log */
+	if (zh->zh_flags & ZIL_REPLAY_NEEDED) {		/* unplayed log */
 		mutex_exit(&zilog->zl_lock);
 		return (EBUSY);
 	}
@@ -1645,7 +1660,7 @@ zil_replay(objset_t *os, void *arg, uint64_t *txgp,
 	const zil_header_t *zh = zilog->zl_header;
 	zil_replay_arg_t zr;
 
-	if (zil_empty(zilog)) {
+	if ((zh->zh_flags & ZIL_REPLAY_NEEDED) == 0) {
 		zil_destroy(zilog, B_TRUE);
 		return;
 	}

From 617528f9abf18db0f9cbe28da57410ad361b2553 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sun, 3 Jan 2010 03:05:30 +0000
Subject: [PATCH 1005/2592] MFC r200726:

Apply fix for Solaris bug 6801979: zfs recv can fail with E2BIG
(onnv revision 8986)

PR:		kern/141355
Requested by:	mm
Submitted by:	pjd
Obtained from:	OpenSolaris
---
 .../uts/common/fs/zfs/dmu_object.c            | 40 ++++++++++++++--
 .../opensolaris/uts/common/fs/zfs/dmu_send.c  | 37 ++++++---------
 .../opensolaris/uts/common/fs/zfs/dnode.c     | 47 +++++--------------
 .../opensolaris/uts/common/fs/zfs/sys/dmu.h   |  4 +-
 4 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c
index 1b9247d66e6..25dfafd4f2c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include 
 #include 
 #include 
@@ -108,19 +106,51 @@ dmu_object_claim(objset_t *os, uint64_t object, dmu_object_type_t ot,
 
 int
 dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot,
-    int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+    int blocksize, dmu_object_type_t bonustype, int bonuslen)
 {
 	dnode_t *dn;
+	dmu_tx_t *tx;
+	int nblkptr;
 	int err;
 
-	if (object == DMU_META_DNODE_OBJECT && !dmu_tx_private_ok(tx))
+	if (object == DMU_META_DNODE_OBJECT)
 		return (EBADF);
 
 	err = dnode_hold_impl(os->os, object, DNODE_MUST_BE_ALLOCATED,
 	    FTAG, &dn);
 	if (err)
 		return (err);
+
+	if (dn->dn_type == ot && dn->dn_datablksz == blocksize &&
+	    dn->dn_bonustype == bonustype && dn->dn_bonuslen == bonuslen) {
+		/* nothing is changing, this is a noop */
+		dnode_rele(dn, FTAG);
+		return (0);
+	}
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_bonus(tx, object);
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err) {
+		dmu_tx_abort(tx);
+		dnode_rele(dn, FTAG);
+		return (err);
+	}
+
+	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
+
+	/*
+	 * If we are losing blkptrs or changing the block size this must
+	 * be a new file instance.   We must clear out the previous file
+	 * contents before we can change this type of metadata in the dnode.
+	 */
+	if (dn->dn_nblkptr > nblkptr || dn->dn_datablksz != blocksize)
+		dmu_free_long_range(os, object, 0, DMU_OBJECT_END);
+
 	dnode_reallocate(dn, ot, blocksize, bonustype, bonuslen, tx);
+
+	dmu_tx_commit(tx);
+
 	dnode_rele(dn, FTAG);
 
 	return (0);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
index 15bb65d6a44..2e85c52b2b1 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -829,11 +829,6 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 	int err;
 	dmu_tx_t *tx;
 
-	err = dmu_object_info(os, drro->drr_object, NULL);
-
-	if (err != 0 && err != ENOENT)
-		return (EINVAL);
-
 	if (drro->drr_type == DMU_OT_NONE ||
 	    drro->drr_type >= DMU_OT_NUMTYPES ||
 	    drro->drr_bonustype >= DMU_OT_NUMTYPES ||
@@ -846,12 +841,15 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 		return (EINVAL);
 	}
 
-	tx = dmu_tx_create(os);
+	err = dmu_object_info(os, drro->drr_object, NULL);
+
+	if (err != 0 && err != ENOENT)
+		return (EINVAL);
 
 	if (err == ENOENT) {
 		/* currently free, want to be allocated */
+		tx = dmu_tx_create(os);
 		dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
-		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, 1);
 		err = dmu_tx_assign(tx, TXG_WAIT);
 		if (err) {
 			dmu_tx_abort(tx);
@@ -860,28 +858,23 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 		err = dmu_object_claim(os, drro->drr_object,
 		    drro->drr_type, drro->drr_blksz,
 		    drro->drr_bonustype, drro->drr_bonuslen, tx);
+		dmu_tx_commit(tx);
 	} else {
 		/* currently allocated, want to be allocated */
-		dmu_tx_hold_bonus(tx, drro->drr_object);
-		/*
-		 * We may change blocksize and delete old content,
-		 * so need to hold_write and hold_free.
-		 */
-		dmu_tx_hold_write(tx, drro->drr_object, 0, 1);
-		dmu_tx_hold_free(tx, drro->drr_object, 0, DMU_OBJECT_END);
-		err = dmu_tx_assign(tx, TXG_WAIT);
-		if (err) {
-			dmu_tx_abort(tx);
-			return (err);
-		}
 
 		err = dmu_object_reclaim(os, drro->drr_object,
 		    drro->drr_type, drro->drr_blksz,
-		    drro->drr_bonustype, drro->drr_bonuslen, tx);
+		    drro->drr_bonustype, drro->drr_bonuslen);
 	}
-	if (err) {
-		dmu_tx_commit(tx);
+	if (err)
 		return (EINVAL);
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_bonus(tx, drro->drr_object);
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err) {
+		dmu_tx_abort(tx);
+		return (err);
 	}
 
 	dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksum, tx);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
index 604d52d8bb5..3fe95b08d28 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
@@ -415,8 +415,7 @@ void
 dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
     dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
 {
-	int i, nblkptr;
-	dmu_buf_impl_t *db = NULL;
+	int nblkptr;
 
 	ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
 	ASSERT3U(blocksize, <=, SPA_MAXBLOCKSIZE);
@@ -428,42 +427,25 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
 	ASSERT3U(bonustype, <, DMU_OT_NUMTYPES);
 	ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
 
-	for (i = 0; i < TXG_SIZE; i++)
-		ASSERT(!list_link_active(&dn->dn_dirty_link[i]));
-
 	/* clean up any unreferenced dbufs */
 	dnode_evict_dbufs(dn);
-	ASSERT3P(list_head(&dn->dn_dbufs), ==, NULL);
 
-	/*
-	 * XXX I should really have a generation number to tell if we
-	 * need to do this...
-	 */
-	if (blocksize != dn->dn_datablksz ||
-	    dn->dn_bonustype != bonustype || dn->dn_bonuslen != bonuslen) {
-		/* free all old data */
-		dnode_free_range(dn, 0, -1ULL, tx);
-	}
-
-	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
-
-	/* change blocksize */
 	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
-	if (blocksize != dn->dn_datablksz &&
-	    (!BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
-	    list_head(&dn->dn_dbufs) != NULL)) {
-		db = dbuf_hold(dn, 0, FTAG);
-		dbuf_new_size(db, blocksize, tx);
-	}
-	dnode_setdblksz(dn, blocksize);
 	dnode_setdirty(dn, tx);
-	dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
-	dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
+	if (dn->dn_datablksz != blocksize) {
+		/* change blocksize */
+		ASSERT(dn->dn_maxblkid == 0 &&
+		    (BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
+		    dnode_block_freed(dn, 0)));
+		dnode_setdblksz(dn, blocksize);
+		dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
+	}
+	if (dn->dn_bonuslen != bonuslen)
+		dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
+	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
 	if (dn->dn_nblkptr != nblkptr)
 		dn->dn_next_nblkptr[tx->tx_txg&TXG_MASK] = nblkptr;
 	rw_exit(&dn->dn_struct_rwlock);
-	if (db)
-		dbuf_rele(db, FTAG);
 
 	/* change type */
 	dn->dn_type = ot;
@@ -1187,11 +1169,6 @@ dnode_block_freed(dnode_t *dn, uint64_t blkid)
 	if (dn->dn_free_txg)
 		return (TRUE);
 
-	/*
-	 * If dn_datablkshift is not set, then there's only a single
-	 * block, in which case there will never be a free range so it
-	 * won't matter.
-	 */
 	range_tofind.fr_blkid = blkid;
 	mutex_enter(&dn->dn_mtx);
 	for (i = 0; i < TXG_SIZE; i++) {
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
index 4535c686407..7befe96bc32 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -237,7 +237,7 @@ uint64_t dmu_object_alloc(objset_t *os, dmu_object_type_t ot,
 int dmu_object_claim(objset_t *os, uint64_t object, dmu_object_type_t ot,
     int blocksize, dmu_object_type_t bonus_type, int bonus_len, dmu_tx_t *tx);
 int dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot,
-    int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
+    int blocksize, dmu_object_type_t bonustype, int bonuslen);
 
 /*
  * Free an object from this objset.

From faeec9b29abd0dd42837b248daafc0892a736393 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sun, 3 Jan 2010 03:10:28 +0000
Subject: [PATCH 1006/2592] MFC r200727:

Apply fix for Solaris bug 6764159: restore_object() makes a call
that can block while having a tx open but not yet committed
(onnv revision 7994)

Submitted by:	mm
Approved by:	pjd
Obtained from:	OpenSolaris
---
 .../opensolaris/uts/common/fs/zfs/dmu_send.c     | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
index 2e85c52b2b1..98032653227 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -828,6 +828,7 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 {
 	int err;
 	dmu_tx_t *tx;
+	void *data = NULL;
 
 	if (drro->drr_type == DMU_OT_NONE ||
 	    drro->drr_type >= DMU_OT_NUMTYPES ||
@@ -869,6 +870,12 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 	if (err)
 		return (EINVAL);
 
+	if (drro->drr_bonuslen) {
+		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
+		if (ra->err)
+			return (ra->err);
+	}
+
 	tx = dmu_tx_create(os);
 	dmu_tx_hold_bonus(tx, drro->drr_object);
 	err = dmu_tx_assign(tx, TXG_WAIT);
@@ -880,18 +887,13 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 	dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksum, tx);
 	dmu_object_set_compress(os, drro->drr_object, drro->drr_compress, tx);
 
-	if (drro->drr_bonuslen) {
+	if (data != NULL) {
 		dmu_buf_t *db;
-		void *data;
+
 		VERIFY(0 == dmu_bonus_hold(os, drro->drr_object, FTAG, &db));
 		dmu_buf_will_dirty(db, tx);
 
 		ASSERT3U(db->db_size, >=, drro->drr_bonuslen);
-		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
-		if (data == NULL) {
-			dmu_tx_commit(tx);
-			return (ra->err);
-		}
 		bcopy(data, db->db_data, drro->drr_bonuslen);
 		if (ra->byteswap) {
 			dmu_ot[drro->drr_bonustype].ot_byteswap(db->db_data,

From 90ad4a8e4c34fffa07af517a61df7c18883ba691 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Mon, 4 Jan 2010 01:07:32 +0000
Subject: [PATCH 1007/2592] MFC r200793:

Plug a memory leak.

PR:		bin/141836
Submitted by:	Henning Petersen 
---
 usr.bin/finger/finger.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/usr.bin/finger/finger.c b/usr.bin/finger/finger.c
index b2787520c48..944415e0829 100644
--- a/usr.bin/finger/finger.c
+++ b/usr.bin/finger/finger.c
@@ -373,6 +373,7 @@ net:	for (p = nargv; *p;) {
 		    printf("\n");
 	}
 
+	free(used);
 	if (entries == 0)
 		return;
 

From e8a4477a720530dc629225c1c990a2de723af810 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Mon, 4 Jan 2010 01:08:27 +0000
Subject: [PATCH 1008/2592] Plug a memory leak.

PR:		bin/141835
Submitted by:	Henning Petersen 
---
 bin/pax/sel_subs.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bin/pax/sel_subs.c b/bin/pax/sel_subs.c
index 87fba2ff008..bd5c560afc5 100644
--- a/bin/pax/sel_subs.c
+++ b/bin/pax/sel_subs.c
@@ -396,6 +396,7 @@ trng_add(char *str)
 			default:
 				paxwarn(1, "Bad option %c with time range %s",
 				    *flgpt, str);
+				free(pt);
 				goto out;
 			}
 			++flgpt;

From ca22ec93f0a23d240fa50d266372828da8023757 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Mon, 4 Jan 2010 01:09:59 +0000
Subject: [PATCH 1009/2592] MFC r201137:

Grammar fix.

Submitted by:	Kenyon Ralph 
---
 lib/libexpat/libbsdxml.3 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libexpat/libbsdxml.3 b/lib/libexpat/libbsdxml.3
index f687518517b..555bc9ae1b4 100644
--- a/lib/libexpat/libbsdxml.3
+++ b/lib/libexpat/libbsdxml.3
@@ -40,7 +40,7 @@ library is a verbatim copy of the eXpat XML library version 2.0.1.
 .Pp
 The
 .Nm
-library is intended to use within the
+library is intended to be used within the
 .Fx
 base system only.
 Use of the

From 7231db3aea38b424a5e57118505b72e58fe3db32 Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Mon, 4 Jan 2010 14:35:36 +0000
Subject: [PATCH 1010/2592] MFC r198940:

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
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 30feab007626c6623159ee49210f9af313de8387 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Mon, 4 Jan 2010 15:05:11 +0000
Subject: [PATCH 1011/2592] MFC r200027: Teach an IPv6 to send_pkt() and
 ipfw_tick(). It fixes the issue which keep-alive doesn't work for an IPv6.

---
 sys/netinet/ipfw/ip_fw2.c | 280 +++++++++++++++++++++++---------------
 1 file changed, 167 insertions(+), 113 deletions(-)

diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c
index d5d49ca80e2..0c33b3b68d6 100644
--- a/sys/netinet/ipfw/ip_fw2.c
+++ b/sys/netinet/ipfw/ip_fw2.c
@@ -94,6 +94,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #ifdef INET6
 #include 
+#include 
 #endif
 
 #include 	/* XXX for in_cksum */
@@ -251,6 +252,10 @@ static struct mtx ipfw_dyn_mtx;		/* mutex guarding dynamic rules */
 #define	IPFW_DYN_UNLOCK()	mtx_unlock(&ipfw_dyn_mtx)
 #define	IPFW_DYN_LOCK_ASSERT()	mtx_assert(&ipfw_dyn_mtx, MA_OWNED)
 
+static struct mbuf *send_pkt(struct mbuf *, struct ipfw_flow_id *,
+    u_int32_t, u_int32_t, int);
+
+
 /*
  * Timeouts for various events in handing dynamic rules.
  */
@@ -710,60 +715,18 @@ send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr *ip6)
 	m = args->m;
 	if (code == ICMP6_UNREACH_RST && args->f_id.proto == IPPROTO_TCP) {
 		struct tcphdr *tcp;
-		tcp_seq ack, seq;
-		int flags;
-		struct {
-			struct ip6_hdr ip6;
-			struct tcphdr th;
-		} ti;
 		tcp = (struct tcphdr *)((char *)ip6 + hlen);
 
-		if ((tcp->th_flags & TH_RST) != 0) {
-			m_freem(m);
-			args->m = NULL;
-			return;
+		if ((tcp->th_flags & TH_RST) == 0) {
+			struct mbuf *m0;
+			m0 = send_pkt(args->m, &(args->f_id),
+			    ntohl(tcp->th_seq), ntohl(tcp->th_ack),
+			    tcp->th_flags | TH_RST);
+			if (m0 != NULL)
+				ip6_output(m0, NULL, NULL, 0, NULL, NULL,
+				    NULL);
 		}
-
-		ti.ip6 = *ip6;
-		ti.th = *tcp;
-		ti.th.th_seq = ntohl(ti.th.th_seq);
-		ti.th.th_ack = ntohl(ti.th.th_ack);
-		ti.ip6.ip6_nxt = IPPROTO_TCP;
-
-		if (ti.th.th_flags & TH_ACK) {
-			ack = 0;
-			seq = ti.th.th_ack;
-			flags = TH_RST;
-		} else {
-			ack = ti.th.th_seq;
-			if ((m->m_flags & M_PKTHDR) != 0) {
-				/*
-				 * total new data to ACK is:
-				 * total packet length,
-				 * minus the header length,
-				 * minus the tcp header length.
-				 */
-				ack += m->m_pkthdr.len - hlen
-					- (ti.th.th_off << 2);
-			} else if (ip6->ip6_plen) {
-				ack += ntohs(ip6->ip6_plen) + sizeof(*ip6) -
-				    hlen - (ti.th.th_off << 2);
-			} else {
-				m_freem(m);
-				return;
-			}
-			if (tcp->th_flags & TH_SYN)
-				ack++;
-			seq = 0;
-			flags = TH_RST|TH_ACK;
-		}
-		bcopy(&ti, ip6, sizeof(ti));
-		/*
-		 * m is only used to recycle the mbuf
-		 * The data in it is never read so we don't need
-		 * to correct the offsets or anything
-		 */
-		tcp_respond(NULL, ip6, tcp, m, ack, seq, flags);
+		m_freem(m);
 	} else if (code != ICMP6_UNREACH_RST) { /* Send an ICMPv6 unreach. */
 #if 0
 		/*
@@ -1651,13 +1614,16 @@ send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
     u_int32_t ack, int flags)
 {
 	struct mbuf *m;
-	struct ip *ip;
-	struct tcphdr *tcp;
+	int len, dir;
+	struct ip *h = NULL;		/* stupid compiler */
+#ifdef INET6
+	struct ip6_hdr *h6 = NULL;
+#endif
+	struct tcphdr *th = NULL;
 
 	MGETHDR(m, M_DONTWAIT, MT_DATA);
-	if (m == 0)
+	if (m == NULL)
 		return (NULL);
-	m->m_pkthdr.rcvif = (struct ifnet *)0;
 
 	M_SETFIB(m, id->fib);
 #ifdef MAC
@@ -1669,67 +1635,118 @@ send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
 	(void)replyto;		/* don't warn about unused arg */
 #endif
 
-	m->m_pkthdr.len = m->m_len = sizeof(struct ip) + sizeof(struct tcphdr);
-	m->m_data += max_linkhdr;
+	switch (id->addr_type) {
+	case 4:
+		len = sizeof(struct ip) + sizeof(struct tcphdr);
+		break;
+#ifdef INET6
+	case 6:
+		len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
+		break;
+#endif
+	default:
+		/* XXX: log me?!? */
+		m_freem(m);
+		return (NULL);
+	}
+	dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN);
 
-	ip = mtod(m, struct ip *);
-	bzero(ip, m->m_len);
-	tcp = (struct tcphdr *)(ip + 1); /* no IP options */
-	ip->ip_p = IPPROTO_TCP;
-	tcp->th_off = 5;
-	/*
-	 * Assume we are sending a RST (or a keepalive in the reverse
-	 * direction), swap src and destination addresses and ports.
-	 */
-	ip->ip_src.s_addr = htonl(id->dst_ip);
-	ip->ip_dst.s_addr = htonl(id->src_ip);
-	tcp->th_sport = htons(id->dst_port);
-	tcp->th_dport = htons(id->src_port);
-	if (flags & TH_RST) {	/* we are sending a RST */
+	m->m_data += max_linkhdr;
+	m->m_flags |= M_SKIP_FIREWALL;
+	m->m_pkthdr.len = m->m_len = len;
+	m->m_pkthdr.rcvif = NULL;
+	bzero(m->m_data, len);
+
+	switch (id->addr_type) {
+	case 4:
+		h = mtod(m, struct ip *);
+
+		/* prepare for checksum */
+		h->ip_p = IPPROTO_TCP;
+		h->ip_len = htons(sizeof(struct tcphdr));
+		if (dir) {
+			h->ip_src.s_addr = htonl(id->src_ip);
+			h->ip_dst.s_addr = htonl(id->dst_ip);
+		} else {
+			h->ip_src.s_addr = htonl(id->dst_ip);
+			h->ip_dst.s_addr = htonl(id->src_ip);
+		}
+
+		th = (struct tcphdr *)(h + 1);
+		break;
+#ifdef INET6
+	case 6:
+		h6 = mtod(m, struct ip6_hdr *);
+
+		/* prepare for checksum */
+		h6->ip6_nxt = IPPROTO_TCP;
+		h6->ip6_plen = htons(sizeof(struct tcphdr));
+		if (dir) {
+			h6->ip6_src = id->src_ip6;
+			h6->ip6_dst = id->dst_ip6;
+		} else {
+			h6->ip6_src = id->dst_ip6;
+			h6->ip6_dst = id->src_ip6;
+		}
+
+		th = (struct tcphdr *)(h6 + 1);
+		break;
+#endif
+	}
+
+	if (dir) {
+		th->th_sport = htons(id->src_port);
+		th->th_dport = htons(id->dst_port);
+	} else {
+		th->th_sport = htons(id->dst_port);
+		th->th_dport = htons(id->src_port);
+	}
+	th->th_off = sizeof(struct tcphdr) >> 2;
+
+	if (flags & TH_RST) {
 		if (flags & TH_ACK) {
-			tcp->th_seq = htonl(ack);
-			tcp->th_ack = htonl(0);
-			tcp->th_flags = TH_RST;
+			th->th_seq = htonl(ack);
+			th->th_flags = TH_RST;
 		} else {
 			if (flags & TH_SYN)
 				seq++;
-			tcp->th_seq = htonl(0);
-			tcp->th_ack = htonl(seq);
-			tcp->th_flags = TH_RST | TH_ACK;
+			th->th_ack = htonl(seq);
+			th->th_flags = TH_RST | TH_ACK;
 		}
 	} else {
 		/*
-		 * We are sending a keepalive. flags & TH_SYN determines
-		 * the direction, forward if set, reverse if clear.
-		 * NOTE: seq and ack are always assumed to be correct
-		 * as set by the caller. This may be confusing...
+		 * Keepalive - use caller provided sequence numbers
 		 */
-		if (flags & TH_SYN) {
-			/*
-			 * we have to rewrite the correct addresses!
-			 */
-			ip->ip_dst.s_addr = htonl(id->dst_ip);
-			ip->ip_src.s_addr = htonl(id->src_ip);
-			tcp->th_dport = htons(id->dst_port);
-			tcp->th_sport = htons(id->src_port);
-		}
-		tcp->th_seq = htonl(seq);
-		tcp->th_ack = htonl(ack);
-		tcp->th_flags = TH_ACK;
+		th->th_seq = htonl(seq);
+		th->th_ack = htonl(ack);
+		th->th_flags = TH_ACK;
 	}
-	/*
-	 * set ip_len to the payload size so we can compute
-	 * the tcp checksum on the pseudoheader
-	 * XXX check this, could save a couple of words ?
-	 */
-	ip->ip_len = htons(sizeof(struct tcphdr));
-	tcp->th_sum = in_cksum(m, m->m_pkthdr.len);
-	/*
-	 * now fill fields left out earlier
-	 */
-	ip->ip_ttl = V_ip_defttl;
-	ip->ip_len = m->m_pkthdr.len;
-	m->m_flags |= M_SKIP_FIREWALL;
+
+	switch (id->addr_type) {
+	case 4:
+		th->th_sum = in_cksum(m, len);
+
+		/* finish the ip header */
+		h->ip_v = 4;
+		h->ip_hl = sizeof(*h) >> 2;
+		h->ip_tos = IPTOS_LOWDELAY;
+		h->ip_off = 0;
+		h->ip_len = len;
+		h->ip_ttl = V_ip_defttl;
+		h->ip_sum = 0;
+		break;
+#ifdef INET6
+	case 6:
+		th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6),
+		    sizeof(struct tcphdr));
+
+		/* finish the ip6 header */
+		h6->ip6_vfc |= IPV6_VERSION;
+		h6->ip6_hlim = IPV6_DEFHLIM;
+		break;
+#endif
+	}
+
 	return (m);
 }
 
@@ -4529,13 +4546,16 @@ static void
 ipfw_tick(void * vnetx) 
 {
 	struct mbuf *m0, *m, *mnext, **mtailp;
+#ifdef INET6
+	struct mbuf *m6, **m6_tailp;
+#endif
 	int i;
 	ipfw_dyn_rule *q;
 #ifdef VIMAGE
 	struct vnet *vp = vnetx;
 #endif
 
-        CURVNET_SET(vp);
+	CURVNET_SET(vp);
 	if (V_dyn_keepalive == 0 || V_ipfw_dyn_v == NULL || V_dyn_count == 0)
 		goto done;
 
@@ -4547,6 +4567,10 @@ ipfw_tick(void * vnetx)
 	 */
 	m0 = NULL;
 	mtailp = &m0;
+#ifdef INET6
+	m6 = NULL;
+	m6_tailp = &m6;
+#endif
 	IPFW_DYN_LOCK();
 	for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
 		for (q = V_ipfw_dyn_v[i] ; q ; q = q->next ) {
@@ -4562,14 +4586,37 @@ ipfw_tick(void * vnetx)
 			if (TIME_LEQ(q->expire, time_uptime))
 				continue;	/* too late, rule expired */
 
-			*mtailp = send_pkt(NULL, &(q->id), q->ack_rev - 1,
+			m = send_pkt(NULL, &(q->id), q->ack_rev - 1,
 				q->ack_fwd, TH_SYN);
-			if (*mtailp != NULL)
-				mtailp = &(*mtailp)->m_nextpkt;
-			*mtailp = send_pkt(NULL, &(q->id), q->ack_fwd - 1,
+			mnext = send_pkt(NULL, &(q->id), q->ack_fwd - 1,
 				q->ack_rev, 0);
-			if (*mtailp != NULL)
-				mtailp = &(*mtailp)->m_nextpkt;
+
+			switch (q->id.addr_type) {
+			case 4:
+				if (m != NULL) {
+					*mtailp = m;
+					mtailp = &(*mtailp)->m_nextpkt;
+				}
+				if (mnext != NULL) {
+					*mtailp = mnext;
+					mtailp = &(*mtailp)->m_nextpkt;
+				}
+				break;
+#ifdef INET6
+			case 6:
+				if (m != NULL) {
+					*m6_tailp = m;
+					m6_tailp = &(*m6_tailp)->m_nextpkt;
+				}
+				if (mnext != NULL) {
+					*m6_tailp = mnext;
+					m6_tailp = &(*m6_tailp)->m_nextpkt;
+				}
+				break;
+#endif
+			}
+
+			m = mnext = NULL;
 		}
 	}
 	IPFW_DYN_UNLOCK();
@@ -4578,6 +4625,13 @@ ipfw_tick(void * vnetx)
 		m->m_nextpkt = NULL;
 		ip_output(m, NULL, NULL, 0, NULL, NULL);
 	}
+#ifdef INET6
+	for (m = mnext = m6; m != NULL; m = mnext) {
+		mnext = m->m_nextpkt;
+		m->m_nextpkt = NULL;
+		ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
+	}
+#endif
 done:
 	callout_reset(&V_ipfw_timeout, V_dyn_keepalive_period * hz,
 		      ipfw_tick, vnetx);

From 479812d91cb095d542f704d4c86457d6b3edff14 Mon Sep 17 00:00:00 2001
From: Hajimu UMEMOTO 
Date: Mon, 4 Jan 2010 15:22:38 +0000
Subject: [PATCH 1012/2592] MFC r200055, r200102: - Teach an IPv6 to the debug
 prints. - Use INET_ADDRSTRLEN and INET6_ADDRSTRLEN rather than hard   coded
 number.

---
 sys/netinet/ipfw/ip_fw2.c | 100 +++++++++++++++++++++++++++++++-------
 1 file changed, 83 insertions(+), 17 deletions(-)

diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c
index 0c33b3b68d6..4c08bc5d17b 100644
--- a/sys/netinet/ipfw/ip_fw2.c
+++ b/sys/netinet/ipfw/ip_fw2.c
@@ -899,7 +899,11 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
 
 	} else {
 		int len;
-		char src[48], dst[48];
+#ifdef INET6
+		char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
+#else
+		char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
+#endif
 		struct icmphdr *icmp;
 		struct tcphdr *tcp;
 		struct udphdr *udp;
@@ -1050,6 +1054,32 @@ hash_packet(struct ipfw_flow_id *id)
 	return i;
 }
 
+static __inline void
+unlink_dyn_rule_print(struct ipfw_flow_id *id)
+{
+	struct in_addr da;
+#ifdef INET6
+	char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
+#else
+	char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
+#endif
+
+#ifdef INET6
+	if (IS_IP6_FLOW_ID(id)) {
+		ip6_sprintf(src, &id->src_ip6);
+		ip6_sprintf(dst, &id->dst_ip6);
+	} else
+#endif
+	{
+		da.s_addr = htonl(id->src_ip);
+		inet_ntoa_r(da, src);
+		da.s_addr = htonl(id->dst_ip);
+		inet_ntoa_r(da, dst);
+	}
+	printf("ipfw: unlink entry %s %d -> %s %d, %d left\n",
+	    src, id->src_port, dst, id->dst_port, V_dyn_count - 1);
+}
+
 /**
  * unlink a dynamic rule from a chain. prev is a pointer to
  * the previous one, q is a pointer to the rule to delete,
@@ -1062,9 +1092,7 @@ hash_packet(struct ipfw_flow_id *id)
 	/* remove a refcount to the parent */				\
 	if (q->dyn_type == O_LIMIT)					\
 		q->parent->count--;					\
-	DEB(printf("ipfw: unlink entry 0x%08x %d -> 0x%08x %d, %d left\n",\
-		(q->id.src_ip), (q->id.src_port),			\
-		(q->id.dst_ip), (q->id.dst_port), V_dyn_count-1 ); )	\
+	DEB(unlink_dyn_rule_print(&q->id);)				\
 	if (prev != NULL)						\
 		prev->next = q = q->next;				\
 	else								\
@@ -1394,11 +1422,32 @@ add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
 	r->next = V_ipfw_dyn_v[i];
 	V_ipfw_dyn_v[i] = r;
 	V_dyn_count++;
-	DEB(printf("ipfw: add dyn entry ty %d 0x%08x %d -> 0x%08x %d, total %d\n",
-	   dyn_type,
-	   (r->id.src_ip), (r->id.src_port),
-	   (r->id.dst_ip), (r->id.dst_port),
-	   V_dyn_count ); )
+	DEB({
+		struct in_addr da;
+#ifdef INET6
+		char src[INET6_ADDRSTRLEN];
+		char dst[INET6_ADDRSTRLEN];
+#else
+		char src[INET_ADDRSTRLEN];
+		char dst[INET_ADDRSTRLEN];
+#endif
+
+#ifdef INET6
+		if (IS_IP6_FLOW_ID(&(r->id))) {
+			ip6_sprintf(src, &r->id.src_ip6);
+			ip6_sprintf(dst, &r->id.dst_ip6);
+		} else
+#endif
+		{
+			da.s_addr = htonl(r->id.src_ip);
+			inet_ntoa_r(da, src);
+			da.s_addr = htonl(r->id.dst_ip);
+			inet_ntoa_r(da, dst);
+		}
+		printf("ipfw: add dyn entry ty %d %s %d -> %s %d, total %d\n",
+		    dyn_type, src, r->id.src_port, dst, r->id.dst_port,
+		    V_dyn_count);
+	})
 	return r;
 }
 
@@ -1455,20 +1504,37 @@ install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
 	static int last_log;
 	ipfw_dyn_rule *q;
 	struct in_addr da;
-	char src[48], dst[48];
+#ifdef INET6
+	char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
+#else
+	char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
+#endif
 
 	src[0] = '\0';
 	dst[0] = '\0';
 
-	DEB(
-	printf("ipfw: %s: type %d 0x%08x %u -> 0x%08x %u\n",
-	    __func__, cmd->o.opcode,
-	    (args->f_id.src_ip), (args->f_id.src_port),
-	    (args->f_id.dst_ip), (args->f_id.dst_port));
-	)
-
 	IPFW_DYN_LOCK();
 
+	DEB(
+#ifdef INET6
+	if (IS_IP6_FLOW_ID(&(args->f_id))) {
+		ip6_sprintf(src, &args->f_id.src_ip6);
+		ip6_sprintf(dst, &args->f_id.dst_ip6);
+	} else
+#endif
+	{
+		da.s_addr = htonl(args->f_id.src_ip);
+		inet_ntoa_r(da, src);
+		da.s_addr = htonl(args->f_id.dst_ip);
+		inet_ntoa_r(da, dst);
+	}
+	printf("ipfw: %s: type %d %s %u -> %s %u\n",
+	    __func__, cmd->o.opcode, src, args->f_id.src_port,
+	    dst, args->f_id.dst_port);
+	src[0] = '\0';
+	dst[0] = '\0';
+	)
+
 	q = lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
 
 	if (q != NULL) {	/* should never occur */

From aed7a0f87878c3021ea9e36870d3956ffc36ba21 Mon Sep 17 00:00:00 2001
From: Shteryana Shopova 
Date: Mon, 4 Jan 2010 15:58:36 +0000
Subject: [PATCH 1013/2592] MFC r201254: Make sure the multicast forwarding
 cache entry's stall queue is properly initialized before trying to insert an
 entry into it.

PR:		kern/142052
Reviewed by:	bms
---
 sys/netinet/ip_mroute.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 39c71b06c06..48d5ffc03cb 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -1384,6 +1384,15 @@ fail:
 	    rt->mfc_rp.s_addr = INADDR_ANY;
 	    rt->mfc_bw_meter = NULL;
 
+	    /* initialize pkt counters per src-grp */
+	    rt->mfc_pkt_cnt = 0;
+	    rt->mfc_byte_cnt = 0;
+	    rt->mfc_wrong_if = 0;
+	    timevalclear(&rt->mfc_last_assert);
+
+	    TAILQ_INIT(&rt->mfc_stall);
+	    rt->mfc_nstall = 0;
+
 	    /* link into table */
 	    LIST_INSERT_HEAD(&mfchashtbl[hash], rt, mfc_hash);
 	    TAILQ_INSERT_HEAD(&rt->mfc_stall, rte, rte_link);

From 618a79fc2b4c022d16aaaa6f0eee31ab71976988 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Mon, 4 Jan 2010 19:27:17 +0000
Subject: [PATCH 1014/2592] MFC 201216: Remove a trailing reference to the
 obsolete vaps_ variable.

---
 etc/network.subr | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/etc/network.subr b/etc/network.subr
index 36bfa54cef4..5f02714e44c 100644
--- a/etc/network.subr
+++ b/etc/network.subr
@@ -568,7 +568,7 @@ childif_destroy()
 {
 	local cfg child child_wlans ifn
 
-	child_wlans="`get_if_var $ifn wlans_IF` `get_if_var $ifn vaps_IF`"
+	child_wlans=`get_if_var $ifn wlans_IF`
 	for child in ${child_wlans}; do
 		ifconfig $child destroy && cfg=0
 	done

From 3da1f178b520f2f1c77b7c421a63cfa475858200 Mon Sep 17 00:00:00 2001
From: Ken Smith 
Date: Mon, 4 Jan 2010 19:57:35 +0000
Subject: [PATCH 1015/2592] MFC r200775:

	Add FreeBSD- to the beginning of the ISO image filenames.
---
 release/Makefile | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/release/Makefile b/release/Makefile
index ce70afd0dd8..87d08a905e4 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -1128,36 +1128,36 @@ iso.1:
 .if defined(CD_BOOT)
 	@sh ${.CURDIR}/${TARGET_ARCH}/mkisoimages.sh ${BOOTABLE} \
 	    FreeBSD_bootonly \
-	    ${CD}/${BUILDNAME}-${TARGET}-bootonly.iso ${CD_BOOT}
+	    ${CD}/FreeBSD-${BUILDNAME}-${TARGET}-bootonly.iso ${CD_BOOT}
 .endif
 	@sh ${.CURDIR}/${TARGET_ARCH}/mkisoimages.sh ${BOOTABLE} \
 	    FreeBSD_Install \
-	    ${CD}/${BUILDNAME}-${TARGET}-disc1.iso ${CD_DISC1} \
+	    ${CD}/FreeBSD-${BUILDNAME}-${TARGET}-disc1.iso ${CD_DISC1} \
 	    ${CD_DISC1_PKGS}
 	@sh ${.CURDIR}/${TARGET_ARCH}/mkisoimages.sh \
 	    FreeBSD_Packages \
-	    ${CD}/${BUILDNAME}-${TARGET}-disc2.iso ${CD_DISC2} \
+	    ${CD}/FreeBSD-${BUILDNAME}-${TARGET}-disc2.iso ${CD_DISC2} \
 	    ${CD_DISC2_PKGS}
 .if defined(MAKE_DVD)
 	@sh ${.CURDIR}/${TARGET_ARCH}/mkisoimages.sh ${BOOTABLE} \
 	    FreeBSD_Install \
-	    ${CD}/${BUILDNAME}-${TARGET}-dvd1.iso ${CD_DVD1} \
+	    ${CD}/FreeBSD-${BUILDNAME}-${TARGET}-dvd1.iso ${CD_DVD1} \
 	    ${CD_DVD1_PKGS}
 .endif
 .if !defined(NODOC)
 	@sh ${.CURDIR}/${TARGET_ARCH}/mkisoimages.sh \
 	    FreeBSD_Documentation \
-	    ${CD}/${BUILDNAME}-${TARGET}-disc3.iso ${CD_DOCS} \
+	    ${CD}/FreeBSD-${BUILDNAME}-${TARGET}-disc3.iso ${CD_DOCS} \
 	    ${CD_DOCS_PKGS}
 .endif
 .if defined(SEPARATE_LIVEFS)
 	@sh ${.CURDIR}/${TARGET_ARCH}/mkisoimages.sh ${BOOTABLE} \
 	    FreeBSD_LiveFS \
-	    ${CD}/${BUILDNAME}-${TARGET}-livefs.iso ${CD_LIVEFS}
+	    ${CD}/FreeBSD-${BUILDNAME}-${TARGET}-livefs.iso ${CD_LIVEFS}
 .endif
 	@echo "Generating MD5 and SHA256 sums..."
-	@(cd ${CD} && md5 *.iso > ${BUILDNAME}-${TARGET}-iso.CHECKSUM.MD5)
-	@(cd ${CD} && sha256 *.iso > ${BUILDNAME}-${TARGET}-iso.CHECKSUM.SHA256)
+	@(cd ${CD} && md5 *.iso > FreeBSD-${BUILDNAME}-${TARGET}-iso.CHECKSUM.MD5)
+	@(cd ${CD} && sha256 *.iso > FreeBSD-${BUILDNAME}-${TARGET}-iso.CHECKSUM.SHA256)
 	touch ${.TARGET}
 .else
 	@echo "Do not know how to create an ISO for ${TARGET_ARCH}."

From 1b1bff673f381cd2b33c37bdb66499ef6da0a3f2 Mon Sep 17 00:00:00 2001
From: Warner Losh 
Date: Mon, 4 Jan 2010 21:33:10 +0000
Subject: [PATCH 1016/2592] Revert 201158.  DEFAULTS isn't for this kind of
 thing.a

---
 sys/amd64/conf/DEFAULTS   | 7 -------
 sys/arm/conf/DEFAULTS     | 7 -------
 sys/i386/conf/DEFAULTS    | 7 -------
 sys/ia64/conf/DEFAULTS    | 7 -------
 sys/mips/conf/DEFAULTS    | 7 -------
 sys/pc98/conf/DEFAULTS    | 7 -------
 sys/powerpc/conf/DEFAULTS | 7 -------
 sys/sparc64/conf/DEFAULTS | 7 -------
 sys/sun4v/conf/DEFAULTS   | 7 -------
 9 files changed, 63 deletions(-)

diff --git a/sys/amd64/conf/DEFAULTS b/sys/amd64/conf/DEFAULTS
index d6d39b6c769..1fb52b34e0c 100644
--- a/sys/amd64/conf/DEFAULTS
+++ b/sys/amd64/conf/DEFAULTS
@@ -20,10 +20,3 @@ options 	GEOM_PART_BSD
 options 	GEOM_PART_EBR
 options 	GEOM_PART_EBR_COMPAT
 options 	GEOM_PART_MBR
-
-# Store the plain version of the configuration file in the kernel itself.
-# To store the entire file, including comments, put this in /etc/src.conf:
-# CONFIGARGS=	-C
-# See config(8) for more details.
-#
-options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
diff --git a/sys/arm/conf/DEFAULTS b/sys/arm/conf/DEFAULTS
index 4052ef3e500..591a0a14c8d 100644
--- a/sys/arm/conf/DEFAULTS
+++ b/sys/arm/conf/DEFAULTS
@@ -9,10 +9,3 @@ device		mem
 
 options 	GEOM_PART_BSD
 options 	GEOM_PART_MBR
- 
-# Store the plain version of the configuration file in the kernel itself.
-# To store the entire file, including comments, put this in /etc/src.conf:
-# CONFIGARGS=	-C
-# See config(8) for more details.
-#
-options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
diff --git a/sys/i386/conf/DEFAULTS b/sys/i386/conf/DEFAULTS
index eb3ed17b81b..32e77e41979 100644
--- a/sys/i386/conf/DEFAULTS
+++ b/sys/i386/conf/DEFAULTS
@@ -28,10 +28,3 @@ options 	GEOM_PART_MBR
 # enable support for native hardware
 options 	NATIVE
 device		atpic
- 
-# Store the plain version of the configuration file in the kernel itself.
-# To store the entire file, including comments, put this in /etc/src.conf:
-# CONFIGARGS=	-C
-# See config(8) for more details.
-#
-options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
diff --git a/sys/ia64/conf/DEFAULTS b/sys/ia64/conf/DEFAULTS
index 58eaaf4b591..625ff90955c 100644
--- a/sys/ia64/conf/DEFAULTS
+++ b/sys/ia64/conf/DEFAULTS
@@ -17,10 +17,3 @@ device		uart_ns8250
 options 	GEOM_PART_BSD
 options 	GEOM_PART_GPT
 options 	GEOM_PART_MBR
- 
-# Store the plain version of the configuration file in the kernel itself.
-# To store the entire file, including comments, put this in /etc/src.conf:
-# CONFIGARGS=	-C
-# See config(8) for more details.
-#
-options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
diff --git a/sys/mips/conf/DEFAULTS b/sys/mips/conf/DEFAULTS
index 98337445e59..dc480cea27a 100644
--- a/sys/mips/conf/DEFAULTS
+++ b/sys/mips/conf/DEFAULTS
@@ -11,10 +11,3 @@ device		uart_ns8250
 
 options 	GEOM_PART_BSD
 options 	GEOM_PART_MBR
- 
-# Store the plain version of the configuration file in the kernel itself.
-# To store the entire file, including comments, put this in /etc/src.conf:
-# CONFIGARGS=	-C
-# See config(8) for more details.
-#
-options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
diff --git a/sys/pc98/conf/DEFAULTS b/sys/pc98/conf/DEFAULTS
index bd0afd6ca80..0002cf0a30c 100644
--- a/sys/pc98/conf/DEFAULTS
+++ b/sys/pc98/conf/DEFAULTS
@@ -24,10 +24,3 @@ device		uart_ns8250
 # Default partitioning schemes
 options 	GEOM_PART_BSD
 options 	GEOM_PART_PC98
- 
-# Store the plain version of the configuration file in the kernel itself.
-# To store the entire file, including comments, put this in /etc/src.conf:
-# CONFIGARGS=	-C
-# See config(8) for more details.
-#
-options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
diff --git a/sys/powerpc/conf/DEFAULTS b/sys/powerpc/conf/DEFAULTS
index 30b54291c7d..7c981d147ba 100644
--- a/sys/powerpc/conf/DEFAULTS
+++ b/sys/powerpc/conf/DEFAULTS
@@ -14,10 +14,3 @@ device		uart_z8530
 
 options 	GEOM_PART_APM
 options 	GEOM_PART_MBR
- 
-# Store the plain version of the configuration file in the kernel itself.
-# To store the entire file, including comments, put this in /etc/src.conf:
-# CONFIGARGS=	-C
-# See config(8) for more details.
-#
-options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
diff --git a/sys/sparc64/conf/DEFAULTS b/sys/sparc64/conf/DEFAULTS
index 32a79b105f8..38b2408bf44 100644
--- a/sys/sparc64/conf/DEFAULTS
+++ b/sys/sparc64/conf/DEFAULTS
@@ -19,10 +19,3 @@ options 	GEOM_PART_VTOC8
 
 # Let sunkbd emulate an AT keyboard by default.
 options 	SUNKBD_EMULATE_ATKBD
- 
-# Store the plain version of the configuration file in the kernel itself.
-# To store the entire file, including comments, put this in /etc/src.conf:
-# CONFIGARGS=	-C
-# See config(8) for more details.
-#
-options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
diff --git a/sys/sun4v/conf/DEFAULTS b/sys/sun4v/conf/DEFAULTS
index a610d779a5f..610d65333a0 100644
--- a/sys/sun4v/conf/DEFAULTS
+++ b/sys/sun4v/conf/DEFAULTS
@@ -11,10 +11,3 @@ device		mem		# Memory and kernel memory devices
 # Default partitioning schemes
 options 	GEOM_PART_BSD
 options 	GEOM_PART_VTOC8
- 
-# Store the plain version of the configuration file in the kernel itself.
-# To store the entire file, including comments, put this in /etc/src.conf:
-# CONFIGARGS=	-C
-# See config(8) for more details.
-#
-options 	INCLUDE_CONFIG_FILE	# Include this file in kernel

From eee4cfb98fc1b3185d3bea1aad559feba31ee4c6 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Mon, 4 Jan 2010 22:44:48 +0000
Subject: [PATCH 1017/2592] MFC 201351: Use stricter checking to match possible
 vlan clones by not allowing extra garbage characters around or within the
 tag.

---
 sys/net/if_vlan.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 126d83ffb35..f23541e230d 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -577,7 +577,7 @@ vlan_clone_match_ethertag(struct if_clone *ifc, const char *name, int *tag)
 {
 	const char *cp;
 	struct ifnet *ifp;
-	int t = 0;
+	int t;
 
 	/* Check for . style interface names. */
 	IFNET_RLOCK_NOSLEEP();
@@ -587,13 +587,15 @@ vlan_clone_match_ethertag(struct if_clone *ifc, const char *name, int *tag)
 		if (strncmp(ifp->if_xname, name, strlen(ifp->if_xname)) != 0)
 			continue;
 		cp = name + strlen(ifp->if_xname);
-		if (*cp != '.')
+		if (*cp++ != '.')
 			continue;
-		for(; *cp != '\0'; cp++) {
-			if (*cp < '0' || *cp > '9')
-				continue;
+		if (*cp == '\0')
+			continue;
+		t = 0;
+		for(; *cp >= '0' && *cp <= '9'; cp++)
 			t = (t * 10) + (*cp - '0');
-		}
+		if (*cp != '\0')
+			continue;
 		if (tag != NULL)
 			*tag = t;
 		break;

From 3354257d950ed739495b44fbae5a0103d7b673a1 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 5 Jan 2010 12:32:09 +0000
Subject: [PATCH 1018/2592] MFC r201194: Use clock_gettime(CLOCK_SECOND)
 instead of gettimeofday(2) for implementation of time(3). CLOCK_SECOND is
 much faster.

---
 lib/libc/gen/time.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/lib/libc/gen/time.c b/lib/libc/gen/time.c
index 840f9b6b7bc..214dfce1bb8 100644
--- a/lib/libc/gen/time.c
+++ b/lib/libc/gen/time.c
@@ -37,13 +37,12 @@ __FBSDID("$FreeBSD$");
 #include 
 
 time_t
-time(t)
-	time_t *t;
+time(time_t *t)
 {
-	struct timeval tt;
+	struct timespec tt;
 	time_t retval;
 
-	if (gettimeofday(&tt, (struct timezone *)0) < 0)
+	if (clock_gettime(CLOCK_SECOND, &tt) < 0)
 		retval = -1;
 	else
 		retval = tt.tv_sec;

From 847d100007f43925b1461908ce4fc8ca0158ac5b Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 5 Jan 2010 12:34:16 +0000
Subject: [PATCH 1019/2592] MFC r201400: Remove reference to the bug in FreeBSD
 2.0.

---
 sbin/mount_msdosfs/mount_msdosfs.8 | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/sbin/mount_msdosfs/mount_msdosfs.8 b/sbin/mount_msdosfs/mount_msdosfs.8
index 857899b392a..9a3be1377eb 100644
--- a/sbin/mount_msdosfs/mount_msdosfs.8
+++ b/sbin/mount_msdosfs/mount_msdosfs.8
@@ -205,14 +205,6 @@ The use of the
 flag could result in damaged file systems,
 albeit the damage is in part taken care of by
 procedures similar to the ones used in Win'95.
-.Pp
-.Fx 2.1
-and earlier versions could not handle cluster sizes larger than 16K.
-Just mounting an MS-DOS file system could cause corruption to any
-mounted file system.
-Cluster sizes larger than 16K are unavoidable for file system sizes
-larger than 1G, and also occur when file systems larger than 1G are
-shrunk to smaller than 1G using FIPS.
 .Sh HISTORY
 The
 .Nm

From 48eae87f1203ee432f3412c968829b7684c6b096 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 13:46:39 +0000
Subject: [PATCH 1020/2592] MFC r200933: Make geom_stripe report it's stripe
 size to upper layers.

---
 sys/geom/stripe/g_stripe.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/geom/stripe/g_stripe.c b/sys/geom/stripe/g_stripe.c
index 81f75610777..a91335790ba 100644
--- a/sys/geom/stripe/g_stripe.c
+++ b/sys/geom/stripe/g_stripe.c
@@ -675,6 +675,8 @@ g_stripe_check_and_run(struct g_stripe_softc *sc)
 	}
 	sc->sc_provider->sectorsize = sectorsize;
 	sc->sc_provider->mediasize = mediasize * sc->sc_ndisks;
+	sc->sc_provider->stripesize = sc->sc_stripesize;
+	sc->sc_provider->stripeoffset = 0;
 	g_error_provider(sc->sc_provider, 0);
 
 	G_STRIPE_DEBUG(0, "Device %s activated.", sc->sc_name);

From c730493bbfef362e06ca39d23fa377665e2954e8 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 13:47:55 +0000
Subject: [PATCH 1021/2592] MFC r200935: As soon as mirror has no own stripes,
 report largest stripe of unrerlying components, hoping others fit, if they
 are not equal.

---
 sys/geom/mirror/g_mirror.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c
index 973e10b9b2e..25de44a5eff 100644
--- a/sys/geom/mirror/g_mirror.c
+++ b/sys/geom/mirror/g_mirror.c
@@ -2036,6 +2036,15 @@ g_mirror_launch_provider(struct g_mirror_softc *sc)
 	pp = g_new_providerf(sc->sc_geom, "mirror/%s", sc->sc_name);
 	pp->mediasize = sc->sc_mediasize;
 	pp->sectorsize = sc->sc_sectorsize;
+	pp->stripesize = 0;
+	pp->stripeoffset = 0;
+	LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+		if (disk->d_consumer && disk->d_consumer->provider &&
+		    disk->d_consumer->provider->stripesize > pp->stripesize) {
+			pp->stripesize = disk->d_consumer->provider->stripesize;
+			pp->stripeoffset = disk->d_consumer->provider->stripeoffset;
+		}
+	}
 	sc->sc_provider = pp;
 	g_error_provider(pp, 0);
 	g_topology_unlock();

From 3bda9adcd9b95a451a495fd103e3bf8d23c7fd72 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 13:49:18 +0000
Subject: [PATCH 1022/2592] MFC r200940: As soon as geom_raid3 reports it's own
 stripe as sector size, report largest underlying provider's stripe,
 multiplied by number of data disks in array, due to transformation done, as
 array stripe.

---
 sys/geom/raid3/g_raid3.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c
index 0feca0c8482..6425b2ee944 100644
--- a/sys/geom/raid3/g_raid3.c
+++ b/sys/geom/raid3/g_raid3.c
@@ -2317,6 +2317,8 @@ static void
 g_raid3_launch_provider(struct g_raid3_softc *sc)
 {
 	struct g_provider *pp;
+	struct g_raid3_disk *disk;
+	int n;
 
 	sx_assert(&sc->sc_lock, SX_LOCKED);
 
@@ -2324,6 +2326,18 @@ g_raid3_launch_provider(struct g_raid3_softc *sc)
 	pp = g_new_providerf(sc->sc_geom, "raid3/%s", sc->sc_name);
 	pp->mediasize = sc->sc_mediasize;
 	pp->sectorsize = sc->sc_sectorsize;
+	pp->stripesize = 0;
+	pp->stripeoffset = 0;
+	for (n = 0; n < sc->sc_ndisks; n++) {
+		disk = &sc->sc_disks[n];
+		if (disk->d_consumer && disk->d_consumer->provider &&
+		    disk->d_consumer->provider->stripesize > pp->stripesize) {
+			pp->stripesize = disk->d_consumer->provider->stripesize;
+			pp->stripeoffset = disk->d_consumer->provider->stripeoffset;
+		}
+	}
+	pp->stripesize *= sc->sc_ndisks - 1;
+	pp->stripeoffset *= sc->sc_ndisks - 1;
 	sc->sc_provider = pp;
 	g_error_provider(pp, 0);
 	g_topology_unlock();

From ae07f94f6f8fa594ef23fabde120c6ce05374335 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 13:50:14 +0000
Subject: [PATCH 1023/2592] MFC r200942: Make geom_concat to passthrough stripe
 parameters of the first component, hoping that rest will fit.

---
 sys/geom/concat/g_concat.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c
index a12f7b830e0..1f523755c7d 100644
--- a/sys/geom/concat/g_concat.c
+++ b/sys/geom/concat/g_concat.c
@@ -347,14 +347,14 @@ static void
 g_concat_check_and_run(struct g_concat_softc *sc)
 {
 	struct g_concat_disk *disk;
+	struct g_provider *pp;
 	u_int no, sectorsize = 0;
 	off_t start;
 
 	if (g_concat_nvalid(sc) != sc->sc_ndisks)
 		return;
 
-	sc->sc_provider = g_new_providerf(sc->sc_geom, "concat/%s",
-	    sc->sc_name);
+	pp = g_new_providerf(sc->sc_geom, "concat/%s", sc->sc_name);
 	start = 0;
 	for (no = 0; no < sc->sc_ndisks; no++) {
 		disk = &sc->sc_disks[no];
@@ -371,10 +371,13 @@ g_concat_check_and_run(struct g_concat_softc *sc)
 			    disk->d_consumer->provider->sectorsize);
 		}
 	}
-	sc->sc_provider->sectorsize = sectorsize;
+	pp->sectorsize = sectorsize;
 	/* We have sc->sc_disks[sc->sc_ndisks - 1].d_end in 'start'. */
-	sc->sc_provider->mediasize = start;
-	g_error_provider(sc->sc_provider, 0);
+	pp->mediasize = start;
+	pp->stripesize = sc->sc_disks[0].d_consumer->provider->stripesize;
+	pp->stripeoffset = sc->sc_disks[0].d_consumer->provider->stripeoffset;
+	sc->sc_provider = pp;
+	g_error_provider(pp, 0);
 
 	G_CONCAT_DEBUG(0, "Device %s activated.", sc->sc_name);
 }

From 2aa244f295f96ef09a19ce721445d8f14ea716e0 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 13:51:23 +0000
Subject: [PATCH 1024/2592] MFC r200934: Add two disk ioctls, giving user-level
 tools information about disk/array stripe (optimal access block) size and
 offset.

---
 sys/geom/geom_dev.c |  7 ++++++-
 sys/sys/disk.h      | 12 ++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index 8b560abe37b..af05618f163 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -323,7 +323,12 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread
 			return (ENOENT);
 		strlcpy(data, pp->name, i);
 		break;
-
+	case DIOCGSTRIPESIZE:
+		*(off_t *)data = cp->provider->stripesize;
+		break;
+	case DIOCGSTRIPEOFFSET:
+		*(off_t *)data = cp->provider->stripeoffset;
+		break;
 	default:
 		if (cp->provider->geom->ioctl != NULL) {
 			error = cp->provider->geom->ioctl(cp->provider, cmd, data, fflag, td);
diff --git a/sys/sys/disk.h b/sys/sys/disk.h
index 4fe2e09c22f..422229ef69c 100644
--- a/sys/sys/disk.h
+++ b/sys/sys/disk.h
@@ -104,4 +104,16 @@ void disk_err(struct bio *bp, const char *what, int blkdone, int nl);
 	 * must be at least MAXPATHLEN bytes long.
 	 */
 
+#define DIOCGSTRIPESIZE	_IOR('d', 139, off_t)	/* Get stripe size in bytes */
+	/*-
+	 * Get the size of the device's optimal access block in bytes.
+	 * This should be a multiple of the sectorsize.
+	 */
+
+#define DIOCGSTRIPEOFFSET _IOR('d', 140, off_t)	/* Get stripe offset in bytes */
+	/*-
+	 * Get the offset of the first device's optimal access block in bytes.
+	 * This should be a multiple of the sectorsize.
+	 */
+
 #endif /* _SYS_DISK_H_ */

From 3bf7eb487a22d93920f00dc9d4fc7651806071d9 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 13:55:49 +0000
Subject: [PATCH 1025/2592] MFC r196799: Don't bother obtaining the ident if we
 are not going to print it.

---
 usr.sbin/diskinfo/diskinfo.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/usr.sbin/diskinfo/diskinfo.c b/usr.sbin/diskinfo/diskinfo.c
index 48b019b1a14..7ecf7cb4f32 100644
--- a/usr.sbin/diskinfo/diskinfo.c
+++ b/usr.sbin/diskinfo/diskinfo.c
@@ -104,9 +104,6 @@ main(int argc, char **argv)
 		error = ioctl(fd, DIOCGFWHEADS, &fwheads);
 		if (error)
 			fwheads = 0;
-		error = ioctl(fd, DIOCGIDENT, ident);
-		if (error)
-			ident[0] = '\0';
 		if (!opt_v) {
 			printf("%s", argv[i]);
 			printf("\t%u", sectorsize);
@@ -133,7 +130,7 @@ main(int argc, char **argv)
 				printf("\t%-12u\t# Heads according to firmware.\n", fwheads);
 				printf("\t%-12u\t# Sectors according to firmware.\n", fwsectors);
 			} 
-			if (ident[0] != '\0')
+			if (ioctl(fd, DIOCGIDENT, ident) == 0)
 				printf("\t%-12s\t# Disk ident.\n", ident);
 		}
 		printf("\n");

From ea78eb420419dbcae9935d116de327291df4dac0 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 13:56:58 +0000
Subject: [PATCH 1026/2592] MFC 200968: Make diskinfo report disk stripe size
 and offset. It should help users to make file systems optimally aligned and
 tuned for better performance.

---
 usr.sbin/diskinfo/diskinfo.8 |  3 ++-
 usr.sbin/diskinfo/diskinfo.c | 12 +++++++++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/usr.sbin/diskinfo/diskinfo.8 b/usr.sbin/diskinfo/diskinfo.8
index dfc7040f349..f68d426e6b4 100644
--- a/usr.sbin/diskinfo/diskinfo.8
+++ b/usr.sbin/diskinfo/diskinfo.8
@@ -46,7 +46,8 @@ and optionally runs a naive performance test on the device.
 .Pp
 If given no arguments, the output will be a single line per specified device
 with the following fields: device name, sectorsize, media size in bytes,
-media size in sectors, firmware cylinders, firmware heads, and firmware sectors.
+media size in sectors, stripe size, stripe offset, firmware cylinders,
+firmware heads, and firmware sectors.
 The last three fields are only present if the information is available.
 .Pp
 If given the
diff --git a/usr.sbin/diskinfo/diskinfo.c b/usr.sbin/diskinfo/diskinfo.c
index 7ecf7cb4f32..1f967b732da 100644
--- a/usr.sbin/diskinfo/diskinfo.c
+++ b/usr.sbin/diskinfo/diskinfo.c
@@ -58,7 +58,7 @@ main(int argc, char **argv)
 {
 	int i, ch, fd, error;
 	char buf[BUFSIZ], ident[DISK_IDENT_SIZE];
-	off_t	mediasize;
+	off_t	mediasize, stripesize, stripeoffset;
 	u_int	sectorsize, fwsectors, fwheads;
 
 	while ((ch = getopt(argc, argv, "ctv")) != -1) {
@@ -104,11 +104,19 @@ main(int argc, char **argv)
 		error = ioctl(fd, DIOCGFWHEADS, &fwheads);
 		if (error)
 			fwheads = 0;
+		error = ioctl(fd, DIOCGSTRIPESIZE, &stripesize);
+		if (error)
+			stripesize = 0;
+		error = ioctl(fd, DIOCGSTRIPEOFFSET, &stripeoffset);
+		if (error)
+			stripeoffset = 0;
 		if (!opt_v) {
 			printf("%s", argv[i]);
 			printf("\t%u", sectorsize);
 			printf("\t%jd", (intmax_t)mediasize);
 			printf("\t%jd", (intmax_t)mediasize/sectorsize);
+			printf("\t%jd", (intmax_t)stripesize);
+			printf("\t%jd", (intmax_t)stripeoffset);
 			if (fwsectors != 0 && fwheads != 0) {
 				printf("\t%jd", (intmax_t)mediasize /
 				    (fwsectors * fwheads * sectorsize));
@@ -124,6 +132,8 @@ main(int argc, char **argv)
 			    (intmax_t)mediasize, buf);
 			printf("\t%-12jd\t# mediasize in sectors\n",
 			    (intmax_t)mediasize/sectorsize);
+			printf("\t%-12jd\t# stripesize\n", stripesize);
+			printf("\t%-12jd\t# stripeoffset\n", stripeoffset);
 			if (fwsectors != 0 && fwheads != 0) {
 				printf("\t%-12jd\t# Cylinders according to firmware.\n", (intmax_t)mediasize /
 				    (fwsectors * fwheads * sectorsize));

From 328562d78af3b1ff685ce35885d87e78528ca869 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 13:58:18 +0000
Subject: [PATCH 1027/2592] MFC 200969: Report stripe size only if physical
 sector size is not equal to logical.

---
 sys/cam/ata/ata_da.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index f62af46d46b..204efe24f99 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -687,9 +687,14 @@ adaregister(struct cam_periph *periph, void *arg)
 	softc->disk->d_sectorsize = softc->params.secsize;
 	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);
+	if (ata_physical_sector_size(&cgd->ident_data) !=
+	    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)) %
+		    softc->disk->d_stripesize;
+	}
 	/* 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;

From aaa35fa8536d9c115dc78fececf9af541f0fdfec Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 14:02:12 +0000
Subject: [PATCH 1028/2592] MFC 200991: Teach twe driver to report array stripe
 size to GEOM.

---
 sys/dev/twe/twe.c         | 5 +++--
 sys/dev/twe/twe_freebsd.c | 7 +++++++
 sys/dev/twe/twevar.h      | 1 +
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sys/dev/twe/twe.c b/sys/dev/twe/twe.c
index 59b5027adac..a904db03def 100644
--- a/sys/dev/twe/twe.c
+++ b/sys/dev/twe/twe.c
@@ -201,7 +201,7 @@ twe_add_unit(struct twe_softc *sc, int unit)
     int				table, error = 0;
     u_int16_t			dsize;
     TWE_Param			*drives = NULL, *param = NULL;
-    TWE_Unit_Descriptor		*ud;
+    TWE_Array_Descriptor	*ud;
 
     if (unit < 0 || unit > TWE_MAX_UNITS)
 	return (EINVAL);
@@ -244,8 +244,9 @@ twe_add_unit(struct twe_softc *sc, int unit)
 	error = EIO;
 	goto out;
     }
-    ud = (TWE_Unit_Descriptor *)param->data;
+    ud = (TWE_Array_Descriptor *)param->data;
     dr->td_type = ud->configuration;
+    dr->td_stripe = ud->stripe_size;
 
     /* build synthetic geometry as per controller internal rules */
     if (dr->td_size > 0x200000) {
diff --git a/sys/dev/twe/twe_freebsd.c b/sys/dev/twe/twe_freebsd.c
index 9ad65c94d9e..0328599c129 100644
--- a/sys/dev/twe/twe_freebsd.c
+++ b/sys/dev/twe/twe_freebsd.c
@@ -818,6 +818,13 @@ twed_attach(device_t dev)
     sc->twed_disk->d_maxsize = (TWE_MAX_SGL_LENGTH - 1) * PAGE_SIZE;
     sc->twed_disk->d_sectorsize = TWE_BLOCK_SIZE;
     sc->twed_disk->d_mediasize = TWE_BLOCK_SIZE * (off_t)sc->twed_drive->td_size;
+    if (sc->twed_drive->td_type == TWE_UD_CONFIG_RAID0 ||
+	sc->twed_drive->td_type == TWE_UD_CONFIG_RAID5 ||
+	sc->twed_drive->td_type == TWE_UD_CONFIG_RAID10) {
+	    sc->twed_disk->d_stripesize =
+		TWE_BLOCK_SIZE << sc->twed_drive->td_stripe;
+	    sc->twed_disk->d_stripeoffset = 0;
+    }
     sc->twed_disk->d_fwsectors = sc->twed_drive->td_sectors;
     sc->twed_disk->d_fwheads = sc->twed_drive->td_heads;
     sc->twed_disk->d_unit = sc->twed_drive->td_sys_unit;
diff --git a/sys/dev/twe/twevar.h b/sys/dev/twe/twevar.h
index 90391ad95df..4ee90e52c73 100644
--- a/sys/dev/twe/twevar.h
+++ b/sys/dev/twe/twevar.h
@@ -59,6 +59,7 @@ struct twe_drive
     /* unit state and type */
     u_int8_t		td_state;
     u_int8_t		td_type;
+    u_int8_t		td_stripe;
 
     /* handle for attached driver */
     device_t		td_disk;

From 579a42937de65fd73bcac423284b7826e97b3b24 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 5 Jan 2010 14:03:46 +0000
Subject: [PATCH 1029/2592] MFC 200977: Avoid false positive probe on ICH6
 chipsets.

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

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 84a16306e2f..698da60ab1f 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -115,8 +115,8 @@ static struct {
 	{0x43931002, "ATI IXP700",	0},
 	{0x43941002, "ATI IXP800",	0},
 	{0x43951002, "ATI IXP800",	0},
-	{0x26528086, "Intel ICH6",	0},
-	{0x26538086, "Intel ICH6M",	0},
+	{0x26528086, "Intel ICH6",	AHCI_Q_NOFORCE},
+	{0x26538086, "Intel ICH6M",	AHCI_Q_NOFORCE},
 	{0x26818086, "Intel ESB2",	0},
 	{0x26828086, "Intel ESB2",	0},
 	{0x26838086, "Intel ESB2",	0},

From e10b0dfd664ab9c90591a18871155c111ab20d40 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 5 Jan 2010 17:04:14 +0000
Subject: [PATCH 1030/2592] MFC 200847: - Rename the __tcpi_(snd|rcv)_mss
 fields of the tcp_info structure to remove   the leading underscores since
 they are now implemented. - Implement the tcpi_rto and tcpi_last_data_recv
 fields in the tcp_info   structure.

---
 sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c | 2 +-
 sys/netinet/tcp.h                     | 8 ++++----
 sys/netinet/tcp_usrreq.c              | 6 ++++--
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c b/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c
index c582dbda39c..975b90854bd 100644
--- a/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c
+++ b/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c
@@ -203,7 +203,7 @@ static int set_tcpinfo(struct iwch_ep *ep)
 
 	ep->snd_seq = ti.tcpi_snd_nxt;
 	ep->rcv_seq = ti.tcpi_rcv_nxt;
-	ep->emss = ti.__tcpi_snd_mss - sizeof(struct tcpiphdr);
+	ep->emss = ti.tcpi_snd_mss - sizeof(struct tcpiphdr);
 	ep->hwtid = TOEPCB(ep->com.so)->tp_tid; /* XXX */
 	if (ti.tcpi_options & TCPI_OPT_TIMESTAMPS)
 		ep->emss -= 12;
diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h
index 03b8bf63708..8779582adc1 100644
--- a/sys/netinet/tcp.h
+++ b/sys/netinet/tcp.h
@@ -181,10 +181,10 @@ struct tcp_info {
 	u_int8_t	tcpi_snd_wscale:4,	/* RFC1323 send shift value. */
 			tcpi_rcv_wscale:4;	/* RFC1323 recv shift value. */
 
-	u_int32_t	__tcpi_rto;
+	u_int32_t	tcpi_rto;		/* Retransmission timeout (usec). */
 	u_int32_t	__tcpi_ato;
-	u_int32_t	__tcpi_snd_mss;
-	u_int32_t	__tcpi_rcv_mss;
+	u_int32_t	tcpi_snd_mss;		/* Max segment size for send. */
+	u_int32_t	tcpi_rcv_mss;		/* Max segment size for receive. */
 
 	u_int32_t	__tcpi_unacked;
 	u_int32_t	__tcpi_sacked;
@@ -195,7 +195,7 @@ struct tcp_info {
 	/* Times; measurements in usecs. */
 	u_int32_t	__tcpi_last_data_sent;
 	u_int32_t	__tcpi_last_ack_sent;	/* Also unimpl. on Linux? */
-	u_int32_t	__tcpi_last_data_recv;
+	u_int32_t	tcpi_last_data_recv;	/* Time since last recv data. */
 	u_int32_t	__tcpi_last_ack_recv;
 
 	/* Metrics; variable units. */
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 1e58cd7b134..8ac1966bddc 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1200,6 +1200,8 @@ tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti)
 		ti->tcpi_rcv_wscale = tp->rcv_scale;
 	}
 
+	ti->tcpi_rto = tp->t_rxtcur * tick;
+	ti->tcpi_last_data_recv = (long)(ticks - (int)tp->t_rcvtime) * tick;
 	ti->tcpi_rtt = ((u_int64_t)tp->t_srtt * tick) >> TCP_RTT_SHIFT;
 	ti->tcpi_rttvar = ((u_int64_t)tp->t_rttvar * tick) >> TCP_RTTVAR_SHIFT;
 
@@ -1214,8 +1216,8 @@ tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti)
 	ti->tcpi_snd_wnd = tp->snd_wnd;
 	ti->tcpi_snd_bwnd = tp->snd_bwnd;
 	ti->tcpi_snd_nxt = tp->snd_nxt;
-	ti->__tcpi_snd_mss = tp->t_maxseg;
-	ti->__tcpi_rcv_mss = tp->t_maxseg;
+	ti->tcpi_snd_mss = tp->t_maxseg;
+	ti->tcpi_rcv_mss = tp->t_maxseg;
 	if (tp->t_flags & TF_TOE)
 		ti->tcpi_options |= TCPI_OPT_TOE;
 }

From 02bcb7ecc3fc5afb9bc3502923e615330fa313fa Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 5 Jan 2010 18:25:41 +0000
Subject: [PATCH 1031/2592] MFC 201196: Change vlan interfaces to cope more
 usefully with the parent interface being renamed.  Previously the vlan
 interfaces would lose their configuration as if the parent interface had been
 physically removed.  Now vlan interfaces ignore rename events. - Add a new
 ifnet flag (IFF_RENAMING) that is set while an ifnet is being   renamed. 
 This flag can be checked in ifnet departure/arrival event   handlers to treat
 rename events differently. - Change the ifnet departure event handler in the
 if_vlan(4) driver to   ignore departure events due to a trunk interface being
 renamed.

---
 sys/net/if.c      | 10 ++++++++++
 sys/net/if.h      |  1 +
 sys/net/if_vlan.c |  7 ++++++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/sys/net/if.c b/sys/net/if.c
index 55de666a636..7ffa2687c8c 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -2161,6 +2161,14 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
 			return (EINVAL);
 		if (ifunit(new_name) != NULL)
 			return (EEXIST);
+
+		/*
+		 * XXX: Locking.  Nothing else seems to lock if_flags,
+		 * and there are numerous other races with the
+		 * ifunit() checks not being atomic with namespace
+		 * changes (renames, vmoves, if_attach, etc).
+		 */
+		ifp->if_flags |= IFF_RENAMING;
 		
 		/* Announce the departure of the interface. */
 		rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
@@ -2195,6 +2203,8 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
 		EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp);
 		/* Announce the return of the interface. */
 		rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
+
+		ifp->if_flags &= ~IFF_RENAMING;
 		break;
 
 #ifdef VIMAGE
diff --git a/sys/net/if.h b/sys/net/if.h
index 857ab7fb460..f94b54a1b62 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -150,6 +150,7 @@ struct if_data {
 #define	IFF_MONITOR	0x40000		/* (n) user-requested monitor mode */
 #define	IFF_STATICARP	0x80000		/* (n) static ARP */
 #define	IFF_DYING	0x200000	/* (n) interface is winding down */
+#define	IFF_RENAMING	0x400000	/* (n) interface is being renamed */
 
 /*
  * Old names for driver flags so that user space tools can continue to use
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index f23541e230d..f0cd3b31d69 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -466,7 +466,8 @@ vlan_setmulti(struct ifnet *ifp)
  * A handler for network interface departure events.
  * Track departure of trunks here so that we don't access invalid
  * pointers or whatever if a trunk is ripped from under us, e.g.,
- * by ejecting its hot-plug card.
+ * by ejecting its hot-plug card.  However, if an ifnet is simply
+ * being renamed, then there's no need to tear down the state.
  */
 static void
 vlan_ifdetach(void *arg __unused, struct ifnet *ifp)
@@ -481,6 +482,10 @@ vlan_ifdetach(void *arg __unused, struct ifnet *ifp)
 	if (ifp->if_vlantrunk == NULL)
 		return;
 
+	/* If the ifnet is just being renamed, don't do anything. */
+	if (ifp->if_flags & IFF_RENAMING)
+		return;
+
 	VLAN_LOCK();
 	/*
 	 * OK, it's a trunk.  Loop over and detach all vlan's on it.

From 32c5340155b9e2178c692979dc6d0ae61cec1e56 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 5 Jan 2010 22:14:55 +0000
Subject: [PATCH 1032/2592] MFC r201282, r201543

r201282
-------
The proxy arp entries could not be added into the system over the
IFF_POINTOPOINT link types. The reason was due to the routing
entry returned from the kernel covering the remote end is of an
interface type that does not support ARP. This patch fixes this
problem by providing a hint to the kernel routing code, which
indicates the prefix route instead of the PPP host route should
be returned to the caller. Since a host route to the local end
point is also added into the routing table, and there could be
multiple such instantiations due to multiple PPP links can be
created with the same local end IP address, this patch also fixes
the loopback route installation failure problem observed prior to
this patch. The reference count of loopback route to local end would
be either incremented or decremented. The first instantiation would
create the entry and the last removal would delete the route entry.

r201543
-------
The IFA_RTSELF address flag marks a loopback route has been installed
for the interface address. This marker is necessary to properly support
PPP types of links where multiple links can have the same local end
IP address. The IFA_RTSELF flag bit maps to the RTF_HOST value, which
was combined into the route flag bits during prefix installation in
IPv6. This inclusion causing the prefix route to be unusable. This
patch fixes this bug by excluding the IFA_RTSELF flag during route
installation.

PR:		ports/141342, kern/141134
---
 sys/net/if_llatbl.c    |  4 ++-
 sys/net/if_llatbl.h    |  2 +-
 sys/net/if_var.h       |  1 +
 sys/net/route.c        |  4 +--
 sys/net/route.h        |  1 +
 sys/net/rtsock.c       | 22 +++++++++++++++
 sys/netinet/in.c       | 52 ++++++++++++++++++++++++++++------
 sys/netinet6/in6.c     | 16 ++++++++---
 sys/netinet6/nd6_rtr.c |  2 +-
 usr.sbin/arp/arp.c     | 64 +++++++++++++++++++++++-------------------
 10 files changed, 121 insertions(+), 47 deletions(-)

diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
index 4991c81d92c..5992f6d82e0 100644
--- a/sys/net/if_llatbl.c
+++ b/sys/net/if_llatbl.c
@@ -274,7 +274,9 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
 #ifdef INET
 			if (dst->sa_family == AF_INET && 
 			    ((struct sockaddr_inarp *)dst)->sin_other != 0) {
-				struct rtentry *rt = rtalloc1(dst, 0, 0);
+				struct rtentry *rt;
+				((struct sockaddr_inarp *)dst)->sin_other = 0;
+				rt = rtalloc1(dst, 0, 0);
 				if (rt == NULL || !(rt->rt_flags & RTF_HOST)) {
 					log(LOG_INFO, "%s: RTM_ADD publish "
 					    "(proxy only) is invalid\n",
diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h
index f54c78ad8a2..21357ebaef6 100644
--- a/sys/net/if_llatbl.h
+++ b/sys/net/if_llatbl.h
@@ -159,7 +159,7 @@ struct lltable {
 				    const struct sockaddr *mask);
 	struct llentry *	(*llt_lookup)(struct lltable *, u_int flags,
 				    const struct sockaddr *l3addr);
-	int			(*llt_rtcheck)(struct ifnet *,
+	int			(*llt_rtcheck)(struct ifnet *, u_int flags,
 				    const struct sockaddr *);
 	int			(*llt_dump)(struct lltable *,
 				     struct sysctl_req *);
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 523b9e8a813..53802446b13 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -712,6 +712,7 @@ struct ifaddr {
 	struct mtx ifa_mtx;
 };
 #define	IFA_ROUTE	RTF_UP		/* route installed */
+#define IFA_RTSELF	RTF_HOST	/* loopback route to self installed */
 
 /* for compatibility with other BSDs */
 #define	ifa_list	ifa_link
diff --git a/sys/net/route.c b/sys/net/route.c
index 20875380118..b00ea69f206 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -98,8 +98,6 @@ VNET_DEFINE(struct rtstat, rtstat);
 #define	V_rttrash	VNET(rttrash)
 #define	V_rtstat	VNET(rtstat)
 
-static void rt_maskedcopy(struct sockaddr *,
-	    struct sockaddr *, struct sockaddr *);
 
 /* compare two sockaddr structures */
 #define	sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
@@ -1315,7 +1313,7 @@ rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate)
 	return (0);
 }
 
-static void
+void
 rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
 {
 	register u_char *cp1 = (u_char *)src;
diff --git a/sys/net/route.h b/sys/net/route.h
index ea5bb073430..4cf8a816466 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -384,6 +384,7 @@ void	 rt_missmsg(int, struct rt_addrinfo *, int, int);
 void	 rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *);
 void	 rt_newmaddrmsg(int, struct ifmultiaddr *);
 int	 rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
+void 	 rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *);
 
 /*
  * Note the following locking behavior:
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index a0677ec1dfc..df4f9ae762b 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -60,6 +60,7 @@
 #include 
 
 #include 
+#include 
 #ifdef INET6
 #include 
 #endif
@@ -622,6 +623,27 @@ route_output(struct mbuf *m, struct socket *so)
 			}
 		}
 #endif
+		/*
+		 * If performing proxied L2 entry insertion, and
+		 * the actual PPP host entry is found, perform
+		 * another search to retrieve the prefix route of
+		 * the local end point of the PPP link.
+		 */
+		if ((rtm->rtm_flags & RTF_ANNOUNCE) &&
+		    (rt->rt_ifp->if_flags & IFF_POINTOPOINT)) {
+			struct sockaddr laddr;
+			rt_maskedcopy(rt->rt_ifa->ifa_addr,
+				      &laddr,
+				      rt->rt_ifa->ifa_netmask);
+			/* 
+			 * refactor rt and no lock operation necessary
+			 */
+			rt = (struct rtentry *)rnh->rnh_matchaddr(&laddr, rnh);
+			if (rt == NULL) {
+				RADIX_NODE_HEAD_RUNLOCK(rnh);
+				senderr(ESRCH);
+			}
+		} 
 		RT_LOCK(rt);
 		RT_ADDREF(rt);
 		RADIX_NODE_HEAD_RUNLOCK(rnh);
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index e289c931383..ed8ef061ae8 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -924,9 +924,25 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
 	/*
 	 * add a loopback route to self
 	 */
-	if (V_useloopback && !(ifp->if_flags & IFF_LOOPBACK))
-		error = ifa_add_loopback_route((struct ifaddr *)ia, 
+	if (V_useloopback && !(ifp->if_flags & IFF_LOOPBACK)) {
+		struct route ia_ro;
+
+		bzero(&ia_ro, sizeof(ia_ro));
+		*((struct sockaddr_in *)(&ia_ro.ro_dst)) = ia->ia_addr;
+		rtalloc_ign_fib(&ia_ro, 0, 0);
+		if ((ia_ro.ro_rt != NULL) && (ia_ro.ro_rt->rt_ifp != NULL) &&
+		    (ia_ro.ro_rt->rt_ifp == V_loif)) {
+			RT_LOCK(ia_ro.ro_rt);
+			RT_ADDREF(ia_ro.ro_rt);
+			RTFREE_LOCKED(ia_ro.ro_rt);
+		} else
+			error = ifa_add_loopback_route((struct ifaddr *)ia, 
 				       (struct sockaddr *)&ia->ia_addr);
+		if (error == 0)
+			ia->ia_flags |= IFA_RTSELF;
+		if (ia_ro.ro_rt != NULL)
+			RTFREE(ia_ro.ro_rt);
+	}
 
 	return (error);
 }
@@ -1043,7 +1059,7 @@ in_scrubprefix(struct in_ifaddr *target)
 {
 	struct in_ifaddr *ia;
 	struct in_addr prefix, mask, p;
-	int error;
+	int error = 0;
 	struct sockaddr_in prefix0, mask0;
 
 	/*
@@ -1057,9 +1073,28 @@ in_scrubprefix(struct in_ifaddr *target)
 	 * deletion is unconditional.
 	 */
 	if ((target->ia_addr.sin_addr.s_addr != INADDR_ANY) &&
-	    !(target->ia_ifp->if_flags & IFF_LOOPBACK)) {
-		error = ifa_del_loopback_route((struct ifaddr *)target,
+	    !(target->ia_ifp->if_flags & IFF_LOOPBACK) &&
+	    (target->ia_flags & IFA_RTSELF)) {
+		struct route ia_ro;
+		int freeit = 0;
+
+		bzero(&ia_ro, sizeof(ia_ro));
+		*((struct sockaddr_in *)(&ia_ro.ro_dst)) = target->ia_addr;
+		rtalloc_ign_fib(&ia_ro, 0, 0);
+		if ((ia_ro.ro_rt != NULL) && (ia_ro.ro_rt->rt_ifp != NULL) &&
+		    (ia_ro.ro_rt->rt_ifp == V_loif)) {
+			RT_LOCK(ia_ro.ro_rt);
+			if (ia_ro.ro_rt->rt_refcnt <= 1)
+				freeit = 1;
+			else
+				RT_REMREF(ia_ro.ro_rt);
+			RTFREE_LOCKED(ia_ro.ro_rt);
+		}
+		if (freeit)
+			error = ifa_del_loopback_route((struct ifaddr *)target,
 				       (struct sockaddr *)&target->ia_addr);
+		if (error == 0)
+			target->ia_flags &= ~IFA_RTSELF;
 		/* remove arp cache */
 		arp_ifscrub(target->ia_ifp, IA_SIN(target)->sin_addr.s_addr);
 	}
@@ -1317,7 +1352,7 @@ in_lltable_prefix_free(struct lltable *llt,
 
 
 static int
-in_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr)
+in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
 {
 	struct rtentry *rt;
 
@@ -1326,7 +1361,8 @@ 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) {
+	if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || 
+	    ((rt->rt_ifp != ifp) && !(flags & LLE_PUB))) {
 #ifdef DIAGNOSTIC
 		log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
 		    inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
@@ -1378,7 +1414,7 @@ in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3add
 		 * verify this.
 		 */
 		if (!(flags & LLE_IFADDR) &&
-		    in_lltable_rtcheck(ifp, l3addr) != 0)
+		    in_lltable_rtcheck(ifp, flags, l3addr) != 0)
 			goto done;
 
 		lle = in_lltable_new(l3addr, flags);
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index bf511247a28..7e5d6d4eee0 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1196,8 +1196,12 @@ in6_purgeaddr(struct ifaddr *ifa)
 	 * The check for the current setting of "nd6_useloopback" 
 	 * is not needed.
 	 */
-	error = ifa_del_loopback_route((struct ifaddr *)ia,
-			       (struct sockaddr *)&ia->ia_addr);
+	if (ia->ia_flags & IFA_RTSELF) {
+		error = ifa_del_loopback_route((struct ifaddr *)ia,
+				       (struct sockaddr *)&ia->ia_addr);
+		if (error == 0)
+			ia->ia_flags &= ~IFA_RTSELF;
+	}
 
 	/* stop DAD processing */
 	nd6_dad_stop(ifa);
@@ -1758,6 +1762,8 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia,
 		|| (ifp->if_flags & IFF_LOOPBACK))) {
 		error = ifa_add_loopback_route((struct ifaddr *)ia,
 				       (struct sockaddr *)&ia->ia_addr);
+		if (error == 0)
+			ia->ia_flags |= IFA_RTSELF;
 	}
 
 	/* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
@@ -2340,7 +2346,9 @@ in6_lltable_prefix_free(struct lltable *llt,
 }
 
 static int
-in6_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr)
+in6_lltable_rtcheck(struct ifnet *ifp, 
+		    u_int flags, 
+		    const struct sockaddr *l3addr)
 {
 	struct rtentry *rt;
 	char ip6buf[INET6_ADDRSTRLEN];
@@ -2408,7 +2416,7 @@ in6_lltable_lookup(struct lltable *llt, u_int flags,
 		 * verify this.
 		 */
 		if (!(flags & LLE_IFADDR) &&
-		    in6_lltable_rtcheck(ifp, l3addr) != 0)
+		    in6_lltable_rtcheck(ifp, flags, l3addr) != 0)
 			return NULL;
 
 		lle = in6_lltable_new(l3addr, flags);
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 4ec64fbadbd..30132a962b8 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -1631,7 +1631,7 @@ nd6_prefix_onlink(struct nd_prefix *pr)
 	bzero(&mask6, sizeof(mask6));
 	mask6.sin6_len = sizeof(mask6);
 	mask6.sin6_addr = pr->ndpr_mask;
-	rtflags = ifa->ifa_flags | RTF_UP;
+	rtflags = (ifa->ifa_flags & ~IFA_RTSELF) | RTF_UP;
 	error = rtrequest(RTM_ADD, (struct sockaddr *)&pr->ndpr_prefix,
 	    ifa->ifa_addr, (struct sockaddr *)&mask6, rtflags, &rt);
 	if (error == 0) {
diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c
index 8a3410fd8f8..31426583898 100644
--- a/usr.sbin/arp/arp.c
+++ b/usr.sbin/arp/arp.c
@@ -326,7 +326,6 @@ set(int argc, char **argv)
 			doing_proxy = 1;
 			if (argc && strncmp(argv[1], "only", 3) == 0) {
 				proxy_only = 1;
-				dst->sin_other = SIN_PROXY;
 				argc--; argv++;
 			}
 		} else if (strncmp(argv[0], "blackhole", 9) == 0) {
@@ -365,33 +364,30 @@ set(int argc, char **argv)
 			sdl_m.sdl_alen = ETHER_ADDR_LEN;
 		}
 	}
-	for (;;) {	/* try at most twice */
-		rtm = rtmsg(RTM_GET, dst, &sdl_m);
-		if (rtm == NULL) {
-			warn("%s", host);
-			return (1);
-		}
-		addr = (struct sockaddr_inarp *)(rtm + 1);
-		sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr);
-		if (addr->sin_addr.s_addr != dst->sin_addr.s_addr)	
-			break;
-		if (sdl->sdl_family == AF_LINK &&
-		    !(rtm->rtm_flags & RTF_GATEWAY) &&
-		    valid_type(sdl->sdl_type) )
-			break;
-		if (doing_proxy == 0) {
-			printf("set: can only proxy for %s\n", host);
-			return (1);
-		}
-		if (dst->sin_other & SIN_PROXY) {
-			printf("set: proxy entry exists for non 802 device\n");
-			return (1);
-		}
-		dst->sin_other = SIN_PROXY;
-		proxy_only = 1;
+
+	/*
+	 * In the case a proxy-arp entry is being added for
+	 * a remote end point, the RTF_ANNOUNCE flag in the 
+	 * RTM_GET command is an indication to the kernel
+	 * routing code that the interface associated with
+	 * the prefix route covering the local end of the
+	 * PPP link should be returned, on which ARP applies.
+	 */
+	rtm = rtmsg(RTM_GET, dst, &sdl_m);
+	if (rtm == NULL) {
+		warn("%s", host);
+		return (1);
+	}
+	addr = (struct sockaddr_inarp *)(rtm + 1);
+	sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr);
+	if (addr->sin_addr.s_addr == dst->sin_addr.s_addr) {
+		printf("set: proxy entry exists for non 802 device\n");
+		return (1);
 	}
 
-	if (sdl->sdl_family != AF_LINK) {
+	if ((sdl->sdl_family != AF_LINK) ||
+	    (rtm->rtm_flags & RTF_GATEWAY) ||
+	    !valid_type(sdl->sdl_type)) {
 		printf("cannot intuit interface index and type for %s\n", host);
 		return (1);
 	}
@@ -436,7 +432,11 @@ delete(char *host, int do_proxy)
 	dst = getaddr(host);
 	if (dst == NULL)
 		return (1);
-	dst->sin_other = do_proxy;
+
+	/*
+	 * Perform a regular entry delete first.
+	 */
+	flags &= ~RTF_ANNOUNCE;
 
 	/*
 	 * setup the data structure to notify the kernel
@@ -471,11 +471,16 @@ delete(char *host, int do_proxy)
 			break;
 		}
 
-		if (dst->sin_other & SIN_PROXY) {
+		/*
+		 * Regualar entry delete failed, now check if there
+		 * is a proxy-arp entry to remove.
+		 */
+		if (flags & RTF_ANNOUNCE) {
 			fprintf(stderr, "delete: cannot locate %s\n",host);
 			return (1);
 		}
-		dst->sin_other = SIN_PROXY;
+
+		flags |= RTF_ANNOUNCE;
 	}
 	rtm->rtm_flags |= RTF_LLDATA;
 	if (rtmsg(RTM_DELETE, dst, NULL) != NULL) {
@@ -485,6 +490,7 @@ delete(char *host, int do_proxy)
 	return (1);
 }
 
+
 /*
  * Search the arp table and do some action on matching entries
  */

From c5f368cee7056d57c971e60cd0ce76a814468b8b Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 5 Jan 2010 22:28:23 +0000
Subject: [PATCH 1033/2592] MFC r201284

Multiple IPv6 addresses of the same prefix can be installed on the
same interface. The first address will install the prefix route into
the kernel routing table and that prefix will be marked as on-link.
Without RADIX_MPATH enabled, the other address aliases of the same
prefix will update the prefix reference count but no other routes
will be installed. Consequently the prefixes associated with these
addresses would not be marked as on-link. As such, incoming packets
destined to these address aliases will fail the ND6 on-link check
on input. This patch fixes the above problem by searching the kernel
routing table and try to find an on-link prefix on the given interface.
---
 sys/netinet6/nd6.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 0297972cd3e..50c273d87a3 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -934,8 +934,28 @@ nd6_is_new_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp)
 		if (pr->ndpr_ifp != ifp)
 			continue;
 
-		if (!(pr->ndpr_stateflags & NDPRF_ONLINK))
-			continue;
+		if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) {
+			struct rtentry *rt;
+			rt = rtalloc1((struct sockaddr *)&pr->ndpr_prefix, 0, 0);
+			if (rt == NULL)
+				continue;
+			/*
+			 * This is the case where multiple interfaces
+			 * have the same prefix, but only one is installed 
+			 * into the routing table and that prefix entry
+			 * is not the one being examined here. In the case
+			 * where RADIX_MPATH is enabled, multiple route
+			 * entries (of the same rt_key value) will be 
+			 * installed because the interface addresses all
+			 * differ.
+			 */
+			if (!IN6_ARE_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr,
+			       &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr)) {
+				RTFREE_LOCKED(rt);
+				continue;
+			}
+			RTFREE_LOCKED(rt);
+		}
 
 		if (IN6_ARE_MASKED_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr,
 		    &addr->sin6_addr, &pr->ndpr_mask))

From a17a2dcab6ce55d5b46027b5ccd896e3a15efc40 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 5 Jan 2010 22:33:10 +0000
Subject: [PATCH 1034/2592] MFC r201285

Consolidate the route message generation code for when address
aliases were added or deleted. The announced route entry for
an address alias is no longer empty because this empty route
entry was causing some route daemon to fail and exit abnormally.
---
 sys/netinet/in.c | 97 ++++++++++++++++++++++++------------------------
 1 file changed, 49 insertions(+), 48 deletions(-)

diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index ed8ef061ae8..ed34b249c48 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -950,6 +950,49 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
 #define rtinitflags(x) \
 	((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
 	    ? RTF_HOST : 0)
+
+/*
+ * Generate a routing message when inserting or deleting 
+ * an interface address alias.
+ */
+static void in_addralias_rtmsg(int cmd, struct in_addr *prefix, 
+    struct in_ifaddr *target)
+{
+	struct route pfx_ro;
+	struct sockaddr_in *pfx_addr;
+	struct rtentry msg_rt;
+
+	/* QL: XXX
+	 * This is a bit questionable because there is no
+	 * additional route entry added/deleted for an address
+	 * alias. Therefore this route report is inaccurate.
+	 */
+	bzero(&pfx_ro, sizeof(pfx_ro));
+	pfx_addr = (struct sockaddr_in *)(&pfx_ro.ro_dst);
+	pfx_addr->sin_len = sizeof(*pfx_addr);
+	pfx_addr->sin_family = AF_INET;
+	pfx_addr->sin_addr = *prefix;
+	rtalloc_ign_fib(&pfx_ro, 0, 0);
+	if (pfx_ro.ro_rt != NULL) {
+		msg_rt = *pfx_ro.ro_rt;
+
+		/* QL: XXX
+		 * Point the gateway to the new interface
+		 * address as if a new prefix route entry has 
+		 * been added through the new address alias. 
+		 * All other parts of the rtentry is accurate, 
+		 * e.g., rt_key, rt_mask, rt_ifp etc.
+		 */
+		msg_rt.rt_gateway = 
+			(struct sockaddr *)&target->ia_addr;
+		rt_newaddrmsg(cmd, 
+			      (struct ifaddr *)target,
+			      0, &msg_rt);
+		RTFREE(pfx_ro.ro_rt);
+	}
+	return;
+}
+
 /*
  * Check if we have a route for the given prefix already or add one accordingly.
  */
@@ -997,40 +1040,7 @@ in_addprefix(struct in_ifaddr *target, int flags)
 				IN_IFADDR_RUNLOCK();
 				return (EEXIST);
 			} else {
-				struct route pfx_ro;
-				struct sockaddr_in *pfx_addr;
-				struct rtentry msg_rt;
-
-				/* QL: XXX
-				 * This is a bit questionable because there is no
-				 * additional route entry added for an address alias.
-				 * Therefore this route report is inaccurate. Perhaps
-				 * it's better to supply a empty rtentry as how it
-				 * is done in in_scrubprefix().
-				 */
-				bzero(&pfx_ro, sizeof(pfx_ro));
-				pfx_addr = (struct sockaddr_in *)(&pfx_ro.ro_dst);
-				pfx_addr->sin_len = sizeof(*pfx_addr);
-				pfx_addr->sin_family = AF_INET;
-				pfx_addr->sin_addr = prefix;
-				rtalloc_ign_fib(&pfx_ro, 0, 0);
-				if (pfx_ro.ro_rt != NULL) {
-					msg_rt = *pfx_ro.ro_rt;
-					/* QL: XXX
-					 * Point the gateway to the given interface
-					 * address as if a new prefix route entry has 
-					 * been added through the new address alias. 
-					 * All other parts of the rtentry is accurate, 
-					 * e.g., rt_key, rt_mask, rt_ifp etc.
-					 */
-					msg_rt.rt_gateway = 
-						(struct sockaddr *)&ia->ia_addr;
-					rt_newaddrmsg(RTM_ADD, 
-						      (struct ifaddr *)target,
-						      0, &msg_rt);
-					RTFREE(pfx_ro.ro_rt);
-				}
-
+				in_addralias_rtmsg(RTM_ADD, &prefix, target);
 				IN_IFADDR_RUNLOCK();
 				return (0);
 			}
@@ -1099,20 +1109,6 @@ in_scrubprefix(struct in_ifaddr *target)
 		arp_ifscrub(target->ia_ifp, IA_SIN(target)->sin_addr.s_addr);
 	}
 
-	if ((target->ia_flags & IFA_ROUTE) == 0) {
-		struct rtentry rt;
-
-		/* QL: XXX
-		 * Report a blank rtentry when a route has not been
-		 * installed for the given interface address.
-		 */
-		bzero(&rt, sizeof(rt));
-		rt_newaddrmsg(RTM_DELETE, 
-			      (struct ifaddr *)target,
-			      0, &rt);
-		return (0);
-	}
-
 	if (rtinitflags(target))
 		prefix = target->ia_dstaddr.sin_addr;
 	else {
@@ -1121,6 +1117,11 @@ in_scrubprefix(struct in_ifaddr *target)
 		prefix.s_addr &= mask.s_addr;
 	}
 
+	if ((target->ia_flags & IFA_ROUTE) == 0) {
+		in_addralias_rtmsg(RTM_DELETE, &prefix, target);
+		return (0);
+	}
+
 	IN_IFADDR_RLOCK();
 	TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
 		if (rtinitflags(ia))

From 130fd3bc32870c485fd5c0ed1c0e944b1867e10c Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 5 Jan 2010 22:37:05 +0000
Subject: [PATCH 1035/2592] MFC r201319

Remove a deleted comment line that was brought back by
my previous commit.
---
 sys/net/if_var.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 53802446b13..58e2837ff25 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -846,7 +846,6 @@ void	if_ref(struct ifnet *);
 void	if_rele(struct ifnet *);
 int	if_setlladdr(struct ifnet *, const u_char *, int);
 void	if_up(struct ifnet *);
-/*void	ifinit(void);*/ /* declared in systm.h for main() */
 int	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
 int	ifpromisc(struct ifnet *, int);
 struct	ifnet *ifunit(const char *);

From c7fabb717622b35a5643cdecba354eb1c7a8c0fd Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Wed, 6 Jan 2010 08:26:43 +0000
Subject: [PATCH 1037/2592] MFC r201290: Treat an empty argument as an error,
 instead of fetching the contents of the root directory.

---
 usr.bin/fetch/fetch.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c
index 2512a2e8632..7553bd8d102 100644
--- a/usr.bin/fetch/fetch.c
+++ b/usr.bin/fetch/fetch.c
@@ -340,6 +340,11 @@ fetch(char *URL, const char *path)
 		fetchDebug = 1;
 
 	/* parse URL */
+	url = NULL;
+	if (*URL == '\0') {
+		warnx("empty URL");
+		goto failure;
+	}
 	if ((url = fetchParseURL(URL)) == NULL) {
 		warnx("%s: parse error", URL);
 		goto failure;

From a0a23c972722c71a389250efb9858a6d8c79330f Mon Sep 17 00:00:00 2001
From: Jung-uk Kim 
Date: Wed, 6 Jan 2010 20:28:47 +0000
Subject: [PATCH 1038/2592] MFC:	r200251

- Try pre-allocating all FIBs upfront.  Previously we tried pre-allocating
128 FIBs first and allocated more later if necessary.  Remove now unused
definitions from the header file[1].
- Force sequential bus scanning.  It seems parallel scanning is in fact
slower and causes more harm than good[1].  Adjust a comment to reflect that.
---
 sys/dev/aac/aac.c     | 2 +-
 sys/dev/aac/aac_cam.c | 7 +++++--
 sys/dev/aac/aacvar.h  | 7 -------
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index 8713cbbee7b..b8aed26871e 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -604,7 +604,7 @@ aac_alloc(struct aac_softc *sc)
 	TAILQ_INIT(&sc->aac_fibmap_tqh);
 	sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command),
 				  M_AACBUF, M_WAITOK|M_ZERO);
-	while (sc->total_fibs < AAC_PREALLOCATE_FIBS) {
+	while (sc->total_fibs < sc->aac_max_fibs) {
 		if (aac_alloc_commands(sc) != 0)
 			break;
 	}
diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c
index ddf19f335b8..e9fc8e26c00 100644
--- a/sys/dev/aac/aac_cam.c
+++ b/sys/dev/aac/aac_cam.c
@@ -260,8 +260,11 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
 		cpi->hba_inquiry = PI_WIDE_16;
 		cpi->target_sprt = 0;
 
-		/* Resetting via the passthrough causes problems. */
-		cpi->hba_misc = PIM_NOBUSRESET;
+		/*
+		 * Resetting via the passthrough or parallel bus scan
+		 * causes problems.
+		 */
+		cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN;
 		cpi->hba_eng_cnt = 0;
 		cpi->max_target = camsc->inf->TargetsPerBus;
 		cpi->max_lun = 8;	/* Per the controller spec */
diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h
index 7f64371ef86..cf0971f0de9 100644
--- a/sys/dev/aac/aacvar.h
+++ b/sys/dev/aac/aacvar.h
@@ -56,13 +56,6 @@
  */
 #define AAC_ADAPTER_FIBS	8
 
-/*
- * FIBs are allocated in page-size chunks and can grow up to the 512
- * limit imposed by the hardware.
- */
-#define AAC_PREALLOCATE_FIBS	128
-#define AAC_NUM_MGT_FIB		8
-
 /*
  * The controller reports status events in AIFs.  We hang on to a number of
  * these in order to pass them out to user-space management tools.

From ef80613c4b849bfbd315500a0591987f449d8cd3 Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Wed, 6 Jan 2010 20:40:41 +0000
Subject: [PATCH 1039/2592] MFC r200820:

  Support the tablet in (at least) the Toshiba Portege M200 Tablet PC.
  This device only appears on the ACPI bus, so isn't caught by the current
  entry for it in the uart(4) ISA attachment.

PR:		kern/140172
Reviewed by:	jhb, marcel
Approved by:	ed (mentor, implicit)
---
 sys/dev/uart/uart_bus_acpi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/uart/uart_bus_acpi.c b/sys/dev/uart/uart_bus_acpi.c
index 042dfef5d21..d320b73a799 100644
--- a/sys/dev/uart/uart_bus_acpi.c
+++ b/sys/dev/uart/uart_bus_acpi.c
@@ -59,6 +59,7 @@ static driver_t uart_acpi_driver = {
 static struct isa_pnp_id acpi_ns8250_ids[] = {
 	{0x0005d041, "Standard PC COM port"},		/* PNP0500 */
 	{0x0105d041, "16550A-compatible COM port"},	/* PNP0501 */
+	{0x04f0235c, "Wacom Tablet PC Screen"},		/* WACF004 */
 	{0}
 };
 

From 88af2d60d9ebd458960628b1eaee8c1a39bd8661 Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Wed, 6 Jan 2010 20:54:04 +0000
Subject: [PATCH 1040/2592] MFC r200819:

  Grammar and minor tweaks to powerd(8) man page.

PR:		docs/133186
Approved by:	ed (mentor, implicit)
---
 usr.sbin/powerd/powerd.8 | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/usr.sbin/powerd/powerd.8 b/usr.sbin/powerd/powerd.8
index 7465410a665..580886268e0 100644
--- a/usr.sbin/powerd/powerd.8
+++ b/usr.sbin/powerd/powerd.8
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd December 24, 2008
+.Dd December 21, 2009
 .Dt POWERD 8
 .Os
 .Sh NAME
@@ -45,7 +45,7 @@ The
 .Nm
 utility monitors the system state and sets various power control options
 accordingly.
-It offers three modes (maximum, minimum, and adaptive) that can be
+It offers four modes (maximum, minimum, adaptive and hiadaptive) that can be
 individually selected while on AC power or batteries.
 The modes maximum, minimum, adaptive and hiadaptive may be abbreviated
 max, min, adp, hadp.
@@ -57,9 +57,10 @@ Adaptive mode attempts to strike a balance by degrading performance when
 the system appears idle and increasing it when the system is busy.
 It offers a good balance between a small performance loss for greatly
 increased power savings.
-Hiadaptive mode is alike adaptive mode, but tuned for systems where
+Hiadaptive mode is like adaptive mode, but tuned for systems where
 performance and interactivity are more important then power consumption.
-It rises frequency faster, drops slower and keeps twice lower CPU load.
+It increases frequency faster, reduces the frequency less aggressively and
+will maintain full frequency for longer.
 The default mode is adaptive for battery power and hiadaptive for the rest.
 .Pp
 The

From d14e59b97c7df3957dd6cd148666685322215584 Mon Sep 17 00:00:00 2001
From: "Simon L. B. Nielsen" 
Date: Wed, 6 Jan 2010 21:45:30 +0000
Subject: [PATCH 1041/2592] Fix BIND named(8) cache poisoning with DNSSEC
 validation. [SA-10:01]

Fix ntpd mode 7 denial of service. [SA-10:02]

Fix ZFS ZIL playback with insecure permissions. [SA-10:03]

Various FreeBSD 8.0-RELEASE improvements. [EN-10:01]

Security:	FreeBSD-SA-10:01.bind
Security:	FreeBSD-SA-10:02.ntpd
Security:	FreeBSD-SA-10:03.zfs
Errata:		FreeBSD-EN-10:01.freebsd
Approved by:	so (simon)
---
 contrib/ntp/ntpd/ntp_request.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/contrib/ntp/ntpd/ntp_request.c b/contrib/ntp/ntpd/ntp_request.c
index b1bc99d6f3f..67bad2a8b9f 100644
--- a/contrib/ntp/ntpd/ntp_request.c
+++ b/contrib/ntp/ntpd/ntp_request.c
@@ -409,6 +409,7 @@ process_private(
 	int mod_okay
 	)
 {
+	static u_long quiet_until;
 	struct req_pkt *inpkt;
 	struct req_pkt_tail *tailinpkt;
 	struct sockaddr_storage *srcadr;
@@ -444,8 +445,14 @@ process_private(
 	    || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0)
 	    || (++ec, rbufp->recv_length < REQ_LEN_HDR)
 		) {
-		msyslog(LOG_ERR, "process_private: INFO_ERR_FMT: test %d failed, pkt from %s", ec, stoa(srcadr));
-		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+		NLOG(NLOG_SYSEVENT)
+			if (current_time >= quiet_until) {
+				msyslog(LOG_ERR,
+					"process_private: drop test %d"
+					" failed, pkt from %s",
+					ec, stoa(srcadr));
+				quiet_until = current_time + 60;
+			}
 		return;
 	}
 

From 2c8f00d0c75df34540b1f02a26a6af7d881374de Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Wed, 6 Jan 2010 22:45:49 +0000
Subject: [PATCH 1042/2592] MFC r198923-198924,198927-198928

r198923:
  Use correct dma tag for jumbo buffer.

r198924:
  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.

r198927:
  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.

r198928:
  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    | 122 +++++++++++++++++++++++-----------------
 sys/dev/bge/if_bgereg.h |   5 +-
 2 files changed, 73 insertions(+), 54 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 251f5b5e08e..505b6123828 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,27 +932,24 @@ 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_rx_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,
+	bus_dmamap_sync(sc->bge_cdata.bge_rx_mtag,
 	    sc->bge_cdata.bge_rx_std_dmamap[i],
 	    BUS_DMASYNC_PREREAD);
 
@@ -1031,7 +1028,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);
 
@@ -1047,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,
@@ -1071,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;
@@ -1088,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,
@@ -1141,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;
@@ -1979,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]);
 	}
 
@@ -1993,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. */
@@ -2109,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,
@@ -2134,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);
 		}
 	}
@@ -3168,18 +3179,17 @@ 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;
 			}
 		} 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;
@@ -3189,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;
@@ -3309,10 +3318,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;
@@ -3645,7 +3654,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);
@@ -3655,8 +3664,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;
@@ -3670,11 +3679,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];
@@ -3886,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
@@ -3907,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;
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 1a03353586d8ffc95a2c9ef4d72561a030504fbd Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Wed, 6 Jan 2010 23:02:35 +0000
Subject: [PATCH 1043/2592] MFC
 r198967,199009-199011,199014,199020,199035-199036,199054

r198967:
  Correct MSI mode register bits.

r199009:
  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.

r199010:
  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.

r199011:
  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.

r199014:
  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.

r199020:
  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().

r199035:
  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.

r199036:
  Count number of inbound packets which were chosen to be discarded
  as input errors. Also count out of receive BDs as input errors.

r199054:
  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.
---
 sys/dev/bge/if_bge.c    | 188 ++++++++++++++++++++++------------------
 sys/dev/bge/if_bgereg.h |  16 +---
 2 files changed, 106 insertions(+), 98 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 505b6123828..54c310bcc21 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);
 }
@@ -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, NULL)) != 0)
+		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, NULL)) != 0)
+		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,
@@ -1979,6 +1983,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 +1993,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 +2143,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 +2251,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]);
@@ -2699,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);
@@ -2814,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.
 	 */
@@ -3134,7 +3160,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);
 
@@ -3165,45 +3192,31 @@ 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) {
-				ifp->if_ierrors++;
-				bge_newbuf_jumbo(sc, sc->bge_jumbo, m);
+				BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT);
 				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;
 			}
+			BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT);
 		} 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) {
-				ifp->if_ierrors++;
-				bge_newbuf_std(sc, sc->bge_std, m);
+				BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT);
 				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;
 			}
+			BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT);
 		}
 
 		ifp->if_ipackets++;
@@ -3266,7 +3279,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);
 
@@ -3542,7 +3555,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
@@ -3920,7 +3935,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);
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index 073c82e8c48..99f0d4b3c9a 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
@@ -2484,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
 
@@ -2547,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 ed797ec921d42f5202d9f060e1a2ffca740eebc9 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Wed, 6 Jan 2010 23:26:09 +0000
Subject: [PATCH 1044/2592] MFC r199065,199115-199116,199153,199661-199662

r199065:
  Correct disabling checksum offloading for BCM5700 B0.

r199115:
  Add missing bus_dmamap_sync(9) before issuing kick command.

r199116:
  Zero out Tx/Rx descriptors before using them. Also add missing
  bus_dmamap_sync(9) after Tx descriptor initialization.

r199153:
  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).

r199661:
  Remove extra white space.

r199662:
  Fix typo introduced in r199011.
---
 sys/dev/bge/if_bge.c    | 39 +++++++++++++++++++++++----------------
 sys/dev/bge/if_bgereg.h |  2 +-
 2 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 54c310bcc21..a88cfa974ec 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -238,7 +238,7 @@ static const struct bge_vendor {
 
 	{ 0, NULL }
 };
-	
+
 static const struct bge_revision {
 	uint32_t	br_chipid;
 	const char	*br_name;
@@ -295,7 +295,7 @@ static const struct bge_revision {
 	{ 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_A0,	"BCM5754/5787 A0" },
 	{ BGE_CHIPID_BCM5787_A1,	"BCM5754/5787 A1" },
 	{ BGE_CHIPID_BCM5787_A2,	"BCM5754/5787 A2" },
 	{ BGE_CHIPID_BCM5906_A1,	"BCM5906 A1" },
@@ -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,10 @@ 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_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);
@@ -1278,11 +1284,11 @@ bge_sig_post_reset(sc, type)
 	if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
 		switch (type) {
 		case BGE_RESET_START:
-			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001); 
+			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001);
 			/* START DONE */
 			break;
 		case BGE_RESET_STOP:
-			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002); 
+			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002);
 			break;
 		}
 	}
@@ -1674,7 +1680,7 @@ bge_blockinit(struct bge_softc *sc)
 	RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
 	RCB_WRITE_4(sc, vrcb, bge_nicaddr, 0x00000000);
 	RCB_WRITE_4(sc, vrcb, bge_maxlen_flags,
-	    BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt, 0));	
+	    BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt, 0));
 
 	/* Set random backoff seed for TX */
 	CSR_WRITE_4(sc, BGE_TX_RANDOM_BACKOFF,
@@ -1904,7 +1910,7 @@ bge_lookup_vendor(uint16_t vid)
 	for (v = bge_vendors; v->v_name != NULL; v++)
 		if (v->v_id == vid)
 			return (v);
-		
+
 	panic("%s: unknown vendor %d", __func__, vid);
 	return (NULL);
 }
@@ -2255,7 +2261,7 @@ bge_dma_alloc(device_t dev)
 		    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");
+			    "can't create spare DMA map for jumbo RX\n");
 			return (ENOMEM);
 		}
 		for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
@@ -2743,7 +2749,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;
 	}
 
@@ -2989,7 +2995,7 @@ bge_reset(struct bge_softc *sc)
 		}
 	}
 
-	/* 
+	/*
 	 * Set GPHY Power Down Override to leave GPHY
 	 * powered up in D0 uninitialized.
 	 */
@@ -3316,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.
@@ -3625,7 +3630,7 @@ bge_cksum_pad(struct mbuf *m)
 			last = n;
 		}
 	}
-	
+
 	/* Now zero the pad area, to avoid the bge cksum-assist bug. */
 	memset(mtod(last, caddr_t) + last->m_len, 0, padlen);
 	last->m_len += padlen;
@@ -3826,6 +3831,8 @@ 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_PREWRITE);
 	/* Transmit. */
 	bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
 	/* 5700 b2 errata */
@@ -3977,7 +3984,7 @@ bge_init_locked(struct bge_softc *sc)
 	BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
 	bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
 	}
-	
+
 	bge_ifmedia_upd_locked(ifp);
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
@@ -4360,7 +4367,7 @@ bge_stop(struct bge_softc *sc)
 	bge_sig_legacy(sc, BGE_RESET_STOP);
 	bge_sig_post_reset(sc, BGE_RESET_STOP);
 
-	/* 
+	/*
 	 * Keep the ASF firmware running if up.
 	 */
 	if (sc->bge_asf_mode & ASF_STACKUP)
@@ -4700,7 +4707,7 @@ bge_add_sysctls(struct bge_softc *sc)
 	BGE_SYSCTL_STAT(sc, ctx, "Multiple Collision Frames",
 	    children, txstats.dot3StatsMultipleCollisionFrames,
 	    "MultipleCollisionFrames");
-	BGE_SYSCTL_STAT(sc, ctx, "Deferred Transmissions", 
+	BGE_SYSCTL_STAT(sc, ctx, "Deferred Transmissions",
 	    children, txstats.dot3StatsDeferredTransmissions,
 	    "DeferredTransmissions");
 	BGE_SYSCTL_STAT(sc, ctx, "Excessive Collisions",
@@ -4709,7 +4716,7 @@ bge_add_sysctls(struct bge_softc *sc)
 	BGE_SYSCTL_STAT(sc, ctx, "Late Collisions",
 	    children, txstats.dot3StatsLateCollisions,
 	    "LateCollisions");
-	BGE_SYSCTL_STAT(sc, ctx, "Outbound Unicast Packets", 
+	BGE_SYSCTL_STAT(sc, ctx, "Outbound Unicast Packets",
 	    children, txstats.ifHCOutUcastPkts, "UcastPkts");
 	BGE_SYSCTL_STAT(sc, ctx, "Outbound Multicast Packets",
 	    children, txstats.ifHCOutMulticastPkts, "MulticastPkts");
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index 99f0d4b3c9a..4179db6206e 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -1907,7 +1907,7 @@
 /*
  * This magic number is written to the firmware mailbox at 0xb50
  * before a software reset is issued.  After the internal firmware
- * has completed its initialization it will write the opposite of 
+ * has completed its initialization it will write the opposite of
  * this value, ~BGE_MAGIC_NUMBER, to the same location, allowing the
  * driver to synchronize with the firmware.
  */

From 1377b76a28d6215ae3dfb4aedcc25776a1475ad1 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Wed, 6 Jan 2010 23:34:53 +0000
Subject: [PATCH 1045/2592] MFC 199663-199666

r199663:
  Due to newly added PCIe capabilities fallback code for finding the
  PCIe capability did not work right on recent controllers. Remove
  FreeBSD 6.x support code.

r199664:
  Use capability pointer to access PCIe registers rather than
  directly access them at fixed address. While I'm here don't touch
  other bits of PCIe device control register except max payload size.

r199665:
  Controller does not write Rx descriptors, remove BUS_DMASYNC_PREREAD.

r199666:
  Rearrange bge_start_locked to see we can send more frames by
  checking IFF_DRV_RUNNING and IFF_DRV_OACTIVE flags. Also if we
  have less than 16 free send BDs set IFF_DRV_OACTIVE and try it
  later. Previously bge(4) used to reserve 16 free send BDs after
  loading dma maps but hardware just need one reserved send BD. If
  prouder index has the same value of consumer index it means the Tx
  queue is empty.
  While I'm here check IFQ_DRV_IS_EMPTY first to save one lock
  operation.
---
 sys/dev/bge/if_bge.c    | 141 +++++++++++++++++++---------------------
 sys/dev/bge/if_bgereg.h |   3 +
 2 files changed, 69 insertions(+), 75 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index a88cfa974ec..bf3578cdf0b 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -414,7 +414,7 @@ static uint32_t bge_readreg_ind(struct bge_softc *, int);
 #endif
 static void bge_writemem_direct(struct bge_softc *, int, int);
 static void bge_writereg_ind(struct bge_softc *, int, int);
-static void bge_set_max_readrq(struct bge_softc *, int);
+static void bge_set_max_readrq(struct bge_softc *);
 
 static int bge_miibus_readreg(device_t, int, int);
 static int bge_miibus_writereg(device_t, int, int, int);
@@ -558,25 +558,23 @@ bge_writemem_ind(struct bge_softc *sc, int off, int val)
  * PCI Express only
  */
 static void
-bge_set_max_readrq(struct bge_softc *sc, int expr_ptr)
+bge_set_max_readrq(struct bge_softc *sc)
 {
 	device_t dev;
 	uint16_t val;
 
-	KASSERT((sc->bge_flags & BGE_FLAG_PCIE) && expr_ptr != 0,
-	    ("%s: not applicable", __func__));
-
 	dev = sc->bge_dev;
 
-	val = pci_read_config(dev, expr_ptr + BGE_PCIE_DEVCTL, 2);
-	if ((val & BGE_PCIE_DEVCTL_MAX_READRQ_MASK) !=
+	val = pci_read_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL, 2);
+	if ((val & PCIM_EXP_CTL_MAX_READ_REQUEST) !=
 	    BGE_PCIE_DEVCTL_MAX_READRQ_4096) {
 		if (bootverbose)
 			device_printf(dev, "adjust device control 0x%04x ",
 			    val);
-		val &= ~BGE_PCIE_DEVCTL_MAX_READRQ_MASK;
+		val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST;
 		val |= BGE_PCIE_DEVCTL_MAX_READRQ_4096;
-		pci_write_config(dev, expr_ptr + BGE_PCIE_DEVCTL, val, 2);
+		pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL,
+		    val, 2);
 		if (bootverbose)
 			printf("-> 0x%04x\n", val);
 	}
@@ -1055,8 +1053,7 @@ bge_init_rx_ring_std(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_PREREAD | BUS_DMASYNC_PREWRITE);
+	    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREWRITE);
 
 	sc->bge_std = i - 1;
 	bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
@@ -1099,8 +1096,7 @@ bge_init_rx_ring_jumbo(struct bge_softc *sc)
 	};
 
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
-	    sc->bge_cdata.bge_rx_jumbo_ring_map,
-	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+	    sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE);
 
 	sc->bge_jumbo = i - 1;
 
@@ -2413,7 +2409,6 @@ bge_dma_alloc(device_t dev)
 	return (0);
 }
 
-#if __FreeBSD_version > 602105
 /*
  * Return true if this device has more than one port.
  */
@@ -2462,7 +2457,6 @@ bge_can_use_msi(struct bge_softc *sc)
 	}
 	return (can_use_msi);
 }
-#endif
 
 static int
 bge_attach(device_t dev)
@@ -2471,7 +2465,7 @@ bge_attach(device_t dev)
 	struct bge_softc *sc;
 	uint32_t hwcfg = 0, misccfg;
 	u_char eaddr[ETHER_ADDR_LEN];
-	int error, reg, rid, trys;
+	int error, msicount, reg, rid, trys;
 
 	sc = device_get_softc(dev);
 	sc->bge_dev = dev;
@@ -2580,42 +2574,34 @@ bge_attach(device_t dev)
   	/*
 	 * Check if this is a PCI-X or PCI Express device.
   	 */
-#if __FreeBSD_version > 602101
 	if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
 		/*
 		 * Found a PCI Express capabilities register, this
 		 * must be a PCI Express device.
 		 */
-		if (reg != 0) {
-			sc->bge_flags |= BGE_FLAG_PCIE;
-#else
-	if (BGE_IS_5705_PLUS(sc)) {
-		reg = pci_read_config(dev, BGE_PCIE_CAPID_REG, 4);
-		if ((reg & 0xFF) == BGE_PCIE_CAPID) {
-			sc->bge_flags |= BGE_FLAG_PCIE;
-			reg = BGE_PCIE_CAPID;
-#endif
-			bge_set_max_readrq(sc, reg);
-		}
+		sc->bge_flags |= BGE_FLAG_PCIE;
+		sc->bge_expcap = reg;
+		bge_set_max_readrq(sc);
 	} else {
 		/*
 		 * Check if the device is in PCI-X Mode.
 		 * (This bit is not valid on PCI Express controllers.)
 		 */
+		if (pci_find_extcap(dev, PCIY_PCIX, ®) == 0)
+			sc->bge_pcixcap = reg;
 		if ((pci_read_config(dev, BGE_PCI_PCISTATE, 4) &
 		    BGE_PCISTATE_PCI_BUSMODE) == 0)
 			sc->bge_flags |= BGE_FLAG_PCIX;
 	}
 
-#if __FreeBSD_version > 602105
-	{
-		int msicount;
-
-		/*
-		 * Allocate the interrupt, using MSI if possible.  These devices
-		 * support 8 MSI messages, but only the first one is used in
-		 * normal operation.
-		 */
+	/*
+	 * Allocate the interrupt, using MSI if possible.  These devices
+	 * support 8 MSI messages, but only the first one is used in
+	 * normal operation.
+	 */
+	rid = 0;
+	if (pci_find_extcap(sc->bge_dev, PCIY_MSI, ®) != 0) {
+		sc->bge_msicap = reg;
 		if (bge_can_use_msi(sc)) {
 			msicount = pci_msi_count(dev);
 			if (msicount > 1)
@@ -2625,12 +2611,8 @@ bge_attach(device_t dev)
 		if (msicount == 1 && pci_alloc_msi(dev, &msicount) == 0) {
 			rid = 1;
 			sc->bge_flags |= BGE_FLAG_MSI;
-		} else
-			rid = 0;
+		}
 	}
-#else
-	rid = 0;
-#endif
 
 	sc->bge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
 	    RF_SHAREABLE | RF_ACTIVE);
@@ -2921,10 +2903,8 @@ bge_release_resources(struct bge_softc *sc)
 		bus_release_resource(dev, SYS_RES_IRQ,
 		    sc->bge_flags & BGE_FLAG_MSI ? 1 : 0, sc->bge_irq);
 
-#if __FreeBSD_version > 602105
 	if (sc->bge_flags & BGE_FLAG_MSI)
 		pci_release_msi(dev);
-#endif
 
 	if (sc->bge_res != NULL)
 		bus_release_resource(dev, SYS_RES_MEMORY,
@@ -2945,6 +2925,7 @@ bge_reset(struct bge_softc *sc)
 	device_t dev;
 	uint32_t cachesize, command, pcistate, reset, val;
 	void (*write_op)(struct bge_softc *, int, int);
+	uint16_t devctl;
 	int i;
 
 	dev = sc->bge_dev;
@@ -3023,11 +3004,17 @@ bge_reset(struct bge_softc *sc)
 			val = pci_read_config(dev, 0xC4, 4);
 			pci_write_config(dev, 0xC4, val | (1 << 15), 4);
 		}
-		/*
-		 * Set PCIE max payload size to 128 bytes and clear error
-		 * status.
-		 */
-		pci_write_config(dev, 0xD8, 0xF5000, 4);
+		devctl = pci_read_config(dev,
+		    sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL, 2);
+		/* Clear enable no snoop and disable relaxed ordering. */
+		devctl &= ~(0x0010 | 0x0800);
+		/* Set PCIE max payload size to 128. */
+		devctl &= ~PCIM_EXP_CTL_MAX_PAYLOAD;
+		pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL,
+		    devctl, 2);
+		/* Clear error status. */
+		pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_STA,
+		    0, 2);
 	}
 
 	/* Reset some of the PCI state that got zapped by reset. */
@@ -3042,8 +3029,10 @@ bge_reset(struct bge_softc *sc)
 	if (BGE_IS_5714_FAMILY(sc)) {
 		/* This chip disables MSI on reset. */
 		if (sc->bge_flags & BGE_FLAG_MSI) {
-			val = pci_read_config(dev, BGE_PCI_MSI_CTL, 2);
-			pci_write_config(dev, BGE_PCI_MSI_CTL,
+			val = pci_read_config(dev,
+			    sc->bge_msicap + PCIR_MSI_CTRL, 2);
+			pci_write_config(dev,
+			    sc->bge_msicap + PCIR_MSI_CTRL,
 			    val | PCIM_MSICTRL_MSI_ENABLE, 2);
 			val = CSR_READ_4(sc, BGE_MSI_MODE);
 			CSR_WRITE_4(sc, BGE_MSI_MODE,
@@ -3694,11 +3683,8 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
 	} else if (error != 0)
 		return (error);
 
-	/*
-	 * Sanity check: avoid coming within 16 descriptors
-	 * of the end of the ring.
-	 */
-	if (nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16)) {
+	/* Check if we have enough free send BDs. */
+	if (sc->bge_txcnt + nsegs >= BGE_TX_RING_CNT) {
 		bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, map);
 		return (ENOBUFS);
 	}
@@ -3763,18 +3749,25 @@ static void
 bge_start_locked(struct ifnet *ifp)
 {
 	struct bge_softc *sc;
-	struct mbuf *m_head = NULL;
+	struct mbuf *m_head;
 	uint32_t prodidx;
-	int count = 0;
+	int count;
 
 	sc = ifp->if_softc;
+	BGE_LOCK_ASSERT(sc);
 
-	if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+	if (!sc->bge_link ||
+	    (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+	    IFF_DRV_RUNNING)
 		return;
 
 	prodidx = sc->bge_tx_prodidx;
 
-	while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
+	for (count = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd);) {
+		if (sc->bge_txcnt > BGE_TX_RING_CNT - 16) {
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			break;
+		}
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
 		if (m_head == NULL)
 			break;
@@ -3827,24 +3820,22 @@ bge_start_locked(struct ifnet *ifp)
 #endif
 	}
 
-	if (count == 0)
-		/* No packets were dequeued. */
-		return;
-
-	bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
-	    sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
-	/* Transmit. */
-	bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
-	/* 5700 b2 errata */
-	if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
+	if (count > 0) {
+		bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
+		    sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
+		/* Transmit. */
 		bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
+		/* 5700 b2 errata */
+		if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
+			bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
 
-	sc->bge_tx_prodidx = prodidx;
+		sc->bge_tx_prodidx = prodidx;
 
-	/*
-	 * Set a timeout in case the chip goes out to lunch.
-	 */
-	sc->bge_timer = 5;
+		/*
+		 * Set a timeout in case the chip goes out to lunch.
+		 */
+		sc->bge_timer = 5;
+	}
 }
 
 /*
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index 4179db6206e..cc5e0b3f610 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -2584,6 +2584,9 @@ struct bge_softc {
 	struct resource		*bge_irq;
 	struct resource		*bge_res;
 	struct ifmedia		bge_ifmedia;	/* TBI media info */
+	int			bge_expcap;
+	int			bge_msicap;
+	int			bge_pcixcap;
 	uint32_t		bge_flags;
 #define	BGE_FLAG_TBI		0x00000001
 #define	BGE_FLAG_JUMBO		0x00000002

From eefce03276a2ab77cace3204d33c147c2282bde4 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Wed, 6 Jan 2010 23:42:15 +0000
Subject: [PATCH 1046/2592] MFC r199667-199668

r199667:
  Cache Rx producer/Tx consumer index as soon as we know status block
  update and then clear status block. Previously it used to access
  these index without synchronization which may cause problems when
  bounce buffers are used. Also add missing bus_dmamap_sync(9) in
  polling handler. Since we now update status block in driver, adjust
  bus_dmamap_sync(9) for status block.

r199668:
  For MSI case, interrupt is not shared and we don't need to force
  PCI flush to get correct status block update. Add an optimized
  interrupt handler that is activated for MSI case. Actual interrupt
  handling is done by taskqueue such that the handler does not
  require driver lock for Rx path. The MSI capable bge(4) controllers
  automatically disables further interrupt once it enters interrupt
  state so we don't need PIO access to disable interrupt in interrupt
  handler.
---
 sys/dev/bge/if_bge.c    | 153 +++++++++++++++++++++++++++++++++-------
 sys/dev/bge/if_bgereg.h |   2 +
 2 files changed, 129 insertions(+), 26 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index bf3578cdf0b..0bed9dfe9ac 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -361,8 +362,8 @@ static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
 static int bge_get_eaddr_eeprom(struct bge_softc *, uint8_t[]);
 static int bge_get_eaddr(struct bge_softc *, uint8_t[]);
 
-static void bge_txeof(struct bge_softc *);
-static int bge_rxeof(struct bge_softc *);
+static void bge_txeof(struct bge_softc *, uint16_t);
+static int bge_rxeof(struct bge_softc *, uint16_t, int);
 
 static void bge_asf_driver_up (struct bge_softc *);
 static void bge_tick(void *);
@@ -371,6 +372,8 @@ static void bge_stats_update_regs(struct bge_softc *);
 static int bge_encap(struct bge_softc *, struct mbuf **, uint32_t *);
 
 static void bge_intr(void *);
+static int bge_msi_intr(void *);
+static void bge_intr_task(void *, int);
 static void bge_start_locked(struct ifnet *);
 static void bge_start(struct ifnet *);
 static int bge_ioctl(struct ifnet *, u_long, caddr_t);
@@ -2470,6 +2473,8 @@ bge_attach(device_t dev)
 	sc = device_get_softc(dev);
 	sc->bge_dev = dev;
 
+	TASK_INIT(&sc->bge_intr_task, 0, bge_intr_task, sc);
+
 	/*
 	 * Map control/status registers.
 	 */
@@ -2832,8 +2837,27 @@ again:
 	 * Hookup IRQ last.
 	 */
 #if __FreeBSD_version > 700030
-	error = bus_setup_intr(dev, sc->bge_irq, INTR_TYPE_NET | INTR_MPSAFE,
-	   NULL, bge_intr, sc, &sc->bge_intrhand);
+	if (BGE_IS_5755_PLUS(sc) && sc->bge_flags & BGE_FLAG_MSI) {
+		/* Take advantage of single-shot MSI. */
+		sc->bge_tq = taskqueue_create_fast("bge_taskq", M_WAITOK,
+		    taskqueue_thread_enqueue, &sc->bge_tq);
+		if (sc->bge_tq == NULL) {
+			device_printf(dev, "could not create taskqueue.\n");
+			ether_ifdetach(ifp);
+			error = ENXIO;
+			goto fail;
+		}
+		taskqueue_start_threads(&sc->bge_tq, 1, PI_NET, "%s taskq",
+		    device_get_nameunit(sc->bge_dev));
+		error = bus_setup_intr(dev, sc->bge_irq,
+		    INTR_TYPE_NET | INTR_MPSAFE, bge_msi_intr, NULL, sc,
+		    &sc->bge_intrhand);
+		if (error)
+			ether_ifdetach(ifp);
+	} else
+		error = bus_setup_intr(dev, sc->bge_irq,
+		    INTR_TYPE_NET | INTR_MPSAFE, NULL, bge_intr, sc,
+		    &sc->bge_intrhand);
 #else
 	error = bus_setup_intr(dev, sc->bge_irq, INTR_TYPE_NET | INTR_MPSAFE,
 	   bge_intr, sc, &sc->bge_intrhand);
@@ -2875,6 +2899,8 @@ bge_detach(device_t dev)
 
 	callout_drain(&sc->bge_stat_ch);
 
+	if (sc->bge_tq)
+		taskqueue_drain(sc->bge_tq, &sc->bge_intr_task);
 	ether_ifdetach(ifp);
 
 	if (sc->bge_flags & BGE_FLAG_TBI) {
@@ -2896,6 +2922,9 @@ bge_release_resources(struct bge_softc *sc)
 
 	dev = sc->bge_dev;
 
+	if (sc->bge_tq != NULL)
+		taskqueue_free(sc->bge_tq);
+
 	if (sc->bge_intrhand != NULL)
 		bus_teardown_intr(dev, sc->bge_irq, sc->bge_intrhand);
 
@@ -3135,15 +3164,13 @@ bge_reset(struct bge_softc *sc)
  */
 
 static int
-bge_rxeof(struct bge_softc *sc)
+bge_rxeof(struct bge_softc *sc, uint16_t rx_prod, int holdlck)
 {
 	struct ifnet *ifp;
 	int rx_npkts = 0, stdcnt = 0, jumbocnt = 0;
-	uint16_t rx_prod, rx_cons;
+	uint16_t rx_cons;
 
-	BGE_LOCK_ASSERT(sc);
 	rx_cons = sc->bge_rx_saved_considx;
-	rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx;
 
 	/* Nothing to do. */
 	if (rx_cons == rx_prod)
@@ -3259,9 +3286,12 @@ bge_rxeof(struct bge_softc *sc)
 #endif
 		}
 
-		BGE_UNLOCK(sc);
-		(*ifp->if_input)(ifp, m);
-		BGE_LOCK(sc);
+		if (holdlck != 0) {
+			BGE_UNLOCK(sc);
+			(*ifp->if_input)(ifp, m);
+			BGE_LOCK(sc);
+		} else
+			(*ifp->if_input)(ifp, m);
 		rx_npkts++;
 
 		if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
@@ -3296,7 +3326,7 @@ bge_rxeof(struct bge_softc *sc)
 }
 
 static void
-bge_txeof(struct bge_softc *sc)
+bge_txeof(struct bge_softc *sc, uint16_t tx_cons)
 {
 	struct bge_tx_bd *cur_tx = NULL;
 	struct ifnet *ifp;
@@ -3304,8 +3334,7 @@ bge_txeof(struct bge_softc *sc)
 	BGE_LOCK_ASSERT(sc);
 
 	/* Nothing to do. */
-	if (sc->bge_tx_saved_considx ==
-	    sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx)
+	if (sc->bge_tx_saved_considx == tx_cons)
 		return;
 
 	ifp = sc->bge_ifp;
@@ -3316,8 +3345,7 @@ bge_txeof(struct bge_softc *sc)
 	 * Go through our tx ring and free mbufs for those
 	 * frames that have been sent.
 	 */
-	while (sc->bge_tx_saved_considx !=
-	    sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx) {
+	while (sc->bge_tx_saved_considx != tx_cons) {
 		uint32_t		idx = 0;
 
 		idx = sc->bge_tx_saved_considx;
@@ -3348,6 +3376,7 @@ static int
 bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct bge_softc *sc = ifp->if_softc;
+	uint16_t rx_prod, tx_cons;
 	uint32_t statusword;
 	int rx_npkts = 0;
 
@@ -3358,13 +3387,17 @@ bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 	}
 
 	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
-	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTREAD);
+	    sc->bge_cdata.bge_status_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+	rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx;
+	tx_cons = sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx;
 
 	statusword = atomic_readandclear_32(
 	    &sc->bge_ldata.bge_status_block->bge_status);
 
 	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
-	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
+	    sc->bge_cdata.bge_status_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	/* Note link event. It will be processed by POLL_AND_CHECK_STATUS. */
 	if (statusword & BGE_STATFLAG_LINKSTATE_CHANGED)
@@ -3377,12 +3410,12 @@ bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 			bge_link_upd(sc);
 
 	sc->rxcycles = count;
-	rx_npkts = bge_rxeof(sc);
+	rx_npkts = bge_rxeof(sc, rx_prod, 1);
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 		BGE_UNLOCK(sc);
 		return (rx_npkts);
 	}
-	bge_txeof(sc);
+	bge_txeof(sc, tx_cons);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		bge_start_locked(ifp);
 
@@ -3391,12 +3424,76 @@ bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 }
 #endif /* DEVICE_POLLING */
 
+static int
+bge_msi_intr(void *arg)
+{
+	struct bge_softc *sc;
+
+	sc = (struct bge_softc *)arg;
+	/*
+	 * This interrupt is not shared and controller already
+	 * disabled further interrupt.
+	 */
+	taskqueue_enqueue(sc->bge_tq, &sc->bge_intr_task);
+	return (FILTER_HANDLED);
+}
+
+static void
+bge_intr_task(void *arg, int pending)
+{
+	struct bge_softc *sc;
+	struct ifnet *ifp;
+	uint32_t status;
+	uint16_t rx_prod, tx_cons;
+
+	sc = (struct bge_softc *)arg;
+	ifp = sc->bge_ifp;
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
+
+	/* Get updated status block. */
+	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+	    sc->bge_cdata.bge_status_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+	/* Save producer/consumer indexess. */
+	rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx;
+	tx_cons = sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx;
+	status = sc->bge_ldata.bge_status_block->bge_status;
+	sc->bge_ldata.bge_status_block->bge_status = 0;
+	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+	    sc->bge_cdata.bge_status_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+	/* Let controller work. */
+	bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
+
+	if ((status & BGE_STATFLAG_LINKSTATE_CHANGED) != 0) {
+		BGE_LOCK(sc);
+		bge_link_upd(sc);
+		BGE_UNLOCK(sc);
+	}
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+		/* Check RX return ring producer/consumer. */
+		bge_rxeof(sc, rx_prod, 0);
+	}
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+		BGE_LOCK(sc);
+		/* Check TX ring producer/consumer. */
+		bge_txeof(sc, tx_cons);
+	    	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+			bge_start_locked(ifp);
+		BGE_UNLOCK(sc);
+	}
+}
+
 static void
 bge_intr(void *xsc)
 {
 	struct bge_softc *sc;
 	struct ifnet *ifp;
 	uint32_t statusword;
+	uint16_t rx_prod, tx_cons;
 
 	sc = xsc;
 
@@ -3440,7 +3537,14 @@ 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);
+	    sc->bge_cdata.bge_status_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+	rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx;
+	tx_cons = sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx;
+	sc->bge_ldata.bge_status_block->bge_status = 0;
+	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+	    sc->bge_cdata.bge_status_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
 	    sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
@@ -3449,21 +3553,18 @@ bge_intr(void *xsc)
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		/* Check RX return ring producer/consumer. */
-		bge_rxeof(sc);
+		bge_rxeof(sc, rx_prod, 1);
 	}
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		/* Check TX ring producer/consumer. */
-		bge_txeof(sc);
+		bge_txeof(sc, tx_cons);
 	}
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 	    !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);
 }
 
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index cc5e0b3f610..7fe768d72d8 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -2641,6 +2641,8 @@ struct bge_softc {
 #ifdef DEVICE_POLLING
 	int			rxcycles;
 #endif /* DEVICE_POLLING */
+	struct task		bge_intr_task;
+	struct taskqueue	*bge_tq;
 };
 
 #define	BGE_LOCK_INIT(_sc, _name) \

From 56ab4ace6f644bc68848268fc35b53f5677c45cb Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 7 Jan 2010 00:44:54 +0000
Subject: [PATCH 1047/2592] MFC
 r199670-199671,199674,199679,199761,199807-199808

r199670:
  Fix two long standing bugs on bge(4). Most pre BCM5755 controllers
  have a DMA bug when buffer address crosses a multiple of the 4GB
  boundary(e.g. 4GB, 8GB, 12GB etc). Limit DMA address to be within
  4GB address for these controllers. The second DMA bug limits DMA
  address to be within 40bit address space. This bug applies to
  BCM5714 and BCM5715 and 5708(bce(4) controller). This is not
  actually a MAC controller bug but an issue with the embedded PCIe
  to PCI-X bridge in the device. So for BCM5714/BCM5715 controllers
  also limit the DMA address to be within 40bit address space.
  Special thanks to davidch@ who gave me detailed errata information.
  I think this change will fix long standing bge(4) instability
  issues on systems with more than 4GB memory.

r199671:
  Implement TSO for BCM5755 or newer controllers. Some controllers
  seem to require a special firmware to use TSO. But the firmware is
  not available to FreeBSD and Linux claims that the TSO performed by
  the firmware is slower than hardware based TSO. Moreover the
  firmware based TSO has one known bug which can't handle TSO if
  ethernet header + IP/TCP header is greater than 80 bytes. The
  workaround for the TSO bug exist but it seems it's too expensive
  than not using TSO at all. Some hardwares also have the TSO bug so
  limit the TSO to the controllers that are not affected TSO issues
  (e.g. 5755 or higher).
  While I'm here set VLAN tag bit to all descriptors that belengs to
  a frame instead of the first descriptor of a frame. The datasheet
  is not clear how to handle VLAN tag bit but it worked either way in
  my testing. This makes it simplify TSO configuration a little bit.

  Big thanks to davidch@ who sent me detailed TSO information.
  Without this I was not able to implement it.

r199674:
  Add missing function prototype in r199671.

r199679:
  Reduce status block size DMAed by controller. bge(4) uses single
  Tx/Rx/Rx return ring such that large part of status block was not
  used at all. All bge(4) controllers except BCM5700 AX/BX has a
  feature to control the size of status block. So use minimum status
  block size allowed in controller. This reduces number of DMAed
  status block size to 32 bytes from 80 bytes.

r199761:
  BGE_FLAG_40BIT_BUG should be set before creating DMA tags.

r199807:
  Make sure one shot MSI is enabled.

r199808:
  Fix typo which inversed the logic which in turn disabled MSI.
---
 sys/dev/bge/if_bge.c    | 234 +++++++++++++++++++++++++++++++++-------
 sys/dev/bge/if_bgereg.h |  19 +++-
 2 files changed, 212 insertions(+), 41 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 0bed9dfe9ac..01811f22226 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -96,6 +96,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -369,6 +370,8 @@ static void bge_asf_driver_up (struct bge_softc *);
 static void bge_tick(void *);
 static void bge_stats_update(struct bge_softc *);
 static void bge_stats_update_regs(struct bge_softc *);
+static struct mbuf *bge_setup_tso(struct bge_softc *, struct mbuf *,
+    uint16_t *);
 static int bge_encap(struct bge_softc *, struct mbuf **, uint32_t *);
 
 static void bge_intr(void *);
@@ -1754,8 +1757,15 @@ bge_blockinit(struct bge_softc *sc)
 	sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx = 0;
 	sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx = 0;
 
+	/* Set up status block size. */
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
+	    sc->bge_chipid != BGE_CHIPID_BCM5700_C0)
+		val = BGE_STATBLKSZ_FULL;
+	else
+		val = BGE_STATBLKSZ_32BYTE;
+
 	/* Turn on host coalescing state machine */
-	CSR_WRITE_4(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);
+	CSR_WRITE_4(sc, BGE_HCC_MODE, val | BGE_HCCMODE_ENABLE);
 
 	/* Turn on RX BD completion state machine and enable attentions */
 	CSR_WRITE_4(sc, BGE_RBDC_MODE,
@@ -1811,6 +1821,8 @@ bge_blockinit(struct bge_softc *sc)
 		    BGE_RDMAMODE_MBUF_SBD_CRPT_ATTN;
 	if (sc->bge_flags & BGE_FLAG_PCIE)
 		val |= BGE_RDMAMODE_FIFO_LONG_BURST;
+	if (sc->bge_flags & BGE_FLAG_TSO)
+		val |= BGE_RDMAMODE_TSO4_ENABLE;
 	CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
 	DELAY(40);
 
@@ -1837,7 +1849,10 @@ bge_blockinit(struct bge_softc *sc)
 	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);
+	if (sc->bge_flags & BGE_FLAG_TSO)
+		CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE | 0x08);
+	else
+		CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
 
 	/* Turn on send BD initiator state machine */
 	CSR_WRITE_4(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);
@@ -2104,15 +2119,22 @@ bge_dma_alloc(device_t dev)
 {
 	struct bge_dmamap_arg ctx;
 	struct bge_softc *sc;
+	bus_addr_t lowaddr;
+	bus_size_t sbsz, txsegsz, txmaxsegsz;
 	int i, error;
 
 	sc = device_get_softc(dev);
 
+	lowaddr = BUS_SPACE_MAXADDR;
+	if ((sc->bge_flags & BGE_FLAG_40BIT_BUG) != 0)
+		lowaddr = BGE_DMA_MAXADDR;
+	if ((sc->bge_flags & BGE_FLAG_4G_BNDRY_BUG) != 0)
+		lowaddr = BUS_SPACE_MAXADDR_32BIT;
 	/*
 	 * Allocate the parent bus DMA tag appropriate for PCI.
 	 */
 	error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev),
-	    1, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,	NULL,
+	    1, 0, lowaddr, BUS_SPACE_MAXADDR, NULL,
 	    NULL, BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT,
 	    0, NULL, NULL, &sc->bge_cdata.bge_parent_tag);
 
@@ -2125,10 +2147,17 @@ bge_dma_alloc(device_t dev)
 	/*
 	 * Create tag for Tx mbufs.
 	 */
+	if (sc->bge_flags & BGE_FLAG_TSO) {
+		txsegsz = BGE_TSOSEG_SZ;
+		txmaxsegsz = 65535 + sizeof(struct ether_vlan_header);
+	} else {
+		txsegsz = MCLBYTES;
+		txmaxsegsz = MCLBYTES * BGE_NSEG_NEW;
+	}
 	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_tx_mtag);
+	    0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+	    txmaxsegsz, BGE_NSEG_NEW, txsegsz, 0, NULL, NULL,
+	    &sc->bge_cdata.bge_tx_mtag);
 
 	if (error) {
 		device_printf(sc->bge_dev, "could not allocate TX dma tag\n");
@@ -2140,7 +2169,7 @@ bge_dma_alloc(device_t dev)
 	 */
 	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);
+	    MCLBYTES, 0, NULL, NULL, &sc->bge_cdata.bge_rx_mtag);
 
 	if (error) {
 		device_printf(sc->bge_dev, "could not allocate RX dma tag\n");
@@ -2343,14 +2372,25 @@ bge_dma_alloc(device_t dev)
 
 	sc->bge_ldata.bge_tx_ring_paddr = ctx.bge_busaddr;
 
-	/* Create tag for status block. */
+	/*
+	 * Create tag for status block.
+	 * Because we only use single Tx/Rx/Rx return ring, use
+	 * minimum status block size except BCM5700 AX/BX which
+	 * seems to want to see full status block size regardless
+	 * of configured number of ring.
+	 */
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
+	    sc->bge_chipid != BGE_CHIPID_BCM5700_C0)
+		sbsz = BGE_STATUS_BLK_SZ;
+	else
+		sbsz = 32;
 	error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
 	    PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
-	    NULL, BGE_STATUS_BLK_SZ, 1, BGE_STATUS_BLK_SZ, 0,
-	    NULL, NULL, &sc->bge_cdata.bge_status_tag);
+	    NULL, sbsz, 1, sbsz, 0, NULL, NULL, &sc->bge_cdata.bge_status_tag);
 
 	if (error) {
-		device_printf(sc->bge_dev, "could not allocate dma tag\n");
+		device_printf(sc->bge_dev,
+		    "could not allocate status dma tag\n");
 		return (ENOMEM);
 	}
 
@@ -2361,7 +2401,7 @@ bge_dma_alloc(device_t dev)
 	if (error)
 		return (ENOMEM);
 
-	bzero((char *)sc->bge_ldata.bge_status_block, BGE_STATUS_BLK_SZ);
+	bzero((char *)sc->bge_ldata.bge_status_block, sbsz);
 
 	/* Load the address of the status block. */
 	ctx.sc = sc;
@@ -2369,7 +2409,7 @@ bge_dma_alloc(device_t dev)
 
 	error = bus_dmamap_load(sc->bge_cdata.bge_status_tag,
 	    sc->bge_cdata.bge_status_map, sc->bge_ldata.bge_status_block,
-	    BGE_STATUS_BLK_SZ, bge_dma_map_addr, &ctx, BUS_DMA_NOWAIT);
+	    sbsz, bge_dma_map_addr, &ctx, BUS_DMA_NOWAIT);
 
 	if (error)
 		return (ENOMEM);
@@ -2566,6 +2606,16 @@ bge_attach(device_t dev)
 			sc->bge_flags |= BGE_FLAG_BER_BUG;
 	}
 
+	/*
+	 * All controllers that are not 5755 or higher have 4GB
+	 * boundary DMA bug.
+	 * Whenever an address crosses a multiple of the 4GB boundary
+	 * (including 4GB, 8Gb, 12Gb, etc.) and makes the transition
+	 * from 0xX_FFFF_FFFF to 0x(X+1)_0000_0000 an internal DMA
+	 * state machine will lockup and cause the device to hang.
+	 */
+	if (BGE_IS_5755_PLUS(sc) == 0)
+		sc->bge_flags |= BGE_FLAG_4G_BNDRY_BUG;
 
 	/*
 	 * We could possibly check for BCOM_DEVICEID_BCM5788 in bge_probe()
@@ -2576,6 +2626,21 @@ bge_attach(device_t dev)
 	    misccfg == BGE_MISCCFG_BOARD_ID_5788M)
 		sc->bge_flags |= BGE_FLAG_5788;
 
+	/*
+	 * Some controllers seem to require a special firmware to use
+	 * TSO. But the firmware is not available to FreeBSD and Linux
+	 * claims that the TSO performed by the firmware is slower than
+	 * hardware based TSO. Moreover the firmware based TSO has one
+	 * known bug which can't handle TSO if ethernet header + IP/TCP
+	 * header is greater than 80 bytes. The workaround for the TSO
+	 * bug exist but it seems it's too expensive than not using
+	 * TSO at all. Some hardwares also have the TSO bug so limit
+	 * the TSO to the controllers that are not affected TSO issues
+	 * (e.g. 5755 or higher).
+	 */
+	if (BGE_IS_5755_PLUS(sc))
+		sc->bge_flags |= BGE_FLAG_TSO;
+
   	/*
 	 * Check if this is a PCI-X or PCI Express device.
   	 */
@@ -2599,13 +2664,20 @@ bge_attach(device_t dev)
 			sc->bge_flags |= BGE_FLAG_PCIX;
 	}
 
+	/*
+	 * The 40bit DMA bug applies to the 5714/5715 controllers and is
+	 * not actually a MAC controller bug but an issue with the embedded
+	 * PCIe to PCI-X bridge in the device. Use 40bit DMA workaround.
+	 */
+	if (BGE_IS_5714_FAMILY(sc) && (sc->bge_flags & BGE_FLAG_PCIX))
+		sc->bge_flags |= BGE_FLAG_40BIT_BUG;
 	/*
 	 * Allocate the interrupt, using MSI if possible.  These devices
 	 * support 8 MSI messages, but only the first one is used in
 	 * normal operation.
 	 */
 	rid = 0;
-	if (pci_find_extcap(sc->bge_dev, PCIY_MSI, ®) != 0) {
+	if (pci_find_extcap(sc->bge_dev, PCIY_MSI, ®) == 0) {
 		sc->bge_msicap = reg;
 		if (bge_can_use_msi(sc)) {
 			msicount = pci_msi_count(dev);
@@ -2722,6 +2794,10 @@ bge_attach(device_t dev)
 	ifp->if_hwassist = BGE_CSUM_FEATURES;
 	ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING |
 	    IFCAP_VLAN_MTU;
+	if ((sc->bge_flags & BGE_FLAG_TSO) != 0) {
+		ifp->if_hwassist |= CSUM_TSO;
+		ifp->if_capabilities |= IFCAP_TSO4;
+	}
 #ifdef IFCAP_VLAN_HWCSUM
 	ifp->if_capabilities |= IFCAP_VLAN_HWCSUM;
 #endif
@@ -2839,6 +2915,8 @@ again:
 #if __FreeBSD_version > 700030
 	if (BGE_IS_5755_PLUS(sc) && sc->bge_flags & BGE_FLAG_MSI) {
 		/* Take advantage of single-shot MSI. */
+		CSR_WRITE_4(sc, BGE_MSI_MODE, CSR_READ_4(sc, BGE_MSI_MODE) &
+		    ~BGE_MSIMODE_ONE_SHOT_DISABLE);
 		sc->bge_tq = taskqueue_create_fast("bge_taskq", M_WAITOK,
 		    taskqueue_thread_enqueue, &sc->bge_tq);
 		if (sc->bge_tq == NULL) {
@@ -3729,6 +3807,72 @@ bge_cksum_pad(struct mbuf *m)
 	return (0);
 }
 
+static struct mbuf *
+bge_setup_tso(struct bge_softc *sc, struct mbuf *m, uint16_t *mss)
+{
+	struct ether_header *eh;
+	struct ip *ip;
+	struct tcphdr *tcp;
+	struct mbuf *n;
+	uint16_t hlen;
+	uint32_t ip_off, poff;
+
+	if (M_WRITABLE(m) == 0) {
+		/* Get a writable copy. */
+		n = m_dup(m, M_DONTWAIT);
+		m_freem(m);
+		if (n == NULL)
+			return (NULL);
+		m = n;
+	}
+	ip_off = sizeof(struct ether_header);
+	m = m_pullup(m, ip_off);
+	if (m == NULL)
+		return (NULL);
+	eh = mtod(m, struct ether_header *);
+	/* Check the existence of VLAN tag. */
+	if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
+		ip_off = sizeof(struct ether_vlan_header);
+		m = m_pullup(m, ip_off);
+		if (m == NULL)
+			return (NULL);
+	}
+	m = m_pullup(m, ip_off + sizeof(struct ip));
+	if (m == NULL)
+		return (NULL);
+	ip = (struct ip *)(mtod(m, char *) + ip_off);
+	poff = ip_off + (ip->ip_hl << 2);
+	m = m_pullup(m, poff + sizeof(struct tcphdr));
+	if (m == NULL)
+		return (NULL);
+	tcp = (struct tcphdr *)(mtod(m, char *) + poff);
+	m = m_pullup(m, poff + sizeof(struct tcphdr) + tcp->th_off);
+	if (m == NULL)
+		return (NULL);
+	/*
+	 * It seems controller doesn't modify IP length and TCP pseudo
+	 * checksum. These checksum computed by upper stack should be 0.
+	 */
+	*mss = m->m_pkthdr.tso_segsz;
+	ip->ip_sum = 0;
+	ip->ip_len = htons(*mss + (ip->ip_hl << 2) + (tcp->th_off << 2));
+	/* Clear pseudo checksum computed by TCP stack. */
+	tcp->th_sum = 0;
+	/*
+	 * Broadcom controllers uses different descriptor format for
+	 * TSO depending on ASIC revision. Due to TSO-capable firmware
+	 * license issue and lower performance of firmware based TSO
+	 * we only support hardware based TSO which is applicable for
+	 * BCM5755 or newer controllers. Hardware based TSO uses 11
+	 * bits to store MSS and upper 5 bits are used to store IP/TCP
+	 * header length(including IP/TCP options). The header length
+	 * is expressed as 32 bits unit.
+	 */
+	hlen = ((ip->ip_hl << 2) + (tcp->th_off << 2)) >> 2;
+	*mss |= (hlen << 11);
+	return (m);
+}
+
 /*
  * Encapsulate an mbuf chain in the tx ring  by coupling the mbuf data
  * pointers to descriptors.
@@ -3741,11 +3885,19 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
 	struct bge_tx_bd	*d;
 	struct mbuf		*m = *m_head;
 	uint32_t		idx = *txidx;
-	uint16_t		csum_flags;
+	uint16_t		csum_flags, mss, vlan_tag;
 	int			nsegs, i, error;
 
 	csum_flags = 0;
-	if (m->m_pkthdr.csum_flags) {
+	mss = 0;
+	vlan_tag = 0;
+	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+		*m_head = m = bge_setup_tso(sc, m, &mss);
+		if (*m_head == NULL)
+			return (ENOBUFS);
+		csum_flags |= BGE_TXBDFLAG_CPU_PRE_DMA |
+		    BGE_TXBDFLAG_CPU_POST_DMA;
+	} else if ((m->m_pkthdr.csum_flags & BGE_CSUM_FEATURES) != 0) {
 		if (m->m_pkthdr.csum_flags & CSUM_IP)
 			csum_flags |= BGE_TXBDFLAG_IP_CSUM;
 		if (m->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP)) {
@@ -3792,12 +3944,29 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
 
 	bus_dmamap_sync(sc->bge_cdata.bge_tx_mtag, map, BUS_DMASYNC_PREWRITE);
 
+#if __FreeBSD_version > 700022
+	if (m->m_flags & M_VLANTAG) {
+		csum_flags |= BGE_TXBDFLAG_VLAN_TAG;
+		vlan_tag = m->m_pkthdr.ether_vtag;
+	}
+#else
+	{
+		struct m_tag		*mtag;
+
+		if ((mtag = VLAN_OUTPUT_TAG(sc->bge_ifp, m)) != NULL) {
+			csum_flags |= BGE_TXBDFLAG_VLAN_TAG;
+			vlan_tag = VLAN_TAG_VALUE(mtag);
+		}
+	}
+#endif
 	for (i = 0; ; i++) {
 		d = &sc->bge_ldata.bge_tx_ring[idx];
 		d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr);
 		d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr);
 		d->bge_len = segs[i].ds_len;
 		d->bge_flags = csum_flags;
+		d->bge_vlan_tag = vlan_tag;
+		d->bge_mss = mss;
 		if (i == nsegs - 1)
 			break;
 		BGE_INC(idx, BGE_TX_RING_CNT);
@@ -3806,26 +3975,6 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
 	/* Mark the last segment as end of packet... */
 	d->bge_flags |= BGE_TXBDFLAG_END;
 
-	/* ... and put VLAN tag into first segment.  */
-	d = &sc->bge_ldata.bge_tx_ring[*txidx];
-#if __FreeBSD_version > 700022
-	if (m->m_flags & M_VLANTAG) {
-		d->bge_flags |= BGE_TXBDFLAG_VLAN_TAG;
-		d->bge_vlan_tag = m->m_pkthdr.ether_vtag;
-	} else
-		d->bge_vlan_tag = 0;
-#else
-	{
-		struct m_tag		*mtag;
-
-		if ((mtag = VLAN_OUTPUT_TAG(sc->bge_ifp, m)) != NULL) {
-			d->bge_flags |= BGE_TXBDFLAG_VLAN_TAG;
-			d->bge_vlan_tag = VLAN_TAG_VALUE(mtag);
-		} else
-			d->bge_vlan_tag = 0;
-	}
-#endif
-
 	/*
 	 * Insure that the map for this transmission
 	 * is placed at the array index of the last descriptor
@@ -4332,14 +4481,23 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 			ifp->if_capenable ^= IFCAP_HWCSUM;
 			if (IFCAP_HWCSUM & ifp->if_capenable &&
 			    IFCAP_HWCSUM & ifp->if_capabilities)
-				ifp->if_hwassist = BGE_CSUM_FEATURES;
+				ifp->if_hwassist |= BGE_CSUM_FEATURES;
 			else
-				ifp->if_hwassist = 0;
+				ifp->if_hwassist &= ~BGE_CSUM_FEATURES;
 #ifdef VLAN_CAPABILITIES
 			VLAN_CAPABILITIES(ifp);
 #endif
 		}
 
+		if ((mask & IFCAP_TSO4) != 0 &&
+		    (ifp->if_capabilities & IFCAP_TSO4) != 0) {
+			ifp->if_capenable ^= IFCAP_TSO4;
+			if ((ifp->if_capenable & IFCAP_TSO4) != 0)
+				ifp->if_hwassist |= CSUM_TSO;
+			else
+				ifp->if_hwassist &= ~CSUM_TSO;
+		}
+
 		if (mask & IFCAP_VLAN_MTU) {
 			ifp->if_capenable ^= IFCAP_VLAN_MTU;
 			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index 7fe768d72d8..cefe516e58d 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -1402,6 +1402,8 @@
 #define	BGE_RDMAMODE_MBUF_SBD_CRPT_ATTN	0x00002000
 #define	BGE_RDMAMODE_FIFO_SIZE_128	0x00020000
 #define	BGE_RDMAMODE_FIFO_LONG_BURST	0x00030000
+#define	BGE_RDMAMODE_TSO4_ENABLE	0x08000000
+#define	BGE_RDMAMODE_TSO6_ENABLE	0x10000000
 
 /* Read DMA status register */
 #define	BGE_RDMASTAT_PCI_TGT_ABRT_ATTN	0x00000004
@@ -1949,11 +1951,11 @@ struct bge_tx_bd {
 	uint16_t		bge_flags;
 	uint16_t		bge_len;
 	uint16_t		bge_vlan_tag;
-	uint16_t		bge_rsvd;
+	uint16_t		bge_mss;
 #else
 	uint16_t		bge_len;
 	uint16_t		bge_flags;
-	uint16_t		bge_rsvd;
+	uint16_t		bge_mss;
 	uint16_t		bge_vlan_tag;
 #endif
 };
@@ -2482,7 +2484,15 @@ struct bge_gib {
 #define	BGE_JSLOTS	384
 
 #define	BGE_NSEG_JUMBO	4
-#define	BGE_NSEG_NEW 32
+#define	BGE_NSEG_NEW	32
+#define	BGE_TSOSEG_SZ	4096
+
+/* Maximum DMA address for controllers that have 40bit DMA address bug. */
+#if (BUS_SPACE_MAXADDR < 0xFFFFFFFFFF)
+#define	BGE_DMA_MAXADDR		BUS_SPACE_MAXADDR
+#else
+#define	BGE_DMA_MAXADDR		0xFFFFFFFFFF
+#endif
 
 /*
  * Ring structures. Most of these reside in host memory and we tell
@@ -2595,11 +2605,14 @@ struct bge_softc {
 #define	BGE_FLAG_MSI		0x00000100
 #define	BGE_FLAG_PCIX		0x00000200
 #define	BGE_FLAG_PCIE		0x00000400
+#define	BGE_FLAG_TSO		0x00000800
 #define	BGE_FLAG_5700_FAMILY	0x00001000
 #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_40BIT_BUG	0x00020000
+#define	BGE_FLAG_4G_BNDRY_BUG	0x00040000
 #define	BGE_FLAG_RX_ALIGNBUG	0x00100000
 #define	BGE_FLAG_NO_3LED	0x00200000
 #define	BGE_FLAG_ADC_BUG	0x00400000

From 02b41ac4df747ca2b2656b9ad4da6045779d0f63 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 7 Jan 2010 00:55:07 +0000
Subject: [PATCH 1048/2592] MFC r200088,200227-200228,200246,200264,201446

r200088:
  Add workaround to overcome hardware limitation which allows only a
  single outstanding DMA read operation. Most controllers targeted to
  client with PCIe bus interface(e.g. BCM5761) may have this
  limitation. All controllers for servers does not have this
  limitation.
  Collapsing mbuf chains to reduce number of memory reads before
  transmitting was most effective way to workaround this. I got about
  940Mbps from 850Mbps with mbuf collapsing on BCM5761. However it
  takes a lot of CPU cycles to collapse mbuf chains so add tunable to
  control the number of allowed TX buffers before collapsing. The
  default value is 0 which effectively disables the forced collapsing.
  For most cases 2 would yield best performance(about 930Mbps)
  without much sacrificing CPU cycles.
  Note the collapsing is only activated when the controller is on
  PCIe bus and the frame does not need TSO operation. TSO does not
  seem to suffer from the hardware limitation because the payload
  size is much bigger than normal IP datagram.
  Thanks to davidch@ who told me the limitation of client controllers
  and actually gave possible workarounds to mitigate the limitation.

r200227:
  Remove PHY isolate/power down code in bge_stop(). The isolation
  handler in brgphy(4) does not exist and brgphy(4) just resets the
  PHY and returns EINVAL as it has no isolation handler. I also agree
  on Marius's opinion that stop handler of every NIC driver seems to
  be the wrong place for implementing PHY isolate/power down.
  If we need PHY isolate/power down it should be implemented in
  brgphy(4) and users should administratively down the PHY.

r200228:
  Don't access jumbo frame related registers if controller lacks the
  feature. These registers are reserved on controllers that have no
  support for jumbo frame.
  Only BCM5700 has mini ring so do not poke mini ring related
  registers if controller is not BCM5700.

r200246:
  Partially revert r200228. For mini RCB case, bge(4) still have to
  disable mini ring withtout regard to mini ring support.

r200264:
  Create sysctl node(dev.bge.%d.focred_collapse) instead of
  hw.bge.forced_collapse. hw.bge.forced_collapse affects all bge(4)
  controllers on system which may not desirable behavior of the
  sysctl node. Also allow the sysctl node could be modified at any
  time.

r201446:
  Fix regression introduced in r198318. BCM5754/BCM5754M uses the
  same ASIC ID of BCM5758 such that r198318 incorecctly enabled TSO
  on BCM5754.BCM5754M controllers. BCM5754/BCM5754M needs a special
  firmware to enable TSO and bge(4) does not support firmware based
  TSO.
---
 sys/dev/bge/if_bge.c    | 88 ++++++++++++++++++++++++++---------------
 sys/dev/bge/if_bgereg.h |  1 +
 2 files changed, 57 insertions(+), 32 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 01811f22226..b4f49159913 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -1625,7 +1625,9 @@ bge_blockinit(struct bge_softc *sc)
 	else
 		val = BGE_STD_RX_RING_CNT / 8;
 	CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, val);
-	CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, BGE_JUMBO_RX_RING_CNT/8);
+	if (BGE_IS_JUMBO_CAPABLE(sc))
+		CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH,
+		    BGE_JUMBO_RX_RING_CNT/8);
 
 	/*
 	 * Disable all unused send rings by setting the 'ring disabled'
@@ -1667,8 +1669,10 @@ bge_blockinit(struct bge_softc *sc)
 
 	/* Initialize RX ring indexes */
 	bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, 0);
-	bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
-	bge_writembx(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
+	if (BGE_IS_JUMBO_CAPABLE(sc))
+		bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5700)
+		bge_writembx(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
 
 	/*
 	 * Set up RX return ring 0
@@ -2638,8 +2642,15 @@ bge_attach(device_t dev)
 	 * the TSO to the controllers that are not affected TSO issues
 	 * (e.g. 5755 or higher).
 	 */
-	if (BGE_IS_5755_PLUS(sc))
-		sc->bge_flags |= BGE_FLAG_TSO;
+	if (BGE_IS_5755_PLUS(sc)) {
+		/*
+		 * BCM5754 and BCM5787 shares the same ASIC id so
+		 * explicit device id check is required.
+		 */
+		if (pci_get_device(dev) != BCOM_DEVICEID_BCM5754 &&
+		    pci_get_device(dev) != BCOM_DEVICEID_BCM5754M)
+			sc->bge_flags |= BGE_FLAG_TSO;
+	}
 
   	/*
 	 * Check if this is a PCI-X or PCI Express device.
@@ -3915,6 +3926,26 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
 			csum_flags |= BGE_TXBDFLAG_IP_FRAG;
 	}
 
+	if ((m->m_pkthdr.csum_flags & CSUM_TSO) == 0 &&
+	    sc->bge_forced_collapse > 0 &&
+	    (sc->bge_flags & BGE_FLAG_PCIE) != 0 && m->m_next != NULL) {
+		/*
+		 * Forcedly collapse mbuf chains to overcome hardware
+		 * limitation which only support a single outstanding
+		 * DMA read operation.
+		 */
+		if (sc->bge_forced_collapse == 1)
+			m = m_defrag(m, M_DONTWAIT);
+		else
+			m = m_collapse(m, M_DONTWAIT, sc->bge_forced_collapse);
+		if (m == NULL) {
+			m_freem(*m_head);
+			*m_head = NULL;
+			return (ENOBUFS);
+		}
+		*m_head = m;
+	}
+
 	map = sc->bge_cdata.bge_tx_dmamap[idx];
 	error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_tx_mtag, map, m, segs,
 	    &nsegs, BUS_DMA_NOWAIT);
@@ -4551,17 +4582,11 @@ static void
 bge_stop(struct bge_softc *sc)
 {
 	struct ifnet *ifp;
-	struct ifmedia_entry *ifm;
-	struct mii_data *mii = NULL;
-	int mtmp, itmp;
 
 	BGE_LOCK_ASSERT(sc);
 
 	ifp = sc->bge_ifp;
 
-	if ((sc->bge_flags & BGE_FLAG_TBI) == 0)
-		mii = device_get_softc(sc->bge_miibus);
-
 	callout_stop(&sc->bge_stat_ch);
 
 	/* Disable host interrupts. */
@@ -4635,27 +4660,6 @@ bge_stop(struct bge_softc *sc)
 	/* Free TX buffers. */
 	bge_free_tx_ring(sc);
 
-	/*
-	 * Isolate/power down the PHY, but leave the media selection
-	 * unchanged so that things will be put back to normal when
-	 * we bring the interface back up.
-	 */
-	if ((sc->bge_flags & BGE_FLAG_TBI) == 0) {
-		itmp = ifp->if_flags;
-		ifp->if_flags |= IFF_UP;
-		/*
-		 * If we are called from bge_detach(), mii is already NULL.
-		 */
-		if (mii != NULL) {
-			ifm = mii->mii_media.ifm_cur;
-			mtmp = ifm->ifm_media;
-			ifm->ifm_media = IFM_ETHER | IFM_NONE;
-			mii_mediachg(mii);
-			ifm->ifm_media = mtmp;
-		}
-		ifp->if_flags = itmp;
-	}
-
 	sc->bge_tx_saved_considx = BGE_TXCONS_UNSET;
 
 	/* Clear MAC's link state (PHY may still have link UP). */
@@ -4861,6 +4865,26 @@ bge_add_sysctls(struct bge_softc *sc)
 
 #endif
 
+	/*
+	 * A common design characteristic for many Broadcom client controllers
+	 * is that they only support a single outstanding DMA read operation
+	 * on the PCIe bus. This means that it will take twice as long to fetch
+	 * a TX frame that is split into header and payload buffers as it does
+	 * to fetch a single, contiguous TX frame (2 reads vs. 1 read). For
+	 * these controllers, coalescing buffers to reduce the number of memory
+	 * reads is effective way to get maximum performance(about 940Mbps).
+	 * Without collapsing TX buffers the maximum TCP bulk transfer
+	 * performance is about 850Mbps. However forcing coalescing mbufs
+	 * consumes a lot of CPU cycles, so leave it off by default.
+	 */
+	SYSCTL_ADD_INT(ctx, children, OID_AUTO, "forced_collapse",
+	    CTLFLAG_RW, &sc->bge_forced_collapse, 0,
+	    "Number of fragmented TX buffers of a frame allowed before "
+	    "forced collapsing");
+	resource_int_value(device_get_name(sc->bge_dev),
+	    device_get_unit(sc->bge_dev), "forced_collapse",
+	    &sc->bge_forced_collapse);
+
 	if (BGE_IS_5705_PLUS(sc))
 		return;
 
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index cefe516e58d..2694c77a6fb 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -2647,6 +2647,7 @@ struct bge_softc {
 	int			bge_link;	/* link state */
 	int			bge_link_evt;	/* pending link event */
 	int			bge_timer;
+	int			bge_forced_collapse;
 	struct callout		bge_stat_ch;
 	uint32_t		bge_rx_discards;
 	uint32_t		bge_tx_discards;

From c7d57a89e4bc2cb31bd6d0ae2fdf9541105899ce Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 7 Jan 2010 11:33:57 +0000
Subject: [PATCH 1049/2592] MFC r201504: PG_NOSYNC is called VPO_NOSYNC for
 long time.

---
 share/man/man9/vm_page_bits.9 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/share/man/man9/vm_page_bits.9 b/share/man/man9/vm_page_bits.9
index 991c7637e53..fdee5afd295 100644
--- a/share/man/man9/vm_page_bits.9
+++ b/share/man/man9/vm_page_bits.9
@@ -94,7 +94,7 @@ is zero and
 .Fa size
 is one page, the modified bit in the page map is cleared; as well,
 the
-.Dv PG_NOSYNC
+.Dv VPO_NOSYNC
 flag is cleared.
 .Pp
 .Fn vm_page_clear_dirty

From e1c0f1246fa62b05d2084b3afe432b7cc89a7832 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Thu, 7 Jan 2010 11:41:47 +0000
Subject: [PATCH 1050/2592] MFC r201347: Allow swap out of the kernel stack for
 the thread with priority greater or equial then PSOCK, not less or equial.

---
 sys/kern/sched_4bsd.c | 2 +-
 sys/kern/sched_ule.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index 4fe1c1415f2..573296af257 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -913,7 +913,7 @@ sched_sleep(struct thread *td, int pri)
 	td->td_sched->ts_slptime = 0;
 	if (pri)
 		sched_prio(td, pri);
-	if (TD_IS_SUSPENDED(td) || pri <= PSOCK)
+	if (TD_IS_SUSPENDED(td) || pri >= PSOCK)
 		td->td_flags |= TDF_CANSWAP;
 }
 
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 593652f7571..3bd5b71fad8 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -1909,7 +1909,7 @@ sched_sleep(struct thread *td, int prio)
 	THREAD_LOCK_ASSERT(td, MA_OWNED);
 
 	td->td_slptick = ticks;
-	if (TD_IS_SUSPENDED(td) || prio <= PSOCK)
+	if (TD_IS_SUSPENDED(td) || prio >= PSOCK)
 		td->td_flags |= TDF_CANSWAP;
 	if (static_boost == 1 && prio)
 		sched_prio(td, prio);

From d2f946c4442d3564a0dcb510259101408e0b88eb Mon Sep 17 00:00:00 2001
From: Bruce M Simpson 
Date: Thu, 7 Jan 2010 14:15:34 +0000
Subject: [PATCH 1051/2592] MFC r200871:  Use ALLOW_NEW_SOURCES and
 BLOCK_OLD_SOURCES to signal a join or leave  with SSM MLDv2 by default.  This
 is current practice and complies with RFC 4604, as well as being  required by
 production IPv6 networks in Japan.  The behaviour may be disabled by setting
 the net.inet6.mld.use_allow  sysctl/tunable to 0.

Requested by:	Hideki Yamamoto, dikshie
---
 sys/netinet6/mld6.c     | 75 ++++++++++++++++++++++++++++++++---------
 sys/netinet6/mld6_var.h |  1 +
 2 files changed, 60 insertions(+), 16 deletions(-)

diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index 8759ade17e8..cade0d2b208 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -132,7 +132,8 @@ static struct mbuf *
 static int	mld_v2_enqueue_filter_change(struct ifqueue *,
 		    struct in6_multi *);
 static int	mld_v2_enqueue_group_record(struct ifqueue *,
-		    struct in6_multi *, const int, const int, const int);
+		    struct in6_multi *, const int, const int, const int,
+		    const int);
 static int	mld_v2_input_query(struct ifnet *, const struct ip6_hdr *,
 		    struct mbuf *, const int, const int);
 static int	mld_v2_merge_state_changes(struct in6_multi *,
@@ -236,6 +237,11 @@ SYSCTL_INT(_net_inet6_mld, OID_AUTO, v1enable, CTLFLAG_RW,
     &mld_v1enable, 0, "Enable fallback to MLDv1");
 TUNABLE_INT("net.inet6.mld.v1enable", &mld_v1enable);
 
+static int	mld_use_allow = 1;
+SYSCTL_INT(_net_inet6_mld, OID_AUTO, use_allow, CTLFLAG_RW,
+    &mld_use_allow, 0, "Use ALLOW/BLOCK for RFC 4604 SSM joins/leaves");
+TUNABLE_INT("net.inet6.mld.use_allow", &mld_use_allow);
+
 /*
  * Packed Router Alert option structure declaration.
  */
@@ -461,6 +467,8 @@ mld_domifattach(struct ifnet *ifp)
 	mli = mli_alloc_locked(ifp);
 	if (!(ifp->if_flags & IFF_MULTICAST))
 		mli->mli_flags |= MLIF_SILENT;
+	if (mld_use_allow)
+		mli->mli_flags |= MLIF_USEALLOW;
 
 	MLD_UNLOCK();
 
@@ -1550,7 +1558,8 @@ mld_v2_process_group_timers(struct mld_ifinfo *mli,
 			int retval;
 
 			retval = mld_v2_enqueue_group_record(qrq, inm, 0, 1,
-			    (inm->in6m_state == MLD_SG_QUERY_PENDING_MEMBER));
+			    (inm->in6m_state == MLD_SG_QUERY_PENDING_MEMBER),
+			    0);
 			CTR2(KTR_MLD, "%s: enqueue record = %d",
 			    __func__, retval);
 			inm->in6m_state = MLD_REPORTING_MEMBER;
@@ -2025,7 +2034,7 @@ mld_initial_join(struct in6_multi *inm, struct mld_ifinfo *mli,
 			ifq = &inm->in6m_scq;
 			_IF_DRAIN(ifq);
 			retval = mld_v2_enqueue_group_record(ifq, inm, 1,
-			    0, 0);
+			    0, 0, (mli->mli_flags & MLIF_USEALLOW));
 			CTR2(KTR_MLD, "%s: enqueue record = %d",
 			    __func__, retval);
 			if (retval <= 0) {
@@ -2118,7 +2127,8 @@ mld_handle_state_change(struct in6_multi *inm, struct mld_ifinfo *mli)
 
 	_IF_DRAIN(&inm->in6m_scq);
 
-	retval = mld_v2_enqueue_group_record(&inm->in6m_scq, inm, 1, 0, 0);
+	retval = mld_v2_enqueue_group_record(&inm->in6m_scq, inm, 1, 0, 0,
+	    (mli->mli_flags & MLIF_USEALLOW));
 	CTR2(KTR_MLD, "%s: enqueue record = %d", __func__, retval);
 	if (retval <= 0)
 		return (-retval);
@@ -2203,7 +2213,8 @@ mld_final_leave(struct in6_multi *inm, struct mld_ifinfo *mli)
 				in6m_acquire_locked(inm);
 
 				retval = mld_v2_enqueue_group_record(
-				    &inm->in6m_scq, inm, 1, 0, 0);
+				    &inm->in6m_scq, inm, 1, 0, 0,
+				    (mli->mli_flags & MLIF_USEALLOW));
 				KASSERT(retval != 0,
 				    ("%s: enqueue record = %d", __func__,
 				     retval));
@@ -2250,6 +2261,10 @@ mld_final_leave(struct in6_multi *inm, struct mld_ifinfo *mli)
  * it was recorded for a Group-Source query, and will be omitted if
  * it is not both in-mode and recorded.
  *
+ * If use_block_allow is non-zero, state change reports for initial join
+ * and final leave, on an inclusive mode group with a source list, will be
+ * rewritten to use the ALLOW_NEW and BLOCK_OLD record types, respectively.
+ *
  * The function will attempt to allocate leading space in the packet
  * for the IPv6+ICMP headers to be prepended without fragmenting the chain.
  *
@@ -2260,7 +2275,7 @@ mld_final_leave(struct in6_multi *inm, struct mld_ifinfo *mli)
 static int
 mld_v2_enqueue_group_record(struct ifqueue *ifq, struct in6_multi *inm,
     const int is_state_change, const int is_group_query,
-    const int is_source_query)
+    const int is_source_query, const int use_block_allow)
 {
 	struct mldv2_record	 mr;
 	struct mldv2_record	*pmr;
@@ -2308,10 +2323,16 @@ mld_v2_enqueue_group_record(struct ifqueue *ifq, struct in6_multi *inm,
 		 * If the mode did not change, and there are non-ASM
 		 * listeners or source filters present,
 		 * we potentially need to issue two records for the group.
-		 * If we are transitioning to MCAST_UNDEFINED, we need
-		 * not send any sources.
 		 * If there are ASM listeners, and there was no filter
 		 * mode transition of any kind, do nothing.
+		 *
+		 * If we are transitioning to MCAST_UNDEFINED, we need
+		 * not send any sources. A transition to/from this state is
+		 * considered inclusive with some special treatment.
+		 *
+		 * If we are rewriting initial joins/leaves to use
+		 * ALLOW/BLOCK, and the group's membership is inclusive,
+		 * we need to send sources in all cases.
 		 */
 		if (mode != inm->in6m_st[0].iss_fmode) {
 			if (mode == MCAST_EXCLUDE) {
@@ -2321,9 +2342,26 @@ mld_v2_enqueue_group_record(struct ifqueue *ifq, struct in6_multi *inm,
 			} else {
 				CTR1(KTR_MLD, "%s: change to INCLUDE",
 				    __func__);
-				type = MLD_CHANGE_TO_INCLUDE_MODE;
-				if (mode == MCAST_UNDEFINED)
-					record_has_sources = 0;
+				if (use_block_allow) {
+					/*
+					 * XXX
+					 * Here we're interested in state
+					 * edges either direction between
+					 * MCAST_UNDEFINED and MCAST_INCLUDE.
+					 * Perhaps we should just check
+					 * the group state, rather than
+					 * the filter mode.
+					 */
+					if (mode == MCAST_UNDEFINED) {
+						type = MLD_BLOCK_OLD_SOURCES;
+					} else {
+						type = MLD_ALLOW_NEW_SOURCES;
+					}
+				} else {
+					type = MLD_CHANGE_TO_INCLUDE_MODE;
+					if (mode == MCAST_UNDEFINED)
+						record_has_sources = 0;
+				}
 			}
 		} else {
 			if (record_has_sources) {
@@ -2436,9 +2474,12 @@ mld_v2_enqueue_group_record(struct ifqueue *ifq, struct in6_multi *inm,
 	 * If we are appending to an existing packet, we need to obtain
 	 * a pointer to the group record after m_append(), in case a new
 	 * mbuf was allocated.
+	 *
 	 * Only append sources which are in-mode at t1. If we are
-	 * transitioning to MCAST_UNDEFINED state on the group, do not
-	 * include source entries.
+	 * transitioning to MCAST_UNDEFINED state on the group, and
+	 * use_block_allow is zero, do not include source entries.
+	 * Otherwise, we need to include this source in the report.
+	 *
 	 * Only report recorded sources in our filter set when responding
 	 * to a group-source query.
 	 */
@@ -2460,7 +2501,8 @@ mld_v2_enqueue_group_record(struct ifqueue *ifq, struct in6_multi *inm,
 			now = im6s_get_mode(inm, ims, 1);
 			CTR2(KTR_MLD, "%s: node is %d", __func__, now);
 			if ((now != mode) ||
-			    (now == mode && mode == MCAST_UNDEFINED)) {
+			    (now == mode &&
+			     (!use_block_allow && mode == MCAST_UNDEFINED))) {
 				CTR1(KTR_MLD, "%s: skip node", __func__);
 				continue;
 			}
@@ -2550,7 +2592,8 @@ mld_v2_enqueue_group_record(struct ifqueue *ifq, struct in6_multi *inm,
 			    __func__, ip6_sprintf(ip6tbuf, &ims->im6s_addr));
 			now = im6s_get_mode(inm, ims, 1);
 			if ((now != mode) ||
-			    (now == mode && mode == MCAST_UNDEFINED)) {
+			    (now == mode &&
+			     (!use_block_allow && mode == MCAST_UNDEFINED))) {
 				CTR1(KTR_MLD, "%s: skip node", __func__);
 				continue;
 			}
@@ -2961,7 +3004,7 @@ mld_v2_dispatch_general_query(struct mld_ifinfo *mli)
 		case MLD_AWAKENING_MEMBER:
 			inm->in6m_state = MLD_REPORTING_MEMBER;
 			retval = mld_v2_enqueue_group_record(&mli->mli_gq,
-			    inm, 0, 0, 0);
+			    inm, 0, 0, 0, 0);
 			CTR2(KTR_MLD, "%s: enqueue record = %d",
 			    __func__, retval);
 			break;
diff --git a/sys/netinet6/mld6_var.h b/sys/netinet6/mld6_var.h
index efd01abb559..e62ec236ce5 100644
--- a/sys/netinet6/mld6_var.h
+++ b/sys/netinet6/mld6_var.h
@@ -55,6 +55,7 @@ struct mld_ifinfo {
 	struct ifqueue	 mli_gq;	/* queue of general query responses */
 };
 #define MLIF_SILENT	0x00000001	/* Do not use MLD on this ifp */
+#define MLIF_USEALLOW	0x00000002	/* Use ALLOW/BLOCK for joins/leaves */
 
 #define MLD_RANDOM_DELAY(X)		(arc4random() % (X) + 1)
 #define MLD_MAX_STATE_CHANGES		24 /* Max pending changes per group */

From aecc4e172413d0ec5939a1e40e8d777198e11679 Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Thu, 7 Jan 2010 16:18:46 +0000
Subject: [PATCH 1052/2592] Bump __FreeBSD_version to 800500 which should have
 happened already after r198460 but was missed.

Note: that 800108 should have been 800501 with that but as there is no
functional problem here, it'll just stay as is. [1]

This will make pkg_add -r use packages-8-stable for stable/8 rather
than packages-8.0-release.

Reported by:	Paride Legovini (pl ninthfloor.org) on stable@,
		(pluknet gmail.com), jhb
Discussed with:	rwatson [1]
---
 sys/sys/param.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/sys/param.h b/sys/sys/param.h
index 38c0c04706d..d3ee0677c2a 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 800108	/* Master, propagated to newvers */
+#define __FreeBSD_version 800500	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include 

From f12d6d2a3fa9388d28aaa73cd62ccbf7df879a47 Mon Sep 17 00:00:00 2001
From: Antoine Brodin 
Date: Thu, 7 Jan 2010 19:37:21 +0000
Subject: [PATCH 1053/2592] MFC r200129 to stable/8:   Remove trailing ";" in
 UMA_HASH_INSERT and UMA_HASH_REMOVE macros.

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

diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h
index c2ed06dc7db..1aaf84f819d 100644
--- a/sys/vm/uma_int.h
+++ b/sys/vm/uma_int.h
@@ -144,10 +144,10 @@
 
 #define UMA_HASH_INSERT(h, s, mem)					\
 		SLIST_INSERT_HEAD(&(h)->uh_slab_hash[UMA_HASH((h),	\
-		    (mem))], (s), us_hlink);
+		    (mem))], (s), us_hlink)
 #define UMA_HASH_REMOVE(h, s, mem)					\
 		SLIST_REMOVE(&(h)->uh_slab_hash[UMA_HASH((h),		\
-		    (mem))], (s), uma_slab, us_hlink);
+		    (mem))], (s), uma_slab, us_hlink)
 
 /* Hash table for freed address -> slab translation */
 

From 84e096effd46521daf360ee05a578ddceb1f6637 Mon Sep 17 00:00:00 2001
From: Alexander Leidinger 
Date: Fri, 8 Jan 2010 09:59:13 +0000
Subject: [PATCH 1054/2592] MFC r197816: ---snip---     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 ---snip---

---
 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 aab57f153be71fa03f866cff617039881425f434 Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Fri, 8 Jan 2010 10:13:27 +0000
Subject: [PATCH 1055/2592] MFC r200994:   Set the locally-assigned bit in the
 randomly generated Ethernet address   if we end up having to generate one.

PR:		kern/133239
Discussed with:	yongari
Approved by:	ed (mentor, implicit)
---
 sys/dev/jme/if_jme.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/jme/if_jme.c b/sys/dev/jme/if_jme.c
index c2e64f02f8c..eb8b6304523 100644
--- a/sys/dev/jme/if_jme.c
+++ b/sys/dev/jme/if_jme.c
@@ -465,7 +465,7 @@ jme_reg_macaddr(struct jme_softc *sc)
 		    "generating fake ethernet address.\n");
 		par0 = arc4random();
 		/* Set OUI to JMicron. */
-		sc->jme_eaddr[0] = 0x00;
+		sc->jme_eaddr[0] = 0x02;	/* U/L bit set. */
 		sc->jme_eaddr[1] = 0x1B;
 		sc->jme_eaddr[2] = 0x8C;
 		sc->jme_eaddr[3] = (par0 >> 16) & 0xff;

From 716779e2ff3faf0b4f92e73ed333e76655906dac Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Fri, 8 Jan 2010 14:30:03 +0000
Subject: [PATCH 1056/2592] MFC r201354: sh(1): Correct two places where "$@"
 lacked necessary quotes.

---
 bin/sh/sh.1 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 2739dccdd8e..bdf464bfdad 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -862,7 +862,7 @@ command is:
 If
 .Ic in
 and the following words are omitted,
-.Ic in Li $@
+.Ic in Li \&"$@\&"
 is used instead.
 The words are expanded, and then the list is executed
 repeatedly with the variable set to each word in turn.
@@ -1077,7 +1077,7 @@ and
 is
 .Dq Li "def ghi" ,
 then
-.Dq Li $@
+.Li \&"$@\&"
 expands to
 the two arguments:
 .Bd -literal -offset indent

From e859c2af8042db335bd3043e9f693a1e60d79543 Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Fri, 8 Jan 2010 14:33:03 +0000
Subject: [PATCH 1057/2592] MFC r201355: sh(1): document ulimit -w (swapuse
 rlimit).

---
 bin/sh/sh.1 | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index bdf464bfdad..e2da58f8958 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 January 8, 2010
 .Dt SH 1
 .Os
 .Sh NAME
@@ -2131,7 +2131,7 @@ and not found.
 For aliases the alias expansion is printed;
 for commands and tracked aliases
 the complete pathname of the command is printed.
-.It Ic ulimit Oo Fl HSabcdflmnpstuv Oc Op Ar limit
+.It Ic ulimit Oo Fl HSabcdflmnpstuvw Oc Op Ar limit
 Set or display resource limits (see
 .Xr getrlimit 2 ) .
 If
@@ -2195,6 +2195,9 @@ The maximal amount of CPU time to be used by each process, in seconds.
 The maximal number of simultaneous processes for this user ID.
 .It Fl v Ar virtualmem
 The maximal virtual size of a process, in kilobytes.
+.It Fl w Ar swapuse
+The maximum amount of swap space reserved or used for this user ID,
+in kilobytes.
 .El
 .It Ic umask Oo Fl S Oc Op Ar mask
 Set the file creation mask (see

From d3db09cb06648a268ed6809977350c9d6f7ec71c Mon Sep 17 00:00:00 2001
From: Rick Macklem 
Date: Fri, 8 Jan 2010 20:25:59 +0000
Subject: [PATCH 1058/2592] MFC: r200999 Modify the experimental server so that
 it uses VOP_ACCESSX(). This is necessary in order to enable NFSv4 ACL
 support. The argument to nfsvno_accchk() was changed to an accmode_t and the
 function nfsrv_aclaccess() was no longer needed and, therefore, deleted.

Reviewed by:	trasz
---
 sys/fs/nfs/nfs_commonacl.c      | 64 ----------------------------
 sys/fs/nfs/nfs_var.h            |  6 +--
 sys/fs/nfsserver/nfs_nfsdport.c | 73 +++++++++++++++-----------------
 sys/fs/nfsserver/nfs_nfsdserv.c | 74 ++++++++++++++++++---------------
 4 files changed, 75 insertions(+), 142 deletions(-)

diff --git a/sys/fs/nfs/nfs_commonacl.c b/sys/fs/nfs/nfs_commonacl.c
index 99d796eeb08..3127ca4cbae 100644
--- a/sys/fs/nfs/nfs_commonacl.c
+++ b/sys/fs/nfs/nfs_commonacl.c
@@ -619,70 +619,6 @@ nfsrv_buildacl(struct nfsrv_descript *nd, NFSACL_T *aclp, enum vtype type,
 	return (retlen);
 }
 
-/*
- * Check access for an NFSv4 acl.
- * The vflags are the basic VREAD, VWRITE, VEXEC. The mask is the NFSV4ACE
- * mask bits for the more detailed check.
- * If the more detailed check fails, due to no acl, do a basic one.
- */
-APPLESTATIC int
-nfsrv_aclaccess(vnode_t vp, accmode_t vflags, u_int32_t mask,
-    struct ucred *cred, NFSPROC_T *p)
-{
-	int error = 0;
-	accmode_t access;
-
-	if (nfsrv_useacl == 0) {
-		error = VOP_ACCESS(vp, vflags, cred, p);
-		return (error);
-	}
-
-	/* Convert NFSV4ACE mask to vaccess_t */
-	access = 0;
-	if (mask & NFSV4ACE_READDATA)
-		access |= VREAD;
-	if (mask & NFSV4ACE_LISTDIRECTORY)
-		access |= VREAD;
-	if (mask & NFSV4ACE_WRITEDATA)
-		access |= VWRITE;
-	if (mask & NFSV4ACE_ADDFILE)
-		access |= VWRITE;
-	if (mask & NFSV4ACE_APPENDDATA)
-		access |= VAPPEND;
-	if (mask & NFSV4ACE_ADDSUBDIRECTORY)
-		access |= VAPPEND;
-	if (mask & NFSV4ACE_READNAMEDATTR)
-		access |= VREAD_NAMED_ATTRS;
-	if (mask & NFSV4ACE_WRITENAMEDATTR)
-		access |= VWRITE_NAMED_ATTRS;
-	if (mask & NFSV4ACE_EXECUTE)
-		access |= VEXEC;
-	if (mask & NFSV4ACE_SEARCH)
-		access |= VEXEC;
-	if (mask & NFSV4ACE_DELETECHILD)
-		access |= VDELETE_CHILD;
-	if (mask & NFSV4ACE_READATTRIBUTES)
-		access |= VREAD_ATTRIBUTES;
-	if (mask & NFSV4ACE_WRITEATTRIBUTES)
-		access |= VWRITE_ATTRIBUTES;
-	if (mask & NFSV4ACE_DELETE)
-		access |= VDELETE;
-	if (mask & NFSV4ACE_READACL)
-		access |= VREAD_ACL;
-	if (mask & NFSV4ACE_WRITEACL)
-		access |= VWRITE_ACL;
-	if (mask & NFSV4ACE_WRITEOWNER)
-		access |= VWRITE_OWNER;
-	if (mask & NFSV4ACE_SYNCHRONIZE)
-		access |= VSYNCHRONIZE;
-
-	if (access != 0)
-		error = VOP_ACCESS(vp, access, cred, p);
-	else
-		error = VOP_ACCESS(vp, vflags, cred, p);
-	return (error);
-}
-
 /*
  * Set an NFSv4 acl.
  */
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 72e65c7a4d9..5864250c555 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -332,8 +332,6 @@ int nfsrv_dissectace(struct nfsrv_descript *, struct acl_entry *,
 #ifdef NFS4_ACL_EXTATTR_NAME
 int nfsrv_buildacl(struct nfsrv_descript *, NFSACL_T *, enum vtype,
     NFSPROC_T *);
-int nfsrv_aclaccess(vnode_t, accmode_t, u_int32_t, struct ucred *,
-    NFSPROC_T *);
 int nfsrv_setacl(vnode_t, NFSACL_T *, struct ucred *,
     NFSPROC_T *);
 int nfsrv_compareacl(NFSACL_T *, NFSACL_T *);
@@ -516,8 +514,8 @@ int nfsvno_getattr(vnode_t, struct nfsvattr *, struct ucred *,
 int nfsvno_setattr(vnode_t, struct nfsvattr *, struct ucred *,
     NFSPROC_T *, struct nfsexstuff *);
 int nfsvno_getfh(vnode_t, fhandle_t *, NFSPROC_T *);
-int nfsvno_accchk(vnode_t, u_int32_t, struct ucred *,
-    struct nfsexstuff *, NFSPROC_T *, int, int);
+int nfsvno_accchk(vnode_t, accmode_t, struct ucred *,
+    struct nfsexstuff *, NFSPROC_T *, int, int, u_int32_t *);
 int nfsvno_namei(struct nfsrv_descript *, struct nameidata *,
     vnode_t, int, struct nfsexstuff *, NFSPROC_T *, vnode_t *);
 void nfsvno_setpathbuf(struct nameidata *, char **, u_long **);
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index ca80fde358f..3b7f8d0a1df 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -131,32 +131,20 @@ nfsvno_getfh(struct vnode *vp, fhandle_t *fhp, struct thread *p)
 /*
  * Perform access checking for vnodes obtained from file handles that would
  * refer to files already opened by a Unix client. You cannot just use
- * vn_writechk() and VOP_ACCESS() for two reasons.
- * 1 - You must check for exported rdonly as well as MNT_RDONLY for the write case
+ * vn_writechk() and VOP_ACCESSX() for two reasons.
+ * 1 - You must check for exported rdonly as well as MNT_RDONLY for the write
+ *     case.
  * 2 - The owner is to be given access irrespective of mode bits for some
  *     operations, so that processes that chmod after opening a file don't
  *     break.
  */
 int
-nfsvno_accchk(struct vnode *vp, u_int32_t accessbits, struct ucred *cred,
-    struct nfsexstuff *exp, struct thread *p, int override, int vpislocked)
+nfsvno_accchk(struct vnode *vp, accmode_t accmode, struct ucred *cred,
+    struct nfsexstuff *exp, struct thread *p, int override, int vpislocked,
+    u_int32_t *supportedtypep)
 {
 	struct vattr vattr;
 	int error = 0, getret = 0;
-	accmode_t accmode;
-
-	/*
-	 * Convert accessbits to Vxxx flags.
-	 */
-	if (accessbits & (NFSV4ACE_WRITEDATA | NFSV4ACE_APPENDDATA |
-	    NFSV4ACE_ADDFILE | NFSV4ACE_ADDSUBDIRECTORY |
-	    NFSV4ACE_DELETECHILD | NFSV4ACE_WRITEATTRIBUTES |
-	    NFSV4ACE_DELETE | NFSV4ACE_WRITEACL | NFSV4ACE_WRITEOWNER))
-		accmode = VWRITE;
-	else if (accessbits & (NFSV4ACE_EXECUTE | NFSV4ACE_SEARCH))
-		accmode = VEXEC;
-	else
-		accmode = VREAD;
 
 	if (accmode & VWRITE) {
 		/* Just vn_writechk() changed to check rdonly */
@@ -166,7 +154,7 @@ nfsvno_accchk(struct vnode *vp, u_int32_t accessbits, struct ucred *cred,
 		 * device resident on the file system.
 		 */
 		if (NFSVNO_EXRDONLY(exp) ||
-			(vp->v_mount->mnt_flag & MNT_RDONLY)) {
+		    (vp->v_mount->mnt_flag & MNT_RDONLY)) {
 			switch (vp->v_type) {
 			case VREG:
 			case VDIR:
@@ -187,22 +175,26 @@ nfsvno_accchk(struct vnode *vp, u_int32_t accessbits, struct ucred *cred,
 	if (vpislocked == 0)
 		NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, p);
 
-#if defined(NFS4_ACL_EXTATTR_NAME) && defined(notyet)
-	/*
-	 * This function should be called once FFS has NFSv4 ACL support
-	 * in it.
-	 */
 	/*
 	 * Should the override still be applied when ACLs are enabled?
 	 */
-	if (nfsrv_useacl != 0 && NFSHASNFS4ACL(vp->v_mount))
-		error = nfsrv_aclaccess(vp, accmode, accessbits, cred, p);
-	else
-#endif
-	if (accessbits == NFSV4ACE_READATTRIBUTES)
-		error = 0;
-	else
-		error = VOP_ACCESS(vp, accmode, cred, p);
+	error = VOP_ACCESSX(vp, accmode, cred, p);
+	if (error != 0 && (accmode & (VDELETE | VDELETE_CHILD))) {
+		/*
+		 * Try again with VEXPLICIT_DENY, to see if the test for
+		 * deletion is supported.
+		 */
+		error = VOP_ACCESSX(vp, accmode | VEXPLICIT_DENY, cred, p);
+		if (error == 0) {
+			if (vp->v_type == VDIR) {
+				accmode &= ~(VDELETE | VDELETE_CHILD);
+				accmode |= VWRITE;
+				error = VOP_ACCESSX(vp, accmode, cred, p);
+			} else if (supportedtypep != NULL) {
+				*supportedtypep &= ~NFSACCESS_DELETE;
+			}
+		}
+	}
 
 	/*
 	 * Allow certain operations for the owner (reads and writes
@@ -790,9 +782,9 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp,
 		else
 			vput(ndp->ni_dvp);
 		if (!error && nvap->na_size != VNOVAL) {
-			error = nfsvno_accchk(*vpp, NFSV4ACE_ADDFILE,
+			error = nfsvno_accchk(*vpp, VWRITE,
 			    nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE,
-			    NFSACCCHK_VPISLOCKED);
+			    NFSACCCHK_VPISLOCKED, NULL);
 			if (!error) {
 				tempsize = nvap->na_size;
 				NFSVNO_ATTRINIT(nvap);
@@ -1334,8 +1326,9 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
 				else
 					NFSVNO_EXINIT(&nes);
 				nd->nd_repstat = nfsvno_accchk(vp, 
-				    NFSV4ACE_ADDFILE, cred, &nes, p,
-				    NFSACCCHK_NOOVERRIDE,NFSACCCHK_VPISLOCKED);
+				    VWRITE, cred, &nes, p,
+				    NFSACCCHK_NOOVERRIDE,
+				    NFSACCCHK_VPISLOCKED, NULL);
 				nd->nd_repstat = nfsrv_opencheck(clientid,
 				    stateidp, stp, vp, nd, p, nd->nd_repstat);
 				if (!nd->nd_repstat) {
@@ -1481,9 +1474,9 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
 #endif
 	}
 	if (!nd->nd_repstat)
-		nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_SEARCH,
+		nd->nd_repstat = nfsvno_accchk(vp, VEXEC,
 		    nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE,
-		    NFSACCCHK_VPISLOCKED);
+		    NFSACCCHK_VPISLOCKED, NULL);
 	if (nd->nd_repstat) {
 		vput(vp);
 		if (nd->nd_flag & ND_NFSV3)
@@ -1752,9 +1745,9 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
 	if (!nd->nd_repstat && cnt == 0)
 		nd->nd_repstat = NFSERR_TOOSMALL;
 	if (!nd->nd_repstat)
-		nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_SEARCH,
+		nd->nd_repstat = nfsvno_accchk(vp, VEXEC,
 		    nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE,
-		    NFSACCCHK_VPISLOCKED);
+		    NFSACCCHK_VPISLOCKED, NULL);
 	if (nd->nd_repstat) {
 		vput(vp);
 		if (nd->nd_flag & ND_NFSV3)
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index c0ac41dbbda..e56610b660e 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -88,6 +88,7 @@ nfsrvd_access(struct nfsrv_descript *nd, __unused int isdgram,
 	int getret, error = 0;
 	struct nfsvattr nva;
 	u_int32_t testmode, nfsmode, supported = 0;
+	accmode_t deletebit;
 
 	if (nd->nd_repstat) {
 		nfsrv_postopattr(nd, 1, &nva);
@@ -105,26 +106,30 @@ nfsrvd_access(struct nfsrv_descript *nd, __unused int isdgram,
 	}
 	if (nfsmode & NFSACCESS_READ) {
 		supported |= NFSACCESS_READ;
-		if (nfsvno_accchk(vp, NFSV4ACE_READDATA, nd->nd_cred, exp, p,
-		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED))
+		if (nfsvno_accchk(vp, VREAD, nd->nd_cred, exp, p,
+		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported))
 			nfsmode &= ~NFSACCESS_READ;
 	}
 	if (nfsmode & NFSACCESS_MODIFY) {
 		supported |= NFSACCESS_MODIFY;
-		if (nfsvno_accchk(vp, NFSV4ACE_WRITEDATA, nd->nd_cred, exp, p,
-		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED))
+		if (nfsvno_accchk(vp, VWRITE, nd->nd_cred, exp, p,
+		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported))
 			nfsmode &= ~NFSACCESS_MODIFY;
 	}
 	if (nfsmode & NFSACCESS_EXTEND) {
 		supported |= NFSACCESS_EXTEND;
-		if (nfsvno_accchk(vp, NFSV4ACE_APPENDDATA, nd->nd_cred, exp, p,
-		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED))
+		if (nfsvno_accchk(vp, VWRITE | VAPPEND, nd->nd_cred, exp, p,
+		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported))
 			nfsmode &= ~NFSACCESS_EXTEND;
 	}
 	if (nfsmode & NFSACCESS_DELETE) {
 		supported |= NFSACCESS_DELETE;
-		if (nfsvno_accchk(vp, NFSV4ACE_DELETE, nd->nd_cred, exp, p,
-		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED))
+		if (vp->v_type == VDIR)
+			deletebit = VDELETE_CHILD;
+		else
+			deletebit = VDELETE;
+		if (nfsvno_accchk(vp, deletebit, nd->nd_cred, exp, p,
+		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported))
 			nfsmode &= ~NFSACCESS_DELETE;
 	}
 	if (vnode_vtype(vp) == VDIR)
@@ -133,8 +138,8 @@ nfsrvd_access(struct nfsrv_descript *nd, __unused int isdgram,
 		testmode = NFSACCESS_EXECUTE;
 	if (nfsmode & testmode) {
 		supported |= (nfsmode & testmode);
-		if (nfsvno_accchk(vp, NFSV4ACE_EXECUTE, nd->nd_cred, exp, p,
-		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED))
+		if (nfsvno_accchk(vp, VEXEC, nd->nd_cred, exp, p,
+		    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported))
 			nfsmode &= ~testmode;
 	}
 	nfsmode &= supported;
@@ -189,9 +194,9 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
 		}
 		if (!nd->nd_repstat)
 			nd->nd_repstat = nfsvno_accchk(vp,
-			    NFSV4ACE_READATTRIBUTES,
-			    nd->nd_cred, exp, p,
-			    NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED);
+			    VREAD_ATTRIBUTES,
+			    nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE,
+			    NFSACCCHK_VPISLOCKED, NULL);
 	}
 	if (!nd->nd_repstat)
 		nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p);
@@ -291,8 +296,9 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram,
 			else if (nva2.na_uid != nd->nd_cred->cr_uid ||
 			    NFSVNO_EXSTRICTACCESS(exp))
 				nd->nd_repstat = nfsvno_accchk(vp,
-				    NFSV4ACE_WRITEDATA, nd->nd_cred, exp, p,
-				    NFSACCCHK_NOOVERRIDE,NFSACCCHK_VPISLOCKED);
+				    VWRITE, nd->nd_cred, exp, p,
+				    NFSACCCHK_NOOVERRIDE,
+				    NFSACCCHK_VPISLOCKED, NULL);
 		}
 	}
 	if (!nd->nd_repstat && (nd->nd_flag & ND_NFSV4))
@@ -612,13 +618,13 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int isdgram,
 	if (!nd->nd_repstat &&
 	    (nva.na_uid != nd->nd_cred->cr_uid ||
 	     NFSVNO_EXSTRICTACCESS(exp))) {
-		nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_READDATA,
+		nd->nd_repstat = nfsvno_accchk(vp, VREAD,
 		    nd->nd_cred, exp, p,
-		    NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED);
+		    NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED, NULL);
 		if (nd->nd_repstat)
-			nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_EXECUTE,
-			    nd->nd_cred, exp, p,
-			    NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED);
+			nd->nd_repstat = nfsvno_accchk(vp, VEXEC,
+			    nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER,
+			    NFSACCCHK_VPISLOCKED, NULL);
 	}
 	if ((nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)
 		nd->nd_repstat = nfsrv_lockctrl(vp, &stp, &lop, NULL, clientid,
@@ -788,9 +794,9 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int isdgram,
 	if (!nd->nd_repstat &&
 	    (forat.na_uid != nd->nd_cred->cr_uid ||
 	     NFSVNO_EXSTRICTACCESS(exp)))
-		nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_WRITEDATA,
+		nd->nd_repstat = nfsvno_accchk(vp, VWRITE,
 		    nd->nd_cred, exp, p,
-		    NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED);
+		    NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED, NULL);
 	if ((nd->nd_flag & ND_NFSV4) && !nd->nd_repstat) {
 		nd->nd_repstat = nfsrv_lockctrl(vp, &stp, &lop, NULL, clientid,
 		    &stateid, exp, nd, p);
@@ -2146,17 +2152,17 @@ nfsrvd_lock(struct nfsrv_descript *nd, __unused int isdgram,
 	}
 	if (!nd->nd_repstat) {
 	    if (lflags & NFSLCK_WRITE) {
-		nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_WRITEDATA,
+		nd->nd_repstat = nfsvno_accchk(vp, VWRITE,
 		    nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER,
-		    NFSACCCHK_VPISLOCKED);
+		    NFSACCCHK_VPISLOCKED, NULL);
 	    } else {
-		nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_READDATA,
+		nd->nd_repstat = nfsvno_accchk(vp, VREAD,
 		    nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER,
-		    NFSACCCHK_VPISLOCKED);
+		    NFSACCCHK_VPISLOCKED, NULL);
 		if (nd->nd_repstat)
-		    nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_EXECUTE,
+		    nd->nd_repstat = nfsvno_accchk(vp, VEXEC,
 			nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER,
-			NFSACCCHK_VPISLOCKED);
+			NFSACCCHK_VPISLOCKED, NULL);
 	    }
 	}
 
@@ -2672,15 +2678,15 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
 		nd->nd_repstat = NFSERR_INVAL;
 	}
 	if (!nd->nd_repstat && (stp->ls_flags & NFSLCK_WRITEACCESS))
-	    nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_WRITEDATA, nd->nd_cred,
-	        exp, p, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED);
+	    nd->nd_repstat = nfsvno_accchk(vp, VWRITE, nd->nd_cred,
+	        exp, p, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED, NULL);
 	if (!nd->nd_repstat && (stp->ls_flags & NFSLCK_READACCESS)) {
-	    nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_READDATA, nd->nd_cred,
-	        exp, p, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED);
+	    nd->nd_repstat = nfsvno_accchk(vp, VREAD, nd->nd_cred,
+	        exp, p, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED, NULL);
 	    if (nd->nd_repstat)
-		nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_EXECUTE,
+		nd->nd_repstat = nfsvno_accchk(vp, VEXEC,
 		    nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER,
-		    NFSACCCHK_VPISLOCKED);
+		    NFSACCCHK_VPISLOCKED, NULL);
 	}
 
 	if (!nd->nd_repstat) {

From 6d2fb730284bbd839ccc110e638858ddbfdebb89 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Fri, 8 Jan 2010 21:15:09 +0000
Subject: [PATCH 1059/2592] MFC r198987,199414,199543,200422

Partial merge r198987:
  Use device_printf() and if_printf() instead of printf() with an explicit
  unit number and remove 'unit' members from softc.

Partial merge r199414:
  Use the bus_*() routines rather than bus_space_*() for register operations.

r199543:
  Several fixes to this driver:
  - Overhaul the locking to avoid recursion and add missing locking in a few
    places.
  - Don't schedule a task to call vge_start() from contexts that are safe to
    call vge_start() directly.  Just invoke the routine directly instead
    (this is what all of the other NIC drivers I am familiar with do).  Note
    that vge(4) does not use an interrupt filter handler which is the primary
    reason some other drivers use tasks.
  - Add a new private timer to drive the watchdog timer instead of using
    if_watchdog and if_timer.
  - Fixup detach by calling ether_ifdetach() before stopping the interface.

r200422:
  Remove driver lock assertion in MII register access. This change
  was made in r199543 to remove MTX_RECURSE. These routines can be
  called in device attach phase(e.g. mii_phy_probe()) so checking
  assertion here is not right as caller does not hold a driver lock.
---
 sys/dev/vge/if_vge.c    | 175 +++++++++++++++++++---------------------
 sys/dev/vge/if_vgevar.h |  20 +++--
 2 files changed, 92 insertions(+), 103 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index f08f8a267f3..08c183b72c4 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -93,7 +93,6 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
@@ -160,12 +159,13 @@ static int vge_rxeof		(struct vge_softc *);
 static void vge_txeof		(struct vge_softc *);
 static void vge_intr		(void *);
 static void vge_tick		(void *);
-static void vge_tx_task		(void *, int);
 static void vge_start		(struct ifnet *);
+static void vge_start_locked	(struct ifnet *);
 static int vge_ioctl		(struct ifnet *, u_long, caddr_t);
 static void vge_init		(void *);
+static void vge_init_locked	(struct vge_softc *);
 static void vge_stop		(struct vge_softc *);
-static void vge_watchdog	(struct ifnet *);
+static void vge_watchdog	(void *);
 static int vge_suspend		(device_t);
 static int vge_resume		(device_t);
 static int vge_shutdown		(device_t);
@@ -378,7 +378,6 @@ vge_miibus_readreg(dev, phy, reg)
 	if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
 		return(0);
 
-	VGE_LOCK(sc);
 	vge_miipoll_stop(sc);
 
 	/* Specify the register we want to read. */
@@ -400,7 +399,6 @@ vge_miibus_readreg(dev, phy, reg)
 		rval = CSR_READ_2(sc, VGE_MIIDATA);
 
 	vge_miipoll_start(sc);
-	VGE_UNLOCK(sc);
 
 	return (rval);
 }
@@ -418,7 +416,6 @@ vge_miibus_writereg(dev, phy, reg, data)
 	if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
 		return(0);
 
-	VGE_LOCK(sc);
 	vge_miipoll_stop(sc);
 
 	/* Specify the register we want to write. */
@@ -443,7 +440,6 @@ vge_miibus_writereg(dev, phy, reg, data)
 	}
 
 	vge_miipoll_start(sc);
-	VGE_UNLOCK(sc);
 
 	return (rval);
 }
@@ -929,7 +925,9 @@ vge_attach(dev)
 	sc->vge_dev = dev;
 
 	mtx_init(&sc->vge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
-	    MTX_DEF | MTX_RECURSE);
+	    MTX_DEF);
+	callout_init_mtx(&sc->vge_watchdog, &sc->vge_mtx, 0);
+
 	/*
 	 * Map control/status registers.
 	 */
@@ -945,9 +943,6 @@ vge_attach(dev)
 		goto fail;
 	}
 
-	sc->vge_btag = rman_get_bustag(sc->vge_res);
-	sc->vge_bhandle = rman_get_bushandle(sc->vge_res);
-
 	/* Allocate interrupt */
 	rid = 0;
 	sc->vge_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
@@ -967,8 +962,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 +986,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 +994,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;
 	}
@@ -1019,14 +1012,11 @@ vge_attach(dev)
 #ifdef DEVICE_POLLING
 	ifp->if_capabilities |= IFCAP_POLLING;
 #endif
-	ifp->if_watchdog = vge_watchdog;
 	ifp->if_init = vge_init;
 	IFQ_SET_MAXLEN(&ifp->if_snd, VGE_IFQ_MAXLEN);
 	ifp->if_snd.ifq_drv_maxlen = VGE_IFQ_MAXLEN;
 	IFQ_SET_READY(&ifp->if_snd);
 
-	TASK_INIT(&sc->vge_txtask, 0, vge_tx_task, ifp);
-
 	/*
 	 * Call MI attach routine.
 	 */
@@ -1075,21 +1065,11 @@ vge_detach(dev)
 
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
-		vge_stop(sc);
-		/*
-		 * Force off the IFF_UP flag here, in case someone
-		 * still had a BPF descriptor attached to this
-		 * interface. If they do, ether_ifattach() will cause
-		 * the BPF code to try and clear the promisc mode
-		 * flag, which will bubble down to vge_ioctl(),
-		 * which will try to call vge_init() again. This will
-		 * turn the NIC back on and restart the MII ticker,
-		 * which will panic the system when the kernel tries
-		 * to invoke the vge_tick() function that isn't there
-		 * anymore.
-		 */
-		ifp->if_flags &= ~IFF_UP;
 		ether_ifdetach(ifp);
+		VGE_LOCK(sc);
+		vge_stop(sc);
+		VGE_UNLOCK(sc);
+		callout_drain(&sc->vge_watchdog);
 	}
 	if (sc->vge_miibus)
 		device_delete_child(dev, sc->vge_miibus);
@@ -1528,7 +1508,7 @@ vge_txeof(sc)
 	if (idx != sc->vge_ldata.vge_tx_considx) {
 		sc->vge_ldata.vge_tx_considx = idx;
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-		ifp->if_timer = 0;
+		sc->vge_timer = 0;
 	}
 
 	/*
@@ -1554,7 +1534,7 @@ vge_tick(xsc)
 
 	sc = xsc;
 	ifp = sc->vge_ifp;
-	VGE_LOCK(sc);
+	VGE_LOCK_ASSERT(sc);
 	mii = device_get_softc(sc->vge_miibus);
 
 	mii_tick(mii);
@@ -1571,13 +1551,10 @@ vge_tick(xsc)
 			if_link_state_change(sc->vge_ifp,
 			    LINK_STATE_UP);
 			if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-				taskqueue_enqueue(taskqueue_swi,
-				    &sc->vge_txtask);
+				vge_start_locked(ifp);
 		}
 	}
 
-	VGE_UNLOCK(sc);
-
 	return;
 }
 
@@ -1597,7 +1574,7 @@ vge_poll (struct ifnet *ifp, enum poll_cmd cmd, int count)
 	vge_txeof(sc);
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		taskqueue_enqueue(taskqueue_swi, &sc->vge_txtask);
+		vge_start_locked(ifp);
 
 	if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
 		u_int32_t       status;
@@ -1613,7 +1590,7 @@ vge_poll (struct ifnet *ifp, enum poll_cmd cmd, int count)
 
 		if (status & VGE_ISR_TXDMA_STALL ||
 		    status & VGE_ISR_RXDMA_STALL)
-			vge_init(sc);
+			vge_init_locked(sc);
 
 		if (status & (VGE_ISR_RXOFLOW|VGE_ISR_RXNODESC)) {
 			vge_rxeof(sc);
@@ -1686,7 +1663,7 @@ vge_intr(arg)
 			vge_txeof(sc);
 
 		if (status & (VGE_ISR_TXDMA_STALL|VGE_ISR_RXDMA_STALL))
-			vge_init(sc);
+			vge_init_locked(sc);
 
 		if (status & VGE_ISR_LINKSTS)
 			vge_tick(sc);
@@ -1695,10 +1672,10 @@ vge_intr(arg)
 	/* Re-enable interrupts */
 	CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
 
-	VGE_UNLOCK(sc);
-
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		taskqueue_enqueue(taskqueue_swi, &sc->vge_txtask);
+		vge_start_locked(ifp);
+
+	VGE_UNLOCK(sc);
 
 	return;
 }
@@ -1736,8 +1713,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 +1734,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);
 		}
 	}
@@ -1780,19 +1756,6 @@ vge_encap(sc, m_head, idx)
 	return (0);
 }
 
-static void
-vge_tx_task(arg, npending)
-	void			*arg;
-	int			npending;
-{
-	struct ifnet		*ifp;
-
-	ifp = arg;
-	vge_start(ifp);
-
-	return;
-}
-
 /*
  * Main transmit routine.
  */
@@ -1802,21 +1765,29 @@ vge_start(ifp)
 	struct ifnet		*ifp;
 {
 	struct vge_softc	*sc;
+
+	sc = ifp->if_softc;
+	VGE_LOCK(sc);
+	vge_start_locked(ifp);
+	VGE_UNLOCK(sc);
+}
+
+static void
+vge_start_locked(ifp)
+	struct ifnet		*ifp;
+{
+	struct vge_softc	*sc;
 	struct mbuf		*m_head = NULL;
 	int			idx, pidx = 0;
 
 	sc = ifp->if_softc;
-	VGE_LOCK(sc);
+	VGE_LOCK_ASSERT(sc);
 
-	if (!sc->vge_link || ifp->if_drv_flags & IFF_DRV_OACTIVE) {
-		VGE_UNLOCK(sc);
+	if (!sc->vge_link || ifp->if_drv_flags & IFF_DRV_OACTIVE)
 		return;
-	}
 
-	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
-		VGE_UNLOCK(sc);
+	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		return;
-	}
 
 	idx = sc->vge_ldata.vge_tx_prodidx;
 
@@ -1849,10 +1820,8 @@ vge_start(ifp)
 		ETHER_BPF_MTAP(ifp, m_head);
 	}
 
-	if (idx == sc->vge_ldata.vge_tx_prodidx) {
-		VGE_UNLOCK(sc);
+	if (idx == sc->vge_ldata.vge_tx_prodidx)
 		return;
-	}
 
 	/* Flush the TX descriptors */
 
@@ -1876,12 +1845,10 @@ vge_start(ifp)
 	 */
 	CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE);
 
-	VGE_UNLOCK(sc);
-
 	/*
 	 * Set a timeout in case the chip goes out to lunch.
 	 */
-	ifp->if_timer = 5;
+	sc->vge_timer = 5;
 
 	return;
 }
@@ -1891,11 +1858,20 @@ vge_init(xsc)
 	void			*xsc;
 {
 	struct vge_softc	*sc = xsc;
+
+	VGE_LOCK(sc);
+	vge_init_locked(sc);
+	VGE_UNLOCK(sc);
+}
+
+static void
+vge_init_locked(struct vge_softc *sc)
+{
 	struct ifnet		*ifp = sc->vge_ifp;
 	struct mii_data		*mii;
 	int			i;
 
-	VGE_LOCK(sc);
+	VGE_LOCK_ASSERT(sc);
 	mii = device_get_softc(sc->vge_miibus);
 
 	/*
@@ -2051,12 +2027,11 @@ vge_init(xsc)
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	callout_reset(&sc->vge_watchdog, hz, vge_watchdog, sc);
 
 	sc->vge_if_flags = 0;
 	sc->vge_link = 0;
 
-	VGE_UNLOCK(sc);
-
 	return;
 }
 
@@ -2093,7 +2068,9 @@ vge_ifmedia_sts(ifp, ifmr)
 	sc = ifp->if_softc;
 	mii = device_get_softc(sc->vge_miibus);
 
+	VGE_LOCK(sc);
 	mii_pollstat(mii);
+	VGE_UNLOCK(sc);
 	ifmr->ifm_active = mii->mii_media_active;
 	ifmr->ifm_status = mii->mii_media_status;
 
@@ -2168,6 +2145,7 @@ vge_ioctl(ifp, command, data)
 		ifp->if_mtu = ifr->ifr_mtu;
 		break;
 	case SIOCSIFFLAGS:
+		VGE_LOCK(sc);
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 			    ifp->if_flags & IFF_PROMISC &&
@@ -2182,16 +2160,19 @@ vge_ioctl(ifp, command, data)
 				    VGE_RXCTL_RX_PROMISC);
 				vge_setmulti(sc);
                         } else
-				vge_init(sc);
+				vge_init_locked(sc);
 		} else {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 				vge_stop(sc);
 		}
 		sc->vge_if_flags = ifp->if_flags;
+		VGE_UNLOCK(sc);
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		VGE_LOCK(sc);
 		vge_setmulti(sc);
+		VGE_UNLOCK(sc);
 		break;
 	case SIOCGIFMEDIA:
 	case SIOCSIFMEDIA:
@@ -2225,6 +2206,7 @@ vge_ioctl(ifp, command, data)
 			}
 		}
 #endif /* DEVICE_POLLING */
+		VGE_LOCK(sc);
 		if ((mask & IFCAP_TXCSUM) != 0 &&
 		    (ifp->if_capabilities & IFCAP_TXCSUM) != 0) {
 			ifp->if_capenable ^= IFCAP_TXCSUM;
@@ -2236,6 +2218,7 @@ vge_ioctl(ifp, command, data)
 		if ((mask & IFCAP_RXCSUM) != 0 &&
 		    (ifp->if_capabilities & IFCAP_RXCSUM) != 0)
 			ifp->if_capenable ^= IFCAP_RXCSUM;
+		VGE_UNLOCK(sc);
 	    }
 		break;
 	default:
@@ -2247,22 +2230,25 @@ vge_ioctl(ifp, command, data)
 }
 
 static void
-vge_watchdog(ifp)
-	struct ifnet		*ifp;
+vge_watchdog(void *arg)
 {
-	struct vge_softc		*sc;
+	struct vge_softc *sc;
+	struct ifnet *ifp;
 
-	sc = ifp->if_softc;
-	VGE_LOCK(sc);
-	printf("vge%d: watchdog timeout\n", sc->vge_unit);
+	sc = arg;
+	VGE_LOCK_ASSERT(sc);
+	callout_reset(&sc->vge_watchdog, hz, vge_watchdog, sc);
+	if (sc->vge_timer == 0 || --sc->vge_timer > 0)
+		return;
+
+	ifp = sc->vge_ifp;
+	if_printf(ifp, "watchdog timeout\n");
 	ifp->if_oerrors++;
 
 	vge_txeof(sc);
 	vge_rxeof(sc);
 
-	vge_init(sc);
-
-	VGE_UNLOCK(sc);
+	vge_init_locked(sc);
 
 	return;
 }
@@ -2278,9 +2264,10 @@ vge_stop(sc)
 	register int		i;
 	struct ifnet		*ifp;
 
-	VGE_LOCK(sc);
+	VGE_LOCK_ASSERT(sc);
 	ifp = sc->vge_ifp;
-	ifp->if_timer = 0;
+	sc->vge_timer = 0;
+	callout_stop(&sc->vge_watchdog);
 
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
@@ -2318,8 +2305,6 @@ vge_stop(sc)
 		}
 	}
 
-	VGE_UNLOCK(sc);
-
 	return;
 }
 
@@ -2336,9 +2321,11 @@ vge_suspend(dev)
 
 	sc = device_get_softc(dev);
 
+	VGE_LOCK(sc);
 	vge_stop(sc);
 
 	sc->suspended = 1;
+	VGE_UNLOCK(sc);
 
 	return (0);
 }
@@ -2363,10 +2350,12 @@ vge_resume(dev)
 	pci_enable_io(dev, SYS_RES_MEMORY);
 
 	/* reinitialize interface if necessary */
+	VGE_LOCK(sc);
 	if (ifp->if_flags & IFF_UP)
-		vge_init(sc);
+		vge_init_locked(sc);
 
 	sc->suspended = 0;
+	VGE_UNLOCK(sc);
 
 	return (0);
 }
@@ -2383,7 +2372,9 @@ vge_shutdown(dev)
 
 	sc = device_get_softc(dev);
 
+	VGE_LOCK(sc);
 	vge_stop(sc);
+	VGE_UNLOCK(sc);
 
 	return (0);
 }
diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h
index 5d240a33a9e..c4f7edb839f 100644
--- a/sys/dev/vge/if_vgevar.h
+++ b/sys/dev/vge/if_vgevar.h
@@ -100,22 +100,20 @@ struct vge_list_data {
 struct vge_softc {
 	struct ifnet		*vge_ifp;	/* interface info */
 	device_t		vge_dev;
-	bus_space_handle_t	vge_bhandle;	/* bus space handle */
-	bus_space_tag_t		vge_btag;	/* bus space tag */
 	struct resource		*vge_res;
 	struct resource		*vge_irq;
 	void			*vge_intrhand;
 	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;
 	int			vge_link;
 	int			vge_camidx;
-	struct task		vge_txtask;
 	struct mtx		vge_mtx;
+	struct callout		vge_watchdog;
+	int			vge_timer;
 	struct mbuf		*vge_head;
 	struct mbuf		*vge_tail;
 
@@ -135,20 +133,20 @@ struct vge_softc {
  * register space access macros
  */
 #define CSR_WRITE_STREAM_4(sc, reg, val)	\
-	bus_space_write_stream_4(sc->vge_btag, sc->vge_bhandle, reg, val)
+	bus_write_stream_4(sc->vge_res, reg, val)
 #define CSR_WRITE_4(sc, reg, val)	\
-	bus_space_write_4(sc->vge_btag, sc->vge_bhandle, reg, val)
+	bus_write_4(sc->vge_res, reg, val)
 #define CSR_WRITE_2(sc, reg, val)	\
-	bus_space_write_2(sc->vge_btag, sc->vge_bhandle, reg, val)
+	bus_write_2(sc->vge_res, reg, val)
 #define CSR_WRITE_1(sc, reg, val)	\
-	bus_space_write_1(sc->vge_btag, sc->vge_bhandle, reg, val)
+	bus_write_1(sc->vge_res, reg, val)
 
 #define CSR_READ_4(sc, reg)		\
-	bus_space_read_4(sc->vge_btag, sc->vge_bhandle, reg)
+	bus_read_4(sc->vge_res, reg)
 #define CSR_READ_2(sc, reg)		\
-	bus_space_read_2(sc->vge_btag, sc->vge_bhandle, reg)
+	bus_read_2(sc->vge_res, reg)
 #define CSR_READ_1(sc, reg)		\
-	bus_space_read_1(sc->vge_btag, sc->vge_bhandle, reg)
+	bus_read_1(sc->vge_res, reg)
 
 #define CSR_SETBIT_1(sc, reg, x)	\
 	CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) | (x))

From f2940816a85f0df6e5ae06331f3ea8b02b853695 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Fri, 8 Jan 2010 21:25:52 +0000
Subject: [PATCH 1060/2592] MFC r200519-200522

r200519:
  Remove register keyword.

r200520:
  Prefer device_printf(9) to printf(9).

r200521:
  Fix spelling in comment.

r200522:
  Prefer bus_alloc_resource_any(9) to bus_alloc_resource(9).
---
 sys/dev/vge/if_vge.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index 08c183b72c4..883947038d4 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -233,7 +233,7 @@ vge_eeprom_getword(sc, addr, dest)
 	int			addr;
 	u_int16_t		*dest;
 {
-	register int		i;
+	int			i;
 	u_int16_t		word = 0;
 
 	/*
@@ -536,7 +536,7 @@ fail:
 /*
  * Program the multicast filter. We use the 64-entry CAM filter
  * for perfect filtering. If there's more than 64 multicast addresses,
- * we use the hash filter insted.
+ * we use the hash filter instead.
  */
 static void
 vge_setmulti(sc)
@@ -602,7 +602,7 @@ static void
 vge_reset(sc)
 	struct vge_softc		*sc;
 {
-	register int		i;
+	int			i;
 
 	CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_SOFTRESET);
 
@@ -918,10 +918,9 @@ vge_attach(dev)
 	u_char			eaddr[ETHER_ADDR_LEN];
 	struct vge_softc	*sc;
 	struct ifnet		*ifp;
-	int			unit, error = 0, rid;
+	int			error = 0, rid;
 
 	sc = device_get_softc(dev);
-	unit = device_get_unit(dev);
 	sc->vge_dev = dev;
 
 	mtx_init(&sc->vge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
@@ -934,22 +933,22 @@ vge_attach(dev)
 	pci_enable_busmaster(dev);
 
 	rid = VGE_PCI_LOMEM;
-	sc->vge_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
-	    0, ~0, 1, RF_ACTIVE);
+	sc->vge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
 
 	if (sc->vge_res == NULL) {
-		printf ("vge%d: couldn't map ports/memory\n", unit);
+		device_printf(dev, "couldn't map ports/memory\n");
 		error = ENXIO;
 		goto fail;
 	}
 
 	/* Allocate interrupt */
 	rid = 0;
-	sc->vge_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
-	    0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
+	sc->vge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_SHAREABLE | RF_ACTIVE);
 
 	if (sc->vge_irq == NULL) {
-		printf("vge%d: couldn't map interrupt\n", unit);
+		device_printf(dev, "couldn't map interrupt\n");
 		error = ENXIO;
 		goto fail;
 	}
@@ -1027,7 +1026,7 @@ vge_attach(dev)
 	    NULL, vge_intr, sc, &sc->vge_intrhand);
 
 	if (error) {
-		printf("vge%d: couldn't set up irq\n", unit);
+		device_printf(dev, "couldn't set up irq\n");
 		ether_ifdetach(ifp);
 		goto fail;
 	}
@@ -1179,7 +1178,7 @@ vge_newbuf(sc, idx, m)
 
 	/*
 	 * Note: the manual fails to document the fact that for
-	 * proper opration, the driver needs to replentish the RX
+	 * proper operation, the driver needs to replenish the RX
 	 * DMA ring 4 descriptors at a time (rather than one at a
 	 * time, like most chips). We can allocate the new buffers
 	 * but we should not set the OWN bits until we're ready
@@ -1971,7 +1970,7 @@ vge_init_locked(struct vge_softc *sc)
 
 	/*
 	 * Configure one-shot timer for microsecond
-	 * resulution and load it for 500 usecs.
+	 * resolution and load it for 500 usecs.
 	 */
 	CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_TIMER0_RES);
 	CSR_WRITE_2(sc, VGE_SSTIMER, 400);
@@ -2261,7 +2260,7 @@ static void
 vge_stop(sc)
 	struct vge_softc		*sc;
 {
-	register int		i;
+	int			i;
 	struct ifnet		*ifp;
 
 	VGE_LOCK_ASSERT(sc);

From bce2400f8c380dede12d1b817f3e0012698c2c1d Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Fri, 8 Jan 2010 21:37:16 +0000
Subject: [PATCH 1061/2592] MFC r200525:   Overhaul bus_dma(9) usage and fix
 various things.    o Separate TX/RX buffer DMA tag from TX/RX descriptor ring
 DMA tag.    o Separate RX buffer DMA tag from common buffer DMA tag. RX DMA  
    tag has different restriction compared to TX DMA tag.    o Add 40bit DMA
 address support.    o Adjust TX/RX descriptor ring alignment to 64 bytes from
 256      bytes as documented in datasheet.    o Added check to ensure TX/RX
 ring reside within a 4GB boundary.      Since TX/RX ring shares the same high
 address register they      should have the same high address.    o TX/RX side
 bus_dmamap_load_mbuf_sg(9) support.    o Add lock assertion to
 vge_setmulti().    o Add RX spare DMA map to recover from DMA map load
 failure.    o Add optimized RX buffer handler, vge_discard_rxbuf which is    
  activated when vge(4) sees bad frames.    o Don't blindly update
 VGE_RXDESC_RESIDUECNT register. Datasheet      says the register should be
 updated only when number of      available RX descriptors are multiple of 4. 
   o Use __NO_STRICT_ALIGNMENT instead of defining VGE_FIXUP_RX which      is
 only set for i386 architecture. Previously vge(4) also      performed
 expensive copy operation to align IP header on amd64.      This change should
 give RX performance boost on amd64      architecture.    o Don't reinitialize
 controller if driver is already running. This      should reduce number of
 link state flipping.    o Since vge(4) drops a driver lock before passing
 received frame      to upper layer, make sure vge(4) is still running after  
    re-acquiring driver lock.    o Add second argument count to vge_rxeof().
 The argument will      limit number of packets could be processed in RX
 handler.    o Rearrange vge_rxeof() not to allocate RX buffer if received    
  frame was bad packet.    o Removed if_printf that prints DMA map failure.
 This type of      message shouldn't be used in fast path of driver.    o
 Reduce number of allowed TX buffer fragments to 6 from 7. A TX     
 descriptor allows 7 fragments of a frame. However the CMZ field      of
 descriptor has just 3bits and the controller wants to see      fragment + 1
 in the field. So if we have 7 fragments the field      value would be 0 which
 seems to cause unexpected results under      certain conditions. This change
 should fix occasional TX hang      observed on vge(4).    o Simplify
 vge_stat_locked() and add number of available TX      descriptor check.    o
 vge(4) controllers lack padding short frames. Make sure to fill      zero for
 the padded bytes. This closes unintended information      disclosure.    o
 Don't set VGE_TDCTL_JUMBO flag. Datasheet is not clear whether      this bit
 should be set by driver or write-back status bit after      transmission. At
 least vendor's driver does not set this bit so      remove it. Without this
 bit vge(4) still can send jumbo frames.    o Don't start driver when vge(4)
 know there are not enough RX      buffers.    o Remove volatile keyword in RX
 descriptor structure. This should      be handled by bus_dma(9).    o
 Collapse two 16bits member of TX/RX descriptor into single 32bits     
 member.    o Reduce number of RX descriptors to 252 from 256. The     
 VGE_RXDESCNUM is 16bits register but only lower 8bits are valid.      So the
 maximum number of RX descriptors would be 255. However      the number of
 should be multiple of 4 as controller wants to      update 4 RX descriptors
 at a time. This limits the maximum      number of RX descriptor to be 252.

PR:	kern/141276, kern/141414
---
 sys/dev/vge/if_vge.c    | 1447 +++++++++++++++++++++------------------
 sys/dev/vge/if_vgereg.h |   16 +-
 sys/dev/vge/if_vgevar.h |  123 ++--
 3 files changed, 867 insertions(+), 719 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index 883947038d4..4a73f8d8112 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -140,22 +140,21 @@ static int vge_probe		(device_t);
 static int vge_attach		(device_t);
 static int vge_detach		(device_t);
 
-static int vge_encap		(struct vge_softc *, struct mbuf *, int);
+static int vge_encap		(struct vge_softc *, struct mbuf **);
 
-static void vge_dma_map_addr	(void *, bus_dma_segment_t *, int, int);
-static void vge_dma_map_rx_desc	(void *, bus_dma_segment_t *, int,
-				    bus_size_t, int);
-static void vge_dma_map_tx_desc	(void *, bus_dma_segment_t *, int,
-				    bus_size_t, int);
-static int vge_allocmem		(device_t, struct vge_softc *);
-static int vge_newbuf		(struct vge_softc *, int, struct mbuf *);
+static void vge_dmamap_cb	(void *, bus_dma_segment_t *, int, int);
+static int vge_dma_alloc	(struct vge_softc *);
+static void vge_dma_free	(struct vge_softc *);
+static void vge_discard_rxbuf	(struct vge_softc *, int);
+static int vge_newbuf		(struct vge_softc *, int);
 static int vge_rx_list_init	(struct vge_softc *);
 static int vge_tx_list_init	(struct vge_softc *);
-#ifdef VGE_FIXUP_RX
+static void vge_freebufs	(struct vge_softc *);
+#ifndef __NO_STRICT_ALIGNMENT
 static __inline void vge_fixup_rx
 				(struct mbuf *);
 #endif
-static int vge_rxeof		(struct vge_softc *);
+static int vge_rxeof		(struct vge_softc *, int);
 static void vge_txeof		(struct vge_softc *);
 static void vge_intr		(void *);
 static void vge_tick		(void *);
@@ -547,6 +546,8 @@ vge_setmulti(sc)
 	struct ifmultiaddr	*ifma;
 	u_int32_t		h, hashes[2] = { 0, 0 };
 
+	VGE_LOCK_ASSERT(sc);
+
 	ifp = sc->vge_ifp;
 
 	/* First, zot all the multicast entries. */
@@ -662,249 +663,326 @@ vge_probe(dev)
 	return (ENXIO);
 }
 
-static void
-vge_dma_map_rx_desc(arg, segs, nseg, mapsize, error)
-	void			*arg;
-	bus_dma_segment_t	*segs;
-	int			nseg;
-	bus_size_t		mapsize;
-	int			error;
-{
-
-	struct vge_dmaload_arg	*ctx;
-	struct vge_rx_desc	*d = NULL;
-
-	if (error)
-		return;
-
-	ctx = arg;
-
-	/* Signal error to caller if there's too many segments */
-	if (nseg > ctx->vge_maxsegs) {
-		ctx->vge_maxsegs = 0;
-		return;
-	}
-
-	/*
-	 * Map the segment array into descriptors.
-	 */
-
-	d = &ctx->sc->vge_ldata.vge_rx_list[ctx->vge_idx];
-
-	/* If this descriptor is still owned by the chip, bail. */
-
-	if (le32toh(d->vge_sts) & VGE_RDSTS_OWN) {
-		device_printf(ctx->sc->vge_dev,
-		    "tried to map busy descriptor\n");
-		ctx->vge_maxsegs = 0;
-		return;
-	}
-
-	d->vge_buflen = htole16(VGE_BUFLEN(segs[0].ds_len) | VGE_RXDESC_I);
-	d->vge_addrlo = htole32(VGE_ADDR_LO(segs[0].ds_addr));
-	d->vge_addrhi = htole16(VGE_ADDR_HI(segs[0].ds_addr) & 0xFFFF);
-	d->vge_sts = 0;
-	d->vge_ctl = 0;
-
-	ctx->vge_maxsegs = 1;
-
-	return;
-}
-
-static void
-vge_dma_map_tx_desc(arg, segs, nseg, mapsize, error)
-	void			*arg;
-	bus_dma_segment_t	*segs;
-	int			nseg;
-	bus_size_t		mapsize;
-	int			error;
-{
-	struct vge_dmaload_arg	*ctx;
-	struct vge_tx_desc	*d = NULL;
-	struct vge_tx_frag	*f;
-	int			i = 0;
-
-	if (error)
-		return;
-
-	ctx = arg;
-
-	/* Signal error to caller if there's too many segments */
-	if (nseg > ctx->vge_maxsegs) {
-		ctx->vge_maxsegs = 0;
-		return;
-	}
-
-	/* Map the segment array into descriptors. */
-
-	d = &ctx->sc->vge_ldata.vge_tx_list[ctx->vge_idx];
-
-	/* If this descriptor is still owned by the chip, bail. */
-
-	if (le32toh(d->vge_sts) & VGE_TDSTS_OWN) {
-		ctx->vge_maxsegs = 0;
-		return;
-	}
-
-	for (i = 0; i < nseg; i++) {
-		f = &d->vge_frag[i];
-		f->vge_buflen = htole16(VGE_BUFLEN(segs[i].ds_len));
-		f->vge_addrlo = htole32(VGE_ADDR_LO(segs[i].ds_addr));
-		f->vge_addrhi = htole16(VGE_ADDR_HI(segs[i].ds_addr) & 0xFFFF);
-	}
-
-	/* Argh. This chip does not autopad short frames */
-
-	if (ctx->vge_m0->m_pkthdr.len < VGE_MIN_FRAMELEN) {
-		f = &d->vge_frag[i];
-		f->vge_buflen = htole16(VGE_BUFLEN(VGE_MIN_FRAMELEN -
-		    ctx->vge_m0->m_pkthdr.len));
-		f->vge_addrlo = htole32(VGE_ADDR_LO(segs[0].ds_addr));
-		f->vge_addrhi = htole16(VGE_ADDR_HI(segs[0].ds_addr) & 0xFFFF);
-		ctx->vge_m0->m_pkthdr.len = VGE_MIN_FRAMELEN;
-		i++;
-	}
-
-	/*
-	 * When telling the chip how many segments there are, we
-	 * must use nsegs + 1 instead of just nsegs. Darned if I
-	 * know why.
-	 */
-	i++;
-
-	d->vge_sts = ctx->vge_m0->m_pkthdr.len << 16;
-	d->vge_ctl = ctx->vge_flags|(i << 28)|VGE_TD_LS_NORM;
-
-	if (ctx->vge_m0->m_pkthdr.len > ETHERMTU + ETHER_HDR_LEN)
-		d->vge_ctl |= VGE_TDCTL_JUMBO;
-
-	ctx->vge_maxsegs = nseg;
-
-	return;
-}
-
 /*
  * Map a single buffer address.
  */
 
+struct vge_dmamap_arg {
+	bus_addr_t	vge_busaddr;
+};
+
 static void
-vge_dma_map_addr(arg, segs, nseg, error)
+vge_dmamap_cb(arg, segs, nsegs, error)
 	void			*arg;
 	bus_dma_segment_t	*segs;
-	int			nseg;
+	int			nsegs;
 	int			error;
 {
-	bus_addr_t		*addr;
+	struct vge_dmamap_arg	*ctx;
 
-	if (error)
+	if (error != 0)
 		return;
 
-	KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg));
-	addr = arg;
-	*addr = segs->ds_addr;
+	KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
 
-	return;
+	ctx = (struct vge_dmamap_arg *)arg;
+	ctx->vge_busaddr = segs[0].ds_addr;
 }
 
 static int
-vge_allocmem(dev, sc)
-	device_t		dev;
-	struct vge_softc		*sc;
+vge_dma_alloc(sc)
+	struct vge_softc	*sc;
 {
-	int			error;
-	int			nseg;
+	struct vge_dmamap_arg	ctx;
+	struct vge_txdesc	*txd;
+	struct vge_rxdesc	*rxd;
+	bus_addr_t		lowaddr, tx_ring_end, rx_ring_end;
+	int			error, i;
+
+	lowaddr = BUS_SPACE_MAXADDR;
+
+again:
+	/* Create parent ring tag. */
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->vge_dev),/* parent */
+	    1, 0,			/* algnmnt, boundary */
+	    lowaddr,			/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
+	    0,				/* nsegments */
+	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->vge_cdata.vge_ring_tag);
+	if (error != 0) {
+		device_printf(sc->vge_dev,
+		    "could not create parent DMA tag.\n");
+		goto fail;
+	}
+
+	/* Create tag for Tx ring. */
+	error = bus_dma_tag_create(sc->vge_cdata.vge_ring_tag,/* parent */
+	    VGE_TX_RING_ALIGN, 0,	/* algnmnt, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    VGE_TX_LIST_SZ,		/* maxsize */
+	    1,				/* nsegments */
+	    VGE_TX_LIST_SZ,		/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->vge_cdata.vge_tx_ring_tag);
+	if (error != 0) {
+		device_printf(sc->vge_dev,
+		    "could not allocate Tx ring DMA tag.\n");
+		goto fail;
+	}
+
+	/* Create tag for Rx ring. */
+	error = bus_dma_tag_create(sc->vge_cdata.vge_ring_tag,/* parent */
+	    VGE_RX_RING_ALIGN, 0,	/* algnmnt, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    VGE_RX_LIST_SZ,		/* maxsize */
+	    1,				/* nsegments */
+	    VGE_RX_LIST_SZ,		/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->vge_cdata.vge_rx_ring_tag);
+	if (error != 0) {
+		device_printf(sc->vge_dev,
+		    "could not allocate Rx ring DMA tag.\n");
+		goto fail;
+	}
+
+	/* Allocate DMA'able memory and load the DMA map for Tx ring. */
+	error = bus_dmamem_alloc(sc->vge_cdata.vge_tx_ring_tag,
+	    (void **)&sc->vge_rdata.vge_tx_ring,
+	    BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_COHERENT,
+	    &sc->vge_cdata.vge_tx_ring_map);
+	if (error != 0) {
+		device_printf(sc->vge_dev,
+		    "could not allocate DMA'able memory for Tx ring.\n");
+		goto fail;
+	}
+
+	ctx.vge_busaddr = 0;
+	error = bus_dmamap_load(sc->vge_cdata.vge_tx_ring_tag,
+	    sc->vge_cdata.vge_tx_ring_map, sc->vge_rdata.vge_tx_ring,
+	    VGE_TX_LIST_SZ, vge_dmamap_cb, &ctx, BUS_DMA_NOWAIT);
+	if (error != 0 || ctx.vge_busaddr == 0) {
+		device_printf(sc->vge_dev,
+		    "could not load DMA'able memory for Tx ring.\n");
+		goto fail;
+	}
+	sc->vge_rdata.vge_tx_ring_paddr = ctx.vge_busaddr;
+
+	/* Allocate DMA'able memory and load the DMA map for Rx ring. */
+	error = bus_dmamem_alloc(sc->vge_cdata.vge_rx_ring_tag,
+	    (void **)&sc->vge_rdata.vge_rx_ring,
+	    BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_COHERENT,
+	    &sc->vge_cdata.vge_rx_ring_map);
+	if (error != 0) {
+		device_printf(sc->vge_dev,
+		    "could not allocate DMA'able memory for Rx ring.\n");
+		goto fail;
+	}
+
+	ctx.vge_busaddr = 0;
+	error = bus_dmamap_load(sc->vge_cdata.vge_rx_ring_tag,
+	    sc->vge_cdata.vge_rx_ring_map, sc->vge_rdata.vge_rx_ring,
+	    VGE_RX_LIST_SZ, vge_dmamap_cb, &ctx, BUS_DMA_NOWAIT);
+	if (error != 0 || ctx.vge_busaddr == 0) {
+		device_printf(sc->vge_dev,
+		    "could not load DMA'able memory for Rx ring.\n");
+		goto fail;
+	}
+	sc->vge_rdata.vge_rx_ring_paddr = ctx.vge_busaddr;
+
+	/* Tx/Rx descriptor queue should reside within 4GB boundary. */
+	tx_ring_end = sc->vge_rdata.vge_tx_ring_paddr + VGE_TX_LIST_SZ;
+	rx_ring_end = sc->vge_rdata.vge_rx_ring_paddr + VGE_RX_LIST_SZ;
+	if ((VGE_ADDR_HI(tx_ring_end) !=
+	    VGE_ADDR_HI(sc->vge_rdata.vge_tx_ring_paddr)) ||
+	    (VGE_ADDR_HI(rx_ring_end) !=
+	    VGE_ADDR_HI(sc->vge_rdata.vge_rx_ring_paddr)) ||
+	    VGE_ADDR_HI(tx_ring_end) != VGE_ADDR_HI(rx_ring_end)) {
+		device_printf(sc->vge_dev, "4GB boundary crossed, "
+		    "switching to 32bit DMA address mode.\n");
+		vge_dma_free(sc);
+		/* Limit DMA address space to 32bit and try again. */
+		lowaddr = BUS_SPACE_MAXADDR_32BIT;
+		goto again;
+	}
+
+	/* Create parent buffer tag. */
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->vge_dev),/* parent */
+	    1, 0,			/* algnmnt, boundary */
+	    VGE_BUF_DMA_MAXADDR,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
+	    0,				/* nsegments */
+	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->vge_cdata.vge_buffer_tag);
+	if (error != 0) {
+		device_printf(sc->vge_dev,
+		    "could not create parent buffer DMA tag.\n");
+		goto fail;
+	}
+
+	/* Create tag for Tx buffers. */
+	error = bus_dma_tag_create(sc->vge_cdata.vge_buffer_tag,/* parent */
+	    1, 0,			/* algnmnt, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    MCLBYTES * VGE_MAXTXSEGS,	/* maxsize */
+	    VGE_MAXTXSEGS,		/* nsegments */
+	    MCLBYTES,			/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->vge_cdata.vge_tx_tag);
+	if (error != 0) {
+		device_printf(sc->vge_dev, "could not create Tx DMA tag.\n");
+		goto fail;
+	}
+
+	/* Create tag for Rx buffers. */
+	error = bus_dma_tag_create(sc->vge_cdata.vge_buffer_tag,/* parent */
+	    VGE_RX_BUF_ALIGN, 0,	/* algnmnt, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    MCLBYTES,			/* maxsize */
+	    1,				/* nsegments */
+	    MCLBYTES,			/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->vge_cdata.vge_rx_tag);
+	if (error != 0) {
+		device_printf(sc->vge_dev, "could not create Rx DMA tag.\n");
+		goto fail;
+	}
+
+	/* Create DMA maps for Tx buffers. */
+	for (i = 0; i < VGE_TX_DESC_CNT; i++) {
+		txd = &sc->vge_cdata.vge_txdesc[i];
+		txd->tx_m = NULL;
+		txd->tx_dmamap = NULL;
+		error = bus_dmamap_create(sc->vge_cdata.vge_tx_tag, 0,
+		    &txd->tx_dmamap);
+		if (error != 0) {
+			device_printf(sc->vge_dev,
+			    "could not create Tx dmamap.\n");
+			goto fail;
+		}
+	}
+	/* Create DMA maps for Rx buffers. */
+	if ((error = bus_dmamap_create(sc->vge_cdata.vge_rx_tag, 0,
+	    &sc->vge_cdata.vge_rx_sparemap)) != 0) {
+		device_printf(sc->vge_dev,
+		    "could not create spare Rx dmamap.\n");
+		goto fail;
+	}
+	for (i = 0; i < VGE_RX_DESC_CNT; i++) {
+		rxd = &sc->vge_cdata.vge_rxdesc[i];
+		rxd->rx_m = NULL;
+		rxd->rx_dmamap = NULL;
+		error = bus_dmamap_create(sc->vge_cdata.vge_rx_tag, 0,
+		    &rxd->rx_dmamap);
+		if (error != 0) {
+			device_printf(sc->vge_dev,
+			    "could not create Rx dmamap.\n");
+			goto fail;
+		}
+	}
+
+fail:
+	return (error);
+}
+
+static void
+vge_dma_free(sc)
+	struct vge_softc	*sc;
+{
+	struct vge_txdesc	*txd;
+	struct vge_rxdesc	*rxd;
 	int			i;
 
-	/*
-	 * Allocate map for RX mbufs.
-	 */
-	nseg = 32;
-	error = bus_dma_tag_create(sc->vge_parent_tag, ETHER_ALIGN, 0,
-	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
-	    NULL, MCLBYTES * nseg, nseg, MCLBYTES, BUS_DMA_ALLOCNOW,
-	    NULL, NULL, &sc->vge_ldata.vge_mtag);
-	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
-		return (ENOMEM);
+	/* Tx ring. */
+	if (sc->vge_cdata.vge_tx_ring_tag != NULL) {
+		if (sc->vge_cdata.vge_tx_ring_map)
+			bus_dmamap_unload(sc->vge_cdata.vge_tx_ring_tag,
+			    sc->vge_cdata.vge_tx_ring_map);
+		if (sc->vge_cdata.vge_tx_ring_map &&
+		    sc->vge_rdata.vge_tx_ring)
+			bus_dmamem_free(sc->vge_cdata.vge_tx_ring_tag,
+			    sc->vge_rdata.vge_tx_ring,
+			    sc->vge_cdata.vge_tx_ring_map);
+		sc->vge_rdata.vge_tx_ring = NULL;
+		sc->vge_cdata.vge_tx_ring_map = NULL;
+		bus_dma_tag_destroy(sc->vge_cdata.vge_tx_ring_tag);
+		sc->vge_cdata.vge_tx_ring_tag = NULL;
 	}
-
-	/*
-	 * Allocate map for TX descriptor list.
-	 */
-	error = bus_dma_tag_create(sc->vge_parent_tag, VGE_RING_ALIGN,
-	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
-	    NULL, VGE_TX_LIST_SZ, 1, VGE_TX_LIST_SZ, BUS_DMA_ALLOCNOW,
-	    NULL, NULL, &sc->vge_ldata.vge_tx_list_tag);
-	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
-		return (ENOMEM);
+	/* Rx ring. */
+	if (sc->vge_cdata.vge_rx_ring_tag != NULL) {
+		if (sc->vge_cdata.vge_rx_ring_map)
+			bus_dmamap_unload(sc->vge_cdata.vge_rx_ring_tag,
+			    sc->vge_cdata.vge_rx_ring_map);
+		if (sc->vge_cdata.vge_rx_ring_map &&
+		    sc->vge_rdata.vge_rx_ring)
+			bus_dmamem_free(sc->vge_cdata.vge_rx_ring_tag,
+			    sc->vge_rdata.vge_rx_ring,
+			    sc->vge_cdata.vge_rx_ring_map);
+		sc->vge_rdata.vge_rx_ring = NULL;
+		sc->vge_cdata.vge_rx_ring_map = NULL;
+		bus_dma_tag_destroy(sc->vge_cdata.vge_rx_ring_tag);
+		sc->vge_cdata.vge_rx_ring_tag = NULL;
 	}
-
-	/* Allocate DMA'able memory for the TX ring */
-
-	error = bus_dmamem_alloc(sc->vge_ldata.vge_tx_list_tag,
-	    (void **)&sc->vge_ldata.vge_tx_list, BUS_DMA_NOWAIT | BUS_DMA_ZERO,
-	    &sc->vge_ldata.vge_tx_list_map);
-	if (error)
-		return (ENOMEM);
-
-	/* Load the map for the TX ring. */
-
-	error = bus_dmamap_load(sc->vge_ldata.vge_tx_list_tag,
-	     sc->vge_ldata.vge_tx_list_map, sc->vge_ldata.vge_tx_list,
-	     VGE_TX_LIST_SZ, vge_dma_map_addr,
-	     &sc->vge_ldata.vge_tx_list_addr, BUS_DMA_NOWAIT);
-
-	/* Create DMA maps for TX buffers */
-
-	for (i = 0; i < VGE_TX_DESC_CNT; i++) {
-		error = bus_dmamap_create(sc->vge_ldata.vge_mtag, 0,
-			    &sc->vge_ldata.vge_tx_dmamap[i]);
-		if (error) {
-			device_printf(dev, "can't create DMA map for TX\n");
-			return (ENOMEM);
+	/* Tx buffers. */
+	if (sc->vge_cdata.vge_tx_tag != NULL) {
+		for (i = 0; i < VGE_TX_DESC_CNT; i++) {
+			txd = &sc->vge_cdata.vge_txdesc[i];
+			if (txd->tx_dmamap != NULL) {
+				bus_dmamap_destroy(sc->vge_cdata.vge_tx_tag,
+				    txd->tx_dmamap);
+				txd->tx_dmamap = NULL;
+			}
 		}
+		bus_dma_tag_destroy(sc->vge_cdata.vge_tx_tag);
+		sc->vge_cdata.vge_tx_tag = NULL;
 	}
-
-	/*
-	 * Allocate map for RX descriptor list.
-	 */
-	error = bus_dma_tag_create(sc->vge_parent_tag, VGE_RING_ALIGN,
-	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
-	    NULL, VGE_TX_LIST_SZ, 1, VGE_TX_LIST_SZ, BUS_DMA_ALLOCNOW,
-	    NULL, NULL, &sc->vge_ldata.vge_rx_list_tag);
-	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
-		return (ENOMEM);
-	}
-
-	/* Allocate DMA'able memory for the RX ring */
-
-	error = bus_dmamem_alloc(sc->vge_ldata.vge_rx_list_tag,
-	    (void **)&sc->vge_ldata.vge_rx_list, BUS_DMA_NOWAIT | BUS_DMA_ZERO,
-	    &sc->vge_ldata.vge_rx_list_map);
-	if (error)
-		return (ENOMEM);
-
-	/* Load the map for the RX ring. */
-
-	error = bus_dmamap_load(sc->vge_ldata.vge_rx_list_tag,
-	     sc->vge_ldata.vge_rx_list_map, sc->vge_ldata.vge_rx_list,
-	     VGE_TX_LIST_SZ, vge_dma_map_addr,
-	     &sc->vge_ldata.vge_rx_list_addr, BUS_DMA_NOWAIT);
-
-	/* Create DMA maps for RX buffers */
-
-	for (i = 0; i < VGE_RX_DESC_CNT; i++) {
-		error = bus_dmamap_create(sc->vge_ldata.vge_mtag, 0,
-			    &sc->vge_ldata.vge_rx_dmamap[i]);
-		if (error) {
-			device_printf(dev, "can't create DMA map for RX\n");
-			return (ENOMEM);
+	/* Rx buffers. */
+	if (sc->vge_cdata.vge_rx_tag != NULL) {
+		for (i = 0; i < VGE_RX_DESC_CNT; i++) {
+			rxd = &sc->vge_cdata.vge_rxdesc[i];
+			if (rxd->rx_dmamap != NULL) {
+				bus_dmamap_destroy(sc->vge_cdata.vge_rx_tag,
+				    rxd->rx_dmamap);
+				rxd->rx_dmamap = NULL;
+			}
 		}
+		if (sc->vge_cdata.vge_rx_sparemap != NULL) {
+			bus_dmamap_destroy(sc->vge_cdata.vge_rx_tag,
+			    sc->vge_cdata.vge_rx_sparemap);
+			sc->vge_cdata.vge_rx_sparemap = NULL;
+		}
+		bus_dma_tag_destroy(sc->vge_cdata.vge_rx_tag);
+		sc->vge_cdata.vge_rx_tag = NULL;
 	}
 
-	return (0);
+	if (sc->vge_cdata.vge_buffer_tag != NULL) {
+		bus_dma_tag_destroy(sc->vge_cdata.vge_buffer_tag);
+		sc->vge_cdata.vge_buffer_tag = NULL;
+	}
+	if (sc->vge_cdata.vge_ring_tag != NULL) {
+		bus_dma_tag_destroy(sc->vge_cdata.vge_ring_tag);
+		sc->vge_cdata.vge_ring_tag = NULL;
+	}
 }
 
 /*
@@ -961,25 +1039,7 @@ vge_attach(dev)
 	 */
 	vge_read_eeprom(sc, (caddr_t)eaddr, VGE_EE_EADDR, 3, 0);
 
-	/*
-	 * Allocate the parent bus DMA tag appropriate for PCI.
-	 */
-#define VGE_NSEG_NEW 32
-	error = bus_dma_tag_create(NULL,	/* parent */
-			1, 0,			/* alignment, boundary */
-			BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
-			BUS_SPACE_MAXADDR,	/* highaddr */
-			NULL, NULL,		/* filter, filterarg */
-			MAXBSIZE, VGE_NSEG_NEW,	/* maxsize, nsegments */
-			BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
-			BUS_DMA_ALLOCNOW,	/* flags */
-			NULL, NULL,		/* lockfunc, lockarg */
-			&sc->vge_parent_tag);
-	if (error)
-		goto fail;
-
-	error = vge_allocmem(dev, sc);
-
+	error = vge_dma_alloc(sc);
 	if (error)
 		goto fail;
 
@@ -1051,7 +1111,6 @@ vge_detach(dev)
 {
 	struct vge_softc		*sc;
 	struct ifnet		*ifp;
-	int			i;
 
 	sc = device_get_softc(dev);
 	KASSERT(mtx_initialized(&sc->vge_mtx), ("vge mutex not initialized"));
@@ -1084,97 +1143,93 @@ vge_detach(dev)
 	if (ifp)
 		if_free(ifp);
 
-	/* Unload and free the RX DMA ring memory and map */
-
-	if (sc->vge_ldata.vge_rx_list_tag) {
-		bus_dmamap_unload(sc->vge_ldata.vge_rx_list_tag,
-		    sc->vge_ldata.vge_rx_list_map);
-		bus_dmamem_free(sc->vge_ldata.vge_rx_list_tag,
-		    sc->vge_ldata.vge_rx_list,
-		    sc->vge_ldata.vge_rx_list_map);
-		bus_dma_tag_destroy(sc->vge_ldata.vge_rx_list_tag);
-	}
-
-	/* Unload and free the TX DMA ring memory and map */
-
-	if (sc->vge_ldata.vge_tx_list_tag) {
-		bus_dmamap_unload(sc->vge_ldata.vge_tx_list_tag,
-		    sc->vge_ldata.vge_tx_list_map);
-		bus_dmamem_free(sc->vge_ldata.vge_tx_list_tag,
-		    sc->vge_ldata.vge_tx_list,
-		    sc->vge_ldata.vge_tx_list_map);
-		bus_dma_tag_destroy(sc->vge_ldata.vge_tx_list_tag);
-	}
-
-	/* Destroy all the RX and TX buffer maps */
-
-	if (sc->vge_ldata.vge_mtag) {
-		for (i = 0; i < VGE_TX_DESC_CNT; i++)
-			bus_dmamap_destroy(sc->vge_ldata.vge_mtag,
-			    sc->vge_ldata.vge_tx_dmamap[i]);
-		for (i = 0; i < VGE_RX_DESC_CNT; i++)
-			bus_dmamap_destroy(sc->vge_ldata.vge_mtag,
-			    sc->vge_ldata.vge_rx_dmamap[i]);
-		bus_dma_tag_destroy(sc->vge_ldata.vge_mtag);
-	}
-
-	if (sc->vge_parent_tag)
-		bus_dma_tag_destroy(sc->vge_parent_tag);
-
+	vge_dma_free(sc);
 	mtx_destroy(&sc->vge_mtx);
 
 	return (0);
 }
 
-static int
-vge_newbuf(sc, idx, m)
+static void
+vge_discard_rxbuf(sc, prod)
 	struct vge_softc	*sc;
-	int			idx;
-	struct mbuf		*m;
+	int			prod;
 {
-	struct vge_dmaload_arg	arg;
-	struct mbuf		*n = NULL;
-	int			i, error;
+	struct vge_rxdesc	*rxd;
+	int			i;
 
-	if (m == NULL) {
-		n = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-		if (n == NULL)
-			return (ENOBUFS);
-		m = n;
-	} else
-		m->m_data = m->m_ext.ext_buf;
+	rxd = &sc->vge_cdata.vge_rxdesc[prod];
+	rxd->rx_desc->vge_sts = 0;
+	rxd->rx_desc->vge_ctl = 0;
 
-
-#ifdef VGE_FIXUP_RX
 	/*
-	 * This is part of an evil trick to deal with non-x86 platforms.
-	 * The VIA chip requires RX buffers to be aligned on 32-bit
-	 * boundaries, but that will hose non-x86 machines. To get around
-	 * this, we leave some empty space at the start of each buffer
-	 * and for non-x86 hosts, we copy the buffer back two bytes
-	 * to achieve word alignment. This is slightly more efficient
-	 * than allocating a new buffer, copying the contents, and
-	 * discarding the old buffer.
+	 * Note: the manual fails to document the fact that for
+	 * proper opration, the driver needs to replentish the RX
+	 * DMA ring 4 descriptors at a time (rather than one at a
+	 * time, like most chips). We can allocate the new buffers
+	 * but we should not set the OWN bits until we're ready
+	 * to hand back 4 of them in one shot.
 	 */
-	m->m_len = m->m_pkthdr.len = MCLBYTES - VGE_ETHER_ALIGN;
-	m_adj(m, VGE_ETHER_ALIGN);
-#else
-	m->m_len = m->m_pkthdr.len = MCLBYTES;
-#endif
-
-	arg.sc = sc;
-	arg.vge_idx = idx;
-	arg.vge_maxsegs = 1;
-	arg.vge_flags = 0;
-
-	error = bus_dmamap_load_mbuf(sc->vge_ldata.vge_mtag,
-	    sc->vge_ldata.vge_rx_dmamap[idx], m, vge_dma_map_rx_desc,
-	    &arg, BUS_DMA_NOWAIT);
-	if (error || arg.vge_maxsegs != 1) {
-		if (n != NULL)
-			m_freem(n);
-		return (ENOMEM);
+	if ((prod % VGE_RXCHUNK) == (VGE_RXCHUNK - 1)) {
+		for (i = VGE_RXCHUNK; i > 0; i--) {
+			rxd->rx_desc->vge_sts = htole32(VGE_RDSTS_OWN);
+			rxd = rxd->rxd_prev;
+		}
+		sc->vge_cdata.vge_rx_commit += VGE_RXCHUNK;
 	}
+}
+
+static int
+vge_newbuf(sc, prod)
+	struct vge_softc	*sc;
+	int			prod;
+{
+	struct vge_rxdesc	*rxd;
+	struct mbuf		*m;
+	bus_dma_segment_t	segs[1];
+	bus_dmamap_t		map;
+	int			i, nsegs;
+
+	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+	if (m == NULL)
+		return (ENOBUFS);
+	/*
+	 * This is part of an evil trick to deal with strict-alignment
+	 * architectures. The VIA chip requires RX buffers to be aligned
+	 * on 32-bit boundaries, but that will hose strict-alignment
+	 * architectures. To get around this, we leave some empty space
+	 * at the start of each buffer and for non-strict-alignment hosts,
+	 * we copy the buffer back two bytes to achieve word alignment.
+	 * This is slightly more efficient than allocating a new buffer,
+	 * copying the contents, and discarding the old buffer.
+	 */
+	m->m_len = m->m_pkthdr.len = MCLBYTES;
+	m_adj(m, VGE_RX_BUF_ALIGN);
+
+	if (bus_dmamap_load_mbuf_sg(sc->vge_cdata.vge_rx_tag,
+	    sc->vge_cdata.vge_rx_sparemap, m, segs, &nsegs, 0) != 0) {
+		m_freem(m);
+		return (ENOBUFS);
+	}
+	KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
+
+	rxd = &sc->vge_cdata.vge_rxdesc[prod];
+	if (rxd->rx_m != NULL) {
+		bus_dmamap_sync(sc->vge_cdata.vge_rx_tag, rxd->rx_dmamap,
+		    BUS_DMASYNC_POSTREAD);
+		bus_dmamap_unload(sc->vge_cdata.vge_rx_tag, rxd->rx_dmamap);
+	}
+	map = rxd->rx_dmamap;
+	rxd->rx_dmamap = sc->vge_cdata.vge_rx_sparemap;
+	sc->vge_cdata.vge_rx_sparemap = map;
+	bus_dmamap_sync(sc->vge_cdata.vge_rx_tag, rxd->rx_dmamap,
+	    BUS_DMASYNC_PREREAD);
+	rxd->rx_m = m;
+
+	rxd->rx_desc->vge_sts = 0;
+	rxd->rx_desc->vge_ctl = 0;
+	rxd->rx_desc->vge_addrlo = htole32(VGE_ADDR_LO(segs[0].ds_addr));
+	rxd->rx_desc->vge_addrhi = htole32(VGE_ADDR_HI(segs[0].ds_addr) |
+	    (VGE_BUFLEN(segs[0].ds_len) << 16) | VGE_RXDESC_I);
 
 	/*
 	 * Note: the manual fails to document the fact that for
@@ -1184,73 +1239,127 @@ vge_newbuf(sc, idx, m)
 	 * but we should not set the OWN bits until we're ready
 	 * to hand back 4 of them in one shot.
 	 */
-
-#define VGE_RXCHUNK 4
-	sc->vge_rx_consumed++;
-	if (sc->vge_rx_consumed == VGE_RXCHUNK) {
-		for (i = idx; i != idx - sc->vge_rx_consumed; i--)
-			sc->vge_ldata.vge_rx_list[i].vge_sts |=
-			    htole32(VGE_RDSTS_OWN);
-		sc->vge_rx_consumed = 0;
+	if ((prod % VGE_RXCHUNK) == (VGE_RXCHUNK - 1)) {
+		for (i = VGE_RXCHUNK; i > 0; i--) {
+			rxd->rx_desc->vge_sts = htole32(VGE_RDSTS_OWN);
+			rxd = rxd->rxd_prev;
+		}
+		sc->vge_cdata.vge_rx_commit += VGE_RXCHUNK;
 	}
 
-	sc->vge_ldata.vge_rx_mbuf[idx] = m;
-
-	bus_dmamap_sync(sc->vge_ldata.vge_mtag,
-	    sc->vge_ldata.vge_rx_dmamap[idx],
-	    BUS_DMASYNC_PREREAD);
-
 	return (0);
 }
 
 static int
 vge_tx_list_init(sc)
-	struct vge_softc		*sc;
+	struct vge_softc	*sc;
 {
-	bzero ((char *)sc->vge_ldata.vge_tx_list, VGE_TX_LIST_SZ);
-	bzero ((char *)&sc->vge_ldata.vge_tx_mbuf,
-	    (VGE_TX_DESC_CNT * sizeof(struct mbuf *)));
+	struct vge_ring_data	*rd;
+	struct vge_txdesc	*txd;
+	int			i;
 
-	bus_dmamap_sync(sc->vge_ldata.vge_tx_list_tag,
-	    sc->vge_ldata.vge_tx_list_map, BUS_DMASYNC_PREWRITE);
-	sc->vge_ldata.vge_tx_prodidx = 0;
-	sc->vge_ldata.vge_tx_considx = 0;
-	sc->vge_ldata.vge_tx_free = VGE_TX_DESC_CNT;
+	VGE_LOCK_ASSERT(sc);
+
+	sc->vge_cdata.vge_tx_prodidx = 0;
+	sc->vge_cdata.vge_tx_considx = 0;
+	sc->vge_cdata.vge_tx_cnt = 0;
+
+	rd = &sc->vge_rdata;
+	bzero(rd->vge_tx_ring, VGE_TX_LIST_SZ);
+	for (i = 0; i < VGE_TX_DESC_CNT; i++) {
+		txd = &sc->vge_cdata.vge_txdesc[i];
+		txd->tx_m = NULL;
+		txd->tx_desc = &rd->vge_tx_ring[i];
+	}
+
+	bus_dmamap_sync(sc->vge_cdata.vge_tx_ring_tag,
+	    sc->vge_cdata.vge_tx_ring_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	return (0);
 }
 
 static int
 vge_rx_list_init(sc)
-	struct vge_softc		*sc;
+	struct vge_softc	*sc;
 {
+	struct vge_ring_data	*rd;
+	struct vge_rxdesc	*rxd;
 	int			i;
 
-	bzero ((char *)sc->vge_ldata.vge_rx_list, VGE_RX_LIST_SZ);
-	bzero ((char *)&sc->vge_ldata.vge_rx_mbuf,
-	    (VGE_RX_DESC_CNT * sizeof(struct mbuf *)));
+	VGE_LOCK_ASSERT(sc);
 
-	sc->vge_rx_consumed = 0;
+	sc->vge_cdata.vge_rx_prodidx = 0;
+	sc->vge_cdata.vge_head = NULL;
+	sc->vge_cdata.vge_tail = NULL;
+	sc->vge_cdata.vge_rx_commit = 0;
 
+	rd = &sc->vge_rdata;
+	bzero(rd->vge_rx_ring, VGE_RX_LIST_SZ);
 	for (i = 0; i < VGE_RX_DESC_CNT; i++) {
-		if (vge_newbuf(sc, i, NULL) == ENOBUFS)
+		rxd = &sc->vge_cdata.vge_rxdesc[i];
+		rxd->rx_m = NULL;
+		rxd->rx_desc = &rd->vge_rx_ring[i];
+		if (i == 0)
+			rxd->rxd_prev =
+			    &sc->vge_cdata.vge_rxdesc[VGE_RX_DESC_CNT - 1];
+		else
+			rxd->rxd_prev = &sc->vge_cdata.vge_rxdesc[i - 1];
+		if (vge_newbuf(sc, i) != 0)
 			return (ENOBUFS);
 	}
 
-	/* Flush the RX descriptors */
+	bus_dmamap_sync(sc->vge_cdata.vge_rx_ring_tag,
+	    sc->vge_cdata.vge_rx_ring_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
-	bus_dmamap_sync(sc->vge_ldata.vge_rx_list_tag,
-	    sc->vge_ldata.vge_rx_list_map,
-	    BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
-
-	sc->vge_ldata.vge_rx_prodidx = 0;
-	sc->vge_rx_consumed = 0;
-	sc->vge_head = sc->vge_tail = NULL;
+	sc->vge_cdata.vge_rx_commit = 0;
 
 	return (0);
 }
 
-#ifdef VGE_FIXUP_RX
+static void
+vge_freebufs(sc)
+	struct vge_softc	*sc;
+{
+	struct vge_txdesc	*txd;
+	struct vge_rxdesc	*rxd;
+	struct ifnet		*ifp;
+	int			i;
+
+	VGE_LOCK_ASSERT(sc);
+
+	ifp = sc->vge_ifp;
+	/*
+	 * Free RX and TX mbufs still in the queues.
+	 */
+	for (i = 0; i < VGE_RX_DESC_CNT; i++) {
+		rxd = &sc->vge_cdata.vge_rxdesc[i];
+		if (rxd->rx_m != NULL) {
+			bus_dmamap_sync(sc->vge_cdata.vge_rx_tag,
+			    rxd->rx_dmamap, BUS_DMASYNC_POSTREAD);
+			bus_dmamap_unload(sc->vge_cdata.vge_rx_tag,
+			    rxd->rx_dmamap);
+			m_freem(rxd->rx_m);
+			rxd->rx_m = NULL;
+		}
+	}
+
+	for (i = 0; i < VGE_TX_DESC_CNT; i++) {
+		txd = &sc->vge_cdata.vge_txdesc[i];
+		if (txd->tx_m != NULL) {
+			bus_dmamap_sync(sc->vge_cdata.vge_tx_tag,
+			    txd->tx_dmamap, BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(sc->vge_cdata.vge_tx_tag,
+			    txd->tx_dmamap);
+			m_freem(txd->tx_m);
+			txd->tx_m = NULL;
+			ifp->if_oerrors++;
+		}
+	}
+}
+
+#ifndef	__NO_STRICT_ALIGNMENT
 static __inline void
 vge_fixup_rx(m)
 	struct mbuf		*m;
@@ -1265,8 +1374,6 @@ vge_fixup_rx(m)
 		*dst++ = *src++;
 
 	m->m_data -= ETHER_ALIGN;
-
-	return;
 }
 #endif
 
@@ -1275,49 +1382,39 @@ vge_fixup_rx(m)
  * been fragmented across multiple 2K mbuf cluster buffers.
  */
 static int
-vge_rxeof(sc)
+vge_rxeof(sc, count)
 	struct vge_softc	*sc;
+	int			count;
 {
 	struct mbuf		*m;
 	struct ifnet		*ifp;
-	int			i, total_len;
-	int			lim = 0;
+	int			prod, prog, total_len;
+	struct vge_rxdesc	*rxd;
 	struct vge_rx_desc	*cur_rx;
-	u_int32_t		rxstat, rxctl;
+	uint32_t		rxstat, rxctl;
 
 	VGE_LOCK_ASSERT(sc);
+
 	ifp = sc->vge_ifp;
-	i = sc->vge_ldata.vge_rx_prodidx;
 
-	/* Invalidate the descriptor memory */
+	bus_dmamap_sync(sc->vge_cdata.vge_rx_ring_tag,
+	    sc->vge_cdata.vge_rx_ring_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
-	bus_dmamap_sync(sc->vge_ldata.vge_rx_list_tag,
-	    sc->vge_ldata.vge_rx_list_map,
-	    BUS_DMASYNC_POSTREAD);
-
-	while (!VGE_OWN(&sc->vge_ldata.vge_rx_list[i])) {
-
-#ifdef DEVICE_POLLING
-		if (ifp->if_capenable & IFCAP_POLLING) {
-			if (sc->rxcycles <= 0)
-				break;
-			sc->rxcycles--;
-		}
-#endif
-
-		cur_rx = &sc->vge_ldata.vge_rx_list[i];
-		m = sc->vge_ldata.vge_rx_mbuf[i];
-		total_len = VGE_RXBYTES(cur_rx);
+	prod = sc->vge_cdata.vge_rx_prodidx;
+	for (prog = 0; count > 0 &&
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0;
+	    VGE_RX_DESC_INC(prod)) {
+		cur_rx = &sc->vge_rdata.vge_rx_ring[prod];
 		rxstat = le32toh(cur_rx->vge_sts);
+		if ((rxstat & VGE_RDSTS_OWN) != 0)
+			break;
+		count--;
+		prog++;
 		rxctl = le32toh(cur_rx->vge_ctl);
-
-		/* Invalidate the RX mbuf and unload its map */
-
-		bus_dmamap_sync(sc->vge_ldata.vge_mtag,
-		    sc->vge_ldata.vge_rx_dmamap[i],
-		    BUS_DMASYNC_POSTWRITE);
-		bus_dmamap_unload(sc->vge_ldata.vge_mtag,
-		    sc->vge_ldata.vge_rx_dmamap[i]);
+		total_len = VGE_RXBYTES(rxstat);
+		rxd = &sc->vge_cdata.vge_rxdesc[prod];
+		m = rxd->rx_m;
 
 		/*
 		 * If the 'start of frame' bit is set, this indicates
@@ -1325,17 +1422,22 @@ vge_rxeof(sc)
 		 * or an intermediate fragment. Either way, we want to
 		 * accumulate the buffers.
 		 */
-		if (rxstat & VGE_RXPKT_SOF) {
-			m->m_len = MCLBYTES - VGE_ETHER_ALIGN;
-			if (sc->vge_head == NULL)
-				sc->vge_head = sc->vge_tail = m;
-			else {
-				m->m_flags &= ~M_PKTHDR;
-				sc->vge_tail->m_next = m;
-				sc->vge_tail = m;
+		if ((rxstat & VGE_RXPKT_SOF) != 0) {
+			if (vge_newbuf(sc, prod) != 0) {
+				ifp->if_iqdrops++;
+				VGE_CHAIN_RESET(sc);
+				vge_discard_rxbuf(sc, prod);
+				continue;
+			}
+			m->m_len = MCLBYTES - VGE_RX_BUF_ALIGN;
+			if (sc->vge_cdata.vge_head == NULL) {
+				sc->vge_cdata.vge_head = m;
+				sc->vge_cdata.vge_tail = m;
+			} else {
+				m->m_flags &= ~M_PKTHDR;
+				sc->vge_cdata.vge_tail->m_next = m;
+				sc->vge_cdata.vge_tail = m;
 			}
-			vge_newbuf(sc, i, NULL);
-			VGE_RX_DESC_INC(i);
 			continue;
 		}
 
@@ -1347,43 +1449,32 @@ vge_rxeof(sc)
 		 * a 'VLAN CAM filter miss' and clears the 'RXOK' bit.
 		 * We don't want to drop the frame though: our VLAN
 		 * filtering is done in software.
+		 * We also want to receive bad-checksummed frames and
+		 * and frames with bad-length.
 		 */
-		if (!(rxstat & VGE_RDSTS_RXOK) && !(rxstat & VGE_RDSTS_VIDM)
-		    && !(rxstat & VGE_RDSTS_CSUMERR)) {
+		if ((rxstat & VGE_RDSTS_RXOK) == 0 &&
+		    (rxstat & (VGE_RDSTS_VIDM | VGE_RDSTS_RLERR |
+		    VGE_RDSTS_CSUMERR)) == 0) {
 			ifp->if_ierrors++;
 			/*
 			 * If this is part of a multi-fragment packet,
 			 * discard all the pieces.
 			 */
-			if (sc->vge_head != NULL) {
-				m_freem(sc->vge_head);
-				sc->vge_head = sc->vge_tail = NULL;
-			}
-			vge_newbuf(sc, i, m);
-			VGE_RX_DESC_INC(i);
+			VGE_CHAIN_RESET(sc);
+			vge_discard_rxbuf(sc, prod);
 			continue;
 		}
 
-		/*
-		 * If allocating a replacement mbuf fails,
-		 * reload the current one.
-		 */
-
-		if (vge_newbuf(sc, i, NULL)) {
-			ifp->if_ierrors++;
-			if (sc->vge_head != NULL) {
-				m_freem(sc->vge_head);
-				sc->vge_head = sc->vge_tail = NULL;
-			}
-			vge_newbuf(sc, i, m);
-			VGE_RX_DESC_INC(i);
+		if (vge_newbuf(sc, prod) != 0) {
+			ifp->if_iqdrops++;
+			VGE_CHAIN_RESET(sc);
+			vge_discard_rxbuf(sc, prod);
 			continue;
 		}
 
-		VGE_RX_DESC_INC(i);
-
-		if (sc->vge_head != NULL) {
-			m->m_len = total_len % (MCLBYTES - VGE_ETHER_ALIGN);
+		/* Chain received mbufs. */
+		if (sc->vge_cdata.vge_head != NULL) {
+			m->m_len = total_len % (MCLBYTES - VGE_RX_BUF_ALIGN);
 			/*
 			 * Special case: if there's 4 bytes or less
 			 * in this buffer, the mbuf can be discarded:
@@ -1391,46 +1482,47 @@ vge_rxeof(sc)
 			 * care about anyway.
 			 */
 			if (m->m_len <= ETHER_CRC_LEN) {
-				sc->vge_tail->m_len -=
+				sc->vge_cdata.vge_tail->m_len -=
 				    (ETHER_CRC_LEN - m->m_len);
 				m_freem(m);
 			} else {
 				m->m_len -= ETHER_CRC_LEN;
 				m->m_flags &= ~M_PKTHDR;
-				sc->vge_tail->m_next = m;
+				sc->vge_cdata.vge_tail->m_next = m;
 			}
-			m = sc->vge_head;
-			sc->vge_head = sc->vge_tail = NULL;
+			m = sc->vge_cdata.vge_head;
+			m->m_flags |= M_PKTHDR;
 			m->m_pkthdr.len = total_len - ETHER_CRC_LEN;
-		} else
+		} else {
+			m->m_flags |= M_PKTHDR;
 			m->m_pkthdr.len = m->m_len =
 			    (total_len - ETHER_CRC_LEN);
+		}
 
-#ifdef VGE_FIXUP_RX
+#ifndef	__NO_STRICT_ALIGNMENT
 		vge_fixup_rx(m);
 #endif
-		ifp->if_ipackets++;
 		m->m_pkthdr.rcvif = ifp;
 
 		/* Do RX checksumming if enabled */
-		if (ifp->if_capenable & IFCAP_RXCSUM) {
-
+		if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
+		    (rxctl & VGE_RDCTL_FRAG) == 0) {
 			/* Check IP header checksum */
-			if (rxctl & VGE_RDCTL_IPPKT)
+			if ((rxctl & VGE_RDCTL_IPPKT) != 0)
 				m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
-			if (rxctl & VGE_RDCTL_IPCSUMOK)
+			if ((rxctl & VGE_RDCTL_IPCSUMOK) != 0)
 				m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
 
 			/* Check TCP/UDP checksum */
-			if (rxctl & (VGE_RDCTL_TCPPKT|VGE_RDCTL_UDPPKT) &&
+			if (rxctl & (VGE_RDCTL_TCPPKT | VGE_RDCTL_UDPPKT) &&
 			    rxctl & VGE_RDCTL_PROTOCSUMOK) {
 				m->m_pkthdr.csum_flags |=
-				    CSUM_DATA_VALID|CSUM_PSEUDO_HDR;
+				    CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
 				m->m_pkthdr.csum_data = 0xffff;
 			}
 		}
 
-		if (rxstat & VGE_RDSTS_VTAG) {
+		if ((rxstat & VGE_RDSTS_VTAG) != 0) {
 			/*
 			 * The 32-bit rxctl register is stored in little-endian.
 			 * However, the 16-bit vlan tag is stored in big-endian,
@@ -1444,83 +1536,83 @@ vge_rxeof(sc)
 		VGE_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
 		VGE_LOCK(sc);
-
-		lim++;
-		if (lim == VGE_RX_DESC_CNT)
-			break;
-
+		sc->vge_cdata.vge_head = NULL;
+		sc->vge_cdata.vge_tail = NULL;
 	}
 
-	/* Flush the RX DMA ring */
-
-	bus_dmamap_sync(sc->vge_ldata.vge_rx_list_tag,
-	    sc->vge_ldata.vge_rx_list_map,
-	    BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
-
-	sc->vge_ldata.vge_rx_prodidx = i;
-	CSR_WRITE_2(sc, VGE_RXDESC_RESIDUECNT, lim);
-
-
-	return (lim);
+	if (prog > 0) {
+		sc->vge_cdata.vge_rx_prodidx = prod;
+		bus_dmamap_sync(sc->vge_cdata.vge_rx_ring_tag,
+		    sc->vge_cdata.vge_rx_ring_map,
+		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+		/* Update residue counter. */
+		if (sc->vge_cdata.vge_rx_commit != 0) {
+			CSR_WRITE_2(sc, VGE_RXDESC_RESIDUECNT,
+			    sc->vge_cdata.vge_rx_commit);
+			sc->vge_cdata.vge_rx_commit = 0;
+		}
+	}
+	return (prog);
 }
 
 static void
 vge_txeof(sc)
-	struct vge_softc		*sc;
+	struct vge_softc	*sc;
 {
 	struct ifnet		*ifp;
-	u_int32_t		txstat;
-	int			idx;
+	struct vge_tx_desc	*cur_tx;
+	struct vge_txdesc	*txd;
+	uint32_t		txstat;
+	int			cons, prod;
+
+	VGE_LOCK_ASSERT(sc);
 
 	ifp = sc->vge_ifp;
-	idx = sc->vge_ldata.vge_tx_considx;
 
-	/* Invalidate the TX descriptor list */
+	if (sc->vge_cdata.vge_tx_cnt == 0)
+		return;
 
-	bus_dmamap_sync(sc->vge_ldata.vge_tx_list_tag,
-	    sc->vge_ldata.vge_tx_list_map,
-	    BUS_DMASYNC_POSTREAD);
-
-	while (idx != sc->vge_ldata.vge_tx_prodidx) {
-
-		txstat = le32toh(sc->vge_ldata.vge_tx_list[idx].vge_sts);
-		if (txstat & VGE_TDSTS_OWN)
-			break;
-
-		m_freem(sc->vge_ldata.vge_tx_mbuf[idx]);
-		sc->vge_ldata.vge_tx_mbuf[idx] = NULL;
-		bus_dmamap_unload(sc->vge_ldata.vge_mtag,
-		    sc->vge_ldata.vge_tx_dmamap[idx]);
-		if (txstat & (VGE_TDSTS_EXCESSCOLL|VGE_TDSTS_COLL))
-			ifp->if_collisions++;
-		if (txstat & VGE_TDSTS_TXERR)
-			ifp->if_oerrors++;
-		else
-			ifp->if_opackets++;
-
-		sc->vge_ldata.vge_tx_free++;
-		VGE_TX_DESC_INC(idx);
-	}
-
-	/* No changes made to the TX ring, so no flush needed */
-
-	if (idx != sc->vge_ldata.vge_tx_considx) {
-		sc->vge_ldata.vge_tx_considx = idx;
-		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-		sc->vge_timer = 0;
-	}
+	bus_dmamap_sync(sc->vge_cdata.vge_tx_ring_tag,
+	    sc->vge_cdata.vge_tx_ring_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
 	/*
-	 * If not all descriptors have been released reaped yet,
-	 * reload the timer so that we will eventually get another
-	 * interrupt that will cause us to re-enter this routine.
-	 * This is done in case the transmitter has gone idle.
+	 * Go through our tx list and free mbufs for those
+	 * frames that have been transmitted.
 	 */
-	if (sc->vge_ldata.vge_tx_free != VGE_TX_DESC_CNT) {
-		CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE);
+	cons = sc->vge_cdata.vge_tx_considx;
+	prod = sc->vge_cdata.vge_tx_prodidx;
+	for (; cons != prod; VGE_TX_DESC_INC(cons)) {
+		cur_tx = &sc->vge_rdata.vge_tx_ring[cons];
+		txstat = le32toh(cur_tx->vge_sts);
+		if ((txstat & VGE_TDSTS_OWN) != 0)
+			break;
+		sc->vge_cdata.vge_tx_cnt--;
+		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+		txd = &sc->vge_cdata.vge_txdesc[cons];
+		bus_dmamap_sync(sc->vge_cdata.vge_tx_tag, txd->tx_dmamap,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(sc->vge_cdata.vge_tx_tag, txd->tx_dmamap);
+
+		KASSERT(txd->tx_m != NULL, ("%s: freeing NULL mbuf!\n",
+		    __func__));
+		m_freem(txd->tx_m);
+		txd->tx_m = NULL;
 	}
 
-	return;
+	sc->vge_cdata.vge_tx_considx = cons;
+	if (sc->vge_cdata.vge_tx_cnt == 0)
+		sc->vge_timer = 0;
+	else {
+		/*
+		 * If not all descriptors have been released reaped yet,
+		 * reload the timer so that we will eventually get another
+		 * interrupt that will cause us to re-enter this routine.
+		 * This is done in case the transmitter has gone idle.
+		 */
+		CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE);
+	}
 }
 
 static void
@@ -1568,8 +1660,7 @@ vge_poll (struct ifnet *ifp, enum poll_cmd cmd, int count)
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 		goto done;
 
-	sc->rxcycles = count;
-	rx_npkts = vge_rxeof(sc);
+	rx_npkts = vge_rxeof(sc, count);
 	vge_txeof(sc);
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
@@ -1588,11 +1679,13 @@ vge_poll (struct ifnet *ifp, enum poll_cmd cmd, int count)
 		 */
 
 		if (status & VGE_ISR_TXDMA_STALL ||
-		    status & VGE_ISR_RXDMA_STALL)
+		    status & VGE_ISR_RXDMA_STALL) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			vge_init_locked(sc);
+		}
 
 		if (status & (VGE_ISR_RXOFLOW|VGE_ISR_RXNODESC)) {
-			vge_rxeof(sc);
+			vge_rxeof(sc, count);
 			ifp->if_ierrors++;
 			CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_RUN);
 			CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_WAK);
@@ -1650,10 +1743,10 @@ vge_intr(arg)
 			break;
 
 		if (status & (VGE_ISR_RXOK|VGE_ISR_RXOK_HIPRIO))
-			vge_rxeof(sc);
+			vge_rxeof(sc, VGE_RX_DESC_CNT);
 
 		if (status & (VGE_ISR_RXOFLOW|VGE_ISR_RXNODESC)) {
-			vge_rxeof(sc);
+			vge_rxeof(sc, VGE_RX_DESC_CNT);
 			CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_RUN);
 			CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_WAK);
 		}
@@ -1661,8 +1754,10 @@ vge_intr(arg)
 		if (status & (VGE_ISR_TXOK0|VGE_ISR_TIMER0))
 			vge_txeof(sc);
 
-		if (status & (VGE_ISR_TXDMA_STALL|VGE_ISR_RXDMA_STALL))
+		if (status & (VGE_ISR_TXDMA_STALL|VGE_ISR_RXDMA_STALL)) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			vge_init_locked(sc);
+		}
 
 		if (status & VGE_ISR_LINKSTS)
 			vge_tick(sc);
@@ -1680,77 +1775,126 @@ vge_intr(arg)
 }
 
 static int
-vge_encap(sc, m_head, idx)
+vge_encap(sc, m_head)
 	struct vge_softc	*sc;
-	struct mbuf		*m_head;
-	int			idx;
+	struct mbuf		**m_head;
 {
-	struct mbuf		*m_new = NULL;
-	struct vge_dmaload_arg	arg;
-	bus_dmamap_t		map;
-	int			error;
+	struct vge_txdesc	*txd;
+	struct vge_tx_frag	*frag;
+	struct mbuf		*m;
+	bus_dma_segment_t	txsegs[VGE_MAXTXSEGS];
+	int			error, i, nsegs, padlen;
+	uint32_t		cflags;
 
-	if (sc->vge_ldata.vge_tx_free <= 2)
-		return (EFBIG);
+	VGE_LOCK_ASSERT(sc);
 
-	arg.vge_flags = 0;
+	M_ASSERTPKTHDR((*m_head));
 
-	if (m_head->m_pkthdr.csum_flags & CSUM_IP)
-		arg.vge_flags |= VGE_TDCTL_IPCSUM;
-	if (m_head->m_pkthdr.csum_flags & CSUM_TCP)
-		arg.vge_flags |= VGE_TDCTL_TCPCSUM;
-	if (m_head->m_pkthdr.csum_flags & CSUM_UDP)
-		arg.vge_flags |= VGE_TDCTL_UDPCSUM;
-
-	arg.sc = sc;
-	arg.vge_idx = idx;
-	arg.vge_m0 = m_head;
-	arg.vge_maxsegs = VGE_TX_FRAGS;
-
-	map = sc->vge_ldata.vge_tx_dmamap[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 && error != EFBIG) {
-		if_printf(sc->vge_ifp, "can't map mbuf (error %d)\n", error);
-		return (ENOBUFS);
-	}
-
-	/* Too many segments to map, coalesce into a single mbuf */
-
-	if (error || arg.vge_maxsegs == 0) {
-		m_new = m_defrag(m_head, M_DONTWAIT);
-		if (m_new == NULL)
-			return (1);
-		else
-			m_head = m_new;
-
-		arg.sc = sc;
-		arg.vge_m0 = m_head;
-		arg.vge_idx = idx;
-		arg.vge_maxsegs = 1;
-
-		error = bus_dmamap_load_mbuf(sc->vge_ldata.vge_mtag, map,
-		    m_head, vge_dma_map_tx_desc, &arg, BUS_DMA_NOWAIT);
-		if (error) {
-			if_printf(sc->vge_ifp, "can't map mbuf (error %d)\n",
-			    error);
-			return (EFBIG);
+	/* Argh. This chip does not autopad short frames. */
+	if ((*m_head)->m_pkthdr.len < VGE_MIN_FRAMELEN) {
+		m = *m_head;
+		padlen = VGE_MIN_FRAMELEN - m->m_pkthdr.len;
+		if (M_WRITABLE(m) == 0) {
+			/* Get a writable copy. */
+			m = m_dup(*m_head, M_DONTWAIT);
+			m_freem(*m_head);
+			if (m == NULL) {
+				*m_head = NULL;
+				return (ENOBUFS);
+			}
+			*m_head = m;
 		}
+		if (M_TRAILINGSPACE(m) < padlen) {
+			m = m_defrag(m, M_DONTWAIT);
+			if (m == NULL) {
+				m_freem(*m_head);
+				*m_head = NULL;
+				return (ENOBUFS);
+			}
+		}
+		/*
+		 * Manually pad short frames, and zero the pad space
+		 * to avoid leaking data.
+		 */
+		bzero(mtod(m, char *) + m->m_pkthdr.len, padlen);
+		m->m_pkthdr.len += padlen;
+		m->m_len = m->m_pkthdr.len;
+		*m_head = m;
 	}
 
-	sc->vge_ldata.vge_tx_mbuf[idx] = m_head;
-	sc->vge_ldata.vge_tx_free--;
+	txd = &sc->vge_cdata.vge_txdesc[sc->vge_cdata.vge_tx_prodidx];
+
+	error = bus_dmamap_load_mbuf_sg(sc->vge_cdata.vge_tx_tag,
+	    txd->tx_dmamap, *m_head, txsegs, &nsegs, 0);
+	if (error == EFBIG) {
+		m = m_collapse(*m_head, M_DONTWAIT, VGE_MAXTXSEGS);
+		if (m == NULL) {
+			m_freem(*m_head);
+			*m_head = NULL;
+			return (ENOMEM);
+		}
+		*m_head = m;
+		error = bus_dmamap_load_mbuf_sg(sc->vge_cdata.vge_tx_tag,
+		    txd->tx_dmamap, *m_head, txsegs, &nsegs, 0);
+		if (error != 0) {
+			m_freem(*m_head);
+			*m_head = NULL;
+			return (error);
+		}
+	} else if (error != 0)
+		return (error);
+	bus_dmamap_sync(sc->vge_cdata.vge_tx_tag, txd->tx_dmamap,
+	    BUS_DMASYNC_PREWRITE);
+
+	m = *m_head;
+	cflags = 0;
+
+	/* Configure checksum offload. */
+	if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
+		cflags |= VGE_TDCTL_IPCSUM;
+	if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
+		cflags |= VGE_TDCTL_TCPCSUM;
+	if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
+		cflags |= VGE_TDCTL_UDPCSUM;
+
+	/* Configure VLAN. */
+	if ((m->m_flags & M_VLANTAG) != 0)
+		cflags |= m->m_pkthdr.ether_vtag | VGE_TDCTL_VTAG;
+	txd->tx_desc->vge_sts = htole32(m->m_pkthdr.len << 16);
+	/*
+	 * XXX
+	 * Velocity family seems to support TSO but no information
+	 * for MSS configuration is available. Also the number of
+	 * fragments supported by a descriptor is too small to hold
+	 * entire 64KB TCP/IP segment. Maybe VGE_TD_LS_MOF,
+	 * VGE_TD_LS_SOF and VGE_TD_LS_EOF could be used to build
+	 * longer chain of buffers but no additional information is
+	 * available.
+	 *
+	 * When telling the chip how many segments there are, we
+	 * must use nsegs + 1 instead of just nsegs. Darned if I
+	 * know why. This also means we can't use the last fragment
+	 * field of Tx descriptor.
+	 */
+	txd->tx_desc->vge_ctl = htole32(cflags | ((nsegs + 1) << 28) |
+	    VGE_TD_LS_NORM);
+	for (i = 0; i < nsegs; i++) {
+		frag = &txd->tx_desc->vge_frag[i];
+		frag->vge_addrlo = htole32(VGE_ADDR_LO(txsegs[i].ds_addr));
+		frag->vge_addrhi = htole32(VGE_ADDR_HI(txsegs[i].ds_addr) |
+		    (VGE_BUFLEN(txsegs[i].ds_len) << 16));
+	}
+
+	sc->vge_cdata.vge_tx_cnt++;
+	VGE_TX_DESC_INC(sc->vge_cdata.vge_tx_prodidx);
 
 	/*
-	 * Set up hardware VLAN tagging.
+	 * Finally request interrupt and give the first descriptor
+	 * ownership to hardware.
 	 */
-
-	if (m_head->m_flags & M_VLANTAG)
-		sc->vge_ldata.vge_tx_list[idx].vge_ctl |=
-		    htole32(m_head->m_pkthdr.ether_vtag | VGE_TDCTL_VTAG);
-
-	sc->vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);
+	txd->tx_desc->vge_ctl |= htole32(VGE_TDCTL_TIC);
+	txd->tx_desc->vge_sts |= htole32(VGE_TDSTS_OWN);
+	txd->tx_m = m;
 
 	return (0);
 }
@@ -1771,47 +1915,50 @@ vge_start(ifp)
 	VGE_UNLOCK(sc);
 }
 
+
 static void
 vge_start_locked(ifp)
 	struct ifnet		*ifp;
 {
 	struct vge_softc	*sc;
-	struct mbuf		*m_head = NULL;
-	int			idx, pidx = 0;
+	struct vge_txdesc	*txd;
+	struct mbuf		*m_head;
+	int			enq, idx;
 
 	sc = ifp->if_softc;
+
 	VGE_LOCK_ASSERT(sc);
 
-	if (!sc->vge_link || ifp->if_drv_flags & IFF_DRV_OACTIVE)
+	if (sc->vge_link == 0 ||
+	    (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+	    IFF_DRV_RUNNING)
 		return;
 
-	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		return;
-
-	idx = sc->vge_ldata.vge_tx_prodidx;
-
-	pidx = idx - 1;
-	if (pidx < 0)
-		pidx = VGE_TX_DESC_CNT - 1;
-
-
-	while (sc->vge_ldata.vge_tx_mbuf[idx] == NULL) {
+	idx = sc->vge_cdata.vge_tx_prodidx;
+	VGE_TX_DESC_DEC(idx);
+	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
+	    sc->vge_cdata.vge_tx_cnt < VGE_TX_DESC_CNT - 1; ) {
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
 		if (m_head == NULL)
 			break;
-
-		if (vge_encap(sc, m_head, idx)) {
+		/*
+		 * Pack the data into the transmit ring. If we
+		 * don't have room, set the OACTIVE flag and wait
+		 * for the NIC to drain the ring.
+		 */
+		if (vge_encap(sc, &m_head)) {
+			if (m_head == NULL)
+				break;
 			IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 			break;
 		}
 
-		sc->vge_ldata.vge_tx_list[pidx].vge_frag[0].vge_buflen |=
-		    htole16(VGE_TXDESC_Q);
-
-		pidx = idx;
+		txd = &sc->vge_cdata.vge_txdesc[idx];
+		txd->tx_desc->vge_frag[0].vge_addrhi |= htole32(VGE_TXDESC_Q);
 		VGE_TX_DESC_INC(idx);
 
+		enq++;
 		/*
 		 * If there's a BPF listener, bounce a copy of this frame
 		 * to him.
@@ -1819,37 +1966,28 @@ vge_start_locked(ifp)
 		ETHER_BPF_MTAP(ifp, m_head);
 	}
 
-	if (idx == sc->vge_ldata.vge_tx_prodidx)
-		return;
+	if (enq > 0) {
+		bus_dmamap_sync(sc->vge_cdata.vge_tx_ring_tag,
+		    sc->vge_cdata.vge_tx_ring_map,
+		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+		/* Issue a transmit command. */
+		CSR_WRITE_2(sc, VGE_TXQCSRS, VGE_TXQCSR_WAK0);
+		/*
+		 * Use the countdown timer for interrupt moderation.
+		 * 'TX done' interrupts are disabled. Instead, we reset the
+		 * countdown timer, which will begin counting until it hits
+		 * the value in the SSTIMER register, and then trigger an
+		 * interrupt. Each time we set the TIMER0_ENABLE bit, the
+		 * the timer count is reloaded. Only when the transmitter
+		 * is idle will the timer hit 0 and an interrupt fire.
+		 */
+		CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE);
 
-	/* Flush the TX descriptors */
-
-	bus_dmamap_sync(sc->vge_ldata.vge_tx_list_tag,
-	    sc->vge_ldata.vge_tx_list_map,
-	    BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
-
-	/* Issue a transmit command. */
-	CSR_WRITE_2(sc, VGE_TXQCSRS, VGE_TXQCSR_WAK0);
-
-	sc->vge_ldata.vge_tx_prodidx = idx;
-
-	/*
-	 * Use the countdown timer for interrupt moderation.
-	 * 'TX done' interrupts are disabled. Instead, we reset the
-	 * countdown timer, which will begin counting until it hits
-	 * the value in the SSTIMER register, and then trigger an
-	 * interrupt. Each time we set the TIMER0_ENABLE bit, the
-	 * the timer count is reloaded. Only when the transmitter
-	 * is idle will the timer hit 0 and an interrupt fire.
-	 */
-	CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE);
-
-	/*
-	 * Set a timeout in case the chip goes out to lunch.
-	 */
-	sc->vge_timer = 5;
-
-	return;
+		/*
+		 * Set a timeout in case the chip goes out to lunch.
+		 */
+		sc->vge_timer = 5;
+	}
 }
 
 static void
@@ -1868,11 +2006,14 @@ vge_init_locked(struct vge_softc *sc)
 {
 	struct ifnet		*ifp = sc->vge_ifp;
 	struct mii_data		*mii;
-	int			i;
+	int			error, i;
 
 	VGE_LOCK_ASSERT(sc);
 	mii = device_get_softc(sc->vge_miibus);
 
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		return;
+
 	/*
 	 * Cancel pending I/O and free all RX/TX buffers.
 	 */
@@ -1883,7 +2024,11 @@ vge_init_locked(struct vge_softc *sc)
 	 * Initialize the RX and TX descriptors and mbufs.
 	 */
 
-	vge_rx_list_init(sc);
+	error = vge_rx_list_init(sc);
+	if (error != 0) {
+                device_printf(sc->vge_dev, "no memory for Rx buffers.\n");
+                return;
+	}
 	vge_tx_list_init(sc);
 
 	/* Set our station address */
@@ -1916,12 +2061,14 @@ vge_init_locked(struct vge_softc *sc)
 	 * Note that we only use one transmit queue.
 	 */
 
+	CSR_WRITE_4(sc, VGE_TXDESC_HIADDR,
+	    VGE_ADDR_HI(sc->vge_rdata.vge_tx_ring_paddr));
 	CSR_WRITE_4(sc, VGE_TXDESC_ADDR_LO0,
-	    VGE_ADDR_LO(sc->vge_ldata.vge_tx_list_addr));
+	    VGE_ADDR_LO(sc->vge_rdata.vge_tx_ring_paddr));
 	CSR_WRITE_2(sc, VGE_TXDESCNUM, VGE_TX_DESC_CNT - 1);
 
 	CSR_WRITE_4(sc, VGE_RXDESC_ADDR_LO,
-	    VGE_ADDR_LO(sc->vge_ldata.vge_rx_list_addr));
+	    VGE_ADDR_LO(sc->vge_rdata.vge_rx_ring_paddr));
 	CSR_WRITE_2(sc, VGE_RXDESCNUM, VGE_RX_DESC_CNT - 1);
 	CSR_WRITE_2(sc, VGE_RXDESC_RESIDUECNT, VGE_RX_DESC_CNT);
 
@@ -2028,10 +2175,7 @@ vge_init_locked(struct vge_softc *sc)
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	callout_reset(&sc->vge_watchdog, hz, vge_watchdog, sc);
 
-	sc->vge_if_flags = 0;
 	sc->vge_link = 0;
-
-	return;
 }
 
 /*
@@ -2170,7 +2314,8 @@ vge_ioctl(ifp, command, data)
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		VGE_LOCK(sc);
-		vge_setmulti(sc);
+		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			vge_setmulti(sc);
 		VGE_UNLOCK(sc);
 		break;
 	case SIOCGIFMEDIA:
@@ -2245,8 +2390,9 @@ vge_watchdog(void *arg)
 	ifp->if_oerrors++;
 
 	vge_txeof(sc);
-	vge_rxeof(sc);
+	vge_rxeof(sc, VGE_RX_DESC_CNT);
 
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	vge_init_locked(sc);
 
 	return;
@@ -2260,7 +2406,6 @@ static void
 vge_stop(sc)
 	struct vge_softc		*sc;
 {
-	int			i;
 	struct ifnet		*ifp;
 
 	VGE_LOCK_ASSERT(sc);
@@ -2277,34 +2422,9 @@ vge_stop(sc)
 	CSR_WRITE_1(sc, VGE_RXQCSRC, 0xFF);
 	CSR_WRITE_4(sc, VGE_RXDESC_ADDR_LO, 0);
 
-	if (sc->vge_head != NULL) {
-		m_freem(sc->vge_head);
-		sc->vge_head = sc->vge_tail = NULL;
-	}
-
-	/* Free the TX list buffers. */
-
-	for (i = 0; i < VGE_TX_DESC_CNT; i++) {
-		if (sc->vge_ldata.vge_tx_mbuf[i] != NULL) {
-			bus_dmamap_unload(sc->vge_ldata.vge_mtag,
-			    sc->vge_ldata.vge_tx_dmamap[i]);
-			m_freem(sc->vge_ldata.vge_tx_mbuf[i]);
-			sc->vge_ldata.vge_tx_mbuf[i] = NULL;
-		}
-	}
-
-	/* Free the RX list buffers. */
-
-	for (i = 0; i < VGE_RX_DESC_CNT; i++) {
-		if (sc->vge_ldata.vge_rx_mbuf[i] != NULL) {
-			bus_dmamap_unload(sc->vge_ldata.vge_mtag,
-			    sc->vge_ldata.vge_rx_dmamap[i]);
-			m_freem(sc->vge_ldata.vge_rx_mbuf[i]);
-			sc->vge_ldata.vge_rx_mbuf[i] = NULL;
-		}
-	}
-
-	return;
+	VGE_CHAIN_RESET(sc);
+	vge_txeof(sc);
+	vge_freebufs(sc);
 }
 
 /*
@@ -2350,9 +2470,10 @@ vge_resume(dev)
 
 	/* reinitialize interface if necessary */
 	VGE_LOCK(sc);
-	if (ifp->if_flags & IFF_UP)
+	if (ifp->if_flags & IFF_UP) {
+		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 		vge_init_locked(sc);
-
+	}
 	sc->suspended = 0;
 	VGE_UNLOCK(sc);
 
diff --git a/sys/dev/vge/if_vgereg.h b/sys/dev/vge/if_vgereg.h
index 8d11a9c3e1f..b53a21e25d8 100644
--- a/sys/dev/vge/if_vgereg.h
+++ b/sys/dev/vge/if_vgereg.h
@@ -587,8 +587,7 @@
 
 struct vge_tx_frag {
 	uint32_t		vge_addrlo;
-	uint16_t		vge_addrhi;
-	uint16_t		vge_buflen;
+	uint32_t		vge_addrhi;
 };
 
 /*
@@ -600,7 +599,7 @@ struct vge_tx_frag {
  * to obtain this behavior, the special 'queue' bit must be set.
  */
 
-#define VGE_TXDESC_Q		0x8000
+#define VGE_TXDESC_Q		0x80000000
 
 struct vge_tx_desc {
 	uint32_t		vge_sts;
@@ -645,11 +644,10 @@ struct vge_tx_desc {
 /* Receive DMA descriptors have a single fragment pointer. */
 
 struct vge_rx_desc {
-	volatile uint32_t	vge_sts;
-	volatile uint32_t	vge_ctl;
-	volatile uint32_t	vge_addrlo;
-	volatile uint16_t	vge_addrhi;
-	volatile uint16_t	vge_buflen;
+	uint32_t	vge_sts;
+	uint32_t	vge_ctl;
+	uint32_t	vge_addrlo;
+	uint32_t	vge_addrhi;
 };
 
 /*
@@ -658,7 +656,7 @@ struct vge_rx_desc {
  * not interrupts are generated for this descriptor.
  */
 
-#define VGE_RXDESC_I		0x8000
+#define VGE_RXDESC_I		0x80000000
 
 #define VGE_RDSTS_VIDM		0x00000001	/* VLAN tag filter miss */
 #define VGE_RDSTS_CRCERR	0x00000002	/* bad CRC error */
diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h
index c4f7edb839f..404d5f5f0f4 100644
--- a/sys/dev/vge/if_vgevar.h
+++ b/sys/dev/vge/if_vgevar.h
@@ -32,27 +32,39 @@
  * $FreeBSD$
  */
 
-#if !defined(__i386__)
-#define VGE_FIXUP_RX
-#endif
-
 #define VGE_JUMBO_MTU	9000
 
 #define VGE_IFQ_MAXLEN 64
 
 #define VGE_TX_DESC_CNT		256
-#define VGE_RX_DESC_CNT		256	/* Must be a multiple of 4!! */
-#define VGE_RING_ALIGN		256
+#define VGE_RX_DESC_CNT		252	/* Must be a multiple of 4!! */
+#define VGE_TX_RING_ALIGN	64
+#define VGE_RX_RING_ALIGN	64
+#define VGE_MAXTXSEGS		6
+#define VGE_RX_BUF_ALIGN	sizeof(uint32_t)
+
+/*
+ * VIA Velocity allows 64bit DMA addressing but high 16bits
+ * of the DMA address should be the same for Tx/Rx buffers.
+ * Because this condition can't be guaranteed vge(4) limit
+ * DMA address space to 48bits.
+ */
+#if (BUS_SPACE_MAXADDR < 0xFFFFFFFFFF)
+#define	VGE_BUF_DMA_MAXADDR	BUS_SPACE_MAXADDR
+#else
+#define	VGE_BUF_DMA_MAXADDR	0xFFFFFFFFFFFF
+#endif
+
 #define VGE_RX_LIST_SZ		(VGE_RX_DESC_CNT * sizeof(struct vge_rx_desc))
 #define VGE_TX_LIST_SZ		(VGE_TX_DESC_CNT * sizeof(struct vge_tx_desc))
-#define VGE_TX_DESC_INC(x)	(x = (x + 1) % VGE_TX_DESC_CNT)
-#define VGE_RX_DESC_INC(x)	(x = (x + 1) % VGE_RX_DESC_CNT)
-#define VGE_ADDR_LO(y)		((u_int64_t) (y) & 0xFFFFFFFF)
-#define VGE_ADDR_HI(y)		((u_int64_t) (y) >> 32)
-#define VGE_BUFLEN(y)		((y) & 0x7FFF)
-#define VGE_OWN(x)		(le32toh((x)->vge_sts) & VGE_RDSTS_OWN)
-#define VGE_RXBYTES(x)		((le32toh((x)->vge_sts) & \
-				 VGE_RDSTS_BUFSIZ) >> 16)
+#define VGE_TX_DESC_INC(x)	((x) = ((x) + 1) % VGE_TX_DESC_CNT)
+#define VGE_TX_DESC_DEC(x)	\
+	((x) = (((x) + VGE_TX_DESC_CNT - 1) % VGE_TX_DESC_CNT))
+#define VGE_RX_DESC_INC(x)	((x) = ((x) + 1) % VGE_RX_DESC_CNT)
+#define VGE_ADDR_LO(y)		((uint64_t) (y) & 0xFFFFFFFF)
+#define VGE_ADDR_HI(y)		((uint64_t) (y) >> 32)
+#define VGE_BUFLEN(y)		((y) & 0x3FFF)
+#define VGE_RXBYTES(x)		(((x) & VGE_RDSTS_BUFSIZ) >> 16)
 #define VGE_MIN_FRAMELEN	60
 
 #ifdef VGE_FIXUP_RX
@@ -67,34 +79,57 @@ struct vge_type {
 	char			*vge_name;
 };
 
-struct vge_softc;
-
-struct vge_dmaload_arg {
-	struct vge_softc	*sc;
-	int			vge_idx;
-	int			vge_maxsegs;
-	struct mbuf		*vge_m0;
-	u_int32_t		vge_flags;
+struct vge_txdesc {
+	struct mbuf		*tx_m;
+	bus_dmamap_t		tx_dmamap;
+	struct vge_tx_desc	*tx_desc;
+	struct vge_txdesc	*txd_prev;
 };
 
-struct vge_list_data {
-	struct mbuf		*vge_tx_mbuf[VGE_TX_DESC_CNT];
-	struct mbuf		*vge_rx_mbuf[VGE_RX_DESC_CNT];
+struct vge_rxdesc {
+	struct mbuf 		*rx_m;
+	bus_dmamap_t		rx_dmamap;
+	struct vge_rx_desc	*rx_desc;
+	struct vge_rxdesc	*rxd_prev;
+};
+
+struct vge_chain_data{
+	bus_dma_tag_t		vge_ring_tag;
+	bus_dma_tag_t		vge_buffer_tag;
+	bus_dma_tag_t		vge_tx_tag;
+	struct vge_txdesc	vge_txdesc[VGE_TX_DESC_CNT];
+	bus_dma_tag_t		vge_rx_tag;
+	struct vge_rxdesc	vge_rxdesc[VGE_RX_DESC_CNT];
+	bus_dma_tag_t		vge_tx_ring_tag;
+	bus_dmamap_t		vge_tx_ring_map;
+	bus_dma_tag_t		vge_rx_ring_tag;
+	bus_dmamap_t		vge_rx_ring_map;
+	bus_dmamap_t		vge_rx_sparemap;
+
 	int			vge_tx_prodidx;
-	int			vge_rx_prodidx;
 	int			vge_tx_considx;
-	int			vge_tx_free;
-	bus_dmamap_t		vge_tx_dmamap[VGE_TX_DESC_CNT];
-	bus_dmamap_t		vge_rx_dmamap[VGE_RX_DESC_CNT];
-	bus_dma_tag_t		vge_mtag;        /* mbuf mapping tag */
-	bus_dma_tag_t		vge_rx_list_tag;
-	bus_dmamap_t		vge_rx_list_map;
-	struct vge_rx_desc	*vge_rx_list;
-	bus_addr_t		vge_rx_list_addr;
-	bus_dma_tag_t		vge_tx_list_tag;
-	bus_dmamap_t		vge_tx_list_map;
-	struct vge_tx_desc	*vge_tx_list;
-	bus_addr_t		vge_tx_list_addr;
+	int			vge_tx_cnt;
+	int			vge_rx_prodidx;
+	int			vge_rx_commit;
+
+	struct mbuf		*vge_head;
+	struct mbuf		*vge_tail;
+};
+
+#define	VGE_CHAIN_RESET(_sc)						\
+do {									\
+	if ((_sc)->vge_cdata.vge_head != NULL) {			\
+		m_freem((_sc)->vge_cdata.vge_head);			\
+		(_sc)->vge_cdata.vge_head = NULL;			\
+		(_sc)->vge_cdata.vge_tail = NULL;			\
+	}								\
+} while (0);
+
+struct vge_ring_data {
+	struct vge_tx_desc	*vge_tx_ring;
+	bus_addr_t		vge_tx_ring_paddr;
+	struct vge_rx_desc	*vge_rx_ring;
+	bus_addr_t		vge_rx_ring_paddr;
 };
 
 struct vge_softc {
@@ -104,25 +139,18 @@ struct vge_softc {
 	struct resource		*vge_irq;
 	void			*vge_intrhand;
 	device_t		vge_miibus;
-	bus_dma_tag_t		vge_parent_tag;
-	bus_dma_tag_t		vge_tag;
 	u_int8_t		vge_type;
 	int			vge_if_flags;
-	int			vge_rx_consumed;
 	int			vge_link;
 	int			vge_camidx;
 	struct mtx		vge_mtx;
 	struct callout		vge_watchdog;
 	int			vge_timer;
-	struct mbuf		*vge_head;
-	struct mbuf		*vge_tail;
 
-	struct vge_list_data	vge_ldata;
+	struct vge_chain_data	vge_cdata;
+	struct vge_ring_data	vge_rdata;
 
 	int			suspended;	/* 0 = normal  1 = suspended */
-#ifdef DEVICE_POLLING
-	int			rxcycles;
-#endif
 };
 
 #define	VGE_LOCK(_sc)		mtx_lock(&(_sc)->vge_mtx)
@@ -162,5 +190,6 @@ struct vge_softc {
 #define CSR_CLRBIT_4(sc, reg, x)	\
 	CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~(x))
 
+#define VGE_RXCHUNK		4
 #define VGE_TIMEOUT		10000
 

From 97a0b2e16cb2dc009cbe6696297445858ee79978 Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Fri, 8 Jan 2010 21:58:12 +0000
Subject: [PATCH 1062/2592] MFC r201352

  If a filter has already been added, actually return EEXIST when trying
  at add it again.
---
 sys/kern/kern_event.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 27eac03eb05..47a17fb8976 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -852,6 +852,7 @@ kqueue_add_filteropts(int filt, struct filterops *filtops)
 {
 	int error;
 
+	error = 0;
 	if (filt > 0 || filt + EVFILT_SYSCOUNT < 0) {
 		printf(
 "trying to add a filterop that is out of range: %d is beyond %d\n",
@@ -868,7 +869,7 @@ kqueue_add_filteropts(int filt, struct filterops *filtops)
 	}
 	mtx_unlock(&filterops_lock);
 
-	return (0);
+	return (error);
 }
 
 int

From ef227052593c4f1e2a27c936c8937c884fccf2ad Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Fri, 8 Jan 2010 22:08:18 +0000
Subject: [PATCH 1063/2592] MFC r200526-200527,200529,200531-200533,200536

r200526:
  Use PCIR_BAR instead of hard-coded value.

r200527:
  Fix typo in register definition.

r200529:
  Clear VGE_TXDESC_Q bit for transmitted frames. The VGE_TXDESC_Q bit
  seems to work like a tag that indicates 'not list end' of queued
  frames. Without having a VGE_TXDESC_Q bit indicates 'list end'. So
  the last frame of multiple queued frames has no VGE_TXDESC_Q bit.
  The hardware has peculiar behavior for VGE_TXDESC_Q bit handling.
  If the VGE_TXDESC_Q bit of descriptor was set the controller would
  fetch next descriptor. However if next descriptor's OWN bit was
  cleared but VGE_TXDESC_Q was set, it could confuse controller.
  Clearing VGE_TXDESC_Q bit for transmitted frames ensure correct
  behavior.

r200531:
  Use ANSI function definations.

r200532:
  Remove unnecessary return statement.

r200533:
  s/u_intXX_t/uintXX_t/g

r200536:
  style(9).
---
 sys/dev/vge/if_vge.c    | 383 ++++++++++++++++------------------------
 sys/dev/vge/if_vgereg.h |   8 +-
 sys/dev/vge/if_vgevar.h |   2 +-
 3 files changed, 157 insertions(+), 236 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index 4a73f8d8112..a8d2bc3a44f 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -172,7 +172,7 @@ static int vge_ifmedia_upd	(struct ifnet *);
 static void vge_ifmedia_sts	(struct ifnet *, struct ifmediareq *);
 
 #ifdef VGE_EEPROM
-static void vge_eeprom_getword	(struct vge_softc *, int, u_int16_t *);
+static void vge_eeprom_getword	(struct vge_softc *, int, uint16_t *);
 #endif
 static void vge_read_eeprom	(struct vge_softc *, caddr_t, int, int, int);
 
@@ -187,9 +187,6 @@ static int vge_cam_set		(struct vge_softc *, uint8_t *);
 static void vge_setmulti	(struct vge_softc *);
 static void vge_reset		(struct vge_softc *);
 
-#define VGE_PCI_LOIO             0x10
-#define VGE_PCI_LOMEM            0x14
-
 static device_method_t vge_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		vge_probe),
@@ -227,13 +224,10 @@ DRIVER_MODULE(miibus, vge, miibus_driver, miibus_devclass, 0, 0);
  * Read a word of data stored in the EEPROM at address 'addr.'
  */
 static void
-vge_eeprom_getword(sc, addr, dest)
-	struct vge_softc	*sc;
-	int			addr;
-	u_int16_t		*dest;
+vge_eeprom_getword(struct vge_softc *sc, int addr, uint16_t *dest)
 {
-	int			i;
-	u_int16_t		word = 0;
+	int i;
+	uint16_t word = 0;
 
 	/*
 	 * Enter EEPROM embedded programming mode. In order to
@@ -269,8 +263,6 @@ vge_eeprom_getword(sc, addr, dest)
 	CSR_CLRBIT_1(sc, VGE_CHIPCFG2, VGE_CHIPCFG2_EELOAD);
 
 	*dest = word;
-
-	return;
 }
 #endif
 
@@ -278,20 +270,15 @@ vge_eeprom_getword(sc, addr, dest)
  * Read a sequence of words from the EEPROM.
  */
 static void
-vge_read_eeprom(sc, dest, off, cnt, swap)
-	struct vge_softc	*sc;
-	caddr_t			dest;
-	int			off;
-	int			cnt;
-	int			swap;
+vge_read_eeprom(struct vge_softc *sc, caddr_t dest, int off, int cnt, int swap)
 {
-	int			i;
+	int i;
 #ifdef VGE_EEPROM
-	u_int16_t		word = 0, *ptr;
+	uint16_t word = 0, *ptr;
 
 	for (i = 0; i < cnt; i++) {
 		vge_eeprom_getword(sc, off + i, &word);
-		ptr = (u_int16_t *)(dest + (i * 2));
+		ptr = (uint16_t *)(dest + (i * 2));
 		if (swap)
 			*ptr = ntohs(word);
 		else
@@ -304,10 +291,9 @@ vge_read_eeprom(sc, dest, off, cnt, swap)
 }
 
 static void
-vge_miipoll_stop(sc)
-	struct vge_softc	*sc;
+vge_miipoll_stop(struct vge_softc *sc)
 {
-	int			i;
+	int i;
 
 	CSR_WRITE_1(sc, VGE_MIICMD, 0);
 
@@ -319,15 +305,12 @@ vge_miipoll_stop(sc)
 
 	if (i == VGE_TIMEOUT)
 		device_printf(sc->vge_dev, "failed to idle MII autopoll\n");
-
-	return;
 }
 
 static void
-vge_miipoll_start(sc)
-	struct vge_softc	*sc;
+vge_miipoll_start(struct vge_softc *sc)
 {
-	int			i;
+	int i;
 
 	/* First, make sure we're idle. */
 
@@ -359,23 +342,19 @@ vge_miipoll_start(sc)
 
 	if (i == VGE_TIMEOUT)
 		device_printf(sc->vge_dev, "failed to start MII autopoll\n");
-
-	return;
 }
 
 static int
-vge_miibus_readreg(dev, phy, reg)
-	device_t		dev;
-	int			phy, reg;
+vge_miibus_readreg(device_t dev, int phy, int reg)
 {
-	struct vge_softc	*sc;
-	int			i;
-	u_int16_t		rval = 0;
+	struct vge_softc *sc;
+	int i;
+	uint16_t rval = 0;
 
 	sc = device_get_softc(dev);
 
 	if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
-		return(0);
+		return (0);
 
 	vge_miipoll_stop(sc);
 
@@ -403,17 +382,15 @@ vge_miibus_readreg(dev, phy, reg)
 }
 
 static int
-vge_miibus_writereg(dev, phy, reg, data)
-	device_t		dev;
-	int			phy, reg, data;
+vge_miibus_writereg(device_t dev, int phy, int reg, int data)
 {
-	struct vge_softc	*sc;
-	int			i, rval = 0;
+	struct vge_softc *sc;
+	int i, rval = 0;
 
 	sc = device_get_softc(dev);
 
 	if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
-		return(0);
+		return (0);
 
 	vge_miipoll_stop(sc);
 
@@ -444,10 +421,9 @@ vge_miibus_writereg(dev, phy, reg, data)
 }
 
 static void
-vge_cam_clear(sc)
-	struct vge_softc	*sc;
+vge_cam_clear(struct vge_softc *sc)
 {
-	int			i;
+	int i;
 
 	/*
 	 * Turn off all the mask bits. This tells the chip
@@ -472,19 +448,15 @@ vge_cam_clear(sc)
 	CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_MAR);
 
 	sc->vge_camidx = 0;
-
-	return;
 }
 
 static int
-vge_cam_set(sc, addr)
-	struct vge_softc	*sc;
-	uint8_t			*addr;
+vge_cam_set(struct vge_softc *sc, uint8_t *addr)
 {
-	int			i, error = 0;
+	int i, error = 0;
 
 	if (sc->vge_camidx == VGE_CAM_MAXADDRS)
-		return(ENOSPC);
+		return (ENOSPC);
 
 	/* Select the CAM data page. */
 	CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
@@ -538,13 +510,12 @@ fail:
  * we use the hash filter instead.
  */
 static void
-vge_setmulti(sc)
-	struct vge_softc	*sc;
+vge_setmulti(struct vge_softc *sc)
 {
-	struct ifnet		*ifp;
-	int			error = 0/*, h = 0*/;
-	struct ifmultiaddr	*ifma;
-	u_int32_t		h, hashes[2] = { 0, 0 };
+	struct ifnet *ifp;
+	int error = 0/*, h = 0*/;
+	struct ifmultiaddr *ifma;
+	uint32_t h, hashes[2] = { 0, 0 };
 
 	VGE_LOCK_ASSERT(sc);
 
@@ -595,15 +566,12 @@ vge_setmulti(sc)
 		CSR_WRITE_4(sc, VGE_MAR1, hashes[1]);
 	}
 	if_maddr_runlock(ifp);
-
-	return;
 }
 
 static void
-vge_reset(sc)
-	struct vge_softc		*sc;
+vge_reset(struct vge_softc *sc)
 {
-	int			i;
+	int i;
 
 	CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_SOFTRESET);
 
@@ -635,8 +603,6 @@ vge_reset(sc)
 	}
 
 	CSR_CLRBIT_1(sc, VGE_CHIPCFG0, VGE_CHIPCFG0_PACPI);
-
-	return;
 }
 
 /*
@@ -644,10 +610,9 @@ vge_reset(sc)
  * IDs against our list and return a device name if we find a match.
  */
 static int
-vge_probe(dev)
-	device_t		dev;
+vge_probe(device_t dev)
 {
-	struct vge_type		*t;
+	struct vge_type	*t;
 
 	t = vge_devs;
 
@@ -672,13 +637,9 @@ struct vge_dmamap_arg {
 };
 
 static void
-vge_dmamap_cb(arg, segs, nsegs, error)
-	void			*arg;
-	bus_dma_segment_t	*segs;
-	int			nsegs;
-	int			error;
+vge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 {
-	struct vge_dmamap_arg	*ctx;
+	struct vge_dmamap_arg *ctx;
 
 	if (error != 0)
 		return;
@@ -690,14 +651,13 @@ vge_dmamap_cb(arg, segs, nsegs, error)
 }
 
 static int
-vge_dma_alloc(sc)
-	struct vge_softc	*sc;
+vge_dma_alloc(struct vge_softc *sc)
 {
-	struct vge_dmamap_arg	ctx;
-	struct vge_txdesc	*txd;
-	struct vge_rxdesc	*rxd;
-	bus_addr_t		lowaddr, tx_ring_end, rx_ring_end;
-	int			error, i;
+	struct vge_dmamap_arg ctx;
+	struct vge_txdesc *txd;
+	struct vge_rxdesc *rxd;
+	bus_addr_t lowaddr, tx_ring_end, rx_ring_end;
+	int error, i;
 
 	lowaddr = BUS_SPACE_MAXADDR;
 
@@ -906,12 +866,11 @@ fail:
 }
 
 static void
-vge_dma_free(sc)
-	struct vge_softc	*sc;
+vge_dma_free(struct vge_softc *sc)
 {
-	struct vge_txdesc	*txd;
-	struct vge_rxdesc	*rxd;
-	int			i;
+	struct vge_txdesc *txd;
+	struct vge_rxdesc *rxd;
+	int i;
 
 	/* Tx ring. */
 	if (sc->vge_cdata.vge_tx_ring_tag != NULL) {
@@ -990,13 +949,12 @@ vge_dma_free(sc)
  * setup and ethernet/BPF attach.
  */
 static int
-vge_attach(dev)
-	device_t		dev;
+vge_attach(device_t dev)
 {
-	u_char			eaddr[ETHER_ADDR_LEN];
-	struct vge_softc	*sc;
-	struct ifnet		*ifp;
-	int			error = 0, rid;
+	u_char eaddr[ETHER_ADDR_LEN];
+	struct vge_softc *sc;
+	struct ifnet *ifp;
+	int error = 0, rid;
 
 	sc = device_get_softc(dev);
 	sc->vge_dev = dev;
@@ -1010,7 +968,7 @@ vge_attach(dev)
 	 */
 	pci_enable_busmaster(dev);
 
-	rid = VGE_PCI_LOMEM;
+	rid = PCIR_BAR(1);
 	sc->vge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
 	    RF_ACTIVE);
 
@@ -1106,11 +1064,10 @@ fail:
  * allocated.
  */
 static int
-vge_detach(dev)
-	device_t		dev;
+vge_detach(device_t dev)
 {
-	struct vge_softc		*sc;
-	struct ifnet		*ifp;
+	struct vge_softc *sc;
+	struct ifnet *ifp;
 
 	sc = device_get_softc(dev);
 	KASSERT(mtx_initialized(&sc->vge_mtx), ("vge mutex not initialized"));
@@ -1139,7 +1096,7 @@ vge_detach(dev)
 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vge_irq);
 	if (sc->vge_res)
 		bus_release_resource(dev, SYS_RES_MEMORY,
-		    VGE_PCI_LOMEM, sc->vge_res);
+		    PCIR_BAR(1), sc->vge_res);
 	if (ifp)
 		if_free(ifp);
 
@@ -1150,12 +1107,10 @@ vge_detach(dev)
 }
 
 static void
-vge_discard_rxbuf(sc, prod)
-	struct vge_softc	*sc;
-	int			prod;
+vge_discard_rxbuf(struct vge_softc *sc, int prod)
 {
-	struct vge_rxdesc	*rxd;
-	int			i;
+	struct vge_rxdesc *rxd;
+	int i;
 
 	rxd = &sc->vge_cdata.vge_rxdesc[prod];
 	rxd->rx_desc->vge_sts = 0;
@@ -1179,15 +1134,13 @@ vge_discard_rxbuf(sc, prod)
 }
 
 static int
-vge_newbuf(sc, prod)
-	struct vge_softc	*sc;
-	int			prod;
+vge_newbuf(struct vge_softc *sc, int prod)
 {
-	struct vge_rxdesc	*rxd;
-	struct mbuf		*m;
-	bus_dma_segment_t	segs[1];
-	bus_dmamap_t		map;
-	int			i, nsegs;
+	struct vge_rxdesc *rxd;
+	struct mbuf *m;
+	bus_dma_segment_t segs[1];
+	bus_dmamap_t map;
+	int i, nsegs;
 
 	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
 	if (m == NULL)
@@ -1251,12 +1204,11 @@ vge_newbuf(sc, prod)
 }
 
 static int
-vge_tx_list_init(sc)
-	struct vge_softc	*sc;
+vge_tx_list_init(struct vge_softc *sc)
 {
-	struct vge_ring_data	*rd;
-	struct vge_txdesc	*txd;
-	int			i;
+	struct vge_ring_data *rd;
+	struct vge_txdesc *txd;
+	int i;
 
 	VGE_LOCK_ASSERT(sc);
 
@@ -1280,12 +1232,11 @@ vge_tx_list_init(sc)
 }
 
 static int
-vge_rx_list_init(sc)
-	struct vge_softc	*sc;
+vge_rx_list_init(struct vge_softc *sc)
 {
-	struct vge_ring_data	*rd;
-	struct vge_rxdesc	*rxd;
-	int			i;
+	struct vge_ring_data *rd;
+	struct vge_rxdesc *rxd;
+	int i;
 
 	VGE_LOCK_ASSERT(sc);
 
@@ -1319,13 +1270,12 @@ vge_rx_list_init(sc)
 }
 
 static void
-vge_freebufs(sc)
-	struct vge_softc	*sc;
+vge_freebufs(struct vge_softc *sc)
 {
-	struct vge_txdesc	*txd;
-	struct vge_rxdesc	*rxd;
-	struct ifnet		*ifp;
-	int			i;
+	struct vge_txdesc *txd;
+	struct vge_rxdesc *rxd;
+	struct ifnet *ifp;
+	int i;
 
 	VGE_LOCK_ASSERT(sc);
 
@@ -1361,11 +1311,10 @@ vge_freebufs(sc)
 
 #ifndef	__NO_STRICT_ALIGNMENT
 static __inline void
-vge_fixup_rx(m)
-	struct mbuf		*m;
+vge_fixup_rx(struct mbuf *m)
 {
-	int			i;
-	uint16_t		*src, *dst;
+	int i;
+	uint16_t *src, *dst;
 
 	src = mtod(m, uint16_t *);
 	dst = src - 1;
@@ -1382,16 +1331,14 @@ vge_fixup_rx(m)
  * been fragmented across multiple 2K mbuf cluster buffers.
  */
 static int
-vge_rxeof(sc, count)
-	struct vge_softc	*sc;
-	int			count;
+vge_rxeof(struct vge_softc *sc, int count)
 {
-	struct mbuf		*m;
-	struct ifnet		*ifp;
-	int			prod, prog, total_len;
-	struct vge_rxdesc	*rxd;
-	struct vge_rx_desc	*cur_rx;
-	uint32_t		rxstat, rxctl;
+	struct mbuf *m;
+	struct ifnet *ifp;
+	int prod, prog, total_len;
+	struct vge_rxdesc *rxd;
+	struct vge_rx_desc *cur_rx;
+	uint32_t rxstat, rxctl;
 
 	VGE_LOCK_ASSERT(sc);
 
@@ -1556,14 +1503,13 @@ vge_rxeof(sc, count)
 }
 
 static void
-vge_txeof(sc)
-	struct vge_softc	*sc;
+vge_txeof(struct vge_softc *sc)
 {
-	struct ifnet		*ifp;
-	struct vge_tx_desc	*cur_tx;
-	struct vge_txdesc	*txd;
-	uint32_t		txstat;
-	int			cons, prod;
+	struct ifnet *ifp;
+	struct vge_tx_desc *cur_tx;
+	struct vge_txdesc *txd;
+	uint32_t txstat;
+	int cons, prod;
 
 	VGE_LOCK_ASSERT(sc);
 
@@ -1599,8 +1545,11 @@ vge_txeof(sc)
 		    __func__));
 		m_freem(txd->tx_m);
 		txd->tx_m = NULL;
+		txd->tx_desc->vge_frag[0].vge_addrhi = 0;
 	}
-
+	bus_dmamap_sync(sc->vge_cdata.vge_tx_ring_tag,
+	    sc->vge_cdata.vge_tx_ring_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	sc->vge_cdata.vge_tx_considx = cons;
 	if (sc->vge_cdata.vge_tx_cnt == 0)
 		sc->vge_timer = 0;
@@ -1616,12 +1565,11 @@ vge_txeof(sc)
 }
 
 static void
-vge_tick(xsc)
-	void			*xsc;
+vge_tick(void *xsc)
 {
-	struct vge_softc	*sc;
-	struct ifnet		*ifp;
-	struct mii_data		*mii;
+	struct vge_softc *sc;
+	struct ifnet *ifp;
+	struct mii_data *mii;
 
 	sc = xsc;
 	ifp = sc->vge_ifp;
@@ -1645,8 +1593,6 @@ vge_tick(xsc)
 				vge_start_locked(ifp);
 		}
 	}
-
-	return;
 }
 
 #ifdef DEVICE_POLLING
@@ -1667,7 +1613,7 @@ vge_poll (struct ifnet *ifp, enum poll_cmd cmd, int count)
 		vge_start_locked(ifp);
 
 	if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
-		u_int32_t       status;
+		uint32_t       status;
 		status = CSR_READ_4(sc, VGE_ISR);
 		if (status == 0xFFFFFFFF)
 			goto done;
@@ -1698,12 +1644,11 @@ done:
 #endif /* DEVICE_POLLING */
 
 static void
-vge_intr(arg)
-	void			*arg;
+vge_intr(void *arg)
 {
-	struct vge_softc	*sc;
-	struct ifnet		*ifp;
-	u_int32_t		status;
+	struct vge_softc *sc;
+	struct ifnet *ifp;
+	uint32_t status;
 
 	sc = arg;
 
@@ -1770,21 +1715,17 @@ vge_intr(arg)
 		vge_start_locked(ifp);
 
 	VGE_UNLOCK(sc);
-
-	return;
 }
 
 static int
-vge_encap(sc, m_head)
-	struct vge_softc	*sc;
-	struct mbuf		**m_head;
+vge_encap(struct vge_softc *sc, struct mbuf **m_head)
 {
-	struct vge_txdesc	*txd;
-	struct vge_tx_frag	*frag;
-	struct mbuf		*m;
-	bus_dma_segment_t	txsegs[VGE_MAXTXSEGS];
-	int			error, i, nsegs, padlen;
-	uint32_t		cflags;
+	struct vge_txdesc *txd;
+	struct vge_tx_frag *frag;
+	struct mbuf *m;
+	bus_dma_segment_t txsegs[VGE_MAXTXSEGS];
+	int error, i, nsegs, padlen;
+	uint32_t cflags;
 
 	VGE_LOCK_ASSERT(sc);
 
@@ -1904,10 +1845,9 @@ vge_encap(sc, m_head)
  */
 
 static void
-vge_start(ifp)
-	struct ifnet		*ifp;
+vge_start(struct ifnet *ifp)
 {
-	struct vge_softc	*sc;
+	struct vge_softc *sc;
 
 	sc = ifp->if_softc;
 	VGE_LOCK(sc);
@@ -1917,13 +1857,12 @@ vge_start(ifp)
 
 
 static void
-vge_start_locked(ifp)
-	struct ifnet		*ifp;
+vge_start_locked(struct ifnet *ifp)
 {
-	struct vge_softc	*sc;
-	struct vge_txdesc	*txd;
-	struct mbuf		*m_head;
-	int			enq, idx;
+	struct vge_softc *sc;
+	struct vge_txdesc *txd;
+	struct mbuf *m_head;
+	int enq, idx;
 
 	sc = ifp->if_softc;
 
@@ -1991,10 +1930,9 @@ vge_start_locked(ifp)
 }
 
 static void
-vge_init(xsc)
-	void			*xsc;
+vge_init(void *xsc)
 {
-	struct vge_softc	*sc = xsc;
+	struct vge_softc *sc = xsc;
 
 	VGE_LOCK(sc);
 	vge_init_locked(sc);
@@ -2004,9 +1942,9 @@ vge_init(xsc)
 static void
 vge_init_locked(struct vge_softc *sc)
 {
-	struct ifnet		*ifp = sc->vge_ifp;
-	struct mii_data		*mii;
-	int			error, i;
+	struct ifnet *ifp = sc->vge_ifp;
+	struct mii_data *mii;
+	int error, i;
 
 	VGE_LOCK_ASSERT(sc);
 	mii = device_get_softc(sc->vge_miibus);
@@ -2182,11 +2120,10 @@ vge_init_locked(struct vge_softc *sc)
  * Set media options.
  */
 static int
-vge_ifmedia_upd(ifp)
-	struct ifnet		*ifp;
+vge_ifmedia_upd(struct ifnet *ifp)
 {
-	struct vge_softc	*sc;
-	struct mii_data		*mii;
+	struct vge_softc *sc;
+	struct mii_data *mii;
 
 	sc = ifp->if_softc;
 	VGE_LOCK(sc);
@@ -2201,12 +2138,10 @@ vge_ifmedia_upd(ifp)
  * Report current media status.
  */
 static void
-vge_ifmedia_sts(ifp, ifmr)
-	struct ifnet		*ifp;
-	struct ifmediareq	*ifmr;
+vge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
-	struct vge_softc	*sc;
-	struct mii_data		*mii;
+	struct vge_softc *sc;
+	struct mii_data *mii;
 
 	sc = ifp->if_softc;
 	mii = device_get_softc(sc->vge_miibus);
@@ -2216,17 +2151,14 @@ vge_ifmedia_sts(ifp, ifmr)
 	VGE_UNLOCK(sc);
 	ifmr->ifm_active = mii->mii_media_active;
 	ifmr->ifm_status = mii->mii_media_status;
-
-	return;
 }
 
 static void
-vge_miibus_statchg(dev)
-	device_t		dev;
+vge_miibus_statchg(device_t dev)
 {
-	struct vge_softc	*sc;
-	struct mii_data		*mii;
-	struct ifmedia_entry	*ife;
+	struct vge_softc *sc;
+	struct mii_data *mii;
+	struct ifmedia_entry *ife;
 
 	sc = device_get_softc(dev);
 	mii = device_get_softc(sc->vge_miibus);
@@ -2266,20 +2198,15 @@ vge_miibus_statchg(dev)
 		    IFM_SUBTYPE(ife->ifm_media));
 		break;
 	}
-
-	return;
 }
 
 static int
-vge_ioctl(ifp, command, data)
-	struct ifnet		*ifp;
-	u_long			command;
-	caddr_t			data;
+vge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 {
-	struct vge_softc	*sc = ifp->if_softc;
-	struct ifreq		*ifr = (struct ifreq *) data;
-	struct mii_data		*mii;
-	int			error = 0;
+	struct vge_softc *sc = ifp->if_softc;
+	struct ifreq *ifr = (struct ifreq *) data;
+	struct mii_data *mii;
+	int error = 0;
 
 	switch (command) {
 	case SIOCSIFMTU:
@@ -2331,7 +2258,7 @@ vge_ioctl(ifp, command, data)
 			if (ifr->ifr_reqcap & IFCAP_POLLING) {
 				error = ether_poll_register(vge_poll, ifp);
 				if (error)
-					return(error);
+					return (error);
 				VGE_LOCK(sc);
 					/* Disable interrupts */
 				CSR_WRITE_4(sc, VGE_IMR, 0);
@@ -2394,8 +2321,6 @@ vge_watchdog(void *arg)
 
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	vge_init_locked(sc);
-
-	return;
 }
 
 /*
@@ -2403,10 +2328,9 @@ vge_watchdog(void *arg)
  * RX and TX lists.
  */
 static void
-vge_stop(sc)
-	struct vge_softc		*sc;
+vge_stop(struct vge_softc *sc)
 {
-	struct ifnet		*ifp;
+	struct ifnet *ifp;
 
 	VGE_LOCK_ASSERT(sc);
 	ifp = sc->vge_ifp;
@@ -2433,10 +2357,9 @@ vge_stop(sc)
  * resume.
  */
 static int
-vge_suspend(dev)
-	device_t		dev;
+vge_suspend(device_t dev)
 {
-	struct vge_softc	*sc;
+	struct vge_softc *sc;
 
 	sc = device_get_softc(dev);
 
@@ -2455,11 +2378,10 @@ vge_suspend(dev)
  * appropriate.
  */
 static int
-vge_resume(dev)
-	device_t		dev;
+vge_resume(device_t dev)
 {
-	struct vge_softc	*sc;
-	struct ifnet		*ifp;
+	struct vge_softc *sc;
+	struct ifnet *ifp;
 
 	sc = device_get_softc(dev);
 	ifp = sc->vge_ifp;
@@ -2485,10 +2407,9 @@ vge_resume(dev)
  * get confused by errant DMAs when rebooting.
  */
 static int
-vge_shutdown(dev)
-	device_t		dev;
+vge_shutdown(device_t dev)
 {
-	struct vge_softc		*sc;
+	struct vge_softc *sc;
 
 	sc = device_get_softc(dev);
 
diff --git a/sys/dev/vge/if_vgereg.h b/sys/dev/vge/if_vgereg.h
index b53a21e25d8..a04c3943bf5 100644
--- a/sys/dev/vge/if_vgereg.h
+++ b/sys/dev/vge/if_vgereg.h
@@ -339,19 +339,19 @@
 #define VGE_TXQCSR_RUN0		0x0001	/* Enable TX queue 0 */
 #define VGE_TXQCSR_ACT0		0x0002	/* queue 0 active indicator */
 #define VGE_TXQCSR_WAK0		0x0004	/* Wake up (poll) queue 0 */
-#define VGE_TXQCST_DEAD0	0x0008	/* queue 0 dead indicator */
+#define VGE_TXQCSR_DEAD0	0x0008	/* queue 0 dead indicator */
 #define VGE_TXQCSR_RUN1		0x0010	/* Enable TX queue 1 */
 #define VGE_TXQCSR_ACT1		0x0020	/* queue 1 active indicator */
 #define VGE_TXQCSR_WAK1		0x0040	/* Wake up (poll) queue 1 */
-#define VGE_TXQCST_DEAD1	0x0080	/* queue 1 dead indicator */
+#define VGE_TXQCSR_DEAD1	0x0080	/* queue 1 dead indicator */
 #define VGE_TXQCSR_RUN2		0x0100	/* Enable TX queue 2 */
 #define VGE_TXQCSR_ACT2		0x0200	/* queue 2 active indicator */
 #define VGE_TXQCSR_WAK2		0x0400	/* Wake up (poll) queue 2 */
-#define VGE_TXQCST_DEAD2	0x0800	/* queue 2 dead indicator */
+#define VGE_TXQCSR_DEAD2	0x0800	/* queue 2 dead indicator */
 #define VGE_TXQCSR_RUN3		0x1000	/* Enable TX queue 3 */
 #define VGE_TXQCSR_ACT3		0x2000	/* queue 3 active indicator */
 #define VGE_TXQCSR_WAK3		0x4000	/* Wake up (poll) queue 3 */
-#define VGE_TXQCST_DEAD3	0x8000	/* queue 3 dead indicator */
+#define VGE_TXQCSR_DEAD3	0x8000	/* queue 3 dead indicator */
 
 /* RX descriptor queue control/status register */
 
diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h
index 404d5f5f0f4..7249b8b8fc3 100644
--- a/sys/dev/vge/if_vgevar.h
+++ b/sys/dev/vge/if_vgevar.h
@@ -139,7 +139,7 @@ struct vge_softc {
 	struct resource		*vge_irq;
 	void			*vge_intrhand;
 	device_t		vge_miibus;
-	u_int8_t		vge_type;
+	uint8_t			vge_type;
 	int			vge_if_flags;
 	int			vge_link;
 	int			vge_camidx;

From b79a3f6583630086113f38675c078e1bf4a94b79 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Fri, 8 Jan 2010 22:26:24 +0000
Subject: [PATCH 1064/2592] MFC r200538,200540-200541,200543,200545,200548

r200538:
  Introduce vge_flags member in softc. The vge_flags member will
  record device specific bits. Remove vge_link and use vge_flags.
  While here, move clearing link state before mii_mediachg() as
  mii_mediachg() may affect link state.

r200540:
  Save PHY address by reading VGE_MIICFG register. For PCIe
  controllers(VT613x), we assume the PHY address is 1.
  Use the saved PHY address in MII register access routines and
  remove accessing VGE_MIICFG register.
  While I'm here save PCI express capability register which will be
  used in near future.

r200541:
  Add MSI support for VT613x controllers.

r200543:
  Increase output queue size from 64 to 255.

r200545:
  We don't have to reload EEPROM in vge_reset(). Because vge_reset()
  is called in vge_init_lock(), vge(4) always used to reload EEPROM.
  Also add more comment why vge(4) clears VGE_CHIPCFG0_PACPI bit.
  While I'm here add missing new line in vge_reset().

r200548:
  Sort function prototyes.
---
 sys/dev/vge/if_vge.c    | 187 +++++++++++++++++++++++-----------------
 sys/dev/vge/if_vgevar.h |   9 +-
 2 files changed, 114 insertions(+), 82 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index a8d2bc3a44f..d94e3a82a6a 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -127,6 +127,10 @@ MODULE_DEPEND(vge, miibus, 1, 1, 1);
 
 #define VGE_CSUM_FEATURES    (CSUM_IP | CSUM_TCP | CSUM_UDP)
 
+/* Tunables */
+static int msi_disable = 0;
+TUNABLE_INT("hw.vge.msi_disable", &msi_disable);
+
 /*
  * Various supported device vendors/types and their names.
  */
@@ -136,56 +140,52 @@ static struct vge_type vge_devs[] = {
 	{ 0, 0, NULL }
 };
 
-static int vge_probe		(device_t);
-static int vge_attach		(device_t);
-static int vge_detach		(device_t);
-
-static int vge_encap		(struct vge_softc *, struct mbuf **);
-
-static void vge_dmamap_cb	(void *, bus_dma_segment_t *, int, int);
-static int vge_dma_alloc	(struct vge_softc *);
-static void vge_dma_free	(struct vge_softc *);
-static void vge_discard_rxbuf	(struct vge_softc *, int);
-static int vge_newbuf		(struct vge_softc *, int);
-static int vge_rx_list_init	(struct vge_softc *);
-static int vge_tx_list_init	(struct vge_softc *);
-static void vge_freebufs	(struct vge_softc *);
-#ifndef __NO_STRICT_ALIGNMENT
-static __inline void vge_fixup_rx
-				(struct mbuf *);
-#endif
-static int vge_rxeof		(struct vge_softc *, int);
-static void vge_txeof		(struct vge_softc *);
-static void vge_intr		(void *);
-static void vge_tick		(void *);
-static void vge_start		(struct ifnet *);
-static void vge_start_locked	(struct ifnet *);
-static int vge_ioctl		(struct ifnet *, u_long, caddr_t);
-static void vge_init		(void *);
-static void vge_init_locked	(struct vge_softc *);
-static void vge_stop		(struct vge_softc *);
-static void vge_watchdog	(void *);
-static int vge_suspend		(device_t);
-static int vge_resume		(device_t);
-static int vge_shutdown		(device_t);
-static int vge_ifmedia_upd	(struct ifnet *);
-static void vge_ifmedia_sts	(struct ifnet *, struct ifmediareq *);
+static int	vge_attach(device_t);
+static int	vge_detach(device_t);
+static int	vge_probe(device_t);
+static int	vge_resume(device_t);
+static int	vge_shutdown(device_t);
+static int	vge_suspend(device_t);
 
+static void	vge_cam_clear(struct vge_softc *);
+static int	vge_cam_set(struct vge_softc *, uint8_t *);
+static void	vge_discard_rxbuf(struct vge_softc *, int);
+static int	vge_dma_alloc(struct vge_softc *);
+static void	vge_dma_free(struct vge_softc *);
+static void	vge_dmamap_cb(void *, bus_dma_segment_t *, int, int);
 #ifdef VGE_EEPROM
-static void vge_eeprom_getword	(struct vge_softc *, int, uint16_t *);
+static void	vge_eeprom_getword(struct vge_softc *, int, uint16_t *);
 #endif
-static void vge_read_eeprom	(struct vge_softc *, caddr_t, int, int, int);
-
-static void vge_miipoll_start	(struct vge_softc *);
-static void vge_miipoll_stop	(struct vge_softc *);
-static int vge_miibus_readreg	(device_t, int, int);
-static int vge_miibus_writereg	(device_t, int, int, int);
-static void vge_miibus_statchg	(device_t);
-
-static void vge_cam_clear	(struct vge_softc *);
-static int vge_cam_set		(struct vge_softc *, uint8_t *);
-static void vge_setmulti	(struct vge_softc *);
-static void vge_reset		(struct vge_softc *);
+static int	vge_encap(struct vge_softc *, struct mbuf **);
+#ifndef __NO_STRICT_ALIGNMENT
+static __inline void
+		vge_fixup_rx(struct mbuf *);
+#endif
+static void	vge_freebufs(struct vge_softc *);
+static void	vge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+static int	vge_ifmedia_upd(struct ifnet *);
+static void	vge_init(void *);
+static void	vge_init_locked(struct vge_softc *);
+static void	vge_intr(void *);
+static int	vge_ioctl(struct ifnet *, u_long, caddr_t);
+static int	vge_miibus_readreg(device_t, int, int);
+static void	vge_miibus_statchg(device_t);
+static int	vge_miibus_writereg(device_t, int, int, int);
+static void	vge_miipoll_start(struct vge_softc *);
+static void	vge_miipoll_stop(struct vge_softc *);
+static int	vge_newbuf(struct vge_softc *, int);
+static void	vge_read_eeprom(struct vge_softc *, caddr_t, int, int, int);
+static void	vge_reset(struct vge_softc *);
+static int	vge_rx_list_init(struct vge_softc *);
+static int	vge_rxeof(struct vge_softc *, int);
+static void	vge_setmulti(struct vge_softc *);
+static void	vge_start(struct ifnet *);
+static void	vge_start_locked(struct ifnet *);
+static void	vge_stop(struct vge_softc *);
+static void	vge_tick(void *);
+static int	vge_tx_list_init(struct vge_softc *);
+static void	vge_txeof(struct vge_softc *);
+static void	vge_watchdog(void *);
 
 static device_method_t vge_methods[] = {
 	/* Device interface */
@@ -353,7 +353,7 @@ vge_miibus_readreg(device_t dev, int phy, int reg)
 
 	sc = device_get_softc(dev);
 
-	if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
+	if (phy != sc->vge_phyaddr)
 		return (0);
 
 	vge_miipoll_stop(sc);
@@ -389,7 +389,7 @@ vge_miibus_writereg(device_t dev, int phy, int reg, int data)
 
 	sc = device_get_softc(dev);
 
-	if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
+	if (phy != sc->vge_phyaddr)
 		return (0);
 
 	vge_miipoll_stop(sc);
@@ -582,27 +582,12 @@ vge_reset(struct vge_softc *sc)
 	}
 
 	if (i == VGE_TIMEOUT) {
-		device_printf(sc->vge_dev, "soft reset timed out");
+		device_printf(sc->vge_dev, "soft reset timed out\n");
 		CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_STOP_FORCE);
 		DELAY(2000);
 	}
 
 	DELAY(5000);
-
-	CSR_SETBIT_1(sc, VGE_EECSR, VGE_EECSR_RELOAD);
-
-	for (i = 0; i < VGE_TIMEOUT; i++) {
-		DELAY(5);
-		if ((CSR_READ_1(sc, VGE_EECSR) & VGE_EECSR_RELOAD) == 0)
-			break;
-	}
-
-	if (i == VGE_TIMEOUT) {
-		device_printf(sc->vge_dev, "EEPROM reload timed out\n");
-		return;
-	}
-
-	CSR_CLRBIT_1(sc, VGE_CHIPCFG0, VGE_CHIPCFG0_PACPI);
 }
 
 /*
@@ -954,7 +939,7 @@ vge_attach(device_t dev)
 	u_char eaddr[ETHER_ADDR_LEN];
 	struct vge_softc *sc;
 	struct ifnet *ifp;
-	int error = 0, rid;
+	int error = 0, cap, i, msic, rid;
 
 	sc = device_get_softc(dev);
 	sc->vge_dev = dev;
@@ -978,11 +963,28 @@ vge_attach(device_t dev)
 		goto fail;
 	}
 
-	/* Allocate interrupt */
+	if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) == 0) {
+		sc->vge_flags |= VGE_FLAG_PCIE;
+		sc->vge_expcap = cap;
+	}
 	rid = 0;
-	sc->vge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
-	    RF_SHAREABLE | RF_ACTIVE);
+	msic = pci_msi_count(dev);
+	if (msi_disable == 0 && msic > 0) {
+		msic = 1;
+		if (pci_alloc_msi(dev, &msic) == 0) {
+			if (msic == 1) {
+				sc->vge_flags |= VGE_FLAG_MSI;
+				device_printf(dev, "Using %d MSI message\n",
+				    msic);
+				rid = 1;
+			} else
+				pci_release_msi(dev);
+		}
+	}
 
+	/* Allocate interrupt */
+	sc->vge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    ((sc->vge_flags & VGE_FLAG_MSI) ? 0 : RF_SHAREABLE) | RF_ACTIVE);
 	if (sc->vge_irq == NULL) {
 		device_printf(dev, "couldn't map interrupt\n");
 		error = ENXIO;
@@ -991,12 +993,37 @@ vge_attach(device_t dev)
 
 	/* Reset the adapter. */
 	vge_reset(sc);
+	/* Reload EEPROM. */
+	CSR_WRITE_1(sc, VGE_EECSR, VGE_EECSR_RELOAD);
+	for (i = 0; i < VGE_TIMEOUT; i++) {
+		DELAY(5);
+		if ((CSR_READ_1(sc, VGE_EECSR) & VGE_EECSR_RELOAD) == 0)
+			break;
+	}
+	if (i == VGE_TIMEOUT)
+		device_printf(dev, "EEPROM reload timed out\n");
+	/*
+	 * Clear PACPI as EEPROM reload will set the bit. Otherwise
+	 * MAC will receive magic packet which in turn confuses
+	 * controller.
+	 */
+	CSR_CLRBIT_1(sc, VGE_CHIPCFG0, VGE_CHIPCFG0_PACPI);
 
 	/*
 	 * Get station address from the EEPROM.
 	 */
 	vge_read_eeprom(sc, (caddr_t)eaddr, VGE_EE_EADDR, 3, 0);
-
+	/*
+	 * Save configured PHY address.
+	 * It seems the PHY address of PCIe controllers just
+	 * reflects media jump strapping status so we assume the
+	 * internal PHY address of PCIe controller is at 1.
+	 */
+	if ((sc->vge_flags & VGE_FLAG_PCIE) != 0)
+		sc->vge_phyaddr = 1;
+	else
+		sc->vge_phyaddr = CSR_READ_1(sc, VGE_MIICFG) &
+		    VGE_MIICFG_PHYADDR;
 	error = vge_dma_alloc(sc);
 	if (error)
 		goto fail;
@@ -1030,8 +1057,8 @@ vge_attach(device_t dev)
 	ifp->if_capabilities |= IFCAP_POLLING;
 #endif
 	ifp->if_init = vge_init;
-	IFQ_SET_MAXLEN(&ifp->if_snd, VGE_IFQ_MAXLEN);
-	ifp->if_snd.ifq_drv_maxlen = VGE_IFQ_MAXLEN;
+	IFQ_SET_MAXLEN(&ifp->if_snd, VGE_TX_DESC_CNT - 1);
+	ifp->if_snd.ifq_drv_maxlen = VGE_TX_DESC_CNT - 1;
 	IFQ_SET_READY(&ifp->if_snd);
 
 	/*
@@ -1093,7 +1120,10 @@ vge_detach(device_t dev)
 	if (sc->vge_intrhand)
 		bus_teardown_intr(dev, sc->vge_irq, sc->vge_intrhand);
 	if (sc->vge_irq)
-		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vge_irq);
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    sc->vge_flags & VGE_FLAG_MSI ? 1 : 0, sc->vge_irq);
+	if (sc->vge_flags & VGE_FLAG_MSI)
+		pci_release_msi(dev);
 	if (sc->vge_res)
 		bus_release_resource(dev, SYS_RES_MEMORY,
 		    PCIR_BAR(1), sc->vge_res);
@@ -1577,16 +1607,16 @@ vge_tick(void *xsc)
 	mii = device_get_softc(sc->vge_miibus);
 
 	mii_tick(mii);
-	if (sc->vge_link) {
+	if ((sc->vge_flags & VGE_FLAG_LINK) != 0) {
 		if (!(mii->mii_media_status & IFM_ACTIVE)) {
-			sc->vge_link = 0;
+			sc->vge_flags &= ~VGE_FLAG_LINK;
 			if_link_state_change(sc->vge_ifp,
 			    LINK_STATE_DOWN);
 		}
 	} else {
 		if (mii->mii_media_status & IFM_ACTIVE &&
 		    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
-			sc->vge_link = 1;
+			sc->vge_flags |= VGE_FLAG_LINK;
 			if_link_state_change(sc->vge_ifp,
 			    LINK_STATE_UP);
 			if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
@@ -1868,7 +1898,7 @@ vge_start_locked(struct ifnet *ifp)
 
 	VGE_LOCK_ASSERT(sc);
 
-	if (sc->vge_link == 0 ||
+	if ((sc->vge_flags & VGE_FLAG_LINK) == 0 ||
 	    (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
 	    IFF_DRV_RUNNING)
 		return;
@@ -2107,13 +2137,12 @@ vge_init_locked(struct vge_softc *sc)
 		CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
 	}
 
+	sc->vge_flags &= ~VGE_FLAG_LINK;
 	mii_mediachg(mii);
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	callout_reset(&sc->vge_watchdog, hz, vge_watchdog, sc);
-
-	sc->vge_link = 0;
 }
 
 /*
diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h
index 7249b8b8fc3..ec3edbad986 100644
--- a/sys/dev/vge/if_vgevar.h
+++ b/sys/dev/vge/if_vgevar.h
@@ -34,8 +34,6 @@
 
 #define VGE_JUMBO_MTU	9000
 
-#define VGE_IFQ_MAXLEN 64
-
 #define VGE_TX_DESC_CNT		256
 #define VGE_RX_DESC_CNT		252	/* Must be a multiple of 4!! */
 #define VGE_TX_RING_ALIGN	64
@@ -141,7 +139,12 @@ struct vge_softc {
 	device_t		vge_miibus;
 	uint8_t			vge_type;
 	int			vge_if_flags;
-	int			vge_link;
+	int			vge_phyaddr;
+	int			vge_flags;
+#define	VGE_FLAG_PCIE		0x0001
+#define	VGE_FLAG_MSI		0x0002
+#define	VGE_FLAG_LINK		0x8000
+	int			vge_expcap;
 	int			vge_camidx;
 	struct mtx		vge_mtx;
 	struct callout		vge_watchdog;

From b90779265517284024c49f5ac34660de57815851 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Sat, 9 Jan 2010 00:02:40 +0000
Subject: [PATCH 1065/2592] MFC r200551-200552,200555,200558,200609,200613

r200551:
  Whenever link state change interrupt is raised, vge_tick() is
  called and vge(4) used to drive auto-negotiation timer(mii_tick) in
  vge_tick(). Therefore the mii_tick was not called for every hz such
  that auto-negotiation complete was never handled in vge(4).
  Use mii_pollstat to extract current negotiated speed/duplex instead
  of mii_tick. The latter is valid only for auto-negotiation case.
  While I'm here change the confusing function name vge_tick() to
  vge_link_statchg().

r200552:
  Report media change result to caller instead of returning success
  without regard to the result.

r200555:
  Don't report current link status if interface is not UP.
  If interface is not UP, the current link status wouldn't
  reflect the negotiated status.

r200558:
  Tell upper layer vge(4) supports long frames. This should be done
  after ether_ifattach(), as ether_ifattach() initializes it with
  ETHER_HDR_LEN.
  While I'm here remove setting if_mtu, it's already handled in
  ether_ifattach().

r200609:
  All vge(4) controllers support RX/TX checksum offloading for VLAN
  tagged frames so add checksum offloading capabilities. Also add
  missing VLAN hardware tagging control in ioctl handler and let
  upper stack know current VLAN capabilities.

r200613:
  Rewrite RX filter setup and simplify code.
  Now promiscuous mode and multicast handling is performed in single
  function, vge_rxfilter().
---
 sys/dev/vge/if_vge.c | 161 ++++++++++++++++++++++++-------------------
 1 file changed, 91 insertions(+), 70 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index d94e3a82a6a..0c7cc61bd17 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -168,6 +168,7 @@ static void	vge_init(void *);
 static void	vge_init_locked(struct vge_softc *);
 static void	vge_intr(void *);
 static int	vge_ioctl(struct ifnet *, u_long, caddr_t);
+static void	vge_link_statchg(void *);
 static int	vge_miibus_readreg(device_t, int, int);
 static void	vge_miibus_statchg(device_t);
 static int	vge_miibus_writereg(device_t, int, int, int);
@@ -178,11 +179,11 @@ static void	vge_read_eeprom(struct vge_softc *, caddr_t, int, int, int);
 static void	vge_reset(struct vge_softc *);
 static int	vge_rx_list_init(struct vge_softc *);
 static int	vge_rxeof(struct vge_softc *, int);
-static void	vge_setmulti(struct vge_softc *);
+static void	vge_rxfilter(struct vge_softc *);
+static void	vge_setvlan(struct vge_softc *);
 static void	vge_start(struct ifnet *);
 static void	vge_start_locked(struct ifnet *);
 static void	vge_stop(struct vge_softc *);
-static void	vge_tick(void *);
 static int	vge_tx_list_init(struct vge_softc *);
 static void	vge_txeof(struct vge_softc *);
 static void	vge_watchdog(void *);
@@ -504,38 +505,66 @@ fail:
 	return (error);
 }
 
+static void
+vge_setvlan(struct vge_softc *sc)
+{
+	struct ifnet *ifp;
+	uint8_t cfg;
+
+	VGE_LOCK_ASSERT(sc);
+
+	ifp = sc->vge_ifp;
+	cfg = CSR_READ_1(sc, VGE_RXCFG);
+	if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0)
+		cfg |= VGE_VTAG_OPT2;
+	else
+		cfg &= ~VGE_VTAG_OPT2;
+	CSR_WRITE_1(sc, VGE_RXCFG, cfg);
+}
+
 /*
  * Program the multicast filter. We use the 64-entry CAM filter
  * for perfect filtering. If there's more than 64 multicast addresses,
  * we use the hash filter instead.
  */
 static void
-vge_setmulti(struct vge_softc *sc)
+vge_rxfilter(struct vge_softc *sc)
 {
 	struct ifnet *ifp;
-	int error = 0/*, h = 0*/;
 	struct ifmultiaddr *ifma;
-	uint32_t h, hashes[2] = { 0, 0 };
+	uint32_t h, hashes[2];
+	uint8_t rxcfg;
+	int error = 0;
 
 	VGE_LOCK_ASSERT(sc);
 
-	ifp = sc->vge_ifp;
-
 	/* First, zot all the multicast entries. */
-	vge_cam_clear(sc);
-	CSR_WRITE_4(sc, VGE_MAR0, 0);
-	CSR_WRITE_4(sc, VGE_MAR1, 0);
+	hashes[0] = 0;
+	hashes[1] = 0;
 
+	rxcfg = CSR_READ_1(sc, VGE_RXCTL);
+	rxcfg &= ~(VGE_RXCTL_RX_MCAST | VGE_RXCTL_RX_BCAST |
+	    VGE_RXCTL_RX_PROMISC);
 	/*
-	 * If the user wants allmulti or promisc mode, enable reception
-	 * of all multicast frames.
+	 * Always allow VLAN oversized frames and frames for
+	 * this host.
 	 */
-	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
-		CSR_WRITE_4(sc, VGE_MAR0, 0xFFFFFFFF);
-		CSR_WRITE_4(sc, VGE_MAR1, 0xFFFFFFFF);
-		return;
+	rxcfg |= VGE_RXCTL_RX_GIANT | VGE_RXCTL_RX_UCAST;
+
+	ifp = sc->vge_ifp;
+	if ((ifp->if_flags & IFF_BROADCAST) != 0)
+		rxcfg |= VGE_RXCTL_RX_BCAST;
+	if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
+		if ((ifp->if_flags & IFF_PROMISC) != 0)
+			rxcfg |= VGE_RXCTL_RX_PROMISC;
+		if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
+			hashes[0] = 0xFFFFFFFF;
+			hashes[1] = 0xFFFFFFFF;
+		}
+		goto done;
 	}
 
+	vge_cam_clear(sc);
 	/* Now program new ones */
 	if_maddr_rlock(ifp);
 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
@@ -561,11 +590,15 @@ vge_setmulti(struct vge_softc *sc)
 			else
 				hashes[1] |= (1 << (h - 32));
 		}
-
-		CSR_WRITE_4(sc, VGE_MAR0, hashes[0]);
-		CSR_WRITE_4(sc, VGE_MAR1, hashes[1]);
 	}
 	if_maddr_runlock(ifp);
+
+done:
+	if (hashes[0] != 0 || hashes[1] != 0)
+		rxcfg |= VGE_RXCTL_RX_MCAST;
+	CSR_WRITE_4(sc, VGE_MAR0, hashes[0]);
+	CSR_WRITE_4(sc, VGE_MAR1, hashes[1]);
+	CSR_WRITE_1(sc, VGE_RXCTL, rxcfg);
 }
 
 static void
@@ -1045,13 +1078,13 @@ vge_attach(device_t dev)
 
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-	ifp->if_mtu = ETHERMTU;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = vge_ioctl;
 	ifp->if_capabilities = IFCAP_VLAN_MTU;
 	ifp->if_start = vge_start;
 	ifp->if_hwassist = VGE_CSUM_FEATURES;
-	ifp->if_capabilities |= IFCAP_HWCSUM|IFCAP_VLAN_HWTAGGING;
+	ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM |
+	    IFCAP_VLAN_HWTAGGING;
 	ifp->if_capenable = ifp->if_capabilities;
 #ifdef DEVICE_POLLING
 	ifp->if_capabilities |= IFCAP_POLLING;
@@ -1066,6 +1099,9 @@ vge_attach(device_t dev)
 	 */
 	ether_ifattach(ifp, eaddr);
 
+	/* Tell the upper layer(s) we support long frames. */
+	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
+
 	/* Hook interrupt last to avoid having to lock softc */
 	error = bus_setup_intr(dev, sc->vge_irq, INTR_TYPE_NET|INTR_MPSAFE,
 	    NULL, vge_intr, sc, &sc->vge_intrhand);
@@ -1595,7 +1631,7 @@ vge_txeof(struct vge_softc *sc)
 }
 
 static void
-vge_tick(void *xsc)
+vge_link_statchg(void *xsc)
 {
 	struct vge_softc *sc;
 	struct ifnet *ifp;
@@ -1606,7 +1642,7 @@ vge_tick(void *xsc)
 	VGE_LOCK_ASSERT(sc);
 	mii = device_get_softc(sc->vge_miibus);
 
-	mii_tick(mii);
+	mii_pollstat(mii);
 	if ((sc->vge_flags & VGE_FLAG_LINK) != 0) {
 		if (!(mii->mii_media_status & IFM_ACTIVE)) {
 			sc->vge_flags &= ~VGE_FLAG_LINK;
@@ -1735,7 +1771,7 @@ vge_intr(void *arg)
 		}
 
 		if (status & VGE_ISR_LINKSTS)
-			vge_tick(sc);
+			vge_link_statchg(sc);
 	}
 
 	/* Re-enable interrupts */
@@ -2008,7 +2044,7 @@ vge_init_locked(struct vge_softc *sc)
 	 * reception of VLAN tagged frames.
 	 */
 	CSR_CLRBIT_1(sc, VGE_RXCFG, VGE_RXCFG_FIFO_THR|VGE_RXCFG_VTAGOPT);
-	CSR_SETBIT_1(sc, VGE_RXCFG, VGE_RXFIFOTHR_128BYTES|VGE_VTAG_OPT2);
+	CSR_SETBIT_1(sc, VGE_RXCFG, VGE_RXFIFOTHR_128BYTES);
 
 	/* Set DMA burst length */
 	CSR_CLRBIT_1(sc, VGE_DMACFG0, VGE_DMACFG0_BURSTLEN);
@@ -2047,29 +2083,12 @@ vge_init_locked(struct vge_softc *sc)
 	/* Enable the TX descriptor queue */
 	CSR_WRITE_2(sc, VGE_TXQCSRS, VGE_TXQCSR_RUN0);
 
-	/* Set up the receive filter -- allow large frames for VLANs. */
-	CSR_WRITE_1(sc, VGE_RXCTL, VGE_RXCTL_RX_UCAST|VGE_RXCTL_RX_GIANT);
-
-	/* If we want promiscuous mode, set the allframes bit. */
-	if (ifp->if_flags & IFF_PROMISC) {
-		CSR_SETBIT_1(sc, VGE_RXCTL, VGE_RXCTL_RX_PROMISC);
-	}
-
-	/* Set capture broadcast bit to capture broadcast frames. */
-	if (ifp->if_flags & IFF_BROADCAST) {
-		CSR_SETBIT_1(sc, VGE_RXCTL, VGE_RXCTL_RX_BCAST);
-	}
-
-	/* Set multicast bit to capture multicast frames. */
-	if (ifp->if_flags & IFF_MULTICAST) {
-		CSR_SETBIT_1(sc, VGE_RXCTL, VGE_RXCTL_RX_MCAST);
-	}
-
 	/* Init the cam filter. */
 	vge_cam_clear(sc);
 
-	/* Init the multicast filter. */
-	vge_setmulti(sc);
+	/* Set up receiver filter. */
+	vge_rxfilter(sc);
+	vge_setvlan(sc);
 
 	/* Enable flow control */
 
@@ -2153,14 +2172,15 @@ vge_ifmedia_upd(struct ifnet *ifp)
 {
 	struct vge_softc *sc;
 	struct mii_data *mii;
+	int error;
 
 	sc = ifp->if_softc;
 	VGE_LOCK(sc);
 	mii = device_get_softc(sc->vge_miibus);
-	mii_mediachg(mii);
+	error = mii_mediachg(mii);
 	VGE_UNLOCK(sc);
 
-	return (0);
+	return (error);
 }
 
 /*
@@ -2176,6 +2196,10 @@ vge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 	mii = device_get_softc(sc->vge_miibus);
 
 	VGE_LOCK(sc);
+	if ((ifp->if_flags & IFF_UP) == 0) {
+		VGE_UNLOCK(sc);
+		return;
+	}
 	mii_pollstat(mii);
 	VGE_UNLOCK(sc);
 	ifmr->ifm_active = mii->mii_media_active;
@@ -2235,7 +2259,7 @@ vge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 	struct vge_softc *sc = ifp->if_softc;
 	struct ifreq *ifr = (struct ifreq *) data;
 	struct mii_data *mii;
-	int error = 0;
+	int error = 0, mask;
 
 	switch (command) {
 	case SIOCSIFMTU:
@@ -2245,25 +2269,15 @@ vge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 		break;
 	case SIOCSIFFLAGS:
 		VGE_LOCK(sc);
-		if (ifp->if_flags & IFF_UP) {
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
-			    ifp->if_flags & IFF_PROMISC &&
-			    !(sc->vge_if_flags & IFF_PROMISC)) {
-				CSR_SETBIT_1(sc, VGE_RXCTL,
-				    VGE_RXCTL_RX_PROMISC);
-				vge_setmulti(sc);
-			} else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
-			    !(ifp->if_flags & IFF_PROMISC) &&
-			    sc->vge_if_flags & IFF_PROMISC) {
-				CSR_CLRBIT_1(sc, VGE_RXCTL,
-				    VGE_RXCTL_RX_PROMISC);
-				vge_setmulti(sc);
-                        } else
+		if ((ifp->if_flags & IFF_UP) != 0) {
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
+			    ((ifp->if_flags ^ sc->vge_if_flags) &
+			    (IFF_PROMISC | IFF_ALLMULTI)) != 0)
+				vge_rxfilter(sc);
+			else
 				vge_init_locked(sc);
-		} else {
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-				vge_stop(sc);
-		}
+		} else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+			vge_stop(sc);
 		sc->vge_if_flags = ifp->if_flags;
 		VGE_UNLOCK(sc);
 		break;
@@ -2271,7 +2285,7 @@ vge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 	case SIOCDELMULTI:
 		VGE_LOCK(sc);
 		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-			vge_setmulti(sc);
+			vge_rxfilter(sc);
 		VGE_UNLOCK(sc);
 		break;
 	case SIOCGIFMEDIA:
@@ -2280,8 +2294,7 @@ vge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 		break;
 	case SIOCSIFCAP:
-	    {
-		int mask = ifr->ifr_reqcap ^ ifp->if_capenable;
+		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 #ifdef DEVICE_POLLING
 		if (mask & IFCAP_POLLING) {
 			if (ifr->ifr_reqcap & IFCAP_POLLING) {
@@ -2318,8 +2331,16 @@ vge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 		if ((mask & IFCAP_RXCSUM) != 0 &&
 		    (ifp->if_capabilities & IFCAP_RXCSUM) != 0)
 			ifp->if_capenable ^= IFCAP_RXCSUM;
+		if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
+		    (ifp->if_capabilities & IFCAP_VLAN_HWCSUM) != 0)
+			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
+		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
+		    (IFCAP_VLAN_HWTAGGING & ifp->if_capabilities) != 0) {
+			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
+			vge_setvlan(sc);
+		}
 		VGE_UNLOCK(sc);
-	    }
+		VLAN_CAPABILITIES(ifp);
 		break;
 	default:
 		error = ether_ioctl(ifp, command, data);

From 2e04b85932d3a894a02efba06c8d3899a21afa4a Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Sat, 9 Jan 2010 00:07:03 +0000
Subject: [PATCH 1066/2592] MFC 200615:   Add hardware MAC statistics support.
 This statistics could be   extracted from dev.vge.%d.stats sysctl node.

---
 sys/dev/vge/if_vge.c    | 238 +++++++++++++++++++++++++++++++++++++++-
 sys/dev/vge/if_vgereg.h |  50 ++++++++-
 sys/dev/vge/if_vgevar.h |  37 +++++++
 3 files changed, 322 insertions(+), 3 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index 0c7cc61bd17..be785c1b646 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -131,6 +132,13 @@ MODULE_DEPEND(vge, miibus, 1, 1, 1);
 static int msi_disable = 0;
 TUNABLE_INT("hw.vge.msi_disable", &msi_disable);
 
+/*
+ * The SQE error counter of MIB seems to report bogus value.
+ * Vendor's workaround does not seem to work on PCIe based
+ * controllers. Disable it until we find better workaround.
+ */
+#undef VGE_ENABLE_SQEERR
+
 /*
  * Various supported device vendors/types and their names.
  */
@@ -183,7 +191,10 @@ static void	vge_rxfilter(struct vge_softc *);
 static void	vge_setvlan(struct vge_softc *);
 static void	vge_start(struct ifnet *);
 static void	vge_start_locked(struct ifnet *);
+static void	vge_stats_clear(struct vge_softc *);
+static void	vge_stats_update(struct vge_softc *);
 static void	vge_stop(struct vge_softc *);
+static void	vge_sysctl_node(struct vge_softc *);
 static int	vge_tx_list_init(struct vge_softc *);
 static void	vge_txeof(struct vge_softc *);
 static void	vge_watchdog(void *);
@@ -1057,6 +1068,7 @@ vge_attach(device_t dev)
 	else
 		sc->vge_phyaddr = CSR_READ_1(sc, VGE_MIICFG) &
 		    VGE_MIICFG_PHYADDR;
+	vge_sysctl_node(sc);
 	error = vge_dma_alloc(sc);
 	if (error)
 		goto fail;
@@ -1698,7 +1710,6 @@ vge_poll (struct ifnet *ifp, enum poll_cmd cmd, int count)
 
 		if (status & (VGE_ISR_RXOFLOW|VGE_ISR_RXNODESC)) {
 			vge_rxeof(sc, count);
-			ifp->if_ierrors++;
 			CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_RUN);
 			CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_WAK);
 		}
@@ -2034,7 +2045,8 @@ vge_init_locked(struct vge_softc *sc)
                 return;
 	}
 	vge_tx_list_init(sc);
-
+	/* Clear MAC statistics. */
+	vge_stats_clear(sc);
 	/* Set our station address */
 	for (i = 0; i < ETHER_ADDR_LEN; i++)
 		CSR_WRITE_1(sc, VGE_PAR0 + i, IF_LLADDR(sc->vge_ifp)[i]);
@@ -2358,6 +2370,7 @@ vge_watchdog(void *arg)
 
 	sc = arg;
 	VGE_LOCK_ASSERT(sc);
+	vge_stats_update(sc);
 	callout_reset(&sc->vge_watchdog, hz, vge_watchdog, sc);
 	if (sc->vge_timer == 0 || --sc->vge_timer > 0)
 		return;
@@ -2396,6 +2409,7 @@ vge_stop(struct vge_softc *sc)
 	CSR_WRITE_1(sc, VGE_RXQCSRC, 0xFF);
 	CSR_WRITE_4(sc, VGE_RXDESC_ADDR_LO, 0);
 
+	vge_stats_update(sc);
 	VGE_CHAIN_RESET(sc);
 	vge_txeof(sc);
 	vge_freebufs(sc);
@@ -2469,3 +2483,223 @@ vge_shutdown(device_t dev)
 
 	return (0);
 }
+
+#define	VGE_SYSCTL_STAT_ADD32(c, h, n, p, d)	\
+	    SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
+
+static void
+vge_sysctl_node(struct vge_softc *sc)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid_list *child, *parent;
+	struct sysctl_oid *tree;
+	struct vge_hw_stats *stats;
+
+	stats = &sc->vge_stats;
+	ctx = device_get_sysctl_ctx(sc->vge_dev);
+	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vge_dev));
+	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
+	    NULL, "VGE statistics");
+	parent = SYSCTL_CHILDREN(tree);
+
+	/* Rx statistics. */
+	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "rx", CTLFLAG_RD,
+	    NULL, "RX MAC statistics");
+	child = SYSCTL_CHILDREN(tree);
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames",
+	    &stats->rx_frames, "frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
+	    &stats->rx_good_frames, "Good frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "fifo_oflows",
+	    &stats->rx_fifo_oflows, "FIFO overflows");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "runts",
+	    &stats->rx_runts, "Too short frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "runts_errs",
+	    &stats->rx_runts_errs, "Too short frames with errors");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_64",
+	    &stats->rx_pkts_64, "64 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_65_127",
+	    &stats->rx_pkts_65_127, "65 to 127 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_128_255",
+	    &stats->rx_pkts_128_255, "128 to 255 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_256_511",
+	    &stats->rx_pkts_256_511, "256 to 511 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_512_1023",
+	    &stats->rx_pkts_512_1023, "512 to 1023 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_1024_1518",
+	    &stats->rx_pkts_1024_1518, "1024 to 1518 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_1519_max",
+	    &stats->rx_pkts_1519_max, "1519 to max frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_1519_max_errs",
+	    &stats->rx_pkts_1519_max_errs, "1519 to max frames with error");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_jumbo",
+	    &stats->rx_jumbos, "Jumbo frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "crcerrs",
+	    &stats->rx_crcerrs, "CRC errors");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "pause_frames",
+	    &stats->rx_pause_frames, "CRC errors");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "align_errs",
+	    &stats->rx_alignerrs, "Alignment errors");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "nobufs",
+	    &stats->rx_nobufs, "Frames with no buffer event");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "sym_errs",
+	    &stats->rx_symerrs, "Frames with symbol errors");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "len_errs",
+	    &stats->rx_lenerrs, "Frames with length mismatched");
+
+	/* Tx statistics. */
+	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
+	    NULL, "TX MAC statistics");
+	child = SYSCTL_CHILDREN(tree);
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
+	    &stats->tx_good_frames, "Good frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_64",
+	    &stats->tx_pkts_64, "64 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_65_127",
+	    &stats->tx_pkts_65_127, "65 to 127 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_128_255",
+	    &stats->tx_pkts_128_255, "128 to 255 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_256_511",
+	    &stats->tx_pkts_256_511, "256 to 511 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_512_1023",
+	    &stats->tx_pkts_512_1023, "512 to 1023 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_1024_1518",
+	    &stats->tx_pkts_1024_1518, "1024 to 1518 bytes frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "frames_jumbo",
+	    &stats->tx_jumbos, "Jumbo frames");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "colls",
+	    &stats->tx_colls, "Collisions");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "late_colls",
+	    &stats->tx_latecolls, "Late collisions");
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "pause_frames",
+	    &stats->tx_pause, "Pause frames");
+#ifdef VGE_ENABLE_SQEERR
+	VGE_SYSCTL_STAT_ADD32(ctx, child, "sqeerrs",
+	    &stats->tx_sqeerrs, "SQE errors");
+#endif
+	/* Clear MAC statistics. */
+	vge_stats_clear(sc);
+}
+
+#undef	VGE_SYSCTL_STAT_ADD32
+
+static void
+vge_stats_clear(struct vge_softc *sc)
+{
+	int i;
+
+	VGE_LOCK_ASSERT(sc);
+
+	CSR_WRITE_1(sc, VGE_MIBCSR,
+	    CSR_READ_1(sc, VGE_MIBCSR) | VGE_MIBCSR_FREEZE);
+	CSR_WRITE_1(sc, VGE_MIBCSR,
+	    CSR_READ_1(sc, VGE_MIBCSR) | VGE_MIBCSR_CLR);
+	for (i = VGE_TIMEOUT; i > 0; i--) {
+		DELAY(1);
+		if ((CSR_READ_1(sc, VGE_MIBCSR) & VGE_MIBCSR_CLR) == 0)
+			break;
+	}
+	if (i == 0)
+		device_printf(sc->vge_dev, "MIB clear timed out!\n");
+	CSR_WRITE_1(sc, VGE_MIBCSR, CSR_READ_1(sc, VGE_MIBCSR) &
+	    ~VGE_MIBCSR_FREEZE);
+}
+
+static void
+vge_stats_update(struct vge_softc *sc)
+{
+	struct vge_hw_stats *stats;
+	struct ifnet *ifp;
+	uint32_t mib[VGE_MIB_CNT], val;
+	int i;
+
+	VGE_LOCK_ASSERT(sc);
+
+	stats = &sc->vge_stats;
+	ifp = sc->vge_ifp;
+
+	CSR_WRITE_1(sc, VGE_MIBCSR,
+	    CSR_READ_1(sc, VGE_MIBCSR) | VGE_MIBCSR_FLUSH);
+	for (i = VGE_TIMEOUT; i > 0; i--) {
+		DELAY(1);
+		if ((CSR_READ_1(sc, VGE_MIBCSR) & VGE_MIBCSR_FLUSH) == 0)
+			break;
+	}
+	if (i == 0) {
+		device_printf(sc->vge_dev, "MIB counter dump timed out!\n");
+		vge_stats_clear(sc);
+		return;
+	}
+
+	bzero(mib, sizeof(mib));
+reset_idx:
+	/* Set MIB read index to 0. */
+	CSR_WRITE_1(sc, VGE_MIBCSR,
+	    CSR_READ_1(sc, VGE_MIBCSR) | VGE_MIBCSR_RINI);
+	for (i = 0; i < VGE_MIB_CNT; i++) {
+		val = CSR_READ_4(sc, VGE_MIBDATA);
+		if (i != VGE_MIB_DATA_IDX(val)) {
+			/* Reading interrupted. */
+			goto reset_idx;
+		}
+		mib[i] = val & VGE_MIB_DATA_MASK;
+	}
+
+	/* Rx stats. */
+	stats->rx_frames += mib[VGE_MIB_RX_FRAMES];
+	stats->rx_good_frames += mib[VGE_MIB_RX_GOOD_FRAMES];
+	stats->rx_fifo_oflows += mib[VGE_MIB_RX_FIFO_OVERRUNS];
+	stats->rx_runts += mib[VGE_MIB_RX_RUNTS];
+	stats->rx_runts_errs += mib[VGE_MIB_RX_RUNTS_ERRS];
+	stats->rx_pkts_64 += mib[VGE_MIB_RX_PKTS_64];
+	stats->rx_pkts_65_127 += mib[VGE_MIB_RX_PKTS_65_127];
+	stats->rx_pkts_128_255 += mib[VGE_MIB_RX_PKTS_128_255];
+	stats->rx_pkts_256_511 += mib[VGE_MIB_RX_PKTS_256_511];
+	stats->rx_pkts_512_1023 += mib[VGE_MIB_RX_PKTS_512_1023];
+	stats->rx_pkts_1024_1518 += mib[VGE_MIB_RX_PKTS_1024_1518];
+	stats->rx_pkts_1519_max += mib[VGE_MIB_RX_PKTS_1519_MAX];
+	stats->rx_pkts_1519_max_errs += mib[VGE_MIB_RX_PKTS_1519_MAX_ERRS];
+	stats->rx_jumbos += mib[VGE_MIB_RX_JUMBOS];
+	stats->rx_crcerrs += mib[VGE_MIB_RX_CRCERRS];
+	stats->rx_pause_frames += mib[VGE_MIB_RX_PAUSE];
+	stats->rx_alignerrs += mib[VGE_MIB_RX_ALIGNERRS];
+	stats->rx_nobufs += mib[VGE_MIB_RX_NOBUFS];
+	stats->rx_symerrs += mib[VGE_MIB_RX_SYMERRS];
+	stats->rx_lenerrs += mib[VGE_MIB_RX_LENERRS];
+
+	/* Tx stats. */
+	stats->tx_good_frames += mib[VGE_MIB_TX_GOOD_FRAMES];
+	stats->tx_pkts_64 += mib[VGE_MIB_TX_PKTS_64];
+	stats->tx_pkts_65_127 += mib[VGE_MIB_TX_PKTS_65_127];
+	stats->tx_pkts_128_255 += mib[VGE_MIB_TX_PKTS_128_255];
+	stats->tx_pkts_256_511 += mib[VGE_MIB_TX_PKTS_256_511];
+	stats->tx_pkts_512_1023 += mib[VGE_MIB_TX_PKTS_512_1023];
+	stats->tx_pkts_1024_1518 += mib[VGE_MIB_TX_PKTS_1024_1518];
+	stats->tx_jumbos += mib[VGE_MIB_TX_JUMBOS];
+	stats->tx_colls += mib[VGE_MIB_TX_COLLS];
+	stats->tx_pause += mib[VGE_MIB_TX_PAUSE];
+#ifdef VGE_ENABLE_SQEERR
+	stats->tx_sqeerrs += mib[VGE_MIB_TX_SQEERRS];
+#endif
+	stats->tx_latecolls += mib[VGE_MIB_TX_LATECOLLS];
+
+	/* Update counters in ifnet. */
+	ifp->if_opackets += mib[VGE_MIB_TX_GOOD_FRAMES];
+
+	ifp->if_collisions += mib[VGE_MIB_TX_COLLS] +
+	    mib[VGE_MIB_TX_LATECOLLS];
+
+	ifp->if_oerrors += mib[VGE_MIB_TX_COLLS] +
+	    mib[VGE_MIB_TX_LATECOLLS];
+
+	ifp->if_ipackets += mib[VGE_MIB_RX_GOOD_FRAMES];
+
+	ifp->if_ierrors += mib[VGE_MIB_RX_FIFO_OVERRUNS] +
+	    mib[VGE_MIB_RX_RUNTS] +
+	    mib[VGE_MIB_RX_RUNTS_ERRS] +
+	    mib[VGE_MIB_RX_CRCERRS] +
+	    mib[VGE_MIB_RX_ALIGNERRS] +
+	    mib[VGE_MIB_RX_NOBUFS] +
+	    mib[VGE_MIB_RX_SYMERRS] +
+	    mib[VGE_MIB_RX_LENERRS];
+}
diff --git a/sys/dev/vge/if_vgereg.h b/sys/dev/vge/if_vgereg.h
index a04c3943bf5..bf8dcdc35f3 100644
--- a/sys/dev/vge/if_vgereg.h
+++ b/sys/dev/vge/if_vgereg.h
@@ -301,7 +301,7 @@
 			 VGE_ISR_RXOFLOW|VGE_ISR_PHYINT|		\
 			 VGE_ISR_LINKSTS|VGE_ISR_RXNODESC|		\
 			 VGE_ISR_RXDMA_STALL|VGE_ISR_TXDMA_STALL|	\
-			 VGE_ISR_MIBOFLOW|VGE_ISR_TIMER0)
+			 VGE_ISR_TIMER0)
 
 /* Interrupt mask register */
 
@@ -543,6 +543,54 @@
 #define VGE_TXBLOCK_128PKTS	0x08
 #define VGE_TXBLOCK_8PKTS	0x0C
 
+/* MIB control/status register */
+#define	VGE_MIBCSR_CLR		0x01
+#define	VGE_MIBCSR_RINI		0x02
+#define	VGE_MIBCSR_FLUSH	0x04
+#define	VGE_MIBCSR_FREEZE	0x08
+#define	VGE_MIBCSR_HI_80	0x00
+#define	VGE_MIBCSR_HI_C0	0x10
+#define	VGE_MIBCSR_BISTGO	0x40
+#define	VGE_MIBCSR_BISTOK	0x80
+
+/* MIB data index. */
+#define	VGE_MIB_RX_FRAMES		0
+#define	VGE_MIB_RX_GOOD_FRAMES		1
+#define	VGE_MIB_TX_GOOD_FRAMES		2
+#define	VGE_MIB_RX_FIFO_OVERRUNS	3
+#define	VGE_MIB_RX_RUNTS		4
+#define	VGE_MIB_RX_RUNTS_ERRS		5
+#define	VGE_MIB_RX_PKTS_64		6
+#define	VGE_MIB_TX_PKTS_64		7
+#define	VGE_MIB_RX_PKTS_65_127		8
+#define	VGE_MIB_TX_PKTS_65_127		9
+#define	VGE_MIB_RX_PKTS_128_255		10
+#define	VGE_MIB_TX_PKTS_128_255		11
+#define	VGE_MIB_RX_PKTS_256_511		12
+#define	VGE_MIB_TX_PKTS_256_511		13
+#define	VGE_MIB_RX_PKTS_512_1023	14
+#define	VGE_MIB_TX_PKTS_512_1023	15
+#define	VGE_MIB_RX_PKTS_1024_1518	16
+#define	VGE_MIB_TX_PKTS_1024_1518	17
+#define	VGE_MIB_TX_COLLS		18
+#define	VGE_MIB_RX_CRCERRS		19
+#define	VGE_MIB_RX_JUMBOS		20
+#define	VGE_MIB_TX_JUMBOS		21
+#define	VGE_MIB_RX_PAUSE		22
+#define	VGE_MIB_TX_PAUSE		23
+#define	VGE_MIB_RX_ALIGNERRS		24
+#define	VGE_MIB_RX_PKTS_1519_MAX	25
+#define	VGE_MIB_RX_PKTS_1519_MAX_ERRS	26
+#define	VGE_MIB_TX_SQEERRS		27
+#define	VGE_MIB_RX_NOBUFS		28
+#define	VGE_MIB_RX_SYMERRS		29
+#define	VGE_MIB_RX_LENERRS		30
+#define	VGE_MIB_TX_LATECOLLS		31
+
+#define	VGE_MIB_CNT		(VGE_MIB_TX_LATECOLLS - VGE_MIB_RX_FRAMES + 1)
+#define	VGE_MIB_DATA_MASK	0x00FFFFFF
+#define	VGE_MIB_DATA_IDX(x)	((x) >> 24)
+
 /* EEPROM control/status register */
 
 #define VGE_EECSR_EDO		0x01	/* data out pin */
diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h
index ec3edbad986..f6222501b51 100644
--- a/sys/dev/vge/if_vgevar.h
+++ b/sys/dev/vge/if_vgevar.h
@@ -130,6 +130,42 @@ struct vge_ring_data {
 	bus_addr_t		vge_rx_ring_paddr;
 };
 
+struct vge_hw_stats {
+	uint32_t		rx_frames;
+	uint32_t		rx_good_frames;
+	uint32_t		rx_fifo_oflows;
+	uint32_t		rx_runts;
+	uint32_t		rx_runts_errs;
+	uint32_t		rx_pkts_64;
+	uint32_t		rx_pkts_65_127;
+	uint32_t		rx_pkts_128_255;
+	uint32_t		rx_pkts_256_511;
+	uint32_t		rx_pkts_512_1023;
+	uint32_t		rx_pkts_1024_1518;
+	uint32_t		rx_pkts_1519_max;
+	uint32_t		rx_pkts_1519_max_errs;
+	uint32_t		rx_jumbos;
+	uint32_t		rx_crcerrs;
+	uint32_t		rx_pause_frames;
+	uint32_t		rx_alignerrs;
+	uint32_t		rx_nobufs;
+	uint32_t		rx_symerrs;
+	uint32_t		rx_lenerrs;
+
+	uint32_t		tx_good_frames;
+	uint32_t		tx_pkts_64;
+	uint32_t		tx_pkts_65_127;
+	uint32_t		tx_pkts_128_255;
+	uint32_t		tx_pkts_256_511;
+	uint32_t		tx_pkts_512_1023;
+	uint32_t		tx_pkts_1024_1518;
+	uint32_t		tx_jumbos;
+	uint32_t		tx_colls;
+	uint32_t		tx_pause;
+	uint32_t		tx_sqeerrs;
+	uint32_t		tx_latecolls;
+};
+
 struct vge_softc {
 	struct ifnet		*vge_ifp;	/* interface info */
 	device_t		vge_dev;
@@ -152,6 +188,7 @@ struct vge_softc {
 
 	struct vge_chain_data	vge_cdata;
 	struct vge_ring_data	vge_rdata;
+	struct vge_hw_stats	vge_stats;
 
 	int			suspended;	/* 0 = normal  1 = suspended */
 };

From babaf83d9a5e0c6d644e177a3cbf54082972a0e3 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Sat, 9 Jan 2010 00:12:59 +0000
Subject: [PATCH 1067/2592] MFC r200616-200617,200635,200639,200644

r200616:
  Add new flag VGE_FLAG_SUSPENDED to mark suspended state and
  remove suspended member in softc.

r200617:
  Add "Velocity" to probe message which will make it clearer which
  ethernet controller was recognized. VIA consistently calls
  "Velocity" family for gigabit ethernet controllers. For fast
  ethernet controllers they uses "Rhine" family(vr(4) controllers))
  and vr(4) already shows "Rhine" in probe message.

r200635:
  Remove unused VGE_ETHER_ALIGN definition.

r200639:
  Actually clear interrupts. Writing 0 has no effect.

r200644:
  Remove unused member variable of softc.
---
 sys/dev/vge/if_vge.c    | 18 +++++++-----------
 sys/dev/vge/if_vgevar.h | 10 +---------
 2 files changed, 8 insertions(+), 20 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index be785c1b646..1a175f7d595 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -144,7 +144,7 @@ TUNABLE_INT("hw.vge.msi_disable", &msi_disable);
  */
 static struct vge_type vge_devs[] = {
 	{ VIA_VENDORID, VIA_DEVICEID_61XX,
-		"VIA Networking Gigabit Ethernet" },
+		"VIA Networking Velocity Gigabit Ethernet" },
 	{ 0, 0, NULL }
 };
 
@@ -1728,15 +1728,11 @@ vge_intr(void *arg)
 	uint32_t status;
 
 	sc = arg;
-
-	if (sc->suspended) {
-		return;
-	}
-
 	VGE_LOCK(sc);
-	ifp = sc->vge_ifp;
 
-	if (!(ifp->if_flags & IFF_UP)) {
+	ifp = sc->vge_ifp;
+	if ((sc->vge_flags & VGE_FLAG_SUSPENDED) != 0 ||
+	    (ifp->if_flags & IFF_UP) == 0) {
 		VGE_UNLOCK(sc);
 		return;
 	}
@@ -2164,7 +2160,7 @@ vge_init_locked(struct vge_softc *sc)
 	 * Enable interrupts.
 	 */
 		CSR_WRITE_4(sc, VGE_IMR, VGE_INTRS);
-		CSR_WRITE_4(sc, VGE_ISR, 0);
+		CSR_WRITE_4(sc, VGE_ISR, 0xFFFFFFFF);
 		CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
 	}
 
@@ -2430,7 +2426,7 @@ vge_suspend(device_t dev)
 	VGE_LOCK(sc);
 	vge_stop(sc);
 
-	sc->suspended = 1;
+	sc->vge_flags |= VGE_FLAG_SUSPENDED;
 	VGE_UNLOCK(sc);
 
 	return (0);
@@ -2460,7 +2456,7 @@ vge_resume(device_t dev)
 		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 		vge_init_locked(sc);
 	}
-	sc->suspended = 0;
+	sc->vge_flags &= ~VGE_FLAG_SUSPENDED;
 	VGE_UNLOCK(sc);
 
 	return (0);
diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h
index f6222501b51..65483b83117 100644
--- a/sys/dev/vge/if_vgevar.h
+++ b/sys/dev/vge/if_vgevar.h
@@ -65,12 +65,6 @@
 #define VGE_RXBYTES(x)		(((x) & VGE_RDSTS_BUFSIZ) >> 16)
 #define VGE_MIN_FRAMELEN	60
 
-#ifdef VGE_FIXUP_RX
-#define VGE_ETHER_ALIGN		sizeof(uint32_t)
-#else
-#define VGE_ETHER_ALIGN		0
-#endif
-
 struct vge_type {
 	uint16_t		vge_vid;
 	uint16_t		vge_did;
@@ -173,12 +167,12 @@ struct vge_softc {
 	struct resource		*vge_irq;
 	void			*vge_intrhand;
 	device_t		vge_miibus;
-	uint8_t			vge_type;
 	int			vge_if_flags;
 	int			vge_phyaddr;
 	int			vge_flags;
 #define	VGE_FLAG_PCIE		0x0001
 #define	VGE_FLAG_MSI		0x0002
+#define	VGE_FLAG_SUSPENDED	0x4000
 #define	VGE_FLAG_LINK		0x8000
 	int			vge_expcap;
 	int			vge_camidx;
@@ -189,8 +183,6 @@ struct vge_softc {
 	struct vge_chain_data	vge_cdata;
 	struct vge_ring_data	vge_rdata;
 	struct vge_hw_stats	vge_stats;
-
-	int			suspended;	/* 0 = normal  1 = suspended */
 };
 
 #define	VGE_LOCK(_sc)		mtx_lock(&(_sc)->vge_mtx)

From 6f311c868241531cf23698ca951d6c8661f3ef67 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Sat, 9 Jan 2010 00:17:43 +0000
Subject: [PATCH 1068/2592] MFC r200638:   Implement interrupt moderation
 scheme supported by VT61xx   controllers. TX/RX interrupt mitigation is
 controlled by   VGE_TXSUPPTHR and VGE_RXSUPPTHR register. These registers
 suppress   generation of interrupts until the programmed frames counter
 equals   to the registers. VT61xx also supports interrupt hold off timer  
 register. If this interrupt hold off timer is active all interrupts   would
 be disabled until the timer reaches to 0. The timer value is   reloaded
 whenever VGE_ISR register written. The timer resolution is   about 20us.

  Previously vge(4) used single shot timer to reduce Tx completion
  interrupts. This required VGE_CRS1 register access in Tx
  start/completion handler to rearm new timeout value and it did not
  show satisfactory result(more than 50k interrupts under load). Rx
  interrupts was not moderated at all such that vge(4) used to
  generate too many interrupts which in turn made polling(4) better
  approach under high network load.

  This change activates all interrupt moderation mechanism and
  initial values were tuned to generate interrupt less than 8k per
  second. That number of interrupts wouldn't add additional packet
  latencies compared to polling(4). These interrupt parameters could
  be changed with sysctl.
  dev.vge.%d.int_holdoff
  dev.vge.%d.rx_coal_pkt
  dev.vge.%d.tx_coal_pkt
  Interface has be brought down and up again before change take
  effect.

  With interrupt moderation there is no more need to loop in
  interrupt handler. This loop always added one more register access.
  While I'm here remove dead code which tried to implement subset of
  interrupt moderation.
---
 sys/dev/vge/if_vge.c    | 163 +++++++++++++++++++++-------------------
 sys/dev/vge/if_vgereg.h |   3 +-
 sys/dev/vge/if_vgevar.h |  17 +++++
 3 files changed, 103 insertions(+), 80 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index 1a175f7d595..87fa950ce87 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -175,6 +175,7 @@ static int	vge_ifmedia_upd(struct ifnet *);
 static void	vge_init(void *);
 static void	vge_init_locked(struct vge_softc *);
 static void	vge_intr(void *);
+static void	vge_intr_holdoff(struct vge_softc *);
 static int	vge_ioctl(struct ifnet *, u_long, caddr_t);
 static void	vge_link_statchg(void *);
 static int	vge_miibus_readreg(device_t, int, int);
@@ -1631,15 +1632,6 @@ vge_txeof(struct vge_softc *sc)
 	sc->vge_cdata.vge_tx_considx = cons;
 	if (sc->vge_cdata.vge_tx_cnt == 0)
 		sc->vge_timer = 0;
-	else {
-		/*
-		 * If not all descriptors have been released reaped yet,
-		 * reload the timer so that we will eventually get another
-		 * interrupt that will cause us to re-enter this routine.
-		 * This is done in case the transmitter has gone idle.
-		 */
-		CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE);
-	}
 }
 
 static void
@@ -1746,30 +1738,21 @@ vge_intr(void *arg)
 
 	/* Disable interrupts */
 	CSR_WRITE_1(sc, VGE_CRC3, VGE_CR3_INT_GMSK);
-
-	for (;;) {
-
-		status = CSR_READ_4(sc, VGE_ISR);
-		/* If the card has gone away the read returns 0xffff. */
-		if (status == 0xFFFFFFFF)
-			break;
-
-		if (status)
-			CSR_WRITE_4(sc, VGE_ISR, status);
-
-		if ((status & VGE_INTRS) == 0)
-			break;
-
+	status = CSR_READ_4(sc, VGE_ISR);
+	CSR_WRITE_4(sc, VGE_ISR, status | VGE_ISR_HOLDOFF_RELOAD);
+	/* If the card has gone away the read returns 0xffff. */
+	if (status == 0xFFFFFFFF || (status & VGE_INTRS) == 0)
+		goto done;
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
 		if (status & (VGE_ISR_RXOK|VGE_ISR_RXOK_HIPRIO))
 			vge_rxeof(sc, VGE_RX_DESC_CNT);
-
 		if (status & (VGE_ISR_RXOFLOW|VGE_ISR_RXNODESC)) {
 			vge_rxeof(sc, VGE_RX_DESC_CNT);
 			CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_RUN);
 			CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_WAK);
 		}
 
-		if (status & (VGE_ISR_TXOK0|VGE_ISR_TIMER0))
+		if (status & (VGE_ISR_TXOK0|VGE_ISR_TXOK_HIPRIO))
 			vge_txeof(sc);
 
 		if (status & (VGE_ISR_TXDMA_STALL|VGE_ISR_RXDMA_STALL)) {
@@ -1780,13 +1763,14 @@ vge_intr(void *arg)
 		if (status & VGE_ISR_LINKSTS)
 			vge_link_statchg(sc);
 	}
+done:
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+		/* Re-enable interrupts */
+		CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
 
-	/* Re-enable interrupts */
-	CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
-
-	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		vge_start_locked(ifp);
-
+		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+			vge_start_locked(ifp);
+	}
 	VGE_UNLOCK(sc);
 }
 
@@ -1984,17 +1968,6 @@ vge_start_locked(struct ifnet *ifp)
 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 		/* Issue a transmit command. */
 		CSR_WRITE_2(sc, VGE_TXQCSRS, VGE_TXQCSR_WAK0);
-		/*
-		 * Use the countdown timer for interrupt moderation.
-		 * 'TX done' interrupts are disabled. Instead, we reset the
-		 * countdown timer, which will begin counting until it hits
-		 * the value in the SSTIMER register, and then trigger an
-		 * interrupt. Each time we set the TIMER0_ENABLE bit, the
-		 * the timer count is reloaded. Only when the transmitter
-		 * is idle will the timer hit 0 and an interrupt fire.
-		 */
-		CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE);
-
 		/*
 		 * Set a timeout in case the chip goes out to lunch.
 		 */
@@ -2084,6 +2057,9 @@ vge_init_locked(struct vge_softc *sc)
 	CSR_WRITE_2(sc, VGE_RXDESCNUM, VGE_RX_DESC_CNT - 1);
 	CSR_WRITE_2(sc, VGE_RXDESC_RESIDUECNT, VGE_RX_DESC_CNT);
 
+	/* Configure interrupt moderation. */
+	vge_intr_holdoff(sc);
+
 	/* Enable and wake up the RX descriptor queue */
 	CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_RUN);
 	CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_WAK);
@@ -2110,42 +2086,6 @@ vge_init_locked(struct vge_softc *sc)
 	CSR_WRITE_1(sc, VGE_CRS0,
 	    VGE_CR0_TX_ENABLE|VGE_CR0_RX_ENABLE|VGE_CR0_START);
 
-	/*
-	 * Configure one-shot timer for microsecond
-	 * resolution and load it for 500 usecs.
-	 */
-	CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_TIMER0_RES);
-	CSR_WRITE_2(sc, VGE_SSTIMER, 400);
-
-	/*
-	 * Configure interrupt moderation for receive. Enable
-	 * the holdoff counter and load it, and set the RX
-	 * suppression count to the number of descriptors we
-	 * want to allow before triggering an interrupt.
-	 * The holdoff timer is in units of 20 usecs.
-	 */
-
-#ifdef notyet
-	CSR_WRITE_1(sc, VGE_INTCTL1, VGE_INTCTL_TXINTSUP_DISABLE);
-	/* Select the interrupt holdoff timer page. */
-	CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
-	CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_INTHLDOFF);
-	CSR_WRITE_1(sc, VGE_INTHOLDOFF, 10); /* ~200 usecs */
-
-	/* Enable use of the holdoff timer. */
-	CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_HOLDOFF);
-	CSR_WRITE_1(sc, VGE_INTCTL1, VGE_INTCTL_SC_RELOAD);
-
-	/* Select the RX suppression threshold page. */
-	CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
-	CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_RXSUPPTHR);
-	CSR_WRITE_1(sc, VGE_RXSUPPTHR, 64); /* interrupt after 64 packets */
-
-	/* Restore the page select bits. */
-	CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
-	CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_MAR);
-#endif
-
 #ifdef DEVICE_POLLING
 	/*
 	 * Disable interrupts if we are polling.
@@ -2494,6 +2434,25 @@ vge_sysctl_node(struct vge_softc *sc)
 	stats = &sc->vge_stats;
 	ctx = device_get_sysctl_ctx(sc->vge_dev);
 	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vge_dev));
+
+	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "int_holdoff",
+	    CTLFLAG_RW, &sc->vge_int_holdoff, 0, "interrupt holdoff");
+	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rx_coal_pkt",
+	    CTLFLAG_RW, &sc->vge_rx_coal_pkt, 0, "rx coalescing packet");
+	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "tx_coal_pkt",
+	    CTLFLAG_RW, &sc->vge_tx_coal_pkt, 0, "tx coalescing packet");
+
+	/* Pull in device tunables. */
+	sc->vge_int_holdoff = VGE_INT_HOLDOFF_DEFAULT;
+	resource_int_value(device_get_name(sc->vge_dev),
+	    device_get_unit(sc->vge_dev), "int_holdoff", &sc->vge_int_holdoff);
+	sc->vge_rx_coal_pkt = VGE_RX_COAL_PKT_DEFAULT;
+	resource_int_value(device_get_name(sc->vge_dev),
+	    device_get_unit(sc->vge_dev), "rx_coal_pkt", &sc->vge_rx_coal_pkt);
+	sc->vge_tx_coal_pkt = VGE_TX_COAL_PKT_DEFAULT;
+	resource_int_value(device_get_name(sc->vge_dev),
+	    device_get_unit(sc->vge_dev), "tx_coal_pkt", &sc->vge_tx_coal_pkt);
+
 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
 	    NULL, "VGE statistics");
 	parent = SYSCTL_CHILDREN(tree);
@@ -2699,3 +2658,51 @@ reset_idx:
 	    mib[VGE_MIB_RX_SYMERRS] +
 	    mib[VGE_MIB_RX_LENERRS];
 }
+
+static void
+vge_intr_holdoff(struct vge_softc *sc)
+{
+	uint8_t intctl;
+
+	VGE_LOCK_ASSERT(sc);
+
+	/*
+	 * Set Tx interrupt supression threshold.
+	 * It's possible to use single-shot timer in VGE_CRS1 register
+	 * in Tx path such that driver can remove most of Tx completion
+	 * interrupts. However this requires additional access to
+	 * VGE_CRS1 register to reload the timer in addintion to
+	 * activating Tx kick command. Another downside is we don't know
+	 * what single-shot timer value should be used in advance so
+	 * reclaiming transmitted mbufs could be delayed a lot which in
+	 * turn slows down Tx operation.
+	 */
+	CSR_WRITE_1(sc, VGE_CAMCTL, VGE_PAGESEL_TXSUPPTHR);
+	CSR_WRITE_1(sc, VGE_TXSUPPTHR, sc->vge_tx_coal_pkt);
+
+	/* Set Rx interrupt suppresion threshold. */
+	CSR_WRITE_1(sc, VGE_CAMCTL, VGE_PAGESEL_RXSUPPTHR);
+	CSR_WRITE_1(sc, VGE_RXSUPPTHR, sc->vge_rx_coal_pkt);
+
+	intctl = CSR_READ_1(sc, VGE_INTCTL1);
+	intctl &= ~VGE_INTCTL_SC_RELOAD;
+	intctl |= VGE_INTCTL_HC_RELOAD;
+	if (sc->vge_tx_coal_pkt <= 0)
+		intctl |= VGE_INTCTL_TXINTSUP_DISABLE;
+	else
+		intctl &= ~VGE_INTCTL_TXINTSUP_DISABLE;
+	if (sc->vge_rx_coal_pkt <= 0)
+		intctl |= VGE_INTCTL_RXINTSUP_DISABLE;
+	else
+		intctl &= ~VGE_INTCTL_RXINTSUP_DISABLE;
+	CSR_WRITE_1(sc, VGE_INTCTL1, intctl);
+	CSR_WRITE_1(sc, VGE_CRC3, VGE_CR3_INT_HOLDOFF);
+	if (sc->vge_int_holdoff > 0) {
+		/* Set interrupt holdoff timer. */
+		CSR_WRITE_1(sc, VGE_CAMCTL, VGE_PAGESEL_INTHLDOFF);
+		CSR_WRITE_1(sc, VGE_INTHOLDOFF,
+		    VGE_INT_HOLDOFF_USEC(sc->vge_int_holdoff));
+		/* Enable holdoff timer. */
+		CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_HOLDOFF);
+	}
+}
diff --git a/sys/dev/vge/if_vgereg.h b/sys/dev/vge/if_vgereg.h
index bf8dcdc35f3..bdabeb5a501 100644
--- a/sys/dev/vge/if_vgereg.h
+++ b/sys/dev/vge/if_vgereg.h
@@ -300,8 +300,7 @@
 #define VGE_INTRS	(VGE_ISR_TXOK0|VGE_ISR_RXOK|VGE_ISR_STOPPED|	\
 			 VGE_ISR_RXOFLOW|VGE_ISR_PHYINT|		\
 			 VGE_ISR_LINKSTS|VGE_ISR_RXNODESC|		\
-			 VGE_ISR_RXDMA_STALL|VGE_ISR_TXDMA_STALL|	\
-			 VGE_ISR_TIMER0)
+			 VGE_ISR_RXDMA_STALL|VGE_ISR_TXDMA_STALL)
 
 /* Interrupt mask register */
 
diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h
index 65483b83117..0064704d854 100644
--- a/sys/dev/vge/if_vgevar.h
+++ b/sys/dev/vge/if_vgevar.h
@@ -65,6 +65,20 @@
 #define VGE_RXBYTES(x)		(((x) & VGE_RDSTS_BUFSIZ) >> 16)
 #define VGE_MIN_FRAMELEN	60
 
+#define	VGE_INT_HOLDOFF_TICK	20
+#define	VGE_INT_HOLDOFF_USEC(x)	((x) / VGE_INT_HOLDOFF_TICK)
+#define	VGE_INT_HOLDOFF_MIN	0
+#define	VGE_INT_HOLDOFF_MAX	(255 * VGE_INT_HOLDOFF_TICK)
+#define	VGE_INT_HOLDOFF_DEFAULT	150
+
+#define	VGE_RX_COAL_PKT_MIN	1
+#define	VGE_RX_COAL_PKT_MAX	VGE_RX_DESC_CNT
+#define	VGE_RX_COAL_PKT_DEFAULT	64
+
+#define	VGE_TX_COAL_PKT_MIN	1
+#define	VGE_TX_COAL_PKT_MAX	VGE_TX_DESC_CNT
+#define	VGE_TX_COAL_PKT_DEFAULT	128
+
 struct vge_type {
 	uint16_t		vge_vid;
 	uint16_t		vge_did;
@@ -176,6 +190,9 @@ struct vge_softc {
 #define	VGE_FLAG_LINK		0x8000
 	int			vge_expcap;
 	int			vge_camidx;
+	int			vge_int_holdoff;
+	int			vge_rx_coal_pkt;
+	int			vge_tx_coal_pkt;
 	struct mtx		vge_mtx;
 	struct callout		vge_watchdog;
 	int			vge_timer;

From 50a44b8b9b9545c4a992c5a09ce4c2db0ff1933e Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Sat, 9 Jan 2010 00:26:57 +0000
Subject: [PATCH 1069/2592] MFC r200696,200740,200756,200758-200759,200972

r200696:
  Add rudimentary WOL support. While I'm here remove enabling
  busmastering/memory address in resume path. Bus driver will handle
  that.

r200740:
  Swap VGE_TXQTIMER and VGE_RXQTIMER register definition. Pending
  timer for Tx queue is at 0x3E.

r200756:
  Correct fragment bit definition in comments.

r200758:
  VT6130 datasheet was wrong. If VT6130 receive a jumbo frame the
  controller will split the jumbo frame into multiple RX buffers.
  However it seems the hardware always dma the frame to 8 bytes
  boundary for the split frames. Only the first part of the fragment
  can have 4 byte alignment and subsequent buffers should be 8 bytes
  aligned. Change RX buffer the alignment requirement to 8 bytes from
  4 bytes.

r200759:
  Disable jumbo frame support for PCIe VT6130/VT6132 controllers.
  Quite contrary to VT6130 datasheet which says it supports up to 8K
  jumbo frame, VT6130 does not seem to send jumbo frame that is
  larger than 4K in length. Trying to send a frame that is larger
  than 4K cause TX MAC hang.
  Even though it's possible to allow 4K jumbo frame for VT6130, I
  think it's meaningless to allow 4K jumbo frame. I'm not sure VT6132
  also has the same limitation but I guess it uses the same MAC of
  VT6130.

r200972:
  Remove wrong assertion.
---
 sys/dev/vge/if_vge.c    | 221 ++++++++++++++++++++++++++++++++++++----
 sys/dev/vge/if_vgereg.h |  44 +++++++-
 sys/dev/vge/if_vgevar.h |   5 +-
 3 files changed, 244 insertions(+), 26 deletions(-)

diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index 87fa950ce87..127a123cc63 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -157,6 +157,7 @@ static int	vge_suspend(device_t);
 
 static void	vge_cam_clear(struct vge_softc *);
 static int	vge_cam_set(struct vge_softc *, uint8_t *);
+static void	vge_clrwol(struct vge_softc *);
 static void	vge_discard_rxbuf(struct vge_softc *, int);
 static int	vge_dma_alloc(struct vge_softc *);
 static void	vge_dma_free(struct vge_softc *);
@@ -190,6 +191,7 @@ static int	vge_rx_list_init(struct vge_softc *);
 static int	vge_rxeof(struct vge_softc *, int);
 static void	vge_rxfilter(struct vge_softc *);
 static void	vge_setvlan(struct vge_softc *);
+static void	vge_setwol(struct vge_softc *);
 static void	vge_start(struct ifnet *);
 static void	vge_start_locked(struct ifnet *);
 static void	vge_stats_clear(struct vge_softc *);
@@ -1011,6 +1013,11 @@ vge_attach(device_t dev)
 	if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) == 0) {
 		sc->vge_flags |= VGE_FLAG_PCIE;
 		sc->vge_expcap = cap;
+	} else
+		sc->vge_flags |= VGE_FLAG_JUMBO;
+	if (pci_find_extcap(dev, PCIY_PMG, &cap) == 0) {
+		sc->vge_flags |= VGE_FLAG_PMCAP;
+		sc->vge_pmcap = cap;
 	}
 	rid = 0;
 	msic = pci_msi_count(dev);
@@ -1069,6 +1076,8 @@ vge_attach(device_t dev)
 	else
 		sc->vge_phyaddr = CSR_READ_1(sc, VGE_MIICFG) &
 		    VGE_MIICFG_PHYADDR;
+	/* Clear WOL and take hardware from powerdown. */
+	vge_clrwol(sc);
 	vge_sysctl_node(sc);
 	error = vge_dma_alloc(sc);
 	if (error)
@@ -1098,6 +1107,8 @@ vge_attach(device_t dev)
 	ifp->if_hwassist = VGE_CSUM_FEATURES;
 	ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM |
 	    IFCAP_VLAN_HWTAGGING;
+	if ((sc->vge_flags & VGE_FLAG_PMCAP) != 0)
+		ifp->if_capabilities |= IFCAP_WOL;
 	ifp->if_capenable = ifp->if_capabilities;
 #ifdef DEVICE_POLLING
 	ifp->if_capabilities |= IFCAP_POLLING;
@@ -2211,9 +2222,17 @@ vge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 
 	switch (command) {
 	case SIOCSIFMTU:
-		if (ifr->ifr_mtu > VGE_JUMBO_MTU)
+		VGE_LOCK(sc);
+		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > VGE_JUMBO_MTU)
 			error = EINVAL;
-		ifp->if_mtu = ifr->ifr_mtu;
+		else if (ifp->if_mtu != ifr->ifr_mtu) {
+			if (ifr->ifr_mtu > ETHERMTU &&
+			    (sc->vge_flags & VGE_FLAG_JUMBO) == 0)
+				error = EINVAL;
+			else
+				ifp->if_mtu = ifr->ifr_mtu;
+		}
+		VGE_UNLOCK(sc);
 		break;
 	case SIOCSIFFLAGS:
 		VGE_LOCK(sc);
@@ -2279,6 +2298,15 @@ vge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 		if ((mask & IFCAP_RXCSUM) != 0 &&
 		    (ifp->if_capabilities & IFCAP_RXCSUM) != 0)
 			ifp->if_capenable ^= IFCAP_RXCSUM;
+		if ((mask & IFCAP_WOL_UCAST) != 0 &&
+		    (ifp->if_capabilities & IFCAP_WOL_UCAST) != 0)
+			ifp->if_capenable ^= IFCAP_WOL_UCAST;
+		if ((mask & IFCAP_WOL_MCAST) != 0 &&
+		    (ifp->if_capabilities & IFCAP_WOL_MCAST) != 0)
+			ifp->if_capenable ^= IFCAP_WOL_MCAST;
+		if ((mask & IFCAP_WOL_MAGIC) != 0 &&
+		    (ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0)
+			ifp->if_capenable ^= IFCAP_WOL_MAGIC;
 		if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
 		    (ifp->if_capabilities & IFCAP_VLAN_HWCSUM) != 0)
 			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
@@ -2365,7 +2393,7 @@ vge_suspend(device_t dev)
 
 	VGE_LOCK(sc);
 	vge_stop(sc);
-
+	vge_setwol(sc);
 	sc->vge_flags |= VGE_FLAG_SUSPENDED;
 	VGE_UNLOCK(sc);
 
@@ -2382,17 +2410,26 @@ vge_resume(device_t dev)
 {
 	struct vge_softc *sc;
 	struct ifnet *ifp;
+	uint16_t pmstat;
 
 	sc = device_get_softc(dev);
-	ifp = sc->vge_ifp;
-
-	/* reenable busmastering */
-	pci_enable_busmaster(dev);
-	pci_enable_io(dev, SYS_RES_MEMORY);
-
-	/* reinitialize interface if necessary */
 	VGE_LOCK(sc);
-	if (ifp->if_flags & IFF_UP) {
+	if ((sc->vge_flags & VGE_FLAG_PMCAP) != 0) {
+		/* Disable PME and clear PME status. */
+		pmstat = pci_read_config(sc->vge_dev,
+		    sc->vge_pmcap + PCIR_POWER_STATUS, 2);
+		if ((pmstat & PCIM_PSTAT_PMEENABLE) != 0) {
+			pmstat &= ~PCIM_PSTAT_PMEENABLE;
+			pci_write_config(sc->vge_dev,
+			    sc->vge_pmcap + PCIR_POWER_STATUS, pmstat, 2);
+		}
+	}
+	vge_clrwol(sc);
+	/* Restart MII auto-polling. */
+	vge_miipoll_start(sc);
+	ifp = sc->vge_ifp;
+	/* Reinitialize interface if necessary. */
+	if ((ifp->if_flags & IFF_UP) != 0) {
 		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 		vge_init_locked(sc);
 	}
@@ -2409,15 +2446,8 @@ vge_resume(device_t dev)
 static int
 vge_shutdown(device_t dev)
 {
-	struct vge_softc *sc;
 
-	sc = device_get_softc(dev);
-
-	VGE_LOCK(sc);
-	vge_stop(sc);
-	VGE_UNLOCK(sc);
-
-	return (0);
+	return (vge_suspend(dev));
 }
 
 #define	VGE_SYSCTL_STAT_ADD32(c, h, n, p, d)	\
@@ -2543,8 +2573,6 @@ vge_stats_clear(struct vge_softc *sc)
 {
 	int i;
 
-	VGE_LOCK_ASSERT(sc);
-
 	CSR_WRITE_1(sc, VGE_MIBCSR,
 	    CSR_READ_1(sc, VGE_MIBCSR) | VGE_MIBCSR_FREEZE);
 	CSR_WRITE_1(sc, VGE_MIBCSR,
@@ -2706,3 +2734,154 @@ vge_intr_holdoff(struct vge_softc *sc)
 		CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_HOLDOFF);
 	}
 }
+
+static void
+vge_setlinkspeed(struct vge_softc *sc)
+{
+	struct mii_data *mii;
+	int aneg, i;
+
+	VGE_LOCK_ASSERT(sc);
+
+	mii = device_get_softc(sc->vge_miibus);
+	mii_pollstat(mii);
+	aneg = 0;
+	if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+	    (IFM_ACTIVE | IFM_AVALID)) {
+		switch IFM_SUBTYPE(mii->mii_media_active) {
+		case IFM_10_T:
+		case IFM_100_TX:
+			return;
+		case IFM_1000_T:
+			aneg++;
+		default:
+			break;
+		}
+	}
+	vge_miibus_writereg(sc->vge_dev, sc->vge_phyaddr, MII_100T2CR, 0);
+	vge_miibus_writereg(sc->vge_dev, sc->vge_phyaddr, MII_ANAR,
+	    ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA);
+	vge_miibus_writereg(sc->vge_dev, sc->vge_phyaddr, MII_BMCR,
+	    BMCR_AUTOEN | BMCR_STARTNEG);
+	DELAY(1000);
+	if (aneg != 0) {
+		/* Poll link state until vge(4) get a 10/100 link. */
+		for (i = 0; i < MII_ANEGTICKS_GIGE; i++) {
+			mii_pollstat(mii);
+			if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID))
+			    == (IFM_ACTIVE | IFM_AVALID)) {
+				switch (IFM_SUBTYPE(mii->mii_media_active)) {
+				case IFM_10_T:
+				case IFM_100_TX:
+					return;
+				default:
+					break;
+				}
+			}
+			VGE_UNLOCK(sc);
+			pause("vgelnk", hz);
+			VGE_LOCK(sc);
+		}
+		if (i == MII_ANEGTICKS_GIGE)
+			device_printf(sc->vge_dev, "establishing link failed, "
+			    "WOL may not work!");
+	}
+	/*
+	 * No link, force MAC to have 100Mbps, full-duplex link.
+	 * This is the last resort and may/may not work.
+	 */
+	mii->mii_media_status = IFM_AVALID | IFM_ACTIVE;
+	mii->mii_media_active = IFM_ETHER | IFM_100_TX | IFM_FDX;
+}
+
+static void
+vge_setwol(struct vge_softc *sc)
+{
+	struct ifnet *ifp;
+	uint16_t pmstat;
+	uint8_t val;
+
+	VGE_LOCK_ASSERT(sc);
+
+	if ((sc->vge_flags & VGE_FLAG_PMCAP) == 0) {
+		/* No PME capability, PHY power down. */
+		vge_miibus_writereg(sc->vge_dev, sc->vge_phyaddr, MII_BMCR,
+		    BMCR_PDOWN);
+		vge_miipoll_stop(sc);
+		return;
+	}
+
+	ifp = sc->vge_ifp;
+
+	/* Clear WOL on pattern match. */
+	CSR_WRITE_1(sc, VGE_WOLCR0C, VGE_WOLCR0_PATTERN_ALL);
+	/* Disable WOL on magic/unicast packet. */
+	CSR_WRITE_1(sc, VGE_WOLCR1C, 0x0F);
+	CSR_WRITE_1(sc, VGE_WOLCFGC, VGE_WOLCFG_SAB | VGE_WOLCFG_SAM |
+	    VGE_WOLCFG_PMEOVR);
+	if ((ifp->if_capenable & IFCAP_WOL) != 0) {
+		vge_setlinkspeed(sc);
+		val = 0;
+		if ((ifp->if_capenable & IFCAP_WOL_UCAST) != 0)
+			val |= VGE_WOLCR1_UCAST;
+		if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0)
+			val |= VGE_WOLCR1_MAGIC;
+		CSR_WRITE_1(sc, VGE_WOLCR1S, val);
+		val = 0;
+		if ((ifp->if_capenable & IFCAP_WOL_MCAST) != 0)
+			val |= VGE_WOLCFG_SAM | VGE_WOLCFG_SAB;
+		CSR_WRITE_1(sc, VGE_WOLCFGS, val | VGE_WOLCFG_PMEOVR);
+		/* Disable MII auto-polling. */
+		vge_miipoll_stop(sc);
+	}
+	CSR_SETBIT_1(sc, VGE_DIAGCTL,
+	    VGE_DIAGCTL_MACFORCE | VGE_DIAGCTL_FDXFORCE);
+	CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_GMII);
+
+	/* Clear WOL status on pattern match. */
+	CSR_WRITE_1(sc, VGE_WOLSR0C, 0xFF);
+	CSR_WRITE_1(sc, VGE_WOLSR1C, 0xFF);
+
+	val = CSR_READ_1(sc, VGE_PWRSTAT);
+	val |= VGE_STICKHW_SWPTAG;
+	CSR_WRITE_1(sc, VGE_PWRSTAT, val);
+	/* Put hardware into sleep. */
+	val = CSR_READ_1(sc, VGE_PWRSTAT);
+	val |= VGE_STICKHW_DS0 | VGE_STICKHW_DS1;
+	CSR_WRITE_1(sc, VGE_PWRSTAT, val);
+	/* Request PME if WOL is requested. */
+	pmstat = pci_read_config(sc->vge_dev, sc->vge_pmcap +
+	    PCIR_POWER_STATUS, 2);
+	pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
+	if ((ifp->if_capenable & IFCAP_WOL) != 0)
+		pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
+	pci_write_config(sc->vge_dev, sc->vge_pmcap + PCIR_POWER_STATUS,
+	    pmstat, 2);
+}
+
+static void
+vge_clrwol(struct vge_softc *sc)
+{
+	uint8_t val;
+
+	val = CSR_READ_1(sc, VGE_PWRSTAT);
+	val &= ~VGE_STICKHW_SWPTAG;
+	CSR_WRITE_1(sc, VGE_PWRSTAT, val);
+	/* Disable WOL and clear power state indicator. */
+	val = CSR_READ_1(sc, VGE_PWRSTAT);
+	val &= ~(VGE_STICKHW_DS0 | VGE_STICKHW_DS1);
+	CSR_WRITE_1(sc, VGE_PWRSTAT, val);
+
+	CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_GMII);
+	CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE);
+
+	/* Clear WOL on pattern match. */
+	CSR_WRITE_1(sc, VGE_WOLCR0C, VGE_WOLCR0_PATTERN_ALL);
+	/* Disable WOL on magic/unicast packet. */
+	CSR_WRITE_1(sc, VGE_WOLCR1C, 0x0F);
+	CSR_WRITE_1(sc, VGE_WOLCFGC, VGE_WOLCFG_SAB | VGE_WOLCFG_SAM |
+	    VGE_WOLCFG_PMEOVR);
+	/* Clear WOL status on pattern match. */
+	CSR_WRITE_1(sc, VGE_WOLSR0C, 0xFF);
+	CSR_WRITE_1(sc, VGE_WOLSR1C, 0xFF);
+}
diff --git a/sys/dev/vge/if_vgereg.h b/sys/dev/vge/if_vgereg.h
index bdabeb5a501..77cd61eb6ba 100644
--- a/sys/dev/vge/if_vgereg.h
+++ b/sys/dev/vge/if_vgereg.h
@@ -89,8 +89,8 @@
 #define VGE_RXQCSRC		0x36	/* RX queue ctl/status clear */
 #define VGE_RXDESC_ADDR_LO	0x38	/* RX desc base addr (lo 32 bits) */
 #define VGE_RXDESC_CONSIDX	0x3C	/* Current RX descriptor index */
-#define VGE_RXQTIMER		0x3E	/* RX queue timer pend register */
-#define VGE_TXQTIMER		0x3F	/* TX queue timer pend register */
+#define VGE_TXQTIMER		0x3E	/* TX queue timer pend register */
+#define VGE_RXQTIMER		0x3F	/* RX queue timer pend register */
 #define VGE_TXDESC_ADDR_LO0	0x40	/* TX desc0 base addr (lo 32 bits) */
 #define VGE_TXDESC_ADDR_LO1	0x44	/* TX desc1 base addr (lo 32 bits) */
 #define VGE_TXDESC_ADDR_LO2	0x48	/* TX desc2 base addr (lo 32 bits) */
@@ -590,6 +590,42 @@
 #define	VGE_MIB_DATA_MASK	0x00FFFFFF
 #define	VGE_MIB_DATA_IDX(x)	((x) >> 24)
 
+/* Sticky bit shadow register */
+
+#define	VGE_STICKHW_DS0		0x01
+#define	VGE_STICKHW_DS1		0x02
+#define	VGE_STICKHW_WOL_ENB	0x04
+#define	VGE_STICKHW_WOL_STS	0x08
+#define	VGE_STICKHW_SWPTAG	0x10
+
+/* WOL pattern control */
+#define	VGE_WOLCR0_PATTERN0	0x01
+#define	VGE_WOLCR0_PATTERN1	0x02
+#define	VGE_WOLCR0_PATTERN2	0x04
+#define	VGE_WOLCR0_PATTERN3	0x08
+#define	VGE_WOLCR0_PATTERN4	0x10
+#define	VGE_WOLCR0_PATTERN5	0x20
+#define	VGE_WOLCR0_PATTERN6	0x40
+#define	VGE_WOLCR0_PATTERN7	0x80
+#define	VGE_WOLCR0_PATTERN_ALL	0xFF
+
+/* WOL event control */
+#define	VGE_WOLCR1_UCAST	0x01
+#define	VGE_WOLCR1_MAGIC	0x02
+#define	VGE_WOLCR1_LINKON	0x04
+#define	VGE_WOLCR1_LINKOFF	0x08
+
+/* Poweer management config */
+#define VGE_PWRCFG_LEGACY_WOLEN	0x01
+#define VGE_PWRCFG_WOL_PULSE	0x20
+#define VGE_PWRCFG_WOL_BUTTON	0x00
+
+/* WOL config register */
+#define	VGE_WOLCFG_PHYINT_ENB	0x01
+#define	VGE_WOLCFG_SAB		0x10
+#define	VGE_WOLCFG_SAM		0x20
+#define	VGE_WOLCFG_PMEOVR	0x80
+
 /* EEPROM control/status register */
 
 #define VGE_EECSR_EDO		0x01	/* data out pin */
@@ -725,8 +761,8 @@ struct vge_rx_desc {
 #define VGE_RDSTS_OWN		0x80000000	/* own bit. */
 
 #define VGE_RXPKT_ONEFRAG	0x00000000	/* only one fragment */
-#define VGE_RXPKT_EOF		0x00000100	/* first frag in frame */
-#define VGE_RXPKT_SOF		0x00000200	/* last frag in frame */
+#define VGE_RXPKT_EOF		0x00000100	/* last frag in frame */
+#define VGE_RXPKT_SOF		0x00000200	/* first frag in frame */
 #define VGE_RXPKT_MOF		0x00000300	/* intermediate frag */
 
 #define VGE_RDCTL_VLANID	0x0000FFFF	/* VLAN ID info */
diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h
index 0064704d854..ca899cc5fc0 100644
--- a/sys/dev/vge/if_vgevar.h
+++ b/sys/dev/vge/if_vgevar.h
@@ -39,7 +39,7 @@
 #define VGE_TX_RING_ALIGN	64
 #define VGE_RX_RING_ALIGN	64
 #define VGE_MAXTXSEGS		6
-#define VGE_RX_BUF_ALIGN	sizeof(uint32_t)
+#define VGE_RX_BUF_ALIGN	sizeof(uint64_t)
 
 /*
  * VIA Velocity allows 64bit DMA addressing but high 16bits
@@ -186,9 +186,12 @@ struct vge_softc {
 	int			vge_flags;
 #define	VGE_FLAG_PCIE		0x0001
 #define	VGE_FLAG_MSI		0x0002
+#define	VGE_FLAG_PMCAP		0x0004
+#define	VGE_FLAG_JUMBO		0x0008
 #define	VGE_FLAG_SUSPENDED	0x4000
 #define	VGE_FLAG_LINK		0x8000
 	int			vge_expcap;
+	int			vge_pmcap;
 	int			vge_camidx;
 	int			vge_int_holdoff;
 	int			vge_rx_coal_pkt;

From 1cb2c81c143207a531a02eac5e435f59c28887d1 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sat, 9 Jan 2010 00:27:23 +0000
Subject: [PATCH 1070/2592] MFC: r201397

Add one more supported controller.
---
 share/man/man4/mfi.4 | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/share/man/man4/mfi.4 b/share/man/man4/mfi.4
index a2c09ea3efb..d34eb273f24 100644
--- a/share/man/man4/mfi.4
+++ b/share/man/man4/mfi.4
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 26, 2009
+.Dd January 2, 2010
 .Dt MFI 4
 .Os
 .Sh NAME
@@ -92,6 +92,8 @@ Dell PERC5
 Dell PERC6
 .It
 IBM ServeRAID-MR10i
+.It
+Intel RAID Controller SROMBSAS18E
 .El
 .Sh FILES
 .Bl -tag -width ".Pa /dev/mfid?" -compact

From 18c3b93957a24c6ace5cec8dc5dba3fb53743d54 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Sat, 9 Jan 2010 00:36:28 +0000
Subject: [PATCH 1071/2592] MFC r200641,200676

r200641:
  Document newly added loader tunable and sysctl variables.
   o hw.vge.msi_disable
   o dev.vge.%d.int_holdoff
   o dev.vge.%d.rx_coal_pkt
   o dev.vge.%d.tx_coal_pkt

r200676:
  Document more VIA Velocity family controllers to vge(4). Previously
  it mentioned only VT6122. While I'm here remove the mention of
  VT3119 which seems to be VIA's internal model name and VT3119
  wouldn't be available to end users.

  Reviewed by:  brueffer
---
 share/man/man4/vge.4 | 51 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/share/man/man4/vge.4 b/share/man/man4/vge.4
index 2e9c7a57488..7efc99ee121 100644
--- a/share/man/man4/vge.4
+++ b/share/man/man4/vge.4
@@ -30,12 +30,12 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 21, 2007
+.Dd December 18, 2009
 .Dt VGE 4
 .Os
 .Sh NAME
 .Nm vge
-.Nd "VIA Networking Technologies VT6122 PCI Gigabit Ethernet adapter driver"
+.Nd "VIA Networking Technologies Velocity Gigabit Ethernet adapter driver"
 .Sh SYNOPSIS
 To compile this driver into the kernel,
 place the following lines in your
@@ -55,22 +55,23 @@ if_vge_load="YES"
 The
 .Nm
 driver provides support for various NICs and embedded Ethernet interfaces
-based on the VIA Networking Technologies VT6122 Gigabit Ethernet
-controller chips.
+based on the VIA Technologies VT6120, VT6122, VT6130 and VT6132 Velocity
+Family Gigabit Ethernet controller chips.
 .Pp
-The VT6122 is a 33/66Mhz 64-bit PCI device which combines a tri-speed MAC with
-an integrated 10/100/1000 copper PHY.
+The VT6120/VT6122 is a 33/66Mhz 64-bit PCI device which combines a tri-speed
+MAC with an integrated 10/100/1000 copper PHY.
 (Some older cards use an external PHY.)
+The VT6130/VT6132 is the PCI express version of Velocity family.
 The MAC supports TCP/IP hardware
 checksums (IPv4 only), TCP large send, VLAN tag insertion and stripping,
 as well as VLAN filtering, a 64-entry CAM filter and a 64-entry VLAN filter,
 64-bit multicast hash filter, 4 separate transmit DMA queues, flow control
 and jumbo frames up to 16K in size.
-The VT6122 has a 16K receive FIFO and 48K transmit FIFO.
+The Velocity family controllers have a 16K receive FIFO and 48K transmit FIFO.
 .Pp
 The
 .Nm
-driver takes advantage of the VT6122's checksum offload and VLAN
+driver takes advantage of the controller's checksum offload and VLAN
 tagging features, as well as the jumbo frame and CAM filter support.
 The CAM filter is used for multicast address filtering to provide
 64 perfect multicast address filter support.
@@ -162,7 +163,7 @@ For more information on configuring this device, see
 .Sh HARDWARE
 The
 .Nm
-driver supports VIA Networking VT3119 and VT6122 based
+driver supports VIA Networking VT6120, VT6122, VT6130 and VT6132 based
 Gigabit Ethernet adapters including:
 .Pp
 .Bl -bullet -compact
@@ -173,6 +174,38 @@ ZyXEL GN650-T 64-bit PCI Gigabit Ethernet NIC (ZX1701)
 .It
 ZyXEL GN670-T 32-bit PCI Gigabit Ethernet NIC (ZX1702)
 .El
+.Sh LOADER TUNABLES
+Tunables can be set at the
+.Xr loader 8
+prompt before booting the kernel or stored in
+.Xr loader.conf 5 .
+.Bl -tag -width "xxxxxx"
+.It Va hw.vge.msi_disable
+This tunable disables MSI support on the Ethernet hardware.
+The default value is 0.
+.El
+.Sh SYSCTL VARIABLES
+The following variables are available as both
+.Xr sysctl 8
+variables and
+.Xr loader 8
+tunables:
+.Bl -tag -width "xxxxxx"
+.It Va dev.vge.%d.int_holdoff
+Maximum number of time to delay interrupts.
+The valid range is 0 to 5100 in units of 1us, the default is
+150 (150us).
+The resolution of of timer is about 20us so finer tuning than
+20us wouldn't be available.
+The interface should be brought down and up again before a change
+takes effect.
+.It Va dev.vge.%d.rx_coal_pkt
+Maximum number of packets to fire Rx completion interrupt.
+The valid range is 1 to 255, the default is 64.
+.It Va dev.vge.%d.tx_coal_pkt
+Maximum number of packets to fire Tx completion interrupt.
+The valid range is 1 to 255, the default is 128.
+.El
 .Sh DIAGNOSTICS
 .Bl -diag
 .It "vge%d: couldn't map memory"

From b7cf4e03b65f9fcd70870eecb245608321892840 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Sat, 9 Jan 2010 01:17:31 +0000
Subject: [PATCH 1072/2592] MFC r200693:   Make sure to enable Next Page bit
 for IP1001. Otherwise the PHY   fails to re-establishe 1000baseT link after
 downgrading to   10/100Mbps link.

---
 sys/dev/mii/ip1000phy.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/dev/mii/ip1000phy.c b/sys/dev/mii/ip1000phy.c
index 8e81d810b90..9b406d77895 100644
--- a/sys/dev/mii/ip1000phy.c
+++ b/sys/dev/mii/ip1000phy.c
@@ -398,8 +398,10 @@ ip1000phy_mii_phy_auto(struct mii_softc *sc)
 
 	isc = (struct ip1000phy_softc *)sc;
 	reg = 0;
-	if (isc->model == MII_MODEL_ICPLUS_IP1001)
+	if (isc->model == MII_MODEL_ICPLUS_IP1001) {
 		reg = PHY_READ(sc, IP1000PHY_MII_ANAR);
+		reg |= IP1000PHY_ANAR_NP;
+	}
 	reg |= IP1000PHY_ANAR_10T | IP1000PHY_ANAR_10T_FDX |
 	    IP1000PHY_ANAR_100TX | IP1000PHY_ANAR_100TX_FDX |
 	    IP1000PHY_ANAR_PAUSE | IP1000PHY_ANAR_APAUSE;

From f0c3103b9a2164522e2615291b66363e86ddb7f1 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sun, 10 Jan 2010 07:08:11 +0000
Subject: [PATCH 1073/2592] MFC r201756:

Re-apply onnv-gate revisions 7994 and 8986 (corresponds to FreeBSD
revision 200726 and 200727).

Reviewed by:  mm@
---
 .../opensolaris/uts/common/fs/zfs/dmu_send.c        | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
index 98032653227..5c97cd788d2 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -847,6 +847,12 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 	if (err != 0 && err != ENOENT)
 		return (EINVAL);
 
+	if (drro->drr_bonuslen) {
+		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
+		if (ra->err)
+			return (ra->err);
+	}
+
 	if (err == ENOENT) {
 		/* currently free, want to be allocated */
 		tx = dmu_tx_create(os);
@@ -862,7 +868,6 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 		dmu_tx_commit(tx);
 	} else {
 		/* currently allocated, want to be allocated */
-
 		err = dmu_object_reclaim(os, drro->drr_object,
 		    drro->drr_type, drro->drr_blksz,
 		    drro->drr_bonustype, drro->drr_bonuslen);
@@ -870,12 +875,6 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
 	if (err)
 		return (EINVAL);
 
-	if (drro->drr_bonuslen) {
-		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
-		if (ra->err)
-			return (ra->err);
-	}
-
 	tx = dmu_tx_create(os);
 	dmu_tx_hold_bonus(tx, drro->drr_object);
 	err = dmu_tx_assign(tx, TXG_WAIT);

From 28f48c5ccc8ca82b4c5bb59820f0bff91076b012 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sun, 10 Jan 2010 11:25:34 +0000
Subject: [PATCH 1074/2592] MFC r201743: Give some information on SF_MNOWAIT
 flag.

MFC r201759 (by brueffer):
Fix a typo and bump date for the previous commit.

MFC r201760:
Further fix grammar.
---
 lib/libc/sys/sendfile.2 | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/lib/libc/sys/sendfile.2 b/lib/libc/sys/sendfile.2
index 322971f0080..d9f8cab5673 100644
--- a/lib/libc/sys/sendfile.2
+++ b/lib/libc/sys/sendfile.2
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 24, 2006
+.Dd January 7, 2010
 .Dt SENDFILE 2
 .Os
 .Sh NAME
@@ -116,9 +116,17 @@ Busy servers may benefit by transferring requests that would
 block to a separate I/O worker thread.
 .It
 .Dv SF_MNOWAIT .
-(description missing)
+Do not wait for some kernel resource to become available,
+in particular,
+.Vt mbuf
+and
+.Vt sf_buf .
+The flag does not make the
+.Fn sendfile
+syscall truly non-blocking, since other resources are still allocated
+in a blocking fashion.
 .It
-.Dv SF_SYNC ,
+.Dv SF_SYNC .
 .Nm
 sleeps until the network stack no longer references the VM pages
 of the file, making subsequent modifications to it safe.

From cd56dc4253eb0f193fc0c1b23b2113b4d9b6f4a6 Mon Sep 17 00:00:00 2001
From: Fabien Thomas 
Date: Sun, 10 Jan 2010 16:00:00 +0000
Subject: [PATCH 1075/2592] MFC 201021: Log process mappings for existing
 processes at PMC start time.

---
 sys/dev/hwpmc/hwpmc_mod.c | 164 +++++++++++++++++++++++++++++++++++++-
 sys/sys/pmc.h             |   3 +-
 2 files changed, 163 insertions(+), 4 deletions(-)

diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index ee37cc60ac3..b8c87baa717 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -63,6 +63,12 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
+#include 
+#include 
+#include 
+#include 
+#include 
+
 /*
  * Types
  */
@@ -1619,6 +1625,151 @@ pmc_log_kernel_mappings(struct pmc *pm)
 static void
 pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
 {
+	vm_map_t map;
+	struct vnode *vp;
+	struct vmspace *vm;
+	vm_map_entry_t entry;
+	vm_offset_t last_end;
+	u_int last_timestamp;
+	struct vnode *last_vp;
+	vm_offset_t start_addr;
+	vm_object_t obj, lobj, tobj;
+	char *fullpath, *freepath;
+
+	last_vp = NULL;
+	last_end = (vm_offset_t) 0;
+	fullpath = freepath = NULL;
+
+	if ((vm = vmspace_acquire_ref(p)) == NULL)
+		return;
+
+	map = &vm->vm_map;
+	vm_map_lock_read(map);
+
+	for (entry = map->header.next; entry != &map->header; entry = entry->next) {
+
+		if (entry == NULL) {
+			PMCDBG(LOG,OPS,2, "hwpmc: vm_map entry unexpectedly "
+			    "NULL! pid=%d vm_map=%p\n", p->p_pid, map);
+			break;
+		}
+
+		/*
+		 * We only care about executable map entries.
+		 */
+		if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) ||
+		    !(entry->protection & VM_PROT_EXECUTE) ||
+		    (entry->object.vm_object == NULL)) {
+			continue;
+		}
+
+		obj = entry->object.vm_object;
+		VM_OBJECT_LOCK(obj);
+
+		/* 
+		 * Walk the backing_object list to find the base
+		 * (non-shadowed) vm_object.
+		 */
+		for (lobj = tobj = obj; tobj != NULL; tobj = tobj->backing_object) {
+			if (tobj != obj)
+				VM_OBJECT_LOCK(tobj);
+			if (lobj != obj)
+				VM_OBJECT_UNLOCK(lobj);
+			lobj = tobj;
+		}
+
+		/*
+		 * At this point lobj is the base vm_object and it is locked.
+		 */
+		if (lobj == NULL) {
+			PMCDBG(LOG,OPS,2, "hwpmc: lobj unexpectedly NULL! pid=%d "
+			    "vm_map=%p vm_obj=%p\n", p->p_pid, map, obj);
+			VM_OBJECT_UNLOCK(obj);
+			continue;
+		}
+
+		if (lobj->type != OBJT_VNODE || lobj->handle == NULL) {
+			if (lobj != obj)
+				VM_OBJECT_UNLOCK(lobj);
+			VM_OBJECT_UNLOCK(obj);
+			continue;
+		}
+
+		/*
+		 * Skip contiguous regions that point to the same
+		 * vnode, so we don't emit redundant MAP-IN
+		 * directives.
+		 */
+		if (entry->start == last_end && lobj->handle == last_vp) {
+			last_end = entry->end;
+			if (lobj != obj)
+				VM_OBJECT_UNLOCK(lobj);
+			VM_OBJECT_UNLOCK(obj);
+			continue;
+		}
+
+		/* 
+		 * We don't want to keep the proc's vm_map or this
+		 * vm_object locked while we walk the pathname, since
+		 * vn_fullpath() can sleep.  However, if we drop the
+		 * lock, it's possible for concurrent activity to
+		 * modify the vm_map list.  To protect against this,
+		 * we save the vm_map timestamp before we release the
+		 * lock, and check it after we reacquire the lock
+		 * below.
+		 */
+		start_addr = entry->start;
+		last_end = entry->end;
+		last_timestamp = map->timestamp;
+		vm_map_unlock_read(map);
+
+		vp = lobj->handle;
+		vref(vp);
+		if (lobj != obj)
+			VM_OBJECT_UNLOCK(lobj);
+
+		VM_OBJECT_UNLOCK(obj);
+
+		freepath = NULL;
+		pmc_getfilename(vp, &fullpath, &freepath);
+		last_vp = vp;
+		vrele(vp);
+		vp = NULL;
+		pmclog_process_map_in(po, p->p_pid, start_addr, fullpath);
+		if (freepath)
+			free(freepath, M_TEMP);
+
+		vm_map_lock_read(map);
+
+		/*
+		 * If our saved timestamp doesn't match, this means
+		 * that the vm_map was modified out from under us and
+		 * we can't trust our current "entry" pointer.  Do a
+		 * new lookup for this entry.  If there is no entry
+		 * for this address range, vm_map_lookup_entry() will
+		 * return the previous one, so we always want to go to
+		 * entry->next on the next loop iteration.
+		 * 
+		 * There is an edge condition here that can occur if
+		 * there is no entry at or before this address.  In
+		 * this situation, vm_map_lookup_entry returns
+		 * &map->header, which would cause our loop to abort
+		 * without processing the rest of the map.  However,
+		 * in practice this will never happen for process
+		 * vm_map.  This is because the executable's text
+		 * segment is the first mapping in the proc's address
+		 * space, and this mapping is never removed until the
+		 * process exits, so there will always be a non-header
+		 * entry at or before the requested address for
+		 * vm_map_lookup_entry to return.
+		 */
+		if (map->timestamp != last_timestamp)
+			vm_map_lookup_entry(map, last_end - 1, &entry);
+	}
+
+	vm_map_unlock_read(map);
+	vmspace_free(vm);
+	return;
 }
 
 /*
@@ -1897,7 +2048,7 @@ pmc_allocate_owner_descriptor(struct proc *p)
 
 	/* allocate space for N pointers and one descriptor struct */
 	po = malloc(sizeof(struct pmc_owner), M_PMC, M_WAITOK|M_ZERO);
-	po->po_sscount = po->po_error = po->po_flags = 0;
+	po->po_sscount = po->po_error = po->po_flags = po->po_logprocmaps = 0;
 	po->po_file  = NULL;
 	po->po_owner = p;
 	po->po_kthread = NULL;
@@ -2520,8 +2671,15 @@ pmc_start(struct pmc *pm)
 		po->po_sscount++;
 	}
 
-	/* Log mapping information for all processes in the system. */
-	pmc_log_all_process_mappings(po);
+	/*
+	 * Log mapping information for all existing processes in the
+	 * system.  Subsequent mappings are logged as they happen;
+	 * see pmc_process_mmap().
+	 */
+	if (po->po_logprocmaps == 0) {
+		pmc_log_all_process_mappings(po);
+		po->po_logprocmaps = 1;
+	}
 
 	/*
 	 * Move to the CPU associated with this
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index 68d7df0af14..13ae433983d 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -750,7 +750,8 @@ struct pmc_owner  {
 	struct pmclog_buffer	*po_curbuf;	/* current log buffer */
 	struct file		*po_file;	/* file reference */
 	int			po_error;	/* recorded error */
-	int			po_sscount;	/* # SS PMCs owned */
+	short			po_sscount;	/* # SS PMCs owned */
+	short			po_logprocmaps;	/* global mappings done */
 };
 
 #define	PMC_PO_OWNS_LOGFILE		0x00000001 /* has a log file */

From a267011a08d5da690383ee1275de08578419066d Mon Sep 17 00:00:00 2001
From: Fabien Thomas 
Date: Sun, 10 Jan 2010 16:04:32 +0000
Subject: [PATCH 1076/2592] MFC 201023:  * Support the L1D_CACHE_LD event on
 Core2 processors.  * Correct a group of typos: for Core2 programmable events,
 check    user supplied umask values against the correct event descriptor   
 field.

---
 sys/dev/hwpmc/hwpmc_core.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
index b6de04dfce8..43a49143fc3 100644
--- a/sys/dev/hwpmc/hwpmc_core.c
+++ b/sys/dev/hwpmc/hwpmc_core.c
@@ -669,7 +669,7 @@ static struct iap_event_descr iap_events[] = {
     IAPDESCR(3CH_01H, 0x3C, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
     IAPDESCR(3CH_02H, 0x3C, 0x02, IAP_F_FM | IAP_F_ALLCPUS),
 
-    IAPDESCR(40H, 0x40, IAP_M_MESI, IAP_F_CC),
+    IAPDESCR(40H, 0x40, IAP_M_MESI, IAP_F_CC | IAP_F_CC2),
     IAPDESCR(40H_21H, 0x40, 0x21, IAP_F_FM | IAP_F_CA),
 
     IAPDESCR(41H, 0x41, IAP_M_MESI, IAP_F_CC | IAP_F_CC2),
@@ -1419,17 +1419,17 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
 
 		mask = 0;
 
-		if (ie->iap_flags & IAP_M_CORE) {
+		if (ie->iap_umask & IAP_M_CORE) {
 			if ((c = (config & IAP_F_CORE)) != IAP_CORE_ALL &&
 			    c != IAP_CORE_THIS)
 				return (EINVAL);
 			mask |= IAP_F_CORE;
 		}
 
-		if (ie->iap_flags & IAP_M_AGENT)
+		if (ie->iap_umask & IAP_M_AGENT)
 			mask |= IAP_F_AGENT;
 
-		if (ie->iap_flags & IAP_M_PREFETCH) {
+		if (ie->iap_umask & IAP_M_PREFETCH) {
 
 			if ((c = (config & IAP_F_PREFETCH)) ==
 			    IAP_PREFETCH_RESERVED)
@@ -1438,16 +1438,16 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
 			mask |= IAP_F_PREFETCH;
 		}
 
-		if (ie->iap_flags & IAP_M_MESI)
+		if (ie->iap_umask & IAP_M_MESI)
 			mask |= IAP_F_MESI;
 
-		if (ie->iap_flags & IAP_M_SNOOPRESPONSE)
+		if (ie->iap_umask & IAP_M_SNOOPRESPONSE)
 			mask |= IAP_F_SNOOPRESPONSE;
 
-		if (ie->iap_flags & IAP_M_SNOOPTYPE)
+		if (ie->iap_umask & IAP_M_SNOOPTYPE)
 			mask |= IAP_F_SNOOPTYPE;
 
-		if (ie->iap_flags & IAP_M_TRANSITION)
+		if (ie->iap_umask & IAP_M_TRANSITION)
 			mask |= IAP_F_TRANSITION;
 
 		/*

From 40095a24edebf3b01e0bbf5ddac944cb2c482686 Mon Sep 17 00:00:00 2001
From: Fabien Thomas 
Date: Sun, 10 Jan 2010 16:08:14 +0000
Subject: [PATCH 1077/2592] MFC 201151:  Use VFS_{LOCK,UNLOCK}_GIANT() around
 the call to vrele().

---
 sys/dev/hwpmc/hwpmc_mod.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index b8c87baa717..f35e11da872 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1625,6 +1626,7 @@ pmc_log_kernel_mappings(struct pmc *pm)
 static void
 pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
 {
+	int locked;
 	vm_map_t map;
 	struct vnode *vp;
 	struct vmspace *vm;
@@ -1733,7 +1735,11 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
 		freepath = NULL;
 		pmc_getfilename(vp, &fullpath, &freepath);
 		last_vp = vp;
+
+		locked = VFS_LOCK_GIANT(vp->v_mount);
 		vrele(vp);
+		VFS_UNLOCK_GIANT(locked);
+
 		vp = NULL;
 		pmclog_process_map_in(po, p->p_pid, start_addr, fullpath);
 		if (freepath)

From 86892d512c035f426a76e76568f61843eb2108b7 Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Sun, 10 Jan 2010 16:58:12 +0000
Subject: [PATCH 1078/2592] MFC r210428: sh: Add a regression test that tries
 out all arithmetic ops.

The gaps in the numbering sequence cannot really be avoided, as HEAD changes
are not necessarily merged in the same order as they are made (if they are
merged at all).
---
 tools/regression/bin/sh/expansion/arith2.0 | 76 ++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 tools/regression/bin/sh/expansion/arith2.0

diff --git a/tools/regression/bin/sh/expansion/arith2.0 b/tools/regression/bin/sh/expansion/arith2.0
new file mode 100644
index 00000000000..c4fdccd5531
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/arith2.0
@@ -0,0 +1,76 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+	if [ $(($1)) != $2 ]; then
+		failures=$((failures+1))
+		echo "For $1, expected $2 actual $(($1))"
+	fi
+}
+
+# variables
+unset v
+check "v=2" 2
+check "v" 2
+check "$(($v))" 2
+check "v+=1" 3
+check "v" 3
+
+# constants
+check "4611686018427387904" 4611686018427387904
+check "0x4000000000000000" 4611686018427387904
+check "0400000000000000000000" 4611686018427387904
+check "0x4Ab0000000000000" 5381801554707742720
+
+# try out all operators
+v=42
+check "!v" 0
+check "!!v" 1
+check "!0" 1
+check "~0" -1
+check "~(-1)" 0
+check "-0" 0
+check "-v" -42
+check "v*v" 1764
+check "v/2" 21
+check "v%10" 2
+check "v+v" 84
+check "v-4" 38
+check "v<<1" 84
+check "v>>1" 21
+check "v<43" 1
+check "v>42" 0
+check "v<=43" 1
+check "v>=43" 0
+check "v==41" 0
+check "v!=42" 0
+check "v&3" 2
+check "v^3" 41
+check "v|3" 43
+check "v>=40&&v<=44" 1
+check "v<40||v>44" 0
+check "(v=42)&&(v+=1)==43" 1
+check "v" 43
+check "(v=42)&&(v-=1)==41" 1
+check "v" 41
+check "(v=42)&&(v*=2)==84" 1
+check "v" 84
+check "(v=42)&&(v/=10)==4" 1
+check "v" 4
+check "(v=42)&&(v%=10)==2" 1
+check "v" 2
+check "(v=42)&&(v<<=1)==84" 1
+check "v" 84
+check "(v=42)&&(v>>=2)==10" 1
+check "v" 10
+check "(v=42)&&(v&=32)==32" 1
+check "v" 32
+check "(v=42)&&(v^=32)==10" 1
+check "v" 10
+check "(v=42)&&(v|=32)==42" 1
+check "v" 42
+
+# missing: ternary, comma
+
+exit $((failures != 0))

From 1bb65f7e64ea9eeac7c34bcb64bf973311d3c65c Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Sun, 10 Jan 2010 23:51:02 +0000
Subject: [PATCH 1079/2592] MFC rev 201269, 201373: o   Revamp bus_space access
 functions (201269). o   Change BUS_SPACE_MAXADDR from 2^32-1 to 2^64-1
 (201373).

---
 sys/conf/files.ia64         |   1 +
 sys/ia64/ia64/bus_machdep.c | 356 +++++++++++++++++
 sys/ia64/ia64/machdep.c     |  10 -
 sys/ia64/ia64/mp_machdep.c  |   2 +-
 sys/ia64/ia64/nexus.c       |  37 +-
 sys/ia64/ia64/sys_machdep.c |   1 +
 sys/ia64/include/bus.h      | 767 ++++++++++++++++++------------------
 sys/ia64/include/cpufunc.h  | 120 ------
 8 files changed, 773 insertions(+), 521 deletions(-)
 create mode 100644 sys/ia64/ia64/bus_machdep.c

diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64
index ad9d8e5ce57..032407c073b 100644
--- a/sys/conf/files.ia64
+++ b/sys/conf/files.ia64
@@ -75,6 +75,7 @@ ia64/ia32/ia32_reg.c		optional	compat_ia32
 ia64/ia32/ia32_signal.c		optional	compat_ia32
 ia64/ia32/ia32_trap.c		optional	compat_ia32
 ia64/ia64/autoconf.c		standard
+ia64/ia64/bus_machdep.c		standard
 ia64/ia64/busdma_machdep.c	standard
 ia64/ia64/clock.c		standard
 ia64/ia64/context.S		standard
diff --git a/sys/ia64/ia64/bus_machdep.c b/sys/ia64/ia64/bus_machdep.c
new file mode 100644
index 00000000000..f9e019bfc64
--- /dev/null
+++ b/sys/ia64/ia64/bus_machdep.c
@@ -0,0 +1,356 @@
+/*-
+ * 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 
+
+extern u_long ia64_port_base;
+
+#define __PIO_ADDR(port)        \
+        (void *)(ia64_port_base | (((port) & 0xfffc) << 10) | ((port) & 0xFFF))
+
+uint8_t
+bus_space_read_io_1(u_long port)
+{
+	uint8_t v;
+
+	ia64_mf();
+	v = ia64_ld1(__PIO_ADDR(port));
+	ia64_mf_a();
+	ia64_mf();
+	return (v);
+}
+
+uint16_t
+bus_space_read_io_2(u_long port)
+{
+	uint16_t v;
+
+	ia64_mf();
+	v = ia64_ld2(__PIO_ADDR(port));
+	ia64_mf_a();
+	ia64_mf();
+	return (v);
+}
+
+uint32_t
+bus_space_read_io_4(u_long port)
+{
+	uint32_t v;
+
+	ia64_mf();
+	v = ia64_ld4(__PIO_ADDR(port));
+	ia64_mf_a();
+	ia64_mf();
+	return (v);
+}
+
+#if 0
+uint64_t
+bus_space_read_io_8(u_long port)
+{
+}
+#endif
+
+void
+bus_space_write_io_1(u_long port, uint8_t val)
+{
+
+	ia64_mf();
+	ia64_st1(__PIO_ADDR(port), val);
+	ia64_mf_a();
+	ia64_mf();
+}
+
+void
+bus_space_write_io_2(u_long port, uint16_t val)
+{
+
+	ia64_mf();
+	ia64_st2(__PIO_ADDR(port), val);
+	ia64_mf_a();
+	ia64_mf();
+}
+
+void
+bus_space_write_io_4(u_long port, uint32_t val)
+{
+
+	ia64_mf();
+	ia64_st4(__PIO_ADDR(port), val);
+	ia64_mf_a();
+	ia64_mf();
+}
+
+#if 0
+void
+bus_space_write_io_8(u_long port, uint64_t val)
+{
+}
+#endif
+
+void
+bus_space_read_multi_io_1(u_long port, uint8_t *ptr, size_t count)
+{
+
+	while (count-- > 0)
+		*ptr++ = bus_space_read_io_1(port);
+}
+
+void
+bus_space_read_multi_io_2(u_long port, uint16_t *ptr, size_t count)
+{
+
+	while (count-- > 0)
+		*ptr++ = bus_space_read_io_2(port);
+}
+
+void
+bus_space_read_multi_io_4(u_long port, uint32_t *ptr, size_t count)
+{
+
+	while (count-- > 0)
+		*ptr++ = bus_space_read_io_4(port);
+}
+
+#if 0
+void
+bus_space_read_multi_io_8(u_long port, uint64_t *ptr, size_t count)
+{
+}
+#endif
+
+void
+bus_space_write_multi_io_1(u_long port, const uint8_t *ptr, size_t count)
+{
+
+	while (count-- > 0)
+		bus_space_write_io_1(port, *ptr++);
+}
+
+void
+bus_space_write_multi_io_2(u_long port, const uint16_t *ptr, size_t count)
+{
+
+	while (count-- > 0)
+		bus_space_write_io_2(port, *ptr++);
+}
+
+void
+bus_space_write_multi_io_4(u_long port, const uint32_t *ptr, size_t count)
+{
+
+	while (count-- > 0)
+		bus_space_write_io_4(port, *ptr++);
+}
+
+#if 0
+void
+bus_space_write_multi_io_8(u_long port, const uint64_t *ptr, size_t count)
+{
+}
+#endif
+
+void
+bus_space_read_region_io_1(u_long port, uint8_t *ptr, size_t count)
+{
+
+	while (count-- > 0) {
+		*ptr++ = bus_space_read_io_1(port);
+		port += 1;
+	}
+}
+
+void
+bus_space_read_region_io_2(u_long port, uint16_t *ptr, size_t count) 
+{
+
+	while (count-- > 0) {
+		*ptr++ = bus_space_read_io_2(port);
+		port += 2;
+	}
+}
+
+void
+bus_space_read_region_io_4(u_long port, uint32_t *ptr, size_t count) 
+{
+
+	while (count-- > 0) {
+		*ptr++ = bus_space_read_io_4(port);
+		port += 4;
+	}
+}
+
+#if 0
+void bus_space_read_region_io_8(u_long, uint64_t *, size_t);
+#endif
+
+void
+bus_space_write_region_io_1(u_long port, const uint8_t *ptr, size_t count)
+{
+
+	while (count-- > 0) {
+		bus_space_write_io_1(port, *ptr++);
+		port += 1;
+	}
+}
+
+void
+bus_space_write_region_io_2(u_long port, const uint16_t *ptr, size_t count)
+{
+
+	while (count-- > 0) {
+		bus_space_write_io_2(port, *ptr++);
+		port += 2;
+	}
+}
+
+void
+bus_space_write_region_io_4(u_long port, const uint32_t *ptr, size_t count)
+{
+
+	while (count-- > 0) {
+		bus_space_write_io_4(port, *ptr++);
+		port += 4;
+	}
+}
+
+#if 0
+void
+bus_space_write_region_io_8(u_long port, const uint64_t *ptr, size_t count)
+{
+}
+#endif
+
+void
+bus_space_set_region_io_1(u_long port, uint8_t val, size_t count)
+{
+
+	while (count-- > 0) {
+		bus_space_write_io_1(port, val);
+		port += 1;
+	}
+}
+
+void
+bus_space_set_region_io_2(u_long port, uint16_t val, size_t count)
+{
+
+	while (count-- > 0) {
+		bus_space_write_io_2(port, val);
+		port += 2;
+	}
+}
+
+void
+bus_space_set_region_io_4(u_long port, uint32_t val, size_t count)
+{
+
+	while (count-- > 0) {
+		bus_space_write_io_4(port, val);
+		port += 4;
+	}
+}
+
+#if 0
+void
+bus_space_set_region_io_8(u_long port, uint64_t val, size_t count)
+{
+}
+#endif
+
+void 
+bus_space_copy_region_io_1(u_long src, u_long dst, size_t count) 
+{
+	long delta;
+	uint8_t val;
+
+	if (src < dst) {
+		src += count - 1;
+		dst += count - 1;
+		delta = -1;
+	} else
+		delta = 1;
+
+	while (count-- > 0) {
+		val = bus_space_read_io_1(src);
+		bus_space_write_io_1(dst, val);
+		src += delta;
+		dst += delta;
+	}
+}
+
+void 
+bus_space_copy_region_io_2(u_long src, u_long dst, size_t count) 
+{
+	long delta;
+	uint16_t val;
+
+	if (src < dst) {
+		src += 2 * (count - 1);
+		dst += 2 * (count - 1);
+		delta = -2;
+	} else
+		delta = 2;
+
+	while (count-- > 0) {
+		val = bus_space_read_io_2(src);
+		bus_space_write_io_2(dst, val);
+		src += delta;
+		dst += delta;
+	}
+}
+
+void 
+bus_space_copy_region_io_4(u_long src, u_long dst, size_t count) 
+{
+	long delta;
+	uint32_t val;
+
+	if (src < dst) {
+		src += 4 * (count - 1);
+		dst += 4 * (count - 1);
+		delta = -4;
+	} else
+		delta = 4;
+
+	while (count-- > 0) {
+		val = bus_space_read_io_4(src);
+		bus_space_write_io_4(dst, val);
+		src += delta;
+		dst += delta;
+	}
+}
+
+#if 0
+void
+bus_space_copy_region_io_8(u_long src, u_long dst, size_t count)
+{
+}
+#endif
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 684bf2623ee..95b604f6c9f 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -930,16 +930,6 @@ ia64_init(void)
 	return (ret);
 }
 
-void *
-ia64_ioport_address(u_int port)
-{
-	uint64_t addr;
-
-	addr = (port > 0xffff) ? IA64_PHYS_TO_RR6((uint64_t)port) :
-	    ia64_port_base | ((port & 0xfffc) << 10) | (port & 0xFFF);
-	return ((void *)addr);
-}
-
 uint64_t
 ia64_get_hcdp(void)
 {
diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c
index 020c71b0f83..9cbf7705df9 100644
--- a/sys/ia64/ia64/mp_machdep.c
+++ b/sys/ia64/ia64/mp_machdep.c
@@ -366,7 +366,7 @@ ipi_send(struct pcpu *cpu, int ipi)
 	volatile uint64_t *pipi;
 	uint64_t vector;
 
-	pipi = __MEMIO_ADDR(ia64_lapic_address |
+	pipi = (void *)IA64_PHYS_TO_RR6(ia64_lapic_address |
 	    ((cpu->pc_md.lid & LID_SAPIC_MASK) >> 12));
 	vector = (uint64_t)(ipi_vector[ipi] & 0xff);
 	KASSERT(vector != 0, ("IPI %d is not assigned a vector", ipi));
diff --git a/sys/ia64/ia64/nexus.c b/sys/ia64/ia64/nexus.c
index 502dc72a4fc..5ce4731eb8f 100644
--- a/sys/ia64/ia64/nexus.c
+++ b/sys/ia64/ia64/nexus.c
@@ -389,26 +389,23 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
 
 static int
 nexus_activate_resource(device_t bus, device_t child, int type, int rid,
-			struct resource *r)
+    struct resource *r)
 {
-	vm_paddr_t paddr, psize;
+	vm_paddr_t paddr;
 	void *vaddr;
 
-	/*
-	 * If this is a memory resource, map it into the kernel.
-	 */
+	paddr = rman_get_start(r);
+
 	switch (type) {
 	case SYS_RES_IOPORT:
 		rman_set_bustag(r, IA64_BUS_SPACE_IO);
-		rman_set_bushandle(r, rman_get_start(r));
+		rman_set_bushandle(r, paddr);
 		break;
 	case SYS_RES_MEMORY:
-		paddr = rman_get_start(r);
-		psize = rman_get_size(r);
-		vaddr = pmap_mapdev(paddr, psize);
-		rman_set_virtual(r, vaddr);
+		vaddr = pmap_mapdev(paddr, rman_get_size(r));
 		rman_set_bustag(r, IA64_BUS_SPACE_MEM);
-		rman_set_bushandle(r, (bus_space_handle_t) paddr);
+		rman_set_bushandle(r, (bus_space_handle_t) vaddr);
+		rman_set_virtual(r, vaddr);
 		break;
 	}
 	return (rman_activate_resource(r));
@@ -488,11 +485,27 @@ nexus_get_reslist(device_t dev, device_t child)
 }
 
 static int
-nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count)
+nexus_set_resource(device_t dev, device_t child, int type, int rid,
+    u_long start, u_long count)
 {
 	struct nexus_device	*ndev = DEVTONX(child);
 	struct resource_list	*rl = &ndev->nx_resources;
 
+	if (type == SYS_RES_IOPORT && start > (0x10000 - count)) {
+		/*
+		 * Work around a firmware bug in the HP rx2660, where in ACPI
+		 * an I/O port is really a memory mapped I/O address. The bug
+		 * is in the GAS that describes the address and in particular
+		 * the SpaceId field. The field should not say the address is
+		 * an I/O port when it is in fact an I/O memory address.
+		 */
+		if (bootverbose)
+			printf("%s: invalid port range (%#lx-%#lx); "
+			    "assuming I/O memory range.\n", __func__, start,
+			    start + count - 1);
+		type = SYS_RES_MEMORY;
+	}
+
 	/* XXX this should return a success/failure indicator */
 	resource_list_add(rl, type, rid, start, start + count - 1, count);
 	return(0);
diff --git a/sys/ia64/ia64/sys_machdep.c b/sys/ia64/ia64/sys_machdep.c
index d4dcc1fd536..e39cbab621e 100644
--- a/sys/ia64/ia64/sys_machdep.c
+++ b/sys/ia64/ia64/sys_machdep.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
+#include 
 #include 
 #include 
 
diff --git a/sys/ia64/include/bus.h b/sys/ia64/include/bus.h
index 80b90cadc65..a2a02a09f5a 100644
--- a/sys/ia64/include/bus.h
+++ b/sys/ia64/include/bus.h
@@ -1,3 +1,29 @@
+/*-
+ * 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.
+ */
+
 /*	$NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $	*/
 
 /*-
@@ -75,39 +101,50 @@
 #include 
 #include 
 
+/*
+ * I/O port reads with ia32 semantics.
+ */
+#define inb     bus_space_read_io_1
+#define inw     bus_space_read_io_2
+#define inl     bus_space_read_io_4
+
+#define outb    bus_space_write_io_1
+#define outw    bus_space_write_io_2
+#define outl    bus_space_write_io_4
+
 /*
  * Values for the ia64 bus space tag, not to be used directly by MI code.
  */
 #define	IA64_BUS_SPACE_IO	0	/* space is i/o space */
 #define IA64_BUS_SPACE_MEM	1	/* space is mem space */
 
+#define	BUS_SPACE_BARRIER_READ	0x01	/* force read barrier */
+#define	BUS_SPACE_BARRIER_WRITE	0x02	/* force write barrier */
+
 #define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
 #define BUS_SPACE_MAXSIZE	0xFFFFFFFFFFFFFFFF
 #define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
-#define BUS_SPACE_MAXADDR	0xFFFFFFFF
+#define BUS_SPACE_MAXADDR	0xFFFFFFFFFFFFFFFF
 
 #define BUS_SPACE_UNRESTRICTED	(~0)
 
+
 /*
  * Map a region of device bus space into CPU virtual address space.
  */
-
-static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
-				  bus_size_t size, int flags,
-				  bus_space_handle_t *bshp);
-
 static __inline int
-bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
-	      bus_size_t size __unused, int flags __unused,
-	      bus_space_handle_t *bshp)
+bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size __unused,
+    int flags __unused, bus_space_handle_t *bshp)
 {
 
-	*bshp = addr;
+	*bshp = (__predict_false(bst == IA64_BUS_SPACE_IO))
+	    ? addr : IA64_PHYS_TO_RR6(addr);
 	return (0);
 }
 
+
 /*
  * Unmap a region of device bus space.
  */
@@ -123,7 +160,7 @@ bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh __unused,
  */
 static __inline int
 bus_space_subregion(bus_space_tag_t bst, bus_space_handle_t bsh,
-    bus_size_t ofs, bus_size_t size, bus_space_handle_t *nbshp)
+    bus_size_t ofs, bus_size_t size __unused, bus_space_handle_t *nbshp)
 {
 	*nbshp = bsh + ofs;
 	return (0);
@@ -149,12 +186,9 @@ bus_space_free(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size);
 /*
  * Bus read/write barrier method.
  */
-#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
-#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
-
 static __inline void
-bus_space_barrier(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
-    bus_size_t size, int flags)
+bus_space_barrier(bus_space_tag_t bst __unused, bus_space_handle_t bsh __unused,
+    bus_size_t ofs __unused, bus_size_t size __unused, int flags __unused)
 {
 	ia64_mf_a();
 	ia64_mf();
@@ -166,40 +200,53 @@ bus_space_barrier(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
  * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
  * data is returned.
  */
+uint8_t  bus_space_read_io_1(u_long);
+uint16_t bus_space_read_io_2(u_long);
+uint32_t bus_space_read_io_4(u_long);
+uint64_t bus_space_read_io_8(u_long);
+
 static __inline uint8_t
 bus_space_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
 {
-	uint8_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	return (ia64_ld1(bsp));
+	uint8_t val;
+
+	val = (__predict_false(bst == IA64_BUS_SPACE_IO))
+	    ? bus_space_read_io_1(bsh + ofs)
+	    : ia64_ld1((void *)(bsh + ofs));
+	return (val);
 }
 
 static __inline uint16_t
 bus_space_read_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
 {
-	uint16_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	return (ia64_ld2(bsp));
+	uint16_t val;
+
+	val = (__predict_false(bst == IA64_BUS_SPACE_IO))
+	    ? bus_space_read_io_2(bsh + ofs)
+	    : ia64_ld2((void *)(bsh + ofs));
+	return (val);
 }
 
 static __inline uint32_t
 bus_space_read_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
 {
-	uint32_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	return (ia64_ld4(bsp));
+	uint32_t val;
+
+	val = (__predict_false(bst == IA64_BUS_SPACE_IO))
+	    ? bus_space_read_io_4(bsh + ofs)
+	    : ia64_ld4((void *)(bsh + ofs));
+	return (val);
 }
 
 static __inline uint64_t
 bus_space_read_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
 {
-	uint64_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	return (ia64_ld8(bsp));
+	uint64_t val;
+
+	val = (__predict_false(bst == IA64_BUS_SPACE_IO))
+	    ? bus_space_read_io_8(bsh + ofs)
+	    : ia64_ld8((void *)(bsh + ofs));
+	return (val);
 }
 
 
@@ -208,44 +255,53 @@ bus_space_read_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
  * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
  * data is passed by value.
  */
+void bus_space_write_io_1(u_long, uint8_t);
+void bus_space_write_io_2(u_long, uint16_t);
+void bus_space_write_io_4(u_long, uint32_t);
+void bus_space_write_io_8(u_long, uint64_t);
+
 static __inline void
 bus_space_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
     uint8_t val)
 {
-	uint8_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	ia64_st1(bsp, val);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_io_1(bsh + ofs, val);
+	else
+		ia64_st1((void *)(bsh + ofs), val);
 }
 
 static __inline void
 bus_space_write_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
     uint16_t val)
 {
-	uint16_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	ia64_st2(bsp, val);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_io_2(bsh + ofs, val);
+	else
+		ia64_st2((void *)(bsh + ofs), val);
 }
 
 static __inline void
 bus_space_write_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
     uint32_t val)
 {
-	uint32_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	ia64_st4(bsp, val);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_io_4(bsh + ofs, val);
+	else
+		ia64_st4((void *)(bsh + ofs), val);
 }
 
 static __inline void
 bus_space_write_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
     uint64_t val)
 {
-	uint64_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	ia64_st8(bsp, val);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_io_8(bsh + ofs, val);
+	else
+		ia64_st8((void *)(bsh + ofs), val);
 }
 
 
@@ -254,48 +310,61 @@ bus_space_write_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
  * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
  * data is returned in the buffer passed by reference.
  */
+void bus_space_read_multi_io_1(u_long, uint8_t *, size_t);
+void bus_space_read_multi_io_2(u_long, uint16_t *, size_t);
+void bus_space_read_multi_io_4(u_long, uint32_t *, size_t);
+void bus_space_read_multi_io_8(u_long, uint64_t *, size_t);
+
 static __inline void
 bus_space_read_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint8_t *bufp, size_t count)
 {
-	uint8_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	while (count-- > 0)
-		*bufp++ = ia64_ld1(bsp);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_read_multi_io_1(bsh + ofs, bufp, count);
+	else {
+		while (count-- > 0)
+			*bufp++ = ia64_ld1((void *)(bsh + ofs));
+	}
 }
 
 static __inline void
 bus_space_read_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint16_t *bufp, size_t count)
 {
-	uint16_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	while (count-- > 0)
-		*bufp++ = ia64_ld2(bsp);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_read_multi_io_2(bsh + ofs, bufp, count);
+	else {
+		while (count-- > 0)
+			*bufp++ = ia64_ld2((void *)(bsh + ofs));
+	}
 }
 
 static __inline void
 bus_space_read_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint32_t *bufp, size_t count)
 {
-	uint32_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	while (count-- > 0)
-		*bufp++ = ia64_ld4(bsp);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_read_multi_io_4(bsh + ofs, bufp, count);
+	else {
+		while (count-- > 0)
+			*bufp++ = ia64_ld4((void *)(bsh + ofs));
+	}
 }
 
 static __inline void
 bus_space_read_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint64_t *bufp, size_t count)
 {
-	uint64_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	while (count-- > 0)
-		*bufp++ = ia64_ld8(bsp);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_read_multi_io_8(bsh + ofs, bufp, count);
+	else {
+		while (count-- > 0)
+			*bufp++ = ia64_ld8((void *)(bsh + ofs));
+	}
 }
 
 
@@ -304,48 +373,61 @@ bus_space_read_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
  * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
  * data is read from the buffer passed by reference.
  */
+void bus_space_write_multi_io_1(u_long, const uint8_t *, size_t);
+void bus_space_write_multi_io_2(u_long, const uint16_t *, size_t);
+void bus_space_write_multi_io_4(u_long, const uint32_t *, size_t);
+void bus_space_write_multi_io_8(u_long, const uint64_t *, size_t);
+
 static __inline void
 bus_space_write_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, const uint8_t *bufp, size_t count)
 {
-	uint8_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	while (count-- > 0)
-		ia64_st1(bsp, *bufp++);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_multi_io_1(bsh + ofs, bufp, count);
+	else {
+		while (count-- > 0)
+			ia64_st1((void *)(bsh + ofs), *bufp++);
+	}
 }
 
 static __inline void
 bus_space_write_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, const uint16_t *bufp, size_t count)
 {
-	uint16_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	while (count-- > 0)
-		ia64_st2(bsp, *bufp++);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_multi_io_2(bsh + ofs, bufp, count);
+	else {
+		while (count-- > 0)
+			ia64_st2((void *)(bsh + ofs), *bufp++);
+	}
 }
 
 static __inline void
 bus_space_write_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, const uint32_t *bufp, size_t count)
 {
-	uint32_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	while (count-- > 0)
-		ia64_st4(bsp, *bufp++);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_multi_io_4(bsh + ofs, bufp, count);
+	else {
+		while (count-- > 0)
+			ia64_st4((void *)(bsh + ofs), *bufp++);
+	}
 }
 
 static __inline void
 bus_space_write_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, const uint64_t *bufp, size_t count)
 {
-	uint64_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
-	while (count-- > 0)
-		ia64_st8(bsp, *bufp++);
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_multi_io_8(bsh + ofs, bufp, count);
+	else {
+		while (count-- > 0)
+			ia64_st8((void *)(bsh + ofs), *bufp++);
+	}
 }
 
 
@@ -355,16 +437,22 @@ bus_space_write_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
  * data is written to the buffer passed by reference and read from successive
  * bus space addresses. Access is unordered.
  */
+void bus_space_read_region_io_1(u_long, uint8_t *, size_t);
+void bus_space_read_region_io_2(u_long, uint16_t *, size_t);
+void bus_space_read_region_io_4(u_long, uint32_t *, size_t);
+void bus_space_read_region_io_8(u_long, uint64_t *, size_t);
+
 static __inline void
 bus_space_read_region_1(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint8_t *bufp, size_t count)
 {
-	uint8_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		*bufp++ = ia64_ld1(bsp);
-		ofs += 1;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_read_region_io_1(bsh + ofs, bufp, count);
+	else {
+		uint8_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			*bufp++ = ia64_ld1(bsp++);
 	}
 }
 
@@ -372,12 +460,13 @@ static __inline void
 bus_space_read_region_2(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint16_t *bufp, size_t count)
 {
-	uint16_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		*bufp++ = ia64_ld2(bsp);
-		ofs += 2;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_read_region_io_2(bsh + ofs, bufp, count);
+	else {
+		uint16_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			*bufp++ = ia64_ld2(bsp++);
 	}
 }
 
@@ -385,12 +474,13 @@ static __inline void
 bus_space_read_region_4(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint32_t *bufp, size_t count)
 {
-	uint32_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		*bufp++ = ia64_ld4(bsp);
-		ofs += 4;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_read_region_io_4(bsh + ofs, bufp, count);
+	else {
+		uint32_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			*bufp++ = ia64_ld4(bsp++);
 	}
 }
 
@@ -398,12 +488,13 @@ static __inline void
 bus_space_read_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint64_t *bufp, size_t count)
 {
-	uint64_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		*bufp++ = ia64_ld8(bsp);
-		ofs += 8;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_read_region_io_8(bsh + ofs, bufp, count);
+	else {
+		uint64_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			*bufp++ = ia64_ld8(bsp++);
 	}
 }
 
@@ -414,16 +505,22 @@ bus_space_read_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
  * data is read from the buffer passed by reference and written to successive
  * bus space addresses. Access is unordered.
  */
+void bus_space_write_region_io_1(u_long, const uint8_t *, size_t);
+void bus_space_write_region_io_2(u_long, const uint16_t *, size_t);
+void bus_space_write_region_io_4(u_long, const uint32_t *, size_t);
+void bus_space_write_region_io_8(u_long, const uint64_t *, size_t);
+
 static __inline void
 bus_space_write_region_1(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, const uint8_t *bufp, size_t count)
 {
-	uint8_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		ia64_st1(bsp, *bufp++);
-		ofs += 1;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_region_io_1(bsh + ofs, bufp, count);
+	else {
+		uint8_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			ia64_st1(bsp++, *bufp++);
 	}
 }
 
@@ -431,12 +528,13 @@ static __inline void
 bus_space_write_region_2(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, const uint16_t *bufp, size_t count)
 {
-	uint16_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		ia64_st2(bsp, *bufp++);
-		ofs += 2;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_region_io_2(bsh + ofs, bufp, count);
+	else {
+		uint16_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			ia64_st2(bsp++, *bufp++);
 	}
 }
 
@@ -444,12 +542,13 @@ static __inline void
 bus_space_write_region_4(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, const uint32_t *bufp, size_t count)
 {
-	uint32_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		ia64_st4(bsp, *bufp++);
-		ofs += 4;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_region_io_4(bsh + ofs, bufp, count);
+	else {
+		uint32_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			ia64_st4(bsp++, *bufp++);
 	}
 }
 
@@ -457,12 +556,13 @@ static __inline void
 bus_space_write_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, const uint64_t *bufp, size_t count)
 {
-	uint64_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		ia64_st8(bsp, *bufp++);
-		ofs += 8;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_write_region_io_8(bsh + ofs, bufp, count);
+	else {
+		uint64_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			ia64_st8(bsp++, *bufp++);
 	}
 }
 
@@ -476,44 +576,36 @@ static __inline void
 bus_space_set_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint8_t val, size_t count)
 {
-	uint8_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
+
 	while (count-- > 0)
-		ia64_st1(bsp, val);
+		bus_space_write_1(bst, bsh, ofs, val);
 }
 
 static __inline void
 bus_space_set_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint16_t val, size_t count)
 {
-	uint16_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
+
 	while (count-- > 0)
-		ia64_st2(bsp, val);
+		bus_space_write_2(bst, bsh, ofs, val);
 }
 
 static __inline void
 bus_space_set_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint32_t val, size_t count)
 {
-	uint32_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
+
 	while (count-- > 0)
-		ia64_st4(bsp, val);
+		bus_space_write_4(bst, bsh, ofs, val);
 }
 
 static __inline void
 bus_space_set_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint64_t val, size_t count)
 {
-	uint64_t *bsp;
-	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-	    __MEMIO_ADDR(bsh + ofs);
+
 	while (count-- > 0)
-		ia64_st8(bsp, val);
+		bus_space_write_8(bst, bsh, ofs, val);
 }
 
 
@@ -523,16 +615,22 @@ bus_space_set_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
  * data is passed by value and written to successive bus space addresses.
  * Writes are unordered.
  */
+void bus_space_set_region_io_1(u_long, uint8_t, size_t);
+void bus_space_set_region_io_2(u_long, uint16_t, size_t);
+void bus_space_set_region_io_4(u_long, uint32_t, size_t);
+void bus_space_set_region_io_8(u_long, uint64_t, size_t);
+
 static __inline void
 bus_space_set_region_1(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint8_t val, size_t count)
 {
-	uint8_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		ia64_st1(bsp, val);
-		ofs += 1;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_set_region_io_1(bsh + ofs, val, count);
+	else {
+		uint8_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			ia64_st1(bsp++, val);
 	}
 }
 
@@ -540,12 +638,13 @@ static __inline void
 bus_space_set_region_2(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint16_t val, size_t count)
 {
-	uint16_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		ia64_st2(bsp, val);
-		ofs += 2;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_set_region_io_2(bsh + ofs, val, count);
+	else {
+		uint16_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			ia64_st2(bsp++, val);
 	}
 }
 
@@ -553,12 +652,13 @@ static __inline void
 bus_space_set_region_4(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint32_t val, size_t count)
 {
-	uint32_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		ia64_st4(bsp, val);
-		ofs += 4;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_set_region_io_4(bsh + ofs, val, count);
+	else {
+		uint32_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			ia64_st4(bsp++, val);
 	}
 }
 
@@ -566,12 +666,13 @@ static __inline void
 bus_space_set_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
     bus_size_t ofs, uint64_t val, size_t count)
 {
-	uint64_t *bsp;
-	while (count-- > 0) {
-		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
-		    __MEMIO_ADDR(bsh + ofs);
-		ia64_st8(bsp, val);
-		ofs += 8;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO))
+		bus_space_set_region_io_4(bsh + ofs, val, count);
+	else {
+		uint64_t *bsp = (void *)(bsh + ofs);
+		while (count-- > 0)
+			ia64_st8(bsp++, val);
 	}
 }
 
@@ -583,159 +684,104 @@ bus_space_set_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
  * The data is read from successive bus space addresses and also written to
  * successive bus space addresses. Both reads and writes are unordered.
  */
+void bus_space_copy_region_io_1(u_long, u_long, size_t);
+void bus_space_copy_region_io_2(u_long, u_long, size_t);
+void bus_space_copy_region_io_4(u_long, u_long, size_t);
+void bus_space_copy_region_io_8(u_long, u_long, size_t);
+
 static __inline void
-bus_space_copy_region_1(bus_space_tag_t bst, bus_space_handle_t bsh1,
-    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count)
+bus_space_copy_region_1(bus_space_tag_t bst, bus_space_handle_t sbsh,
+    bus_size_t sofs, bus_space_handle_t dbsh, bus_size_t dofs, size_t count)
 {
-	bus_addr_t dst, src;
-	uint8_t *dstp, *srcp;
-	src = bsh1 + ofs1;
-	dst = bsh2 + ofs2;
-	if (dst > src) {
+	uint8_t *dst, *src;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO)) {
+		bus_space_copy_region_io_1(sbsh + sofs, dbsh + dofs, count);
+		return;
+	}
+
+	src = (void *)(sbsh + sofs);
+	dst = (void *)(dbsh + dofs);
+	if (src < dst) {
 		src += count - 1;
 		dst += count - 1;
-		while (count-- > 0) {
-			if (bst == IA64_BUS_SPACE_IO) {
-				srcp = __PIO_ADDR(src);
-				dstp = __PIO_ADDR(dst);
-			} else {
-				srcp = __MEMIO_ADDR(src);
-				dstp = __MEMIO_ADDR(dst);
-			}
-			ia64_st1(dstp, ia64_ld1(srcp));
-			src -= 1;
-			dst -= 1;
-		}
+		while (count-- > 0)
+			ia64_st1(dst--, ia64_ld1(src--));
 	} else {
-		while (count-- > 0) {
-			if (bst == IA64_BUS_SPACE_IO) {
-				srcp = __PIO_ADDR(src);
-				dstp = __PIO_ADDR(dst);
-			} else {
-				srcp = __MEMIO_ADDR(src);
-				dstp = __MEMIO_ADDR(dst);
-			}
-			ia64_st1(dstp, ia64_ld1(srcp));
-			src += 1;
-			dst += 1;
-		}
+		while (count-- > 0)
+			ia64_st1(dst++, ia64_ld1(src++));
 	}
 }
 
 static __inline void
-bus_space_copy_region_2(bus_space_tag_t bst, bus_space_handle_t bsh1,
-    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count)
+bus_space_copy_region_2(bus_space_tag_t bst, bus_space_handle_t sbsh,
+    bus_size_t sofs, bus_space_handle_t dbsh, bus_size_t dofs, size_t count)
 {
-	bus_addr_t dst, src;
-	uint16_t *dstp, *srcp;
-	src = bsh1 + ofs1;
-	dst = bsh2 + ofs2;
-	if (dst > src) {
-		src += (count - 1) << 1;
-		dst += (count - 1) << 1;
-		while (count-- > 0) {
-			if (bst == IA64_BUS_SPACE_IO) {
-				srcp = __PIO_ADDR(src);
-				dstp = __PIO_ADDR(dst);
-			} else {
-				srcp = __MEMIO_ADDR(src);
-				dstp = __MEMIO_ADDR(dst);
-			}
-			ia64_st2(dstp, ia64_ld2(srcp));
-			src -= 2;
-			dst -= 2;
-		}
+	uint16_t *dst, *src;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO)) {
+		bus_space_copy_region_io_2(sbsh + sofs, dbsh + dofs, count);
+		return;
+	}
+
+	src = (void *)(sbsh + sofs);
+	dst = (void *)(dbsh + dofs);
+	if (src < dst) {
+		src += count - 1;
+		dst += count - 1;
+		while (count-- > 0)
+			ia64_st2(dst--, ia64_ld2(src--));
 	} else {
-		while (count-- > 0) {
-			if (bst == IA64_BUS_SPACE_IO) {
-				srcp = __PIO_ADDR(src);
-				dstp = __PIO_ADDR(dst);
-			} else {
-				srcp = __MEMIO_ADDR(src);
-				dstp = __MEMIO_ADDR(dst);
-			}
-			ia64_st2(dstp, ia64_ld2(srcp));
-			src += 2;
-			dst += 2;
-		}
+		while (count-- > 0)
+			ia64_st2(dst++, ia64_ld2(src++));
 	}
 }
 
 static __inline void
-bus_space_copy_region_4(bus_space_tag_t bst, bus_space_handle_t bsh1,
-    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count)
+bus_space_copy_region_4(bus_space_tag_t bst, bus_space_handle_t sbsh,
+    bus_size_t sofs, bus_space_handle_t dbsh, bus_size_t dofs, size_t count)
 {
-	bus_addr_t dst, src;
-	uint32_t *dstp, *srcp;
-	src = bsh1 + ofs1;
-	dst = bsh2 + ofs2;
-	if (dst > src) {
-		src += (count - 1) << 2;
-		dst += (count - 1) << 2;
-		while (count-- > 0) {
-			if (bst == IA64_BUS_SPACE_IO) {
-				srcp = __PIO_ADDR(src);
-				dstp = __PIO_ADDR(dst);
-			} else {
-				srcp = __MEMIO_ADDR(src);
-				dstp = __MEMIO_ADDR(dst);
-			}
-			ia64_st4(dstp, ia64_ld4(srcp));
-			src -= 4;
-			dst -= 4;
-		}
+	uint32_t *dst, *src;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO)) {
+		bus_space_copy_region_io_4(sbsh + sofs, dbsh + dofs, count);
+		return;
+	}
+
+	src = (void *)(sbsh + sofs);
+	dst = (void *)(dbsh + dofs);
+	if (src < dst) {
+		src += count - 1;
+		dst += count - 1;
+		while (count-- > 0)
+			ia64_st4(dst--, ia64_ld4(src--));
 	} else {
-		while (count-- > 0) {
-			if (bst == IA64_BUS_SPACE_IO) {
-				srcp = __PIO_ADDR(src);
-				dstp = __PIO_ADDR(dst);
-			} else {
-				srcp = __MEMIO_ADDR(src);
-				dstp = __MEMIO_ADDR(dst);
-			}
-			ia64_st4(dstp, ia64_ld4(srcp));
-			src += 4;
-			dst += 4;
-		}
+		while (count-- > 0)
+			ia64_st4(dst++, ia64_ld4(src++));
 	}
 }
 
 static __inline void
-bus_space_copy_region_8(bus_space_tag_t bst, bus_space_handle_t bsh1,
-    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count)
+bus_space_copy_region_8(bus_space_tag_t bst, bus_space_handle_t sbsh,
+    bus_size_t sofs, bus_space_handle_t dbsh, bus_size_t dofs, size_t count)
 {
-	bus_addr_t dst, src;
-	uint64_t *dstp, *srcp;
-	src = bsh1 + ofs1;
-	dst = bsh2 + ofs2;
-	if (dst > src) {
-		src += (count - 1) << 3;
-		dst += (count - 1) << 3;
-		while (count-- > 0) {
-			if (bst == IA64_BUS_SPACE_IO) {
-				srcp = __PIO_ADDR(src);
-				dstp = __PIO_ADDR(dst);
-			} else {
-				srcp = __MEMIO_ADDR(src);
-				dstp = __MEMIO_ADDR(dst);
-			}
-			ia64_st8(dstp, ia64_ld8(srcp));
-			src -= 8;
-			dst -= 8;
-		}
+	uint64_t *dst, *src;
+
+	if (__predict_false(bst == IA64_BUS_SPACE_IO)) {
+		bus_space_copy_region_io_8(sbsh + sofs, dbsh + dofs, count);
+		return;
+	}
+
+	src = (void *)(sbsh + sofs);
+	dst = (void *)(dbsh + dofs);
+	if (src < dst) {
+		src += count - 1;
+		dst += count - 1;
+		while (count-- > 0)
+			ia64_st8(dst--, ia64_ld8(src--));
 	} else {
-		while (count-- > 0) {
-			if (bst == IA64_BUS_SPACE_IO) {
-				srcp = __PIO_ADDR(src);
-				dstp = __PIO_ADDR(dst);
-			} else {
-				srcp = __MEMIO_ADDR(src);
-				dstp = __MEMIO_ADDR(dst);
-			}
-			ia64_st8(dstp, ia64_ld8(srcp));
-			src += 8;
-			dst += 8;
-		}
+		while (count-- > 0)
+			ia64_st8(dst++, ia64_ld8(src++));
 	}
 }
 
@@ -744,86 +790,51 @@ bus_space_copy_region_8(bus_space_tag_t bst, bus_space_handle_t bsh1,
  * Stream accesses are the same as normal accesses on ia64; there are no
  * supported bus systems with an endianess different from the host one.
  */
-#define	bus_space_read_stream_1(t, h, o)	\
-	bus_space_read_1(t, h, o)
-#define	bus_space_read_stream_2(t, h, o)	\
-	bus_space_read_2(t, h, o)
-#define	bus_space_read_stream_4(t, h, o)	\
-	bus_space_read_4(t, h, o)
-#define	bus_space_read_stream_8(t, h, o)	\
-	bus_space_read_8(t, h, o)
 
-#define	bus_space_read_multi_stream_1(t, h, o, a, c)	\
-	bus_space_read_multi_1(t, h, o, a, c)
-#define	bus_space_read_multi_stream_2(t, h, o, a, c)	\
-	bus_space_read_multi_2(t, h, o, a, c)
-#define	bus_space_read_multi_stream_4(t, h, o, a, c)	\
-	bus_space_read_multi_4(t, h, o, a, c)
-#define	bus_space_read_multi_stream_8(t, h, o, a, c)	\
-	bus_space_read_multi_8(t, h, o, a, c)
+#define	bus_space_read_stream_1		bus_space_read_1
+#define	bus_space_read_stream_2		bus_space_read_2
+#define	bus_space_read_stream_4		bus_space_read_4
+#define	bus_space_read_stream_8		bus_space_read_8
 
-#define	bus_space_write_stream_1(t, h, o, v)	\
-	bus_space_write_1(t, h, o, v)
-#define	bus_space_write_stream_2(t, h, o, v)	\
-	bus_space_write_2(t, h, o, v)
-#define	bus_space_write_stream_4(t, h, o, v)	\
-	bus_space_write_4(t, h, o, v)
-#define	bus_space_write_stream_8(t, h, o, v)	\
-	bus_space_write_8(t, h, o, v)
+#define	bus_space_write_stream_1	bus_space_write_1
+#define	bus_space_write_stream_2	bus_space_write_2
+#define	bus_space_write_stream_4	bus_space_write_4
+#define	bus_space_write_stream_8	bus_space_write_8
 
-#define	bus_space_write_multi_stream_1(t, h, o, a, c)	\
-	bus_space_write_multi_1(t, h, o, a, c)
-#define	bus_space_write_multi_stream_2(t, h, o, a, c)	\
-	bus_space_write_multi_2(t, h, o, a, c)
-#define	bus_space_write_multi_stream_4(t, h, o, a, c)	\
-	bus_space_write_multi_4(t, h, o, a, c)
-#define	bus_space_write_multi_stream_8(t, h, o, a, c)	\
-	bus_space_write_multi_8(t, h, o, a, c)
+#define	bus_space_read_multi_stream_1	bus_space_read_multi_1
+#define	bus_space_read_multi_stream_2	bus_space_read_multi_2
+#define	bus_space_read_multi_stream_4	bus_space_read_multi_4
+#define	bus_space_read_multi_stream_8	bus_space_read_multi_8
 
-#define	bus_space_set_multi_stream_1(t, h, o, v, c)	\
-	bus_space_set_multi_1(t, h, o, v, c)
-#define	bus_space_set_multi_stream_2(t, h, o, v, c)	\
-	bus_space_set_multi_2(t, h, o, v, c)
-#define	bus_space_set_multi_stream_4(t, h, o, v, c)	\
-	bus_space_set_multi_4(t, h, o, v, c)
-#define	bus_space_set_multi_stream_8(t, h, o, v, c)	\
-	bus_space_set_multi_8(t, h, o, v, c)
+#define	bus_space_write_multi_stream_1	bus_space_write_multi_1
+#define	bus_space_write_multi_stream_2	bus_space_write_multi_2
+#define	bus_space_write_multi_stream_4	bus_space_write_multi_4
+#define	bus_space_write_multi_stream_8	bus_space_write_multi_8
 
-#define	bus_space_read_region_stream_1(t, h, o, a, c)	\
-	bus_space_read_region_1(t, h, o, a, c)
-#define	bus_space_read_region_stream_2(t, h, o, a, c)	\
-	bus_space_read_region_2(t, h, o, a, c)
-#define	bus_space_read_region_stream_4(t, h, o, a, c)	\
-	bus_space_read_region_4(t, h, o, a, c)
-#define	bus_space_read_region_stream_8(t, h, o, a, c)	\
-	bus_space_read_region_8(t, h, o, a, c)
+#define	bus_space_read_region_stream_1	bus_space_read_region_1
+#define	bus_space_read_region_stream_2	bus_space_read_region_2
+#define	bus_space_read_region_stream_4	bus_space_read_region_4
+#define	bus_space_read_region_stream_8	bus_space_read_region_8
 
-#define	bus_space_write_region_stream_1(t, h, o, a, c)	\
-	bus_space_write_region_1(t, h, o, a, c)
-#define	bus_space_write_region_stream_2(t, h, o, a, c)	\
-	bus_space_write_region_2(t, h, o, a, c)
-#define	bus_space_write_region_stream_4(t, h, o, a, c)	\
-	bus_space_write_region_4(t, h, o, a, c)
-#define	bus_space_write_region_stream_8(t, h, o, a, c)	\
-	bus_space_write_region_8(t, h, o, a, c)
+#define	bus_space_write_region_stream_1	bus_space_write_region_1
+#define	bus_space_write_region_stream_2	bus_space_write_region_2
+#define	bus_space_write_region_stream_4	bus_space_write_region_4
+#define	bus_space_write_region_stream_8	bus_space_write_region_8
 
-#define	bus_space_set_region_stream_1(t, h, o, v, c)	\
-	bus_space_set_region_1(t, h, o, v, c)
-#define	bus_space_set_region_stream_2(t, h, o, v, c)	\
-	bus_space_set_region_2(t, h, o, v, c)
-#define	bus_space_set_region_stream_4(t, h, o, v, c)	\
-	bus_space_set_region_4(t, h, o, v, c)
-#define	bus_space_set_region_stream_8(t, h, o, v, c)	\
-	bus_space_set_region_8(t, h, o, v, c)
+#define	bus_space_set_multi_stream_1	bus_space_set_multi_1
+#define	bus_space_set_multi_stream_2	bus_space_set_multi_2
+#define	bus_space_set_multi_stream_4	bus_space_set_multi_4
+#define	bus_space_set_multi_stream_8	bus_space_set_multi_8
 
-#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c)	\
-	bus_space_copy_region_1(t, h1, o1, h2, o2, c)
-#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c)	\
-	bus_space_copy_region_2(t, h1, o1, h2, o2, c)
-#define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c)	\
-	bus_space_copy_region_4(t, h1, o1, h2, o2, c)
-#define	bus_space_copy_region_stream_8(t, h1, o1, h2, o2, c)	\
-	bus_space_copy_region_8(t, h1, o1, h2, o2, c)
+#define	bus_space_set_region_stream_1	bus_space_set_region_1
+#define	bus_space_set_region_stream_2	bus_space_set_region_2
+#define	bus_space_set_region_stream_4	bus_space_set_region_4
+#define	bus_space_set_region_stream_8	bus_space_set_region_8
+
+#define	bus_space_copy_region_stream_1	bus_space_copy_region_1
+#define	bus_space_copy_region_stream_2	bus_space_copy_region_2
+#define	bus_space_copy_region_stream_4	bus_space_copy_region_4
+#define	bus_space_copy_region_stream_8	bus_space_copy_region_8
 
 #include 
 
diff --git a/sys/ia64/include/cpufunc.h b/sys/ia64/include/cpufunc.h
index fe469110a45..9ae06a2253d 100644
--- a/sys/ia64/include/cpufunc.h
+++ b/sys/ia64/include/cpufunc.h
@@ -54,126 +54,6 @@ breakpoint(void)
 #define	HAVE_INLINE_FFS
 #define	ffs(x)	__builtin_ffs(x)
 
-#define	__MEMIO_ADDR(x)		(void*)(IA64_PHYS_TO_RR6(x))
-extern void *ia64_ioport_address(u_int);
-#define	__PIO_ADDR(x)		ia64_ioport_address(x)
-
-/*
- * I/O port reads with ia32 semantics.
- */
-static __inline uint8_t
-inb(unsigned int port)
-{
-	uint8_t v;
-
-	ia64_mf();
-	v = ia64_ld1(__PIO_ADDR(port));
-	ia64_mf_a();
-	ia64_mf();
-	return (v);
-}
-
-static __inline uint16_t
-inw(unsigned int port)
-{
-	uint16_t v;
-
-	ia64_mf();
-	v = ia64_ld2(__PIO_ADDR(port));
-	ia64_mf_a();
-	ia64_mf();
-	return (v);
-}
-
-static __inline uint32_t
-inl(unsigned int port)
-{
-	uint32_t v;
-
-	ia64_mf();
-	v = ia64_ld4(__PIO_ADDR(port));
-	ia64_mf_a();
-	ia64_mf();
-	return (v);
-}
-
-static __inline void
-insb(unsigned int port, void *addr, size_t count)
-{
-	uint8_t *buf = addr;
-	while (count--)
-		*buf++ = inb(port);
-}
-
-static __inline void
-insw(unsigned int port, void *addr, size_t count)
-{
-	uint16_t *buf = addr;
-	while (count--)
-		*buf++ = inw(port);
-}
-
-static __inline void
-insl(unsigned int port, void *addr, size_t count)
-{
-	uint32_t *buf = addr;
-	while (count--)
-		*buf++ = inl(port);
-}
-
-static __inline void
-outb(unsigned int port, uint8_t data)
-{
-
-	ia64_mf();
-	ia64_st1(__PIO_ADDR(port), data);
-	ia64_mf_a();
-	ia64_mf();
-}
-
-static __inline void
-outw(unsigned int port, uint16_t data)
-{
-
-	ia64_mf();
-	ia64_st2(__PIO_ADDR(port), data);
-	ia64_mf_a();
-	ia64_mf();
-}
-
-static __inline void
-outl(unsigned int port, uint32_t data)
-{
-
-	ia64_mf();
-	ia64_st4(__PIO_ADDR(port), data);
-	ia64_mf_a();
-	ia64_mf();
-}
-
-static __inline void
-outsb(unsigned int port, const void *addr, size_t count)
-{
-	const uint8_t *buf = addr;
-	while (count--)
-		outb(port, *buf++);
-}
-
-static __inline void
-outsw(unsigned int port, const void *addr, size_t count)
-{
-	const uint16_t *buf = addr;
-	while (count--)
-		outw(port, *buf++);
-}
-
-static __inline void
-outsl(unsigned int port, const void *addr, size_t count)
-{
-	const uint32_t *buf = addr;
-	while (count--)
-		outl(port, *buf++);
-}
 
 static __inline void
 disable_intr(void)

From 0801667fe3b2618a18ddffad9c20865106b3c86e Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Mon, 11 Jan 2010 02:31:00 +0000
Subject: [PATCH 1080/2592] MFC r201143:

Apply OpenSolaris revision 8021:b8fe9660eb2d which brings our zpool
to version 14, making it possible for zpools created on OpenSolaris
2009.06 be used on FreeBSD.

PR:		kern/141800
Submitted by:	mm
Reviewed by:	pjd, trasz
Obtained from:	OpenSolaris onnv-gate
---
 .../opensolaris/cmd/zpool/zpool_main.c        |   2 +
 sys/cddl/boot/zfs/zfsimpl.h                   |   6 +-
 .../contrib/opensolaris/common/zfs/zfs_prop.c |   3 +-
 .../uts/common/fs/zfs/sys/zfs_acl.h           |   3 +-
 .../opensolaris/uts/common/fs/zfs/zfs_acl.c   | 190 ++++++++++--------
 .../opensolaris/uts/common/fs/zfs/zfs_ioctl.c |   8 +
 .../opensolaris/uts/common/sys/fs/zfs.h       |   6 +-
 7 files changed, 122 insertions(+), 96 deletions(-)

diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
index 2388df9ac99..297037178a9 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
@@ -3488,6 +3488,8 @@ zpool_do_upgrade(int argc, char **argv)
 		(void) printf(gettext(" 11  Improved scrub performance\n"));
 		(void) printf(gettext(" 12  Snapshot properties\n"));
 		(void) printf(gettext(" 13  snapused property\n"));
+		(void) printf(gettext(" 14  passthrough-x aclinherit "
+		    "support\n"));
 		(void) printf(gettext("For more information on a particular "
 		    "version, including supported releases, see:\n\n"));
 		(void) printf("http://www.opensolaris.org/os/community/zfs/"
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index 688bb5c6203..1149eac95d0 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -479,13 +479,14 @@ typedef enum {
 #define	SPA_VERSION_11			11ULL
 #define	SPA_VERSION_12			12ULL
 #define	SPA_VERSION_13			13ULL
+#define	SPA_VERSION_14			14ULL
 /*
  * When bumping up SPA_VERSION, make sure GRUB ZFS understand the on-disk
  * format change. Go to usr/src/grub/grub-0.95/stage2/{zfs-include/, fsys_zfs*},
  * and do the appropriate changes.
  */
-#define	SPA_VERSION			SPA_VERSION_13
-#define	SPA_VERSION_STRING		"13"
+#define	SPA_VERSION			SPA_VERSION_14
+#define	SPA_VERSION_STRING		"14"
 
 /*
  * Symbolic names for the changes that caused a SPA_VERSION switch.
@@ -520,6 +521,7 @@ typedef enum {
 #define	SPA_VERSION_DSL_SCRUB		SPA_VERSION_11
 #define	SPA_VERSION_SNAP_PROPS		SPA_VERSION_12
 #define	SPA_VERSION_USED_BREAKDOWN	SPA_VERSION_13
+#define	SPA_VERSION_PASSTHROUGH_X	SPA_VERSION_14
 
 /*
  * The following are configuration names used in the nvlist describing a pool's
diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
index fef05abf3ce..70c08adc78a 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
@@ -97,6 +97,7 @@ zfs_prop_init(void)
 		{ "restricted",	ZFS_ACL_RESTRICTED },
 		{ "passthrough", ZFS_ACL_PASSTHROUGH },
 		{ "secure",	ZFS_ACL_RESTRICTED }, /* bkwrd compatability */
+		{ "passthrough-x", ZFS_ACL_PASSTHROUGH_X },
 		{ NULL }
 	};
 
@@ -173,7 +174,7 @@ zfs_prop_init(void)
 	    "discard | groupmask | passthrough", "ACLMODE", acl_mode_table);
 	register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_RESTRICTED,
 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
-	    "discard | noallow | restricted | passthrough",
+	    "discard | noallow | restricted | passthrough | passthrough-x",
 	    "ACLINHERIT", acl_inherit_table);
 	register_index(ZFS_PROP_COPIES, "copies", 1,
 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h
index df148c62494..f87823c5d0f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h
@@ -26,8 +26,6 @@
 #ifndef	_SYS_FS_ZFS_ACL_H
 #define	_SYS_FS_ZFS_ACL_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef _KERNEL
 #include 
 #endif
@@ -180,6 +178,7 @@ typedef struct zfs_acl {
 #define	ZFS_ACL_GROUPMASK	2
 #define	ZFS_ACL_PASSTHROUGH	3
 #define	ZFS_ACL_RESTRICTED	4
+#define	ZFS_ACL_PASSTHROUGH_X	5
 
 struct znode;
 struct zfsvfs;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
index a43d85c709e..eb93721e167 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
@@ -1663,7 +1663,8 @@ zfs_ace_can_use(znode_t *zp, uint16_t acep_flags)
  * inherit inheritable ACEs from parent
  */
 static zfs_acl_t *
-zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, boolean_t *need_chmod)
+zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, uint64_t mode,
+    boolean_t *need_chmod)
 {
 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
 	void		*pacep;
@@ -1676,112 +1677,123 @@ zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, boolean_t *need_chmod)
 	size_t		ace_size;
 	void		*data1, *data2;
 	size_t		data1sz, data2sz;
-	enum vtype	vntype = ZTOV(zp)->v_type;
+	boolean_t	vdir = ZTOV(zp)->v_type == VDIR;
+	boolean_t	vreg = ZTOV(zp)->v_type == VREG;
+	boolean_t	passthrough, passthrough_x, noallow;
+
+	passthrough_x =
+	    zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X;
+	passthrough = passthrough_x ||
+	    zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH;
+	noallow =
+	    zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW;
 
 	*need_chmod = B_TRUE;
 	pacep = NULL;
 	aclp = zfs_acl_alloc(paclp->z_version);
-	if (zfsvfs->z_acl_inherit != ZFS_ACL_DISCARD) {
-		while (pacep = zfs_acl_next_ace(paclp, pacep, &who,
-		    &access_mask, &iflags, &type)) {
+	if (zfsvfs->z_acl_inherit == ZFS_ACL_DISCARD)
+		return (aclp);
+	while (pacep = zfs_acl_next_ace(paclp, pacep, &who,
+	    &access_mask, &iflags, &type)) {
 
-			/*
-			 * don't inherit bogus ACEs
-			 */
-			if (!zfs_acl_valid_ace_type(type, iflags))
-				continue;
+		/*
+		 * don't inherit bogus ACEs
+		 */
+		if (!zfs_acl_valid_ace_type(type, iflags))
+			continue;
 
-			if (zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW &&
-			    type == ALLOW)
-				continue;
+		if (noallow && type == ALLOW)
+			continue;
 
-			ace_size = aclp->z_ops.ace_size(pacep);
+		ace_size = aclp->z_ops.ace_size(pacep);
 
-			if (!zfs_ace_can_use(zp, iflags))
-				continue;
+		if (!zfs_ace_can_use(zp, iflags))
+			continue;
 
-			/*
-			 * If owner@, group@, or everyone@ inheritable
-			 * then zfs_acl_chmod() isn't needed.
-			 */
-			if (zfsvfs->z_acl_inherit ==
-			    ZFS_ACL_PASSTHROUGH &&
-			    ((iflags & (ACE_OWNER|ACE_EVERYONE)) ||
-			    ((iflags & OWNING_GROUP) ==
-			    OWNING_GROUP)) && (vntype == VREG ||
-			    (vntype == VDIR &&
-			    (iflags & ACE_DIRECTORY_INHERIT_ACE))))
-				*need_chmod = B_FALSE;
+		/*
+		 * If owner@, group@, or everyone@ inheritable
+		 * then zfs_acl_chmod() isn't needed.
+		 */
+		if (passthrough &&
+		    ((iflags & (ACE_OWNER|ACE_EVERYONE)) ||
+		    ((iflags & OWNING_GROUP) ==
+		    OWNING_GROUP)) && (vreg || (vdir && (iflags &
+		    ACE_DIRECTORY_INHERIT_ACE)))) {
+			*need_chmod = B_FALSE;
 
-			aclnode = zfs_acl_node_alloc(ace_size);
-			list_insert_tail(&aclp->z_acl, aclnode);
-			acep = aclnode->z_acldata;
-			zfs_set_ace(aclp, acep, access_mask, type,
-			    who, iflags|ACE_INHERITED_ACE);
+			if (!vdir && passthrough_x &&
+			    ((mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)) {
+				access_mask &= ~ACE_EXECUTE;
+			}
+		}
+
+		aclnode = zfs_acl_node_alloc(ace_size);
+		list_insert_tail(&aclp->z_acl, aclnode);
+		acep = aclnode->z_acldata;
+
+		zfs_set_ace(aclp, acep, access_mask, type,
+		    who, iflags|ACE_INHERITED_ACE);
+
+		/*
+		 * Copy special opaque data if any
+		 */
+		if ((data1sz = paclp->z_ops.ace_data(pacep, &data1)) != 0) {
+			VERIFY((data2sz = aclp->z_ops.ace_data(acep,
+			    &data2)) == data1sz);
+			bcopy(data1, data2, data2sz);
+		}
+		aclp->z_acl_count++;
+		aclnode->z_ace_count++;
+		aclp->z_acl_bytes += aclnode->z_size;
+		newflags = aclp->z_ops.ace_flags_get(acep);
+
+		if (vdir)
+			aclp->z_hints |= ZFS_INHERIT_ACE;
+
+		if ((iflags & ACE_NO_PROPAGATE_INHERIT_ACE) || !vdir) {
+			newflags &= ~ALL_INHERIT;
+			aclp->z_ops.ace_flags_set(acep,
+			    newflags|ACE_INHERITED_ACE);
+			zfs_restricted_update(zfsvfs, aclp, acep);
+			continue;
+		}
+
+		ASSERT(vdir);
+
+		newflags = aclp->z_ops.ace_flags_get(acep);
+		if ((iflags & (ACE_FILE_INHERIT_ACE |
+		    ACE_DIRECTORY_INHERIT_ACE)) !=
+		    ACE_FILE_INHERIT_ACE) {
+			aclnode2 = zfs_acl_node_alloc(ace_size);
+			list_insert_tail(&aclp->z_acl, aclnode2);
+			acep2 = aclnode2->z_acldata;
+			zfs_set_ace(aclp, acep2,
+			    access_mask, type, who,
+			    iflags|ACE_INHERITED_ACE);
+			newflags |= ACE_INHERIT_ONLY_ACE;
+			aclp->z_ops.ace_flags_set(acep, newflags);
+			newflags &= ~ALL_INHERIT;
+			aclp->z_ops.ace_flags_set(acep2,
+			    newflags|ACE_INHERITED_ACE);
 
 			/*
 			 * Copy special opaque data if any
 			 */
-			if ((data1sz = paclp->z_ops.ace_data(pacep,
+			if ((data1sz = aclp->z_ops.ace_data(acep,
 			    &data1)) != 0) {
-				VERIFY((data2sz = aclp->z_ops.ace_data(acep,
+				VERIFY((data2sz =
+				    aclp->z_ops.ace_data(acep2,
 				    &data2)) == data1sz);
-				bcopy(data1, data2, data2sz);
+				bcopy(data1, data2, data1sz);
 			}
 			aclp->z_acl_count++;
-			aclnode->z_ace_count++;
+			aclnode2->z_ace_count++;
 			aclp->z_acl_bytes += aclnode->z_size;
-			newflags = aclp->z_ops.ace_flags_get(acep);
-
-			if (vntype == VDIR)
-				aclp->z_hints |= ZFS_INHERIT_ACE;
-
-			if ((iflags & ACE_NO_PROPAGATE_INHERIT_ACE) ||
-			    (vntype != VDIR)) {
-				newflags &= ~ALL_INHERIT;
-				aclp->z_ops.ace_flags_set(acep,
-				    newflags|ACE_INHERITED_ACE);
-				zfs_restricted_update(zfsvfs, aclp, acep);
-				continue;
-			}
-
-			ASSERT(vntype == VDIR);
-
-			newflags = aclp->z_ops.ace_flags_get(acep);
-			if ((iflags & (ACE_FILE_INHERIT_ACE |
-			    ACE_DIRECTORY_INHERIT_ACE)) !=
-			    ACE_FILE_INHERIT_ACE) {
-				aclnode2 = zfs_acl_node_alloc(ace_size);
-				list_insert_tail(&aclp->z_acl, aclnode2);
-				acep2 = aclnode2->z_acldata;
-				zfs_set_ace(aclp, acep2,
-				    access_mask, type, who,
-				    iflags|ACE_INHERITED_ACE);
-				newflags |= ACE_INHERIT_ONLY_ACE;
-				aclp->z_ops.ace_flags_set(acep, newflags);
-				newflags &= ~ALL_INHERIT;
-				aclp->z_ops.ace_flags_set(acep2,
-				    newflags|ACE_INHERITED_ACE);
-
-				/*
-				 * Copy special opaque data if any
-				 */
-				if ((data1sz = aclp->z_ops.ace_data(acep,
-				    &data1)) != 0) {
-					VERIFY((data2sz =
-					    aclp->z_ops.ace_data(acep2,
-					    &data2)) == data1sz);
-					bcopy(data1, data2, data1sz);
-				}
-				aclp->z_acl_count++;
-				aclnode2->z_ace_count++;
-				aclp->z_acl_bytes += aclnode->z_size;
-				zfs_restricted_update(zfsvfs, aclp, acep2);
-			} else {
-				newflags |= ACE_INHERIT_ONLY_ACE;
-				aclp->z_ops.ace_flags_set(acep,
-				    newflags|ACE_INHERITED_ACE);
-			}
+			zfs_restricted_update(zfsvfs, aclp, acep2);
+		} else {
+			newflags |= ACE_INHERIT_ONLY_ACE;
+			aclp->z_ops.ace_flags_set(acep,
+			    newflags|ACE_INHERITED_ACE);
 		}
 	}
 	return (aclp);
@@ -1876,7 +1888,7 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
 			mutex_enter(&parent->z_acl_lock);
 			VERIFY(0 == zfs_acl_node_read(parent, &paclp, B_FALSE));
 			mutex_exit(&parent->z_acl_lock);
-			aclp = zfs_acl_inherit(zp, paclp, &need_chmod);
+			aclp = zfs_acl_inherit(zp, paclp, mode, &need_chmod);
 			zfs_acl_free(paclp);
 		} else {
 			aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index 080643a94c1..00e446b82e9 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -1491,6 +1491,14 @@ zfs_set_prop_nvlist(const char *name, nvlist_t *nvl)
 			if (zpl_earlier_version(name, ZPL_VERSION_FUID))
 				return (ENOTSUP);
 			break;
+
+		case ZFS_PROP_ACLINHERIT:
+			if (nvpair_type(elem) == DATA_TYPE_UINT64 &&
+			    nvpair_value_uint64(elem, &intval) == 0)
+				if (intval == ZFS_ACL_PASSTHROUGH_X &&
+				    zfs_earlier_version(name,
+				    SPA_VERSION_PASSTHROUGH_X))
+					return (ENOTSUP);
 		}
 	}
 
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
index 70da8aec978..2f7e7474c3f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
@@ -253,13 +253,14 @@ typedef enum zfs_cache_type {
 #define	SPA_VERSION_11			11ULL
 #define	SPA_VERSION_12			12ULL
 #define	SPA_VERSION_13			13ULL
+#define	SPA_VERSION_14			14ULL
 /*
  * When bumping up SPA_VERSION, make sure GRUB ZFS understands the on-disk
  * format change. Go to usr/src/grub/grub-0.95/stage2/{zfs-include/, fsys_zfs*},
  * and do the appropriate changes.
  */
-#define	SPA_VERSION			SPA_VERSION_13
-#define	SPA_VERSION_STRING		"13"
+#define	SPA_VERSION			SPA_VERSION_14
+#define	SPA_VERSION_STRING		"14"
 
 /*
  * Symbolic names for the changes that caused a SPA_VERSION switch.
@@ -294,6 +295,7 @@ typedef enum zfs_cache_type {
 #define	SPA_VERSION_DSL_SCRUB		SPA_VERSION_11
 #define	SPA_VERSION_SNAP_PROPS		SPA_VERSION_12
 #define	SPA_VERSION_USED_BREAKDOWN	SPA_VERSION_13
+#define	SPA_VERSION_PASSTHROUGH_X	SPA_VERSION_14
 
 /*
  * ZPL version - rev'd whenever an incompatible on-disk format change

From 811a80b4a43f9ff532186ab888718615a106af10 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Mon, 11 Jan 2010 05:19:51 +0000
Subject: [PATCH 1081/2592] MFC: r201538, r201539

Catch up with the VFS_VPTOFH(9) -> VOP_VPTOFH(9) repocopy that happened
almost three years ago in r166794.

Add a missing word.
---
 share/man/man7/security.7     | 2 +-
 share/man/man9/VFS.9          | 4 ++--
 share/man/man9/VFS_CHECKEXP.9 | 4 ++--
 share/man/man9/VFS_FHTOVP.9   | 4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/share/man/man7/security.7 b/share/man/man7/security.7
index 9a4a4afcd57..101dcd76b53 100644
--- a/share/man/man7/security.7
+++ b/share/man/man7/security.7
@@ -88,7 +88,7 @@ incur on the system under adverse conditions.
 Brute-force network attacks are harder to deal with.
 A spoofed-packet attack, for example, is
 nearly impossible to stop short of cutting your system off from the Internet.
-It may not be able to take your machine down, but it can fill up Internet
+It may not be able to take your machine down, but it can fill up your Internet
 pipe.
 .Pp
 A user account compromise is even more common than a DoS attack.
diff --git a/share/man/man9/VFS.9 b/share/man/man9/VFS.9
index 21e609e8269..54bdd0ce135 100644
--- a/share/man/man9/VFS.9
+++ b/share/man/man9/VFS.9
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 24, 1996
+.Dd January 4, 2010
 .Os
 .Dt VFS 9
 .Sh NAME
@@ -53,7 +53,7 @@ rather than implementing empty functions or casting to
 .Xr VFS_SYNC 9 ,
 .Xr VFS_UNMOUNT 9 ,
 .Xr VFS_VGET 9 ,
-.Xr VFS_VPTOFH 9 ,
+.Xr VOP_VPTOFH 9 ,
 .Xr vnode 9
 .Sh AUTHORS
 This manual page was written by
diff --git a/share/man/man9/VFS_CHECKEXP.9 b/share/man/man9/VFS_CHECKEXP.9
index a3afd2e0e45..92afda86d69 100644
--- a/share/man/man9/VFS_CHECKEXP.9
+++ b/share/man/man9/VFS_CHECKEXP.9
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 7, 2005
+.Dd January 4, 2010
 .Os
 .Dt VFS_CHECKEXP 9
 .Sh NAME
@@ -81,7 +81,7 @@ and
 .Sh SEE ALSO
 .Xr VFS 9 ,
 .Xr VFS_FHTOVP 9 ,
-.Xr VFS_VPTOFH 9 ,
+.Xr VOP_VPTOFH 9 ,
 .Xr vnode 9
 .Sh AUTHORS
 This manual page was written by
diff --git a/share/man/man9/VFS_FHTOVP.9 b/share/man/man9/VFS_FHTOVP.9
index e17133e5ce2..f6f88d204ee 100644
--- a/share/man/man9/VFS_FHTOVP.9
+++ b/share/man/man9/VFS_FHTOVP.9
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 7, 2005
+.Dd January 4, 2010
 .Os
 .Dt VFS_FHTOVP 9
 .Sh NAME
@@ -76,7 +76,7 @@ The locked vnode for the file will be returned in
 .Sh SEE ALSO
 .Xr VFS 9 ,
 .Xr VFS_CHECKEXP 9 ,
-.Xr VFS_VPTOFH 9 ,
+.Xr VOP_VPTOFH 9 ,
 .Xr vnode 9
 .Sh AUTHORS
 This manual page was written by

From 60ee8f1ae1f51a7ba67592e98b2a2415a442be10 Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Mon, 11 Jan 2010 12:32:06 +0000
Subject: [PATCH 1082/2592] MFC: r200026,201801: Swap carp(4) log levels.

---
 share/man/man4/carp.4 | 10 +++++-----
 sys/netinet/ip_carp.c | 36 ++++++++++++++++++------------------
 2 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/share/man/man4/carp.4 b/share/man/man4/carp.4
index 8333b4a0884..a985fb8a9d8 100644
--- a/share/man/man4/carp.4
+++ b/share/man/man4/carp.4
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 6, 2006
+.Dd January 5, 2010
 .Dt CARP 4
 .Os
 .Sh NAME
@@ -118,12 +118,12 @@ See also the first example.
 Disabled by default.
 .It Va net.inet.carp.log
 Value of 0 disables any logging.
-Value of 1 enables logging of bad
-.Nm
-packets.
-Values above 1 enable logging state changes of
+Value of 1 enables logging state changes of
 .Nm
 interfaces.
+Values above 1 enable logging of bad
+.Nm
+packets.
 Default value is 1.
 .It Va net.inet.carp.arpbalance
 Balance local traffic using ARP (see below).
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index e3ffe5a4a6d..433c0f03dd5 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -550,7 +550,7 @@ carp_input(struct mbuf *m, int hlen)
 	/* check if received on a valid carp interface */
 	if (m->m_pkthdr.rcvif->if_carp == NULL) {
 		CARPSTATS_INC(carps_badif);
-		CARP_LOG("carp_input: packet received on non-carp "
+		CARP_DEBUG("carp_input: packet received on non-carp "
 		    "interface: %s\n",
 		    m->m_pkthdr.rcvif->if_xname);
 		m_freem(m);
@@ -560,7 +560,7 @@ carp_input(struct mbuf *m, int hlen)
 	/* verify that the IP TTL is 255.  */
 	if (ip->ip_ttl != CARP_DFLTTL) {
 		CARPSTATS_INC(carps_badttl);
-		CARP_LOG("carp_input: received ttl %d != 255i on %s\n",
+		CARP_DEBUG("carp_input: received ttl %d != 255 on %s\n",
 		    ip->ip_ttl,
 		    m->m_pkthdr.rcvif->if_xname);
 		m_freem(m);
@@ -571,7 +571,7 @@ carp_input(struct mbuf *m, int hlen)
 
 	if (m->m_pkthdr.len < iplen + sizeof(*ch)) {
 		CARPSTATS_INC(carps_badlen);
-		CARP_LOG("carp_input: received len %zd < "
+		CARP_DEBUG("carp_input: received len %zd < "
 		    "sizeof(struct carp_header) on %s\n",
 		    m->m_len - sizeof(struct ip),
 		    m->m_pkthdr.rcvif->if_xname);
@@ -582,7 +582,7 @@ carp_input(struct mbuf *m, int hlen)
 	if (iplen + sizeof(*ch) < m->m_len) {
 		if ((m = m_pullup(m, iplen + sizeof(*ch))) == NULL) {
 			CARPSTATS_INC(carps_hdrops);
-			CARP_LOG("carp_input: pullup failed\n");
+			CARP_DEBUG("carp_input: pullup failed\n");
 			return;
 		}
 		ip = mtod(m, struct ip *);
@@ -596,7 +596,7 @@ carp_input(struct mbuf *m, int hlen)
 	len = iplen + sizeof(*ch);
 	if (len > m->m_pkthdr.len) {
 		CARPSTATS_INC(carps_badlen);
-		CARP_LOG("carp_input: packet too short %d on %s\n",
+		CARP_DEBUG("carp_input: packet too short %d on %s\n",
 		    m->m_pkthdr.len,
 		    m->m_pkthdr.rcvif->if_xname);
 		m_freem(m);
@@ -614,7 +614,7 @@ carp_input(struct mbuf *m, int hlen)
 	m->m_data += iplen;
 	if (carp_cksum(m, len - iplen)) {
 		CARPSTATS_INC(carps_badsum);
-		CARP_LOG("carp_input: checksum failed on %s\n",
+		CARP_DEBUG("carp_input: checksum failed on %s\n",
 		    m->m_pkthdr.rcvif->if_xname);
 		m_freem(m);
 		return;
@@ -643,7 +643,7 @@ carp6_input(struct mbuf **mp, int *offp, int proto)
 	/* check if received on a valid carp interface */
 	if (m->m_pkthdr.rcvif->if_carp == NULL) {
 		CARPSTATS_INC(carps_badif);
-		CARP_LOG("carp6_input: packet received on non-carp "
+		CARP_DEBUG("carp6_input: packet received on non-carp "
 		    "interface: %s\n",
 		    m->m_pkthdr.rcvif->if_xname);
 		m_freem(m);
@@ -653,7 +653,7 @@ carp6_input(struct mbuf **mp, int *offp, int proto)
 	/* verify that the IP TTL is 255 */
 	if (ip6->ip6_hlim != CARP_DFLTTL) {
 		CARPSTATS_INC(carps_badttl);
-		CARP_LOG("carp6_input: received ttl %d != 255 on %s\n",
+		CARP_DEBUG("carp6_input: received ttl %d != 255 on %s\n",
 		    ip6->ip6_hlim,
 		    m->m_pkthdr.rcvif->if_xname);
 		m_freem(m);
@@ -665,7 +665,7 @@ carp6_input(struct mbuf **mp, int *offp, int proto)
 	IP6_EXTHDR_GET(ch, struct carp_header *, m, *offp, sizeof(*ch));
 	if (ch == NULL) {
 		CARPSTATS_INC(carps_badlen);
-		CARP_LOG("carp6_input: packet size %u too small\n", len);
+		CARP_DEBUG("carp6_input: packet size %u too small\n", len);
 		return (IPPROTO_DONE);
 	}
 
@@ -674,7 +674,7 @@ carp6_input(struct mbuf **mp, int *offp, int proto)
 	m->m_data += *offp;
 	if (carp_cksum(m, sizeof(*ch))) {
 		CARPSTATS_INC(carps_badsum);
-		CARP_LOG("carp6_input: checksum failed, on %s\n",
+		CARP_DEBUG("carp6_input: checksum failed, on %s\n",
 		    m->m_pkthdr.rcvif->if_xname);
 		m_freem(m);
 		return (IPPROTO_DONE);
@@ -727,7 +727,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
 		CARPSTATS_INC(carps_badver);
 		SC2IFP(sc)->if_ierrors++;
 		CARP_UNLOCK(ifp->if_carp);
-		CARP_LOG("%s; invalid version %d\n",
+		CARP_DEBUG("%s; invalid version %d\n",
 		    SC2IFP(sc)->if_xname,
 		    ch->carp_version);
 		m_freem(m);
@@ -739,7 +739,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
 		CARPSTATS_INC(carps_badauth);
 		SC2IFP(sc)->if_ierrors++;
 		CARP_UNLOCK(ifp->if_carp);
-		CARP_LOG("%s: incorrect hash\n", SC2IFP(sc)->if_xname);
+		CARP_DEBUG("%s: incorrect hash\n", SC2IFP(sc)->if_xname);
 		m_freem(m);
 		return;
 	}
@@ -772,7 +772,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
 		if (timevalcmp(&sc_tv, &ch_tv, >) ||
 		    timevalcmp(&sc_tv, &ch_tv, ==)) {
 			callout_stop(&sc->sc_ad_tmo);
-			CARP_DEBUG("%s: MASTER -> BACKUP "
+			CARP_LOG("%s: MASTER -> BACKUP "
 			   "(more frequent advertisement received)\n",
 			   SC2IFP(sc)->if_xname);
 			carp_set_state(sc, BACKUP);
@@ -787,7 +787,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
 		 */
 		if (carp_opts[CARPCTL_PREEMPT] &&
 		    timevalcmp(&sc_tv, &ch_tv, <)) {
-			CARP_DEBUG("%s: BACKUP -> MASTER "
+			CARP_LOG("%s: BACKUP -> MASTER "
 			    "(preempting a slower master)\n",
 			    SC2IFP(sc)->if_xname);
 			carp_master_down_locked(sc);
@@ -801,7 +801,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
 		 */
 		sc_tv.tv_sec = sc->sc_advbase * 3;
 		if (timevalcmp(&sc_tv, &ch_tv, <)) {
-			CARP_DEBUG("%s: BACKUP -> MASTER "
+			CARP_LOG("%s: BACKUP -> MASTER "
 			    "(master timed out)\n",
 			    SC2IFP(sc)->if_xname);
 			carp_master_down_locked(sc);
@@ -1024,7 +1024,7 @@ carp_send_ad_locked(struct carp_softc *sc)
 		if (in6_setscope(&ip6->ip6_dst, sc->sc_carpdev, NULL) != 0) {
 			SC2IFP(sc)->if_oerrors++;
 			m_freem(m);
-			CARP_LOG("%s: in6_setscope failed\n", __func__);
+			CARP_DEBUG("%s: in6_setscope failed\n", __func__);
 			return;
 		}
 
@@ -1385,12 +1385,12 @@ carp_setrun(struct carp_softc *sc, sa_family_t af)
 #ifdef INET6
 			carp_send_na(sc);
 #endif /* INET6 */
-			CARP_DEBUG("%s: INIT -> MASTER (preempting)\n",
+			CARP_LOG("%s: INIT -> MASTER (preempting)\n",
 			    SC2IFP(sc)->if_xname);
 			carp_set_state(sc, MASTER);
 			carp_setroute(sc, RTM_ADD);
 		} else {
-			CARP_DEBUG("%s: INIT -> BACKUP\n", SC2IFP(sc)->if_xname);
+			CARP_LOG("%s: INIT -> BACKUP\n", SC2IFP(sc)->if_xname);
 			carp_set_state(sc, BACKUP);
 			carp_setroute(sc, RTM_DELETE);
 			carp_setrun(sc, 0);

From 2d63cbda240d3b39a735444f2f9c58b3e07479ab Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Mon, 11 Jan 2010 12:35:16 +0000
Subject: [PATCH 1083/2592] MFC r200770: Remove VI_OBJDIRTY and make sure that
 OBJ_MIGHTBEDIRTY is set only for vnode-backed vm objects.

---
 sys/kern/vfs_subr.c       |  7 +++----
 sys/sys/vnode.h           |  1 -
 sys/ufs/ffs/ffs_rawread.c | 15 ++++++++-------
 sys/vm/vm_object.c        | 26 +++++---------------------
 sys/vm/vm_object.h        |  2 +-
 5 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index a43b955f1bc..d681fca6f23 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -2697,14 +2697,12 @@ vn_printf(struct vnode *vp, const char *fmt, ...)
 		strlcat(buf, "|VI_DOOMED", sizeof(buf));
 	if (vp->v_iflag & VI_FREE)
 		strlcat(buf, "|VI_FREE", sizeof(buf));
-	if (vp->v_iflag & VI_OBJDIRTY)
-		strlcat(buf, "|VI_OBJDIRTY", sizeof(buf));
 	if (vp->v_iflag & VI_DOINGINACT)
 		strlcat(buf, "|VI_DOINGINACT", sizeof(buf));
 	if (vp->v_iflag & VI_OWEINACT)
 		strlcat(buf, "|VI_OWEINACT", sizeof(buf));
 	flags = vp->v_iflag & ~(VI_MOUNT | VI_AGE | VI_DOOMED | VI_FREE |
-	    VI_OBJDIRTY | VI_DOINGINACT | VI_OWEINACT);
+	    VI_DOINGINACT | VI_OWEINACT);
 	if (flags != 0) {
 		snprintf(buf2, sizeof(buf2), "|VI(0x%lx)", flags);
 		strlcat(buf, buf2, sizeof(buf));
@@ -3198,7 +3196,8 @@ vfs_msync(struct mount *mp, int flags)
 	MNT_ILOCK(mp);
 	MNT_VNODE_FOREACH(vp, mp, mvp) {
 		VI_LOCK(vp);
-		if ((vp->v_iflag & VI_OBJDIRTY) &&
+		obj = vp->v_object;
+		if (obj != NULL && (obj->flags & OBJ_MIGHTBEDIRTY) != 0 &&
 		    (flags == MNT_WAIT || VOP_ISLOCKED(vp) == 0)) {
 			MNT_IUNLOCK(mp);
 			if (!vget(vp,
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 2f2d90a80d4..2c043411706 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -237,7 +237,6 @@ struct xvnode {
 #define	VI_AGE		0x0040	/* Insert vnode at head of free list */
 #define	VI_DOOMED	0x0080	/* This vnode is being recycled */
 #define	VI_FREE		0x0100	/* This vnode is on the freelist */
-#define	VI_OBJDIRTY	0x0400	/* object might be dirty */
 #define	VI_DOINGINACT	0x0800	/* VOP_INACTIVE is in progress */
 #define	VI_OWEINACT	0x1000	/* Need to call inactive */
 
diff --git a/sys/ufs/ffs/ffs_rawread.c b/sys/ufs/ffs/ffs_rawread.c
index 434c833f7c3..574d89c57d3 100644
--- a/sys/ufs/ffs/ffs_rawread.c
+++ b/sys/ufs/ffs/ffs_rawread.c
@@ -101,6 +101,7 @@ ffs_rawread_sync(struct vnode *vp)
 	int upgraded;
 	struct bufobj *bo;
 	struct mount *mp;
+	vm_object_t obj;
 
 	/* Check for dirty mmap, pending writes and dirty buffers */
 	bo = &vp->v_bufobj;
@@ -108,7 +109,8 @@ ffs_rawread_sync(struct vnode *vp)
 	VI_LOCK(vp);
 	if (bo->bo_numoutput > 0 ||
 	    bo->bo_dirty.bv_cnt > 0 ||
-	    (vp->v_iflag & VI_OBJDIRTY) != 0) {
+	    ((obj = vp->v_object) != NULL &&
+	     (obj->flags & OBJ_MIGHTBEDIRTY) != 0)) {
 		VI_UNLOCK(vp);
 		BO_UNLOCK(bo);
 		
@@ -138,13 +140,12 @@ ffs_rawread_sync(struct vnode *vp)
 			return (EIO);
 		}
 		/* Attempt to msync mmap() regions to clean dirty mmap */ 
-		if ((vp->v_iflag & VI_OBJDIRTY) != 0) {
+		if ((obj = vp->v_object) != NULL &&
+		    (obj->flags & OBJ_MIGHTBEDIRTY) != 0) {
 			VI_UNLOCK(vp);
-			if (vp->v_object != NULL) {
-				VM_OBJECT_LOCK(vp->v_object);
-				vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC);
-				VM_OBJECT_UNLOCK(vp->v_object);
-			}
+			VM_OBJECT_LOCK(obj);
+			vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
+			VM_OBJECT_UNLOCK(obj);
 		} else
 			VI_UNLOCK(vp);
 
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index d7a6e97ac46..399cb10a1f9 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -773,9 +773,9 @@ vm_object_page_clean(vm_object_t object, vm_pindex_t start, vm_pindex_t end, int
 	int curgeneration;
 
 	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
-	if (object->type != OBJT_VNODE ||
-		(object->flags & OBJ_MIGHTBEDIRTY) == 0)
+	if ((object->flags & OBJ_MIGHTBEDIRTY) == 0)
 		return;
+	KASSERT(object->type == OBJT_VNODE, ("Not a vnode object"));
 
 	pagerflags = (flags & (OBJPC_SYNC | OBJPC_INVAL)) ? VM_PAGER_PUT_SYNC : VM_PAGER_CLUSTER_OK;
 	pagerflags |= (flags & OBJPC_INVAL) ? VM_PAGER_PUT_INVAL : 0;
@@ -875,18 +875,8 @@ vm_object_page_clean(vm_object_t object, vm_pindex_t start, vm_pindex_t end, int
 			pmap_remove_write(p);
 	}
 
-	if (clearobjflags && (tstart == 0) && (tend == object->size)) {
-		struct vnode *vp;
-
+	if (clearobjflags && (tstart == 0) && (tend == object->size))
 		vm_object_clear_flag(object, OBJ_MIGHTBEDIRTY);
-		if (object->type == OBJT_VNODE &&
-		    (vp = (struct vnode *)object->handle) != NULL) {
-			VI_LOCK(vp);
-			if (vp->v_iflag & VI_OBJDIRTY)
-				vp->v_iflag &= ~VI_OBJDIRTY;
-			VI_UNLOCK(vp);
-		}
-	}
 
 rescan:
 	curgeneration = object->generation;
@@ -2148,18 +2138,12 @@ vm_object_coalesce(vm_object_t prev_object, vm_ooffset_t prev_offset,
 void
 vm_object_set_writeable_dirty(vm_object_t object)
 {
-	struct vnode *vp;
 
 	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
-	if ((object->flags & OBJ_MIGHTBEDIRTY) != 0)
+	if (object->type != OBJT_VNODE ||
+	    (object->flags & OBJ_MIGHTBEDIRTY) != 0)
 		return;
 	vm_object_set_flag(object, OBJ_MIGHTBEDIRTY);
-	if (object->type == OBJT_VNODE &&
-	    (vp = (struct vnode *)object->handle) != NULL) {
-		VI_LOCK(vp);
-		vp->v_iflag |= VI_OBJDIRTY;
-		VI_UNLOCK(vp);
-	}
 }
 
 #include "opt_ddb.h"
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index 0b06fed2828..6a9f129cf83 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -154,7 +154,7 @@ struct vm_object {
 #define OBJ_DEAD	0x0008		/* dead objects (during rundown) */
 #define	OBJ_NOSPLIT	0x0010		/* dont split this object */
 #define OBJ_PIPWNT	0x0040		/* paging in progress wanted */
-#define OBJ_MIGHTBEDIRTY 0x0100		/* object might be dirty */
+#define OBJ_MIGHTBEDIRTY 0x0100		/* object might be dirty, only for vnode */
 #define OBJ_CLEANING	0x0200
 #define	OBJ_COLORED	0x1000		/* pg_color is defined */
 #define	OBJ_ONEMAPPING	0x2000		/* One USE (a single, non-forked) mapping flag */

From 5e3b84c3d2ce5421f64c08e4bf79587c2d9effe2 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Mon, 11 Jan 2010 18:42:29 +0000
Subject: [PATCH 1084/2592] MFC 201522: Expose the upper 256 ptys in the
 default devfs rules.  I should have updated this when expanding the old
 pty(4) driver to use 512 ptys by default.  This is more important for 7.x.

---
 etc/defaults/devfs.rules | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/etc/defaults/devfs.rules b/etc/defaults/devfs.rules
index a00b75d9247..a3e30b776b1 100644
--- a/etc/defaults/devfs.rules
+++ b/etc/defaults/devfs.rules
@@ -44,6 +44,14 @@ add path 'ptyP*' unhide
 add path 'ptyQ*' unhide
 add path 'ptyR*' unhide
 add path 'ptyS*' unhide
+add path 'ptyl*' unhide
+add path 'ptym*' unhide
+add path 'ptyn*' unhide
+add path 'ptyo*' unhide
+add path 'ptyL*' unhide
+add path 'ptyM*' unhide
+add path 'ptyN*' unhide
+add path 'ptyO*' unhide
 add path 'ttyp*' unhide
 add path 'ttyq*' unhide
 add path 'ttyr*' unhide
@@ -52,6 +60,14 @@ add path 'ttyP*' unhide
 add path 'ttyQ*' unhide
 add path 'ttyR*' unhide
 add path 'ttyS*' unhide
+add path 'ttyl*' unhide
+add path 'ttym*' unhide
+add path 'ttyn*' unhide
+add path 'ttyo*' unhide
+add path 'ttyL*' unhide
+add path 'ttyM*' unhide
+add path 'ttyN*' unhide
+add path 'ttyO*' unhide
 add path ptmx unhide
 add path pts unhide
 add path 'pts/*' unhide

From 6049e7fcf744816a91255361f1263ba0c953a75e Mon Sep 17 00:00:00 2001
From: Rick Macklem 
Date: Mon, 11 Jan 2010 19:30:23 +0000
Subject: [PATCH 1085/2592] MFC: r201029 When porting the experimental nfs
 subsystem to the FreeBSD8 krpc, I added 3 functions that were already in the
 experimental client under different names. This patch deletes the functions
 in the experimental client and renames the calls to use the other set. (This
 is just removal of duplicated code and does not fix any bug.)

---
 sys/fs/nfsclient/nfs.h         |   1 -
 sys/fs/nfsclient/nfs_clbio.c   | 105 ++-------------------------------
 sys/fs/nfsclient/nfs_clvnops.c |   6 +-
 3 files changed, 8 insertions(+), 104 deletions(-)

diff --git a/sys/fs/nfsclient/nfs.h b/sys/fs/nfsclient/nfs.h
index 8029a00c2db..a72ec6da75d 100644
--- a/sys/fs/nfsclient/nfs.h
+++ b/sys/fs/nfsclient/nfs.h
@@ -67,7 +67,6 @@ int ncl_vinvalbuf(struct vnode *, int, struct thread *, int);
 int ncl_asyncio(struct nfsmount *, struct buf *, struct ucred *,
     struct thread *);
 int ncl_doio(struct vnode *, struct buf *, struct ucred *, struct thread *);
-int ncl_msleep(struct thread *, void *, struct mtx *, int, char *, int);
 void ncl_nhinit(void);
 void ncl_nhuninit(void);
 void ncl_nodelock(struct nfsnode *);
diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c
index 030e322cd99..3193822f47e 100644
--- a/sys/fs/nfsclient/nfs_clbio.c
+++ b/sys/fs/nfsclient/nfs_clbio.c
@@ -74,101 +74,6 @@ static struct buf *nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size,
 static int nfs_directio_write(struct vnode *vp, struct uio *uiop, 
     struct ucred *cred, int ioflag);
 
-/*
- * Any signal that can interrupt an NFS operation in an intr mount
- * should be added to this set. SIGSTOP and SIGKILL cannot be masked.
- */
-static int nfs_sig_set[] = {
-	SIGINT,
-	SIGTERM,
-	SIGHUP,
-	SIGKILL,
-	SIGSTOP,
-	SIGQUIT
-};
-
-#ifdef notnow
-/*
- * Check to see if one of the signals in our subset is pending on
- * the process (in an intr mount).
- */
-int
-ncl_sig_pending(sigset_t set)
-{
-	int i;
-	
-	for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++)
-		if (SIGISMEMBER(set, nfs_sig_set[i]))
-			return (1);
-	return (0);
-}
-#endif
- 
-/*
- * The set/restore sigmask functions are used to (temporarily) overwrite
- * the process p_sigmask during an RPC call (for example). These are also
- * used in other places in the NFS client that might tsleep().
- */
-static void
-ncl_set_sigmask(struct thread *td, sigset_t *oldset)
-{
-	sigset_t newset;
-	int i;
-	struct proc *p;
-	
-	SIGFILLSET(newset);
-	if (td == NULL)
-		td = curthread; /* XXX */
-	p = td->td_proc;
-	/* Remove the NFS set of signals from newset */
-	PROC_LOCK(p);
-	mtx_lock(&p->p_sigacts->ps_mtx);
-	for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) {
-		/*
-		 * But make sure we leave the ones already masked
-		 * by the process, ie. remove the signal from the
-		 * temporary signalmask only if it wasn't already
-		 * in p_sigmask.
-		 */
-		if (!SIGISMEMBER(td->td_sigmask, nfs_sig_set[i]) &&
-		    !SIGISMEMBER(p->p_sigacts->ps_sigignore, nfs_sig_set[i]))
-			SIGDELSET(newset, nfs_sig_set[i]);
-	}
-	mtx_unlock(&p->p_sigacts->ps_mtx);
-	PROC_UNLOCK(p);
-	kern_sigprocmask(td, SIG_SETMASK, &newset, oldset, 0);
-}
-
-static void
-ncl_restore_sigmask(struct thread *td, sigset_t *set)
-{
-	if (td == NULL)
-		td = curthread; /* XXX */
-	kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0);
-}
-
-/*
- * NFS wrapper to msleep(), that shoves a new p_sigmask and restores the
- * old one after msleep() returns.
- */
-int
-ncl_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority, char *wmesg, int timo)
-{
-	sigset_t oldset;
-	int error;
-	struct proc *p;
-	
-	if ((priority & PCATCH) == 0)
-		return msleep(ident, mtx, priority, wmesg, timo);
-	if (td == NULL)
-		td = curthread; /* XXX */
-	ncl_set_sigmask(td, &oldset);
-	error = msleep(ident, mtx, priority, wmesg, timo);
-	ncl_restore_sigmask(td, &oldset);
-	p = td->td_proc;
-	return (error);
-}
-
 /*
  * Vnode op for VM getpages.
  */
@@ -1356,9 +1261,9 @@ nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size, struct thread *td)
 	if (nmp->nm_flag & NFSMNT_INT) {
  		sigset_t oldset;
 
- 		ncl_set_sigmask(td, &oldset);
+ 		newnfs_set_sigmask(td, &oldset);
 		bp = getblk(vp, bn, size, NFS_PCATCH, 0, 0);
- 		ncl_restore_sigmask(td, &oldset);
+ 		newnfs_restore_sigmask(td, &oldset);
 		while (bp == NULL) {
 			if (newnfs_sigintr(nmp, td))
 				return (NULL);
@@ -1544,9 +1449,9 @@ again:
 			NFS_DPF(ASYNCIO,
 				("ncl_asyncio: waiting for mount %p queue to drain\n", nmp));
 			nmp->nm_bufqwant = TRUE;
- 			error = ncl_msleep(td, &nmp->nm_bufq, &ncl_iod_mutex, 
-					   slpflag | PRIBIO,
- 					   "nfsaio", slptimeo);
+ 			error = newnfs_msleep(td, &nmp->nm_bufq, 
+			    &ncl_iod_mutex, slpflag | PRIBIO, "nfsaio",
+  			   slptimeo);
 			if (error) {
 				error2 = newnfs_sigintr(nmp, td);
 				if (error2) {
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 5dc3a593458..147c1641392 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -2708,9 +2708,9 @@ loop:
 		mtx_lock(&np->n_mtx);
 		while (np->n_directio_asyncwr > 0) {
 			np->n_flag |= NFSYNCWAIT;
-			error = ncl_msleep(td, (caddr_t)&np->n_directio_asyncwr,
-					   &np->n_mtx, slpflag | (PRIBIO + 1), 
-					   "nfsfsync", 0);
+			error = newnfs_msleep(td, &np->n_directio_asyncwr,
+			    &np->n_mtx, slpflag | (PRIBIO + 1), 
+			    "nfsfsync", 0);
 			if (error) {
 				if (newnfs_sigintr(nmp, td)) {
 					mtx_unlock(&np->n_mtx);

From a5905446f81f9381d4c27ac97cefb51456548702 Mon Sep 17 00:00:00 2001
From: Andrew Gallatin 
Date: Mon, 11 Jan 2010 20:32:51 +0000
Subject: [PATCH 1086/2592] Sync mxge(4) with head: r197391: Add support for TX
 throttling r198250: Move mxge(4)'s NIC watchdog reset handler from 	 a
 callout to a taskqueue r198303: Make mxge do a better job recovering from NIC
 h/w faults r200845: Don't take the driver mutex in mxge_tick() r201758:
 Remove extraneous semicolons

---
 sys/dev/mxge/if_mxge.c     | 188 ++++++++++++++++++++++++++++++-------
 sys/dev/mxge/if_mxge_var.h |   5 +
 2 files changed, 159 insertions(+), 34 deletions(-)

diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index e59d10c13c6..e0de0d7a50a 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
@@ -106,6 +107,7 @@ static int mxge_max_slices = 1;
 static int mxge_rss_hash_type = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
 static int mxge_always_promisc = 0;
 static int mxge_initial_mtu = ETHERMTU_JUMBO;
+static int mxge_throttle = 0;
 static char *mxge_fw_unaligned = "mxge_ethp_z8e";
 static char *mxge_fw_aligned = "mxge_eth_z8e";
 static char *mxge_fw_rss_aligned = "mxge_rss_eth_z8e";
@@ -596,10 +598,13 @@ static int
 mxge_select_firmware(mxge_softc_t *sc)
 {
 	int aligned = 0;
+	int force_firmware = mxge_force_firmware;
 
+	if (sc->throttle)
+		force_firmware = sc->throttle;
 
-	if (mxge_force_firmware != 0) {
-		if (mxge_force_firmware == 1)
+	if (force_firmware != 0) {
+		if (force_firmware == 1)
 			aligned = 1;
 		else
 			aligned = 0;
@@ -1313,9 +1318,47 @@ mxge_reset(mxge_softc_t *sc, int interrupts_setup)
 	mxge_change_promisc(sc, sc->ifp->if_flags & IFF_PROMISC);
 	mxge_change_pause(sc, sc->pause);
 	mxge_set_multicast_list(sc);
+	if (sc->throttle) {
+		cmd.data0 = sc->throttle;
+		if (mxge_send_cmd(sc, MXGEFW_CMD_SET_THROTTLE_FACTOR,
+				  &cmd)) {
+			device_printf(sc->dev,
+				      "can't enable throttle\n");
+		}
+	}
 	return status;
 }
 
+static int
+mxge_change_throttle(SYSCTL_HANDLER_ARGS)
+{
+	mxge_cmd_t cmd;
+	mxge_softc_t *sc;
+	int err;
+	unsigned int throttle;
+
+	sc = arg1;
+	throttle = sc->throttle;
+	err = sysctl_handle_int(oidp, &throttle, arg2, req);
+        if (err != 0) {
+                return err;
+        }
+
+	if (throttle == sc->throttle)
+		return 0;
+
+        if (throttle < MXGE_MIN_THROTTLE || throttle > MXGE_MAX_THROTTLE)
+                return EINVAL;
+	
+	mtx_lock(&sc->driver_mtx);
+	cmd.data0 = throttle;
+	err = mxge_send_cmd(sc, MXGEFW_CMD_SET_THROTTLE_FACTOR, &cmd);
+	if (err == 0)
+		sc->throttle = throttle;
+	mtx_unlock(&sc->driver_mtx);	
+	return err;
+}
+
 static int
 mxge_change_intr_coal(SYSCTL_HANDLER_ARGS)
 {
@@ -1507,6 +1550,12 @@ mxge_add_sysctls(mxge_softc_t *sc)
 			0, mxge_change_intr_coal, 
 			"I", "interrupt coalescing delay in usecs");
 
+	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 
+			"throttle",
+			CTLTYPE_INT|CTLFLAG_RW, sc,
+			0, mxge_change_throttle, 
+			"I", "transmit throttling");
+
 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 
 			"flow_control_enabled",
 			CTLTYPE_INT|CTLFLAG_RW, sc,
@@ -3591,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;
 
@@ -3612,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];
@@ -3691,12 +3738,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;
@@ -3723,7 +3769,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) {
@@ -3782,24 +3827,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->dying == 2)
+			sc->dying = 0;
+		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
@@ -3823,8 +3887,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");
@@ -3840,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
@@ -3865,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
@@ -3873,23 +3943,43 @@ 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;
+	running = sc->ifp->if_drv_flags & IFF_DRV_RUNNING;
+	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);
 
 }
 
@@ -4044,6 +4134,7 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 	default:
 		err = ENOTTY;
         }
+
 	return err;
 }
 
@@ -4070,6 +4161,7 @@ mxge_fetch_tunables(mxge_softc_t *sc)
 	TUNABLE_INT_FETCH("hw.mxge.rss_hash_type", &mxge_rss_hash_type);
 	TUNABLE_INT_FETCH("hw.mxge.rss_hashtype", &mxge_rss_hash_type);
 	TUNABLE_INT_FETCH("hw.mxge.initial_mtu", &mxge_initial_mtu);
+	TUNABLE_INT_FETCH("hw.mxge.throttle", &mxge_throttle);
 	if (sc->lro_cnt != 0)
 		mxge_lro_cnt = sc->lro_cnt;
 
@@ -4087,6 +4179,12 @@ mxge_fetch_tunables(mxge_softc_t *sc)
 	if (mxge_initial_mtu > ETHERMTU_JUMBO ||
 	    mxge_initial_mtu < ETHER_MIN_LEN)
 		mxge_initial_mtu = ETHERMTU_JUMBO;
+
+	if (mxge_throttle && mxge_throttle > MXGE_MAX_THROTTLE)
+		mxge_throttle = MXGE_MAX_THROTTLE;
+	if (mxge_throttle && mxge_throttle < MXGE_MIN_THROTTLE)
+		mxge_throttle = MXGE_MIN_THROTTLE;
+	sc->throttle = mxge_throttle;
 }
 
 
@@ -4503,6 +4601,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 */
@@ -4519,7 +4628,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);
@@ -4660,6 +4769,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:
@@ -4681,7 +4791,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;
 }
@@ -4702,6 +4817,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 dedb7ba2e47..5c1627f71e5 100644
--- a/sys/dev/mxge/if_mxge_var.h
+++ b/sys/dev/mxge/if_mxge_var.h
@@ -261,6 +261,7 @@ struct mxge_softc {
 	int fw_multicast_support;
 	int link_width;
 	int max_mtu;
+	int throttle;
 	int tx_defrag;
 	int media_flags;
 	int need_media_probe;
@@ -269,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;
@@ -287,6 +290,8 @@ struct mxge_softc {
 #define MXGE_PCI_REV_Z8ES	1
 #define MXGE_XFP_COMPLIANCE_BYTE	131
 #define MXGE_SFP_COMPLIANCE_BYTE	  3
+#define MXGE_MIN_THROTTLE	416
+#define MXGE_MAX_THROTTLE	4096
 
 #define MXGE_HIGHPART_TO_U32(X) \
 (sizeof (X) == 8) ? ((uint32_t)((uint64_t)(X) >> 32)) : (0)

From 4cc5ccf39929b94cd1f1c70093087e39445c8311 Mon Sep 17 00:00:00 2001
From: Qing Li 
Date: Tue, 12 Jan 2010 00:04:13 +0000
Subject: [PATCH 1087/2592] MFC	r201544

An existing incomplete ARP entry would expire a subsequent
statically configured entry of the same host. This bug was
due to the expiration timer was not cancelled when installing
the static entry. Since there exist a potential race condition
with respect to timer cancellation, simply check for the
LLE_STATIC bit inside the expiration function instead of
cancelling the active timer.
---
 sys/netinet/if_ether.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 15d529db88d..09b82609166 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -168,17 +168,23 @@ arptimer(void *arg)
 	ifp = lle->lle_tbl->llt_ifp;
 	IF_AFDATA_LOCK(ifp);
 	LLE_WLOCK(lle);
-	if ((!callout_pending(&lle->la_timer) &&
-	    callout_active(&lle->la_timer))) {
-		(void) llentry_free(lle);
-	}
-#ifdef DIAGNOSTIC
+	if (lle->la_flags & LLE_STATIC)
+		LLE_WUNLOCK(lle);
 	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));
-	}
+		if (!callout_pending(&lle->la_timer) &&
+		    callout_active(&lle->la_timer)) {
+			(void) llentry_free(lle);
+		} 
+#ifdef DIAGNOSTIC
+		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);
 }
 

From 9600c47d52adc7afd2315b63b894fe58202a9692 Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Tue, 12 Jan 2010 06:00:56 +0000
Subject: [PATCH 1088/2592] MFC r201443:   Add vlan(4) to all GENERIC kernels.

---
 sys/amd64/conf/GENERIC   | 1 +
 sys/i386/conf/GENERIC    | 1 +
 sys/ia64/conf/GENERIC    | 1 +
 sys/pc98/conf/GENERIC    | 1 +
 sys/powerpc/conf/GENERIC | 1 +
 sys/sparc64/conf/GENERIC | 1 +
 sys/sun4v/conf/GENERIC   | 1 +
 7 files changed, 7 insertions(+)

diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index f20510664a5..6dc5c2ca1ae 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -265,6 +265,7 @@ device		wi		# WaveLAN/Intersil/Symbol 802.11 wireless NICs.
 device		loop		# Network loopback
 device		random		# Entropy device
 device		ether		# Ethernet support
+device		vlan		# 802.1Q VLAN support
 device		tun		# Packet tunnel.
 device		pty		# BSD-style compatibility pseudo ttys
 device		md		# Memory "disks"
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 80ad672b2e7..7b5d4911650 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -278,6 +278,7 @@ device		wi		# WaveLAN/Intersil/Symbol 802.11 wireless NICs.
 device		loop		# Network loopback
 device		random		# Entropy device
 device		ether		# Ethernet support
+device		vlan		# 802.1Q VLAN support
 device		tun		# Packet tunnel.
 device		pty		# BSD-style compatibility pseudo ttys
 device		md		# Memory "disks"
diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
index 937f2f9e93b..98a63fb7485 100644
--- a/sys/ia64/conf/GENERIC
+++ b/sys/ia64/conf/GENERIC
@@ -144,6 +144,7 @@ device		kue		# Kawasaki LSI USB Ethernet
 
 # Various (pseudo) devices
 device		ether		# Ethernet support
+device		vlan		# 802.1Q VLAN support
 device		faith		# IPv6-to-IPv4 relaying (translation)
 device		gif		# IPv6 and IPv4 tunneling
 device		loop		# Network loopback
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index edb8150317e..821b563d97b 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -232,6 +232,7 @@ device		xe		# Xircom pccard Ethernet
 device		loop		# Network loopback
 device		random		# Entropy device
 device		ether		# Ethernet support
+device		vlan		# 802.1Q VLAN support
 device		tun		# Packet tunnel.
 device		pty		# BSD-style compatibility pseudo ttys
 device		md		# Memory "disks"
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index db6d0cd8370..4fc2ce83547 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -123,6 +123,7 @@ device		fxp		# Intel EtherExpress PRO/100B (82557, 82558)
 device		loop		# Network loopback
 device		random		# Entropy device
 device		ether		# Ethernet support
+device		vlan		# 802.1Q VLAN support
 device		tun		# Packet tunnel.
 device		pty		# BSD-style compatibility pseudo ttys
 device		md		# Memory "disks"
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index d79db515ed9..1b4a74c18cc 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -207,6 +207,7 @@ device		ath_rate_sample	# SampleRate tx rate control for ath
 device		loop		# Network loopback
 device		random		# Entropy device
 device		ether		# Ethernet support
+device		vlan		# 802.1Q VLAN support
 device		tun		# Packet tunnel.
 device		pty		# BSD-style compatibility pseudo ttys
 device		md		# Memory "disks"
diff --git a/sys/sun4v/conf/GENERIC b/sys/sun4v/conf/GENERIC
index ea72139d0a9..e0e2cc25b8b 100644
--- a/sys/sun4v/conf/GENERIC
+++ b/sys/sun4v/conf/GENERIC
@@ -169,6 +169,7 @@ device		bge		# Broadcom BCM570xx Gigabit Ethernet
 device		loop		# Network loopback
 device		random		# Entropy device
 device		ether		# Ethernet support
+device		vlan		# 802.1Q VLAN support
 device		tun		# Packet tunnel.
 device		pty		# BSD-style compatibility pseudo ttys
 device		md		# Memory "disks"

From 0e003a57cecbd121622d0accd6141c3195bef732 Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Tue, 12 Jan 2010 06:09:56 +0000
Subject: [PATCH 1089/2592] MFC r201953:   Correct the explination text for the
 kern.ngroups.  It reflects the   number of supplemental groups, not the total
 number of groups.

---
 sys/kern/kern_mib.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index 04e4dc0437b..78382c7c5c4 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -125,7 +125,8 @@ SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD,
     0, _POSIX_VERSION, "Version of POSIX attempting to comply to");
 
 SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RD,
-    0, NGROUPS_MAX, "Maximum number of groups a user can belong to");
+    0, NGROUPS_MAX,
+    "Maximum number of supplemental groups a user can belong to");
 
 SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, CTLFLAG_RD,
     0, 1, "Whether job control is available");

From 43ede8f5fed075bdb4296b5749dbd1f706206f88 Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Tue, 12 Jan 2010 06:11:36 +0000
Subject: [PATCH 1090/2592] MFC r201954:

  Update the comment on printing group membership to reflect that fact
  that each group the process is a member of is printed rather than
  an entry for each group the user could be a member of.
---
 sys/fs/procfs/procfs_status.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/fs/procfs/procfs_status.c b/sys/fs/procfs/procfs_status.c
index 80d73928560..7850504fe30 100644
--- a/sys/fs/procfs/procfs_status.c
+++ b/sys/fs/procfs/procfs_status.c
@@ -82,7 +82,7 @@ procfs_doprocstatus(PFS_FILL_ARGS)
 	sid = sess->s_leader ? sess->s_leader->p_pid : 0;
 
 /* comm pid ppid pgid sid tty ctty,sldr start ut st wmsg
-				euid ruid rgid,egid,groups[1 .. NGROUPS]
+				euid ruid rgid,egid,groups[1 .. ngroups]
 */
 
 	pc = p->p_comm;

From 2a46409df577e3bed64de59e5c8381669c25b0af Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Tue, 12 Jan 2010 06:14:24 +0000
Subject: [PATCH 1091/2592] MFC r201955:   Improve the comment about
 CMGROUP_MAX.

---
 sys/sys/socket.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index 0de965f6b4d..5fa906c9378 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -483,8 +483,8 @@ struct cmsghdr {
 #if __BSD_VISIBLE
 /*
  * While we may have more groups than this, the cmsgcred struct must
- * be able to fit in an mbuf, and NGROUPS_MAX is too large to allow
- * this.
+ * be able to fit in an mbuf and we have historically supported a
+ * maximum of 16 groups.
 */
 #define CMGROUP_MAX 16
 

From cb8922f4cbbb02d4496c141985259027a1f65ffe Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Tue, 12 Jan 2010 07:33:33 +0000
Subject: [PATCH 1092/2592] MFC r201444:

  The size of credential messages is limited by CMGROUP_MAX rather than
  NGROUPS.
---
 crypto/heimdal/kcm/connect.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/heimdal/kcm/connect.c b/crypto/heimdal/kcm/connect.c
index b3a21aa66a0..edad6fcdf25 100644
--- a/crypto/heimdal/kcm/connect.c
+++ b/crypto/heimdal/kcm/connect.c
@@ -149,7 +149,7 @@ update_client_creds(int s, kcm_client *peer)
 	struct sockcred *sc;
 	
 	memset(&msg, 0, sizeof(msg));
-	crmsgsize = CMSG_SPACE(SOCKCREDSIZE(NGROUPS));
+	crmsgsize = CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX));
 	if (crmsgsize == 0)
 	    return 1 ;
 

From bd048c87c0bfbbbd34d209e2b563901726562c38 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 12 Jan 2010 18:47:40 +0000
Subject: [PATCH 1093/2592] MFC 201202: Use reallocf() to simplify some logic.

---
 usr.sbin/arp/arp.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c
index 31426583898..61427d34c81 100644
--- a/usr.sbin/arp/arp.c
+++ b/usr.sbin/arp/arp.c
@@ -499,7 +499,7 @@ search(u_long addr, action_fn *action)
 {
 	int mib[6];
 	size_t needed;
-	char *lim, *buf, *newbuf, *next;
+	char *lim, *buf, *next;
 	struct rt_msghdr *rtm;
 	struct sockaddr_inarp *sin2;
 	struct sockaddr_dl *sdl;
@@ -522,13 +522,9 @@ search(u_long addr, action_fn *action)
 		return 0;
 	buf = NULL;
 	for (;;) {
-		newbuf = realloc(buf, needed);
-		if (newbuf == NULL) {
-			if (buf != NULL)
-				free(buf);
+		buf = reallocf(buf, needed);
+		if (buf == NULL)
 			errx(1, "could not reallocate memory");
-		}
-		buf = newbuf;
 		st = sysctl(mib, 6, buf, &needed, NULL, 0);
 		if (st == 0 || errno != ENOMEM)
 			break;

From d46150d4321ccf67d0fbb74cee004fe2f8aecd0f Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 12 Jan 2010 19:55:07 +0000
Subject: [PATCH 1094/2592] MFC 201215: Add support for configuring vlan(4)
 interfaces as child devices similar to wlan(4) interfaces.  vlan(4)
 interfaces are listed via a new 'vlans_' variable.  If a vlan interface
 is a number, then that number is treated as the vlan tag for the interface
 and the interface will be named '.'. Otherwise, the vlan tag must be
 provided via a vlan parameter in a 'create_args_' variable.

While I'm here, fix a few nits in rc.conf(5) and mention create_args_ in
the description of cloned_interfaces.
---
 etc/defaults/rc.conf     |  2 ++
 etc/network.subr         | 56 +++++++++++++++++++++++++++++++++++++---
 share/man/man5/rc.conf.5 | 49 +++++++++++++++++++++++++++++++++--
 3 files changed, 101 insertions(+), 6 deletions(-)

diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index c1dc00078bf..dd5c0b35bed 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -198,6 +198,8 @@ ifconfig_lo0="inet 127.0.0.1"	# default loopback device configuration.
 #ifconfig_lo0_alias0="inet 127.0.0.254 netmask 0xffffffff" # Sample alias entry.
 #ifconfig_ed0_ipx="ipx 0x00010010"	# Sample IPX address family entry.
 #ifconfig_fxp0_name="net0"	# Change interface name from fxp0 to net0.
+#vlans_fxp0="101 vlan0"		# vlan(4) interfaces for fxp0 device
+#create_arg_vlan0="vlan 102"	# vlan tag for vlan0 device
 #wlans_ath0="wlan0"		# wlan(4) interfaces for ath0 device
 #wlandebug_wlan0="scan+auth+assoc"	# Set debug flags with wlanddebug(8)
 #ipv4_addrs_fxp0="192.168.0.1/24 192.168.1.1-5/28" # example IPv4 address entry.
diff --git a/etc/network.subr b/etc/network.subr
index 5f02714e44c..497cc5b7520 100644
--- a/etc/network.subr
+++ b/etc/network.subr
@@ -46,7 +46,7 @@ ifn_start()
 	ifconfig_up ${ifn} && cfg=0
 	ipv4_up ${ifn} && cfg=0
 	ipx_up ${ifn} && cfg=0
-	childif_create ${ifn}
+	childif_create ${ifn} && cfg=0
 
 	return $cfg
 }
@@ -67,7 +67,7 @@ ifn_stop()
 	ipv4_down ${ifn} && cfg=0
 	ifconfig_down ${ifn} && cfg=0
 	ifscript_down ${ifn} && cfg=0
-	childif_destroy ${ifn}
+	childif_destroy ${ifn} && cfg=0
 
 	return $cfg
 }
@@ -530,7 +530,7 @@ clone_down()
 #
 childif_create()
 {
-	local cfg child child_wlans create_args debug_flags ifn i
+	local cfg child child_vlans child_wlans create_args debug_flags ifn i
 	cfg=1
 
 	ifn=$1
@@ -559,6 +559,32 @@ childif_create()
 		fi
 	done
 
+	# Create vlan interfaces
+	child_vlans=`get_if_var $ifn vlans_IF`
+
+	if [ -n "${child_vlans}" ]; then
+		load_kld if_vlan
+	fi
+
+	for child in ${child_vlans}; do
+		if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then
+			child="${ifn}.${child}"
+			create_args=`get_if_var $child create_args_IF`
+			ifconfig $child create ${create_args} && cfg=0
+		else
+			create_args="vlandev $ifn `get_if_var $child create_args_IF`"
+			if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then
+				ifconfig $child create ${create_args} && cfg=0
+			else
+				i=`ifconfig vlan create ${create_args}`
+				ifconfig $i name $child && cfg=0
+			fi
+		fi
+		if autoif $child; then
+			ifn_start $child
+		fi
+	done
+
 	return ${cfg}
 }
 
@@ -566,12 +592,34 @@ childif_create()
 #
 childif_destroy()
 {
-	local cfg child child_wlans ifn
+	local cfg child child_vlans child_wlans ifn
 
 	child_wlans=`get_if_var $ifn wlans_IF`
 	for child in ${child_wlans}; do
+		if ! ifexists $child; then
+			continue
+		fi
+		if autoif $child; then
+			ifn_stop $child
+		fi
 		ifconfig $child destroy && cfg=0
 	done
+
+	child_vlans=`get_if_var $ifn vlans_IF`
+	for child in ${child_vlans}; do
+		if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then
+			child="${ifn}.${child}"
+		fi
+		if ! ifexists $child; then
+			continue
+		fi
+		if autoif $child; then
+			ifn_stop $child
+		fi
+		ifconfig $child destroy && cfg=0
+	done
+
+	return ${cfg}
 }
 
 # Create netgraph nodes.
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 06823235d8b..0f377b2e679 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -1161,6 +1161,45 @@ and
 variables.
 .Pp
 If a
+.Va vlans_ Ns Aq Ar interface
+variable is set,
+a
+.Xr vlan 4
+interface will be created for each item in the list with the
+.Ar vlandev
+argument set to
+.Ar interface .
+If a vlan interface's name is a number,
+then that number is used as the vlan tag and the new vlan interface is
+named
+.Ar interface . Ns Ar tag .
+Otherwise,
+the vlan tag must be specified via a
+.Va vlan
+parameter in the
+.Va create_args_ Ns Aq Ar interface
+variable.
+.Pp
+To create a vlan device named
+.Li em0.101
+on
+.Li em0
+with the vlan tag 101:
+.Bd -literal
+vlans_em0="101"
+.Ed
+.Pp
+To create a vlan device named
+.Li myvlan
+on
+.Li em0
+with the vlan tag 102:
+.Bd -literal
+vlans_em0="myvlan"
+create_args_myvlan="vlan 102"
+.Ed
+.Pp
+If a
 .Va wlans_ Ns Aq Ar interface
 variable is set,
 an
@@ -1227,7 +1266,7 @@ Finally, you can add
 options in this variable, in addition to the
 .Pa /etc/start_if. Ns Aq Ar interface
 file.
-For instance, configure an
+For instance, to configure an
 .Xr ath 4
 wireless device in station mode with an address obtained 
 via DHCP, using WPA authentication and 802.11b mode, it is
@@ -1249,7 +1288,7 @@ This is intended to replace the no longer supported
 .Va pccard_ifconfig
 variable.
 .Pp
-It is also possible to rename interface by doing:
+It is also possible to rename an interface by doing:
 .Bd -literal
 ifconfig_ed0_name="net0"
 ifconfig_net0="inet 192.0.2.1 netmask 0xffffff00"
@@ -1286,6 +1325,12 @@ Now this works only for IPv6 link local multicast addresses.
 .It Va cloned_interfaces
 .Pq Vt str
 Set to the list of clonable network interfaces to create on this host.
+Further cloning arguments may be passed to the
+.Xr ifconfig 8
+.Cm create
+command for each interface by setting the
+.Va create_args_ Ns Aq Ar interface
+variable.
 Entries in
 .Va cloned_interfaces
 are automatically appended to

From 8e42544da718ea0ba64994213aa5b4d02771bc3e Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 13 Jan 2010 18:12:21 +0000
Subject: [PATCH 1095/2592] MFC 199607, 200797, 201270, 201669: Use
 pthread_once() to initialize the thread-local storage for localtime() and
 gmtime() and _once() to initialize gmt state rather than home-rolled versions
 using pthread mutex locks.

---
 lib/libc/stdtime/localtime.c | 81 ++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 40 deletions(-)

diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c
index 9fc5f3ee99b..bee916b03f9 100644
--- a/lib/libc/stdtime/localtime.c
+++ b/lib/libc/stdtime/localtime.c
@@ -235,9 +235,14 @@ static struct state	gmtmem;
 
 static char		lcl_TZname[TZ_STRLEN_MAX + 1];
 static int		lcl_is_set;
-static int		gmt_is_set;
+static pthread_once_t	gmt_once = PTHREAD_ONCE_INIT;
 static pthread_rwlock_t	lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER;
-static pthread_mutex_t	gmt_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_once_t	gmtime_once = PTHREAD_ONCE_INIT;
+static pthread_key_t	gmtime_key;
+static int		gmtime_key_error;
+static pthread_once_t	localtime_once = PTHREAD_ONCE_INIT;
+static pthread_key_t	localtime_key;
+static int		localtime_key_error;
 
 char *			tzname[2] = {
 	wildabbr,
@@ -1407,27 +1412,24 @@ struct tm * const	tmp;
 	return result;
 }
 
+static void
+localtime_key_init(void)
+{
+
+	localtime_key_error = _pthread_key_create(&localtime_key, free);
+}
+
 struct tm *
 localtime(timep)
 const time_t * const	timep;
 {
-	static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
-	static pthread_key_t localtime_key = -1;
 	struct tm *p_tm;
-	int r;
 
 	if (__isthreaded != 0) {
-		if (localtime_key < 0) {
-			_pthread_mutex_lock(&localtime_mutex);
-			if (localtime_key < 0) {
-				if ((r = _pthread_key_create(&localtime_key,
-				    free)) != 0) {
-					_pthread_mutex_unlock(&localtime_mutex);
-					errno = r;
-					return(NULL);
-				}
-			}
-			_pthread_mutex_unlock(&localtime_mutex);
+		_pthread_once(&localtime_once, localtime_key_init);
+		if (localtime_key_error != 0) {
+			errno = localtime_key_error;
+			return(NULL);
 		}
 		p_tm = _pthread_getspecific(localtime_key);
 		if (p_tm == NULL) {
@@ -1464,6 +1466,17 @@ struct tm *		tmp;
 	return tmp;
 }
 
+static void
+gmt_init(void)
+{
+
+#ifdef ALL_STATE
+	gmtptr = (struct state *) malloc(sizeof *gmtptr);
+	if (gmtptr != NULL)
+#endif /* defined ALL_STATE */
+		gmtload(gmtptr);
+}
+
 /*
 ** gmtsub is to gmtime as localsub is to localtime.
 */
@@ -1476,16 +1489,7 @@ struct tm * const	tmp;
 {
 	register struct tm *	result;
 
-	_MUTEX_LOCK(&gmt_mutex);
-	if (!gmt_is_set) {
-#ifdef ALL_STATE
-		gmtptr = (struct state *) malloc(sizeof *gmtptr);
-		if (gmtptr != NULL)
-#endif /* defined ALL_STATE */
-			gmtload(gmtptr);
-		gmt_is_set = TRUE;
-	}
-	_MUTEX_UNLOCK(&gmt_mutex);
+	_once(&gmt_once, gmt_init);
 	result = timesub(timep, offset, gmtptr, tmp);
 #ifdef TM_ZONE
 	/*
@@ -1509,27 +1513,24 @@ struct tm * const	tmp;
 	return result;
 }
 
+static void
+gmtime_key_init(void)
+{
+
+	gmtime_key_error = _pthread_key_create(&gmtime_key, free);
+}
+
 struct tm *
 gmtime(timep)
 const time_t * const	timep;
 {
-	static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
-	static pthread_key_t gmtime_key = -1;
 	struct tm *p_tm;
-	int r;
 
 	if (__isthreaded != 0) {
-		if (gmtime_key < 0) {
-			_pthread_mutex_lock(&gmtime_mutex);
-			if (gmtime_key < 0) {
-				if ((r = _pthread_key_create(&gmtime_key,
-				    free)) != 0) {
-					_pthread_mutex_unlock(&gmtime_mutex);
-					errno = r;
-					return(NULL);
-				}
-			}
-			_pthread_mutex_unlock(&gmtime_mutex);
+		_pthread_once(&gmtime_once, gmtime_key_init);
+		if (gmtime_key_error != 0) {
+			errno = gmtime_key_error;
+			return(NULL);
 		}
 		/*
 		 * Changed to follow POSIX.1 threads standard, which

From 955990d26e9822385ef807cc1975ab4924f92c45 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 19:55:51 +0000
Subject: [PATCH 1096/2592] MFC: 197164

Factor out the duplicated macro for the device type used in the
OFW device tree for PCI bridges and add a new one for PCI Express.
While at it, take advantage of the former for the rman(9) work-
around in jbusppm(4).
---
 sys/sparc64/pci/ofw_pci.h     | 4 ++++
 sys/sparc64/pci/psycho.c      | 4 +---
 sys/sparc64/pci/schizo.c      | 4 +---
 sys/sparc64/sparc64/jbusppm.c | 6 +++++-
 4 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/sys/sparc64/pci/ofw_pci.h b/sys/sparc64/pci/ofw_pci.h
index 19c2fbed5db..3b5059858c1 100644
--- a/sys/sparc64/pci/ofw_pci.h
+++ b/sys/sparc64/pci/ofw_pci.h
@@ -44,6 +44,10 @@ typedef uint32_t ofw_pci_intr_t;
 #define	OFW_PCI_CS_MEM32	0x02
 #define	OFW_PCI_CS_MEM64	0x03
 
+/* OFW device types */
+#define	OFW_TYPE_PCI		"pci"
+#define	OFW_TYPE_PCIE		"pciex"
+
 struct ofw_pci_ranges {
 	uint32_t	cspace;
 	uint32_t	child_hi;
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index c8caec2c4ef..8034612fd4c 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -224,8 +224,6 @@ struct psycho_dma_sync {
  * providing two PCI buses.
  */
 
-#define	OFW_PCI_TYPE		"pci"
-
 struct psycho_desc {
 	const char	*pd_string;
 	int		pd_mode;
@@ -275,7 +273,7 @@ psycho_probe(device_t dev)
 	const char *dtype;
 
 	dtype = ofw_bus_get_type(dev);
-	if (dtype != NULL && strcmp(dtype, OFW_PCI_TYPE) == 0 &&
+	if (dtype != NULL && strcmp(dtype, OFW_TYPE_PCI) == 0 &&
 	    psycho_get_desc(dev) != NULL) {
 		device_set_desc(dev, "U2P UPA-PCI bridge");
 		return (0);
diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index 0eedd91917f..c1e6e1b4c8f 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -209,8 +209,6 @@ struct schizo_dma_sync {
 #define	SCHIZO_ICON_WRITE_8(sc, offs, v) \
 	SCHIZO_SPC_WRITE_8(STX_ICON, (sc), (offs), (v))
 
-#define	OFW_PCI_TYPE		"pci"
-
 struct schizo_desc {
 	const char	*sd_string;
 	int		sd_mode;
@@ -244,7 +242,7 @@ schizo_probe(device_t dev)
 	const char *dtype;
 
 	dtype = ofw_bus_get_type(dev);
-	if (dtype != NULL && strcmp(dtype, OFW_PCI_TYPE) == 0 &&
+	if (dtype != NULL && strcmp(dtype, OFW_TYPE_PCI) == 0 &&
 	    schizo_get_desc(dev) != NULL) {
 		device_set_desc(dev, "Sun Host-PCI bridge");
 		return (0);
diff --git a/sys/sparc64/sparc64/jbusppm.c b/sys/sparc64/sparc64/jbusppm.c
index c08b64d0d58..db654f00cbe 100644
--- a/sys/sparc64/sparc64/jbusppm.c
+++ b/sys/sparc64/sparc64/jbusppm.c
@@ -40,6 +40,10 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
+#if 1
+#include 
+#endif
+
 #define	JBUSPPM_NREG	2
 
 #define	JBUSPPM_DEVID	0
@@ -150,7 +154,7 @@ jbusppm_attach(device_t dev)
 			for (j = 0; j < nchildren; j++) {
 				if (ofw_bus_get_type(children[j]) != NULL &&
 				    strcmp(ofw_bus_get_type(children[j]),
-				    "pci") == 0 &&
+				    OFW_TYPE_PCI) == 0 &&
 				    ofw_bus_get_compat(children[j]) != NULL &&
 				    strcmp(ofw_bus_get_compat(children[j]),
 				    "pci108e,a801") == 0 &&

From d9d6b39c57320ee369f6477317d86df45325b56d Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 19:59:13 +0000
Subject: [PATCH 1097/2592] MFC: r200815, r200816

Provide and consume missing module dependency information.
---
 sys/dev/auxio/auxio.c         | 8 +++++---
 sys/sparc64/central/central.c | 1 +
 sys/sparc64/fhc/fhc.c         | 3 ++-
 sys/sparc64/pci/apb.c         | 1 +
 sys/sparc64/pci/ofw_pcib.c    | 1 +
 sys/sparc64/sbus/sbus.c       | 1 +
 sys/sparc64/sparc64/nexus.c   | 1 +
 7 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/sys/dev/auxio/auxio.c b/sys/dev/auxio/auxio.c
index 9943a0afd60..6e2d356ea7a 100644
--- a/sys/dev/auxio/auxio.c
+++ b/sys/dev/auxio/auxio.c
@@ -56,7 +56,7 @@
  */
 
 /*
- * AUXIO registers support on the sbus & ebus2, used for the floppy driver
+ * AUXIO registers support on the SBus & EBus2, used for the floppy driver
  * and to control the system LED, for the BLINK option.
  */
 
@@ -85,8 +85,8 @@ __FBSDID("$FreeBSD$");
 #include 
 
 /*
- * on sun4u, auxio exists with one register (LED) on the sbus, and 5
- * registers on the ebus2 (pci) (LED, PCIMODE, FREQUENCY, SCSI
+ * On sun4u, auxio exists with one register (LED) on the SBus, and 5
+ * registers on the EBus2 (pci) (LED, PCIMODE, FREQUENCY, SCSI
  * OSCILLATOR, and TEMP SENSE.
  */
 
@@ -142,6 +142,7 @@ static driver_t auxio_sbus_driver = {
 
 static devclass_t	auxio_devclass;
 DRIVER_MODULE(auxio, sbus, auxio_sbus_driver, auxio_devclass, 0, 0);
+MODULE_DEPEND(auxio, sbus, 1, 1, 1);
 
 /* EBus */
 static device_method_t auxio_ebus_methods[] = {
@@ -158,6 +159,7 @@ static driver_t auxio_ebus_driver = {
 };
 
 DRIVER_MODULE(auxio, ebus, auxio_ebus_driver, auxio_devclass, 0, 0);
+MODULE_DEPEND(auxio, ebus, 1, 1, 1);
 MODULE_VERSION(auxio, 1);
 
 #define AUXIO_LOCK_INIT(sc)	\
diff --git a/sys/sparc64/central/central.c b/sys/sparc64/central/central.c
index 4ded549e70d..012130f150a 100644
--- a/sys/sparc64/central/central.c
+++ b/sys/sparc64/central/central.c
@@ -106,6 +106,7 @@ static driver_t central_driver = {
 static devclass_t central_devclass;
 
 DRIVER_MODULE(central, nexus, central_driver, central_devclass, 0, 0);
+MODULE_DEPEND(fhc, nexus, 1, 1, 1);
 MODULE_VERSION(central, 1);
 
 static int
diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c
index 91416ec8431..6ef7b1b519f 100644
--- a/sys/sparc64/fhc/fhc.c
+++ b/sys/sparc64/fhc/fhc.c
@@ -120,8 +120,9 @@ static driver_t fhc_driver = {
 static devclass_t fhc_devclass;
 
 DRIVER_MODULE(fhc, central, fhc_driver, fhc_devclass, 0, 0);
-DRIVER_MODULE(fhc, nexus, fhc_driver, fhc_devclass, 0, 0);
 MODULE_DEPEND(fhc, central, 1, 1, 1);
+DRIVER_MODULE(fhc, nexus, fhc_driver, fhc_devclass, 0, 0);
+MODULE_DEPEND(fhc, nexus, 1, 1, 1);
 MODULE_VERSION(fhc, 1);
 
 static const struct intr_controller fhc_ic = {
diff --git a/sys/sparc64/pci/apb.c b/sys/sparc64/pci/apb.c
index ad4dfca7cd1..54087cc9353 100644
--- a/sys/sparc64/pci/apb.c
+++ b/sys/sparc64/pci/apb.c
@@ -112,6 +112,7 @@ static devclass_t pcib_devclass;
 
 DEFINE_CLASS_0(pcib, apb_driver, apb_methods, sizeof(struct apb_softc));
 DRIVER_MODULE(apb, pci, apb_driver, pcib_devclass, 0, 0);
+MODULE_DEPEND(apb, pci, 1, 1, 1);
 
 /* APB specific registers */
 #define	APBR_IOMAP	0xde
diff --git a/sys/sparc64/pci/ofw_pcib.c b/sys/sparc64/pci/ofw_pcib.c
index 3be57e3d340..72ddeb88001 100644
--- a/sys/sparc64/pci/ofw_pcib.c
+++ b/sys/sparc64/pci/ofw_pcib.c
@@ -94,6 +94,7 @@ static devclass_t pcib_devclass;
 DEFINE_CLASS_0(pcib, ofw_pcib_driver, ofw_pcib_methods,
     sizeof(struct ofw_pcib_gen_softc));
 DRIVER_MODULE(ofw_pcib, pci, ofw_pcib_driver, pcib_devclass, 0, 0);
+MODULE_DEPEND(ofw_pcib, pci, 1, 1, 1);
 
 static int
 ofw_pcib_probe(device_t dev)
diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c
index dd36f036d7e..b42a9934f9c 100644
--- a/sys/sparc64/sbus/sbus.c
+++ b/sys/sparc64/sbus/sbus.c
@@ -248,6 +248,7 @@ static driver_t sbus_driver = {
 static devclass_t sbus_devclass;
 
 DRIVER_MODULE(sbus, nexus, sbus_driver, sbus_devclass, 0, 0);
+MODULE_DEPEND(sbus, nexus, 1, 1, 1);
 MODULE_VERSION(sbus, 1);
 
 #define	OFW_SBUS_TYPE	"sbus"
diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c
index 58c0805600e..798eec9eed0 100644
--- a/sys/sparc64/sparc64/nexus.c
+++ b/sys/sparc64/sparc64/nexus.c
@@ -145,6 +145,7 @@ static devclass_t nexus_devclass;
 
 DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, sizeof(struct nexus_softc));
 DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
+MODULE_VERSION(nexus, 1);
 
 static const char *const nexus_excl_name[] = {
 	"aliases",

From cd93dd27dd070bd29ce11ea985366e15a985be5f Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 20:03:24 +0000
Subject: [PATCH 1098/2592] MFC: r200874

Enroll these drivers in multipass probing. The motivation behind this
is that the JBus to EBus bridges share the interrupt controller of a
sibling JBus to PCIe bridge (at least as far as the OFW device tree
is concerned, in reality they are part of the same chip) so we have to
probe and attach the latter first. That happens to be also the case
due to the fact that the JBus to PCIe bridges appear first in the OFW
device tree but it doesn't hurt to ensure the right order.
---
 sys/dev/auxio/auxio.c         | 7 +++++--
 sys/sparc64/central/central.c | 3 ++-
 sys/sparc64/ebus/ebus.c       | 3 ++-
 sys/sparc64/fhc/fhc.c         | 6 ++++--
 sys/sparc64/pci/apb.c         | 2 +-
 sys/sparc64/pci/ofw_pcib.c    | 3 ++-
 sys/sparc64/pci/ofw_pcibus.c  | 3 ++-
 sys/sparc64/sbus/dma_sbus.c   | 8 +++++++-
 sys/sparc64/sbus/sbus.c       | 3 ++-
 sys/sparc64/sparc64/nexus.c   | 3 ++-
 sys/sparc64/sparc64/upa.c     | 2 +-
 11 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/sys/dev/auxio/auxio.c b/sys/dev/auxio/auxio.c
index 6e2d356ea7a..35fd307a97a 100644
--- a/sys/dev/auxio/auxio.c
+++ b/sys/dev/auxio/auxio.c
@@ -141,7 +141,9 @@ static driver_t auxio_sbus_driver = {
 };
 
 static devclass_t	auxio_devclass;
-DRIVER_MODULE(auxio, sbus, auxio_sbus_driver, auxio_devclass, 0, 0);
+/* The probe order is handled by sbus(4). */
+EARLY_DRIVER_MODULE(auxio, sbus, auxio_sbus_driver, auxio_devclass, 0, 0,
+    BUS_PASS_DEFAULT);
 MODULE_DEPEND(auxio, sbus, 1, 1, 1);
 
 /* EBus */
@@ -158,7 +160,8 @@ static driver_t auxio_ebus_driver = {
 	sizeof(struct auxio_softc)
 };
 
-DRIVER_MODULE(auxio, ebus, auxio_ebus_driver, auxio_devclass, 0, 0);
+EARLY_DRIVER_MODULE(auxio, ebus, auxio_ebus_driver, auxio_devclass, 0, 0,
+    BUS_PASS_DEFAULT);
 MODULE_DEPEND(auxio, ebus, 1, 1, 1);
 MODULE_VERSION(auxio, 1);
 
diff --git a/sys/sparc64/central/central.c b/sys/sparc64/central/central.c
index 012130f150a..777660fdfeb 100644
--- a/sys/sparc64/central/central.c
+++ b/sys/sparc64/central/central.c
@@ -105,7 +105,8 @@ static driver_t central_driver = {
 
 static devclass_t central_devclass;
 
-DRIVER_MODULE(central, nexus, central_driver, central_devclass, 0, 0);
+EARLY_DRIVER_MODULE(central, nexus, central_driver, central_devclass, 0, 0,
+    BUS_PASS_BUS);
 MODULE_DEPEND(fhc, nexus, 1, 1, 1);
 MODULE_VERSION(central, 1);
 
diff --git a/sys/sparc64/ebus/ebus.c b/sys/sparc64/ebus/ebus.c
index 3bafaae3323..a3e6d582780 100644
--- a/sys/sparc64/ebus/ebus.c
+++ b/sys/sparc64/ebus/ebus.c
@@ -138,7 +138,8 @@ static driver_t ebus_driver = {
 
 static devclass_t ebus_devclass;
 
-DRIVER_MODULE(ebus, pci, ebus_driver, ebus_devclass, 0, 0);
+EARLY_DRIVER_MODULE(ebus, pci, ebus_driver, ebus_devclass, 0, 0,
+    BUS_PASS_BUS);
 MODULE_DEPEND(ebus, pci, 1, 1, 1);
 MODULE_VERSION(ebus, 1);
 
diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c
index 6ef7b1b519f..6aefffa1a6f 100644
--- a/sys/sparc64/fhc/fhc.c
+++ b/sys/sparc64/fhc/fhc.c
@@ -119,9 +119,11 @@ static driver_t fhc_driver = {
 
 static devclass_t fhc_devclass;
 
-DRIVER_MODULE(fhc, central, fhc_driver, fhc_devclass, 0, 0);
+EARLY_DRIVER_MODULE(fhc, central, fhc_driver, fhc_devclass, 0, 0,
+    BUS_PASS_BUS);
 MODULE_DEPEND(fhc, central, 1, 1, 1);
-DRIVER_MODULE(fhc, nexus, fhc_driver, fhc_devclass, 0, 0);
+EARLY_DRIVER_MODULE(fhc, nexus, fhc_driver, fhc_devclass, 0, 0,
+    BUS_PASS_BUS);
 MODULE_DEPEND(fhc, nexus, 1, 1, 1);
 MODULE_VERSION(fhc, 1);
 
diff --git a/sys/sparc64/pci/apb.c b/sys/sparc64/pci/apb.c
index 54087cc9353..2f4932e2c1c 100644
--- a/sys/sparc64/pci/apb.c
+++ b/sys/sparc64/pci/apb.c
@@ -111,7 +111,7 @@ static device_method_t apb_methods[] = {
 static devclass_t pcib_devclass;
 
 DEFINE_CLASS_0(pcib, apb_driver, apb_methods, sizeof(struct apb_softc));
-DRIVER_MODULE(apb, pci, apb_driver, pcib_devclass, 0, 0);
+EARLY_DRIVER_MODULE(apb, pci, apb_driver, pcib_devclass, 0, 0, BUS_PASS_BUS);
 MODULE_DEPEND(apb, pci, 1, 1, 1);
 
 /* APB specific registers */
diff --git a/sys/sparc64/pci/ofw_pcib.c b/sys/sparc64/pci/ofw_pcib.c
index 72ddeb88001..1988561ab84 100644
--- a/sys/sparc64/pci/ofw_pcib.c
+++ b/sys/sparc64/pci/ofw_pcib.c
@@ -93,7 +93,8 @@ static devclass_t pcib_devclass;
 
 DEFINE_CLASS_0(pcib, ofw_pcib_driver, ofw_pcib_methods,
     sizeof(struct ofw_pcib_gen_softc));
-DRIVER_MODULE(ofw_pcib, pci, ofw_pcib_driver, pcib_devclass, 0, 0);
+EARLY_DRIVER_MODULE(ofw_pcib, pci, ofw_pcib_driver, pcib_devclass, 0, 0,
+    BUS_PASS_BUS);
 MODULE_DEPEND(ofw_pcib, pci, 1, 1, 1);
 
 static int
diff --git a/sys/sparc64/pci/ofw_pcibus.c b/sys/sparc64/pci/ofw_pcibus.c
index bd2c7a65888..571b6acd32b 100644
--- a/sys/sparc64/pci/ofw_pcibus.c
+++ b/sys/sparc64/pci/ofw_pcibus.c
@@ -101,7 +101,8 @@ static devclass_t pci_devclass;
 
 DEFINE_CLASS_1(pci, ofw_pcibus_driver, ofw_pcibus_methods, 1 /* no softc */,
     pci_driver);
-DRIVER_MODULE(ofw_pcibus, pcib, ofw_pcibus_driver, pci_devclass, 0, 0);
+EARLY_DRIVER_MODULE(ofw_pcibus, pcib, ofw_pcibus_driver, pci_devclass, 0, 0,
+    BUS_PASS_BUS);
 MODULE_VERSION(ofw_pcibus, 1);
 MODULE_DEPEND(ofw_pcibus, pci, 1, 1, 1);
 
diff --git a/sys/sparc64/sbus/dma_sbus.c b/sys/sparc64/sbus/dma_sbus.c
index b4c2e5e6224..4bc1d438723 100644
--- a/sys/sparc64/sbus/dma_sbus.c
+++ b/sys/sparc64/sbus/dma_sbus.c
@@ -149,7 +149,13 @@ static driver_t dma_driver = {
 	sizeof(struct dma_softc),
 };
 
-DRIVER_MODULE(dma, sbus, dma_driver, dma_devclass, 0, 0);
+/*
+ * The probe order is handled by sbus(4) as we don't want the variants
+ * with children to be attached earlier than the stand-alone controllers
+ * in order to generally preserve the OFW device tree order.
+ */
+EARLY_DRIVER_MODULE(dma, sbus, dma_driver, dma_devclass, 0, 0,
+    BUS_PASS_DEFAULT);
 MODULE_DEPEND(dma, sbus, 1, 1, 1);
 MODULE_VERSION(dma, 1);
 
diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c
index b42a9934f9c..0c4b509e508 100644
--- a/sys/sparc64/sbus/sbus.c
+++ b/sys/sparc64/sbus/sbus.c
@@ -247,7 +247,8 @@ static driver_t sbus_driver = {
 
 static devclass_t sbus_devclass;
 
-DRIVER_MODULE(sbus, nexus, sbus_driver, sbus_devclass, 0, 0);
+EARLY_DRIVER_MODULE(sbus, nexus, sbus_driver, sbus_devclass, 0, 0,
+    BUS_PASS_BUS);
 MODULE_DEPEND(sbus, nexus, 1, 1, 1);
 MODULE_VERSION(sbus, 1);
 
diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c
index 798eec9eed0..04c2ddbcbee 100644
--- a/sys/sparc64/sparc64/nexus.c
+++ b/sys/sparc64/sparc64/nexus.c
@@ -144,7 +144,8 @@ static device_method_t nexus_methods[] = {
 static devclass_t nexus_devclass;
 
 DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, sizeof(struct nexus_softc));
-DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
+EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0,
+    BUS_PASS_BUS);
 MODULE_VERSION(nexus, 1);
 
 static const char *const nexus_excl_name[] = {
diff --git a/sys/sparc64/sparc64/upa.c b/sys/sparc64/sparc64/upa.c
index 7e81c8923ae..ecb11a2db4f 100644
--- a/sys/sparc64/sparc64/upa.c
+++ b/sys/sparc64/sparc64/upa.c
@@ -151,7 +151,7 @@ static device_method_t upa_methods[] = {
 static devclass_t upa_devclass;
 
 DEFINE_CLASS_0(upa, upa_driver, upa_methods, sizeof(struct upa_softc));
-DRIVER_MODULE(upa, nexus, upa_driver, upa_devclass, 0, 0);
+EARLY_DRIVER_MODULE(upa, nexus, upa_driver, upa_devclass, 0, 0, BUS_PASS_BUS);
 
 static const struct intr_controller upa_ic = {
 	upa_intr_enable,

From b61d79e43e04064c3c029c3d5e8605a946a9038d Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 20:05:32 +0000
Subject: [PATCH 1099/2592] MFC: r200876

Make these constants unsigned which is more appropriate.
---
 sys/sparc64/include/bus_common.h | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/sys/sparc64/include/bus_common.h b/sys/sparc64/include/bus_common.h
index e2ea4e9984b..3d70427b28f 100644
--- a/sys/sparc64/include/bus_common.h
+++ b/sys/sparc64/include/bus_common.h
@@ -39,18 +39,18 @@
 #ifndef _MACHINE_BUS_COMMON_H_
 #define	_MACHINE_BUS_COMMON_H_
 
-#define	INTMAP_V		0x080000000LL	/* Interrupt valid (enabled) */
-#define	INTMAP_TID_MASK		0x07c000000LL	/* UPA target ID */
+#define	INTMAP_V		0x080000000ULL	/* Interrupt valid (enabled) */
+#define	INTMAP_TID_MASK		0x07c000000ULL	/* UPA target ID */
 #define	INTMAP_TID_SHIFT	26
-#define	INTMAP_IGN_MASK		0x0000007c0LL	/* Interrupt group no. */
+#define	INTMAP_IGN_MASK		0x0000007c0ULL	/* Interrupt group no. */
 #define	INTMAP_IGN_SHIFT	6
-#define	INTMAP_INO_MASK		0x00000003fLL	/* Interrupt number */
+#define	INTMAP_INO_MASK		0x00000003fULL	/* Interrupt number */
 #define	INTMAP_INR_MASK		(INTMAP_IGN_MASK | INTMAP_INO_MASK)
-#define	INTMAP_SBUSSLOT_MASK	0x000000018LL	/* SBus slot # */
-#define	INTMAP_PCIBUS_MASK	0x000000010LL	/* PCI bus number (A or B) */
-#define	INTMAP_PCISLOT_MASK	0x00000000cLL	/* PCI slot # */
-#define	INTMAP_PCIINT_MASK	0x000000003LL	/* PCI interrupt #A,#B,#C,#D */
-#define	INTMAP_OBIO_MASK	0x000000020LL	/* Onboard device */
+#define	INTMAP_SBUSSLOT_MASK	0x000000018ULL	/* SBus slot # */
+#define	INTMAP_PCIBUS_MASK	0x000000010ULL	/* PCI bus number (A or B) */
+#define	INTMAP_PCISLOT_MASK	0x00000000cULL	/* PCI slot # */
+#define	INTMAP_PCIINT_MASK	0x000000003ULL	/* PCI interrupt #A,#B,#C,#D */
+#define	INTMAP_OBIO_MASK	0x000000020ULL	/* Onboard device */
 #define	INTIGN(x)		(((x) & INTMAP_IGN_MASK) >> INTMAP_IGN_SHIFT)
 #define	INTVEC(x)		((x) & INTMAP_INR_MASK)
 #define	INTSLOT(x)		(((x) >> 3) & 0x7)

From 4acf9b45482b98a844a1396e90d059e2537e2262 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 20:07:45 +0000
Subject: [PATCH 1100/2592] MFC: r200878

- Add macros for the states of the interrupt clear registers.
- Change INTMAP_VEC() to take an INO as its second argument rather
  than an INR. The former is what I actually intended with this
  macro and how it's currently used.
---
 sys/sparc64/include/bus_common.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/sys/sparc64/include/bus_common.h b/sys/sparc64/include/bus_common.h
index 3d70427b28f..f04eb7f5b4c 100644
--- a/sys/sparc64/include/bus_common.h
+++ b/sys/sparc64/include/bus_common.h
@@ -39,6 +39,10 @@
 #ifndef _MACHINE_BUS_COMMON_H_
 #define	_MACHINE_BUS_COMMON_H_
 
+#define	INTCLR_PENDING		0x000000003ULL	/* Interrupt queued to CPU */
+#define	INTCLR_RECEIVED		0x000000001ULL	/* Interrupt received */
+#define	INTCLR_IDLE		0x000000000ULL	/* Interrupt idle */
+
 #define	INTMAP_V		0x080000000ULL	/* Interrupt valid (enabled) */
 #define	INTMAP_TID_MASK		0x07c000000ULL	/* UPA target ID */
 #define	INTMAP_TID_SHIFT	26
@@ -60,9 +64,9 @@
 	(INTMAP_TID((mr), (mid)) | INTMAP_V)
 #define	INTMAP_TID(mr, mid)						\
 	(((mr) & ~INTMAP_TID_MASK) | ((mid) << INTMAP_TID_SHIFT))
-#define	INTMAP_VEC(ign, inr)						\
+#define	INTMAP_VEC(ign, ino)						\
 	((((ign) << INTMAP_IGN_SHIFT) & INTMAP_IGN_MASK) |		\
-	((inr) & INTMAP_INR_MASK))
+	((ino) & INTMAP_INO_MASK))
 
 /* counter-timer support. */
 void sparc64_counter_init(const char *name, bus_space_tag_t tag,

From 990824aa76c1b0646a236094c8f5ea155b8e93a4 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 20:32:54 +0000
Subject: [PATCH 1101/2592] MFC: r200879

- Add support for the JBus to EBus bridges which hang off of nexus(4)
  and are found in sun4u and sun4v machines based on the Fire ASIC.
- Initialize the configuration space of the PCI to EBus variant the
  same way as OpenSolaris does.
---
 sys/sparc64/ebus/ebus.c | 411 ++++++++++++++++++++++++++++++----------
 1 file changed, 308 insertions(+), 103 deletions(-)

diff --git a/sys/sparc64/ebus/ebus.c b/sys/sparc64/ebus/ebus.c
index a3e6d582780..124eebb8204 100644
--- a/sys/sparc64/ebus/ebus.c
+++ b/sys/sparc64/ebus/ebus.c
@@ -1,6 +1,7 @@
 /*-
  * Copyright (c) 1999, 2000 Matthew R. Green
  * Copyright (c) 2001 Thomas Moestl 
+ * Copyright (c) 2009 by Marius Strobl 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +34,7 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * UltraSPARC 5 and beyond EBus support
+ * Driver for JBus to EBus and PCI to EBus bridges
  */
 
 #include 
@@ -43,14 +44,17 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
-#include 
-
 #include 
 
 #include 
 #include 
 #include 
 
+#include 
+#ifndef SUN4V
+#include 
+#endif
+#include 
 #include 
 
 #include 
@@ -59,11 +63,19 @@ __FBSDID("$FreeBSD$");
 #include 
 
 /*
- * The register, ranges and interrupt map properties are identical to the ISA
- * ones.
+ * The register, interrupt map and for the PCI variant also the ranges
+ * properties are identical to the ISA ones.
  */
 #include 
 
+struct ebus_nexus_ranges {
+	uint32_t	child_hi;
+	uint32_t	child_lo;
+	uint32_t	phys_hi;
+	uint32_t	phys_lo;
+	uint32_t	size;
+};
+
 struct ebus_devinfo {
 	struct ofw_bus_devinfo	edi_obdinfo;
 	struct resource_list	edi_rl;
@@ -76,32 +88,92 @@ struct ebus_rinfo {
 };
 
 struct ebus_softc {
-	struct isa_ranges	*sc_range;
+	void			*sc_range;
 	struct ebus_rinfo	*sc_rinfo;
 
+	u_int			sc_flags;
+#define	EBUS_PCI		(1 << 0)
+
 	int			sc_nrange;
 
 	struct ofw_bus_iinfo	sc_iinfo;
+
+#ifndef SUN4V
+	uint32_t		sc_ign;
+#endif
 };
 
-static device_probe_t ebus_probe;
-static device_attach_t ebus_attach;
+static device_probe_t ebus_nexus_probe;
+static device_attach_t ebus_nexus_attach;
+static device_probe_t ebus_pci_probe;
+static device_attach_t ebus_pci_attach;
 static bus_print_child_t ebus_print_child;
 static bus_probe_nomatch_t ebus_probe_nomatch;
 static bus_alloc_resource_t ebus_alloc_resource;
 static bus_release_resource_t ebus_release_resource;
+static bus_setup_intr_t ebus_setup_intr;
 static bus_get_resource_list_t ebus_get_resource_list;
 static ofw_bus_get_devinfo_t ebus_get_devinfo;
 
-static struct ebus_devinfo *ebus_setup_dinfo(device_t, struct ebus_softc *,
-    phandle_t);
-static void ebus_destroy_dinfo(struct ebus_devinfo *);
-static int ebus_print_res(struct ebus_devinfo *);
+static int ebus_attach(device_t dev, struct ebus_softc *sc, phandle_t node);
+static struct ebus_devinfo *ebus_setup_dinfo(device_t dev,
+    struct ebus_softc *sc, phandle_t node);
+static void ebus_destroy_dinfo(struct ebus_devinfo *edi);
+static int ebus_print_res(struct ebus_devinfo *edi);
 
-static device_method_t ebus_methods[] = {
+static devclass_t ebus_devclass;
+
+static device_method_t ebus_nexus_methods[] = {
 	/* Device interface */
-	DEVMETHOD(device_probe,		ebus_probe),
-	DEVMETHOD(device_attach,	ebus_attach),
+	DEVMETHOD(device_probe,		ebus_nexus_probe),
+	DEVMETHOD(device_attach,	ebus_nexus_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	ebus_print_child),
+	DEVMETHOD(bus_probe_nomatch,	ebus_probe_nomatch),
+	DEVMETHOD(bus_alloc_resource,	ebus_alloc_resource),
+	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_release_resource,	ebus_release_resource),
+	DEVMETHOD(bus_setup_intr,	ebus_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_get_resource_list, ebus_get_resource_list),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	ebus_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	KOBJMETHOD_END
+};
+
+static driver_t ebus_nexus_driver = {
+	"ebus",
+	ebus_nexus_methods,
+	sizeof(struct ebus_softc),
+};
+
+/*
+ * NB: we rely on the interrupt controllers of the accompanying PCI-Express
+ * bridge to be registered as the nexus variant of the EBus bridges doesn't
+ * employ its own one.
+ */
+EARLY_DRIVER_MODULE(ebus, nexus, ebus_nexus_driver, ebus_devclass, 0, 0,
+    BUS_PASS_BUS + 1);
+MODULE_DEPEND(ebus, nexus, 1, 1, 1);
+
+static device_method_t ebus_pci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ebus_pci_probe),
+	DEVMETHOD(device_attach,	ebus_pci_attach),
 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
 	DEVMETHOD(device_suspend,	bus_generic_suspend),
 	DEVMETHOD(device_resume,	bus_generic_resume),
@@ -130,21 +202,33 @@ static device_method_t ebus_methods[] = {
 	KOBJMETHOD_END
 };
 
-static driver_t ebus_driver = {
+static driver_t ebus_pci_driver = {
 	"ebus",
-	ebus_methods,
+	ebus_pci_methods,
 	sizeof(struct ebus_softc),
 };
 
-static devclass_t ebus_devclass;
-
-EARLY_DRIVER_MODULE(ebus, pci, ebus_driver, ebus_devclass, 0, 0,
+EARLY_DRIVER_MODULE(ebus, pci, ebus_pci_driver, ebus_devclass, 0, 0,
     BUS_PASS_BUS);
 MODULE_DEPEND(ebus, pci, 1, 1, 1);
 MODULE_VERSION(ebus, 1);
 
 static int
-ebus_probe(device_t dev)
+ebus_nexus_probe(device_t dev)
+{
+	const char* compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat != NULL && strcmp(ofw_bus_get_name(dev), "ebus") == 0 &&
+	    strcmp(compat, "jbus-ebus") == 0) {
+		device_set_desc(dev, "JBus-EBus bridge");
+		return (BUS_PROBE_GENERIC);
+	}
+	return (ENXIO);
+}
+
+static int
+ebus_pci_probe(device_t dev)
 {
 
 	if (pci_get_class(dev) != PCIC_BRIDGE ||
@@ -158,27 +242,58 @@ ebus_probe(device_t dev)
 		device_set_desc(dev, "PCI-EBus3 bridge");
 	else
 		return (ENXIO);
-	return (0);
+	return (BUS_PROBE_GENERIC);
 }
 
 static int
-ebus_attach(device_t dev)
+ebus_nexus_attach(device_t dev)
+{
+	struct ebus_softc *sc;
+	phandle_t node;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+
+#ifndef SUN4V
+	if (OF_getprop(node, "portid", &sc->sc_ign,
+	    sizeof(sc->sc_ign)) == -1) {
+		device_printf(dev, "could not determine IGN");
+		return (ENXIO);
+	}
+#endif
+
+	sc->sc_nrange = OF_getprop_alloc(node, "ranges",
+	    sizeof(struct ebus_nexus_ranges), &sc->sc_range);
+	if (sc->sc_nrange == -1) {
+		printf("%s: could not get ranges property\n", __func__);
+		return (ENXIO);
+	}
+	return (ebus_attach(dev, sc, node));
+}
+
+static int
+ebus_pci_attach(device_t dev)
 {
 	struct ebus_softc *sc;
-	struct ebus_devinfo *edi;
 	struct ebus_rinfo *eri;
 	struct resource *res;
-	device_t cdev;
 	phandle_t node;
 	int i, rnum, rid;
 
 	sc = device_get_softc(dev);
+	sc->sc_flags |= EBUS_PCI;
+
+	pci_write_config(dev, PCIR_COMMAND,
+	    pci_read_config(dev, PCIR_COMMAND, 2) | PCIM_CMD_SERRESPEN |
+	    PCIM_CMD_PERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN, 2);
+	pci_write_config(dev, PCIR_CACHELNSZ, 16 /* 64 bytes */, 1);
+	pci_write_config(dev, PCIR_LATTIMER, 64 /* 64 PCI cycles */, 1);
 
 	node = ofw_bus_get_node(dev);
 	sc->sc_nrange = OF_getprop_alloc(node, "ranges",
-	    sizeof(*sc->sc_range), (void **)&sc->sc_range);
+	    sizeof(struct isa_ranges), &sc->sc_range);
 	if (sc->sc_nrange == -1) {
-		printf("ebus_attach: could not get ranges property\n");
+		printf("%s: could not get ranges property\n", __func__);
 		return (ENXIO);
 	}
 
@@ -188,29 +303,52 @@ ebus_attach(device_t dev)
 	/* For every range, there must be a matching resource. */
 	for (rnum = 0; rnum < sc->sc_nrange; rnum++) {
 		eri = &sc->sc_rinfo[rnum];
-		eri->eri_rtype = ofw_isa_range_restype(&sc->sc_range[rnum]);
+		eri->eri_rtype = ofw_isa_range_restype(
+		    &((struct isa_ranges *)sc->sc_range)[rnum]);
 		rid = PCIR_BAR(rnum);
 		res = bus_alloc_resource_any(dev, eri->eri_rtype, &rid,
 		    RF_ACTIVE);
 		if (res == NULL) {
-			printf("ebus_attach: failed to allocate range "
-			    "resource!\n");
+			printf("%s: failed to allocate range resource!\n",
+			    __func__);
 			goto fail;
 		}
 		eri->eri_res = res;
 		eri->eri_rman.rm_type = RMAN_ARRAY;
 		eri->eri_rman.rm_descr = "EBus range";
 		if (rman_init(&eri->eri_rman) != 0) {
-			printf("ebus_attach: failed to initialize rman!");
+			printf("%s: failed to initialize rman!", __func__);
 			goto fail;
 		}
 		if (rman_manage_region(&eri->eri_rman, rman_get_start(res),
 		    rman_get_end(res)) != 0) {
-			printf("ebus_attach: failed to register region!");
+			printf("%s: failed to register region!", __func__);
 			rman_fini(&eri->eri_rman);
 			goto fail;
 		}
 	}
+	return (ebus_attach(dev, sc, node));
+
+ fail:
+	for (i = rnum; i >= 0; i--) {
+		eri = &sc->sc_rinfo[i];
+		if (i < rnum)
+			rman_fini(&eri->eri_rman);
+		if (eri->eri_res != 0) {
+			bus_release_resource(dev, eri->eri_rtype,
+			    PCIR_BAR(rnum), eri->eri_res);
+		}
+	}
+	free(sc->sc_rinfo, M_DEVBUF);
+	free(sc->sc_range, M_OFWPROP);
+	return (ENXIO);
+}
+
+static int
+ebus_attach(device_t dev, struct ebus_softc *sc, phandle_t node)
+{
+	struct ebus_devinfo *edi;
+	device_t cdev;
 
 	ofw_bus_setup_iinfo(node, &sc->sc_iinfo, sizeof(ofw_isa_intr_t));
 
@@ -229,20 +367,6 @@ ebus_attach(device_t dev)
 		device_set_ivars(cdev, edi);
 	}
 	return (bus_generic_attach(dev));
-
-fail:
-	for (i = rnum; i >= 0; i--) {
-		eri = &sc->sc_rinfo[i];
-		if (i < rnum)
-			rman_fini(&eri->eri_rman);
-		if (eri->eri_res != 0) {
-			bus_release_resource(dev, eri->eri_rtype,
-			    PCIR_BAR(rnum), eri->eri_res);
-		}
-	}
-	free(sc->sc_rinfo, M_DEVBUF);
-	free(sc->sc_range, M_OFWPROP);
-	return (ENXIO);
 }
 
 static int
@@ -274,28 +398,26 @@ ebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
 	struct resource_list_entry *rle = NULL;
 	struct resource *res;
 	struct ebus_rinfo *ri;
+	struct ebus_nexus_ranges *enr;
 	bus_space_tag_t bt;
 	bus_space_handle_t bh;
-	int passthrough = (device_get_parent(child) != bus);
-	int isdefault = (start == 0UL && end == ~0UL);
-	int ridx, rv;
+	uint64_t cend, cstart, offset;
+	int i, isdefault, passthrough, ridx, rv;
 
-	sc = (struct ebus_softc *)device_get_softc(bus);
+	isdefault = (start == 0UL && end == ~0UL);
+	passthrough = (device_get_parent(child) != bus);
+	sc = device_get_softc(bus);
 	rl = BUS_GET_RESOURCE_LIST(bus, child);
-	/*
-	 * Map EBus ranges to PCI ranges.  This may include changing the
-	 * allocation type.
-	 */
 	switch (type) {
 	case SYS_RES_MEMORY:
 		KASSERT(!(isdefault && passthrough),
-		    ("ebus_alloc_resource: passthrough of default alloc"));
+		    ("%s: passthrough of default allocation", __func__));
 		if (!passthrough) {
 			rle = resource_list_find(rl, type, *rid);
 			if (rle == NULL)
 				return (NULL);
 			KASSERT(rle->res == NULL,
-			    ("ebus_alloc_resource: resource entry is busy"));
+			    ("%s: resource entry is busy", __func__));
 			if (isdefault) {
 				start = rle->start;
 				count = ulmax(count, rle->count);
@@ -303,25 +425,53 @@ ebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
 			}
 		}
 
-		(void)ofw_isa_range_map(sc->sc_range, sc->sc_nrange,
-		    &start, &end, &ridx);
+		res = NULL;
+		if ((sc->sc_flags & EBUS_PCI) != 0) {
+			/*
+			 * Map EBus ranges to PCI ranges.  This may include
+			 * changing the allocation type.
+			 */
+			(void)ofw_isa_range_map(sc->sc_range, sc->sc_nrange,
+			    &start, &end, &ridx);
+			ri = &sc->sc_rinfo[ridx];
+			res = rman_reserve_resource(&ri->eri_rman, start, end,
+			    count, flags, child);
+			if (res == NULL)
+				return (NULL);
+			rman_set_rid(res, *rid);
+			bt = rman_get_bustag(ri->eri_res);
+			rman_set_bustag(res, bt);
+			rv = bus_space_subregion(bt,
+			    rman_get_bushandle(ri->eri_res),
+			    rman_get_start(res) - rman_get_start(ri->eri_res),
+			    count, &bh);
+			if (rv != 0) {
+				rman_release_resource(res);
+				return (NULL);
+			}
+			rman_set_bushandle(res, bh);
+		} else {
+			/* Map EBus ranges to nexus ranges. */
+			for (i = 0; i < sc->sc_nrange; i++) {
+				enr = &((struct ebus_nexus_ranges *)
+				    sc->sc_range)[i];
+				cstart = (((uint64_t)enr->child_hi) << 32) |
+				    enr->child_lo;
+				cend = cstart + enr->size - 1;
+				if (start >= cstart && end <= cend) {
+					offset =
+					    (((uint64_t)enr->phys_hi) << 32) |
+					    enr->phys_lo;
+					start += offset - cstart;
+					end += offset - cstart;
+					res = bus_generic_alloc_resource(bus,
+					    child, type, rid, start, end,
+					    count, flags);
+					break;
+				}
+			}
 
-		ri = &sc->sc_rinfo[ridx];
-		res = rman_reserve_resource(&ri->eri_rman, start, end, count,
-		    flags, child);
-		if (res == NULL)
-			return (NULL);
-		rman_set_rid(res, *rid);
-		bt = rman_get_bustag(ri->eri_res);
-		rman_set_bustag(res, bt);
-		rv = bus_space_subregion(bt, rman_get_bushandle(ri->eri_res),
-		    rman_get_start(res) - rman_get_start(ri->eri_res), count,
-		    &bh);
-		if (rv != 0) {
-			rman_release_resource(res);
-			return (NULL);
 		}
-		rman_set_bushandle(res, bh);
 		if (!passthrough)
 			rle->res = res;
 		return (res);
@@ -336,34 +486,77 @@ static int
 ebus_release_resource(device_t bus, device_t child, int type, int rid,
     struct resource *res)
 {
+	struct ebus_softc *sc;
 	struct resource_list *rl;
 	struct resource_list_entry *rle;
-	int passthrough = (device_get_parent(child) != bus);
-	int rv;
+	int passthrough, rv;
 
+	passthrough = (device_get_parent(child) != bus);
 	rl = BUS_GET_RESOURCE_LIST(bus, child);
 	switch (type) {
 	case SYS_RES_MEMORY:
+		sc = device_get_softc(bus);
+		if ((sc->sc_flags & EBUS_PCI) == 0)
+			return (resource_list_release(rl, bus, child, type,
+			    rid, res));
 		if ((rv = rman_release_resource(res)) != 0)
 			return (rv);
 		if (!passthrough) {
 			rle = resource_list_find(rl, type, rid);
-			KASSERT(rle != NULL, ("ebus_release_resource: "
-			    "resource entry not found!"));
-			KASSERT(rle->res != NULL, ("ebus_alloc_resource: "
-			    "resource entry is not busy"));
+			KASSERT(rle != NULL,
+			    ("%s: resource entry not found!", __func__));
+			KASSERT(rle->res != NULL,
+			   ("%s: resource entry is not busy", __func__));
 			rle->res = NULL;
 		}
 		break;
 	case SYS_RES_IRQ:
 		return (resource_list_release(rl, bus, child, type, rid, res));
 	default:
-		panic("ebus_release_resource: unsupported resource type %d",
-		    type);
+		panic("%s: unsupported resource type %d", __func__, type);
 	}
 	return (0);
 }
 
+static int
+ebus_setup_intr(device_t dev, device_t child, struct resource *ires,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+#ifndef SUN4V
+	struct ebus_softc *sc;
+	u_long vec;
+
+	sc = device_get_softc(dev);
+	if ((sc->sc_flags & EBUS_PCI) == 0) {
+		/*
+		 * Make sure the vector is fully specified.  This isn't
+		 * necessarily the case with the PCI variant.
+		 */
+		vec = rman_get_start(ires);
+		if (INTIGN(vec) != sc->sc_ign) {
+			device_printf(dev,
+			    "invalid interrupt vector 0x%lx\n", vec);
+			return (EINVAL);
+		}
+
+		/*
+		 * As we rely on the interrupt controllers of the
+		 * accompanying PCI-Express bridge ensure at least
+		 * something is registered for this vector.
+		 */
+		if (intr_vectors[vec].iv_ic == NULL) {
+			device_printf(dev,
+			    "invalid interrupt controller for vector 0x%lx\n",
+			    vec);
+			return (EINVAL);
+		}
+	}
+#endif
+	return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
+	    arg, cookiep));
+}
+
 static struct resource_list *
 ebus_get_resource_list(device_t dev, device_t child)
 {
@@ -385,12 +578,13 @@ ebus_get_devinfo(device_t bus, device_t dev)
 static struct ebus_devinfo *
 ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node)
 {
+	struct isa_regs reg, *regs;
+	ofw_isa_intr_t intr, *intrs;
 	struct ebus_devinfo *edi;
-	struct isa_regs *reg;
-	ofw_isa_intr_t *intrs;
-	ofw_pci_intr_t rintr;
-	u_int64_t start;
-	int nreg, nintr, i;
+	uint64_t start;
+	uint32_t rintr;
+	int i, nintr, nreg, rv;
+	uint8_t maskbuf[sizeof(reg) + sizeof(intr)];
 
 	edi = malloc(sizeof(*edi), M_DEVBUF, M_ZERO | M_WAITOK);
 	if (ofw_bus_gen_setup_devinfo(&edi->edi_obdinfo, node) != 0) {
@@ -398,40 +592,51 @@ ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node)
 		return (NULL);
 	}
 	resource_list_init(&edi->edi_rl);
-	nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)®);
+	nreg = OF_getprop_alloc(node, "reg", sizeof(*regs), (void **)®s);
 	if (nreg == -1) {
 		device_printf(dev, "<%s>: incomplete\n",
 		    edi->edi_obdinfo.obd_name);
-		goto fail;
+		ebus_destroy_dinfo(edi);
+		return (NULL);
 	}
 	for (i = 0; i < nreg; i++) {
-		start = ISA_REG_PHYS(reg + i);
-		resource_list_add(&edi->edi_rl, SYS_RES_MEMORY, i,
-		    start, start + reg[i].size - 1, reg[i].size);
+		start = ISA_REG_PHYS(regs + i);
+		(void)resource_list_add(&edi->edi_rl, SYS_RES_MEMORY, i,
+		    start, start + regs[i].size - 1, regs[i].size);
 	}
-	free(reg, M_OFWPROP);
+	free(regs, M_OFWPROP);
 
 	nintr = OF_getprop_alloc(node, "interrupts",  sizeof(*intrs),
 	    (void **)&intrs);
+	if (nintr == -1)
+		return (edi);
 	for (i = 0; i < nintr; i++) {
-		rintr = ofw_isa_route_intr(dev, node, &sc->sc_iinfo, intrs[i]);
-		if (rintr == PCI_INVALID_IRQ) {
+		rv = 0;
+		if ((sc->sc_flags & EBUS_PCI) != 0) {
+			rintr = ofw_isa_route_intr(dev, node, &sc->sc_iinfo,
+			    intrs[i]);
+		} else {
+			intr = intrs[i];
+			rv = ofw_bus_lookup_imap(node, &sc->sc_iinfo, ®,
+			    sizeof(reg), &intr, sizeof(intr), &rintr,
+			    sizeof(rintr), maskbuf);
+#ifndef SUN4V
+			if (rv != 0)
+				rintr = INTMAP_VEC(sc->sc_ign, rintr);
+#endif
+		}
+		if ((sc->sc_flags & EBUS_PCI) == 0 ? rv == 0 :
+		    rintr == PCI_INVALID_IRQ) {
 			device_printf(dev,
 			    "<%s>: could not map EBus interrupt %d\n",
 			    edi->edi_obdinfo.obd_name, intrs[i]);
-			free(intrs, M_OFWPROP);
-			goto fail;
+			continue;
 		}
-		resource_list_add(&edi->edi_rl, SYS_RES_IRQ, i,
-		    rintr, rintr, 1);
+		(void)resource_list_add(&edi->edi_rl, SYS_RES_IRQ, i, rintr,
+		    rintr, 1);
 	}
 	free(intrs, M_OFWPROP);
-
 	return (edi);
-
-fail:
-	ebus_destroy_dinfo(edi);
-	return (NULL);
 }
 
 static void

From 96642ec4ae54d27e6605bd09db90be68da60cac7 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 20:35:27 +0000
Subject: [PATCH 1102/2592] MFC: r200880

- Correct an off-by-one error when calculating the end of a child
  range.
- Spell the PCI TLA in uppercase.
---
 sys/sparc64/isa/ofw_isa.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/sparc64/isa/ofw_isa.c b/sys/sparc64/isa/ofw_isa.c
index de5e4cecd38..6139ba7a059 100644
--- a/sys/sparc64/isa/ofw_isa.c
+++ b/sys/sparc64/isa/ofw_isa.c
@@ -79,11 +79,11 @@ ofw_isa_range_map(struct isa_ranges *range, int nrange, u_long *start,
 	for (i = 0; i < nrange; i++) {
 		r = &range[i];
 		cstart = ISA_RANGE_CHILD(r);
-		cend = cstart + r->size;
+		cend = cstart + r->size - 1;
 		if (*start < cstart || *start > cend)
 			continue;
 		if (*end < cstart || *end > cend) {
-			panic("ofw_isa_map_iorange: iorange crosses pci "
+			panic("ofw_isa_map_iorange: iorange crosses PCI "
 			    "ranges (%#lx not in %#lx - %#lx)", *end, cstart,
 			    cend);
 		}

From f71a779bb74568bd2037089e9a4a828075d06842 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 20:40:49 +0000
Subject: [PATCH 1103/2592] MFC: r200914

Don't use an out register to hold the vector number across the call
of the interrupt handler in intr_fast() as the handler might clobber
it (no in-tree handler currently does but an upcoming one will).
While at it, tidy the register usage in the interrupt counting code.
---
 sys/sparc64/sparc64/interrupt.S | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/sys/sparc64/sparc64/interrupt.S b/sys/sparc64/sparc64/interrupt.S
index ca4456faa4c..75a97275301 100644
--- a/sys/sparc64/sparc64/interrupt.S
+++ b/sys/sparc64/sparc64/interrupt.S
@@ -176,7 +176,7 @@ ENTRY(intr_fast)
 
 3:	ldx	[%l0 + IR_FUNC], %o0
 	ldx	[%l0 + IR_ARG], %o1
-	lduw	[%l0 + IR_VEC], %o2
+	lduw	[%l0 + IR_VEC], %l2
 
 	ldx	[PCPU(IRFREE)], %l1
 	stx	%l1, [%l0 + IR_NEXT]
@@ -188,17 +188,17 @@ ENTRY(intr_fast)
 	call	%o0
 	 mov	%o1, %o0
 
-	/* intrcnt[intr_countp[%o2]]++ */
-	SET(intrcnt, %l7, %l2)		/* %l2 = intrcnt */
-	prefetcha [%l2] ASI_N, 1
-	SET(intr_countp, %l7, %l3)	/* %l3 = intr_countp */
-	sllx	%o2, 1, %l4		/* %l4 = vec << 1 */
-	lduh	[%l4 + %l3], %l5	/* %l5 = intr_countp[%o2] */
-	sllx	%l5, 3, %l6		/* %l6 = intr_countp[%o2] << 3 */
-	add	%l6, %l2, %l7		/* %l7 = intrcnt[intr_countp[%o2]] */
-	ldx	[%l7], %l2
+	/* intrcnt[intr_countp[%l2]]++ */
+	SET(intrcnt, %l7, %l3)		/* %l3 = intrcnt */
+	prefetcha [%l3] ASI_N, 1
+	SET(intr_countp, %l7, %l4)	/* %l4 = intr_countp */
+	sllx	%l2, 1, %l2		/* %l2 = vec << 1 */
+	lduh	[%l4 + %l2], %l4	/* %l4 = intr_countp[%l2] */
+	sllx	%l4, 3, %l4		/* %l4 = intr_countp[%l2] << 3 */
+	add	%l4, %l3, %l4		/* %l4 = intrcnt[intr_countp[%l2]] */
+	ldx	[%l4], %l2
 	inc	%l2
-	stx	%l2, [%l7]
+	stx	%l2, [%l4]
 
 	ba,a	%xcc, 1b
 	 nop

From 4cb21bdfca96964ce8560e4fcfa1947b2e63f43e Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 20:51:21 +0000
Subject: [PATCH 1104/2592] MFC: r200915

Don't probe the bq4802 variant found in Ultra 25 and 45 for now as
this chip isn't MC146818 compatible and requires different handlers
(but which I can't test due to lack of such hardware).
---
 sys/sparc64/sparc64/rtc.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/sys/sparc64/sparc64/rtc.c b/sys/sparc64/sparc64/rtc.c
index 5bd196b25ef..7d9e1295e83 100644
--- a/sys/sparc64/sparc64/rtc.c
+++ b/sys/sparc64/sparc64/rtc.c
@@ -28,10 +28,11 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * The `rtc' device is a MC146818 compatible clock found on the ISA
- * bus and EBus. The EBus variant actually is the Real-Time Clock
- * function of a National Semiconductor PC87317/PC97317 which also
- * provides Advanced Power Control functionality.
+ * The `rtc' device is found on the ISA bus and the EBus.  The ISA version
+ * always is a MC146818 compatible clock while the EBus variant either is the
+ * MC146818 compatible Real-Time Clock function of a National Semiconductor
+ * PC87317/PC97317 which also provides Advanced Power Control functionality
+ * or a Texas Instruments bq4802.
  */
 
 #include "opt_isa.h"
@@ -130,6 +131,10 @@ rtc_ebus_probe(device_t dev)
 {
 
 	if (strcmp(ofw_bus_get_name(dev), "rtc") == 0) {
+		/* The bq4802 is not supported, yet. */
+		if (ofw_bus_get_compat(dev) != NULL &&
+		    strcmp(ofw_bus_get_compat(dev), "bq4802") == 0)
+			return (ENXIO);
 		device_set_desc(dev, RTC_DESC);
 		return (0);
 	}

From 7d0ba636c63b0a0e944f7be428d71493f9142971 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 20:59:36 +0000
Subject: [PATCH 1105/2592] MFC: r200916

Remove devices which are/were only relevant for sun4u.
---
 sys/sun4v/conf/NOTES | 19 -------------------
 1 file changed, 19 deletions(-)

diff --git a/sys/sun4v/conf/NOTES b/sys/sun4v/conf/NOTES
index a773e5cffd6..b6925417b0f 100644
--- a/sys/sun4v/conf/NOTES
+++ b/sys/sun4v/conf/NOTES
@@ -21,37 +21,18 @@ cpu		SUN4V
 device		ebus
 #device		isa
 device		pci
-device		sbus
-#device		central
-device		fhc
 
 
 #####################################################################
 # HARDWARE DEVICE CONFIGURATION
 
-#
-# Mandatory devices:
-#
-
-#device		eeprom		# eeprom (really a front-end for the MK48Txx)
-device		mk48txx		# Mostek MK48Txx clocks
-#device		rtc		# rtc (really a front-end for the MC146818)
-device		mc146818	# Motorola MC146818 and compatible clocks
-
 #
 # Optional devices:
 #
 
-#device		auxio		# auxiliary I/O device
-#device		clkbrd		# Clock Board (blinkenlight on Sun Exx00)
-#device		creator		# Creator, Creator3D and Elite3D framebuffers
-#device		machfb		# ATI Mach64 framebuffers
-
 device		ofw_console	# Open Firmware console device
 option 		OFWCONS_POLL_HZ=4 # 20 or more works best on Ultra2
 
-#device		sab		# Siemens SAB82532 based serial ports
-
 
 #####################################################################
 # Devices we don't want to deal with

From f16888057471aa9ee249d8f3b5273b7d170e2d78 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:03:04 +0000
Subject: [PATCH 1106/2592] MFC: r200917

Hook ebus(4) and isa(4) up to the sun4v LINT build in order to
ensure that their compilation doesn't break as they are expected
to work as-is now (but aren't actually run-time tested).
---
 sys/conf/files.sun4v | 4 ++++
 sys/sun4v/conf/NOTES | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/sys/conf/files.sun4v b/sys/conf/files.sun4v
index d83b0a29d29..5964f5659fc 100644
--- a/sys/conf/files.sun4v
+++ b/sys/conf/files.sun4v
@@ -35,6 +35,10 @@ libkern/ffsl.c			standard
 libkern/fls.c			standard
 libkern/flsl.c			standard
 libkern/memmove.c		standard
+sparc64/ebus/ebus.c		optional	ebus
+sparc64/isa/isa.c		optional	isa
+sparc64/isa/isa_dma.c		optional	isa
+sparc64/isa/ofw_isa.c		optional	ebus | isa
 sparc64/sparc64/autoconf.c	standard
 sun4v/sun4v/bus_machdep.c	standard
 sun4v/sun4v/clock.c		standard
diff --git a/sys/sun4v/conf/NOTES b/sys/sun4v/conf/NOTES
index b6925417b0f..b655ae278a6 100644
--- a/sys/sun4v/conf/NOTES
+++ b/sys/sun4v/conf/NOTES
@@ -19,7 +19,7 @@ cpu		SUN4V
 # HARDWARE BUS CONFIGURATION
 
 device		ebus
-#device		isa
+device		isa
 device		pci
 
 

From 778251c8a483c30fb7c565d479c5b209cd51b231 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:04:56 +0000
Subject: [PATCH 1107/2592] MFC: r200918

Add structures for OFW MSI/MSI-X support. These are identical for
both sun4u and sun4v.
---
 sys/sparc64/pci/ofw_pci.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/sys/sparc64/pci/ofw_pci.h b/sys/sparc64/pci/ofw_pci.h
index 3b5059858c1..ad9642014d4 100644
--- a/sys/sparc64/pci/ofw_pci.h
+++ b/sys/sparc64/pci/ofw_pci.h
@@ -48,6 +48,31 @@ typedef uint32_t ofw_pci_intr_t;
 #define	OFW_TYPE_PCI		"pci"
 #define	OFW_TYPE_PCIE		"pciex"
 
+struct ofw_pci_msi_addr_ranges {
+	uint32_t	addr32_hi;
+	uint32_t	addr32_lo;
+	uint32_t	addr32_sz;
+	uint32_t	addr64_hi;
+	uint32_t	addr64_lo;
+	uint32_t	addr64_sz;
+};
+
+#define	OFW_PCI_MSI_ADDR_RANGE_32(r) \
+	(((uint64_t)(r)->addr32_hi << 32) | (uint64_t)(r)->addr32_lo)
+#define	OFW_PCI_MSI_ADDR_RANGE_64(r) \
+	(((uint64_t)(r)->addr64_hi << 32) | (uint64_t)(r)->addr64_lo)
+
+struct ofw_pci_msi_eq_to_devino {
+	uint32_t	eq_first;
+	uint32_t	eq_count;
+	uint32_t	devino_first;
+};
+
+struct ofw_pci_msi_ranges {
+	uint32_t	first;
+	uint32_t	count;
+};
+
 struct ofw_pci_ranges {
 	uint32_t	cspace;
 	uint32_t	child_hi;

From 8677820407133e7e33fc2a7aab223c68d6d4aa04 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:08:57 +0000
Subject: [PATCH 1108/2592] MFC: r200920

- Sort the prototypes.
- Add macros to ease the access of device configuration space in
  ofw_pcibus_setup_device().
---
 sys/sparc64/pci/ofw_pcibus.c | 49 ++++++++++++++++++------------------
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/sys/sparc64/pci/ofw_pcibus.c b/sys/sparc64/pci/ofw_pcibus.c
index 571b6acd32b..ae1cc3718b0 100644
--- a/sys/sparc64/pci/ofw_pcibus.c
+++ b/sys/sparc64/pci/ofw_pcibus.c
@@ -64,11 +64,11 @@ static void ofw_pcibus_setup_device(device_t bridge, uint32_t clock,
     u_int busno, u_int slot, u_int func);
 
 /* Methods */
-static device_probe_t ofw_pcibus_probe;
-static device_attach_t ofw_pcibus_attach;
-static pci_assign_interrupt_t ofw_pcibus_assign_interrupt;
-static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo;
 static bus_child_pnpinfo_str_t ofw_pcibus_pnpinfo_str;
+static device_attach_t ofw_pcibus_attach;
+static device_probe_t ofw_pcibus_probe;
+static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo;
+static pci_assign_interrupt_t ofw_pcibus_assign_interrupt;
 
 static device_method_t ofw_pcibus_methods[] = {
 	/* Device interface */
@@ -124,6 +124,11 @@ static void
 ofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno,
     u_int slot, u_int func)
 {
+#define	CS_READ(n, w)							\
+	PCIB_READ_CONFIG(bridge, busno, slot, func, (n), (w))
+#define	CS_WRITE(n, v, w)						\
+	PCIB_WRITE_CONFIG(bridge, busno, slot, func, (n), (v), (w))
+
 #ifndef SUN4V
 	uint32_t reg;
 
@@ -138,33 +143,27 @@ ofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno,
 	 * For bridges, we additionally set up the bridge control and the
 	 * secondary latency registers.
 	 */
-	if ((PCIB_READ_CONFIG(bridge, busno, slot, func, PCIR_HDRTYPE, 1) &
-	    PCIM_HDRTYPE) == PCIM_HDRTYPE_BRIDGE) {
-		reg = PCIB_READ_CONFIG(bridge, busno, slot, func,
-		    PCIR_BRIDGECTL_1, 1);
+	if ((CS_READ(PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) ==
+	    PCIM_HDRTYPE_BRIDGE) {
+		reg = CS_READ(PCIR_BRIDGECTL_1, 1);
 		reg |= PCIB_BCR_MASTER_ABORT_MODE | PCIB_BCR_SERR_ENABLE |
 		    PCIB_BCR_PERR_ENABLE;
 #ifdef OFW_PCI_DEBUG
 		device_printf(bridge,
 		    "bridge %d/%d/%d: control 0x%x -> 0x%x\n",
-		    busno, slot, func, PCIB_READ_CONFIG(bridge, busno, slot,
-		    func, PCIR_BRIDGECTL_1, 1), reg);
+		    busno, slot, func, CS_READ(PCIR_BRIDGECTL_1, 1), reg);
 #endif /* OFW_PCI_DEBUG */
-		PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_BRIDGECTL_1,
-		    reg, 1);
+		CS_WRITE(PCIR_BRIDGECTL_1, reg, 1);
 
 		reg = OFW_PCI_LATENCY;
 #ifdef OFW_PCI_DEBUG
 		device_printf(bridge,
 		    "bridge %d/%d/%d: latency timer %d -> %d\n",
-		    busno, slot, func, PCIB_READ_CONFIG(bridge, busno, slot,
-		    func, PCIR_SECLAT_1, 1), reg);
+		    busno, slot, func, CS_READ(PCIR_SECLAT_1, 1), reg);
 #endif /* OFW_PCI_DEBUG */
-		PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_SECLAT_1,
-		    reg, 1);
+		CS_WRITE(PCIR_SECLAT_1, reg, 1);
 	} else {
-		reg = PCIB_READ_CONFIG(bridge, busno, slot, func,
-		    PCIR_MINGNT, 1);
+		reg = CS_READ(PCIR_MINGNT, 1);
 		if (reg != 0) {
 			switch (clock) {
 			case 33000000:
@@ -180,10 +179,9 @@ ofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno,
 	}
 #ifdef OFW_PCI_DEBUG
 	device_printf(bridge, "device %d/%d/%d: latency timer %d -> %d\n",
-	    busno, slot, func, PCIB_READ_CONFIG(bridge, busno, slot, func,
-	    PCIR_LATTIMER, 1), reg);
+	    busno, slot, func, CS_READ(PCIR_LATTIMER, 1), reg);
 #endif /* OFW_PCI_DEBUG */
-	PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_LATTIMER, reg, 1);
+	CS_WRITE(PCIR_LATTIMER, reg, 1);
 
 	/*
 	 * Compute a value to write into the cache line size register.
@@ -192,8 +190,7 @@ ofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno,
 	 * reached.  Generally, the cache line size is fixed at 64 bytes
 	 * by Fireplane/Safari, JBus and UPA.
 	 */
-	PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_CACHELNSZ,
-	    STRBUF_LINESZ / sizeof(uint32_t), 1);
+	CS_WRITE(PCIR_CACHELNSZ, STRBUF_LINESZ / sizeof(uint32_t), 1);
 #endif
 
 	/*
@@ -201,8 +198,10 @@ ofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno,
 	 * it to 255, so that the PCI code will reroute the interrupt if
 	 * needed.
 	 */
-	PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_INTLINE,
-	    PCI_INVALID_IRQ, 1);
+	CS_WRITE(PCIR_INTLINE, PCI_INVALID_IRQ, 1);
+
+#undef CS_READ
+#undef CS_WRITE
 }
 
 static int

From bdb2fdd6af408713975b6ebec1a9dc96b49c92ce Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:12:27 +0000
Subject: [PATCH 1109/2592] MFC: r200921

- Add quirk handling for ALi M5229, mainly setting the magic "force
  enable IDE I/O" bit which prevents data access traps with revision
  0xc8 in Fire-based machines when pci(4) enables PCIM_CMD_PORTEN.
- Like for sun4v also don't add the PCI side of host-PCIe bridges to
  the bus on sun4u as they don't have configuration space implement
  there either.
---
 sys/sparc64/pci/ofw_pcibus.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/sys/sparc64/pci/ofw_pcibus.c b/sys/sparc64/pci/ofw_pcibus.c
index ae1cc3718b0..a0a447bbf0c 100644
--- a/sys/sparc64/pci/ofw_pcibus.c
+++ b/sys/sparc64/pci/ofw_pcibus.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2000, Michael Smith 
  * Copyright (c) 2000, BSDi
  * Copyright (c) 2003, Thomas Moestl 
+ * Copyright (c) 2005 - 2009 Marius Strobl 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -193,6 +194,22 @@ ofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno,
 	CS_WRITE(PCIR_CACHELNSZ, STRBUF_LINESZ / sizeof(uint32_t), 1);
 #endif
 
+	/*
+	 * Ensure that ALi M5229 report the actual content of PCIR_PROGIF
+	 * and that IDE I/O is force enabled.  The former is done in order
+	 * to have unique behavior across revisions as some default to
+	 * hiding bits 4-6 for compliance with PCI 2.3.  The latter is done
+	 * as at least revision 0xc8 requires the PCIM_CMD_PORTEN bypass
+	 * to be always enabled as otherwise even enabling PCIM_CMD_PORTEN
+	 * results in an instant data access trap on Fire-based machines.
+	 * Thus these quirks have to be handled before pci(4) adds the maps.
+	 * Note that for older revisions bit 0 of register 0x50 enables the
+	 * internal IDE function instead of force enabling IDE I/O.
+	 */
+	if ((CS_READ(PCIR_VENDOR, 2) == 0x10b9 &&
+	    CS_READ(PCIR_DEVICE, 2) == 0x5229))
+		CS_WRITE(0x50, CS_READ(0x50, 1) | 0x3, 1);
+
 	/*
 	 * The preset in the intline register is usually wrong.  Reset
 	 * it to 255, so that the PCI code will reroute the interrupt if
@@ -222,9 +239,14 @@ ofw_pcibus_attach(device_t dev)
 		    domain, busno);
 	node = ofw_bus_get_node(dev);
 
-#ifndef SUN4V
-	/* Add the PCI side of the HOST-PCI bridge itself to the bus. */
+	/*
+	 * Add the PCI side of the host-PCI bridge itself to the bus.
+	 * Note that we exclude the host-PCIe bridges here as these
+	 * have no configuration space implemented themselves.
+	 */
 	if (strcmp(device_get_name(device_get_parent(pcib)), "nexus") == 0 &&
+	    ofw_bus_get_type(pcib) != NULL &&
+	    strcmp(ofw_bus_get_type(pcib), OFW_TYPE_PCIE) != 0 &&
 	    (dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
 	    domain, busno, 0, 0, sizeof(*dinfo))) != NULL) {
 		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, node) != 0)
@@ -232,7 +254,6 @@ ofw_pcibus_attach(device_t dev)
 		else
 			pci_add_child(dev, (struct pci_devinfo *)dinfo);
 	}
-#endif
 
 	if (OF_getprop(ofw_bus_get_node(pcib), "clock-frequency", &clock,
 	    sizeof(clock)) == -1)

From c05db9b041cd18328b5936fc358c6653ec8e7af3 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:13:50 +0000
Subject: [PATCH 1110/2592] MFC: r200922

Fix whitespace according to style(9).
---
 sys/sparc64/include/iommureg.h | 58 +++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/sys/sparc64/include/iommureg.h b/sys/sparc64/include/iommureg.h
index 6032ac585a6..0665cdea403 100644
--- a/sys/sparc64/include/iommureg.h
+++ b/sys/sparc64/include/iommureg.h
@@ -37,7 +37,7 @@
  */
 
 #ifndef _MACHINE_IOMMUREG_H_
-#define _MACHINE_IOMMUREG_H_
+#define	_MACHINE_IOMMUREG_H_
 
 /*
  * UltraSPARC IOMMU registers, common to both the PCI and SBus
@@ -61,9 +61,9 @@
 #define	ISD_LN_TAG_DIAG	0x0900	/* streaming buffer line tag diag 0..15 */
 
 /* streaming buffer control register */
-#define STRBUF_EN		0x0000000000000001UL
-#define STRBUF_D		0x0000000000000002UL
-#define STRBUF_RR_DIS		0x0000000000000004UL
+#define	STRBUF_EN		0x0000000000000001UL
+#define	STRBUF_D		0x0000000000000002UL
+#define	STRBUF_RR_DIS		0x0000000000000004UL
 
 #define	IOMMU_MAXADDR(bits)	((1UL << (bits)) - 1)
 
@@ -72,24 +72,24 @@
  */
 /* Nummber of entries in IOTSB */
 #define	IOMMUCR_TSBSZ_SHIFT	16
-#define IOMMUCR_TSB1K		0x0000000000000000UL
-#define IOMMUCR_TSB2K		0x0000000000010000UL
-#define IOMMUCR_TSB4K		0x0000000000020000UL
-#define IOMMUCR_TSB8K		0x0000000000030000UL
-#define IOMMUCR_TSB16K		0x0000000000040000UL
-#define IOMMUCR_TSB32K		0x0000000000050000UL
-#define IOMMUCR_TSB64K		0x0000000000060000UL
-#define IOMMUCR_TSB128K		0x0000000000070000UL
+#define	IOMMUCR_TSB1K		0x0000000000000000UL
+#define	IOMMUCR_TSB2K		0x0000000000010000UL
+#define	IOMMUCR_TSB4K		0x0000000000020000UL
+#define	IOMMUCR_TSB8K		0x0000000000030000UL
+#define	IOMMUCR_TSB16K		0x0000000000040000UL
+#define	IOMMUCR_TSB32K		0x0000000000050000UL
+#define	IOMMUCR_TSB64K		0x0000000000060000UL
+#define	IOMMUCR_TSB128K		0x0000000000070000UL
 /* Mask for above */
-#define IOMMUCR_TSBMASK		0xfffffffffff8ffffUL
+#define	IOMMUCR_TSBMASK		0xfffffffffff8ffffUL
 /* 8K iommu page size */
-#define IOMMUCR_8KPG		0x0000000000000000UL
+#define	IOMMUCR_8KPG		0x0000000000000000UL
 /* 64K iommu page size */
-#define IOMMUCR_64KPG		0x0000000000000004UL
+#define	IOMMUCR_64KPG		0x0000000000000004UL
 /* Diag enable */
-#define IOMMUCR_DE		0x0000000000000002UL
+#define	IOMMUCR_DE		0x0000000000000002UL
 /* Enable IOMMU */
-#define IOMMUCR_EN		0x0000000000000001UL
+#define	IOMMUCR_EN		0x0000000000000001UL
 
 /*
  * Diagnostic register definitions
@@ -97,9 +97,9 @@
 #define	IOMMU_DTAG_VPNBITS	19
 #define	IOMMU_DTAG_VPNMASK	((1 << IOMMU_DTAG_VPNBITS) - 1)
 #define	IOMMU_DTAG_VPNSHIFT	13
-#define IOMMU_DTAG_ERRBITS	3
+#define	IOMMU_DTAG_ERRBITS	3
 #define	IOMMU_DTAG_ERRSHIFT	22
-#define	IOMMU_DTAG_ERRMASK \
+#define	IOMMU_DTAG_ERRMASK						\
 	(((1 << IOMMU_DTAG_ERRBITS) - 1) << IOMMU_DTAG_ERRSHIFT)
 
 #define	IOMMU_DDATA_PGBITS	21
@@ -114,18 +114,18 @@
 /* Entry valid */
 #define	IOTTE_V			0x8000000000000000UL
 /* 8K or 64K page? */
-#define IOTTE_64K		0x2000000000000000UL
-#define IOTTE_8K		0x0000000000000000UL
+#define	IOTTE_64K		0x2000000000000000UL
+#define	IOTTE_8K		0x0000000000000000UL
 /* Is page streamable? */
-#define IOTTE_STREAM		0x1000000000000000UL
+#define	IOTTE_STREAM		0x1000000000000000UL
 /* Accesses to same bus segment? */
 #define	IOTTE_LOCAL		0x0800000000000000UL
 /* Let's assume this is correct */
-#define IOTTE_PAMASK		0x000007ffffffe000UL
+#define	IOTTE_PAMASK		0x000007ffffffe000UL
 /* Accesses to cacheable space */
-#define IOTTE_C			0x0000000000000010UL
+#define	IOTTE_C			0x0000000000000010UL
 /* Writeable */
-#define IOTTE_W			0x0000000000000002UL
+#define	IOTTE_W			0x0000000000000002UL
 
 /* log2 of the IOMMU TTE size */
 #define	IOTTE_SHIFT		3
@@ -167,14 +167,14 @@
  */
 
 #define	IOTSB_BASESZ		(1024 << IOTTE_SHIFT)
-#define IOTSB_VEND		(~IO_PAGE_MASK)
-#define IOTSB_VSTART(sz)	(u_int)(IOTSB_VEND << ((sz) + 10))
+#define	IOTSB_VEND		(~IO_PAGE_MASK)
+#define	IOTSB_VSTART(sz)	(u_int)(IOTSB_VEND << ((sz) + 10))
 
-#define MAKEIOTTE(pa,w,c,s)						\
+#define	MAKEIOTTE(pa, w, c, s)						\
 	(((pa) & IOTTE_PAMASK) | ((w) ? IOTTE_W : 0) |			\
 	((c) ? IOTTE_C : 0) | ((s) ? IOTTE_STREAM : 0) |		\
 	(IOTTE_V | IOTTE_8K))
-#define IOTSBSLOT(va)						\
+#define	IOTSBSLOT(va)							\
 	((u_int)(((vm_offset_t)(va)) - (is->is_dvmabase)) >> IO_PAGE_SHIFT)
 
 #endif /* !_MACHINE_IOMMUREG_H_ */

From b740c16a21112acf3d910eadb8db76d6367295a7 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:16:07 +0000
Subject: [PATCH 1111/2592] MFC: r200923

- Add support for the IOMMUs of Fire JBus to PCIe and Oberon Uranus
  to PCIe bridges.
- Add support for talking the PROM mappings over to the kernel IOTSB
  just like we do with the kernel TSB in order to allow OFW drivers
  to continue to work.
- Change some members, parameters and variables to unsigned where
  more appropriate.
---
 sys/sparc64/include/iommureg.h |  76 ++++++++++++++------
 sys/sparc64/include/iommuvar.h |  11 +--
 sys/sparc64/sparc64/iommu.c    | 122 ++++++++++++++++++++++++++++-----
 3 files changed, 166 insertions(+), 43 deletions(-)

diff --git a/sys/sparc64/include/iommureg.h b/sys/sparc64/include/iommureg.h
index 0665cdea403..f4d0349903e 100644
--- a/sys/sparc64/include/iommureg.h
+++ b/sys/sparc64/include/iommureg.h
@@ -44,10 +44,13 @@
  * controllers.
  */
 
-/* iommmu registers */
+/* IOMMU registers */
 #define	IMR_CTL		0x0000	/* IOMMU control register */
 #define	IMR_TSB		0x0008	/* IOMMU TSB base register */
 #define	IMR_FLUSH	0x0010	/* IOMMU flush register */
+/* The TTE Cache is Fire and Oberon only. */
+#define	IMR_CACHE_FLUSH	0x0100	/* IOMMU TTE cache flush address register */
+#define	IMR_CACHE_INVAL	0x0108	/* IOMMU TTE cache invalidate register */
 
 /* streaming buffer registers */
 #define	ISR_CTL		0x0000	/* streaming buffer control reg */
@@ -70,27 +73,56 @@
 /*
  * control register bits
  */
-/* Nummber of entries in IOTSB */
+/* Nummber of entries in the IOTSB - pre-Fire only */
+#define	IOMMUCR_TSBSZ_MASK	0x0000000000070000UL
 #define	IOMMUCR_TSBSZ_SHIFT	16
-#define	IOMMUCR_TSB1K		0x0000000000000000UL
-#define	IOMMUCR_TSB2K		0x0000000000010000UL
-#define	IOMMUCR_TSB4K		0x0000000000020000UL
-#define	IOMMUCR_TSB8K		0x0000000000030000UL
-#define	IOMMUCR_TSB16K		0x0000000000040000UL
-#define	IOMMUCR_TSB32K		0x0000000000050000UL
-#define	IOMMUCR_TSB64K		0x0000000000060000UL
-#define	IOMMUCR_TSB128K		0x0000000000070000UL
-/* Mask for above */
-#define	IOMMUCR_TSBMASK		0xfffffffffff8ffffUL
-/* 8K iommu page size */
+/* TSB cache snoop enable */
+#define	IOMMUCR_SE		0x0000000000000400UL
+/* Cache modes - Fire and Oberon */
+#define	IOMMUCR_CM_NC_TLB_TBW	0x0000000000000000UL
+#define	IOMMUCR_CM_LC_NTLB_NTBW	0x0000000000000100UL
+#define	IOMMUCR_CM_LC_TLB_TBW	0x0000000000000200UL
+#define	IOMMUCR_CM_C_TLB_TBW	0x0000000000000300UL
+/* IOMMU page size - pre-Fire only */
 #define	IOMMUCR_8KPG		0x0000000000000000UL
-/* 64K iommu page size */
 #define	IOMMUCR_64KPG		0x0000000000000004UL
-/* Diag enable */
+/* Bypass enable - Fire and Oberon */
+#define	IOMMUCR_BE		0x0000000000000002UL
+/* Diagnostic mode enable - pre-Fire only */
 #define	IOMMUCR_DE		0x0000000000000002UL
-/* Enable IOMMU */
+/* IOMMU/translation enable */
 #define	IOMMUCR_EN		0x0000000000000001UL
 
+/*
+ * TSB base register bits
+ */
+ /* TSB base address */
+#define	IOMMUTB_TB_MASK		0x000007ffffffe000UL
+#define	IOMMUTB_TB_SHIFT	13
+/* IOMMU page size - Fire and Oberon */
+#define	IOMMUTB_8KPG		0x0000000000000000UL
+#define	IOMMUTB_64KPG		0x0000000000000100UL
+/* Nummber of entries in the IOTSB - Fire and Oberon */
+#define	IOMMUTB_TSBSZ_MASK	0x0000000000000004UL
+#define	IOMMUTB_TSBSZ_SHIFT	0
+
+/*
+ * TSB size definitions for both control and TSB base register */
+#define	IOMMU_TSB1K		0
+#define	IOMMU_TSB2K		1
+#define	IOMMU_TSB4K		2
+#define	IOMMU_TSB8K		3
+#define	IOMMU_TSB16K		4
+#define	IOMMU_TSB32K		5
+#define	IOMMU_TSB64K		6
+#define	IOMMU_TSB128K		7
+/* Fire and Oberon */
+#define	IOMMU_TSB256K		8
+/* Fire and Oberon */
+#define	IOMMU_TSB512K		9
+#define	IOMMU_TSBENTRIES(tsbsz)						\
+	((1 << (tsbsz)) << (IO_PAGE_SHIFT - IOTTE_SHIFT))
+
 /*
  * Diagnostic register definitions
  */
@@ -113,16 +145,16 @@
  */
 /* Entry valid */
 #define	IOTTE_V			0x8000000000000000UL
-/* 8K or 64K page? */
+/* Page size - pre-Fire only */
 #define	IOTTE_64K		0x2000000000000000UL
 #define	IOTTE_8K		0x0000000000000000UL
-/* Is page streamable? */
+/* Streamable page - streaming buffer equipped variants only */
 #define	IOTTE_STREAM		0x1000000000000000UL
-/* Accesses to same bus segment? */
+/* Accesses to the same bus segment - SBus only */
 #define	IOTTE_LOCAL		0x0800000000000000UL
-/* Let's assume this is correct */
-#define	IOTTE_PAMASK		0x000007ffffffe000UL
-/* Accesses to cacheable space */
+/* Physical address mask (based on Oberon) */
+#define	IOTTE_PAMASK		0x00007fffffffe000UL
+/* Accesses to cacheable space - pre-Fire only */
 #define	IOTTE_C			0x0000000000000010UL
 /* Writeable */
 #define	IOTTE_W			0x0000000000000002UL
diff --git a/sys/sparc64/include/iommuvar.h b/sys/sparc64/include/iommuvar.h
index 5904f046a2a..1ef4e0bd0ae 100644
--- a/sys/sparc64/include/iommuvar.h
+++ b/sys/sparc64/include/iommuvar.h
@@ -66,10 +66,10 @@ struct iommu_state {
 	int			is_tsbsize;	/* (r) 0 = 8K, ... */
 	uint64_t		is_pmaxaddr;	/* (r) max. physical address */
 	uint64_t		is_dvmabase;	/* (r) */
-	int64_t			is_cr;		/* (r) Control reg value */
+	uint64_t		is_cr;		/* (r) Control reg value */
 
 	vm_paddr_t		is_flushpa[2];	/* (r) */
-	volatile int64_t	*is_flushva[2];	/* (r, *i) */
+	volatile uint64_t	*is_flushva[2];	/* (r, *i) */
 	/*
 	 * (i)
 	 * When a flush is completed, 64 bytes will be stored at the given
@@ -99,11 +99,14 @@ struct iommu_state {
 	/* behavior flags */
 	u_int			is_flags;	/* (r) */
 #define	IOMMU_RERUN_DISABLE	(1 << 0)
+#define	IOMMU_FIRE		(1 << 1)
+#define	IOMMU_FLUSH_CACHE	(1 << 2)
+#define	IOMMU_PRESERVE_PROM	(1 << 3)
 };
 
 /* interfaces for PCI/SBus code */
-void iommu_init(const char *name, struct iommu_state *is, int tsbsize,
-    uint32_t iovabase, int resvpg);
+void iommu_init(const char *name, struct iommu_state *is, u_int tsbsize,
+    uint32_t iovabase, u_int resvpg);
 void iommu_reset(struct iommu_state *is);
 void iommu_decode_fault(struct iommu_state *is, vm_offset_t phys);
 
diff --git a/sys/sparc64/sparc64/iommu.c b/sys/sparc64/sparc64/iommu.c
index 88ab2c9fb6a..b5f24dbb2ab 100644
--- a/sys/sparc64/sparc64/iommu.c
+++ b/sys/sparc64/sparc64/iommu.c
@@ -138,11 +138,13 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -212,6 +214,12 @@ static __inline void
 iommu_tlb_flush(struct iommu_state *is, bus_addr_t va)
 {
 
+	if ((is->is_flags & IOMMU_FIRE) != 0)
+		/*
+		 * Direct page flushing is not supported and also not
+		 * necessary due to cache snooping.
+		 */
+		return;
 	IOMMU_WRITE8(is, is_iommu, IMR_FLUSH, va);
 }
 
@@ -282,18 +290,19 @@ iommu_map_remq(struct iommu_state *is, bus_dmamap_t map)
  *	- create a private DVMA map.
  */
 void
-iommu_init(const char *name, struct iommu_state *is, int tsbsize,
-    uint32_t iovabase, int resvpg)
+iommu_init(const char *name, struct iommu_state *is, u_int tsbsize,
+    uint32_t iovabase, u_int resvpg)
 {
 	vm_size_t size;
 	vm_offset_t offs;
-	uint64_t end;
+	uint64_t end, obpmap, obpptsb, tte;
+	u_int maxtsbsize, obptsbentries, obptsbsize, slot, tsbentries;
 	int i;
 
 	/*
-	 * Setup the iommu.
+	 * Setup the IOMMU.
 	 *
-	 * The sun4u iommu is part of the PCI or SBus controller so we
+	 * The sun4u IOMMU is part of the PCI or SBus controller so we
 	 * will deal with it here..
 	 *
 	 * The IOMMU address space always ends at 0xffffe000, but the starting
@@ -301,16 +310,30 @@ iommu_init(const char *name, struct iommu_state *is, int tsbsize,
 	 * is->is_tsbsize entries, where each entry is 8 bytes.  The start of
 	 * the map can be calculated by (0xffffe000 << (8 + is->is_tsbsize)).
 	 */
-	is->is_cr = (tsbsize << IOMMUCR_TSBSZ_SHIFT) | IOMMUCR_EN;
+	if ((is->is_flags & IOMMU_FIRE) != 0) {
+		maxtsbsize = IOMMU_TSB512K;
+		/*
+		 * We enable bypass in order to be able to use a physical
+		 * address for the event queue base.
+		 */
+		is->is_cr = IOMMUCR_SE | IOMMUCR_CM_C_TLB_TBW | IOMMUCR_BE;
+	} else {
+		maxtsbsize = IOMMU_TSB128K;
+		is->is_cr = (tsbsize << IOMMUCR_TSBSZ_SHIFT) | IOMMUCR_DE;
+	}
+	if (tsbsize > maxtsbsize)
+		panic("%s: unsupported TSB size	", __func__);
+	tsbentries = IOMMU_TSBENTRIES(tsbsize);
+	is->is_cr |= IOMMUCR_EN;
 	is->is_tsbsize = tsbsize;
 	is->is_dvmabase = iovabase;
 	if (iovabase == -1)
 		is->is_dvmabase = IOTSB_VSTART(is->is_tsbsize);
 
 	size = IOTSB_BASESZ << is->is_tsbsize;
-	printf("%s: DVMA map: %#lx to %#lx%s\n", name,
+	printf("%s: DVMA map: %#lx to %#lx %d entries%s\n", name,
 	    is->is_dvmabase, is->is_dvmabase +
-	    (size << (IO_PAGE_SHIFT - IOTTE_SHIFT)) - 1,
+	    (size << (IO_PAGE_SHIFT - IOTTE_SHIFT)) - 1, tsbentries,
 	    IOMMU_HAS_SB(is) ? ", streaming buffer" : "");
 
 	/*
@@ -333,11 +356,53 @@ iommu_init(const char *name, struct iommu_state *is, int tsbsize,
 	 */
 	is->is_tsb = contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, ~0UL,
 	    PAGE_SIZE, 0);
-	if (is->is_tsb == 0)
+	if (is->is_tsb == NULL)
 		panic("%s: contigmalloc failed", __func__);
 	is->is_ptsb = pmap_kextract((vm_offset_t)is->is_tsb);
 	bzero(is->is_tsb, size);
 
+	/*
+	 * Add the PROM mappings to the kernel IOTSB if desired.
+	 * Note that the firmware of certain Darwin boards doesn't set
+	 * the TSB size correctly.
+	 */
+	if ((is->is_flags & IOMMU_FIRE) != 0)
+		obptsbsize = (IOMMU_READ8(is, is_iommu, IMR_TSB) &
+		    IOMMUTB_TSBSZ_MASK) >> IOMMUTB_TSBSZ_SHIFT;
+	else
+		obptsbsize = (IOMMU_READ8(is, is_iommu, IMR_CTL) &
+		    IOMMUCR_TSBSZ_MASK) >> IOMMUCR_TSBSZ_SHIFT;
+	obptsbentries = IOMMU_TSBENTRIES(obptsbsize);
+	if (bootverbose)
+		printf("%s: PROM IOTSB size: %d (%d entries)\n", name,
+		    obptsbsize, obptsbentries);
+	if ((is->is_flags & IOMMU_PRESERVE_PROM) != 0 &&
+	    !(cpu_impl == CPU_IMPL_ULTRASPARCIIi && obptsbsize == 7)) {
+		if (obptsbentries > tsbentries)
+			panic("%s: PROM IOTSB entries exceed kernel",
+			    __func__);
+		obpptsb = IOMMU_READ8(is, is_iommu, IMR_TSB) &
+		    IOMMUTB_TB_MASK;
+		for (i = 0; i < obptsbentries; i++) {
+			tte = ldxa(obpptsb + i * 8, ASI_PHYS_USE_EC);
+			if ((tte & IOTTE_V) == 0)
+				continue;
+			slot = tsbentries - obptsbentries + i;
+			if (bootverbose)
+				printf("%s: adding PROM IOTSB slot %d "
+				    "(kernel slot %d) TTE: %#lx\n", name,
+				    i, slot, tte);
+			obpmap = (is->is_dvmabase + slot * IO_PAGE_SIZE) >>
+			    IO_PAGE_SHIFT;
+			if (rman_reserve_resource(&is->is_dvma_rman, obpmap,
+			    obpmap, IO_PAGE_SIZE >> IO_PAGE_SHIFT, RF_ACTIVE,
+			    NULL) == NULL)
+				panic("%s: could not reserve PROM IOTSB slot "
+				    "%d (kernel slot %d)", __func__, i, slot);
+			is->is_tsb[slot] = tte;
+		}
+	}
+
 	/*
 	 * Initialize streaming buffer, if it is there.
 	 */
@@ -349,7 +414,7 @@ iommu_init(const char *name, struct iommu_state *is, int tsbsize,
 		offs = roundup2((vm_offset_t)is->is_flush,
 		    STRBUF_FLUSHSYNC_NBYTES);
 		for (i = 0; i < 2; i++, offs += STRBUF_FLUSHSYNC_NBYTES) {
-			is->is_flushva[i] = (int64_t *)offs;
+			is->is_flushva[i] = (uint64_t *)offs;
 			is->is_flushpa[i] = pmap_kextract(offs);
 		}
 	}
@@ -368,11 +433,16 @@ iommu_init(const char *name, struct iommu_state *is, int tsbsize,
 void
 iommu_reset(struct iommu_state *is)
 {
+	uint64_t tsb;
 	int i;
 
-	IOMMU_WRITE8(is, is_iommu, IMR_TSB, is->is_ptsb);
-	/* Enable IOMMU in diagnostic mode */
-	IOMMU_WRITE8(is, is_iommu, IMR_CTL, is->is_cr | IOMMUCR_DE);
+	tsb = is->is_ptsb;
+	if ((is->is_flags & IOMMU_FIRE) != 0) {
+		tsb |= is->is_tsbsize;
+		IOMMU_WRITE8(is, is_iommu, IMR_CACHE_INVAL, ~0ULL);
+	}
+	IOMMU_WRITE8(is, is_iommu, IMR_TSB, tsb);
+	IOMMU_WRITE8(is, is_iommu, IMR_CTL, is->is_cr);
 
 	for (i = 0; i < 2; i++) {
 		if (is->is_sb[i] != 0) {
@@ -386,6 +456,8 @@ iommu_reset(struct iommu_state *is)
 				is->is_sb[i] = 0;
 		}
 	}
+
+	(void)IOMMU_READ8(is, is_iommu, IMR_CTL);
 }
 
 /*
@@ -396,7 +468,7 @@ static void
 iommu_enter(struct iommu_state *is, vm_offset_t va, vm_paddr_t pa,
     int stream, int flags)
 {
-	int64_t tte;
+	uint64_t tte;
 
 	KASSERT(va >= is->is_dvmabase,
 	    ("%s: va %#lx not in DVMA space", __func__, va));
@@ -423,7 +495,7 @@ iommu_enter(struct iommu_state *is, vm_offset_t va, vm_paddr_t pa,
 static int
 iommu_remove(struct iommu_state *is, vm_offset_t va, vm_size_t len)
 {
-	int streamed = 0;
+	int slot, streamed = 0;
 
 #ifdef IOMMU_DIAG
 	iommu_diag(is, va);
@@ -443,6 +515,12 @@ iommu_remove(struct iommu_state *is, vm_offset_t va, vm_size_t len)
 		len -= ulmin(len, IO_PAGE_SIZE);
 		IOMMU_SET_TTE(is, va, 0);
 		iommu_tlb_flush(is, va);
+		if ((is->is_flags & IOMMU_FLUSH_CACHE) != 0) {
+			slot = IOTSBSLOT(va);
+			if (len <= IO_PAGE_SIZE || slot % 8 == 7)
+				IOMMU_WRITE8(is, is_iommu, IMR_CACHE_FLUSH,
+				    is->is_ptsb + slot * 8);
+		}
 		va += IO_PAGE_SIZE;
 	}
 	return (streamed);
@@ -829,12 +907,13 @@ iommu_dvmamap_load_buffer(bus_dma_tag_t dt, struct iommu_state *is,
     bus_dmamap_t map, void *buf, bus_size_t buflen, struct thread *td,
     int flags, bus_dma_segment_t *segs, int *segp, int align)
 {
-	bus_addr_t amask, dvmaddr;
+	bus_addr_t amask, dvmaddr, dvmoffs;
 	bus_size_t sgsize, esize;
 	vm_offset_t vaddr, voffs;
 	vm_paddr_t curaddr;
 	pmap_t pmap = NULL;
 	int error, firstpg, sgcnt;
+	u_int slot;
 
 	KASSERT(buflen != 0, ("%s: buflen == 0!", __func__));
 	if (buflen > dt->dt_maxsize)
@@ -877,8 +956,15 @@ iommu_dvmamap_load_buffer(bus_dma_tag_t dt, struct iommu_state *is,
 		buflen -= sgsize;
 		vaddr += sgsize;
 
-		iommu_enter(is, trunc_io_page(dvmaddr), trunc_io_page(curaddr),
+		dvmoffs = trunc_io_page(dvmaddr);
+		iommu_enter(is, dvmoffs, trunc_io_page(curaddr),
 		    (map->dm_flags & DMF_STREAMED) != 0, flags);
+		if ((is->is_flags & IOMMU_FLUSH_CACHE) != 0) {
+			slot = IOTSBSLOT(dvmoffs);
+			if (buflen <= 0 || slot % 8 == 7)
+				IOMMU_WRITE8(is, is_iommu, IMR_CACHE_FLUSH,
+				    is->is_ptsb + slot * 8);
+		}
 
 		/*
 		 * Chop the chunk up into segments of at most maxsegsz, but try
@@ -1183,6 +1269,8 @@ iommu_diag(struct iommu_state *is, vm_offset_t va)
 	int i;
 	uint64_t data, tag;
 
+	if ((is->is_flags & IOMMU_FIRE) != 0)
+		return;
 	IS_LOCK_ASSERT(is);
 	IOMMU_WRITE8(is, is_dva, 0, trunc_io_page(va));
 	membar(StoreStore | StoreLoad);

From f07dd8aaa55b59f430ce5de2112ccd58cc54eb3d Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:17:45 +0000
Subject: [PATCH 1112/2592] MFC: r200924

Style changes.
---
 sys/sparc64/sparc64/ofw_machdep.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/sys/sparc64/sparc64/ofw_machdep.c b/sys/sparc64/sparc64/ofw_machdep.c
index bcacea77b41..88e6f6dcacd 100644
--- a/sys/sparc64/sparc64/ofw_machdep.c
+++ b/sys/sparc64/sparc64/ofw_machdep.c
@@ -23,7 +23,7 @@
  * 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$");
 
@@ -64,34 +64,32 @@ OF_getetheraddr(device_t dev, u_char *addr)
 
 	node = OF_peer(0);
 	if (node <= 0 || OF_getprop(node, "idprom", &idp, sizeof(idp)) == -1)
-		panic("Could not determine the machine ethernet address");
+		panic("Could not determine the machine Ethernet address");
 	bcopy(&idp.id_ether, addr, ETHER_ADDR_LEN);
 }
 
 static __inline uint32_t
 phys_hi_mask_space(const char *bus, uint32_t phys_hi)
 {
-	uint32_t space;
 
-	space = phys_hi;
 	if (strcmp(bus, "ebus") == 0 || strcmp(bus, "isa") == 0)
-		space &= 0x1;
+		phys_hi &= 0x1;
 	else if (strcmp(bus, "pci") == 0)
-		space &= OFW_PCI_PHYS_HI_SPACEMASK;
+		phys_hi &= OFW_PCI_PHYS_HI_SPACEMASK;
 	/* The phys.hi cells of the other busses only contain space bits. */
-	return (space);
+	return (phys_hi);
 }
 
 /*
  * Return the physical address and the bus space to use for a node
  * referenced by its package handle and the index of the register bank
- * to decode. Intended to be used to together with sparc64_fake_bustag()
+ * to decode.  Intended to be used to together with sparc64_fake_bustag()
  * by console drivers in early boot only.
  * Works by mapping the address of the node's bank given in the address
  * space of its parent upward in the device tree at each bridge along the
  * path.
  * Currently only really deals with max. 64-bit addresses, i.e. addresses
- * consisting of max. 2 phys cells (phys.hi and phys.lo). If we encounter
+ * consisting of max. 2 phys cells (phys.hi and phys.lo).  If we encounter
  * a 3 phys cells address (as with PCI addresses) we assume phys.hi can
  * be ignored except for the space bits (generally contained in phys.hi)
  * and treat phys.mid as phys.hi.
@@ -109,17 +107,17 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
 
 	/*
 	 * In general the addresses are contained in the "reg" property
-	 * of a node. The first address in the "reg" property of a PCI
+	 * of a node.  The first address in the "reg" property of a PCI
 	 * node however is the address of its configuration registers in
-	 * the configuration space of the host bridge. Additional entries
-	 * denote the memory and I/O addresses. For relocatable addresses
+	 * the configuration space of the host bridge.  Additional entries
+	 * denote the memory and I/O addresses.  For relocatable addresses
 	 * the "reg" property contains the BAR, for non-relocatable
-	 * addresses it contains the absolute PCI address. The PCI-only
+	 * addresses it contains the absolute PCI address.  The PCI-only
 	 * "assigned-addresses" property however always contains the
 	 * absolute PCI addresses.
 	 * The "assigned-addresses" and "reg" properties are arrays of
 	 * address structures consisting of #address-cells 32-bit phys
-	 * cells and #size-cells 32-bit size cells. If a parent lacks
+	 * cells and #size-cells 32-bit size cells.  If a parent lacks
 	 * the "#address-cells" or "#size-cells" property the default
 	 * for #address-cells to use is 2 and for #size-cells 1.
 	 */

From 1f0040f79ffda48c6590ed73c13e4dcbda462807 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:19:46 +0000
Subject: [PATCH 1113/2592] MFC: r200925

- By re-arranging the code in OF_decode_addr() somewhat and accepting
  a bit of a detour we can just iterate through the banks array instead
  of having to calculate every offset. This change is inspired by the
  powerpc version of this function.
- Add support for the JBus to EBus bridges which hang off of nexus(4).
---
 sys/sparc64/sparc64/ofw_machdep.c | 66 +++++++++++++++----------------
 1 file changed, 33 insertions(+), 33 deletions(-)

diff --git a/sys/sparc64/sparc64/ofw_machdep.c b/sys/sparc64/sparc64/ofw_machdep.c
index 88e6f6dcacd..9d522629c78 100644
--- a/sys/sparc64/sparc64/ofw_machdep.c
+++ b/sys/sparc64/sparc64/ofw_machdep.c
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2001 by Thomas Moestl .
- * Copyright (c) 2005 by Marius Strobl .
+ * Copyright (c) 2005 - 2009 by Marius Strobl .
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -98,11 +98,11 @@ int
 OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
 {
 	char name[32];
-	uint64_t cend, cstart, end, phys, sz, start;
+	uint64_t cend, cstart, end, phys, pphys, sz, start;
 	pcell_t addrc, szc, paddrc;
 	phandle_t bus, lbus, pbus;
 	uint32_t banks[10 * 5];	/* 10 PCI banks */
-	uint32_t cspace, spc;
+	uint32_t cspc, pspc, spc;
 	int i, j, nbank;
 
 	/*
@@ -148,17 +148,18 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
 	nbank /= sizeof(banks[0]) * (addrc + szc);
 	if (bank < 0 || bank > nbank - 1)
 		return (ENXIO);
+	bank *= addrc + szc;
+	spc = phys_hi_mask_space(name, banks[bank]);
+	/* Skip the high cell for 3-cell addresses. */
+	bank += addrc - 2;
 	phys = 0;
 	for (i = 0; i < MIN(2, addrc); i++)
-		phys |= (uint64_t)banks[(addrc + szc) * bank + addrc - 2 + i] <<
-		    32 * (MIN(2, addrc) - i - 1);
+		phys = ((uint64_t)phys << 32) | banks[bank++];
 	sz = 0;
 	for (i = 0; i < szc; i++)
-		sz |= (uint64_t)banks[(addrc + szc) * bank + addrc + i] <<
-		    32 * (szc - i - 1);
+		sz = ((uint64_t)sz << 32) | banks[bank++];
 	start = phys;
 	end = phys + sz - 1;
-	spc = phys_hi_mask_space(name, banks[(addrc + szc) * bank]);
 
 	/*
 	 * Map upward in the device tree at every bridge we encounter
@@ -170,7 +171,7 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
 	 * If a bridge doesn't have a "ranges" property no mapping is
 	 * necessary at that bridge.
 	 */
-	cspace = 0;
+	cspc = 0;
 	lbus = bus;
 	while ((pbus = OF_parent(bus)) != 0) {
 		if (OF_getprop(pbus, "#address-cells", &paddrc,
@@ -193,42 +194,40 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
 				return (ENXIO);
 		}
 		nbank /= sizeof(banks[0]) * (addrc + paddrc + szc);
+		bank = 0;
 		for (i = 0; i < nbank; i++) {
-			cspace = phys_hi_mask_space(name,
-			    banks[(addrc + paddrc + szc) * i]);
-			if (cspace != spc)
+			cspc = phys_hi_mask_space(name, banks[bank]);
+			if (cspc != spc) {
+				bank += addrc + paddrc + szc;
 				continue;
+			}
+			/* Skip the high cell for 3-cell addresses. */
+			bank += addrc - 2;
 			phys = 0;
 			for (j = 0; j < MIN(2, addrc); j++)
-				phys |= (uint64_t)banks[
-				    (addrc + paddrc + szc) * i +
-				    addrc - 2 + j] <<
-				    32 * (MIN(2, addrc) - j - 1);
+				phys = ((uint64_t)phys << 32) | banks[bank++];
+			pspc = banks[bank];
+			/* Skip the high cell for 3-cell addresses. */
+			bank += paddrc - 2;
+			pphys = 0;
+			for (j = 0; j < MIN(2, paddrc); j++)
+				pphys =
+				    ((uint64_t)pphys << 32) | banks[bank++];
 			sz = 0;
 			for (j = 0; j < szc; j++)
-				sz |= (uint64_t)banks[
-				    (addrc + paddrc + szc) * i + addrc +
-				    paddrc + j] <<
-				    32 * (szc - j - 1);
+				sz = ((uint64_t)sz << 32) | banks[bank++];
 			cstart = phys;
 			cend = phys + sz - 1;
 			if (start < cstart || start > cend)
 				continue;
 			if (end < cstart || end > cend)
 				return (ENXIO);
-			phys = 0;
-			for (j = 0; j < MIN(2, paddrc); j++)
-				phys |= (uint64_t)banks[
-				    (addrc + paddrc + szc) * i + addrc +
-				    paddrc - 2 + j] <<
-				    32 * (MIN(2, paddrc) - j - 1);
-			start += phys - cstart;
-			end += phys - cstart;
 			if (OF_getprop(pbus, "name", name, sizeof(name)) == -1)
 				return (ENXIO);
 			name[sizeof(name) - 1] = '\0';
-			spc = phys_hi_mask_space(name,
-			    banks[(addrc + paddrc + szc) * i + addrc]);
+			spc = phys_hi_mask_space(name, pspc);
+			start += pphys - cstart;
+			end += pphys - cstart;
 			break;
 		}
 		if (i == nbank)
@@ -239,8 +238,8 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
 		bus = pbus;
 	}
 
-	/* Done with mapping. Return the bus space as used by FreeBSD. */
 	*addr = start;
+	/* Determine the bus space based on the last bus we mapped. */
 	if (OF_parent(lbus) == 0) {
 		*space = NEXUS_BUS_SPACE;
 		return (0);
@@ -248,11 +247,12 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
 	if (OF_getprop(lbus, "name", name, sizeof(name)) == -1)
 		return (ENXIO);
 	name[sizeof(name) - 1] = '\0';
-	if (strcmp(name, "central") == 0 || strcmp(name, "upa") == 0) {
+	if (strcmp(name, "central") == 0 || strcmp(name, "ebus") == 0 ||
+	    strcmp(name, "upa") == 0) {
 		*space = NEXUS_BUS_SPACE;
 		return (0);
 	} else if (strcmp(name, "pci") == 0) {
-		switch (cspace) {
+		switch (cspc) {
 		case OFW_PCI_PHYS_HI_SPACE_IO:
 			*space = PCI_IO_BUS_SPACE;
 			return (0);

From 74794d0d58faeaab501f8361091a956c4e140bea Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:21:29 +0000
Subject: [PATCH 1114/2592] MFC: r200926

Recognize the NS16552 found in PCIe-based sun4u machines.
---
 sys/dev/uart/uart_bus_ebus.c    | 2 +-
 sys/dev/uart/uart_cpu_sparc64.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/sys/dev/uart/uart_bus_ebus.c b/sys/dev/uart/uart_bus_ebus.c
index e4ea2d14937..c79c91e908e 100644
--- a/sys/dev/uart/uart_bus_ebus.c
+++ b/sys/dev/uart/uart_bus_ebus.c
@@ -77,7 +77,7 @@ uart_ebus_probe(device_t dev)
 	if (!strcmp(nm, "lom-console") || !strcmp(nm, "su") ||
 	    !strcmp(nm, "su_pnp") || !strcmp(cmpt, "rsc-console") ||
 	    !strcmp(cmpt, "rsc-control") || !strcmp(cmpt, "su") ||
-	    !strcmp(cmpt, "su16550")) {
+	    !strcmp(cmpt, "su16550") || !strcmp(cmpt, "su16552")) {
 		/*
 		 * On AXi and AXmp boards the NS16550 (used to connect
 		 * keyboard/mouse) share their IRQ lines with the i8042.
diff --git a/sys/dev/uart/uart_cpu_sparc64.c b/sys/dev/uart/uart_cpu_sparc64.c
index 9d92a390873..0f40cb70bd7 100644
--- a/sys/dev/uart/uart_cpu_sparc64.c
+++ b/sys/dev/uart/uart_cpu_sparc64.c
@@ -254,7 +254,8 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 		addr += range - range * (di->bas.chan - 1);
 	} else if (!strcmp(buf, "lom-console") || !strcmp(buf, "su") ||
 	    !strcmp(buf, "su_pnp") || !strcmp(compat, "rsc-console") ||
-	    !strcmp(compat, "su") || !strcmp(compat, "su16550")) {
+	    !strcmp(compat, "su") || !strcmp(compat, "su16550") ||
+	    !strcmp(compat, "su16552")) {
 		class = &uart_ns8250_class;
 		di->bas.chan = 0;
 	}

From d07d09d79f47e3ce572cbae296bea1a0144c1fee Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Wed, 13 Jan 2010 21:23:27 +0000
Subject: [PATCH 1115/2592] MFC: r200938

- Don't check for a valid interrupt controller on every interrupt
  in intr_execute_handlers(). If we managed to get here without an
  associated interrupt controller we have way bigger problems.
  While at it predict stray vector interrupts as false as they are
  rather unlikely.
- Don't blindly call the clear function of an interrupt controller
  when adding a handler in inthand_add() as interrupt controllers
  like the one driven by upa(4) are auto-clearing and thus provide
  NULL instead.
---
 sys/sparc64/sparc64/intr_machdep.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sys/sparc64/sparc64/intr_machdep.c b/sys/sparc64/sparc64/intr_machdep.c
index 9f9df1b4a26..d0174b93198 100644
--- a/sys/sparc64/sparc64/intr_machdep.c
+++ b/sys/sparc64/sparc64/intr_machdep.c
@@ -276,7 +276,7 @@ intr_execute_handlers(void *cookie)
 	struct intr_vector *iv;
 
 	iv = cookie;
-	if (iv->iv_ic == NULL || intr_event_handle(iv->iv_event, NULL) != 0)
+	if (__predict_false(intr_event_handle(iv->iv_event, NULL) != 0))
 		intr_stray_vector(iv);
 }
 
@@ -377,7 +377,8 @@ inthand_add(const char *name, int vec, driver_filter_t *filt,
 #endif
 	ic->ic_enable(iv);
 	/* Ensure the interrupt is cleared, it might have triggered before. */
-	ic->ic_clear(iv);
+	if (ic->ic_clear != NULL)
+		ic->ic_clear(iv);
 	sx_xunlock(&intr_table_lock);
 	return (0);
 }

From ea6ffaa74206318dc577d797414a75737b00faaa Mon Sep 17 00:00:00 2001
From: Rick Macklem 
Date: Thu, 14 Jan 2010 17:35:07 +0000
Subject: [PATCH 1116/2592] MFC: r201345 Fix the experimental NFS client so
 that it can create Unix domain sockets on an NFSv4 mount point. It was
 generating incorrect XDR in the request for this case.

Tested by:	infofarmer
---
 sys/fs/nfsclient/nfs_clrpcops.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 37131cf9448..88e17791284 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -1633,10 +1633,15 @@ nfsrpc_mknod(vnode_t dvp, char *name, int namelen, struct vattr *vap,
 		return (ENAMETOOLONG);
 	NFSCL_REQSTART(nd, NFSPROC_MKNOD, dvp);
 	if (nd->nd_flag & ND_NFSV4) {
-		NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
-		*tl++ = vtonfsv34_type(vtyp);
-		*tl++ = txdr_unsigned(NFSMAJOR(rdev));
-		*tl = txdr_unsigned(NFSMINOR(rdev));
+		if (vtyp == VBLK || vtyp == VCHR) {
+			NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
+			*tl++ = vtonfsv34_type(vtyp);
+			*tl++ = txdr_unsigned(NFSMAJOR(rdev));
+			*tl = txdr_unsigned(NFSMINOR(rdev));
+		} else {
+			NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
+			*tl = vtonfsv34_type(vtyp);
+		}
 	}
 	(void) nfsm_strtom(nd, name, namelen);
 	if (nd->nd_flag & ND_NFSV3) {

From 699df0c4facbef5a763de24be4e3738e9394d55f Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 14 Jan 2010 20:38:40 +0000
Subject: [PATCH 1117/2592] Partial merge r199559:   - Add a private timer to
 drive the transmit watchdog instead of using     if_watchdog and if_timer.  
 - Fix some issues in detach for sn(4), ste(4), and ti(4).  Primarily this    
 means calling ether_ifdetach() before anything else.

---
 sys/dev/ste/if_ste.c    | 21 ++++++++++-----------
 sys/dev/ste/if_stereg.h |  1 +
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c
index f68a97d2e83..55b256f4b97 100644
--- a/sys/dev/ste/if_ste.c
+++ b/sys/dev/ste/if_ste.c
@@ -108,7 +108,7 @@ static int ste_ioctl(struct ifnet *, u_long, caddr_t);
 static int ste_encap(struct ste_softc *, struct ste_chain *, struct mbuf *);
 static void ste_start(struct ifnet *);
 static void ste_start_locked(struct ifnet *);
-static void ste_watchdog(struct ifnet *);
+static void ste_watchdog(struct ste_softc *);
 static int ste_shutdown(device_t);
 static int ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *,
 		struct mbuf *);
@@ -924,7 +924,7 @@ ste_txeof(sc)
 
 	sc->ste_cdata.ste_tx_cons = idx;
 	if (idx == sc->ste_cdata.ste_tx_prod)
-		ifp->if_timer = 0;
+		sc->ste_timer = 0;
 }
 
 static void
@@ -960,6 +960,8 @@ ste_stats_update(xsc)
 		}
 	}
 
+	if (sc->ste_timer > 0 && --sc->ste_timer == 0)
+		ste_watchdog(sc);
 	callout_reset(&sc->ste_stat_callout, hz, ste_stats_update, sc);
 
 	return;
@@ -1094,7 +1096,6 @@ ste_attach(dev)
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = ste_ioctl;
 	ifp->if_start = ste_start;
-	ifp->if_watchdog = ste_watchdog;
 	ifp->if_init = ste_init;
 	IFQ_SET_MAXLEN(&ifp->if_snd, STE_TX_LIST_CNT - 1);
 	ifp->if_snd.ifq_drv_maxlen = STE_TX_LIST_CNT - 1;
@@ -1159,11 +1160,11 @@ ste_detach(dev)
 
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
+		ether_ifdetach(ifp);
 		STE_LOCK(sc);
 		ste_stop(sc);
 		STE_UNLOCK(sc);
 		callout_drain(&sc->ste_stat_callout);
-		ether_ifdetach(ifp);
 	}
 	if (sc->ste_miibus)
 		device_delete_child(dev, sc->ste_miibus);
@@ -1708,7 +1709,7 @@ ste_start_locked(ifp)
 		BPF_MTAP(ifp, cur_tx->ste_mbuf);
 
 		STE_INC(idx, STE_TX_LIST_CNT);
-		ifp->if_timer = 5;
+		sc->ste_timer = 5;
 	}
 	sc->ste_cdata.ste_tx_prod = idx;
 
@@ -1716,13 +1717,12 @@ ste_start_locked(ifp)
 }
 
 static void
-ste_watchdog(ifp)
-	struct ifnet		*ifp;
+ste_watchdog(struct ste_softc *sc)
 {
-	struct ste_softc	*sc;
+	struct ifnet		*ifp;
 
-	sc = ifp->if_softc;
-	STE_LOCK(sc);
+	ifp = sc->ste_ifp;
+	STE_LOCK_ASSERT(sc);
 
 	ifp->if_oerrors++;
 	if_printf(ifp, "watchdog timeout\n");
@@ -1736,7 +1736,6 @@ ste_watchdog(ifp)
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		ste_start_locked(ifp);
-	STE_UNLOCK(sc);
 
 	return;
 }
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index 0114ebe459c..68d96741e8d 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -517,6 +517,7 @@ struct ste_softc {
 	int			ste_tx_thresh;
 	u_int8_t		ste_link;
 	int			ste_if_flags;
+	int			ste_timer;
 	struct ste_chain	*ste_tx_prev;
 	struct ste_list_data	*ste_ldata;
 	struct ste_chain_data	ste_cdata;

From 41c95608a0dd535b8d96bfc4a0ce435a1e6c71df Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 14 Jan 2010 20:47:49 +0000
Subject: [PATCH 1118/2592] MFC r200798,200801,200803-200804,200808,200810
 r200798:   Use ANSI function definations.

r200801:
   o Remove unnecessary return statement.
   o Remove register keyword.

r200803:
  s/u_intXX_t/uintXX_t/g

r200804:
  Remove trailing white spaces.

r200808:
  style(9)

r200810:
  Sort function prototyes.
---
 sys/dev/ste/if_ste.c    | 452 ++++++++++++++++------------------------
 sys/dev/ste/if_stereg.h |  68 +++---
 2 files changed, 219 insertions(+), 301 deletions(-)

diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c
index 55b256f4b97..91bd968b020 100644
--- a/sys/dev/ste/if_ste.c
+++ b/sys/dev/ste/if_ste.c
@@ -91,45 +91,44 @@ static struct ste_type ste_devs[] = {
 	{ 0, 0, NULL }
 };
 
-static int ste_probe(device_t);
-static int ste_attach(device_t);
-static int ste_detach(device_t);
-static void ste_init(void *);
-static void ste_init_locked(struct ste_softc *);
-static void ste_intr(void *);
-static void ste_rxeoc(struct ste_softc *);
-static int ste_rxeof(struct ste_softc *);
-static void ste_txeoc(struct ste_softc *);
-static void ste_txeof(struct ste_softc *);
-static void ste_stats_update(void *);
-static void ste_stop(struct ste_softc *);
-static void ste_reset(struct ste_softc *);
-static int ste_ioctl(struct ifnet *, u_long, caddr_t);
-static int ste_encap(struct ste_softc *, struct ste_chain *, struct mbuf *);
-static void ste_start(struct ifnet *);
-static void ste_start_locked(struct ifnet *);
-static void ste_watchdog(struct ste_softc *);
-static int ste_shutdown(device_t);
-static int ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *,
-		struct mbuf *);
-static int ste_ifmedia_upd(struct ifnet *);
-static void ste_ifmedia_upd_locked(struct ifnet *);
-static void ste_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+static int	ste_attach(device_t);
+static int	ste_detach(device_t);
+static int	ste_probe(device_t);
+static int	ste_shutdown(device_t);
 
-static void ste_mii_sync(struct ste_softc *);
-static void ste_mii_send(struct ste_softc *, u_int32_t, int);
-static int ste_mii_readreg(struct ste_softc *, struct ste_mii_frame *);
-static int ste_mii_writereg(struct ste_softc *, struct ste_mii_frame *);
-static int ste_miibus_readreg(device_t, int, int);
-static int ste_miibus_writereg(device_t, int, int, int);
-static void ste_miibus_statchg(device_t);
-
-static int ste_eeprom_wait(struct ste_softc *);
-static int ste_read_eeprom(struct ste_softc *, caddr_t, int, int, int);
-static void ste_wait(struct ste_softc *);
-static void ste_setmulti(struct ste_softc *);
-static int ste_init_rx_list(struct ste_softc *);
-static void ste_init_tx_list(struct ste_softc *);
+static int 	ste_eeprom_wait(struct ste_softc *);
+static int	ste_encap(struct ste_softc *, struct ste_chain *, struct mbuf *);
+static int	ste_ifmedia_upd(struct ifnet *);
+static void	ste_ifmedia_upd_locked(struct ifnet *);
+static void	ste_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+static void	ste_init(void *);
+static void	ste_init_locked(struct ste_softc *);
+static int	ste_init_rx_list(struct ste_softc *);
+static void	ste_init_tx_list(struct ste_softc *);
+static void	ste_intr(void *);
+static int	ste_ioctl(struct ifnet *, u_long, caddr_t);
+static int	ste_mii_readreg(struct ste_softc *, struct ste_mii_frame *);
+static void	ste_mii_send(struct ste_softc *, uint32_t, int);
+static void	ste_mii_sync(struct ste_softc *);
+static int	ste_mii_writereg(struct ste_softc *, struct ste_mii_frame *);
+static int	ste_miibus_readreg(device_t, int, int);
+static void	ste_miibus_statchg(device_t);
+static int	ste_miibus_writereg(device_t, int, int, int);
+static int	ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *,
+		    struct mbuf *);
+static int	ste_read_eeprom(struct ste_softc *, caddr_t, int, int, int);
+static void	ste_reset(struct ste_softc *);
+static void	ste_rxeoc(struct ste_softc *);
+static int	ste_rxeof(struct ste_softc *);
+static void	ste_setmulti(struct ste_softc *);
+static void	ste_start(struct ifnet *);
+static void	ste_start_locked(struct ifnet *);
+static void	ste_stats_update(void *);
+static void	ste_stop(struct ste_softc *);
+static void	ste_txeoc(struct ste_softc *);
+static void	ste_txeof(struct ste_softc *);
+static void	ste_wait(struct ste_softc *);
+static void	ste_watchdog(struct ste_softc *);
 
 #ifdef STE_USEIOSPACE
 #define STE_RES			SYS_RES_IOPORT
@@ -194,16 +193,15 @@ SYSCTL_INT(_hw_ste, OID_AUTO, rxsyncs, CTLFLAG_RW, &ste_rxsyncs, 0, "");
 
 
 #define MII_SET(x)		STE_SETBIT1(sc, STE_PHYCTL, x)
-#define MII_CLR(x)		STE_CLRBIT1(sc, STE_PHYCTL, x) 
+#define MII_CLR(x)		STE_CLRBIT1(sc, STE_PHYCTL, x)
 
 /*
  * Sync the PHYs by setting data bit and strobing the clock 32 times.
  */
 static void
-ste_mii_sync(sc)
-	struct ste_softc		*sc;
+ste_mii_sync(struct ste_softc *sc)
 {
-	register int		i;
+	int i;
 
 	MII_SET(STE_PHYCTL_MDIR|STE_PHYCTL_MDATA);
 
@@ -213,20 +211,15 @@ ste_mii_sync(sc)
 		MII_CLR(STE_PHYCTL_MCLK);
 		DELAY(1);
 	}
-
-	return;
 }
 
 /*
  * Clock a series of bits through the MII.
  */
 static void
-ste_mii_send(sc, bits, cnt)
-	struct ste_softc		*sc;
-	u_int32_t		bits;
-	int			cnt;
+ste_mii_send(struct ste_softc *sc, uint32_t bits, int cnt)
 {
-	int			i;
+	int i;
 
 	MII_CLR(STE_PHYCTL_MCLK);
 
@@ -247,12 +240,9 @@ ste_mii_send(sc, bits, cnt)
  * Read an PHY register through the MII.
  */
 static int
-ste_mii_readreg(sc, frame)
-	struct ste_softc		*sc;
-	struct ste_mii_frame	*frame;
-	
+ste_mii_readreg(struct ste_softc *sc, struct ste_mii_frame *frame)
 {
-	int			i, ack;
+	int i, ack;
 
 	/*
 	 * Set up frame for RX.
@@ -261,7 +251,7 @@ ste_mii_readreg(sc, frame)
 	frame->mii_opcode = STE_MII_READOP;
 	frame->mii_turnaround = 0;
 	frame->mii_data = 0;
-	
+
 	CSR_WRITE_2(sc, STE_PHYCTL, 0);
 	/*
  	 * Turn on data xmit.
@@ -299,7 +289,7 @@ ste_mii_readreg(sc, frame)
 	 * need to clock through 16 cycles to keep the PHY(s) in sync.
 	 */
 	if (ack) {
-		for(i = 0; i < 16; i++) {
+		for (i = 0; i < 16; i++) {
 			MII_CLR(STE_PHYCTL_MCLK);
 			DELAY(1);
 			MII_SET(STE_PHYCTL_MCLK);
@@ -328,18 +318,15 @@ fail:
 	DELAY(1);
 
 	if (ack)
-		return(1);
-	return(0);
+		return (1);
+	return (0);
 }
 
 /*
  * Write to a PHY register through the MII.
  */
 static int
-ste_mii_writereg(sc, frame)
-	struct ste_softc		*sc;
-	struct ste_mii_frame	*frame;
-	
+ste_mii_writereg(struct ste_softc *sc, struct ste_mii_frame *frame)
 {
 
 	/*
@@ -349,7 +336,7 @@ ste_mii_writereg(sc, frame)
 	frame->mii_stdelim = STE_MII_STARTDELIM;
 	frame->mii_opcode = STE_MII_WRITEOP;
 	frame->mii_turnaround = STE_MII_TURNAROUND;
-	
+
 	/*
  	 * Turn on data output.
 	 */
@@ -375,16 +362,14 @@ ste_mii_writereg(sc, frame)
 	 */
 	MII_CLR(STE_PHYCTL_MDIR);
 
-	return(0);
+	return (0);
 }
 
 static int
-ste_miibus_readreg(dev, phy, reg)
-	device_t		dev;
-	int			phy, reg;
+ste_miibus_readreg(device_t dev, int phy, int reg)
 {
-	struct ste_softc	*sc;
-	struct ste_mii_frame	frame;
+	struct ste_softc *sc;
+	struct ste_mii_frame frame;
 
 	sc = device_get_softc(dev);
 
@@ -397,16 +382,14 @@ ste_miibus_readreg(dev, phy, reg)
 	frame.mii_regaddr = reg;
 	ste_mii_readreg(sc, &frame);
 
-	return(frame.mii_data);
+	return (frame.mii_data);
 }
 
 static int
-ste_miibus_writereg(dev, phy, reg, data)
-	device_t		dev;
-	int			phy, reg, data;
+ste_miibus_writereg(device_t dev, int phy, int reg, int data)
 {
-	struct ste_softc	*sc;
-	struct ste_mii_frame	frame;
+	struct ste_softc *sc;
+	struct ste_mii_frame frame;
 
 	sc = device_get_softc(dev);
 	bzero((char *)&frame, sizeof(frame));
@@ -417,15 +400,14 @@ ste_miibus_writereg(dev, phy, reg, data)
 
 	ste_mii_writereg(sc, &frame);
 
-	return(0);
+	return (0);
 }
 
 static void
-ste_miibus_statchg(dev)
-	device_t		dev;
+ste_miibus_statchg(device_t dev)
 {
-	struct ste_softc	*sc;
-	struct mii_data		*mii;
+	struct ste_softc *sc;
+	struct mii_data *mii;
 
 	sc = device_get_softc(dev);
 
@@ -436,30 +418,26 @@ ste_miibus_statchg(dev)
 	} else {
 		STE_CLRBIT2(sc, STE_MACCTL0, STE_MACCTL0_FULLDUPLEX);
 	}
-
-	return;
 }
- 
+
 static int
-ste_ifmedia_upd(ifp)
-	struct ifnet		*ifp;
+ste_ifmedia_upd(struct ifnet *ifp)
 {
-	struct ste_softc	*sc;
+	struct ste_softc *sc;
 
 	sc = ifp->if_softc;
 	STE_LOCK(sc);
 	ste_ifmedia_upd_locked(ifp);
 	STE_UNLOCK(sc);
 
-	return(0);	
+	return (0);
 }
 
 static void
-ste_ifmedia_upd_locked(ifp)
-	struct ifnet		*ifp;
+ste_ifmedia_upd_locked(struct ifnet *ifp)
 {
-	struct ste_softc	*sc;
-	struct mii_data		*mii;
+	struct ste_softc *sc;
+	struct mii_data *mii;
 
 	sc = ifp->if_softc;
 	STE_LOCK_ASSERT(sc);
@@ -474,12 +452,10 @@ ste_ifmedia_upd_locked(ifp)
 }
 
 static void
-ste_ifmedia_sts(ifp, ifmr)
-	struct ifnet		*ifp;
-	struct ifmediareq	*ifmr;
+ste_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
-	struct ste_softc	*sc;
-	struct mii_data		*mii;
+	struct ste_softc *sc;
+	struct mii_data *mii;
 
 	sc = ifp->if_softc;
 	mii = device_get_softc(sc->ste_miibus);
@@ -489,15 +465,12 @@ ste_ifmedia_sts(ifp, ifmr)
 	ifmr->ifm_active = mii->mii_media_active;
 	ifmr->ifm_status = mii->mii_media_status;
 	STE_UNLOCK(sc);
-
-	return;
 }
 
 static void
-ste_wait(sc)
-	struct ste_softc		*sc;
+ste_wait(struct ste_softc *sc)
 {
-	register int		i;
+	int i;
 
 	for (i = 0; i < STE_TIMEOUT; i++) {
 		if (!(CSR_READ_4(sc, STE_DMACTL) & STE_DMACTL_DMA_HALTINPROG))
@@ -506,8 +479,6 @@ ste_wait(sc)
 
 	if (i == STE_TIMEOUT)
 		device_printf(sc->ste_dev, "command never completed!\n");
-
-	return;
 }
 
 /*
@@ -515,10 +486,9 @@ ste_wait(sc)
  * it a command.
  */
 static int
-ste_eeprom_wait(sc)
-	struct ste_softc		*sc;
+ste_eeprom_wait(struct ste_softc *sc)
 {
-	int			i;
+	int i;
 
 	DELAY(1000);
 
@@ -531,10 +501,10 @@ ste_eeprom_wait(sc)
 
 	if (i == 100) {
 		device_printf(sc->ste_dev, "eeprom failed to come ready\n");
-		return(1);
+		return (1);
 	}
 
-	return(0);
+	return (0);
 }
 
 /*
@@ -542,18 +512,13 @@ ste_eeprom_wait(sc)
  * data is stored in the EEPROM in network byte order.
  */
 static int
-ste_read_eeprom(sc, dest, off, cnt, swap)
-	struct ste_softc		*sc;
-	caddr_t			dest;
-	int			off;
-	int			cnt;
-	int			swap;
+ste_read_eeprom(struct ste_softc *sc, caddr_t dest, int off, int cnt, int swap)
 {
-	int			err = 0, i;
-	u_int16_t		word = 0, *ptr;
+	uint16_t word, *ptr;
+	int err = 0, i;
 
 	if (ste_eeprom_wait(sc))
-		return(1);
+		return (1);
 
 	for (i = 0; i < cnt; i++) {
 		CSR_WRITE_2(sc, STE_EEPROM_CTL, STE_EEOPCODE_READ | (off + i));
@@ -561,24 +526,23 @@ ste_read_eeprom(sc, dest, off, cnt, swap)
 		if (err)
 			break;
 		word = CSR_READ_2(sc, STE_EEPROM_DATA);
-		ptr = (u_int16_t *)(dest + (i * 2));
+		ptr = (uint16_t *)(dest + (i * 2));
 		if (swap)
 			*ptr = ntohs(word);
 		else
-			*ptr = word;	
+			*ptr = word;
 	}
 
-	return(err ? 1 : 0);
+	return (err ? 1 : 0);
 }
 
 static void
-ste_setmulti(sc)
-	struct ste_softc	*sc;
+ste_setmulti(struct ste_softc *sc)
 {
-	struct ifnet		*ifp;
-	int			h = 0;
-	u_int32_t		hashes[2] = { 0, 0 };
-	struct ifmultiaddr	*ifma;
+	struct ifnet *ifp;
+	struct ifmultiaddr *ifma;
+	uint32_t hashes[2] = { 0, 0 };
+	int h;
 
 	ifp = sc->ste_ifp;
 	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
@@ -613,8 +577,6 @@ ste_setmulti(sc)
 	CSR_WRITE_2(sc, STE_MAR3, (hashes[1] >> 16) & 0xFFFF);
 	STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_ALLMULTI);
 	STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_MULTIHASH);
-
-	return;
 }
 
 #ifdef DEVICE_POLLING
@@ -650,7 +612,7 @@ ste_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 		ste_start_locked(ifp);
 
 	if (cmd == POLL_AND_CHECK_STATUS) {
-		u_int16_t status;
+		uint16_t status;
 
 		status = CSR_READ_2(sc, STE_ISR_ACK);
 
@@ -675,12 +637,11 @@ ste_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 #endif /* DEVICE_POLLING */
 
 static void
-ste_intr(xsc)
-	void			*xsc;
+ste_intr(void *xsc)
 {
-	struct ste_softc	*sc;
-	struct ifnet		*ifp;
-	u_int16_t		status;
+	struct ste_softc *sc;
+	struct ifnet *ifp;
+	uint16_t status;
 
 	sc = xsc;
 	STE_LOCK(sc);
@@ -738,8 +699,6 @@ ste_intr(xsc)
 		ste_start_locked(ifp);
 
 	STE_UNLOCK(sc);
-
-	return;
 }
 
 static void
@@ -770,20 +729,19 @@ ste_rxeoc(struct ste_softc *sc)
  * the higher level protocols.
  */
 static int
-ste_rxeof(sc)
-	struct ste_softc		*sc;
+ste_rxeof(struct ste_softc *sc)
 {
-        struct mbuf		*m;
-        struct ifnet		*ifp;
-	struct ste_chain_onefrag	*cur_rx;
-	int			total_len = 0, count=0, rx_npkts = 0;
-	u_int32_t		rxstat;
+        struct mbuf *m;
+        struct ifnet *ifp;
+	struct ste_chain_onefrag *cur_rx;
+	uint32_t rxstat;
+	int total_len = 0, count = 0, rx_npkts = 0;
 
 	STE_LOCK_ASSERT(sc);
 
 	ifp = sc->ste_ifp;
 
-	while((rxstat = sc->ste_cdata.ste_rx_head->ste_ptr->ste_status)
+	while ((rxstat = sc->ste_cdata.ste_rx_head->ste_ptr->ste_status)
 	      & STE_RXSTAT_DMADONE) {
 #ifdef DEVICE_POLLING
 		if (ifp->if_capenable & IFCAP_POLLING) {
@@ -824,7 +782,7 @@ ste_rxeof(sc)
 			continue;
 		}
 
-		/* No errors; receive the packet. */	
+		/* No errors; receive the packet. */
 		m = cur_rx->ste_mbuf;
 		total_len = cur_rx->ste_ptr->ste_status & STE_RXSTAT_FRAMELEN;
 
@@ -858,11 +816,10 @@ ste_rxeof(sc)
 }
 
 static void
-ste_txeoc(sc)
-	struct ste_softc	*sc;
+ste_txeoc(struct ste_softc *sc)
 {
-	u_int8_t		txstat;
-	struct ifnet		*ifp;
+	struct ifnet *ifp;
+	uint8_t txstat;
 
 	ifp = sc->ste_ifp;
 
@@ -893,22 +850,19 @@ ste_txeoc(sc)
 		ste_init_locked(sc);
 		CSR_WRITE_2(sc, STE_TX_STATUS, txstat);
 	}
-
-	return;
 }
 
 static void
-ste_txeof(sc)
-	struct ste_softc	*sc;
+ste_txeof(struct ste_softc *sc)
 {
-	struct ste_chain	*cur_tx;
-	struct ifnet		*ifp;
-	int			idx;
+	struct ifnet *ifp;
+	struct ste_chain *cur_tx;
+	int idx;
 
 	ifp = sc->ste_ifp;
 
 	idx = sc->ste_cdata.ste_tx_cons;
-	while(idx != sc->ste_cdata.ste_tx_prod) {
+	while (idx != sc->ste_cdata.ste_tx_prod) {
 		cur_tx = &sc->ste_cdata.ste_tx_chain[idx];
 
 		if (!(cur_tx->ste_ptr->ste_ctl & STE_TXCTL_DMADONE))
@@ -928,12 +882,11 @@ ste_txeof(sc)
 }
 
 static void
-ste_stats_update(xsc)
-	void			*xsc;
+ste_stats_update(void *xsc)
 {
-	struct ste_softc	*sc;
-	struct ifnet		*ifp;
-	struct mii_data		*mii;
+	struct ste_softc *sc;
+	struct ifnet *ifp;
+	struct mii_data *mii;
 
 	sc = xsc;
 	STE_LOCK_ASSERT(sc);
@@ -963,8 +916,6 @@ ste_stats_update(xsc)
 	if (sc->ste_timer > 0 && --sc->ste_timer == 0)
 		ste_watchdog(sc);
 	callout_reset(&sc->ste_stat_callout, hz, ste_stats_update, sc);
-
-	return;
 }
 
 
@@ -973,14 +924,13 @@ ste_stats_update(xsc)
  * IDs against our list and return a device name if we find a match.
  */
 static int
-ste_probe(dev)
-	device_t		dev;
+ste_probe(device_t dev)
 {
-	struct ste_type		*t;
+	struct ste_type *t;
 
 	t = ste_devs;
 
-	while(t->ste_name != NULL) {
+	while (t->ste_name != NULL) {
 		if ((pci_get_vendor(dev) == t->ste_vid) &&
 		    (pci_get_device(dev) == t->ste_did)) {
 			device_set_desc(dev, t->ste_name);
@@ -989,7 +939,7 @@ ste_probe(dev)
 		t++;
 	}
 
-	return(ENXIO);
+	return (ENXIO);
 }
 
 /*
@@ -997,13 +947,12 @@ ste_probe(dev)
  * setup and ethernet/BPF attach.
  */
 static int
-ste_attach(dev)
-	device_t		dev;
+ste_attach(device_t dev)
 {
-	struct ste_softc	*sc;
-	struct ifnet		*ifp;
-	int			error = 0, rid;
-	u_char			eaddr[6];
+	struct ste_softc *sc;
+	struct ifnet *ifp;
+	u_char eaddr[6];
+	int error = 0, rid;
 
 	sc = device_get_softc(dev);
 	sc->ste_dev = dev;
@@ -1132,7 +1081,7 @@ fail:
 	if (error)
 		ste_detach(dev);
 
-	return(error);
+	return (error);
 }
 
 /*
@@ -1143,11 +1092,10 @@ fail:
  * allocated.
  */
 static int
-ste_detach(dev)
-	device_t		dev;
+ste_detach(device_t dev)
 {
-	struct ste_softc	*sc;
-	struct ifnet		*ifp;
+	struct ste_softc *sc;
+	struct ifnet *ifp;
 
 	sc = device_get_softc(dev);
 	KASSERT(mtx_initialized(&sc->ste_mtx), ("ste mutex not initialized"));
@@ -1187,25 +1135,22 @@ ste_detach(dev)
 
 	mtx_destroy(&sc->ste_mtx);
 
-	return(0);
+	return (0);
 }
 
 static int
-ste_newbuf(sc, c, m)
-	struct ste_softc	*sc;
-	struct ste_chain_onefrag	*c;
-	struct mbuf		*m;
+ste_newbuf(struct ste_softc *sc, struct ste_chain_onefrag *c, struct mbuf *m)
 {
-	struct mbuf		*m_new = NULL;
+	struct mbuf *m_new = NULL;
 
 	if (m == NULL) {
 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
 		if (m_new == NULL)
-			return(ENOBUFS);
+			return (ENOBUFS);
 		MCLGET(m_new, M_DONTWAIT);
 		if (!(m_new->m_flags & M_EXT)) {
 			m_freem(m_new);
-			return(ENOBUFS);
+			return (ENOBUFS);
 		}
 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
 	} else {
@@ -1221,16 +1166,15 @@ ste_newbuf(sc, c, m)
 	c->ste_ptr->ste_frag.ste_addr = vtophys(mtod(m_new, caddr_t));
 	c->ste_ptr->ste_frag.ste_len = (1536 + ETHER_VLAN_ENCAP_LEN) | STE_FRAG_LAST;
 
-	return(0);
+	return (0);
 }
 
 static int
-ste_init_rx_list(sc)
-	struct ste_softc	*sc;
+ste_init_rx_list(struct ste_softc *sc)
 {
-	struct ste_chain_data	*cd;
-	struct ste_list_data	*ld;
-	int			i;
+	struct ste_chain_data *cd;
+	struct ste_list_data *ld;
+	int i;
 
 	cd = &sc->ste_cdata;
 	ld = sc->ste_ldata;
@@ -1238,7 +1182,7 @@ ste_init_rx_list(sc)
 	for (i = 0; i < STE_RX_LIST_CNT; i++) {
 		cd->ste_rx_chain[i].ste_ptr = &ld->ste_rx_list[i];
 		if (ste_newbuf(sc, &cd->ste_rx_chain[i], NULL) == ENOBUFS)
-			return(ENOBUFS);
+			return (ENOBUFS);
 		if (i == (STE_RX_LIST_CNT - 1)) {
 			cd->ste_rx_chain[i].ste_next =
 			    &cd->ste_rx_chain[0];
@@ -1255,16 +1199,15 @@ ste_init_rx_list(sc)
 
 	cd->ste_rx_head = &cd->ste_rx_chain[0];
 
-	return(0);
+	return (0);
 }
 
 static void
-ste_init_tx_list(sc)
-	struct ste_softc	*sc;
+ste_init_tx_list(struct ste_softc *sc)
 {
-	struct ste_chain_data	*cd;
-	struct ste_list_data	*ld;
-	int			i;
+	struct ste_chain_data *cd;
+	struct ste_list_data *ld;
+	int i;
 
 	cd = &sc->ste_cdata;
 	ld = sc->ste_ldata;
@@ -1283,15 +1226,12 @@ ste_init_tx_list(sc)
 
 	cd->ste_tx_prod = 0;
 	cd->ste_tx_cons = 0;
-
-	return;
 }
 
 static void
-ste_init(xsc)
-	void			*xsc;
+ste_init(void *xsc)
 {
-	struct ste_softc	*sc;
+	struct ste_softc *sc;
 
 	sc = xsc;
 	STE_LOCK(sc);
@@ -1300,11 +1240,10 @@ ste_init(xsc)
 }
 
 static void
-ste_init_locked(sc)
-	struct ste_softc	*sc;
+ste_init_locked(struct ste_softc *sc)
 {
-	int			i;
-	struct ifnet		*ifp;
+	struct ifnet *ifp;
+	int i;
 
 	STE_LOCK_ASSERT(sc);
 	ifp = sc->ste_ifp;
@@ -1394,7 +1333,7 @@ ste_init_locked(sc)
 	/* Disable interrupts if we are polling. */
 	if (ifp->if_capenable & IFCAP_POLLING)
 		CSR_WRITE_2(sc, STE_IMR, 0);
-	else   
+	else
 #endif
 	/* Enable interrupts. */
 	CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
@@ -1408,16 +1347,13 @@ ste_init_locked(sc)
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
 	callout_reset(&sc->ste_stat_callout, hz, ste_stats_update, sc);
-
-	return;
 }
 
 static void
-ste_stop(sc)
-	struct ste_softc	*sc;
+ste_stop(struct ste_softc *sc)
 {
-	int			i;
-	struct ifnet		*ifp;
+	struct ifnet *ifp;
+	int i;
 
 	STE_LOCK_ASSERT(sc);
 	ifp = sc->ste_ifp;
@@ -1432,8 +1368,8 @@ ste_stop(sc)
 	STE_SETBIT2(sc, STE_DMACTL, STE_DMACTL_TXDMA_STALL);
 	STE_SETBIT2(sc, STE_DMACTL, STE_DMACTL_RXDMA_STALL);
 	ste_wait(sc);
-	/* 
-	 * Try really hard to stop the RX engine or under heavy RX 
+	/*
+	 * Try really hard to stop the RX engine or under heavy RX
 	 * data chip will write into de-allocated memory.
 	 */
 	ste_reset(sc);
@@ -1455,15 +1391,12 @@ ste_stop(sc)
 	}
 
 	bzero(sc->ste_ldata, sizeof(struct ste_list_data));
-
-	return;
 }
 
 static void
-ste_reset(sc)
-	struct ste_softc	*sc;
+ste_reset(struct ste_softc *sc)
 {
-	int			i;
+	int i;
 
 	STE_SETBIT4(sc, STE_ASICCTL,
 	    STE_ASICCTL_GLOBAL_RESET|STE_ASICCTL_RX_RESET|
@@ -1481,25 +1414,20 @@ ste_reset(sc)
 
 	if (i == STE_TIMEOUT)
 		device_printf(sc->ste_dev, "global reset never completed\n");
-
-	return;
 }
 
 static int
-ste_ioctl(ifp, command, data)
-	struct ifnet		*ifp;
-	u_long			command;
-	caddr_t			data;
+ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 {
-	struct ste_softc	*sc;
-	struct ifreq		*ifr;
-	struct mii_data		*mii;
-	int			error = 0;
+	struct ste_softc *sc;
+	struct ifreq *ifr;
+	struct mii_data *mii;
+	int error = 0;
 
 	sc = ifp->if_softc;
 	ifr = (struct ifreq *)data;
 
-	switch(command) {
+	switch (command) {
 	case SIOCSIFFLAGS:
 		STE_LOCK(sc);
 		if (ifp->if_flags & IFF_UP) {
@@ -1513,7 +1441,7 @@ ste_ioctl(ifp, command, data)
 			    sc->ste_if_flags & IFF_PROMISC) {
 				STE_CLRBIT1(sc, STE_RX_MODE,
 				    STE_RXMODE_PROMISC);
-			} 
+			}
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 			    (ifp->if_flags ^ sc->ste_if_flags) & IFF_ALLMULTI)
 				ste_setmulti(sc);
@@ -1547,14 +1475,14 @@ ste_ioctl(ifp, command, data)
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
 			error = ether_poll_register(ste_poll, ifp);
 			if (error)
-				return(error);
+				return (error);
 			STE_LOCK(sc);
 			/* Disable interrupts */
 			CSR_WRITE_2(sc, STE_IMR, 0);
 			ifp->if_capenable |= IFCAP_POLLING;
 			STE_UNLOCK(sc);
 			return (error);
-			
+
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
@@ -1573,19 +1501,16 @@ ste_ioctl(ifp, command, data)
 		break;
 	}
 
-	return(error);
+	return (error);
 }
 
 static int
-ste_encap(sc, c, m_head)
-	struct ste_softc	*sc;
-	struct ste_chain	*c;
-	struct mbuf		*m_head;
+ste_encap(struct ste_softc *sc, struct ste_chain *c, struct mbuf *m_head)
 {
-	int			frag = 0;
-	struct ste_frag		*f = NULL;
-	struct mbuf		*m;
-	struct ste_desc		*d;
+	struct mbuf *m;
+	struct ste_desc *d;
+	struct ste_frag *f = NULL;
+	int frag = 0;
 
 	d = c->ste_ptr;
 	d->ste_ctl = 0;
@@ -1623,14 +1548,13 @@ encap_retry:
 	d->ste_frags[frag - 1].ste_len |= STE_FRAG_LAST;
 	d->ste_ctl = 1;
 
-	return(0);
+	return (0);
 }
 
 static void
-ste_start(ifp)
-	struct ifnet		*ifp;
+ste_start(struct ifnet *ifp)
 {
-	struct ste_softc	*sc;
+	struct ste_softc *sc;
 
 	sc = ifp->if_softc;
 	STE_LOCK(sc);
@@ -1639,13 +1563,12 @@ ste_start(ifp)
 }
 
 static void
-ste_start_locked(ifp)
-	struct ifnet		*ifp;
+ste_start_locked(struct ifnet *ifp)
 {
-	struct ste_softc	*sc;
-	struct mbuf		*m_head = NULL;
-	struct ste_chain	*cur_tx;
-	int			idx;
+	struct ste_softc *sc;
+	struct ste_chain *cur_tx;
+	struct mbuf *m_head = NULL;
+	int idx;
 
 	sc = ifp->if_softc;
 	STE_LOCK_ASSERT(sc);
@@ -1658,7 +1581,7 @@ ste_start_locked(ifp)
 
 	idx = sc->ste_cdata.ste_tx_prod;
 
-	while(sc->ste_cdata.ste_tx_chain[idx].ste_mbuf == NULL) {
+	while (sc->ste_cdata.ste_tx_chain[idx].ste_mbuf == NULL) {
 		/*
 		 * We cannot re-use the last (free) descriptor;
 		 * the chip may not have read its ste_next yet.
@@ -1691,7 +1614,7 @@ ste_start_locked(ifp)
 
 			/* Set TX polling interval to start TX engine */
 			CSR_WRITE_1(sc, STE_TX_DMAPOLL_PERIOD, 64);
-		  
+
 			STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_UNSTALL);
 			ste_wait(sc);
 		}else{
@@ -1712,14 +1635,12 @@ ste_start_locked(ifp)
 		sc->ste_timer = 5;
 	}
 	sc->ste_cdata.ste_tx_prod = idx;
-
-	return;
 }
 
 static void
 ste_watchdog(struct ste_softc *sc)
 {
-	struct ifnet		*ifp;
+	struct ifnet *ifp;
 
 	ifp = sc->ste_ifp;
 	STE_LOCK_ASSERT(sc);
@@ -1736,15 +1657,12 @@ ste_watchdog(struct ste_softc *sc)
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		ste_start_locked(ifp);
-
-	return;
 }
 
 static int
-ste_shutdown(dev)
-	device_t		dev;
+ste_shutdown(device_t dev)
 {
-	struct ste_softc	*sc;
+	struct ste_softc *sc;
 
 	sc = device_get_softc(dev);
 
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index 68d96741e8d..8de19614302 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -96,7 +96,7 @@
 
 #define STE_LATE_COLLS  0x75
 #define STE_MULTI_COLLS	0x76
-#define STE_SINGLE_COLLS 0x77	
+#define STE_SINGLE_COLLS 0x77
 
 #define STE_DMACTL_RXDMA_STOPPED	0x00000001
 #define STE_DMACTL_TXDMA_CMPREQ		0x00000002
@@ -386,27 +386,27 @@
 
 
 struct ste_stats {
-	u_int32_t		ste_rx_bytes;
-	u_int32_t		ste_tx_bytes;
-	u_int16_t		ste_tx_frames;
-	u_int16_t		ste_rx_frames;
-	u_int8_t		ste_carrsense_errs;
-	u_int8_t		ste_late_colls;
-	u_int8_t		ste_multi_colls;
-	u_int8_t		ste_single_colls;
-	u_int8_t		ste_tx_frames_defered;
-	u_int8_t		ste_rx_lost_frames;
-	u_int8_t		ste_tx_excess_defers;
-	u_int8_t		ste_tx_abort_excess_colls;
-	u_int8_t		ste_tx_bcast_frames;
-	u_int8_t		ste_rx_bcast_frames;
-	u_int8_t		ste_tx_mcast_frames;
-	u_int8_t		ste_rx_mcast_frames;
+	uint32_t		ste_rx_bytes;
+	uint32_t		ste_tx_bytes;
+	uint16_t		ste_tx_frames;
+	uint16_t		ste_rx_frames;
+	uint8_t			ste_carrsense_errs;
+	uint8_t			ste_late_colls;
+	uint8_t			ste_multi_colls;
+	uint8_t			ste_single_colls;
+	uint8_t			ste_tx_frames_defered;
+	uint8_t			ste_rx_lost_frames;
+	uint8_t			ste_tx_excess_defers;
+	uint8_t			ste_tx_abort_excess_colls;
+	uint8_t			ste_tx_bcast_frames;
+	uint8_t			ste_rx_bcast_frames;
+	uint8_t			ste_tx_mcast_frames;
+	uint8_t			ste_rx_mcast_frames;
 };
 
 struct ste_frag {
-	u_int32_t		ste_addr;
-	u_int32_t		ste_len;
+	uint32_t		ste_addr;
+	uint32_t		ste_len;
 };
 
 #define STE_FRAG_LAST		0x80000000
@@ -415,14 +415,14 @@ struct ste_frag {
 #define STE_MAXFRAGS	8
 
 struct ste_desc {
-	u_int32_t		ste_next;
-	u_int32_t		ste_ctl;
+	uint32_t		ste_next;
+	uint32_t		ste_ctl;
 	struct ste_frag		ste_frags[STE_MAXFRAGS];
 };
 
 struct ste_desc_onefrag {
-	u_int32_t		ste_next;
-	u_int32_t		ste_status;
+	uint32_t		ste_next;
+	uint32_t		ste_status;
 	struct ste_frag		ste_frag;
 };
 
@@ -472,8 +472,8 @@ struct ste_desc_onefrag {
 #define STE_NEXT(x, y)		(x + 1) % y
 
 struct ste_type {
-	u_int16_t		ste_vid;
-	u_int16_t		ste_did;
+	uint16_t		ste_vid;
+	uint16_t		ste_did;
 	char			*ste_name;
 };
 
@@ -486,7 +486,7 @@ struct ste_chain {
 	struct ste_desc		*ste_ptr;
 	struct mbuf		*ste_mbuf;
 	struct ste_chain	*ste_next;
-	u_int32_t		ste_phys;
+	uint32_t		ste_phys;
 };
 
 struct ste_chain_onefrag {
@@ -515,7 +515,7 @@ struct ste_softc {
 	device_t		ste_miibus;
 	device_t		ste_dev;
 	int			ste_tx_thresh;
-	u_int8_t		ste_link;
+	uint8_t			ste_link;
 	int			ste_if_flags;
 	int			ste_timer;
 	struct ste_chain	*ste_tx_prev;
@@ -523,7 +523,7 @@ struct ste_softc {
 	struct ste_chain_data	ste_cdata;
 	struct callout		ste_stat_callout;
 	struct mtx		ste_mtx;
-	u_int8_t		ste_one_phy;
+	uint8_t			ste_one_phy;
 #ifdef DEVICE_POLLING
 	int			rxcycles;
 #endif
@@ -534,12 +534,12 @@ struct ste_softc {
 #define	STE_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->ste_mtx, MA_OWNED)
 
 struct ste_mii_frame {
-	u_int8_t		mii_stdelim;
-	u_int8_t		mii_opcode;
-	u_int8_t		mii_phyaddr;
-	u_int8_t		mii_regaddr;
-	u_int8_t		mii_turnaround;
-	u_int16_t		mii_data;
+	uint8_t			mii_stdelim;
+	uint8_t			mii_opcode;
+	uint8_t			mii_phyaddr;
+	uint8_t			mii_regaddr;
+	uint8_t			mii_turnaround;
+	uint16_t		mii_data;
 };
 
 /*

From 3070a40c8ab14afabd3b58f9f848dc874d6fbb02 Mon Sep 17 00:00:00 2001
From: Andrew Gallatin 
Date: Thu, 14 Jan 2010 20:59:02 +0000
Subject: [PATCH 1119/2592] MFC 202119: Fix reporting of 10G Twinax media

---
 sys/dev/mxge/if_mxge.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index e0de0d7a50a..9d356ef7210 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -2774,6 +2774,7 @@ static struct mxge_media_type mxge_xfp_media_types[] =
 };
 static struct mxge_media_type mxge_sfp_media_types[] =
 {
+	{IFM_10G_TWINAX,      0,	"10GBASE-Twinax"},
 	{0,		(1 << 7),	"Reserved"},
 	{IFM_10G_LRM,	(1 << 6),	"10GBASE-LRM"},
 	{IFM_10G_LR, 	(1 << 5),	"10GBASE-LR"},
@@ -2908,7 +2909,7 @@ mxge_media_probe(mxge_softc_t *sc)
 		if (mxge_verbose)
 			device_printf(sc->dev, "%s:%s\n", cage_type,
 				      mxge_media_types[0].name);
-		mxge_set_media(sc, IFM_10G_CX4);
+		mxge_set_media(sc, mxge_media_types[0].flag);
 		return;
 	}
 	for (i = 1; i < mxge_media_type_entries; i++) {

From ed0e6c2a44d7a3cf979fe5b059bd0d02cac7b7d7 Mon Sep 17 00:00:00 2001
From: Andrew Gallatin 
Date: Thu, 14 Jan 2010 21:10:36 +0000
Subject: [PATCH 1120/2592] MFC r202121:  Use better default RSS hash (src +
 dst, rather than just src port)

---
 sys/dev/mxge/if_mxge.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index 9d356ef7210..fc8d0ae8996 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -104,7 +104,7 @@ static int mxge_verbose = 0;
 static int mxge_lro_cnt = 8;
 static int mxge_ticks;
 static int mxge_max_slices = 1;
-static int mxge_rss_hash_type = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
+static int mxge_rss_hash_type = MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT;
 static int mxge_always_promisc = 0;
 static int mxge_initial_mtu = ETHERMTU_JUMBO;
 static int mxge_throttle = 0;
@@ -4175,7 +4175,7 @@ mxge_fetch_tunables(mxge_softc_t *sc)
 	sc->pause = mxge_flow_control;
 	if (mxge_rss_hash_type < MXGEFW_RSS_HASH_TYPE_IPV4 
 	    || mxge_rss_hash_type > MXGEFW_RSS_HASH_TYPE_MAX) {
-		mxge_rss_hash_type = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
+		mxge_rss_hash_type = MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT;
 	}
 	if (mxge_initial_mtu > ETHERMTU_JUMBO ||
 	    mxge_initial_mtu < ETHER_MIN_LEN)

From 1d2d3276c2dab0b7680c21de966a5846f63eb36e Mon Sep 17 00:00:00 2001
From: Andrew Gallatin 
Date: Thu, 14 Jan 2010 21:30:06 +0000
Subject: [PATCH 1121/2592] MFC: r202120:  Update mxge(4) firmware to 1.4.48b
 (latest available) from Myricom.

---
 sys/dev/mxge/eth_z8e.h      | 14280 ++++++++++++-------------
 sys/dev/mxge/ethp_z8e.h     | 14357 ++++++++++++-------------
 sys/dev/mxge/rss_eth_z8e.h  | 19007 ++++++++++++++++-----------------
 sys/dev/mxge/rss_ethp_z8e.h | 19175 +++++++++++++++++-----------------
 4 files changed, 33883 insertions(+), 32936 deletions(-)

diff --git a/sys/dev/mxge/eth_z8e.h b/sys/dev/mxge/eth_z8e.h
index 5f60c1e9c66..929ce20d622 100644
--- a/sys/dev/mxge/eth_z8e.h
+++ b/sys/dev/mxge/eth_z8e.h
@@ -28,7033 +28,7255 @@ POSSIBILITY OF SUCH DAMAGE.
 $FreeBSD$
 ***************************************************************************/
 
-static unsigned int eth_z8e_uncompressed_length = 359956 ;
-static unsigned int eth_z8e_length = 112403 ;
-static unsigned char eth_z8e[112403 + 1] = 
-  "\x78\x9c\xec\xbd\x7f\x7c\x54\xd5\xb5\x37\xbc\x72\x32\xc0\x24\x8d"
-  "\x4c\xc4\x48\x47\x44\x1d\x14\xda\xa8\x41\xa2\x62\x8b\x16\x24\x4a"
-  "\xb4\xd0\xcb\x8f\xa8\x60\xd3\x8a\x26\x68\x82\x41\x23\x44\x88\x10"
-  "\x30\x64\xc2\x80\x36\xa1\x40\x52\x49\x21\x40\x48\x62\x8b\x82\x2d"
-  "\x48\x04\xda\xe6\xf6\xa2\x8e\x25\xbe\x1f\x7a\x9b\x64\x62\x5f\xfa"
-  "\x1a\x7d\xb0\x1d\xb8\x91\xa6\x3c\x01\x46\x32\x90\x31\x99\x99\xfd"
-  "\x7c\xd7\xde\xe7\x24\x33\xc3\x04\xe5\xf6\x7e\xde\xe7\x9f\xe6\xf3"
-  "\x99\x9c\x73\xf6\xd9\x7b\xed\xb5\xd7\x5e\x7b\xed\xb5\xf6\x5e\x7b"
-  "\x1d\xa2\x7f\xe2\x4f\xdb\xd7\xf8\xcf\x14\xff\xd7\xdf\xbf\xfe\xfe"
-  "\xf5\xf7\xaf\xbf\x7f\xfd\xfd\xeb\xef\x5f\x7f\xff\x77\xfe\xce\x6b"
-  "\x26\xfa\x43\x25\x51\x8f\xc3\x6c\x75\xd3\xb9\xe2\xad\x9b\x85\x1f"
-  "\xc9\x31\x6e\x32\x5b\xf9\xaa\xff\xe8\x35\xa4\x6b\x95\x64\xbe\x39"
-  "\x91\x12\xa6\xed\x24\xaa\x1a\x29\xba\x36\x6f\x11\x9e\xb5\x5b\x44"
-  "\x57\xfa\x1b\x44\x4d\x63\x89\x36\x8f\x14\x5e\xc0\x99\xef\xa6\x1f"
-  "\x75\x30\x9c\xb5\x78\xe6\xf7\xeb\x46\x0a\x0f\xd2\x0b\xdd\xf4\xe3"
-  "\xf9\x9c\xbe\x66\x24\x60\x25\x11\x39\xb6\x08\x5f\x08\x5c\x33\x97"
-  "\x67\x98\xe9\x63\x24\x3e\xbb\x22\xe0\x30\x8c\x46\xc0\x38\x76\x19"
-  "\x18\x09\x06\x5e\x5e\x8d\x62\x18\x5e\xb7\x83\xac\x5e\x87\xf3\x5a"
-  "\x94\xf5\xa2\x4d\xc9\x5c\xb6\x02\x79\x84\x83\x62\x9b\x8a\xfc\x64"
-  "\xbb\x99\x62\x4e\x51\xdc\x3f\x70\xd5\x70\xfd\x8c\xdb\xbb\x56\x95"
-  "\x1b\xcb\x30\x50\x36\xa6\xc7\x11\x97\xda\x5f\x16\xb0\x6d\x25\x64"
-  "\x42\xde\x77\xbc\x9a\x53\x53\x79\x13\xe3\xf4\xbc\x1a\xf2\xce\x37"
-  "\xf2\xaa\x77\xda\x0c\xfd\xdd\x37\xf0\xae\x28\xfc\x9d\xe9\x35\xfd"
-  "\x5d\x02\xde\x55\x45\xe0\x67\x72\xf5\xfa\x09\xf5\x30\x2e\x36\x37"
-  "\xae\x47\xd0\x33\x3a\x6e\x8c\x53\x13\xf2\x97\x72\xfe\x74\x9b\xf0"
-  "\xcf\xb5\x91\xc4\x85\x69\x87\xbc\xd3\x8f\xd4\xab\xbc\xb8\x1f\xcd"
-  "\xe5\xf5\x7b\x1b\xee\x65\xba\x5e\xef\xd5\x3d\x8e\xf8\x84\x70\x9c"
-  "\x88\xf4\x77\x23\xf0\x2e\x39\xfc\xdd\x7b\xa9\xfa\xbb\x6f\xe2\x5d"
-  "\x7a\xf8\xbb\x18\xa3\x9c\x15\xef\xb2\x8d\x77\xa1\xfd\xa4\x38\xce"
-  "\x84\xdf\x10\x33\xd1\x50\xfc\x86\x99\x8d\xbe\x5b\x66\x15\x41\xfb"
-  "\x75\x64\x12\xeb\xb7\x94\x05\x1d\x82\x5c\x45\x3e\xb2\x8d\x22\xfb"
-  "\x49\x8a\x6f\x03\x5c\xda\xb4\x8a\xcc\xf6\x02\xe1\x73\x15\x75\x51"
-  "\xab\xa7\x8b\xec\x1e\xd1\xe9\xf2\x5f\xa0\x92\x0b\x64\x76\xf9\xcf"
-  "\x50\xc9\x8b\x64\x6d\x2a\xfe\x9c\xa2\xf1\x45\x50\x13\x64\x1f\xcd"
-  "\x65\x3b\xa8\xb5\xa6\x83\xec\x35\xe1\x65\xed\x37\x90\xb5\x05\xcf"
-  "\xa0\xb9\x85\xf1\x68\xb2\xf9\xc9\x1f\xbf\xa5\xac\x78\x1b\x99\xec"
-  "\x63\x48\x6b\xc9\x71\xea\xb8\x7c\xa3\x9a\x71\x59\x77\x9a\xcc\xbf"
-  "\x5c\x88\xbe\x3f\xcd\xf8\xd6\x96\xed\x5f\xe5\xd3\x8e\x58\x67\xd2"
-  "\x11\xeb\x71\x6a\xb2\x4e\xa1\xa6\xa2\x74\xda\x74\x9a\x12\x8e\xf8"
-  "\x26\x53\x93\xe9\x61\x8c\x8d\x74\x72\x75\xe1\xde\x16\x40\x1e\x2f"
-  "\xd9\x96\x13\xfa\xf5\x1b\x65\x55\xcf\x91\xd9\xad\x60\xa2\x3f\xbf"
-  "\x51\xf5\x41\x21\x11\xd3\x8c\x9f\xa3\xb5\x63\xd9\x75\x64\x05\x7e"
-  "\x9d\xc0\xe5\x5e\xe0\xd2\x32\xd6\x4a\xa9\xc0\x79\x98\xab\xda\x4f"
-  "\xa6\x62\x8a\x1b\x64\x4c\x24\x05\x1d\x72\x6c\x76\xd5\x6e\x11\x9d"
-  "\xcc\x5b\xdd\x2f\x67\x62\x7c\x25\x98\x50\xf7\x2e\xae\x6f\x13\xc6"
-  "\xa8\xfd\x75\x32\x75\xaf\xc8\x8c\xa9\xdb\x22\x3a\xf0\xce\x66\xbc"
-  "\x03\xbf\x77\xe0\x7d\xe7\x84\x24\x4a\x74\xf9\xd3\xe8\xfd\xde\x4e"
-  "\x13\xc3\x18\xee\xa5\x18\x86\x67\x29\xa2\x58\xb4\x67\x08\xf0\xf9"
-  "\xa2\x0e\xe9\xb7\x20\x1f\xca\xa3\xff\xd7\xef\xe1\xf2\xe2\x9b\x4f"
-  "\x78\x83\xdf\x7c\xe2\x42\x70\xeb\x13\xdd\x62\xeb\x13\xe7\x03\x5b"
-  "\x9f\xf8\xc2\xbe\x92\xcc\x81\x6f\x3e\xe1\x69\x2d\x90\x7d\x90\xd8"
-  "\x5a\x80\x3e\x08\x90\x79\xf5\x19\x4a\x7c\xea\x45\xf4\xbd\xff\x33"
-  "\x5a\xbd\x88\xac\xc1\xb8\x9d\x69\x2e\xff\x5f\xe8\xa9\x62\x12\xb8"
-  "\xcf\x88\xd6\xbe\xee\xf8\xda\xa3\x8a\x67\xcd\xdc\xa6\x76\xb7\xf6"
-  "\x73\x39\x26\x3c\x71\x6f\x1e\xc5\xaf\x19\xbf\x36\xfc\x8e\x89\xf8"
-  "\xda\x63\xa0\x95\x7d\xf8\x9a\x18\xaa\xed\x25\x9a\x10\xa4\x18\x74"
-  "\x91\x17\xf8\x27\x0e\x42\xb7\xd1\xc1\xf5\xef\x54\x7e\xbb\x94\x4a"
-  "\x7a\x7a\xf2\x88\x65\x0a\xcb\x13\x96\x2f\x3d\x8e\xab\xd2\x50\x8f"
-  "\x53\xf2\xfe\x16\xe1\x15\xf1\xef\x54\x22\xbd\xd3\xfb\x72\x5e\x8c"
-  "\xe7\xe5\x3c\xad\x3b\xfe\x9d\xcd\xc8\x93\x83\x3c\x3e\x9d\x86\x9d"
-  "\x0c\x0b\xe3\xc4\x73\x95\x9f\x62\x01\xb3\xe0\x77\x17\xdb\x4d\x3b"
-  "\xb7\x88\xe3\xc8\xb7\xa1\x1f\x16\x60\x03\x0e\xe8\x7f\x55\xbd\x91"
-  "\x06\x5a\x77\x6c\x44\x3e\x2e\xef\xf2\xa5\xb1\xdc\x75\xbb\xf2\x3b"
-  "\xc9\xe2\xa7\x78\xd1\xa7\xea\x43\x9e\x4e\x96\x8f\x57\xf9\x68\x68"
-  "\x8f\x83\x32\x18\x36\x97\x73\x75\x75\x12\xca\x6d\x16\xf6\x3c\xc8"
-  "\x25\x9a\xdd\x23\xf2\x62\x20\x8b\x3b\x8e\xa0\xbc\xaa\x7b\xb8\xd9"
-  "\xc0\x91\xeb\xe0\xbe\x96\x78\x82\x1f\x8e\xe4\xfb\xe8\xaa\x6a\x8a"
-  "\x45\xb9\xc7\x18\x1e\xc3\x02\x1f\xb8\xd1\xd6\xcd\x47\xf2\x3d\x14"
-  "\x14\x61\x30\xdd\x3a\xbc\xcc\x30\x78\x48\x17\x80\xc7\xfc\xd7\x84"
-  "\x32\x57\xd5\x4b\x78\x8f\xfe\x2e\xc8\xf0\x7c\x64\xb2\x49\x7c\x1f"
-  "\x67\x18\x3d\x2c\xd3\x00\xd3\xb9\xfc\x41\xea\xa2\xe1\x4e\x8f\x3d"
-  "\x2f\xb6\xb5\x98\x88\xcb\xef\x2f\xe9\x1c\x22\xba\x33\x63\x99\xe7"
-  "\xf8\xbd\xcb\x7f\x9e\xf3\xbc\x2e\xba\xf3\x62\xaf\xea\x22\x13\xe3"
-  "\x8c\xf2\x45\x8c\x67\x68\x5f\x3e\xfa\xd0\xe3\x53\xe8\xf1\xf4\x19"
-  "\xe9\x53\x68\xd6\x03\xd3\xa6\x50\xea\xbd\xe3\x53\xef\xfe\xee\xa4"
-  "\xbb\x29\xe3\x87\x8f\x4e\xa1\x8c\xd9\x53\xe8\x31\xfc\x32\x1f\x9e"
-  "\x81\x87\x69\x53\xee\x4c\xfd\xfe\xf8\x8c\x69\x33\x1e\xa2\x47\xe6"
-  "\xde\x95\x7a\xd7\x5d\xf4\xc0\x43\x33\xef\x4c\x4d\xd5\xaf\x77\xa6"
-  "\x72\x96\x1f\x4f\x7a\xe8\xb1\xf1\x19\x4b\x97\x14\x2e\x19\x3f\x7b"
-  "\xc6\xb4\xd0\x39\x31\x39\x70\x31\xc8\x34\xf5\x8a\x73\xd3\x29\x08"
-  "\x19\x51\x8b\xbe\xc6\xaf\xcb\x59\x72\x12\x63\x3d\x71\x75\x2d\xf7"
-  "\x91\x94\x93\xc3\x8f\x63\x7c\x9b\x7a\x1c\x96\x75\x6e\x6d\xcb\x24"
-  "\xa6\x15\xe6\x1e\xe4\xb9\x76\x01\xde\x9d\xd0\x65\xf3\x10\xbc\xdf"
-  "\x15\xfe\xfe\xea\x22\xbc\xff\x7b\xab\x8d\xc8\x85\x1f\xe8\xeb\x85"
-  "\xcc\x03\x1d\x3d\xd4\x6d\xcf\x1c\x02\x3e\x8e\x41\x1d\x1d\x18\x83"
-  "\x6d\x28\xeb\x0e\x19\xdb\x1d\xe8\x87\x36\xdb\x2a\x8a\x3d\x4b\x96"
-  "\x7f\x6f\x2d\x4c\x23\xee\x0f\x57\xa1\x0e\xe3\x42\x3f\x8c\x78\x09"
-  "\x03\x7d\x0c\x38\xc7\x14\x9c\xc4\xe4\x10\x39\xe0\x66\x38\x9b\xf0"
-  "\x4e\x87\x15\x68\x85\x3c\x80\xbc\x7e\x2d\x68\x4f\x26\x11\xbf\xa5"
-  "\x32\xd8\x97\x2c\xe7\x16\x94\xcb\x36\xf8\x17\xf9\xbd\x4d\x05\xc8"
-  "\xf7\xcb\xe9\x31\xe8\xef\x18\xcc\x9d\x68\x8b\x25\x1f\x7c\xec\x0d"
-  "\xae\x7f\xb3\x5d\xf4\x64\x92\x4a\x4b\xdc\x2b\xe2\xf1\xbc\xfe\xcd"
-  "\x4f\x84\x1d\x69\xab\x64\xda\x3e\x4e\x43\xdf\xc6\xf2\x18\x14\x2f"
-  "\xcb\xf4\x58\xd0\x62\x0c\xf0\x6b\x0f\x70\xf9\x73\xb2\xfc\x30\xa4"
-  "\xc5\x20\xef\x27\xc1\xf8\x37\x3f\x05\xaf\x70\x1a\xe6\xf3\x6b\x4b"
-  "\x01\xef\x7f\x05\x45\x26\x09\xf3\xf9\x46\xdc\x1f\x77\xae\xea\xa2"
-  "\x53\x05\xa4\xb9\xf1\x2e\x68\x07\xcc\xbe\xfe\xfa\xdb\xb8\x2c\xea"
-  "\x32\xf5\xf4\xe5\x61\x0e\x4d\x3c\xc6\xba\x40\x80\xf1\x39\xd7\x9f"
-  "\xc7\xc9\x75\xf2\x38\x46\x5f\x74\xa1\x9f\xe2\x7a\x1c\x57\xcf\x8c"
-  "\xe8\xa7\x1c\xc0\xf9\x04\x74\x6f\x07\x8c\xc3\xc1\x6e\xd4\x81\x67"
-  "\xc0\xd5\x74\xb8\x06\x0c\xaf\xe2\x83\xab\x37\x44\xf0\xc1\x43\x80"
-  "\x7d\x21\xe4\xfd\xde\x88\xf7\xb7\xe2\x7d\xaf\xfe\x1e\xe3\xe9\xea"
-  "\xe6\x88\xfa\x3b\xf1\x3e\x88\xfa\xbd\x18\x2f\xb1\xa8\x2f\xa3\x96"
-  "\xf5\xb4\x81\xfc\xfe\xf0\xfc\x23\xac\xdd\x0e\x0b\xcb\x10\x96\x85"
-  "\x32\x7f\x9d\xce\xab\xaa\xfe\x11\x29\x11\xf9\xc1\xc3\x96\x61\xe0"
-  "\x07\xbe\x5e\x83\x3c\xc3\x20\x8b\x4c\x98\x37\x8e\x1f\x29\x66\xbd"
-  "\x6d\xc4\xfc\x88\xfc\xc5\xc8\x37\x8a\xe9\x28\x69\x70\x4e\xd2\x20"
-  "\x43\xd7\xb3\x78\x2c\x98\x51\xa6\x32\xa2\x4c\x03\xca\xdc\x1c\x54"
-  "\x74\x8b\xed\xe9\x8e\x5a\xa6\x29\xa2\x4c\x87\xec\x7f\x55\x8f\x89"
-  "\xf9\xc5\x28\x23\x65\x4b\x5f\x18\x0c\x6e\x1b\xf4\xb1\x6b\xcc\xe1"
-  "\x30\x92\x3a\x50\xef\x6d\x1b\xd5\x38\xfe\x06\xfa\xfc\x2e\xa4\xfd"
-  "\x05\x70\x3f\x63\x3e\x61\x5e\x76\x79\x7c\x90\x7d\xd3\x13\xd4\x1c"
-  "\x7e\xcd\x22\x4b\x31\xf1\xfd\x78\xbe\x67\xd8\xa2\x6f\xa6\xce\xe3"
-  "\xd7\x2c\xc2\x95\xd3\x65\x9d\x3c\xb6\x44\xdf\xbf\x05\x15\xcc\x6b"
-  "\x36\x62\x0c\x6a\x78\x0e\xe8\x75\xb4\xe0\x39\x06\xfc\xf9\x29\xe4"
-  "\x2a\x78\x72\x3a\xf3\xdb\x44\xa4\x7f\xa8\xbf\x7f\x97\xf3\xe3\xfe"
-  "\x4e\xfd\x9e\xf9\xf2\x53\x9d\x2f\xc1\xe7\x49\xbf\x91\x75\x4b\x5e"
-  "\x57\xe5\x83\x8a\xaf\xa7\xe1\xdd\xeb\xb8\xce\xc0\x75\x23\xae\x8f"
-  "\xe0\xba\xc8\x7e\x81\xac\xf6\x00\xf4\x08\xf5\x3c\x0f\xd7\x47\x71"
-  "\x7d\x00\xd7\xc7\x70\x1d\xcf\xe3\xd2\xb3\x22\x8f\x22\x78\xa2\x2b"
-  "\xa8\xc6\xe2\x30\xd5\x1f\x49\xa3\xf5\xf1\xa1\xc6\xe7\xb9\x81\x34"
-  "\xa1\xd2\x34\xc8\xf3\x81\xb4\xbe\xe9\x4c\x97\x0c\xb4\xdd\xc7\xf5"
-  "\xeb\xe3\x7a\x88\xea\x17\x95\x27\xa8\xca\xe9\x7d\xa7\xa7\xa9\x7c"
-  "\x31\xa1\x75\xba\xe9\x9a\xe6\x12\xaf\x10\xb8\x36\x32\x5d\x91\x7e"
-  "\x18\x34\x81\x3e\x73\xcd\x06\xa6\xd3\x40\x7f\x5f\x93\x1c\xd2\xdf"
-  "\xd0\x67\x93\x7c\xe1\xfd\x9d\x98\xc1\x34\xe3\xfe\x36\xf0\x65\xdc"
-  "\x31\xa7\xf0\x3c\x35\x54\xe1\x9f\x98\x01\xb9\xde\xc5\x7d\x1f\x5b"
-  "\xc0\xe3\xe1\xda\xc9\x6e\xda\x25\x65\x22\xbf\xf3\xc6\x1d\x48\xe4"
-  "\xf2\xb1\xf9\xf2\x5d\x26\xe4\x65\xbb\xf1\x8e\xeb\xe6\x71\x18\x5b"
-  "\x28\xdf\x15\x1a\xe5\x20\x33\x1b\x64\x59\xcc\x71\x3c\xe7\xf3\xdc"
-  "\x8d\x39\xb4\x13\x79\xaa\xdd\x74\x55\xe2\x60\xf6\x8d\x28\xdb\x52"
-  "\x3f\xbe\x94\xb4\x5b\x4a\x69\x88\xcb\x7f\x9c\xe6\xf8\x45\x60\x3c"
-  "\x51\x9c\xcb\x3f\x99\x6e\x25\xba\xda\xe5\x3f\x46\x68\xf0\x18\x97"
-  "\xbf\x0a\x73\xe4\x3a\x7e\xff\xfe\x6d\x14\x13\x83\xab\xfd\x76\xd2"
-  "\x62\x5c\xfe\x5d\x48\x3f\x44\xb7\x90\x29\xe6\xfb\x43\x44\x8f\xcb"
-  "\x3f\x11\xcf\x85\xf4\xf0\x10\xf1\xb7\xac\x00\x25\xce\x7c\x45\xd8"
-  "\x5d\xfe\x1c\x7a\xf8\x95\xa0\x70\xf9\x9b\xf1\x2e\x9f\xe6\x04\xbe"
-  "\x14\x73\x02\x3d\x42\x98\xb7\x34\xcc\x09\x9c\xc3\xfd\xdf\x04\x68"
-  "\x89\xeb\xfb\xf8\xd9\x85\x0b\xba\xae\x28\xdf\x52\x9f\xb5\x52\xa3"
-  "\x3e\xcc\x2b\x22\x6e\x4b\x03\xda\xe7\xec\x13\x79\xb1\x98\x13\xde"
-  "\xef\xeb\xc3\x75\xfd\x96\xf7\xe4\x73\xd9\x96\x36\xc0\x71\xde\x01"
-  "\xc5\x9f\xf1\x77\xf9\x3b\x28\x0b\xb2\x63\xce\x4a\x8f\x60\xdc\x87"
-  "\xaf\x11\x34\x67\xe5\xfb\x02\x72\xcb\x32\x67\xa5\x5d\xe0\x9d\x19"
-  "\xf0\x9c\x2e\x7f\x17\xd7\xd1\x06\x78\x2d\x12\x5e\xd9\x16\x0f\xf2"
-  "\x7a\x38\x5f\x28\x1c\x86\xc1\x79\xe7\x04\xc8\x82\xfc\x9e\xbe\xf2"
-  "\x2d\xee\xbe\xf2\xad\x84\x5f\xaa\x88\xdf\xfa\x60\xd0\x91\xf4\x01"
-  "\xcf\x51\xa2\x6c\x6b\x06\x9e\xb3\xbf\x04\x9f\x48\x3a\x06\x68\x98"
-  "\x28\xdf\x9a\x81\x3e\x4f\xef\x91\xf8\x6e\x2d\x95\xf8\xae\xdf\x6a"
-  "\xff\x52\xb6\x63\x6b\x89\x6a\xc7\xd6\xd5\x9c\xee\x05\xdf\xe2\xbe"
-  "\xde\xab\xde\xd5\xa1\xdc\x5c\x59\xae\x6c\x6b\xbd\x30\x6f\x6d\x00"
-  "\x0f\xc6\xce\x09\x88\x52\xa6\x21\xe8\x5a\xca\x74\x64\xbb\x05\x75"
-  "\xd4\x8b\xb8\xad\x0d\xc0\xc7\x89\xf2\x7f\xee\x13\x3c\x6f\x6e\x75"
-  "\x7f\xa9\x60\xff\x0d\x70\xe6\xf7\x30\x4c\xf3\x56\x37\x60\x79\xfc"
-  "\x9a\x0d\xf4\x10\xbe\x39\xfe\x35\xfe\xac\x95\x14\xeb\xf2\x7f\x48"
-  "\xc9\xa5\xa5\x31\xae\xa2\x42\xb4\x73\x03\x60\xe6\xe0\x3d\x5d\x83"
-  "\xba\xde\x07\x5c\x37\xd7\x87\x3a\x3c\x80\x79\x06\xb0\x72\x18\xa7"
-  "\x5e\x07\x25\x8a\xf8\x6a\xea\x95\xf8\x55\xdb\x82\x65\xd5\x69\x41"
-  "\x73\x75\xaa\xc1\x3f\xcc\x3b\x8a\x6e\xcc\x33\xfb\x38\x2d\xd1\xe0"
-  "\x93\x40\x59\x75\xe2\xed\x44\x89\xb3\xbd\xc2\xcf\xbc\x32\x81\x0a"
-  "\x62\x5a\xbd\xc7\x40\x6b\x33\xb5\x16\x1c\xa2\xdb\x88\xed\x27\x2f"
-  "\xb5\x7a\xab\xf0\xbc\x93\x18\xbf\x56\xef\x3a\x6a\xe9\xda\x45\xb3"
-  "\x0b\xbc\x6b\x02\xe6\xea\xca\x96\xae\x59\x84\xf2\xef\x03\xc7\xe0"
-  "\x53\x05\xa6\xd2\xd6\x02\x2f\x3f\xdb\x5b\xba\xc0\x9f\x01\x11\xf0"
-  "\x97\x55\x93\xdf\x5c\x5d\x3f\xfb\x82\xf0\xcc\xea\x2a\x1d\x82\xb4"
-  "\x3e\x4b\x8c\xf0\x5b\x8a\xec\xa2\xa5\x6b\x03\x3d\x75\x81\x62\x5a"
-  "\xf2\x0e\x49\x3e\x7d\xaa\xa0\x80\x64\xf9\x0b\x7e\xcb\x93\x5d\xa5"
-  "\xf4\x64\x1e\x0d\x47\xfe\x73\xcc\xb3\x62\x78\x29\x35\x77\xe4\xd3"
-  "\xac\x33\xfe\xd8\xd9\x17\xfa\x44\x73\x76\x15\xb5\xe4\x55\x81\x1e"
-  "\xd5\x36\xb6\x33\x66\x9d\xe9\x16\xb3\x2f\xf4\x88\x96\xbc\x7d\xd4"
-  "\x9c\x7d\x88\x66\x7e\xee\xb4\x04\xca\xab\x13\x83\x71\xd5\xa9\xc1"
-  "\xf2\xea\xb4\x40\x5c\x75\xa5\xbf\x1c\xb8\xc4\x55\xd7\x8b\xf5\xdb"
-  "\x60\xc3\x60\x6e\x97\xfd\xbb\x6d\x38\xee\x6d\xb2\x7f\xcd\xdb\x6c"
-  "\xa2\x6c\x5b\x5a\x5f\xf9\xb6\x54\xc9\xf7\x71\xdb\x6c\x2e\x3f\xf3"
-  "\xff\xb6\x34\xe4\x4b\x53\x3c\xb2\x2d\x43\xf1\xfe\xb6\x39\xdc\xaf"
-  "\xc8\x9b\x8d\x5f\x01\x7e\xd0\x45\xb6\x41\xa7\xa2\xab\x19\x6e\xb0"
-  "\x6c\x9b\x3b\x68\xde\x86\xf1\xb0\xcd\x03\xbb\x44\x6b\xf5\xee\xa2"
-  "\x00\x64\x6b\xab\x37\x40\xb3\x5f\xf4\xa1\x6f\xd1\x07\x45\x01\xd0"
-  "\xf3\x38\x3d\xf5\x22\xd9\x5d\x45\xc7\x49\xbc\x57\xc9\xf4\xb0\xcc"
-  "\x7e\xf1\x7d\x11\x2c\xdf\xe6\xe6\xf7\xb3\x5f\xb4\xc3\x36\x02\x9c"
-  "\xb8\x6d\x9e\xe0\xfa\xed\x89\xba\xae\x04\x3c\xb6\x5b\x18\x8f\xbe"
-  "\x1e\xf0\x18\xe6\x71\x11\xb7\xdd\x86\xb4\xd7\x78\xee\x08\x32\xdf"
-  "\x95\x6d\xaf\x14\xe6\xed\x9e\x59\x43\x84\x27\xf0\x2a\x49\x1e\x08"
-  "\xde\x2f\x04\xdb\x5e\x59\x45\x54\x2f\xc7\x54\x60\x54\x29\xca\x79"
-  "\x44\xf9\xf6\xca\xe0\xfa\x9d\x77\x01\x4e\xac\x58\xc1\x65\x77\xa6"
-  "\x2a\x9e\xf9\x4c\x8e\x3d\x51\xbe\x33\xf5\xeb\xda\xf9\x3d\x8e\x51"
-  "\xc5\x6e\x7a\x3b\x93\x65\x1c\xee\xcb\xdc\xb4\x3f\x45\xbf\xaf\x72"
-  "\x53\xd5\x71\x29\x1f\x21\xe7\x0a\x4a\xe8\xda\xd3\x74\xfd\x74\xd0"
-  "\x84\x70\x9f\x80\xfb\x99\x73\x6e\x45\xbb\xcb\x3e\xeb\x44\x9f\xf7"
-  "\xb0\xcc\x11\x8e\x89\xd0\x37\x28\x0d\xed\x35\x8b\x9e\xe4\x04\x11"
-  "\xbf\x7b\xa1\xe8\xb3\xb2\x2d\x69\xc1\xf3\x70\xd0\x75\x2c\xae\x23"
-  "\x76\x5e\xa4\x24\xfc\xac\x3b\x1d\xc1\x52\x96\xc9\xb8\x4f\x15\x2b"
-  "\xac\xf1\x9b\x96\x53\x8a\xc5\x4b\xe6\x3a\x47\x30\xd3\xb2\x26\x91"
-  "\x6d\xaa\x24\xbe\x17\x8e\x6d\x54\x77\x91\x4c\x3c\xb7\x04\xe3\x50"
-  "\x5f\x91\x45\x88\x65\xc9\x54\xb7\x14\xf2\xc8\x41\xd6\x3a\x87\x68"
-  "\x08\xf4\x24\x6b\x8c\xa7\x81\x0b\xe3\x06\x3c\x6f\x00\x9e\xf3\xe7"
-  "\xad\x4c\xa3\x0f\x8b\x28\xea\x5a\x44\x8f\xe3\xfa\xfe\xf6\x0f\xf2"
-  "\xbe\xc6\xa0\xc9\x20\xef\x0f\x1b\x74\x1a\xcc\xde\xe7\x71\x1e\xb8"
-  "\x28\x3c\x15\x8b\x89\x69\x61\xb5\xfb\xc5\x7f\xc1\x26\x29\x2d\x09"
-  "\xd0\x0d\x73\x56\xde\x24\x5c\x1e\xe1\x74\x15\x9d\x91\xeb\x75\x75"
-  "\xc8\x53\xe2\x17\x41\xb6\x6f\xd9\xb6\xad\x62\x5b\xb5\x7c\xf7\x74"
-  "\x51\xbe\x3b\xbd\x7b\xb9\xf0\xd7\x4a\x7b\x74\x74\xaa\x9b\xee\x29"
-  "\x50\x7d\x53\x6d\xc3\x5c\xd8\xd1\x6d\xde\x9d\x0e\xd8\x57\x33\xec"
-  "\xd6\x02\xe1\x0c\xc6\xed\x9e\x89\x7c\x98\xff\x7e\x5f\x19\xba\x66"
-  "\x87\x79\xad\x6b\xdd\x16\x9e\xdb\x46\x63\xfe\xbb\x69\xee\x25\x6b"
-  "\x42\x72\x75\x91\xd0\x2f\xb6\x81\x45\xc9\x18\x9d\x7d\x8c\xbf\x44"
-  "\xfc\xd2\xa2\xbf\x1e\x98\x1b\xab\xeb\xbb\x61\x77\xd9\x57\xd3\x68"
-  "\xf4\xc3\xf5\xa7\x69\xf4\x3f\xec\x45\xe2\x94\x70\x8c\x2e\xfd\xe5"
-  "\x2a\x1f\x74\x82\xd1\x5e\x37\xad\xc9\x1b\x7c\x6e\x85\x5c\xbc\x28"
-  "\x3a\x2b\x96\xf7\xd3\xec\xc4\x9c\x95\x41\xc1\xf7\x3c\xce\xea\x90"
-  "\xce\xf4\xe8\x71\xdc\x30\xd9\xa0\xc5\x20\xf4\x37\x89\xb2\xdd\x99"
-  "\x4a\x07\xbc\xa1\x46\x38\x04\x39\x6f\xe4\x75\xbc\x1b\x76\x4a\x3d"
-  "\xa8\x6c\x5b\x6a\x37\xe4\x08\xaf\x77\x40\x67\xf6\x2e\xb3\x0a\x1f"
-  "\x60\x56\xba\x69\x9c\x5b\xb7\xb3\xbc\x2e\xff\x43\x2c\x53\x52\x07"
-  "\x5b\x27\x1d\x80\x7f\xe3\xe1\x56\x68\x44\x2c\x93\x84\xf9\xc0\xdc"
-  "\x12\x85\xb7\x8f\xe1\x3a\x4b\xce\x53\x07\xde\x2f\xf3\x8a\x4e\x51"
-  "\x76\x60\x3a\xeb\x21\xce\xe5\xbd\x9c\xf6\x2e\x78\x58\x38\x97\x32"
-  "\x4e\x37\xbe\xeb\xbc\xb1\x97\x4e\x41\xc7\x83\x7e\xe7\x51\x36\xd7"
-  "\x8d\x7b\x8e\x14\x92\x6e\xc7\xdd\x08\xfb\xef\xdb\x7b\x0c\xbc\x20"
-  "\x3b\x04\xe8\x8b\xfa\x59\xee\x75\x11\xaf\xa1\x2d\x2b\x16\x3e\xe0"
-  "\x6a\x43\xde\xb9\x46\x1b\xb8\x7d\xaa\x5d\x37\xe6\x85\xb6\x0b\x38"
-  "\x78\xa0\x2f\x4b\x1a\x2c\x5b\x49\x66\x9b\xa2\xb5\x99\xdb\xcb\x6d"
-  "\xe1\x36\xcb\xb6\x40\xbf\xe0\x79\xc5\xe5\xbf\x07\xfa\x97\x4c\x4f"
-  "\x03\xac\x43\x6e\xfa\x56\xba\xd2\xad\x6e\x94\x7a\x5d\xd4\x7e\x34"
-  "\x6f\xf5\xd8\xbf\xa4\x1b\xed\x41\x71\xf2\x14\xdd\xc4\x3a\x6d\x2c"
-  "\x5f\xe5\x9c\xec\x03\xff\x9a\xf7\x8d\xe5\xb9\xd8\x55\x7c\x01\xf2"
-  "\x5b\xe6\xbd\x06\x79\x3b\x90\xe7\x4e\x3d\xef\x9d\x6a\x7d\x57\x5e"
-  "\x87\xf1\x15\x73\xf3\x19\xf0\xee\x74\x5e\x93\x00\x9d\x13\x8d\x67"
-  "\x81\x67\x5c\xd1\x57\xfb\xc6\x46\xc7\x65\xbb\x27\xa8\xc6\x62\x17"
-  "\xea\xf9\x26\xf3\x94\x7d\x25\x5d\x07\xbe\x3c\x51\xb2\x9a\xae\x61"
-  "\x7e\x12\x71\xbb\x73\x14\xdd\x6f\xaa\x12\x8e\x52\x72\x41\x7a\x16"
-  "\x2c\xa7\xeb\x31\xfe\xe6\x9f\xa6\x9b\xde\xca\x2a\xb6\x01\x57\xa2"
-  "\x8a\xb3\x44\x52\xd6\xc4\xed\xce\x76\xf9\x3f\xa7\xba\xb3\x6c\x6b"
-  "\xdd\x74\xd4\xe0\x45\xdc\x1f\xbb\x9c\x5c\x00\x5d\x0b\x94\xad\x60"
-  "\x7b\x80\xd7\xcb\x4e\x92\x2d\x85\xdb\x8b\x5f\x0c\xd2\x6e\x10\x17"
-  "\xc5\x7c\xc1\xfa\x1b\xe6\x2b\x37\xd9\x32\x71\x2d\x90\x3f\x07\x19"
-  "\xcf\xd9\xc8\x97\x20\x2e\x06\x39\x4f\x01\xd2\xc6\x0a\x47\x0c\x8f"
-  "\x89\xc3\x3d\x0e\x5b\x86\x9b\x26\x95\xa9\xbe\xb1\x8d\x66\x58\x83"
-  "\xe0\x90\x8d\xbe\x25\xe6\x4d\xc0\xfa\x77\x5b\x49\x0c\xe3\xb1\x51"
-  "\x8e\x0b\xc0\xaa\xd3\x94\x7c\xc6\xdc\x58\x50\xeb\x08\xe6\x41\x16"
-  "\xe7\x05\xd7\xef\x2f\x95\xf7\xfa\x3b\xc6\x03\x73\x5f\x41\x74\xf8"
-  "\x07\xe6\x3a\x47\x31\x8f\x8f\x49\x52\x70\x0e\x4c\x77\x8e\x3a\xcd"
-  "\xcf\xd7\xf2\xb3\xd7\xdc\x50\xea\xaa\x4e\x43\xfd\xa7\x51\xef\x98"
-  "\x24\x65\x03\x8c\xb9\xb6\x1b\x75\xf4\x38\xc6\x24\xb9\x29\xf9\x90"
-  "\x5a\x3b\x6c\x28\x1d\x64\xec\x25\xf2\xd8\x69\xa9\x21\x7d\x4c\xdf"
-  "\xfc\xef\xbc\x8e\x81\x76\x65\x04\xcc\xdb\x0a\x74\xb9\xc1\x76\xd5"
-  "\x37\x4e\xd2\xcd\x8d\xad\x79\x92\xbf\x35\xa1\x8d\x29\x7c\x3b\xe8"
-  "\xd1\x78\x7d\x57\x89\xaf\x9b\x1b\x2f\xfd\x8d\xd9\x85\xdf\x21\xfc"
-  "\x9c\xfa\x73\x33\x7e\x6e\xdc\xa7\x4a\xba\x75\xe7\xc0\xce\xb9\xb9"
-  "\x11\x73\x7d\x01\x3f\xbb\x69\xcc\x5e\xd1\x3d\x56\x0b\xea\xf7\xb5"
-  "\x5f\xb0\x8d\x31\xa6\x1d\xf4\xcf\x51\xfd\xc0\x30\x28\x06\x63\x91"
-  "\x69\x2e\xec\xd5\xc2\xd7\x54\xe2\x65\x9c\xcd\x4d\xd5\x5e\xb2\x7d"
-  "\x8b\xdb\x7e\x73\xc2\xb2\x6a\xe1\xf1\x82\xf6\x7c\xe5\xb6\x1d\xa9"
-  "\xf1\x13\xaf\x31\xf7\x38\x6e\x1e\xeb\xa6\xa7\xab\xa4\xcc\x8f\x3f"
-  "\x50\xc0\xf0\x44\x9c\xe4\x07\x61\xb4\x5d\xc9\xb3\x86\x52\xee\x47"
-  "\x3c\xff\x08\xed\xb6\x9c\xa5\x9b\x65\x7f\x1e\x41\xdb\x77\x42\xa6"
-  "\xb0\xed\x54\x27\xe5\xff\xcd\x90\xff\xb6\x26\x63\x3d\x74\x23\xde"
-  "\xc1\x6e\xea\x6a\xc9\xf3\x11\xc3\x08\x00\x76\x85\x5c\x13\xda\x5f"
-  "\xba\xba\x4b\xf8\xde\x2f\xe9\x34\x61\x3e\x46\x7f\x37\x94\x72\x9d"
-  "\x76\xe8\xc1\xce\xc5\xb2\xde\x34\xc8\x2a\x6f\xd4\xfe\xef\xc7\xed"
-  "\x96\x77\x8f\x8c\x95\x72\x31\x03\x3a\x56\x76\x78\xbf\xdc\x72\x58"
-  "\xf5\xc9\x2d\xe6\xf0\x3e\xb9\xe5\x30\x7e\x33\xf1\xcb\xc1\xaf\x50"
-  "\x7f\x0e\xfd\x4d\x0a\xb9\x5f\xd7\xe3\xb8\x25\x1d\x63\xdf\xad\x68"
-  "\xcd\x69\xc0\x95\x79\xe0\x0b\x32\xb3\xed\xcd\xfb\x0a\x9c\xce\xfc"
-  "\xca\xe9\x41\xe8\x25\x78\xce\xc4\xfb\x44\x1e\x8b\x15\x41\x0a\x7b"
-  "\xef\x5a\x07\x9e\x5a\xd5\xcb\xb8\xbf\x25\xd7\x0b\xd6\x94\x95\x31"
-  "\x1f\x22\xcf\x7c\x8b\xbf\xac\x0c\xf5\x1d\x32\xe8\x87\xb4\x1a\x7e"
-  "\x1f\x5d\x3f\xb8\xe5\x78\xbf\x1e\x05\xfd\x92\x65\x4b\x17\x8d\xed"
-  "\x84\xfc\x41\x5f\xed\x2f\x52\xf3\xc6\xd8\x7f\xf0\x33\xe4\xde\x09"
-  "\xdc\x77\xb4\x40\xbe\xf4\xae\x7f\xf3\x68\x9f\x46\xc3\x7a\x35\x4a"
-  "\xf3\xaf\xff\x6b\x82\x3f\xbe\xf6\x98\xab\xf3\x10\xb5\xfa\x0f\x90"
-  "\xed\x39\x09\xe3\x33\x17\xf3\xf3\x4a\x11\xd8\xdf\xbb\x07\xb6\xd6"
-  "\x39\x27\xe6\xd9\x9b\x4e\xd3\x58\xd9\xf6\x9f\x9e\xc4\x0c\xfe\x94"
-  "\x84\xad\xd3\xe2\xb3\xce\x4d\x0b\x85\x7f\xd3\x29\x8c\x8f\x3e\x6b"
-  "\xfc\xc6\x5e\x4a\xd9\xbe\x8a\x52\x6b\x7a\x69\x6c\x6d\x2f\x25\x8b"
-  "\xbf\x27\x6b\x35\xd0\xb5\x9e\xba\x90\x48\x18\xdf\x99\xc3\x0b\xc8"
-  "\x5c\xbb\x8a\x64\x9f\x07\xca\xa1\x73\xf9\xa1\x73\x9d\x4b\x66\x39"
-  "\xd7\xaf\x73\xf5\xf5\xb1\xce\xb5\xfb\xa8\xe2\x8b\xdd\x47\xaf\xca"
-  "\xa3\x98\x84\x6c\x4a\x04\x7e\xf6\xb3\x34\xf6\x86\x84\x0e\xe8\x7b"
-  "\x68\xb3\x5b\x6f\x2f\xae\xa9\x96\x3c\x1a\x26\xdb\x0a\xd9\x2b\xca"
-  "\xf7\x17\x0d\x3a\xa7\x6a\xcc\x3b\x5e\xde\x03\x42\x1b\xc6\xdd\xc3"
-  "\xfb\x18\x87\x46\xf9\x4c\xcb\x6a\xc0\x77\x48\x2f\x1c\x23\x7c\x48"
-  "\x1f\xcd\x75\x37\x20\xbd\xc7\x31\x2e\xdd\xad\xbd\xb6\x6b\x30\x79"
-  "\x6b\x59\x63\xcc\xfb\xe3\x3e\x14\x5a\x29\xeb\xdb\x89\xab\xfd\xc2"
-  "\xe3\x3a\xcb\x63\x70\x5c\xd3\x9c\x7c\xe1\xb7\x2d\xe6\x3d\xa5\x71"
-  "\x87\x78\xbf\x8b\xd7\xb9\xdf\x86\x9e\xf2\x55\x7b\x5c\x2c\xfb\xa1"
-  "\x8f\xdb\x2c\xf9\x80\x09\x7d\x5f\xd8\x93\x29\x5c\xf7\x8e\xae\x77"
-  "\xf3\xde\xe8\x66\xb9\x0f\x3b\x0e\xfc\xf3\xb0\xd4\xc3\x58\xdf\x63"
-  "\x19\x08\xbd\xe9\x9a\x53\xf4\xad\x49\x6c\xd7\xf7\x38\xbe\x35\xda"
-  "\x4d\xd3\x8c\x7d\x3d\xb9\xbf\x8b\x34\xe8\x7f\xe9\xf9\x9c\x56\x38"
-  "\x86\xac\x85\x36\xd1\x39\x98\xee\x23\xf7\x5c\x35\xfa\x26\xca\xe4"
-  "\x18\x70\x30\xdf\xfc\xaa\x5b\x9b\x37\x0f\x69\x45\x06\x1c\xe4\xb9"
-  "\x16\xcf\x65\xfd\x79\x54\x99\xea\x90\x32\xf3\xba\xb5\xdb\x7e\x85"
-  "\xb4\xbd\x11\x65\x0e\x47\x94\x69\x0e\x29\x53\xaa\xd7\xe3\x8e\x28"
-  "\xe3\x09\x2f\xf3\x6d\xba\x14\xb7\x6f\x27\x85\x97\xf9\xf6\xd8\x88"
-  "\x32\x13\x2f\xc5\xed\xdb\xd3\x23\xca\x64\x46\x94\xc9\x0b\xa1\x25"
-  "\xef\xad\xa6\x22\xad\x38\xa2\xcc\x86\x88\x32\x35\xc6\xf3\x60\x7b"
-  "\xdc\xcb\x76\x92\x15\x7c\xd9\xc9\xfd\x09\xbd\xbd\xab\x7b\xeb\xf3"
-  "\x3d\x7a\xd9\xf6\x28\xed\xea\x8a\xa8\xcf\x1f\x5e\x5f\x72\xc2\xa5"
-  "\xed\x4a\xb6\x85\x97\x49\x4e\x8d\x28\x93\x16\x52\xa6\x5e\xd5\x93"
-  "\x3c\x37\xa2\x4c\x4e\x44\x99\xc2\x4b\xf9\x2a\xb9\x2c\xa2\x4c\x75"
-  "\x44\x99\x3d\x5f\x41\x0b\x9e\x8f\x95\x2f\xc2\x48\xd6\x79\x1f\xc4"
-  "\x5c\x7f\xeb\xd5\x6c\xcb\x60\x2e\xf1\xfc\xb2\xd7\x37\x84\xe7\x14"
-  "\x9e\x7f\x8e\x14\xf9\xa0\x2f\x25\xfb\xdc\x74\x47\x81\x31\x07\xf1"
-  "\x3e\x26\x8f\x67\xa5\x2b\x27\xb7\x0f\xa6\x53\x72\x3d\x86\x6f\x02"
-  "\xd7\x75\x64\x34\xeb\x5e\xb7\xa6\xf7\xeb\xb6\x6a\xbf\x9e\x14\x9c"
-  "\x5b\xb7\x31\x1c\xae\xbf\x4e\xed\x8f\xc6\xb0\x6e\x7d\xa4\x48\x96"
-  "\x29\x0a\xd1\x87\xb9\x7e\xef\xa1\x55\x3e\x53\x38\x1e\xb7\x66\x5e"
-  "\x06\x8f\x04\xe8\x38\x93\x5a\xa1\x7f\xf0\x3e\x50\x4b\x0d\x74\x19"
-  "\xe8\xef\x8c\xdb\x49\xba\xd5\x2d\x75\xab\xc5\xbd\xc4\xf7\xae\xe2"
-  "\xfb\xe4\x3e\x91\xd2\x2d\x6f\xb3\x36\xa1\x7e\xd6\xc1\x9b\x0a\xce"
-  "\x53\xb7\xd4\xff\x59\x07\xbb\xed\xa1\x23\xc5\x1e\xe0\x75\x5b\xa2"
-  "\xb1\x6f\xea\xa6\xdb\xd2\xa5\xde\x50\x76\x20\x95\xf7\xb0\x78\xdd"
-  "\xf7\x88\x77\x12\xe7\x01\xff\xdf\x3a\xda\x68\x2f\x6c\x40\x8c\xa9"
-  "\x5b\xbb\x2e\x47\x33\xd5\x87\xb7\xe5\x87\xf3\xe4\x10\xf0\xca\x6d"
-  "\xa5\xe1\xfd\x7e\x5b\x65\x78\xbf\xdf\x56\x1f\xce\x93\x1a\x78\xf2"
-  "\xb6\x43\x11\x65\x9a\x22\xca\x1c\x0b\x29\x53\xa9\xd7\xd3\x19\x51"
-  "\xc6\x17\x5e\xe6\x76\x73\xc8\x33\xda\x78\xbb\xb5\xdf\x86\x91\x7b"
-  "\xf2\xb7\x27\x87\x3c\x6b\x55\x52\x7e\xde\x3e\xd9\x48\xe3\x7d\xb4"
-  "\xda\x2d\x6a\x4f\x58\x87\x97\x19\x31\xde\x39\x7f\x7e\x38\x0e\xb7"
-  "\x17\x47\xe0\xd0\x3f\xfe\x2b\x94\x0d\xf6\x87\x53\x94\x92\x23\x79"
-  "\x08\x63\x04\xf3\xf5\x1c\x7e\x06\xac\x6a\xe4\x07\x1d\x6e\x3f\x1c"
-  "\x01\xaf\x39\x02\xde\xf1\x90\xe7\x44\x3c\x77\x85\xb4\x21\x31\xd6"
-  "\x2a\xfd\x62\xa0\x8f\xa5\x98\x8c\x74\xb6\x0d\x81\x6f\xa7\x5d\xce"
-  "\x33\x69\xec\xeb\x30\xe2\x24\xdd\xfe\x05\xdb\x91\x0a\x66\x4a\xe8"
-  "\xf8\x27\xd5\xae\x94\xf4\x70\x3c\x52\xe6\x86\xe3\x91\x92\x13\xd2"
-  "\x2e\xaf\x65\x0d\x3d\x62\xf1\x3f\xfa\x23\xd6\x71\xd8\x87\x46\xfa"
-  "\x1c\xac\x86\x5e\x76\x81\x12\xd9\xd7\xe3\x54\x21\xc5\xba\x8a\x3a"
-  "\x61\x93\xed\x6e\x1a\x94\x9f\xe2\x0f\xa4\xe9\xfe\x29\xb0\x37\x53"
-  "\x9a\x0c\x7e\x0c\xae\x3f\x90\x16\x2c\x7f\x3b\x1f\x69\x90\x7f\xb7"
-  "\x65\xa8\x35\xf6\x7d\x8d\xc2\x9e\x59\x0d\x7a\xc2\xbe\x19\xff\xa1"
-  "\x6e\x0f\xcc\x65\x9f\x05\xc8\x9e\x4e\xcc\xef\x09\x6a\x7f\x6b\x7c"
-  "\x42\x08\x5f\x7b\x6d\xab\xa6\x8a\x93\x34\xfe\x23\x9e\xff\x79\x8c"
-  "\xb2\xef\xc3\x11\xbf\x87\xd8\x86\x76\xf9\x4f\x4b\x1d\x0d\xef\xdb"
-  "\xf4\xb2\xd3\x43\xca\x7a\x74\x1b\xb7\x93\xdf\x4d\xf0\x93\xe9\x88"
-  "\xd7\x43\x80\x93\xa4\xf4\xba\xf1\x1f\x1d\xc1\x78\x45\x99\x62\xa3"
-  "\x0c\xdb\xc3\x5c\xc6\x52\x48\xa6\x3b\x8a\xc9\xe4\x5c\x75\x52\xc2"
-  "\xd6\xfb\xbe\x93\xf5\x63\x57\x71\x27\xb9\xbc\xed\xbc\x36\x65\x52"
-  "\x7b\xc9\xe3\xdb\x62\x7d\x64\xee\x2e\x3f\x80\x3e\x19\xdf\x16\x28"
-  "\x3f\x30\x09\xb8\xc1\xfe\x4a\x91\x72\x2e\x94\x76\x0f\x3d\x94\xf1"
-  "\xe8\x9c\x59\xe3\x7f\xf8\xe8\x8c\xb9\x0f\xdd\x67\x9b\xbb\xe8\x85"
-  "\xdc\x9c\xf1\x4b\x5e\x2a\xb4\xad\x58\xba\xa8\x70\xd1\xe2\x67\x6d"
-  "\xa9\x45\xe3\x8a\x6c\x0b\x0a\xd5\x35\x39\x7f\xc1\xb2\xc2\x29\x7c"
-  "\x9b\x62\x2b\x58\x9a\xbb\x5c\xde\xde\x1a\x4f\xe1\x40\x16\x15\xe6"
-  "\x2e\xb5\x8d\xcb\x49\xb1\x3d\xbc\x60\x51\xfe\x4b\x4b\x73\xa3\xc2"
-  "\xba\xcf\xb6\x34\x77\x69\xee\x82\x1c\xdb\x14\x5b\x2a\x43\x0e\x05"
-  "\x17\xd2\x9f\xa9\xc6\x3c\xc6\xf3\x57\x85\x43\xb4\xe9\xf3\x99\x5b"
-  "\xf1\xcf\x1d\xbb\x2e\x9d\xcb\xee\x68\x0c\xe7\xb9\x3b\x8e\x86\xf3"
-  "\xdc\x1d\xed\x97\xce\x65\x77\x44\xcc\x7f\x77\x44\xcc\x7f\x13\x12"
-  "\x2e\x9d\xcb\x26\x44\xcc\x7f\x13\x22\xe6\xbf\x09\xfd\xf3\x1f\x78"
-  "\xc9\xbd\x56\xca\x85\x09\x11\xf3\xdf\x84\x88\xf9\x6f\x42\x61\xc4"
-  "\xf3\xba\x90\xe7\x6b\xf0\x5c\x15\x3a\x3f\xe2\x79\x97\x31\x3e\x07"
-  "\xe4\xcb\x84\x46\x23\x0f\xcb\x7a\xc8\xe6\x0e\x3d\x6f\x5b\x48\xde"
-  "\x4e\x3d\x6f\x47\xff\xf8\x03\x1f\xb1\x8f\x88\xb2\xbb\x53\x67\xb0"
-  "\x4c\x67\xff\x10\x9e\x9b\x30\x3e\x6e\x3a\x4b\x13\x3e\x60\x58\xcc"
-  "\xc3\x72\xfd\x70\xeb\x13\x3d\x75\x23\xc8\xcc\x65\xea\x5e\x23\x93"
-  "\x70\x8c\x3f\x8e\x2b\x21\x2d\x01\x3f\xc8\x94\xd4\x34\xb7\xb6\xb9"
-  "\x50\xcd\x17\xa9\x95\x52\xdf\x47\x19\x1d\xfe\xcf\xf8\x19\x70\xac"
-  "\x28\x63\xae\x50\x73\x71\x07\xee\x13\x98\xa7\x51\xde\x24\xb4\x3b"
-  "\xc6\xe0\x4a\x48\x4b\xc4\x2f\x09\xf0\x2a\x0d\x78\xbc\x0f\x16\x6d"
-  "\xfc\x47\xae\x2f\xf7\xdb\x7c\x1a\x59\x2a\x1c\xc1\x76\x57\x90\xf5"
-  "\xea\xd4\x26\xb5\x46\xf0\x66\xa7\x70\xbc\x9f\x59\x87\xf4\xe8\x36"
-  "\xd2\x9d\xd0\xff\x52\x1b\xd5\xba\xc9\x9d\xe8\xff\x87\x3b\xd4\xda"
-  "\xe6\x9b\x6c\x23\xf6\x9e\xa2\x3b\xdf\xc0\xb5\x0f\xd7\x72\x03\xbe"
-  "\x53\xda\xce\x77\xf2\x9a\xc7\x63\x0c\x37\x22\x7d\x32\xe4\x5b\xaf"
-  "\xc5\x5f\x9a\x19\xe5\x5d\xa6\x70\xc4\x3e\x1a\x25\x9d\x6d\xe9\x5e"
-  "\x37\xdd\xb9\x8b\xf1\x0d\x49\x2f\x13\x8e\xe1\x73\x39\xbf\x9b\xeb"
-  "\x43\x99\xc1\x74\x6d\xc3\x1f\x4c\xf9\x5d\xde\x79\x2c\xa2\x1d\x5f"
-  "\x9e\xa2\xbb\x1e\x51\xed\xb8\x6b\x5f\x44\xdd\x5d\xd1\xdb\x71\x97"
-  "\x09\xed\xf8\x32\x7a\x3b\xee\xb2\x49\xda\x6a\x68\x8b\x76\xc9\xbb"
-  "\xc9\x68\xcb\x97\x92\xee\xe1\xe9\x73\x75\x5d\xc8\x0b\x1b\x2c\x11"
-  "\xef\x64\xd9\xc7\x8a\x07\xfa\x4d\xcf\x57\x6c\xa9\xa6\x8c\x28\x75"
-  "\x56\x09\xc7\xb0\xc7\xdc\x74\x57\xb3\x84\x33\x90\xbe\x57\xe1\x02"
-  "\x3a\x69\x92\x4e\x5d\x5c\x6e\xb0\xfe\x36\xec\x12\xb5\xae\x71\x17"
-  "\x78\xf6\xce\x06\x63\x4d\x72\x59\xb1\xf0\x18\x74\xec\x71\xdc\x6d"
-  "\x8d\x78\xe7\x0b\x79\x37\x31\xec\xdd\xea\xfe\xf4\x99\x46\xfa\xd7"
-  "\xeb\xa7\xbb\x8b\x23\xfa\x09\xfd\x33\xf1\xaa\xf0\x76\xdf\xbd\x41"
-  "\xb5\x0f\x7d\x74\x09\xad\xef\xde\x83\x3e\xea\x8b\xde\x47\x77\x37"
-  "\x45\xe7\xb5\xbb\x8f\x4b\x78\x23\x28\x1a\x3c\x1f\xfa\xae\x4f\xf2"
-  "\xa0\xde\x4f\x97\xf6\xcf\xc4\xd1\x46\xff\x7c\xbd\x36\x4e\xcc\x8e"
-  "\x68\x63\x00\x30\x3e\x53\x6d\xbd\x67\x7c\x04\xec\xa2\xe8\xbc\x38"
-  "\xb1\x12\xed\x0c\x44\x6f\xe7\xc4\xbd\x83\xf3\xe2\xc4\xa3\x68\x4f"
-  "\xe0\x52\x5e\x44\xf7\xc9\x32\x14\xad\x8c\x5f\x38\xa2\xd5\x73\x4f"
-  "\x92\xdd\xcf\x7a\xee\x3d\x33\x79\x0d\x29\x24\x3d\x25\x9c\xff\xd0"
-  "\x06\x2e\xc7\xf4\xf3\x2b\x39\xcb\xfd\x70\xca\x46\xda\x57\xf1\x64"
-  "\x8f\xe3\x9e\x0d\x11\xb4\x3a\x77\x8a\xbe\x73\x55\xb7\x16\xb3\x4b"
-  "\xd1\xeb\x3b\x1f\x45\xe0\xb4\x27\x3a\xbd\xee\x71\x82\x5e\xe7\xa2"
-  "\xd3\xeb\x9e\xe3\x83\xd3\xeb\x1e\xee\xff\x73\x97\xd2\xeb\x3b\x89"
-  "\xa1\xf4\x82\xae\x2b\xdb\x77\x8b\x15\xbc\xd1\x97\x25\x78\x0d\x0e"
-  "\x34\x49\xb4\x80\x57\x54\x99\x2e\x2e\x93\x6e\xf1\x29\x3e\x81\x0e"
-  "\x69\x3e\x4b\xdf\x49\x31\xc6\xff\xf0\x6a\x1a\x26\xfa\x9e\x10\x80"
-  "\x17\xc3\xe5\x5c\x45\xe7\x9c\x2e\x7f\x2a\xb1\xfd\x11\x51\x6f\x59"
-  "\x74\x59\xf0\x9d\x7a\xd0\xf4\xb5\x28\xe9\x8d\xca\x27\xe4\x3b\x9e"
-  "\x70\x19\xf1\x9d\xb6\xf0\x3e\x02\xdd\x50\x8e\x06\x7c\xda\x2f\xfb"
-  "\xbb\x7c\x9f\x7d\x37\xed\xd2\x3e\xfb\xee\x09\xd5\x5f\xdf\xfd\x20"
-  "\x1c\xbf\xef\x66\x46\xef\xaf\xef\x16\x0c\xde\x5f\xdf\xdd\x30\x78"
-  "\x7f\x7d\x77\x0f\xf7\x97\x9b\xbe\xeb\x0e\x9f\x37\xbe\xeb\x0c\x6f"
-  "\x2f\xea\x45\x39\xa1\x0d\xbd\x86\x9f\xbf\x6e\xbb\x8d\x1f\xcb\x38"
-  "\xee\xab\xba\x12\x02\x2f\xc7\x8c\x61\x1c\xaf\x14\xc6\xa0\xb0\x41"
-  "\xc3\xca\x55\xd1\xf7\x47\xd9\xc6\x6d\xad\x26\xde\x0b\x27\xdb\x8d"
-  "\xac\xbb\x4f\xfa\x4d\x50\xa3\x76\xdc\x6b\xa7\xe8\xbe\x35\x41\x4d"
-  "\x2b\x66\x3f\x4b\xe9\x5f\x29\xd7\x10\x26\x35\x87\xf6\x05\xfb\xe2"
-  "\xb0\x6d\xba\x49\xd9\x4e\x7f\x3b\x45\xf7\xce\x53\xfd\x72\xdf\x82"
-  "\x70\x3a\x4e\xf2\x44\xef\x97\x7b\xcd\xe8\x97\xbf\x45\xef\x97\x7b"
-  "\xc7\x0e\xde\x2f\xf7\xa6\xa1\x5f\xfe\x76\xe9\x38\xba\x37\x53\x1f"
-  "\x47\x6b\xb9\x8c\x6d\x31\xdb\xe3\xf7\xfe\x91\xf3\xe0\x1e\x63\xe4"
-  "\xde\x77\xf8\xfd\xf8\x2e\x63\x1c\xc9\x32\x1b\x00\x4b\xd6\xaf\xe7"
-  "\x29\xd3\x61\x84\xc2\x6d\xb0\x74\x45\x1b\x27\xf7\x1e\xe5\xbc\x77"
-  "\x14\x90\x19\x34\xcc\xdc\xc9\x30\x96\x12\x9d\xa5\xfb\x6e\xe0\x7c"
-  "\x9c\x7e\x87\x37\x74\x9c\xdc\xeb\x33\xf2\xb1\xac\x53\x79\xef\xf5"
-  "\x88\x9e\x3c\xe2\x7c\xe1\xb0\xef\xd3\xdb\x3f\x4c\xce\x23\x9c\x9f"
-  "\xf3\x45\xe4\x99\xae\xc6\xe3\x7d\x1b\xc2\xc7\xe3\x7d\xd9\xe1\xfc"
-  "\x09\xfa\xa3\x5c\x10\x72\x0e\xf7\x87\x80\xc3\xd7\xe6\xaf\xcb\x8f"
-  "\xcd\xfb\x8e\x47\x8c\x4d\xf0\xc0\xf7\x56\x2b\x1e\xf8\xde\x93\x11"
-  "\xb8\x7a\xa3\xf3\xc0\xf7\x12\x06\xe7\x81\xef\x25\x0f\xce\x03\xdf"
-  "\x4b\x67\x1e\x70\xd3\xf7\x8a\xc3\xc7\xe6\xf7\xe6\x87\xb7\xfd\x3e"
-  "\xaf\x1a\x9b\x74\xf5\x95\x8c\x4d\xe8\x42\xd7\x0c\x36\x0e\x79\x4c"
-  "\xa1\xee\x98\xba\x5e\x63\x3f\xe3\x6b\xd1\xcc\x8c\x71\x05\xfc\x26"
-  "\x27\xf2\x9a\x12\x64\xfc\x24\xa6\x61\xad\x3c\x6b\x33\x79\x6c\x28"
-  "\x1d\x37\xa9\x73\x2f\x76\xe4\x7d\x8b\xf7\x87\x15\x3d\xa7\xbc\x18"
-  "\xde\xfe\xc9\xe9\xd1\xe9\x39\x79\x3e\xe8\x69\x8f\x4e\xcf\xc9\x45"
-  "\x83\xd3\x73\x72\x15\xfb\xec\x5f\x3a\xa6\x26\xef\xb5\x2d\x97\x3a"
-  "\x8a\x2c\x73\x96\xa6\x0c\xf9\x7a\xf3\xd3\xe4\x8e\xf0\xf9\x69\x72"
-  "\xf3\x95\xcf\x4f\x53\x92\xa3\xcf\x4f\x53\xd2\xa2\xcf\x4f\x53\x32"
-  "\xd5\x78\x98\x52\x19\x3e\x1e\xa6\x14\x84\xf3\x04\x68\xf7\x3f\x36"
-  "\x3f\x4d\x71\x47\x8c\x81\x8a\x53\x74\xff\x02\xe8\x14\xa5\xaa\xdf"
-  "\xa6\x8e\x8b\xc0\xd1\x1f\xbd\xdf\xee\x4f\x42\xbf\x55\x44\xef\xb7"
-  "\xfb\x53\x07\xef\xb7\xfb\x67\xa2\xdf\x2a\x2e\xed\xb7\xfb\x73\xae"
-  "\x5c\xa7\xb8\xbf\x3a\xbc\xcf\xee\x2f\xbd\xf2\x3e\xbb\xff\x78\xf4"
-  "\x3e\xbb\xdf\x1b\xbd\xcf\xa6\x26\xa8\x3e\x9b\x9a\x1e\xde\x67\x53"
-  "\xc7\x86\xf7\xd9\x14\xff\x3f\xdb\x67\xe8\x9f\x2e\xe5\x67\x30\xf5"
-  "\x0d\xd8\xed\xc3\x7a\x1c\x53\x6b\xdc\x94\xa6\xef\xe1\xa6\xa9\xb9"
-  "\x43\xf5\xe1\x7e\xe4\xa9\xbc\x74\x1e\x98\xda\xa8\xa7\xfd\xf0\xd2"
-  "\x7e\x98\x7a\x0c\x32\xba\xab\xa9\x58\xee\x6b\xa9\x3e\x64\x9a\x23"
-  "\x9f\x73\x15\xef\x4d\x4d\xf5\x72\x59\xf4\xb1\x70\xf9\xfc\xc4\x72"
-  "\x1d\xf9\xbd\x0c\x87\xcf\x2a\x85\xc3\x4a\xb3\x5d\xc9\x1c\x3f\xb8"
-  "\x6f\xcc\x9b\x5d\xce\x92\xbb\x00\xef\x81\x7b\x14\xaf\xa6\x45\xea"
-  "\xbf\x75\x78\x17\xa7\xf8\xf4\xc1\xbf\x44\xe0\xb0\x2b\x3a\x9f\xa6"
-  "\x1d\x46\x1b\xea\xa2\xf3\x69\x5a\xfb\xe0\x7c\x9a\xc6\x32\xb3\x2e"
-  "\xc4\xf6\x19\xf1\x94\xdf\x1d\x61\xfb\x3c\x60\xb5\x78\x15\xef\x48"
-  "\x9d\xa8\xfc\x4d\xe8\x1c\x0f\x44\xea\x7f\xe8\x9b\x07\xde\xd5\x71"
-  "\xfe\x4d\x44\xf9\x41\xf4\xbf\x07\x58\xff\xdb\x1f\x1d\xe7\x07\x2e"
-  "\xa3\xff\x3d\xc0\xfa\xdf\xfe\x4b\xc7\xd6\x03\xba\xfe\x17\xcd\xc6"
-  "\x7b\xe0\x78\xf4\xfe\x7f\x20\xa2\xff\x29\xb3\x10\xf6\xb0\x2c\x1f"
-  "\x96\xef\xc1\xd1\xa1\xf9\xd8\xc7\x88\xf3\x32\x8f\x44\xc9\x3b\x3d"
-  "\x12\xe6\x20\xf9\x0a\x2e\xe1\x3d\xf6\x89\x8a\xca\x7b\x0f\xd6\xa8"
-  "\xf1\xf8\xa0\x37\x7c\x3c\x3e\x78\x28\x7c\x3c\x3e\x90\x19\x51\xee"
-  "\x58\xf8\x7b\xf0\xcf\xff\x98\x8c\x9d\x96\x1e\xc1\x03\xef\x9f\xa2"
-  "\x69\x1f\x28\x1e\x48\xbf\x2e\x1c\x8f\x69\xf3\xa3\xf3\xc0\xb4\x42"
-  "\xb4\xff\xfd\xe8\x3c\x30\xad\x72\x70\x1e\x98\xb6\x17\xb4\x7c\x3f"
-  "\x94\x6f\x1f\x2b\x4e\x1b\x16\x91\xa7\x2d\xba\xcc\x9b\xd6\x19\x7d"
-  "\x8d\x20\x9d\x14\x8d\xd3\x27\x85\xd3\x38\xdd\x1a\x4e\x43\xb4\xe5"
-  "\x9f\xa7\x61\xff\x59\xdf\x1e\x47\x7a\xe4\xf8\x77\x9d\xa2\x87\xf4"
-  "\xf1\xff\x70\x84\xac\x4b\xdf\xa5\x70\x89\xb6\x2e\x92\xce\xf6\xaf"
-  "\x2b\x3a\x2d\xd3\x8f\x0f\xd2\x66\xf6\x69\x73\x05\x2f\x19\x4b\x0f"
-  "\x25\x20\xfd\x31\x5e\x0f\xe5\xf5\x90\x5a\xa4\x3f\xe6\x27\xb3\x9c"
-  "\xaf\xfa\xe7\xa5\x87\xf8\xec\xa5\x60\xfa\x33\xff\x5a\x46\x53\x06"
-  "\xcf\x41\x8c\x57\x56\xb1\xf4\x59\xb0\xac\x63\x5e\xbf\x99\x79\xfd"
-  "\x21\xa9\xff\xf1\x3e\x0b\xfb\x03\x5a\x8a\x28\xc3\xe5\xf5\x93\xc1"
-  "\xef\x9c\x3f\x02\xf6\x06\x1e\x17\x9c\xdf\xc8\xab\xd6\xcd\x4a\x23"
-  "\x64\xd3\x43\x87\xa2\xf7\xf1\x43\xcd\x83\xf3\xce\x43\x9d\xaa\x9f"
-  "\x1f\x1e\x1d\xde\xcf\x0f\x43\xff\x1b\x3e\x97\xdb\x0a\x1e\xb8\xa2"
-  "\x71\x52\x68\x13\x9e\x41\xe5\xfd\xda\x27\xda\x0b\x4a\xe8\xc6\xd3"
-  "\xf4\xf0\x3a\x59\x9f\x26\x7c\x96\x35\x31\xd4\x24\x65\xc0\xc3\x9f"
-  "\x48\x3c\x91\x27\xcb\x4f\x9a\x58\xfb\x7c\x3b\xbf\xab\x73\x08\x1f"
-  "\xf2\xb5\xf1\x9e\x00\x9f\xf5\x03\x2f\x5c\x73\x92\x1e\xde\x19\x56"
-  "\xde\x44\xe4\x52\x30\xda\xeb\xe4\x78\x7c\xf8\x98\xb1\xa6\xbb\x6e"
-  "\x10\xff\x20\xe4\xf1\x19\xbe\x0f\xca\xf7\xeb\xe1\x41\xf7\x2f\x19"
-  "\x27\xf6\x8f\x67\x9c\x2e\x2f\x07\xbe\x3f\xd3\xe0\x5f\xe5\x33\xf9"
-  "\xfd\xf9\x03\x3e\x79\xdf\xcf\x73\xd3\xf7\x07\x3d\xcf\x11\x3e\x0e"
-  "\xbe\x5f\x15\x0a\x47\x9d\x77\xff\xfe\x1e\xc3\xaf\x0e\xf7\x87\xbe"
-  "\x02\x96\x81\xcf\xf1\x08\x7c\xba\xa0\xa7\x34\xe9\x30\x7c\x97\x83"
-  "\xc1\x7d\xae\x78\x96\xf9\x61\x7a\xe2\xe5\xd6\xfc\x62\xad\x94\xb1"
-  "\xf9\x12\xde\x9a\x2e\xf5\x25\x86\x71\x79\x1c\xa7\x97\x86\xd9\x16"
-  "\x72\xef\x9e\xf7\xb6\x66\xcc\x52\xe3\x7e\x46\xc4\x1a\xe1\xf4\x1a"
-  "\xe9\x37\xa5\x8f\xfb\xa7\xfc\x91\xe3\x60\xfa\x61\x63\x8e\x8e\x48"
-  "\x3f\x66\x8c\x7b\xd8\xb5\x0c\x37\x62\x9d\x75\xba\x57\x8d\x85\x19"
-  "\x33\x83\x71\xa1\xf6\xda\x0c\xa9\xff\x19\xeb\xa5\x6e\xe4\x0b\x2f"
-  "\x37\x23\x62\xfd\x6f\x7a\x8d\x18\x7c\x9d\x3e\x01\xfd\xeb\xe5\xbd"
-  "\x2d\x75\x76\x78\x46\x71\xc4\x7a\x85\x67\x93\x3c\x27\xfa\x29\xe0"
-  "\xfe\x40\x97\x7b\x3f\xf8\x22\xa2\xbe\x1a\xfb\x99\xcb\xb5\x7f\xc6"
-  "\x20\xed\x9f\x31\xd0\xfe\xc5\x12\x6e\xc4\x5a\xe2\x0c\xd9\xfe\xc0"
-  "\x25\xf2\xef\x07\x09\x90\x5f\x06\xdd\xa0\x73\xff\x20\xd7\xd0\xd5"
-  "\x79\xfd\x60\x70\x5d\xfd\x07\x03\xeb\x7f\xaa\xdc\xc0\xfa\x9f\x27"
-  "\x9a\xae\xee\x26\xb9\xb7\x1a\x5e\x77\x99\xa5\x26\x5a\x5b\x7e\x30"
-  "\xc8\xfa\xdf\x0f\xf4\xf5\xbf\x7f\x4b\x0c\x97\x67\x3f\x68\x0b\xef"
-  "\xc3\x19\x11\x7d\xf8\x03\x4f\x78\x1f\xce\xa8\xf9\xef\xce\x6b\x3c"
-  "\x71\xc6\xc6\xc6\x6a\xb1\x31\x5a\x4c\x2c\x5e\xa3\x89\x34\x2c\xd6"
-  "\x14\x3b\x04\xbf\xa1\xfa\x75\x98\x16\xab\x99\xf0\x1b\xa2\x5f\x87"
-  "\x46\x3c\x0f\xe3\xb2\xf8\x99\xf4\xeb\x90\x88\xe7\xa1\x5f\xf1\x7e"
-  "\x98\x5e\xaf\x51\xbf\x29\xe2\x79\xc8\x57\xbc\x1f\xfa\x4f\x96\xa7"
-  "\x4b\x9e\xc3\xfd\xd0\x66\x2c\x5e\xbe\x20\x7f\x51\x8e\xdc\x2f\xce"
-  "\xb5\x2d\x78\xe6\x99\xdc\x65\xcb\x6c\x85\x4b\x6c\x0f\x3e\xf0\xe8"
-  "\x5d\xf7\xd9\xd4\xb6\x73\xfe\x94\x71\x39\xf1\x34\x6b\xc5\x52\x7e"
-  "\x31\xeb\xb1\x19\x99\xb6\x8c\x07\x1f\x08\x7f\x69\x80\x91\xdb\xcb"
-  "\x97\x83\x12\x32\xfe\xd2\xca\x47\x12\x6d\x18\x29\x65\x4f\x47\x4b"
-  "\x3d\x91\x5a\xf3\x78\x64\x41\x33\xb4\x09\xd1\x6b\x17\xce\x9b\x79"
-  "\x4f\x7f\x96\xf4\x11\x1e\x5f\x5f\x4a\x05\x0b\xf9\xbc\xc9\xac\x3b"
-  "\xc5\x7b\x1e\xb2\xfd\x80\xb4\x93\xf4\xf8\x8b\x4d\xd0\x6a\xf9\xd9"
-  "\xd5\xe1\x27\x9b\x9d\xcc\x28\x7f\x35\xde\xc5\x88\xfb\x83\x48\xf3"
-  "\xea\x3e\xcd\x19\x63\x64\xda\x7b\xa5\x46\x3e\xcb\x29\x9a\xf5\x17"
-  "\xf1\x9e\x90\xcf\xe2\xfe\x4a\x3d\xdf\xac\xb7\x82\x8e\x99\x79\x2c"
-  "\x1b\x6a\x5e\x23\x53\xed\x6b\x44\xdb\x46\x90\x79\xdb\x48\x3e\x43"
-  "\x3f\xab\xc6\xd8\x0b\x2d\xc7\xb3\x9b\x1e\x2f\xe0\xba\x39\x6f\x50"
-  "\x9b\xf9\x9a\xcc\x3f\x22\x2c\x7f\xf3\xc0\x5e\xec\xac\x1a\x0d\xf9"
-  "\xe6\x7c\x4e\x16\x5f\x7c\xed\x51\x57\x71\x29\x59\x02\xe2\x8b\x3b"
-  "\xa6\x53\x4c\x2b\x66\xdf\x95\x7e\xe1\x77\x2e\x3d\x8d\xfa\x67\x5f"
-  "\x67\x59\x29\xbe\x70\x61\xf4\xcf\xea\xb2\x8b\x4d\x67\xc8\x84\x71"
-  "\x1d\xe3\x5c\xca\x7e\x0a\xb3\xa9\xf6\x4b\x32\x81\x06\xa3\x4f\xd3"
-  "\x9c\xd4\xe2\x59\x22\x60\x9f\x45\xa6\xff\x2c\x62\x7f\xc3\xdd\x0b"
-  "\x37\xfd\x99\x4c\xbf\xee\x2d\xd5\x7a\x85\x95\x8a\x0b\x05\xe4\x86"
-  "\x20\xbb\x57\xf8\xd8\x5f\xbf\x39\x3b\xc0\x79\x1e\xef\xb1\x5b\xa9"
-  "\xb5\xd0\x4b\xab\x8f\x0b\x5f\xd9\x9f\x95\x9f\x7f\x4b\x97\x97\xfd"
-  "\x17\xcd\xab\x67\x51\xec\xa9\x4c\xd2\x5a\xf2\xaa\xc9\x35\xdf\x4b"
-  "\xc5\xc7\x45\x67\x73\xf6\xe7\xd4\x9a\xd7\x40\x59\xed\xa4\x35\x77"
-  "\x7c\x46\x32\x3e\xc4\xfa\xbf\xb2\xdf\xa3\x75\xf5\x22\x4e\xbb\x40"
-  "\xab\x56\xd3\x55\xab\xfe\x42\x16\x57\x67\x3b\xea\x39\x43\x3f\x3e"
-  "\x46\x31\x80\xa7\xbd\xfc\x19\x59\x5f\xfe\x11\xfb\xf3\xa6\x51\x4d"
-  "\x09\x59\x85\x3d\x39\xa1\xd7\x9e\x9c\xd8\x2b\x92\x47\xf4\xd8\x93"
-  "\x93\x5a\x0b\x90\xbf\xe3\x5d\x1a\xde\x4e\x49\xef\x9d\x6e\xd7\xaa"
-  "\xcf\xd3\x68\xdb\x6c\xee\xff\x39\x29\x35\xe7\x91\x7f\xfd\xc1\xd2"
-  "\x20\xca\x86\x96\xf1\xc7\x1d\xac\x76\x65\xfa\x28\x08\x58\xd5\xbd"
-  "\x34\xba\xa6\x97\xac\xc1\xf2\x83\xa5\x4c\x8b\xbe\xf5\x6f\x1e\x85"
-  "\x2c\x1c\xb6\xff\xe9\x46\x93\xab\xb9\x8b\x5a\xbc\xbd\xd4\x4a\x9f"
-  "\x92\xab\xe8\xef\xce\x5f\x3f\xdd\x38\x24\x08\xe6\x77\xae\xea\x00"
-  "\x7c\xc5\x33\xf6\x16\x3e\x97\x58\x4a\x15\x25\x94\x50\xb0\x8a\x86"
-  "\x9d\x46\xba\xb2\xe9\xb7\x41\xb7\xf9\xbb\x73\x95\xf4\xc1\x7d\xbc"
-  "\xa0\xa4\x85\x62\x5b\xbd\xd5\xdc\x66\x2d\x10\xff\x57\x72\x79\xdb"
-  "\xc8\x55\xf0\x37\x67\xd0\xfc\x59\xe7\x86\x20\x99\xf7\x5d\x6c\xd3"
-  "\x5c\xa6\x8b\xe4\xca\xf4\xd2\xfb\xa8\x5b\xac\xff\x6b\x02\xe4\x55"
-  "\x5a\xab\xd7\xc7\xe7\x92\x52\x45\xb7\x35\xbe\x62\x29\xa5\xd4\x9e"
-  "\xa7\xb1\x3b\xcf\x53\xb2\xe8\x49\xd6\xd8\xaf\xf6\xc9\x33\x89\xb4"
-  "\x13\xd7\x84\x0e\x32\xa3\xbd\xca\xa7\x3a\x4e\xf7\xaf\xed\x4b\xa6"
-  "\xba\xde\x01\xff\xda\xde\xee\x01\xff\x5a\xf0\x52\x3d\xfb\xd8\x62"
-  "\x5c\x64\x32\x3f\x57\x9c\x25\xd3\xda\xb3\x44\x77\x94\x6a\x64\x7b"
-  "\x9a\xcf\x47\x3c\x32\xc4\x95\x73\x46\xde\x9f\xa4\x8c\xc3\xb8\x26"
-  "\xe0\x17\x83\x31\x20\xd7\xb3\x3b\x74\xbe\x45\x9a\x86\xb4\x37\x70"
-  "\x8d\xc5\x75\xa7\xbd\x46\x78\x44\xd9\x9e\xd1\xdd\x1a\xc5\x33\xff"
-  "\x2a\x5f\xde\x3d\xa3\x7b\x1c\x19\xd0\x7f\x72\x93\x0c\x3e\x56\x32"
-  "\x7d\x56\xfd\xfb\xa7\xce\x70\xbc\x16\x8f\xc4\xa7\x2f\x2f\x86\x63"
-  "\xb7\xe8\xe9\xc0\x21\x23\xc0\xf5\xa2\x7e\x37\xae\x16\xfc\x30\x2e"
-  "\x33\x0a\x8d\xb2\xdd\x7d\x79\x5c\xe7\x05\xa4\x0b\x23\x1d\xed\x35"
-  "\xf1\xbb\x83\xa7\xce\x68\x2a\x4f\xb2\x06\x98\x3e\x1d\x3e\xc6\xfa"
-  "\xac\x74\x1e\xd3\xdd\x9a\x45\x1c\xc9\x99\x48\x35\x23\x45\xdb\xce"
-  "\x2d\xa2\x49\x8d\xb5\x47\x26\xb9\x69\xa1\x8d\x71\xc4\xbc\xdd\xb4"
-  "\x01\xef\x8e\xd8\x88\x98\x2e\x4d\xd9\xec\x3f\xf6\x48\xa6\x9b\xe2"
-  "\x8f\x87\xb6\x41\x38\xfe\x6d\x3a\xcf\x9d\x6f\x97\x38\x87\x08\x6d"
-  "\xe6\xf4\x56\x77\x17\xfd\xba\xb7\x73\x88\xfd\x8f\xa4\xb9\xfc\x27"
-  "\x69\x42\x12\x59\x59\xff\xab\xdb\x22\xdc\xb8\x76\xb2\x3f\x27\xf8"
-  "\xe4\x86\xd3\xf4\xc8\x1b\xb7\x27\x51\xd2\x9f\x8a\x48\x97\x47\x8f"
-  "\xbc\x1b\x22\x8f\x1e\x6a\xe9\x68\x0c\x91\x45\xf3\x2e\x5c\x2a\x8b"
-  "\xe6\x7e\xa1\x64\x91\xf0\x2b\xd9\x13\x70\xeb\xe9\x9f\x45\xa4\xeb"
-  "\x7e\x21\x73\x3f\x88\x48\xf7\xe9\xe9\xfb\x22\xd2\x3d\x2a\xfd\xb1"
-  "\x33\x86\xac\x6b\x65\x3c\x56\xb0\xac\x7b\xec\x23\x96\x75\xad\x39"
-  "\xba\xac\x93\x3e\x86\x8f\xfd\x46\xfc\xa2\x94\xf8\xec\x11\xee\x37"
-  "\x32\xfe\xe2\x3d\x32\x70\x8f\x43\xda\x2c\x4e\xab\xfc\x94\x4c\xf8"
-  "\x49\x39\x27\x1c\x33\xf7\xb3\x9c\x63\x19\xc7\x7e\x27\x3b\x46\x8a"
-  "\xf6\x1d\x5b\xc4\xb1\x9a\x2d\xa2\xb9\xc7\xf1\xe8\x61\x43\xde\xfd"
-  "\x14\x69\x1b\x90\xf6\x53\xbc\x67\xb9\xc7\x34\x69\xc9\x6c\xe4\x73"
-  "\xfa\x1d\xe0\xe3\x1c\x4b\x0c\x15\x6c\x02\xcf\xf3\x79\xc0\x75\xa0"
-  "\xaf\x0b\x32\x89\xcf\x72\xc9\x38\x27\x5a\x2a\x64\x54\x07\x8f\xb7"
-  "\x91\x6b\x31\xbe\x5c\x45\x9f\x53\x89\x57\x9c\xe6\x73\x71\x8c\x43"
-  "\xd6\xca\x1f\x70\x1c\x8f\x98\xa6\x3c\x22\xf6\x01\x67\x7f\x15\xc8"
-  "\x5d\x53\x25\x70\x3a\x92\xcf\x7d\xfd\x18\xec\xff\x6d\xfa\x79\xa4"
-  "\xc7\x0b\x38\x2e\xd0\x49\x7a\xb4\x0c\xf6\x9d\x8f\xdb\x66\x09\x94"
-  "\x12\x9f\x5f\xc1\x18\x65\x1b\x2f\x6f\x07\x7e\x95\xc6\x19\x16\x8e"
-  "\xed\x84\x3c\xae\x76\x1f\x31\xce\x6e\x7a\xf4\x58\x4b\x71\x23\x97"
-  "\x2f\x62\xda\x08\x87\xdd\x80\x11\x23\xcf\xc0\x38\xc8\xcc\x67\x60"
-  "\xdc\xf4\x58\x9e\x2c\x1f\xff\xe6\xd1\x96\xf9\x1e\x62\x39\xef\xea"
-  "\x04\x8c\xe2\x93\x0a\x06\x60\x09\xc8\xfd\xb0\x77\x3a\xfc\xab\x56"
-  "\x8b\x2f\x00\x3f\x9d\xfb\x8b\xcf\x2d\xf2\xfe\x1a\xe8\x92\xc0\x7e"
-  "\xf1\x4a\xf7\x7c\xb4\xa5\xee\x53\x22\xfd\xec\x25\xf8\xed\xd1\x66"
-  "\x3e\x6f\xc4\xe7\x2d\xe5\x59\x4b\x6d\x22\x89\x15\xc9\x09\xfd\xe7"
-  "\x2d\xff\x7f\x38\x6b\x09\xfa\x5b\x6b\x35\xd1\x00\xfc\x9b\xf9\xbc"
-  "\x25\xf0\x4f\x61\x3e\xd4\xdb\xd4\xf6\xf3\x1f\x4b\x9a\x27\x71\x1a"
-  "\x6c\xc5\xa3\x46\xff\x73\x7b\xb9\x2d\x27\xe9\x11\x9f\xd2\x09\x45"
-  "\x9b\x9b\xe6\xb6\xf1\x7b\xa4\x75\x70\xfe\x09\x90\x63\xae\x9c\x00"
-  "\xed\x3f\x15\xd0\x2a\x56\x91\x49\xc9\xb4\x79\xff\xe0\xf2\x4a\xa6"
-  "\xcd\xab\x1f\x90\x69\xf3\x7e\xae\x64\x9a\xa2\xb1\x92\x69\xf3\xca"
-  "\x95\x4c\x9b\xb7\x46\xee\x83\x41\xa6\xf1\x3b\x96\x6b\x86\x4c\xdb"
-  "\x39\x52\x1c\x65\xd9\xd1\xe3\x98\x57\x60\xc8\xb6\x8d\x48\x63\xd9"
-  "\xc1\x38\x2a\x39\xf5\xd8\x51\xf1\xbf\x92\x49\xf9\x19\xf0\x7d\x1e"
-  "\x9f\x55\xe8\xd4\xef\xd1\x2f\xf3\x4e\x28\x19\x37\xaf\x69\x40\xc6"
-  "\xcd\x9b\x3e\x50\x96\x65\xdc\xbc\x4f\x94\x8c\x53\xe9\x75\x3f\x66"
-  "\x19\xf7\xd8\x51\xa6\x81\x0e\x5f\xe3\x35\x3b\x3d\x3f\xe8\xf8\x48"
-  "\x5b\xa8\x8c\x0b\x1f\x5f\x8f\x8f\x36\x64\x1c\xcb\x36\x3c\xa7\x40"
-  "\xa6\x49\xdf\x60\x1e\x67\x55\xa0\xb9\x31\xee\xb8\x0f\xb8\xcd\x1c"
-  "\xff\x87\xe9\x36\xed\x0c\x0d\xd3\xcf\xfd\xe8\xed\x7e\x3c\xcf\xf0"
-  "\x75\x74\xd3\xbc\x82\x68\x7a\xb3\xa1\xa7\x81\x1f\x6f\x0a\x60\xbc"
-  "\xb9\x4a\x31\x97\x56\x8b\xd2\x56\xff\x31\x7a\xaa\x90\xb4\x60\xec"
-  "\xf3\x27\xb8\x6f\x61\x67\x0c\xe5\x2b\xcb\x1e\xcc\xa1\xfb\xb2\xbc"
-  "\x34\x14\xb6\xf9\x89\x0a\x0d\xef\x8a\xe8\x7b\x21\xef\xfe\xc8\xf5"
-  "\x84\x94\x1b\x1f\xf2\xee\x73\xa9\xe3\x9d\xe5\xd8\x4f\x8f\x57\x0e"
-  "\x66\xfb\x5f\x19\x2e\x3f\xbc\x77\x70\x5c\x7e\x38\x6f\x70\x5c\x7e"
-  "\x28\xf5\x80\xf1\x5d\x14\x03\xdb\xec\xea\xb3\xf4\x43\xb9\x1e\x23"
-  "\x63\x57\xac\x8d\x5a\xcf\xeb\xfa\xfb\x21\x21\xef\x43\xeb\xfa\x20"
-  "\x4a\xf9\xd0\xfa\x4e\x5c\x1e\x7e\x66\xcc\xe5\xe1\x67\x8e\xb9\x3c"
-  "\xfc\xcc\x07\x58\x06\x82\x76\x96\xa0\x16\x9e\xef\x0e\xbf\x1c\x83"
-  "\x47\xf9\xdc\x1d\xf2\x2d\xd2\xd7\x7c\x4e\xd8\xc7\x48\x5b\x50\x9e"
-  "\xcd\xda\x84\xf7\x7c\x96\x9c\xe5\x73\xfa\x4a\x22\xb5\x47\xdd\x5f"
-  "\x66\x67\x24\x6e\xc3\xfd\x06\x6e\xf2\xfd\xbb\x91\xb8\xe1\xfd\xf8"
-  "\x90\xf7\x9f\x0d\xf4\x7b\xe6\x65\xfd\xeb\x5d\xd5\x44\x1c\x43\xef"
-  "\x08\xcc\x17\xcc\xc9\x1c\x8f\x4b\x5f\x9f\xf9\xd1\x44\xc8\xf9\xd2"
-  "\x10\xbf\x5d\xf6\x39\xbb\xa9\xd5\xcb\xe7\x54\xbd\x32\x56\x0a\xda"
-  "\xf2\x4d\xcc\x27\x23\xf8\xac\x0e\x9f\xdb\xc9\x0a\x64\x68\x2a\x26"
-  "\xce\x8f\x0a\x8c\xb2\x83\xad\x03\x71\xbd\x7a\x9d\xec\x03\xeb\x45"
-  "\x99\x5d\x46\x19\x86\xcd\x7e\x94\x98\x07\x6e\x92\x67\x57\xfd\x5d"
-  "\x2c\x77\xbf\x09\x3d\x79\x84\xaa\x27\x9b\xf4\x7a\x60\xc7\xfe\x30"
-  "\xe1\x72\x67\x47\x06\x6f\xdf\x8f\x93\xae\xbc\x7d\xa4\xb7\xef\xc7"
-  "\x19\x5f\xd1\xbe\xcb\xd5\xbb\xe1\xca\xeb\x4d\x34\xea\x3d\x7a\xe5"
-  "\x74\xfd\xb1\xff\xeb\xd3\x35\x55\xa7\xeb\x13\xa9\x5f\x41\xd7\x28"
-  "\xf5\x3c\x91\xf3\xf5\xeb\xb1\x19\xf5\x54\x47\xab\x87\xe4\xdf\xa0"
-  "\xe7\xba\xcc\x46\x6c\x3a\x8e\x0b\xa9\x62\x52\x3d\xe1\x0e\x8d\x9d"
-  "\xa9\xe2\x45\x3e\xe1\x35\x62\x67\xea\x31\x2c\x31\xb7\xcc\xbf\x3a"
-  "\xab\x9e\xf5\x11\x11\x74\xd3\xfc\x24\x8e\x7b\x98\xbe\x3a\x34\xc6"
-  "\xe4\xfc\xe4\xcb\xc5\xec\xe4\x58\x39\x42\x64\xd2\x91\x6a\xe9\x0f"
-  "\x80\x79\x68\xfe\x02\x3e\x1f\xa0\xf6\x33\xe7\xe7\xab\x31\x39\x3f"
-  "\xdf\x4d\x4f\x34\x0e\x0e\xe3\x40\xc1\xae\x92\xd4\x21\x83\xf9\xfc"
-  "\xa3\xfc\x5e\x37\x3d\x2b\xd7\x2f\x03\xeb\x1b\x2a\xc5\x39\xab\x1e"
-  "\x8b\x2b\x2b\x2e\x24\x56\x18\xe6\xee\xa7\xee\xd5\xcf\x26\x80\x06"
-  "\xa5\xa0\xe5\xfc\x0e\x83\x06\x46\x3a\xd2\x7c\x06\x0d\xa0\xaf\x24"
-  "\xb8\xea\xfd\x7c\x76\xc8\xab\xce\x7b\x3f\x79\x83\x28\x3f\x90\xad"
-  "\x60\x3f\xa9\xf6\x19\xe2\x1b\x2a\xbd\x2f\x5b\x35\xa3\xfc\x58\x9b"
-  "\xfd\x4b\xe6\x61\x4f\xdc\x81\xec\x1e\xc7\x93\xe9\x06\x7c\xc1\x78"
-  "\x89\x81\x7c\x75\xd2\x2f\xe9\x49\xf4\xff\x13\x93\x25\x5f\xa3\x0e"
-  "\x89\xbb\x46\xb1\x41\xe0\x8f\x36\x68\xae\x02\x2f\xeb\xa9\x5d\x01"
-  "\xb4\x9f\x65\xdd\xa1\xc5\x6e\x13\xe7\x91\xba\xc3\xb9\x64\x4d\xc5"
-  "\x39\x7b\xf2\xdd\xe0\x39\x8e\xb7\x21\xf1\x4a\x40\x9b\xcd\x8c\x93"
-  "\x1b\x57\xcf\xcb\xc9\x34\xe7\x02\xe9\xb4\x78\xf2\x8d\x20\xd2\x83"
-  "\xcb\x06\x70\xa8\x95\x67\x3c\x9e\xec\x34\x70\x08\x72\xfd\x3d\x56"
-  "\x0d\xba\x18\xd7\xdb\x29\xcf\x59\xa2\xee\x09\x1c\x97\x8a\x63\x59"
-  "\xac\x48\x26\xc6\xa1\xc7\xf1\xd4\x68\x83\xde\x7a\x19\xa3\x8e\xe6"
-  "\xa0\xac\x5b\xd1\x46\xd1\xf9\x08\xf4\xc1\xa7\x66\x5e\x4a\xe7\xa7"
-  "\xb2\x43\xe8\x1c\xcb\x7c\xc5\x6b\x2c\xe8\xa3\x00\xd3\x9b\xf7\x35"
-  "\x6c\xcb\x59\xaf\x7a\xea\x67\x47\xbc\xd2\xef\x24\x81\xe1\x06\x41"
-  "\x7f\x86\x01\xb8\xdf\x50\x34\x7e\x6a\x4f\x3f\x8d\x51\xb7\x40\x5f"
-  "\xac\x55\x67\x52\xd8\xf7\x1d\xb2\xe3\xa9\xa3\xfd\xf5\x30\xae\x76"
-  "\xab\x16\x14\x56\x8e\x6b\xe7\x61\x5c\x0b\x6d\xc2\xc7\x7a\xa5\xf4"
-  "\x63\x42\x5b\x0f\x95\xb4\x9b\xa0\x5b\x6a\xb2\xae\xee\x64\xd6\xef"
-  "\xcd\xf2\x1e\x75\x0d\xc2\xdf\x9f\x70\xec\x38\xa3\x5d\x68\x8b\x99"
-  "\x79\x0b\xb8\x43\xff\xcb\xbe\x4a\xf2\xcb\x72\xee\xa7\xac\x2f\x38"
-  "\xcd\xc8\x87\xe7\x0f\x39\x9f\xf1\x8c\x77\xe0\xaf\xac\x57\xd0\xae"
-  "\x78\xc6\xd3\xc3\xf1\xf2\x64\x9b\xb3\x93\x19\x46\x8f\x23\xab\x32"
-  "\xac\x9d\x7d\x99\x26\x83\xef\x78\x8f\xa8\xc9\xe6\x93\xb2\x53\xd1"
-  "\x36\xeb\xb0\x31\x26\xb9\xbc\x1a\x63\x59\x6d\xa1\xbc\xe8\xb5\x0f"
-  "\xf0\x41\xe1\x18\x32\x9b\x6c\x1c\xef\x2e\xab\x41\xc5\xd5\xcd\xf2"
-  "\x47\xf6\x17\xbf\xe3\xd8\x70\x3a\x0d\x79\x3c\x25\x9e\xa4\x2c\x0f"
-  "\xb7\x0d\xef\xd2\x2f\x37\x5f\x72\x8c\x36\x8e\xb7\xb7\x59\x8d\x23"
-  "\xd0\x65\xc1\xa2\xcd\xea\x7c\x8f\x57\xc5\x48\xcb\x7e\x41\x68\xaf"
-  "\xcb\xfe\x62\xbf\x3c\x19\x0f\x43\xc6\x9e\xc8\x66\x1f\x37\x31\xbc"
-  "\xe0\x75\x19\x2b\x51\xf7\xd9\xf3\x34\x15\xf8\x65\x9c\x35\x7b\x21"
-  "\x9f\x83\xf5\xb3\x4d\x26\x7d\xd2\x8e\x14\xfa\xe9\x31\x1f\xd3\x36"
-  "\xfb\x30\x9f\x57\xf7\x4a\x5a\x64\x1f\x35\xce\xa8\x73\xdc\x37\x8e"
-  "\x25\x38\xc1\x4f\xb1\xac\x53\xd8\xec\x1c\x5b\x60\x41\x3d\xeb\x24"
-  "\x8a\xa6\xe0\x7b\x4d\xb4\x29\x5e\x5e\x70\x35\xc7\x66\x54\xfb\x4b"
-  "\x27\xc1\xdf\xb1\x7f\x47\xde\x5b\xd5\xba\x8c\x31\xd6\x16\xbc\xce"
-  "\x7b\x4c\x6e\x1d\x46\x8f\x63\x01\xe6\xff\xf9\x55\x97\x8e\x8b\x05"
-  "\x57\x1b\x36\x06\x9f\x8b\x53\xfb\x55\x03\xf0\x50\x5e\xae\x4b\x0f"
-  "\xc8\xa6\x3f\x30\xac\xd2\x4b\xc7\xcc\x82\x2a\x83\x97\x0b\x6e\xe6"
-  "\x73\xd5\xd9\x99\x5c\xff\x60\x32\x53\xd8\x7f\xc4\xfd\x64\x3e\x65"
-  "\xa3\xd8\xaf\x3a\x2f\x31\xb0\xff\xb5\xc0\x67\xb4\xc1\xa0\x89\x6a"
-  "\xc3\xd3\x8f\x74\xc7\xbf\xe9\x19\x68\xfb\xd3\x8f\x48\x5a\x0c\xbc"
-  "\x2f\x0f\xa1\x0d\x3f\x97\x29\xbe\x7b\x7a\x3a\xf8\x43\x5f\xb3\x51"
-  "\x69\x22\xfe\xc0\x33\x1c\xa7\x51\xe1\xb8\x88\x0c\x7e\x47\xde\x42"
-  "\x37\x9d\x4a\x56\xfb\x50\x4f\xa3\xfd\x0b\xda\xf4\x72\xa3\x19\x97"
-  "\xa8\xed\x0c\xc3\xf1\x19\xe2\x39\x56\xc5\x2d\x78\x26\x86\xf1\xb5"
-  "\x7d\x8b\xfb\xf8\xe9\x16\xae\x97\x79\x42\xf4\xe5\x0d\xf1\xf6\x25"
-  "\x53\x77\x5f\x1e\xc6\x4f\xb2\x86\x7a\x20\xff\x3e\x37\xe9\x75\x7a"
-  "\x0d\x5c\x19\x37\xe8\x8a\xe6\x1e\xb1\x28\x3a\x7d\xb9\x5e\x1e\xef"
-  "\x7d\x79\xc3\xf0\x33\xe3\x37\xf4\xeb\xce\xc7\xd0\x6b\x3b\x3d\xe5"
-  "\xfb\xe6\x07\x97\x8b\xa3\x73\xfc\x22\x08\xbb\xa0\xb3\x02\xfc\x3b"
-  "\x7c\x8d\x93\x86\x7b\x9f\xd4\xb2\x56\x52\x1a\x6c\x5b\x12\x17\xc5"
-  "\xa4\xda\x20\xae\xcb\xc5\x44\x8e\x47\x8b\xe7\x54\xfd\x39\x85\x9f"
-  "\xbb\x97\x8b\xf9\x3d\x8e\x67\xf6\x18\x7b\x77\x2a\xf6\xcc\x33\x8d"
-  "\xfd\x71\x78\x62\x9f\xe0\x73\x3e\x34\xa7\x08\x75\xc4\x3e\xdf\xc9"
-  "\xf5\x66\xf1\xdc\x81\xfa\x90\x0f\xf3\xff\xfc\x89\x9c\xcf\x13\x7b"
-  "\xdb\x08\xfc\x92\x07\xd9\xe3\xec\x64\xbc\xba\xe3\xf6\xcd\x37\x70"
-  "\x1d\xee\x4d\xd3\xbe\x1e\x6e\x39\xe9\x06\x6e\x48\x3f\x5a\xa1\xd2"
-  "\xfd\x1c\x8b\x8c\x7d\x10\xf1\x3e\xc7\xc0\xd5\xc0\x81\xeb\xe3\x73"
-  "\x95\x22\x7e\xb7\x8c\xed\xc2\xf5\x79\x5e\xce\xe3\xbc\x95\x06\xbe"
-  "\x5f\x7d\xf6\x27\x3a\xdd\xdd\x94\x73\x5c\xf1\x64\xce\x71\x63\xfe"
-  "\xc2\x7d\x67\xf8\x7e\x6f\x4e\x5b\xa4\x2c\x7b\x7a\xc9\x92\xc2\xac"
-  "\xa5\xb9\x7c\x49\x1e\xf7\xd2\xad\xf1\xa1\x36\x29\xcb\x37\x15\x1b"
-  "\x20\x97\xcf\x3e\xd1\xe6\x11\xc6\xfe\x65\x6e\xff\xf9\x27\xdd\x4f"
-  "\x7a\x2a\xeb\xaa\xac\xd3\xe1\xdd\xfc\x0f\x8a\x57\x33\x98\x98\x13"
-  "\x66\xd2\x06\x93\x9d\x2c\x2f\xba\xe3\x3e\x49\x95\xf4\x28\xf7\xd4"
-  "\xa3\x5c\xff\xfa\x67\x74\x3f\xb1\xdd\x69\x81\xf5\x07\x9d\xb6\x51"
-  "\x32\xc6\x91\x76\x70\x55\xbb\xc6\x73\x78\x09\xee\xd9\x76\x92\x7a"
-  "\x83\x1e\x37\xe7\xbd\xf3\xed\x90\xc3\xb9\x9d\xa2\x7c\x77\x1a\x60"
-  "\xba\x07\xc5\x21\x64\x8f\x9d\x7d\xb2\x3a\x68\x21\x0d\xba\x1f\x5e"
-  "\xd6\x50\xaf\xc6\xe1\xc2\x79\x4d\x56\xe2\x33\xa2\x3f\x39\x49\x0b"
-  "\x1f\x31\x59\x21\x6b\x47\xd1\x6e\xdc\x4b\x5b\x97\xdf\x85\xf5\xd7"
-  "\x0d\x67\xea\x4d\xb1\x42\x13\x42\xc4\x08\xf5\x47\x26\xfd\x26\x16"
-  "\x3f\x4d\xc4\xc8\xdd\xa2\x58\x50\x6a\xd8\x50\x13\x59\x86\x27\x98"
-  "\x6f\xba\x71\xb4\x75\xea\xfd\x93\x27\xd9\x4b\x8a\xc1\xdd\x7e\x9f"
-  "\x45\x84\xc6\x79\x6a\x6f\x9b\x77\x6b\x29\x49\x7f\x81\xf2\xf6\xb6"
-  "\x68\xb8\x6e\x74\x88\x02\x3e\x9b\x1b\x8c\xf7\x24\xda\x5f\x22\x6d"
-  "\x7f\xaf\x5b\xe3\xd8\xc1\x3c\x47\x73\xcc\x32\xe0\x7a\xe2\x7d\xa4"
-  "\xa1\xfd\x45\xa2\xcc\x93\xa8\xf6\x03\x9f\x1d\x13\x5c\xef\x49\x1c"
-  "\x80\x6f\x22\x86\x6f\xdf\x46\xda\xae\x92\x4e\xcd\x65\xba\x9f\x5c"
-  "\x36\x2f\xbd\x8f\xfb\x41\xfa\xb3\x00\xf4\x27\x86\x51\xe7\x08\x96"
-  "\xd9\xbf\x24\x4d\x3f\x5f\xa7\x9d\xa5\x67\x7f\xd4\x30\x48\x39\x3e"
-  "\xcf\xda\x1d\xbf\xef\xe6\x1e\xc7\xb3\xe8\xff\xef\x79\xf5\x39\x01"
-  "\xb2\xeb\x59\xd8\x7f\xb9\xea\x39\x7e\xdf\x98\x6e\x19\xd7\xf2\xd9"
-  "\x46\x23\x4f\xf4\x79\x81\xd7\x1c\x85\x93\xfb\x55\x5c\xfc\x47\x27"
-  "\xfb\xee\x0f\xb2\xcf\x3f\xcc\x55\x74\x17\xef\xb3\x0c\x19\xee\xa3"
-  "\x04\xfb\x05\xd1\x07\xbb\x3d\x09\x6c\xab\x05\x60\x7b\xf9\x2f\x8a"
-  "\xcc\x96\xae\xf3\xc4\xb1\xfe\x78\xbf\xf6\xed\x85\x7f\xd0\x5c\xbe"
-  "\x73\x4e\xd7\xba\x20\xb5\x62\x7e\x76\xd5\x9c\x73\xb6\x74\x1d\xc3"
-  "\x7d\x80\x5a\xe8\x53\x6a\x29\xfa\xb8\x54\xae\x95\xd4\x88\x52\xa6"
-  "\x73\xdf\x45\x31\xd7\x65\xfa\xff\x88\xe3\xd5\xb3\xac\x00\xdd\x6d"
-  "\x67\x29\x6f\xcd\x7b\x80\xb3\xff\xaf\x80\x25\x63\x3b\x4d\xa1\xf7"
-  "\x71\xdf\xe3\xc8\xdb\x60\xc8\x91\xa8\x71\x34\x62\x9c\x1b\x2d\x45"
-  "\x4f\x6a\x41\xc8\x24\x8e\xc1\x05\x59\x34\x91\xdb\x85\xe7\x54\x7e"
-  "\xc6\x35\x85\xaf\x96\x35\xce\x9d\x16\xff\x93\x2c\xa3\x32\x59\xfe"
-  "\x20\x7d\x6e\xdd\x45\x29\xb3\x32\xf4\xe7\x99\xfa\xf3\x74\xfd\x39"
-  "\x5d\x7f\x4e\xd3\x9f\x27\xf3\xb3\x92\x6d\x8b\x6c\xfd\x72\x57\x1b"
-  "\xd6\x86\xe7\x54\xa3\x2f\x80\xcf\x55\x96\xa2\xd5\x52\x46\xea\x78"
-  "\x4c\xd4\xf1\x4a\xd5\x9f\x0d\x7c\x6e\xb0\xf8\x57\xff\x4f\xe1\xd3"
-  "\x10\x81\x8f\x33\x04\x1f\xb2\x14\xa5\x7d\x1d\x7c\x12\x2d\x1c\xaf"
-  "\xf9\x9f\xc0\x87\x71\xe1\xb4\x1e\xc7\x73\x69\xe1\xf8\x3c\x97\x61"
-  "\xe0\x13\x95\xdf\x96\x8b\x4e\x9e\x1f\x96\x5d\x27\x63\x55\x0e\x63"
-  "\xd9\x5f\xd7\x6b\xc4\x53\x7b\x6e\xc3\xe5\xe2\xa9\x61\x2c\x58\x91"
-  "\x07\xed\x7f\x6e\xbe\x3e\x0f\x1e\x56\xfa\xd2\x73\x4d\x86\x6f\x0c"
-  "\xda\xba\xa7\x42\xb5\x75\xef\x3a\x8e\x29\xb6\x92\xae\xb7\x17\x89"
-  "\x4e\xe8\xff\xff\xd5\x64\xf3\x84\x8d\x81\xfc\xc2\x65\xcb\x5e\xb8"
-  "\xcf\x96\xbf\x60\x71\xae\x6d\x5c\x8e\x6d\x59\xde\xa2\x85\x85\xb9"
-  "\xe1\xfb\xc5\x89\x7a\xbc\x7c\xe9\x07\xcf\x3a\x29\x8f\x01\xe6\x7f"
-  "\xb6\xe3\x95\xef\xe2\xf3\xaf\x08\xc7\x73\x7c\x56\xd6\x5c\xfb\x1a"
-  "\x99\x78\x8f\xa2\xc7\xf1\xfc\x5c\x63\x4e\x50\xf1\xa1\x29\x46\x4b"
-  "\x64\x9d\xeb\x79\xd8\xbf\xcf\x76\x85\xa4\x73\xde\x52\x23\x8d\xe1"
-  "\xeb\xb2\x69\xd8\x49\x7a\x7e\x0c\xd7\x19\x95\x86\x17\x45\x3d\x6c"
-  "\xdd\x18\xd8\x23\x6c\x1b\x0a\x8e\x1f\xc4\xe7\xcb\x50\x4e\x00\x9f"
-  "\x8f\x58\xf6\xf2\x37\x20\x94\xee\x2b\x18\xc7\xcf\x51\x66\x17\xd2"
-  "\x4c\x9b\x90\x17\xfa\x74\x27\x97\x43\x7a\x80\xcf\xf9\x23\xdd\xac"
-  "\xc7\x44\x42\x5a\xfe\xd5\x7c\x0e\x1f\x69\x89\x21\x69\xe3\x38\x4e"
-  "\x2f\xd2\x6c\x0a\x5e\xfe\x3d\x4c\x67\x3c\xa7\xe9\x36\x37\xe7\x99"
-  "\xa1\xd7\x1b\x16\x2f\x8b\xa3\xa8\xdf\x75\x47\xaa\x6d\xee\x63\xdf"
-  "\x99\x72\xff\x33\x4b\x16\x2f\x8c\x27\x49\xf6\xe4\xd4\xa2\x71\xa9"
-  "\x77\x15\xdd\x7a\x9f\xad\x20\x37\x77\xa9\x6d\x45\xee\xe2\x42\xdb"
-  "\x82\x15\x0b\x56\xc6\xd3\xc2\x25\x4b\x9f\xe1\x53\xe4\xdc\x2d\xcb"
-  "\xb2\x9e\x59\xf8\x2c\x6f\xea\xab\xdc\xf1\x61\xf3\xf1\x5c\x96\x6d"
-  "\x7a\xdc\x85\xa3\x90\xb9\x3e\x11\xf7\x4e\x36\xee\x39\x16\x91\x15"
-  "\xd7\x26\xfc\x0e\xe3\xd7\x88\xdf\x31\xfc\xda\x4e\xd3\xd2\x24\x5c"
-  "\x0f\xf5\x38\xf2\xbd\x86\x5e\x30\xc0\x43\x2f\x98\x0d\x1e\xc2\x3c"
-  "\x7e\x48\xcd\x6f\x2f\x4c\x6a\xf5\xcb\xf1\xd3\xcf\x53\x15\x17\x07"
-  "\x78\x4a\xc6\x3b\x64\x9f\x95\xe5\x78\x0f\x1e\x66\x3b\x16\x34\x8f"
-  "\x63\xba\x9d\xa2\x82\xf1\xb0\xfd\x9b\x39\x16\x08\xae\x4d\xe0\x97"
-  "\x66\x15\x7f\xe3\x85\x43\xc8\x37\x06\x75\x1c\xd6\xeb\x50\xcf\x23"
-  "\xc5\x51\xb6\xf3\x4f\xea\xcf\xca\x26\x5e\xf2\x21\xdf\xf3\x55\xdf"
-  "\x2b\xb2\xb0\xff\x9f\xb2\xad\x8c\x77\x8b\x9f\xd4\xeb\x70\x82\x16"
-  "\xa5\xb5\x0e\xd1\xbf\xcf\xc1\x6b\x4c\x96\x98\xa9\x02\xf8\x9c\x0b"
-  "\xc6\x3e\xd1\x2e\xe3\xf4\x95\xf6\x42\x46\xdc\x7d\xb7\xab\x48\xe6"
-  "\x8f\xe1\x35\xa8\xd9\x05\x22\xc8\x71\x51\x83\xb1\xcf\xb7\x73\x39"
-  "\x61\x7e\x27\x3b\xb8\xe9\xaa\x34\xa5\x0b\x70\x7c\xb4\xc5\xba\x1f"
-  "\xa8\xf0\x31\x6d\x4f\x53\xfe\x3f\x94\x3d\xb3\x34\x49\xe9\x59\x8b"
-  "\xd3\x0d\x5f\x32\x8c\xd1\x64\x3c\xcf\x35\x64\x80\x9b\x16\xdb\x74"
-  "\xbf\x1f\xa7\x6a\xff\xe2\x0d\xfa\x73\xa3\x8e\x63\x0c\xc7\x7a\x00"
-  "\xfe\x6d\xdc\x77\xb0\x0d\x1b\x71\x7f\x0c\xf4\x69\x56\xf4\x59\x2c"
-  "\xd7\x18\xa0\xd7\xf0\xfb\x63\x1c\x77\x1e\xef\x8e\xa9\x38\x0a\x2f"
-  "\x34\x71\x9b\x07\x7c\x03\x6b\xd2\x40\xbf\x0f\x79\x4f\x0d\x63\xa9"
-  "\xd1\x75\x91\xc7\xe7\x0b\x4e\xc0\x6b\x30\xe4\x0e\xcb\x99\xac\x00"
-  "\xc6\xa9\xd4\x4b\x17\xfb\x0d\x79\x33\xc0\x07\x4b\x12\xa3\xc9\x92"
-  "\x68\xfd\xae\xf7\xcd\x4a\xe1\xc8\x9f\x0b\x9c\x1a\x64\x1f\x70\xdc"
-  "\xc8\x8b\xfd\xfa\x6f\x9f\x92\x91\x4b\xfa\xf5\x5f\x03\x0f\x8e\x77"
-  "\xeb\x66\xdc\x7a\xe5\x3e\xa7\x2e\x37\x96\x6c\x30\xe4\x86\x01\xc7"
-  "\x12\x23\x82\x96\x22\xfc\x2b\xdb\x7d\x9c\xd7\x58\x79\xbe\x94\xfa"
-  "\x08\xe0\x0c\xbf\xa0\xce\xf8\x04\xcb\x77\x43\xcf\x5d\x92\x0e\x19"
-  "\x63\x92\x3a\xaa\x23\xff\xd9\x01\x59\xb4\xc4\x1d\x0a\x53\x98\x77"
-  "\x1f\x67\xb8\x2c\x8f\x58\x27\xc9\x0a\x98\x38\xce\xc6\x71\x7d\x7e"
-  "\x81\x0c\x2e\x48\x34\x70\x05\x0d\x8f\x1a\xf8\xea\xdf\xf8\x80\x8d"
-  "\xbd\xa4\x60\x4e\xa0\x8f\x7d\x5d\x9b\x54\x7f\xbe\x28\xe5\x0d\xde"
-  "\xed\x45\xd9\x99\x6e\x7a\xbe\x5e\x1f\x43\xcd\x28\xbf\xf7\x48\x49"
-  "\x3a\xf2\x14\xe4\xe9\xfe\x9a\x6d\xe8\xdf\x63\x21\xbc\xff\x64\x88"
-  "\xbd\x7c\x4c\xf5\xe1\xfd\xa5\x27\xa9\x60\x4f\x48\xba\xde\xb7\x47"
-  "\x32\x4e\xd2\x8b\x4f\x2a\xdb\x73\x77\x8d\x2a\x5f\x20\x7d\x36\x0d"
-  "\x1c\x59\x16\xf0\x79\x24\x1e\xe3\x92\xf6\xb2\x8f\x0b\xdc\xc6\x7c"
-  "\x01\x58\x87\x24\xcd\x47\x8a\xc3\x4c\x27\x15\xcf\x20\xff\x55\x45"
-  "\xa7\x17\xcd\x61\xb4\xe7\x79\x13\xf5\x30\x9d\x86\xaf\x11\xc1\xe1"
-  "\xde\x18\x91\xb5\xd2\x24\x63\x37\xf3\x18\xe7\xbd\x09\xf0\x87\xd4"
-  "\xab\x14\xdd\x5e\x9c\x6e\xd0\xcd\xe8\x3b\xa6\x93\x9b\x0a\x1a\x99"
-  "\xb6\xe1\x6d\x1c\xd6\x76\xd2\x68\x3b\x68\xca\xeb\xa5\x78\x9e\xaf"
-  "\x8f\x8b\x66\xe7\x28\xde\x2b\x7f\x61\xc1\x11\xd3\x77\xe8\x48\xd1"
-  "\x44\x52\xb4\x7d\x11\xf6\xdf\xf3\x66\xd9\x0e\x05\xeb\x28\xd3\x97"
-  "\xc7\x0a\xf0\x6c\xd7\x63\x0b\xe9\xfe\x1a\x2f\xcc\x87\xbe\xaf\xc6"
-  "\xf2\x72\x19\x03\x82\xe3\x8b\xb6\x31\x8d\x58\x2e\xf2\x58\xe2\x31"
-  "\xc0\xe3\x49\xd1\x68\xa9\x29\x84\x46\x4d\x4c\x1f\x9d\x4e\x87\x22"
-  "\x64\x79\xae\x2d\x7f\x8a\x92\xc5\xb6\xe4\x71\x39\x13\x64\x20\x0f"
-  "\xdb\xc3\xd3\xee\xb3\x65\x4c\x19\x57\x94\x97\x32\x5b\x5d\xa6\x65"
-  "\xcc\xe4\x6b\x7c\xb8\xfd\x64\x43\x3d\xf9\xe1\x36\xd8\x8a\x2e\x25"
-  "\x3f\x96\xae\x73\x93\x5f\xf2\x0d\x6c\xe5\xae\x8a\xf3\x44\x01\xa6"
-  "\xe1\x62\xf4\x69\xd9\xee\xa2\x39\x90\xc1\x73\x56\x8a\x2f\xeb\x90"
-  "\xce\x31\x6a\x99\x17\xc1\xf3\x45\x6c\xf3\x7a\xe2\xda\xdb\xf0\xab"
-  "\xf4\xc4\xed\x9b\xf8\xd0\xad\x76\x01\x58\x6d\x46\x5b\xd8\x2e\x16"
-  "\x5c\xbe\x48\x04\x98\x2e\x59\x45\xe8\x6f\x94\x63\x1b\x19\xf9\x7c"
-  "\x98\x03\xd2\x94\x6d\xb8\x0c\xed\xcf\xdf\xa5\xcb\xaf\x0c\x3c\x27"
-  "\xb9\x29\x55\xe1\xe3\xb0\xf2\xfa\x9c\x29\xb8\xf6\xb6\x47\x61\x03"
-  "\x54\x1a\x30\x01\x6b\xa8\x1e\x7b\x4e\xc2\xfb\xba\xbe\x82\xc1\xf5"
-  "\x7b\x0a\x2c\x31\x2a\xce\x1d\xc6\x75\x69\x9d\x16\xcc\xec\xf7\x05"
-  "\xc0\xbb\xe1\x6b\x12\xd9\x57\x20\x13\xfc\xc6\xb1\x2e\xfb\xdf\x55"
-  "\x38\x82\xee\x0a\x2d\xe8\x43\xdf\x25\x2a\x9d\xb9\x8b\x65\x26\xec"
-  "\xcf\x65\x4e\x63\x2e\x93\x73\xa0\x46\xa5\xca\x86\x59\x26\xf7\xf8"
-  "\xce\x3b\x4c\x04\x39\x3d\xff\xe6\x24\x69\x97\xf8\x82\x8e\x18\x52"
-  "\xfe\x99\xcb\x7e\x63\xc8\x55\xde\x63\xb1\xac\x11\x1e\x5e\x5f\xb3"
-  "\xf8\x85\x87\xf7\x5b\xe4\x7c\x41\xa7\xc9\x55\xdc\x53\xca\x71\x48"
-  "\xa5\xde\x83\x7a\xd5\x5c\x11\x50\x73\x05\xea\x87\x2d\x9f\x8d\x39"
-  "\x21\xe6\x34\x2d\x5b\xc7\xf8\x33\x6d\x78\x0d\x37\x08\x5a\xb9\x78"
-  "\x6e\x64\xfa\xc4\xbf\xe5\xe1\x7d\x7e\x6e\xab\xc5\x8f\x36\x87\xb6"
-  "\x4b\x0b\xba\x37\x39\xd0\x2e\x0d\xed\x2a\x3a\xc3\xe3\xc4\xc7\xfe"
-  "\x17\x18\x63\x23\x65\xac\x5d\x69\x63\x17\xee\x0a\x6d\x23\xcb\x7c"
-  "\xd5\x86\xc2\x0f\xa3\xb5\x51\x68\xdc\x46\xa6\x41\xe1\x36\x7d\x8c"
-  "\x49\x3c\x59\x66\x74\x51\x61\xe6\xf0\x35\xec\xf7\xb0\xbb\x08\x7c"
-  "\x34\x8d\xfb\x10\x73\x66\x25\xe3\x19\xad\xbf\x18\x9e\x82\xf5\x52"
-  "\x8e\x65\x4d\x69\x76\x8f\xe3\xa5\xd4\xe8\xf4\x7e\xe9\x91\xcb\xd3"
-  "\xfb\xa5\x71\x5c\x9e\xf1\x60\x3f\x10\x8b\x1f\x06\x3a\xf8\x16\x36"
-  "\x5a\x59\xb4\x7a\x87\xaf\xa9\x67\xbc\xa2\xbe\x83\xdc\xe9\xaa\xd0"
-  "\xe5\x0e\xf8\x50\xcc\xc1\x8f\xe5\x10\x70\x6b\x36\x64\x90\x25\xc6"
-  "\x16\x2b\x65\x82\x26\x2a\xa3\xc1\xb0\xac\xa9\x64\xbf\x8b\x69\xa8"
-  "\x3f\xea\x7b\xd0\xd8\x06\x1a\xe5\x05\xd7\xde\x7e\xb3\x25\x86\xa6"
-  "\x7a\x62\x6f\x8f\xb7\x14\xf9\xc7\x32\x0d\x01\xb3\x08\x63\xf7\x13"
-  "\xb6\x4d\x55\x6c\xac\xe5\x98\xff\x5f\x95\xeb\x79\x9e\xb8\xdd\x79"
-  "\x2a\x7e\xd6\xf2\x4c\x37\x6d\x38\x6e\xac\x6b\xe2\x39\xcf\x4d\x9f"
-  "\xea\xeb\x55\xd7\x6f\x17\xeb\xf7\x41\x5e\x5b\x84\x6d\x95\x05\xba"
-  "\xe3\x0a\x8e\x43\xae\x89\xf8\x7d\x34\xc0\x27\xca\x27\xc4\xe0\x13"
-  "\x94\xdf\x13\x9d\x07\x96\xff\xf1\xf2\x3c\xb0\x5c\xee\x17\x33\xdd"
-  "\x95\x7d\xb2\xdc\x63\xe8\x26\x62\xed\xf5\xdb\x6d\x25\x5c\xff\xf2"
-  "\x75\xaa\x6e\xa6\x49\x1a\xaf\xd5\xcf\x04\x5d\x4a\x7b\x1c\x2b\x46"
-  "\x1b\x72\x80\xf9\xc5\x12\xa0\x18\x96\x45\xcc\x2b\x78\x37\x09\x72"
-  "\xa6\x5a\xad\x21\xee\x6b\x94\xdf\x88\x72\x2c\xb5\x79\xec\x79\x3b"
-  "\xd8\x87\xd3\x1b\xb7\xdb\x8d\x3c\xf3\xdd\xf4\xdb\xb1\x32\x8f\x79"
-  "\x77\x3b\x60\x1c\xaf\x1a\x81\x79\x59\xf9\x32\x25\xf0\x98\xe6\xb8"
-  "\x37\x3c\xae\x91\x96\x04\xbc\x39\x06\x0e\x6c\x9c\x15\x55\xfd\x73"
-  "\x91\x23\x0d\xb2\x42\xc8\xf9\x10\x73\xd1\xe8\x6e\xd0\xee\xe7\x5a"
-  "\x70\xcf\xc5\x09\x56\xe2\x36\x5f\x5c\x3b\x6a\xcf\x4f\xee\x20\xd3"
-  "\xff\x63\x7d\x9a\x0a\xee\xa2\xa4\x35\xdf\x31\xd1\xff\x9e\x44\x1a"
-  "\xd3\xc1\x4d\x2b\x76\x29\xda\xad\xe8\x30\xfa\xc7\x4d\xcb\x67\x72"
-  "\x7f\xf0\xfa\xdb\x1c\xbf\xf8\x52\xad\x11\x16\x41\xfe\xe5\x38\xd5"
-  "\xfb\xa5\x45\x91\xeb\x3e\xac\xc3\xdb\x16\x2d\xb3\xe5\x2c\x59\xb1"
-  "\x78\xcc\x98\x30\xfb\xc8\x24\xcf\x75\x38\x8a\xac\x6a\x0e\x2d\x9a"
-  "\x69\xe0\xcd\xba\x08\x9e\xd1\xfe\xa5\x97\xc4\xf9\x9e\x99\xa5\xbb"
-  "\xee\x66\xa5\xd2\xc0\xfd\x9d\x34\xf3\xce\x90\xc7\xbb\x69\xe6\x5d"
-  "\x77\x67\x3d\x9a\xbb\x20\x67\x65\x48\xea\x3d\xa1\x6b\x72\x15\xdb"
-  "\x51\x77\xec\xa8\x07\x21\x2b\x62\x66\xbf\xcc\xf3\xc9\xca\x07\x4a"
-  "\xfc\xe2\xef\x90\xd7\x93\x30\xc6\xb2\x5a\x0a\xfd\xd4\x02\x59\x26"
-  "\xae\x67\x19\x3e\x4c\x9d\x57\x83\x0e\x05\xde\xb2\xa0\xed\x1e\xe8"
-  "\x72\x17\x78\x4d\x06\xe5\x72\x5b\xab\x39\xf6\xec\xbe\xc9\x4a\xaf"
-  "\x58\x69\x43\xfa\xd5\xb8\xce\xc0\x75\x28\xae\xb3\x6c\x8b\x61\xeb"
-  "\xb0\x7f\xf0\x72\xf6\x0f\x5e\xc9\x78\xc4\xdc\xe1\x2d\xa5\x3b\x96"
-  "\xb2\x9e\x5e\xd4\xce\x7a\x87\x9b\x56\x96\xf1\xfe\x00\xe7\x45\x99"
-  "\x31\xb6\xe7\x28\x95\xaf\x42\xee\xab\xac\xb4\x89\xf2\x7d\x93\xc5"
-  "\x8e\x4c\xfe\x76\xcb\x58\xa4\xbf\x12\x1b\x73\x82\x62\xad\xc3\xbe"
-  "\xdf\xe3\x58\x89\xf9\x2f\x57\x8e\x8d\xc1\xbe\xf7\xc6\xba\x06\x8f"
-  "\xf9\x01\x5d\x04\xba\x20\x74\x91\xac\xa2\xf5\x84\x7b\xd3\x80\x1e"
-  "\xb2\xb2\xad\x5f\xa7\xd5\x28\x1e\xcf\x6e\x83\xdf\x71\xdf\x65\xf0"
-  "\x63\x58\x6c\xb0\xc5\x85\xb9\x4b\x73\x73\x6c\xe3\x96\xc5\x53\x48"
-  "\x64\xb0\xbc\xdc\xc5\xb6\xa5\xb9\x2f\xbe\x94\xbb\x4c\x46\xf5\xe2"
-  "\xb7\x61\xf3\x79\x92\x88\xff\x75\x81\x71\x66\xc5\x36\x8a\xe9\xb8"
-  "\xea\x11\x8e\x27\x25\xd6\xff\x9a\x7d\x18\xbb\x94\x2d\xe1\x49\x0e"
-  "\xb7\x25\x5e\xee\x50\x3a\xdc\xbe\x14\x65\xc7\xbc\xbc\x92\x9f\x4f"
-  "\xd2\x2a\xff\x40\x0c\xea\x55\xfb\xf8\x3b\x08\x3a\x7d\xda\x7b\x1c"
-  "\xab\x76\x19\xf4\x71\x53\xb1\x71\x8e\xa0\x4b\xca\x09\xcc\xa5\x90"
-  "\x73\x61\xf3\xa8\xfa\x9e\xdb\xaa\xbd\xbc\xc7\x2a\xd7\x64\xe3\xf6"
-  "\xa5\x72\x5d\x0c\xf3\x14\xca\xa3\x1f\x52\x20\x1f\x59\x8e\x95\x19"
-  "\xf0\x50\x67\x15\xd7\xa7\xdb\x38\xdf\x3c\x4d\x2f\xcb\x3d\xeb\x60"
-  "\xd9\xbe\x54\x96\x1d\x77\x48\x9d\x03\x70\xe4\x3e\x56\x71\x0a\xeb"
-  "\x8f\x32\x0e\x3a\x60\xf1\x1a\x2c\x64\x40\x1a\x7f\xfb\x8f\xd3\x54"
-  "\x5c\xab\x95\xd2\x4f\x10\x75\xc1\x1e\x7a\x39\x67\xc0\x2f\xbb\x38"
-  "\x85\x75\x4a\x86\xeb\xa6\x97\x93\x19\x9e\x8a\xdb\xf5\x32\x70\x29"
-  "\xda\x33\xa0\x1b\xbd\xdc\x1c\x62\x73\x01\x1f\x85\xa7\x17\xb8\xc8"
-  "\x18\x91\xca\x6f\x4e\xb6\x9b\xe5\x64\x95\xde\x76\xa3\x3d\x80\xd7"
-  "\x0e\x9e\xab\x32\xf6\x5d\xdd\x7a\xbb\x19\x3f\xc6\x3d\x14\x67\x85"
-  "\xef\x2a\x96\x4b\x18\xc3\xc5\x89\x21\x63\x98\xd7\x5c\x86\x20\x6d"
-  "\xec\x80\x3f\xee\xaa\xfc\x48\xf9\xf0\xe0\x82\x67\x9e\x67\x23\x7d"
-  "\x66\x6a\x8a\x8d\x65\x45\xd6\xa3\x0f\x4d\x7b\x3c\x6b\xda\x9c\x79"
-  "\xb3\xe7\x4a\xff\xfb\xfe\xf7\xe9\x8b\xa3\x67\x08\xe7\xab\x44\xf0"
-  "\x46\x32\xfa\x6b\xc8\x49\x2a\x71\xab\xf8\xcc\xc5\x7b\xc2\xe3\x33"
-  "\x17\x3b\xf1\x3b\x8e\x1f\x34\x93\xd5\x6e\xfc\xa0\x47\x96\x1c\xd3"
-  "\xf9\xa5\x0b\xf8\x1e\x1b\xe0\x97\x12\xb9\xe6\xcd\x7e\x09\x6a\x2d"
-  "\xb5\x18\xf2\x7f\xd5\xd8\xd0\x77\x03\xb6\xdf\xea\x84\x7e\xdb\xaf"
-  "\x5f\x16\xac\x9e\x64\xd8\x81\x48\x9b\x08\x1b\x30\x8e\x6d\x40\xb5"
-  "\xf6\x53\x22\x75\xac\x48\x5b\x6d\xc0\x4e\x33\x93\x61\x03\x72\x6c"
-  "\x48\xde\xf7\x54\x63\x74\x75\x61\x88\x8d\xe5\x95\xf1\x02\x2f\x2a"
-  "\x9b\x90\xcb\xc9\xb5\x36\xb3\x27\x89\xd7\x9f\xa1\xd7\x26\x63\x8e"
-  "\xc7\xbc\xd3\x23\x44\x9c\x27\x49\xc7\xe9\x10\xaf\x47\xb3\xbe\xab"
-  "\xec\xbd\xe2\x49\x2c\x7f\xc5\xda\x51\x0f\xce\x09\xc8\x58\x6a\x90"
-  "\xbd\xab\xdb\x07\x78\xae\xc4\xcd\x7d\xc9\x34\x00\x1f\x74\x80\x0e"
-  "\xa6\x81\x36\x97\x50\x7f\x9b\xf5\x75\x0c\x63\x0d\x43\xd5\x55\x72"
-  "\x62\xb0\xf6\x45\x6f\x5b\x49\xc6\x57\xb6\x8d\xbf\x99\x83\x71\x61"
-  "\xb4\xf1\xd2\xf6\x95\x54\x45\xb4\x2f\xf3\xd2\xf6\x95\x34\xf6\xef"
-  "\xbb\xf4\xaf\x4b\x94\x9c\xe0\x76\x32\x1f\xa0\x9d\x47\x63\xad\xe6"
-  "\x6f\x85\xdc\xa7\x44\x93\xab\xc3\xd7\x68\xfa\x19\x10\xfb\x3d\x4d"
-  "\xa3\xa5\x9d\xe6\xdb\xac\x05\xf3\x36\x3b\xf0\xc3\x95\xf5\xec\x01"
-  "\x5d\x55\xf8\x14\x7e\xf6\x89\x4d\x90\xbd\xbc\xd6\x32\xd8\xd9\x36"
-  "\xd0\xec\xb8\xb1\x0e\x80\xfb\x76\xb6\x27\xe7\x04\xa6\x0a\x4e\x67"
-  "\x1a\xc0\x26\xf1\x80\xaf\xda\x95\xde\x66\x5f\xd7\x2f\xb3\xbf\x35"
-  "\x35\x3b\x76\x0d\xd9\x8e\xd4\xdc\xc5\xe9\x35\xe8\x3b\xb9\x36\x28"
-  "\xbf\x91\x37\x08\xcc\xac\x40\x1a\x0d\x02\xf7\xb8\x01\x77\xb0\x73"
-  "\x90\xa1\x69\x4b\x16\xdb\xf2\x16\x2c\xce\x59\xb2\x70\x61\x8a\xed"
-  "\xa5\xc5\x4f\xe7\x2f\x79\xe6\x79\x16\xfc\xcb\x0a\x5f\xc2\xf8\x95"
-  "\xe3\x36\x7d\xe6\xcc\xac\x07\xe7\x3d\xf6\xa3\x30\x1d\xc0\x5c\xe9"
-  "\x08\x96\xc9\x6f\x64\xad\x7d\x6e\x55\x8f\xa3\x14\xfd\xff\x6c\x91"
-  "\x9a\x6f\x4a\x31\xff\x3f\x93\xa0\x74\xad\x27\x3a\xd5\xd9\xcf\xd2"
-  "\xc6\x10\xb9\x36\x1c\xcf\x4d\xfc\xad\x83\x81\x35\x90\xd2\xca\x50"
-  "\x1d\xa2\x5b\x7e\xa7\xae\x74\x97\x11\x07\xa1\x70\x0c\x69\xa6\x31"
-  "\x95\x54\xa5\x89\x52\x37\x95\x1e\x85\xbd\x78\x1c\xef\x9b\xdc\x94"
-  "\x57\xad\xdb\x8f\xc7\x79\x8f\x95\xed\xc7\x00\x6c\xc9\x39\x2b\x9d"
-  "\x53\xb3\x56\xc6\xb0\x0f\xb1\xfc\x6e\x82\xff\xa2\xe8\xe0\x7d\x4e"
-  "\xde\x33\xe2\xef\x26\x54\x3c\x27\xed\xc9\x58\x99\x07\xf7\x15\xa7"
-  "\x48\xda\x56\x78\x6f\xab\x3b\x25\xbf\xdd\x08\xfb\x63\xcd\x58\x43"
-  "\xf7\xb4\xac\xb1\xc9\x33\xa9\x9b\x54\x7f\xb4\x73\x5f\x70\x7d\x59"
-  "\x2b\x9d\xaa\x0e\xf4\x01\xca\x5a\xd4\xba\xcf\x9a\xf9\x97\x5d\xcf"
-  "\x8e\x6b\x6f\x1c\x34\x06\xb9\xa3\x74\xd8\x66\x15\xaf\x98\xfd\xe0"
-  "\x3c\x86\x1f\x16\xfb\x64\x01\xee\xa1\x48\x9f\x2e\xe5\x97\xb0\xa6"
-  "\xd9\xf0\x07\xc1\x7d\x7b\xbf\xbe\xcc\xdf\xda\x80\x9d\x63\x2b\x59"
-  "\x33\xf4\x2c\xad\xd9\x56\x37\xc8\xba\xb2\x71\x06\x55\xf7\x9b\x1a"
-  "\xd6\xe3\x70\x8c\xee\xf7\x25\xc1\x33\x8f\xf1\x01\x7f\x30\xc7\x24"
-  "\xc3\x9f\x48\xfa\x90\x61\xce\xe2\xef\x79\x9c\x22\xc7\x8f\xe4\xf7"
-  "\x43\x6e\xe6\x35\x61\x47\x51\x93\xf4\x65\x73\xe4\x84\xe2\xa2\xf0"
-  "\x70\x8c\xe3\x75\x4b\x7e\x1f\x8a\x4b\xd1\x82\x97\x16\x4d\x28\x5a"
-  "\xb8\xc8\xf6\x4c\xde\xa2\x82\xac\x45\x32\x6e\xa8\x0c\x49\x5a\xb8"
-  "\xb2\x80\x57\xe9\x6f\x8d\x8f\x98\x2b\x74\xbf\xb3\x7e\xff\x1a\xe9"
-  "\x7b\xe6\xf8\x0c\xf4\xd0\x94\xef\xd9\xda\x36\x35\x1f\x3a\x3a\x2f"
-  "\xf5\xb3\x70\xf8\x0d\x3f\x0b\xf0\x55\x62\x95\x8a\x57\xae\xfb\x66"
-  "\x30\xdf\xad\x1d\x7d\x69\x99\xb5\xa9\xfd\x7e\x46\xec\xef\xd2\x97"
-  "\x29\xcf\x08\xc8\xd8\xd2\xaf\x71\xbf\x39\xd6\xb9\x8a\x1e\xe2\x3d"
-  "\x62\x9d\x9f\xd7\x66\x1b\xfc\x6c\xf8\xa8\x31\x2c\x3e\xa3\x30\xc1"
-  "\x17\xea\x9f\xb2\xf6\x43\xcc\x2d\xd6\xfe\x76\xbc\xac\x11\xe3\xee"
-  "\xd5\x9c\x8c\xc7\xae\x48\x3c\x80\xdf\x18\xa4\x87\xf8\xff\x18\xed"
-  "\x5c\x0b\xfd\x6f\xdd\x25\x3a\xde\x03\x0f\xcd\x84\x32\xb7\x2c\xb7"
-  "\x30\x9e\xa6\x2d\xc8\xcf\xe7\x71\xbd\x20\x37\xff\xa5\xa5\x4b\x96"
-  "\x65\x2d\x5a\xbc\x08\xa9\x0f\x2c\xe4\x70\xae\x32\xcb\x7d\xfa\x1b"
-  "\xdb\xe2\xdc\xdc\x1c\x95\xa4\x77\x43\xf8\xde\x88\xda\xff\x5e\x97"
-  "\xe6\xa6\x35\xbe\x01\xbd\x65\x5d\xb5\xd0\xd6\x1e\xc7\xef\xef\x72"
-  "\x4c\x4b\x9d\x62\x5d\x4e\xb8\x5d\xb0\xae\xd0\xe0\x07\xd9\x7f\x76"
-  "\xf6\x11\x79\xf3\x93\x6e\x21\xf7\x12\xd0\x67\xaf\xfc\x91\xbf\x7b"
-  "\xea\xa6\x57\x8e\xb2\x3e\x1c\x02\x67\x6f\x3f\x2d\xd7\x3e\x21\xbf"
-  "\x9b\xc9\xf0\xf8\x7b\x6f\x7c\x36\x1b\xef\xc1\xff\x6b\x4a\x15\xff"
-  "\xaf\xeb\xe7\xff\x6e\x2d\x16\x36\xce\xba\x4e\x43\x0f\x0e\x1f\x33"
-  "\xaf\xd0\xa5\x63\x89\x7d\x06\x5f\xb1\x1a\xb4\x35\xfa\x59\xf1\xd6"
-  "\x2b\xbf\x31\xd6\x26\xeb\xf4\xd8\xe2\x7c\xcf\x65\x59\xc7\x15\xc3"
-  "\xaf\x9a\xca\x3e\xd0\x27\xe9\x95\x75\x8a\x5f\x5e\xc9\x0e\xf1\xe5"
-  "\x49\x3c\x4d\xaf\xe8\xf6\xec\x2b\x45\x06\x7e\x68\xe7\x44\x4e\x63"
-  "\x18\x6a\xec\xaf\x0d\x28\xde\x79\xa5\xc6\xa0\x2d\xdb\x8d\x78\xde"
-  "\x3b\x30\xa7\xaf\x9b\xc9\x73\x9d\x7e\x36\xbd\x8f\xdb\x0f\x38\x29"
-  "\x06\x1c\xe4\xc5\xb3\xb9\xc9\xa0\x95\x91\x27\x94\x27\xa6\x2d\x28"
-  "\x80\x51\xb7\x68\xe1\xc2\xdc\xa5\xcb\x8c\x78\xbd\xc9\x4b\xf2\x73"
-  "\x54\x7c\xde\xfb\xd0\xfd\x2b\x30\x02\xa7\x70\x88\x5f\xa4\xaa\xdb"
-  "\x08\x1b\x20\x85\xed\x70\xe9\xef\x25\xf5\xff\xf5\xf7\xd4\xea\xb6"
-  "\xc0\x49\xfa\xc9\x44\x5c\x21\x0f\x5e\xbd\xa0\xf4\xb2\xb8\x73\x3d"
-  "\x8e\x57\xf3\x0d\xbd\xac\x7b\xe8\x24\xd8\xd7\xaf\x16\x1b\xdf\x61"
-  "\x32\x74\x05\x3e\x8b\xe2\x5c\xcc\xb1\xcf\xd7\x6f\x0b\x96\xef\xce"
-  "\x14\xf1\x5b\xca\xa0\x93\x24\x30\xdf\x5f\xd5\xc5\x71\xd1\x39\x5e"
-  "\xcc\xab\x47\x59\x97\x61\x59\xc2\x31\xce\x3b\xe8\xd5\x6a\xfe\x76"
-  "\xb3\x9b\xd6\xd7\x78\xe2\x76\x67\xae\x5b\x45\xe6\x9d\x5b\xe4\xf7"
-  "\x6f\xdd\x4d\xf5\x4c\xc7\x57\x3b\x3e\x28\x56\xdf\xd3\xe6\xef\x10"
-  "\x6f\xc4\x3b\xd8\xc3\x0d\xfa\x5a\x72\xbe\xbe\x8e\x97\xdf\xe3\xf8"
-  "\x09\xf4\xbf\x84\x46\xc5\x97\x5b\xc5\xb7\x4b\xa9\x88\xbf\xcf\xa6"
-  "\x62\xbd\x34\xd4\x8b\xb2\x6a\xd6\x63\x3c\xd0\x7f\xa0\x67\xbf\x9a"
-  "\x2f\xca\xab\x49\xc5\x89\x66\xbe\x78\x75\x3e\xb7\x13\xf0\x0a\x79"
-  "\x7d\x87\xd7\x76\x74\xb8\x85\x6c\xff\x41\x8f\x1b\xcb\xba\x1c\x9e"
-  "\x33\x82\x17\xcf\xd4\x63\xee\x36\x63\xae\xf2\xe8\xdf\xfd\x99\xcb"
-  "\x6b\x9e\xc3\xd7\xb8\x31\x17\xdd\x24\xb2\xfc\x89\xbc\xd7\x70\x95"
-  "\xf1\x5d\x25\x5e\xf7\x04\x6e\x7b\x06\xf6\x10\x50\x1e\x34\x01\x3f"
-  "\x96\x76\xd0\x4f\xa4\xaf\x3f\xf3\x22\xd3\xae\x17\xf4\xe2\xef\xef"
-  "\x8a\x8b\x67\x1a\x60\x87\x5e\x75\x8a\x7e\xf2\x39\xd3\x8d\xf7\xfd"
-  "\xd8\x5f\x07\x69\x16\x8e\x1f\x8d\xfe\xf9\x88\x69\xc6\xb8\x88\xb2"
-  "\xad\xd9\xfe\x9e\xcc\xef\xf3\x19\x42\x96\x47\xab\x8b\xa1\xfb\x2d"
-  "\xe4\xb1\x5c\x3e\x8f\xed\x39\xfe\xe6\x07\xdf\xdb\x73\x44\x50\xd2"
-  "\x7c\x15\xd3\xbc\x7c\xde\xea\x4e\x11\xfc\xd2\x41\xe2\xa8\x97\xe8"
-  "\x4b\x8d\xfc\x3e\x2d\x86\xf1\xd6\xec\x67\xf8\x9c\x63\x3d\xb9\x8a"
-  "\xca\x08\xf5\x9a\x37\xad\xa2\x44\x3e\x17\xca\xdf\xb3\x68\xf5\xd6"
-  "\x50\x6b\x41\x0d\xfd\xa7\xbf\x8a\x9c\xcb\xf9\x9c\x7f\xb9\xff\x4f"
-  "\x45\x55\xbc\x97\x12\x87\xfb\x77\x6d\x8f\x73\x5d\x65\x55\x7f\x3a"
-  "\xf6\x67\xfa\x93\xf3\xcf\x64\xfb\xb1\x7c\xde\xd5\x9c\xf9\x9f\xd4"
-  "\x9c\xf6\x9f\x64\xef\x10\x41\xb6\x09\x4a\x5e\xe0\x3a\xca\x00\xab"
-  "\x9e\xcf\x53\x26\x06\xbb\xad\xf1\x68\xbf\x69\x4e\x11\x51\xab\xd7"
-  "\x03\x1e\xfa\x3d\xe3\x38\xae\xf6\x3c\x99\x9d\x8b\xff\x20\xef\x95"
-  "\xae\x7e\xa6\xde\x95\xd3\xce\x7a\x92\x9f\xcf\x8f\xf2\xde\x13\x74"
-  "\xdd\x60\x05\xe3\x18\x50\x78\xf3\x77\xa4\x8d\xf2\xd0\xa3\xf4\xf2"
-  "\x65\x72\x8d\x77\x27\xd3\x03\x38\xb5\xcc\x55\x34\x69\x6e\x07\x4d"
-  "\x1f\xd7\xe9\x93\x19\x4a\x9f\xb2\x74\xa6\x0f\xc7\x1e\x0c\xa2\xbf"
-  "\x80\x5b\x1a\x68\x10\x34\xea\x00\xce\x66\x7d\xdd\xce\xbc\xe9\x3c"
-  "\x25\x38\x17\xf3\xb7\x89\xca\xdf\xb2\x64\x98\xcc\xc1\x8b\x67\x1b"
-  "\x2a\x2e\x90\x89\xfb\x8d\xd7\xe7\x2b\xe4\x7b\x49\xf3\x0d\xdc\x67"
-  "\xa1\xdf\x33\x67\x3e\xe4\x6f\x9a\xa3\xbf\xca\x80\xc3\x58\xf4\x55"
-  "\x3d\x5f\x15\x6f\x57\xb3\x2e\x6f\xec\xe3\x0e\xa4\x83\xb7\xfd\xfc"
-  "\xdd\x41\xb9\x2e\x51\x3e\x36\x08\xde\x66\x7b\xbe\xf6\x35\x4a\x08"
-  "\x3a\x5e\xf1\xec\x84\xac\xa9\xc1\x5c\x56\x3b\x82\x12\x79\x2d\x6b"
-  "\xbb\xf4\x1f\x5e\x9f\x6c\xc8\x9e\xf5\x23\xf9\x4c\x52\xf9\x5c\x4d"
-  "\x7e\x5f\x6e\x77\x81\xce\xe7\x05\xc8\x33\xd3\x4d\xd7\xee\x52\xf2"
-  "\x77\x7d\xa6\x31\x96\xa0\x27\x79\x0c\xfe\xc7\xf8\xcc\xf0\x30\xbf"
-  "\x4b\x3f\x04\x37\x6c\x58\x8b\x60\xdf\xce\x81\x6f\xaa\xad\xaf\x34"
-  "\xf8\x1c\x6d\x2b\x60\x39\xc1\x63\x7a\x30\x3d\x1b\x3a\x5e\xb3\xd8"
-  "\x91\x49\x9b\x4e\x13\x25\xac\x11\x9e\x84\x0e\x8b\x68\xf5\x36\xcb"
-  "\xf3\x6c\xfc\xfd\xc4\x5a\xa4\xe3\x7d\xcc\x6c\xaf\xc7\x02\x9d\xb0"
-  "\x8d\xe9\x6f\xa4\xf3\xfe\x02\xaf\xc7\xcc\xf6\x0a\xcf\x9c\x95\x16"
-  "\xfe\xbe\xdb\x68\xb9\xe6\xac\xa7\xb7\x5a\x79\xdf\xc1\x63\x01\xfd"
-  "\xfc\xfd\xb0\xba\x33\x63\x19\x4f\xe4\x4d\xea\xcf\xdb\x9d\x69\x72"
-  "\x15\xa9\x3a\x43\xd2\x86\xcc\x29\x42\x59\xee\x6f\x3d\x4d\xe9\x92"
-  "\x3f\x2d\xe8\xb7\x8f\x38\x4e\x5f\x37\xe6\xbe\x65\x99\x31\xc1\xee"
-  "\x4c\x2d\x00\xd8\x18\x3f\x89\xf2\x3b\x73\x7e\x8f\xfe\xad\x97\x4e"
-  "\xc8\x80\x76\x12\xe5\x9e\x54\xe4\x33\x31\x5c\x3e\x13\xcd\x71\xf2"
-  "\x45\xdc\xf9\xa8\xfa\xa3\x28\xfb\xac\xd3\x59\xf2\x63\xf0\xe4\x86"
-  "\x22\x96\x09\x01\xf3\x9e\x6c\xdb\x73\xac\x63\xfc\xf4\x0b\xee\xff"
-  "\x00\xc6\x69\x20\x6e\x4f\xf6\x84\x4e\x8a\xe1\xef\xfd\xa9\x35\x8d"
-  "\x0d\x57\xf3\x19\x70\x7b\x50\x40\x6f\xdb\x20\x79\xcf\xd2\xc5\x7e"
-  "\x55\x7b\x72\xa4\x2f\x53\xfc\x27\x6e\x97\xaf\x93\x9a\x4b\x3f\xa5"
-  "\x66\xbf\xab\xf4\xf0\x79\x8f\x49\xf9\x34\x99\x00\x77\xc3\x38\x7e"
-  "\x67\x07\xbf\x67\x05\xea\x69\xb0\x35\x65\xb6\xf5\x30\x0f\xfd\x4d"
-  "\xd9\x50\x1b\x8a\x0c\x1b\xef\x2b\xda\xd0\xc6\xe7\xc8\x85\xb0\x52"
-  "\x70\xfd\xef\xf8\xbb\x16\x76\xd1\x93\x4c\x13\x56\xf1\x1a\xcf\x86"
-  "\x3d\xd0\xdd\xd3\x74\xb8\xe7\x74\xb8\x6d\x97\x83\xcb\x3c\xd3\x5c"
-  "\x2d\xf7\x33\xd0\xa6\xdf\xb5\x05\x00\x3b\x10\xdf\x98\x08\x19\x6e"
-  "\xb7\x7f\xc9\x6b\x7d\x9b\x6e\x40\x3d\x6d\xad\xfe\x36\xe2\x98\x14"
-  "\xb5\x41\xcc\x71\xe7\xac\xa4\xfb\x6f\xd9\xcf\xd2\x46\x5e\xab\x4e"
-  "\x84\x2d\xca\xeb\xf8\x76\x96\x93\x6c\xd7\x96\x04\x68\xa8\x0b\x5a"
-  "\x0d\x9f\xa7\x06\x8c\xab\x3f\xe4\x3d\x13\xc8\x9a\x80\xb0\x6a\xef"
-  "\x5e\x74\x13\xfb\x68\xc8\xf3\xd5\x6b\xaf\xdf\x3e\x7c\x0d\x4d\x15"
-  "\x9a\x45\xfa\xe7\x05\xcb\x3f\xee\x44\xdf\x4e\x52\xfe\x62\xbb\x8b"
-  "\x43\x7c\xc5\x62\x51\xd7\x2b\xec\x2b\x26\xcc\xbb\xd3\x6b\x78\x0f"
-  "\x23\xee\x13\xa7\x27\xae\xbd\x41\xa0\xef\x7a\x1c\x1b\x1b\xdd\xf4"
-  "\x53\xb9\x66\xbb\x81\xfd\xab\xa5\xbc\xde\x34\xce\x13\x77\xb0\x51"
-  "\xa8\xb3\x57\x31\xc1\xe5\x81\x86\x8a\x2f\xc8\xa4\xe8\xb2\x69\x48"
-  "\x6b\x57\x8f\x53\x94\x1d\x6c\xe4\xb3\x33\x7a\x1d\x16\xd4\xf1\x17"
-  "\x51\x7e\x10\xb0\x36\xe9\x32\x83\xef\x37\x7a\xf8\xbd\xbf\x2f\x19"
-  "\xba\xd1\xc6\x9c\x9a\x5e\x5e\x4b\xde\x98\x28\x1c\x37\x39\xbb\xcd"
-  "\x07\x1b\x1f\xb3\xb2\x7e\xb4\x69\x92\x3b\x66\x5f\xa3\xbe\xbe\x24"
-  "\xcf\x8c\x47\xae\x0b\xf5\xf7\xe5\x0e\x6b\xbc\x0b\x40\x60\xef\x25"
-  "\x9d\xa6\xca\xb7\x7a\x1d\xa4\xf5\x41\xaf\xeb\xd5\xa0\xbf\xef\xc8"
-  "\x4c\xd8\x34\x8a\x52\xf1\x6e\xd4\x69\xda\xb4\xd1\xaf\x51\x12\x7e"
-  "\x89\x9e\xeb\xf3\xe2\x00\x37\x8d\xd7\xde\x5a\xce\xf3\x5a\xcb\xa6"
-  "\x33\x52\xef\xda\x4e\x63\x83\x80\xc7\xfb\x05\x15\xa3\x68\x2c\xaf"
-  "\x7f\x21\x2d\x39\x2b\xa0\xf6\xcd\x0c\x5b\x7d\xed\x28\x4a\x09\xaf"
-  "\x77\x93\x7e\x16\xbc\x52\xae\xa5\xaf\xf0\xd0\x8d\x05\xf7\xf3\x77"
-  "\x01\x2b\xf2\x84\x23\x56\x88\xeb\xad\x9a\xda\xcf\xae\x78\xc4\x52"
-  "\xad\xf8\x4f\xee\x13\x81\xef\x78\x1f\x4e\xdf\x93\x88\x91\x67\xe5"
-  "\xe3\xf7\x7a\x44\x5f\xb2\x16\xb2\xfe\x98\x28\xf1\xd0\xcf\xb9\x06"
-  "\xd6\xde\x96\xcd\x30\x18\x9f\xac\x05\x6a\x3f\x83\xcf\xc0\x82\xc6"
-  "\x32\x1e\xeb\x86\xed\x94\xf0\xd3\xed\x94\xd8\xb2\x90\xdb\x55\xa1"
-  "\xca\x68\x26\x62\x7c\x83\x65\x3c\xde\xc0\x1b\xc0\x9b\xeb\x93\xdf"
-  "\xd4\xf5\x9f\x73\xda\x0b\x45\xd0\xf9\x1c\xeb\x95\x15\x1f\x38\x97"
-  "\xee\xa5\x39\x7c\x66\x98\xcf\x0b\xcd\x27\x4f\x1d\xe0\xd5\x8d\xa2"
-  "\x44\xc0\x6a\x71\xe5\x13\xaf\x77\xdf\xec\x5c\x7a\x88\x61\x9f\xe0"
-  "\x79\x65\x23\xe8\xa3\xe6\x97\xca\x2a\x97\xaf\x9d\x5a\x30\xce\x67"
-  "\x17\x88\x00\xc3\x39\x45\x95\xd7\xc9\xf6\xee\xb0\xda\xb2\xd4\x39"
-  "\x65\xd9\xd6\xfe\x7d\x22\xbd\x1d\xae\xf3\x0c\xaf\x32\xc5\x95\x0d"
-  "\xfb\x56\x6f\x93\x41\x6b\xc5\x5f\x95\x8b\x9c\x4b\x77\x11\xf7\x0f"
-  "\xe7\xc7\x73\xa6\xab\x0b\x79\xcf\x84\xf7\x0b\xe7\xc1\xbb\x72\xc0"
-  "\xfd\xee\xc0\x5e\x27\xef\xc1\x0d\xe4\xa9\xd9\xce\xe7\x21\x36\x35"
-  "\xef\x00\x8d\xd4\x9a\x71\xc5\x05\xc6\x15\xa3\xc8\xeb\x2a\xfc\x34"
-  "\xba\x1f\x23\x64\x00\xf8\x7e\x4d\xab\xdc\xf3\xa9\xfc\x7c\xb6\x3f"
-  "\x28\x94\x5c\xfb\x59\x75\x10\xf2\xc0\x8d\x2b\xcb\x04\x29\x57\xee"
-  "\x60\xdf\x91\x9f\x6d\xb3\xc4\xa8\xfe\xe5\xb6\xb0\xee\x13\xad\x8f"
-  "\x43\xf6\xa3\xd8\x97\xb3\xbf\x8f\xf9\x9b\x66\x41\xde\x53\x1c\x05"
-  "\x7a\xf7\x59\x49\xf1\x9f\xa8\x04\x5c\xdd\x3f\x7e\xf7\x61\x7d\x5e"
-  "\x3c\xdc\x1d\xb7\x27\x5f\xbc\x6c\x25\xc3\x9f\x14\xe3\x37\x2f\x4b"
-  "\xf9\xe8\x5a\x59\x56\xd5\x69\x6a\xec\x30\x8e\x7a\xd9\x46\xb5\x8f"
-  "\xff\xb3\x4c\x94\x8f\x2e\xe3\x63\x21\x7f\x1c\x10\xd7\x68\x0f\xcf"
-  "\x9f\x02\x32\x0b\xf3\xc2\x50\x97\xb7\x57\xff\x76\xdc\x6b\xd7\x42"
-  "\x67\x1e\xca\x67\x13\x0c\xdc\xae\x6c\xef\xe8\x67\x6e\x65\xa7\xbc"
-  "\x66\x33\xd6\x5e\x84\x19\x34\x76\x58\x04\x9f\xe1\x61\x5f\x73\x6f"
-  "\xdc\x67\x98\xd7\x3d\x36\x35\x6e\x5e\x9b\x0e\x9d\x57\xca\xdd\x2c"
-  "\x1f\x95\x72\xbb\x78\x6f\x10\x36\xd0\x50\x6e\x33\xe0\xe4\xb9\x69"
-  "\x61\xb3\x9a\xd7\x15\xec\x41\xd7\x3e\x8c\xb6\xa1\x4d\xb2\x6d\x68"
-  "\xa3\x6c\x9b\xfe\xcd\x15\xd4\x25\xcf\xee\x5e\x59\x7b\x5e\xd3\xf5"
-  "\xfd\xcf\x3c\xfc\x5d\xc8\x53\x54\xb5\x5a\xfa\x5b\xa3\x4f\xd4\xfa"
-  "\xfa\xe6\x49\x22\xfe\xa7\xf1\x57\x06\x73\xb3\x49\xc1\xf4\xd8\x7e"
-  "\xce\xf1\xd9\xf4\xef\x36\x01\x76\x2e\x64\xba\x8d\x6d\x83\x6e\xd4"
-  "\xc7\xdf\xbc\x1b\x90\x43\x9b\x3b\xb9\xaf\xee\xd8\x4b\x69\x8a\x0f"
-  "\x37\x7f\x56\xab\xbe\xb9\x03\xdd\x60\xf3\x06\xf0\xbd\xfa\x66\x4d"
-  "\xbf\xef\x71\x8c\xf4\x3d\x0e\x95\xb1\x57\x88\xa3\x94\x77\x22\xfe"
-  "\x63\xe8\x55\x9b\x8b\x79\x3f\x9d\xf1\x5d\xe1\x37\xe4\xdf\xe6\x62"
-  "\x63\x6f\x49\xee\x27\xaf\x04\xaf\x94\xa8\xb3\x8b\x3d\x8e\xaa\xd1"
-  "\x86\xae\x22\xbf\xd3\xe3\x10\x47\x39\xdf\x9c\x95\xe7\xe4\x7e\x73"
-  "\x85\x3c\xa7\x7b\x5a\x3f\xe3\x52\x75\xa7\xbe\x36\x91\xcc\x7e\xdf"
-  "\x28\x0b\xfd\xef\x90\xf4\xe3\x67\x1a\x70\xdd\x12\x77\xf9\xad\x9c"
-  "\xaa\xc2\x81\xfd\x84\xcd\x19\x32\x5d\xfa\x42\x56\x6d\x30\x78\x04"
-  "\xed\x1d\xaa\xe2\xe5\xbd\x76\xe1\x48\x0a\x49\x1e\xe8\x16\xd6\xf8"
-  "\x5b\x6a\x98\x27\xab\x0e\x85\xd2\x69\x8e\x3f\x68\x57\x32\x68\x73"
-  "\x8d\x90\x63\x7d\x73\xcd\x57\xeb\x15\x3f\x8f\x33\x74\x12\x45\xe7"
-  "\x44\xc8\x97\xad\xc7\x24\xad\xcb\xb6\xd6\x73\x2c\x83\x97\x4b\x38"
-  "\x1e\xcb\xcf\xff\xc8\xb1\x6e\xfc\x65\x5b\x9d\x01\x3e\x0f\xb5\x90"
-  "\x7d\x52\xb6\xb6\x9d\x2a\x20\x2d\xab\x80\xf7\x50\x0e\x96\xb2\xad"
-  "\x26\xec\xd0\x09\xe2\xa1\xa7\x60\x9c\xaf\x5e\x44\x96\x27\xf3\x00"
-  "\xdb\x9e\x9c\xc4\xb1\x68\x38\x0e\x0d\xc7\x93\x0a\xd8\x93\x47\xe0"
-  "\x7e\x24\xf4\xba\x44\xfe\x36\x3c\xfb\x5b\x04\x1c\x02\xf2\xf8\x38"
-  "\xc7\xc3\xd1\x5c\x1e\x1f\xad\x3e\x43\x66\x8e\x75\xe3\x2f\x3f\x58"
-  "\xdd\xea\xfd\x4c\xda\x29\xc3\x0b\xa0\x9b\x07\x69\x34\x68\x6e\x0d"
-  "\xc6\x1d\x84\x3e\x7c\x70\x9d\x6a\xf7\x39\xa1\xda\xad\xf0\x66\xfc"
-  "\x95\x8c\xdb\xd6\x56\x22\x71\xdf\xfa\x82\x1f\xf0\x83\x65\xb5\xcd"
-  "\x81\xb2\xda\xa3\xea\x1c\x55\x33\x95\x14\x8a\x4e\x17\x74\x64\xf6"
-  "\xf9\xe3\x33\x65\xec\xcf\xc1\x6d\xe4\xf6\x71\xdd\x7f\x3a\x7f\x46"
-  "\xc6\xee\xf1\xe3\xd9\x9e\xaf\x97\xe9\x42\x99\xae\x66\xea\x2d\xab"
-  "\x95\x6d\x6f\xf5\xaa\xb2\x59\xf2\x9e\xcb\x87\xd0\x41\x6f\x73\x3f"
-  "\x1d\xd0\x76\x6e\x1f\xb7\xdf\xcf\x34\x01\x0d\xf4\xb6\x5a\xfb\xf4"
-  "\x76\x72\x1b\xff\x13\xb3\xce\x76\xb4\x13\x6d\x95\xed\xec\x43\x3b"
-  "\x8f\xe6\x11\xf9\xd6\xff\x95\xbe\x8c\xaf\x3d\xca\xb6\xa6\xfd\x23"
-  "\xe8\xd3\xc5\x95\x04\x9b\xd2\xb4\xaf\xa4\x52\x5b\x0f\xdd\xa4\xc4"
-  "\x03\xdb\xd2\x23\x3a\x59\xef\x77\x15\xe0\xe7\xaf\x91\xdf\xdc\x94"
-  "\x7a\x32\x7f\x33\xf1\x45\xb4\x29\xf8\x39\x95\x74\x8a\x4e\xe8\xa8"
-  "\x3e\x97\x1f\x79\xf2\xd0\x7e\xd8\xa2\xa7\x74\xfc\x39\xef\xea\x2f"
-  "\x54\xbb\x2c\xf9\x94\xf4\xfe\x8f\xcb\x34\x57\x7b\x19\x19\x6d\x79"
-  "\x0a\xf9\xd0\x1e\x2b\x60\xc9\xb8\x71\x41\xb4\x73\x07\xf0\xf4\x85"
-  "\xb4\xa9\xa5\xcb\x07\x98\x7f\xa1\xf8\x0c\x8a\xd9\x7e\x16\xed\x38"
-  "\x4b\xd6\xca\x12\xe8\x5f\x8f\xb2\xde\xb8\xe5\x8d\x6f\x64\xd2\x58"
-  "\x37\xfd\x5c\x7d\xaf\xa2\xff\xbb\xe6\x5b\x5b\x8c\xf8\x19\x41\x8e"
-  "\x3f\x14\x77\xb0\x86\xf9\x48\xc6\xd2\xe0\x39\xa3\x07\x3c\xc3\xbe"
-  "\x18\x2b\x50\x47\x4f\xf2\x48\x89\x8f\x43\xc5\xdf\xc0\x33\x7f\x47"
-  "\x25\x89\xd7\x17\x50\xae\x5a\x80\x66\x0c\x1f\xfa\xdc\x3a\xbe\x32"
-  "\x0d\xa3\x9e\x4f\x78\x9b\x20\xeb\xa0\x6b\xc2\x8e\x6e\x28\xf1\x68"
-  "\xaf\xbc\x4d\x29\x57\x26\x53\xb6\xfa\x07\x93\xdf\xbc\xae\xcf\xf0"
-  "\xd0\xb6\x11\xa7\xa9\xfa\x44\xf8\x18\xb3\x49\x59\xa6\xe4\x60\xf5"
-  "\x1e\x5e\x4b\xbf\xb2\x7a\xab\x55\xdc\x1e\x87\x28\xbb\xc2\x72\x7b"
-  "\x0d\x3c\x70\x9f\x37\x18\xee\x57\x4e\x87\x6d\xa6\xc1\x60\x6d\xdc"
-  "\x22\x63\x29\xd9\x37\x6d\x81\xbc\x80\xae\x70\xc4\xca\x71\x6d\x31"
-  "\x77\xee\xf2\xd2\xb2\x9d\x64\xb6\x9f\xe1\xf5\x9d\x59\x74\xa4\x26"
-  "\x95\x6a\x61\xdf\x8b\xee\xe4\x11\x9b\xcf\xf3\x9e\xba\x92\x21\xac"
-  "\x93\xb6\x7a\x51\x66\x59\x72\x62\xc5\x16\x43\x87\xdf\xd6\x52\x7c"
-  "\x81\x34\xf5\xdd\x80\x6d\xcd\xe9\x36\xe1\xaf\xd2\x82\x79\x35\x1c"
-  "\x5b\x26\xbe\x9d\x75\xd0\x3c\x23\xd6\x8a\xd4\x7d\x8a\x30\xe6\xba"
-  "\xad\xf1\x1b\x97\x52\x0a\xc7\x85\xb2\x78\x94\x2e\xa7\xe6\xeb\x6d"
-  "\x2c\x63\x13\xf5\x7d\xe4\x44\x15\x7f\xa5\x3a\xbd\xee\x3c\xea\x92"
-  "\xef\xb7\x8f\x0f\xc0\x96\x91\x70\x97\xd2\xd8\x9a\xf3\x94\xcc\x7a"
-  "\x50\xd6\xe7\x4a\x67\x63\xfb\x70\x56\x97\x45\x04\xfe\x77\x32\xed"
-  "\x3c\x3d\x10\x37\xca\xb3\x8c\x63\x4d\x09\xeb\x60\x67\x44\x2b\x46"
-  "\x4a\x9f\x11\x19\x03\x40\x7d\x57\x8a\xa8\xea\x35\x32\xf1\x77\x14"
-  "\x79\xad\x8e\xd7\x79\xf9\xac\x88\x9a\x43\xb6\xd7\x18\x71\x75\xa2"
-  "\xcb\xf2\x4f\x9c\x13\xa4\x8e\xf5\x89\xf3\xca\xfa\x6d\xfb\xe1\x41"
-  "\x6d\x15\xc0\x64\x3e\xf8\xef\xc1\xdd\x91\x74\x19\xbd\xc6\x14\x2c"
-  "\x53\xb6\x59\x70\x28\x6c\x46\x4f\x8f\xd3\xb9\x9c\xe7\xb7\x1d\x95"
-  "\x7c\x96\x66\xc0\x1e\xdb\xf1\x22\xbf\xe3\x34\xf6\xf5\x4e\x93\xfd"
-  "\xbe\xa3\x91\x6d\x34\xdd\xce\x7d\xdf\xd6\x9f\xa6\xf4\x2d\x9e\x77"
-  "\x99\x5e\x75\x6a\xfd\x7a\x78\x8f\x63\xc7\x31\x63\xee\x65\x1d\x44"
-  "\x7d\x6f\x72\x47\xa7\x3b\x66\xbf\x67\x30\x5a\x1a\xeb\xf9\xd2\xa7"
-  "\x8b\xe3\xfa\x38\x6a\xac\xc6\x5c\x2c\xbf\x27\xb0\x76\xd4\x83\xcb"
-  "\x56\xd2\xe8\xc7\xae\xe3\x3d\x6d\x79\x26\xa2\x53\xe9\x08\x35\x69"
-  "\x03\x7b\x63\x69\x92\x37\xe4\xb7\xc2\xd8\x1e\xd2\xa0\x2f\xa8\x78"
-  "\x56\x5d\x4a\x57\x30\xce\xc3\xd6\x3c\x19\x52\x4f\x69\xff\x9c\x8f"
-  "\x3a\xd8\xb7\x81\xe1\x2b\x3d\xaa\x66\x22\xd7\xc1\x76\xa0\xd2\x05"
-  "\x6a\x26\x5e\x86\xbe\xc9\x4c\xdf\xa0\x6e\xfb\xba\xba\xfe\xae\xe8"
-  "\x5b\x44\xb1\x13\xaa\xc8\xfa\x7e\x89\xdb\x84\x39\x26\xc6\xb6\x94"
-  "\x2c\xa8\xff\x23\x7e\xcf\xe3\xd2\x79\x07\xaf\x41\xee\x1c\xef\x62"
-  "\x1d\xa3\x2f\x33\x61\x36\xaf\x4f\x48\xbb\x61\xe7\xe8\xf1\x28\x87"
-  "\xb4\x11\xef\x9d\xf5\x99\x2a\x56\x51\x0a\x7f\x93\x0f\xe9\xd2\x07"
-  "\xc1\xf3\xcd\xe7\x7b\x6e\x49\x22\xeb\x2d\x55\xec\xef\xbe\x33\xdd"
-  "\x1d\xf3\x76\x8a\x5c\xeb\xe2\xfa\xd7\x7b\x32\x38\x96\xd7\xfe\x5e"
-  "\xf7\x10\xd5\x57\x3b\x4f\xe0\x39\x39\xe4\x79\xb5\xb1\x87\xe0\xa6"
-  "\x9d\x6e\xb9\x0f\xc9\x3e\xbd\xd2\xdf\xb5\xbd\x71\xc0\x57\x66\xe7"
-  "\x09\x1d\x97\x13\x47\x0a\x88\x76\xf2\x39\x86\x91\xa2\x0d\xf5\x41"
-  "\xff\xd9\xe1\xd5\xd7\x90\xda\x24\x5f\xb1\x6e\xfe\x2a\xdb\x8b\x7f"
-  "\x77\x6e\x44\x3e\x9e\xd3\xb2\x8a\x28\x4d\xd9\x1b\xed\x6d\x41\xf0"
-  "\xcf\x40\xfb\x77\xce\xe2\x35\xce\xa8\xf2\x7b\x3b\x91\x2c\x53\xfe"
-  "\xb1\x4f\xfa\x57\x95\x9f\x6f\xc0\xd5\x8c\xb1\x70\x14\xd7\x04\xf0"
-  "\x1c\x5f\x13\x71\x75\xe2\x9a\x04\x3d\xb7\x92\xf9\x12\xf6\xb6\x15"
-  "\x36\x8d\xb9\x3b\xee\x63\xcf\x60\x67\xf1\x98\x36\xae\x75\x8f\x93"
-  "\xf2\x17\xad\x6d\x6a\xf1\x40\x97\x04\x39\x97\xf9\x45\xaf\xed\x46"
-  "\x3e\xf3\x52\xdb\x64\xdf\xc9\xfe\x1e\xb5\xd5\xe1\xfe\x1e\xb5\x8d"
-  "\xf8\xf9\xc0\xe1\x33\xf1\x83\x1e\x59\xdb\x34\xf0\xab\x6b\xec\x71"
-  "\xd4\x36\x81\x8e\x7e\xa9\x6b\x5e\xd1\x78\xad\x95\xdf\x88\xab\x60"
-  "\x1b\x2e\xee\x77\x4e\xd5\x5e\x0f\xe1\xd9\x2c\xe2\x3c\x69\x7a\x7b"
-  "\xdb\xf1\x9c\x68\xb3\x63\x0e\x8e\x03\x4d\x46\xa1\xcd\x71\xe7\x1b"
-  "\xb8\xbd\x8c\x6f\x77\xdc\x27\x47\x43\xcf\x21\x32\x4c\x6e\xbf\x27"
-  "\x0e\xe5\x40\x4b\xf1\xad\xa9\xd9\x06\x3d\x75\x3a\xf1\x7e\x95\xd6"
-  "\x0d\x18\x4a\x67\x43\x7e\xc0\x30\xf2\xf7\xd3\x7e\x14\xc7\xc7\x47"
-  "\x9f\x22\x1f\xec\x77\xb3\x71\xc6\xb1\xc7\x51\xd7\xf0\x41\xbe\xda"
-  "\xcb\xe0\xb2\xde\x90\xb2\x7c\x36\x3e\xac\x7c\x5c\x48\xdf\x8d\x42"
-  "\x5b\xe2\x0e\x36\xe8\x7d\x47\x3a\x2e\x49\x0a\x97\xf6\x86\x53\x54"
-  "\xfb\xa1\xc2\xa7\x6e\xd7\x60\x63\xac\x64\x0c\x74\x54\x48\xe4\x09"
-  "\xca\x76\x9d\xec\x1a\xed\x25\x57\x4d\x10\x7a\x4b\xbb\x27\xad\x44"
-  "\x38\x4f\x51\xfd\xea\x56\x5f\xe7\x15\xce\xe9\xf5\x32\x4e\x95\xe8"
-  "\x2d\x25\x57\xf1\x5d\xf2\x1b\xb5\x67\xe9\xf5\x7d\x2e\x8f\x8c\xf5"
-  "\xcc\xf7\xd2\x87\x97\x7d\x31\x78\x7e\xe3\xd8\x67\xc6\x3a\x41\x10"
-  "\x79\x6b\x39\x1d\x69\x2e\xaf\x47\xc6\x58\x1b\xf0\xa5\xfe\xb8\x5d"
-  "\x8d\xb5\xd7\x73\xe5\xf9\x6d\xc6\xd7\xff\x7d\x27\xe3\x1c\x2c\xfb"
-  "\xb8\x9d\xdb\x60\x87\x0d\xeb\xf2\xf7\x38\x79\xac\xd8\x96\xf3\xba"
-  "\xe7\xeb\x0f\x80\x1f\x45\xb0\xfc\xe3\xf6\x2b\x6b\xc3\xeb\x32\x46"
-  "\xb0\xdd\x2f\xce\x7a\xe2\x3e\x6e\x67\xbd\xaa\xa2\x64\x88\x79\x5a"
-  "\x8d\x70\x76\xc7\xb7\x43\x46\xbe\x9e\xf3\x41\x91\xea\xb3\x2b\x84"
-  "\x9b\x63\xb4\xbd\x56\x6f\x3b\xe8\x25\x79\x76\x42\xb5\x8a\x29\x87"
-  "\x3c\x35\x83\xcf\x65\xed\x6d\x3c\x97\xb1\x9f\xa7\x4e\x8b\xae\xfe"
-  "\x39\xe3\xca\xf0\x18\x3c\x36\xf6\x40\x1d\x7d\xaa\x8e\x5f\x64\xfc"
-  "\xf7\xea\xf8\x45\xc6\xe5\xea\x80\xcc\xb8\xe1\x34\xfd\xe2\xf8\x95"
-  "\xdb\xbf\xbf\x90\xf6\x2f\xe4\x6a\xbb\x92\xa5\xbb\x66\x05\x60\x83"
-  "\xfa\xcd\x1e\x92\xdf\x93\xd1\xa8\xd4\xe5\xf6\x93\xbf\xec\x77\xce"
-  "\x96\xa2\x5e\x72\x2e\xff\x33\x75\xd0\x2f\x65\xfc\xd7\x96\x42\xb6"
-  "\x3b\x3d\x69\x7d\xeb\x3f\x49\xeb\xd3\x7e\x91\xc2\xf4\xde\xc9\xf1"
-  "\xfb\x42\xf8\xac\xd5\xfb\x67\x72\x65\xf3\x5a\x71\x1b\xaf\xd1\xa7"
-  "\x41\x6e\x50\x10\x32\x03\x76\x46\x40\xd2\x03\x3a\x98\xb2\x19\x3f"
-  "\xeb\x94\x36\xa3\x47\x9e\xcb\xbb\x0a\xba\x7b\x82\x70\x2c\x5c\xc7"
-  "\xeb\xf8\x81\xbe\x4c\x5b\x8f\x83\x32\x38\x96\x1e\xaf\xa1\x0b\xf3"
-  "\xee\xf9\x73\xfc\xb1\x42\xda\x84\xb0\x5f\x38\xa6\x9e\xcb\xeb\xa6"
-  "\x00\x6c\x81\x9a\x8b\x94\x54\x03\xfd\x19\xb2\x3c\x91\xe5\x7d\x9d"
-  "\x1e\x53\x6f\xe3\xc5\x81\x98\x7a\xb5\xbc\x5e\xd5\x8e\xfb\x8b\x64"
-  "\x0a\x94\x7f\xd6\xb9\xe3\x22\x8d\xdd\xb9\x9c\x92\x77\xf0\x7a\xe4"
-  "\x3f\x94\xfe\xc6\xfa\x86\x8c\xaf\xb7\x24\x99\xf7\x26\x06\xf4\xb7"
-  "\x15\x1c\xf7\xb3\x5f\x9e\x99\xe4\x3a\xce\x15\xd1\x7b\x97\xfc\x46"
-  "\x80\xbf\xec\x63\x9f\xdf\x7c\xbe\x01\xb4\x3b\xea\xa6\x5f\xce\xec"
-  "\xd3\x5e\x3f\x1a\xad\x6f\x0d\x5f\xab\xaa\x90\x98\x88\x1f\x8c\x55"
-  "\x72\x1f\xb0\x06\x8f\xcb\xb6\x23\x93\x26\x74\x51\xaa\xf2\x9f\x88"
-  "\xc3\x5c\xb9\xcb\xcb\xfb\xf9\x25\x2f\x90\x35\xb0\x63\x7e\x8c\xfd"
-  "\x75\x8a\xe5\xef\x17\xf3\xaf\xe4\x0b\xd1\x39\x21\x9f\x52\x79\x2f"
-  "\x85\x7d\x2c\x6c\x2f\xcb\xfc\x1f\x8e\x2d\xa6\xd4\x50\xd8\xd3\x95"
-  "\xf3\xd3\x7d\xb6\x19\x8b\x9f\x59\xf2\x42\xc1\x82\xc2\x45\x4f\x2f"
-  "\xca\x5f\x54\xb8\xf2\x3e\x19\x4c\x58\xfe\x7b\x78\x5c\xce\x5c\xb9"
-  "\x09\x1e\xa2\x77\x8c\x1d\x58\x53\x7c\x63\x75\x80\xd7\x40\xae\x88"
-  "\x5e\x6f\x4c\xd7\xf7\x15\x3d\x3b\xe5\x3e\xdb\x1b\x95\xd0\xd3\x48"
-  "\xad\x6d\x7c\xe2\xdc\xa8\xe2\xa1\x74\x3a\x6f\x0e\x30\xfc\xe9\x8a"
-  "\x97\x3d\x95\xe0\xe5\xc9\x27\x69\xcf\x7c\xde\xdf\x41\x7f\x1d\x75"
-  "\x15\x9f\x26\xe8\x28\x93\x79\xdf\xa8\x85\xd7\x64\xa4\x0e\xff\xa6"
-  "\x3a\xc3\x70\x56\xc6\x06\xda\x75\x12\xcf\xec\xab\x1e\x14\x99\x3b"
-  "\x02\x4b\xac\xbb\x82\x4b\xac\x6f\x0a\x91\xb9\x3d\x78\x2e\x6f\x87"
-  "\x38\x97\xb7\x7d\xe0\x5c\xff\x9b\xd7\xfa\x1d\x14\x8b\x1f\x78\x61"
-  "\x5b\x62\xc8\x1e\x22\xbf\xbb\x97\x61\x16\x2c\x65\x5f\xae\x37\xd9"
-  "\x3f\x1a\xb6\xff\x36\x8b\xc7\x9e\x17\x3b\xb3\x03\x3c\xaf\xea\xcd"
-  "\x75\xad\x3b\x45\x6a\xdf\xf8\xcd\x1c\xa7\x5c\xe7\x7e\x33\xc0\xe5"
-  "\x78\x9f\x91\xf5\x7e\x19\x3f\x54\x7b\x43\xfa\xf2\xb1\xce\xbf\x73"
-  "\x04\x25\x56\x8e\xa0\x84\x1e\xc7\x9b\xfd\xfe\x5f\xc2\xac\xe6\x56"
-  "\x9e\xdf\x38\xde\x2d\x64\x4c\x0f\xcf\x95\x8c\x07\xf3\x25\x60\x1e"
-  "\xe6\x3d\x48\x75\xee\xe7\x4d\xf0\xd9\xc2\x3d\x57\x2e\x63\xdf\x94"
-  "\x6b\xf2\x42\xb3\x8b\x09\x1b\x28\x5b\xee\x0f\x2b\x3f\x45\x13\xc6"
-  "\x61\x86\x6a\xcf\x9e\x7b\xe4\xde\xfe\xf2\x33\xf5\x18\x27\xa5\x75"
-  "\xbd\x94\x10\x2c\xdb\x3d\x97\xf5\x99\x96\x62\xb9\xaf\x6e\x46\xb9"
-  "\x06\xde\x77\x97\x67\xe5\x64\xfc\xe4\x3f\x53\xdd\x05\x32\x75\xd0"
-  "\xee\x74\xde\x1f\x18\xa0\xed\xee\x6d\xbc\x2f\x24\xd6\x6f\x29\xb3"
-  "\x14\x6b\x65\x0c\x23\x78\xf1\xec\x24\xa3\x1c\xe6\xf0\x61\x5c\xee"
-  "\x24\xed\x5e\x2d\xcb\x71\x5e\xf9\xed\xbd\xc4\xf9\x98\xb7\x7c\x9c"
-  "\xdf\x8f\xe7\xda\x60\x62\x86\xc0\xf8\x0a\x2c\x0f\x34\xe0\xdd\xdc"
-  "\x60\xd9\x27\x47\x91\x96\x29\xd7\xa5\xfb\xac\x24\x63\x74\x98\x0f"
-  "\x36\xba\xdc\x7f\x77\x4a\x7c\xd8\x5f\xb5\x10\xb2\x48\xea\x7f\xbb"
-  "\x3f\xaa\xfd\x87\x8c\xeb\x8c\x3e\xdc\x93\xa3\xf3\xc8\x1e\x85\xdf"
-  "\x9e\xdc\xee\xf5\xb5\x47\xbb\xcd\xed\x47\xbd\x9a\x99\x8e\x58\xd9"
-  "\x2f\xde\x53\x79\xc4\xda\x0b\x1b\x62\x4f\x8a\x5b\xfb\xb9\x4f\xe9"
-  "\x1e\xaa\x1c\xef\x4b\x41\x2f\xed\x8a\xb5\x0e\xef\xc3\xfb\x99\x86"
-  "\x7f\x07\x7f\xaf\x9a\xf7\xa5\xdc\xb4\x7b\x2c\xd3\x0d\x7c\xde\x2c"
-  "\xf7\x26\xd6\x3e\xc1\xf1\xe5\x87\xb2\x0f\x1e\xd3\x99\xcf\x1f\x58"
-  "\x70\x2f\x96\x8b\x49\x16\x7f\x9a\x56\x27\xcf\x1a\xca\x33\xec\x13"
-  "\xf5\x38\x23\xa9\x7a\xdc\x91\x14\x7e\x56\x67\xe0\xf7\x1c\x32\xce"
-  "\x9c\x73\x6c\x15\xfd\xbc\x98\xf4\xeb\x93\x31\x47\xce\xab\xbd\x5d"
-  "\xf6\xeb\xe3\x35\x4d\xf6\x93\xe7\xfd\x57\x94\xeb\x0a\xf1\x8d\x8f"
-  "\xc1\xb3\xdf\x88\x35\xd2\xe3\x78\xcb\xdc\xef\x2f\x84\xb6\x77\x97"
-  "\xb5\x3b\xbd\x66\x4f\xa5\xb7\xec\x63\xcc\xdf\x6f\x8d\x85\x2c\xca"
-  "\xbf\x8c\xed\x64\xe2\xb3\x87\x1c\x5f\x22\x18\xbf\xbb\x98\x63\x4c"
-  "\x70\x2c\x2b\xe5\xdf\xfe\xd6\x2b\xfa\x99\xee\xd8\xb3\xf4\xd6\x03"
-  "\x03\xfb\xa0\x01\x7d\xed\xee\xad\xbd\x4a\xef\x7a\x6b\xaf\x5c\xbb"
-  "\x5b\xdf\x5e\xff\xcb\x55\x3e\xad\x61\x95\x5b\xab\x95\xe7\xbb\xde"
-  "\x02\xed\xf6\xe7\x1b\x3e\x32\xc8\x27\xe3\x4c\x45\x9f\x27\xf7\x4d"
-  "\x52\x30\x7f\x25\x63\x94\x0e\xd8\x37\xbf\x52\xdf\x3d\x5a\x3b\x2a"
-  "\x3b\xc8\x73\x5e\xfc\xef\xda\xa4\x6f\x49\xc1\x79\x5e\xc3\x1b\xaa"
-  "\x6c\x2d\x95\x47\xf7\xcb\xbc\xe6\x74\xf8\xf3\x08\x7e\x56\x34\xfb"
-  "\x55\xaa\xb1\x1f\xb0\x49\x0b\xba\x2d\x31\x24\xec\xf5\xc2\xcb\x31"
-  "\xcc\xa0\x4f\x79\x5c\x98\x43\x51\x87\x80\x7c\x18\x86\x32\xb9\x4c"
-  "\x7b\x35\x86\x7e\x25\xbf\xef\x11\x74\x4c\x15\x76\xd6\x23\x3d\xec"
-  "\xdb\x72\x9e\x90\xef\x6a\xe4\xfb\x59\x53\x71\x17\xfb\xce\x4c\xe7"
-  "\xd8\x60\x1d\x7a\xdd\x9e\xb8\x7d\x93\x6e\x49\xa0\x6c\xd4\xb9\xcb"
-  "\x4d\xc5\xc5\x57\x3e\xb6\x7f\x35\xa8\x2e\x3b\xd0\xae\x5f\x27\x0d"
-  "\xf4\xc9\xdf\xf4\x3e\xf9\x75\xd2\x57\xed\x21\xeb\x3a\xc9\xb5\xa7"
-  "\x69\xdf\x10\xb6\x9b\x71\x7f\xd3\x69\xda\x2b\xf7\x28\x95\x2f\xf2"
-  "\xde\x3f\xea\xf7\xa8\x63\xef\x3b\xfa\xfd\xf5\xb8\xdf\xa6\xdf\x8f"
-  "\xc2\xfd\x1a\xfd\x1e\xf4\xde\xbb\x48\xbf\x4f\xc2\xfd\x23\xfa\x3d"
-  "\xc6\xe7\xde\x7b\xf5\xfb\x91\xb8\x1f\xa3\xdf\x5f\x87\xfb\x38\x7d"
-  "\xef\xcd\x0c\x7c\x2f\x5c\xb9\x5e\xf4\x6b\xa7\xda\xdf\xe1\x7d\xb5"
-  "\x37\x52\xd4\x98\xee\x4f\x4b\x82\x7d\x39\xd7\x58\x5f\x47\x7a\x23"
-  "\xd7\x83\xf4\x14\xf0\x5f\x6a\x48\xfa\x1e\x3d\x7f\x3a\xf4\xac\xca"
-  "\x90\xf4\x1a\x3d\x7d\x3e\xf2\x37\x86\xa4\x57\xea\xe9\x85\x6e\xaa"
-  "\x3a\x1e\x92\xbe\x4e\x4f\xdf\x60\xec\x69\xeb\xe9\x45\x7a\x3a\xfa"
-  "\x7f\xc3\xba\x90\x74\x3d\x9e\xe0\xde\xc3\xe8\xe3\x8e\x90\xf4\x6c"
-  "\xc9\xb3\x32\x2e\x9c\x45\x1c\x29\x9e\x88\x31\xbf\xd7\xed\xa6\xd7"
-  "\x8a\x43\xf2\xcc\xd5\xcb\xfa\xdc\xf4\xb3\x5d\x21\xe9\xd3\x55\xfa"
-  "\xbe\x44\x37\x7d\xba\x27\x24\x7d\xf2\x60\x3c\x14\x53\x4d\x51\x63"
-  "\xc5\xf1\xfa\x16\x7f\xdf\x43\xfa\xc5\x49\x9f\xc8\xb7\x67\xf1\x19"
-  "\x19\xcb\x4e\x71\xd2\x56\x22\xc4\x49\x7a\x7b\xa2\xee\x2b\x96\xce"
-  "\xfe\x41\x7c\xa6\xa8\x83\xde\xbe\x41\x9e\x3f\xe1\xb8\x68\x7c\xce"
-  "\x68\x15\x9f\x33\xda\x27\xe3\xbc\x4e\x28\x2a\x55\x31\xd3\x94\xbf"
-  "\x61\x97\xb4\x95\xf4\xbd\x30\xe4\xe1\xef\x87\x12\xc3\xe1\x75\x16"
-  "\x57\x61\xaf\xf4\x8b\x63\x5d\x95\xd3\xd8\x66\x90\x67\x52\x42\x74"
-  "\x56\x35\x1e\xdf\x9e\x15\xe4\xf3\xc0\x0e\x65\x57\x55\xa8\x58\x7c"
-  "\x5d\xec\xc7\x11\x9a\xd7\x4d\x6f\xcf\xe4\x6b\xac\xd5\x72\xa2\xc7"
-  "\xf1\x76\xca\xc0\xb9\x8a\x7d\xeb\xf4\x74\x37\xd2\xd3\x43\xd2\x2f"
-  "\x89\xed\x3b\x20\x9f\xb6\xd4\x0b\xf3\x96\xb6\xbe\x8b\xc2\xeb\xbf"
-  "\x28\x7c\x9b\xfe\x0a\xbc\x17\xca\xf3\x06\x37\x06\xca\xb6\xb8\xf5"
-  "\xb3\xf5\x27\xfc\xcb\x85\x07\x7a\x1a\xc7\xea\xfe\xc6\x6c\xd8\x75"
-  "\xb3\x0b\x7a\xc4\xc6\xa7\xd9\xaf\xeb\x82\x8c\x33\x63\xef\xe2\xb8"
-  "\xa0\xec\xe7\xe3\xe5\x3d\x84\x84\x56\xc8\x9e\xda\x85\xfc\xfe\x33"
-  "\x9a\x95\x07\xfd\x27\x2f\x40\xb5\x80\xbd\xf3\x69\xc3\xa7\xe8\xed"
-  "\x8e\x7e\xdf\x39\xe0\xc0\xf5\xd9\x65\xac\xfd\xfd\x52\xcf\xe7\x6f"
-  "\x08\x89\xf2\xf3\x4e\xf1\x07\xd6\x2b\x3e\x76\x5b\xd6\x90\x0d\x32"
-  "\xd7\x86\xfb\x36\xf5\xc3\x3b\xa4\x0f\xd6\x26\x35\x4e\xf7\xab\xef"
-  "\x7a\x96\x6d\xcd\x50\xb2\x60\xff\x7c\xf1\x0b\x3e\x6f\xb1\x3f\x1b"
-  "\xb2\xa4\x1a\x3a\x4c\x75\xb4\xf2\xab\x77\x92\xd6\xb7\x1e\x73\xc6"
-  "\xd9\x46\x4d\xc9\x9e\x86\x99\x41\xcd\xbc\x86\xd7\x73\x64\xbc\xed"
-  "\xf5\xbb\x37\xec\x5d\xec\xd3\x5a\x56\x75\xd0\xcb\xd7\x91\x75\xbe"
-  "\x8f\xfd\x82\xf7\xb7\x0c\x2f\xe4\x18\x3f\xed\xf5\xd0\x07\xb4\x83"
-  "\x78\xff\xde\xe2\x46\xcd\x2f\xe7\x91\x86\x99\x72\x0d\xa0\x6c\x77"
-  "\x0e\xef\x21\xb8\xda\x03\xac\xcb\x24\x40\x97\x99\x2b\x96\x25\x9b"
-  "\x03\x2b\xf2\x46\xf8\x97\xe5\x7d\x63\xe7\x52\x4a\x08\x2c\x4b\x4e"
-  "\xda\x7c\x91\x26\x19\x71\xbc\x61\x23\xa4\x8a\x1e\x6b\x7c\xc5\x72"
-  "\x4a\x61\x1b\x62\x78\x4c\xa2\xdc\x97\xe1\xfb\xa0\xb6\xb5\xb3\x76"
-  "\xf9\xe5\xbf\x19\x10\x80\xed\xc0\xf1\x7e\x19\x97\x68\x6d\xdd\xb0"
-  "\x1d\xf6\x88\x7e\x16\xaf\xe4\x73\x1a\x09\xfd\x43\x1b\x7e\x41\x38"
-  "\x4f\xe7\x93\xc6\xf1\xd6\x4b\x72\xa5\x9d\x3e\xa4\x25\xcf\x4f\xae"
-  "\xa2\x4f\xa9\x64\x29\xf7\x51\xc3\xeb\x3c\x7f\xb2\x9f\x1e\xf2\x27"
-  "\x9e\xa6\x86\x77\x2c\x3e\xd2\xf0\x8b\x71\x3e\xc7\x3a\x77\xc3\x87"
-  "\xac\xf7\xbb\xe9\x1d\x33\xfb\x0a\x3b\x97\x3e\xc8\x69\x27\xec\x9f"
-  "\xcb\x7d\xf4\xe9\xea\xbc\x5e\xc3\x61\x7e\xb6\xf3\xd9\xc0\xf8\xbd"
-  "\x05\x6f\xf7\xfa\x86\x28\x5b\xb0\xe1\x5d\x5d\xf6\x57\xa2\xcf\x46"
-  "\x03\xf6\xa0\xeb\xc2\xc1\xb2\xed\xbc\x0e\x79\x93\xab\xc6\x4f\xb3"
-  "\xbd\xc2\x2d\xf7\xbc\xf8\x4c\x74\xd1\x54\xa7\xb8\x58\x49\xea\x3c"
-  "\xd0\x3b\x6b\x82\xe5\xdb\xd9\xff\x95\xef\xe5\xb9\x36\xb5\xa6\xb4"
-  "\x83\xd4\x3a\xcc\x8e\x44\xb5\xa6\xb4\xc3\xb6\x76\x14\xfb\xab\xbe"
-  "\x53\xda\x1d\xb7\x03\xf3\xe9\x3b\x73\xbb\xe3\x1b\xf6\x0c\x3e\xd7"
-  "\x54\xdb\x6c\x37\x52\x12\xaf\x65\xb2\xef\x69\x9d\xf2\x39\x45\x1d"
-  "\x07\xd6\x89\x72\xf9\xee\xa6\x93\x05\x14\xcb\xeb\x3f\xa8\xf7\xa3"
-  "\x09\x35\x64\x03\xae\x57\x09\xf3\xf6\x36\xe9\x07\x54\xb6\xdd\xed"
-  "\xea\x12\x4e\xf6\x43\x53\x6b\xce\x07\x2a\x45\xdc\xf6\x36\x95\xff"
-  "\xc0\x98\xd6\x2e\xb4\xc1\xbc\xbd\xde\xe5\x3b\xa3\xcf\xd5\x07\xc0"
-  "\xfb\xdb\xeb\x45\xd9\xf6\x06\x75\xc6\xf6\xc0\x8b\x86\x5c\x55\x3c"
-  "\x7a\x20\x57\xd1\xad\xda\xa6\xe8\x76\xa0\x52\x9f\x97\x6e\xe2\x7b"
-  "\xe8\x09\xa9\x6a\x3f\xf7\xc0\x7c\x43\x77\x71\xeb\x79\xb8\x0c\xee"
-  "\xd3\x94\xac\x3d\x50\x8c\xb6\xeb\xfb\xc0\x07\x6c\x9c\x86\xf6\x61"
-  "\x6e\x7a\xa7\x91\xdb\x35\x98\x6c\x95\xb4\x28\xa6\x58\xe0\x2c\x63"
-  "\x98\xf0\x39\x78\x97\x77\xaa\x53\x7d\x03\xec\xd0\x75\xf2\x0c\x22"
-  "\xea\x41\xff\x68\x2c\x37\x39\xd6\x01\xc3\x0b\xc1\x3f\x60\xe0\xc2"
-  "\xf5\xf1\x3b\xb4\x55\xea\xd9\xa0\x55\x03\xe7\xe1\x7e\x85\xbd\x1e"
-  "\xcb\xf6\xb7\x73\x39\xfb\x94\x1c\x4a\x66\x9a\x28\x9a\x1d\x92\xfb"
-  "\x3e\x15\xfd\xfd\x70\xf0\xcb\x70\x7a\xa8\xe7\xa0\x19\xb2\x61\x29"
-  "\xfb\x16\x1c\x4a\xd6\xe9\xd7\xa5\xea\x3f\xf8\x17\xdd\x86\xc2\xbb"
-  "\x83\x1b\x43\xca\xde\xd0\x9f\x57\x7d\x6f\x4e\xe3\x7d\x3a\x5e\x0b"
-  "\x55\xfc\x7a\xb0\x31\xa4\x5c\x63\xd6\x17\x69\xc4\xf1\xf8\xf9\xfb"
-  "\x60\x4c\xf3\x1e\xc7\xc1\xe6\x01\x7a\x2b\x38\x51\xea\xb8\xd1\xa8"
-  "\xc3\x4d\x07\x37\x18\x78\xe2\x3e\x5b\xf5\xc9\xa1\xc4\x81\x3e\x39"
-  "\x98\x6a\x94\x63\xbf\x6e\xf4\x91\x8c\x41\x12\x55\x0e\xf2\x9a\xfb"
-  "\x68\xc8\x60\xff\x54\xa7\xe4\x47\x3a\x54\xc6\xfe\x93\xa0\xab\x53"
-  "\xf1\xd0\xa1\x7c\x35\x17\x1e\x92\x67\xda\x79\x3d\xfb\x88\x8f\x79"
-  "\xe4\x50\x29\xe0\xd6\xe8\x38\x57\xe9\x38\x54\x01\x87\x0d\x83\x9e"
-  "\x9b\xe9\x3f\xbb\x76\xe8\x70\xc8\x79\xbd\xf9\x8a\xb6\xbf\xe1\xb3"
-  "\xb2\x87\x36\x29\xdb\xa1\x71\x13\xfa\xc7\x7e\x81\x46\x71\x4c\xfd"
-  "\x92\x02\x71\xba\xb5\x00\xf6\x8c\x79\xf7\x1e\xc8\x86\xbd\x25\x17"
-  "\x28\x9e\xf7\xe0\x59\xb6\xb0\xaf\x9f\x88\x43\x7a\xf9\xee\xbd\x03"
-  "\x67\x95\x7e\x6b\xe5\xb3\x7f\x1b\x39\x66\xd2\x19\x1a\xa5\xf6\xd4"
-  "\x7f\xf3\x10\xdb\xd0\xc2\x0e\xbb\xb9\x6c\x77\x03\x9f\x5d\x6b\x85"
-  "\x56\x2e\xec\x79\xdb\x83\xe5\xbb\x1b\x00\xd7\x69\x7f\x81\x46\xf0"
-  "\x5c\xc6\xb6\xb8\xe2\x8f\xdf\xf8\x00\xd7\xc9\x71\x9b\x60\x7b\xc7"
-  "\x08\xf3\x1e\x53\xd0\xbc\x6f\x22\xc3\xe5\xba\xc1\x53\xda\x49\xfa"
-  "\xcd\xcf\x45\xdc\x1e\x13\x7f\xdb\x8b\x6d\x6d\x97\x0f\x78\x96\xef"
-  "\x31\xe1\xdd\x70\xbc\xfb\x00\xd7\x20\xc7\x70\xe2\x18\xb4\x80\x6f"
-  "\x65\xf8\xa2\x6c\x8f\x49\xe1\xee\x91\x79\x4f\xd2\x6f\xaf\xe3\x3c"
-  "\x46\x6c\xa8\xa0\x3d\x33\x96\xdf\x73\x1b\x02\x28\xe7\x2a\x02\x9e"
-  "\xb2\x4c\xbb\x2c\xe3\xe6\xf6\xa1\x9c\xee\xb7\x61\x53\x7b\x6e\xbf"
-  "\x4d\x34\xf6\x8e\xdc\xf4\x9b\x1c\xc6\x39\x7a\xfc\xd0\xdf\x4e\x0a"
-  "\x8f\xe5\xf1\x3b\x3e\x2b\xca\xe9\x19\x46\xfc\x0d\xdc\x63\xfc\x1f"
-  "\x52\xe7\xe7\x43\x62\xe9\x6c\x0a\x89\xcb\x65\xf7\x88\xff\x62\x5c"
-  "\xc0\xa7\xb1\xa0\x37\xe8\xbf\x6f\xa2\x3a\x67\xf1\x5b\x39\x86\xd0"
-  "\x26\xb6\xf7\x2d\xea\x5c\xf0\x6f\xff\x5d\xe7\xc7\xb4\x39\x01\xbf"
-  "\xc5\x8d\x3a\x31\x76\xd3\x06\x9e\x7f\xdb\x00\xfe\x4c\x44\xbe\x7f"
-  "\xa8\xb8\x55\xbf\xdd\x13\x9e\x5f\xbe\x2f\x8d\x78\x8e\x2c\x6f\xf3"
-  "\xa2\x6f\x06\xdb\x23\xdb\x38\x4a\xae\x0b\xe4\x0c\x5f\x43\x05\xf6"
-  "\x7f\x50\x2c\xfa\xea\x73\xc6\xad\xb5\xb3\x8b\xdb\x64\x11\x8e\x54"
-  "\x72\x75\xfa\x95\xae\x82\x39\xe2\xe4\x58\xe4\xf9\x07\x8d\x64\x9f"
-  "\x53\x8e\x05\x8e\xfc\xa7\x55\xdc\xd2\xc6\x9f\xcd\x7f\x29\x9e\x82"
-  "\xcf\x66\x7e\x43\x68\xff\x36\x1d\xf3\x81\x79\x5f\xaf\x7b\x08\xaf"
-  "\x4b\x97\x6c\xa3\xd1\x1c\xff\x02\xbc\xd9\xc1\xdf\x89\xe1\xef\xf6"
-  "\xfe\xb2\xb7\x73\x88\xcb\xff\x29\x15\x3c\x47\xda\x69\x6a\x5c\x67"
-  "\x2a\x26\x53\xc5\x29\x4a\x9c\xe3\x17\xfe\x23\xfe\x49\x64\x9c\xeb"
-  "\xad\x19\xa1\xce\x47\xc2\x2e\xf7\x2c\xb3\x0a\x5f\x8f\xe3\x77\xd0"
-  "\x7f\xb7\x67\xea\x3e\x3c\xde\x0d\x2a\xde\xb7\x09\xf5\xcf\xd2\xf4"
-  "\x33\xcc\x8a\xb6\x8d\x37\xa8\x73\x1a\x23\xbe\xd5\xe3\x68\x4c\x1a"
-  "\xd0\xe7\x1a\xeb\x15\x0d\xf7\x65\xaa\xf1\xd5\x58\x7f\x04\x96\xff"
-  "\x3a\xb5\xd7\x98\x84\xbc\x69\xfd\x7b\x8d\xd2\x3e\x6d\xac\x47\x1f"
-  "\x66\x2a\x5d\x6f\x5f\x66\x56\xc0\xac\x8f\x01\x4e\xdf\x22\xcb\xa2"
-  "\x9c\xc5\x2b\x6d\xc9\xc6\xe2\x01\x5e\x6b\xe4\xef\xa5\xc7\xa0\x4d"
-  "\x09\xe8\xd7\x46\x6e\x17\xd3\x04\xf9\x4c\x78\x3e\x7c\x64\xd7\x20"
-  "\xf1\x0b\xcd\x5b\x33\xfc\x0e\xb9\x6f\x56\x0d\x7e\x3a\x83\x3e\xb8"
-  "\x86\xe3\x95\xb8\x50\x4f\x4b\x6d\x2f\xb5\x58\xbb\xa9\x35\x87\xcf"
-  "\x94\x40\x5f\x7e\xee\xbf\xa8\xc3\x16\x5d\x7e\x41\x06\xb6\x01\x67"
-  "\x37\xc3\x82\x9c\xe8\x64\x9f\x11\x57\x31\xe4\x99\x87\xbf\x4f\x43"
-  "\x12\x46\x4b\xb0\x93\x5a\x8a\x58\x6f\x3f\xef\x6c\xad\xfd\x94\x5a"
-  "\xad\xff\xaf\xac\x87\x75\x0c\xe7\xd2\xee\xcb\xc1\xf6\x40\x2f\x24"
-  "\x1d\x76\x17\x60\x27\x0d\x0e\xfb\x63\xf7\x15\xc2\xbe\x02\xbc\x3f"
-  "\x6e\xbb\x12\xd8\x90\x65\x73\x5d\x56\x75\x2e\xa5\xe4\x3a\xba\x2a"
-  "\x70\x91\xe3\xd3\xdd\x24\x94\x0f\xde\xef\x5f\x92\x67\x57\x1c\xd2"
-  "\xc7\x31\x43\x9e\x61\x39\x4b\xd2\x8f\x4a\x9d\x5b\xf9\x9c\x78\x5f"
-  "\xb3\xc7\xf1\xfb\xec\x01\xdd\xbb\x7f\x5d\x19\x32\xe6\xf7\xeb\x94"
-  "\xaf\xd5\xee\x0c\xc5\x57\xbf\xbf\x97\x61\x45\xc7\x63\x4f\xb6\xf2"
-  "\xd9\xfb\xbd\xa1\xaf\xb5\x75\xc7\xed\xc9\xd6\x61\xd9\x22\xf7\x1b"
-  "\x8d\x0f\xc3\xe5\x16\x15\x1a\xdf\x98\x2b\xd4\x8f\xaf\x3d\x9a\xfb"
-  "\x4c\xee\xa2\xe5\xb9\x39\xb6\xb9\x2f\x2d\x5d\x3c\x7e\xc9\xc2\x85"
-  "\xb6\x59\xb9\xcb\x96\x2d\x78\x36\x37\x9e\xe6\x2e\x5d\xb0\x78\xd9"
-  "\xa2\xc2\x45\x4b\x16\xdb\x6c\xe9\x77\x67\xe5\x2d\x29\x1c\x7f\x7f"
-  "\x7a\x6a\xc4\x79\x27\x3e\xeb\x74\x9c\x75\x3a\xfb\x6a\x8c\xcf\x00"
-  "\x5d\xcd\xb1\x27\x2c\x2b\x85\xf3\x65\xd8\x13\xe0\xbf\xd3\xbc\xae"
-  "\x8e\x71\x7b\x82\x75\x4d\x8e\x75\x85\x79\xb3\x79\xc7\x16\xd1\x76"
-  "\x8a\x9a\x2f\x40\x4f\xe1\xef\x93\x72\xdc\xa6\xe3\xb0\xf1\x3c\xea"
-  "\x3b\x48\xcd\x1f\x71\x4c\xa6\x9f\x22\xcd\x13\xb7\x2f\xb3\xe2\xaf"
-  "\x64\xc2\xdc\x03\x3d\xf7\x3f\xda\x84\x36\x4c\x6c\x18\x29\x9a\xc4"
-  "\x7f\x59\x49\x8f\x29\xab\xb9\xdc\x3e\xde\x7f\x33\xcf\xf1\xdb\x05"
-  "\xcb\x53\x35\xb6\xfe\xe3\x23\x45\x97\xed\x1e\xe5\xcb\xd8\xfc\x0e"
-  "\xeb\xc4\x6b\xe5\x77\xaa\xfe\x03\xe3\xbf\x21\x73\x40\x4e\x37\xf9"
-  "\x75\x5d\x84\xf7\xc7\x56\x9c\xc4\xb3\x3a\x63\x7f\x38\x21\x7c\xcf"
-  "\xf5\xdd\x2e\xa2\x3f\xda\xd4\x8f\xcb\xfc\x31\x4d\xfd\xf8\x3e\xf4"
-  "\xd7\x5c\xa5\x7e\x91\xe9\xff\xec\xcf\xa8\xff\xbf\x5b\xfe\xc3\x43"
-  "\x97\xff\x7d\x9d\xfa\x65\xbb\xff\x2f\xb6\xff\x9f\x29\xff\xe1\xe1"
-  "\xcb\xfd\x98\xdf\xc0\x5b\xc7\x7f\xfa\x57\x32\x83\x3f\xab\x60\x5f"
-  "\x9b\xec\x9f\x91\xb5\xd8\x2f\x3a\xec\x4f\xd2\xe8\x92\x7f\x10\x7f"
-  "\x27\xa8\xb3\xb0\x48\x74\x94\x5c\x64\xbd\xe7\xc3\x8d\xe0\xdf\xc6"
-  "\x4d\x27\x29\x61\xe3\x49\x4a\x6c\x2d\xe4\xef\x05\x72\x7c\x1a\xc8"
-  "\x19\x60\xea\xc2\x73\xf3\x72\x1f\xfd\xc9\xf3\x05\xfb\x29\x38\x5b"
-  "\xa1\x4d\xb6\x1c\xe7\x6f\x2d\x8a\xa6\x84\x6c\x4a\xaa\x19\x29\x0e"
-  "\x8b\xff\xc3\xde\xfb\xc7\x45\x55\xe5\xff\xe3\x67\x2e\xa3\x8e\x3a"
-  "\xc0\x68\x64\x68\x68\x53\x51\x3b\x16\x16\xed\xc7\x7a\xbb\xad\x11"
-  "\x89\xbd\xdf\xd6\x5a\xb8\xae\xbd\x97\xdd\x2c\xb1\xb4\x1d\x77\xfd"
-  "\x31\xe1\x00\xa3\xc1\x80\x68\xbc\xc1\x05\x64\xdf\xeb\x96\x16\xa0"
-  "\xf5\xb5\x95\xdd\xb7\x18\x6d\xf6\x5e\xda\xb5\x1a\x53\x5b\x32\x60"
-  "\xa8\xd5\xc4\xc2\x75\x22\x24\x72\xd1\x26\x40\x19\x61\xe6\x9e\xef"
-  "\xeb\x75\xce\xbd\xcc\x0c\x30\x30\x33\xe2\x8f\xf6\xed\x1f\xf7\x71"
-  "\xe7\x9e\x7b\xe6\xdc\x73\x5e\xaf\xe7\x79\xbd\x5e\xe7\xd7\xeb\x95"
-  "\xf3\x8c\x91\x0a\xcf\x2c\x81\xb4\xc3\xaf\x8b\xf1\x23\x5e\x5f\x5b"
-  "\x3d\x02\x63\x2a\x35\x91\x77\x7f\x23\x61\xd3\xc5\xcf\x31\x1c\x60"
-  "\xf6\x39\xf4\x93\xc3\xdc\x0f\xe2\xc1\x35\x5c\x9f\x1f\x7c\x48\x9a"
-  "\xbf\x80\xdf\x07\xd8\x5c\x1b\xb4\xa3\x0a\xe3\xaa\x61\x99\xbb\xc5"
-  "\x2a\x16\x57\xed\xf5\xb5\xf1\x23\x32\x16\x13\xa1\xce\x76\x8a\xec"
-  "\x07\x39\x88\x31\xba\xa0\xdf\xed\x82\x7e\x56\x59\x3a\x81\x16\x43"
-  "\xfd\x0a\xca\x26\xd0\x3c\xa8\x53\x79\x57\xce\x7b\x60\x07\x55\x75"
-  "\x4a\xf3\xab\x16\xe8\x17\xbb\x0a\x21\x4f\x62\x2a\xb9\xa1\x10\xf2"
-  "\x15\x41\x3e\xb4\xc5\x78\xfd\xde\x3f\x08\x34\xd8\x03\xdf\xac\xd7"
-  "\x3e\x89\xcf\x16\x36\x0f\x85\xdf\x86\x76\x68\x9b\x88\x65\x1e\xe8"
-  "\x36\x25\x7e\x43\xfe\x2e\x94\x0f\xf2\xef\xed\x5d\x6c\x4e\x1c\xd2"
-  "\x79\x39\xef\xf1\x98\xee\x79\x3b\xd1\x8f\x9b\x14\xf7\x6e\x67\x7d"
-  "\xe1\x5a\xd0\xe9\xdd\xcc\x57\xdb\x66\x1c\xbf\xa3\x8d\xc1\xec\x0a"
-  "\x18\xc7\xf3\xf1\x26\xd8\x16\x7a\x90\x03\x60\x4f\xb0\xfd\x97\x60"
-  "\x4b\x40\x5d\x36\x63\xec\x39\x7c\x0f\xe3\x80\x3d\xa0\x97\x2b\xd1"
-  "\x0e\x78\xf2\xec\xc3\x04\xcf\x6e\x81\x3d\xa0\x5c\xbd\x90\x3a\xb8"
-  "\x8f\xfc\xf7\xda\x64\x5b\x00\x65\x10\xea\xff\x42\x18\xd3\xf7\x00"
-  "\x0f\x01\x03\xd5\x60\x5b\x8c\x03\x2d\xa9\x93\x68\x5f\xcd\x74\x7e"
-  "\x1a\xf3\x2d\x1a\xc2\x65\xb4\xe5\x6e\x68\x9f\x1a\xbe\x51\x6d\x23"
-  "\xb5\x4c\x4e\x70\x19\x63\x99\x2d\xeb\x71\x1c\x43\xd9\xa0\x0c\x0a"
-  "\xb2\x4c\x7a\x07\xed\xff\x73\xa4\xfc\x4d\x1b\x79\xaf\x53\xa2\x59"
-  "\x0d\xd0\x0c\xcb\x64\xe7\x69\xc1\xe6\x4a\xe2\xb4\xb1\xa0\x7d\x10"
-  "\x21\xfd\xb7\x44\x2e\x17\xc7\x79\x22\xd8\x15\x48\x2f\xa4\x13\x7c"
-  "\x83\x48\x72\xec\x30\xb7\x5f\xde\xaf\x90\xd6\xd1\x8a\x81\xd7\x1b"
-  "\xdc\xf4\xb7\xd8\x3c\xe9\x0f\xff\xdf\x20\xf1\xf2\x67\x1e\xbc\x03"
-  "\xfb\xfb\xfd\x58\x9c\x77\x83\x3a\xee\xe5\x73\x06\xfb\x26\xa2\x7f"
-  "\x1f\xf4\x21\x0a\x34\xde\x5b\x80\xfe\x2a\x41\x36\xaf\xff\x07\x91"
-  "\x62\x1e\xbe\x3f\x91\xdb\xa7\xfb\xaa\x78\x5c\xb0\x7d\x6c\xae\xae"
-  "\x19\xea\xc5\x63\x82\xed\x93\x62\x82\xed\x5b\xe7\x19\xe7\xd0\x1d"
-  "\xe3\x70\x9f\xc9\xbd\x07\xda\xb2\x83\x8f\xc7\x2c\x3b\x70\x4e\x85"
-  "\xe5\xef\xd1\x63\xdd\x1a\xb1\x5f\xca\x6d\xc5\x78\x87\x90\x8e\x73"
-  "\x7d\x8d\xc8\x37\x39\x1d\x7d\x5d\x02\x9f\xd4\x50\xa7\x71\x52\x9d"
-  "\xda\xe0\x59\x05\xdf\x66\x73\x52\x18\xfb\x70\x13\xfe\xc7\xec\xfe"
-  "\x0f\xf6\x1b\xc0\x70\x38\xfc\x67\x34\xdc\xa9\x9c\x97\xc7\x44\xdc"
-  "\x57\xfc\xdb\x6e\x9c\x53\xd9\x57\x2e\xc7\x44\xc4\x78\x88\x28\x33"
-  "\x0a\x9f\xf4\xa2\x3d\xd2\x66\x17\xf0\x8a\xe1\x6e\xbf\xb3\x0a\xe8"
-  "\xfd\x3e\xd8\xff\x15\xf1\xbc\x5d\xfb\x8a\xa5\xfa\x59\xb8\xef\xf4"
-  "\xbf\x54\x97\xfd\xb7\x7c\x96\xfb\x7d\x53\xef\x3a\x5f\xaf\x6d\xb9"
-  "\xaf\x18\x31\x09\x65\xd5\x20\xff\xd1\x4e\x84\x7c\xdb\x7b\xb1\xc5"
-  "\xce\x2b\xbe\x8f\x7e\x94\x92\xa4\xfa\x23\x5e\x14\x12\xed\xaa\x3d"
-  "\xfb\x9d\x67\x3f\x87\x32\x9a\xa1\x8f\xf7\x62\x40\xee\xd7\x92\xcc"
-  "\x99\x28\xd9\x14\x5b\xd0\xd7\x24\x94\xcb\xf6\x14\x72\xbd\xba\xbf"
-  "\x6d\x7f\xa3\x13\xe7\x64\x0f\xc3\x33\xf4\xef\xfd\xd5\x1d\x63\x2a"
-  "\x2d\x1b\x98\xdc\xd8\x0f\xe3\x9f\xa9\x6c\xfe\x18\xe9\x22\xf7\xd7"
-  "\x4d\x40\x1f\x8c\x27\xc8\xfa\xac\xa9\x99\xd4\x39\xda\x88\xb4\xbf"
-  "\x18\xfa\xec\x49\x5c\x23\x39\x05\x18\x52\x61\xff\x05\xfe\xee\x42"
-  "\xbf\xa8\x40\xc7\xfa\x0d\x2f\xb0\x7e\xab\xc6\x7e\xdb\x83\x67\xd0"
-  "\xe1\x3b\x07\x92\xe3\xc9\x7e\x93\x85\xf5\x63\xf4\x2d\xf0\x32\xd0"
-  "\x0e\xe3\x0f\xc2\xb7\xf7\xc8\xfb\x22\x11\x23\xe8\x4b\x80\xe3\xe4"
-  "\x3d\x27\xf6\x65\x89\x76\x4a\xc8\xd7\x28\xf7\x3d\x37\xff\x79\x9e"
-  "\x3e\xfd\x2d\x9c\xf7\xb7\x03\x6a\x99\xd6\x4e\xd6\x8f\xf7\x95\x3b"
-  "\xa1\x1f\x7b\xd2\x14\xe9\x89\x74\x85\xbc\xd0\xfe\xb7\xe7\xc9\x34"
-  "\xf5\xa0\xe7\x1f\x24\x9e\xd7\xf3\x39\x8b\x03\xcb\xa5\xf9\x8c\x5e"
-  "\x1a\x4a\xf8\x3b\x8c\x7d\x6a\x3d\xb6\x1d\x74\x03\x7e\x1f\x31\xf2"
-  "\xb2\x24\xb3\x0e\xd8\x11\x23\x07\xa0\xff\xcf\x6d\x70\xcb\x8e\x7d"
-  "\xbb\xd8\x98\x05\xf8\xc4\xf9\x73\xe0\x08\x3b\xaf\x3f\x80\xec\x00"
-  "\x9c\x6c\x76\xcb\xa7\x03\xcd\x32\x1d\x64\x4c\xca\xfd\x1e\x74\xca"
-  "\x5d\xde\xf2\xe7\xe0\xb5\x50\xc6\x78\x94\x6f\x6e\x1b\xea\x60\xb4"
-  "\xb7\x7c\x3b\xa8\x46\xf9\x86\xb8\x36\xa4\xe1\x9c\x0d\xd7\x57\x36"
-  "\xf2\xee\x1e\x6f\x99\xf4\xee\x1f\xf8\x1a\x20\xb7\xb9\x10\x5b\x86"
-  "\x27\x79\x7e\xd4\x61\x90\x9f\xed\x4b\x96\x74\x1e\xfa\xbf\xc2\xb4"
-  "\xed\x12\xbd\x1a\x21\xff\x01\x3c\xab\x85\x67\xbd\xc7\x36\xf2\xb1"
-  "\x1e\xc8\xe9\xbd\xe8\x67\x16\xf2\x25\xd7\x81\x9d\xdf\x93\xcb\x65"
-  "\xb7\x2c\x2b\xe8\xd3\x49\x63\xd3\x5b\xc9\x68\x43\x1c\xfd\xb2\x85"
-  "\x7c\xf0\x00\xf4\x19\x07\xfa\x3d\x83\xb2\xb5\x2d\xe4\xc3\xd1\xf0"
-  "\xdd\x08\xe9\x1e\xd9\x42\xaa\xbf\x85\xfb\x44\xb8\x1f\x83\xfb\xf5"
-  "\x70\xdf\x07\xf9\x45\x29\x7f\x2c\x3c\xff\x01\xd2\xff\x9f\x74\x87"
-  "\x3a\x7e\x30\x03\xee\xf3\x24\xdb\x11\xd3\x33\xf1\x19\xee\x2b\x24"
-  "\x9e\xd7\x70\x9e\x7f\x80\x7b\xae\x4c\x50\xff\x06\x6b\x23\x2b\xcb"
-  "\x00\x79\xa6\x61\xd9\x78\x86\xb2\x85\xfc\xed\x0b\x0f\x1b\x14\xca"
-  "\xf9\x5b\x28\xdc\xa7\xc3\xff\x3e\x86\xbb\x11\xee\xaf\x49\x34\xa8"
-  "\x47\xd9\xb0\xc4\x84\xb4\x3d\x60\xd1\x72\x7b\x77\x9e\xdc\xe7\x51"
-  "\x0f\xbb\x65\x87\x85\x2c\x59\xc8\xf9\x0d\x79\x19\x0e\x20\xef\x03"
-  "\x98\x17\xee\x09\xd2\x3d\x5e\xba\x3f\x28\xdd\xff\x43\xba\xcf\x96"
-  "\xee\x73\x6c\xe4\x83\x72\xc9\xc6\x00\xba\x7c\x50\xce\xf6\x37\xe4"
-  "\xed\xcc\xe3\xdf\xf8\x5b\x35\x8e\x91\x41\x8e\xa3\x1e\x0c\xe9\xca"
-  "\xf9\xdb\x4c\x79\xbe\x0d\xe7\x69\x7b\x72\xfe\xf2\xe5\xcb\xcc\x6f"
-  "\xc3\xdf\x16\x78\xc8\x36\x9d\x5a\x11\x4f\xc0\x06\xba\xb6\x44\x00"
-  "\xfd\xcf\xcb\x41\x1c\xb3\x35\x44\xc9\x87\x75\x08\xfa\x8a\x62\xe3"
-  "\xa1\xd1\x76\x1d\xf6\x55\x36\x17\x89\x3e\x92\x46\x57\xc4\xc0\x35"
-  "\x03\xc6\x06\x33\x65\xf9\x8d\xe3\x1e\xc9\xd7\xd5\x04\xf8\x96\xc5"
-  "\x3d\x56\xff\x9b\x81\xaf\xc9\x5c\x0b\x7d\xff\x6f\x0d\x1e\xe9\x31"
-  "\x58\x67\xa0\x67\x03\xb4\x67\x7a\x13\xa9\x46\x3a\x7e\xbf\x99\xb7"
-  "\x39\x56\x6e\xb3\xc4\x0f\x83\x4c\xdf\x66\xf2\x41\x25\xc8\xc2\x14"
-  "\xc4\x70\x53\xaf\x9c\xfd\x80\x9d\x41\x92\x30\x02\xbc\xfc\x60\x19"
-  "\xf2\xd4\xdd\x7f\xbc\x64\x50\x44\x57\x4e\x75\xb2\xb7\x4c\xb1\x24"
-  "\xa3\x4c\x41\x6c\x80\xfc\x46\x5e\xc7\xf7\xe9\x7f\x6a\xec\x7f\xbc"
-  "\xdf\x55\x97\x78\xff\xf7\xa0\xda\xc9\xfb\x1d\xee\xe5\x02\x7c\x7e"
-  "\xc0\xce\x9e\xd9\x48\x75\x86\xd4\xa7\x1b\xa0\x4f\xdf\x0d\xe9\x2a"
-  "\x5e\x57\x9e\x2e\x7d\x0b\x70\xf6\x01\xb6\xfb\x7a\x39\x5d\x6a\x2f"
-  "\x94\x73\xd0\x81\xfc\x96\xd3\xa5\xf2\x01\x8f\x07\xed\xd8\x4f\xe4"
-  "\x74\xa9\x4d\x60\x47\x7d\x38\x5d\x96\x27\x05\x0c\x6f\xfb\xf7\xca"
-  "\xff\x43\xbe\xa1\x5f\x1b\x3e\x67\xfc\xa1\x16\xfa\xea\x76\xd4\x0f"
-  "\xeb\x9f\x24\xea\xf4\x2d\x24\x94\xf7\xcb\x0f\xb5\xde\x32\xf2\xa3"
-  "\xb7\x69\x4e\xb8\x93\xaa\x2a\xa2\x6b\x9d\xd3\x65\x7b\xb5\x04\xbe"
-  "\x53\x22\xc7\xdf\x74\xfb\xc3\xfe\xf0\x63\x8c\x5b\xee\x51\x17\x8b"
-  "\x5c\x17\xb7\x7e\xe6\x3c\xc0\xba\x61\x59\xeb\xc1\x5e\xef\x04\xb9"
-  "\xc0\xe5\xf6\x87\x76\x39\x2e\x71\x91\xa4\xb7\x58\x6c\xdc\x34\x1e"
-  "\x1b\x17\x75\x23\xae\xe5\x8b\x38\x8f\x65\x72\x91\x3a\x03\x8c\xe5"
-  "\x4d\x27\xc9\xa2\x35\x63\xd0\x77\x44\x12\xd4\xb5\x14\xea\xb6\x43"
-  "\xa2\x11\xf4\x9b\x8f\xd6\x49\xb4\x44\x79\xb5\x03\x65\xf8\x7a\x33"
-  "\x8f\x65\x81\x73\x37\xd8\x1f\x7e\x8b\x7a\x2b\x92\x3a\x0e\x94\x60"
-  "\xdf\x38\x64\x90\x6d\x50\xa8\xdf\x76\x6e\x03\xee\x3f\xce\x7c\x99"
-  "\xe4\x55\x44\xf3\xb9\xbf\x8f\xc6\xf1\xb6\x1e\x72\xf0\x75\x52\xe6"
-  "\x0f\x0e\x9f\x9b\x43\x22\x23\x52\xf8\x7e\x8b\xbf\x88\x65\xac\xaf"
-  "\x1d\xb2\xf4\xf1\x17\x25\x40\xda\x61\xd9\xdf\xa5\xdb\x5e\xe4\x34"
-  "\x81\x77\x76\x77\xbf\x38\xb4\x0b\xcb\x82\x32\x33\xbb\x72\x3e\x52"
-  "\xb9\xd3\xf7\x37\x4a\x73\x5e\xba\xb0\x75\xf1\xb8\x8f\xe4\x5a\xf4"
-  "\x11\xcb\xeb\xf0\x91\x9e\xd5\x89\xcd\x7b\x40\xff\x94\xfa\x30\xd2"
-  "\x1a\xf5\x36\xeb\xc7\xd0\x87\xb1\x2f\xf7\xe4\x57\xc4\xc0\xc5\xfb"
-  "\x2e\xd7\xcf\x0e\xd6\x77\x59\xbf\xfd\xc8\xe4\xfe\xde\x47\xb1\x6c"
-  "\xee\x0b\x79\xfa\x5c\xa4\x1a\xde\x6d\xb6\x91\xbf\xa8\xa4\x3a\xce"
-  "\x94\xea\x12\x0d\xef\x4b\xf8\x5e\x8d\x43\xd3\xb8\x2d\x74\x28\x06"
-  "\xf1\x65\x05\xcc\xc0\x7d\x0b\x8f\x1b\xf8\x51\xbd\x8c\x19\xe8\x4f"
-  "\x4b\x5a\x48\xcd\xe2\xcd\x13\xe8\x16\xe0\xcd\x16\xe8\x03\xcb\xe1"
-  "\xf9\x11\xb8\x2f\xe1\x77\x85\x06\xef\x12\xb6\xb7\x74\xe5\xd4\xa8"
-  "\xe5\xf8\xae\xd8\x9e\xce\xd1\x0d\x1a\xc4\x47\x11\xd4\x1d\x31\xc2"
-  "\xd6\x13\x0d\x3c\x6e\x32\xe2\x03\xb1\x11\xbe\xee\x61\x86\x0f\x76"
-  "\x56\x19\xd2\x59\x9d\x00\x1f\x50\x56\x92\xec\x6b\x12\xda\xe7\xe4"
-  "\xf3\xfa\x35\xcb\x3d\xf7\xb6\x41\x99\xda\x03\x5a\x18\xd7\xe4\x6d"
-  "\xd1\x1a\x6f\x24\xd7\x1e\xd0\x32\x9f\x72\x27\xac\xce\x07\x09\xfe"
-  "\x07\xd7\x65\xb8\x9c\xbb\xf6\xa7\xf0\xdf\x72\x37\xbd\x2c\x6c\xad"
-  "\x62\xff\x42\x36\x97\x78\x0d\xbc\x3b\xe0\x39\x4e\xb0\x91\xbf\xd6"
-  "\xe3\x58\x01\xf7\xe0\xdc\x1c\x41\xb4\x80\x43\x90\x43\x35\xad\xb2"
-  "\x5d\x7a\x67\x04\xae\xef\xfe\x15\xcf\x42\xe2\x18\x18\xe8\xf5\x57"
-  "\x3d\x8c\x05\x07\xdc\x9f\x08\xf8\x98\x8e\x73\x35\x52\x1c\x88\x46"
-  "\x9c\x87\x42\xbf\xd9\x2d\xa4\x7e\x4d\x2d\xfa\x11\x58\xd5\xdf\xb7"
-  "\xa8\xd9\x44\xcf\xa2\x7f\x51\x6d\x0a\xb9\xa6\x89\xd4\x2f\xc4\x79"
-  "\x9f\xac\x6f\x71\x8e\xa5\xd6\xe0\x3d\xc7\x52\x6b\x91\xae\xc3\x84"
-  "\xd4\xcd\xf0\xb8\xaa\xa5\xfb\xec\x21\x2e\x9b\x94\x17\x46\xe0\x75"
-  "\x0e\x89\x56\x2f\x76\xe5\xd4\xf6\xfa\x3f\x44\x4c\x61\x5f\xc5\x75"
-  "\x7d\x9c\x33\x52\x38\x09\xfa\x2d\x00\x7e\x41\xbd\xd7\xdf\x36\xdf"
-  "\xb2\x16\xf1\x54\x37\x82\xd9\xfe\x42\xa0\xe7\xaa\xea\xd8\x3a\x18"
-  "\xf7\xb1\x57\x5b\x0d\xdf\xde\x89\xb1\xe1\x0d\x29\x64\x32\xce\x5f"
-  "\x87\xbb\xa8\x05\xc7\xa8\x88\x8d\x6d\x2c\xfe\x42\xdd\x87\xc6\x4c"
-  "\x22\xc0\xfb\x1b\xe0\x77\x95\x6c\xe7\xc0\x7f\x34\x21\x0e\x12\x81"
-  "\xf6\x4d\x42\x26\xb9\xa1\x2b\xa7\x6e\xb3\xcc\x2b\xb4\x01\x70\x1e"
-  "\x4d\x9a\x0b\x80\xba\xd6\xb2\xb5\x33\xf4\x8d\x6c\x63\x74\x63\x72"
-  "\x14\xcb\x00\xec\xd6\x65\x87\x74\x12\x0d\xd7\x1d\x75\xa0\xff\xfe"
-  "\x2a\xd9\x7c\x75\x25\xd0\x07\x0e\x7b\xd4\xf3\x98\xfb\xf7\x84\x89"
-  "\xf8\xff\xf0\x4e\xb4\xaf\x7c\xd1\xc7\x7a\x8b\x4c\x1f\xdc\x57\x16"
-  "\x0e\x76\x3e\xe3\xb7\x93\xb6\x41\xdd\x6a\x0c\x6b\x89\xea\x14\xa9"
-  "\xbf\x65\xdb\x0b\xec\xbc\x4b\x35\x9f\x5f\xaf\x9f\x28\x8f\xa3\x79"
-  "\xbd\xad\x27\xc3\xd7\x85\xb0\x98\xda\x18\xe3\x93\xc5\xd1\xfe\x26"
-  "\x92\xd9\xde\x56\xe7\x4c\x62\x31\xdf\x8b\x79\x8e\xc8\xb2\xb4\x23"
-  "\x2b\x92\xec\x8f\x9c\x09\xfd\xd9\xba\x1d\xfa\x8c\x3e\xf0\xbd\x4f"
-  "\x56\x69\xde\x9e\x9f\x91\xc2\x67\x3c\xcf\xc4\xfc\xcb\xb3\x75\x52"
-  "\xeb\xb3\xa8\x1b\x36\x48\xf1\x99\x51\xe7\x76\xe5\xd4\xf7\xda\xff"
-  "\x3c\x2e\xb5\xd5\xc0\xcb\xc0\xf5\x41\xeb\x72\x3c\x47\xce\xc6\x01"
-  "\x3c\xbf\x9a\xcf\xe1\xd7\xf7\xce\xff\x63\x3e\xfc\x1f\xdf\x9f\x64"
-  "\x9d\xbd\xc8\xa5\x00\x1a\x5b\x67\x63\x5b\x39\x36\x27\x00\x6f\xeb"
-  "\x0d\xee\x7e\x5c\xc7\xf6\x09\xed\x6f\xf3\xec\xa7\xf5\xc5\xee\xf1"
-  "\x63\xed\xf4\x69\x9b\xc9\x80\xeb\xc0\x86\x30\xa2\xf9\xa7\x8a\xfc"
-  "\x64\xd3\x26\xba\xbd\x58\x10\x67\xad\x2f\x22\x6a\x45\x01\x90\x11"
-  "\xfb\x5d\x5a\xf2\xb5\x2d\xe4\xe3\x71\xe1\xea\xeb\xe6\x25\x18\x47"
-  "\x51\x73\x24\x11\x0a\xdb\x47\xa9\x6e\x74\x5c\xb7\x9d\x86\xdc\x36"
-  "\xff\x11\xa3\x83\x68\x7f\x59\x4c\xbe\x5a\x4e\x42\x12\xc0\x72\xbf"
-  "\x59\x4d\xa0\x4e\x7f\x8f\xc2\x73\x67\xfb\xd5\x68\x4f\xfc\x3d\x0a"
-  "\xcb\xcc\x28\x21\xaa\x8c\x66\xda\x5a\xf0\xcc\x08\x15\xc8\x76\xcd"
-  "\xcb\x80\xb9\xb1\xea\xeb\xb6\xf7\x40\x19\xfb\x92\xd9\xff\x2a\x03"
-  "\xaf\x9b\x61\x02\xd4\xad\x22\xb0\xba\x1d\xde\xeb\xae\xdb\xe1\xbd"
-  "\xc3\x5c\x37\x8d\xbb\x6e\x7a\xa8\xdb\x27\x0f\x05\x56\xb7\x4f\x17"
-  "\xba\xeb\xf6\xe9\x42\x3f\xeb\xb6\x2b\xf0\xba\x99\xae\x83\xba\x9d"
-  "\x0c\xac\x6e\x47\x9d\xee\xba\x1d\x75\x5e\x48\xdd\x70\x6c\x6e\x8e"
-  "\xa2\x27\x99\xaf\xe3\x14\xa2\xc6\xbd\x5d\x2d\xe4\xf0\x83\xe6\x12"
-  "\xf6\x3c\x1e\x7e\x2b\xa4\xfe\x6e\xcf\xea\xa4\x5f\x72\x3b\xe6\xef"
-  "\x2b\xee\x30\xe0\x9e\xe6\xbf\x2f\x01\x2c\xab\x39\xa6\x0f\x33\x5b"
-  "\x3b\xcb\x4e\xa5\xbd\x86\x7f\x2f\x2c\x63\xfb\x15\xde\xd0\x4b\xcf"
-  "\xf5\x1d\x63\x2a\x92\x71\xaf\x80\x08\xfd\x9b\x8e\xa9\x58\x8e\x71"
-  "\xdd\x5e\x4f\xb1\x0b\x34\x07\xfd\x10\xa1\xaf\x24\x25\xa1\x1b\x2b"
-  "\x32\x5e\x4f\x71\x08\xe8\x37\x60\x3d\x3b\x87\xf7\xf7\x6a\xf9\x8c"
-  "\x89\xfc\x0d\xfb\xe8\x37\xf4\x90\x6e\xb3\x49\xb1\x16\xa9\x80\xb6"
-  "\x49\xc5\x12\x2c\x1f\xd2\x1d\x72\x3c\x44\xc0\xbb\x1c\x93\xa5\x33"
-  "\xdc\x31\x98\x1c\x3c\x3c\x4d\x96\x83\x09\x46\x12\x8e\xf1\xd0\x36"
-  "\x99\x47\xe1\x1a\x22\xd8\x54\x7f\xdf\x8b\x74\x4f\xec\x1c\x45\xc3"
-  "\x33\x48\x08\x9e\xad\xc1\x3d\x5c\xd6\x48\x3b\x89\xce\x20\x23\x12"
-  "\x4d\x50\xa6\x83\x24\x87\x9b\xa0\x3c\xa0\x35\xb7\xf5\x0f\xb3\x73"
-  "\x70\x9b\xa1\x3c\xdc\xdb\x1a\x62\x24\xea\x84\xc8\x2c\xba\x7e\x2b"
-  "\x51\xe2\x39\x1c\x3c\x4f\xc3\xcf\xd2\x8c\x54\x75\xe5\x1c\x2e\x97"
-  "\xdb\xe7\x07\x7f\xc2\x38\x7f\x8e\x9c\x74\xf3\xe7\xc8\x2b\xfd\xf9"
-  "\x73\x24\x94\xf3\xe7\x88\xd2\xcd\x9f\x4f\xe7\x78\xf3\xe7\xc8\x34"
-  "\x6f\xfe\x1c\x31\x04\xc7\x9f\x23\x7a\x37\x7f\xf8\x37\x38\x7f\x8e"
-  "\x64\x0f\xcc\x9f\x23\x5b\xdc\xfc\x39\x12\xe3\x1f\x7f\x8e\xd4\xfa"
-  "\xe6\xcf\x91\x85\x83\xf0\x67\xe4\xc0\xfc\xf9\x74\xb2\xff\xfc\xf9"
-  "\x74\x4e\x00\xfc\x09\xe5\xfc\x39\xfa\xbc\x9b\x3f\x47\x1f\xe8\xcf"
-  "\x9f\x4f\x2b\x38\x7f\x3e\xdd\xe1\xe6\xcf\xd1\x56\x6f\xfe\x7c\x5a"
-  "\xeb\xcd\x9f\xa3\x9a\xe0\xf8\x73\x54\xe5\xe6\x0f\xff\x06\xe7\xcf"
-  "\x51\xed\xc0\xfc\x39\x3a\xc3\xcd\x9f\x4f\x6b\xfc\xe3\xcf\xd1\x15"
-  "\xbe\xf9\xf3\xa9\x33\x70\xfe\x1c\x7d\xa7\x0f\x7f\x34\xbe\xf9\x73"
-  "\xb4\x35\x00\xfe\x84\x73\xfe\x1c\xbb\xc5\xcd\x9f\x86\x2f\xfa\xf3"
-  "\xa7\xe1\x11\xce\x9f\x86\xd9\x6e\xfe\x1c\xcb\xf3\xe6\x4f\xc3\x0a"
-  "\x6f\xfe\x34\x54\x06\xc7\x9f\x86\x72\x37\x7f\xf8\x37\x38\x7f\x1a"
-  "\x2c\x03\xf3\xa7\xa1\xc1\xcd\x9f\x86\xe5\xfe\xf1\xe7\x58\xa8\x6f"
-  "\xfe\x34\x94\x0c\xc2\x9f\x51\x03\xf3\xe7\xd8\x13\xfe\xf3\xe7\x58"
-  "\xde\x60\xfc\x09\xcc\xf6\x3b\xc6\xec\xaa\x61\x28\xa7\xd9\x57\x39"
-  "\x48\x3b\xdc\x9f\x26\xe6\x1c\x6b\x2e\x13\x47\xb2\x58\x52\xf0\xbb"
-  "\x44\xbb\x96\xdc\xdf\x44\x3e\xbb\xab\x4c\x1c\xa1\xa2\x39\x65\xc9"
-  "\x62\xce\x76\x2d\x5d\x37\x52\x29\xae\x1b\xa5\xc4\xb3\x91\x03\x95"
-  "\xc5\xf7\x4b\x7e\xf6\x9b\x90\x89\x64\x0a\x9e\x77\x59\x0f\xf6\x33"
-  "\xfe\xee\xca\xf9\xac\x04\x6c\x41\xdd\x60\xe7\x2e\x70\xef\xd2\xfe"
-  "\x0d\x38\xee\xfd\xac\xba\xf7\xbc\x7a\x0e\x35\xa1\x8f\x22\xc3\x4d"
-  "\xb8\xc7\xfe\x33\xfb\x66\xe6\xf3\xa6\x5c\x15\x7f\x13\x3d\x81\x63"
-  "\x91\x16\xf2\xf9\x69\x9a\x5f\x8e\xf3\xc8\x9d\x60\xbb\x5f\x73\x8a"
-  "\x7c\x3e\xa3\x77\x4f\x17\x4d\x7a\x49\x9a\xf3\xdb\xc3\xf3\x1e\x7f"
-  "\x82\xe6\xef\xdc\x83\xf1\xef\x56\x9b\x31\xae\xdb\xf1\x07\xc1\xf6"
-  "\xbd\x15\xbf\x81\xfe\x57\xb6\xc1\x1d\xf7\xbd\xf0\xbd\x7b\x9f\x33"
-  "\xbf\x59\xe8\xe3\x8d\xef\xe9\x3f\x3e\x4d\xc6\x1d\x7c\x67\x0c\x3c"
-  "\x5f\x2b\xd9\xf7\x98\x7f\xec\x29\xd2\xe8\xf2\x78\xaf\x86\xe7\x2f"
-  "\xa0\xec\x71\xd2\xfb\x50\x78\x3e\x88\x76\x36\x3b\x7f\x5f\x94\x2d"
-  "\xed\x31\x6d\x2c\x87\x34\x8d\x94\x67\x1c\xe4\x29\x44\xdb\x5d\x2a"
-  "\x63\x3c\x3c\x3f\x8b\x63\x62\xe9\x7d\x04\x3c\x3f\x86\x6b\x01\xd2"
-  "\xfb\x6b\xe1\xf9\x07\xf0\xfc\x3d\x7e\xde\xa1\x47\xea\xa3\x8d\xca"
-  "\xe0\xce\x6c\x36\xb2\xf1\x1f\x8f\xd3\x8e\x63\x81\xc6\xb9\xee\xfd"
-  "\x3c\x9f\xb7\xf5\x79\xa7\xf7\x78\xd7\x28\xbf\xe3\x7b\xce\x1a\x37"
-  "\x78\xbc\xab\xe9\xf3\x6e\xbb\xc7\xbb\xbd\x7d\xca\xdc\xeb\xf1\x6e"
-  "\x57\x9f\xff\x35\x78\xbc\xdb\xd2\xe7\x5d\xa7\xc7\xbb\x3c\xe9\x5d"
-  "\x48\x57\xce\x71\xb5\x7b\x4d\xee\x73\x93\x94\x2e\x40\xba\x47\xfc"
-  "\x83\xcf\xf5\x52\x3a\x7c\xff\xf8\x4c\x1b\x29\xde\x23\xa5\x33\xde"
-  "\xf3\xf2\x8f\x2f\xf0\x28\x7f\x06\x9f\xfb\x38\xae\xef\xdd\x0b\x37"
-  "\xa6\xa2\x4a\xec\x49\x7a\x09\xde\x69\x11\x57\x9e\xd8\x5e\x99\xa6"
-  "\x7d\x2a\xf5\x17\xda\x94\xa5\x46\xdc\x8e\xb2\x62\x99\x51\xbb\x62"
-  "\xd5\x92\xa5\x5e\x7e\x97\x23\xd0\x6f\x19\xc6\xf5\x41\x9f\x0a\x92"
-  "\x8f\xf0\xd6\x5e\xdf\xf8\x20\x57\xe1\x5b\x30\xfe\xbf\x9f\xf9\x60"
-  "\xdf\xcc\xfd\x13\x57\xa3\x4f\x06\xee\x7f\x81\x3c\xdc\x44\x8e\x1f"
-  "\x93\xfc\x2f\x58\xba\x72\xfe\x41\x7c\xfb\x5f\x38\xd1\xc8\x7c\xa4"
-  "\x41\x3e\xee\x7f\xe1\x84\x0d\xfa\x79\x02\x1d\xc3\xfd\xe4\xf3\xf8"
-  "\x3a\xff\x90\x6d\x13\xfb\xa2\xf3\xcc\xcf\x58\x36\x9f\xdb\xe8\xeb"
-  "\xfb\x71\x67\x2b\xfe\x4f\x5a\xeb\x6e\xf5\xf8\xff\x72\xfe\x5e\xd6"
-  "\x0f\xd2\x37\xf3\x76\xe2\x5e\xd9\x31\x4d\xf0\xcc\xe6\xe3\xd9\xbb"
-  "\x7f\x70\x3f\x2e\xf9\x3b\x59\x9b\xb0\xdd\xde\x6d\x13\x7e\xda\x44"
-  "\xfe\xf1\x96\x47\xdb\x1a\x3d\xfc\x49\xc9\x6d\xe0\x3e\xbb\xfa\xb7"
-  "\x95\x9d\xd7\xa1\xaa\x9d\x76\xfc\x36\xca\x33\xbe\xd7\x1d\x9e\xf3"
-  "\x77\xb6\xc9\xf5\xf1\xa8\x1f\xdb\x47\x07\xf5\xfb\x82\xd3\x04\xe4"
-  "\x07\xf0\x54\x6a\xc3\x2b\x34\xe7\xf8\x06\xb6\x77\x1b\xcf\xee\x61"
-  "\xec\x02\xa6\xab\x4e\x2c\x97\xe7\x2a\x51\x47\x71\x5f\xd8\x27\xdc"
-  "\xf6\x1f\xfa\xf9\xc9\x97\xf5\xd7\x09\x0f\xfb\x8f\x7f\x13\xd2\x76"
-  "\x79\x62\xc8\xe3\x7b\xc7\xf0\x7b\x90\x6f\x01\xdf\x2f\xbe\xb3\x0d"
-  "\xfb\x3b\x3c\x33\x3f\xa2\xf8\x5f\xac\xa3\xaf\x58\x50\xbe\xfc\xb0"
-  "\xb9\xe9\x68\x8b\x96\xe9\xb8\x99\xc5\x2a\xb1\x4d\x97\xe7\xf1\xd8"
-  "\x79\x15\xc8\x83\x7d\x0b\xe5\x13\x55\x1d\xb3\x1c\xd0\x9e\x85\x3a"
-  "\xd9\xf4\x5c\xee\xda\xb7\xdc\xa9\x26\xc9\x9c\xc6\xb6\x67\x51\xd6"
-  "\x63\xdf\xe1\x32\xdf\x56\x2f\xf1\x3e\x9e\xb7\xc3\xb6\x15\xd3\xdd"
-  "\xfb\xb4\x6d\x76\x39\x9f\x2c\x9f\xf9\x3a\x94\xed\x43\x96\x8f\xc7"
-  "\xaa\x9c\xc3\x79\xff\x3d\x4d\x13\xb1\x35\x4a\xf9\xd9\xde\x51\xee"
-  "\x5f\xc3\xe6\xa0\xf9\x6f\xcc\x81\x3a\xb7\xda\xc8\x71\x69\x9f\x31"
-  "\xff\x2e\xdc\x1b\xb1\x2e\x48\x2b\x3c\xfb\x49\xf3\xed\x5b\x80\x4f"
-  "\xf1\xbe\xe2\xa3\xf3\xfd\xed\x4d\xcc\x07\x11\xc6\x82\xc0\x39\x58"
-  "\x2e\x93\x9b\x52\xe9\x39\x5a\x85\x3e\x3e\x21\x8f\x5a\xce\xc3\x65"
-  "\x38\x7b\xc7\xf6\x23\x1b\xd2\x70\x9e\x48\x7a\x97\x86\xe7\xe3\x7a"
-  "\x7f\x8f\xf4\xf8\x3d\x02\x7f\xd3\x34\x5a\xb9\x69\x2d\xd3\xb1\x4a"
-  "\xf7\xd9\xdb\x26\x23\x3c\xab\xfb\x3c\x47\x78\x3d\xaf\x21\x51\x6c"
-  "\x5f\x6d\x27\x6d\x66\xfb\x8f\xa5\x74\xa9\xec\xd1\xac\x3e\x69\x74"
-  "\x06\x60\x04\x63\x5e\x2e\x94\xfa\xa3\x13\xcf\x60\x86\x3b\x9f\x60"
-  "\xe7\x2f\x31\xd6\xbb\x74\x8f\x95\xee\x31\x3c\x4e\x60\x53\x8c\x3b"
-  "\xd6\x2f\xce\xd5\x34\xcd\xf4\x15\x7b\x58\x8e\xcd\x2c\xc7\x1e\xc6"
-  "\xf3\x9b\x52\x8c\xa2\x85\xf0\x3f\xe3\x60\x71\x9e\xe1\xfd\x66\xf9"
-  "\x2c\xa6\x2b\x6f\xe7\x76\x31\xaf\x01\xfd\xbe\xde\x80\x3e\x87\xb2"
-  "\xda\xd0\x67\x43\x27\xb1\x92\x6e\x62\x35\x76\x65\x63\x9c\xba\x3a"
-  "\x1e\x9f\x2e\x0c\xf9\x81\x67\x81\xd0\x86\xac\x33\x9c\x66\x31\xea"
-  "\xd2\xdb\x48\x94\x21\x8e\x36\x03\x0d\x1c\xae\xfc\x9d\xdb\x25\x1c"
-  "\x6d\x05\x5d\x38\xe5\x14\xf9\x92\xc9\x66\x16\x57\xb5\x8d\xad\x67"
-  "\xa9\x5a\xc8\x97\x79\x2c\x0f\x4d\xda\xca\x69\xf7\x25\xd3\x0f\xdb"
-  "\x72\xe4\x38\x64\x5f\xc6\xca\xb1\x4e\x6d\xe4\xcb\x82\xb3\xa3\xdf"
-  "\x2c\x87\xb4\xd9\xde\x7b\xa1\xbf\xc4\x98\xac\xe1\x58\x77\xc8\x43"
-  "\xb0\x6c\xc8\xe3\x96\xff\x90\x9e\xee\x24\x93\xa0\x5e\x2d\x72\xf9"
-  "\xf0\x3e\xcf\x46\xbe\x60\x3a\x06\xcb\x3c\x9b\x7f\xac\x1e\xd2\x4a"
-  "\x6c\xc2\x73\x5a\xbe\x97\xfa\xcb\x72\x1b\x29\xd9\x33\x98\x2d\x04"
-  "\x7d\xc1\x04\x7d\x29\x5b\xcc\x7b\xc3\xc0\xfd\x03\xbf\x61\xe2\x73"
-  "\x8f\x5f\x9e\xc5\xfd\x5a\x9b\xce\x11\x25\xce\x05\x72\xcc\x36\xb3"
-  "\x73\x85\x98\x06\x32\xbb\x1c\xfa\x08\x6b\x5f\x60\xfa\xbf\x99\x9f"
-  "\x83\x68\x27\xaa\xa2\x14\xd9\xbf\x71\xf3\x3c\x0f\x5f\xeb\xd2\xf9"
-  "\x88\xe6\x35\x75\x26\xb6\x8e\xcd\xea\xd8\xb7\x0e\x58\x5f\xa0\x53"
-  "\xa7\x4f\x5b\x53\xf5\x86\x81\xad\xb9\x6c\xac\x28\xe0\x7b\x4f\x9b"
-  "\xf7\x85\x44\x4e\x7c\x0e\xbe\xb5\x57\x9e\x4b\xc4\x3c\x45\x18\x03"
-  "\x14\xca\xef\x6d\x67\x0a\xfb\x46\x33\xef\xeb\xcd\x0e\x31\xff\x0d"
-  "\x03\xd6\x41\x4a\x77\xd4\x39\x1d\x78\x76\x7b\x40\x3f\x38\x2c\xbe"
-  "\x13\xee\xf5\xde\xf8\x86\x01\xcf\x97\xdc\xe9\x90\xeb\x7c\xd2\x81"
-  "\xe7\x1a\xb0\xce\x9c\xb6\x27\x4f\xcb\x74\x2c\x6c\x87\xb2\xcd\x9f"
-  "\x91\x66\x72\x32\x15\xf7\xc3\xe1\x39\x1d\xec\xc3\x9c\x06\x27\x53"
-  "\x59\xbe\xee\xde\x3c\xcc\xdf\x05\x8b\x19\x02\xe5\x97\xb1\xf8\x42"
-  "\xd0\x06\xe0\x85\xc5\x8c\x67\x76\x4f\xb2\xb1\xdd\xfa\x14\xc2\xdb"
-  "\xcd\xf6\xbf\xb6\x44\x71\xac\x9c\xdc\x23\xeb\x0c\x9b\x94\xb6\x09"
-  "\xbf\x9d\xd6\x4d\xce\x90\x93\xbf\xc3\x18\xbf\x40\x8f\x6c\xf4\x1f"
-  "\x55\xd7\x09\xfd\xc4\xd4\x8d\x58\xc0\xd8\xc0\x80\xa1\x93\x9b\xb9"
-  "\x9e\x43\x9a\x9f\x34\xe1\xf7\x91\xb6\xc0\x3b\x3b\xd0\x34\xbf\x2b"
-  "\xa7\x45\x23\xd3\xb4\x68\x02\x8e\x7b\x4e\xc6\x0c\xa6\x23\x5c\x50"
-  "\xe7\x3a\xb0\xae\x2c\x93\x3e\xc3\xfa\x1d\x13\xc7\xbc\x61\xc0\xbd"
-  "\xd6\xf0\x3b\x53\x92\xed\x8c\x77\xbc\x2f\xb5\xbc\x01\xdf\xd8\x83"
-  "\xfb\x16\x50\x56\xa2\x8f\x23\x48\x4b\x92\xe8\xc7\xfc\xdc\x17\xa7"
-  "\x71\x3a\xf0\xfc\x5f\xa9\xf9\xbc\xf1\xc4\xbf\x40\xbd\x3c\xd6\x7f"
-  "\xbe\x62\xfe\x56\xca\xa4\xb8\xdc\xf0\xee\x80\x47\x9d\x3b\xd9\x39"
-  "\xc9\x76\x9c\xf3\x6b\x59\x8e\xdf\x2a\x44\xff\x3e\x88\x8b\x53\x9e"
-  "\xf8\x6f\x79\x04\xeb\x89\x7b\x79\x5d\xa3\x2b\x0a\x40\xef\x16\x23"
-  "\x9d\xe1\x3f\x1b\xa0\x2f\x18\x06\xd1\x89\x2c\x96\x54\x57\xce\x57"
-  "\x33\x64\x9d\x08\xe3\x0c\xd0\x0b\xad\x77\xb1\xf1\x27\xd8\xd5\x56"
-  "\x11\xed\x9a\xd6\x58\xc4\x0d\xf4\xf5\x66\x49\xc6\x36\xc3\x7f\x96"
-  "\xcb\x6b\x62\x2e\x3c\x0f\x71\x86\xad\xe3\x76\xca\xf1\x96\xb8\x3f"
-  "\xad\xaf\x8a\xdd\xe7\x27\xbe\x2a\xe9\x77\x7e\x02\xcf\x8d\xbc\xc0"
-  "\x62\xfc\xec\x42\x9d\x52\xdb\xd6\x8c\x3a\x82\xfd\x1f\xcf\x54\x98"
-  "\x61\x6c\xce\xcf\x9e\x34\xe3\x3c\x3d\x8b\x8f\x80\x75\xe1\x3e\xf1"
-  "\x9b\xd8\x6f\xc0\xad\x12\xef\x1c\x4b\xad\xa4\x37\x66\x2f\xf0\x1b"
-  "\xd7\xe0\xf6\x2b\xff\x9d\x58\x6e\x42\x7d\xdd\x7a\x17\xc6\x9f\x85"
-  "\x3c\xd1\x72\xec\x59\x16\x6b\x96\xb7\x67\xc0\xb1\x1c\xf3\xf1\x76"
-  "\x07\x89\x45\x9f\x18\x78\x0e\x8b\xd1\x40\x65\x9f\x81\x7e\x63\xd1"
-  "\x07\x9e\x65\x2d\xc6\x6f\x68\xfd\xe2\xb7\x13\xd8\x59\xd6\x4e\xcb"
-  "\x1d\xed\xb8\xbf\xaa\xad\x25\x83\xf9\x45\x51\x25\x9a\x9c\x14\xff"
-  "\xc7\xec\x8a\xd1\xf6\x19\xf8\x8e\xf9\x4f\xc7\x32\x83\xf6\x81\xda"
-  "\xba\x4b\xb2\x51\xdb\x40\xee\x5f\x07\xbc\x62\xeb\x1a\xf0\x7b\xc2"
-  "\x29\x72\x6a\x34\x8f\x87\xc8\xfd\x79\x4b\xfb\xac\x47\xf2\x33\xf2"
-  "\x40\x33\xe6\x2b\xf4\xeb\x4c\xed\x6d\x18\x3b\xf4\xeb\x75\xcc\xa7"
-  "\x6e\xde\xce\x4e\x89\x06\x9d\x9b\x78\xbd\xc2\x17\x99\x04\x56\x47"
-  "\xac\x5f\x60\x75\xfb\x7a\x8e\x34\x9e\x18\xd9\x95\xf3\x75\x81\x7c"
-  "\xb6\x9e\xdb\x55\xdc\xd7\x2e\xe7\xc5\xd7\xd2\x19\xb3\x9d\x0e\xe9"
-  "\xdb\x8e\x61\xf8\xf6\x01\xa9\xcc\x1a\xee\x6f\xb8\xd5\x00\xe5\xd6"
-  "\x74\xe5\x9c\x8a\x90\xc7\x35\xd2\xd9\xa0\x18\x3e\xde\x3a\x15\xe3"
-  "\x1e\xd7\xb4\xf6\x3b\xe7\x3b\x6b\xd5\x2a\xa3\x76\xc9\xb2\xd5\x86"
-  "\xc5\xc6\xa7\xf5\xda\xa5\x29\x29\xab\x52\xb4\xe8\x2c\xc5\xb3\xff"
-  "\xf0\xf8\x26\xa7\xe2\xa5\x78\x5e\xe5\xee\x78\x5e\xa7\xf2\x3c\xe3"
-  "\xce\xd9\xc8\xa9\x82\xe1\x99\xc3\x38\x55\xee\xab\x9c\x62\x41\xac"
-  "\x84\xab\x0a\x2e\x0b\x5c\xd5\x38\xa7\xb1\xc8\x41\xe2\x41\xd7\x33"
-  "\xfb\x50\xf6\xc5\x2e\xe6\x9c\x4a\xc6\xbd\x43\x4d\xe4\x9f\x23\xca"
-  "\x44\x25\x61\x3e\x40\x72\xc4\x4a\xcc\xbf\x0d\xfe\x0f\x97\x05\xae"
-  "\x6a\xb8\xd8\xff\xc4\xf7\xd9\xb9\xea\x4a\xcf\x77\x7c\x5f\x88\x29"
-  "\x16\xf3\xd0\x75\x4a\xb6\xfe\x2b\xfe\x37\xcf\xd7\xa7\x0e\x02\xcd"
-  "\xf9\x72\xaf\x94\x8f\xe9\xd7\xb0\x75\x44\x3b\x40\xbe\x10\x9a\xf3"
-  "\x59\xa5\x94\x8f\xed\x77\x91\xdb\x83\x7e\xcb\x21\xbf\x9c\x4f\x49"
-  "\x73\x5a\x67\x4b\xf9\x98\xdc\x14\x73\x84\x81\xbe\x3b\x82\xe6\xfc"
-  "\x8f\x4e\xca\xa7\xf1\x2c\xcf\x23\xcf\x48\x31\xa7\x7e\x17\xe6\x11"
-  "\xd7\x29\xb9\xdf\x84\x9c\x53\xe5\x90\x7f\x40\x7f\x8f\x81\xf1\xa9"
-  "\xad\x9f\xff\x27\xc3\xd3\xcb\x96\xde\xbb\x6c\x65\x1a\x46\xa0\x31"
-  "\xae\x4a\x35\xe2\x7d\xe5\xe2\x5f\xb1\xdb\xaa\x45\xcf\x3c\xcd\x7f"
-  "\x18\x97\xc7\xe2\x8f\xe5\x80\x37\xbc\x2f\x49\x35\xe0\xed\xe9\x55"
-  "\xf8\x68\xd2\xc7\xa4\x3e\x2d\x87\xa2\xf6\xc4\xa1\xae\x2b\xa7\xcd"
-  "\x01\xd8\x68\xe5\x72\xf6\xb4\xd2\x46\x3e\x63\x72\x19\x63\x52\x1c"
-  "\xd4\x39\x89\x3c\xbf\xc5\xf9\xdf\x36\x8f\xfb\x66\x3c\x3d\xae\x4c"
-  "\x1c\xa5\x0a\x5f\x67\x78\x3a\xdc\xb9\x6c\x29\xe8\x8c\xbd\xf0\xdf"
-  "\x78\x1b\x79\x7a\x0e\x97\x8d\xe5\x4a\xe6\x87\x30\xa7\xad\x58\xda"
-  "\xb3\xa9\x14\xf3\x76\x56\xa1\x2f\x70\x78\x66\x31\x5f\xe1\xb9\x19"
-  "\xf2\xe1\x9e\x4e\x8c\xf5\x1a\x01\xcf\x16\x9c\x9b\x82\x67\x8c\xa1"
-  "\x1a\x25\xe6\xbd\x54\x8f\x67\x51\xe1\x59\x0b\xcf\xd1\x50\xfe\x76"
-  "\xb9\x5f\x0c\x6c\x2b\x9f\xb6\xc8\x71\x68\x79\xcc\xd9\xd3\xf5\xbd"
-  "\x31\x67\x31\xce\x8c\x59\xc3\xe2\xd2\x70\x1b\xe4\x74\x67\x48\xe4"
-  "\xf5\x63\x20\x4f\x67\x6f\x1c\x1e\x36\xef\x71\x46\x29\xef\x97\xe1"
-  "\xf3\x1a\x67\x22\x3c\x62\xf7\xe2\x73\xb4\x1c\xbb\x17\xe7\xbd\x58"
-  "\x6c\x34\xb8\xd3\x1c\xf4\xf7\x48\x07\x3c\xb7\xcc\x63\xea\x9d\xc9"
-  "\x47\x3f\x9f\xf6\xac\x25\x8a\x9b\xcb\x70\x2e\x0d\x9e\xb9\x8f\x37"
-  "\x7a\x86\x9c\x61\xfb\xaf\x65\xff\x4f\x9e\x3e\x07\x06\x3c\xe7\xf4"
-  "\x09\xd8\x0c\x2c\x66\xc8\xf2\x55\xe1\xce\xc5\x4b\xb9\x1d\x78\xe6"
-  "\x6b\x2e\xbf\x2a\x2a\xb9\xbd\x70\xe6\x30\x9d\xcf\xe3\x2c\xd8\xc8"
-  "\x37\x49\x38\x66\x09\x57\x2c\x5f\x45\xe1\xbf\xe1\xa6\xc5\x4b\x59"
-  "\x1a\xe4\x5b\x0f\xb6\x9a\x54\xbf\xb7\xad\x51\x78\x3e\x52\x94\x7c"
-  "\x29\x9c\xa9\x7a\x72\x72\x36\x7e\x47\xc5\xec\x90\x4f\x88\x1a\x63"
-  "\xdb\x61\xdd\xca\x3c\xfc\x53\x6d\x82\x34\xdc\x1b\xda\x31\x9f\xa8"
-  "\xd1\x4f\xa7\x54\x97\x2a\x1e\x6b\xe8\x9b\x79\xb2\xaf\x18\x1b\xa4"
-  "\xf5\x6d\xcf\xfc\x9f\x30\x54\xde\xf2\x74\xcc\xbc\x07\xe1\x57\x8c"
-  "\x14\x56\xd5\x13\x9b\x51\x1d\x63\x5e\x37\x75\xfc\xfe\xfe\x5f\xf0"
-  "\x18\x80\xdf\xc0\x18\xe2\x0c\xdb\xeb\x2b\xe2\xb8\xa4\x2b\x69\x0b"
-  "\xdf\x5b\xfa\xcd\x31\xf4\x8b\x29\xe6\xa0\x3d\x89\xe7\x6b\xbf\x61"
-  "\xf2\x8b\xaa\x2a\xf6\x6c\xcb\x44\x7f\xb1\x0a\xa0\xf1\x37\xef\xe0"
-  "\x3b\xc9\xe7\x8e\xc0\x7c\xd4\xb8\x48\x24\x3b\x5f\x0a\x36\x0a\xfa"
-  "\x97\x69\x21\xed\x6f\xa1\xdd\x81\xf3\x4a\x62\xce\x37\x4b\x10\xb7"
-  "\xc0\x63\xf4\x35\xd1\x49\xc7\xec\xdc\x41\x47\xef\x5e\x80\x38\x46"
-  "\x5b\xd7\xaa\x41\x9a\xd9\x51\xe7\x24\xc0\xf5\x53\x1e\xcf\xe2\xf1"
-  "\x56\xb9\x4c\xf4\x8b\x04\x36\xd4\x5e\xb8\x6b\xba\x72\xec\x49\x1e"
-  "\xb1\xba\xa4\xf3\xb4\xf6\x35\xe8\xaf\x09\xcb\xe6\xb6\x73\xfb\x2b"
-  "\xdc\x06\xb1\x6f\xb0\x91\xf0\x99\xbc\x2f\xda\xc1\xfe\xc9\x8e\x91"
-  "\x7e\x83\xfd\x13\xb3\xbd\x4f\x19\x27\xe5\x39\x53\x8e\x69\x3b\xce"
-  "\x3d\x24\xc0\xf5\x53\xc8\x5f\x23\xc7\x6b\x5e\x2f\xb0\xf3\x8f\x2d"
-  "\x21\x91\x78\x2e\xda\xde\x2c\xa7\x8f\x50\xc4\x03\x4d\xed\x9d\x72"
-  "\xdf\xef\x18\x53\xb1\xa5\x2b\xe7\x5b\xa5\x3c\xd7\xc2\xe7\x5e\xbe"
-  "\x8d\xf0\x78\xde\x01\xcf\xd1\xf2\x33\xfc\x8e\x95\x65\x05\xfc\x86"
-  "\xf1\x6f\x56\x9b\xf4\x7b\x8e\x8d\xe4\x94\x4b\xbf\x17\xd8\x84\x8c"
-  "\xd9\x72\xbd\xc5\x9c\x90\x70\x5e\xf7\xf6\x02\x31\xbf\xc1\x86\x31"
-  "\xb2\x21\x8f\xc9\x46\x4e\xb3\x3d\xe9\xe8\x1f\xa9\xa0\x5b\xb3\xc0"
-  "\xba\x01\x6c\xe2\x67\x10\x4b\xed\xac\x6f\x14\xae\xd5\xcc\x43\x7b"
-  "\x12\xfd\x40\x30\x5f\x5a\xe8\x3f\xce\x49\x46\x32\xbf\xe3\xf9\x0d"
-  "\xf5\xcc\xdf\x76\xba\x4e\x2d\xfb\x8e\x03\x39\xb3\x90\x0a\xcf\x6c"
-  "\x40\x7f\x72\x2c\xbe\x40\x97\x2e\x8c\xf9\x90\x93\x7c\xc7\x95\xa6"
-  "\x91\x88\x12\x91\xfb\x8e\x63\x3e\x22\x46\xc2\xf8\x23\x6d\x60\xff"
-  "\x71\x34\xe7\x95\x7a\xd9\x7f\x1c\x3d\xe7\x72\xc0\xef\x68\xe0\xb9"
-  "\x12\xee\x3a\xf6\x8c\x3e\xe4\xb8\xef\x60\xe5\x80\xfe\xe4\x04\x90"
-  "\x67\x02\xf7\x27\x17\x98\x1e\x68\x4f\xe2\x98\x68\xdf\x22\xc7\x8e"
-  "\xf6\x48\xdb\x05\x7d\x61\x33\x4f\xb3\x4b\xbe\x61\xda\x41\xfe\x65"
-  "\xc5\x4b\x7b\x24\xed\x38\x2f\xb6\x99\xcd\x7d\x7d\xe3\xa4\x3d\xfa"
-  "\xad\x03\xc9\x92\xf6\x31\xed\x95\xed\x6c\x2f\x60\x07\xd8\xbe\x1d"
-  "\xcc\xde\xe2\x63\xc4\x0e\xd2\xb7\xbf\x3e\xf5\xf4\xaa\x25\x4b\x17"
-  "\xfd\x72\x85\x41\x3b\x7f\x41\x02\x0b\x8c\x16\xa3\x5d\x66\x5c\xca"
-  "\x54\x8d\x76\xfe\x83\xb3\x12\x13\x17\x2c\xfa\xc9\x82\x07\x16\x3c"
-  "\xf6\x93\xfb\xf8\x09\xc3\x05\x29\x6b\x30\xb8\x9e\x71\x95\x16\xff"
-  "\xf4\x94\x14\xfa\x76\xed\xd2\x94\x55\x7d\xfb\x79\x04\x9b\xbf\x12"
-  "\xd8\x9c\x6d\x27\xfe\xe6\x73\x64\x1d\x25\xf2\xdc\x15\x97\x69\x1d"
-  "\x85\x48\x5b\x16\xeb\x30\xa7\x23\x02\xed\x26\x29\xc6\x30\xea\x13"
-  "\x25\xf6\x55\xd4\x2b\xd0\x96\xea\xde\x78\xa8\xbd\xf3\x67\x1d\x6d"
-  "\x02\xfe\x4f\xea\xa3\x3c\xad\x53\x41\x27\x4d\xca\xe2\x7e\xf8\x3b"
-  "\x9c\xf2\xbc\x36\xa6\xc9\x75\x68\xc2\x3c\x39\x1d\x0f\xba\x63\x72"
-  "\x76\x46\xbb\xe3\xce\x91\x7e\x34\x22\x04\xcd\x94\x11\x60\x83\x8c"
-  "\x84\x6b\x14\x5e\x73\x7a\xe5\x76\x1a\x6d\xc0\xb1\x58\xb8\x02\x74"
-  "\xab\x29\x84\xc7\xbc\xc9\x3d\xcc\xfc\xb3\x27\xba\x9c\x21\x8b\x5c"
-  "\x02\xdc\x43\xe8\x22\x97\x92\x8d\xff\x68\x1a\x3d\x8c\xbe\xd0\xe0"
-  "\x7f\xf5\x18\xdb\x09\x70\x9c\x97\xe8\x34\xe7\x25\xba\xa8\x73\x11"
-  "\xd8\xe5\x70\xff\x0a\xcf\x78\x27\xba\xbe\xa2\x2c\xae\x05\xe4\x2d"
-  "\xe2\xfe\xbf\xaa\xf1\x3c\xea\x93\x80\xe1\xb2\x76\x1e\xd7\x33\x71"
-  "\xcd\x37\x27\x16\xad\xb1\xf1\xb8\x9e\x67\x78\xfc\x5a\x1e\x97\x97"
-  "\x98\xa1\x9c\x0f\x17\xb9\x42\xb4\x89\xae\x1e\xca\xcf\xa9\x9e\x55"
-  "\x0d\x16\xab\x73\xc0\x79\x89\xdc\xea\x4a\x5a\xb8\x7a\x03\xcd\xfd"
-  "\x28\x9b\x16\x1a\x95\x34\x6f\xb7\x09\x65\x33\xcd\xad\x9b\x07\xcf"
-  "\x90\xfe\xb1\x96\x16\xa6\x2a\x69\xee\xdf\xed\x70\x87\xe7\x4f\x2d"
-  "\xb4\x30\x0d\x9e\xdf\xc8\x83\xff\x65\xd3\xdc\x3f\xe1\xff\x08\xcd"
-  "\x7d\xd3\x04\x77\x78\xde\x63\x80\x7c\xf0\xfc\x96\x1e\xee\xf0\xfc"
-  "\xbf\xc9\x2d\xe4\x6c\x0d\xfc\x07\xd2\x8e\x15\xf3\x6f\x35\x16\xb3"
-  "\x6f\xe5\x9e\x28\xe6\xdf\x68\x2a\xe6\xdf\x38\x59\xcc\xbf\xd1\x5a"
-  "\xcc\xbf\xf1\xe7\x24\xc8\x9f\x47\x73\xab\xaa\x21\x1f\xd4\xf5\x2f"
-  "\x33\xe0\x0e\xcf\x7f\x2d\x87\x7c\xf0\xfc\x4e\x24\xdc\xe1\xf9\x5d"
-  "\xa8\x4b\x1a\x3c\xbf\xe7\x80\xfc\x05\x34\x77\xdf\x72\xc8\xa7\xa6"
-  "\xb9\xef\xdb\xe0\x0e\xcf\x07\x16\x40\x3e\x78\x3e\x08\xe5\xa4\xc2"
-  "\xf3\xdf\x66\x42\x7e\x78\xfe\x27\xd6\xa7\x98\xe6\x9e\xc6\x72\x35"
-  "\x34\xf7\x0c\xe6\x87\x67\x3b\x94\x97\x0a\xcf\xed\xb1\x70\x87\xe7"
-  "\x8e\x06\xc8\x0f\xcf\x67\xa1\xad\xab\x37\xd3\xdc\xae\x18\xc8\x17"
-  "\x41\x73\x1d\x90\x6e\x84\xe7\xee\x0d\x90\x0f\x9e\x9d\x98\x1f\x9e"
-  "\x5d\x8d\x90\x1f\x9e\x29\xd2\x68\x0b\xdd\xa8\x68\x85\x7c\x91\x74"
-  "\xa3\x72\x0e\xdc\xe1\x79\x24\xd6\x1f\x9e\x47\xab\xe0\x0e\xcf\x63"
-  "\x81\x56\x69\xf0\x1c\x0a\xf5\x5b\x5d\x42\x37\x6a\xb0\xfc\x28\xba"
-  "\x71\x3c\xd2\x07\x9e\x23\x3a\x21\x1f\x3c\x5f\x07\xf4\x48\x85\xe7"
-  "\x89\x7b\x21\x7f\xd4\x80\xfc\xdc\x18\xb5\x99\xae\x1b\x49\xe8\xc6"
-  "\x5b\x54\x74\xdd\x28\xb8\xdf\x5a\x45\xd7\x8d\xd0\xd1\x8d\xb7\x45"
-  "\x42\x3a\xdc\xbf\x57\x0c\xcf\x31\xd2\x33\xdc\x75\x7a\x78\x8e\x95"
-  "\x9e\xe1\x3e\x35\x1e\x9e\xa7\x4b\xcf\x70\xbf\xbd\x1a\x9e\x67\xd0"
-  "\x8d\x31\xdb\xe1\x19\xef\xd3\xe1\x79\xa6\xf4\x0c\xf7\x3b\x96\xc0"
-  "\xdd\x69\x9f\x1c\x37\xc7\x1e\x9a\x40\xec\xa1\xe9\x06\xd4\xd1\xae"
-  "\xa2\xd5\xd9\x62\x98\x11\x63\xe2\x8d\xcc\x3a\x8b\xf1\x30\x1d\xeb"
-  "\x50\x4e\x58\x33\x6c\x2c\x16\x98\xe4\x4f\x6e\x64\x13\xe9\xfa\x1d"
-  "\xd8\x33\x33\x30\xae\x39\xb4\x7d\x2f\xcd\x19\xd1\x0e\x6d\x9e\x49"
-  "\x73\xc6\x36\xc1\x1d\x9e\xc7\x7d\x02\x6d\x86\xe7\x7b\x36\xc2\x1d"
-  "\x9e\x1f\x9f\x05\x6d\x9f\xd9\x95\xd3\x05\xf2\xf1\x2c\x5f\x73\xf8"
-  "\xfd\xfd\xc9\xe1\xce\x2c\x9a\xe8\x04\x7d\xb0\xd5\x1c\x1b\xee\x4c"
-  "\x26\xb4\xd0\xa4\x09\x47\x5f\xfd\xa5\x71\x79\x34\x2c\x81\xd5\x09"
-  "\xe3\x71\xd0\x9e\x68\x81\x7f\x7b\x2c\x6d\x22\x8e\x1b\xd1\x6f\x3c"
-  "\x0d\x7b\xdc\xd7\xfb\x07\xd8\xfb\x49\xe6\x78\xfe\x5e\x43\xdc\xef"
-  "\x7f\x8a\xef\x17\x87\xa3\x4f\xe3\x29\x77\x80\xfd\xec\xc8\xc3\x3c"
-  "\x36\xd2\xb5\x83\xe6\x84\x10\x6b\x67\xab\xd4\xc6\x51\x98\x2f\x1f"
-  "\xff\xe7\x6b\x3e\x46\x2c\xc8\xd0\x17\x82\xdc\xc2\xf1\x29\xe8\x2f"
-  "\x41\x6b\x8e\xae\x6a\x22\xdd\x49\xa5\x68\xbf\xa8\xcd\x2a\x2e\xcf"
-  "\xce\x4f\xee\xd9\xb8\xbb\x44\xbb\x36\x1c\xca\xeb\xfe\x59\x96\x83"
-  "\x76\x5a\xcc\xe8\x27\x88\xa5\x37\xf0\x33\x3a\xec\xf7\x01\xbe\x77"
-  "\x93\xfd\xae\xe4\xf3\xc1\xdd\x49\xf8\x5f\xcf\xf1\x80\x2b\xf7\xc6"
-  "\x66\x31\xcc\xac\xe1\x6b\xdd\xe7\x6f\x7c\x47\xb4\x09\xe1\x46\x32"
-  "\x42\xbb\xf6\x3d\x28\xff\xbc\xde\x6b\xec\xd8\x9b\x97\xbd\x7b\xe4"
-  "\x5d\xc8\xfb\x32\x9b\xe7\x39\xdf\x1b\xff\x93\x42\x1b\x7e\x8d\xba"
-  "\x4b\x20\xf1\xa8\x4f\xb9\x2d\x7a\xde\x81\xbe\x25\x9d\xea\x74\xbb"
-  "\xb3\x60\x96\xdd\x55\x60\x56\xd1\x22\xb3\x26\xcc\xa9\x20\x7c\xcf"
-  "\x7c\xf7\xb4\x3b\x1d\x68\xfb\x1d\xc2\xbc\x27\xc5\x91\xb7\x47\xde"
-  "\x61\x22\x82\x25\xe5\x33\x78\xee\xbe\x85\xe6\xc6\x16\x5b\xdb\x1a"
-  "\x88\x25\x05\xcb\xea\x8e\xa6\xb9\x33\x23\xc4\x91\xf7\x44\x95\xa1"
-  "\x0d\x6d\xc2\x39\xb0\x4f\xf0\x7f\x7f\x00\x3a\x83\x1e\xe8\x56\xf6"
-  "\xc6\xe7\x05\x5a\x16\x02\xed\xd0\xbe\x45\x7f\x13\x8b\x5c\x2e\xf4"
-  "\x07\x96\x67\x03\x3a\x70\x1d\x79\xbe\x15\x63\x1b\xf3\xef\x76\xdf"
-  "\x27\x8e\xd9\x9d\x57\xb7\x10\xd7\xf5\x34\xe8\x5f\xa9\x93\x9d\x51"
-  "\x77\x62\xbc\x33\xd4\x15\x3c\xaf\x27\xef\x56\x3c\x6d\x58\xb4\xd6"
-  "\xb0\x2a\xc5\xb8\x28\xd5\x70\xaf\x16\x06\x75\xda\x55\xcf\x68\x57"
-  "\x2c\x5d\xb1\x2a\x65\x4d\x5f\xfd\x08\x63\x9b\x6e\xb0\xff\x1c\xcc"
-  "\xa6\xfa\x10\x6c\x6b\x3e\xb7\xee\x5c\x8e\xbc\xde\xfa\x02\xf7\x55"
-  "\x0f\x79\x40\xff\x3f\xcd\xd6\x20\xc4\x2d\x66\x1d\x2d\x89\xcb\xcb"
-  "\x47\x3f\x1b\xa9\xe8\x0b\xdd\x4e\xac\xa4\x9d\xc7\x18\x64\x71\xb4"
-  "\xc0\xd6\x4f\xcb\xa4\x96\xb4\x76\xc4\x38\xc8\x8f\xf4\x48\xc0\x78"
-  "\xfd\xf9\xc2\x04\x7d\x13\x71\xce\x3b\x5f\x98\xae\x92\xe3\xa0\xb8"
-  "\x0a\xd2\xf5\xa2\x3a\x23\x1b\xe3\xa0\xf4\xd0\x48\x52\x0b\xb4\xec"
-  "\xce\xdb\x6d\x04\x19\x6f\x28\xcd\xa1\x55\x2e\x18\xfb\x30\x5f\x32"
-  "\xbf\xbf\x3f\xde\x45\x75\x4a\x57\x0e\x51\xc1\x3d\x8c\x86\x65\x56"
-  "\xf6\xa8\x4d\x04\xdf\x63\xfc\x13\x57\x8f\x8e\x98\x0f\x53\xf1\xe7"
-  "\x7a\xc0\x4d\x0e\xa1\x2c\x76\xa4\xfe\x34\x81\xf4\x31\x62\x51\x7a"
-  "\x71\xcb\x1c\x22\x60\x5e\xb0\xcf\xc8\x42\xf8\x9d\xb1\x98\x84\x42"
-  "\xbe\xf0\x8c\x0f\x21\xbd\x4b\x37\xc6\x99\xa5\x53\x75\x67\xe9\xc6"
-  "\xf4\x50\x9d\xda\xda\xec\x20\x3d\xb7\xdc\x3f\x6f\x9a\x9d\x28\xb7"
-  "\x82\x1d\x57\x2a\x42\xff\x2a\x89\x33\xb8\x9e\xd3\x8d\x74\x3e\xa7"
-  "\x53\xf6\xf4\xe8\x54\xce\x74\x9d\xb2\x3b\x5d\x37\xb2\xa7\x4b\xa7"
-  "\xb2\x2e\xb1\x93\x43\xf6\x3f\x92\xba\xe6\x56\x36\xff\xda\x13\x9a"
-  "\xb9\xb7\x27\x34\xbd\x44\xdd\x4c\x22\xee\x30\x80\x1d\x97\x43\x14"
-  "\x2f\x81\xcd\x0e\x98\x50\x3b\x5f\xbb\x3f\x9e\x16\x66\x82\xbe\x71"
-  "\xde\xfd\xe0\x54\xfa\x8d\x2b\x97\x38\xb5\x0f\x83\x2c\x82\xb1\x3d"
-  "\xa4\x01\x7e\x42\x97\xd3\xdc\xd1\x7b\x60\xac\x1f\x05\x97\xd6\xc6"
-  "\xf9\x00\xfd\x9a\x56\xe2\xf8\x1f\xf3\xf2\x7c\x23\xa1\x1f\xe3\x5d"
-  "\x98\xc7\xe2\x33\xe6\x74\x2f\x29\x65\x36\x84\x53\x2f\xdb\x10\x07"
-  "\x94\x03\xfb\xf2\x80\x3c\x05\xbd\x63\x69\x11\xe4\x49\xe1\x6a\x5f"
-  "\xf3\xb0\x4a\xf4\x83\x4a\x8b\x56\x6f\x2f\x16\x7b\xfd\xa6\x82\x3c"
-  "\x74\xbe\x05\xfd\x27\x9b\xbd\x2b\x30\x69\xcc\xdf\x92\x10\x7c\x57"
-  "\x79\xce\x21\xe0\xb3\x36\x45\x41\xad\x9d\x0e\x02\xff\x51\xd2\xa8"
-  "\xb8\xbc\xca\x73\x76\x01\xf1\x52\x07\x69\xf0\xdf\xda\xe2\x73\x52"
-  "\xb9\x5b\xcc\xb1\x59\xcf\x12\x16\x2f\x00\xe3\xa3\x20\x8e\x8a\xcd"
-  "\x30\x16\xc4\x58\x2e\x29\x21\xd0\x8f\x5d\xa3\xe1\xb7\x0a\xf3\x51"
-  "\xb5\x49\x23\x42\x19\x80\x25\x13\x0d\x4d\x77\x88\x85\xe9\xd9\x80"
-  "\xa9\x78\x3a\x39\xae\x55\xdc\x6a\x8e\xec\xca\x71\x25\x03\x3d\x4c"
-  "\xf2\xdc\x42\x5d\xb9\x93\xa0\xbf\x25\x3a\xcb\x49\x0e\x1a\xcf\xa2"
-  "\xaf\xcc\x10\xfb\xe8\xdd\x26\x7b\x68\x86\xde\x1e\x9a\x99\x2c\x16"
-  "\x66\x94\xc3\xb5\xcb\x90\x82\xeb\x88\x62\xb4\x2b\x87\xfb\x8e\x4e"
-  "\xfc\x96\x76\xb1\x3d\xe3\x39\x38\x1f\xcb\xfd\xb5\x31\x1f\xd2\x52"
-  "\xec\x18\x16\x2f\x06\xec\x7d\xe0\x69\x34\xc6\x8c\x29\x3d\x07\xf8"
-  "\x38\x47\x22\xe5\x78\x20\xa5\x92\x9f\xe8\xa2\x34\xb7\x9d\x2f\xd9"
-  "\xef\x11\x3c\xf6\xc7\x56\xe6\xf3\x96\xc9\x2c\xf4\xef\x86\xb6\xfc"
-  "\x6a\x1d\xc6\x34\x77\xfb\x77\xeb\xd2\x09\x60\x9f\xd5\x33\xfb\x0c"
-  "\xb0\xc3\xe2\xd0\x17\xa6\xb7\xa2\xdf\x7f\xb4\xc3\x4a\x99\xbf\x52"
-  "\x71\x9e\x6c\x47\xa1\x1c\x71\xe5\xef\xde\x00\x57\x76\x17\xfa\x2a"
-  "\x57\x8c\x2b\x90\x65\x0c\xe8\x15\xad\xb8\xf1\xdf\x20\x3f\xd8\xf0"
-  "\x3d\xfa\xfb\x31\x2f\xd0\x6d\x1e\x7c\x2b\xc4\xd5\xa3\x9f\x09\xd7"
-  "\x7d\x70\xc5\xb9\x0a\xd3\xed\x70\x69\x5c\x85\x99\xf1\xae\xc2\x84"
-  "\x68\xb8\x74\x70\xc5\xc0\x15\x0b\xd7\x74\xb8\xc0\xfe\x48\x98\x09"
-  "\x77\x7c\x3f\x1b\xae\x39\x70\xcd\x85\x6b\x1e\x5c\x0b\x5c\x5b\xcd"
-  "\x5a\x11\xf0\x09\x17\xde\xa3\x5c\x85\x19\xa6\x81\x7d\x8c\x1c\x6d"
-  "\x65\x7e\xcc\x47\x9c\xa0\xe1\x18\xb3\x33\xe3\x2c\xfa\x02\x6c\x3d"
-  "\xa8\xeb\x0c\xd0\x9f\x33\x8d\xf4\x35\x87\x81\xe5\x43\xdf\xea\x09"
-  "\xb0\x3c\x9f\xf1\x6a\xc4\x48\xb3\xce\x19\x15\x57\xef\xcc\x21\xd9"
-  "\xd0\x9f\x15\x75\xc9\xcd\x24\xd1\x4e\xb2\x6a\x9a\xbb\x49\xd6\x12"
-  "\xc9\x17\x73\x06\x9e\x3b\x79\x66\x03\x62\xd8\x45\x93\xb4\x3d\x05"
-  "\xe9\x91\x2e\x75\x46\x3c\x55\x67\x98\x98\x7f\x41\x90\x3d\x18\xfb"
-  "\xa8\x77\x0c\x89\x98\x82\x71\x64\x6d\xdb\x59\xf2\xdc\x12\x2a\xd6"
-  "\xea\xc1\xe6\x68\x00\x70\x29\xc8\x2b\x88\x2f\x79\x1c\xf9\xa3\x46"
-  "\x9a\x0d\x58\x19\xed\x02\xba\x89\x38\x7e\x04\x5c\xe1\x58\x52\xc6"
-  "\x16\xe8\x32\x8d\x1c\x2f\x86\x0a\xa2\x13\xde\x29\x31\x9e\x4c\x09"
-  "\x8c\x1f\x4b\xd2\x48\x74\x09\xbc\x63\xb1\xff\xa0\xde\x8f\x1a\xc2"
-  "\xa9\xf8\x2b\x1d\x29\xfb\x25\x51\x85\x9e\xe6\xf1\x24\x5d\x40\xfb"
-  "\x5e\x7f\xe4\x05\x09\xfa\x47\x4e\x6b\xc9\x41\xdd\x71\xd0\x49\x95"
-  "\x20\xbb\x13\xf4\x3d\x20\xb7\x81\x96\xae\x80\x68\xa9\x20\x7b\x2e"
-  "\x16\x2d\x7b\xa2\xe2\x0c\x9c\x9e\xc9\x04\x69\xd6\x97\x9e\x48\xe3"
-  "\xb5\xcd\x40\x4f\xa0\xab\xf5\xb0\x8b\x84\x29\xc8\x62\x99\x9e\x2f"
-  "\x03\x3d\x81\xa6\x91\x48\x53\xa0\x07\xa3\x29\x95\x68\x5a\xe6\x41"
-  "\x53\x90\x4d\xcc\x17\x23\xd2\x54\x04\x9a\x96\xf9\xa0\x69\xef\x58"
-  "\x1c\x68\xba\xcd\x2f\x9a\x96\x5f\x00\x4d\x05\x95\x2f\x9a\x3a\x51"
-  "\x5f\x16\x25\x24\x53\x90\x77\x56\xe7\x21\xe6\x57\x14\x6c\x9d\x5d"
-  "\x60\xb3\x95\x8b\xea\x74\x3d\xd0\x44\x8d\x6b\xf5\x18\xbf\x28\xcb"
-  "\x44\xbf\xc8\x2a\xa7\xe7\x5d\x45\x99\x16\x4c\x03\xb9\xa5\xbf\x13"
-  "\x7d\xab\x19\x6c\xa4\x4c\xa0\x55\x75\xe7\x3a\x49\x8b\x62\xc4\x03"
-  "\xdd\x68\x4b\x16\x65\x52\x11\xba\x05\xca\x90\x27\xa7\x12\x65\x37"
-  "\xc8\x09\x43\x1a\xb9\xa1\x18\x64\x5d\x37\xc8\xce\x53\x0a\xa1\xf1"
-  "\x41\x83\x48\xe1\xca\x42\xff\x98\x62\x68\x46\x39\xc8\x6a\xc6\x5f"
-  "\xe4\x19\xae\x01\xd6\x3e\xf9\x3e\x94\x17\x52\xfb\x51\xb2\x93\x64"
-  "\xe9\xfb\xf3\x57\xcc\x4a\xd2\xba\x0a\x86\xee\x27\x18\x43\x2d\xa3"
-  "\x15\xf9\x5a\x49\xac\xcd\xee\x7e\x22\xa6\x73\x19\x8c\xbc\xc0\x7e"
-  "\x81\x7d\x64\x93\x87\xec\x05\xb9\xae\x29\x95\xfc\xf1\xbb\x40\xf6"
-  "\x96\xa2\xbf\x71\xe0\x25\xfa\xe9\x1f\xb0\x7f\x3c\x07\xfd\x63\x2d"
-  "\x8b\xa1\x12\x09\xf4\xa8\xec\xee\xe2\x3c\x44\x9e\x59\x9d\xd5\x8c"
-  "\x7f\xc5\x92\xac\xe7\x74\xcf\x78\x8e\xd2\x24\xe2\x82\xba\x8b\x45"
-  "\x99\x95\xb4\x4b\x3f\x06\xe7\x0b\x61\xac\x1b\x1b\xbe\x04\xec\x86"
-  "\x6f\x40\x17\xac\x04\x7c\x9d\x21\xd1\xdb\x56\x82\x2d\xd0\x85\x71"
-  "\x9b\xa0\x3e\x6b\x78\xbc\x4b\x31\x87\x26\xc3\x3b\xe6\xef\x53\x94"
-  "\xfd\x7d\x76\xe8\x70\x8c\xee\x9e\xdb\x59\xa5\x13\xdc\xdf\x7c\x33"
-  "\xdb\xa5\x3a\xce\xe3\x86\x2b\x94\xbf\xe3\x6b\xcc\x5b\xd9\x39\xfd"
-  "\x36\x85\x92\xfb\x58\xcf\x2b\x3b\x6c\x30\x93\x51\xa7\x14\xca\x4c"
-  "\xba\xf1\xf7\xd5\x06\x8c\xe1\x2b\xbf\xcb\x82\xba\xe6\x6c\x71\xdc"
-  "\x91\x4d\xb2\x5d\xf9\xff\x50\x59\x4d\xa7\xd1\xa7\x5e\x60\xb2\x57"
-  "\xa1\x64\x6b\xdb\xae\xbc\x37\x37\x00\x9d\xe2\xc5\x8d\x6f\x16\x80"
-  "\x4c\x89\xa5\xbf\x82\xb6\xfe\x12\xda\x7a\x0a\xe8\x7a\x0a\xda\x9a"
-  "\x2e\xb5\x55\x8a\x65\x25\x02\xfd\xe1\xdd\xc0\xba\x4f\x6e\xeb\xaf"
-  "\x30\x2e\xc2\x0b\xdb\x33\x4f\x93\x6b\xe8\x4d\xb8\xee\xca\xce\x2a"
-  "\x76\x59\x9d\xc7\x09\x7e\x97\xe9\xe6\x82\x84\x19\x8f\x01\x1e\x91"
-  "\xe6\x60\x0f\x6c\xa7\x61\xe9\xc5\x32\x1f\xb0\x3e\xb4\x47\x3f\xa6"
-  "\x6c\x25\xd4\x07\x69\x7f\x86\xc4\x60\x7f\x06\xda\x47\x97\x21\xfd"
-  "\xbd\xe3\xc9\x46\x30\x1e\x08\xc0\x83\x95\x12\x0f\xf2\x25\x1e\x80"
-  "\x9d\x08\x7a\x5a\x05\xfa\x37\xb2\x2c\x87\xf3\x20\x30\x1a\x8d\xe8"
-  "\x37\x27\x7d\x81\xfd\xf5\x80\xef\xfe\xaa\x3a\xdb\xcd\xc7\x86\x0a"
-  "\xf4\x3b\x4a\xc3\xcc\x21\x62\x0f\xf4\xdb\x22\xa9\xdf\x52\x7d\x9c"
-  "\xdc\x67\x5b\x14\x23\x7f\xe3\x5f\x9f\x1d\xb5\xee\xff\x68\x9f\x8d"
-  "\xb8\xb8\x7d\x56\xf5\x90\x77\x9f\x55\x65\x78\xf7\x59\xd5\x5d\xee"
-  "\x3e\x2b\xbd\x1b\x96\x3e\xab\x9a\x73\x79\xfa\xac\x6a\xce\x00\x7d"
-  "\x76\x87\x1f\x7d\x36\xd2\x47\x9f\x8d\xbc\x78\x7d\x76\xf4\xf2\x4b"
-  "\xa7\x63\xd5\x15\xdd\xc2\x00\x3a\xf6\x39\x0f\x1d\x1b\x8a\x3a\x76"
-  "\x4c\xfc\x40\xfd\xb5\xa7\x04\xfa\xab\x5a\xea\xaf\x3f\xff\x0b\x94"
-  "\x37\xf6\x07\x87\x1a\x87\xee\xaf\xce\x12\xb7\xfd\xe4\xb3\xcf\xea"
-  "\xb1\xcf\x96\x13\xab\x8d\xf5\xd9\xc5\x72\x9f\x2d\x91\xc6\x3a\x83"
-  "\xf4\xdb\x08\x5f\xfd\x16\x63\xe3\x60\x5c\x9c\x41\xfb\xad\x64\x2f"
-  "\xf5\x4c\xc6\x7e\x6b\xb9\xc2\x74\xad\x5a\xe1\xdd\x6f\xd5\xd3\xbd"
-  "\xfb\xed\xd8\xaf\xdd\xfd\x56\x7a\x37\x2c\xfd\x56\x4d\x2e\x4f\xbf"
-  "\x55\x93\xef\x8e\xae\x0d\x8d\xbe\x74\xba\x56\xb3\x8c\xf5\x5b\x5f"
-  "\xba\x36\x4b\xd2\xb5\xa1\xa8\x6b\x43\x5d\xfe\xf5\xdd\xb0\xb3\xff"
-  "\xc7\xfb\xee\x45\xd6\xb9\xe1\xef\x78\xf7\xdd\x70\xbb\x77\xdf\x0d"
-  "\x7f\xcd\xdd\x77\xa5\x77\xc3\xd2\x77\xc3\xf7\x5e\x9e\xbe\x1b\xbe"
-  "\xf7\xbb\xa3\x73\x35\x36\x5f\x7d\x57\x3b\x85\x64\x37\x29\xc6\xfd"
-  "\xc0\x5a\xc2\xf6\xc6\x65\x5b\x9d\xf7\x12\xb6\x9f\x44\x31\x6e\xb1"
-  "\x35\x72\x06\x11\x37\xee\xb6\x63\x5c\x0d\xdc\xd7\xf2\x5b\x8f\x7d"
-  "\x23\x6c\xfd\x55\x31\x6e\x9d\xbc\xef\x65\x9b\x14\x7b\x63\xb0\x7d"
-  "\x2f\x34\x6f\x77\xb6\xf4\xbf\xbd\x1c\x1b\xbb\x37\xc8\xcf\xcc\x07"
-  "\x8c\x62\x9c\x85\xe6\xef\xce\xb0\x8f\xde\x9d\xe1\x6b\x8d\x24\x6c"
-  "\x1d\xa5\xb8\xd7\xa3\x63\x4a\x9c\xbd\x63\x23\x21\xc5\xb8\xfe\x90"
-  "\x3b\xce\x01\xff\xd5\xf2\x3d\x0e\xed\xb6\x8e\x9c\x79\xa4\x2b\x77"
-  "\xbc\x5a\x4e\x63\x71\x6a\x73\x42\xa8\x08\xef\x68\xd1\xac\x9a\x6d"
-  "\x66\xa2\x42\xbf\xc2\x77\x9c\x43\x2c\x8e\x8f\x02\x19\xc1\xf6\x71"
-  "\xb0\x35\xf7\xeb\xae\xef\x2c\x6b\x27\xca\xba\x0d\x6c\x3f\x1b\xee"
-  "\x97\xd9\x5e\x84\xf8\x0f\xb9\x6d\x0b\x15\x94\x44\x2c\x8d\x6b\xa0"
-  "\xa1\x19\x95\x6c\x7f\x2f\x60\x45\xde\x43\x83\x31\xb7\xc4\xc9\x71"
-  "\x26\xd9\xb7\x2d\x85\xfa\xbd\x6b\xc6\x73\xa0\x21\xb4\x2c\x85\x68"
-  "\xe0\x52\xd3\xc2\x8c\x4a\xa8\xd7\x0e\x79\xee\xd0\xe7\x5e\x6d\x8c"
-  "\xb5\x79\x7d\xa4\x52\xda\xaf\x83\x3e\x01\xd8\x99\xaf\x4d\x82\x98"
-  "\xe7\x82\x74\x9a\x93\x45\xad\x26\x27\x09\x07\x5a\xe0\x7a\x3b\xc8"
-  "\x29\x41\x2c\x8b\xb3\xaf\x9f\x44\xc8\xee\xb5\xad\x02\xee\xbd\x70"
-  "\xbd\x78\x7d\xa7\xc5\xfc\x7d\x5c\x8f\x67\x3e\xe1\x5b\x14\xd7\xbc"
-  "\x92\xf8\x35\x8f\xab\x09\xbf\x2b\x70\xdd\xe1\x11\x78\xc6\xf5\x6c"
-  "\xb1\x23\x52\x89\x79\x21\xfd\x67\x96\xb4\xcf\x48\xb8\x81\xed\x81"
-  "\x57\x49\x79\x75\x98\xd7\xa6\xb8\x86\xed\x3b\x85\xe7\x99\x38\x57"
-  "\x8e\xfb\xe4\xd9\x79\x8a\x92\xb8\x06\x26\x1f\x0a\x32\x2a\xa1\xfd"
-  "\x7c\x3f\x2d\xb4\x73\x13\xb4\x19\xf2\xa8\x71\x1f\x0d\xbb\x9b\x89"
-  "\x66\x33\xa4\x61\x39\x70\x57\xb3\xbd\xbc\x8a\x6b\x22\xb1\x6c\x9f"
-  "\x67\x00\xd4\x19\x95\x14\xb0\xcd\xcf\xc4\x28\x3e\x6e\x52\x44\xcc"
-  "\x0d\x57\x50\x0a\xdf\x34\xad\xc7\x39\x6c\xdc\x77\x8d\x7b\xc9\x15"
-  "\x11\xb7\x40\xf9\x4a\xa4\x45\x57\x6e\x84\xd2\xa6\x18\x5f\xd9\xbb"
-  "\x77\x00\xd7\x59\x14\x11\x0b\xf1\x3b\xf8\x1f\x9e\xff\x1a\xb6\x3f"
-  "\x1f\xeb\xac\x35\x87\x50\x78\xff\x20\xdf\x9b\xad\x5a\x0c\xff\x77"
-  "\xc7\x7f\xe1\xff\x03\x2c\x45\x24\x01\xcf\xd8\xfe\x68\x7c\xf6\xb9"
-  "\x57\x58\xe2\x5b\x6d\x24\x60\xa3\x2f\xef\x64\x8c\x00\x2e\x64\x8c"
-  "\x60\x7d\x5f\x37\xdb\x04\xa6\x8f\x14\x11\x6c\x2f\x50\x11\xf0\xd0"
-  "\xf5\x72\xa4\x92\xcd\x4b\xf7\x20\x5f\x9a\xe0\xdd\xb5\xa5\xc8\x97"
-  "\x4d\xa0\x0b\xa4\xbc\x16\x77\xfd\xf1\xf9\x5a\xc6\x4f\x11\x78\xc1"
-  "\xf6\x22\x29\xae\x7d\x96\xc5\xdf\x01\x99\x81\x7b\xc8\x0f\x98\x08"
-  "\xae\x7f\x36\x50\xc0\xc8\xee\x14\x87\x50\x96\xc6\xd3\xdf\x6d\x77"
-  "\x08\x9b\x4e\x11\x94\x2d\xa4\xf0\x97\x44\x09\x7a\x48\x89\x65\xd2"
-  "\xa8\x38\x76\xae\x81\xf1\x71\x2d\xf0\x2e\x0d\xb0\x0b\x34\xdf\x04"
-  "\xf4\x2b\xeb\x66\xeb\x34\xa6\x32\x91\xa8\x45\xc8\x67\x53\x5c\xbb"
-  "\x0b\xca\xd3\x60\xcc\x3f\xdc\xeb\x0c\x34\x4c\xed\xca\xbd\x36\x4f"
-  "\xa6\x21\xd6\x09\xf7\x2a\x63\xec\x3f\xc8\xab\xe4\x18\x8a\x38\x2c"
-  "\xb7\xd9\x17\x3d\x0b\x77\x93\xa8\xc2\x3b\xc8\x0c\x51\x75\xb4\x95"
-  "\x86\x5c\xbf\x1d\xe7\x9b\x1f\x45\xcf\x40\x86\x56\x92\xf8\xfc\x09"
-  "\x6a\xb5\xbb\x88\x38\xfa\x68\x2b\xae\x41\xb8\xd6\xdf\x36\x3e\x71"
-  "\x0d\xd0\x0b\xf4\x7d\x96\x83\x68\xac\x66\x3b\x8f\xdf\x45\xbe\x25"
-  "\xae\xd5\x20\xc3\x41\xae\x83\x4e\x55\x66\x7d\x4b\x26\x22\xbd\xc4"
-  "\xd0\xf4\xc8\x16\xc5\x84\x27\x1e\x33\x92\xec\xc0\xe4\xe8\x04\xe6"
-  "\x4f\x16\xed\x0b\x90\xf9\x02\x8b\x6b\x6d\x07\xfb\xa4\x30\x3d\x32"
-  "\xc0\x72\x7c\xc6\x15\xc2\x76\x8b\x38\x0f\x2d\xb5\x39\x11\xdb\xdc"
-  "\xe9\x20\x38\x97\xff\xe8\xb3\xe8\x9b\xf8\x2c\x11\xf3\x8f\xb6\x62"
-  "\x9b\xc1\xd6\xd9\x12\xf0\x9c\xbe\x62\x82\xcf\xf8\xa7\xf8\x6d\x0a"
-  "\xf4\x16\xd7\x5f\xbf\x5d\x54\x67\x6c\xc1\x6f\x63\x1d\xf0\xfc\xcd"
-  "\xa3\x67\x09\xa3\x3b\xd2\xdf\xea\x70\x11\x3a\xda\xb3\x0e\xce\x00"
-  "\xeb\x70\x9d\xef\xf6\xdf\x41\xa2\x0a\x76\x73\xbe\xbb\xd6\x4b\x34"
-  "\xd0\xe3\x1a\x58\xc6\x96\x3a\x83\x9d\x3c\x8a\x75\xb0\x9f\x26\x8f"
-  "\x9c\x26\x8c\xff\x56\x5d\x1b\x71\x85\xdc\x36\x1e\xf7\x12\x20\xff"
-  "\xcd\x4e\xe0\xff\x39\x07\xfa\x33\xb2\x5b\xb3\xcf\x13\xb4\x5f\x9c"
-  "\x1d\x3a\xa1\x3f\xff\x23\x9f\x78\xcc\x14\x28\xff\x23\x87\x89\xff"
-  "\x91\x57\x40\xfb\x27\x06\xd1\xfe\x89\xc3\xd4\xfe\x89\x57\x40\xfb"
-  "\x27\x05\xd1\xfe\x49\xc3\xd4\xfe\x49\x3e\xdb\x9f\x30\x51\xa4\x6c"
-  "\x8f\x49\xd8\xea\x6c\xd4\x01\x5c\x5f\x5d\xff\x18\xee\x21\x61\xe7"
-  "\xad\xa4\x67\xc2\xcf\x5f\xa9\xfa\x3c\xab\xfb\x3c\x6b\xfa\x3c\x47"
-  "\xf4\x79\x8e\xec\xf3\x1c\x25\x3f\x83\x1e\x19\x71\x46\x31\xe9\x20"
-  "\xd8\xa5\xd9\x36\xc5\xf5\xc9\xd2\xfb\x68\xf4\xf7\x05\x3a\x3d\x7a"
-  "\x90\x38\x84\xd7\x9f\x52\x5c\xcf\xce\xbd\xd3\xf5\x93\x74\x74\x6d"
-  "\x36\x11\x0b\x12\x66\x3f\x9a\x09\xb2\x0b\xf8\x47\x7b\x22\x47\x82"
-  "\x8d\x70\x1d\xfa\x94\xc3\x3d\x07\xda\x94\xf7\x68\x93\xe2\xfa\xb7"
-  "\xb1\x7d\x77\x18\x2c\x44\x0c\xb9\x8d\xad\xe5\x8b\x85\x09\xb3\xed"
-  "\x21\xb7\x4d\xa2\x5b\xcd\xda\x22\x41\x54\x15\xe5\x88\xda\x4c\x3b"
-  "\xb5\xcf\xfd\x16\xe4\xd0\x59\xf4\xd3\x0e\x3c\x36\x52\xbb\x25\xe5"
-  "\x34\xd4\x37\xea\xc6\xda\x0c\x28\x1b\xbe\x03\xdf\x82\x71\x5c\x42"
-  "\x34\x8b\x61\x0c\x65\xd4\x75\x56\x13\x8c\x11\x23\x95\x19\x4f\x43"
-  "\x13\xa2\xb1\xcc\x01\xed\xd3\x82\xd5\x7b\xe0\x9b\xf7\x3e\xa6\x53"
-  "\x12\xba\x4e\x19\x11\x18\x4f\xa3\x66\xfb\xb4\x7b\x0b\x8c\xd3\x79"
-  "\xb9\xaa\x60\xca\xf5\xe9\xff\x02\xca\x95\xea\xab\x09\xa6\x5c\xdf"
-  "\x67\x14\x0b\x52\xa5\xfa\x6a\x83\x28\x77\xf2\xdc\x41\xca\x95\xea"
-  "\x1b\x1f\x4c\xb9\x3e\xe3\x5f\xd2\x82\x34\xa9\xbe\xd9\xc1\x94\xeb"
-  "\xf4\x5d\xee\xea\x3d\xc1\x61\x61\x8a\xef\xf8\xdf\x80\x85\xe0\x70"
-  "\x30\x65\x90\xf6\x1b\xf7\x04\x87\x81\x29\x8e\xc1\x30\x10\x1c\xff"
-  "\x6f\x18\x94\xff\xc1\xf1\xfe\x86\xed\x83\xf1\x3e\x38\xbe\xdf\xe0"
-  "\x13\xff\x68\xcb\x03\xef\x0d\x34\xcc\xac\x11\x8b\x12\x0c\x62\xd8"
-  "\xea\x94\xf5\x62\x3c\x49\x00\x19\x16\xbe\x85\x8c\x8b\x67\xe3\x63"
-  "\x6d\x5e\x66\x09\x11\x60\xbc\x2b\x54\xac\x6d\x10\xac\xce\x19\xa8"
-  "\x73\x5c\x3b\xd2\x1c\x8a\x9b\x21\x7d\x1f\xe8\xac\x4e\xb0\x3b\x79"
-  "\x39\x09\x86\x22\x73\x3c\x91\x7c\x5a\x74\xa2\x6f\xd3\x44\x90\x63"
-  "\xd6\x2d\x0e\xdc\xb3\x32\x0e\xfe\xe7\x04\xfc\x42\x19\x0e\xf2\xba"
-  "\x68\x57\xc4\xa7\xb0\x7c\x76\x76\x6e\xae\x68\x75\x0a\xcd\xd2\xa1"
-  "\x6f\x43\x3b\x7c\xf3\xdb\x10\x3b\x11\xd0\x07\x51\x57\xae\xb6\xcd"
-  "\xa6\xb8\xb1\x51\x3a\x27\xda\xc6\x7c\x72\x42\x7d\xf1\x0c\x26\xe6"
-  "\x45\xdf\x9c\x77\x18\x88\x80\xfe\xce\xbb\x72\x6f\x8c\x44\x3f\x9d"
-  "\x83\x9d\xb7\x76\x15\x64\x2c\xc0\xff\xd3\x02\xd0\xa1\xa7\x89\x80"
-  "\x67\x2c\x61\x1c\x50\x5f\x04\x63\x88\x07\xa7\xe2\x9c\x47\x3b\x31"
-  "\xe3\x34\x7a\x41\x82\x9e\xaa\xd3\x55\xb8\x2f\x8e\xed\xf1\x56\xdc"
-  "\xb8\xa7\x8c\xef\xf9\x76\xb0\x38\xb0\xf0\xcc\xc6\x31\xb8\x2f\x46"
-  "\x3d\xcb\x41\x8b\x42\xe3\xeb\x3a\xdb\x59\x7c\x9e\x26\xc5\x8d\x6f"
-  "\xa1\x7f\xc4\x0e\x75\xc6\xbc\x4e\x75\x46\x12\xd4\xab\x52\x6e\x03"
-  "\x7e\x5f\x4e\xc7\x71\x1b\xe6\x83\xf7\xf5\xf2\xf9\xeb\x81\xfd\x18"
-  "\x4c\x1a\x9f\x18\x49\xed\xbd\x7e\x2f\x14\x37\xdf\x8d\xb4\x07\x5b"
-  "\x61\x4e\x67\x96\x6e\x0a\x9f\xc7\xb8\x69\x21\x8e\x87\xa1\xde\xd3"
-  "\xf9\xd8\x34\x61\x3a\xf3\x77\x0b\x3a\xe0\x31\x9d\x10\xa0\xdd\x7a"
-  "\x13\xd3\xff\x96\x29\xa8\x23\x6f\x9e\x0c\xe5\xff\xb0\x49\x71\x53"
-  "\x36\x1f\x8b\x25\xcc\x61\xe7\x0e\x15\x37\x45\xc1\x37\xe6\xd0\x82"
-  "\x59\x76\xcc\x07\xef\xb7\x4b\xef\xe7\x79\xbc\x9f\x87\xfb\x24\xa5"
-  "\xf7\xd2\x58\x2e\x61\x81\xc7\xfb\x05\x86\x29\x38\x37\x71\x53\x2b"
-  "\xb6\x01\xf4\x59\x2c\xea\xb6\x5e\x3f\x1e\xa1\x09\xb1\x52\xbe\xd9"
-  "\x6d\x8a\x9b\x15\x1d\x80\x2d\x78\x3f\xd7\xe3\xff\x73\xf7\x9b\x62"
-  "\x49\x42\x29\xd2\xf0\xe6\x08\x9b\x90\xc1\x7d\x45\x28\x6e\xd2\xb2"
-  "\xb6\xab\x13\x74\x9e\xe5\x41\xba\x0d\xca\xd4\x75\x82\x1d\x05\xbf"
-  "\xd9\x79\x27\x4f\x7a\xcb\xa7\x1f\xb5\x4b\x56\x2c\xd6\x3e\xbd\x2a"
-  "\x75\x25\x9e\x5e\xf3\x8e\x1b\xaf\xc1\xf3\x9d\x62\x81\x69\x86\x75"
-  "\x0b\x9e\x37\xd3\xb0\x73\xda\x9b\x81\x8f\xce\xa2\x4c\x83\x2b\x2c"
-  "\x93\xb8\x8a\xd2\xd1\x3f\x8c\x60\x8e\xa4\x5f\x58\xd6\xce\x22\x67"
-  "\x14\x37\x57\xb0\x58\x98\x5a\xe6\xdb\xb9\xd3\xb2\xf6\x7d\x4c\x3b"
-  "\x88\xb4\xb0\x26\xf3\xb4\x37\xcd\xd5\xc2\x7b\xe6\x06\xa1\x26\xb9"
-  "\x9d\xec\x8f\xb4\x93\x03\xda\x76\x52\x82\xe9\x62\xbd\x80\xfb\x46"
-  "\xcf\x28\xa2\xaf\xc5\x6f\xe1\x18\x1f\x7f\xf3\xf9\x8a\x9b\xb7\xe2"
-  "\x77\xd0\x77\x06\xd0\xa6\x14\xbf\x67\x83\x1e\x19\x52\xc2\xf6\x19"
-  "\xab\x21\xdf\xcf\xc4\x42\xd3\x0c\xd6\xc7\x73\x6f\x9e\xeb\x14\xd4"
-  "\xbf\x97\xce\xb3\x31\x5f\xfd\x5d\xb9\xd1\xb3\x3d\xce\x6e\xaa\x3b"
-  "\x04\x72\x3f\xa4\x25\xc9\x67\x0b\x30\x56\x98\x2f\x99\x71\x1e\xc6"
-  "\xb2\xe7\x4b\xe2\x92\x44\xb5\x09\xe8\x6b\x9a\x51\x5d\x4d\x70\x2e"
-  "\x45\x81\x7b\x60\xdb\x14\xb7\xce\xa0\xa1\x26\x9d\x19\xfb\x29\xd0"
-  "\xe2\x7f\x70\x1f\x5f\x58\xa6\x61\x17\xee\xdb\x2b\xca\x24\x7f\x4c"
-  "\x73\x08\x87\x6a\xaa\x88\xf6\x3f\xd1\x1e\x8a\xfe\xf0\x47\x4b\xa8"
-  "\xf3\xb6\xc3\x16\x52\xd3\xfc\x27\xf2\x51\x63\x35\x51\x2f\x24\x21"
-  "\x59\x36\xea\x62\xe3\x7d\x23\x11\x12\x6d\x24\xc4\x7c\x16\xfb\xa9"
-  "\x8b\xc5\xea\xae\x73\xd4\x82\x8d\xf3\xcc\x86\x0a\x73\xeb\x08\xed"
-  "\x7c\x42\xa0\x3f\xb1\x75\x63\x76\xce\xc6\xce\xce\x23\x87\xe2\x1c"
-  "\xb6\xc7\xf9\x9a\xe4\xcc\xd3\x44\x55\xab\x3f\x4e\x32\x92\xa9\xe8"
-  "\x4a\xd7\x8d\x4f\x4c\x0e\xa1\xec\x8c\x8d\x09\x32\x1b\x80\xa7\xe9"
-  "\xba\xb0\x97\xd2\x48\x44\x9d\xd1\x46\xac\xad\xd5\xe4\xe5\x14\x12"
-  "\x41\xbb\xf4\xa3\x6b\x6a\x0e\x11\xba\xf1\x98\xed\x75\xb3\x65\x84"
-  "\xbc\x67\x2a\x7c\x9d\x02\xe7\x2c\xc3\x0a\x70\xef\xd4\x39\x12\xbb"
-  "\xe8\x64\x36\x9b\x67\xc5\x39\x6d\x67\x97\x4e\xdb\xd3\xa5\xbb\xa9"
-  "\xbb\x4b\x37\x45\x9e\x0b\x7f\x62\x99\x86\x94\xe2\xd9\x9c\xdc\xeb"
-  "\xa6\xe3\x5e\x3d\xb4\xed\x9d\xa3\x8f\xb7\xe2\xbc\x37\xe2\x12\xbe"
-  "\x1d\x25\x3e\xad\x23\x77\xda\xd9\xd9\x1f\x9c\x8b\xd7\x94\x3d\x05"
-  "\xf5\x6d\x6b\x27\x9e\xfb\x7f\xce\xa7\xeb\x04\xdc\xfb\x43\x73\xa3"
-  "\x0d\xdd\xa5\x71\x49\xb8\x07\x08\x74\xc1\xf4\xc0\xfb\xf6\xad\x6c"
-  "\x6e\x02\xdb\x0f\xfc\x30\xec\x6a\x47\xfe\x00\x9f\xda\xed\x02\xf2"
-  "\xa2\x76\x09\xf2\xa1\xde\x8b\x0f\x8c\x6f\x29\x0e\x01\xf9\x81\xbc"
-  "\x40\x9e\xb8\xf9\x71\x84\xf1\x63\x97\xc8\xf9\xd1\x0d\x7a\x40\xe6"
-  "\xc9\xf9\xa8\x38\xfd\x60\x7c\x41\x7e\x20\x6f\x6a\x9a\x8f\x13\x2f"
-  "\x9e\xd8\x39\x4f\x80\x9e\xe3\x65\xbe\x20\x4f\xac\x6d\x60\xeb\x02"
-  "\x5f\x1e\x3e\x42\xc8\x8f\xa6\x52\xb1\x76\xee\x27\xbd\xfc\x71\xfa"
-  "\xe2\xcf\xd7\x6e\xfe\x00\xef\xfb\xf3\xe7\xb4\x06\xd7\x66\x90\x3f"
-  "\x55\x81\xf0\xa7\xa6\x99\xf3\xc7\x29\xf1\x67\xea\x1c\x22\x38\xba"
-  "\x74\xc2\xd6\x34\x32\x63\xee\x49\x2d\x39\x98\x54\x4b\x80\xd6\x44"
-  "\x2c\xcc\x98\x13\x5c\x3f\x9a\x9a\xed\x7f\x3f\xd2\x8d\xbb\xda\x8f"
-  "\x02\xed\x47\xdf\xab\xba\xb0\x7e\x34\x75\xee\xd5\x7e\x74\xa9\xfa"
-  "\xd1\xd4\x39\x7d\xfb\x51\xaf\xae\x4e\x59\xba\x62\xf1\xb2\x95\x78"
-  "\x7c\xef\xa9\x35\xc6\xa5\xab\xb9\xc6\xf6\xd2\xd9\x91\x2e\x73\xbc"
-  "\x80\x3e\xd7\x6a\xb6\xd4\x93\xd7\x27\xd5\x0b\xae\xaf\x22\x95\x34"
-  "\xcf\x1e\x2b\xe6\xb5\x57\xa1\xef\x4c\xec\x6f\x18\xfb\xbd\x45\x71"
-  "\xe7\xde\xba\x28\x1e\x77\x12\x7f\x33\x7b\x25\x2a\xae\x15\xd7\x48"
-  "\xd6\x77\xc3\xb5\x96\x28\xc3\x1d\x44\x65\x99\xc2\xde\x4f\x44\x5f"
-  "\x82\xb4\x34\xae\xb5\x0c\x63\xb2\x77\x13\x65\xa7\x7a\x96\x7d\x03"
-  "\x94\x67\x0f\x35\xcd\x50\x6a\x89\xd0\x95\x7b\x7b\x39\xe8\xe4\x25"
-  "\xbd\x3e\x86\x14\x77\x34\xd2\x91\xb7\x39\xb0\xaf\xe3\x99\xb3\x33"
-  "\x8a\xdb\x8f\x9f\xcf\x21\x2c\x7e\xfc\x63\x53\xe1\x5b\x93\xe3\xf4"
-  "\xcc\xe7\x00\xf4\x7b\xfe\x7e\x1a\x5b\x77\xea\x51\xa7\xb3\x38\xc8"
-  "\x1d\xea\x4c\x43\x47\x41\x26\x39\x94\x51\x49\xb4\xf3\xb1\xdf\xc7"
-  "\x8c\x7e\x78\x0b\xf4\xfb\x79\x16\x52\x1b\xf9\x47\xf2\x51\x12\xe0"
-  "\x2d\x69\xa8\x7e\xef\x81\xb3\x29\xfe\xf5\x7b\x19\x5f\x88\x2b\xc4"
-  "\x17\x62\x6b\x2c\x60\x0b\xf1\x26\xe3\xeb\xb7\xe7\x38\xbe\xc2\x1b"
-  "\x89\xe6\xa5\x76\xc0\x98\x93\x63\x0c\xcf\xfc\xd6\x9a\x3e\xf1\xdd"
-  "\xff\xcf\xf5\xc1\x97\x20\xe1\x2b\x1d\xf0\x95\xee\xc6\xd7\xe3\xc7"
-  "\x35\xe4\x65\x86\xaf\x09\x6e\x7c\xe5\x1f\x6f\x95\xb1\x85\x38\x43"
-  "\x4c\x89\xbf\xd0\x11\xec\xf3\x32\xce\xca\x9e\xe1\xeb\x9c\xac\xff"
-  "\x0b\xd0\xff\xbb\x3c\xf4\xe8\xe4\x0b\xe9\xff\xd3\x58\xff\x47\x9e"
-  "\x20\x7f\x90\x2f\xc8\x8b\x7f\x45\x3e\xa0\xdf\x57\xda\x35\x10\x2f"
-  "\xae\xb5\x0c\xc5\x0b\xe4\x03\xf2\x83\xf1\x01\xf8\x21\xaf\x39\xe3"
-  "\x1a\x24\xf2\x04\x79\x71\x47\x06\x11\x90\x2f\x65\xd0\xe7\xb1\x9f"
-  "\x03\x6d\xe7\x20\x5f\x98\xed\x9a\x13\xba\x72\x33\x9e\x9b\x95\x62"
-  "\xe4\x76\xe5\xde\xe1\xec\x6f\xb7\xde\xa9\xe9\xf5\xf5\xa8\xb8\x9d"
-  "\x8d\xcb\x2c\x93\xee\x85\xfe\x76\xbb\x34\x66\x49\xe7\xbe\xd6\x14"
-  "\xb1\x2b\xa4\x3e\x5d\x8f\xe3\x3f\x36\xd6\x73\xc1\x58\x4f\x0d\x63"
-  "\xbd\x02\x18\xeb\x99\x5a\xb9\x5f\x00\xc5\x9d\xcb\x88\x74\x9e\x97"
-  "\x86\xa6\xab\x68\xe1\x2c\x07\xd2\x8f\xad\x9b\x86\x66\xcc\xc3\x75"
-  "\x1e\x5a\x08\xe3\xc8\x57\x05\x02\xcf\x80\x21\x57\x80\xd8\xb9\x33"
-  "\x4f\x5a\x17\xce\x30\xac\xc5\x3d\x03\xb1\x3c\x1e\x92\xe2\xf6\xc5"
-  "\x98\xce\xd6\xd4\x04\x71\xbb\x6b\xbd\xf7\x9a\x9a\xe7\x9a\xeb\xeb"
-  "\x66\xbb\xb4\x9e\x16\xcb\x7d\x82\xe1\xb9\x0d\x90\x6b\x15\xe6\x7a"
-  "\xc1\xbd\xa6\xf6\x09\xbe\x7f\xc0\x7b\x4d\x2d\x96\xf9\x00\xb1\x29"
-  "\x62\x97\xe3\x3e\x12\x78\xd6\xf1\xf4\xdb\x93\x3d\xd3\xdd\x6b\xd6"
-  "\x3c\x5d\x14\x58\xbc\x11\x1c\x73\xb7\xf1\xb1\x76\xec\x06\x79\x4c"
-  "\xeb\xc3\xbe\x09\x40\xee\xde\x3d\xc7\x2d\x77\xef\x66\x7b\x0b\x69"
-  "\xa4\x39\xb2\xb6\x9f\xdc\xfd\x0c\xde\x4f\x7f\xed\x51\x94\xbb\x05"
-  "\xe9\x1a\x5e\xbf\xbb\x30\x9e\x6b\x08\xc6\x7b\xc4\x74\x3c\xbf\x83"
-  "\xf2\xb7\x14\xcf\xb6\x30\x99\x6c\x56\x6d\x60\x6b\xe7\x77\x4d\xf7"
-  "\x96\xc5\xd3\xf5\xde\xb2\xf8\xae\x65\x83\xcb\xe2\xff\x17\x3a\xb8"
-  "\x2c\xbe\xeb\x77\x57\x65\x71\xb0\xb2\x18\x6c\xb1\x0b\x92\xc5\xdf"
-  "\x6f\xb8\x2a\x8b\x2f\x96\x2c\xfe\xfe\x61\x0f\x59\xfc\x33\x6f\x59"
-  "\x3c\x3d\xaf\xbf\x2c\x9e\x5e\xe2\x96\xc5\x77\xc5\xbb\x65\x71\xac"
-  "\xc3\x5b\x16\xdf\x7d\xde\x3f\x59\x3c\xfd\xec\xc5\x95\xc5\x77\x47"
-  "\x78\xcb\xe2\xbb\x9b\x25\x5d\x71\x2c\x70\x59\x7c\xf7\xc1\xc1\x65"
-  "\xf1\xdd\xb5\xde\xb2\xf8\xee\xed\x5c\xe6\xde\xed\xe0\xb2\xf8\xee"
-  "\x3d\x92\x8c\x6e\xf0\x4c\x77\xcb\x62\x9e\xde\x5f\x16\xdf\xa3\x19"
-  "\x42\x16\xeb\x5c\xa2\x2c\x8b\x1b\x40\x16\x37\x08\xe2\x2f\x7c\xc9"
-  "\xe2\x1f\xc6\xd7\xa2\x2c\x4e\x41\x59\xfc\xc3\xf8\xc1\x65\xf1\x0f"
-  "\xa7\xa1\xcc\x05\xbc\x92\x12\xf4\xeb\x0b\xf8\xb3\x3c\xf3\x19\xce"
-  "\xe9\x36\x23\x3e\x5b\x14\xf7\x3e\xff\x68\x86\xa7\xac\xbe\xe7\x9d"
-  "\x5e\x59\x0d\xe9\xe2\x44\x6f\x59\x8d\x72\x1a\xe5\x75\xe9\x0b\xd4"
-  "\x56\xf6\x02\x6d\x84\x76\xb5\xca\x32\xbb\x10\xd2\x30\xe6\x0f\xfa"
-  "\xeb\x29\x3d\xc7\x2e\x25\xd0\xa0\x79\x3d\x7c\x17\xff\xd3\x95\xfb"
-  "\x6f\x11\xde\xf2\xfd\xde\x39\xce\x5c\x4f\xf9\xfe\x6f\x0f\xa1\x7c"
-  "\x2f\xe0\x67\xb6\x99\x5c\x77\x96\xc6\xe9\x51\xd6\xf3\xf7\x33\x4e"
-  "\x0f\x2e\xdf\xff\x2d\xf5\x72\xc9\x77\x94\x29\x63\x3d\xc6\x72\xbe"
-  "\xe4\x0a\xb4\xad\xb3\x76\xc9\xa5\x91\xef\x28\x4f\x50\x8e\xa0\x6c"
-  "\x91\xe5\x3b\xca\x16\xa7\x34\xd6\x2e\xc9\xf1\x90\xef\x23\x3d\xe4"
-  "\xbb\x22\x18\xf9\x3e\xa3\xea\x3b\x25\xdf\x91\x0f\x19\x17\x57\xbe"
-  "\xcb\xe3\x6a\xe4\x03\xf2\x04\x79\xe1\x39\xb6\x46\x3e\x20\x3f\x90"
-  "\x0f\x68\xd3\xc8\xf2\x7d\x9a\x89\xcb\xf7\xd2\x5e\xf9\x3e\x63\x4f"
-  "\xaf\x7c\x17\xb8\x7c\x2f\x41\x3f\x68\x6c\x8e\xf8\x5e\x7d\x7f\xf9"
-  "\x7e\x6f\x86\x5b\xbe\xff\x9b\x56\x92\x77\xcd\xe8\x5b\x00\xfa\xf7"
-  "\x0e\x6f\x19\xff\xc3\x6f\xfd\x93\xf1\xf7\x1e\xeb\x27\xe3\x81\x86"
-  "\x05\x7c\x6d\x08\xe5\xfb\x3c\x94\xef\x4e\x94\xf3\x41\xc9\xf8\x7b"
-  "\x1d\x6e\x3d\x74\xcf\x06\x2e\x5b\xef\xdd\xec\x2d\xf7\x7f\xd8\x28"
-  "\xc9\xa8\xa5\x9e\x72\x5f\x0c\xf1\x47\xee\xff\xf0\x1d\x59\xee\xa3"
-  "\x5c\xad\x10\x1b\x3c\xe4\x3e\x93\x93\x07\x2d\x69\x4d\x1e\x72\xff"
-  "\x87\x5b\x78\x1d\x7e\x68\x77\x31\xb9\xff\xc3\x5d\x3c\xfd\x9e\x25"
-  "\x9e\xe9\x6e\xb9\xcf\xd3\x5d\x9e\x72\xbf\x15\xe5\xfe\x4c\xd5\x10"
-  "\x72\x7f\xba\xff\x72\xff\x81\x4a\xb7\xdc\x7f\xa0\x72\x70\xb9\xff"
-  "\x40\x29\xca\x7d\xe6\xff\x15\x78\x0f\x78\x56\x16\x4d\xe0\x32\x1f"
-  "\xe7\x44\x40\x17\xd8\xd0\xa7\x05\xe4\xcb\x67\xfe\xde\xe1\x82\xf7"
-  "\xad\x05\xf8\x5b\x64\xff\x69\x0c\xb7\x13\x15\xea\x80\x82\x16\xa2"
-  "\xc4\xd8\x69\x9c\x4e\xf1\x27\x4b\x30\x1e\x67\xaf\xbe\x98\x79\xda"
-  "\x4f\x7d\x71\x18\xf4\x45\x7d\x57\xee\x7d\x91\x1e\xfa\x02\xe3\xcf"
-  "\xd5\xf7\xd1\x17\x36\xd0\x17\xcd\xf2\x7f\x20\xff\x1c\xcf\xfc\x58"
-  "\x3f\x96\xbf\x85\x5d\x98\xbf\x01\xf2\x37\x72\xfd\x72\x9f\xd1\x5b"
-  "\xbf\xc4\x97\x8b\x5e\xe3\x87\xfb\xfe\x20\xeb\x17\xd4\xcf\x62\x3f"
-  "\xfd\x72\xff\x23\xbd\xfa\x65\x82\x87\x7e\x31\xc9\xfa\xe5\xbe\x23"
-  "\x57\xfc\xf8\xe1\x02\xe4\x5a\xb0\xfa\x05\x65\x1a\xca\xb3\xc1\xf4"
-  "\x8b\xe8\xa1\x5f\xc4\xa0\xf4\xcb\xfd\x91\xdf\x29\xfd\x72\x09\xc6"
-  "\x0f\x9e\x3c\x40\xbe\x30\xdd\x02\xbc\x41\x3e\x20\x0f\x90\xfe\xe8"
-  "\x6b\x1a\x79\x83\x7c\x41\x9e\x4c\x33\xb8\x75\x0b\xe3\x0b\xd3\x2f"
-  "\xf7\x47\xf4\xd5\x2f\x65\xe3\x65\xfd\x12\x5f\xdd\x5f\xbf\xc4\x37"
-  "\xba\xf5\xcb\x7d\x6c\xfe\x86\xf9\xd7\x53\xcc\x3c\xec\xad\x5b\x66"
-  "\x2d\xf6\x4f\xb7\x3c\x70\xf7\x00\xba\x85\xf9\x31\x2e\x78\xc1\x6b"
-  "\xec\x30\x0f\xf4\x4b\x10\xba\xe5\x81\x05\xbc\x8e\xb8\x7f\x79\xe6"
-  "\x0e\x2e\xbf\xe3\xed\x6e\x7d\x33\x33\xc3\x33\xcd\xad\x6f\x66\xcd"
-  "\x95\x64\xdc\x13\x81\xeb\x9b\x59\x2c\x46\x0d\xee\x6d\xae\x68\xe7"
-  "\x32\xdd\x5b\xdf\xcc\xba\xdb\x5b\xdf\xcc\xe2\xb1\x95\x15\xb3\x92"
-  "\xb9\xbe\x99\x15\xc5\xd3\x67\x2e\xf4\x4c\x77\xeb\x1b\x9e\xde\x5f"
-  "\xdf\xcc\x32\x0d\xa1\x6f\xd4\x3d\x51\x71\xfa\x9e\x82\xcc\x79\xce"
-  "\x1d\x71\xf6\x98\xa4\xfb\x5d\x7d\xfb\x0d\xef\x2f\x2e\x82\xfd\xa7"
-  "\x77\xfd\xe9\x49\xbe\xde\x21\x4a\x67\x80\xbb\xa3\xe2\x92\x5a\x96"
-  "\x43\xdf\x69\xf3\xdd\x77\xa0\xdf\xa8\xe4\x7e\x53\xab\x3f\x49\xa0"
-  "\x2f\x09\xb8\x26\xf5\x32\xf4\x19\x6b\x67\x03\xeb\x43\xea\xe6\x78"
-  "\x82\xbe\x13\x43\xdb\x88\x26\x54\xa1\x18\x89\xeb\x1d\x2e\xe8\x3f"
-  "\x0f\x4e\xa5\xe2\xed\x0d\xf1\x24\x54\x4f\xc2\xb0\x0f\xed\x96\xd6"
-  "\x3d\xd0\x7f\x03\xae\x77\x00\x7e\x63\x17\x7d\xec\x5e\xef\xe8\xf6"
-  "\x63\xbd\xc3\x6a\xb2\xb1\xf5\x0e\x3c\xd3\x24\x42\x3f\x61\xe7\x6c"
-  "\x70\xbd\xc3\xc1\xd6\x88\x98\xfc\xda\xc6\xd6\x3b\x9a\x08\xae\x75"
-  "\xc8\xfe\x59\x70\x8d\xe3\xf6\x24\x22\xa0\x7f\x87\x97\xa1\xdf\x1c"
-  "\xd4\xd5\xb2\x7e\x13\xb8\x0c\x4b\x68\x1c\x6c\x9f\x8f\x13\x68\xea"
-  "\x52\x67\xce\xa3\x2f\x99\xe3\xff\xa7\xc9\xa1\x40\xdf\x94\x2e\xe0"
-  "\x91\x08\xb2\x8a\xaa\xfa\xc8\xaa\x1e\x89\xde\x3d\x9c\xde\xc0\x2b"
-  "\xd5\x93\x9d\x84\x42\x3a\xf7\x4d\xe9\xb0\x01\xd6\x74\xe3\x4b\xd7"
-  "\x22\x6d\x63\x49\xa9\xe4\x9f\x52\x7c\x4e\x3f\x5a\x04\x7a\xe2\x59"
-  "\x86\x8a\x73\x8e\x11\x2e\xd5\xd1\xd6\x82\x6e\x12\x03\x72\x29\x14"
-  "\xe5\x12\xe0\x73\xcc\xb6\x6e\xa0\xed\x17\x9c\xb6\xe8\x5f\x0c\xef"
-  "\xce\xe7\x74\x5a\x28\xfb\xa6\x9e\x1e\xa0\xaf\x83\xd3\xf7\xc9\x67"
-  "\x35\xa4\x4c\x5e\xef\x03\x5d\x5f\x07\x3c\x65\x72\xa9\x33\x9c\x62"
-  "\x4c\x09\x57\x8f\x2e\x4a\xfc\x0a\xe8\xdb\x09\x7d\xaa\x47\x87\xfc"
-  "\xd7\x94\xb5\xe0\xfa\xe4\x67\x7c\xbd\x6f\xb4\xe4\x37\xe3\x39\xd0"
-  "\x11\xcb\xb4\xc4\x5a\x0e\x32\x7a\xe4\xac\x82\x9e\xd2\xb8\x24\x36"
-  "\x06\xc9\x08\x94\xbe\x0f\xce\xbc\x3c\xf4\xd5\x7e\x87\xe8\x3b\x3b"
-  "\x3a\x78\xfa\xfe\xbb\xcf\xfd\x9f\x17\x97\xbe\x9a\xef\x10\x7d\x1f"
-  "\xdc\x10\x3c\x7d\xff\xc3\xe7\xfe\x4f\xa4\x2f\x8e\x13\xe4\x31\x82"
-  "\x3c\x3e\x40\xbd\xc2\x75\xe8\xc3\x46\xf7\xd8\xe0\x61\xa3\xbc\x2e"
-  "\x0a\xb4\x51\x16\xa2\xbf\x66\x68\xb3\xe1\x19\x72\xc3\x29\xc5\x43"
-  "\x5f\xcb\x6b\xa2\xc5\x18\x37\x04\x79\xf5\x12\xf0\x6a\x25\x9e\x59"
-  "\x91\xf8\x04\x7a\x60\x51\x27\xc8\xea\xc9\x71\x7a\x57\x21\xe8\x89"
-  "\xd7\xe2\xec\x3e\x78\x26\xa0\x8c\x0f\x35\x12\xcd\x93\x06\xce\x3b"
-  "\xf1\x39\xe0\x59\x37\xd8\x44\x8e\x56\x82\x67\x50\xc3\x5b\x41\xae"
-  "\xf6\xe8\x47\x2f\x04\x1b\x5b\xe6\xdb\xee\x34\x07\xb3\x87\x06\xe4"
-  "\xdb\x56\x6f\xbe\x75\x0c\xc0\x37\xf7\x3e\x03\xb0\x4d\x19\xdf\x6c"
-  "\x8c\x6f\x4c\xae\x3f\x07\xb6\x29\xf0\x4f\xe6\x1b\x93\xeb\xc0\x3b"
-  "\xc6\xb7\xb6\x26\x66\x03\xc9\x72\x1d\xed\x1f\xe4\x5d\x4d\x32\xd8"
-  "\x73\xb9\xff\xde\xcc\xf8\x86\x73\xdb\xc9\x81\xf2\xed\xa1\x3d\xde"
-  "\x76\xcf\x8f\x6e\xf4\xcf\xee\x79\xf8\x2e\xb4\x6b\x3c\xed\x1e\x7c"
-  "\xee\x00\x3b\xc7\x15\x9a\xb1\xa0\x33\xa8\x71\xf4\xc3\xf1\xde\x36"
-  "\xcc\x8f\xd4\xbc\x4e\x73\xd6\x04\x6e\xc3\x3c\xcc\xe6\xdb\x2a\x5e"
-  "\x1a\xc8\x7e\x79\xf8\xac\xb7\xfd\xf2\x70\x35\xb7\x53\x7e\xa4\xed"
-  "\xc8\x41\xfb\xe5\xe1\x46\x9e\x3e\xc7\xe4\x99\xee\xb6\x5f\x78\x7a"
-  "\x07\xfa\x29\xcb\xfd\x51\x4c\x60\x36\xcb\x9d\x97\xd9\x66\x89\x1d"
-  "\xc4\x66\x89\xfd\x17\xb3\x59\xe6\x16\x5f\xd5\xa9\x43\xc9\xfc\x1f"
-  "\xc5\x07\x2f\xf3\x1f\xb1\x5f\xd5\xa9\x43\xd1\x77\x6e\x43\xf0\xf4"
-  "\x4d\xf4\x79\xfe\x61\x68\x9d\xfa\xe3\x6a\xb7\x4e\xfd\x71\xb5\x6f"
-  "\x9d\xfa\xe3\xfb\xae\xea\xd4\x81\x74\xea\xa3\x33\x82\xd7\xa9\x3f"
-  "\x56\x79\xeb\xd4\xf9\xa9\xfe\xe9\xd4\x1f\x3f\x3f\xfc\x3a\xf5\xc7"
-  "\x7d\xe6\xa1\xe7\x27\xf3\x3a\x25\xd6\x06\xae\x53\xe7\x3f\xe0\x5b"
-  "\xa7\xce\x7f\xc8\x5b\xa7\xce\x8f\xe2\xba\x73\xbe\x91\xeb\xd4\xf9"
-  "\xb1\x3c\x3d\xb1\xc6\x33\xdd\xad\x53\x79\x3a\xd7\xa9\xf3\xb3\x03"
-  "\xd3\xa9\x37\x5c\x66\x9d\xaa\x1d\x44\xa7\x6a\xff\xc5\x74\xea\x4f"
-  "\x7c\xc6\x7f\xbe\x2a\xf3\x65\x99\x3f\x7f\x73\xf0\x32\xff\x31\x9f"
-  "\xe7\x1f\x87\x96\xf9\x3f\xdd\xeb\x96\xf9\x3f\xdd\xeb\x5b\xe6\xff"
-  "\xf4\xae\xab\x32\x7f\x20\x99\xbf\x20\x26\x78\x99\xff\x9f\x4e\x6f"
-  "\x99\x9f\xb4\xcc\x3f\x99\xff\xd3\x35\xc3\x2f\xf3\x7f\xda\x67\xff"
-  "\x5f\xd2\x02\x5e\xa7\xc7\xf6\x05\x2e\xf3\x93\xee\xf6\x2d\xf3\x93"
-  "\xee\xf3\x96\xf9\x49\x1a\x2e\xdb\x93\xf4\x5c\xe6\x27\x45\xf3\xf4"
-  "\xc7\x2c\x9e\xe9\x6e\x99\xcf\xd3\xb9\xcc\x4f\x32\x06\x26\xf3\xc3"
-  "\x2f\xb3\xcc\xd7\x0c\x22\xf3\x35\xff\x62\x32\xff\x67\x0d\xc1\xcb"
-  "\xa4\x85\xf3\xdc\x32\x69\xe1\x3c\xdf\x32\xe9\xf1\x83\x57\x65\xd2"
-  "\x40\x32\x29\x29\x2f\x78\x99\xf4\x78\xb1\xb7\x4c\x5a\xe8\xf2\x4f"
-  "\x26\x2d\x0c\x1d\x7e\x99\xb4\x30\xca\x5b\x26\x2d\x94\xea\xf4\xf3"
-  "\xc7\x02\x97\x49\x0b\x3f\xf4\x2d\x93\x16\x7e\xec\x2d\x93\x16\x4a"
-  "\x6b\x66\x0b\x9d\x5c\x26\x2d\xac\xe2\xe9\x3f\x5f\xe0\x99\xee\x96"
-  "\x49\x3c\x9d\xcb\xa4\x27\x86\xda\xff\xc0\xb0\x5f\x1b\xd9\x07\xfb"
-  "\xbf\x92\xb1\xbf\x28\xf9\xa3\x12\x19\xfb\x8b\xf8\x3e\xe7\x92\xb8"
-  "\xd6\x5f\xa7\x11\x65\x01\xc6\xdc\x80\xfe\x6e\xf8\x39\x62\xff\xc9"
-  "\x23\xb8\xff\x40\xdd\x08\x32\xac\x59\x92\x69\x26\x90\x69\xcd\xf0"
-  "\x8c\x3e\xa9\x26\xc7\xb5\xa2\x2c\xc2\x58\x04\xf8\xcc\x65\x9b\x7d"
-  "\x04\x9e\xdd\x0c\xe8\x5c\x55\xb3\x74\xae\x6a\x49\xff\x73\x55\x25"
-  "\x1e\xe7\x77\xb0\x6f\x84\xae\x53\x84\xe1\x5a\x30\xc8\x37\x49\x8e"
-  "\x55\x8f\x70\xaa\x24\x39\x76\x0e\xe4\xd8\x39\x77\x9f\x40\x39\xd6"
-  "\x01\x72\xac\x33\x5d\x37\x05\x65\x59\xff\x33\x55\x7c\xed\x97\xc9"
-  "\xb1\xfc\x3e\x72\xec\x17\x7d\xe4\xd8\x33\x20\xc7\x92\x41\x8e\x8d"
-  "\x76\xf7\x87\x9b\x1b\x89\x30\x77\x31\xf4\x09\x90\x63\xbf\x3d\x87"
-  "\x72\xec\x60\x90\x72\xec\xc9\xed\xde\xfd\x21\x39\xd4\xbf\xfe\xb0"
-  "\x68\xb2\xaf\xfe\xd0\x53\x18\x6c\x7f\x58\x14\xe3\xdd\x1f\x16\x39"
-  "\x78\x9d\x9e\xf8\x71\xe0\xfd\x61\xd1\xb1\xde\xfe\xf0\xab\xbe\xfd"
-  "\x61\xd1\x17\xde\xfd\x61\xd1\x1e\x8e\xfb\x64\x35\xef\x0f\x8b\xaa"
-  "\x79\xfa\x13\xf3\x3c\xd3\xdd\xfd\x81\xa7\xf3\xfe\x90\x1c\x79\x75"
-  "\x7d\xf6\x4a\xd5\xd1\x8b\x33\xae\xae\xcf\x0e\x35\x2e\x4b\x8e\x09"
-  "\x7e\x5c\xf6\xd4\x65\x5a\xff\xfe\x2e\xcd\x25\x2f\x3e\x10\x3c\x7d"
-  "\x97\x5c\xa6\xf5\xef\xef\xd2\xbc\xc2\xd3\x17\xb0\xfe\xbd\x74\xd0"
-  "\xf5\xef\xc1\xed\x18\x7d\x4c\x4d\xaf\x0d\xaf\x8f\x91\xf7\x6e\xf6"
-  "\xb7\xe1\x7f\xf1\x8a\xf7\xd9\xa9\x67\x1e\xe9\x7b\x76\x6a\x28\xdb"
-  "\xde\xf9\x7f\xca\xb6\x5f\xb2\x21\x78\xdb\xfe\x17\xcb\xbd\x6d\x19"
-  "\xfd\x31\xff\x6c\x99\x5f\x7c\xed\xcb\x96\x71\x06\x6d\xdb\xff\xc2"
-  "\xe1\x6d\xcb\xe8\x0f\x48\xfc\x9f\x18\xb8\x2d\xa3\x7f\xcd\xb7\x2d"
-  "\xa3\xaf\xf0\xb6\x65\xf4\xd9\xdc\x66\xd1\x37\x70\x5b\x46\xbf\x99"
-  "\xa7\x3f\x13\xe9\x99\xee\xb6\x65\x78\x3a\xb7\x65\xf4\xcd\x57\xd7"
-  "\x6d\xaf\x54\x5b\xe6\x97\x73\xae\xea\xda\xa1\x74\x81\xde\x11\xbc"
-  "\x2e\xf8\x55\xf9\x55\x5d\x3b\x14\x7d\x7f\x59\x1c\x3c\x7d\x57\xf8"
-  "\x8c\x7f\x35\xb4\xae\x5d\xb5\xc5\xad\x6b\x57\x6d\xf1\xad\x6b\x57"
-  "\x85\x7a\xeb\xda\x15\x6f\x5f\xd5\xb5\x83\xe9\xda\x5f\xd9\x83\xd7"
-  "\xb5\x2b\x1b\xbc\x75\xad\xe1\x41\xff\x74\xed\xaa\xc7\x86\x5f\xd7"
-  "\xae\x5a\xe2\xad\x6b\x0d\xb1\x12\xff\x9f\x0f\x5c\xd7\x1a\xc6\xf9"
-  "\xd6\xb5\x86\x89\xde\xba\x76\x55\x1b\xd7\xa9\x86\xd9\x5c\xd7\x1a"
-  "\x08\x4f\x5f\xb1\xc1\x33\xdd\xad\x6b\x79\x3a\xd7\xb5\x86\x79\x57"
-  "\xd7\x73\xaf\x54\x5d\xfb\xac\xcf\xf8\x87\x57\x75\x81\xac\x0b\x0c"
-  "\x4b\x82\xd7\x05\xab\x23\x82\xd7\x05\xa9\x3b\xdc\xba\x20\x75\x87"
-  "\x6f\x5d\x90\x3a\xd1\x5b\x17\xac\x3e\x78\x55\x17\x0c\xa6\x0b\x9e"
-  "\x75\x06\xaf\x0b\x8c\xcd\xde\xba\x20\xed\xc7\xfe\xe9\x82\xd4\xc5"
-  "\xc3\xaf\x0b\x52\x0d\xde\xba\x20\x6d\xa6\xc4\xff\xdf\x04\xae\x0b"
-  "\xd2\x26\xfb\xd6\x05\x69\xb7\x78\xeb\x82\x54\x07\x97\xf9\x69\xf3"
-  "\xb8\x2e\x48\x53\xf3\xf4\xd5\xc5\x9e\xe9\x6e\x5d\xc0\xd3\xb9\x2e"
-  "\x48\x5b\x78\x75\x9d\xf7\x4a\xd5\x05\xe9\x96\xe0\x65\xd5\xda\x79"
-  "\x6e\x59\xb5\x76\x9e\x6f\x59\xb5\xe6\xa0\xb7\xac\x32\x3d\x7b\x55"
-  "\x56\x0d\x26\xab\xd2\x0c\xc1\xcb\xaa\x35\x7d\xd6\x7f\xd7\xfa\xb9"
-  "\xfe\xbb\xd6\xe7\xfa\x6f\xf0\xb2\x6a\x6d\x9f\xf5\xdf\xb5\x52\x9d"
-  "\x4c\xf7\x05\x2e\xab\xd6\x7e\xe8\x5b\x56\xad\xed\xb3\xfe\xbb\x56"
-  "\x5a\xff\x5d\x2b\xad\xff\xae\x95\xd6\x7f\x4d\x33\x3d\xd3\xdd\xb2"
-  "\x8a\xa7\x73\x59\xf5\xdc\x05\xae\xff\x66\x9a\xdc\xeb\xbf\x99\xec"
-  "\xcc\x80\xb8\xc5\x1c\xd9\x7f\xfd\x37\xe3\xb4\xb7\x1f\x93\xe7\xf2"
-  "\xd9\x5a\x30\xf6\x8b\x4e\x7e\x36\x7d\xc0\x75\xe1\x89\xe6\xc8\xab"
-  "\xeb\xc2\xc3\xb1\x2e\x9c\x51\xe5\xdd\x4f\xcc\xb7\xf8\xd7\x4f\x32"
-  "\xef\x1e\xfe\x75\xe1\xcc\xd9\xde\xfd\xc4\x2c\x63\x22\x88\x75\xe1"
-  "\xcc\x6f\x7d\xf7\x93\xcc\xf3\xde\xfd\x24\x53\xda\x97\x6b\x8e\xe6"
-  "\xfd\x24\xd3\xc6\xd3\x9f\x9b\xe7\x99\xee\xee\x27\xcf\x79\xac\x0b"
-  "\x9b\x63\xfd\xd1\xe9\x4e\x75\xe6\x02\xd4\xd1\x31\x0d\xf7\xbb\x7a"
-  "\xf1\x6c\x94\xf0\x3c\x90\x4e\x7f\x8a\xcb\x7e\xc4\x71\xcf\x8e\xb8"
-  "\xce\x21\x75\x7a\xb3\xa4\xd3\x97\xf4\xd7\xe9\xb2\x3e\x47\x3c\xbf"
-  "\xec\xd7\x9a\x70\x1f\x5c\x07\xa4\xcf\x23\xab\x2e\x04\xd7\x88\x69"
-  "\x6f\x7d\x1e\x2c\xae\xb3\x2e\xd3\xf9\x97\xef\xd2\x9a\xb0\x79\x76"
-  "\xf0\x63\xbb\xec\xcb\x74\xfe\xe5\xbb\x34\x4f\x9d\x75\x01\xe7\x5f"
-  "\x72\x06\x3d\xff\x72\x75\x6e\x02\xe9\xbb\x6e\x46\xf0\xf4\x5d\x5f"
-  "\x19\xbc\xbd\x9f\x9b\xec\xb6\xf7\x73\x93\x65\xdb\x06\x65\x21\xf3"
-  "\xbb\x03\xf2\xaf\x30\x05\xae\x73\x84\xfc\x3a\x85\xf9\x1d\x57\x59"
-  "\x9b\x8f\x10\x83\x19\xed\x9d\xe7\x8f\x24\x9a\x3c\xed\x9d\x0d\xa9"
-  "\xb2\xad\x93\x88\x76\x10\xd8\x35\x68\xd3\xc8\x36\x7e\x71\xfb\x10"
-  "\xfb\x41\x6f\x89\xeb\xc4\x31\x41\x4f\x68\xe6\x82\x7f\xfd\xf1\x40"
-  "\xce\x96\xe0\xc7\x03\xcf\xf7\xd9\xff\xf6\x5f\x7e\xee\x7f\xcb\xf5"
-  "\xb9\xff\x2d\xf8\xf1\x40\x6e\x9f\xfd\x6f\xb9\xd2\xfe\xb7\x0d\xd3"
-  "\x02\xb7\x73\x72\x07\xd9\xff\x96\xdb\x67\xff\x5b\xae\xb4\xff\xed"
-  "\xbf\xa4\xfd\x6f\xb9\xd2\xfe\xb7\x0d\x31\x9e\xe9\x6e\x3b\x87\xa7"
-  "\x73\x3b\xe7\xbf\xfc\xda\xff\x06\x76\x4e\xd2\x05\xd8\x39\x8e\xef"
-  "\x8e\x9d\x33\xf1\x0a\xb1\x73\xf2\x4c\x7e\xe8\x89\x05\x7d\xf4\x44"
-  "\xe7\xff\x2d\x3d\xf1\x5f\x17\xb0\xf7\x2d\x7f\xd0\xfd\xff\x8c\xbe"
-  "\x05\x1e\xf4\x45\x19\x2d\xd1\xd6\x15\x1d\xd7\x19\x14\x7d\x41\x36"
-  "\x97\x9a\xbf\x2b\xb4\xcd\xb3\x04\x4f\xdb\x5f\x4f\xbf\x6a\xe3\x0c"
-  "\x45\xdf\x8d\xda\xe0\xe9\x5b\xb0\x39\x78\x1b\x67\xd3\x92\x8f\x7a"
-  "\x6d\x9c\x4d\x4b\xfa\xda\x38\x68\xd3\x3c\xe2\xe0\xb6\xce\xaf\xc1"
-  "\x46\xd9\xb8\x12\xec\x9d\x34\x42\xac\xcd\xef\x90\x02\xb0\x79\x36"
-  "\x9e\x01\xbb\x67\x39\xd8\x3d\xce\xd7\x24\xbb\xa7\xe8\x98\xb7\xdd"
-  "\x53\xb8\x62\x40\xbb\x27\xd4\x6d\xf7\x38\xc1\xa6\xe9\x79\x2d\xae"
-  "\xb3\xf8\x8c\x87\x0d\xf4\xcb\xfe\x36\x50\x77\x21\xe8\x9c\x5b\xe2"
-  "\x1c\x3d\x60\x07\x0d\x66\x03\x31\xde\xf7\xb1\x83\xbe\x7b\x36\xd0"
-  "\xaf\x33\x82\xb7\x81\x8a\xfa\xf8\x10\x2d\x1e\xe7\x9f\x0d\xb4\xe9"
-  "\x46\x9f\x73\x3d\x41\xdb\x40\x9b\x62\xbd\x6d\xa0\x4d\x4e\x09\x17"
-  "\xe3\x02\xb7\x81\x36\x1d\xf7\x6d\x03\x6d\x3a\xe9\x6d\x03\x6d\xaa"
-  "\xe2\xb6\x4e\xb1\x86\xdb\x40\x9b\x6a\x78\x7a\xa1\xc6\x33\xdd\x6d"
-  "\x03\xf1\x74\x6e\x03\x15\x47\xf9\xb9\x7e\xb3\xc0\x09\x3a\xf6\xf2"
-  "\xef\x9b\x1b\x6c\xfd\x66\xb8\xf6\xcd\x45\x5e\x21\xeb\x37\xbf\xc9"
-  "\xbe\xaa\xa7\x07\xd3\x23\xc5\xb1\xc1\xeb\x91\xff\xbe\x4c\xfb\xff"
-  "\xbf\x4b\x7a\xfa\x37\xd5\xc1\xd3\x77\xf3\xa0\xfb\xff\x07\xd7\xd3"
-  "\x2f\xb4\xb9\xe7\x22\x5e\x68\x0b\x6c\x2e\xe2\x85\xc5\xde\x3a\xf9"
-  "\x77\x8a\xab\x73\x11\xfe\xea\xe1\xdf\x46\x07\xaf\x87\x5f\x88\xf1"
-  "\xd6\xc3\x2f\x6e\xf5\x4f\x0f\xbf\xf0\x87\xe1\x9f\x8b\x78\xa1\xca"
-  "\x5b\x0f\xbf\x28\xe9\xbd\xcd\x6f\x07\xae\x87\x5f\x5c\xea\x5b\x0f"
-  "\xbf\xb8\xc2\x5b\x0f\xbf\x18\xcf\xf5\xed\x8b\x5b\xb8\x1e\x7e\x71"
-  "\x01\x4f\xdf\x5c\xe5\x99\xee\xd6\xc3\x3c\x9d\xeb\xe1\x17\x77\x04"
-  "\xb6\xe6\x72\xc3\x15\xba\xe6\xa2\xfd\x17\x5b\x73\xd9\xaa\xbc\xaa"
-  "\x27\x86\xd2\x13\x2f\x56\x05\xaf\x27\x5e\x5a\x12\xbc\x9e\x28\x8d"
-  "\x70\xeb\x89\xd2\x88\xc0\xf4\x44\x49\xbe\xb7\x9e\x78\x79\xea\x55"
-  "\x3d\xe1\xaf\x9e\xd8\x3a\x37\x78\x3d\x51\xb2\xc0\x5b\x4f\x94\xee"
-  "\xf3\x4f\x4f\x94\x7c\x3c\xfc\x7a\xa2\xc4\xe6\xad\x27\x4a\x77\xf1"
-  "\x3a\xbd\xf4\x45\xe0\x7a\xa2\xb4\xd0\xb7\x9e\x28\xfd\x9d\xb7\x9e"
-  "\x28\xd5\x73\x7d\x50\x6a\xe1\x7a\xa2\x34\x83\xa7\xbf\x64\xf3\x4c"
-  "\x77\xeb\x09\x9e\xce\xf5\x44\x69\xcd\xd5\xfd\x76\x57\xea\x7e\xbb"
-  "\x6d\xb1\xc1\xcb\xb2\x57\x2c\x6e\x59\xf6\x8a\xc5\xf7\x7e\xbb\x57"
-  "\xee\xf6\xde\x6f\xb7\xed\x8b\xab\xfb\xed\x06\x93\x55\xa5\xb6\xe0"
-  "\x65\xd5\x2b\xc4\x5b\x56\xbd\xea\x67\x3c\xc8\x57\x32\x87\x5f\x56"
-  "\xbd\x52\xe0\x2d\xab\x5e\x95\x62\x40\x6e\xab\x08\x5c\x56\xbd\xfa"
-  "\x03\xdf\xb2\xea\xd5\x07\xbc\x65\xd5\xab\x52\xfc\xc7\x57\x97\x73"
-  "\x59\xf5\xaa\x14\xff\x71\xdb\x2e\xcf\x74\xb7\xac\xe2\xe9\x5c\x56"
-  "\xbd\xea\x97\xff\x7f\xf7\xfa\x5a\x50\x36\xed\x25\x58\x5f\x1b\x2e"
-  "\x9b\xf6\x4a\x59\x5f\xfb\xff\xae\xae\xff\x0c\x6a\xcf\xbe\x7a\x01"
-  "\x7e\xff\x5f\x1b\x74\xfd\x67\x70\x1d\xb0\xd3\xe9\xd6\x01\x3b\x9d"
-  "\xbe\xd6\x27\x36\x02\x86\x0a\xc0\x1e\xcd\x3f\x43\x94\xbf\xc6\xf5"
-  "\x89\xc3\xb5\xa4\x10\xd7\x27\x56\xca\xeb\x13\xa5\x92\x8d\xbb\xf3"
-  "\x59\x6f\x1b\xf7\xf7\xa1\x03\xd9\xb8\x68\xdb\xba\xc0\x6e\x75\xf6"
-  "\x5d\x97\xf8\xf9\xc0\xba\xa3\x3b\x34\x33\xe9\xfc\x6b\x71\x8e\x40"
-  "\x74\xc7\xcb\x6b\xb9\xee\x78\xe9\x3b\xa5\x3b\x76\x68\x83\xd7\x1d"
-  "\x3b\x67\x7a\xeb\x8e\xf2\x3f\xf8\xa7\x3b\x76\xbe\x3d\xfc\xba\x63"
-  "\x67\xb5\xb7\xee\x28\xdf\xcc\xeb\xf4\xda\x1b\x81\xeb\x8e\xf2\x54"
-  "\xdf\xba\xa3\x3c\xd3\x5b\x77\x94\x4b\x7b\x4d\xcb\xcb\xb9\xee\x28"
-  "\x5f\xc2\xd3\x5f\xab\xf4\x4c\x77\xeb\x0e\x9e\xce\x75\x47\xf9\x9e"
-  "\xc0\xe6\x43\xc2\xaf\xd0\xf9\x10\xcd\xbf\xd8\x7c\xc8\x1f\x2f\xe0"
-  "\xfc\xdb\xae\xbd\x35\xbd\xfb\xe7\x77\xed\xed\x37\x5e\x4f\x03\x5b"
-  "\xb7\x9d\xaf\xb9\xf6\x8e\xd7\x6d\xc7\x25\x59\xb6\xeb\x2e\x6f\x59"
-  "\xf6\xc7\x63\xbe\x64\xd9\x60\xeb\xaa\x38\x3e\x77\x81\x9c\xc3\x58"
-  "\x6b\x41\xad\xab\xa6\x7d\x97\xe4\x57\x79\x75\xf0\xf2\xeb\x7f\xfa"
-  "\xf8\x3f\xad\xf0\xd3\xff\xe9\x2e\x9f\xfe\x4f\x9d\x41\xef\xa1\xdf"
-  "\xd5\xc7\xff\x69\x85\xe4\xff\xf4\x8f\x41\x9c\x8b\xab\xb8\xdb\xb7"
-  "\xfc\xaa\xe8\xe3\xff\xb4\x42\x5a\x3f\xad\x90\xfc\x9f\x56\x48\xfe"
-  "\x4f\xff\x58\xec\x99\xee\x96\x5f\x7f\xf4\x38\x17\x57\x31\xa8\xff"
-  "\x53\x5a\x90\x90\x54\x2c\x88\x95\x70\x55\x41\x1d\x27\x02\x06\x2c"
-  "\xf0\xbb\x1a\xf8\x38\x0e\x7e\xd7\xfb\xea\x63\xf6\xd0\x84\x24\x31"
-  "\x07\xea\x2c\x10\x85\xd5\xfe\x8d\xc5\x32\xc9\x89\xf5\xec\xe4\xbc"
-  "\x4a\x48\x0a\x77\x8e\x9a\x23\x52\x3d\x01\xbe\x24\xb1\xf8\x78\x90"
-  "\x3f\x0c\x30\xa3\x4d\x23\x61\x67\x14\xbb\x23\xe4\x7c\x50\xdf\xb0"
-  "\x26\x45\xc5\xc7\x58\x46\x57\xee\x6e\x2d\xb4\x25\xdb\x67\x5d\xa1"
-  "\xac\xc4\x3f\x4c\x21\x99\x4e\xfa\x95\x65\x65\x3b\x69\x56\xec\x5e"
-  "\x16\xde\x36\x6a\x0e\xcd\x4a\x22\x68\x63\x55\x4e\xb2\x2b\xb1\x4c"
-  "\xcb\xca\x6e\x7c\x37\x17\xdf\xb9\xa0\x8e\xe6\x15\x44\x28\x6a\x1f"
-  "\xa5\x02\x59\x30\x22\xab\x93\xb6\xae\x72\x42\x9d\x4d\x4e\xf2\xde"
-  "\x94\x06\xe5\xeb\x2f\x41\x9a\x8b\x44\x62\x4c\x3c\x2c\x03\x6c\x4c"
-  "\xa8\xcf\xee\x15\x65\x90\x7f\xa0\x3a\x3c\xbf\x9b\xc4\x8c\x98\x4a"
-  "\x6d\x81\xe1\x66\xb7\xc5\x17\x1d\xc3\xd7\x4d\x21\x96\xdb\x80\x76"
-  "\x5a\x22\x0c\xf4\x3e\xb0\xef\xbc\xae\x1b\x44\x26\xaa\x30\x9e\x66"
-  "\xd6\x56\x22\x6c\x12\x47\xa9\xf6\x67\xb0\x78\x96\xf6\xae\xdc\xd7"
-  "\x37\xdb\x14\x93\x2a\x91\xe6\x18\x33\x0d\x63\xae\x02\x6e\x08\xa4"
-  "\xef\xda\x67\x22\xa4\x2f\x2f\x52\x96\xac\x58\xac\x35\x2e\x5b\xb1"
-  "\x74\x55\xaa\x51\x7b\xcb\x92\x31\x64\xc1\xaa\x55\xda\x15\x8b\x57"
-  "\xae\xd1\x7a\xbe\xb9\x57\xbb\x64\xd9\xea\xc5\x4f\x2d\x5f\x3a\x6d"
-  "\xc5\xd3\x86\x31\x38\x78\xf5\xa8\x47\x04\xd6\x45\xcc\x7d\xbd\xaa"
-  "\xec\xbf\x09\xf9\xed\x78\xa2\xc4\x7a\x75\xe5\x56\x46\xc9\x31\xf5"
-  "\x8a\x5e\xa0\x9d\x02\xe4\xc9\x02\x19\xb8\xc9\x3c\x0a\xf3\xea\xb6"
-  "\x41\xbd\xca\xa0\xde\x50\x47\xa8\x73\xe5\x1c\xb9\xce\x32\x26\xb2"
-  "\x10\x13\xe6\x76\xc0\x60\xe5\xb2\x70\xc7\xa8\xff\xa0\x34\x09\xdb"
-  "\xd7\x09\xfd\x44\x01\x69\x6f\xa3\x5e\xa2\x85\x09\x49\xf0\xdf\x0d"
-  "\x32\xc6\xf0\xbf\xb4\x28\x41\xdb\x85\xfd\x84\xea\xe3\x78\x9f\x7a"
-  "\x63\xe1\x63\x3a\x05\xe1\x31\xfd\x2a\x2b\xdd\x31\xfd\xde\x60\xb1"
-  "\xe5\xa0\x1e\x6d\x90\x5e\x6d\x23\x6d\x36\x4c\xc7\xd8\x92\x18\xeb"
-  "\x15\xeb\x0c\xed\x02\xbd\x48\x2d\x34\x47\xc2\x7e\xde\x0b\xdb\xc5"
-  "\xbc\x37\xab\xac\xca\x73\x24\xd1\x49\x7b\x68\xfe\x0b\xdb\xeb\x3a"
-  "\x3b\x49\xf8\x3a\xc3\xd3\x74\xe4\xeb\x1f\x86\x3b\x97\x2d\xc5\x98"
-  "\xe4\x62\xfe\x9b\x55\x34\xbf\x62\xef\x63\x53\x89\xa6\x2b\xf7\x8d"
-  "\x68\x8f\xd8\x82\xca\xc0\xf8\xff\x06\xe3\x3f\xf2\x11\xea\x23\xf1"
-  "\xf1\x0d\xe3\x3e\x63\x7f\x3e\xf6\xe2\xef\x0f\x22\x39\x08\x58\xa0"
-  "\xea\xd5\xdb\x13\x5d\x9c\x8e\xd8\x77\x3b\xb2\xf4\xe4\x4e\x46\xbb"
-  "\x3f\xc5\x88\x45\xab\xb3\xc5\x82\xd5\x55\xb4\x60\xf5\x0e\xa0\xd9"
-  "\x8c\xa2\x34\xa2\x5d\xe4\xd2\x90\xc2\x73\x24\xd6\x5e\xb8\x7a\x7b"
-  "\xa8\x22\x5b\x01\xb6\x85\x00\x7a\x23\x16\x64\x46\xac\xd4\xdf\x67"
-  "\x20\x1d\xff\xd6\x46\xc8\xa3\xab\x09\xf9\x6a\x26\x09\x29\x83\xff"
-  "\x05\xd8\x1e\xee\xff\x29\xf7\x8d\xca\x6d\xf0\x5f\x8c\x0d\x19\xd8"
-  "\xff\xff\x34\xc3\x67\xbf\xeb\x6d\xb7\x51\x3b\x70\xbb\xdf\x8c\x16"
-  "\x8b\x8c\x30\xde\x34\xce\xa0\x05\xc6\xe8\xfe\xed\x36\x6a\x79\xbb"
-  "\x47\xb4\x0f\x7f\xbb\xff\xc4\x63\x2e\xe6\xfe\xa9\x3c\xb8\x76\xbf"
-  "\xe9\x73\xfe\xcf\xa3\xdd\x3e\xf8\xbd\x27\x0a\xda\x0d\xfc\x36\x02"
-  "\xbf\x8d\x03\xf0\xdb\x28\xf1\x7b\x6c\xd3\xf0\xb7\xfb\xcd\x56\xde"
-  "\xee\x37\xb7\x07\xd7\xee\x3d\x3e\xe5\x9f\xbb\xdd\xa9\x3e\xf8\xfd"
-  "\x56\x84\x58\x94\x0a\xfc\x4e\x05\x7e\xa7\x0e\xc0\xef\x54\x89\xdf"
-  "\xe3\x3e\x19\xfe\x76\xef\xe1\xf3\xff\xb9\x7b\xb6\x04\xd7\xee\xb7"
-  "\xb4\x7e\xb4\xdb\x07\xbf\xff\x57\x0d\xed\x06\x7e\xa7\x02\xbf\x53"
-  "\x07\xe0\x77\xaa\xc4\xef\x7b\x36\x0e\x7f\xbb\xdf\xe2\xfe\x6f\x72"
-  "\xdf\x2a\x0e\xae\xdd\xff\x1b\x39\x74\xbb\xd3\x7c\xf0\xfb\xcf\x4a"
-  "\x11\x1a\x2a\x16\xa4\x01\xbf\xd3\x06\xe0\x77\x9a\xc4\xef\xc7\x67"
-  "\x0d\x7f\xbb\xff\xb7\x9e\xb7\xfb\x7f\xf3\x82\x6b\xf7\x9f\x35\x43"
-  "\xb7\x7b\x75\x39\xc8\xec\x7e\x3c\xb7\x9a\x66\x90\x3b\xce\x61\xfb"
-  "\xab\x8c\x34\x74\x75\xf9\xd8\x75\xd9\x0a\xa7\x7a\xf5\xae\xb1\x8d"
-  "\x44\x80\xb1\x9f\x3e\xdc\x46\x46\x43\x5b\xf5\xb4\xc8\x14\x8f\x77"
-  "\x11\xca\x71\x82\xec\x77\xa9\x57\xef\xe8\x2e\x48\x98\xf1\xeb\x67"
-  "\x88\x36\xcb\x4e\x34\x75\x66\x1b\x31\x1b\xa8\xbd\x8e\x7c\x41\x42"
-  "\x6d\x44\xc0\x79\xac\x8f\xda\xaa\xc8\xca\x14\x4a\xa1\xec\x27\x70"
-  "\xbc\x58\xd4\x42\x62\xc1\x26\xce\xa6\xa0\x3f\x8a\x45\xa2\x85\xf2"
-  "\x63\x91\x96\x50\xf6\xac\xf0\x05\x44\xf1\xee\x53\x0e\x82\xf4\x44"
-  "\xda\xc2\xd8\x32\x96\xd1\x15\x2c\xc8\x1f\x3d\xce\xe9\xfa\xf2\x33"
-  "\x81\xd2\xb5\x4a\xc7\xed\xca\xd5\x16\xab\xad\x9b\x80\x6d\xa9\xc1"
-  "\x73\xcd\x40\xaf\xe6\x3a\x43\x3b\x8c\x43\xfe\x9c\x47\x0b\x57\x57"
-  "\x8a\xa0\xb3\x02\x2c\xd7\xe7\xfe\x37\x0f\x79\xaa\x03\x99\xd9\x0f"
-  "\x6b\x6e\x7a\xbf\xdd\x4c\x43\x8d\x3a\x4e\x6f\x63\xcc\xd8\xc6\x11"
-  "\xed\x03\xd3\xdb\xa8\x73\x82\xce\x71\xa9\x8d\xd1\xfe\xd3\xfb\xed"
-  "\x5a\x6f\x7a\x1b\xc9\xa5\xa1\xf7\xdb\xdc\x8f\x58\x81\x31\xde\x9b"
-  "\xde\x6f\x2f\xe0\xf4\xae\x72\xd0\x42\x63\xac\x08\xba\x32\xc0\x72"
-  "\x7d\x9e\x7f\xf4\xa0\x37\xe0\xbb\xbf\x0e\x73\xd3\xfb\xaf\x0b\x80"
-  "\xde\x12\xbe\x8d\x80\xef\xb1\x4d\x3e\xe8\x0d\xf8\x36\x02\xbe\x8d"
-  "\x01\xe0\xfb\xaf\xf7\xf5\xa1\xf7\x25\xc2\xf7\x5f\xa5\xf8\x4f\xc6"
-  "\x3e\xf8\xfe\xcb\x01\x4e\xef\xbf\xe8\x81\xde\x80\x6f\x63\x80\xf8"
-  "\xfe\x6b\xb2\x1f\xfa\x03\xf0\xdd\x5f\x77\xba\xe9\xbd\xf7\x00\x0d"
-  "\x4d\x95\xf0\x9d\x0a\xf8\x1e\xf7\xc9\xc0\xf4\x4e\x05\x7c\xa7\x02"
-  "\xbe\x53\x03\xc0\xf7\xde\x0a\x6f\x7a\xa7\x5e\x22\x7c\xef\x35\x71"
-  "\x7a\xa7\xf6\xc1\xf7\xde\xe9\x9c\xde\x7f\x6d\xa0\x85\xa9\x80\xef"
-  "\xd4\x40\xcb\xf5\x39\xae\xf6\xa0\x37\xe0\xbb\xbf\xce\x76\xd3\xfb"
-  "\xdd\xe9\x40\x6f\x09\xdf\xa9\x80\xef\x7b\x36\xfa\xa0\x37\xe0\x3b"
-  "\x15\xf0\x9d\x1a\x00\xbe\xdf\x9d\xdc\x87\xde\x97\x08\xdf\xef\xb4"
-  "\x4a\xf4\xee\x83\xef\x77\x76\x70\x7a\xbf\x33\x07\xe8\x0d\xf8\x4e"
-  "\x0d\x10\xdf\xef\xc6\xfb\x61\x27\x00\xbe\xfb\xdb\x0a\x6e\x7a\xbf"
-  "\xb7\x83\x86\xa6\x49\xf8\x4e\x03\x7c\x3f\x3e\x6b\x60\x7a\xa7\x01"
-  "\xbe\xd3\x00\xdf\x69\x01\xe0\xfb\xbd\x42\x6f\x7a\xa7\x5d\x22\x7c"
-  "\xbf\x97\xc4\xe9\x9d\xd6\x07\xdf\xef\x45\x70\x7a\xbf\x5b\x45\x0b"
-  "\xd3\x00\xdf\x69\x81\x96\xeb\xf3\xfc\xef\x60\xf6\xc9\xea\x52\xa2"
-  "\xf2\xa6\xf9\xbe\xc8\x8b\x67\xa3\xec\x53\x5c\x1e\x1b\xc5\x52\x33"
-  "\xb0\x8d\x62\xc9\xe3\x34\xb7\xc4\x04\x67\xa3\xec\x8b\x0e\xc6\x46"
-  "\xe9\x4f\xf3\xf7\x0b\x2e\x9e\x9d\xf2\x7e\xea\xe5\xb1\x53\xde\x8f"
-  "\x1f\xd8\x4e\xd9\xe7\xe4\x34\xdf\xb7\x3d\x38\x3b\xe5\xfd\x2d\xc1"
-  "\xd8\x29\xfd\x69\x7e\x80\x5c\x3c\x5b\x65\xff\xd7\x97\xc7\x56\xd9"
-  "\xbf\x67\x60\x5b\x65\xbf\x81\xd3\x7c\x7f\x44\x70\xb6\xca\x01\x75"
-  "\x30\xb6\x4a\x7f\x9a\x1f\x34\x5e\x3c\x7b\xe5\xe0\x13\x97\xc7\x5e"
-  "\x39\xa8\x1b\xd8\x5e\x39\x20\x8d\x7f\x0e\xe4\x05\x67\xaf\x1c\xf4"
-  "\x63\xfc\xd3\xdf\x5e\xe9\x4f\xf3\x0f\x5a\x2f\x9e\xcd\xf2\xc1\xc7"
-  "\x97\xc7\x66\xf9\xa0\x64\x60\x9b\xe5\x83\x24\x4e\xf3\x83\xce\xe0"
-  "\x6c\x96\x0f\x3a\x83\xb1\x59\xfa\xd3\xbc\x7a\xe1\xc5\xb3\x5b\xaa"
-  "\x1f\xbc\x3c\x76\x4b\xb5\x66\x60\xbb\xe5\x6f\x35\x9c\xe6\x7f\x33"
-  "\x04\x67\xb7\x54\xeb\x83\xb1\x5b\x90\xd6\x48\x73\xb4\x55\x38\xcd"
-  "\x3f\x8a\xa1\x61\xab\xb3\x7b\xc0\x1e\x09\x05\xba\x87\xb6\x11\xa1"
-  "\x14\x69\xde\xc0\x69\xee\x0a\x33\xc5\x03\x7d\xf4\x48\x33\xd6\x8e"
-  "\x7f\x46\x86\xb9\x0a\x56\xef\xa2\x02\x81\xb6\xa8\x48\x8b\xe2\xc3"
-  "\x1f\x38\x73\x48\x98\xd6\xbc\x0e\x7e\x7f\xc4\xfc\x67\x6a\xcd\xb9"
-  "\xc7\xa1\x8d\x21\xb8\x46\xe1\x2c\x9c\x65\x73\x85\xa6\x27\xb7\x28"
-  "\x0e\xad\xa1\x93\xe3\x6c\x3d\x60\x4b\xd0\x5f\x45\x46\x58\xdb\x2a"
-  "\x89\xd5\x79\x88\xd4\x35\xfc\x85\x88\x61\xa6\x59\x77\x3a\x89\x8e"
-  "\xfe\x53\x17\x51\x63\xb4\x11\xd7\xd3\x91\x6a\xab\xa9\x1a\x70\xf1"
-  "\x27\x92\xd8\x4a\xcf\xd1\x2f\x75\xea\x9e\xd0\x8c\xed\xae\x50\x93"
-  "\xd6\x55\x98\xa9\x77\x86\x66\x14\x57\xa4\xd9\x04\xb5\x83\xe8\x96"
-  "\x37\x53\x5a\xf4\x14\x51\x16\x35\x11\xd5\xa6\xa7\x88\x7a\x53\x13"
-  "\xd1\xd4\x34\x37\x90\xda\x53\xd5\xa4\xb6\xfd\x18\xa9\x3d\x07\x57"
-  "\x37\x5c\x22\x5c\xd9\xc7\x48\x4d\x1b\x21\x8f\x9c\x26\x24\xab\x99"
-  "\xda\x6f\x6f\x24\x11\x35\xce\x06\x82\xfb\x78\xcf\x28\x0e\x85\xaa"
-  "\x93\x49\x04\xfd\x32\x92\xd0\xa7\x23\x05\x78\xa7\xc4\x74\xab\xd3"
-  "\x4e\x6a\x9a\x1d\xf0\xfe\xc3\x36\x78\xaf\xcc\x6a\x86\xf2\xc5\x6a"
-  "\xf4\x17\x67\xaf\xc9\xfe\x90\x38\xf3\xdb\xeb\x81\xce\x55\xb2\x4d"
-  "\x56\xd4\x4d\x62\x37\x01\x9b\x11\x33\x89\x94\x63\x66\x5b\x77\xa0"
-  "\x98\x39\xc4\xfd\x9f\xfd\x2a\x72\x3c\xd0\x7b\x92\xf8\xab\x24\xcd"
-  "\xa3\xc7\x4e\x50\xdc\xa7\x85\xeb\x33\x75\x9d\x87\x88\x75\x83\x48"
-  "\x12\xd7\x10\x32\xd7\x45\x08\xd2\x04\xd7\x92\x1f\x35\x90\x70\xdc"
-  "\x3f\x26\xfe\x53\x37\xde\xda\x6c\x27\x99\x4e\xa8\xeb\x19\x47\x6f"
-  "\x5d\xeb\x36\xd4\x11\x78\x37\xa9\x4e\x6f\x23\x6a\x03\xd1\x20\x9d"
-  "\xc1\x16\x2d\x7f\xb4\x95\x8c\x5e\xd9\x49\x29\xd2\x18\x69\x8b\x74"
-  "\xc6\xf2\x64\xda\x5b\x97\xd8\x49\x96\x83\x68\xac\x66\xb8\x9b\xa8"
-  "\xdd\x4a\xbe\x25\x50\x47\x2d\x1d\xdd\x5e\x0f\xf8\x98\x8d\x98\xb0"
-  "\x29\x3e\x8c\x05\x1c\x8c\xa7\xb9\xd5\xcd\x65\xd0\x5e\x5c\xc3\x0f"
-  "\xac\xcd\x1f\xf9\xb3\xfe\xd1\xcf\x26\x74\xe3\xd9\xa8\xe3\x78\xae"
-  "\x75\xd2\x30\x23\xe9\x01\x5b\x8f\xe3\x79\x44\xfb\xd0\x78\x36\xc6"
-  "\xb8\xf1\x5c\x33\xda\x8d\xe7\xda\xd3\xbe\xf1\x5c\xfb\x10\xc7\xb3"
-  "\x31\xfe\xca\xc4\x73\xcd\xf1\xc1\xf1\x5c\xb3\xd7\x37\x9e\x8d\x33"
-  "\x64\x7b\x77\x78\xf0\x5c\x1b\x71\xe9\xf0\x6c\xd4\x05\x87\xe7\x1a"
-  "\xbb\x37\x9e\x6b\x08\xc7\xf3\x47\x7b\x82\xc3\x73\x9d\xcf\xf8\x07"
-  "\x83\xd9\xdb\x1e\x78\x96\xe4\x73\x7d\x0d\xe0\x19\xe4\xb3\x51\x92"
-  "\xcf\x63\x9b\xfc\xc0\xb3\x87\x7c\xae\x3b\xe6\xc6\x73\xfd\x3b\xbe"
-  "\xf1\x5c\x3f\x51\xc2\xf3\x15\x2a\x9f\xad\x15\x83\xe3\xd9\x5a\x30"
-  "\x08\x9e\xab\xe4\xb1\xc4\xf0\xe0\xd9\xda\x7c\x09\xf1\x1c\xa4\x7c"
-  "\xb6\x5a\xbc\xf1\x5c\x57\xcf\xf1\x5c\xb7\x21\x38\x3c\xd7\xfb\xdc"
-  "\xff\x3c\xd8\x58\xc6\x8d\xe7\x54\x49\x3e\xff\xbd\x84\x86\xa5\x82"
-  "\x7c\x4e\x95\xe4\xf3\xb8\x4f\x86\xc6\x73\xaa\x87\x7c\xfe\xf8\x0f"
-  "\x6e\x3c\xff\xbd\xd0\x37\x9e\x3f\xf9\x9a\xe3\x39\xf5\x0a\x95\xcf"
-  "\x9f\x64\x0e\x8e\xe7\x4f\x16\xfa\xc6\x73\xea\x0c\x79\x9c\x36\x3c"
-  "\x78\xfe\x64\xcf\xa5\xc3\x73\x6a\x90\xf2\xf9\x93\x62\x6f\x3c\x7f"
-  "\xbc\x9d\xe3\xf9\xe3\x05\xc1\xe1\xf9\xef\x3e\xe3\xff\x0c\x36\x4e"
-  "\xf4\xc0\xb3\x24\x9f\x3f\x5d\x0e\x78\x06\xf9\x9c\x2a\xc9\xe7\x7b"
-  "\x36\xfa\x81\x67\x0f\xf9\x7c\x78\x8d\x1b\xcf\x9f\x3e\xe1\x1b\xcf"
-  "\x47\xde\x96\xf0\x7c\x85\xca\xe7\x23\x8f\x0c\x8e\xe7\x23\x31\x83"
-  "\xe0\xb9\x4a\x1e\x03\x0f\x0f\x9e\x8f\x6c\xb8\x84\x78\x0e\x52\x3e"
-  "\x1f\x49\xf6\xc6\xf3\x61\x03\xc7\xf3\xe1\xe8\xe0\xf0\xfc\xa9\x4f"
-  "\xff\x6f\x83\x8d\xc1\xdd\x78\x4e\x93\xe4\xf3\xb1\x99\x34\x2c\x0d"
-  "\xe4\x73\x9a\x24\x9f\x1f\x9f\x35\x34\x9e\xd3\x3c\xe4\xf3\xd1\x87"
-  "\xdc\x78\x3e\x36\xcd\x37\x9e\x1b\xf2\x39\x9e\xd3\xae\x50\xf9\xdc"
-  "\x30\x79\x70\x3c\x1f\x75\xfa\xc6\x73\xda\x0c\x79\x7e\x61\x78\xf0"
-  "\xdc\xb0\xe0\xd2\xe1\x39\x2d\x48\xf9\xdc\x10\xeb\x8d\xe7\xa3\xf1"
-  "\x1c\xcf\x9f\x76\x06\x87\xe7\x63\x3e\xe3\xdf\x05\x36\xbf\xd1\x38"
-  "\x13\xe7\x37\xba\x71\x7e\xc3\xbd\xf7\x4f\x1f\x5e\xcf\xf1\xdc\x03"
-  "\x78\x7e\xd9\x13\xcf\x9f\xf7\x9d\xdf\xf8\x6c\xa2\xd8\x8b\xe7\xc6"
-  "\x7e\x78\x16\x01\xcf\x3d\x0c\xcf\x9f\x3f\x28\xcf\x6f\x58\xdb\xb6"
-  "\x03\x4e\x4e\x11\xeb\x3c\xc0\x72\x91\x84\xe5\xcf\x01\xcb\x40\x43"
-  "\x11\x68\x5c\xd3\xd8\x40\x12\xed\x9c\x96\xdd\x40\x63\xd1\x13\xc7"
-  "\xdd\xad\x02\xe2\x17\x71\x2b\x63\xb8\x76\x25\x60\x37\xe5\x63\x52"
-  "\x9b\x06\xd7\x5a\xb8\xcc\x70\x91\x8f\x49\x4d\x2b\x60\x77\x99\x27"
-  "\x76\xeb\x25\xec\x7e\x76\x6c\x70\xec\x7e\x56\x75\xe9\xe6\x32\x3e"
-  "\xe7\xf3\x5f\x9f\x27\x69\x12\x7f\x7c\x82\x5a\x4d\x0d\x12\x3e\x4f"
-  "\x91\x44\x27\x09\xa7\x8f\xeb\xc6\xab\x93\x88\xe6\x39\x17\x11\x0a"
-  "\x9f\x22\x9a\xc2\xcf\xa0\xdd\x72\xff\x6d\x22\xea\x43\x8e\xbf\x90"
-  "\x9a\xf6\x06\x52\x73\xee\x43\x52\x23\xc2\x75\x0a\x2e\xa8\x6b\xe2"
-  "\x52\xcf\x76\xdb\xa5\x76\x7f\xfe\x31\x94\x15\xed\xbb\xdd\x9f\x57"
-  "\xb2\x76\x2f\x81\x76\x77\xbb\xdb\x6d\x85\x7e\x00\xfc\x99\x24\x4a"
-  "\xf3\x21\x89\x76\x32\x7a\x95\x93\xd2\x6e\x09\xff\xc8\x9f\x43\x87"
-  "\x1d\x24\xd1\x00\x3c\x7b\x1a\xf0\xdf\x5c\x4e\xb2\x32\x00\xff\xdd"
-  "\x0e\xc4\x9d\xdd\x9a\x7d\x1e\xf0\xff\x59\x1b\x05\xfa\xf5\x20\xfe"
-  "\x3f\x47\xfc\x7f\xa6\x11\x19\xfe\x8f\x1d\x08\x0e\xff\x8d\x7e\xe0"
-  "\xdf\x9f\xf9\x90\x13\x33\x71\x3e\xa4\x1b\xe7\x43\xdc\x7b\x40\x87"
-  "\xc0\xbf\xe7\x7c\xc8\x71\x0f\xfc\x9f\x18\x04\xff\xff\x78\x50\x9e"
-  "\x0f\xb9\xfc\xf8\x3f\x3e\x04\xfe\x8f\x0f\x82\xff\xe1\x9e\xfb\xf8"
-  "\xc7\x25\xc4\xff\x3f\x86\xc0\xff\x3f\xfc\xc0\xbf\x51\x17\x1c\xfe"
-  "\x8f\xf7\xc1\xff\x71\x09\xff\x8d\x41\xe2\xff\x84\x3f\xf8\xf7\x63"
-  "\xfe\xa4\x09\xf1\x0f\xf2\xdf\xb8\xc3\x63\x2f\xf0\x50\xf8\xf7\x90"
-  "\xff\x36\x0f\xfc\x37\x0d\x82\xff\x2f\x64\xfc\x5f\x01\xf2\xdf\x36"
-  "\x04\xfe\x6d\x83\xe1\x7f\x98\xe7\x4a\xbe\xb8\x84\xf8\xff\x62\x08"
-  "\xfc\x7f\xe1\x0f\xfe\x83\x94\xff\xb6\x3e\xf8\xb7\x49\xf8\x3f\x11"
-  "\x24\xfe\x9b\xfc\xc0\xbf\x3f\xf3\x2d\x27\x67\xe2\x7c\x4b\x37\xce"
-  "\xb7\xb8\xf7\x84\x0f\x81\x7f\xcf\xf9\x96\x2f\x3d\xf0\x7f\x72\x10"
-  "\xfc\x37\x3f\x28\xcf\xb7\x5c\x7e\xfc\x7f\x39\x04\xfe\xbf\x1c\x04"
-  "\xff\xc3\x3d\xb7\xd2\x7c\x09\xf1\xdf\x3c\x04\xfe\x9b\xfd\xc0\x7f"
-  "\x6a\x90\xf2\xff\xcb\x3e\xf8\xff\x52\xc2\x7f\x53\x90\xf8\x3f\xe9"
-  "\x0f\xfe\xfd\x98\x9f\x69\x45\xfc\x83\xfc\x4f\xdd\xe1\x71\x36\x60"
-  "\x28\xfc\x7b\xc8\xff\x16\x0f\xfc\xb7\x0e\x82\xff\xaf\x64\xfc\x5f"
-  "\x01\xf2\xbf\x65\x08\xfc\xb7\x0c\x86\xff\x61\x9e\x8b\xf9\xea\x12"
-  "\xe2\xff\xab\x21\xf0\xff\x95\x3f\xf8\x0f\x52\xfe\xb7\xf4\xc1\x7f"
-  "\x8b\x84\xff\x93\x41\xe2\xbf\xd5\x0f\xfc\xfb\x33\x9f\xf3\x4f\x36"
-  "\x9f\xd3\x8d\xf3\x39\xee\x33\x22\x43\xe0\xdf\x73\x3e\xe7\x6b\x0f"
-  "\xfc\xff\x73\x10\xfc\x9f\x7a\x50\x9e\xcf\xb9\xfc\xf8\xff\x7a\x08"
-  "\xfc\x7f\x3d\x08\xfe\x87\x7b\xee\xe6\xd4\x25\xc4\xff\xa9\x21\xf0"
-  "\x7f\xca\x0f\xfc\xa7\x05\x29\xff\xbf\xee\x83\xff\xaf\x25\xfc\xb7"
-  "\x06\x89\xff\x7f\x0e\xd3\xfc\x4f\x5b\x33\xce\xff\x88\xea\xd5\x3b"
-  "\x7a\x4a\xe2\x6c\x62\x41\xc6\xf6\x70\x85\x96\x38\xd5\xe9\xc9\x56"
-  "\x63\x27\x79\xf4\x2c\xf0\xc4\x70\x96\x3c\x79\x56\x83\xf1\x02\x8b"
-  "\x29\x8c\xff\xbd\xce\x88\xc2\xe5\xcc\x6b\xaf\xdf\xb4\x92\x28\x5d"
-  "\x61\x26\x76\xbe\xca\xda\xe2\x20\xd8\xe6\x4c\xa4\xc1\x29\x37\x0d"
-  "\x70\x0e\x8e\x7e\xa3\xd3\x94\xe5\x40\x9e\x6e\x1b\x69\x06\xbc\xd4"
-  "\x34\xdb\x80\xf6\x6b\x19\xb6\x90\x17\x50\x9f\x0d\xdb\xce\x10\xa5"
-  "\xf3\xcb\xc8\x49\xc0\xe3\x88\xd0\x74\xa2\x88\x6a\xa6\x22\xf2\x12"
-  "\x79\x84\x7c\xd5\xae\xc5\xfd\x4a\x6d\xc7\xeb\x00\xdf\xce\x2f\x75"
-  "\x93\xca\x20\xdf\xf0\xcf\xcb\xb4\xb1\xf5\x0f\xb8\x67\xd4\x34\x02"
-  "\x2d\x73\xff\x19\x24\x9f\xda\xfc\x39\xff\xe2\xc7\x3c\xc5\x99\x02"
-  "\x9c\xa7\x10\xd5\xc6\x68\xff\xf8\x64\xd4\x79\x9d\x69\x1d\x76\x3e"
-  "\x9d\x89\xf1\x8f\x4f\x67\x9e\xf7\xe6\xd3\x70\xcf\x1f\x9c\x91\xfc"
-  "\xc1\x9c\x89\xe6\x7c\x3a\xbd\x3c\x38\x3e\x9d\x09\x6a\xff\x6f\xff"
-  "\xf1\xb4\x7d\x3a\x8e\xa7\x81\x4f\x7e\xf6\x27\x63\xb9\xd7\x19\xdc"
-  "\x61\xe7\xd3\x37\x87\xfd\xe3\x93\x7d\x5a\x1f\x3e\x0d\xf3\x38\xf7"
-  "\x1b\x29\x1e\xf4\x37\x35\x9c\x4f\xdf\x44\x04\xc7\x27\xbb\x1f\xe7"
-  "\x3f\xfc\x19\xf7\x7d\xdb\x88\xe3\x3e\x11\xc6\x7d\xfe\xf1\x29\x55"
-  "\xe7\x75\x66\x78\xd8\xf9\xf4\x6d\x86\x7f\x7c\xfa\xf6\x88\x37\x9f"
-  "\x86\x7b\x3c\xf6\xed\x76\xce\xa7\x6f\x8d\x9c\x4f\xf6\xbd\xc1\xf1"
-  "\xe9\xdb\xd6\xe1\x19\x9f\x74\x6c\xc0\xf1\x09\xf0\xc9\xcf\xfe\x94"
-  "\x5a\xee\x75\xc6\x79\xd8\xf9\xd4\x11\xed\x1f\x9f\x3a\x32\xfb\xf0"
-  "\x69\x98\xc7\x0d\x1d\x73\x38\x9f\x3a\xa2\x38\x9f\xda\x97\x04\xc7"
-  "\xa7\x0e\x9f\xf1\x3f\x03\xb3\xa3\xcf\xc6\xa0\x1d\x2d\x82\x1d\xed"
-  "\x1f\x9f\xd2\x74\x5e\x67\xb2\x87\x9d\x4f\x9d\x35\xfe\xf1\xe9\xec"
-  "\x2d\xde\x7c\x1a\x6e\xfb\xb6\xd3\xce\xf9\xd4\x79\x80\xf3\xa9\x53"
-  "\x1d\x1c\x9f\xce\xfa\xb1\xff\x73\xe0\x73\x58\xfd\x6d\xbe\x73\x0d"
-  "\x57\x96\xcd\x77\xce\xe4\x1f\xaf\xce\x7d\x7c\x71\x6d\xbe\x73\x25"
-  "\x9c\x57\xe7\x0c\x9c\x57\x67\xab\x82\xe3\xd5\xb9\xe6\x60\xcf\x6f"
-  "\xf5\xb7\xfb\x1c\x1b\xae\x2c\xbb\xcf\xe1\xa7\xfc\x73\x64\x5e\x5c"
-  "\xbb\xcf\x21\xc9\x3f\x87\x24\xff\xba\x82\x94\x7f\x0e\x3f\xe4\xdf"
-  "\xc0\xe7\xbe\xfa\xdb\x7e\xdd\xb1\x57\x96\xed\x77\xbe\xde\x3f\x5e"
-  "\x75\x4f\xbd\xb8\xb6\xdf\xf9\x4e\xce\xab\xf3\xd5\x9c\x57\xe7\x35"
-  "\xc1\xf1\xaa\xdb\x67\xfc\x97\xa1\xce\x8b\xf5\xb7\xff\x7a\xae\x30"
-  "\xfb\xaf\xc7\x4f\xfb\xaf\xe7\x22\xdb\x7f\x3d\x92\xfd\xd7\x23\xd9"
-  "\x7f\xdd\x41\xda\x7f\x3d\x41\xd9\x7f\x7d\x78\x25\xf5\x2b\x57\xde"
-  "\x95\x65\x03\xba\x74\xfe\xf1\xca\xb5\xee\xe2\xda\x80\xae\xb9\x9c"
-  "\x57\x2e\x2d\xe7\x95\x53\x1f\x1c\xaf\x5c\x3e\xe3\x1f\x0e\x75\x3e"
-  "\xad\xbf\x1d\x48\xa7\x5f\x59\x76\xa0\xe8\xe7\xf8\x97\x4e\xbb\xb8"
-  "\x76\xa0\x28\x8d\x7f\x45\x69\xfc\x2b\x06\x39\xfe\xa5\x7e\x8c\x7f"
-  "\xfd\x98\xf7\x13\x14\x9b\xd1\x06\x74\x15\xac\xde\x11\x0e\xf4\x0f"
-  "\x37\x11\xa1\x3b\x0a\xf8\xa5\x06\x7e\xad\xd3\x92\x9e\x02\xe0\x97"
-  "\xdd\x49\x1e\x7d\xf6\x04\xad\x6b\x73\x91\x6e\xe0\xd5\x79\xb0\x03"
-  "\xad\xf6\x56\x3c\xa3\xf7\xc3\x26\x41\x31\xed\xf1\x67\x35\x04\xf9"
-  "\x85\xf4\x77\xa9\xda\xeb\x29\xf0\x8b\xf1\x4f\x9d\xa9\x77\x16\x98"
-  "\xb4\x8f\x9c\x3e\x41\x57\xd9\x28\xad\xd5\x3b\xa0\x4e\xb3\x6c\xb5"
-  "\xfa\x06\x92\xd8\x4c\x46\x6b\xe7\x03\x5f\x04\x72\x1c\xd3\xad\xf6"
-  "\x06\x82\x7e\x3f\xd9\x1c\xf8\x09\x5d\x84\xf3\xa8\x4e\x8d\xfe\x9b"
-  "\xf0\x5c\xa1\xec\xa3\xc9\x7a\x6a\x0b\xe3\x7f\xdf\x39\x55\xc6\xff"
-  "\xa3\x3a\xcd\xcb\x78\x3e\x71\xb8\x6d\x41\x81\xb0\xf9\x3f\xf1\x44"
-  "\xe4\x24\xb9\x8e\xab\x96\x53\x0a\x75\x1c\x5f\x07\x26\x3d\xd6\xb3"
-  "\xae\xd3\x42\xb2\x8c\x44\x53\xd7\xdd\x4a\xcc\x9d\xd4\x5e\x97\xfd"
-  "\x35\x49\x3c\x8b\xeb\x02\x80\x27\x41\x71\x0b\xe3\xb7\x40\xe6\x89"
-  "\x27\x74\x93\x6c\x82\x22\xaa\xae\x9e\x90\xf0\x75\x40\x6b\x27\x11"
-  "\xd8\x79\x4d\x81\xa8\x80\x5e\x7a\x6b\x76\x13\x01\xda\x6d\xb7\x3a"
-  "\x3f\x43\x7a\xea\xe1\xfd\xcc\xde\xf5\x86\x30\xd3\xab\x98\x86\xb4"
-  "\xc5\x7d\xa6\x56\x83\x9d\xe5\x91\xdf\x73\xde\x65\x13\xab\xa9\x9b"
-  "\xd4\x39\x09\x01\x7c\x38\x3f\x4a\x6a\x00\x7c\xd1\xe0\xe4\xb6\xa0"
-  "\xd8\x3e\x2c\xf3\x95\x42\x48\x27\xda\xad\xae\x02\x63\x34\xaf\xe3"
-  "\x88\xf6\xa1\xf1\x65\xd4\xb9\xf1\x15\x52\x78\x61\xf8\x0a\xb9\x6f"
-  "\x78\xf1\x35\xcc\xf6\xab\x10\xa2\xba\x30\x7c\x85\x3c\xcf\xf1\x25"
-  "\x54\x72\x7c\x85\x64\xb8\xf1\x35\xa2\xfd\xa2\xe1\x4b\x10\x16\x32"
-  "\x7c\x6d\x14\xa2\x82\xc3\x17\x86\xbe\x1a\x86\x79\x56\x61\xe4\x02"
-  "\xb4\xb5\x01\x5f\x92\xfc\x1a\xdb\xe4\x07\xbe\x3c\xe4\xd7\x88\xd3"
-  "\x17\x86\xaf\x11\xa5\xc3\x8c\xaf\xe1\xb5\xb9\x85\x11\xfa\x0b\xc3"
-  "\xd7\x88\x93\x1c\x5f\x23\x34\x1c\x5f\x23\x1a\xdd\xf8\x1a\xdb\x74"
-  "\xf1\xf0\xa5\xdc\xcb\xf1\xa5\xcc\x08\x0e\x5f\x23\x93\x87\x65\x7e"
-  "\x58\x50\xed\xc1\xf1\x81\xab\x20\x55\x92\x5f\xe3\x3e\x19\x1a\x5f"
-  "\xa9\x1e\xf2\x4b\xf5\xc8\x85\xe1\x6b\x94\x6b\x78\xf1\x35\xcc\xe3"
-  "\x04\x61\x54\xf5\x85\xe1\x4b\xf5\x20\xc7\xd7\x28\x03\xc7\x97\x6a"
-  "\xa6\x1b\x5f\xe3\x3e\xb9\x78\xf8\x1a\x15\xc5\xf1\x35\xb2\x31\x38"
-  "\x7c\xa9\x2c\xc3\x32\xaf\x2d\x8c\x8d\xc0\x31\x0d\xe0\x4b\x92\x5f"
-  "\xf7\x6c\xf4\x03\x5f\x1e\xf2\x6b\x4c\xc5\x85\xe1\x6b\xcc\x13\xc3"
-  "\x8c\xaf\xe1\x1d\xdb\x08\x63\x74\x17\x86\xaf\x31\xaf\x71\x7c\x8d"
-  "\xae\xe7\xf8\x1a\x53\xe2\xc6\xd7\x3d\x1b\x2f\x1e\xbe\x46\x67\x70"
-  "\x7c\x8d\x9e\x19\x1c\xbe\xc6\x6a\x87\x65\x3e\x5e\x08\x35\xe2\x38"
-  "\xcc\x55\x90\x26\xc9\xaf\xc7\x67\x0d\x8d\xaf\x34\x0f\xf9\x15\x1a"
-  "\x7a\x61\xf8\x52\xbf\x33\xbc\xf8\x1a\xe6\xf1\x98\xa0\xce\xbb\x30"
-  "\x7c\x85\x8e\xe0\xf8\x52\xc7\x72\x7c\xa9\x9d\x6e\x7c\x3d\x3e\xeb"
-  "\xe2\xe1\x6b\x6c\x23\xc7\xd7\xd8\x92\xe0\xf0\x15\x9a\x3d\x6c\xeb"
-  "\x08\x42\x78\xc3\x85\x8d\x21\xc3\x9f\xbd\x30\x8c\x85\xdf\x78\x65"
-  "\x8f\x21\xc3\xda\x2e\x0c\x63\xe1\xcb\x38\xc6\xc2\x36\x73\x8c\x85"
-  "\x27\x5f\x92\x31\xa4\x10\x16\xcf\x31\x16\x46\x82\xc3\x58\xf8\xf0"
-  "\xad\x7f\x08\xe3\x67\x5e\xd8\x38\x72\xdc\x91\x0b\xc3\xd8\xb8\xe7"
-  "\xaf\xec\x71\xe4\xb8\x79\x17\x86\xb1\x71\xb5\x1c\x63\x1a\x07\xc7"
-  "\xd8\xb8\x03\x97\x66\x1c\xa9\xd9\xc1\x31\xa6\x09\x6e\xdd\x46\x18"
-  "\x1f\xd4\xf9\x97\x01\xd7\x6d\x84\x88\xed\x17\x36\x96\x8c\xf8\xc1"
-  "\x85\x61\xec\x9a\xaf\xaf\xec\xb1\xe4\x35\x7b\x2e\x0c\x63\x11\x77"
-  "\x71\x8c\x5d\xb3\x90\x63\x2c\x42\x77\x69\xc6\x92\xd7\xa8\x38\xc6"
-  "\xc6\x57\x07\x87\xb1\x88\x5d\xc3\xb6\xde\x24\x5c\xa7\xbc\xb0\xf1"
-  "\xe4\x84\xd2\x0b\xc3\xd8\x84\x47\xae\xec\xf1\xe4\x84\xc8\x0b\xc3"
-  "\xd8\x84\xdf\x71\x8c\x5d\x6b\xe1\x18\x9b\x50\x70\x69\xc6\x93\xd7"
-  "\x2e\xe7\x18\xbb\x36\x26\x38\x8c\x5d\xe7\x87\xff\x7f\x3f\xd7\xc9"
-  "\x84\x89\xfa\x0b\x1b\x53\x4e\x54\x5c\x18\xc6\x22\xdf\xb8\xb2\xc7"
-  "\x94\x91\x19\x17\x86\xb1\xc8\xf3\x1c\x63\x91\xd1\x1c\x63\x91\xf6"
-  "\x4b\x33\xa6\xbc\xae\x9e\x63\xec\xba\xe2\xe0\x30\x36\xd1\x38\x6c"
-  "\xeb\x7b\xc2\xf5\x35\x17\x36\xae\xbc\x7e\xe9\x85\x61\xec\xfa\x6b"
-  "\xaf\xec\x71\xe5\x24\xdb\x85\x61\xec\xfa\x27\x38\xc6\x26\xe5\x71"
-  "\x8c\x5d\xbf\xe0\xd2\x8c\x2b\x27\x4d\xe7\x18\x9b\x18\x9c\x3f\x0a"
-  "\xe1\xfa\x7e\xfe\xaf\x96\xad\x4c\x5b\xbc\x7c\xd9\x12\xed\xb2\x95"
-  "\xc6\x94\x67\xb5\xab\x97\xad\x5d\x7a\xdf\x2d\xa9\x31\xda\x14\x93"
-  "\x36\x65\xd9\xca\x5f\x48\x09\x4b\xc6\x90\xf9\x4b\x97\x2f\x36\x61"
-  "\x0a\xe4\xfe\xc5\xca\x15\x4b\x57\x1a\xb5\x29\x4b\x9f\x4d\x5d\x96"
-  "\xb2\x14\x7f\xaf\xd6\x3e\xb3\x2a\x05\x12\x9e\x5e\xba\x2c\x6d\xa9"
-  "\xf6\xa9\xd4\x67\x9e\x59\x9a\xb2\x7a\x0c\x79\x24\x75\xb9\x71\x99"
-  "\x61\xf9\x52\xed\xec\x47\x1e\x98\xb6\xe0\xc1\x9f\x2c\xb8\xff\x7e"
-  "\x0c\x4e\xe6\x11\x9b\x2c\x8a\x16\x64\x26\x03\xe6\x94\x2d\x42\xf4"
-  "\xdb\x75\xa0\x5d\x30\x9e\xed\xa6\x76\xa2\xd9\x98\x42\x94\xf9\xed"
-  "\x44\x55\xd8\x4e\xd4\xda\x5f\x92\x78\x9a\xff\x67\x4b\x51\x3b\x89"
-  "\xa0\x45\xb3\x5a\xc5\x7c\x3b\xa1\xf9\xf6\x78\xfb\xe8\x86\x06\x48"
-  "\xd3\x88\xf9\x47\x1d\xf0\x9f\x08\xa0\xad\x92\xe6\xb7\x57\x36\x09"
-  "\xd1\x26\xfb\xe8\x63\xd5\x59\x5f\x13\x81\x8e\x99\xac\xda\x2d\xda"
-  "\x85\x7d\xd8\xbb\xa0\xed\x44\x98\xa2\x85\x4b\x0d\xd7\x5e\xb8\x6a"
-  "\xe0\x6a\x20\xc2\x0d\x04\x2e\x15\x5c\x51\x70\xe9\xe0\x9a\x0e\xd7"
-  "\x4c\xb8\x66\xc3\x35\x17\xae\x05\x70\xd5\xc3\x65\x27\x82\x16\xf2"
-  "\x6a\x23\x79\x39\xda\x68\xb8\xe6\xc1\x05\xa3\x6a\x6d\x31\x11\x6e"
-  "\x84\xfc\x37\x2e\x81\xab\x19\xae\x0c\xb8\xf2\xe0\xc2\xf4\x3d\x70"
-  "\xc1\xff\xb5\x3a\xfe\xee\xa6\x02\xb8\xaa\x09\xd4\x73\xe8\xeb\xa6"
-  "\x56\xb8\xe0\xbb\x37\x47\xc0\x65\x84\x0b\xea\x1b\xad\x1b\xe4\x3f"
-  "\x86\x21\xca\x2c\x0e\x5f\x77\x83\x8d\xc5\xc0\x13\xa6\x64\xd2\x1c"
-  "\x12\x42\xf3\x8f\x55\x1b\x6e\x23\x8a\x53\xc2\x94\x87\xac\x1b\x40"
-  "\xce\xa8\xec\x3c\xa6\x23\x3c\x23\xcd\xba\x36\x4e\x99\x63\x23\xcf"
-  "\x94\x63\x4c\xb3\xc0\xf0\x36\x65\x8e\xf4\xff\x3c\x1b\x71\x6e\x67"
-  "\x31\xe0\x36\x56\x54\xd1\xac\xa4\x97\x59\xec\x37\xa0\x21\x9e\xcb"
-  "\xa2\x79\x15\xd3\xa9\x6a\xa7\x0d\xfb\xbc\x65\x2d\xab\xd7\x8d\xbc"
-  "\x7f\xc1\x7b\xa8\x9b\x3d\x74\x16\xc6\xb9\x54\xe2\x33\xcd\x6f\x68"
-  "\xe8\x0e\xcd\x88\xc7\xdf\xe7\x4b\xe3\x0c\xb4\x20\x03\xfb\x94\x60"
-  "\x31\xbf\x4a\x9a\xe0\x7f\xdd\xa1\x66\x95\x76\x7e\x38\x6d\xe2\x65"
-  "\x0b\x90\x6f\x8f\x5c\x56\x77\xe8\x2c\x3b\xdd\x62\x8e\xa5\x85\x80"
-  "\x21\xa9\x3c\x11\xca\xa3\x05\x26\x8d\x4d\xb8\x41\x83\xe9\xb4\x24"
-  "\x2e\x4f\xfe\x0d\x77\x35\x2d\xca\x28\xc7\x7b\xf8\x3a\xd2\xc9\x9e"
-  "\x73\xe2\x09\xbf\x6b\x08\xca\xba\x36\xe1\x86\xb7\xee\xac\x27\x0a"
-  "\xcb\x7c\xac\xf7\x0d\xd9\x59\xf5\x54\xd4\x9a\x43\xe0\xfb\x37\xac"
-  "\xeb\xfd\xee\x44\xb3\x0e\x63\xa4\x8a\x1b\xa3\x22\x31\x06\x1f\xfe"
-  "\x17\xeb\xf6\xd2\x78\xa2\xdc\xf6\xdf\x44\x85\x6d\xec\xda\x78\xc3"
-  "\x2e\x39\x0e\x1d\xfe\x47\x80\xfc\x0f\xff\x38\x8b\x7a\x94\xbd\x86"
-  "\xf2\xf6\x44\x71\x9a\xde\xd0\x68\x23\xdd\x1b\x30\xbf\xf6\x26\x46"
-  "\xcb\x1b\xa5\xf7\x5a\xe4\x27\x96\x2f\x16\x66\x26\xe3\x33\xc6\xb9"
-  "\x0b\x47\xf4\x99\xa3\xab\x38\x8d\x32\xf4\x58\x0e\xe6\x17\x8b\xd2"
-  "\xf1\xb7\x45\x84\xf6\xba\x72\x88\x4e\xbb\x92\xc4\x37\x09\xda\x87"
-  "\x5c\xf9\xbb\x0d\xf0\x1e\xfa\xdd\x6e\x23\xe4\xcf\x66\xf4\x2e\x34"
-  "\x41\xdb\xb5\x33\xe1\x9d\xb1\x37\xf6\x25\xa7\xb3\x42\xcc\xdf\xbd"
-  "\xa1\x6b\xa3\xd6\x60\x53\x8c\x2b\x90\xdb\xc0\x64\x9c\x3b\x9f\xc4"
-  "\x53\xed\x12\xfb\xe8\xdd\x1b\x7a\xd2\x68\xfd\xa6\xcf\x08\x81\x6f"
-  "\xd2\xee\x73\xb4\x26\x63\x1e\x75\x14\xfd\x27\x21\x35\xc9\x8d\x24"
-  "\x6b\x31\x89\x1a\xbb\x8e\xda\x13\x5d\x24\x7c\x6c\x63\x38\xad\x9d"
-  "\xd7\x08\x32\xfa\x2c\xc9\xa8\xa7\xad\x75\x86\xbd\x24\xe3\x24\x51"
-  "\x67\x2e\x23\x11\x59\xf3\xa8\xdd\x5c\x43\x1d\x56\x53\x23\xa9\xeb"
-  "\x84\xcb\x50\x0b\xf9\x8e\xc0\xb5\x97\x64\xad\x21\xca\x47\x41\x9e"
-  "\x9a\xcf\x12\x75\x9d\xe1\x2c\xa4\x9d\x26\x19\xc9\xd4\x59\x5b\x83"
-  "\xf9\x0e\x92\x44\xa7\x3d\x3c\xf3\x34\x51\x96\xfd\x27\x9e\x2d\x3b"
-  "\x4e\xb6\x41\x5d\xba\x47\xdb\x63\xcf\xe7\xb7\x57\x75\xa4\x51\x67"
-  "\xd7\xc6\x1b\x67\xda\xc8\xdd\x06\xaf\xb6\x60\x9d\x31\x6e\x28\xb4"
-  "\x17\xf3\x88\x85\xe9\xad\x8b\x9c\x88\xf3\x1b\x63\x41\x16\x13\xf9"
-  "\x3d\xbe\xb3\x87\xa6\x03\x7e\x6e\x5c\x98\xe8\xa4\x5d\x98\x1f\xdb"
-  "\x0d\x34\xca\x96\xda\x9f\x1d\x62\x20\x4a\xf8\xc6\x76\x9b\x22\x42"
-  "\xef\xc1\x43\xe4\xc9\x48\xf9\x7b\x52\x9e\x03\x36\xc5\x78\x16\x7b"
-  "\x51\xe4\xef\x76\x61\x5e\x48\x6f\xb4\x29\xae\xa9\xe2\xf5\xbb\x71"
-  "\x07\xa6\x49\xb2\x14\xcb\xd9\x23\x62\xbf\xce\xdb\xb9\xc7\x15\x9a"
-  "\x61\xa0\x02\x75\xd0\xc2\x04\x15\xed\x88\x54\x3f\xea\xa4\x0e\xa8"
-  "\x37\xca\x58\x35\xc6\x49\xe5\xf9\x6f\x4a\x85\xf7\x1a\x6d\x1a\xfb"
-  "\xfd\x04\x7e\x47\x2c\x8d\x4b\x46\xd9\x9a\x58\x8f\xf9\x13\x92\x8b"
-  "\x52\x40\xf6\x16\x02\x05\xa1\xdf\x88\xa1\xa6\xc8\xf3\x5b\xcd\x1a"
-  "\xec\xdf\x14\x30\x46\x0b\x12\x34\xbd\xe5\xe4\x90\x11\x36\xe1\xa6"
-  "\xe9\x14\xfe\x4f\x0b\xd2\xa5\xf2\xa7\x4c\xe6\xd8\xbc\x29\x16\xfb"
-  "\x1d\xd4\xab\x0a\xd2\x47\x34\x09\x37\xed\xc5\x33\x9a\xf0\x6c\x67"
-  "\xb1\x24\x85\x9b\xf6\x71\xcc\xec\xdc\xe3\xf5\x2c\x20\xfd\xa0\x4f"
-  "\x82\x1c\xe0\xf6\xc5\x4d\x5f\xb8\xfb\x05\xc7\x31\xef\xdf\xe9\x50"
-  "\x27\x6d\x94\x98\x13\x22\x42\x3e\x45\x13\xa7\x83\xd0\x3d\x7a\xb7"
-  "\xa9\x6b\xe3\xcd\x6a\x1b\x39\xab\xf3\xe2\xe7\xc6\xdf\x37\x60\xdc"
-  "\x4a\xa8\x4b\x48\x8b\x70\xf3\x0f\xe0\x3e\x0a\xee\xf7\xed\xaf\x47"
-  "\x5d\xcb\xca\x1d\x8b\xbf\x5f\x9a\x40\xed\xb3\x1f\x21\x18\xa3\x12"
-  "\xe8\x7e\xf3\x02\x1b\xf9\x59\x33\x96\xb3\x11\x63\x77\x42\x1a\xe6"
-  "\x81\xf4\xe5\x36\xf2\xf3\xc3\xbc\xfc\x1b\x34\x9d\x28\xb3\xbc\xcb"
-  "\xff\x0d\x2f\x9f\x97\x8b\xe5\xc9\x65\x97\xbe\x40\xdb\xa4\xb2\x2b"
-  "\xe5\xb2\x0b\x21\x4d\x2e\x7f\xf6\x8a\xde\x6f\xd4\xc3\x37\x16\x7a"
-  "\xb6\x61\xeb\x0b\xb4\x13\xcb\x80\x77\x6d\x36\xb2\x78\x17\xbe\xcb"
-  "\x87\x34\xfc\xaf\x07\xa6\x42\xf6\xcf\x83\x32\x6a\xb0\x8c\xe8\x08"
-  "\x1b\x49\x9e\xee\x29\x37\x80\x46\xa1\xb2\xac\xe5\x65\x45\xcf\x90"
-  "\xcb\xf2\x28\x47\xc2\xd4\x9f\x64\x8c\x61\xb9\x6a\x2c\x17\xf2\xeb"
-  "\x6d\x64\xa1\xc9\xb3\xed\x92\xec\x34\x41\x1e\x85\x94\xff\x21\x94"
-  "\x4b\x72\xbd\x31\x76\x27\xdd\x18\x15\x8f\x7d\x03\x64\x20\x01\x4c"
-  "\xe2\x77\x2b\xfb\xc8\x40\x25\xe6\x03\xb9\x99\xca\x62\x97\x4e\xa0"
-  "\xad\x90\xe7\xb0\x57\xbc\x4e\x81\xc4\x41\x5a\xab\x1c\x37\xb4\x08"
-  "\xf2\xd8\x84\x28\x9f\x7e\x11\xcd\x37\x12\xc1\x5a\x62\x43\x9b\x14"
-  "\x71\x35\xd3\x1a\xd5\x49\xac\x25\x22\x11\xcb\xe2\x8a\xe3\xcd\xd4"
-  "\xd2\x22\xdc\xb2\x14\xe3\x3d\x07\xa6\xe7\x6e\x61\xf1\x1f\x69\x37"
-  "\xd8\x6a\x19\xdf\x27\xa8\xdb\xce\x08\xb7\xfe\xce\x6a\x6f\x67\xf8"
-  "\x87\xdf\x4c\x17\xfc\x16\x6c\x3b\xb4\xef\xc0\xa6\xd6\x17\x0b\xdc"
-  "\xc6\x13\x21\x6f\x19\xa6\xa3\xfd\x07\xb6\xe7\x36\x8f\x77\xb4\x2c"
-  "\x6e\x0e\xa7\xdd\xad\x8f\x20\x1d\x59\x7d\x9d\xff\x61\xc1\x3a\x8b"
-  "\x25\x71\x73\xb0\x0d\x59\x26\x2a\x5a\x9d\x5d\x16\x8c\xa7\xab\x4d"
-  "\x43\xdb\xf4\xd6\xa9\x89\xa5\x84\x42\xff\x9d\x13\x60\x1b\xd8\xfe"
-  "\x5f\xb0\xbf\xcf\xd8\x27\xc7\xcd\xc1\xf8\xc9\x9b\xcc\x23\x54\x09"
-  "\x25\xd4\xd2\x31\x25\xae\xb8\x6b\xe3\xad\x73\xe5\xf8\xb4\x81\x95"
-  "\x7b\xeb\x5c\xb9\xed\x65\x52\xdb\xe1\x5b\x6c\xce\xe6\xce\x2d\x2c"
-  "\x3e\x36\x3c\xdf\xba\xc1\x17\xbf\x40\x86\x98\xf0\xbf\xd0\xf6\xf8"
-  "\x6d\x32\x9d\x9c\x76\x8c\x0d\x3e\xee\x94\xf0\xbd\x89\x89\x19\x16"
-  "\xc2\x7c\xe1\x17\xa6\x9b\x02\xac\x17\x9b\xff\xae\x03\xdb\x3f\xd1"
-  "\xf9\x1e\xe5\xb2\xef\x7b\x0f\x3c\x2a\x95\x87\xef\x64\x5e\x95\x49"
-  "\x36\x79\xe0\xdf\xf8\x9e\xcf\xf9\x4f\x8f\x76\x69\x06\x68\xd7\xb7"
-  "\xc1\xb7\xeb\x7b\x7b\xfb\xb7\x4b\x37\x71\x78\xdb\xa5\xf3\xb9\xfe"
-  "\xe9\xd1\x2e\x6d\xff\x76\xe9\x3e\x0c\xbe\x5d\xba\xcd\x03\xb4\xeb"
-  "\xdb\x61\x6e\x97\xc3\x8f\x76\xc5\xf6\x6f\xd7\xd4\x57\x82\x6f\xd7"
-  "\xd4\xe5\xfd\xdb\x35\xf5\xc3\xe1\x6d\xd7\x54\x9f\xf1\xcf\x7c\xca"
-  "\xc3\xa2\x0c\x0b\x97\x87\xb7\xa5\x06\x2e\x0f\x6f\x8b\xef\x2f\x0f"
-  "\x6f\x7f\xcd\x2d\x0f\x6f\xff\x4d\x50\xf2\xb0\x28\x41\xb2\x27\x6e"
-  "\x7f\xa2\x9f\x3c\x2c\x48\x20\x03\xcb\xc3\xdb\x7f\xc0\xe4\x61\x61"
-  "\x42\x80\x6d\xb8\x5d\xd9\x2b\x0f\x43\x13\x88\x97\x3c\x0c\xcb\xb0"
-  "\x74\x6d\xbc\x7d\x61\x70\xf2\xf0\xf6\x85\xfd\xe5\xe1\x6d\x7b\xbd"
-  "\xe5\xe1\xed\x3e\xf7\x7a\x03\x0e\x1d\x03\xc9\xc3\x44\xe7\x37\x54"
-  "\xc2\x86\x23\xc0\xfa\xb4\x0d\xf2\xad\xec\x21\xbe\x95\x1d\xd8\xb7"
-  "\x62\x92\x7c\x7e\x4b\xb5\xf3\x30\xd8\x19\x9a\xcc\x57\x88\xd0\x02"
-  "\x23\xe7\xba\xa8\x06\x62\x35\x39\xc8\x1d\x06\xc0\x44\x0e\x99\x59"
-  "\x57\xd2\x46\xea\xa2\x5a\x08\x1d\xbd\xf3\x30\xfd\xfd\xfd\x24\x3e"
-  "\x05\xb1\x39\x6d\x9c\xd5\xe8\x08\x90\xaf\x31\x8d\x32\x36\xeb\x9c"
-  "\x80\xcd\x34\xc4\xe3\x1d\x0f\x58\xdb\x4e\x49\xd8\xbc\x63\x5a\x2f"
-  "\x7f\x72\x38\x3e\x07\xc4\x26\xf4\x09\x6f\x6c\xa6\x1b\x38\x36\xa7"
-  "\x9d\xef\x8f\xcd\x74\xc3\xc0\xd8\x9c\x76\x84\x63\x33\xdd\x10\x58"
-  "\x1b\xa6\x6d\x77\x63\x33\xdd\xe0\x85\xcd\x5b\xef\x07\x7b\x6c\x9a"
-  "\x23\x38\x6c\x4e\x73\xc8\x6d\x2f\x95\xda\x0e\x69\x49\xde\xd8\xbc"
-  "\xc3\x67\xac\x6b\x8c\xbf\x0e\xf2\x50\x7d\x4a\xb8\x93\xb8\xc0\x6e"
-  "\x15\xf3\x8e\xb7\x26\xba\x68\x17\xc6\x61\xa7\xc2\x74\x42\xd3\x75"
-  "\xea\x2e\x18\x53\x76\x75\xe9\x55\x74\xcc\xce\x67\x68\x4f\x24\xf6"
-  "\xab\x70\xda\xa5\x0b\x03\x9a\x45\xc3\x7d\x7c\x69\x1a\x89\x80\x2b"
-  "\xb2\x54\xa2\x2b\xfc\x8e\xa5\xe9\x91\x63\x8a\xd2\x48\x4c\x78\x27"
-  "\x51\x41\x1d\x92\xc2\xd7\x69\x08\x8c\xf9\x23\xf0\x37\xcd\xd9\x4a"
-  "\xb6\x9d\x23\x4a\x9c\x4f\x14\x47\xc3\xf7\x4c\xe1\x94\xae\xd6\x91"
-  "\x6d\x29\x50\x1f\x81\x44\x6e\x13\x68\xa5\x2b\x5d\x27\xd0\xb0\x8c"
-  "\xe7\xe8\x73\x49\xac\x4e\x62\xf4\xfd\xf1\x80\xa1\x78\x9a\xa5\xc7"
-  "\xef\xc6\x63\x3c\x60\x7a\xeb\xfd\xb3\x69\x57\xe4\x98\xc2\x73\x24"
-  "\x66\x5b\x1a\x89\x2e\x4b\x23\x3a\xda\xa3\x13\x80\x06\x49\x4f\x3e"
-  "\xab\x41\xbe\x27\x51\x01\xbe\x95\x06\xdf\x02\x5e\xba\xf2\xe1\x5b"
-  "\x4e\xf8\xd6\x37\xf0\xad\x33\xf0\xad\x1c\xf8\x56\x0e\xff\x56\x60"
-  "\x34\xbf\x73\xf9\x60\xf3\xbe\x89\x99\x53\xd0\x3f\xed\x57\xe1\xa6"
-  "\x51\x73\x70\x0e\xb8\xe3\x39\x7d\x80\x78\xbf\xb3\xc6\x57\xf9\x9b"
-  "\x76\x93\x28\xaa\x3a\xda\xfa\xe8\xf3\x27\x68\xa2\x93\x90\xe7\x77"
-  "\x93\x18\xec\x73\x75\x8e\xd3\xd0\xcf\x8e\xb6\x1e\xd4\xb5\x05\xf8"
-  "\xad\x58\x9f\xe7\x5f\x37\xe6\xd0\x7a\x51\x0d\x63\x51\x75\x46\xde"
-  "\xa6\x1c\x6a\xea\x89\x8a\x4b\xee\x8e\x8a\xcb\x5e\xe4\xd4\x00\xae"
-  "\xa8\x49\x9b\x42\xb4\x2d\xc2\x3d\x99\x87\x0e\x83\x8e\xf8\x39\x51"
-  "\x35\x09\xf7\xec\xc9\x3a\x86\xf3\x77\xb1\xd5\xde\xf3\x77\xb1\x6d"
-  "\x44\xf8\xfe\x42\x22\xfc\xbf\xe5\x44\x98\x5e\x4c\x20\x9f\xf7\x75"
-  "\xf7\x2e\x5e\xd6\xf7\x7f\x90\xf8\x87\x29\xc4\xec\xa4\x5f\xc1\xf8"
-  "\x34\xa9\x08\xc6\xc0\x89\x53\x15\x36\x4b\x1a\xce\x6b\x7d\xff\x2e"
-  "\xa0\xe9\x3f\x41\x2f\x85\xb7\x08\x77\xb9\x80\x77\xc4\x90\x42\xae"
-  "\x39\x25\xdc\xe5\x74\xc2\xef\xf0\xce\x51\x73\x5c\x59\x49\xc4\x19"
-  "\x69\xd6\xf4\x14\x64\x24\xbb\x60\x1c\x2b\xaa\x8e\xb7\x66\x7d\x4d"
-  "\xa2\xac\x6d\x2e\x52\x02\xb8\x5b\xe4\x52\x61\x7f\x48\xb2\x3c\x75"
-  "\x88\xb4\x18\x89\x90\x75\x96\x84\xd2\x0e\x9d\x5a\xc6\xf5\x23\x6d"
-  "\xe1\x8e\xcc\x36\x2a\x22\xbe\x71\x7e\x01\xde\x85\x99\xcf\x82\xae"
-  "\xb5\xb7\x92\x12\x18\x4b\xbb\x56\xeb\xc7\xdb\x3b\xf4\xd7\xbc\x2c"
-  "\x92\x88\xb0\x4e\xa2\x29\x69\x07\x0c\xae\x06\xfc\xb5\x03\xce\xed"
-  "\x1c\xe7\x78\xfe\xa6\x0c\x31\x9e\xbb\xbb\x6a\x5b\x3b\xc7\x38\xc3"
-  "\x1d\x62\x7c\x15\xe0\x6e\xa5\x1b\x77\xce\x0e\xc0\xf8\xc6\x3b\x77"
-  "\x95\xe4\x50\x92\xb9\x8c\x08\xdb\x4e\x8d\xc2\x77\x8a\x11\x53\x05"
-  "\xed\xa1\x79\x0e\xe2\x1e\x87\xdd\xf3\x56\xf7\xe4\xb8\x6c\xed\x7c"
-  "\xfa\x4d\x93\xf0\x7d\x1d\xa4\xab\xb4\xff\xf9\x3d\x0d\xd0\xfb\x2d"
-  "\x3e\x3f\x73\xcf\x1e\x1c\xbb\xdb\x80\x16\x48\x17\x18\x47\x7f\xaf"
-  "\x49\x88\x75\x21\x1d\xd3\xcb\x49\x88\x21\x8e\x36\x03\xfd\x94\x94"
-  "\xcd\x69\xc4\x3a\xd9\x3c\xf5\x3a\x2d\xf9\x88\xcd\x27\xf2\xff\xb8"
-  "\x80\x6e\x4e\x75\x82\x06\xf8\x6d\xb2\xfc\xb2\x9b\xf5\x39\xa4\x63"
-  "\x0b\x70\x6c\x11\x70\x0f\x68\x12\x0a\x7d\x1d\x65\xc1\x3c\x26\x0b"
-  "\xf2\x76\x26\x67\xd8\xa8\x98\xb8\x24\x84\x9a\x9f\xc5\xf5\x0c\x17"
-  "\xf9\xff\xd9\x7b\x1f\xb8\xa8\xab\x74\x71\xf8\x99\x61\xd0\x81\x50"
-  "\xd0\xa8\xd8\x56\x6b\x34\x6a\xb1\xfc\x43\x86\x65\x2e\x16\x25\x16"
-  "\x96\x7f\x28\xad\x28\x4d\x31\xc1\x86\x22\x1c\x61\xc0\x51\x81\x19"
-  "\x47\x6c\x81\x10\xd8\x22\x97\x0a\x85\xbd\xeb\x7e\x5e\x77\xaf\x6d"
-  "\xb6\x51\xcb\xbd\xd7\xdd\xd8\x85\xf6\xc7\xee\x02\x83\xfb\xba\xef"
-  "\x65\xf7\xb5\xbb\x93\x97\x75\xc9\x45\x9d\x62\x8c\x11\x66\xe6\xbc"
-  "\xcf\x73\xce\xf7\xcb\x7c\x67\x98\x41\x74\xdb\xfb\xfb\x6d\x6f\xd4"
-  "\x38\xf3\x3d\xe7\x39\xcf\x79\xce\xf3\xef\x3c\xe7\x7c\xcf\x9f\x8d"
-  "\x06\x60\x25\xe7\x90\x5f\xce\x5e\xf2\x1b\x53\xbd\x3b\x84\x6f\x20"
-  "\x7e\x4d\x19\x80\x18\x56\xf9\x47\xfb\x4f\x4a\x3b\xc2\x3d\xa8\xbf"
-  "\xe4\x1f\xa2\xf7\xa8\x22\xd0\x2e\xa7\x56\x91\xfd\xa2\x3d\x47\xef"
-  "\xe1\xfe\x2a\xa3\x01\xed\xd6\xbd\x23\x61\xf6\xc8\x8e\x04\x1d\x7e"
-  "\x6e\x92\x7d\x08\xdd\xa3\x75\x90\x78\x5b\x99\x18\x4b\xfe\xc3\x66"
-  "\xb2\x83\x1b\x79\x3b\x95\xfa\x9b\x1d\x09\x33\x38\x8f\x9f\x4f\x80"
-  "\x05\x2e\x50\x21\x4d\x31\x48\x2f\x34\x6e\x05\x6d\x97\xfe\x34\x78"
-  "\xd0\x36\x64\xbe\xaf\xca\xd1\x01\xe2\x55\x7f\x94\xf0\x07\x90\x78"
-  "\xa6\x0a\xad\x77\x49\x15\x3e\xbd\x4b\xaa\x20\xde\x09\xbd\x4b\x2a"
-  "\xff\x2a\xea\xdd\xef\x32\xb8\xde\x85\x8d\xcc\x24\x7d\x5a\xa8\xb1"
-  "\xb9\x7f\x8a\x3c\x4a\x32\x92\x8e\x90\xce\xfc\xe6\xc7\xa4\x33\x8b"
-  "\x1a\xfe\x4f\xd5\x99\x4b\x43\x09\x3a\xfc\xfc\x43\x74\x06\xf1\x72"
-  "\x9d\x21\x5e\xfd\x2e\x63\x18\x64\x1e\x71\x5b\x2d\xff\xcf\x7e\x9d"
-  "\x19\xee\x47\x5b\x6d\x8e\xde\x73\x13\x74\x71\x3e\xdd\xdd\xac\x7b"
-  "\x92\x79\x4f\xab\x17\xfd\xc1\x7c\x02\x62\x86\xad\x8c\xd9\xdc\x6f"
-  "\x83\x37\xca\x14\xc7\xe7\xb3\xab\x96\x65\xd2\xbb\x11\x7a\x2f\x42"
-  "\x73\x74\xd1\x06\x7a\x17\xd2\xdb\xeb\xd9\x5f\x92\x49\xef\x47\x58"
-  "\xc4\xe7\xc7\x3c\x68\xd7\xde\x8a\x9f\xb5\x7a\x23\x1c\x18\x23\xdc"
-  "\x3d\xc3\x0e\xcd\x62\x4e\xbe\xaa\x98\x62\x17\xf2\xbf\x7c\xbd\x37"
-  "\xbd\x3b\xc1\xfc\x64\x79\xce\x9f\x7c\x82\x34\x2f\x27\xcd\xdb\xdd"
-  "\x4d\x32\x8c\xa4\x79\x3b\xc9\xa7\xcc\x93\xe7\xed\xe4\x67\xca\xc7"
-  "\x72\x89\x34\xe7\xa3\x28\x77\x54\x82\x93\xca\x25\xbe\x4b\xbe\xde"
-  "\x57\x4e\x3c\xa3\x5f\x39\x3a\xa2\x06\x6d\xd0\x18\x23\xaa\x24\x13"
-  "\xed\x47\x73\x46\x7d\xcf\xbb\xf8\xad\xc6\xef\x55\xf8\x1d\x86\xdf"
-  "\xfc\xde\xb6\x2b\xeb\xaf\xee\x96\xee\x3f\x2e\x3e\x2a\xd1\xfd\x29"
-  "\xb7\xc9\xdb\x61\xca\x59\xe9\xf7\x50\xe5\x3d\xa9\xf2\xbb\x8b\x51"
-  "\x78\x9f\x7c\xec\x54\x37\xca\x48\x23\xde\xa7\x88\x67\x05\xbe\x4f"
-  "\xf8\x33\x68\x66\xe0\xd8\x45\x47\xef\x3d\x51\x7f\x55\x43\x4c\x7f"
-  "\x9f\xf4\xbd\x94\xbf\x7f\x41\x19\x51\xbc\x26\xf9\xdf\x7e\xa9\xde"
-  "\xe3\xc8\x07\x93\xb2\xde\x60\xfc\xb0\xab\xef\x09\x79\xa7\xcd\x95"
-  "\xf1\xe2\x9e\x90\xf7\x1f\x2e\x4f\xf0\xb0\x2b\xc3\xb5\x38\x25\x64"
-  "\x8c\x38\xe3\xbe\x94\x35\x47\x3c\xad\xde\x91\x8c\xe8\x8f\x8a\xcf"
-  "\x5d\x61\x7c\xb1\x38\xe4\xf9\x4f\x9e\x28\x53\xa2\xbb\xe1\x3e\xd2"
-  "\xfd\xa8\xee\x23\x6e\xf8\xd1\xd9\x7e\xf5\x9a\x39\x37\xc1\x94\x3e"
-  "\x88\xa1\xf8\x69\xd5\xc0\x87\x8c\x62\xa8\xea\xb3\x10\x3f\x7c\x21"
-  "\x23\x7a\x04\x63\xc1\x57\xce\x42\xb2\xf7\xf9\xb8\xc8\xaa\xad\xa0"
-  "\x19\xc6\x78\x75\xf8\x79\x7d\xf4\xef\x4e\xf5\x03\xda\x49\x4a\xb7"
-  "\xd3\x0e\x87\x10\x96\xfd\x35\x63\xea\x8a\x4c\xe6\xea\xcc\x7c\x15"
-  "\xd6\x24\x78\x5a\x4b\x3f\x81\x29\xe8\x8b\x62\x6c\xa6\xb7\xf9\x3b"
-  "\x85\xf0\x9d\x6a\x9d\xcd\xfd\x17\xd8\xbf\x15\x7d\x18\xfa\x2c\xf3"
-  "\xd3\xe8\xab\xdd\x17\xe1\x2d\xa5\xaf\x7e\xe1\x5f\x7c\xbe\xfa\x02"
-  "\xfa\xea\x4a\xf4\xd5\xe6\x38\xe8\x36\xb4\x02\xfa\x8e\xc9\xab\x0d"
-  "\xd1\xae\x52\x03\xfa\xec\x9d\xe8\xb3\x4d\x7f\x01\xee\xaf\x07\xfa"
-  "\x01\x7d\xed\xd4\x83\x79\x10\x3b\xb2\x0d\x7d\xf6\x05\xfd\xb5\x6f"
-  "\x94\x0a\x9f\xfd\x66\x1e\xfa\xec\x6d\x18\x13\xe7\xa1\xcf\x1e\x08"
-  "\xe2\xb3\xcf\x87\x88\x87\x25\xff\x33\xbc\x2d\x41\xfd\xa6\x9a\xc1"
-  "\xee\xa7\x41\xfd\xc6\x9f\x26\x5f\xa1\x9e\x2c\x99\x11\x4a\x06\xc4"
-  "\x6f\xe2\xbf\x17\xe5\xd0\x85\x32\xe0\x71\xab\x6b\x72\xda\x08\xf6"
-  "\x69\x9e\xa9\x05\x96\x1f\x9f\xed\x55\x4f\x35\x42\xcc\x6a\xc3\x87"
-  "\x6c\xb8\x20\x03\xe3\xfe\x8c\x29\xee\x2a\x53\x62\x15\xc6\xd4\x1e"
-  "\x8c\xbd\x47\x86\xe2\xb4\xc8\x83\x18\xc7\x0e\x7d\x34\xf1\xd0\x3b"
-  "\x13\xe5\x39\x69\x46\x12\xfa\xd0\xa4\x83\x5b\x61\xf1\xc8\xfe\x82"
-  "\xa3\x6c\x7f\x41\x93\x67\x7f\xc1\x61\x2c\x3b\xf5\x51\x3b\xc9\xe5"
-  "\xdf\x01\xd3\x5a\x59\x75\x91\xc5\x33\xc5\x94\xe8\x98\x52\x70\x04"
-  "\x9f\x5b\x28\xbf\x74\x33\x4c\x59\x93\x70\xa9\x55\xc8\xeb\x87\x40"
-  "\x72\x12\xf2\xfa\x18\xf6\xe3\xb8\x8f\xfa\x5c\xde\xbf\x4a\x32\xc3"
-  "\xf1\x02\x8f\xf7\x7d\x72\x0b\xe8\x63\x25\xb9\x75\x0d\xb4\x02\xf6"
-  "\x27\x93\x47\xfb\x5a\x2e\xb7\x8f\x41\xee\x67\x91\xdf\x53\x0f\x62"
-  "\x5f\x3b\xf2\x65\xf5\xb5\xd2\x38\x86\xfa\x5a\xea\x67\x49\x6e\x6f"
-  "\x5e\xb1\xdc\xbe\x7d\xf2\xea\xe4\x66\x84\xab\x94\x5b\x95\x4f\x6e"
-  "\xc6\xb9\x6c\xbf\x51\xe7\xd9\x6f\x8c\xf7\x97\x9b\x31\xc5\x27\x37"
-  "\x63\x02\x3e\x2f\xf6\xc9\xed\xe2\x15\xc8\x2d\xfc\xf3\xaf\xae\xdc"
-  "\x96\x56\x5d\xa5\xdc\xae\xd6\xde\xfa\x14\x72\x43\x7b\x33\xa2\xbd"
-  "\x19\x03\xec\xcd\xa8\xb0\x37\x23\xda\x9b\x51\x61\x6f\xe7\xae\x40"
-  "\x6e\xd7\x9c\xfe\xea\xca\xed\xfe\xd4\xab\x93\x5b\xe1\x55\xda\xdb"
-  "\xcc\x64\x9f\xdc\x0a\xd1\xde\x0a\xd1\xde\x0a\x03\xec\xad\x50\x61"
-  "\x6f\x85\x68\x6f\x85\x0a\x7b\xfb\xf8\x0a\xe4\x36\xed\xf7\x5f\x5d"
-  "\xb9\xa5\xb8\xaf\x52\x6e\x57\x69\x6f\x33\xeb\x14\x72\x43\x7b\x2b"
-  "\x44\x7b\x2b\x0c\xb0\xb7\x42\x85\xbd\x15\xa2\xbd\x15\x2a\xec\xed"
-  "\xe7\x57\x20\xb7\xbb\x2b\xbf\xba\x72\x7b\xb0\xf9\xea\xe4\x56\x74"
-  "\xb5\xf6\x36\xe0\x93\x5b\x11\xda\x5b\x11\xda\x5b\x51\x80\xbd\x15"
-  "\x29\xec\xad\x08\xed\xad\x48\x61\x6f\x25\x57\x20\xb7\xf5\x0f\x7e"
-  "\x75\xe5\x96\x1a\x72\xfe\x53\x96\x9b\x2c\x33\x92\x1f\x97\x1b\xcb"
-  "\x00\x37\xc6\x93\xff\xfa\x9c\x90\x1b\xc9\x8b\xcb\x6e\x30\x23\x7a"
-  "\xbf\x24\x33\xb7\x24\x33\xe2\x1f\xc9\x8d\xe2\x48\x2e\x37\x95\x26"
-  "\x96\x62\x48\x37\xc6\x92\x72\x1c\xf9\x88\x9e\xb9\xba\xf4\xff\x32"
-  "\x1a\x47\xba\x03\xe3\xc8\x1c\x65\x1c\xf9\xb6\x9f\xbc\xaa\xbe\x40"
-  "\x79\xa9\x25\x79\x3d\x1b\x22\x8e\xdc\xfa\xab\x10\xf2\xea\xb9\xac"
-  "\xbc\x50\x36\xb1\x23\x83\x42\x5e\x6f\x4a\xf1\x7f\x43\xfe\xdf\x29"
-  "\xaf\x02\x94\x17\xc5\xff\x1f\x83\xfa\xad\x8d\x57\x2a\xaf\x87\x2e"
-  "\x1b\xff\x07\x97\x57\x21\x5c\x99\xbc\x66\x26\xfb\xe4\x55\xa8\x73"
-  "\x63\x9f\x26\xf7\x67\x3e\x79\x89\xfe\xcc\x1d\xd8\x9f\xe5\x28\xfb"
-  "\xb3\x89\xc8\x2b\xa0\x3f\xfb\x4a\xc9\xeb\xe1\x90\xf3\xff\x1e\x1c"
-  "\x8b\x7b\xd0\xcf\xd1\x7c\xe5\xd4\x7e\x1c\x27\xbb\xd9\x5f\x57\x3b"
-  "\x71\x9c\xec\x9e\x9c\x56\x93\x07\xf1\x23\x3b\x70\x9c\x8c\xb2\xab"
-  "\xca\x83\xe4\xca\x3c\xd0\x78\x5f\xc4\xb1\xf2\x59\x1c\x2b\xa3\x7f"
-  "\x1a\xfe\x9b\x3e\xba\x33\xd3\x01\x5e\x1c\x2b\xd3\x3c\x18\xd2\x1b"
-  "\xcf\xfe\x86\x63\xe5\x3e\xf4\x7d\x7d\x6f\x8a\xb1\xf2\x5f\xe4\xb1"
-  "\xf2\xfb\x7e\x63\xe5\x57\x5e\x90\xc6\xca\x12\xff\x1b\x94\xbc\x7f"
-  "\xe6\xc7\x21\xc6\xca\x1d\x97\x1d\x2b\xd3\x18\xf9\x2d\x1a\x2f\x5f"
-  "\xd0\x4f\x7f\x43\xf2\x6d\x6f\x9e\xff\x3b\xc7\xca\x17\x70\xac\x6c"
-  "\x15\xbc\x7f\xf3\x8a\x79\xbf\x22\xe4\xfa\x0f\xb2\x0d\xb2\x97\xd1"
-  "\xbe\x08\xf9\x2c\xf7\x41\x23\xd8\x07\xd1\x7c\xc6\x70\x55\x41\x19"
-  "\xea\x2b\xb7\x0f\xde\x27\xed\x88\xd3\x92\x6d\x90\x9d\x90\x6d\xf0"
-  "\xbe\x08\xfd\x20\x9b\x74\x53\xea\xa1\x17\x60\x71\xe3\x0b\x90\xe4"
-  "\x9e\xe2\x3f\x46\x7e\x24\x8b\xe4\xe1\xf3\x6d\xde\x40\xdf\x96\xad"
-  "\xf4\x6d\xef\x8f\xed\x8b\x2e\xe7\xdb\x5e\x08\x65\x2b\x1d\x97\xb5"
-  "\x15\xb2\x11\xde\x1f\xa1\xbd\xfc\x23\x6c\xe5\xcd\xff\xba\x52\x79"
-  "\x3d\x12\x72\xfd\xc7\xc4\xe4\x65\xd4\x5c\x5e\x5e\x46\x40\x79\xd5"
-  "\xfb\xe4\xe5\x3f\x36\xf6\xc9\x4b\x8c\x8d\xbd\x81\x63\xe3\x6c\xe5"
-  "\xd8\x78\x22\xf2\x0a\x1c\x1b\x7f\x95\xe4\xb5\x32\xe4\x3a\xbf\x09"
-  "\xca\x6b\x02\xf6\x65\x24\xfb\x1a\x50\xc8\xcb\x6f\x4c\xac\x90\x97"
-  "\xc2\xbe\x14\x63\xe2\x6c\xe5\x98\x78\x22\xf2\x0a\x1c\x13\x7f\x95"
-  "\xe4\xb5\x3a\xe4\xfa\x8f\x89\xc9\xab\x70\x02\xf6\x55\x88\xf6\x75"
-  "\x73\x8a\x4f\x5e\xfe\x63\x61\x9f\xbc\x0a\x15\xf6\xa5\x88\x1d\xb2"
-  "\x95\xb1\xc3\x44\xe4\x15\x38\x16\xfe\x2a\xc9\x2b\x5d\xfb\x77\xca"
-  "\x6b\x02\xf6\x55\x88\xf6\x75\x73\x9d\x42\x5e\x7e\x63\x60\x85\xbc"
-  "\x14\xf6\xa5\x18\x03\x67\x2b\xc7\xc0\x13\x91\x57\xe0\x18\xf8\xab"
-  "\x24\xaf\xc7\x5a\xfe\x3e\x79\x15\x4d\xc0\xbe\x8a\xc8\xbe\xfa\x7d"
-  "\xf2\xf2\x1f\xfb\xfa\xe4\x55\xa4\xb0\x2f\xc5\xd8\x37\x5b\x39\xf6"
-  "\x9d\x88\xbc\x02\xc7\xbe\x5f\x25\x79\xad\xd5\x8f\x37\x96\x52\x8e"
-  "\xa1\xdc\x66\x9f\xbc\x48\x36\x23\x38\x76\x1a\x89\x2a\x28\x0b\x3d"
-  "\x7e\xba\x29\x35\xd4\x78\x97\xce\x83\x79\xa4\x9f\xf6\x84\x88\x98"
-  "\x90\x05\xc4\x84\x5d\xfa\x1f\x83\xff\x98\xf7\xe7\x63\xc6\x50\x23"
-  "\xf2\x1c\xc5\xe6\x50\x63\xde\x7f\xbf\xea\x31\x14\xc9\x89\xc6\x51"
-  "\xee\x02\x94\x93\x14\xc7\xbf\xf5\x77\xce\x51\x8c\x0c\x26\xa8\xdf"
-  "\xc2\x38\xbe\x78\x33\x8e\xa1\x9e\xbb\x52\x39\x3d\x11\x72\xff\x37"
-  "\xcd\x13\xd1\x98\x97\xc6\x52\xf4\xde\xb1\xbb\xaf\x1f\x2a\x8b\x20"
-  "\x86\xbf\x7b\xec\xf7\x7f\xf7\x58\x73\x06\xc7\x54\xdb\x50\x6e\x23"
-  "\x19\x50\x7d\x06\x92\xab\x5e\x10\x63\x2a\x79\x3c\xd5\xed\x74\xf1"
-  "\x77\x8f\x36\xb7\x1d\x56\xd8\x99\xab\x11\xe1\x69\x1c\xd5\x99\xf9"
-  "\x26\x90\xad\x98\x3f\x81\x29\x24\x03\x1c\x83\x71\x79\x28\xc7\x50"
-  "\x87\x94\xef\x1b\xb7\x86\x1a\x43\x5d\xfe\x7d\x63\xc3\x79\x31\x7e"
-  "\xe2\xef\x1b\xff\x8f\x18\x43\x3d\x19\xf2\xfd\xc7\xaa\x1f\x89\xf9"
-  "\x06\xe2\xbd\x2d\xc1\x0d\xa8\x4f\x7f\x8d\x1e\x10\xf3\x7a\xee\xea"
-  "\x02\x0b\x8d\x69\x69\x3c\x6b\x33\x75\x40\xe5\x2e\x88\x19\x1e\xca"
-  "\x88\xc6\x31\xea\x14\x37\xfa\xba\x57\xce\x0a\xde\x97\x9c\x83\x18"
-  "\xc7\x8b\x7a\xbe\x56\x86\xc6\xb2\x64\x2b\xfc\x9d\xe3\x73\x90\xd4"
-  "\x70\x1a\x16\x73\xfb\x40\xbb\x70\xef\x37\x25\x7a\xa7\x14\x1c\x26"
-  "\x3b\x59\x71\x8a\xb9\x48\x06\x64\x1f\xbf\x3b\x45\xb2\x79\x1b\xcc"
-  "\x1f\x0b\xd9\x70\xb9\xa8\xfd\xdf\x05\x8f\xb5\x8d\xdf\x87\x90\x4f"
-  "\xcb\xc4\xe4\xb3\xcd\x5f\x3e\x07\xaf\xf6\x7d\xb0\xbc\x3e\x72\x5b"
-  "\x82\xfa\xa0\xf4\x3e\xf8\xcd\x67\xae\x54\x3e\x19\x73\xaf\x4e\x3e"
-  "\x46\xb8\x3a\xf9\x18\x75\xfc\xdd\xa2\x9f\x7c\x8c\x8b\x85\x7c\x8c"
-  "\xf1\x34\x56\xf2\xc9\xe7\xe2\x04\xe5\x13\x30\x46\xfa\x4a\xc9\xe7"
-  "\xe9\x90\xf3\x3f\x97\x91\xcf\x55\xda\x8f\xb1\x89\xbf\x43\xf4\x97"
-  "\x8f\x64\x3f\xc6\xc3\x34\x36\xf2\xc9\xe7\xdc\x04\xe5\x13\x30\x26"
-  "\xfa\x4a\xc9\x67\x7d\xc8\xf9\xef\xf1\xe5\x53\x78\x95\xf6\x53\xa8"
-  "\xe3\xef\x0a\xfd\xe4\x53\x28\xd9\x4f\x61\x3c\x8d\x85\x7c\xf2\xf9"
-  "\x78\x82\xf2\x09\x9c\x3f\xfd\x2a\xc9\xe7\xd9\xa8\xab\x94\xcf\x55"
-  "\xda\x4f\x61\x13\x7f\x27\xe8\x2f\x1f\xc9\x7e\x0a\x0f\xd3\xd8\xc7"
-  "\x27\x9f\x9f\x4f\x50\x3e\x01\x63\x9e\xaf\x94\x7c\x36\x86\x3c\xff"
-  "\x69\x7c\xf9\x14\x5d\xa5\xfd\x14\xe9\xf8\xbb\x3f\x3f\xf9\x14\x49"
-  "\xf6\x53\x14\x4f\x63\x1d\x9f\x7c\x4a\x26\x28\x9f\x80\x31\xce\x57"
-  "\x4a\x3e\x99\x2b\x2f\xf7\xbe\x48\x8e\x9d\x95\xef\x65\x47\x30\x7e"
-  "\xa3\xf8\x99\x62\xe7\x6e\x67\x0b\xb8\xb7\x09\xd9\x54\x7e\x01\x31"
-  "\x55\x92\x6c\xf8\x3b\xd9\x17\xc5\x3b\x59\x1e\xb7\xbd\x3c\x23\x89"
-  "\xed\xd1\xc4\x52\x5c\xc6\xdf\xbb\xf2\x77\x13\x1f\x51\x5e\xcb\x88"
-  "\x22\x7e\xa3\x31\x2a\xc6\xde\x40\xe3\x54\xf3\x5f\xae\x20\x6e\x7b"
-  "\x2e\x94\x5c\x2e\xff\x6e\xa2\x41\xb1\x8e\x4f\x1e\x7b\x7e\xa9\x72"
-  "\xb9\xe2\xf7\xae\x9b\x43\x9e\xff\x38\xbe\x5c\x0a\xe1\xca\xe4\x82"
-  "\xfd\xcd\xcb\x33\x93\x85\x5c\x3e\x0e\x90\x4b\xe1\xe2\x11\x45\xbf"
-  "\x33\x71\xb9\x04\xf4\x37\x5f\x29\xb9\x6c\x29\x0e\x39\xd6\x44\xbf"
-  "\x44\x32\xa1\xf5\xdd\x35\xcf\x41\x7c\xe5\x69\x48\x1e\xf9\x5b\x5c"
-  "\xe4\x6a\xf4\x73\x23\x2f\xc6\x69\xbb\xd1\xc7\x95\x3a\xd9\x5f\xa7"
-  "\x3a\x27\xa7\xfd\xf6\xa4\x03\xba\x33\xed\x30\xbc\x23\x03\xf6\x9f"
-  "\xa5\xb5\xea\x2d\x50\x91\x4f\x63\xf9\x9f\xc2\xef\x4e\x7d\x0e\xab"
-  "\x8f\xb0\x11\xdb\x40\x0b\xb4\xee\xfa\x29\xb0\x17\x13\x22\x1b\x11"
-  "\x66\x13\xf2\xf0\xbc\x3a\x2b\xe9\x12\x8e\x47\x17\x98\x20\x66\xe5"
-  "\x00\x73\x75\x0f\xfc\x16\xde\xc2\xba\x3e\x32\x01\x10\x7f\x49\x26"
-  "\xfb\x5f\xa0\xf1\xe7\xcf\x85\x4c\x1e\x13\x32\x79\x53\x31\xfe\xd4"
-  "\x61\xfe\x19\x03\xca\xe3\xb3\x00\x79\x9c\xea\x07\xe4\xef\xe4\xd5"
-  "\x4e\x94\x87\x53\x96\xc7\x39\x28\xdd\x4e\xf2\xb0\x8f\xae\x77\x1d"
-  "\x96\xe4\xd1\x40\xfe\xcb\x00\x31\x6f\xc8\xe3\xcf\xf3\x0a\x79\xc8"
-  "\x7b\xb2\x94\xf2\x90\xc7\xfe\x3b\x12\x68\x9f\xd6\xe8\xf8\xf3\x12"
-  "\x8e\x3f\xdf\xc0\xf1\xa7\xf9\x04\xa8\xdf\x28\xbd\x52\x79\x64\x87"
-  "\xec\xff\x65\x59\x50\xdf\x32\x32\xb5\xc0\x42\x72\xb0\x99\x8e\x01"
-  "\xc9\x84\xfa\x13\xcf\xdf\xe2\xb4\xc5\x46\xb4\x1d\xfb\xe4\xb4\x61"
-  "\x86\x63\x7e\x1c\xef\xdb\x36\xfc\x09\x68\xce\x40\xc8\x60\x64\xc4"
-  "\xe6\x68\x01\xe2\x7d\xeb\xae\x3f\x71\x39\x9c\x57\x67\x37\x6f\x74"
-  "\x82\x7a\x3e\xea\x21\x8e\xf7\x63\x36\xd1\xbe\x5c\xf4\x6d\x6f\x6d"
-  "\x85\xc5\x2b\x0d\xcc\x45\x63\x53\xb2\x21\x5a\x7b\x42\x7e\xad\xdb"
-  "\xf0\x2b\xa0\x79\x9d\x91\x29\xa6\xc4\x8f\x8c\x00\xe4\xdf\x88\xef"
-  "\xe1\x85\x3e\x39\xd1\x7a\x12\x2e\xab\x27\x26\xb0\xce\x55\x29\xaf"
-  "\x0d\xf6\x09\xad\x4f\x1e\x96\xe6\x0b\x1a\xe4\x39\xb5\xab\x9d\x2f"
-  "\x90\xe7\xd4\x2e\x88\xf5\x24\xe6\x3f\xa0\xfd\x5c\xb1\xbc\xb6\x1e"
-  "\x9f\x98\xbc\x8c\x70\xe5\xf2\x1a\x0a\x22\xaf\xe7\xb3\xc6\xca\xcb"
-  "\xa8\x53\xc8\xab\xca\x27\x2f\xe3\x62\x21\x2f\x63\xbc\x4f\x5e\xc6"
-  "\x84\xcb\xcb\x6b\x9c\xf5\xad\xff\xf4\xf2\xd2\x87\x1c\xff\x04\xc8"
-  "\xeb\x2a\xec\xeb\x42\x10\x79\xe5\xc4\x06\x91\x97\xd2\xbe\xfa\x14"
-  "\xf2\x92\xec\xcb\xa8\xb0\x2f\xe3\x04\xec\x6b\x9c\x75\xad\xff\xf4"
-  "\xf2\x7a\x21\xe4\xfa\x1f\x7f\x79\x15\x5e\x85\x7d\xfd\x39\x88\xbc"
-  "\x5e\x68\x1f\x2b\xaf\x42\x85\x7d\x61\x6c\x31\x2a\xaf\x42\xc9\xbe"
-  "\x0a\x15\xf6\x55\x38\x01\xfb\x1a\x67\x3d\xeb\x3f\xbd\xbc\x5e\x1c"
-  "\x77\xfd\x8f\x42\x5e\x57\x61\x5f\x1f\x06\x91\x57\xae\x31\x88\xbc"
-  "\x14\xf6\x35\xb3\x4e\x21\x2f\xc9\xbe\x0a\x15\xf6\x55\x38\x01\xfb"
-  "\x1a\x67\x1d\xeb\x3f\xbd\xbc\x5e\x0a\x19\xff\xf9\xcb\xab\xe8\x2a"
-  "\xec\xcb\x1c\x44\x5e\x79\xf1\x63\xe5\x55\xa4\xb4\xaf\x01\x9f\xbc"
-  "\x8a\x24\xfb\x2a\x52\xd8\x57\xd1\x04\xec\x6b\x9c\xf5\xab\xff\xf4"
-  "\xf2\xda\x16\x72\xfe\x5b\x29\xaf\xe1\x6a\x39\x3e\x3c\xe2\x2f\x2f"
-  "\x8c\xd7\xa3\xfb\xc4\xd8\x4a\x96\x57\xe8\xd8\x70\x5b\xcf\xa8\xac"
-  "\xfe\xe2\x8b\x0d\xb9\x9c\xa4\xf7\x14\x24\x1f\x8a\x11\x29\x26\x1c"
-  "\xde\x2f\x64\x44\xef\x00\xc7\x8d\x0b\x27\xb2\xff\xe9\x2a\xe4\x24"
-  "\x8f\xab\xbe\x74\x39\xfd\xf1\x6a\xe4\x64\x08\xb9\xff\xc9\x5f\x4e"
-  "\x72\xbf\x35\x51\x39\x05\xeb\xb3\xb6\x9b\xc6\xca\xa9\x50\xe7\x93"
-  "\x93\xe8\xa7\xa8\xef\xa2\xbe\xca\x5f\x4e\xe3\xf4\x57\x13\xd9\x7f"
-  "\xf1\x4f\x2f\xa7\xfc\xd0\xfe\x4f\xcd\xef\x36\x3f\x56\xab\xf6\xb6"
-  "\xe0\xa7\x15\x3f\x1d\x98\x16\x8e\x69\xfc\x7c\xa3\x5a\x29\xcf\x53"
-  "\x09\xb4\x4f\xbb\x35\x5a\x95\x49\xe7\xe9\x12\xcc\x24\x19\x26\x7a"
-  "\x0f\xa4\x60\x7b\x04\x9c\x1a\x2c\x98\xde\x3a\x65\x4f\xca\x24\x84"
-  "\xef\x60\x95\xf7\x38\x31\x6d\x32\xc1\xb2\x3d\x1a\x7e\xd6\x79\xb4"
-  "\x8a\x9f\x7d\x23\xc1\xab\x80\xe0\x09\x16\xe1\xb4\x12\x1c\x8f\x87"
-  "\x98\x5a\x0d\x8d\x63\x69\x8b\x90\x60\xe8\x8c\x4c\x9d\x92\xc6\x29"
-  "\xaa\x14\x8e\x4b\x82\x8b\xf4\x58\x7b\x8e\x12\xac\x67\x8f\x26\x5e"
-  "\x09\xc7\x1e\x04\xc2\x2b\xc3\x5d\x23\xe1\x4b\xf0\x6b\xef\x6c\x80"
-  "\x29\x7b\x74\x1c\xdf\x94\x01\x35\x48\xf4\x45\xb1\xc8\xbb\x3b\x38"
-  "\xbc\x4a\x33\xd7\x0f\x7e\x12\x28\xdb\x31\x85\x4d\x9a\x35\x57\x82"
-  "\x4b\xf4\xaa\x81\x9f\xef\x82\xe9\x1a\x25\xaf\x25\xd8\xa9\x32\x1f"
-  "\x51\xd6\x1a\x65\x7b\x3d\xd8\xfe\x83\x82\xc6\x68\xcf\xcb\xba\x64"
-  "\xa9\x2d\x8b\x95\xf5\x12\x1c\x96\xbb\x53\x92\x49\x0c\xb6\x23\x79"
-  "\x14\x5f\xd5\xb2\x0c\x19\xce\xec\x81\x6f\xa0\x8c\x5a\x6d\x7a\x00"
-  "\xa9\xdd\xd3\x58\xe5\xe2\x72\xa9\xed\x29\xfe\x7c\x54\xd9\x65\x3e"
-  "\x22\x4c\x32\xc2\x4e\x47\x98\x54\x19\xaf\xc7\xca\xf7\xec\x8b\x76"
-  "\x5b\xdd\xd7\x92\x5e\x74\xf5\x03\xe9\x32\xe1\xbd\x56\xc2\x99\x26"
-  "\xda\x1c\x03\x07\x47\x65\xad\xa1\xbc\x56\x09\x2e\x96\xb7\x27\x32"
-  "\xb5\xd9\xa3\xd2\xac\x1c\x0b\xab\x55\xc2\x5e\x27\x60\x97\x64\x21"
-  "\x6c\xfa\x58\xd8\x18\x25\xec\xf5\x02\x36\x79\x06\xc2\xae\x1b\x0b"
-  "\xeb\x9e\xae\x80\xbd\x41\xc0\x2e\x3d\x89\xb0\x19\x63\x61\x75\x4a"
-  "\xd8\x38\x01\xfb\x10\xd1\xb0\x61\x2c\x6c\x8a\x12\xf6\x1b\x02\xf6"
-  "\xfe\x2a\x84\xcd\x1c\x0b\x6b\x51\xc2\xde\x28\x60\x1f\x48\x45\xd8"
-  "\xac\x40\xd8\x46\xae\x07\x30\x5b\xd2\x83\x6f\x0a\xd8\x07\xdd\x08"
-  "\xab\x0f\xd2\xb6\x30\x8e\x57\xc0\xce\x10\xb0\x8b\xed\x08\x9b\x1b"
-  "\x44\x16\x4a\xd8\x99\x02\x76\xed\x31\x84\x35\x04\x91\x85\x12\xf6"
-  "\x26\x01\xbb\xa2\x16\x61\x8d\x41\x64\xa1\x84\xbd\x59\xc0\x3e\x9a"
-  "\x82\xb0\xa6\x20\xfc\xf5\xc1\x46\xae\x74\x20\x4c\x31\xf2\xa4\x27"
-  "\x08\x6f\x95\x38\x67\x09\x9c\xab\x9b\x10\xde\x12\x84\xb7\x4a\xd8"
-  "\xd9\x02\x36\x3d\x1d\x61\xcb\xc6\xc2\x82\xea\xa0\xe0\xef\x42\x89"
-  "\xbf\xb7\x08\xf8\xc7\x01\xe1\xcb\x83\xf0\x97\xf2\x5b\x25\x5b\x8b"
-  "\x17\xb0\x69\xb1\x08\x5b\x15\x84\xbf\x4a\xd8\x5b\x05\x6c\x66\x1d"
-  "\xc2\xd6\x06\xe1\xaf\x12\xf6\x36\x01\xfb\x24\xe9\x64\x5d\x10\xfe"
-  "\x2a\x61\xbf\x25\x60\x33\x8c\x08\x5b\x1f\x84\xde\xd9\x0a\xd8\x04"
-  "\x01\xfb\x0c\xd1\xdb\x10\x44\x16\x4a\xd8\x39\x02\xf6\xb9\xb9\x08"
-  "\xdb\x14\x44\x1e\x4a\xd8\xdb\x05\xec\x7a\xb2\xe3\xc3\x41\xe4\xa1"
-  "\x84\xbd\x83\x45\x3e\xbb\x4e\xf2\x8b\x47\x02\x61\x51\xf6\xc2\x27"
-  "\x5a\x61\x2e\x8b\xdc\xe8\xc4\xdf\x04\xc7\xdf\x45\x8d\xe2\xb3\xba"
-  "\xef\x22\x7f\x23\xf9\xb0\x79\x2c\xf2\x89\x0c\x09\xdf\xb1\x31\x75"
-  "\x5b\x35\x4a\xd8\xf9\x2c\x72\x9b\x51\x82\x6d\x1e\x0b\xab\x55\xc2"
-  "\x2e\x60\x91\xd9\x32\x9d\x2d\x63\x61\x63\x46\x61\x59\xe4\xf3\x1a"
-  "\x84\x39\x7e\x48\xf2\x8d\x0a\x3a\x17\x2a\xf0\xdd\xc9\x22\xf5\xcd"
-  "\x12\xbe\xd6\xb1\xf8\x74\x4a\xd8\x85\x2c\x72\xfb\x0c\x09\xb6\x7d"
-  "\x2c\x6c\x8a\x12\xf6\x2e\x16\xf9\x42\x96\x04\xdb\x31\x16\xd6\xa2"
-  "\x84\x4d\x62\x91\xb9\xb1\x12\x6c\xe7\x18\xde\x93\x1d\x58\x31\x16"
-  "\x10\x3e\x69\x11\x8b\x7c\xa9\x5d\x82\xf5\x8b\x03\x14\xfd\xf0\xdd"
-  "\x42\xee\x5b\xda\x51\xee\x3c\x0e\x44\x9f\xdf\x1b\x2c\xc6\x30\xdc"
-  "\x0e\xd7\x9c\x55\xef\x36\x88\x3e\x49\x3e\x9b\xbe\x98\xf7\x63\xde"
-  "\x86\xfb\x32\xd7\x38\x99\x5b\x99\x56\xa3\x66\x3d\x0b\x9c\xa0\xe1"
-  "\xe7\x1d\x4f\x29\x2e\xb7\x63\xba\x63\xe6\x7d\x96\xa1\xca\xdd\xc5"
-  "\x76\xd5\x37\x73\xe9\xfc\x0e\xfc\x5d\x6e\x87\xac\x06\xfa\x5d\x63"
-  "\x65\x2e\x3a\xf3\xd6\x53\xbd\x4c\x67\xf3\x0e\xd0\xd9\x57\x2e\xc4"
-  "\xe1\x3a\x63\x80\x30\x5d\x3e\xd0\xbb\x96\x61\x9b\x69\x00\xce\xa8"
-  "\x77\x77\xb1\x6d\xfa\x64\xa4\x21\x05\xeb\xcb\x3a\x8d\xcf\x9c\x06"
-  "\x8c\x81\xb0\xaf\x4c\x6e\xcd\xa7\xf3\x84\x76\x7b\x1c\x53\x4a\x52"
-  "\xd8\xde\xf5\xfd\x86\x52\xb8\x19\xe9\xe6\x7b\x57\xf9\xd9\x22\x17"
-  "\xf4\xf7\x79\xa7\x2c\x4b\xa6\x33\x47\x58\x7d\xa9\x4e\x9c\x47\x52"
-  "\x7c\x2f\xa7\xd9\xca\x7a\xd8\x8c\xfb\xd2\xbd\xc3\x65\x16\xba\xfb"
-  "\xa0\xb5\xf4\x2c\x9c\x56\xe4\x39\xbe\x51\xca\xcf\x2a\xc1\x36\xa5"
-  "\x07\x3d\xc3\xc3\x0a\xd1\x6c\xff\xb2\x8c\xa1\xca\xe2\x4c\x8c\xd7"
-  "\x8e\x8b\x36\x16\xe7\xda\xc1\xb9\x52\xfa\x6d\xb2\xc3\x17\x2e\xe9"
-  "\x77\x99\x5d\x35\xad\x53\xfa\x5d\x2b\x9f\xa5\x12\xfc\x6c\x97\x65"
-  "\x73\xb1\x6d\xa9\xde\xb7\x32\xb4\x14\x5f\xd2\x39\x6b\x6c\xca\xb2"
-  "\xb9\xba\x9b\xe8\x4e\x8b\x92\x04\xac\x33\x55\x9c\x8f\x59\x7c\x0e"
-  "\xbf\xa3\xa5\x6f\x87\xf4\xcd\x08\x86\xcb\x6d\xc6\x7d\x3d\xac\x6a"
-  "\x47\x1c\xb5\xad\xd4\xc3\xbc\x88\x57\xcf\xca\xdf\x2d\xb7\x99\xfa"
-  "\x41\x9c\x2b\x5d\xf2\x0d\x7e\xce\x0d\xf1\x0e\xf9\xcb\x22\xde\x2d"
-  "\xe7\x75\xed\x2f\x49\x51\xd2\x45\x07\xb2\x24\xde\xb9\xf0\xae\xa4"
-  "\x45\x77\xdf\xb3\xf8\xde\xcd\xcf\x6d\xc9\xca\xde\xfa\xbc\x3e\xe7"
-  "\x85\x17\x73\x5f\xca\xdb\x66\xd8\x9e\x5f\x60\x2c\x2c\xda\x61\xda"
-  "\xb9\x8b\xe0\x46\xdb\xf0\x56\xaa\xca\xa9\x06\xac\xe7\x41\xaa\x67"
-  "\x3f\xa7\x07\xd3\x04\xff\x4b\x8a\x35\xba\xe0\xb1\xad\x0d\xa3\x4d"
-  "\x3a\x67\x79\x40\x5d\xf2\x47\x3a\xf3\x19\xe5\xac\xb2\x35\x3c\xdc"
-  "\x4a\xe7\xf0\xf7\xa9\x4b\x3a\xbb\x1d\x0f\xb7\xd2\x3d\x10\x6d\x71"
-  "\xfd\x10\x3f\x9b\xce\xea\x2f\x69\xa1\xfc\xc6\xdb\x00\xda\xb1\x6c"
-  "\x30\x9c\xb3\x63\x20\xee\xb5\xeb\x99\xa3\xee\x7a\x36\x40\xf8\xeb"
-  "\x0e\xb0\x7e\xc7\x6e\x3d\x54\xe3\x33\xea\x5a\xcc\x19\x75\xe9\xfe"
-  "\xb6\x19\xfc\x3c\xf3\x19\x87\x0e\xb0\xbe\xb2\xeb\x59\xdf\xde\x03"
-  "\x6c\xa0\xf1\x7a\x66\x8f\xaf\x83\xa8\xa1\xca\xd2\x14\xbb\xba\xa4"
-  "\x9e\xeb\x2d\xe6\x7b\x23\x4b\x16\xd7\x60\xde\x02\x37\x84\x35\xe2"
-  "\x33\xa6\x39\xdb\x74\x82\xee\x77\x3e\x77\x85\x23\xbe\x78\x36\x92"
-  "\xab\xaa\xc6\x7a\x84\x9c\x4a\xdf\x6d\xc7\x9e\x14\xeb\x73\xd8\x5c"
-  "\xa7\xc1\xae\x2e\x3d\xd6\xf8\x05\xaf\x2f\xda\x56\x3f\x00\x84\xef"
-  "\x27\xf9\xae\xf0\x82\x1b\x99\x1b\x61\x6b\xbd\xbb\x73\x55\x08\x93"
-  "\x8b\xb8\x9d\xca\xf6\x24\x6c\x7d\xc9\xa8\xcb\x2b\xcc\xcd\x9d\x13"
-  "\x09\x09\xfc\xdb\xef\x0e\x09\x23\xe2\x83\xd7\x0e\xb0\x76\x6c\x67"
-  "\x2b\xb6\xb7\xa3\x0b\x23\x68\xd4\x19\xc0\x36\xd5\x9e\x51\x9b\xc3"
-  "\x31\xfd\x38\xfe\x3e\x8e\xb4\x77\x88\x7b\x07\x6a\xef\x64\x95\xa5"
-  "\xc7\x91\xce\x0e\x3a\xa7\x96\xce\x9f\x1a\xdc\xb1\x4e\x85\xed\xae"
-  "\x43\xb8\x0e\xdd\x8d\x70\x2b\x96\xdb\x8f\x74\x1c\xc6\xdf\x04\xcf"
-  "\x6d\x03\xe1\xdb\x45\xbb\x6a\xf9\x59\xf6\xc8\xab\xd6\x83\xd7\xb3"
-  "\xaa\xa1\x4a\xb3\x9e\xce\xa7\xe3\xe7\x76\xe3\x33\xf2\xa5\x03\x61"
-  "\x6b\x07\xcd\xeb\x54\x38\x9e\x52\x35\xfa\x70\x2e\x26\x9a\x88\x0e"
-  "\x1a\xd3\xfd\x0e\x23\x28\xef\x48\x06\xcc\x73\x81\xea\x77\x7d\x00"
-  "\x0d\x07\x58\x13\x7e\x1a\xf0\x53\xff\x5b\xcc\xfb\x0d\x7e\x3a\x30"
-  "\xbd\x13\xbf\x7f\x8b\xdf\xbf\xe9\xe3\xef\xe0\xe2\x88\xee\x82\x62"
-  "\xd6\xbf\xa0\x1e\x6e\x21\xfc\xa8\x5b\x4f\x9d\x56\xd7\x94\x13\xed"
-  "\x74\x16\x24\x8b\x34\xbb\xfd\xcf\xcc\xdb\x63\x00\xcc\xc7\xef\x32"
-  "\xf1\xad\xfc\xec\xe9\xc4\xcf\x80\xf8\x6d\x4d\xc2\xdf\x1b\xa4\xdf"
-  "\x69\xf8\x59\x77\xf9\x4f\x20\xbe\x50\x1f\x6b\xeb\xc4\x61\x27\xf4"
-  "\x71\x4f\x0c\xae\xcc\x04\xea\x97\x7b\x40\xfd\x1d\xad\x7f\xfa\xcb"
-  "\x76\x91\xf6\xca\x51\xf1\xfc\x4a\x8b\xf4\xdd\x07\xea\x2a\xe4\x53"
-  "\x15\xe2\xdf\xaf\x13\x69\xfb\xe7\xe2\x37\x8e\xb0\x6b\x2c\xfe\xf5"
-  "\xd7\x62\xf9\xda\x58\x92\xe7\x08\xdd\x81\x80\xb2\xb4\xab\xcd\x9d"
-  "\x24\xa3\x1a\xa1\x5b\x2a\x2f\xe3\x69\x1d\xa8\x5b\x0d\x3e\xfd\xd9"
-  "\xf3\x73\x7f\xfd\xd9\x73\x24\x40\x7f\x6a\xc9\x1f\x61\xb9\xd8\x46"
-  "\xa1\x2f\xc7\x07\x77\x67\xe1\xf3\x9e\xa3\x88\xe7\xb8\x6e\x23\xe1"
-  "\xb0\xf2\xf1\x64\xcd\x59\x1c\xfb\xe9\x41\x43\xfe\x65\x40\xbd\xc7"
-  "\x43\x3a\x4b\x75\x4b\xf5\x0a\x5a\x90\x3e\x4c\x6b\x22\xfa\xb6\x21"
-  "\x5e\x7c\x3e\x8c\x70\x4d\x36\xf8\x5c\xa6\x8d\x97\xa9\x7c\x01\xf5"
-  "\x51\xa2\x97\x70\x52\x39\xe6\x6b\x57\x07\x95\x91\xea\x7e\x17\xd3"
-  "\x69\xac\x08\xe6\xcf\x20\x8c\xd6\x2b\x93\x4e\xd2\xb7\xcd\x9d\x88"
-  "\xb6\x94\x06\xde\xa1\x0c\xc0\xe1\x7e\x22\xda\x5b\xc4\x69\xb5\xb5"
-  "\x6e\x7e\x31\x24\x12\x3e\xf2\xeb\x76\xb5\x35\xa3\x91\x6c\x51\xe0"
-  "\xfa\x91\x38\xf7\xca\xdc\xf1\x5b\x03\xf0\x7a\x0e\x11\x3d\x98\xaf"
-  "\xa8\xb7\x8e\xc6\x82\x35\xbb\x44\x5b\xb1\xae\xc3\x58\xfe\x18\xb5"
-  "\x9d\xf8\x89\xf9\x2d\x88\xc7\x41\x79\xfc\x3c\x6d\xd1\x9e\xc3\x74"
-  "\xe6\x2a\xf1\x83\xe0\xe9\x5e\x13\x71\x06\x9f\xf9\x3a\xce\x37\x2c"
-  "\x4f\xf2\x60\x58\x07\xe1\x30\xbb\x99\x9b\xa1\x3f\xfa\xc1\x2e\x17"
-  "\xf6\xed\x65\x39\xfe\xf2\xd9\x9b\xa6\x94\x0f\x96\x3b\x86\xe5\xdb"
-  "\x19\xb6\x91\xfc\x09\xd6\x19\x4d\x77\x29\x60\x5a\xad\xb7\x12\x71"
-  "\x14\xb9\xf8\xfc\x08\xe2\x79\x1a\x69\xa9\x25\x3c\x48\x4f\xbb\x84"
-  "\xab\xee\x97\xc5\xfe\xb2\x96\xf0\x1d\x26\x99\x73\x7b\xde\xc5\xdb"
-  "\x84\xbe\xab\x6c\xce\x21\x91\xd7\x82\x30\x2d\x6c\x24\x0d\xe8\x0c"
-  "\x53\xd1\x97\xf0\xbc\x66\xf3\x25\x2e\xdf\x76\xe1\xd7\xca\x56\x14"
-  "\x94\xb0\x7e\x1f\xdd\x65\x20\x9f\x03\x2b\xd1\xdd\x4c\xf5\xb1\x1d"
-  "\x1b\x78\xdf\x4a\x75\x50\x79\x81\x6f\xef\x29\xc2\x27\xf3\x6a\x3e"
-  "\xd2\x21\xf8\xb5\x37\x06\xd3\x0f\x93\x2e\x72\xbe\xa1\x1f\x1d\x34"
-  "\x93\x2e\x96\x69\xb0\x3c\xf9\xd0\xe3\x83\x3b\xe8\x79\x6f\x3d\xf7"
-  "\xb1\xa3\xf9\x7b\x57\x52\xbe\x0d\xc7\xda\x35\x2f\xa2\x2e\x79\x01"
-  "\x6e\x89\x85\x44\xa7\x95\xb7\xed\xa8\x73\x77\xaa\xaa\x0d\xa3\x15"
-  "\xa2\x13\x79\xd4\x82\xb4\x1e\xc5\xbe\x66\x80\x68\x45\x7f\xdd\xcc"
-  "\x7e\x90\x01\x44\x33\xfa\x33\x89\xbe\x7d\x33\x25\xd9\x37\x53\x1b"
-  "\x89\x9f\xf3\x85\xef\xc3\xbc\x97\x7f\x49\xb4\x2b\xda\xed\x52\xf2"
-  "\x98\xb7\x1b\xe5\x40\xf2\x22\xb9\xf8\x70\x96\x91\xee\xd7\x22\x2e"
-  "\xe9\xbc\x36\xa1\x1b\xc4\xeb\xda\xeb\x59\x27\xc1\xfb\x60\x5f\xe6"
-  "\xf7\x23\x96\x62\xdd\x0b\x0c\xd8\xa7\xa3\x5d\xd0\x59\xbe\x88\xf7"
-  "\x28\xdd\x59\x83\x38\x5a\x88\xa7\x08\xb7\x8f\xf4\x11\x9f\x3b\x25"
-  "\xba\xcb\xb0\x3f\x9f\x8b\x9f\x64\x9f\xfd\xbf\x5c\xe8\xaf\x5f\xfb"
-  "\x02\xed\x9f\xe4\x5d\xeb\x35\xa7\x01\xd7\x87\x7c\xd0\x9d\x57\xbf"
-  "\x3c\x4d\xea\x3b\x24\x59\xbf\x9c\xdd\x86\xf6\xa2\xc0\x31\x10\x20"
-  "\xeb\x16\xae\x8f\x3b\x56\xd2\x9d\xbf\x2a\x2c\xdb\x22\xf0\xec\xe3"
-  "\x6d\xe6\xfa\x64\xe5\x3a\xd0\xc9\x76\x60\x3b\x47\xf5\x60\x5f\x9a"
-  "\x24\xe7\xce\x00\x9e\xc8\xbe\xab\x8e\xee\x5c\x20\x9f\x84\x71\xe6"
-  "\x7d\x43\x23\x3e\xbf\x44\xb2\xf7\x72\xd9\xef\x73\x34\x8a\xfe\x56"
-  "\xf2\x5b\xfb\x44\xfe\xf5\x7e\x3a\x4c\x6d\xba\x95\xeb\x2f\xd1\x62"
-  "\xde\x40\xb4\xb4\x70\x3a\xcc\x3a\xc0\xbc\x06\xaa\xdf\xae\x7e\x39"
-  "\x41\xb2\x57\x09\x57\x99\x9b\x70\xed\x45\x5f\x45\x34\x61\xdd\xe5"
-  "\xdc\xff\x3d\xc4\x79\xe2\x91\x68\xef\x70\x59\xa9\xec\x1e\xc7\x25"
-  "\x35\x2f\xdb\x81\xbf\xb3\x5c\xe2\x5c\xe6\x48\x2c\x7f\x44\xf7\x1c"
-  "\xc1\xbf\xb2\x81\x7c\xb4\xee\x19\xfe\x7b\xb9\xee\x49\xd4\xd5\xb3"
-  "\xa0\x41\x7c\x5a\xd2\x51\x59\x2f\x06\xd4\xaf\x2c\xa2\x98\x1d\x79"
-  "\x7d\x14\x63\xa4\x23\xc4\x6f\xd2\x65\x8c\x91\x92\x86\x2a\xbf\x93"
-  "\x25\xeb\x2d\xd6\xd3\x40\xbc\x17\xf2\xf9\xce\x8f\x50\x8f\x5b\x7c"
-  "\xba\xf5\x9d\x1f\x49\x7c\x3c\x82\x7c\xd4\x62\x7d\x73\xa4\x76\x1d"
-  "\x41\x78\x8c\xc5\x5e\xf9\x86\x44\x7b\xbd\x04\xff\x91\x2c\x07\xc9"
-  "\x56\x3b\xab\xc9\xff\x72\x19\x94\x6f\x90\xca\x1e\x16\x75\x95\x3f"
-  "\x2b\xc3\x52\x8c\x28\xce\x5b\x2f\x7f\x96\xfc\xe0\x02\x94\x3d\xf7"
-  "\x7d\xfc\x3e\x27\x91\x46\xb6\x23\xea\x78\x85\xdf\x8f\xbd\x17\xe3"
-  "\x1e\x9f\x1e\x95\x27\x05\xf8\x27\xf2\xc5\xb5\xdd\x88\x83\xfc\x29"
-  "\xe9\x12\xf9\x54\x1a\x33\x20\xbe\x28\xc9\x7e\x24\x9a\xcb\xbf\xef"
-  "\xaf\x2b\x95\x9f\xa1\xae\xcc\x53\xe0\xae\x0d\xd6\xcf\x35\x0a\x1f"
-  "\xd8\x20\xb5\xed\x13\xa9\x6d\x47\xa5\xb6\x7d\x22\xb5\xed\x08\xd6"
-  "\x81\x7c\xab\xfc\xa1\x82\x8f\xc8\xb7\xca\x69\x12\x7c\x0b\xf9\x72"
-  "\x9f\xbd\x56\xac\x92\x6d\x79\xac\xbf\xa8\xe4\xf6\xe0\xa3\xab\x22"
-  "\x21\xc0\x5f\xb4\x04\xf7\x17\xe5\x2e\xa9\xbd\x4d\x01\xb6\x71\x58"
-  "\xd0\x2e\xf5\x2d\x28\x87\x6e\xe7\xb0\x74\xb6\xb8\xf9\x3a\xf2\x9f"
-  "\x54\xb7\xb2\x0f\x3a\x24\xf8\x2a\xd9\x72\xc5\xb9\xb1\x72\xa8\x38"
-  "\xae\xb4\x67\x92\x35\xf9\x04\xc2\x41\x32\xe5\x71\x25\xa6\x09\xb9"
-  "\x56\x50\xdc\x5a\xab\xf4\xd1\x08\x5b\xe7\x65\x64\x2f\x15\xad\xfe"
-  "\xb6\x58\x31\x57\xb2\x45\xa9\xee\xca\xef\xa2\x8c\x12\x7d\xf5\x56"
-  "\x26\x05\xd4\x4b\xb2\x69\x27\x3e\x48\x32\x2d\x91\xfb\x34\x82\xc7"
-  "\xb2\x26\x2c\xa3\x0f\xe8\x1f\x6b\x89\x3e\xbb\xba\xdc\xce\x7d\xd6"
-  "\x01\xee\x2b\x4c\x43\x9c\x9e\xca\xdc\x46\xa9\x9f\xc0\xb4\x44\x29"
-  "\x6d\xb1\xd4\x97\xc8\x7a\xf3\x71\x00\x4d\x1d\xc1\xe3\xa3\x72\xbb"
-  "\x1c\x1f\x71\x5c\xdc\x17\x55\x76\x4a\xed\xa3\xb4\x79\x22\xad\xbc"
-  "\x8e\xd2\xaa\x05\x1f\xea\x18\xef\xaf\xca\x17\x4b\xfd\x15\xd9\x97"
-  "\xda\xae\xfe\xce\x11\xb2\x31\x7a\xb6\xab\x5f\xd1\x11\x7e\x9b\x65"
-  "\x98\xc6\x10\xf5\x98\x97\x4a\xfe\x80\xfc\x85\x6e\xab\xf0\x1b\xba"
-  "\xd5\xfc\xfb\x25\xf2\x3b\x14\x87\x50\x3e\xc2\x25\x91\x2f\xc2\xf4"
-  "\x3d\xba\x47\x30\x2e\xf8\x9b\x16\xf1\xbe\x92\x25\x95\x7d\x9d\xc7"
-  "\x0a\x7f\x4b\x0b\x93\xd3\xe4\x72\x68\xeb\xcb\xa9\x1c\x95\x97\xfd"
-  "\x17\xf9\x2e\x37\xf9\x26\x51\xdf\x1f\x25\x1d\xe7\xe3\x06\x39\x2e"
-  "\x1a\x51\x2b\x60\xe9\x7c\x67\xee\xd3\xaa\xe2\x85\x3f\xab\xba\x8e"
-  "\xca\x72\xf9\xa1\xaf\x2c\xbd\xc4\x3e\x69\xcc\x07\xcd\xa1\xcf\x79"
-  "\x8c\x15\x2b\xe8\xac\x32\x88\x76\x54\xdd\xcb\xdb\x21\x7c\x6a\xad"
-  "\xa0\xc5\x1c\x7b\x68\x98\xe7\x3d\x41\x6d\xa1\xbc\x1a\x45\x1e\x1b"
-  "\x49\xa0\xbc\xed\x9c\xae\x80\x72\xde\x11\xfd\x18\xf8\x46\x71\x6f"
-  "\x96\xf6\xd0\x01\xd9\xf7\x56\x39\x24\x3a\xdf\x96\xfd\x2e\xf2\x25"
-  "\x99\x7c\x2f\xcf\xdb\x2a\xc1\xac\x96\xbe\xb9\x7f\xaf\xfa\x58\xf0"
-  "\x35\x4e\x2d\xf1\x3b\x55\x6a\xc7\x67\x7c\x9c\xfd\xb7\x0c\xe4\x6d"
-  "\xd5\x49\x99\xb7\xca\xdf\x64\x3f\x58\x7f\x0c\x3d\x73\xbd\x2f\xe6"
-  "\x63\xd8\x06\x82\x21\x9a\x44\x1f\xf1\x4a\x67\x60\x4c\x7d\x46\x5d"
-  "\x93\x43\xfd\x92\x88\x55\x6b\x56\x48\x73\x30\xd0\x9a\xff\x2f\xd8"
-  "\x2f\xec\xaf\x93\x7d\x0c\x1b\x4a\xc3\x31\xff\x69\x84\xd9\xcf\xef"
-  "\xb8\xa5\x33\x81\x95\x30\xe4\x9f\xde\x19\xb6\x4b\x38\xf7\x1b\x64"
-  "\xbf\x41\xbe\xa4\xdb\x79\x5a\x8a\xe9\xaa\x75\x87\x24\x5f\x72\x5e"
-  "\x5d\x3d\xcb\x3f\x0e\xab\x9e\xe5\xef\x33\x6a\x16\x05\xfa\x0c\x8c"
-  "\x9b\xcb\x86\x2a\xf7\x3b\xfd\xe2\x00\x4c\x1b\xdf\x77\xec\xef\x20"
-  "\x1b\xa5\x7b\x16\xb8\x7f\xe2\xf3\x4a\xd5\x15\x32\xcd\xe4\x37\x07"
-  "\x77\xcb\xf3\x17\x35\xb7\x52\xac\xe6\x5f\x5f\x75\x96\x9f\xef\xa4"
-  "\xfa\x64\x7c\x1a\xa0\x73\xfa\x91\x0f\x34\xe7\x52\x9d\x24\xf9\xf9"
-  "\x26\x3f\x5f\x29\xf5\x61\xe4\x27\xfd\xfb\x2a\xf3\x75\xfe\x7d\x55"
-  "\xcd\xb4\xb1\x3e\xb2\xda\x3e\xf1\xbe\xaa\xba\x85\xfc\x96\xec\x23"
-  "\xfd\x7d\x41\x75\xdf\x21\xbf\x58\xb6\x3a\x57\x8e\x65\x7d\x7e\x74"
-  "\xbf\x9b\x7c\x14\xd6\xdf\x22\xea\xae\xd9\x80\xfd\x7e\xa6\x5c\x37"
-  "\xe6\xd7\x75\xe3\x88\x8c\x55\x96\xa2\x1e\xed\x4f\x91\x62\x40\x6e"
-  "\x9b\xc3\xfc\xac\xf4\xaa\x72\xd4\xbf\x48\xd2\xb3\xd6\xbc\xcf\xa1"
-  "\xcf\xd7\x57\xb4\x0f\x6e\x1b\xe5\xef\x39\x65\x5c\x78\xf0\x00\x2b"
-  "\xc7\x7a\xda\x95\x6d\xdc\x8f\x69\x35\xd2\x1c\x02\xe7\x2d\xc7\x55"
-  "\x53\xdf\x78\xc0\xbf\x6d\xa2\x1d\x35\x9d\xd4\x0e\x1a\x13\x61\xfd"
-  "\x14\x67\x1f\xc1\x98\x0f\x7f\x7f\x87\xec\xe0\x88\x1c\x17\x5d\xb2"
-  "\x2a\xe3\x2b\x73\x2e\xf9\x4a\x69\xec\xd9\x81\xf1\x4e\xad\x72\x2e"
-  "\x66\xd5\xb2\x74\x9d\x21\x3f\x27\xcf\xb8\x75\xa1\x2e\x27\x2f\xc7"
-  "\x98\xb3\x39\x37\x67\xd7\x66\x63\xce\xb6\xbc\xb9\x2f\x6d\x7e\x3e"
-  "\x67\x8b\x6e\xc7\xe6\x02\x5d\xa2\xe9\x56\x53\x24\xf8\x40\x97\xe8"
-  "\x36\x17\x14\x14\xbe\x94\x9d\xa5\xcb\xcb\xd9\x32\x2f\x3f\xbb\x20"
-  "\xdb\xa8\xdb\x9c\xbf\xad\x30\x2f\x4b\x77\x6b\xd6\xfc\x5b\x13\xef"
-  "\xce\x8a\x54\xce\xa1\xcd\x8e\x81\x01\xef\x17\x9f\xf6\xd7\x7c\x01"
-  "\xda\x68\x95\x21\x3f\xda\x94\x93\x27\xe6\xed\xbe\xbb\x68\x41\x1d"
-  "\x18\xe8\x2e\x45\xba\x33\x8c\x55\xd6\xa6\xe1\xb7\x86\xe0\xb0\x9d"
-  "\x3a\xba\x4b\x11\x69\x9f\x31\x54\x59\xeb\xb2\xab\xeb\xec\xfc\x3e"
-  "\x30\x4c\xc7\xb6\xcd\x60\x5f\xfc\xa6\x1f\x63\x36\x03\xad\x0b\x6e"
-  "\xfc\x02\x62\x6b\x8b\x40\x83\x9f\x28\xfc\xc4\xd0\x5d\x8b\x43\x95"
-  "\xdf\x9d\x6b\x57\xbf\x9a\x26\xce\x5b\xfe\x6e\xa7\x23\xe2\x1d\x03"
-  "\x2b\x7f\x47\xba\xd3\xe3\xbb\xbf\x91\xe7\x7a\xd7\xec\x83\x35\xa4"
-  "\x9f\xa7\xd5\xdf\xe5\x73\xd8\x7b\x51\x97\x69\xce\x74\xf0\x17\x0f"
-  "\xa6\x60\x3c\x78\xaa\xf5\x46\x9e\xf7\x1b\xa7\x1a\xa2\x90\x2e\x4d"
-  "\x5b\x71\x22\xbc\x86\x75\x15\xc4\x31\x86\x75\xd4\xca\xf3\x69\xd8"
-  "\x86\x18\x6c\x4b\xaf\xd4\x8e\x02\xde\x8e\x03\x2c\xbe\x6e\x3a\xd2"
-  "\xf7\x2a\xa7\xe7\xb8\xdc\x06\xa4\xbb\x17\x69\xa2\xfb\xd0\x62\x88"
-  "\xae\x60\x73\x7d\x34\xdf\x75\x46\xfd\x6a\xb8\xb7\x08\xf9\x76\x93"
-  "\xb8\x27\xa2\xe6\x90\xb0\x3f\x6c\x57\x72\x23\xfe\xae\xfe\x1c\xa2"
-  "\xf6\xd3\x3d\x7e\xd6\x9b\x59\x97\xd3\x0d\x36\x7d\x2f\x44\xef\x64"
-  "\x0e\xf6\xc1\xa7\xfd\xa2\x4d\xaf\x26\x92\x6f\x78\xef\x85\x5e\x0d"
-  "\xb5\x09\xfb\x8a\xa8\xc6\xcf\x43\xce\x2d\x6a\x5e\xbb\x9e\x39\xd9"
-  "\x5b\xca\x98\xeb\xd5\x37\x88\x27\x14\x6f\x0d\x5a\xe9\x5e\xb8\x57"
-  "\x2d\x48\x77\xaf\x14\x1b\x3b\xd9\xc8\x06\x45\x2c\xf5\x2a\xe9\x99"
-  "\x33\x04\x6e\xad\x8c\x9b\xee\x07\xa4\x32\x42\xfe\xaf\x85\x63\x19"
-  "\x87\x02\xbf\x3d\x10\x3f\xe1\xc4\xdf\x0e\xb9\x1e\x31\x0e\x7f\x95"
-  "\x62\x02\x07\xea\xb2\x23\x44\x7d\xf1\xaf\x1e\x60\x27\x6d\x98\x5e"
-  "\x73\x09\x34\x08\x8b\xfd\x06\xe1\x7f\x2d\xc5\xae\xae\x3d\x4c\xf8"
-  "\xf7\x5e\x0f\x50\x86\x30\x83\x95\xdf\xed\x75\xf2\xbb\xfa\x5e\x43"
-  "\xfb\x2f\xed\x09\x9c\xcb\x96\xf4\x79\x49\x80\x3e\xa7\xbc\x4a\x31"
-  "\x21\xf6\x04\xa4\x43\x35\x17\xb1\x1f\xc6\xe7\xf9\x75\x90\x40\xf5"
-  "\xe0\xef\x1e\x9a\x0f\x41\x9c\xc7\xe4\xfa\x18\xea\x7f\xb5\x57\xcc"
-  "\xc1\x48\xba\x35\x97\xe6\xaf\xcd\x26\xc6\xda\xd0\xbf\x13\x8d\xa4"
-  "\x63\x58\xa6\x4f\xd6\x29\xd4\xf5\x93\x5c\xaf\x62\x21\x81\x55\xbe"
-  "\xa6\x6f\x9c\x8e\x70\xa8\x57\x87\x50\x9f\x48\xaf\x86\x2a\xeb\x62"
-  "\x64\x9d\x42\x5d\xeb\x21\x38\xa4\x21\xf2\xd8\xae\x14\x0d\xf9\xc8"
-  "\x3e\x75\xdd\x3e\xd2\x31\xf6\xbd\x47\x7b\xd9\x0d\xeb\x7b\x85\x9c"
-  "\xea\xf6\xd9\x5c\x42\x06\x3e\xbe\xd7\x65\x28\xf8\xde\x83\x7a\x1c"
-  "\x49\x7c\x16\x73\xd5\x75\xfb\x90\xb6\x1e\x1e\x8b\x97\xa0\x0c\x78"
-  "\x5f\x55\x97\x4a\xe5\x25\x1e\x76\xfa\x78\x58\xd7\x14\x8c\x87\x01"
-  "\xbc\xd3\x88\xbb\x02\xeb\x8e\x92\xad\x60\x99\xd1\xfb\xff\x82\xc9"
-  "\x12\xeb\xd0\x68\xea\x40\x4b\x75\xb4\xc7\x12\xfc\xeb\x9a\x60\x75"
-  "\x04\xea\x71\x7b\x13\x00\xcd\x85\x53\xb9\xf8\x58\xe2\xeb\xeb\xc9"
-  "\x41\xe5\xbb\xc5\x8f\x36\xfe\x61\x95\xaf\xa7\xbd\x26\xee\x72\xa5"
-  "\xfa\x8c\xe3\xd1\x17\xaf\x13\xfd\x62\xeb\x6c\xd2\xe7\xd7\xdf\xb6"
-  "\xd5\x03\x50\x9a\xf4\xdc\x30\x88\x7d\x4d\xe0\x7c\x7e\xe8\xf7\x0b"
-  "\xaf\x9f\xf3\x7f\xbf\xf0\xfa\xa9\x50\xef\x17\xfc\xeb\x3d\x30\x87"
-  "\xea\xf5\x36\xae\x53\xf9\xea\x3e\x10\xeb\x0d\x52\xb7\x5c\x7e\x7e"
-  "\x93\x72\xfc\x72\x60\x27\xd1\xd0\x4d\x77\x92\x7f\x73\x9d\x8a\x21"
-  "\x9e\x76\xde\x67\x1f\x30\x89\x78\x85\xe2\xa0\x03\x19\x04\x13\xd8"
-  "\x8e\xd1\x3f\x6d\x2c\xdd\xed\x09\x97\xf8\x43\xf8\x43\x40\x27\x2c"
-  "\xc0\x8d\x7a\x39\x5b\xed\x07\x0c\x2c\xc8\x43\x14\xc0\x37\x39\x3c"
-  "\xc3\x3f\x91\x24\x3d\x3b\xf8\x83\x66\x14\x7e\x34\xff\xef\xf8\x8b"
-  "\x10\xf4\x72\x7c\x2e\x50\x49\xf5\x95\x2b\x20\x52\xc7\x29\xcd\x40"
-  "\x2e\x12\xec\x8f\xa2\x68\xcb\x3a\x1c\x8b\x7f\xf3\x08\x07\x66\xcc"
-  "\x2d\xe1\x97\x9f\x99\xf2\x99\x52\xfc\x9f\xf1\x2f\x6c\x83\xa2\x82"
-  "\x9b\xc3\xb2\xf8\x72\xa3\x9b\x3a\x46\x93\xd4\x4d\x31\xfe\x95\x5a"
-  "\xc2\xf9\x57\x34\xfd\x63\x42\x7c\x09\x98\xff\x4d\x1f\x7c\x98\x73"
-  "\x8f\x02\xf8\x77\x82\xfc\x99\xa1\xdb\x70\xe5\x7f\x37\x29\x7e\xdf"
-  "\x2c\xbe\x66\xb4\x7e\x99\x15\x8c\xfb\xa7\xeb\x89\x90\x7f\xfa\xd4"
-  "\x63\x66\x5a\x30\x50\x1f\xff\x67\xca\xfc\xf6\x93\xa7\x2f\x7f\x56"
-  "\xbc\xff\xf3\xec\x76\xff\xe7\x78\xf7\x97\x41\x7a\x2b\xfd\x63\xb6"
-  "\x63\x3c\x7c\x8b\x4f\x5e\xd1\x01\x26\x13\x5d\x1b\x60\x42\xbe\x3f"
-  "\x89\x9a\x30\x80\x5b\xd3\x15\xc9\x9a\xe0\xd0\xff\x98\xbf\x1b\xf7"
-  "\x48\x0c\xbc\xd9\x11\x33\x26\x33\x30\x8d\x9e\x27\xe9\xa4\xb4\x3b"
-  "\x7f\x39\x06\x9e\xa7\xe9\x14\xcf\xaa\x14\xfc\xa7\x09\x0b\xae\xfb"
-  "\x32\x68\xfd\xfa\xef\xff\x87\x7f\x2a\xb2\x8f\xaf\xff\xfe\x41\x7f"
-  "\x4c\xf4\xe2\xe8\x89\xf8\x17\xfd\xc7\x46\x1d\x25\x93\x32\x98\x94"
-  "\xc0\xa4\x1f\x5f\x4a\x3f\xfe\xf5\xdf\xd7\x7f\x5f\xff\x7d\xfd\xf7"
-  "\xf5\xdf\xd7\x7f\x5f\xff\x7d\x05\xfe\x54\x7c\x1c\xc1\xa4\x3f\xf9"
-  "\xb7\xc8\xa3\x21\x10\x3f\xe7\x44\x8a\x25\xe4\x74\xcb\x22\x50\x69"
-  "\x61\x92\xe6\xcb\x8c\xf1\x74\xa3\x04\x4d\x00\x98\xf6\xd8\xd0\x7a"
-  "\x92\xbb\xf0\xf3\x4d\x45\xfa\x4d\xc1\xc1\xff\x07\xfe\x54\xc8\xac"
-  "\x30\x1c\x03\x86\xc3\x24\x98\x0c\x5a\x88\x80\x48\xb8\x06\xa2\x60"
-  "\x0a\x4c\xc5\xb1\x65\x0c\x4c\x83\xe9\x70\x2d\xc4\xc2\x75\x70\x3d"
-  "\xdc\x00\x71\xf0\x0d\xb8\x11\x29\x9f\x01\x33\x83\xd3\x6c\x81\x94"
-  "\x38\xfc\x07\xff\x4f\x87\x14\xfe\x9c\xf9\x75\xfa\xff\x68\x7a\xab"
-  "\x94\xde\x23\xa5\xdb\xbf\x4e\xff\x1f\x4d\xd7\xfd\x6f\xfe\x9e\xf5"
-  "\xbf\xf5\x5b\x85\x6e\x59\x78\x66\x55\x50\x7f\x18\x98\xaa\x92\xfe"
-  "\x46\x9f\xe1\x32\xe5\xc7\xe0\xf3\x2f\x1f\xf8\x97\x82\x9f\x24\xf1"
-  "\xd3\x0c\x20\xe6\x72\x99\xf2\xef\xb2\x33\x73\x26\x3d\x7e\x8c\xf8"
-  "\xb1\xe0\x67\x2f\x7e\x6a\xf0\xf3\x86\x8c\x47\xc0\xd0\x71\xe9\x76"
-  "\x0d\x40\xcf\x51\x80\x13\x7d\xf8\x49\x03\xf8\x3d\xc2\xff\xdf\xb1"
-  "\x00\xff\xcf\x3a\x80\x93\xcd\x00\xff\xe9\xf4\xe1\xec\xab\xf5\x51"
-  "\x77\xda\x22\x7e\xeb\xf0\xf3\x57\xda\x7b\x8a\x9a\xf4\x39\xdd\xfb"
-  "\xda\xb2\x7c\x5d\x9a\xee\xce\xf9\x49\xf3\x93\xee\xd2\xcd\x9b\xa7"
-  "\x5b\x98\x98\x78\xef\x82\xc4\x45\x0b\x16\xde\xad\x5b\x78\xd7\x92"
-  "\x45\x77\x2f\x59\xb8\x58\xf7\xd2\xce\xfc\x9c\x3b\x13\x9f\xcf\xd6"
-  "\x6d\xcd\xc9\x7f\x69\xc7\xe6\xfc\xec\xcb\x35\xe6\xea\xfe\x88\xb4"
-  "\x99\x5e\xe0\xdc\xf7\xe7\x74\x34\xa8\x0f\x75\x80\xfa\x1d\x13\xf8"
-  "\x72\x12\xa4\x8f\xff\x9f\xea\xd9\x19\xa0\x7a\x46\x07\xaa\x27\xaa"
-  "\x40\xb5\xa6\x1e\x54\x69\xa9\xa0\xda\x8d\x69\x26\x2d\xa8\x0a\x36"
-  "\x80\xea\xa5\x74\x50\x65\xf7\x8d\x4d\xdb\xeb\x12\x69\x8d\x26\x50"
-  "\xbd\x79\x14\x54\x75\x65\xa0\xaa\x3a\x25\xd2\x7e\x8c\x30\x3f\x2c"
-  "\xfe\xc7\x34\xfa\xaa\xff\x26\x12\x07\x8c\xff\xa7\xee\x3c\xfa\x25"
-  "\xd0\xf1\xf5\xdf\xd7\x7f\x5f\xff\x7d\xfd\xf7\xf5\xdf\xd7\x7f\x5f"
-  "\xff\xfd\x0f\xff\x7d\xae\xd6\xc0\xaf\x30\xca\x1b\xb2\x6a\xe3\xec"
-  "\xaa\xc8\xa3\xb4\x2e\x04\x68\xbf\x13\x68\xf9\xf9\x22\xd2\x47\xb9"
-  "\xa6\x24\x6a\xd9\x41\x00\xda\xb3\xf9\xda\x01\xe6\xa0\xfd\x98\xa9"
-  "\x3f\x04\x68\x8f\x07\xa0\x75\x2a\x88\x67\x83\x1d\x72\x35\x62\x4d"
-  "\x12\x73\x52\x3e\xad\x6b\xc2\x74\x23\xa6\x17\x8f\xb3\xce\x85\xaf"
-  "\xa9\x22\x9c\xa9\xb3\x38\x3d\x87\x03\xf0\x10\x8e\x16\x4c\x73\x8e"
-  "\x83\x23\x4a\xa6\xcb\xa9\x06\x15\xe1\x1b\xb4\x42\x9c\xd3\xda\x7a"
-  "\x1d\x96\x75\x62\x9b\x12\xa4\x35\x41\x03\xcc\x0a\x61\xed\x26\x37"
-  "\xed\x0d\x55\x9d\x81\x88\x4f\xf1\x5b\x8d\xdf\x1f\x83\x58\xc3\x49"
-  "\xe5\xe2\x09\x07\x96\x55\x0d\x59\x23\x12\x47\xcb\x22\x6e\xbe\xbf"
-  "\x1a\x22\xde\x75\xaa\x5b\xd5\x02\x36\x26\x42\x82\x55\x23\xec\x06"
-  "\x19\x56\xe4\xa9\x57\x48\x79\xd7\x60\x9e\xc9\x3f\x4f\xf3\xaa\x94"
-  "\x17\x85\x79\x75\x01\xf4\x69\x6c\xc3\x6e\xc0\x7a\x88\x16\x9d\x1d"
-  "\xbf\x69\x3f\x92\x44\x1b\xd1\xd4\x8e\xf0\x16\x82\x4f\xd5\x31\xf7"
-  "\x3a\x1d\x70\x5a\x88\x77\x08\x9b\xd6\xd6\x24\x60\xf1\xf7\x0c\x2a"
-  "\x2f\xfd\xd6\xd1\xfa\x28\xfa\x2d\xd5\x3b\x6d\xc8\x1a\x19\xe5\x4f"
-  "\x13\x80\x94\x37\x1d\xf3\x12\xfc\xf3\x7e\x91\x28\xe5\xdd\x80\x79"
-  "\xa9\xfe\x79\x2a\xb9\x5c\x1c\xe6\x65\xca\x79\x63\xd7\xd7\xe0\xf0"
-  "\x03\xc2\x71\x20\x32\x09\x3f\x93\xb5\xb2\xec\x0a\xe2\x98\xd7\xfc"
-  "\x0d\x5a\x47\xf5\xd3\x5e\xaf\x95\x81\xcd\xe4\x02\xdd\x8d\x60\x3e"
-  "\x0d\x91\x3d\xb4\x4e\xa7\x7a\x17\x68\xcd\x06\xe6\xa2\xbd\xe7\xdd"
-  "\x8e\x01\x30\x3b\x58\x3f\x9d\x35\x54\x7a\x11\xb4\x74\x77\x63\xe9"
-  "\x76\x88\x6b\x2f\xfe\x4b\xd0\xb5\x41\x5e\x35\x03\xf3\x0c\x2a\xdb"
-  "\x07\xdd\x0d\x7d\x60\x6e\xf0\x2f\x6b\x9e\x09\x71\x5d\x74\x6e\x91"
-  "\x15\xa2\x89\x8e\x76\x9d\x1b\xdc\x91\x3f\xed\x2d\x7e\x03\x34\xe6"
-  "\x59\xa0\xee\xca\x6a\x95\x68\xb9\xa6\x9e\x68\x29\x3b\x0b\xda\x1f"
-  "\x6c\x45\xd9\x9f\x25\x7a\xff\xbd\xf7\x9d\x5d\x2e\x75\x5b\xdc\x4a"
-  "\x68\x8b\x3b\x05\xed\x71\x4b\xa1\xdd\x94\x0a\xd5\x67\x21\xaa\xcd"
-  "\x95\x0c\xed\x9a\x87\xd0\x36\x52\xc1\x36\x80\xbf\x75\x1e\x84\x71"
-  "\xf2\x7d\x17\x67\xe0\x9a\xf2\xba\x17\x40\x6b\x17\x38\x51\x9e\xd7"
-  "\xd4\xc9\x7b\x08\xe8\x39\x58\x3b\x0a\xbe\x01\x71\x48\x5f\x3f\xd2"
-  "\x72\x2f\xd2\xd2\x15\x1f\x07\x74\xb7\xcb\x64\x5b\xbd\x1b\x34\xc5"
-  "\x10\x11\xc2\x26\x62\xf9\xfe\x63\xd4\xa9\x43\x07\x58\x3f\xe9\xd6"
-  "\xe0\xee\x0c\xb4\xaf\x28\x0d\xd6\x7d\x58\x5a\x97\x37\x60\xfe\x3e"
-  "\x68\x06\x77\x64\xd0\x7a\xe4\x3e\xcc\xd3\xc9\x79\xb4\xaf\x9a\xf6"
-  "\x4b\x2f\x88\xa5\xbb\x7b\x52\xe0\xc3\xe1\x7e\x5a\xf3\x37\x40\xeb"
-  "\x30\x09\x5f\xb4\x09\xc2\xb0\x3d\xe1\x48\xcf\x67\x8d\x98\x7e\x0b"
-  "\xc2\x61\x79\x94\xff\xff\xc5\xf7\xda\xb3\x1b\xd6\x3b\xbd\x37\xac"
-  "\xbf\xe8\xfd\xde\xfa\x41\xf6\xbd\xf5\x9f\x7b\xbe\xb7\xfe\x33\xf3"
-  "\x4e\xd0\x7a\x6e\x58\xef\xe8\x36\x70\x19\xc4\x74\x1b\xce\xd1\xfa"
-  "\x3d\x2d\x9d\x65\xbe\x71\x3b\xca\xde\xfd\x31\x94\xe4\x40\x9c\x37"
-  "\xe2\xdf\x6a\x6d\xee\x3f\xc0\xc6\x62\x60\xf8\xbb\x29\x58\xfb\x06"
-  "\x23\xff\x23\x4e\xe8\xac\x96\xda\xd4\x6b\x57\xbf\xcb\xd7\xc4\x39"
-  "\x22\xda\xe2\xf0\x33\x03\x3f\x3a\xfc\xc4\xb3\xc8\xff\x88\x47\x5e"
-  "\x99\xa7\xee\x51\x01\xed\x1b\x58\xe0\x05\x15\x8a\xc8\x89\xf4\xc7"
-  "\x84\xe0\xdb\x0c\x6f\x65\x8f\xfd\x5b\x16\x28\x1d\x1a\xd2\xd3\xfe"
-  "\x6d\x07\xf9\x13\xf2\x2f\x43\xd6\x29\x29\x76\xf5\x4f\x63\xb8\xee"
-  "\x1f\x60\x4e\x16\xd9\x63\xc7\xf4\x7e\xe7\x6e\xbd\xca\xb1\x5b\xaf"
-  "\x1e\x8c\xec\xf9\x6f\x84\xc9\x42\x98\x34\x89\x87\xfd\x84\x0b\xed"
-  "\xc4\x31\xc5\x0d\x61\x88\xd3\xf0\xb3\x2f\x7a\x35\x07\x0f\xb0\x53"
-  "\x08\x57\x35\x8a\x0b\x71\x23\x1e\xe4\xff\x94\x26\x39\x0d\x79\xdd"
-  "\xb7\x1f\xe1\xa8\xbc\xcd\x95\x42\x7e\xd7\x6e\xcb\xed\xa7\x75\xb3"
-  "\x91\x6c\x44\xd4\x87\x30\xb4\xa7\xd2\x31\xc5\x05\x93\x86\xac\x90"
-  "\x4e\xb8\xa9\x1c\x9d\xa1\x85\xe5\xfe\x9b\x99\xf5\xe8\x97\x60\xf5"
-  "\x10\xd3\xab\x68\x0f\x7d\x1b\x96\x17\x75\x4f\xd5\xca\x34\x52\x1d"
-  "\x7c\x0f\x3d\xd1\x89\xfa\xd0\x96\xeb\x82\x29\xf5\x10\x86\xe5\xd6"
-  "\x12\x3e\xc2\x85\x7a\x60\xc7\xb6\xfe\x77\x5b\xae\x03\xbc\xcc\x0f"
-  "\xa7\x5d\xc2\x97\xe1\x87\x0f\xd3\x19\xe2\x23\xfd\x6b\xc7\x32\x53"
-  "\x9a\x38\xbe\xc7\x7f\xe6\x25\x7c\x2e\xd0\xe8\x38\xbd\x4f\x12\x0e"
-  "\x7e\x26\x04\xe2\x6c\x2d\x7a\x10\x06\x60\x6a\xab\xc3\xac\x0f\xe3"
-  "\xeb\xf7\xb0\xfc\x3b\xa5\xfd\xe1\x6c\x30\x23\x6c\x2a\x5f\xbb\xf7"
-  "\x20\xd0\xb9\x09\x08\xf3\x7d\x36\xa8\x0f\x9b\x32\x00\x1a\xa2\x99"
-  "\xf6\xef\x10\x9d\x4a\x59\x3e\xbe\xfc\xc9\xa5\xf0\x64\xea\x8a\xd4"
-  "\xa5\xb0\xea\x81\x65\x4b\x21\xf1\xde\x79\x89\x77\xdd\xb3\xf8\x2e"
-  "\x48\x7f\xea\xf1\xa5\x90\xbe\x7a\x29\xac\xc5\x4f\xc6\x43\x2b\xf0"
-  "\x61\xd9\xd2\x3b\x13\x1f\x9e\x97\xbe\x6c\xc5\x72\x78\x6c\xdd\xc2"
-  "\xc4\x85\x0b\xe1\x81\xe5\x2b\xef\x4c\x4c\x94\xbe\xef\x4c\x24\x90"
-  "\x67\x16\x2f\x5f\x3b\x2f\x3d\x7f\x9b\x71\xdb\xbc\xd5\x2b\x96\xc1"
-  "\xf2\xe5\x4b\xd3\x03\xfa\xc6\x04\xcf\x17\x1e\xe2\xad\x93\x5d\x48"
-  "\xa3\x33\x12\xe0\x10\xca\x1c\x3f\x03\x7c\xef\x05\xc4\xec\x3b\x44"
-  "\xb2\xe2\xfe\x72\xea\x29\xb4\x73\xcd\x90\x35\x9a\xe4\x5f\x4e\x3c"
-  "\xa3\x73\x0a\xce\xc0\x75\x07\x31\xef\x13\xc9\x47\x87\x63\xfe\x51"
-  "\xff\xfc\x69\x16\xcc\xff\x2b\xad\xe5\xb7\xe1\x07\xf9\xec\x44\xdf"
-  "\x87\xfc\x74\xc0\xa0\x39\x23\x9c\xef\xa5\x44\x19\xd3\x1a\x57\x2c"
-  "\xdb\xaf\xb0\xf1\x3e\x5a\x0b\xab\xdb\x05\x61\xe7\x21\xfa\x97\xdd"
-  "\xc6\x14\xda\xef\x02\x36\xa3\x84\xe3\xe2\x28\x8e\x48\x69\x3f\xa6"
-  "\xfd\x10\xad\x33\xe6\x78\x62\x12\x15\xfe\xc0\x4e\x78\xaa\x31\x4f"
-  "\xe0\x8a\x09\xef\x46\xbf\x80\x7e\xfb\xb4\xd7\x9c\x00\x2c\xf2\xa7"
-  "\x76\xef\x48\x02\xef\x63\xb0\x9c\x5e\xd6\xe3\x6a\x5a\xc3\x6a\x40"
-  "\xb8\x1f\xa4\xa9\x68\x0d\x28\x5f\x0f\x0a\xd1\x46\xd4\x67\xa7\xb7"
-  "\xb2\x2d\x81\xef\x55\xe6\x69\x31\xcd\x2c\x12\x9f\x2b\xdb\xe6\x30"
-  "\xb3\xd8\xbf\x8c\x69\xef\x53\x1a\xca\x38\x8c\x6c\x91\xef\xcf\xc4"
-  "\xba\x91\x17\x73\x90\xbe\x5e\x0f\x95\xbf\xc0\xcb\x4f\xc6\xb4\x08"
-  "\x84\x9d\xe3\x8d\x6c\xbb\x1d\x75\x86\xd2\xb0\x5f\xbf\xee\x38\xe2"
-  "\xbb\x83\xf6\x8e\xb3\xa8\x98\x18\xfc\x3d\xb7\x75\xd7\x00\x3f\x03"
-  "\xdc\x8e\x79\x5e\x33\xe2\x1c\x19\xad\xbf\x97\xca\x62\x5d\x9a\xa1"
-  "\x11\x3d\xf6\xa5\x31\xa7\x28\x26\xf0\x10\x3d\x17\x46\x61\x3a\xa8"
-  "\x4e\xb2\x67\x94\xc5\x00\xca\x29\x62\xc8\x3a\x6d\x5d\x80\x9c\x72"
-  "\x11\xcf\x1c\xe4\x7b\x2f\xe2\x68\xf7\x0e\x62\x1d\xf8\x8c\x78\xd5"
-  "\x12\x5e\x19\x87\x53\xe8\xc1\xb4\xba\x00\x3d\xd8\x83\xb8\x2f\x2a"
-  "\xf2\x9b\x03\xf2\xb3\x31\x7f\x58\xca\x47\xbb\x9a\x76\x32\xa0\x7e"
-  "\xa2\xcd\x8b\xf5\x3b\xd1\x6e\xc2\xb0\xbe\x8c\x43\x14\xaf\x8d\xc2"
-  "\x4f\xd7\xf8\xc3\x4f\xc7\xd8\x20\x9a\x7c\x09\xf9\x44\x0e\xdf\x28"
-  "\xe9\xaa\xa8\x7f\x7a\x52\x00\xbc\x1b\xe1\x27\xd3\x19\x1b\xf8\x7d"
-  "\x2d\xc2\x4c\x46\x9f\x44\x7b\xae\x4f\xb5\x15\x53\xfc\x36\x3d\x2b"
-  "\x00\xbe\x0c\xe1\x6e\x24\x3e\x72\x1e\x5c\xe0\x3c\xc8\x90\xe2\x2d"
-  "\xb2\x05\x2d\x96\xa9\x0f\x28\xd3\x82\x65\x66\x7b\x05\xdf\xc2\x86"
-  "\x06\x83\x96\xe9\x0c\x28\x33\xc0\xe5\x2f\xea\xd1\x90\xbe\xc8\x65"
-  "\xb8\x8f\x19\xf1\xc3\x41\x6d\xc3\xb8\xec\xda\x18\x7f\x1c\xb1\x03"
-  "\x58\xef\xed\xfb\x85\x1d\x5f\x83\x32\x5f\x88\x69\x1f\x23\xde\x79"
-  "\xa4\x27\xa4\xcb\x36\x87\x0b\x7d\x60\x5a\x94\xe8\xcb\xaf\xdd\x1e"
-  "\x5d\x0c\xf4\x7b\x1e\xfd\x26\xdc\x6c\x64\xa5\xa4\xe3\xd7\x6e\xc7"
-  "\x6f\x4a\xe7\x75\x92\x6d\xb1\x91\x47\xbd\x02\xe7\xb5\xaf\xa3\x0d"
-  "\xaa\xf1\xd9\x23\xd5\xf1\x07\xda\xc7\x8b\xfa\x79\x3b\xfa\x57\xa0"
-  "\xbd\xc8\x98\x9e\x84\xe9\x5d\x52\xfe\x47\x04\x8f\xbf\xef\x94\x7e"
-  "\x93\x5e\xde\x2e\xe9\x25\xea\x79\x2c\x3f\xb7\x41\xe8\xba\x28\xef"
-  "\x15\x7a\xbd\x0c\xf3\x7e\x84\xdf\x2b\xf0\xfb\x75\xfc\x7e\x0c\xbf"
-  "\xb7\xd3\xd9\x0b\x66\x0f\xc6\x13\xe2\xf9\x59\xfc\x7e\x1c\xbf\x57"
-  "\xe0\xf7\x5a\xfc\x5e\x44\x76\xe9\xd8\xa1\x87\x00\x9d\x18\xf0\x0a"
-  "\x5b\x9c\x2c\xe4\x11\x1b\x2f\xd9\x87\xb0\xcf\x0b\xbe\x34\x26\xd2"
-  "\xd4\xe8\xd7\x7d\x69\x23\x69\xc4\x97\x74\xc4\xcf\xcf\x0a\x91\xec"
-  "\x3a\x5c\xc8\x45\xc0\x78\x45\x39\x49\x76\x52\x9a\x80\x53\x29\xeb"
-  "\xb4\xc3\xb5\x27\x4b\x9d\x8c\xe1\x77\x2b\x3f\xb7\x01\x62\xdb\x91"
-  "\x27\x18\xd7\x5c\x5b\x47\x7c\xf2\xc9\xfb\xda\x44\x85\xbc\x31\xae"
-  "\xbd\x0e\x02\x6c\x29\x09\xe5\x9d\xcc\xe5\x8d\xbc\x93\x69\x26\xfa"
-  "\xb1\x7f\xa1\x3e\x6b\x92\x68\x43\x4c\x06\xfa\xf6\x01\x9f\x6f\xbe"
-  "\x2e\xcd\x1f\x4f\x4c\x06\x96\x69\x90\xfa\xb2\x51\x3d\x23\x7d\x09"
-  "\x33\x90\x0d\x5d\x87\xf1\xff\x2f\xf9\x59\x43\x94\xe7\x8c\x38\x91"
-  "\x49\x75\x86\xe5\xf2\x3c\x8c\xff\xaf\xe9\x95\xf3\x40\xec\x93\x72"
-  "\x86\x19\x79\xde\x31\xb9\x1c\xab\x7c\x8f\xe3\x75\x62\xff\x48\xf1"
-  "\x02\xf5\xfb\xd8\xff\xf6\x23\xcc\x49\x3b\x4c\x89\x09\x79\x76\x51"
-  "\xf9\x4f\x1d\xf3\x2c\xa0\xbe\xc5\x02\xe1\x36\xf7\x29\x58\xe3\x66"
-  "\x9e\x79\x00\x11\x36\x77\x32\xcc\x01\x98\x66\x73\x9f\xa4\xc9\xf0"
-  "\x59\x36\x77\x1d\xf6\xaf\x65\x94\xff\xe1\xed\xa0\x52\xe1\xb7\xf9"
-  "\x0e\x50\xab\x6c\xee\xc3\x98\xde\x0c\xb7\x80\x46\xf5\x70\x38\x1b"
-  "\xb2\xb9\x93\xf0\xd9\x08\x0f\x85\xb3\x3f\x6f\xf2\x40\xcc\xca\x7d"
-  "\xcc\x6c\x73\x67\xc1\x43\xfb\xbc\xcc\xe6\xee\xc4\xbc\x5c\x58\xe3"
-  "\xb9\xc4\xd6\x78\x86\x18\xd3\xbe\x87\xbf\x2f\xe0\xef\x3f\x33\xe4"
-  "\x1b\x7e\x7f\x88\x1f\x33\xb3\x61\x9c\xcc\x2a\x7e\xea\xd8\xb4\x53"
-  "\xcd\xef\x6b\x64\x11\xef\x21\xcf\xdf\x8b\x19\x61\xfa\x30\x16\xf9"
-  "\x5e\xf4\xc8\x08\x7e\x57\xbe\x37\x95\x3f\x97\xbf\xa7\x43\x3c\x31"
-  "\xf3\x71\xd0\x40\xf4\xdb\xdc\x7d\xb0\x09\xfd\xcd\x9a\x9d\x0e\x46"
-  "\xb4\x4f\xdd\xc3\x60\xcd\xce\x0f\x19\xfa\xba\xe8\x35\x3b\xcd\x0c"
-  "\xf3\xb4\x88\x0f\x63\xd6\x01\xac\x03\xcb\x46\xbe\x37\x93\xe3\x2b"
-  "\x7f\x2f\x05\x61\x1d\x04\xa7\xc4\x43\x38\x08\x76\x8d\x07\xa2\x11"
-  "\x3e\x65\xa4\xe2\xbd\x44\xfc\xa4\xe3\xc7\x82\x65\x5f\xf5\x5a\x63"
-  "\x7f\x49\xfd\x1a\x96\x6f\xc2\xe7\x63\x97\xf8\xf9\x0a\xa7\x08\x7e"
-  "\x32\xc2\x37\xa1\xcc\x53\x87\x04\xbd\x3d\x9c\xde\xca\xf7\x6c\x97"
-  "\x44\x3b\xba\xa5\x76\x74\x51\xba\x13\x75\x1d\x7f\x3b\x9c\x22\xef"
-  "\x02\x96\x5b\x37\x24\xe8\x72\x30\x6d\x33\xf5\xc9\x61\x6b\x3c\xcc"
-  "\x42\x3c\x44\xbe\x5a\x88\x8f\x34\xe6\xc1\x3a\x1c\x2c\xa2\x19\x46"
-  "\x2a\x9a\xb1\xff\x6a\x9e\x3d\xc2\xa8\xaf\x6d\x4e\xbc\xc4\x71\x37"
-  "\x2f\x40\x3c\x1b\x86\x08\xa7\xb6\x39\x91\x95\x37\xa7\xb8\xd5\x3a"
-  "\xe4\x07\x73\xad\x71\xef\x71\x6f\xda\x49\x67\xa0\x7c\x04\x09\x16"
-  "\x8b\xca\x66\x32\x62\x3b\xab\x10\x67\x16\xe6\xc3\xb5\x58\xd7\x87"
-  "\x88\x37\x91\xea\x63\x15\xcd\x29\x88\x73\x29\xe2\xca\x22\x9a\x86"
-  "\xad\x10\x83\xcf\xe9\xc3\x9c\xbe\x66\x83\xb7\xbc\xb9\xd6\xab\x6d"
-  "\xb6\xc8\xfa\x43\xba\x23\xf8\x46\x3a\xf3\x36\xa5\xc5\xc8\x7a\xe2"
-  "\x29\x6f\xce\xbc\x03\xe8\xfe\x22\xe6\x26\x5d\x59\x00\x06\x55\xb7"
-  "\xf3\x24\xf2\x5a\x0b\xdd\x86\x66\xb8\x1d\x68\xec\xe5\x84\x6e\x67"
-  "\x1d\x3e\x1f\x04\xa2\xaf\xdb\x59\x06\x5d\x03\x87\x61\xb5\xc1\xb9"
-  "\xc7\xa3\x6d\xb6\x77\x0d\xac\x02\x2c\xff\x21\xd2\xe8\xdd\x68\xd0"
-  "\x58\xba\x0d\x4e\x7a\x36\x77\x0d\xa0\x7e\x7a\x98\xc7\x5d\xde\x9c"
-  "\xee\xd6\x36\x3b\x56\x5f\x64\x8e\x55\x03\x96\x70\x4c\x1b\x89\x56"
-  "\x31\x77\xb4\xc9\xcc\xba\x06\xaa\x60\xe3\x45\x50\x75\xe9\x9b\xb9"
-  "\x9e\x6e\x34\x18\x80\x97\xbf\xe8\x8e\x7e\x76\xc0\x02\xcf\xea\x61"
-  "\x2a\xc2\x5f\x20\x9d\x65\x53\x2d\xd0\xd9\x97\x0b\xab\xce\xb9\xc3"
-  "\x56\x5f\x1c\x61\x9d\x99\x75\xd0\xa5\xaf\x23\x7e\x18\x68\x8c\xb2"
-  "\xea\xdc\x20\x5b\x7d\x71\x88\x75\xe9\xdf\x86\xce\xcc\x66\x58\xf9"
-  "\x97\xd6\x68\x4f\x45\x73\xa6\x37\xa2\xd9\xe2\xad\x68\xae\xf5\x44"
-  "\x34\xdb\xdd\x15\x48\x4b\x44\xb3\x83\x55\xbe\x9f\x89\xfc\x8b\xe0"
-  "\xb2\x88\x7c\x7f\x23\xfe\xd6\x71\xf9\x6a\xdf\x37\xb0\xf2\xf7\x6b"
-  "\x47\x2a\xde\xb7\x70\xbd\x8f\x78\xdf\x60\x73\x93\xfe\xbf\x5f\x8b"
-  "\x70\xb5\x42\x47\xde\x6f\x12\xba\xff\x7e\x23\xc9\x15\x61\x8f\xe1"
-  "\xa7\x15\x3f\x3d\xac\xf2\x03\x1d\xe2\x9a\x46\x78\xbd\xe5\x1f\x24"
-  "\x7a\xb5\x1f\xa0\x3d\x7c\x40\xe7\x02\xab\xbb\x9d\x87\xc1\x83\xfe"
-  "\xb8\xdb\xe9\x81\xd5\xdb\x5d\x28\x5b\x94\x81\xc9\x83\xfc\x3c\x05"
-  "\x1b\xb7\x83\xd9\x66\x3a\x05\xec\x17\xb5\xc4\x8f\xe8\xd5\xdb\x3f"
-  "\x64\xde\x8a\x0f\x12\x29\x7f\xf5\x76\x33\x8e\xab\x10\x4f\xc4\x07"
-  "\x29\xde\xca\x0f\x32\xa5\xf8\x0a\xe9\xf8\x60\x13\xd1\x31\x32\x94"
-  "\x40\xfb\xdb\x34\x98\x6f\xc0\xb4\xd3\xd4\xdf\x78\x49\xef\xca\x3f"
-  "\xb0\x33\xed\xcf\x52\x56\x85\x33\x87\xe7\x65\xe0\x3a\xe0\xbd\x8f"
-  "\x31\x1a\xb7\x6d\x32\x41\x13\xb7\x29\xcf\x8d\x16\x16\xf1\xb3\x14"
-  "\x56\xf1\x81\xdd\x5b\xf9\x6f\x56\xc4\x13\x46\xf7\x9e\xb0\xf2\x7f"
-  "\xb3\x08\x9d\xf9\x98\xdb\x1e\xab\xf8\x37\x8b\xff\x1c\x41\xf0\xf9"
-  "\x81\x21\xeb\x8d\xcd\x76\xe8\xd6\xf3\x73\xda\xac\x37\xb6\xda\xc1"
-  "\x96\x2c\xfd\xee\xb4\xc3\x4f\xf9\x3c\x11\xf9\x38\x43\x29\x5c\x77"
-  "\x16\xbe\x69\x41\x7e\x00\xfe\x8e\xc2\xdf\x65\x6b\xe6\x60\x9b\xcb"
-  "\x3d\x69\x28\xef\x21\xf2\x37\xcc\x9a\x84\xf1\x09\xa4\x60\x5b\xb5"
-  "\x6c\x28\x21\x8a\x45\xfe\x7a\x21\x1b\x89\xa3\x31\x68\x34\x3e\x4f"
-  "\x45\x9e\xc6\xe3\xf7\xf4\x83\x5f\x40\x2c\x7e\xe2\x0e\x5a\xbd\x16"
-  "\xf2\xc7\xf8\x3b\x91\xed\x88\x8b\xac\x2e\x82\xb9\xd1\x4e\x71\xee"
-  "\x70\xf4\x9e\x18\x1a\x8b\xc5\xd2\x6f\x66\xfd\x20\xa1\xf1\x0b\xf9"
-  "\xec\x61\xac\x2f\xc8\x5d\xa3\x9e\xa1\x04\x35\xd1\x29\xd3\x42\xb4"
-  "\x21\x9d\x33\x91\xce\xba\x27\x76\xa6\x00\xdd\x63\x13\xcc\x7f\x0f"
-  "\x59\xbf\x39\xda\xfe\x10\xf9\x27\x65\x9e\x84\xc8\x77\xca\x7c\x0a"
-  "\x35\x4f\x40\x36\xee\xf9\x82\x0d\xd4\xe4\x89\xfd\x74\x66\x37\xfb"
-  "\x6f\x1c\xc3\x58\x4a\x71\x6c\xbe\xc6\xe4\x62\x36\x07\x6b\xa5\xfb"
-  "\x70\x68\x1c\xdc\x88\x30\xa5\x6e\xe6\xa5\x71\x31\x8d\x89\xe9\xec"
-  "\x36\x6f\xc5\xaf\x63\x59\xc5\xaf\x63\x06\x8b\x98\xfb\x10\x1f\xc7"
-  "\xce\xd0\xdb\xe1\xbe\x4c\x21\x9b\x66\x03\xf6\x83\x7d\x83\xda\x5f"
-  "\xc7\x20\xee\x69\x84\xbb\xdb\xc0\x5a\xbd\x11\xbf\x8e\x43\xb8\x5a"
-  "\x3b\xfc\xe9\xb0\x72\xae\x0f\xfb\xb4\x81\xb2\x03\xd4\xaf\xcd\x38"
-  "\x6a\x87\x9b\xcb\xc7\xcc\x25\x89\xb7\x97\x16\xbf\x7d\x15\x2a\xf0"
-  "\xdf\x25\x42\x3b\x32\x52\x82\x67\xfb\xfa\xc5\x66\x07\x9d\x67\x67"
-  "\x2e\x81\x19\x28\x87\x6f\x9e\x85\x99\xb3\xcc\x26\x76\x86\x59\x67"
-  "\xb4\xfc\x60\x97\x0b\x63\x88\x99\x73\xed\xf0\xfd\xde\x50\x7c\xf3"
-  "\x7e\xc1\xfa\x10\x47\x6d\x0d\xc6\x81\xd4\x6e\xe2\xdb\x1a\x13\xf3"
-  "\x62\xfb\x3e\x21\x1b\x6b\x2c\xa2\x58\x78\xa6\x41\xe6\x43\xa8\x3d"
-  "\x7e\xac\xfc\xd7\xf1\x22\x5e\x9c\xd9\xc3\xac\x0c\x5a\x6f\xa2\xb9"
-  "\xbf\x99\x27\x78\xcc\x54\xfe\xbe\x65\x10\xfd\x07\xcd\x91\xd0\xd9"
-  "\x73\x05\x71\xcc\x85\x38\xdb\xed\x70\x5b\xa2\x34\x26\x73\xda\xdc"
-  "\xcb\xc9\x97\x58\x42\xcd\xad\xfa\xf0\xdf\xe4\xe8\x9e\x81\x7d\x2d"
-  "\xfa\x22\xa6\x3d\x71\xb8\x54\xc8\xd9\x45\x78\x69\x0f\x6b\x1f\xe6"
-  "\x17\x38\x59\x3f\x2b\x3f\x51\x4f\xf1\x07\xed\xa7\xc3\xb4\xcf\x50"
-  "\x7f\x59\x6b\x3e\xd1\x74\xd3\x67\xad\x37\x0d\xc3\x19\x8c\x07\x69"
-  "\xcf\xaa\x18\x9f\xdd\x74\xaa\xcd\x08\xd2\x98\xef\xa6\x0d\x76\x48"
-  "\xe8\x94\xe9\x42\x9f\xc1\x90\xb7\x58\x3f\xf9\xbb\x01\xa0\x79\xb7"
-  "\x82\x62\xe6\x42\x5a\x0d\x08\x5b\x2e\xb7\x81\xda\x27\xda\x75\x53"
-  "\x83\xb2\x5d\x48\x83\x03\x63\x6b\xce\x83\x82\x9d\xa0\xe5\x67\x61"
-  "\x79\xa8\xef\x58\xce\xdb\x42\x6d\xe6\x6d\xc1\xb8\x82\xfa\x13\x9b"
-  "\x7b\x11\xc6\x47\x3c\xbd\x16\x71\xe1\xf8\xf7\x5b\x8b\x45\x4c\x75"
-  "\x13\x3f\x93\x26\x68\x6c\xa4\x6d\x4e\x31\x5f\x82\x9b\xcc\x5e\x76"
-  "\xfa\x0c\xdc\x5c\x88\x7c\x0a\xa3\x6f\xde\x17\xbb\x50\x77\xb5\xbf"
-  "\x73\x52\x1f\x6c\x2b\xbe\x88\x7e\x9b\xc3\x5e\x8b\xb0\x7d\x08\x93"
-  "\x2d\xc1\x66\x8b\x39\x61\xfe\x3d\x99\xbe\xb1\x4f\x5e\x8a\x7a\x5b"
-  "\x4c\xf3\x18\xc8\xe7\x4c\xf9\x99\xe1\x33\x7e\x27\xb1\x8a\xdf\x05"
-  "\xdd\x5b\x4c\x7e\xd5\x2b\xd9\x21\xd6\x73\x03\xe9\x91\x79\x27\x7c"
-  "\x03\x75\xf2\x93\xd2\x12\xb8\x8e\x74\x8c\x45\xfc\x3a\x51\xf0\xfd"
-  "\xe6\x0e\x66\xb5\x00\xed\x7f\x35\x14\xc1\x37\xd1\xf6\x12\xce\xc2"
-  "\xcd\x1f\x6f\x2a\xd6\x21\xad\x00\x35\xe7\x81\xfa\xc9\x3f\x23\xfc"
-  "\x5c\xba\xa7\xac\xf1\x3c\xe9\xe2\xcd\x6e\x59\x17\x87\xac\x3a\xed"
-  "\x78\x3e\x01\xf9\xda\x2a\xc6\x15\xba\x42\x9a\x63\x3b\x0d\x3a\x3a"
-  "\x6f\x34\x0c\x3f\x2a\x4c\x7b\x8c\x7d\xc1\x66\xd0\xd9\x84\xc8\x6b"
-  "\x8c\x4f\x75\x55\xf8\xdd\xca\x3f\x56\xb0\x48\xcf\xc7\x10\x2e\x85"
-  "\x7d\xe1\x21\x18\xf4\xd9\x3a\xf4\x91\x2a\xb2\x13\x8c\x91\x75\x65"
-  "\x76\x78\xc0\x24\x64\xa3\x4b\x27\x5c\x21\x68\x38\xc6\xf8\x7e\xd2"
-  "\xcf\xb1\xbd\xba\x73\xba\x52\x15\xd1\xf1\x4b\x6e\x17\x88\xab\x51"
-  "\x2d\x7c\xb3\x17\x69\x3d\x64\xf5\xea\xd1\x0f\xeb\xbd\x95\xdd\x4d"
-  "\xfc\xb7\x94\x47\x74\x78\xb1\xfe\xe0\xf8\x4f\x1c\xa6\x3d\xf1\x7d"
-  "\x30\x2b\x4d\xe0\x39\x51\xdf\x7a\xe3\x59\x7a\xe6\x67\x69\x38\xb5"
-  "\xb6\x26\x5b\x7d\x8a\x38\x83\x14\x61\x44\x9c\x3f\x6b\xc5\x20\xd6"
-  "\x31\x64\x9d\x95\x66\x87\xdb\xb5\x62\xbe\xd1\x16\x74\x7e\x92\xf6"
-  "\x3b\x93\xed\x74\x35\x80\x64\xd3\xb7\xd0\x79\x8f\x4e\x6c\x57\x93"
-  "\x47\xfb\x7e\xab\xe4\x67\x69\x0c\x76\xcd\x69\xb8\x45\xd3\xad\xe7"
-  "\xfa\xad\x66\xea\x59\x47\xfc\xce\x48\xc4\xbc\xb1\x9f\x59\xbd\xf8"
-  "\xe9\xc7\x8f\x53\x3c\x23\x71\x30\x1b\x29\x98\x9d\xc5\xf9\x36\x98"
-  "\x85\x63\xa2\x5b\x34\xde\x08\x94\x49\x39\xc9\x68\x96\x9d\x0d\xc6"
-  "\xab\x31\x16\xe1\xbf\x1b\xb7\xd3\xd8\x62\x76\x14\xf2\xbf\x5e\xc8"
-  "\x81\x70\x80\x0a\x6d\x91\x78\xce\xcc\xf5\xcc\xd5\x5e\xea\x44\x9a"
-  "\x67\x27\xb7\xd7\x3b\x41\x77\x1b\xb5\x7d\x36\xc5\x1c\xcc\x89\xbc"
-  "\xa7\xef\x82\x7a\xe6\x68\x6b\x70\x03\xcd\x4b\x23\xae\x0c\x3b\x58"
-  "\x53\xc5\x38\xe5\x44\x0f\xe1\x93\xf4\x81\xc9\x6d\x17\x3c\xb6\x35"
-  "\xe9\x8a\x54\x84\xeb\x87\x34\x27\x41\x63\x26\xdf\x5c\xcf\xec\x83"
-  "\x68\xe3\xf7\xd3\xf9\xa9\xe7\x61\xf6\x1f\x08\xbe\x4d\xcf\xcf\x61"
-  "\x1b\x38\xc8\xfb\x83\xd9\xc7\x91\x5e\x97\x74\xde\xc4\x00\xed\xa5"
-  "\x27\x7c\x38\x8e\xea\xef\xd2\x3b\xc0\x83\x6d\xe5\x7b\xed\x51\x3e"
-  "\x25\x03\xcc\xf5\x61\x91\x4b\xc3\xeb\xcf\xe3\x67\xa0\x39\xa3\x8d"
-  "\xa8\x0f\x28\x2b\x1c\xf7\xba\xb0\x2e\x63\xe0\x59\x9e\x8a\x33\x64"
-  "\x25\x9a\xe3\x23\xda\xe2\xb9\xbf\x6c\xf2\x22\x5f\xfc\xe5\x15\xaf"
-  "\x15\xb2\xba\x65\x9d\xbf\xac\xe2\x31\x76\xb9\xa5\x1e\x3f\xc7\xf0"
-  "\xd3\x2a\x9e\x95\x9f\x5b\xca\x14\xbf\x7b\x86\xac\xb7\x60\xff\xa7"
-  "\x8b\x15\x32\xa0\x34\xa4\x91\x74\xe3\x33\xec\x5f\x70\xfc\x4e\xef"
-  "\x28\x28\x9d\xf4\x98\xd2\xbd\x18\xab\x20\x6f\x0f\x63\x7e\x0c\xd9"
-  "\x28\x9d\x5d\xa7\xcc\x1f\x3d\xa3\x04\x6e\xb9\xc8\xe7\x1c\xf6\x94"
-  "\x97\x93\x7e\x62\x99\x23\xd1\xee\xf2\xf2\x21\x6b\x3c\xc8\x3c\xc4"
-  "\xb4\x7e\xca\x0f\x1e\x33\xc4\x27\x8c\xc6\x56\x18\x6f\x92\x7c\x06"
-  "\xe0\xd6\x24\xf4\x4b\xe8\x8f\xbb\xc5\x99\x5a\x70\xeb\x22\x7a\x46"
-  "\x7f\xf8\x09\xfe\x4e\xec\x42\xbf\x33\x5c\xd9\x16\x37\xa2\x86\xc9"
-  "\xc3\x6a\x48\x71\x57\x7a\x72\xdd\x91\xff\x11\x6f\xeb\x6f\x86\x6e"
-  "\xf7\x4f\x81\xee\xde\x43\x1c\x73\xe8\xbc\x44\xf3\x4e\xe6\x79\x67"
-  "\xf8\x08\x8e\xbd\x2e\xb4\xf2\xf3\x81\xe1\x56\xde\xf6\x57\x4e\x63"
-  "\xaf\xbe\x91\xe3\x96\x78\xe1\x49\xab\xde\xca\xdc\xd5\x67\xe8\x0c"
-  "\x85\xb8\xc8\xfd\xc3\x30\xf7\xcd\x5d\x90\xd8\x30\x0c\xf1\x87\x86"
-  "\x21\x81\xfd\x95\xee\x73\xf0\xdd\x01\x31\xd5\x00\xda\x43\xbb\x30"
-  "\x0e\x73\x83\xca\x53\x81\x71\x98\x1b\xe3\xb0\x0b\x09\xe4\xff\x46"
-  "\xe3\xb0\x91\x11\x8a\xc3\x7e\x5d\xcf\xcf\xd5\xad\xf8\x75\xfd\x14"
-  "\x3d\xa8\xa2\x32\x21\x06\xe9\x33\x9f\x87\xf8\x9c\xa8\x3e\x8c\x01"
-  "\xb1\xcd\x76\xa9\xbd\xc8\xdf\xe2\x68\x3d\x4c\xe6\x6d\x45\x9f\xcc"
-  "\x2a\xba\xeb\x43\xf6\xb5\x6a\xd2\x1d\x27\xd9\x07\xb5\x61\x0f\xbd"
-  "\x13\x69\xbe\xd1\xa5\x29\x68\x60\x2e\x4a\x37\xce\x22\xdd\xbb\x55"
-  "\x4f\x75\x1f\xc3\xf4\x21\xeb\xad\xb5\x76\xf5\x4f\x42\xbe\xd7\x8c"
-  "\xde\x23\xc7\x03\xb7\x4d\x63\x6a\x0b\xc5\xdf\x99\x25\x6e\xe6\xb0"
-  "\x9d\x27\xdb\xbc\x2d\x66\x4d\x2e\x73\xeb\xf2\xe8\xfd\xd4\x6d\x40"
-  "\xef\xce\x68\xce\xfc\x27\x18\xbb\x5c\xee\x7d\x19\xf5\x09\x18\x9f"
-  "\x1b\xa2\x73\x11\x27\xc6\xff\xcc\x9c\x10\x64\x3f\x7c\xf0\x78\x9c"
-  "\xde\xb5\xbe\xc6\xdf\xeb\xde\xb6\xd2\x0e\xe9\x2e\xe9\x5c\xc4\x01"
-  "\xe1\x1f\xbf\x35\x97\xc6\xf9\xfe\x76\xfd\x2d\xa0\xfd\xfd\x83\xe5"
-  "\x6d\x87\x5b\x6f\x22\x5f\x7e\xdb\x25\x11\xdb\xb4\x35\x09\xdf\x7e"
-  "\xdb\x1f\xc5\x1c\xdd\x6d\xd8\xff\xdf\x1d\x45\xf8\x0c\xb3\x49\x27"
-  "\x6e\x3b\xc9\x22\xdb\x7e\x40\x70\xf3\x2d\x60\xd9\xe6\x86\x4c\x56"
-  "\xd1\xd6\xc4\xb8\x5d\x9c\x07\xf6\xbd\x17\x87\xe8\x9d\xac\xf3\x86"
-  "\xf5\x43\xd8\xd7\xcf\xc5\xbc\xc3\x54\x87\x03\x61\x90\xef\x11\xe2"
-  "\xdd\xda\x6d\x0e\x3b\x24\x25\x0b\x7d\xbf\xad\x5d\xcc\x1d\xdd\xd6"
-  "\x3e\x88\x65\x31\xf6\xbb\x76\xc8\xfa\xad\x18\x3b\xac\xea\x94\xe2"
-  "\x4f\xfe\x4e\x1b\xd3\xe2\xed\xb0\x86\xcf\xa7\x18\x67\x41\x9c\x51"
-  "\xc7\xfa\x43\xc6\x6e\x7e\xed\x4c\xf8\x11\x7f\xef\xac\x86\x1b\x10"
-  "\x87\x5e\xc6\x8b\xfd\xe7\x8f\x07\xd5\x4f\x3c\x81\x69\xc5\x32\x5e"
-  "\x84\xb9\x0e\x9f\xab\x46\x61\x44\x99\x06\x45\x99\x27\x06\xd5\xb7"
-  "\xff\x18\xd3\x8e\x05\x94\x69\x0d\x28\xd3\xa3\x28\x63\x91\xea\xe9"
-  "\x0b\x28\xe3\xf4\x2f\x93\xa0\x19\x4b\x5b\x42\x9c\x7f\x99\x84\x84"
-  "\x80\x32\x8b\xc7\xd2\x96\xb0\x32\xa0\xcc\x86\x80\x32\xb9\x0a\xde"
-  "\xd2\xfb\xe5\x44\x4c\xb3\x04\x94\xa9\x0d\x28\xd3\x24\x3f\x63\x2c"
-  "\xd9\x2a\xfa\x7a\xd4\x27\x94\x29\xca\xf5\x30\xe6\x63\xfb\x17\xcf"
-  "\x1d\x6f\x1d\x00\xea\x4c\x83\xf9\xa0\x38\x5f\x9a\x7c\x28\x8d\x29"
-  "\xc8\x6f\xa3\xbf\xa7\xf9\x7a\x7e\x56\x1c\xd5\x75\x06\xe6\x9c\x23"
-  "\x1d\x1a\xb2\xce\x89\x1d\xcb\x8f\x39\x09\xfe\x74\xce\x59\xec\x4f"
-  "\xe7\x9c\xb4\xb1\xfc\x98\xb3\x21\xa0\x4c\x6e\x40\x99\x62\x45\x99"
-  "\x26\xa9\x9e\xda\x80\x32\x4d\x01\x65\x8e\x8d\xd5\xcf\x39\xed\x01"
-  "\x65\x4e\x06\x94\xe9\xf3\xf1\x70\x0e\x5f\xd3\x41\xf6\x80\xe9\xf8"
-  "\x7c\xf7\x78\xeb\x30\x62\x64\x7d\x96\xd7\x63\x08\xbd\xbe\x7d\x4f"
-  "\x9d\x58\x97\xc0\xcf\xf6\xe8\x83\xdb\xf9\x39\x62\xd4\xff\xfe\x60"
-  "\xd8\x15\x4e\x7d\x2e\xf2\xb6\xbf\xcd\xe4\xc2\x18\xf3\xf6\x4c\x3b"
-  "\x24\xe6\xca\xef\x3e\xe9\x7d\x31\x3f\x0b\x8a\x8f\x2f\x6e\x4f\x11"
-  "\xf6\x77\x7b\x9d\x34\x27\x4b\xed\xc1\x71\xc3\xed\x75\x57\x47\xd7"
-  "\x1d\x8b\x88\x2e\x3a\x1b\x05\x71\xf4\x8e\x8e\x1d\x46\x69\xa5\x3a"
-  "\xef\x78\x40\xa6\xb5\x51\xbc\xb3\xa6\x73\x78\x1c\x74\x4e\xcd\x90"
-  "\xf5\x8e\x28\xc5\x78\x83\x68\x75\x36\xef\x72\x69\x02\x68\x1e\x10"
-  "\x34\xdf\x91\x22\x7c\xd4\x1d\x29\xb2\x3f\x09\xa9\x7f\xe5\x27\xca"
-  "\xbb\x31\xe6\xa3\xf7\x74\x5d\x0d\x18\x3f\xe2\x98\x89\xe8\x3e\x0d"
-  "\x77\x94\xf3\x78\x36\x6f\x18\xe8\xb7\xad\x78\x09\x7f\x8f\x27\xb5"
-  "\xa5\x95\xce\x23\xa7\x38\xa5\xdd\xf0\x39\x0c\xf2\x31\x17\xf9\xc6"
-  "\x3b\xce\xb5\x15\x3b\x88\xd6\x16\xf9\xfd\x36\xd2\xc2\x69\x1a\x2c"
-  "\x3f\x61\xa1\x77\x8c\x34\x2f\xdf\xe6\x5c\x4c\x30\xa7\x90\xb7\x4d"
-  "\x32\x0f\xe8\x6c\x73\x84\xad\x0b\x35\xf6\x51\xf2\x55\xd0\x30\xff"
-  "\x69\xa1\x3f\x73\xe3\xfd\xed\x21\x1c\xf5\x74\xee\x62\x7f\x9d\x9b"
-  "\x9b\xe6\xaf\x73\x73\x33\xfc\xed\x41\x8d\xf6\x30\x37\x37\xa0\x4c"
-  "\x71\x40\x99\x2a\x45\x99\x5a\xa9\x9e\xa6\x80\x32\xc7\x02\xca\x28"
-  "\xfd\x1f\xb6\x79\x6e\xcf\xe8\x38\x92\xfb\xfb\xb9\x76\xc5\xb3\xba"
-  "\x8e\xf7\x53\x73\x9d\x72\x1a\xbd\xf7\xc4\xb8\x93\xbf\xcb\x17\xf8"
-  "\xe6\xc5\x04\xf8\x28\x84\x9f\x17\xef\x4f\xc3\xbc\x24\x7f\x1a\xe6"
-  "\xa5\xca\xcf\x35\x62\x1c\xfc\xab\x33\x30\x4f\x3e\x97\xce\x19\xbd"
-  "\x07\x1e\x8b\x76\x3f\xfe\x34\xc5\x61\xd4\x3f\xf1\x35\x16\x25\x18"
-  "\x3b\x5e\xa4\x3b\x8e\x5d\x74\x1f\x56\x18\x9d\x97\x64\x87\xf9\xb5"
-  "\x38\x3e\xab\x43\x98\x01\x8c\xa7\xd6\x20\x8e\x75\x58\x7f\x3d\xd6"
-  "\x81\xbc\x9b\x77\x24\x80\x86\x96\x00\x1a\x3a\x14\xcf\x31\xf8\xdc"
-  "\xab\x68\x77\x4c\x58\x1c\x5f\x03\x85\x31\xf3\x3c\x87\x9c\x4e\x63"
-  "\x7a\x6c\x63\xbf\x99\xc7\x01\x29\xb4\xae\x65\xfa\x69\x98\xf7\x31"
-  "\xc5\xc1\x02\xe7\xfc\x19\x4a\xde\x0a\x5e\xcc\x4f\xf4\xa7\x63\x7e"
-  "\x8a\x3f\x1d\xf3\xd3\x7d\xbe\x66\xde\x3a\x61\x23\xf3\xb3\xd0\x47"
-  "\xf7\x53\x1a\xf2\x42\x17\xed\xd6\x5d\xdb\x3a\x9b\x62\xd2\xf9\x15"
-  "\x4e\x6c\x2f\x7b\x59\x3d\x5d\x7a\xe6\x77\xb8\xb0\xd9\x34\xff\x7f"
-  "\x22\x54\x4c\x15\x33\x18\x79\xa2\x56\x5a\x9b\xa4\x43\xdc\xad\xb2"
-  "\x8e\x7b\x2b\x4f\xd4\x7a\x2b\xba\x32\x31\x0d\xfd\xdf\x1d\x2e\x31"
-  "\xf6\xe8\x3c\x8a\xfa\x5c\x8f\x32\xc1\x71\xea\x82\x5f\x4a\xe3\xba"
-  "\xc3\xb4\x5e\x05\x7d\x0d\x9d\xb3\x16\x25\xde\x69\x2e\xd0\x2a\x6c"
-  "\xc5\xa9\xdb\x75\x3f\x3b\x0d\x0b\xba\x28\x5e\x23\x5f\x40\xeb\x5e"
-  "\xda\xdc\x0e\xa0\xb9\x10\x9b\xfb\x2c\x8f\xa9\x31\xbf\x53\x2a\x9b"
-  "\xaa\x28\xeb\x90\xe6\x2a\xfa\x29\x6f\x81\x1b\x34\x6d\x4e\x07\x9d"
-  "\x27\x1d\x2b\xe2\xf0\x05\x5d\x6d\xe8\x03\xb0\x8c\x49\x2e\x43\xf3"
-  "\x1a\xd2\x78\x44\x33\xbf\x98\xee\x66\x3b\xcd\x71\x83\x38\x73\xaf"
-  "\x1f\xc7\x33\x03\xb6\xe2\x7e\xb0\x39\x7b\x69\x7e\x51\x23\xd6\x0f"
-  "\x2c\xe8\x0c\x73\x81\x76\xb0\xe2\x04\xf6\x9f\x0b\x3a\x3d\x15\x27"
-  "\xca\x91\x36\xb4\x95\xf9\xdc\xaf\x29\x79\xb7\x7c\x79\xfa\xe3\x6b"
-  "\x56\xcd\x7b\xea\xf1\x15\xeb\x96\x2f\xd1\xad\xcb\x79\x29\x3b\x6b"
-  "\xde\xb6\x42\xa3\x6e\x47\x7e\x8e\x31\x27\xef\x79\x7e\x04\x9e\x6e"
-  "\xb3\x51\x7c\x27\xe4\x6e\x2e\x30\x2e\xa5\x9f\x73\x75\x86\xfc\xec"
-  "\x22\xfe\x73\x4e\x24\xf8\x23\xc9\x31\x66\xe7\xeb\x6e\xcd\x9a\xab"
-  "\x7b\x68\x73\x4e\x6e\x61\x7e\x76\x50\x5c\x4b\x74\xf9\xd9\xf9\xd9"
-  "\x9b\xb3\x74\x4b\x75\x89\x84\x59\x89\x4e\x21\xcf\x44\xd9\xe7\x14"
-  "\x60\x1f\x8d\x71\x71\x3f\xf9\x1e\xea\xab\xcf\xc0\xc2\x77\x29\x2e"
-  "\xe3\x67\xd6\xa1\x6e\xa1\x9f\xb7\x0f\x59\x13\x8f\x8d\xed\x9b\x13"
-  "\x03\xfa\xbf\xc4\x80\xfe\x2f\xb1\x6f\x6c\xdf\x9c\xe8\xf2\x2f\x73"
-  "\xa7\xd6\xbf\xcc\x9d\x71\x63\xfb\xe6\x3b\xe7\x06\x94\x49\x0e\x28"
-  "\xb3\x72\xd4\x77\x20\xad\x7b\xb9\xaf\xb9\x33\x33\xa0\x8c\x21\xa0"
-  "\x8c\x25\xe0\x59\x19\xff\x60\x3c\x7a\x67\x93\xb2\xbf\xc7\xe7\x63"
-  "\xb2\xfd\xfa\x7c\xd6\x9d\xed\x32\x0c\xf5\x27\x8d\x74\x37\x86\x80"
-  "\x3d\xa5\x80\xed\x97\x60\x1d\xa3\xbe\xea\x00\x1f\x33\xf7\x8b\x98"
-  "\x7b\xe1\x66\xc9\x5f\xd1\x5d\x19\x72\xbf\xd8\x87\xb2\xb8\xf9\x3c"
-  "\xdc\xd9\xd5\x28\x60\x1d\x7c\x6e\xf8\x7b\xeb\x87\x1a\xa7\x83\x96"
-  "\xca\xd2\x99\x6d\xcc\xba\x80\x9f\x0d\x88\x69\x51\xf8\x41\xdf\xb3"
-  "\x70\x9d\x5d\xfd\x4e\x3b\xd5\x41\xef\x23\xed\xb0\x90\xeb\x32\x95"
-  "\x2b\xe3\xeb\x5f\x78\x7d\x5d\x74\xe7\x07\x9d\x83\x48\x3e\x91\xea"
-  "\xa5\xb3\x04\xa9\x6e\xc4\xa1\x61\xea\xc4\x99\xd2\x99\x70\x31\xf8"
-  "\x89\x45\x9c\x47\x64\x9c\x88\x8f\xfb\x95\xbd\xd2\xda\x4e\x11\xcb"
-  "\x2c\xec\x90\x63\x06\x8a\xff\x83\xf9\x8e\xe0\xeb\x01\x21\xba\xc6"
-  "\xea\xed\x6d\x2d\xed\x23\x9a\x5c\x14\x5b\xda\xe2\xdc\xd0\xdd\xe0"
-  "\xc6\x31\x29\xc4\xf0\x31\x92\xe9\x1c\xd8\x9a\xdc\xfc\x3d\xca\x26"
-  "\x13\x58\x1a\xd5\xde\x5e\x36\x5a\x8e\xc6\x5d\x77\xf1\x77\xca\x65"
-  "\x94\x8e\xe5\x71\x7c\xe0\xa0\x75\x83\xa1\xee\xa3\x21\xb8\xd6\xd9"
-  "\x34\x86\xbb\x4b\x2f\xc5\xb3\xe5\x8d\x88\x2b\xe8\x9a\x36\x35\xd8"
-  "\x86\xac\x77\x1d\xb6\xc3\x33\xb5\xb2\x1f\x6e\xab\xe7\xbe\x4f\x8d"
-  "\xe9\xc7\x91\x17\x03\xa1\x62\x0f\xc9\x67\x1b\x68\x3d\x06\xc2\xf6"
-  "\x8f\x07\x4b\x74\xb7\x61\xbb\xd1\x16\x8f\xfc\xa0\x34\x31\x5c\xf2"
-  "\xaf\x38\xee\x4f\xd2\xc9\xe5\x26\xd2\x3e\x69\xdd\xad\x03\x6d\xd5"
-  "\x29\xc6\x7f\x8b\x5e\x7f\x8d\xaf\x93\x4b\xc2\xf1\xcf\x5d\x55\x52"
-  "\x1b\xae\xc1\x67\xf4\x7f\x77\xf1\x71\x2e\xbd\x13\xa7\x71\x72\x81"
-  "\x01\xe3\xb0\x38\x27\xfa\xc6\xa4\x3a\x39\x8f\xcf\x1b\x53\x5e\x31"
-  "\x73\xb5\xc5\xf5\x51\xde\xb1\xd1\x3c\x2a\x47\x74\x9b\xdc\x94\xde"
-  "\x21\xa7\x8b\x38\x20\xa9\x37\xe0\xb9\x5f\x7e\xc6\xdf\xd8\xff\xdf"
-  "\xb5\x41\xc2\xef\x40\x9f\x4b\xeb\x10\x54\xa7\x61\xd1\x13\x87\xb8"
-  "\xdd\x2c\x8a\x95\xf3\xf9\xdc\xd7\xf7\x71\x7c\xed\x76\x82\x37\xb2"
-  "\xed\x08\x8f\xa3\xb0\x0c\xdd\x21\x83\xe3\x06\x15\x1b\xe1\x6b\x22"
-  "\x06\x08\x0f\xd9\x0c\xbf\xc7\x01\x9f\x11\x17\xcd\xcf\x3b\x48\x47"
-  "\x76\xb8\x61\x86\xe1\x3e\x9a\x23\x5e\xc4\xf5\x96\xd2\x08\x2f\xe1"
-  "\x33\xbb\x05\x6e\xc2\x47\x77\xdd\xb0\x41\x3d\xd2\xba\x88\xda\xdf"
-  "\x11\x4a\x56\x98\xdf\xac\xe0\x65\x38\x3e\xb7\xfb\xb7\x75\xd1\xc9"
-  "\x80\xe7\x3e\xf9\x99\xe6\x63\x85\xee\x2d\xea\x15\x79\x77\xc3\x78"
-  "\x75\xd1\x98\x16\x61\xe2\xfd\xeb\xbb\x3b\xc9\x1f\xff\xdd\xa9\x01"
-  "\xcf\xeb\xe4\xe7\x3a\xfe\x1e\xe0\xee\x2c\xb9\x0e\x31\x1f\xd7\x76"
-  "\xe4\x70\xa9\x23\x7c\x62\xfa\x73\xcf\xcf\x85\xfe\xdc\x7d\x44\x41"
-  "\xc3\x24\x7c\x6e\xf1\xc9\xf3\xee\x76\x19\x3f\xfe\xee\x51\xc0\xa1"
-  "\x8d\xdc\x6d\x0f\xd4\x97\x02\x13\xe9\x19\xe9\xcc\xdd\xee\x20\x79"
-  "\x2e\x91\x77\x4f\x5c\x70\x3d\xbb\x27\x51\x91\x2e\x8d\x3b\xee\x79"
-  "\x5d\xea\xab\xc9\x47\x3a\xe9\x2e\x1d\xe9\x3c\x5f\xae\x17\x74\xce"
-  "\xa7\x74\xbf\x07\xea\xd6\x3d\x86\x40\xbc\x74\x27\xc3\x28\x0e\x1f"
-  "\x4e\x69\x7c\x71\x4f\x93\xaf\x6d\xf7\x1c\xb5\xc3\xa2\x26\x59\x6f"
-  "\xc5\x9c\xdb\xdd\x0d\xa1\xe2\x79\x84\x3f\xe5\xcf\xb3\x7b\x06\x7c"
-  "\x3c\xbb\xc7\xe5\xc3\xbb\x58\xa3\x80\xfb\x5f\xf8\x1c\xeb\x83\x5b"
-  "\xac\xbb\x9c\x7e\x88\xb5\xfe\x8b\xd3\xfc\xeb\x5a\x9c\xa1\xc0\x91"
-  "\xa5\xa8\xcb\xa0\x80\xeb\xc5\x67\x4b\x68\xf9\x2c\x6e\x08\x2d\x9f"
-  "\xc5\x2d\xc1\xe5\xb3\xb8\x47\x51\xef\xa9\xcb\xeb\xf6\xbd\xa0\xa0"
-  "\xa7\x11\x9f\x63\xfc\x75\xf9\x5e\x5d\xc0\xf3\xa8\xfc\x19\xda\xef"
-  "\xe1\x5d\x29\xe1\x94\x6e\x9c\x05\x31\x42\xd7\xef\x4d\x57\xe6\xbf"
-  "\x33\x2c\xf2\x89\x46\xfe\xae\x8a\xde\x03\x0a\x38\x53\x20\x1c\xc1"
-  "\x28\xf2\xeb\x65\xda\xcb\x42\x9c\x3d\x2b\xf7\x41\x36\x2f\xf5\x41"
-  "\xf7\x36\x8b\xf7\x1b\xed\xa7\x98\xf5\xc3\x8c\x50\xfd\x09\xe2\xc5"
-  "\xfe\xff\xde\x23\x82\x3f\xf7\xa2\xfe\x3f\xc6\xdf\xa7\xb2\xf2\xf6"
-  "\x53\xa8\x4f\xc3\x67\x60\x09\xad\x09\x1b\xc1\xef\x9d\xfe\x7d\xdc"
-  "\x92\x58\x66\x55\xad\x6d\xb4\x06\xf6\x7d\x4b\xe6\x62\x4c\x3f\x1c"
-  "\xed\xb6\x64\x04\xc9\x4b\x63\xd6\xb0\xc7\x83\xa4\x67\xa2\xbc\x86"
-  "\xed\xb0\xa4\x8e\xe8\x55\xa4\x9b\x98\x75\xea\x3a\x82\xb7\x53\x7d"
-  "\x58\x26\x94\xdc\xe4\xf5\xef\x42\xf7\x96\xb4\x07\xb4\xe3\xd2\x19"
-  "\xf8\xf6\x03\xa2\x1d\xdf\x3e\x18\x50\xf7\xa9\x10\xed\xa0\x71\xda"
-  "\xa5\xe0\xed\xf8\x76\x0c\xe7\xad\x1a\xdb\x32\xa6\xef\xff\xf6\x5c"
-  "\x6c\xcb\x25\xce\x77\xff\xf4\x54\x79\xfc\x67\xbe\x84\xe3\x6a\x35"
-  "\xf0\xb2\x6b\x8b\x7d\x72\x93\xe0\x72\xa3\xeb\x21\x3d\x48\x9d\x65"
-  "\xcc\x3a\x79\xad\x1d\xbe\x7d\x5c\xee\x33\xa4\xf4\x06\x41\x0b\xf2"
-  "\x49\xcd\xf9\xc4\xeb\x0d\x25\x6f\xd9\x3e\xc5\x3b\x99\x6f\xa3\xfd"
-  "\x2f\x91\xfd\x87\x13\xfb\x54\x87\xcc\xc7\x21\x6b\xb2\x36\x20\xcf"
-  "\xa5\xc8\x8b\xf7\xcb\x2b\x19\x4d\x4f\x96\xd3\x27\x26\xa7\xe4\xdc"
-  "\x00\x39\xa1\x7c\x92\x3d\xfe\xed\x4e\x2e\x16\xed\x43\x19\x8d\xe1"
-  "\x75\x72\x3d\xca\x68\x24\xb8\x8c\x92\x9b\x83\xeb\x5a\xb2\x88\x3d"
-  "\xa7\x43\x30\x7c\xfd\x28\xbb\x11\xae\x83\x92\x9c\xc6\xca\x67\x69"
-  "\x94\x2c\x9f\x89\xb5\x71\x69\x7a\x40\x1b\x3d\x88\xa3\x4b\xb4\xf5"
-  "\xbe\x99\x01\xb8\xf5\xc1\x75\x71\xa9\x05\xdb\xe9\x09\xde\xce\xa5"
-  "\x0d\xa1\x75\x71\x29\xdd\x93\xe3\x19\xab\x8b\x4b\xe5\x7b\x90\x83"
-  "\x95\x19\x60\xd6\x60\xf5\xdc\xa7\xa1\xd8\xc4\x0e\xf7\x25\xd3\x7b"
-  "\x2e\x45\xfa\x0c\x7f\xfd\xc3\x36\x50\x39\xe2\x9f\x5b\x8c\x25\x48"
-  "\x0e\x67\x74\xa0\xbe\x9c\x4e\x0e\x59\xef\x2b\x0e\xe0\xd5\x05\xc4"
-  "\xef\x19\x54\xab\x1f\x12\xfc\xba\xff\x97\x01\x34\xd5\x07\xe7\xd7"
-  "\x7d\xc7\x90\x5f\x17\x82\xf3\xeb\xbe\xce\xd0\xfc\xba\x8f\xe4\x7f"
-  "\x61\x2c\xbf\xee\x07\x25\xbf\xe8\x0e\x40\x6a\xdf\x2d\x71\xa8\x1b"
-  "\x23\x9b\x58\xa3\xf0\xe5\x31\xd1\xa8\x2b\xa2\xcc\x00\x95\x49\x8a"
-  "\x76\x09\x3d\xd1\xdd\x08\xda\xf3\x70\xff\x0c\xd9\xfe\xa7\xd6\xc3"
-  "\x64\x36\xb2\x9e\xd1\xfd\x3d\x54\xce\x66\xba\xd0\x4a\x77\x8f\xd1"
-  "\x3c\x5e\x40\xbd\xa6\xe0\xbe\xe0\xfe\x5a\xe4\xe9\xab\x41\xd2\x8f"
-  "\x88\xb9\xc8\xfb\xed\xfe\x3e\xe2\xfe\x56\x7f\x19\x21\xdf\xd4\xfc"
-  "\xf4\x5c\xd5\x44\x3e\xe3\xcb\x2c\x25\x71\xac\xcc\x52\x4e\x08\x79"
-  "\xa5\xbc\xeb\x4f\x5f\x4a\x5a\x70\x79\xa5\x64\x86\x96\x57\x4a\x71"
-  "\x68\x79\xa5\xd4\x93\xbc\xec\x90\xd2\xe3\xdf\x6f\xa4\x1c\xf3\x6f"
-  "\x2f\xd6\x8b\xe5\x98\x7a\xd2\xb5\xf4\x3c\xd1\x76\xcb\x1f\xf2\x71"
-  "\x24\xab\x46\x8c\xaf\x90\xfe\x59\x44\xe3\x95\xe2\x08\x89\x1b\x79"
-  "\x58\xbb\x2b\xe4\x39\xf5\x51\xdd\x38\xb6\xa3\xf5\x6a\xfc\x1e\x51"
-  "\x78\xe0\x87\x5e\xb5\x6a\x09\xfe\x56\x9f\x81\x65\xdb\xbd\xea\x30"
-  "\x0b\xed\x27\xe1\xfb\x48\xf8\xbc\xff\x03\xc7\x95\xb2\xa0\xf5\xc3"
-  "\x34\xc7\x5b\x2d\xe6\x0f\xff\x7c\x06\x1e\x5c\x2e\xe4\xb2\xec\x31"
-  "\x7f\x3e\x3e\x60\x0f\x2e\x97\x07\x5c\x28\x97\x3f\x07\x97\xcb\x83"
-  "\xb1\xa1\xe5\xf2\x20\xed\x3d\xfb\xf3\x58\x3b\x7a\x30\x4d\xb2\xa3"
-  "\xbd\x54\x46\x97\x47\xf1\xea\x83\xff\x46\x30\xf8\x1b\x6d\xe4\x41"
-  "\x7e\x07\xd3\xbc\x01\xd9\x8e\x78\x99\x62\xc4\xc5\xeb\x97\x60\x4c"
-  "\x12\x0e\x25\xde\xa6\xe8\x81\x60\x76\xf2\x20\xbf\x53\x78\xbe\x01"
-  "\xb4\xc8\xc3\x8c\x83\x84\x23\x1f\xe0\x3c\x2c\x9b\x42\x70\x94\x4e"
-  "\x67\x7e\x2b\xe0\xfb\x65\x38\xf2\x75\x02\xf6\x41\x3b\x1b\xd2\xf3"
-  "\xbb\x4c\xfc\x71\x2f\x93\xda\x3f\x99\xf7\x23\x04\x4f\x70\x01\x30"
-  "\x8b\x85\x3d\x2e\x2b\xf6\xb7\xc7\x65\xe9\xfe\xfa\x89\xfc\xc7\x72"
-  "\x5e\xf4\x73\xf8\xfb\xb0\xc7\xaa\x5a\xf2\xe5\xd8\xe6\xb2\xce\x00"
-  "\xdb\x44\x1d\x48\x7d\x49\xe8\x40\xea\xaa\x00\x5a\xfb\x82\xeb\xc0"
-  "\x32\x77\x68\x1d\x48\x8d\x0b\xad\x03\xa9\x49\xa4\x03\x76\x48\xcd"
-  "\xf5\xb7\xcd\xd4\x95\xfe\x6d\xc7\x7a\xb9\x6d\xc2\xb4\x2b\xb1\x4d"
-  "\x8c\x85\xae\x0d\x65\x87\x52\xfc\xaf\xa2\x7b\x7b\xae\x80\x67\xe2"
-  "\x1e\x0a\x58\x0e\xf4\x6e\x06\x7d\xbc\x9e\x78\x78\x88\x8f\xd1\x96"
-  "\xc7\x2a\xf9\x58\x2d\xc6\x5a\x66\x84\x7d\x83\xd6\xb6\x09\x7e\x3e"
-  "\xb4\xd9\xbf\xfd\xcb\x93\x82\xf3\x73\xf9\x4a\xe4\xa7\x39\x38\x3f"
-  "\x97\xeb\x43\xf3\x73\x79\x19\xed\x51\x1c\x6b\x53\xcb\xe9\xee\x31"
-  "\xad\xdc\x37\x9d\x87\xe5\x17\x27\xd6\x3f\x2d\x3f\xe9\xdf\x3f\x2d"
-  "\x3f\x7e\xe5\xfd\xd3\x43\x71\xc1\xfb\xa7\x87\x12\x83\xf7\x4f\x0f"
-  "\xa5\x09\x7b\x78\xc8\xe2\x6f\x0f\x0f\x65\xfa\xeb\x04\xf2\xee\x4b"
-  "\xeb\x9f\x1e\xea\x09\xb0\x81\x9a\x33\xf0\xf0\x63\x18\x53\xec\x13"
-  "\x72\x4b\xbb\x2e\x80\xc6\x81\xe0\x72\x7b\x58\x83\x72\xab\x09\x2e"
-  "\xb7\x87\x75\xa1\xe5\xf6\x70\x32\xca\xad\x66\xac\xdc\x1e\x5e\x77"
-  "\xe5\x31\xc5\xc3\xe5\xfe\x32\x7b\xd8\x70\xe5\x32\x7b\xb8\x33\xb8"
-  "\xcc\x1e\xee\x0b\x2e\xb3\x87\xa5\x3d\xff\x69\x49\xfe\x32\x4b\x8b"
-  "\xf5\x97\x19\xf2\xed\x4b\x93\x59\x5a\x59\x80\xcc\xb6\x9d\x81\x15"
-  "\x38\x6e\x56\xf7\x08\x99\xad\xf8\x8d\x3f\x8d\x69\x4d\xc1\x65\x96"
-  "\xd6\x82\x32\xdb\x16\x5c\x66\x69\x27\x43\xcb\x2c\xcd\x81\x32\xdb"
-  "\x36\x56\x66\x2b\xb4\x57\x2e\xb3\x15\xc9\xfe\x32\x5b\x11\x7f\xe5"
-  "\x32\x5b\x61\x09\x2e\xb3\x15\xf5\xc1\x65\xb6\xe2\x98\x90\xd9\x8a"
-  "\x7e\x7f\x99\xad\xe8\xf0\x97\x19\xf2\xed\xef\x94\x19\xca\xc7\x2e"
-  "\xd6\xb5\x3e\xb2\x62\x90\xcf\x2b\x3f\x92\x62\x87\x47\xb5\x62\x5e"
-  "\xfe\x11\xae\x3b\x92\x0c\xdf\x41\x98\xa4\xb1\x7d\xf7\x23\x1b\xa4"
-  "\xb4\xa7\xc6\xca\xe1\x11\x13\xf6\xab\x03\xed\xc5\x7c\xbd\x94\x90"
-  "\x21\xf1\x1c\xe1\xc4\x1c\xd9\x23\xf5\x54\x16\x65\xcc\x6c\x2e\x37"
-  "\x50\x5f\x8c\xf0\x4e\xc2\x43\xfb\xe9\x03\x70\xb5\x5f\x49\x5c\x16"
-  "\x7a\x2d\x76\xbb\xbd\xb5\x74\x21\xe2\x7b\xf4\x8f\x42\x57\x1f\x0d"
-  "\x8c\x7f\x1b\x31\xef\x6d\xa1\xa7\xab\x02\xe6\x4c\x1e\x0d\x11\xff"
-  "\x3e\x4a\xf1\x6f\x63\x70\x3d\x7d\x74\x9c\xf8\xf7\x51\x8a\x7f\x1b"
-  "\x15\xe3\xd5\xe9\x1b\xdd\xf6\x80\xf1\xea\xa3\xc7\xa3\x9d\x42\x77"
-  "\x78\x1c\x5b\xd1\x6e\x47\x9a\xfb\x02\x68\x46\xd9\xac\xdc\x2c\xd1"
-  "\xfc\x74\x40\x79\x77\x70\x9a\x57\xc6\x22\xcd\xef\x04\xa7\x79\x65"
-  "\x62\x68\x9a\x57\xae\x44\x9a\xdf\x19\x6b\x5b\x2b\xb3\x24\x3d\x08"
-  "\x32\x2e\x5f\x69\x09\x2e\xff\x95\x01\xf2\x87\x0c\x63\x31\x73\xf0"
-  "\xf2\xfe\x70\xad\x4a\x38\x5a\xd3\x4e\xb0\xa4\x23\x41\x60\x07\x02"
-  "\x71\x06\x87\x5b\x15\x3b\x46\xf7\x68\x0d\x7e\x50\xdd\x5b\x95\x22"
-  "\xec\x71\x55\xbd\xbf\x3d\xae\xca\xf0\xb7\xc7\x47\xdd\x01\xe5\x4c"
-  "\x01\xf9\x69\x5f\x9e\x8f\x5d\xd5\x1f\xa0\x03\x1f\x9e\x81\xd5\xd9"
-  "\x42\x07\x56\xff\xdc\x9f\x8e\xd5\x10\x5c\x07\x56\xc7\x61\xfb\x3f"
-  "\x0c\xae\x03\xab\x93\x42\xeb\xc0\xea\x74\xe4\xe5\x87\x4a\xbd\x5d"
-  "\x5b\x9c\x32\x39\x00\xc6\x18\xdc\xe7\xad\xae\x0a\x3e\xaf\xb3\xfa"
-  "\xb0\xe0\xf1\xea\x53\xfe\x3c\x5e\x7d\xdc\x9f\x87\xab\xe1\x4b\xe0"
-  "\xe1\xe8\x79\x34\x43\xd6\x35\x81\xf6\x6f\x3b\x03\x6b\x24\xfb\x4f"
-  "\xff\xa1\x3f\x8d\x6b\xa4\xf1\x4f\xb0\xb9\xac\x35\x59\xc8\x4b\x5b"
-  "\x70\x5e\xae\xb1\x04\x6f\xf3\x9a\x7a\xec\x83\x6c\xde\x31\xb6\xb4"
-  "\xe6\x18\xa6\xaf\xe5\x77\x89\x5d\x82\x98\x43\x98\xbe\xd6\x0d\x5a"
-  "\xde\x5f\x8d\xf6\x4b\x6b\x4e\xd2\x1c\x39\x9f\x63\x46\xfd\x8d\x9e"
-  "\x01\xe9\xd4\x07\x11\x5d\x9b\x8a\x03\xdf\x4b\xf2\xa3\x0c\xf8\x9e"
-  "\x53\xda\x7f\x12\x6d\x82\x74\x9b\xd3\x0d\xb2\xbe\x13\xbc\x3f\xee"
-  "\xf4\x44\xb2\x0b\x82\x97\x61\xc5\x5c\xa7\x25\xc0\x37\xa5\x67\x04"
-  "\x97\x71\xba\x21\xb4\xee\xa4\x57\x09\x39\xa7\xb7\xfa\xcb\x39\xfd"
-  "\xb0\xd7\x3a\x75\x1d\xb5\xd5\x8e\x7c\xbe\x12\x19\xd3\xfb\xcb\x90"
-  "\xfe\x7e\xef\xfa\x5e\x43\x29\xdc\x74\x16\x1e\x13\x77\x39\xab\x19"
-  "\x8e\x89\x55\xd0\xce\x7d\xc0\x63\x25\x9c\x4e\x84\xd9\xe4\x06\x35"
-  "\xdb\xfb\x62\x2f\xe5\x35\x5a\x99\x8b\xdf\x95\x66\x65\x3d\x74\x1e"
-  "\x05\xea\xc2\xb5\xa7\xe1\xb1\x07\xfc\xca\x6b\x00\x6c\x02\x47\xb1"
-  "\x98\xdf\x7f\xcc\x24\xcf\xc3\x87\x9a\xdf\x47\x98\x06\x79\x3d\xad"
-  "\x78\x17\xf6\x58\x6d\xc8\x7e\x19\x69\xa2\x7d\x98\x44\xd3\xf8\x7e"
-  "\xe0\x31\x87\xac\xbf\x62\x8f\xce\xe3\xe0\xdb\x03\xf2\x78\x14\xe6"
-  "\x35\x8f\x33\x9f\xab\xb0\x83\xc7\x17\x2b\xf1\x88\x33\x99\x1e\x5f"
-  "\x29\xef\xe3\xc0\xdf\x19\x97\xc1\x25\xd1\xf3\xb8\x25\x80\x9e\x5a"
-  "\x8c\x2d\x9b\x25\x1c\x0d\x97\xc1\x11\x6b\x3b\xbc\x04\xe6\x7b\x21"
-  "\xec\x2c\xac\xfb\xb4\x8e\xd6\xc9\x34\xf4\x43\x94\x1b\x34\x62\x6c"
-  "\xf7\xf8\x67\x5d\x71\x34\x87\x43\xfb\x73\xef\x6f\xa5\x77\x70\xfc"
-  "\x3d\x7e\xdc\xfd\xad\x5d\x26\x8f\x74\xf6\xce\x5a\xae\x13\x5d\xfa"
-  "\x0b\xad\x0d\x07\x58\xff\x41\xbe\x57\x6d\xad\xdf\xf8\xaf\x8a\xd6"
-  "\xe0\xd0\x5a\x88\x52\xb8\x1f\xe1\xdf\x10\xb6\xbe\x2e\x20\x26\x5d"
-  "\x1b\x62\xfc\xb7\x96\xc6\x7f\xf7\x07\xb7\xf3\xb5\xe3\x8c\xff\xd6"
-  "\xd2\xf8\xef\x7e\x65\xbf\x29\xde\xf3\xac\x6d\x50\xc6\xa4\x74\x2e"
-  "\x8a\x6e\x2b\xc5\x99\xeb\xa6\xdd\x51\x07\x31\x6e\x7a\xaf\x8c\xb6"
-  "\x69\xeb\x6f\x27\x7b\x8d\xe9\x72\xb4\xd0\x9e\x66\x2d\xdd\xf1\x2a"
-  "\xfa\x32\xb2\xd7\xb5\x76\xde\x97\xb9\x85\x2d\x9a\x4d\xcc\x31\xb7"
-  "\x0f\x75\x68\x9b\x5e\xc2\xb5\xb6\xb3\x44\xcf\xf8\x5a\x88\xa9\x7d"
-  "\x30\xd9\xd6\xcf\xfb\x45\x15\xc5\xab\x3c\x6e\x75\x5f\x04\xc2\xdb"
-  "\x56\xdc\x05\x84\xd7\x3b\xda\x4f\x12\xee\x75\xc9\x64\xe3\x84\x93"
-  "\x70\x77\x23\x1c\xe1\x25\x38\xb9\x1d\x62\x1f\xc9\xba\x2c\x65\xdb"
-  "\xf9\xfc\x0b\xd6\x8d\xe9\xdf\xa7\x79\x15\x1b\x95\x33\xaf\x67\xf3"
-  "\xfb\xe8\x9d\xd9\x85\x56\x66\x7e\x91\xcd\xcf\xa7\x39\xb1\x75\xfc"
-  "\xfe\xdc\x77\xfe\xcb\x1e\x6e\x9c\x05\x5a\x29\xed\x68\xbb\xce\x85"
-  "\x7a\xbc\xce\xe1\xef\x23\xd6\x05\xc4\xbf\x6b\xf9\x38\xd3\x0e\x8f"
-  "\xd3\xd9\x00\x20\xad\x0b\x25\x7f\xc0\x6c\xee\x21\xae\x1f\xe3\xad"
-  "\x6b\xa0\x77\xd2\xb4\x2e\x49\x9c\xfb\xf3\xc4\xe2\x80\xb9\x37\x47"
-  "\x35\x5f\xdb\xf2\x27\xac\xf7\x89\x8f\x84\x8e\x3c\xf9\x91\xbf\x4c"
-  "\x9f\xc8\x30\x9f\xa3\x77\x41\xa2\x3f\xd8\xe8\x0e\xf4\x8f\x4f\x98"
-  "\xe4\xd8\x2d\x20\xbd\x56\xee\x0f\x74\x79\x1c\x6f\x40\x3f\xf3\x04"
-  "\x8f\xff\x3d\x63\xfa\x85\x27\x3a\xb0\x7d\x7e\x3a\xd9\xcd\x75\xe8"
-  "\x09\x7b\x97\x13\xf5\x26\x9f\xf4\xff\xc9\xa7\x11\x66\x0f\xed\xcd"
-  "\xc3\xe7\xc9\xe7\xe1\xc9\x18\x8f\x15\xb4\x5d\x0e\xbe\xf7\x28\x06"
-  "\x75\x84\xeb\x2d\xf5\x1b\x0b\xc4\x9a\x20\xa7\x7f\x1d\x4f\xce\x95"
-  "\x79\x4e\x30\xdd\xf9\x7f\x02\xb1\xa6\x81\x74\xe1\x49\xa0\xf5\x11"
-  "\x53\x07\x60\x32\xe1\x92\x75\xc8\xe6\xee\x85\x6e\x77\xe0\x98\xe7"
-  "\x49\x63\xf0\xb6\x3f\x49\xfd\xff\xab\x76\x78\xb2\xcf\x5f\xb6\x4f"
-  "\xf2\xfe\x5f\x7e\xaf\x63\x47\x1e\x04\x94\x6b\xf7\x97\xfd\x13\x19"
-  "\x94\x1f\x72\x9d\x4d\x79\x7b\x1f\x8e\x67\x36\x39\xf9\x9a\xab\xa7"
-  "\xd0\xfe\x9f\x88\x1d\xcf\x0f\x32\x6d\x7b\x9f\x17\x61\xa5\xf5\xb6"
-  "\xe8\xb7\x9e\x4a\xf3\x9b\x33\xba\x9e\xcf\x19\x6d\x3a\x03\x4f\x49"
-  "\xef\x7e\x32\xf6\xfb\xd3\xf7\x54\x56\xe8\xd8\xe0\x29\x7a\xff\xb3"
-  "\x29\xb8\xcf\x78\xaa\x21\x78\x6c\xf0\x54\xb3\xe4\x17\x36\xb1\x88"
-  "\x40\x3d\x78\xaa\x07\x65\xcc\xcb\xc8\x63\x58\x9a\x0b\x0d\x3d\x86"
-  "\xcd\x80\xd1\x31\x6c\x3e\xf9\x83\xa7\xfa\x47\xc7\xb0\x8e\x60\x63"
-  "\x58\x7b\x10\x79\x66\xa4\x06\x97\x67\xc6\x86\xe0\x63\xd8\x0c\xa3"
-  "\xe8\xe7\x33\x8e\xf8\xcb\x39\xa3\xca\xf7\x4e\xf8\xa9\xac\x2f\x2f"
-  "\x1e\xce\x70\x8d\x8d\x87\x9f\x2e\x14\xb2\x7a\xfa\x7d\x7f\xda\x9e"
-  "\x8e\x09\xee\xdb\x9f\x4e\x08\x1d\x0f\x3f\x9d\x1a\xda\xb7\x3f\x9d"
-  "\x39\x36\x1e\xd6\x4d\x0a\x80\x29\x1b\x8d\x95\xfc\x62\xb3\xa7\x1b"
-  "\x04\x9f\x9e\xa6\x78\x2e\x4c\x01\xdf\xec\xaf\xef\x4f\x93\xbd\x45"
-  "\xa3\x6f\x3b\x4b\x3e\x4d\xd6\x99\x50\x3c\xa1\x33\x4c\x6e\xa9\x83"
-  "\x08\xb4\x81\x0f\x87\xac\xcf\x8c\xea\x3f\xad\xa5\xa3\x7a\xc8\x47"
-  "\x86\x5c\xd3\xa6\x96\xe9\x23\x3a\x9e\x49\x1e\xef\x7d\x69\x58\x1c"
-  "\xa4\xbf\x36\x86\x1f\xcf\xf0\xf8\x8f\x70\x8c\x2f\xb3\x67\x8e\x06"
-  "\xd8\x98\x53\xac\x85\x5d\xbf\x53\xc8\x6d\x7d\xc0\x58\xf6\x99\x0e"
-  "\xbe\x2f\x2e\xa4\xbf\x7d\xa6\x3f\xb8\x8e\xae\x1f\xe5\x17\xea\x3f"
-  "\xe1\xbd\x37\x20\x5f\x27\x64\xb0\xde\xe4\x8d\x50\xce\x75\xaf\x5f"
-  "\xec\xef\x93\xd6\xeb\x02\xca\x05\x8c\xff\x9e\xe9\xa0\xfc\x89\xf5"
-  "\x37\xeb\x8f\x84\xee\x6f\x36\x2c\x12\xed\x7f\x36\xe0\xfd\xf2\xfa"
-  "\x8e\xf1\xfb\x9b\xf5\x21\xda\xbf\x01\xfc\xfb\x9b\x0d\x01\xef\xe8"
-  "\x37\xe8\x82\xf7\x37\x1b\x16\xcb\x7e\x46\xf8\x8d\x0d\xdf\x9d\x98"
-  "\xbf\xd9\x60\xf0\xf7\x37\x1b\x32\x2e\xe7\x6f\xda\xc6\xf8\x9b\x0d"
-  "\xcd\xd1\x0d\x41\xdb\xd2\x19\xdc\xdf\x6c\xe8\x13\x32\x7c\x36\xd9"
-  "\xdf\xdf\x6c\x70\xfb\xcb\x70\x43\x80\x0c\x9f\x0d\x78\xff\xbd\xbe"
-  "\xe3\x6a\x7d\x52\x58\x58\x98\x3a\x4c\xa5\x56\x85\x01\x5d\x68\xa2"
-  "\x82\xc9\x61\x9a\xb0\x70\xfc\x4c\x92\xbe\x27\xab\xc3\xd4\x1a\xfc"
-  "\x84\x4b\xdf\x93\x02\x9e\x27\x53\x59\xfc\x68\xa4\xef\xf0\x80\xe7"
-  "\x49\x97\xc9\x9f\x2c\xd5\x2b\xd7\xaf\x09\x78\x0e\xbf\x4c\xfe\xa4"
-  "\xbf\xb3\x3c\x8c\x79\xf6\xdf\x5f\xb8\x22\xaf\x68\x73\x6e\x4e\x16"
-  "\x5f\x5b\x9e\xad\xdb\xbc\x65\x4b\x76\x41\x81\xce\xb8\x4d\xf7\xe0"
-  "\x03\x8f\x2f\x5c\xa2\x13\x4b\xd4\x73\x97\xde\x9a\x15\x09\xab\x76"
-  "\xe4\x53\xc6\xaa\xb5\x2b\x32\x74\xe9\x0f\x3e\xe0\x9f\x29\xa3\xe1"
-  "\x4b\xd1\xc7\xc3\xa2\xbc\x03\xbb\xe2\x7a\x80\xaa\xeb\xb9\xdf\xe9"
-  "\xeb\x6a\x02\x10\xe3\x89\x2d\x15\x9d\x18\x75\xb0\x61\x33\xa3\xfd"
-  "\x0a\xa7\x61\xd3\x52\x6a\xc4\xbc\x26\x0b\x18\xb6\xd2\xf9\x22\x9b"
-  "\x9e\x66\xbf\x70\x80\xee\x11\x50\x9f\x06\xfd\x1b\xed\x38\xfa\xa7"
-  "\x67\x5b\x9f\x1b\x74\x66\x8a\x6d\xb7\xdc\x8b\x79\x2a\x76\x9f\x17"
-  "\xd3\x9c\xd2\x3e\xf6\xe7\x56\xf0\xb4\x5f\x58\x64\xb8\xe8\x33\xb0"
-  "\xc9\xc3\x7e\xc1\xf8\x33\xbb\xaf\x56\x82\xdb\x74\xc2\x6b\xdd\x58"
-  "\x4b\x7e\xa1\x41\xdc\x93\x0d\x6f\x4c\x07\xed\x1b\xd7\xd3\x59\x8b"
-  "\x9b\xda\xe5\xb5\xd1\x15\xf8\x6c\x07\x7d\x3d\xd5\x4d\xb0\x5e\xf5"
-  "\xc6\x7f\xe7\xf0\xd3\xfd\xe0\x9d\xbe\xb5\xd4\x9b\xda\xe9\x4e\xf9"
-  "\x35\x7f\xc1\x2e\x3f\xf2\x3f\xe2\x6c\xc5\x16\x88\xf6\xb0\xcf\xe6"
-  "\xa7\x81\xaa\xbb\x0c\x60\xa7\x9b\xb9\x5b\xf3\xcf\x62\xfd\x99\x0f"
-  "\x44\xef\x64\x9f\xd9\x30\x6e\x5c\x35\x60\x66\xd5\xe7\x40\x83\x36"
-  "\xad\x6a\xcd\xa7\x3d\x0d\x99\x09\x87\x2e\x81\x06\x79\x30\xe3\x2c"
-  "\x6c\xce\x28\x5e\xc5\x3c\xe6\x55\xa0\xf9\xad\x89\xf6\x92\xfe\x7a"
-  "\x61\xf5\xef\x41\xf3\xaf\xc3\x16\xf5\x30\x8b\x83\x62\x23\xeb\x67"
-  "\x74\x06\xab\x93\xb9\x68\xdd\x6b\x67\xa6\x87\x60\x66\x0f\x99\xe3"
-  "\xa0\xdb\xe8\x84\x92\x53\xcc\x55\xfe\x7b\x71\xb6\x43\xd7\x80\x93"
-  "\xf6\xa6\x6a\x4b\x56\x41\xd8\x99\x0c\x50\x77\xe9\xeb\xc1\xb6\xc1"
-  "\x09\xc5\xa7\x58\x7f\x67\xe6\x5f\xa0\x5b\x7f\x0c\x36\xf5\x82\xba"
-  "\xb3\xef\x63\xe0\xe7\x88\x56\x7a\x32\x4b\x2f\x42\x5c\x49\x0e\xa5"
-  "\x5d\x84\x5d\x25\x30\x65\xd7\x1f\x68\x2c\xd4\x8b\xf5\x9c\x83\x67"
-  "\x4e\x82\x0a\xf1\xa9\x77\x7f\x0c\x71\xbb\x9f\xa6\xbd\xda\x29\xd0"
-  "\x50\x0a\x71\xcc\x9c\x10\x35\x6c\x4e\x88\x19\x66\x09\xd3\x87\xcc"
-  "\x09\xb1\xdd\x06\x84\xef\xfb\x39\x4c\xed\x85\xd8\x5f\x9c\xed\x55"
-  "\xd7\x7f\x0e\x33\x74\xab\x49\xfe\x9b\xd7\x35\x7c\x8e\xf0\x95\xbf"
-  "\xb7\x7b\xb1\xac\xb2\x8c\x3b\xe2\xf7\x2e\x5b\x86\x0b\xbc\x88\xab"
-  "\x7e\x18\x66\x34\x0c\x43\x9c\xb7\xe2\xf7\x76\xe2\xc5\x48\x65\x5b"
-  "\x1c\xfa\xc1\xc9\xef\x3c\xd7\xa2\xb1\x75\x0e\x40\x97\x73\x18\xba"
-  "\xe1\x4f\x60\x33\xfd\xb5\xf5\x5f\x9f\x6b\x09\xc7\x38\x52\xd5\xba"
-  "\x8b\xd6\x9f\x0b\x9d\x31\x77\xd1\x19\x54\x16\xa8\x29\x85\x28\xc3"
-  "\x2e\x98\x7c\x16\xd3\xb9\xcf\x29\xff\x40\x67\x73\xff\xb5\x75\x17"
-  "\xdf\x5f\xad\xaf\x2f\xed\x82\xb0\x6e\x67\x3d\xed\xe3\x55\x7b\x22"
-  "\x3d\x99\x36\x67\x0f\xd8\x0c\x7f\x6e\xf5\x6a\x3d\x69\x55\x5e\xd0"
-  "\xbe\xfd\x45\x8f\xda\xa6\xf9\x02\x6c\x19\x4e\xf8\x10\xeb\x66\x95"
-  "\x9e\x5c\xf4\x55\x29\xdd\x4e\x17\x9d\x43\x93\xc8\x06\xe3\x22\x6b"
-  "\xf2\x61\xee\xa1\xcf\x21\xfe\xe0\xe7\x90\xc0\x86\x12\xd4\xb4\x67"
-  "\xfa\xd9\x73\x31\x70\x10\xbf\xa3\x70\xec\x85\xed\xe5\x7b\xa7\x59"
-  "\x84\xb4\x77\x7a\x24\x01\x1a\x87\x7d\x7b\xa7\x87\x07\x7d\x7b\xa7"
-  "\x51\x97\x3a\x68\xff\x34\xda\x85\x85\xf4\xb9\xe6\x3c\x68\xf6\x9e"
-  "\x07\x98\x6f\x51\x83\xee\x39\x3a\x13\x63\xcb\x3c\x5b\xd6\x39\xfe"
-  "\xfb\x34\x3c\xd7\x87\xdf\x51\xf8\xc1\xf1\xdb\x73\x7c\xbf\x6f\x9f"
-  "\xa4\xb7\x98\xa6\xc6\xb4\x2e\xfc\x0e\xc3\xef\x8f\xcc\x0d\xcc\x81"
-  "\x75\xd0\x5e\x87\x48\xd2\x5f\x69\x9f\x36\xf6\x89\xcf\x1d\xb7\xc3"
-  "\x2b\x55\xb2\x1e\x0b\x7f\xbe\xa9\xe3\xc3\x33\xe7\xe8\x5c\x5f\x07"
-  "\xa7\x67\x44\xaf\xa2\x33\x7e\xa5\x74\xa2\xe1\x56\xaa\xf7\x34\x6c"
-  "\xd1\xe2\x77\x34\x7e\xd0\x2e\x9f\x6b\x90\xcb\x0e\x8e\xe8\xb1\xce"
-  "\x2d\x33\x31\x9d\xc9\xe9\xd8\x5e\x0d\xe5\xbd\x77\xe6\x9c\x5a\xc0"
-  "\x24\xa8\x11\xa7\x4b\xc2\x8f\xb6\xbe\x29\x97\x6c\x7a\x50\x1d\xcd"
-  "\xda\xb2\x92\xa0\xe1\x7a\xd6\x73\xf0\x00\x6b\x17\xb6\xb6\x25\xd3"
-  "\x0e\x55\xfc\x4c\x05\xec\xb3\xdb\xab\x30\xaf\x0d\x7b\x4f\xe2\x4b"
-  "\x7b\x26\xad\x27\xdd\x62\xb1\x43\xe4\x29\x65\x1b\x98\xf5\x59\x03"
-  "\xf5\x9b\x3f\x29\x6d\x0d\x67\xea\x8d\x86\x6e\xfb\x00\xfc\xeb\x70"
-  "\x7f\xb8\xf9\x37\xa0\xb6\xb9\x4f\xc3\x82\x58\x88\xa3\x39\x98\xc6"
-  "\x03\xcc\x8e\xdf\xfd\xf8\x19\x40\x3d\x99\x79\x16\xb6\x74\xdd\x11"
-  "\x0b\xb1\xbf\x33\x81\xe4\x8f\xb6\xfc\x45\xe1\x8f\x5e\xea\xea\x6b"
-  "\x51\xf8\x22\xfd\xcc\xb1\xbe\xe8\xf9\x6f\x08\x5f\xc4\xdc\xc2\xf7"
-  "\x78\xec\x52\x7a\x78\x40\xba\xb4\x67\x64\xeb\xa7\x01\xe9\x2e\x29"
-  "\xfd\x0f\x01\xe9\x0e\x29\xfd\x3a\xd9\xd7\x75\x13\x1d\x3b\xc8\xd7"
-  "\x65\x5f\x22\x5f\xd7\x9d\x25\xf9\x3a\xbe\xc7\x31\xfb\x63\xf6\x2f"
-  "\x16\x71\x7f\x3b\x64\xbf\x4f\xf4\xb3\x5f\x80\x4c\x7b\x04\xa6\x15"
-  "\x52\x5a\xed\x9f\x40\x83\x1f\xee\xe7\x98\x75\xe3\x7f\x92\x9f\x23"
-  "\x1f\x47\x7b\x51\xde\xba\x9e\xf5\xbe\x75\x80\x9d\x6c\x38\xc0\x3a"
-  "\x87\xac\x59\x7d\xb2\xbf\x7b\x05\xd3\xaa\x30\xed\x15\xcc\x27\xbf"
-  "\x47\x3c\xe9\xca\x68\xa1\x73\x1c\xfb\x50\xc7\x12\xa3\x55\x60\xa8"
-  "\x46\x9d\xa7\xf3\x9f\xca\x90\xbf\x36\xf4\x49\xb4\x26\x97\x9f\x87"
-  "\xab\x4e\x44\x1f\xd5\x47\xf6\x76\xfd\x5e\x2f\xcd\x4b\xfc\x05\x4a"
-  "\x9d\xec\x2c\xed\x0f\x21\x1a\x36\xed\x7c\x84\xce\x79\x55\xb5\xeb"
-  "\x01\x68\x7f\x3f\xed\x5f\x41\xbf\xab\xa9\x45\x9a\xda\x72\x49\xd6"
-  "\xd9\xb9\x76\xf8\x20\x57\xc8\x5a\xcf\xcf\x8f\x3e\x0d\x59\xc7\x98"
-  "\x15\x7d\x21\xb6\x2d\xda\x63\x01\x3a\xb3\x04\x6d\x94\xe6\x59\xf5"
-  "\x6f\xe1\xa7\x56\x3e\xb7\x84\xce\x00\x47\x18\x5b\xaf\x0b\x88\x66"
-  "\x3b\x64\xb9\xbb\x8a\x5b\xa8\x7c\x13\xf1\x86\x59\xcd\x32\x0e\x15"
-  "\x3f\xf7\x04\xc7\xf0\x74\xee\x89\x1d\xb2\xc5\x9e\xba\xc8\xb6\xb8"
-  "\xae\x0d\x0e\x20\x3f\x6f\xeb\x47\x1c\xc5\xa7\x05\x0e\xc4\xc5\xd0"
-  "\xef\xfb\xe5\x49\xf8\xa7\x94\xb0\xcf\x10\x7f\x2e\xc9\x8b\xce\xa9"
-  "\xa2\x75\x49\xc8\x97\x28\x3a\xf3\x40\xc4\x9d\x59\x17\x1b\xff\x04"
-  "\x20\x9d\xb5\x85\xfa\x96\xe5\xa4\xb3\xac\xe8\x7c\x2d\x7e\xb6\x96"
-  "\x3a\x09\xd8\x8e\x84\xa8\xd1\xf3\xb5\xfe\x07\xce\xd6\x42\xfe\xc7"
-  "\x1d\x52\xb3\x63\x48\xbf\x93\xce\xd7\x42\xfa\xd7\x91\x1e\x4a\x6d"
-  "\x72\xbd\xfe\x0c\xe7\x79\x32\xa5\xd5\x58\x59\x87\x2c\x7f\x6a\x2f"
-  "\xb5\x05\xf3\x74\x22\x1e\x64\x3d\x76\xd8\xea\xa2\x7c\x4c\x8b\x22"
-  "\xf8\x05\xe8\xc7\x6c\x59\x1e\x78\xe7\x8c\x47\x5d\xb3\x0b\x34\xc2"
-  "\xa7\xe9\xa7\x51\x79\xe1\xd3\x9e\xef\xf0\xf9\xb4\xe7\x7f\x2e\x7c"
-  "\x9a\xe0\xb1\xf0\x69\xcf\xbf\x2b\x7c\xda\xf3\x3f\xe2\xeb\x87\xd0"
-  "\xa7\x51\x1e\xf9\x35\xd9\xa7\x1d\xbc\x9e\x75\x90\xef\x18\xb2\x3e"
-  "\x5f\x2f\xfb\xb6\xfd\x98\x46\xbe\x83\x68\x14\x7e\x2a\xdb\xc1\xfe"
-  "\xdf\x04\x10\xeb\x33\xe9\xb7\x9e\xce\xa1\xe8\x97\x7e\x53\x3f\x12"
-  "\x21\x7c\xdc\xf3\x03\x3e\x1f\xf7\xbc\xc1\x57\x96\x7c\x9c\x5e\x25"
-  "\x7c\x9c\x48\x6f\x7c\x86\x7c\x5c\xb6\x83\x78\x20\xe1\x57\xd3\x7b"
-  "\x33\x09\x1e\xf9\xb8\xc5\xa5\xf4\x71\xfe\xf6\xa5\x4f\x95\x7d\x1c"
-  "\xf9\x36\x7c\x5e\x87\x3e\x8d\x9f\x47\x4f\x76\x56\x87\x3c\x97\xed"
-  "\x8e\x64\x40\x6d\xa6\x73\xa2\x89\x6f\xcb\xce\xc1\x64\xe9\x4c\x17"
-  "\xa9\xdd\xfa\x5a\x79\x5f\xa4\x1d\x9e\xaf\x0f\x8c\x99\xe9\xc5\x84"
-  "\x62\xef\xd6\xcd\x1e\x9a\xdb\xb5\x9c\x06\x5b\x3d\xb3\x74\xbb\x4f"
-  "\x81\x77\xef\x8b\x9f\x90\x5c\x71\x7c\x31\x89\xbe\xc9\xef\x60\xff"
-  "\x79\x62\x93\x93\xcf\xd7\x7f\x52\xa3\xc6\x3c\x13\x7c\x5b\x91\x77"
-  "\x8e\xea\x50\x94\x9b\xe7\xcb\xcb\x89\xa0\x3c\x9a\x63\x44\xb8\x96"
-  "\x50\x73\x0a\x13\xa7\x23\xe7\xe9\xd0\x74\xe4\x14\x8e\x43\xc7\x77"
-  "\x39\x1d\x18\x6f\xe1\xf8\x68\xda\x79\xc8\x49\xa1\x67\x7e\xb6\x68"
-  "\xf0\x7a\x7e\x29\xe5\x87\x29\xf2\x95\x75\x7d\x12\xa4\xbc\xa2\xbe"
-  "\x17\x54\xe3\xe3\x7f\x61\xd6\xf8\xf8\x5f\x78\xe0\x32\xf8\x37\x93"
-  "\xef\xa3\xbd\x77\x1e\xab\x3f\xdc\x7c\x37\xb7\xbd\x0e\x3a\x63\x09"
-  "\xe1\x2a\xa4\xf7\x2d\x9f\x98\x67\xf1\xf1\x1f\x3f\x6f\xa7\x1a\xf3"
-  "\xf9\x79\x9d\xe8\x97\x53\x77\x02\x88\x35\x7d\xa3\x65\x7e\x1e\x48"
-  "\xdb\x54\xb7\x4c\x1b\xcf\xff\x38\x90\x36\xcc\x9f\xa7\xc8\xf7\xf8"
-  "\x64\xfe\x82\x69\x9c\x79\xa4\x28\x1b\x6a\x27\xdd\xb1\xd0\x86\xc3"
-  "\x16\xda\xeb\x53\x37\xfa\x6e\xe4\x45\xd4\x7f\x3d\x7f\xb7\x23\xed"
-  "\xed\xa5\xb5\x32\x37\x77\x3b\xe9\x4c\x32\xa7\xbc\x17\xe4\x06\xec"
-  "\x47\xa6\xd3\xf9\x2b\x34\x9f\xbe\xc9\x93\xae\x16\x67\x25\xbf\x58"
-  "\x2b\x97\x0d\x35\xf7\x48\xf5\x4a\x75\xf2\x7d\x52\x58\xa6\x5d\x2e"
-  "\x43\xb8\x69\x6f\x10\xfa\xff\x9b\xf9\x39\x65\xee\x01\xf2\xb7\x37"
-  "\x60\x7c\x3c\x5d\xd4\x93\x09\x52\x3d\x68\xdb\x39\x89\xe3\xd4\x33"
-  "\x4e\xfb\x72\x93\xae\xbc\x7d\x20\xb5\x2f\xd7\x70\x99\xf6\x8d\x57"
-  "\xef\xd1\x2b\xaf\x37\x46\xae\xb7\xff\xca\xf9\xfa\xd2\x8c\x89\xf3"
-  "\x35\x51\xe2\xeb\x4b\xe9\x97\xe1\x6b\xb0\x7a\xca\x26\x5e\x8f\x4e"
-  "\xae\xa7\x25\x58\x3d\xc0\xff\x42\x9e\xd3\xa3\x95\xef\x2e\xa0\x7b"
-  "\x43\xc4\x59\xe5\x79\xa0\xbc\x5b\x45\xdc\x27\x92\x17\x2b\xdf\xad"
-  "\xe2\xdb\x67\x96\x77\xe7\xa6\x26\x8a\x43\x98\xd7\x0e\x79\x49\x34"
-  "\x17\x98\x5a\xa2\xbc\x83\x24\x2f\xed\x32\x77\xba\xd0\xd9\x38\x09"
-  "\x54\x37\x63\xfc\x0c\x16\xa7\x38\x2f\x2f\xaf\x82\xce\x69\x10\x6b"
-  "\x8a\xf2\x5a\x84\x6d\xe6\xd5\xd9\xe1\x25\x7e\xce\x22\x9d\xc1\x3c"
-  "\x68\x96\xe0\x6f\xa4\x3e\x74\x14\xa6\x45\x86\x09\x3a\x27\x59\x79"
-  "\xa2\xe7\x70\x69\xa2\xdf\x1e\xc3\xe5\xf9\xf9\xdb\xf2\x97\xe8\x0a"
-  "\x5e\x7a\x6e\x5e\x81\x71\xb3\xb1\xb0\x80\x6f\x46\x8f\x04\x4c\xd0"
-  "\x19\x73\x5e\xca\xde\x56\x68\x4c\xd8\xb1\x39\x47\x6c\x5e\x9f\x83"
-  "\x80\x4a\x20\xf0\x3b\xdb\x3f\x0e\x7d\x50\x0f\x53\xf3\xb3\x23\x06"
-  "\xf8\x19\x98\x74\xfe\xbb\xb4\x37\xb7\x3d\x0e\xc0\x89\xe3\xa3\x21"
-  "\xeb\xb6\x0d\x76\x78\xfc\x88\xcc\x47\x3a\xa7\x10\xe3\xa4\xb8\xb3"
-  "\xb0\x6d\x27\xc9\x7e\x0d\x86\xbc\x8d\xe2\x3c\x08\xbe\xff\xdf\x66"
-  "\xc4\x84\x6e\xd0\xb6\x16\xd1\x3c\xef\x36\xd4\x81\x3c\x3b\x3f\x77"
-  "\x71\x17\x8d\xbf\x0d\xd7\xc9\x71\x09\xbd\xb7\x12\xef\x99\x6f\xbe"
-  "\xff\x34\x6c\x5b\x4e\xf5\x92\xdd\x1c\xc2\xf8\x97\x70\x31\x6b\x9e"
-  "\x8b\x62\x60\x7c\xd6\x22\x0d\x76\x39\xf6\x45\x7a\xa3\x58\xc4\x89"
-  "\x56\x3b\x18\x62\x7f\x15\xe3\x00\x69\x3f\xb7\xf6\x90\xd8\xbb\xad"
-  "\x19\xb2\x1a\xa2\x46\x61\xad\x08\x5b\x71\xa2\x95\xee\xeb\x09\xca"
-  "\xdf\x48\x5b\xab\x77\x24\x23\x5c\xd9\x66\x1c\xb3\xa3\x7c\x0c\x1f"
-  "\x61\xdb\x63\x49\xd6\xd2\x39\x22\x93\x30\xed\x6d\xba\xff\x80\x55"
-  "\xda\x5a\x31\x6d\x12\x7e\xf7\x92\x4c\xe9\x9c\x03\xcc\xa3\xb5\x3e"
-  "\xaa\xee\xe2\x0b\xad\x6d\x71\xa7\x51\xaf\x0d\xe8\xff\x32\x4e\x89"
-  "\x7d\x71\x08\x8f\x75\xd8\x2c\xc3\xd0\xae\x63\xad\x34\x07\x88\xb4"
-  "\x9f\x6a\xd7\x39\x81\x85\xad\xff\x84\xca\xa1\x5d\xc4\x99\x4d\x14"
-  "\xfb\x60\x3a\xdf\xff\x67\xe8\x91\x79\x6e\xd4\xb1\x73\x04\x13\x6a"
-  "\xde\x9a\xfa\xe0\x1a\xde\x97\x7c\x0e\xb4\xc6\xab\x0f\x0c\xce\x40"
-  "\x7f\x7f\x6b\xd6\x12\x5d\xd6\x66\xa3\x2e\x37\x27\x2f\x5b\x97\x95"
-  "\x93\xa5\xcb\xdb\x66\xd4\x3d\xbf\x8d\x26\x90\x68\xca\xc8\x4f\x27"
-  "\xbc\xd4\xbe\x1d\x19\xe1\xf2\x3b\xf2\xc1\x1d\xfa\x49\xd8\x7e\xe4"
-  "\x49\xfe\xaa\xc1\x21\xfd\x64\x7f\x9e\xe4\xdf\x29\xf4\x78\x3b\x8e"
-  "\xff\x0c\xf1\x62\x7f\x61\x58\x3f\x3e\x63\xfb\x0d\xfd\xfe\xb6\x97"
-  "\x5f\x22\xc1\x1e\x95\x61\xb9\x5e\xcc\x3e\x3b\x9a\x57\x23\xe9\x63"
-  "\xa3\xd8\x8b\xcc\xcf\xab\x69\xe4\x7b\x04\xb6\xdb\x43\x96\xa1\x33"
-  "\xba\x76\xc1\x96\xf3\xb0\xfd\x37\xcc\xba\x3d\x56\xd2\x21\xad\xb7"
-  "\xdc\xd6\x23\xe9\x0f\xea\x44\xbe\x6e\xac\xfe\xe4\x17\x93\xfe\xb0"
-  "\xa1\x0c\x2d\x5f\x4f\xe2\x76\xa1\x9f\xc2\x67\xec\x4f\xed\xb0\xbd"
-  "\x8c\xda\xe1\xdc\x91\xa1\x35\xbf\xc1\xfb\xeb\x4f\xe9\xdd\x6c\x9b"
-  "\x8b\x9f\xb1\x14\x81\xba\x81\x32\xca\x37\xca\x32\x92\xe1\x83\xdb"
-  "\x30\xd7\x17\x7f\x1d\x13\xfc\xec\xe2\x3a\x86\x71\x01\xd2\xa4\x96"
-  "\xe3\x02\xea\x03\x90\xb6\x3e\x63\x09\x63\x58\x47\xaf\x42\x0f\xce"
-  "\x07\xd3\x03\x94\xed\x96\xdc\x6d\x5b\x5e\x44\x43\xcf\xcf\x36\x6e"
-  "\xd1\xd3\xf9\x15\xe4\x07\xf8\xe1\x18\xb7\x66\xe9\x0a\x0b\xb2\xb7"
-  "\x44\x42\x30\xa8\xd1\x4c\xa5\xfc\x63\xbc\xa8\xaf\x83\x83\x19\xe1"
-  "\xb4\x87\x43\xec\xd9\x30\x1e\x1c\x2c\xc0\x71\x8f\x9f\xdc\x8d\xdf"
-  "\xb5\xc5\x25\x62\x9c\x98\x08\x3c\xe6\x47\x9e\x89\x75\x08\xc6\x3f"
-  "\x10\x1f\x06\xd5\x2a\xec\x0f\x0a\xea\x64\x1d\xc0\xdf\x4d\xd8\x26"
-  "\xc5\xb9\xf2\xc6\x93\x83\xea\xf0\x53\xe4\x7f\xc4\x7a\x93\xb3\xe8"
-  "\x07\xa2\x1b\x4f\x43\x01\xf9\x7e\xba\xab\x83\xca\x9f\x94\xcb\x54"
-  "\x8f\xee\xa3\x36\x26\xcb\x7a\xa2\x28\xf3\x11\xa5\x89\xf1\x73\xbe"
-  "\x83\x64\xce\x84\xec\x35\x32\x1c\xf2\x95\x35\x72\x3f\x62\x4c\x08"
-  "\xf4\x0d\xbf\x8a\xa1\x77\xee\x82\x1e\xae\x7f\x5a\xdb\x11\x7e\x36"
-  "\x0a\xc6\x78\xa7\xc1\xb8\x48\x5a\xff\xd2\xc3\xfb\x74\x13\xe2\x72"
-  "\x09\x5c\xcc\x5a\x70\xbd\x5c\x17\x8b\xb0\x1d\x69\xe4\x7a\x66\x2c"
-  "\xf7\xcd\x49\x1a\x93\x68\x6c\xce\x06\x33\x26\xd9\xa1\xc0\xc8\x75"
-  "\x0b\x7f\x1b\xbf\x21\xce\x5e\x23\x7d\xa3\x76\x92\x5e\xf9\x74\xca"
-  "\xd8\x21\xcb\x9b\xda\x8c\xe5\x8a\x75\xfc\xbc\x5d\xa3\x5d\xe6\x65"
-  "\xa8\xf3\x64\xb8\xdd\x6a\x91\x96\x21\x61\xbb\x7c\x5c\x29\xce\x05"
-  "\xa2\x7d\x34\x61\x48\x63\xcf\x19\x28\xfc\x8c\xf6\x06\x44\xbb\x68"
-  "\x9c\x66\xeb\xa1\xf3\x11\xc4\xf9\x42\x85\x29\xa8\xc3\x49\xd2\xfe"
-  "\x60\x7a\xc6\xfe\xbf\x20\x49\xc8\xae\x70\x83\xc2\xf6\x1c\xd2\x7a"
-  "\x83\xc9\xc4\x23\xf2\x67\x36\xd3\x72\x6e\xaf\x62\x5f\x71\x61\xb9"
-  "\x5c\x8e\x9f\x25\xe0\x16\x7d\xe2\x79\x28\x3c\x42\x7d\x04\xd1\x67"
-  "\x87\xc2\x04\xaa\x9f\xda\x47\x7d\x2e\xd7\x9b\x38\xba\x93\xa0\xb0"
-  "\x3d\x80\x86\x93\x32\x2e\x09\x77\x9f\xfc\x4c\xe7\x85\xd9\x61\x87"
-  "\xa1\x7d\x06\xda\x94\x93\xb7\xe1\x9a\x76\x23\xda\x96\x93\xe0\x8a"
-  "\xa2\x64\x1e\x62\xba\x05\x9f\x31\xfe\xd9\xa6\x13\xef\x9c\x4e\xb4"
-  "\x0a\x5f\xb4\x23\x97\xce\xa2\x32\xeb\xe8\x3c\xc1\x64\xe1\x6f\xf8"
-  "\x79\x39\x3c\x6f\x8e\x64\xb3\x11\xb4\x07\x89\xaf\xbb\x71\xba\xb9"
-  "\x6f\x10\xe7\x2b\x60\x3e\xda\xc8\x90\xb8\xf7\x24\x42\xd0\x56\x64"
-  "\x19\xad\x03\x75\xa2\x9d\xbf\xe3\x2c\x32\x88\xf3\x4a\x26\xf7\x60"
-  "\x7e\x93\x2c\x3f\x3a\x03\x9a\xda\x8d\xe5\xb4\xed\xfc\x8c\xaf\xa2"
-  "\xe3\x32\xbd\x52\x9e\x9a\xeb\x03\xe7\x41\xd1\xa8\xfd\x0f\x4e\xe7"
-  "\xb0\xfd\x72\x3d\x1c\x16\xe1\x08\x9e\xee\xaa\x1b\xb2\xee\xd0\x8c"
-  "\xe2\x11\xe7\xa4\x68\xa9\x9e\xf6\x26\x9e\xa7\xf3\xf9\xaa\x42\xfe"
-  "\xce\x88\xaf\x8b\xc3\x76\x38\x76\xe3\x38\x9b\x64\xa0\x83\x30\x2c"
-  "\xa3\x21\x7c\x42\x17\x77\xac\x93\xcb\x84\xa9\x88\x8f\x3b\xb2\xe4"
-  "\xba\x65\x1c\x44\xff\xb8\x3e\x4f\xb4\x45\x43\x36\x42\xb0\x84\x97"
-  "\xeb\x04\xbf\xeb\x66\xc7\x39\xae\x83\xbc\x9d\x3b\x5a\x95\xb2\x16"
-  "\xb1\xd8\x8e\x93\x0a\x7d\x20\x7a\x46\xe5\x6f\x07\x53\xac\xe8\x4b"
-  "\x76\xb8\x14\x34\xa6\x0c\x59\x4d\xda\x51\x39\x54\x72\x19\xd1\xbd"
-  "\x15\x41\xef\x11\xe3\xb6\x82\x30\x5e\xc6\xe9\x24\x79\xe0\x58\x6c"
-  "\x31\xb4\xd7\xd3\xb9\x4d\xb6\x1e\xe4\x09\xd2\x68\xda\x4f\x7a\x85"
-  "\x78\x33\xfd\x75\xd3\x64\x50\xd0\xab\x22\xbf\x8e\x69\x65\x32\x0c"
-  "\xd2\xc7\xd7\xb2\xc8\xfc\xc4\xbc\xa6\x51\x39\x2e\xe4\xb0\xc7\x64"
-  "\x3a\x2f\xd3\x67\x48\xbc\x32\x7d\x2a\xd5\xd1\x2f\xd7\x81\xbf\xd1"
-  "\x3f\xec\x18\x13\xab\x3e\xb7\xd3\x98\x2d\x0e\x30\xa2\x4e\x7e\xf3"
-  "\x96\x17\xb3\xb3\xe6\xea\x36\x6f\xa5\xa3\x8e\x0a\x72\xb3\xb3\x0d"
-  "\xfc\x25\x91\x7f\x1c\x18\xcb\xeb\x43\x3e\x88\x58\x76\xd7\xf6\xd7"
-  "\xc4\xfa\x18\xb2\x0b\xb2\x77\xda\x57\x30\xb9\xad\xf8\x73\x3e\x36"
-  "\xb1\x59\x16\x82\xcd\xc5\x2c\x14\xbf\x73\xdf\x47\xed\x8f\x73\x8a"
-  "\x7e\x00\xe5\x49\x7d\xe4\x90\x75\x67\xad\x3f\xbf\x76\x36\xf9\xdb"
-  "\xf2\xce\x63\xc1\xfd\xc4\xce\xc7\xb8\x9f\x28\x17\x7a\x41\xfe\x89"
-  "\xf6\x16\x10\x5e\x2c\xd3\x17\x80\xd3\xe9\xf3\x51\xbb\x40\xf6\x51"
-  "\xa2\x9f\xd8\x15\x8f\x7d\x50\xad\xa8\x6b\xd7\x0c\x9f\xde\xec\x6a"
-  "\x10\x7a\xb3\x2b\xd1\x0e\x55\xb9\xf2\x58\x45\xf4\x1d\x3b\x79\xfc"
-  "\x48\x3e\x1d\xf3\xd3\x65\x7c\x75\xd3\xa9\xdf\xd8\x95\x39\x36\x7e"
-  "\xd8\x15\x45\xf1\x03\xad\x7b\x24\x5e\x20\xad\x5a\x61\x37\xbb\xaa"
-  "\x14\xfe\x27\x06\x9f\x1b\x82\xc9\xfa\x39\xea\x8e\xe7\xd1\xeb\xbc"
-  "\x79\x5b\xf2\x8c\x4b\xe9\x18\xaa\x6c\x93\x21\x7b\x8b\x31\x3b\x2b"
-  "\xf0\x3d\x5e\x82\x1c\x8b\xc9\xe7\xd2\x3b\x22\x88\x1f\xbb\xb0\xfd"
-  "\x25\x33\xe4\x36\x70\x3f\x85\xb1\xa3\xe4\xe3\xa2\xce\x40\xf1\xa7"
-  "\x8d\x7c\x1d\xe0\xee\x19\xb2\x9e\x10\xdc\x32\x13\xf3\x62\x1a\xb6"
-  "\x7f\xa7\x7c\xd7\x21\x8e\x49\x77\xa7\xc8\xcf\xbe\xf2\xbb\xf7\xf1"
-  "\xbe\xef\x00\x5f\x33\x88\x3c\x2d\xd6\x28\xe2\x2d\x7c\xde\x7d\x4a"
-  "\x7a\xe6\x67\x2d\xd1\xb9\x60\x03\xb0\xfb\x0d\xc1\xdf\xdd\x28\x7f"
-  "\x93\xe4\x2b\x8a\xc5\xba\x9b\x03\x00\x3f\x28\x75\x84\x37\xf2\xf7"
-  "\x09\xbb\x8f\xc9\xf5\x61\xf9\x53\xca\x3a\xa9\xdf\x0a\xc4\x67\x87"
-  "\xdd\x65\xf4\xbd\x97\x9f\xfd\xb6\x7b\x20\x08\xad\x06\x25\xdc\x90"
-  "\xb5\x38\x06\xeb\x3f\x2e\xb7\x79\xad\x89\xa7\xc5\x8f\xd3\xc6\x01"
-  "\xa9\x8d\x4d\xa4\x5b\x54\x3f\xe9\xbf\x44\x43\x99\x74\xee\x89\x9d"
-  "\xee\x0a\x23\xfa\xf9\x19\x68\x71\x64\xd7\xc5\x26\xec\xe7\x07\xe4"
-  "\x76\x50\x1b\x9b\x4b\x1d\x1a\xf9\xec\x29\x51\xbe\xf8\xd9\x00\xda"
-  "\x8e\x2a\xca\xf4\xb7\xce\xa6\x77\x05\xc5\xcb\x99\x75\xd7\x11\xd2"
-  "\x43\x3a\x93\xaa\x6e\x54\x0f\x8b\x7b\xc7\xea\x5d\x71\x2a\xe9\x9d"
-  "\x52\x97\x72\x16\x6e\x41\x4d\x2a\xc8\x36\x2e\xe1\xd1\x3d\x06\x76"
-  "\x74\xb4\xd9\x66\x63\xce\xb6\xbc\x82\xb9\xba\x82\xac\xcd\x92\xd1"
-  "\xfb\xd9\xbc\x95\x8f\xdd\x9d\xb2\x9d\x0d\x59\x4b\x52\x7d\xbe\xa5"
-  "\xc4\xa7\xff\xb4\x06\x8c\xdf\x29\x5a\xf2\x86\xb0\xa7\x92\x5c\x85"
-  "\xed\xf2\xf2\x64\xa3\x8d\x3c\x66\x2b\x51\xf6\xff\x34\x36\x8e\x38"
-  "\x0f\x25\x8b\x24\x9e\x3a\x05\x8f\x4b\x3e\xe1\xed\xe4\x67\x6e\x15"
-  "\x3b\xa9\x9d\xfc\x7c\x19\x1e\x9f\x95\x74\xc8\xed\xf5\x8d\x1b\x4a"
-  "\xec\x3c\x8e\x92\xe2\xb5\xf1\xc6\xe5\xbe\xf8\xb4\xb4\x58\x9a\x73"
-  "\xeb\x95\xc7\x78\x72\x7c\x8d\xb4\x64\x89\x58\xb5\x74\xd1\x9a\x62"
-  "\x36\xb2\xc9\x44\x67\xd1\x91\x0c\x4a\x37\xcb\xb1\x25\x5f\x1f\x58"
-  "\x61\x3b\x36\x64\x2d\xcd\x50\xfa\x09\x16\xf6\x62\xaf\x14\x23\x1e"
-  "\x13\x63\xd7\x6b\x7e\x76\x1a\xeb\x42\xda\xb4\xe3\xd0\x86\xed\x2a"
-  "\x45\xff\x57\xcd\xcf\xd7\xa4\xf8\x9a\x0d\xc6\x49\xf7\xae\x99\xf9"
-  "\x99\xec\x87\x10\xb7\x03\x65\x8b\x70\x18\xff\x95\x70\xdd\xf0\xa2"
-  "\x8e\xd2\xda\x20\xa7\x1c\x23\x41\xe9\x45\xea\x8b\xf0\x37\xea\xad"
-  "\x59\xda\x93\x68\x4e\x73\x14\x24\xc0\xe0\x60\x9c\x7a\xb0\x20\x43"
-  "\x43\xf3\x05\xc4\x0b\x5b\x83\x0b\x84\xfe\x98\xe3\xd0\x4f\x75\x28"
-  "\xf1\x49\xb8\x88\xa7\x1a\xa2\x83\x15\xc4\xa9\x49\xbf\xf9\x3d\x5e"
-  "\x83\x09\xe8\x47\x4b\xed\xac\x20\x41\x1d\xe2\x7c\xad\xf1\xda\x19"
-  "\x45\xf7\x9a\xd1\x1d\x75\xe4\xaf\xc4\x39\xfb\x96\x1f\xbe\x26\xe6"
-  "\x06\xa4\x7a\xcd\x3f\x62\xea\xef\xf3\x7e\xa5\x9a\xf7\x2b\x0c\xc4"
-  "\x1d\x0c\xe6\x0e\xbe\x4e\xd7\xf0\x7d\x7e\xbf\xa0\xb4\xff\xdb\xd1"
-  "\x6e\x70\xf3\xbb\xc9\xcc\x46\x8a\xd3\xdc\xf4\x9e\x8a\xef\x6f\x6e"
-  "\x33\xba\x61\xad\x8b\x74\xd2\xec\xa2\x73\xdb\x9d\x3c\x5e\xb0\x68"
-  "\xe4\xb3\xda\xe9\xae\x34\xba\x7f\x0f\xdb\x15\x46\x72\xd7\x99\xe9"
-  "\x8c\x7d\x0b\xdd\xaf\x06\x62\x3c\x1e\x07\xd5\x18\xd3\x0b\x19\x58"
-  "\x56\xd1\x7d\x86\x62\xac\x70\x1a\xe5\x12\xf6\x57\x84\xcd\x16\xef"
-  "\xaa\x65\x3f\x61\xf9\x98\xd6\xbe\xdb\x25\x1c\x58\x17\xf6\xff\xa5"
-  "\xe5\xa2\x2e\xc4\x37\x24\xcb\xd3\xb2\x6a\xec\xfc\x86\x0f\x1f\x96"
-  "\x5f\x29\xc5\x05\x20\xe6\xae\x7e\x45\xb8\x8e\xcb\x73\x57\xbe\xd8"
-  "\xc7\xd2\x23\xcf\x5d\x89\x33\xa3\xcd\x75\x54\x7f\xa8\x39\x22\x66"
-  "\x7e\x9a\xf4\x5e\x4b\x31\x5c\xc8\x78\x02\xfb\x77\xa2\x5d\x8e\x0b"
-  "\x85\x7c\xf6\xe4\x50\x7c\xd8\x5e\x2c\xc6\xb5\x83\xe2\x2e\x36\x8c"
-  "\x01\xf6\x18\x45\x5f\xb6\x27\x43\xee\xcb\xb0\x6c\xb3\xe4\x2b\xa4"
-  "\x7e\x6e\xcf\xe8\xf8\x37\xf8\xba\xff\x3d\x75\x32\x8f\x64\x9e\x0b"
-  "\x1e\xed\x39\x37\x18\xf9\xd1\x3a\x1f\x6f\xf7\xf0\x77\x17\xbe\x7c"
-  "\xeb\xad\x0a\xde\xd3\x73\xbc\xf0\x9b\x7b\xb0\xff\x37\xaf\x13\x7d"
-  "\x8a\x48\x63\x91\x27\xda\xe8\xee\x44\xc1\x83\x1c\x3e\x37\xe3\x30"
-  "\x27\x20\x6d\xd6\x18\xbb\x4a\x75\x58\xf8\x32\x2b\xf6\x7f\x7b\xa2"
-  "\x44\xb9\x3d\x2d\x44\x8b\x92\xde\x27\xf2\x5e\xcc\xdb\xb6\x23\x8f"
-  "\x26\xd4\x0a\x0b\x74\x5b\xb6\x65\x65\x47\x06\x99\x0f\x89\xa3\xfb"
-  "\x52\x9d\x75\xa3\xe7\x5a\xed\x4b\xa0\x75\xfa\xe2\xfe\x80\x7d\x73"
-  "\x74\xb7\x91\x7e\x59\xf7\xd3\x5c\x01\xbf\xc3\x81\xce\x46\x15\xf3"
-  "\x06\xfd\x54\x5e\xf0\x7a\xdf\x75\x83\x3b\xf4\x52\x8c\x55\x76\x82"
-  "\xf8\x28\x8d\x39\xd8\x19\xd8\x1b\x21\xf7\x43\x44\x1f\x8f\xcd\x47"
-  "\x12\xb8\x5f\xf4\x8e\xe8\x35\x9c\x5f\x23\x09\xd8\xdf\x58\xfb\xed"
-  "\x18\x8b\x4b\xed\x72\xca\xfc\xa0\xf6\x63\xac\xab\x1d\x62\x39\xa8"
-  "\xa3\xfb\x12\x24\x5c\xe4\x3f\x11\xb7\xf5\xb8\xbc\x4e\x9c\xce\x0b"
-  "\x6d\x2d\xa2\xf3\x7f\xf7\x5e\xf4\x56\x90\xbf\xd9\xbb\x58\xf6\x4b"
-  "\xd4\x17\x79\x11\xcf\x3b\x5f\x38\xc2\xd1\x6e\xe8\xdc\xa1\xeb\x4f"
-  "\x43\x59\x99\xb8\x0f\x60\x6f\x96\xff\x7d\x00\x65\x29\xf8\x29\x93"
-  "\x3e\x87\x15\xbf\xc7\xfb\xc8\x65\x0c\xbe\xb4\xbd\xad\x01\x30\x87"
-  "\x91\xa6\xce\xd1\x78\x45\x9c\x59\x2a\x9d\x5b\x4c\x77\x58\x94\x45"
-  "\xd0\xb9\xa0\x3e\xdd\xd8\x3b\x4f\x8a\x41\xfa\x89\x77\xd4\xdf\x22"
-  "\x0c\x5f\xcb\x8d\x3c\x69\xa3\x39\x5a\x6a\x13\x1b\xca\x41\x9d\x28"
-  "\x8b\xf7\xe9\x81\xe0\x11\xa6\x2d\xf6\xc5\x29\x65\x51\x54\x46\xc9"
-  "\x07\xac\xe3\x01\x31\x36\x2d\xcb\x94\xfb\x6c\x3a\x13\x55\xdc\x05"
-  "\xb1\xb7\xb3\xb9\xb4\x1f\xc7\xfc\x65\xc5\x3e\x1c\x7b\x3b\xa5\xb9"
-  "\x08\x0d\x53\x5b\x13\x1b\xf9\x98\xad\xac\xc1\x37\x27\xb0\xb7\x93"
-  "\xfc\x2e\xc7\x11\x79\xa2\xc7\xe6\xe4\xf7\x93\xaa\xe4\xbb\x87\x11"
-  "\xb6\x43\x8e\x51\x64\x5c\xed\x62\xce\x89\x9f\x63\x89\x36\x58\x8b"
-  "\x30\x03\xa3\xf3\xb1\x74\xff\x90\x3c\x06\x34\xa1\x1d\xf3\xd8\x7b"
-  "\x5f\x94\x6f\xac\x67\x3d\xca\xfd\x8d\x75\x14\x0f\x8e\x8f\xf6\x41"
-  "\xe0\xb8\x0d\xe3\x07\x5d\x4e\x5e\x0e\x86\x0f\xcf\x1b\xb6\x2d\xc5"
-  "\xa1\xc3\xf3\x86\x9c\xa5\xb4\xa4\x6c\x55\xea\x0a\xfe\x8d\xc6\xb1"
-  "\x34\xc8\xfc\xf1\xe8\x1d\xa4\x34\x67\x84\xe3\x5c\x9a\x3b\x1d\x12"
-  "\x77\x14\x4e\x96\xbe\xb5\xd2\xf7\x24\xec\xf7\x7a\xd1\x06\xde\xa6"
-  "\x3b\x68\x90\x86\x56\xe9\x5e\x48\xb9\xcf\x46\x5f\xbe\xef\x87\xf2"
-  "\x7b\x32\xbe\xc6\x9e\xce\x2a\xa4\x3b\x46\xf7\xbe\xf8\x09\xb6\x69"
-  "\x74\xfe\x43\xcc\x2f\x8a\xf7\x5e\x98\xee\x92\xd3\xe5\xf9\xd8\x21"
-  "\xeb\xcb\x51\xf2\xdc\xab\x80\x7d\x79\x86\xaf\xac\xdf\xdc\x76\xac"
-  "\xfc\x7e\x0d\x61\x52\x64\x9e\xc9\x78\xcc\x3a\x76\x5e\x8a\x93\xc2"
-  "\x78\x5c\x6d\xdd\x97\xc4\xcf\x07\xa5\x58\x9c\xcf\x33\xbf\x6c\x94"
-  "\xeb\xa1\x31\x02\xd1\x2d\xbd\xbb\xe1\x76\x4f\xe7\x80\x8a\x73\x44"
-  "\x5f\x1e\x95\xff\x44\xee\x05\x1b\x29\x62\xed\xee\x2f\x58\x4b\xf5"
-  "\x9f\xd0\x66\xb7\x02\xb8\x8b\xd8\xb1\x91\x2f\x58\x33\xf1\xba\xfa"
-  "\x39\x80\xfd\xff\x05\xe0\x09\x5b\xff\xe9\x30\xf2\x7d\xf5\x45\xef"
-  "\x79\xba\x0b\xaf\x11\xe1\x56\x3b\x2f\xb0\x43\x58\x66\xb5\x81\x9d"
-  "\x3f\x84\x70\xab\xce\x9d\x67\x07\x11\x76\x95\x1e\xdb\x5d\xc4\xdc"
-  "\x9e\xb0\x17\x3f\xd5\x3d\x49\x7e\xe8\x3b\x89\x8e\x8a\xce\xb9\xcc"
-  "\xaa\xae\x61\x7b\xef\xb8\x7d\xc8\xfa\x9d\xe4\xd1\x3b\xad\x10\x2f"
-  "\xf1\x68\x8d\x89\x7e\xbf\xf8\x29\xb6\xe9\xd3\x4d\xd8\x87\xa2\x0c"
-  "\x3e\x45\x38\x1c\xff\xe7\x71\x7f\xe3\x08\xbb\x7d\x3a\x7e\x12\x82"
-  "\xf9\x7d\xa4\xb5\xdd\x53\xc4\x5a\x6a\x36\x22\xfd\x67\x91\xfe\x2f"
-  "\xd8\x31\x6c\x43\x73\xf5\x19\x00\xa2\xdf\x43\x38\x3d\x10\xb6\x69"
-  "\xa7\x6a\x5a\x23\xe6\x6f\x32\xc5\x40\x23\xc2\x6e\x74\xc2\xb4\x43"
-  "\x08\xb3\x71\xfb\x34\xe0\xf4\x0f\x20\xdd\x11\x9d\x73\x3d\x58\x37"
-  "\xd1\x8f\xf5\xf7\xc9\x74\xca\xf5\x13\xbd\xb2\x0e\x6e\xa2\xf9\xae"
-  "\xc8\x8f\xea\x88\x6e\x31\x87\x5f\x3e\xd3\x51\xa0\x07\x47\xd8\x1d"
-  "\xb7\xdb\xa1\x7c\x31\xd9\x10\xb5\xc7\x81\x3a\x25\xed\x7b\xfb\x54"
-  "\xe6\x81\x18\x4f\x96\xa7\xca\xed\x53\xb6\x2b\x7d\x5b\x3e\x9f\x47"
-  "\xdd\xbc\xc5\x98\x53\xb4\x19\x47\x67\x91\x60\xa0\x24\x3e\x7e\xcb"
-  "\xce\xd2\x6d\xcb\xd3\x6d\xdd\x9c\x93\xbb\xad\x28\x3b\x7f\x2e\x1f"
-  "\x72\x17\x64\xe7\x65\xd1\xf4\x6a\xfe\xe6\x7c\x43\x64\x40\xcc\x5d"
-  "\xde\x39\x97\xd6\x23\x92\x2f\x3b\x03\xaf\xcc\x94\xe6\x16\x5d\xcc"
-  "\x9a\xc2\xc7\x6e\xc2\x0e\xca\x3f\xd5\xed\x4a\xa1\xfc\x69\xa2\xaf"
-  "\x79\x65\x06\x6f\xd7\x60\x9a\x5c\x8e\xaf\xdd\xe5\x31\x2a\xa5\x8f"
-  "\xa4\x81\x6f\x0d\xf9\x2b\x33\x99\x1a\xdb\x84\x6d\x96\xe2\x54\xbb"
-  "\xb4\x97\xef\x7f\x9d\x86\x4a\x0f\xb6\x93\xde\x15\xf4\xf0\x38\x90"
-  "\xef\x39\xaa\xa4\x39\x18\x3b\xb3\x4e\x8a\x22\x3e\x54\x8b\x71\xa4"
-  "\x3a\x5a\x65\x51\x51\x2c\xd4\xa8\xf6\x26\xd2\x3b\xc1\x46\xab\x37"
-  "\xd1\xb7\x86\xa7\x3c\x9d\x62\x5a\x3e\xb7\xce\xed\xa0\xa2\x58\xd6"
-  "\x6f\x35\xed\x29\xd9\x7b\xe3\x12\xe1\x9b\x2b\xf6\x10\x3c\xca\x69"
-  "\x89\xa0\x9f\xdf\xdb\x8a\xfd\x51\x65\x85\x77\x6a\x74\xad\xa7\x20"
-  "\x4e\xba\xbb\xf8\xa3\xa3\xde\xca\x8f\x1a\x3c\xd8\x6f\x7b\x31\x16"
-  "\x65\xd5\x31\xd7\x7a\x2a\x3f\x3a\xe0\xdd\x91\xa0\x26\xff\x6d\x36"
-  "\x21\x7f\xb6\xe9\x23\xd9\x05\xfd\x35\x1e\xba\x6f\xaf\xf2\xa3\x43"
-  "\x8c\x61\xd9\xc8\x8f\x7e\x42\x7d\x24\x3e\x37\x49\xcf\xc7\xe8\xd9"
-  "\x8b\xb1\x18\xa6\x7d\x80\xcf\x2d\xfc\x6e\x3f\x19\xde\x1f\xf6\xdf"
-  "\xe9\x39\x5a\xc5\xd7\x08\x26\x62\xec\x9b\x4c\x6d\x95\xdb\xc8\xc7"
-  "\x00\x34\x0f\x31\xda\x96\xca\x32\x39\x9d\x62\x53\x11\x27\xc2\x16"
-  "\xe4\x69\xbd\xf0\x59\xa3\x70\xcf\xca\x6d\xe6\xbc\xac\xfc\x08\x63"
-  "\x20\x94\x1f\xdd\xc7\xbc\xf7\xff\x63\xef\x6d\xc0\xa3\xaa\xae\xbd"
-  "\xf1\x3d\x93\x01\x26\x71\x92\x19\x69\xc4\x11\x83\x8c\x35\xb6\xa3"
-  "\x8d\x10\x95\xf6\x52\x5f\x94\x54\xb0\xa5\x8a\x26\xb5\x78\x6f\x7a"
-  "\xa5\x26\x54\xf0\x06\x8b\x30\x42\x08\x01\x43\x3e\x06\x9a\x1b\x62"
-  "\xbe\xd4\x60\x03\x09\x21\x6d\xd1\x8b\x2d\x6a\x54\xac\xb1\x52\x1d"
-  "\x05\x63\x94\x24\x13\x31\xb6\xa9\xa5\xed\x40\x43\x0c\x18\x60\x24"
-  "\x43\x66\x48\x66\xce\xfe\xaf\xdf\xde\xe7\x64\x26\x98\x50\x63\x7b"
-  "\x3f\xde\xff\x7b\xf3\x3c\x93\x73\xce\x3e\xfb\xec\x8f\xb5\xd7\x5e"
-  "\x7b\xad\xb5\xd7\x5e\xeb\xf2\x6b\xb9\xbe\xe4\x7e\xac\x0d\xa9\x21"
-  "\xb1\x57\xc5\xe4\xde\x46\xe9\x3e\x0d\x7e\xb0\x85\xc7\xfa\x40\xe3"
-  "\x64\xcf\xf0\xb2\x18\x39\x3f\x4b\x0f\x47\xc8\x20\x7d\x5c\xe0\x73"
-  "\xa9\x38\x67\xc2\xf5\xc6\x4d\xf2\x79\xcb\x1c\xb9\x9e\x3d\x6a\xd4"
-  "\xf2\x52\x9a\xb0\x01\xc2\x9e\x15\xe1\x7f\x5f\xfd\x79\xe7\x33\xc7"
-  "\xa2\x3f\xd4\x5e\xd5\xdf\xf9\xa3\x8b\x34\xde\x80\xee\x33\x47\x9e"
-  "\xe1\x7c\x74\xc1\xf9\x7b\x4c\x3f\x5a\xb5\x2a\x3b\x63\xf5\x32\x5c"
-  "\xec\x57\xaf\xbd\xe6\xfc\xb5\xc2\x24\xe3\xc8\x3c\x9a\x8b\x7e\x83"
-  "\x7e\xca\xb3\x10\x8f\x36\x45\xc8\x7b\xd0\x39\xcd\x05\xdd\xc7\x5e"
-  "\x31\xbd\xeb\x7c\x33\x6f\xa3\xe0\x37\x8e\x18\x99\x7e\x2c\x1b\x06"
-  "\xe1\x57\x3b\x3a\x50\x25\xe6\x77\xb9\x85\xe8\x7f\x99\x49\xb3\x39"
-  "\x1a\xdd\xf7\x43\xb3\x29\x54\xfa\x81\xcd\x36\x55\xc4\xc8\xd3\xbf"
-  "\xb4\xa1\x4b\x0f\xfe\x22\x9f\xee\x61\x93\x21\xf4\x58\x6a\xec\xb5"
-  "\xd7\xcf\x74\x11\x1d\x29\xcb\xe4\x5b\x9a\xa9\xcc\xb2\xf4\x31\xdb"
-  "\x10\x71\x6e\x56\xee\xc1\x95\x8d\x69\x73\xc1\x4b\xdc\xbd\x12\x57"
-  "\xca\xda\xc4\x5e\xd0\x54\xf6\xef\x47\x59\xd9\xbb\x06\x2b\xc9\x29"
-  "\x53\xd9\x7f\xd0\x7d\x9b\x58\xf7\xad\x23\xd7\x68\x36\xad\xaf\xc1"
-  "\x10\xc5\x69\x4e\x70\x1d\x97\x7f\xc4\x64\xc8\xbf\x28\xfa\xe9\xb9"
-  "\x4e\x58\x9f\x47\x11\xa4\x26\x4d\x34\x30\x73\x9c\xc9\x38\xfd\x8a"
-  "\x04\xeb\xdc\x5b\xe6\xcc\x2e\xc8\xcf\xcb\xe5\x4a\x30\x60\xe6\x91"
-  "\x71\x02\x03\xc9\xf7\x5c\x53\x28\x69\xe1\x96\x40\xf2\x68\x6d\x2d"
-  "\x77\x72\xd8\x70\x32\x9a\xaf\x8e\x82\xb5\x4c\xff\xfc\xa0\x47\x0f"
-  "\x5e\x05\xf4\x15\xf1\x2e\x8f\xb2\xf2\x1f\xbc\x41\x69\xd4\xff\x5c"
-  "\x5e\x66\x76\xc8\xb3\x05\xe5\xdb\x94\x0a\xb3\x23\x5c\xbe\x81\xa1"
-  "\x7c\xe2\x87\xf5\xbb\xf2\x7b\xf5\x6e\xc3\x2d\xcc\x6d\xf3\xb1\x37"
-  "\xe8\x7e\x8c\xf1\x74\x40\xf7\x82\x32\x88\xee\x94\x14\x9c\x23\x7a"
-  "\x94\x2b\xf4\xa0\xfa\x53\xac\xfc\xfd\xc6\x31\xbe\x13\x7b\x19\x31"
-  "\x07\xcf\xf8\x9d\x15\x34\x56\xf3\xbb\xd5\xf5\x9e\xf8\x91\x8a\x04"
-  "\x6d\x4e\xd0\xfb\x4f\xa5\x3e\xb6\x22\x59\xcb\x33\xba\xbc\x04\x1b"
-  "\x46\xee\xc2\xb8\xf2\x81\xde\x5e\xf8\x50\x1b\x43\xe6\x4d\xa1\xf5"
-  "\xe7\x3a\xf0\x30\x6d\x44\x21\xe2\x8a\x2c\xd8\x2b\x25\xba\x92\xfc"
-  "\x90\xb9\x28\x79\x79\x9c\xef\x12\x66\xce\xfd\xa1\xce\x1c\xfc\xae"
-  "\x6e\xc7\x93\xbc\x03\x3c\x1e\xf6\x1a\x40\x5b\x62\x8b\x92\x97\x70"
-  "\xfd\x9c\x1b\x11\xdb\x2a\xb6\xef\x5b\x3a\xc5\x39\xeb\x46\xf8\x45"
-  "\xab\x9a\xc2\xbb\x28\xdf\x61\xca\x07\x5d\x53\x37\xe5\x6d\xed\x61"
-  "\x15\x9f\xd2\xb5\x25\xb6\x88\xef\x8c\xed\xe3\xca\x8c\x42\x16\xa5"
-  "\x96\xd7\x2a\x62\xcb\x0f\x09\x59\x77\x42\x58\xd6\xad\x8c\x0f\x39"
-  "\xd9\xc4\xd4\x09\xfc\x0d\x2a\xa3\x85\x0f\x28\x2d\x3b\x14\xe1\x1f"
-  "\x0a\xfb\x41\x9d\x44\x47\x3a\x67\x56\x93\x6c\x83\x38\x91\xeb\x69"
-  "\x2c\x03\x01\xf0\x35\x2e\xaa\xe3\x00\xd1\x89\x7d\x1b\x1f\x66\xfa"
-  "\x10\x7d\x43\x6b\x44\xd4\x29\x56\xf9\x50\x7b\x6f\x17\x7c\x6a\x7f"
-  "\x2d\xcc\xab\x55\x09\xbd\x5c\xf9\x93\xdc\x05\x3b\xde\xe7\x4f\x79"
-  "\x11\x67\xbd\x05\x73\x06\x36\x8d\x48\xa7\xe7\x7d\x33\xaa\x99\xdd"
-  "\xdd\xd7\xcb\xda\x89\x4b\xe3\x05\x56\x3d\xa5\xef\x4b\xf2\x12\x3f"
-  "\x41\x65\xc3\x7e\x9b\xe6\x7c\x6b\x6c\x1f\x9b\x40\x7d\xd9\x27\x78"
-  "\xac\x75\xf6\x44\xfa\xce\x75\x1d\xb5\x8d\xd6\xfc\x84\xe7\x07\xbb"
-  "\xf4\xe2\xcc\xef\x14\xde\x11\xeb\x63\x89\x82\x36\x08\x9f\x65\xf6"
-  "\xaf\xd0\xb7\x07\x88\x8f\xee\x44\xb9\xd0\x2d\xd0\x73\x07\xca\x38"
-  "\xc5\xaa\xbe\xc7\x57\xd9\x0d\xa8\x83\x78\x02\x97\xed\x01\xec\xd9"
-  "\x54\x25\xb5\xf7\x06\x18\xd2\x2b\xa9\x7d\x84\xf3\x2e\xb4\x93\xfa"
-  "\xda\xe4\x77\x56\xcd\xd1\xce\x6a\x63\x7d\xa4\xe7\x85\x1a\xbe\x10"
-  "\x3d\x6e\x92\xe7\x49\x2b\xbf\x0b\x98\x50\xfb\x3b\x95\x01\xa5\x57"
-  "\xa1\xb6\xa1\x1c\xbe\xc6\x6a\xa0\xf6\xeb\x52\x83\x7e\x4e\x7d\xe8"
-  "\x4c\xcd\xf5\x73\x94\x6b\x5b\x29\xe0\x76\x35\x5f\x83\x98\x44\x55"
-  "\x7b\xc1\x1b\x03\xe6\x72\x3d\xaf\x7c\x28\xb6\xc8\x52\x1c\xdb\x77"
-  "\x09\xd1\xe5\xca\xcd\x3b\x06\xb0\x86\x56\xb9\xb4\x3a\xc7\x98\x13"
-  "\x01\x37\xd1\x03\x65\x80\xf7\x82\x17\x92\xf6\x17\x55\xbe\x8c\xdc"
-  "\xa8\x14\xea\xa3\x9e\xda\x82\x71\x9c\x42\xeb\xca\x5c\xd8\xd7\x50"
-  "\x1b\x88\x0e\x3e\x16\x7f\xa1\x18\x9d\xd4\x57\x2b\xe5\x21\xf9\xa7"
-  "\x4a\xfa\xe9\xcf\xe1\x75\x52\xf7\xf0\xd8\xf0\xf9\x77\x3e\xc0\xf3"
-  "\x2a\xf3\x45\xbd\x85\x9b\x73\x44\x1d\x88\xdb\xd8\x9b\x6d\xe3\x47"
-  "\x0e\xd8\xbc\x63\xcd\x09\xea\xcf\x63\x55\xda\x99\x77\xb4\x9d\xe6"
-  "\x73\xa1\xa4\x0d\x8f\x47\xc7\x15\xcd\xe5\x71\xbe\x1b\x6f\xc4\xde"
-  "\xe7\x4e\xbd\xb0\xf5\x91\xeb\xaa\xa4\xff\xd3\x69\x7c\x4f\x63\x9c"
-  "\x89\xb7\xeb\x82\xcd\x84\xdb\xc7\x85\xac\x20\x62\x59\x13\x15\x83"
-  "\xbd\x1c\xf4\x70\x54\x87\x6f\x58\x76\x1d\x51\xc7\x63\x7b\xce\xa7"
-  "\xbd\x69\xf3\xbe\xbb\xcc\xb6\x02\x36\x30\xc9\x37\xe4\xda\xec\x57"
-  "\x2f\x9d\x29\x8c\x63\x6c\xdf\x9e\x77\x93\x2d\x8d\x04\x9b\xac\xa4"
-  "\xbb\xe4\x65\x5e\xda\x42\x5c\xcf\xd3\x95\xda\xfc\xce\xc7\xcf\x5b"
-  "\xff\x7e\x1a\x94\x6b\xe4\xe3\xb9\x1e\xdd\xa5\x52\x6e\x28\x69\x9e"
-  "\x4f\x70\xea\xf3\x46\x07\x92\x55\x3b\xd8\xf9\xde\x68\xbf\xd7\x1b"
-  "\xdd\x6a\x40\x2c\x55\x73\x11\x0f\x98\x83\x93\x38\x70\x14\x31\x54"
-  "\x09\x87\x7a\x2b\xcf\x08\x99\x8c\xdd\x76\x4d\x01\x4f\x0d\x71\xf7"
-  "\xce\x33\x18\xb7\xc7\x5b\xb5\x31\x11\xfc\x2d\x95\x4b\xfd\x1e\x42"
-  "\x99\x34\xd6\x46\x94\x0b\x1e\x97\xf2\x51\xff\xcb\x9b\xe4\xfa\xfc"
-  "\x04\xe1\xd2\x63\xb9\x2a\x0e\xa7\xd1\xb3\xc5\xc3\x6e\x10\x76\x45"
-  "\x8a\xd3\x0a\xdf\x01\x06\x65\xd3\xb5\x77\xf3\x2d\x7e\xaf\x56\x26"
-  "\x95\x65\xd2\xda\x89\xf2\xd8\xe7\x3c\xfb\xa5\x94\xbe\x93\x02\xbe"
-  "\x09\x67\x2c\xcc\xb9\x3a\xc4\x11\x48\x1f\xe6\x0d\xe9\x1d\xd1\x40"
-  "\xf0\x8b\xe9\x71\x3e\x5d\x21\xf2\x84\x79\x2a\xc5\x53\xa9\x57\x02"
-  "\xb4\xc6\x5a\x64\x5c\xd3\x3e\x55\x67\xfc\xc4\xbe\xd1\xc7\xf1\x09"
-  "\x61\xe3\x78\xc6\x69\xa0\xbe\x3d\x9e\xf6\xe5\x78\x39\x0f\x14\xa7"
-  "\x8e\xc9\xf3\x76\x4f\xbc\x20\xf6\x31\xa5\xcd\xc8\x74\x82\xaf\x17"
-  "\xfa\x41\x33\xd1\x07\xd8\xd2\x29\xc0\x1f\x76\x82\xb9\xf3\xfc\x85"
-  "\x88\x27\xaa\xc9\x94\x24\x1f\x29\xed\x8e\x10\xbd\xff\xb1\xf0\x2d"
-  "\x44\xbc\x5a\x26\xcd\x27\xdd\x09\xf6\x44\x21\xda\x2f\xc6\xd1\xc9"
-  "\x4c\x0a\xc1\x4a\xec\xd9\x03\x3e\x31\x2d\x2e\xd8\x6e\xa3\xaf\xe6"
-  "\x20\xf5\x39\xb2\x5f\x7a\xc5\x53\xe1\xa4\x7e\xe9\xa9\x5f\xb9\x27"
-  "\x99\x98\xab\xb9\xc7\xc0\xc3\x4c\x09\xfb\xc1\xae\x6e\x88\xec\xa3"
-  "\x02\xff\xf5\xa2\x0f\xd5\x6f\x8e\xd6\x47\xae\x47\x1f\x01\x83\x6a"
-  "\xcd\x27\xbb\x68\x27\xf8\x86\x3e\x56\xbd\x28\xae\x08\xb6\xec\xcd"
-  "\xf3\x69\x2d\x9e\x87\x31\xac\x77\xf2\x2a\xb4\x73\xb4\xf1\x42\x79"
-  "\xb2\xac\xad\x99\xe6\xa2\xc2\x4c\xbf\x73\x6b\xd2\xe8\xf0\xde\x7a"
-  "\xe7\x85\xe1\xbd\xf5\x4a\x7c\x8f\x76\xc0\xb6\xdf\x0c\x27\x0d\x84"
-  "\xdf\xb4\x4e\x96\x8c\x56\x6f\x5c\x51\x03\xda\x35\xea\x3b\xc2\xfd"
-  "\xbe\xca\xd5\x23\xe7\x84\x52\x8f\x38\xdf\x27\x61\xff\xce\xa4\xbc"
-  "\xb7\xb5\x33\x1c\x6b\xb9\x79\x85\x59\x67\x8b\x02\x1f\x20\xe8\x1b"
-  "\xf5\x77\xb4\x72\xcd\xba\x2a\xf8\x79\x99\x47\x74\x65\xd4\xf7\x34"
-  "\x0f\x6c\xc4\x53\x7f\x99\xca\x9b\x15\x57\xc4\x38\xc9\x86\x31\x71"
-  "\xbe\xa0\x88\x23\x4c\x6d\xcd\xa5\x79\x0d\xf9\x57\x2f\xe5\xc1\x27"
-  "\x89\xff\xfd\xb9\xe0\x4d\xbd\xd1\xcd\xb3\xe4\xde\xc7\x93\x59\x1e"
-  "\xf6\xcb\x61\x5d\x2d\x3d\xe7\x7a\xd8\xb9\x39\x72\xae\x5e\xbe\x9d"
-  "\x97\x1e\xec\x50\x9c\x66\x6e\xdb\x60\x26\x39\xe7\xa7\x17\x93\xfc"
-  "\xa1\xe7\x31\x07\x3b\xc2\xb8\x23\x6d\xff\x35\xdc\xa1\xef\x9b\x46"
-  "\xc7\x8b\x27\xff\x70\x61\xbc\x78\xf2\x59\x55\xce\xc8\x94\xf6\x05"
-  "\x3f\x65\xda\xfa\x41\x72\xc6\x76\x5b\x3e\xea\x7f\xb2\x5a\xd6\x4d"
-  "\x30\x09\xa6\x80\xce\x2c\x24\xb8\x15\x52\xde\x24\x8d\x36\x00\x87"
-  "\xcc\x21\xac\x5f\x4c\xe0\x39\xbd\x5b\x40\x74\x44\xdd\x3f\x6f\xdd"
-  "\x43\xb4\x2f\x41\x71\x3e\x1e\xef\x2d\xc8\xaa\x85\x7d\x9d\x2f\xba"
-  "\xb9\x91\xf2\xac\xf0\xb0\xdf\x89\x18\xc4\xdc\xd8\xbc\x9b\xca\xd8"
-  "\x23\xf6\xab\xe4\x99\x15\x13\xe6\x39\xe2\x9d\x60\xae\x53\x5a\x3c"
-  "\xb5\x1b\xb1\x4f\x68\xad\xf9\xe9\x2e\x8d\xd7\x57\x9c\x29\x80\xb7"
-  "\x38\x23\x4f\xf2\x4e\x42\x3f\xc1\x6e\xab\x5e\xd9\x3d\x30\xd3\xca"
-  "\xd0\xe7\x81\x4d\x53\x77\xff\xfb\x0c\x66\x68\xb6\xfe\x88\x39\x6e"
-  "\x60\xf1\x45\xdf\x30\xb0\x4f\x66\x33\x3d\xe0\xe0\x61\x3f\xdd\x2b"
-  "\x61\xf7\x53\x9f\x36\x3e\x1e\xf6\xe4\x62\x8c\x07\xe4\xfb\xd4\x20"
-  "\xef\x97\xfa\x8a\x1a\x5a\xff\x1e\x55\x63\x25\x3f\xbe\x62\x94\x35"
-  "\xe1\x36\xdb\xf2\x35\xb6\xa5\xab\xd6\xad\xbc\xf2\xca\x11\x3a\x5f"
-  "\x83\xd0\xdf\x39\x6b\xec\x72\x0f\xa5\x66\x71\x84\x7c\x4b\x6b\x5b"
-  "\x0d\xf5\xff\xf1\x05\xe7\xaf\xab\x0b\x33\xd4\x23\x9a\x19\xc9\x2c"
-  "\x7c\x7f\x3d\x5b\x78\x7d\xc4\xe3\x8d\x6c\xe1\x0d\x37\x66\xdc\xbd"
-  "\x6c\xc9\xd2\xf5\x11\xa9\x5f\x8f\x94\x95\x2a\xb7\x53\xdd\x51\x53"
-  "\x6f\x25\xfa\xa1\xbb\xeb\x11\xac\x35\xdb\xbe\x97\x1f\xe4\x1f\x13"
-  "\xee\xce\x86\x5f\x84\xb6\xec\x20\x6b\x23\xfa\xc6\x2f\x07\x5d\x9f"
-  "\x24\x7d\x83\x85\x18\x64\x18\x33\xf5\xdd\x4b\xeb\xf3\x59\x69\x5f"
-  "\xb6\x6d\x6d\x7b\x0d\xf1\x3c\x25\xad\x26\x29\x6f\x6c\x43\x8c\xe5"
-  "\x8b\xe9\xfa\x03\xb9\x47\xb6\xed\x87\xc4\xa7\xa4\x88\x73\xa0\x39"
-  "\x38\x07\xba\xed\x36\xc0\x68\x86\xaf\x90\x49\x7f\x24\x35\xbd\xf0"
-  "\x13\xea\x61\xdb\xc4\x19\x1f\xe4\xa5\x6f\xae\xb7\x3d\xc8\x92\x71"
-  "\xc5\x7e\x33\xbd\x4b\xe6\x5b\x5a\x4d\xbc\x36\x1d\xfb\x06\x89\x94"
-  "\xbe\x35\x4a\x77\x84\x45\x59\x27\x7d\xc7\xef\xdc\x06\xd9\xb7\x57"
-  "\xdd\x3b\x18\xfd\xcc\x81\xba\x06\xc6\x11\xed\x8e\xf3\x99\x79\x06"
-  "\xce\x54\xeb\xc0\xe7\xf5\xd1\x3c\x4e\x13\xb6\xcf\x58\x13\x25\x3d"
-  "\xd8\x36\xac\xff\xc1\x59\x13\x7a\xf6\x69\x38\xef\x77\x6e\x67\x1a"
-  "\x4e\x8e\xb0\x95\x5d\x99\xbd\x6c\xf5\xb2\xa5\xb6\xab\xd7\xc4\xb0"
-  "\x88\x88\x51\x59\xcb\x56\xda\x56\x2f\x7b\x78\xed\xb2\x35\x22\xda"
-  "\x13\xde\x9e\xa7\xa7\x89\x79\x2f\x65\x38\x26\x9f\xb0\xd7\xdd\xbe"
-  "\x0c\x7c\x3b\x2f\x7d\xcf\x25\xe2\x61\x60\xcd\x31\x99\x4b\x94\x8a"
-  "\xd8\x14\x29\xf3\x21\x96\x72\x6d\x40\xee\x5b\x1c\x0c\x4a\x7d\x7f"
-  "\x6d\x39\x9e\x29\xdd\x12\x8e\x31\xbd\xfd\x4d\xe8\x57\x54\x18\x11"
-  "\x0f\xb3\xbd\x49\x83\x91\x87\xd5\xa5\xa8\xba\xec\x3e\x41\x2b\x68"
-  "\x8d\x35\xcb\x38\x3d\xc3\xf4\x62\xa6\x82\x75\x6a\x3b\x6c\x48\xa3"
-  "\x84\xbc\x1c\xdd\x0a\x3d\x84\x1e\x65\xf6\xd0\xf7\x7c\xcb\xc1\x20"
-  "\xd1\x49\xa2\x35\xbc\x44\x2b\x8f\xea\xdc\x8d\xfa\x40\x3f\x68\x9d"
-  "\xbb\xf4\x04\xab\x15\x65\x29\x25\xad\x0c\xf4\x03\xe7\x0e\x94\x2d"
-  "\xad\xaa\x1f\xa1\xba\x14\xc8\xe9\x22\x5e\x0d\x95\x05\xf9\x98\xe8"
-  "\x80\xe5\xf9\x0d\x01\x3d\xd2\x64\x4c\xa3\xed\xd0\x6b\x12\xbd\x38"
-  "\x18\xf0\x3b\x6b\x73\xc3\xba\xed\xba\x14\xe8\x7f\x50\xae\x87\xd5"
-  "\xce\x41\x79\xd2\xb6\xa0\xb6\xce\xc3\x6a\x9a\xc2\xbc\x53\xad\x47"
-  "\x5b\x97\x64\x7b\x64\x3b\x7d\xd4\x16\x11\xa3\x50\x9e\x91\x12\xfd"
-  "\x06\xad\xac\x56\xfb\xae\xf5\x87\xca\xeb\x23\xbc\x13\x7b\x3b\x5c"
-  "\xe8\x92\x65\xbf\xd1\x3e\xb4\x3d\xb2\xcd\x6a\x7b\xad\x52\x0f\x5f"
-  "\x97\x18\xa9\xa7\x92\x31\x60\xea\x66\x87\xcf\x5e\x6e\x2f\x3c\x9f"
-  "\x46\xdc\xba\xe4\xfe\x1f\xc3\x48\x76\x61\x72\x92\x0d\xf4\x22\xe3"
-  "\xee\xdb\xe6\xfd\x73\xc6\xbc\xd4\x7b\xee\x5a\x24\x76\xd4\x87\xdf"
-  "\xcf\x5f\x39\x7a\x86\x91\x78\x65\x21\xdc\x08\xd0\x78\x4d\x38\xca"
-  "\xea\x7d\x72\x5f\xa5\x6e\xdf\xc8\x7d\x95\xba\x4e\xfa\x79\x19\xdb"
-  "\x61\xa2\x9f\x8f\x56\x25\x4a\xae\xef\x55\xf1\xa5\x8f\xda\xdb\x1b"
-  "\xc6\x97\x7a\x61\xe7\x0b\x7d\xb6\x94\x73\x77\x90\xac\xb1\x7d\x76"
-  "\xe4\xbb\x30\x4f\xbf\xc3\x36\xcc\xd3\x0f\xd3\x83\x1d\x0b\x35\xfe"
-  "\x9e\xd2\x0c\xc4\xdb\x4f\x02\x6f\x2f\xfd\x04\xd6\x8b\x38\xcb\x90"
-  "\x37\x20\x5b\x98\x75\x88\x0b\x24\xe7\x27\x78\xa8\x0c\x5a\x4f\x10"
-  "\x87\x1d\x72\x86\xe0\xe3\x61\x37\x2e\xe6\xe8\x8e\x12\x6d\x8e\x82"
-  "\x9f\x17\x71\xe4\x06\x44\xcc\xf6\xd3\xaa\x6c\xc8\x68\xde\x64\x43"
-  "\x37\xe0\x8d\x3e\x18\x80\xce\x16\xb2\x13\x8f\x35\x67\xab\x6d\x6a"
-  "\x81\xae\x00\xfc\xb0\xd0\x17\x39\xeb\x16\x0a\x1b\xcb\x4d\x53\x6f"
-  "\x15\x3a\x33\x61\x63\xb9\xa3\x2f\x8c\x73\xf5\x3e\x8c\x25\x60\x40"
-  "\x78\x10\x10\xf6\x56\xc3\x7d\xae\x8f\x1f\xee\x73\x0e\xf5\x73\x50"
-  "\x9c\xfb\x9b\xa4\xc6\xba\x16\x7d\x1c\xab\x7f\xa3\xf7\xad\x7e\xe9"
-  "\xdf\xec\x9b\x93\x4d\xc0\xbc\xd0\xfa\xf8\xd9\xfe\xd5\xef\x3e\xaf"
-  "\x7f\x2b\x3e\xdb\xbf\xfa\xd6\x61\x9d\x98\x9c\x23\x24\xeb\xd5\x9f"
-  "\x45\x3f\x81\x07\xd4\xcf\xc3\x51\x56\xe3\x57\x22\xee\x93\x46\xa3"
-  "\xad\x71\x45\x7a\xf5\xbc\xff\xce\xef\x62\xbf\x07\x65\x3d\xa1\x57"
-  "\xb2\x9e\x70\xd2\x8f\xae\xa0\xb1\x61\x1e\x96\x07\x64\xfb\x76\x2e"
-  "\x38\x90\xdb\x87\xb5\x39\x30\xa6\x9d\x45\x0e\x3f\x0c\x58\x02\x26"
-  "\xa9\x21\xef\x5c\xf8\xab\xf6\x3b\x77\x16\x0e\xd3\xe6\xaf\x2c\x6e"
-  "\x8c\x2a\x62\xb6\xfd\x75\x37\x20\xbd\xc6\xc3\x76\x32\xd5\x8e\xc4"
-  "\x77\xfe\xb7\x04\xef\x14\xf5\x7b\x97\xf6\xfd\xf9\x7e\xe4\xc4\x41"
-  "\x87\x15\x4b\x72\x96\xdd\x24\xce\x30\xd8\xd5\xd0\x7b\x23\xe7\x55"
-  "\xe9\xfe\x6b\xa1\x9b\xa0\x71\x9f\x84\xbd\x69\xb9\xfe\x35\x64\x21"
-  "\x1e\x2a\xbd\x4b\xe2\xc2\x4e\xff\x76\x11\xa3\x92\xc6\xe8\x76\x61"
-  "\xbb\x9a\xc7\x54\xf9\xa3\x61\x4e\xc4\xf9\x06\x61\x0b\xe6\xce\x13"
-  "\xf6\x13\x34\x3e\x3b\x3b\xc2\x36\x61\x0d\x4b\x23\xe8\x87\x29\xb2"
-  "\x8d\xab\x56\xda\xb2\x96\xac\x5c\xba\xea\x81\x07\x92\x6c\x6b\x57"
-  "\x8a\x9d\x01\x2c\x2c\x6b\xb2\xd7\x12\x7d\x10\x74\x61\xfe\xc2\x85"
-  "\x19\xb7\xde\xf3\xfd\x1f\x8c\xe0\x33\x8c\x55\x4e\xa5\x84\xca\x25"
-  "\xf9\xa7\xdc\x2b\xd7\xb1\x86\x16\x0f\xfb\x89\xe4\x79\x89\x97\xa1"
-  "\xb1\x9f\x76\x82\xfd\x2c\x31\x82\x5e\xc6\xd1\x73\x32\x77\x36\x64"
-  "\x63\x2c\xd4\x76\x05\x23\xf9\x13\x9a\x03\x51\x7e\xe7\xcf\x2c\x9a"
-  "\x3f\xdb\xec\x2b\x99\xde\x70\x65\x15\xab\xd6\x73\x1a\xa3\x9f\xcd"
-  "\xa2\x35\xf7\x30\xbd\x4f\x26\xbe\x73\xa9\xe0\xc5\x30\x26\x92\x17"
-  "\x77\x99\x83\x73\x05\x2f\x9e\xb1\x9e\xe9\xc0\x87\x6b\xf3\x23\x44"
-  "\x72\x6d\x28\x87\x77\x67\x04\x99\x05\x78\x5e\xb9\x12\xb8\x3e\x9d"
-  "\x07\x07\xb8\x27\x63\xbd\x91\xed\xa4\xe7\x8a\x13\x8c\xb5\xfb\x82"
-  "\xec\xbe\xb3\x24\x8f\xd0\x7d\x65\x0f\xcd\x8d\xa0\x02\xc7\xb2\xb0"
-  "\xe9\x20\x38\xff\x6c\x97\xc6\xeb\x9a\x8b\x6c\xc2\xdf\x20\x74\xe4"
-  "\xc0\x05\xf0\x00\x19\x21\xb3\x4b\xca\xbf\x3f\x6b\xbd\xa0\xde\x22"
-  "\x3a\x60\x1d\x2d\x9d\xda\x78\x00\xed\xa2\x76\x36\x52\xbb\xf6\xa2"
-  "\x3d\x15\x0f\xa0\x5f\x51\x37\x9a\x83\xc9\xe2\x9c\x1d\xda\x79\x9f"
-  "\x8f\xdd\x88\xf6\xdd\xf7\xf0\x8d\xac\xfe\x01\x81\x1f\x62\x0f\x52"
-  "\xb5\x6d\x30\x10\xee\x4c\xea\x61\x3f\x2f\xf4\x89\xf8\x4f\x3f\x4f"
-  "\xf7\x30\xa3\xb4\xbf\x52\xf5\x5f\xc8\x83\x77\x12\xc7\x7e\x5e\x28"
-  "\x63\xee\xfe\xbc\x50\xcb\x17\xd9\xb6\x79\x4b\x1c\xc4\x60\x2e\x7f"
-  "\xe0\x81\x65\xab\xd7\x68\xf1\x24\xed\xab\x56\x2c\xbd\x59\x3d\x9b"
-  "\xb3\x72\xd9\xba\x8c\xe5\x4b\x85\xed\x1f\xa5\xca\xdb\xf3\x78\x91"
-  "\x24\xc8\x04\xc2\x9e\x46\xf0\x21\x4f\xff\xa1\x5e\xe5\x49\x8e\xb2"
-  "\x5f\xc0\x37\x33\xad\xef\xbf\x78\x4c\xae\x0f\xd1\xa7\xfd\xce\x5f"
-  "\x18\xb5\xf5\xa1\x7f\xe2\x6c\xe2\xf5\x7f\x61\xa5\x31\xef\x8a\xa4"
-  "\x59\x38\xff\xec\x5a\x09\x1b\x80\xff\xb8\x59\xd9\xd2\x9c\xc8\x63"
-  "\x5e\xec\xa2\x39\x69\x02\xff\x0c\x5d\x96\xf4\x13\xfc\x8b\xa5\xa0"
-  "\xa9\xb0\x21\x40\x5c\xdf\x6e\xf6\x8b\x59\xc4\x8b\x10\x4e\xfd\x47"
-  "\x0a\xc9\x42\x89\x9b\x37\x30\xe3\x8e\x27\x79\x37\x74\x94\xd2\xbe"
-  "\xf8\x17\x85\x6f\xd2\x7c\x52\xf7\x28\x3c\xe5\xf4\xce\xc3\x7e\x21"
-  "\x7d\xe6\x97\x34\xcf\x56\xf5\x0c\xb3\x29\xdf\x6e\x0f\x33\x35\xc9"
-  "\x75\xe8\x25\x26\xf4\x95\x82\xee\xfc\xa2\x95\x97\xbe\x54\x25\x74"
-  "\x40\xa5\x2f\x31\x85\x67\x45\xe1\x99\xf8\x9c\x18\x2a\xc7\x88\x38"
-  "\xee\xaa\xad\x44\x14\xc1\x3c\x80\xfe\x52\xb9\x29\x38\x1f\x0e\xb9"
-  "\x5e\x2d\x3f\x05\x32\x3b\xad\x2b\x3e\xac\x2d\x3c\xba\x39\x81\x0f"
-  "\xf4\x35\xd0\xfa\x06\x3e\xd3\x1b\x57\x14\x24\x79\xb5\xd9\x26\xf8"
-  "\x4d\xdf\x74\x4e\x6b\x5d\x48\x9c\x4b\x5b\xcf\x62\x47\xf2\x99\xbb"
-  "\x16\x6a\xf8\xa7\xe0\xfb\x01\x86\xf5\xb2\xb0\x9b\xed\x12\x36\x3c"
-  "\xd0\xdd\x02\x86\x83\x04\x37\x82\x9d\x87\xea\x68\x24\xde\x38\xb6"
-  "\x87\xed\xda\x02\xf8\x55\x28\x84\xef\x83\x82\x5f\x36\x23\xce\xe9"
-  "\x51\xb6\x6b\x2d\x60\x87\xb2\xa8\xcf\x8d\x41\x7f\xfa\x77\xe0\xbf"
-  "\x02\x7d\xdf\x98\x47\x6b\xd1\x03\xe8\xff\x53\xe7\xc0\x5f\x12\x6f"
-  "\x2d\xee\x0b\x96\x72\x45\xc0\x5e\xd8\x33\x3c\x75\x6e\x63\x2f\x57"
-  "\xce\x39\x19\x6f\xa1\x55\xfd\x9c\x9e\x05\x03\x24\x07\x42\x6f\x5b"
-  "\x70\x12\x3e\x36\x1a\x08\xb7\x4b\x18\xd5\x6b\xac\xd8\xc0\x2c\xf0"
-  "\x49\x52\xe0\xe0\x81\x76\x5f\x1d\x6b\x77\xd4\xb1\xf7\x82\xd5\xcc"
-  "\x95\x83\xbd\xc1\xa7\x1b\x0e\xe6\x56\x83\xcf\x8b\xa6\xfb\x25\xb6"
-  "\x7f\x16\x75\xcd\x3e\xd8\x79\x88\x1d\x74\x1d\x62\xb6\x7f\x15\xcf"
-  "\x0b\x5a\xd3\xdf\x63\xad\x29\xef\xb1\x82\x6e\xae\x80\x47\xc9\x7f"
-  "\x08\x75\x94\x50\x59\x0d\xf0\xe5\x61\x51\xfa\xad\x31\xd4\x7f\x43"
-  "\x6a\x2e\xe6\xbb\x97\x70\xe9\x37\x68\xe3\xbb\xf5\x67\x98\xd1\xb5"
-  "\xf2\x2d\x71\x2f\x79\x87\xbe\x06\xf7\xd2\x2e\xb1\x97\x0c\xdf\x25"
-  "\x88\x0d\x4c\x6b\xaf\x52\x89\x36\x86\x64\xbb\x09\x5e\x06\xed\xfb"
-  "\x9d\xf9\xc3\xdf\x0b\x5f\xa9\x3b\x00\x0f\x6a\x53\xdb\x22\x09\x93"
-  "\xd6\x2e\x82\xe9\x3f\xab\xf0\x49\x8f\x84\xcf\xae\x5e\xc0\x07\x76"
-  "\x22\x4a\x4e\x5f\x03\xb5\x2d\x85\x60\xa0\x68\x75\x60\xfc\xa9\xad"
-  "\x1c\xe5\x57\x9c\x61\x26\xd7\x4a\xd8\x91\x3c\x7d\xa7\x39\xcd\x60"
-  "\x54\x06\x4e\x36\x56\x9e\x65\x42\x87\x8b\x75\xa8\x52\xbc\x47\x99"
-  "\x4f\x63\x4f\xd0\xe2\x8d\xde\x6f\xa5\x5f\x02\xfd\x6c\xc0\x43\xba"
-  "\x26\xd2\x78\x95\x50\x1b\x5a\x68\xac\x1a\x70\x95\x38\xbe\x57\xf8"
-  "\xa1\x55\x79\x8b\x70\x7a\xe9\x5e\x12\xc9\xb2\xa2\x14\x21\x2b\x3d"
-  "\xd5\xa2\x6c\x71\xf7\x4a\x9b\x82\x9f\x97\xed\xa0\x75\xa5\xee\x71"
-  "\x71\x6e\xcd\x54\x3f\x59\xc4\x07\x65\xdb\x85\x7d\xeb\xd3\xc3\xeb"
-  "\x7f\xa9\x88\x3b\xfa\x54\x40\x2f\xf6\x8e\x9b\xe7\xa8\x78\x3e\x87"
-  "\xf2\x78\x3d\xec\x12\x8f\x5c\x33\x9e\x0e\x6a\x73\x8a\xe8\xf5\x30"
-  "\xfe\xd3\x3c\xa5\x76\x13\xbe\x0b\xdd\x23\x09\x87\xc1\xe9\xc3\xba"
-  "\x47\x89\xe7\xff\x31\x4b\xc3\x73\xea\x9b\x09\xf4\x02\x73\x7b\xac"
-  "\x75\x9f\xe8\x6a\x2b\xf6\xf3\xf9\xe5\xe9\xcc\x44\xfc\x92\x29\xd3"
-  "\xcc\xdd\xc1\x03\xc0\x43\x93\x98\x3f\xf2\x1d\xf1\x3b\x5e\x33\xd1"
-  "\xe2\x0e\x4a\x37\x68\xe9\xa0\xcb\x0a\xc9\x88\x90\x4f\x53\xd7\x9b"
-  "\x79\xfe\x59\x96\x20\x74\x3d\x5a\xfa\x7a\xaf\xb9\xdd\xca\x60\xdf"
-  "\x17\xc4\x99\x57\x7c\x43\xe9\x51\x44\xc7\xf7\x51\xbd\x2e\xca\x1f"
-  "\xaf\xe5\xe7\xfd\xe9\x06\x77\xee\x01\xd1\x07\xf8\x71\xd0\xe8\x3a"
-  "\xa5\x4f\x48\xcd\xf5\x9a\xc5\xb8\x6b\x69\x6b\xd2\xc5\x3a\x84\xf3"
-  "\x75\xc4\x5f\x71\xd1\x9e\x1e\x91\xae\x23\xbe\x4d\xc4\x46\x8d\x48"
-  "\xd3\xe3\x2c\x23\x7c\xf0\x44\xa4\x45\x51\x9b\xd9\xf0\x33\xd5\x5d"
-  "\xf9\xa0\xe0\x23\xad\xa9\xeb\xa9\x3c\xd4\xf3\xa0\x5a\xf7\x7a\xce"
-  "\xa4\x6f\x2f\x99\x26\xd7\xbc\xdd\x35\xc3\x3c\x23\xf8\x9f\xfe\x74"
-  "\x51\xb7\xd2\x9f\xae\x0f\xf5\xa7\x47\xa1\x7e\x94\x05\x3d\xa3\x88"
-  "\xd1\x1a\xec\x65\xf0\x2b\xc9\xcb\xcd\x55\x1c\xf6\x9c\x54\xae\x68"
-  "\x4f\x2e\xc9\xf1\xb1\x16\xcb\xe8\xfb\x89\xa1\x05\xae\xfc\x7f\xa5"
-  "\x79\xf1\x0c\x70\x9f\x85\x8c\xef\x24\xdb\x1e\xc4\x1e\xd0\x33\x97"
-  "\x01\x07\x43\x44\x2b\x42\xd1\xef\x24\xcf\xec\x65\xba\x7c\x9a\x7f"
-  "\x52\xce\x7b\xe6\x9b\xf0\x81\x54\xa0\x70\x4e\xf7\x49\xc0\x7f\x73"
-  "\x1f\xf6\x01\xdf\x99\x25\xf6\xde\x62\xce\xa5\xb8\x03\xbd\xac\xb5"
-  "\xf0\x23\xd6\x1a\x74\x17\xee\x3b\xe3\x35\xc8\x3d\x38\x03\xca\xbd"
-  "\x13\xef\x0a\x68\xce\x65\x84\x1a\xc6\xd4\xc5\x81\xff\x25\xd8\xfd"
-  "\x45\xd2\xf7\x67\x1a\x34\xbe\xf7\x6f\xf4\x21\x00\x3f\x4a\xd8\xa3"
-  "\x57\x4a\x7f\x9f\x42\x6d\x29\xe0\x7e\x3b\x9b\xb9\x01\x72\xef\x33"
-  "\x1d\x71\x3e\x96\xa2\x96\x7b\x5a\x2d\x37\x70\xa1\x72\x81\xb7\xad"
-  "\x35\x42\xf7\x4b\x7d\xfa\x7d\x72\x88\xca\x0e\xc5\xfc\xde\x41\xeb"
-  "\x48\x41\xc1\x39\xe8\x40\x7e\x75\x1b\xd5\x93\xdc\x1e\xec\x60\xf0"
-  "\xc7\x56\xaf\xd0\x7a\x7b\xda\xca\xd4\xfd\xc6\x82\x53\xec\x97\xd7"
-  "\x28\xdc\x6e\x21\xfe\x1c\x3a\xcf\x02\xd0\x6a\xf0\xfa\xf9\x21\x36"
-  "\xd1\x9d\xed\x61\xf0\x27\x44\x65\x7c\xf3\x6d\xe8\x97\x89\xde\x85"
-  "\xb8\x55\xff\xdb\x01\x0f\xab\xa4\x35\x40\xf8\x17\xda\x74\xf9\xf6"
-  "\xb8\x22\x36\x97\xeb\xcd\x62\x3f\x99\xd6\xa7\x05\x34\xb6\x35\xa2"
-  "\x3d\xa5\xcd\x0b\x22\xf6\x36\xa3\xa8\xae\x67\xb1\xb7\xc9\x8d\xcd"
-  "\x96\x3a\xe8\x7b\xa3\xcf\xd9\xbc\xd1\x01\x0b\xa7\xb1\xf3\x3b\x7f"
-  "\xe9\xf1\xb0\xdd\x62\x5d\x2f\x83\x2d\xad\x58\x33\x7e\x75\xa7\x37"
-  "\xfa\x03\x2b\xca\x82\xff\x01\x25\x27\xd8\x58\xf9\x29\xf1\x2f\x02"
-  "\x2e\xbf\xba\xae\xbd\xcf\xef\xe2\x25\x1f\x58\x31\x9f\xd4\x3a\xcc"
-  "\x54\x47\x88\x6f\xf9\x80\x78\x82\x5f\xa9\x6b\xb3\xb8\xb7\xe2\x7d"
-  "\x70\x08\xb6\xbf\xbf\x2c\xab\x1b\x84\x8e\xed\x97\xb3\x89\xbf\x73"
-  "\xf5\x1b\x3f\xb0\x7e\xdf\x5a\x48\xeb\xfb\xaf\x32\x3d\xba\x77\x93"
-  "\x54\x99\x5b\xf8\x4c\x1a\x73\x7f\xbb\xd6\x1a\xe3\xa6\x42\x88\x57"
-  "\x8d\x3f\xc1\x9e\x7d\x7f\xd0\xc9\xf4\x43\xb4\x46\x0f\xea\x89\x4f"
-  "\xaf\x4d\x37\x55\x4c\x65\xc9\xf4\x6e\xea\x09\xf6\xab\x97\x83\x7a"
-  "\x16\x4f\x3f\x8b\xf7\xf2\xac\x68\x2a\x37\x05\xfa\x88\xb6\x33\x90"
-  "\x3f\xf7\xc8\x73\xc2\xdb\x59\xa2\x42\xe5\x41\x8f\x5a\x39\x95\x25"
-  "\x42\x27\x40\x69\xf6\x8c\x90\xdc\x63\xd0\xe4\x97\x4d\x53\x59\xd2"
-  "\xc8\x7a\x7f\xa5\xfa\x42\x7a\x56\xc4\x8c\x5b\xe7\x65\x57\x38\x6e"
-  "\xe1\x47\xa9\x5c\xf8\xa0\xe5\xfc\x72\xab\x5e\xee\xc5\xed\x59\x6f"
-  "\xae\x91\xf8\x27\x74\xea\x84\x77\xd8\xb3\x50\x75\xb5\x3a\xe1\x2b"
-  "\x2a\xe6\xa0\x0b\xb6\x97\x11\x3a\x19\x8b\x68\x87\xea\xe7\x25\xb4"
-  "\xe9\xda\x4c\x94\x81\xf6\x64\x2c\x91\x7a\x5e\xf8\x80\x21\xb8\x0a"
-  "\x3f\xbe\x65\xdb\x99\xe9\xd1\xed\xcc\xd2\xf6\x80\xe8\xd7\x6e\x39"
-  "\x27\x0d\x0c\xed\x55\x4a\x30\xdf\x08\x37\xa8\xdd\xa8\x0f\x38\xd2"
-  "\x1e\x3c\xed\x2a\xc8\xe6\x8a\xeb\x41\x9c\x3f\xdc\x73\xdc\xb5\x7a"
-  "\x0f\x4b\x85\xcf\x1c\x9c\x9b\x5f\xcc\xbc\x3b\xa9\xbc\x9d\x53\x99"
-  "\x85\xca\x3a\xeb\x5e\x01\x9a\x6b\xfd\xb2\x6b\xf5\x5e\x2a\xfb\xd9"
-  "\x68\xac\x6d\xe5\x04\x1f\xb9\xc6\x3d\xbb\xcf\x1d\xe8\x62\xf0\x91"
-  "\x7b\x97\x83\x87\x50\x0e\xe5\xf9\x96\xe8\x6f\xad\xd5\x96\x21\xfd"
-  "\xf4\x88\xbe\x0e\xeb\xcf\xd5\x7e\xb8\xcf\x88\xf2\x16\xb9\x33\x89"
-  "\x2f\x57\xfb\xa4\xc1\x5a\xe2\xd7\xb3\x8f\xb9\x56\xef\x62\x18\x1f"
-  "\xe4\xa7\xe7\x42\x77\x1f\xe5\x3d\x39\x72\x5c\x90\x87\xde\xbd\x40"
-  "\xe5\xfe\x53\x78\x5f\x08\xfb\x15\xe1\x3c\x75\xd4\x1f\x82\x95\xaf"
-  "\x96\x60\x24\xf5\x68\xcf\x4e\x43\x5b\x69\xec\x12\xdc\xd9\x1f\x8d"
-  "\x6e\xf3\x4c\x34\x80\xf0\xbe\xa8\x5d\xe8\xc2\x9f\x8b\xbd\x2b\xa8"
-  "\x70\x49\xd7\x9e\x73\x29\x44\x0f\x3c\x74\x05\x4d\x10\x74\x65\x06"
-  "\xfc\x2f\x3d\xf7\xa6\x59\x27\xc7\x17\x7d\x01\xff\x35\xda\x18\x47"
-  "\xe8\xe9\x2d\x68\xab\x36\xc6\xdc\x18\x5a\xa0\x60\xff\x65\x2a\xc1"
-  "\x7b\xc8\xca\x24\xfe\xf1\x2a\x2a\xf7\x05\x95\xc7\x2d\x53\xd7\xe6"
-  "\xb2\xfe\xe8\x77\xe6\xf0\x47\xac\x4c\xb3\x7f\xa0\xf9\x3b\x3b\x43"
-  "\xda\x94\x58\x41\xab\x76\xea\xb9\x1a\xe7\xe4\x39\x97\xfa\x6d\x89"
-  "\xf4\x3b\xf6\x5c\x21\x7d\x5f\x32\x6a\x7f\xa3\xa6\xc2\xd7\x6a\x01"
-  "\x7c\x12\x89\x7d\x72\xa2\x59\xb4\x2e\x4c\x74\xfb\x06\xc5\x19\x95"
-  "\x1e\xf6\xfc\xcd\x88\x57\x0b\x3b\x74\xad\x6d\xe3\xd3\xa9\x3f\x6f"
-  "\x94\xba\xb5\xe7\x17\x68\x72\x23\x37\x12\x8c\x9d\x66\xe1\x2f\x15"
-  "\xfb\xae\xbe\xe8\x50\x9a\x37\xd6\x5c\x28\xe7\xcd\xf3\x0e\x1e\x2d"
-  "\xe9\x6e\x46\x80\x15\xa2\x5f\xaa\xfc\x34\x11\x7d\xa6\x72\xaa\x48"
-  "\xa6\x9d\x2f\x79\x0b\x59\xf6\x98\x3e\x88\xb5\xbe\x51\x9f\xe4\xf9"
-  "\xa5\xd0\x02\xd1\x37\x9c\xc1\x15\x7d\x6b\x8c\x15\xba\xac\xf1\xf5"
-  "\xa7\x4b\xc2\x36\x94\xe6\x9a\x8a\x32\x5e\x78\x4a\xd8\x07\xd1\x98"
-  "\x48\x9d\x63\x63\x26\x8f\x79\x34\x66\x7c\x65\x36\x4a\xbb\xe2\x32"
-  "\x73\xe1\x56\xc4\x08\x10\x36\xc9\x38\x37\xf2\x42\x39\xd1\xf4\x42"
-  "\x11\x33\x99\xea\x23\xfc\x88\xa0\x43\x2f\x58\x30\x56\x33\xf6\xb0"
-  "\x14\x89\x87\x2f\x4c\x80\x4e\x49\xfa\x88\x6f\xdc\x4b\x78\xaf\xea"
-  "\xe4\x34\x5b\x19\x9d\xb0\x95\x89\xa4\xb1\xe3\x6c\xa3\x8c\x91\x19"
-  "\x33\x40\xfc\x61\xe3\x2e\x61\x23\x48\xed\x5d\x17\xd4\xe8\x5f\xe3"
-  "\x2e\x3e\xc0\xbb\xa1\xf3\x03\xff\x94\x01\x5a\x96\x2f\x7d\x78\xf8"
-  "\x9d\x2f\xcc\xd7\x78\x15\xf0\xd6\xb0\x85\x42\x3e\x1a\xfb\xd3\xc8"
-  "\x23\x7d\x0c\x9c\x50\xcf\x33\xbc\xf0\x03\xf5\xac\x82\x1d\x76\x4a"
-  "\xf4\x2d\xd1\xbb\x4e\x31\xde\x80\x01\xea\x16\x6d\xd7\x43\x9f\xf5"
-  "\x42\x5d\x58\xc7\xda\x28\xec\xa2\xe4\x79\xa3\x17\xf6\x6a\x38\x42"
-  "\xfd\x9d\x28\xfd\x02\x37\x4e\xdb\x9f\xc4\x04\x0e\xf4\x73\x6b\xcc"
-  "\x55\x75\xc0\xc9\x17\x0e\x47\xc2\x29\x35\xa8\x14\x48\x1a\xd4\x78"
-  "\x80\x8b\xb9\xde\x78\xe0\x6f\xf3\x15\x2f\x5e\xaf\xf1\x24\x12\xce"
-  "\x16\xa2\x2f\x7b\x83\x02\xd6\x25\x2f\x79\xe1\xcb\xeb\x91\x7c\xf8"
-  "\x23\x7c\xf1\x53\xf8\x7a\x0c\x96\xec\xb5\x84\x0a\xac\xf0\x23\xcf"
-  "\x94\x92\xbd\xb6\x1e\x07\xd3\x67\x38\xa0\x57\x3e\xe4\x81\xbc\x48"
-  "\xf2\xa8\x85\xc7\x10\x9f\x42\xf3\x7c\xe3\x72\x66\xfe\x61\x16\x95"
-  "\x5d\x60\x8f\x87\x2f\x46\xf8\x61\x84\x2f\xd5\x50\x81\x7d\x32\xdd"
-  "\x4f\x21\xbe\xce\xc2\x8d\x7b\xc5\xd9\x95\x90\x93\x13\x3d\x3e\x0c"
-  "\x7f\x90\x7a\xb7\x37\xc0\x36\x9e\x64\x46\xf8\x7a\x0c\x6e\x39\x44"
-  "\xf2\xda\x9f\x84\xac\x14\xe7\x60\xf1\xc4\x87\x24\x10\xcc\xad\x4a"
-  "\xf4\x21\x8f\x37\xfa\x50\xb7\xec\xf7\x69\x2e\xfb\x2d\xdb\x8d\xf6"
-  "\x4b\x1a\xf7\x6b\x5b\xbe\x68\xfb\xde\xad\x41\x2a\x5f\x29\x79\x2d"
-  "\x21\x54\xf2\x9a\x55\x9e\x99\x69\x65\xf9\xd9\xbc\xd7\xed\x6b\x25"
-  "\xf9\xed\xac\x88\x7d\x81\xbd\x6f\xf4\x11\xfd\x43\xdd\x07\xcf\x9c"
-  "\x14\xbe\x2b\x83\xf4\x5c\xb0\x42\xfd\xa6\x8f\xbe\xe9\x6b\x65\x83"
-  "\x25\xaf\x89\xbe\xb7\xfb\xe4\xb7\x19\xe2\x1e\xdf\x47\xc0\x41\xed"
-  "\xf3\x30\x1c\xa8\xef\xe8\x1f\xfa\x1f\x04\x4c\x08\x06\x6a\x5f\xad"
-  "\x43\x6a\x3f\xd1\xc7\xf7\x68\xd5\xd9\x4e\xfd\xa4\xbe\x8a\x7e\x0e"
-  "\x51\x3f\x5b\xb2\x18\x0b\x94\x86\x32\xcf\xc5\xbc\x66\x85\xbc\x5b"
-  "\xf0\x3e\xf1\xf2\x79\x55\x8c\xe4\x5a\xc3\xb3\xf9\x55\xfa\x52\xe2"
-  "\x4d\xf2\xbd\x24\xdf\x7a\x79\x6f\x3b\xf5\xc9\xed\xa0\x5f\xb0\x8e"
-  "\x81\xc7\xd1\xf8\x76\xaa\xdb\x7a\x50\x39\xc6\xf2\x7b\x79\x2f\xf1"
-  "\xa8\x01\x77\x90\xf2\x64\x51\xff\x49\x1e\xee\x51\xdb\x8f\xbc\x1b"
-  "\x3f\x95\xfd\x32\xaf\x60\xf1\x6f\xfc\x6b\x89\xde\xdd\x55\xc2\xb4"
-  "\xbe\xdc\x47\xf9\xa8\x3f\x56\x2a\x4b\xc4\x5c\x54\xa8\x9f\xb5\xd4"
-  "\xce\x40\x44\x9f\xda\xfa\x02\x54\xe6\x87\x2c\x26\x8d\xe9\xb6\x9f"
-  "\xa2\x7e\x9c\x62\xd6\xaa\x7c\xe2\xbf\xee\x06\xdf\xf8\x52\xdb\x45"
-  "\xe9\x2c\xd1\xc3\x5e\x94\xf1\xba\xa4\x6f\xb9\x4b\x4e\xb0\xbd\x67"
-  "\x35\xff\x71\x0a\xfc\x6f\x46\x1f\x0a\x02\x8f\x84\x2f\x39\xac\x19"
-  "\x7e\xc2\x19\xec\x51\xaf\xa3\x3a\xfc\xf6\x29\xa2\x3d\x4e\xe9\x7f"
-  "\x8e\x9e\xe1\x0b\x1b\xf6\xe8\x3a\xfa\x2e\xc0\x09\x66\x28\x9f\x6f"
-  "\x39\xd4\x8d\x2b\x60\x38\xaa\xed\xd0\x73\x6c\x36\xd5\xb1\x00\xb2"
-  "\x7c\x63\xbe\x57\xff\x93\xe7\x58\xd2\xf8\x68\xca\xcb\x89\x63\xd1"
-  "\x6f\xe8\x24\x51\x1e\xf5\x6d\xf2\x09\xf6\xeb\xe8\x91\x73\xcc\x26"
-  "\x68\x99\xa4\x83\x2f\x77\x40\xe7\x37\xce\x7a\xa5\xdf\x4a\x27\x2f"
-  "\x19\xe7\x77\x9d\x5a\x3b\xe8\x7e\xcc\x58\x23\xe3\x87\xc3\xaf\x93"
-  "\xc6\x2a\xab\xfc\x49\x71\x36\xae\xa0\xe2\x49\xa2\x17\xc4\x2b\x20"
-  "\xb6\x3b\xf8\xba\x03\xbb\x7c\x6c\xcd\x0e\x66\x2c\x38\x09\x1d\xd3"
-  "\x9d\x6c\x7f\x5d\x32\xab\x3f\x03\x9f\x10\xf6\xc9\x4f\x9c\xc1\x3e"
-  "\xa3\xa4\x21\xe0\x49\xa1\x3b\xe5\x6b\xec\x96\xca\x27\x35\x1e\xfe"
-  "\xd7\x67\xf3\xce\x32\xbd\x8c\x37\xfa\x6b\xdf\x7c\x1b\x0f\x56\xeb"
-  "\x95\xac\x3a\xf8\x56\x8c\xf1\x3b\xe0\x5b\x51\xf3\x35\x28\x78\x9f"
-  "\x5c\x9a\x73\xfd\xd6\x98\xf2\xd5\x2c\x09\x7e\x51\xcd\x5e\xc9\xcb"
-  "\xc9\xf5\xfa\x95\x44\x6a\x9f\x45\xdd\x5b\xb3\x48\xff\x83\x2f\xaf"
-  "\xd8\x79\x46\xe8\x3b\xf1\xfe\x9e\x10\xc9\x32\xa2\xdc\xd5\x2c\xb1"
-  "\xee\x0c\xb3\x83\x0f\xca\x38\x26\x79\x36\xc8\x87\x77\xf6\x99\x79"
-  "\xe8\x13\x3b\xdb\x71\x22\xec\x37\xd5\xbb\x06\xbe\x56\xf9\xa8\xfa"
-  "\x58\xe8\xd1\x2b\xa7\x88\xbd\x74\xe1\x0b\x0b\xf6\x01\xf4\xcc\xaa"
-  "\x1f\x67\x86\xfd\x09\x8c\x41\x6f\x88\x7d\xb9\xfd\x41\x79\x1e\xc3"
-  "\xef\x7c\xe5\x80\xe6\x57\x72\x74\x5a\x7e\xce\x36\x53\xf0\x58\xe7"
-  "\x6c\xe3\x1b\xb7\x57\xba\xc7\x94\x55\xa8\x4c\xe0\xc1\x17\x2b\xb7"
-  "\x69\xce\x05\xf8\x1a\x83\x52\x22\x65\x33\x65\x22\xc9\x8c\x5e\xbf"
-  "\x4b\xfa\x43\x6a\x6a\x72\x6f\x56\x22\xe4\xb1\xa6\x6d\x78\x87\x34"
-  "\xf8\x98\x48\x11\xe3\xde\xe4\x81\x8c\xa6\xca\xb9\x6f\xd8\x86\xd3"
-  "\x24\xbf\x85\x75\x17\xf0\xda\x29\x7d\x56\xc5\xf9\x9d\x4d\x41\x6d"
-  "\xed\x05\x0f\x22\xf5\xd1\xaf\x5a\x3c\xba\x83\x4b\xc7\x82\x25\xf6"
-  "\x4c\x84\xff\x2c\xd8\xba\xc0\xaf\xa5\xf3\xd5\x14\x6d\x2d\x16\xe7"
-  "\x5c\x37\x4d\xbd\x75\xcd\x7a\x96\xf0\xfd\xcb\x8c\x0c\xfb\x52\x94"
-  "\xb7\x57\xf2\x08\xaf\x66\x85\x75\xf8\x29\x02\x37\x70\x5e\x4a\xc8"
-  "\x43\xf0\x43\x24\xfd\xb9\xf6\x69\xfe\x88\x24\xaf\xf0\xea\x4f\x22"
-  "\xea\xd9\x3d\xbc\xe6\x53\x1d\xd8\xef\x45\xf9\x92\x8f\x7a\x75\xb1"
-  "\xb0\xb9\xa7\x7c\x92\x17\x78\x75\xf1\x05\xe0\x6b\x07\x7c\x15\x55"
-  "\xf6\x75\xf7\x7d\x2c\xe1\x9b\xcb\xa2\x60\xd7\xfa\x46\xbe\xc7\x10"
-  "\x27\xfd\x0c\x9a\xa9\xfe\x73\x78\x8f\x79\xe9\x9a\x01\x3d\xe8\x6f"
-  "\xee\x71\x83\xc7\x18\x4a\x37\xdd\x05\xfd\x84\x90\x1b\x7e\x33\x1f"
-  "\x36\xa7\x94\x36\xf9\xf5\x53\x01\x43\xe5\x06\x96\x24\xfd\x3a\xfd"
-  "\x46\x9c\x13\xf3\x5e\xfa\x63\xff\x55\xf1\xcc\x7a\x55\x35\xb3\xfb"
-  "\x9d\xbf\x59\x41\xb2\xb0\xf0\xed\x28\xea\xaf\x30\x37\x0a\x1b\xd8"
-  "\x41\xcf\x04\x39\x56\xaf\x45\xd3\xb3\x3d\xfc\xfc\x9b\xa7\xd4\xfd"
-  "\x9b\x0e\x0f\x7b\xcd\xb8\xf3\x94\xe0\xa5\x3a\x84\x4e\xac\x24\x60"
-  "\x0d\xdb\x0f\xbc\x26\xfd\x70\xd0\x75\xbf\x83\x31\xd8\x93\xd6\x4f"
-  "\xe1\x1d\x54\x1f\xf1\x3f\xaf\x26\xa8\x3a\xa4\x0e\x81\x57\xe0\xcd"
-  "\x8b\x21\x2f\x7e\xec\x82\x4d\x2a\xd6\x34\xe2\xe5\x52\xa4\xbc\x11"
-  "\x48\x56\x08\x7f\xc2\xfd\xff\xcd\x5a\xe8\x59\x47\xa5\xdf\xdb\x19"
-  "\x13\xdf\x6c\xf1\xa7\x0b\xbb\x93\x72\x0b\xd2\x8c\x34\x17\xec\x74"
-  "\x35\x11\xce\xe1\x6a\xa1\xab\x8d\xae\xf1\xc4\xe7\x7a\x81\x97\x24"
-  "\x6f\x5b\x11\x8f\xa7\x3f\xda\x9f\x36\x96\xed\x38\x60\xe3\xde\xfc"
-  "\xcf\x4c\xda\xd6\xbd\xd6\x87\x58\x2c\xa9\x3b\x18\x5b\x13\xe4\x83"
-  "\xb6\x2b\xd8\x24\xea\x6f\x5f\xc1\x0e\xec\x81\xbf\xe6\x1a\xb9\x07"
-  "\xfe\x9a\x87\xb1\x7d\x36\xfa\x51\xca\x3e\xe2\x23\x5f\xeb\x0b\xff"
-  "\xf6\x79\xfc\xce\xd7\xfa\x08\x8e\xd2\xd7\xd4\xb8\xe6\xeb\x6b\x22"
-  "\x46\x5e\x25\x64\xb8\xe8\xdf\xdb\x64\x7f\xcd\x99\xf4\x6c\xe4\xb1"
-  "\xe6\x06\xb5\xbf\xb3\xe9\xd9\x62\x2b\xa0\x35\x38\x9a\x60\x32\x95"
-  "\xfa\x1c\x6b\x31\xa2\xbf\x68\x6f\x7f\xf4\x39\x7b\xa4\xdd\x3c\xca"
-  "\x44\xff\xbd\xd1\xf4\x1d\xc1\x92\x7f\x65\x71\xa3\x06\x4f\x15\x4e"
-  "\xb0\x35\xd6\xf7\x53\x19\x92\x67\xa3\xfc\x54\x86\x96\x7f\x18\xf6"
-  "\x53\xe1\x23\x85\xc6\x94\xf2\x91\xfc\x6e\xd4\x6c\xf2\xfd\xce\x7d"
-  "\x5d\x6f\xae\x90\xfb\x2a\xf8\xd6\x17\xf1\x2d\xce\x41\x8f\xf8\x3e"
-  "\x36\x62\xec\xa6\xc2\x57\xc0\x07\x16\x39\x76\xfe\x4c\xb5\x2d\xf1"
-  "\xa2\x2d\xd1\x01\x0b\xe1\xd8\x49\xd9\x9e\x7d\xad\x63\xcd\xb1\xfc"
-  "\x2b\x89\x47\x25\xce\x7d\xa6\x94\x5d\xe7\xb8\x13\x7c\xcc\x5d\xa7"
-  "\x10\xdf\x12\x48\x4b\xc9\xe7\xae\x1e\xf6\xdb\xa7\xda\x03\xbd\xe3"
-  "\x5c\xd3\x7f\x2b\x63\xa4\x0d\x16\x32\x77\xde\x0d\xd8\xa7\x65\xa7"
-  "\xd8\xeb\x1f\xba\xbd\xe2\x8c\x12\xee\x85\x3d\x24\xf6\xa7\xb1\xbe"
-  "\xc1\xf7\xaf\xa6\x27\x50\x28\x6f\x3d\xd2\x29\x0d\xe7\x26\x77\x46"
-  "\xbc\xe3\xa5\xfe\xd9\x72\xae\xbd\x5e\x0e\xfe\x48\xb4\x37\xf8\x1d"
-  "\x17\xda\xac\x94\xf8\x67\xa3\x0f\x05\xb0\x1d\x0e\xfa\x5d\x98\x2b"
-  "\xb6\x1c\xe8\x3d\x5f\x5f\x4e\xf8\xc8\x95\x2d\xfe\xd9\xe3\xeb\xc3"
-  "\xeb\xb3\x50\x67\x41\x90\x9f\xf2\x46\xfb\x67\x83\xaf\xaa\xcc\x9f"
-  "\x60\x9c\x57\xc7\x5d\xfd\x31\x81\x34\xbf\xf3\xf5\xb2\x37\x73\xe5"
-  "\x98\x8d\xb3\xdc\x32\xad\xef\xf5\x6a\xdf\x09\x5e\x02\x67\x67\xd6"
-  "\x48\x9f\xca\x94\xe7\xc0\xd8\x6b\x59\x20\x19\x6b\x19\xad\x19\xe7"
-  "\x24\x2c\xde\x88\x1f\x5e\x33\xc6\xd5\x8e\x37\xe2\x3f\x47\x1d\x43"
-  "\x6a\x1d\xb9\x5f\xb0\x8e\x0b\x9c\x8f\x11\x3c\xe3\x34\x92\xfe\x0d"
-  "\xe3\x97\x7f\xdf\xe8\x90\xb6\x4d\x81\xd9\x92\x96\xbe\xb9\x36\x44"
-  "\x32\x68\xd0\x64\x16\x3a\x06\xd8\xba\xba\x3d\x41\x16\x2c\xf9\xbd"
-  "\xad\x2d\x77\x90\xb9\x72\x0e\xb1\x6e\xe6\x12\xf1\x0f\xda\x88\xda"
-  "\x90\xac\xdc\x30\x54\x1a\x68\x18\xd2\xbf\x81\x58\x3d\x59\x3b\xe0"
-  "\xbf\x3a\x02\xcf\xda\x7d\x87\x98\x3b\x13\xba\xe2\x0e\xe8\xe8\x1b"
-  "\x88\x6e\x64\x2a\x44\x33\x48\xce\x08\x09\x78\x10\x0f\x26\x65\xc6"
-  "\xd0\x02\x21\x33\x7a\x85\x5f\xb7\x58\xe2\xdd\x4d\xdc\x59\x16\x84"
-  "\x1e\x3f\x34\x94\x6e\xf3\x3b\x59\x1a\x7c\x49\x43\x87\xce\x8d\xcd"
-  "\xf6\xd4\x60\x14\x17\x32\x21\xc9\x2f\xf0\x29\xed\xf6\x79\x58\x88"
-  "\x64\x81\xba\x01\x16\x5f\x47\xfc\x33\xd1\x72\x0b\xe8\xfd\x4e\xd5"
-  "\xa7\x74\xf9\x40\xd8\xa7\x74\x3d\xf4\x55\x5d\x74\x3f\xc0\x0c\xa1"
-  "\x2d\xa1\x05\xb5\x03\x2c\x71\x47\x0e\xb3\xd7\x42\x1f\x79\x5c\xf2"
-  "\x6f\xe0\x37\x84\x7f\xe9\x55\x76\xec\x8b\x84\xf9\x37\x9c\xb1\x0b"
-  "\xd3\x33\x83\xd0\xe3\x8c\x0b\xde\x6f\x0a\x9b\xac\x60\x89\x3f\x3d"
-  "\x68\xb2\x18\x87\x4a\xcf\xd9\x3d\xcc\x95\x3d\xa4\x7f\x7d\x54\x7f"
-  "\x8b\x9a\xfd\x49\x75\x84\x4f\xf0\x37\x13\x25\xdd\xa7\xb2\xc6\xf4"
-  "\x4d\x1c\xaa\x4d\x67\x33\xfb\x58\xb2\x3c\xdf\x12\x4d\x6b\xe5\x5b"
-  "\x09\xb0\x49\xcc\x7f\x88\x59\x43\xb5\x8b\x75\x05\x3f\x63\x51\xee"
-  "\x60\x0a\xc3\x2f\xff\x53\xde\x3b\x73\x05\x4b\xc6\x5e\x0a\xf6\x7d"
-  "\x6c\x8f\x20\xff\x9b\x27\x13\xf3\xd8\x88\x75\xea\xa1\xf5\xab\x97"
-  "\x5f\x9f\xfc\x6f\xcb\x6c\x0f\x2c\x5f\xfd\xd0\xba\x25\xab\x97\xb1"
-  "\x05\xd2\x84\x43\xb8\xcc\x5c\x0f\xfb\x8d\x75\xcb\xb3\xb3\x6c\xf7"
-  "\xaf\x5d\xbd\x7a\xd9\xca\x6c\xdb\x9d\xf3\xd2\x3e\xeb\x37\xa9\xd6"
-  "\xba\x4b\xf8\xc9\x13\xb6\x7d\xfb\xdb\xf8\x4f\xbf\x36\x50\x91\xc3"
-  "\x0c\xe6\xa2\xdb\x16\x99\x83\x0b\x6c\x32\xae\xc4\x7e\x2f\x6c\x69"
-  "\x79\x41\x7a\x8d\xe4\xb5\xf7\x7f\x2a\xe5\x93\xd6\x46\x79\x66\x73"
-  "\xbf\xd0\x13\x73\xff\x82\x04\x39\xa7\xf6\xeb\xa2\xb2\x19\xee\x1f"
-  "\xc2\xbd\x39\x9b\x95\xb8\xa6\x62\xbf\x7e\xbf\xdc\x57\xa9\x5d\xa8"
-  "\xd3\xf2\x69\x79\xe4\xfb\xb7\x3c\x78\x5f\x2f\x7c\x88\xbd\x65\x27"
-  "\xf8\x4c\xf6\x3b\xf7\x5b\x3d\xfa\x17\x35\x1f\x7a\xbd\xd2\xfe\x6e"
-  "\xbf\xf0\x23\xc4\x7f\x7a\xf9\x80\x5a\x4e\x1a\xd5\x77\x11\xe5\x9d"
-  "\x4f\x63\xd0\xaa\xda\xe9\x4d\x3f\xaa\xb6\x4b\xda\xc2\xbe\x75\x93"
-  "\xb4\x35\xd9\x9f\x15\x71\x5e\x4f\x9c\x55\xc4\x9a\xa9\xf2\xaa\x7e"
-  "\xb5\xbc\x32\x8d\x26\x50\xfe\x1a\xe2\xf7\x6c\xe3\xa7\x85\xfb\xe5"
-  "\xb9\xca\x11\xe7\xc3\x55\x38\xd5\x5a\x9f\x26\xfa\x90\x70\x82\xbd"
-  "\x55\x78\x3e\xbe\x0c\x8f\xe0\x77\x57\xde\xbf\xea\x21\xc7\x92\xec"
-  "\xe5\x3f\x5a\xbe\x62\x79\xf6\xfa\x9b\x44\x80\x14\xf1\xef\xdb\x57"
-  "\x2f\x5d\x74\xbe\xcf\xcb\x24\xe8\x89\x70\x36\x0a\xb2\x3e\xf4\x73"
-  "\xb0\xb1\x90\xfa\xba\x03\x5b\x84\x6f\xbb\x71\xb5\xfd\x80\x7a\x7e"
-  "\xf2\x40\xb5\x47\xf7\x5e\xb6\xd4\x5b\x9d\xb3\xb9\xbe\x1c\x42\x79"
-  "\xe2\x5d\xbf\xc9\x0c\x1b\x8e\x39\x47\x59\xcb\x1c\xec\xd9\x11\xfc"
-  "\xec\x58\x0f\x2b\x36\x60\xdd\xf2\xb0\xb6\xe0\x0d\x6a\x5c\xbb\xb7"
-  "\xb7\x01\x06\xe0\x15\x09\x06\xbb\x8e\xb2\xb7\xa5\x8c\x7d\xda\xba"
-  "\x0b\xb6\x4b\xca\x69\xeb\xd3\xc0\x2d\xb4\x57\xe1\xe9\xb5\x9c\xa7"
-  "\x6f\x57\x4e\x67\xd5\xf2\xd3\x59\xdb\xc3\xfe\x76\xde\xce\xa6\x6f"
-  "\xf7\xd0\xb7\xeb\xe1\xbf\xbf\xe2\x14\xdb\x03\x7b\x00\x3c\x9b\xb3"
-  "\x2d\x2c\x64\x0c\xd8\xd0\x1e\x77\x6f\xb2\xe0\xc3\xbb\x29\xbf\xdb"
-  "\x77\x03\x23\x1e\xd3\x0e\x7b\x0c\xb1\xf7\x18\x4d\x7c\x20\x7d\xe7"
-  "\xa6\x76\xb9\x7b\x07\x21\xd7\xdb\x14\xe2\x05\xa9\xaf\xbb\x68\xfd"
-  "\x4c\x43\xb9\xb0\x07\x21\x7e\x95\xf8\xb3\xb7\xcb\x3c\xec\x2d\x6d"
-  "\xcf\x53\xd8\x82\x8c\x1c\xc7\xb7\x9f\x25\x38\x4f\xd2\x7c\x7c\x62"
-  "\x2d\x81\xcc\x10\x3e\x17\xf9\xf6\x87\xe8\x23\xf6\xf3\xef\xf2\x71"
-  "\xa5\x5e\xbc\x7b\x39\x33\x62\x7f\x1d\x79\x84\x7f\x6b\xd8\xb3\x38"
-  "\x36\x20\xce\x69\xf3\xc5\x12\x5f\x5e\xce\xf0\x16\x64\x45\xa9\xe5"
-  "\x86\x50\x2e\xfc\xc8\x48\x58\x36\x5f\xef\xde\x7c\x4a\xb3\x23\xa1"
-  "\x76\x34\x7f\xa8\x96\xd1\x87\xb9\xac\x38\xf7\x07\x61\x4b\x2d\xfc"
-  "\x46\xca\xb3\x48\x3a\x92\x4f\xe1\xa7\xc8\x52\x3f\x59\xfa\x97\xf5"
-  "\x3b\x9b\x87\xf1\x9f\x1b\x25\x2f\x08\x7e\x0c\xf1\x49\x80\xff\xe0"
-  "\xed\xd0\x3e\xe0\x3f\x95\x5f\x8d\x7d\x7b\x39\x0f\x9a\x1b\xbe\xd8"
-  "\x3c\x68\x6e\xd0\x60\x21\xe5\xc7\xe6\x64\xae\x2f\xe0\x33\xcb\x58"
-  "\xa6\xb0\xaf\x50\xcf\xdb\xd1\x1a\x92\x20\x69\x4b\xcb\x34\x61\x1b"
-  "\x93\xd3\xd7\x40\x34\xbe\x70\xe7\x20\x33\x29\x25\xcd\x36\xf0\xe2"
-  "\x6d\x79\xc2\x2e\xc5\x48\xdf\x35\xc2\x6e\x05\x76\x78\x71\x22\xf6"
-  "\xcd\x21\xb6\xf3\x2c\x33\x74\xb3\x77\xec\xd8\xdb\x0a\x8f\xc3\x3b"
-  "\x1b\xb1\xa7\xc9\x4b\x5f\xec\x32\xe7\xe9\x4b\x50\x86\x32\x70\x72"
-  "\xb6\xf6\x1d\xce\xc5\xe1\xbb\xa3\xec\x9d\x25\xe2\x3b\xe4\x05\xcc"
-  "\xf2\x2d\x8b\x89\xe7\x4a\x47\xfe\x20\xf1\x62\xf5\x8a\x25\x8d\xd3"
-  "\xda\x10\xca\x09\x36\xd2\xbb\x45\x4a\xc9\x39\x3b\xa5\xa5\x8b\x3d"
-  "\x95\x21\x2b\xf6\x5c\x09\xd7\x3e\xb0\xba\xbb\x3f\x76\x89\xf6\xc0"
-  "\xfe\x34\x9b\xd6\x51\x21\xbb\xbc\xf3\x72\xfd\x71\x1a\x8f\x29\x22"
-  "\x36\x08\x8d\x73\x8b\x38\xe3\x42\xb8\xb8\x5b\xb6\xb1\xe5\xb6\xfe"
-  "\xd2\xd7\xac\xfd\x84\xab\x3e\xbd\x91\xed\xb7\x06\xb0\x86\x7b\xf7"
-  "\x5b\x07\x69\xac\x5a\xe2\x89\xf6\x2d\x90\xbc\xb3\xfc\x0e\x38\x1a"
-  "\x65\x8d\x1b\xa2\x77\xc9\x9a\x9d\x94\xb4\x55\x7a\xc7\x08\x98\x11"
-  "\x3e\xb7\xb4\xaf\x80\xbd\x9b\xd2\x4a\x75\xb0\x50\x8e\x72\x18\xfb"
-  "\xfd\x38\x53\x00\x79\x27\x35\x97\xf7\x43\x7e\xc3\x39\x2c\xec\xf1"
-  "\xe3\x8c\xe2\x0e\x92\x7f\x51\x2e\x95\xb9\x59\x3b\x47\x58\x4e\x69"
-  "\x02\xef\xa3\xee\x3d\x5e\xf1\xa0\x98\x73\xb0\x0d\x35\x89\xfd\x8d"
-  "\xa8\x1f\x1f\x27\xbc\xee\xaf\x3f\x25\xf6\xe5\xfa\xeb\xd5\x72\xe0"
-  "\xa7\x80\xca\x68\xd1\xca\x50\x72\x78\x37\xec\xf2\x42\x03\xdc\x23"
-  "\xbf\x97\xf6\x1b\x77\xf9\x14\x71\x46\x06\xdf\x4b\x3b\x8e\x96\x60"
-  "\x84\x5d\x3c\xd1\x9d\x77\x4d\x9a\x1f\x03\xba\xb7\x6a\xf2\x3a\x60"
-  "\xd4\x5f\x12\xb0\xf9\x68\xae\xfb\x4a\xfc\xc4\xa7\xbe\x3b\x8b\xe8"
-  "\x7d\xf5\x05\x74\x04\x06\xd0\x44\x9c\xfb\x55\x62\x9a\x17\xe0\xec"
-  "\x2f\x7c\x6d\x4a\xdb\xf6\x77\xb7\xaa\xe7\x80\xa3\x4e\xb1\x77\xbf"
-  "\x17\xde\xef\x0f\xa9\x3a\xea\x77\xf7\x49\xf9\xe2\xdd\x7d\x42\x47"
-  "\x5d\x1a\x60\xbf\xd8\x10\xd0\x37\x6e\xf0\xe8\xa5\x6f\xd7\x77\x1b"
-  "\x3d\x24\x01\x68\x76\x69\x94\xcf\x81\xb2\x46\xe7\x07\x5b\x8d\xb2"
-  "\xcc\xf7\x84\x1c\x1d\x96\xe3\xdf\x13\x7e\xe5\xb0\x37\xaf\x80\xb7"
-  "\x8b\xf9\x7d\x32\xec\xb9\xdc\x8e\x33\xd0\x55\x4f\x94\x3a\x05\x99"
-  "\x47\xb5\x9d\xfc\xd2\x89\x91\xcf\x93\xf1\x2c\x61\xf6\x5e\x8a\xb6"
-  "\xef\x55\xa1\x57\x3c\x66\x1d\xe3\x05\x0d\x44\xfb\x1c\x3e\xf8\x1f"
-  "\xf0\xba\x89\x57\x44\x6c\x51\xc7\x6a\xc4\x31\x7a\x6f\x2d\x7c\x9a"
-  "\xcb\xf9\xf6\x9e\x38\x37\xa7\x38\xe7\xf2\x02\xc8\x4b\x5e\xf8\x3a"
-  "\x3f\xc3\x28\xdf\xc5\x94\xef\x67\x07\xf2\xfa\x60\xa7\x16\x8f\x38"
-  "\x5b\xdd\x6a\xdd\xde\xe8\x56\xe3\x55\x26\x96\x49\x75\xee\xf5\xb0"
-  "\xba\xaa\xf1\xd3\x84\xf7\xf6\x5e\x48\x1f\x2b\xfb\x75\x30\x31\x3c"
-  "\x26\x7f\x51\xc7\xe4\x60\xe2\xdf\xb2\x95\x50\x79\xef\x4b\x4e\xb0"
-  "\xb6\x4b\xa0\x1f\xa2\xfb\xe9\x27\x58\xab\xa0\xb5\xd2\x0e\xb9\xf5"
-  "\x0f\xea\x3d\xd5\xd1\xfa\xa6\x7a\x7f\x39\xdd\x3f\xa3\xde\x4f\xa5"
-  "\xfb\xc7\xd4\x7b\x82\x77\xeb\x7a\xf5\x3e\x9e\xee\x97\xa8\xf7\x34"
-  "\x8f\x5b\xbf\xab\xde\x4f\xa1\xfb\xeb\xd5\xfb\xcb\xe8\xfe\x32\x75"
-  "\x8f\xd9\xd8\xc3\x5a\x27\x8c\x9f\xff\x3f\xd8\x21\xd7\xde\x56\x0b"
-  "\xcd\x65\xd5\x8f\xce\x70\x5a\xa2\x87\x35\xe5\x69\xfb\x48\x94\xde"
-  "\x82\x7a\x28\x7d\x0e\xe1\x5f\x4a\x44\xba\xea\x9b\xbd\x75\x11\xc9"
-  "\x13\x4d\x11\xe9\x7b\xd4\xf4\x15\x94\xbf\x25\x22\xbd\x41\x4d\xa7"
-  "\xf9\xff\xa2\x21\x22\xbd\x5a\x4d\xaf\xd3\x6c\x37\xd4\xf4\x12\x35"
-  "\x9d\xc6\xff\x99\x3d\x11\xe9\x79\x6a\x7a\x2b\x8d\xb1\x2f\x22\x5d"
-  "\xc8\xcc\xd2\xd7\x9e\x99\xef\xcf\x9b\x45\xb4\xad\x95\xd6\xde\xe7"
-  "\x77\x45\xe4\x59\x2a\xbf\x6d\x23\x18\x3c\xd7\x1a\x91\x9e\xae\xa6"
-  "\xdb\x3c\xec\x5c\x59\x44\xfa\xc2\xb1\x70\x48\x57\xc3\x32\xc7\xd2"
-  "\xe7\x82\x6f\x14\xb6\xa8\x82\x8f\x6c\xff\x21\xce\xc7\x98\x77\xf0"
-  "\xa3\xb6\x7c\xce\x8f\xb2\xf6\xf9\xaa\x5d\xa6\x45\xae\x57\xc0\xf9"
-  "\xf6\xeb\xc4\xd9\x13\xf8\x7a\xc3\x39\xa3\x0d\x38\x67\xd4\x26\xf6"
-  "\xcc\x67\xe6\x16\x4a\x3f\x70\x9a\x4f\x61\xe8\x04\xd4\x3d\x5f\xca"
-  "\xf3\x07\xe8\x4e\x51\x0e\xd6\x70\x77\xf6\xa0\xf4\x11\x48\xb2\x03"
-  "\xd2\x20\x1b\x8b\xf3\x28\x11\xb2\x99\x9c\x8f\xed\x3f\x54\x06\x71"
-  "\x96\x4f\xea\x0f\xb0\xd6\x23\x3f\xec\x95\x22\xf3\x7a\x58\xbb\xd0"
-  "\x2d\x46\x59\xcd\x47\xfc\xce\xf6\x39\xe1\x33\x15\x6d\xd5\x6a\x3a"
-  "\xf1\x31\xed\x8b\x22\xd2\x3f\xc3\x6b\x86\xe9\xd3\x8b\x5e\x6e\x7c"
-  "\xc9\x36\x34\xc0\x7d\xc1\x01\x1e\xa8\xf8\xb3\xb4\x3b\x26\x1a\x74"
-  "\x45\xa8\xe4\xa5\x64\x9c\xa9\x40\xac\xa1\x60\x0e\xf7\xc2\x26\x8e"
-  "\xd2\x2f\xba\xcb\xe7\x25\xda\xef\xe7\xe5\x3f\x82\x0d\xe5\x59\x86"
-  "\x3d\xb9\x82\x3e\xc4\x81\x30\x73\x9c\x5d\xdd\x78\x92\x99\xda\x89"
-  "\xf6\xc0\x3e\x19\xfb\x65\x77\x66\x79\x59\x5b\x56\x88\xd5\x53\xd9"
-  "\x3b\x7e\xa4\xd1\xfd\x76\x5f\xf8\x7c\xe4\x8b\xd8\xc3\xbc\xa2\x40"
-  "\xc4\x54\x73\x0b\xff\x69\x88\xd7\xce\xcb\x2d\x56\xfe\x16\xf8\x11"
-  "\x7f\x8a\xb9\x88\x11\x0e\xb8\x93\xe9\x5e\xfe\xf0\x8e\xd2\xc7\xea"
-  "\x93\x9c\xa7\xee\x15\x92\x8e\xbc\xd4\x20\x69\x81\x7b\x05\xff\x39"
-  "\xce\x5a\xb8\x1d\xf4\x6d\xc0\x1b\xed\x1f\xf5\x9c\xc0\xc6\x1d\x4c"
-  "\x3f\x54\x4a\x6b\xc6\xa9\x26\xbd\xa4\x3d\x1d\x8b\x15\xbd\xb1\x08"
-  "\x7a\x4b\x11\x57\xa9\xb4\x39\x7d\xcf\xca\x80\xbe\x6d\x43\x37\x7b"
-  "\xe4\x32\x66\x5d\x1c\xd0\x53\x1e\xf7\x9f\xe2\xb2\xe1\x7b\x21\x80"
-  "\x98\x2a\xfa\x97\xe8\xfd\xeb\x2b\x9b\xf4\x41\xb1\x8e\x74\x2c\x16"
-  "\xba\xae\x92\x66\xc8\x80\x66\x77\x57\x08\x7c\x8f\x89\xf8\x1e\x1b"
-  "\x5f\x63\x37\x86\xd6\x65\x4d\x0e\xae\xc9\xba\x68\xc7\x6a\x66\x0a"
-  "\xad\xb1\xc7\x3f\x31\xc0\x66\x6b\xf1\x9a\x48\x16\x4e\xe6\x7e\x6b"
-  "\x4c\x65\x0e\x4b\x82\xac\x1c\xa7\xb3\x88\xfd\x47\xdc\x2b\xfa\x97"
-  "\x2d\xf5\x39\x17\x8e\x0d\x17\x22\x19\x19\xf1\xb0\xd0\x96\xd1\xfa"
-  "\x5a\xb6\x9d\xe4\x6e\xf5\x2c\x5e\xfe\x31\x36\xc5\xf1\x00\xd3\xc7"
-  "\x9d\xe5\xae\x13\x2b\x98\x1e\x71\xb5\xf2\x97\x09\x7d\xd4\x84\xb6"
-  "\xac\x20\x73\xe7\x7e\xc4\xf2\x57\x63\x8c\x3a\x5e\xc0\xfa\x09\x9b"
-  "\x58\xca\x6f\x39\xc1\x3a\xde\x34\x07\x98\x1e\x7e\xb1\x5d\x0f\x42"
-  "\xee\xe8\xf8\xd0\x27\xfc\xb6\xbc\x6f\xc5\xd9\x39\xd7\xea\x5b\x91"
-  "\xf6\x69\xc1\x31\x61\x2f\x12\x2f\xcf\xeb\x75\xb4\xe2\xb9\x00\x67"
-  "\x03\x63\x0e\xa6\x3c\x37\x18\x98\x20\x75\x1e\x1d\x6d\x72\xcc\xfc"
-  "\x5e\x29\x27\x75\x8c\xa9\xe3\x53\x4a\x5e\x49\xe1\x88\xd1\x51\x07"
-  "\xbe\x82\x7b\xc4\xde\xae\x88\x6f\x3d\xd7\xc5\x07\xaa\x98\x3c\x0b"
-  "\xf4\xfe\x63\xca\x96\x57\x52\x60\xfb\x42\xf7\x22\x96\x8d\xd0\x9d"
-  "\x6e\x79\x25\x4d\xea\x1b\x5f\xc9\x94\xba\xd3\x57\x1c\x9b\xa6\xc2"
-  "\x46\xfc\xfd\xaa\xfe\xe8\x57\x0a\xe9\xba\xb4\x3f\xc6\x3d\xaa\x1e"
-  "\x40\xae\x35\x7b\x1d\xb6\x2b\x58\x3c\x74\xf6\x19\x21\xe9\xcf\x48"
-  "\xce\xe1\x43\xd5\x7c\x8b\x78\x37\xfd\xa8\x83\x45\x49\xde\xfd\xfd"
-  "\x23\x33\xeb\x98\x8d\xda\x1a\xcb\x8d\xaf\xd8\x84\xbd\x5b\xc9\x2b"
-  "\xc9\xee\x3e\xf8\x1f\x0f\x31\xc9\x1b\x1f\x6a\xe0\xd1\xaf\xd8\x64"
-  "\xfe\x43\xd7\xb7\xf7\x51\x1f\x8c\xbf\xf6\xba\x03\x27\xd5\xb5\xfa"
-  "\x10\xe1\xfd\xaf\xbd\xbc\xe4\x15\xf5\x3c\xf3\xa1\x22\x8d\xae\x4a"
-  "\x1c\x3d\xb4\x56\xc2\x6d\xaf\x43\xc2\xed\x50\x83\xba\x2e\x4d\xc7"
-  "\x3d\xf1\x09\xc9\xd2\x6e\xe1\xd0\x0a\x8d\x77\xf1\xa8\x79\xf0\x0d"
-  "\xdd\xa7\x49\x5a\x7b\x88\xe4\x9f\xf7\x13\xd5\xf7\xc9\x48\xa3\xfe"
-  "\x11\x5d\x7e\xbf\x05\xfd\x1a\x8b\xb6\x0a\x58\xe4\xb1\x28\xea\x9f"
-  "\x05\xf6\xc2\x90\xef\xdc\xbe\xb9\x2e\xb7\x18\x83\xce\x6b\xc4\xf9"
-  "\x43\xaa\x07\xb1\x02\x40\x37\xa9\x4c\x03\xca\x0b\xb7\xff\x83\x58"
-  "\xad\x2d\xa8\x0f\xef\x78\x09\xf5\x57\x2f\x60\x25\xf4\xab\x18\xd7"
-  "\x1e\x07\x74\x25\x67\x09\x66\xb0\x9d\xea\x9c\x0d\x98\x48\x98\x75"
-  "\xc6\xab\xf2\x90\x3a\x0e\x9d\xd1\x23\xe1\x21\x9f\x15\x23\xd1\x86"
-  "\xd5\xb0\xa1\xe9\x9c\xad\xc2\x4f\xf5\x9d\xfb\xc1\x31\x01\x2f\xf1"
-  "\xee\x83\x1d\x11\xdf\x4e\x1b\xce\x4b\xed\x86\xcd\x23\xf6\xa3\xa1"
-  "\xf3\x97\xf8\xfa\x41\x4b\xc4\x77\x2d\x19\x9f\xa6\x30\xc4\x5d\xdb"
-  "\xf4\xa4\x88\x45\x92\xec\x77\x7e\x70\x38\x0c\x6f\x59\xce\x28\x75"
-  "\x5c\xa1\xd5\xe1\x61\x1f\xd4\x69\xed\xa4\x7b\x87\x1c\x93\x4e\x5b"
-  "\x78\x4c\x3e\x48\xd1\xbe\x83\xdc\x4c\x63\xd4\x87\xb8\x3e\x63\xf8"
-  "\x3b\xd5\xb9\x13\x88\x06\x07\xe7\xba\x04\x3e\xb2\xce\x1a\xd8\x29"
-  "\x13\x0e\x59\x24\x0e\x75\xe6\xc9\xb5\xb0\x53\xe8\x2b\xb0\x6f\x23"
-  "\xfd\x5f\x77\x56\x51\xb9\x7b\xd4\x36\xef\x52\xdb\xb0\x8b\xda\x50"
-  "\x37\xe6\xb9\x96\xe1\x73\x6b\x9d\xad\x11\x67\xf5\x92\x24\x6c\x3f"
-  "\xb4\xf2\x01\x5e\x8d\xb3\x05\x3c\x87\xd7\x54\xd0\xf8\x14\x9c\x65"
-  "\x97\xc2\x17\x4a\xbe\x83\x7f\xdc\xee\x20\xb9\xc7\xd8\x9c\x4b\xb4"
-  "\x21\x2f\xff\x2c\x9b\x04\x5b\x13\xd0\x16\xe8\x12\x78\x34\xa5\x6f"
-  "\x69\xce\x0b\x9f\x27\xfa\x5d\x12\xce\xfd\x91\x3c\x8e\x98\x97\x55"
-  "\x18\x6b\xd8\x1f\xf7\xb0\xdf\xd1\x1c\x6e\xae\xa2\x77\xd9\xe5\x42"
-  "\x26\x6b\xee\x0c\x19\x5b\x0d\x05\x27\xd9\x44\x11\x97\x22\x37\xc0"
-  "\x6c\x0f\xe2\xdc\xc9\x87\xeb\xa9\xcc\x4e\x4a\x8f\x13\xe9\x81\x00"
-  "\xce\x8e\x77\xd2\xbb\x38\x7a\xf7\x32\x5d\x15\x2a\x23\xb7\x82\xda"
-  "\x9d\x7f\x92\x5d\x41\x6d\xe9\xa5\x7a\x3a\xa9\x9d\x3d\x05\x0f\xb1"
-  "\x29\xed\x8e\x5e\xf0\xd4\x54\x9e\x87\xa9\xfe\x15\x3a\x8f\xb2\xdf"
-  "\x5d\x47\xfd\xca\x85\x6c\x89\xb3\x7a\xe5\x74\xcd\x0f\xb1\xb8\xfc"
-  "\x8d\xb4\xa6\x6d\xa4\xfa\x29\x3f\xca\x81\x4f\x05\xd9\x16\xea\x1b"
-  "\xf4\x12\x54\xee\xc6\x3e\xde\x43\x65\xf7\xb6\xf5\x51\x79\xb9\x5d"
-  "\xa2\x4c\x0f\xfa\x48\xe5\xaa\x36\x4a\x36\xb9\xbf\xfc\xbb\x44\x6d"
-  "\x9f\xd4\xc3\x3e\x9c\x8f\x7e\x8e\xee\xb7\xf4\x77\x0b\x47\xfa\xfa"
-  "\xf8\x7d\x02\xfc\x26\x52\xfa\x52\xcd\x2f\x07\xdd\xd3\x7c\xef\x6c"
-  "\x14\x63\x14\xe1\x23\xa5\x22\xc2\x47\x4a\x81\x97\x1f\x41\x5b\x1c"
-  "\x22\x06\xd7\xef\x48\x1e\x6a\x35\x48\xdf\x9f\xbf\x17\xf3\x94\xfa"
-  "\x8c\x78\xed\x66\xa9\x3b\xfc\x9d\x4a\xb3\xf7\x56\xa5\x86\x82\x66"
-  "\x0f\xd5\x49\xf3\xb7\x2a\xfc\xfc\xbb\x03\x38\x9b\x48\xf9\x42\xd2"
-  "\x87\xda\xef\xf6\x8d\xcc\x2f\xde\x17\x9e\xf7\x9c\x72\xde\xb3\xcd"
-  "\x47\xe3\x39\xd6\x7e\x70\xf9\x54\xa1\x47\x48\x8e\x2b\x62\x8e\x82"
-  "\xe3\x2c\x8a\xe0\x7c\x0c\x6d\x6b\xef\x15\x67\x64\xcc\xdc\x99\xcc"
-  "\xdc\xbd\x41\xc9\xaf\xd0\x3a\x71\x34\x91\xf2\x1c\x67\x53\x60\x5f"
-  "\x0d\xdf\xa8\x94\xff\x84\xf4\x87\xda\xf5\xd4\xe2\xb5\x31\x4c\xf9"
-  "\xb7\xf4\x8b\xb8\xfe\x87\x58\x13\x8c\xcf\x0e\x7a\xe0\x53\x54\x97"
-  "\xbf\x8d\x25\x60\x0c\x69\x2c\xbb\x11\x13\x94\xbe\xe9\xfb\xc5\x60"
-  "\xef\x04\x77\xf0\x23\xe6\x20\xdc\x3a\xc1\xba\x6a\x0c\x79\x24\xef"
-  "\xf7\x30\x0b\xc9\xdc\xc1\xfd\xc1\xd9\x4c\x3b\xd7\x5b\x37\x59\x9e"
-  "\x8f\xac\xa3\x39\xbb\xc6\xca\x03\x7e\xe7\xef\x89\xff\x79\xa5\x50"
-  "\x3b\xb7\x57\x26\xfd\x9d\x1a\xa8\xfe\x25\x7a\xf5\x0c\xb3\x84\x6d"
-  "\xd7\xf5\xf2\x7c\xd4\xe4\xaf\xf8\x9d\x5d\xf6\x30\x4f\xd7\xb5\x57"
-  "\xd5\xc3\xda\xe5\x1c\xeb\xda\xbb\x9f\xb8\xe8\xcd\x72\x5f\x3d\x9e"
-  "\xf2\x2e\x1a\xde\x57\x17\x32\x6a\xd7\x5e\x1a\x43\xbb\xe4\xf7\x5a"
-  "\xed\x19\x21\xa3\xba\xae\x20\xfd\x45\x2f\xbe\xa5\xef\xcc\x32\x6e"
-  "\x43\x57\x55\x18\xd7\xba\xd2\x41\x47\xa8\x4f\x24\x97\xff\xbe\x15"
-  "\xfd\x02\x4c\x28\x9f\x81\x9e\x3b\xf6\xef\x1a\xc3\xaf\xaf\xf1\xa5"
-  "\x86\x20\x7c\x6f\x95\xf8\x03\x84\x4f\x27\x69\x0c\xbe\x04\x3f\x26"
-  "\x6e\xaa\xa7\xad\x7e\x90\xb5\x59\xfb\x59\xfb\x52\x9c\xe5\x22\x9e"
-  "\xf9\xc1\xbf\xb2\x6e\xdb\xe8\x34\x4c\x21\xde\x94\xf8\xb7\x64\x94"
-  "\x85\x79\x02\xfb\x28\x37\x49\x1a\xed\x5e\xc4\x22\x65\xa2\x8c\x36"
-  "\xa5\x97\xb5\xe5\x12\xef\x5e\x66\xb1\xb6\xd7\x7f\xc4\xda\xad\x1f"
-  "\x88\x7a\xc0\x67\xb8\x56\xf7\x5f\xa8\x6c\xc2\xb1\x97\xd2\xd4\xb2"
-  "\xfb\xa8\xec\xf8\x31\xcb\x2e\xf1\xa7\x8c\xb3\xec\xcf\xdf\xee\x12"
-  "\x7f\xf2\x78\xca\x2e\xa8\xe1\x21\xa2\x2d\xb1\x44\x3f\x6c\xf0\xab"
-  "\x84\xb3\x61\xa1\x01\xf8\x20\x98\xce\xa5\xcd\xe9\x47\x5b\xc0\x63"
-  "\x8b\xbd\xc4\x2d\xcd\x09\xe2\xdc\xd8\x29\x26\x7c\xd6\xb8\x83\xc7"
-  "\x18\x74\x40\x7e\xe7\x47\xd9\x61\xfe\x7b\x78\x0f\x85\xf8\x9f\x8f"
-  "\x6a\xa4\x5d\x61\xb3\xaa\xcf\xff\xe8\x7b\x28\x67\x74\x3e\xfb\x9d"
-  "\x64\x69\x9f\xfa\xd1\xfb\x9a\xbc\xde\x1f\xfd\x8e\x56\x96\xed\xfc"
-  "\xbd\x75\x2d\x08\xf8\xb2\xdc\x6c\x2d\x9e\xb8\x3c\x54\x18\xc3\xee"
-  "\x5e\x76\xff\xb2\xe5\x39\xcb\x96\xda\x16\xad\x5d\xbd\xf2\xba\x55"
-  "\x0f\x3c\x60\xbb\x73\xd9\x9a\x35\x4b\xfe\x6d\x59\x0c\x5b\xb4\x7a"
-  "\xc9\xca\x35\xcb\xe1\x0c\xde\x66\x9b\x7f\x63\x46\xd6\xaa\xec\xeb"
-  "\x6e\x99\x9f\x7c\xde\x39\x43\x9c\x31\x3c\x0c\xbe\x8e\xe8\xed\x14"
-  "\xa2\xbd\x17\xc3\xff\x84\x79\x3d\x77\x3d\x42\x32\x05\xe1\xdf\x09"
-  "\xec\x21\xd1\xbc\x3d\x02\x7e\x93\xf8\x8f\x4e\xf8\x1e\xab\x7d\x92"
-  "\x77\xf4\xb0\x93\xdf\x22\x5e\xa5\x0b\x7e\xc6\x48\xd6\x3a\x4c\x72"
-  "\x9e\x57\xc6\xbc\x3d\x39\x8d\xf2\x1c\x78\x94\xd2\xbc\xd1\xad\xf6"
-  "\xca\x3f\x33\x03\xad\x3f\xc4\xeb\xfe\x91\xe6\xfe\x24\x5e\x36\x85"
-  "\x1f\xe0\x7f\xb5\x32\xd5\xdf\x9f\xde\xed\x09\x60\xaf\xd9\x98\x1a"
-  "\x2c\xe0\xa0\xa7\x72\x6e\xfd\xf1\x98\x84\xcb\x2b\x29\xd2\x6e\xb7"
-  "\x2f\x04\xbe\x78\x93\x88\x21\xf0\x47\x9a\x93\x1d\x59\x61\x3a\x7d"
-  "\x2c\x49\xe5\x47\xba\x08\xee\xeb\x8e\xd2\xb3\x3c\x63\x7f\xd8\x36"
-  "\xd2\xbe\x80\x84\x28\x76\x3c\x4b\xfe\xf0\xcd\xf1\x6c\xf9\xc3\x7d"
-  "\xe4\x8f\x16\x14\xf1\x3b\x3f\xfd\xef\xfd\x69\xf5\x7f\xe1\x32\xba"
-  "\xff\xc6\xef\x73\xd4\x2f\xfa\xfd\xdf\xd8\xff\xbf\xab\x8c\xbe\x0b"
-  "\xfd\x80\x6f\x84\x5b\x87\x1f\xfd\x33\x33\x12\x7e\x56\x93\x8c\x6d"
-  "\x28\xf8\x13\xb3\xe6\x05\x79\x77\xc1\x0f\x59\x42\xfe\x71\x86\x98"
-  "\xb0\xbd\xd9\xb9\xbc\x3b\x7f\x00\xb2\xd8\xb1\xdf\x12\xfe\x36\x55"
-  "\x1c\x65\xa6\xf2\xa3\xcc\xd2\x9e\x2d\x7d\xcf\x42\xf7\x89\x33\x0d"
-  "\x6e\x7a\x6e\xcd\x09\xb0\x83\xde\x4f\xb1\xc7\xe1\x6a\xcf\x24\xba"
-  "\x73\x98\x31\xe0\xaf\x29\x93\xc5\xd7\x4d\xe1\xfb\xb8\xb3\x8c\x64"
-  "\xf7\x32\xd4\xdb\xf9\xbc\x92\x32\xe1\xf9\x0d\x2d\x13\x10\x3f\xf7"
-  "\x28\xfb\xf3\x53\x2a\x6e\x5e\x27\xcf\xec\x1c\xbb\x4e\xd5\xe7\x77"
-  "\x12\xef\x4b\x6b\xd3\xb1\x67\xe4\x7a\x7e\x6c\xbd\xaa\xc3\xc0\xbd"
-  "\xf0\x0b\x4b\xfd\x68\x42\x0c\x6d\x94\xf9\x9c\xd2\x24\x62\x68\x3f"
-  "\xbf\x21\x65\x42\xde\x12\xa6\x6f\xf7\x9c\x10\xbb\x61\xd8\x77\xa1"
-  "\x79\x87\xfd\x9f\xc6\x1d\x53\x78\x15\xb5\xaf\xac\x7e\x0a\x2f\xa1"
-  "\x36\xed\xf6\x3b\xff\x12\xef\x61\x7f\x30\xaa\x3a\x56\x17\xcd\x8b"
-  "\x3d\xe5\x94\x27\x75\x2d\x9b\x5e\x4e\xf9\x2a\x28\x1f\x78\x37\xd9"
-  "\xbe\xbf\xc6\x12\x0c\xf6\x52\x9d\x1d\xb6\xfb\xf0\xec\x11\x3a\x30"
-  "\xd4\x4d\xfd\xb0\x1d\x65\x1e\xa1\x17\x41\x1d\x5a\xbd\x54\x3e\xd1"
-  "\xbf\x3f\xb8\x54\x7d\x77\x95\x2c\xe7\x2f\xaa\x3c\xd4\xdc\x50\x19"
-  "\x8e\x71\xde\x50\xbe\x81\xd6\x74\x92\xa9\xa9\x8e\x6a\xaa\xc3\x65"
-  "\x2e\x62\xdc\x8c\x73\x75\x87\x83\xc4\xef\x29\xaa\xfd\x97\xe7\x27"
-  "\xea\xb7\x82\x07\x11\x7c\x07\xc9\xfa\x52\x26\x25\xde\x23\x8b\xe8"
-  "\x04\xf1\x1b\xc2\x16\x99\x78\x0d\xa4\x53\x1d\xd5\xf0\xfb\x47\xb2"
-  "\xc2\x5e\x5a\xb7\x1b\xc1\x27\xdc\x77\xf6\x76\x26\x62\x01\x12\xaf"
-  "\xb0\x26\x97\x07\x64\x6c\x00\x8f\x4d\xe3\x15\x80\x1f\xe0\x0f\xca"
-  "\xef\x63\x86\x21\x1a\x63\xc2\x91\x16\xe2\x3d\x2e\x3e\xc1\x3c\x8b"
-  "\xd5\xb1\x69\x11\x3c\x81\x1a\x13\x49\xd2\x70\xcf\x72\x5a\xdb\x4d"
-  "\x54\x47\x8b\x87\x9d\x14\xba\x33\x49\x83\x3c\xb9\xda\x3a\x2f\xe3"
-  "\xfa\x79\x16\x73\xa2\x75\x04\xb7\xbd\x49\x99\x3a\xe2\x43\xff\xe2"
-  "\xa2\xb1\xd8\x8b\xbc\x38\x37\x4e\xf9\x77\xd3\x9a\x9f\xa4\x8e\xc9"
-  "\xe1\xf2\x1c\xf0\x00\x9e\x64\xb4\x83\xbe\x69\x25\x58\x53\x5d\x47"
-  "\x3d\x2a\x1d\xeb\x94\xfc\xcb\xd1\x77\x35\xd8\xd3\x58\x6f\x0e\xc3"
-  "\xdf\xe3\x8b\x84\x3f\xc1\x62\xb3\x1c\x83\xa3\x6b\x23\xc6\x8e\xf8"
-  "\xf5\xa3\x0b\xa1\x7b\xa3\xfa\xf6\x49\xbd\xc1\x91\xeb\xe0\xe3\x87"
-  "\x70\x66\x1f\xc1\x62\x1f\xe5\x6b\x02\x6d\xde\xf4\x67\xa6\xc6\xb7"
-  "\x3f\xfa\x75\xc9\x9f\x1e\xe9\x94\x31\xa0\x8f\xa8\x31\xa0\x3d\xb3"
-  "\x64\xfc\xe7\x23\x4f\xc9\xf8\xcf\x47\x76\x44\xc6\xb4\x0f\xc7\xb3"
-  "\x3f\x52\xa6\xd9\xfb\x03\x07\x30\xf6\xd4\xc7\x59\x52\x36\x3b\x52"
-  "\x06\xfd\x8a\xf8\x6e\x28\x0b\x6d\x3c\x8c\xf9\xa9\xbd\x47\x8c\x7b"
-  "\x4a\x67\x11\xb0\x99\xa5\x8e\x49\x93\x8c\x7b\x71\xf4\x3a\xd9\xb6"
-  "\xa3\x46\x7a\x36\x52\x1b\x84\x7c\x87\x78\xf7\x95\xf8\x26\x3f\xfc"
-  "\x0d\xe6\x0f\xe1\xb2\x99\xbe\xb9\x9a\xae\x5c\xcb\xbb\x73\x10\x79"
-  "\x8e\xec\x79\x62\x10\xfa\x95\x23\x07\xfa\x87\xec\x7a\xaa\x37\x40"
-  "\xf5\xea\x81\x1b\xc0\x0b\xad\x8c\x4a\x09\xa3\x3d\x34\x7e\x02\xbf"
-  "\xf6\x07\x9b\x08\xee\x47\x49\xfe\x6f\x4b\x93\xbc\xdd\x91\x3d\x6a"
-  "\xfb\x5c\xd2\xbf\xed\x47\x87\x11\x6f\x50\xfa\x9b\x39\x5a\x3d\xbc"
-  "\x57\x38\xcc\x63\x1e\xd9\x03\xdc\xa3\xb2\x5a\x55\x9c\x30\x53\xbe"
-  "\x7d\xc3\x38\x24\xce\x09\x1f\x9d\x03\x3e\x53\x6d\x3f\x70\xef\xeb"
-  "\x12\x76\x9e\xc3\xc0\x01\xe2\xe1\xed\x72\x9c\x3d\xb3\xc0\xa7\x4a"
-  "\x3c\xfc\x2b\xd3\xca\x90\x67\x8d\x8f\x94\x29\x54\x86\x86\x2b\x91"
-  "\xb4\x81\xf2\x26\x11\x4f\x3a\x8c\x37\x1a\x2d\x90\x65\x76\xab\x71"
-  "\x2f\xfc\x01\x1a\x1b\xf8\x64\x74\x81\x6f\x97\x78\xd9\x3d\x7b\xbf"
-  "\x2f\x28\x62\x60\x53\xbb\x88\x26\xfc\x75\x6b\x7f\x4c\x87\x31\x8c"
-  "\xdb\x7f\xdd\xac\xe1\x76\xc4\xb8\x0a\xdc\xde\x2c\xe8\xd1\x5f\x49"
-  "\xfe\xfd\xda\x42\x0d\xf7\x31\xcf\x11\x8b\xbe\x32\x47\xc6\xa9\x87"
-  "\x0e\x44\xcc\xfb\x40\x9f\x90\x2f\x30\x9e\xed\xb9\xdd\xc2\xaf\x25"
-  "\xe2\xd4\xb7\xfb\x8e\x41\x6e\x3c\x81\xf9\xaf\xcd\x71\x8c\x0d\xd5"
-  "\x85\x78\x09\x1d\x9b\x89\x06\x62\x0e\xfa\xa8\x4d\x88\xff\x08\xbf"
-  "\x1d\x07\x16\xa7\x88\x18\xf6\xfb\x33\x31\x6e\xdd\x89\x9a\x7d\x71"
-  "\xa5\xa4\x01\x26\x15\x5f\x44\x1b\xcf\x83\xab\x59\xc2\xb5\x3b\x7d"
-  "\xe4\xfc\x3e\x12\xc0\xfc\x8e\x84\x2b\x60\x0a\xd8\x52\x5e\xea\xff"
-  "\x1f\x96\x6a\x70\x8d\x80\xe9\x59\x15\x1f\x55\xda\xda\x3d\x2a\x6d"
-  "\x85\x7f\x50\x6a\x57\xd3\x26\xf4\x85\xd6\x14\xd4\x2f\xfc\x6c\xab"
-  "\x72\xcf\x01\x2f\x70\xaa\xbb\xd7\xc3\x32\x98\x46\xc7\x08\x57\x84"
-  "\xcf\x25\x8c\x95\x46\x3b\xa0\x43\x90\x6d\x3f\x16\xaf\x8d\x07\xda"
-  "\x1d\x49\x13\x68\x8d\x11\x7b\x31\xe1\x3e\x1f\xbb\x8d\xbe\x9b\x0c"
-  "\xda\x16\xe6\xaf\x8e\x2d\x1a\xd9\xf7\x63\x73\xd0\x77\xe0\x84\x23"
-  "\x07\x7a\x04\xb9\x96\x79\xd8\x9f\x5b\x46\xd2\xab\x3f\xff\x56\xee"
-  "\x11\x4a\x7e\x0c\xf4\xde\x71\x9f\xcc\x8f\xf5\x8d\xf2\xbb\xc4\x5a"
-  "\x27\xd7\x43\xe8\x37\x90\xb6\x57\x85\xc1\x61\xca\x7f\x00\x67\x16"
-  "\xe1\x93\xe2\xa2\xc3\x52\x0e\x24\x1a\xbd\x8f\xd6\x0e\x17\xe5\xcb"
-  "\x6e\x27\x19\x20\x38\x91\xb1\x3a\x95\xdf\x04\x9d\xe0\xeb\xd2\x2f"
-  "\x5a\xd7\xcb\xa2\x1d\xb7\xf0\xbf\xf6\xb0\x9e\x87\x69\x1e\x05\xb0"
-  "\x97\x4f\x65\xdb\x7a\xd8\xf1\xef\x51\xbd\xf1\xea\xd5\x4a\xd7\x6f"
-  "\xd2\xf5\x32\xba\x5e\x49\xd7\xcb\xe9\x8a\xb3\xa7\x8a\x9a\x3f\xb9"
-  "\x87\xf5\x7e\x4a\xe9\x37\xaa\x57\x6a\x63\x4f\x16\x5d\xd3\x1e\x05"
-  "\x5f\x79\x9f\x48\x7f\x1b\xcf\x74\x7d\x59\xed\x77\xab\x9c\xdb\x3d"
-  "\x5b\xa9\x9c\x5c\xe4\xc3\xba\x46\x69\x0e\xca\xb3\x1e\x65\xe3\x2c"
-  "\x31\xdd\x5f\x17\xc1\x9f\x52\x39\x1f\xff\x80\xae\xb3\xe8\x3a\x8d"
-  "\xae\xd9\xf4\xfd\x11\x94\x0b\x5f\xb7\x61\x7a\xe1\x99\xb5\x34\x57"
-  "\x8e\x27\x8d\x75\x23\xe6\xbb\x46\x0f\x80\x4f\x23\xf2\x2d\x96\xf9"
-  "\xa4\xec\xfa\xb1\x45\x1b\xbb\xa0\xc4\xdb\x03\x41\x1a\x3b\x2a\xff"
-  "\x5b\xf8\x9e\xae\xf3\xd4\x6b\x8a\x7a\xbd\x4d\xbd\x7e\x47\xbd\xce"
-  "\x57\xaf\x0b\x3c\xac\xc7\xa3\xf2\x26\x04\xb3\x1e\x0f\x60\x42\x73"
-  "\x77\x91\xac\xb7\x37\x1e\xb2\x35\xd1\xff\xaf\xf7\x23\x96\x82\xf3"
-  "\xe3\x12\x4d\x57\x07\x1d\xef\x90\xf3\x23\x7f\xad\xb0\x9b\xf8\xb8"
-  "\x21\x4c\x0b\x0f\x06\x4c\xba\x14\x46\xbc\xd3\xc4\x3a\x3d\xf1\x0d"
-  "\xa2\x9c\x8f\x03\x7a\x75\xff\x11\x3e\x97\x11\x23\x22\x23\x68\x94"
-  "\x67\xe1\x62\xcd\x25\x98\xaf\x42\x8f\x09\xdf\x4a\xd1\x07\x83\x84"
-  "\x87\x46\x92\x29\xb4\xf9\x3b\x0b\xf2\x92\xea\x23\x6b\x8a\xdf\xd9"
-  "\x6b\x0a\xcb\xf8\x1f\xef\x93\xfb\x39\x97\x10\x7d\xea\x4d\x8c\x48"
-  "\xcf\x45\x9b\x09\xd6\x5d\xd4\x9f\x59\x47\x59\xef\x42\xba\xde\xd0"
-  "\x2d\xfb\x9c\xac\xf5\x59\x1d\x2b\x87\x06\xf3\x6e\xd6\xd3\x4b\xf4"
-  "\x70\x35\xf0\xfb\xe8\x30\x5d\xee\x11\xfb\xba\x2a\xfe\xd0\x38\xf7"
-  "\x6c\xc3\x78\x47\xd0\x93\xa4\x30\x9d\xee\xdd\x3d\x72\x5c\x3c\xbb"
-  "\x83\x92\x5f\xe8\xa2\x79\x09\x1c\x70\x9c\x37\x2f\xe7\x60\x5e\xaa"
-  "\xdf\x76\x8f\xa4\xf1\xc7\xe6\x80\xc6\xab\x6d\x24\xbc\xed\x49\xc3"
-  "\xd8\x78\x58\xef\x01\x75\x4d\xea\xa2\x35\xf2\xeb\x94\xae\xea\x45"
-  "\x65\xba\x5a\x17\xe1\x5f\x0f\xfc\x01\x5e\xae\xa5\xab\xf8\x8d\x72"
-  "\x80\x27\x97\x69\xe9\x6a\xf9\x84\xa7\x3d\x36\xcc\x1f\x2d\x5d\xe2"
-  "\xe4\x5f\x73\x41\x6f\xf0\x2d\xfa\x03\x9e\xd9\x75\xdf\x01\x6a\xf7"
-  "\xf1\x5d\xc4\x5f\x08\x1e\x70\xd3\x06\x66\x5a\x57\xc3\x62\xe5\xdc"
-  "\x3c\xfe\xb6\xf6\xad\xd4\x75\x1e\x6f\xd2\x68\x54\xa5\xa0\x67\xdd"
-  "\x49\x23\x69\x65\xdf\x04\xee\x34\x07\x83\xc6\x83\xbe\xb6\xe0\x2c"
-  "\x41\x73\x69\xde\xd7\xd1\x77\x5e\x0f\x2b\xab\x51\xd7\x92\x56\xa9"
-  "\x47\x3e\x71\x75\x5b\x83\xa4\x5d\xb2\xec\x13\xc3\xf4\x2f\x82\x0f"
-  "\x11\xb4\x1e\x75\xa1\x2c\x5a\x57\x2c\xbe\x82\xf4\x8b\x24\xfd\x3e"
-  "\x31\xdf\xc3\x62\x0e\x6b\xb4\x15\xeb\x93\x59\xc7\x1c\x15\xf7\xc9"
-  "\xf5\x49\x81\xfe\xcb\xe1\x13\x7e\x84\xda\x1d\x7d\x0c\xeb\x26\xfc"
-  "\xbc\x66\xac\x8f\x81\xaf\x97\xf4\x1e\xf6\x09\xe2\xed\xed\x52\xe1"
-  "\x48\xf3\xe7\x93\x36\x75\x1c\x0e\x53\xfd\xbb\x40\xcb\x37\xe5\x48"
-  "\x3f\xe5\xd0\xfd\x08\x3f\xf8\xe0\x51\xad\x3c\x70\xa0\x0e\x73\xe4"
-  "\xc4\x81\x08\x7d\x56\x83\x9c\x17\xc7\x5f\x15\x31\x15\x4a\x0e\xaa"
-  "\x71\xc6\x3f\x59\x22\xd3\x3f\x51\xf7\x5a\x0f\xaa\x7e\xbb\x3e\x49"
-  "\x8e\xb2\xc6\xaf\x96\x71\x67\xfe\x38\x59\xf2\x1f\x9f\xc4\x9f\xe7"
-  "\x17\x4a\x4f\x69\xf6\xb0\xcf\xcc\xe3\xea\x3e\xf7\x27\x11\xfb\x9f"
-  "\x9f\x20\x06\xb7\x81\xca\xda\x48\xe9\xc3\xfb\x9f\x72\xad\xf1\xd8"
-  "\x25\x6f\x70\x30\x70\x51\x51\x0a\x23\xda\x3c\xb1\xd6\xa9\xcd\xdf"
-  "\x4f\xf6\xca\xf6\xc8\xf9\x8b\x3e\x03\x1f\x30\x87\x83\xf0\xc5\x43"
-  "\x73\x18\x73\x99\xee\x83\x41\x6d\xee\x4a\xfe\x2e\x49\xcc\x5d\x31"
-  "\x6f\x3f\x39\x10\xd1\x8e\x3c\x15\x57\x0f\xf7\xdf\x6f\x35\xd1\x3b"
-  "\x8f\x87\x7d\x94\x20\xdf\x9d\xa8\x52\xdb\xe1\xa3\xf7\x75\xae\xfc"
-  "\xb7\x30\xf6\x45\x72\x4e\x9c\x28\x04\xde\xb9\x09\x57\x68\xbd\xa8"
-  "\x91\x31\xe6\xfb\x12\x34\x5c\xa1\x39\xb5\x94\x70\xea\xd9\xea\x29"
-  "\xbc\x86\xc6\x04\xf6\x98\x2b\xe8\x19\xf3\x75\xa9\xbc\xea\x2c\xb8"
-  "\xaa\x38\x5a\x43\xdf\xd2\xfa\x1f\xa3\x8d\xc9\x61\x5f\xb4\xdf\x21"
-  "\x70\x22\x1f\xb6\x31\xc9\x62\x3f\x12\x38\x01\x7c\x10\xfb\x92\x84"
-  "\x1b\xe6\xa2\xdb\x19\xf0\x42\x9c\xe7\xa7\x67\xb4\x09\x78\x41\x65"
-  "\xed\xd2\x7c\x54\x7a\x58\xdf\x02\x09\xfb\xbe\xa6\x48\x1b\x41\x2a"
-  "\xdb\x76\xc0\x46\xf2\x4e\xc9\x5e\x47\xf6\x95\xec\x12\xc4\x08\x87"
-  "\x2f\x3a\xc4\x5c\xc7\x37\xd8\xd3\x91\x74\xee\x92\x7f\xa1\x6f\x7d"
-  "\x61\x78\x79\x84\x5f\x81\xfd\x8b\x85\x0e\xf2\x4b\x7e\xe7\x49\xcb"
-  "\x48\x5a\xf1\xc7\x6e\xc1\x0f\xd2\xba\x7a\x55\x3c\xb3\x11\xfe\xd1"
-  "\x1a\x71\x72\x96\xc6\xc7\xce\x8c\xc7\xde\xf0\x1f\x21\x5f\x40\x86"
-  "\xed\xa0\xfb\x3c\xac\xaf\x63\xe8\x8a\x67\x41\xc7\x83\xb9\x0e\x9d"
-  "\x11\xf4\x57\xf0\x29\xdf\xc3\xbc\x6f\xb7\xc1\xd7\xc6\xaa\xcf\xfa"
-  "\x25\xcd\xcf\xe5\x67\xe1\xfb\xc5\xb6\x9a\x7d\xe9\x28\xf3\x22\x16"
-  "\x70\x57\xc1\xa7\xd0\xcd\x9c\x3c\xcf\xff\xe1\x29\x93\xfa\xb3\xd1"
-  "\x6f\x73\xf8\x77\x3a\x5e\xbd\xaf\xba\xf0\xef\x74\x92\xcc\x7b\x9a"
-  "\x68\xde\xe9\xf9\x2a\xac\x7e\xea\x77\x9e\xb2\x69\xb0\x02\x2d\x00"
-  "\x6d\x84\x4d\x00\x74\x4d\xba\x20\x83\x6f\x0f\x1a\x2f\x6a\xf7\xa6"
-  "\x6b\xef\x76\x6d\x80\x2c\x7a\x4a\xd8\x34\xc1\x8f\xe6\xf8\xec\x4f"
-  "\x4e\x89\x3d\x40\xe9\x9b\xef\x54\x3c\xd5\xfd\x1f\x95\xa7\x98\xc1"
-  "\xb1\x9a\x4d\x83\xde\xdb\x1c\xe2\x2e\xc8\xae\x6a\x5c\xf3\x8e\x13"
-  "\xec\xf4\x25\xd9\x1b\x99\x9e\xde\x4f\xa7\x7b\x2d\xbe\xe6\x61\xfa"
-  "\xc6\x12\x15\x60\xf1\xe0\x7d\xe6\x6d\x64\xd3\xa9\xfd\x1e\x6d\xac"
-  "\xc0\x1f\x40\xff\xa6\xea\x10\xd0\xd6\x2b\xf1\x1d\x7c\x2d\x7b\x04"
-  "\xdc\x54\x9a\x73\x0a\xfa\xe6\x53\xad\x51\x3e\x66\x91\xeb\xc7\x69"
-  "\x5a\xff\xfe\xa8\xf2\x83\xa7\x7a\x69\x0e\x74\x46\xb4\xf3\x0f\xe1"
-  "\xfb\x29\x97\xe1\x7b\xb3\x0f\xbc\xd7\x58\xf0\x39\xfd\xb0\x06\x1f"
-  "\xd8\xa6\x92\x3c\xef\x10\xe3\x1d\xe4\x7d\xd4\xb6\x56\xc7\x06\x66"
-  "\x3c\xc1\xbc\x0f\x23\x66\x01\xcd\x9b\x16\xa9\x97\xf7\x2e\xd3\xe4"
-  "\x6b\xd9\x6e\xef\xf5\xe6\xa2\x28\x06\x7d\x7a\x46\xc8\x26\xf6\xfc"
-  "\xf8\x69\xab\xd0\xa1\xbb\x83\x73\x98\x2b\xff\x26\xe4\xb9\x52\x5d"
-  "\x83\x0e\xf7\x17\x58\xd9\x7e\xeb\x1c\x9a\xcf\xa7\xfb\x68\xce\x1c"
-  "\x1e\xbf\xdd\xd4\xe9\x3e\x49\x37\xe4\x39\x42\x3c\xe3\xcc\x1f\xc1"
-  "\xb3\x55\xee\x73\x9f\xfe\x2d\xd6\x04\xc8\xf8\xb4\x1e\x1c\xc0\xba"
-  "\xeb\x77\x7a\x87\xf9\x7f\xa2\xf7\x44\x9f\x4e\xab\xfb\x2e\xd8\x5b"
-  "\x3c\xdd\x04\x5f\x0b\xaa\xed\x2b\xf2\x9b\xa4\xee\xdf\x5b\x36\xcc"
-  "\x37\x53\x3e\x7c\x27\x6d\x9b\x4e\x57\x65\x84\xa0\x13\x38\x5d\x85"
-  "\xbe\x4a\xdc\x9c\x42\x63\xeb\xdd\x17\x9e\xc7\xa7\x04\x2f\xb1\xbf"
-  "\x2f\x72\x9e\x7a\x0f\x87\xe5\xcd\x93\x85\xd7\x55\x33\xdb\x68\xf3"
-  "\xd2\x11\xc7\x2c\x9f\x18\xd9\xf7\x2b\x2b\x79\x43\x95\x5e\xb9\x75"
-  "\x53\x05\x33\xe9\xca\x08\x8c\x98\x77\x39\x99\x97\xf4\xb0\x4f\x7f"
-  "\x68\x36\x5d\x9a\x36\x2f\x7b\x12\xcf\xb7\x32\x7d\xf9\x99\x49\xc6"
-  "\x2b\x03\x97\x36\xf0\xa8\x6b\xef\xbe\x33\x1b\x7b\x7b\x55\xec\xe3"
-  "\x15\x2c\x6a\x5e\x88\xea\x36\x31\x87\x87\xf5\x67\xe1\x6c\xe6\x7e"
-  "\x13\x78\x8a\x7e\xd8\xce\xdc\x9a\x57\xc7\x8c\x79\xdd\xbc\xb7\xec"
-  "\x81\x09\x46\x5a\x47\x2d\x44\xff\x4b\x2e\x32\x5d\xda\x30\x44\x65"
-  "\xbc\x99\x29\xbe\x6b\x1c\x7f\xdb\x1c\x53\xa8\x6d\xe7\xc6\xd7\x36"
-  "\xdf\xee\x70\xdb\x7c\xbb\xff\xc1\x6d\xb3\x84\xdb\x96\x45\x6d\x3b"
-  "\xb3\x75\x7c\x6d\x3b\xdb\x1b\x6e\xdb\xd9\xde\xcf\xd9\xb6\x3d\xe3"
-  "\x6f\x5b\xee\xa5\x3d\xac\xff\xfa\xf1\xb5\xcd\x6f\x0f\xb7\xcd\x6f"
-  "\xff\x7b\xda\x96\x5f\xc7\x8f\xb5\x27\xc8\x78\xa4\xa0\xfb\x3d\xcc"
-  "\xf7\xf5\x8d\x09\x68\x17\x9b\x4c\xed\x3a\x5e\x50\xc7\xff\x2a\x79"
-  "\x96\xfe\x67\xe5\x5a\xd7\x4f\xeb\xdf\xc9\x74\x89\xc7\x3e\x21\xf3"
-  "\x2a\x51\x53\x77\x73\x27\x0f\xce\xf0\xc1\xde\x29\x08\x7f\x04\xf0"
-  "\xdd\x9b\xfc\xfc\x40\x40\xcf\x63\x5a\x53\x76\x9e\x31\xb0\xe7\x07"
-  "\xbc\xc4\xb7\xf4\x7b\x34\xff\x82\xda\xb7\xe6\x9a\x0b\xd1\x27\xdf"
-  "\x25\xf3\xb2\x98\x19\xf4\x09\x57\xc4\x9e\xa9\xcc\x9f\x64\x9c\xf7"
-  "\x29\xf8\x01\x5f\x92\x76\x3e\x4b\x2b\x2b\xb5\x77\x12\x37\xe7\xb1"
-  "\x28\x9c\x11\x13\x7e\xcb\xac\x5e\x96\x98\xc7\x26\xa4\xe6\x52\xf9"
-  "\x01\x96\x69\xce\xa5\xb2\x09\x1e\x92\x27\xf7\x3d\x1c\xb5\x82\x99"
-  "\xaa\xa9\x6c\x5c\xe7\x59\x0b\xf8\xa6\x6d\xcc\x80\xb3\x64\x38\x13"
-  "\x26\xcf\x83\x4d\x34\x52\x3d\xd5\x5a\x3d\x7f\x03\x7e\x71\x12\x7e"
-  "\x67\xd7\x86\xe1\x77\xf6\x9a\x30\xfc\x7c\x27\x25\xfc\x7c\xdd\x61"
-  "\xf8\x9d\xed\x1c\x1f\xfc\xce\xda\xc2\xf0\x93\xdf\x5e\x18\x7e\x67"
-  "\xef\x19\x1b\x7e\x67\x57\x84\xe1\x27\xcb\x1a\x03\x7e\x13\x47\x87"
-  "\xdf\xd9\x17\x3e\x1f\xfc\xce\x76\x7e\x4e\xf8\xc5\x4a\xf8\x0d\xbc"
-  "\x1c\x86\xdf\xc0\xf2\x30\xfc\x06\xae\x93\xf0\x1b\x48\x0c\xc3\xcf"
-  "\x1f\x3f\x3e\xf8\x0d\x64\x86\xe1\x27\xbf\xbd\x30\xfc\x06\xb6\x8e"
-  "\x0d\xbf\x81\x3d\x61\xf8\xc9\xb2\xc6\x07\xbf\x81\x4f\x09\x6e\x16"
-  "\x15\x7e\x96\xb1\xe1\xe7\x8f\xff\x9c\xf0\x33\x4b\xf8\xf9\xcf\x86"
-  "\xe1\xe7\x7f\x26\x0c\x3f\xff\x43\x12\x7e\xfe\xa5\x61\xf8\x05\x16"
-  "\x8d\x0f\x7e\xfe\x86\x30\xfc\xe4\xb7\x17\x86\x9f\xff\xc3\xb1\xe1"
-  "\xe7\xef\x0b\xc3\x4f\x96\x35\x06\xfc\x26\x8d\x0e\xbf\xc0\xf5\x9f"
-  "\x0f\x7e\x81\x45\x17\x82\xdf\xf8\x78\x8f\x40\x16\x1b\xc3\x06\x6f"
-  "\x9c\xe5\x8c\xed\x77\x0d\xb1\x9c\xce\x31\xbd\xe2\x0c\x34\xd6\x2b"
-  "\x13\x8d\xd8\xaf\xa5\x7b\xe8\xae\xe6\x1e\x65\x81\x50\xbd\x32\xc1"
-  "\xc8\x9d\xaf\x95\x28\xce\xdf\x2e\xe0\x45\x13\x0d\x4a\xd1\x24\x03"
-  "\xce\xaf\x8e\x56\x96\xb4\xf5\x3b\xf7\xc3\xa8\xcb\xd8\x15\x38\xd7"
-  "\xb1\x89\xf8\x37\xdc\xfb\x9d\xe7\xb2\x88\x17\xf9\x8c\x9f\xfd\xa5"
-  "\xcb\xd7\x2c\xf9\xd1\x8a\x65\xb6\xd5\xcb\x96\xae\x5d\xb9\x74\xc9"
-  "\xca\x6c\xdb\x92\xfb\x7f\xbc\x66\xa4\xaf\x63\x11\x7b\x73\x33\xc6"
-  "\xef\xdc\x9e\x61\x5f\x03\x4e\x9e\x0b\xff\x52\x8e\x2f\xb3\xe8\x13"
-  "\xec\x5c\x9f\xf0\x11\x1d\xd3\xba\x87\x0f\xa5\x6f\x4f\xb9\x8a\xbf"
-  "\x21\xfc\x66\x0d\x65\x6d\x27\x39\xab\x10\xfe\x05\xd4\x3d\x86\xc2"
-  "\x1e\x36\x74\x96\x47\x77\xec\x86\x5d\x86\xb4\x39\x1f\x14\xbe\x18"
-  "\xe0\x77\x80\x1b\x9b\xbb\x94\x92\x8e\xdd\x7c\x4b\x47\x03\x60\xd0"
-  "\x0e\x9f\x45\x39\x51\xd3\x8f\xb2\xd0\x2e\x1e\xdd\xdc\x45\x65\x69"
-  "\xfb\x52\x90\xcb\x7d\x29\x1b\xf8\x5f\x50\x9e\xca\x7b\x23\xfe\xa1"
-  "\x4b\xf2\x83\x83\x45\xe6\x22\x5b\x14\xf2\xc2\x77\x18\x7c\x6a\x69"
-  "\xb1\x45\xd0\x6e\xe4\x25\xfe\x7c\x2e\x7d\x3f\x77\xa7\x88\x1d\xa2"
-  "\x96\x21\xdb\xf4\x25\x6a\x53\x93\xe8\x4b\x49\xf3\xe6\xfe\x47\xd2"
-  "\xb7\xa3\x1c\x09\xd7\xd0\x16\xaa\x7b\x33\xca\x80\x4f\x1f\x7c\xab"
-  "\x7e\x33\x8d\xbe\x91\xbe\x4b\x36\x5d\xbe\x5d\x96\x11\x7a\x58\x6b"
-  "\x17\xf1\xd4\x31\xf4\xfc\x83\x88\x3a\x2e\xa2\xe7\x6f\x45\xbc\x37"
-  "\xd1\xf3\xd5\xc4\x87\x5e\xac\xbe\x8f\xa5\x67\xc4\x86\x35\x89\x7e"
-  "\x55\x14\xaa\xf6\x9c\xc1\x3e\x4a\xb3\xa8\x79\x2e\x3e\xc1\x82\x88"
-  "\x45\x3c\x59\x2d\x63\x32\x3d\xbf\x0c\x19\x52\x7d\x1f\x4f\xcf\xdb"
-  "\xa0\xdf\x57\xdf\x5f\x42\xcf\x1b\xe9\xf9\xab\xea\x7b\xe2\xf3\x87"
-  "\xa4\xaf\x2d\x63\x33\x62\xe0\xe5\x12\xec\x4b\x44\x2c\xf1\xe8\xe6"
-  "\x0e\x4a\x2b\x24\xf9\xb5\x00\xe3\x88\x7e\xba\x36\xc0\xcf\xc1\x50"
-  "\x1b\xce\x7a\xc8\xb1\xea\xd8\x2d\xfd\x44\xe8\xd3\x29\x1d\x7a\x9c"
-  "\xa8\x38\x11\x8f\xa0\xa3\x04\xf7\xd4\xd6\x6f\x01\x86\x6a\x5d\x24"
-  "\x23\x0d\xf9\xd4\x71\x26\xd8\xc1\xff\x24\x2b\x44\xb9\xf2\x9c\xc3"
-  "\x90\x7a\xce\x21\x68\xfa\x62\x67\x92\x83\x26\xd1\x0f\xc2\x3d\xe8"
-  "\x40\xbc\xd1\xcd\x2b\xc4\x39\x7c\xc2\x3f\x0d\x0f\x80\x03\x5c\x7f"
-  "\x2e\x5b\xea\x57\x82\xd9\x61\x3f\xf4\x43\x9d\xaa\x8e\x85\x49\x19"
-  "\x20\x18\x61\xff\x33\x24\xe6\x7e\xc4\xbb\x3d\x11\xef\xd2\xb5\x77"
-  "\xd2\x46\x2d\xd8\x12\xf1\x6e\xc1\x79\xef\xba\x23\xde\xcd\x1e\x59"
-  "\x66\x88\x45\xbc\xb3\x8f\xfc\x2e\x94\x10\xf1\x2e\xfe\xbc\x77\xb3"
-  "\x23\xde\x19\xd4\x77\x51\x94\x9e\x16\xf6\xd9\x35\xe8\x53\xd3\x89"
-  "\x8e\x87\xb2\x22\xd2\xbb\xd5\x74\xd4\x5f\xe8\x61\xcf\x1e\x56\xd3"
-  "\x05\x0e\x13\x8e\x7c\x45\xad\xa3\x2e\x5c\xc7\xa0\x6a\x73\xd5\xbc"
-  "\x42\x8e\xd5\x60\x92\x59\x67\x9b\x04\x7c\x31\x17\x15\x22\x6e\x45"
-  "\x95\xf4\x4f\x23\xe7\x98\x88\xd3\x46\x57\xfa\x2e\x69\x2c\xba\x37"
-  "\xba\x0d\x9f\x62\xd1\xce\x3d\x85\x4a\x9a\x1d\x4a\x49\x00\xbe\x44"
-  "\xa7\xc3\x8f\x4d\x41\x1f\xfc\x00\xf8\x98\x9b\x0d\x32\x77\xb6\xbf"
-  "\x10\x71\xa2\xda\x65\x7c\xa8\x38\xec\xbf\xc1\xee\x1e\xbe\x78\xda"
-  "\x1d\x27\x45\x8c\xa8\x75\x7d\x2c\xc1\x71\x0b\xef\xee\x61\x4a\x76"
-  "\x68\x4b\xb3\x43\x3d\xcb\xbb\x4d\x9e\x47\x53\x64\x7f\x20\xb3\xf6"
-  "\x09\xfd\xaf\xb1\x87\x71\x83\xc8\xc3\xd3\xb7\xc9\x3e\x72\x01\xd7"
-  "\x9d\x4e\x2d\xe6\x8f\xb2\x47\x8b\x8d\xe6\x61\xdc\x78\x36\xfa\x03"
-  "\xb4\xd7\x35\xd2\xe6\x50\xf9\x03\xca\x44\xdb\x3d\x4c\xc9\x43\xd9"
-  "\x94\xa7\x7b\xd8\xe6\x90\xd2\xd7\x05\xd9\x54\x6a\x57\x8f\x56\xbe"
-  "\xdf\xc9\x0d\x1e\x16\x12\x72\x24\xca\x3c\xbb\xe5\x5c\x32\xa5\x59"
-  "\x3d\xfa\x9f\x2e\x94\x36\x8b\x9c\xf8\x9f\x57\x0f\x5f\xe8\xbc\x17"
-  "\xcd\x47\x17\x2f\xe9\x68\xa1\x39\xdc\x24\xcf\x7d\x76\xb8\xa4\xac"
-  "\xce\x1f\x86\x5d\x04\x62\xde\x41\x76\x96\x74\x84\xcb\xfd\x0f\x4a"
-  "\xa3\x31\x02\xbd\x15\xfb\x40\xe3\x9b\x73\x5c\xc0\xa4\xf2\x0c\x33"
-  "\x56\xac\xd6\x7c\xe6\xf2\xd6\x08\x5f\xe2\xaa\x2d\x32\x3f\xdb\x9e"
-  "\x2b\xf6\x84\x44\x1b\xcf\x6f\x03\xda\x4b\x65\x39\xc6\x5c\x1b\x8d"
-  "\x1d\x4d\x42\x3f\x59\xda\x9a\x26\xec\xbb\x74\xec\xe6\x28\xeb\x65"
-  "\x8f\xf8\x8b\xd9\x6c\x4d\xf6\x46\x9e\x8a\x41\xf8\x6f\xea\x70\x0d"
-  "\xf7\x73\x75\x10\x79\x33\x85\xfe\x5c\xc7\xb2\x89\x2e\x35\xa1\x0d"
-  "\x6a\x7a\x76\x7b\x30\x80\x33\x95\x63\xd9\x54\x1a\x85\x5f\x8e\xd2"
-  "\x8e\x26\xd8\x72\xcf\x0c\xa8\x6d\xd6\xe9\xb2\x61\x43\x8c\x36\x0b"
-  "\xd8\xea\x74\xcb\x35\x38\x96\x9f\xa1\xb2\xf3\x3f\x62\xdd\x3a\xf6"
-  "\x29\xec\x4e\x60\x13\x5f\xb9\x41\xb5\x85\xa2\x34\x91\x6f\x70\x38"
-  "\x8f\xb0\xeb\xc7\x59\x40\xd0\xc7\x7a\x11\xc7\x83\xfa\x40\x63\x21"
-  "\xce\x95\xeb\x74\xdf\x14\x7a\xcc\xd5\x4c\xf6\x1b\x76\x66\x3a\x9d"
-  "\xb0\x53\xf6\x17\xeb\x92\x3d\x3a\x9d\x38\x3f\xe4\x51\xd3\x2a\x51"
-  "\x77\xce\x20\x3b\xa5\xd3\x5d\x8c\xb8\x7b\x04\x8f\x16\xf8\x24\x6a"
-  "\xf7\xd1\x3c\xc9\x1d\x04\x2e\xb4\x20\x66\x13\xe5\xb7\x48\x7a\x4f"
-  "\x30\xd7\x31\x1f\xea\x07\x6c\x69\xec\xbc\x04\xd3\x2d\x54\x76\x99"
-  "\x06\x53\xc4\xca\xa5\x3c\xbb\xc7\x1a\x17\xc0\x28\x44\x6d\xc6\x19"
-  "\x7a\xd7\xd4\x8f\xa8\x7d\xfa\x7b\x94\x98\x8e\x26\xd8\x34\x52\x5b"
-  "\xcf\x49\x5a\x21\xc7\x4e\xcc\x25\x9d\xfe\x3a\xaa\x63\x2f\xf6\x00"
-  "\xe1\x63\x57\xc4\x43\xd6\xe9\x3a\x55\xf8\x09\x1f\xee\x55\x39\x12"
-  "\x0e\x6a\xfe\x12\xa9\x67\xb9\xec\x37\xfe\x62\x7d\x78\xff\x87\xd2"
-  "\x85\xce\x6c\x8a\x3c\xeb\x4d\xef\x52\x22\xda\xec\x13\x67\x92\xa8"
-  "\x2c\xea\x6b\x2f\xea\x2a\x87\xcf\x18\xe0\xc5\x89\x08\xfc\xd7\xe9"
-  "\xde\x45\x3b\x61\x33\x17\x8a\x6e\x4d\xe3\x5b\x5a\x17\x01\xce\x54"
-  "\x36\xa3\xb9\xd0\x34\x46\xcc\x45\x11\xaf\x85\xea\x6b\xd4\x78\x20"
-  "\xe2\x7d\xa6\x9f\xd0\xe9\x8f\xc8\xbe\x4a\x7f\x69\x38\xdf\x3b\x9c"
-  "\x56\x6e\x0e\xd0\x7c\xdf\xab\xf2\x2c\x7b\xc7\xf4\xb5\x35\x83\x25"
-  "\xe3\x1c\xbb\x1a\x5f\xd4\xc7\x4d\xe6\x1a\xf8\xef\x84\x2f\x32\xd7"
-  "\x86\x1b\xa8\xbd\x51\x8f\x3d\x31\x45\x9c\xb5\xf2\xb9\x66\x9c\x81"
-  "\xed\x4c\x5f\x4f\x9e\xf0\x4f\x61\x4c\xcd\x0d\x72\x71\x1e\x1b\xe7"
-  "\xb4\x62\xcd\xd0\x8d\xf7\x09\x3f\xd6\x28\xf3\x8b\xfa\xa2\xd4\x45"
-  "\x2d\x56\x79\x13\x9c\xdd\xbd\xf4\x84\x2e\x4a\xe8\x26\xe9\x7e\xca"
-  "\x09\x9d\xe1\x55\x19\xaf\x4b\xfa\x55\x56\x6d\x00\x27\xca\x33\x9c"
-  "\x5e\x26\x7c\x36\xea\x0c\xd7\xd9\xae\x65\xac\x4f\x67\xb8\x5e\xf8"
-  "\x36\x2d\x69\x3e\xa0\xc2\xe0\x40\xa5\x6c\x97\x39\x23\x57\x2f\xda"
-  "\x88\xf6\x8d\xb3\x6d\x01\x75\xed\x9a\xe8\x2f\x36\xcc\xd1\xce\x7e"
-  "\x8a\xfe\xab\x3e\x4f\x5d\x5f\x3e\x83\x36\x3c\xa3\xae\x57\x1a\xef"
-  "\xd9\xf2\xf7\xd7\x6d\xc8\x56\xcb\xac\x13\x7e\x5f\x09\x2e\x54\x6e"
-  "\x1d\xb5\xe3\x80\xb6\x86\xaa\x76\xeb\x49\x62\x6d\x2f\x36\x1c\x1e"
-  "\x5e\x3f\x55\x18\x8e\x88\x51\xb4\x6a\x55\xb6\x8d\x18\x70\xc7\x92"
-  "\xec\xfb\xb3\x6c\xcb\x56\xaf\x5e\xb5\xda\x06\x07\x07\x91\x73\x4c"
-  "\xd8\xa6\x14\x1b\xbc\x6a\xac\x99\xdd\xc3\xb1\x66\x8a\x27\xcc\x8e"
-  "\x8c\x89\xe4\xd1\x4d\x18\xd3\xa7\xd9\xf8\xfa\x38\x61\xcc\x58\xc9"
-  "\x55\x7a\xa5\x91\x7e\x4d\xf4\x73\xd1\xaf\x05\x72\x4b\x46\x80\xa5"
-  "\xd0\xfa\x28\xce\x69\x6a\x3e\xb1\x95\xe2\x09\x16\xec\x4f\x1f\xd5"
-  "\x4d\x78\xb9\x5e\x31\x30\x71\x9e\xdd\xa9\xc0\xc6\x03\x3e\x7a\x9b"
-  "\xe8\xe7\xa2\x5f\x0b\xfd\xa4\xcf\x97\xb7\xc4\xb9\xbf\xc6\xc8\x77"
-  "\xd8\x33\xe6\xce\x1a\xf8\xfa\xed\xe0\x45\x06\xb1\xc7\xa0\x3c\x2e"
-  "\xf3\x9d\xd7\x06\x3d\xc9\xb1\xb3\xd5\x7c\x62\x3d\x8d\x2b\x62\xb6"
-  "\x51\xf2\x45\x71\xe7\xb9\x6a\x35\x9f\xf0\x6b\xab\xf5\x07\xfe\xa3"
-  "\x29\xbf\x96\xcf\xc0\x8b\xf5\x3e\x35\x9f\xe0\x2b\x15\xa7\x7e\xb4"
-  "\x7a\x27\x70\xe7\x41\xad\x5e\x4b\x64\x79\x11\x79\x26\x2a\x4e\x6f"
-  "\x00\x79\x94\x22\x83\xe0\xdf\x78\xf1\x84\x74\xca\x3f\xaa\xdf\xbd"
-  "\xf1\x8d\xd3\x24\x76\xfe\x38\x39\xee\x5f\xbe\xec\xa6\xe5\x2b\x73"
-  "\x10\x95\x24\x7b\xd5\xda\x6c\x5c\x57\x2e\xf9\xb1\xb8\xac\xca\x78"
-  "\xe0\x7e\x79\x93\xbd\x22\x19\x37\x2b\x08\xdf\x70\x5d\xba\xd6\x81"
-  "\xcb\xfd\xab\xf0\x98\x9b\x95\xb4\xf6\x7e\x2d\x8c\x6a\x24\x1e\xda"
-  "\xfd\xc5\x93\x68\xfd\x98\x20\xf6\xe2\xe8\x7e\x2f\xc9\xb3\x22\xee"
-  "\x8d\xb9\xc8\xc3\xde\xb6\x07\x99\x26\xc3\xca\xf1\x9f\xc4\x84\x8f"
-  "\x3c\xdd\xa4\x37\xeb\x95\x49\x46\x73\x91\xe3\x7e\x73\x70\xf9\x32"
-  "\xa2\xb3\x8d\xf4\xad\xd7\xc3\x8a\xd5\xb3\xb9\xcd\x9d\xc2\x1f\x5c"
-  "\xf1\xa4\x14\xcd\xee\x4f\x29\x69\x2e\x81\x4f\x66\x61\x07\xf4\xb8"
-  "\xf0\x81\xb0\x97\x9e\x3b\xe8\x19\x71\x16\xe2\xe9\xb9\x8a\x9e\xbb"
-  "\xe8\xd9\x4a\xcf\x09\x4a\xc9\x2b\x36\x9c\x95\xa2\x67\x1b\x3d\x27"
-  "\xfa\x8b\x8d\x69\xda\xbc\x88\x84\x8d\x1a\xe4\xe7\xa6\x51\xe5\xdd"
-  "\x91\x3e\x45\x68\x6e\x19\xab\xb5\x58\x8a\x22\x6e\x62\xb1\x71\x78"
-  "\xff\x4f\xc6\x25\xb1\x2c\x16\xeb\x9a\x58\xdb\xa3\xaf\x8c\xb2\x5e"
-  "\x1e\x23\x78\xef\x62\x63\xab\xb6\x47\x2b\x78\xeb\x62\xe3\xe1\x88"
-  "\x98\x93\x78\xee\x1b\x8e\x39\x29\x79\xd1\xed\x82\x17\xd5\x45\xcf"
-  "\xe2\xc5\xc6\xc5\xc3\x71\x81\x8a\xa3\x47\xec\xff\x7a\xe8\x3d\x64"
-  "\x1a\x4a\x4f\x0a\xaf\x83\x46\x17\xea\x1c\x2d\xbe\x26\x62\x7a\x67"
-  "\xac\x27\xfe\x9b\xae\x2a\x2f\x6e\x13\xb2\x96\x13\x7e\xff\xf8\xee"
-  "\x51\xf5\x06\x57\x88\xbe\xbc\x0a\x7f\x8f\xde\x82\xa5\xba\xab\xea"
-  "\x99\x4e\x3c\x4b\x5f\x5f\xfc\x94\x2e\x5a\x9c\x1f\xd4\xfc\x00\x45"
-  "\x9e\xc9\x1d\xf5\x0c\xc0\x21\xc6\x64\xfc\x8a\x15\xab\xcc\xc1\x25"
-  "\xcb\x24\xef\x16\x73\x99\xa4\x9f\xad\x32\xa6\x96\x2e\xc6\xc0\xef"
-  "\x96\xfe\xf6\x3d\xba\x98\x12\xc4\xf1\x30\xeb\x56\xac\xe2\xf4\xad"
-  "\x39\x77\xc9\x32\x91\x46\xf9\x36\x21\x2e\xb3\x6c\xdf\x71\x77\x42"
-  "\x2f\xe3\x03\x21\x79\xd6\x58\x17\xdd\x7b\xdf\xb4\x42\xd4\x63\x14"
-  "\xbc\xc3\x21\x66\x42\x5c\x26\xb4\xad\x3e\xc2\x4f\x51\x25\xa5\xc1"
-  "\x36\xaa\xff\x6e\x66\x82\xbf\x46\xd9\x96\xe8\x5e\x11\xff\xa6\x38"
-  "\xa6\x50\xf3\xa5\x40\x70\xee\x3d\xbf\x3f\x77\x7f\x5f\xcc\x8a\xab"
-  "\xef\x4f\x4a\xbb\x8d\xee\x92\xd4\x90\x83\x91\xf8\x92\xd0\x1f\xd3"
-  "\x5e\xd3\xff\xf4\xe2\x57\x44\xdc\xac\xe2\x98\x0e\x2a\x47\xee\x0b"
-  "\x6f\xba\xf7\x38\xe8\x89\xf0\xc5\x10\x62\x56\x71\xfe\x49\xf1\x89"
-  "\xd8\x64\x3d\xba\xd8\x6d\xf0\x99\x28\x7c\x11\x15\xc7\x54\x63\xdc"
-  "\x69\xac\xc4\x1a\xaf\x94\x36\x67\x63\x2e\x00\xbf\x94\x2d\x6d\x0b"
-  "\xdc\x16\xf4\xfd\x22\x3b\xd1\xd1\x79\xf4\xfb\x17\x19\x9f\xe0\xde"
-  "\xe3\x5a\x99\xf0\x15\x42\xf8\xd4\x48\x57\x8b\xbf\xf8\xa2\x61\xfc"
-  "\x1f\x3e\x37\xa6\xbb\xe8\x61\xf8\x33\x81\xbf\x06\xc9\xb7\xc6\xfe"
-  "\x44\xf2\x92\x17\xe5\x79\x98\x79\xbe\x9c\xd3\x17\x95\x78\x58\x43"
-  "\x83\x7a\x4f\xf8\x3f\xa3\xee\xbc\x32\xfe\xa4\xe9\x2b\x24\xde\x5f"
-  "\xd4\x44\xf8\x37\x8f\x7e\xff\x42\xf9\x0f\x68\x71\x49\x37\xe9\xc5"
-  "\x19\x9f\x9e\x28\x2b\x4b\xa6\xf4\xc3\x5a\xfa\x04\x5d\x0a\xc1\xe6"
-  "\xa2\x3e\x8d\x86\xf4\xc7\xb4\x2e\xa6\x67\x82\x39\x2b\x54\x9f\xb3"
-  "\xfc\xc5\x26\x93\xf6\x4c\xf7\x56\x8d\xc6\xd0\x3d\xf1\x7f\x3b\x7b"
-  "\xd5\xfb\x64\x0f\xfb\x99\x96\x3e\xc7\xa3\xaf\xa9\xd6\xda\xa9\x38"
-  "\xa3\xcc\xb2\xad\xb1\x0e\x65\x4b\x00\xf1\x8e\x66\x51\x9e\x4c\x9a"
-  "\x2b\xd2\x77\x40\x4e\x5f\x43\xd9\xa0\x65\x11\xe2\xb6\xbb\x1e\x00"
-  "\x0e\xc4\x0a\xff\x61\xe5\x1b\x2c\x69\xe0\xdf\x70\xbe\x59\xc4\xf1"
-  "\x81\xff\xaf\x20\x9b\x28\xfc\x46\x6f\x09\x24\x0b\x7f\xc9\xeb\xec"
-  "\x26\xcd\xf7\x17\xcd\x39\x3b\xd7\x97\x05\xe1\x0f\x4c\xe8\xb9\xfc"
-  "\xf6\x38\xe1\x03\x4c\xf5\xfd\xb5\x23\x87\xc5\xd7\x29\xd2\xf7\x97"
-  "\x38\xfb\x3c\x91\x78\xfd\x9c\xd1\xfd\x7f\x71\xe7\xeb\x01\xcd\xff"
-  "\x17\x62\x3d\xd3\xbd\x9d\x0f\x04\x91\x26\xfc\xf3\xab\x7e\x5f\x0d"
-  "\xa3\xfa\x02\xd3\x13\x0d\xd4\x4b\x5f\x60\xe3\x5b\x3b\x62\xe7\xc8"
-  "\xf1\x8f\xcd\xd3\xe2\xa1\x46\xa4\x55\x11\xfe\x4a\xdd\x88\xee\x22"
-  "\x87\x9a\x46\xf4\x6f\xe7\xa2\x61\x3e\x8b\x68\x17\xf4\x7d\x34\x3f"
-  "\x7d\xbc\x20\x6b\x5b\xe4\x7c\x11\xd6\x00\x0c\xcb\xf0\x04\x5a\x63"
-  "\x27\xd2\x6f\x12\x7e\x0b\x86\xe9\xc2\x00\xef\x52\xe3\xf6\x05\xcd"
-  "\xb9\x51\x3c\x35\x18\x8c\xca\x08\xea\x3a\x45\x6c\xc2\x10\xd3\xa7"
-  "\x86\x82\x38\x53\x6c\x08\x0e\xf0\xce\xd4\x50\x3f\xaf\x7c\x00\xf1"
-  "\xc5\xe0\xcb\x74\x3a\xcf\x08\x55\x89\x58\x7d\x4a\x0e\xef\x00\x8f"
-  "\x1f\x1a\xe0\xad\xa1\x1c\xde\x42\x63\x60\x82\xfc\x00\x5f\x2b\x71"
-  "\xba\x00\x8b\x73\x44\xbd\x71\xd7\xd9\x37\x38\xfc\xac\x20\xee\x8d"
-  "\x52\x1c\x80\xdf\x17\x5d\x46\x30\xaa\xd0\x1d\xec\x16\x3e\xa7\x53"
-  "\x73\xe7\xf2\xd4\xd0\x24\x4e\x74\x32\x4a\xc4\xac\xc9\xe1\x07\x52"
-  "\xd7\xf3\x7e\x11\xcf\x6c\x3d\xf1\xd5\xeb\xfb\x39\xe2\xa3\x51\xd9"
-  "\x2d\x19\xb9\x5f\x46\x3c\xb4\xc1\xd4\x5c\xa5\x20\x23\x57\x47\x6d"
-  "\xf9\x2b\x4f\xcd\xfd\x2b\xb5\x27\x99\xca\xb5\xd0\xf3\x5c\xbe\x53"
-  "\xb4\xb3\x50\xc8\x31\xd4\x47\xc8\xa1\x28\xb3\x89\xda\x88\x40\x42"
-  "\x6f\x64\x04\x5d\x85\x22\xfe\x9a\x1a\x23\x39\x35\x77\x88\xa3\x3e"
-  "\xaa\x6b\x76\xea\x7a\x36\x37\x63\xfd\xf4\x42\x21\x0f\x9e\x82\xcf"
-  "\x1a\x1b\xd5\x5b\x08\x78\x98\x10\xa3\x50\x9c\x59\x2a\x36\xdb\x2f"
-  "\x14\x5b\x6d\x54\xd9\xb9\xb8\x3b\x91\x97\x57\x75\xf2\xe2\x1e\x1f"
-  "\x2f\x7f\x6c\x11\x2f\x69\x83\xee\x86\x78\x90\xe3\x07\xe8\x99\xd2"
-  "\xfb\xaa\x79\xf9\xe3\x8b\x78\xf1\xe9\xa5\x74\xa5\xe7\x33\xb3\x78"
-  "\xf9\x13\xf4\xdc\x1a\xa4\xef\x3a\x78\x71\x1b\xbe\x4b\xe3\xc5\xed"
-  "\x7d\x74\xa5\x67\x77\x37\xe5\xa3\xe7\x8e\xc3\x74\xa5\xe7\xf7\x3b"
-  "\x7b\x74\x66\x7a\xf7\x04\xa5\x9d\x35\xc8\xba\x02\x06\x51\x57\xf1"
-  "\x90\x41\xd6\xa1\x18\x44\x1d\xa5\x3a\x83\xa8\xa3\xd4\x60\x90\x75"
-  "\x1c\x6a\xa5\xfc\x5d\xbc\xb8\x73\x0e\xe5\x4b\xe7\xc5\x1f\xee\xa1"
-  "\x2b\x3d\xff\x3e\x81\xf2\xd1\x73\x57\x19\x5d\xe9\xf9\x0f\xd4\x96"
-  "\x27\xe8\xf9\x8f\x2b\x28\xff\x61\x5e\x7c\xd8\x43\xf9\x16\xf3\xe2"
-  "\x3f\x2f\xa2\x2b\x3d\xff\xa5\x85\xf2\xd1\xf3\x11\x2a\xe7\x71\x7a"
-  "\x3e\xda\x48\xf9\x17\xf3\xd2\x49\x68\x8f\x87\x97\x1a\x51\x6e\x26"
-  "\x2f\x8d\x41\x7e\x7a\xbe\x88\xca\x7b\x9c\x9e\x63\x77\xd1\x95\x9e"
-  "\xcd\x0b\x29\x3f\x3d\x5b\xa8\xaf\x55\xdd\xbc\x74\x72\x03\xe5\x5b"
-  "\xca\x4b\xe3\x29\xfd\x31\x7a\xbe\x24\x40\xf9\xe8\xf9\x52\xe4\xa7"
-  "\xe7\xcb\xd2\x28\x3f\x3d\x4f\x05\x8c\x7a\x79\xe9\xb4\xc5\x94\x2f"
-  "\x8b\x97\x4e\xdf\x47\x57\x7a\xfe\x32\xda\x4f\xcf\x89\x79\x74\xa5"
-  "\xe7\xaf\x10\xac\x9e\xa0\xe7\x6b\xa8\x7d\x55\x7d\xbc\xf4\x6b\x28"
-  "\x7f\x05\x2f\x9d\x01\xf8\xd0\x73\x72\x16\xe5\xa3\xe7\x1b\x08\x1e"
-  "\x8f\xd3\xf3\xd7\x93\x29\xff\x8a\x51\xc7\xb3\x74\xb6\x91\x17\x4d"
-  "\x64\xbc\xf4\x5b\x76\x5e\x34\x89\xae\xb7\x76\xf1\xa2\x09\x76\x5e"
-  "\xfa\xed\xd9\x94\x4e\xd7\x79\x8d\xf4\x9c\xa4\x3e\xd3\x75\x7e\x09"
-  "\x3d\x27\xab\xcf\x74\xbd\x2d\x93\x9e\x67\xa9\xcf\x74\xfd\x4e\x2f"
-  "\x3d\xcf\xe6\xa5\x0b\x5c\xf4\x8c\xeb\x22\x7a\x9e\xa3\x3e\xd3\xf5"
-  "\xf6\xcd\x74\x0d\x7a\xa7\xdd\x5b\xe3\x8d\xcd\x4c\xf3\xc6\x56\xbb"
-  "\xb0\x96\x85\x2a\xaa\x3a\x94\xb8\xc7\xd2\x68\x2d\x99\x58\x70\x96"
-  "\x4d\xea\xd1\x4d\xfe\x19\xf8\x3f\x77\x9e\x47\xc4\x40\x52\xfd\x0b"
-  "\x4d\x3c\xaa\xbb\xf8\x65\x5a\xbf\x67\x23\xc6\x2d\xf5\xd5\xc4\x9d"
-  "\x13\xce\xd0\xb5\x8c\x3b\x2f\x3a\x4a\x7d\xa5\xe7\x8b\x0f\xd1\x95"
-  "\x9e\xbf\x51\x4a\x7d\xa6\xe7\x7b\x6f\xa5\x6b\x99\xbf\x78\x72\xbc"
-  "\x47\x67\x16\x74\x89\x3f\xbd\xb8\xd1\x1c\x2c\x20\x3a\x41\x74\x74"
-  "\x5b\x6d\xa1\x39\x98\xc9\x78\xf9\xd6\x4c\x33\x7c\x94\xef\xb8\xb7"
-  "\x8b\xc7\x65\x8a\x36\x21\x0e\x01\x1f\x4a\xd4\xcb\xba\x2f\xe2\x47"
-  "\x75\x93\xbf\x05\x7d\x24\x8f\xcb\x1d\xeb\xfd\x12\xf1\x7e\x6a\x6d"
-  "\x95\x7c\x6f\x61\xe1\xf7\xff\x82\xf7\x45\x66\xe8\x90\xaf\xb8\x83"
-  "\xe8\xe1\xe4\xdd\xc8\xe3\xd1\x5d\x7c\x80\x3b\xa3\x98\xdb\xd7\xab"
-  "\xf6\x71\x12\xf2\x3d\x83\xef\xc6\xd2\x91\x28\x65\xdb\x9a\xca\x9d"
-  "\xbc\x03\xf2\x20\xd1\x7d\xbd\x2d\x3f\xb1\xe9\xa8\x2e\x3e\x77\x87"
-  "\x90\xf3\x6b\xd3\x71\x7e\xe6\xa8\xee\x4b\x37\x0f\x95\xb6\x55\x21"
-  "\xf6\x38\xbd\x5b\x5f\x10\x20\x39\x3f\xff\x56\x5a\x9f\x44\x7a\xab"
-  "\xb0\xc9\x96\xf7\x4d\xc2\x1e\x47\xde\xef\x12\x3a\x4b\x2a\x0b\xdf"
-  "\x46\xf2\xdf\xa1\xe2\x9b\xd3\x95\xb8\xda\x4c\xb1\x7f\xa4\xfb\xd2"
-  "\xb7\x7e\xab\x78\xf4\xe6\x6c\x36\xc1\xb6\xe1\x0d\x2a\xff\x4b\x25"
-  "\x23\x65\x35\x2d\xaf\x78\xf7\xd0\xeb\x94\xb7\x56\xe8\x55\xbe\x54"
-  "\xa3\xe9\x61\x39\xf5\xe1\x51\xf8\x77\xd6\xb3\x14\xac\x45\x92\xf7"
-  "\x8a\xb7\xc2\x2f\x59\xd0\xb4\x35\x25\x58\x96\x99\x12\x2a\xab\x4d"
-  "\xe7\x15\xb5\x99\x71\x41\x1d\x13\xf6\xec\xba\xf8\x3b\x67\x06\xa0"
-  "\xef\x7a\x0f\x79\x27\x28\x13\xbf\x5d\x36\x23\x97\xe9\x5d\xab\x3f"
-  "\xc2\xf3\x6d\xbc\x78\xa1\xc1\xdd\xd7\xc5\xe0\x67\x91\x9e\xe7\xf3"
-  "\xe2\x7f\x29\x51\x26\x7e\xaf\xaa\x1e\x3c\x63\x2e\xf4\x34\x87\x00"
-  "\x97\x77\x09\xce\xc4\x8f\xc7\x27\x46\xc4\x5a\xef\x28\x27\xd8\x81"
-  "\x9f\xc3\xd9\xe3\x8c\x50\x08\xfe\x61\x4a\x3c\x04\x07\xa9\xeb\x8b"
-  "\x87\x3f\x4d\xa6\xd6\xfb\x43\x25\xa6\x2d\x0f\x1e\x63\xcc\x41\x0b"
-  "\xfc\x6d\x88\xd8\xbd\x38\x5b\x5f\xa9\x60\x7d\x93\x79\x47\xf8\x96"
-  "\xbc\xdf\x91\xb1\xc1\xb1\x6a\x75\x76\xc6\x5a\xc7\x4d\x36\xc4\x9c"
-  "\x5e\xf5\x80\xed\xa1\x65\x0f\xad\x5a\xbd\xfe\x7c\xbe\xcf\x48\xed"
-  "\xda\x47\xb8\x21\xfc\x09\xbd\x4b\xbc\xa4\xd0\xff\xea\xa6\x94\x61"
-  "\xac\xb7\x3d\x29\x7d\x74\x53\x1e\x8f\x87\xfd\xbb\xf0\x09\xa0\xd4"
-  "\xd4\xe6\xf2\xba\x7b\xbb\xb6\xe0\xcc\xf5\x5a\xf0\xeb\x5e\xe6\x66"
-  "\x67\xa8\x6d\x32\xc6\x54\x7b\x90\x78\xdb\x9c\x3c\xee\xca\x39\x03"
-  "\x1c\x4f\xe7\xe5\xd5\x59\x7c\xc7\x62\xdb\xb9\xf2\x4c\xc2\x99\x29"
-  "\x8e\x73\xe5\xd5\xe9\x5a\xfc\x87\x50\x59\x75\x93\x62\xda\xd6\x81"
-  "\xf8\x0f\x43\xdc\xca\xda\x08\x96\x83\x25\x6d\x59\x44\xe3\x97\xee"
-  "\x70\xd2\xba\x43\xbc\xbe\xf0\x2d\xf0\xf4\xe2\xaa\x10\xb7\x1b\x42"
-  "\x4e\x66\xa4\x6b\x1c\x8f\xab\x65\x43\xa6\xad\x69\x78\x8f\xb8\x0f"
-  "\xa1\x21\x3b\xcb\xef\xe4\xca\xbf\x66\x11\xde\x38\x19\x17\x71\xfb"
-  "\xb2\x4e\x32\x4a\x8f\x51\x2a\xaa\x3d\x3d\x0b\x98\x1e\x79\x89\xaf"
-  "\x61\x8b\xe9\x3e\x6f\x09\x8b\xa5\x7c\xe6\xbc\x77\x29\xdd\x6f\x8f"
-  "\x09\x16\xd8\x8d\x83\x05\xf6\x98\x21\x6e\x37\xb9\xbb\x03\x6c\xe8"
-  "\xea\xc5\x0d\xd7\x79\x99\x61\x1b\xf1\x3f\x3b\x14\x9a\x5f\x75\xf7"
-  "\xba\x42\x8f\xd8\x27\x06\x1f\xb1\x1b\x86\x86\xec\xc6\xe0\x3a\xbb"
-  "\x61\x70\x9d\x7d\xe2\x90\xdf\x6e\x74\x2f\xf5\xb2\xf7\xbc\xbf\x64"
-  "\xed\xdd\xbd\x42\x47\x38\x14\x5b\x6b\x1a\x8a\xad\xee\x33\x75\xb3"
-  "\xf8\x19\x0e\x06\x7e\x57\xb7\x9d\x78\x5b\xc2\x09\x53\xf0\xa9\xc5"
-  "\x55\xbc\x7c\x7b\x23\xc1\xf7\x9e\xdb\xae\xe1\xa7\x43\xc5\x09\x89"
-  "\xb6\xdb\x89\x16\x15\x19\x12\x28\x8d\xf0\xc7\x5e\xcd\x8b\x13\x0f"
-  "\x93\x6c\x6d\xa3\x5f\xa2\x47\x8e\x03\xe3\xc5\x53\x89\x46\x1a\x12"
-  "\x90\x57\xe6\xbb\xd2\xee\x11\xd7\x69\xb9\x22\x36\x5e\x71\xfc\xe6"
-  "\x1d\x42\xe6\x9a\x52\xa2\xf1\xcd\x07\x0c\xa3\x9f\xeb\xa6\x3c\x7b"
-  "\x86\x65\x57\x85\xe8\x49\x79\x95\x6b\x74\x3a\xfd\x76\x35\xf6\x0b"
-  "\x15\x82\x5b\x8f\xee\xd2\x69\xf0\x41\xc3\x0b\x16\xa8\xf2\xe2\x14"
-  "\xe1\x0b\x13\x67\xa1\xa1\x53\x90\x69\x97\x0a\xbd\x85\xa2\x4f\x81"
-  "\x9f\xe4\x26\xf8\xfd\x81\x0e\x81\xf0\xba\xc5\xa3\xbb\x14\x3a\xab"
-  "\x09\x24\x77\x35\xd2\xaf\x89\x7e\xae\x27\xa0\x5b\x70\xb2\xdb\x34"
-  "\xbd\xcb\xe8\x6d\xbd\x34\xdd\xc3\x4a\xaa\xc2\xb2\xe7\xa5\x59\xd4"
-  "\x6f\xd7\xb8\x6d\xef\x74\x97\x8e\xb9\xff\x2d\xfc\xcc\x01\xc6\x15"
-  "\x55\xde\x2a\x65\xd8\xb7\x20\xd1\xfd\x4b\x7f\x8b\x38\xe0\xe2\x5d"
-  "\xd9\xd6\xcc\xfc\x4f\x59\x14\xde\x35\xc2\xb6\x80\x9e\x6d\xab\x75"
-  "\xdc\xed\x0b\x30\xfa\xc6\xc0\x13\xee\xed\x6a\x1c\xf0\xea\x31\x2f"
-  "\xda\x29\x8d\xbe\xfd\xb0\x6a\x40\x2d\xb7\xa6\xb6\xb0\xe0\x61\x26"
-  "\xfc\xc1\x23\xfe\x05\xe6\x4b\x55\x3e\xc9\x78\x88\xd5\xb1\x3a\x8a"
-  "\xe8\x95\xf5\x62\xba\x37\x22\x1f\x37\x6d\xcd\x54\xa8\x0c\x9a\x33"
-  "\x2d\x3c\x76\xeb\x02\xa5\xbc\xba\x83\xd6\x87\x2a\x3e\x6d\xf1\x6c"
-  "\x65\x5b\x2d\xc9\x16\x56\xf4\x5f\xc8\x1e\xf0\x2f\x02\xbd\x45\x88"
-  "\xe4\xe7\xf6\xdd\x41\xc6\x6f\x0d\xb2\xb7\xb3\xcf\x32\x6f\x74\xdb"
-  "\x0a\x6f\xec\xb6\x26\x6f\xec\xf6\xc6\x50\xec\xb6\x00\xfd\x82\x8e"
-  "\xd5\xcc\x74\x42\x77\x59\x52\xc8\x29\x7d\x03\xa7\x7e\xca\xfd\xc2"
-  "\xde\xd1\x09\x5f\x5e\xd2\x4f\x91\xf0\x11\xac\xc6\x06\xa1\x32\x13"
-  "\x45\x4c\x10\x92\x09\x42\xeb\x48\x16\x18\xa0\x79\x30\xc0\xac\x5a"
-  "\xbc\x87\x1d\xaa\x1f\xe0\x8a\x9c\xb0\x1c\xa0\xf2\xf8\xf1\xb8\x0f"
-  "\xe9\x7f\x6d\xdf\x01\xbf\x46\xa0\xcd\xf0\x6b\x04\x7e\x7f\x8d\x1d"
-  "\x7e\x03\xc3\x7e\x8d\xfc\x76\x3d\xf1\x98\x1d\xc4\x5f\x0a\x3e\x53"
-  "\xf8\x1a\x14\x36\xdb\xcc\x14\x8a\xdd\x3a\x1b\x34\x2d\x23\xd7\x25"
-  "\x7c\x0d\x82\xd7\xc4\x5a\xe3\x2f\xbe\x2c\x4b\xe3\x1f\x41\x3f\x43"
-  "\x5b\xda\x72\xe9\x97\x4d\xe9\x85\x1e\x5d\xd2\x5e\x8d\xb6\xd2\x7a"
-  "\xea\x08\xc5\x2c\x8a\xf7\xc3\x0e\x7f\x28\x6b\x2e\xf2\x12\x1c\xe1"
-  "\x93\x32\x2a\x34\x94\x35\x87\x7e\x37\xd3\xef\x96\x50\x79\x75\x66"
-  "\xa8\x7c\x7b\x55\xa8\x3c\x33\x9b\x7e\xb9\xf4\xcb\xa3\x5f\x21\xfd"
-  "\x36\xd3\xaf\x84\x97\x67\x96\xd1\x15\xef\xab\xe9\x57\x43\xbf\x3a"
-  "\xfa\x35\xd0\x6f\x57\x68\x5b\xad\x23\xa4\x33\x24\xd0\x2f\x91\x7e"
-  "\xb6\x50\xf9\xb6\x96\x50\xf9\xd6\x14\x71\x36\xb2\x78\xaa\x45\xc3"
-  "\xd3\xd1\xcf\xdd\xfb\x17\x08\x3f\xd6\x13\xfe\xc2\xcd\x88\x17\x99"
-  "\x77\x16\x3e\xb2\x16\xbc\x6d\xf7\x8d\xcf\x9f\xb9\x6e\x6a\xca\x58"
-  "\x78\x8d\xf2\x89\xc6\x0c\x8d\xb3\xbc\x31\xe3\x95\x28\xd6\xda\xdc"
-  "\x60\xc2\x62\x5b\xd0\xc9\x0a\x89\xae\xe9\xda\x33\xbb\x59\xaa\x97"
-  "\x15\xb4\x76\x0f\xb2\x82\xa5\x3c\x24\x68\x40\x1e\x6c\xaa\xcb\x82"
-  "\xc0\xf1\x10\x4f\xb7\x0d\x95\x55\x67\x85\x4c\xdb\xaa\xb8\x69\x5b"
-  "\x8b\xf0\xbb\x45\xb4\x04\xb1\x6f\x86\x65\x50\xe0\x1c\xc9\xa1\x6d"
-  "\x7d\x67\xd9\x23\x4b\xb9\xd2\x46\xa3\x0b\xdf\x5a\x66\x1d\xfb\x99"
-  "\xc0\x3d\x55\x0e\xbd\xe3\x30\x2f\x24\x5c\x8a\x0e\x11\xdc\x14\xc8"
-  "\x9f\x84\x77\x90\x45\x35\xdc\xa3\x35\xdd\xa2\xc5\x0b\xe1\x13\xa7"
-  "\x26\xd2\x3b\x03\xe2\x89\xd4\x91\x1c\x5a\x97\xc3\x12\xeb\xe8\x9d"
-  "\x88\xfd\x46\xed\xbe\xcb\x61\xe6\xca\x8f\xed\xac\xfe\x41\x66\x8c"
-  "\x3d\x29\xe3\x09\x86\x08\xf6\xc3\xfe\xa8\xcb\x32\x9b\xee\x3c\x69"
-  "\x63\x6f\xdb\xff\x44\x6b\x73\x23\xad\x61\x99\x4d\x43\xb4\x7e\x11"
-  "\x2c\x43\xe3\x83\xe5\xe5\x87\xff\xb3\x60\x39\x94\x70\xaf\x4b\xc2"
-  "\x33\x93\x01\x66\xe7\xc3\x13\x30\xde\xd0\x4d\xf0\x24\xb8\xba\x3b"
-  "\x43\x24\x4f\xb2\x25\x1a\x3c\x6b\x09\x9e\x04\x53\x2b\x60\x4a\xf0"
-  "\x10\x30\xe5\x2a\x4c\xeb\x23\x60\x4a\xb4\x4b\xf8\x28\x03\x4c\x15"
-  "\x82\x69\xfd\x18\x30\x1d\x96\xe7\x09\xa6\x3b\x3f\x17\x4c\x77\xff"
-  "\x1d\x30\x9d\x96\x3c\x16\x4c\x83\xe0\x1b\x2a\x32\x1b\x39\xd1\x45"
-  "\x77\xf0\x3d\xe1\x6f\x8f\x78\xbe\x20\xf1\xae\x01\xc5\x54\xdd\x84"
-  "\x38\xb1\xd8\x57\x47\xfc\x9a\x82\x5c\x7e\xa4\x60\x37\x3f\x17\xaa"
-  "\xa8\xb5\x20\x8d\xe8\x5a\xd6\x4c\xd8\xea\x38\x3c\xb4\x76\xf1\xa6"
-  "\xf6\x01\x1f\xad\x67\xb6\xe5\x83\xe0\xa9\x2b\x6a\x53\x15\x9e\xc5"
-  "\x40\x53\xee\xbb\x86\x19\x06\x89\x6e\x38\x72\xd8\xf4\x2a\xa2\x85"
-  "\x83\xe5\xdb\x82\x27\x74\x57\x18\x6e\x73\x28\x9c\x7e\x05\xf0\x1b"
-  "\xa7\x10\xcd\x25\x5a\x2e\xc6\x17\x63\x86\xfd\xba\xb6\xfb\xde\xa2"
-  "\xf2\xae\x38\x7b\x30\x33\xc8\x0a\xb2\x3e\x3b\xbe\x4a\x41\xba\x2d"
-  "\x54\xf6\xb7\xe7\x09\x62\x68\xe5\xf5\x62\x5c\x1b\x99\xbb\x3b\x3c"
-  "\x4f\x14\x95\x46\x63\x2c\x30\x2f\x30\x47\x2a\x23\x68\x33\xd1\x7d"
-  "\xcb\x0e\xd5\x1f\x7b\xc8\x49\xb4\x19\x3e\x7b\x69\x2c\xe1\xa7\x7d"
-  "\xd4\xf9\xf1\x08\xcd\x8f\x0d\x22\x86\x86\x95\xe0\xd1\x38\xe8\x97"
-  "\x63\x88\x31\x73\x07\x5b\xc4\xf8\x55\xa9\x6b\x81\x84\xfb\xb6\x83"
-  "\x9c\xa7\xb3\x10\xfc\x58\x57\xd4\x32\xee\xcf\x8a\x41\x1c\x15\x92"
-  "\xf9\x93\xcd\x4b\x89\x7f\x3a\x4d\x6b\xc5\x4a\xc2\xaf\x53\x2c\x71"
-  "\xe7\x4a\xe2\x89\xfc\x88\xdb\x43\xed\x59\x2f\xe3\x1d\x2a\xc5\x53"
-  "\x4b\xe8\x9d\xf0\x83\xa7\x68\x7e\xf0\xfa\xed\xd0\x43\x84\xf5\x43"
-  "\xab\xec\xfa\x70\x9d\x87\x3c\x21\x63\x68\x81\x38\xc3\xa9\x9b\xfe"
-  "\x5b\xb9\x1f\xfc\x6b\x9c\x0f\x63\x7d\xba\xe9\xd2\x4f\x77\xc9\x6b"
-  "\x89\x8e\x7c\x36\xe9\x84\x6e\xfa\x53\xbc\x74\xbf\xd5\x81\x18\xae"
-  "\xda\xbb\x82\x74\xc0\xc1\x36\xa3\x90\x15\x86\xb6\x84\xb2\x10\xdb"
-  "\x97\x17\x64\x8d\x93\xf6\x4e\x17\xb6\xf8\xa1\x92\x43\xdd\x04\xa7"
-  "\x14\xa5\xf4\x50\x1f\xd1\x94\x64\xfe\x63\xea\xeb\x83\xd4\xd7\x13"
-  "\x04\xd7\x13\xd4\xd7\x75\x6a\x5f\xd5\x58\x46\x0a\xc1\x9f\xde\x8d"
-  "\xbe\x36\x6a\x7d\xfd\x31\xfc\xe2\xbf\xe8\xdd\x78\x92\x7d\x89\x13"
-  "\x3f\xde\xd6\x27\xce\xe1\xf8\xdd\xc1\x3f\x31\xd4\x2b\xd6\xee\xb2"
-  "\xcc\x92\x7b\x08\x1f\x01\x73\xe2\x17\xbc\x3c\xae\xda\xa3\x8d\x03"
-  "\xda\xc3\x87\xb2\x62\xea\x57\x52\x7b\x00\xfb\x53\x2c\x09\xf3\x99"
-  "\x60\x9f\x58\x0f\xf8\x8f\x8c\x27\x1a\x2f\xc6\x60\x22\x8d\xc1\x4a"
-  "\x75\x0c\xb6\xa8\x63\x40\xfc\x32\xad\xc3\x46\x92\x1b\xad\xf5\x4e"
-  "\x39\x06\xe3\x83\x91\xcd\xf3\x0f\x9e\xaf\xf1\x63\xcf\xd7\xc4\x69"
-  "\x83\x52\x46\xd6\xc1\x1f\x1f\xc9\x08\xdf\x57\x86\x68\xde\x56\xa8"
-  "\xf3\x96\x67\xdd\xa2\xcd\xd9\x1e\xdd\x95\xaf\x7e\xbe\x39\xfb\xe5"
-  "\x67\xfe\x1f\x9d\xb3\xf1\xff\xb9\x73\xf6\xaa\x87\x47\xce\xd9\xab"
-  "\x76\x8d\x9c\xb3\x57\xfd\x20\x3c\x67\xd5\x77\xff\x90\x39\x7b\x95"
-  "\xe3\xbf\x67\xce\x5e\xe5\x18\x65\xce\xfa\x3e\xc7\x9c\xb5\x8e\x31"
-  "\x67\xad\xff\x79\x73\x36\xb1\xfa\xbf\x6e\x8d\xfd\xea\x87\x83\xfa"
-  "\x51\xd6\xd8\x47\x22\xd6\xd8\x58\xac\xb1\x57\x67\x8d\x36\x5f\x87"
-  "\xea\x68\xbe\x9a\xd4\xf9\xfa\xaf\xbf\xa1\xf2\xbe\xb2\xe4\xbd\xc3"
-  "\x7f\x7b\xbe\x06\xeb\xc2\xfc\xd3\x98\x73\x36\x0b\x73\x76\x37\x73"
-  "\x7b\xc4\x9c\x5d\xa2\xcd\xd9\x3a\x55\x16\xba\xc0\xbc\x8d\x1f\x6b"
-  "\xde\x22\x36\x0a\xe2\xa2\x5c\x70\xde\xaa\xfc\xd2\xd0\x34\xcc\x5b"
-  "\xd7\xff\xb0\xb5\xf6\xab\xd7\x8c\x9c\xb7\x5f\x5d\x3c\x72\xde\x7e"
-  "\xf5\xe2\xf0\xbc\x55\xdf\xfd\x43\xe6\xed\x57\xed\xff\x3d\xf3\xf6"
-  "\xab\xf6\xff\x7b\xd6\x5a\xfb\xc2\xff\xba\xb5\xf6\x6b\x8f\x89\x79"
-  "\x3b\xd6\x5a\x5b\xa0\xae\xb5\xb1\x58\x6b\xaf\xb9\xfa\xf3\xcd\xdd"
-  "\x6b\xa7\xfd\x3f\x3e\x77\xff\x93\xd7\xdc\x6b\x8f\x8d\x9c\xbb\x5f"
-  "\xb3\x8e\x9c\xbb\xd7\xb6\x85\xe7\xae\xfa\xee\x1f\x32\x77\xaf\xed"
-  "\xfe\xef\x99\xbb\xd7\x76\xff\xdf\xb3\xe6\x26\x8d\x19\xa3\xdc\x76"
-  "\x05\x2b\x3c\xaa\x4b\x5a\xe2\xae\x13\x36\x79\x85\xee\xe0\x4d\x4c"
-  "\xda\x91\x24\x6d\x71\x5b\x67\x33\xa5\xb4\xcd\x03\x7f\xf3\xb0\x67"
-  "\x79\x22\xc2\x5e\x44\xda\xa6\x24\x3d\xa3\xd9\xbb\xec\x54\x7d\xd2"
-  "\x5f\xc8\xde\x85\x97\xb4\xa9\x36\x2d\x49\xdd\x12\x37\xda\x72\xb5"
-  "\x67\xe1\x1b\x4a\x97\xd4\xcb\xb7\xb4\x39\xbc\xd1\x6d\x63\xf9\x91"
-  "\x36\xc6\x15\x71\x0e\xdb\x90\xfe\x2b\x16\xa7\xf4\x97\x32\x56\x25"
-  "\xf6\x61\xae\xb3\xd1\xb7\x62\x2f\xac\x3f\xce\x92\xdc\xef\x4c\x63"
-  "\x94\x36\x4b\x4b\x13\x71\x4a\x9d\x51\x5c\xa1\x77\x44\x43\x10\x7b"
-  "\xda\x08\x5f\x9b\x33\x06\x80\x8b\xd7\xcd\x27\x1a\x21\xec\x3e\xe0"
-  "\x83\x9f\x5f\x7a\xb9\xaf\xfe\x0c\x33\xb4\x6f\x16\xba\x67\xd8\xc9"
-  "\x34\x54\x00\xff\xa3\xae\xad\xe1\x7a\x03\x53\x76\x2c\xb6\xf3\xd8"
-  "\xed\xd2\x16\x97\x70\x45\xb3\x9d\x41\xdc\x1a\x65\xda\xbd\x2d\x9a"
-  "\xbf\x47\x4e\xed\x7b\x3d\xdf\xab\x47\xec\xdb\xfa\xd5\xcc\x42\x3f"
-  "\x13\x2f\xdf\x8e\x76\xb5\x6a\xba\xc4\x31\xed\xaa\x11\x6b\xf1\x72"
-  "\xab\x41\xb5\xd3\xc1\x79\x57\x69\xc3\xac\x27\xca\x44\xe9\xdc\x59"
-  "\x20\x62\xa5\x98\x09\x16\xb0\x85\x25\x3a\xa5\x57\xea\x17\xa7\x6c"
-  "\x9a\xca\xd8\x73\x1b\x7a\xf5\xb0\xdd\x08\xfd\xf4\x72\x9f\x2b\xff"
-  "\x06\x11\xfb\x1c\xfe\x84\x7b\x74\x33\xde\x4d\x3d\x2e\xe3\x2a\xd2"
-  "\x3d\xfc\xaf\xeb\xee\xa4\x67\xec\xe5\x2b\xfd\x56\x03\xf2\x52\x7a"
-  "\x91\x2b\xe7\x23\x66\x76\x08\x7b\x75\xa3\x9a\x37\x0d\x79\x3d\xba"
-  "\x19\xc2\x0e\x99\x9e\x97\x62\xcf\x00\x36\xed\xb0\x45\xe2\x75\x8b"
-  "\xed\x82\x3e\x94\x6d\x67\xca\xb4\xc5\x76\x61\x47\x4a\xfd\xac\xa4"
-  "\x3e\x53\x1e\x13\xec\x6e\xc4\x35\x9f\x59\xaa\x29\x0d\xe5\xd0\xd5"
-  "\xe4\x5a\x09\xdb\x92\x19\x29\x28\x7b\x4c\x7b\x7d\xd3\x76\x5a\x03"
-  "\x0c\x4c\x9e\xa1\xd1\xbd\x7f\x54\x37\x33\xdb\xac\xe3\x9c\xd7\xdd"
-  "\xdb\xb2\x09\x3a\x6e\xd8\x48\x0b\xbb\xef\x99\x77\x52\xf9\x86\x9d"
-  "\x42\x87\x3b\x33\xc9\xa3\xbb\xae\x4b\xf5\x69\x21\x63\x39\xe8\x66"
-  "\x6e\x46\x3d\xf8\x46\xcd\x9f\x20\xf0\x8f\xda\x6c\xcb\x8f\xe2\xf4"
-  "\xfc\x90\xb4\xa3\x36\x2e\xa1\xef\x57\x84\xed\xc7\xc4\x77\x34\x66"
-  "\x33\xa1\xff\x15\x31\x2b\xf0\x3c\xa6\x8d\xb2\x3a\x6e\x6d\x44\xdd"
-  "\x3e\x33\x76\x1a\x8e\x10\x5e\x68\x38\x82\xf6\x3e\x9f\xef\xd1\xcb"
-  "\xfd\x8d\x64\xe1\x37\xb9\x82\xc6\x30\x54\x6b\x85\x3f\x41\xa6\x0c"
-  "\x61\x5c\x60\xeb\x9e\xfc\x36\xc6\xa5\x92\xd6\x02\x99\x77\x66\x6f"
-  "\xb8\xfd\xe2\x5b\x31\x9e\x0a\x8d\x85\xb4\x5d\x4a\xde\x26\xe2\x52"
-  "\x10\xcd\x80\xbd\xf7\x81\x5c\x6a\x17\xf0\x96\x70\xe4\xb9\xd5\x01"
-  "\x7d\x7d\x8e\x4c\x7f\xfd\x4c\x40\x0f\xdb\x0f\xe8\xc2\xcb\x1f\x64"
-  "\x06\xe8\xd4\x51\x26\x4f\xb8\xb7\x65\xa6\x36\x8e\x1b\x68\xec\x72"
-  "\x08\x77\x09\xe6\x95\x04\xbf\xfa\x41\xb1\x5f\xd5\x52\xaf\x30\x93"
-  "\x42\xf9\x3c\xba\xe4\x4e\x2a\xcf\xb2\x63\x0a\xf7\xc2\xc6\x9a\x60"
-  "\xb8\xd6\x5f\x9c\xdc\xa8\xc1\x10\x6d\x82\x8d\x74\xb9\xb0\x95\x4f"
-  "\x4e\x92\x38\x34\x33\xa8\xf5\x79\x2c\x78\x96\x3f\xc7\x12\xca\x67"
-  "\xb0\xd9\x8a\xd1\xbf\x80\x47\x5d\xde\x00\x7d\xf3\x5d\x7d\x8c\xc1"
-  "\xbf\x76\xea\x4f\xfe\xc2\xdd\xde\x10\x53\xa2\xfd\x0b\xb0\x37\x11"
-  "\xda\x74\xed\xe4\xd4\xf5\x04\x2f\x5a\xef\x0b\x02\xcc\xe2\xce\xf7"
-  "\xca\xb8\x36\xec\x53\x16\x5a\x43\x34\x9c\xe8\x3a\xad\xa9\x86\x82"
-  "\x4f\xd9\x65\x80\x97\x12\x5b\x9d\xd5\xa3\xbb\xfe\x27\xf7\x64\xb3"
-  "\xc2\xf1\xd1\xd1\xeb\x85\xff\x0b\xf0\x17\x44\xf3\xf5\x22\xae\xb1"
-  "\x97\xf8\x93\xf2\xea\xac\x71\x96\x53\x33\x16\x8d\x44\xbf\x15\xe8"
-  "\xa1\xd5\x3e\xa7\xa2\xcf\xbe\x00\x83\x2e\xff\xae\x87\xe1\xaf\xf3"
-  "\x2c\x53\xb6\xf8\x17\xa0\xcf\xc4\xeb\xf4\x8e\x5f\xa7\x7f\x43\xfc"
-  "\x85\xea\xe6\x04\x6f\x65\xd3\xe5\x0d\x8a\x69\x5b\x2f\xea\x46\x1b"
-  "\x70\x56\xe6\xae\xb3\x4c\xc0\x1d\xf0\x77\x07\x42\x8c\x47\x47\xb6"
-  "\x21\x38\xde\x36\x8c\xdd\xff\x19\x2c\xa1\xec\x39\x39\xee\xa1\x4d"
-  "\x2a\x0c\xb2\xb0\x47\xb6\xad\xb7\xdd\xe1\x65\x77\xa1\x0d\xde\x93"
-  "\xec\xce\x93\x4c\x8c\xbf\xdb\xde\xc7\x42\x51\xd7\x4e\x86\x4d\x05"
-  "\xc6\x3f\x3f\x48\xe3\x3f\x10\x80\xaf\x0e\xaf\xbb\xf0\x1c\x03\xff"
-  "\x12\xec\xb7\xeb\x3f\x3b\xfe\x37\xfe\xe4\x9e\xdc\xf1\x8e\xff\x8d"
-  "\xff\xa0\xf1\xbf\xf1\x7f\x40\xff\x67\x7d\x81\xfe\xcf\xfa\x07\xf5"
-  "\x7f\xd6\xff\x80\xfe\x7f\xfd\x0b\xf4\xff\xeb\xff\xa0\xfe\x7f\x7d"
-  "\xcc\xfe\xcf\xbb\x4c\xe1\xc2\xd6\x26\xae\xaa\x03\x6b\x80\x5c\xaf"
-  "\xbe\xb1\x11\xb6\x34\xe2\x6c\x94\xfa\xcc\xe4\x59\x29\xe3\x79\xcf"
-  "\xa6\xf3\x9e\x2d\xe7\x3d\xc7\x9f\xf7\x6c\x3d\xef\x39\x41\x7b\xa6"
-  "\x75\x64\xc2\x29\xdd\xd7\x4f\x12\x5f\x4a\x6b\xdf\x37\x4a\xd4\xf7"
-  "\x89\xf0\x65\x43\x6b\x7a\xe2\x58\xf1\xb9\x62\x75\x8c\x0f\xe9\x39"
-  "\x13\x71\xb3\x74\xdf\x08\x0e\x3a\x19\xe7\x51\x53\xed\x88\x7f\xa4"
-  "\x94\x65\x56\xdf\xb5\x1e\xf1\xe2\x03\xc4\xe7\x5b\x27\x52\xd9\x97"
-  "\xa6\x12\x9d\xc6\xb8\xda\x56\xc3\xb6\xe6\x1b\xc7\xd1\xcf\x19\x0e"
-  "\x17\x53\xa2\xae\x15\xb6\x0d\x4a\x79\x66\xb5\x37\xea\xda\xa9\x7c"
-  "\x5b\xad\xa3\xdc\xa9\x18\xdd\x7d\x9d\xac\x42\xaf\xd8\xf2\xf2\x68"
-  "\x7c\xfb\xf6\xb2\x47\xfa\x78\x6f\x5e\x90\x07\xdc\x8b\x5d\xac\xc0"
-  "\x8b\xd8\x09\x2d\xac\xdd\xdb\x29\xe2\x27\x88\x38\x11\xde\xbd\x0c"
-  "\xfc\x4f\x01\xf2\x50\x5a\xbb\x77\x0f\x6b\xa3\x67\xd7\xca\x63\xd4"
-  "\xcf\x7f\xda\xe6\xee\xdb\xc3\x42\x65\x99\x55\x8a\x29\x33\x9b\x9b"
-  "\x32\x73\xdb\xfa\x10\x63\x2f\x33\x0f\x6d\x6d\xa7\x76\xb8\x83\x4d"
-  "\x90\xb3\xf2\x44\xb9\xbe\x0e\x21\x93\x62\xcf\x56\x89\xa5\xfc\xb1"
-  "\x99\xb9\x68\x1f\xda\x36\x2a\xbf\x5b\xf6\x98\x81\xda\x7e\xd3\x3d"
-  "\x76\x03\xc3\x79\x86\xf1\xe1\xc8\x3f\xed\x1b\x93\x8f\x2e\x7b\x6c"
-  "\xb3\x2c\xd7\xf8\x05\xca\x9d\x3d\x26\xfd\xe7\x65\x8f\xab\xed\xb5"
-  "\x7c\x91\x72\x57\x5c\xa0\x5c\xb5\xbd\xb6\x2f\x52\xee\xd8\x31\xa1"
-  "\xcb\x9e\x50\xdb\x9b\xf2\x05\xca\xfd\x66\xc2\x05\xca\x55\xdb\x5b"
-  "\xf8\x45\xca\xcd\xbe\xc0\xb8\x19\xbe\x18\x2e\x7c\xb3\xe5\x42\xb8"
-  "\xf0\xc5\xf0\xe0\xa6\x0b\xf4\xff\x71\xc3\x17\xc3\x81\x9b\xc6\x3e"
-  "\xa3\x4a\x38\xf0\xc5\xc6\xff\xa6\x0b\x8e\xff\x17\x1b\xfb\xff\x63"
-  "\xbd\xd0\xd8\x7f\xb1\x71\xff\x3f\x63\xe2\x3f\x64\x03\x5e\x56\xe5"
-  "\xe2\x71\xb5\x99\x4a\x45\xa6\x4b\x89\xab\x7a\x6b\x93\x92\xc2\xe6"
-  "\x11\xd5\x35\xd7\xb0\x8b\xe7\xed\x60\x6c\x63\x1d\xd3\x93\xec\xac"
-  "\x7f\x76\x43\x97\xde\x1d\x9c\x0d\x7a\x15\xda\x95\x13\xd0\x5d\x45"
-  "\xe9\x6f\xd2\xfa\xe7\x23\x1e\x56\x96\x91\xe9\xaa\xc8\x4f\x61\xe2"
-  "\x8c\x1b\xc9\x0f\xf0\x01\x98\xfa\x29\xd1\xd4\x9a\x00\xec\x63\x2e"
-  "\xa6\xef\x82\x84\xbb\x54\x46\x80\x3d\xaf\x78\x75\x29\xab\x45\x3e"
-  "\xaf\xb0\x49\xaf\xa8\x7a\x8b\x17\xd8\xe1\x03\xcc\xdb\xa3\x9b\xb3"
-  "\x2c\xca\xcb\xf4\xf5\xc4\x9b\xfb\x8b\xe7\x64\x7a\x74\x37\xa7\xa9"
-  "\xe7\x43\xfb\x84\xef\x3a\x6a\xeb\x26\x92\x11\x90\x17\x3e\xec\x66"
-  "\x38\x98\x1e\x7e\x81\x29\x6f\x19\xfc\xd9\x5d\xe8\x9c\x75\xa8\x6c"
-  "\xdb\x2e\x7c\xcf\xcb\x68\x3d\x3e\xc9\xf4\xed\x3e\x2f\xc9\x14\x8b"
-  "\x6d\x15\x24\x8f\xdc\x76\x0d\xf4\x27\x67\x58\xfe\x46\xae\x40\x97"
-  "\xc5\x4d\xd5\xe9\xb0\x35\x14\x3e\xd2\x75\x37\xdb\x21\xdb\xab\x71"
-  "\x1e\xa7\x9e\xa0\x67\x21\x13\xc1\xe6\xc6\x94\xb9\x80\x57\xc4\xa6"
-  "\xb4\xfb\xce\x88\xf8\x17\x47\x75\x37\x5f\x03\x3f\x62\xfd\xa6\x6d"
-  "\x0d\x3e\xd3\xb6\xdd\xfe\xe2\x9b\x13\xb5\x3e\xa0\x7e\x2d\x1d\x32"
-  "\x20\xf2\xd1\xfb\xf9\xda\xb9\xeb\x51\xc7\x7d\xd3\xd4\xc9\xa9\x56"
-  "\xee\x05\x5c\x65\x5b\x6e\x79\x06\xb0\x27\xbe\xa3\xc6\x57\x60\xbf"
-  "\x42\xea\x44\x6e\xee\x80\x6c\x4d\xed\xde\x2c\xe5\xdc\xcc\xcd\x22"
-  "\x86\x06\xd1\xff\x7b\xec\xfa\x71\xf2\xc0\x37\x8b\x38\x4e\xae\x2b"
-  "\xb0\xde\xde\xf2\x18\x95\xff\x7f\xa8\x4f\x3e\x29\xd7\x65\xd6\xc8"
-  "\xb3\x93\x37\x57\x51\x1d\x35\xf4\x9c\x82\x7c\x47\x75\xb7\xc4\xab"
-  "\xef\x1b\x22\xde\x37\xc0\xf6\x54\x7d\x3f\x4b\x7d\xbf\x2b\xe2\xfd"
-  "\x2e\xc7\x15\xd0\x73\xdc\xb2\x18\x7d\x20\x38\x16\xd2\xfb\x6a\xe1"
-  "\x93\x00\x7d\x88\xcd\x2c\x54\xf3\x55\xf7\xe9\x6e\x59\xdb\x4f\xb8"
-  "\x45\xef\xeb\x22\xbe\xaf\xdb\x9f\x9b\xcc\x80\xa3\xfe\xe2\x5b\x4a"
-  "\x3c\xfa\x9a\x3e\x29\x1b\xdf\x5c\x2d\xfa\x4e\x6b\x66\x64\x79\x1e"
-  "\xdd\x2d\x8b\xb0\x2e\xfa\x88\x27\xa3\x3c\x79\xa8\x33\x12\xde\xda"
-  "\x09\x4e\xdb\xd2\x87\x96\xd8\xee\x5f\xb5\x76\x25\x4e\xe0\x8d\x3c"
-  "\x5b\x66\xc1\x19\x55\xa5\x6c\x6b\x89\xbb\x06\x67\xe6\x2c\xe2\x7c"
-  "\x76\x35\x8d\x63\xb0\x62\xbb\x2b\x14\xb7\x3d\x2d\x54\x51\xed\x28"
-  "\x38\xcb\xf4\xf9\x56\x7e\xc4\xb5\xe1\x56\x76\x4a\x37\xf7\x4a\x11"
-  "\x6f\xce\x26\xfc\xcc\xfb\x5c\x1b\xde\x42\x9a\x38\x1f\xee\xce\x94"
-  "\x69\x2f\xe5\xb7\xe8\xdf\xc8\xef\xd2\xb7\x66\x9e\x61\xfb\xad\x5e"
-  "\x76\xc0\x76\x06\xbe\x56\x7d\x2f\x29\x1d\x7a\xd8\xe2\x52\xfe\x2d"
-  "\xa8\x0b\xfa\x02\xdc\x4b\xdd\xc7\xdc\x58\xd4\x03\x3b\xc5\x3e\xdd"
-  "\xdc\x8b\x51\x9f\x47\x37\xd7\x12\x55\x27\x6c\xb7\x4d\x94\xaf\x4d"
-  "\x29\xdf\x5a\x22\xe6\x77\xf1\x2d\xae\xa0\xde\xf4\xb4\x7a\x26\x8f"
-  "\xd5\x4d\x86\x4d\xee\xdc\xa6\x88\x33\x6a\xa6\x7e\x3d\x9b\x4b\x69"
-  "\xad\x9a\x8f\x09\xc4\xe2\x19\x8b\x5e\x9c\x23\xb9\xf8\x5c\xdd\xbd"
-  "\xbb\x15\xd3\x56\x82\xef\xd6\x92\x16\x5a\x01\xcc\x22\x7e\xf0\x20"
-  "\xb5\xe5\x5b\x7b\x78\xec\xd6\xdc\x7c\xcc\x53\x82\xc5\xaf\x60\x33"
-  "\x18\xb7\xdd\xb5\x07\x36\x82\x15\xdb\xd3\x7e\x99\x13\xd0\xbf\xd7"
-  "\xda\xc4\x6c\xff\x0c\x9e\x2a\xe5\xe6\x3b\x96\xf2\xe0\xb5\x9d\x2e"
-  "\xd6\xda\xfd\x22\x3b\x78\xb8\x85\x99\x16\xb3\xa8\x02\x0f\x0f\x09"
-  "\xdd\x41\x36\xd3\xa7\x7a\x58\x14\x7c\x1b\xc1\x2f\x39\xe2\xe1\xb6"
-  "\x07\xda\x88\xcf\x29\x0b\x3e\x9b\xdf\x3b\xc1\x76\x37\x23\xfe\x48"
-  "\xee\x41\x8b\x33\x3f\x5e\x71\xa6\x3a\x16\xfa\xf0\x88\xb3\x3e\x49"
-  "\x1b\x4f\x32\x63\x5b\xd6\x9f\x58\x5e\x26\x57\x60\xd3\x97\x9a\x19"
-  "\xc5\xc5\x79\x9f\x5c\xca\xec\xa0\x31\x5d\x67\x8f\xdb\x9e\xc3\xe2"
-  "\xdb\xb3\x3d\xcc\xdd\xdb\xc2\x6a\x57\xb3\x78\xee\xcf\x8a\x6e\x6d"
-  "\x7d\x8f\xf1\xd2\x73\x29\xcf\xe7\xbb\x26\x68\xf6\x57\xe6\x22\x1d"
-  "\xf4\x9f\x71\x65\xb0\xc3\x1a\x60\xc9\x19\xc7\x0a\x85\xce\x16\xfa"
-  "\xf1\xa0\xdf\x6e\x1b\xf2\xdb\xbf\x3c\xe8\xb7\x5f\xa1\xe9\xd5\x7f"
-  "\xb8\xdc\xc2\x76\xe0\x9c\x50\xf1\x0d\x8b\x71\x4e\x08\xfc\x64\x30"
-  "\x3a\xb4\x00\x3a\x74\xe1\xab\x65\x9d\x3d\x41\xb9\xdf\xce\x66\x7a"
-  "\xc5\x39\x24\xe8\xf5\x2d\xf5\x3f\xa2\xf6\xf6\x9d\x61\x91\xb6\x44"
-  "\xe7\xd6\xd9\xf5\xb0\x23\xe2\xc5\x73\xbb\x07\x77\xdc\xbb\x1b\xf6"
-  "\x44\xb4\x0e\xcc\x1e\xff\xdc\xfe\x96\xb0\xb3\x46\xff\x69\x3c\x5c"
-  "\x7b\xce\x60\x7c\x68\x9c\xce\x78\xf5\x18\x8b\xb6\xa5\x18\x87\x8e"
-  "\x11\xe3\x20\xc6\x6d\x75\x40\x8f\xf1\xc0\x58\x60\x4c\xc2\xe3\xf1"
-  "\xa1\x18\x8f\x3d\x8a\x1c\x8f\x41\x5a\x07\xb4\x31\x39\x97\x70\x6f"
-  "\xd3\x85\xc6\x05\xe3\x81\xb1\x69\xed\xfe\x13\x1b\x31\x26\x5e\x39"
-  "\x26\x04\xcf\xc9\xda\xb8\x60\x4c\xdc\x7d\x1d\xd8\x37\x88\xbe\xfd"
-  "\x43\xc6\xee\xb8\x86\x2b\x6d\x0b\x0f\x0d\x8f\x4f\x70\xac\xf1\x39"
-  "\x1e\x1e\x1f\x1a\xfb\xcf\x8e\xcf\x49\x0b\xf6\x79\x30\x3e\x9e\xf1"
-  "\x8c\x4f\x6b\xb7\x1c\x9f\xa0\x3a\x3e\xd7\x2c\x60\xfa\x80\xdf\xae"
-  "\xdf\x96\xc3\x66\x2f\x3c\x66\x63\x6f\xa7\xb7\x31\x82\x75\xb6\x52"
-  "\xbe\xad\xe6\x8b\xcd\xa3\xf9\xbe\xcf\x3f\x8f\xe6\xfd\xe4\x7f\xe7"
-  "\xd1\x78\xe7\xd1\xbc\xa4\xbf\x6f\x1e\xcd\x77\xfd\xef\x3c\xfa\xaf"
-  "\x9a\x47\xf3\xf7\x9d\x3f\x8f\x86\xd7\xea\xd5\xcb\x1e\x5a\xb2\x7c"
-  "\xe5\xf2\x95\xff\x66\xfb\xd1\xfa\xec\x65\x6b\xe4\x8a\x3d\x62\xcd"
-  "\xb6\x86\xf2\x53\xf4\x88\x9d\xdc\x5a\xd3\xc1\x9e\x9f\xda\xa1\x0f"
-  "\x7d\x6c\x35\xf0\x32\x73\x95\x52\x66\xb1\x20\x8e\x32\xe6\x1b\xe2"
-  "\x2b\xf7\xe8\xee\x48\x86\x5f\x3e\xe9\x03\xe5\x0e\x61\x6f\x49\xbc"
-  "\xe1\x6c\xec\xb7\x6c\x1a\xa4\xdf\x06\x66\x30\x07\x98\xd1\x75\x05"
-  "\xde\xdf\x5e\x0e\x1f\x62\x7c\xc7\xe2\xd9\xf5\x88\x7b\x3c\xc8\x0c"
-  "\x3e\x53\x66\xca\x66\x2a\xcf\x1b\xbb\xb5\xc4\x60\xc3\xd9\x91\xef"
-  "\x24\x10\xcf\xd1\x35\xec\x5b\x48\x77\x7b\x1a\x9f\xf8\xed\x15\x98"
-  "\xeb\x38\xc7\x77\x4a\xf7\x9d\xef\x9d\x83\x4f\x74\xe2\x63\xef\xb9"
-  "\x86\xea\x9a\x76\x6f\x93\xf0\x9b\x40\xf3\x5e\xbe\x5f\x20\xfc\x9a"
-  "\x0d\x99\xaa\x45\xac\xd1\x7e\xd3\x76\x57\x7f\xd9\xf6\xb4\xf7\xf2"
-  "\x1a\x99\xed\x6e\xcc\xfb\xef\x6c\xbc\xbd\x86\xe6\x7d\x9a\x8b\xb5"
-  "\x59\x7f\xc9\x0e\xa6\x13\xbe\xa5\xff\xad\x79\x1f\x81\x67\x57\x7c"
-  "\xbe\x79\xaf\xe1\x17\xf0\x0a\xf8\x05\xdc\xba\x88\x70\x0b\xf8\xa6"
-  "\xe1\xd7\x13\x03\x12\xbf\xcc\x87\x99\x65\xfb\x19\xc2\xb1\xa0\xc4"
-  "\x31\x9c\x37\x6e\xcb\x3d\x34\xf6\xfc\x1f\x38\x0f\xbf\xf4\x2a\x7e"
-  "\xad\x23\xfc\x5a\x17\xc6\xaf\x7b\xff\x64\x61\xb5\x02\xbf\xae\x0f"
-  "\xe3\xd7\x96\xd0\x02\x0d\xb7\x80\x67\xc0\x29\xe5\xdf\xec\x0c\x73"
-  "\x5e\xc3\xb3\xfa\x07\xe4\x9e\xa9\x98\xff\x7a\x9a\xff\xfe\x88\x75"
-  "\x74\xda\xdf\x33\xff\x17\x88\xf9\x8f\x31\xc1\xf8\x60\x5c\x30\x16"
-  "\xff\x7f\x1c\x07\xc4\x99\xe5\xfe\xd1\xc6\x22\xb9\xf7\x6f\x8d\x05"
-  "\xc6\x01\xe3\x21\xc6\x81\xc6\x43\xdb\xbf\xc6\x7e\x26\xc6\x04\x63"
-  "\x31\x23\x8f\xe9\x31\x2e\xf5\x34\xe7\x31\xcf\x09\xb6\xfb\x30\x2e"
-  "\x82\x77\x75\xc6\xae\xac\x9e\x1c\x8e\xc5\xe2\x2f\xbe\xdd\xf1\x59"
-  "\xbe\xf5\xf6\xcd\xc3\xbe\xd1\x74\xdf\x11\x72\x99\x6b\xea\x4d\x34"
-  "\xdf\xbe\xad\xca\x2c\x5b\x67\xcb\xbd\xa8\x3b\x8e\xa8\x73\xda\x06"
-  "\xf9\x4f\xc8\x7a\x21\x92\xf5\x4c\x24\xeb\x95\x91\xac\x07\xdd\x9b"
-  "\xf0\x2d\x70\xbb\x3c\x2b\x0f\xd9\x2e\xb6\x3a\x9d\xe4\x8c\x05\x80"
-  "\x9f\xd8\x83\x8d\xdd\xd6\x20\x62\xa6\x97\x93\x1c\xf9\x73\x3d\xa3"
-  "\x67\xc2\xa1\xd0\x38\x71\xe7\xf6\xa0\xba\xc7\xec\x70\x6c\x80\xfd"
-  "\xc1\x1d\x32\x8e\x89\xee\xdb\x1f\x22\x5d\xec\xcf\xe9\x95\x86\xd0"
-  "\xa6\x91\xfb\x73\x91\xfb\xb7\xcf\xe7\x7b\xd5\xbd\xb9\x3b\x84\x8f"
-  "\x5f\xd0\x07\xd0\xb5\x67\xf3\x3b\xf4\xe1\xfd\xb9\x43\x78\xff\xf2"
-  "\xc8\xfd\xb9\x3b\x84\xbe\xd4\xa3\xbb\xc3\x03\x9b\x14\x7a\xae\x93"
-  "\xe9\xdf\xee\x8c\x4c\x0f\xef\x7f\xcb\x74\x9c\x81\x52\x65\xee\x3e"
-  "\x29\x6b\xdf\x11\xd0\x64\xda\x31\xf8\x9b\x71\xd0\xdd\xb4\x7d\x61"
-  "\xba\x9b\x26\xfd\x7c\x5b\x6b\xb3\xda\x3e\x43\x77\xe1\xa7\x2a\xed"
-  "\xb2\xbb\x40\x77\xcb\xaa\x33\x65\xfb\x16\xfe\x84\x60\x12\x85\x78"
-  "\x6a\x48\xc7\x59\x21\xd0\xdf\x1d\xf4\xdd\x0e\x41\x93\x6b\xd3\x37"
-  "\x8b\x7d\xf8\x85\xbb\x47\xd2\xe2\xd4\xc3\x23\x69\xf1\xc2\x3f\x5d"
-  "\x98\x16\xdf\x55\x74\x61\x5a\x7c\x67\xf4\xff\xd2\xe2\x2f\x4a\x8b"
-  "\x89\x17\xfb\xbb\x68\xf1\x5d\x0b\xff\x97\x16\xff\x67\xd1\xe2\xbb"
-  "\x16\x44\xd0\xe2\x1f\x8c\xa4\xc5\xa9\xc1\xcf\xd2\xe2\xff\xaf\xbd"
-  "\xaf\x01\x88\xaa\x4a\xfb\x3f\x73\x1d\x15\x95\x8f\xd1\xcc\xc8\x45"
-  "\x9b\xca\xda\xa9\xd5\xa4\xa2\x56\xcb\x8a\x5a\xdb\xa8\x55\x41\xd7"
-  "\x8a\x12\x0b\x0d\x0c\xcb\x8f\x11\x51\x49\x89\x0f\x23\x5f\x44\xc0"
-  "\x61\x40\x5f\xbe\x41\xc3\xc2\xcf\xc8\x75\xf7\x4f\xbb\xfa\x2e\xad"
-  "\xd6\x52\x22\x60\xaf\xed\x52\xe1\x36\x11\x19\x19\xda\xa4\xa3\x8c"
-  "\x30\x33\xf7\xff\x3c\xf7\xdc\xcb\xdc\x3b\xcc\xc0\xcc\x05\x3f\x5f"
-  "\xa9\xeb\xcc\x9c\x7b\xee\xb9\xe7\x3c\xcf\xef\xf9\x3d\xcf\x39\xe7"
-  "\xde\x73\xc2\x54\x76\x2e\x9e\xb6\xcf\xce\xc5\xd3\x16\x49\xb9\x78"
-  "\xe6\x62\xf7\xb8\x38\x6c\xe1\xc5\xe5\xe2\xb0\x34\x29\x17\xcf\x0c"
-  "\xe7\x79\x65\xba\xe7\x5c\x3c\x73\x72\xcf\x5c\x3c\xf3\x71\x29\x17"
-  "\xcf\x1c\x49\x39\x77\xe6\x22\xca\xc5\x33\x35\x34\x7d\xda\x34\x71"
-  "\xba\x9d\x8b\x69\x7a\x77\x2e\x9e\x99\xda\x0b\x17\x6b\xac\x36\x81"
-  "\x8b\x1b\x81\x8b\x1b\x19\xdb\xab\xae\xb8\xf8\xb9\x7d\x47\x90\x8b"
-  "\x63\x91\x8b\x9f\xdb\xd7\x33\x17\x3f\xb7\x05\x39\x17\xf0\x4a\x8a"
-  "\x36\xb3\xad\xb8\x8e\x62\xf5\x82\xaf\x70\x4c\xb7\x05\xf1\x79\x42"
-  "\xf1\xec\x85\x19\x09\x62\xae\x9e\x75\x6f\x17\x57\x43\xba\xed\x66"
-  "\x29\x57\x23\x4f\x23\x5f\x17\x6f\x66\x0d\x25\x9b\xd9\xa6\xf6\x75"
-  "\xb3\x22\x04\xce\xce\x84\x34\xdc\x1b\x03\xd7\xfc\x29\x3e\xcf\x1d"
-  "\x4a\x90\x41\xcb\x5b\x70\x5f\xbc\x06\xf2\xa6\x49\xf9\xfd\xd9\xfd"
-  "\x96\x75\x62\x7e\x9f\x75\x00\xf9\x3d\x83\xbe\x07\xcf\xf1\xba\xa5"
-  "\x78\x4e\x15\x72\x3d\x3d\x3f\x7b\x5e\xcf\xfc\x3e\xeb\xc7\xcb\xc5"
-  "\xef\xc8\x29\xc3\x44\x7d\x39\x57\xbc\x02\x6d\x33\x1d\x89\xba\x34"
-  "\xfc\x8e\x7c\x82\x3c\x82\xdc\x22\xf0\x3b\x72\x8b\x85\xef\x6b\x17"
-  "\xad\x15\xf1\xfb\x20\x11\xbf\x2b\xe4\xf0\xfb\xec\xf1\x57\x15\xbf"
-  "\xa3\x1e\x12\x2e\x2e\xbf\x0b\xfd\x6a\xd4\x03\xea\x04\x75\x21\xee"
-  "\x5b\xa3\x1e\x50\x1f\xa8\x07\x8c\x69\x04\x7e\x9f\x10\x4f\xf9\xbd"
-  "\xb8\x8b\xdf\x67\x6b\xba\xf8\x9d\xa1\xfc\x5e\x84\x6b\xb9\x71\x63"
-  "\xc4\xcf\x36\x75\xe7\xf7\x67\x8d\x76\x7e\x9f\x95\xcb\xf3\x5d\x0b"
-  "\xae\xd7\x00\xf6\xed\x2f\xe5\xf8\xe7\xa3\xdd\xe3\xf8\xe7\xa6\x77"
-  "\xe3\x78\x7e\x5f\x79\x9e\xdf\xcb\x90\xdf\x2d\xc8\xf3\xb2\x38\xfe"
-  "\xb9\x45\x76\x3f\x34\xd3\x4c\xb9\xf5\x39\x2f\x29\xef\x3f\x1f\xc6"
-  "\xfb\xa5\x2f\xc5\xbc\x6f\x1b\xe0\x0e\xef\x3f\x7f\xaf\xc0\xfb\xc8"
-  "\xab\xbb\x6d\x8d\x22\xde\x47\x9e\x7c\x7e\x72\xf5\xca\x66\x11\xef"
-  "\x3f\xef\x4d\xeb\xf0\x7c\x94\x95\xe3\xfd\xe7\xd5\xbc\x3f\x68\x14"
-  "\xa7\xdb\x79\x9f\xa6\x5b\xc5\xbc\xdf\x8a\xbc\xff\x7c\x42\x2f\xbc"
-  "\x1f\xe4\x3e\xef\xcf\x1d\x67\xe7\xfd\xb9\xe3\x7a\xe6\xfd\xb9\xc3"
-  "\x91\xf7\xb9\x75\x5f\x41\xf7\x80\x67\x65\xd6\x28\xca\xf9\x38\x26"
-  "\x02\xbe\xc0\x80\xeb\x84\x9c\x50\x44\x58\x4b\xd1\x2f\xc0\x01\xe7"
-  "\x5b\x33\xf0\xbb\x8d\xbb\xa6\xc9\xcf\x48\xbc\xd0\x07\x64\x9c\x20"
-  "\x4a\xdc\x63\x88\xca\x29\xe2\x05\xb8\xb6\xd1\xee\x2f\xc2\xe7\xb9"
-  "\xe9\x2f\x70\x4f\xf4\x86\xf6\x75\xe1\x19\x22\x7f\x81\xfb\x34\x35"
-  "\x38\xf8\x0b\x03\xf8\x8b\x16\xe1\x1a\xc8\xbf\x5f\x9c\x1f\xeb\xc7"
-  "\xe5\x3f\xc1\x1d\x98\xbf\xf1\x2d\xdc\x7b\x8c\xf3\x2f\xe1\xad\x52"
-  "\xff\x12\x11\x60\x93\xf4\x1f\x5e\x18\x23\xf8\x17\xf4\xcf\xb6\x6e"
-  "\xfe\xe5\xc5\x8f\xba\xfc\xcb\x28\x91\x7f\x89\x17\xfc\xcb\x0b\x4f"
-  "\x5f\xf1\xfd\x87\x3e\xf0\x9a\x5c\xff\x82\x9c\x86\x7c\xd6\x93\x7f"
-  "\xb1\x89\xfc\x8b\x4d\x96\x7f\x79\x31\xe3\xaa\xf2\x2f\x97\xa0\xff"
-  "\x20\xd6\x01\xea\x85\xf3\x2d\xa0\x1b\xd4\x03\xea\x00\xe5\x8f\x6b"
-  "\x4c\xa3\x6e\x50\x2f\xa8\x93\x09\x5a\xbb\x6f\xe1\xf4\xc2\xf9\x97"
-  "\x17\xd3\x1c\xfd\x4b\xc9\x08\xc1\xbf\x44\x4c\xe9\xee\x5f\x22\xec"
-  "\xeb\xdf\x2b\xc2\xb9\xf1\x1b\xba\xd6\x5f\x78\x88\xd4\xb7\xcc\xfd"
-  "\xc2\x3d\xdf\x12\xb1\xdd\x89\x6f\xe1\xd6\x69\xcc\xd8\x2c\xe9\x3b"
-  "\x94\x81\x7f\x91\xe1\x5b\x22\x6a\x68\x1d\xf1\x59\xe8\x70\x7f\xca"
-  "\xdf\x11\x51\x76\x7f\xf3\xbc\x51\x9c\x66\xf7\x37\x73\xab\x79\x1f"
-  "\x79\xd4\x73\x7f\x33\x77\x0b\xf7\xec\x01\xb4\x61\xf7\x19\xca\xe9"
-  "\x52\x7f\x33\x77\xbb\xd4\xdf\xcc\x4d\xa0\x75\x98\x7b\x8c\xfa\x9b"
-  "\xb9\x3a\xde\x0f\x35\x88\xd3\xed\xfe\x86\xa6\x77\xf7\x37\x73\xdb"
-  "\x7a\xf1\x37\xde\x9d\x01\x73\xaa\x3a\x33\x0a\xca\x2c\xe5\x11\xc1"
-  "\xe3\xc3\x1f\xb3\x3a\xda\x0d\xb5\x17\x2b\xdd\xaf\x46\x98\x7f\x7a"
-  "\x89\xce\x77\xd8\xf8\xf7\x89\x3b\x02\xe6\x54\x9c\x58\x04\xb6\xd3"
-  "\xe6\xda\x76\xc0\x6e\xbc\x04\xbb\x39\x12\xf3\x3d\x01\x5b\x62\x70"
-  "\x4e\xaa\x10\x6c\xa6\xde\xd4\xc8\xd9\x90\x77\x4b\x30\xc1\x75\x1c"
-  "\x7d\xda\x88\xca\x47\xa1\x18\x84\xf3\x1d\x56\xb0\x9f\x27\xef\x62"
-  "\x6d\xbf\x69\x0c\x26\x3e\x31\xc4\x17\x6d\x68\x0f\x3f\xef\x81\x6b"
-  "\x41\xe0\x7c\x07\xe0\x37\xf0\xe5\xa3\xf6\xf9\x8e\x0e\x37\xe6\x3b"
-  "\xea\xe3\x0d\xdc\x7c\x07\xbe\x1f\x65\x03\x3b\xe1\xde\xd9\xc1\xf9"
-  "\x0e\x33\x37\x47\xc4\xf1\x57\x29\x37\xdf\xd1\x4c\x70\xae\x43\x58"
-  "\x0b\x06\xe7\x38\x7e\x13\x4e\x18\x5c\x2b\xa2\x10\xec\xe6\x63\xcd"
-  "\x11\xce\x6e\x3c\xe7\xb0\x97\xc3\x7a\x7a\xc6\xc7\x02\x32\xb5\x7a"
-  "\x17\x94\xb1\x05\x85\xba\x9d\xcd\x66\x05\xae\x93\x69\x05\x1d\xd9"
-  "\x80\xab\x58\x2f\x07\xae\xea\xe4\xe5\xdd\x49\xe5\x0d\xba\xf2\x7a"
-  "\xc9\x44\x58\x48\xa7\xeb\x64\x9a\x0d\x80\x35\xcd\x88\xe2\xd5\x28"
-  "\xdb\x40\x52\xcc\xaf\x95\x69\x5b\x13\x33\xc4\x06\xf2\xc4\xf7\x22"
-  "\x76\x9f\x37\x0f\xb4\x7a\xb5\x87\x64\x74\x90\xf1\xc0\x4b\x3e\xc8"
-  "\x4b\x80\xcf\xa1\xa5\x1d\x20\xdb\x6f\xa9\x6c\x71\xcd\x36\xfc\xb4"
-  "\xac\xd1\xa8\xa1\xec\xdb\x3a\x3b\x41\xbe\x66\x2a\xdf\x97\x96\xa9"
-  "\x48\x89\x30\xdf\x07\xbe\xbe\x0e\x74\xca\xf1\x92\xc9\x8f\xc5\xbd"
-  "\x24\xac\x9d\x9a\x00\xdb\x0f\x20\x5f\x13\xee\x1b\xa2\x41\xfd\xab"
-  "\x4a\x4e\xe0\xfc\xe4\x57\x74\xbe\x6f\x08\xbf\x06\xc7\x1a\xf0\x11"
-  "\x0b\xd5\xa4\xbe\x02\x38\x7a\xd0\x4b\xa4\xb3\x78\x4e\x05\xd7\x07"
-  "\x49\xf0\x54\xbe\x91\x2e\xf7\xff\xb9\xb8\xf2\x55\x5f\x45\xf2\x7d"
-  "\x39\x4f\xbe\x7c\xe7\xab\x2e\x8f\x7c\x55\x57\x91\x7c\x23\xcd\xf2"
-  "\xe5\xfb\x8a\xcb\xe7\x1f\x51\xbe\xd8\x4f\x10\xfa\x08\x42\xff\x00"
-  "\xfd\x0a\xf5\xa1\xd1\xad\xf6\xbe\x41\x74\xab\x30\x2f\x0a\xb2\x51"
-  "\x66\xe2\x9a\xcf\xd0\x66\xed\x02\xdc\x4b\x21\x7a\xae\x30\x27\xaa"
-  "\xc3\xfd\x42\x50\x57\x05\xa0\xab\x25\xf8\xfe\x0b\xaf\x27\xf0\x03"
-  "\x2f\x9b\x80\xab\xc7\xcc\xa9\xb2\x66\x82\x9f\xd8\x16\x11\xec\x42"
-  "\x67\x0c\x72\xbc\x4f\x1c\x51\xbd\xa4\xa5\xba\xb3\xad\x01\x9d\x75"
-  "\x40\x4c\x64\x6e\x25\xf8\x3e\xab\x5f\x2b\xf0\x6a\x67\xcc\x90\x08"
-  "\x88\xb1\x05\xbd\xed\x59\x69\xe6\xe2\x21\xa7\x7a\xcb\x97\xea\xed"
-  "\xac\x13\xbd\xd9\x9f\x33\x80\xd8\x94\xd3\x9b\x81\xd3\x1b\xc7\xeb"
-  "\x6b\x20\x36\x05\xfd\x09\x7a\xe3\x78\x1d\x74\xc7\xe9\xad\xad\x99"
-  "\x8b\x81\x04\x5e\xc7\xf8\x07\x75\x57\x1b\x09\xf1\xdc\xba\xf9\xe1"
-  "\x9c\xde\x70\x6c\x3b\xd2\x53\xbd\x45\x6b\xa4\x71\xcf\x82\x4d\xee"
-  "\xc5\x3d\xd1\xdb\x30\xae\x11\xc7\x3d\xf8\xfb\x2c\xc4\x39\x56\x9f"
-  "\xfc\x72\x93\xac\x7e\x74\xf4\x3e\x69\x0c\xb3\x20\x99\xd6\xe9\x95"
-  "\x53\x9e\xc7\x30\x0b\xb8\xf1\xb6\xdd\x05\xce\xe2\x97\x05\x0b\xa5"
-  "\xf1\xcb\x82\x29\x34\x4e\x59\x90\x7b\x76\x2d\xc6\x2f\x0b\xc2\x68"
-  "\xfa\x2b\x6d\xe2\x74\x7b\xfc\x42\xd3\xb9\xbd\xc8\xd7\x2d\x28\xf3"
-  "\x2c\x66\x99\x78\x99\x63\x96\xc0\x1e\x62\x96\xc0\x6b\x2c\x66\x89"
-  "\x51\x5e\xf7\xa9\xbd\x71\xfe\x82\x7d\xf2\x39\x7f\x61\xd4\x75\x9f"
-  "\xda\x9b\x7c\x63\xa6\xc9\x97\xef\x6b\x2e\x9f\xff\xef\xdd\xa7\x2e"
-  "\x9e\x62\xf7\xa9\x8b\xa7\xb8\xf6\xa9\x8b\x3e\xb8\xee\x53\x9d\xf9"
-  "\xd4\x85\xbb\xe4\xfb\xd4\x45\x09\x52\x9f\xba\xf8\x47\xf7\x7c\xea"
-  "\xa2\x0b\xfd\xef\x53\x17\x3b\x8c\x43\x2f\x3e\x46\xeb\xf4\xfa\xe3"
-  "\x9e\xfb\xd4\xc5\x7f\x76\xed\x53\x17\x1f\x90\xfa\xd4\xc5\x3a\xea"
-  "\x3b\x17\xb7\x52\x9f\xba\xb8\x9c\xa6\xbf\x1e\x2c\x4e\xb7\xfb\x54"
-  "\x9a\x4e\x7d\xea\x62\x93\x67\x3e\xf5\x96\xcb\xec\x53\xd5\x3d\xf8"
-  "\x54\xf5\x35\xe6\x53\x97\xba\xdc\xff\xe9\x3a\xe7\x0b\x9c\xbf\xc4"
-  "\x4b\x3e\xe7\x6b\xab\xe4\x73\xfe\xf2\x40\x3b\xe7\x2f\x0f\x74\xcd"
-  "\xf9\xb1\xdb\xae\x73\xbe\x33\xce\x5f\x5a\x26\x9f\xf3\x63\xb5\x52"
-  "\xce\x5f\x7e\xdc\x3d\xce\x8f\x3d\xd5\xff\x9c\x1f\xeb\xf0\xfc\xdf"
-  "\xf2\x1a\x5a\xa7\x65\x0f\x78\xce\xf9\xcb\xb7\xbb\xe6\xfc\xe5\x1f"
-  "\x48\x39\x7f\x79\x2a\xe5\xf6\xe5\x4d\x94\xf3\x97\xe7\xd1\xf4\x65"
-  "\x41\xe2\x74\x3b\xe7\xd3\x74\xca\xf9\xcb\x5b\x3d\xe3\x7c\xbf\xcb"
-  "\xcc\xf9\xaa\x1e\x38\x5f\x75\x8d\x71\xfe\x0a\x97\xeb\x9f\xf5\xce"
-  "\x49\xab\x0e\xd9\x39\x69\xd5\x21\xd7\x9c\xb4\x6a\xf2\x75\x4e\x72"
-  "\xc6\x49\xcb\x2d\xf2\x39\x69\x95\x52\xca\x49\xf1\xcb\xdc\xe3\xa4"
-  "\x55\x29\xfd\xcf\x49\xab\x74\x52\x4e\x8a\x8f\xa0\x75\x5a\xf1\xa9"
-  "\xe7\x9c\x14\xff\x88\x6b\x4e\x8a\x7f\x52\xca\x49\xf1\xfc\x9c\x59"
-  "\xbc\x96\x72\x52\xfc\x78\x9a\xbe\xa2\x46\x9c\x6e\xe7\x24\x9a\x4e"
-  "\x39\x29\xbe\xb7\xe7\x1f\x38\xec\x1f\xf1\x77\xc0\xfe\xeb\x02\xf6"
-  "\x57\x1f\x3b\x5c\x24\x60\x7f\x35\x7d\xce\xb9\x28\x62\xd2\x86\x95"
-  "\x44\x99\x81\xfb\x98\x80\xbd\x6b\x5f\x44\xec\xaf\x7e\x1a\x9f\x3f"
-  "\xf0\x6e\x02\x0e\x6b\xe1\x39\x2d\x1e\x38\xad\x05\x7e\xe3\xfa\x56"
-  "\x63\x22\x26\x21\x17\xe1\xbe\x07\xf8\x9b\x72\x9b\x71\x20\xbe\xbb"
-  "\xe9\xd1\x7b\x55\x2d\xfc\x7b\x55\x51\xdd\xdf\xab\x2a\x12\xbd\xbf"
-  "\x83\xb6\xe1\x93\xa2\xf0\xc5\xb9\x60\xe0\x37\x9e\xc7\x6a\x06\x5a"
-  "\xbc\x78\x1e\x3b\x0f\x3c\x76\xde\x6e\x13\xc8\x63\x67\x81\xc7\x4c"
-  "\xab\x34\x63\x91\xcb\xba\xbf\x53\x45\xe7\x7e\x39\x1e\x5b\xef\xc0"
-  "\x63\xaf\x3a\xf0\xd8\x02\xe0\xb1\x48\xe0\xb1\x21\x76\x7b\xb8\xbd"
-  "\x89\x30\xd3\xe6\x81\x4d\x00\x8f\xe5\x9c\x47\x1e\xfb\x58\x26\x8f"
-  "\xad\x1e\x29\xb5\x87\x35\x29\xee\xd9\xc3\xea\x6c\x57\xf6\xd0\x99"
-  "\x29\xd7\x1e\x56\x97\x49\xed\x61\xcd\x22\xde\x46\x3f\xf6\xdc\x1e"
-  "\xd6\x4c\xef\xb2\x87\xd7\x1d\xed\x61\xcd\xb3\x52\x7b\x58\xa3\xa1"
-  "\xb8\x5f\x93\x4c\xed\x61\xcd\x14\xde\x4e\x0e\x89\xd3\xed\xf6\x40"
-  "\xd3\xa9\x3d\xac\xc9\xb8\x3e\x3f\x7b\xa5\xfa\xe8\x04\xe3\xf5\xf9"
-  "\xd9\xde\xfa\x65\x6b\xca\xe4\xf7\xcb\x12\x2f\xd3\xfc\xf7\xd5\x34"
-  "\x96\xfc\xe6\x24\xf9\xf2\x4d\xba\x4c\xf3\xdf\x57\xd3\xb8\x42\x62"
-  "\x1f\xe6\xbf\x53\x7a\x9c\xff\xee\x39\x8e\x79\xab\xac\xb6\x2b\x86"
-  "\x7f\xab\x4c\x78\x76\xb3\x7b\x0c\xff\xd6\x8d\xd2\x77\xa7\x52\x3e"
-  "\x72\x7c\x77\xaa\xb7\xd8\xde\xf2\x7f\x2a\xb6\x4f\x32\xcb\x8f\xed"
-  "\xd7\x1a\xa4\xb1\x4c\xea\x74\xf7\x62\x99\xb7\xe6\xba\x8a\x65\x2c"
-  "\xb2\x63\xfb\xb7\x16\x49\x63\x99\x54\xbe\x4e\x29\x99\x9e\xc7\x32"
-  "\xa9\x37\xbb\x8e\x65\x52\x6f\x95\xc6\x32\x6f\x99\x68\xcc\x92\x3a"
-  "\x8d\xc6\x32\xa9\x7c\x7a\x4a\x86\x38\xdd\x1e\xcb\xd0\x74\x1a\xcb"
-  "\xa4\x86\x5f\x9f\xb7\xbd\x52\x63\x99\xb7\x5d\xae\xff\x76\xdd\xd7"
-  "\x0a\xbe\x20\x75\x91\x7c\x5f\xf0\x5f\x2e\xd7\x3f\xbb\xee\x6b\x05"
-  "\xf9\xae\x53\xca\x97\x6f\x5a\x82\x7c\x5f\xbb\xc1\xdb\xee\x6b\x37"
-  "\x78\xbb\xf6\xb5\xe9\x29\x52\x5f\xbb\x7e\xc2\x75\x5f\xdb\x93\xaf"
-  "\xfd\xaf\x28\xf9\xbe\x36\x7d\x9a\xd4\xd7\x6e\xf8\xd0\x3d\x5f\x9b"
-  "\xfe\x69\xff\xfb\xda\xf4\x46\xa9\xaf\xdd\x50\x4e\xeb\x94\x76\xc1"
-  "\x73\x5f\xbb\xe1\x6d\xd7\xbe\x76\x43\xa6\xd4\xd7\x6e\x88\xa4\x3e"
-  "\x75\x43\x15\xf5\xb5\x1b\xe2\x68\x7a\x9a\x59\x9c\x6e\xf7\xb5\x34"
-  "\x9d\xfa\xda\x0d\x87\xae\xcf\xe7\x5e\xa9\xbe\x36\x53\x73\xdd\x17"
-  "\xf4\xe6\x0b\x36\x34\xca\xf7\x05\x59\x69\xf2\x7d\x41\xb6\xbf\xdd"
-  "\x17\x64\xfb\xbb\xf6\x05\xba\x4c\xa9\x2f\xd8\x38\xf9\xba\x2f\xe8"
-  "\xc9\x17\x64\x6a\xe5\xfb\x02\x5d\xb8\xd4\x17\x64\x7f\xec\x9e\x2f"
-  "\xd0\x7d\xd1\xff\xbe\x40\xd7\x22\xf5\x05\xd9\x95\xbc\xfe\x07\x7a"
-  "\xee\x0b\xb2\xb3\x5d\xfb\x82\xec\x7c\xa9\x2f\xc8\x5e\x44\x39\x3f"
-  "\xfb\x10\xf5\x05\xd9\xc9\x34\x7d\xa3\x52\x9c\x6e\xf7\x05\x34\x9d"
-  "\xfa\x82\xec\x86\xeb\xf3\xbc\x57\xaa\x2f\xc8\x09\x92\xcf\x55\x9b"
-  "\x0e\xd9\xb9\x6a\xd3\x21\xd7\x5c\xb5\x69\xb2\x94\xab\x72\xbe\xbf"
-  "\xce\x55\x3d\x71\x55\x76\x8b\x7c\xae\xda\xe4\x30\xff\xbb\xd9\xcd"
-  "\xf9\xdf\x4d\x2e\xe7\x7f\xe5\x73\xd5\x26\x87\xf9\xdf\xcd\xfc\xfc"
-  "\x6f\xce\x07\x9e\x73\xd5\xe6\x47\x5c\x73\xd5\x66\x87\xf9\xdf\xcd"
-  "\xfc\xfc\xef\x66\x7e\xfe\x77\x33\x3f\xff\x9b\x53\x29\x4e\xb7\x73"
-  "\x15\x4d\xa7\x5c\xb5\xb9\x8f\xf3\xbf\x79\x6d\xf6\xf9\xdf\x3c\xee"
-  "\x9d\x01\x5b\x5e\x61\x4c\xf7\xf9\xdf\xbc\x79\xd2\x75\x4c\x36\x5b"
-  "\xb9\xb9\x60\xb4\x0b\x13\x7d\x37\xdd\xe9\xbc\xf0\xcd\x85\x31\xd7"
-  "\xe7\x85\xfb\x63\x5e\x38\x6f\xbc\xd4\x4e\xf2\xf3\xdd\xb3\x93\xbc"
-  "\xed\xfd\x3f\x2f\x9c\x57\x25\xb5\x93\xfc\x54\x1e\x13\x32\xe6\x85"
-  "\xf3\xa3\x5d\xdb\x49\xfe\x62\xa9\x9d\xe4\xf3\xcf\xe5\xe6\xe7\x51"
-  "\x3b\xc9\x9f\xcd\xdb\xcf\x21\x71\xba\xdd\x4e\x36\x8b\xe6\x85\xf3"
-  "\xcb\xdd\xf1\xe9\x16\xef\x82\x72\xf4\xd1\xe3\x1b\x1f\xb3\x76\xe1"
-  "\x39\x8e\xc7\xb3\x33\x9f\x3e\x9f\x72\x3f\xe2\xb8\xb3\x3c\x62\x6a"
-  "\xaf\x3e\xbd\x85\xf7\xe9\x51\xdd\x7d\xba\xe0\xcf\x11\xcf\x85\x6e"
-  "\xcd\x09\x3b\xe0\xda\x23\x7f\x7e\xbf\xa1\x2f\xb8\x46\x4c\x4b\xfd"
-  "\xb9\x5c\x5c\x17\x5e\xa6\xf7\x5f\xae\xa6\x39\xe1\xfc\x2a\xf9\x7d"
-  "\xbb\xa2\xcb\xf4\xfe\xcb\xd5\x34\x4e\x5d\xd8\x87\xf7\x5f\x8a\x7b"
-  "\x7c\xff\xe5\xfa\xd8\x04\xca\xb7\x68\x97\x7c\xf9\x96\x8e\x93\x1f"
-  "\xef\x6f\x39\x66\x8f\xf7\xb7\x1c\x13\x62\x1b\xe4\x42\x6e\xdd\x1d"
-  "\xe0\xbf\xcc\x58\x38\xce\x13\xb2\x21\x96\x5b\x77\xdc\xab\xbe\xe5"
-  "\x0b\xdc\x1b\x09\xe2\x9d\x2d\x4f\x87\xc6\x8b\xe3\x9d\xd2\x1f\x85"
-  "\x58\x27\x14\xe3\x20\x88\x6b\x30\xa6\x11\x62\x7c\xdd\x99\x5e\x9e"
-  "\x07\xbd\x23\x62\x2a\xf6\x09\x3a\x7d\x0a\xca\xaf\xfd\xfe\x40\x89"
-  "\xb7\xfc\xfe\xc0\x16\x87\xe7\xdf\xb6\xba\xf9\xfc\xdb\x16\x97\xcf"
-  "\xbf\xc9\xef\x0f\x6c\x71\x78\xfe\x6d\x2b\xff\xfc\x5b\xe9\x16\xcf"
-  "\xe3\x9c\xad\x3d\x3c\xff\xb6\xd5\xe1\xf9\xb7\xad\xfc\xf3\x6f\x5b"
-  "\xf9\xe7\xdf\xb6\xf2\xcf\xbf\x95\x96\x89\xd3\xed\x71\x0e\x4d\xa7"
-  "\x71\xce\x56\xb7\x9e\x7f\x83\x38\xa7\xa2\x0f\x71\x4e\xef\x63\x17"
-  "\x57\x4c\x9c\x13\x74\x85\xc4\x39\xef\xb4\xb9\xe1\x27\xca\x1d\xfc"
-  "\xc4\xd4\xff\x5b\x7e\x62\x6b\x1f\x9e\x7d\xdb\xd6\xe3\xf3\xff\x9c"
-  "\x7c\x33\x44\xf2\x45\x8e\xe6\x65\x6b\x1d\x17\x31\x55\x96\x7c\x81"
-  "\x9b\x8b\x13\xaf\x16\xd9\x96\x07\xc9\x97\xed\xbb\x15\xd7\x63\x9c"
-  "\xde\xe4\xbb\x2d\x57\xbe\x7c\x2b\x5c\xee\xff\xdd\x7b\x8c\xb3\xa3"
-  "\xf1\x70\x57\x8c\xb3\xa3\xd1\x31\xc6\xc1\x98\x66\xba\x99\xc6\x3a"
-  "\x1b\x20\x46\x49\x5f\x02\xf1\xce\x4a\x42\xea\x5b\x0e\x90\x0c\x88"
-  "\x79\xd2\x4f\x43\xdc\xb3\x08\xe2\x1e\xcb\x36\x3e\xee\xd9\x31\x5d"
-  "\x1a\xf7\x54\x7c\xeb\x34\xee\xf1\xb1\xc7\x3d\x16\x88\x69\x3a\xb7"
-  "\x45\x4c\xd5\x9d\x16\xc5\x40\xaf\x75\x8f\x81\x3a\x32\xc1\xe7\xdc"
-  "\x11\x11\xd2\x09\x71\x50\x4f\x31\x10\xa7\x7b\x87\x38\xe8\xea\x8b"
-  "\x81\xde\x35\xca\x8f\x81\x76\x38\xac\x21\xba\xf3\x6d\xf7\x62\xa0"
-  "\x1d\x9b\x5c\x8e\xf5\xc8\x8e\x81\x76\x94\x4b\x63\xa0\x9d\x5a\x1e"
-  "\x17\x6f\x7b\x1e\x03\xed\x9c\xe9\x3a\x06\xda\xf9\x82\x34\x06\xda"
-  "\x39\x9e\xc6\x3a\x3b\x53\x69\x0c\xb4\x33\x98\xa6\x57\xa4\x8a\xd3"
-  "\xed\x31\x10\x4d\xa7\x31\xd0\x4e\x9d\x9b\xf3\x37\xe5\x16\xf0\xb1"
-  "\x97\xff\xb9\xb9\x9e\xe6\x6f\xfa\xeb\xb9\xb9\xfb\xaf\x90\xf9\x9b"
-  "\x5d\xa6\xeb\x7e\xba\x27\x3f\xb2\xb3\x5c\xbe\x1f\xd9\x73\x99\x9e"
-  "\xff\xbf\x9a\xfc\xf4\xee\x29\xf2\xe5\xfb\x7e\x8f\xcf\xff\xf7\xec"
-  "\xa7\xf7\x46\xda\xc7\x22\xf6\x46\x7a\x36\x16\xf1\xc1\x17\x52\x9f"
-  "\x5c\xb9\xe2\xfa\x58\x84\xbb\x7e\x78\x4f\x9e\x7c\x3f\xfc\x41\x99"
-  "\xd4\x0f\xff\xc9\xc7\x3d\x3f\xbc\x77\x4c\xff\x8f\x45\xec\x1d\x2f"
-  "\xf5\xc3\x7b\xcd\x3c\x16\x26\x78\xee\x87\xf7\x7e\xe9\xda\x0f\xef"
-  "\xfd\x56\xea\x87\xf7\xee\xa3\xfe\xf6\x4f\xde\xd4\x0f\xef\xad\xa1"
-  "\xe9\x95\xe3\xc5\xe9\x76\x3f\x4c\xd3\xa9\x1f\xfe\x93\xbf\x67\x73"
-  "\x2e\xb7\x5c\xa1\x73\x2e\xea\x6b\x6c\xce\x65\x5f\xfc\x75\x3f\xd1"
-  "\x9b\x9f\xf8\xd3\x78\xf9\x7e\xe2\xcf\x8d\xf2\xfd\x44\x55\x9a\xdd"
-  "\x4f\x54\xa5\x79\xe6\x27\xfe\x9f\x55\xea\x27\xfe\x52\x7c\xdd\x4f"
-  "\xb8\xeb\x27\xf6\x55\xcb\xf7\x13\xff\xaf\x46\xea\x27\x3e\x7c\xc0"
-  "\x3d\x3f\x51\xf5\x64\xff\xfb\x89\xaa\xd9\x52\x3f\xf1\xa1\x9a\xc7"
-  "\xc2\xb3\x9e\xfb\x89\x0f\x15\xae\xfd\xc4\x87\x43\xa4\x7e\xa2\xaa"
-  "\x89\xfa\x83\x0f\x83\xa8\x9f\xa8\x32\xd2\xf4\xbf\xcc\x16\xa7\xdb"
-  "\xfd\x04\x4d\xa7\x7e\xe2\xc3\xe0\xeb\xcf\xdb\x5d\xa9\xcf\xdb\xfd"
-  "\xb5\x5c\x3e\x97\x1d\x08\xb2\x73\xd9\x81\x20\xd7\xcf\xdb\xed\xdf"
-  "\x2e\x7d\xde\xee\x6f\xcf\x5e\x7f\xde\xae\x27\xae\xfa\x70\xb6\x7c"
-  "\xae\xda\x1f\x27\xe5\xaa\x03\x6e\xee\x07\xb9\xff\x97\xfe\xe7\xaa"
-  "\x03\x44\xca\x55\x07\xf8\x3d\x20\xff\x76\xab\xe7\x5c\x75\x60\xb7"
-  "\x6b\xae\x3a\xf0\x67\x29\x57\x1d\xe0\xf7\x7f\x3c\x60\xa0\x5c\x75"
-  "\x80\xdf\xff\xf1\x6f\x6a\x71\xba\x9d\xab\x68\x3a\xe5\xaa\x03\x6e"
-  "\xad\xff\x6f\x9f\x5f\x93\x15\xd3\x5e\x82\xf9\xb5\xfe\x8a\x69\xaf"
-  "\x94\xf9\xb5\xbf\x5f\x9f\xff\xe9\x31\x9e\xfd\x9f\x3e\xac\xfb\x5f"
-  "\xdd\xe3\xfc\x4f\xcf\x3e\xe0\xa0\xd6\xee\x03\x0e\x6a\x5d\xcd\x4f"
-  "\xa4\x03\x86\x32\x20\x1e\x5d\x7f\x9a\x28\x37\xe0\xfc\xc4\xb1\x23"
-  "\x24\x13\xe7\x27\x96\x08\xf3\x13\xc5\x7c\x8c\xfb\x8f\xef\xa5\x31"
-  "\xee\x47\x29\xce\x62\x5c\x8c\x6d\xad\x10\xb7\x5a\x1c\xe7\x25\x5e"
-  "\x74\xee\x3b\x3a\x7c\x0a\x2a\x2e\x6c\x8b\x08\xf1\xc4\x77\x14\xae"
-  "\xa6\xbe\xa3\xe0\xaa\xf2\x1d\x7f\xcf\x95\xef\x3b\xfe\x51\x29\xf5"
-  "\x1d\x87\xc6\xb8\xe7\x3b\x0e\x4e\xe8\x7f\xdf\x71\x70\x8a\xd4\x77"
-  "\x1c\xf2\xe2\xf1\x70\x87\xe7\xbe\xe3\xe0\x8f\xae\x7d\xc7\xc1\x5f"
-  "\xa4\xbe\xe3\x20\xff\xac\xe9\xa1\x00\xea\x3b\x0e\x36\xd2\xf4\x8f"
-  "\xc6\x89\xd3\xed\xbe\x83\xa6\x53\xdf\x71\x48\xe3\xd9\x78\x88\xdf"
-  "\x15\x3a\x1e\xa2\xba\xc6\xc6\x43\x3e\xee\xc3\xfb\x6f\x35\x81\xb5"
-  "\x5d\xcf\xcf\xd7\x04\x76\xeb\xaf\xaf\x84\x58\xf7\x0c\x9d\x73\xed"
-  "\xea\xaf\x1b\x8e\xf3\x5c\xf6\xcf\x6d\x52\x2e\xfb\x64\xba\x2b\x2e"
-  "\xeb\x69\x5e\x15\xfb\xe7\x56\xe0\x39\xdc\x6b\x4d\xd6\xbc\xea\xca"
-  "\xab\x89\xbf\x0e\x4d\x91\xcf\x5f\xff\x74\x58\xff\xb4\xc6\xcd\xf5"
-  "\x4f\xff\xe9\x72\xfd\x53\x8b\xec\x67\xe8\xff\xe9\xb0\xfe\x69\x0d"
-  "\xbf\xfe\xe9\x27\x32\xde\x8b\xab\xd9\xee\x9a\xbf\x6a\x1c\xd6\x3f"
-  "\xad\xe1\xe7\x4f\x6b\xf8\xf5\x4f\x6b\xf8\xf5\x4f\x3f\x51\x8a\xd3"
-  "\xed\xfc\xf5\x89\xe8\xbd\xb8\x9a\x1e\xd7\x3f\x65\x33\x22\x2b\x74"
-  "\x8c\xad\x12\x0e\xc4\xe1\xcd\x80\x81\x6a\xf8\x5e\x03\x7a\x1c\x01"
-  "\xdf\x1b\x5c\xd9\x98\xd1\x27\xb2\xc2\xb6\x16\xea\xcc\x10\x45\xbd"
-  "\xf1\xe7\xea\xea\xd1\x16\xb8\xef\xa7\x31\x54\x57\x91\x15\x7e\x96"
-  "\xc1\x21\x36\x36\x86\x80\x5e\x2a\xb8\xfd\xf1\x20\xbf\x2f\x60\x46"
-  "\xbd\x92\xf8\x9e\x56\x7c\x9a\x26\xe4\x83\xfa\xfa\x36\x2b\x3e\x7d"
-  "\x12\xcb\x68\x5f\xf7\x69\x2e\xb4\xc5\xe4\xb2\xae\x50\x56\xe8\xf6"
-  "\xb1\xe4\x4d\x0b\xfb\x43\xf5\x92\x33\xa4\x45\xf1\xe9\x71\xbf\xb6"
-  "\xc1\x21\x6c\x52\x38\xc1\x18\xab\x72\xb4\x51\x89\x65\x56\x2f\xe9"
-  "\xc0\x73\xd5\x78\xce\x0a\x75\x4c\x5c\x4c\x98\xac\x33\x83\xbd\x80"
-  "\x0b\x06\x26\x99\xd8\xd6\xa5\x16\xa8\x73\xbc\x85\xfc\x7d\x6c\xa3"
-  "\xf2\xfd\x02\x48\xb3\x12\x7f\xdc\x13\x0f\xcb\x80\x18\x13\xeb\xf3"
-  "\x6d\x09\xe4\x77\x56\x87\xb7\xf7\x90\xf1\x03\xef\x62\x0d\x9e\xe1"
-  "\xe6\x33\x97\xef\xbf\xf9\xa5\x8c\x25\xd5\x77\x83\xec\xd4\x84\x71"
-  "\x76\xde\xc3\xfb\x14\xf5\xc0\x89\x5e\xb8\x9f\x66\x52\x3e\x61\x36"
-  "\xda\x06\x7b\x1d\x4c\xe0\xf6\xb3\x34\xb6\xaf\x3b\x0c\xd7\x3d\xc0"
-  "\xed\x0f\x89\x7b\xa6\xe1\x9e\xab\x80\x1b\x02\xe9\xea\x8f\xe2\x09"
-  "\x71\xd4\x45\x6c\xd4\xe2\x79\xea\xb8\x85\x8b\xa3\x97\xae\x88\x53"
-  "\xdf\x11\x35\x94\xcc\x5e\xba\x54\xbd\x78\xde\x92\x37\xd4\xe2\x33"
-  "\x0f\xa9\xa3\x16\x2e\x9f\x37\x7f\x51\xf4\x84\xc5\xaf\x68\x87\x62"
-  "\x87\x51\x54\x8f\x91\x58\x17\xdb\xba\xc3\xe3\x4b\xf4\x84\xe4\x8c"
-  "\x20\x4a\xac\x17\xdc\x4f\x27\xec\xa9\x97\xb5\x99\x35\x31\x90\x27"
-  "\x09\x38\x70\x63\xe2\x60\xc8\xfb\x59\x51\x29\xd4\xab\x04\xea\x0d"
-  "\x75\xc4\x3a\xef\x17\xea\x2c\x60\x22\x09\x31\x91\x78\x06\x30\x78"
-  "\xf8\xb8\x9f\x79\xf0\x53\x2c\x1b\x8e\xed\x33\x81\x9d\x28\x4e\x28"
-  "\x6a\x27\xa0\x5f\x02\x0e\xa8\x80\x6b\xcd\x02\xc6\xf0\x5a\x36\x2b"
-  "\x52\xdb\x8e\x76\xc2\xc6\x3c\x4a\x6d\xaa\xb6\xe1\x59\x8d\x82\xd0"
-  "\x3d\xfd\x6a\xc7\xd9\xf7\xf4\xab\xe5\x6c\x01\xea\xd1\x06\xe9\x53"
-  "\x0c\x8a\xc1\x3a\x4c\xc7\xbd\x25\x71\xaf\x57\xac\x33\xb4\x0b\xfc"
-  "\x22\x5b\xcd\xae\xe5\xb1\x9f\xb6\xd7\x68\x4b\xfb\x5f\xff\x7a\xe5"
-  "\x79\x12\x6a\x61\x3b\xd9\xf5\x7b\x8d\x75\x26\x13\xf1\x4b\xd1\xbe"
-  "\xc2\x0e\x3a\xfc\x88\x9f\x65\x61\x34\xee\x49\x6e\x5b\xff\xbf\xfe"
-  "\xec\xfa\xda\xca\x67\xef\x22\x2a\x28\x3b\x4f\xb4\xb7\xa0\xd2\x33"
-  "\xfd\xd7\x72\xfa\x47\x3d\x42\x7d\x78\x3d\xd6\xb6\x7e\x14\xd7\x5d"
-  "\x8f\x5d\xf8\xdb\x6e\x23\x1f\x03\x16\x58\x6f\x9d\x31\xd4\x4a\xe5"
-  "\x88\xb6\x7b\x36\x29\x86\x4c\xe4\x64\x77\xa4\xcc\x96\xa5\x6b\xb0"
-  "\x65\x64\x03\x57\xe8\x4c\x20\xb3\xb4\xac\x95\x44\xfd\xb2\x55\x45"
-  "\x32\xcf\x93\x40\x63\xa6\xce\xe8\xa3\x48\x56\x40\x6c\xc1\x80\xdf"
-  "\x08\x04\xce\x08\xe4\xed\x3d\x0d\xe5\xf8\xcf\x36\x42\x66\x2c\x27"
-  "\xe4\x87\x29\x64\x40\x09\x5c\xe7\x59\x7b\x8e\xd0\xf5\x9f\xd6\x1d"
-  "\x19\x57\x0a\xd7\xe2\xde\x90\x1e\x5e\xbf\xcb\xa5\xdd\x75\xb5\x3b"
-  "\x5b\xeb\xbc\xdd\x75\x79\xb6\xac\xec\x30\x68\x77\x1a\x9b\x91\x1d"
-  "\xd7\xbd\xdd\xd9\x5a\xda\xee\x81\x67\xfa\xbf\xdd\x75\x74\xcf\xc5"
-  "\x75\x75\x01\xf2\xda\x5d\xe7\x72\xfc\x4f\xd4\x6e\x17\xfa\xae\xd7"
-  "\x41\xbb\x41\xdf\x7a\xd0\x77\xb6\x13\x7d\x67\xf3\xfa\x1e\xd6\xdc"
-  "\xff\xed\xae\x8f\xa0\xed\xae\x1f\x29\xaf\xdd\xf5\x2e\xf9\xcf\xde"
-  "\x6e\xbd\x0b\x7d\x37\xa4\xd9\xb2\xf4\xa0\x6f\x3d\xe8\x5b\xef\x44"
-  "\xdf\x7a\x5e\xdf\xc3\x3f\xef\xff\x76\x37\xd0\xf1\xff\x75\x0d\xde"
-  "\xf2\xda\xdd\x90\xeb\x46\xbb\x5d\xe8\xfb\x68\x32\xb4\x1b\xf4\x9d"
-  "\x03\xfa\xd6\x3b\xd1\xb7\x9e\xd7\xf7\x83\xe9\xfd\xdf\xee\xa3\x74"
-  "\xfd\x9b\x75\x47\x95\xf2\xda\x7d\x34\xa3\xf7\x76\xe7\xb8\xd0\xf7"
-  "\xe7\xf1\xb6\xac\x1c\xd0\x77\x0e\xe8\x3b\xc7\x89\xbe\x73\x78\x7d"
-  "\xcf\x79\xa2\xff\xdb\xfd\xf9\x54\xbe\xdd\x16\x79\xed\xfe\x3c\xb5"
-  "\xf7\x76\xeb\xcc\xb6\x8c\xee\x9c\x5e\x1f\x3f\x89\xdc\x73\x1e\xdb"
-  "\xff\xbf\xad\xac\x8f\xce\x3c\x2c\x25\x59\x61\xf1\xd6\x59\x86\x35"
-  "\x11\x06\xfa\x7e\x31\x7e\x06\x32\x04\xda\x1a\xc3\x66\x6d\xd2\xe1"
-  "\xa7\x0d\xca\xb1\x00\xf7\x5b\xbd\x75\xa6\x8e\x8c\xc8\xb4\x0d\x0b"
-  "\x88\x3a\xc9\x48\x54\x75\x89\x06\x92\xa8\x65\x8d\x75\xe4\x5b\xe2"
-  "\x63\x20\x0c\x8e\x63\x1d\x6e\xab\x22\x4b\x62\x59\x16\xca\x3e\x8a"
-  "\xfd\xc5\xac\x13\x24\x10\x62\xe2\x64\x16\xfc\x87\xce\x46\xd4\x50"
-  "\x7e\x20\xca\x12\xca\xd6\xfb\xcd\x26\x8a\xff\x99\x6f\x26\x28\x4f"
-  "\x94\x2d\xf4\x2d\x03\x39\xb9\x9a\x08\xf9\xc3\x1c\x2a\xd7\xc2\x05"
-  "\x9e\xca\xf5\x7f\x8b\x68\x5c\x99\xad\xaa\x37\x74\x10\x88\x2d\x55"
-  "\xf8\x5e\x33\xa4\x87\xd7\x69\xcf\x40\x3f\xe4\x73\x0b\x9b\x99\x0d"
-  "\xfd\x4d\x9d\xd1\xc3\x72\x5d\x3e\xff\x26\xe2\xd3\x78\xf0\x15\xdd"
-  "\xb0\x66\x97\xf7\x17\xe1\xac\x4f\x76\x3c\x95\x77\x76\xc2\xb0\xa6"
-  "\x81\x67\x9c\xcb\x3b\x3b\x1e\xe4\x9d\x66\xf5\xce\x8e\x73\x5f\xde"
-  "\x5f\x3c\x2e\x95\x77\x76\xd8\xa5\x91\xf7\x17\xde\xbc\xbc\x75\x52"
-  "\x79\x1f\xab\xa1\xf2\x3e\xb6\x08\xe4\x9d\x6c\x03\x5f\xe9\x61\xb9"
-  "\x2e\xdf\x7f\x14\xc9\x1b\xf0\xdd\xdd\x87\xd9\xe5\xfd\xaf\x1a\x90"
-  "\x37\x8f\xef\x6c\xc0\xf7\xb0\x66\x17\xf2\x06\x7c\xeb\x01\xdf\xd9"
-  "\x1e\xe0\xfb\x5f\x1f\x38\xc8\xfb\x12\xe1\xfb\x5f\xfc\xfe\x4f\x7a"
-  "\x07\x7c\xff\x6b\x12\x95\xf7\x17\x4d\x6c\xa6\x1e\xf0\x9d\xed\x21"
-  "\xbe\xff\x75\xcc\x0d\xff\x01\xf8\xee\xee\x3b\xed\xf2\x6e\x9c\xc4"
-  "\xfa\xe8\x79\x7c\xeb\x01\xdf\xc3\x3f\x77\x2e\x6f\x3d\xe0\x5b\x0f"
-  "\xf8\xd6\x7b\x80\xef\xc6\x5b\xa5\xf2\xd6\x5f\x22\x7c\xff\xbb\x8d"
-  "\x97\xb7\x03\xbe\xff\x5d\x41\xe5\xfd\xef\x69\x20\x6f\xc0\xb7\xde"
-  "\x43\x7c\x37\x4e\x75\x43\xde\x80\xef\xee\x3e\xdb\x2e\xef\x2f\x2b"
-  "\x40\xde\x3c\xbe\xf5\x80\xef\x07\xd3\x5d\xc8\x1b\xf0\x9d\x03\xf8"
-  "\xd6\x7b\x80\xef\x2f\xb3\x1d\xe4\x7d\x89\xf0\xfd\x25\x8d\xff\x32"
-  "\x72\x1c\xf0\xfd\xa5\x3f\x95\x77\xe3\x7e\x36\x33\x07\xf0\xad\xf7"
-  "\x10\xdf\x5f\xee\x73\x23\x4e\x00\x7c\x77\x8f\x15\xec\xf2\xfe\xda"
-  "\x9f\xf5\xc9\xe1\xf1\x9d\x03\xf8\x9e\xf3\x84\x73\x79\xe7\x00\xbe"
-  "\x73\x00\xdf\x39\x1e\xe0\xfb\x6b\x85\x54\xde\x39\x97\x08\xdf\x5f"
-  "\xd5\xf2\xf2\x76\xc0\xf7\x57\x69\x54\xde\x5f\x8d\x07\x79\x03\xbe"
-  "\x73\x3c\xc4\xf7\xd7\x2e\xdf\xff\xed\x29\x3e\x59\x5e\x4c\xbc\xa4"
-  "\x32\x6f\xca\xb8\x78\x31\x4a\xd3\x8a\xcb\x13\xa3\x34\x05\x3b\x8f"
-  "\x51\xbe\xb6\x50\x99\x7f\x5d\x26\x2f\x46\x69\xca\x93\x13\xa3\x74"
-  "\x97\xf9\x7f\xc8\xc5\x8b\x53\x8e\xff\x78\x79\xe2\x94\xe3\xfb\x9c"
-  "\xc7\x29\xc7\xb5\x54\xe6\xc7\x47\xca\x8b\x53\xfe\xe3\x2d\x27\x4e"
-  "\xe9\x2e\xf3\x6f\xe2\x2e\x5e\xac\xf2\xcd\xdc\xcb\x13\xab\x7c\xa3"
-  "\x71\x1e\xab\xfc\xa7\x85\xca\xfc\x3f\x69\xf2\x62\x95\x6f\x92\xe5"
-  "\xc4\x2a\xdd\x65\x6e\x68\xbd\x78\xf1\x8a\xe1\xe8\xe5\x89\x57\x0c"
-  "\x45\xce\xe3\x15\x03\xdf\xff\xf9\xc6\x22\x2f\x5e\x31\xb8\xd1\xff"
-  "\xe9\x1e\xaf\x74\x97\x79\x73\xc4\xc5\x8b\x59\x9a\x9f\xbc\x3c\x31"
-  "\x4b\xb3\xca\x79\xcc\xf2\x6d\x2d\x95\xf9\xb7\x5a\x79\x31\x4b\x73"
-  "\x8c\x9c\x98\xa5\xbb\xcc\xbf\x6b\xb8\x78\x71\xcb\x77\x1f\x5e\x9e"
-  "\xb8\xe5\xbb\x54\xe7\x71\xcb\x77\xc1\x54\xe6\xcd\x2d\xf2\xe2\x96"
-  "\xef\x9a\xe4\xc4\x2d\x28\x6b\x94\x39\xc6\x2a\x54\xe6\x27\xca\x58"
-  "\x5f\x5d\x43\x27\xc4\x23\x3e\x20\x77\x9f\x36\xc2\x14\xa3\xcc\x1b"
-  "\xa9\xcc\xad\xbe\x9b\x74\x20\x9f\x18\x94\x19\xd7\x8e\x9f\xfc\x7d"
-  "\xad\x19\x3a\x0b\xcb\x10\x68\x8b\x17\x39\xa1\x68\xd9\x6d\x59\x4b"
-  "\x7c\xd5\x89\x29\xf0\xfd\x04\xb7\x7e\xa6\x3a\x71\xdd\x71\x68\xe3"
-  "\x00\x9c\xa3\xb0\x64\x46\x06\x5a\x7d\x72\x2b\x4f\x28\xbe\x3f\xc5"
-  "\x8e\x89\x08\xec\x84\x58\x82\x7d\xdd\x7f\x64\x7d\x5b\x25\xa9\xb7"
-  "\x7c\x46\xea\x1a\xff\x4a\x6c\xbe\x9b\xf4\x13\x2d\x44\xc3\xfe\xa4"
-  "\x19\x59\x1b\x67\x20\xd6\x57\xfc\xbd\xeb\xe3\x6b\x00\x17\x7b\x49"
-  "\x68\x2b\x7b\x9e\xfd\x4e\xe3\xdd\xe9\x93\x6f\xb4\xfa\x6c\xd2\x5a"
-  "\x33\x0b\xaa\x2c\x3e\xf9\x86\xdd\x2b\x0d\x8c\xb7\x99\x68\x16\xb5"
-  "\xb0\x6c\xd6\x7c\xa2\xcc\x6a\x26\x5e\x1b\xe7\x13\xef\x8d\xcd\x44"
-  "\x55\xdb\xd2\x48\x8e\x9c\xac\x21\x47\xce\x7c\x49\x8e\x9c\x87\xa3"
-  "\x03\x0e\x1b\x1c\xc9\x5f\x92\x5a\xe8\x25\x4d\x3f\x45\x48\x52\x0b"
-  "\x6b\xfc\x4d\x13\x19\x59\x6b\x69\x24\xf8\x1c\xef\x69\xc5\xf7\x29"
-  "\xde\x91\x64\x24\xfb\x9d\x3f\x61\x5f\xf1\x67\xe0\x9c\x12\xd3\xeb"
-  "\x2d\x46\x52\xdb\x62\xc6\xf3\x91\x70\x5e\x99\xd4\x02\xe5\xdb\x6a"
-  "\x70\xbd\x38\x63\x6d\xf2\xa7\xd0\x3e\x95\x1a\xfc\xa6\x97\x10\x93"
-  "\x65\x75\x90\xc0\x8d\xa0\x66\xc4\x4c\x28\x4b\x31\x53\xda\xe1\x29"
-  "\x66\xbe\xa7\xeb\x9f\xbd\xee\x3f\x02\xe4\x3d\xda\xf6\x7a\xb8\x6a"
-  "\xc6\x97\xdf\xb0\xf8\x9c\x16\xce\xcf\xd4\x99\x3e\x23\xf5\xa9\x36"
-  "\x12\xfa\x06\x21\xd3\xac\x84\xa0\x4c\x70\x2e\x79\x86\x96\xf8\xe1"
-  "\xf3\x63\xb6\x9f\x34\x23\xea\x5b\x8c\xe4\x4d\x0b\xd4\xf5\xb4\xb9"
-  "\xab\xae\x75\xa9\x75\x04\xce\x8d\xae\x8b\x31\x10\x6f\x2d\x51\xa1"
-  "\x9c\x2d\x19\x3a\xf3\x8c\x56\x32\x64\x89\x89\x65\x51\xc6\x28\x5b"
-  "\x94\x33\x96\x27\xc8\xbe\x3e\xca\x48\x92\xcc\x44\x55\x9f\x08\x9f"
-  "\xf1\xac\xb1\x9e\xfc\x42\xa0\x8e\xb9\xac\x8f\x4a\x0d\xf8\xc8\x45"
-  "\x4c\x18\x14\x2d\xe5\x80\x83\x11\xec\xba\x96\xf0\x12\x68\x2f\xce"
-  "\xe1\x7b\xd6\xe6\x13\xee\xcc\x7f\x74\x8b\x09\xed\x78\xce\x8e\xa7"
-  "\x78\xfe\x51\xcb\xfa\x66\x87\x75\x42\xac\x47\xf1\x3c\xf0\x4c\xef"
-  "\x78\xce\x4e\xb0\xe3\xf9\x87\x37\xed\x78\xfe\x71\x9e\x6b\x3c\xb7"
-  "\x1e\xe0\xf1\xac\xbb\x32\xf1\xdc\x3a\xb3\x67\x3c\xb7\x06\xf6\x80"
-  "\xe7\x34\x21\xde\xed\x1f\x3c\xb7\xa6\x5d\x3a\x3c\x67\xc7\xcb\xc3"
-  "\x73\x6b\x94\x14\xcf\x3f\xc4\x51\x3c\xff\xa0\x91\x87\xe7\x1f\x5d"
-  "\xee\x7f\xd0\x53\xbc\x2d\xc2\x33\xcf\xcf\x6d\xc1\x80\x67\xe0\xe7"
-  "\x6c\x9e\x9f\x87\x35\xbb\x81\x67\x11\x3f\x9f\x9c\x6e\xc7\x73\xdb"
-  "\xbd\xae\xf1\xfc\x53\x26\xc5\xb3\xfe\x0a\xe5\xe7\x9f\x6e\xed\x19"
-  "\xcf\x3f\x11\xd7\x78\xd6\x7b\x09\x7d\x89\xfe\xc1\xf3\x4f\xe1\x97"
-  "\x10\xcf\x32\xf9\xf9\xa7\x20\x29\x9e\x4f\x4e\xa5\x78\xfe\xd1\x2c"
-  "\x0f\xcf\x6d\x2e\x9f\x7f\xee\xa9\x2f\x63\xc7\xb3\x9e\xe7\xe7\x9f"
-  "\x55\xac\xaf\x1e\xf8\x59\xcf\xf3\xf3\xf0\xcf\x7b\xc7\xb3\x5e\xc4"
-  "\xcf\xa7\xc6\xd8\xf1\xfc\xb3\xc2\x35\x9e\x4f\xcf\xe5\xf1\x7c\x85"
-  "\xf2\xf3\xa9\x5f\x7a\xc6\xf3\xa9\x86\x1e\xf0\x9c\x26\xf4\xd3\xfa"
-  "\x07\xcf\xa7\x35\x97\x0e\xcf\x7a\x99\xfc\x7c\x5a\x29\xc5\xf3\xa9"
-  "\x91\x14\xcf\x6d\x35\xf2\xf0\xfc\xb3\xcb\xfd\x7f\x7a\xea\x27\x8a"
-  "\xf0\xcc\xf3\xf3\x2f\x06\xc0\x33\xf0\xb3\x9e\xe7\xe7\x07\xd3\xdd"
-  "\xc0\xb3\x88\x9f\x7f\x3e\x65\xc7\xf3\x2f\x47\x5d\xe3\xf9\x97\x09"
-  "\x14\xcf\x39\x57\x28\x3f\x1b\x3f\xea\x19\xcf\xc6\x32\xd7\x78\xce"
-  "\xf1\x12\xfa\xc0\xfd\x83\x67\xa3\xf9\x12\xe2\x59\x26\x3f\x1b\x8f"
-  "\x49\xf1\xfc\x73\x0b\xc5\xf3\xcf\x79\xf2\xf0\xfc\x8b\xcb\xf5\xdf"
-  "\x7a\xea\x83\xdb\xf1\x9c\xc3\xf3\xb3\xa9\x92\xf5\xcd\x01\x7e\xce"
-  "\xe1\xf9\x79\xce\x13\xbd\xe3\x39\x47\xc4\xcf\x67\x0e\xd8\xf1\x6c"
-  "\xda\xe2\x1a\xcf\x67\xad\x3c\x9e\xaf\x50\x7e\x3e\x9b\xdd\x33\x9e"
-  "\xcf\x6a\x7b\xc0\x73\x9a\x30\xbe\xd0\x3f\x78\x3e\x5b\x73\xe9\xf0"
-  "\x9c\x23\x93\x9f\xcf\x96\x4b\xf1\x7c\x66\x1f\xc5\xf3\x99\x18\x79"
-  "\x78\x36\xb9\xdc\xff\xce\xb3\xf1\x8d\xf6\x4a\x1c\xdf\xe8\xc0\xf1"
-  "\x0d\xfb\xb3\x7f\x31\x7e\x0d\x14\xcf\x9d\x80\xe7\x42\x31\x9e\xbf"
-  "\x76\x1c\xdf\x38\x97\x69\xeb\xc2\x73\x7b\x37\x3c\xdb\x00\xcf\x9d"
-  "\x1c\x9e\xcf\x7f\x28\x8c\x6f\xd4\xb7\x95\x01\x4e\x4e\x92\xfa\x30"
-  "\xc0\x72\x16\x8f\xe5\xaf\x01\xcb\x20\x43\x1b\xc8\xb8\xb6\xa9\x91"
-  "\x84\x1a\xa9\x2c\x3b\x40\xc6\x36\x31\x8e\x3b\x5a\x19\xc4\x2f\xe2"
-  "\x56\xc0\xf0\x91\x25\x80\xdd\xd8\xa3\xe4\xc8\x4a\x38\x56\xc3\x91"
-  "\x08\x07\x39\x4a\x6a\x5b\x01\xbb\x0b\xc5\xd8\x6d\xe0\xb1\x7b\x7e"
-  "\x7a\xcf\xd8\x3d\x3f\xfe\xd2\x8d\x65\x9c\xa7\xe3\x5f\x5f\x87\xab"
-  "\x42\x67\x7e\xc3\xd6\xc7\x37\xf2\xf8\x3c\x49\x42\x2d\xc4\x8f\x9d"
-  "\xa3\x19\xe1\x1d\x4e\x54\x6b\xac\x84\xc9\x9c\x4f\x54\x99\x5f\x41"
-  "\xbb\x05\xfb\x6d\x26\xde\x9f\x99\xff\x4a\x6a\xcf\x34\x92\xda\xf3"
-  "\x9f\x92\x5a\x1b\x1c\x27\xe1\x80\xba\x86\x46\x8b\xdb\x6d\xe4\xdb"
-  "\xdd\xfe\x24\x94\x35\xce\x75\xbb\xdb\xc7\x71\xed\x8e\x82\x76\x77"
-  "\xd8\xdb\x5d\x0f\x76\x00\xfa\x19\x6d\xe3\xc7\x43\x42\x8d\x64\xc8"
-  "\x52\x0b\xcb\x76\xf0\xf8\x47\xfd\x7c\x76\xcc\x4c\x42\xb5\xa0\xb3"
-  "\x57\x00\xff\x2d\x15\x24\x29\x01\xf0\xdf\x61\x46\xdc\x19\xeb\x93"
-  "\x2f\x00\xfe\xcf\x47\xb2\x20\xbf\x4e\xc4\xff\xd7\x88\xff\x73\xa9"
-  "\x36\x0e\xff\xe7\x26\xc9\xc3\x7f\xbb\x1b\xf8\x77\x67\x3c\xa4\xa3"
-  "\x12\xc7\x43\x3a\x70\x3c\xc4\xfe\x0c\x68\x2f\xf8\x17\x8f\x87\x98"
-  "\x45\xf8\xef\xe8\x01\xff\x17\x04\xfc\xeb\x2e\x3f\xfe\x2f\xf4\x82"
-  "\xff\x0b\x3d\xe1\xbf\x9f\xc7\x3e\x2e\x5c\x42\xfc\x77\xf4\x82\xff"
-  "\x0e\x37\xf0\x9f\x1d\x2f\x0f\xff\x17\x1c\xf0\x6f\xe6\xf1\x6f\x96"
-  "\x89\xff\x0e\x77\xf0\xef\xc6\xf8\x89\x15\xf1\x0f\xfc\x9f\x6d\x12"
-  "\x3d\x0b\xdc\x1b\xfe\x45\xfc\xdf\x29\xc2\xbf\xb5\x07\xfc\x5b\x3e"
-  "\x14\xc6\x4f\x2e\x3f\xfe\x2d\xbd\xe0\xdf\xd2\x03\xfe\xfb\x7b\xac"
-  "\xc4\x72\x09\xf1\x6f\xed\x05\xff\x56\x77\xf0\x2f\x93\xff\x2d\x0e"
-  "\xf8\xef\xe4\xf1\xdf\x29\x13\xff\x56\x37\xf0\xef\xc6\x78\x0b\x43"
-  "\x2a\x71\xbc\xa5\x03\xc7\x5b\xec\xcf\x84\xf7\x82\x7f\xf1\x78\x8b"
-  "\xcd\x8e\x7f\x86\xf4\x80\x7f\x56\xc0\xff\x15\xc0\xff\x6c\x2f\xf8"
-  "\x67\x7b\xc2\x7f\x3f\x8f\xad\xb0\x97\x0e\xff\x0c\xe9\x19\xff\x0c"
-  "\x71\x03\xff\x7a\x99\xfc\xcf\x3a\xe0\xdf\xc6\xe3\xdf\x26\x0f\xff"
-  "\x0c\x71\x07\xff\xbd\x8f\xcf\x30\x03\x10\xff\xc0\xff\x7a\x93\xe8"
-  "\xdd\x80\xde\xf0\x6f\xe7\x7f\x46\x21\xc2\xff\x00\xd7\xf8\x67\x98"
-  "\x0f\x85\xf1\x99\xcb\x8e\x7f\x86\xe9\x19\xff\x0c\xd3\x03\xfe\xfb"
-  "\x79\x2c\x86\x61\x2e\x21\xfe\x07\xf4\x82\xff\x01\xee\xe0\x5f\x1e"
-  "\xff\x33\x8c\x14\xff\x8c\x82\xe2\x3f\x5d\x21\x13\xff\x03\xdc\xc0"
-  "\xbf\x1b\xe3\x39\xcc\x20\x6e\x3c\xa7\x03\xc7\x73\xec\xef\x88\xf4"
-  "\x82\x7f\xd1\x78\x0e\xa3\x14\xe1\x7f\x50\x0f\xf8\x1f\x28\xe0\xff"
-  "\xf2\xf3\x3f\x33\xb0\x17\xfc\x0f\xec\x09\xff\xfd\x3b\x76\xc3\x0c"
-  "\xbc\x84\xf8\x1f\xd4\x0b\xfe\x07\xb9\x81\xff\x1c\x79\xfc\xcf\x0c"
-  "\x74\xc0\xbf\x92\xc7\xbf\x52\x26\xfe\x07\xf5\xcf\xf8\x0f\xe3\x15"
-  "\x8e\xe3\x3f\x36\x6f\x9d\xa9\xb3\x28\x22\xd0\x96\x91\x6f\xf4\x53"
-  "\xa8\x89\xc5\x3b\xb7\xb2\x3e\xce\x44\x66\x9c\x03\x9d\x68\xcf\x91"
-  "\x97\xce\xa9\x70\xbf\x40\x03\x0b\xfd\x7f\xc9\x3b\xa2\x70\x58\x32"
-  "\x54\xea\x8d\x4b\x88\xd2\xea\xbb\x49\x8f\x69\xf5\x27\xcc\x04\xdb"
-  "\xfc\x26\xca\xe0\xa4\x5d\x06\x38\x06\xc7\xfe\xac\x51\x95\xac\x85"
-  "\x3c\x1d\x06\xd2\x02\x78\xa9\x6d\x31\x80\xec\x57\x73\xd8\x42\x5d"
-  "\x9c\x60\x06\x9b\x4b\x4f\x13\xa5\xe5\x3b\xff\xd1\xa0\xe3\x91\x3e"
-  "\xab\x88\x22\xa0\x85\xb5\xa1\x2e\x51\x47\xa8\x57\xf5\x6a\x96\x85"
-  "\x7a\xcf\xac\x03\x7c\x5b\xbe\xd3\x8c\x2e\x81\x7c\xfd\x3e\x2e\xc3"
-  "\x78\x71\xf3\x1f\x06\x66\xb0\xb1\xb6\x09\x64\x99\x3e\x58\xa6\x9e"
-  "\xbc\xdc\x79\xff\xa5\xf7\x71\x0a\x66\x28\xc1\x71\x0a\x9b\x77\x76"
-  "\x9c\x7b\x7a\xca\x8e\x97\xbc\xd3\xda\xef\x7a\x1a\x52\xe6\x9e\x9e"
-  "\x86\x5c\x70\xd0\x53\xff\x8e\x1f\x30\x43\xe8\x7a\x30\xcc\x90\x3c"
-  "\xaa\x27\x2f\x83\x3c\x3d\x0d\x95\xf5\xfc\x6f\xb7\xfe\x34\x33\xac"
-  "\x02\xfb\xd3\xa0\x27\x37\xed\x29\xdb\x2c\x79\x07\xb7\xdf\xf5\x34"
-  "\x2c\xc4\x3d\x3d\x0d\xdb\x22\xd5\x53\x3f\xf7\x73\x99\x61\x74\x3f"
-  "\x68\x66\x58\x30\xd5\xd3\xd0\x34\x79\x7a\x1a\xe6\xc6\xfb\x1f\xee"
-  "\xf4\xfb\x7c\xc2\xb0\xdf\x67\x83\x7e\x9f\x7b\x7a\xd2\xc7\x4b\xde"
-  "\x19\xee\x77\x3d\x79\x1b\xdd\xd3\x93\xcf\xd3\x0e\x7a\xea\xdf\xfe"
-  "\x18\xe3\x33\x92\xea\xc9\xbb\x95\xea\xc9\x3b\x50\x9e\x9e\x7c\x22"
-  "\xfa\xa7\x7f\xe2\x6b\xc6\xfe\x09\xe8\xc9\x4d\x7b\xd2\x9b\x25\xef"
-  "\x38\xf7\xbb\x9e\x7c\xf3\xdc\xd3\x93\xef\x2f\x52\x3d\xf5\x77\xbf"
-  "\xc1\x77\x3f\xd5\x93\xaf\x8e\xea\xc9\xa7\x51\x9e\x9e\xfc\x5c\xee"
-  "\xff\xe9\x59\x1c\xad\x2a\xc3\x38\xda\x06\x71\xb4\x7b\x7a\xca\x89"
-  "\x97\xbc\x93\xdd\xef\x7a\x52\x05\xbb\xa7\x27\x55\xbe\x83\x9e\xfa"
-  "\x39\xbe\x55\x45\x51\x3d\xa9\x26\x51\x3d\xf9\x25\xcb\xd3\x93\xca"
-  "\x8d\xe7\x3f\x9d\xbf\x87\xd5\x3d\xe6\x1b\x31\xed\xca\x8a\xf9\x86"
-  "\xb7\xb9\xa7\xab\x11\x4f\x5e\xdc\x98\x6f\x84\x8a\xea\x6a\x78\x0b"
-  "\xd5\xd5\xf0\xf1\xf2\x74\x35\x22\x5c\xee\xfb\x5b\xdd\xe3\xbe\x1b"
-  "\xcc\x57\x56\xdc\x77\x83\x9b\xfc\x77\xc3\x2f\x17\x37\xee\xbb\x81"
-  "\xe7\xbf\x1b\x78\xfe\x1b\x21\x93\xff\x46\xba\xc1\x7f\xce\xdf\xfb"
-  "\xea\x1e\xfb\xdd\x58\x7e\x65\xc5\x7e\x37\x4e\x75\x4f\x57\x37\x16"
-  "\x5f\xdc\xd8\xef\xc6\x18\xaa\xab\x1b\xa7\x50\x5d\x8d\x4c\x95\xa7"
-  "\xab\x1b\x5d\xee\xff\xd2\xdb\xfb\x62\xdd\xe3\xbf\x9b\xae\xb0\xf8"
-  "\x6f\x94\x9b\xf1\xdf\x4d\x17\x39\xfe\xbb\x89\x8f\xff\x46\xf1\xf1"
-  "\xdf\x28\x99\xf1\xdf\x4d\xb2\xe2\x3f\x07\x5d\xf1\x76\xe5\x6f\xb9"
-  "\xb2\x62\x40\xff\x22\xf7\x74\xe5\x7f\xee\xe2\xc6\x80\xfe\xd5\x54"
-  "\x57\xfe\xb9\x54\x57\x37\x35\xc9\xd3\xd5\xcd\x2e\xf7\x3f\xec\xed"
-  "\xfd\xb4\xee\x71\xe0\xe8\x8a\x2b\x2b\x0e\x1c\xed\x66\xff\x77\xf4"
-  "\x96\x8b\x1b\x07\x8e\xe6\xfb\xbf\xa3\xf9\xfe\xef\xcd\x32\xfb\xbf"
-  "\xa3\xdd\xe8\xff\xba\x33\xee\x37\xc6\x0b\x63\x40\x6b\x86\xce\xe4"
-  "\x07\xf2\xf7\x8b\x27\x4c\x47\x00\xe8\xcb\x1b\xf4\x95\xa2\x26\x9d"
-  "\x19\xa0\x2f\xa3\x85\xcc\x58\xf6\x0d\x5b\xd7\x66\x25\x1d\xa0\xab"
-  "\x0b\x10\x07\xd6\x1b\x5b\xf1\x1d\xbd\x87\x9b\x99\x80\x2d\x73\x96"
-  "\xa9\x08\xea\x0b\xe5\x6f\xf5\x56\xa9\x59\xd0\x17\xa7\x3f\xef\x82"
-  "\x2a\x4b\xc6\x26\xed\xf4\x53\xdf\xb0\x4b\x0d\x2c\x7b\x24\xc6\x8c"
-  "\x6b\x47\x06\x1e\x89\x69\x24\xa1\x2d\x64\x88\x7a\x16\xea\x25\x60"
-  "\x26\xa6\xd7\x1b\x1b\x09\xae\xfb\xc9\x8d\x81\x7f\xa3\x19\x69\xf9"
-  "\xb7\xc6\x1b\xd7\x6f\xc2\xf7\x0a\x85\x35\x9a\xea\x4f\xe6\x71\xfa"
-  "\x77\x1c\x53\xe5\xf4\xff\x6f\x8d\xaa\x10\xdf\x4f\xec\xf7\x58\x30"
-  "\x80\x1b\xff\xb3\x7d\xe3\x3f\x5a\xa8\xe3\xd2\x45\x2c\x0b\x75\x1c"
-  "\x51\x67\x32\x12\xac\x67\x9d\xa9\x9a\x24\xc5\x11\x55\x5d\x47\x2b"
-  "\x49\x34\xb1\xc6\xba\xe4\x1f\x49\xe8\x39\x9c\x17\x40\x3c\x05\xe4"
-  "\x53\x7d\xff\xea\x90\xed\x1b\xcd\x68\x28\x4f\x57\xd7\x40\x88\x5f"
-  "\x0a\xc8\xda\x42\x18\xee\x7d\x4d\x86\x78\x81\xbc\x62\xea\x93\x9b"
-  "\x09\xc8\xce\x58\x6f\xf9\x0a\xe5\x19\x03\xe7\xa7\x74\xcd\x37\xf8"
-  "\x6e\x3a\x83\x69\x28\x5b\x7c\xce\xb4\x5e\x6b\xe4\xf2\x08\xe7\xa9"
-  "\xee\x92\x49\x7d\x7c\x07\xa9\xb3\x10\x02\xf7\xd3\x1e\x0e\x6f\x04"
-  "\x7c\xfd\x4a\x26\x6f\x8f\x19\xd9\x3f\xe3\x95\xb7\xc4\x60\xdc\x6a"
-  "\xcd\xc8\x8e\xa3\x75\x1c\x78\xa6\x77\x7c\x65\xc7\xdb\xf1\x75\x8b"
-  "\xa2\x6f\xf8\x1a\xfb\x41\x3f\xe3\xab\x9f\xe3\xd7\xb1\x09\x7d\xc3"
-  "\xd7\xd8\x0b\x14\x5f\x63\xc7\x51\x7c\x8d\x35\xda\xf1\x35\xf0\xcc"
-  "\xc5\xc3\xd7\x98\x06\x8a\xaf\x31\x3a\x79\xf8\xba\x25\xae\x7f\xc6"
-  "\x59\x6f\xad\xc1\x58\x1b\xf0\xc5\xf3\xd7\xb0\x66\x37\xf0\x25\xe2"
-  "\xaf\x5b\xe7\xf5\x0d\x5f\xb7\x0e\xef\x5f\x7c\xf5\x77\xcc\xad\x6e"
-  "\xea\x1b\xbe\x6e\x7d\x81\xe2\x4b\x9d\x4a\xf1\x75\x6b\x98\x1d\x5f"
-  "\xc3\x9a\x2f\x1e\xbe\xd4\x81\x14\x5f\xb7\x18\xe5\xe1\xeb\x56\x59"
-  "\xeb\x5f\x75\xef\x1f\x8c\xd3\x60\xff\xc0\x9a\xa1\xe7\xf9\x6b\xf8"
-  "\xe7\xbd\xe3\x4b\x2f\xe2\xaf\xdb\x3f\xea\x1b\xbe\x6e\x5f\xd6\xcf"
-  "\xf8\xea\xe7\x7e\xc2\xed\x53\xfa\x86\xaf\xdb\x3f\xa4\xf8\xba\xad"
-  "\x85\xe2\xeb\xf6\x4a\x3b\xbe\x86\x7f\x7e\xf1\xf0\x75\x9b\x8e\xe2"
-  "\xeb\xb6\x30\x79\xf8\x1a\xe7\x7a\xfd\x67\x8f\xc6\xb5\xef\x4c\xc3"
-  "\x3e\x0d\xe0\x8b\xe7\xaf\x07\xd3\xdd\xc0\x97\x88\xbf\xee\xbc\xb5"
-  "\x6f\xf8\xba\xe3\x68\xff\xe2\xab\xbf\xfb\x36\x77\x14\xf5\x0d\x5f"
-  "\x77\xde\x4c\xf1\x75\xc7\x54\x8a\xaf\x3b\x55\x76\x7c\x3d\x98\x7e"
-  "\xf1\xf0\x35\xce\x48\xf1\x35\xae\x52\x1e\xbe\xee\x74\x63\xfd\x57"
-  "\x77\xc6\xe3\x35\xad\xd8\x0f\xb3\x66\xe4\xf0\xfc\x35\xe7\x89\xde"
-  "\xf1\x95\x23\xe2\x2f\x4d\x4a\xdf\xf0\xa5\xb9\xb7\x9f\xf1\xd5\xcf"
-  "\xfd\xb1\x5f\x5b\xfa\x86\x2f\xcd\x1b\x14\x5f\xbf\x2e\xa7\xf8\xd2"
-  "\x68\xed\xf8\x9a\xf3\xc4\xc5\xc3\xd7\xaf\xc3\x28\xbe\x7e\xad\x92"
-  "\x87\x2f\x8d\x1b\xeb\xff\xb8\x3b\x8f\xf0\x9b\x69\x7d\xeb\x43\xde"
-  "\xfd\x7d\xdf\x30\x76\xf7\xa6\x2b\xbb\x0f\x79\x77\x64\xdf\x30\x76"
-  "\xf7\x71\x8a\xb1\xbb\xbd\x28\xc6\xee\x3e\x76\x69\xfa\x90\x77\xed"
-  "\xa3\x18\xbb\x2b\x4e\x1e\xc6\x7e\xd3\x8f\xf3\x1f\x13\x2a\xfb\xd6"
-  "\x8f\x9c\xf0\x74\xdf\x30\x36\xfe\xc2\x95\xdd\x8f\x1c\x7f\xa8\x6f"
-  "\x18\x9b\xf0\x38\xc5\xd8\xf8\x45\x14\x63\x13\x26\x5d\x9a\x7e\xe4"
-  "\x78\x7f\x8a\xb1\xdf\xc8\x9c\xb7\x99\x20\xeb\xfd\x17\xe7\xf3\x36"
-  "\x81\x23\xfb\xd6\x97\x9c\xb8\xbb\x6f\x18\x9b\x38\xf7\xca\xee\x4b"
-  "\x4e\xd4\xf4\x0d\x63\x13\xb7\x51\x8c\xdd\xd3\x40\x31\x36\xb1\xe8"
-  "\xd2\xf4\x25\xef\x49\xa0\x18\xbb\x67\x8a\x3c\x8c\x05\xaa\xfb\x6f"
-  "\xbe\xe9\xbe\xf8\xbe\xf5\x27\xef\x1b\xde\x37\x8c\xdd\xfb\xd1\x95"
-  "\xdd\x9f\xbc\x37\xa3\x6f\x18\xbb\x6f\x08\xc5\xd8\xbd\x41\x14\x63"
-  "\xf7\x91\x4b\xd3\x9f\x0c\x34\x50\x8c\x05\x96\xc9\xc3\xd8\x7d\x6e"
-  "\xac\xff\xef\xee\x3c\x59\x50\x53\xdf\xfa\x94\x41\x2b\xfa\x86\xb1"
-  "\xa0\x3b\xae\xec\x3e\xe5\xfd\xc6\xbe\x61\x2c\x68\x31\xc5\xd8\xfd"
-  "\x79\x14\x63\x41\x51\x97\xa6\x4f\x79\xff\x54\x8a\xb1\xfb\x95\xf2"
-  "\x30\x16\xd4\xda\x7f\xf3\x7b\xbf\x0d\xee\x5b\xbf\xf2\xc1\x2f\xfb"
-  "\x86\xb1\x07\xd7\x5f\xd9\xfd\xca\x07\x67\xf7\x0d\x63\x0f\x1e\xa5"
-  "\x18\x7b\xc0\x42\x31\xf6\x60\xcd\xa5\xe9\x57\x3e\x50\x41\x31\xf6"
-  "\x80\xbc\xf5\x28\x98\xdf\x76\x5b\xff\x6a\xe1\x92\x95\xf3\x16\x2d"
-  "\x8c\x52\x2f\x5c\x12\x17\xbb\x4c\xbd\x7c\xe1\xea\xe8\x47\xee\x58"
-  "\x31\x5e\x1d\x1b\xaf\x8e\x5d\xb8\xe4\x55\x3e\x21\x6a\x28\x99\x15"
-  "\xbd\x68\x5e\x3c\xa6\x40\xee\x57\x97\x2c\x8e\x5e\x12\xa7\x8e\x8d"
-  "\x5e\xb6\x62\x61\x6c\x34\x7e\x5f\xae\x5e\xb0\x34\x16\x12\x5e\x89"
-  "\x5e\xb8\x32\x5a\x3d\x7f\xc5\x82\x05\xd1\xb1\xcb\x87\x92\xe9\x2b"
-  "\x16\xc5\x2d\xd4\x2e\x8a\x56\x4f\x9d\xfe\xf8\x84\xd9\x4f\xfe\x71"
-  "\xf6\x63\x8f\xe1\xe6\x64\xa2\xbd\xc9\x02\xd8\x8c\x82\x4a\xc0\x9c"
-  "\xf2\x04\x13\xfc\x65\x9d\x3f\xe1\xf6\xb3\xdd\x78\x86\xa8\xd6\xc7"
-  "\x12\x65\xda\x19\xe2\x95\x79\x86\x78\xab\x5f\x23\xc1\xec\xfa\x7f"
-  "\xab\x21\x7d\x24\x9b\xe9\x17\xc9\x66\x45\x4e\x82\xcf\x32\xe3\x10"
-  "\xf3\x24\xcc\xcb\xae\x6f\x0f\xc7\x73\x20\x5b\x25\x9b\xa9\xf2\x6a"
-  "\x66\x82\xf3\x8c\x43\x2e\x68\x92\x7e\x24\x0c\x3b\x74\x52\xc2\x1e"
-  "\x9b\x91\xf9\x08\x67\x34\xa0\xed\x84\x99\x9c\x0b\x47\x32\x61\x1e"
-  "\x0a\x84\x23\x18\x8e\x69\x70\xc4\xc1\x91\x00\x87\x0e\x8e\x22\x38"
-  "\x2a\xe0\xa8\x84\xa3\x0a\x8e\x6a\x38\x6a\x08\xf3\xf0\x54\x38\xa2"
-  "\xe0\x80\xbc\x0f\x67\xd0\x72\x1e\xce\x83\xe3\x10\x61\xa6\x78\xc3"
-  "\x01\x65\x3d\x32\x05\x8e\x18\xc2\x3c\xea\x05\x9f\x69\x70\x94\xc3"
-  "\xb1\x0b\x8e\x06\x38\x4c\x90\xb7\x88\x9e\x7b\x14\xd2\x1e\x6d\x25"
-  "\x50\xcf\xde\x8f\xc7\x20\xff\x63\x2a\x38\x82\xe0\x80\x7b\x3e\x66"
-  "\x86\xf4\x90\x1e\xae\xd1\xf5\x52\x66\xa5\x5f\xca\x2d\x06\x6e\x0f"
-  "\x3c\x66\xf2\x2f\xd6\xb5\x64\x80\x75\xfd\x05\x8d\xf6\x6e\xa2\x38"
-  "\xc9\x4c\x3e\x50\x9f\x8a\x3c\xe3\x17\xc9\xed\xe9\x08\xbf\x51\x66"
-  "\xed\xe9\x93\xf7\x1b\x48\xa6\x1a\xf7\x34\xf3\x0c\x6f\x93\xf7\xf3"
-  "\xd7\x5b\x0c\x8a\x9b\x2a\xb8\x3d\xe0\xd2\x6b\x77\xb1\x49\xe1\x85"
-  "\xdc\xde\x6f\x28\x43\xb4\x83\xb4\x5a\x25\xeb\xf5\x49\x25\xda\x7c"
-  "\xf5\x6a\xae\x5e\x9b\xd8\xb5\xc4\x17\xae\xcf\x65\xa1\x6e\x46\x9f"
-  "\xc8\x49\x50\x4f\x25\xfe\xb6\xae\x37\x4f\xba\xe0\x93\xaf\xc3\xef"
-  "\xe6\xe2\x39\xd5\x6c\x46\x7e\x15\xf6\xb3\xab\x13\xf5\xa4\x19\xae"
-  "\xbb\xe0\x53\x18\xae\x7e\xc6\x8f\x6d\xc6\x6b\xd7\x12\xc6\xc0\x3c"
-  "\xa4\xa1\xb6\x3a\x39\xf7\x82\x4f\x64\xb0\x35\xaf\x30\x19\xd2\x95"
-  "\xd6\xcc\xc8\x49\xb4\x7c\xf3\x24\x6b\xc6\xa6\x48\xc8\x97\xca\xa5"
-  "\x17\xcd\x69\x14\xbe\xc3\x67\xb2\x35\x2b\xdf\x8c\x9f\x3e\x29\xc4"
-  "\xc4\xfd\x5e\x1b\x4c\xe8\xa7\x8a\xa8\x9f\x21\xa4\x8d\x79\xf8\xae"
-  "\x89\x35\x44\x51\xfd\x0c\xd6\xfb\x21\x53\x52\x0d\x6b\x53\x27\x0e"
-  "\x80\xfb\x3f\x74\xae\xeb\xbe\x37\x17\xc6\xe3\x1e\xa9\x6c\xfa\x6f"
-  "\x33\x4a\xf5\x84\xe0\xb5\x58\xb7\xfc\x11\x44\x59\xac\x27\x5e\xd8"
-  "\xc6\xf6\xf4\x87\xd5\xc2\x3e\x74\x78\x0d\x03\xf9\x9f\x7e\x3a\x89"
-  "\x15\x95\x7d\xca\xca\xb5\x67\xb2\x8e\xca\xf4\xe1\x30\x83\x62\x64"
-  "\x39\xe6\x57\xdf\xc6\xc9\x72\x13\x7f\x3e\x17\xf5\x89\xe5\xb3\x99"
-  "\x05\x95\xf8\x1b\xf7\xb9\xf3\x03\x04\xab\x13\xc7\x55\x51\x19\xe5"
-  "\x57\x61\x39\x98\x9f\xcd\xca\x85\xef\x0f\x05\xb1\x99\x9c\x8c\x35"
-  "\xea\x25\x24\xb8\x99\x79\xf8\x80\x75\xfd\x91\x28\x28\x03\xec\xee"
-  "\x48\x0c\xe4\x6f\xe0\xe4\x9d\xb9\x29\xcc\xc0\x3c\x5c\x09\xe7\x62"
-  "\xba\xf6\xbe\xa4\x72\x56\x40\xbe\x78\xa8\x53\x8b\x41\x31\x7e\x1f"
-  "\xa7\xe7\x95\xec\x31\xdc\x63\xf3\xec\x4a\xd6\x12\x6a\xf9\xc6\x06"
-  "\x5c\x45\xda\xd3\xa7\x28\x0d\xe4\xd1\x48\xa1\x8d\x54\xf7\x5d\xe5"
-  "\x6c\xc2\xdf\xc6\x21\x58\xce\x94\xf1\xce\xca\x81\x7b\x9b\x5e\xb6"
-  "\xa8\x15\x1d\xe7\xd9\x86\x8d\xcf\xa1\x1c\x09\xdb\xb1\x92\xad\x7d"
-  "\x33\x84\x35\x67\x7d\x4e\xc8\x91\x98\x26\x02\x36\x1f\xe0\xab\x60"
-  "\x8d\xa1\x6f\x10\x3f\x5f\xad\x1f\xfb\x69\x4d\x13\x59\x13\xc2\xb6"
-  "\xe2\x1e\xbe\x75\xa6\x16\x92\xf0\x25\xf1\x4e\x3a\x42\x46\x26\x84"
-  "\xb0\xc6\xda\xc8\x26\x42\xd3\x8f\x90\xa4\x6f\x89\x72\xcd\x21\xd6"
-  "\x3c\x03\xf8\xff\x70\x13\xa6\xb7\x10\xdc\xa3\x32\xa9\x95\xb5\x24"
-  "\xce\x25\xde\xf8\xfd\xc8\x21\x4c\xff\x9e\x24\x9d\x22\xca\xd0\x78"
-  "\xa3\x5f\x09\xdc\x13\xaf\x2f\x85\xba\xd8\xce\xb3\xfb\x37\x9e\x27"
-  "\x64\xcd\x0b\xc4\x3f\x61\x1e\x51\x85\x5a\x09\x5b\x6f\xf9\x33\x09"
-  "\xb5\xb2\xe0\x5f\x3e\x26\x6f\x2e\x24\x5e\xa1\x16\x7c\x8f\xed\x0b"
-  "\x82\xfb\x74\x97\x42\x5e\x68\x5b\x35\xb6\x6d\xcd\x71\xe2\x8f\xfb"
-  "\x93\xd3\x6b\x0e\xf0\xd7\x1c\x27\x28\xb3\x0b\x3e\x7e\x3a\x73\xa6"
-  "\x4a\x05\x6d\x37\xa3\x0c\xe0\x3e\x0d\x36\xbc\x0e\xae\xdf\x18\xcb"
-  "\xc9\x40\xf1\xb2\x85\x78\x5b\x33\x37\x4d\x7a\x39\xbe\x9a\x2b\xd7"
-  "\xc0\x3c\x12\x54\x1a\xcb\xd5\x49\x92\x37\xd4\xc2\x9e\x35\xfa\x6c"
-  "\x02\xdc\x3f\x12\x11\x1a\xff\x18\x8b\xd7\x82\x2e\xe3\xda\xd3\x1f"
-  "\x29\x12\xe4\x2d\xe8\x05\xf2\xe8\x40\x17\x71\x03\xb4\x44\x09\xe7"
-  "\xf7\x1b\x14\x13\x75\x76\xac\x3d\x84\xf8\x1a\x24\xe4\xe5\xf3\x18"
-  "\x0c\x8a\x09\x8d\x22\x3c\x22\xbe\xba\xf2\xb4\xa7\x3f\x4a\x0c\x8a"
-  "\x7b\x0c\xf4\x1e\x8f\x54\x63\x1e\x9e\xfb\x85\xbc\x03\xd8\xb4\x4f"
-  "\x52\xad\x3e\xf9\xd5\x2c\xc3\x9a\x01\x8f\xe1\xec\x59\x7f\xef\x19"
-  "\x16\xd6\x6c\xcb\xcc\x0d\x03\x7e\xf7\xc6\x7d\x5d\x69\xfe\x47\xb3"
-  "\xe1\x7c\xa4\x7a\x25\xf7\xbd\x1c\xef\xc3\x66\x44\x46\x76\x9d\x5b"
-  "\x4b\x06\xb2\xc5\x73\x2a\xc1\x77\xa8\x42\x6b\x58\x33\xd8\x7a\x65"
-  "\x56\x2c\xfa\x8e\xfc\x4a\xb4\x6b\x9b\xcf\xa6\x18\x73\x7e\x61\x24"
-  "\xf2\x13\xda\x08\x9b\x91\x1b\x46\xaf\x7d\xe8\x2e\xb4\x1b\xca\x35"
-  "\x8f\xc6\x58\xa1\x0c\xa8\x53\x1a\x9c\x1b\xd8\xcc\x3c\xda\x84\xef"
-  "\x93\xc2\xef\x6a\x6e\xdf\x4b\xe6\xd1\x6f\x29\x7e\x3f\x49\x95\xfc"
-  "\x66\x50\x76\x60\x4f\xc0\x59\xc8\x0f\x27\x98\xc7\x14\x22\x1b\xd6"
-  "\xb0\xbc\x8d\x5e\xf0\xc9\x8d\xa4\x3c\x32\xc0\x06\xf9\x14\xcd\xbc"
-  "\x3d\x5e\x18\x72\x64\x51\x7b\xfa\x63\x80\x7f\xbf\x10\x89\x9d\xa4"
-  "\x1f\xd4\xe0\x1e\x9b\x50\x97\x01\x50\xe6\x0b\xf0\x39\x18\x3e\xe7"
-  "\x1e\xac\x41\x7d\x73\xe5\x0e\xc3\xef\xf9\xa3\x58\xe3\xd4\x27\x09"
-  "\xee\xa7\x09\xf6\xf6\x58\x9c\x81\x2c\x52\x62\x39\xeb\x71\x9f\x51"
-  "\x48\xc3\x3c\x90\x9e\x01\xe9\x26\x5a\xfe\x43\x41\x26\xa8\xab\x43"
-  "\xf9\x1f\xd0\xf2\x69\xb9\x58\x9e\x50\x76\xf1\x66\xb6\x8d\x2f\xbb"
-  "\x41\x28\x3b\x13\xd2\x84\xf2\xa7\x2e\xee\xba\x87\x11\xce\x27\x88"
-  "\xdb\x90\xb7\x99\x35\x61\x19\xed\xe9\xc1\xde\x06\x92\xdc\x8a\xe7"
-  "\xd2\x20\x0d\xaf\x15\xe1\x6a\xc0\xc1\x10\x28\xe3\x10\x96\x11\x1c"
-  "\x64\x20\x49\x5a\x07\x8e\xf3\x11\x38\x8e\x2f\x2b\x5c\x28\xcb\x5e"
-  "\x8e\x80\xa7\xa3\xd5\xbc\x5e\xb1\x5c\x6f\x2c\x17\xf2\xa7\x19\xc8"
-  "\x92\x43\xe2\xb6\x83\x6d\xe9\xd8\xac\x7c\xdc\x83\x57\xc1\xe3\xf1"
-  "\x00\x72\xb2\x50\x6f\xdc\x67\x14\xb8\x7b\x1f\xda\x0b\xc7\xdf\x99"
-  "\x9b\x82\xa1\x9c\x06\x07\xbe\x56\x62\x3e\x6b\xfa\x6f\x7f\x2c\xc6"
-  "\x7d\x56\x47\xb1\xad\x90\xc7\x24\xd9\x5b\x94\x21\x8f\xb6\xa7\x3f"
-  "\xee\x25\xec\x71\x9a\x05\x79\x0c\xcc\x24\x97\x6b\x38\x26\xde\x4a"
-  "\x98\xfa\x22\x03\xc6\xcf\x88\xab\x29\xf5\x01\x26\x52\x5f\x64\x23"
-  "\xb6\x92\x39\x86\xe0\x44\xb6\xfa\x04\xf3\xf8\xdb\xb8\x37\xb5\x67"
-  "\x3e\xf9\xf1\x30\x0e\x4f\x1d\x10\x57\x26\xdc\x47\xd0\x0f\x9f\x66"
-  "\x9e\xf8\x73\xbd\xf1\x0c\x67\x5b\xf0\x9d\x7b\x3f\x3a\x07\xe2\x50"
-  "\x8c\x45\x21\xfe\x8f\xd1\x31\x34\x1e\xb5\x41\xde\x12\x4c\xc7\x58"
-  "\x15\x78\xb2\x54\x74\x8e\x2d\x99\x93\x47\x65\xf7\xc4\x62\xce\x1f"
-  "\x60\x7d\x2d\x4f\x55\x63\x9d\x6d\x45\x73\xf2\xb0\x0d\x49\xf1\xac"
-  "\xad\xde\xd2\x5e\x8d\x5c\xaa\x5e\x89\x71\xf4\x13\x4f\x87\x16\x13"
-  "\xd6\x56\x3c\x27\xcf\xb3\x36\x3c\xc1\x3d\xff\x04\x7d\x85\xd3\xc6"
-  "\x31\x73\xf2\x70\xaf\xe7\x8d\x89\x03\xbd\x7e\x57\xc4\x56\x9f\x1d"
-  "\x3b\xc7\xd0\x9e\xfe\xc4\x22\x61\x2f\x5d\x0f\xcb\x5d\x24\xb4\xbd"
-  "\x84\x6f\x3b\xc8\x8b\xdb\xb3\x67\x62\x1e\xb7\x97\x37\xfc\x7e\xc2"
-  "\xe5\x5e\x9f\xc0\x23\x35\x78\x2d\xb4\x3d\xb8\x54\x90\x93\xc5\x88"
-  "\xfb\x98\x0f\x3f\xc9\xfc\x6e\x72\x68\x42\x35\xe1\xd6\xed\xcf\xcc"
-  "\xad\xf1\xac\x5e\xbf\xe3\x9e\x7f\xaf\x83\x7e\x4a\xa8\xe5\xef\x2c"
-  "\xe5\xbd\xdf\xcd\x9b\xc1\x97\x87\xe7\x04\x5d\x95\xf0\xfd\x07\x19"
-  "\xf7\x70\xb9\xff\x81\xa8\x5d\xaa\xee\xed\x9a\x3a\xbc\x0f\xed\x6a"
-  "\xea\xde\xae\xa9\x93\xfb\xb7\x5d\x53\x83\xdd\x68\x97\xda\x49\xbb"
-  "\x7e\x94\xdf\xae\xa9\xfb\xba\xb7\xeb\xc9\xe1\xfd\xdb\xae\x27\xfd"
-  "\xdd\x68\x57\x60\xf7\x76\x3d\xf9\x91\xfc\x76\x3d\x99\xe1\xa4\x5d"
-  "\x3f\xf6\x73\xbb\x8c\x1e\xf3\x61\x56\x81\x8a\xf2\xe1\xef\x37\x79"
-  "\xce\x87\xbf\x8f\xec\xce\x87\x4f\x7d\x6c\xe7\xc3\xa7\x3e\x90\xc5"
-  "\x87\x59\x91\x7c\x4c\xf1\xd4\x9b\xdd\xf8\x30\x23\x32\xcc\x39\x1f"
-  "\x3e\xf5\x02\xc7\x87\x99\x91\x61\x9e\xb5\xe1\xa9\x71\x5d\x7c\xe8"
-  "\x13\x19\x26\xe1\x43\xdf\x02\x55\x7b\xfa\x53\x09\xf2\xf8\xf0\xa9"
-  "\x84\xee\x7c\xf8\xfb\x26\x29\x1f\x3e\xe5\xf2\x59\x67\x36\x63\x53"
-  "\x88\x33\x3e\x0c\xb5\xfc\xcc\x52\x6c\x6c\x0a\xf1\xac\x3e\x21\x2e"
-  "\xdf\xff\x06\xcc\x37\xf4\x7c\xaf\xdc\x06\x0f\xef\x15\xef\xf2\x5e"
-  "\x5e\x9f\x94\x43\x9c\xa1\x7a\x73\x0b\x61\x4e\x24\x10\xa6\x2e\xa0"
-  "\x11\xfa\x01\x66\x72\x8f\x16\x30\xb1\x96\x4c\xa9\x2b\x6a\x23\x75"
-  "\x01\x27\x08\x3b\xe4\x93\x72\xf6\xdd\x88\xb0\xe0\x58\xc4\xe6\xd3"
-  "\xf7\xd6\xc7\x99\x3d\xc4\x66\x88\x45\xc0\x66\x9d\x05\xb0\xb9\x12"
-  "\xf1\xf8\xcc\xbc\xfa\xb6\x93\x3c\x36\x9f\x99\xde\xa5\x9f\xb5\x14"
-  "\x9f\x4e\xb1\x09\x36\x21\xc5\x66\x2e\x1f\x17\x3d\x73\x73\x77\x6c"
-  "\xe6\x56\x3b\xc7\xe6\xd3\xe7\x28\x36\x73\xab\x3d\x6b\xc3\xd3\xd5"
-  "\x76\x6c\xe6\x56\x4b\xb0\x79\x67\x44\x58\x7b\xfa\x33\xfe\xf2\xb0"
-  "\xf9\x8c\xbf\xd0\xf6\x62\xbe\xed\x70\xaf\x78\x29\x36\x9f\x09\x73"
-  "\xa9\xc3\xb4\xbd\x46\xe0\x43\xef\x93\xcc\x1f\xd4\x56\x88\x5b\x6d"
-  "\x69\xd6\x10\xe8\x77\xb5\xe3\x9e\xf1\x2c\x13\x44\xd8\x55\x1a\xef"
-  "\x76\xe8\xff\xb6\xb7\xc7\x78\xb1\x43\x3f\xb9\x8f\xed\xf4\x27\x50"
-  "\x77\x3f\xb6\x5d\xe3\x0b\x32\x1b\x07\x9f\x23\x8a\x57\x92\x91\x70"
-  "\xf8\x17\xf3\x72\x85\xef\x81\xec\x2a\xff\xa1\x59\x2b\xc9\x78\x3f"
-  "\x13\xf1\x82\x3a\x84\xfb\xa5\xa8\x88\x9f\x85\x8c\xc4\xef\xec\xda"
-  "\xbf\x68\xa0\x7f\xa6\xc4\xb1\x4f\xdb\x10\xb8\x5f\xbc\x1f\xcb\x2e"
-  "\xd7\x10\xe8\xab\x79\x81\x0e\xfc\x4b\x19\xb6\xd2\xba\x4a\xc3\xb0"
-  "\xbe\xf9\x87\xd9\x35\xe1\x5c\x9d\x6c\xe3\x22\x74\x80\x21\x1d\x9b"
-  "\x14\x83\xf7\x0d\xc6\xbd\x8b\xd9\x3b\x23\x72\xd9\x76\xff\xa1\x99"
-  "\xe7\xc9\xf8\xd2\x95\x64\x5c\xc9\x4a\xa2\x61\x3b\x35\x0c\xc8\x20"
-  "\xfc\xa5\x65\x2a\xd4\x7b\x38\xcb\xc0\xbd\x56\xc2\xbd\x2c\xd8\xc7"
-  "\x83\x7b\x59\xe0\x5e\x3f\xc3\xbd\x4e\xc3\xbd\xd6\xc2\xbd\xd6\xd2"
-  "\x7b\x79\x26\xf3\x3f\xf4\xb8\xff\x73\xe8\x9b\x63\x71\x2d\xdd\x1f"
-  "\xfc\xe2\x07\x87\xe0\x78\xf5\xd9\x35\x31\x1e\xe2\xfd\x0f\x2e\xd7"
-  "\x7f\xde\xb8\x87\x04\xb0\x5e\xed\x21\x33\xde\xfe\x86\xc5\x7e\xf4"
-  "\xdb\x7b\xc8\x78\xb4\xb9\x3a\xf3\x29\xb0\xb3\xf6\x90\x8f\x35\x6d"
-  "\x1e\xde\x6b\x9a\xcb\xe7\x1f\xd2\xd7\x42\xbf\xd9\x1b\xfa\xa1\xde"
-  "\xf9\x8d\x1b\xd7\xb2\xf1\x9d\x01\x73\x2a\x3b\x02\xe6\x34\xbc\x6c"
-  "\x51\x01\xae\xd8\x78\x75\x2c\x51\x9f\x60\x66\x15\x7f\x76\x0c\x7c"
-  "\xc4\x8b\xc4\xab\x99\x99\x75\x2c\xe9\x4b\x1c\x6b\x9c\xd6\x2a\x1d"
-  "\x6b\x9c\xee\x4d\x98\x19\xc0\x10\xa1\x19\x84\x09\xab\x24\x90\x4f"
-  "\x7a\xcc\xac\xa5\x65\xcd\x78\x21\x74\xfb\x58\x92\x68\x61\x7f\x80"
-  "\x7e\x6c\x45\x16\xf4\x7f\x43\xef\x52\x18\xaa\x57\xe2\x18\xdc\x8c"
-  "\x99\x20\xd3\x9f\xc0\x2f\xf9\xc1\xf7\x31\xa0\x3b\xa2\x8d\x25\x37"
-  "\x9c\x64\x66\x04\x58\xe0\xbb\x9f\x69\x70\x88\x35\x29\x9c\x58\xfc"
-  "\x0b\x23\x3b\x33\xf2\x2b\xad\xd0\x97\xb5\x79\x59\x43\x70\x1c\xa4"
-  "\xbe\xcd\x4a\x8a\x00\x77\x2f\x5b\xbd\xd0\x1e\xc2\xab\xe7\x7f\x46"
-  "\x4e\xc4\x11\x26\xe9\x1c\xf1\x61\xcf\x6a\xbc\x05\x5c\x4f\x6f\xf3"
-  "\x33\xbf\xd9\xc6\xda\x10\xdf\x38\xee\x00\xe7\x7c\x13\xcf\x81\xaf"
-  "\x35\xb6\x92\x22\xe8\x37\x5b\x97\xc7\x8c\x30\x9e\x8d\xb9\xa1\xd0"
-  "\x46\x46\xfa\x9a\x88\xaa\xe8\x0c\x60\x70\x39\xe0\xef\x0c\xe0\xdc"
-  "\x48\x71\x8e\xef\x0a\x95\x20\xc6\xd7\x7d\x36\xbe\xf4\x0c\xc5\x38"
-  "\x87\x3b\xc4\xf8\x52\xc0\xdd\x12\x3b\xee\x2c\x67\x01\xe3\xe9\x7f"
-  "\xa8\x2d\x5a\xcb\xe2\xb8\x08\x53\x7a\x72\x30\x9e\x53\x0c\xbc\x8b"
-  "\x51\x7f\x16\x66\x26\xf6\x7e\xd8\xac\x2f\x3a\xc6\xcc\x69\x50\xcf"
-  "\x62\x7f\x6e\x66\x66\x84\x40\xba\x97\xfa\xb9\x5f\xab\x40\xde\x5f"
-  "\xd0\x31\x8a\x59\xc7\xb0\x9f\x6f\x00\x59\xa0\x5c\xd4\xb3\xc8\xaf"
-  "\x9b\x99\xe9\x63\x50\x8e\xab\x2a\xc8\x00\xed\xa3\x6c\x0b\xc8\x6c"
-  "\x1c\x96\x67\x60\xa6\x73\xfd\x2c\x9c\xff\x38\xcc\x8d\x7d\xd2\x6b"
-  "\xac\x20\x37\x8b\x77\x64\x24\xe8\xbb\xa6\xfa\xb5\x0e\xce\xe6\x50"
-  "\x8e\x27\x16\x11\xe6\xe5\x36\x90\x95\x15\x64\xd5\xce\x71\x41\x18"
-  "\xc7\x05\x69\x9f\x8c\x4f\x30\xb0\xb6\xd0\xa8\x01\x6c\xe2\x32\x9c"
-  "\x7b\xb1\x92\x97\xb4\x84\x7d\xf3\x14\xc8\xcb\xd4\x88\xbc\xe1\x6b"
-  "\x5b\x45\xb9\x01\xe5\xe5\xd3\x46\x54\x6c\xfa\x85\xe0\x3d\x89\x35"
-  "\x03\xad\x80\x5f\xe4\x07\xbf\x14\xc5\x10\xb0\x4b\xdf\x0c\xb4\x5f"
-  "\xb0\x67\xbf\x14\x8e\xaf\xc2\x8b\xc0\x6e\x2d\xab\x34\xb7\x75\xae"
-  "\xd2\xa8\xe1\x18\x2b\x70\x08\xee\xf9\x55\x8c\xb2\x4d\x9f\x16\x84"
-  "\xfc\x51\x1f\x6f\x20\x16\x90\xad\x2f\xfa\x9b\x55\x9a\x00\x4e\xc6"
-  "\xaf\x6a\xc8\x44\x33\x51\x40\x9d\x54\x50\x5f\x52\xba\x80\x78\x1d"
-  "\x89\x69\x26\x56\xb0\x0d\x41\xee\xd3\x17\xaa\x09\x94\xcb\x7c\xac"
-  "\xf9\x82\xf0\x32\x53\xb8\xc6\x5d\xd8\x76\x3b\xee\xc2\xb6\xa3\xec"
-  "\x28\xee\xc2\x2a\xae\x45\xdc\x1d\x0e\xe7\x70\x37\xa0\x73\x0c\x87"
-  "\xa7\x71\xf5\x96\xbd\x20\xa3\x30\x1c\xdb\x24\x88\x99\x4f\x77\x20"
-  "\x66\x66\xee\xbf\x52\x31\x73\xa1\x5d\xa3\x86\xe3\xa2\x60\x06\xca"
-  "\xe5\x30\x83\xb2\x3a\x1c\xde\x41\x04\x19\x71\xb6\x9a\xd6\x1e\xa2"
-  "\x4e\x22\x8f\x81\xad\x1e\xf3\x4b\x19\x4b\x8e\x70\x72\x9a\x75\x4c"
-  "\xfd\x1c\x6b\x6b\x66\x66\x9e\x4b\x3a\x4a\x54\x1d\x6b\x59\xb6\xde"
-  "\xb2\x9b\xd8\xbc\x37\xc5\xe0\x38\x33\xc4\xbf\x95\xc2\x1c\x0e\x8e"
-  "\xc7\xf9\x69\x89\x92\x1b\x87\xcf\x2c\xa8\xb4\xad\x6f\x0f\x67\x7d"
-  "\x54\x5e\x38\xf6\x66\x5b\xff\x6f\xb5\xcd\xc7\x2f\xb2\x3d\x7d\xd6"
-  "\x14\x03\x39\x56\xc9\x8d\x07\x67\xe4\x63\xec\x82\xfc\x1b\x4d\xc7"
-  "\x8b\x71\xec\x7c\x56\x84\x30\x3f\x81\x9c\xc0\x8f\xcb\xf1\xe3\x76"
-  "\xb3\x50\x87\x43\x71\xdc\x8e\xe7\x94\xe9\xc2\xb8\x9d\xf0\x1b\xcf"
-  "\xc3\x75\x61\x38\xe6\x23\xba\xae\x96\xcf\xc7\x5f\x37\xed\x28\x72"
-  "\xbd\xfd\x3a\xfa\x1b\xfc\x48\x6d\x27\x43\xbc\x9c\xc6\x18\xde\x05"
-  "\x95\x60\x3f\xca\x13\xcc\x1f\x8f\xc2\x27\x03\x9f\x8b\xe1\x73\x00"
-  "\x7c\x3e\x82\x65\x7b\xe6\xaf\xfe\xc8\xbd\xff\x09\xed\xb7\xd0\xfb"
-  "\xff\x91\x7b\x96\x42\x7b\x37\xf1\x39\xc9\x7f\x6f\x4f\xff\x63\x94"
-  "\x30\xcf\xd2\x95\xbf\x4b\x3f\x7f\xc4\xbe\xcd\x00\xd0\x91\x92\xce"
-  "\xfd\xd0\xdf\xa2\xf2\x14\xdc\x6f\xa2\x54\x83\x6e\xb4\x38\x47\x0b"
-  "\xf8\x55\xb4\xb3\x31\x8f\xf2\x9f\x8f\xa0\x7d\xe0\x78\x29\xc6\x6b"
-  "\x94\x7f\xe9\x3d\xe0\xbe\x4d\x20\x87\x3c\xf1\x7d\x9d\xc9\x03\xce"
-  "\x99\x5d\x9d\xf3\x4c\x16\xb3\x5d\xbe\xff\xf6\xa4\xc6\xca\x7a\x58"
-  "\x56\xa4\xcb\x18\x31\x60\x8e\x2e\xb4\xc2\x5a\x6d\xeb\x0c\xf7\xfb"
-  "\x38\xe1\x94\x87\xf1\xc5\xec\x2a\x57\xe5\x5a\xbd\x37\x25\x5b\x8a"
-  "\xe6\xe8\x70\x4c\xb2\xae\xc2\x42\xb6\x9f\x6c\x65\x42\xef\x1a\x4b"
-  "\x7c\x5a\x88\x0a\xe3\xa7\xe9\x6d\x7f\x67\x31\x86\xca\x3a\x49\xc6"
-  "\x75\xfc\x1c\xee\xd7\x09\xb1\xe0\x86\x93\x64\x8a\xed\x55\xff\xa1"
-  "\x19\x0b\x88\xb2\x03\xe2\xd5\x8e\x57\x63\xfc\x0e\x37\xb5\x12\xb0"
-  "\x13\x5d\x9d\xc9\x40\x4a\x20\x2f\xfb\x43\xb8\xef\xd3\x91\xac\xb9"
-  "\x36\x52\x4f\x42\x35\xd6\xea\xc4\x6f\x89\x0f\x70\x91\xaa\x3e\x7e"
-  "\x37\xa9\xb7\x9c\x22\x03\xdf\x60\xd4\xf5\x96\xef\x49\xe6\x02\xe0"
-  "\x30\xe0\xac\xa4\x17\x80\xab\x2d\xe7\x48\xa1\x98\xab\x5f\xdb\x6a"
-  "\xe7\xea\x9f\x81\xab\xd3\x81\xab\x93\xfc\x49\x9d\xb6\x9a\x00\x77"
-  "\x0c\x9e\xa1\xf5\x33\x27\x6a\x81\xb3\xdf\x00\xce\x8e\xff\x9e\x70"
-  "\x7c\xdd\xd6\x4a\x80\x6b\x7d\x8b\x97\x90\x91\x9d\x4b\x81\xb3\x7f"
-  "\x8e\xb9\x21\x3f\x91\x72\x76\xc1\x12\xe0\xec\xa5\x10\x13\x2f\x01"
-  "\xce\x6e\x73\xc2\xd9\xa7\x5d\xc4\xc3\x3c\xff\x74\x2c\xd5\x30\x05"
-  "\x0c\x8b\xf3\x2a\x4c\xfe\x57\x83\x3d\xc4\xc9\x73\x53\x5c\xe9\x00"
-  "\xe5\x8d\xf2\xb7\x81\x1e\x8e\x80\x0e\xb8\xb8\xd5\x3c\x38\xa4\x13"
-  "\x7c\x9a\xd5\x57\xd7\xb0\xe3\x64\x23\xe3\x1b\x47\x54\x33\xb4\x7f"
-  "\x67\x3b\x96\x87\x43\xdc\x1f\xee\x63\xc9\xd8\x94\x9c\x01\x31\xb5"
-  "\x15\x62\xef\xce\x76\x7f\x2f\x90\x81\xca\xb8\x2a\xc6\x0f\x65\x68"
-  "\x1b\x03\xfa\x1c\xf4\xdb\x5d\xc0\xa1\x41\xc5\x0b\xc8\xa4\xce\x4c"
-  "\x9d\x85\xcd\xd4\x19\xad\x99\x3a\x13\x5c\xeb\xfb\x07\x03\xea\xe5"
-  "\xaf\x84\xcd\xcc\x56\xb1\x59\x39\x0d\x56\x9f\x4d\xc9\x46\x1f\x9d"
-  "\x19\x7e\x7b\xe1\xf9\xc4\x79\xc4\x27\x54\x73\xa1\x9a\xea\x6b\x1b"
-  "\x41\x3d\x51\x7d\x1d\x27\x99\xd0\xef\x43\x9f\xcb\xf9\x57\x5e\x67"
-  "\xd0\x5f\xe0\xe2\x7d\xbb\xde\x1c\x7c\x2c\xaf\xb7\x23\x6d\xd5\x04"
-  "\xfc\xc9\xe0\x2e\x5f\xcb\xe9\xed\x38\x11\xfc\x2c\xc8\xdb\xb7\x18"
-  "\x7c\x6d\x67\x7f\xf9\x5a\xbe\x1f\x83\xbe\x16\xfd\x2c\xea\xad\xc0"
-  "\x63\xbd\x3d\xef\xf2\xf9\xf7\x9e\xf5\x96\x1d\x26\x4f\x6f\x93\x94"
-  "\x76\xbd\x65\x27\x80\x4e\xb4\xd6\xcc\xec\x38\x07\xbd\xe9\xec\x7a"
-  "\xcb\x8e\x87\xdf\x69\x76\xbd\x9d\xf3\x40\x6f\x03\xcf\x5c\xbb\x7a"
-  "\x7b\xc1\xe5\xfa\x47\xbd\xe8\x4d\xa6\xbd\x4d\x8a\x10\xe9\x0d\xec"
-  "\x2d\x1b\xec\x2d\xdb\xc1\xde\xf4\x22\x7b\xcb\x06\x7b\xd3\x8b\xec"
-  "\xed\x94\x07\x7a\x1b\xd6\x7c\xed\xea\x6d\x8e\xcb\xf5\x2f\x7b\xd6"
-  "\x9b\x5e\xae\xbd\xed\xb3\xeb\x4d\x0f\xf6\xa6\x07\x7b\xd3\x3b\xd8"
-  "\x9b\x5e\x64\x6f\x7a\xb0\x37\xbd\xc8\xde\x8e\x7b\xa0\xb7\xe1\x9f"
-  "\x5f\xbb\x7a\x9b\xeb\x72\xee\xb0\x17\xbd\xc9\xb4\xb7\xc9\xde\x22"
-  "\xbd\xe1\xde\xe6\x60\x6f\x7a\x07\x7b\xcb\x11\xd9\x9b\x1e\xec\x2d"
-  "\x47\x64\x6f\x07\x3c\xd0\xdb\x83\xe9\xd7\xae\xde\x5e\x72\xf9\xfe"
-  "\x73\xcf\x7a\xcb\x91\x69\x6f\x93\xa3\xec\x7a\xcb\x01\x7b\xcb\x01"
-  "\x7b\xcb\x71\xb0\xb7\x1c\x91\xbd\xe5\x80\xbd\xe5\x88\xec\xed\x4d"
-  "\x0f\xf4\x36\xe7\x89\x6b\x57\x6f\x91\x2e\xc7\x3f\x05\xbd\x09\x3a"
-  "\x43\xfd\x71\x7a\x63\xc3\x89\x05\xe2\xc9\x9d\xf3\xa9\xde\x50\x5f"
-  "\x9c\xee\xce\x86\xfb\x65\xf2\x3a\xb3\xf0\x3a\x43\xf9\xa1\xde\x30"
-  "\x8e\xe4\xf4\xa6\x50\xfa\x63\x0c\x69\x81\x58\x52\x88\x23\x9f\x89"
-  "\x61\xcd\x47\x62\xb6\x76\xc5\x91\x16\xc7\x38\x72\xa1\x38\x8e\xdc"
-  "\x2d\xd1\x57\xc6\x79\xd0\x17\xc3\xeb\x6b\xae\x8b\x38\x72\xc1\x3f"
-  "\x5c\xe8\xab\xa1\x57\x7d\x81\x6e\x46\x76\x9e\xa5\xfa\x2a\xe0\xe3"
-  "\xff\xa2\xd8\x3e\xea\x6b\x39\xe8\x0b\xe3\xff\xe3\x84\x29\x7c\xc9"
-  "\x53\x7d\xcd\xef\x35\xfe\x77\xae\x2f\x7d\x98\x67\xfa\x9a\xb4\xcf"
-  "\xae\x2f\xbd\xd6\x02\x3e\x4d\xf0\x67\x76\x7d\x51\x7f\x66\x71\xf4"
-  "\x67\x0b\xc5\xfe\xcc\x1d\x7d\x39\xf8\xb3\x6b\x4a\x5f\xaf\xb8\x1c"
-  "\xff\xb7\x42\x5f\xdc\x0a\x3c\x87\xe3\x95\xbe\xad\xd0\x4f\xb6\xb0"
-  "\x3f\xcc\x30\x41\x3f\xd9\x32\x38\x64\xe3\x12\x32\xae\x73\x15\xf4"
-  "\x93\x41\x77\x19\x4b\xc8\x94\xf4\x25\x44\x69\x7b\x1d\xfa\xca\x27"
-  "\xa1\xaf\x0c\xfc\xd4\xf1\x53\x8c\x5f\x6d\xa4\x91\xd8\xa0\xaf\x8c"
-  "\xe3\x60\x50\xdf\x71\xec\x4f\xd0\x57\x6e\x01\xee\x6b\x29\xa0\x7d"
-  "\xe5\xef\x85\xbe\xf2\x9f\x25\x7d\xe5\x0d\xaf\xf1\x7d\x65\x5e\xfe"
-  "\x45\x62\xd9\xbf\xb8\xc3\x45\x5f\xb9\xa6\xd7\xbe\x32\xf6\x91\x0b"
-  "\xb1\xbf\xfc\x73\xcc\x88\x7c\x9e\xdb\x0a\x4e\xf7\xb1\xaf\xfc\x33"
-  "\xf4\x95\xd7\x52\xd9\x17\x78\x2c\xfb\x68\x97\xcf\x7f\xa0\x6d\xa0"
-  "\xbd\x74\xf9\x22\x90\xb3\xe0\x83\x3a\xc1\x07\xe1\x78\x46\x47\x86"
-  "\xee\x18\xe0\x95\xb3\x0f\xce\x27\xad\xf2\xf7\x42\xdb\x40\x3b\x41"
-  "\xdb\xe0\x7c\x11\xf0\x20\xf8\xa2\xfd\x25\xaf\x91\x49\xa5\xaf\x91"
-  "\x20\x8b\x8f\xb4\x8f\xfc\x4c\x14\xea\xc3\xce\x6d\x36\x47\x6e\x8b"
-  "\x16\x73\xdb\x9f\xbb\xfb\xa2\xde\xb8\xed\x35\x57\xb6\x52\xd3\xab"
-  "\xad\xa0\x8d\x70\xfe\x08\xec\xe5\x62\xd8\x4a\xc1\x7f\x3c\xd5\xd7"
-  "\xab\x2e\x9f\xff\x70\x4f\x5f\xd9\xb3\x7b\xd7\x57\x76\x18\x3b\xe8"
-  "\x21\x95\x5d\x5f\xd2\xbe\xb1\x48\x5f\x3a\xbb\xbe\x44\x7d\xe3\x68"
-  "\x71\xdf\xd8\x1d\x7d\x39\xf6\x8d\xaf\x25\x7d\xc5\xd4\xf4\x51\x5f"
-  "\x6e\xd8\x57\x36\xd8\xd7\x43\x51\x22\x7d\x49\xfa\xc4\x76\x7d\xe9"
-  "\x45\xf6\x25\xea\x13\x47\x8b\xfb\xc4\xee\xe8\xcb\xb1\x4f\x7c\x2d"
-  "\xe9\xeb\x35\x97\xcf\x7f\xb8\xa7\x2f\xbd\x1b\xf6\xa5\x47\xfb\xaa"
-  "\xb2\xeb\x4b\xda\x17\x16\xe9\x4b\x64\x5f\xa2\xd8\x21\x5a\x1c\x3b"
-  "\xb8\xa3\x2f\xc7\xbe\xf0\xb5\xa4\xaf\x45\x9a\x3e\xea\xcb\x0d\xfb"
-  "\xd2\x83\x7d\x3d\xec\x2d\xd2\x97\xa4\x0f\x6c\xd7\x57\x8e\xc8\xbe"
-  "\x44\x7d\xe0\x68\x71\x1f\xd8\x1d\x7d\x39\xf6\x81\xaf\x25\x7d\x2d"
-  "\x6e\xec\x9b\xbe\x72\xdc\xb0\xaf\x1c\xb0\xaf\x87\x23\xed\xfa\x92"
-  "\xf6\x7d\x45\xfa\x12\xd9\x97\xa8\xef\x1b\x2d\xee\xfb\xba\xa3\x2f"
-  "\xc7\xbe\xef\xb5\xa4\xaf\xa5\x69\x3d\xf5\xa5\xc4\x7d\x28\x4b\x92"
-  "\x5d\x5f\xa8\x9b\x4e\xe8\x3b\x75\x7a\xeb\x8e\xb9\xee\x3f\x4d\xde"
-  "\xef\xaa\xbf\x8b\x6b\xd7\x3c\xd3\x8a\xef\x83\xd0\x98\x90\x75\x88"
-  "\x09\x8f\xc4\xec\x20\xd2\x3e\xef\x81\x6e\x7d\xa8\x4e\x61\x8c\x62"
-  "\x9e\xab\x3e\xef\x5f\x65\xf7\xa1\x50\x4f\xd8\x8f\xb2\x2c\x07\x3d"
-  "\xf1\x71\x7c\x61\x1f\xc7\x28\x3a\xcf\x6a\x98\x42\x88\xe3\x13\xe6"
-  "\x41\x1f\x6a\xbe\xa7\x7a\x5a\x16\xe8\x4a\x4f\x38\x4e\x84\x7d\x5e"
-  "\xec\x4b\xe1\xbc\x63\x5d\x4b\x2b\x49\x5f\x49\x54\xdc\xdc\x63\xab"
-  "\x74\xee\x71\xe3\x09\xe8\x53\x2d\x05\xbd\x75\x86\x93\xac\x13\x64"
-  "\x4a\xc6\x6b\xb4\x4f\x25\xf4\xa7\xea\x4c\x66\x6e\xee\xb1\xde\x62"
-  "\x20\x4f\x1b\x58\x73\x29\xe4\xc7\x7e\x54\x6d\x64\x01\x41\x5b\x49"
-  "\xfa\x96\xf8\xa0\x0e\xa0\x0f\xc6\xe9\x43\xdc\x87\x2a\x11\xcf\x37"
-  "\x2e\x70\xd5\x87\xea\x7d\xbe\xb1\xe8\x34\xed\x3f\x71\xf3\x8d\x57"
-  "\x44\x1f\x2a\xd6\xe5\xfc\xc7\xf4\xed\x74\xbc\x01\x65\x5f\xaf\xb1"
-  "\x10\xc0\xd3\x0f\x7e\x6d\x74\x5c\xcf\x92\xa5\x6b\xc0\x3e\x2d\xf6"
-  "\x67\xeb\xe3\x6b\x48\xfa\x6a\xa2\xea\x68\x0f\xf7\x83\x3e\xaa\x8f"
-  "\x05\xb8\x6e\xc3\x49\x2a\x7b\x7c\x47\xcc\xf8\x7a\x0c\xf7\xac\x0c"
-  "\xf6\x65\xd1\x56\xb8\x39\xc7\xf9\x24\xa8\xa8\x99\x4c\xe2\xec\x03"
-  "\xec\xc2\x92\xb9\x29\xd9\xe6\xa3\x33\xa1\x9d\x3c\xdd\xc4\x9a\x51"
-  "\x07\x68\x1f\x87\x9b\x50\x37\xbb\x49\xd2\x71\xaa\x1b\x4e\x2f\x8c"
-  "\x74\x2e\xb8\xbb\x6d\x7c\xee\x42\x3f\x55\xee\xe9\x67\xa9\x54\x3f"
-  "\xc5\x72\xe7\x83\x85\xe7\x23\x97\x6a\x98\x62\x7e\x3e\xb8\xe0\x45"
-  "\x4f\xf5\x13\xd7\xed\xfd\x67\xf7\xf4\x93\x1d\x26\x4f\x3f\xd9\x5a"
-  "\x6e\x6e\x51\xaa\x9f\x34\xaa\x9f\xec\x38\xec\x2b\xd9\xf5\x73\xce"
-  "\x4d\xfd\x38\xf4\x91\xae\x29\xfd\xac\x70\x39\xfe\xd3\x8b\x7e\x64"
-  "\xda\x4f\xb6\x91\x9b\x43\x94\xe8\x47\xcf\xdb\x4f\xb6\x09\xfb\x46"
-  "\x76\xfd\x9c\x72\x53\x3f\x0e\x7d\xa2\x6b\x4a\x3f\xab\x5c\x8e\x7f"
-  "\xf7\xac\x1f\xbd\x4c\xfb\xd1\x6b\xb9\xb9\x42\xa9\x7e\x78\xfb\xd1"
-  "\xc7\x61\x5f\xc8\xae\x9f\xe3\x6e\xea\xc7\x71\xfc\xf4\x5a\xd2\xcf"
-  "\x1b\xe3\x65\xea\x47\xa6\xfd\xe8\x8d\xdc\x9c\xa0\x44\x3f\x39\xbc"
-  "\xfd\xe8\x4d\xd8\xf7\xb1\xeb\xe7\x80\x9b\xfa\x71\xe8\xf3\x5c\x53"
-  "\xfa\x59\x5d\x2b\x4f\x3f\x39\x32\xed\x27\x47\xcb\xcd\xfd\x49\xf5"
-  "\xc3\xdb\x4f\x4e\x1c\xf6\x75\xec\xfa\x79\xd3\x4d\xfd\x38\xf4\x71"
-  "\xae\x29\xfd\x24\x2c\xea\x6d\xbe\x48\x88\x9d\xc5\xf3\xb2\x9d\x10"
-  "\xbf\x61\xfc\x8c\xb1\x73\x9d\xa9\x8a\x58\x96\x52\xdd\xa4\x9f\x27"
-  "\xaa\x0c\x5e\x37\xdc\x9c\xec\xeb\x74\x4e\x96\x8b\xdb\xd6\xfd\x76"
-  "\x17\x9b\xa2\xf4\xc7\xb8\x8c\x9b\x77\xe5\xe6\x26\x3e\xc6\xb1\x54"
-  "\xaf\x4e\x51\xfc\x86\x7d\x54\x88\xbd\x09\xf6\x53\x93\xbe\xf7\x20"
-  "\x6e\x9b\xef\x4a\x2f\xbd\xcf\x4d\x14\x89\x9e\xe3\x13\xfa\x9e\xfd"
-  "\xaa\x17\x8f\xe7\x5d\x13\x5d\xee\xff\xd4\xb3\x5e\xf4\x61\x9e\xe9"
-  "\x05\xfc\xcd\xba\x49\xfb\xa8\x5e\x8e\x3b\xe8\x45\x9f\xd6\x29\xf2"
-  "\x3b\xee\xeb\xc5\xc1\xdf\x5c\x53\x7a\x49\x2a\x72\xd9\xd7\x04\x5e"
-  "\x42\x9d\xe0\xf3\xdd\x1b\xe7\x93\x71\xe9\xcd\x64\x4a\xe7\x4f\xfe"
-  "\x43\x67\x00\xcf\x75\xbe\xee\xef\x55\x07\x1c\x97\x68\x62\x7f\xf0"
-  "\x35\x0d\x0e\xf9\xec\x98\x91\xd4\x45\x1a\x48\xc7\xaa\x70\x92\x79"
-  "\x12\x9f\x55\xaf\x22\xeb\x63\xb1\x2f\xbf\x97\x1c\x6e\x3a\x43\x66"
-  "\x54\xb0\x9d\xf5\x6d\x55\xa4\x7a\xf5\x5e\xc2\xbe\xae\x19\x5a\x0a"
-  "\x79\x5e\x06\x19\x9e\x66\x92\x67\x5f\x80\xfe\xe8\xc4\x78\xa2\x9a"
-  "\xd6\xc6\x9a\xeb\xda\x3e\x23\x85\x70\xaf\x8f\xe3\x09\x41\xf9\xa2"
-  "\x4e\x32\x5f\xc3\xfe\xe7\x01\xaa\x93\x99\x54\x27\x05\xa2\xfe\xa7"
-  "\x1a\xce\x9f\xd0\x82\x3e\x7e\x71\xd0\x47\x53\x2b\x01\xf9\x0e\x9e"
-  "\x61\x02\x7d\x98\x04\x7d\x9c\x22\x89\xcb\x50\x1f\x86\xae\xe7\x5d"
-  "\x3b\x78\x7d\x14\x21\x7f\x69\x89\x2a\x5f\xe8\x7f\x9e\x16\xe9\x43"
-  "\x78\x27\x4b\xac\x0f\xa1\xef\xbf\x0a\xf4\xb1\xd2\xde\xff\xbc\x00"
-  "\xfd\xcf\x7c\xe8\x7f\x26\x1d\x25\x4c\x7e\xa2\xa7\xfa\x48\x71\xe9"
-  "\xff\x05\x5d\xa0\x6f\xe9\xf4\xd5\x35\xa0\x1e\xea\xe3\x2b\x09\xea"
-  "\x04\xfd\x89\xf5\x27\x7f\xaf\x84\x38\xb0\x1d\xc3\xe0\x90\x0e\x16"
-  "\xfa\xfc\xd0\xdf\xaf\x8f\xf8\x8a\xe0\x98\x01\xd5\x41\x67\x67\xbd"
-  "\xb1\x8a\xa0\xec\xab\x57\x7f\xc5\xe9\xe1\x34\x93\x72\xec\x25\x13"
-  "\x61\xee\x01\x1c\x42\x7f\x5f\xf5\x32\xbe\x97\x0b\xdc\x56\xb8\x80"
-  "\x4c\x9a\xa6\x65\xcd\xd8\x37\x45\x1b\xc2\x67\x4f\x90\xd7\xea\xb4"
-  "\xff\x20\x38\xae\xd3\xe9\xb3\x29\xf9\xe3\x38\x42\x90\xdf\x50\xee"
-  "\x03\x57\xd8\xf5\x84\xcf\x93\x70\xba\x7a\xd6\x8d\xe7\x5c\xc5\xfa"
-  "\x8a\x30\xb8\xf5\x7c\x72\x07\x3f\x5e\x50\x24\x8c\xa9\xc9\x1d\x2f"
-  "\x10\xc6\xd4\x7e\xa6\xcf\x93\x24\x7d\x01\xf6\xe3\xb1\xbe\xd6\x36"
-  "\xb9\xa7\xaf\xec\x30\xcf\xf5\xd5\xee\x44\x5f\x6f\xa5\x76\xd7\x57"
-  "\xb6\xd6\xae\xaf\x49\x4a\x91\xbe\xd2\xa8\xbe\xb2\xe3\xec\xfa\xca"
-  "\x8e\xef\x5d\x5f\x3d\x3c\xdf\x7a\xd5\xeb\x2b\xd5\x65\xff\xc7\x41"
-  "\x5f\x32\xec\xeb\x67\x27\xfa\x7a\x3b\xc8\x89\xbe\x44\xf6\x35\x29"
-  "\xc2\xae\x2f\x3d\x6f\x5f\xd9\x22\xfb\xca\x76\xc3\xbe\x7a\x78\xae"
-  "\xf5\xaa\xd7\xd7\x3a\x97\xcf\xff\x48\xf5\xa5\x97\x61\x5f\xdf\x38"
-  "\xd1\xd7\xba\x96\xee\xfa\xd2\x8b\xed\x6b\x9f\x48\x5f\xbc\x7d\xe9"
-  "\x45\xf6\xa5\x77\xc3\xbe\x7a\x78\x9e\xf5\xaa\xd7\xd7\x7f\xf5\xf8"
-  "\xfc\x8f\x48\x5f\x32\xec\xeb\xef\x4e\xf4\x95\x96\xeb\x44\x5f\x22"
-  "\xfb\x9a\xec\x6d\xd7\x57\x0e\x6f\x5f\x7a\x91\x7d\xe9\xdd\xb0\xaf"
-  "\x1e\x9e\x63\xbd\xea\xf5\xb5\xde\x65\xfc\x27\xd5\x57\x8e\x0c\xfb"
-  "\x4a\x72\xa2\xaf\xf4\xa9\xdd\xf5\x95\x23\xb2\xaf\xc9\x51\x22\x7d"
-  "\xf1\xf6\x95\x23\xb2\xaf\x1c\x37\xec\xab\x87\xe7\x57\xaf\x7a\x7d"
-  "\x6d\x70\x39\xfe\x2d\xd6\x57\x47\x96\x10\x1f\x56\x48\xf5\x05\xf1"
-  "\xba\x5f\x0b\xed\x5b\x09\xfa\x72\x1d\x1b\x6e\x30\x76\xe9\xea\x7b"
-  "\x7b\x6c\xc8\xe9\x89\x9f\xa7\x40\xfd\x60\x8c\x88\x31\x61\x47\x26"
-  "\xd5\x11\xce\x01\xf6\x18\x17\xba\xf3\xfe\x93\x0c\x3d\x09\xfd\xaa"
-  "\x7e\xd7\xd3\x97\x72\xf4\x94\xe1\xf2\xfd\x27\xa9\x9e\x04\xbf\xe5"
-  "\xae\x9e\x9c\xf9\xac\xcc\xbc\xee\x7a\xd2\x6b\xed\x7a\xa2\x7e\x0a"
-  "\x7d\x17\xfa\x2a\xa9\x9e\x7a\xf0\x57\xee\xbc\x7f\x71\xd5\xeb\x29"
-  "\xcb\x25\xff\xe9\x18\x5b\x25\x1c\x55\x70\x54\xc3\x51\x63\x65\xc8"
-  "\x93\xc5\x8c\xad\x01\xf3\xe3\x3a\x7f\xc5\x6b\xbb\x9d\x1f\xc4\x0e"
-  "\xba\x69\x1a\xe6\x01\xd9\x72\xef\xb7\x0a\x65\xb0\xe9\x04\x65\x57"
-  "\xed\xa3\x88\x24\xc5\x34\xef\x60\xa1\x2c\x9f\x14\x12\x2c\x94\x05"
-  "\x6d\x4a\x06\x59\x57\xfb\xa5\x04\x0f\x82\xfc\x35\x6c\xfa\xec\x91"
-  "\x90\xd7\x8b\x2b\x33\x45\xc9\xbd\x2b\x22\xe4\xb5\xae\x55\xe0\xfb"
-  "\xe1\xd5\x7e\x0a\xc8\x4b\xcb\x1c\xc2\xe7\x53\xdb\xd6\x12\x35\x57"
-  "\x4f\x86\xc1\xfb\x39\xd6\x73\x28\x9f\x6f\x9c\xb8\x8e\x3e\x29\xc1"
-  "\x5c\x79\x7c\x9e\x61\x2c\x63\x34\xf3\x6d\xd1\x88\xf3\x59\x9f\x20"
-  "\x58\xa6\x90\xcf\x9b\x2f\x6b\xbc\x24\xcf\x56\x42\x70\x3f\x5a\xae"
-  "\x7e\xf1\x0c\xe1\xeb\xe7\x83\x79\xad\x43\x67\xb5\x5a\x15\xca\x40"
-  "\x1b\x43\x02\x25\xd7\xac\x23\x5c\x7e\x3e\xaf\x2f\x97\x77\xd0\x94"
-  "\x32\xc8\x1b\xc4\xcb\x5c\x29\x96\x39\x9f\xcf\x4f\x90\xa3\xf8\x9c"
-  "\x75\x2d\x83\x65\xe1\x79\x15\x3b\xe8\xe1\x7d\xd0\x86\x29\x42\x3e"
-  "\xe1\x7e\xf5\x31\x84\x70\x79\x19\x72\x2f\xaf\x93\xe1\xd0\x8e\x60"
-  "\x21\x1f\xae\xa7\x20\xe4\x4d\xb2\x92\x9b\x4b\xed\xb2\x19\x61\x4d"
-  "\x9f\x5d\x61\x4d\x51\x4e\x75\x2c\xd3\x2f\x45\x61\xc0\x7c\x47\x5a"
-  "\xb9\xb2\x51\x7f\x11\x90\xff\x06\x5e\x46\x21\x54\x27\xaa\x2e\x9d"
-  "\x58\x19\x0b\x9e\xab\x2e\xa1\x75\x1d\xc9\xe7\x9b\xd6\x3d\x9f\x52"
-  "\x9c\xef\x46\x2a\xc7\xc8\x63\x20\x9b\xb0\xee\x79\xbd\xc4\x79\x47"
-  "\xd1\xbc\xcf\xa5\x42\xde\xd9\xdd\xf3\xaa\xc4\x79\x6f\xa2\x79\xc3"
-  "\xa7\x40\xde\x70\x27\x75\x1d\x21\xca\xeb\x4f\xf3\xbe\x60\x82\xbc"
-  "\x11\xdd\xf3\xaa\xc5\x79\x6f\xa6\x79\xe7\x63\x1d\x22\xbb\xe7\x0d"
-  "\x16\xe7\x1d\x4d\xf3\xce\xd9\x05\x79\xa3\xba\xe7\x4d\x16\xe7\xfd"
-  "\x15\xcd\x3b\x37\x0a\xf2\xc6\x38\xe6\x2d\xa5\xba\xbd\x8d\xd7\x6d"
-  "\x00\xcd\xfb\x72\x00\xe4\x5d\xe4\xa4\x6d\x03\xb8\x72\x69\xde\x31"
-  "\x34\xef\xb3\x04\xf2\x6a\x9d\xe8\x42\x9c\x77\x2c\xcd\xbb\xb4\x01"
-  "\xf2\xc6\x39\xd1\x85\x38\xef\x2d\x34\x6f\x74\x25\xe4\x8d\x77\xa2"
-  "\x0b\x7b\xde\xa1\xaf\x46\x42\x9e\x04\x68\x67\x83\x13\xd9\x8a\xcb"
-  "\xbc\x95\x96\xb9\x50\x05\xf9\x93\x9d\xc8\x56\x9c\xf7\x36\x9a\xf7"
-  "\xb5\x6a\xc8\x9b\xea\x44\xb6\xe2\xbc\xb7\xd3\xbc\x8b\xb4\x90\x37"
-  "\xad\x7b\x5e\xb0\x37\x2a\xdf\xfb\x78\xf9\x8e\xa3\xf9\x97\xa8\x21"
-  "\x7f\x86\x13\xf9\x62\x79\x82\xcd\xde\x41\xf3\x46\x05\x41\x5e\x9d"
-  "\x13\xf9\x8a\xf3\xde\x49\xf3\x26\xec\x83\xbc\xb9\x4e\xe4\x2b\xce"
-  "\xfb\x6b\x9a\x37\x16\x31\x99\xe7\x44\xbe\xe2\xbc\x1a\x9a\x37\x2e"
-  "\x17\xf2\x16\x39\xa9\xef\x6d\xa2\xbc\x77\xd1\xbc\x2b\xb1\xbe\x65"
-  "\x4e\xf4\x21\xce\x7b\x37\xcd\x9b\x38\x0d\xf2\x96\x3b\xd1\x87\x38"
-  "\xef\x6f\x68\xde\x55\x68\xc7\x15\x4e\xf4\xd1\x95\x17\xfc\xc2\x78"
-  "\xeb\xd0\x37\xe2\x4a\x31\xbf\x42\xc9\x3d\xa3\xc2\x32\xdc\xfa\xfe"
-  "\x5c\x5e\xc0\x49\x35\xcf\x77\x13\x68\x99\x6b\x46\x42\xbe\x4a\x42"
-  "\xd7\xf3\xab\x3c\x62\xe6\xf8\x08\xfc\x8b\xe5\xfe\x52\x3b\x77\xdf"
-  "\x43\xf3\x2e\x8b\x87\xbc\xfb\xc4\x1c\xca\x32\x4a\x71\xbe\x89\x34"
-  "\xdf\x06\x94\x55\x95\x34\x9f\x97\x3d\xdf\xd0\x94\x38\x38\xbf\xbf"
-  "\xc4\x81\x8f\xa1\x9e\xe2\xb2\xee\xa5\x65\xbd\x35\x0e\xf2\x56\x4b"
-  "\xf3\x59\xee\x13\xe5\xbb\x8f\xe6\x4b\x45\xd9\x1c\x92\xe6\x53\x8b"
-  "\xf3\xdd\x4f\xf3\x65\x22\x67\xd5\x48\xf3\x05\x8b\xf3\x05\x59\xd3"
-  "\xd7\xa5\x72\x79\x53\x94\xb5\x8e\xf2\x03\x59\xdf\x27\xf2\x69\x0f"
-  "\x58\xd3\xd3\x82\xf8\xbc\x0d\x82\x0c\x39\x39\x53\xcc\x33\x3c\xe6"
-  "\x1f\xb4\xa6\xaf\x6f\xe1\xf3\x1d\x13\xfb\x01\x91\xaf\xfd\x2d\x3b"
-  "\x34\xa9\x85\xf7\xa3\xdc\xf3\x92\xc0\xef\x4d\xce\xe2\x0d\xed\xdd"
-  "\x64\xd8\x49\xe6\xbf\x8b\xa8\xef\x11\xd6\xd4\xcf\xe3\x6c\xcf\x56"
-  "\x34\xa7\x32\xd4\xc4\x5a\xc4\x69\x1b\x19\xb6\x61\xa2\x89\x28\x71"
-  "\xfd\x24\xd6\x27\xbf\xd1\x00\xe9\xc6\x31\x73\x1a\xda\xd3\xff\xbb"
-  "\xc2\xa0\x78\x30\x17\xd7\xf2\x80\xef\xfb\x0c\x24\x8d\x5b\xf7\x79"
-  "\xe3\x5a\x88\x07\x99\x60\x05\xae\xc1\x5c\x0a\xdf\xb3\xe0\xe0\xd6"
-  "\x3d\xd6\x12\x86\x5d\x47\x82\xab\x57\x5a\xc8\x89\x78\xc2\xd8\xb2"
-  "\x22\xb5\xea\x58\x5c\x4f\x24\x4f\xc1\xae\x8a\x99\x02\x75\xd1\xc1"
-  "\x7d\xa3\x9a\xe1\x37\x57\x17\x68\x3f\xf8\xc6\x8c\xea\x58\x5c\x63"
-  "\x28\xef\x01\xa3\x4f\x81\x8e\x7d\x6b\xce\x8f\xda\x44\x72\xcb\x49"
-  "\x26\x2f\xe8\x2c\x70\xc3\xd9\x55\x31\x8f\x62\x19\x36\x9f\xc8\x0c"
-  "\xc8\x13\x87\x6b\x91\xb0\x79\x85\x5a\xba\x4e\x49\xde\x7a\xae\xfe"
-  "\x6b\xd9\x06\x36\x60\x4e\x99\xad\x23\x35\x19\xf7\x6f\xa8\x4e\x3c"
-  "\x49\x9a\x45\xe7\x8c\x37\x17\x72\x6b\x98\x60\xbb\xa0\x8d\x65\xed"
-  "\xe9\x79\xc9\x06\xc5\xa8\x6a\xba\x46\x49\x9e\xcb\xfd\x41\x21\xb6"
-  "\xf6\x63\x33\x23\x2b\x20\x7f\x25\xc4\x77\x4d\x54\x0e\x79\xfb\x0d"
-  "\x0a\x1f\xe1\x7b\x8d\x41\x31\xdc\x9f\xff\x7e\xcc\xa0\x18\x6f\xe2"
-  "\xbf\x1b\x84\xb5\x57\x9c\xaf\x05\x13\x99\x00\xed\xce\xb5\x15\x86"
-  "\x7b\x61\x3c\x8a\xeb\xb2\xb1\x3e\x91\x09\xea\xb1\xb8\x5f\x47\x7e"
-  "\x3c\xdc\x33\x97\xae\xa7\x99\xff\x08\x7c\xfa\xf1\x9f\x46\xfe\x93"
-  "\xc5\x3c\x9c\x6e\x03\x22\xd4\x6c\x46\x6e\x0c\xb6\x39\xd1\xca\xda"
-  "\xa0\xdc\x2a\x36\xad\xa1\xa1\x3e\xbe\x95\xd0\x75\xa8\xf3\x17\x72"
-  "\xeb\xe2\xa0\x5c\x41\xf6\xec\x90\x86\x06\xee\x5e\x99\x05\x3a\x71"
-  "\xbd\x70\x01\x97\xc0\x7b\xef\xbb\x3f\xe8\x81\x07\x7f\x3b\x69\xf2"
-  "\xbc\xf9\xaf\x44\x45\x2f\x78\x35\x66\xe1\x6b\xaf\x2f\x5a\xbc\x64"
-  "\xa9\x76\x59\xec\xf2\xb8\x15\x2b\x57\xc5\xbf\xb1\x1a\xf3\x75\xb5"
-  "\xa1\x70\xaa\xc2\xc4\x10\xb8\xcf\x13\x78\x1f\x6e\xdf\x3b\x4c\xa3"
-  "\x7a\xc9\xaf\x55\xaa\x9d\xcb\xb4\xde\x9f\x10\x5c\x97\xb9\x8d\x29"
-  "\xb8\x0b\xd7\x88\x06\x0c\x28\xea\x8b\x9e\xaa\xc6\x3d\x06\x5a\x98"
-  "\x82\x80\x3a\xe3\x53\xd5\xb8\xc7\xc5\x41\xff\x56\x32\xee\x36\xdc"
-  "\x87\xa0\xc0\x0b\xcf\x97\xde\x49\xc8\x21\xb8\xd6\x59\x99\xb7\xa9"
-  "\x88\x7f\xce\x28\xd6\x98\x3b\x8a\x6d\xc3\xf2\x73\x37\xb3\xad\xc6"
-  "\x35\x31\x24\x0b\x7e\x03\x76\x54\x27\x98\x82\xe3\x07\x21\xe2\x85"
-  "\x58\x36\xa0\x64\x33\xdb\x92\x3a\x8a\x6d\x79\x6b\x33\xdb\x56\x3a"
-  "\x8a\x35\x8c\xcb\x25\xde\xed\xe9\x05\x3a\x03\x93\xcf\xad\x1b\xbd"
-  "\x11\xce\xdb\x86\xe6\xa7\x6d\x84\x73\x13\x2d\x64\x40\x29\xfc\x86"
-  "\x34\xd3\x41\x35\xad\xf7\xfb\x67\xcc\x03\xa1\xbc\x38\xb6\x73\x91"
-  "\x22\x0b\xee\x43\xf5\x54\xa8\x38\x04\x1a\x81\xfb\x19\xeb\xcd\xcd"
-  "\x80\xb3\x42\x6e\xed\x75\xb8\x9f\x5f\x7d\x5e\x1b\xc1\xf2\xf6\xc4"
-  "\x9a\x07\x2e\x1f\xcd\x5a\xe0\x5a\x83\x6d\xcd\x22\x85\x81\x29\xd8"
-  "\x0f\x65\x9b\xc4\xed\xd1\x2c\x58\x1c\xa7\x5e\xb2\x62\xd1\xa2\xbb"
-  "\x86\x12\x0d\xf7\x29\xd9\x1f\x23\x0e\xca\x23\x39\x9b\xd9\x43\xd0"
-  "\xce\x6a\x68\x6f\xcd\x11\x88\xba\x01\x33\x04\xda\xa4\x83\x3a\x3c"
-  "\x0b\xe9\xfb\xe1\xfb\x7e\xa8\x7b\x0d\xdd\x53\x61\x57\x0a\x9b\x5e"
-  "\xe8\x0d\xf5\x44\xde\x57\xe3\x7a\x55\x67\x57\xcd\x56\x40\xbb\x73"
-  "\x21\x5f\x8d\x7a\x34\xb9\x03\xae\x3b\x0e\xf5\x28\x87\xef\x98\x9f"
-  "\xb3\x19\xc8\x7f\x88\xb6\x6b\xd7\x32\xfc\x0d\xb2\xaa\x2e\x1e\xc5"
-  "\x66\xb4\xa7\x17\x56\xe1\x7a\x76\xdc\x3a\xdf\xf0\x1b\xe4\x52\x03"
-  "\x79\x75\x67\x93\x66\x2b\xa0\xff\xa5\x28\xb5\x97\x99\x86\x75\xc2"
-  "\x7a\x60\x1f\xf0\x30\x44\x5f\xb6\xce\x70\x32\xc1\x4c\x14\x87\x5b"
-  "\x08\x29\xda\xcc\x96\xc1\x51\x04\x47\xde\x67\x70\xee\x53\x38\x6a"
-  "\x20\xbd\x16\x3e\x3f\x83\xcf\x4f\x5b\xb8\x39\x3b\x7f\xac\xf7\xf2"
-  "\x04\xb6\x75\x62\x1e\xb9\x1d\xcb\x07\x6c\x3d\xdf\xcc\xec\x6c\xc4"
-  "\xba\xe3\xda\x91\xec\xd0\xa2\x69\xd2\x35\xf6\x8a\xab\x09\x9c\x87"
-  "\xcf\x63\xf4\x53\x7c\x94\x04\xc0\x31\x85\xff\x9e\x0a\x79\x76\xf1"
-  "\xdf\xf3\xe0\x28\xef\xfd\x70\x2c\xcf\xd5\x51\xaa\x72\x3f\xaf\x3b"
-  "\xc7\xae\x69\xee\xe5\x2b\xab\x21\xcc\x3b\x6a\x38\xc2\xa5\xe9\xef"
-  "\x04\xd2\xb4\xf7\x2c\xf4\x77\x85\x17\xff\x19\x04\x07\xc8\x69\x3b"
-  "\x94\xbf\x5d\x4b\xd3\xb6\x27\xc0\xe7\x21\x38\x1a\xa4\xf7\xdf\x05"
-  "\xd7\xef\x8a\x42\x7d\x76\xae\x05\xde\x06\x5d\x1a\x98\xa2\x00\xd4"
-  "\xd1\x46\x8a\x2d\x85\x8d\xe5\xd2\xfc\x01\x5b\x45\x76\xfc\x94\xf8"
-  "\x48\xf1\x53\x6c\x76\xc0\x8f\x0e\xf9\x08\xec\x25\xaa\x94\xe2\x65"
-  "\xff\xd9\x35\x51\xf0\xbb\xd8\x02\xe5\xec\x57\xbf\xc4\x95\xc1\xc5"
-  "\xcd\x1b\x4f\x12\xe2\x13\x43\x94\xc8\x2f\x6d\x4c\xc9\x74\xc4\x2c"
-  "\xde\x9b\xbf\x2f\xad\x0b\xd4\x0f\xd2\xca\xb0\x7e\x4b\xa1\x5c\xf8"
-  "\x5d\x0e\xf9\xca\xea\xc9\x19\xa1\x6e\xdc\x35\xe9\xaf\x01\x1e\xf9"
-  "\xfa\x62\x99\x78\x1d\x6b\x6f\x97\x3f\x5e\x43\xef\x5d\xaa\x80\x74"
-  "\xec\x5f\x92\xa4\x5f\xc8\x00\x7c\xbe\x19\x31\x89\x9f\xf5\x96\x40"
-  "\xb0\xa5\x10\x62\x6b\x0f\x27\x13\xfd\x49\x20\xd8\xdb\x90\x66\xa6"
-  "\xa4\xe5\x9e\x04\x12\x88\xe5\x21\xaf\x1b\x98\x92\x8a\x52\xb4\x45"
-  "\xda\x8e\x0b\x74\x9d\xac\x22\xff\xcf\xb4\x84\xbb\x4f\x09\xd6\x07"
-  "\xce\x8b\xee\x9b\x8b\x7d\xc9\x8d\xab\x69\x5b\xe1\x5e\xe5\x70\x7d"
-  "\x25\xb6\x1d\xe5\x09\xe7\xab\xa0\x4e\xc1\x78\x8e\x5b\x7f\x9b\xb6"
-  "\xa7\x1c\xd7\x68\x45\x79\x60\x7e\xdc\xb3\x85\xae\xd9\x57\xc8\xad"
-  "\x89\x06\xe5\x57\xa2\x3e\x58\xb8\x07\x96\x91\x64\x61\x2d\x2c\xf0"
-  "\xd1\x3b\xab\xcd\xe0\xff\xcb\x3e\x94\xea\xa7\x34\x4f\xac\x1f\xb8"
-  "\xae\x12\xae\x3f\xc4\x42\x1b\x91\x4f\xe0\x9e\x7e\xe8\xf3\x21\x4d"
-  "\x67\x4b\x87\x32\x56\x9a\xb9\xf1\x14\x28\x67\x3b\xd4\x45\x87\xe5"
-  "\x40\x7d\x0e\xf1\x65\xb5\x7c\x94\x20\xd5\x35\x5f\x5e\x39\xea\x9c"
-  "\xb3\xe7\xd5\x5c\x9b\x80\xbb\xca\xde\x28\xa1\xe7\xaa\x20\x4f\x15"
-  "\xdb\x19\x42\x70\xcd\x53\xea\x4b\xb8\x73\xfb\x92\x2e\x70\xfa\x3d"
-  "\x44\x79\xad\x2c\x7f\xf9\x9b\x6c\xab\xbd\xde\x65\x61\xc2\xba\xb1"
-  "\x7c\xbd\xf7\xe1\xfd\xd8\x55\x11\x9c\x6f\xc5\x7b\xe0\xf5\x7c\x79"
-  "\xe3\xb1\x3c\x41\x56\xf7\x40\x3d\xa8\xbc\x4a\x23\x21\xbd\x1c\xb1"
-  "\xc8\xc9\x0d\x78\xf4\x6c\x12\x62\xb1\x6c\x36\x5c\xbf\x3f\x0b\x7f"
-  "\xaf\xc2\xdf\xa5\xad\x1c\xc7\x76\x9d\x2f\x2d\xc2\xf3\xf5\xd0\x4f"
-  "\xdf\xf8\x3a\x60\xc9\x46\xc8\xed\x23\x49\xa0\x69\x2d\xd7\xb6\x5d"
-  "\xa6\x35\x53\x15\x07\x2d\x84\x60\x3d\x41\x46\x55\x50\x57\x88\x39"
-  "\x0a\xa6\x60\x5d\x81\xaf\xf7\xb1\x60\x9a\x58\x67\xe0\x33\xbe\x7e"
-  "\x5b\x16\xf3\xba\xdf\x87\x6d\x44\x79\xde\x43\xb9\x0f\xce\xbd\x33"
-  "\x1c\xeb\x6e\x6f\xf7\x96\x10\xb1\x8c\xb9\x76\x83\x1e\x50\x5f\xa8"
-  "\x17\x51\x99\x88\x7d\x1d\x94\xb5\x8b\xfe\xa6\xd8\x40\x59\xeb\x46"
-  "\xb1\xb5\x98\xdf\x9e\x77\x6b\x0a\x9e\x4b\x84\x7b\x4f\xd4\x12\xc4"
-  "\xbf\x02\xd7\xfe\x85\x72\x77\xe1\x7e\x3c\x50\x06\xee\xb1\x03\x3a"
-  "\xdf\xfa\x05\xe2\x11\x7e\xd7\xf2\xf7\x38\x06\xfe\x7c\x3c\x1c\x53"
-  "\xec\xf6\xbf\xf5\x63\x29\xbe\xb6\x38\xda\x3f\xea\x5b\x67\x4b\x0a"
-  "\x21\x1c\x1e\x62\x89\xfa\x34\xb3\x75\x1e\xef\x3b\x78\x5d\x6f\xfd"
-  "\xf3\x41\xb0\x17\x7b\x19\x5b\xa7\x38\xe8\xba\x8a\xc3\xe3\xaa\x69"
-  "\xb8\x9f\xb1\x02\xae\xad\xe2\xcb\xe1\xda\xcc\xe1\x69\x2d\x87\x81"
-  "\x5a\x76\x15\xb4\xb3\x0b\x07\x5b\xf2\x78\x3d\xd7\x3a\xc8\x84\xaf"
-  "\x7b\x71\x0b\xee\xd1\x80\x9c\xd4\xbe\x96\x3c\xda\xde\x69\xe7\x25"
-  "\xd4\xbd\x8d\xd3\xfd\xd6\xe0\x52\xea\x6f\x79\xde\xda\x42\xcf\x8f"
-  "\x92\x60\x18\xeb\xb2\x82\xc3\x2f\xd6\x25\x29\x02\xeb\x52\xc5\xd5"
-  "\x23\x49\x4d\xe0\x5c\x1b\xde\x1f\xca\x8a\xe7\xed\x55\x28\x6b\x1a"
-  "\x96\xf5\x16\x70\x15\xd6\x09\xee\xdd\xc8\xf1\xdf\xef\x39\x1c\x4c"
-  "\xe7\xeb\x5e\x63\x5e\x8b\xd7\x96\x04\x5f\x60\xb8\x6b\x6b\x20\xdf"
-  "\x3e\x33\x5d\xc7\x79\x28\x5c\x5f\xa1\x9e\x8f\xf9\xdf\xdb\x85\x1c"
-  "\xad\x7e\x91\xfb\xbe\x49\xfd\x1c\x60\xf5\x24\x51\x42\x79\x5e\x88"
-  "\x51\x01\x17\x6d\xcc\x7b\x6f\x43\x8c\x81\xfa\xda\x05\x31\x52\x05"
-  "\xca\x1b\xb1\x0c\x31\x52\x50\x7b\xfa\x3b\xfb\x04\xdc\xc2\x7d\x8a"
-  "\x50\xf6\x54\x3f\xef\x5c\x00\x1c\x57\xd9\xb1\xf5\xce\x05\x5e\x8e"
-  "\x15\x20\x47\x2f\xb8\xdf\x1b\x7c\xbb\x2a\x20\x3f\xc4\x62\xef\x2d"
-  "\xe4\xeb\xce\xef\x11\x51\x7e\xa3\xa0\x07\xde\x56\x6b\xb3\x90\x7f"
-  "\x39\x1d\x94\xef\xe2\xaf\x2d\xa7\xf7\x2a\xdf\x2d\xe4\xc5\x18\x91"
-  "\xae\xcf\x5e\xbe\x1b\x79\x70\x22\xe8\x9e\xe3\x3e\x6e\xaf\x2a\x9a"
-  "\x86\xb6\x43\xef\xf1\xde\xb3\x1c\x0e\x21\xee\xb1\xe3\xa8\x3c\xd5"
-  "\x81\x9f\x90\x8b\x75\x75\x50\x06\xf2\x29\x62\x09\x39\x15\xfb\x12"
-  "\x50\x5e\x04\x6f\x3f\x42\x9d\x7f\x91\x62\xe5\xbd\xc7\x01\x2b\x13"
-  "\x44\x65\x1b\x9c\xf9\xb9\x52\xca\x81\x45\xf4\x9a\x6d\xf7\xf2\x6d"
-  "\xdb\x45\xdb\xc6\xff\x46\xb9\x25\xa2\xdc\xde\x3d\x27\x92\x23\xc8"
-  "\xed\xdd\x79\x7c\xfe\x2a\xe4\x72\xbb\xbd\x6e\x2b\x16\x6c\xb9\x3b"
-  "\x5f\xbc\x3b\x13\xed\xc1\x5e\xaf\x6d\xf1\x0e\x7c\x51\xe5\x9c\x2f"
-  "\xb6\x85\xf0\xed\x2d\x73\xb0\x8d\x72\x3e\xde\x8d\x16\xf4\x50\x67"
-  "\xea\xe0\xd7\x22\x2f\x8c\x46\xfe\xc4\x7b\x8b\x7d\x50\x09\x95\x2b"
-  "\x6f\xcb\xef\x3e\xd2\x5d\x0f\xef\x7a\x8b\xed\x19\x75\x8d\x9c\x80"
-  "\x65\xa0\x4e\xb9\xb8\x12\xd2\xa8\x5e\xb7\xb5\x20\x37\x88\x39\x1a"
-  "\xf2\xe6\xda\x58\xb4\x97\x77\x55\x52\x5b\xdc\x96\xc0\xdb\xa2\x70"
-  "\xef\x6f\x41\x47\x81\xa2\xfb\xa6\x3a\xdc\x17\x75\x73\x08\xe5\x40"
-  "\xdb\xf8\xee\x11\xc1\xa7\x61\x7e\xb8\x36\x1e\xae\xa9\x72\xf0\x8f"
-  "\x3a\xac\x1f\xdc\x2b\x90\xe3\xac\xcd\x1c\x57\xc4\xb7\xd3\xfa\xec"
-  "\x2f\xe5\xfd\x04\xa4\x05\xf2\x69\x69\xbc\x2f\x11\x70\x33\x41\x5a"
-  "\xa7\xf7\xfc\x9d\xc7\x47\xdb\x02\x85\xf8\x88\x2b\x8b\xe3\xa2\xf7"
-  "\x02\xf8\xf6\x61\xda\x04\x9a\x56\xde\x82\x69\x59\x54\x0e\xb9\x2c"
-  "\xe7\xaf\xca\xd3\x78\x7f\x85\xf6\xc5\x18\x98\x77\xcc\x68\x63\xf8"
-  "\x1b\xca\xd0\x62\xf9\xf5\xc9\x1d\xd8\x87\xc8\x83\x73\xb9\xc8\x07"
-  "\xc8\x17\xea\x05\x94\x37\xd4\x33\xb8\xcf\x03\xc8\x3b\x18\x87\xe0"
-  "\x79\xc8\x97\x8a\x5c\x04\xe9\x47\x71\x5f\x23\xf6\x27\x2f\x28\xf7"
-  "\xbd\x7d\xfc\xb5\xdf\x73\xb1\xc2\x4f\x21\x03\x84\x34\xe1\x3a\xe0"
-  "\x86\x4d\x78\x1d\x5e\x2f\xf0\x17\x72\x97\x05\xb9\x89\xbb\x5f\xc5"
-  "\x5d\x3c\xc6\xb9\x7e\x83\x10\x17\x75\x32\xa2\xbc\xb8\x1e\x34\xc7"
-  "\x69\x15\x71\x94\xcf\x2a\xa2\xf1\x5a\x4e\x7f\xc0\x95\x89\x17\xd8"
-  "\x6f\x4b\x63\x89\xb2\xe4\x0c\xf2\x62\x61\x14\xad\x67\x45\x35\x6d"
-  "\x47\xc5\x7a\xae\x1d\x94\x53\x75\xb4\x2e\x85\x51\x25\x1d\xdc\xb9"
-  "\x6d\xd8\x16\x3c\xb7\x51\x74\x8e\xed\xd4\xe0\xb9\x8f\xb8\x7a\x39"
-  "\x5c\x67\xeb\x8c\xe9\x96\x1f\xf7\xe9\x02\x0e\xf5\x2a\xd9\x2c\x70"
-  "\xef\xf6\x60\xbe\x9e\x56\x81\x77\x41\x2e\x19\xc8\xbd\xdc\xb9\x05"
-  "\x7c\x9e\x19\xfc\x27\xc7\xef\xdb\x27\x50\xb9\xfa\x33\xbc\xbc\x73"
-  "\x69\x3b\xb6\x73\x7b\x7f\xb3\x3f\x85\x83\x6c\xb7\x8f\x13\x64\x2b"
-  "\xfe\x8e\xf6\x03\xf7\x47\x5b\xa0\xbc\x92\xc0\xf5\x61\x8b\x30\x0f"
-  "\xd6\x89\xfa\x88\x8a\x00\xc7\x98\xfa\x04\xb3\xf3\x43\xf4\x4b\x34"
-  "\x56\xdd\x99\xcf\x8f\xcf\x90\xea\xd8\xad\xe0\x17\xb6\xb7\x08\x1c"
-  "\xc3\xb6\x87\x40\x9f\xbf\x19\xeb\xf8\x3d\xa6\xe1\x1a\xc2\xe2\x3c"
-  "\xc8\x4f\xef\x77\x18\xf8\x32\xb7\x57\x0b\xbc\x81\x5c\x52\x67\x6a"
-  "\xe6\x63\xba\x1d\xda\x12\x9e\x4b\x4e\x33\x3b\x96\x49\xe3\xb0\x1d"
-  "\xcb\xa4\x9c\xb1\xf3\x6d\x47\xce\x80\xb8\x39\xb5\x3d\x7d\xc7\x54"
-  "\x49\x1c\x00\x69\x3d\x73\xc7\x0e\x7f\xb4\x51\xdc\x97\x81\xe3\x27"
-  "\x6e\xcc\x69\xc7\x97\x42\x9d\x91\x37\xcf\xae\x11\xc6\x2f\x76\xae"
-  "\xc0\x58\xcd\xe1\x7e\xfb\x24\xdc\x89\xf7\x13\xca\x53\x12\x5c\xd7"
-  "\x1f\xe4\x80\x63\x2e\x3b\x52\x79\x9e\x2f\x93\x70\x25\xef\xc3\x90"
-  "\x27\xa5\xbe\xaa\x30\x5a\xea\xab\x76\xce\xeb\xce\x91\x3b\x03\xdd"
-  "\xf7\x55\x3b\xbd\x90\xb7\x04\x8e\x94\x72\xc1\xce\xa0\x12\x49\x2c"
-  "\xbb\x63\xbf\x10\xcb\xda\x79\x74\xc7\x34\xe4\x28\xb8\x7f\x15\x7f"
-  "\x6f\xc0\x5f\x7e\xa5\x70\x6f\xc0\x51\x4b\x9d\x1a\xb0\x99\x5e\xe8"
-  "\x0f\xdf\x75\x7c\x0c\xc8\xd9\x66\x07\xb7\xb6\x7a\x45\x23\xe0\x6f"
-  "\x28\xe2\xac\x7a\xc9\x19\xd2\x62\xf7\x15\x87\xce\x2e\x15\xe4\xbb"
-  "\xeb\x11\x71\x5c\x58\xbc\x99\x4d\x6b\x4f\xdf\x35\x52\xdc\xc6\x4c"
-  "\x48\xdb\xc8\x8f\x21\x70\xb2\xe5\xca\xda\xd9\x5a\xba\x59\xda\x36"
-  "\xda\x8e\x5d\x38\xae\xb3\x1f\xfb\x44\x70\xff\x26\x8c\x7b\x20\xe6"
-  "\x83\xef\xef\x44\x96\x76\x61\xbe\x78\xdf\x85\xb5\xe2\xf8\xaa\x70"
-  "\x3f\x72\x25\xdf\xf7\xac\x81\x78\x47\x32\x26\x36\xfd\x77\x61\x6a"
-  "\x6d\xec\xc2\x25\x71\x0b\xee\x53\x2f\x5c\xb2\x30\x6e\xe1\xbc\x45"
-  "\x0b\x57\xcf\x8b\x5b\xb8\x74\xc9\xf8\xc5\xf3\x5e\x5d\xf8\x8a\x7a"
-  "\xd5\xbc\xe5\xea\xc0\xf8\x3b\xe2\x87\x12\x7b\xd6\x87\xd4\xf3\x96"
-  "\x2f\x5f\xb1\x38\x3a\x4a\xbd\x64\xe1\x2b\x13\x62\xa3\x97\x47\xc7"
-  "\xa9\xe7\xc5\x2e\x5d\xb1\x24\x4a\x7d\x47\xd4\x3d\x77\x04\x3e\x18"
-  "\x35\x54\x3c\x86\x76\x9b\x8a\xb4\xd9\xce\xb7\xb6\x6e\x3c\x4f\xbc"
-  "\xfc\x14\xda\x58\xbf\xf8\x85\x4b\xe8\xb8\xdd\xee\xb7\x27\xe6\x12"
-  "\x2d\xee\x13\x89\x7b\x8c\xb1\xe9\xbb\xf2\xe0\x53\x89\xf9\xa0\x9d"
-  "\x6a\xf8\x8e\x3a\x0e\x68\x4f\xdf\x1d\x62\x60\x3e\x08\xe4\xf6\x0f"
-  "\x83\x74\x68\x5b\x00\x7b\xbe\xa6\x15\x62\x36\x2d\x3e\x47\x5c\x7a"
-  "\x9e\x8c\xd4\xad\x24\x4a\x38\xbc\xe1\x50\xe1\x3e\x92\x70\x4d\x82"
-  "\x81\xd9\xc3\xaf\xcf\xbc\x27\xc0\x38\xa4\x2e\x97\x4d\xab\xcb\xa5"
-  "\x7a\xd9\x73\xb3\x30\x1e\x1c\xfa\x36\x09\x45\x7c\x36\x33\x7b\xb8"
-  "\xb5\x65\xde\x02\x2c\xe3\x58\xea\xd9\xff\x79\x22\x18\xe2\xc1\xa6"
-  "\xea\xd1\xdc\xb9\x9b\x4d\x0c\xf1\x86\x7a\x29\x0f\x26\x04\x92\x1c"
-  "\xb8\xd7\x72\x7f\x96\x85\x7b\x18\x84\xf1\x34\x68\x83\x0a\xda\xd2"
-  "\xc8\xb7\xe3\x20\xd7\x8e\xcd\xec\xb8\xdc\x11\x50\x3f\x3d\xd6\x67"
-  "\x8f\xb7\xd0\x06\xa8\x77\xa3\x81\xd9\xad\x85\x7a\xaa\xb0\x5e\xce"
-  "\xc6\xfa\x70\xbc\x0b\xea\xf9\xac\x6d\x25\xc8\x6d\x2c\xdd\x57\x62"
-  "\x63\x09\xb5\x3f\x68\x4f\x46\x29\x7c\xcf\x3a\x43\xbc\x33\x71\x8f"
-  "\xbf\xb5\xb7\xb0\x47\x4c\x16\x52\x1f\xd3\x48\xfc\xde\x60\x8d\xec"
-  "\x5f\x5a\x5b\xf9\x36\x25\x23\x37\xfc\xe9\xb5\x46\x25\xb6\x09\x7c"
-  "\x85\x77\xe9\x19\x97\x63\x8b\xca\x9c\x51\xac\x89\x2d\x14\xc7\x5c"
-  "\x7b\x7e\x44\x99\x60\xbc\x75\x76\x2d\xee\x23\xb7\xa7\x01\xee\xad"
-  "\xe1\x63\x63\x13\xdb\x19\x21\x8a\xa5\xf6\x20\xce\x4c\x2e\xca\xf6"
-  "\x12\xca\xc6\xfd\x04\xf1\x1a\xaa\xff\xf7\x9f\x85\x6b\x8c\xf6\xf2"
-  "\xdf\x0f\x74\x2c\x1f\xcb\x84\xef\x46\xe1\x3e\xb4\x1f\xfe\x3e\xc6"
-  "\x04\x46\xc0\xb2\xd1\xc5\xfd\xc6\xe9\x37\xb3\xc7\xea\x21\x7d\xe3"
-  "\x05\xa2\x84\xbc\xc7\x4a\x37\x73\xe5\x83\x4d\xed\xe2\xc6\xae\xdf"
-  "\x1a\x45\x48\x2a\xe4\x39\x9b\xbe\x47\x63\xe2\xf6\xf6\x7b\x1f\xec"
-  "\xbf\x50\xed\x38\x96\xcd\xe3\xf9\x21\x07\x3c\x07\xeb\x31\x26\xcc"
-  "\x85\xf2\x01\x43\x1b\xcf\x81\x1f\x86\xdf\xf7\xe4\x12\x0d\xde\x07"
-  "\xbe\x37\xe0\x78\x48\x7b\x7a\x25\x11\xee\xc7\x02\xfe\xb3\x6c\x74"
-  "\x0c\x86\xc7\xd6\x78\x1c\xbf\x4e\x8a\x67\xd9\x83\xc0\xef\x58\x47"
-  "\xc4\x18\x5c\x13\x24\x60\x0a\xb0\x7e\x8c\xc3\xd5\x48\xa2\x61\xd3"
-  "\xdf\xaf\x2a\x1d\x01\xf9\x00\x57\x25\x80\x27\xc4\x15\xe4\x8d\x14"
-  "\x30\x05\x58\x6b\xc0\x7c\x50\x87\xa1\x95\xab\x83\x95\xc8\x91\x2d"
-  "\x4c\xe5\x17\x88\x31\xf6\xbf\xff\xd0\xc8\xde\x34\xa7\x91\xea\xa9"
-  "\xf2\x8b\x7a\x33\xd5\x81\x5d\xee\x95\x15\x22\xb9\x37\x00\x8e\x87"
-  "\xa2\x9c\xe9\x58\x75\xe5\x17\x50\xb7\x06\x2e\x16\x7f\x13\x74\xc0"
-  "\xf9\xaa\xca\x5c\xbc\x9e\x97\x61\xad\x5d\x86\x95\x46\x67\x32\x74"
-  "\x90\x9d\x92\xee\x2d\x58\x69\x41\x5b\x69\x4f\xff\x60\x9c\xb0\x5f"
-  "\xa0\x33\x5d\xc2\x3d\x94\xca\x5c\xe2\x85\xf7\x38\x34\x92\xcb\x3f"
-  "\xdb\xd9\x3d\x1c\x71\x7c\xa8\x8c\x10\x1c\x0b\xc7\xeb\xc6\x8d\x44"
-  "\xb9\x7e\x90\xe1\x54\xbf\xaf\x48\xea\xc6\x1d\x6c\xfa\x07\x79\x39"
-  "\x23\x00\x37\xb4\x7e\x87\x7a\xaa\xdf\x38\x35\xf5\x8b\xd5\xb7\x21"
-  "\x9e\x3f\xb0\xd6\x43\x6f\x1b\xd3\xf8\xdf\x6d\x67\xc1\xd7\x38\x8e"
-  "\xe7\xbb\x9e\x5f\xd8\xfb\x88\x74\x7e\x61\xef\x78\x57\xf3\x0b\xd2"
-  "\xfb\xee\x7d\x03\xef\x6b\x2b\x9d\xad\xb0\xdf\x7b\x6f\x94\xcd\xc9"
-  "\xbd\x85\xeb\xef\x29\x13\xf7\x5f\xf6\x7e\x8a\x75\xa8\xc3\xfd\xd6"
-  "\x7f\x35\x5b\xc1\x42\x39\x87\x38\x9f\xbd\xb7\x86\xc6\x2b\x18\x07"
-  "\xed\xad\xc0\x3c\x8e\xed\xe8\xfa\xf3\x1a\x89\xb1\x23\xb9\xc0\xfd"
-  "\x18\xf8\x7b\xa2\xc2\xcf\xd1\x65\xc2\x69\x46\x92\x99\xb0\x4e\x7e"
-  "\x78\x13\xf2\x2b\x2e\x3f\x0b\x7f\x34\x89\xff\x6d\xe4\x7e\x28\xbb"
-  "\xf2\x77\x9d\xef\xc3\xdf\x10\x5a\x5f\xae\x3c\x33\x51\xf0\xf7\xab"
-  "\x16\xe5\x98\xda\xc3\xd5\x2c\x11\x2e\x71\xf6\x87\xb3\x09\xc9\xb3"
-  "\x07\x42\x79\x06\x2e\x33\xcb\x5a\xf8\xf2\x85\xdf\xac\xf8\x37\xa6"
-  "\x48\x7f\xc3\xdf\x80\x08\xd1\x0d\x6e\x19\x10\xc5\x3d\x9e\x34\xd6"
-  "\xd2\x95\xc4\x94\xa9\xa4\x37\x4d\x1e\xc8\x7d\xf8\xe1\x3f\xf1\x50"
-  "\x9e\x06\xce\x07\xd8\x4f\x0f\x30\xa5\x88\x32\x1f\xa6\xd5\x1f\x33"
-  "\xc9\x75\x23\x3c\xfe\x1b\x2b\xfa\x7e\x0b\xfd\x08\x30\x3b\xcd\x79"
-  "\x31\xfe\xd4\x0d\x43\x84\xaf\x76\x78\x8c\x49\x70\x96\xd5\x2e\xff"
-  "\x31\x4d\x42\x92\x58\x9f\xf6\xf3\xb7\x86\x4b\x7f\xdf\xae\x92\xfe"
-  "\xbe\x23\xa4\x3f\xaa\x5e\x8d\xff\x24\x19\x86\x03\x73\x8c\xec\x4a"
-  "\xf4\x73\x30\x19\x3f\x9d\x83\x09\xd9\xff\xf8\xda\x0c\x80\xfa\x14"
-  "\x89\x92\x95\xce\x73\x5f\x9c\xbf\xd1\x29\xbc\x00\x6f\x31\xaa\xba"
-  "\x9d\x74\x4c\xc3\xdf\x83\xd4\x7c\xda\xbd\x1f\x75\xcb\xcf\xa5\xa9"
-  "\x45\xbf\x15\xc1\xf0\x4f\x19\x5c\x98\xd6\x1f\x75\xbd\xfe\xf7\x7f"
-  "\xf0\x4f\x81\xf6\x71\xfd\xef\x22\xfd\xb1\xd4\x8b\x03\x13\x71\x1f"
-  "\xf8\x1f\xdb\x45\x94\x2c\x7f\x82\xe5\x13\x58\xfe\x4b\xbf\xf8\xf1"
-  "\xeb\x7f\xd7\xff\xae\xff\x5d\xff\xbb\xfe\x77\xfd\xef\xfa\xdf\x35"
-  "\xf0\xa7\x10\x77\xac\x71\x5f\xbd\xc1\xfc\xa7\xb8\xff\xa3\xe0\x0f"
-  "\x71\x1a\xd3\x97\xeb\x58\xfe\x8f\x24\x07\x57\xab\xcb\x22\x0d\x2a"
-  "\x5d\x58\x43\x60\xa5\xd6\xe8\x95\x16\x52\xa3\xa9\x88\x69\xf5\xcf"
-  "\x0b\x6f\x9c\x54\x15\x6f\x56\xa6\x4e\x3d\x34\xae\x3c\xaa\x65\x64"
-  "\xee\xec\x63\x41\xfb\xe2\x4c\xde\x19\xd3\x6a\xc7\xef\x5a\xd4\x16"
-  "\x50\x14\xd1\x34\x65\x7f\x82\x85\x59\xfb\xc4\x3f\x6e\xdb\x3a\xbf"
-  "\x79\x84\x7e\xd6\xe7\xf7\xed\x8d\x3d\x33\x34\xfd\x99\xcf\xee\xde"
-  "\xf1\xda\xc9\xd1\x05\x2f\x7e\xf5\xd0\x5f\x57\x77\x0c\x5a\xf7\xfb"
-  "\x4f\xee\x7c\x77\xc1\x89\x51\x9b\x9f\xfb\xd7\x83\x7f\x59\x79\xde"
-  "\x37\x6b\x46\xdd\x3d\x7b\x96\x9c\x1e\x5b\xf2\xd2\x7f\x1e\xfd\x9f"
-  "\x44\x9b\x22\xe5\xf1\x8f\x6e\xdd\x32\xef\xdb\xe1\xd9\x33\x8f\xde"
-  "\xfb\xc1\xb2\x5f\x86\xac\x7f\xfa\xd3\xbb\xb6\x2f\xfc\xf1\xe6\xfc"
-  "\x17\xbe\x9c\xfc\xe1\x1b\x17\x06\xbe\xfd\xe4\xc7\x77\x6c\x8b\xfe"
-  "\xfe\xc6\x4d\xcf\x7e\xf1\xc0\x9f\x57\x9c\xf3\xc9\x9c\x7e\x64\xc2"
-  "\xee\xc5\xa7\xc6\x14\xcf\x3d\xfe\xc8\x81\x37\xad\x03\xde\xfa\xdd"
-  "\xc1\xdb\xdf\x79\xe5\xbb\x1b\x72\xfe\xf8\xbf\xf7\xff\x69\xf9\xd9"
-  "\x61\x1b\xfe\x70\xf8\x37\x3b\x5f\xff\xe9\x57\x85\x73\xbe\x7e\xf8"
-  "\x6f\x6b\x3a\x07\xff\xd7\x53\xff\xfc\xf5\x7b\xaf\xfe\x70\xd3\x7f"
-  "\x3f\xff\xef\xdf\xfe\xbf\x55\xed\x7e\x1b\x43\xeb\x27\xbe\xbf\xf4"
-  "\xe7\x5b\x4a\x5f\xfe\xe6\xb1\xbf\x27\xb1\x7d\x91\x1f\x61\x8e\xfe"
-  "\xe9\x52\xeb\x8d\x7e\xa4\x24\xcb\xb9\x9e\xe5\xb5\x4e\x7f\x26\x3f"
-  "\x40\x14\x5e\x64\x90\x52\x56\x3f\x41\x6e\x7b\x5d\xfc\xa9\xc5\xd7"
-  "\xf7\xf6\x87\xef\x84\xe1\x33\x15\xf7\xc3\xf1\x2b\x2e\xc5\xde\xf3"
-  "\x1f\xeb\xf4\x8a\x4b\xf1\xa7\x80\x76\x0e\x80\x9a\x0c\x24\x83\x40"
-  "\x32\x5e\x64\x08\x19\x4a\x86\x11\x6f\xe2\x43\x7c\x89\x1f\x51\x91"
-  "\xe1\x64\x04\xb9\x81\x8c\x24\x37\x92\x51\xe4\x26\xe2\x4f\x6e\x26"
-  "\xa3\xa1\xf6\x01\x64\x8c\xf3\x3a\x27\x93\x60\x7f\xf8\x07\xfe\x0f"
-  "\x23\xc1\xdc\xef\xc8\xeb\xe9\x97\x34\xbd\x9a\x4f\x6f\xe0\xd3\x0d"
-  "\xd7\xd3\x2f\x69\xba\xfa\x32\x7f\xde\x7a\x59\x3f\x15\x10\x16\xd0"
-  "\xc8\x40\x12\x1f\x74\xfd\x39\xa6\x2a\xf8\xbf\xae\xdf\xa4\x97\xeb"
-  "\xbb\x95\x27\xbd\xde\xf1\x2f\x18\x8e\x20\xfa\x35\x89\x10\x3a\x97"
-  "\xc0\x8a\xff\x2c\xae\xae\x14\xfe\xf2\xe2\xe1\x48\x85\x43\x07\x47"
-  "\x0e\x1c\xa5\x70\x6c\x17\xca\x21\xc4\x68\x26\xe4\x0c\x70\xfb\x2f"
-  "\xb9\xf0\x59\x4b\xc8\xd9\x48\x42\xce\x19\x08\x31\x95\x11\xd2\xae"
-  "\x16\x55\xdc\xdb\x5e\x23\x2b\x7f\x57\x38\xad\x60\x72\x45\x37\xf3"
-  "\xd4\x3f\x55\x3d\x39\x3b\x44\x7d\xef\x3d\x41\xf7\x04\xdd\xaf\x9e"
-  "\x30\x41\x7d\x5f\x60\xe0\xe4\x89\x81\x0f\x4c\xbc\xef\x41\xf5\x7d"
-  "\xf7\x3f\xf4\xc0\x83\x0f\xdd\x37\x49\xbd\xf8\x8d\xd8\x85\xf7\x06"
-  "\xbe\x1a\xad\x5e\xb0\x30\x76\xf1\xaa\x79\xb1\xd1\xbd\x35\x58\xde"
-  "\x1f\x34\x85\x8c\xb1\xd2\x6a\x8a\xb5\xa1\xc0\x11\xf2\xbf\xf9\x13"
-  "\xa6\x2e\x8f\xd8\xcf\x68\xf8\x43\xfa\xa7\x88\xd7\x11\xc5\x8a\x5c"
-  "\xa2\x58\x06\xdf\x5f\xf7\x26\x8a\x57\xaa\x88\x62\x33\xa4\xe5\x24"
-  "\x10\x45\x56\x03\x51\xa4\x1d\x22\x8a\x94\xf0\xee\x69\xa5\x8b\x68"
-  "\xda\x5f\xdb\x88\xe2\x2f\x6a\xa2\x78\xdf\x4c\x14\x15\x61\x34\xed"
-  "\x63\xc8\x53\x6d\xbc\x38\x8d\x96\xfd\xe7\xa9\x9e\x15\xff\x1f\x7a"
-  "\x77\xed\x26"
+static unsigned int eth_z8e_uncompressed_length = 366788 ;
+static unsigned int eth_z8e_length = 115959 ;
+static unsigned char eth_z8e[115959 + 1] = 
+  "\x78\x9c\xec\xbd\x7f\x7c\x54\xd5\xb5\x37\xbc\x32\x19\x60\x12\x23"
+  "\x13\x31\xd2\x29\xa5\x3a\x5a\xb4\xd1\x0b\x12\x15\x5b\xb4\xa0\x51"
+  "\xc0\x82\x0d\x10\x15\x6d\x54\x34\xa0\x81\x06\x8d\x18\x21\xc0\x00"
+  "\x21\x33\x0c\x70\x9d\x44\x7e\x44\x8d\x18\x21\x90\x44\x62\x9b\xdb"
+  "\x52\x4d\x2c\x2a\xd8\x50\x63\x49\xef\x43\xef\x85\x0c\xb7\x2f\xbe"
+  "\x6f\x6e\x5f\xbc\x1d\xd2\x88\x29\x4f\x80\x91\x0c\x64\x48\x66\xce"
+  "\x7e\xbf\x6b\xef\x73\x92\x99\x61\x82\x72\x7b\x3f\xcf\xfb\x4f\xf9"
+  "\x7c\xc2\x9c\xb3\x7f\xac\xbd\xf6\xda\x6b\xad\xbd\xf6\xde\x6b\xaf"
+  "\x43\xf4\x77\xfc\x33\x7d\xe4\xf8\x7b\xaa\xff\xe3\xdf\x3f\xfe\xfd"
+  "\xe3\xdf\x3f\xfe\xfd\xe3\xdf\x3f\xfe\xfd\xe3\xdf\xff\x3f\xff\xce"
+  "\x9a\xcc\xf4\xfb\x72\xa2\x1e\xb7\xc5\xe6\xa3\x0b\xf6\x37\x5f\x17"
+  "\x21\x24\x27\xf8\xc8\x62\xe3\x5f\xfd\x8f\x5e\x43\xba\xa9\x9c\x2c"
+  "\x37\xa4\x52\xca\x94\x1d\x44\x15\x23\x45\xd7\xeb\x5b\x85\x7f\xdd"
+  "\x56\xd1\x35\xf5\x1d\xa2\x96\x31\x44\xaf\x8f\x14\x01\xc0\x99\xeb"
+  "\xa3\xa7\x2b\x18\xce\x3a\xbc\x73\xfe\xfa\x91\xc2\x8f\xf4\x22\x1f"
+  "\xe5\xa6\x70\xfa\xda\x91\x80\x95\x46\xe4\xde\x2a\x82\x11\x70\x2d"
+  "\x5c\x9f\x61\x4e\xbd\x5e\xe2\x53\x17\x03\x87\x61\xec\x05\x8c\xf5"
+  "\x97\x80\x91\x62\xe0\x15\x30\x51\x02\xc3\xeb\x76\x93\x2d\xe0\x6e"
+  "\xbe\x06\x75\x03\xe8\x53\x3a\xd7\xdd\x82\x32\xc2\x4d\x89\x2d\x8e"
+  "\x10\xd9\x6f\xa0\x84\x13\x94\x5c\x8b\x5f\x13\x7e\xdf\xe0\xfe\xae"
+  "\x53\xf5\xc6\x30\x0c\xd4\x4d\xe8\x71\x27\x65\xf4\xd7\x05\x6c\x7b"
+  "\x09\x99\x51\x76\x51\xc0\xd4\x6c\x52\x65\x53\x93\xf4\xb2\x26\x94"
+  "\x9d\x6b\x94\x55\x79\xa6\x19\x7a\xde\x15\xc8\x73\x44\xe7\x99\x5f"
+  "\xd3\xf3\x52\x90\x57\x11\x83\x9f\xd9\xdb\x1b\xa2\x13\x94\xb4\x1b"
+  "\xb8\xd8\x0f\x60\x54\xb8\x8e\x5e\xfe\x2a\x94\x6f\x89\x86\x45\xa4"
+  "\xe7\x8d\x40\x9e\x2f\x3a\xef\x77\x19\x7a\xde\xb7\x90\x17\x8a\xce"
+  "\x4b\x30\xea\xd9\x7a\xdc\xc9\xb6\x38\xfd\xe4\xf6\x13\x54\xdb\xdc"
+  "\x87\xe4\x49\x28\xe3\xe2\x32\x73\xec\x2e\xe2\xb1\xe2\xbc\x03\x35"
+  "\xfd\xed\x73\x99\x79\x06\x1c\x1f\xea\x47\xd0\x14\xb4\x4c\x2e\x36"
+  "\xea\x4f\xb5\x33\x0c\x92\x34\x64\x38\x3e\x4a\x9a\xce\x70\xf8\x1d"
+  "\xcf\xa3\xb9\xdf\xfa\xb3\x9d\xfb\x17\x39\xe6\x44\x66\x80\x1d\x62"
+  "\x21\x1a\x8a\xbf\x61\x16\x83\x07\x96\xda\x84\xe6\xfc\x36\x99\x45"
+  "\x59\x4d\xa6\xe6\x16\xe4\x75\x04\xc9\x3e\x8a\x9c\xed\x74\x85\x0d"
+  "\xf8\xd1\xe6\x55\x64\x71\x16\x8a\xa0\xd7\xd1\x45\xad\xfe\x2e\x72"
+  "\xfa\x45\xa7\x37\x74\x8e\x4a\xce\x91\xc5\x1b\x3a\x45\x25\x2f\x91"
+  "\xad\xa5\xf8\x0b\x8a\xc7\x5f\x9a\x49\x90\x73\x34\xd7\xed\xa0\xd6"
+  "\xaa\x0e\x72\x56\x45\xd7\x75\x7e\x97\x6c\x87\xf1\x8e\xb1\xb3\x32"
+  "\x1e\x2d\xf6\x10\x85\x92\x6b\x32\x8b\xdf\x22\xb3\xf3\x7a\x32\x1d"
+  "\xce\x6b\x36\x70\xf1\x31\x2e\xeb\x4f\x92\x65\xd7\x42\xf0\xd0\x49"
+  "\xc6\xb7\x3e\xf3\xbd\x55\x41\xd3\x01\x5b\x16\x1d\xb0\x1d\xa3\x16"
+  "\xdb\x64\x6a\x71\x4c\xa5\xcd\x27\x29\xe5\x40\x70\x12\xb5\x98\x1f"
+  "\x80\x8c\x4d\x25\x6f\x17\x9e\xed\x61\x94\x09\x90\x7d\x39\x81\x3f"
+  "\xae\x38\x52\xf1\x1c\x59\x7c\x0a\x26\xe8\x7b\xc5\xb1\x4f\x8b\x88"
+  "\x98\xbe\xfc\x1e\xaf\x1f\x4b\xbf\x4d\x36\xe0\xd7\x09\x5c\xee\x6a"
+  "\xa7\x94\x6b\xc6\xd8\x28\x03\x38\x0f\xf3\x56\x86\xc8\x5c\x4c\x49"
+  "\x83\xc8\x56\x9a\xe6\x96\x32\xde\xb5\x73\xab\xe8\x64\x1e\xed\x5e"
+  "\x9d\x03\x39\x4d\xc9\x42\xdb\x5d\xdc\xde\x66\xc8\xba\xb3\x96\xcc"
+  "\xdd\x2b\x72\x12\xaa\xb7\x8a\x0e\xe4\xe5\x1b\x79\xe0\xa7\x0e\xe4"
+  "\x77\x8e\x4f\xa3\x54\x6f\x28\x93\x3e\xe9\xed\x34\x33\x8c\xe1\x01"
+  "\x4a\x60\x78\x56\x07\x25\xa2\x3f\x43\x80\xcf\x5d\xd5\x48\xff\x1e"
+  "\xca\xa1\x7e\xbd\x8f\x5e\x9d\xc7\xf5\xc5\xb7\x9e\x0c\x68\xdf\x7a"
+  "\xf2\x9c\xf6\xe6\x93\xdd\xe2\xcd\x27\xcf\x86\xdf\x7c\xf2\x2b\xe7"
+  "\x4a\xb2\x84\xbf\xf5\xa4\xbf\xb5\x50\x8e\x41\x6a\x6b\x21\xc6\x20"
+  "\x4c\x96\x35\xa7\x28\xf5\xe9\x97\x30\xf6\xa1\xcf\x69\xcd\x22\xb2"
+  "\x69\x49\x3f\x0f\x7a\x43\x9f\xd1\xd3\xc5\x24\xb4\xa4\x5f\x58\xe2"
+  "\xf5\xaf\x3b\xb9\xde\xa5\x64\xc8\x82\x3e\x5d\x69\xf7\x99\xaa\x27"
+  "\x72\xbb\xfe\xa4\x06\x17\xfe\xd6\xe3\xcf\x83\xbf\x8d\x22\xb9\x7e"
+  "\x23\x68\xe5\x1c\xbe\x36\x81\x76\xf6\x12\x8d\xd7\x28\xe1\x24\x5d"
+  "\x39\x09\xf8\xa7\x0e\x42\xb7\xd1\x5a\xd9\x6f\xe7\x7d\xdf\x45\x25"
+  "\x3d\x3d\xf9\xc4\xba\x89\xf5\x12\xeb\x29\xb4\xe3\x41\x3b\x0e\x29"
+  "\x8b\x5b\x45\x40\x24\xff\x76\x1e\xd2\x3b\x03\xab\xf3\x13\xfc\xab"
+  "\xf3\x4d\xdd\xc9\xbf\x7d\x16\x65\x76\xa3\x4c\x83\x4e\xc3\x4e\x86"
+  "\x05\x99\xf0\x5f\x19\xa2\x44\xc0\x2c\xfc\xe8\x7c\x9b\x79\xc7\x56"
+  "\x71\x0c\xe5\x8e\xf6\xc3\x02\x6c\xc0\x01\xfd\xaf\xec\x34\xd2\x40"
+  "\xeb\x8e\x4d\x28\xc7\xf5\xbd\xc1\x4c\xd6\xdf\x3e\x6f\x41\x27\x59"
+  "\x43\x94\x2c\xfa\x54\x7b\x28\xd3\xc9\x7a\xf6\xca\x20\x0d\xed\x71"
+  "\x53\x36\xc3\xe6\x7a\xde\xae\x4e\x42\xbd\x67\x85\x33\x1f\xfa\x8d"
+  "\x66\xf5\x88\xfc\x04\xe8\xf4\x8e\x03\xa8\xaf\xda\x1e\x9e\x6d\xe0"
+  "\xc8\x6d\xf0\x58\x4b\x3c\xc1\x0f\x07\x0a\x82\x74\x65\x25\x25\xa2"
+  "\xde\x23\x0c\x8f\x61\x81\x0f\x7c\xe8\xeb\xb3\x07\x0a\xfc\xa4\x89"
+  "\x28\x98\x3e\x1d\x5e\x4d\x14\x3c\xa4\x0b\xc0\x63\xfe\x6b\x41\x9d"
+  "\x2b\x6b\x24\xbc\x87\x3f\xd2\x18\x5e\x90\xcc\x76\x89\xef\x63\x0c"
+  "\xa3\x87\x75\x0c\x60\x36\x2f\xbf\x9f\xba\xc8\x6a\xf1\x3b\xf3\x13"
+  "\x5b\x8b\x89\xb8\xfe\x7b\x25\x9d\x43\x44\x77\x4e\x22\xf3\x1c\xe7"
+  "\x7b\x43\x67\x51\x66\xf8\xdf\x44\x77\x7e\xe2\x95\x5d\x64\x66\x9c"
+  "\x51\xdf\xc1\x78\x46\x8e\xe5\xc3\xd3\x1e\x9b\x4c\x8f\x4d\x9d\x31"
+  "\x75\x32\xcd\xbc\x6f\xca\x64\xca\xb8\x6b\x5c\xc6\x1d\x3f\x9c\x78"
+  "\x07\x65\xff\xf4\xe1\xc9\x94\x3d\x6b\x32\x3d\x82\xbf\xec\x47\xa6"
+  "\x3d\x3c\x75\xda\x23\x93\x29\xe7\x81\x19\x78\x9b\x32\xf9\xb6\x8c"
+  "\x1f\x8f\xcb\x9e\x32\x63\x1a\x3d\x34\xe7\xf6\x8c\xdb\x6f\xa7\xfb"
+  "\xa6\x65\xdd\x96\x91\xa1\xff\xde\x96\xc1\x45\x9e\x98\x38\xed\x91"
+  "\x71\xd9\x4b\x5e\x2c\x7a\x71\xdc\xac\x19\x53\x62\xe6\xd9\xf4\xf0"
+  "\x79\x8d\xe9\x1b\x10\x67\xa6\x93\x06\x7d\xb1\x13\xe3\x8e\xbf\xae"
+  "\xe6\x92\x76\xc8\x7d\xea\x7f\xec\xe4\xf1\x92\x7a\xd5\xca\x73\x95"
+  "\xb9\xc7\x6d\x6d\x03\xdd\xfc\x4c\x37\xcc\x67\x28\x73\xcd\x39\xe4"
+  "\xdd\xac\xcf\x1b\x43\x90\x1f\x8c\xce\xbf\xea\x10\xf2\xc7\xb7\xda"
+  "\x89\xbc\xf8\x03\xad\x03\xd0\x7f\xa0\xa9\x9f\xba\x9d\x39\x43\xc0"
+  "\xd3\x09\x68\xa3\x03\xf2\x78\xa4\xc7\x9d\x3a\x21\x42\xce\x3b\x30"
+  "\x26\x47\xec\xab\x28\xf1\x34\xa5\x5e\xd9\x5a\x94\x49\x3c\x36\xde"
+  "\x22\x1d\xc6\xb9\x7e\x18\xc9\x12\x06\xc6\x1b\x70\x8e\xea\x70\x8a"
+  "\x23\x74\x82\x8f\xe1\x6c\x46\x9e\x0e\xeb\xa1\x56\xe8\x06\xe8\xee"
+  "\x07\x35\x67\x3a\x89\xe4\x9a\xe9\x5a\x5f\xba\x9c\x0f\x50\x6f\x8f"
+  "\xc1\xcb\x28\x1f\x68\x29\x44\xb9\x5d\xd3\x13\x30\xf6\x09\x98\xa7"
+  "\xd0\x17\x6b\x33\x78\x3a\xa0\x95\x35\x94\x8b\x9e\x1c\x52\x69\x57"
+  "\x01\x06\xde\xcb\x1a\x5e\x15\x4e\xa4\xad\x92\x69\x09\x9c\x86\x71"
+  "\x4e\x64\x79\x14\xab\x65\x7a\x22\xd2\x97\x01\xbf\xb6\x30\xd7\x3f"
+  "\x23\xeb\x0f\x43\xda\xa3\x28\xfb\xaa\x96\xdc\xf0\x1a\xf8\x86\xd3"
+  "\x60\x23\x8c\x4c\x03\xbc\xd7\x35\x91\x43\xc2\x12\xca\xc1\x73\x45"
+  "\xf3\xaa\x2e\x3a\x51\x48\x26\x1f\xf2\x34\x27\x60\xf6\xf5\xb7\x3f"
+  "\x86\xeb\xa2\x2d\x73\x4f\x5f\x3e\xe6\xb7\xab\xd2\x79\x2e\x0c\x33"
+  "\x3e\x67\xfa\xcb\xa4\x71\x9b\x2c\xd3\x18\x8b\x09\x18\xa7\xa4\x1e"
+  "\xf7\x55\x35\x31\xe3\xb4\x17\x70\x5e\x05\xdd\xdb\x00\x23\x55\xeb"
+  "\xce\xe7\x7e\xbd\x0a\xb8\x26\x1d\xae\x01\x23\xa0\xf8\xe0\x2a\x5f"
+  "\x0c\x1f\xfc\x27\x60\x4f\x1e\xc8\x1f\x41\x31\xf9\xfb\x91\x7f\xbf"
+  "\x9e\x0f\xd9\x1a\x61\x8f\xce\x1f\x31\x09\xf9\x0f\xa0\xfd\x00\x64"
+  "\x27\xd1\x47\xa9\x75\x3b\xd9\xf6\x1b\x28\x9f\x1d\x53\xbe\x00\xe5"
+  "\x1f\xc4\xd8\x06\x58\xaf\x73\xf9\x6a\x9d\x57\x51\xde\x82\xf2\xae"
+  "\x98\xf6\x77\xa0\xfc\x23\x11\xf8\xc5\xf4\xff\xea\x7c\xe4\xe7\x30"
+  "\x6f\xe1\x37\x0f\x65\x86\xb1\xbc\xb2\xae\x38\x50\xc0\xb6\xe2\x88"
+  "\x23\x31\xed\x33\x2d\x9f\xd7\x0c\x1a\x75\x33\x8d\x52\xeb\x74\x3b"
+  "\xe4\x98\xc2\xe1\x6a\x73\x4c\x1b\x63\x50\x67\x29\xf8\xe7\x55\x83"
+  "\x37\xe2\xd4\x99\x18\x53\x27\x47\xf2\x96\x6a\x47\x1f\x63\x55\x47"
+  "\xd7\x43\x91\x30\xb8\x6f\xb0\x8d\xae\x2e\x8e\xe9\x7b\x0e\xda\x5d"
+  "\xbd\x49\xc9\xf9\x15\xe0\x89\xdb\x91\x36\x03\x30\xdf\x60\x3e\x62"
+  "\x5e\xf7\xfa\x83\xd0\x93\xd3\x53\xd4\x7c\x7f\xf5\xe7\xd6\x62\xe2"
+  "\xe7\x71\xfc\xcc\xb0\x45\x5f\x96\x2e\x03\x57\x7f\x8e\x5f\x4e\x6f"
+  "\xe1\x74\x96\x3d\xd1\xf7\x13\x4d\xc1\x4c\x4b\x80\x8c\x9a\xf0\x1e"
+  "\xd6\xdb\xb8\x0f\xef\x09\xc0\xff\x35\xe8\x60\xf0\xec\x74\xe6\xc7"
+  "\x09\x48\xbf\x4b\xcf\xbf\x8d\xcb\xe3\xf9\x36\xfd\x99\xf9\xf6\x35"
+  "\x9d\x6f\x21\x07\xd7\xdc\x2c\xdb\x96\xb2\xa0\xea\x6b\x8a\xef\xa7"
+  "\x20\xef\x1a\xfc\xce\xc0\x2f\xe3\xf5\x10\xda\xfe\xdc\x79\x8e\x6c"
+  "\xce\x30\x6c\x0e\xf5\xfe\x47\xfc\x3e\x8c\xdf\x0f\xf0\xfb\x08\x7e"
+  "\x6b\x59\x6e\xfd\x2b\xf2\x29\x86\x67\xba\x34\x25\xab\xc3\xd4\x18"
+  "\xa6\x95\xeb\xf2\xa3\xe4\xf7\xcc\x40\x9a\x50\x69\x26\x45\x73\x3d"
+  "\xad\x6f\x3a\xb7\x9f\x0d\xf8\x05\xdc\xbe\x2e\xf7\x43\xd4\x38\xa9"
+  "\x32\x9a\xaa\x67\x56\xe3\xad\xa7\xa9\x72\x09\x91\x6d\xe2\x37\xb3"
+  "\x24\x20\x04\x7e\xc7\x32\x5d\x7d\x74\x4d\x06\x68\x62\xc6\x3b\xeb"
+  "\x3e\x93\x2c\x2f\xe1\x5e\x5d\x15\x31\xde\xb0\xc5\xaf\x29\x88\x1e"
+  "\xef\xd4\x3a\xa6\x19\x8f\xb7\x81\x2f\xe3\x0e\x7e\xe6\x39\x6d\xa8"
+  "\xc1\x33\xe0\xed\x2e\xe8\xc7\x40\x62\x31\xf3\xdd\x35\x0d\x3e\xfa"
+  "\x65\xb9\xb4\x83\xca\x1a\xb6\x72\x7e\x00\x7a\x86\x79\x23\xb1\x90"
+  "\xe5\xe5\x9a\x23\x46\xbe\xcc\x4b\xfa\xad\x8f\xe1\x27\x16\xc8\xbc"
+  "\x2e\x1f\xd8\xc5\xc8\x63\xdc\x58\x8e\x13\x8b\x38\x6f\xa4\x65\x00"
+  "\x6e\x4d\xbe\x0e\x37\x91\xed\x07\xb6\x03\x30\x1f\x77\xa2\xcc\x58"
+  "\x1f\x5d\x99\x33\xd8\x9a\x4b\x78\x6a\x72\xc6\x11\x99\x6e\x71\xd1"
+  "\x10\x6f\xe8\x28\xcd\x0e\x89\xf0\x38\x17\x25\x79\x43\xbb\x09\x0c"
+  "\x72\x95\x37\x74\x8c\x6e\x21\xba\xde\x1b\xaa\xc0\x7c\x5b\xc7\xf9"
+  "\x9f\xa4\x53\x42\x02\x7e\x9d\x37\xb9\x4c\x09\xde\xd0\x7a\x1a\xe3"
+  "\x32\xe3\xb7\x80\x1e\x18\x22\x7a\xbc\xa1\x2c\x94\xcb\xa3\xd9\x61"
+  "\x71\x66\xea\x10\xf1\x97\xdc\x30\xa5\x66\x6d\x10\x4e\x6f\x08\xb6"
+  "\x6f\xe8\x10\xd2\x35\x31\x3b\x7c\x01\x7f\x3d\x42\xf3\xd4\xe4\xcf"
+  "\x0e\x9f\x11\x53\x36\x7c\x82\xf7\xbf\x08\x61\x22\xe1\x0d\x4d\xa2"
+  "\xd6\x40\x00\xe5\x9c\x42\x94\xd6\xe4\x3c\x7d\xce\x44\x7d\x98\x3b"
+  "\xb5\xd2\x9a\x7c\xf4\xd1\xd1\x87\xfe\x61\x5e\x59\xd1\xb7\x1a\xbf"
+  "\x65\x35\xcb\xe5\xbb\xa7\xc6\x23\x2c\x35\x8e\x5b\xb1\x90\xe0\x3e"
+  "\x78\x43\x1d\x94\x0b\x53\x78\xf6\x4a\xbf\x60\xfc\x87\xaf\xe5\x75"
+  "\xc4\x24\x82\xee\xb3\xce\x5e\xe9\x14\xc8\xb3\x88\xa4\x1a\x87\x37"
+  "\xd4\x45\x68\xc3\x03\x78\x1b\x24\x3c\x4f\x4d\x3d\xca\xfa\xb9\x5c"
+  "\x24\x1c\x86\xc1\x65\x67\x87\xc9\x8a\xf2\xf5\x7d\x49\x35\x95\xf8"
+  "\xdb\x8b\xbf\x4e\xd4\xed\x15\xee\xb4\x4f\x05\xe6\x39\xe1\xa9\xb5"
+  "\x88\xe4\x5a\x5b\x0f\xec\x76\x49\xcb\x30\x0d\x13\xa5\xb5\x18\x7f"
+  "\x9a\x0a\xde\x02\xbe\xb5\x13\x25\xbe\x65\xb5\x3f\xec\x91\xfd\xa8"
+  "\xfd\x81\xea\x47\xed\x9d\x9c\xde\x8d\x39\x1e\xcf\x39\xdd\x2a\xef"
+  "\xa7\xa8\x37\x47\xd6\xf3\xd4\xe6\x08\x4b\x6d\x7e\x10\x32\x03\xba"
+  "\xba\x98\x8e\xa0\xab\x8b\x69\x09\xf8\x39\x5e\xc7\x46\x12\x49\xb5"
+  "\xf9\x7d\x49\xb5\x0e\xd4\x2f\xeb\x93\x73\x6f\x6d\x65\x8f\x82\xfd"
+  "\x26\xe0\xcc\x05\x5f\x26\x02\x46\x25\x60\xd5\xf7\xb9\xed\x34\x7b"
+  "\xa5\x08\xce\x0e\xad\x0d\xe5\xae\xa4\xc4\xb1\xe4\x02\xbe\xfb\x41"
+  "\xa3\x3c\xf4\xb3\x05\xbf\x53\x91\x4f\x57\xa3\xad\x4f\x00\xb7\x92"
+  "\xdb\x43\x3b\xf5\x80\xf9\x0e\x60\xe5\x31\x4e\x17\xdc\x94\x8a\xf7"
+  "\xbd\x17\x14\x7e\x6d\x9a\xa7\x36\xa8\x59\x6a\x3b\x0d\x1e\x62\xfe"
+  "\x51\x74\xab\xa0\x59\x01\x11\xf2\x86\x76\x10\x78\x2c\xb5\x35\x70"
+  "\x8c\xf3\x61\xeb\xef\xc6\x38\x33\x4f\xad\xc7\x6f\x1d\x31\xff\xb4"
+  "\x16\x2e\xe3\xb2\x9f\x30\x0f\xcd\x2a\x0c\xac\x1d\x47\x85\x09\x78"
+  "\x77\xe6\x86\x2c\xf4\x74\xa1\xd9\x15\xf6\xd4\x1e\x6c\x2d\xe4\x71"
+  "\x39\x8a\x3a\x5c\xaf\x80\xac\x09\xb0\x77\x13\x44\xc8\xea\xf0\x9b"
+  "\xaf\xcc\x77\x8a\xd6\x40\x16\xca\x16\x12\xf7\x87\xf9\x88\xcb\xcf"
+  "\xec\x12\xbe\xb0\xe5\x6d\x07\xf7\x4d\x0c\x77\xd1\xe1\xae\x3b\x89"
+  "\xd7\x1c\x87\xbb\xea\x98\x4f\x35\x61\x79\x7b\x3a\x78\xb4\x6f\x66"
+  "\x97\x6b\xc8\xd3\xe7\x28\x01\x69\xe1\xc3\xf9\xbb\x91\xdf\x82\x72"
+  "\x87\x24\xdf\xce\x3a\x17\xb2\x86\x2c\xb5\x7b\x43\x9e\xb7\x73\x66"
+  "\x9d\xeb\x13\x87\xf3\x2b\xe8\xa9\x2e\x17\x68\xb5\x9b\x66\x9e\x0a"
+  "\x25\xb6\x16\xe6\xa1\x4c\x0f\xd2\xeb\x24\xff\xcf\x3c\xd5\x2d\x66"
+  "\xbd\x24\xce\xcc\x3a\xf7\x17\x31\x33\x5f\x7c\x92\xeb\xa0\xe1\x57"
+  "\xac\x15\x1a\xcb\xc5\xa1\x8e\xdd\x74\xc5\x31\x1f\xb1\x4c\x64\xcd"
+  "\xd7\xc4\xcc\x53\x67\xc4\xd3\x2f\x31\x6d\x26\xd1\xe1\x7c\xc8\x8f"
+  "\xa3\x82\xe9\xdd\x76\x38\xbf\x09\xed\x4f\x05\x5c\xa7\xf0\x3a\x76"
+  "\xa0\x6c\xb3\xf5\xa9\x53\xa9\x74\xa8\xa3\x82\x42\x49\xb5\x7b\xc3"
+  "\xa5\xb5\x07\xb5\xa4\xda\x4e\xad\xb4\x36\x28\x92\xde\x9e\x1e\x2a"
+  "\x7d\x3b\x27\x9c\xf4\x36\x78\xe0\xed\x83\x18\xa7\x24\x1e\xf3\x5e"
+  "\xac\xc1\xf1\xfe\xaf\xbd\x3c\xfe\x9e\xb7\xdb\xd0\xd7\x20\xf4\x9d"
+  "\x50\xbc\xff\x76\x1b\xaf\xa3\x51\x37\xd8\x97\xf4\x76\x27\xca\x05"
+  "\x95\x7c\xed\xb2\x30\x5f\xca\xf9\xa6\x6c\xd7\x30\xcc\x0f\x89\x7d"
+  "\x49\xbb\x6c\xf8\x4b\xc7\xdf\x44\xa4\x79\x00\xff\x2a\xc9\x53\x9e"
+  "\x5d\x1e\x71\x4f\x39\x6c\xc7\x73\xcc\x93\x4e\x91\xb4\xab\x7e\x76"
+  "\x78\xa2\x13\x74\x84\xac\xec\xf2\x68\xa5\xbb\x2a\x01\xef\x60\x50"
+  "\xf2\xff\xae\xff\xc5\xf0\xfb\x56\xa7\xf3\x1a\xdb\x8c\xfc\x36\x51"
+  "\x56\xf7\x60\x0f\xf3\xab\xa5\x6e\xba\x66\xa9\xab\x17\x9e\xba\x9c"
+  "\x9f\x6c\x10\xfe\xb0\xa7\xce\xa1\x79\xea\xf2\x43\x43\x61\x97\x3a"
+  "\x9a\x88\x75\x54\xe8\x77\x02\x74\xf8\x03\x68\x52\x27\x79\xc0\xeb"
+  "\x80\x1c\xac\x1c\xe5\x3a\xdc\x05\x7e\x28\xfc\xb5\xd4\x4f\xad\x81"
+  "\xa3\x92\xae\x22\xa9\x6e\x3a\xf3\x15\x8f\xf1\xd3\x85\xe4\x12\xa5"
+  "\x75\x39\x5a\x69\x5d\x7e\xb8\x14\x70\x93\xd0\x4e\xf2\xcf\x4f\x06"
+  "\xa5\xcc\xfe\x1c\x3c\xdb\x84\x3a\x7f\x20\xc5\xe7\x3f\xef\x1c\x4c"
+  "\x4f\xb2\xbe\x62\x1d\x35\x3b\x14\x64\xbe\xf9\x92\x75\x9b\xd2\x55"
+  "\x94\x6b\xe8\x2a\xd6\x53\x6c\xeb\xb3\xae\xd2\x74\x5d\xa5\xe9\xba"
+  "\x4a\xbe\x5b\xa0\x6f\x3c\x35\x0e\xd6\x49\xb3\x1d\x4a\xd7\xcc\x0e"
+  "\x67\x08\xf0\x47\x0a\x60\x38\xd4\x78\xa0\x4c\x59\xcd\x06\x59\x5e"
+  "\xd2\xa9\xa6\x5e\x83\xce\xc1\xdf\x5e\x4d\xe9\x9c\xa0\xae\x73\x4c"
+  "\x86\xce\x09\x63\xfe\x82\x5c\x69\xf1\x74\x8e\xa6\xeb\x9c\xb0\x50"
+  "\x3a\x47\xd3\x75\x0e\xa7\x87\x75\x9d\x13\x8e\xa3\x73\x20\xd3\xdc"
+  "\xdf\x44\x5d\xd7\xb8\x58\xd7\x70\x7f\xc1\x6f\xf9\x9a\xd2\x35\x1e"
+  "\xd8\xf9\x26\xd6\x35\x61\xd4\xd1\x0c\x5d\xd3\x23\xeb\xd7\xb3\xbe"
+  "\xe9\xfb\x67\x82\x0e\xb5\x13\xeb\x19\xa9\x53\x42\xd7\x87\x58\xa7"
+  "\x80\x7e\xf7\xc6\xea\x14\xc0\xdb\x8b\xe7\x54\x5d\x57\x75\x5a\xd7"
+  "\x8a\x10\x74\xca\xc1\xd9\x8e\x00\xc6\xfa\x73\xac\x75\xa1\xbb\x1d"
+  "\x45\x2e\xaf\x23\x44\xd0\x05\x41\xd1\xea\x22\xe0\x08\x1e\x0e\x43"
+  "\x5f\x10\x41\x36\xa7\x87\x20\xe7\xe0\xf3\x9c\xd6\xc2\xcf\x28\x0c"
+  "\x79\x9d\xd9\xd5\xed\x7d\x3a\x90\x9e\x3a\xf3\x94\xf0\x83\x3e\xbe"
+  "\xa7\x0b\x5d\xd0\x31\xe9\xfe\xc3\x5d\xfb\x29\xab\x43\x68\x59\xf3"
+  "\x7c\x76\xc8\x41\xce\xcc\x45\xcd\xd6\xa7\x5f\x4a\x85\xac\x89\x66"
+  "\xe8\xc6\xff\x6b\xe6\xa9\x54\xeb\xdc\x0e\xba\x36\x6b\xbe\xd0\xc2"
+  "\x90\x35\xf4\xf7\x20\xfa\xdd\x06\xdc\x3b\x21\x77\x41\xc8\xda\xf4"
+  "\x50\x8c\xac\x89\xe4\xb7\xff\x15\xcf\x76\x45\xbf\xb7\x83\x90\xb5"
+  "\x36\x4d\xce\x69\x1d\x72\x7d\x85\x76\xe4\xde\x13\xe4\xad\x4d\x2b"
+  "\x55\xf2\xa6\x09\x25\x6f\x1a\xd3\xcf\xa4\xcb\x1b\xc6\x02\x72\x63"
+  "\xc3\x5f\x3a\xfe\xe2\xcb\x5b\x61\x8c\xbc\xbd\xa4\xcb\x5b\x92\x92"
+  "\x37\x8c\x6b\x62\x78\xb5\x92\x39\x6e\x83\xd7\x61\xfd\x32\x97\x5c"
+  "\x37\x5d\xb0\xed\x28\xf9\x47\xca\x1d\xe6\x97\x3a\x07\x64\x2e\x1f"
+  "\x32\x07\x78\xc2\xcf\xfa\x13\xfc\xf9\x5f\x3c\xe7\xcd\x2a\x14\xff"
+  "\x95\x1b\x1e\xe5\x82\x4c\x39\xa0\xd3\xfe\x02\x7d\xfa\x5f\x4f\x07"
+  "\xa8\x06\x32\x35\x1d\xb2\x94\x03\x99\xca\x87\x6c\xb1\x4c\x75\x86"
+  "\x57\x33\xcc\x9f\x77\xf6\xc3\x90\x73\x66\xb4\x4c\xa9\x9d\xeb\xf8"
+  "\xfb\x7f\x3d\xee\x6b\xa1\x19\x3f\x6c\x62\x7b\x05\xcf\x9d\x3e\xfa"
+  "\xa8\x5c\x7f\x0e\xf8\x68\xfb\x46\x69\xeb\x40\x16\x0b\x4b\xe8\x9a"
+  "\x93\x74\x5d\x3d\xf8\x9e\xf0\x9c\x82\xe7\xdd\xb3\x6f\xfe\x04\x36"
+  "\xc5\x97\x1e\xb4\xdd\xc3\xf2\x28\xdc\x13\xb0\xb6\xa0\x4c\xf0\xa3"
+  "\x45\xf4\xa4\xa7\x88\xe4\xc6\x6b\x45\x9f\x8d\xf7\x98\xac\x78\x1f"
+  "\x0e\x1a\x8c\xc1\xef\x88\x1d\xe7\x29\x0d\x7f\xb6\x1d\x6e\xcd\xc5"
+  "\xf6\x15\x9e\x33\xc4\x0a\x5b\xf2\xe6\xe5\x34\xd6\x1a\x20\x4b\xb5"
+  "\x5b\xcb\xb1\xae\x4d\xe5\xbd\x96\x34\x7e\x16\xee\xea\x86\xea\xf3"
+  "\x64\x66\x3b\x52\x4b\x42\x7b\x0e\xab\x10\x4b\xd3\xa9\x7a\x09\xf4"
+  "\x84\x9b\x6c\xd5\x6e\xd1\x10\xee\x61\x3a\xd4\xe4\x18\xb8\x30\x6e"
+  "\xc0\xf3\xbb\xc0\xb3\xe9\xd1\x95\x99\xf4\x07\x07\xc5\xdd\xa3\xec"
+  "\x71\x5f\xd7\xdf\xff\x41\xf2\x43\x06\x4d\xe2\xe7\xdb\x47\x1b\x74"
+  "\x1a\x64\x3f\xcb\xcc\xf3\x75\x78\xb9\xf0\x6f\x79\x8e\x98\x16\x36"
+  "\x67\x48\xfc\x15\x74\x74\x95\x84\xe9\xbb\xb3\x57\x5e\x27\xbc\x5d"
+  "\xa2\xd9\xeb\x38\x45\xd5\xc8\x2f\x29\x16\x9a\x96\xd4\x08\xde\x6d"
+  "\x08\x75\x2f\x17\xa1\x1d\xd2\xee\xb5\xbb\x7c\x74\xb7\x5d\x8d\x45"
+  "\x6d\x9b\x5c\xd7\x59\x1a\x42\x80\x75\x15\xc3\x3a\x8c\xfa\xe1\xd2"
+  "\x46\xd8\xa7\xf6\x7a\x1f\xb5\xc8\x33\x03\xc8\x73\x5b\xe1\x2a\xfa"
+  "\xce\x49\xb2\xfb\xa4\x6d\xef\x69\x4c\x63\xbd\x80\xb4\x54\xa4\x75"
+  "\x89\xd2\x46\x1b\xca\x63\x7d\xdc\xe0\x53\xb6\xae\xbd\xcb\x28\x87"
+  "\xe7\x66\x7e\x8e\xe2\x21\x79\xaa\x41\x18\x2f\xfb\xc0\x61\x48\x82"
+  "\xce\x56\xc6\xbf\x54\xfc\x65\xc6\xcf\x1e\xd0\xeb\x6f\xe7\xc0\xee"
+  "\x22\xe7\x1a\x1a\x8d\xf1\x01\x7e\xd7\xcf\x77\x3a\xc4\x09\xe1\xb6"
+  "\x07\x77\xad\x0a\x62\x5d\x70\x7d\x81\x8f\x5e\xee\x18\xdc\x7e\x86"
+  "\xdd\x73\x5e\x74\x6e\x59\xde\x4f\xcb\xe3\xb3\x57\x6a\x82\x9f\x59"
+  "\x2f\x55\x23\x9d\xe9\x06\x38\x7b\x0c\x9a\x0d\x3e\x2e\x8d\xa9\x6a"
+  "\x1d\x78\x43\x9a\x70\x0b\x6a\xbe\x96\xcf\x0f\x6e\xb8\x46\xd1\xe1"
+  "\xed\xce\x6e\xe8\x13\xde\x1f\xad\x06\xbd\x97\xda\x44\xb0\xc7\x7d"
+  "\x03\xec\xff\x5b\xca\xf5\xbd\x98\x80\x37\x34\x8d\x75\x4c\xdc\xf9"
+  "\x8b\xcf\x67\x06\xe0\x7f\x6f\x42\xeb\x68\xe8\x23\xa9\xa3\x9a\xc6"
+  "\x94\x28\xbc\x83\x0c\xb7\xb9\xe4\x2c\x75\x20\x7f\x69\x40\x74\x0a"
+  "\x4f\x93\x8d\xd7\x1a\xcd\xcb\x7b\x39\xed\x4e\xf0\xb6\x68\x5e\xc2"
+  "\x38\x7d\xef\xce\xe6\x6b\x7b\xe9\x04\xd6\x79\x58\xe3\xf9\xd5\xbe"
+  "\xcc\xf7\xec\x07\x8a\x48\xdf\xeb\xb9\xa1\xc6\x47\x63\x73\x0c\xbc"
+  "\xd8\xde\x00\x7d\x99\xd6\x6d\x6c\x77\xf0\x9e\xfb\xd2\x62\x11\x64"
+  "\xfb\x03\x65\x0f\x19\x7d\xe0\xfe\xe9\xfd\xf2\x45\xf6\x0b\x38\xf8"
+  "\xb1\x66\x96\x34\x58\xba\x92\x2c\x76\x45\x6b\x0b\xf7\x97\xfb\xc2"
+  "\x7d\x96\x7d\x91\xba\x16\x73\x45\xe8\x4e\xac\xc1\x64\x3a\x60\x7d"
+  "\x0f\xeb\x9f\x5b\x02\x8a\xa7\x6e\xa8\x89\xe5\xa3\xfe\x71\xb4\xd4"
+  "\xd6\x3b\x2f\xd0\xb5\x4e\x4d\xb4\x03\xe6\x3e\xd0\x29\x91\x7f\x35"
+  "\xb6\xb9\x83\xcc\xbf\x1f\xfa\x78\x6e\xf6\x16\x9f\x63\x5b\x9b\xcb"
+  "\x5e\x8d\xb2\x1d\x28\xf3\x2f\x7a\xd9\x7f\x51\xe7\x2d\xf2\x77\x18"
+  "\xff\x62\x3e\x7b\x07\x78\x34\xfb\xe5\xbc\xff\x5b\x9f\xf1\x2e\xf0"
+  "\x8e\x5f\x87\x28\xfd\xd0\x17\x1f\x97\xba\x7a\x9e\xd7\xc2\xe7\x45"
+  "\x17\xda\xf9\x16\xf3\x94\x73\x25\x7d\x1b\x7c\x79\xbc\x64\x0d\x5d"
+  "\xcd\xfc\x24\x92\x1a\x47\x2b\xba\x8f\x49\x11\x6e\xd8\xa1\xd0\xaa"
+  "\x85\xcb\xe9\x3b\x90\xa3\xb4\x93\x34\xe6\xfa\xdc\x62\x3b\x70\x25"
+  "\xda\x72\x9a\x48\xea\xa0\xa4\x46\x9b\x37\xf4\x05\x55\x9f\xe6\xfd"
+  "\x96\x31\x99\x06\x2f\xe2\x39\xeb\x52\xfa\x02\xf3\x4d\xba\xda\x2f"
+  "\x18\xb3\x8f\xf7\xd7\xdb\x69\x4c\x1d\xf7\x17\x7f\x09\x48\x7b\x43"
+  "\x9c\x17\x73\x85\x9c\xdb\x76\xd9\x7c\x34\xe6\x08\x7e\xd3\xe5\x9f"
+  "\x9b\xe6\xe9\xef\x36\x94\x5b\x2f\xce\x6b\x5c\x26\x1d\x69\x55\xc2"
+  "\x9d\xc0\x32\xd1\x84\xb6\x0f\xfa\x68\xf2\x44\x35\x36\x63\x2a\x18"
+  "\xd6\x20\x38\xd8\x30\xb6\xc4\xbc\x79\x82\x6e\xbc\xcd\x5e\x92\x00"
+  "\x3c\x6e\x1c\x22\xe5\x02\xb0\xaa\x4d\x4a\x6f\x6b\xc0\x75\xa7\x5b"
+  "\xcb\x87\x8e\xce\xd7\xca\xf6\x65\xca\x67\x3d\x4f\xe8\xf3\x69\x7c"
+  "\xf8\x4d\x63\x9a\x47\x31\x8f\xdf\xb8\x51\xc1\x69\xb2\x35\x8f\x3a"
+  "\xc9\xef\x9b\xf8\x3d\x60\xf9\x38\xd3\x5b\x99\x89\xf6\x4f\x72\xbb"
+  "\x1b\xd5\x3e\xc0\x8d\x9b\xba\xd1\x46\x8f\xfb\xc6\x8d\x3e\x1a\x97"
+  "\xa7\xce\x1a\x3e\xce\x1c\x44\xf6\x52\x59\x76\x58\xe6\x94\x4c\x7f"
+  "\x7f\xe6\xe1\x1a\x96\xbf\x5d\x96\x6e\xcb\xae\x74\x5d\x6f\xf0\xde"
+  "\x4a\x4a\x3b\x7d\x3f\xeb\xb0\x4d\xf2\xb7\x49\x98\x6e\xec\x7a\x57"
+  "\xf3\x9b\xf8\x3c\x48\xa9\xaf\xef\x67\x5d\xfc\x77\x13\x14\xe0\x4d"
+  "\x19\xf8\x9b\xa4\xbf\x4f\xc7\xdf\x5c\xfc\xed\xc6\xfb\x24\x49\xbb"
+  "\xed\x79\x09\x3e\xe4\x75\xc3\x7e\xe7\x77\x1f\xdd\x94\x2e\xb6\x8f"
+  "\x31\x09\x8b\x7a\xae\xfe\x36\xef\x25\xdc\x34\x07\x63\x70\x4c\x8d"
+  "\x05\xc3\xa1\x04\xe0\xc6\x74\x17\xce\x4a\x11\x6c\x29\x09\x00\xef"
+  "\x9b\xd6\xb7\x54\x06\xc8\x7e\x13\xf7\xff\x26\x0f\xf7\x29\x00\xfa"
+  "\xf3\xef\xd2\x4a\xe1\x3f\x50\x15\x22\x3e\x97\x02\x2c\xc8\xff\xcf"
+  "\xa6\xaa\x7d\x89\xa6\x4c\x86\xa7\xf3\x84\x30\xfa\xaf\x74\xda\xc7"
+  "\x99\x3c\x96\x80\xf5\x19\xfa\x6e\x3d\x4d\xdf\xbf\x46\x24\xef\xcb"
+  "\x3c\x90\x4f\xb4\x03\x7a\x04\x73\x8d\xdc\x2f\x87\x5e\x62\x98\x98"
+  "\xff\x6f\x9c\x64\x9c\xa3\x6c\x42\xfe\x66\xe4\x61\xee\xf1\x1f\xce"
+  "\x0f\x12\xc3\x0a\x73\xff\x50\x7f\xbf\xe6\x37\x63\xae\xc6\x98\x7f"
+  "\x9c\x59\x52\x08\x3d\xd3\xaf\xb7\x6e\x6a\x5a\x73\x4a\x04\x8d\xfe"
+  "\xf1\x59\x65\x8f\xfb\xfb\xe0\xff\x45\xf3\x06\xe5\xff\x7e\x9c\xd3"
+  "\x17\x1d\x18\xa3\xc6\x4c\x03\x5d\xa2\xc7\x2c\x3d\x5f\x8d\xd7\xf7"
+  "\xab\xa2\xc7\x2b\x1d\x3d\xf9\x7e\x07\xfe\x42\x78\x4e\x51\xef\x91"
+  "\x7f\xdf\x3f\x12\xf1\x0e\xee\x48\x9f\x03\x7c\x30\xff\x8f\xc9\x51"
+  "\xe3\xc0\xe9\xe8\x07\xf3\xc8\x57\x64\xe1\xfd\x39\x3e\xa7\xe4\x74"
+  "\xe6\x67\x4e\xd7\x60\xcf\xa0\x3f\x7e\xe4\xa7\xb2\xac\x6e\xd1\x28"
+  "\x2a\xdf\xbb\x1e\x3c\xb7\xaa\x97\xf1\xbf\x4f\xee\x29\xae\xf5\x78"
+  "\x98\x4f\x51\x27\x60\x0d\x79\x60\x57\xa6\x67\x19\x74\x45\xbd\x09"
+  "\x9c\xcf\x3c\x89\xf4\x3c\xd0\xa5\x46\x9e\x43\x62\xed\x17\xdf\xd6"
+  "\x48\xf7\xf4\xdb\x64\x96\x5d\x1e\xd6\x47\x5d\x74\x73\x05\x74\x16"
+  "\xc6\x76\xdf\x44\x35\xd7\xdc\xfc\x06\xbf\x43\x57\x1e\xc7\x73\xf9"
+  "\x61\xe8\xa4\xde\xb2\x06\x57\x9f\x89\x86\xf5\x9a\x28\x33\x54\xf6"
+  "\xe5\xee\x50\x72\xfd\x46\x6f\xe7\x1e\x6a\x0d\xbd\x4f\xf6\xe7\x24"
+  "\x8c\x52\x2f\x7a\xee\x5c\x29\xc2\xef\xf5\xd6\x9b\xbd\xa1\x33\xcd"
+  "\x98\x9b\xaf\x3b\x49\x37\x4b\x7a\xbc\xd2\x8e\x59\xff\x69\x09\x5b"
+  "\xa7\xcf\x97\x9e\xcd\x0b\x45\x68\xf3\x09\x11\x80\x7d\x97\xbc\xa9"
+  "\x97\xc6\x6e\x5b\x45\x19\x55\xbd\x34\x66\x67\x2f\xa5\x8b\x2f\xd3"
+  "\x4d\x55\xb0\xdb\x9e\x3e\x97\x4a\xd0\x09\x39\xc3\x0b\xc9\xb2\x73"
+  "\x15\x49\x1e\x09\x97\xc2\x7e\x0b\xc1\x7e\x3b\x93\xce\xba\xb1\xdf"
+  "\x7e\xeb\x93\xb6\x71\xe3\x7a\xc5\x47\x8d\xeb\xaf\xcc\xa7\x84\x94"
+  "\x79\x94\x0a\xfc\x9c\xa7\x29\xfd\x8f\x29\x1d\xb0\x1d\xd1\x67\x9f"
+  "\xde\x5f\xd0\xee\x98\x35\x9f\x86\xc9\xbe\x42\x5f\x8b\xd2\x7d\x13"
+  "\x07\x9d\x87\x4d\xcc\x53\x01\x96\x1b\xee\xc3\x71\x3e\x2b\xdd\x33"
+  "\x2a\x68\x5e\x5a\x25\x82\x9c\x5e\x74\xbd\x08\x22\xfd\x20\xb7\xdd"
+  "\x80\xf4\x1e\xf7\xcd\x7e\x9f\xa9\x6a\xee\x60\x3c\x8a\x75\x92\xae"
+  "\x57\x6e\x79\x49\x98\x5c\xcc\xa3\x07\xd7\x84\x60\x7f\x9f\x66\x99"
+  "\xbd\xa5\x70\x76\x81\x08\xd9\x17\xf3\xb9\xf5\x2d\xf3\xf8\x4c\x9d"
+  "\xcf\xd2\xde\x85\x6d\xf3\x75\xe7\xe8\x3c\x5f\xf0\x7a\xc1\x5a\x00"
+  "\x98\x65\xbb\x0e\x0a\xac\xd3\xbf\xa9\x1d\xcf\xbe\x1c\xaf\x4b\xbf"
+  "\x91\x5b\x76\xfb\xe8\x27\x66\xc6\x9d\xcf\x4c\x59\x77\xc2\xde\xba"
+  "\x1a\x78\x75\x06\x40\x07\xe4\x63\xfe\xff\x71\x9b\x7e\xee\x29\xfd"
+  "\x51\x90\x86\xf9\x7f\xc6\x68\x4e\x2b\xba\x9e\x6c\x45\x76\x31\x98"
+  "\x4d\x63\x96\x3e\x22\x26\xfa\x56\x8f\xfb\x9f\xd2\x0c\x38\x98\xa7"
+  "\x7e\xd9\x6d\x7a\xf4\x51\xa4\xa5\x1b\x70\x50\xe6\x1a\xbc\x4f\xec"
+  "\x2f\xa3\xea\x4c\x8f\xa8\xf3\x68\xb7\xe9\x96\x5f\x22\x6d\x6e\x4c"
+  "\x9d\x82\x98\x3a\xc5\x11\x75\x5c\x7a\x3b\xe5\x31\x75\x6a\x62\xea"
+  "\x34\xc4\xc1\xad\x25\xa6\xce\xd1\x98\x3a\x1d\x71\x70\x0b\x46\xd7"
+  "\x19\x6b\x89\xae\x33\xd6\x16\x41\x4b\xf6\xd7\xc8\x40\xda\xd8\x98"
+  "\x3a\x93\x62\xea\x64\x19\xef\x83\xf9\xe4\x2c\xdd\x41\x36\xf0\x66"
+  "\x27\x8f\xe7\xeb\x18\x9f\xee\x37\x9f\xef\xd1\xeb\x7a\x2e\xee\xd7"
+  "\xd8\xaa\x98\xf6\x76\xc7\xb4\xd7\x74\x71\xbf\xc6\x1e\x89\xa9\xe3"
+  "\x8b\xa9\xe3\x8f\xa8\x53\xa3\xda\x19\x67\x8e\xae\x33\x2e\x2d\xba"
+  "\xce\xb8\x31\x17\xf3\xd5\xb8\x89\x31\x75\xa6\xc7\xd4\xc9\xf9\x1a"
+  "\x5a\xf0\x3c\xae\x7c\xa7\x46\xb2\xad\x7c\x3f\x6c\x84\x71\x9f\xb2"
+  "\x4f\xc0\x16\xb4\xb1\xab\x37\x38\x84\xcf\x3f\x78\xbe\x3a\xe0\x08"
+  "\x62\x6e\x19\x87\xf5\xcf\x1d\x76\x63\xce\x62\x7f\x09\x96\x69\x65"
+  "\x63\x8f\xf3\x0c\x66\x8b\x72\x3b\x86\x2f\x15\xb7\x75\x60\x34\xcf"
+  "\x53\xe3\x02\xfd\x36\xb1\xf2\x2f\x22\x05\xe7\xd6\x19\x0c\x87\xdb"
+  "\xaf\x56\x7e\x18\x09\x6c\x93\x1f\x70\x70\x9d\x5b\xd3\x23\xec\x68"
+  "\x6e\x3f\xb0\x67\x55\xd0\x1c\x8d\xc7\xad\x96\x4b\xe0\x91\x02\xdb"
+  "\xc8\xd2\x5a\x45\xc4\x67\xcc\x87\xab\x60\x03\xc1\xee\x67\xdc\xda"
+  "\xe9\xd6\x72\x69\x93\x2d\xee\x25\x7e\xf6\x16\xdf\x2d\xcf\xa0\x95"
+  "\x4d\x7a\xeb\xc1\x16\xb4\xcf\xb6\x7b\x4b\xe1\x59\xea\x96\xf3\x2f"
+  "\xdb\x6e\xb7\x9e\x3b\x50\xec\x67\xbc\x9a\x0d\xff\x0c\x1f\xdd\x1a"
+  "\x90\xb6\x86\xa7\x49\x9e\x8f\xf3\x99\xd1\x81\xc0\x44\x2e\x03\xfe"
+  "\x1f\x77\xc8\xe8\x2f\xe6\x7a\xf0\xc0\xad\x55\x97\xa2\x99\x1a\xc3"
+  "\xf1\xa3\xa3\x79\x72\x08\x78\x65\x7c\x46\xf4\xb8\x8f\xcf\x8c\x1e"
+  "\xf7\xf1\xd9\xd1\x3c\x69\x02\x4f\x8e\xcf\x8b\xa9\x53\x14\x53\x67"
+  "\x7d\x44\x9d\x72\xbd\x9d\xca\x98\x3a\xf5\x31\x75\xf6\x46\xbc\xa3"
+  "\x8f\xe3\x0f\xf6\xaf\x7d\xa4\xef\xcf\xf8\xb6\x88\x77\x53\x85\xd4"
+  "\x9f\xe3\xbb\x8c\x34\xde\x43\xda\xb9\x55\xf9\x9e\x28\x78\x19\x96"
+  "\x18\x79\x47\xf9\x8c\xd1\xd1\x38\x64\x8c\x8d\xc6\x21\xa3\x5f\xfe"
+  "\xb7\xa8\xb5\xdb\xef\x4f\xd0\x6d\x69\x92\x87\x20\x23\x98\xb3\x67"
+  "\xf3\x3b\x60\x55\xa2\x3c\xe8\x90\x51\x10\x03\xaf\x38\x06\xde\xc6"
+  "\x88\xf7\x54\xbc\x57\x45\xf4\x21\x35\xd1\x26\xfd\xf8\x60\xbf\x65"
+  "\xec\x31\xd2\x79\x4d\x09\x7c\x3b\x9d\x72\xae\xc9\x64\x9f\xaa\x11"
+  "\xed\x94\x51\xcb\xeb\x4f\x1d\x66\xa4\xfc\x93\xde\xaf\x40\x34\x1e"
+  "\xb7\x99\xa3\xf1\xb8\x2d\x2d\xa2\x5f\x01\xeb\x5a\x7a\xc8\x1a\x7a"
+  "\xf8\x71\xb6\x7d\xd8\x17\x4e\xfa\x36\xad\x81\xcd\x76\x8e\x52\xd9"
+  "\xa7\xec\x44\x11\x25\x7a\x1d\x9d\x58\xcb\x35\xba\x06\xe5\xa7\xe4"
+  "\xa6\x54\xdd\x2f\xcf\x0e\xf8\x45\x06\x3f\x6a\x65\x4d\xa9\x5a\xe9"
+  "\xde\xb1\x48\x83\xfe\x1b\x4f\xca\xce\xfd\xc8\x21\x9c\x39\x95\xa0"
+  "\x27\xd6\x45\xb7\x2f\xd3\xd7\x11\x63\xd8\x37\x0a\xba\xa7\x13\x73"
+  "\x7c\x8a\x3a\x1b\xbf\xad\x29\x82\xaf\x03\xf6\x55\xf7\x8a\x76\xba"
+  "\x7d\x2d\xdb\x00\x2c\xa3\xec\x63\x75\x20\xe4\x27\x5e\x7b\x7b\x43"
+  "\x27\xa5\xed\x86\x7c\x97\x5e\x37\x18\x51\xd7\xaf\xaf\x8d\x79\x1e"
+  "\x35\x8f\x0f\x91\xf9\x40\xc0\x4f\x80\x93\xa6\xec\xbd\xdb\xd7\x1e"
+  "\x80\xbc\xf6\xb8\x6f\x1f\x6b\xd4\xe1\x75\x34\xd7\xb1\x16\x91\xf9"
+  "\xd6\x62\x32\x37\xaf\x6a\x97\xb0\xf5\xb1\xef\x84\x2d\xdd\xe5\x2d"
+  "\xee\x24\x6f\xa0\x8d\xf7\xba\xcc\xca\x4f\xe5\x76\x57\x62\x90\x2c"
+  "\xdd\xa5\x4d\xb0\x2b\x6f\x77\x85\x4b\x9b\x78\xbd\x64\xf7\xd1\x6d"
+  "\x75\xac\x6f\x22\x69\x37\x6d\x5a\xf6\xc3\xb3\x67\x8e\xfb\xe9\xc3"
+  "\x33\xe6\x4c\xbb\xdb\x3e\x67\xd1\x0b\x0b\xf2\xc6\xbd\xb8\xac\xc8"
+  "\xbe\x62\xc9\xa2\xa2\x45\x8b\x7f\x66\xcf\x70\xdc\xe8\xb0\xcf\x2f"
+  "\x52\xbf\xe9\x05\xf3\x97\x16\x4d\xe6\xc7\xb1\xf6\xc2\x25\x0b\x96"
+  "\xcb\xc7\x9b\x93\x29\x1a\xc8\xa2\xa2\x05\x4b\xec\x37\xe6\x8d\xb5"
+  "\x3f\x30\x7f\x51\xc1\xb2\x25\x0b\xe2\xc2\xba\xdb\xbe\x64\xc1\x92"
+  "\x05\xf3\xf3\xec\x93\xed\x19\x0c\x39\x12\x5c\xc4\x78\x66\x18\xf3"
+  "\x18\xcf\x5f\x5b\xdc\xe2\x88\x3e\x9f\xf9\x14\xff\xdc\x31\xe7\xe2"
+  "\xb9\xec\x8e\xfc\x68\x9e\xbb\xc3\x11\xcd\x73\x77\x78\x2e\x9e\xcb"
+  "\xee\x88\x99\xff\xee\x88\x99\xff\xee\x68\xba\x78\x2e\xbb\x23\x66"
+  "\xfe\xbb\x23\x66\xfe\xbb\xa3\x7f\xfe\x03\x2f\xf9\xd6\x49\xbd\x30"
+  "\x21\x66\xfe\x9b\x10\x33\xff\x4d\x18\x13\xf3\x3e\x21\xe2\xfd\x6a"
+  "\xbc\x4f\x8d\x9c\x1f\xf1\x3e\xc7\x90\xcf\x01\xfd\x32\x21\xdf\x28"
+  "\xc3\xba\x1e\xba\xb9\x43\x2f\xeb\x8a\x28\xdb\xa9\x97\xad\xe8\x97"
+  "\x3f\x3e\xfb\x46\xba\x5a\xaf\x4f\xb8\xc0\x3a\x9d\xfd\xd0\x78\x6e"
+  "\x82\x7c\x5c\x77\x9a\x26\xbc\xc4\xb0\x98\x87\xd9\x2f\x51\xbc\xf9"
+  "\x64\x4f\xf5\x08\xb2\x70\x9d\xea\xd7\xc8\x2c\xdc\xb7\x6f\xc4\x2f"
+  "\x21\x2d\x05\x7f\xd0\x29\x13\x60\xff\xee\x18\xab\xe6\x8b\x3b\x33"
+  "\xa5\xcd\x8f\x3a\x0a\xfe\x9d\x72\x5d\x03\x38\x36\xd4\xb1\x6c\x51"
+  "\x73\x71\x07\x9e\x53\x98\xa7\x51\xdf\x2c\x4c\xb7\xff\x07\x7e\x09"
+  "\x69\xa9\xf8\x4b\xeb\x71\xdf\x99\x69\xc0\xe3\x33\xf2\x78\xf2\x1f"
+  "\x6b\xe7\xf6\xaf\x07\x4d\x64\xdd\xe2\xd6\xda\xbc\x1a\xdb\xd6\x77"
+  "\x16\xa9\xbd\x85\x86\x1a\xe1\xfe\x24\xa7\x1a\xe9\xf1\xd7\x49\x77"
+  "\xc2\xfe\xbb\x33\x5f\xed\xb7\xdc\x89\xf1\xff\x49\x85\xda\x3b\x6d"
+  "\xa8\x81\xbe\xed\x3d\x41\x3f\x78\x14\xbf\x7d\xf8\xbd\xcb\x80\xdf"
+  "\x2c\xd7\xdb\x77\x1e\x15\xee\x84\x47\x18\x6e\x4c\x7a\x17\xf4\x5b"
+  "\xaf\x35\xe4\xca\xb9\x38\xef\x07\x58\xc3\x24\x3e\x1c\x27\xdd\x0e"
+  "\x9b\xa1\xd7\x47\x3f\x98\xc3\xf8\x46\xa4\x4f\x14\xee\xe1\x73\xb8"
+  "\xbc\x8f\xdb\x43\x9d\xc1\x6c\x6d\xc3\xef\x54\xf9\x89\xff\x60\x7d"
+  "\x4c\x3f\x2e\x9c\xa0\x1f\x26\xa8\x7e\xfc\xf0\xa9\x98\xb6\xab\xe2"
+  "\xf7\xe3\x07\x7b\xd0\x8f\x0b\x83\xf4\xe3\x88\xa4\xad\x09\x7d\x31"
+  "\x5d\x94\xc7\xf6\xcf\x05\x49\xf7\xa8\xf4\x1f\x9a\x75\x5b\x28\x80"
+  "\x75\x58\x2a\xf2\x64\xdd\x47\x8a\x07\xc6\x4d\x2f\x37\xd6\x5a\x49"
+  "\xd9\x17\xb7\xf9\xc3\xa9\xc2\x3d\xec\x11\x1f\xfd\xb0\x58\xc2\x19"
+  "\x48\x9f\xab\x70\x01\x9d\x4c\x4c\x27\xf4\x07\xf5\x06\x1b\x6f\x63"
+  "\x5d\xa2\xf6\x42\x7e\x08\xf9\xff\xc1\x3c\x63\x2f\x73\x69\xb1\xf0"
+  "\x1b\x74\x44\xde\xc1\x98\xbc\x60\x44\x5e\x47\x54\xde\x9a\xfe\xf4"
+  "\x90\x91\xfe\xcd\xc6\x69\xe2\xd8\x98\x71\xc2\xf8\x4c\xdc\x1f\xdd"
+  "\xef\x89\x93\x54\xff\x30\x46\x17\xd1\x7a\x62\x0e\xc6\xa8\x2f\xfe"
+  "\x18\x4d\x2c\x8a\xcf\x6b\x13\xe5\x3e\x9a\x18\x41\xf1\xe0\xd5\x63"
+  "\xec\xfa\x24\x0f\xea\xe3\x74\xf1\xf8\x4c\x3c\x64\x8c\xcf\x37\xeb"
+  "\xe3\x5d\xa9\x31\x7d\x0c\x9f\xa0\xbb\x36\xa9\xbe\xde\xf5\x79\x34"
+  "\xec\xbb\xd2\xe3\xf3\xe2\x5d\x99\xe8\x67\x38\x7e\x3f\xef\x9a\x3b"
+  "\x38\x2f\xde\xe5\x40\x7f\xc2\x17\xf3\xe2\x5d\xca\x87\x49\xe7\xc1"
+  "\x98\xbc\xdd\xc2\x1d\xb7\x9d\x16\x67\x88\xed\xdc\xbb\xf8\x2c\xc5"
+  "\x16\x91\x7e\x2c\x9a\xff\xd0\x07\xae\xc7\xf4\x0b\x29\x3d\xcb\xe3"
+  "\x70\xc2\x4e\xa6\xaf\xe3\xc9\x1e\xf7\xdd\x93\x62\x68\x75\xe6\x04"
+  "\xdd\xbd\xbf\xdb\x94\x50\xa7\xe8\xf5\xa3\xb5\xd1\x38\xdd\x9d\x13"
+  "\x9f\x5e\x77\x17\x82\x5e\x67\xe2\xd3\xeb\xee\x8d\x83\xd3\xeb\x6e"
+  "\x1e\xff\x33\x17\xd3\xeb\xee\xe6\x48\x7a\xc1\xd6\x95\xfd\xfb\x9e"
+  "\x0d\xbc\xd1\x97\x2b\xaa\xb9\xaf\x61\x4a\xb5\x82\x57\x54\x9d\x2e"
+  "\xae\x13\xb0\x06\x15\x9f\xc0\x86\xb4\x9c\xa6\xbb\x8f\x19\xf2\x3f"
+  "\xbc\x92\x86\x89\xbe\x27\xd9\xa7\x28\x81\xeb\x79\x1d\x67\x9a\xbd"
+  "\xa1\x0c\xe2\xf5\x47\x74\xbb\x3f\x9a\x18\x5f\x17\xfc\x28\x1b\x34"
+  "\x7d\x2d\x4e\x7a\xbe\xf2\x27\xfb\x51\x4d\xb4\x8e\xf8\x91\x2b\x7a"
+  "\x8c\x40\x37\xd4\xa3\x81\x3b\x38\x97\xfc\xbb\xf4\x98\xfd\xc8\x7f"
+  "\xf1\x98\x4d\x7a\x55\x8d\xd7\xa4\x97\xa2\xf1\x9b\x64\x89\x3f\x5e"
+  "\x93\xec\x83\x8f\xd7\xa4\x49\x83\x8f\xd7\xa4\x1c\x1e\x2f\x1f\x4d"
+  "\x2a\x8f\x9e\x37\x26\x15\x46\xf7\x77\x92\x94\x61\x61\x1a\x7a\x35"
+  "\xbf\x7f\xd3\x7e\x1b\x7f\xac\xe3\x78\xac\xaa\x4b\x08\xbc\x9c\x70"
+  "\x3d\xe3\x78\xb9\x30\x06\x85\x0d\x1a\x96\xaf\x8a\x7f\xde\xca\x6b"
+  "\xdc\xd6\x4a\x22\x3e\x47\xb6\x5f\xcb\xb6\xfb\xe4\x05\x9a\x89\xda"
+  "\xf0\x6c\x3a\x41\xf7\xde\xa6\x99\x4c\xc5\x7c\xe6\x29\x7d\xb7\xe5"
+  "\x1e\xc2\xe4\xe2\xc8\xb1\xe0\xb3\x4f\x5e\x9b\x6e\x56\x6b\xa7\xbf"
+  "\x9c\xa0\x7b\x86\xa8\x71\xb9\xf7\xaa\x68\x3a\x4e\xae\x89\x3f\x2e"
+  "\x93\xf7\x62\x5c\xfe\x12\x7f\x5c\x26\x1f\x1d\x7c\x5c\x26\xfb\x31"
+  "\x2e\x7f\xb9\x58\x8e\xee\xb1\xe8\x72\xb4\x8e\xeb\xd8\x17\xf3\x7a"
+  "\xfc\x9e\x95\x5c\x06\xcf\x90\x91\x7b\xe6\x73\xfe\xb8\x2e\x43\x8e"
+  "\x64\x9d\x49\x80\x25\xdb\xd7\xcb\x4c\xd4\x61\x44\xc2\x9d\x67\xed"
+  "\x8a\x27\x27\xf7\xf0\x1d\xf2\x84\x5b\x0b\xc9\x02\x1a\xe6\xec\x60"
+  "\x18\x4b\x88\x00\xe3\x30\x97\xe3\x74\xac\xf0\x23\xe4\xe4\x9e\x7a"
+  "\xa3\x1c\xeb\x3a\xbd\x6c\x8d\xe8\xc9\xe7\x9d\x80\xd8\x36\xf5\xfe"
+  "\x0f\x93\xf3\x08\x97\xe7\x72\x31\x65\x82\x4a\x1e\xef\x9d\x14\x2d"
+  "\x8f\xf7\xa6\x46\xf3\xe7\x64\x49\x27\x0d\x7a\x0e\xcf\x79\xc0\xe1"
+  "\x1b\xf3\xd7\xa5\x65\xf3\xde\x8d\x31\xb2\x09\x1e\xc8\x1c\xa7\x78"
+  "\x20\xf3\xca\x68\x5c\xef\xad\x8b\xcf\x03\xf7\x36\x0d\xce\x03\xf7"
+  "\xb6\x0d\xce\x03\xf7\x06\x98\x07\x7c\x94\x39\x36\x5a\x36\x33\x53"
+  "\xa2\xfb\x8e\x76\xa5\x6c\xd2\x55\x97\x23\x9b\xb0\x85\xae\x1e\x4c"
+  "\x0e\x59\xa6\xd8\x87\xa4\xba\xd7\x38\xeb\xf8\x46\x34\xb3\x40\xae"
+  "\x18\xbf\x66\xde\x53\x82\x8e\x9f\xc8\x34\xdc\x29\xef\x06\x66\x1e"
+  "\x8d\xa4\xe3\x66\x75\x7f\xcd\x79\x82\xee\x7b\x9c\xcf\x95\x15\x3d"
+  "\xef\xbf\x3e\xba\xff\x99\x81\xf8\xf4\xbc\x2f\x05\xf4\x74\xc6\xa7"
+  "\xe7\x7d\xe9\x83\xd3\xf3\xbe\xa9\x7c\x37\xe8\x62\x99\xba\x6f\xae"
+  "\x7d\xb9\xb4\x51\x64\x9d\xd3\x74\xdf\x07\xdf\x6c\x7e\xba\xaf\x22"
+  "\x7a\x7e\xba\xaf\xf8\xf2\xe7\xa7\xfb\xda\xe2\xcf\x4f\xf7\xf9\xe3"
+  "\xcf\x4f\xf7\x5b\x94\x3c\xdc\x9f\x19\x2d\x0f\xf7\xdb\xa3\x79\x22"
+  "\x33\xf0\x3f\x37\x3f\xdd\x5f\x1e\x23\x03\x5b\x4e\xd0\x94\xab\x60"
+  "\x53\xb8\xd4\xb8\x4d\xf9\x2c\x06\xc7\xdd\xf1\xc7\xed\xfe\x16\x8c"
+  "\xdb\x96\xf8\xe3\x76\xbf\x6f\xf0\x71\xbb\x3f\x84\x71\xdb\x72\xf1"
+  "\xb8\x4d\x49\xbb\x7c\x9b\x62\xca\xf4\xe8\x31\x9b\x92\x71\xf9\x63"
+  "\x36\x65\x63\xfc\x31\x9b\x52\x17\x7f\xcc\xa6\x34\xa9\x31\x9b\x12"
+  "\x88\x1e\xb3\x29\x47\xa3\xc7\x0c\x74\xfb\x3b\xc7\x0c\xe3\x53\xa7"
+  "\xfc\x13\xa6\x3e\x8a\x75\xfb\xb0\x1e\xf7\xd4\x2c\x1f\x4d\x4b\x53"
+  "\x6b\xeb\x69\x6a\xee\x50\x63\xf8\x1e\xca\x64\x5e\x3c\x0f\x4c\xcd"
+  "\xd7\xd3\x7e\x7a\xf1\x38\x4c\x5d\x0f\x1d\xdd\xd5\x52\x2c\xcf\xb6"
+  "\xd4\x18\x32\xcd\x51\xae\x79\x15\x9f\x4f\x4d\x95\xfe\xeb\x18\x63"
+  "\xe1\x0d\x86\x88\xf5\x3a\xca\x07\x18\x0e\xdf\x89\x8c\x81\x75\xe4"
+  "\x72\xe6\xf8\xc1\x7d\x6a\x1a\xea\x9a\x4b\x6e\x07\xbc\x69\x5f\x28"
+  "\x5e\x9d\x16\x6b\xff\x56\x23\x6f\x9f\xe2\xd3\x1f\x6f\x88\xc6\x61"
+  "\xda\x9c\xf8\x7c\x3a\xad\x00\x7d\xa8\x8e\xcf\xa7\xd3\x3c\x83\xf3"
+  "\xe9\x34\x8c\x3f\x55\x47\xac\x7d\x46\x3c\x1d\xf2\xc5\xac\x7d\xa6"
+  "\x1d\xb4\x06\x14\xef\x48\x9b\xa8\xb4\xa1\x0e\x38\xc7\xda\x7f\x18"
+  "\x9b\x07\x5e\xd0\x71\x5e\x10\x5d\xff\x81\x41\xec\xbf\x07\xd8\xfe"
+  "\x7b\x2f\x3e\xce\x0f\x5c\xc2\xfe\x7b\x80\xed\xbf\xf7\x2e\x96\xad"
+  "\x07\x74\xfb\x2f\xde\x1a\xef\x81\x8d\xf1\xc7\xff\x81\x98\xf1\xa7"
+  "\x9c\x22\xac\x87\x65\xfd\xe8\x72\x87\x22\xcb\xb1\x6f\x12\x97\x65"
+  "\x1e\x89\x53\x36\x18\x0b\x33\x7e\xb9\x1f\xdb\x2f\xe2\x3d\xf6\xa5"
+  "\x8a\xcb\x7b\x3f\xce\x52\xf2\xf8\xe3\xba\x68\x79\xfc\x71\x5e\xb4"
+  "\x3c\x3e\x10\x33\x76\x3f\x5e\x1f\x9d\x0f\xfe\xf9\x1f\xd3\xb1\x3f"
+  "\x0e\xc4\xf0\xc0\x27\x27\x68\xfa\x4b\x8a\x07\xa6\xff\x31\x1a\x8f"
+  "\xe9\x29\xf1\x79\x60\xfa\x18\xf4\xff\x93\xf8\x3c\x30\x3d\x73\x70"
+  "\x1e\x98\xce\x3e\x3e\x9f\x44\xf2\xed\x23\xc5\x99\xc3\x62\xca\xb8"
+  "\xe2\xeb\xbc\xe9\x95\xf1\xf7\x08\xa6\x37\x28\x1a\x4f\xef\x8c\xa6"
+  "\xf1\xf4\x83\xd1\x34\x44\x5f\xfe\x7e\x1a\xf6\xc7\x26\xe8\x71\xcf"
+  "\x88\x95\x7f\xef\x09\x9a\xa1\xcb\xff\x83\x8d\xd1\x38\xce\x98\xa3"
+  "\x70\x89\xb7\x2f\x32\x83\xd7\xbf\xde\xf8\xb4\x9c\xb1\x31\x7e\x9f"
+  "\x67\xd4\x61\x0e\xf2\x6a\x17\xc9\xd2\x8c\x26\xa4\x3f\xc2\xfb\xa1"
+  "\xbc\x1f\xb2\x13\xe9\x8f\x84\xc8\x22\xe7\xab\xfe\x79\x69\x86\x8f"
+  "\x7d\x51\x98\xfe\xcc\xbf\xd6\xd1\x94\xcd\x73\x10\xe3\x95\x5b\x2c"
+  "\xfd\x16\xac\xeb\x99\xd7\x6f\x60\x5e\x7f\x50\xda\x7f\x7c\xce\xc2"
+  "\x7e\x84\x56\x07\x65\x7b\x03\x21\x32\xf8\x9d\xcb\x47\xc3\x7e\x70"
+  "\x12\xcb\x05\x97\x37\xca\xaa\x7d\x33\x57\x0c\x7f\x3f\x98\x17\x7f"
+  "\x8c\x1f\x2c\x1e\x9c\x77\x1e\xac\x54\xe3\xfc\xe0\xa1\xe8\x71\x7e"
+  "\xb0\x41\x73\x0f\x9f\xc3\x7d\xf5\x81\xce\x97\x33\xc6\x45\x76\xe1"
+  "\x1f\x54\xdf\xaf\x7b\xb2\xad\xb0\x84\xae\x3d\x49\x3f\x99\x20\xdb"
+  "\x33\x89\xa0\x75\x6d\x02\xb5\x48\x1d\xf0\x93\x52\x89\x27\xca\xe4"
+  "\x86\xc8\x24\xd6\x3d\xdf\xc6\x79\xd5\x6e\x11\x44\xb9\x23\x7c\x26"
+  "\xc0\x77\x8a\xc1\x0b\x57\xb7\xd3\x4f\x66\x46\xd5\x37\x13\x79\x15"
+  "\x0c\x4f\xb5\x94\xc7\x9f\xac\x37\xf6\x74\xd7\xe3\x3d\xfe\xbe\xef"
+  "\x4f\xea\x0d\xdf\x07\xe5\x33\xf6\x93\x41\xcf\x2f\x19\x27\xbe\x37"
+  "\xc3\x38\x5d\x5a\x0f\xfc\x24\x64\xf0\xaf\xf2\xb5\xcc\x4a\x19\xf0"
+  "\xe5\xcb\xb2\x21\xaf\xf9\x12\x7b\x83\x11\x72\x90\x35\x35\x12\x8e"
+  "\x8a\xcf\x91\x95\x63\xf8\xe3\xe1\x39\xef\x6b\x60\xe9\xf8\x64\x6d"
+  "\x8c\xc1\xa7\x0a\x76\x4a\x91\x0e\xa3\xfe\x52\x30\x78\xcc\x15\xcf"
+  "\x32\x3f\x64\x35\x5f\x6a\xcf\x2f\xd1\x46\xd9\xaf\x5f\xc4\x5b\x59"
+  "\xd2\x5e\x62\x18\x97\xc6\x71\x66\x46\xd4\xda\x42\x9e\xdd\xf3\xd9"
+  "\xd6\xcc\xb0\x92\xfb\x99\x31\x7b\x84\x33\xb3\xa4\x3f\x95\x2e\xf7"
+  "\x4f\x87\x62\xe5\x60\x66\x81\x31\x47\xc7\xa4\xaf\x37\xe4\x1e\xeb"
+  "\x5a\x86\x1b\xb3\xcf\x3a\xb3\x4e\xc9\xc2\xcc\x90\x96\x14\xb9\x5e"
+  "\x9b\x29\xed\x3f\x63\xbf\x14\xf9\x75\x31\xf5\x62\xf6\xff\x66\x66"
+  "\x89\xc1\xf7\xe9\x53\x30\xbe\x01\x3e\xdb\x52\x31\x0a\x66\x8d\x8d"
+  "\xd9\xaf\xf0\x6f\x96\x77\xd0\xff\x0c\xb8\xb3\x74\xbd\x37\xbb\x36"
+  "\xba\xbd\x59\x59\xce\x53\x97\xea\xff\xac\x41\xfa\x3f\x6b\xa0\xff"
+  "\x8b\x25\xdc\x98\xbd\xc4\x59\xb2\xff\xe1\x8b\xf4\xdf\xac\x26\xe8"
+  "\x2f\x83\x6e\xb0\xb9\x67\x5f\x63\xd8\xea\xbc\x7f\x30\xb8\xad\x3e"
+  "\x6b\x60\xff\x4f\xd6\x9b\x35\xb0\xff\xe7\x8f\x67\xab\xfb\x48\x9e"
+  "\xad\x46\xb5\x3d\x7b\xa2\xb5\x2a\x5e\x5f\x66\x0f\xb2\xff\x37\x5b"
+  "\xdf\xff\x9b\xdd\x1c\xad\xcf\x66\xbb\xa2\xc7\x70\x56\xcc\x18\xce"
+  "\xae\x89\x1e\xc3\x59\x59\xff\xdd\x79\x0d\xef\x94\x98\x98\x68\x4a"
+  "\x4c\x30\x25\x24\x22\x1b\x5d\xa4\x61\x89\xe6\xc4\x21\xf8\x1b\xaa"
+  "\xff\x0e\x33\x25\x9a\xcc\xf8\x1b\xa2\xff\x0e\x8d\x79\x1f\xc6\x75"
+  "\xf1\x67\xd6\x7f\x87\xc4\xbc\x0f\xfd\x9a\xfc\x61\x7a\xbb\x46\xfb"
+  "\xe6\x98\xf7\x21\x5f\x93\x3f\xf4\xef\xac\x4f\x17\xbd\x47\xfb\xa1"
+  "\xcd\x58\xbc\x7c\x7e\xc1\xa2\x3c\x79\x5e\xbc\xc0\x3e\xff\xd9\x67"
+  "\x17\x2c\x5d\x6a\x2f\x7a\xd1\x7e\xff\x7d\x0f\xdf\x7e\xb7\x5d\x1d"
+  "\x3b\x17\x4c\xbe\x31\x2f\x99\x66\xae\x58\xc2\x19\x33\x1f\x99\x91"
+  "\x63\xcf\xbe\xff\xbe\xe8\x4c\x03\x8c\x3c\x5e\xbe\x14\x94\x08\xf9"
+  "\xcb\x2c\x1d\x49\xb4\x71\xa4\xd4\x3d\x1d\xec\xe7\xab\xf6\x3c\x1e"
+  "\xbb\xea\x10\xb8\x5f\xf4\x3a\x45\xf3\x0d\x7c\xa6\xff\xd0\x1f\xb8"
+  "\x13\xe3\x6a\x5c\x54\xb8\x90\xef\xaf\x3c\x74\x5c\xfc\xce\x4f\xf6"
+  "\x07\xc9\xd4\x4e\x4f\x5e\xdf\x32\x1d\x65\xf1\xee\xed\x08\x91\xdd"
+  "\x49\x96\x13\xf4\xe8\xa7\xc8\x4b\x10\xf7\x68\x48\x0b\xe8\xbe\xd0"
+  "\x73\xfe\x43\xa6\xfd\xce\x65\x94\xb3\x9e\xa0\x87\x37\x88\xdf\x09"
+  "\xf9\xce\xf7\x84\x54\xb9\x87\x1f\xd7\xdc\x0f\xd9\x58\x37\x54\xbd"
+  "\x46\xe6\x9d\xaf\x11\xbd\x35\x82\x2c\x6f\x8d\xe4\x58\x1d\x0f\x67"
+  "\x19\x67\xa1\xa5\x78\xf7\xd1\x93\x76\x6e\x9b\xcb\x6a\xa6\x87\xee"
+  "\x97\xe5\x47\x44\x95\x2f\x1e\x38\x8b\x7d\x38\xcb\x84\x72\xb3\xbf"
+  "\x20\x6b\x30\xb9\xde\xe5\x2d\x76\x91\x35\x2c\xbe\xba\x75\x3a\x25"
+  "\xb4\xc2\x12\x5e\x19\x12\xa1\xe6\x25\x27\xb9\xfd\x3f\x5a\x57\x8a"
+  "\xaf\xbc\xd0\xd6\x33\xbb\x9c\x62\xf3\x29\x32\x43\xae\x13\x9a\x97"
+  "\xb0\x9f\xc2\xc3\x0d\x3b\x2f\x90\x19\x34\x18\x7d\x92\x1e\xf1\x15"
+  "\xcf\x14\x61\xe7\x4c\x32\xff\x9b\x83\x7d\x0e\x1b\xaf\xdd\xfc\x27"
+  "\x32\xff\xaa\xd7\x65\xea\x15\x36\x2a\x2e\x12\x9d\x82\x63\xf8\x04"
+  "\x44\x90\xfd\xfc\x0f\xcd\x0b\x73\x99\xe1\x3d\x4e\x1b\xb5\x16\x05"
+  "\x68\xcd\x31\x11\xf4\xfc\x49\xdd\x0f\x38\xdc\x15\x60\x1f\x46\xcb"
+  "\x9a\x99\x94\x78\x22\x87\x4c\x87\xf3\x2b\xc9\x3b\x37\x40\xc5\xc7"
+  "\x44\xe7\xa1\x79\x5f\x50\x6b\x7e\x03\xe5\xb6\x91\xe9\x50\xc7\xe7"
+  "\x24\xe3\xd0\x94\x7d\x59\x53\x72\x8e\x6c\x6b\x16\x71\xda\x39\x5a"
+  "\xb5\x86\xae\x5c\xf5\x19\x59\xbd\x9d\x6d\x68\xe7\x14\x3d\x71\x94"
+  "\x12\x00\xcf\xb4\xfa\x73\xb2\xad\x7e\x9c\x7d\x7d\x33\xa9\xaa\x84"
+  "\x6c\xc2\x99\x9e\xd2\xeb\x4c\x4f\xed\x15\xe9\x23\x7a\x9c\xe9\x69"
+  "\xad\x85\x28\xdf\xb1\x9f\x86\xb7\x51\xda\xef\x4e\xb6\x99\x2a\xcf"
+  "\xd2\x68\xfb\x2c\x1e\xff\x47\x8e\x55\x9d\x45\xf9\xb2\xfd\xd9\x1a"
+  "\xea\x46\xd6\x09\x25\xed\xcf\xf7\xe6\x04\x49\x03\xac\xca\x5e\x1a"
+  "\x5d\xd5\x4b\x36\xad\x74\x7f\x36\xd3\xa2\xaf\xac\xc1\x05\x5d\x38"
+  "\xec\xbd\x67\xf6\x9a\xbd\x87\xba\xe8\x70\xa0\x97\x5a\xe9\xcf\xe4"
+  "\x75\x7c\xd9\xfc\xab\x67\xf6\x0e\xd1\xc0\xfc\xcd\xab\x3a\x00\x5f"
+  "\xf1\x8c\xf3\x30\xdf\x57\x76\xd1\x96\x12\x4a\x29\x5c\x45\xc3\x4e"
+  "\x22\x5d\xad\xe9\x77\x79\xbc\xa1\x2f\x9b\x57\x49\x3f\xdc\x27\xed"
+  "\x25\x87\x29\xb1\x35\x50\xc9\xfe\x9e\xa6\x70\xf2\x97\x35\xde\xc0"
+  "\x11\xf2\x16\xfe\xa5\x59\xb3\x7c\xe9\xd9\xa8\x91\xe5\xd7\xe7\x8f"
+  "\x98\xbc\xe6\xf3\xe4\xcd\x09\xd0\x27\x68\x5b\x94\x7d\xc9\x7b\x0f"
+  "\x99\xad\x81\x20\xdf\x73\xca\x10\xdd\xb6\xe4\x2d\x4b\x68\xec\xce"
+  "\xb3\x34\x66\xc7\x59\x4a\x17\x3d\xe9\x26\xf6\xad\xe5\xfb\xa9\x3b"
+  "\xf0\x9b\xd2\x41\x16\xf4\x57\xf9\x61\x27\xe9\x3e\xb6\x7d\xe9\x54"
+  "\xdd\x3b\xe0\x63\xdb\xdb\x3d\xe0\x63\x0b\x5e\xca\x66\x3f\xdb\x76"
+  "\x7a\xd8\xc2\xfc\xbc\xe5\x34\x99\xd7\x9d\x26\xba\xd5\x65\x22\xfb"
+  "\x33\x7c\xaf\xe2\xd1\x0f\xbc\x79\xa7\xe4\x73\x3b\x3d\x5a\x80\xdf"
+  "\x14\xfc\x25\x20\x5d\xee\x67\x77\xe8\x7c\x8b\x34\x13\xd2\x1e\xc5"
+  "\x6f\x22\x7e\x67\x3a\xab\x84\x1f\x6d\xb4\x75\x9b\x28\x99\xf9\x57"
+  "\xf7\xe7\x6d\xeb\x71\x3f\x0a\xfb\xe7\xb9\x02\x83\x8f\x95\x4e\x7f"
+  "\x38\xfb\x93\x13\xa7\x38\x2e\x94\x5f\xe2\xd3\x97\x9f\xc0\x31\xa2"
+  "\xf4\x74\xc6\xe1\xd7\xdc\x2e\xda\x2f\xc7\xaf\x15\x7f\x2c\x97\x63"
+  "\x8c\xba\xdd\x7d\xf9\xdc\xe6\x3b\x48\x17\x46\x3a\xfa\x6b\xe6\xbc"
+  "\xdf\x9c\x38\x65\x52\x65\xd2\x4d\x80\x19\xd4\xe1\x43\xd6\x1f\x0a"
+  "\xb0\x4c\x77\x9b\xac\xe2\x40\xde\x04\xaa\x1a\x29\x8e\xec\xd8\x2a"
+  "\x5a\x94\xac\x3d\x8a\xb6\x9f\x37\xe2\xe8\xb4\x6c\x44\xde\x01\xac"
+  "\x62\x99\x2e\x2d\xf3\xd8\x7f\xec\x31\x8e\x1b\x35\x26\xb2\x0f\xc2"
+  "\x3d\x9b\xef\xf7\x5a\xdf\x2d\x69\x1e\x22\x4c\xd9\xc1\x56\x5f\x17"
+  "\xfd\xaa\xb7\x73\x88\xf3\x8f\x64\xf2\x86\xda\x69\x7c\x1a\xd9\xd8"
+  "\xfe\xab\xde\x2a\x7c\xf8\xed\x64\x7f\x4e\xf0\xc9\x77\x4f\xd2\x63"
+  "\x8f\xfe\x53\x1a\xa5\xfd\xbb\x83\x74\x7d\xf4\xd8\x0b\x03\xfa\xe8"
+  "\x89\x73\x87\x3b\xf6\x46\xe8\xa2\x27\xde\xb9\x58\x17\x3d\x5e\xab"
+  "\x74\x91\x08\x29\xdd\x13\xf6\xe9\xe9\x9b\x62\xd2\x75\xbf\x90\xc7"
+  "\x5f\x8a\x49\x0f\xea\xe9\x4f\xc5\xa4\xfb\x55\x7a\xce\x0e\x43\xd7"
+  "\xb5\x32\x1e\x2b\x58\xd7\xe5\xac\x65\x5d\xd7\x9a\xa7\xeb\x3a\xe9"
+  "\x63\x98\xb3\x40\xbc\xed\x22\xbe\xb3\x84\xe7\xc9\x8c\xbf\xf8\x1d"
+  "\x19\xb8\x27\x9d\xa0\x9f\x86\x39\xad\xfc\xcf\x64\xc6\x9f\xd4\x73"
+  "\xc2\xfd\x50\x2e\xeb\x39\xd6\x71\xec\x77\xb2\x7d\xa4\x68\xdb\xbe"
+  "\x55\x1c\xad\xda\x2a\x0e\xf5\xb8\x7f\x5a\x60\xe8\xbb\x57\x90\xb6"
+  "\x11\x69\xaf\x20\x9f\xf5\x1e\xd3\xe4\x70\xce\x5e\x8e\xe3\xd0\x01"
+  "\x1e\x1b\x6d\x4d\xa0\xc2\xcd\xe0\x79\xbe\x5f\xb8\x1e\xf4\xf5\x16"
+  "\xf1\xbd\xd5\x30\xc9\x78\x4a\xa6\x0c\xe8\xa8\x0e\x96\xb7\x91\xeb"
+  "\x20\x5f\x5e\xc7\x17\x54\x12\x10\x27\xf9\x9e\x1d\xe3\x90\xbb\xf2"
+  "\x41\x8e\x11\x94\xd0\x02\xeb\x82\xfd\xc0\xd9\x5f\x05\x7a\xd7\x5c"
+  "\x0e\x9c\x54\x8c\x94\x9f\x62\xfd\x5f\xad\xdf\x63\x7a\xd2\xce\xf1"
+  "\xc7\xda\xe9\xa7\x13\xb1\xbe\x0b\x72\xdf\xac\x61\x17\xf1\xbd\x17"
+  "\xc8\x28\xaf\xf1\xf2\xb7\xe3\xaf\xdc\xb8\xfb\xc2\xb1\xe8\x50\xc6"
+  "\xdb\x16\x24\xc6\xd9\x47\x3f\x5d\x7f\xb8\x78\x2f\xd7\x4f\x67\xda"
+  "\x08\xb7\xd3\x80\x91\x20\xef\xce\xb8\xc9\xc2\x77\x67\x7c\x94\x23"
+  "\x63\x08\x8a\xe4\x06\xd7\xe1\xb9\x7e\x62\x3d\xef\xed\x04\x8c\xe2"
+  "\x76\x05\x03\xb0\x04\xf4\x7e\x54\x9e\x0e\xff\xca\x35\xe2\xab\x76"
+  "\x7a\x2c\xc0\xe3\xc5\xf7\x20\xf9\x7c\x0d\x74\x49\x61\xdf\x78\x65"
+  "\x7b\xfe\x74\x4d\xf5\x9f\x89\xf4\xbb\x9c\xe0\xb7\x9f\x16\xf3\x3d"
+  "\x25\xbe\xbf\x29\xef\x6e\x9a\x26\x90\x58\x91\x9e\xd2\x7f\x7f\xf3"
+  "\xff\xc0\xdd\x4d\xd0\xdf\xb6\xd3\x24\x1a\x80\x7f\x31\xdf\xdf\x04"
+  "\xfe\xc7\x98\x0f\xf5\x3e\xb9\xde\x78\x82\x69\xfe\x58\x0b\xa7\x61"
+  "\xad\x78\xd0\x18\x7f\xee\x2f\xf7\x05\x79\xf5\xca\x26\x14\x47\x7c"
+  "\xf4\xb8\x8b\xf3\x91\x56\xc1\xe5\xc7\x43\x8f\x79\xf3\xc2\xf4\xde"
+  "\x89\xb0\x69\xcb\x2a\x32\x2b\x9d\xf6\xc4\x5b\x5c\x5f\xe9\xb4\x27"
+  "\xb2\x07\x74\xda\x13\xd3\x94\x4e\x53\x34\x56\x3a\xed\x89\xbb\x94"
+  "\x4e\x7b\xe2\x36\x79\x0e\x06\x9d\xc6\x79\xac\xd7\x0c\x9d\xb6\x63"
+  "\xa4\x38\xc8\xba\xa3\xc7\xfd\x84\xdd\xd0\x6d\x9b\x90\xc6\xba\x83"
+  "\x71\x54\x7a\x2a\xc7\x21\xfe\xdf\x74\x52\x7e\x06\xfc\x9c\xcf\xf7"
+  "\x15\x3a\xf5\x67\x8c\xcb\x13\xaf\x2a\x1d\xf7\x44\xd1\x80\x8e\x7b"
+  "\x3c\x38\x50\x97\x75\xdc\x13\xa5\x4a\xc7\xa9\xf4\xea\x27\x58\xc7"
+  "\xe5\x38\x98\x06\x3a\x7c\x13\xef\xd9\xe9\xe5\x99\x8e\xae\x48\x1d"
+  "\x17\x2d\x5f\x4f\x1c\x32\x74\x1c\xeb\x36\xbc\xc3\x06\x49\x3e\x28"
+  "\xe5\x0d\xe5\x2a\x40\x73\x43\xee\x78\x0c\xb8\xcf\x1c\x67\x8c\xe9"
+  "\x36\xe5\x14\x0d\xd3\xef\x0a\xe9\xfd\x7e\xd2\x66\xf8\x3a\xfa\xe8"
+  "\x09\x7b\x3c\xbb\xd9\xb0\xd3\xc0\x8f\xd7\x85\x39\x4e\x87\x0b\x73"
+  "\x69\xa5\x70\xb5\x86\x8e\xd2\xd3\x45\x64\xd2\x12\x9f\x3f\xce\x63"
+  "\x8b\x75\xc6\x50\xfe\x65\xdd\x83\x39\xf4\xa9\xdc\x00\x0d\xc5\xda"
+  "\xfc\xf8\x16\x13\xf2\x1c\xf4\xa3\x88\xbc\x95\xdc\x4e\x44\xbd\x71"
+  "\x11\x79\x32\x1e\xe5\xb8\xd3\x1c\x63\xee\xc9\xcc\xc1\xd6\xfe\x97"
+  "\x89\xcb\xdf\x06\xc7\x65\xee\x90\xc1\x71\x99\x2b\xed\x80\x71\x5d"
+  "\x94\x80\xb5\xd9\x55\xa7\xe9\x49\xb9\x1f\x23\xe3\xde\xac\x8b\xd7"
+  "\xce\xdc\x87\xf4\xfc\x21\x11\xf9\x91\x6d\xbd\x14\xa7\x7e\x64\x7b"
+  "\xaf\x7e\x0d\xfc\xc6\xaf\x81\xff\x1f\x5f\x03\xff\x2b\xd6\x81\xa0"
+  "\x9d\x55\x33\x45\x97\xbb\x35\x24\x65\xf0\x20\xdf\xd7\x3b\x49\x4f"
+  "\x7d\x5b\xdf\xf3\x39\xee\xbc\x5e\xae\x05\xe5\xbd\xad\xcd\xc8\xe7"
+  "\x7b\xf9\xac\x9f\xa7\x62\x04\xd5\x19\x75\x7f\x9d\x99\xb1\xb8\x0d"
+  "\x0f\x19\xb8\xc9\xfc\x17\x62\x71\x43\xfe\xb8\x88\xfc\x4d\x03\xe3"
+  "\xfe\xd4\x25\xfd\xeb\xbd\x95\x24\x63\x70\x1e\xc0\xf2\x05\x73\x32"
+  "\xc7\xfd\xd3\xf7\x67\x9e\xea\x80\x9e\xcf\x88\xf0\xdb\xed\x82\x6e"
+  "\xbf\x8e\xe3\x2f\xb0\xed\xbb\x45\xad\x87\xbf\x85\xf9\x64\x04\xdf"
+  "\xd7\xe1\xbb\x3b\xb9\xe1\x6c\xd3\x81\x62\x96\xa1\xa7\xed\x46\xdd"
+  "\xc1\xf6\x81\xb8\x5d\xbd\x4d\xf6\x81\x0d\xa0\xce\x1c\xa3\x0e\xc3"
+  "\x66\x3f\x4a\xcc\x03\xd7\xc9\x3b\xaf\xa1\x2e\xd6\xbb\xdf\x82\x9d"
+  "\x3c\x42\xb5\x33\x8f\xf4\x76\x3c\xa8\x33\xe8\x5d\xf5\x4b\xf7\xef"
+  "\xe9\x96\xcb\xef\x1f\xe9\xfd\xcb\xa5\xaf\xe9\xdf\x25\xda\xcd\x9d"
+  "\x74\xf9\xed\xa6\x1a\xed\x3a\x2e\x9f\xae\xb9\xbb\xbf\x39\x5d\x33"
+  "\x74\xba\xe6\xfa\xbe\x86\xae\x71\xda\x99\x97\xf6\xcd\xdb\xb1\xeb"
+  "\xed\xcc\x9b\x1e\xaf\x1d\x92\xff\x06\xbd\xd7\x65\x31\x62\x60\x72"
+  "\x3c\x58\x15\xef\x6e\x5e\x79\x64\xac\x5f\x15\x27\x76\x5e\x9d\x11"
+  "\xeb\x57\x8f\x45\x8b\xb9\x65\xde\xa7\xb9\x35\x6c\x8f\x08\xcd\x47"
+  "\xf3\x5a\x38\xbe\xea\xd4\x35\xea\xce\xb8\x5e\xa7\xed\x52\x31\x86"
+  "\x39\xce\x96\x10\x39\x74\xa0\x52\xfa\x03\x60\x1e\x9a\x7f\x15\xdf"
+  "\x0f\x50\xe7\x99\xf3\x47\x2b\x99\x9c\x3f\x1a\xb0\xf3\x07\x87\xd1"
+  "\x94\x59\x57\x92\x31\x64\x30\x9f\x7f\xd4\x9f\xeb\xa3\x17\xe6\x70"
+  "\xfd\x70\xd9\xc7\xd9\xe2\x8c\x4d\x8f\xf3\xf7\xec\xbe\x88\x38\x84"
+  "\x98\xbb\x9f\xf9\x9b\x7e\x37\x01\x34\x70\x81\x96\xf3\x2b\x0c\x1a"
+  "\x18\xe9\x48\xab\x37\x68\x00\x7b\x25\xc5\x5b\x13\xe2\xbb\x43\x01"
+  "\x75\x4f\x7c\xfe\x61\x51\xda\x94\xa1\x60\x3f\xa3\xce\x19\x92\x3f"
+  "\xce\x0e\xac\xb6\x99\x8c\xfa\x63\xec\xce\x0b\xcc\xc3\xfe\xa4\xa6"
+  "\x0c\xc0\x0a\x18\xf0\x05\xe3\x25\x06\xca\x55\x4b\xbf\xa4\x67\x30"
+  "\xfe\xb9\x2a\xbe\x23\xda\x90\xb8\x9b\x28\x51\x03\xfe\xe8\x83\xc9"
+  "\x5b\x18\x60\x3b\xb5\x2b\x8c\xfe\xb3\xae\xdb\xb3\xd8\x67\xe6\x32"
+  "\xd2\x76\x38\x93\x6e\x52\x31\x14\x9f\x79\x41\x3b\xc3\x31\x71\x24"
+  "\x5e\x29\xe8\xf3\x5e\xc6\xc9\x87\x5f\xff\xea\x74\x9a\x7d\x8e\x74"
+  "\x5a\x3c\xf3\xa8\x86\x74\x6d\xe9\x00\x0e\x3b\xe5\x1d\x8f\x67\x2a"
+  "\x0d\x1c\x34\x6e\xbf\xc7\x66\x82\x2d\xc6\xed\x76\xca\xbb\x96\x68"
+  "\x7b\x3c\xc7\xb4\xe3\xd8\x18\x2b\xd2\x89\x71\x40\x9d\x43\x06\xbd"
+  "\xf5\x3a\x46\x1b\xc5\x9a\x6c\x5b\xd1\x46\xd1\xf9\x00\xec\xc1\x67"
+  "\x42\x17\xd3\xf9\xd9\xd4\x08\x3a\x27\x32\x5f\xf1\x1e\x0b\xf0\xff"
+  "\x35\xd3\x9b\xcf\x35\xec\xcb\xd9\xae\x7a\xf6\xbe\x03\x01\xe9\x77"
+  "\x92\xc2\x70\x35\xd0\x9f\x61\x00\xee\x15\x8a\xc6\xcf\xe6\xf4\xd3"
+  "\x18\x6d\x0b\x8c\xc5\x3a\x75\x27\x85\x7d\xdf\xa1\x3b\x9e\x75\xf4"
+  "\xb7\xc3\xb8\x3a\x6d\x26\x4d\xd8\x38\x66\xa6\x9f\x71\x2d\xb2\x8b"
+  "\x20\xdb\x95\xd2\x8f\x09\x7d\xdd\x53\xd2\x66\x86\x6d\x69\x92\x6d"
+  "\x75\xa7\xb3\x7d\x6f\x91\xcf\x68\x6b\x10\xfe\x7e\x95\xe3\x52\x1a"
+  "\xfd\x42\x5f\x2c\xcc\x5b\xc0\x1d\xf6\x5f\xde\x7e\xc9\x2f\xcb\x79"
+  "\x9c\xf2\x6a\x39\xcd\x28\x87\xf7\x65\x5c\xce\x78\x47\x1e\xf8\x2b"
+  "\xef\x4e\xf4\x2b\x99\xf1\xf4\x3b\x65\xec\x17\xf4\x39\xaf\x8d\x61"
+  "\xf4\xb8\xf3\x32\xa3\xfa\xd9\x97\x63\x36\xf8\x8e\xcf\x88\x5a\xec"
+  "\x41\xa9\x3b\x15\x6d\xf3\x0a\x0c\x99\xe4\xfa\x4a\xc6\xf2\x5c\x91"
+  "\xbc\x18\x70\x0e\xf0\x41\xd1\xf5\x64\x31\xdb\x39\x96\x66\xde\x3c"
+  "\x15\x07\x3c\x6f\x77\xec\x78\x71\x1e\xc7\x9d\xd4\x69\xc8\xf2\x94"
+  "\xda\x4e\x79\x35\xdc\x37\xf0\x5a\xe0\x52\xf3\x25\xc7\x84\xe4\x58"
+  "\x9e\xaf\x2b\x39\x02\x5d\x16\x7e\xfb\x75\x75\xbf\x27\xa0\xe2\x2b"
+  "\x2e\xf8\xae\x30\xd5\xca\xf1\x62\xbf\x3c\x19\x47\x43\xde\xfd\x5e"
+  "\xc0\x3e\x6e\x62\x78\x61\xad\xbc\x67\xa6\xfb\xec\xf9\x5b\x0a\x43"
+  "\x32\x0e\x9f\xb3\x88\xef\xc2\x86\x78\x4d\x26\x7d\xd2\x0e\x14\x85"
+  "\xe8\x91\x20\xd3\x76\x41\x01\xdf\x71\x0f\x48\x5a\x2c\x70\x18\xf7"
+  "\xda\x39\xce\x24\xc7\x29\x1d\x1f\xa2\x44\xb6\x29\xec\x4e\x8e\x49"
+  "\xb0\x30\x9b\x6d\x12\x45\x53\xf0\xbd\x49\x1c\x51\xbc\xbc\xe0\x53"
+  "\xbe\xc7\xae\xce\x97\xda\xc1\xdf\x89\x5f\xb6\xd3\x82\xff\x54\xfb"
+  "\x32\x86\xac\x2d\x7c\x88\xcf\x98\x7c\x3a\x0c\xb4\x85\xf9\x7f\xfe"
+  "\xd4\x8b\xe5\x62\xc1\xa7\xc6\x1a\x83\xef\xc5\xa9\xf3\xaa\x01\x78"
+  "\x3e\x5a\x20\xf7\xa5\x07\x74\xd3\xef\x01\x6b\x61\xc6\xc5\x32\xb3"
+  "\x70\xaa\xc1\xcb\x85\x37\xf0\xdd\xea\x05\x16\x6e\x7f\x30\x9d\x29"
+  "\x9c\x8f\xf3\x38\x59\x4e\xd8\x29\xf1\xeb\xee\x4b\x0c\x9c\x7f\x2d"
+  "\xac\x37\xfa\x60\xd0\x44\xf5\xe1\x67\x09\xdd\xc9\x0d\xf5\x03\x7d"
+  "\xff\x99\xf2\x37\x1b\xc8\xbf\x2b\x82\x36\xfc\x3e\x51\xf1\xdd\x42"
+  "\xac\x29\x9e\x6d\x51\xbc\xa8\xd2\x44\x72\xd3\x1d\x1c\x03\x56\xe1"
+  "\xb8\x88\x0c\x7e\xef\x71\xff\x6c\x8c\x8f\xce\x1c\x52\xe7\x50\x3f"
+  "\x43\xff\x17\xba\x54\xbd\x85\x87\x18\x97\xb8\xfd\x8c\xc6\xb1\x81"
+  "\xe7\x58\x15\xeb\xe0\x67\x8d\x8c\xaf\xfd\x26\x1e\xe3\x9f\xad\xe1"
+  "\x76\x65\xdc\x83\xbe\xfc\x21\x81\xbe\x74\xea\xee\xcb\x87\xfc\xa4"
+  "\x9b\xd0\x0e\xf4\xdf\xe9\x7a\xbd\xcd\x3a\x03\x57\xc6\x0d\xb6\xa2"
+  "\xa5\x47\x2c\x8a\x4f\x5f\x6e\x57\xc6\x63\xca\x1f\x86\x3f\x0b\xfe"
+  "\x86\x7e\xd3\xf9\x18\x76\x6d\xa7\xbf\xf4\x23\x9b\xb6\x5c\x1c\xe4"
+  "\xf8\x5f\x58\x17\x74\x6e\x01\xff\x0e\x5f\xdb\x4c\xc3\x03\x4f\x99"
+  "\x72\x57\x52\x26\xd6\xb6\x24\xce\x8b\x89\x3b\x35\xfc\x2e\x17\x13"
+  "\x38\xee\x35\xde\x33\xf4\xf7\xb1\xfc\xde\xbd\x5c\xcc\xed\x71\xe7"
+  "\xe7\x18\x67\x77\x2a\x66\x4d\x7e\x7e\x7f\x9c\x9f\xc4\x27\xf9\x9e"
+  "\x0f\xc7\x84\xd2\x44\xe2\xf3\x9d\xdc\x6e\x2e\xcf\x1d\x68\x0f\xe5"
+  "\x30\xff\xcf\x93\x31\x72\xfc\x89\xb7\x8c\xc0\x5f\xfc\x38\x1b\xa8"
+  "\xc3\x78\x75\x27\x7d\x64\x33\x70\x1d\x1e\xc8\x34\x7d\x43\xdc\x02"
+  "\x06\x6e\x48\x3f\xb8\x45\xa5\x87\x38\x46\x21\xfb\x20\xf6\xb8\x17"
+  "\xa5\x19\xb8\x1a\x38\x70\x7b\x7c\xaf\x52\x24\x37\xec\xe5\x98\x30"
+  "\xdc\x9e\x7f\x75\x3e\x97\xcd\x34\xf0\xfd\xa6\xbc\x5c\x52\x25\x04"
+  "\xcf\x2d\x7c\x9e\x64\x1f\x45\xd4\x1a\x60\x9d\xb2\xa8\xe2\x40\x55"
+  "\x80\xe3\x7f\x7e\x8c\x36\xf6\x75\x8b\x7c\xd2\xfa\xf2\xe3\x8e\x31"
+  "\xd7\x41\xf9\x23\x52\x3f\x94\x35\xec\xd3\xc4\x74\x8e\x01\xfc\x31"
+  "\xc7\x5d\x85\xad\x09\xb9\x5d\x14\x6a\x29\xee\xe4\xbb\x90\xd0\x39"
+  "\x8b\x38\x4e\xe8\x5e\xb6\x35\xb0\x4e\xe1\xf8\x15\x89\xac\x9b\x9a"
+  "\x97\x4f\x60\x18\x61\xb3\x83\xcc\x2d\x8e\x6f\x16\x4f\xdf\x47\xcf"
+  "\x4d\x50\xb2\xf3\xdc\x04\x63\x9e\xc5\x73\x66\xf4\xb9\xf4\x73\xe9"
+  "\xb1\x3a\xf7\x99\x17\x5f\x2c\xca\x5d\xb2\x80\x7f\xd2\x6f\x5c\x76"
+  "\x73\x72\xe4\xda\x99\xf5\xb0\x8a\x63\xf0\x5c\x0e\xef\x53\xbd\x3e"
+  "\xc2\x38\x67\x7d\xae\xd2\xd8\x2b\xd3\xfd\xb9\xef\x65\x9b\x9a\x6d"
+  "\x4f\xe4\xed\xf9\xb4\x98\x45\x87\x12\x8e\x5b\xc8\x14\xdb\xde\xc2"
+  "\xf9\x45\xf3\x0b\xee\xe6\x13\x95\xe4\x78\xed\x1c\x8c\x6e\xe7\x79"
+  "\xea\x6f\x47\xe9\xc1\x80\x89\xcb\x95\xf6\x66\x8a\xa4\x76\x9f\xba"
+  "\x4b\xfb\xfc\x18\x63\x0f\x64\x10\x3f\xb8\x60\xb8\x6c\x7f\x39\x8f"
+  "\x8b\x73\x0d\x99\x7e\xb3\xaa\xcd\xc4\x36\x4a\x09\x9e\x79\x6d\x28"
+  "\xed\x22\x3d\x9e\xd0\xef\xce\xb6\x61\x9e\x79\xde\x21\x4a\x1b\xa0"
+  "\x7f\x9e\x2f\x1c\x6c\x7e\x8a\xf4\x21\x60\x9f\xb3\x0e\x7a\xbe\x7c"
+  "\xd0\xf3\x7e\xcf\xc7\xf3\x94\x9e\x79\xfe\x8b\x16\x1b\xf1\xb8\xbf"
+  "\xdc\x4e\xcf\x1f\x37\xdb\x30\x97\x8c\xa2\x5f\xe0\xf9\x0b\xae\xcb"
+  "\x79\x51\xe3\xfc\xdd\x53\x35\x66\x70\x21\xb8\x31\x41\xa8\x7f\x64"
+  "\xd6\x1f\x12\xf1\x67\x12\x09\xf2\x34\x2c\x11\x14\x1e\x36\xd4\x4c"
+  "\xd6\xe1\x29\x96\xeb\xae\x1d\x6d\xbb\xf7\x9e\x49\x13\x9d\x25\xc5"
+  "\x90\xde\x50\xd0\x2a\x22\xe3\x5f\xb5\x7b\x1e\xbd\xd9\x45\xd2\x1f"
+  "\xa2\xb4\xdd\x13\x0f\xd7\x4d\x6e\x51\xc8\x77\x8f\xb5\xe4\x0b\x0d"
+  "\xce\x65\x64\x7a\xaf\xd7\x67\xe2\x18\xec\x6c\x83\x70\x8c\xfe\x76"
+  "\x2a\x78\xe9\x13\xa4\xa1\xff\x0e\xe1\xb9\xd0\xa0\xce\x3b\x0b\x1a"
+  "\xb5\xb2\x0b\x0d\x03\xf0\xcd\xc4\xf0\x9d\x6f\x91\xa9\xae\xa4\xd3"
+  "\xe4\x35\xdf\x43\x5e\x7b\x80\x3e\xc1\x73\x5c\x5a\xa2\x4d\xc1\x71"
+  "\x5f\x01\xa3\xda\xad\x79\x9c\x17\xc8\xa4\xdf\x1f\x34\x9d\xa6\x82"
+  "\xbf\x35\x0c\x52\x8f\xef\xeb\x76\x27\x7f\xf8\x5f\x3d\xee\x17\x30"
+  "\xfe\x99\x75\xfa\x9c\x07\xdd\xfc\x02\xf8\xff\x79\x39\xdf\x21\xff"
+  "\xf3\x6e\x19\xf3\xf7\x85\xe9\x46\x99\xf8\xf3\x1e\xef\xa9\x8a\x66"
+  "\x1e\x57\x71\xfe\x6f\x9d\x7c\x37\x61\x10\x3f\x86\x61\x5e\xc7\xed"
+  "\x7c\x8e\x34\x64\x78\x90\x52\x9c\xe7\x44\x5f\xd8\x4d\x69\x60\x77"
+  "\x53\x18\x6b\xcb\xd0\x79\x91\x73\xb8\xeb\xac\x8c\x4d\xc9\xfa\xe3"
+  "\xdd\x85\xbf\x37\x79\x83\x67\x9a\xbd\xeb\x35\x6a\x85\xfd\xe1\xad"
+  "\x3a\xd3\xac\x62\x58\x86\xe9\x30\xfd\x99\x0e\x3b\xfe\x1f\x97\xdc"
+  "\x0b\xaa\x12\x2e\xa6\x73\xdf\x79\x31\xc7\x6b\xfe\xbf\x89\xbf\x21"
+  "\xc2\xba\x10\x74\xb7\x9f\xa6\xc5\x57\xfd\x0e\x70\xde\xfb\x2f\xc0"
+  "\x92\x31\xaf\x26\xd3\x27\x78\xee\x71\x2f\x1e\x6d\xe8\xc9\xb8\xb1"
+  "\x42\x12\x9a\x37\x59\x1d\x4f\x99\x34\xe8\x5c\x8e\x4d\x06\x5d\x3b"
+  "\x81\xfb\x85\xf7\x0c\x7e\xc7\xef\x58\xfe\xb5\xae\x6d\xde\x61\x0d"
+  "\x3d\xc5\x3a\x38\x87\xf5\x2b\xd2\xe7\x54\x9f\x97\x3a\x39\x5b\x7f"
+  "\xcf\xd2\xdf\xa7\xeb\xef\x53\xf5\xf7\x4c\xfd\x7d\x12\xbf\x2b\xdd"
+  "\xbd\xb8\xa1\x7f\x5e\x31\x0d\x3b\x82\xf7\x66\x63\x2c\x80\xcf\x95"
+  "\x56\xc7\x1a\x39\x07\xe8\x78\x4c\xd0\xf1\xca\xd0\xdf\x0d\x7c\xbe"
+  "\x6b\x0d\xad\xf9\x1f\xc2\xe7\xc5\xcc\x68\x7c\x5e\xcc\x8e\xc0\x87"
+  "\xac\x8e\xcc\x6f\x82\x4f\xaa\x95\x63\xdd\xff\x1d\xf8\x30\x2e\x9c"
+  "\x86\xf6\x8f\xc4\xe0\xe3\x33\xf0\x89\xcb\x6f\xcb\x45\x27\xcf\x7f"
+  "\x4b\xbf\x2d\x63\xf4\x0e\xe3\xb9\xad\xba\xd7\x88\x33\x57\x38\xfa"
+  "\x52\x71\xe6\x20\x0b\x36\x94\x41\xff\x5f\xec\xd2\xe7\xf9\x26\x65"
+  "\x0f\x16\xce\x31\x7c\x7f\xd0\xd7\xfa\x2d\xaa\xaf\xbb\xd7\x73\xac"
+  "\xb5\x95\xf4\x1d\xa7\x43\x74\x62\x7d\xf3\xd7\x16\xbb\x3f\x4a\x06"
+  "\x0a\x8a\x96\x2e\x7d\xe1\x6e\x7b\xc1\xfc\xc5\x0b\xec\x37\xe6\xd9"
+  "\x97\xe6\x2f\x5a\x58\xb4\x20\xfa\x3c\x3c\x55\xff\xee\x88\xf4\xf3"
+  "\x67\x9b\x9b\x65\x80\xf9\x9f\xf5\xb6\xf2\xcd\x7c\xe9\x1a\xe1\x2e"
+  "\x74\xb1\xae\xdf\xf9\x1a\x99\xf9\x0c\x06\xf8\x74\x18\x3a\x5e\xc5"
+  "\xd6\xa7\x04\xd6\xf1\x48\x87\x0d\xf7\x42\x71\x44\x3a\xca\xbe\x94"
+  "\x6a\xa4\x31\x7c\x5d\x37\x0d\x6b\xa7\xc2\x46\x6e\x33\x2e\x0d\xcf"
+  "\x8b\x1a\xcc\xaf\x09\x58\x6f\xf1\xda\x57\x70\xdc\x24\xbe\x3f\x87"
+  "\x7a\x02\xf8\xc8\x33\x45\xfe\xb6\x8d\xb2\xed\x05\xe3\xb8\x0c\x75"
+  "\xea\x90\x66\xde\x8c\xb2\x58\x2f\x74\x72\x3d\xa4\x6f\xe2\x38\x06"
+  "\x48\xb7\xe8\xf1\xa0\x38\xad\x96\xe3\x0c\x20\x2d\x35\x22\xed\x03"
+  "\x8e\x61\x8e\x34\xbb\x0e\xef\x0f\x4c\x67\xbc\x67\xea\x7b\x0a\x5c"
+  "\xe6\x3f\xf5\x76\xa3\x62\x12\xf0\x47\x28\x6e\xbf\x35\xc3\x3e\xe7"
+  "\x91\x1f\x4c\xbe\xe7\xd9\x17\x17\x2f\x4c\x26\x49\xf6\x74\x4c\x97"
+  "\x19\xb7\x3b\x6e\xbe\xdb\x5e\xb8\x60\xc1\x12\xfb\x8a\x05\x8b\x8b"
+  "\xec\xf3\x57\xcc\x5f\x99\x4c\x0b\x5f\x5c\xf2\x2c\xdf\x92\xe7\x61"
+  "\x59\x9a\xfb\xec\xc2\x9f\xb1\xd3\x82\x2a\x9d\x1c\x35\x8f\xcf\x61"
+  "\xdd\xa6\xc7\x95\x38\xb8\x85\x6d\x8d\xa4\xdf\xa6\xe3\x99\xe3\x2d"
+  "\xd9\xf0\xdb\x82\xbf\x26\xfc\xed\xc5\xdf\x51\xfc\x1d\x39\x49\x2b"
+  "\xf8\xdb\x01\x7b\x7a\xdc\x4b\xd6\x1b\xf6\xc4\x00\x0f\x2d\xa9\x34"
+  "\x78\x08\xf3\xff\x1e\x35\xbf\x2d\x39\xd8\x1a\x92\xf2\xd3\xcf\x53"
+  "\x5b\xce\x0f\xf0\x14\xc7\x8b\x6c\x65\x9f\x9c\xe5\xc8\x07\x0f\xf3"
+  "\x3a\x1d\x34\x4f\x62\xba\x9d\xa0\x65\xfb\xab\xb7\x8a\x43\x1c\xeb"
+  "\x04\xbf\x2d\xe0\x97\x43\x2a\xbe\xc8\xd2\xa9\x28\x77\x3d\xda\x68"
+  "\x52\x6d\xe8\xef\x23\xc5\x41\xde\xc7\x68\xd7\xdf\xd5\x9a\x7f\xd9"
+  "\xa3\xfc\xcc\xbf\xfa\x59\x98\x95\xfd\x1b\xd5\xda\xd1\xc8\x5b\x7a"
+  "\x4a\x6f\xa3\x19\xb4\x70\xed\x74\x4b\x9b\x5b\xae\xb1\x78\x0f\xcd"
+  "\x9a\x70\xaf\x00\x3e\x67\xb4\xc4\x27\x55\xfc\x42\x57\x2f\x74\xc4"
+  "\x1d\x77\x78\x1d\xb2\x7c\x02\xef\xb1\xcd\x2a\x14\x1a\xc7\x94\xd6"
+  "\x12\x9f\x6f\xe3\x7a\xc2\xf2\xdb\x74\x6d\xf3\x95\x99\xca\x16\xe0"
+  "\xb8\x71\x4b\x0f\xea\x30\x83\x4c\xdb\x93\xb4\x64\xa5\x5a\xaf\xad"
+  "\xd0\xbf\x37\xb0\xf4\xa8\xe1\x2b\x07\x19\x4d\xc7\x7b\x87\xa1\x03"
+  "\x7c\xb4\xb4\x41\xf7\x6b\x6a\x56\xfd\x2f\x1a\xad\xbf\xef\xd5\x71"
+  "\x4c\xe0\x58\x16\xc0\xff\x08\x8f\x1d\xd6\xbe\x7b\xf1\x7c\x14\xf4"
+  "\x39\xa4\xe8\x53\x24\x6d\x40\xd8\x35\x9c\x7f\x94\xbf\xd9\x81\xbc"
+  "\xa3\x2a\x4e\xc4\xd2\x39\xdc\xe7\x01\xdf\xc7\xaa\x4c\xe0\xfa\x28"
+  "\x9f\x19\x42\x96\xf6\x7a\xcf\xb3\x7c\x2e\xcd\x06\xbc\x06\x43\xef"
+  "\xb0\x9e\xc9\x0d\x43\x4e\xa5\xdd\x5d\xb4\xd1\xd0\x37\x03\x7c\x50"
+  "\x54\x13\x4f\x97\xc4\x1b\x77\x7d\x6c\x92\x84\xfb\xa5\x0e\xe0\xd4"
+  "\x20\xc7\x80\xe3\x69\x9e\xef\xb7\xef\xfb\x94\x8e\x2c\x0a\xf4\xaf"
+  "\x45\x74\x3c\x38\x4e\xb7\x8f\x71\xeb\x95\xe7\xb8\xba\xde\x58\x36"
+  "\xda\xd0\x1b\x06\x1c\x6b\x82\xd0\xac\x0e\xfc\xe7\x69\xac\xe4\x3d"
+  "\x64\x9e\x2f\xa5\x3d\x02\x38\xc3\xcf\xa9\x3b\x4c\x5a\x69\x23\x78"
+  "\xb7\xe8\x28\x74\x8c\x59\xda\x9c\xee\x97\x7a\x06\x74\xd1\xb2\xc2"
+  "\x48\x98\xc2\xd2\x58\xc9\x70\x59\x1f\xb1\x4d\x92\x1b\x36\x73\x1c"
+  "\x91\x4a\x7d\x7e\x81\x0e\x5e\x56\x63\xe0\x0a\x1a\x1e\x34\xf0\xd5"
+  "\xbf\x95\x74\xd0\x47\xcb\x80\x7b\x1f\xfb\xf2\xb6\xa8\xf1\x5c\x21"
+  "\xf5\x0d\xf2\x76\xa3\xee\x31\x1f\xbd\x94\xa1\xcb\xd0\x21\xd4\xdf"
+  "\x7d\xa0\x64\x2a\xca\x2c\x0b\xea\xfe\xa8\x47\x30\xbe\x47\x07\x78"
+  "\x7f\xc9\xa9\x88\xfd\x80\xa3\x6a\x0c\xef\x71\xb5\xd3\xf2\x89\x11"
+  "\xe9\xfa\xd8\x1e\xc8\x46\xfa\x29\xb5\xb6\x6e\xcc\x51\xf5\x97\x2b"
+  "\xdf\x5d\x1d\x47\xd6\x05\x7c\xdf\x8a\x65\x5c\xd2\x5e\x8e\xf1\xf2"
+  "\x42\x63\xbe\x00\xac\x3d\x92\xe6\x23\x45\x13\xd3\x49\xc5\x6b\x58"
+  "\x32\x52\xd1\x69\x79\x65\x14\xed\x79\xde\x44\x3b\x4c\xa7\xe1\x6b"
+  "\x85\x36\x3c\x90\x20\x72\x57\x9a\x89\xe5\x85\x65\x9c\xcf\x5e\xc0"
+  "\x1f\xd2\xae\x52\x74\x5b\xde\x66\xd0\xcd\x18\x3b\xa6\x93\x8f\x96"
+  "\x4f\x67\xda\x46\xf7\x71\xd8\x91\x76\xa3\xef\xa0\x29\xef\x07\xe3"
+  "\xbd\x4b\x97\x8b\x43\xcd\xa3\xd8\x17\x60\xc9\x57\x07\xcc\x3f\xa0"
+  "\x03\x8e\x09\xa4\x68\xbb\x62\xa2\x8f\x0a\x2b\x23\xd6\x0d\x07\x99"
+  "\xbe\x2c\x2b\xc0\xb3\x42\x8f\x9d\x74\x50\xf9\xa3\x2c\xe1\x98\xb4"
+  "\x15\x52\x96\x97\xcb\x18\x17\x1c\x77\xf5\x08\xd3\x88\xf5\x22\xcb"
+  "\x12\xcb\x00\xcb\x93\xa2\xd1\x8a\x8a\x08\x1a\xb5\x30\x7d\x74\x3a"
+  "\xed\x89\xd1\xe5\x0b\xec\x05\x93\x95\x2e\xb6\xa7\xdf\x98\x37\x5e"
+  "\x06\x2a\xb1\x3f\x30\xe5\x6e\x7b\xf6\xe4\x1b\x1d\xf9\x63\x67\xa9"
+  "\x9f\x29\xd9\x59\xfc\x9b\x1c\xbd\xee\xb2\xa3\x9d\x50\xf4\xda\x6d"
+  "\x8d\x47\xe9\x0f\x47\x9a\x2f\x61\xa8\x8c\x1b\xc8\x71\x43\xb7\x2c"
+  "\x26\x0a\x03\xef\xcd\x27\x31\xa6\x96\xc6\x09\x1c\xa7\x76\x36\xd6"
+  "\x8c\xb3\xce\x89\x0b\xd5\xc8\xdb\x89\xf4\xe1\x85\x1c\xeb\xfe\x2f"
+  "\x42\x4b\x6a\x9c\xc0\x6b\x7b\x51\x5a\x1b\xf4\x27\xb5\x7b\xf0\x97"
+  "\xed\x4f\xfa\xd0\x3f\xed\x66\xa7\x00\xdc\x02\xa3\x5f\xbc\x07\x00"
+  "\x3a\x4d\x98\xed\x10\x61\xa6\x51\xae\x83\xe3\x49\x03\x76\x22\xef"
+  "\x01\x38\xd0\xff\x82\x23\x6a\x7d\xe9\x00\xff\x2f\x99\xa0\xeb\xb2"
+  "\x6c\xbc\x73\xfc\x8b\x6c\x39\xae\x6e\x9b\x8c\x43\xad\xad\xbb\xe5"
+  "\x61\xac\x07\xb2\x0d\x98\x80\x35\x54\x3f\xc7\x96\xf0\xbe\xa9\x5f"
+  "\xa4\x56\xf6\xfe\x58\x6b\x82\x8a\xeb\x07\x19\x77\x55\x9b\xb4\x9c"
+  "\x7e\xbf\x07\xe4\x0d\x5f\x9b\xca\x7e\x11\x39\xe0\x3d\x17\x97\x31"
+  "\xf2\xb6\xb8\x35\xdf\x16\x93\x16\xc4\x38\xa6\x2a\xfb\xb9\x8b\xf5"
+  "\x27\xd6\x96\x2b\xfb\xf7\xff\xe5\x7c\x68\x22\x97\x5a\xcf\xac\x94"
+  "\xfb\x3e\x67\xdd\x66\x82\xce\xee\xba\x21\x4d\xae\x51\x82\x9a\x3b"
+  "\x81\x94\x2f\xea\xca\x87\x0c\x1d\xcb\xe7\x49\xd6\xb5\xc2\xcf\x7b"
+  "\x89\xd6\x90\xf0\xcb\x98\xe9\x3c\x77\xd0\x49\xf2\x16\xf7\xb8\x38"
+  "\x56\xab\xb4\x81\xd0\xae\x9a\x37\xc2\x6a\xde\x40\xfb\xfe\xc4\x5b"
+  "\xe6\x61\x7e\x48\x38\x49\x2b\xed\x8c\x3f\xd3\x86\xf7\xab\x35\xd0"
+  "\xca\xcb\xf3\x24\xd3\x27\xf9\x37\xbb\xd9\xa7\x81\xfb\x6a\x0d\xa1"
+  "\xcf\x91\xfd\x32\x69\xbe\xcd\x6e\xf4\xcb\x84\x7e\x39\x4e\xb1\xcc"
+  "\x04\xd9\xd7\x04\xf2\x36\x52\xc6\x23\x96\xeb\xe7\x55\x99\x91\x7d"
+  "\x64\xfd\xaf\xfa\xb0\x6a\x7e\xbc\x3e\x0a\x13\xf7\x91\x69\xb0\xea"
+  "\x4e\x5d\xde\x24\x9e\xac\x3f\xba\x68\x65\x60\xf8\x5a\xf6\xf1\x68"
+  "\x9c\x00\xfd\x36\x85\xc7\x10\xf3\x67\x39\xe3\x19\x6f\xbc\x18\x9e"
+  "\x82\xb5\x1a\x36\xb4\x6b\x1e\x70\x39\x14\x9f\xde\xab\x4e\x5d\x9a"
+  "\xde\xab\x3e\xe5\xfa\x8c\x07\xfb\xbc\x58\x43\x58\xac\x83\x6f\xb1"
+  "\x5e\xf3\xc4\x6b\x77\xf8\xda\x1a\xc6\x2b\x6e\x9e\x60\x79\xd1\x75"
+  "\x10\xf8\x50\x40\x4e\x04\xeb\xa4\x1e\xf7\xea\xfe\xfd\x2f\x6b\x82"
+  "\x3d\x51\xea\x07\x93\x28\x8f\x07\xc3\xba\xb6\x9c\x7d\x4c\xa6\xa0"
+  "\xfd\xb8\xf9\x1a\x7f\x87\xc1\xd3\x68\xd7\xd6\xfd\xd3\x0d\xd6\x04"
+  "\xba\xd7\x9f\xf8\x4f\xc9\x56\x47\x68\x0c\xd3\x10\x30\x1d\x90\xe3"
+  "\x65\xbc\x4e\x55\x7b\x17\xab\x61\xff\x6f\x94\xeb\x52\x7f\x52\xa3"
+  "\x5d\xc5\x0a\x5b\x8d\xf9\xef\xf5\xfe\x3d\xdc\x1e\x77\xb1\xd9\x47"
+  "\x1d\xa3\x95\x5c\x7e\x67\x9b\x28\xfb\xb0\x49\x73\x5b\x85\x7d\x95"
+  "\x15\x76\x64\xf1\x0e\x4d\x70\x5c\xfe\x0f\x9b\x06\xf8\x44\xf9\xbf"
+  "\x18\x7c\x82\xfa\x53\xe3\xf3\x40\xf1\x82\x4b\xf3\x40\xb1\xdc\x9b"
+  "\x65\xba\xab\xb5\x4a\xf1\x46\xc3\x4e\x11\xeb\xbe\xb3\xcd\x5e\x22"
+  "\xdb\xb7\xab\xb6\x99\x26\x99\x7c\x2e\x91\x05\xba\xb8\x50\x76\xaf"
+  "\xa1\x07\x98\x5f\xac\x61\xfe\x66\x01\x49\x9e\x46\x1e\xec\x9f\xc2"
+  "\x74\xb5\x5f\xfa\x91\x43\x7e\x77\xcf\xbd\xa2\xc1\xef\xcc\xdf\xce"
+  "\xfe\xaa\x81\xa4\xc6\x2a\x94\x09\xfa\xe8\x13\x19\x93\x14\x73\x70"
+  "\x05\x60\x54\x56\x8c\xc0\x1c\xad\xfc\xb6\x52\x58\xa6\x39\xc6\x0f"
+  "\xcb\x35\xd2\xd2\x80\x37\xc7\xfb\xc1\x7a\x67\x4d\x46\xff\xbc\xe4"
+  "\xce\x84\xae\x10\xd2\x4f\x07\xf3\xd2\xe8\x6e\xd0\xee\x0d\x93\x56"
+  "\x7f\x7e\xbc\x8d\xb8\xcf\xe7\xd7\x8d\xaa\x7f\xf9\x56\x32\xff\xab"
+  "\xed\x19\x2a\xbc\x9d\xd2\xd6\xfe\xc0\x4c\xff\x7b\x22\x99\x98\x0e"
+  "\x3e\x5a\x93\xa9\x68\xb7\xc6\x65\x8c\x8f\x8f\x56\xcb\x7d\x51\xde"
+  "\x6b\x9c\x1d\x12\x17\xd4\x7e\xe8\x1a\xe8\xbf\xe7\x6c\x2a\xdf\x71"
+  "\xd1\xf9\x3f\xdb\xf3\xf6\x45\x4b\xed\x79\x2f\xae\x58\x7c\xfd\xf5"
+  "\x51\x6b\x25\xb3\xbc\xc3\xe2\x5e\xb3\x47\xcd\xa7\x6b\x3a\x0d\xbc"
+  "\xd9\x2e\xc1\x3b\xfa\xbf\xe2\xa2\x7d\xcb\xac\x5c\xdd\x4d\x39\x37"
+  "\x83\x06\x9e\x6f\xa3\xac\xdb\x22\x5e\xef\xa0\xac\xdb\xef\xc8\x7d"
+  "\x78\xc1\xfc\xbc\x95\x11\xa9\x77\x46\xee\xeb\x6d\xd9\x86\xb6\x13"
+  "\x47\xdd\x0f\x5d\x91\x30\x6b\x35\xcf\x2d\x25\x9f\x97\x84\xc4\x97"
+  "\xd0\xd7\x13\x21\x63\xb9\x87\x8b\x42\x74\x18\xba\x4c\x7c\x87\x75"
+  "\xf8\x30\x75\x37\x0f\xf6\x14\x78\xcb\x8a\xbe\xfb\x61\xd7\x9d\xe3"
+  "\xfd\x99\x13\xe4\x4c\x68\xad\xe4\x98\xbc\x1f\x06\x95\x8d\x51\xd2"
+  "\x84\xf4\xab\xf0\xfb\x05\x7e\x87\xe2\xf7\x6f\xf6\xc5\x58\xf7\xb0"
+  "\x2f\xf4\x72\xf6\x85\x2e\x91\xbe\x1e\xb7\x06\x5c\x74\xeb\x12\xb6"
+  "\xd9\x4b\x8a\xd8\x06\xf1\x91\x93\xbf\x8b\x47\x5c\x16\x69\xfb\xed"
+  "\xcf\x51\x06\xff\x0a\x79\x86\x54\xd2\x24\x4a\x3f\x0c\x8a\xed\x39"
+  "\xfc\x8d\xab\x31\x68\xf3\xfa\xc4\x84\xe3\x94\x68\x1b\xd6\xd3\xe3"
+  "\x76\xb2\xff\xd3\x51\xa6\xd3\x60\xdf\xd0\x64\x3a\xc7\xda\x87\x03"
+  "\xb6\x61\x19\x49\xfb\x56\xb7\xe7\x76\xca\x79\xc1\x59\x14\x61\xd3"
+  "\xf1\x99\x60\xb2\xb2\x4f\x44\x58\xd9\xa7\xce\x0a\x43\x0e\xf0\x5c"
+  "\x63\xf0\x69\x54\x7c\xb4\xc5\x45\x0b\x96\x2c\xc8\xb3\xdf\xb8\x34"
+  "\x99\x22\xa2\xa3\xe5\x2f\x58\x6c\x5f\xb2\xe0\xa5\x65\x0b\x96\xca"
+  "\xc8\x66\x9c\x1b\x35\xe7\xa7\x89\xe4\x0f\xc6\x1a\xf7\x76\xec\xa3"
+  "\x98\xbe\xae\x21\x1c\x53\x4b\x94\x7d\xc0\xb6\x4b\x97\x5a\x6f\x5c"
+  "\x38\x18\xbd\xde\x58\x5b\xa9\xec\xbc\x0f\x3b\xd5\x5a\x67\xed\x38"
+  "\x7e\x6f\x27\x57\xc3\x40\xfc\x6e\xd7\x7c\xd0\xd2\xa4\xe8\x66\xf1"
+  "\xf5\xb8\x5d\x39\x06\xdd\x7c\xb4\xd6\xa7\xdb\x52\x5d\x52\x7f\x60"
+  "\x8e\x85\xfe\x8b\x9a\x5f\xd5\xb7\x33\x5d\xac\x7f\x13\xe5\x7e\x6f"
+  "\xd2\x87\x1c\x03\xc3\xc4\x30\xd1\x9e\x0f\xe3\xd3\x09\xbd\xc9\xfa"
+  "\xcd\x63\xc0\x43\x9b\xd3\xb9\x3d\x7d\x1d\xf4\xad\x93\xb4\xd6\x2e"
+  "\xf5\xa3\xe7\xc3\x2e\xd6\x29\x7c\x76\xaa\x95\x02\x8e\x3c\xcb\x5b"
+  "\xeb\x63\x1b\x53\xc6\x90\x07\x2c\xde\xa7\x85\x9e\x0b\xf1\x77\x56"
+  "\x39\x4d\xc5\xf6\x72\xee\xe6\xbd\x61\xb4\xd5\xd1\xe3\x5e\x6b\x1b"
+  "\xf0\x4d\x5f\xeb\x63\xbb\x93\xe1\xfa\xc8\x75\x8c\xe1\xa9\xd8\x65"
+  "\x6b\x27\x81\x77\xa6\x0e\xd8\x4f\x6b\x5d\x11\xeb\x32\xc6\x47\xe2"
+  "\x19\x00\x2e\x32\x4e\xa6\xf2\x1d\x94\xfd\x66\xfd\x59\xa1\xf7\xdd"
+  "\xe8\x0f\xe0\x41\xff\x39\x33\x8c\xb3\x67\x9f\xde\x6f\xc6\x8f\x71"
+  "\x8f\xc4\x59\xc7\x77\x2f\xe3\x8b\x7a\x2d\x11\xb2\xcd\xfb\x32\x43"
+  "\x90\xd6\x36\xe0\x93\xec\xb2\xc7\xea\x8d\x17\x17\xdb\x0b\x16\x2d"
+  "\x7e\x3e\x77\xc5\xfc\xe7\x17\xe4\x2e\x2b\x1c\x6b\x5f\xb6\xf8\x99"
+  "\x82\x17\x9f\x7d\x9e\xb9\x66\x69\xd1\xb2\x67\x9f\xb7\xb3\x66\xc9"
+  "\x9d\x9a\x95\x95\x7b\xff\xa3\x8f\x3c\x9e\x4c\xf7\xcf\x47\x1a\x56"
+  "\xfe\x59\x19\x63\x55\xd6\xc3\xd3\xa6\x3c\x96\x3b\x65\xf6\xa3\xb3"
+  "\xe6\xc8\x4b\x0b\xfd\xf9\x53\x17\xc7\x2f\x10\xc5\x87\xa9\xe0\xa5"
+  "\x0e\x8c\xef\x90\x76\xda\x30\x57\xc5\xbb\x76\x6f\x8c\x8e\x77\xed"
+  "\xc6\x5a\xd6\xdd\x8c\xbf\x63\x44\xeb\x53\xf1\x87\x75\xea\x86\x6c"
+  "\xc5\x5f\x49\x33\x7a\xdc\xee\xbd\x03\xfc\xb5\x41\xc6\x54\x62\x5f"
+  "\x0e\xb5\x3f\xeb\x86\xfe\x77\xb6\x45\xe6\x0d\xac\x27\xdd\xfe\xfe"
+  "\xf5\x64\xbf\x4e\x59\x37\xda\x58\x5b\x22\xcd\x8f\x75\x65\x12\xaf"
+  "\x2b\xd5\x7e\xd2\x86\xa7\x24\x4f\x0d\x2a\xdf\x16\x32\xd6\x95\x2c"
+  "\xdb\x7c\x56\xac\xd6\x1f\xeb\x72\x22\x65\x5c\xc6\x58\xd4\x65\x9c"
+  "\xeb\xc9\xfd\x3b\xcb\x85\x3d\xbc\xa7\x0d\xfb\xb8\x03\xb6\x02\xe6"
+  "\xaf\x1e\x21\x92\x2e\xe8\x7b\x1d\xeb\x2a\x79\x8f\x9b\xed\x66\x9d"
+  "\x9f\x86\x9f\xa4\x75\x9f\x09\xf7\xda\x2e\xb5\xa6\x74\x7f\x97\xf5"
+  "\xba\x58\x37\xea\xfe\xd9\x61\x19\x8f\x0e\x3a\x7d\xdd\xa1\x01\x9e"
+  "\xdd\x30\x97\x79\x61\x60\x2d\xbb\x2e\x4a\xff\x77\xcb\x6f\x35\xae"
+  "\x0b\x19\xf7\xf5\x8b\xae\x27\x93\xf9\xfa\x72\xaa\x30\x09\xcc\x47"
+  "\xeb\x76\x73\x1b\x4c\x4f\x1f\xb9\x0f\xa2\xac\x79\x80\x7e\xeb\x33"
+  "\xfa\xe9\xa7\xef\xb3\x18\x7b\x2c\x0a\xef\x0d\x4f\x0d\x46\xab\xf8"
+  "\x74\x5a\xef\xfa\x5a\x3a\xb9\x69\x08\xcb\xa4\x41\xaf\x8b\x69\xb5"
+  "\xbe\xe5\x62\x5a\x6d\xb8\x26\x82\x56\x93\x2f\xa6\xd5\xfa\x60\xc4"
+  "\xb9\x8f\xbe\x8f\xb2\xe1\x29\xa6\x19\xf3\x18\xfa\xbd\x1b\x7c\xb6"
+  "\x6e\x80\x7e\x1b\xd2\x2f\xa6\xdf\x86\x49\xf1\xe9\xb7\xbe\xed\x86"
+  "\x68\x38\xa5\xf1\xe6\x8d\xe1\x6b\x4d\xfa\x7d\x9e\x0d\x8d\x2d\xa3"
+  "\xe5\x9a\x34\xf8\xba\x49\xcb\x7f\xdd\x8d\x3f\xfc\xf2\x3a\x62\xc0"
+  "\x16\x17\x3a\xaf\x6e\x68\x68\xc1\x9a\x97\xf7\x95\x2e\x31\x17\x1d"
+  "\x33\xf6\x3c\xf0\xdc\xc6\x6b\xe7\xd9\xe1\x7b\x05\xa7\x33\x3d\xf9"
+  "\x5b\x51\xe0\xf7\x36\x65\x97\xfe\x33\xf5\xef\xb9\xdc\x34\x83\x12"
+  "\xd7\x92\xfd\x40\xd5\xed\x9c\x6e\x03\x0f\x49\xdf\x27\xf9\x2d\xd5"
+  "\x41\x60\xe6\x86\x33\x69\x10\xb8\xfd\xfc\x3f\xd8\x9d\xd6\x18\x7d"
+  "\x94\x3f\x7f\x71\xde\x8b\x0b\x17\x7e\xbd\x2a\x8a\xf4\x1f\x2b\x77"
+  "\x6b\xfc\x3d\xa3\xa1\x3d\xeb\x9e\x5b\x85\x36\xd9\xfe\xb7\xa8\x79"
+  "\xf3\x9f\xa1\xff\x7e\xd6\xa4\x6c\xc9\x27\x3b\xd5\x3d\xde\x97\x27"
+  "\x44\xe8\x67\xf0\xc8\xcb\x99\xc2\xfd\xcf\xc5\x03\x63\xfc\x72\xca"
+  "\xc5\x63\xfc\xb2\x3d\xfe\x18\xbf\x3c\x55\x5b\xce\xf7\x2a\x5e\xc6"
+  "\xfa\x67\xb1\xb4\x35\xf9\x9d\xcf\xcb\xb1\x66\xee\xc4\x7a\xb9\x6b"
+  "\xf6\xca\xe6\x7b\x73\x57\x26\xb0\x3f\xb8\xfc\x76\x46\xe8\xbc\xe8"
+  "\xe0\x33\x6b\x3e\x1f\xe3\x6f\x67\xf0\x37\x73\xf8\x1b\xaa\xb2\x0c"
+  "\x9e\xb7\x9c\x20\xb9\x76\x44\xbe\xbd\xfa\x84\xfc\xc6\x2f\x6c\x85"
+  "\x97\x6b\x0c\xdb\xda\x8a\xe9\x8d\xef\x17\x6f\x56\xe3\xd1\xc6\x63"
+  "\xc1\xed\xe5\xae\x6c\x56\x6d\x9c\xe7\xef\x63\x91\x55\xd9\x10\x2f"
+  "\xb7\x5d\x72\xef\x3e\xa9\xbd\x70\xd0\x98\xf2\x6e\xd7\xb0\xd7\x55"
+  "\xec\x69\xf6\x69\xf4\x1b\x3e\x75\xec\x5f\xd7\xe3\xf6\x64\xc4\xfa"
+  "\xe7\x29\x1f\x13\xcf\x74\xc3\xb7\x07\xcf\x73\xfa\xd7\x03\xfc\xbd"
+  "\x15\xac\xe3\xec\x25\x6b\x87\x9e\x26\xcf\x35\xd5\x83\xec\xa1\x1b"
+  "\xf7\x89\x75\x1f\xb8\x61\x80\x51\xd9\xef\x17\x84\x77\xd6\x17\x03"
+  "\xbe\x7d\x9e\x3d\x86\x6f\x98\xf4\x07\xc4\xdc\xcb\xdf\x74\x39\x41"
+  "\x9e\xcf\xe4\x37\x64\x6e\xe0\xfd\x6f\x4f\xa0\x45\xfa\x25\x7a\x7c"
+  "\x91\xb8\xe8\x78\xd4\xf2\x1e\x2d\xe7\x47\xe2\xe2\x98\xbf\x6c\xd1"
+  "\x78\xc7\xc2\x45\xf6\x67\xf3\x17\x15\xe6\x2e\x92\x31\x60\x65\x78"
+  "\xd9\xa2\x95\x85\x7c\x22\x71\x73\x72\xcc\x1c\xa6\xfb\x10\xf6\xfb"
+  "\x4a\x49\x3f\xc2\xd2\xc7\x41\x0f\x93\xf2\x23\x2c\xcb\x52\xf3\x7a"
+  "\x69\xde\xc5\x3e\x33\xa5\xfd\xfe\x5f\xe0\xab\xd4\x0a\x15\x7b\x5e"
+  "\xf7\xb3\x61\xbe\x2b\xad\x8c\x53\x67\x77\xbf\xcf\x18\xfb\x2e\xf5"
+  "\xe5\xc8\xfb\x1e\x32\x4e\xf8\x6b\x3c\x6e\xa5\xe4\x75\x4c\xe3\x58"
+  "\xa7\x3a\x3f\x97\x1e\x33\xf8\xd9\xf0\x37\x64\x58\x7c\xdf\x64\x7c"
+  "\x30\xd2\xd7\xa8\xec\x3e\xcc\x79\xb6\xfe\x7e\xac\x36\x11\xe3\x1e"
+  "\x30\x35\x03\x8f\x32\x7b\x2c\x1e\xc0\xef\x7a\xa4\x4f\x1c\xf0\xe5"
+  "\x32\xfa\x59\x96\x85\xe7\x8b\x6c\xd5\xfb\xa6\x65\xc1\x28\x5d\xba"
+  "\xa0\x28\x99\xa6\xcc\x2f\x28\x60\xb9\x9e\xbf\xa0\x60\xd9\x92\x17"
+  "\x97\xe6\x2e\x5a\xbc\x08\xa9\xf7\x2d\xe4\xd0\xbc\xb2\xc8\xdd\x7a"
+  "\x8e\x7d\xf1\x82\x05\x79\x2a\x49\x1f\x86\xe8\x73\x20\x75\x76\x5f"
+  "\xd6\xe4\x23\x4f\xd1\x80\xfd\xf5\x4a\x9a\x30\x95\xe5\xe0\xef\x59"
+  "\x29\xd3\xd2\x36\x2a\xf3\x45\xaf\x7b\xca\xfc\x06\x3f\xc8\xf1\x73"
+  "\xb2\xbf\x4f\xc3\xab\xdd\x42\x9e\x9b\x60\xcc\x36\x4e\xe3\xef\x63"
+  "\x63\x4d\x36\x95\xed\xfd\x01\x38\xaf\xf4\xeb\x7f\xbe\x5f\xbf\x4e"
+  "\xf9\x09\x98\xf9\x9b\x9e\x7c\xcf\x1e\xf9\xe0\xff\x97\x43\x8a\xff"
+  "\x5f\xe9\xe7\xff\x6e\x53\x22\xd6\x70\xaf\xe4\x19\xf6\x7c\xb4\xcc"
+  "\xbc\x52\x7c\xb1\x2c\xb1\xff\xe7\x2b\x15\x06\x6d\x8d\x71\x56\xbc"
+  "\xb5\xf1\x36\x63\x1f\xb6\x5a\x8f\x13\xcf\xcf\x5c\x97\x6d\x75\x31"
+  "\xfc\xca\x7b\xd9\x9f\xbd\x9d\x36\xea\xfc\xf2\xca\xb1\x08\xbf\xac"
+  "\xd4\x93\xf4\x4a\x48\x8d\xd3\x2b\x01\x03\x3f\x1f\xbd\x22\xcf\x03"
+  "\x18\x86\x92\xfd\xb2\x95\x8a\x77\x36\xda\x0c\xda\xf2\xba\x18\xef"
+  "\xe9\x03\xb6\x45\xd9\x41\xe9\x23\xa1\xe2\x0c\xf4\x71\xff\x01\xa7"
+  "\xde\x80\x83\xb2\xe8\xbf\xa5\xc5\xa0\x95\x51\x26\x92\x27\xa6\xcc"
+  "\x2f\xc4\xa2\x75\xd1\xc2\x85\x0b\x96\x2c\x35\x62\x2f\xa7\xbf\x58"
+  "\x90\xa7\x62\x2d\xdf\x8d\xe1\x5f\x01\x09\x9c\xcc\xe1\x9a\x91\xaa"
+  "\x1e\x63\x6c\xc8\xb1\xbc\xcf\x20\x7d\xf7\xe4\x3a\xe6\xd5\xdb\x76"
+  "\xea\x6b\x9a\x76\xda\xd4\xa2\x7c\x5f\x36\x6d\x50\xf6\xe2\x15\x2f"
+  "\x01\xa7\x4e\xc3\x5e\xe4\xfd\xcb\x6e\xb2\x07\xf9\x1e\x11\xfb\x2f"
+  "\xef\xd8\x2a\x3a\x78\xbf\xb2\xc7\xbd\x29\xc5\xf8\x3e\x17\xdb\x22"
+  "\x9b\xd4\xb7\xcd\xfd\xcd\x8b\x39\xb6\xfd\xab\x0f\x69\xa5\x8d\xa9"
+  "\x22\xb9\x26\x13\x36\x4f\x0a\xcb\xc2\x95\x5d\x1c\xf7\x9e\xe3\x01"
+  "\x6d\xca\x61\x5b\x89\xf5\x0b\xc7\xb0\xef\xa0\x4d\xe9\x58\xdf\xa4"
+  "\xfa\xe8\xd5\x39\xfe\xa4\xc6\xd4\xf5\xab\xc8\xc2\x6d\x40\x37\xf9"
+  "\x5a\x6a\x98\xb6\x9b\x8a\x3e\x85\xee\xd1\xf7\x77\xf9\xfb\xbc\x1d"
+  "\x3e\xda\x94\xa9\xef\xa5\x8f\xd1\xf7\x2e\xc7\xa0\x5c\x95\x8f\xae"
+  "\xd4\x63\x82\xd7\x7e\xf4\x7d\x17\x39\xf8\xbb\x7d\x2a\x96\xcf\xc7"
+  "\xf3\xd0\x8f\xbd\xfc\x6d\x3c\xd8\x57\x58\x43\x6c\xec\x44\x1f\xf6"
+  "\xaa\x38\xe0\xcc\x2b\x9b\xef\x53\xbe\xc5\x1b\xdb\x98\x06\x80\x9b"
+  "\xa1\xc3\xcd\x00\x5c\x8c\xff\x77\xe6\x29\x5e\xdd\x4c\x46\x1b\x98"
+  "\x53\xfc\xb0\x45\x7d\x6c\x8f\x02\x6f\x0b\xfe\x52\xb6\xc8\xf3\x69"
+  "\x1f\xd6\x2d\x56\xc1\x7e\x43\x03\xdf\x20\xdb\x3c\xd1\x98\x5f\xb8"
+  "\x6d\x1d\xf7\xb1\xbc\x7f\xc6\x7b\x67\x7a\x5b\x63\x79\x7d\x6d\xc0"
+  "\xc4\xbb\x45\x3b\x7f\xaa\x06\x30\x2d\x98\x2b\xfd\xfa\xb7\xa7\x52"
+  "\xb6\x9c\x65\x1f\x33\x1f\xe6\xc2\xeb\x44\x6e\x28\x95\xcf\x75\xae"
+  "\x34\xbe\xed\x55\x7d\x96\xe9\xb5\xb9\x6e\xe0\xbc\x06\xf5\x41\x7f"
+  "\xc8\x83\xab\x83\x36\xef\xe7\x76\x59\x16\x78\x2c\x7b\x31\x36\xfc"
+  "\x9d\x78\x71\xfe\x54\x03\xd6\xf9\x57\x82\x06\xc7\x79\x8c\xf8\x8c"
+  "\x95\x7d\xbf\x90\x66\xe5\x58\xe4\xed\xb4\xf9\x30\x8f\x0f\xe3\x02"
+  "\x1a\xda\x42\x3d\x39\x3f\xe6\xfb\xa8\xac\x0f\xd7\x14\xc3\x8e\x5d"
+  "\xc8\xba\xa4\xfc\x21\x5e\x17\xf3\x37\x64\xf8\xd9\x99\x27\x34\x39"
+  "\xbe\xab\x78\x7c\xcb\x1f\x5a\xd3\x29\xb4\x0b\x6e\x12\x07\x03\x44"
+  "\x17\x4c\x14\x0a\x9a\x12\x18\x6f\x93\xf3\x14\xdf\x99\xad\x81\x1e"
+  "\xf6\x10\xda\xb5\x6c\x5e\x45\xa9\x7c\xc7\x98\xbf\x8f\xd2\x1a\xa8"
+  "\xa2\xd6\xc2\x2a\xfa\xb7\x50\x05\x35\x2f\xe7\x98\x11\xe5\xc1\x7f"
+  "\x77\x54\xf0\xb9\x55\x12\x9e\xf7\xd9\x1f\xe3\xb6\xb6\x94\xff\xfb"
+  "\xd1\x3f\xd1\xbf\x37\xff\x89\xec\x4f\xc8\xf7\x9a\x43\x39\xff\x46"
+  "\x87\x32\xff\x8d\x9c\x1d\x42\xe3\xb5\x52\xc9\x0b\xdc\x86\x07\xb0"
+  "\x6a\xf8\x6e\x6e\xaa\xd6\x6d\x4b\x46\xff\xcd\xbc\x27\xdf\x1a\xf0"
+  "\x53\xf3\xe2\x8f\x19\xc7\xeb\x77\x9e\x25\x4b\xf3\xe2\xdf\xcb\x67"
+  "\xb5\x86\x39\x55\xe3\xcd\x6b\x63\x3b\x2d\xc4\x77\x91\xf9\x9c\x0f"
+  "\x76\xbb\xb6\x85\x71\x0c\x2b\xbc\xf9\x5b\xea\x46\x7d\xd8\x71\x7a"
+  "\xfd\x2d\x1d\x5c\x7f\x07\xd3\x03\x38\x1d\x9e\xa3\x68\x72\xa8\x0d"
+  "\x34\x7d\x4c\xa7\x4f\x4e\x24\x7d\xb6\x64\x32\x7d\x38\x8e\xa5\x86"
+  "\xf1\x02\x6e\x99\xa0\x81\x66\xb4\x01\x9c\x2d\xfa\xbe\xa8\x65\xf3"
+  "\x59\x4a\x69\x5e\xcc\xdf\xc7\x2a\x7f\xc7\x9a\x6d\x06\x7f\x9c\x6e"
+  "\xd8\x72\x8e\xcc\x3c\x6e\x7c\x16\xb2\x45\xe6\x4b\x9a\x7b\x78\xcc"
+  "\xfc\x49\x0d\x2e\xfc\xad\xc7\x9f\x87\xf9\x0e\xbf\x1b\x31\x5e\x1e"
+  "\xe0\x60\xc7\x58\xd5\xf0\xaf\xe2\xc5\xda\xbd\x1c\xab\x41\x5f\x97"
+  "\x0c\xa4\x43\x8e\x42\x42\x7e\x8f\x16\x32\x53\x6e\xd7\x20\x47\xbc"
+  "\x2f\xb2\xf3\x35\x4a\xd1\xdc\x1b\x0b\x76\x40\xd7\x55\x61\x2e\xdd"
+  "\x39\x82\x52\x79\xaf\x70\x9b\xf4\x45\x7f\x75\x8c\xa1\xfb\xca\x46"
+  "\xf2\xfd\xb6\xf2\x6c\x13\xef\xa5\x78\x1a\xd3\x75\x3e\x4f\x47\x19"
+  "\xe8\xff\x91\xfa\x77\x28\x36\x49\xbf\x63\x96\xfd\xc1\x6c\x74\xd8"
+  "\x87\x87\xc4\xf6\x1c\xe2\x33\x95\x94\xb5\xc2\x9f\xd2\x61\x15\xad"
+  "\x81\x43\xf2\x5e\x63\x6b\x20\x2c\xcf\x54\x90\x9f\x30\x2b\xe0\xb7"
+  "\xc2\x9e\x3c\xc2\xb4\x33\xd2\xf9\x3c\x86\xf7\xaa\x66\x05\x84\x7f"
+  "\xf6\x4a\x2b\x7f\x1f\x70\xb4\xdc\x8f\xd7\xd3\x5b\x6d\xb0\xc5\x57"
+  "\xfa\xad\xe8\x7b\xa8\x1f\x56\x77\x4e\x22\xcb\x1b\xca\xa6\xf5\x97"
+  "\xed\xce\x31\xf3\x77\x6f\xb9\xcd\x88\xb4\x21\xb3\x1d\xa8\xcb\x63"
+  "\xa5\xa7\x29\x3b\xf4\xb5\xf4\xfe\x75\x1a\xc7\x6b\xec\xc6\xbc\xb9"
+  "\x34\x27\x41\xeb\xce\x31\x85\x01\x1b\xbc\x9f\x2a\xbf\x53\x18\xf2"
+  "\xeb\xdf\xfd\xe9\x84\xfc\xb6\x91\x28\xbd\x70\x04\xe5\xcc\x0c\x97"
+  "\xef\xc6\xf3\xf7\x12\x44\x52\x28\x27\xbe\x1f\xdb\x97\x9e\xe6\x92"
+  "\x27\xc0\x4f\xaf\x67\xb0\x3c\x87\x2d\xef\x8f\xb6\x3f\xc7\xf6\xc9"
+  "\x6b\xff\xc2\xf4\x0c\x43\xc6\xc2\x49\xef\x8f\x1e\xdf\x49\x09\x25"
+  "\xe0\x5b\xb5\xaf\xf3\xda\x1f\x39\x16\x80\x53\x13\xb0\xf9\x5e\x6b"
+  "\x62\xbe\xb1\x76\xb1\xff\xd9\xfb\x76\xe9\xf3\x95\xfc\x57\x97\x37"
+  "\xd8\x49\x87\x5c\x7f\xa6\x43\x21\xaf\xab\xe9\xac\xdf\xac\x7c\xbf"
+  "\xcc\x0c\xf7\x73\xce\x73\x82\x57\x73\xc3\x35\x34\xd8\x7e\x3b\xaf"
+  "\x39\x31\x87\xfd\x45\xad\xbf\x5e\xcf\x30\xd6\x9a\x5f\xd3\x07\x0f"
+  "\xc7\x13\x10\xc2\x46\x5a\xd9\xa7\x0d\xc0\xc5\x29\x7a\xd2\x69\xfc"
+  "\x2a\xde\xe7\x7a\x7d\x1e\xec\xfe\x4c\x1d\xee\x19\x1d\xae\xe7\x52"
+  "\x70\x99\x67\x0e\x55\xca\xb3\x1e\xf4\xe9\xd3\x9a\x30\x60\x87\x93"
+  "\x3f\xf5\x41\xc7\x3b\x9d\x17\x78\x1f\xb4\xe2\x30\xda\xa9\x69\x0d"
+  "\x1d\x21\x8e\x4d\xb2\x53\xc3\xfc\x78\xc6\x46\xba\x9f\x9b\xf3\x34"
+  "\xbd\xbe\x4f\x13\xe9\xa9\x58\x03\xf3\x1e\x9b\x93\x75\x1c\xaf\xaf"
+  "\x4b\xc2\x34\xd4\x5b\xe4\x23\xbe\x57\x0f\x18\x9f\xfe\x81\xcf\x93"
+  "\xa0\x27\xc2\xc2\x66\xda\x7f\xde\x47\xec\xcb\x22\xef\xd9\xaf\xfb"
+  "\xce\xb6\xe1\x6b\xe9\x5e\x61\xb2\x4a\x3f\x46\xad\xf4\xf8\x5e\x8c"
+  "\x6d\x9b\xf2\xab\x6b\x9c\x18\xe1\x53\x97\x78\x9a\x2a\x26\xb3\x4f"
+  "\x9d\xb0\x34\x84\xaa\xe4\x5e\xde\xfb\xa3\x7b\xdc\x15\xf9\x3e\x7a"
+  "\xcd\xc1\xfc\xb3\x91\xfd\xeb\xa5\x8e\xad\xf8\xcc\x9f\xb4\xdf\x25"
+  "\xd4\xdd\xbb\x04\x6d\x79\xb8\x61\xcb\x57\x64\x56\xf4\xa8\xf8\xa0"
+  "\xb5\xab\xa7\x59\x78\xf6\xbb\xf8\xee\x94\x0e\xdb\x0a\xd8\x1b\x44"
+  "\xe9\x7e\xac\xbf\x2a\x54\x3c\x43\x8f\x7c\xae\xe1\xfc\x50\x5f\x3a"
+  "\xe6\xb2\x0a\x8e\x79\x60\xf1\xd1\xeb\x07\x85\xfb\xba\xe6\x6e\xcb"
+  "\x7e\xd7\x23\x36\xb6\xa9\x2a\x3a\x7d\x09\x1f\x15\xea\x7b\x6b\x32"
+  "\x66\x40\xec\x9e\x58\xff\x18\x6e\xb7\x25\x7b\x01\x04\x6b\xc4\xb4"
+  "\x93\xf4\xe6\xe3\xbd\x6e\x32\xf5\xc1\x16\xec\x35\xc1\xe6\xdf\x9e"
+  "\x93\xb2\x79\x14\x65\x20\x6f\xd4\x49\x7a\x63\x72\xc8\x44\x69\xf8"
+  "\x4b\xf5\x7f\x27\x3f\x09\x70\x33\x79\xdf\xf1\xf0\x59\xde\x37\x7a"
+  "\x63\x87\xb4\xd5\xb6\xd1\x18\x0d\xf0\xf8\x0c\x65\xcb\x28\x1a\xc3"
+  "\x7b\x7f\x48\x4b\xcf\x0d\xab\xb3\x44\x63\x7d\xbf\x6e\x14\x8d\x8d"
+  "\x6e\xf7\x0d\x3d\x16\xc0\x9b\x39\xfc\xbb\xc2\x4f\xd7\x16\xde\xc3"
+  "\xdf\x93\xdc\x6a\x13\xee\x44\x21\xbe\x63\x33\xa9\xf3\xfe\xad\x09"
+  "\xd6\x4a\xc5\x77\xf2\xec\x0c\xfc\xc6\x67\x93\xfa\x39\x4d\x82\x8c"
+  "\x95\x90\xfc\xe1\x6e\xfe\x3e\x6f\xc4\xde\x6b\xaa\xc4\x43\xbf\xe7"
+  "\x1c\x5e\x77\xcb\x3c\x86\xc1\xf8\xe4\xce\x57\x67\x3c\x7c\x07\xda"
+  "\x47\x6f\xc8\x78\xbc\x1b\xb7\x51\xca\x2b\xdb\x28\xf5\xf0\x42\xee"
+  "\xd7\xd6\x0c\x25\x8b\x66\x62\x7c\x35\x0f\xcb\x19\x78\x02\x78\x73"
+  "\x7b\xcc\x1b\xad\xa1\x33\xcd\xce\x22\xa1\x35\x3f\xc7\xb6\xe8\xd6"
+  "\x97\x9a\x97\xec\xa6\xd9\x7c\x67\x9c\xef\x8b\xcd\x25\x7f\x35\xe0"
+  "\x55\x8f\xa2\x54\xc0\x5a\xe3\x2d\x20\x3e\x03\xb8\xa1\x79\xc9\x1e"
+  "\x86\xfd\x2a\xcf\x05\x9b\x40\x1f\x35\x27\xbc\x39\xd5\x1b\x6c\xa3"
+  "\xc3\x90\xef\x59\x85\x22\xcc\x70\x50\xe6\x8f\xb2\xbf\xdb\x6d\xf6"
+  "\x5c\x75\x4f\x5d\xf6\xb5\xff\xec\x4c\xef\x87\xf7\xac\x84\x77\xcc"
+  "\x3b\x0f\x36\x9e\xde\x27\x83\xd6\x8a\xbf\xde\xfc\x76\xf3\x92\x3a"
+  "\xe2\xf1\xe1\xf2\x78\xb7\x78\xbb\x50\xf6\x54\xf4\xb8\x70\x19\xe4"
+  "\xdd\x05\xb8\x3f\x1c\x38\xff\xe5\x73\xc9\x81\x32\x55\xdb\xf8\x3e"
+  "\xcc\x1b\xc5\xdb\x41\x23\xb5\x5f\xbe\xf5\x1d\xc6\xd5\x47\x5b\xeb"
+  "\xbc\x45\x7f\x8e\xef\xe7\x09\xd9\x07\xdf\xaf\x6d\x95\xe7\x60\x6f"
+  "\xbe\x31\x2b\xa4\x09\xa5\xcf\x2a\xa7\x6b\xd0\x03\x3e\xfc\xb2\x2e"
+  "\x90\xfa\xe4\x56\xf6\xad\xa9\x9c\x61\x4d\x50\xe3\xcb\x7d\x61\x7b"
+  "\x25\xde\x18\x47\x9c\xd1\xa5\x32\xae\xc6\x18\xf3\x77\xed\x34\x3e"
+  "\x67\x1d\x05\x7a\xf7\xd9\x48\xf1\x9f\x28\x07\x5c\xfd\x7e\x44\xa3"
+  "\x43\x9f\xcb\x1c\xdd\x49\xef\xa7\x8b\xd5\x36\x32\xfc\x6d\x21\xbf"
+  "\x63\x72\x95\x0f\xb3\x8d\x75\x54\xb5\x49\xe8\xf1\xf6\x2a\xa7\xeb"
+  "\x75\x8b\x94\x9f\x43\xa5\x05\xf5\x8b\xe2\xf6\x37\x11\x7a\xc7\x0d"
+  "\x35\x8d\xfe\xb0\x1d\x29\xa0\xab\x30\x1f\x0c\xf5\x06\x7a\xf5\x6f"
+  "\x0a\x56\xfe\x01\x36\xf5\x50\xbe\x9b\x62\xe0\x76\x79\xe7\x69\x95"
+  "\xe5\x6a\x6d\x53\x79\xc4\xd8\xaf\x11\x16\xd0\xd8\x6d\x15\x7c\x87"
+  "\x8b\xef\x1a\x04\x92\xbe\x2c\xf7\x27\x5d\xd0\xfd\x9e\x2a\x83\xb0"
+  "\x53\xa5\xbe\xcd\x0d\xf2\x37\xdd\xdb\x3d\x7c\x5e\x8a\x75\xd3\x50"
+  "\xee\x73\x8f\xfb\x2d\xac\x7f\x0a\xe6\xaa\xf9\xbc\x72\x50\xdf\x6b"
+  "\xb9\x66\x32\xfa\x86\x3e\xc9\xbe\xa1\x8f\xb2\x6f\xfa\x37\x77\x4e"
+  "\xd0\x5b\xf2\xee\xf6\xe5\xf5\xe7\xad\x79\x8a\xb6\x5f\x96\xf3\xf7"
+  "\x44\x4f\xd0\xf6\x71\xf2\xfe\x01\xc6\x44\x9d\x2d\xbc\xd5\x29\x92"
+  "\x5f\x49\xbe\x4c\x98\x7b\x14\xcc\x0b\xcd\x6f\x70\x7c\x3e\xfd\xbb"
+  "\x5d\x80\x7d\x0d\x74\xb9\xf4\xa1\xec\x46\x7b\xfc\xdd\xc3\x01\x3d"
+  "\xb4\xad\x92\xc7\xea\xd6\xdd\x94\xa9\xf8\x70\xdb\x26\xde\xbf\x55"
+  "\xeb\xbc\x6d\x93\xc0\xf7\x6a\x7d\xd2\xef\x9b\x9d\x20\x7d\xb3\x23"
+  "\x75\xec\xe5\xe1\xb8\x4d\xca\xb2\x48\x3e\x3e\x0f\xcf\x63\xd9\xc7"
+  "\x80\xf1\x5d\x11\x32\xf4\xdf\xb6\xb1\xec\xe7\xd3\x7f\xc6\xbe\x12"
+  "\xbc\x52\xa2\xee\xae\x02\x9f\x43\x86\x8d\x22\xbf\xd3\xe4\x16\x07"
+  "\xb9\xdc\xec\x95\x67\xe4\x19\xfc\x16\x79\x4f\xfb\xa4\x7e\xc7\x69"
+  "\xdb\x71\x7d\x3f\x23\x9d\xfd\xe2\x7b\xdc\xdb\xd1\x76\x93\xf4\xe7"
+  "\x61\x1a\x70\xdb\x12\x77\xf9\xad\xa4\xed\x63\x06\xce\x52\xb6\xc9"
+  "\xf3\x09\xe5\x2b\xba\x7d\x92\xc1\x23\xe8\xef\x50\x15\x2f\xf1\xad"
+  "\x77\x0e\x8c\x25\xc9\x03\xdd\xc2\x96\xfc\xbd\x2a\xe6\xc9\xed\x79"
+  "\x91\x74\x9a\x1d\xd2\x9c\x4a\x07\x6d\xcb\x12\x52\xd6\xb7\x65\x7d"
+  "\xbd\x3d\xb1\x7d\x9f\x61\x8b\x28\x3a\xa7\x42\xbf\xec\x5c\x2f\x69"
+  "\xed\xa9\xcd\xe1\x58\x16\xab\x4b\x38\x1e\x4f\xd5\x4a\x8e\x75\x14"
+  "\xf2\xd4\x3a\xc2\x7c\x1f\x0e\xf3\xac\xe6\xa9\xf5\x9c\x28\x24\x53"
+  "\x6e\x21\x9f\x1f\xed\xcf\xe6\xf5\x95\x70\xc2\x16\x48\x86\x7d\x02"
+  "\x39\x5f\xb3\x88\xac\x4f\xe5\x03\xb6\x33\x3d\x8d\x63\x11\x71\x1c"
+  "\x22\x8e\x27\x16\x76\xa6\x8f\xc0\xf3\x48\xd8\x73\xa9\xc2\x52\x9b"
+  "\xcf\x3e\x28\x61\xb7\x80\x3e\x3e\xc6\xf1\x90\x4c\x5e\x7f\x90\xd6"
+  "\x9c\x22\x0b\xc7\x3a\x0a\x95\xee\xcf\x6f\x0d\x7c\x2e\xd7\x16\xc3"
+  "\x0b\x61\x4f\x6b\x34\x1a\x34\xb7\x69\x49\xfb\xb3\x31\xc7\xcf\x51"
+  "\xfd\x3e\x23\x54\xbf\x15\xde\x8c\xbf\xd2\x71\xbb\x3c\x25\x12\xf7"
+  "\x9d\xdf\x0d\x01\xbe\xe6\xa9\x5f\x1f\xf6\xd4\xbb\xd4\x3d\xba\x43"
+  "\x54\x52\x24\x3a\xbd\xb0\x8d\xd9\x27\x92\xef\x14\xb2\x8f\x0b\xf7"
+  "\x91\xfb\xc7\x6d\xff\xfb\xd9\x53\x32\x76\x53\x08\xef\xce\x02\xbd"
+  "\x4e\x17\xea\x74\x1d\xa2\x5e\x4f\xbd\xec\x7b\x6b\x40\xd5\xcd\x95"
+  "\xcf\x5c\x3f\x82\x0e\x7a\x9f\xfb\xe9\x80\xbe\x73\xff\xb8\xff\x21"
+  "\xa6\x09\x68\xa0\xf7\xd5\xd6\xa7\xf7\x93\xfb\xf8\x6f\xe0\xd4\x6d"
+  "\xe8\x27\xfa\x2a\xfb\xd9\x87\x7e\x1e\xcc\x27\x0a\x96\x7d\x59\x73"
+  "\x21\xb9\xde\xc5\xeb\x43\xe7\x7f\xc0\x8e\x2e\x2e\x27\xac\x03\xcd"
+  "\xbf\x2e\x29\x37\x95\xc1\x36\x29\xf1\x63\x3d\xe8\x17\x9d\x6c\xef"
+  "\x7b\x0b\xf1\x17\xaa\x92\xdf\x62\x95\xf6\x31\x7f\x37\xf3\x25\xf4"
+  "\x49\xfb\x82\x4a\x3a\x45\x27\x6c\xd3\xa0\x37\x84\x32\xf9\xe8\x3f"
+  "\xd6\x8f\x27\x74\xfc\xb9\xec\x9a\xaf\x54\xbf\xac\x05\x94\xf6\xc9"
+  "\x13\x1e\x93\xb7\xcd\x43\x46\x5f\x9e\x46\x39\xf4\xc7\x06\x58\x32"
+  "\x6e\xbc\x86\x7e\x6e\x07\x9e\xc1\x88\x3e\x1d\xee\x0a\x02\xe6\x67"
+  "\x94\x9c\x4d\x09\xdb\x4e\xa3\x1f\xa7\xc9\x56\x5e\x02\xfb\xeb\x61"
+  "\xb6\x17\x77\x3c\x7a\x45\x0e\x81\xef\xab\xd4\xf7\x4a\x54\x6c\x95"
+  "\x6b\x4e\xd2\xce\x35\x46\xfc\x14\x8d\xe3\x4f\x25\xed\x2f\x60\x3e"
+  "\x92\xb1\x54\x78\xce\xe8\x01\xcf\xb0\x7f\xca\x0a\xb4\xd1\x93\x3e"
+  "\x52\xe2\xe3\x56\xf1\x57\xf0\xce\xdf\xd1\x49\xe3\x3d\x01\xd4\xcb"
+  "\x17\xa0\x19\xc3\x87\x3d\x37\x87\x7f\x99\x86\x71\xef\x6f\xbc\x4b"
+  "\x13\xd1\xc6\x44\x5e\xfb\x36\x94\xf8\x4d\x1b\xde\xa5\xb1\x97\xa7"
+  "\x53\x76\xee\x1e\x4c\x7f\xf3\x59\x00\xc3\x43\xdf\x46\x9c\xa4\xea"
+  "\x57\xa3\x65\xcc\x2e\x75\x99\xd2\x83\xd5\x39\xbc\xff\x7e\x79\xed"
+  "\x56\xab\xb8\x4d\x6e\xe1\xb9\xcc\x7a\x73\x0d\x3c\xf0\x6c\x1b\x0c"
+  "\xf7\xcb\xa7\x43\xf5\x9e\xc1\x60\x6d\xda\x2a\x63\x69\x39\x37\x6f"
+  "\x65\x1f\xbf\x2f\x3d\x07\x6c\x1c\xd7\x18\x73\x67\x5d\x80\x96\xee"
+  "\x20\x8b\xf3\x14\xef\xc9\xcc\xa4\x03\x55\x19\xb4\x13\x6b\x72\xd1"
+  "\x9d\x3e\xe2\xf5\xb3\xec\x4f\xa0\x74\x08\xdb\xa4\x7c\x8f\x4d\x2c"
+  "\x4d\x4f\xdd\xb2\xd5\xb0\xe1\x6b\xd6\x14\x9f\x23\x93\xfa\x6e\x44"
+  "\x4d\xf1\x54\xbb\x08\x55\x98\xb4\xfc\x2a\x8e\x2d\x94\x7c\xfc\x08"
+  "\xc7\x16\x32\x62\xed\x48\xdb\xc7\x01\x99\xeb\xb6\x25\x6f\x5a\x42"
+  "\x63\x39\x2e\x98\xd5\xaf\x6c\x39\x35\x5f\xd7\xec\x06\x7e\xa9\xfa"
+  "\x19\x7a\xaa\x8a\xbf\xb3\x33\x50\x7d\x16\x6d\xa9\xfc\xcf\xc3\x58"
+  "\xc3\x48\xb8\x4b\x68\x4c\xd5\x59\x4a\x67\x3b\x28\xf7\x0b\x65\xb3"
+  "\xf1\xba\x70\x66\x97\x55\x84\xff\x77\x3a\xed\x38\x39\x10\x37\xcc"
+  "\xbf\x94\x63\x8d\x89\xb8\xdf\x24\x56\x7b\xeb\xd2\x8f\x46\xc6\x80"
+  "\x50\xdf\x15\x23\xaa\x78\x8d\xcc\xfc\x1d\x4d\xde\xcb\xe3\xbd\x61"
+  "\xbe\x4b\xa3\xe6\x90\xda\x2c\x23\xae\xd2\xa0\x67\x73\x1e\xb5\xde"
+  "\xd1\x86\x62\xfd\xe5\xef\x69\x6e\x5e\xce\x73\x46\x6d\x05\xdf\xdf"
+  "\x19\x58\xe3\xd4\x2e\xe3\x3c\x4e\x63\xff\xf2\x4c\x49\xcb\xda\x26"
+  "\x5e\xf7\xe8\x6b\xc6\x4f\xec\xfd\x69\xca\x86\xe1\xb9\x8c\x71\xa8"
+  "\x56\xfb\xc8\xc3\x81\x4b\x9b\x31\x9f\xf1\xbc\xae\xbe\xe1\x59\xdb"
+  "\xe5\x4b\xd8\x57\x7f\x09\xfc\x52\xf5\x6f\xe0\x9a\xba\x39\x56\x92"
+  "\xfb\xed\xd1\xc6\xfc\x26\xbf\xd1\xb0\x6e\xd4\xfd\x4b\x57\xd2\xe8"
+  "\x47\xbe\xcd\x67\xde\xf2\x1e\x46\xa7\x9a\x77\xdf\x9e\x3a\x70\x46"
+  "\x95\x29\xe9\x2d\xbf\xbf\xc6\x6b\x0c\x13\xe6\x60\x15\x23\xac\x4b"
+  "\xcd\xbf\xc6\x1d\xe3\xb7\xe7\x47\xb4\xb3\xbe\x7f\x1e\x45\x1b\xec"
+  "\x2b\xc1\xf0\x95\x6d\xf2\xf6\x44\x6e\x83\xd7\x56\x6a\x7e\x7d\x7b"
+  "\xe2\x25\x6c\xb1\x74\xa6\xaf\xa6\xaf\x27\xbd\x5d\x5f\x2a\xfa\x3a"
+  "\x28\x71\x7c\x05\xd9\x3e\x29\xf1\x99\xd9\x4f\xd5\xbe\x84\xac\x68"
+  "\xff\x33\xce\x67\x5e\x6f\xbe\x95\xf7\xe2\x76\xdd\xe6\xe5\x79\xbb"
+  "\x2f\x27\x65\x16\xaf\xf5\xa5\x2d\xbe\xcb\x3e\x0e\xf5\x90\x36\xe2"
+  "\x77\xa7\x83\xe6\x2d\xab\x68\x2c\x7f\xe7\x10\xe9\xf2\xdb\x60\xfe"
+  "\x6f\x3d\xdf\xf3\xbd\x34\xb2\x7d\xaf\x82\x7d\xec\x77\x4d\xc7\xfa"
+  "\x52\xee\x1d\xcb\xf6\xcb\x2e\xf8\x39\x3e\xda\x7b\xbd\xbe\x21\x6a"
+  "\xac\x76\x7d\x81\xf7\xf4\x88\xf7\xb5\xc6\x5e\xbe\x8f\x76\x75\xc8"
+  "\xf3\x40\xf6\x23\x5e\xcc\xf3\x75\x7b\xe1\x80\xef\xcd\xae\x2f\x74"
+  "\x5c\xbe\x38\x50\x48\xbc\x57\x7d\x74\xe7\x48\x71\x04\xed\xed\xf5"
+  "\x51\x6d\x50\xdf\x8f\x39\x22\xf9\x8a\xed\xdd\x7f\xe6\x35\xd8\x97"
+  "\xcd\x9b\x50\x8e\xe7\x89\x5c\x07\x65\x2a\x1b\xbe\xdd\xa3\x81\x7f"
+  "\x06\xfa\xbf\xeb\x21\xde\xeb\x8b\xab\x13\x61\xe2\xc8\x3a\xa5\xc7"
+  "\x0f\x4a\x3f\xae\xd2\x50\x36\x7e\x61\xdb\xff\xb5\x10\xbf\x29\xe0"
+  "\x39\x17\x7e\x53\xf1\xeb\xc0\x6f\x9a\x28\xed\xcd\x60\xbe\xc4\x1a"
+  "\xd6\x86\x75\x82\xa5\x3b\xe9\x78\xf3\x60\xf7\xff\x98\x36\xde\xf5"
+  "\x8f\x91\xf2\x4b\xad\x3b\x78\xd8\x0f\xfb\x0c\x2b\xe5\xa5\x21\xd1"
+  "\x6b\xbf\x96\xef\xd9\xd4\x1d\x74\xee\x60\x7f\x90\xba\x98\xef\x9f"
+  "\xd7\x35\xe1\x0f\x92\xf6\x4e\x36\xfe\xa0\x33\xea\x0e\x0e\xfc\xbd"
+  "\xd3\xd4\xe3\xae\x3b\xe8\xa3\x3a\x69\x63\x5d\x9e\x4e\xac\x53\x77"
+  "\x29\x78\x5d\x94\xf4\x69\xb9\xea\xef\x85\x1a\xbc\x5b\x44\xd2\x05"
+  "\x9f\xde\xdf\x72\xbc\xa7\xda\x9d\x98\xd7\x92\x40\x93\x51\xe8\x73"
+  "\x52\x28\x9b\xfb\xcb\xf8\x76\x27\xfd\xb5\x30\xf2\xee\x23\xc3\xe4"
+  "\xfe\xfb\x93\xda\x19\x1e\x89\x9b\x66\xf4\xd3\x53\xa7\x13\x9f\x1b"
+  "\x99\xba\x01\x43\xd9\x41\x28\x0f\x18\x46\xf9\x7e\xda\x8f\xe2\x6f"
+  "\x0e\x60\x4c\x51\x0e\x6b\x62\x8b\x71\xaf\xb2\xc7\xfd\xce\x9e\x4f"
+  "\x0b\xd4\xf9\x01\xd7\x0d\x44\xd4\xe5\x78\x03\xf1\xea\xa3\x4d\x8b"
+  "\x6a\xf3\xaf\x85\x27\xa8\xee\x8f\xaa\xdd\x77\xea\x07\x93\xa5\x92"
+  "\xeb\x61\xdf\x55\xf9\x38\x26\x01\xdb\x43\x93\xbc\xa3\x03\xe4\xad"
+  "\xd2\x30\xe7\xb7\xd7\x64\x96\x88\xe6\x13\xf4\xf3\x45\xad\xc1\xce"
+  "\xcb\x9c\x0f\x7f\x2e\xcf\xdf\x45\xaf\x8b\xbc\xc5\xb7\xcb\xef\xfb"
+  "\x9e\xa6\x5f\xbc\xe5\xf5\xcb\x38\xd9\xfc\xbc\x81\xf3\xd9\xf7\x81"
+  "\xe7\x06\x8e\x1b\x67\xac\xb1\x35\x94\xdd\xc9\xe9\x48\xf3\x06\xfc"
+  "\x32\x3e\xdd\x80\x6f\xf6\xf1\x7a\x25\x53\xbf\x78\x48\xde\x7d\x67"
+  "\x7c\x43\x3f\x6e\x66\x9c\x35\xcf\xf1\x7a\xee\x83\x13\xeb\x3f\x6f"
+  "\xa8\xa7\x99\x65\xc2\xbe\x9c\xf7\x0a\x7f\x31\x0e\x7c\x27\xb4\xd2"
+  "\xe3\xf5\x97\xd9\x07\x79\x77\xc2\x19\x12\xa7\xfd\x49\xc7\xeb\xd9"
+  "\x26\xd9\x52\x32\xc4\x32\xa5\x4a\x34\x77\x27\xb7\xd7\xf4\xb8\x7f"
+  "\x91\xfd\xa9\x83\xfe\x1b\x7c\xf8\x8b\x6c\xa3\xef\x3b\xf5\xbe\xa3"
+  "\x2d\xb9\x7e\x1a\x5f\xa9\xe2\xf1\xa1\xcc\xa0\xdf\x79\xe6\x71\x66"
+  "\x7b\x80\xfd\x46\x75\x5a\xb4\xf5\xcf\x0d\x97\x87\x47\xdb\x37\x68"
+  "\xa3\x4f\xb5\x51\x3f\xe9\xbf\xd7\x46\xfd\xa4\x4b\xb5\x01\xdd\xf0"
+  "\xdd\x93\x54\x7f\xf0\xf2\xd7\x8e\xf5\x15\x92\x57\x3c\xed\xe5\x4a"
+  "\x67\xfe\xf2\xae\x30\xd6\x6f\x21\xcb\x85\x1a\xf9\x2d\x1e\x13\xb9"
+  "\xbc\xbe\x10\x85\x3c\x9f\x96\x1f\x76\xf4\x52\xf3\xf2\x3f\x51\x07"
+  "\xfd\x8b\xdc\x37\x3a\x5c\xc4\x6b\xb6\x0b\xbe\xbe\xb2\x76\x7f\x9f"
+  "\xa9\xde\xc6\xf4\xde\xc1\xb1\x0f\x23\xf8\xac\x35\xf0\x27\xf2\xce"
+  "\xe3\xfd\xd5\x23\xbc\xaf\xed\x83\x7e\xa8\xd1\xa0\x1b\x60\xa3\x87"
+  "\x25\x3d\x60\xbf\xa8\xf5\xd6\x97\x6a\xbd\xe5\x97\x77\xfe\xae\x84"
+  "\xdd\x9b\x22\xdc\x05\x69\xbc\xf7\x1d\xee\xcb\xb1\xf7\xb8\x29\x9b"
+  "\xe3\x10\xf2\xbe\xb3\xb0\x34\xa6\xcd\x0e\x25\x0a\xb9\x9e\x82\xed"
+  "\xcf\xf1\x08\xbd\x01\x1f\x85\x61\x47\x57\x9d\xa7\xb4\x2a\xd8\x9e"
+  "\xd0\xd9\xa9\xac\xd7\xab\xf5\x78\x84\x9b\xce\x0f\xc4\x23\xdc\xc9"
+  "\x7b\x3d\x6d\x78\x3e\x4f\xe6\x70\xe9\x97\x9e\xed\xe7\x69\xcc\x8e"
+  "\xe5\x94\xbe\x9d\xf7\xf2\xfe\xa6\x6c\x1f\xb6\x2b\x64\x6c\xc2\x17"
+  "\xd3\x79\x3f\x7f\xc0\xf6\x59\xc1\x31\x53\xfb\xf5\x96\x59\xee\x81"
+  "\x5c\x16\xbd\x7f\x29\xe7\xc1\x90\xe7\xf8\xc1\x90\x25\x94\xdd\x57"
+  "\xf6\xd7\x42\x1f\xfd\xcb\xc4\x3e\xd3\x2f\xf6\xc4\x1b\x5b\xc3\xb7"
+  "\xa9\x22\x22\x9e\xe4\xa7\x63\x94\x7e\x07\xac\xe2\xc1\x78\x22\xbc"
+  "\x3d\x87\xc6\x77\x51\x86\xf2\x57\x48\xc2\x9c\xf8\x4b\x1f\x9f\x9f"
+  "\x97\xbc\x40\xb6\xf0\xf6\xb9\x09\xce\x5a\x4a\xe4\x6f\x3f\xf3\x5f"
+  "\xc9\x57\xa2\x73\x7c\x01\x65\xf0\xf9\x03\xfb\x34\xd8\x57\xcb\xf2"
+  "\x8d\x63\x8a\x29\x2a\x4e\xce\x74\xe5\x6c\x74\xb7\x7d\xc6\xe2\x67"
+  "\x5f\x7c\xa1\x70\x7e\xd1\xa2\x67\x16\x15\x2c\x2a\x5a\x29\xc3\x06"
+  "\x8c\x95\xff\x3d\x70\x63\xde\x1c\x79\xe8\x1c\x61\x5f\x8c\x19\xd8"
+  "\x8f\xfb\xd5\xa2\x30\xef\x1f\x5c\x16\xbd\x7e\x35\x41\x3f\x47\xf3"
+  "\xef\x90\xe7\x4a\xbf\x2a\xf6\x25\xec\xdd\xcb\xba\x62\x93\x8a\x23"
+  "\xd3\xa9\xfc\x18\x54\x39\xcd\xd3\xcb\x31\x7a\x26\xb5\xd3\xbb\x32"
+  "\xe6\x25\xc6\xca\xe5\x2d\x3e\x49\xb0\x43\x26\xf1\x39\xcb\x61\xde"
+  "\xcb\x90\xb6\xef\xaf\xfe\x26\xe7\xb0\xd3\x32\xa6\x52\x5d\x3b\xde"
+  "\xd9\xef\x5d\x13\x39\xdb\xc3\x2f\xda\xea\xb4\x17\x6d\x3f\x17\x22"
+  "\x67\x9b\x76\x26\x7f\xbb\x38\x93\xbf\x4d\x78\x6a\xeb\x21\x63\xa3"
+  "\x4f\xd2\xaf\xc2\x21\x37\x7d\x0b\x7f\xc3\x06\x62\x08\xec\xbe\x2a"
+  "\xab\x43\xf4\xe1\x4f\x13\x9e\xb7\x0f\x46\x9c\xa1\x71\x9e\xbc\xb3"
+  "\x51\xb8\x84\x7d\xa9\x76\x4f\xe3\xb6\x45\xd9\xdb\xff\xcb\xef\xcc"
+  "\x4f\x44\xf9\xb0\xc2\x65\xf7\x7c\xef\xfa\x13\xa4\xce\x4d\x77\xcf"
+  "\x6b\x96\x7b\xc6\xbb\x2f\x70\x3d\x3e\x67\x63\x1b\x5a\xc6\x62\x35"
+  "\xfd\xb2\x8b\xfd\xf0\xd8\x7e\xde\x31\x82\x52\xcb\x47\x50\x4a\x8f"
+  "\x7b\xf7\xc6\x7e\x1f\x0b\x8b\x9a\x53\x79\x5e\xe3\xd8\xc1\xd0\x39"
+  "\x3d\x3c\x47\x32\x1e\xcc\xa7\x80\xb9\x97\xcf\xe0\xd4\xbd\xa2\xdd"
+  "\x2d\xb0\x1f\x27\x5e\xbe\xce\xdd\xdd\x22\xe7\x0f\x93\x53\x8c\xdf"
+  "\x48\xf3\xe4\xf9\xa8\xf2\x39\x34\x43\x2e\x2d\xaa\x3f\xef\xde\x26"
+  "\xcf\xcf\x97\x9f\x62\x1d\xe2\xaa\xee\xa5\x14\xcd\xd3\x98\xc2\x76"
+  "\xcc\xe1\x62\x79\xae\xcc\x67\xda\x0d\x7c\xee\x2c\xef\xe5\xc9\x58"
+  "\xd4\x7f\xa2\xea\x73\x64\xee\xa0\x5f\x67\xf2\x5e\xfb\x00\x6d\x7f"
+  "\xfd\x06\x9f\xad\x88\xb2\x9a\x4c\x6b\xb1\xc9\xc3\x30\xb4\xf3\xa7"
+  "\x27\x1a\xf5\x30\x77\x0f\xe3\x7a\xed\xf4\xeb\x95\xb2\x1e\x97\x95"
+  "\xdf\x31\x4c\x9d\x8b\x79\xec\x20\x97\x0f\xe1\x7d\xa7\x96\x9a\x2d"
+  "\x20\x6f\xe1\xe5\xe1\x06\xe4\xcd\xd1\x3c\x7f\x2d\x44\x5a\x8e\xdc"
+  "\xe3\xc5\xba\x5c\xc6\x3b\xb1\xec\x87\xae\xfb\xb2\x59\xe2\xc3\x7e"
+  "\xac\x45\xd0\x4d\xd2\xee\xfb\xf5\xe1\x9d\x7f\x93\x31\xb2\x31\x86"
+  "\xef\xce\xd3\xf9\x46\x9f\x3f\xdf\x9d\xdf\x5d\x56\xef\xea\xb6\xb4"
+  "\xbb\x02\x26\x0b\x1d\xb0\xb1\xdf\x7d\x6f\xc6\x01\x5b\x2f\xd6\x0e"
+  "\xef\xa6\xfb\x4c\xd5\x0d\xca\xe6\x50\xf5\xf8\x6c\x07\xf6\x68\x57"
+  "\xa2\x2d\x75\x3a\xf2\xa7\x1b\xfe\x15\xfc\xed\x6f\x3e\xe3\xf1\xd1"
+  "\xaf\xed\x4c\x37\xf0\xfd\x1e\xb9\xcf\xbf\xee\xc9\x4e\xf4\x67\x28"
+  "\xfb\xc0\x31\x9d\xf9\x7e\x83\x15\xcf\x62\xb9\x98\x68\x0d\x65\x9a"
+  "\xaa\xe5\xbd\x46\x79\x5f\x7e\x82\x1e\xb3\x25\x43\x8f\xe1\x32\x96"
+  "\xdf\xd5\x7d\xfb\x77\xfb\xef\xff\x73\x9c\x1a\xf6\x1d\x08\xeb\x7e"
+  "\x75\x32\x7e\xcb\x59\x75\x3e\xca\x7e\x75\xbc\x3f\xc8\xf7\x03\xf9"
+  "\x0c\x13\xf5\x3a\xfb\xfd\x1c\xe5\xbd\x98\x77\x83\x46\xdc\x96\x1e"
+  "\xf7\x7b\xe6\x7e\x7f\x1d\xf4\xbd\xdb\xd3\xee\x08\x58\x7a\x33\x02"
+  "\x9e\xe3\xcd\xc8\xb3\x43\x37\xe5\x5c\x72\x4d\xc7\xf1\x68\x97\x91"
+  "\x49\x4b\x6e\x9c\xc8\xf1\x2c\x38\x2e\x98\xf2\x93\x7f\x6f\xad\x7e"
+  "\x7f\x3c\xf1\x34\xbd\x37\x79\xe0\x2c\x31\xac\xef\x83\xbd\x57\xaf"
+  "\xec\xb0\xf7\xea\xe5\x3e\x58\x59\xfb\xbc\x5d\xab\x82\xa6\x86\x55"
+  "\x3e\x93\xba\x27\xf0\x1e\x2c\xb0\x8f\x8e\x18\xfe\x28\x28\xc7\xf1"
+  "\x1a\xe2\xc6\x4c\x12\x9e\x0f\x03\x0a\x66\x83\xdc\xc3\x18\x58\xd7"
+  "\x34\xa8\x73\xb2\x75\xa3\xe6\x69\x3c\x07\x26\x7f\x5a\x23\x7d\x2b"
+  "\x0a\xcf\xf2\x7e\xd8\x50\xb5\xc6\x52\x65\x74\xbf\xc8\xab\x4f\x46"
+  "\xbf\x8f\xe0\x77\x45\xb3\x86\xb1\xc6\xde\xfa\x66\x93\xe6\xb3\x26"
+  "\x90\x70\xd6\x88\x00\xc7\x83\x83\x7d\xe5\xf7\x62\x4e\x45\x1b\x02"
+  "\xfa\x61\x18\xea\xcc\x67\xda\x2b\x19\x6a\xf8\x4c\xe2\xe4\xbe\x57"
+  "\x38\xd9\xae\xf4\xb3\x6f\xc7\x59\x42\xb9\xab\x50\x6e\x53\x4b\x71"
+  "\x17\xfb\xa7\xc8\x38\x6b\x1d\x7a\xdb\xfe\xa4\x0f\x03\xdf\x4b\xa1"
+  "\x79\x68\x13\xfc\xe3\x9e\x77\xf9\xb2\xdd\x50\x73\x29\x1b\x43\xcd"
+  "\x79\x99\x34\xd8\x3a\x85\xd7\xa1\xb7\xa2\xfd\x99\x82\xf1\x6f\xdc"
+  "\x14\x32\x05\xa9\xcf\x34\x4c\xfc\x93\xcb\x41\x21\xf7\x30\x11\x5e"
+  "\x85\xf1\xea\xb6\xc1\x8e\x3d\x44\xad\xa1\x16\xe9\xfb\x01\x99\xb5"
+  "\x96\x04\xc4\x59\x6f\x68\x8f\xf4\x85\x55\x77\xc6\x1b\x37\x78\x43"
+  "\xfb\xa9\xb5\xd0\x4f\xac\x17\xda\xa9\x51\xc6\x3a\xbd\xb5\xd0\x45"
+  "\x1c\xd3\x13\xf9\x19\x6a\xfe\x6b\xdc\xa8\xff\xce\x15\xdd\xe9\x51"
+  "\x67\x46\x0f\x2c\x5b\xfc\x6c\xd1\xa2\x17\x17\x8f\xcb\x5a\xb0\x7c"
+  "\x41\x81\xfd\x61\xe5\x4a\x17\x35\x2f\x59\x06\x62\x1f\xbf\x2f\xe7"
+  "\x0a\xb6\x41\x38\x06\xb2\x8c\x7f\xec\x9e\x40\xfd\xb1\x8f\xd9\x16"
+  "\xf9\x3f\x10\xff\xd8\xb0\x31\x38\xf6\xf1\xc0\x1e\xf6\x6f\x6c\xfd"
+  "\x32\xa0\x7d\xd2\xc3\xef\x7c\x4f\x52\x73\x37\x56\xb2\x1c\xed\x94"
+  "\x7e\x67\xef\x97\x47\xc6\xfd\x61\x1f\x3b\xde\xf7\x40\x7a\xbd\x71"
+  "\x27\x15\xbc\x88\xb9\xe2\xfd\xbd\x03\x77\x64\xde\x87\xfe\x6f\x34"
+  "\x2b\xf9\x95\x65\x8f\x1a\x67\xbd\xfa\x37\xa6\xe4\xd9\xb4\xe6\x3e"
+  "\x17\x50\xfb\x2b\xef\xff\xe7\x4e\x6d\x98\x45\xed\xed\xff\x86\x8c"
+  "\xfb\x57\x4a\x36\x3f\xd1\x65\xf3\x37\xb6\x4b\x9d\xc7\x0f\xc8\xc6"
+  "\x6f\xe6\x0c\xc8\xf5\x5f\x8c\xba\x73\xbe\xee\x2c\x5f\xb7\x73\xaf"
+  "\x39\x49\x1f\x2c\xe2\x3d\x17\x3c\x5f\x87\x67\x79\xef\x53\xf9\xa2"
+  "\x7f\x30\x4e\x7f\x46\x1b\x1f\x5c\xa3\x3f\x7f\xe7\x24\xed\x09\xeb"
+  "\xcf\xa3\xf0\xfc\x85\xfe\x0c\x99\xdd\x73\x58\x7f\x4e\xc3\xf3\x07"
+  "\xfa\x33\x74\xfc\x9e\x1d\xfa\xf3\x48\x3c\x6f\xd0\x9f\xbf\x8d\xe7"
+  "\x17\xf4\x67\xc8\xe0\x9e\x47\xf5\x73\x51\xcb\x09\xda\x73\xdf\xe5"
+  "\xdb\xdd\x7b\x52\xd4\xd9\xdb\x9e\x2c\xe8\x7a\xfd\xae\x5a\x7f\xda"
+  "\x3c\x8c\x4d\x83\x41\x5f\xa4\xf3\xde\xa0\x05\xe9\x0e\x1f\xd5\xe6"
+  "\x0c\xa4\xff\x26\xa0\x97\x2f\x87\x9e\x1b\x1b\x91\xde\xa9\xa7\xd7"
+  "\xc3\xbe\x2f\x8e\x48\x3f\xa6\xa7\x37\xa3\xfc\x9e\x88\xf4\x23\x7a"
+  "\x7a\x9b\x8f\xb6\x6f\x8c\x48\x6f\xd1\xd3\xfd\x86\x1f\x82\x9e\xbe"
+  "\x57\xa5\x7f\xc0\x3e\x03\x93\x22\xd2\x77\xeb\xe9\xd0\xff\xbf\x19"
+  "\x13\x91\x2e\xf5\xca\x16\x79\x6f\xcb\x2a\x0e\x14\xb3\x6c\x7d\x30"
+  "\xd5\x47\x6f\x45\xe2\x5c\xa1\xd7\x9d\xeb\xa3\xca\x39\x11\xe9\xfa"
+  "\xfd\xea\x0f\x8a\x7c\xd4\x11\x99\x3e\xa8\xed\x9b\x50\x49\xf3\x06"
+  "\xdb\x9b\xe4\x6f\xf2\x48\xff\x47\x69\x33\x7e\xd8\xc8\x77\xba\xac"
+  "\x3b\x44\xbb\xbd\x44\x88\x76\xfa\xb0\x52\xf9\xfd\x35\xf0\xdc\xd1"
+  "\xc5\x77\xe3\x3a\xe8\xc3\xb5\xf2\xbe\x14\xc7\x32\xe4\xfb\x72\xab"
+  "\xf8\xbe\xdc\x87\x32\xce\xf3\x78\x87\x4b\xc5\x39\x54\x7e\xa5\x5d"
+  "\x72\x8d\xae\x9f\x5f\xa2\xcc\x38\xde\xb3\x64\x38\xbc\x8f\xe7\x2d"
+  "\xea\x95\xbe\x8e\xbc\x46\xe2\x34\x5e\xab\xca\x3b\x54\x11\x6b\x25"
+  "\xa5\xf7\x3f\x6c\xd4\xf8\x8e\xbb\x5b\xad\xe7\xb7\xa8\xf8\x99\x5d"
+  "\xec\x73\x13\x59\xd6\x47\x1f\xca\x75\x6e\xa2\xed\xaa\xb7\x7a\xdc"
+  "\x1f\x96\x0f\xdc\xeb\xf9\xa0\x53\x4f\xaf\x44\x7a\x7d\x44\xfa\xd1"
+  "\xc1\x75\x3b\xf4\x9d\xa5\xc6\xd3\x77\x5e\x04\x42\xe7\x45\x70\xf3"
+  "\x7f\x01\xef\x85\xf2\x8e\xca\xb5\x61\x4f\x4d\xa5\x1e\x2f\xe2\x78"
+  "\x68\xb9\xe0\x7b\x3e\x1c\x5f\xff\x8a\x59\x01\x3f\xcd\x2a\xec\x11"
+  "\x9b\x9e\x61\xff\xb9\x73\x32\x76\x92\xb3\x8b\x63\xf9\xb2\x4f\x56"
+  "\x80\xcf\x7d\x52\x5a\x31\xc7\xed\x5c\xc8\xf9\x9f\xd3\xcc\x7c\xd8"
+  "\xde\xf9\x61\xda\x09\xd8\x3b\x9e\x31\xfc\x21\x3f\x9a\xde\xef\xa3"
+  "\x08\x1c\xb8\x3d\xa7\xfc\x3e\xc6\x47\x32\x36\x07\x7f\xf7\x4b\x94"
+  "\x86\xe6\x89\xdf\xb3\xfd\x7a\xbc\xc1\xba\x96\xc0\x57\x1f\xad\xc7"
+  "\x73\x8d\xfa\x43\x1e\xd2\x07\xeb\x93\x92\xe5\x8f\x9a\x95\xae\xa9"
+  "\xb5\x28\x7d\xf1\x51\xb3\x78\x9b\xef\xe8\x7c\xc4\xf7\x5f\x72\x60"
+  "\x2b\xc7\xf5\xab\x5a\xb3\x83\x4c\x7d\x65\xb0\x4d\x4e\xef\x35\x29"
+  "\xfd\xb4\xb7\x41\x33\x59\xd6\xf2\x7e\xa1\x8c\x91\x5f\xd6\x38\x7d"
+  "\xf7\xe2\xa0\xe9\xf0\xaa\x0e\x5a\xfd\x6d\xb2\xcd\x0d\xb2\xff\xf7"
+  "\xde\xdb\x86\x17\x71\xdc\xaa\xf6\x79\xb0\x3b\x4d\xbf\x41\xfe\xef"
+  "\x16\xef\x35\x85\xa4\xbd\xb2\xb7\x41\xee\x31\x79\x1a\x47\xf3\x1c"
+  "\xe2\x6d\x0b\xb3\xcd\x9c\x02\x9b\x39\x05\xfa\xdf\x12\x5e\x91\x3f"
+  "\x22\xb4\x34\xff\x8a\x1d\x4b\x28\x25\xbc\x34\x3d\xed\xf5\xf3\x34"
+  "\xd1\x98\x7f\xb0\x36\xcd\x10\x3d\xb6\xe4\x2d\x98\x53\x78\xed\x3a"
+  "\x3c\x21\x55\x9e\xa5\xf1\xb3\x66\xda\x59\xb9\x73\xf9\xa5\xbf\xf3"
+  "\x11\xc6\x9a\x95\x63\x74\x33\x2e\xf1\xfa\xba\x71\x1b\xd6\xc1\xfa"
+  "\x9d\xd2\x92\x2f\x68\x24\xec\x5c\xd3\xf0\x73\xa2\xf9\x64\x01\x99"
+  "\xf8\x1b\x09\x25\x0b\xe4\xfe\xd0\x90\xc3\xf9\x21\xf2\x3a\xfe\x4c"
+  "\x25\x4b\x78\x8c\xf6\x0d\x61\x3b\x8d\xfd\x21\x51\x3e\xf5\x24\xed"
+  "\xbb\xc6\x1a\xc4\x9c\x11\x84\xed\xfc\x1c\xaf\xf5\xf6\xdd\xcc\xeb"
+  "\x4d\x1f\xed\x2b\x60\x9f\xf0\xe6\x25\xf7\x73\xda\x34\xe7\x17\xd2"
+  "\xf7\x81\xd4\xbd\xd3\x7d\x76\x7e\x77\xf2\x1d\xd7\xe4\x0f\xc7\xbe"
+  "\xdb\x1b\x1c\xa2\xf6\x20\xf6\xe9\xdf\x4c\x69\xcf\x56\x6b\xae\x7d"
+  "\xf6\xc1\x78\x57\xf3\xd4\xf1\xf7\xec\xaf\xf3\x56\x85\x68\x56\x40"
+  "\xf8\xe4\x39\x25\xdf\xed\x77\xdc\xdb\x2c\xce\x97\x93\xba\x8f\xb6"
+  "\xef\x0b\xad\xb4\xae\x5e\xc5\x00\xdc\xf7\x39\x29\x1f\x23\xcc\x91"
+  "\x75\x7b\xd5\x1e\x6d\xdd\x41\xb5\x67\x59\xd7\xb6\x6e\x14\xfb\x20"
+  "\xef\xeb\xe8\x4e\xaa\x83\xed\xbb\x6f\x6f\x77\xf2\xc7\xf9\x83\xcf"
+  "\x47\xb5\xfc\x9d\xf2\x34\xde\x2b\x67\x7f\xe2\x6a\xe5\x47\x8c\x36"
+  "\x3e\x66\xbf\x62\xce\xbb\xae\xbd\x90\x12\x79\x7f\x11\x69\x77\x8e"
+  "\xaf\x22\x3b\x70\xbd\x52\x58\xea\x3c\xd2\x77\xcb\x53\x57\xe9\xed"
+  "\x12\xcd\xec\x33\xa8\xce\x34\x3e\x0e\x88\xa4\x3a\x8f\x5e\x7e\x43"
+  "\x6b\x17\xfa\x60\xa9\xcb\xf1\x06\x4f\xe9\x36\xe1\xc7\xe0\xfd\xba"
+  "\x1c\xe1\xa9\xcb\x57\x77\xc5\x3f\xfe\xcc\xd0\xab\x8a\x47\x3f\xfe"
+  "\xa3\xce\xeb\x6d\x8a\x6e\x1f\x07\xf4\xf9\xea\x3a\x7e\xc6\xdc\x9d"
+  "\xa1\xce\xe0\x3f\x6e\x36\x6c\x64\x9f\x5e\x86\xeb\xe0\x59\x8f\x85"
+  "\xf3\xb1\x0f\x7d\x77\xe8\xf9\xf2\xbb\x05\xe8\x1f\x74\xfd\xc7\xa3"
+  "\xb9\x5f\x83\xe9\x56\x49\x8b\x62\x4a\x04\xce\x0e\x4d\xc5\x45\x0e"
+  "\x78\x03\xf7\x36\xab\xef\xf6\x35\xad\x91\x77\x66\xd1\x0e\xc6\xc7"
+  "\xc4\x7a\x93\xef\xf8\x32\xbc\x01\xfc\x7f\x3b\xdf\xc0\x85\xdb\xe3"
+  "\x3c\xf4\x95\xfd\x76\x98\x56\xf9\x5c\x86\xc7\xf5\x44\x21\xef\x5d"
+  "\x9c\x03\xcd\xd8\x0f\xa8\x69\x23\xd3\x44\xd1\xac\x49\x7e\x1b\x6c"
+  "\x4b\xff\x38\x34\x3d\x15\x4d\x0f\xf5\xae\x59\xa0\x1b\x96\xb0\x3f"
+  "\x48\xd3\x46\x9d\x7e\x5d\xaa\xfd\xa6\xbb\xf4\xb5\x3a\xf2\x7e\xfb"
+  "\x55\x44\xdd\xef\xf6\x97\x55\xdf\x88\x34\xf1\xd9\x2a\xef\xb5\x2b"
+  "\x7e\x6d\x1a\x3d\x50\xaf\x69\x74\xee\x57\x6c\x23\xd7\xe4\xf0\x37"
+  "\xfd\x98\xe6\x3d\xee\xa6\x8c\x01\x7a\x2b\x38\x71\xda\xb8\xd6\x68"
+  "\xc3\x47\xbf\xf5\x1b\x78\xe2\x59\x9f\x83\x9b\x8a\x06\xc6\xe4\xb7"
+  "\x15\x46\x3d\xf6\xdf\xc7\x7b\x26\xdf\x17\x8c\xab\x07\xf9\x4c\x07"
+  "\xd8\xb5\x86\xee\x6d\x96\xfc\x48\x4d\x5d\xec\xeb\x0a\xba\x3a\x14"
+  "\x0f\x35\x1d\x51\x73\x61\x93\x8c\xdd\xc2\xe7\x25\x07\x82\xcc\x23"
+  "\x4d\x1d\x80\xab\xef\x97\x37\x05\x75\x1c\xb0\xfe\xdb\xe7\x8f\x5d"
+  "\xd7\xdd\x3f\x3f\x4f\x5e\x8c\x1d\xb7\xac\x30\x36\x4e\xa5\x65\xe0"
+  "\x0e\xe4\xfe\x09\x03\x77\x48\x3f\xb2\x29\x7a\xef\x77\x61\x9d\xba"
+  "\x67\xb3\x5a\xb7\xee\xdd\x8c\x31\x73\x9e\xa3\x51\xfc\x6d\x8c\x92"
+  "\x42\x71\xb2\xb5\x10\x6b\x69\x4b\x63\x1e\xf4\xc5\xff\xc7\xde\xf7"
+  "\xc0\x45\x59\xa5\xfb\x9f\x79\x19\x74\xd0\xe1\x8f\x2e\x1a\x2a\xda"
+  "\x54\xba\x3b\x16\x1a\x7b\xaf\xed\xcf\xba\x56\x54\xb8\xb1\x85\xe1"
+  "\xb6\x76\x97\xdd\xdc\xd4\x02\x17\x37\xd4\x89\x90\xd0\x60\x06\x50"
+  "\xf9\xb7\x80\xb4\xeb\x76\xb5\x90\xe8\x5e\x77\x97\xee\xda\x86\x5d"
+  "\xb7\x68\xb3\x9a\x12\xef\xa2\x02\x43\x85\x85\x2d\xe6\x88\xa8\xe8"
+  "\xa2\x8d\x38\xca\x00\x33\xef\xf9\x3d\xcf\x39\xef\xcb\xcc\x00\x83"
+  "\xc3\x88\x7f\xda\x2b\x9f\xcf\xfb\x79\x79\xcf\x7b\xe6\xbc\xe7\x3c"
+  "\xcf\xf7\x3c\xcf\x73\xfe\x3d\x4f\x92\xfe\x02\x19\x83\x7b\x29\x50"
+  "\xde\xe0\x5e\x4d\x1a\x00\xe9\x05\x3b\x93\x9c\xe7\xd4\x3e\xda\x0c"
+  "\x63\xdb\xca\x62\x18\xcb\x1a\xce\x90\xc9\x7c\x6f\xc4\x07\x1f\xe0"
+  "\x9c\x0e\x35\xc4\xbf\x22\xe6\xef\x4c\xc6\x33\x90\x0d\x30\x22\xa4"
+  "\x86\xa4\x57\xc4\x82\x9d\xc9\x50\x6e\x86\x61\x25\x19\x8f\xfa\x0d"
+  "\xe7\x86\x38\x66\x3e\x4a\x85\x72\x33\xd0\x3f\x99\x48\xe3\x15\xf0"
+  "\x7d\xa3\xa8\x7a\xc7\x52\x2c\x12\xb6\xf7\x1b\x70\x26\xb4\x92\x0f"
+  "\x03\xe1\xfb\x46\x8c\xd1\x87\xf3\x3c\x26\x9b\x0d\x7d\x28\x18\xe1"
+  "\x5d\x10\xbc\xbb\x1b\xee\x22\xfa\x2a\x43\x5f\xd2\x50\x7e\x18\x96"
+  "\x0f\xdf\x32\xf2\xba\x33\x1f\x22\x46\xc8\xb7\x12\xf3\xc8\x3e\xd0"
+  "\x44\x43\xbc\x1f\xbe\xc7\x33\xb5\x0e\xf8\x9d\x09\x2c\x3d\xfe\x9b"
+  "\xe6\xbe\xdf\x48\xf6\x33\xf4\xe5\x8f\x56\xd2\xc2\xbf\x22\xed\xaa"
+  "\x71\xaf\x29\xb7\x65\x3f\x4a\x92\xfa\x3a\xd8\xc7\x1f\xad\x90\xfe"
+  "\x57\xf7\xe5\x35\xc4\x13\x7d\x37\x09\x63\xeb\xa5\x2f\xf8\x81\xec"
+  "\xfd\xe8\x77\x40\x07\x9c\x5f\x68\x66\xe3\x71\xe1\x83\xbe\x73\x39"
+  "\xe5\xec\xec\xce\x87\x7d\xfe\xdf\x80\x37\x35\x9b\xb8\xcf\xbc\x5a"
+  "\x11\xff\x4f\x63\x67\xe6\xc6\xe0\x38\x03\xe7\x0e\x96\xac\xad\xe8"
+  "\x3b\xe3\xc0\xc7\xe0\x1f\x69\x5c\x7c\x45\xb1\xdf\xe2\x58\x1c\x7f"
+  "\x1b\x67\xa7\x17\x36\x49\x79\xf1\xb7\x71\x6b\x97\x50\xfc\x2d\xfc"
+  "\x66\x51\xdf\x6f\xdc\xce\xc8\x7c\xc4\xb1\x0e\x6d\xc0\xff\x2d\x50"
+  "\x67\x69\x0f\x92\x86\xaf\x1f\x7f\x54\x24\xaf\xd9\x9a\xc9\x07\x2d"
+  "\xc8\xb7\xc1\x7d\x21\x7f\xb4\xcb\xdd\x6f\x8f\x71\x03\xfa\x14\x82"
+  "\xf4\x3a\xd9\xbf\x0e\xfc\x0f\xdf\xfb\x80\xef\x83\x73\xf1\x9b\x55"
+  "\xe2\xe2\x83\xcf\x60\xa1\xc7\x90\x1f\xd0\x7f\xfd\xc0\xd2\x9b\x4e"
+  "\x0b\xde\xb1\xf0\x73\x46\xc6\x35\x58\xcf\x56\x62\x8c\x86\xe7\x60"
+  "\x7e\xbe\xdf\x78\x97\xd4\x4f\x6d\x71\x0e\x7b\xb0\x19\xbe\x89\x67"
+  "\x66\x5c\x9e\x23\xa0\xdf\x86\x40\xbe\x44\xee\xa3\xce\x38\xbd\x5f"
+  "\x7e\x7c\x9f\xd5\xef\x39\xaa\xdf\xb3\xc6\x0a\xf8\xf4\xb4\x36\x5d"
+  "\x3c\x99\xcd\xcb\x85\x07\x65\x13\x9d\xe1\x14\xf1\x03\xbc\x1e\xc7"
+  "\xba\x35\xb4\x77\x60\x9b\x82\x69\x4e\x24\x31\xb5\xdb\xb9\x0d\x07"
+  "\xba\xb3\x75\x3a\xe4\x39\x45\x26\xe2\xbe\x69\x8c\x6b\x00\xf9\x4f"
+  "\x73\x1f\xcc\x9f\x04\x2e\x5e\x33\x86\x88\xbf\x8c\x1f\x4b\x85\x38"
+  "\x1b\xae\x8d\xbd\xd9\x63\xf6\xc7\x75\x22\xfd\x56\x82\x36\xcd\x44"
+  "\xe8\x9f\x6d\x18\xf3\x0a\x63\x90\xff\x57\x4f\xbb\xbf\xc9\xfe\x15"
+  "\xd1\xfd\x8a\x08\xa7\xc9\x27\x44\x99\x41\x94\x9b\x4e\x90\x10\xe0"
+  "\xab\x7d\x8f\x7d\x2e\x91\xcf\xe7\x97\x8d\xe7\x67\x8b\xcb\x40\x8e"
+  "\x3d\x1f\x46\x6d\x5d\x39\x1f\x83\xfd\xff\xba\x4a\x1e\xcb\x16\xf1"
+  "\xd8\x05\xca\x13\xe4\xe3\x7d\x82\xe4\x8b\x80\xd3\xf6\xe3\xad\xfc"
+  "\x9c\x52\xe8\x4d\xf0\x1b\x17\xfb\xf7\x93\x70\x4e\xc3\x77\x43\xb9"
+  "\x8c\xf9\x24\x7c\x4f\x02\xc1\x98\x35\xb8\xc6\x1f\x0a\x79\x77\xf7"
+  "\xad\xf1\xb3\xf9\xa1\x4f\x40\xa7\xbd\x1b\xca\x6d\xe0\x77\x43\x97"
+  "\x38\x54\x92\x1c\xc0\xf4\x8a\x78\xfc\x2d\xfc\x2e\xd8\xca\xe6\x72"
+  "\x3e\xb6\x39\xb1\xf6\xb1\x11\x65\x2b\xb4\x49\x0d\xff\xcf\xc1\x76"
+  "\x21\x4d\x20\x9f\x12\x9e\xe7\xee\xd9\xee\xc1\x57\xa9\xea\x75\x95"
+  "\x9d\xcd\x35\xb4\xc6\x03\x9e\xce\x00\x0f\xbe\x83\xfe\x88\x4c\xf0"
+  "\x9d\xfa\xf2\x1e\x52\x1f\x76\x9e\x34\xc0\xff\xb8\x97\xd7\xf8\xab"
+  "\x63\xa4\x4d\x33\xb8\x5c\x07\xdd\x90\x0f\x75\xde\x82\x65\x81\xac"
+  "\x6c\xc7\xfd\x4f\x26\x18\x11\x35\x58\x30\xd6\x16\x61\x65\xd4\x8b"
+  "\xed\xa4\x3e\x1d\xc7\x33\xf6\xa5\x0d\xe5\x5f\x91\x86\xb0\xcf\xd9"
+  "\x77\xd0\xf6\x32\xa6\x9c\x1f\xaa\xec\x4a\x28\xbb\x5a\x2a\xbb\x03"
+  "\xca\x0e\xf5\x5c\xf6\xd1\xaa\x61\x96\x3d\x8c\x7a\x1f\xad\x18\x4e"
+  "\xd9\x20\x2f\xd5\xa6\x30\x7e\x2e\x4a\x3f\x89\x04\x3a\x2e\xa2\x2f"
+  "\xca\x9b\x29\xdf\x4f\xba\xe7\x1c\x3b\x3b\x95\xc3\xf6\xeb\xaa\xd8"
+  "\x19\xaa\xb3\x84\xed\x09\xe4\xe7\xa6\x8e\x13\xdc\x4f\xd0\x95\xb3"
+  "\xa7\xc5\x39\x26\xe9\x5b\xe7\x01\x9b\xb0\x86\xef\xd1\xcc\xdf\xa9"
+  "\xe2\xb8\xda\xf3\x17\x2c\x6b\xf0\x7a\xbc\x1d\xce\xf7\x9f\xd6\xdc"
+  "\x2d\xcf\x73\x9c\x0f\x78\x3b\x5c\x2a\x4b\xd3\x7f\xfe\x4c\x0e\x72"
+  "\x99\x98\x9e\x2a\xc7\xcb\x4c\x95\x8e\x6f\x3e\x9e\xf8\x4c\xe2\x8a"
+  "\xb4\xc4\x04\xcd\xa2\x35\x29\xab\x66\xad\x5e\xbe\x5c\xb3\x20\xf1"
+  "\xf9\xe7\x97\xfd\x32\x71\x0c\x59\x94\xb2\x6c\xd5\xf3\x2b\x70\x8e"
+  "\x4b\xa3\x89\xfe\xd7\x25\x49\xab\x53\x67\xdd\x17\x1d\xd9\x6f\x8e"
+  "\x0b\xcf\xfa\xb5\xa0\xad\x6b\xc8\x84\xfe\xe9\x20\xe3\xd0\xb7\x4c"
+  "\xf0\x5a\x6a\x7c\x11\xc6\x59\x80\xbf\xd3\xa8\x0f\xa0\xdf\x1e\x45"
+  "\x1b\x1c\xfd\xda\x81\xfc\xae\x7b\xf5\x65\xda\x78\x82\x7c\xb1\x13"
+  "\xec\xb7\xe6\xd7\xb8\x8f\xb6\x16\x18\xfb\x5a\x78\x4c\xb7\x2f\x70"
+  "\x2f\x6b\xcd\xaf\x21\xcd\x12\xf0\x6e\xe8\xa6\xaf\x89\x12\xf4\x0c"
+  "\xd8\xff\x7b\x63\xa9\x30\x9a\x16\x4d\xa4\x35\xf4\x58\x18\x91\xfc"
+  "\x4e\x0b\x26\xb3\x0d\xd7\xc3\x55\x71\x76\x03\x45\x79\xca\xfb\xd6"
+  "\xde\x05\x9c\x2e\xdb\x2b\xf9\xbe\xdc\x2f\x56\xe2\x58\x61\x3d\x8b"
+  "\xb9\xb7\x17\xfa\x7f\xf5\x6e\xa7\x9c\x6e\x48\x97\x6c\xb4\x66\xa0"
+  "\xfb\x0b\xad\xf0\xcc\x7d\x5f\xec\xcd\x77\xdf\xeb\xf0\x37\xd0\x7f"
+  "\x9f\x95\xf1\x0b\x7f\xf3\xd9\x6e\x7e\xe1\xff\xae\xd7\x17\x0b\xf9"
+  "\xd5\x3f\xfd\x72\x2f\xf9\xfb\xbe\xfe\xde\x14\x39\xf4\xe5\xcd\xf7"
+  "\x59\xbb\xaf\x61\xfb\x2f\xe7\xf7\xa6\xb9\x43\x5d\x88\x37\xc0\x56"
+  "\xcb\xaf\xbf\x26\x2a\xc0\xe7\xe6\xe2\xa7\x01\xd3\x87\x49\x58\x86"
+  "\x9d\xb6\x19\x7e\x41\xc2\xf5\xa7\x08\xc6\x3c\x6b\x4f\x4d\xa7\x6d"
+  "\xfa\x8b\x68\xfb\x99\x02\x00\xbf\xd5\x25\xad\x44\x5d\xdc\x4a\x42"
+  "\x1a\x52\x31\xf6\x29\xfa\x9f\x82\xd2\xc0\xd2\x35\xc1\x73\x5d\x9a"
+  "\x8d\x1c\xb0\x9c\xc3\xfd\x41\xc6\x86\xa5\x20\x77\x5a\x30\x6e\x2c"
+  "\xad\x51\x2f\x25\xa1\x65\x13\xe9\x6e\x9a\x93\xac\xa4\xc2\xb3\x56"
+  "\x48\x6b\x7a\x4b\x8c\xf2\x7f\x6b\x5d\xad\x3f\xc6\x87\x6b\x25\xb5"
+  "\x81\x12\x36\xd7\xf2\x33\x39\x0d\x6c\xbe\x02\xfa\x49\x13\x9f\xbf"
+  "\x6e\xb8\xc0\xf5\x79\xc3\x5e\x69\x5e\x07\xff\x67\x36\x19\xb4\xa3"
+  "\x1a\x63\x44\x62\x99\x7f\x16\xab\x59\x8c\xc8\xb7\xd6\x45\xf9\x67"
+  "\x2c\x23\x42\x83\xf9\x34\xd9\x03\x72\x10\xe3\x0d\x42\xbf\xdb\x01"
+  "\xfd\xac\x6a\xdb\x44\x5a\x0a\xf5\x2b\x2a\x9f\x48\xf3\xa1\x4e\x95"
+  "\x5d\x39\xb5\x19\xa0\xb3\x74\xd2\xfa\x86\x11\xfa\xc5\x8e\x62\xc8"
+  "\x13\xb7\x86\xdc\x5c\x0c\xf9\x4a\x20\x1f\xda\xa3\xbc\x7e\x75\x0f"
+  "\x00\x0d\x76\xc1\x37\x1b\x35\x4f\xe1\xf3\x3e\x36\x37\x84\xdf\x86"
+  "\x76\x68\x5a\xc9\xbe\x3a\xd0\x6d\x4a\xfc\x86\xfc\x5d\x28\x1f\xe4"
+  "\xdf\x1e\xad\xb4\xbe\x5a\xca\xcb\xd9\xa7\xe2\xfd\x75\x67\xd1\x26"
+  "\x67\x0c\xcf\xa2\xe2\x75\xa0\xd3\x7b\x98\x5f\x46\xf4\x05\xc6\x6c"
+  "\x0c\x66\x57\x38\x48\x30\x1f\x87\x83\x6d\x91\x04\x72\x00\xec\x09"
+  "\xb6\x97\x18\x6c\x09\xa8\xcb\x66\x8c\xa3\x89\xef\x61\x7c\xb4\x0b"
+  "\xf4\x72\x15\xda\x01\x4f\x5d\x78\x84\xe0\x5c\x36\xd8\x03\xca\xe7"
+  "\x17\x53\x1b\x8f\xf7\xb1\x2f\x49\xb6\x05\x50\x06\xa1\xfe\x2f\x4e"
+  "\x23\xca\x5e\xe0\x21\x60\xa0\x16\x6c\x8b\x71\xa7\xc9\xbe\xed\x12"
+  "\xed\x6b\x99\xce\x4f\x63\x7e\x84\xfd\xb8\x8c\xde\xb7\x13\xda\xa7"
+  "\x86\x6f\xd4\x9a\xc9\x17\x2c\xc6\x37\x97\x31\xfb\x8c\xb2\x1e\xc7"
+  "\xb1\xa5\x19\xca\xa0\x20\xcb\xa4\x77\xd0\x7e\xe3\x66\xf9\x9b\xf0"
+  "\x4e\x27\xd1\xac\x0e\x68\x06\x65\xee\x67\xe7\xc9\xad\x60\x2b\x48"
+  "\xb4\xc9\x40\xbb\x82\xff\x76\x7f\x98\x5c\x2e\x8e\x7f\x45\xb0\x2b"
+  "\x90\x5e\x48\x27\x28\x27\x43\x92\x63\x4d\xdc\x7e\xa9\x9b\x29\xad"
+  "\x6b\x97\x02\xaf\x37\x38\xe9\xbf\x7f\xb1\x2b\xfd\xe1\xf7\x1b\xf8"
+  "\x77\x0e\x1c\x74\xe1\x1d\x8c\x41\x0e\xec\xc0\xf9\x48\xa8\xe3\x6e"
+  "\x3e\x97\xb2\xff\x77\xe8\xbf\x0b\xfd\x05\x03\x8d\x77\x17\xa1\x6f"
+  "\x5a\x90\xcd\xeb\xbf\x26\x52\xfc\xd6\x03\xbf\xe3\xf6\xe9\x81\x39"
+  "\x3c\xc6\xe1\x81\xa9\xf8\xdc\x06\xf5\xe2\xf1\x0d\x0f\xf8\xf3\xf8"
+  "\x86\xfb\x1d\xae\x31\x5b\x9d\xf1\x5a\xf7\x5b\x9d\xfb\xf9\xf7\x6b"
+  "\xf8\x38\x75\xbf\x06\xe7\x9a\x58\xfe\xde\x24\xac\x5b\x0b\xf6\x4b"
+  "\xb9\xad\x18\xbb\x15\xd2\xd1\xf6\x6f\x41\xbe\xc9\xe9\xe8\xd7\x16"
+  "\xf8\xa4\x86\x6f\x16\x4b\x75\x4a\x82\x67\x15\x7c\x9b\xed\xa3\xc1"
+  "\x38\xae\x9b\xf0\x37\x7a\xe7\x6f\xb0\xdf\x00\x86\x83\xe1\x37\x1b"
+  "\xe1\x4e\xe5\xbc\x3c\xbe\xeb\x01\xf5\x6f\x7b\x70\xae\xe9\xc0\x74"
+  "\x39\xbe\x2b\xc6\x76\x45\x99\x51\xfc\x94\x1b\xed\x91\x36\x3b\x80"
+  "\x57\x0c\x77\x7b\xec\xd5\x40\xef\x03\x60\xff\xff\x45\xf2\x25\x77"
+  "\x40\x2d\xd5\xcf\xc8\xe3\x1e\xd4\x44\x97\xff\x46\xf6\x65\x70\xc0"
+  "\xda\x37\x1e\xea\xb3\x2d\x0f\xa8\x11\x93\x50\x56\x1d\xf2\x1f\xed"
+  "\xc4\xae\x9c\xba\xf0\x3e\x6c\xb1\xf3\xb2\x07\xca\xd0\xbe\x94\xea"
+  "\x8f\x78\xc9\x94\x68\x17\xed\xda\xef\x5c\xfb\x39\x94\xb1\x14\xfa"
+  "\x78\x1f\x06\xe4\x7e\xcd\x71\x50\xff\x3b\xc9\xa6\xc0\xfd\xa2\x8d"
+  "\x50\xae\x11\x6d\x70\xae\x57\xeb\x93\xf6\xb4\xd8\x71\xae\xba\x09"
+  "\x9e\xa1\x7f\xd7\x47\x9f\x1f\xf3\xd7\xfc\x0d\x4c\x6e\xd4\xc1\xf8"
+  "\x67\x36\x9b\x3f\x47\xba\xc8\xfd\x75\xd3\x53\x38\xf6\x8b\xe4\x7d"
+  "\x36\xbd\x8d\x34\xd8\x3a\x88\xb4\x57\x1e\xfa\xec\x71\x5c\xa3\x3c"
+  "\x0d\x18\x52\x61\xff\x05\xfe\xee\x40\x1f\xc8\x40\xc7\xc6\x0d\x2f"
+  "\xb3\x7e\xab\xc6\x7e\xdb\x8b\x3e\x18\xe0\x3b\x35\x4b\xa3\xc8\x9e"
+  "\x74\x23\xeb\xc7\xe8\x5b\xe3\x55\xa0\x1d\xc6\x52\xed\xca\xa9\x8f"
+  "\x94\xf7\xf8\x22\x46\xd0\x97\x86\x84\x93\x74\xec\xcb\x12\xed\x94"
+  "\x90\x2f\x5e\xee\x7b\x2e\xfc\x67\x79\xfa\xf5\xb7\x60\xde\xdf\xea"
+  "\xf3\x65\x5a\xdb\x59\x3f\x3e\x30\xdd\x0e\xfd\xd8\x95\xa6\x48\x4f"
+  "\xa4\x2b\xe4\x85\xf6\x7f\x52\x27\xd3\xd4\x49\xcf\x86\x19\x12\xcf"
+  "\x1b\xf9\x5c\x4e\x7d\xbb\x34\xcf\xd3\x47\x43\x09\x7f\x4d\xd8\xa7"
+  "\xd6\x63\xdb\x41\x37\xe0\xf7\x11\x23\xaf\x4a\x32\xab\xc6\x82\x18"
+  "\x69\x80\xfe\xff\xe3\x7c\xa7\xec\x38\xa0\x65\x63\x16\xe0\x13\xe7"
+  "\x4f\xc3\x8f\x99\xbf\x8a\x41\x64\x87\x99\xd4\x85\x38\xe5\x53\xc3"
+  "\x52\x99\x0e\x32\x26\xe5\x7e\x0f\x65\xbc\xe9\x2e\x7f\x1a\x5e\x82"
+  "\x32\xc6\xa3\x7c\x73\xda\x50\x0d\x15\xee\xf2\xad\x21\x1f\xe5\x1b"
+  "\xe2\x5a\x97\x86\x73\x59\x0d\x92\xef\xeb\xda\x48\x77\x99\x54\x3b"
+  "\x83\xaf\xc1\x73\x9b\x0b\xb1\xa5\x7b\x8a\xe7\x47\x1d\x06\xf9\x59"
+  "\x9c\x12\x49\xe7\xa5\xa3\x8e\x83\x34\xd9\x17\x76\x0b\xe4\xaf\xc1"
+  "\x73\x87\xe8\x6b\x60\x6c\x0b\x1f\xeb\x81\x9c\xde\x8d\x3e\xa5\xcd"
+  "\xe4\x6f\x2d\x0d\xd0\x0b\x7b\x73\xb9\xec\x96\x65\x05\x7d\x26\x7e"
+  "\xec\x0b\xed\x24\x40\x77\x1f\x3d\x06\x3a\x1b\x7d\x0b\xda\xd0\xaf"
+  "\x21\x94\xad\x39\x41\x3e\xdb\x08\xdf\x0d\x95\xee\x61\x70\x5f\x09"
+  "\xf7\x49\x70\x7f\x02\xee\x53\xe0\x7e\x2f\xe4\x17\xa5\xfc\x91\xf0"
+  "\x3c\x03\xd2\xff\x55\xba\x43\x1d\x4d\xbb\xe0\xbe\x50\xb2\x1d\x21"
+  "\xfd\xd3\x6e\x7c\x86\xfb\x29\x89\xe7\x75\x9c\xe7\xa6\xa3\x50\x4e"
+  "\x3a\xd4\xbf\xd9\xd4\xc2\xca\xd2\x41\x9e\x37\xb0\x6c\x3c\x07\x0c"
+  "\xff\xff\xc2\xc5\x06\x85\x72\x1a\x0b\xe0\x3e\x07\xee\x0b\xe0\x9e"
+  "\x0a\xf7\x5b\x24\x1a\x34\xa2\x6c\x48\x48\x67\x34\x9f\xa7\xe1\xf6"
+  "\xee\x42\xb9\xcf\xa3\x1e\x76\xca\x8e\x7d\x19\x09\x8b\x39\xbf\xcd"
+  "\xa4\x9e\xe1\x00\xf2\x3e\x80\x79\xe1\xfe\x90\x74\x8f\x92\xee\xf3"
+  "\xa5\xfb\xc3\xd2\x3d\x5a\xba\xc7\x98\x49\xe3\x74\xc9\xc6\x00\xba"
+  "\x34\x4e\x67\xfb\x8b\xf2\x77\x46\xf3\x6f\x7c\x1a\x8d\x63\x64\x90"
+  "\xe3\x77\x41\xf9\x7e\x5d\x39\x8d\xd5\xf2\x3c\x24\xce\xf9\xf4\xe6"
+  "\xd4\x2c\x79\x95\xad\x1f\x37\x36\x3a\x65\xdb\x3b\x6d\x6a\x45\x14"
+  "\x01\x1b\x68\x42\x99\x00\xfa\x9f\x97\xa3\x15\xa4\xf5\x57\xc9\x5f"
+  "\xbd\x1f\xfa\x70\x63\xe3\xa1\x80\x6e\xdc\xab\xde\xc2\xe6\x68\xd1"
+  "\xdf\x58\xc0\x3b\xed\x70\x59\x2d\x01\xef\xd8\x64\xf9\x8d\xe3\x1e"
+  "\xc9\x37\xe4\x87\x5d\x39\x9f\xce\x73\x8e\xd5\x1b\x3b\xf8\x5a\xd5"
+  "\x4d\xb7\x40\xfa\x22\x97\xf4\x4a\xac\x33\xd0\xb3\x19\xda\x33\xa7"
+  "\x95\x7c\x9a\x01\xf7\x7f\x69\xe3\x6d\x8e\x94\xdb\x2c\xf1\x43\x27"
+  "\xd3\xb7\x8d\x34\x46\x80\x2c\x4c\x41\x0c\xb7\xf6\xc9\xd9\x46\x76"
+  "\x26\x4d\xc2\x08\xf0\xd2\x84\x3e\x30\x0d\x2e\x7d\xd0\x55\x06\x85"
+  "\x42\x3d\x5a\xdc\x65\xca\xbe\x16\x94\x29\x88\x0d\x90\xdf\xc0\x6b"
+  "\xd3\xee\x7e\xfd\x2f\x1f\xfb\x1f\xef\x77\x9f\x85\xb9\xff\xb6\x21"
+  "\xdf\xce\xfb\x5d\x33\xe0\x0c\xf0\x69\x2a\x43\xfe\x98\xc9\xa7\x36"
+  "\xa9\x4f\x37\x43\x9f\xbe\x0b\xd2\xa5\xd8\xc0\x3c\x5d\xfa\x16\xe0"
+  "\xcc\x84\xed\x9e\x22\xa7\x4b\xed\xc5\x72\x52\x91\xdf\x72\xba\x54"
+  "\x3e\xe0\xd1\x94\x8c\xfd\x44\x4e\x97\xda\x04\x76\xd4\x67\x55\xb2"
+  "\x3c\x29\xe2\x78\x9b\x2b\xff\x0e\xf9\x86\x7e\x9d\xf8\x5c\xfa\x67"
+  "\x65\xd0\x57\x2b\x50\x3f\xac\x7f\x8a\xa8\x5f\xd8\x42\x02\x79\xbf"
+  "\xc4\x31\x85\xab\x8c\x3c\x98\x49\x73\x82\xed\x54\xf5\x8e\xb9\xde"
+  "\x3e\x47\xb6\x57\xcb\xba\x72\x3e\x0f\x93\x63\x09\x3b\x7d\xdf\x7f"
+  "\xbe\xa0\xbe\xa2\x8f\xbe\x50\x97\xcf\xe7\xc9\x75\x71\xd1\xcf\x8c"
+  "\x07\x58\x37\x2c\x6b\x3d\xd8\xeb\x56\x90\x0b\x5c\x6e\x7f\x9e\x2c"
+  "\xc7\x58\x2f\x91\xf4\x16\x8b\xf3\x9d\xc6\xe3\x7c\xa3\x6e\xc4\xbd"
+  "\x34\x22\xce\x63\xa5\x3b\x48\x83\x0e\xc6\xf2\xe9\xc7\xc9\x92\xb5"
+  "\x63\xd0\x77\x49\x3c\xd4\x75\x19\xd4\x6d\xbb\x03\xe7\xd8\x57\xe1"
+  "\x38\xf5\xe0\x04\x47\x1a\xb5\x49\x34\x83\x7e\xd4\xd4\x2d\xd1\x16"
+  "\xe5\xd7\x76\x94\xe9\xeb\xf5\x3c\x8e\x0d\xce\xe5\x60\xff\xf8\x2d"
+  "\xea\xb1\x30\x6a\xab\x29\xc3\xbe\xf2\xb9\x5d\xb6\x49\xa1\xbe\x15"
+  "\xdc\x26\xac\xff\x19\xf3\xed\x93\xff\x8e\x99\xcf\x05\x36\x15\xf0"
+  "\xb6\x37\xe9\xf8\x7a\x32\xf3\xdb\x88\xcf\x8b\xfd\xc2\x26\xe6\xf1"
+  "\xfd\x4f\x35\xeb\xf8\xde\x8d\xa6\xd8\xbe\xbd\x1b\x4e\x5b\x31\x95"
+  "\xfb\x5d\x6a\x4a\x72\xf6\x89\xa6\xb9\xf8\x3b\xf8\xfd\x2b\x90\x9e"
+  "\xe5\x4c\xaf\x8f\xe7\xf6\xc0\x3b\x6d\x41\xd9\x51\xb8\x87\x6b\x02"
+  "\xfa\x7f\x96\xbe\x67\x66\xdf\x67\x73\x1e\xd0\x37\xa5\xfe\x8b\x74"
+  "\x46\x9d\xcd\xfa\x30\xf4\x5f\xec\xc7\xbd\x05\xef\xb4\xc3\xc5\xfb"
+  "\x2d\xd7\xcd\xa9\xac\xdf\xb2\x3e\xdb\x64\x71\xa9\x47\x25\x9b\xf7"
+  "\x42\x7e\xbe\x18\xa6\xee\xca\x39\xa8\x06\x7b\x55\x8a\x93\xf0\x39"
+  "\xdb\x7f\x8c\xfe\x39\xec\x17\xa9\x05\xd7\x90\x71\x4d\x11\xcf\x38"
+  "\x05\x03\xba\xd1\xa7\x86\xbc\x26\xbc\xa0\xc3\x40\x1d\xb8\xbe\x73"
+  "\x91\x5a\x4b\xfb\xfc\xcf\x1f\x8c\x77\xfa\xc7\xf9\xbc\x5a\x6a\x97"
+  "\x19\xbe\x55\xc6\xf7\x5c\x7d\xfe\x06\xb7\xa9\x3e\xaf\x44\x9c\x9a"
+  "\x00\x7b\x70\xdf\xc2\x63\xa9\x1e\xdc\x2c\x63\x0f\xfa\x65\xc2\x09"
+  "\xf2\xc5\x8c\xcd\x13\xe9\x16\xe0\xe9\x16\xe8\x4b\xc9\xf0\x3c\x0e"
+  "\xee\x09\xfc\xae\x08\xc1\xbb\xd4\x47\xb6\xc0\x6f\x1b\xe5\x98\xd7"
+  "\x48\x1b\x6b\xc0\xd1\x46\xc4\x59\x09\xd0\x01\xb1\xc6\xd6\x6b\x75"
+  "\x3c\x96\x3c\xe2\x0c\x31\x16\x9c\xfd\x08\xc3\x19\x3b\xbf\x0f\xe9"
+  "\x58\x5f\xc4\x59\x57\xce\x17\xe1\xb2\xef\x59\x33\x39\x68\xe4\xeb"
+  "\x26\x5f\x44\xca\x7b\x56\x71\xcd\x26\xf5\x16\x32\x01\xca\xd5\xd4"
+  "\x68\x98\x7f\xc7\x23\x26\xfb\x7c\x82\x79\x71\xbd\x8b\xcb\xc9\x9b"
+  "\x52\xe1\x37\x09\x4e\x9a\xef\x63\xfb\x36\xf6\x2c\x66\x73\x91\xdf"
+  "\x81\x77\x59\xae\xe3\x0c\x33\xd9\x1b\x8b\x63\x0d\xdc\x43\x77\x5b"
+  "\x28\xc1\xd8\xf4\x20\xc7\xbe\xd8\x2e\xdb\xb5\x77\x86\xe2\xba\x79"
+  "\x8d\x0d\xea\x87\x63\x68\x68\x6b\x4d\x1b\x8c\x25\x6b\x3d\xcc\x19"
+  "\xcf\xc1\xb9\x1e\x29\x66\x4c\x0b\xce\x63\xa1\x8f\xfd\x13\xe4\xab"
+  "\x19\xf5\x5b\x80\x9f\xab\x07\xfa\x1e\xd6\xa7\xd3\x0b\xe8\x7f\x58"
+  "\x93\x42\xbe\xd3\x4a\xbe\xc2\xf1\x60\xb3\xe1\x1c\xce\xd1\x7c\x19"
+  "\xe1\x3e\x47\xf3\x65\x86\x74\x95\xc2\x65\x75\x5e\xcd\x1b\xa4\x3b"
+  "\xb9\xc4\x55\xc6\xf3\x36\x57\xc2\xb5\x4b\xa2\xd5\xae\xae\x9c\x2f"
+  "\xfb\xe6\x7f\x11\x97\xd8\xb7\x71\xbf\x04\xce\x39\x29\xec\x04\x7d"
+  "\x77\x00\x9f\xa0\xde\xeb\x6f\x7f\xdc\xb8\x0e\x71\xf4\x25\x8b\xe1"
+  "\x88\x7e\x71\x87\xb7\x67\xe7\x4b\xc6\x4f\xee\xa3\xf2\xcb\x0d\xf0"
+  "\xed\x9a\x4d\x67\x89\x52\x97\x42\xa6\xe2\xfc\x77\xb0\x83\x1a\x71"
+  "\x8c\x8b\x98\x78\x8d\xc5\x6a\x69\xde\x98\x9a\x49\x04\x78\x7f\x33"
+  "\xfc\x9f\x2a\xdb\x49\xf0\x9b\x10\x3f\x1b\x09\x45\xfb\xe8\xa1\x4c"
+  "\x72\x73\x57\x4e\xf3\x42\x99\x57\x68\x43\xe0\x3c\x9c\x34\x97\x80"
+  "\x75\x65\x7b\x13\xd1\x77\xba\x99\xd1\x8d\xc9\x61\x2c\x03\xfa\x5d"
+  "\xf3\x3c\x3f\x2b\x09\xe1\xba\xa7\x19\xf0\x5f\x23\xd9\x8c\xcd\xf1"
+  "\x80\xfd\x26\x97\x7a\x5e\x74\xfe\x1f\xf6\x03\xfc\x7d\xb0\x15\xed"
+  "\x33\x4f\xf4\x69\x3e\x2a\xd3\x07\xf7\x85\x06\xc3\x38\x81\xf1\xdb"
+  "\x4e\x3b\xa0\x6e\x75\xba\x75\x44\x75\x9a\x1c\xfa\xf4\xb5\x97\xd9"
+  "\x39\xb5\x5a\x3e\x3f\x7f\x68\xaf\x3c\x0e\xe7\xf5\x3e\xf4\x52\x70"
+  "\xb6\x1f\xc1\x79\x75\xf4\x17\xc6\xf6\xd4\x7d\x13\xc6\xe6\xd2\x4d"
+  "\xf6\x79\xc4\xa8\xbf\x07\xf3\xc8\x76\x55\xcb\x79\x43\x18\xd9\x13"
+  "\x36\x0f\xfa\xf1\xa1\xc5\x66\xc5\x7b\x9a\xe1\xef\x5d\x3c\xb4\x58"
+  "\xa2\x6f\x1d\x5f\xf3\x3f\x34\x0b\x75\xc9\x06\x29\x36\x3d\xea\x68"
+  "\x28\xbb\x5a\xee\x37\xa0\x37\x6a\xe0\x37\x11\x5c\xc6\xe0\x3a\xeb"
+  "\x21\xe6\x5f\x84\x8d\x1b\x78\x7e\x35\x9f\xf3\x3f\xd4\xd1\x67\x4b"
+  "\x43\x3e\xfc\x1d\xdf\x0b\x76\x88\x2c\x71\x28\x80\xa6\x87\x58\xdb"
+  "\x38\x16\xc3\xe6\x75\xe5\x7c\x15\xee\xec\xb7\xcd\x4c\x36\xef\xe9"
+  "\x70\xed\x97\x5f\xcd\x73\x8e\x37\xbf\xb0\xcc\xda\x4c\x34\x83\xf5"
+  "\x43\x5d\x10\x09\xf9\x87\x8a\xfc\x64\xd3\x26\x5a\x51\x2a\x88\x0f"
+  "\xae\x2f\x21\x6a\x45\x11\x90\x0d\xfb\x59\xda\xd2\x09\xd0\x1f\x3f"
+  "\x08\x56\xdf\xb4\xf0\xa1\xd4\xd1\x54\x1f\x46\x84\xe2\xce\xd1\xaa"
+  "\x5b\x6c\x37\x55\x50\xbf\xdb\x1f\x5f\x90\x6a\x23\x9a\x5f\x95\x92"
+  "\x93\xc9\xc4\xef\x21\x07\x7c\x5b\x4d\x74\x66\xd2\x52\x8b\x67\x2e"
+  "\xf7\xa8\xd1\xfe\x68\xa9\xc5\x32\x33\xca\x88\x2a\xa3\x8d\xb6\x17"
+  "\x2d\xf7\x57\x81\x3e\x08\x79\x15\x30\x36\x56\x7d\x53\x45\x2f\x94"
+  "\xf1\xf1\x52\xf6\xbb\x41\xf7\xd6\x0c\x5d\x37\xdd\xc4\x13\xe4\xef"
+  "\x3f\x1b\x5e\xdd\xbe\x4e\x72\xd6\xed\xeb\xa4\x11\xae\x5b\x88\xb3"
+  "\x6e\x49\x58\xb7\x0b\xc3\xab\x9b\x59\xe5\xac\x9b\x59\xe5\x65\xdd"
+  "\x76\x0c\xbf\x6e\xe9\x37\x9d\x20\x2d\x2f\x0d\xaf\x6e\x47\x2b\x9d"
+  "\x75\x3b\x5a\x79\x39\x75\xc3\xb1\xbc\x3e\x9c\x1e\x67\x3e\xce\x53"
+  "\x88\x1a\xf7\xc8\x9d\x20\x87\xcf\xe9\xcb\xd8\xf3\x78\xf8\xff\x4d"
+  "\xa9\x7f\x5b\x0c\x56\x7a\x8c\xdb\x39\x87\x27\xcd\xd6\xe1\xbe\xd2"
+  "\xc3\x21\x80\xe5\x5a\x8e\xe9\xaf\xd9\xde\x4e\x83\x85\x4a\xfb\x3a"
+  "\x0f\xdf\x5d\xce\xf6\x7d\xbc\x2f\xc5\x92\x3d\x9c\x71\x7e\xcc\xbb"
+  "\xe1\xb8\xe7\x42\x84\xfe\x4c\xc7\xbc\xab\xc5\x98\x8f\x6f\xa5\x58"
+  "\x04\x9a\x83\xbe\xb7\xd0\x5f\x9e\x92\xd0\xc2\x77\xe7\xbe\x95\x62"
+  "\x13\xd0\x67\xc6\x7a\x76\x5e\xf6\x70\xaa\x7c\x46\x4c\xfe\x86\x25"
+  "\xe0\xfd\x48\x48\x2f\x92\xe3\xcc\x52\x01\xed\x99\x77\x35\x58\x3e"
+  "\xa4\x6f\x97\x63\xc1\x9a\xc9\xe1\xb9\x92\x6c\xb0\x06\xdb\x86\x92"
+  "\x7b\x87\x0f\xc9\x72\xef\xa1\x54\x12\x8c\xb1\x12\x37\xe9\x47\xe3"
+  "\x9a\x23\xd8\x3f\x87\x93\x90\xee\x71\xd6\xd1\x34\x38\x83\xf8\xe1"
+  "\xd9\x38\xdc\x0b\x67\x0a\xb3\x90\xe9\x19\xc4\x3f\x2e\x1d\xca\xb4"
+  "\x91\xa5\xc1\xe9\x50\x1e\xd0\x9a\x8f\x0d\xbe\x66\x73\x7c\x9b\xa1"
+  "\x3c\x5c\xff\xf6\x4b\x25\xea\x87\xc2\x0c\x74\xfd\x56\xa2\xc4\x73"
+  "\x74\x78\x1e\x8e\x9f\x85\x1b\xa5\xea\xca\xf9\x7a\x91\xdc\x3e\x2f"
+  "\xf8\x13\xc4\xf9\x73\xe4\x25\x27\x7f\x8e\x2c\x18\xc8\x9f\xaf\xdf"
+  "\xe3\xfc\xf9\xba\xca\xc9\x9f\x23\x56\x77\xfe\x7c\x7d\xc8\x9d\x3f"
+  "\x47\xc2\x7d\xe3\xcf\x91\x50\x27\x7f\x8e\x58\x9d\xfc\x39\x12\x31"
+  "\x38\x7f\x8e\x44\x3b\xf9\xf3\x75\xb3\x77\xfc\x39\xb2\xd6\x33\x7f"
+  "\x8e\xa8\x86\xe0\xcf\xa8\xc1\xf9\x73\x64\x9f\xf7\xfc\x39\x62\x1d"
+  "\x06\x7f\x02\x39\x7f\x8e\x7e\xdf\xc9\x1f\xf3\x99\x81\xfc\x31\xff"
+  "\x8c\xf3\xc7\xbc\xd0\xc9\x9f\xa3\x9b\xdd\xf9\x63\x5e\xeb\xce\x1f"
+  "\xf3\x6e\xdf\xf8\x63\xde\xe5\xe4\x0f\xff\x06\xe7\x8f\xb9\x6e\x70"
+  "\xfe\x98\xdb\x9c\xfc\x31\xa7\x7b\xc7\x9f\xa3\x93\x3c\xf3\xc7\x5c"
+  "\x39\x7c\xfe\x1c\x5d\xd1\x8f\x3f\x21\x9e\xf9\x73\x74\xf3\x30\xf8"
+  "\x13\xcc\xf9\xd3\xfa\xa9\x93\x3f\xad\xc5\x03\xf9\x73\xb4\x9b\xf3"
+  "\xe7\xa8\xc5\xc9\x9f\x63\x73\xdc\xf9\xd3\x3a\xc9\x9d\x3f\xad\x8b"
+  "\x7d\xe3\x4f\xeb\x22\x27\x7f\xf8\x37\x38\x7f\x5a\x93\x07\xe7\x4f"
+  "\xeb\x06\x27\x7f\x5a\xc3\xbc\xe3\x4f\xeb\x7b\x9e\xf9\xd3\x1a\x33"
+  "\x04\x7f\x46\x0f\xce\x9f\x63\x01\xde\xf3\xe7\xd8\x9c\xa1\xf8\x33"
+  "\x3c\x5b\xef\x18\xf3\xa1\x35\x02\xe5\x78\x8e\x0f\x0c\xb4\xc3\x7d"
+  "\x7e\x62\xce\xb1\xd2\x72\x71\x94\x8a\x9f\x85\x38\x16\xa3\x59\x47"
+  "\xee\x6f\x25\xc7\x0e\x97\x8b\xfe\x2a\x9a\xb3\x3d\x41\xcc\xf9\x83"
+  "\x9a\x66\x8f\x52\x8a\xd9\xa3\x95\x78\xb6\xd9\x73\xec\xe9\xb6\x7b"
+  "\xfd\x26\x91\x69\x78\x3e\x6d\x3d\xd8\xcb\xf8\x7f\x57\x4e\x5b\x0c"
+  "\xd8\x82\x45\x43\x9d\x93\xc2\xbd\x4e\x7b\x36\xe0\xf8\xb6\x2d\xb5"
+  "\xcf\xaf\x44\x0e\x4d\x47\xff\x5c\xba\x5b\xf1\x3c\x43\x5b\xd9\x66"
+  "\xe6\xef\x69\x67\x4d\xd4\xad\xf4\x08\x8e\x3d\x4e\x90\xe3\x5b\x69"
+  "\xc1\x4e\x8c\xd7\x68\x05\x5b\xfd\x3b\x90\xa7\xad\x6f\x1f\x1c\x8d"
+  "\x7f\x45\x9a\x23\xd4\xf1\xbc\x27\x03\x20\xaf\x0e\x63\x63\x3e\xaf"
+  "\xc7\x98\x8f\x27\xce\x81\xed\xfb\x5d\xfc\x06\xfa\x1e\x7a\x0d\xee"
+  "\xb8\x4f\x86\xef\x81\x3c\xce\xce\xae\xa2\x5f\x43\xbe\xe7\xec\xc4"
+  "\x21\x19\x77\xf0\x9d\x31\xf0\xfc\xb1\x64\xcf\x63\xfe\xb1\xf0\xfc"
+  "\x86\xcb\x7b\x35\x3c\x17\x43\xd9\xe3\xa4\xf7\x81\xf0\xfc\x1c\xda"
+  "\xd9\xcc\x4f\x46\x49\x96\xb4\x57\xf7\xc4\x22\x48\x0b\x91\xf2\x8c"
+  "\x83\x3c\x77\xa3\xed\x2e\x95\x31\x1e\x9e\xa7\xe2\x18\x58\x7a\x1f"
+  "\x0a\xcf\xe8\x57\x4a\x29\xbd\x9f\x00\x75\x3c\x0e\xcf\xdf\xe3\x67"
+  "\x4b\x7a\xa5\x3e\x7a\xbc\xca\xb7\x33\xd7\xc7\xb9\x2f\x2e\x81\xcd"
+  "\x05\xc1\x58\xe0\xb8\xcb\xfe\x9f\xe3\x5b\xdc\xdf\x9d\x08\x75\x79"
+  "\x97\x2f\xbf\xe3\x7b\xd4\x4e\x44\xba\xbc\x4b\xef\xf7\x2e\xd6\xe5"
+  "\x5d\x52\xbf\x32\x93\x5c\xde\xc5\xf7\xfb\xdd\x06\x97\x77\xd1\xfd"
+  "\xde\x55\xb8\xbc\x9b\x23\xbd\xf3\x83\xf4\x6a\xe7\x1a\xde\xf1\xe9"
+  "\x52\xba\x00\xe9\x8d\x2e\xe9\xa1\x52\x3a\x7e\xbf\xdd\x4c\xfe\x23"
+  "\x41\x4a\x67\xbc\xe7\xe5\x9f\x24\xce\xf2\xdb\xda\xf8\x1c\xc7\xc9"
+  "\xd0\xbe\xbd\x73\x63\xde\x4d\x17\x7b\xe3\x5f\x81\x77\x75\x88\x2b"
+  "\x57\x6c\xaf\x4a\xd3\x3c\xbd\xe6\x97\x9a\x94\xc4\x54\xdc\xbe\xb2"
+  "\x72\x45\xaa\x66\xe5\xea\x84\x44\x37\x3f\xe5\xa1\xe8\xb3\x0f\xe3"
+  "\x7c\xa1\xef\x13\xc9\xa7\x7e\x7b\x5f\x1c\x0a\x90\xab\xf0\xad\x2c"
+  "\x33\x89\x66\xeb\x63\x9b\xb9\x3f\xef\x5a\xf4\x9d\xc2\xfd\xa4\x90"
+  "\x47\x5a\xc9\xc9\x8d\x92\x9f\x14\x23\xe4\xdd\xe1\xd9\x4f\xca\xa9"
+  "\x7c\xe6\x1f\x10\xf2\x71\x3f\x29\xa7\x8a\xa0\x9f\x3f\x44\xc7\xf0"
+  "\xb8\x12\x3c\xde\xd6\x49\xd9\x36\xb1\x2c\xe9\x66\x3e\xf6\xb2\xf8"
+  "\x5c\x46\x7f\x7f\xa7\x3b\xb7\xe3\xef\xa4\xf5\xd2\xed\xce\xdf\xb7"
+  "\x87\xf1\xf7\xb2\x7e\x90\xbe\x99\xbf\x13\xcf\x8f\x8e\x69\x85\x67"
+  "\x36\x7f\xcf\xde\xb5\xf3\xb9\xbc\x82\x9d\x3b\xb0\x4d\xd8\x6e\xf7"
+  "\xb6\x09\x3f\x6d\x25\xed\xcb\x9c\x6d\x6b\xcf\x77\xf1\xa5\x26\xb5"
+  "\xa1\xbd\x8a\xf7\xd1\x01\x6d\x65\xfb\x13\xa9\x6a\xe7\x0e\xfc\x36"
+  "\xca\x33\x7e\x66\x00\x9e\x0b\x76\x56\xca\xf5\x71\xa9\xdf\x0e\x1c"
+  "\xd7\x43\xfd\x8a\x39\x4d\x40\x7e\x00\x4f\xa5\x36\x2c\xa0\x39\x27"
+  "\x23\xd9\x1e\x78\x3c\x6b\x8b\x71\x42\x98\xae\x3a\xd5\x17\xff\x07"
+  "\x75\x14\x9f\xc3\x3c\xe5\xb4\xff\xd0\xc7\x55\x81\xac\xbf\x4e\xb9"
+  "\xd8\x7f\xfc\x9b\x90\x16\xef\x8a\x21\x97\xef\x6d\xc4\xef\x41\x3e"
+  "\xc2\xf7\xdd\xef\xac\xc4\xfe\x6e\x26\xed\x35\xb8\x17\x13\x7f\x8b"
+  "\x75\xf4\x14\x1b\xce\x93\x0f\x42\x27\x1d\x4f\x35\xca\x74\xdc\xcc"
+  "\x62\x14\x9d\x32\xcb\xf3\x75\xec\xdc\x0f\xe4\xd9\xdc\x17\x2b\xf9"
+  "\x34\xf3\x63\x4e\xf3\x7b\xe6\xde\xa9\x26\x4b\x39\x6d\x4f\x4f\x40"
+  "\x19\x8f\x7d\x86\xcb\xfa\xd3\xa9\x12\xcf\xa5\xbd\x62\xa7\xef\xc5"
+  "\x74\xe7\x3e\xf7\xd3\x9b\xe5\x7c\xb2\x5c\xe6\xeb\x55\xa7\x57\xb2"
+  "\x7c\x3c\x7e\x6d\x08\xe7\xf9\xf7\x42\x5a\xc9\xe9\x2c\x29\x3f\xf7"
+  "\x8f\xca\xfc\xdf\x9c\x2e\xa3\x05\xef\x87\x74\xe5\x9c\x86\xf1\xcf"
+  "\xc9\x18\x4e\x47\xfe\x5d\xb8\x67\x61\x5d\x90\x46\x78\x46\x9b\x16"
+  "\xf4\xcc\x05\xfe\xa8\x06\xd5\x73\x7c\xff\xf4\xcd\xa7\x49\x07\xb7"
+  "\x21\x04\x6a\xc3\x39\x56\xde\xd6\x8e\x49\x2e\x7b\x8c\xd5\x72\x1e"
+  "\x2e\xbb\xd9\x3b\xb6\x77\x5b\x97\x86\xf3\x41\xd2\xbb\x34\x3c\xc7"
+  "\xda\xf7\xff\x28\x97\xff\xfd\xf1\x7f\x9a\x46\xab\x36\xad\x63\xba"
+  "\x55\xe9\x3c\x23\xdf\x11\x06\xcf\xea\x7e\xcf\xa1\x6e\xcf\x6b\x49"
+  "\x38\xdb\x7f\x6b\xa5\x6d\x6c\xaf\xb6\x94\x2e\x95\x1d\xc0\xea\x93"
+  "\x46\xe7\x02\x36\xaa\xf1\xcc\xb3\xd4\x0f\xab\xf1\xac\x74\xb0\xfd"
+  "\x17\xec\x9c\x34\xbc\x9f\x23\xdd\x23\xa5\x7b\x04\x8f\x1d\xfa\x0f"
+  "\x97\xf8\xdf\x38\x47\xf3\x0f\xb3\xa7\x78\xe4\x72\xbc\x76\x39\x1e"
+  "\x39\x9e\xb3\x96\xe2\xa7\x2e\xee\xca\xe9\x08\x1b\x2a\xf6\x3b\xbc"
+  "\x9f\x2b\x9f\x99\x76\xe4\xef\x5c\x2c\xe6\xb7\x6e\xc1\x58\x95\xe8"
+  "\x67\xcb\xd0\x81\xbe\x56\xac\xc4\x44\x7a\x88\x29\xb5\x2b\x0b\xe3"
+  "\x55\x36\xd8\x98\xef\x62\x3c\x6b\xaa\xc0\x79\x73\xb4\x1d\x1b\x74"
+  "\x67\x58\xac\xca\x17\x3a\x48\xb8\xee\x3e\xda\x06\x34\x28\x73\x14"
+  "\xec\x5c\x2c\xe1\x68\x2b\xe8\xc0\x69\x40\x0b\x36\x5f\xcc\x62\x2d"
+  "\x77\xb0\x75\x2f\xd5\x09\x72\x26\x82\xe5\xa1\xf1\x5b\x39\xed\xce"
+  "\xb0\xb9\xaf\xd7\x72\xe4\x78\x84\x1d\x7d\xf1\x8f\xcd\xe4\x4c\xe4"
+  "\x85\x80\x0f\xd2\x21\xad\xdd\x7d\xcf\xf4\x19\x56\x26\xd6\xdd\x4c"
+  "\x3a\xb6\x63\xd9\x5d\x39\x67\xd4\x7d\x7d\x16\xd2\x5f\xb0\x93\xc9"
+  "\x50\xaf\x13\x72\xf9\xf0\x1e\xfa\xff\x69\xd6\x97\xb0\xcc\x0b\x05"
+  "\xc7\xa0\xdc\x33\x51\x66\x61\x43\x33\xdf\x73\x7d\x06\xf4\xdf\x7f"
+  "\x56\x0f\x65\x03\x41\x5f\x88\x82\xbe\x14\x23\xe6\xbf\x3f\x97\xfb"
+  "\xc2\x7e\x3f\x8a\xcf\x31\x9e\xd9\x8a\xfb\xba\x36\x5d\x24\x4a\xdc"
+  "\x03\xc1\x31\x7b\x86\x9f\xef\x81\x34\x90\xd5\x95\xd0\x47\x98\xad"
+  "\x38\x3c\xbd\x7f\x86\xf9\xf8\xd9\xd4\x49\x54\x25\x29\xb2\x2f\xef"
+  "\x33\x56\x97\xf8\x03\xd2\xf9\x92\xb3\x53\x71\xa5\x7c\x53\x0f\xaf"
+  "\x63\xff\x3a\x60\x7d\xa1\xac\x2d\x1e\x6d\x4c\xd5\xfb\x73\xd9\xfa"
+  "\x4c\xe1\xbb\x31\x7c\x8f\xea\xd9\x44\xbf\xb0\x29\x2f\x77\xe5\x9c"
+  "\x5d\xda\x17\x77\x01\xf2\x94\xe0\xde\x7b\x28\xbf\xaf\x9d\x29\xf8"
+  "\x8d\xb3\xf9\xbc\xaf\x9f\x2d\x13\x0b\xde\x47\x7f\x08\x4a\x29\xbd"
+  "\xac\xc1\x6e\x43\x1f\x0b\x83\xfa\xa9\x62\xf1\xdc\x70\x4f\x78\xe1"
+  "\xfb\xe8\x23\xcc\x7a\xa7\x4d\xae\xf3\x37\x65\x78\x2e\x04\xeb\xcc"
+  "\x69\xfb\xcd\x4b\x32\x1d\x8b\x3b\xa1\x6c\xfd\x57\xa4\x8d\x7c\x33"
+  "\x09\xf7\xcd\xe1\x39\x27\xec\xc3\x9c\x06\xdf\xb0\x31\x1f\xfb\x3e"
+  "\xcb\x73\x96\x8d\xfd\x59\x6c\x1d\x28\xbf\x9c\xc5\x07\x83\x36\x00"
+  "\x2f\x8c\x7a\x3c\x5b\xff\x0d\x3b\xe3\xb3\x3e\x85\xf0\x76\xb3\x7d"
+  "\xb2\xdf\x48\xeb\x24\xdf\xc4\xcb\xba\xc2\x2c\xa5\x6d\xc2\x6f\xa7"
+  "\xf5\x90\xb3\xe4\x9b\xbb\x31\xee\x37\xd0\x23\x06\xfd\xbb\x35\x58"
+  "\xa1\x9f\xa4\xf7\x20\x16\x62\x30\x9e\x24\xe4\x9f\xcb\xf5\x1b\xd2"
+  "\xfc\x9b\x70\xfc\x3e\xd2\x16\x78\x67\x01\x9a\x6e\x87\xb2\x77\xc9"
+  "\x34\x2d\x99\x88\xe3\x9d\xb3\x8d\x43\xe9\x06\x07\xd4\xb9\x01\x38"
+  "\x67\x9c\xfc\x15\xd4\xcf\x92\x29\x8e\x79\x7f\x2e\xee\xc9\x86\xff"
+  "\xa5\xb3\x69\x9c\x77\xbc\x2f\x59\x9e\x80\x6f\x98\x70\x7f\x03\xca"
+  "\x4a\xf4\x41\x06\x6d\xb2\x4b\xf4\x63\xf1\x18\x4a\xd3\x38\x1d\xa4"
+  "\xfc\x55\x7c\xbe\x78\xca\xc1\xae\x1c\x4b\xac\x73\xbe\xd8\xc2\x74"
+  "\x37\xe2\xad\x9c\x8d\x09\x2d\x49\x2e\x75\xb6\xb2\x73\xa6\x9d\x38"
+  "\xd7\x67\x09\xc1\x6f\x15\xa3\xff\x2d\xc4\xc5\x69\x57\xfc\x7f\x73"
+  "\x0e\xeb\x89\x7b\x7e\x1d\x01\xef\xc6\x80\xbe\x8d\x45\x3a\xc3\x6f"
+  "\xb4\xd0\x17\xe6\x0e\xa1\x0b\x59\x2c\x38\xf8\x66\x8b\xac\x0b\x61"
+  "\x7c\x01\x7a\xe1\xdc\x41\x36\xee\x04\x7b\xda\x24\xa2\x3d\x73\xae"
+  "\x09\x71\x03\x7d\xbd\x42\x92\xb1\x15\x5d\x39\xe7\x42\xe4\x35\x2f"
+  "\x07\x9e\x9b\x38\xcb\xd6\x7b\xad\x72\x8c\x33\xee\xef\xee\xdc\x1c"
+  "\xe7\x39\x8b\x73\x51\x03\xce\x59\xe0\x19\x9b\x97\x59\x2c\xac\x1d"
+  "\xa8\x53\xea\x3b\xda\x50\x47\xb0\xdf\xe3\xd9\x0b\x3d\x8c\xc9\xf9"
+  "\x39\x9d\x36\x9c\x9f\x67\x31\x43\xb0\x2e\x3c\x76\x43\x2b\xfb\x1f"
+  "\x70\xab\xc4\x3b\xc7\xd2\xb9\xed\x7d\x71\xbc\x81\xdf\xb8\xd6\xb6"
+  "\x47\xf9\x43\x62\xbc\x15\xf5\xf5\xb9\x83\x18\x93\x1a\xf2\xd4\xca"
+  "\xf1\xa8\x59\xfc\x69\xde\x9e\xcd\x1e\xfd\x1a\xce\x26\x91\x78\x2e"
+  "\x1f\xcf\xb1\x31\x1a\xa8\xba\x9b\xd1\x57\x32\xfa\x7d\x34\xae\xc3"
+  "\x98\x26\x9d\x1b\x7f\x3b\x91\x9d\x05\xb6\x1a\x67\x77\xe2\x3e\xac"
+  "\x8e\x13\x19\xcc\x9f\x91\x2a\x2e\xdd\x4e\xf1\x77\xcc\x9e\x08\xe8"
+  "\x6e\xc6\x77\x2c\x56\x00\x96\xe9\xb3\xdf\xdf\xce\x85\x92\x6d\xda"
+  "\x01\x72\xff\xa6\xd3\xa4\x93\xd9\xee\xf0\xff\xc4\xd3\xe4\xfc\x9b"
+  "\x3c\x2e\x2a\xf7\x5d\x2f\xed\xc7\x1e\xc5\x7d\x59\x00\xcd\x98\x6f"
+  "\x81\xf3\xb7\x68\x6e\xc7\x18\xc2\xe7\x67\x30\x3f\xd2\xf9\x3b\xab"
+  "\x24\x1a\x54\x6d\xe2\xf5\x0a\x5e\x92\x2e\xb0\x3a\x62\xfd\x86\x59"
+  "\xb7\x0e\x69\x1c\x31\xaa\x2b\xe7\x7c\xa4\xec\x03\x83\xdb\x53\xdc"
+  "\xbf\x34\xe7\xc5\xf9\x6d\x92\xfd\xbc\x4b\xfa\xf6\xae\xcb\xff\xf6"
+  "\xf9\x24\xa9\xcc\x7c\xee\x63\xbb\x33\x14\xca\xcd\x87\x7a\x54\xcb"
+  "\xe3\x19\xe9\x0c\x51\x04\x1f\x67\x9d\x6f\x74\x8e\x67\x38\x0d\xdd"
+  "\xce\xb7\xad\x5e\x9d\xaa\x49\x58\xf1\xbc\x6e\x59\xea\x33\x49\x9a"
+  "\xc4\x94\x94\xd5\x29\x1a\x74\x72\xe4\xda\x7f\x78\x1c\xa0\xf3\x6d"
+  "\x52\xcc\xbc\x4a\x67\xcc\x3c\x6b\x84\x6b\x9c\x49\x33\xb1\x46\x8e"
+  "\xcc\xdc\x85\x35\xd6\x53\x39\xa5\x82\x58\x05\x57\x35\x5c\x46\xb8"
+  "\x6a\x71\x2e\x63\x89\x8d\x44\x81\xae\x67\x32\xcf\xe9\xdb\xc1\x8a"
+  "\x7e\x40\xa3\x5a\x89\xf5\x8d\x72\x51\x49\x98\xaf\x9e\x1c\x11\xe3"
+  "\x2e\xa0\x3f\xf4\x6a\xb8\x8c\x70\xd5\xc2\xc5\x7e\x27\x7e\xc2\xce"
+  "\xa5\x57\xb9\xbe\xe3\xfb\x47\x32\xeb\x30\x0f\xcd\xc6\x21\x22\xe4"
+  "\xfb\x0d\xcf\xd7\xaf\x0e\x02\xcd\x39\xb3\x54\xca\xc7\xc6\x92\x41"
+  "\xd9\x44\x33\x48\x3e\x3f\x9a\xd3\xb6\x58\xca\xc7\xf6\x1d\xcb\xed"
+  "\x41\x5f\xfd\x90\x5f\xce\xa7\xa4\x39\xe7\xda\xa5\x7c\x6c\x8f\x9c"
+  "\x98\x23\x0c\xf6\x5d\x7f\x9a\xf3\x3f\x49\x52\xbe\x10\xd7\xf2\x5c"
+  "\xf2\x8c\x12\x73\xbe\x42\x9f\xf8\x8d\x62\xb6\x32\x94\xdb\x4e\xd6"
+  "\x58\xc8\x3f\xa8\x8f\xd3\xe1\xf1\xe9\x82\xb5\x3f\x9f\x74\xcf\xac"
+  "\x48\xbc\x67\xc5\xaa\x34\x8c\xd4\x94\xba\x7a\x4d\x2a\xde\x57\x2d"
+  "\x7b\x96\xdd\x56\x2f\x59\xfe\x0c\xff\x27\x35\x39\x12\xff\x49\x06"
+  "\xbc\xe1\x3d\x61\x8d\x0e\x6f\xcf\xac\xc6\xc7\xf4\xa4\x88\x35\xcf"
+  "\xc8\xe1\xe9\x5d\x71\xa8\xed\xca\xb9\x58\x06\xd8\x28\xe2\x72\xf6"
+  "\x22\xe8\xc5\x63\x6c\xbf\x17\xc6\x23\xda\xab\xb5\x13\x79\x5e\xcb"
+  "\xdd\xb7\xc7\xc5\xbf\xa0\x6f\x8f\xe0\x6c\xdd\x33\xc1\xf6\x15\x89"
+  "\xa0\x33\x32\xe0\xb7\x6d\x66\xf2\x4b\x9b\x24\x1b\x8d\xcc\x4f\x68"
+  "\xce\xc5\x39\xd2\xde\x4e\xa5\x98\xbf\x33\x15\xfd\xdf\xc3\x33\x8b"
+  "\xfd\x0c\xcf\x15\xf0\xbc\x1b\x9e\x31\xe6\x73\x28\x3c\x67\xe0\x9c"
+  "\x14\x3c\x87\xc1\x73\xb8\x98\xbf\x3d\x1f\xcf\xf2\xc2\xb3\x06\x9e"
+  "\xa7\x77\xe5\x74\x45\xcb\xfd\x62\x70\x5b\xb9\x2b\x41\x8e\x47\xcd"
+  "\x63\x4f\x77\xa5\xf6\xc5\x9e\xc6\x78\x48\xfa\x90\xc5\x4c\xff\x32"
+  "\x1b\xa4\x6b\x8b\x5f\xd8\x54\x2c\x73\x8b\xac\x2f\xf9\x7c\x47\x57"
+  "\xa5\xec\xa7\x84\xcf\x67\x74\x55\xbb\xc4\xf0\xc6\xe7\x5a\x39\x86"
+  "\x37\xce\x77\xb1\x18\x82\x70\xa7\x39\xe8\x8f\x95\x0e\x3e\x97\xc7"
+  "\x62\x4f\xda\x66\xa1\x6f\x5b\x8b\x21\x41\x71\x5b\x39\xce\xa1\xc1"
+  "\x33\xf7\xcd\x48\xcf\x92\x2e\xe6\x6b\x44\xf6\xdb\xe6\xea\xb3\x61"
+  "\xd0\xf3\x50\x9f\x81\xcd\xc0\xe2\x45\x25\xaf\x0e\xb6\x2f\x4b\xe4"
+  "\x76\xa0\xad\x98\xcb\xaf\x77\x93\xb9\xbd\x60\x4b\xa7\x8f\xf3\x98"
+  "\x22\x66\x62\xb3\xe3\x98\x25\x58\x91\xbc\x9a\xc2\x6f\x83\xd3\x97"
+  "\x25\xb2\x34\xc8\xb7\x1e\x6c\x35\xa9\x7e\xbf\x30\x85\xe3\x59\x52"
+  "\x51\xf2\x45\x61\x5b\xfc\xd4\xd4\x2c\xfc\x8e\x8a\xd9\x21\x9f\x11"
+  "\x35\xc6\x80\xc4\xba\x95\xbb\xf8\x95\xdb\x04\x69\xb8\x87\xf4\xfc"
+  "\xe3\x44\x8d\x7e\x74\xa5\xba\x2c\xe6\xf1\xb7\x6c\x56\xd9\xa7\x13"
+  "\x7c\x6f\x71\xff\xf6\x3c\xfe\x13\x86\xca\x19\xcf\x44\x2c\x9c\x0f"
+  "\xff\x45\x48\x61\x94\x5d\xb1\x19\x7e\x7e\xcc\x7b\x73\xcf\xff\xe1"
+  "\x47\xa3\x79\xac\xcc\x6e\x18\xff\x77\xb5\xb3\x3d\x2c\x38\x2e\xe9"
+  "\x8a\xdf\xc2\xf7\xa0\x76\x67\xa2\xdf\x5a\x31\x07\xed\x49\x3c\x9f"
+  "\xdc\x9d\x8c\x98\xa5\xaa\x77\x75\xaf\x65\xa2\x8f\x64\x05\xd0\xb8"
+  "\x7b\x19\xbe\x93\x7c\x63\x09\xcc\x97\x94\x83\x84\xb1\xb3\xb8\x60"
+  "\xa3\xe0\x19\xd4\x13\xc4\xbe\x12\xed\x0e\x9c\x4f\x12\x73\xba\x55"
+  "\x88\x5b\xe0\x31\xfa\xea\xb0\xd2\x31\x3b\x97\xd2\x80\xea\x50\xc4"
+  "\x31\xda\xba\xa6\x10\xa4\x59\x77\x13\x7c\xf7\x21\xb8\x7e\xca\x63"
+  "\xb7\x3c\xd9\x2e\x97\x89\xfe\xcb\xc0\x86\xca\x80\x3b\x8c\xb7\xbb"
+  "\xed\x2e\x31\xed\xa4\xb3\xc7\x3d\x53\xd1\xaf\x1a\x96\xcd\x6d\x67"
+  "\xfb\xcf\xb8\x0d\xd2\xa3\x35\x93\xe0\x52\xde\x17\x7b\xc0\xfe\xc9"
+  "\xad\x94\xfe\x07\xfb\xe7\xfb\x0b\xfb\x95\x51\x20\xcf\x95\x72\x4c"
+  "\xf7\x24\x00\x46\x1f\x82\xeb\xa7\x90\x5f\x27\xc7\x6d\x5f\x2f\xb0"
+  "\x73\x92\x27\xfc\xc2\xf0\x5c\x79\x4f\xbe\x9c\xee\xaf\x88\x02\x9a"
+  "\xf6\x6c\x91\xfb\xfe\xf9\x31\xef\x2e\x82\xe7\x4a\x79\x8e\x85\xcf"
+  "\xb9\xf4\x54\xbb\x3c\x2f\x85\xe7\x5a\xf9\x19\xfe\x6f\x92\x65\x05"
+  "\x8e\x13\xcf\xc3\x58\x12\xc7\x9d\xcf\x84\x81\x5d\x18\x86\xe3\xbc"
+  "\x1e\xe0\x7f\x6e\x12\xcf\xdb\x0b\x36\x68\xc1\x74\xe9\x7f\xb5\x59"
+  "\xd8\x68\x97\xdb\x22\xe6\xf8\x05\xf3\xf6\xd8\xa3\xc5\x82\xd6\x2d"
+  "\x96\x80\x9d\x1a\xc8\x03\xfa\xbf\x8b\xb7\x37\xed\x4c\x45\x51\x4f"
+  "\xc8\x22\xdc\xf1\x68\x5c\x8e\xf8\xb2\xb3\x7d\x58\xc5\xeb\x42\x16"
+  "\xa2\x8d\x89\xbe\x35\x98\x1f\x3c\xf4\x05\x69\x27\xa3\x98\xff\xfd"
+  "\x82\xd6\x7c\xe6\x77\xfe\x05\xad\x5a\xf6\x03\x09\xb2\x25\x94\x0a"
+  "\xc9\xa1\xe8\x1b\x92\xc5\xd9\xe8\xd2\x06\x31\x7f\x90\x92\x1f\xc8"
+  "\x6d\x69\x24\xb4\x4c\xe4\x7e\x20\x99\xdf\x8d\x51\x30\x26\x49\x1b"
+  "\xdc\x17\x24\xcd\xf9\xe3\x6e\xd9\x17\x24\xbd\xe8\xb0\xc1\xff\xd3"
+  "\xa1\xed\x18\x7f\x5c\xcb\x9e\x9d\x3e\x9c\x94\x83\xfa\x86\x14\x40"
+  "\xc6\x09\xdc\x37\xe4\xf0\x74\x83\x3d\x84\xe3\xc4\xbe\x50\x8e\x2b"
+  "\xef\x92\x06\xf2\xcf\x26\xc5\xc6\xea\x09\x97\xd2\xd2\xcd\x64\xe3"
+  "\x6e\x69\x7f\xa5\x05\xe7\xc8\x36\xb3\x79\xb0\xee\x0a\xda\x9b\xb4"
+  "\x75\x30\xf9\xd2\x39\xc6\xbe\xb0\x93\xf9\x7c\xb0\x03\xef\x1d\x4c"
+  "\xd6\xf1\x71\xa3\xbd\xba\x7f\x1f\x7e\xfa\x99\xd5\x09\x89\x4b\x7e"
+  "\xb5\x52\xa7\x79\x7c\xd1\x43\x2c\xa8\x60\x84\x66\x45\x6a\x22\x53"
+  "\x3f\x9a\xc7\xe7\x3f\x18\x17\xb7\x68\xc9\x4f\x16\x3d\xb0\xe8\x89"
+  "\x9f\xdc\xcb\x4f\x27\x2e\x4a\x59\x8b\x81\x29\x53\x57\x6b\xf0\x47"
+  "\x4f\x4b\xd1\xac\xd7\x25\xa6\xac\xee\xdf\xf7\x43\xd9\x9c\x96\xc0"
+  "\xe6\x6f\xad\xf8\x3f\x9f\x37\x73\x2c\x92\xe7\xb3\xb8\x9c\x73\xcc"
+  "\x47\xda\xb2\x38\xa1\x39\xf6\x3a\xb4\xa5\xa4\x38\xe3\xa8\x63\x94"
+  "\xd8\x7f\x51\xd7\x74\xe5\x38\xb2\x5c\xfd\x5d\x49\xbf\xdd\x2e\xe0"
+  "\xef\xa4\x7e\x2b\xa5\xbd\x47\x27\x4f\x36\x70\x9f\x55\x8e\x5d\xf2"
+  "\x1c\x37\xa6\xc9\x75\x68\xc5\x3c\x39\x76\x87\x33\x9e\xad\xa3\xc5"
+  "\x19\xb3\x91\xfd\xb9\xd1\x88\x10\x34\x5d\xfc\xc1\x2e\x19\x05\xd7"
+  "\x68\xbc\x62\xfa\x64\x79\x1a\x6d\xc6\xf1\x59\xb0\x02\xf4\x6d\xba"
+  "\x1f\x8f\xf9\x94\xdb\xc4\xe2\x14\xc4\x39\xec\x7e\x4b\x1c\x02\xdc"
+  "\xfd\xe8\x12\x87\x92\x8d\x09\x69\x1a\x6d\x62\xe7\xea\xd3\x68\x23"
+  "\xc6\x36\x03\x1c\xe7\xc7\xd9\xf5\xe8\x83\xcc\xbe\x04\x6c\x75\xb8"
+  "\x9f\xc4\xf3\xe1\x71\x8e\x93\x94\xc5\x77\xc1\x73\xf4\xdc\x77\x5f"
+  "\x2d\xee\x97\x7c\x0a\x30\x5c\xde\xc9\x63\xe2\xc6\xad\xfd\xe6\xc8"
+  "\x92\xb5\x66\x1e\x13\xf7\x2c\x8f\x23\xcd\x63\x6d\x13\x3d\x94\xb3"
+  "\x6f\x89\xc3\x4f\x13\xe7\xe8\xa5\xfc\x8c\xab\x68\x1c\x2a\xce\xed"
+  "\xa0\x73\x15\xb9\x9f\x25\xd1\xe2\xcc\xe9\x34\xf7\xe0\x5c\xb8\x6f"
+  "\xa7\xf9\xd5\x38\x96\x55\xd0\xdc\x66\x15\x2d\xd6\x43\xfa\x57\xcd"
+  "\x70\xdf\x4e\x73\x0f\x57\xd2\x62\x03\x3c\x9b\xd3\xe1\x0e\xcf\xef"
+  "\x47\x41\x7e\x0d\xcd\xdd\x8d\xbf\xab\xa0\xb9\x1f\x44\x42\x3e\x78"
+  "\xfe\x50\x0b\x77\x78\xfe\x48\x03\xf9\xe0\xd9\x18\x76\x82\xd0\x0d"
+  "\xf0\x3f\xa4\x1d\x8b\xe1\xdf\x3a\x11\xc3\xbe\x95\x7b\x2a\x86\x7f"
+  "\xa3\x23\x86\x7f\xe3\x9b\x18\xfe\x8d\xce\x18\xfe\x8d\x8f\x43\x20"
+  "\x9f\x96\xe6\x7e\x92\x05\xf7\x4a\x9a\xbb\xc7\x02\xf9\xe0\x79\xef"
+  "\x52\xb8\xc3\xf3\xff\x36\x42\x3e\x78\xae\x85\xba\x18\xe0\x79\x5f"
+  "\x15\xe4\x8b\xa0\xb9\x07\xa6\xc3\x7d\x07\xcd\xad\xdb\x02\xf9\xe0"
+  "\xb9\x41\x0d\x77\x78\x36\x41\x39\x06\x78\x6e\xb4\xc2\x1d\x9e\x2f"
+  "\x60\x3d\x22\x69\xee\x45\x28\x37\xb3\x8a\xe6\xda\x30\x3f\x3c\xf7"
+  "\x40\x79\x7a\x78\xee\x6d\x87\x7c\xf0\xec\x28\x85\x3b\x3c\x53\x6c"
+  "\xeb\x1c\x5a\x48\xda\xe0\xbe\x8b\x16\x0a\x90\xae\x87\x67\xe5\x3c"
+  "\xb8\xc3\xb3\x3f\xe6\x87\xe7\xd1\x9b\xe1\x0e\xcf\x01\x48\xa3\xb9"
+  "\xb4\x70\x6c\x05\xdc\xab\x69\x61\x10\x81\x7c\xf0\x1c\x82\xf5\x87"
+  "\xe7\xf1\x46\xc8\x07\xcf\x13\x90\x56\xf0\x7c\x13\xb6\x73\x1e\x2d"
+  "\x9c\x84\xe5\xef\xa6\x85\xe1\x48\x17\x78\x9e\xb6\x03\xee\xf0\x7c"
+  "\x0b\xd0\xc3\x00\xcf\xb7\xa5\xc2\x7d\xf7\xa0\xfc\x2c\xfc\x2e\xd8"
+  "\xb7\xa3\x08\x2d\x9c\x6d\xa4\xd9\xa3\xe1\x1e\xa9\xa3\xd9\xfe\x5a"
+  "\x5a\xf8\xaf\x60\x27\x8f\x82\xfb\xf7\x63\xe0\x39\x42\x7a\x86\xfb"
+  "\xbf\x68\xe0\x39\x52\x7a\x86\xfb\xbf\xd8\xe0\x79\x8e\xf4\x0c\xf7"
+  "\xbb\xb2\xe0\x19\xea\xf8\x83\x78\x78\x86\xfb\x5d\x1d\xf0\x3c\x4f"
+  "\x7a\x86\xfb\xdc\x70\xb8\xdb\x2d\x53\x1f\x6e\xb7\x04\xc6\x56\x58"
+  "\x02\xb3\x43\x50\x6f\x3b\x4a\x32\x35\x62\x50\x66\x05\xe8\xcd\x51"
+  "\x86\x0b\x64\xf4\x09\x85\x70\x37\xca\x09\x53\x86\x99\xc5\xc2\x93"
+  "\x7c\x41\x8e\x6a\x55\x28\x16\x80\x8d\x33\x17\xe4\xb2\x00\x6d\x5e"
+  "\x4c\x73\xfc\x3b\xe1\xde\x42\x73\xc6\xb6\x42\x9b\xe1\x79\xdc\x67"
+  "\x70\x87\xe7\x1f\x14\x42\x9b\xe1\xf9\xc9\x07\xe1\xde\xd2\x95\xab"
+  "\xd8\x61\x26\xa2\x99\xf5\xfb\x3f\xfc\x08\x64\xb8\x81\xc6\xd9\x41"
+  "\x1f\x6c\xcd\x6b\x0c\xb6\x2f\x05\x3a\x67\xc3\x98\x57\x43\xe8\xb6"
+  "\x18\x2d\x0d\x5a\xc0\xea\x84\x71\x69\x68\xef\x74\x81\x7f\x7b\x2c"
+  "\x85\x6f\x1f\xc2\xf8\x09\x34\x28\xd1\xd3\xfb\x6e\xf6\x7e\x72\x9e"
+  "\x99\xbf\x0f\x21\xce\xf7\x3f\x85\xf7\xc2\xa4\x60\xf4\x43\x3e\xed"
+  "\xff\x99\xcd\x0a\x01\x6d\x1b\x62\x56\x28\xa0\x8e\x7e\xc4\x64\x6d"
+  "\x97\xda\x38\x1a\xf3\x3d\x80\xbf\xf3\x34\x47\x23\x16\xe5\xaa\x8a"
+  "\x41\x6e\xe1\x98\x15\xf4\x97\xa0\xd1\x4f\xaf\x6e\x55\x28\x43\xb6"
+  "\xa1\x4d\xa3\xce\xab\x64\xf2\x4c\x21\x1c\xec\x2d\xac\x5e\xac\x59"
+  "\x17\x0c\xe5\x29\xc7\x19\x6c\xd4\x6a\xd4\x3f\x48\x4e\xf0\xf4\x2d"
+  "\xec\x7c\x0f\xff\x7f\x03\xdb\xb7\xc9\xff\xd7\xb1\x39\x62\x28\x0b"
+  "\x7f\xeb\x3a\x46\x70\xe4\xde\x51\x26\x06\xe5\x55\xb1\x75\x6f\x85"
+  "\x70\xe8\x03\xd1\x2c\x04\xa7\x12\x7f\xcd\xba\x8f\xa0\x7c\x3f\x8d"
+  "\xdb\x78\xb2\x2f\x2f\x7b\xe7\xff\x21\xe4\x7d\x15\xe7\x7e\x72\xfd"
+  "\x22\xfb\xe2\x07\x43\x1b\x7e\x8d\xba\x4b\x20\x51\xa8\x4f\x99\x7d"
+  "\xaa\xf0\xab\x42\xbf\xb0\x76\x75\x76\xa9\xbd\x28\xb6\xd4\x51\x94"
+  "\x57\x49\x4b\xf2\xaa\x82\xec\x0a\xc2\xf6\xd7\x2b\xfc\x8e\xdf\x69"
+  "\x43\x7b\x70\x3f\xe6\xdd\x26\x8e\x9a\xd3\x38\x3b\x9d\x08\xc6\x94"
+  "\xaf\xf0\xf9\x30\xcd\xbd\x27\xc6\xd4\xd1\x4c\x8c\x29\xac\xac\x16"
+  "\x9a\x3b\xbf\x4e\x1c\x75\x7f\x53\x39\xda\xd5\xe9\x38\x2f\xf6\x19"
+  "\xa6\x2f\x03\x3a\x2b\xa1\x2e\xbb\xfb\x62\x5b\x03\x2d\x8b\x81\x76"
+  "\x68\xf3\xa2\xaf\x8a\x25\x0e\x07\xfa\x58\xcb\x37\x2b\xf8\x38\xd1"
+  "\xac\xf0\xab\xc0\xb8\xe0\xd2\x77\x2f\x88\x63\xaa\x63\x1a\x16\xe3"
+  "\x1a\x5f\x08\xfa\xac\xb2\xb2\xf3\xed\x76\x8c\xf7\x07\xba\x42\xca"
+  "\xeb\xca\xbb\x95\xcf\xe8\x96\xac\xd3\xad\x4e\x49\x5d\xb2\x46\x77"
+  "\x8f\x06\x06\x7a\x9a\xd5\xcb\x35\x2b\x13\x57\xae\x4e\x59\x3b\xc0"
+  "\x4f\x4e\x57\xae\x72\x11\x60\x83\xf9\xec\xdc\x07\xf6\x36\x9b\x6f"
+  "\x57\x8c\x9a\x8e\xbc\xde\xfa\x32\x8f\x2f\x01\x79\x40\xff\x27\xb1"
+  "\xf1\x8c\xb8\x25\xaf\x96\x96\xc5\x68\x0b\xd0\x47\xc7\x1a\x8c\x5f"
+  "\x60\x21\x26\xd2\xc9\x63\xce\xb2\x78\x72\x60\xff\xa7\x65\x52\x63"
+  "\x5a\x27\x62\x1c\x64\x72\x56\x35\x60\x5c\xd7\x5d\xbc\x40\xd5\xaa"
+  "\x18\xa5\xea\x2e\xce\xaa\x94\xe3\x01\x39\x8a\xb2\x55\xa2\x3a\x57"
+  "\x83\xf1\x80\x7a\x69\x18\xa9\x07\x5a\xf6\xe4\x57\xcf\x01\x19\x1f"
+  "\xb9\x2d\x87\x56\x3b\x60\x3c\xc4\x7c\xf1\xfc\x21\xc6\xec\xa0\x5a"
+  "\xa5\x23\x87\xa8\xe0\x1e\x44\x83\xf2\x16\xf6\xaa\xb3\x2b\xf0\x3d"
+  "\xc6\x01\x72\xf4\x6a\x89\xbe\x89\x8a\x3f\x4f\x02\xdc\xe4\x10\xca"
+  "\xe2\x9e\x26\x9d\x21\x90\x3e\x46\x2c\xc9\x8e\x3c\x11\x43\x04\xcc"
+  "\x0b\xf6\x19\x59\x0c\xff\x67\x2c\x23\x81\x90\x2f\x38\x63\x1f\xa4"
+  "\x77\x69\xc7\xd8\x0d\x5a\x55\x8f\x41\x3b\xa6\x97\x6a\xd5\xa6\x36"
+  "\x1b\xe9\x9d\x11\x63\x99\x65\x21\xca\xad\x60\xc7\x6d\x13\xa1\x7f"
+  "\x95\xc5\x84\x38\x5e\xd4\x8e\xb2\xbf\xa8\x55\xf6\xf6\x6a\x55\xf6"
+  "\x17\xb4\xca\x9e\x17\xb4\xa3\x7a\xbb\xb4\x2a\x53\x82\x85\xec\xb7"
+  "\xfc\x37\x69\x68\x6b\x67\x73\xb2\xbd\x81\x79\x8b\x7b\x03\xb3\xe7"
+  "\xa9\xdb\x48\xe8\x6c\x1d\xd8\x71\x60\xcb\xbe\x02\x76\x3c\x60\x42"
+  "\x6d\xff\x7d\x8c\x99\x16\xe7\x01\x7d\xfd\xcf\xcc\x9f\x49\xbf\x71"
+  "\xe4\x8e\xd9\xa5\x79\x04\x64\x11\x8c\xf7\x21\x0d\xf0\x73\x13\xe8"
+  "\x96\xef\x24\xc3\xf8\x1f\x64\x96\x52\x63\xe6\x7c\x20\x34\x37\x20"
+  "\x09\xe7\x04\x30\x2f\xcf\x17\x5c\x6d\x66\x77\x35\x8f\x4f\x9a\xab"
+  "\x0c\xdf\x86\x36\x44\xee\x28\x8d\x6c\x43\xd4\x28\x07\xf7\x03\x02"
+  "\x79\xa2\xfb\xc6\xd7\x22\xc8\x93\xe2\x4c\x8f\x71\x4f\xd1\x87\x31"
+  "\x2d\xc9\x8c\x2a\x15\xfb\x7c\x1e\x83\x3c\x1c\xb5\x12\xfa\x0f\x8b"
+  "\xdb\x41\x8b\xb2\xab\xf4\xe7\x88\x1f\xbe\xab\xba\x68\x13\xf0\x59"
+  "\x93\xa2\xa0\x26\xab\x8d\xc0\x6f\x94\x34\x3c\x46\x5b\x75\xd1\x22"
+  "\x20\x5e\x1a\x20\x0d\x7e\xbb\xb1\xf4\xa2\x54\xee\x96\xbc\x46\xc3"
+  "\x73\x84\xc5\xf8\xc0\x38\x41\x88\xa3\x52\x3d\x8c\x0f\x31\xa6\x51"
+  "\x8a\x1f\xf4\xe3\x51\x1f\xc3\xff\x2a\xcc\x47\xd5\xd9\x55\x22\x94"
+  "\x01\x78\x0a\xa3\x81\xd9\x5b\xc4\xe2\x6c\x0d\xdd\xf6\xb0\x99\x4e"
+  "\x8d\xc9\x17\xb7\xe6\x55\x77\xe5\x8e\x0e\x03\x5a\x45\xca\xf3\x0d"
+  "\x0d\x95\x76\x82\x3e\xac\xe8\x83\x76\xb2\x37\xf5\x02\xfa\xb9\xf5"
+  "\xb3\x04\x54\xcf\xb5\x04\xe6\xaa\x2c\x81\x79\x44\x2c\xce\x8d\x81"
+  "\x2b\x56\x97\x42\xd4\xa7\x15\xa3\x5b\xfa\x7c\xb0\x9e\xbb\x4e\x7c"
+  "\xb0\x82\x5d\xc6\xec\x33\xc0\x0e\xda\x5b\xd0\xde\x7c\x8c\xd5\x81"
+  "\x76\x18\xca\xdc\xae\x5c\x95\x4a\xb6\xa3\x50\x8e\x38\x0a\xaa\xa3"
+  "\xe1\x8a\x82\x74\xc0\xcc\x94\x68\x59\xc6\xd0\xa0\x58\xa3\x58\xf8"
+  "\xc0\x8e\x2e\x3c\xff\xd4\x9b\x74\x3f\xe6\x05\xba\xe1\xba\xb2\x9f"
+  "\xa3\x37\x69\x1e\x5c\xf7\xc2\x75\x9f\xa3\x38\xbb\xd4\x51\x9c\x55"
+  "\xe5\x28\xce\x35\x3b\x8a\x63\x6b\xe0\xaa\x85\xab\x0e\xae\x46\xb8"
+  "\x9a\xe0\x02\x1b\x2b\xb6\x05\xee\xf8\xbe\x0d\xae\x76\xb8\x3a\xe0"
+  "\xb2\xc0\x65\x75\x6c\xcd\x33\x8a\x80\x4f\xb8\x34\x70\x85\x43\x39"
+  "\x83\xce\x5f\xd1\xfc\xa3\xd5\x2c\x26\x81\xff\x11\x1a\x8c\x31\x6b"
+  "\x33\x2e\xa0\x7f\xc5\xea\xbd\x5a\xeb\xf0\x7c\xb3\x2b\x54\x1e\xd7"
+  "\x50\xb0\x7c\xe8\x5b\xbd\xc3\x2b\x2f\x40\xe3\x71\x9e\x24\x2c\xaf"
+  "\xd6\x1e\x1e\xa3\xb3\xe7\x90\x2c\xe8\xcf\x8a\x86\xa5\x6d\x24\xce"
+  "\x42\x0c\x75\x6d\x3d\xc4\x90\x20\xf9\x51\xcf\xc0\x33\x27\xc9\xa1"
+  "\x88\x61\x07\x8d\xd7\xf4\x16\x65\x55\x3b\xd4\x1b\xcd\x54\x9d\x1b"
+  "\xc6\x7c\x36\x82\xec\xc1\x18\x60\x7d\x63\x48\xc4\x14\x8c\x23\xeb"
+  "\x3b\x2e\x90\x17\x13\xa8\x58\x9f\x04\x36\x47\x33\x80\x4b\x41\x5e"
+  "\x47\x7c\xc9\xe3\xc8\x47\x5b\x68\x16\x60\x25\xc0\x01\x74\x13\x71"
+  "\xfc\x08\xb8\xc2\xb1\xa4\x8c\x2d\xd0\x65\x21\x72\xdc\x24\x3a\x4a"
+  "\xb5\x0b\xde\x29\x31\xae\x52\x19\x8c\x1f\xcb\xd2\xc8\xf4\x32\x78"
+  "\xc7\x62\x60\x42\xbd\x1f\xd3\x05\x53\xf1\x59\x2d\x29\xff\x15\x51"
+  "\x05\x9e\xe1\x71\x55\x1d\x40\xfb\xbe\xd8\x02\x45\x0b\x54\x0b\xce"
+  "\x68\xc8\x5e\xed\x61\xd0\x49\x55\x20\xbb\x17\xa8\x7a\x41\x6e\x03"
+  "\x2d\x1d\xc3\xa3\xe5\x98\xe4\x2b\x45\xcb\xde\xf0\x98\x10\x4e\xcf"
+  "\xa5\x04\x69\xd6\x9f\x9e\x48\xe3\x75\x6d\x40\x4f\xa0\xab\xa9\xc9"
+  "\x41\x82\x14\x64\x99\x4c\xcf\x57\x81\x9e\x40\xd3\x30\xa4\x29\xd0"
+  "\x83\xd1\x94\x4a\x34\x2d\x77\xa1\x29\xc8\x26\xe6\xdf\x12\x69\x2a"
+  "\x02\x4d\xcb\x3d\xd0\xb4\x6f\x2c\x0e\x34\x7d\xcd\x2b\x9a\x56\x5e"
+  "\x06\x4d\xc7\x1a\x3d\xd1\xd4\x8e\xfa\xb2\x64\x01\xa1\x20\xef\x4c"
+  "\xf6\xfd\xcc\x57\x2b\xd8\x3a\xb1\x60\xb3\xc5\x88\xea\x6c\x15\xd0"
+  "\x44\x8d\xeb\xf7\x18\xc7\xcb\x90\x4e\x8f\xc2\x28\xa4\xdb\x51\x92"
+  "\xb7\x14\xd3\x40\x6e\x25\xdd\x89\xbe\xe9\x74\x66\x52\x2e\xd0\xea"
+  "\x86\x8b\x56\xd0\x2f\x41\xdd\x3d\x68\x4b\x96\xe4\xbd\x26\xd2\x24"
+  "\x82\x32\xe4\xa9\x99\x44\xd9\x03\x72\x42\x97\x46\x6e\x2e\x05\x59"
+  "\xd7\x03\xb2\xf3\xb4\x42\xbd\x79\xbe\x4e\xa4\x70\x19\xd0\xe7\xa8"
+  "\x18\x98\x1b\x03\xb2\x9a\xf1\x17\x79\x86\xeb\x82\xf5\x4f\x7d\x02"
+  "\xe5\x05\x6e\x3c\xb0\xd4\x4e\x0c\x49\x03\xf9\x2b\x1a\xe2\x35\x8e"
+  "\xa2\x4b\xf7\x13\x8c\x25\x98\xd1\x8e\x7c\xad\x22\xa6\x36\x67\x3f"
+  "\x11\x5f\xe0\x32\x18\x79\x81\xfd\x02\xfb\xc8\x26\x17\xd9\x0b\x72"
+  "\x3d\x64\x9b\x14\x5b\xc3\x01\xb2\x77\x1b\xc6\x0a\x00\x5e\x62\xcc"
+  "\x8d\x41\xfb\xc7\x8b\xd0\x3f\xd6\xb1\xb8\x47\x61\x40\x8f\xaa\x9e"
+  "\x2e\xce\x43\xe4\x99\xc9\x5e\xcb\xf8\x57\x2a\xc9\x7a\x4e\xf7\xdc"
+  "\x29\x94\xc6\x13\x07\xd4\x5d\x2c\xc9\x5b\x48\xbb\x92\xc6\xe0\x1c"
+  "\x22\x8c\x75\x23\x83\x13\xc0\x6e\xf8\x06\x74\xc1\x2a\xc0\xd7\x59"
+  "\x32\xfd\xb5\x55\x60\x0b\x74\x61\xfc\x32\xa8\xcf\x5a\x1e\xf7\x55"
+  "\xcc\x0d\x08\x83\x77\xcc\x87\xaa\x28\xfb\x50\x3d\xaf\xc5\x31\xba"
+  "\x73\x6e\x67\xb5\x56\x70\x7e\xf3\x83\x85\x0e\xd5\xc9\x7c\x76\x0e"
+  "\x5e\x11\xc4\x7d\x19\xa9\xfe\x2b\x1f\xe9\xda\xa1\x08\xca\xe2\x73"
+  "\xb7\x95\x45\x3a\x3d\x19\x7d\x5a\x11\x74\x17\x2d\xac\xca\xd2\x61"
+  "\x0c\x6b\xf9\x9d\x21\x1e\xe9\x50\x39\x3b\x8b\x64\x39\x0a\x4e\x56"
+  "\x9a\xd2\xcf\xa0\x4f\xc2\x61\xca\xde\x20\xb6\xfe\xe3\xc8\xff\x60"
+  "\x11\xd0\x29\x4a\x2c\xfc\x60\x31\xc8\x94\x48\xfa\x2c\xb4\xf5\x57"
+  "\xd0\xd6\xd3\x40\xd7\xd3\xd0\xd6\x17\xa4\xb6\x4a\x31\xdd\x44\xa0"
+  "\x3f\xbc\x1b\x5c\xf7\xc9\x6d\x7d\x16\xfd\x8f\x57\xc4\x67\x9e\x21"
+  "\xdf\xa1\xb7\xe2\x5a\x2c\x3b\xa7\xd8\x65\xb2\x1f\x26\xf8\x5d\xa6"
+  "\x9b\x8b\x62\x9b\x9f\x00\x3c\x22\xcd\xc1\x1e\x88\xa2\x41\xd9\x91"
+  "\x32\x1f\xb0\x3e\xb4\x37\x69\x4c\xf9\x2a\xa8\x0f\xd2\xfe\x2c\x89"
+  "\xc0\xfe\x0c\xb4\x9f\x5e\x8e\xf4\x77\x8f\xab\x1c\xca\x78\x30\x0a"
+  "\x78\xb0\x4a\xe2\x41\x81\xc4\x03\xb0\x13\x41\x4f\xab\x40\xff\x86"
+  "\x95\xe7\x70\x1e\x0c\x8f\x46\xc1\xba\x11\xee\xaf\x09\x9e\xfb\xeb"
+  "\xf8\x37\x7b\xf8\xd8\x50\x81\xbe\x5c\xc1\x36\xfe\x2f\xb1\x17\xfa"
+  "\x6d\x89\xd4\x6f\x69\xd2\x7d\x72\x9f\x3d\xa1\x08\xf9\x91\x77\x7d"
+  "\x76\xdc\xdd\xff\x47\xfb\x6c\xe8\x95\xed\xb3\xe3\x15\xee\x7d\x76"
+  "\xfc\x1c\xf7\x3e\x3b\xee\x94\xb3\xcf\x4a\xef\x46\xa4\xcf\x8e\x27"
+  "\xd7\xa6\xcf\x8e\x27\x83\xf4\xd9\x68\x2f\xfa\x6c\x98\x87\x3e\x1b"
+  "\x76\xe5\xfa\xec\x77\xa6\x5f\x3d\x1d\x3b\x31\xb1\x47\x18\x44\xc7"
+  "\xbe\xe8\xa2\x63\x03\x51\xc7\x7e\xc7\x36\x58\x7f\xed\x2d\x83\xfe"
+  "\xaa\x96\xfa\xeb\xcf\xff\x0a\xe5\x85\x9e\xdb\xdf\x72\xe9\xfe\x6a"
+  "\x2f\x73\xda\x4f\x1e\xfb\x6c\x12\xf6\xd9\x4a\x62\x32\xb3\x3e\xbb"
+  "\x4c\xee\xb3\x65\xd2\x58\x67\x88\x7e\x1b\xea\xa9\xdf\x62\x9c\x2b"
+  "\x8c\x71\x35\x64\xbf\x95\xec\xa5\xde\xa9\xd8\x6f\x8d\xd7\x99\xae"
+  "\x9d\xf0\x9e\x7b\xbf\x9d\xd0\xe1\xde\x6f\x27\xbc\xee\xec\xb7\xd2"
+  "\xbb\x11\xe9\xb7\x13\xaa\xaf\x4d\xbf\x9d\x50\xfd\xed\xd1\xb5\x13"
+  "\x5b\xae\x9e\xae\x9d\x7c\x0b\xeb\xb7\x9e\x74\xad\x41\xd2\xb5\x81"
+  "\xa8\x6b\x6f\xfa\x8b\x77\x7d\x37\xec\xcd\xff\xe3\x7d\xf7\x0a\xeb"
+  "\xdc\x49\x6b\xdc\xfb\xee\xa4\x4a\xf7\xbe\x3b\xe9\x17\xce\xbe\x2b"
+  "\xbd\x1b\x91\xbe\x3b\x29\xf5\xda\xf4\xdd\x49\xa9\xdf\x1e\x9d\x3b"
+  "\xd9\xe3\x1e\x65\xcd\x34\x92\xd5\xaa\x98\x7c\xce\x54\xc6\xf6\xcb"
+  "\x65\x99\xec\xf7\x10\xb6\xc7\x44\x31\x65\x92\x29\x6c\x2e\x11\x0b"
+  "\xab\xab\x30\x56\x09\xee\x75\xf9\xad\xcb\x5e\x12\xb6\xfe\xaa\x98"
+  "\x72\xb7\xbc\x17\xe6\x35\x29\x9e\xc9\x50\x7b\x61\x68\x7e\x75\x94"
+  "\xf4\x3b\xe9\xfc\x44\x75\xb4\xfc\xcc\xfc\xbe\x28\xa6\xa4\xd3\x82"
+  "\xea\x79\x96\x80\xea\x79\x9e\xd6\x48\x82\xb2\x29\xc5\xfd\x1f\xe7"
+  "\xa7\xc5\x94\x9e\x2f\x24\xa4\x94\xad\x3f\x4c\xa9\x82\x36\x36\xf3"
+  "\x7d\x0f\xf6\xac\xf3\x39\x0b\x09\xa4\xd5\xc8\x69\x2c\xb6\x74\x8e"
+  "\x1f\x15\xe1\x1d\xc8\x90\xe4\xd7\xf4\x44\x85\x3e\x89\x67\x5f\x44"
+  "\x2c\x4e\x69\x02\x19\xc1\xf6\x76\xb0\x35\xf7\x9b\xa6\x58\xcb\x3b"
+  "\x89\xb2\x61\x03\xdb\xe3\x86\x7b\x68\x2a\x4a\x10\xff\x7e\xb7\x6f"
+  "\xa1\x82\x92\x88\xdb\x62\xd2\x69\x60\xee\x42\xb6\xe7\x17\xb0\x22"
+  "\xef\xab\xc1\x78\x79\xe2\xd4\x98\x30\xd9\x2f\x2e\x85\xfa\x7d\xa8"
+  "\xc7\x33\xa1\x7e\xb4\x3c\x85\x84\xc0\xa5\xa6\xc5\xb9\x0b\xbb\x72"
+  "\xc3\x17\xcb\x73\x87\x1e\xf7\x6f\x63\x7c\xdc\x29\x61\x4a\x69\x0f"
+  "\x0f\xfa\x07\x60\xfc\xdb\x24\x88\xf9\x0e\x48\xa7\x39\x06\x6a\x4a"
+  "\xb7\x93\x60\xa0\x05\xae\xb7\x63\x9c\x2d\xb1\x3c\xa6\x74\xfd\x64"
+  "\x42\xfe\xbc\xae\x5d\xc0\xbd\x17\x8e\xff\x98\x62\x35\xea\xff\x05"
+  "\xd7\xe3\x99\x4f\xfd\x13\x8a\xa9\x3f\x8b\x3b\xc5\x63\xe1\xc2\xff"
+  "\x89\xb8\xee\xb0\x00\x9e\x71\x3d\x5b\x3c\x1f\xa6\xc4\xbc\x90\x3e"
+  "\xce\x98\xf6\x15\x81\x51\x15\xee\x8b\x57\xf1\xbc\xe1\x18\x57\x12"
+  "\x78\x33\x35\x01\xeb\x00\xcf\x6c\x3d\x05\xf7\xce\xb3\x33\x16\x65"
+  "\x31\xe9\x4c\x3e\x14\xe5\x2e\x84\xf6\xa7\xb3\x3d\x9e\xd0\xce\x4d"
+  "\xd0\x66\xc8\xa3\xc6\xbd\x35\xec\xae\x27\x21\x9b\x21\x0d\xcb\x81"
+  "\xbb\x9a\xed\xef\x55\x84\xb3\xb5\x2e\x8f\xe7\x02\xd4\xb9\x0b\x29"
+  "\x60\x9b\x9f\x93\x51\x7c\xda\xaa\x98\xa6\x0c\x56\x50\x0a\xdf\x0c"
+  "\x5b\x8f\x73\xd8\xb8\x17\x1b\xf7\x97\x2b\xa6\x1e\x86\xf2\x95\xaf"
+  "\xb1\x39\xdb\xa9\xbb\xcd\x8a\xf0\xa4\xbe\xbd\x03\x6c\x9d\x65\x5a"
+  "\x28\x7e\x07\x7f\x23\xe5\x67\x71\x8c\xb0\xce\x1a\xbd\x1f\x85\x67"
+  "\x07\xdf\xaf\xad\x5a\x0a\xbf\xb7\xf7\xed\xd7\xe6\xbf\x03\x2c\x4d"
+  "\x83\x7a\x4f\x61\xe7\x45\xf0\xd9\xe3\xfe\x61\x89\x6f\xf5\x61\x80"
+  "\x8d\xfe\xbc\x93\x31\x02\xb8\x90\x31\x82\xf5\x7d\x4b\x6f\x16\x98"
+  "\x3e\x52\x4c\x63\xfb\x64\x4b\x80\x87\x8e\x57\xc3\x94\x6c\x5e\xba"
+  "\x17\xf9\xd2\x0a\xef\x6e\x7e\x02\xf9\xb2\x09\x74\x81\x94\x37\xdd"
+  "\x59\x7f\x7c\xbe\x99\xf1\x53\x04\x5e\xb0\xfd\x49\x8a\x9b\x67\xb2"
+  "\x98\x46\x20\x33\x70\x5f\x79\x0d\xe4\xa6\x88\x5b\xc0\xc8\x9f\x53"
+  "\x6c\x42\x79\x1a\x4f\xff\xb0\xd3\x26\x6c\x3a\x4d\x50\xb6\x90\xe2"
+  "\x5f\x11\x25\xe8\x21\x25\x96\x49\xc3\x63\xc2\xee\x94\xf9\xb8\x0e"
+  "\x78\x97\x06\xd8\x05\x9a\x6f\x02\xfa\x95\xf7\xb0\x75\x9a\xb0\x72"
+  "\x91\xa8\x45\xc8\x67\x56\xdc\x9c\x00\xe5\x85\x60\xfc\x4e\xdc\xff"
+  "\x0c\x34\x4c\xed\xca\xbd\x39\x4a\xa6\x21\xd6\x09\xf7\x2f\x63\x2c"
+  "\x4f\xa0\xe7\x6e\x8e\xa1\x69\x45\x72\x9b\x3d\xd1\xb3\xf8\xcf\x24"
+  "\xbc\x78\x36\x99\x2b\xaa\x8e\x56\x53\xbf\x29\x15\x38\xdf\xfc\x58"
+  "\x07\xfa\x97\x6a\x27\x71\x1b\x8f\x50\x93\xc5\x41\xc4\x80\xa3\xd5"
+  "\xb8\x06\xe1\x58\x7f\xfb\xf8\xb8\xb5\x40\x2f\xd0\xf7\x06\x1b\x09"
+  "\x31\xe9\x2d\x3c\xf6\x1e\x39\x47\x1c\xcf\x83\x0c\x07\xb9\x0e\x3a"
+  "\x55\x69\x38\x47\x26\x21\xbd\xc4\xc0\xac\xea\x13\x0a\xcd\x84\x27"
+  "\x52\x49\xd6\xf0\xe4\xe8\xcd\x66\x46\x77\xb0\x2f\x40\xe6\x0b\x2c"
+  "\x16\xbd\x05\xec\x93\xe2\xac\xea\xe1\x95\xa3\xd1\x7a\x92\x91\xd8"
+  "\x6e\x11\xe7\xa1\xa5\x36\xc7\x61\x9b\xad\x36\x82\x73\xf9\x8f\x3d"
+  "\x87\x7e\x8d\x2f\x10\xb1\xe0\x68\x35\xb6\x19\x6c\x9d\xb9\xc3\x9f"
+  "\xd3\xd7\x6c\x1f\xea\xdb\x14\xe8\x2d\xae\x9f\x52\x21\xaa\x73\xe7"
+  "\xe2\xb7\xb1\x0e\x78\x26\xe7\xb1\x0b\x84\xd1\x1d\xe9\x6f\xb2\x39"
+  "\x08\x0d\x70\xad\x83\x7d\x98\x75\xb8\xc5\x73\xfb\x67\x93\xf0\xa2"
+  "\x3f\x73\xbe\x3b\xd6\x4b\x34\x48\xc2\x35\xb0\xdc\xb9\x18\x2f\xf0"
+  "\x31\xac\x83\xe5\x0c\x59\x70\x86\x30\xfe\x9b\xb4\x1d\xc4\xe1\x77"
+  "\xfb\x78\xdc\x4b\x80\xfc\xd7\xdb\x81\xff\x17\x6d\xe8\xcb\xc8\x62"
+  "\xca\xea\x26\x68\xbf\xd8\xcf\x6b\x85\x81\xfc\xbf\x75\xc2\x13\xe9"
+  "\xc3\xe5\xff\x2d\x23\xc4\xff\x5b\xaf\x83\xf6\xdf\xe6\x43\xfb\x6f"
+  "\x1d\xa1\xf6\xdf\x76\x1d\xb4\x7f\xba\x0f\xed\xbf\x6d\x84\xda\x3f"
+  "\xdd\x63\xfb\x1f\x9a\x24\x52\xb6\xc7\x24\x28\x53\x83\x3a\x80\xeb"
+  "\xab\x19\x81\xb8\x87\x84\x9d\xc1\x92\x9e\x09\x3f\x93\xa5\xea\xf7"
+  "\xac\xee\xf7\x1c\xd2\xef\x39\xb4\xdf\x73\x58\xbf\xe7\x70\xf9\x19"
+  "\xf4\x88\xff\x59\xc5\xf4\x4c\xb0\x4b\xb3\xcc\x8a\x19\x61\xd2\xfb"
+  "\xe9\xe8\xeb\x0b\x74\xfa\xf4\x21\xe2\x3f\x4e\x39\xad\x98\xc1\xfc"
+  "\x5d\xd2\xf5\x93\xb5\x74\x5d\x16\x11\x8b\x62\xdb\x1e\xcb\x04\xd9"
+  "\x05\xfc\xa3\xbd\x61\xa3\xc0\x46\xb8\x09\xfd\xc9\xe1\x9e\x03\x4d"
+  "\x0a\xee\x25\x99\xf1\x1c\xb6\x6f\xb6\xce\x48\x44\xbf\xdb\xd9\x5a"
+  "\xbe\x58\x1c\xdb\x66\xf1\xbb\x7d\x32\xdd\x9a\x67\x2c\x11\x44\x55"
+  "\x49\x8e\xa8\xc9\xb4\x50\x4b\xec\x39\x90\x43\x17\xd0\xc7\x3b\xf0"
+  "\x38\x95\x5a\x8c\x29\x67\xb0\xbe\x87\xea\x33\xa0\x6c\xf8\x0e\x7c"
+  "\x0b\xc6\x71\xb1\x35\x2c\x1e\x39\x94\xd1\x60\xad\x25\x18\x63\x47"
+  "\x2a\xd3\x4c\x03\x63\x6b\xb0\xcc\x41\xed\xd3\xa2\xcc\x45\xf0\xcd"
+  "\x7b\x9e\xd0\x2a\x09\xcd\x56\x86\x0e\x8f\xa7\x33\xec\x1e\xed\xde"
+  "\xa2\xcc\x26\x5e\xae\xca\x87\x72\xbf\xbb\xc8\x73\xb9\x7a\xa9\xbe"
+  "\x21\xbe\x94\xbb\x63\x88\x72\xa5\xfa\x6a\x7c\x28\xf7\x7b\x4a\xcf"
+  "\xe5\x1a\xa4\xfa\x46\xf9\x52\xee\x80\x3d\xe9\x2e\xe5\x4a\xf5\xcd"
+  "\xf2\xa5\xdc\x5d\x43\xf0\x6d\x91\x6f\x58\xd0\xaa\x86\xc2\x82\x6f"
+  "\x38\xd0\x0e\xd1\x7e\xfd\x22\xdf\x30\xa0\xad\x1a\x0a\x03\xbe\xf1"
+  "\x7f\xe6\x90\xfc\xf7\x8d\xf7\x33\xe3\x87\xe2\xbd\x6f\x7c\x9f\xe9"
+  "\x11\xff\x68\xcb\x03\x9f\x42\x68\x50\x5e\x95\x58\xb2\x20\x44\x0c"
+  "\xca\x1c\xbf\x5e\x8c\x22\x0f\x81\x0c\x0b\xde\x42\xc6\x45\xb1\xf1"
+  "\xf1\xed\x51\x99\x65\x44\x80\xf1\xae\xf0\xe6\xba\x66\xc1\x64\x9f"
+  "\x8b\x3a\xc7\xb1\x3d\xcd\xa6\xb8\x0d\xd2\x3f\x06\x9d\x65\x05\xbb"
+  "\x93\x97\xb3\x20\xa4\x44\x1f\x45\x24\xff\x16\x56\xf4\x67\x1a\x07"
+  "\x72\xcc\xb4\xc5\x86\x7b\x56\xc6\xc1\xef\xec\x80\x5f\x28\xc3\x46"
+  "\xde\x12\x2d\x8a\xa8\x14\x96\xcf\xc2\xce\xd2\x95\x64\x8e\xa7\x06"
+  "\x2d\xfa\x39\xb4\xc0\x37\xdf\xf0\xb3\x10\x01\xfd\x11\x75\xe5\xde"
+  "\xbe\xdd\xac\xb8\x63\xb3\x74\x76\xb4\x83\xf9\xe3\x84\xfa\xe2\xb9"
+  "\x4c\xcc\x8b\x7e\x39\x67\xeb\x88\x80\xbe\xd2\x21\x6f\x23\xfa\xe8"
+  "\x1c\xea\x0c\xb6\xa3\x68\xa3\x15\x7f\x4f\x8b\x40\x87\x9e\x21\x02"
+  "\x9e\xbb\x84\x71\x80\xae\x04\xc6\x10\xf3\x67\xe2\x9c\x47\x27\xd1"
+  "\x67\x52\x11\xe7\x9f\xa8\x3a\xab\x12\xf7\xc5\xb1\x3d\xde\x8a\x3b"
+  "\x92\xcb\xf9\x9e\x6f\x1b\x8b\xbf\x0b\xcf\x6c\x1c\x83\xfb\x62\xd4"
+  "\xb1\x5b\x68\x49\x60\x54\x83\xb5\x93\xc7\x83\x54\xdc\xb1\x12\x7d"
+  "\x25\x9e\x57\x6f\xb4\x58\xd5\x1b\x6d\x5d\xb9\x77\x24\xc9\x6d\xc0"
+  "\xef\xcb\xe9\x38\x6e\xc3\x7c\xf0\x3e\x5f\x3e\x93\xed\x21\x1e\xf5"
+  "\xf8\xb8\x30\x6a\xe9\xf3\x81\xa1\x88\x38\x83\xb4\xa7\x45\x1b\xdb"
+  "\xad\x06\xed\x34\x3e\x8f\x11\x11\x8a\xe3\x61\xd0\x0d\x4d\x7c\x6c"
+  "\x1a\xdb\xc4\xfc\xe5\x82\x0e\x78\x42\x2b\x0c\xd3\x6e\xbd\x83\xe9"
+  "\x7f\xe3\x34\xd4\x91\x11\x07\xa1\xfc\x7f\x6b\x55\x44\xf0\x73\xc9"
+  "\x45\xb1\xed\xec\x2c\xa2\xe2\x8e\x26\xf8\x46\x3b\x3c\x97\x62\x3e"
+  "\x78\x1f\x2f\xbd\xb7\xb8\xbc\xb7\xe0\x3e\x49\xe9\xbd\x34\x96\x8b"
+  "\xb5\xba\xbc\xb7\xea\xa6\xe1\xdc\x44\x44\x05\xb6\x01\xe8\xd8\x88"
+  "\xba\xad\xcf\xa7\x47\x60\x6c\xa3\x94\xaf\xad\x43\x11\xf1\xde\x79"
+  "\xc0\x16\xbc\xef\x70\xf9\x7d\xc7\x9e\xf4\x48\xf2\xd0\x36\xa4\x61"
+  "\x44\x9d\x59\xc8\x5d\xc4\xc7\xb3\x77\x34\xb3\xb6\xab\x63\x6b\x5d"
+  "\xcb\x33\x2b\x22\xb6\x40\x99\xb5\x56\xb0\xa3\x20\x0f\xc6\x11\x74"
+  "\x1b\x93\xc9\x27\x22\x35\x09\x2b\x97\x69\x9e\x59\xbd\x66\x15\x9e"
+  "\x68\x1b\xe3\xb6\xbf\x31\x04\xcf\x7c\x8a\x45\xd9\xcd\xa6\x2d\x78"
+  "\x06\x2d\x84\x9d\xdd\xde\x0c\x7c\xb4\x97\xe4\x85\x38\x82\x72\x2b"
+  "\x1c\x25\x59\x46\xc3\x05\x22\xe8\xc3\xe8\x51\xe3\xba\x07\xc9\x59"
+  "\xc5\xac\x44\x16\x5f\x54\xc3\xfc\x42\x5b\x8d\xeb\x3e\xc1\x34\xe6"
+  "\xd3\xdb\xb4\x94\xa7\xfd\x8f\xbe\x56\xf8\x48\xdf\x2c\xd4\x2d\xed"
+  "\x24\x7b\xc2\x2c\xa4\x46\xd3\x49\xca\x30\x5d\x6c\x14\x70\xdf\x28"
+  "\xe4\xaf\xc7\x6f\xe1\x18\x1f\xff\xe7\xf3\x15\xb3\x7e\x8c\xdf\x41"
+  "\x7f\x1a\x1d\x8a\x59\x4f\xe0\xf7\xcc\x8a\x59\x8b\xfc\xca\xd8\x3e"
+  "\x63\xf5\x59\xc5\xec\x71\x62\x71\x76\x33\xeb\xe3\xb9\xb3\x94\x76"
+  "\x41\xbd\x5d\x3a\xe3\xc6\xfc\xfc\x77\xe5\xce\xb2\xbb\x9c\xe7\x44"
+  "\x5f\x20\xf7\x77\xe5\xce\x0e\x91\xcf\x16\x60\x9c\x31\x4f\x32\xa3"
+  "\x1b\xc6\xb2\xdd\x65\x0f\xdb\x44\x75\x36\xd0\x37\xbb\xb9\xb6\x96"
+  "\xe0\x5c\x8a\x02\xf7\xc0\x76\x28\xee\xb4\xd0\xc0\xec\x5a\x3d\xf6"
+  "\x53\xa0\xc5\x9f\x70\x1f\x5f\x50\x5e\xc8\x0e\xdc\xb7\x57\x92\x5b"
+  "\xf1\xdf\x69\x36\x61\x7f\x5d\x35\xd1\xfc\x3b\xda\x43\xb3\xb3\x1f"
+  "\x4d\xa0\xf6\xdb\x9b\x8c\xa4\xae\xed\x6d\x72\xa0\xa5\x96\xa8\x17"
+  "\x13\x3f\x83\x99\x3a\xd8\x78\x3f\x95\x08\x71\x66\xe2\xa7\xbf\x80"
+  "\xfd\xd4\x41\x0c\x6b\xe0\x6e\xab\x07\x1b\x27\x39\xf4\x4d\x7d\xbb"
+  "\xbf\xe6\x71\x42\x1c\x45\x7c\xdd\x98\x9d\xb3\xb1\xb0\x33\xca\x81"
+  "\x38\x87\xed\x72\xbe\x26\x2c\xf3\x0c\x51\xd5\x27\x1d\x26\x19\x4b"
+  "\xa9\xe8\x78\x41\x3b\x3e\x6e\xa9\x1f\x65\x67\x6c\xd2\x21\xb3\x0e"
+  "\x78\xfa\x82\x36\xe8\x95\x34\x12\xda\x90\x6a\x26\xa6\xf6\x5a\xf2"
+  "\x6a\x0a\x09\xa5\x5d\x49\x01\x75\x75\xfb\x09\x2d\x3c\x96\xf5\x96"
+  "\xde\xe8\x2f\xef\x99\x0a\xce\x56\xe0\x9c\x65\x50\x11\xee\x9d\xba"
+  "\x48\x22\x97\x1c\xcf\x62\xf3\xac\x38\xa7\x6d\xef\xd2\x6a\x7a\xbb"
+  "\xb4\xb7\xf6\x74\x69\xa7\xc9\x73\xe1\xbf\x58\x11\x42\xb6\xe1\xd9"
+  "\x9c\x5c\x4d\x07\xee\xd5\x43\xdb\xde\x1e\x70\x32\x1f\xe7\xbd\x11"
+  "\x97\xf0\xed\x70\xf1\x19\x2d\xb9\xd3\xc2\xce\xfe\xe0\x5c\x7c\x48"
+  "\xf9\xd3\x50\xdf\x8e\x4e\xe2\xba\xff\xa7\xfb\x05\xad\x80\x7b\x7f"
+  "\x68\xee\x6c\x6d\xcf\xb6\x87\x6d\xb8\x07\x08\x74\xc1\x9c\xe1\xf7"
+  "\xed\x3b\xd9\xdc\x04\xb6\x9f\x02\x66\x77\x74\x22\x7f\x80\x4f\x9d"
+  "\x16\x01\x79\x51\x9f\x80\x7c\x68\x74\xe3\x03\xe3\x5b\x8a\x4d\x40"
+  "\x7e\x20\x2f\x90\x27\x4e\x7e\x1c\x64\xfc\xd8\x21\x72\x7e\xf4\x80"
+  "\x1e\x90\x79\xd2\x1d\x1e\xa3\x1a\x8a\x2f\xc8\x0f\xe4\x4d\x5d\xdb"
+  "\x61\xe2\xc6\x13\x0b\xe7\x09\xd0\x73\xbc\xcc\x17\xe4\x89\xa9\x03"
+  "\x6c\x5d\xe0\xcb\x23\x07\x09\x79\x74\x26\x15\xeb\x63\x3f\xeb\xe3"
+  "\x8f\xdd\x13\x7f\x4e\x39\xf9\x03\xbc\x1f\xc8\x9f\x33\x21\xb8\x36"
+  "\x03\xfc\xb9\x45\x37\x1c\xfe\xd4\xb5\x71\xfe\xd8\x25\xfe\xcc\x8c"
+  "\x21\x82\xad\x4b\x2b\x6c\x4d\x23\x73\x63\x8f\x6b\xc8\xde\xf8\x7a"
+  "\x02\xb4\xae\x16\x8b\x37\xb6\xfb\xd6\x8f\xfe\x75\xae\xf7\xfd\xe8"
+  "\xfb\xfb\x6e\xf4\xa3\xe1\xf6\xa3\xef\xeb\x2e\xaf\x1f\xfd\xab\xf2"
+  "\x46\x3f\xba\x5a\xfd\xe8\x5f\x49\xff\x7e\xd4\xa7\xab\x53\x12\x57"
+  "\x2e\x5b\xb1\x0a\x8f\xef\x3d\xbd\x36\x35\xf1\x79\xae\xb1\xdd\x74"
+  "\x76\x98\x43\x1f\x25\xa0\xff\xb5\xba\x2d\x8d\xe4\xad\xc9\x8d\x82"
+  "\xe3\x64\x98\x92\xe6\x77\x37\x8a\xf9\xf6\x78\xf4\xa3\x89\xfd\x6d"
+  "\x33\xfa\xb8\x50\xdc\x9d\xda\x10\xce\x63\x56\xe2\xff\xcc\x5e\x09"
+  "\x8f\xc9\xc7\x35\x92\xf5\x3d\x70\xad\x23\xca\x60\x1b\x01\x7b\x06"
+  "\xdf\xcf\xfd\x14\xfd\x0a\xd2\x6d\x31\xf9\xe5\x18\xe7\xbe\x87\x28"
+  "\xad\xea\xd8\xd2\x0d\x50\x9e\x25\x30\xbb\x59\xa9\xc1\x73\x0e\x77"
+  "\x2d\x05\x9d\x1c\xde\xe7\x77\x48\x31\x77\x33\x1d\x35\xa7\x0a\xfb"
+  "\x3a\x9e\x39\x3b\xab\xb8\xeb\x77\xdd\x39\x04\xfd\x6b\x58\x9e\x98"
+  "\x09\xdf\x9a\x1a\xa3\x62\x7e\x08\xa0\xdf\xf3\xf7\xff\x8f\xad\x3b"
+  "\xf5\xaa\xb3\x30\x56\x11\xd8\x8d\x79\x21\xe7\x8b\x72\x2b\xf6\x67"
+  "\x54\x11\xcd\xe3\xd8\xef\xef\xfa\xf8\x91\x2d\xd0\xef\x17\x1a\x49"
+  "\x7d\xd8\x7f\x93\x03\xf1\x80\xb7\xf8\x4b\xf5\x7b\x17\x9c\x4d\xf3"
+  "\xae\xdf\xcb\xf8\x42\x5c\x21\xbe\x10\x5b\x63\x01\x5b\x88\x37\x19"
+  "\x5f\xbf\xbd\xc8\xf1\x15\xdc\x42\x42\x5e\xe9\x04\x8c\xd9\x39\xc6"
+  "\xf0\x1c\x70\x7d\xfa\x67\x9e\xfb\xff\xc5\x7e\xf8\x12\x24\x7c\xbd"
+  "\x00\xf8\x7a\xc1\x89\xaf\x27\x0f\x87\x90\x57\x19\xbe\x34\x4e\x7c"
+  "\x15\x9c\xcc\x97\xb1\x85\x38\x43\x4c\x89\xbf\xd4\x12\xec\xf3\x32"
+  "\xce\xca\x97\xf3\x75\x4e\xd6\xff\x05\xe8\xff\x5d\x2e\x7a\x74\xea"
+  "\xe5\xf4\xff\xff\xc7\xfa\x3f\xf2\x04\xf9\x83\x7c\x41\x5e\xfc\x33"
+  "\xf2\x01\x7d\xc0\xd2\xae\xc1\x78\x71\x73\xfa\xa5\x78\x81\x7c\x40"
+  "\x7e\x30\x3e\x00\x3f\xe4\x35\x67\x5c\x83\x44\x9e\x20\x2f\x66\x67"
+  "\x10\x01\xf9\x52\x0e\x7d\x1e\xfb\x39\xd0\x96\xed\x71\x66\xb6\x6b"
+  "\x4e\x60\xf2\x66\x3c\x37\x2b\xc5\xd7\xed\xca\x9d\xbb\x6b\xa0\xdd"
+  "\x3a\xb7\xb6\xcf\xef\xa3\xe2\x2e\x36\x2e\x33\x4e\xbe\x07\xfa\xdb"
+  "\x5d\xd2\x98\x25\x3b\x9f\xaf\x1f\xdd\x33\x43\xea\xd3\x3a\x1c\xff"
+  "\xb1\xb1\x9e\x03\xc6\x7a\x6a\x18\xeb\x15\xc1\x58\x2f\xbd\x9d\xfb"
+  "\x0a\x50\xdc\xcd\xe3\x20\xe1\xd8\x2e\x30\xab\x12\xc6\x19\x5b\x90"
+  "\x7e\x6c\xdd\x34\x70\x23\x8e\x57\x3b\x68\x31\x8c\x23\xff\x53\x20"
+  "\xf0\x0c\x18\x72\x0c\x13\x3b\x77\x47\x49\xeb\xc2\xf3\x74\xeb\x70"
+  "\xcf\xc0\x3d\x21\xbc\x7e\x77\x31\x1f\x54\x6c\x4d\x4d\x10\x2b\x1c"
+  "\xeb\xdd\xd7\xd4\x5c\xd7\x5c\xdf\xd2\x5b\xa4\xf5\xb4\xbb\x59\xec"
+  "\x75\x94\x0f\x28\xd7\xde\xd4\x37\x0a\xce\x35\xb5\xcf\xf0\x7d\xb7"
+  "\xfb\x9a\xda\xdd\x75\x84\x9d\x09\xbb\x67\x3a\xee\x23\x81\x67\x33"
+  "\x4f\xbf\x2b\xcc\x35\xdd\xb9\x66\xcd\xd3\x45\x81\xc5\x18\xc1\x31"
+  "\x77\x07\x1f\x6b\xdf\x33\x4f\x1e\xd3\x7a\xb0\x6f\x86\x21\x77\xef"
+  "\x27\x4e\xb9\x7b\x3f\xdb\x5b\x48\xc3\xf2\xaa\xeb\x07\xc8\xdd\xaf"
+  "\xe0\xfd\x7d\xbf\x78\x0c\xe5\x6e\x51\x56\x95\xc4\xd3\x7d\x40\x13"
+  "\x3f\x8c\x15\x89\xe9\x78\x7e\x07\xe5\xef\x36\x3c\xdb\xc2\x64\x72"
+  "\x5e\xe5\x06\xb6\x76\x7e\x4f\x87\xbb\x2c\xbe\x4f\xe3\x2e\x8b\xff"
+  "\xed\x96\xa1\x65\xf1\xbc\xbd\x43\xcb\xe2\x7f\x5b\x70\x43\x16\xfb"
+  "\x2a\x8b\xc1\x16\xbb\x2c\x59\x3c\xaf\xf4\x86\x2c\xbe\x52\xb2\x78"
+  "\x5e\x91\x8b\x2c\xfe\xa9\xbb\x2c\xbe\x2f\x6a\xa0\x2c\xbe\x6f\x91"
+  "\x53\x16\xdf\x63\x73\xca\xe2\x7b\xaa\xdc\x65\xf1\xfd\x3b\xbd\x93"
+  "\xc5\xf7\xbd\x79\x65\x65\xf1\x7d\x75\xee\xb2\xf8\xfe\x32\x49\xae"
+  "\xbc\x34\x7c\x59\x7c\x7f\xe6\xd0\xb2\xf8\xfe\x8d\xee\xb2\xf8\xfe"
+  "\x78\x2e\x73\xef\xaf\xe2\xb2\xf8\xfe\x64\x9e\x7e\x4f\xa9\x6b\xba"
+  "\x53\x16\xf3\xf4\x81\xb2\xf8\xfe\xda\x4b\xc8\x62\xad\x43\x94\x65"
+  "\x71\x33\xc8\xe2\x66\x41\xfc\xa5\x27\x59\x1c\x6d\xab\x47\x59\x9c"
+  "\x82\xb2\x38\xda\x36\xb4\x2c\x8e\x3e\x8e\x32\x17\xf0\x4a\xca\xd0"
+  "\xc7\x2f\xe0\xcf\xb8\xfc\x2b\x9c\xd3\x6d\x43\x7c\xc2\xfb\x7b\x1f"
+  "\xcb\x70\x95\xd5\x51\x6b\xfa\x64\x35\xa4\x8b\x93\xdc\x65\x35\xca"
+  "\x69\x94\xd7\xdb\x5e\xa6\xe6\xf2\x97\x69\x4b\x57\x6e\x54\x85\x2c"
+  "\xb3\x8b\x21\x0d\xe3\xfd\xa0\x0f\x9f\x6d\x17\xd9\xa5\x04\x1a\xb4"
+  "\xad\x87\xef\xe2\x6f\x20\x6f\x9d\xbb\x7c\x8f\x26\xf6\x5c\x57\xf9"
+  "\xfe\x80\x02\xe5\x7b\x11\x3f\xb3\xcd\xe4\xba\x7d\x5b\x8c\x0a\x65"
+  "\x3d\x7f\xff\xe0\xef\x87\x96\xef\x0f\xcc\xba\x56\xf2\x1d\x65\xca"
+  "\x58\x97\xb1\x9c\x27\xb9\x02\x6d\xb3\xd6\x27\x5c\x1d\xf9\x8e\xf2"
+  "\x04\xe5\x08\xca\x16\x59\xbe\xa3\x6c\xb1\x4b\x63\xed\xb2\x1c\x17"
+  "\xf9\x3e\xca\x45\xbe\x2b\x7c\x91\xef\x0f\xea\xbe\x55\xf2\x1d\xf9"
+  "\x90\x71\x65\xe5\xbb\x3c\xae\x46\x3e\x20\x4f\x90\x17\xae\x63\x6b"
+  "\xe4\x03\xf2\x03\xf9\x80\x36\x8d\x2c\xdf\x67\xa5\x73\xf9\xbe\xad"
+  "\x4f\xbe\x3f\x98\xdc\x27\xdf\x05\x2e\xdf\xcb\xd0\x37\x1a\x9b\x23"
+  "\x8e\xd6\x0c\x94\xef\xd1\x73\x9c\xf2\x3d\xaa\x59\x92\x77\x6d\xe8"
+  "\x5b\x00\xfa\xf7\x62\x77\x19\x3f\xff\x0d\xef\x64\x7c\xf4\x4b\x03"
+  "\x64\x3c\xd0\xb0\x88\xaf\x0d\xa1\x7c\xb7\xa0\x7c\xb7\xa3\x9c\xf7"
+  "\x49\xc6\x47\x57\x39\xf5\x50\xd4\x3c\x2e\x5b\xa3\x63\xdd\xe5\xfe"
+  "\xfc\xcd\x92\x8c\x9a\xea\x2a\xf7\x45\x3f\x6f\xe4\xfe\xfc\x35\xb2"
+  "\xdc\x47\xb9\xfa\xa6\xd8\xec\x22\xf7\x51\x4e\xce\xcf\x34\xa6\xb5"
+  "\xba\xc8\xfd\xf9\x0b\x79\x1d\xe6\x57\x3a\x98\xdc\x9f\x9f\xc0\xd3"
+  "\xa3\xc2\x5d\xd3\x9d\x72\x9f\xa7\x3b\x5c\xe5\x7e\x3b\xca\xfd\xf9"
+  "\xc6\x4b\xc8\xfd\x39\xde\xcb\xfd\x47\x93\x9c\x72\xff\xd1\xa4\xa1"
+  "\xe5\xfe\xa3\x4f\xa0\xdc\x67\x3e\x61\x81\xf7\x80\x67\x65\xc9\x44"
+  "\x2e\xf3\x71\x4e\x04\x74\x81\x19\x7d\x5a\x40\xbe\x07\x98\xef\x77"
+  "\xb8\xe0\x7d\x7b\x11\xfe\x2f\xb2\xdf\xb4\x04\x5b\x88\x0a\x75\x40"
+  "\xd1\x09\xa2\xc4\xb8\x69\x9c\x4e\x8f\x6c\x2b\xc3\x58\x9e\x7d\xfa"
+  "\xe2\x87\xbf\xf7\x52\x5f\x34\x81\xbe\x68\xec\xca\xfd\x61\xa3\x8b"
+  "\xbe\xc0\xd8\x73\x8d\xfd\xf4\x85\x19\xf4\x45\x9b\xfc\x9b\xae\xdc"
+  "\x87\x89\x6b\x7e\xac\x1f\xcb\x7f\x82\x5d\x98\xbf\x19\xf2\xb7\x70"
+  "\xfd\xf2\x70\x84\xbb\x7e\x79\x64\xa9\xe8\x36\x7e\x78\x78\x99\xac"
+  "\x5f\x50\x3f\x8b\x03\xf4\xcb\x8f\xfc\xfb\xf4\xcb\x44\x17\xfd\x92"
+  "\x2e\xeb\x97\x87\x8b\xaf\xfb\xf1\xc3\x65\xc8\x35\x5f\xf5\x0b\xca"
+  "\x34\x94\x67\x43\xe9\x17\xd1\x45\xbf\x88\x3e\xe9\x97\x98\xc6\x6f"
+  "\x95\x7e\xb9\x0a\xe3\x07\x57\x1e\x20\x5f\x98\x6e\x01\xde\x20\x1f"
+  "\x90\x07\x48\x7f\xf4\x3f\x8d\xbc\x41\xbe\x20\x4f\x66\xe9\x9c\xba"
+  "\x85\xf1\x85\xe9\x97\x98\xba\xfe\xfa\xa5\x7c\xbc\xac\x5f\x1e\xc9"
+  "\x1a\xa8\x5f\x1e\xd9\xec\xd4\x2f\x0f\xb3\xf9\x1b\xe6\x5f\x4f\xf1"
+  "\xc3\x22\x77\xdd\x12\x3b\xc9\x3b\xdd\xf2\xc8\x99\x41\x74\x0b\xf3"
+  "\x6d\x5c\xf4\xb2\xdb\xd8\xc1\x02\xfa\xc5\x07\xdd\xf2\xa8\x9a\xd7"
+  "\x11\xf7\x2f\xff\x70\x31\x97\xdf\x8f\x54\x3a\xf5\xcd\x0f\xe7\xb8"
+  "\xa6\x39\xf5\x4d\xac\x52\x92\x71\x13\x86\xaf\x6f\x1e\x3d\xce\xf6"
+  "\x1e\x40\x1b\xde\xec\xe4\x32\xdd\x5d\xdf\x3c\x7a\xc6\x5d\xdf\x3c"
+  "\x6a\xe4\x75\x88\x0d\xe3\xfa\xe6\xd1\x26\x9e\xfe\xc3\x50\xd7\x74"
+  "\xa7\xbe\xe1\xe9\x03\xf5\x4d\x6c\xe4\x25\xf4\x8d\xba\x37\x3c\x46"
+  "\xd5\x5b\x94\x6b\xb1\x6f\x8f\x29\x8d\x88\xbf\xdf\xd1\xbf\xdf\xf0"
+  "\xfe\xe2\x20\xd8\x7f\xfa\xd6\x9f\x9e\xe2\xeb\x1d\xa2\x74\x06\xb8"
+  "\x27\xfc\x61\xdb\x89\x64\xe8\x3b\x1d\x9e\xfb\x0e\xf4\x1b\x95\xdc"
+  "\x6f\xea\x93\x8e\x13\xe8\x4b\x02\xae\x49\xbd\x0a\x7d\xc6\x64\x6d"
+  "\x66\x7d\x48\xdd\x16\x45\xd0\x77\x62\x60\x07\x09\x09\x54\x28\x46"
+  "\xe1\x7a\x87\x03\xfa\xcf\xfc\x99\x54\xbc\xa3\x39\x8a\x04\x26\x91"
+  "\x20\xec\x43\x7f\x96\xd6\x3d\xd0\x7f\x03\xae\x77\x00\x7e\x23\x97"
+  "\x7c\xea\x5c\xef\xe8\xf1\x62\xbd\xc3\x94\x6e\x66\xeb\x1d\x78\xa6"
+  "\x49\x84\x7e\xc2\xce\xd9\xe0\x7a\x87\x8d\xad\x11\x31\xf9\xf5\x1a"
+  "\x5b\xef\x68\x25\xb8\xd6\x21\xfb\x67\xc1\x35\x8e\x3b\xe2\x89\x80"
+  "\xfe\x1d\x5e\x85\x7e\xb3\x57\x5b\xcf\xfa\xcd\xf0\x65\xd8\x82\xcd"
+  "\x43\xed\xf3\xb1\x03\x4d\x1d\xea\x5c\x0b\x7d\x25\xcf\xfc\xa7\x56"
+  "\x9b\x02\x7d\x53\x3a\x80\x47\x22\xc8\x2a\xaa\xea\x27\xab\x7a\x25"
+  "\x7a\xf7\x72\x7a\x03\xaf\x54\x4f\x59\x09\x85\x74\xee\x9b\xd2\x66"
+  "\x06\xac\x69\xc7\x6f\x5b\x87\xb4\x8d\x24\xdb\x24\xff\x94\xe2\x8b"
+  "\x49\x01\x22\xd0\x13\xcf\x32\xbc\x79\xd1\xe6\xef\x50\x1d\xad\x2e"
+  "\xea\x21\x11\x20\x97\x02\x51\x2e\x01\x3e\xc7\xbc\xd6\x03\xb4\x3d"
+  "\xca\x69\x8b\xfe\xc5\xf0\x6e\x7f\x51\xab\x81\xb2\x6f\xed\xed\x05"
+  "\xfa\xda\x38\x7d\x9f\x7a\x2e\x84\x94\xcb\xeb\x7d\xa0\xeb\x1b\x80"
+  "\xa7\x4c\x2e\x59\x83\x29\xc6\x99\x70\xf4\x6a\xc3\xc5\x93\x40\x5f"
+  "\x2b\xf4\xa9\x5e\x2d\xf2\x3f\xa4\xfc\x04\xae\x4f\x7e\xc5\xd7\xfb"
+  "\x02\x24\xbf\x19\x2f\x82\x8e\x58\xa1\x21\xa6\x4a\x90\xd1\xa3\x62"
+  "\xa3\x7b\xb7\x3d\x6c\x63\x63\x90\x8c\xe1\xd2\xf7\xb1\x01\xfe\x8f"
+  "\xaf\x0e\x7d\x35\xdf\x22\xfa\x2e\x68\xf1\x9d\xbe\x0b\x3d\xee\xff"
+  "\xbc\xb2\xf4\x0d\xf9\x16\xd1\x37\x6e\x9e\xef\xf4\xfd\xb1\xc7\xfd"
+  "\x9f\x48\x5f\x1c\x27\xc8\x63\x04\x79\x7c\x80\x7a\x85\xeb\xd0\x45"
+  "\x11\xce\xb1\xc1\xa2\x08\x79\x5d\x14\x68\xa3\x2c\x46\x1f\xce\xd0"
+  "\x66\xdd\x72\x72\xf3\x69\xc5\x4f\x5e\x97\xd7\x44\x4b\x31\x96\x08"
+  "\xf2\xea\x15\xe0\xd5\x2a\x3c\xb3\x22\xf1\x09\xf4\xc0\x12\x2b\xc8"
+  "\xea\xa9\x31\x2a\x47\x31\xe8\x89\xdf\xc7\x94\x7a\xe0\x99\x80\x32"
+  "\x3e\x30\x95\x84\x3c\xa5\xe3\xbc\x13\x5f\x04\x9e\xf5\x80\x4d\x64"
+  "\x6b\x27\x78\x06\x35\xb8\x1d\xe4\x6a\x6f\x52\xc0\x62\xb0\xb1\x65"
+  "\xbe\xfd\x39\xcd\xc6\xec\xa1\x41\xf9\xb6\xd5\x9d\x6f\xe7\x07\xe1"
+  "\x9b\xcb\x3e\x03\x1d\xe7\x9b\x99\xf1\x8d\xc9\xf5\x17\xc1\x36\x05"
+  "\xfe\xc9\x7c\x63\x72\x1d\x78\xc7\xf8\xd6\xd1\xca\x6c\x20\x59\xae"
+  "\xa3\xfd\x83\xbc\xab\x5b\x0a\xf6\x5c\xee\xc2\x32\xc6\x37\x9c\xdb"
+  "\x5e\x3a\x5c\xbe\xfd\x24\xd9\xdd\xee\x59\x74\xc8\x3b\xbb\xe7\x27"
+  "\xa7\xd0\xae\x71\xb5\x7b\xf0\xf9\x3c\xd8\x39\x8e\xc0\x8d\x56\xab"
+  "\x4f\xe3\xe8\x9f\xd8\xdc\x6d\x98\x45\x35\xbc\x4e\x8f\x7f\x7f\xf8"
+  "\x36\xcc\x22\x36\xdf\xf6\xe6\x2b\x83\xd9\x2f\x8b\xde\x74\xb7\x5f"
+  "\x16\x65\x71\x3b\x65\x51\xf3\xf9\x1c\xb4\x5f\x16\x6d\xe6\xe9\x8f"
+  "\x47\xba\xa6\x3b\xed\x17\x9e\x7e\x1e\xfd\x94\xe5\x2e\x6a\x1b\x9e"
+  "\xcd\x72\xe7\x35\xb6\x59\x22\x87\xb0\x59\x22\xff\xc9\x6c\x96\x7f"
+  "\xf7\x18\xff\xf2\x86\x4e\x95\x65\xfe\x22\x9b\xef\x32\xff\xa7\x95"
+  "\x37\x74\xea\xa5\xe8\xfb\xef\xa5\xbe\xd3\xf7\x67\x1e\xcf\x3f\x5c"
+  "\x5a\xa7\x3e\x99\xe5\xd4\xa9\x4f\x66\x79\xd6\xa9\x3f\xbf\x70\x43"
+  "\xa7\x0e\xa6\x53\x7f\x6a\xf1\x5d\xa7\xfe\xdc\xe8\xae\x53\x17\xcf"
+  "\xf2\x4e\xa7\x3e\x79\xef\xc8\xeb\xd4\x27\xfb\xcd\x43\x2f\xe6\x3e"
+  "\xdf\x15\x3f\xdb\x38\x7c\x9d\xfa\x64\xb7\x67\x9d\xba\x58\xe1\xae"
+  "\x53\x9f\x6c\xe2\xba\x73\x71\x04\xd7\xa9\x4f\xb6\xf3\xf4\x9f\x6d"
+  "\x70\x4d\x77\xea\x54\x9e\xce\x75\xea\xe2\xb9\xc3\xd3\xa9\x37\x5f"
+  "\x63\x9d\xaa\x19\x42\xa7\x6a\xfe\xc9\x74\xea\x2f\xca\x6e\xc8\xfc"
+  "\x4b\xc9\xfc\xc5\xb1\xbe\xcb\xfc\xa7\x3c\x9e\x7f\xbc\xb4\xcc\x5f"
+  "\x96\xea\x94\xf9\xcb\x52\x3d\xcb\xfc\xa5\xa7\x6e\xc8\xfc\xc1\x64"
+  "\xfe\x2f\xda\x7c\x97\xf9\x4b\x77\xb9\xcb\xfc\xa7\x6f\xf1\x4e\xe6"
+  "\x2f\xfb\xfe\xc8\xcb\xfc\x65\xfd\xf6\xff\x3d\xad\xe6\x75\x5a\xb2"
+  "\x76\xf8\x32\x7f\xd9\x19\xcf\x32\x7f\xd9\x05\x77\x99\xbf\xac\x96"
+  "\xcb\xf6\xa7\x35\x5c\xe6\x2f\x6b\xe1\xe9\x4b\xd2\x5d\xd3\x9d\x32"
+  "\x9f\xa7\x73\x99\xff\x74\xc4\xf0\x64\x7e\xf0\x35\x96\xf9\x21\x43"
+  "\xc8\xfc\x90\x7f\x32\x99\xff\x4c\xa9\xef\x32\x69\xb9\xca\x29\x93"
+  "\x96\xab\x3c\xcb\xa4\xc4\xcc\x1b\x32\x69\x30\x99\xf4\x74\x94\xef"
+  "\x32\x29\x31\xc6\x5d\x26\x2d\xff\x8b\x77\x32\x29\x71\xef\xc8\xcb"
+  "\xa4\xc4\x26\x77\x99\xb4\xbc\x82\xd7\x29\x21\x70\xf8\x32\x69\x79"
+  "\xb6\x67\x99\xb4\xbc\xc0\x5d\x26\x2d\x97\xd6\xcc\x96\xef\xe2\x32"
+  "\x69\xb9\x8e\xa7\x27\xa8\x5d\xd3\x9d\x32\x89\xa7\x73\x99\xb4\xfc"
+  "\x52\xfb\x1f\x18\xf6\xeb\xc3\xfa\x61\xff\x59\x19\xfb\x2b\xc2\x0e"
+  "\x94\xc9\xd8\x5f\xc1\xf7\x39\x97\xc5\xe4\xff\x3a\x8d\x28\x8b\x30"
+  "\xe6\x06\xf4\x77\xdd\xcf\x11\xfb\x49\xc5\xb8\xff\x40\xdd\x02\x32"
+  "\xac\x4d\x92\x69\xe9\x20\xd3\xda\xe0\x19\x7d\x52\x4d\x8d\xc9\x47"
+  "\x59\x84\xb1\x08\xf0\x99\xcb\x36\x8b\x3f\x9e\xdd\x1c\xd6\xb9\xaa"
+  "\x36\xe9\x5c\x55\xc2\xc0\x73\x55\x65\x2e\xe7\x77\xb0\x6f\x04\x66"
+  "\x2b\x82\x70\x2d\x18\xe4\x9b\x24\xc7\x6a\xfd\xed\x2a\x49\x8e\x5d"
+  "\x04\x39\x76\xd1\xd9\x27\x50\x8e\x9d\x07\x39\x66\x7d\x41\x3b\x0d"
+  "\x65\xd9\xc0\x33\x55\x7c\xed\x97\xc9\xb1\x82\x7e\x72\xec\x97\xfd"
+  "\xe4\xd8\x72\x90\x63\x4b\x41\x8e\x05\x38\xfb\xc3\x6d\x2d\x44\x88"
+  "\x5d\x06\x7d\x02\xe4\xd8\x6f\x2f\xa2\x1c\xdb\xeb\xa3\x1c\x4b\x8a"
+  "\x77\xef\x0f\x2b\xf6\x7a\xd7\x1f\x92\x0e\x7a\xea\x0f\xbd\xc5\xbe"
+  "\xf6\x87\xa4\x36\xf7\xfe\xb0\x42\xda\x93\xf2\xcb\x80\xe1\xf7\x87"
+  "\x15\x2f\xf5\xf5\x87\x67\xfb\xf7\x87\x15\x5b\xdd\xfb\xc3\x8a\x64"
+  "\x8e\xfb\x15\x35\xbc\x3f\xac\xc8\xe2\xe9\xbf\x54\xb9\xa6\x3b\xfb"
+  "\x03\x4f\xe7\xfd\x61\x45\xe3\x8d\xf5\xd9\xeb\x55\x47\x3f\x3b\xe7"
+  "\xc6\xfa\xec\xa5\xc6\x65\x2b\xda\x7c\x1f\x97\x25\x5f\xa3\xf5\xef"
+  "\x6f\xd3\x5c\xf2\xb3\x19\xbe\xd3\x77\xe5\x35\x5a\xff\xfe\x36\xcd"
+  "\x2b\x24\x5f\xc6\xfa\xf7\xea\x21\xd7\xbf\x87\xb6\x63\x9e\x6b\xab"
+  "\xeb\xb3\xe1\x9f\x6b\x93\xf7\x6e\x0e\xb4\xe1\x9f\xfb\x99\xfb\xd9"
+  "\x29\x9d\x7f\xff\xb3\x53\x97\xb2\xed\xed\xff\xa7\x6c\xfb\x55\xf3"
+  "\x7c\xb7\xed\x9f\x9b\xee\x6e\xcb\xa4\xbc\xe4\x9d\x2d\xf3\xdc\xeb"
+  "\x9e\x6c\x19\xbb\xcf\xb6\xfd\x73\x55\xee\xb6\x4c\x4a\x06\xaf\xd3"
+  "\xea\x4f\x87\x6f\xcb\xa4\xfc\xc2\xb3\x2d\x93\x92\xe8\x6e\xcb\xa4"
+  "\xcc\xe5\x36\x4b\x4a\x29\xb7\x65\x52\x62\x79\xfa\xea\x46\xd7\x74"
+  "\xa7\x2d\xc3\xd3\xb9\x2d\x93\x52\x76\x63\xdd\xf6\x7a\xb5\x65\x70"
+  "\xea\xf2\x86\xae\x1d\x5a\x17\xa4\x54\xf9\xae\x0b\xd6\x2c\xbd\xa1"
+  "\x6b\x2f\x45\xdf\xd4\x18\xdf\xe9\x9b\x66\xf4\x5d\xd7\xae\x5d\xe8"
+  "\xd4\xb5\x6b\x17\x7a\xd6\xb5\xe9\x7b\xdd\x75\xed\x0b\xcf\xdd\xd0"
+  "\xb5\x43\xe9\xda\x35\x95\xbe\xeb\xda\xf4\x52\x77\x5d\xbb\xd6\xe1"
+  "\x9d\xae\x5d\x1b\x38\xf2\xba\x76\x6d\xb8\xbb\xae\x5d\xdb\x2e\xf1"
+  "\xff\xde\xe1\xeb\xda\xb5\xfb\x3c\xeb\xda\xb5\x9f\xba\xeb\xda\xb5"
+  "\xdb\xb9\x4e\x5d\x6b\xe7\xba\x76\x6d\x35\x4f\x7f\x61\x9e\x6b\xba"
+  "\x53\xd7\xf2\x74\xae\x6b\xd7\xa9\x6e\xac\xe7\x5e\xaf\xba\xf6\x45"
+  "\x8f\xf1\x0f\x6f\xe8\x02\x59\x17\xac\x0b\xf7\x5d\x17\x64\xd4\xf9"
+  "\xae\x0b\x0c\x8b\x9d\xba\xc0\xb0\xd8\xb3\x2e\xd0\x7f\xea\xae\x0b"
+  "\x32\x33\x6f\xe8\x82\xa1\x74\xc1\x8b\xbb\x7c\xd7\x05\xfa\x32\x77"
+  "\x5d\x90\x15\xe0\x9d\x2e\x30\x4c\x1a\x79\x5d\x60\xd0\xba\xeb\x02"
+  "\x83\x55\xe2\xff\x8f\x86\xaf\x0b\x0c\x07\x3d\xeb\x02\xc3\x61\x77"
+  "\x5d\x60\xa8\xe2\x32\x3f\x4b\xc5\x75\x81\xa1\x86\xa7\x67\xc6\xb8"
+  "\xa6\x3b\x75\x01\x4f\xe7\xba\x20\x2b\xf4\xc6\x3a\xef\xf5\xaa\x0b"
+  "\xb2\xd3\x7d\x97\x55\x1b\x54\x4e\x59\xb5\x41\xe5\x59\x56\xad\xcf"
+  "\x74\x97\x55\x39\x33\x6f\xc8\xaa\xa1\x64\x55\x96\xd6\x77\x59\xb5"
+  "\xbe\xdf\xfa\xef\x06\x2f\xd7\x7f\xd7\x7b\x5c\xff\xf5\x5d\x56\xad"
+  "\xef\xb7\xfe\xbb\x41\x5a\xff\xcd\xbe\x30\x7c\x59\xb5\x21\xdb\xb3"
+  "\xac\xda\xd0\x6f\xfd\x77\x83\xb4\xfe\xbb\x41\x5a\xff\xdd\x20\xad"
+  "\xff\x66\x5b\x5d\xd3\x9d\xb2\x8a\xa7\x73\x59\xb5\xe1\x32\xd7\x7f"
+  "\xf3\x22\x9d\xeb\xbf\x79\xec\xcc\x80\xb8\x25\xaf\x7a\xe0\xfa\x6f"
+  "\xee\xef\xdd\xfd\x98\x6c\x7c\x80\xad\x05\x63\xbf\xb0\xf2\xb3\xe9"
+  "\x83\xae\x0b\x4f\xca\xab\xbe\xb1\x2e\x3c\x12\xeb\xc2\xb9\x3a\xf7"
+  "\x7e\x92\x77\xd8\xbb\x7e\x92\x7b\x66\xe4\xd7\x85\x73\xed\xee\xfd"
+  "\x24\xaf\x56\xc2\x84\x0f\xeb\xc2\x79\x6f\x78\xee\x27\x79\x3b\xdd"
+  "\xfb\x49\x9e\xb4\x2f\x37\xaf\x85\xf7\x93\xbc\x2d\x3c\x7d\xa3\xca"
+  "\x35\xdd\xd9\x4f\x36\xba\xac\x0b\xe7\xb5\x7b\xa3\xd3\xed\xea\x5c"
+  "\x2b\xea\xe8\x88\xe6\xfb\x1d\x7d\x78\x4e\x95\xf0\x3c\x98\x4e\x7f"
+  "\x9a\xcb\x7e\xc4\x71\xef\xf6\x98\xcd\x97\xd4\xe9\x6d\x92\x4e\x4f"
+  "\x18\xa8\xd3\x65\x7d\x8e\x78\x7e\xd5\xab\x35\xe1\x7e\xb8\x1e\x96"
+  "\x3e\xbf\x55\x77\x39\xb8\x46\x4c\xbb\xeb\x73\x5f\x71\x5d\x70\x8d"
+  "\xce\xbf\x7c\x9b\xd6\x84\xf3\xec\xbe\x8f\xed\x0a\xaf\xd1\xf9\x97"
+  "\x6f\xd3\x3c\x75\xc1\x65\x9c\x7f\x29\x1a\xf2\xfc\xcb\x8d\xb9\x09"
+  "\xa4\x6f\xa1\xc5\x77\xfa\x16\x27\xf9\x6e\xef\x97\x86\x39\xed\xfd"
+  "\xd2\x30\xd9\xb6\x41\x59\xc8\xfc\xee\x80\xfc\x2b\x4e\x81\xeb\x22"
+  "\x21\xbf\x4e\x61\x7e\xc7\x55\xa6\xb6\x83\x44\xa7\x47\x7b\x67\x53"
+  "\x71\x5c\xba\xab\xbd\x53\x32\x4b\xb6\x75\xe2\xd0\x0e\x02\xbb\x06"
+  "\x6d\x1a\xd9\xc6\x2f\xed\xbc\xc4\x7e\xd0\x19\x31\x9b\x71\x4c\xd0"
+  "\x1b\x98\x6b\xfd\xe7\x1f\x0f\x14\x2d\xf4\x7d\x3c\xb0\xa9\xdf\xfe"
+  "\xb7\x52\x2f\xf7\xbf\x6d\xf2\xb8\xff\xcd\xf7\xf1\xc0\xa6\x7e\xfb"
+  "\xdf\x4a\x25\x2c\x14\x1f\x1f\xbe\x9d\x53\x3a\xc4\xfe\xb7\xd2\x7e"
+  "\xfb\xdf\x4a\xa5\xfd\x6f\xa5\xd2\xfe\xb7\x52\x69\xff\x5b\x71\x9b"
+  "\x6b\xba\xd3\xce\xe1\xe9\xdc\xce\x29\xf5\x6a\xff\x1b\xd8\x39\xb6"
+  "\xcb\xb0\x73\xb6\x7c\x7b\xec\x9c\xdb\xae\x13\x3b\xe7\x37\x91\x5e"
+  "\xe8\x09\x6b\x3f\x3d\xb1\xf9\xff\x96\x9e\x28\xbd\x8c\xbd\x6f\xbf"
+  "\x1d\x72\xff\x3f\xa3\x6f\x91\x0b\x7d\x51\x46\x4b\xb4\x75\x4c\x8f"
+  "\xd9\xec\x13\x7d\x41\x36\x6f\xd3\x7f\x5b\x68\xfb\x9b\x74\xdf\x69"
+  "\xbb\xb9\xe3\x86\x8d\x73\x29\xfa\xfe\xb6\xd9\x77\xfa\xbe\x1c\xeb"
+  "\xbb\x8d\xb3\x35\xfc\x40\x9f\x8d\xb3\x35\xbc\xbf\x8d\x83\x36\xcd"
+  "\x02\x1b\xb7\x75\x7e\x0d\x36\x4a\xe1\x2a\xb0\x77\xd2\x08\x31\xb5"
+  "\x7d\x40\x8a\xc0\xe6\x29\x3c\x0b\x76\x4f\x32\xd8\x3d\xf6\xdf\x4b"
+  "\x76\xcf\x96\x97\xdc\xed\x9e\xff\x98\x31\xa8\xdd\x13\xe8\xb4\x7b"
+  "\xec\x60\xd3\xf4\xfe\x3e\x66\x73\xe9\x59\x17\x1b\xe8\x57\x03\x6d"
+  "\xa0\x9e\x62\xd0\x39\x33\x62\xb6\xf4\x82\x1d\x34\x94\x0d\xc4\x78"
+  "\xdf\xcf\x0e\xfa\xf6\xd9\x40\xbf\x9b\xe3\xbb\x0d\xb4\xa5\x9f\x0f"
+  "\xd1\xad\xfb\xbc\xb3\x81\xb6\x1c\xf2\x38\xd7\xe3\xb3\x0d\xb4\xa5"
+  "\xdd\xdd\x06\xda\xba\x8b\xd7\xe9\xe5\x7d\xc3\xb7\x81\xb6\xfe\xce"
+  "\xb3\x0d\xb4\x75\x9b\xbb\x0d\xb4\x55\xc7\x6d\x9d\xad\xb5\xdc\x06"
+  "\xda\xba\x81\xa7\xbf\x5c\xeb\x9a\xee\xb4\x81\x78\x3a\xb7\x81\xb6"
+  "\x36\x79\xb9\x7e\x63\xb5\x83\x8e\xbd\xf6\xfb\xe6\x86\x5a\xbf\x19"
+  "\xa9\x7d\x73\xb7\x5e\x27\xeb\x37\xaf\xce\xbd\xa1\xa7\x87\xd2\x23"
+  "\x5b\xdb\x7d\xd7\x23\x65\xd7\x68\xff\xff\xb7\x49\x4f\xbf\x9a\xe5"
+  "\x3b\x7d\xb7\x0d\xb9\xff\x7f\x68\x3d\x5d\xb1\xdd\x39\x17\x51\xb1"
+  "\x7d\x78\x73\x11\x15\x93\xdc\x75\x72\xf9\x7b\x37\xe6\x22\xbc\xd5"
+  "\xc3\x65\x2d\xbe\xeb\xe1\xd7\xda\xdc\xf5\xf0\xeb\x3f\xf6\x4e\x0f"
+  "\x57\x2c\x1b\xf9\xb9\x88\x0a\x9d\xbb\x1e\x7e\x7d\x9e\x84\x85\xe7"
+  "\x86\xaf\x87\x5f\x9f\xea\x59\x0f\xbf\x3e\xc3\x5d\x0f\x57\xd8\xb8"
+  "\xbe\x7d\x7d\x21\xd7\xc3\xaf\xab\x79\x7a\xb9\xce\x35\xdd\xa9\x87"
+  "\x79\x3a\xd7\xc3\xaf\x2f\x1e\xde\x9a\xcb\xcd\xd7\xe9\x9a\x8b\xe6"
+  "\x9f\x6c\xcd\xe5\x3f\x77\xdf\xd0\x13\x97\xd2\x13\xaf\xeb\x7c\xd7"
+  "\x13\xdb\xc3\x7d\xd7\x13\x7f\xa8\x73\xea\x89\x3f\xd4\x0d\x4f\x4f"
+  "\xfc\xe1\x01\x77\x3d\xb1\xfd\xe8\x0d\x3d\xe1\xad\x9e\xf8\x2f\xa5"
+  "\xef\x7a\xe2\x0f\x6a\x77\x3d\xf1\xc7\xb5\xde\xe9\x89\x3f\x14\x8c"
+  "\xbc\x9e\xf8\xc3\x16\x77\x3d\xf1\xc7\x04\x09\x0b\x5b\x87\xaf\x27"
+  "\xfe\x38\xdf\xb3\x9e\xf8\xe3\x02\x77\x3d\xf1\x47\x0d\xd7\x07\x7f"
+  "\x4c\xe7\x7a\xe2\x8f\x73\x78\xfa\xf6\x2d\xae\xe9\x4e\x3d\xc1\xd3"
+  "\xb9\x9e\xf8\xe3\x86\x1b\xfb\xed\xae\xd7\xfd\x76\x95\xed\xbe\xcb"
+  "\xb2\x3f\xa5\x3b\x65\xd9\x9f\xd2\x3d\xef\xb7\xfb\xef\x33\xee\xfb"
+  "\xed\xde\xd8\x7a\x63\xbf\xdd\x50\xb2\xea\x8f\x5b\x7c\x97\x55\xff"
+  "\x5d\xed\x2e\xab\x76\x78\x19\x0f\xf2\x4f\x77\x8d\xbc\xac\xfa\x53"
+  "\xb4\xbb\xac\xda\x21\xc5\x80\x7c\x23\x71\xf8\xb2\xea\x4f\xe7\x3c"
+  "\xcb\xaa\x3f\x75\xbb\xcb\xaa\x3f\x49\xf1\x1f\x77\x4c\xe7\xb2\xea"
+  "\x4f\x52\xfc\xc7\x37\x12\x5c\xd3\x9d\xb2\x8a\xa7\x73\x59\xb5\xc3"
+  "\x2b\xff\xff\xce\xf5\x35\x9f\x6c\xda\xab\xb0\xbe\x36\x52\x36\xed"
+  "\xf5\xb2\xbe\xf6\xe6\x8d\xf5\x9f\x21\xed\xd9\x1d\x97\xe1\xf7\xff"
+  "\xcf\x43\xae\xff\x0c\xad\x03\x76\xee\x72\xea\x80\x9d\xbb\x3c\xad"
+  "\x4f\x14\x02\x86\x8a\xc0\x1e\x2d\x38\x4b\x94\xbf\xc6\xf5\x89\xa6"
+  "\x7a\x52\x8c\xeb\x13\xab\xe4\xf5\x89\x6d\x92\x8d\xbb\x73\xa6\xbb"
+  "\x8d\xfb\xd6\xde\xc1\x6c\x5c\xb4\x6d\x1d\x60\xb7\xda\xfb\xaf\x4b"
+  "\xfc\x7c\x70\xdd\xd1\x13\x98\x6b\xeb\xfe\x7d\xcc\x96\xe1\xe8\x8e"
+  "\x57\xd7\x71\xdd\xf1\xca\xb7\x4a\x77\xbc\xd9\xec\xbb\xee\xa8\xb2"
+  "\xba\xeb\x8e\xb7\x97\x79\xa7\x3b\x76\x3e\x37\xf2\xba\x63\x67\x96"
+  "\xbb\xee\x78\x3b\x56\xc2\xc3\x8a\xe1\xeb\x8e\xb7\x67\x79\xd6\x1d"
+  "\x6f\xdf\xe5\xae\x3b\xde\x96\xf6\x9a\xbe\xbd\x94\xeb\x8e\xb7\xc3"
+  "\x79\xfa\x5b\x49\xae\xe9\x4e\xdd\xc1\xd3\xb9\xee\x78\x3b\x79\x78"
+  "\xf3\x21\xc1\xd7\xe9\x7c\x48\xc8\x3f\xd9\x7c\xc8\xff\x5c\xc6\xf9"
+  "\xb7\x77\x52\xeb\xfa\xf6\xcf\xbf\x93\x3a\x60\xbc\x9e\x06\xb6\x6e"
+  "\x27\x5f\x73\xed\x1b\xaf\x9b\x0f\x4b\xb2\xec\x2f\xa7\xdc\x65\xd9"
+  "\xae\x97\x3c\xc9\xb2\xa1\xd6\x55\x71\x7c\xee\x00\x39\x87\xb1\xd6"
+  "\x7c\x5a\x57\x4d\xfb\x36\xc9\xaf\xb7\xb3\x7c\x97\x5f\x7f\xe9\xe7"
+  "\xff\xf4\x5d\x2f\xfd\x9f\xbe\xe3\xd1\xff\xa9\xdd\xe7\x3d\xf4\xef"
+  "\x44\xb9\xcb\xaf\x77\x25\xff\xa7\xbb\x7c\x38\x17\xf7\xce\x19\xcf"
+  "\xf2\xeb\x9d\x7e\xfe\x4f\xdf\x91\xd6\x4f\xdf\x95\xfc\x9f\xbe\x23"
+  "\xf9\x3f\xdd\x15\xe3\x9a\xee\x94\x5f\xbb\x5c\xce\xc5\xbd\x3b\xa4"
+  "\xff\x53\x5a\x14\x6b\x2b\x15\xc4\x2a\xb8\xaa\xa1\x8e\x93\x00\x03"
+  "\x46\xf8\xbf\x16\xf8\x38\x0e\xfe\x6f\xf4\xd4\xc7\x2c\x81\xb1\x36"
+  "\x31\x07\xea\x2c\x10\x85\xc9\xf2\x8d\xd1\x38\xd9\x8e\xbc\xd9\xc1"
+  "\x79\x15\x6b\x0b\xb6\x8f\x8e\x11\x69\x12\xa1\x6a\xf8\x1f\xe3\xe3"
+  "\x41\xfe\x20\xc0\x8c\x26\x8d\x04\x9d\x55\xbc\x5b\x27\xe7\x83\xfa"
+  "\x06\xb5\x2a\xde\x2d\xc0\x32\xa0\xae\xcd\xd0\x96\xb9\x1e\xeb\x0a"
+  "\x65\xc5\xbd\x31\x8d\x64\xda\xe9\x49\xe3\xaa\x4e\xd2\xa6\xa8\xbe"
+  "\x25\xb8\x63\x74\x0c\x35\xc4\x13\xb4\xb1\xaa\x26\x5b\x94\x58\xa6"
+  "\x71\x55\x0f\xbe\x53\xe2\x3b\x07\xd4\x51\xbf\x92\x08\x25\x9d\xa3"
+  "\x55\x20\x0b\xfc\x0d\x56\xda\xbe\xda\x0e\x75\x4e\xb7\x93\x8f\xa6"
+  "\x35\x2b\xdf\x7a\xa5\x19\x7d\x09\x85\x61\x4c\x3c\x2c\x03\x6c\x4c"
+  "\xa8\x4f\xf5\x8c\x72\xc8\x3f\x58\x1d\x36\xfe\x99\x44\xf8\xcf\xa4"
+  "\xe6\xe1\xe1\xa6\xda\xe3\xf9\xb7\xe0\xec\x69\xc4\x78\x3b\xd0\x4e"
+  "\x43\x84\xc1\xde\x0f\xf3\x3b\xe6\x21\x64\xa2\x0a\xe3\x69\x1a\xb6"
+  "\x12\x61\x93\x38\x5a\xb5\x27\x83\xc5\xb3\xb4\x74\xe5\xbe\x17\x6b"
+  "\x56\x4c\x4f\x42\x9a\x63\xcc\x34\x8c\xb9\x0a\xb8\x21\x90\x9e\xf0"
+  "\x31\xd4\xba\x3f\x2f\x52\x12\x56\x2e\xd3\xa4\xae\x58\x99\xb8\x7a"
+  "\x4d\xaa\x66\x46\xc2\x18\xb2\x68\xf5\x6a\xcd\xca\x65\xab\xd6\x6a"
+  "\x5c\xdf\xdc\xa3\x49\x58\xf1\xfc\xb2\xa7\x93\x13\x67\xad\x7c\x46"
+  "\x37\x06\xea\x44\x5c\xea\x11\x8a\x75\x11\x73\xdf\xd3\x95\xff\x86"
+  "\x90\xdf\x8e\x27\x4a\xac\x17\x7c\xaf\x49\x8e\xa9\x57\xf2\x32\xb5"
+  "\x0a\x90\xc7\x00\x32\x70\x93\x7e\x34\xe4\xad\x36\xbf\x06\xf5\x2a"
+  "\x87\x7a\x43\x1d\xa1\xce\x7f\x25\x72\x9d\x65\x4c\x18\x10\x13\xfa"
+  "\x4e\xc0\xe0\x5f\x6f\x09\xb6\x8d\x7e\x98\xd2\x78\x6c\x9f\x15\xfa"
+  "\x89\x02\xd2\x9e\x43\xbd\x04\x32\xc0\x06\xbf\x9d\x27\x63\x0c\x7f"
+  "\x4b\x4b\x62\x8d\x5d\xd8\x4f\x68\xd2\x7d\xbc\x4f\xbd\x1f\xfa\x84"
+  "\x56\x41\x78\x4c\xbf\xbf\x26\x39\x63\xfa\xbd\xcf\x62\xcb\x41\x3d"
+  "\x3a\x20\x3d\xcb\x4c\x2e\x6e\xc0\x74\x8c\x2d\x89\xb1\x5e\xb1\xce"
+  "\xd0\x2e\xd0\x8b\xd4\x48\x73\x24\xec\xe7\x57\xc4\x8b\xf9\x1f\x64"
+  "\x99\x94\x17\x49\x9c\x9d\xf6\xd2\x82\x8a\xf8\x06\xab\x95\x04\x67"
+  "\xeb\x9e\xa1\xa3\xde\xcb\x0e\xb6\xaf\x48\xc4\x98\xe4\x62\xc1\x07"
+  "\x59\xb4\xe0\xdd\x8c\x27\x66\x92\x10\x28\xbb\xc5\x25\xb6\xa0\x72"
+  "\x78\xfc\xff\x2b\xe3\x3f\xf2\x11\xea\x23\xf1\xf1\xfd\x88\x8f\x53"
+  "\x07\xf2\xb1\x0f\x7f\x6f\x88\x64\x2f\x60\x81\xaa\x33\xa3\xe2\x1c"
+  "\x9c\x8e\xd8\x77\xcf\x1b\x92\xc8\x9d\x8c\x76\xef\xb7\x89\x25\x99"
+  "\x1a\xb1\x28\x33\x9e\x16\x65\x46\x03\xcd\x9a\x4b\xd2\x88\x66\x89"
+  "\x23\x84\x14\x5f\x24\x91\x96\xe2\xcc\xa8\x40\x45\x96\x02\x6c\x0b"
+  "\x01\xf4\x46\x24\xc8\x8c\x48\xa9\xbf\x37\x23\x1d\xff\x06\xa3\x90"
+  "\xc7\x9e\x27\xe4\xe4\x3c\xe2\x57\x0e\xbf\x1b\x5e\x7b\xde\xe7\xfe"
+  "\x9f\x72\xdf\x4f\x7a\x0d\x7e\x8b\xb1\x21\x87\xf9\x7b\x8b\xc7\x7e"
+  "\xe7\x6c\xb7\x71\xf0\x76\xef\x6e\x81\x76\x57\x40\xbb\x9b\xa1\xdd"
+  "\x35\x83\xb4\xdb\xc8\xdb\xed\xdf\x39\xf2\xed\xde\xcd\x63\x2e\xe6"
+  "\xee\x5e\xea\x5b\xbb\x77\x7b\x9c\xff\x73\xb6\x5b\xef\x81\xdf\x1f"
+  "\x34\x89\x25\x7a\xe0\xb7\x1e\xf8\xad\x1f\x84\xdf\x7a\x89\xdf\x63"
+  "\x5b\x47\xbe\xdd\x1f\x54\xf0\x76\x7f\x10\xef\x5b\xbb\x3f\xf0\x28"
+  "\xff\x5c\xda\xed\x81\xdf\x1f\xd6\x41\xbb\x81\xdf\x7a\xe0\xb7\x7e"
+  "\x10\x7e\xeb\x25\x7e\x8f\xfb\x6c\xe4\xdb\xfd\x21\x9f\xff\xcf\xfd"
+  "\x70\xa1\x6f\xed\xfe\xb0\xf9\xd2\xed\x36\x78\xe0\xf7\x47\x35\x62"
+  "\x89\x01\xf8\x6d\x00\x7e\x1b\x06\xe1\xb7\x41\xe2\xf7\x0f\x0a\x47"
+  "\xbe\xdd\x1f\x71\xff\x37\xb9\x1f\xc5\xf8\xd6\xee\x8f\x3c\xda\x27"
+  "\x2e\xed\xf6\xc0\x6f\xe3\x6e\x68\x37\xf0\xdb\x00\xfc\x36\x0c\xc2"
+  "\x6f\x83\xc4\xef\x27\x1f\x1c\xf9\x76\x1b\xf3\x79\xbb\x8d\x51\xbe"
+  "\xb5\xdb\x58\xeb\x85\x5c\x8b\x01\xd9\x35\x80\xe7\xa6\xf4\xb9\x64"
+  "\xf6\x45\x6c\xff\x27\x11\x34\x30\x33\x66\x6c\x76\x96\xc2\xae\xce"
+  "\x8c\x1d\xdb\x42\x04\x18\xfb\x25\x05\x9b\x49\x00\xb4\x35\x89\x96"
+  "\x64\x9b\xf1\x2e\x42\x39\x76\x90\xfd\x0e\x75\x66\x74\x4f\x51\x6c"
+  "\xf3\xaf\x97\x13\x8d\xc1\x42\x42\x1a\xf4\x66\xa2\xd7\x51\x4b\x03"
+  "\x39\x4a\x02\xcd\x44\xc0\x79\xac\x03\x1d\xd5\x64\x55\x0a\xa5\x50"
+  "\xf6\x04\x1c\x2f\x96\x9c\x20\x91\x60\x13\x67\x51\xd0\x1f\xa5\x22"
+  "\xd1\x40\xf9\x91\x48\x4b\x28\xbb\x35\x78\x11\x51\x7c\xf8\xb4\x8d"
+  "\x20\x3d\x91\xb6\x30\xb6\x8c\x64\x74\xb5\x12\xf2\xe8\x93\x9c\xae"
+  "\xaf\x2e\x1f\x2e\x5d\x3f\x36\x73\xbb\x32\x73\xa9\xc9\xdc\x43\xc0"
+  "\xb6\x0c\xc1\x73\xcd\x90\x5e\xd6\xa0\xeb\x84\x71\xc8\xc7\x51\xb4"
+  "\x38\x73\xa1\x08\x3a\x6b\x78\xe5\x7e\xe2\x71\xff\x9b\x0b\xbd\x6b"
+  "\x81\xde\x03\xb0\xe6\xa4\xf7\x9e\x32\xa0\x77\xad\x44\xef\xba\xb1"
+  "\x2d\xfe\x9d\x1e\xe8\x5d\x0b\xf4\x6e\x06\x7a\xd7\x78\x4f\xef\x3d"
+  "\x1b\xfb\xd1\xbb\xe2\xea\xd0\x7b\xcf\x42\x89\xde\x66\x77\x7a\xef"
+  "\x51\x73\x7a\x7f\x52\x05\xf4\x6e\x04\x7a\x1b\x87\x59\xae\xc7\xf3"
+  "\x8f\x2e\x72\x1c\xf0\x3d\x50\x87\x39\xe9\xbd\x57\x4d\x03\xf5\x12"
+  "\xbe\xf5\x80\xef\xb1\xad\x83\xd3\x5b\x0f\xf8\xd6\x03\xbe\xf5\xc3"
+  "\xc0\x77\xcd\x05\x77\x7a\xeb\xaf\x12\xbe\x6b\x8c\x9c\xde\xfa\x7e"
+  "\xf8\xae\xc9\xe0\xf4\xae\xd1\xd0\x62\x3d\xe0\x5b\x3f\x4c\x7c\xef"
+  "\x0d\xf3\x82\xde\x80\xef\x81\xba\xd3\x49\xef\xff\xcd\x00\x7a\x4b"
+  "\xf8\xd6\x03\xbe\xc7\x7d\xe6\x81\xde\x80\x6f\x3d\xe0\x5b\x3f\x0c"
+  "\x7c\xff\x6f\x62\x3f\x7a\x5f\x25\x7c\xff\x6f\xa4\x44\xef\x7e\xf8"
+  "\xde\xdb\xc1\xe9\xbd\xb7\x14\xe8\x0d\xf8\xd6\x0f\x13\xdf\xff\x9b"
+  "\xef\x85\xde\x02\x7c\x0f\xd4\xd9\x4e\x7a\xff\xad\x83\x06\x1a\x24"
+  "\x7c\x1b\x00\xdf\x3f\x28\x1c\x9c\xde\x06\xc0\xb7\x01\xf0\x6d\x18"
+  "\x06\xbe\xff\x76\xd0\x9d\xde\x86\xab\x84\xef\xbf\x71\xfb\xaf\xc8"
+  "\xd0\x0f\xdf\x7f\x5b\xcc\xe9\xfd\x37\x42\x8b\x0d\x80\x6f\xc3\x30"
+  "\xf1\xfd\x37\x9b\x17\xf4\x06\x7c\x0f\xb4\x15\x9c\xf4\xde\xb7\x18"
+  "\xe8\x2d\xe1\xdb\x00\xf8\x7e\xf2\x41\x0f\xf4\x06\x7c\x1b\x00\xdf"
+  "\x86\x61\xe0\x7b\xdf\xfc\x7e\xf4\xbe\x4a\xf8\xde\x17\x22\xd1\xbb"
+  "\x1f\xbe\x6b\xeb\x38\xbd\x6b\x75\x40\x6f\xc0\xb7\x61\x98\xf8\xde"
+  "\xe7\xf1\xfc\xef\x50\xf6\xc9\xf3\xdb\x88\xca\x9d\xe6\xfb\x1b\xaf"
+  "\x9c\x8d\xb2\xff\xbd\x6b\x63\xa3\xec\xdf\x30\xb8\x8d\xb2\x3f\x8a"
+  "\xd3\x7c\x5f\x9b\x6f\x36\xca\xfe\x16\x5f\x6c\x94\x81\x34\xaf\x8b"
+  "\xbe\x72\x76\x4a\xdd\xac\x6b\x63\xa7\x1c\xb0\x0d\x6e\xa7\x1c\xd8"
+  "\xc5\x69\x7e\x20\xde\x37\x3b\xa5\x6e\xa1\x2f\x76\xca\x40\x9a\xd7"
+  "\x57\x5f\x39\x5b\xa5\xfe\xf5\x6b\x63\xab\xd4\x27\x0f\x6e\xab\xd4"
+  "\x6b\x39\xcd\xeb\xea\x7c\xb3\x55\xea\x6b\x7c\xb1\x55\x06\xd2\xdc"
+  "\x14\x71\xe5\xec\x15\xd3\x84\x6b\x63\xaf\x34\x98\x07\xb7\x57\x1a"
+  "\xa4\xf1\x4f\x43\x94\x6f\xf6\x8a\xc9\x8b\xf1\xcf\x40\x7b\x65\x20"
+  "\xcd\x1b\x2b\xae\x9c\xcd\xd2\x58\x70\x6d\x6c\x96\xc6\x45\x83\xdb"
+  "\x2c\x8d\x21\x9c\xe6\xa6\x5d\xbe\xd9\x2c\x8d\x3b\x7c\xb1\x59\x06"
+  "\xd2\xfc\xb3\xd0\x2b\x67\xb7\x7c\xea\xb8\x36\x76\xcb\xa7\xb5\x83"
+  "\xdb\x2d\x9f\x6e\xe0\x34\xff\x54\xeb\x9b\xdd\xf2\x99\xc6\x17\xbb"
+  "\x05\x69\x8d\x34\x47\x5b\x85\xd3\xbc\xa9\x8d\x06\x65\x6a\x7a\xc1"
+  "\x1e\x09\x04\xba\x07\x76\x10\x61\x1b\xd2\xbc\x99\xd3\xdc\x11\x94"
+  "\x6d\x06\xfa\x24\x21\xcd\x58\x3b\xfe\x11\x16\xe4\x28\xca\x8c\xa5"
+  "\x02\x81\xb6\xa8\x08\xf0\xec\x9c\x3d\x87\x04\x69\xf4\xd9\xf0\x7f"
+  "\x13\xf3\x9f\xa9\xd1\xe7\x1e\x86\x36\xfa\xe1\x1a\x85\xbd\x38\x36"
+  "\xcb\x11\xc8\xde\x7d\x9f\x4e\x8d\xc9\xea\x05\x5b\x82\x3e\x1b\x16"
+  "\x6a\xea\xa8\x22\x26\xfb\x7e\xd2\xd0\xfc\x57\x22\x06\x65\xb7\xde"
+  "\x69\x27\x5a\xfa\x0f\x6d\x68\x5d\xaa\x99\x38\x9e\x09\x53\x9b\xd2"
+  "\x6b\x01\x17\x6f\x93\xb8\x76\x7a\x91\x1e\xd3\xaa\x7b\x03\x73\xa3"
+  "\xa0\x1c\xa3\xa3\x38\x4f\x65\x0f\xcc\x8d\x7c\x33\xcd\x2c\xa8\x6d"
+  "\x44\x9b\xdc\x46\x69\xc9\xd3\x44\x59\xd2\x4a\x54\x9b\x9e\x26\xea"
+  "\x4d\xad\x24\xa4\xae\xad\x99\xd4\x9f\xae\x25\xf5\x9d\x87\x48\xfd"
+  "\x45\xb8\x7a\xe0\x12\xe1\xca\x3a\x44\xea\x3a\x08\x59\x70\x86\x10"
+  "\x43\x1b\xb5\xdc\xd1\x42\x42\xeb\xec\xcd\x04\xf7\xf1\x9e\x55\x7c"
+  "\xbe\x57\xbd\x94\x84\xd2\x63\x61\x84\x3e\x13\x26\xc0\x3b\x25\xa6"
+  "\x9b\xec\x16\x52\xd7\x66\xc3\xf7\xdb\xe1\xbd\xd2\xd0\x06\xe5\x8b"
+  "\xb5\xe8\x2f\xce\x52\x97\xb5\x8f\xd8\x0b\xec\x3a\xa0\x73\xbc\x6c"
+  "\x93\x95\xf4\x90\xc8\x4d\xc0\x66\xc4\x4c\x1c\xe5\x98\x79\xad\x67"
+  "\xb8\x98\xf9\x9c\xfb\x3f\x7b\x36\x6c\x3c\xd0\x7b\xb2\xf8\x6c\x7c"
+  "\xc8\x63\x87\x8e\x50\xdc\xa7\x85\xeb\x33\x0d\xd6\xfd\xc4\xb4\x41"
+  "\x24\x71\x6b\x09\x89\x75\x10\x82\x34\xc1\xb5\xe4\xc7\x74\x24\x18"
+  "\xf7\x8f\x89\xff\xd0\x8e\x37\xb5\x59\x48\xa6\x1d\xea\x7a\xd6\xd6"
+  "\x57\xd7\x86\x0d\x0d\x04\xde\x4d\x6e\x48\x32\x13\xb5\x8e\x84\x20"
+  "\x9d\xc1\x2e\x8a\x79\xac\x9d\x04\xac\xb2\x52\x8a\x34\x46\xda\x22"
+  "\x9d\xb1\x3c\x99\xf6\xa6\x04\x0b\x31\xd8\x48\x88\x49\x0f\xf7\x74"
+  "\x6a\x31\x91\x73\x04\xea\xd8\x4c\x03\xec\x3a\xc0\x47\x1b\x62\x02"
+  "\xf0\xd8\x0e\x38\x18\x4f\x73\x3f\x2b\x2b\x87\xf6\xe2\x1a\xfe\xf0"
+  "\xda\xdc\xe4\xcd\xfa\xc7\x00\x9b\xd0\x05\xcf\xb5\x1c\xcf\x5f\xee"
+  "\x02\x3c\x57\x00\x9e\x6b\x38\x9e\xfd\x3b\xbd\xc0\x73\x9d\x13\xcf"
+  "\x07\x3f\x76\xe2\xf9\xcb\xdf\x7b\xc6\xf3\x97\x0a\x09\xcf\xe6\xeb"
+  "\x13\xcf\x5f\xfc\x6e\x68\x3c\x7f\x91\x3a\x04\x9e\x9b\x65\x7b\x77"
+  "\x64\xf0\xfc\x45\xdd\x55\xc4\x73\xad\x6f\x78\xfe\xa2\xd2\x1d\xcf"
+  "\x07\xab\x39\x9e\x0f\x26\xfb\x86\xe7\x2f\x8d\xbe\xd8\xdb\x4e\x3c"
+  "\xeb\x25\xf9\xfc\xd5\x06\x1a\xa4\x07\xf9\xac\x97\xe4\xf3\xd8\xd6"
+  "\x4b\xe3\x59\xef\x22\x9f\x9b\x5f\x72\xe2\xf9\xab\x35\x9e\xf1\x7c"
+  "\xe8\x53\x8e\x67\xfd\x75\x2a\x9f\x0f\x25\x0e\x8d\xe7\x43\xd1\x9e"
+  "\xf1\xac\x8f\x97\xc7\x12\x23\x83\xe7\x43\x65\x57\x0f\xcf\x7a\x1f"
+  "\xe5\xf3\xa1\x74\x77\x3c\x37\xe7\x73\x3c\x37\xcf\xf3\x0d\xcf\x5f"
+  "\x79\xdc\xff\x3c\xd4\x58\xc6\x05\xcf\x92\x7c\x3e\xbc\x08\xf0\x0c"
+  "\xf2\x59\x2f\xc9\xe7\x71\x9f\x79\x81\x67\x17\xf9\xfc\xf7\x65\x4e"
+  "\x3c\x1f\x9e\xef\x19\xcf\x2d\xaf\x4b\x78\xbe\x4e\xe5\x73\xcb\x5d"
+  "\x43\xe3\xb9\x25\x74\x08\x3c\x37\xcb\xe3\xb4\x91\xc1\x73\x4b\xf2"
+  "\x55\xc4\xb3\x8f\xf2\xb9\x25\xc6\x1d\xcf\x7f\x8f\xe7\x78\xfe\xbb"
+  "\xda\x37\x3c\x1f\x5e\xea\xcb\x38\xd1\x89\x67\x83\x24\x9f\xcd\xd3"
+  "\x69\x90\x01\xe4\xb3\x41\x92\xcf\x3f\x28\xbc\x34\x9e\x0d\x2e\xf2"
+  "\xf9\xeb\xef\x3b\xf1\x6c\x9e\xe0\x19\xcf\x47\x9e\xe3\x78\x36\x5c"
+  "\xa7\xf2\xf9\x88\xff\xd0\x78\xfe\xba\xcd\x33\x9e\x0d\xf1\xf2\x18"
+  "\x78\x64\xf0\x7c\x64\xde\xd5\xc3\xb3\xc1\x47\xf9\x7c\x24\xcc\x1d"
+  "\xcf\x5f\x6b\x39\x9e\x0f\xb7\xf8\x86\x67\xb3\x47\xff\x6f\x43\x8d"
+  "\xc1\x5d\xf0\x2c\xc9\xe7\x56\x2b\xe0\x19\xe4\xb3\x41\x92\xcf\x4f"
+  "\x3e\xe8\x05\x9e\x5d\xe4\xf3\x51\x85\x13\xcf\xad\xc7\x3d\xe3\xb9"
+  "\xf5\x01\x09\xcf\xd7\xa9\x7c\x3e\x7a\x70\x68\x3c\x1f\xdd\x35\x04"
+  "\x9e\x9b\xe5\xf9\x85\x91\xc1\x73\xab\xfa\x2a\xe2\xd9\x47\xf9\x7c"
+  "\xb4\xdd\x1d\xcf\x66\x1b\xc7\xb3\x79\x87\x6f\x78\x3e\x46\x46\x66"
+  "\x7e\xe3\xb8\x15\xe7\x37\x7a\x70\x7e\xc3\xb9\xf7\x2f\x29\xb8\x91"
+  "\xe3\xb9\x17\xf0\xfc\xaa\x2b\x9e\xff\xde\x7f\x7e\xe3\xd8\xa7\x62"
+  "\x1f\x9e\x8f\x0f\xc0\xb3\x08\x78\xee\x65\x78\x6e\x73\xc8\xf3\x1b"
+  "\xa6\x8e\x0a\xc0\xc9\x69\x62\x5a\x08\x58\x2e\x91\xb0\xfc\x77\xc0"
+  "\x32\xd0\x50\x04\x1a\xd7\xb5\x34\x93\x38\x0b\xa7\x65\x0f\xd0\x58"
+  "\x74\xc5\x71\x4f\xbb\x80\xf8\x45\xdc\xca\x18\xae\x5f\x05\xd8\x4d"
+  "\xf9\x94\xd4\xa7\xc1\xb5\x0e\x2e\x3d\x5c\xe4\x53\x52\xd7\x0e\xd8"
+  "\x5d\xe1\x8a\xdd\x46\x09\xbb\x6d\x2f\x0d\x8d\xdd\x36\xdd\xd5\x9b"
+  "\xcb\x68\xe3\xf3\x5f\x7f\x8f\x0f\x89\xfb\xf1\x11\x6a\x4a\x6f\x96"
+  "\xf0\x79\x9a\xc4\xd9\x49\x30\x7d\x52\x3b\x5e\x1d\x4f\x42\x5e\x74"
+  "\x10\xa1\xf8\x69\x12\x52\xfc\x15\xb4\x5b\xee\xbf\xad\x44\xbd\xdf"
+  "\xf6\x57\x52\xd7\xd9\x4c\xea\x2e\xee\x23\x75\x22\x5c\xa7\xe1\x82"
+  "\xba\xc6\x25\xba\xb6\xdb\x22\xb5\xfb\x78\x01\x94\x35\xdd\x73\xbb"
+  "\x8f\x27\xb1\x76\x27\x40\xbb\x7b\x9c\xed\x36\x41\x3f\x00\xfe\x4c"
+  "\x16\xa5\xf9\x90\x38\x0b\x09\x58\x6d\xa7\xb4\x47\xc2\x3f\xf2\x67"
+  "\x7f\x93\x8d\xc4\xe9\x80\x67\xcf\x00\xfe\xdb\x2a\x89\x21\x03\xf0"
+  "\xdf\x63\x43\xdc\x59\x4c\x59\xdd\x80\xff\xb6\xed\x14\xe8\xd7\x8b"
+  "\xf8\xff\x3b\xe2\xff\x58\xad\xc8\xf0\x7f\x2c\xc3\x37\xfc\x9f\xf0"
+  "\x06\xff\x5e\xcc\x87\xb4\x23\xfe\x2b\x7a\x70\x3e\xc4\xb9\x07\xf4"
+  "\x52\xf8\x77\x91\xe7\x27\x5c\xf0\xdf\x3e\x04\xfe\x4f\xca\xf8\x37"
+  "\x5f\x7b\xfc\x9f\xbc\x04\xfe\x4f\x0e\x85\xff\x11\x9e\xfb\x38\x79"
+  "\x15\xf1\xdf\x7e\x09\xfc\xb7\x7b\x83\xff\x5a\xdf\xf0\x7f\xb2\x1f"
+  "\xfe\x4f\x48\xf8\x3f\xe1\x23\xfe\x4f\x79\x81\x7f\x6f\xe6\x4f\xfe"
+  "\x61\xc5\xf9\x93\x1e\x9c\x3f\x71\xee\x05\xbe\x04\xfe\x5d\xe7\x4f"
+  "\x4e\xb9\xe0\xff\x1f\x43\xe0\xff\xb4\x43\x9e\x3f\xb9\xf6\xf8\x3f"
+  "\x7d\x09\xfc\x9f\x1e\x02\xff\x23\x3d\x57\x72\xfa\x2a\xe2\xff\x1f"
+  "\x97\xc0\xff\x3f\xbc\xc0\xbf\xde\x47\xf9\x7f\xba\x1f\xfe\x4f\x49"
+  "\xf8\x3f\xe5\x23\xfe\x3b\xbc\xc1\xbf\x17\xf3\x2d\x67\x11\xff\x20"
+  "\xff\xf5\x35\x2e\x7b\xc2\x2f\x85\x7f\x17\xf9\xdf\xe1\x82\xff\xb3"
+  "\x43\xe0\xff\x8c\x8c\xff\xeb\x40\xfe\x9f\xb9\x04\xfe\xcf\x0c\x85"
+  "\xff\x11\x9e\x5b\x39\x73\x15\xf1\x7f\xf6\x12\xf8\x3f\xeb\x0d\xfe"
+  "\x7d\x94\xff\x67\xfa\xe1\xbf\x43\xc2\x7f\x87\x8f\xf8\xff\xc6\x0b"
+  "\xfc\x7b\x33\x3f\x73\x0e\xc7\xb3\x20\xff\x0d\xd1\x2e\x67\x03\x2e"
+  "\x81\x7f\xd7\xf9\x99\x6f\x5c\xf0\x7f\x6e\x08\xfc\x5b\x1c\xf2\xfc"
+  "\xcc\xb5\xc7\xbf\xe5\x12\xf8\xb7\x0c\x81\xff\x91\x9e\x8b\xb1\x5c"
+  "\x45\xfc\x9f\xbb\x04\xfe\xcf\x79\x81\x7f\x83\x8f\xf2\xdf\xd2\x0f"
+  "\xff\xdf\x48\xf8\xff\xc6\x47\xfc\x77\x7a\x83\x7f\x2f\xe6\x73\xac"
+  "\x6c\x3e\xa7\x07\xe7\x73\x9c\x67\x44\x2e\x85\x7f\x17\xf9\xdf\xe9"
+  "\x82\x7f\xeb\x10\xf8\x3f\x2f\xe3\xff\x3a\x90\xff\xe7\x2f\x81\xff"
+  "\xf3\x43\xe1\x7f\x84\xe7\x6e\xce\x5f\x45\xfc\x5b\x2f\x81\x7f\xab"
+  "\x37\xf8\xf7\x51\xfe\x9f\xef\x87\xff\x4e\x09\xff\x9d\x3e\xe2\xff"
+  "\xc2\x08\xcd\xff\x5c\x2c\xc3\xf9\x1f\x51\x9d\x19\xdd\x5b\x16\x93"
+  "\x25\x16\xe5\x46\x05\x2b\x34\xc4\xae\xce\x26\xa6\x54\x2b\x79\xec"
+  "\x02\xf0\x44\x77\x81\x3c\x75\x21\x04\xe3\x05\x46\x52\x18\xff\xbb"
+  "\x9d\x11\x85\xcb\x9e\x6f\xd7\x6d\x5a\x45\x94\x8e\xa0\x6c\x76\x8e"
+  "\xd0\x74\xc2\x46\xb0\xcd\x99\x48\x83\xd3\x4e\x1a\xe0\x1c\x1c\xfd"
+  "\x46\x1b\x52\x9e\x03\x79\x7a\xcc\xa4\x0d\xf0\x52\xd7\x66\x06\xda"
+  "\xaf\x63\xd8\x42\x5e\x40\x7d\xe6\xbd\x76\x96\x28\xed\xc7\xc2\x26"
+  "\x03\x8f\x43\x03\x5f\x20\x8a\xf0\x36\x2a\x22\x2f\x91\x47\xc8\x57"
+  "\xcd\x3a\xdc\xaf\x74\xf1\x77\x0d\x80\x6f\xfb\x31\xed\xe4\x72\xc8"
+  "\x37\xf2\xf3\x32\x17\xd9\xfa\x07\xdc\xe7\xd4\xb5\x00\x2d\x73\x2f"
+  "\xf8\xc8\xa7\x8b\x5e\x9c\x7f\xf1\x66\x9e\xc2\x16\x8d\xf3\x14\xc0"
+  "\xa7\x1a\x2f\xf9\x54\xeb\x76\xa6\x75\xc4\xf9\xd4\xd5\xe6\x1d\x9f"
+  "\x6c\xf7\xf6\xe3\xd3\x08\xcf\x1f\xd8\x24\x7f\x30\x5d\x2d\x9c\x4f"
+  "\x5d\xd3\x7d\xe3\x93\xcd\xa7\xfd\xbf\x03\xc7\xd3\xdd\x1d\x38\x9e"
+  "\x16\x61\x3c\xed\x1d\x9f\xf4\x31\x6e\x67\x70\x47\x9c\x4f\xdd\x45"
+  "\xde\xf1\xa9\xfb\xb8\x3b\x9f\x46\x7a\x9c\xdb\x2d\xc5\x83\xee\xde"
+  "\xc0\xf9\x64\xab\xf3\x8d\x4f\xdd\x5e\x9c\xff\xf0\x66\xdc\xd7\xbb"
+  "\x19\xc7\x7d\xc0\x27\x2f\xfb\x93\xbe\xd6\xed\xcc\xf0\x88\xf3\xa9"
+  "\x77\x8e\x77\x7c\xea\x2d\xee\xc7\xa7\x11\x1e\x8f\xf5\xc6\x73\x3e"
+  "\xf5\x46\x70\x3e\xf5\xa4\xfa\xc6\xa7\xde\x8a\x91\x19\x9f\x38\xe6"
+  "\xe1\xf8\x44\x84\xf1\x89\x77\x7c\x32\xc4\xb8\x9d\x71\x1e\x71\x3e"
+  "\xd9\x5b\xbc\xe3\x93\xe3\x2e\x77\x3e\x8d\xf4\xb8\xc1\x41\x38\x9f"
+  "\xec\x4d\x9c\x4f\xf6\x70\xdf\xf8\xe4\xf0\x18\xff\x73\x78\x76\xb4"
+  "\xd8\x86\x76\x34\xf0\xc9\xcb\xfe\x64\xa8\x75\x3b\x93\x3d\xe2\x7c"
+  "\x12\x37\x78\xc7\x27\xf1\x70\x3f\x3e\x8d\xb0\x7d\x2b\x56\x72\x3e"
+  "\x89\x19\x9c\x4f\x8e\x1a\xdf\xf8\x24\x7a\xb3\xff\x73\xd0\x73\x58"
+  "\x03\x6c\x3e\x81\x94\x5e\x57\x36\x9f\x40\x22\xbd\xe2\x95\x40\x0a"
+  "\xae\xa8\xcd\x27\x10\xb6\xff\x1f\xee\x5a\xce\x2b\xaa\xf3\x89\x57"
+  "\x02\x29\xf3\xf5\xfc\xd6\x00\xbb\x4f\x10\xe6\x5d\x57\x76\x9f\xa0"
+  "\xf0\x4e\xfe\x09\xc2\x5d\x57\xd4\xee\x13\x04\x2e\xff\x04\x05\x97"
+  "\x7f\x85\x0a\xdf\xe4\x9f\x20\x78\x21\xff\x06\x3f\xf7\x35\xc0\xf6"
+  "\x13\xfc\xda\xaf\x2b\xdb\x4f\xf0\xcb\xf7\x8e\x57\x7e\x47\xaf\xa8"
+  "\xed\x27\xf8\xed\xe0\xbc\xf2\xcb\xe2\xbc\x12\x6a\x7d\xe3\x95\x9f"
+  "\xc7\xf8\x2f\x97\x3a\x2f\x36\xc0\xfe\x13\xfc\xaf\x2f\xfb\x4f\xf0"
+  "\xf7\xce\xfe\x13\xfc\xaf\xac\xfd\x27\xf8\x73\xfb\x4f\xf0\xe7\xf6"
+  "\x5f\xa1\xd2\x37\xfb\x4f\xf0\xf7\xc9\xfe\x73\xe7\x95\x64\x03\x0a"
+  "\xa3\xa3\xae\x2b\x1b\x50\x18\x65\xf6\x8e\x57\xa3\xef\xbe\xa2\x36"
+  "\xa0\x30\x5a\xc9\x79\x35\xaa\x99\xf3\x6a\x94\xc6\x37\x5e\x8d\xf6"
+  "\x18\xff\xf0\x52\xe7\xd3\x06\xd8\x81\x82\xaa\xe3\xba\xb2\x03\x05"
+  "\x95\x77\xe3\x5f\x41\x75\xfc\x8a\xda\x81\x82\x8a\x8f\x7f\x05\x15"
+  "\x1f\xff\x16\x8e\xf6\x6d\xfc\x2b\xa8\xbc\x18\xff\x7a\x31\xef\x27"
+  "\x8c\x8d\x45\x1b\xd0\x51\x94\x19\x1d\x0c\xf4\x0f\x4e\x27\x42\x4f"
+  "\x38\xf0\x4b\x0d\xfc\xca\xd6\x90\xde\x22\xe0\x97\xc5\x4e\x1e\x7b"
+  "\xee\x08\x6d\xe8\x70\x90\x1e\xe0\x55\x37\xd8\x81\x26\x4b\x3b\x9e"
+  "\xd1\xfb\xb7\x56\x61\xcc\xf1\x27\x9f\x0b\x21\xc8\x2f\xa4\xbf\x43"
+  "\x65\xd7\x51\xe0\x17\xe3\x9f\x3a\x4f\x65\x2f\xca\x36\x2e\x38\x73"
+  "\x84\xae\x36\x53\x5a\x9f\x64\x43\xdf\x91\x59\xf5\x49\xcd\x24\xae"
+  "\x8d\x04\x68\x1e\x47\xbe\x8c\xf9\x1d\xa6\x9b\x2c\xcd\x04\xfd\x7e"
+  "\xb2\x39\xf0\x23\xda\x50\xfb\x97\x5a\x35\xfa\x6f\xc2\x73\x85\xb2"
+  "\x8f\x26\xd3\xe9\x2d\x8c\xff\xfd\xe7\x54\x19\xff\xbf\xd4\x86\xbc"
+  "\x8a\xe7\x13\x47\xdc\x16\x1c\xc3\xe6\xff\xc4\x23\x61\x93\xe5\x3a"
+  "\xae\x4e\xa6\x14\xea\x38\xbe\xc1\x6a\x21\x58\xcf\x06\xab\x91\x18"
+  "\x52\x49\x48\x43\x4f\x3b\xd1\x5b\xa9\xa5\x21\xeb\x14\x89\xbb\x80"
+  "\xeb\x02\x88\xa7\x31\x87\x39\xbf\xc7\xa8\xc4\x23\xda\xc9\x70\x6f"
+  "\x6a\x68\x24\x24\x38\x1b\x68\x6d\x27\x02\x3b\xaf\x29\x10\x15\xd0"
+  "\x2b\xc9\x94\xd5\x4a\x68\x50\x4e\x94\xc9\xfe\x15\xd2\x33\x09\xde"
+  "\xcf\xeb\x5b\x6f\x08\xca\x79\x10\xd3\x90\xb6\xb8\xcf\xd4\xa4\xb3"
+  "\xb0\x3c\xf2\x7b\xce\xbb\x2c\x62\x4a\xef\x21\x0d\x76\x42\xcc\x42"
+  "\xc0\xae\x03\xf1\xcd\x80\xaf\x00\x1f\xe5\xf6\xd8\xf8\x11\x99\xaf"
+  "\x14\x02\x77\xa0\xdd\x0a\xf8\xaa\xe1\x75\xf4\xef\xf4\x02\x5f\xb5"
+  "\x4e\x7c\x05\xce\xbf\x3c\x7c\xa9\x2f\x8c\x30\xbe\x46\xd8\x7e\x55"
+  "\x1b\x2f\x0f\x5f\x81\xf7\x72\x7c\xa9\x93\x38\xbe\x02\xe7\x38\xf1"
+  "\xe5\xdf\x79\xe5\xf0\xa5\x0e\xe5\xf8\x1a\xdb\xe4\x1b\xbe\x02\xab"
+  "\x47\x64\x9e\x55\x08\x51\xa3\xad\xed\x28\xd2\x4b\xf2\x6b\x6c\xeb"
+  "\xa5\xf1\xa5\x77\x91\x5f\xc1\xbf\xbf\x3c\x7c\x05\x3f\x31\xb2\xf8"
+  "\x1a\x69\x9b\x3b\x58\x73\x79\xf8\x0a\xde\xc6\xf1\x15\x54\xcb\xf1"
+  "\x15\xbc\xd9\x89\xaf\xb1\xad\x57\x0e\x5f\x41\xa9\x1c\x5f\x41\x73"
+  "\x7c\xc3\x57\x88\x4f\xfe\xaf\x06\x8e\x0f\xc6\x27\xe3\xf8\x00\xf0"
+  "\x25\xc9\xaf\x71\x9f\x79\x81\x2f\x17\xf9\x35\xde\xff\xf2\xf0\x35"
+  "\xee\x2f\x23\x8c\xaf\x11\x1e\x27\x8c\xcb\xba\x3c\x7c\x8d\x73\x70"
+  "\x7c\x8d\xd3\x72\x7c\x8d\xb3\x3a\xf1\x35\xee\xb3\x2b\x87\xaf\x90"
+  "\x26\x8e\xaf\x90\xcd\xbe\xe1\x6b\xbc\x67\xff\xcf\xc3\x99\xd7\x16"
+  "\x42\xeb\x70\x4c\xe3\x28\x32\x48\xf2\xeb\x07\x85\x97\xc6\x97\xc1"
+  "\x45\x7e\x85\x26\x5e\x1e\xbe\x42\x27\x8c\x2c\xbe\x46\x7a\x6c\xf3"
+  "\x1d\xf3\xe5\xe1\x2b\xf4\x17\x1c\x5f\xdf\xc9\xe7\xf8\x0a\x5d\xe4"
+  "\xc4\xd7\x0f\x0a\xaf\x1c\xbe\xbe\x33\x87\xe3\x6b\xbc\xd5\x37\x7c"
+  "\x85\x7a\xe3\xff\xf5\xd2\xf3\xf1\xc2\x4d\x11\x38\x0e\x03\x7c\x49"
+  "\xf2\xeb\xc9\x07\xbd\xc0\x97\x8b\xfc\x9a\xb8\xf7\xf2\xf0\x35\x71"
+  "\xcd\x08\xe3\x6b\x84\xc7\x63\x13\xa3\x2e\x0f\x5f\x13\x3f\xe0\xf8"
+  "\x9a\xd0\xce\xf1\x35\x71\x97\x13\x5f\x4f\x3e\x78\xe5\xf0\x35\x61"
+  "\x33\xc7\xd7\x84\x45\xbe\xe1\xeb\x26\x6f\xfc\x9f\x7a\xb9\x8e\x30"
+  "\xa9\xf4\xf2\xc6\x90\x93\x66\x5e\x1e\xc6\xc2\x0e\x5d\xdf\x63\xc8"
+  "\xb0\xed\x97\x87\xb1\x49\xb7\x70\x8c\x85\xc5\x72\x8c\x4d\x0a\xbb"
+  "\x3a\x63\xc8\x9b\x6c\x1c\x63\x37\x55\xfb\x86\xb1\x49\x23\xb8\xfe"
+  "\x31\xc5\x7a\x79\xe3\xc8\x29\xc5\x97\x87\xb1\x29\xf7\x5e\xdf\xe3"
+  "\xc8\x29\xaa\xcb\xc3\xd8\x94\x8d\x1c\x63\x93\xab\x38\xc6\xa6\x64"
+  "\x5c\x9d\x71\xe4\xe4\xc5\x1c\x63\x93\x7d\x5c\xb7\x09\xf7\x62\xff"
+  "\x9b\xb7\xeb\x36\xd3\xe2\x2f\x6f\x2c\x39\xf5\xdc\xe5\x61\x6c\xea"
+  "\xeb\xd7\xf7\x58\x72\x6a\xf2\xe5\x61\x6c\xea\x29\x8e\xb1\xa9\xa1"
+  "\x1c\x63\x53\xcd\x57\x67\x2c\x19\x6e\xe4\x18\x0b\xcf\xf2\x0d\x63"
+  "\xd3\x12\x46\x6e\xbd\x49\xb3\xfb\xf2\xc6\x93\x9a\x27\x2e\x0f\x63"
+  "\x1a\xff\xeb\x7b\x3c\x79\x73\xe3\xe5\x61\x4c\xb3\x80\x63\xec\xe6"
+  "\x74\x8e\x31\x4d\xf4\xd5\x19\x4f\xde\x3c\x9d\x63\x6c\x5a\x9b\x6f"
+  "\x18\xd3\x78\xe1\xff\xdf\xdb\x75\xb2\xdb\x34\x97\x37\xa6\xbc\xf5"
+  "\xbd\xcb\xc3\xd8\xad\x2b\xae\xef\x31\xe5\xad\x73\x2e\x0f\x63\xb7"
+  "\xee\xe4\x18\xbb\xa5\x85\x63\xec\xd6\xca\xab\x33\xa6\xbc\x25\x9f"
+  "\x63\xec\x96\x18\xdf\x30\x76\x5b\xc4\xc8\xad\xef\xcd\xd8\x70\x79"
+  "\xe3\xca\x19\x53\x2f\x0f\x63\xd3\xeb\xaf\xef\x71\xe5\xf4\x2d\x97"
+  "\x87\xb1\x19\x13\x38\xc6\xa6\x47\x71\x8c\xcd\x50\x5f\x9d\x71\xe5"
+  "\x6d\x1d\x1c\x63\xb7\xf9\xe6\x8f\x42\x98\x31\xc0\xff\xd5\x8a\x55"
+  "\x69\xcb\x92\x57\x24\x68\x56\xac\x4a\x4d\x79\x4e\xf3\xfc\x8a\x75"
+  "\x89\xf7\xce\x58\x13\xa1\x49\x49\xd7\xa4\xac\x58\xf5\x4b\x29\x21"
+  "\x61\x0c\x79\x3c\x31\x79\x59\x3a\xa6\x40\xee\x5f\xae\x5a\x99\xb8"
+  "\x2a\x55\x93\x92\xf8\xdc\x9a\x15\x29\x89\xf8\xff\xf3\x9a\xe5\xab"
+  "\x53\x20\xe1\x99\xc4\x15\x69\x89\x9a\xa7\xd7\x2c\x5f\x9e\x98\xf2"
+  "\xfc\x18\xb2\x60\x4d\x72\xea\x0a\x5d\x72\xa2\x26\x7a\xc1\x03\xb3"
+  "\x16\xcd\xff\xc9\xa2\xfb\xef\xc7\xe0\x64\x2e\xb1\xc9\xc2\x69\x51"
+  "\x1e\x62\x4e\x79\x42\x98\xfd\x5c\x43\x18\x61\xf1\x6c\x37\x75\x92"
+  "\x90\xc2\x14\xa2\x2c\xe8\x24\xaa\xe2\x4e\xa2\xd6\xfc\x8a\x44\xd1"
+  "\x82\x8f\x4b\x4b\x3a\x49\x28\x2d\x89\xcd\x17\x0b\xba\x2b\x68\x41"
+  "\xb7\xd9\x12\xd0\x8a\x69\x21\x62\xc1\xd1\x5a\xf8\x4d\x28\xd0\x56"
+  "\x49\x0b\xec\x0b\x5b\x85\xd9\x91\x96\x80\x63\x3a\xc3\x29\x22\xd0"
+  "\x31\xdf\x35\xfe\x59\xb4\x08\x1f\x63\xd4\x49\x68\x3b\x11\xbe\xd7"
+  "\x0c\x57\x0d\x11\xb4\xa9\x70\x6d\x80\xab\x14\xae\x6a\xb8\x8c\x70"
+  "\x35\xc1\x65\x86\xab\x03\x2e\x2b\x5c\x30\x82\x9b\xa9\x84\x4b\x0d"
+  "\x57\x3e\x5c\x95\x70\x41\xde\x99\x8d\xbc\x9c\x99\x2d\x44\xb8\x5d"
+  "\x05\x57\x24\x5c\x31\x70\x41\xfe\x3b\xc2\xe1\x2a\x83\x6b\x0e\x5c"
+  "\x51\x70\x41\xfa\x1d\xc9\x70\xe1\xef\xcd\xfc\x5d\x44\x34\x5c\x59"
+  "\x04\xea\x79\xe9\x2b\xa2\x02\x2e\xf8\x6e\x44\x1d\x11\x66\x45\xc0"
+  "\x05\xf5\x9d\x65\x1e\xe2\x37\xda\x4b\x94\x19\x13\x9c\x7d\xb3\x99"
+  "\xc5\xc0\x13\xb4\x77\xd1\x1c\xe2\x47\x0b\x8e\xe9\x74\xb7\x13\xc5"
+  "\x69\x41\xab\x30\x6d\x00\x39\xa3\xea\xae\x60\x31\x1d\xe1\x19\x69"
+  "\xd6\x55\xa8\x25\x66\x92\xcc\x62\xb8\x0d\x0f\x6f\x5a\x22\xfd\x3e"
+  "\xca\xac\x18\x15\xcf\x62\xc0\x15\xbe\x9b\x4e\x0d\xf1\xaf\xb2\xd8"
+  "\x6f\x40\x43\x3c\x97\x45\xf3\xdf\xb1\x50\xd5\xce\x32\xec\xf3\xc6"
+  "\x75\x58\xaf\xef\x1d\xe2\xfd\x0b\xde\x43\xdd\x2c\x81\xb1\xf9\x50"
+  "\x4f\x25\x3e\xd3\x82\xd6\xd2\x9e\xc0\x8d\x66\xfc\xbf\x7b\x5b\x4c"
+  "\x08\x2d\xca\x55\xe1\x38\xdb\xa8\xff\x4f\xd2\x0a\xbf\xeb\x09\xcc"
+  "\xab\xd4\x3c\x1e\x4c\x5b\x79\xd9\x02\xd4\x21\x59\x2e\xab\x27\x30"
+  "\xb6\x94\x6e\xc9\x6b\xa4\xc5\x80\x21\xa9\x3c\x11\xca\xa3\x45\xd9"
+  "\x55\x90\xaf\x16\xd3\x69\x59\x8c\x56\xfe\x1f\xee\x35\xb4\x24\x37"
+  "\x06\xef\xc1\xd9\xc4\xca\x9e\x73\xa2\x08\xbf\x87\x10\x94\x75\x1d"
+  "\xc2\xcc\x95\x77\x36\x12\x85\xf1\x71\xac\xf7\xcc\xb9\x86\x46\x2a"
+  "\x6a\xf4\x7e\xf0\xfd\x99\x77\xf7\x7d\x77\x52\x5e\x2d\xc6\x48\x15"
+  "\x0b\x67\x34\x62\x0c\x3e\xfc\x2d\xd6\xed\x95\xf1\x44\xf9\xda\x6f"
+  "\x88\x0a\xdb\xd8\x55\x38\x33\x41\x8e\x43\x87\xbf\x11\x20\xff\x23"
+  "\x3f\x36\x50\x97\xb2\xbf\x4f\x59\x7b\xbe\xd7\xc4\x69\x3a\x73\xb3"
+  "\x59\xa1\x9c\x87\xf9\x35\xb7\x32\x5a\x1e\x92\xde\x37\x23\x3f\xb1"
+  "\x7c\xb1\x38\x8f\xe0\x33\xc6\xb9\x0b\x06\xc4\x6a\xf4\xd3\xab\x39"
+  "\x8d\x72\x55\x58\x0e\xe6\x17\x4b\xb2\x91\x4f\xe9\x22\xb4\xd7\x91"
+  "\x43\xb4\x9a\x55\x24\xaa\x55\xb8\x5d\xe1\x28\xa8\x8e\x84\xf7\xd0"
+  "\xef\xaa\xe7\x40\x7e\x0d\xa3\x77\x71\x76\x85\x59\x98\x69\x85\x77"
+  "\x73\xfa\x62\x5f\x72\x3a\x2b\xc4\x82\xea\xe8\xae\xc2\xdb\xb5\x66"
+  "\xc5\x94\x68\xb9\x0d\x4c\xc6\x39\xf3\x49\x3c\xbd\x3d\xdc\x12\x50"
+  "\x1d\xdd\x9b\x46\x1b\x37\x7d\x45\x08\x7c\x93\xf6\x5c\xa4\x75\x19"
+  "\x0b\xa9\xad\xe4\xdf\x09\xa9\x5b\xda\x42\x0c\xcb\x48\xf8\xd8\x6c"
+  "\x6a\x89\x73\x90\xe0\xb1\x2d\xc1\xb4\x7e\x61\x0b\xc8\xe8\x0b\x24"
+  "\xa3\x91\xb6\x37\xe8\x76\x93\x8c\xe3\x44\x9d\xb9\x82\x84\x1a\x16"
+  "\x52\x8b\xbe\x8e\xda\x4c\xe9\x2d\xa4\xc1\x0a\x97\xae\x1e\xf2\x1d"
+  "\x84\x6b\x37\x31\xac\x25\xca\xc7\x40\x9e\xea\x2f\x10\x75\x83\xee"
+  "\x02\xa4\x9d\x21\x19\x4b\xa9\xbd\xbe\x0e\xf3\xed\x25\x71\x76\x4b"
+  "\x70\xe6\x19\xa2\x2c\xff\x77\x3c\x5b\x76\x98\xbc\x06\x75\xe9\x09"
+  "\xe8\x6e\xec\x2e\xb0\xc7\x9f\x4f\xa3\x76\x68\x8b\xd5\x4c\xee\xd1"
+  "\xb8\xb5\x05\xeb\x8c\x71\x43\xa1\xbd\x98\x47\x2c\xce\xce\x5f\x62"
+  "\x47\x9c\xdf\xde\x0e\xb2\x98\xc8\xef\xf1\x9d\x25\x30\x1b\xf0\x73"
+  "\x47\x68\x9c\x9d\x76\x61\x7e\x6c\x37\xd0\x28\x4a\x6a\x7f\x94\x9f"
+  "\x8e\x28\xbb\x0a\xef\x88\x37\x2b\xa6\x69\x5c\x78\x88\x3c\x19\x25"
+  "\x7f\x4f\xca\x93\x61\x56\x84\xb3\xd8\x8b\x22\x7b\xa7\x4d\xc0\xbc"
+  "\x90\x0e\xfc\x9f\xaa\xe3\xf5\xbb\x63\x31\xa6\x49\xb2\x14\xfb\x6d"
+  "\xb2\x88\xfd\x3a\x7f\xa7\xce\x11\x98\x1b\x42\x05\x6a\x03\x3c\x57"
+  "\xd2\xf3\x61\xea\xc7\xec\xd4\x26\x16\x67\x55\x80\xbc\x54\x63\x9c"
+  "\x54\x9e\x3f\x62\x16\xbc\xaf\xd2\xa4\xb1\xff\x27\xe0\x77\xc4\x6d"
+  "\x31\x04\x65\x6b\x5c\x23\xe6\x5f\x40\x4a\x52\x40\xf6\x16\xe7\x62"
+  "\xec\x74\xa5\x18\x98\x5d\xdd\xbd\x35\x0f\xfb\x0c\xa1\x80\x31\x5a"
+  "\x14\x5b\xd5\x57\x4e\x0e\xf1\x87\xfa\x74\x50\xf8\x3d\x2d\xca\xaa"
+  "\x90\x78\x7f\x90\x63\xf3\x8e\x76\xec\x77\x50\xaf\x54\x48\xf7\x6f"
+  "\x15\x22\x52\xf1\x8c\x26\x3c\xef\x60\xb1\x24\x85\x88\xb5\x1c\x33"
+  "\x3b\x75\x6e\xcf\x02\xd2\x0f\xfa\x24\xc8\x01\x6e\x5f\x44\x6c\x75"
+  "\xf6\x0b\x8e\x63\xde\xbf\xb3\xa0\x4e\x33\x9b\xc4\x1c\x3f\x11\xf2"
+  "\x29\x5a\x39\x1d\x84\x9e\x80\xea\xb9\x5d\x85\x11\x35\x66\x22\x9a"
+  "\xdd\xf8\x59\x58\x55\x8a\x71\x2b\xa1\x2e\x7e\x50\xe6\x39\xb8\x8f"
+  "\x86\xfb\x85\x3d\x8d\xa8\x6b\x59\xb9\x63\xf1\xff\x57\x26\x52\x4b"
+  "\x34\x8c\x5c\xce\x0b\x48\xf7\x59\x6a\x33\x79\x8a\xc5\x77\x2d\xc4"
+  "\xd8\x9d\x90\x86\x79\x20\x7d\xba\x99\x2c\xd9\xc0\xcb\xd7\xd6\x5a"
+  "\x51\x66\xb9\x95\x3f\xeb\x47\xbc\x7c\x5e\x2e\x96\x27\x97\xbd\xed"
+  "\x65\xda\x21\x95\x9d\x24\x97\x5d\x0c\x69\x72\xf9\xd1\x2b\xfb\xbe"
+  "\x91\x0f\xdf\x50\xbb\xb6\x61\xeb\xcb\xd4\x8a\x65\xc0\xbb\xed\x66"
+  "\xb2\x7c\x31\xbe\x2b\x80\x34\xfc\xad\x0b\xa6\xfc\x30\x72\xd4\x9e"
+  "\x3a\x56\x46\x9d\x99\x24\xb4\xb9\xca\x0d\xa0\x51\xa0\x2c\x6b\xa5"
+  "\xb2\x2c\x72\x59\xce\x72\x64\x4c\xed\x8e\x94\x78\x8a\xe5\xaa\xb1"
+  "\xdc\xae\xc2\xd9\x1a\x33\x59\xa6\x75\x6d\xbb\x24\x3b\xc3\x20\x8f"
+  "\x42\xc2\xa4\x02\xe5\x92\x5c\x6f\x8c\xdd\x49\x0b\x67\x60\x4c\x5b"
+  "\x05\xc8\x40\x02\x7d\xa9\x14\xca\x49\xea\x27\x03\x95\x98\x4f\x2c"
+  "\xfc\xee\x2c\x16\xbb\x74\x22\x6d\x87\x3c\x45\x6e\xf1\x3a\x05\x72"
+  "\x1f\xa4\x55\xc8\x71\x43\x4b\x20\x8f\x59\xf8\xee\x52\x4f\xb6\xb4"
+  "\xfe\x16\x22\x98\xca\xcc\x68\x93\x22\xae\xe6\x99\xc2\xad\xc4\x54"
+  "\x26\x12\xb1\x3c\x26\x32\x4a\x4f\x8d\x27\x84\x3b\xa7\x62\xbc\xe7"
+  "\xe1\xe9\xb9\xd9\x2c\xfe\x23\xed\x01\x5b\x2d\xe3\x5f\x08\xea\xb6"
+  "\xb3\x42\xe4\x02\x93\xa5\x93\xf5\x2f\xf8\x9f\xe9\x82\xdf\x82\x6d"
+  "\x87\xf6\x1d\xd8\xd4\x49\xa5\x02\xb7\xf1\x44\xc8\x5b\x8e\xe9\x68"
+  "\xff\x81\xed\xf9\x9a\xcb\x3b\x5a\xfe\x70\x3b\xa7\x5d\xa4\x3f\xd2"
+  "\x91\xd5\xd7\xfe\xb0\x11\xeb\x2c\x96\x3d\xdc\x8e\x6d\x30\xa4\x53"
+  "\xd1\x64\xef\x32\x62\x3c\x5d\x4d\x1a\xda\xa6\x77\x1e\x8d\xdb\x46"
+  "\xa8\xb8\xed\xe1\xf6\xe1\xb5\xe1\x4e\xb6\xff\x17\xec\xef\xb3\x96"
+  "\xa9\x0f\xb7\x63\xfc\xe4\x4d\x7a\x7f\xd5\x43\x65\xd4\x78\x7e\x5a"
+  "\xcc\xff\x67\xef\x7d\x00\xa2\xaa\xd2\x86\xf1\x67\x2e\x83\x0e\x04"
+  "\x32\x19\xd5\xd4\x52\x8d\x2d\xd6\x54\xfe\x41\xd3\x32\xd3\xa4\xc2"
+  "\xc2\x42\xa1\xb4\x96\xd2\xfc\x17\xba\x63\xa1\x12\x92\xa0\x02\x83"
+  "\x93\x15\x12\x2a\x15\x19\x16\x02\xfb\xae\xfb\x7d\xb6\xaf\xbb\xb9"
+  "\xef\xe7\x7e\x1f\xfb\x7e\xb6\xcd\x2e\x58\x6c\x01\xe3\xbe\xaf\xed"
+  "\xb2\xfb\xd9\x36\xf2\x92\xb1\x2e\xea\x14\x63\x8c\x30\x33\xe7\xf7"
+  "\x3c\xe7\xdc\xcb\xdc\x3b\xcc\x28\xb8\xbd\xef\xf7\x6d\xbf\xa8\xeb"
+  "\xdc\x7b\xce\x73\x9e\xf3\x9c\xe7\xdf\x79\xce\xb9\xe7\x9c\x9b\xd2"
+  "\x57\x91\xa2\x57\xbe\x4f\x3b\x32\xbc\x29\x7a\xa5\xed\x75\x72\xdb"
+  "\xb1\x2e\x3e\x67\x33\xb9\x86\x7f\x1f\x1b\x9f\x53\x66\x45\x92\x17"
+  "\xf6\xcd\x26\x2a\x8b\x6d\x4f\xad\x57\xf8\xe4\x73\xd3\xb7\xc1\x2f"
+  "\x3f\x25\xa5\xfc\x3e\xb3\xd8\x01\xfc\x2c\xfc\x1d\x5b\x4d\x23\xa4"
+  "\x8b\xcf\x7f\xb7\x63\xec\x9f\xe9\x7b\x9f\x09\xdf\x97\x72\x7e\x81"
+  "\x8c\x8f\xf2\x14\x59\xd5\xc9\x31\xf9\xc8\xeb\x98\x12\x71\xfe\x53"
+  "\xd5\x2e\xe3\xd0\x76\x4d\x79\xe7\xd2\xdb\x35\xa5\x60\x68\xbb\xa6"
+  "\xfc\xfe\x1b\x6e\x57\xc4\xf7\x9f\xaa\x76\x99\x87\xb6\x6b\xea\xd6"
+  "\x4b\x6f\xd7\xd4\x8c\xa1\xed\x9a\xfa\xce\x37\xdb\xae\xa9\x07\x87"
+  "\xd1\xae\x94\xa1\xed\xba\xfd\x89\x4b\x6f\xd7\xed\xc9\x43\xdb\x75"
+  "\xfb\xd6\x6f\xb6\x5d\xb7\x47\xfc\xfe\x59\x44\x7f\xb8\xf3\xa5\xe5"
+  "\xc2\x1f\x4e\x9b\x38\x72\x7f\x78\xbb\x77\xa8\x3f\x9c\xfe\x54\xd0"
+  "\x1f\x4e\x9f\x77\x49\xfe\x70\x67\x86\x1c\x4f\x4c\xbf\x72\x88\x3f"
+  "\xac\xcc\x68\x08\xef\x0f\xa7\x7d\xc9\xfd\xe1\x8e\x8c\x86\x91\xb5"
+  "\x61\xda\xe1\x41\x7f\x18\x9f\xd1\xa0\xf1\x87\x63\x5e\x5a\xde\x57"
+  "\x31\x3d\xf1\xd2\xfc\xe1\xf4\xc4\xa1\xfe\x70\x5a\x81\xd6\x1f\x4e"
+  "\x8f\xb8\xd6\x1b\xf5\xb0\x26\x9c\x3f\xcc\xf4\x9d\x65\xb2\x6e\xd4"
+  "\x8c\x90\x9e\x7d\x17\xa8\xcb\x7c\x91\xba\x46\x38\xef\x72\x87\x31"
+  "\x62\x5d\x86\x5f\x54\x61\x9c\x61\x2c\xf9\x11\x48\x27\x8b\x41\x6a"
+  "\x4f\xea\x00\x67\x91\x17\x26\xe5\xa1\x4e\xd8\x61\x56\x7b\x6d\x0f"
+  "\xb4\x27\x9d\x04\x16\xf3\x8b\x2a\xf6\xdf\xd2\x1b\x52\xf3\x49\x37"
+  "\xef\xf8\x9d\xb3\xc0\x3b\x42\xdd\xbc\xa3\x5a\xd1\xcd\x76\x1f\xea"
+  "\xe6\x46\xd2\xc7\x3b\xcf\x3b\x7b\x4e\xc9\xba\x79\xe7\xe7\x83\xf2"
+  "\xb1\x0b\xfd\x0c\xab\x9b\x68\x13\x5a\xdd\xdc\x6a\x14\xba\x79\xe7"
+  "\x2f\x86\xea\xe6\x56\x63\x78\xdd\xbc\x73\x87\xd0\xcd\xad\xc6\x91"
+  "\xb5\xe1\xce\xec\xa0\x6e\x6e\x35\x6a\x74\xf3\xa6\xf4\x86\xbe\x8a"
+  "\x3b\x0f\x5e\x9a\x6e\xde\x79\x50\x69\xfb\x5e\xb9\xed\x98\x66\xd4"
+  "\xea\xe6\x9d\x11\xbf\x75\x4d\xdf\x5f\x47\x7f\x18\x77\x4a\x9a\xd1"
+  "\xe8\xc7\xb8\x35\x50\xfe\x45\x79\xa6\x9f\xf5\xd1\x77\xd8\x99\x34"
+  "\x0d\x58\xa1\x25\xae\x0f\xc7\x94\x7d\x7d\x56\x03\x8b\xfd\xc5\xf5"
+  "\x6c\xc0\x04\x48\x7b\x02\xeb\xb3\x8c\x41\x9e\x25\xe3\xef\xd8\xbd"
+  "\x1b\x21\x11\x2f\xd3\x5e\x99\xaf\x78\x9f\xc2\x0a\x4d\xb1\x3b\x37"
+  "\xc2\x84\x04\x0f\x18\x90\x86\xec\x84\xad\x46\xc0\x31\x7f\x22\xdd"
+  "\x33\x7b\xfd\xc1\xfa\xaf\x41\x4f\xf3\x89\x81\x18\xac\xaf\x28\x81"
+  "\xb1\x0d\x16\xa8\xcf\x47\x7a\x24\x30\xd5\x4b\xec\xa0\xbf\xd0\x22"
+  "\xb1\x31\x2f\x7d\x8f\x6d\xc9\xe6\x34\x05\x92\xd3\x5d\xa8\x43\x2e"
+  "\x66\xb3\x52\xbd\xa9\xf4\x3d\x60\x76\x53\x7a\x17\xeb\x33\xc5\xee"
+  "\xf8\x1a\x26\xd4\x6f\x84\xe4\xba\x8d\x60\x61\x03\x16\x09\x79\x90"
+  "\xbd\xf4\x39\x23\xc9\x1d\xdb\x80\x75\x6d\xc4\xba\x50\x96\xfe\xed"
+  "\x58\x97\x0f\xeb\x3a\x8b\x75\x9d\xc1\xba\xec\x58\x97\x5d\xd4\x35"
+  "\x32\x9e\xdf\x95\x7c\xa1\x79\xdf\xcc\x92\xeb\xe9\x7c\xda\x2f\x12"
+  "\x8a\x46\xa7\xd3\x1c\x70\xef\x16\xeb\x08\xf5\xfd\xae\x6d\x91\xf0"
+  "\xef\xfa\x39\x24\x31\xc3\x89\xc6\x05\x2f\x7e\xc6\x32\x7d\x00\x2f"
+  "\xfe\x1c\x26\x90\xcd\xb5\x7b\x4f\xa3\x9d\x9d\x68\x3c\x62\xe9\x19"
+  "\x69\x5d\x11\xf7\xbf\x56\xd8\xd9\xd1\x40\x1c\x8e\x45\xe3\x5e\xb2"
+  "\xec\xb2\xb3\xa2\x81\xa4\x74\xe8\x4f\x4a\x37\x2f\xf3\x19\x51\xaf"
+  "\x58\x91\x39\x1f\xcc\x27\xa5\xd4\xe9\x1f\x1d\xc3\x3e\xe2\x49\x30"
+  "\x74\x4a\xa9\xb9\xb6\x3f\xd1\xfc\xdd\xcc\x32\xed\xfc\xdd\xcc\x7d"
+  "\x20\xcd\x4a\x04\x69\x76\x32\x48\xf7\xa4\x03\xc2\x69\xaf\x39\x39"
+  "\x02\xd7\xdd\x5f\x66\xbe\x73\x3d\x94\xfa\xd8\x17\x38\x3e\xf5\xee"
+  "\xc4\x31\x70\xe6\x2d\x3a\x97\x63\x23\xcd\x6b\xdd\xfd\x57\xe4\xe9"
+  "\xdf\xb0\x5f\x4a\xc0\xfb\x5f\xa2\xec\x20\x2f\x1f\xae\x38\x25\xdd"
+  "\x7d\xc8\x87\xf7\x09\x9e\xd1\xe9\x7e\x5b\x36\xf8\x4c\x2f\x1f\x1c"
+  "\xa8\x7c\x09\xfc\x38\x8e\x0d\x18\xbe\x28\xb7\xfd\x15\x92\x9c\x3d"
+  "\x7e\xa8\x45\xbd\x5b\xe6\x37\x90\x3d\x64\x3b\x56\x7e\x04\x27\x0b"
+  "\x40\xb2\x9d\x83\x78\xd6\x6b\x89\x53\xf4\x7a\x7e\x4f\x82\xb7\xa4"
+  "\x87\x05\x48\xbf\x69\x7e\x01\xf3\xc6\x94\x9e\xc3\xbe\xd6\xdd\x0d"
+  "\xb5\x38\x96\xf6\x6f\xb0\x8e\x75\xf7\x5a\xaf\x78\x3b\x00\x89\x63"
+  "\x3c\x60\xac\xfd\x0a\x75\x70\x03\xea\xdf\x57\xa8\xe7\x6e\xa1\xe7"
+  "\xb4\xff\xa6\x8e\x74\xfc\xa5\xc6\xbc\xfa\xaf\x84\x8e\x73\xbd\x23"
+  "\x1d\x5f\x8f\x7a\xb7\x2e\xa8\x77\xbe\x5e\xd4\xf1\x8a\xbb\x72\x6a"
+  "\xed\x0c\x4a\xd6\x80\x54\x7f\x6a\x34\xe5\xe9\xa2\x6f\x91\xcc\x1f"
+  "\x65\x79\x21\x38\x0e\x4b\x5d\xdb\x7f\x5d\xba\xd9\xfc\x28\x3b\xdb"
+  "\x29\xdd\xed\xc2\x74\x83\xf9\xf1\x9b\x8d\xc8\xef\xb5\x62\x7e\x26"
+  "\x35\x97\xc6\xee\x2e\xe4\x05\xf1\x05\xc7\xd1\x37\x77\x4a\x33\x7f"
+  "\x49\x7c\x2c\xdc\x0f\x51\x79\xf7\xb0\x2e\xe4\xd9\x61\xc6\xe7\x34"
+  "\x66\x1e\xe2\xf3\xd4\x5b\xcd\xf0\x31\x9f\x4f\x14\x65\xfc\xc8\x37"
+  "\x5f\x5c\xc6\x41\x94\xb7\xc9\xf1\x4c\x3f\xb7\x39\xe2\xe3\x49\x94"
+  "\xce\xb2\x1e\xe4\x95\x1f\x79\xd5\xc7\x7d\x41\x16\xf7\x05\xe5\xbf"
+  "\x30\x15\xbb\x58\x20\x33\x27\x8a\x95\x3e\x47\xef\x33\xfc\xb0\x34"
+  "\x0f\x58\xc9\x69\xe4\x97\xa7\x83\xfc\xc6\x98\x40\xa1\xf0\x0d\xc4"
+  "\xaf\xf8\x1e\x30\xb2\x8a\xff\x28\xfb\x79\x69\x4b\xb4\x1f\xf5\x97"
+  "\xfc\x43\xc2\x56\x5d\x0c\xda\xe5\x98\x4a\xb2\x5f\xb4\xe7\x84\xad"
+  "\xdc\x5f\x65\xd7\xa2\xdd\xfa\x0a\x2d\x37\x0e\x14\x5a\xcc\x78\x5d"
+  "\xaf\xf8\x10\xfa\x8e\xd6\x5e\xe2\x6d\xc5\x5d\xad\xe4\x3f\x9c\x45"
+  "\x2e\xf0\x21\x6f\xc7\x50\x7f\x53\x68\x49\xe2\x3c\xfe\xa1\x05\x26"
+  "\x7b\x41\x87\x34\x19\x91\x5e\xa8\x5f\x0d\x86\x36\x6b\x27\xf8\xd1"
+  "\x36\x14\xbe\xcf\x5f\x63\x06\xc4\x2b\x1d\xb1\x7c\xa2\xf0\x4c\x17"
+  "\x59\xef\xee\xb9\x37\xa8\x77\xf7\xdc\x4b\xbc\x13\x7a\x77\x4f\xea"
+  "\xb7\x51\xef\x3e\xce\xe6\x7a\x17\x35\x70\x1d\xd7\xa7\xc3\x4e\xdf"
+  "\xbf\xe0\xef\x3d\x13\x48\x47\x48\x67\x7e\xf7\x53\xd2\x99\x39\x8b"
+  "\xfe\x5f\xd5\x99\xf3\x7d\x16\x33\x5e\xff\x29\x3a\x83\x78\xb9\xce"
+  "\x10\xaf\x3e\xce\xee\x07\x85\x47\xdc\x56\xcb\x4f\x34\x9a\x6d\x30"
+  "\x07\x6d\x35\x37\x61\xeb\xf5\xd0\xc6\xf9\x94\x9a\x6b\x7e\x9c\x05"
+  "\x3a\xa5\x39\x3b\x6c\xbf\x07\x63\xbf\x9d\x31\xa7\xef\x67\x10\x88"
+  "\xdb\xda\xc8\xe7\xb3\x2b\xe7\x03\xbd\x1b\xa1\xf7\x22\x34\x47\x97"
+  "\x90\x47\xef\x42\x3a\xab\xfc\x3b\x5e\x06\x7a\x3f\xc2\x62\x7c\x59"
+  "\x7e\xb4\xeb\xc0\xf6\xdf\x54\x05\x62\xce\x63\x8c\x30\xe7\x98\x0b"
+  "\xde\x4b\xe4\x73\xf2\x95\x2f\x51\xec\x82\x3e\x73\x0e\x5f\xef\x4d"
+  "\xef\x4e\x30\xdf\xa3\xcc\xf9\x93\x4f\x90\xe7\xe5\xe4\x79\xbb\x54"
+  "\x92\x61\x2c\xcd\xdb\x09\x9f\x32\xe7\x73\x65\xde\x4e\x79\xa6\x7c"
+  "\x97\x34\xa7\x9b\xe6\x7c\x54\xe5\x72\x64\x38\xb9\xdc\xcc\x35\xe4"
+  "\xeb\x83\xe5\xc4\x33\xfa\x95\x9c\x01\x09\x0c\x61\x63\x8c\xb8\x97"
+  "\x69\x3c\xa1\x3f\x29\xdd\xbb\x06\x7f\x25\xfc\x8d\xc6\xdf\x28\xe4"
+  "\x0f\xff\x6e\xdb\xc8\xfa\xab\xd4\x06\x4e\x4f\xe5\x4b\x19\xb2\x6f"
+  "\xfc\x11\xb7\xc9\x5b\x21\xfe\x94\x7c\xdf\x57\x91\xea\x53\xde\x5d"
+  "\x0c\xc2\x07\xe5\x53\x43\x75\xa3\x8c\xf4\xe2\x7d\x8a\x78\x56\xe1"
+  "\xdb\xc3\x9f\x41\x9f\x84\xb2\x71\xd0\x7b\x4f\xd4\x5f\x5d\x1f\xb3"
+  "\xde\x23\xff\xce\xe6\xef\x5f\x50\x46\x14\xaf\xc9\xfe\xb7\x41\xd4"
+  "\x7b\x6f\x01\xf2\x21\x45\x5d\x6f\x38\x7e\xb8\xa4\x7b\x23\x7e\xd3"
+  "\x66\x64\xbc\xb8\x37\xe2\xf7\x0f\xe7\x5a\xfc\x6c\x84\xb8\x22\xee"
+  "\x7f\x64\x49\x0f\xba\x32\xf7\xfb\x1d\x81\x81\xec\x84\x23\xc5\xa7"
+  "\x47\x18\x5f\xdc\x17\xf1\xfc\x27\x7f\xdc\xd6\xa3\xbe\xda\x07\x49"
+  "\xf7\xe3\xda\xf7\xfb\xe0\x9d\x53\xdd\x52\xe6\x2d\xd7\x43\x7c\x17"
+  "\x18\x29\x7e\x9a\xdf\xf3\x3e\xa3\x18\x6a\xe7\x29\x48\xee\x3f\x9b"
+  "\x9d\x30\x80\xb1\xe0\x2b\xa7\x60\x56\xe0\x87\xa6\xd8\xca\xd5\xa0"
+  "\xef\xc7\x78\xb5\xff\x87\xd6\x84\x8f\x8f\x77\x83\x7f\xef\x83\xae"
+  "\x76\xd4\xfe\x3a\x84\x65\x5f\x64\x8f\x99\xb7\x9c\x79\x5b\x97\xbf"
+  "\x06\x99\x16\xbf\xa3\xf4\x04\xc4\xa3\x2f\x32\x3a\x8b\x7e\xc6\xdf"
+  "\x29\x44\x6f\x92\xcc\x4e\xdf\xe7\xb0\x63\x35\xfa\x30\xf4\x59\xb6"
+  "\x27\xd0\x57\xfb\xce\xc1\xdb\x6a\x5f\xfd\xcc\x3f\x05\x7d\xf5\x59"
+  "\xf4\xd5\x15\xe8\xab\x6d\x26\x68\xcf\x73\x00\xfa\x8e\xd1\x0b\xf2"
+  "\x12\xbc\xa5\x79\xe8\xb3\x37\xa1\xcf\x2e\xfa\x1c\xb8\xbf\xee\xe9"
+  "\x06\xf4\xb5\x63\xf6\xae\x83\xc4\x81\xf5\xe8\xb3\xcf\x5a\xaf\xd8"
+  "\x53\x2a\x7c\xf6\x5b\xeb\xd0\x67\xaf\xc7\x98\x78\x1d\xfa\xec\x9e"
+  "\x30\x3e\xfb\x4c\x84\x78\x58\xf6\x3f\xfd\xeb\x2d\xd2\x5b\x12\x83"
+  "\x2d\x4f\x80\xb4\xe7\xcf\xa3\x47\xa8\x27\xf7\x1f\x8b\x24\x03\xe2"
+  "\x37\xf1\x3f\x80\x72\x68\x43\x19\xf0\xb8\xd5\x3b\x3a\x7d\x00\xfb"
+  "\x34\xff\x98\x12\xf3\x4f\x4f\x75\x48\x63\x0a\xc0\xb8\x20\xef\x7d"
+  "\xd6\xbf\x21\x1b\xe3\xfe\xec\x78\x5f\xe5\xd6\xa3\x95\x18\x53\xfb"
+  "\x31\xf6\x1e\xe8\x33\x19\x90\x07\x46\x77\xa1\x35\x81\x78\x18\xb8"
+  "\x0e\xe5\x39\x6a\x7c\x0f\xfa\xd0\x69\x7b\x57\xc3\x8c\x81\x1d\x25"
+  "\x19\x6c\x47\x49\xaa\x7f\x47\x49\x1a\x96\x1d\xf3\xb0\x8b\xe4\xf2"
+  "\xaf\x80\x69\xcb\xd9\xce\x32\xb3\x3f\x7e\xeb\x51\x77\x7c\x49\x3a"
+  "\x3e\x67\x53\x7e\xe9\x0a\x88\xcf\xb4\x9c\x77\x08\x79\xfd\x04\x48"
+  "\x4e\x42\x5e\x9f\xc2\x0e\x1c\xf7\x51\x9f\xcb\xfb\x57\x59\x66\x38"
+  "\x5e\xe0\xf1\x7e\x50\x6e\x21\x7d\xac\x2c\xb7\xb6\x1e\x07\x60\x7f"
+  "\x32\x7a\xb0\xaf\xe5\x72\xfb\x14\x94\x7e\x16\xf9\x3d\x66\x2f\xf6"
+  "\xb5\x03\xdf\x54\x5f\x2b\x8f\x63\xa8\xaf\xa5\x7e\x96\xe4\xf6\xd6"
+  "\x88\xe5\x36\xb7\xf2\x12\xe5\xd6\x70\x69\x72\xbb\x29\x4d\x25\xb7"
+  "\x56\x94\x89\x03\xe5\xd6\x1c\x22\x37\x97\x4a\x6e\x2d\xf8\xdc\x11"
+  "\x94\xdb\xb9\x11\xc8\x2d\xfa\xab\x6f\xaf\xdc\x1e\x4c\xbb\x34\xb9"
+  "\x95\x5e\xa2\xbd\xdd\x54\x1b\x94\x5b\x29\xda\x5b\x29\xda\x5b\x69"
+  "\x88\xbd\x95\xaa\xec\xad\x14\xed\xad\x54\x65\x6f\xa7\x47\x20\xb7"
+  "\xcb\x3a\xbf\xbd\x72\x4b\xf7\x5d\xa2\xdc\x2e\xd5\xde\x3c\x2a\xb9"
+  "\xd1\xb7\xbe\xd1\xde\x4a\x43\xec\xad\x54\x65\x6f\xa5\x68\x6f\xa5"
+  "\x2a\x7b\xfb\x74\x04\x72\xbb\xfc\xdf\xbe\xbd\x72\x7b\xe8\xd0\xa5"
+  "\xc9\xcd\x76\x89\xf6\x76\x73\x46\x50\x6e\x36\xb4\x37\x1b\xda\x9b"
+  "\x2d\xc4\xde\x6c\x2a\x7b\xb3\xa1\xbd\xd9\x54\xf6\xf6\xde\x08\xe4"
+  "\x76\x47\xc5\xb7\x57\x6e\x19\xb9\x97\x28\xb7\x4b\xb4\xb7\x9b\xf7"
+  "\xa9\xe4\x86\xf6\x66\x43\x7b\xb3\x85\xd8\x9b\x4d\x65\x6f\x36\xb4"
+  "\x37\x9b\xca\xde\x4a\x46\x20\xb7\xc5\xf7\x7d\x7b\xe5\xb6\x20\xe2"
+  "\xfc\xa7\x22\x37\x45\x66\x24\x3f\x2e\x37\x96\x0d\x3e\x8c\x27\xff"
+  "\x79\xa5\x90\x1b\xc9\x8b\xcb\xae\x37\x3b\x61\x87\x2c\x33\x9f\x2c"
+  "\x33\xe2\x1f\xc9\x8d\xe2\x48\x2e\x37\x9d\x3e\x91\x62\x48\x1f\xc6"
+  "\x92\x4a\x1c\xf9\x90\x95\x79\xdb\xac\xff\x34\x18\x47\xfa\x42\xe3"
+  "\xc8\x35\xea\x38\xf2\x67\x1a\x79\x55\x7e\x8d\xf2\x92\x64\x79\x3d"
+  "\x15\x21\x8e\x5c\xfd\xdb\x08\xf2\x3a\x7a\x51\x79\xa1\x6c\x12\x07"
+  "\x7a\x85\xbc\xde\x92\xe3\xff\xda\xfc\xbf\x53\x5e\x1b\x50\x5e\x14"
+  "\xff\x7f\x0a\xd2\xdb\x4b\x47\x2a\xaf\xcc\x8b\xc6\xff\xe1\xe5\x55"
+  "\xda\x30\x32\x79\xdd\xe4\x09\xca\xab\xd4\xe1\xc3\x3e\x4d\xe9\xcf"
+  "\x82\xf2\x12\xfd\x99\x2f\xb4\x3f\x5b\xa3\xee\xcf\x86\x23\xaf\x90"
+  "\xfe\xec\x5b\x25\xaf\x47\x22\xce\xff\xfb\x71\x2c\xee\x47\x3f\x47"
+  "\xf3\x95\x63\xba\x71\x9c\xec\x63\x5f\x2c\xf0\xe0\x38\xd9\x37\x3a"
+  "\x7d\xd7\x3a\x48\x1e\x28\xc4\x71\x32\xca\xae\x72\x1d\xcc\xaa\x58"
+  "\x07\xfa\xc0\xb3\x38\x56\x3e\x85\x63\x65\xf4\x4f\xfd\x7f\xb3\x26"
+  "\xb4\x2e\x77\x43\x00\xc7\xca\x34\x0f\x86\xf4\x26\xb3\xbf\xe1\x58"
+  "\xb9\x0b\x7d\x5f\xd7\x5b\x62\xac\xfc\xb9\x32\x56\xfe\xa5\x66\xac"
+  "\xfc\xca\x33\xf2\x58\x59\xe6\x7f\xad\x9a\xf7\x4f\xfe\x34\xc2\x58"
+  "\xb9\xe5\xa2\x63\x65\x1a\x23\xbf\x4d\xe3\xe5\xb3\xd6\xb1\x7b\x64"
+  "\xdf\xf6\xd6\x99\xbf\x73\xac\x7c\x16\xc7\xca\x76\xc1\xfb\xb7\x46"
+  "\xcc\xfb\x85\x11\xd7\x7f\x90\x6d\x90\xbd\x0c\xf6\x45\xc8\x67\xa5"
+  "\x0f\x1a\xc0\x3e\x88\xe6\x33\xfa\x2b\x4b\x92\x51\x5f\xb9\x7d\xf0"
+  "\x3e\xa9\xd0\x64\x20\xdb\x20\x3b\x21\xdb\xe0\x7d\x11\xfa\x41\xec"
+  "\x8b\x7c\x75\xcf\xc0\x8c\xfa\x67\x60\x9a\x2f\x5e\x3b\x46\x7e\x28"
+  "\x87\xe4\x11\xf4\x6d\x81\x50\xdf\xb6\x4a\xed\xdb\x7e\x39\xb4\x2f"
+  "\xba\x98\x6f\x7b\x26\x92\xad\xb4\x5c\xd4\x56\xc8\x46\x78\x7f\x84"
+  "\xf6\xf2\x9f\x61\x2b\x6f\xfd\x65\xa4\xf2\x5a\x14\x71\xfd\xc7\x30"
+  "\xe5\xb5\x6f\x18\xf2\x6a\x60\xa3\x2c\x59\x2a\x79\x69\xc6\xc6\x2a"
+  "\x79\xb9\x54\xf2\x0a\x8e\x8d\x57\xa9\xc7\xc6\xc3\x91\x57\xe8\xd8"
+  "\xf8\xdb\x24\xaf\xc7\x23\xae\xf3\x1b\x9e\xbc\x4a\x87\x61\x5f\xa5"
+  "\x68\x5f\x96\x7d\x41\x79\x69\xc7\xc4\x41\x79\x95\xaa\xec\x4b\x35"
+  "\x26\x5e\xa5\x1e\x13\x0f\x47\x5e\xa1\x63\xe2\x6f\x93\xbc\xb2\x23"
+  "\xae\xff\x18\xa6\xbc\x86\x61\x5f\xa5\x64\x5f\x5e\x95\xbc\x34\x63"
+  "\x61\x95\xbc\x54\xf6\xa5\x8a\x1d\x56\xa9\x63\x87\xe1\xc8\x2b\x74"
+  "\x2c\xfc\x6d\x92\xd7\x13\x8e\xbf\x4f\x5e\xb6\x61\xd8\x97\x0d\xed"
+  "\xeb\x96\x8c\xa0\xbc\xb4\x63\xe0\xa0\xbc\x6c\x2a\xfb\x52\x8d\x81"
+  "\x57\xa9\xc7\xc0\xc3\x91\x57\xe8\x18\xf8\xdb\x24\xaf\xc5\x79\x7f"
+  "\xa7\xbc\x86\x61\x5f\x36\xb4\xaf\x5b\x1a\x54\xf2\xd2\x8c\x7d\x55"
+  "\xf2\x52\xd9\x97\x6a\xec\xbb\x4a\x3d\xf6\x1d\x8e\xbc\x42\xc7\xbe"
+  "\xdf\x26\x79\x3d\x65\xbe\xd0\x58\x4a\x3d\x86\xf2\xd9\x82\xf2\x22"
+  "\xd9\x0c\xe0\xd8\x69\x20\xae\x24\x39\xf2\xf8\xe9\x66\x5f\xa4\xf1"
+  "\x2e\x9d\x07\xf3\x50\x37\xed\x09\x11\x31\x21\x0b\x89\x09\xdb\xac"
+  "\x3f\x05\xed\x98\xf7\xbd\x21\x63\xa8\x01\x65\x8e\x62\x45\xa4\x31"
+  "\xef\xbf\x5e\xf2\x18\x8a\xe4\x44\xe3\x28\xdf\x06\x94\x93\x1c\xc7"
+  "\xbf\xfd\x77\xce\x51\x0c\xf4\x5a\xa4\xb7\x31\x8e\x2f\x5e\x81\x63"
+  "\xa8\x95\x23\x95\xd3\xd2\x88\xfb\xbf\x69\x9e\x88\xc6\xbc\x34\x96"
+  "\xa2\xf7\x8e\xed\x5d\xdd\x50\xb1\x11\x8c\xfc\xdd\x63\xb7\xf6\xdd"
+  "\xe3\xae\x93\x38\xa6\x5a\x8f\x72\x1b\xc8\x86\x9d\x27\x61\x56\xe5"
+  "\x33\x62\x4c\xa5\x8c\xa7\xda\x3d\x5e\xfe\xee\xd1\xe9\x73\xc1\x3c"
+  "\x17\xf3\xd6\x23\x3c\x8d\xa3\x5a\x97\xbf\x05\x64\x2b\xb6\x13\x10"
+  "\x4f\x32\xc0\x31\x18\x97\x87\x7a\x0c\x55\xa7\x7e\xdf\xb8\x3a\xd2"
+  "\x18\xea\xe2\xef\x1b\x6b\xcf\x88\xf1\x13\x7f\xdf\xf8\xff\xc4\x18"
+  "\x6a\x79\xc4\xf7\x1f\xf3\xdf\x11\xf3\x0d\xc4\x7b\xa7\xc5\x07\xa8"
+  "\x4f\x5f\x24\xf4\x88\x79\x3d\xdf\xce\x12\x33\x8d\x69\x69\x3c\xeb"
+  "\x2c\x6a\x81\x8a\xcd\x60\xec\xef\xcb\x4e\xc0\x31\x6a\xbc\x0f\x7d"
+  "\xdd\x2b\xa7\x04\xef\x4b\x4e\x83\xd1\xfd\xac\x95\xaf\x95\xa1\xb1"
+  "\x2c\xd9\x0a\x7f\xe7\xb8\x12\xa6\xd5\x76\xc2\x0c\x6e\x1f\x68\x17"
+  "\xbe\x1d\x5b\x8f\x06\xe2\x4b\xd2\xc8\x4e\xe6\x1d\x67\x5e\x92\x01"
+  "\xd9\xc7\xc7\xc7\x49\x36\x3f\x03\xdb\xa7\x42\x36\x5c\x2e\x92\xf6"
+  "\x5d\xf0\x50\xdb\xf8\xb7\x08\xf2\x69\x1c\x9e\x7c\xd6\x6b\xe5\xb3"
+  "\xf7\x52\xdf\x07\x2b\xeb\x23\xd7\x5b\xa4\xbd\xf2\xfb\xe0\xb7\x9e"
+  "\x1c\xa9\x7c\x56\x74\x5d\xa2\x7c\x1a\x2e\x51\x3e\x0e\xfe\x6e\x51"
+  "\x2b\x9f\x0e\x59\x3e\xcd\x34\x56\x0a\xca\xe7\xdc\x30\xe5\x13\x32"
+  "\x46\xfa\x56\xc9\xe7\xe9\x88\xf3\x3f\x17\x96\x4f\xe9\x25\xda\x4f"
+  "\x69\x2a\x7f\x87\xa8\x91\x4f\xa9\x6c\x3f\xa5\x69\x34\x36\x0a\xca"
+  "\xe7\xf4\x30\xe5\x13\x32\x26\xfa\x56\xc9\x67\x55\xc4\xf9\xef\x8b"
+  "\xc8\xe7\x12\xed\xa7\xd4\xc1\xdf\x15\x6a\xe5\x23\xdb\x4f\x69\x33"
+  "\x8d\x85\x82\xf2\xf9\x74\x98\xf2\x09\x9d\x3f\xfd\x36\xc9\x67\x75"
+  "\xf3\xa5\xc9\xc7\x76\x89\xf6\x63\x4b\xe5\xef\x04\x35\xf2\xb1\xc9"
+  "\xf6\x63\x4b\xa3\xb1\x4f\x50\x3e\xef\x0d\x53\x3e\x21\x63\x9e\x6f"
+  "\x95\x7c\xac\x11\xcf\x7f\xba\x88\x7c\x2e\xd1\x7e\x6c\x0e\xfe\xee"
+  "\x4f\x2b\x1f\xd9\x7e\x6c\xcd\x34\xd6\x09\xca\xa7\x64\x98\xf2\x09"
+  "\x19\xe3\x7c\xab\xe4\xf3\x8c\xfe\x62\xef\x8b\x94\xd8\x59\xfd\x5e"
+  "\x76\x00\xe3\x37\x8a\x9f\x29\x76\x6e\xf7\x34\x82\x6f\xbd\x90\x4d"
+  "\xc5\xd7\x60\xac\x94\x65\xc3\xdf\xc9\x3e\x2b\xde\xc9\xf2\xb8\xed"
+  "\xa5\xf1\x3d\x6c\xab\x3e\x91\xe2\x32\xfe\xde\x95\xbf\x9b\x38\x42"
+  "\x79\xd9\x03\xaa\xf8\x8d\xc6\xa8\x18\x7b\x03\x8d\x53\x6d\x9f\x8f"
+  "\x20\x6e\x5b\x19\x49\x2e\x17\x7f\x37\x51\xab\x5a\xc7\xa7\x8c\x3d"
+  "\xbf\x51\xb9\x8c\xf8\xbd\xeb\xb3\x11\xcf\x7f\xbc\xb0\x5c\x4a\x1b"
+  "\x46\x26\x17\xec\x6f\x5e\xba\xc9\x23\xe4\xf2\x69\x88\x5c\x4a\x3b"
+  "\x06\x54\xfd\xce\xf0\xe5\x12\xd2\xdf\x7c\xab\xe4\xb2\x76\x5a\xc4"
+  "\xb1\x26\xfa\x25\x92\x09\xad\xef\xde\xb5\x12\x92\x2b\x3a\x61\xd6"
+  "\xc0\xdf\x4c\xb1\x0b\xd0\xcf\x0d\x3c\x6b\x32\xb4\xa3\x8f\x2b\xf5"
+  "\xb0\x2f\xc6\x78\x46\xa7\x7f\x74\xcc\x0d\xed\xcb\x5d\xd0\x5f\x98"
+  "\x0d\x3b\x4e\xd1\x5a\xf5\x46\xd8\x9e\x4f\x63\xf9\x7f\x81\x8f\x8f"
+  "\x7f\x05\x0b\xf6\xb3\x01\x67\x4f\x23\x38\x36\xff\x0b\xb0\x67\x2d"
+  "\xb1\xf5\x08\xb3\x0c\x79\x78\x46\x5a\xdb\x73\x1e\xc7\xa3\x93\x8b"
+  "\xc0\x98\xd1\xc3\xbc\xed\x3d\x1f\xc1\xdb\x58\xd7\x91\x22\x00\xe2"
+  "\x2f\xc9\x64\xc7\x33\x34\xfe\x7c\x4f\xc8\xe4\x11\x21\x93\xb7\x54"
+  "\xe3\x4f\x33\xe6\x9f\xcc\x43\x79\x7c\x19\x22\x8f\xe3\xdd\x80\xfc"
+  "\x1d\xbd\xc0\x83\xf2\xf0\x28\xf2\x38\x0d\xa5\xcf\x91\x3c\x5c\x83"
+  "\xeb\x5d\xfb\x65\x79\xd4\x92\xff\xca\x03\xe3\x1e\x65\xfc\x79\x46"
+  "\x25\x0f\x65\x4f\x96\x5a\x1e\xca\xd8\xbf\x10\xe5\xb1\x31\x38\xfe"
+  "\x3c\x8f\xe3\xcf\x3d\x38\xfe\xb4\xfd\x1e\xa4\x3d\xa5\x23\x95\xc7"
+  "\xba\x88\xfd\xbf\x22\x0b\xea\x5b\x06\xc6\x94\x98\x49\x0e\xce\xa2"
+  "\x83\x40\x32\xa1\xfe\xc4\xff\x37\x93\xa1\xb8\x00\x6d\xc7\x35\x3a"
+  "\xbd\x9f\xe1\x98\x1f\xc7\xfb\xce\x25\x7f\x06\x9a\x33\x10\x32\x18"
+  "\x18\x70\xba\x1b\x81\x78\xef\xd8\xfc\x67\x2e\x87\x33\xd2\xfa\xdc"
+  "\xa5\x1e\x90\x26\xa1\x1e\xe2\x78\xdf\xb8\x8c\xf6\xe5\xa2\x6f\x7b"
+  "\x7b\x35\xcc\xc8\xc8\x63\x5e\x1a\x9b\x92\x0d\xd1\xda\x13\xf2\x6b"
+  "\xed\x79\xbf\x05\x9a\xd7\x19\x88\xdf\x7a\xf4\x48\x01\x00\xf9\x37"
+  "\xe2\x7b\xf4\xf3\x41\x39\xd1\x7a\x12\x2e\xab\xc7\x86\xb1\xce\x55"
+  "\x2d\xaf\x25\xae\x61\xad\x4f\xee\x97\xe7\x0b\x6a\x95\x39\xb5\x4b"
+  "\x9d\x2f\x50\xe6\xd4\xce\x8a\xf5\x24\xb6\x4f\xd0\x7e\x46\x2c\xaf"
+  "\xbc\x82\x61\xca\xab\x61\xe4\xf2\xea\x0b\x23\xaf\xe7\x92\xc2\xc8"
+  "\xcb\x11\x94\xd7\x4d\x69\x2a\x79\x75\xc8\xf2\x6a\x56\xc9\xab\xe5"
+  "\xe2\xf2\xba\xc0\xfa\xd6\x7f\x78\x79\xe5\x47\x1c\xff\x68\xe5\x55"
+  "\x7a\x09\xf6\x75\x36\x8c\xbc\xf2\x5b\x87\xca\xab\x54\x65\x5f\x37"
+  "\xd5\x06\xe5\x55\x2a\xdb\x57\xa9\xca\xbe\x4a\x87\x61\x5f\x17\x58"
+  "\xd7\xfa\x0f\x2f\xaf\x0d\x11\xd7\xff\x84\xc8\xeb\x12\xec\xeb\xb3"
+  "\x30\xf2\x2a\x28\x0e\x23\x2f\xb5\x7d\x79\x54\xf2\x92\xed\xab\x54"
+  "\x65\x5f\xa5\xc3\xb0\xaf\x0b\xac\x67\xfd\x87\x97\xd7\xf3\x17\x5c"
+  "\xff\x13\x94\x97\xed\x12\xec\xeb\xfd\x30\xf2\xda\x38\x61\xa8\xbc"
+  "\x6c\x2a\xfb\xba\x39\x23\x28\x2f\x9b\x6c\x5f\x36\x95\x7d\xd9\x86"
+  "\x61\x5f\x17\x58\xc7\xfa\x0f\x2f\xaf\xc2\x88\xf1\x5f\x88\xbc\x2e"
+  "\xc1\xbe\x6c\x61\xe4\x55\x78\x3c\x8c\xbc\x54\xf6\x75\xf3\x3e\x95"
+  "\xbc\x64\xfb\xb2\xa9\xec\xcb\x36\x0c\xfb\xba\xc0\xfa\xd5\x7f\x78"
+  "\x79\x15\x45\x9c\xff\x56\xcb\xab\x7f\xa7\x12\x1f\xee\xd7\xca\x0b"
+  "\xe3\xf5\x84\x2e\x31\xb6\x52\xe4\x15\x39\x36\xdc\x54\x3e\x28\xab"
+  "\xcf\x83\xb1\x21\x97\x93\xfc\x9e\x82\xe4\x43\x31\x22\xc5\x84\xfd"
+  "\x3b\x84\x8c\xe8\x1d\xe0\x05\xe3\xc2\xe1\xec\x7f\xba\x04\x39\x29"
+  "\xe3\xaa\x6f\x5c\x4e\x7f\xba\x14\x39\x6d\x8e\xb8\xff\x49\x2b\x27"
+  "\xa5\xdf\x1a\xae\x9c\xc2\xf5\x59\x5b\x52\x86\xca\xa9\xd4\x11\x94"
+  "\x93\xe8\xa7\xa8\xef\xa2\xbe\x4a\x2b\xa7\x0b\xf4\x57\xc3\xd9\x7f"
+  "\xf1\x0f\x2f\xa7\xe2\xc8\xfe\x4f\xe2\xdf\x36\x3f\x58\x25\x05\x1a"
+  "\xf1\x72\xe0\xd5\x82\x69\xd1\x98\xc6\xcf\x25\xaf\x92\xf3\xfc\x15"
+  "\x40\xfb\xb4\x1d\x09\xba\xe5\x74\x9e\x2e\xc1\x8c\x52\x60\x12\xb6"
+  "\x42\x2a\xb6\x47\xc0\x49\x50\x86\xe9\x8e\xf8\xad\xa9\xa3\x10\xbe"
+  "\x85\x55\xdc\x7b\x00\xd3\x46\x13\x2c\xdb\xaa\xe7\xdf\x28\x4b\xd0"
+  "\xf1\xb3\x6f\x64\x78\x1d\x10\x3c\xc1\x22\x9c\x41\x86\x4b\xe2\x7b"
+  "\x82\x25\x09\xea\x87\xd2\x16\x23\xc3\x98\x03\x76\x30\xab\x69\x8c"
+  "\xd7\xa5\x72\x5c\x32\x5c\xac\xdf\xfe\xe7\x6c\x82\xf5\x6f\xd5\x27"
+  "\xab\xe1\xd8\x7d\x40\x78\x15\xb8\xcb\x64\x7c\x16\x4d\x7b\x6f\x04"
+  "\x88\xdf\x6a\xe6\xf8\xe2\x7b\x24\x90\xe9\x8b\x63\xb1\xa9\x65\x1c"
+  "\x5e\xa7\x9f\xa0\x81\x1f\x05\xea\x76\xc4\xb3\x51\xb7\x76\xc9\x70"
+  "\x29\x01\x09\x52\x08\x16\xd3\xf5\x6a\x5e\xcb\xb0\x63\x14\x3e\xa2"
+  "\xac\xf5\xea\xf6\xfa\xb1\xfd\x7b\x05\x8d\x09\xfe\x97\x6e\xf1\xc8"
+  "\x6d\x99\xa1\xae\x97\xe0\xb0\xdc\x14\x59\x26\x46\x6c\xc7\xac\x41"
+  "\x7c\x95\x19\x5e\x05\xce\xe6\x87\x6b\x50\x46\x0e\xa7\x15\x40\x6e"
+  "\xf7\xe5\xac\xe2\xbe\x54\xb9\xed\xa9\x5a\x3e\xea\x5c\x0a\x1f\x51"
+  "\x7e\x1e\x84\x1d\x8b\x30\x69\x0a\x5e\xbf\x9d\xef\xd9\x17\xed\xb6"
+  "\xfb\xae\x20\xbd\x68\xeb\x06\xd2\x65\xc2\x7b\x85\x8c\x33\x5d\xb4"
+  "\xd9\x08\x7b\x07\x65\xad\xa7\x3c\x87\x0c\x97\xc8\xdb\x13\xbb\x20"
+  "\xd7\xaf\xd3\x67\x0c\x85\x35\xa8\x61\xaf\x14\xb0\x69\x49\x08\x9b"
+  "\x35\x14\xd6\xa8\x86\xbd\x4a\xc0\xce\x3d\x86\xb0\x8b\x86\xc2\xfa"
+  "\xc6\xaa\x60\xaf\x16\xb0\x0f\x56\x22\x6c\xf6\x50\x58\xb3\x1a\xd6"
+  "\x24\x60\xb3\x88\x86\x25\x43\x61\x53\xd5\xb0\xd7\x08\xd8\x79\x69"
+  "\x08\xbb\x7c\x28\x6c\x99\x1a\xf6\x5a\x01\xfb\x90\x0f\x61\x73\x42"
+  "\x61\xeb\xb9\x1e\xc0\x8d\xb2\x1e\x7c\x4f\xc0\x66\x1c\x42\x58\x6b"
+  "\x98\xb6\x45\x71\xbc\x02\x36\x49\xc0\xde\x57\x83\xb0\xb9\x61\x64"
+  "\xa1\x86\xbd\x4e\xc0\x3e\x65\x45\xd8\xbc\x30\xb2\x50\xc3\x5e\x2f"
+  "\x60\x17\xa6\x23\x6c\x41\x18\x59\xa8\x61\x6f\x10\xb0\x8b\xbc\x08"
+  "\x5b\x14\x86\xbf\x41\xd8\xd8\xc7\xf7\x23\x4c\x31\xf2\xe4\x68\x18"
+  "\xde\xaa\x71\x8e\x13\x38\xb3\xb3\x11\xbe\x2c\x0c\x6f\xd5\xb0\x37"
+  "\x0a\xd8\x27\x0d\x08\xbb\x6d\x28\x2c\xe8\xf6\x0a\xfe\x4e\x95\xf9"
+  "\xfb\x7d\x01\xbf\xb8\x11\xe1\xcb\xc3\xf0\x97\xf2\x1d\xb2\xad\x25"
+  "\x0b\xd8\x47\x5a\x11\xb6\x32\x0c\x7f\xd5\xb0\xe3\x05\xec\x33\x19"
+  "\x08\x5b\x15\x86\xbf\x6a\xd8\x9b\x04\xec\x72\xd2\xc9\xea\x30\xfc"
+  "\x55\xc3\xde\x2c\x60\x57\x4e\x40\xd8\x9a\x30\xf4\xde\xa8\x82\xb5"
+  "\x08\xd8\xa7\x89\xde\xda\x30\xb2\x50\xc3\xde\x22\x60\x9f\xed\x42"
+  "\xd8\x86\x30\xf2\x50\xc3\xde\x2a\x60\x57\x91\x1d\xef\x0b\x23\x0f"
+  "\x35\xec\x6d\x2c\xf6\x87\x71\xb2\x5f\xdc\x1f\x0a\x8b\xb2\x17\x3e"
+  "\xd1\x0e\x13\x58\xac\xf5\x00\xde\x13\x1c\x3f\x43\x61\x10\x9f\xdd"
+  "\x77\x3b\xf9\x1b\xd9\x87\x4d\x64\xb1\xcb\x8c\x32\xbe\x83\x43\xea"
+  "\xb6\xeb\xd5\xb0\x93\x58\xec\xa6\x09\x32\xec\xa1\xa1\xb0\x06\x35"
+  "\xec\x64\x16\xbb\x5e\xa1\xb3\x71\x28\xac\x71\x10\x96\xc5\xe6\x1d"
+  "\x46\x98\xc3\x75\xb2\x6f\x54\xd1\x39\x55\x85\x6f\x0a\x8b\xcd\xcf"
+  "\x95\xf1\x39\x86\xe2\x33\xab\x61\xa7\xb2\xd8\xcd\xc7\x64\xd8\xe6"
+  "\xa1\xb0\xa9\x6a\xd8\xdb\x59\x6c\x41\x92\x0c\xdb\x32\x14\xb6\x4c"
+  "\x0d\x3b\x8d\xc5\x3e\xdf\x2a\xc3\xb6\x0e\xe1\x3d\xd9\x81\x1d\x63"
+  "\x01\xe1\x93\xa6\xb3\xd8\xc2\x62\x19\x56\x13\x07\xa8\xfa\xe1\x3b"
+  "\x84\xdc\xd7\x16\xa3\xdc\xf9\xfc\x05\xfa\xfc\x8e\x70\x31\x46\xde"
+  "\xad\x70\xd9\x29\xe9\x45\x8b\xe8\x93\x94\xb3\xe9\x5f\xe4\xe7\x5a"
+  "\x05\x6a\xd3\x21\xd3\xc3\x7c\xea\xb4\x5d\x12\x3b\x3a\xd9\x03\x7a"
+  "\x7e\xde\x71\xfc\x4b\x16\x17\xa6\xbb\xaf\x4b\x37\xf7\x55\xbc\x38"
+  "\xcd\xa5\x1b\x9f\x4c\xe7\x77\xe0\x7d\xaa\x0b\xd6\x64\xd0\xfd\x2e"
+  "\x3b\xe3\x67\xde\xfa\x77\x66\x38\x9c\x81\x1e\x3a\xfb\xca\x8b\x38"
+  "\xbc\x27\xf3\x20\xca\x9c\x0f\xf4\xae\xa5\xdf\x59\xd4\x03\x88\xff"
+  "\x45\xb6\xde\x3a\x8b\x55\xbe\xe4\xc2\xfa\x72\x3a\xf1\x99\xd3\x80"
+  "\x31\x10\xf6\x95\xc7\x1d\xf9\x74\x9e\xd0\x8b\xbf\x74\xc7\xbf\xe4"
+  "\x62\x2f\x2c\xee\xce\x2b\x85\x1b\x90\x6e\xae\x2b\xfc\x6c\x91\xb3"
+  "\xd6\x7b\x02\xf1\x19\xc7\xe9\xcc\x11\x56\xf3\xb2\x43\x9c\x47\xf2"
+  "\xe2\x97\x9c\x66\x3b\x3b\xca\x92\x1e\x74\x07\xfa\xb7\x95\xd1\xb7"
+  "\x0f\x1c\xa5\xa7\xa0\x53\x95\xe7\xbe\xe6\x65\x7e\x56\x09\xdb\xfb"
+  "\xa0\x3b\xec\x19\x1e\x76\x48\x60\x3b\x32\xbc\x7d\x15\x2f\x99\x30"
+  "\x5e\x2b\x10\x6d\x7c\x29\xd9\x05\x01\xbd\x7c\x9f\xe2\xd2\xc1\x41"
+  "\xf9\x7e\x96\x4b\xf7\xbd\x6d\xf2\x7d\xba\x72\x96\x4a\xf8\xb3\x5d"
+  "\x32\x5a\xb1\x6d\x5d\x81\xb7\xb3\x0d\x14\x5f\xd2\x39\x6b\x2c\x3e"
+  "\xa3\xd5\x7c\x3d\x7d\xd3\x02\xdb\xb9\x23\xa3\x4b\x9c\x8f\xf9\xd2"
+  "\x4f\xf0\x37\x41\xfe\x75\xcb\xbf\x8c\x60\xb8\xdc\x92\xd2\xf3\x58"
+  "\x65\x59\x23\xb5\xad\xd4\xcf\x02\x2c\x6e\xbe\x81\x95\xff\xef\x2c"
+  "\x67\x51\x37\x88\x73\xa5\x5f\xfa\x3d\xc1\x71\xde\x21\x7f\x59\xcc"
+  "\xff\xce\xe2\x75\xed\x78\xc9\xa5\xa6\x8b\x36\xef\xa4\x4c\x99\x7a"
+  "\xfb\xb4\xe9\x77\xdc\x39\xe3\xae\x15\x2b\x9f\xce\x59\xb5\xfa\x87"
+  "\xd6\x35\xcf\x3c\x9b\xbb\x76\xdd\xfa\xbc\xe7\xf2\x37\x14\x3c\xbf"
+  "\xb1\xb0\x68\xd3\x66\x82\x1b\x6c\xc3\xdb\x69\x3a\x8f\x04\x58\xcf"
+  "\x7d\x58\xcf\xcb\x73\x39\x3d\x98\x26\xf8\xff\xf2\x34\xbd\x39\x7c"
+  "\x6c\xeb\xc4\x68\x93\xce\x59\xee\x91\x5e\x7e\x95\xce\x7c\x46\x39"
+  "\xeb\x9c\xb5\x0f\x3a\xe8\x1c\xfe\x2e\xe9\xe5\x6d\xed\xee\x07\x1d"
+  "\xf4\x1d\x88\x26\x53\x37\x24\xdf\x48\x67\xf5\xbf\x9c\x47\xf9\xf5"
+  "\x37\x01\x34\x63\xd9\x70\x38\x6f\x34\x82\xe9\xf5\xab\x98\xbb\xfa"
+  "\x2a\xd6\x43\xf8\xab\x77\xb3\x6e\xf7\x16\x2b\xec\xc4\x67\xd4\x35"
+  "\xe3\x49\xa9\x7c\x6e\x53\x12\x3f\xcf\x3c\xa9\x6e\x37\xeb\xda\x76"
+  "\x15\xeb\x7a\x61\x37\xeb\xa9\xbf\x8a\xb9\x92\xab\x21\xae\xaf\xe2"
+  "\x65\xaf\x4b\x7a\x39\x8b\xeb\x2d\xe6\x07\x62\x5f\x72\xef\xc2\xbc"
+  "\xc9\x3e\x88\xaa\xc7\x67\x4c\xf3\x34\x99\x05\xdd\xef\x7e\xe5\x8d"
+  "\xc6\xf6\x1d\x67\x03\xb9\xba\x9d\x58\x8f\x90\x53\xf9\x9a\x66\xec"
+  "\x49\xb1\x3e\xb7\xd3\xdb\x09\x2e\xa9\xdc\x5a\xff\x35\xaf\x2f\xc1"
+  "\x59\xd3\x03\x84\xef\xe7\xf9\xde\xe8\x0d\xd7\x32\x1f\xc2\xa6\x07"
+  "\xb6\xe4\xea\x10\x26\x19\x71\x7b\xd4\xed\xb1\xac\x5e\x5b\x60\x5e"
+  "\xf7\x7c\x6e\xee\x2d\xb1\x60\xe1\xbf\x9a\x6f\x48\x14\x20\x3e\x78"
+  "\x7d\x37\x6b\xc6\x76\x3a\xb0\xbd\x2d\x6d\x18\x41\xa3\xce\x00\xb6"
+  "\xa9\x0a\xf1\xbe\x87\xe9\x87\xf1\xfe\x30\xd2\xde\x22\xbe\x3b\xb0"
+  "\xe7\xaf\xac\xa2\xbc\x00\xe9\x6c\xa1\x73\x6a\xe9\xfc\xa9\xde\xc2"
+  "\x45\x3a\x6c\x77\x35\xc2\xb5\x98\xaf\x85\xf1\x27\xa5\xed\x73\x91"
+  "\x8e\x7d\x78\x4f\xf0\xdc\x36\x10\xbe\x59\xb4\x6b\x0f\x3f\xcb\x1e"
+  "\x79\xe5\xd8\x7b\x15\xab\xec\xab\xd8\x6e\xa6\xf3\xe9\xf8\xb9\xdd"
+  "\xf8\x8c\x7c\x69\x41\xd8\xaa\x5e\xdb\x22\x1d\x8e\xa7\x74\xf5\x83"
+  "\x38\xcb\xdd\x44\x13\xd1\x41\x63\xba\x8f\x31\x82\x0a\x0c\x64\xc3"
+  "\x44\x2f\xe8\x3e\xee\x02\xa8\xdd\xcd\x1a\xf0\xaa\xc5\xab\xe6\x23"
+  "\xcc\xfb\x1d\x5e\x2d\x98\xde\x8a\xbf\x1f\xe1\xef\xef\xba\xf8\x3b"
+  "\x38\x13\xd1\xbd\xa1\x98\x75\x4f\xae\x81\xef\x13\x7e\xd4\xad\x1f"
+  "\x74\x4a\x7b\x52\x89\x76\x3a\x0b\x92\xc5\x6e\x3f\xa4\x3d\x33\xef"
+  "\x15\x0b\x60\x3e\xfe\xce\x12\xbf\xea\xeb\x95\x6d\x78\xed\x93\xef"
+  "\x7b\xf0\x4a\x14\xf7\x18\x26\x48\x95\x71\x17\xbf\x42\xf1\x45\xba"
+  "\x2a\x8b\x86\x0f\x3b\xac\xeb\xd0\xf0\xe0\x76\xa6\x80\x54\x55\x8e"
+  "\x97\x43\x9b\x5e\x55\x23\xd2\xde\xc8\x11\xcf\x6f\xe4\xc9\xbf\xb5"
+  "\x20\xed\x46\x3e\xed\x46\xfc\xbb\x3b\x44\xda\xee\x2e\xfc\x9d\x80"
+  "\xd7\x8c\x90\xfa\x09\x67\x2b\xc9\x73\x80\xbe\x81\x80\xb2\x74\x49"
+  "\xdb\xb7\x91\x8c\x76\x09\xdd\xd2\x05\x18\x4f\x2b\x43\xdd\xaa\x0d"
+  "\xea\xcf\x2b\xcf\x6b\xf5\xe7\x95\xe5\x21\xfa\x53\x45\xfe\x08\x6d"
+  "\xa1\xb5\x5e\xe8\xcb\xe1\xde\x2d\x39\xf8\xfc\x4a\x0e\xe2\x39\x6c"
+  "\x5e\xca\x71\xf0\x33\x98\x77\x9d\xc2\xb1\x9f\x15\xf4\xe4\x5f\x7a"
+  "\xa4\x57\x7e\x49\x3a\x4b\x75\xcb\xf5\x0a\x5a\x90\x3e\x4c\x6b\x20"
+  "\xfa\xd6\x23\x5e\x7c\xde\x87\x70\x0d\x4e\xf8\x4a\xa1\x8d\x97\xa9"
+  "\x78\x06\xf5\x51\xa6\x97\x70\x52\x39\x16\x6c\x57\x19\x95\x11\x75"
+  "\x57\xae\xc1\x74\x1a\x2b\x82\xed\x4b\x88\xa2\xf5\xca\xa4\x93\xf4"
+  "\xeb\xf4\xa5\xa0\x2d\xa5\x43\xa0\x2f\x1b\x70\xb8\x9f\x82\xf6\x16"
+  "\xd3\x29\x55\x66\x4c\x2a\x86\x14\xc2\x47\x7e\xdd\x25\x55\x1a\xeb"
+  "\xc9\x16\x05\xae\x15\xc0\xcf\xbd\xda\x5e\xf6\x51\x1e\xf0\x7a\xea"
+  "\x88\x1e\xcc\x57\xd5\x5b\x4d\x63\xc1\x5d\x9b\x45\x5b\xb1\xae\x7d"
+  "\x58\xfe\x20\xb5\x9d\xf8\x89\xf9\x8d\x88\x67\x3f\xe5\xf1\xf3\xb4"
+  "\x45\x7b\xf6\xd1\x99\xab\xc4\x0f\x82\xa7\xef\x9a\x88\x33\xf8\xca"
+  "\xdb\x38\xdf\xb0\x3c\xc9\x83\x61\x1d\x84\xc3\xe6\x63\x3e\x86\xfe"
+  "\xe8\xc7\x9b\xbd\xd8\xb7\xef\x1c\xa7\x95\xcf\x0e\x50\xcb\x07\xcb"
+  "\x1d\xc4\xf2\xb4\xdf\x81\x9f\x6d\x8c\x75\x26\xd0\xb7\x14\x30\xad"
+  "\x2a\x50\x81\x38\x36\x7a\xf9\xfc\x08\xe2\xb9\x1c\x69\xa9\x22\x3c"
+  "\x48\x4f\xb3\x8c\x2b\xe3\x37\xc5\x5a\x59\xcb\xf8\xf6\x91\xcc\xb9"
+  "\x3d\x6f\xe6\x6d\x42\xdf\xb5\xe3\x44\x9d\xc8\x6b\x44\x98\x46\x36"
+  "\x80\x31\xc6\x96\x6c\xf9\x9b\x0d\x3c\xef\x90\xed\x3c\x97\x6f\xb3"
+  "\xf0\x6b\x3b\x75\x1b\x4a\x58\xb7\x8a\xee\x46\xe5\x1c\x58\x99\xee"
+  "\x43\x54\x1f\x2b\x5c\xc2\xfb\x56\xaa\x83\xca\xcb\xf8\xc8\xf7\x1d"
+  "\x52\x78\x35\x09\xe9\x10\xfc\xaa\x6c\xc1\xf4\x7d\xa4\x8b\x9c\x6f"
+  "\xe8\x47\x7b\x6d\xa4\x8b\x3b\x0e\x63\xf9\xc3\x3b\xe9\xb9\x90\x3f"
+  "\x67\x71\x1f\x1b\xcc\xd7\x53\xbe\x13\xc7\xda\xbb\x9e\x45\x5d\x0a"
+  "\x00\x7c\x3f\x11\x52\x3c\x76\xde\xb6\x03\x9e\x2d\x69\xba\x26\x1f"
+  "\x00\xd1\x89\x3c\x6a\xec\xab\xd8\x99\x83\x7d\xcd\x3e\xa2\x15\xfd"
+  "\xf5\x21\xf6\xe3\x6c\x20\x9a\xd1\x9f\xc9\xf4\xed\xfc\x44\x96\xfd"
+  "\x21\x6a\x23\xf1\x73\x92\xf0\x7d\x98\x57\xb5\x89\x68\x0f\xb6\x7b"
+  "\xe7\x41\x35\x8f\x79\xbb\x51\x0e\x24\x2f\x92\x8b\x0a\x27\xe9\x7e"
+  "\x15\xe2\x92\xcf\xa3\x13\xba\x41\xbc\xae\xba\x8a\xb5\x12\x7c\x10"
+  "\x76\x17\xff\x3e\x62\x29\xd6\x3d\x39\x0f\xfb\x74\xb4\x0b\x3a\xcb"
+  "\x17\xf1\x1e\xa0\x6f\xd6\x20\x8e\x46\xe2\x29\xd2\x32\x9b\xf4\x11"
+  "\x9f\x5b\xe5\x72\xb3\xb0\x3f\x9f\x80\xd7\xac\xa0\xfd\x57\x4d\xd4"
+  "\xea\xd7\xae\x50\xfb\x27\x79\x57\x05\x6c\xe9\xc0\xf5\x21\x1f\xcc"
+  "\x67\xa4\x5d\xbf\x93\xfb\x0e\x59\xd6\x55\xd7\x35\xa1\xbd\xa8\x70"
+  "\xec\x0b\x91\x75\x23\xd7\xc7\xc2\x0c\xfa\xe6\xaf\x0e\xcb\x36\xca"
+  "\x78\x78\x9b\xb9\x3e\xd9\xb9\x0e\xb4\xb2\x42\x6c\xe7\xa0\x1e\xec"
+  "\x02\x59\xce\xad\x21\x3c\x51\x7c\x57\x06\x7d\x73\x81\x7c\x12\xc6"
+  "\x99\xf7\xf4\x0d\x04\xfd\x12\xc9\x3e\xc0\x65\xbf\x6b\x7f\xbd\xe8"
+  "\x6f\x65\xbf\xb5\x4b\xe4\x5f\xa5\xd1\x61\xa2\xe5\x53\xae\xbf\x44"
+  "\x8b\x6d\x09\xd1\xd2\xc8\xe9\xb0\x99\xe1\x8c\x54\xb5\x88\xea\xc7"
+  "\xb2\x2e\xd9\x5e\x65\x5c\x3b\x0f\x11\xae\x17\xd0\x57\x11\x4d\x58"
+  "\x77\x2a\xf7\x7f\x0f\x70\x9e\xfc\x52\xa6\xbd\xc5\x6b\xa7\xb2\xaf"
+  "\xec\x3f\x2f\xf1\xb2\x2d\x78\x9f\xe4\x15\xe7\x32\xc7\x62\xf9\xfd"
+  "\xe6\x95\x04\xff\x46\x22\xf9\x68\xf3\x93\x74\x5f\xed\x37\x3f\x8e"
+  "\xba\x7a\x0a\xf4\x88\xcf\x40\x3a\xaa\xe8\x45\x8f\x54\x7d\x9a\x62"
+  "\x76\xe4\xf5\x01\x8c\x91\xf6\x13\xbf\x49\x97\x31\x46\x9a\xd6\x57"
+  "\xf1\x6a\x92\xa2\xb7\x58\x4f\x2d\xf1\x5e\xc8\xe7\xd5\x15\xa8\xc7"
+  "\x8d\x41\xdd\x7a\x75\x85\xcc\xc7\xfd\xc8\x47\x03\xd6\x77\x42\x6e"
+  "\xd7\x7e\x84\xc7\x58\xac\xfa\xf7\x32\xed\x35\x32\x7c\x89\x22\x07"
+  "\xd9\x56\x5b\x77\x92\xff\xe5\x32\x78\x2d\x51\x2e\xbb\x4f\xd4\xf5"
+  "\xda\x95\x0a\x2c\xc5\x88\xe2\xbc\xf5\xd7\xae\x24\x3f\x38\x19\x65"
+  "\xcf\x7d\x1f\xff\x9e\x93\x48\x23\xdb\x11\x75\x54\xf3\xef\x63\xbf"
+  "\x80\x71\x4f\x50\x8f\x5e\xed\x09\xf1\x4f\xe4\x8b\xab\xda\x11\x07"
+  "\xf9\x53\xd2\x25\xf2\xa9\x34\x66\x40\x1a\x9b\x65\xfb\x91\x69\x7e"
+  "\xed\x09\xad\xae\x54\xbf\x83\xba\x32\x31\x88\xfb\xb5\xf4\x70\xfd"
+  "\x5c\xbd\xf0\x81\xb5\x72\xdb\xf6\xc8\x6d\x3b\x20\xb7\x6d\x8f\xdc"
+  "\xb6\xfd\x58\x07\xf1\xed\x29\x15\x1f\x91\x6f\xaf\xff\x4e\x86\x6f"
+  "\x24\x5f\x1e\xb4\xd7\xd7\xa3\x15\x5b\x1e\xea\x2f\x5e\xff\x15\xd9"
+  "\x83\x8a\x2e\x57\x88\xbf\x68\x0c\xef\x2f\x5e\x3b\x28\xb7\xb7\x21"
+  "\xc4\x36\xf6\xc9\xf1\x6e\x9b\x22\x87\x76\x4f\xbf\x7c\xb6\x78\x79"
+  "\x1b\xf9\x4f\xaa\x5b\xdd\x07\xd5\x09\xbe\xca\xb6\xfc\xfa\x4f\x86"
+  "\xca\xe1\xf5\x02\xb5\x3d\x93\xac\xc9\x27\x10\x0e\x92\x29\x8f\x2b"
+  "\x31\x4d\xc8\xf5\xf5\x0c\xf2\x0d\x6a\x1f\x8d\xb0\xd5\x01\x46\xf6"
+  "\xf2\x7a\x91\xd6\x16\x5f\xeb\x92\x6d\x51\xae\xbb\x7a\x1e\xca\x28"
+  "\x45\x55\x6f\x4f\x48\xbd\x24\x9b\x66\xe2\x83\x2c\xd3\xe9\x4a\x9f"
+  "\x46\xf0\x58\xb6\xa8\xaf\xa2\xda\x1c\xd2\x3f\x56\x11\x7d\x58\x57"
+  "\x0d\xf7\x59\xbb\xb9\xaf\x28\xea\xe3\xf4\x54\x27\xd7\xcb\xfd\x04"
+  "\xa6\xa5\x88\xb4\xd7\xdd\x72\x5f\xa2\xe8\xcd\x1b\x5a\x9a\xaa\xcb"
+  "\xc2\xc7\x47\xaf\xd5\x28\xf1\x11\xc7\xc5\x7d\x51\xf5\x36\xb9\x7d"
+  "\x94\x36\x51\xa4\xbd\x96\x41\x69\x3b\x05\x1f\xaa\x19\xef\xaf\x5e"
+  "\x75\xcb\xfd\x15\xd9\x97\x84\xcf\xcb\xc9\xc6\xe8\x19\x71\x74\x10"
+  "\x7e\x67\x59\x3f\x8d\x21\x6a\x5c\x52\x95\x8f\xfc\x01\xf9\x0b\xf3"
+  "\x6a\xe1\x37\xcc\x0b\xf8\xef\x78\xf2\x3b\x14\x87\x50\x3e\xc2\xf5"
+  "\x90\x2f\xc2\xf4\xbb\xcc\x0f\x61\x5c\xf0\x37\x03\xe2\x7d\x23\x49"
+  "\x2e\x3b\x9f\xc7\x0a\x7f\x4b\x8f\x52\xd2\x94\x72\xe8\xb7\xfc\x54"
+  "\x8e\xca\x2b\xfe\x8b\x7c\x97\x8f\x7c\x93\xa8\xef\x55\x59\xc7\xf9"
+  "\xb8\x41\x89\x8b\x06\x24\x15\x2c\x9d\xef\x2c\x7c\xda\x71\xe1\xcf"
+  "\xde\x68\xa3\xb2\x5c\x7e\xe8\x2b\x4b\xcf\xb3\x13\xf5\xf9\xa0\xaf"
+  "\xfb\x8a\xfc\x62\x79\xab\xa0\x73\xb7\x45\x6e\xc7\x97\xbc\x1d\xc2"
+  "\xa7\x56\x09\x5a\xca\x5b\xeb\xfa\x29\x6f\x77\x3c\xb5\x85\xf2\x76"
+  "\xa9\xf2\xd8\x80\x85\xf2\x6e\xe1\x74\x85\x94\x0b\x0c\x58\x87\xc0"
+  "\xd7\x8b\xef\x66\x19\xea\x76\x2b\xbe\x77\xf7\x7e\x41\xe7\xee\x55"
+  "\x8a\xdf\x45\xbe\x7b\xc8\xf7\xf2\xbc\xd5\x32\xcc\x02\xf9\x97\xfb"
+  "\xf7\xdd\x6f\x08\xbe\x9a\x24\x99\xdf\x3e\xb9\x1d\xef\xf0\x71\xf6"
+  "\xdf\xb2\x91\xb7\xbb\x2b\x15\xde\xaa\xef\xc9\x7e\xb0\x7e\x23\x3d"
+  "\x73\xbd\x2f\xe6\x63\xd8\x5a\x82\x21\x9a\x44\x1f\xf1\xc6\xb6\xd0"
+  "\x98\x1a\xc7\x7a\xe3\xa8\x5f\x12\xb1\xea\x1e\x9d\x3c\x07\x03\x8e"
+  "\xfc\x7f\xc2\x7e\xe1\xcd\x0c\xc5\xc7\xb0\xbe\x74\x1c\xf3\x77\x22"
+  "\xcc\x9b\xfc\x1b\xb7\x74\x26\xb0\x1a\x86\xfc\xd3\xbb\xfd\x2e\x19"
+  "\xe7\x9b\x16\xc5\x6f\x90\x2f\x69\xf7\x74\xca\x31\xdd\x9b\x1d\x75"
+  "\xb2\x2f\x39\x23\xbd\xf9\x27\x6d\x1c\xf6\xe6\x9f\xb4\x3e\xa3\xe6"
+  "\x74\xa8\xcf\xc0\xb8\x79\x5b\x5f\xc5\x9b\x07\x34\x71\x00\xa6\x5d"
+  "\xd8\x77\xbc\x59\x46\x36\x4a\xdf\x59\xe0\xfe\x89\xcf\x2b\xd5\xdc"
+  "\xab\xd0\x4c\x7e\xb3\x77\x8b\x32\x7f\x51\xf3\x29\xc5\x6a\xda\xfa"
+  "\x6a\x92\x34\xbe\x93\xea\x53\xf0\xe9\x81\xce\xe9\x47\x3e\xd0\x9c"
+  "\xcb\x9b\x3d\xb2\x9f\x6f\xd0\xf8\x4a\xb9\x0f\x23\x3f\xa9\xed\xab"
+  "\xca\xdb\xb4\x7d\x55\xcd\xef\x86\xfa\xc8\x9a\x9a\xe1\xf7\x55\x35"
+  "\x79\xe4\xb7\x14\x1f\xa9\xf5\x05\x35\xb5\x75\x9a\x58\xb6\x26\x59"
+  "\x89\x65\x83\x7e\xf4\xcd\x43\xe4\xa3\xb0\xfe\x46\x51\xf7\x9e\x44"
+  "\xec\xf7\x4d\x4a\xdd\x98\x9f\xd1\x6e\x46\xdd\xac\x28\x2f\x43\x9d"
+  "\xf2\xca\x31\x20\xb7\xcd\x7e\x7e\x56\xfa\xee\x54\xd4\xbf\x58\xd2"
+  "\x33\xc7\xba\xaf\xa0\x2b\xd8\x57\x34\xf7\xae\x57\xf8\xbb\xe7\x27"
+  "\xea\xb8\x70\xef\x6e\x56\x8e\xf5\x14\xab\xdb\xb8\x03\xd3\x76\xc9"
+  "\x73\x08\x9c\xb7\x1c\xd7\x9e\xac\xfa\xdd\xda\xb6\x89\x76\xec\xd9"
+  "\x46\xed\xa0\x31\x11\xd6\x9f\x46\x71\x0f\xc6\x7c\x78\x5f\xd5\x52"
+  "\x3f\xa8\xf3\xaf\x24\x9d\xb7\xab\xe3\xab\xed\xc9\xe4\x2b\xe5\xb1"
+  "\x67\x0b\xc6\x3b\x55\xea\xb9\x98\xf9\xf7\x67\x99\xf3\xf2\xd7\xac"
+  "\x2b\x58\x3d\xd5\xbc\x66\xdd\x9a\x82\x35\x2b\x72\xd7\x6c\x5e\x51"
+  "\xb0\x66\xfd\xba\x09\x6b\x57\xfc\x70\xcd\xd3\xe6\xc2\x15\x1b\xcc"
+  "\x29\x45\xe3\x8b\x62\x21\x08\x3a\xd3\xbc\x62\xc3\x86\xe7\xd7\xae"
+  "\xca\x31\xaf\x5b\xf3\xf4\xc4\xfc\x55\x1b\x56\x15\x98\x57\xe4\xaf"
+  "\x7f\x7e\x5d\x8e\x79\x7c\xce\xa4\xf1\x29\x77\xe4\xc4\xaa\xe7\xd0"
+  "\x6e\x34\x42\x4f\xe0\xeb\xbf\x76\xef\xfa\x1a\x0c\x09\xba\xbc\xfc"
+  "\x84\xa2\x35\xeb\xc4\xbc\xdd\x5b\xa7\x27\x57\x43\x1e\x7d\x4b\x91"
+  "\xbe\x19\xc6\x2a\xde\x02\xfc\xd5\x13\x1c\xb6\xd3\x4c\xdf\x52\x44"
+  "\xda\x93\xfa\x2a\xde\x3a\xe8\x92\xea\x6a\xf8\xf7\xc0\x30\x1d\xdb"
+  "\x96\xc4\xbe\xfe\x5d\x37\xc6\x6c\x79\xb4\x2e\xb8\xfe\x6b\x48\xac"
+  "\xda\x08\x7a\xbc\xe2\xf0\x32\xd2\xb7\x16\xb1\x4c\x97\x4b\xaa\x05"
+  "\x71\xde\xf2\xdb\xdb\xdc\x31\xbf\x4a\x61\xe5\xbf\x92\xbf\x75\xf6"
+  "\xf6\x56\x65\xae\x37\xf3\x45\xc8\x24\xfd\xec\x94\xde\xe6\xef\x73"
+  "\x5e\x40\x5d\xa6\x39\xd3\xde\x5f\xdf\x97\x8a\xf1\xe0\x71\xc7\xb5"
+  "\x3c\x6f\xab\x47\x82\x38\xa4\x4b\xdf\x54\x9c\x02\xaf\x63\x5d\x1b"
+  "\x4c\x8c\xf5\x55\xbc\x9d\xae\xcc\xa7\x61\x1b\x8c\xd8\x96\x0e\xb9"
+  "\x1d\xb7\xf1\x76\xec\x66\xc9\xd5\x63\x91\xbe\xd7\x88\x9e\xb7\x0b"
+  "\x94\x36\x20\xdd\x1d\x2e\xe9\x2d\xfa\x1e\x9a\x91\xe8\x0a\x37\xd7"
+  "\x47\xf3\x5d\x48\xe7\x7b\x81\x8d\xc8\xb7\xeb\xc5\x77\x22\x76\xd5"
+  "\x09\xfb\xc3\xf6\x78\xea\xf1\x7e\xe7\x57\x10\xb7\x83\xbe\xe3\x67"
+  "\xbf\x81\xb5\x79\x7c\xe0\xb4\x76\x40\xc2\x26\xe6\x66\xff\xf3\xaf"
+  "\xdd\x72\x9b\xba\xc9\x37\xfc\x8f\x67\x3a\xf4\xd4\x26\xec\x2b\xe2"
+  "\xea\xbf\x8a\x38\xb7\xa8\x7f\xfd\x2a\xe6\x61\x6f\xab\x63\xae\xda"
+  "\x47\x88\x27\x14\x6f\xf5\xda\xe9\xbb\x70\xb5\x33\xb0\xee\x2a\x39"
+  "\x36\xf6\xb0\x81\x25\xaa\x58\xaa\x96\xf4\xcc\x13\x01\xb7\x41\xc1"
+  "\x4d\xdf\x07\xa4\x32\x42\xfe\xb5\xef\x61\x19\xb7\x0a\x7f\x4d\x28"
+  "\x7e\xc2\x89\xf7\x6e\xa5\x1e\x31\x0e\xaf\xa5\x98\xc0\x8d\xba\x1c"
+  "\x76\x3e\x1b\xeb\x4b\x7e\x6d\x37\x3b\xe6\xc4\xf4\x5d\xe7\x41\x8f"
+  "\xb0\xc7\xea\x77\x73\xfc\x5e\xe4\x3b\xff\x0e\xde\x0b\x57\x01\x6c"
+  "\x43\x98\xde\x8a\xb7\xab\x3c\xfc\x5b\x7d\x7b\xd1\xfe\xcb\xcb\x43"
+  "\xe7\xb2\x65\x7d\x9e\x19\xa2\xcf\xa9\xaf\x51\x4c\x58\x8d\xf8\x51"
+  "\x87\x76\x9d\xc3\x7e\x18\x9f\x27\x55\x83\x85\xea\xc1\xfb\xa3\x34"
+  "\x1f\x82\x38\xad\x4a\x7d\x0c\xf5\x7f\x67\x40\xcc\xc1\xc8\xba\x35"
+  "\x81\xe6\xaf\x6d\x45\x8c\x35\xa1\x7f\x27\x1a\x49\xc7\xb0\x4c\xad"
+  "\xa2\x53\xa8\xeb\xc7\xb8\x5e\x25\x82\x85\x55\xec\x35\xd7\x8f\x05"
+  "\x6e\x1f\x75\xa8\x4f\xa4\x57\x08\xdb\xa2\xe8\x14\xea\xda\x51\x82"
+  "\x43\x1a\x62\x0f\x6e\x4e\xd5\x93\x8f\xec\x92\xea\x66\x93\x8e\xb1"
+  "\x37\x1f\xee\x60\x57\x2f\xee\x10\x72\xaa\x9b\xed\xf4\x0a\x19\x04"
+  "\xf9\x5e\x67\x54\xf1\xfd\x28\xea\x71\x2c\xf1\x59\xcc\x55\xd7\xcd"
+  "\x46\xda\x8e\xf2\x58\xbc\x04\x65\xc0\xfb\xaa\xbd\x3e\x2a\x2f\xf3"
+  "\xb0\x35\xc8\xc3\xba\xec\x70\x3c\x0c\xe1\x9d\x5e\x7c\x2b\xb0\x2e"
+  "\x87\x6c\x05\xcb\x0c\x7e\xff\x2f\x9c\x2c\xb1\x0e\xbd\xbe\x1a\x0c"
+  "\x54\x47\x73\x22\x87\x3f\x1c\xae\x8e\x50\x3d\x6e\x6e\x00\xa0\xb9"
+  "\x70\x2a\x97\x9c\x48\x7c\xad\xf3\x84\x95\xef\xd3\x1a\xda\xf8\xc5"
+  "\x2a\xea\xe1\x75\xf1\x2d\x57\xac\xaf\x7e\xc2\x85\xe8\x4b\x36\x8b"
+  "\x7e\xd1\x71\x23\xe9\x73\xfd\x2a\x67\x0d\x00\xa5\xc9\xcf\x8b\x7a"
+  "\xb1\xaf\x09\x9d\xcf\x8f\xfc\x7e\xa1\xfe\x27\xda\xf7\x0b\xf5\xd5"
+  "\x91\xde\x2f\x84\xd4\x7b\x82\xea\x0d\xd4\x2f\xd2\xa9\xea\x6e\x0d"
+  "\x84\xa9\x5b\x29\x3f\xa9\x41\x3d\x7e\x69\x98\x42\x34\xb4\xd3\x37"
+  "\xc9\xbf\xb7\x48\xc7\x10\x4f\x33\xef\xb3\x1b\x52\x44\xbc\x42\x71"
+  "\x50\x83\x91\x60\x42\xdb\x31\xf8\x67\x48\xfc\x0d\xfd\x9c\xe7\x0f"
+  "\xd1\x0f\x00\x9d\x0c\x04\xd7\xb7\x28\xd9\x92\x06\x18\x58\x98\x87"
+  "\x38\x80\x1b\x38\x3c\xc3\x3f\x91\x24\x3f\xbb\xf9\x83\x7e\x10\x7e"
+  "\x30\xff\xef\xf8\x8b\x11\xf4\x72\x7c\x5e\xd0\xc9\xf5\x75\xab\x20"
+  "\xd2\x2e\x50\x9a\x81\x52\x24\xdc\xdf\x73\x78\x95\x2d\xc2\xf1\xaa"
+  "\xd9\xc0\x81\x19\xf3\x89\x8c\xc1\x67\xa6\x7e\xa6\x14\xed\x33\xfe"
+  "\x45\x2d\x51\x55\x70\x43\x54\x0e\x5f\x6e\xf4\xfd\xd4\xc1\x24\x94"
+  "\x87\xba\x4a\x23\x94\x45\xf3\x9b\x04\xfa\xc7\x8b\xf8\x2c\x98\x6f"
+  "\xb6\x0c\x02\x5c\xe1\xd9\xaa\x02\xff\x58\x90\x3f\xae\xe8\x02\x6d"
+  "\x1c\xe9\xdf\xf5\xaa\xfb\x1b\xc4\xcf\xb8\x19\xdf\x20\xfe\x0b\xff"
+  "\x99\x8f\xc6\x28\xb7\x41\xf5\x18\xe7\x08\x07\x1a\xe4\xff\x8d\x66"
+  "\x25\x49\xad\xa1\xc1\xfc\xf1\xb5\xda\xe7\x9b\xb3\xb5\xcf\xb7\xec"
+  "\xff\x06\x28\x07\x4e\xa4\xcd\x75\x39\xca\xac\x60\x30\x31\x21\xc4"
+  "\x64\x12\xaa\x42\x4c\x28\xf8\x27\x53\x13\x85\xf4\xf8\x54\xc9\xfa"
+  "\xf0\xd0\xff\x39\x7f\xd7\x6e\x95\x0d\xe2\x06\xb7\x71\x48\xe6\x9c"
+  "\x90\x34\x7a\x1e\x65\x96\xd3\xa6\xfc\x66\x08\x3c\x4f\x33\xab\x9e"
+  "\x75\xa9\xf8\x4f\x03\xea\x7f\xeb\x37\x41\xeb\x77\x7f\xff\x3f\xfc"
+  "\xd3\x91\x7d\x7c\xf7\xf7\x9f\xf4\xc7\x44\x2f\x8e\x9e\x88\xff\xd0"
+  "\x7f\x6c\xd0\x51\x32\x39\x83\xc9\x09\x4c\xbe\xf9\x46\xfa\xf1\xef"
+  "\xfe\xbe\xfb\xfb\xee\xef\xbb\xbf\xef\xfe\xbe\xfb\xfb\xee\xef\x5b"
+  "\xf0\xa7\xe3\xe3\x08\x26\xff\x29\xf7\x22\x8f\x86\x40\xab\xab\x79"
+  "\x9a\xa4\x83\x20\x04\x0e\xb7\xa7\x83\xce\x00\xa3\xf4\xdf\x5c\x94"
+  "\x67\x1e\x24\x68\x98\x05\x68\x9f\xcd\x14\xbc\x6e\xc7\xeb\x7b\xaa"
+  "\xf4\xeb\xc3\x83\xff\x17\xfc\xe9\x90\x61\x51\x38\x0e\x8c\x86\x51"
+  "\x30\x1a\x0c\x10\x03\xb1\x70\x19\xc4\x41\x3c\x8c\xc1\xf1\xa5\x11"
+  "\x2e\x87\xb1\x70\x05\x24\xc2\x95\x70\x15\x5c\x0d\x26\xb8\x06\xae"
+  "\x45\xca\x93\xe0\xba\xf0\x34\x97\x41\xaa\x09\xff\xc1\xff\xb3\x20"
+  "\x95\x3f\x2f\xff\x2e\xfd\xbf\x34\xdd\x21\xa7\x1f\x95\xd3\x5d\xdf"
+  "\xa5\xff\x97\xa6\x9b\xff\x2f\xff\x8e\xfb\xbf\xfa\xab\x43\xd7\x2c"
+  "\xbc\xb3\x2e\xac\x4f\x0c\x4d\xd5\xc9\x7f\x83\xcf\x70\x91\xf2\x43"
+  "\xf0\x69\xcb\x87\xfe\xa5\xe2\x35\x4d\xdc\xda\x00\xc4\x7c\x2e\x53"
+  "\xff\xf9\x22\x95\x54\xfe\x4a\xf5\x78\x19\xf1\x4a\xc2\xeb\x06\xbc"
+  "\x6e\xc3\x6b\xba\x82\x47\xc0\xd0\x94\xec\x5f\x0f\x02\xfc\x39\x1b"
+  "\xe0\xff\x54\xe1\xaf\x07\xe0\xf8\x04\xbc\x1c\xc0\xf5\xe2\x2f\xcb"
+  "\x01\x4e\x34\x04\x71\x9e\x99\x16\xa4\xae\x27\x59\xdc\x9b\xf1\x72"
+  "\x1f\xa6\x3b\x17\xf8\x14\xd8\xc6\xb9\x8b\xd2\xcd\x53\x26\x4d\x9b"
+  "\x34\x6d\xc6\x4a\xf3\xc4\x89\xe6\xa9\x29\x29\x77\x4d\x9e\x32\x75"
+  "\xf2\x94\x19\xe6\x29\xd3\x67\x4e\xbd\x63\xe6\xf4\x19\xe6\xb5\x9b"
+  "\xf2\xd7\x4c\x49\xf9\xe1\x2a\xf3\xea\x35\xf9\x6b\x0b\x57\xe4\xaf"
+  "\xba\x58\x8b\x2e\xe9\x8f\xc8\xbb\x2e\x00\x5c\x02\x5a\x6e\xdf\x00"
+  "\xd2\xfe\x32\x90\x7e\x35\x03\x82\x39\x16\xf9\xd2\xfe\xe9\x56\x1f"
+  "\x03\xdd\xd3\x1d\xa0\x5b\x96\x06\xba\x27\xb2\x40\xf7\x88\x0f\x74"
+  "\xdb\x30\x6d\xab\x03\x74\x25\x89\xa0\x2b\x34\x80\x6e\x7d\xed\xd0"
+  "\xb4\x1d\x07\x45\xda\x3b\x29\xa0\xdb\x97\x03\xba\xba\x59\xa0\xdb"
+  "\x5d\x2d\xd2\x0e\x21\xcc\xbb\xd3\xfe\x53\xda\x7c\xe9\x7f\xc3\x8d"
+  "\x07\x22\xff\x49\x9f\xd6\x7e\x03\x74\x7c\xf7\xf7\xdd\xdf\x77\x7f"
+  "\xdf\xfd\x7d\xf7\xf7\xdd\xdf\x77\x7f\xff\xc5\x7f\x5f\x49\x7a\xf8"
+  "\x2d\x46\x83\x7d\x76\x83\xc9\xa5\xfb\x5e\x0e\xad\x0f\x01\xda\xf7"
+  "\x04\x06\x7e\xce\x88\x7c\xa9\xd7\x96\xc4\xdd\xbf\x17\x80\xf6\x6e"
+  "\xbe\xbe\x9b\xb9\x69\x5f\x66\xda\x4f\x00\x9a\x31\x42\xa4\xf5\x2a"
+  "\x88\x67\x89\x0b\x9e\xcb\x10\x6b\x93\x98\x87\xf2\x69\x7d\x13\xa6"
+  "\x17\x60\x7a\xf3\x05\xd6\xbb\xf0\xb5\x55\x84\x33\x6d\x1c\xa7\x67"
+  "\x5f\x08\x1e\xc2\xd1\xe8\x82\xfc\x59\x17\xc0\x11\xa7\xd0\xe5\x91"
+  "\x40\x47\xf8\x7a\xed\x60\xf2\xd8\x1d\x57\x62\x59\x0f\xb6\xc9\x22"
+  "\xaf\x0d\xea\x61\x76\x88\x6a\x2e\xf2\xd1\x1e\x51\xdd\x49\x88\xfd"
+  "\x11\xfe\x4a\xf8\xfb\x06\x88\xb5\x9c\x54\x2e\x99\x70\x60\x59\x5d"
+  "\x9f\x3d\x26\x65\xb0\x2c\xe2\xe6\xfb\xac\x21\x76\x8d\x47\x72\x48"
+  "\x02\xd6\x18\x23\xc3\x4a\x08\xbb\x44\x81\x15\x79\xd2\x3c\x39\xef"
+  "\x32\xcc\x2b\xd2\xe6\xe9\x5f\x93\xf3\xe2\x30\xaf\x3a\x84\x3e\xbd"
+  "\xb3\xdf\x07\x27\x21\xe6\x00\xd2\x62\xa6\x3d\x49\x54\x46\x86\xbf"
+  "\x1c\xe1\x9b\xb5\xb8\x00\xe4\xbc\xb1\x98\xe7\xd2\xe6\xfd\x3a\x45"
+  "\xce\xbb\x1a\xf3\x7c\xda\x3c\x9d\x52\xce\xd4\x67\x8f\x35\x85\x69"
+  "\x27\xd5\xaf\x13\x75\x53\x1b\x62\x67\x21\x4c\x19\xc1\x2c\x32\x97"
+  "\x01\xc9\x8a\xf2\x9a\x1a\x06\xeb\x27\x98\xe5\x0a\x1e\x17\x96\x57"
+  "\xf1\x14\x79\x19\x5b\xac\x94\x4f\x33\x13\x0e\xe0\x3c\x24\x3c\x2e"
+  "\x88\x49\x27\x3c\xf4\x8c\xf7\x49\xd4\x6e\xf9\xde\x4c\xed\xd3\xae"
+  "\xd9\xc1\x21\x0f\x44\xe3\xa0\x66\x14\x5e\xa3\x0d\x8a\x0e\x6c\x30"
+  "\xb1\x80\xed\x1a\x5a\x97\xd5\x74\x30\x60\x67\xe0\x2c\xf2\x82\xf9"
+  "\x5a\xb0\x75\xc2\x65\x26\x5a\xf7\xb3\x73\x33\x18\x6c\x79\xcc\x4b"
+  "\x7b\xd9\xdb\xdd\x3d\x60\x73\xb3\x6e\x3a\xbb\xa8\xf4\x1c\x18\xe8"
+  "\x5b\x90\xa5\xcf\x81\xa9\xb9\xf8\xf3\xb0\x6b\x8d\x02\x12\x03\x5b"
+  "\x12\x95\xed\x82\xf6\xda\x2e\xb0\xd5\x6a\xcb\xda\xae\x03\x53\x1b"
+  "\x9d\x83\x64\x87\x04\xa2\xa3\xd9\xec\x03\x5f\x6c\xd3\xc1\xe2\x3d"
+  "\xa0\xb7\x8d\x03\xa9\x2d\xc7\xa1\xd0\xe2\x22\x5a\xb6\x9d\x02\xc3"
+  "\x8f\x57\xa3\x0e\x9d\x22\x7a\x3f\x3e\xf8\xee\x66\xaf\xd4\x64\xca"
+  "\x80\x26\xd3\x71\x68\x36\xcd\x86\xe6\xa2\x34\xd8\x79\x0a\xe2\x9a"
+  "\xbc\xb3\xa0\x59\xff\x00\xda\x58\x1a\x38\x7b\xf0\xde\xec\x47\x18"
+  "\x0f\xdf\xc7\x71\x12\x2e\x3b\x5a\xfd\x0c\x18\x5c\x02\x27\xf2\xf7"
+  "\xb2\xe3\xca\x9e\x04\x7a\x0e\xd7\x8e\x0d\xd7\x80\x09\xe9\xeb\x46"
+  "\x5a\xee\xea\x84\xb8\x2b\x93\x4d\x90\x82\x34\x8f\x76\xd6\xf8\x40"
+  "\x5f\x0c\x31\x11\x6c\x2b\x91\xef\x67\x46\xdd\xac\xdb\xcd\xba\x49"
+  "\x47\x7b\xb7\x64\xa3\x9d\xc6\x65\x60\xdd\x3d\xf2\x3a\xbf\x1e\xdb"
+  "\x8f\x40\xdf\x5b\x98\x4d\xeb\x9b\xbb\x30\xcf\xaa\xe4\xd1\x3e\x6d"
+  "\xda\x7f\x3d\x39\x91\xbe\x05\x94\x0a\xef\xf7\x77\xd3\x1a\xc2\x1e"
+  "\x5a\xd7\x49\xf8\x12\x8a\x20\x0a\xdb\x13\x8d\xf4\xdc\x55\x8f\xe9"
+  "\xdf\x47\x38\x2c\xbf\xdf\x05\x87\xb8\x1e\xb1\xab\x17\x7b\x02\x57"
+  "\x2f\x3e\x17\x78\x73\x71\x2f\x7b\x73\xf1\x57\xfe\x37\x17\x7f\x69"
+  "\xdb\x04\x06\xff\xd5\x8b\xdd\xed\x79\x5c\x06\xc6\xf6\xbc\xd3\xb4"
+  "\x1e\xd0\x40\x67\xa3\x2f\x7d\x0e\x65\xef\xfb\x14\x4a\xd6\x80\x29"
+  "\x10\xf3\x91\xd5\xe9\xfb\x04\x96\x16\x03\xc3\xfb\xa2\x70\xed\xeb"
+  "\x8d\xfd\xd8\x2d\x6c\xc8\x80\x6d\x8a\x37\xbb\xa4\xdf\xee\xa7\x7a"
+  "\xdd\x31\xff\xee\xc6\xcb\x83\x97\x17\x2f\x1f\x8b\xfd\xd8\x87\xbc"
+  "\xb2\x8d\xd9\xaa\x03\xda\x87\x30\x39\x00\xba\x53\x10\x3f\x0b\xe9"
+  "\x37\x46\xe0\x5b\x52\xa0\xe2\x84\xfb\xe6\x32\x28\xed\xeb\xb3\xd2"
+  "\x7e\x70\x37\xf9\x25\xf2\x53\x58\x4f\x39\xd6\xd3\xcd\x6d\x71\x37"
+  "\xf3\xb0\xd8\x13\xb4\x27\xbe\xdb\xb3\xc5\xaa\x73\x6f\xb1\x4a\xbd"
+  "\xb1\x27\x7a\x11\xe6\x80\x4b\x6a\x32\xcb\x3c\xec\x26\x5c\x68\x13"
+  "\xee\x78\x1f\x44\x21\xce\xbc\xff\xf5\x75\x87\x7e\xef\x6e\x76\x1c"
+  "\xe1\x8e\x0d\xe2\x42\xdc\x88\x07\xf9\x1f\xdf\xad\xa4\x21\xaf\xbb"
+  "\x76\x20\x1c\x95\x77\x7a\x53\xc9\x7f\xbb\x9c\xb9\xdd\xb4\x0e\x37"
+  "\x96\x0d\x88\xfa\x10\x86\xf6\x68\xba\xe3\xbd\x30\xaa\xcf\x0e\x59"
+  "\x84\x9b\xca\xd1\x99\x5c\x58\xae\x97\xd9\xac\xe8\xdf\x60\x41\x1f"
+  "\xb3\xea\x68\x4f\x7e\x13\x96\x17\x75\x8f\xc9\x52\x68\xa4\x3a\xf8"
+  "\x9e\x7c\xa2\x13\xf5\xa1\x29\xd7\x0b\xf1\x35\x10\x85\xe5\x16\x12"
+  "\x3e\xc2\x85\x7a\xe0\xc2\xb6\xf6\x36\xe5\xba\x21\xc0\x34\x38\x5d"
+  "\x32\xbe\x06\x0d\x3e\x4c\x67\x88\x8f\xf4\xaf\x19\xcb\xc4\x37\x70"
+  "\x7c\x8f\xfe\xaf\x00\xe1\xf3\x82\xde\xcc\xe9\x7d\x9c\x70\xf0\x33"
+  "\x26\x10\xa7\x63\xe3\x7d\xd0\x03\x09\x06\xb7\xcd\x1a\xc5\xd7\x03"
+  "\x62\xf9\x77\x4b\xbb\xa3\x59\x6f\x76\xd4\x18\xbe\x16\xf0\x3e\xa0"
+  "\x73\x18\x7a\x60\xcc\x5f\x59\xaf\x35\x2a\xbe\x07\xf4\x44\x33\xed"
+  "\x07\x22\x3a\xd5\xb2\x7c\x74\xee\xe3\xb3\xe1\xf1\xb4\x79\x69\xb3"
+  "\x61\xfe\xbd\xf7\xcf\x86\x94\xbb\x26\xa6\xdc\x7e\xe7\x8c\xdb\x21"
+  "\xeb\x07\x8f\xce\x86\xac\x05\xb3\x61\x21\x5e\x59\x0b\xe7\x3e\x9a"
+  "\x36\x77\xe1\x6c\xc8\x7e\x60\x1e\x3e\xdd\x3f\x7b\x4a\xca\x83\x13"
+  "\xb3\xee\x9f\x37\x17\x1e\x59\x34\x35\x65\xea\x54\xb8\x77\x6e\xc6"
+  "\x94\x94\x14\xf9\x77\x4a\x0a\x81\x3c\x39\x63\xee\xc2\x89\x59\xf9"
+  "\xeb\x0b\xd6\x4f\x5c\x30\xef\x7e\x98\x3b\x77\x76\x96\xb6\xaf\xb5"
+  "\xf8\xbf\xf6\x13\x8f\x3d\xec\x6c\x3a\x9d\xbd\x00\x75\x28\x7b\xbc"
+  "\x7a\xf8\x9e\x0e\x30\x7e\x52\x47\x32\xe3\xbe\x35\x81\xfa\x2b\x7d"
+  "\x9f\x3d\xe1\x38\xf2\x6e\x39\xf1\x8e\xce\x3f\x38\x09\x57\x8d\xc7"
+  "\xbc\x5b\xe4\xbe\x23\x1a\xf3\x7d\xda\xfc\xcb\x8f\x62\xfe\x64\xda"
+  "\x23\xe0\xc4\x0b\xf9\xed\x41\x1f\x88\x7c\x75\x43\xaf\x2d\x3b\x9a"
+  "\xef\xd1\x44\x59\xd3\xda\xd9\x3e\xbb\x71\x86\xca\xd6\xbb\x68\x8d"
+  "\xad\x79\x33\x44\x9d\x01\xe3\xe5\xed\x05\xa9\xb4\x8f\x06\x9c\x05"
+  "\x32\x8e\x73\x83\x38\x62\xe5\x7d\x9e\xae\x3a\x5a\xbf\x2c\xf0\x94"
+  "\xa9\xfc\x82\x8b\xf0\xec\xc4\x3c\x19\xd7\x63\xed\xe8\x1f\xd0\x7f"
+  "\xff\x6b\xc0\x66\x01\x16\xdb\xd4\x18\x18\xb0\xf0\x3e\x01\xcb\x35"
+  "\x2a\xfa\xbc\x93\xd6\xc6\xe6\x21\xdc\x8f\xd3\x75\xb4\xb6\x94\xaf"
+  "\x33\x85\x04\x3a\x6b\xc1\x13\xa8\x38\x06\x7c\x0f\x34\x4f\xbb\x5c"
+  "\xcf\x62\xf1\xb9\xe2\x98\x8e\xd9\xc4\xbe\x68\x4c\x8b\xa6\x34\x94"
+  "\x75\x14\xd9\x24\xdf\xf7\x89\x75\x63\xfa\x26\xa4\xaf\xc3\x4f\xe5"
+  "\xcf\xf2\xf2\xa3\x31\xed\x09\x84\xd5\x05\x62\x8f\x49\xa8\x3b\x94"
+  "\x86\x71\xc2\x55\x69\x88\x2f\x8a\xf6\xa4\xb3\x38\xb3\x1b\xef\xf5"
+  "\x8e\xcd\x3d\xfc\x6c\x71\x17\xe6\x05\x6c\x88\x73\x60\xb0\x7e\x0b"
+  "\x95\xc5\xba\xf4\x7d\x03\x56\xec\xe3\x2e\xe7\x67\x9e\xf9\x89\x9e"
+  "\xb3\x83\x30\x26\xaa\x93\xec\x1a\x65\x31\x0d\xe5\x14\xd3\x67\xbf"
+  "\x7c\x5f\x88\x9c\x0e\x23\x1e\xda\x43\xd1\x81\x38\x12\x03\xbd\x58"
+  "\x07\x3e\x23\x5e\x49\xc6\xab\xe0\xf0\x08\x3d\xb8\xbc\x2b\x44\x0f"
+  "\x62\x10\xf7\xec\x60\xfe\x58\xbd\x36\xff\xca\xd3\x98\x7f\x9f\x9c"
+  "\x8f\xf6\x35\x36\x59\x9b\x3f\x36\x15\xf3\x1f\xc0\xfa\x3d\x68\x3f"
+  "\x51\x2e\x30\xee\xaf\xa3\xf8\x2f\x08\xbf\x28\x04\x3e\x0f\xe1\x1f"
+  "\xa2\xf5\xef\xe4\xdb\x09\xbe\x5e\xd6\x55\x84\x37\x20\xfc\xb6\x90"
+  "\xfa\xdb\x10\x7e\xa1\x8a\xbe\x90\xf6\x5f\x91\x8b\xf9\xd9\xa4\x5b"
+  "\xf8\x9b\x83\x30\xa3\xc9\x66\xc9\x5f\x34\xe5\x52\xbc\x38\xf6\x58"
+  "\x48\xfd\x04\xf7\x6c\x40\xe1\x51\x2f\xf1\xc8\xb8\x5f\x8e\x45\x8e"
+  "\x0b\x1a\xae\x30\x84\xd4\x61\xc1\x32\x1b\x50\x7f\x74\x8a\x6e\x84"
+  "\x29\x33\x2b\xa4\xcc\x12\xae\x5b\xa2\x1e\x59\xc6\xa2\x8c\xec\x8b"
+  "\xd4\x38\xa8\x6d\x18\x1f\x5d\x51\x16\xd2\xf6\x25\x58\xef\x96\x1d"
+  "\xc2\xce\x2f\x43\x9d\x98\x8a\x69\xf3\x11\x67\x34\xe9\x11\xe9\xba"
+  "\xd3\xed\x45\x5f\x99\x1e\x27\xfa\xfc\x2b\x4e\x24\x14\x03\xdd\x4f"
+  "\xa4\x7b\xc2\xcd\x06\x32\x64\x1b\xb8\xe2\x04\xfe\x52\x3a\x3f\xcb"
+  "\x88\x6c\x8f\x0d\x3c\x1c\x10\x38\x13\xa3\xd1\x46\x25\x7c\xf6\xcb"
+  "\x75\xcc\xa5\xfd\xc3\x48\xbf\x84\x7e\x18\x68\x0f\x34\xa6\x4f\xc3"
+  "\xf4\xd9\x72\xfe\x74\x82\xc7\xfb\x29\xf2\x3d\xe9\xad\x24\xeb\x2d"
+  "\xda\xc1\x95\x7c\xbf\xb8\xb0\x05\x51\x3e\x20\xf4\xfe\x7e\xcc\xbb"
+  "\x06\x7f\xe7\xe1\x6f\x34\xfe\x3e\x82\x75\x9f\xa0\x33\x1f\x6c\x7e"
+  "\x8c\x3b\xc4\x73\x1b\xfe\x3e\x8a\xbf\xbf\xc2\xdf\x85\xf8\xfb\x13"
+  "\xb2\x5b\x77\xa1\x15\x42\x74\xa6\x27\x20\x6c\x75\xb4\x90\x61\x62"
+  "\xb5\x6c\x3f\xc2\x7e\xcf\x06\xd3\x98\x48\x93\x04\xcf\xe5\xb4\x81"
+  "\x74\xe2\x4b\x16\xe2\xcf\xa3\xfa\x65\xbb\x8f\x16\x72\x12\x30\x01"
+  "\x51\x4e\x2f\xe4\x2d\xa7\x09\x38\x9d\xba\x4e\xfc\x4d\x2b\xf5\x30"
+  "\x86\xbf\x29\xfc\xbc\x08\xb8\x72\x1a\xf2\x44\x8f\xcf\x7a\xe2\x13"
+  "\x87\xe7\x78\xaf\x68\x50\xc9\x1b\xe3\xf1\x2b\xf3\x42\xe4\xbd\x0f"
+  "\xe5\xbd\x83\xcb\x1b\x79\xa7\xd0\x4c\xf4\xa3\x4e\xd3\xf3\x28\x45"
+  "\x6f\x50\xbf\x7b\x82\xbe\xfb\xca\x46\x2d\x1e\xe3\x7e\x2c\x83\xe3"
+  "\xaa\x2b\xf8\x59\x7a\x74\xee\x4d\x54\x31\xe9\xe8\x95\x18\xff\xb7"
+  "\x1d\xe7\x71\x53\xc5\xb1\x51\x84\xc7\x63\xe3\xe7\xeb\x78\xa2\xf2"
+  "\xc8\xb6\xae\x02\x25\x9f\xe7\xc5\x74\xe6\x11\x2d\x51\xb9\x3c\x2f"
+  "\xc9\x85\xaa\xa5\xe4\x81\xd8\xb7\xe5\x89\x2a\xe0\x79\x33\x82\x78"
+  "\x9b\x3a\x64\xbc\x51\x14\x6f\x50\xdc\x80\xfd\x77\x37\xc2\xe0\xf8"
+  "\x27\x3e\xf2\x59\x4a\xe5\x4d\x2d\xa8\x34\xd2\xad\x65\x10\xed\xf4"
+  "\x1d\x83\x4c\x1f\xf3\x4f\x2c\x83\x18\xa7\xef\x00\xdc\x02\x70\xb9"
+  "\xd3\x77\x1c\x6e\x05\x18\xe7\xf4\x55\x63\xff\xbc\x8f\xf2\xdf\xb7"
+  "\x80\x4e\x87\xbf\xb6\x9b\xca\x24\x9d\xd3\xb7\x0d\x92\xcb\xf4\xf8"
+  "\x9b\x0b\x0f\x44\xb3\x3e\xa7\x2f\x03\xe1\x72\x20\xd3\xcf\xce\xa6"
+  "\x45\xb3\xcf\x96\xf9\xc1\x98\xf1\x22\xb3\x39\x7d\x18\x2b\xfb\x5a"
+  "\x31\x3d\xc0\x32\xfd\xe7\xf1\xea\x63\x81\xf2\xa6\x8e\x4c\xff\x59"
+  "\x76\xff\x8b\xef\xe3\xf3\x67\x8c\x49\xc0\x9c\xbe\x59\xd0\xee\xf1"
+  "\x20\x9c\x8d\xb1\xed\x4d\x2d\x4b\xcf\x49\x30\x40\xe7\x1c\x6d\x6f"
+  "\xea\xc0\x36\x76\x0f\x60\xfb\xb0\x0f\xfa\x62\x60\x0b\xfe\x56\x34"
+  "\x9d\xe4\xcf\xe5\x4d\x5e\x66\x68\xea\x9e\x84\x03\x0f\x6a\x83\xd3"
+  "\xd7\x05\xcb\x30\x74\xce\xdc\xe4\x66\x44\xff\x98\xad\x34\xee\x98"
+  "\x45\x67\x24\x24\x64\x6e\xb2\x31\xcc\x33\xb0\x98\x26\x1c\x2b\xf4"
+  "\x00\xd6\xe1\x45\x7c\xe7\x38\xbe\xf2\x66\x13\xc2\xba\x09\x4e\x8d"
+  "\x87\x70\x10\x6c\xa6\x1f\x12\xd8\xf6\x66\xd3\x40\x4c\xb3\x01\x2f"
+  "\x0b\x5e\xd9\x2c\xb6\xf9\x19\x66\x4f\xfc\x0d\xed\x73\xc5\xf2\x45"
+  "\xf8\x5c\xde\x47\x67\x32\x11\x2f\xfd\x30\x1a\xe1\x8b\x50\x7f\xd2"
+  "\x50\x0f\x91\xde\xe6\xfd\x9c\xde\x8a\xe6\xff\xde\xc7\xdb\xd1\xfc"
+  "\xdf\x44\x3b\x9a\x7f\x42\xe9\xbd\xa8\x53\x78\xdf\xd2\x2b\xf2\x3e"
+  "\xc4\x72\x8b\x78\xb9\xf2\xe6\x16\x66\x68\xee\xf0\xa2\x7d\x21\x5f"
+  "\xcb\x88\x8f\xc8\xd7\x32\xe2\x25\xe2\x6f\x71\x16\x55\x02\x8b\x69"
+  "\xee\x40\x7a\xba\xb1\x7c\xff\x00\xef\xa7\x8f\x18\xfa\x38\xee\x23"
+  "\xa3\x11\xcf\x12\xd4\xdf\x28\x66\x38\x82\xf2\x3e\x62\x1a\xb0\x9b"
+  "\x21\x73\x13\xf3\x66\xfa\xb6\xfa\x96\x6d\x82\xa8\x09\x50\xa6\xa3"
+  "\xf3\x63\x9d\x45\x39\xd8\xce\x66\xfc\x4d\xc3\x7c\xb8\x02\xeb\x7a"
+  "\x9f\xc5\x1c\x31\x50\x7d\x6c\xfb\x11\xb4\xd5\x23\x38\x6e\x87\x1c"
+  "\xa2\xe9\xbc\x1d\x8c\xf8\x6c\x39\xcf\xe9\x3b\x92\x1e\x28\x3f\x62"
+  "\x0d\x18\x8e\x64\x2b\x3a\x44\xfa\x23\xf8\x56\x0d\x0b\x3c\xcc\xe7"
+  "\xf4\xed\x05\xd4\x31\x63\xbb\xe7\x38\xe5\xe3\xd8\xe0\x00\xca\x99"
+  "\x74\x6a\x1b\xfe\xee\x03\xd2\x9f\xf6\xbc\xe7\x09\xf6\x7d\xd2\xa1"
+  "\x05\x79\x9e\xad\x13\x21\x4f\x87\xcf\xb6\x65\x3e\x03\x2c\xcd\xd3"
+  "\x97\xf9\xcb\x8f\xcc\x68\xcf\x23\xb9\x1c\xc3\x32\x54\x2e\x17\x12"
+  "\x74\x18\x1f\xeb\x98\x2f\xa1\xc8\xad\x8f\xb7\xda\x58\xbb\x27\x03"
+  "\x61\xf3\xf8\x79\xb8\xa4\x47\x04\x3f\xbf\x87\xb9\xfc\x86\x23\xdd"
+  "\xd4\x36\x36\xa6\x0c\xda\x7a\xa6\x03\x8d\x51\xda\x7a\xf6\x91\x9e"
+  "\x06\x90\x2f\x8d\xa8\xa3\x03\xf3\x7b\xca\xa2\x97\x9e\x03\x1d\xa6"
+  "\xf9\xdb\xac\x07\x30\xbf\x19\xe1\x5a\xb9\xde\x2e\x38\xe7\x4b\xf0"
+  "\x19\x8e\x58\x7c\xe5\x47\x5a\x16\x9c\x1b\x60\x6d\xd6\x6a\x78\xaa"
+  "\xa7\x0c\x79\x75\x00\xe6\x9f\xf6\x45\xb5\xe7\xe5\x20\x4c\x1f\xa6"
+  "\xef\xe3\xfa\x3f\xff\x74\x2f\x5b\xf0\x1c\x3b\xbb\xe0\xdc\x67\x6c"
+  "\xbe\x95\xbd\xbf\xac\x08\xc6\x5c\xb6\x95\x05\xc8\x2e\x5a\xbb\x0e"
+  "\xc0\x65\xc7\xe9\x0c\x9c\x34\xc8\x58\x11\x60\xf3\x4f\x9f\x65\x4b"
+  "\x9f\x23\xde\xcc\x82\x36\x2b\xda\x4f\x51\x35\xf1\x3b\xbd\xcd\x7a"
+  "\x18\xeb\x4f\x43\xbc\x36\xe6\x2c\xda\x8b\xb0\x8e\x84\xa7\x4e\x1b"
+  "\xa1\xb5\xab\x1a\x7c\x31\x47\x2c\xfe\xed\x47\x66\x04\x62\x8e\x64"
+  "\x07\xb6\x1f\xb1\xa2\x9c\x1a\x7d\xdb\x8f\xb4\xf8\x63\x8e\xa0\x0e"
+  "\x7c\x30\x03\xe5\x14\x43\x32\xef\xc7\x31\x3b\x3e\xdf\xd1\x4f\xf2"
+  "\x2f\xff\x20\x9d\x19\x3e\xb0\xa2\x6f\x64\x42\xf7\x3f\x48\xa7\x71"
+  "\x37\x8b\xf9\xc0\x3a\x10\xf3\x41\x36\xc2\x59\x85\x7d\x7d\x50\x44"
+  "\x7a\xc9\xfb\xa6\x8a\x0f\x0a\xb1\x2f\x89\xc2\xfc\x72\xbc\x6a\xf0"
+  "\x42\x1f\xf7\x81\x17\xf1\x5f\xde\x27\x70\x7a\xd9\x3d\x55\x18\x67"
+  "\x9e\x23\x9d\xb4\xb1\x98\x0f\x4d\x99\xfe\x19\x36\xe4\x23\xda\xca"
+  "\x07\xde\xc0\xf6\x0f\x0d\x2c\xf6\xc3\x19\x5e\xae\xff\x1f\xde\x49"
+  "\xf8\x07\xb6\x58\x68\x4c\xae\x67\xdb\x3f\x4c\xc7\xb4\x7f\xed\x23"
+  "\x7d\x35\x7c\xd8\x18\x30\xb4\x98\x58\xf9\x87\x2d\x0f\xbf\xc8\xdc"
+  "\xfe\xf2\x0f\xbb\x03\xe5\x1f\x76\xf8\x46\x61\x0c\x5b\x74\x18\xc8"
+  "\x47\xf9\x7e\xcd\x18\x7d\x0f\xa8\x3d\x6f\x1f\xd7\x01\x67\x11\xda"
+  "\xc1\xa6\x6b\xcb\xda\x7a\x50\x1f\xf2\x7e\xc6\xfd\x53\xbb\xe7\x18"
+  "\xe7\x2b\xd2\xd1\x48\x7a\x45\x32\x5e\x9a\x07\x65\x58\x57\x0b\xd2"
+  "\xd2\xe1\xdf\x8e\x78\x63\xb0\x9e\xd8\x8f\x9e\xf4\x72\x9b\xfd\x08"
+  "\x75\xf6\x30\x96\x39\x02\x42\xcf\x3f\xca\x8e\xe4\x27\xc9\x5f\x91"
+  "\x8f\xca\xf4\x79\x49\x6f\xbe\x20\xdf\x26\x7c\x15\x2c\x53\x7c\x15"
+  "\xf9\x29\x1a\x17\x90\xaf\x0a\xc8\xbe\x2a\x20\xfb\x2a\xfe\x6c\x40"
+  "\x7f\x53\xde\xd4\x4d\x3e\x29\xb3\x48\xf8\x9a\x4c\x7f\x0a\x43\xfd"
+  "\x88\x43\x1c\xdd\x42\x1e\x08\x53\xd1\x74\x8e\xc3\x73\x3e\x35\xe3"
+  "\x98\xb9\xd9\x80\x97\x25\x20\x7c\x8e\x55\xf6\x39\x92\xe2\x73\xfc"
+  "\xd8\xd7\xa1\x5d\x05\xc2\xf9\x9c\x80\xec\x73\xfc\x4c\xf8\x9c\x80"
+  "\xec\x73\x28\xdd\x2f\xfb\x1c\x7f\x18\x9f\x13\x28\x6f\xa6\xf6\x46"
+  "\xc9\xbe\xa6\x8c\x7c\x0d\xb5\x37\xb0\xbd\xb9\x23\x20\x7c\x8d\x17"
+  "\xc7\x04\x12\xf9\x1a\x3f\x96\x09\x28\xbe\xa6\x8f\xfb\x04\x13\xf9"
+  "\x9b\x81\x97\x00\x7d\xa8\x19\xc8\xcf\x70\x9f\xe2\x1b\xe7\x23\x9f"
+  "\x82\xfc\x9b\x13\xea\x53\xd0\x57\x59\xf0\xde\x28\xfb\xaa\xec\x84"
+  "\xad\xcc\x87\x3e\x65\x46\x66\x91\x07\xe8\xdb\xbf\x09\x3e\xf4\xdd"
+  "\x45\x05\x65\xce\x22\x1f\xa0\x2f\xb0\xb2\xf6\x32\x40\xbf\x83\x3a"
+  "\xec\x47\x7f\x01\x80\xb6\xd9\x88\x36\xda\x8d\x75\xb7\xb4\xe7\x7d"
+  "\x02\x68\xf3\x96\xf9\x3d\xbd\xce\xa5\x1e\x8b\x71\xfe\x69\xe6\x46"
+  "\xfe\xb8\x96\xe6\x95\xa1\x8f\xb1\xb8\xdb\x7a\xde\x83\x8c\x2e\x16"
+  "\xc8\x58\xee\x32\x23\x1d\x2d\xf3\xd7\x38\x12\xe8\x5b\x41\x0b\xce"
+  "\x31\x07\xfa\xc6\x7f\x9f\x7f\xda\x98\xb0\xa4\x0b\xae\xcf\x58\xc1"
+  "\x02\x68\x53\xc8\x77\xb4\x35\xb4\x49\xa4\x3d\x1b\xed\xce\x8a\xb6"
+  "\xd6\xe8\x0b\xb1\x35\xb4\x9b\x3b\xf0\xde\x2c\xf8\xf7\x81\x15\x6d"
+  "\x2d\x3d\xc0\xfb\xb4\x2e\x3e\x16\x43\x7b\xb0\xd2\x5c\x15\xda\x5b"
+  "\x7a\x60\xbb\xb0\xb7\x80\x28\x57\x14\x20\xfe\x49\xb2\xbd\xa1\x2c"
+  "\x30\xbf\x1c\xaf\x1a\xbc\xc2\xdb\x5b\x5e\x88\xbd\x3d\x27\xdb\x5b"
+  "\x8c\xb0\x37\x94\x6b\x94\x7f\x8b\xb0\x39\xaa\x83\xc6\x6c\x83\x36"
+  "\x17\xfb\x21\x3f\xd3\x47\xe8\x0f\xd9\xdd\x87\xd8\xbf\x7c\xd8\x8d"
+  "\x36\xd7\x11\x28\x6f\x41\x7c\xcc\x4d\xfe\x13\xf5\xf3\x2f\xd4\xe7"
+  "\x2d\xc8\x63\x7f\x59\xe6\xbf\xb6\x0c\xeb\xea\x46\x9f\xf6\x19\xfa"
+  "\xd3\xbf\x2c\xf5\x40\x03\xe2\x6a\xc4\xfa\x5a\xd0\xa6\x3a\x02\xdb"
+  "\xb9\x4d\x65\xfb\xb7\x10\xce\x8f\xb2\x07\x71\xf0\x3e\x53\x6b\x53"
+  "\x62\xa6\x3b\xfc\x7c\x61\x9f\xfd\x86\x38\x17\x1c\xef\xe0\xe7\x40"
+  "\xda\x6f\x30\xb9\xe0\xd3\x03\xf2\x7d\xb2\x0b\x7e\xcd\xd3\xc9\x16"
+  "\xf3\x4a\xe1\xca\x53\x70\x43\x07\xea\x3d\xe0\x7d\x1c\xde\x1f\xcf"
+  "\xbc\xe5\x7d\x16\xa8\x1c\x63\xc1\xba\xfb\xc8\x1e\x99\x7d\x1a\xc5"
+  "\x8c\xa9\xa8\x8f\x06\xd6\x67\x89\x63\xb1\x7f\x8c\x65\x03\x26\x9a"
+  "\x93\x4a\xc0\xe7\x31\xc8\x83\x64\xfc\x1d\xbb\xf7\x6b\x48\xc4\xcb"
+  "\xb4\xd7\x1e\x28\xa3\xf8\x0a\xef\x53\x58\xa1\x29\x76\xe7\x46\x98"
+  "\x90\xe0\x11\xe7\x9a\x27\x6c\x35\xd2\xdc\x4c\x22\xdd\x33\xfb\x6f"
+  "\x7d\xf5\x5f\xcb\x67\x9b\xc7\x63\x7d\x61\xbe\x65\xec\xef\x23\x3e"
+  "\x34\xb5\x28\xb4\x10\x6d\x48\xe7\x75\x48\x67\xcf\x63\x9b\x52\x81"
+  "\xbe\x93\x15\xce\xcf\xf4\xd9\xcd\x83\xed\x8f\x90\x3f\x41\xe1\x49"
+  "\x84\xfc\x0c\x85\x4f\x91\xf6\xb1\x52\x7f\xed\xdf\xc8\x7a\xe8\xec"
+  "\x0d\xda\x6f\x6b\xf3\xb1\xff\x40\x3e\x96\x95\xfa\xc1\x90\x59\xe4"
+  "\x65\xce\x1e\xe6\xa0\xef\x6d\xd5\xd3\x79\x20\xc5\x2c\x10\x88\xf9"
+  "\x43\x0f\xdb\xfe\x87\xee\xde\x8d\xcc\x47\x73\x1f\x58\xc7\x41\x17"
+  "\xdc\xbf\x5f\xc8\xe2\x48\x3a\x1f\x03\x1a\xfe\xd0\x8d\xb8\x2e\x27"
+  "\x5c\x6d\x58\xde\xbf\xfd\x0f\x6e\x84\xc3\x98\xf4\x94\x87\xc3\x19"
+  "\x8e\xa4\xe7\x6d\x86\xef\x9d\x82\x71\x46\x3e\x0e\x28\xff\x23\xf7"
+  "\x0b\x98\x66\xc4\xb4\x24\xb6\xfd\x8f\x18\xcf\x8e\x33\xb8\xe0\x0f"
+  "\x3e\x11\xeb\x8e\x4b\x52\xe0\x5c\x60\xe6\x67\xa8\x6a\x74\x48\xac"
+  "\x96\x28\xd3\xec\xe7\xd2\x81\x76\x77\x1a\xd5\x94\x1a\x3e\x3b\xe8"
+  "\xd7\x8f\xb4\xd0\x39\x9a\xb6\x12\x48\x42\xf9\x10\x7d\xaf\xda\x8a"
+  "\xd8\x49\x66\x1f\x67\xf9\xf1\x66\x2f\x8e\x21\xc6\xd5\xba\xe0\xe7"
+  "\x05\x91\xf8\x19\xf8\x9a\x75\x21\x0e\xeb\x2e\x1c\x07\x12\x7f\x88"
+  "\x9f\x68\x37\x01\xe4\xc3\x09\xf2\x4b\xf5\x1b\x69\x2c\x3c\xce\xa5"
+  "\xf0\x2b\xb2\x4c\xfe\xe0\x13\xe3\xc5\x1b\x53\x99\x9d\x81\xe3\x7a"
+  "\x7a\xd7\x70\xe3\xbd\x82\x07\x1f\x64\xf7\xa2\x2f\xa1\xb9\x54\x3a"
+  "\xf3\x72\x83\x89\xa1\x3f\xb8\x71\x9a\x0b\x6e\x3d\x2a\xcf\xd9\x78"
+  "\x9c\xbe\xb9\xe4\x5f\xc2\xf6\x5d\x7c\xef\xf1\x20\xfe\xef\x2f\x6f"
+  "\x47\xce\x0a\xff\xd4\x79\xa8\x54\xc8\x9f\xce\xa1\xf0\xd0\xde\xf9"
+  "\x2e\xcc\xdf\xe0\x61\xe8\x43\x3b\xf7\xd3\x38\x83\xf6\xf1\x62\xda"
+  "\x0a\xd4\x6b\xe6\xc8\x27\x9a\xbe\xbf\xc2\x71\x7d\x3f\x9c\xc4\xf1"
+  "\x20\xed\x95\x17\xf3\x37\xdf\xcf\x68\x2a\x00\x79\x4e\xe8\xc6\x56"
+  "\x17\x4c\xcc\x55\xe8\xa2\x58\x03\x79\x6b\xa0\xd8\x83\x62\x0e\x9a"
+  "\x9f\xdf\x50\xcc\xbc\x14\x7b\x20\xac\x57\x69\x03\xb5\x4f\xb4\xeb"
+  "\xfb\x71\xea\x76\x21\x0d\x6e\x1c\x5b\x73\x1e\x6c\xd8\x04\x06\x7e"
+  "\x06\x9f\x9f\xe6\xf7\xe7\xf2\xb6\x50\x9b\x79\x5b\xb8\x9f\xc5\x7e"
+  "\xc2\x37\x1d\xf5\x85\xa7\x5b\x11\x57\xb6\x0b\x6e\xeb\x10\xfa\x74"
+  "\x63\x6b\xa8\x0e\x0d\xea\x80\xe1\x88\xc9\x76\x1e\xae\xb7\x05\x58"
+  "\x27\xe2\xfc\x1c\xf9\x14\x45\xbf\x01\x8a\xb7\xbd\xa4\xbb\xc7\xbb"
+  "\xa8\x5f\x76\x16\x9f\x43\xdf\xcd\x61\xaf\x40\xd8\x2e\x84\xf9\x44"
+  "\x86\xfd\x44\xbc\x9b\xe1\xbf\xa3\xe9\x17\xfb\xb2\x2b\x91\x8e\x1e"
+  "\x37\xef\xf3\x3b\xf3\x94\x67\x86\xcf\xf8\xbb\x8f\x6d\x3f\xde\x15"
+  "\x9e\x96\x16\x13\xf5\x69\xfe\xaf\x59\x0f\xd6\x73\x35\xe9\x91\x6d"
+  "\x13\x5c\x83\x3a\x79\xa2\xb4\x04\xae\x24\x1d\x63\x31\x7f\x34\x08"
+  "\xbe\x27\xcf\x60\x76\x8c\x41\xd1\xa3\xe6\x6d\x84\xef\xa1\x0d\xc1"
+  "\x29\x48\x9e\xbf\xac\xd8\x8c\xb4\x02\xec\x3a\x03\x14\xa7\x7c\x86"
+  "\xf0\x7a\xfa\x3e\x62\xfd\x19\xd2\xc5\xe4\x5c\x45\x17\xf1\xbe\xe8"
+  "\x42\xbe\x02\xf9\x5a\x23\xe6\x15\x92\x3f\xa7\xb9\xf8\x4e\x48\x3e"
+  "\x4a\xed\xc5\x4b\x87\x69\xbf\x61\x5f\xb3\x24\x26\xfa\xb5\x72\x17"
+  "\x24\xfb\xf0\xb7\x86\x5f\xe8\x4b\xe4\xe7\x72\x84\x3b\xc8\xbe\xf6"
+  "\x13\x4c\x0d\xa6\xa1\x4f\xd6\x91\x9d\xd4\x62\xdd\x1e\x17\x3c\xe0"
+  "\x10\xb2\x49\x76\x10\xae\x08\x34\x94\x33\xbe\x8f\xfd\x2b\x6c\xef"
+  "\xf8\xa7\xcc\xa5\x3a\xa4\x63\xfc\x14\x6e\x17\x88\xab\x5e\x12\x3e"
+  "\x3b\x80\xb4\xd6\xd9\x03\x56\xf4\xcf\xd6\x40\xc5\x67\x55\xfc\x5e"
+  "\xce\x63\x72\x5f\x1a\x1e\x7f\xe7\x21\x3a\x8b\xa3\x0b\xc6\x37\x0a"
+  "\x3c\x9d\xfb\x1d\xd7\x9e\xa2\xe7\x5f\xd1\xb3\xc7\xe0\xaa\x72\xd6"
+  "\xa4\x8a\xb3\x8f\x11\x46\x8c\xf3\xc7\xff\xaa\x17\xeb\xe8\xb3\x8f"
+  "\x6f\x74\xc1\x24\xf9\xbd\x84\xab\x2a\x82\xed\x19\xc9\x76\xc8\xe6"
+  "\x84\x4d\xdf\xbc\xa3\xad\x81\xdb\x5f\x11\xea\x7c\x8d\xec\x7f\x69"
+  "\x0e\x26\xae\x13\x6e\xae\x6c\x33\x71\xfd\x96\x98\x74\x93\x49\x73"
+  "\x36\x2b\xe6\x0d\xbd\x6e\xca\xc0\x6b\x09\x5e\x56\xf9\x19\xa1\x6f"
+  "\x2a\xc7\xab\x03\x9f\x8b\x39\xef\xde\xce\xd1\xb9\x30\xaf\x17\x63"
+  "\x77\x7a\x76\xc1\x4d\x8b\xd8\xdb\xc9\x92\x72\x5f\xbf\x87\xe6\x11"
+  "\x6e\x42\x79\x8d\x37\x08\x59\xdc\xcc\xcf\x7d\x47\xda\x88\xef\xcc"
+  "\x56\xc3\xbc\xcd\xa5\x1e\xa4\xfb\xa6\x83\xcd\x35\x1e\x30\xdf\x44"
+  "\xed\xbf\xe9\x10\xb5\xc9\x83\xfc\xa7\xdf\x0d\x35\xcc\xdd\x54\xeb"
+  "\x03\x7a\x87\x85\xb8\xd0\xfe\x5f\xae\x14\x73\x12\x9d\x2e\xc2\x27"
+  "\xeb\x04\x53\xda\x2f\xf8\xec\xaa\x32\x6f\xd4\xd1\xf3\x35\x75\x62"
+  "\xde\xa5\x20\x38\x1f\x7c\xf3\xe5\x68\xe7\x73\xe8\xec\xe6\x33\x70"
+  "\xf3\x63\x0c\x79\xdd\x64\xe5\x67\x40\xba\x69\xfe\xa5\x8e\xcf\x6b"
+  "\xdc\x8c\xfe\x6f\xbc\x55\x3e\xef\xc6\xcd\x7d\x0d\xe2\xdc\x89\x79"
+  "\xd8\x1f\xf5\xb4\x59\xbd\xe0\xa7\x36\x63\xd9\xf7\xbe\xf6\xea\x13"
+  "\x0a\x40\x57\x4a\xdf\x55\x41\x3a\x18\xca\x4a\xf8\xb2\x9b\xba\x4b"
+  "\x4e\x33\xaf\xd2\x66\x7a\xd7\x89\x78\x2b\x5d\x50\x55\x13\xd1\x26"
+  "\x06\xdb\x61\x79\xa7\x29\x59\xc8\x31\x80\xbc\xd2\xca\xd1\xb2\x5f"
+  "\xc8\xf0\xe6\xe3\x5a\x19\x5a\xf6\xe3\x85\xa5\x2c\xb3\xf0\xca\x90"
+  "\x9f\xd5\x97\x51\x75\x8f\x72\xb5\x54\xf7\xd9\x2d\x49\x68\x1f\xdb"
+  "\x84\x6c\x2c\x7c\xfe\x87\x91\xde\x7c\x89\x7d\xcf\x40\x36\xd0\x7b"
+  "\x4e\x4a\x27\x1d\xa7\xf4\x00\xc6\x37\xf8\x9c\x82\xf9\x46\xb2\x5f"
+  "\x3a\x4f\x53\x9d\x3f\x78\x6e\x12\x58\xf8\x59\x35\x09\x5b\xcb\xcb"
+  "\x49\x77\x11\x66\x5a\x82\xaf\xbc\x1c\xeb\xab\x54\xf8\x8a\x69\x05"
+  "\x94\x4f\x7a\x8a\xe9\xfb\x90\x2f\xdc\x57\x78\x70\x2c\x18\x3e\xf6"
+  "\xb0\xb4\x0c\xc6\x68\x86\x0f\xbc\x24\xcb\x1e\xb8\xe5\x18\xfa\x31"
+  "\xf4\xdf\x9f\x95\x8b\xfe\xe7\x96\x4f\xe8\x19\xfd\xe7\x09\xbc\x3f"
+  "\xda\x86\x7e\xaa\xbf\xe2\xdf\xdd\x03\x12\x8c\xee\x97\x20\xd5\xb7"
+  "\x73\x4c\x86\x2f\xf6\x63\x9f\xb3\xfb\x10\xb4\xfb\xfe\x05\xe8\x1b"
+  "\xa1\x88\xe3\x77\x74\xae\xab\x6d\x13\xf3\xbf\xdb\xbf\x1f\x7d\xd9"
+  "\x59\x07\x3f\xc7\x5c\xec\x93\xd7\xbd\xd2\x89\x51\xc0\x52\x8e\x5b"
+  "\xf0\x27\x6e\x8c\x65\xe7\x6a\xe6\xdb\x79\x92\xce\x7a\x31\xc5\xee"
+  "\xe8\x87\x09\x6f\x6d\x86\x94\xda\x7e\x48\xae\xeb\x07\x0b\xfb\x82"
+  "\xbe\x3b\x13\xfc\x56\xcd\x98\x3c\x30\xd4\x6d\xc6\x78\xce\x07\x3a"
+  "\xff\x0e\x8c\xe7\x7c\x18\xcf\x9d\xb5\x90\xbf\x1c\x8c\xe7\x06\x78"
+  "\xac\xfc\xc7\x02\x7e\xfe\xf7\xf6\x3f\x16\xc4\x5b\x41\x17\xb7\x1c"
+  "\x8c\x48\x9f\xed\x0c\xdc\x12\x13\xd7\x85\xb1\x24\xb6\xd9\x25\xb7"
+  "\x17\x7f\x93\x12\xac\x30\x9a\xb7\x15\x7d\x38\xdb\xfe\x59\x58\x9e"
+  "\xf1\xbe\x59\x22\x9d\xf2\x90\x2d\x61\x1b\x6e\x1d\x47\xef\x5a\x0f"
+  "\x5d\xeb\xd5\x6f\xa8\x65\x5e\x4a\x2f\x18\xc7\xbc\x98\x6e\xa0\xba"
+  "\x0f\x62\x7a\x9f\xfd\xd6\x14\x97\xf4\x7e\x6b\x24\x1d\xc5\x71\x93"
+  "\xec\x6b\x6e\xfd\x05\x93\xca\x50\x47\x3f\x9c\x51\xe2\xc3\x78\xfc"
+  "\x0c\xd9\xf1\xad\x07\x33\x73\x99\xcf\xbc\x8e\xde\x7b\xdf\xda\x40"
+  "\xef\xe4\xe9\x5d\xdc\xcf\x31\xd6\xb9\xd8\x7b\x78\xea\x43\x68\xfc"
+  "\x90\x90\x8b\x38\x2b\x3e\x9c\xc1\x70\xdc\x3e\xdc\xb8\x9e\xd6\x82"
+  "\xbc\xce\xd7\x9d\xdc\xda\xe3\x82\xc7\x53\xe5\xf3\x5b\x7b\x84\x3f"
+  "\xbd\xad\xd5\x83\x3c\xd0\xfa\x80\xdb\x1a\xe8\x1c\x92\xde\xf2\x63"
+  "\xc5\x8e\xeb\xc9\xf7\xdf\xb6\x47\xc4\x42\xc7\x8a\x44\x5f\x70\xdb"
+  "\x26\x31\xa7\x7f\xdb\x2c\x17\xcc\xe4\x3a\x97\x77\x23\xe9\xc4\x6d"
+  "\x05\x2c\xf6\xd8\x16\x82\x9b\x54\x06\x65\xeb\x7d\x80\xb1\xc0\xb1"
+  "\x22\xc6\x6d\xe5\x0c\xb0\x37\x9f\xed\xa3\xb5\x14\x9e\xab\x17\xf7"
+  "\x61\x6c\xd0\x8a\x79\xc5\x54\x87\x1b\x61\x90\xef\x31\xe2\x9d\xfd"
+  "\x6d\x68\x0f\x77\xc9\xfe\xf0\xb6\x1c\x31\xd7\x7c\x5b\x4e\x2f\x96"
+  "\xc5\x58\xf1\x0a\xcc\xc7\xf8\x77\x61\xa2\xfc\x6e\x97\xbf\x57\xc5"
+  "\xb4\x66\x17\x2c\xe2\xf3\xac\x05\xe3\xc0\x54\x60\x66\xdd\x11\x63"
+  "\x3d\x4d\x3b\x27\xce\xe3\xeb\x62\x24\xb8\xba\xcf\x3e\xc1\xa0\xe0"
+  "\xc5\xfe\xf6\xa7\xbd\xd2\x63\x8f\x61\x5a\x92\x82\x17\x61\x70\xac"
+  "\x3c\x61\xc2\x20\x8c\x28\x33\x4b\x55\xe6\xb1\x5e\xe9\xd6\x9f\x62"
+  "\x5a\x56\x48\x99\xe5\x21\x65\xf2\x54\x65\xca\xe4\x7a\xb6\x85\x94"
+  "\xa9\x0e\x29\xb3\x2f\x0c\x6d\x8d\x21\x65\x5a\x42\xca\x74\x84\xa1"
+  "\xad\x27\xa4\x8c\x4f\x5b\x66\x62\x9c\x8a\xb7\xb4\x46\x25\x05\xd3"
+  "\xcc\xda\x32\x13\x53\x42\xca\xa4\x2a\xcf\x18\x7b\x2e\x17\xb1\x01"
+  "\xea\x13\xca\x14\xe5\x5a\x8c\xf9\xd8\xfe\xd9\x11\x63\x78\xd2\x4d"
+  "\xd4\x99\x02\xdb\x5e\x71\x0e\x3e\xf9\x55\x9a\x3f\x27\x7f\x8e\x71"
+  "\x71\x0f\xe9\x04\xc5\x9d\x54\xd7\x49\x98\xb4\x83\x74\x08\x71\x1e"
+  "\x1a\xca\x8f\x89\x2d\x21\x74\x76\x84\xd0\xd9\x3d\x94\x1f\x13\x7d"
+  "\xda\x32\x93\xe2\xb4\x65\x26\x25\xa9\xca\x34\x88\x7a\x26\xa5\x84"
+  "\x94\x49\x0d\x29\x93\x35\x54\x3f\x27\xe5\x84\x94\x29\x08\x29\xb3"
+  "\x2d\xc8\xc3\x49\xfc\x5b\x2a\x64\x0f\x98\x8e\xe3\x9f\xbb\x2f\xb4"
+  "\x4e\xcc\xa8\xe8\xb3\xb2\x5e\x4c\xe8\xf5\xe4\x71\xd5\x62\xdd\x14"
+  "\x3f\x83\xa8\x0b\x26\x4f\x07\x71\x8e\x9f\xfb\xc7\xfd\xde\x68\x7a"
+  "\xa7\x84\xbc\xed\x6e\x2a\xf2\x62\x9f\x3b\x19\xfb\xa8\xe9\x33\x94"
+  "\x35\x15\xb4\x0e\x85\x9f\x59\xc7\xc7\x23\x93\x5c\xc2\xfe\x26\x4f"
+  "\x93\xdf\xe1\x50\x7b\x70\x9c\x31\x79\xda\x25\xd2\xf5\x09\xd1\x45"
+  "\x67\x38\x21\x8e\xa2\xc1\xb1\xc6\x20\xad\x54\xe7\x64\xe5\xcc\x5d"
+  "\x3a\x6f\xb4\x9b\x9f\x0f\x88\xf7\x74\x9e\x16\x96\x39\xa0\x1a\x9f"
+  "\x10\xad\x9e\x43\x9b\xbd\x7a\x2d\xcd\x93\x2b\x65\x9a\x5d\xc2\x47"
+  "\x4d\x76\x29\xfe\x24\xa2\xfe\x95\x77\xd6\xb4\x23\xd7\xe9\xbd\x7f"
+  "\x5b\x2d\xc6\x9b\x38\xc6\x22\xba\x3b\x21\xc5\xc2\xe3\xdf\x75\xfd"
+  "\x40\xf7\xce\xe2\x99\x7c\x5d\x80\x68\x4b\xca\x72\xfa\x6e\x02\xc5"
+  "\x3e\xcd\x79\x5f\x41\x2f\x1f\xa3\x91\x6f\x4c\xd9\xd1\x54\xec\x46"
+  "\x5a\x53\xb2\x95\x75\x33\x2e\x48\x11\x71\x5d\x79\x67\x15\xad\x59"
+  "\xa0\xf7\x78\x4d\x9e\x19\x04\x53\x8c\x74\xa6\x2a\x3c\xa0\x6f\x30"
+  "\x20\x6c\xc4\x6f\xab\xa9\xf9\x2a\x68\x98\x7a\x5e\xe8\x4f\x4a\xb3"
+  "\xd6\x1e\xa2\x51\x4f\x53\x3a\xb4\x3a\x97\xd2\xad\xd5\xb9\x14\xaf"
+  "\xd6\x1e\x24\xb4\x87\x29\x71\xda\x32\x53\x92\xb4\x65\xa6\x4c\x50"
+  "\x95\xa9\x12\xf5\x4c\x49\x0d\x29\x93\x15\x52\x46\xed\xff\xb0\xcd"
+  "\x53\xf2\x06\xc7\x9d\xdc\xdf\x4f\x29\x53\x3d\x4b\xd5\xbc\x9f\x9a"
+  "\x52\xad\xa4\xd1\xdc\x1d\xc5\xa8\xa4\x37\x32\xbe\x83\x21\x3e\x8a"
+  "\xe0\x9b\x43\x68\x38\x16\x42\x43\x97\xf2\xbc\x4b\x8c\x9b\x7f\x8b"
+  "\xbc\xbb\x45\xd6\x33\x4f\xc2\x56\x78\x24\xc1\xf7\xe8\x13\x14\x9b"
+  "\x51\xff\xc4\xd7\x6e\x95\x60\x4c\x79\x8e\xbe\xc5\xee\xa5\xef\xf6"
+  "\x45\xd1\xb9\x6e\x2e\xb8\x7d\x09\x8e\xe7\xf2\x10\xa6\x07\xe3\xa9"
+  "\xcc\x93\x30\x85\xea\xaf\xc1\x3a\x90\x77\x53\xd3\xb5\x34\x4c\xcd"
+  "\xd6\xd2\x30\xd5\xaa\x7a\x36\xe2\x73\x91\xaa\xdd\xc6\x28\x13\x5f"
+  "\xa3\x89\xb1\xf5\xd4\x2a\x25\x9d\xe6\x00\xb0\x8d\xdd\x36\x1e\x07"
+  "\xa4\xd2\x7a\xb9\xb1\x9d\x30\xb5\x84\xe6\x0b\x64\x9c\x87\xd5\xbc"
+  "\x15\xbc\x98\x7a\x34\x84\x0e\x57\x08\x1d\xee\xa0\xaf\x99\xe2\x11"
+  "\x36\x72\xbb\xde\x05\xf7\xa4\x50\x1a\xf2\xc2\x9c\xe0\x33\x5f\xe1"
+  "\xb8\x91\xe2\xd4\xdb\x1f\xf1\x60\x7b\xd9\x4b\xd2\x58\xf9\xf9\x31"
+  "\x76\x23\xc5\xdd\x7f\xcc\x43\xff\x4c\x6b\x22\x6f\xc0\xb4\x25\x42"
+  "\xae\xb7\x63\xfb\xef\x4e\x17\x78\x6f\xe7\xef\x60\x09\x16\xef\x2d"
+  "\x2c\xa6\x73\x7f\x24\x7d\xee\x8d\xed\x6c\x90\xd7\x6b\x9a\x11\x47"
+  "\xa5\x62\x0f\x81\x8a\xce\x86\xc0\xf6\xbf\x64\x61\x5a\x03\xda\x44"
+  "\x8d\x18\xd3\x7c\x5a\x8b\xba\x5f\x83\xf2\xc3\x31\xf0\x34\x79\x2c"
+  "\xd3\x79\x88\xd6\xcc\xa1\x5f\xa2\xb3\x23\xe3\xc4\x7a\x89\xdb\x8f"
+  "\xa9\xec\xca\x63\xde\x3c\x87\x75\xc2\xb4\x3d\x14\xdb\x91\xdf\xa0"
+  "\xb5\x77\x4d\x3e\x37\xd0\x3c\x8b\xd3\x77\x8a\xc7\xe4\x98\x5f\x23"
+  "\xca\x4e\x33\xaa\xca\xba\xe5\x79\x90\x6e\xca\x9b\xec\x03\x7d\x93"
+  "\xc7\x4d\x67\xe4\x27\x8a\x38\x7e\xda\x9e\x26\xf4\x17\x58\x26\x4d"
+  "\x29\x43\x73\x26\x54\x06\xc7\x3c\xfa\x49\xc5\xf4\xbd\xc9\x4e\x8e"
+  "\x5b\x7e\x27\xcd\xc7\x47\xce\xe2\x6e\x70\x7a\x3a\x68\x4e\x53\x2f"
+  "\xd6\x2e\x4d\xab\x89\xf2\x82\xa1\x77\x7b\x27\xca\x7e\x5a\x8d\x7f"
+  "\x7b\x27\x8e\x17\x3b\x51\xcf\x6f\xa7\xf3\xfb\x35\xb1\xcc\xdc\xb9"
+  "\x59\x8f\x66\xce\x9f\xf8\x83\x47\xe7\x2d\x9a\x3b\xd3\xbc\x68\xcd"
+  "\xda\x55\x39\x13\xd7\x3f\x5f\x60\x2e\xcc\x5f\x53\xb0\x66\xdd\x0f"
+  "\xf9\xb1\x9e\xe6\x15\x05\xe2\xd7\x92\xbb\x62\x43\xc1\x6c\xba\x9d"
+  "\x60\xce\xcb\x5f\xb5\x91\xdf\xde\x12\x0b\x5a\x24\x6b\x0a\x56\xe5"
+  "\x9b\xc7\xe7\x4c\x30\x3f\xb0\x62\x4d\xee\xf3\xf9\xab\xc2\xe2\x9a"
+  "\x69\xce\x5f\x95\xbf\x6a\x45\x8e\x79\xb6\x39\x85\x30\xab\xd1\xa9"
+  "\xe4\x99\xa2\xf8\xa7\x0d\xd8\x9f\x63\x0c\xdd\x4d\x7e\x8a\xfa\xf5"
+  "\x93\x70\x67\x09\xc5\x70\xfc\x1c\x4e\xd4\x43\xec\x13\x5c\x7d\xf6"
+  "\xe9\xc5\x43\xfb\xf1\xe9\x55\x5a\xfd\x9d\xde\xa0\xd5\xdf\xe9\x07"
+  "\x87\xf6\xe3\xd3\x43\xec\x7f\x7a\x88\xfd\x4f\xef\x1a\xda\x8f\x4f"
+  "\xf7\x6a\xcb\xdc\x61\xd0\x96\xb9\xc3\x34\xe8\x67\x90\xd6\x17\xb8"
+  "\x5f\xba\x63\x42\x48\x99\x59\x21\x65\x32\x42\x9e\x97\xa8\x9e\x31"
+  "\x76\xbd\x23\x57\x1d\x1b\xe0\x73\xb1\x62\xeb\x41\xff\x76\x47\x95"
+  "\x02\x43\x7d\x4f\x3d\x7d\xef\x47\xc0\xee\x57\xc1\x76\xcb\xb0\x83"
+  "\xf6\x4f\x3e\x89\xd6\x2c\x8a\xf8\xfc\xce\x89\xb2\x6f\xa3\xef\xff"
+  "\x28\x7d\x68\x17\xca\xe2\x86\x33\x70\xc7\x9e\x7a\x01\xeb\xa6\x75"
+  "\xac\xec\xcd\xc5\x7d\xf5\x63\xc1\x40\x65\xe9\x1c\x4a\x66\x9f\xb6"
+  "\x8f\xce\x48\xc4\xb4\x38\xbc\xd0\x4f\xdd\x69\x76\x49\x8e\x5a\xaa"
+  "\x83\xd6\x34\xb8\xe0\x4e\xae\xcb\x54\x6e\x1b\x5f\x7b\xc7\xeb\xdb"
+  "\x43\xdf\x31\xa2\xb3\x5d\xc9\x7f\x52\xbd\x74\x3e\x2a\xd5\x8d\x38"
+  "\xf4\x4c\x9a\xf6\x57\xf9\x9c\x4b\x23\x5e\x89\x88\xb3\x40\xc1\x89"
+  "\xf8\xcc\x20\xce\xd3\xe5\xeb\xd4\x45\xdc\x73\x67\xb5\x12\x5f\xd0"
+  "\x58\x21\x9c\xef\x08\xbf\x26\x19\x12\x76\xd9\x03\x1d\x8e\xd2\x2e"
+  "\xa2\xa9\x99\xe2\x50\xa7\xc9\x07\xed\xb5\x3e\x1c\xbf\x82\x91\x8f"
+  "\xa7\x8a\x4e\x83\xb3\xc1\x07\x34\x3f\xbc\xac\x08\xca\xea\xa5\x00"
+  "\xbd\x67\x93\xcb\xd1\x18\xed\x4e\xbe\xe6\x7f\x1b\xa5\x63\x79\x1c"
+  "\x4b\xb8\x69\xed\x72\xa4\x6f\x6c\x11\x9c\xe3\x46\x1a\xef\xcd\x98"
+  "\x26\xc7\xbe\xe5\xf5\x88\x2b\xec\xba\x5a\x09\x9c\x7d\xf6\x19\xd8"
+  "\xff\x2d\xeb\x50\x7c\x76\x53\x0d\xf7\x7d\x12\xa6\x97\x23\x2f\x1a"
+  "\x23\xc5\x29\xb2\x7f\xcf\xa3\xb5\x5e\x08\x7b\xe8\x42\xb0\x44\x77"
+  "\x13\xb6\x1b\x6d\xb1\xec\xc7\xa5\x29\xd1\xb2\x7f\x35\x60\xb9\x1e"
+  "\xa5\xdc\x70\xda\x27\xef\x21\x70\xa3\xad\x7a\xc4\x58\x71\xe6\x8a"
+  "\xd7\xf9\x5a\xdd\xbb\x30\xfe\x9b\xa1\xd8\xc1\x65\xf8\x8c\xfe\x6f"
+  "\x06\x9f\x4f\xa4\x75\x35\x34\xa6\xde\x90\x87\x31\x9b\xc9\x83\xbe"
+  "\xf1\xae\xe5\x4a\x1e\x9f\x27\xa2\xbc\x62\xe6\x6d\x32\x75\x51\x5e"
+  "\xf1\x60\x1e\x95\x23\xba\x8b\x7c\x94\x5e\xad\xa4\x8b\xbe\xe5\xae"
+  "\x7d\x21\xcf\x87\x94\x67\xbc\x77\xe0\xfd\xe0\x3a\x7d\xf4\xb9\xb4"
+  "\xc6\x49\xd7\x09\x33\xc7\xd5\x71\xbb\xb9\xcb\xa5\xe4\xf3\x39\xb5"
+  "\x1f\xd1\xbb\x31\x0f\x04\x62\x8f\x95\xf1\x98\x0b\xcb\xd0\x77\xb1"
+  "\x70\x8c\xa1\x63\x03\x7c\xbd\x55\x0f\xe1\x21\x9b\xe1\xdf\xa6\xc1"
+  "\xe7\x4e\xb8\xeb\x58\x3d\xe9\x35\xca\xb5\xd0\x07\x49\x79\xf7\xd0"
+  "\xfc\xf3\x4c\xae\xb7\x94\x46\x78\x09\x1f\xf5\x89\x84\x9b\xf0\xd1"
+  "\xf7\xbb\x58\xaf\x15\x69\x9d\x49\xed\xaf\x8e\x24\x2b\xcc\x2f\x53"
+  "\xf1\x32\x1a\x9f\xab\xb4\x6d\x9d\xd9\x10\xf2\x7c\x50\x79\xa6\xb9"
+  "\x5e\xa1\x7b\x33\xf7\xc9\x79\xad\x17\xaa\x8b\xc6\xbf\x08\xe3\xd6"
+  "\xd6\x77\x37\x68\xf1\xdf\x6d\x0c\x79\x36\x2b\xcf\xd5\xfc\x1d\xc3"
+  "\xdd\x29\x4a\x1d\x5c\x66\xa8\x63\xfb\x4a\xdd\xd1\x17\x3a\xb7\x15"
+  "\xcb\xe4\xa8\xea\x1c\x85\xcf\x05\x41\xf9\xdd\x5d\xa6\xe0\xc3\xfb"
+  "\x4a\x15\x1c\xc6\x25\x77\xd7\x2a\x70\xe2\xfd\xc6\xdd\x07\x54\xe5"
+  "\x1a\x2f\xd2\xd6\x10\xdd\x9d\x1d\x2d\x74\xf7\x6e\xb7\x96\x96\x59"
+  "\x10\xc4\x39\x2b\x2e\x48\xcb\x2c\x93\x0a\x0e\xed\x73\x96\x25\x54"
+  "\x57\x37\x14\x91\x8e\x93\xbe\xce\x4a\x0b\x93\xe7\x95\xf3\x96\x87"
+  "\xd7\xf1\x59\x45\xaa\x74\x79\x7c\x34\xeb\x53\x39\x4e\x20\xff\xec"
+  "\xa1\x6f\x93\xc9\xe7\xa3\x73\x9d\xa4\x73\x93\xe5\xef\x25\xa1\x5e"
+  "\xcf\x6a\x0c\xc5\x4b\xdf\xb8\x19\xc4\x11\xc4\x59\x2e\x62\xbc\x59"
+  "\xdd\xaa\xb6\x79\x5c\x30\x53\x79\x4f\xe4\x16\x73\x83\x77\x77\x45"
+  "\x1a\x77\xf4\xd9\x67\x27\x6b\x79\x36\x7b\x5a\x90\x67\xb3\x53\x83"
+  "\x78\x67\x67\xa8\xe0\x3e\xc4\xe7\x25\x2a\x38\xeb\xc5\x74\x53\xe8"
+  "\xca\xec\xaa\x90\xba\x1a\x54\x38\x0e\xa8\xea\x6a\x54\xc1\x75\xe0"
+  "\x73\x4b\x64\xf9\xcc\xee\x8a\x2c\x9f\x7b\x20\xbc\x7c\xee\x31\x05"
+  "\xeb\xbd\x27\xf9\xe2\x76\x75\x4f\xba\x8a\x9e\x7a\x7c\xce\xd6\xda"
+  "\xd1\x3d\xd6\x90\xe7\x41\xf9\x33\xf4\x1d\xfb\x36\xa7\x46\x53\x7a"
+  "\xc1\x38\x30\x0a\x3b\xbb\xa7\x46\x9d\xff\x6e\xbf\xc8\x27\x1a\xf9"
+  "\x3b\x38\x7a\xbf\x29\xe0\x1c\xa1\x70\x04\xa3\xca\x77\x29\xb4\x6f"
+  "\x8b\x70\x96\xb7\xd2\xff\x39\x03\xd4\xff\xdd\xe3\x13\xef\x6d\x3e"
+  "\x39\xc4\xec\xef\x67\x47\xea\xcb\xfa\xec\x73\x66\xe0\x98\xc1\x2d"
+  "\xf8\x33\x07\xf5\xff\x71\x1e\x9b\xb0\xf2\x4f\x0e\xa1\x3e\xf5\x9f"
+  "\x84\x39\x9f\xe2\xef\x00\xfe\xfe\x46\xdb\xbf\xce\x59\xc2\xec\xba"
+  "\x85\xf5\xf6\xd0\x7e\x77\x4e\x01\x8e\x3d\xfa\x13\x7c\x65\xd9\x61"
+  "\xf2\xaa\x98\x3d\xea\xd1\x30\xe9\x74\x56\x7e\xbf\x0b\xe6\x1c\x27"
+  "\x7a\x55\xe9\x0e\x66\x1f\xb3\x88\xe0\x5d\x54\x1f\x96\x89\x24\x37"
+  "\x65\xff\x8f\xd0\xbd\xd4\xb8\x90\x76\x9c\x3f\x09\xa9\xdb\x45\x3b"
+  "\x52\x3f\xd7\xd6\x9d\x9a\x1c\xbe\x1d\xa9\xb3\xb0\x1d\xe7\xc3\xb7"
+  "\x23\x95\x7f\x13\x9a\x49\xd8\x96\x21\x71\x47\x6a\x01\xb6\xe5\x3c"
+  "\xe7\xbb\x36\xbd\x52\x19\xa7\xda\xce\xe3\xf8\x5f\x02\x5e\x76\x61"
+  "\x71\x50\x6e\x32\xdc\xa1\x84\x1a\xc8\x0a\x53\x67\x2b\xb3\x8f\x5e"
+  "\xe8\x82\x7b\xf5\x4a\x7f\x25\xa7\x77\x09\x5a\x90\x4f\x12\xf1\x09"
+  "\xdb\x83\xe5\x22\xc9\x5b\xb1\x4f\xf1\x9e\xe9\x5e\xb4\xff\x39\xdd"
+  "\x4a\x9f\x8e\xfd\xb9\x5b\xe1\x23\xe6\x65\x85\xe4\x79\x55\x79\xb9"
+  "\x9a\xbc\x92\xc1\xf4\x6d\x4a\xfa\xf0\xe4\x74\xef\xa1\x10\x39\xa1"
+  "\x7c\xee\x9b\xab\x6d\xf7\xbd\xcd\xa2\x7d\x28\xa3\x21\xbc\xbe\xd7"
+  "\x85\x32\x1a\x08\x2f\xa3\x7b\x7d\xe1\x75\xed\x3e\xfe\x3d\x27\x36"
+  "\x16\xc2\xe0\xbb\x8f\xf6\x8c\x0d\x70\x1d\x94\xe5\x34\x54\x3e\xf7"
+  "\x2d\x52\xe4\x33\xbc\x36\xde\x57\x13\xd2\x46\xff\x49\xb8\xff\x4a"
+  "\xd1\xd6\xfb\x57\x85\xe0\x3e\x18\x5e\x17\xef\x6b\xc1\x76\xfa\xc3"
+  "\xb7\xf3\xbe\xae\xc8\xba\x78\x3f\xbd\x0f\xf1\x0f\xd5\xc5\xfb\x4d"
+  "\xa2\x0c\x84\x2b\x33\x8d\xd9\xc3\xd5\x73\x7f\x06\xc5\x45\x2e\xb8"
+  "\x7f\x1b\xbd\xa7\x53\xa5\xe7\x68\xf5\x0f\xdb\x40\xe5\x88\x7f\x3e"
+  "\x31\x8e\x21\x39\x9c\x34\x83\x74\x31\x9d\xec\xb3\xdf\xdf\x1c\xc2"
+  "\xab\xb3\x27\x21\x6d\x6e\xaf\x24\x3d\x20\xf8\x35\x37\x26\x84\x26"
+  "\x57\x78\x7e\xdd\xef\x45\x7e\x9d\x0d\xcf\xaf\xb4\xc4\xc8\xfc\x4a"
+  "\x23\xf9\x9f\x1d\xca\xaf\xb4\x74\x35\xbf\xe8\x9b\xaa\xd4\xbe\xef"
+  "\x9b\x50\x37\x06\x96\xb1\x7a\xe1\xcb\x8d\x09\xa8\x2b\xa2\x4c\x0f"
+  "\x95\x29\x4e\xf0\x0a\x3d\x31\x5f\x0b\x86\x33\x90\x96\xa3\xd8\xff"
+  "\x98\x1a\x18\xcd\x06\x16\xd3\x5a\x6d\xfa\x46\x83\xd1\x59\x74\xd6"
+  "\x41\xdf\x72\xa4\xf9\xc6\x90\x7a\x1d\xe1\x7d\x41\x1a\xc6\xfc\x51"
+  "\xaf\x85\x49\x77\x8b\x39\xd3\xb9\x16\xad\x8f\x98\x6b\xd0\xca\x08"
+  "\xf9\x26\xf1\xd3\xc8\x75\xc3\xb9\x2e\x2c\xb3\xb9\x45\x43\x65\xf6"
+  "\xc0\x35\xb2\xbc\xce\x6b\xe9\x9b\x5b\x15\x5e\x5e\x73\xf7\x47\x96"
+  "\xd7\xdc\xe6\xc8\xf2\x9a\xeb\x22\x79\xb9\xe0\x01\x93\xb6\xdf\x98"
+  "\xeb\xd5\xb6\x17\xeb\xc5\x72\x4c\x1a\x75\x05\x3d\x0f\xb7\xdd\xca"
+  "\x45\x3e\x8e\x64\x55\x8f\xf1\x15\xd2\x3f\x8e\x68\x1c\x29\x8e\x88"
+  "\xb8\x91\x87\x55\x9b\x23\x7e\xf7\x23\xae\x1d\xc7\x95\xb4\x3e\x8f"
+  "\x7f\x97\x19\x1e\x38\x1d\x90\x74\x33\xf1\x5e\x3a\x09\xe9\xbf\x0a"
+  "\x48\x51\x65\xb4\x96\x8c\xef\x9f\xe3\xef\x27\x1e\xd4\xab\x65\x41"
+  "\x6b\xca\x68\x2e\x7a\xa7\x98\xe7\xfc\xec\x24\x3c\xb8\x43\xc8\x25"
+  "\x7d\x8f\x96\x8f\x0f\x5a\xc2\xcb\xe5\xc1\x54\x94\xcb\x67\xe1\xe5"
+  "\xf2\xe0\x92\xc8\x72\x79\xb0\x08\xe5\xf2\xd9\x50\x3b\x7a\xb0\x4a"
+  "\xb6\xa3\x17\xa8\x8c\x79\x1d\xc5\xab\xe9\xf4\x9c\x80\xf7\x68\x23"
+  "\x0f\xf2\xef\x3e\x4e\xec\x51\xec\x88\x97\xa1\xf1\x3f\xaf\x5f\x86"
+  "\x71\xc8\x38\xd4\x78\xbb\x13\x7a\xc2\xd9\x49\x3a\x5f\x33\x30\x29"
+  "\x0f\x0c\xc8\xc3\xec\xbd\x84\x23\x1f\xe0\x0c\xa4\x3f\x46\x70\x94"
+  "\x4e\xdf\x50\x50\xc1\xa7\x28\x70\x7c\x5e\x54\xc0\x5a\x58\x9f\x95"
+  "\x7f\x1b\x2a\x04\xb7\xdc\xfe\xd1\xbc\x1f\x21\x78\x82\x0b\x81\x29"
+  "\x13\xf6\x98\xde\xac\xb5\xc7\xf4\x1a\xad\x7e\x3e\x48\xef\x27\x12"
+  "\x02\xe8\xe7\x50\x97\x7b\xfc\x76\xdd\xcc\x6f\xc6\x36\xe7\x25\x86"
+  "\xd8\x26\xea\xc0\xbc\x5f\x0a\x1d\x98\xf7\x86\x96\xd6\x79\x13\xc2"
+  "\xeb\xc0\xbc\xb4\xc8\x3a\x30\x6f\x79\x64\x1d\x98\x57\x4c\x3a\xe0"
+  "\x82\x79\x87\xb4\xb6\x39\xaf\x5a\xdb\x76\xac\x97\xdb\x26\x5c\x3e"
+  "\x12\xdb\xc4\x58\xe8\x8a\x48\x76\x28\xc7\xff\x3a\xfa\x0e\xda\x08"
+  "\x78\x26\xbe\xeb\x03\x0f\xa5\xd3\x3b\x24\xf4\xf1\x56\xe2\x61\x1d"
+  "\x1f\xa3\x3d\xb4\x44\xcd\xc7\x9d\x62\xac\x65\x43\xd8\x13\xb4\x66"
+  "\x4f\xf0\xf3\xe1\x77\xb4\xed\x7f\xa8\x38\x3c\x3f\x1f\xaa\x46\x7e"
+  "\xda\xc2\xf3\xf3\xa1\x83\x91\xf9\xf9\x50\x2b\xed\xd1\x1e\x6a\x53"
+  "\x0f\xd1\x77\xda\x0d\x4a\xdf\x74\x06\x1e\x9e\x3d\xbc\xfe\xe9\xe1"
+  "\x24\x6d\xff\xf4\xb0\x7e\xe4\xfd\xd3\xc3\xcb\xc3\xf7\x4f\x0f\x17"
+  "\x85\xef\x9f\x1e\xae\x12\xf6\xf0\x70\x8b\xd6\x1e\x1e\xde\xaf\xd5"
+  "\x09\xe4\xdd\x37\xd6\x3f\x65\x98\x42\x6c\x60\xd7\x49\xc8\xd8\x83"
+  "\x31\xc5\x8b\x42\x6e\xf3\x9f\xd2\xd2\x98\x31\x2d\xbc\xdc\x32\x32"
+  "\x50\x6e\xbb\xc2\xcb\x2d\xc3\x1a\x59\x6e\x19\xdb\x50\x6e\xbb\x86"
+  "\xca\x2d\xa3\x76\xe4\x31\x45\xc6\x51\xad\xcc\x32\x1a\x47\x2e\xb3"
+  "\xf9\x89\xe1\x65\x36\x7f\x42\x78\x99\xcd\x4f\x13\x32\x9b\x5f\xac"
+  "\x95\xd9\xfc\x25\x5a\x99\x21\xdf\xbe\x31\x99\xcd\x6f\x0d\x91\xd9"
+  "\xfa\x93\xb0\x60\x3e\xca\xec\xa8\x90\x59\xe6\xe5\x21\x34\x76\x87"
+  "\x97\xd9\x02\x1c\x30\xc2\xfa\xf0\x32\x5b\x90\x14\x59\x66\x0b\x66"
+  "\xa0\xcc\xd6\x0f\x95\xd9\x82\xac\x91\xcb\x6c\xc1\x36\xad\xcc\x16"
+  "\xe4\x8e\x5c\x66\x0b\x5a\xc2\xcb\x6c\x81\x2b\xbc\xcc\x16\x78\x85"
+  "\xcc\x32\x53\xb4\x32\xcb\x34\x6a\x65\x86\x7c\xfb\x3b\x65\x86\xf2"
+  "\x69\x14\xeb\x75\x33\x5f\xed\xe5\x73\xda\x99\xe5\x2e\xc8\xca\x12"
+  "\xef\x04\xb2\xb8\xee\xc8\x32\x7c\x17\x61\x8a\x87\xf6\xdd\x99\xfb"
+  "\xe4\xb4\x1f\x0c\x95\x43\xa6\x03\xfb\xd5\x9e\xe6\x62\xbe\xae\x4b"
+  "\xc8\x90\x78\x8e\x70\x62\x8e\x2c\xd3\x45\x65\x51\xc6\xcc\xe9\xf5"
+  "\x01\xf5\xc5\x08\xef\x21\x3c\x74\x9e\x88\x16\x57\x56\xdc\x48\xe2"
+  "\xb2\xc8\x6b\xcc\x3f\x69\x74\x94\x4e\x45\x7c\x8f\x8c\x13\xba\x9a"
+  "\x15\x1a\xff\xd6\x63\x5d\xe7\x84\x9e\x3e\x1a\x32\x67\x92\x15\x21"
+  "\xfe\xcd\xa2\xf8\xb7\x3e\xbc\x9e\x66\x5d\x20\xfe\xcd\xa2\xf8\xb7"
+  "\x5e\x35\x5e\x1d\xbb\xd4\xe7\x0a\x19\xaf\x3e\xa2\x4f\xf0\x08\xdd"
+  "\xe1\x71\xec\xf6\x4f\x1a\xfb\xec\x8f\x4c\x08\xa1\x19\x65\xf3\xc8"
+  "\x3b\x32\xcd\x3f\x0a\x29\x9f\x16\x9e\xe6\x47\x96\x20\xcd\xef\x86"
+  "\xa7\xf9\x91\xa2\xc8\x34\x3f\x52\x8d\x34\xbf\x3b\xd4\xb6\x1e\x39"
+  "\x20\xeb\x41\x98\x71\xf9\x23\x2d\xe1\xe5\xff\x48\x88\xfc\x21\xbb"
+  "\xa0\x98\xb9\x79\x79\x0d\xdc\xa3\x06\x35\x1c\xad\xd5\x27\x58\xd2"
+  "\x91\x30\xb0\xd3\x42\x71\x46\x80\x5b\x32\x44\xf7\x68\x6f\x41\x58"
+  "\xdd\x7b\xb4\x5c\xd8\xe3\xa3\x2e\xad\x3d\x3e\xda\xa0\xb5\x47\xe4"
+  "\xb5\xb6\x9c\x43\x9b\x9f\x55\xf5\xcd\xf9\xd8\x85\x29\x21\x3a\xf0"
+  "\xfe\x49\x58\xf8\x33\xa1\x03\x8b\xa2\xb5\x74\x2c\x4c\x0f\xaf\x03"
+  "\x0b\x97\x63\xfb\xdf\x0f\xaf\x03\x0b\x8b\x23\xeb\xc0\x42\x5a\xcb"
+  "\xfc\xbe\x5a\x6f\x17\x16\xa7\x8e\x0e\x81\x39\x1c\xde\xe7\x2d\x3c"
+  "\x16\x7e\x5e\x67\x61\x8f\xe0\xf1\xa2\x64\x2d\x8f\x17\xe9\xb5\x3c"
+  "\xc4\xb6\xfc\xfd\x3c\x1c\x3c\xd7\xab\xcf\xbe\x28\xd4\xfe\x9d\x58"
+  "\xa7\x6c\xff\x8f\x9d\xd6\xd2\xb8\x48\x1e\xff\x84\x9b\xcb\x5a\x74"
+  "\x00\x79\xe9\x0c\xcf\xcb\x45\x2d\xe1\xdb\xbc\xc8\x85\x7d\x90\x33"
+  "\x30\xc4\x96\x16\x79\x31\x7d\x21\xff\x36\xe3\x79\x30\xd6\x61\xfa"
+  "\x42\x1f\x18\x78\x7f\x35\xd8\x2f\x3d\x46\xfb\x0e\x18\x9f\x63\x46"
+  "\xfd\x4d\x48\x82\x2c\xea\x83\x88\xae\x65\xc5\xa1\xef\x44\x1f\xe3"
+  "\xf3\x1f\xb4\x8e\x85\xf6\xd5\x24\x14\x41\x96\xd3\xe3\x03\x45\xdf"
+  "\x09\x3e\x04\x77\x11\xd9\x05\xc1\x2b\xb0\x62\xae\xb3\x2c\xc4\x37"
+  "\x3d\xd6\x10\x5e\xc6\x8f\x35\x46\xd6\x9d\xc7\x8e\x09\x39\x3f\x6e"
+  "\xd0\xca\xf9\xb1\x9e\x80\x7d\xcc\x22\x6a\x2b\xea\xc0\x88\xec\x84"
+  "\xde\x9d\x46\xf4\xf7\x2f\x2c\xee\xc8\x2b\x85\xeb\x4f\xc1\xe3\x79"
+  "\xbc\x3e\x89\x79\x13\xb6\xea\xa0\x99\xfb\x80\xc7\x8f\x70\x3a\x11"
+  "\x66\x99\x0f\x24\xf6\xc2\xb3\x1d\x94\x57\x6f\x67\x5e\xfe\xed\x49"
+  "\x3b\x3b\x4a\xe7\xf1\xa0\x2e\x5c\xd1\x09\x8f\x6f\xd7\x94\x47\xad"
+  "\x74\x0a\x1c\xcd\x62\x7e\xff\x71\x87\x32\x0f\x1f\x69\x7e\x1f\x61"
+  "\xba\x94\x75\xbf\xe2\x5d\xd8\xe3\x1d\x11\xfb\x65\xa4\x89\xf6\x90"
+  "\x13\x4d\x17\xf6\x03\x3f\x98\xa1\xe8\xaf\x78\x37\xf7\x83\xf4\xe0"
+  "\xde\x96\x1f\x2c\xc2\x3c\xdf\x05\xe6\x73\x55\x76\xf0\x83\x32\x35"
+  "\x1e\x71\xb6\xdd\x0f\xaa\x95\xfd\x29\x78\xdf\x70\x11\x5c\x0a\x3d"
+  "\x2d\x21\xf4\xa0\x3c\x1f\xf6\xc9\x38\xba\x2e\x82\x23\xd1\xb9\x6f"
+  "\x26\x4c\x0a\x40\xd4\x29\x78\x72\x4a\x35\xad\xd1\xa9\xed\x86\x38"
+  "\x1f\xe8\xc5\xd8\x2e\xfb\x2e\xda\x1b\x42\x63\x43\xa7\x6f\x8e\x83"
+  "\xde\xc1\xf1\x35\x04\xa6\x39\x8e\xb6\x22\xbf\x7c\xf6\x58\xf6\x3c"
+  "\xe2\x69\x9b\xf5\xac\xa3\x76\x37\xeb\xde\xcb\xcf\x9c\xca\xd6\x8c"
+  "\xff\x2a\x69\xfd\x0f\xad\xc3\x28\x85\x39\x08\x7f\x42\xd8\xfa\x93"
+  "\x21\x31\x69\x76\x84\xf1\x5f\x36\x8d\xff\xe6\x84\xb7\xf3\xec\x0b"
+  "\x8c\xff\xb2\x69\xfc\x37\x47\xdd\x6f\x8a\xf7\x3c\xd9\x5d\xea\x98"
+  "\x94\xce\x85\x32\xaf\xa6\x38\xf3\x89\x27\x6e\xab\x06\xa3\x8f\xde"
+  "\x69\xa3\x6d\x3a\xbb\x9b\xc9\x5e\x8d\x6d\xee\x46\x3a\x8f\xc1\x40"
+  "\xdf\xcc\x16\x7d\x19\xd9\xeb\x13\x7c\xbe\x30\xc1\x27\x6c\xd1\x56"
+  "\xc4\xdc\x13\xba\x50\x87\xd6\x5b\x15\x5c\x89\x25\x56\xb1\xef\x63"
+  "\x4c\x17\x8c\x76\x76\xf3\x7e\x51\x47\xf1\x2a\x8f\x5b\x7d\xe7\x80"
+  "\xf0\x36\x15\xb7\x01\xe1\x0d\x0c\xf6\x93\x1c\xf7\x36\xb2\x71\xc2"
+  "\x49\xb8\xdb\x11\x8e\xf0\x12\x9c\xd2\x0e\xb1\x37\xe6\x89\x03\xea"
+  "\xb6\xf3\xf9\x17\xac\x1b\xd3\xff\x4a\xf3\x2a\x4e\x2a\x67\x5b\xcc"
+  "\x26\x75\xd1\x3b\xb3\xb3\x0e\x66\x7b\x96\x4d\xca\xa7\x39\xb1\x27"
+  "\xef\xa2\x72\xef\xfe\xc5\x15\x5d\x30\x0e\x0c\x22\xed\x09\x4f\xb3"
+  "\xd9\x0b\x2e\x78\x72\x86\xd6\x47\x3c\x19\x12\xff\x66\xf3\x71\x26"
+  "\xfe\xc6\xd1\xfa\x44\x79\xfd\x2a\xf9\x03\xe6\xf4\xf5\x71\xfd\xb8"
+  "\xd0\x9a\x0a\x7a\x27\x4d\x6b\xa2\xc4\xb9\x67\x4f\x96\x85\xcc\xbd"
+  "\xb9\x77\xf2\x75\x35\x7f\xc6\x7a\x17\xc7\x0b\x1d\x59\x12\xaf\x95"
+  "\xe9\x93\x0d\xb6\xd3\xf4\x2e\x48\xf4\x07\x4b\x7d\xa1\xfe\xf1\x49"
+  "\x87\x12\xbb\x85\xa4\x77\x28\xfd\x81\x79\x1d\xe1\x5d\x1c\xd2\xcf"
+  "\x3c\xc9\xe3\x7f\xff\x90\x7e\x61\x31\xed\xa3\xd2\xe8\x64\x3b\xd7"
+  "\xa1\xc5\x96\x36\x0f\xea\x4d\x3e\xe9\xff\xe2\x1f\x21\xcc\x56\xda"
+  "\x73\x88\xcf\xa3\xcf\xc0\xe2\x6c\xbf\x1d\x0c\x6d\x6e\xbe\xa7\xca"
+  "\x88\x3a\xc2\xf5\x96\xfa\x8d\xc9\x62\x3d\x92\x27\xa4\x8e\x02\x85"
+  "\xe7\x04\xd3\x9e\xff\x67\x10\xeb\x29\x48\x17\x16\xa7\xd3\xda\x8c"
+  "\x31\x3d\x30\x9a\x70\x29\x3a\xe4\xf4\x75\x40\xbb\x2f\x74\xcc\xb3"
+  "\xf8\x70\xf8\xb6\x2f\xa6\xfe\xff\x35\x17\x2c\x99\xa0\x95\xed\x62"
+  "\xde\xff\x2b\xef\x75\x50\xf6\x5e\x6d\xb9\x25\x71\x5a\xd9\x3f\xd9"
+  "\x40\xf9\x11\xd7\xf8\x94\x7f\x72\x18\xc7\x33\xcb\x3c\x7c\xbd\xd7"
+  "\x12\xb4\xff\x27\x97\x5c\xc8\x0f\x32\xc3\x27\x87\x03\x08\x2b\xaf"
+  "\x0b\x46\xbf\xb5\xa4\x4a\x33\x67\x74\x15\x9f\x33\x5a\x76\x12\x9e"
+  "\x92\xdf\xfd\x3c\xf5\x49\x08\x7d\x07\x22\xc7\x06\x4b\xe8\xfd\xcf"
+  "\xb2\xf0\x3e\x63\x49\x57\xf8\xd8\x60\x89\x4f\xf6\x0b\xcb\x58\x4c"
+  "\xa8\x1e\x3c\x65\x42\x19\xf3\x32\xca\x18\x96\xe6\x42\x23\x8f\x61"
+  "\x9f\x4a\x1f\x1c\xc3\xe6\x93\x3f\x78\x2a\x65\x70\x0c\xeb\x0e\x37"
+  "\x86\x75\x85\x91\xe7\x53\x95\xe1\xe5\xf9\xd4\xbe\xf0\x63\xd8\xa7"
+  "\x0e\x8b\x7e\xfe\x29\xb7\x56\xce\x4f\x1d\x0b\xbe\x13\x5e\x72\xe0"
+  "\x9b\x8b\x87\x97\xa6\x0e\x8d\x87\x97\xbe\x27\x64\xb5\xd4\xaf\xa5"
+  "\x6d\x69\x76\x78\xdf\xbe\x34\x2f\x72\x3c\xbc\xb4\x32\xb2\x6f\x5f"
+  "\xba\x7f\x68\x3c\x6c\x1e\x15\x02\xd3\x3a\x18\x2b\x69\x62\xb3\xa5"
+  "\x5d\x82\x4f\xcb\x28\x9e\x8b\x52\xc1\xfb\xb4\xfa\x8e\x34\x23\x3e"
+  "\xf4\x6d\xa7\xc8\xa7\x29\x3a\x13\x89\x27\x74\x36\xd3\xf7\xab\x21"
+  "\x06\x6d\xe0\xfd\x3e\xfb\xb2\x41\xfd\xa7\x75\x7c\x54\x0f\xf9\xc8"
+  "\x88\xeb\xe9\x24\x85\x3e\xa2\x63\xd9\xb6\x0b\xbd\x2f\x8d\x32\x41"
+  "\xd6\xeb\x43\xf8\xb1\x8c\xc7\x7f\x84\xe3\xc2\x32\x5b\xe6\x09\xb1"
+  "\x31\x8f\x58\x87\xbb\xfc\x37\x42\x6e\xcb\x43\xc6\xb2\xcb\x8d\x7c"
+  "\x4f\x5f\x44\x7f\xbb\x3c\x25\xbc\x8e\x2e\x4f\x1f\xf4\xb7\xf9\x1c"
+  "\xef\xd6\x90\x7c\xab\x90\xc1\x72\x47\x20\x46\x3d\xd7\xbd\xbc\x4c"
+  "\xeb\x93\x96\x5b\x43\xca\x85\x8c\xff\x96\x93\x4f\x8c\xb4\xc6\x21"
+  "\xa4\xbf\x59\xee\x8e\xdc\xdf\xac\x28\x11\xed\x5f\x19\xf2\x7e\x79"
+  "\x85\xf1\xc2\xfd\xcd\x8a\x08\xed\x5f\x91\xae\xed\x6f\x56\x86\xbc"
+  "\xa3\x5f\x61\x0d\xdf\xdf\xac\x28\x53\xfc\x8c\xf0\x1b\x2b\xfe\x34"
+  "\x3c\x7f\xb3\xa2\x51\xeb\x6f\x56\x34\x5c\xcc\xdf\x34\x0d\xf1\x37"
+  "\x2b\x7c\x09\xb5\xe1\xda\xb2\x32\x31\xbc\xbf\x59\x39\x41\xc8\x70"
+  "\xe5\x36\xad\xbf\x59\x99\xa6\x95\xe1\x8a\x10\x19\xae\x0c\x79\xff"
+  "\xbd\xc2\x78\xa9\x3e\x29\x2a\x2a\x4a\x8a\xd2\x49\xba\x28\xa0\x8f"
+  "\x43\xe9\x60\x74\x94\x3e\x2a\x1a\xaf\x51\xf2\xef\x68\x29\x4a\xd2"
+  "\xe3\x15\x2d\xff\x8e\x0a\x79\x1e\x4d\x65\xf1\xd2\xcb\xbf\xd1\x21"
+  "\xcf\xa3\x2e\x92\x3f\x5a\xae\x57\xa9\x5f\x1f\xf2\x1c\x7d\x91\xfc"
+  "\x51\x7f\x67\x79\x18\xf2\xac\xdd\x07\x39\x6f\xdd\xc6\x15\xb9\x6b"
+  "\x72\xf8\xba\xf6\x55\xe6\x15\x4f\x3f\xbd\x6a\xc3\x06\x73\xc1\x7a"
+  "\xf3\x7d\xf7\x3e\x3a\x75\xa6\x59\x2c\x8f\xcf\x9d\x3d\x3e\x27\x16"
+  "\xe6\x17\xe6\x53\xc6\xfc\x85\xf3\xb2\xcd\x59\xf7\xdd\xab\xcd\x54"
+  "\xd0\xf0\x65\xf0\x17\xc2\xa2\xb2\xbd\xd4\xed\x57\x01\x54\x5e\xc5"
+  "\xfd\x4e\x17\xed\x3d\x17\xe3\x09\xeb\xef\x5b\xf7\xe1\x78\xa2\xdf"
+  "\xc6\x68\x5f\x45\x27\xe4\xbc\x48\x8d\x98\xd8\x50\x06\x79\xab\xe9"
+  "\x3c\x95\x9c\x1f\xb1\x5f\xbb\xc1\xfc\x10\x48\x9d\xb0\xf6\x44\x33"
+  "\x8e\xa2\xe9\xd9\xd9\xe5\x03\xb3\x8d\x62\x5b\xeb\x56\xcc\xd3\xb1"
+  "\x7b\x02\x98\xe6\x91\xf7\xe7\xff\xf0\x55\x9e\xf6\xeb\x32\x05\x2e"
+  "\xe1\x24\xac\x9a\xcb\x7e\xcd\xf8\x33\x9d\x5b\x23\xe0\x56\x5d\x13"
+  "\xb0\x3f\xdd\x41\x7e\xa1\xf6\x35\xd0\xd7\xbd\x06\xb0\x67\x2c\x18"
+  "\xf6\x5c\x45\x67\xcd\xae\x8a\x53\xd6\x65\x6f\xc7\x67\x17\xac\x75"
+  "\x51\xdd\x04\x1b\x90\x72\x24\x0e\x3f\x56\x03\x3f\x2b\xb8\x8e\x7b"
+  "\x55\x9c\x84\x70\x99\x9f\x43\x82\x37\xf6\x63\xb7\xb3\xb8\x0c\x12"
+  "\xfc\xec\xcb\x49\xe9\xa0\x6b\x47\xcb\xd8\xe4\x63\x3e\x47\xfe\x29"
+  "\xaa\x7f\x7b\xc2\x26\xf6\xa5\x13\xe3\xc6\xf9\x3d\x36\xb6\xf3\x34"
+  "\xe8\xd1\xa6\x75\x8e\x7c\xda\x4f\xb1\x2a\xaf\xee\x3c\xe8\x91\x07"
+  "\x49\xa7\x60\x75\x43\xf1\x7c\xe6\xb7\xcd\x07\xfd\x47\x45\xb4\xe7"
+  "\xf5\x8f\xb1\x3b\xff\x0d\xf4\xff\xdc\x5f\x26\xf5\x33\x13\x14\x17"
+  "\xb0\x6e\x46\x67\x50\x7b\x98\x97\xd6\xdc\xb6\x2e\xf7\x23\xcc\x1f"
+  "\xfa\xfb\x6c\x26\x68\x2f\xf0\x40\xc9\x71\xe6\x2d\xff\x37\x71\x66"
+  "\x45\x5b\x8f\x87\xf6\xd0\x1a\x4a\xe6\x43\xd4\xc9\x6c\x90\xda\xac"
+  "\x35\xe0\x5c\xe2\x81\xe2\xe3\xac\xbb\x75\xf9\xe7\xd0\x6e\x3d\x08"
+  "\xcb\x3a\x40\x6a\xed\xfa\x14\xf8\x39\xca\x3b\xc7\xa4\x96\x9e\x03"
+  "\x53\xc9\x1a\x4a\x3b\x07\x9b\x4b\x20\x7e\xf3\x27\x34\x16\xea\xc0"
+  "\x7a\x4e\xc3\x93\xc7\x40\x87\xf8\xa4\x2d\x9f\x82\x69\xcb\x13\xb4"
+  "\xd7\x3c\x15\x6a\x4b\xc1\xc4\x6c\x96\xb8\x7e\x9b\xc5\xd8\xcf\x2c"
+  "\x63\xfb\x6c\x96\xc4\xf6\x3c\x84\xef\x7a\x0f\xc6\x74\x40\xe2\xaf"
+  "\x4f\x75\x48\x35\x5f\x41\x92\x79\x01\xc9\x7f\x75\x6d\xed\x57\x08"
+  "\x5f\xf1\x1f\xee\x00\x96\x55\x97\xf1\xc5\x74\x19\x9c\xd9\x5e\x08"
+  "\x20\xae\x9a\x7e\x48\xaa\xed\x07\x53\x60\xfb\x7f\xb8\x89\x17\x03"
+  "\x15\xff\x4e\xe7\xfe\x8e\x7e\x77\x65\xa3\xde\xd9\xda\x03\x6d\x9e"
+  "\x7e\x68\x87\x3f\x83\xb3\xe8\x0b\xc7\x3f\xaf\x6c\x8c\xc6\x38\x52"
+  "\xe7\xd8\x4c\x6b\xdf\x85\xce\xd8\xda\xe8\xfc\xbc\x32\xd8\x55\x0a"
+  "\x71\x79\x9b\x61\xf4\x29\x4c\xe7\x3e\xa7\xfc\x03\xe4\xd9\x17\x8e"
+  "\xcd\x7c\x1f\xf8\x5a\x57\x69\x1b\x44\xb5\x7b\x6a\x68\xbf\xb1\xe4"
+  "\x1f\x33\x26\xd5\xe9\x39\x0a\xce\xbc\xcf\x1c\x81\xb8\x31\x96\xca"
+  "\x00\x18\x7e\xf6\xf5\x51\xc9\xa9\xff\x1a\x9c\xd9\x1e\x78\x1f\xeb"
+  "\x66\x3b\xc7\x64\xa0\xaf\x4a\x6d\xf7\x78\xe9\xdc\x9d\x14\xd6\x6b"
+  "\x8a\xdd\x95\x0f\x13\xea\xbe\x82\xe4\xbd\x5f\x81\x85\xf5\x59\x24"
+  "\xda\xdb\x4d\xe7\xa5\xed\xc5\xdf\x38\x1c\x7b\x61\x7b\xf9\x1e\x6f"
+  "\x16\x2f\xef\xf1\x1e\xb0\x40\x7d\x7f\x70\x8f\x77\x7f\x6f\x70\x8f"
+  "\x37\xea\x92\x91\xf6\x79\xa3\x5d\xb4\x90\x3e\xef\x3a\x03\xfa\x17"
+  "\xce\x00\x4c\x2a\x93\xc0\xbc\x92\xce\xfa\xb0\x3e\xef\xcc\x39\xcd"
+  "\xef\x3b\xc1\x3a\x01\x7f\xe3\xf0\xc2\xf1\x9b\x75\x1c\xb5\xaf\x4b"
+  "\xd6\x5b\x4c\x93\x30\xed\x4a\xfc\x8d\xc2\xdf\x78\x5b\x2d\x73\x63"
+  "\x1d\x74\xe6\x4c\x2c\xe9\xaf\xbc\x9f\xbc\xa5\xcf\x6e\xd5\xbb\xe0"
+  "\xd5\xc3\x8a\x1e\x0b\x7f\xbe\xca\xf8\xfe\xc9\xd3\x74\xae\xb9\x9b"
+  "\xd3\x33\x60\xd5\xd1\x19\xe7\x72\x3a\xd1\xb0\x96\xea\xc5\xfa\xb3"
+  "\xf0\x37\x01\x2f\xb4\xcb\x1f\x76\x29\x65\x7b\x07\xac\x54\xe7\x2a"
+  "\x4c\x67\x4a\x3a\xb6\x57\x4f\x79\xff\xe3\xe4\x69\x49\xc0\x58\x24"
+  "\xc4\xe9\x95\xf1\xa3\xad\xe7\x1c\x22\x9b\xee\x95\x12\x58\x53\xce"
+  "\x34\xa8\xbd\x8a\x1d\xdd\xbb\x9b\x35\x0b\x5b\xb3\xee\x77\xc1\xeb"
+  "\xfc\x2c\x73\xec\xb3\x9b\x2b\x31\xaf\xc9\x0c\x40\x7c\x69\x5e\x4e"
+  "\xeb\x49\xad\x2d\x2e\xb8\x2c\x59\xdd\x06\x66\x5f\xd9\x48\xfd\xe6"
+  "\xcf\x4b\x1d\xd1\x4c\x7a\xba\xb1\xdd\xd5\x03\xff\xdc\xdf\x1d\x6d"
+  "\xfb\x1d\x48\x4e\x5f\x27\x4c\x4e\x04\x13\xcd\xc1\xd4\xef\x66\x2e"
+  "\xfc\xed\xc6\xab\x07\xf5\xe4\xba\x53\xb0\xe6\xca\xdb\x12\x21\xf1"
+  "\xe3\x22\x90\xfd\xd1\x9a\x89\x2a\x7f\xf4\xcb\xb6\xae\x46\x95\x2f"
+  "\x5a\xbb\x6a\xa8\x2f\xca\x5d\x21\x7c\x11\xf3\x09\xdf\xe3\x77\xc9"
+  "\xe9\xf3\x43\xd2\xe5\xfd\x2a\xb9\x53\x42\xd2\xbd\x72\xfa\x75\x21"
+  "\xe9\x6e\x91\xfe\xec\x53\x8a\xaf\x6b\x27\x3a\x0a\xc9\xd7\x3d\x7b"
+  "\x2f\xf9\xba\xf6\x1c\xd9\xd7\xf1\xbd\x98\xcf\x8e\x67\xff\x54\x06"
+  "\x74\x8e\xce\x49\x78\xc6\x4f\xf4\xb3\x5f\x83\x42\x7b\x0c\xa6\xbd"
+  "\x47\x69\x55\x7f\x06\x3d\x5e\xdc\xcf\x31\x7b\xce\x0d\xe4\xe7\xc8"
+  "\xc7\xd1\x3e\x98\xb7\xaf\x62\x1d\x6f\xef\x66\xc7\x6a\x77\xb3\xd6"
+  "\x3e\xfb\x33\x13\x14\x7f\xf7\x0a\xa6\x55\x62\xda\x2b\x98\x4f\x7e"
+  "\x8f\x78\xd2\x96\xdd\x48\xe7\x8a\x76\xa1\x8e\x19\x12\x74\x90\xb7"
+  "\x13\x75\x9e\xce\xbb\xda\x86\xfc\x75\x16\x78\xf8\x9e\x13\x7e\x1e"
+  "\xb8\x94\x82\x3e\xaa\x8b\xec\xed\xaa\x17\x02\x34\x2f\xf1\x39\x94"
+  "\x7a\xd8\x29\xda\x9b\x42\x34\x2c\xdb\xf4\x10\x9d\x6f\xad\x6b\xc6"
+  "\xe8\x88\xce\x21\xa0\xbd\x33\xe8\x77\xf5\x55\x48\x93\x38\xdf\xf7"
+  "\x99\x43\x18\xb9\xa4\x0a\x59\xaf\xe5\xe7\xe7\x77\xc2\x1a\x2f\xb3"
+  "\xa3\x2f\xc4\xb6\x25\xf8\xcb\x80\xce\x62\x41\x1b\xa5\x79\x56\xeb"
+  "\xdb\x78\x55\x29\xe7\xb1\xd0\xb7\x14\x10\xc6\xd9\xe1\x05\xa2\xd9"
+  "\x05\xcf\xa4\xb5\x15\x37\x52\xf9\x6e\xe2\x0d\xb3\xdb\x14\x1c\x3a"
+  "\x7e\x9e\x0b\x8e\xe1\xe9\x3c\x17\x84\xe3\x73\x86\x2c\xf6\xdf\xdd"
+  "\x6d\x4b\xdc\x40\x7e\xde\xd9\x8d\x38\x8a\x3b\x05\x0e\xc4\xc5\xd0"
+  "\xef\x6b\xf2\x64\xfc\xf1\x25\xec\x4b\xc4\x7f\x88\xe4\x45\xe7\x72"
+  "\xd1\xba\x24\xe4\x4b\x1c\x9d\xcd\x20\xe2\xce\x67\x66\xd7\xff\x19"
+  "\x40\x3e\x5b\x0c\xf5\xed\x99\x59\x74\x76\x17\x9d\x27\xc6\xcf\x12"
+  "\x93\xa6\x01\x2b\xb4\xc4\x0d\x9e\x27\xf6\x5f\x70\x96\x18\xf2\xdf"
+  "\x54\x27\xb1\x83\x48\xff\x2c\x3a\x4f\x0c\xe9\xaf\x25\x3d\x94\xdb"
+  "\x94\xfa\xc6\x93\x9c\xe7\xdb\x28\x6d\x97\x9d\xb5\x28\xf2\xa7\xf6"
+  "\x52\x5b\x30\xcf\x2a\xe2\x41\x76\xd4\x05\xb9\xa9\x94\x8f\x69\x8b"
+  "\x08\x7e\x32\xfa\x31\x67\x8e\x1f\xde\x3d\xe9\x97\x76\x6d\x06\xbd"
+  "\xf0\x69\x6b\x9f\xa0\xf2\xc2\xa7\xad\x35\x06\x7d\xda\xda\x68\xe1"
+  "\xd3\x04\x8f\x85\x4f\xcb\x3d\x2f\x7c\x5a\xee\x97\x7c\xfd\x10\xfa"
+  "\x34\xca\x23\xbf\xa6\xf8\xb4\xbd\x57\xb1\x16\xf2\x1d\x7d\xf6\x5c"
+  "\x97\xe2\xdb\x76\x60\x1a\xf9\x0e\xa2\x51\xf8\xa9\x67\x67\xb0\xff"
+  "\x63\x01\xb1\x3e\x93\xee\xad\x74\x5e\x46\xb7\x7c\x4f\xfd\xc8\x23"
+  "\xc2\xc7\xad\x9d\x16\xf4\x71\xb9\x8d\xc1\xb2\xe4\xe3\xd6\xce\x13"
+  "\x3e\x4e\xa4\xd7\x3f\x49\x3e\xee\xd9\x19\xc4\x03\x19\xbf\x44\xef"
+  "\xcd\x64\x78\xe2\x63\xaa\xda\xc7\x69\xed\x6b\x6d\xa5\xe2\xe3\xc8"
+  "\xb7\xe1\x73\xad\x0b\x62\x5b\xb8\xbd\x21\x5c\x35\xf2\x5c\xb1\x3b"
+  "\x92\x01\xb5\x99\xce\xc9\x27\xbe\xdd\x7f\x1a\x46\xcb\xe7\xd4\xc8"
+  "\xed\x5e\xdb\xa1\xec\xc9\x44\xfe\xbb\x42\x63\x66\x7c\x1e\x8c\xd3"
+  "\x50\xd6\x37\xd0\x19\x8e\xce\xb2\x4e\x70\xd6\xb0\xb2\x76\xdf\x71"
+  "\x08\xbc\xf0\xec\x09\x92\x2b\x8e\x2f\x46\xd1\x2f\xf9\x9d\x53\xb0"
+  "\xee\x9a\x65\x1e\x3e\x5f\x7f\x62\x97\x84\x79\x45\x70\xb7\x2a\x8f"
+  "\xef\xb1\x57\x95\x9b\xa8\xca\x7b\x84\xf2\x68\x8e\x11\xef\x21\xd2"
+  "\x9c\xc2\x08\xe8\xf8\xd1\x05\xe8\x78\xef\x02\x74\xfc\x89\xd3\x81"
+  "\xf1\x16\x8e\x8f\x2e\x3f\x03\xeb\xe4\xbd\x21\x78\x85\xad\x67\x7d"
+  "\x8c\x9c\x1f\xa5\xca\x57\xd5\xb5\xfe\x96\x30\xe5\x55\xf5\xad\x9f"
+  "\x77\x11\xfc\x6b\x2e\x82\x7f\xfb\x45\xf0\xbf\x43\xbe\x8f\xf6\xfd"
+  "\xf9\xed\x5a\xb8\x49\x3e\x6e\x7b\x2d\x74\x76\x14\xc2\xfd\x5e\x7e"
+  "\xdf\x72\xc2\x36\x8e\x8f\xff\xf8\x79\x41\x3b\x31\x9f\x9f\x93\x8b"
+  "\x7e\x39\x6d\x13\x80\x58\xd3\xa7\x94\xc9\x8b\x0e\xa5\x6d\x8c\x4f"
+  "\xa1\x8d\xe7\x8f\x0f\xa5\x0d\xf3\x27\xaa\xf2\xe7\x06\x65\xbe\xde"
+  "\x71\x81\x79\xa4\x38\x67\x0d\xf0\x6f\xc7\x34\xe1\xb0\x85\xf6\xfa"
+  "\x54\x0f\xbe\x1b\xc9\x43\xfd\x5f\xcb\xdf\xed\xc8\xfb\x8a\x7b\xd0"
+  "\xa7\xdf\x40\xe7\x80\x52\xcc\x2b\xef\x05\xb9\x1a\xfb\x91\xb1\x74"
+  "\x4e\x0c\xcd\xa7\x2f\xf3\x67\x49\x4d\xc5\x64\x3b\x79\x1d\x4a\xd9"
+  "\x48\x73\x8f\x54\xaf\x5c\x27\xdf\x27\xd5\x67\x7f\x2e\x4e\x29\x43"
+  "\xb8\x69\x6f\x10\xfa\xff\x1b\xf8\xf9\x6b\xbe\x1e\xf2\xb7\x57\x63"
+  "\x7c\x3c\x56\xd4\xb3\x1c\x44\x3d\xcf\xa5\xba\x60\x5d\xd1\x85\xf6"
+  "\x61\x45\x6e\xdf\x73\xc5\x23\x6f\x1f\xc8\xed\x7b\xae\xf1\x22\xed"
+  "\xbb\x50\xbd\x9e\x91\xd7\x6b\x94\xeb\xcd\x4f\x19\x39\x5f\xf3\x73"
+  "\x86\xcf\xd7\x14\x99\xaf\xf9\x35\x17\xe1\x6b\xb8\x7a\x5a\x87\x5f"
+  "\x8f\x59\xae\x67\x03\x84\xab\x07\xf8\x5f\xc4\xf3\x84\x0c\xca\xb7"
+  "\x5b\xe8\x3b\x46\xe2\x1b\x0d\x1b\xd2\xd5\xdf\xa8\x12\xdf\x37\xda"
+  "\xb0\x44\xf9\x46\x55\x70\x9f\xd9\x86\x4d\xcb\x1a\x28\x0e\x61\x01"
+  "\x17\x6c\x28\xa6\xb9\xc0\xb4\x12\x71\x7e\xa1\x5c\xa6\xea\x22\xdf"
+  "\xc6\xa2\x33\x7c\xf8\xf9\x1c\x8c\xf1\xb3\x62\x3c\xe2\x1c\xc0\x0d"
+  "\xbf\xa7\x3d\x83\x62\x4d\x11\x3f\xf4\x8b\x70\xe1\x18\x76\x03\x3f"
+  "\xbf\x9d\xce\x96\xef\xb5\xc9\xf0\xd7\x52\x1f\xaa\xc0\x14\x80\x02"
+  "\x13\x76\x4e\xb2\xa2\xd3\xb5\xaf\x34\x45\xb3\xbf\x71\x6e\x7e\xfe"
+  "\xfa\xfc\x99\xe6\x0d\x6b\x57\x4e\xdc\x50\xb0\xa2\xe0\xf9\x0d\x7c"
+  "\x23\x7c\x2c\x60\x82\xb9\x60\xcd\xda\x55\xeb\x9f\x2f\xb0\x14\xae"
+  "\x58\x23\x36\xce\xdf\x82\x80\x6a\x20\xd0\x7c\xd3\xc4\x84\x3e\xe8"
+  "\x28\x93\xf8\x19\x17\x3d\xd4\x26\x3a\xeb\x44\xd9\x17\xdc\x6c\x02"
+  "\xf0\xe0\xf8\x08\x69\xdc\xe7\x82\x1f\xb8\x15\x3e\xd2\xf9\x8b\x18"
+  "\x27\x99\x4e\x41\xc1\x6f\x48\xf6\x99\x18\xf2\xd6\x8b\x73\x2b\xf8"
+  "\xd9\x03\xce\x02\x4c\x68\x07\x83\x63\x23\xcd\xf3\x3e\x3f\x23\x60"
+  "\x2f\xb0\xf0\xf3\x24\x37\xd3\xf8\xfb\xf9\xa7\x94\xb8\x84\xde\x5b"
+  "\x89\xf7\xcc\x37\xcc\xe9\x84\x82\x1d\x54\x2f\xd9\x4d\x1d\xc6\xbf"
+  "\x84\x8b\xd9\x0b\x52\x29\x06\xc6\x67\x43\x9f\xfd\x79\x8b\x12\xfb"
+  "\x22\xbd\x71\x2c\xa6\x13\xe3\x9a\xe7\x97\xfc\xd6\xe8\x06\x79\x2f"
+  "\xb9\xa1\x4e\xec\x1b\xd7\x23\xec\xa2\x41\x58\x3b\x9d\xad\xdc\x79"
+  "\x94\xbe\x7b\x16\x96\xbf\xb1\xae\x83\x81\x81\xec\x68\x75\x9b\x71"
+  "\xcc\x8e\xf2\xd9\x18\x8f\x6d\x4f\x24\x59\xcb\xe7\x9d\x8c\x42\xda"
+  "\xcf\x89\xf3\x9d\x5d\x07\x31\x6d\x14\xfe\xb6\x90\x4c\xe9\x8c\x05"
+  "\xcc\xa3\xb5\x3e\xba\xf6\xe2\xb3\x8e\x26\x53\x27\xea\xf5\xf3\x34"
+  "\x77\x9d\x2c\xf6\xc5\x21\x3c\xd6\xe1\x2c\xeb\x87\x66\x33\x73\xd0"
+  "\x1c\xa0\x0b\x36\x26\x37\x9b\x3d\xc0\xa2\x16\x9f\xa0\x72\x68\x17"
+  "\x26\x5b\x11\xc5\x3e\x98\xce\xf7\xff\x6d\x34\x29\x3c\x2f\x30\xb3"
+  "\xd3\x04\x13\x69\xde\x9a\xfa\xe0\x5d\xbc\x2f\xf9\x0a\x68\x8d\x57"
+  "\x17\x6c\x9c\x15\xea\xef\xc7\xe7\xcc\x34\xe7\xac\x28\x30\xe7\xae"
+  "\x59\xb7\xca\x9c\xb3\x26\xc7\xbc\x6e\x7d\x81\xf9\x87\xeb\x69\x02"
+  "\x89\xa6\x8c\x34\x3a\x11\xa0\xf6\x15\x66\x47\x2b\xef\xc8\x7b\x0b"
+  "\xad\xa3\xb0\xfd\xc8\x93\xc2\x37\x7a\xfb\xac\xa3\xb5\x3c\x29\x94"
+  "\xcf\xe2\xda\x88\xe3\xbf\xe7\x73\xc5\xfe\xc2\xa8\x6e\x7c\xc6\xf6"
+  "\x6f\x4c\xd1\xda\x5e\xe1\x11\x19\xd6\xa3\xc0\x72\xbd\xb8\xf1\xd4"
+  "\x60\xde\x2e\x59\x1f\xeb\xc5\x3e\x68\x7e\xae\x4e\x3d\xdf\x23\x50"
+  "\x68\x89\x58\x86\xce\x12\xdb\x0c\x4f\x9f\x81\xc2\xcb\x99\x7d\xe3"
+  "\x12\x59\x87\x0c\x81\x72\x97\x43\xd6\x1f\xd4\x89\x42\xeb\x50\xfd"
+  "\x29\x6c\x26\xfd\x61\x7d\xd9\x06\xbe\x9e\xc4\xe7\x45\x3f\x85\xcf"
+  "\xd8\x9f\x22\xed\xad\xd4\x0e\x4f\x61\xb6\xc1\xb6\x87\xf7\xd7\x7f"
+  "\xa5\x77\xb3\x4d\x5e\x7e\x16\x54\x0c\xea\x06\xca\xa8\xf0\xb0\x22"
+  "\x23\x05\x3e\xbc\x0d\x73\x7d\xd1\xea\x18\xe7\x67\xd1\x95\x5c\xc7"
+  "\x30\x2e\x40\x9a\x24\x25\x2e\xa0\x3e\xc0\x05\x45\x13\x0a\x4a\x18"
+  "\xeb\xb3\x17\x99\x55\x7a\x70\x26\x9c\x1e\xa0\x6c\x9f\xce\x5d\xff"
+  "\xf4\xb3\x68\xe8\xf9\xab\x0a\x9e\xb6\xd2\xd9\x19\xe4\x07\xf8\xc1"
+  "\x1c\xe3\x73\xcc\xcf\x6f\x58\xf5\x74\x2c\x84\x83\x1a\xcc\x54\xcb"
+  "\xdf\x18\x40\x7d\xed\xed\xcd\x8e\xa6\x3d\x1c\x62\xcf\xc6\xa6\xcf"
+  "\x7b\x37\xe0\xb8\x47\x23\xf7\x4d\x7f\x72\x9a\x52\x30\x4e\x4c\x01"
+  "\x1e\xf3\x23\xcf\xc4\x3a\x84\xcd\xd7\x11\x1f\x7a\x25\x1d\xf6\x07"
+  "\x45\xc7\x15\x1d\xc0\x7b\xd4\xed\xc2\xa3\xc1\x35\x20\x9b\x93\x7a"
+  "\xa5\xe8\xe3\xe4\x7f\xc4\x7a\x93\x53\xe8\x07\x12\xea\x3b\x61\x53"
+  "\x2a\xc9\xb4\x8e\xf7\x27\x9b\x92\x94\x32\x3b\x07\xf7\x51\x6f\xda"
+  "\xa6\xe8\x89\xaa\x4c\x3c\xa5\x89\xf1\x73\xd1\x0c\x92\x39\x13\xb2"
+  "\xd7\x2b\x70\xc8\x57\x56\xcf\xfd\xc8\xa6\xbc\x50\xdf\xf0\x5b\x23"
+  "\xbd\x73\x17\xf4\x70\xfd\x33\xb8\x6a\xf8\xb9\x2c\x18\xe3\x21\xee"
+  "\x12\x79\xfd\xcb\x51\xde\xa7\x17\x21\x2e\xaf\xc0\x85\x75\x2d\x55"
+  "\xea\x62\x31\xae\x9a\x7a\xae\x67\x9b\x8e\x06\xe7\x24\x37\x15\xd3"
+  "\xd8\x9c\xf5\x66\x8f\x42\x79\x1e\xe6\xba\x85\xf7\x05\xd7\x88\x33"
+  "\xe2\x48\xdf\xa8\x9d\xa4\x57\x41\x9d\xda\x6c\x54\xe4\x4d\x6d\xc6"
+  "\x72\xcd\x66\x7e\x8e\xf0\x66\x8b\xc2\xcb\x48\x67\xd9\x70\xbb\x35"
+  "\x20\x2d\x7d\xc2\x76\xf9\xb8\x52\x9c\x5f\x44\xfb\x68\xa2\x90\x46"
+  "\xc7\x49\xd8\x72\x17\xed\x0d\x48\xf0\xd2\x38\xcd\xe5\xa0\xb3\x19"
+  "\xc4\x5e\xf7\xcd\xe5\x88\xbf\x38\xb8\xf7\x7d\x33\xf6\xff\x45\xc5"
+  "\x42\x76\x9b\xf7\xa9\x6c\xcf\x2d\xaf\x37\x18\x4d\x3c\x22\x7f\xe6"
+  "\x2c\x9a\xcb\xed\x55\xec\x2b\xde\x7c\x54\x29\xc7\xcf\x31\xf0\x89"
+  "\x3e\xf1\x0c\x6c\xa6\x79\x1e\x37\xd1\x87\xbc\xce\xa3\xfa\xa9\x7d"
+  "\xd4\xe7\x72\xbd\x31\xd1\xb7\x56\xb6\xc4\x69\x69\xd8\x92\xa4\xe0"
+  "\x12\xb8\xb7\x4c\x50\x9e\xe9\x5c\x33\x17\x14\x37\x36\x27\xa1\x4d"
+  "\x79\x78\x1b\x2e\x6b\xc6\x2e\xb5\xd9\xc3\xe1\x16\x29\x3c\xc4\xf4"
+  "\x32\x7c\xc6\xf8\xa7\xc0\x2a\xde\x39\x75\x1e\x15\xbe\xa8\xf8\x10"
+  "\x9d\x99\x65\x33\xd3\xb9\x87\xb3\x84\xbf\xe1\x67\xf5\xf0\xbc\xe7"
+  "\x64\x9b\x8d\xa1\x3d\x48\x7c\xdd\x8d\xc7\xc7\x7d\x83\x38\xdb\x01"
+  "\xf3\xd1\x46\xfa\xc4\xf7\x9e\x62\x64\xda\x5a\x06\xeb\x40\x9d\x68"
+  "\xe6\xef\x38\xb7\x34\x8a\xb3\x52\x46\x1f\xc5\xfc\x6e\x45\x7e\xdb"
+  "\x76\x63\x1a\xe2\xc4\x72\x86\x66\x7e\x16\x59\xb1\x5e\xa1\x57\xce"
+  "\x93\xb8\x3e\x70\x1e\x14\x0f\xda\x7f\xef\x58\x0e\x9b\xa2\xd4\xc3"
+  "\x61\x11\x8e\xe0\xe9\x9b\x9f\x98\x97\x31\x88\x47\x9c\xd1\x62\xa0"
+  "\x7a\x9a\x1b\x78\x9e\x35\xe8\xab\xb6\xf0\x77\x46\x7c\x5d\x1c\xb6"
+  "\xc3\xbd\xc5\x1a\xc3\x65\x60\x06\xfa\x0e\x89\x9e\xf0\x09\x5d\x2c"
+  "\xae\x55\xca\x44\xe9\x88\x8f\xc5\x07\x94\xba\x15\x1c\x44\xff\x05"
+  "\x7d\x9e\x68\x8b\x9e\x6c\x84\x60\x09\x2f\xd7\x09\xfe\x8d\xaf\x92"
+  "\xe9\x5c\x07\x79\x3b\x4b\x0c\x6a\x59\x8b\x58\xac\x24\x49\xa5\x0f"
+  "\x48\x4f\xc9\xa0\xfc\x5d\x50\xb2\x44\xf4\x25\x25\xa9\x2a\x1a\x53"
+  "\xf1\x39\x6b\x50\x0e\x15\x5c\x46\xf4\xdd\xa7\xb0\xdf\x51\xe4\xb6"
+  "\x82\x30\x01\xc6\xe9\x24\x79\xe0\x58\x6c\x06\x34\xa3\xdf\x23\x5b"
+  "\x41\x9e\x10\x8d\x9f\x90\x5e\x21\xde\xfd\x5a\xdd\x2c\x69\x54\xd1"
+  "\xab\x23\xbf\x8e\x69\xad\x0a\x0c\xd2\xc7\xd7\xb2\x28\xfc\xc4\xbc"
+  "\xee\x41\x39\x4e\xe5\xb0\x5e\x85\xce\x8b\xf4\x19\x32\xaf\x4a\xa7"
+  "\x88\x3a\x4a\x53\x94\x3a\xf0\x7e\x16\xda\xc0\x90\x58\x75\xe5\xa6"
+  "\x82\x55\xe2\xf0\x24\xea\xe4\x57\x3c\xfd\xec\xaa\x9c\x09\xe6\x15"
+  "\xab\xe9\x98\xa5\x0d\xb9\xab\x56\xe5\xf1\x97\x44\xda\x38\x30\x91"
+  "\xd7\x87\x7c\x10\xb1\xac\xed\x57\xaf\x8b\xf5\x31\x64\x17\x64\xef"
+  "\x6e\xb2\xf7\xa6\xe2\xaf\xf8\xd8\xc4\x59\x36\x15\x9c\x5e\x56\x46"
+  "\xf1\x3b\xf7\x7d\xd4\x7e\x93\x47\xf4\x03\x28\x4f\xea\x23\x91\xb6"
+  "\x0e\x2d\xbf\x4a\xbb\xb5\xb6\x5c\xea\x0d\xef\x27\x4a\xf7\x70\x3f"
+  "\x51\x2e\xf4\x82\xfc\x13\xed\x2d\x20\xbc\x7d\x76\xdb\x04\x2d\x4e"
+  "\xdb\xac\xa0\x8f\xb2\xa5\x2b\x3e\x4a\xf4\x13\xb6\x5c\xec\x83\xaa"
+  "\x44\x5d\xb6\x9c\xa0\xde\xd8\xba\x84\xde\xd8\x8a\x5c\xf0\xda\x31"
+  "\x65\xac\x22\xfa\x8e\xd2\x74\x8a\x1f\xc9\xa7\x63\x7e\x8d\x82\xaf"
+  "\x7a\x2c\xf5\x1b\xb6\xfd\x43\xe3\x07\xdb\x22\x8a\x1f\x68\xdd\x23"
+  "\xf1\x02\x69\x35\x08\xbb\xb1\x1d\x53\xf9\x1f\xe3\xff\x47\xdc\xdb"
+  "\x80\x47\x55\x5d\xfb\xc3\x7b\x26\x93\x30\x09\x93\x4c\xd0\x80\x03"
+  "\x46\x1d\xdb\xd8\x8e\x16\x35\x56\xbc\x97\xfa\x60\x4d\x2b\xde\x4b"
+  "\xef\x8b\x42\x2d\xf6\xa6\xb7\xd4\x04\x49\x6c\xd0\x00\x63\x08\x61"
+  "\xc0\x90\x8f\x01\xd3\x49\xcc\x57\x15\x6d\x84\x24\x84\x8a\x16\x35"
+  "\xd6\xf4\x96\xb6\xb1\x17\x35\x96\xa0\x51\x43\x26\x2a\x42\xb4\x41"
+  "\x87\x10\x62\xa0\x01\x07\x32\x64\x86\x64\xe6\xec\xff\x6f\xed\x7d"
+  "\x4e\x66\xc0\x84\x96\xde\xff\xfb\xbe\x79\x9e\xc9\x39\x67\x9f\x7d"
+  "\xf6\xc7\xda\x6b\xaf\xbd\xd6\xda\x6b\xaf\x85\xe7\xfe\x89\xc6\xfa"
+  "\x41\x5a\x8e\x6f\xa4\xed\xbc\x1b\x97\xaf\xca\xbf\x83\x5c\x60\x65"
+  "\x3b\xec\xd9\xcb\xf3\xb3\xb3\x2e\xdc\xc7\xb3\x69\xbc\x18\xed\xa1"
+  "\x6f\xc1\xbc\xf7\xc6\x12\x3c\x4a\xd0\x7f\x67\x96\xd6\x07\x41\xa7"
+  "\xc0\x3b\xaa\x34\xce\x34\xc0\x9c\xb7\x6c\x17\x76\x80\x25\x59\x1a"
+  "\x9e\x50\xbe\xbb\x1c\x5c\x41\x1a\xfa\x5f\x64\x57\xe5\x25\xc8\xa4"
+  "\x25\x2e\xed\x39\xfc\x7d\xc9\x7e\xb1\xf6\x3d\x23\x6c\x06\x01\xd3"
+  "\xd2\x85\x11\xfc\x16\x3d\xa7\xa8\xcf\xc2\xcf\x13\xf9\x24\x1b\x62"
+  "\x25\x47\x24\x7c\x4b\x30\xfe\x1b\x55\x5a\xe1\x94\x76\x37\xcf\x30"
+  "\xf6\x5c\x91\x37\x7a\xbb\xd8\x4f\x28\x09\x68\xf5\xe1\xfb\xde\xc8"
+  "\x3a\x69\xdd\xba\xb0\x3c\x0f\x2b\x11\x3e\xdc\x37\x09\x1f\x75\xa5"
+  "\x73\x26\x68\x6b\x6b\x64\x3e\xe4\x49\x47\x1e\x83\xd6\xe7\x1f\x39"
+  "\x44\x5a\xee\x45\xfa\x38\xa4\xf6\x91\xe8\xa6\xa8\x9f\xf0\x5f\x6d"
+  "\x43\xa7\xea\xf7\xc4\x43\x31\x12\xa9\xfd\xc2\xff\x9a\x85\xe6\x75"
+  "\x29\xad\x67\x73\xb4\x7e\x50\x1f\x77\x17\x79\x0d\x9a\xdf\x2b\xf9"
+  "\x7d\xe9\xf3\x17\xb4\xcd\x17\xf1\xcd\x60\xdb\xd7\x68\xaf\xa0\xb4"
+  "\x8a\x3b\x8b\x49\x8e\x21\xbf\x57\xc6\x2d\xe3\x78\xe8\xb4\x7e\x15"
+  "\xef\x4a\x2b\x09\xef\x22\x71\x69\xc5\xb7\x97\x03\x93\xd6\x64\xe7"
+  "\xdf\x2e\xb8\x7b\x30\x76\xe4\x56\x6d\x59\xfe\x8a\xd5\xab\xd6\xcc"
+  "\xb6\xae\xc9\x5a\xa6\x4e\xfa\xf3\xe6\xbc\x53\xc8\xee\x3e\x6d\x9e"
+  "\xa1\xae\xca\x30\x6d\x71\x86\xf1\x9f\x6c\xc0\x44\x6c\x66\xe7\x11"
+  "\x39\x9f\x9c\xbb\x23\xe6\xae\xf8\x9e\xe6\xe8\x76\xc1\xb3\x39\x23"
+  "\xd7\x7f\x92\x8d\x63\x4f\x31\xe7\x46\x15\xa6\x3e\x09\xe3\x4d\xd7"
+  "\x8b\x7e\x0a\x7f\x5f\xce\x79\xd4\x4f\xe1\x5f\x46\xf0\x67\x9b\x12"
+  "\xb5\xfe\x86\xe5\x86\x4d\x36\xc1\x47\xa9\xfc\xda\xc5\xe4\xf2\x30"
+  "\x7f\xba\xa9\x5d\xd5\xb9\xf5\x68\x32\x9e\xc6\x5f\xa3\x2d\x59\x92"
+  "\x57\xdd\xb4\x71\x51\x21\x1f\xcb\x70\x90\x1f\x3c\x1a\x83\x4d\x2f"
+  "\x6a\xbc\xa5\xb0\x0f\x2c\xf7\x34\xa1\x3d\x4d\x91\x74\x82\x47\x3d"
+  "\xd2\xa3\xf2\x88\x4d\x52\x76\x9d\xfa\xa7\x3e\xd4\x85\xb6\x19\x2f"
+  "\xd2\x36\xea\x17\xe8\xdf\x96\x9d\x54\x0e\xf1\xd7\x7c\xd8\xa2\xc6"
+  "\x9b\xdc\xfc\x4b\xc1\xef\xa2\x6c\x2f\xc6\xd6\xef\xdc\x0c\xfe\x6f"
+  "\x93\xc0\x0d\x05\x38\x4a\xb6\x41\x3e\x8d\x47\x62\x9b\xef\xa0\xb5"
+  "\x08\xf7\xc0\xdb\xcd\xea\x99\xc4\xcd\xb5\xde\x35\x36\x36\x3c\x6c"
+  "\xd1\x0f\xaf\x49\x37\x90\xbe\x80\x60\xe1\xae\x0f\x30\x89\x3f\x9b"
+  "\x33\x81\x77\x89\x91\xe5\xa9\x65\x11\x4c\x0d\xd4\x0e\xbe\xc6\xa2"
+  "\x27\xfc\x16\xf1\x09\x87\x6d\xe0\x85\x37\xdb\xf8\x1a\x9b\x7e\x12"
+  "\xdf\x5e\x17\xeb\xa7\x89\x62\x3c\x52\x6c\x4e\xa2\x57\x32\x7e\xc0"
+  "\xe3\x27\x9f\x92\xba\x01\xad\xde\xd3\x5c\xbf\x43\xac\x2b\xd5\x62"
+  "\x5d\xe1\x4c\xfa\x63\x7f\x5c\xf8\xca\x4f\xb0\xef\x10\x71\x55\xd5"
+  "\xf3\xdf\xde\x76\x7b\x50\xc4\xca\x2b\xce\x27\x3e\x2d\x48\xfb\x54"
+  "\xe2\x7c\xf3\xde\xfc\x20\xfb\x51\x80\x70\xf2\xf1\x34\xf2\x45\xef"
+  "\x13\xfc\xc2\xe3\x0b\x35\xff\xf3\x14\x37\x92\xe2\x8e\xa2\x5f\x51"
+  "\x34\xee\xd6\x62\x8a\x1d\x50\x46\x71\x59\x99\x94\xc7\x2d\xac\x1a"
+  "\x3c\xbd\x1c\x83\xc7\x9f\xa6\x38\xae\x52\x56\xe8\xc3\xb8\x44\x7d"
+  "\xd1\xc7\x1e\x7f\x45\xee\x55\x6b\x74\xa2\xec\x3a\xb2\x7d\xf7\xa8"
+  "\x65\xa0\x2e\xac\xff\x9b\xa4\x8f\x50\x5a\x3b\xfd\xda\x78\x3e\xfe"
+  "\xf4\x57\xf5\x1b\xe1\xf2\x3c\xec\xf1\x2d\x2a\x5f\xc0\xa4\xee\xea"
+  "\x2f\x28\xab\xcc\xa0\xe9\xae\xc2\xbc\x4f\x99\x45\xd3\x5d\x49\xdf"
+  "\xd6\x9b\x7b\xa9\xfe\xc9\x74\x44\xbc\xf8\x27\x84\xf7\x46\xe2\xe1"
+  "\x26\xe5\x27\xb0\xbe\x53\xdb\x35\xbe\x50\x8e\x4f\xd9\xef\x88\x3f"
+  "\x6c\x2f\x94\x72\xed\xb0\x8c\x31\x09\x1e\xa0\x6c\x8f\x5c\xcb\xca"
+  "\x9a\xb4\xb5\x0c\xdf\xee\x56\x69\x85\xba\xce\x95\x8d\xcb\xbf\x13"
+  "\xdb\xfd\x97\xf5\x6a\x30\xd2\x60\x2e\x61\xf4\x8b\xdb\x86\xe3\x0e"
+  "\xce\x0e\xc3\xf6\x17\x62\xef\x22\xe2\xfd\xca\x08\xd8\xd3\x73\xae"
+  "\xa4\x9b\xbf\xc0\xfa\xbf\x59\x95\xad\x64\x1a\x8f\xeb\xfb\x88\x62"
+  "\xc6\x4a\x18\xac\x10\xba\x19\x6f\xb1\x0d\x6d\xfb\x45\xba\x47\x77"
+  "\xd9\x62\x49\xcb\x7e\x81\xf5\xaf\x6c\x89\xfa\x9d\x18\xff\xc8\xf6"
+  "\xde\xbf\xea\x91\x55\xab\xd7\xad\x22\x85\xda\xda\x35\xd6\xe5\xab"
+  "\xb3\xb2\xe3\x26\xd0\x87\x58\x28\x5e\xb4\x6f\xcb\xb8\x5f\xab\x0a"
+  "\x3b\xd9\xe9\xcb\x98\x08\x15\x8f\x5a\xbf\x41\xf8\xf5\x8b\x8f\x49"
+  "\x57\x20\x62\x53\x90\x0f\x57\xa9\x37\x18\xa4\xef\x25\xac\x2b\x7e"
+  "\x36\xbc\x2e\x47\xe5\xb1\x2a\x66\x12\x1c\x55\x99\x83\x0f\x30\xd7"
+  "\x0f\xb5\x75\x88\xda\x27\x78\xf3\x31\x9b\xa0\x8b\xca\x58\x8e\x41"
+  "\xc0\x6b\xcc\x86\xf5\xc6\x95\xea\xd1\x4d\x9b\x2d\xfb\xe5\x9a\xa7"
+  "\xc1\x83\xfa\x0f\x5e\xd7\xe8\xe7\x2b\x80\xa3\x15\x76\xb5\x2c\xa2"
+  "\x9f\x54\xb6\x41\xb3\x13\x27\x5f\xa5\x6d\x05\xe4\xa7\xb8\xfc\x0e"
+  "\xa5\x9c\xe8\x8d\xab\x44\xa3\x4b\xb4\x16\x29\x28\xe7\xd5\x11\x6f"
+  "\x34\xe6\xcd\xf7\xf0\xed\x8c\x3e\x56\xde\x29\xe3\x19\xb8\x9a\xcf"
+  "\x8f\x67\x50\xee\xc2\xaf\x53\xfd\x0d\x45\xdc\x5f\xec\xa7\x7d\xd3"
+  "\x1a\x91\x66\xbc\x20\xcf\x90\xdf\x59\x9e\x34\xce\xaf\x48\x7f\xa9"
+  "\xaa\x7f\x65\x8a\xcd\x51\xfe\x43\xf2\x49\x1a\xc6\x0d\xd7\x5a\x95"
+  "\x07\x19\x24\xd8\xd1\x7a\x8b\x3c\xc2\x96\x1b\x30\xf9\x88\x74\xb4"
+  "\xd4\x27\xee\x5f\x01\x9c\x28\xcf\x0d\xe3\x81\x84\x11\xd2\x4a\xc2"
+  "\x7c\x4a\xf9\x12\xfa\x26\x12\x0e\xa8\xe3\x7b\x52\x36\x2d\xdf\xa5"
+  "\xad\xd9\xe4\x8f\x55\xc6\xb7\x28\x4f\xda\x5d\x34\x08\x99\xbf\xbc"
+  "\x3d\xa2\x8c\x24\x55\x17\x61\xe0\xfa\x5f\x38\xb6\x0b\x99\xad\xbc"
+  "\x3f\xac\x13\x28\x4f\x22\xba\x2b\xca\x88\xeb\xf3\xb8\x7d\x22\x2e"
+  "\xb3\x4e\x8b\xbd\xee\x77\x56\x24\x6a\x3c\x8a\x56\x56\xbb\xd4\x39"
+  "\x09\x1f\x9a\x98\x83\xb5\xc8\x33\x67\x5c\x1f\x8b\xb4\x71\x19\xd0"
+  "\x81\x79\x2c\x78\xef\x8a\x25\x61\x59\xef\x17\xc2\xc7\xae\x90\x03"
+  "\x65\x39\x90\xb3\x2a\x16\x5c\x28\xb7\x81\x7f\xb0\xae\x58\xb5\x02"
+  "\xec\xc3\xcf\xed\xab\xef\x80\xe8\xf0\x73\xfb\x8a\x3b\xc8\xa4\xec"
+  "\x9e\xf9\x3f\x10\x57\x4c\x8e\x3b\x26\xd0\x1f\x8f\xc7\x5e\x26\x9d"
+  "\x11\xe4\x5c\xd2\x9d\xfa\x65\xec\xd5\x29\xea\xd5\xa8\x5e\x63\xb0"
+  "\xee\x75\x00\xef\xcf\x52\x6c\x1d\x0f\x7b\xc2\xa8\xc6\xbb\xd5\xd6"
+  "\x6c\xd0\xf2\x8a\x93\xda\x3e\x99\xb0\xb1\x27\x3f\x89\x14\x5b\x79"
+  "\xd3\x23\x47\xfc\xce\x27\xc6\xf5\x1f\x52\xbf\x28\xf7\xbd\x90\x9e"
+  "\xa6\xa5\x6b\xfa\x58\xa4\x2d\xd1\x74\xaf\x32\xef\x13\x59\xe1\x6f"
+  "\xcf\xd3\x6d\x27\x69\xfb\x6b\xc8\xe3\xd2\x60\xa6\x95\x53\x6c\xe5"
+  "\xa7\x54\x3e\x29\x4a\xf0\xd5\xce\x8a\x42\xe1\x9b\x94\x78\x71\xa1"
+  "\x67\x7e\x62\x8f\x56\x0f\xc9\x08\xd4\x6e\x75\xef\x46\xcc\x7b\xf2"
+  "\x41\x2a\x7d\x98\x3e\x31\x3e\xfe\xe7\xef\x71\x4c\xbc\xbf\x31\x56"
+  "\xc0\xdb\x83\x23\xbc\xb5\xfa\x53\xcc\xd9\x87\x18\x0b\x16\xf0\x96"
+  "\xb1\x11\xbe\x9b\x60\x5d\xfd\x20\x63\x55\x9f\x31\x16\x8a\xfa\xe9"
+  "\xf1\x51\xc0\xfd\xde\xb3\xca\x29\x8a\xaf\xb7\x1d\xf9\xee\xf5\x7d"
+  "\xc9\x1b\xf1\xcd\xbd\x76\x7e\xaa\x11\xf9\xee\x39\x79\x8a\x37\x20"
+  "\xef\x3d\x39\xe8\x77\x01\x0f\x86\xa2\x1e\x39\x6e\xfd\x31\xd1\xa1"
+  "\x4a\x87\xb7\xfc\x70\x32\x77\xea\x6b\xf8\xa6\x6f\xdd\xe0\x77\x56"
+  "\x6e\x1e\x8f\xe9\x85\x72\x09\x46\x8b\x1c\x74\xff\xc8\x71\xf4\xe9"
+  "\x78\x06\xd6\x50\x8c\xc1\x71\xe4\x83\xfc\xbf\x46\xf4\xc3\x1b\x75"
+  "\xc3\x65\xf8\xd9\x26\xa2\xfb\x68\x6b\x7b\xa8\x80\xb7\xd6\x3c\x80"
+  "\xf6\x9f\x40\xfb\x47\x78\x0b\xfa\xb0\xbb\x7a\x80\x31\x6a\x7f\x88"
+  "\xca\x0c\xb1\xa8\x8c\xf5\xba\x69\xdb\xf1\x3e\xc3\x91\xc8\xb6\x23"
+  "\xef\x03\x3e\x36\xad\x11\x79\x1e\x78\x74\x1a\x13\xed\x1f\x42\xbb"
+  "\x63\x0f\x27\x87\x50\x37\xb5\xdf\xef\xac\x9a\xad\xb5\x53\xab\x9f"
+  "\xda\xab\xe1\x60\x06\xe9\xbb\xe2\x0e\xe6\x52\xbb\xa5\x0e\xbf\x2a"
+  "\xdb\xbb\x26\x87\x79\xa3\xbe\x75\x83\x87\x55\x95\xd0\x1c\xa2\xfe"
+  "\x78\x81\x53\xea\xb9\xb7\xe3\x1a\x0c\xa4\x3c\x59\x55\xa9\xf5\x2f"
+  "\xb2\x5f\x8b\x57\xe7\x09\x3d\xea\xb2\xe5\xf9\x2b\x0a\x96\x41\x3a"
+  "\x8b\x63\x76\x4a\x12\xf2\x5b\x76\x96\x75\xf5\x2a\xeb\x43\xcb\x56"
+  "\xe4\xae\x2e\xc8\xce\x9b\x2d\x44\xee\x35\xd9\xab\xb2\x48\xbd\x9a"
+  "\xb7\x2c\xcf\x1e\x77\x01\xcf\xed\x3a\x9c\x4c\xf6\x88\x44\xcb\x06"
+  "\x58\x6d\x95\xaa\x5b\x0c\x70\x67\x9a\x90\xdd\xe4\x3c\xa8\xfe\x9e"
+  "\x75\x43\x1a\xbd\x2f\x95\x6b\x4d\x6d\x25\xaf\x38\xb8\x92\x73\x11"
+  "\x13\x5a\x77\x8a\xd5\xae\x17\xfd\x1c\x5e\xa0\x95\x23\x6c\xf4\x05"
+  "\xcf\x4a\xe9\x63\x0b\x58\xd8\xa6\xbc\xb6\x8a\xeb\xd1\x47\xc0\x40"
+  "\xe5\x5b\xb5\xb3\x7d\xef\xf4\xb1\xda\x6c\xf4\x9b\xf6\x0e\x24\x5f"
+  "\x28\xce\x20\xd5\xde\x0f\xbe\xb7\x9b\x3b\x63\x4c\x04\x97\x6a\x29"
+  "\x57\xea\xcd\x3a\x8a\x13\xdb\x47\xe7\x21\x53\x69\x8f\x70\xbb\x53"
+  "\x49\x0d\xdb\xf4\x54\xd5\x11\x8f\x2b\x74\xed\x62\x5e\x54\x1f\xd0"
+  "\xf0\x5d\x4f\x67\x4c\x36\xcd\xba\x5d\xd2\xea\x6a\xb1\xff\x8f\x71"
+  "\xbb\x5d\xb6\x5f\xc4\xa7\xc6\xfa\x54\x73\x1a\xfd\x5b\xc5\x8b\x17"
+  "\xa8\x7e\xe5\x6b\x4e\x2b\x09\x56\x7b\x68\x8d\x45\x8d\xe9\x7e\xb0"
+  "\x4c\xa9\x38\x58\x10\xc2\xba\xae\x80\x57\xe5\xd5\xd6\xe1\x50\xc5"
+  "\x41\xbb\xb2\xce\xa6\x27\xfa\x5e\xec\x00\xfc\x56\xe7\xc4\xf1\x2f"
+  "\x73\xa6\x86\xd6\xd9\xc8\x0e\xd3\xc1\x39\xbe\x8d\x3b\xe8\x12\xb1"
+  "\x79\x2b\x0e\x6e\x50\x9f\x2b\xe8\x59\x01\xaf\x86\xb4\x5a\x3c\x3f"
+  "\xa9\xf0\x88\xfc\xe7\xe7\xdd\x42\xcf\x66\x9d\xb0\x21\xa4\x18\xd3"
+  "\xf3\xa8\xef\x5a\x9f\x85\x8c\x40\x7a\x8a\xf1\xbe\xd5\x0c\x69\xe9"
+  "\xc4\xbb\x4a\x3e\x92\x2d\x07\x8c\x99\xa4\x69\xe3\xf9\xf6\x69\x30"
+  "\x10\xb0\xad\x38\x88\x35\xa9\xb6\x52\xc4\xa9\xdf\x74\xe5\x0d\x5c"
+  "\x5f\xf5\x32\xad\x1d\x8b\x42\x62\x2f\x8b\xc9\xbd\x8f\xda\x14\x0d"
+  "\x9e\x64\x2b\x4f\xeb\x07\xc6\xcd\x96\xe1\x65\x71\x72\xfe\xd6\xce"
+  "\x8f\x90\x51\x86\xb8\xc0\xf7\x9a\x5e\x51\xaf\xde\xb8\x49\x3e\x57"
+  "\x6f\x91\xeb\x5d\xad\x5d\xcb\x8b\x34\x87\xe4\x49\xab\xe7\x93\xec"
+  "\x46\x7b\x5b\x74\xdf\x38\xc9\x39\xce\xa2\x7a\xce\x89\x16\x12\x6d"
+  "\xb6\xce\x62\xac\xcb\x47\x7c\x7b\x6d\xe7\xde\x7a\x1f\x13\xe3\x17"
+  "\x77\x70\xe5\x30\xcf\x61\xe0\x57\x26\xe4\x53\xe9\x9b\x01\xf6\x4b"
+  "\xa3\xe0\xc1\x81\xcf\x0a\xf0\x19\xdf\xac\x22\x7c\x2d\x3a\x4b\xed"
+  "\xf8\xe5\x82\xf6\xc2\x41\xf2\x33\x0f\x3c\xfc\xe5\x02\x82\x0d\xad"
+  "\x0d\xd5\x4e\x71\x86\x4f\xd0\xe0\xb6\x82\x39\x54\xc6\x6d\x09\x01"
+  "\x66\xe8\x02\x05\x05\xbc\x03\xf6\x22\x36\xed\x04\xf2\x1b\xf2\x99"
+  "\x91\xe4\xa3\x7f\x74\x1f\x19\xf5\x6d\x96\x30\xf9\xe5\x66\x8d\x07"
+  "\xc2\x7d\xed\xf9\x67\x55\x7f\xe9\xb8\x70\x2f\xed\xc1\xd5\xab\xf3"
+  "\x33\xf2\xb2\xe9\x62\xbb\x6e\xed\xf5\x17\xae\x89\x26\x19\xd7\xe7"
+  "\x97\xbb\x68\xfc\x68\x9d\x90\x67\x3e\x7e\x39\x18\x21\xd7\x92\x6e"
+  "\xed\x4e\x5a\xdf\x68\x4f\xdc\xef\x7c\xd2\xf0\x56\xe1\x46\x81\x27"
+  "\x47\x8c\x4c\x7f\x61\x7d\x0f\x2d\xcb\x5f\x96\x7b\xbb\xdc\xbe\xfd"
+  "\x6a\x3d\x4f\x5a\xce\xaf\xe7\xc9\xc5\xe3\xf5\x48\x19\xc4\x27\xe6"
+  "\x60\x95\xd5\xc3\xe3\x63\x4b\x24\x9d\x7b\x32\x5f\xb3\xc9\x9a\xd8"
+  "\x37\xc6\xc1\xfe\x50\x45\x7f\x2a\x8d\x57\xf1\x46\xa6\xff\xfd\x86"
+  "\x1e\x3d\xf1\x5f\x45\xb8\x27\x9b\x15\xa1\xe7\x53\x63\xee\xbd\x71"
+  "\xa6\x07\x74\xf6\xc9\x0e\x5e\x7e\xb0\x1f\x78\x35\xa9\x9d\x49\xe4"
+  "\xb9\x62\xb9\x47\xf9\xa4\x67\xb2\xbc\xdc\xe5\xe9\x91\x73\xe5\xa9"
+  "\xdb\xc4\x5e\xd9\x2c\xf6\x8b\x3e\xf6\xd4\x2d\x06\x0b\xe4\xb8\x59"
+  "\xec\x37\xb8\x17\xf2\x02\xbd\x3b\x6f\xac\xaf\x1a\x6a\x32\x00\x3b"
+  "\x81\xa5\x3a\x2e\xff\xc0\x84\xc9\xbf\x28\xfc\xf4\x5c\x27\xac\xf3"
+  "\xa3\x00\xe1\x29\x31\x06\x66\x4e\x30\x19\xaf\xb9\x3a\xd9\x72\xe7"
+  "\x77\xe7\xcd\x2d\x2e\x2a\x74\x70\x25\x18\x30\xf3\x88\xf8\x90\x95"
+  "\xb1\xb6\xfb\xaf\x2f\x91\x6b\x45\x55\xec\x84\x6b\x5d\x95\x93\xdb"
+  "\x89\xb7\x06\xbd\x5a\x5c\xbc\x96\xe9\x5f\x1d\xf5\xe8\x89\x97\xa3"
+  "\xf5\xc7\x1d\x3c\x0c\x99\xe0\xa9\xb7\xde\x44\x1a\xfa\xef\xe0\x95"
+  "\xd6\xc5\xf2\xec\xc5\x16\x9d\x52\x6d\x5d\x1c\x2e\xdf\xc0\xa8\x7c"
+  "\xc8\x0b\xfa\x9d\x45\x83\x7a\xb7\xe1\xbb\xcc\x6d\xf5\xb1\x37\x71"
+  "\x3f\x21\x2c\x51\x27\xe9\xa6\xa8\x0c\xd0\x61\x57\xf1\x39\xd0\x67"
+  "\x87\xd0\x13\xeb\x4f\xb1\x2d\xdf\x69\x99\xe4\x3b\xb1\xd7\x13\xd7"
+  "\xdb\xe5\x77\x6e\xc1\xf8\xff\xc7\x6c\x95\x1f\x02\xbf\xb6\x65\xb3"
+  "\x46\x13\xf0\x7e\xbf\xd4\x57\x6f\xa9\xd3\xf2\x4c\x2c\x4f\x92\x8d"
+  "\x27\x6f\xa3\x71\xe5\x23\x83\x83\xe4\x63\x6e\x12\x9d\xc0\x7c\xac"
+  "\xcf\xd1\x34\x8f\xe3\x4b\x13\x63\x12\x4a\x53\x57\x76\x62\xd6\xc5"
+  "\x0f\x4d\x67\x09\xbe\x9f\x51\x9b\x59\xfd\x33\xc2\xce\x78\x90\xf6"
+  "\xa9\xcc\xba\xd4\x15\xe6\xd2\xd4\x65\x21\xe7\xbc\x5b\x69\x9d\x34"
+  "\x3b\x7e\xa0\x33\x07\xbf\xa7\x0b\x3a\xe7\xdc\xba\x5d\xc6\x64\xf1"
+  "\xd5\xce\xe0\x3d\xf8\xa6\x17\xdf\x78\xf0\xeb\xc7\x77\x9d\x03\xec"
+  "\xe9\x9f\xe0\xda\x61\xd6\xf1\xed\x66\x8c\xe4\xcd\x25\x22\x46\x25"
+  "\xd1\xe8\x4e\x1e\x07\x1e\x73\x4c\xe8\x02\xa2\xc3\xba\x80\xa7\x0b"
+  "\x31\x6e\x31\x0b\x1f\xe7\x6f\xa2\xac\x8e\xd0\x88\xd2\xd1\x78\x8a"
+  "\x31\x55\xe7\x7d\x00\x73\xf4\xc0\xec\x2d\xcc\xa2\xda\x8a\xea\x3b"
+  "\x83\x1d\x44\x8b\xe9\x6c\x75\x3b\xea\xdc\x83\x5f\xab\x75\x15\x8b"
+  "\x3a\xc5\x9e\xde\x4f\xfc\x47\x98\x87\xfd\xd5\xdd\xaa\x3c\xd2\x76"
+  "\x13\xbe\xdf\xb8\x92\x70\x62\x50\x1f\x44\xf9\xe0\xf9\x3b\xdc\x39"
+  "\x1d\xc2\x16\x86\x6c\xb1\x29\x0f\xea\xb0\xb9\x03\x1d\x4c\xe1\x16"
+  "\x3d\x9e\x5b\xc9\xb6\x90\x23\x6f\x97\xa3\x87\x75\xd9\x03\xa0\xb1"
+  "\x9d\xe0\x81\x6d\x29\x68\x8f\x28\x0f\xef\x0f\xbc\x8a\xf1\xb5\x82"
+  "\xdf\x43\x79\xdd\x64\x5b\x43\x67\x94\xf9\x1a\xdb\x37\xf0\x7d\x3b"
+  "\x64\x68\x3d\x95\x7f\x8a\x3d\xf3\x31\x1f\xb6\xd9\x6e\x1e\x92\x31"
+  "\x1b\xfb\xd8\x33\xcd\x68\x67\x4c\x44\x3b\x6f\x43\xfb\x0d\xa0\xab"
+  "\x6d\x28\x73\x0f\x2f\x40\x9d\xfd\xa8\x13\xf2\x08\xf0\x37\x05\xf2"
+  "\xae\x81\xda\xdc\x45\xed\x75\x84\xc8\xfe\xd5\x50\x73\x86\x19\x30"
+  "\x17\xda\xb6\xe3\x8a\xfe\xef\x06\x4f\x96\xec\x77\x3e\xd3\xa6\x9d"
+  "\x73\x27\x5e\x02\xcf\xdd\x1a\x2e\x55\x21\x0f\xda\xd8\x8a\x76\xed"
+  "\x89\x1f\x62\x24\xe3\x44\x03\x4f\xa3\x51\xef\x14\x8c\x55\x2b\x60"
+  "\xf7\x3b\xc0\x7a\x0f\xf5\x49\x19\x51\x06\x15\x94\x57\x33\x82\x36"
+  "\xad\xb1\x18\x4c\xfd\x14\xd3\xda\xcf\x01\xef\x03\x8b\x1c\x7e\x4e"
+  "\x76\xb2\xe8\x33\xc1\xbb\x0a\x7d\x35\x78\xd8\xaf\x72\x49\xde\x18"
+  "\x60\xcf\xe4\xcb\x98\x93\xcf\x38\xd4\x3d\xad\x03\x52\xcf\xf4\xf4"
+  "\x7e\x82\x3d\xf5\xcb\x54\x9a\x58\xe6\x1e\xf4\x32\x53\xff\x74\xac"
+  "\x6f\x4f\x7b\xeb\x15\xe2\x51\x7e\x35\xae\xff\x9f\x64\x8e\x05\xdc"
+  "\xa0\x2f\xca\x08\x17\xb1\x6f\xa5\xbd\xcb\xaf\x9a\x33\x1c\x51\x69"
+  "\xe0\x33\xf5\x68\x27\x9d\xd5\x98\x81\x75\xfa\x4e\xb2\x67\x42\xfb"
+  "\x20\x77\xfc\xaa\xf3\x62\xb1\x5e\x01\x1f\x0b\xf2\x78\xd1\x76\x11"
+  "\xd3\x8f\x62\x61\x4a\x5d\x4f\x9d\x41\xf3\x37\xc0\x47\x78\x61\x4d"
+  "\x91\xa8\xb7\x64\x73\x81\xa8\x83\xe2\x7f\x0e\xe6\x5b\xf9\x91\x76"
+  "\xab\x77\xd2\x33\xdd\x11\x76\x3c\x5e\x35\xa6\x98\xd8\xd3\x3c\xdf"
+  "\x8e\xa7\x2e\x37\x42\x6e\xa4\x7d\xcd\x12\xda\xbb\x95\x7e\x61\xea"
+  "\x84\x2d\xe6\x22\x87\xf4\x7f\xe1\x0e\x0c\xa9\xbc\x65\xdd\x6b\x22"
+  "\xce\x10\xf1\x35\xc2\xf6\xe7\x84\x6a\xaf\x53\xf7\x43\xaa\xa3\xfd"
+  "\x82\x58\xc6\xd9\xab\x96\x3d\x98\x9b\x2d\x55\x29\x37\x3e\x9c\xbf"
+  "\xec\xe7\xe7\xf3\xbf\x06\x21\x17\x3b\xeb\xda\xa5\x6e\xb2\x2e\x18"
+  "\xc1\x27\x1a\xc6\x75\x4b\x7a\xb6\x5b\xea\x97\x9e\x4d\x9e\x48\xbf"
+  "\xf4\x83\x9f\xaf\x5a\x9d\x27\xea\x10\xa6\x4d\xd9\xf2\xf4\x53\x1c"
+  "\xbb\x7f\xfe\x0f\xe6\xdf\xb8\x26\x3b\x5f\x04\x0f\x91\xca\x9c\x65"
+  "\x59\x59\x79\xaa\xe1\xd3\x0a\xfa\x8a\xde\x3c\xb4\x4e\x7c\x6a\x7f"
+  "\x24\x5f\x9a\x4c\xad\xc9\x5d\x56\x90\xad\x16\x11\xd9\xd6\x64\xa2"
+  "\x97\xed\xf5\x42\x66\x8e\x93\xfb\xb4\xcf\x36\x47\xec\xeb\x44\xca"
+  "\x91\x33\xf1\xae\x43\x7b\x67\xff\x1a\xe1\xca\xd6\x1b\xbb\x9a\x84"
+  "\xcf\x06\xc3\xde\x5f\x13\x7c\xb7\xd2\x3e\x71\x34\xad\xd9\x8a\xfe"
+  "\x59\x5b\xa3\x7a\x96\xc9\xef\xdc\xca\xc2\xba\x81\x86\x3d\xaa\xed"
+  "\x43\x3f\xd5\x47\x75\xe3\xbd\x35\xc2\x1e\x00\x6b\xec\xb3\x83\x54"
+  "\x06\xed\x5b\x8b\xf8\x12\xe0\x89\xd4\xb3\xec\xfa\xae\x5f\xd3\xda"
+  "\x52\x3f\x9b\xe8\xa8\xe2\xf2\x78\xe5\x3c\xd8\xb6\x8c\x57\xf4\xba"
+  "\x6f\xf6\xb1\x24\x49\x07\xb6\xbe\x82\xf4\xcb\x4f\xb1\xad\x2e\xa4"
+  "\x77\x83\x96\x44\x13\x3f\x22\xf5\xdf\x5b\x5f\x51\x75\x05\xd4\xe7"
+  "\xe8\x88\x36\xec\x0c\xeb\x13\x1a\xf6\x78\x63\x3d\xde\xcd\x72\xbf"
+  "\x5f\xec\x6d\xca\xfd\xe5\xad\xe3\xfd\xc7\xfa\xad\xed\xe7\x25\x0d"
+  "\x20\x3f\xe4\x09\xaf\xba\xc7\x46\x7d\x4f\xa3\x7e\x4b\x3b\xad\xad"
+  "\xc1\x48\xbe\x56\xfa\xf3\xef\x75\x13\x2f\x2c\xe5\x80\x6d\xd7\x0b"
+  "\xde\x85\x74\x17\xa3\x04\xc3\x6d\x77\xe0\x3d\xd6\xaf\x6d\x73\x3c"
+  "\xac\xae\x27\x12\x66\xf9\xe0\xe0\x39\xbe\xa3\xf5\x0c\x6d\x9a\x82"
+  "\x3c\xe9\xe1\x36\x6f\x13\x7e\x22\x48\x56\x90\x7c\xc5\xb6\x93\x22"
+  "\xfe\x98\x0f\xfd\x53\x6d\x06\x08\xe6\x32\x1e\xc1\xb6\x5a\xed\x3b"
+  "\x25\xce\xe3\x21\x19\xa5\x5a\xee\x7f\x01\x76\xdb\x3e\x88\xd2\x1d"
+  "\x11\x7b\xa0\x37\x07\x58\x13\xd2\x62\x90\xb6\x8f\xf2\x51\x3b\x84"
+  "\xae\x02\xed\xa7\xfa\x14\xf0\xc1\x51\x96\x98\x3b\x50\x1e\xde\x3d"
+  "\x99\x12\x1e\xbf\x6d\xbb\xc2\xfa\xa1\x67\x1f\x90\xfa\xa1\x7a\x83"
+  "\x06\x07\x8a\x23\xa4\xce\x85\x68\x6d\xbf\x1c\xef\x53\x22\xe1\x2f"
+  "\xe8\x9c\x0a\x4f\xee\x7c\x76\x4d\x58\xee\xaa\x5f\x38\xbe\x57\x84"
+  "\x76\x84\x69\x7d\xfd\xa3\x04\x47\x6a\xb7\x7d\x03\xe9\x92\x1b\x76"
+  "\x8a\x7e\xc8\xfd\x98\xbf\x60\x8c\x9e\xe6\xe0\x0b\x68\x8d\x24\x19"
+  "\x80\xc6\x97\xf2\xca\x18\x43\x0d\xf7\x34\x4a\x9d\xe7\x33\xb8\xff"
+  "\xa1\xa2\x9f\x08\x3f\xea\xdb\x23\xed\x03\x25\x8c\x1b\x4c\x0a\x95"
+  "\x09\xf8\x51\x59\x58\x37\xc6\xed\x9e\x65\xb9\xf5\x21\x94\xf9\xab"
+  "\x81\x70\x7f\x20\xe7\xa9\x70\xa4\x71\x14\x70\x69\xc0\xfc\xaf\x13"
+  "\x7a\x9b\xe2\x26\x7e\x72\x35\xca\x90\xb1\x3f\x1b\xe6\x71\x1a\x1b"
+  "\x35\xbf\x97\x64\x27\xb4\x5d\x9e\xdd\x02\xbe\x41\xfe\xa0\x76\x2a"
+  "\x15\x9e\x41\x6a\x3b\xed\x03\x84\xe5\xe1\x06\xb2\xdd\xf0\x78\x1f"
+  "\x93\xdf\xd4\xc8\x7d\x0a\x8c\x6d\xfd\x8b\x7c\x5d\x0e\x53\xf5\xe3"
+  "\xa0\xc7\xf5\x49\x84\xdb\x54\x8e\x4f\xc8\x45\x0d\x2e\x05\x70\xc1"
+  "\x98\x52\xbb\x76\x6b\x63\x8a\x7c\xf6\x8b\xd8\x56\x63\x4c\x1a\x3c"
+  "\x9a\xef\x17\x5a\x53\x30\x4f\x4b\x24\x0f\xd8\xb8\xc3\x5c\x7a\x27"
+  "\x37\x07\x6f\xbd\x95\x78\x9a\xed\x7a\x21\xab\x68\xf6\x6f\xd7\x00"
+  "\x4e\x5f\x6a\xb6\xc0\xca\xa6\x9f\xf6\x90\xed\xa0\x3b\x20\x6d\x07"
+  "\x29\xfd\x5e\x1f\x57\xba\x7c\x21\xb2\xcf\xef\xf1\x3b\x1b\xe7\x6b"
+  "\xf2\x0b\xd1\xa5\xa8\x52\x1d\xda\xd8\x08\xfc\x7f\xaa\x59\xa5\x47"
+  "\x53\x4e\xb0\xc6\x52\xb5\xfc\x88\x36\x34\x04\xa5\xfc\xd7\xd8\x24"
+  "\xe5\xa0\xc6\x4a\xd0\x97\xcd\x52\x0e\x6a\xac\xd3\xda\x8d\xf7\x59"
+  "\x17\xf6\x71\xf1\x5d\x3f\xc8\xb6\xe6\x12\x69\x4d\xfd\xb6\xc3\x6a"
+  "\xbb\x2e\xeb\x66\x61\x6c\x6a\xfd\xb7\xbb\x6e\xb7\x2e\xbe\xe3\x3a"
+  "\x47\xce\xec\x7b\xe5\xe5\xae\xc5\x0b\xe9\x7a\xc1\xde\xa3\x15\xe5"
+  "\x07\xce\x97\xb3\x76\xaa\x6d\xd8\x9e\xe8\xd1\xd9\xe4\x1e\xad\xf1"
+  "\x90\x95\xe2\xab\x63\x2d\x1c\x22\xfe\x76\x51\xe8\x73\xce\xcb\xf7"
+  "\xe5\xf0\xd8\x43\x56\x6f\x7c\xac\xcd\x1b\x6f\xf4\x7a\x63\x7b\x7d"
+  "\x14\x7f\xdd\x5c\xca\x03\xe6\xe0\x14\x49\x0f\xf1\x0c\x5e\x62\x10"
+  "\xfc\x0a\x8d\x25\xbb\xfb\xfa\x62\xbe\x28\xc4\xdd\xe0\x5b\x00\x97"
+  "\xed\x76\x6d\xfd\x15\xba\x23\xd7\x21\xeb\x22\x07\x1f\x23\xdc\xc1"
+  "\xba\x6e\xe4\xe5\xa8\x33\x8a\x74\x5d\xdb\xd1\xff\x2d\x56\x09\x8b"
+  "\xed\xa0\x7f\x0d\x1d\x2a\x7c\x17\xe3\x99\xe2\xdf\xc8\xbd\x3c\xa7"
+  "\x45\xd0\x78\x65\xd3\x0d\xf7\xf1\x2a\xa3\x57\x2b\x13\x65\x99\xd4"
+  "\xb3\x30\xa2\x3c\x76\x91\xb3\xd4\x91\x3f\xa5\xa2\x27\x99\x74\x0e"
+  "\x74\x7e\xd1\xec\xd0\x51\x7c\xa0\xf4\x71\x3d\x0b\xde\x25\x94\x26"
+  "\x92\xee\x25\x3d\xc1\xa7\x2b\xa1\x3c\x61\x7d\x84\xe2\xa9\xd1\x2b"
+  "\x01\xf0\x01\x89\x32\x16\xfa\x90\xba\x1f\xdb\x94\x39\xae\xdf\x3f"
+  "\x6f\xec\x9b\x04\x3e\x9c\x71\x1a\x80\xdb\x8d\x83\x5f\x4b\x92\x3c"
+  "\x8f\xe2\xd4\x31\x79\x96\xbd\xe9\x7e\x31\x2f\x55\x7c\x04\x7c\xbd"
+  "\xb4\xf7\x66\x0e\x72\x2f\xd9\xa9\x2b\x51\xc0\x49\x76\x82\xb9\x0b"
+  "\xfd\x25\x14\x83\x7c\x1c\x2f\xed\xc0\x4b\x3b\xf0\x92\xf6\x49\x51"
+  "\xbf\x37\xea\x86\x4c\xcc\x59\xdd\x09\xd6\x94\x42\xed\x27\xd8\x80"
+  "\xef\x36\x29\x80\x95\xb0\x87\x23\xf8\xc4\x7d\x52\x4f\xe7\xa2\xa8"
+  "\xaf\xe6\x20\xfa\x1c\xd9\x2f\xbd\xe2\xa9\x76\xa2\x5f\x7a\xf4\xcb"
+  "\x71\x52\xc8\xfb\x74\x5e\x0d\xb4\x64\x46\x38\xc6\xc4\x8e\xf9\x91"
+  "\x7d\x54\x28\x2e\x8d\xe8\xc3\x8e\xec\x89\xfa\xc8\xf5\xd4\x47\x82"
+  "\xc1\x8e\xef\xa8\xfb\x24\xa2\x9d\x44\xb7\x86\x58\x53\x20\xa1\x94"
+  "\xce\x89\x1d\xb2\x82\x5f\xbd\x8b\xc6\xb0\xd1\xc9\x6b\xa9\x9d\x13"
+  "\x8d\x17\x95\x27\xcb\xfa\xb5\xc1\x5c\x5a\x92\x89\xb6\x74\x4f\x0c"
+  "\xef\x1d\xa7\x2f\x0e\xef\x1d\xfb\xe8\x7b\x6a\x07\x9d\x9b\x33\x93"
+  "\x03\x24\xe0\x37\x64\x2c\xd7\x44\xf5\x26\x94\x36\x51\xbb\x26\x7c"
+  "\x07\xdc\x1f\xaa\xc9\x3b\x7f\x4e\x28\x8d\x01\x46\xf0\xdb\x8e\x74"
+  "\xa9\x4b\xfd\xb5\x63\x5c\xe7\xeb\x3a\xb4\xc0\xac\xb3\x46\xd1\x1c"
+  "\x13\xbc\x2c\xfa\x3b\x51\xb9\x66\x5d\x2d\xf9\x50\xbb\x0b\xb4\x6a"
+  "\xc2\xf7\x98\x07\x56\xbe\xe9\x5b\x5f\x43\x79\xa6\x84\x52\x1d\xf7"
+  "\x46\x7d\x2b\x2e\xc1\x17\x4c\x21\xb8\xa2\xad\x0e\xcc\xf1\x2a\xb1"
+  "\x3e\x0b\x1d\xc4\xaf\x31\xff\x5f\xcd\x14\xba\xdc\xd8\x43\x26\x69"
+  "\x57\xf0\x9c\xc9\xc3\xfe\xe8\x09\xdb\x08\x3d\x97\xec\xd1\xc5\xb6"
+  "\xcb\xb9\x7a\xe5\x56\xac\x69\xcd\x8a\xd3\xcc\xad\x1b\xcc\x7c\x80"
+  "\x3d\xf7\x07\x85\xdb\xf4\x58\xb7\x9a\xc3\xb8\x23\xcf\xd5\x69\xb8"
+  "\x83\xef\x97\x4e\x8c\x17\xcf\x6d\xbc\x38\x5e\x3c\xf7\x43\x55\x47"
+  "\x97\x29\x6d\xf7\x9e\xdb\xa9\xc9\x0a\x7c\xd3\x95\x5b\xad\x45\xa2"
+  "\xfe\xb9\xb2\x6e\xc0\x24\x98\x46\x74\x66\x21\xe0\x56\x82\xbc\xdd"
+  "\x1a\x6d\x20\x1c\x32\x87\x48\x8e\x61\x02\xcf\xf1\x6e\x08\xb4\x47"
+  "\xc6\xc8\xae\x38\x5c\x4f\x3c\xa6\xe2\x6c\x6c\xc6\xfa\xb5\x8d\x6c"
+  "\xd7\x7d\xb1\x87\x2a\xfd\xce\x9d\x89\x1e\x36\xb0\x59\xa5\x7f\x9b"
+  "\x51\x86\x4b\xd8\x82\xc8\xf3\xa0\x26\x9a\xe7\x14\xc7\x8c\xe6\x3a"
+  "\xd2\x92\xd0\x6e\x8a\x69\x06\xde\x7e\xe7\x02\x6d\xed\x57\x9c\x69"
+  "\x04\x6f\xc1\x67\xe8\x89\x8f\x05\xec\x9e\xd6\x2b\xbb\x46\x6e\xb6"
+  "\x30\xea\xf3\xc8\xa6\x59\xbb\x7e\x71\x13\x33\xbc\x6d\x79\x90\xd9"
+  "\xbf\xcd\x92\x4a\xff\xc5\xc0\xfe\x36\x97\xe9\x09\x0e\x1e\xb6\x33"
+  "\x5d\xc2\x6e\x67\x9d\x36\x3e\x1e\xf6\x9c\xa0\xa3\xa4\x3b\x5f\x14"
+  "\xe4\xc3\x72\x2f\x60\x67\xab\x87\xfd\x52\xdd\xf3\xda\x6e\x98\x60"
+  "\x7d\xb8\xdb\xba\x62\x8d\x35\x6b\xf5\xba\x55\xd7\x5e\x1b\x37\x81"
+  "\x0c\xb0\xb3\x53\xca\x00\xcf\xb3\x48\x19\x00\xcf\xe8\x7f\xa3\xe7"
+  "\x42\x9e\x7f\x61\x86\xea\xfe\x20\x23\x95\x85\xef\x6f\x61\x0b\x6f"
+  "\x89\x78\xbc\x95\x2d\xfc\xf6\xad\x19\xf7\x65\x2f\xcb\x5a\x1f\x91"
+  "\x7a\x5b\xa4\x7e\xae\x66\x2b\xea\x8e\x9a\xf5\x7d\xd0\x0f\xdd\xbd"
+  "\x8f\xd1\xba\xf3\xfc\xd9\xa2\x20\xff\x02\xb8\x3b\x97\x7c\x0e\xed"
+  "\xcf\x0f\xb2\xfd\xa0\x6f\xfc\x4a\xa2\xeb\x53\xa4\xdf\x4d\xc8\xff"
+  "\xc0\x2d\x33\xfa\xee\x85\x2c\x76\x56\xda\x6e\xbf\x30\xb3\xab\x2e"
+  "\x00\x3a\xd1\x1b\x94\xfc\xce\xf3\x07\x90\x3e\x0d\xd7\x90\xb4\x3f"
+  "\x79\x41\x07\x39\x37\x4d\xf8\x58\x28\x20\x1f\x0b\xcf\x8b\x35\xe0"
+  "\x26\x5f\x09\x93\xbe\xbe\x9e\xaf\x24\x1f\xdc\x1e\xf6\xc2\x3c\xe2"
+  "\x2f\x28\x2f\xd2\x3e\xb6\x3e\xcc\x52\xe9\x4a\x3c\xaf\x07\x65\xf2"
+  "\xf2\xde\x20\xdf\x96\x4e\x7b\xf2\x29\x28\xf3\x3b\xc4\xb7\x45\x59"
+  "\xa6\xf8\xfd\xce\x17\xe6\x6a\x3c\x08\xd9\x89\x4e\xc6\x7f\x68\xeb"
+  "\x60\x02\xe8\x77\x82\xcf\xcc\x33\xc8\x67\x89\x8e\xa5\xd0\xfa\x60"
+  "\x76\x2c\x16\x67\x8b\x68\x5d\x24\x9a\xd0\x28\x68\xe9\x0b\xb5\x1a"
+  "\x5d\xa8\x96\x72\x64\x1c\x7d\x8f\xf5\xf3\x4b\xb9\x7e\xbe\xd0\xa2"
+  "\xcd\x05\xdc\xef\xd1\x70\xf5\xbc\xf3\x29\xab\xf2\xb3\xf3\xb2\xb3"
+  "\xac\xd7\xad\x89\x63\x11\x11\x22\x73\xb2\x57\x59\xf3\xb2\x1f\x5d"
+  "\x9b\xbd\x46\x08\x68\xf4\xf6\xfc\xbd\x11\xd0\xa0\x70\xbc\x5e\x71"
+  "\x46\xe6\x37\xd7\x92\x0c\x6b\x2e\xbd\x56\xe8\xc1\x05\x6f\x64\xb2"
+  "\xe6\x28\xd5\xf1\x69\x52\x8f\x78\x02\x70\xdd\x25\xfd\x51\xbb\x7a"
+  "\xc9\x7e\x0b\x70\xdd\x75\x9b\xdc\x6b\xff\xcd\x4a\x09\x2b\x63\xb1"
+  "\xdf\xf9\x9b\xac\x30\xbf\xb6\x4b\xd8\xff\x49\x9b\xb7\xdf\x14\x02"
+  "\xc6\x4b\xc3\x3c\xc8\xae\x63\x44\x07\x05\x3d\xfc\x3b\xb4\x50\xe5"
+  "\x9d\x51\xcf\xae\xeb\x79\x01\xef\xaf\x19\x65\x42\x8f\x47\xbe\xdb"
+  "\x25\x7d\xfd\x4d\x8f\x06\x47\xf0\x2f\xfd\xa4\x2f\xd0\x64\xa0\x45"
+  "\xc1\x73\xbc\x68\x3d\xd3\x93\xce\x80\xc7\x1d\x66\xbf\xcd\xf3\xea"
+  "\xb9\xf3\x85\x0e\xf0\x32\x42\x06\x6a\x54\x6d\xbf\x78\x6c\xef\xa0"
+  "\xdf\xb9\xcb\x1a\x96\x0f\x77\xf5\x0b\x3e\x7e\x94\xf0\xe6\x37\xed"
+  "\x19\xb4\x46\x48\xda\x3d\xf5\xef\xb5\x97\xc7\x49\x5d\xb9\xa4\x6f"
+  "\xbb\x32\xd5\x3e\x0c\x11\xcd\x52\x6d\x07\xf5\x12\xaf\x77\xf5\x03"
+  "\xe7\x86\x68\x2c\x40\xe7\x5d\x1a\xbc\xa8\xbf\x42\xee\xdc\xc8\xf4"
+  "\xa0\x5d\xec\xd5\x0d\x01\xbd\x8c\xad\xf8\xc2\x01\x29\xc3\xec\xea"
+  "\x88\xdc\xf3\x91\xb2\xd4\xae\xde\xb0\x5f\x83\xdf\x7c\xe5\x4c\xca"
+  "\xea\x55\x74\x1c\xe5\x91\x8c\x75\xcb\x1e\xc9\xce\x58\x6b\x9f\x6d"
+  "\x5d\xbb\x4a\x6c\xa9\x09\xf1\x3d\x7f\xed\xf2\x47\xac\x44\x45\x32"
+  "\xe6\x2f\x5c\x98\xf1\xfd\xfb\x7f\xf4\x93\x38\xf6\xfd\x65\x48\xcb"
+  "\x5f\x6d\x5d\x98\x3a\x5b\xbe\xba\xef\xee\xbb\x7e\x9c\x71\xd7\xa2"
+  "\xfb\xef\x5d\x32\x81\x4d\xab\x09\x38\x31\x88\x31\x8a\xee\x63\x2f"
+  "\xcf\x91\x36\x0c\x2f\xda\xcf\xb7\x61\x78\x11\xeb\xe7\x8b\x3b\xf1"
+  "\x6b\x63\xec\x65\x48\x33\x2f\xcf\xc1\xcf\xa6\xe2\xcd\x98\xdf\xf9"
+  "\x62\x7d\x18\x6f\x5e\x16\xfe\x75\x49\xe6\x97\x3a\xd3\x17\x41\xff"
+  "\x5e\xf0\x45\xbe\x0b\xd3\x82\x97\x9e\x17\xf4\x52\xc5\x0b\xc2\x87"
+  "\x8c\xa0\x51\xe0\x86\xe4\x57\x5e\xf4\x69\xb8\x21\xce\xc9\x21\x9d"
+  "\x74\x5d\xf4\x1e\xf8\xbd\x84\xf4\xc2\xc0\x85\x41\xda\xcf\xa4\x74"
+  "\x1e\x6f\x5d\xa2\x96\x3b\x9b\xf4\xc4\xc4\xcf\xaa\xfb\x1e\x09\x27"
+  "\xd8\x4b\x2b\xb8\x73\x97\x57\xca\x82\x2f\x5e\x2b\xf0\x66\xd3\xac"
+  "\xef\x8b\xfd\x23\x71\x1e\xe1\xa5\xcc\x30\xfe\xbc\x3c\x87\xc6\x86"
+  "\xe8\x82\xa4\xbd\x2f\x15\x5e\xa0\x7f\x89\x42\x5a\xad\xe6\x07\x3b"
+  "\xff\x5a\xa6\x37\x5c\x5b\xcb\xb6\xe8\x79\x89\x87\xbd\x94\x26\xed"
+  "\xd8\x5e\x6a\xd1\xf8\x67\xdc\x63\xfe\x1f\x4d\xbb\x50\x6f\x55\x1d"
+  "\xa1\xb7\x2a\xb2\xf3\x23\x5d\x76\x2f\xf1\xc8\x6d\x6e\xaf\xf0\xbf"
+  "\x78\x67\x97\xdd\x47\x3e\xfb\xe2\x06\xd8\xcb\xd1\xc5\x21\x3e\x8a"
+  "\xfb\x59\xe8\x9b\x58\x43\x6e\x96\x7a\x03\xc8\x63\x2f\xdf\x26\x65"
+  "\x13\x99\x4e\x70\xf7\xb0\x17\x9b\x49\x36\xa3\xf1\xc1\x7d\x6d\x94"
+  "\x25\xf6\xf6\x89\xe8\x5e\x42\xa9\x5e\xf5\x73\xf3\x72\x39\xc9\xa8"
+  "\x04\xab\xa7\xf4\x4a\xce\x53\x4e\xfc\x70\x25\xda\x17\xe6\x2f\x79"
+  "\x40\xc2\xf6\x65\x57\xbb\x63\x88\xd6\xcd\xc0\xa4\xf6\x85\x05\xbc"
+  "\x57\x1b\xcf\x45\x21\xef\x9d\x34\x5e\x7e\xe7\xcb\x6d\xda\x58\x0e"
+  "\x7f\x63\x65\x6d\x54\x29\xb3\xee\xad\xff\x36\xa5\x63\xfe\xbf\x9c"
+  "\xa6\xda\x4f\xfa\x2e\xfc\x16\x74\x38\x4d\x7e\xdf\xcc\xb4\xef\x2f"
+  "\xf4\x9f\x2a\x0e\xf8\x91\x72\xea\x76\xa1\xc2\xb2\xa9\xe1\x6e\xcf"
+  "\x3b\xab\x43\x67\x30\xdb\x25\x4e\x6a\xba\xb3\x44\xd9\x9f\xe6\x73"
+  "\x4a\x05\xe4\xef\x8a\x03\x7a\x55\x0f\x80\xb9\xdd\xdc\x70\x13\x63"
+  "\xb9\xbe\x75\xe9\xe3\x7a\x12\xd2\x2f\x90\x4f\x34\xb4\xc3\x15\xa1"
+  "\xdb\x1a\xb7\xf1\xf2\xb0\xe6\x00\xd9\x9c\xa0\x1c\x03\x95\x43\xf3"
+  "\x4a\xea\x66\x9a\x5b\xc9\x87\x0e\xca\x5b\x25\xf6\x2e\x9d\xcd\x89"
+  "\x02\xf7\x20\x6b\x0b\x39\xbf\x90\x7f\xa1\xda\x40\x08\xde\x45\x9e"
+  "\xe7\x69\x1e\x1a\xd7\xf7\x88\xb3\x2d\xcd\x39\x64\xd7\xe9\x77\xbe"
+  "\x62\x98\x48\xcf\x07\xfa\x90\xb3\x6c\x55\xd6\xea\x87\x1e\xfa\xfb"
+  "\xa4\x21\xd2\xd6\xb2\xd6\xa9\xb8\x50\x26\xe4\xdf\x2d\xe9\x12\x4f"
+  "\x5f\x01\xfd\xaf\x90\xbc\x2e\x78\x18\xcc\x9b\xab\x4e\xb0\x57\xda"
+  "\x34\xfe\x5d\xce\xa3\x57\x3a\xb9\xf3\x95\xc4\xf0\xdc\x78\xa5\xee"
+  "\xab\x73\xe3\x95\xe6\x89\xe7\xc6\x2b\xdd\x58\x67\x7b\xf1\xbe\x13"
+  "\x75\x76\x0a\x9a\x4f\xe3\x2d\x79\xf0\x36\x73\xf0\x4e\xc1\x83\x67"
+  "\xac\x67\x3a\xe2\xbf\x49\xa7\x4c\xeb\x41\x08\x72\x6d\x08\x34\x22"
+  "\x23\xc8\x12\x69\x2d\xa8\x59\x45\xfa\xc2\x6b\x78\x70\x84\x7b\x32"
+  "\xd6\x83\x5e\xe0\xb9\xfa\x84\xdc\x67\x7d\xe0\x2c\xe4\x10\xdc\xd7"
+  "\x0c\x10\xad\x50\xc8\x59\x3b\x93\xeb\xf5\x6f\xd3\x34\x1e\xd7\x5c"
+  "\x6a\x15\x3e\x7c\xc5\xba\x0d\x3c\xa3\x75\x3b\x23\x64\x6e\x93\xeb"
+  "\xf6\x6f\x73\x2e\xaa\x9b\x8e\x8f\x4d\x9c\x28\x1d\x6d\x6c\xa7\x76"
+  "\xa1\x9d\x2d\x68\xd7\x6e\x6a\x4f\xf5\x43\xd4\xaf\xa8\x5b\xcd\xc1"
+  "\x54\xb1\x37\x40\xed\x7c\xc0\xc7\x6e\xa5\xf6\x3d\xf0\xe8\xad\xac"
+  "\xf1\x21\xda\xdf\x95\x76\x3d\x2a\x2e\x19\x80\x33\x53\x06\xd8\xab"
+  "\xc9\x3e\x11\x53\xf1\xb7\x18\x7b\xa3\xe4\xeb\xd5\xbd\x13\xca\x43"
+  "\xef\x24\x9e\xbe\x9a\xbc\xd7\x41\x6d\x7e\x35\x59\xcb\x17\xd9\xb6"
+  "\xbb\x96\xd9\xc1\x58\xae\x78\xe8\xa1\xec\xbc\x35\x5a\x7c\x68\xdb"
+  "\xea\xdc\xac\x3b\xd4\xf3\xae\xab\xb2\xd7\x65\xac\xc8\x12\xf6\xf4"
+  "\x48\x95\xb7\x17\xf0\x1a\xb3\x49\x16\x10\x36\xaa\x82\xcf\xf8\xfd"
+  "\xb9\x46\x95\xe7\xe8\x63\x2d\x2e\xb9\xff\xdc\xf2\x3d\xb9\x0e\x4c"
+  "\x7d\x14\xed\xd8\xa9\xad\x03\xa4\x8f\x18\x66\xd7\xda\x68\x5f\x88"
+  "\xce\x30\xd3\xfe\x13\xe9\x24\x90\xa7\xc3\xc3\x7e\x9b\xaf\xe1\x76"
+  "\x15\xd2\xe9\xdc\x44\xdb\x2a\xb2\xb5\xdb\x3d\x53\x29\x3f\x18\xe4"
+  "\x71\x7b\x5b\x40\x03\x84\xac\x43\xfb\x21\xd2\x1f\x7f\x4b\x12\xd1"
+  "\x36\xd2\x9b\xb5\xad\x22\xdb\xb5\x57\xfb\xb1\x96\x83\x07\xde\x9d"
+  "\xec\x8d\x3d\x18\xdc\xbc\x81\x19\xa9\x0e\xac\x1b\x1e\xa9\x67\x6d"
+  "\x49\x7d\xab\x90\x31\x75\xed\xf0\x54\x09\x9d\xe2\xab\xd2\x67\xa2"
+  "\xeb\x50\xa2\xaa\x73\x48\x44\x3e\xe0\x7f\x3c\x93\x6d\xde\xdb\x23"
+  "\xf6\xbd\x04\x5d\x68\x29\xe4\x15\xed\x39\xc2\xbe\xb0\x62\x6f\x8f"
+  "\xc2\x73\xa2\xe8\x19\x74\x39\x0e\xe5\xec\xe4\xc5\x36\xa6\xda\x24"
+  "\x46\x0d\xb0\xdf\x45\xe3\x6a\xc0\x78\x6c\x21\x58\xa0\xfc\x64\xb5"
+  "\xfc\x64\x94\x8f\xf5\xef\xca\x5a\x39\xbf\x5a\xda\xb5\xba\x80\xdb"
+  "\xa4\x93\xe9\xa7\xf5\x0b\xed\xf7\xe1\x17\x90\xfa\x99\x00\xe4\xa4"
+  "\x6b\xc6\xf5\x33\x92\x47\x6a\x09\x6a\x38\x49\x75\xab\x7d\xb0\x90"
+  "\xcf\x17\xd2\x27\xa8\x75\x59\x48\x57\xa0\x95\xc9\x51\x26\x1f\x19"
+  "\x6a\xc2\x5a\x63\xc4\x1c\xf3\x26\x94\x62\x4d\xa1\x3a\x88\xc7\xf5"
+  "\x5d\xc3\xb1\xe6\x84\x32\x42\x06\x79\xde\x7c\x3d\x8b\x8f\xe4\x6f"
+  "\xfd\xce\xdf\xe5\x86\x79\x32\x94\x31\x02\x5a\x56\xc4\x4a\xfa\xd9"
+  "\xef\x84\xff\x33\xb2\xe7\xa0\x71\x1d\xc5\x38\x61\xac\x5a\x51\x4f"
+  "\x0b\xf8\xf2\x78\xc0\xe1\x45\x1a\xaf\x6a\x05\x73\x6e\x54\xf0\xea"
+  "\x66\x8a\x9d\xde\xc7\x7e\xf7\x34\x8d\x15\x95\xc5\x5d\xed\xae\xa0"
+  "\x3f\xfd\xdf\xc9\x2f\x15\xc1\x7a\x63\x21\x1f\xa4\x3d\x3a\xe0\xd6"
+  "\x4c\xe2\x61\xc1\xd7\x8b\xfb\xe2\x2c\xae\x88\xb1\x16\x76\x8a\xbf"
+  "\x9f\xb9\x71\x90\x2b\xe7\x9c\x8c\x77\x80\x96\x9e\xd3\xb3\x60\x00"
+  "\x32\x28\xda\xad\x2f\x3e\x49\xbe\xb3\x9a\x30\xbf\x5c\x0c\xf5\x1a"
+  "\xab\x37\xb0\x44\xf2\x35\x56\x6c\xe7\x81\x2e\x5f\x3d\xeb\xb2\xd7"
+  "\xb3\xf7\x82\x5b\x58\x5b\x01\xe9\x34\x7f\xdf\xf6\xbe\x63\x0b\xd9"
+  "\x85\xc7\xe2\xbe\xd4\xfa\x63\xaa\xeb\xbf\xd3\xdf\x3f\xf0\x21\x7b"
+  "\xbf\xed\x43\x66\xfd\x2f\xf1\x9c\xd3\x99\xfe\x1e\xeb\x4c\x7b\x8f"
+  "\x15\xf7\x73\x85\xf8\xa1\xa2\x95\x54\x87\x0b\x65\x35\x91\x8f\xae"
+  "\x44\x65\xd8\x12\x87\xfe\x1b\x16\x39\x98\xd8\x07\x6c\x5b\xf5\x67"
+  "\xb4\xf1\xbf\x8f\x37\x9e\x61\xc6\xb6\x55\x7f\x11\xf7\x42\xbf\x80"
+  "\xfe\xba\xb3\x7a\x84\x8d\x18\xf9\x24\x73\x3b\x06\xe9\x7c\xa5\x52"
+  "\x43\x6d\x0c\xc9\x76\x03\x5e\x06\xed\xfb\xed\x45\xe3\xdf\x0b\x5f"
+  "\xb1\x0d\x04\x0f\xb4\x69\xff\x12\x09\x93\xce\x1e\xc0\xf4\xc7\x2a"
+  "\x7c\xd2\x23\xe1\xf3\xdf\x46\x82\x0f\xd9\x7f\x2a\x05\x43\x4d\x68"
+  "\x5b\x1a\x60\xa0\x68\x75\x10\x0e\xd0\x7e\x15\x95\x5f\x7d\x86\x99"
+  "\xda\x56\x91\x7d\xe8\xef\x57\x9a\x17\x1b\x8c\xca\xc8\xc9\x96\x9a"
+  "\xb3\xcc\x40\xe3\x46\xeb\x6c\x8d\x78\x2f\x60\xbe\x98\xc6\xcc\x1b"
+  "\xfb\x11\x70\xea\x23\xe0\xe7\x47\xa4\x87\xd8\x89\x6b\x10\xe3\xe5"
+  "\x02\x9c\x06\x31\x56\x4d\x74\x95\xf8\xb8\xcf\x46\xfe\x1a\x69\x2d"
+  "\x03\xae\x84\xd3\x2b\xf6\x7d\x33\x88\xb9\xa3\x08\x39\xed\xbf\x07"
+  "\x95\x72\x4f\x8f\xb4\x15\x7c\xd5\xd6\x00\xbe\xb8\xfe\x49\x71\x1e"
+  "\xdd\x04\x5e\x5e\xac\x8b\x5b\xc5\xb9\x95\xdf\x8f\xaf\x7f\x15\x22"
+  "\x96\xf9\xef\x2d\x7a\x61\x13\x76\x28\x49\xc5\xf5\x24\xbf\x73\x37"
+  "\xe6\xfe\x0c\x55\xae\x6e\x11\x67\x5a\x88\x0e\x4c\xc6\x93\x80\x2e"
+  "\x77\x92\x8d\x1d\xbf\x32\x9d\x99\x74\xdc\x6b\xca\x34\x73\x77\xb0"
+  "\x9d\x70\xc8\x24\x70\x5f\xbe\x03\x1f\xe9\x35\x83\x96\x77\x23\xdd"
+  "\xa0\xa5\x13\x5d\x57\x20\x5b\x92\x5c\xbb\x68\xbd\x99\x17\x9d\x65"
+  "\xc9\x42\x47\xa4\xa5\xaf\xf7\x9a\xbb\x2c\x8c\x6c\xee\x83\xe4\x87"
+  "\x82\xbe\x41\x7a\x14\xd6\x81\x3d\xa8\xb7\x0d\xf9\x93\xb4\xfc\x7c"
+  "\x38\xdd\xe0\x76\xb4\x8b\x79\x46\xbe\x95\xb4\x75\x01\xe9\xd1\x8b"
+  "\x1c\x5e\xb3\x18\x33\x2d\x6d\x4d\xba\x58\xc7\xe8\xcc\x3b\xf8\x54"
+  "\x2e\xda\x33\x20\xd2\x75\x90\x33\x45\xac\xf4\x88\x34\x3d\xf9\x17"
+  "\x20\xbf\x78\x11\x69\x51\x68\x33\x1b\x7f\x46\xdd\x35\x0f\x8b\x7d"
+  "\x7a\xcb\xa2\xf5\xb4\x27\x86\x7a\x1e\x56\xeb\x5e\xcf\x99\xf4\xb7"
+  "\x29\xd3\xe4\x9a\xf9\x87\xfc\x48\x19\x97\xf6\x28\xa8\x6e\x65\x38"
+  "\x5d\x1f\x1a\x4e\x8f\xa2\xfa\xa9\x2c\xd2\x4f\x8a\x98\xed\xc1\x41"
+  "\x46\xbe\x9e\x79\x95\xd5\xce\xe9\x8c\x05\xca\x15\xed\x71\x40\xfe"
+  "\x8f\xb7\x4e\xec\x57\xa0\x32\xc1\xd6\x56\xf4\x5f\xc0\xe9\x3f\x16"
+  "\x12\x4d\x09\x19\x7b\x4c\xd6\x87\xc9\xee\xe0\x0f\x67\x69\x4c\x43"
+  "\x98\xe7\xa1\xd8\x1e\xd3\xcd\x83\x4c\x57\x84\xb9\x23\xf7\xea\xfe"
+  "\x38\x9d\x78\xaa\x62\x85\x73\xdc\x1b\x09\x77\xcd\x43\x90\x5b\xca"
+  "\x7b\x12\x85\xbd\x47\x42\x9c\xd5\x1d\x18\x64\x9d\x25\x9f\xb2\xce"
+  "\xa0\xbb\x64\xcf\x19\xaf\x41\xda\x7d\x18\x50\xee\x1f\xaf\xa7\x77"
+  "\xc5\x98\x2f\x19\xa1\xa6\xc9\xe5\x40\xc8\x16\x80\xdd\xe7\x72\x2d"
+  "\xf8\x63\xa1\x26\x4f\xfc\x9d\x3e\x1c\x20\xdf\x86\x64\x17\xa7\x54"
+  "\x0c\x2e\x46\x5b\x8a\xb9\xdf\xc6\x6e\xde\x40\x7a\xdd\x3f\x36\x27"
+  "\xf8\x58\x9a\x5a\xee\x97\x6a\xb9\x07\x2e\x56\x2e\xe1\x6d\x67\x9d"
+  "\xb4\xb5\x50\xe2\x06\xd3\x42\x28\x3b\x14\x37\x58\x82\xb5\xa6\xb8"
+  "\xf8\x1c\xe9\x4e\x5a\x67\xa2\x9e\xb4\xae\x60\x37\x23\x1f\xa9\x8d"
+  "\x0a\xd6\xeb\x2f\x2d\x4c\xb5\x71\x29\x3e\xc5\xfe\x14\xad\x70\x5b"
+  "\x22\xe4\x1c\xd2\x95\x16\x13\x9d\x25\xdd\x73\x51\x88\xc5\xb8\x31"
+  "\xb2\xe4\xe3\x0f\x65\xc4\xef\x23\xbd\x34\x68\x55\x88\x5b\xf4\xaf"
+  "\x8f\x78\x58\x0d\xe8\xb7\xf0\xf9\xb7\xe9\xca\xad\x09\xa5\xec\x4e"
+  "\xae\x37\x0b\x1b\x26\xac\x2f\xe9\x18\x5b\x87\x68\x4f\xc5\xa1\x94"
+  "\x08\x7b\x9a\x28\xd4\x55\x4e\xf6\x34\xdc\x78\x70\xb0\x9e\xd6\x4c"
+  "\x8c\x99\xdf\xf9\xa7\xdd\x1e\xf6\x07\xc1\x97\x54\x92\x1e\x40\xd0"
+  "\xf9\xd6\x6b\xbd\xb1\xfd\x56\x2a\x83\x7c\x01\x29\x05\xc1\x96\x9a"
+  "\xd3\xe0\x7b\x04\x3c\x5a\x75\x5d\x43\xfe\x36\xee\xea\xb7\xd2\x3c"
+  "\x52\xcb\x36\xa3\xec\x0f\x78\x79\xbf\xd5\xc3\x5a\xad\x92\xd6\xd0"
+  "\xfd\x9f\xc4\x5e\x47\x70\x8c\xce\xe1\xfc\x29\xa7\x7e\x94\x74\x72"
+  "\x7f\x02\x5d\xb9\xa6\x6d\xd8\xd8\x6f\xfd\x91\xa5\x04\x3c\x40\xeb"
+  "\x1c\x8f\xee\x53\x71\xb6\x4d\xf3\x5f\x38\xd9\x1e\x14\xdf\x66\x89"
+  "\x73\xa3\x10\xf0\xb8\x49\x27\xd8\x9f\x9f\x1f\x85\x9c\x3f\x86\xb5"
+  "\x75\x14\x72\x02\xdf\x96\x6e\xaa\x9e\xc5\x52\xf1\x6e\xd6\x09\xd6"
+  "\x5a\x1e\xd4\xb3\x24\xfc\x12\xbd\x57\xe6\xc4\xa2\xdc\x34\xd2\x7f"
+  "\xee\x3f\x43\xfb\xae\xad\x82\xee\xd7\x6c\x65\x29\x0a\xca\x23\xbd"
+  "\x6b\xcd\x2c\x96\x42\x3a\x57\xa4\xd9\x32\x42\x72\x4f\x42\x93\xa9"
+  "\x36\xcd\x62\xb3\xcf\xaf\xb7\xd5\x2e\x65\xb9\x3f\x8b\x35\x7e\x9d"
+  "\x97\x5d\x6d\xff\x2e\xef\x1b\x60\xaf\x65\x71\x67\x14\xe7\x57\x5a"
+  "\xf4\x52\xa6\x78\xed\x1e\x73\x9d\xc4\x3b\xa1\x83\x07\xbe\xd1\x1e"
+  "\x87\xaa\xdb\xd5\x09\xbf\x8d\x71\xbd\xf5\x74\x0e\x42\xa4\xe9\x12"
+  "\x09\x96\x89\xa2\x1d\xaa\xcf\xb5\xd0\xa6\x1b\x28\xb6\x9b\xf0\xb5"
+  "\x96\xb1\x4c\xea\x85\xc9\x1f\x1b\x60\x2c\xce\x83\x55\x6e\x65\xa6"
+  "\x27\xb6\xb2\xc4\xfd\x0f\x51\xbf\x5e\x2b\x94\x73\xd1\xc0\xa8\xbd"
+  "\x8a\x8b\xe6\x19\x70\x02\xed\xa6\xfa\x08\x37\xba\x82\x5f\xb6\x15"
+  "\xe7\x73\xa5\xed\x61\xf2\x05\xf0\xda\xeb\x6d\x79\xcd\x6c\x11\xf9"
+  "\xaf\x23\x1f\x36\x4b\x99\x77\x3b\xca\xdb\x3e\x8b\x25\xa2\xac\x77"
+  "\xdd\xb9\x44\x6b\x2d\x5f\x6b\xcb\xdb\x4d\x65\x1f\xa6\xf5\xa8\x0a"
+  "\xf0\x91\xeb\xd2\x9f\x6b\xdd\x81\x1e\x46\xfe\xea\xef\xb5\xf3\x10"
+  "\x95\x33\xc0\xfe\x3c\x5d\xf4\x77\x9b\xc5\x9a\x21\x7d\xe6\x89\xbe"
+  "\x8e\xeb\xdb\xd5\x7e\xb8\xcf\x50\x79\x7f\xb6\xb9\x33\xc1\x73\xaa"
+  "\x7d\xd2\x60\x2d\xf1\xeb\xcf\xd9\x6d\x79\x3b\x19\x8d\x0f\xe5\xc7"
+  "\xf3\x12\xf7\x10\xf2\x9e\x3c\x7f\x5c\x28\x0f\xde\x3d\x8e\x72\xff"
+  "\x35\xbc\x8f\x44\xfb\x1b\xe1\x3c\xf5\xe8\x0f\x60\xd5\xb1\x0d\x30"
+  "\x92\xfa\xb5\xd7\x4e\x53\x5b\x3d\xec\x35\xaf\x3b\xff\xd3\x89\xcf"
+  "\x1f\x61\xee\x03\xef\x4b\xbb\x84\x6e\xe9\xcf\x47\xee\x0d\x2a\x5c"
+  "\xd2\xb3\xff\xd9\xa2\x80\x0e\x78\x70\x25\x5a\x20\xe8\xc9\x4d\xb4"
+  "\xf7\xfb\x3f\x4f\x9b\x75\x72\x7c\xa9\x2f\xc4\x33\x4d\x34\xc6\x11"
+  "\x7a\xfd\x44\x6a\xab\x36\xc6\xdc\x94\x60\x53\x68\xbf\x66\x16\xe0"
+  "\x3d\x66\x61\x12\xff\x78\x2d\xca\x7d\x5c\xe5\x21\x73\xd4\xf5\x34"
+  "\x67\x38\xb6\xc7\xc2\x1f\xb3\x30\xcd\xd6\x0e\xf3\x37\x29\x43\xda"
+  "\x2f\x5a\x88\x46\x6d\xd7\xcb\xb9\x43\x6d\x54\xbf\xcd\x92\xfb\xc8"
+  "\xff\xb3\x04\xdf\x67\x4d\xd8\xdf\x28\xd0\x1d\x27\xc8\x34\xfa\x23"
+  "\xce\x05\x80\x56\x61\x3d\x88\x71\xfb\x46\x99\xdc\xdb\xde\x33\x8d"
+  "\x62\xc7\xd3\x99\x30\xad\x6d\x97\xa6\x83\xff\x9f\x5e\xa9\x83\xdf"
+  "\x93\xac\xc9\x9b\xdc\x04\x18\x3b\xcd\xc2\x77\x39\xf8\x2e\xc5\x17"
+  "\x9f\x90\xea\x8d\xb7\x66\xca\x79\xb3\x67\x3e\x8f\x97\xf4\x36\x23"
+  "\xc0\x4a\xa8\x5f\xaa\xdc\x15\x43\x7d\x46\x39\x59\xda\x5e\xb0\x56"
+  "\xf6\xa4\xf1\x00\xb4\xbe\xa1\x4f\xa2\x6f\xe8\xa3\xe8\x1b\xf9\xc3"
+  "\x90\x7d\x13\xe7\x71\x2f\xad\x3f\x7b\x64\x8c\x80\xca\x84\xd4\xb6"
+  "\x59\x54\xc6\x1b\xeb\x85\x2d\x3e\xc6\x04\xf4\xe1\x8a\x13\xec\xf5"
+  "\x39\x3c\xee\x89\xb8\x4b\x2b\xf3\x75\x26\xcb\xb4\x66\x3e\x0d\x1a"
+  "\x2c\xcf\x07\x91\x0d\xcb\x1b\xcb\x40\xcb\x33\x49\x86\x19\x46\x7d"
+  "\xc0\x8f\x08\x3a\xf4\x7a\x3f\x8d\xd5\x4d\xcd\x2c\x4d\xe2\xe1\xeb"
+  "\x9f\x90\x5e\x42\xc6\x6b\x79\xdd\x05\xbc\x17\x67\xf0\xc2\x76\x99"
+  "\x3a\x61\x97\x19\x49\x63\x2f\xb1\x8d\x52\xa6\x49\x30\x62\xfe\xbc"
+  "\xee\x10\x76\x3a\x68\xef\xba\xa0\x46\xff\x5e\x77\x70\xd2\x0d\x17"
+  "\xa9\x3a\x42\xa2\x65\x45\xd2\x9f\x96\xdf\xf9\x86\x65\x5c\x47\x48"
+  "\xe7\x27\x9d\xbc\x83\xf2\x61\xec\xbf\xa4\x3c\xd2\xdf\xcf\x09\xf5"
+  "\x6c\xe1\x1b\x37\xaa\xe7\x06\x6d\x64\x8f\x84\x6f\x97\x78\x58\xdf"
+  "\x6e\xa1\xcb\x01\x0c\xa8\x6e\xd1\x76\x3d\xe9\x03\xdf\xb0\x87\x75"
+  "\xb2\xaf\x8b\xf3\xdc\xf2\xec\xef\x1b\x2e\x0d\x47\xd0\xdf\x18\xe9"
+  "\xa3\x7f\xcf\xe9\xbd\xb3\x99\xc0\x81\x61\x6e\x89\xfb\x7a\x3d\xe1"
+  "\xe4\x1b\x2d\x91\x70\x5a\x14\x54\x8a\x25\x0d\x7a\xbd\x8e\x8b\xb9"
+  "\xfe\x7a\xdd\xdf\xe7\x27\xde\x8c\xd6\x78\x11\x09\xe7\x44\xc0\xe7"
+  "\xad\x6e\x01\x6b\x57\x7b\x07\xf9\xd5\x7c\xac\x88\x7c\x03\xbf\xb9"
+  "\x8f\xfc\x2e\x07\x5d\xed\x83\xa1\x62\x0b\xc5\x74\x61\x8a\xab\x3d"
+  "\x30\x60\x67\xfa\x0c\x3b\xe9\xa1\x8f\x7a\x49\xc6\x83\xcc\x9a\xc8"
+  "\xe3\xc0\x9f\x60\x9e\x6f\x5c\xc1\xcc\x3f\xcb\x41\xd9\xc5\xb6\x24"
+  "\xf2\x8b\x4c\x3e\x91\xc9\xaf\x79\xa8\xd8\x76\x19\xee\x67\x80\x9f"
+  "\x4b\xe4\xc6\xf6\x1e\xda\xcb\x0e\x39\x39\xe8\x71\x2f\xf9\x66\xd6"
+  "\xbb\xbd\x01\xb6\xf1\x24\x33\x92\xdf\xe5\x60\x79\xbf\xb1\xcb\x77"
+  "\x58\xc8\x37\x09\x76\x96\x04\xfe\x23\x19\x30\xb7\x28\xb1\x47\x21"
+  "\x33\x1c\xf5\xc9\x7e\x7f\xc9\x65\xbf\x65\xbb\xa9\xfd\x82\xc6\xb9"
+  "\xde\x0e\x14\x89\xb6\xbf\xb5\x22\x88\xf2\x15\xd7\xfb\xbe\x90\xeb"
+  "\x7d\xaf\x3c\xbf\xda\xc9\x8a\xf2\xf9\xa0\xdb\xd7\x09\x99\xeb\xac"
+  "\x88\x43\x45\x7b\xe5\xd4\x47\xea\x1f\xd5\xfd\xfe\x99\x93\xc2\x8f"
+  "\x74\x10\xcf\xc5\xb9\xea\x37\x43\xf8\x66\xa8\x93\x8d\xba\xde\x17"
+  "\x7d\xef\xf2\xc9\x6f\x33\xc4\x3d\x7d\x1f\x01\x07\xb5\xcf\xe3\x70"
+  "\x40\xdf\xa9\x7f\xd4\xff\x20\xc1\x04\x30\x50\xfb\x6a\x19\x53\xfb"
+  "\x49\x7d\x7c\x0f\xab\xce\x56\xf4\x13\x7d\x15\xfd\x1c\x43\x3f\x3b"
+  "\x72\x18\x0b\x54\x27\xa4\x9d\x8b\x7b\xdf\x4b\x32\x6a\xf1\x07\xe0"
+  "\xe1\x0b\x6b\x19\x64\x51\xc3\x2b\x45\xb5\xfa\x0a\xf0\x26\x45\x5e"
+  "\xc8\xa4\x5e\x3e\x48\x76\xaa\x6e\x3b\x7e\xc1\x7a\x46\x3c\x8e\xc6"
+  "\xaf\xa3\x6e\xcb\xfb\xca\x31\x56\x34\xc8\x07\xc1\x9b\x06\xdc\x41"
+  "\xe4\xc9\x41\xff\x21\xc3\x0e\xa8\xed\xa7\xbc\x1b\x4f\xcb\x7e\x99"
+  "\x73\x59\xd2\x9b\xff\xe5\xd2\xbb\x7b\x5c\x4c\xeb\xcb\x03\xc8\x87"
+  "\xfe\x58\x50\x96\x88\x43\xa3\xa0\x9f\xdb\xd0\xce\x40\x44\x9f\xf6"
+  "\x0f\x91\xad\xec\xc7\x2c\x6e\x31\xd3\x6d\x3d\x85\x7e\x9c\x62\x96"
+  "\xda\x22\xf0\x5f\xf7\x11\xbf\xd8\xb6\x63\x6a\x3a\x4b\xf1\xb0\x37"
+  "\x65\xbc\x56\xe9\xe7\x75\xfa\x09\xf6\xd6\xbb\x9a\x2f\x57\x85\x7c"
+  "\x61\xc7\xf6\x9b\x08\x8f\x84\x5f\x57\x5a\x33\xfc\xc0\x19\xda\xd3"
+  "\x5e\x87\x3a\xfc\xb6\x19\xa2\x3d\x4e\xe9\x0b\x16\xcf\xc4\x93\xd3"
+  "\xd9\x30\x1d\xbe\x33\x72\xc0\x8c\xca\xe7\xe5\x47\x7d\x74\x25\x18"
+  "\x4e\x68\x57\xfa\x5b\x36\x17\x75\xa6\x90\xfc\xdd\x52\xe4\xd5\x3f"
+  "\xfe\x5b\x36\xfb\xd2\x68\xca\x5b\x81\xc9\xe8\x37\xe9\x32\xa9\x3c"
+  "\xf4\xed\xb2\x13\xec\x2f\x87\xcf\x9f\x63\x56\x41\xcb\x24\x1d\xfc"
+  "\xcb\x4e\xd2\x15\x5e\x5a\xbd\x7f\x11\x3c\x1c\xd9\x23\x5c\xe2\x77"
+  "\xbb\xb4\x76\xe0\xfe\x2b\x76\x44\x5a\xdb\x2f\x1d\x0e\x7b\xd9\x64"
+  "\x65\x55\x3d\x23\x6c\x06\x8b\xab\x9f\x01\xbd\x00\xaf\xb0\xd7\x42"
+  "\xfb\x0e\x58\x3b\x77\xfa\xd8\x9a\x06\x66\x2c\x3e\x49\x7a\xa1\x7b"
+  "\xd8\xde\xfa\x54\xd6\x78\x86\xfc\x33\xd9\x2e\x7b\xea\x0c\xc6\x52"
+  "\xa5\x21\xc4\x93\x92\xce\x95\xaf\xb1\x25\xd6\x3c\xa3\xf1\xf0\x7b"
+  "\xdf\x2d\x3c\xcb\xf4\x32\xf6\xf7\xde\x8e\xf9\x56\x1e\xdc\xa2\x57"
+  "\x72\xea\xc9\xcf\x71\x82\xd1\x4e\x7e\x8e\x35\xbf\xbf\x82\xf7\x71"
+  "\x60\xce\x0d\x5b\xe2\xaa\xf2\xd8\x6c\xf2\x51\x6e\xf6\x4a\x5e\x4e"
+  "\xae\xd7\x7b\xc9\x76\x33\x51\xf5\x05\x9c\xa8\xfa\x02\x4e\x23\xbb"
+  "\x6a\xf9\xbe\xfd\xfa\x10\x64\x18\x51\x6e\x1e\x4b\xa9\x3f\xc3\x6c"
+  "\xc4\x07\x65\x1c\x93\x3c\x1b\xc9\x85\xf7\x0c\x99\x79\xe8\x6f\x36"
+  "\xd6\x70\x22\xec\xc3\xdc\xbb\x86\xfc\x9e\x73\xcb\x64\x36\xc2\x35"
+  "\x33\xc4\xde\xbb\xf0\x4b\x49\x3a\x79\x3c\xb3\x2d\x4f\x32\xc3\x5e"
+  "\xb2\xe3\x6b\x92\xe7\x8d\xf6\x06\xa5\x4d\xab\xdf\xd9\x5e\xa7\xf9"
+  "\x78\x9e\x74\x6f\xd9\x25\xe5\x1d\x25\x06\xf2\x97\xd7\xdf\x26\xfd"
+  "\xfd\xb5\x7b\xdc\x9b\x95\x08\x19\xa7\xfd\x2d\x7a\x47\x69\xe4\x43"
+  "\x29\x4d\xc0\x72\x9f\x91\xe4\x1e\x55\x66\x7c\xd3\xaa\xa5\xa9\x32"
+  "\xa3\xb0\x2b\xb6\xc8\xbd\x32\xac\x4d\x09\x7e\xe7\xbe\x14\x6d\x3d"
+  "\xa3\x75\x5d\xea\x86\xf7\xcd\xf5\xe8\x7a\xe7\x5d\xa4\x7d\x89\xaa"
+  "\x1d\x34\xed\x73\xa4\x21\x7f\x8e\xb6\xbe\x89\xfd\xce\x4d\xb3\xbe"
+  "\xbf\x66\x3d\x4b\xfe\xd1\x4c\x23\xa3\xbd\x32\xe4\x1d\x94\xeb\xee"
+  "\xbe\xda\xb0\x3e\x3d\x4d\xc0\x9b\xce\x03\x0b\x19\x83\xfc\xec\x49"
+  "\x7f\xe5\x43\x9a\xbf\x3d\xb9\xfe\xee\x7b\x25\xa2\x9e\xee\xf1\x75"
+  "\x14\x75\x90\x9d\x35\x95\x2f\x79\x93\x7d\x9b\xc5\x99\x31\xe4\x93"
+  "\xeb\xeb\xbe\xcd\x17\xe1\xc5\x6c\x04\x5f\x45\x95\x27\xdd\x43\x5f"
+  "\x48\xf8\x3a\x58\xd4\xcd\x5b\x98\xe5\xcd\x22\x8f\x21\x41\xfa\xd1"
+  "\x35\xf7\xb1\xb7\xaf\xa5\xf7\x84\xeb\x6d\x37\x91\x3e\xf0\xed\x8d"
+  "\x6e\x5a\xb7\xc7\xd2\x4d\xf7\x92\xac\x2f\x78\xf1\xb7\x73\x6f\xc4"
+  "\x77\x48\xbb\xec\x8d\x53\x01\x43\xcd\x06\x36\x5b\xfa\x2d\x7c\x5b"
+  "\xc4\x06\xf6\x5e\xf1\x88\xff\xeb\x49\xcc\xf2\xf5\x2d\xcc\xe6\x77"
+  "\xbe\xbd\x05\xf2\xa5\xf0\xc9\x29\xea\xaf\xb6\xd6\x92\xaf\xf6\x57"
+  "\x47\x3d\xd1\x72\xac\xde\xb9\x05\xcf\xb6\xf0\xf3\xdb\xfb\xd5\xbd"
+  "\x14\xf4\xfd\x9d\xd4\xed\xa7\xa4\xbd\xb8\xd0\x2f\x55\xc6\x26\x86"
+  "\xf7\xea\xdf\xb9\x45\xb6\xe5\x9d\x5b\xf6\x82\x9a\x34\x3c\xc3\x0f"
+  "\x34\xce\xe0\xdd\x7e\xe7\x3b\x06\x0f\xdb\x37\x5f\xd5\xc7\x74\x0b"
+  "\xbc\x22\x7e\xb7\x8c\x64\xb0\x2f\xda\xaa\x90\x8f\xd6\x09\xf0\x47"
+  "\x69\x82\x87\x07\xaf\xab\x00\x7f\x22\xfa\xdf\x40\xfa\xc6\x09\x69"
+  "\xe2\x56\xc6\xc4\x37\x55\xc6\x1c\x61\xfb\x51\x65\x1d\xc4\x15\xb8"
+  "\x16\x97\x88\xab\x09\x38\x67\xc5\x35\x11\x57\x0b\xae\x49\x78\xdf"
+  "\x4d\x78\x09\x19\xd6\x42\xf1\xe6\x86\xe3\x8d\x99\x93\x9d\xfd\x21"
+  "\xd8\xb8\x37\xff\x98\x49\xfb\xb6\x8e\x24\x8a\x35\xb6\xa8\x81\xb1"
+  "\x35\x41\x3e\x6a\xbd\x9a\x4d\xe9\x43\x5a\x71\x03\xed\x3b\xbf\x33"
+  "\x78\xfe\xbe\x73\x87\x11\xbf\x05\xf8\xd5\xe3\xd7\x89\x5f\x52\xf8"
+  "\xf7\xae\xd1\xef\xec\x48\x02\x1c\xa5\x3f\x88\x4b\xa2\x89\x1d\xe2"
+  "\xbc\x78\x0d\xc9\x45\xb1\x83\xa9\x6a\x7f\xd3\xf0\x6c\xe4\xf1\xd6"
+  "\x12\xb5\xbf\xa9\x78\x4e\xb4\x16\x63\x5d\x8b\x07\x4c\x66\xa1\xcf"
+  "\xf1\xd6\x41\xea\x2f\xb5\x77\x38\x3e\x2e\x31\xf2\xdc\x13\x95\x49"
+  "\xfd\xf7\xc6\xc7\x52\x79\x8c\x7f\x63\x65\xad\x06\x4f\x15\x4e\x74"
+  "\x26\x44\x3f\x8c\x32\x24\x1f\x84\xfc\x28\x43\xcb\x3f\x0e\x7b\xe4"
+  "\x13\x72\x22\xf2\x41\x26\x36\x6a\x67\xaa\xfc\xce\x77\xd9\x5b\xb9"
+  "\x72\x3f\x83\xbe\xf5\x45\x7c\x4b\x7e\x3e\x26\xfa\x1e\x75\x1a\x65"
+  "\x9d\x71\x90\xbb\x3b\xa6\xab\xf5\xfa\x26\x9b\x4b\x45\xd7\x82\xbf"
+  "\xab\xf7\xd0\xf9\x1f\xe2\x87\xe6\xb9\x93\x7d\xcc\x5d\xaf\x30\xa5"
+  "\x3a\x36\x2d\xad\x88\xb7\x0d\xb0\x77\xff\xd0\x15\x18\xbc\xc4\xf5"
+  "\xf0\x5d\x29\x8b\x8e\x96\x30\x77\xe1\xb7\x85\xbd\xfa\x29\xf6\xde"
+  "\x31\xb7\x57\x9c\xad\xa5\x7b\xe1\xf3\x99\xf6\x9b\x69\x6d\x20\x1f"
+  "\xf6\x9a\x8c\xad\x20\x6f\x23\xa5\x23\x8d\xce\xff\x6f\x8f\x78\xc7"
+  "\xab\x8d\x0b\xe4\x9c\x7a\xaf\x81\x78\x0b\xd1\xde\xe0\xbf\xb7\x51"
+  "\x9b\x95\x4a\xe3\x02\xea\x43\x31\xe4\x3f\x8a\xf3\x47\x73\xc2\x5a"
+  "\x40\xba\xc2\xf7\xd6\x03\xef\xb8\x52\x65\x5c\x70\x69\x7d\x78\x4f"
+  "\xf8\x61\x2f\x0e\xf2\x53\xde\x78\xe3\x02\xe2\x49\x6a\x8a\xa2\x8d"
+  "\x77\xd5\xf3\xb6\xe1\x84\x58\xd0\xb2\xf7\xea\xdf\x72\xc8\xb1\xb9"
+  "\xc4\x72\xeb\xb5\xbe\x37\xaa\x7d\x07\xbc\xc4\x1e\xd5\xcd\x75\x32"
+  "\x36\x00\xf2\x1c\x98\x54\x67\x85\x71\x26\x7e\x00\x6b\xc3\x39\x09"
+  "\x8b\xf7\x53\xc6\xd7\x86\x4b\x6a\xc7\xfb\x29\xff\x40\x1d\x63\x6a"
+  "\x1d\xae\x7f\xb2\x0e\xd7\xc5\xea\x90\x7b\xcd\x9d\x49\x97\x2e\x3b"
+  "\xbe\xef\x11\xb8\x52\x19\x9b\x2a\x69\xe6\xfe\xc7\x43\x90\xdf\x82"
+  "\x26\x6b\x1a\xf1\x36\x64\x57\xea\xf6\x04\x59\xd0\x35\x98\xba\xdf"
+  "\x31\xca\xda\x0a\x3e\x64\xfd\xac\xf3\x1e\xfa\x66\x7f\x3e\xc9\x6c"
+  "\xd6\x92\xb1\xea\xd8\xda\x31\xfd\xfb\x59\x04\xef\x06\x8a\xc3\x10"
+  "\x81\x67\x5d\xbe\x0f\x99\x3b\x93\xf4\xab\xdd\xa4\xd7\x2e\xc1\xbc"
+  "\x4a\x53\x40\x1b\xc0\xa3\x87\x04\x3c\xc0\xbf\x08\x79\x0b\x32\x9b"
+  "\x90\xb7\xbc\xc2\x3f\x69\x3c\xf8\x5e\x13\x77\x3e\x95\x45\xba\xef"
+  "\xd0\x58\xba\xd5\xef\x64\x8b\x29\x26\x02\xe9\x9d\xb9\xf1\x10\x5b"
+  "\x14\x8c\xe2\x42\x9e\x02\xef\x4f\xb1\x11\xdc\xe0\x86\x43\xe0\xa3"
+  "\xeb\x47\x58\x52\x3d\x78\x4f\xd0\xec\x44\xa2\xeb\xdb\xd5\xd8\x08"
+  "\x55\x23\xe1\xd8\x08\x8d\xa4\xeb\xe9\xc1\xfd\x08\x33\x84\xaa\x12"
+  "\x6c\xdb\x46\x58\x4a\x43\x01\xb3\x6d\x23\x5d\xde\x71\xc9\xfb\x08"
+  "\x3b\x70\x8a\x93\xb0\xda\x46\x7b\x09\x61\xde\x87\xce\x82\x87\xe9"
+  "\x96\x41\xe8\x40\x2e\x09\xde\xfb\xc5\x3a\x18\xac\x34\xe6\x00\xc6"
+  "\x83\x63\xd5\x71\x89\x1e\xd6\xb9\x19\xf0\x9b\x50\xe7\xa5\xd9\x93"
+  "\x6c\x89\x88\x6d\xf1\x56\x8a\xa4\xef\x28\xab\x63\x32\x9c\x08\x6d"
+  "\x4b\x67\x37\x0f\xb1\x54\x79\x0e\x31\x16\x6b\x62\xd7\x6c\xb2\xff"
+  "\x2b\x5a\xc9\x2c\xa1\x6d\x4b\x75\xc5\x3b\x58\x94\x3b\x98\xc6\xe8"
+  "\x57\x74\x9a\x0f\xde\x9c\xcb\x52\x69\xff\x81\xf6\x4a\xac\x8f\x51"
+  "\xfe\xfd\xa1\x94\x42\x96\x1a\x59\xf6\xca\xf5\x79\x2b\x6e\x49\xfd"
+  "\x79\xb6\xf5\xa1\x15\x79\x2b\xd7\x2d\xcb\xcb\x66\x0b\xa4\xd9\x84"
+  "\x70\xfd\xbc\x9e\x6c\x26\xd6\xad\xc8\xcf\xb1\x2e\x5f\x9b\x97\x97"
+  "\xbd\x2a\xdf\x7a\xcf\x5d\x8b\xbf\xea\xff\x6f\x9b\x65\xa7\xf0\xf7"
+  "\x2a\x6c\xe8\xdc\x87\xf9\xaf\xbe\x35\x52\x5d\xc0\x0c\xe6\xd2\xbb"
+  "\x97\x98\x83\x0b\xac\x32\x3e\x12\x70\xa5\xe2\x70\x3d\x2f\x4e\xaf"
+  "\x93\x7c\x6a\xb7\xdc\x53\x70\x1d\x6e\x92\x67\x2b\xba\xa5\x4e\xc6"
+  "\xbf\x20\x59\xce\x29\xf7\xb4\xa8\x7c\x46\xf7\x2b\xe9\xde\x9c\xcf"
+  "\x5c\x6d\xb3\x68\x3f\xdc\x3d\x4d\xe4\xdb\xb6\x50\xa7\xe5\xd3\xf2"
+  "\xc8\xf7\x5d\x22\x76\x62\xa3\xf0\x85\xd9\x35\x17\xf0\xb9\xcc\xef"
+  "\x74\xdb\x3c\xfa\xbd\x99\xea\xfe\xfa\xa0\xb4\xd7\xeb\x66\xe4\x0f"
+  "\x8f\xff\xea\xca\x11\xb5\x9c\x4c\xd4\x37\x15\x79\x97\x60\x0c\x7a"
+  "\x55\xbb\xbe\x6b\xfa\xd4\x76\x49\xbb\xd3\xae\xff\x90\xf6\x1d\x6e"
+  "\x47\xc4\x79\x6c\x71\xa6\x9e\xd6\x46\x95\x27\xf5\xab\xe5\xd5\x6b"
+  "\x34\x01\xf9\x29\xfe\x8d\xeb\xd2\x69\xa1\x5b\xca\x3f\xe7\xf9\x39"
+  "\x51\xe1\xb4\xcd\xf2\x02\xe8\x43\xf2\x09\xd6\x55\x7b\x21\xbe\x8c"
+  "\x8f\xe0\x0f\x56\x2d\x5f\xbd\xd2\xbe\x2c\x7f\xc5\x83\x2b\x72\x57"
+  "\xe4\xaf\x17\xc7\xc0\x67\x8b\x7f\xff\x76\x5d\xd6\x92\x0b\x7d\x37"
+  "\xcf\x26\x1d\x8b\xea\xf3\xd5\x47\x36\x0d\x52\xcf\xd5\xfd\x74\xd0"
+  "\xc9\xae\xb9\xb4\x76\x77\x67\x0a\x7d\xb0\xf0\x3f\xd0\xbd\xd3\xa3"
+  "\xfb\xeb\x42\x75\xbf\x63\x48\x85\xbd\x78\x3f\x6c\xb2\x76\x5b\x67"
+  "\xb1\x79\x7d\xec\xc0\x7c\xda\xe7\x02\xfc\xac\xb4\x1e\x56\x6f\xa0"
+  "\x75\x0b\xa3\x10\xfc\xb6\x1a\x9f\xf5\x83\xdf\x11\x0c\x88\x27\x04"
+  "\x0c\x76\xf6\xb1\x0f\x66\x0a\x18\x7c\x69\xd9\x29\x7c\x0f\x7c\x69"
+  "\x79\x81\x70\x8b\xda\xac\xf0\xf4\x6d\x9c\xa7\x6f\x55\xbe\xcc\xd9"
+  "\xc6\xbf\xcc\xd9\x1a\xf6\x1b\xf7\xc1\x66\x7c\xdb\x8c\x6f\xcb\x29"
+  "\x0e\x4d\xf5\x29\xd6\x4c\xfb\xdf\xf4\x6c\xce\x4f\x64\x21\x53\xac"
+  "\x85\xda\xe3\x1e\x4c\x15\xfc\x76\x3f\xf2\xbb\x7d\xdf\x66\xe0\x25"
+  "\xad\xe2\x4c\xa3\xd8\xaf\x03\xbf\x87\xef\xdc\x68\x97\x7b\x70\x94"
+  "\x64\x62\x8b\x02\x9e\x0f\xfd\xdd\x8d\xf5\x33\x93\xca\xa5\x3e\x8b"
+  "\x73\xc5\x33\xb8\xc7\xef\xfc\xa0\xc9\xc3\xba\xec\x2a\x6f\x2a\xec"
+  "\x2d\x08\x06\xe7\x8f\xe7\x07\xc2\xa7\x03\x60\x7c\x05\x77\xed\xb3"
+  "\xc8\x31\xfd\x40\xf8\xba\x58\xd8\xcf\xbf\x0c\x9f\x67\xff\xe0\x24"
+  "\x9e\xc7\xf0\x53\xb8\xeb\xed\xb9\x11\xfb\xca\x78\xf7\xe1\x74\xc1"
+  "\xbb\xcd\xe0\x5e\xfb\x06\x8a\xdb\xfd\xe1\xb5\x12\x6f\xde\xfe\x57"
+  "\x6f\x71\x4e\x14\xbe\x09\xd1\xf9\x4b\x09\xcb\x0f\xbf\xe7\xde\x7c"
+  "\x4a\xb3\xd3\x40\xfd\x1f\x1e\x69\x7b\x28\xc8\x44\x1c\xe9\xfe\xa0"
+  "\xb0\xfb\x53\x7d\x0c\xe8\x14\x67\x37\xf9\xd9\x4b\x84\x6c\x47\x7b"
+  "\xd1\xc2\x47\xba\xdf\xf9\x61\xfe\xf8\x39\x31\x93\xe4\xf7\x88\xe7"
+  "\xa2\x18\x5b\x84\xfb\xc4\xbf\x51\x9b\x08\xf7\x51\x76\x13\xed\x51"
+  "\xcb\x39\xf0\x61\xf3\x3f\x37\x07\x3e\x14\xfa\x5f\x94\x95\xc6\xf5"
+  "\xc5\xfc\xe6\x4a\x96\x29\x6c\x08\x82\x3e\x3a\x37\x6b\xe0\xc6\x83"
+  "\xaa\xdf\xdd\x03\x57\x09\x3b\x93\x82\xa1\x26\x3a\x9b\xba\x7d\x94"
+  "\x99\x14\xd7\xc1\x00\xf1\xd9\xfb\x0b\x85\xed\x85\x11\xdf\x09\xdb"
+  "\x0c\xb2\xa5\x4b\x10\x71\xdb\x3e\x64\xdb\xcf\x32\x43\x3f\xfb\x68"
+  "\x36\xed\x05\x85\x61\xfd\x51\x29\xed\xfd\xf1\x8a\xbd\x2d\xe6\x42"
+  "\xbd\x8b\xca\x50\x46\x4e\xce\xd5\xbe\xa3\x18\xc1\xf4\x5d\x1f\xfb"
+  "\x28\x5b\x7c\x47\x79\xc9\xc7\x52\x51\xe2\x52\xf0\x59\x39\x94\x3f"
+  "\x88\xe7\x46\x25\x71\x31\xc7\x7a\x10\x2a\x08\xb6\xe0\xdd\x12\xa5"
+  "\x32\x2e\x11\x69\xe9\x62\x0f\x62\xcc\x42\x7b\x93\x8c\x1b\xfb\xad"
+  "\x6e\xcf\x17\x6d\xa2\x3d\x74\x96\x36\x1f\x6b\xa7\x90\x4b\x3e\x7a"
+  "\xad\xf1\xb8\x88\x27\x87\xf1\x3c\x20\x7d\x67\x9e\x62\xbb\x64\xfb"
+  "\x0e\xdc\x33\x5c\xf1\xbe\x77\x18\xb8\xe9\xd3\x1b\xd9\x5e\x4b\x80"
+  "\xd6\xec\xee\xbd\x96\x51\x8c\xcf\x81\x24\xd0\x3a\xab\xe4\x89\xe5"
+  "\x77\x1a\x4e\x46\x59\x12\x17\xe0\xfd\x1c\xcd\x1e\x49\xc3\x47\x0f"
+  "\xfb\xc8\x44\x70\x03\x1e\xf7\x74\xe5\x92\x6d\x99\xd2\x89\xba\x58"
+  "\xa8\x40\xe9\xa5\xbd\x71\xb2\xdb\x27\x79\x66\x91\x83\x0f\x93\x7c"
+  "\x46\x67\x9d\x68\x3f\x9c\xce\x70\x37\x40\xbe\xa5\xb2\x51\x6e\xa5"
+  "\x76\x96\xbb\x0a\x69\x54\x36\x9d\x67\xaa\x7e\x58\xcc\x35\xb2\xe1"
+  "\x34\x89\x3d\x81\xa8\x47\x8e\xdf\xeb\xe3\xc3\x74\x5e\xfe\x5e\x3b"
+  "\xae\x6a\x39\xe4\x67\x07\x65\x74\x6b\x65\x28\x64\xff\x9a\x27\xec"
+  "\xdc\x3c\xf2\x7b\x69\xff\x73\xaf\x4f\x11\xe7\x50\xe8\x7b\x69\x97"
+  "\xf3\xb1\x61\xdc\x86\x52\x9c\x0d\xf9\x38\x49\xf3\xc3\x83\x7b\xeb"
+  "\xf8\xd9\x36\xc0\x6a\xb8\x32\xd6\xe2\xc3\x1c\xf7\x55\x1a\x33\xf1"
+  "\x6e\x1e\x28\xcc\xce\x8b\xea\x28\xe8\xfc\xfe\x5a\xa6\x57\xe2\x0e"
+  "\xa5\x90\x6f\x06\x3a\xf3\x29\xed\xb6\x3f\x6e\x50\xfd\x34\x44\x9d"
+  "\x62\x1f\xff\x24\xbc\x37\x1e\x52\xf5\xba\x1f\xb7\x4b\xb9\xe2\xe3"
+  "\x76\xa1\xd7\xad\x8e\x65\xcf\x6d\x08\xe8\x5b\x36\x78\xf4\xd2\x96"
+  "\xf1\xe3\x56\x0f\x3b\x3c\x14\xb6\x65\xfc\xd8\x41\x65\x4d\xec\xcf"
+  "\xa2\x57\xb5\x31\x3d\x28\xce\xd7\x86\xe5\xf4\x83\x62\x9d\xa3\x7d"
+  "\x6c\x85\x78\xba\xb8\xc1\x34\xb2\x5b\x72\xdb\xcf\x90\x7e\x37\x46"
+  "\xea\x0c\x0e\xaa\x71\x84\x85\x9d\xe2\xe5\x27\xce\x7f\xbe\x8c\x9e"
+  "\x25\xcc\x0e\x2e\xd0\xf6\x8a\xaa\xf5\x8a\xc7\xac\x03\x79\x6a\x02"
+  "\xcd\xb3\xfb\x84\x7f\x00\x37\x78\x44\x8a\x8d\x6d\xcf\xa3\xb3\x80"
+  "\x07\x37\x92\xdf\x00\x39\xe7\x0e\x8a\x73\x49\x8a\xf3\x4e\x5e\x4c"
+  "\x72\x92\x97\x62\x75\x9c\x61\xc8\x37\x0d\xf9\x5e\x6c\x2f\x1c\x62"
+  "\xdc\x75\x70\x88\xe2\x44\xf6\xab\x75\x7b\x63\x7b\x03\x5f\x37\x31"
+  "\xc0\xff\xe0\x1e\x0f\x7b\x71\xfe\xa5\xd3\x83\x83\x7b\x2e\xc6\x33"
+  "\x4b\x1e\x2e\x8d\x4d\x26\x77\x93\x5e\xe5\x26\xd4\x7f\x0f\xa7\xf6"
+  "\x1f\x7a\x31\xa8\x0f\xb0\x31\xfd\x14\xfe\xad\x12\x07\x0b\x3a\xa7"
+  "\xf0\xd0\x06\x8c\xd7\xb0\x05\x72\x59\x27\xeb\x92\xb6\x30\xb4\x9f"
+  "\x6f\x2e\xf2\xf1\x33\xee\xe0\x6e\xd2\xeb\xd3\xd9\x68\xd0\xa3\x43"
+  "\x3b\xdc\xc1\xd7\x19\xd9\x27\x13\x1d\xe9\x63\x87\x84\x3f\xa6\x9b"
+  "\xec\x25\xec\xc6\x53\xe2\xfd\x42\xc9\xcf\x1d\xda\xa5\x5e\x1d\xe4"
+  "\x1f\x33\xb2\x4d\xff\xb6\x76\xd5\x72\x72\xb2\x7a\xe3\xc2\xec\x82"
+  "\xec\x5c\xeb\x7d\xe4\x82\xf5\x02\x5b\x43\x63\x38\xae\x58\x4f\x3e"
+  "\xad\x91\xc4\x53\x53\x7c\x31\x11\x5b\xcc\x39\x87\x8d\xc7\x15\x23"
+  "\xde\xfa\xff\x83\xd8\x62\x1a\xcf\x4c\x71\xc5\xc2\x7b\x32\x9f\xcc"
+  "\x19\x9f\x03\xca\x9b\x7e\x7a\x16\xeb\xb2\xf3\xd0\x6e\x9a\x47\x72"
+  "\xdd\xe8\x69\x8e\xf4\x61\x23\x78\xa6\xf2\x7e\xc8\x00\x3d\xed\xda"
+  "\x99\x4d\xe0\xa2\x09\xcf\x07\xc2\x67\x44\x7a\x3c\x80\x9b\xa0\x65"
+  "\x64\xbf\x80\x67\xaf\x66\xbb\xa0\xc6\x8c\x16\xb6\x16\x4a\xd9\x15"
+  "\xcd\x52\x5f\xd8\x73\xb6\x51\x99\x62\x94\x7b\x55\x9f\x24\x6b\x67"
+  "\x90\xe4\xdc\x7c\x53\x9d\x9b\x9f\xcc\xb9\x98\x7d\x49\x78\x6e\x7c"
+  "\x62\x0f\xcf\xeb\xcf\xb5\x6f\xed\x7f\xcf\x36\x45\x95\xdb\xa6\x9f"
+  "\x60\x7f\x7d\x9c\x74\x88\xf2\xcc\xf1\x5f\x85\x4f\x4a\xe9\x07\xe2"
+  "\xaf\x3f\x50\xef\x51\xc7\x5f\x6f\x51\xef\xaf\xc4\xfd\x4c\xf5\x7e"
+  "\x16\xee\x75\xea\x3d\xe6\xec\xa7\xc7\xd5\xfb\x24\xdc\x7f\xa0\xde"
+  "\x63\x4d\xf8\xf4\x35\xf5\x7e\x06\xee\x77\xa8\xf7\x33\x71\x5f\xae"
+  "\xde\x63\x0e\x7e\xfa\x28\x93\xfb\xfc\xc6\x01\xf6\xe9\xcf\x2e\x5d"
+  "\x8e\xfc\xd4\x26\xf7\x92\x3f\x85\xcc\xdd\x3d\x57\xae\x29\xe3\x69"
+  "\x85\x18\x9b\x4e\x0d\xbe\x48\xb7\x52\x3d\x48\xdf\xe2\x61\xed\x3b"
+  "\x23\xd2\x13\xd5\xfc\x58\xff\x3f\x5e\x10\x91\x6e\x50\xd3\xdb\x21"
+  "\xaf\x76\x84\xd3\x3f\x09\xa8\xe9\xbd\xc8\xdf\x1d\x91\x3e\xa4\xa6"
+  "\x83\x5e\xbe\xd1\x13\x91\xee\x91\xe9\x7f\x35\x69\x76\x35\x6a\xfa"
+  "\x01\x35\x3d\xc5\xc3\xfe\xe8\x8a\x48\xef\x50\xd3\x41\xff\x3f\x49"
+  "\x8b\x48\x17\x74\x45\xfa\x24\x36\xf3\xbd\x85\x34\xb7\xfe\x9a\xe9"
+  "\x61\x7b\x1c\x11\x79\x5a\xd4\x6f\x1d\x1e\xf6\x3f\x4d\x11\xe9\x3b"
+  "\xd5\xf4\x5a\x8f\x2e\x2e\x29\x22\xbd\x6e\x32\x5a\xa5\xab\x63\x99"
+  "\x93\xe9\xda\x49\x2e\x11\xf6\xc5\x82\x57\xee\xdd\x4f\x67\x9a\xcc"
+  "\x0d\xbc\xcf\x5a\xc4\x79\x1f\xeb\xdd\x2d\xed\x69\x0f\x0a\xdf\x96"
+  "\x74\x3e\xac\x9f\xf5\x36\xa8\xbe\x05\xbc\xe2\xcc\xd8\x06\x3a\x33"
+  "\xd6\x2b\x78\xc0\x9b\x1d\x25\xd2\x5f\xae\x16\x7b\x81\x74\x4e\xea"
+  "\x7e\x3c\xf2\xfc\x80\x74\xf0\x54\x0e\xe9\xa5\xdd\xf9\xa3\xd2\x97"
+  "\x32\x64\x53\x4a\x23\xdd\x0b\xc1\x23\x52\xc7\x24\xe9\x7e\xef\x7e"
+  "\x65\x94\xce\x65\x4a\xfd\x14\xcd\x45\xca\x4f\x36\x64\x91\x79\x3d"
+  "\xac\x57\xf8\xac\x8e\xb2\x4c\x7b\xd6\xef\xec\x6d\x0e\x9f\x87\xe9"
+  "\x35\xa8\xe9\x75\x48\x6f\x0f\xa7\xff\xd5\x3b\x29\x6d\x07\x1d\xe4"
+  "\xc6\xbd\x81\xb1\x11\xee\x0b\x8e\xf0\x40\xf5\x67\xd2\x96\x1c\xb4"
+  "\xee\xea\x90\xab\xdd\x48\xe7\x45\x28\x26\x63\xb0\x80\xd3\x7e\x26"
+  "\xc5\xae\x9c\x7a\xaf\xcf\x0b\x1e\xc3\xcf\xab\x1e\x24\x9b\xd4\xb3"
+  "\x8c\xf6\x4b\x8b\x87\x28\x5e\x96\x99\xd3\x39\xe4\x8d\x27\x99\x89"
+  "\xce\x93\x90\xcd\x39\xed\x65\xde\x93\xe3\x65\xfb\x73\x42\xac\x11"
+  "\x65\x37\x3c\xa8\xf1\x17\x87\xb3\xc2\x67\x5d\xf7\xd2\xfe\xf2\xd5"
+  "\xc5\x22\xf6\xec\x61\xe1\xab\xd7\x5c\x4a\xfb\xfc\xd6\x00\xff\x0b"
+  "\xf1\xbc\xc6\xc5\xe6\x52\x06\x9e\xe3\x70\x13\xee\xd3\xe4\x0f\xef"
+  "\x90\x3e\x59\x9f\xe4\x5c\x3e\x2c\xfd\xad\xb9\xda\x1d\x92\x5e\x1c"
+  "\xee\xe5\xbf\xa6\xf3\x13\x87\x3d\xf8\x36\xe0\x8d\x37\x4e\x78\xae"
+  "\x64\x63\x03\xd3\x8f\x55\x80\x37\x39\xd5\xaa\x97\xf4\xe9\xb3\x4e"
+  "\x45\x6f\x2c\x25\xfd\xb7\x88\x3f\x59\x71\x68\x4e\xf3\xaa\x80\x7e"
+  "\xff\x86\x7e\xf6\xd8\x4c\x66\x59\x1a\xd0\x53\x9e\x7b\x12\xf2\x51"
+  "\x37\x78\x12\xf0\xa9\xfa\xdf\xe3\xfd\x1b\xab\x5a\xf5\x41\xc1\xaf"
+  "\x7c\xd6\x29\x74\xa6\xae\x43\x46\x5a\x43\xdc\x3d\x21\xe2\xb1\x4d"
+  "\xe0\xb1\x03\xa0\xff\xc6\xd0\xba\x9c\xcb\x82\x6b\x72\xa6\x36\xe4"
+  "\x31\x53\x68\x8d\x2d\xe9\xa9\x11\x36\x57\x5b\x7f\x1a\x0a\xb0\xa6"
+  "\xf8\x2d\x71\x35\x58\x53\x48\x17\x93\xa0\x4b\x14\x7b\xc3\x74\xaf"
+  "\xe8\xdf\xea\x6f\x2c\xb8\x78\x0c\xdd\xd0\x3a\x9b\xf0\x97\x40\x6d"
+  "\x99\xa8\xaf\x95\x5b\x99\x21\xa4\x9e\xab\x2c\x3a\xc6\x66\x80\x2f"
+  "\xd6\x27\x9c\xe5\x6d\x27\x72\x99\x9e\xe2\x8f\x16\x65\x0b\x7d\x67"
+  "\xf4\xfe\x9c\x20\x73\x3b\x3e\x65\x45\x79\x34\x46\x9f\x5f\x4b\x7c"
+  "\x1a\xd9\x18\x23\x7f\xe2\x09\xf6\xf9\x2d\xe6\x00\xd6\x8c\x00\x78"
+  "\xed\x87\x49\xb6\xfd\xfc\x6e\xe9\x9f\xe1\x73\x17\x9d\x83\x6c\xcb"
+  "\xfb\x3e\xa5\x2d\x2b\x3e\x46\x63\x71\x70\x48\x9e\xbd\xfc\x7c\x1e"
+  "\x3d\x17\xd3\x39\xcf\xb8\xde\xe4\xdf\x8e\x06\xa2\xa5\x4e\xed\xf3"
+  "\x3b\xe4\xfa\x60\xf4\x4a\x99\xed\xf3\xaf\x9c\x51\x1b\xd7\xf5\xbb"
+  "\x3a\x2c\x9c\x62\x99\xd5\x13\xff\xca\x3d\x62\xdf\x9d\xce\xbc\x3b"
+  "\xee\x6c\xe3\x23\xb5\xaa\x0f\x1d\x8f\x4e\x29\xef\xb0\x48\x3f\x77"
+  "\x9f\x9f\x63\xd2\x66\x0e\x6b\x64\x87\x4d\xec\x39\x94\x77\xcc\x15"
+  "\x3a\xf8\xf2\x8e\x05\x9b\x66\x91\x8d\xbf\x87\x0d\xc7\x76\xa4\xa3"
+  "\xed\x07\x86\xe3\x3c\x93\x9f\x3b\x72\xed\x5b\x60\xbd\x9a\x25\xd1"
+  "\xde\x4f\x46\x48\xfa\x79\x94\x73\xf8\x08\xca\x16\xef\xae\xe9\xb3"
+  "\xb3\x28\x29\x1b\x7a\x7e\x78\x73\x3d\xb3\xa2\xad\xf1\xdc\xf8\x4e"
+  "\x40\xd8\x22\xba\x3a\x8c\xee\x21\x8a\xd3\x12\x62\x72\x8f\xee\x48"
+  "\x22\x8f\x7d\x27\xa0\xe6\xdf\xd1\x35\x84\x3e\x18\xdf\xe9\x70\x07"
+  "\x4e\xaa\x3c\xa1\xa7\x89\x97\xbf\xd3\xc1\x5d\xef\xa8\x71\xed\x3d"
+  "\xa7\x35\xba\x2a\x71\xd4\x73\x4c\xe2\xfa\xbe\x05\x12\x6e\x47\x12"
+  "\xd5\xf5\xea\x1a\xba\xc7\xda\x9d\x2a\x6d\x4a\x3c\xbd\x1a\x8f\xec"
+  "\x51\xf3\xd0\x37\xe8\x77\x9b\xa4\xb5\x1e\xa4\x7f\xbe\x45\xbe\xf7"
+  "\x34\x51\x1a\xfa\x87\x35\xcb\x33\x97\xfa\x35\x19\x6d\x15\xb0\x28"
+  "\x64\x51\x68\xf3\x20\xd9\x5f\x13\x9f\xe2\xf6\xdd\xd9\xe6\x16\x63"
+  "\xd0\xf7\x2c\xd9\xdb\x53\x3d\xe4\x13\x87\xe8\x26\xca\x14\x70\x0a"
+  "\xb7\xff\xc8\x46\xad\x2d\x54\x1f\xbd\x43\x5f\x3b\x84\xbc\x8c\x3e"
+  "\x53\x1e\x1a\xd7\x01\x3b\xe9\xe2\xce\x02\x66\x64\xd7\xd6\xb7\x8b"
+  "\x60\x22\x61\xd6\xb7\x59\x95\xd5\xd5\x71\xe8\x5b\x7f\x3e\x3c\xe4"
+  "\xb3\x62\x04\x6d\xc8\x23\xfb\xa6\xbe\x5d\x2a\xfc\xd4\x18\x03\x7d"
+  "\xc2\xb7\x82\xfa\x2e\x3e\xe2\xdb\xab\xc6\xf3\xa2\xdd\xc4\x1b\x91"
+  "\xad\x00\xed\x1d\x49\x7c\xed\x9b\x1b\xf1\xdd\xdc\x8c\xd3\xe0\x91"
+  "\xc1\x43\x6e\x7a\x46\xc4\x6c\x4b\xf5\x3b\xfb\x16\x86\xe1\x2d\xcb"
+  "\x99\xa0\x8e\xab\xb5\x3a\x90\xc7\xa4\xb5\x13\xe3\xa3\xae\xc1\x7d"
+  "\xb5\xe1\x31\x39\xd2\xa2\x7d\x47\x7a\x19\x3c\x2f\xa5\xf8\x87\x93"
+  "\xf8\x85\xd7\xb9\x93\x41\x83\x83\x77\xb6\x09\x7c\x64\x47\x8d\x64"
+  "\x3b\x0e\xb8\x0e\x4a\x1c\xea\x53\xf5\x46\x47\x8d\x54\x26\xed\xff"
+  "\xc9\x38\x21\x47\x31\x0b\x8e\x24\xcb\xfa\x8e\x26\xc9\x36\x1c\x85"
+  "\xfc\xe7\x31\x5d\x28\xd7\x7d\x7f\x59\x96\x75\xf1\x2d\xe2\xcc\xe8"
+  "\x8d\x6b\xed\x74\x1c\x34\x2b\xfc\x70\x3e\xcf\x9d\x18\xf6\xad\x75"
+  "\x34\x73\xdc\xb7\x96\xeb\xb0\xaa\x97\x3c\xda\xcc\x47\xf8\x16\x3a"
+  "\xcf\xc1\x0b\x78\x5d\x35\xc6\xb0\xf8\x2c\xbb\x82\xe2\xd0\x16\xd9"
+  "\xf9\x17\xe4\x77\x8d\x1b\x0f\x2d\x01\x0d\x4d\x2f\x3a\xcb\xa6\x90"
+  "\xad\x10\xd1\x1f\xd2\x67\xf1\xd8\x43\x64\x17\x98\x1e\x3e\x47\x36"
+  "\x40\x36\x5c\x85\xbc\x38\x9d\xe2\x87\xe7\x12\x3e\x90\xdd\xf8\x00"
+  "\x1b\x48\x47\xbe\x5c\xbc\xcb\xaf\x12\x3a\x82\x43\x2d\x21\x63\xaf"
+  "\xaf\xf8\x24\x8b\x11\x31\xbe\x1c\x01\x66\x7d\x98\xce\x1b\xf5\xc7"
+  "\xa3\xcc\x16\xa4\x27\x88\xf4\x40\x80\x7c\x05\xb4\xe0\x5d\x02\xde"
+  "\xfd\x00\x57\x05\x65\x38\xaa\xd1\xee\xa2\x93\xec\x6a\xb4\x65\x10"
+  "\xf5\xb4\xa0\x9d\x03\xc5\x2b\xd9\x8c\x2e\xfb\x20\xc9\x77\x28\xcf"
+  "\xc3\x54\x7f\x1a\x2d\xf8\xae\x01\xfd\x72\x90\xae\x03\xd7\xc2\x2a"
+  "\x5c\x8b\x42\x2c\xa1\x68\x23\xd6\xbd\x8d\xa8\x9f\xce\x65\xa2\x1c"
+  "\xf2\xa1\x21\xdb\x82\xbe\x91\x6e\x0c\xe5\x6e\x1c\xe2\x03\x28\x7b"
+  "\x70\xff\x10\xca\x73\xf4\x8c\x97\xa9\xf2\xd4\x98\xdf\x03\x3f\xe4"
+  "\x15\xa0\x1f\x23\xbc\x8e\xec\xa9\x91\x06\x9a\x3c\xb0\x30\xcc\x0f"
+  "\x0f\xdc\xa3\xde\xc7\x8e\xe7\x2d\x4e\x67\x45\xe7\x98\x45\xd8\x04"
+  "\xac\x8b\x02\x3d\x3e\xd6\x4b\xbe\x9a\xc2\xbe\x3b\x8f\x7d\x8c\x7c"
+  "\x16\x94\x59\xa9\x96\x49\x69\xdd\x61\xfe\xf9\x98\xc6\x33\xc7\x8d"
+  "\xe7\xfd\x4a\x99\x03\xeb\xa9\x4c\xe9\x57\xe9\xa8\x55\x9e\x49\x3e"
+  "\xb6\x74\xdc\x27\xc2\x08\x6f\xa1\x33\x77\x4a\x01\xdf\x4d\x3a\x09"
+  "\xd2\x85\x90\xfc\x42\xe7\xee\x32\xd6\xbb\x4a\x84\x3e\x62\x86\xd4"
+  "\x99\x4a\x9e\xe1\x58\xdd\xf8\x19\x81\x67\x44\x3c\x02\x79\xa6\x8e"
+  "\xce\xe9\xe5\x09\x7d\x8a\x7f\xd1\xfa\x75\xc5\xf4\x3d\x7d\x8b\xfc"
+  "\x1d\xe1\xb3\x4c\x03\x0e\xa9\xbb\x3b\x62\xa1\x7b\xaf\xd6\x2e\xe7"
+  "\xd1\x54\xa9\x7b\x3e\xe6\x1b\xd7\xbf\x15\xf0\x76\x1a\x27\x71\xc6"
+  "\x90\x6c\x00\x43\xcc\x95\x11\x74\x69\x67\x85\x87\xfc\xce\x01\x6b"
+  "\xc4\x59\xe1\x21\xd1\x86\x51\x71\x1e\x7f\xdd\xa2\xe0\x3a\x2e\xcf"
+  "\x90\x0e\xcc\x0f\xd7\xdd\xef\x55\xeb\x4e\xa4\x7b\xaf\xf4\x89\x45"
+  "\xb6\x81\x56\x69\xd7\x31\x60\xd7\x6c\x29\x30\xdf\x7a\x08\x3f\x27"
+  "\xf6\xdd\x3f\x50\x77\xbe\x7f\x9e\x2f\x72\xc8\x77\x38\xd2\x23\xce"
+  "\xff\x0e\xfc\xdd\xf3\xbf\xc5\x5e\x7e\x84\x70\xc8\x2e\xe2\xd0\x7e"
+  "\x01\x5a\xdb\xab\xc6\xcb\xfc\x42\xe8\x5c\xfa\xd8\x17\x36\x3c\x9b"
+  "\xe5\xbe\xc3\x17\x33\x55\x7a\x93\xb3\x28\x14\x34\x7b\x50\xa7\xf0"
+  "\xf7\x13\x7e\x4e\x24\xff\x05\xc8\xf7\x03\xe9\x37\xf8\x0b\xe3\x05"
+  "\xf9\xe9\x7d\xc9\x05\xcf\x69\x17\x3c\x5b\x7d\x98\x87\x93\xd9\x8c"
+  "\x54\xd1\x3e\xb3\xf1\x90\x31\xa1\x94\xd9\x8b\x8f\xb3\x28\xcc\x8f"
+  "\x63\xd4\xb6\xae\x41\x71\x9e\xcc\xcc\x9d\xa9\xcc\x3d\x18\x94\xbc"
+  "\x28\x78\x80\xbe\x14\xe4\x39\xce\x66\xd0\x79\x06\x8a\x0f\x80\xfc"
+  "\x27\x64\x4c\x80\xc1\xd3\x4b\xd7\xc6\x31\xe5\xe7\xe9\x53\xb9\xfe"
+  "\xc1\x56\xda\xb3\x7e\x65\xd4\x43\x7e\xf5\x75\x45\xcf\xb2\x64\x9a"
+  "\x7b\x98\x83\xfd\x5c\xbf\xbc\x15\xdf\x0c\x3d\x37\x3a\x18\xed\x0e"
+  "\x7e\xca\xec\xa0\x09\x27\xd8\x60\xbf\xa1\x90\x19\x6a\x06\x58\x22"
+  "\xf0\x2c\xb8\x37\x38\x97\x69\xe7\xef\xeb\x2f\x93\xe7\xba\xeb\x81"
+  "\x93\x6b\x2c\x3c\xe0\x77\x0e\xa6\x41\x56\x5b\xa2\xc9\xe4\x95\xd2"
+  "\xff\x96\x01\xf5\xbf\x22\x7c\x05\xc8\x35\x0f\xb0\x1d\xdc\x28\xcf"
+  "\x33\x26\x5d\x81\x6f\xf2\xc3\xfc\xfa\x71\xa6\xee\xe1\xa8\xe7\x03"
+  "\x8f\xb3\xbd\x59\x4c\xc4\x34\x1a\x16\xfe\xd1\x07\x9b\xc6\x6d\x6f"
+  "\x84\x9e\xeb\x38\xe8\xc1\x61\x8b\xe4\xe5\x0f\x5b\x32\x42\x46\x95"
+  "\x67\x38\x2e\xd6\x22\xfa\x16\xdf\x99\x65\xec\xb2\xc1\xde\x30\xae"
+  "\x0d\xee\xa4\x35\x02\x7d\x82\x8c\x37\x68\xa1\x7e\x11\x4c\x7c\xc2"
+  "\xd7\xd6\x60\xf2\xde\x9d\x93\xc4\xb6\x30\xb6\x3b\x82\x42\x67\x62"
+  "\x0c\x00\x9f\x4e\x62\x0c\x2e\x27\x7f\x43\x6e\xd4\xb3\xbf\x71\x94"
+  "\xed\xb7\x0c\xb3\x2e\xdc\x93\x8d\x7d\xdb\xc3\x47\x59\xbf\x75\xe2"
+  "\xf5\x09\x6b\x5c\x00\xbc\xb9\x91\xca\x22\xfa\x46\x76\x89\xee\x42"
+  "\x26\x76\x9a\xdc\xfd\x4c\x94\xb1\x5f\x19\x64\xfb\x1d\x47\x48\x0f"
+  "\x1b\xe8\x6a\xfc\x94\x75\x59\x3e\x12\xf5\x10\x0f\xd9\x96\x37\x7c"
+  "\x91\xb2\xdb\x01\x8f\x76\x9b\x5a\xf6\x10\xca\x4e\x9a\xbc\x6c\xe3"
+  "\xe2\x4b\x2b\xfb\x52\xda\x6d\x4c\xbb\x94\xb2\x8b\xeb\x78\x08\x6b"
+  "\x42\x3c\xf8\x64\xe1\xeb\x92\xce\x52\x86\x46\xc8\x4f\xc8\x35\x5c"
+  "\xda\x7a\x9f\xf8\x84\xe8\x8d\xb0\x43\x28\x3f\xe8\x13\xe7\x2c\x49"
+  "\x77\xac\x9e\xaf\x74\x07\x8f\x31\xd2\x25\xfb\x9d\x27\xda\xc7\xe5"
+  "\xab\xf0\x1e\x2c\xe8\xcf\x89\x41\x69\xd3\x7b\x50\xe5\xbb\x4e\x08"
+  "\x9b\x86\x89\xe5\xa8\x1e\x93\xb4\x0d\xff\xdb\xb5\x9a\xce\x66\x38"
+  "\xb6\xc7\xa4\x96\x65\xbd\x50\x17\xa8\x3a\x77\xb1\x66\x3b\xf2\xad"
+  "\xeb\xf2\x56\xe4\x67\x6b\x07\x81\xe3\xd8\x7d\xd9\xcb\xb3\x57\x14"
+  "\x64\x67\x59\x97\xac\xcd\x5b\x75\xe3\xea\x87\x1e\xb2\xde\x93\xbd"
+  "\x66\xcd\xb2\x9f\x67\xc7\xb1\x25\x79\xcb\x56\xad\x59\x41\xfa\x3a"
+  "\xab\x75\xfe\xad\x19\x39\xab\xf3\x6f\xfc\xee\xfc\xd4\x0b\xf4\x75"
+  "\x74\x2e\xb8\x97\xf8\x76\xac\x95\x33\xb0\x6e\x4e\x23\x5f\x31\xe6"
+  "\xf5\xbc\xed\x31\xc8\x8c\xc0\xc1\x13\xb4\xe6\x60\xee\x1e\x21\x79"
+  "\x82\x7c\xc5\x92\xff\xd9\x6d\xcf\xf0\xee\x01\x16\xfa\x04\xbc\x68"
+  "\x0f\xd2\xc8\xd7\x6b\x2f\xe4\x78\x2f\x8d\x01\xd2\xff\x80\x3c\xed"
+  "\x4f\x20\xcd\x1b\x7b\xd8\x52\xf3\x19\x33\xc8\x75\x73\x68\x0e\xd7"
+  "\x4f\xe1\x95\xe4\xb7\xf5\xa8\x85\xa9\xfe\xa0\xf5\x6e\x4f\x80\x6c"
+  "\x55\x8c\x8b\x82\xc5\x9c\x68\xaa\x9c\x5f\x43\x32\x46\x0a\xe4\x10"
+  "\x69\x33\x1f\x7a\x9a\xe4\x9e\x4d\x22\x96\xd6\x10\xe8\xff\x67\x3d"
+  "\x61\x5a\x7d\xb6\x50\xe5\x37\x89\x97\x5d\xd7\x87\x67\xe9\xff\x62"
+  "\xe8\x02\xff\x17\xa7\x16\x33\x76\xae\x55\xfe\xe8\x9b\x73\xed\xf2"
+  "\x47\xf7\x91\xbf\x90\x43\xfe\x2e\x4c\xff\xdf\xfe\xb4\xfa\xff\xd9"
+  "\xef\x47\xe6\x5c\xfc\xf7\x8f\xd4\x2f\xfa\xfd\xff\x63\xff\xff\x37"
+  "\xdf\x8f\xcc\xbb\xd8\x8f\xf0\x0d\xb8\xd5\xfb\xc4\x67\xcc\x08\xfc"
+  "\xdc\x52\xf5\x20\x70\xfa\x30\xb3\x14\x06\x79\x7f\xf1\xcf\x58\x72"
+  "\xd1\x71\xa6\x27\xfe\x2f\xdf\xc1\xfb\x8b\x46\x48\xd6\x1e\x89\x07"
+  "\xfe\xb6\x56\xf7\x31\x53\x55\x1f\x4b\xec\xca\x97\x31\x18\x68\x0f"
+  "\x85\xce\x13\xb9\xf1\xdc\x59\x10\x60\xef\x7b\x4f\x93\xed\x5e\x5b"
+  "\x57\x26\x68\x4f\x2f\x63\x84\xbf\xa6\x4c\x96\x54\x3f\x83\xef\xe1"
+  "\xce\xa7\x96\x70\xfd\x53\xf3\x91\x76\xe0\x55\x25\x2d\xfa\xd5\x0d"
+  "\x1d\xd1\xd6\x07\x69\x9d\x3f\x75\x56\xc5\xcd\x8d\xf2\xbc\xdc\x59"
+  "\x21\x83\xa9\xfe\x7a\xb1\x3e\x9d\x3d\x27\xd7\xf4\xb3\xef\xaa\x3a"
+  "\x2a\xba\x17\x3a\x57\xf4\xa3\x95\x3b\x1f\x6c\xa5\x32\x7f\xab\xb4"
+  "\x46\xd3\x9a\xf9\xea\x86\xb4\xe8\xc2\x65\x4c\xdf\xe5\x39\xc1\xf6"
+  "\x82\x16\xd2\xbe\x2d\xe6\x5d\x33\xe6\x59\x4b\xc3\x0c\x5e\x8b\xf6"
+  "\x55\x82\x9f\x73\xa1\x4d\xbb\xfc\xce\x2f\xb3\xb0\x6e\x2d\x51\x79"
+  "\xb9\x36\xcc\x8b\xe6\x2a\xe4\x59\xb4\x96\x5d\x53\x85\x7c\xe0\xed"
+  "\x5c\xc4\x77\xcb\xf6\x0d\xff\x0c\x30\xd8\x8d\x3a\xbb\xad\x0f\xd0"
+  "\xf3\x69\xc1\x63\x50\xdd\xe8\x87\xb5\x8f\x79\x85\x3f\x1c\xaa\x43"
+  "\xab\x17\xe5\x83\xfe\x9d\x30\xa9\xfb\x66\xb5\xb2\x9c\x2f\x25\x1f"
+  "\xe6\x3a\x54\x48\x71\xe1\xd4\xf3\x48\x85\x55\x1b\xb0\xae\x8f\x32"
+  "\x23\xea\xd8\x82\x3a\xda\xcc\xa5\x8c\x9b\xe9\x2c\x6b\x6f\x10\xbc"
+  "\xba\xa2\xda\x89\x7a\x3f\x56\xbf\x15\x7c\x88\xe0\x3d\x42\xcc\x2c"
+  "\x75\x0e\xe0\x3f\x72\x40\x27\xc0\x73\x88\x73\x00\xe0\x37\x28\x1d"
+  "\x75\x6c\x41\xbf\xba\x21\x0b\xee\xc6\xda\xdd\x42\xbc\xc2\x03\x67"
+  "\xff\x83\x89\x98\xd8\xe0\x17\xd6\x38\x78\x40\xc6\xc8\xf2\xda\x35"
+  "\x7e\x81\xf0\x83\x78\x84\xaa\x07\x98\x61\x0c\x63\x0c\x1c\xe9\x00"
+  "\xff\x01\xde\xdb\xdb\xac\x8e\x4d\x87\xe0\x0b\xd4\xd8\xa0\x92\x86"
+  "\x7b\x5f\xc3\xfa\x6e\x42\x1d\xe0\x77\x43\x9a\x2f\x25\xd0\x20\x6f"
+  "\x87\xb6\xd6\xcb\xf8\xd6\xde\x66\x0e\x5a\x07\xb8\xed\x9e\x9d\xa9"
+  "\x83\x8c\xe7\x4d\xc4\x58\xec\xa6\xbc\xe4\xeb\x01\xf9\x03\xe0\xc7"
+  "\x1c\xea\x98\xf4\x56\x15\x10\x1f\xe0\x2d\xa1\x76\xe0\x9b\x4e\xc0"
+  "\x9a\xc6\x42\x8d\x1b\x08\xd8\x0b\x1e\x66\x78\xa6\x06\x7b\x8c\xf5"
+  "\xe6\x30\xfc\x4f\xcf\x8f\x84\x3f\x60\xb1\x59\x8e\xc1\x99\x7d\x11"
+  "\x63\x07\x59\xeb\x4c\x3d\xe9\x56\x51\xdf\x1e\xa9\x17\x3a\xbd\x91"
+  "\xfc\x71\x01\x67\xf6\x00\x16\x7b\x90\xaf\x95\x68\xf3\xa6\xcf\x40"
+  "\x73\x1f\x24\x1e\xea\xcc\xe3\x92\x47\x3d\x93\x42\x38\x8c\x67\x21"
+  "\x47\xf7\x33\xef\x66\x2a\x0f\xb8\x71\x16\x57\xf0\xb2\xa7\x4f\x16"
+  "\xd7\x53\xcc\xca\x43\x1d\xe4\x2f\x4b\x1d\xeb\x0e\xb4\x6b\xdc\xff"
+  "\x11\xe1\x00\x8d\x3d\xfa\xb8\x59\xca\xde\xa7\x7b\x49\x7f\x26\xbe"
+  "\x1b\xcb\xa1\x36\xf6\xd2\xfc\xd4\xde\x23\x7d\x90\xfc\x98\x46\xc0"
+  "\x66\xb3\x3a\x26\xad\x32\xfe\xdb\x99\x8d\x6a\xdb\xd2\xf1\x6c\x44"
+  "\x1b\x84\x4e\x65\x78\x2c\x27\xaa\x86\xbe\x29\x0a\x7f\x43\xf3\x07"
+  "\xb8\x6c\xc6\x37\x6b\x71\xe5\x5a\x5e\xf2\x41\x8e\x76\x04\x9f\x12"
+  "\xfe\xa4\xce\x24\x0d\x8f\xd9\xf4\xa8\x37\x80\x7a\xf5\x84\x1b\x84"
+  "\x17\x5a\x19\x35\x12\x46\xcd\x18\x3f\x81\x5f\x7b\x83\xad\x80\xfb"
+  "\x19\xf0\xff\x7f\x6d\x93\xfc\xdd\xe9\xa0\xda\xbe\x36\x19\x97\xe0"
+  "\x6f\xb3\x1b\xa5\xef\x17\xca\x37\x1e\xff\x26\xcc\x67\x9e\x16\x7e"
+  "\xa2\x50\x56\xa7\x8a\x13\x66\xbf\x73\xd8\x34\x8e\x43\xe2\x5c\xfd"
+  "\x99\x4a\xe2\x35\xd5\xf6\x13\xee\x3d\xae\xc2\x6e\x36\xe1\x80\x0f"
+  "\xfc\xa7\x1c\x67\xef\x66\xe2\x55\x25\x1e\x0e\x2f\xd6\xca\x90\x67"
+  "\xf3\x4f\xf7\x2a\x28\x43\xc3\x95\x48\xda\x80\xbc\x85\xa0\x0b\xe3"
+  "\x78\xa3\xd1\x02\x59\xa6\xef\x0f\xaa\x6e\x30\x80\xb1\x21\xdf\xd7"
+  "\x6d\xc2\x37\x91\xc0\x4b\x9f\x6b\xaf\x2f\xc8\x9e\x20\xbc\x7c\x80"
+  "\x68\xc2\xf0\xb1\xe1\xb8\x23\xd6\x30\x6e\x0f\x1f\xd0\x70\x3b\x62"
+  "\x5c\x05\x6e\x6f\x16\xf4\x68\x18\x7c\xf4\xcd\xda\xde\x71\x2f\xcd"
+  "\x73\x05\xf3\xba\xa6\x40\xe8\xbc\xcd\xa4\xe3\x12\xf3\x3e\x30\x24"
+  "\x64\x0c\x1a\xcf\x2e\x47\xbf\xf0\x37\xbe\x49\x61\xc6\x2e\xdf\x31"
+  "\x92\xf9\x4f\xd0\xfc\xd7\xe6\x38\x8d\x0d\xea\x6a\x23\x9f\xf0\x9b"
+  "\x41\x03\x69\x0e\xfa\xd0\x26\x8a\x83\x4e\x7e\xba\xda\x97\xa6\xb1"
+  "\x35\x18\xdb\xbd\x99\x34\x6e\xbe\x7c\xcd\xb6\xbf\x46\xd2\x00\x93"
+  "\x8a\x2f\xa2\x8d\x17\xc0\xd5\x2c\xe1\xea\xdb\x75\xfe\xfc\x3e\xb3"
+  "\x80\xe6\x77\x24\x5c\x09\xa6\x04\x5b\xe4\x45\xff\x8f\xb7\x68\x70"
+  "\x0d\xc3\xf4\xec\xdd\x2a\x3e\xaa\xb4\xf5\xec\x84\xb4\xb5\x46\xfa"
+  "\xdf\x6f\xdd\x44\x7d\xc1\x9a\x42\xf5\x8b\xf8\x32\xaa\xec\xd3\xee"
+  "\x25\x9c\x3a\x3b\xd7\xc3\xb2\x16\x68\x74\x0c\xed\xa9\x25\x7c\xa2"
+  "\xb1\xd2\x68\x07\xe9\x7f\x64\xdb\xcf\x66\x69\xe3\x41\xed\x8e\xa4"
+  "\x09\x68\xc3\xef\xe8\x39\xdc\xe7\xb3\x4f\xe3\xbb\xcb\x88\xb6\x85"
+  "\xf9\xab\xb3\x3b\xcf\xef\xfb\xd9\x4a\xea\x3b\xe1\x84\xbd\x80\x74"
+  "\x40\x72\x2d\xf3\xb0\x2f\x2d\xe7\xd3\xab\x2f\xe3\xa5\xad\x81\xe4"
+  "\xc7\x88\xde\xdb\x1f\x90\xf9\x69\x7d\x43\x7e\xa1\x13\x55\xd7\xc3"
+  "\x42\x5a\xff\x90\x66\x50\x61\xd0\x8b\xfc\xed\x74\x5e\x98\x7c\xc6"
+  "\x4c\xed\x95\xb2\x20\x68\xf4\x1e\x8a\x43\xe0\x61\xa7\xda\xbb\x50"
+  "\x6a\x30\x86\xb1\x7a\x95\xdf\x24\x3a\xc1\xd7\xa5\x4f\x5d\x37\xc8"
+  "\x62\xed\xdf\xe5\x47\xb1\x9e\xbf\x85\x79\x14\x20\x1f\x86\x28\xdb"
+  "\x3a\xc0\xce\xed\x40\xbd\x49\xea\xd5\x82\x6b\x39\xae\x33\x71\x7d"
+  "\x14\xd7\x2b\x71\xfd\x09\xf2\x2b\x6a\xfe\x54\x3c\x7f\x0f\xe9\xb7"
+  "\xaa\x57\xb4\x71\xa4\x15\xd7\xc5\x4f\x10\x5f\xf9\x80\x48\x9f\x4e"
+  "\xcf\xb8\x46\xab\xfd\xee\x94\x73\x7b\xe4\x18\xca\x71\x50\x3e\x5a"
+  "\xd7\x90\x66\x1f\x60\x81\x77\xa9\x6c\x3a\xbf\x8f\xfb\x8d\x11\xfc"
+  "\x29\xca\xf1\xbf\x88\xeb\x1c\x5c\x57\xe2\x9a\x8f\xeb\x2d\x54\x2e"
+  "\x60\xd0\x1d\xa6\x17\xde\xcd\x59\x0e\x39\x9e\x1e\x36\x4c\x32\x66"
+  "\x92\x46\x0f\x08\x9f\xce\xcb\xb7\x54\xe6\x93\xf2\xab\x3f\x53\x1b"
+  "\xbb\xa0\xc4\xdb\xa4\x20\xc6\x0e\xe5\x7f\x8f\xbe\xc7\xf5\x2e\xf5"
+  "\x9a\xa6\x5e\xef\x56\xaf\xff\xae\x5e\xe7\xab\xd7\x05\x1e\xe6\x4f"
+  "\x55\x79\x13\xc0\xcc\x9f\x4a\x30\xc1\xdc\x4d\x95\xf5\x06\xb2\x48"
+  "\xbe\x06\xfd\xbf\x6d\x98\x62\x8a\x39\xfd\x3d\x9a\x2e\x96\x74\x3f"
+  "\x63\xce\xbf\xfd\xfb\x36\xa1\xfb\xf1\x7b\xc3\xb4\xb0\x77\xd0\xa4"
+  "\x4b\x63\xe0\x9d\x62\xea\xf5\xe0\x1b\x64\x39\x0b\xf4\xea\x1e\x34"
+  "\xc5\xd6\xa0\x58\x69\xe4\x3b\x4e\xc8\x51\xf1\x56\xda\xcb\xeb\x15"
+  "\x7a\xea\x72\xf2\x85\xd3\x3b\x84\x5f\xc0\x1b\xdb\x1b\xd4\xe8\x3d"
+  "\xc9\x4b\xaa\x8f\xc8\x37\xfc\xce\xc0\xd2\xb0\x9c\x1f\x30\xc9\xfd"
+  "\xba\x2b\xae\x45\x7a\x84\xfc\xef\xa7\x35\xeb\x36\xc0\xba\x07\xfd"
+  "\x99\xd3\xc7\x02\xf5\xb8\x7e\xbb\x5f\xf6\x39\x55\xeb\xb3\x3a\x56"
+  "\x76\x0d\xe6\xfd\xcc\x3f\x17\xf4\x30\x8f\xf0\xbb\x6f\x9c\x2e\xfb"
+  "\x85\x7e\x5a\xc5\x1f\x8c\xf3\xc8\x71\x1a\xef\x08\x7a\x52\x18\xa6"
+  "\xd3\x81\xc0\xf9\xe3\xe2\x0d\x04\x25\xbf\xd0\x83\x79\x09\x1c\x18"
+  "\x69\xbb\x60\x5e\x56\xd2\xbc\x94\xdf\x9e\x9b\x73\x3e\x8d\x3f\x5b"
+  "\x49\x34\x5e\x6d\x23\xf0\x76\xa4\x89\xc6\xc6\xc3\xce\x25\xa9\x6b"
+  "\x52\x0f\xd6\xc8\xdb\x90\xee\x92\xed\x94\xe9\x6a\x5d\xc0\xbf\x11"
+  "\xf2\x3d\x71\xa5\x96\xae\xe2\x37\x95\xe3\xa0\xb1\xd6\xd2\xd5\xf2"
+  "\x81\xa7\x23\x76\x9a\x3f\x5a\xba\x8a\x93\x1d\x44\x6f\xe8\xdb\xa0"
+  "\xb0\xbb\x83\xfc\xfd\x40\x3b\xda\x7d\x8e\x74\x8a\x4d\x34\x9f\x37"
+  "\x6d\x60\xa6\x75\x75\x2c\x5e\xce\xcd\xd1\xe9\xda\xb7\x52\x4f\x3d"
+  "\x6a\xd4\x68\x54\x8d\xa0\x67\xbe\xc2\xf3\x69\x65\xf0\x79\xee\x34"
+  "\x07\x83\xc6\xde\xfe\xfd\xc1\x39\x82\xe6\x62\xde\xd7\xe3\xbb\x34"
+  "\x0f\x7b\x8a\xa9\x6b\x49\xa7\xdc\x27\x18\x5d\xbb\xbf\x49\xd2\x2e"
+  "\xb5\xec\x71\xfa\x17\xc1\x87\x08\x5a\x4f\x75\x51\x59\x58\x57\x12"
+  "\x7d\xc5\xe9\x53\x25\xfd\x1e\xdd\xe2\x61\x53\x53\x34\xda\x4a\xeb"
+  "\x93\x59\xc7\xec\xd5\x0f\xc8\xf5\x49\x21\x1d\x98\xdd\x27\x7c\x7f"
+  "\x75\xd9\x87\x18\xad\x9b\xe4\x93\x39\x63\x7d\x1c\xf9\x46\x4a\x47"
+  "\x5b\xcb\xc1\x9f\xed\x54\xf7\x1b\x20\xe7\x06\xbf\x43\xb2\xac\x0a"
+  "\x57\xcc\xa7\xe0\x55\xea\xb8\xf4\xa2\x3d\x3b\x89\xb6\x6f\x2a\x90"
+  "\xf1\x69\x48\x1f\x24\xe2\x19\x11\xcf\x6a\xe1\x01\xe9\x5f\x7e\x2c"
+  "\x25\x42\xc7\xd5\x24\xe7\xc9\x68\xac\x88\x0d\xe0\xea\xed\x97\xfa"
+  "\xc4\xb1\xdf\xc9\xf4\x31\xd5\x57\x55\xaf\x6a\x57\x39\x56\x12\x65"
+  "\x99\xf1\x0b\xa9\x17\xfe\xdb\x83\x92\x1f\x19\xcb\x8f\xb0\x63\x11"
+  "\xb0\x96\xbe\x67\xc7\x2a\xc3\xf3\x62\x2c\x93\xbe\xc1\xb7\x5b\x91"
+  "\x3e\xee\xff\x4b\xae\x35\x5e\xa9\xdf\x45\x1d\x53\x4b\xd3\x18\x68"
+  "\x73\xcc\x36\xa7\x36\x7f\x83\xc2\x3f\xa1\x36\x7f\xa9\x8f\x84\x0f"
+  "\x34\x87\x83\xe4\xbf\x0a\x73\x98\xe6\x32\xee\x87\x82\xda\xdc\x95"
+  "\xfc\x5d\xa1\x98\xbb\x62\xde\x06\x93\x22\xda\xd1\xa9\xe2\x6a\xef"
+  "\xf0\x72\x8b\x09\xef\x30\x27\x4f\xa8\xfe\x81\x46\xa5\x8c\x51\xbe"
+  "\x6f\x81\x32\xc2\x03\xa4\x9b\x26\x7d\x02\xe9\x6c\x54\xdb\x4a\xd2"
+  "\xff\xfb\xc8\x27\x57\x2d\xe6\x43\xd8\x0f\x57\x22\xd3\xfc\x70\xa1"
+  "\xbc\x92\xb0\xee\x78\xd4\xa3\xf6\xab\x1f\xf5\xd5\xb7\x15\xfd\x85"
+  "\xe0\xfc\x81\x9c\x63\xa3\xdd\x84\xc7\x6e\xe0\x1e\xd6\x9f\x3a\x8a"
+  "\x77\x8e\x6f\xf7\x68\xb8\x87\x39\x9a\x35\xc0\x42\xf7\x6c\x99\xc1"
+  "\xeb\x30\xa6\x64\x1f\x9e\x8b\xe7\xef\xe0\x9a\x25\xaf\xba\x44\xba"
+  "\xaa\x38\x5f\x87\x6f\x31\xff\xe3\x3a\xb4\x31\xf0\xc5\x1b\xed\x02"
+  "\xc7\x8a\xc8\x66\x2f\x55\xec\x5f\x13\x8e\x11\x7e\x89\x7d\x6c\xe0"
+  "\x9a\xb9\xf4\x3f\x18\xe1\x99\xf0\xcd\x81\x67\x6a\x2f\xe1\x99\xdf"
+  "\x19\x9a\xaf\xf9\xa1\xf5\xb0\xe0\xa0\xdc\x43\x0a\xa5\x6b\x36\xcb"
+  "\x84\x87\xf9\xd7\xb2\xe9\x28\xdf\xda\x6e\xf5\x91\xee\xfc\x73\x77"
+  "\xf0\x6e\x46\x79\x09\x76\x92\x5e\x5e\x91\x8f\x6f\x22\xc6\xdf\x2b"
+  "\x6c\x58\xf6\x2e\x15\xfa\xcc\xcb\xf1\x6e\xd7\xf9\x34\x67\x68\x8e"
+  "\xe0\x2b\xb1\x3e\x7f\x3d\x89\x59\x81\xb7\x58\x6b\x42\x9d\x1a\x3f"
+  "\x7c\x73\x12\xd9\x10\xfc\x4d\xc4\x0a\x27\x9e\x04\xf7\x9d\xb4\x4e"
+  "\x4f\xa2\x77\x9e\x43\xba\x22\xa2\x19\xa4\x7b\x22\x3d\x18\x60\x7d"
+  "\x60\x40\xa7\xbb\x67\x3f\xf9\xc9\x59\xfd\x55\x5f\xc4\x45\x0e\x7e"
+  "\x96\xfc\x36\x59\xf3\xd8\xe5\x7d\x3a\x5d\x2a\xe9\x9d\x8a\x4f\x93"
+  "\x8e\x47\x59\x72\xbe\x8e\x47\xd9\xa9\xfe\x5a\x51\x52\x72\xc4\xaf"
+  "\x59\xbd\xda\xfe\xce\xaf\x5d\xcd\xdb\x8d\x5f\xaf\x0a\xab\xdd\x7e"
+  "\xa7\xd2\xaa\xc1\x8a\x68\x0a\xd1\x58\xb2\x1d\xa1\x79\xae\x0b\x32"
+  "\xf2\xcb\x83\x71\x42\xbb\x37\xdd\x70\x5f\xdb\x06\x92\x69\x15\x61"
+  "\x03\x45\x3e\x65\x2f\xcd\x7e\x49\x11\xe3\x29\x7d\x7e\x2a\xcd\xa8"
+  "\xbb\xbd\xe6\x14\x33\xd8\xf3\xd8\x55\xa4\x43\x37\x87\x78\x1b\xc9"
+  "\xc0\x66\x19\x9f\xbd\xfb\x04\xe3\xaf\xe4\x6f\x64\x7a\xbc\xbf\x06"
+  "\xf7\xf5\x1a\x2f\x85\x6f\x12\xa3\x02\x2c\x89\x78\xa8\xbb\x36\xb2"
+  "\x6b\xfc\x4e\xee\xd0\xc6\x8a\xf8\x0c\xd2\xe3\x85\x63\x07\x29\xc2"
+  "\x2e\x8b\xfc\xab\x7b\x04\xdc\x54\x5a\x75\x8a\x74\xd7\x3c\x2b\xca"
+  "\xc7\x12\xe5\x3a\xc4\x81\xff\x7f\x2b\x94\xf8\xc2\x4b\x80\xfb\x07"
+  "\x22\xda\x39\x12\xbe\xb7\xfc\x0b\x7d\x6f\xf6\x11\x0f\x37\x09\x7c"
+  "\x74\x2c\x56\x83\x0f\xd9\xc8\x9b\xc1\xff\x8b\xf1\x0e\xf2\x21\xb4"
+  "\xad\xd3\xbe\x81\x19\x4f\xe8\xd8\x39\xf4\x91\xce\xa0\x76\x08\x1d"
+  "\xbf\x8e\x9d\xd4\xe4\x74\xd1\x6e\x1d\x7b\xcd\x5c\x1a\xc5\x48\x37"
+  "\x4f\xbe\x09\x85\x7d\x21\x58\x52\xe2\xe1\xdd\xc1\x79\xac\xad\xe8"
+  "\x76\xca\xf3\xb8\xba\x96\xf5\x0e\x17\x5b\xd8\x5e\xcb\x3c\xe6\x2f"
+  "\x63\x9b\x31\x57\x76\x5f\xb2\x1d\xa7\x8e\x69\xfb\xe0\x9d\xc2\xfe"
+  "\x41\xc7\xee\xa7\xb5\x84\x74\x03\x58\x47\xda\x69\xbd\x46\xd9\x1e"
+  "\x6d\xde\x60\x9d\x68\xc7\x37\x4b\x24\x8d\xd9\xdb\x81\xfb\xc5\xe4"
+  "\x1f\x45\xc8\x0f\x32\xbf\x49\xec\x1b\x94\xe9\x92\xc6\xf9\x6d\xe4"
+  "\xa3\xef\x84\x5d\x9c\x8e\x7c\x0d\xe9\x18\xbe\xb3\x51\xdf\x24\x2e"
+  "\x5a\xe6\x21\xff\xfc\xf0\xbc\xe5\x25\x62\xde\x0e\x45\xcc\xcb\x32"
+  "\x5d\x56\x58\x4e\x55\x2c\x37\x6e\x61\xd6\x89\xe6\xa1\x3d\x81\x25"
+  "\xfe\xcd\xc8\x7e\x54\x53\xc3\x9b\x6a\xf5\xca\xf7\x37\x55\x33\x93"
+  "\xae\x12\x60\xa3\x79\x56\x90\x39\x1d\xf3\xf1\x98\xd9\x74\xc5\xe2"
+  "\xbb\xf2\xa7\xf0\x22\x0b\xd3\x57\x9d\x99\x62\xbc\x36\x70\x45\x13"
+  "\x8f\xba\xe1\xbe\x7b\xf2\x69\x3f\xb7\x96\x7d\x91\xcb\xa2\xee\x0a"
+  "\xa1\x6e\x13\xb3\x7b\x74\x51\x5e\x3a\x4f\xbd\x17\x9c\x17\xdd\x53"
+  "\x99\x85\xf5\xcc\x58\xd8\xcf\x07\x2b\x1f\x8a\x36\x62\xfd\x4d\xc4"
+  "\xba\xe1\x9a\x6a\xba\xa2\x69\x0c\x65\xbc\x95\x29\xbe\x6b\xb9\xf4"
+  "\xb6\xd9\x67\x0c\xe8\xf4\xa5\x97\xd6\xb6\xe8\xd4\x70\xdb\xa2\x53"
+  "\xff\x2f\xb7\x2d\x31\xdc\xb6\x1c\xb4\x2d\xea\xaa\x4b\x6b\x5b\x8c"
+  "\x3d\xdc\xb6\x18\xfb\x3f\xd8\xb6\xe6\x4b\x6f\x9b\xe3\x0a\xb4\xed"
+  "\xb5\x4b\x6b\xdb\x94\x96\x70\xdb\xa6\xb4\xfc\x6f\xda\x56\x54\xcf"
+  "\x8f\x75\x81\x02\x93\x3e\x87\xe8\xfc\x80\xce\xf0\xfa\xc6\x64\x61"
+  "\x9b\x7c\x19\xee\x1f\x2d\xae\xe7\x47\x05\x6f\xa3\x33\x08\xdd\xbf"
+  "\xbf\xcc\x30\x1b\x72\xa9\x8c\x03\xa4\x8b\x4e\x16\xb6\x1b\x51\xb3"
+  "\x76\x71\x27\x0f\xde\xe4\x23\x3b\xb8\x20\xf9\x10\x21\xff\xdc\xd6"
+  "\x57\x47\x02\x7a\x1e\x77\x38\x75\xfb\x19\x03\x7b\x75\xc4\xab\xc7"
+  "\xb7\x39\x9a\xdf\x50\xed\x5b\x73\xdd\xc5\xe8\x91\xa1\xe1\xae\x1c"
+  "\x66\x26\x7a\x44\x57\x8a\x4d\x58\x53\x34\xc5\x78\xd7\x69\xac\xfb"
+  "\x65\x86\xdd\xda\xb9\x50\xad\xac\x45\x83\x53\xb8\xb9\x90\x45\xd1"
+  "\xd9\x54\xe1\x63\xd0\xe2\x65\x29\x85\x2c\x7a\x91\x03\xe5\x07\x58"
+  "\xa6\xd9\x81\xb2\x01\x0f\xc1\xcb\xeb\x0c\xe7\xa2\x72\x99\x69\x0b"
+  "\xca\xa6\xeb\x5d\x96\x62\xbe\xe9\x59\x66\xa0\x33\xac\x74\x16\x55"
+  "\x9e\x43\x8d\x31\xfa\xcb\xa2\x93\xb5\x7a\xfe\x0e\xfc\x12\x24\xfc"
+  "\xa2\x43\x61\xf8\x45\xff\x2e\x0c\xbf\xe8\xb5\x12\x7e\xd1\xb9\x61"
+  "\xf8\xc5\x2c\xbd\x34\xf8\x45\xef\x0a\xc3\x4f\x7e\x7b\x71\xf8\x45"
+  "\x1f\x9e\x1c\x7e\xd1\xbe\x30\xfc\x64\x59\x93\xc0\x2f\x66\x62\xf8"
+  "\xc5\x7c\xe7\x1f\x83\x5f\xcc\xd2\x7f\x10\x7e\xf1\x12\x7e\x53\xee"
+  "\x08\xc3\x2f\xe6\x74\x18\x7e\x31\x7f\x90\xf0\x8b\x69\x0e\xc3\x6f"
+  "\x4a\xfd\xa5\xc1\x2f\x66\x30\x0c\x3f\xf9\xed\xc5\xe1\x37\xe5\xaa"
+  "\xc9\xe1\x37\x65\x4e\x18\x7e\xb2\xac\x4b\x83\xdf\x94\xf5\x80\x5b"
+  "\xa2\x0a\xbf\xc4\xc9\xe1\x37\xa5\xfe\x1f\x84\x9f\x59\xc2\xcf\xb8"
+  "\x31\x0c\x3f\xe3\x2d\x61\xf8\x4d\x39\x2b\xe1\x37\x65\x28\x0c\x3f"
+  "\x63\xef\xa5\xc1\xcf\x68\x0b\xc3\x4f\x7e\x7b\x71\xf8\x19\x7f\x36"
+  "\x39\xfc\x8c\xf9\x61\xf8\xc9\xb2\x26\x81\xdf\x94\x89\xe1\x67\x7c"
+  "\xed\x1f\x83\x9f\xb1\xf7\x62\xf0\xbb\x34\x5e\xc3\x38\xa9\x5d\xf1"
+  "\xa5\x95\x13\x3b\x77\xb2\x72\x08\x86\x64\x73\xa7\x94\xc5\xce\x6d"
+  "\x54\x62\x8c\xf2\x5c\x82\x91\x62\x9f\xdd\xd9\xa7\x8b\x7d\xbc\x51"
+  "\x89\x36\x72\xe7\x3b\x2d\x8a\xf3\xdd\x74\x5e\x1a\x63\x50\x4a\xa7"
+  "\x18\xe8\xdc\xfc\xa4\xb1\x8e\x75\xb1\xc7\xa2\x66\xb2\xab\xe9\x6c"
+  "\xd9\x26\xf0\x6b\x74\xef\x2f\x8b\xf5\x82\x17\xf9\x8a\x1f\xee\xac"
+  "\x15\x6b\x44\xe0\xc4\xbc\xec\xac\xb5\xab\xb2\x96\xad\xca\xb7\x2e"
+  "\x5b\xfe\xc8\x9a\xf3\xfd\x9a\x8b\x98\x83\x9b\x69\xfc\xe2\xe6\x8c"
+  "\xfb\x32\x01\x1f\x4b\x3e\xe1\xec\x5f\x63\xb1\x27\x74\x71\xf9\xc2"
+  "\xd7\x7c\xdc\xe1\x7a\x3e\x96\xbe\x35\xed\xeb\xfc\x4d\xe1\xeb\x6e"
+  "\x2c\x67\x2b\xe4\xa9\xa5\xe4\xbf\x44\xdd\x9b\x58\x3a\xa0\x33\x55"
+  "\xf1\xd8\x23\xb4\x17\xe6\x13\xe7\x15\x74\x71\xc2\x3f\x22\xf9\x35"
+  "\xe1\xc6\x43\xbb\x15\xd7\x91\x36\x5e\x7e\xa4\x95\x60\xd0\x45\x7e"
+  "\xc6\x0a\xa2\xae\xe9\xd3\x25\x2c\xe6\xb1\x87\x76\xa3\xac\x56\xb5"
+  "\x1c\x8a\xed\xe9\x4b\xdb\xc0\x3f\xa7\xf2\x54\x5e\x90\x62\x49\xb4"
+  "\x49\x7e\x70\x6a\xac\xb9\xd4\x1a\x45\x79\xc9\xdf\x1f\xf9\xc1\xd3"
+  "\xe2\x07\x51\xbb\x29\x2f\xf8\xf1\x3b\xf1\xfd\x9d\xdb\x29\x3e\x90"
+  "\x56\x86\x6c\xd3\xe5\x27\x74\x53\xd3\x44\x5f\x5c\x87\x32\x87\x1f"
+  "\x4b\xdf\x2a\x62\x0a\x0a\xb8\x26\xdc\x86\xba\x33\xa9\x0c\xf2\xc3"
+  "\x45\xdf\xaa\xdf\x5c\x85\x6f\x04\x3d\x25\x1f\x9f\xb2\x8c\x84\xab"
+  "\xb4\x76\x81\x87\x8e\xc3\x73\x74\x44\x1d\x53\x4f\xe8\xe2\x4f\x46"
+  "\xbc\x37\xe1\xf9\x03\xf0\xa1\xd3\xd4\xf7\xf1\x78\xfe\x03\xf1\xa5"
+  "\xa2\x5f\xd5\x25\xd2\xce\x57\x17\x5f\x87\xb4\x44\x35\xcf\x34\xe4"
+  "\xd9\x48\xbc\xae\x5a\xc6\x65\x78\x5e\x46\x32\xa3\xfa\x3e\x09\xcf"
+  "\x77\xd3\xbe\x80\xfa\x7e\x3a\x9e\xaf\xc7\xf3\x37\xd5\xf7\xe0\xeb"
+  "\x4d\x99\xa2\xcd\xc6\x43\xcd\xd4\x27\xc0\xbe\x89\xe0\x0e\x58\x37"
+  "\x23\x6d\x29\xe4\xd5\x62\x1a\x47\xea\x67\xdb\x86\x13\xac\x4f\x67"
+  "\xba\x9f\xce\x9a\xc9\xb1\x3a\xd2\x26\xfd\xd0\xe8\xd3\x91\xbe\x84"
+  "\xd2\xc9\x5e\x5a\x29\x3f\xd2\x44\xf7\x80\xe9\x49\x82\xa1\x5a\xd7"
+  "\x35\xa8\xab\x50\x1d\x67\xc0\x8e\x7c\xc5\xb2\x92\xed\xea\x58\xa0"
+  "\x6d\x53\xf0\xfe\x13\xcd\xfe\x62\x51\x70\x4c\x9e\x99\xd1\x99\x76"
+  "\xfe\x53\xbe\x11\xf0\x9d\xa4\x7b\xa6\x7e\x2d\xae\x1c\xd2\x44\xac"
+  "\x7a\xc2\x4f\xd2\xaf\x78\x63\x0f\x2d\x10\xbe\x40\x80\xa3\x1a\xae"
+  "\x10\x9e\xf0\x98\xd8\xa0\xd0\xd5\x94\xc5\x87\xe3\x9f\xe8\x4c\x4b"
+  "\x55\x5f\xfc\x4c\xca\x09\xf1\xf3\xc6\xed\x8b\x74\x53\x05\x7d\x88"
+  "\x78\x97\x1e\xf1\xce\xa3\xbd\x13\x36\x70\x65\xf1\xf9\x11\xef\xba"
+  "\x2f\x78\x57\x1b\xf1\xae\xed\x82\x32\x9b\x23\xde\xb5\x5c\xf0\x5d"
+  "\x47\xc4\xbb\xfa\x0b\xde\xf5\x47\xbc\xab\x54\xdf\x45\x21\x3d\x38"
+  "\xee\x8b\x4f\x37\xb5\x50\x4d\x07\xad\x4f\x48\x8a\x48\xcf\x55\xd3"
+  "\x51\x7f\x02\xf8\xbf\x3f\xb7\xa8\xe9\x02\xcf\x81\x47\xdf\x90\x75"
+  "\x24\x2c\x88\xa8\x63\x9e\xba\x7f\x2c\x7d\x89\xe8\xe2\x76\x9b\x75"
+  "\xd6\x29\x84\x53\xe6\xd2\x12\x8a\xeb\x52\x2b\xfd\x4e\xc9\x79\x28"
+  "\x62\xfa\x92\x3c\x8c\x7c\x93\xd1\xc6\x09\x6d\x04\xcb\x12\xf6\x68"
+  "\x67\x33\x43\xae\x43\x0b\x95\xca\x58\x8a\xa1\x74\x0d\xf9\xa7\x2a"
+  "\x1e\x22\x1f\x25\x3e\xe6\x66\xa3\xcc\x9d\xef\x2f\xa1\x78\x71\x5d"
+  "\x32\x4e\x1c\x9d\x69\xd3\xd1\x99\x0d\xf2\xb1\xd5\x65\x3f\x29\x62"
+  "\xc5\xad\x1b\x62\xc9\xf6\xef\xf2\xfe\x01\x9d\xd9\x1a\x2a\x3f\xb4"
+  "\x50\xf5\x33\xf0\xac\x38\x0b\xad\x33\xcb\xf9\x41\x72\xec\x90\xd0"
+  "\x2d\x1b\x91\xaf\x45\xe4\xe1\xe9\xcf\xca\x3e\x9a\xc5\x78\x6c\x57"
+  "\xcf\xc7\xf9\xcb\xcc\xe9\xe3\xf1\x0b\x75\xe6\xdd\x67\x63\xfb\x2d"
+  "\x48\xcb\x3d\xcf\xa6\x51\x67\x7e\x9c\xca\xa4\xb6\x23\x8f\x8d\xca"
+  "\x46\x9e\xda\x71\x9b\x46\xa4\xaf\x0b\xb2\x59\x68\xd7\x80\x56\x3e"
+  "\xde\xb7\x78\x74\x09\xc2\x3e\x9a\xca\x3c\x5b\x15\x47\xe5\xb6\x7b"
+  "\xf4\xbb\x84\xfc\x89\xfb\x6e\x0f\x7b\xdb\x30\xd9\x9a\x27\xf4\x90"
+  "\xc6\x23\x3d\xdc\x75\xc4\x83\x79\xde\x2d\xec\x6e\x63\x8f\xf4\x48"
+  "\xf9\x3d\xf1\x2a\xb2\xb9\xa0\x18\xc8\xb4\xd7\x28\x69\x4d\xe2\x32"
+  "\x31\x5f\x91\x86\x31\xda\x05\x9a\x2c\x71\xf9\x92\xe6\x61\xe2\x6c"
+  "\x51\xc6\x19\x66\xac\x56\xed\x5c\xfd\x65\x89\x8e\x88\x38\x02\xd2"
+  "\x8e\x5d\x97\xb8\xa3\xcb\x21\xf6\x9b\x44\x1b\x2f\x6c\x03\xb5\x17"
+  "\x65\x25\x4f\xba\x7e\x1a\x8f\x74\x0b\xdd\x67\xc5\xe1\x34\x61\x3f"
+  "\xa6\x4b\x3c\x1e\x65\xb9\xf2\x19\xd4\xd5\x3f\x1e\x3f\x01\x79\xaa"
+  "\x47\x19\x53\x50\xfe\x78\x3f\xf3\xa8\x8e\x69\x62\x7f\xc2\xa3\x9b"
+  "\x66\x05\xed\xea\xa6\x36\xa8\xe9\xd6\xae\x60\x80\xce\x7e\x4f\xe8"
+  "\xdf\x89\xd6\x45\xe1\x1b\xa8\xe2\x08\xc5\xfa\xa6\xb8\xac\x6a\x9b"
+  "\x2f\xb3\x92\xfd\x39\xb5\x59\xc2\xf6\xb2\xe9\x1a\x1c\xab\xce\xa0"
+  "\xec\xa2\x4f\x59\xbf\x6e\x5a\x03\xd9\xb4\xd0\x79\x8a\x9a\x0d\xaa"
+  "\x9d\x15\xd2\x44\xbe\xd1\xf1\x3c\x42\xd7\x4b\x36\xbe\x44\x43\x1b"
+  "\xe9\x5c\x3c\xca\xac\xc6\x58\x08\x9f\x17\xba\x69\xe2\x2c\xc4\xa6"
+  "\x3c\x26\xfb\x4d\x36\x6c\xba\xcb\xe6\x4b\x5c\x99\xd6\xeb\xd1\x5d"
+  "\xb6\x58\xe2\xa0\x4c\xa3\x18\xda\x64\x7b\x70\x4a\x37\xed\x75\x8a"
+  "\xe9\x09\x78\x78\xc8\x2f\x5a\x97\x0f\xf3\xc4\x31\x4a\xb8\xe0\xa1"
+  "\xd8\x6d\x80\xc3\x1e\xb9\x26\x10\xcc\xa7\x35\x51\xfd\x04\x5b\x8a"
+  "\x67\x0a\x98\xee\xf4\x97\x5d\x36\x1e\xff\x8b\x62\xa7\x22\xcf\x92"
+  "\xc9\xc6\x85\x60\x14\x42\x9b\xc9\xbf\x47\xdb\xac\x4f\xd1\xbe\xcb"
+  "\x75\x4a\xdc\x91\x6e\xb2\x99\x44\x5b\x9f\x97\xb4\x42\x8e\x9d\x9c"
+  "\x4b\x97\x7d\x82\x3a\xdc\xb4\xbf\x48\xf6\xd8\x22\x0e\xb4\xee\xb2"
+  "\x12\x15\x7e\x22\x9e\x42\x6d\x81\x84\x83\xcc\x7f\xf9\x1c\xa9\x8b"
+  "\xb9\xf2\x63\xb4\xab\x7b\x5c\x17\x83\x74\xa1\x47\x53\xed\xaa\xf1"
+  "\x6e\x28\xa2\xcd\x3e\x71\x9e\xed\x0c\xc9\xd1\x97\x6d\xa1\xba\xaa"
+  "\xc8\x6f\x15\xe1\xc5\x89\x48\xfc\xbf\x6c\x2d\xb5\x93\xec\xf1\x42"
+  "\xb1\x87\xd3\x78\xf9\xe1\xf9\x04\x67\x7c\xd3\x8c\xb9\xd0\x3d\x49"
+  "\x9c\x6d\x11\x2f\xc8\x5f\x76\xf9\xd2\x88\x18\xa8\x58\xfb\x2e\xaf"
+  "\xd2\xd6\x36\x5a\x97\xc9\x0f\xc1\x78\x5a\x95\x15\x73\xf2\x50\xad"
+  "\xca\xd7\xd4\x4e\xea\x43\xef\x26\x96\x4a\x67\x66\xc9\x36\x9b\xf0"
+  "\x8d\x9b\xac\x0e\xf2\xcb\x4b\x3e\x06\xdb\x36\x7c\x1b\xed\x4d\xba"
+  "\xe3\xa9\x19\x5c\xc6\xcf\xbd\xe9\x0c\xd9\xe5\x0c\x0d\x14\x0a\xdf"
+  "\x39\xc6\x45\x8e\x20\xdf\x2e\xe3\x1c\x7b\x79\xbc\x95\xd6\xdc\x21"
+  "\xe1\x97\x9e\xca\xfc\x67\x7d\xcc\xea\x92\x8c\x2a\xff\x32\x04\x5a"
+  "\x79\x05\xfa\x23\xf6\x0b\x70\x3f\xe3\x84\x6e\x7a\xb6\x8c\xdb\x27"
+  "\xfd\xa4\xab\xf6\x85\x31\xf2\x9c\xb9\x97\x89\x73\xbf\xba\xa4\x4f"
+  "\xac\x37\x30\x36\xa4\x4b\x3a\x2c\x7c\x16\xbb\x0e\x35\xa9\x30\x68"
+  "\xaa\x91\xed\x32\x67\x38\xf4\xa2\x8d\xd4\xbe\x4b\x6c\xdb\x4e\x75"
+  "\xed\x8a\xf1\x97\x25\x0d\x6a\xe7\xd3\x45\xff\x55\x5f\xc6\x6d\x5f"
+  "\x23\x59\x65\xfa\xfd\xea\x7a\xb5\x53\xad\x7b\xe7\xff\xbe\xee\xe9"
+  "\x56\xb5\x4c\x87\xf0\xe7\x0c\xb8\xa0\x5c\x87\xbf\x6c\xba\x5d\x5b"
+  "\x43\x55\xbb\xf8\xd9\x72\x6d\x9f\xee\x0a\xaf\x9f\x12\x86\xe7\x9d"
+  "\x3d\x59\xbd\x3a\xdf\x0a\x26\xdd\xbe\x2c\x7f\x79\x8e\x35\x3b\x2f"
+  "\x6f\x75\x9e\x95\x9c\xaf\x44\xce\x31\x61\xf7\x52\x36\xbd\x5e\x8d"
+  "\xc1\xb5\x6b\x3c\x06\x57\xd9\xf4\xfe\xc8\xd8\x68\x68\xdb\xe0\xff"
+  "\x1d\x59\x66\xc6\x57\xe2\x2e\x6a\xe5\xd4\xea\x15\xd2\x4d\xb5\xe2"
+  "\xd7\x86\x1f\x9d\x6d\x62\x19\x01\x96\x86\xf5\x51\xf0\x3b\xe1\x73"
+  "\xd7\xd3\xf7\xd0\xde\x77\x9f\x6e\xc6\xb2\x46\xc5\xc0\x84\xdf\x0d"
+  "\xa7\x42\xf6\x23\xe4\x7b\xbb\x15\xbf\x36\xfc\x3a\xf0\x13\xdf\x29"
+  "\x7f\x11\x67\x46\x5b\x22\xdf\xd1\x7e\x34\x77\xee\xec\xa7\x3c\xbc"
+  "\xd4\x20\xf6\x1d\x94\x27\x65\xbe\x0b\xda\xa0\xe7\x65\x66\x2d\x9f"
+  "\x68\x7b\x42\x29\xb3\x4e\x90\x2f\x8a\x97\xc5\x25\xab\xf9\x04\x7e"
+  "\x6b\xfd\x21\xbf\xf0\xc8\xaf\xe5\x33\xf0\xb2\xcb\x9b\xd4\x7c\xf2"
+  "\x2c\x93\x53\x3f\x51\xbd\xd1\xdc\xf9\xc9\x66\x35\x5f\x62\x64\x79"
+  "\x11\x79\x62\x94\x32\x11\x6f\xb7\x5b\x29\x35\x88\x7d\x5d\x5e\x36"
+  "\xc3\x80\xfc\x13\xfa\xd3\xbc\xb4\x71\xba\xa2\xf9\xc2\x71\xb2\x2f"
+  "\x5f\x91\x7d\xfb\x8a\x55\x05\x14\xa5\x28\x7f\xf5\xda\x7c\xba\xae"
+  "\x5a\xf6\x88\xb8\xac\xce\x78\x68\xb9\xbc\xc9\xcf\x4d\xa5\x9b\x5c"
+  "\xe0\x1b\x5d\xb3\xd6\xda\xe9\xb2\x7c\x35\x3d\x3a\x72\x66\xaf\x5d"
+  "\xae\x85\x56\x8e\xc4\x43\x9b\xbf\xcc\xb2\x04\xb8\x31\x5f\xf2\x23"
+  "\x96\x4c\xc8\xbc\x62\xef\xd7\x5c\xea\x61\xfb\x6c\x22\x06\x1b\xfb"
+  "\xca\xb9\x7b\x9d\x65\x25\x9d\xbb\x37\x97\xda\x97\x9b\x83\x2b\xb2"
+  "\x41\x67\x9b\xf0\x6d\xbd\x87\x55\xaa\x31\x84\x0e\xb5\x08\x9f\x94"
+  "\x65\x57\x0c\x69\x36\x85\x8a\xeb\x50\x16\xf9\x5a\x17\x36\x46\x4f"
+  "\x92\xaf\x96\x43\xb5\x78\x6e\x6e\x7c\x52\xc4\x3c\x49\xc2\x73\x2e"
+  "\x9e\x77\xe3\xd9\x82\xe7\x64\xc5\xf5\x4e\x80\xce\xd9\xe1\xd9\x8a"
+  "\xe7\x14\x94\x3f\x1e\xff\x3d\x12\x36\x6a\xd0\xaf\xdb\x27\x94\x89"
+  "\xcf\xf7\x77\x84\xb9\x35\x33\x4d\x8b\xa9\x2a\xe2\xa7\x96\xcd\x5c"
+  "\xac\xed\x05\xca\x38\x41\x89\x4b\xc5\xba\x26\xd6\xf6\x99\xfb\xa3"
+  "\x2c\x57\xa5\x48\xde\x7b\xa6\x43\xf3\x2d\x20\x79\xeb\x99\xae\x88"
+  "\xd8\xb3\xf4\x5c\x37\x1e\x7b\x56\xf2\xa2\x5b\x25\x2f\x3a\xd3\xc3"
+  "\xcb\x66\x86\x63\xe8\x95\xcd\x6c\x8b\x8c\x13\xe6\xc1\x7b\x92\x69"
+  "\x90\xde\x13\x5e\x07\x67\xe6\x52\x9d\x13\xc5\xd9\x85\x4c\xee\xc8"
+  "\x58\x0f\xfe\x1b\x57\xc1\x8b\x87\x74\x4c\xc8\x63\x78\xe6\xce\x34"
+  "\xf2\xd3\x62\xa5\x77\xc4\xfb\x4d\xa8\x67\xa0\x38\x77\xba\x59\x8f"
+  "\x92\x4f\x57\x6f\x71\x96\xee\xeb\x8d\x4c\x27\x9e\xa5\x4f\x42\x7e"
+  "\x4a\x37\xeb\x7b\x84\x7b\x9a\xbf\xb2\xc8\xb3\xdd\x13\x9e\x37\xf8"
+  "\x50\xdb\x27\xce\x5d\x6d\x0e\x2e\xcb\x96\x7c\xdc\xac\x0f\x24\x2d"
+  "\x3d\x9c\x25\xd7\xfb\x59\x7b\xf8\x7d\x32\x96\x86\x47\x77\xa5\x88"
+  "\x63\x67\xd6\xe5\xae\xe6\xf8\xd6\xec\x58\x96\x2d\xd2\x90\x6f\x13"
+  "\x78\x2d\xb5\x7d\x3b\xdc\xc9\x83\x8c\x8f\x84\xe4\x99\x75\xdd\xac"
+  "\xa6\x07\xae\x2a\xa1\x7a\x8c\x82\x8f\xf8\x90\x99\x28\x66\x1b\xb5"
+  "\xad\x31\xc2\x9f\x5a\x0d\xd2\x44\x3c\xf6\xfb\x98\x89\xfc\xc7\xaa"
+  "\x6d\x69\x12\x71\xb0\xca\xae\x9c\xab\xf9\x7e\xf1\x20\xed\xc2\xfe"
+  "\xdc\xf7\x23\x31\x43\xae\x5b\x3e\x7b\xf1\xdd\xb8\x9b\xad\x86\x1b"
+  "\x8d\xc4\x9d\xe4\xe1\xb8\xcf\x5d\xc3\x2f\xac\xfc\x95\x88\xd7\x57"
+  "\x76\xa5\x0b\xe5\xcc\x16\xe3\xbd\xe9\xa7\xc7\x89\xb6\x68\xf1\xea"
+  "\xdd\x8a\x0f\xf5\x5e\x9d\x2d\x7c\xb7\xea\x25\xbf\x28\x7c\xa6\x95"
+  "\x5d\xb9\x90\xc7\x1d\x5a\x2c\x63\x75\x7e\x36\x17\xe3\x27\xd6\x7d"
+  "\x9a\x1b\xe2\x1c\x60\x22\xf5\xfd\x4a\x0f\x68\xea\x5d\xf8\xfd\xa7"
+  "\x8c\x3d\xf2\xd3\xe3\x5a\xb9\xe4\xdf\x08\xb8\xd5\x84\x6b\xa2\xbf"
+  "\x2c\xd9\x38\x6e\x17\xa4\x9d\x2d\xd4\x25\x5f\x4f\xbe\x97\xc2\xfc"
+  "\xf9\xd5\x3f\x94\x7c\x65\xf2\x1c\x0f\x33\x6f\x91\xf3\x3b\x19\xf8"
+  "\xff\xca\x3c\xf5\x7e\xa1\x87\xdd\x9a\x73\x41\x19\x4f\x6b\xfa\x0e"
+  "\x39\x76\xc9\x76\xe0\xe2\x5d\xf8\xfd\x27\xf2\x17\x6a\xb1\x8a\x37"
+  "\xe9\xc5\x79\xa2\x81\x28\x0b\x4b\x45\xfa\x16\x2d\x3d\x5a\x97\x06"
+  "\xd8\x24\xef\xd4\xe8\xc9\x70\xdc\xe1\x85\x78\xde\x0d\x7e\x73\xb6"
+  "\xfa\x9c\x8e\xe7\x76\xed\x19\xf7\xdd\x1a\xbd\x21\xbd\xc3\xf0\x63"
+  "\xe9\xcf\x92\xbc\xb7\xdc\x02\x9e\xcc\x42\xf2\x55\xb2\xd7\xc3\x9a"
+  "\x6d\x6a\x5e\xc8\xbf\xbf\xad\x94\xf7\x57\xa1\xff\x2f\xe6\x86\xe1"
+  "\x1f\x65\x96\xed\xbf\x7a\x1e\x8f\x8f\x9d\x4b\x31\xa2\x91\x67\x36"
+  "\xe6\x92\xf8\x96\x7c\x1d\x55\x8e\x26\x2e\x71\x6f\x06\x7f\xfa\x10"
+  "\xe1\xc5\xd5\x62\xff\xb4\x6a\x43\xe2\x62\xe2\xef\xe8\xec\xbc\x88"
+  "\xb9\x45\xbe\x0b\x83\x2c\x46\xf8\x8b\xaf\x8a\xb5\x09\x3f\xe9\xeb"
+  "\x6c\x26\xcd\x6f\x21\xe6\x24\xe8\xe1\x53\x59\xe4\xcb\x50\xe8\xca"
+  "\xfc\xb6\x04\xe1\xbf\x50\xf5\x5b\xd8\x50\xc0\x92\xea\x15\xe9\xb7"
+  "\x50\x9c\xab\xbf\x88\xef\x42\xee\x7c\x7f\xdc\x77\x21\xc5\x84\xc7"
+  "\xbd\x8d\x8f\x04\x03\xb8\xa6\x44\xf8\x67\x31\x4c\xe8\xc7\x50\x0f"
+  "\x1a\xa9\x97\x7e\x0c\x2f\x6d\x6d\xb9\xda\x28\x71\xe2\xea\x05\x5a"
+  "\xdc\xe4\x88\xb4\xa5\xc0\x69\xb9\x3f\xad\x4b\xb6\xa9\x69\xe0\x7f"
+  "\x5e\xde\x32\xce\x87\x81\xb6\x91\xce\x10\x73\xb6\x99\x17\xe7\x3c"
+  "\x1b\x39\x87\x18\xa3\x25\x3a\x1a\x65\xc5\xe0\x37\x85\x7e\x0b\xc6"
+  "\xe9\xc4\x08\x27\xf9\x0d\xf3\x1e\xeb\x8a\x23\x8a\x2f\x0a\x06\xa3"
+  "\x32\x82\xba\x03\xc4\x63\xd2\x19\xe1\x45\xa1\x20\x9d\x55\x37\x2c"
+  "\x0a\x0d\x53\x3c\xc3\x03\x74\x4e\xac\xe6\x21\x3a\xb7\x78\x0d\xa7"
+  "\x58\x27\x8b\x42\x5f\xf2\xed\xf2\x3c\x66\x37\xc9\x00\xa1\x11\xde"
+  "\x19\x2a\xe0\x1d\x18\x03\x13\xc9\x17\xe4\x2f\x2a\x41\x17\x60\x09"
+  "\xf6\xa8\x37\xef\x3d\xfb\x26\x27\x5f\x51\x14\xe7\x4a\x29\x0b\x80"
+  "\x26\x5a\x75\x19\xc1\xa8\x12\x77\xb0\x5f\xf8\x9a\x5f\x14\x9a\xc2"
+  "\x17\x39\xee\xe0\x22\x3e\x55\x01\x6f\x07\x3d\x8d\x12\x31\x8b\xd7"
+  "\xf3\x61\xdc\x1b\x17\xad\x1f\xe6\x14\x4f\x11\x65\x77\x2c\x0a\x2a"
+  "\xa3\x8b\x1c\x4a\x71\x86\x43\x87\xef\x8e\xe2\xbb\xa3\x68\x4f\x2a"
+  "\xca\x4c\xc4\xf3\x9d\x7c\xfb\x43\x74\xbe\xa9\x44\xc8\x38\xe8\x63"
+  "\x9b\x7a\x66\xb4\x15\xed\xdb\x4d\xbe\xaa\x33\x82\x6d\x25\xdb\xd5"
+  "\x33\xa0\x22\x96\xa7\x63\x8c\xab\xf5\xcc\x5d\xb4\x9e\xdd\x99\xb1"
+  "\xfe\x1a\x71\x96\x94\xce\x49\x2d\x0a\x5a\x51\x67\x09\xc1\xc3\x24"
+  "\xe2\x27\xd3\x59\xa9\xb2\x6b\xbc\x17\x8b\xc3\x38\xa1\x5c\x5d\xe6"
+  "\x0b\xf2\xaa\x1d\xbb\x79\x99\xbf\x93\x57\xfd\x7a\x0e\x77\x7d\xb6"
+  "\x94\xec\x4b\x79\xd9\x68\x3d\x9e\x91\x1e\xca\xe5\x55\xcf\xcd\xe1"
+  "\x15\x6c\x1e\xae\xbb\x79\x45\x94\x89\x57\xed\x9c\xc3\xcb\x0e\x1f"
+  "\xc0\x77\x2d\xbc\xec\x33\xfa\x2e\x95\x97\x7d\xde\x8e\x2b\x9e\x3d"
+  "\x7b\x90\x0f\xcf\x47\x76\xe3\x8a\xe7\xbe\xe6\x01\x9d\x15\xf7\x3b"
+  "\x53\x79\x45\x74\xaf\xa8\xab\xc2\xd8\x2b\xea\xaa\x98\xda\x2b\xea"
+  "\xa8\x48\xe8\x95\x75\x4c\xeb\x95\x75\x24\xf5\xca\x3a\x8e\xee\x44"
+  "\xfe\x56\x5e\x76\x2c\x09\xf9\xe6\xf2\xb2\x81\xcd\xb8\xe2\xf9\x0b"
+  "\x1f\xf2\xe1\xf9\x78\x16\xae\x78\x3e\x81\xb6\xec\xc4\xf3\xd0\x7c"
+  "\xe4\xdf\xc3\xcb\x4e\xb6\x22\xdf\x3c\x5e\xf6\xe5\x6c\x5c\xf1\xec"
+  "\x6d\x42\x3e\x3c\x9f\x41\x39\xcf\xe1\x79\xd8\x85\xfc\xf3\x78\xc5"
+  "\x15\xd4\x9e\x36\x5e\x31\x93\xca\x4d\xe3\x15\x57\x52\x7e\x3c\x27"
+  "\xa3\xbc\xe7\xf0\x7c\x75\x21\xae\x78\xb6\xa6\x20\x3f\x9e\xaf\x45"
+  "\x5f\x77\xb4\xf3\x8a\xaf\x3b\x90\x0f\xb2\xe2\x75\x48\xff\x35\x9e"
+  "\xbf\xd1\x8d\x7c\x78\xb6\x51\x7e\x3c\xdf\x60\x43\x7e\x3c\x7f\x8b"
+  "\x60\xd4\xc1\x2b\x6e\x9a\x83\x7c\x0b\x78\x45\xea\x16\x5c\xf1\xfc"
+  "\x6d\x6a\x3f\x9e\x6f\x5b\x82\x2b\x9e\xff\x95\xe0\x83\xe7\xdb\xd1"
+  "\xbe\x1d\x9d\xbc\x62\x1e\x95\xbf\x90\x57\x7c\x97\xe0\x83\xe7\xef"
+  "\xa5\x21\x1f\x9e\xef\x02\x3c\x9e\xc3\xf3\xbf\x19\x91\x7f\xe1\x84"
+  "\xe3\x59\xb1\xc0\xc3\x4b\x63\x18\xaf\xb8\x8f\xf1\xd2\x29\xb8\xfe"
+  "\xa8\x85\x97\x46\xdb\x78\xc5\x7f\x26\x22\x1d\xd7\x25\x2e\x3c\xcf"
+  "\x56\x9f\x71\xbd\x3f\x13\xcf\xa9\xea\x33\xae\x3f\x9e\x8b\xe7\x39"
+  "\xea\x33\xae\xe9\x6d\x78\x9e\xcb\x2b\x7e\x52\x87\x67\xba\xce\xc6"
+  "\xf3\x3c\xf5\x19\xd7\x9f\x2e\xc5\x35\xe8\xbd\x2a\xd7\xe1\x8d\x7f"
+  "\x34\xd5\x1b\xff\x7c\x13\xd9\x1a\x85\xaa\x77\xb4\x28\x09\xbf\x26"
+  "\xff\xb2\x31\xc5\x67\xd9\x94\x01\xdd\xd7\x57\xd0\xfa\xe6\x2e\xf4"
+  "\x88\x78\x67\xaa\x7f\xb4\x98\x3e\xdd\xd7\x36\x62\x3d\x9f\x4b\x31"
+  "\xa2\xd1\xf7\x21\xee\x8c\x3e\x83\x3e\xe7\x72\xe7\xd4\x3e\x5c\xf1"
+  "\x3c\xed\x43\xf4\x19\xcf\xff\x52\x81\x2b\x9e\x7f\xfa\x7d\xf4\x3d"
+  "\xd7\x5f\xf6\xb5\x5e\x8f\xce\x9a\x28\xe8\xf5\x0b\x2b\x21\x5b\x17"
+  "\x83\x4e\x80\x86\x3e\xdb\x9c\x69\x0e\x66\x32\x5e\xf5\x42\x9a\x99"
+  "\xe2\x12\x34\xe4\xb6\xf2\x84\x47\x45\x9b\x28\xf6\x08\x1f\x4b\xd1"
+  "\xcb\xba\xa7\xf2\x3e\xdd\xd7\x63\x49\x57\xc9\x13\xca\x27\x7b\x7f"
+  "\xbd\x78\x3f\xab\xd9\x2e\xdf\x27\xb2\xf0\xfb\xff\xa4\xf7\x3f\x30"
+  "\x93\x7e\xf9\xea\xa5\x76\x8f\xee\xeb\x22\x8f\x47\xf7\xb5\x4a\xee"
+  "\x8c\x62\x6e\xdf\xa0\xda\xc7\x29\x94\xef\x51\xfa\x6e\x32\xfd\x89"
+  "\x52\xf9\x52\x5d\x95\x93\x77\x93\xac\x08\x9a\xaf\xb7\x16\xa5\xb4"
+  "\xf6\xe9\xae\x4b\x6b\x10\x3a\x80\xe6\xb9\x74\x6e\xa7\x4f\x97\x12"
+  "\x3d\x56\xf1\x59\x89\x75\x83\x19\xe5\x5d\xf7\xbd\xe2\x00\xf7\xb5"
+  "\x15\x7d\x1f\x6b\x93\x48\xdf\x23\x6c\xc1\xe5\xfd\x2e\x69\xbf\x23"
+  "\xee\xb7\x48\x7d\xe6\x75\x69\xf4\x6d\x24\x6f\x1e\x2a\xbb\x37\x55"
+  "\x49\x68\x4e\x93\xfb\x4f\x29\xb1\xaf\x2b\x1e\xbd\x39\x9f\x45\x5b"
+  "\x37\xbc\x89\xf2\x53\x16\x9f\x2f\xc7\x69\x79\xc5\xbb\xdb\xde\x40"
+  "\xde\x6d\x42\xe7\x92\x92\xa9\xe9\x68\x39\xfa\xf0\x84\xe4\x61\xd2"
+  "\x68\x1d\x92\xbc\x58\x8a\x87\x7c\x2b\x06\x4d\x2f\x58\x83\x95\x8f"
+  "\x5a\x43\x95\xcd\x73\x79\x75\x73\x5a\x42\x50\xc7\x84\x1d\xbd\xee"
+  "\xba\xe9\x37\x07\x48\x17\xf6\x1e\xe5\xdd\xaf\xc4\xfc\x67\xd6\x4d"
+  "\x0e\xa6\x6f\xcb\xfb\x14\xcf\xd7\xc5\xf3\xb2\xa5\xbd\xee\xa1\x1e"
+  "\x46\xfe\x61\xf1\x6c\xe2\x65\x39\x99\x4a\xcc\x83\x39\x8d\xc4\x43"
+  "\x3a\x48\x87\xf3\x21\x7d\xf7\x4b\xc0\x19\xbc\x7a\xca\x90\xd6\x16"
+  "\xf2\x0f\x5f\x05\xd8\x11\x7f\x47\xe7\x9e\x33\x42\x21\xf2\x3b\x04"
+  "\x1e\xec\xba\x34\xa9\x07\x4c\xe9\x26\x3a\x2b\xeb\xbd\xee\x3a\x25"
+  "\xee\xb3\xdc\xae\xa5\xb4\xc7\x99\x48\x7e\x5c\x7c\xe2\x9c\x64\x90"
+  "\x62\xba\xd1\xda\x26\xf3\x9e\xe7\x13\x77\xb9\x3d\x63\x83\x7d\x75"
+  "\x5e\x7e\xc6\x5a\xfb\xed\x56\x8a\x3f\xbf\xfa\x21\xeb\xca\xec\x95"
+  "\xab\xf3\xd6\x5f\xc8\x07\x1a\xfd\x65\xd7\x6d\x06\x6e\x88\x58\xa6"
+  "\xef\x82\x93\x94\xba\xe1\x6f\x2e\xa1\xb1\x7e\xf6\x19\x19\x43\x00"
+  "\x79\x76\x41\x16\x12\x36\x44\x4a\x5d\x73\x3a\xaf\xcf\x6d\x2d\xa7"
+  "\xf3\xde\x6b\x89\x97\xf7\x32\x37\x3b\x83\xb6\xc9\x78\x72\x5d\x41"
+  "\xf0\xba\x05\x85\xbc\xad\xe0\x0c\xe1\xf8\x5c\x5e\xf5\xfc\x02\xde"
+  "\xb0\x92\x9d\xab\x7a\xb4\xae\x4f\xf7\xcd\xb9\xe7\xaa\x9e\x9f\xab"
+  "\xc5\x7c\x09\x55\x3e\x5f\xa7\x98\x5e\x6a\xa1\x98\x2f\x63\xdc\xc2"
+  "\xf6\x03\x96\xa3\xae\xcf\xd2\x41\xe3\x97\x34\x38\xb1\xee\x40\x06"
+  "\x10\xfe\x28\x5e\x58\x69\x0f\x71\x9b\x21\xe4\x64\x46\x5c\x13\x78"
+  "\xc2\xcb\x9e\x31\xd3\x0b\xa9\xf4\x9e\x62\xbd\x84\xc6\x6c\xac\xe8"
+  "\x00\x57\xfe\x2b\x07\x78\xe3\x64\x5c\xc4\xd7\xcc\x39\xc9\x90\x1e"
+  "\xa7\x54\x3f\xdf\x36\xb0\x80\xe9\x29\x2f\x78\x1a\xb6\x14\xf7\x85"
+  "\xcb\x58\x3c\xf2\x99\x0b\xdf\x45\xba\xdf\x16\x17\x2c\xb6\x19\x47"
+  "\x8b\x6d\x71\x63\xdc\x66\x72\xf7\x07\xd8\xd8\x75\x2b\x4b\x6e\xf4"
+  "\x32\xc3\xb3\xe0\x7d\x1a\x14\xcc\xaf\xfa\xdc\xa6\xd0\x63\xb6\x98"
+  "\xe0\x63\x36\xc3\xd8\x98\xcd\x18\x5c\x67\x33\x8c\xae\xb3\xc5\x8c"
+  "\xf9\x6d\x46\x77\x96\x97\xbd\xe7\x7d\x89\x75\xf5\x0f\x0a\xfd\xe1"
+  "\x58\xfc\xcb\x43\x63\xf1\xcf\x77\x9a\xfa\x59\xd2\x4d\x76\x46\xbc"
+  "\x90\x6e\x2b\x78\x5d\xe0\x84\x29\xf8\xfc\x4a\x3b\xaf\x7a\xb9\x16"
+  "\xf0\xbd\xea\xee\xeb\xf9\x97\xa1\xb2\xd9\x43\xd6\xff\x00\x2d\x2a"
+  "\x35\x24\x23\x0d\xf8\xf3\x9d\xa5\xbc\xec\xb6\x9d\x90\xbb\xad\xf8"
+  "\xa5\x78\xe4\x38\x80\xef\xfa\x56\x13\x9e\x93\x29\xaf\xcc\x77\x8b"
+  "\xd7\x23\xae\x37\xa5\x89\x38\x98\x65\xd7\x2d\x6c\x10\xf2\xd8\x37"
+  "\x17\x6b\x7c\x74\xbb\x61\xe2\x33\xe5\xc8\x93\x3f\x2e\xd7\x2a\xa0"
+  "\x27\x55\x3b\x9a\x26\xa6\xd3\x07\x73\x69\xbf\x51\x01\xdc\x50\xe7"
+  "\x31\xf2\x6d\xc4\x8b\x17\xa8\xb2\xe4\x37\x85\x5d\x20\x9d\xc3\x26"
+  "\x7d\x83\x9a\x26\xf4\x46\x8a\x3e\x8d\xfc\xbb\xb7\x92\x3f\x29\xd2"
+  "\x2f\x00\xaf\x3b\xd0\x56\x8a\xf9\x11\x0d\x39\xac\x05\xbf\x56\xfc"
+  "\xda\x9e\x22\xbd\x83\x93\xdd\xad\xe9\x64\x26\x6e\xab\xcd\xea\x61"
+  "\x55\x3d\x61\xb9\xd4\x96\x8a\xb2\x2e\xdd\x07\xab\xce\x96\x7a\x11"
+  "\xfd\xb0\x81\xfc\x9d\xf2\xea\x1d\xdd\xb5\xca\xb8\x7f\x54\xd0\x7d"
+  "\xdb\xe3\xa0\x13\x25\xe2\x5d\xe5\x0b\x69\x45\xa7\x59\x14\xbd\x6b"
+  "\x21\xdb\x04\x3c\x5b\xf3\x74\xdc\xed\x0b\x30\x7c\x63\xe0\xc9\xb9"
+  "\xad\x2d\x23\x5e\x3d\xcd\x8b\x2e\xa4\xe1\xdb\x86\xda\x11\xb5\xdc"
+  "\xba\xe6\xcc\xe2\x47\x99\x88\x57\x41\x31\x6f\x68\xbe\xd4\x16\x41"
+  "\xe6\xa3\xf8\x3c\x79\x51\xa0\x57\xb6\x4f\x70\x6f\xa4\x7c\xdc\xf4"
+  "\x42\x9a\x82\x32\x30\x67\x76\xf1\xf8\x17\x6c\x4a\xd5\xf3\x2d\x58"
+  "\x1f\xec\xfc\xaa\x95\x16\xe5\xd9\x66\xc8\xd5\xd7\x53\xff\x85\xdc"
+  "\x4e\x7e\x6b\x48\xa7\x11\x82\x6c\xdd\xb5\x2b\xc8\xf8\xf7\x83\x6c"
+  "\x5f\xfe\x59\xe6\x8d\xfd\x6c\xa9\x37\xfe\xa5\x3a\x6f\xfc\xcb\xb5"
+  "\xa1\xf8\x97\x7a\xf0\xeb\xb5\xe7\xd1\xde\xee\xf5\xbe\x71\xff\x8b"
+  "\xa7\x2f\xee\x7f\x11\x65\xa6\x68\x3e\x18\x43\xeb\x2e\xdd\xff\x62"
+  "\x48\xff\x97\x60\x43\xc1\xdf\xf7\xbf\x08\x1e\x93\x62\x87\xb7\x69"
+  "\x7e\x45\x42\xc2\x56\x9c\x99\x42\xf1\x2f\x58\x84\x6f\x12\x47\x9b"
+  "\xf0\x2f\x42\xbc\x26\xad\x35\xfe\xb2\x1b\x52\x35\xfe\x91\xe8\x67"
+  "\xa8\xfc\xb3\x1c\xfc\xb2\x90\xbe\xc0\xa3\xbb\xa3\x50\xa3\xad\x58"
+  "\x4f\x17\x87\xe2\xb2\x86\xfc\x64\xff\x3f\x96\x73\x27\xe5\x05\x1c"
+  "\x4b\x50\x77\x54\x68\x2c\x67\x1e\x7e\x77\xe0\xf7\xdd\x50\xd5\xf3"
+  "\x69\xa1\xaa\x97\xed\xa1\xaa\x47\x97\xe0\x97\x8e\xdf\x52\xfc\x32"
+  "\xf1\xcb\xc2\x2f\x87\x57\x3d\x9a\x8b\x2b\xbd\xcf\xc7\xcf\x81\x5f"
+  "\x21\x7e\x25\xf8\x6d\x0e\x3d\xdb\xbc\x38\xa4\x33\x24\xe3\x97\x82"
+  "\x9f\x35\x54\xf5\xd2\xae\x50\xd5\x0b\x56\x71\x26\xb3\xec\x86\x1e"
+  "\x0d\x4f\x27\xf6\xf3\x69\x4c\x17\xfe\xf7\xa3\x3f\xe7\x66\x8a\x0d"
+  "\x5b\x78\x96\x7c\xaf\xa5\xef\xb3\xf9\x2e\x2d\x0e\x83\xee\x5b\xc6"
+  "\xc9\xf0\x9a\xca\x07\x8d\x19\xbb\xc4\xf2\xd2\x27\xd5\x8d\x58\x9a"
+  "\xd3\x83\xc9\x2b\x59\xd0\xc9\x4a\x40\xd7\x74\x5d\x99\xfd\x6c\x91"
+  "\x97\x15\x77\xf6\x8f\xb2\xe2\x2c\x1e\x12\x34\xa0\x90\x6c\xb0\x9f"
+  "\xca\x22\x1c\x0f\xf1\x74\xeb\x58\xe5\xf3\x0b\x42\xa6\x97\xec\xdc"
+  "\xf4\xd2\x2e\xe1\xcf\x0d\xb4\x84\xe2\x5d\x8d\xcb\x9f\x84\x73\x90"
+  "\x41\xf7\x0f\x9d\x65\x8f\x65\x71\x65\x7f\x0e\x78\xaf\x1e\x20\x9e"
+  "\x8e\xed\x10\xb8\xa7\xca\xa0\xff\x4f\x2f\x2f\x01\x2e\xc5\x86\x00"
+  "\x37\x85\x64\x4f\xe0\xdd\xf6\x02\x96\xaa\xe1\x1e\xd6\xf4\x44\x2d"
+  "\x46\x10\x8f\xb9\x61\x08\xef\x0c\x14\x43\xa8\x1e\x32\x68\x7d\x01"
+  "\x4b\xa9\xc7\x3b\x11\xef\x11\xed\xbe\xd7\x6e\xe6\xca\x23\x36\xd6"
+  "\xf8\x30\x33\xc6\x9f\x94\x31\x44\x43\x80\x7d\xd8\x8f\xfe\xa3\x75"
+  "\xf7\x9c\xb4\xb2\x7d\xb6\xc3\x58\x9b\x5b\x30\x2e\x8f\xd6\x8d\x61"
+  "\xfd\x02\x2c\x43\x97\x06\xcb\xd9\x3b\xff\xdf\x82\xe5\x58\x72\x6e"
+  "\x93\x84\x67\x26\x23\x98\x5d\x08\x4f\x82\xf1\x86\x7e\xc0\x13\x70"
+  "\x75\x1f\x08\x41\x96\x64\xcb\x34\x78\x6e\x03\x3c\x01\x53\x0b\xc1"
+  "\x14\xf0\x10\x30\xe5\x2a\x4c\x1b\x23\x60\x0a\xda\x25\x7c\xdf\x11"
+  "\x4c\x15\xc0\xb4\x71\x12\x98\x8e\xcb\xf2\x80\xe9\xf6\x7f\x08\xa6"
+  "\xbb\xfe\x17\x30\xbd\x71\xd2\xf8\x5f\x41\xe2\x1b\xaa\x1f\xad\xe5"
+  "\xa0\x8b\xee\xe0\x7b\xc2\x8f\x23\x78\xbe\x5e\xf0\xae\x3d\x8a\xe9"
+  "\xf9\x3a\x8a\x09\x4d\x7b\xee\x14\xb3\xaa\xd8\xc1\x8f\x14\xef\xe2"
+  "\xe7\x42\xd5\x2f\x7b\x29\x0d\x74\x2d\xe7\x66\xb2\xf5\xb1\x7b\xb0"
+  "\x76\xf1\xd6\xae\x11\xd2\x79\xdd\x72\xcb\x28\xf1\xd4\xd5\xcd\x37"
+  "\x2b\x3c\x87\x11\x4d\x79\xe0\x7a\x66\x18\x05\xdd\xb0\x17\xb0\x6b"
+  "\x6a\x41\x0b\x47\xab\x5e\xea\x3d\xa1\xbb\xa9\xf3\x6e\xbb\xc2\xf1"
+  "\x2b\x26\x7f\x84\x0a\x68\x2e\x68\xb9\x18\x5f\x1a\x33\xda\xcb\xdb"
+  "\xff\xc0\x5f\x50\xde\xcd\xaf\xbf\x9f\x19\x64\xc5\x39\x5f\x1d\x5f"
+  "\xa5\x38\x1d\xbc\xe7\xdf\x9f\x27\x14\x37\xaf\x70\x90\xc6\xb5\x85"
+  "\xb9\xfb\xc3\xf3\x44\x51\x69\x34\x8d\x05\xcd\x0b\x9a\x23\x35\x11"
+  "\xb4\x19\x74\x3f\xb1\x41\x8d\x23\x11\x72\x82\x36\x93\xdf\x71\x8c"
+  "\x25\xc5\x97\x98\x70\x7e\x3c\x86\xf9\xb1\x41\xc4\xf8\xb1\x00\x1e"
+  "\x2d\xa3\x7e\x39\x86\x34\x66\xee\x60\x87\x18\xbf\x5a\x75\x2d\x90"
+  "\x70\x7f\xe9\x65\xce\xd3\xc1\xcf\x25\xd8\x94\xea\x97\x3d\xdc\x9f"
+  "\x13\x47\x71\x9e\x20\xf3\xa7\x9a\xb3\xc0\x3f\x7d\x89\xb5\x62\x15"
+  "\xf0\xeb\x14\x4b\xd9\xbe\x0a\x3c\x91\x9f\x62\x75\xa1\x3d\xeb\x65"
+  "\x8c\x53\xa5\xec\x5b\x8b\xf1\x4e\xf8\x57\x54\x34\xff\x8a\xc3\x36"
+  "\xd2\x43\x84\x75\x43\xab\x6d\xfa\x70\x9d\x47\xbd\x21\x53\x82\x4d"
+  "\x9c\x1d\xd5\xa5\xca\xb8\xa7\xc6\xb7\x03\x04\xd7\x21\x5d\x6a\xab"
+  "\xd4\xd7\xbe\x1f\xb4\x17\x91\x4d\x4f\xea\x4a\x5e\xf1\x11\xf9\x95"
+  "\xd7\x9d\xd0\xde\x15\xa7\x13\x1c\x7c\x37\x95\x30\xd0\xf2\x84\x05"
+  "\x14\xc7\x9b\xfc\x67\x5d\x1a\x2e\xa6\x0a\xfb\xff\x90\xeb\xa8\x0f"
+  "\x70\x4a\x53\x2a\x8e\x06\x41\x53\x52\xf9\x23\xe8\xeb\xc3\xe8\xeb"
+  "\x09\xc0\xf5\x04\xfa\xba\x4e\xed\xab\x1a\xbf\x4c\x01\xfc\xf1\x6e"
+  "\xe2\xb5\x51\xeb\xeb\x23\x80\xb7\x6b\x6f\xc7\xc6\x93\xec\x72\x0e"
+  "\x7e\x7c\xff\x90\x38\xb7\xe3\x77\x07\x0f\x33\xaa\x57\xac\xdd\x95"
+  "\x8f\xe6\xdc\x0f\x7c\x24\x98\x83\x5f\xc0\x9a\xf7\x7c\x9b\x36\x0e"
+  "\xd4\x1e\x3e\x96\x13\xd7\xb8\x0a\xed\x21\xd8\x9f\x62\xb3\x69\x3e"
+  "\x03\xf6\x29\x8d\x04\xff\xf3\x63\x08\x27\x89\x31\x88\xc1\x18\xfc"
+  "\x9f\xf6\xbe\x06\x20\xaa\x2a\xed\xff\xcc\x75\x4c\xb4\x19\x18\x8d"
+  "\x5c\x72\xd1\xc6\x16\x77\xc7\xd2\xa4\xd6\xca\xca\x8a\x4c\x8b\x4a"
+  "\x85\x5a\xda\x28\xb1\x50\xd1\x86\x02\x04\x24\x24\x45\x40\x24\x5f"
+  "\xa4\x01\xa9\xc8\xc5\xe4\x4b\x40\x43\xc4\xa2\xb2\xa2\xa2\x6d\x4c"
+  "\x7b\x5f\x2c\xbe\xea\x4f\xef\x62\xab\x35\xb1\x64\x64\x68\x93\x8e"
+  "\x82\x30\x33\xf7\xff\x3c\xf7\xdc\xcb\xdc\x19\x66\x60\x66\xc0\x8f"
+  "\x7c\xa5\xae\x33\x73\xee\xb9\xe7\x9e\xf3\xfc\x7e\xcf\xc7\x39\xe7"
+  "\xde\x73\x62\x78\x0c\xb2\x79\x0c\x20\x5e\x06\x3f\xec\x01\xfd\x46"
+  "\x9f\xa2\x74\x8a\x81\x6b\x32\xba\xa9\x62\x98\xf5\xd5\xe0\x58\x5f"
+  "\x67\xfe\xd8\x43\xfb\xc8\x12\x5c\xe7\x91\xf5\xac\xfa\xab\xb9\x17"
+  "\xf4\x36\x87\xd7\x5b\x56\x7d\xb7\xa0\xb3\x47\x25\x37\xaf\x77\x4e"
+  "\x67\xff\x1a\xf7\x7f\x54\x67\xbd\xcf\xad\xce\xce\xbc\xdd\x5a\x67"
+  "\x67\x46\x59\xeb\xec\xcc\xc9\x16\x9d\xe5\xcf\x0d\x8b\xce\xce\x9c"
+  "\x75\x61\x74\x76\xe6\x2c\x3b\x3a\xdb\xe2\x84\xce\xfa\x38\xd0\x59"
+  "\x9f\x73\xa7\xb3\xb7\x84\x9d\x3f\x1f\x3b\xab\xb0\x87\xb1\xe3\x63"
+  "\xd7\x8a\x7c\xac\x1c\x7d\xec\xad\xfe\xf6\xf4\xb5\xb7\x00\xf4\x55"
+  "\xc6\xeb\xeb\x93\x1f\x41\x79\xb7\x4d\xfd\xe2\xf0\xe0\xfa\x6a\x2c"
+  "\xb0\xc4\x4f\x0e\x75\x56\x8d\x3a\x5b\x41\x9a\x74\x9c\xce\x2e\x11"
+  "\x74\xb6\x80\xef\x0b\x0d\xa0\xb7\xde\x8e\xf4\x16\xf7\x74\xc2\xfd"
+  "\x9c\x06\xd4\x5b\x3e\x5e\xea\x9d\x88\x7a\xab\xbd\xc8\x7c\xed\x6d"
+  "\xbf\x59\xeb\xed\x2c\x3f\x6b\xbd\xbd\xed\x90\x45\x6f\xf9\x73\xc3"
+  "\xa2\xb7\xb7\xe9\x2f\x8c\xde\xde\xa6\xff\xfd\xf8\xda\xdb\xbd\xcf"
+  "\x9f\xaf\x9d\xfd\x04\xa7\xb7\x8e\x7c\x6d\x2a\xef\x6b\xe5\xe8\x6b"
+  "\x6f\x3f\xee\x9c\xee\xde\xf1\xe3\xff\x71\xdd\x3d\xc7\x3e\xf7\xce"
+  "\x3d\xd6\xba\x7b\xa7\xce\x5a\x77\xef\x7c\xcd\xa2\xbb\xfc\xb9\x61"
+  "\xd1\xdd\x3b\xab\x2e\x8c\xee\xde\x59\xf5\xfb\xf1\xb9\xb3\x1d\x8e"
+  "\x81\x2a\x27\x91\xb4\x36\xc9\x5d\x53\x9b\x0a\xb8\xe7\xf5\xd2\x9a"
+  "\x8c\x77\x10\xfa\x5c\xc9\x5d\x8f\x34\xf9\xcc\x22\xe6\xac\xef\x9a"
+  "\x71\x1f\x03\x7c\xbe\xe5\x55\xd1\xf3\x23\xf4\x79\x87\xbb\xe2\x84"
+  "\xe7\x5f\x8a\xf9\xbd\x0e\x06\x7a\xfe\x85\xcd\xfc\x8e\x7f\xc6\xe5"
+  "\xae\x2a\xca\x8d\xef\xd4\xc2\x6f\x6e\x4d\x2a\xc9\x5d\xd5\xec\xa6"
+  "\xef\xc2\xf5\xa3\xbf\x73\xb4\xf7\x83\x87\xe7\x7a\x96\xc5\x3d\x82"
+  "\x4e\x4d\x8a\x56\x9e\xca\x22\x24\x97\x9b\x87\xb9\xab\x03\xae\xe5"
+  "\xe6\xc2\x4e\x79\x4e\x56\x9c\x4a\x0f\x26\x90\x66\x14\xd2\xb8\x7d"
+  "\x94\xd3\x47\xb0\x66\x38\xc7\xe6\xc4\x1a\x8b\x53\x88\x07\xae\xf3"
+  "\x79\xe3\x19\xe4\xe2\xdd\x32\xb0\x11\xde\xb8\xcf\x10\xee\xed\xc0"
+  "\xfe\xe1\x8f\x86\xa2\x93\x44\xda\x98\xc1\x8d\x3d\xe3\x73\x33\x25"
+  "\x39\xc8\xff\x11\xd7\xe7\xb3\x8c\x94\x98\x0b\xa3\x3d\x58\x79\xa5"
+  "\x8e\x7b\x4e\x17\xb8\x22\x3c\x4b\x83\x7b\x6f\x99\x27\x46\x55\x08"
+  "\xeb\x4c\xb2\x50\xbf\x7f\xa6\xe8\x19\xdc\xef\xba\x28\x9e\x28\xe0"
+  "\x90\xb1\xd9\x95\xba\xae\x8d\x77\xe7\x09\x63\x89\x0e\x9f\xb9\xc6"
+  "\xbd\x60\xff\xe8\x23\xe5\x9f\xdb\xc1\xf7\x65\xb9\x7d\x32\x36\x33"
+  "\xe6\x4c\x13\xa4\xb3\xe9\xa9\xdc\x5e\x4f\x5e\x20\x0b\x7c\x4e\x16"
+  "\xf7\xe0\x31\x17\x45\x2b\x37\x4c\x20\xe4\xcd\x35\x1d\x0c\x3e\xb7"
+  "\x61\xfa\xc7\x1f\x0d\xda\x94\x9b\x71\x3d\x09\x6e\x7d\xed\xa3\x92"
+  "\x7b\x5e\x0e\xfa\x99\xee\xfb\x0a\xdf\x0b\x71\xfe\x65\x01\xfc\xc6"
+  "\xb9\x7c\xf3\x29\x1f\x29\xe6\x85\xf4\x07\xb5\x89\xdf\x12\xaf\x58"
+  "\xee\x59\x76\x0f\x3e\xaf\x0f\xe6\xd5\x49\xee\xe1\xde\xbb\x80\xdf"
+  "\xdc\x9e\x8a\xf8\xbc\x3b\x3e\x9b\xc4\x16\x44\x7b\x70\xf6\x41\x53"
+  "\xa9\x33\x4f\x8c\xf6\xe0\x9e\x31\x85\x76\x6e\x86\x36\x43\x1e\x19"
+  "\x3e\x87\xc3\x7d\xa6\x10\x45\x1e\xa4\x61\x39\xf0\x29\xd3\xc6\xe0"
+  "\x73\x25\xf7\xe0\x1a\xb5\x0e\xc7\xcd\xc1\x1e\xeb\xd8\x74\x29\xa1"
+  "\xef\xe0\x48\xbe\x6a\x93\x04\xcc\xf6\x92\xb0\x2c\x5b\x10\x55\xb1"
+  "\x01\xc7\xb8\xf1\xf9\x69\xee\x99\xf0\x80\xab\xa1\x7c\x69\x31\x37"
+  "\x86\x7b\x8f\x41\x27\xb9\xbb\x84\x5f\xfb\x82\xee\x11\x22\x09\x98"
+  "\x8f\xf7\xc1\x6b\x68\xfe\x7b\xda\xe9\xb3\xca\x95\x3a\x65\xca\x08"
+  "\x16\xce\xdf\x42\x9f\xb1\xf6\x08\xef\xda\x18\x30\xd3\xf2\x6c\x19"
+  "\x77\x1d\x70\x29\x00\xc7\x7f\xb9\x77\x46\xf0\xb7\xc3\xe7\x97\x79"
+  "\xdc\x1a\x7c\x80\x1b\xb6\xd8\x09\x1c\x01\x5e\x08\x1c\xc1\xfa\xbe"
+  "\x95\xa2\x63\xe8\xfc\x46\x00\xb7\x2e\x61\x0e\x60\x68\xda\xe6\x83"
+  "\xeb\x18\x12\x73\x2f\xe2\x82\xcf\xc1\xdf\x9b\x8d\xb8\x6c\x06\x5f"
+  "\xc0\xe7\xad\xb6\xd4\x1f\x7f\xdf\xcb\xe1\x69\x06\x2c\xe8\xf3\xf8"
+  "\xf7\x2e\xe1\xf6\x3b\x01\x9b\x81\xcf\x82\x1f\x48\x82\x7a\x21\x6f"
+  "\x81\x23\x6f\xc6\x77\x33\x45\x89\x34\xfd\x9f\x27\xbb\x19\x7c\xee"
+  "\x03\xc7\xc2\xb3\x9f\x25\x52\x1c\x53\xc7\x32\x59\xdf\xa8\x8a\x19"
+  "\x02\x8e\x6b\x00\xbb\x44\xe0\x2e\xc8\x7c\x33\xc8\xaf\xa8\x87\x9b"
+  "\xaf\xaa\x28\x32\x13\x99\x19\xf2\xe9\x24\xf7\x16\x40\x79\x8a\xc2"
+  "\xf1\xac\x1e\x9f\xbf\x06\x19\x26\x74\x6d\xbc\x37\x49\x90\x21\xd6"
+  "\x09\x9f\x9f\xce\xe6\x9e\xa3\x0f\x30\x50\x0e\x05\x1c\x10\xda\xec"
+  "\x48\x9e\xd9\x6f\x12\xdf\xec\x1b\xc9\x2c\xb3\xcc\x23\x94\x1d\xf1"
+  "\xc7\x12\x1c\x6f\x5e\xd8\x49\x08\xae\xc9\x1e\xf4\xe2\xf7\x6c\x93"
+  "\xde\x44\xcc\x72\x8f\x50\x9c\x9b\x30\x6d\xb8\x7e\x5c\xd0\x0b\xb8"
+  "\x1f\xfd\x8e\xc0\xd4\x6e\xa2\x68\x4a\xd1\xd3\x7d\xb9\xc8\x6f\xc4"
+  "\xb4\x0a\x6c\x38\xd8\x75\xf0\xa9\xd2\xd4\xdf\xc8\x35\x28\x2f\xb3"
+  "\x7c\x47\xe0\x51\xc9\x9c\x05\x8f\x25\x90\x34\xd7\xec\xe8\x1c\x6e"
+  "\x0d\x32\x8c\x2f\xc0\xe6\x33\xdc\xbe\xeb\x7a\x88\x4f\xb2\x77\xb8"
+  "\xb6\x37\xb0\x64\x4e\xb8\x23\x1b\x89\xed\x36\xe3\x38\x34\xdf\xe6"
+  "\x20\x6c\xb3\xa1\x9b\xe0\x58\xfe\xc2\x38\x5c\x27\xf4\x34\x31\x67"
+  "\x7b\x84\x62\x9b\x21\xd6\xa9\x73\x7d\x4c\x7f\xce\xe1\x81\xee\xcd"
+  "\x82\xbc\xcd\x1b\xfe\x58\x62\x96\x55\xd6\xe1\xbd\xb1\x0e\xf8\x1e"
+  "\xcd\xc2\xd3\x84\x93\x3b\xca\xbf\xa9\xdb\x44\x58\xb9\xb8\x0e\x46"
+  "\x17\xeb\x70\x9f\xe3\xf6\xdf\x48\x7c\x35\x6f\x52\xdc\x4d\x1b\x78"
+  "\x19\xa8\x71\x8e\xac\xb2\x0e\xf7\x12\x5b\x88\x75\xd0\x1f\x27\x0b"
+  "\x8e\x13\x0e\xff\x26\x55\x27\x31\x8d\xb8\x7e\x1c\x3e\x53\x81\xf8"
+  "\xa7\x18\x01\xff\x33\xdd\xb8\xb6\x87\xbe\x29\xed\x2c\xc1\xf8\xc5"
+  "\x78\x4a\xc5\xf4\xc7\x7f\xee\x82\xc7\x92\x5c\xc5\x7f\xee\x30\xe1"
+  "\x3f\xf7\x22\x68\xff\x3c\x37\xda\x3f\x6f\x98\xda\x3f\xef\x22\x68"
+  "\xff\xfd\x6e\xb4\xff\xfe\x61\x6a\xff\xfd\x0e\xdb\x7f\xdf\x35\x66"
+  "\x96\x7b\xd6\xc6\x73\x7b\x35\xfa\x00\xea\xaf\x1e\x98\x87\xcf\xd2"
+  "\x70\xef\x4d\xf1\xbf\x09\x7d\x8f\xca\xc3\xe6\xb7\xcc\xe6\xb7\xc2"
+  "\xe6\xb7\xb7\xcd\x6f\x1f\x9b\xdf\xbe\xc2\x6f\xf0\x23\x23\x4f\x48"
+  "\xee\x7f\x0f\xe2\xd2\x34\x9d\xe4\x81\x60\xfe\xbc\x1f\xae\x7d\x03"
+  "\x3e\xdd\xcf\xd1\xde\x70\x72\x09\x61\x7b\x19\x96\x70\x7b\xb6\x49"
+  "\x1e\x38\xd0\x93\x4e\x58\x76\xc4\x04\x15\xee\xab\x65\xd6\xc4\x25"
+  "\x2c\x04\x3b\xdd\xa4\xef\x86\x38\xdf\xe7\x0a\x28\xfb\x0f\xb8\x5f"
+  "\x20\xe2\xaa\x8c\xc7\x67\x6b\x1e\x78\x1b\xdb\x79\x63\xac\x96\x98"
+  "\x47\x5c\xcf\x3d\xdb\x60\xce\x8e\x4b\xd0\x8f\xb8\x7e\x02\xbb\xb5"
+  "\x2a\x38\x3b\xdd\xec\xd1\xd4\xd9\x42\x72\x18\xb3\x32\x39\x19\xf0"
+  "\xed\xdc\x4b\xd6\x76\xb2\x1d\xc9\x46\xb6\xbb\x29\x4c\x4b\x52\xf5"
+  "\xb8\xdf\x46\x1d\x69\xd4\xb7\x70\x7b\x6e\x70\x7b\x8b\xe8\xf7\x12"
+  "\x8c\x7f\x52\x31\x0f\xa4\x35\xea\xab\x48\x03\xfc\xd6\xc6\xfc\x08"
+  "\xed\x0c\x5c\xd2\xd4\x59\x05\xfd\xa5\xb8\x58\xb3\x2c\x2e\x84\x95"
+  "\xc5\x85\x36\x74\xe2\x5e\xa1\x71\x61\x58\xd7\x46\xa8\x47\x93\xb1"
+  "\x06\xfb\x59\x61\x5c\xb9\x86\x66\xae\x4f\x8a\x73\xb6\x66\x39\xe4"
+  "\x97\xc7\x85\x62\xfd\xb0\x6e\xf6\xe7\x61\xb7\xb7\x43\xdd\xef\x78"
+  "\x4c\x25\x25\xf8\xae\x83\x6b\x1c\x09\xcc\x70\x18\x47\x6b\x4a\x23"
+  "\x68\xb9\x1e\xee\x94\xeb\xd0\xfe\x43\xb9\x7c\x7d\x15\x6e\x94\xfb"
+  "\xe0\x4c\xc7\xe5\x96\xf1\xf5\x55\xba\x53\xae\x66\x80\x72\xf9\xfa"
+  "\x06\xb8\x53\x6e\xbb\xe3\x72\xcb\xf9\xfa\xa6\xb9\x51\xee\x43\xb3"
+  "\x1d\x97\xbb\xbd\xdd\x3d\x2e\x3c\xd4\x6f\x0f\x6b\x31\x17\xdc\xe3"
+  "\xc1\x43\x03\xb4\xbf\xb4\xdd\x3d\x0e\x3c\xec\x78\xfd\x07\xe0\x80"
+  "\x7b\xf8\x3f\x3c\x20\xfe\xee\x61\xff\xb0\x6e\x20\xec\xdd\xc3\x7d"
+  "\xbe\x43\xfe\x63\xdf\x00\xb0\x2f\x61\x3d\xab\x02\xcc\x39\x71\x25"
+  "\x66\xcf\xed\xa5\x1b\xcc\x01\xe4\xbe\x75\x84\x78\xe5\x93\xb1\xf7"
+  "\x15\x7e\xcf\x06\x70\x7d\xee\xf9\xf5\xeb\x0a\x08\x03\x7d\x68\x66"
+  "\xcf\x9a\x56\xa6\xc9\x38\x0b\xed\x96\xa9\x3c\xb1\x5b\xf2\x27\x48"
+  "\xdf\x07\x7e\xd0\x00\xb1\x2c\x2d\x2b\xae\x24\x27\x25\x80\x70\xef"
+  "\xc1\x41\x3f\x62\x61\xdc\xf7\x2c\xae\x1b\x18\xf4\x1b\xd8\xd7\x7c"
+  "\x5c\x87\x90\x8c\x85\x6b\x8d\xc0\x63\x28\xa7\x9b\xbc\x65\xd6\x4b"
+  "\x16\xea\xb9\xbc\x7a\xee\xd9\xf4\x9c\xed\xa5\xd8\x57\x60\x53\x55"
+  "\xb8\xa6\x98\xfe\xa8\x64\xc1\x5d\x23\xf4\x84\x29\xc2\x7d\x71\x36"
+  "\x2e\x98\xa5\x93\x2c\x54\xf1\xef\x92\x76\x72\x6b\xdf\x41\xdd\x71"
+  "\xed\xbb\x0d\xd0\x6f\xc0\xfc\x37\xc6\x12\x06\xd7\x27\x86\xbc\x11"
+  "\xb8\x1e\xde\x40\xef\x64\x9b\x34\x95\x19\x78\x3d\xab\x01\xff\x7c"
+  "\x9c\x30\x8d\x06\x3d\x61\x7d\xa3\x49\x0e\xf4\x4f\xe6\x4d\xc5\xf1"
+  "\x94\x93\x24\x65\x1d\x6b\xc6\xb1\x2d\x56\xb6\x63\x16\x3e\x7b\xc8"
+  "\xad\xd5\x2e\x59\xc8\xed\xb5\xce\xef\x65\x34\xe1\x18\xfc\xe6\xfa"
+  "\x48\xf8\x0c\x8e\x2c\x4e\xc5\xe6\xc8\x03\x1a\x0d\x27\xb9\xbd\x38"
+  "\xda\x24\x0b\xb9\x75\xc9\x4e\xc9\x2a\xd3\x0c\xb2\xca\x4c\xa8\x97"
+  "\x51\x68\x03\xde\x5f\x48\xc7\x3e\x21\xe6\xeb\xda\xb8\xd0\x57\x78"
+  "\x47\xdb\xc1\x3e\xb8\xe3\x82\x7c\x58\x3d\xca\x97\xd6\x25\x68\x3d"
+  "\x62\x00\x71\x48\x92\x21\x55\x35\x89\x8e\x91\x2c\xac\xc0\xbe\x36"
+  "\xd4\x3b\x82\xf6\x7b\xe3\x22\xb8\xfd\x3c\xc0\x1f\x3c\xa6\x62\x5c"
+  "\x8c\x89\x17\xe2\xaa\x82\x12\xed\x24\xf4\xbf\x41\x91\x50\xfe\x9d"
+  "\xd0\xa6\x7a\xda\xcf\x8b\xe3\xdf\xb3\x5c\x88\xcf\x0c\x25\xc1\x6f"
+  "\x25\xe6\x83\xf3\x9d\xfc\xf9\x34\xd1\xf9\x34\x7c\x16\x95\x9e\x0f"
+  "\x92\xf1\xe7\x33\x44\xe7\x33\x62\x27\xe1\xb8\x47\xd0\x4c\x6c\x03"
+  "\xc8\x31\x1c\xce\x27\x70\xeb\x17\x70\xfb\x0f\xc6\x85\xf3\xf9\x12"
+  "\x3a\x25\x41\x0b\x4e\x01\xc7\xe0\x7c\xb2\xe8\xfa\xe4\xfd\x49\xfe"
+  "\xe4\xbe\x42\x94\x61\x50\xb8\x8e\xd9\x75\x80\xf6\x95\x17\x46\x71"
+  "\x6d\x07\x1f\x2a\x2e\x4f\x27\x09\x9a\x86\x7e\xd2\x00\x31\x1a\xe4"
+  "\x09\xc1\x7b\x8a\xe5\x2d\xbc\xed\xa9\x8c\x88\x5e\xa2\x5c\xb6\xf2"
+  "\xf9\x18\x7c\x5b\xcf\xfa\x3d\x34\x05\xbe\xcf\x6a\xd6\xec\x54\x37"
+  "\xe5\xe3\xfb\x75\x0a\xee\x5d\xee\x3c\xc0\xd1\x98\xb3\xbb\xc4\xe4"
+  "\xb9\xdb\xdf\x94\xb3\x23\x38\xf5\x34\x61\x52\x7c\xd8\x1f\xb4\x6b"
+  "\xe6\x90\x13\x92\xa0\xb3\xdc\xbe\x86\x4a\x6e\xbd\x7b\x83\x76\xcd"
+  "\x67\x90\x16\x3c\x16\x65\xd1\x14\x4e\xd3\xde\x4d\xa9\x63\x3e\x4d"
+  "\x69\x65\xea\xc3\x4f\x92\xfd\x3e\x7a\x72\x40\x79\x12\xd7\x7c\x35"
+  "\xbc\x6b\x6e\x66\xf0\xd9\x5c\xc8\xbf\x04\xef\x85\xe3\x07\xf8\x9d"
+  "\x8e\x85\x04\xfd\x88\xf7\xc1\xe7\x16\x41\x36\x3f\xe3\xfd\xa0\x7d"
+  "\x1d\x23\x0a\xf0\x39\x67\x22\x83\x7c\x3b\xcc\xd9\x3b\xd5\x9c\xbe"
+  "\x6f\x0c\xca\x37\x32\xb2\x72\xfe\xfd\x3d\x52\x30\x0e\x9f\xd1\x0d"
+  "\xce\x15\xbd\xcf\x26\x3b\xc5\x90\x7b\x20\xad\x5c\x58\x8f\x02\xf7"
+  "\x05\x72\x64\x3f\xce\x42\x3f\xf9\x6c\x41\x54\xa6\x59\xb6\x13\xe4"
+  "\xbb\x53\x5d\x57\x47\x70\x9c\x46\x82\xcf\x19\x77\x4a\x1e\xcd\x60"
+  "\xe5\x3b\x43\x53\x50\x4f\x41\x16\xbb\xf1\x19\x42\xcf\xdd\x25\x55"
+  "\xf8\xcc\x60\xce\x6e\xff\xca\xc4\x6e\xe6\x8b\xfa\x1a\xa2\xfc\x3b"
+  "\xc6\x58\x8f\x5c\xfd\x70\x04\x6b\xbc\xbe\x45\x4b\xea\xdb\xdf\x21"
+  "\x5f\x1e\xae\x23\xb2\x30\x32\x22\x55\xc7\x9a\xb8\xb1\x84\x04\xc2"
+  "\x04\xe9\xc8\x08\x5c\x2b\x09\xd7\x47\xc7\xfd\xbd\x1b\xbb\x1b\x20"
+  "\xee\x79\x35\x62\x4f\x4a\xc7\x48\xe5\xa3\x04\xe2\x25\x3a\x27\xcd"
+  "\xbd\xff\xa3\xe7\xde\xbf\x96\xe3\xf8\xb8\xe8\xbd\x1f\xe9\xba\xe3"
+  "\xc4\xa3\x41\x7d\x84\x24\x87\xb3\x66\x7c\xc6\x2f\x28\x7c\x04\xcb"
+  "\xbd\xfb\x93\x04\x99\x63\x01\xd3\xd5\x2a\xcf\xd7\x13\x89\x77\x63"
+  "\x82\x8e\x34\x75\xd4\x91\x6d\xf1\xc4\x9b\xed\x52\x8f\xae\xaf\xff"
+  "\x82\xb0\x39\x63\x94\x6f\xa5\x68\x47\x0a\xcf\x63\x79\xad\x97\xe0"
+  "\x78\xa8\xa7\x06\x9f\xcb\x3a\x43\xfc\x9f\xfe\x31\x8d\x1b\xc3\xc5"
+  "\xf1\x72\x63\x97\x4a\xd9\xdb\xa5\xba\xae\xa7\x4b\x35\x49\x18\x67"
+  "\x5f\x1c\xa9\x20\x85\xf8\xce\xd0\xc6\xfb\xfc\xf0\x9d\x21\x8c\x2f"
+  "\x8d\x72\x4f\x15\x8e\xa9\x73\x6b\xbf\xac\x56\xf9\x9a\x97\xa9\xc8"
+  "\x0c\x3d\xf7\x4e\x12\x8e\xf3\x2b\x8a\x96\x42\x7d\x3b\x4f\x12\xf1"
+  "\xb3\x45\x67\x57\xab\x18\x7c\xae\x88\xdd\x18\x5c\xdb\x53\x18\x95"
+  "\x89\xcf\x17\x81\x5f\x98\xe5\xba\x6e\x3f\xca\xc5\xcf\xd8\x7e\xc0"
+  "\xa3\xa4\xea\x24\xe2\x03\x38\x9d\xd4\x33\x88\x45\x43\x04\xe2\xd0"
+  "\x6c\x85\x03\x87\x5b\x7c\x37\x83\x78\x20\x16\x88\x89\x05\x8f\x6f"
+  "\x38\x3c\xaa\xcc\x14\x8f\x1e\xf0\x07\x02\x26\x67\x7d\xa3\xf2\x07"
+  "\xc2\x05\xf1\x40\x6c\xea\xdb\x8f\x10\x2b\x4c\xf4\x14\x13\x90\xe7"
+  "\x38\x01\x17\xc4\xa4\xa9\x13\x62\x5e\xc0\xe5\xa1\x6f\x08\x79\x78"
+  "\x2a\x6b\x6e\x98\xff\x75\x1f\x3e\x46\x47\xf8\xfc\x6c\xc1\x07\xb0"
+  "\xef\x8f\xcf\x71\x05\xce\xfb\x20\x3e\x15\xae\xe0\x53\xdf\x4e\xf1"
+  "\x31\xf2\xf8\x4c\x0d\x24\x4c\x77\x97\x8a\xd9\x9a\x48\x66\xcd\xff"
+  "\x51\x49\x3e\x0f\x6d\x20\x20\xeb\xf9\xe6\xec\xca\x24\xf7\xf4\xe8"
+  "\xb1\x7a\xe7\xf5\x28\x64\xf1\x65\x3d\x72\x55\x8f\x42\xa4\x43\xd3"
+  "\xa3\xc7\xf2\x2f\xeb\xd1\xf9\xd2\xa3\xc7\xf2\x6c\xf5\xa8\xcf\x57"
+  "\xc7\x2f\x8f\x5e\x12\x19\x13\x19\xf3\x8c\x72\xe9\x0b\x09\xcb\x57"
+  "\x51\x8f\x6d\xe5\xb3\x7d\x4c\x29\x01\x0c\xee\xd1\x5d\x9f\xdf\x4c"
+  "\xde\x9a\xd0\xcc\x98\x7e\xf2\x91\xb2\x1a\x65\xac\x59\xa3\xd4\xe3"
+  "\x7e\xdd\xa8\x6f\xb8\x8f\xf7\x51\x49\x98\x07\xae\xf3\x47\xd7\x4b"
+  "\x09\xa3\x7b\x0e\xfa\x46\xfb\xe0\xfc\xcb\x86\x1e\x38\xd6\x10\xa9"
+  "\x57\x37\xf1\xd0\x4e\xc2\xf3\x8b\x96\xe3\x9a\x64\x6c\x61\xb4\x4f"
+  "\x11\xee\xaf\xdd\x43\xa4\x06\x59\x9c\x32\x03\xca\xd3\xcb\x77\xaa"
+  "\xa5\x4a\x7c\x97\xe4\x71\x03\xf8\xe4\x6a\xcb\x3a\x44\x8b\x54\xec"
+  "\x15\x8f\xcf\x45\x5d\xc7\xf7\xfa\x4e\x48\x42\xa7\x9e\xc5\xb5\xd9"
+  "\x21\x86\x7d\x6c\x2a\xdc\x6b\x62\x54\x3e\xb7\xc6\x02\xe8\x3d\x3d"
+  "\xff\x44\x03\xd6\xa1\x57\xb6\x23\x98\xdb\xeb\x5c\xb6\xbb\xe4\x94"
+  "\x66\xb7\xff\x17\xc9\xd5\x44\xf9\x28\xea\x7d\xe8\x63\x0f\xe5\x83"
+  "\xde\x07\x6b\x49\x83\x4f\x25\xf9\x32\x14\xf8\x16\x3a\x98\xde\x8b"
+  "\x78\x36\xc9\x39\xbd\x17\xf8\x85\xbc\x42\x7e\x21\xb7\xae\x04\x6e"
+  "\x21\xdf\x04\x7e\xbd\x7a\x86\xf2\xcb\xeb\x30\x51\xbc\x7e\x12\x38"
+  "\x66\xa4\x1c\xc3\x77\x9a\x1b\x92\xbe\x76\xac\xff\x67\x6c\xf8\xc5"
+  "\xf0\xfc\x5a\x0d\xfc\x5a\x6d\xe1\xd7\xa2\x23\x0a\xb2\x8d\xe3\xd7"
+  "\x1c\x0b\xbf\xb2\x3d\x55\x02\xb7\x90\x67\xc8\x29\xf3\x33\x2a\x82"
+  "\x3a\x2f\xf0\xac\x68\x05\x9d\x43\xe5\xf4\x9f\x01\xfd\xef\x12\xf9"
+  "\xd1\x89\x43\xd1\xff\x27\x38\xfd\x47\x4c\x10\x1f\xc4\x05\xb1\xb8"
+  "\x14\x71\xc0\xfd\x8c\xd9\x2e\x7b\x58\xdc\x5b\x3d\x18\x16\x88\x03"
+  "\xe2\xc1\xe1\x00\x78\x08\xf3\xd9\x38\xbf\x89\x98\x20\x16\x37\x26"
+  "\x13\x06\x71\x29\x02\x9d\x47\x3d\x07\xd9\xe6\x21\x2e\x5c\xec\x9a"
+  "\x2e\x8f\xca\x1b\x67\xd9\x13\xa6\x6b\xe3\xa2\xc0\xfe\x71\xeb\xa2"
+  "\x30\xcb\x3a\x6a\xa1\x5c\xbf\x4c\x3b\x01\xd7\xc0\x7e\x9c\xef\xb3"
+  "\xec\xa4\x7b\x86\x48\xc2\x3e\xe4\x75\x9a\x60\xff\x8f\xeb\xeb\x99"
+  "\xa0\xaf\x27\x83\xbe\x9e\x06\xfa\x7a\x38\x16\xc7\xad\x3d\xb0\xe8"
+  "\x3d\x3a\x4f\x06\x7d\x3b\xf9\x8e\x59\xd0\xcf\x50\xa1\xfc\xb8\x39"
+  "\x59\x79\x65\x1a\xce\x21\xb1\xd9\xd0\x8f\x2c\x65\x08\xfc\x06\x0e"
+  "\x99\x5c\xe4\xce\xa2\x16\x7e\xce\x39\x9c\xae\xc5\x17\x56\x4e\xeb"
+  "\xf7\x38\xf7\xdc\x02\x37\x5f\xc7\x98\x4b\x4c\x1b\xac\xe7\xeb\xc4"
+  "\xf3\xb9\x6f\xa5\xe8\xf9\xb9\xba\x30\x61\x9d\x6f\x03\xda\xb5\x3d"
+  "\x29\xcd\x8c\x65\xbe\xee\x6b\x3c\x6f\x33\x5f\x17\xc6\x8d\xf7\xea"
+  "\x24\x61\x35\xf8\x8c\x0a\xfc\x4e\xa0\xe9\x8f\x57\x89\xd3\x2d\xf3"
+  "\xe1\x34\x1d\xdf\x89\xe2\xfb\xdb\x9d\xb4\xaf\x1d\xd6\x2c\xf4\x69"
+  "\x1d\xc4\x37\x2e\xd8\xdd\x25\x79\x16\xbb\xbb\x24\x8f\x93\x8d\x4f"
+  "\x55\x60\x43\x3f\xbb\x8b\x6b\x5a\x85\xff\xb6\x10\xed\xae\x66\x47"
+  "\x00\xad\xdf\xe2\xc5\x20\x93\x11\xb8\xaf\x1b\xa6\xe3\xbb\x43\x68"
+  "\x7f\x0b\xe1\xba\x42\xce\x26\x57\xcd\xca\xe0\xe6\xe5\x17\xa7\x59"
+  "\xdb\xe2\xf0\xbd\xd6\xb6\x78\xf1\x7b\x03\xdb\xe2\xa7\x9f\x18\xd8"
+  "\x16\x2f\xfe\xe1\xb2\x2d\x76\xd7\x16\x43\x2c\x36\x24\x5b\xfc\xb4"
+  "\xdf\x65\x5b\x7c\xae\x6c\xf1\xd3\x4a\x91\x2d\x7e\xdc\xda\x16\x87"
+  "\xb7\xf4\xb7\xc5\xe1\x1d\x16\x5b\xbc\x58\x63\xb1\xc5\x8b\xe7\x5a"
+  "\xdb\xe2\xa5\xf3\x9c\xb3\xc5\x4b\xee\x3d\xb7\xb6\x78\x49\xb8\xb5"
+  "\x2d\x5e\xea\xcf\xdb\x95\x29\xae\xdb\xe2\xa5\x63\x07\xb6\xc5\x4b"
+  "\xaf\xb1\xb6\xc5\x4b\x3a\xa9\xcd\x5d\x3a\x97\xda\xe2\xa5\xfc\x3b"
+  "\xa7\x8b\xfd\xc4\xe9\x16\x5b\x4c\xd3\xfb\xdb\xe2\xa5\x61\x83\xd8"
+  "\x62\x95\xc9\x2c\xd8\xe2\x56\xb0\xc5\xad\x8c\xf9\x19\x47\xb6\xf8"
+  "\x19\x4d\x03\xda\xe2\x78\xb4\xc5\xcf\x68\x06\xb6\xc5\xcf\xbc\x80"
+  "\x36\x17\xf8\x4a\x0a\xb6\xb0\x1d\xb8\xe6\xa2\x76\xc5\xb7\x38\xae"
+  "\xdb\x8e\xfc\x3c\x2a\x59\xf1\xd5\xc2\x64\xb1\xad\x5e\x36\xba\xcf"
+  "\x56\x43\xba\xf9\x1a\x6b\x5b\x8d\x76\x1a\xed\x75\xe1\x16\x56\x57"
+  "\xb4\x85\x3d\xdc\xb5\x71\xd9\x4c\xc1\x66\x67\x43\x1a\xee\xad\x81"
+  "\x6b\x02\x15\x9e\xe1\x0e\x29\xc8\xa0\x7d\x03\xdc\x17\xaf\x81\xbc"
+  "\xe1\xd6\xf6\x7d\x45\x9e\x71\xa3\xd8\xbe\x2f\x7b\x0d\xed\xbb\x86"
+  "\xbe\x17\xcf\xd9\x75\x63\x61\x54\x3e\xda\x7a\x7a\x7e\xf9\xed\x03"
+  "\xdb\xf7\x65\xfb\x2e\x94\x7d\x47\x9b\x72\xa5\xa8\x2f\xe7\xc8\xae"
+  "\x40\xdb\x0c\x0d\x11\xe7\xc7\xbe\xa3\x3d\x41\x3b\x82\xb6\x45\xb0"
+  "\xef\x68\x5b\x8c\x7c\x5f\xbb\x20\x5d\x64\xdf\xaf\x10\xd9\x77\x89"
+  "\x3b\xf6\x7d\xb9\xf4\x77\x65\xdf\x11\x87\xe4\x73\x6b\xdf\x85\x7e"
+  "\x35\xe2\x80\x98\x20\x16\xe2\xbe\x35\xe2\x80\x78\x20\x0e\x18\xd3"
+  "\x08\xf6\x7d\x7a\x12\xb5\xef\x85\x7d\xf6\x7d\x39\xe9\xb3\xef\x0c"
+  "\xb5\xef\x05\xb8\xee\x1b\x37\x46\xbc\x62\x6f\x7f\xfb\xbe\xa2\xce"
+  "\x62\xdf\x97\x45\xf1\xf6\xae\x1d\xd7\x6f\x00\xfb\xa5\xb7\xb6\xf1"
+  "\xea\xbb\x9c\xb3\xf1\xcf\x4c\xe9\x67\xe3\xf9\x3d\xee\x79\xfb\x9e"
+  "\x86\xf6\xdd\x88\x76\xde\x2d\x1b\xff\xcc\x5c\x8b\x1f\x5a\xda\x4c"
+  "\x6d\xeb\x0a\x9d\xb5\xdd\x57\xab\x78\xbf\xf4\xb6\xd8\xee\x9b\x47"
+  "\x38\x63\xf7\xd5\xa3\x05\xbb\x8f\x76\x75\x8f\xb9\x55\x64\xf7\xd1"
+  "\x4e\xaa\xc7\x6a\x13\xdb\x44\x76\xff\x99\x76\x5a\x07\xf5\x6c\x13"
+  "\x67\xf7\x9f\xe9\xe6\xfd\x47\xb5\x38\xdd\x62\xf7\x69\xba\x49\x6c"
+  "\xf7\x3b\xd0\xee\xab\x43\x06\xb1\xfb\x33\x9d\xb7\xfb\xd1\x46\x8b"
+  "\xdd\x8f\x36\x0e\x6c\xf7\xa3\x7f\x46\xbb\xcf\xad\x11\x0b\xd8\x03"
+  "\x9f\xa5\x39\xe3\xa9\xcd\xc7\x31\x11\xf0\x05\x3a\x5c\x37\x04\xf2"
+  "\x7d\x53\x8c\x7e\x01\x0e\x38\xdf\xa1\xc1\xef\x66\xee\x9a\xc3\x5e"
+  "\x7a\xe2\x81\x3e\x40\x73\x94\x48\x71\x8f\x22\x2a\xa7\xe8\x9b\xe0"
+  "\xda\x56\x8b\xbf\x88\xbc\xdd\x49\x7f\x81\x7b\xb3\x37\x77\x6d\x8c"
+  "\x8c\x10\xf9\x0b\xdc\xe7\xa9\xd9\xc6\x5f\xe8\xc0\x5f\xb4\x0b\xd7"
+  "\x40\xfe\x3c\x71\x7e\xac\x1f\x97\xff\x28\x77\x60\xfe\xd6\x0d\xb8"
+  "\x67\x19\xe7\x5f\x22\xb5\xd6\xfe\x25\xca\x60\xb6\xea\x3f\x44\x9e"
+  "\x16\xfc\x0b\xfa\x67\x73\x3f\xff\xf2\xdc\xd6\x3e\xff\x32\x5e\xe4"
+  "\x5f\x92\x04\xff\xf2\xec\xe4\x8b\xbe\xff\x30\x04\xbb\xe6\xae\x7f"
+  "\x41\x9b\x86\xf6\x6c\x20\xff\x62\x16\xf9\x17\xb3\x5b\xfe\xe5\xb9"
+  "\x88\xdf\x95\x7f\x39\x0f\xfd\x07\x31\x06\x88\x0b\xe7\x5b\x00\x1b"
+  "\xc4\x01\x31\x40\xf9\xe3\x7a\xd4\x88\x0d\xe2\x82\x98\x4c\x8f\xb5"
+  "\xf8\x16\x0e\x17\xce\xbf\x3c\x17\x6e\xeb\x5f\x8a\xc6\x09\xfe\x25"
+  "\xda\xbb\xbf\x7f\x89\x56\x59\xfc\x4b\x24\x37\x7e\x43\xd7\xfd\x8b"
+  "\x54\x5a\xfb\x96\x98\x3d\xce\xf9\x96\xe8\xf5\x76\x7c\x0b\xb7\x7e"
+  "\xa3\x66\x8b\x55\xdf\x21\x0d\xfc\x8b\x1b\xbe\x25\xba\x84\xd6\x11"
+  "\x9f\x8d\x56\xeb\xa9\xfd\x8e\x9e\x6d\xf1\x37\xea\x3a\x71\x9a\xc5"
+  "\xdf\xc4\xe4\xf3\x3e\x72\x97\xeb\xfe\x26\xe6\x05\xee\xd9\x03\x68"
+  "\xc3\x9e\x93\xd4\xa6\x5b\xfb\x9b\x98\xf5\xd6\xfe\x26\x26\x84\xd6"
+  "\x21\xa6\x8a\xfa\x9b\x18\x35\xef\xb7\x2a\xc4\xe9\x16\x7f\x43\xd3"
+  "\xfb\xfb\x9b\x98\x03\x83\xf8\x1b\x59\xaf\x6f\x54\x7e\xaf\x66\x77"
+  "\x9a\xb1\x3c\x5a\x39\x2d\xf4\x1e\x93\xad\xde\x50\x7d\x31\xd1\xfd"
+  "\x6f\x84\xf9\xa7\xa7\xe8\x7c\x87\x99\x7f\xbf\xb8\xc7\x37\x2a\xf3"
+  "\x68\x14\xe8\x4e\xa7\x63\xdd\x01\xbd\xf1\x10\xf4\xa6\x41\xfd\x23"
+  "\x01\x5d\x62\x70\x4e\x6a\x1b\xe8\x4c\x93\xa1\x95\xd3\x21\x59\x7b"
+  "\x00\xc1\x35\x1d\xe5\x9d\x44\x21\x97\x48\xae\xc0\xf9\x0e\x13\xe8"
+  "\xcf\xbc\xa9\xac\xf9\x86\xd6\x00\x22\x57\x13\x4f\xd4\xa1\x37\xf9"
+  "\x79\x0f\x5c\x1b\x02\xe7\x3b\x80\xbf\xfe\x4f\x7f\x65\x99\xef\xe8"
+  "\x71\x62\xbe\xa3\x29\x49\xc7\xcd\x77\xe0\xfb\x52\x66\xd0\x13\xee"
+  "\x1d\x1e\x9c\xef\xe8\xe6\xe6\x88\x38\xfb\x55\xcc\xcd\x77\xb4\x11"
+  "\x9c\xeb\x10\xd6\x86\xc1\x39\x8e\x1b\x42\x09\x83\x6b\x47\x6c\x03"
+  "\xbd\xf9\x5c\xd5\xc0\xe9\x8d\xeb\x36\x2c\x56\x35\xd0\x33\x3f\x46"
+  "\x90\xa9\x49\xb6\x3b\x8d\x7d\xbd\x2a\x76\x77\x5b\xb7\x04\xd7\xcc"
+  "\x34\x01\x46\x66\xb0\x55\xac\xcc\xc6\x56\xf5\xf2\xf2\xee\xa5\xf2"
+  "\x06\xac\x3c\x9e\x32\x10\x16\xd2\xe9\x9a\x99\xdd\x3a\xe0\x9a\x6a"
+  "\x5c\xe1\x1a\x94\xad\x3f\x29\xe4\xd7\xcd\x34\xaf\x55\x8f\x36\x83"
+  "\x3c\xf1\x3d\x89\x3d\x67\xba\x47\x9a\x64\x1e\xa1\x9a\x1e\x32\x0d"
+  "\xec\x92\x1c\xed\x12\xf0\x73\x4c\x71\x0f\xc8\xf6\x07\x2a\x5b\x5c"
+  "\xc3\x0d\x3f\x8d\x6b\x55\x4a\x28\xfb\xba\xde\x5e\x90\x6f\x37\x95"
+  "\xef\x53\x71\x0a\x52\x24\xcc\xf7\x81\xaf\x6f\x04\x4c\x39\xbb\x64"
+  "\xf0\x62\x71\xdf\x09\x53\xaf\xca\xd7\xfc\x13\xc8\xd7\x80\x7b\x8c"
+  "\xa8\x10\x7f\x45\xd1\x51\x9c\x9f\xfc\x96\xce\xf7\xc9\xf9\x35\x39"
+  "\xd6\x82\x8f\x00\xd3\xd1\x54\x01\x36\xfa\x8a\x98\xd6\xde\xc2\xa8"
+  "\x4c\xae\x0f\x92\xec\xaa\x7c\xe3\x32\x2f\x8c\x7c\x95\xbf\x23\xf9"
+  "\xc6\xc6\xba\x2f\xdf\x78\x87\x6b\xa5\x9f\x5b\xf9\x2a\x7e\x47\xf2"
+  "\x8d\x6b\x76\x5f\xbe\x09\x81\x03\xc9\x17\xfb\x09\x42\x1f\x41\xe8"
+  "\x1f\xa0\x5f\xa1\x3e\x34\x51\x6b\xe9\x1b\x24\x6a\x85\x79\x51\x90"
+  "\x8d\x34\x1b\xd7\x84\x86\x36\xc7\xae\xc0\x7d\x17\x12\x6f\x11\xe6"
+  "\x44\x73\x71\x6f\x11\xc4\xea\x75\xc0\x2a\x06\xdf\x87\xe1\x71\x02"
+  "\x3f\xf0\xb4\x01\x6c\xf5\xc4\xa8\x7c\x53\x36\xf8\x89\x1d\xd1\x4a"
+  "\x07\x98\x31\x68\xe3\xe5\x09\x44\xf1\x54\x2c\xc5\xce\xbc\x16\x30"
+  "\xeb\x81\x98\xa8\xbb\x83\xe0\xfb\xad\x5e\x1d\x60\x57\x7b\xd5\xa3"
+  "\xc3\x20\xc6\x16\x70\x7b\x33\xb1\x9b\x8b\x87\xec\xe2\xb6\xd5\x1a"
+  "\xb7\x53\x76\x70\xb3\x3c\x67\x00\xb1\x29\x87\x9b\x8e\xc3\x8d\xb3"
+  "\xeb\x6b\x21\x36\x05\xfc\x04\xdc\x38\xbb\x0e\xd8\x71\xb8\x75\xb6"
+  "\x71\x31\x90\x60\xd7\x31\xfe\x41\xec\xea\xc3\x21\x9e\xdb\xb8\xca"
+  "\x9f\xc3\x0d\xc7\xb6\xc3\x5d\xc5\x2d\x91\x58\xc7\x3d\xab\xa3\x9d"
+  "\x8b\x7b\x12\xd7\x61\x5c\x23\x8e\x7b\xf0\xf7\x29\x88\x73\x4c\xf2"
+  "\xca\x0c\x83\x5b\xfd\xe8\x44\x8d\x75\x0c\xb3\x3a\x94\xd6\x29\xe1"
+  "\x73\xd7\x63\x98\xd5\xdc\x78\xdb\x9e\xd7\xed\xc5\x2f\xab\xef\xb5"
+  "\x8e\x5f\x56\x7b\xd3\x38\x65\x75\xd4\xa9\x74\x8c\x5f\xc0\x21\x73"
+  "\xe9\x09\x07\xc4\xe9\x96\xf8\x85\xa6\x73\x7b\xa2\x6f\x5c\x9d\xe4"
+  "\x5a\xcc\x32\xe3\x02\xc7\x2c\xfe\x03\xc4\x2c\xfe\x97\x58\xcc\x92"
+  "\xe4\xf0\xf9\xff\xcb\x3e\x55\xb0\xf9\xab\x35\xee\xdb\xfc\x35\x0e"
+  "\x9f\xff\xbf\xec\x53\x05\xf9\xbe\xe0\xe7\xbe\x7c\xd7\x16\xb8\xef"
+  "\x53\x53\xbc\x2d\x3e\x35\xc5\xdb\xb1\x4f\x5d\xb7\xe9\xb2\x4f\xb5"
+  "\xe7\x53\xd7\x64\xb8\xef\x53\xd7\x85\x58\xfb\xd4\x94\x7d\xce\xf9"
+  "\xd4\x75\x5f\x0d\xbf\x4f\x5d\x67\x33\x0e\x9d\x52\x45\xeb\x94\x7c"
+  "\x8d\xeb\x3e\x35\x25\xdb\xb1\x4f\x4d\x79\xcd\xda\xa7\xa6\xa8\xa9"
+  "\xef\x4c\xd1\x52\x9f\x9a\x92\x4c\xd3\x93\x7d\xc4\xe9\x16\x9f\x4a"
+  "\xd3\xa9\x4f\x4d\xa9\x77\xcd\xa7\x5e\x7b\x81\x7d\xaa\x72\x00\x9f"
+  "\xaa\xbc\xc4\x7c\x6a\xda\x40\xeb\xff\x5e\xb6\xf9\x9c\xcd\x4f\xd1"
+  "\xb9\x6f\xf3\xd7\x3b\x7c\xff\x6d\x70\x9b\x9f\xe1\x61\xb1\xf9\x19"
+  "\x1e\x8e\x6d\xfe\x86\x75\x97\x6d\xbe\x3d\x9b\x9f\x96\xe4\xbe\xcd"
+  "\xdf\x10\x68\x6d\xf3\x33\xde\x73\xce\xe6\x6f\xf8\x7c\xf8\x6d\xfe"
+  "\x06\x9b\xe7\xff\x32\x4a\x68\x9d\xd2\xe5\xae\xdb\xfc\x8c\xf5\x8e"
+  "\x6d\x7e\xc6\x26\x6b\x9b\x9f\x11\x46\x6d\x7b\xc6\x5e\x6a\xf3\x33"
+  "\x62\x69\x7a\xba\x4c\x9c\x6e\xb1\xf9\x34\x9d\xda\xfc\x0c\xad\x6b"
+  "\x36\xdf\xeb\x02\xdb\x7c\xc5\x00\x36\x5f\x71\x89\xd9\xfc\x8d\x7e"
+  "\xee\xdb\xa4\xcc\x02\x8b\x4d\xca\x2c\x70\x6c\x93\x32\xc7\x5e\xb6"
+  "\x49\xf6\x6c\x52\x46\x8b\xfb\x36\xe9\xbf\x0e\x5b\xdb\xa4\x4d\x0f"
+  "\x3a\x67\x93\x32\x9f\x18\x7e\x9b\x94\xa9\xb6\xb6\x49\x9b\x66\xd2"
+  "\x3a\x6d\xdc\xee\xba\x4d\xda\x74\xb5\x63\x9b\xb4\x69\xa2\xb5\x4d"
+  "\xca\xe4\xe7\xcc\x36\x05\x52\x9b\xb4\x49\x4a\xd3\x37\x96\x88\xd3"
+  "\x2d\x36\x89\xa6\x53\x9b\xb4\x69\xb0\xe7\x1f\x38\xee\x37\xf8\xd8"
+  "\x70\xff\x39\x81\xfb\x2f\x55\x7d\x59\x20\x70\xff\x25\xfa\x9c\x73"
+  "\x41\xb4\xcf\x4b\x89\x44\xaa\xc1\x7d\x4d\x40\xdf\x63\x9f\x44\xee"
+  "\xbf\x34\x19\x9f\x3f\x90\x1d\x06\x1b\xd6\xce\xdb\xb4\x24\xb0\x69"
+  "\xed\xf0\x1b\xd7\xbb\x9a\x18\xed\x83\xb6\x08\xf7\x41\xc0\xdf\xd4"
+  "\xb6\xe9\x47\xe2\xbb\x9b\x2e\xbd\x57\xd5\xce\xbf\x57\x15\xd1\xff"
+  "\xbd\xaa\x02\xd1\xfb\x3b\xa8\x1b\xf2\xf5\x12\x4f\x9c\x0b\x06\xfb"
+  "\xc6\xdb\xb1\xba\x91\x46\x19\x6f\xc7\xce\x80\x1d\x3b\x63\xd1\x09"
+  "\xb4\x63\xa7\xc0\x8e\x19\x56\xab\x26\xa1\x2d\xeb\xff\x4e\x15\x9d"
+  "\xfb\xe5\xec\x58\xb6\x8d\x1d\x7b\xc6\xc6\x8e\xad\x00\x3b\x16\x0e"
+  "\x76\x4c\x6e\xd1\x87\x3f\x1d\x26\xcc\xfc\x25\xa0\x13\x60\xc7\x5e"
+  "\x3d\x83\x76\xec\x73\x37\xed\x58\x56\xa7\xb5\x3e\x68\x9e\x70\x4e"
+  "\x1f\x5e\x8a\x74\xa4\x0f\xbd\xd9\xee\xea\xc3\x4b\x49\xd6\xfa\xa0"
+  "\x99\xcb\xeb\x68\xa1\xeb\xfa\xa0\x99\xd2\xa7\x0f\xcf\xd9\xea\x83"
+  "\x66\xba\xb5\x3e\x68\x08\xe5\xbd\x26\x94\xea\x83\xc6\x9b\xd7\xa9"
+  "\x02\x71\xba\x45\x1f\x68\x3a\xd5\x07\x4d\xc4\xe5\xf9\xd9\x8b\xd5"
+  "\x47\x67\xd7\x5d\x9e\x9f\x1d\xac\x5f\xa6\x49\x72\xbf\x5f\xb6\xf9"
+  "\x02\xcd\x7f\xff\x9e\xc6\x92\x73\x14\xee\xcb\x37\xf7\x02\xcd\x7f"
+  "\xff\x9e\xc6\x15\x36\x0f\x61\xfe\xfb\xe5\x01\xe7\xbf\x07\x8e\x63"
+  "\xf2\x92\xea\xfb\x62\xf8\xbc\x24\xe1\xd9\xcd\xfe\x31\xfc\xab\xc7"
+  "\xad\xdf\x9d\x7a\x65\xab\xed\xbb\x53\x83\xc5\xf6\xc6\xff\x53\xb1"
+  "\x7d\x6e\xb3\xfb\xb1\xfd\xab\x35\xd6\xb1\xcc\x6b\x53\x9c\x8b\x65"
+  "\xf2\x6e\x71\x14\xcb\x18\xdd\x8e\xed\xf3\xe6\x5a\xc7\x32\xaf\x29"
+  "\x78\xfc\x97\xbb\x1e\xcb\xe4\xfd\xe6\x38\x96\xc9\x3b\x6b\x1d\xcb"
+  "\xe4\xd5\xd3\x98\xe5\x35\x3f\x1a\xcb\xe4\xe9\x68\xfa\x2b\x11\xe2"
+  "\x74\x4b\x2c\x43\xd3\x69\x2c\xf3\x9a\xff\xe5\x79\xdb\x8b\x35\x96"
+  "\xd9\x92\x77\xd9\xd7\x0e\xe6\x0b\x5e\x9b\xeb\xbe\x2f\xf8\x87\xe1"
+  "\xb2\xaf\x1d\x4c\xbe\x5b\x0e\xbb\x2f\xdf\xad\x21\xee\xfb\xda\x6d"
+  "\xed\x16\x5f\xbb\xad\xdd\xb1\xaf\xdd\xf6\x84\xb5\xaf\x7d\x7d\xe4"
+  "\x65\x5f\x3b\x90\xaf\xcd\x9f\xed\xbe\xaf\xdd\xe6\x67\xed\x6b\x0b"
+  "\x5e\x76\xce\xd7\x6e\xdb\x3e\xfc\xbe\x76\x5b\xb5\xb5\xaf\x2d\x48"
+  "\xa6\x75\xda\xfa\x95\xeb\xbe\xb6\x60\xb1\x63\x5f\x5b\xb0\xdc\xda"
+  "\xd7\x16\xcc\xa2\x3e\xb5\x20\x97\xfa\xda\x82\xf9\x34\x7d\x6b\xb3"
+  "\x38\xdd\xe2\x6b\x69\x3a\xf5\xb5\x05\x05\x97\xe7\x73\x2f\x56\x5f"
+  "\x5b\x44\x2e\xfb\x82\xc1\x7c\x41\x41\xb5\xfb\xbe\xa0\x38\xdc\x7d"
+  "\x5f\xb0\x5d\x6f\xf1\x05\xdb\xf5\x8e\x7d\xc1\xf6\xe5\xd6\xbe\xa0"
+  "\x64\xec\x65\x5f\x30\x90\x2f\x28\x0a\x74\xdf\x17\x6c\xf7\xb7\xf6"
+  "\x05\xa5\x85\xce\xf9\x82\xed\x7b\x86\xdf\x17\x6c\xaf\xb5\xf6\x05"
+  "\xa5\x99\xb4\x4e\xc5\x47\x5c\xf7\x05\xa5\x91\x8e\x7d\x41\x69\x9c"
+  "\xb5\x2f\x28\x9d\x4b\x6d\x7e\x69\x01\xf5\x05\xa5\xa1\x34\xbd\xf8"
+  "\xb0\x38\xdd\xe2\x0b\x68\x3a\xf5\x05\xa5\x15\x97\xe7\x79\x2f\x56"
+  "\x5f\x50\x2e\x73\xdf\x56\xed\x2c\xb0\xd8\xaa\x9d\x05\x8e\x6d\xd5"
+  "\xce\xb1\xd6\xb6\xaa\xfc\x93\xcb\xb6\x6a\x20\x5b\x55\x5a\xeb\xbe"
+  "\xad\xda\x61\x33\xff\xfb\x86\x93\xf3\xbf\x3b\x1d\xce\xff\xba\x6f"
+  "\xab\x76\xda\xcc\xff\xbe\xc1\xcf\xff\x96\x6f\x72\xdd\x56\xbd\x71"
+  "\xb5\x63\x5b\xf5\x86\xcd\xfc\xef\x4e\x7e\xfe\xf7\x0d\x7e\xfe\xf7"
+  "\x0d\x7e\xfe\xb7\x3c\x53\x9c\x6e\xb1\x55\x34\x9d\xda\xaa\x37\x86"
+  "\x38\xff\xbb\xeb\x80\x65\xfe\x77\x17\xf7\xce\x80\x39\xbf\x2a\xb0"
+  "\xff\xfc\xef\xae\xdb\xad\xd7\x31\x79\xe3\x1b\x6e\x2e\x18\xf5\xc2"
+  "\x40\xdf\x4d\xb7\x3b\x2f\x7c\x4d\x55\xe0\xe5\x79\xe1\xe1\x98\x17"
+  "\xde\x25\xb5\xd6\x93\xca\x38\xe7\xf4\x64\xd7\xfa\xe1\x9f\x17\xde"
+  "\x95\x6b\xad\x27\x95\x61\x3c\x27\xdc\x98\x17\xae\xbc\xcb\xb1\x9e"
+  "\x54\xce\xb3\xd6\x93\x4a\xfe\xb9\xdc\xca\x58\xaa\x27\x95\xd3\x78"
+  "\x5d\x2b\x10\xa7\x5b\xf4\xe4\x0d\xd1\xbc\x70\x65\xb2\x33\x3e\xdd"
+  "\x28\xdb\x9d\x81\x3e\x7a\x5a\xeb\x3d\xa6\x3e\x3e\x27\xf0\x7c\xb6"
+  "\xe7\xd3\x97\x52\xdb\x8f\x3c\xee\x2d\x8f\xf6\x1b\xd4\xa7\xb7\xf3"
+  "\x3e\x3d\xa2\xbf\x4f\x17\xfc\x39\xf2\x79\x9b\x53\x73\xc2\x36\xbc"
+  "\x76\xc9\x9f\xcf\xad\x18\x0a\xaf\x91\xd3\xd6\xfe\xdc\x5d\x5e\xef"
+  "\xbe\x40\xef\xbf\xfc\x9e\xe6\x84\x2b\x73\xdd\xef\xdb\xed\xb9\x40"
+  "\xef\xbf\xfc\x9e\xc6\xa9\xab\x86\xf0\xfe\xcb\x9b\x03\xbe\xff\x72"
+  "\x79\x6c\x02\xe5\xbb\x27\xc3\x7d\xf9\xbe\x65\x74\x3f\xde\x7f\xa7"
+  "\xca\x12\xef\xbf\x53\x25\xc4\x36\x68\x0b\xb9\x75\x77\xc0\xfe\x65"
+  "\xc7\xc3\x71\x86\x90\x97\xe2\xb9\x75\xc7\x3d\x9a\xda\xbf\xc1\xbd"
+  "\x92\x20\xde\x79\x67\x72\x50\x92\x38\xde\xa9\xde\x27\xc4\x3a\x41"
+  "\x18\x07\x41\x5c\x83\x31\x8d\x10\xe3\xe7\x9e\x1c\xe4\x79\xd0\x29"
+  "\xd1\x7e\xd8\x27\xe8\x95\xef\xce\xb8\xf4\xfb\x03\x6f\xb6\xbb\xdf"
+  "\x1f\x78\xdb\xe6\xf9\xb7\x77\x9d\x7c\xfe\xed\x1d\x87\xcf\xbf\xb9"
+  "\xdf\x1f\x78\xc7\xe6\xf9\xb7\x77\xf9\xe7\xdf\xaa\x5f\x70\x3d\xce"
+  "\x79\x77\x80\xe7\xdf\xde\xb5\x79\xfe\xed\x5d\xfe\xf9\xb7\x77\xf9"
+  "\xe7\xdf\xde\xe5\x9f\x7f\xab\x4e\x12\xa7\x5b\xe2\x1c\x9a\x4e\xe3"
+  "\x9c\x77\x9d\x7a\xfe\x0d\xe2\x9c\xcc\x21\xc4\x39\x83\x8f\x5d\x5c"
+  "\x34\x71\xce\xbc\x8b\x24\xce\xd9\x7b\xc0\x09\x3f\x91\x61\xe3\x27"
+  "\xfc\xfe\x6f\xf9\x89\x77\x87\xf0\xec\xdb\xfb\x03\x3e\xff\xcf\xc9"
+  "\x57\x23\x92\x2f\xda\x68\x5e\xb6\x26\xbf\x68\x3f\xb7\xe4\x0b\xb6"
+  "\xb9\x30\xe5\xf7\x22\xdb\xf7\x64\xee\xcb\xf6\x83\xb4\xcb\x31\xce"
+  "\x60\xf2\x7d\x3f\xca\x7d\xf9\xd6\xe8\xdc\x8f\x71\x3e\xae\xfe\xb2"
+  "\x2f\xc6\xf9\xb8\xda\x36\xc6\xc1\x98\x66\x41\x37\x8d\x75\x5e\x82"
+  "\x18\x25\x2b\x06\xe2\x9d\x44\x42\x9a\xda\x3f\x21\x1a\x88\x79\xb2"
+  "\x4e\x40\xdc\x13\x05\x71\x8f\x71\x07\x1f\xf7\x7c\x3c\xc5\x3a\xee"
+  "\xf9\xf0\x43\xbb\x71\x8f\xdc\x12\xf7\x18\x21\xa6\xe9\xdd\x11\xed"
+  "\x97\x7b\x42\x14\x03\x3d\xdb\x3f\x06\xea\xc9\x06\x9f\x33\x25\x5a"
+  "\xd5\x0b\x71\xd0\x40\x31\x10\x87\xbd\x4d\x1c\xf4\xfb\x8b\x81\x3e"
+  "\xa8\x73\x3f\x06\xfa\xc8\x66\x0d\xd1\xda\xc5\xce\xc5\x40\x1f\x47"
+  "\x3b\x1c\xeb\x71\x3b\x06\xfa\x38\xd9\x3a\x06\xaa\x0d\xe4\x79\xb1"
+  "\xd8\xf5\x18\xa8\x76\xaa\xe3\x18\xa8\xf6\x26\xeb\x18\xa8\x56\x4a"
+  "\x63\x9d\xda\x30\x1a\x03\xd5\xfa\xd0\xf4\x0f\xc3\xc4\xe9\x96\x18"
+  "\x88\xa6\xd3\x18\xa8\x56\xed\xe4\xfc\x4d\x86\x11\x7c\xec\x85\x7f"
+  "\x6e\x6e\xa0\xf9\x9b\xe1\x7a\x6e\x6e\xee\x45\x32\x7f\xf3\x49\xfd"
+  "\x65\x3f\x3d\x90\x1f\xa9\x4d\x76\xdf\x8f\x7c\x7a\x81\x9e\xff\xff"
+  "\x3d\xf9\xe9\x7f\x7a\xbb\x2f\x5f\xed\x80\xcf\xff\x0f\xec\xa7\xf7"
+  "\xcf\xb2\x8c\x45\xec\x9f\xe5\xda\x58\xc4\x67\x7b\xac\x7d\xf2\xbe"
+  "\x05\x97\xc7\x22\x9c\xf5\xc3\x9f\xc6\xba\xef\x87\x3f\x4b\xb2\xf6"
+  "\xc3\xfb\x7f\x74\xce\x0f\x7f\x76\x7a\xf8\xc7\x22\xf6\x4b\xad\xfd"
+  "\xf0\xfe\x66\x9e\x0b\x23\x5d\xf7\xc3\xfb\xdf\x76\xec\x87\xf7\x7f"
+  "\x68\xed\x87\xf7\x6b\xa8\xbf\xdd\xdf\x4e\xfd\xf0\xfe\x12\x9a\xbe"
+  "\x4f\x2a\x4e\xb7\xf8\x61\x9a\x4e\xfd\xf0\x7e\xbd\x6b\x73\x2e\xd7"
+  "\x5e\xa4\x73\x2e\xca\x4b\x6c\xce\xe5\xf3\xe0\xcb\x7e\x62\x30\x3f"
+  "\x71\x40\xea\xbe\x9f\xf8\xef\x6a\xf7\xfd\xc4\xc1\x70\x8b\x9f\x38"
+  "\x18\xee\x9a\x9f\xa8\xfb\xc6\xda\x4f\xfc\xcf\xf3\x97\xfd\x84\xb3"
+  "\x7e\xe2\xf3\x7c\xf7\xfd\x44\x5d\x89\xb5\x9f\xf8\x42\xee\x9c\x9f"
+  "\x38\x38\x71\xf8\xfd\xc4\xc1\x69\xd6\x7e\xe2\x60\x37\xcf\x85\xe9"
+  "\xae\xfb\x89\x83\x87\x1c\xfb\x89\x83\x3f\x58\xfb\x89\x83\x7b\xa9"
+  "\x3f\xf8\x42\x46\xfd\xc4\xc1\x3a\x9a\xfe\x3f\xd3\xc4\xe9\x16\x3f"
+  "\x41\xd3\xa9\x9f\xf8\xc2\xe7\xf2\xf3\x76\x17\xeb\xf3\x76\x5f\x26"
+  "\xbb\x6f\xcb\x1a\x65\x16\x5b\xd6\x28\x73\xfc\xbc\x5d\xc3\x7a\xeb"
+  "\xe7\xed\xea\xa7\x5f\x7e\xde\x6e\x20\x5b\xf5\xc5\x34\xf7\x6d\x55"
+  "\xc3\x7c\x6b\x5b\xd5\xe8\xe4\x7e\x90\x0d\x07\x87\xdf\x56\x35\xb4"
+  "\x5a\xdb\xaa\x46\x7e\x0f\xc8\x2f\xcf\xba\x6e\xab\x1a\x5f\x74\x6c"
+  "\xab\x1a\xb3\xad\x6d\x55\x63\x38\xb5\x49\x8d\x35\xd4\x56\x35\xf2"
+  "\xfb\x3f\x7e\xd9\x2d\x4e\xb7\xd8\x2a\x9a\x4e\x6d\x55\xa3\x53\xeb"
+  "\xff\x5b\xe6\xd7\xdc\x8a\x69\xcf\xc3\xfc\xda\x70\xc5\xb4\x17\xcb"
+  "\xfc\x5a\xf3\xe5\xf9\x9f\x01\xe3\xd9\xc6\x21\xac\xfb\xff\xd5\x80"
+  "\xf3\x3f\x03\xfb\x80\x96\x40\x8b\x0f\x68\x09\x74\x34\x3f\x91\x05"
+  "\x1c\xd2\x40\x3c\xba\xe9\x04\x91\xbe\x84\xf3\x13\x2d\x0d\x24\x1b"
+  "\xe7\x27\x62\x84\xf9\x89\x42\x3e\xc6\xfd\x7f\x9f\x58\xc7\xb8\x5f"
+  "\x3f\x61\x2f\xc6\xc5\xd8\xd6\x04\x71\xab\xd1\x76\x5e\xe2\x49\xfb"
+  "\xbe\xa3\x47\xbe\x3b\xf3\xec\x8e\x68\x95\x2b\xbe\x63\xdb\x1a\xea"
+  "\x3b\x5e\xff\x5d\xf9\x8e\xe6\x28\xf7\x7d\xc7\xff\xcb\xb4\xf6\x1d"
+  "\x2d\xa7\x9d\xf3\x1d\x2d\x23\x87\xdf\x77\xb4\x78\x5b\xfb\x8e\x16"
+  "\x1d\xad\xd3\x57\x26\xd7\x7d\x47\xcb\x3e\xc7\xbe\xa3\xe5\xa0\xb5"
+  "\xef\x68\xe1\x9f\x35\x6d\x31\x50\xdf\xd1\x52\x4d\xd3\xbf\x32\x8a"
+  "\xd3\x2d\xbe\x83\xa6\x53\xdf\xf1\x0d\x71\x6d\x3c\xc4\xeb\x22\x1d"
+  "\x0f\x51\x5c\x62\xe3\x21\xff\x3b\x84\xf7\xdf\x0e\x79\xd4\xf7\x3d"
+  "\x3f\x7f\xc8\xa3\x5f\x7f\x3d\x11\x62\xdd\x93\x74\xce\xb5\xaf\xbf"
+  "\xae\x3b\xc2\xdb\xb2\xd6\x75\xd6\xb6\xec\x5f\x53\x1c\xd9\xb2\x81"
+  "\xe6\x55\xb1\x7f\x6e\x02\x3b\x87\x7b\xad\xb9\x35\xaf\x9a\xf8\x7b"
+  "\xb2\x5f\xdf\x78\xbb\x6f\xbf\x5a\x6d\xd6\x3f\x3d\xe4\xe4\xfa\xa7"
+  "\xad\x0e\xd7\x3f\x35\xba\xfd\x0c\x7d\xab\xcd\xfa\xa7\x87\xf8\xf5"
+  "\x4f\xff\xd7\x8d\xf7\xe2\x0e\xad\x77\x6c\xbf\x0e\xd9\xac\x7f\x7a"
+  "\x88\x9f\x3f\x3d\xc4\xaf\x7f\x7a\x88\x5f\xff\xf4\x7f\x0f\x8b\xd3"
+  "\x2d\xf6\xeb\x7f\x45\xef\xc5\x1d\x1a\x70\xfd\x53\x56\x13\x97\x99"
+  "\xcb\x98\xab\xe1\xa8\x81\x3a\x5e\x03\x1c\xd0\xc2\xf7\x3a\xc0\x71"
+  "\x1c\x7c\x6f\x76\xa4\x63\x7a\x79\x5c\xa6\x39\x1d\xea\xcc\x10\x49"
+  "\x93\xfe\x57\xad\x76\x82\x11\xee\xfb\x6d\x00\xc5\x2a\x2e\xd3\xcb"
+  "\x38\x2a\xd0\xcc\xaa\x09\xe0\x92\xc9\xed\x8f\x07\xf9\x3d\x81\x33"
+  "\xca\x44\xe2\x79\x42\xf2\x6d\xb8\x90\x0f\xea\xeb\xd9\x26\xf9\x76"
+  "\x22\x96\xd1\xb5\xf1\xdb\x28\x68\x4b\xbd\xc3\xba\x42\x59\x41\xbb"
+  "\x26\x91\x75\x46\xf6\x27\x6d\xcc\x49\xd2\x2e\xf9\xf6\x3d\xaf\xce"
+  "\x51\x81\x6c\x6a\x28\xc1\x18\xab\x7a\x82\x5e\x8a\x65\x6a\x63\x7a"
+  "\xf0\x5c\x3e\x9e\x33\x41\x1d\x53\xa2\x09\x93\x73\x72\x94\x07\xd8"
+  "\x82\x91\xa9\x06\xb6\x63\xa5\x11\xea\x9c\x64\x24\x9f\x4e\x6a\x95"
+  "\xbe\xf5\x7a\x2b\xae\x6f\xe0\x83\x7b\xe2\x61\x19\x10\x63\x62\x7d"
+  "\x3e\x2c\x82\xfc\xf6\xea\xf0\xe2\x9b\x64\xda\xc8\xa9\xac\xce\x35"
+  "\xde\xfc\xdb\xe1\xfb\x6f\x5e\xeb\x27\x11\xed\xf5\x20\x3b\x25\x61"
+  "\xec\x9d\x77\xf1\x3e\x09\x03\xd8\x44\x0f\xdc\x4f\x33\x75\x2b\x61"
+  "\x36\x9b\x47\x79\xec\x4f\xe6\xf6\xb3\xd4\x77\x6d\xfc\xb7\x4e\x27"
+  "\xb9\xbf\x04\x65\x8e\x7b\xa6\xe1\x9e\xab\xc0\x1b\x02\xe9\xdd\xfb"
+  "\x92\x08\xb1\xc5\x22\x3e\x22\x7a\x89\x32\x21\x32\x7a\xf9\xca\xe7"
+  "\x13\x94\x53\x22\xc6\x90\x90\x95\x2b\x95\xd1\x4b\x62\x5e\x50\x8a"
+  "\xcf\xdc\xa1\x8c\x88\x5c\xb5\x64\x69\xd4\xf2\xe9\xd1\xcb\x62\xc7"
+  "\xe0\x83\x91\xa2\x7a\x78\x63\x5d\xcc\x1b\x0f\x4b\x8b\x5e\x21\xe4"
+  "\xd5\x71\x44\x8a\xf5\xea\xda\x78\x58\x2d\xec\xa9\x97\xb3\x85\x35"
+  "\x30\x90\x27\x15\x6c\xe0\xe6\x94\x51\x90\xf7\xdf\x09\xc5\x50\xaf"
+  "\x22\xa8\x37\xd4\x11\xea\x7c\x38\x4f\xa8\xb3\xc0\x89\x54\xe4\x44"
+  "\xca\x49\xe0\xe0\xe1\xf7\xbc\xba\x47\x3d\xc0\xb2\xa1\xd8\x3e\x03"
+  "\xe8\x89\xe4\xa8\xe4\xc8\x48\xf4\x4b\x60\x03\x32\xe1\xda\x66\x81"
+  "\x63\x78\x2d\x9b\x13\x17\xdc\x85\x7a\xc2\xaa\xef\xa6\x3a\x75\xa4"
+  "\xe2\x31\x95\x84\xd0\x3d\xfd\x0e\x1b\x2d\x7b\xfa\x1d\xe1\xf6\x96"
+  "\x83\x7a\x74\x76\x6d\x3c\xe2\xad\x93\xf8\xcc\xc6\x74\xdc\x5b\x12"
+  "\xf7\x7a\xc5\x3a\x43\xbb\xc0\x2f\xb2\x5a\x36\x9d\xe7\x7e\xe6\xfe"
+  "\x3a\x73\x66\xbb\xb2\x49\x7a\x86\x04\x19\xd9\x5e\x76\xd3\xfe\xba"
+  "\x46\x83\x81\x78\xad\x8f\x5d\xc6\x5e\x71\xf8\x6a\x2f\x63\xe4\x72"
+  "\xdc\x93\xdc\xbc\xa9\x5d\xc9\x6e\x3a\x52\xf2\xd8\x54\xa2\x80\xb2"
+  "\x63\x45\x7b\x0b\x4a\x5d\xc3\xff\x08\x87\x3f\xe2\x08\xf5\xe1\x71"
+  "\x3c\xa2\xdd\x97\xd0\x1f\xc7\x3e\xfe\xed\x32\x93\xcf\x81\x0b\xac"
+  "\x6c\x7b\x73\x90\x89\xca\x11\x75\xf7\x54\xaa\x9a\xcc\xe0\x64\xf7"
+  "\x5d\x92\x39\x67\x7b\xb5\x59\xb3\xbd\x83\xd5\x6c\x6f\x01\x99\xa9"
+  "\x73\x12\x89\xf2\x69\x93\x82\x64\x9f\x21\xfe\xfa\xec\xed\xcd\x72"
+  "\x49\x9a\x04\x62\x0b\x06\xfc\x86\x3f\xd8\x0c\x7f\x5e\xdf\xd5\x28"
+  "\xc7\xff\xe9\x24\x64\xe1\x2a\x42\x7e\x9a\x4d\x46\x14\xc1\x75\xae"
+  "\xb5\xe7\x3b\xba\xfe\xd3\xc6\x23\xc6\x62\xb8\x16\xf7\x86\x74\xf1"
+  "\xfa\x0c\x87\x7a\xd7\xd7\xee\xd2\x60\xfb\xed\xfe\x3e\xd6\x9c\x53"
+  "\xea\x6f\xd6\x94\xaa\x59\x4d\x69\x48\xff\x76\x97\x06\xd3\x76\x8f"
+  "\x3c\x39\xfc\xed\xfe\x9e\xee\xb9\xb8\xf1\x3b\x83\x7b\xed\xfe\xde"
+  "\xe1\xf8\x9f\xa8\xdd\x0e\xf0\xd6\xa9\xa1\xdd\x80\x77\x29\xe0\x5d"
+  "\x6a\x07\xef\x52\x1e\xef\x2b\xdb\x86\xbf\xdd\xba\x99\xb4\xdd\xdf"
+  "\x77\xba\xd7\x6e\x9d\x43\xfb\x67\x69\x77\x99\x03\xbc\x7f\x08\x37"
+  "\xe7\x94\x01\xde\x65\x80\x77\x99\x1d\xbc\xcb\x78\xbc\xc7\x7e\x3d"
+  "\xfc\xed\xfe\x81\x8e\xff\x6f\xd4\xb5\xbb\xd7\xee\x1f\xa2\x9c\x68"
+  "\xb7\x03\xbc\xdb\x42\xa1\xdd\x80\x77\x19\xe0\x5d\x66\x07\xef\x32"
+  "\x1e\xef\x5b\xb3\x86\xbf\xdd\x6d\x74\xfd\x9b\x8d\x3f\x1c\x76\xaf"
+  "\xdd\x6d\x11\x83\xb7\xbb\xdc\x01\xde\xff\x09\x36\xe7\x94\x03\xde"
+  "\xe5\x80\x77\xb9\x1d\xbc\xcb\x79\xbc\x17\xcd\x19\xfe\x76\xff\xc7"
+  "\x97\xb6\xbb\xad\xc5\xbd\x76\xff\x27\x6c\xf0\x76\x6f\x6f\x05\x9b"
+  "\xdd\x0f\xf3\xa6\xa4\x59\xe4\xc6\x33\xd8\xfe\x76\x2d\x2b\xdf\xde"
+  "\x7a\xe5\xfa\x34\x89\x51\xb6\xfd\xf0\x95\x87\x09\x03\x7d\x3f\xb5"
+  "\x97\x8e\x8c\x86\xb6\xaa\xd9\x9c\x9d\xb1\xf8\x69\x86\x72\x8c\x60"
+  "\xfb\x4d\xb2\xed\x2d\x3d\x9a\x38\xf5\x4b\x2b\x88\x32\x55\x4f\x14"
+  "\x8d\x29\x3a\x92\x12\xcb\xea\x1b\xc9\x0f\x44\xae\x23\x0c\x8e\x63"
+  "\x7d\xd9\x59\x43\x62\xe2\x59\x16\xca\xde\x85\xfd\xc5\x9c\xa3\xc4"
+  "\x1f\x62\xe2\x34\x16\xfc\x47\xae\x99\x28\xa1\x7c\x7f\x94\x25\x94"
+  "\x1d\xef\x15\x42\x24\xff\x5c\xda\x4d\x50\x9e\x28\x5b\xe8\x5b\xfa"
+  "\x73\x72\x35\x10\xf2\xf0\x22\x2a\xd7\x6d\x2b\x5c\x95\x6b\x7b\x02"
+  "\x8d\x2b\xb7\xeb\x9b\x74\x3d\x04\x62\x4b\x05\xbe\xd7\x0c\xe9\xfe"
+  "\x8d\xb1\x27\xa1\x1f\xf2\x9f\x16\x36\x7b\xbb\xce\x0c\x3e\xcb\xc5"
+  "\x72\x1d\x3e\xff\x26\xb2\xa7\xa1\x60\x33\xfb\x71\xcd\x22\xef\xa3"
+  "\xfe\xac\xbc\x34\x94\xca\xbb\x34\xec\xca\xc3\x23\x4f\xda\x97\x77"
+  "\x69\xa8\x11\x7c\x8e\x49\x56\x1a\xe2\xbc\xbc\x8f\x5e\x63\x2d\xef"
+  "\x52\xff\xf3\x23\xef\x1f\xe9\x3a\x62\x9a\xd2\x58\x6b\x79\xff\x58"
+  "\x42\xe5\xfd\xe3\x5c\x36\xbb\x34\xdc\x0c\xbe\xd2\xb5\x72\x8f\x3a"
+  "\x7c\xff\x51\x24\x6f\xe0\x77\x7f\x1f\x66\x91\xf7\x4f\x25\x20\x6f"
+  "\x9e\xdf\xa5\xc0\xef\x2b\xdb\x1c\xc8\x1b\xf8\x5d\x0a\xfc\x2e\x75"
+  "\x81\xdf\x3f\x6d\xb2\x91\xf7\x79\xe2\xf7\x4f\xfc\xfe\x4f\xa5\x36"
+  "\xfc\xfe\x49\x41\xe5\x7d\x74\x2f\xc8\x1b\xf8\x5d\xea\x22\xbf\x7f"
+  "\xaa\x72\xc2\x7f\x00\xbf\xfb\xfb\x4e\x8b\xbc\x7f\x56\xb0\xf2\x32"
+  "\x9e\xdf\x65\xc0\xef\xb1\x5f\xdb\x97\x77\x19\xf0\xbb\x0c\xf8\x5d"
+  "\xe6\x02\xbf\x3b\xce\x5a\xcb\xbb\xec\x3c\xf1\xbb\xe3\x00\x95\x77"
+  "\x99\x0d\xbf\x3b\xd2\xa8\xbc\x3b\xfc\xd8\xec\x32\xe0\x77\x99\x8b"
+  "\xfc\xfe\xd9\xd7\x09\x79\x03\xbf\xfb\xfb\x6c\x8b\xbc\x8f\xa5\x81"
+  "\xbc\x79\x7e\x97\x01\xbf\x6f\xcd\x72\x20\x6f\xe0\x77\x19\xf0\xbb"
+  "\xcc\x05\x7e\x1f\x8b\xb4\x91\xf7\x79\xe2\xf7\xb1\x99\xbc\xbc\x6d"
+  "\xf8\xfd\xb3\x9e\xca\xfb\xe7\x3c\x90\x37\xf0\xbb\xcc\x45\x7e\x1f"
+  "\xd3\x38\x11\x27\x00\xbf\xfb\xc7\x0a\x16\x79\xff\xa2\x67\xe5\xe5"
+  "\x3c\xbf\xcb\x81\xdf\x8b\xe6\xd8\x97\x77\x39\xf0\xbb\x1c\xf8\x5d"
+  "\xee\x02\xbf\x7f\x39\x64\x2d\xef\xf2\xf3\xc4\xef\x5f\xca\xa9\xbc"
+  "\xcb\x6d\xf8\xfd\x4b\x38\x95\xf7\x2f\x52\x36\xbb\x1c\xf8\x5d\xee"
+  "\x22\xbf\x7f\x71\xf8\xfe\xef\x40\xf1\xc9\xaa\x42\xe2\x61\x2d\xf3"
+  "\xe3\x11\xe7\x2e\x46\x39\xbe\xe0\xc2\xc4\x28\xc7\x7d\xec\xc7\x28"
+  "\x9d\x2d\x54\xe6\x9d\x49\xee\xc5\x28\xc7\x63\xdd\x89\x51\xfa\xcb"
+  "\xfc\x44\xeb\xb9\x8b\x53\x4e\xec\xbb\x30\x71\xca\x09\x8d\xfd\x38"
+  "\xe5\x44\x20\x95\xf9\xf1\x4e\xf7\xe2\x94\x13\xed\xee\xc4\x29\xfd"
+  "\x65\xae\x9f\x7f\xee\x62\x15\xfd\x2d\x17\x26\x56\xc1\xd7\xa1\xec"
+  "\xc5\x2a\xbf\xd6\x52\x99\xff\x1a\xee\x5e\xac\xa2\x0f\x75\x27\x56"
+  "\xe9\x2f\xf3\xdf\xb4\xe7\x2e\x5e\xf9\x6d\xd7\x85\x89\x57\x7e\x4b"
+  "\xb0\x1f\xaf\xfc\xc6\xf7\x7f\xf4\x2d\xee\xc5\x2b\xbf\x39\xd1\xff"
+  "\xe9\x1f\xaf\xf4\x97\xf9\xa9\x99\xe7\x2e\x66\x39\x35\xf1\xc2\xc4"
+  "\x2c\x27\x3b\xec\xc7\x2c\x27\xcb\xa9\xcc\x4f\x06\xba\x17\xb3\x9c"
+  "\x0a\x70\x27\x66\xe9\x2f\x73\x43\xc5\xb9\x8b\x5b\x0c\x2f\x5f\x98"
+  "\xb8\xc5\x10\x66\x3f\x6e\x31\xf8\x50\x99\x9f\xaa\x75\x2f\x6e\x31"
+  "\xec\x75\x27\x6e\x41\x59\xa3\xcc\x31\x56\xa1\x32\xef\x4a\x62\x3d"
+  "\xb7\x57\xf7\x42\x3c\x22\x07\xb9\xcb\x3b\x09\x53\x88\x32\x6f\xa5"
+  "\x32\x37\x79\xee\x8c\x05\xf9\xa8\x51\x66\x5c\x3b\x7e\xf1\xf1\x34"
+  "\x69\xb6\x1f\x66\x19\x02\x6d\xf1\x20\x47\x25\xa7\x5f\x34\xa6\x13"
+  "\x4f\x65\xca\x7a\xf8\xde\xc5\xad\x9f\xa9\x4c\xd9\x78\x04\xda\x38"
+  "\x02\xe7\x28\x8c\xd9\x71\x0a\x93\x7c\x47\xee\x51\xc9\x99\xcf\xd9"
+  "\x89\xd1\x8a\x5e\x88\x25\xd8\xe7\x7c\xbc\x9b\x3a\xab\x49\x93\xf1"
+  "\x0b\xd2\xd8\xfa\x11\x31\x7b\xee\x8c\x9f\x61\x24\x2a\xf6\x17\x95"
+  "\x77\x7d\x82\x8e\x98\x96\xf9\xc8\x9a\x92\xea\x80\x17\xef\x90\xa0"
+  "\x0e\xf6\x0c\xfb\x1f\x95\xac\x57\x5e\xd9\x6c\x92\xef\x0c\x36\x65"
+  "\xef\xce\x37\xca\x2b\xb5\x7b\x12\x75\x8c\xac\x9b\xa8\xa2\xda\x59"
+  "\x36\x67\x29\x91\xe6\xb4\x11\x8f\xcd\x4b\x89\x6c\x73\x1b\x51\xd4"
+  "\xb7\xb7\x92\x86\x63\x75\xa4\xe1\xe4\x21\xd2\x70\x06\x8e\x1e\x38"
+  "\xcc\x70\xa4\x1d\x22\xf5\x9d\x84\x2c\x38\x4e\x48\x6a\x3b\xab\xbf"
+  "\xe1\x30\xf1\xae\x37\xb6\x12\x7c\x8e\xf7\x84\xe4\xcc\x13\xb2\x70"
+  "\xe2\xcd\xfe\xc7\x87\xb0\xcb\x7c\x18\x38\x27\xc5\xf4\x26\xa3\x9e"
+  "\xd4\xb7\x77\xe3\xf9\x59\x70\x5e\x9a\xda\x0e\xe5\x9b\xeb\x70\xbd"
+  "\x38\x7d\x7d\xda\x41\x68\xdf\x64\x94\x73\x87\x10\x93\xe5\xf4\x10"
+  "\xff\xcd\x00\x33\x72\x26\x88\xa5\x9c\x29\xee\x71\x95\x33\x67\xe8"
+  "\xfa\x67\xcf\xf9\x8c\x03\x79\x4f\x30\x3f\x17\xaa\x58\x78\xe8\x7b"
+  "\x16\x9f\xd3\xc2\xf9\x99\x46\xc3\x17\xa4\x29\xc3\x4c\x82\x5e\x20"
+  "\x64\xbe\x89\x10\x94\x09\xce\x25\x2f\x8c\x25\x5e\xf8\xfc\x98\xf9"
+  "\x17\xd5\xb8\xa6\x76\x3d\x59\x67\x84\xba\x9e\xe8\xee\xab\x6b\x63"
+  "\x46\x23\x81\x73\x13\x1a\xd5\x3a\x22\x8b\x25\x0a\x94\x33\xc4\xa2"
+  "\xad\x0b\x3b\xc8\xe8\x18\x03\xcb\xa2\x8c\x51\xb6\x28\x67\x2c\x4f"
+  "\x90\x7d\x53\x84\x9e\xa4\x76\x13\x45\x53\x0a\x7c\x26\xb1\xfa\x26"
+  "\xf2\x1b\x81\x3a\x46\xb1\xf2\xc9\x04\xf8\x91\x80\x9c\xd0\x49\x4e"
+  "\x27\x03\x0f\xc6\xb1\x1b\x4f\xfb\x17\x41\x7b\x71\x0e\xdf\xb5\x36"
+  "\x77\x39\x33\xff\xd1\x2f\x26\xb4\xf0\xb9\x34\x94\xf2\xb9\x27\x90"
+  "\xf5\x2c\xf5\xef\x85\x58\x8f\xf2\x79\xe4\xc9\xc1\xf9\x5c\x1a\x66"
+  "\xe1\x73\xf7\x63\x16\x3e\xf7\xdc\xee\x98\xcf\x67\x5f\xa3\x7c\x2e"
+  "\x8d\xbd\x38\xf9\x7c\x76\xea\xc0\x7c\x3e\xeb\xe1\x98\xcf\xa5\x6a"
+  "\x21\xde\x1d\x1e\x3e\x9f\x0d\x3f\x7f\x7c\x2e\x0d\x75\x8f\xcf\x67"
+  "\x67\x5b\xf3\xb9\x7b\x3e\xe5\x73\x37\x71\x8f\xcf\x3d\x0e\xf7\x3f"
+  "\x18\x28\xde\x16\xf1\x99\xb7\xcf\x26\x1f\xe0\x33\xd8\xe7\x52\xde"
+  "\x3e\x5f\xd9\xe6\x04\x9f\x45\xf6\xb9\x77\x8a\x85\xcf\xa6\xd1\x8e"
+  "\xf9\x6c\x5c\xce\xf3\xf9\x22\xb5\xcf\xbd\x67\x07\xe6\x73\x6f\xeb"
+  "\x00\x7c\xee\x10\xfa\x12\xc3\xc3\x67\xa3\xff\x79\xe4\xb3\x9b\xf6"
+  "\xd9\x28\xb3\xe6\x73\xaf\x2f\xe5\x73\x4f\xb3\x7b\x7c\x36\x39\x7c"
+  "\xfe\x79\xa0\xbe\x8c\x85\xcf\x65\xbc\x7d\x66\x3b\x58\xcf\x32\xb0"
+  "\xcf\x65\xbc\x7d\x1e\xfb\xf5\xe0\x7c\x2e\x13\xd9\x67\xd3\x69\x0b"
+  "\x9f\xd9\x43\x8e\xf9\xcc\xde\x42\xf9\x5c\x76\x91\xda\x67\xf3\xc1"
+  "\x81\xf9\x6c\xae\x70\xcc\xe7\x32\xb5\xd0\x4f\x1b\x1e\x3e\xb3\xe4"
+  "\xfc\xf1\xb9\xcc\x4d\xfb\x6c\x3e\x6c\xcd\x67\x53\x27\xe5\xb3\xa9"
+  "\xc4\x3d\x3e\xb3\x0e\xf7\xff\x19\xa8\x9f\x28\xe2\x33\xb5\xcf\x0c"
+  "\x53\x03\x7c\x06\xfb\x5c\xc6\xdb\xe7\x5b\xb3\x9c\xe0\xb3\xc5\x3e"
+  "\x33\xe4\xf3\x3e\x3e\x33\xcc\x2e\x87\x7c\x66\x98\x91\x3c\x9f\x2f"
+  "\x4e\xfb\xcc\x48\xb6\x0e\xc8\x67\x46\x92\x34\x00\x9f\x3b\x84\x3e"
+  "\xf0\xb0\xf0\x99\x91\x34\x9f\x47\x3e\xbb\x67\x9f\x19\x49\x95\x15"
+  "\x9f\x19\x52\xcb\xf1\x39\x8b\xc4\xba\xc5\x67\x86\x71\xb8\xfe\xdb"
+  "\x40\x7d\x70\x0b\x9f\xcb\xa9\x7d\x66\x46\x66\xb2\x9e\xe5\x60\x9f"
+  "\xcb\x79\xfb\xbc\x68\xce\xe0\x7c\x2e\xb7\xd8\x67\x66\xc4\x6b\x16"
+  "\x3e\x8f\x7c\xc1\x31\x9f\xa5\xdf\x50\x3e\x97\x5f\x9c\xf6\x99\x91"
+  "\x46\x0e\xcc\x67\x69\xa0\x63\x3e\x97\xab\x85\xf1\x85\xe1\xe1\xb3"
+  "\xb4\xe4\xfc\xf1\xb9\xdc\x3d\xfb\xcc\x48\x93\xad\xf9\x3c\x42\x43"
+  "\xf9\x3c\x22\xc0\x3d\x3e\x8f\x74\xb8\xff\x9d\x4b\xe3\x1b\x8c\x47"
+  "\x26\x8e\x6f\xf4\xe0\xf8\x86\xe5\xd9\x3f\xb5\x57\x33\xe5\x73\x2f"
+  "\xf0\x79\x9b\x98\xcf\xff\xb6\x19\xdf\x60\xae\x58\x6e\xee\xe3\xb3"
+  "\x47\x3f\x3e\x9b\x81\xcf\xbd\x1c\x9f\x47\xbd\x2c\x8c\x6f\x34\x75"
+  "\x96\x00\x4f\x8e\x91\xa6\x60\xe0\x72\x0e\xcf\xe5\x7f\x03\x97\x41"
+  "\x86\x66\x90\x71\xfd\xe1\x56\x12\xa4\xa7\xb2\xec\x01\x19\x9b\xc5"
+  "\x3c\xee\xe9\x60\x90\xbf\xc8\x5b\x81\xc3\x0d\x31\xc0\xdd\xf8\xaf"
+  "\x48\x43\x22\x1c\x6b\xe0\x48\x81\x83\x7c\x45\xea\x3b\x80\xbb\x91"
+  "\x62\xee\x36\xf3\xdc\x1d\x35\x65\x60\xee\x8e\x92\x9e\xb7\xb1\x0c"
+  "\x66\x14\x1d\xff\xfa\x77\xa8\x22\xe8\x91\xef\xd9\xa6\xa4\x56\x9e"
+  "\x9f\xc7\x48\x90\x91\x78\xb1\x8b\x54\xe3\x64\xa1\x44\xb1\xd6\x44"
+  "\x98\xec\xa5\x44\x91\xfd\x2d\xb4\x5b\xd0\xdf\x36\x22\xfb\xa2\xfb"
+  "\x23\x52\x7f\xb2\x95\xd4\x9f\x39\x48\xea\xcd\x70\x1c\x83\x03\xea"
+  "\x1a\xb4\x5c\xdc\x6e\x3d\xdf\x6e\x8f\x89\x50\x96\xdf\x00\xed\x36"
+  "\x72\xed\x8e\x80\x76\xf7\x58\xda\xdd\x04\x7a\x00\xf8\x4c\x30\xf3"
+  "\xe3\x21\x41\x7a\x32\x7a\xa5\x91\x65\x7b\x78\xfe\x23\x3e\x5f\xb4"
+  "\x74\x93\xa0\x58\xc0\x6c\x19\xf0\xbf\xbd\x82\xa4\x26\x03\xff\x7b"
+  "\xba\x91\x77\xfa\xa6\xb4\xb3\xc0\xff\x51\xb3\x58\x90\x5f\x2f\xf2"
+  "\xff\xdf\xc8\xff\x2b\xc2\xcc\x1c\xff\xaf\x50\xb8\xc7\x7f\x0f\x27"
+  "\xf8\xef\xc4\x78\x08\x73\x65\x26\x8e\x87\xf4\xe0\x78\x88\xe5\x19"
+  "\xd0\x41\xf8\x2f\x1a\x0f\x61\x46\x8b\xf8\x7f\xe5\x00\xfc\x1f\xf3"
+  "\xb2\x30\x1e\x72\xe1\xf9\x3f\x66\x10\xfe\x8f\x19\x80\xff\xc3\x3c"
+  "\xf6\xc1\x8c\x39\x8f\xfc\xbf\x72\x10\xfe\x8f\x71\x82\xff\xa5\xa1"
+  "\xee\xf1\x7f\x8c\x0d\xff\x47\xf3\xfc\x1f\xed\x26\xff\xaf\x74\x86"
+  "\xff\x83\x8f\x9f\x30\x9e\xc8\x7f\xb0\xff\xa5\x2d\xa2\x67\x81\x07"
+  "\xe3\xbf\xc8\xfe\xcb\x44\xfc\xf7\x1c\x80\xff\x72\x81\xff\x17\x81"
+  "\xfd\x97\x0f\xc2\x7f\xf9\x40\xfc\x1f\xde\xb1\x12\x46\x7e\x1e\xf9"
+  "\xef\x39\x08\xff\xe5\xce\xf0\xdf\x4d\xfb\x2f\xb7\xe1\xbf\x8c\xe7"
+  "\xbf\xcc\x4d\xfe\x7b\x3a\xc1\x7f\x27\xc6\x5b\x98\xb1\x99\x38\xde"
+  "\xd2\x83\xe3\x2d\x96\x67\xc2\x07\xe1\xbf\x68\xbc\x85\xf1\x12\xf1"
+  "\x7f\xec\x00\xfc\x57\xbc\x2c\x8c\xb7\x5c\x78\xfe\x2b\x06\xe1\xbf"
+  "\x62\x00\xfe\x0f\xf3\xd8\x0a\xa3\x38\x8f\xfc\x1f\x3b\x08\xff\x15"
+  "\x4e\xf0\xbf\xcc\x4d\xfb\xaf\xb0\xe1\xbf\x17\xcf\x7f\x2f\x37\xf9"
+  "\x3f\xd6\x19\xfe\x3b\x31\x3e\xe3\x8d\xfc\x07\xfb\x5f\xd6\x22\x7a"
+  "\x37\x60\x30\xfe\x8b\xec\xff\x38\x11\xff\xbd\x07\xe0\xff\x55\x02"
+  "\xff\x2f\x02\xfb\x7f\xd5\x20\xfc\xbf\x6a\x20\xfe\x0f\xf3\x58\xcc"
+  "\x55\xe7\x91\xff\xde\x83\xf0\xff\x2a\x67\xf8\xef\xa6\xfd\xbf\xca"
+  "\x86\xff\xe3\x78\xfe\x8f\x73\x93\xff\xde\x4e\xf0\xdf\x99\xf1\x9c"
+  "\x3f\x70\xe3\x39\x3d\x38\x9e\x63\x79\x47\x64\x10\xfe\x8b\xc7\x73"
+  "\xae\x16\xf1\xff\x0f\x03\xf0\x7f\xfc\xcb\xc2\x78\xce\x85\xe7\xff"
+  "\xf8\x41\xf8\x3f\x7e\x00\xfe\x0f\xf7\xd8\xcd\xf8\xf3\xc8\xff\x3f"
+  "\x0c\xc2\xff\xf1\x4e\xf0\xbf\xdc\x4d\xfb\x3f\xde\x86\xff\x57\xf3"
+  "\xfc\xbf\xda\x4d\xfe\xff\x61\x98\xc6\x7f\xae\xf1\xc7\xf1\x1f\xb3"
+  "\x6c\x7b\x4b\x6f\x41\xb4\xc2\xac\xa9\x6c\xf6\x92\x28\x89\x51\xb6"
+  "\x23\xb7\x29\xc1\x40\x16\x9e\x06\x4c\x62\x4f\x93\xa7\x4e\x2b\x70"
+  "\xbf\x40\x2d\x0b\xfd\x7f\xab\x77\x44\xe1\x30\x6a\x26\x93\xcd\x31"
+  "\x44\x6a\xf2\xdc\x19\x8f\x69\x4d\x47\xbb\x09\xb6\x79\x1d\xca\xe0"
+  "\x98\x45\x06\x38\x06\xc7\xfe\xaa\x52\x14\xa5\x43\x9e\x1e\x1d\x69"
+  "\x07\xbe\xd4\xb7\xeb\x40\xf6\x6b\x38\x6e\x21\x16\x47\x19\x9f\xe6"
+  "\xe2\x13\x44\x6a\xfc\x8f\xcf\x04\xc0\xd8\x5b\xbe\x9a\x48\x7c\xdb"
+  "\x59\x33\x62\x89\x18\x21\xae\xca\x35\x2c\x0b\xf5\x9e\xda\x08\xfc"
+  "\x36\xfe\x47\x35\xa1\x08\xf2\x0d\xff\xb8\x8c\x0f\x37\xff\x01\x9f"
+  "\x75\xf5\x87\x41\x96\x59\x3e\x6e\xe2\x74\x8d\x33\xef\xbf\x38\x31"
+  "\x4e\x31\xa1\x15\xc7\x29\xcc\xb2\xd2\x10\xe7\x70\x2a\x0d\xb5\x7a"
+  "\xa7\x75\xd8\x71\x9a\x90\xe4\x1c\x4e\x13\xbe\xb2\xc6\x69\xb8\xc7"
+  "\x0f\x26\xd0\xf5\x60\x98\x09\xb1\x14\xa7\x6b\x6a\xdc\xc3\x69\x82"
+  "\x5b\xcf\xff\xf6\xef\x4f\xfb\xa6\x61\x7f\x1a\x70\x72\x52\x9f\x4a"
+  "\x5b\xad\xde\xc1\x1d\x76\x9c\x7c\x95\xce\xe1\xe4\xfb\x82\x0d\x4e"
+  "\xc3\xdc\xcf\xf5\xa5\xfb\x41\x33\xbe\x3e\x14\xa7\x3f\x86\xbb\x87"
+  "\x93\xaf\x13\xef\x7f\x38\xd3\xef\x9b\xa4\xc2\x7e\x9f\x19\xfa\x7d"
+  "\xce\xe1\x54\x16\x6a\xf5\xce\xf0\xb0\xe3\x34\xb1\xce\x39\x9c\x26"
+  "\x4d\xb6\xc6\x69\xb8\xfb\x63\x13\x3b\x29\x4e\x13\xb5\x14\xa7\x89"
+  "\x1e\xee\xe1\x34\x69\xe6\xf0\xf4\x4f\xae\x6d\xc6\xfe\x09\xe0\xe4"
+  "\xa4\x3e\x95\xb5\x5a\xbd\xe3\x3c\xec\x38\x5d\x1b\xeb\x1c\x4e\xd7"
+  "\x1e\xb4\xc1\x69\x98\xfb\x0d\xd7\xe6\x51\x9c\xae\x55\x53\x9c\x26"
+  "\x55\xbb\x87\xd3\xb5\x0e\xf7\xff\x74\x2d\x8e\x9e\x9c\x84\x71\xb4"
+  "\x19\xe2\x68\xe7\x70\x2a\x0f\xb5\x7a\x27\x7b\xd8\x71\x9a\xec\xe3"
+  "\x1c\x4e\x93\xe3\xac\x71\x1a\xee\xf8\x76\xf2\x6c\x8a\xd3\x64\x05"
+  "\xc5\x49\x19\xea\x1e\x4e\x93\x9d\x78\xfe\xd3\xfe\x7b\x58\xfd\x63"
+  "\xbe\x3f\xf9\x5d\x5c\x31\xdf\x75\x07\x9c\xc3\xea\x4f\x13\xcf\x6d"
+  "\xcc\x77\x5d\x07\xc5\xea\xba\x5a\x8a\xd5\x75\x52\xf7\xb0\xfa\x93"
+  "\xbf\xbb\xef\x6f\xf5\x8f\xfb\xfc\x9a\x2f\xae\xb8\xcf\xcf\x49\xfb"
+  "\xe7\x77\xf0\xdc\xc6\x7d\x7e\xbc\xfd\xf3\xe3\xed\xdf\x9f\xdc\xb4"
+  "\x7f\x7e\x4e\xd8\x3f\xfb\xef\x7d\xf5\x8f\xfd\xfe\x9c\x7c\x71\xc5"
+  "\x7e\x7f\xf6\x75\x0e\xab\x3f\x3f\x7f\x6e\x63\xbf\x3f\x07\x50\xac"
+  "\xfe\xec\x4d\xb1\x9a\x12\xe6\x1e\x56\x7f\x76\xb8\xff\xcb\x60\xef"
+  "\x8b\xf5\x8f\xff\x54\x17\x59\xfc\xf7\x17\x27\xe3\x3f\xd5\x39\x8e"
+  "\xff\xfe\xc2\xc7\x7f\x7f\xe1\xe3\xbf\xbf\xb8\x19\xff\xa9\xdc\x8a"
+  "\xff\x6c\xb0\xe2\xf5\x6a\x6a\xcb\xc5\x15\x03\x4e\x4d\x70\x0e\xab"
+  "\xa9\x0d\xe7\x36\x06\x9c\x9a\x4f\xb1\x9a\x1a\x45\xb1\x52\xed\x75"
+  "\x0f\xab\xa9\x3a\x77\xdf\x4f\xeb\x1f\x07\xde\x90\x76\x71\xc5\x81"
+  "\x37\x38\xd9\xff\xbd\xe1\x85\x73\x1b\x07\xde\xc0\xf7\x7f\x6f\xe0"
+  "\xfb\xbf\xd7\xbb\xd9\xff\xbd\xc1\x89\xfe\xaf\x33\xe3\x7e\xd3\x75"
+  "\x18\x03\x9a\x34\xdb\x5b\xbc\x40\xfe\x5e\x49\x84\xe9\xf1\x05\xbc"
+  "\x64\x80\xd7\x7a\x25\xe9\xd5\x00\x5e\x7a\x23\x59\x18\xf7\x3d\xdb"
+  "\xd8\x69\x22\x3d\x80\xd5\x59\x88\x03\x9b\xf4\x1d\xf8\x8e\xde\x9d"
+  "\x6d\xcc\xf4\x17\x16\xc5\x29\x08\xe2\x85\xf2\x37\xc9\x26\x13\x16"
+  "\xf0\xe2\xf0\x93\xed\xce\x37\x6a\x76\x06\x2f\x38\xfe\x3d\xbb\x52"
+  "\xc7\xb2\x0d\xea\x6e\x5c\x3b\x52\xd1\xa0\x6e\x25\x41\xed\x64\xb4"
+  "\xf2\x51\xc4\x65\xfa\x54\x4c\x6f\xd2\xb7\x12\x5c\xf7\x93\x1b\x03"
+  "\xff\x5e\xe5\x6d\xfc\x97\x4a\x86\xeb\x37\xe1\x7b\x85\xc2\x1a\x4d"
+  "\x4d\xc7\xf2\x39\xfc\x6d\xc7\x54\x39\xfc\xff\xa5\x52\x6c\xc3\xf7"
+  "\x13\x87\x3d\x16\x9c\xc6\x8d\xff\x99\xbf\xf7\x99\x20\xd4\x71\x65"
+  "\x14\xcb\x42\x1d\xc7\x35\x1a\xf4\x04\xeb\xd9\x68\xd0\x92\xd4\x04"
+  "\xa2\x68\xec\xe9\x20\x29\x06\x56\xdf\x98\xf6\x33\x09\x3a\x8d\xf3"
+  "\x02\xc8\xa7\xe9\x71\x14\xef\x69\x05\xe6\xef\x55\x13\x74\xcc\x74"
+  "\x75\x63\x33\x21\x5e\xeb\x41\xd6\x46\xc2\x70\xef\x6b\x32\xc4\x03"
+  "\xe4\xa5\x6e\x4a\x6b\x43\xd9\x35\x37\x19\xbf\x45\x79\xaa\xe1\xfc"
+  "\xec\xbe\xf9\x06\xcf\x9d\x5f\x63\x1a\xca\x16\x9f\x33\x6d\x8a\xd5"
+  "\x73\x79\x84\xf3\x14\xbb\x34\xd2\x94\xd4\x43\x1a\x8d\x84\xc0\xfd"
+  "\x02\xbf\x0c\x6d\x05\x7e\x4d\x73\xd3\x6e\x4f\xef\x1c\x9e\xf1\x4a"
+  "\xff\x00\x8c\x5b\x4d\x9a\xd2\x10\x5a\xc7\x91\x27\x07\xe7\x57\x69"
+  "\xa8\x85\x5f\x33\x0e\x0d\x8d\x5f\x33\x36\x0d\x2f\xbf\x86\x3b\x7e"
+  "\x9d\x11\x32\x34\x7e\xcd\xf8\x8a\xf2\xeb\x46\x23\xe5\xd7\x8c\x3a"
+  "\x0b\xbf\x46\x9e\x3c\x77\xfc\xba\xb1\x82\xf2\xeb\x46\xb5\x7b\xfc"
+  "\xf2\x9f\x3f\x3c\xe3\xac\x37\x97\x60\xac\x0d\xfc\xe2\xed\xd7\x95"
+  "\x6d\x4e\xf0\x4b\x64\xbf\x6e\xbe\x7d\x68\xfc\xba\xe9\xe7\x61\xe6"
+  "\xd7\x30\xc7\xdc\x37\xed\x1d\x1a\xbf\x6e\xbe\x89\xf2\xeb\xa6\x30"
+  "\xca\xaf\x9b\x55\x16\x7e\x5d\xd9\x76\xee\xf8\x75\x93\x07\xe5\x97"
+  "\x7f\x9d\x7b\xfc\xba\xd9\xad\xf5\xaf\xfa\xf7\x0f\x6e\x21\xd8\x3f"
+  "\x30\x69\xca\x78\xfb\x35\xf6\xeb\xc1\xf9\x55\x26\xb2\x5f\x33\xb7"
+  "\x0e\x8d\x5f\x33\x1f\x1c\x5e\x7e\x0d\x77\x3f\x61\xa6\xf7\xd0\xf8"
+  "\x35\xf3\x65\xca\xaf\xbf\xd6\x52\x7e\xcd\xcc\xb4\xf0\x6b\xec\xd7"
+  "\xe7\x8e\x5f\x7f\x55\x53\x7e\xfd\x55\xe5\x1e\xbf\x6e\x71\xbc\xfe"
+  "\xb3\x4b\xe3\xda\xb7\x85\x63\x9f\x06\xf8\xc5\xdb\xaf\x5b\xb3\x9c"
+  "\xe0\x97\xc8\x7e\xdd\x7a\x76\x68\xfc\xba\x75\xd7\x30\xf3\x6b\x98"
+  "\xfb\x36\xb7\x26\x0c\x8d\x5f\xb7\xfe\x46\xf9\x75\xab\x2f\xe5\xd7"
+  "\xad\x1d\x16\x7e\xdd\x9a\x75\xee\xf8\x75\x4b\x1d\xe5\xd7\x2d\x99"
+  "\xee\xf1\xeb\x36\x27\xd6\x7f\x75\x66\x3c\xfe\x76\x2d\xf6\xc3\x4c"
+  "\x9a\x72\xde\x7e\x2d\x9a\x33\x38\xbf\xca\x45\xf6\xeb\xf6\x27\x86"
+  "\xc6\xaf\xdb\x47\x0f\x2f\xbf\x86\xbb\x3f\x36\xab\x65\x68\xfc\xba"
+  "\xfd\x11\xca\xaf\x59\xc9\x94\x5f\xb7\x07\x5a\xf8\xb5\x68\xce\xb9"
+  "\xe3\xd7\x2c\x15\xe5\xd7\x6d\x1d\xee\xf1\xeb\x76\x27\xd6\xff\x71"
+  "\x76\x1e\x61\xb6\xdf\xd0\xfa\x90\x77\x7e\x32\x34\x8e\xdd\x19\x7d"
+  "\x71\xf7\x21\xef\x9c\x35\x34\x8e\xdd\xf9\x1e\xe5\xd8\x1d\x3a\xca"
+  "\xb1\x3b\xab\xce\x4f\x1f\xf2\x0e\x0d\xe5\xd8\x1d\xf3\xdd\xe3\xd8"
+  "\xec\x61\x9c\xff\xb8\x3b\x73\x68\xfd\xc8\xbb\x27\x0f\x8d\x63\x77"
+  "\x7d\x75\x71\xf7\x23\xef\x2a\x18\x1a\xc7\xee\xbe\x86\x72\xec\xae"
+  "\xb9\x94\x63\x77\x2b\xce\x4f\x3f\x72\xb6\x9e\x72\x6c\xb6\x9b\xf3"
+  "\x36\x77\xbb\xf5\xfe\x8b\xfd\x79\x9b\x80\xce\xa1\xf5\x25\x03\x5e"
+  "\x1c\x1a\xc7\x02\x6e\xb9\xb8\xfb\x92\x38\x7d\x33\x14\x8e\x05\xac"
+  "\xa3\x1c\xbb\xa7\x82\x72\x2c\x20\xe1\xfc\xf4\x25\xef\x09\xa1\x1c"
+  "\xbb\xc7\xdb\x3d\x8e\x05\x74\x0f\xdf\x7c\xd3\x7d\xc1\x43\xeb\x4f"
+  "\xce\xf9\x79\x68\x1c\x9b\xb3\xf5\xe2\xee\x4f\xce\x89\x18\x1a\xc7"
+  "\xe6\xfc\x40\x39\x36\x47\x46\x39\x36\xa7\xf5\xfc\xf4\x27\xef\xad"
+  "\xa1\x1c\xbb\x37\xc9\x3d\x8e\xdd\xe7\xc4\xfa\xff\xce\xce\x93\xcd"
+  "\xdb\x3b\xb4\x3e\xe5\xbc\x05\x43\xe3\xd8\x5c\xd3\xc5\xdd\xa7\x9c"
+  "\x5b\x37\x34\x8e\xcd\x9b\x47\x39\x36\x37\x96\x72\x6c\xde\xec\xf3"
+  "\xd3\xa7\x9c\xeb\x4b\x39\x76\xdf\x61\xf7\x38\x36\x4f\x3b\x7c\xf3"
+  "\x7b\x81\x3e\x43\xeb\x57\x3e\xf0\xf6\xd0\x38\xf6\xc0\x92\x8b\xbb"
+  "\x5f\xf9\xc0\xb4\xa1\x71\xec\x81\x5d\x94\x63\xf7\xb7\x50\x8e\x3d"
+  "\x50\x72\x7e\xfa\x95\xf7\xa7\x51\x8e\xdd\xef\xe6\x7a\x14\x81\xfd"
+  "\xd6\xbf\x8a\x8c\x49\x5c\x12\x15\x19\xa1\x8c\x8c\x49\x88\x8f\x53"
+  "\xae\x8a\x5c\xb3\xfc\xae\x29\xcf\x4f\x53\xc6\x27\x29\xe3\x23\x63"
+  "\x9e\xe1\x13\x22\xc6\x90\x47\x97\x47\x2d\x49\xc2\x14\xc8\xfd\x4c"
+  "\x4c\xf4\xf2\x98\x04\x65\xfc\xf2\xb8\xe7\x23\xe3\x97\xe3\xf7\x55"
+  "\xca\x15\x2b\xe3\x21\x61\xd9\xf2\xc8\xc4\xe5\xca\xa5\xcf\xaf\x58"
+  "\xb1\x3c\x7e\xd5\x18\xb2\xe0\xf9\xa8\x84\xc8\xd8\xa8\xe5\xca\xb9"
+  "\x0b\xee\x9d\x1e\x32\xef\x6f\x21\xf7\xdc\x83\x9b\x93\x89\xf6\x26"
+  "\xf3\x65\x35\xbb\x73\x81\x73\xd2\xa3\xcc\x23\x6f\x37\xfa\x10\x6e"
+  "\x3f\xdb\xcd\x27\x89\x62\x53\x3c\x91\x66\x9e\x24\x1e\xd9\x27\x89"
+  "\x4c\xf9\x2c\x09\x60\x37\x75\xf8\x43\xba\x37\x9b\xad\x0c\x60\x73"
+  "\xe2\x7c\xe0\x33\x4d\x2f\x1f\x8d\x69\x0a\x36\xdb\x43\x8d\xe7\x40"
+  "\xb6\x52\x48\xef\x68\x63\x1e\x89\xd5\xcb\xc7\x28\x52\x7f\x26\x0c"
+  "\x3b\xe6\xc1\x90\x37\xcd\x7a\x66\x1f\x8e\x54\x41\xdb\x09\xf3\x50"
+  "\x14\x1c\xa1\x84\x79\xd8\x03\x0e\x1f\x38\xfc\xe0\x98\x0f\x47\x08"
+  "\x1c\x6a\x38\x12\xe0\x48\x83\x23\x13\x8e\x5c\x38\xf2\xe1\x28\x21"
+  "\xcc\x7c\x5f\x38\x66\xc3\x01\x79\xe7\x47\xd0\x72\xe6\xc7\xc2\x51"
+  "\x00\x47\x3b\x61\x16\x40\x59\x0b\xbd\xe1\x08\x80\x43\x07\x47\x38"
+  "\x1c\xc9\x70\x64\xc0\x51\x01\x47\x3d\xe4\x4b\xa0\xe7\x82\x20\x2d"
+  "\x48\x4b\xa0\x9e\x83\x1f\x41\x98\xbf\x83\x30\xc1\x32\x38\xe0\x9e"
+  "\xc1\xcd\x90\xae\x1c\xe0\x1a\xf5\x20\x65\x66\x7a\xad\xbf\x56\xc7"
+  "\xed\x81\xc7\x3c\x74\xd0\x94\x4e\x46\x98\xb2\xc7\x28\x62\xaf\x27"
+  "\x92\x63\xcc\x43\xaf\x35\x65\xa0\x9d\x51\x06\x70\x7b\x3a\xc2\x6f"
+  "\x94\x59\x57\xd6\x43\x79\x3a\xf2\x6a\x26\xee\x69\xe6\x1a\xdf\x1e"
+  "\xca\xe3\xaf\x6f\xd1\x49\x54\xb1\xdc\x1e\x70\x59\x47\x0a\xd8\xd4"
+  "\xd0\x6d\xdc\xde\x6f\x28\x43\xd4\x83\xcc\xc3\x06\xd6\xe3\x5f\x1a"
+  "\xd4\x79\xed\x1a\xae\x5e\xd1\x6c\x3a\xf1\x84\xeb\xa3\x58\xa8\x9b"
+  "\x5e\x1e\xe7\x03\xf5\x94\xe2\x6f\x53\xf6\x68\xff\xb3\xf2\xca\x58"
+  "\xfc\xde\x5d\x18\x55\xc2\x6a\x2a\xf3\xb1\x9f\xad\x4d\x79\x85\xb4"
+  "\xc1\x75\x67\xe5\x55\xb3\x94\x0f\x79\xb1\x6d\x78\x6d\x3a\x61\x74"
+  "\xcc\xc3\x84\xea\xea\x43\x51\x67\xe5\x71\x4a\x53\x7e\x55\x38\xa4"
+  "\x4b\x4d\xd9\x71\x3e\xb4\xfc\xd1\x60\x27\x77\x06\x40\xbe\x30\x2e"
+  "\xbd\x20\xaa\x46\xf8\x0e\x9f\xa1\xa6\x9c\xca\x56\xfc\x94\xaf\x27"
+  "\x06\xee\x77\x7a\x00\xa1\x9f\x0a\xa2\x7c\x88\x90\x4e\x66\xbe\x64"
+  "\x46\x1d\x91\x68\x1f\xc2\x7a\x3f\x5c\x9f\x5a\xc7\x9a\x95\x29\x23"
+  "\xe0\xfe\x0f\x37\xf4\xdd\xf7\x9a\xaa\x50\xdc\x23\x95\xcd\x0a\x8c"
+  "\x28\x7e\x85\x10\xbc\x16\xeb\xb6\x75\x1c\x91\x16\xbe\x42\x3c\xb0"
+  "\x8d\x5d\x59\x0f\x77\x0b\xfb\xd0\xe1\x35\x0c\xe4\x7f\xf0\xc1\x54"
+  "\x56\x54\xf6\xe7\x26\xae\x3d\x0f\xa9\xa9\x4c\xe7\xab\x74\x92\x29"
+  "\x51\x98\x5f\x79\x1d\x27\xcb\x68\xfe\x7c\x14\xe2\x89\xe5\xb3\xd9"
+  "\xbb\x73\xf1\x37\xee\x73\xe7\x55\x47\x18\x65\x8a\x5f\x0d\x95\x51"
+  "\x65\x3e\x96\x83\xf9\xd9\x9c\x1d\xf0\xfd\x61\x19\x9b\xcd\xc9\x58"
+  "\xa5\x8c\x21\x01\x6d\xcc\xfc\xd7\x4c\x9b\xbe\x0b\x81\x32\x40\xef"
+  "\xbe\x0b\x85\xfc\xd5\x9c\xbc\xb3\x77\xfa\xeb\x98\xf9\x99\x70\x2e"
+  "\xb4\x6f\xef\x4b\x2a\x67\x09\xe4\x53\x43\x9d\x6a\x75\x92\xbb\x92"
+  "\x39\x9c\x13\xd9\x16\xdc\x63\xf3\x54\x22\x6b\x0c\x32\x7e\x6f\x06"
+  "\x5b\x45\xe0\xfc\x61\x1d\xb9\xaf\x42\x68\x23\xc5\xbe\xaf\x9c\x68"
+  "\xfc\xad\x1f\x8d\xe5\x2c\x90\xda\x2b\x07\xee\x5d\xff\xb4\x51\x29"
+  "\xe9\x39\xc3\x36\x6f\xfe\x3b\xca\x91\xb0\x3d\x89\x6c\xfd\xba\x40"
+  "\xb6\x3b\xe7\x6b\x42\x1a\xd4\x87\x09\xe8\xbc\xaf\xa7\x84\xd5\x07"
+  "\xbd\x40\xbc\x3c\x63\xbd\xd8\x83\x75\x87\xc9\xda\x40\xb6\x03\xf7"
+  "\xf0\x6d\x34\xb4\x93\xe4\x43\x44\x96\xda\x40\xbc\x93\x03\x59\x7d"
+  "\x7d\xf8\x61\x42\xd3\x1b\x48\xea\x0f\x44\xba\xf6\x00\xdb\xbd\x10"
+  "\xec\xff\x97\x87\x31\xbd\x9d\xe0\x1e\x95\xa9\x1d\xac\x31\x65\x31"
+  "\x91\xe1\xf7\x86\x03\x98\xfe\x23\x49\x3d\x4e\xa4\x41\x49\x7a\xaf"
+  "\x22\xb8\x27\x5e\x5f\x0c\x75\x31\x9f\x61\x6b\x37\x9f\x21\x64\xed"
+  "\x13\xc4\x27\x79\x09\x51\x04\x99\x08\xdb\x64\x7c\x8f\x04\x99\x58"
+  "\xf0\x2f\x9f\x93\x75\x91\xc4\x23\xc8\x88\xef\xb1\x7d\x43\x70\x9f"
+  "\xee\x62\xc8\x0b\x6d\xd3\x62\xdb\xd6\x1e\x21\x3e\xb8\x3f\x39\xbd"
+  "\xe6\x13\xfe\x9a\x23\x04\x65\x76\x56\xae\x8c\xed\xce\x56\xea\xa1"
+  "\xed\xcd\x28\x03\xb8\x4f\xb3\x19\xaf\x83\xeb\x37\xc7\x73\x32\x90"
+  "\x3c\x6d\x24\x32\x53\xf6\x4e\x9f\xa7\x93\xb4\x5c\xb9\x3a\x66\xa1"
+  "\xac\x38\x9e\xab\x93\x55\xde\x20\x23\x7b\x4a\x2f\xdf\x09\xbc\x5f"
+  "\x38\x33\x28\xe9\x1e\x16\xaf\x05\x2c\x23\xba\xb2\x16\x26\x08\xf2"
+  "\x16\x70\x81\x3c\x6a\xc0\x22\x62\x44\x2c\x91\xc2\xf9\x3c\x9d\x24"
+  "\x20\xd4\xc2\xb5\x87\x91\xbf\x57\x08\x79\xf9\x3c\x35\x3a\xc9\xdd"
+  "\x25\x22\x3e\x22\xbf\xfa\xf2\xc0\xf9\x56\x9d\xe4\x1e\x1e\xfb\x85"
+  "\xf9\x98\x87\xb7\xfd\x42\xde\x11\x6c\xe6\xbf\xc2\x4d\xf2\xca\x12"
+  "\x96\x61\xbb\x81\x8f\xb3\xd8\x53\x3e\xb2\x85\x46\xb6\xdb\x9c\xbd"
+  "\x03\xed\xbc\x0c\xf7\x75\xa5\xf9\x83\x22\xe1\x7c\x80\x32\x91\xfb"
+  "\x9e\x8c\xf7\x61\x35\x71\x01\x7d\xe7\xd2\xc9\x48\xb6\x30\x2a\x17"
+  "\x7c\x87\x22\xa8\x8e\xed\x06\x5d\xcf\xcd\x89\x47\xdf\x51\x99\x8b"
+  "\x7a\x6d\x96\xef\x0c\xec\xde\x5a\x15\x80\xf6\x09\x75\x84\xd5\xec"
+  "\xf0\xa7\xd7\x3e\x2c\x41\xbd\xa1\xb6\x26\x28\xc0\x04\x65\x40\x9d"
+  "\x22\xe0\xdc\xc8\x36\x26\x68\x2f\xbe\x4f\x0a\xbf\x0b\xb8\x7d\x2f"
+  "\x99\xa0\x0f\x29\x7f\xff\x15\x6e\xf5\x9b\x41\xd9\x81\x3e\x81\xcd"
+  "\x42\xfb\x00\xe9\x87\x44\x3a\x4c\x58\x5e\x47\xcf\xca\x77\x04\x50"
+  "\x3b\x32\xc2\x0c\xf9\x24\x6d\xbc\x3e\x9e\x1d\xfd\x5d\x58\x57\x56"
+  "\x30\xf0\x5f\xa9\xb0\xd2\x93\xac\x16\x82\x7b\x6c\x42\x5d\x46\x1c"
+  "\x65\x82\x6f\x82\xcf\x51\xf0\x79\xcb\xfe\x3a\xc4\x9b\x2b\xf7\x4a"
+  "\xfc\xbe\x75\x3c\xab\x9f\x0b\x11\xf0\x29\x06\xf5\x2d\x78\xbe\x8e"
+  "\xc4\xcd\xc7\x72\x36\xe1\x3e\xa3\x90\x86\x79\x20\x3d\x42\x47\xe2"
+  "\x67\xd3\xf2\x1f\x96\x19\xa0\xae\x36\xe5\x6f\xa2\xe5\xd3\x72\xb1"
+  "\x3c\xa1\xec\xc2\x2d\x6c\x27\x5f\x76\x85\x50\x76\x36\xa4\x09\xe5"
+  "\xcf\x8d\xee\xbb\x47\x1d\x9c\x3f\x20\x6e\x43\xfe\x16\xd6\x80\x65"
+  "\xc0\xb9\x76\x1d\xd9\xe8\x8f\xe7\x32\x21\x0d\xaf\x15\xf1\x6a\xc4"
+  "\xfe\x40\x28\xe3\x00\x96\xf1\x88\x4c\x47\x32\x6a\x6c\x6c\x9c\x5c"
+  "\xb0\x71\xb4\xac\x47\xfc\x85\xb2\x2c\xe5\x08\x7c\x6a\x6b\xe6\x71"
+  "\xc5\x72\x65\x58\x2e\xe4\x0f\xd7\x91\x04\x99\xb8\xed\xa0\x5b\x10"
+  "\x5f\x56\x56\xa0\x1d\xe3\xf9\xf8\x1a\xda\x64\xa1\xde\xb8\xcf\x28"
+  "\xd8\x6e\x0d\xea\x0b\x67\xbf\xb3\x77\x2a\xa1\x9c\x0a\x1b\x7b\x2d"
+  "\xc5\x7c\xa6\xac\xc0\x7d\x85\xb8\xcf\xea\x78\xb6\x03\xf2\xd4\x5b"
+  "\xed\x2d\xca\x90\xbb\x21\x4d\x27\xec\x71\x9a\x03\x79\x20\x26\x73"
+  "\xb8\x86\x63\xca\x64\xc2\x34\x15\xe8\x30\x7e\x46\x5e\xcd\x6e\xf2"
+  "\x35\x90\xa6\x02\x33\x31\x17\x45\x69\x03\x52\x58\xed\x51\xe6\xd1"
+  "\xc5\xb8\x37\xb5\x6b\x3e\xf9\x51\x15\xc7\xa7\x1e\x88\x2b\x93\x6f"
+  "\x26\xe8\x87\x4f\x30\x7f\xcb\x6e\xd2\x9f\xe4\x74\x0b\xbe\x73\xef"
+  "\x47\xbf\x0a\x71\x28\xc6\xa2\x10\xff\xab\x73\x19\x1a\x8f\x9a\x21"
+  "\x6f\x11\xa6\x63\xac\x0a\x76\xb2\x58\x74\x8e\x2d\x8a\x4a\xa2\xb2"
+  "\xfb\xdb\x3c\xce\x1f\x60\x7d\x8d\x0f\x68\xb1\xce\xe6\x82\xa8\x24"
+  "\x6c\x43\x6a\x12\x6b\x6e\x32\x76\x69\xd1\x96\x2a\x13\x31\x8e\xfe"
+  "\xdb\xe4\xa0\x42\xc2\x9a\x0b\xa3\x92\x5c\x6c\x03\xf7\xfc\x13\xf4"
+  "\x15\x4e\xe8\x27\x46\x25\xe1\x5e\xcf\x9b\x53\x46\x7a\xdc\x57\xc0"
+  "\x6a\x4f\x4d\x8a\xd2\x76\x65\xfd\x6d\xae\xb0\x97\xae\x6b\xe5\xfe"
+  "\x6d\xae\xd0\xf6\x22\xbe\xed\x70\x2f\x6e\xcf\x9e\x19\xf9\xdc\x5e"
+  "\xde\xf0\xfb\x6f\x0e\xf7\xfa\x04\x3b\x52\x81\xd7\x42\xdb\x03\x8a"
+  "\x05\x39\x19\xf5\xb8\x8f\xf9\xd8\x63\x4c\xc8\xd8\xa0\x64\x2d\xe1"
+  "\xd6\xed\xcf\xde\x51\xe1\x62\xbd\xb8\xe7\xdf\x1b\xa1\x9f\x12\x64"
+  "\xfc\x94\xa5\x76\x2f\xe4\xf6\x85\x7c\x79\x78\x4e\xc0\xaa\x88\xef"
+  "\x3f\xb8\x7e\x8f\x90\x00\x27\xda\xa5\xb0\xd3\xae\x9f\xdd\x6f\x57"
+  "\xc8\xde\xfe\xed\x7a\x6c\xec\xf0\xb6\xeb\x31\x1f\x27\xda\xa5\xec"
+  "\xdf\xae\xc7\xf6\xb9\xdf\xae\xc7\x34\x76\xda\xf5\xf3\x30\xb7\x4b"
+  "\xef\x44\xbb\xfc\xfb\xb7\xeb\xef\x5b\xdd\x6f\xd7\xdf\x23\xfa\xb7"
+  "\xeb\xef\xfb\x86\xb7\x5d\x7f\xaf\x73\xd9\x1e\xe6\x54\xea\xa9\x3d"
+  "\x7c\x3c\xda\x75\x7b\xf8\xf8\xac\xfe\xf6\x30\xb4\xd0\x62\x0f\x43"
+  "\x37\xb9\x65\x0f\x73\xe2\xf8\x98\x22\xf4\xb1\x7e\xf6\x50\x13\xe7"
+  "\x6f\xdf\x1e\x86\xde\xc4\xd9\xc3\xec\x38\x17\xfb\xf5\x8f\x1b\xfb"
+  "\xec\xa1\x3c\xce\xdf\xca\x1e\x7a\x56\x82\x8f\x0c\x0d\x71\xcf\x1e"
+  "\x86\x86\xf4\xb7\x87\x8f\xef\xb5\xb6\x87\xa1\x0e\x9f\x75\x66\x35"
+  "\x3b\x55\xf6\xec\x61\x90\xf1\x57\x96\x72\x63\xa7\xca\xc5\xfa\x38"
+  "\x7c\xff\x1b\x38\x5f\x3d\xf0\xbd\x76\x54\xbb\x76\xaf\x27\x82\x1d"
+  "\xde\xcb\xe3\x5f\x69\x10\x67\x28\xd6\x6d\x27\xcc\x51\xe8\xe1\x37"
+  "\xfa\xb6\x42\x3f\xa0\x9b\xdc\x18\x0b\x9c\x48\x27\xb3\x1b\x0b\x3a"
+  "\x49\xa3\xef\x51\xc2\x8e\xfe\x57\x1a\xbb\x33\xda\x3f\x20\x1e\xb9"
+  "\xf9\xe4\xe8\xa6\x84\x6e\x17\xb9\xf9\x44\x8b\xc0\xcd\x46\x23\x70"
+  "\x33\x11\xf9\xb8\xe8\xf6\xa6\xce\x63\x3c\x37\x17\x4d\xe9\xc3\x27"
+  "\x9d\xf2\xd3\x2e\x37\x41\x27\xac\xb9\xb9\xa3\x84\x72\xf3\xc9\xdf"
+  "\xfa\x73\x73\x47\x89\x7d\x6e\x3e\xd9\x40\xb9\xb9\xa3\xc4\xb5\x36"
+  "\x3c\x99\x6f\xe1\xe6\x8e\x12\x2b\x6e\xfe\x39\xda\xbf\x2b\xeb\x49"
+  "\xbd\x7b\xdc\x7c\x52\x2f\xb4\xbd\x90\x6f\x3b\xa4\x05\x5b\x73\x73"
+  "\x91\xca\x21\x86\x99\xfb\xeb\xc0\x1e\xca\x8e\x31\x8b\xba\x4d\x10"
+  "\xb7\x9a\x35\x9e\x2a\xe8\x77\x75\xe1\x9e\xf1\x2c\x33\x93\xb0\xab"
+  "\x55\xb2\x2e\xe8\xff\x76\x75\xa9\x3d\xd8\x31\xff\x1a\xc3\xf6\xfa"
+  "\x10\xa8\xbb\x17\xdb\xa5\xf2\x04\x99\xf9\xc1\xe7\xb8\xc2\x44\xe2"
+  "\x0d\x87\x4f\x21\x2f\x57\xf8\xee\xcf\xae\xf6\x19\x93\x93\x48\xa6"
+  "\x79\x19\x88\x07\xd4\x21\xd4\x6b\xbd\x82\x78\x19\x89\x37\x7e\x67"
+  "\xd3\x3f\x33\x42\xff\x4c\x8a\x63\x9f\x66\x39\xdc\x2f\xc9\x8b\x65"
+  "\x57\xa9\x08\xf4\xd5\x3c\x00\x03\x9f\x62\x86\xad\x36\xad\x56\x31"
+  "\xac\x67\xe5\x6e\x76\x6d\x28\x57\x27\xb3\x5f\x74\x2c\x70\x28\x96"
+  "\x4d\x55\xe3\x7d\x03\x70\xef\x62\xf6\xcf\xd1\x09\x6c\x97\xcf\x98"
+  "\xec\x33\x64\x5a\x71\x22\xf1\x2b\x4a\x24\x2a\xb6\x57\xc5\x80\x0c"
+  "\x42\x9f\x8a\x53\x20\xee\xa1\x2c\xf3\x19\xee\xe1\x2e\x85\x7b\x4b"
+  "\x4c\xd9\x70\x2f\x23\xdc\xeb\x57\xb8\xd7\x09\xb8\x57\x3a\xdc\x2b"
+  "\x9d\xde\xcb\x35\x99\x87\x0d\xb8\xff\x73\xd0\xba\x49\xb8\x96\xee"
+  "\x4f\x5e\x49\xa3\x02\x71\xbc\xfa\xd4\x5a\xb5\x8b\x7c\x0f\x73\xb8"
+  "\xfe\xf3\xe6\x37\x89\x2f\x2b\xf3\x08\x5d\xf8\xe2\xf7\x2c\xf6\xa3"
+  "\x5f\x7c\x93\x4c\x43\x9d\x6b\xec\x3e\x4e\x58\xb9\x47\xe8\xe7\xaa"
+  "\x4e\x17\xef\xb5\xd8\xe1\xf3\x0f\x59\xe9\xd0\x6f\x96\x41\x3f\x54"
+  "\x56\x59\xb3\x39\x9d\x4d\xea\xf5\x8d\xca\xed\xf1\x8d\xaa\x7e\xda"
+  "\xa8\x00\x5e\xb1\x49\xca\x78\xa2\x3c\xca\x2c\x7b\xfe\x8b\x16\xf0"
+  "\x11\x4f\x12\x8f\x36\x66\x59\x55\xea\x21\x1c\x6b\x5c\xac\xb5\x1e"
+  "\x6b\x5c\xdc\x4e\x98\xa7\x43\x08\x13\x1e\x41\x98\x25\x99\x04\xf2"
+  "\x59\x1f\x4b\xcb\x69\x59\x4f\xdf\x14\xb4\x6b\x12\x49\x31\xb2\x3f"
+  "\x41\x3f\x36\x33\x07\xfa\xbf\x41\x53\x25\x3a\x6d\x22\x8e\xc1\x3d"
+  "\x3d\x15\x64\xfa\x0b\xf8\x25\xaf\xa3\xcc\x53\xa7\x01\x3b\x12\x1b"
+  "\x4f\xae\x3a\xc6\x3c\x65\x30\xc2\x77\x2f\xc3\xa8\x40\x53\x6a\x28"
+  "\x31\xfa\x54\x05\xf4\x6a\x2a\x73\x4d\xd0\x97\x35\xcb\x3c\x55\x38"
+  "\x0e\xd2\xd4\x69\x22\x05\xc0\xbb\xa7\x4d\x1e\xa8\x0f\xa1\xda\xa5"
+  "\x5f\x90\xa3\x09\x84\x49\x3d\x4d\xe4\xec\x29\x95\x4c\xe0\xf5\x82"
+  "\x4e\xaf\xee\x75\x9d\xac\x19\xf9\x8d\xe3\x0e\x70\xce\x33\xe5\x34"
+  "\xf8\x5a\x7d\x07\x29\x80\x7e\xb3\x69\x95\x7a\x9c\xfe\x94\xfa\xaa"
+  "\x6d\x66\xe2\xed\x69\x20\x8a\x82\x93\xc0\xc1\x55\xc0\xbf\x93\xc0"
+  "\x73\x3d\xe5\x39\xbe\x2b\x54\x84\x1c\xdf\xf8\x6f\x69\xf1\x49\xca"
+  "\x71\x8e\x77\xc8\xf1\x95\xc0\xbb\x18\x0b\xef\x8c\xa7\x80\xe3\x59"
+  "\x61\xe5\x05\xe9\x2c\x8e\x8b\x30\xc5\xc7\x46\xe1\x39\xc9\xc8\xa9"
+  "\x8c\xf2\x8b\xe0\x6e\x62\xe9\x87\x2d\xdb\xd3\x33\x31\xaa\x5a\xf9"
+  "\x28\xfb\x6b\x1b\xf3\xb4\x12\xd2\x3d\x94\x7f\xff\x8b\x02\xe4\xbd"
+  "\x87\x8e\x51\x2c\xab\xc2\x7e\xbe\x0e\x64\x81\x72\x51\x3e\x4a\xfe"
+  "\xd2\xc6\x2c\x3e\x8d\x72\x5c\x5d\x41\x46\xc4\xde\xcd\xb6\x83\xcc"
+  "\x8c\x58\x1e\xe0\xcd\xf5\xb3\x70\xfe\xe3\x4b\x6e\xec\x93\x5e\x63"
+  "\x02\xb9\x19\x65\x71\x01\x80\x77\x85\xf6\xd9\x1e\x4e\xe7\x50\x8e"
+  "\x47\xa3\x00\xb9\x4e\x90\x95\x09\x64\xd5\xc5\xd9\x82\x60\xce\x16"
+  "\x64\xfe\x4b\x9a\xac\x63\xcd\x41\x11\x23\xd8\x94\x38\x9c\x7b\x31"
+  "\x91\xa7\x62\x09\xbb\xee\x38\xc8\xcb\xd0\x8a\x76\xc3\xd3\xbc\x9a"
+  "\xda\x06\x94\x97\xbc\x93\x28\xd8\x9c\x31\xca\x37\x53\xea\x46\x9a"
+  "\x80\xbf\x68\x1f\xbc\xd6\x4b\x46\x83\x5e\x7a\x6a\x50\x7f\x41\x9f"
+  "\xbd\xd6\x73\xf6\x2a\xb4\x00\xf4\xd6\xb8\x5a\x75\x5d\xef\x6a\x95"
+  "\x12\x8e\x49\x82\x0d\xc1\x3d\xbf\x0a\x51\xb6\x59\x8b\x65\x68\x3f"
+  "\x9a\x92\x74\xc4\x08\xb2\xf5\x44\x7f\xb3\x5a\xe5\xcb\xc9\xf8\x19"
+  "\x15\x99\xd1\x4d\x24\x50\x27\x05\xd4\x97\x14\xaf\x20\x1e\x0d\xea"
+  "\x36\x62\x02\xdd\x10\xe4\xbe\x20\x52\x49\xa0\x5c\xe6\x73\xd5\x37"
+  "\x84\x97\x99\xc4\x31\xef\x96\xac\xb7\xf0\x6e\xc9\x7a\x94\x1d\xe5"
+  "\xdd\x92\xb4\x4b\x91\x77\x5f\x86\x72\xbc\x1b\xd1\x3b\x91\xe3\x93"
+  "\xb1\xc9\xf8\x0e\xc8\x68\x09\x8e\x6d\x12\xe4\xcc\xc1\x4a\xe4\xcc"
+  "\xd2\xbc\x8b\x95\x33\x67\xbb\x54\x4a\x38\xce\x09\x67\xa0\x5c\x8e"
+  "\x33\x28\xab\x2f\x43\x7b\x88\x20\x23\x4e\x57\x35\x1e\xa1\xca\x54"
+  "\x72\x0f\xe8\x6a\x95\xd7\xfa\x49\xa4\x81\x93\xd3\xb2\x2a\xe5\xdf"
+  "\x59\x73\x1b\xb3\xb4\x21\xf5\x2b\xa2\xe8\x49\x67\xd9\x26\xe3\x1e"
+  "\x62\x96\xed\x0c\xc4\x71\x66\x88\x7f\x73\x85\x39\x1c\x1c\x8f\xf3"
+  "\x8a\xc5\x79\x9b\xd1\xfe\xa6\xec\xdd\xb9\xe6\x6c\x0f\x35\x2b\x57"
+  "\x76\xe0\xd8\x9b\x79\x53\x87\xbf\x59\xae\x0c\xe8\xca\x5a\xe6\xad"
+  "\x23\xff\x09\xe0\xc6\x83\x35\x95\x18\xbb\xa0\xfd\xbd\x8b\x1b\x2f"
+  "\x96\xe3\xd8\xf9\xb2\x99\xc2\xfc\x04\xda\x04\x7e\x5c\x8e\x1f\xb7"
+  "\x5b\x86\x18\x8e\xc1\x71\x3b\xde\xa6\x4c\x11\xc6\xed\x84\xdf\x78"
+  "\x1e\xae\x53\xe1\x98\x8f\xe8\xba\x72\x3e\x1f\x7f\xdd\xe2\x5d\x68"
+  "\xeb\x2d\xd7\xd1\xdf\x60\x57\xca\x7b\x19\xe2\x61\x37\xc6\x90\xed"
+  "\xce\x05\xfd\x91\x1e\x65\x22\x76\xc1\x27\x03\x9f\xf3\xe0\x73\x04"
+  "\x7c\x5e\x8d\x65\xbb\xe6\xaf\x96\xe9\xb8\xfa\x68\x2a\x0f\xf3\xf5"
+  "\xe6\x9e\xa5\x88\xbd\x9e\xc8\x8f\xf1\xdf\xbb\xb2\x22\x66\x0b\xf3"
+  "\x2c\x96\xfc\x7d\xf8\xb4\xe2\xbd\x01\x23\x29\x9d\xfb\xa1\xbf\x45"
+  "\xe5\x1d\xe2\x7e\x13\xa9\x12\xb0\x09\xc6\x39\x5a\xe0\xaf\xa4\x8b"
+  "\x55\xdf\xcd\x7f\xde\x85\xfa\x81\xe3\xa5\x18\xaf\xf1\xf6\x57\xc7"
+  "\xdf\x77\x2f\xc8\xc1\xea\xbe\xf6\xe4\xa1\x63\x22\x9a\x1d\x9d\x73"
+  "\x4d\x16\x11\x0e\xdf\x7f\x9b\xa7\x32\xb1\xae\x95\xb5\x7c\x96\xc3"
+  "\x18\xd1\x37\x2a\x36\xa8\xc2\xa4\x35\xf7\x86\x7a\x7d\x9e\x7c\xdc"
+  "\xc5\xf8\x62\x79\xae\xa3\x72\x4d\xb2\x9d\xe1\xc6\x82\xa8\x58\x1c"
+  "\x93\x6c\xac\x30\x92\x5d\xc7\x3a\x98\xa0\xa9\x93\x88\xbc\x9d\x28"
+  "\x30\x7e\x5a\xd0\xf9\x29\x8b\x31\x54\xce\x31\xe2\xd7\xf3\x6b\xa8"
+  "\x57\x2f\xc4\x82\x2f\x1d\x23\xb3\xcd\xcf\xf8\x8c\xd1\xac\x20\xd2"
+  "\x1e\x88\x57\x7b\x9e\x51\x7b\x7d\x79\xb8\x83\x80\x9e\xc4\x36\x1a"
+  "\x74\xa4\x08\xf2\xb2\x3f\x85\x7a\x3e\x18\xce\x76\xd7\x87\xbf\x42"
+  "\x82\x54\x26\x6d\xca\x0f\x44\x0e\xb6\x48\xd1\x94\xb4\x87\x34\x19"
+  "\x8f\x93\x91\x2f\x30\xca\x26\xe3\x8f\x24\x7b\x05\xd8\x30\xb0\x59"
+  "\xa9\x4f\x80\xad\x36\x9e\x26\xdb\xc4\xb6\xfa\xd9\x52\x8b\xad\xfe"
+  "\x15\x6c\x75\x16\xd8\xea\x54\x1f\xd2\x18\xab\x25\x60\x3b\x46\x2d"
+  "\x8c\xf5\xea\x4e\x89\x05\x9b\xfd\x02\xd8\xec\xa4\x1f\x09\x67\xaf"
+  "\x3b\x3b\x08\xd8\x5a\xcf\xc2\x18\xe2\xdd\xbb\x12\x6c\xf6\xaf\xea"
+  "\xab\xb6\xa6\x50\x9b\xfd\x7a\x0c\xd8\xec\x95\x10\x13\xc7\x80\xcd"
+  "\xee\xb4\x63\xb3\x4f\x38\x88\x87\x79\xfb\xd3\xb3\x52\xc5\xbc\xce"
+  "\xb0\x38\xaf\xc2\x6c\xfd\x76\x94\x8b\x3c\x79\xc6\xdb\x11\x06\x28"
+  "\x6f\x94\xbf\x19\x70\x68\x00\x0c\xb8\xb8\xb5\x7b\x54\x60\x2f\xf8"
+  "\x34\x93\xe7\xf6\xea\xca\x63\xad\x8c\x67\x02\x51\x2c\x8c\xfd\x94"
+  "\xed\x59\x15\x0a\x71\x7f\xa8\xdc\xa8\xd9\x19\xae\x81\x98\xda\x04"
+  "\xb1\x77\x6f\x97\x8f\x07\xc8\x40\xa1\x5f\xad\xf6\x42\x19\x9a\x27"
+  "\x02\x9e\x57\x04\x26\x80\x0d\x9d\x59\xb8\x82\xcc\xea\xcd\xde\x7e"
+  "\x98\xcd\xde\xde\x6c\xca\xde\xde\x02\xd7\x7a\x3e\xac\x43\x5c\x3e"
+  "\x22\x90\xa6\x67\x73\xca\xab\x4d\xf2\x9d\xe1\x7a\xf9\xf6\x56\xf8"
+  "\xdd\x81\xe7\x53\x96\x10\x79\x90\xea\xac\x96\xe2\xb5\x83\x20\x4e"
+  "\x14\xaf\x23\x24\x1b\xfa\x7d\xe8\x73\x39\xff\xca\x63\x06\xfd\x05"
+  "\x2e\xde\xb7\xe0\x66\xe3\x63\x79\xdc\x1a\x3a\xb5\x04\xfc\xc9\xa8"
+  "\x3e\x5f\xcb\xe1\x76\x84\x08\x7e\x16\xe4\xed\x59\x08\xbe\xb6\x77"
+  "\xb8\x7c\x2d\xdf\x8f\x41\x5f\x8b\x7e\x16\x71\x7b\xdd\x65\xdc\xd4"
+  "\x0e\x9f\x7f\x1f\x18\xb7\x52\x7f\x37\x71\xab\xb7\xe0\x56\x1a\xc6"
+  "\x66\x97\x06\x9b\xb2\x4b\x43\xac\x71\x2b\x8d\xb5\xe0\x56\x1a\x0a"
+  "\xbf\xd5\x16\xdc\x4e\xbb\x80\xdb\xc8\x93\x97\x2e\x6e\xcf\x3a\x5c"
+  "\xff\x68\x10\xdc\xdc\xd4\xb7\x07\xfd\x44\xb8\x81\xbe\x95\x82\xbe"
+  "\x95\xda\xe8\x5b\xa9\x48\xdf\x4a\x41\xdf\x4a\x45\xfa\x76\xdc\x05"
+  "\xdc\xae\x6c\xbb\x74\x71\x8b\x72\xb8\xfe\xe5\xc0\xb8\x95\xb9\xa9"
+  "\x6f\x0f\x26\x5b\x70\x2b\x03\x7d\x2b\x03\x7d\x2b\xb3\xd1\xb7\x32"
+  "\x91\xbe\x95\x81\xbe\x95\x89\xf4\xed\x88\x0b\xb8\x8d\xfd\xfa\xd2"
+  "\xc5\x2d\xda\xe1\xdc\xe1\x20\xb8\xb9\xab\x6f\x2d\x22\xdc\x40\xdf"
+  "\xca\x40\xdf\xca\x6c\xf4\xad\x4c\xa4\x6f\x65\xa0\x6f\x65\x22\x7d"
+  "\xfb\xc4\x05\xdc\x6e\xcd\xba\x74\x71\x5b\xe9\xf0\xfd\xe7\x81\x71"
+  "\x2b\x77\x53\xdf\x1e\x9a\x66\xc1\xad\x1c\xf4\xad\x1c\xf4\xad\xdc"
+  "\x46\xdf\xca\x45\xfa\x56\x0e\xfa\x56\x2e\xd2\xb7\x75\x2e\xe0\xb6"
+  "\x68\xce\xa5\x8b\x5b\x9c\xc3\xf1\x4f\x01\x37\x01\x33\xc4\x8f\xc3"
+  "\x8d\x0d\x25\x46\x88\x27\x77\x2f\xa5\xb8\x21\x5e\x1c\x76\xa7\x42"
+  "\xbd\xb2\x79\xcc\x8c\x3c\x66\x28\x3f\xc4\x0d\xe3\x48\x0e\x37\x89"
+  "\xd4\x07\x63\x48\x23\xc4\x92\x42\x1c\xf9\x90\x9a\xed\x6e\x50\x97"
+  "\xf6\xc5\x91\x46\xdb\x38\x32\x52\x1c\x47\xee\xb1\xc2\x4b\x73\x06"
+  "\xf0\x62\x78\xbc\x16\x3b\x88\x23\x57\x7c\xe6\x00\xaf\xe6\x41\xf1"
+  "\x02\x6c\xbc\x7b\x4f\x51\xbc\x5e\xe7\xe3\xff\x82\xf8\x21\xe2\xb5"
+  "\x0a\xf0\xc2\xf8\xff\x08\x61\xb6\x3d\xe5\x2a\x5e\xab\x06\x8d\xff"
+  "\xed\xe3\x55\xe6\xef\x1a\x5e\x0f\x26\x5b\xf0\x2a\x0b\x36\x82\x4f"
+  "\x13\xfc\x99\x05\x2f\xea\xcf\x8c\xb6\xfe\x2c\x52\xec\xcf\x9c\xc1"
+  "\xcb\xc6\x9f\x5d\x52\x78\x25\x38\x1c\xff\x37\x41\x5f\xdc\x04\x76"
+  "\x0e\xc7\x2b\x3d\x3b\xa0\x9f\x6c\x64\x7f\x5a\x68\x80\x7e\xb2\x71"
+  "\x54\xe0\xe6\x18\xe2\xd7\xbb\x1a\xfa\xc9\x80\x9d\x26\x86\xcc\xce"
+  "\x8a\x21\x52\xf3\x73\xd0\x57\x3e\x06\x7d\x65\xb0\x4f\x3d\xbf\xa8"
+  "\xbd\xea\xc3\xf5\xc4\x0c\x7d\x65\x1c\x07\x83\xfa\xfa\xb1\xbf\x40"
+  "\x5f\xb9\x1d\x6c\x5f\xfb\xeb\xb4\xaf\xfc\xa3\xd0\x57\x7e\xcf\xaa"
+  "\xaf\xfc\xd2\xb3\x7c\x5f\x99\x97\x7f\x81\x58\xf6\x4f\x56\x3a\xe8"
+  "\x2b\xd7\x0d\xda\x57\xc6\x3e\xf2\x36\xec\x2f\xff\xaa\x1e\xb7\x95"
+  "\xb7\x6d\xaf\x9f\x18\x62\x5f\xf9\x57\xe8\x2b\xa7\x53\xd9\xbf\xee"
+  "\xb2\xec\x13\x1d\x3e\xff\x81\xba\x81\xfa\xd2\xe7\x8b\x40\xce\x82"
+  "\x0f\xea\x05\x1f\x84\xe3\x19\x3d\x9a\xed\x7b\x81\xaf\x9c\x7e\x70"
+  "\x3e\x69\xb5\x8f\x07\xea\x06\xea\x09\xea\x06\xe7\x8b\xc0\x0e\x82"
+  "\x2f\xca\x28\x7a\x96\xcc\x2a\x7e\x96\xcc\x34\xca\xad\xfb\xc8\x0f"
+  "\x45\x20\x1e\x16\xdb\x66\xb6\xb5\x6d\xcb\xc5\xb6\xed\xbd\xfe\xbe"
+  "\x68\x30\xdb\xf6\xac\x23\x5d\xa9\x1b\x54\x57\x50\x47\x38\x7f\x04"
+  "\xfa\x72\x2e\x74\xe5\xf5\xef\x5c\xc5\x6b\xb5\xc3\xe7\x3f\x9c\xc3"
+  "\xab\x74\xe6\xe0\x78\x95\xfa\x03\x5e\xad\x16\xbc\xac\xfb\xc6\x16"
+  "\xbc\x68\xdf\xd8\x6c\xdb\x37\x5e\x2e\xee\x1b\x3b\x83\x97\x6d\xdf"
+  "\xf8\x52\xc2\xeb\x85\x92\x21\xe2\xe5\x84\x7e\x95\x82\x7e\x3d\x3c"
+  "\x4d\x84\x97\x55\x9f\x58\x84\x97\x48\xbf\x44\x7d\xe2\xe5\xe2\x3e"
+  "\xb1\x33\x78\xd9\xf6\x89\x2f\x25\xbc\xd6\x3a\x7c\xfe\xc3\x39\xbc"
+  "\xca\x9c\xd0\xaf\x32\xd0\xaf\x87\xd3\x2c\x78\x59\xf7\x85\x2d\x78"
+  "\x95\x89\xf4\x4b\x14\x3b\x2c\x17\xc7\x0e\xce\xe0\x65\xdb\x17\xbe"
+  "\x94\xf0\x5a\x47\x86\x88\x97\x13\xfa\x55\x86\xfa\xd5\x22\xc2\xcb"
+  "\xaa\x0f\x2c\xc2\x4b\xa4\x5f\xa2\x3e\xf0\x72\x71\x1f\xd8\x19\xbc"
+  "\x6c\xfb\xc0\x97\x12\x5e\x29\xd5\x43\xc3\xab\xdc\x09\xfd\x2a\x07"
+  "\xfd\x9a\xaf\xb2\xe0\x65\xdd\xf7\xb5\xe0\x55\x2e\xd2\x2f\x51\xdf"
+  "\x77\xb9\xb8\xef\xeb\x0c\x5e\xb6\x7d\xdf\x4b\x09\xaf\xb4\xf0\x81"
+  "\xfa\x52\xe2\x3e\x94\x31\xd5\x82\x17\x62\xd3\x0b\x7d\xa7\x5e\xd9"
+  "\xf6\xbd\x8e\xfb\x4f\x0f\x65\x38\xea\xef\xe2\xda\x35\x0f\x75\xe0"
+  "\xfb\x20\x34\x26\x64\x6d\x62\xc2\x06\x75\x25\xb1\xee\xf3\x7e\xd2"
+  "\xaf\x0f\xd5\x2b\x8c\x51\x2c\x71\xd4\xe7\xfd\xc8\xed\x3e\x14\xe2"
+  "\x84\xfd\x28\xe3\x2a\xc0\x89\x8f\xe3\xb7\x0d\x71\x8c\xa2\xf7\x94"
+  "\x8a\xd9\x06\x71\x7c\xf2\x12\xe8\x43\x2d\x75\x15\xa7\x74\x0f\x47"
+  "\x38\xe1\x38\x11\xf6\x79\xb1\x2f\x85\xf3\x8e\x8d\xed\x1d\x24\x2b"
+  "\x91\x28\xb8\xb9\xc7\x0e\xeb\xb9\xc7\xcd\x47\xa1\x4f\xb5\x12\x70"
+  "\xeb\x0d\x25\x39\x47\xc9\x6c\xcd\xb3\xb4\x4f\x25\xf4\xa7\x1a\x0d"
+  "\xdd\xdc\xdc\x63\x93\x51\x47\x1e\xd4\xb1\xdd\xc5\x90\x1f\xfb\x51"
+  "\xf5\xe1\xaf\x13\xd4\x95\xd4\x1f\x88\x1c\x31\x80\x3e\x18\x87\x87"
+  "\xb8\x0f\x55\x24\x9e\x6f\x5c\xe1\xa8\x0f\x35\xf8\x7c\x63\xc1\x09"
+  "\xda\x7f\xe2\xe6\x1b\x2f\x8a\x3e\xd4\x06\x87\xf3\x1f\x0b\x76\xd1"
+  "\xf1\x06\x94\x7d\x93\xca\x48\x80\x4f\x3f\x79\x75\xd2\x71\x3d\x63"
+  "\xce\xf6\x6a\xec\xd3\x62\x7f\xb6\x29\xa9\x8e\x64\xad\x21\x8a\x9e"
+  "\xae\x50\x2f\xe8\xa3\xca\x8d\x60\xeb\x5e\x3a\x46\x65\x8f\xef\x88"
+  "\xe9\x9f\x53\x73\xcf\xca\x60\x5f\x16\x75\x85\x9b\x73\x5c\x4a\x66"
+  "\x16\xb4\x91\x59\x9c\x7e\x80\x5e\x18\xb3\x77\x86\x9b\xe5\xdb\x5b"
+  "\x50\x4f\x1e\x3c\xcc\x76\x23\x06\xa8\x1f\x5f\x1e\x46\x6c\xf6\x90"
+  "\xd4\x23\x14\x1b\x0e\x17\xc6\x7a\x2e\xb8\xbf\x6e\x7c\xed\x00\x9f"
+  "\x1a\xe7\xf0\x59\x69\x8d\x4f\xa1\xbb\xf3\xc1\xc2\xf3\x91\x2b\x55"
+  "\x4c\x21\x3f\x1f\xfc\xfa\x93\xae\xe2\xf3\x62\xbf\xf7\x9f\x9d\xc3"
+  "\xa7\xd4\xdf\x3d\x7c\x4a\x83\xb9\xb9\x45\x2b\x7c\x4a\xd5\x14\x9f"
+  "\xd2\x10\xec\x2b\x59\xf0\x39\xed\x24\x3e\x36\x7d\xa4\x4b\x0a\x9f"
+  "\x8d\x0e\xc7\x7f\x06\xc1\xc7\x4d\xfd\x29\x6d\xe6\xe6\x10\xad\xf1"
+  "\xe1\xf5\xa7\xb4\x05\xfb\x46\x16\x7c\x8e\x3b\x89\x8f\x4d\x9f\xe8"
+  "\x92\xc2\x27\xd3\xe1\xf8\xf7\xc0\xf8\x94\xb9\xa9\x3f\x65\xc1\xdc"
+  "\x5c\xa1\x15\x3e\x65\xbc\xfe\x94\x85\x60\x5f\xc8\x82\xcf\x11\x27"
+  "\xf1\xb1\x1d\x3f\xbd\x94\xf0\xc9\x92\xba\x89\x8f\x9b\xfa\x53\xd6"
+  "\xcc\xcd\x09\x5a\xe3\xc3\xeb\x4f\x59\x0b\xf6\x7d\x2c\xf8\x7c\xe2"
+  "\x24\x3e\x36\x7d\x9e\x4b\x0a\x9f\x97\xca\xdd\xc3\xa7\xdc\x4d\xfd"
+  "\x29\x0f\xe6\xe6\xfe\xac\xf0\x29\xe7\xf5\xa7\x3c\x04\xfb\x3a\x16"
+  "\x7c\xd6\x39\x89\x8f\x4d\x1f\xe7\x92\xc2\x27\x7b\xee\x60\xf3\x45"
+  "\x42\xec\x2c\x9e\x97\xed\x85\xf8\x0d\xe3\x67\x8c\x9d\x1b\x0d\x35"
+  "\xc4\xb8\x92\x62\x93\x75\x86\x28\x34\x3c\x36\xdc\x9c\xec\x73\x74"
+  "\x4e\x96\x8b\xdb\x36\x06\x26\xb0\xeb\xa5\x3e\x18\x97\x71\xf3\xae"
+  "\xdc\xdc\xc4\xe7\x78\xae\xa3\x57\x14\xbf\x61\x1f\x15\x62\x6f\x82"
+  "\xfd\xd4\xd4\x1f\x5d\x88\xdb\x96\x3a\xc2\x65\xf0\xb9\x89\x02\xd1"
+  "\x73\x7c\x42\xdf\x73\x58\x71\x71\x79\xde\x35\xc7\xe1\xfe\x4f\x03"
+  "\xe3\x52\xe6\xef\x1a\x2e\xe0\x6f\x36\x3e\x98\x4c\x71\x39\x62\x83"
+  "\x4b\x99\xba\x57\xe4\x77\x9c\xc7\xc5\xc6\xdf\x5c\x52\xb8\xe4\x26"
+  "\x38\xec\x6b\x82\x5d\x42\x4c\xf0\xf9\xee\xcd\x4b\x89\x5f\x56\x1b"
+  "\x99\xdd\xfb\x8b\xcf\x98\x85\x60\xe7\x7a\x9f\xf3\xf1\x68\x04\x1b"
+  "\x97\x62\x60\x7f\xf2\x34\x8c\x0a\xfc\xa2\x45\x4f\x1a\xc3\x75\xa4"
+  "\x67\x75\x28\xc9\x3e\x86\xcf\xaa\xd7\x90\x4d\xf1\xd8\x97\x7f\x87"
+  "\x7c\x79\xf8\x24\x59\x58\xc1\xf6\x36\x75\xd6\x10\xed\x9a\x77\x08"
+  "\xfb\x9c\x6a\x4c\x31\xe4\x79\x1a\x64\x78\x82\x79\x79\xda\x59\xe8"
+  "\x8f\xce\x48\x22\x8a\xf9\x9d\x6c\x77\x63\xe7\x17\x64\x1b\xdc\xeb"
+  "\xf3\x24\x42\x50\xbe\x88\x49\xf6\xb3\xd8\xff\xfc\x84\x62\xf2\x08"
+  "\xc5\xe4\x75\x51\xff\x53\x09\xe7\x8f\xc6\x02\x1e\xbf\xd9\xe0\x71"
+  "\xb8\x83\x80\x7c\x47\x2d\x34\x00\x1e\x06\x01\x8f\xe3\x24\x25\x0e"
+  "\xf1\xd0\xf5\x3d\xef\xda\xc3\xe3\x51\x80\xf6\x2b\x96\x28\xb6\x0a"
+  "\xfd\xcf\x13\x22\x3c\x84\x77\xb2\xc4\x78\x08\x7d\xff\xd5\x80\x47"
+  "\xa2\xa5\xff\x79\x16\xfa\x9f\x5b\xa1\xff\x99\xfa\x15\x61\xb6\xa6"
+  "\xb8\x8a\xc7\x2b\x0e\xfd\xbf\x80\x05\xfa\x96\x5e\xcf\xed\xd5\x88"
+  "\x43\x53\x52\x35\x41\x4c\xd0\x9f\x98\x7e\xf1\xf1\x48\x4e\x00\xdd"
+  "\xd1\x8d\x0a\xec\x61\xa1\xcf\x0f\xfd\xfd\xa6\xb0\x6f\x09\x8e\x19"
+  "\x50\x0c\x7a\x7b\x9b\xf4\x35\x04\x65\xaf\x5d\xf3\x2d\x87\xc3\x09"
+  "\xe6\x95\xaa\xa7\x0c\x84\xb9\x11\x78\x08\xfd\x7d\xc5\xd3\xf8\x5e"
+  "\x2e\xd8\xb6\x6d\x2b\xc8\xac\xf9\xb1\x6c\x37\xf6\x4d\x51\x87\xf0"
+  "\xd9\x13\xb4\x6b\x8d\xb1\x9f\x11\x1c\xd7\xe9\x95\xef\x0c\xff\x1c"
+  "\x98\x83\xf6\x0d\xe5\x3e\xf2\x79\x0b\x4e\xf8\x3c\x09\x87\xd5\x63"
+  "\x4e\x3c\xe7\x2a\xc6\x2b\x4c\xe7\xd4\xf3\xc9\x3d\xfc\x78\x41\x81"
+  "\x30\xa6\xe6\xee\x78\x81\x30\xa6\xf6\x2b\x7d\x9e\x24\xf5\x1b\xd0"
+  "\x1f\x97\xf1\x7a\x75\xaf\x73\x78\x95\xfa\xbb\x8e\x57\x97\x1d\xbc"
+  "\xf2\xc2\xfa\xe3\x55\x1a\x2c\xc2\xab\xde\x82\x57\xa9\x9a\xe2\x55"
+  "\x1a\x62\xc1\xab\x34\x74\x70\xbc\x06\x78\xbe\xf5\x77\x8f\xd7\x6b"
+  "\x0e\xfb\x3f\x36\x78\xb9\xa1\x5f\xbf\xda\xc1\x6b\x8b\xcc\x0e\x5e"
+  "\x22\xfd\x7a\xd0\x4f\x84\x17\xaf\x5f\xa5\x22\xfd\x2a\x75\x42\xbf"
+  "\x06\x78\xae\xf5\x77\x8f\xd7\x3f\x1c\x3e\xff\x63\x8d\x57\x99\x1b"
+  "\xfa\xf5\xbd\x1d\xbc\xfe\x51\xdb\x1f\xaf\x32\x91\x7e\x41\x6c\xd1"
+  "\x87\x57\x19\xaf\x5f\x65\x22\xfd\x2a\x73\x42\xbf\x06\x78\x9e\xf5"
+  "\x77\x8f\x57\xfe\x80\xcf\xff\x88\xf0\x72\x43\xbf\x3e\xb5\x83\xd7"
+  "\xd6\x28\x3b\x78\x89\xf5\xab\x45\x84\x17\xaf\x5f\x65\x22\xfd\x2a"
+  "\x73\x42\xbf\x06\x78\x8e\xf5\x77\x8f\xd7\xeb\x0e\xe3\x3f\x6b\xbc"
+  "\xca\xdd\xd0\xaf\x54\x3b\x78\x6d\xf3\xed\x8f\x57\xb9\x48\xbf\x1e"
+  "\x9a\x66\xc1\xab\x9c\xd7\xaf\x72\x91\x7e\x95\x3b\xa1\x5f\x03\x3c"
+  "\xbf\xfa\xbb\xc7\xab\xc0\xe1\xf8\xb7\x18\xaf\x9e\x1c\x21\x3e\xac"
+  "\xb0\xc6\x0b\xe2\x75\xaf\x76\xda\xb7\x12\xf0\x72\x1c\x1b\x16\xd4"
+  "\xf5\x61\xf5\xa3\x25\x36\xe4\x70\xe2\xe7\x29\x10\x1f\x8c\x11\x31"
+  "\x26\xec\xc9\xa6\x18\xe1\x1c\xe0\x80\x71\xa1\x33\xef\x3f\xb9\x81"
+  "\x93\xd0\xaf\x1a\x76\x9c\x0e\xb9\x83\x53\xa1\xc3\xf7\x9f\xac\x71"
+  "\x12\xfc\x96\xb3\x38\xd9\xf3\x59\x45\xb1\xfd\x71\x2a\x0b\xb6\xe0"
+  "\x44\xfd\x14\xfa\x2e\xf4\x55\xd6\x38\x0d\xe0\xaf\x9c\x79\xff\xe2"
+  "\x77\x8f\x53\xb1\x43\xfb\x97\xcb\x98\xab\xe1\xa8\x81\x43\x0b\x47"
+  "\x9d\x89\x21\xf3\x0a\x19\x33\xf7\xfe\x2b\xae\xf3\x57\x98\xde\xef"
+  "\xfc\x15\xec\x15\x2a\x6f\xcc\x03\xb2\xe5\xe2\x16\xa1\x0c\x36\x8b"
+  "\xa0\xec\xb4\x72\x49\x38\x29\xa4\x79\x47\x09\x65\xc9\xd7\x93\x00"
+  "\xa1\x2c\x68\x53\x1a\xc8\x5a\xeb\xb5\x3e\xe0\x0a\xc8\x5f\xc7\x66"
+  "\x45\x74\x42\x5e\x0f\xae\xcc\xf5\x52\x5f\x6e\x8d\x12\x3e\xaf\x29"
+  "\x5d\x82\xef\x87\x6b\xbd\x24\x90\x97\x96\x39\x9a\xcf\xa7\x34\xa7"
+  "\x13\x25\x57\x4f\x86\xc1\xfb\xd9\xd6\x73\x0c\x9f\xcf\x4f\x5c\x47"
+  "\xf9\xfa\x00\xae\x3c\x3e\xcf\x95\xec\x15\x92\x34\xbe\x2d\x2a\x71"
+  "\x3e\xd3\x1c\x82\x65\x0a\xf9\x64\x7c\x59\xd3\xac\xf2\x94\x12\x82"
+  "\xfb\xd1\x72\xf5\x4b\x62\x08\x5f\x3f\x39\xe6\x35\x8d\x59\xa6\x35"
+  "\x49\xa4\xfe\x66\x86\xf8\x5b\x5d\xb3\x91\x70\xf9\xf9\xbc\x9e\x5c"
+  "\xde\x2b\x16\x24\x41\xde\x99\xbc\xcc\xa5\x62\x99\xf3\xf9\xbc\x04"
+  "\x39\x8a\xcf\x99\xd2\x19\x2c\x0b\xcf\x2b\xd8\x2b\xe6\x27\x43\x1b"
+  "\x66\x0b\xf9\x84\xfb\x35\xa9\x09\xe1\xf2\x32\xe4\x26\x1e\x93\xb1"
+  "\xd0\x8e\x00\x21\x1f\xae\xa7\x20\xe4\x4d\x35\x91\x6b\x8a\x2d\xb2"
+  "\x19\x67\xca\x5a\x9e\x66\x5a\x2f\x9d\x6b\x5b\xa6\xd7\x7a\x89\x0e"
+  "\xf3\x35\x74\x70\x65\x03\x7e\xcb\x67\x42\xfe\xab\x78\x19\x05\x52"
+  "\x4c\x14\x7d\x98\x98\x18\x23\x9e\xd3\x16\xd1\xba\x7a\xf3\xf9\xe6"
+  "\xf7\xcf\x27\x15\xe7\xbb\x9a\xca\x31\xae\x0a\x64\x13\xdc\x3f\xaf"
+  "\x87\x38\xef\x78\x9a\xf7\x99\x30\xc8\x1b\xd2\x3f\xaf\x42\x9c\xf7"
+  "\x0f\x34\x6f\xa4\x37\xe4\x0d\xb5\x53\xd7\x71\xa2\xbc\x3e\x34\xef"
+  "\xb3\xf5\x90\x37\xac\x7f\x5e\xa5\x38\xef\x35\x34\xef\x2a\xac\x43"
+  "\x78\xff\xbc\x01\xe2\xbc\x13\x68\xde\xa8\x0c\xc8\x1b\xd1\x3f\x6f"
+  "\x9a\x38\xef\x1f\x69\xde\x98\xd9\x90\x57\x6d\x9b\xb7\x98\x62\x7b"
+  "\x1d\x8f\xad\x2f\xcd\xbb\xd2\x00\x79\xa3\xec\xb4\x6d\x04\x57\x2e"
+  "\xcd\x3b\x91\xe6\x5d\xde\x0a\x79\x63\xed\x60\x21\xce\x3b\x89\xe6"
+  "\x4d\xab\x80\xbc\x09\x76\xb0\x10\xe7\xbd\x96\xe6\x4d\xcc\x84\xbc"
+  "\x49\x76\xb0\xb0\xe4\x1d\x93\x34\x0b\xf2\x24\x43\x3b\x9b\xed\xc8"
+  "\x56\x5c\xe6\x64\x5a\xe6\x0b\x1d\x90\x3f\xcd\x8e\x6c\xc5\x79\xaf"
+  "\xa3\x79\xd7\xe6\x43\xde\x0c\x3b\xb2\x15\xe7\xfd\x13\xcd\xbb\x2e"
+  "\x10\xf2\x66\xf6\xcf\x0b\xfa\x46\xe5\x7b\x33\x2f\x5f\x3f\x9a\x3f"
+  "\xa5\x1b\xf2\x6b\xec\xc8\x17\xcb\x13\x74\x76\x0a\xcd\xfb\xbc\x0c"
+  "\xf2\xe6\xda\x91\xaf\x38\xef\x9f\x69\xde\x6c\x0d\xe4\xcd\xb3\x23"
+  "\x5f\x71\xde\xbf\xd0\xbc\x1b\x90\x93\xf9\x76\xe4\x2b\xce\xab\xa2"
+  "\x79\x5f\x8c\x82\xbc\x05\x76\xea\x7b\x9d\x28\xef\x54\x9a\xf7\xbf"
+  "\xb0\xbe\x25\x76\xf0\x10\xe7\xbd\x9e\xe6\xdd\xec\x07\x79\xcb\xed"
+  "\xe0\x21\xce\x7b\x03\xcd\x9b\x89\x7a\x5c\x61\x07\x8f\xbe\xbc\xe0"
+  "\x17\xa6\x99\xc6\x64\xcd\x2f\xc6\xfc\x12\x29\x5d\x1f\x83\xe1\xd6"
+  "\xf7\xe7\xf2\x02\x4f\xb4\xbc\xbd\x9b\x4e\xcb\x7c\xa9\x13\xf2\x71"
+  "\xcf\xe7\x61\x9e\x86\x6e\xce\x1e\x81\x7f\x31\xfe\xb5\xd8\x62\xbb"
+  "\x6f\xa4\x79\xd3\x83\x21\xef\x5e\xb1\x0d\x65\x19\xa9\x38\xdf\x0c"
+  "\x9a\xaf\x00\x65\x55\x63\x9d\xcf\xc3\x92\x6f\xcc\x2b\xf3\xe1\x7c"
+  "\x6d\x91\x8d\x3d\x86\x7a\x8a\xcb\xba\x89\x96\xf5\xaa\x11\xf2\x6a"
+  "\xad\xf3\x19\x6f\x16\xe5\xbb\x99\xe6\x7b\x0d\x65\x73\xc0\x3a\x9f"
+  "\x52\x9c\xef\xaf\x34\x5f\x11\xda\xac\x3a\xeb\x7c\x01\xe2\x7c\x33"
+  "\x4d\x59\xff\x08\xe3\xf2\xae\x97\xd6\xdb\xca\x0f\x64\x7d\xb3\xc8"
+  "\xa7\xdd\x62\xca\xda\x2a\xe3\xf3\x36\x0b\x32\xe4\xe4\x4c\x39\xcf"
+  "\xf0\x9c\xbf\xd5\x94\xf5\x7a\x2d\x9f\xaf\x45\xec\x07\x44\xbe\xf6"
+  "\x36\x76\x4c\x6e\x2d\xef\x47\x5b\xb9\xfb\xae\x97\x1e\xb6\x17\x6f"
+  "\xc4\x5e\x4f\xae\x3c\xc6\x54\x24\x50\xdf\x23\xac\xa9\xbf\x8b\xb3"
+  "\x97\xe6\x82\xa8\xdc\x20\x03\x6b\x14\xa7\x6d\x66\xd8\xe6\x19\x06"
+  "\x22\xc5\xf5\x93\x58\x79\x65\x8d\x0e\xd2\xf5\x13\xa3\xaa\xbb\xb2"
+  "\x2a\xd2\x74\x92\x07\xc2\x70\x2d\x0f\xf8\xae\xd1\x91\xec\x56\xfc"
+  "\xbe\x39\x1d\xe2\x41\x26\x40\x82\x6b\x30\x17\xc3\xf7\x1c\x38\xb8"
+  "\x75\x8f\x63\x09\xc3\x6e\x24\x01\xda\x44\x23\x39\x9a\x44\x18\x73"
+  "\x4e\x5c\xb0\x32\x1e\xd7\x13\xa9\x38\xc4\xae\x56\xcf\x86\xba\xc4"
+  "\xc2\x7d\x23\xda\xe0\x37\x57\x17\x68\x3f\xf8\xc6\x28\x6d\x3c\xae"
+  "\x31\xb4\x4b\xae\x97\xef\x8e\x65\x37\x2c\xfa\x39\x36\x85\x5c\x7b"
+  "\x8c\xd9\x25\x3b\x05\xb6\xe1\xd4\x6a\xf5\xdd\x58\x86\x59\x1e\x17"
+  "\x05\x79\xe6\xe3\x5a\x24\x6c\x7e\x55\x30\x5d\xa7\x64\xd7\x12\xae"
+  "\xfe\xe9\x6c\x33\xeb\x1b\x95\x66\xee\xc9\x48\xc3\xfd\x1b\xb4\x29"
+  "\xc7\x48\x9b\xe8\x9c\xfe\x9a\x2a\x6e\x0d\x13\x6c\x17\xb4\x31\xad"
+  "\x2b\x6b\x57\xa8\x4e\xf2\x17\x7e\x8d\x98\x5d\x0e\xf7\x07\x85\xd8"
+  "\xda\x8b\xcd\x8e\xcb\x84\xfc\x99\x10\xdf\xed\xa5\x72\xd8\x95\xa7"
+  "\x93\x4c\x2a\xe7\xbf\x97\xe8\x24\x93\x75\xfc\xf7\x2a\x9d\xe4\xae"
+  "\x5a\xfe\x7b\x8d\xb0\xf6\x8a\xfd\xb5\x60\xe2\xc2\xa0\xdd\x09\xe6"
+  "\x6d\xa1\x1e\x18\x8f\xe2\xba\x6c\xac\x3c\x2e\x4c\x39\x09\xf7\xeb"
+  "\xa8\x0c\x86\x7b\x26\xd0\xf5\x34\x2b\xaf\x86\x4f\x2f\xfe\x53\xcf"
+  "\x7f\xb2\x98\x87\xc3\xd6\x37\x9a\xb0\x9a\x1d\x81\xd8\xe6\x14\x13"
+  "\x6b\x86\x72\xf3\xd9\xcc\x1f\x3a\x9a\x92\x3a\x08\x5d\x87\xba\xf2"
+  "\x5e\xc2\xad\x8b\x03\x72\x05\xd9\xb3\xa3\x7f\xe8\xe0\xee\x95\xbd"
+  "\x3b\x56\x5c\x2f\x7c\x58\xda\xff\xa6\x9b\xff\x3a\xf3\x96\x5b\x6f"
+  "\x9b\x75\xfb\x92\xa5\xcb\x22\x96\xaf\x78\x46\x1d\xf9\xec\x73\x51"
+  "\xd1\x31\x2b\x63\xe3\xe2\x57\x25\x3c\x9f\xb8\x3a\xe9\x85\x35\x98"
+  "\xaf\xaf\x0d\xdb\xe6\x4a\x0c\x0c\x81\xfb\xcc\xc1\xfb\x70\xfb\xde"
+  "\x61\x1a\xc5\xa5\xb2\x5c\xaa\xb4\x2f\xd3\x26\x1f\x42\x70\x5d\xe6"
+  "\x4e\x66\xb7\x04\xd7\x88\x06\x0e\x48\x9a\x0a\x1e\xd0\xe2\x1e\x03"
+  "\xed\x4c\xa5\xa1\x51\xff\x80\x16\xf7\xb8\xd8\xef\xd3\x41\xfc\xae"
+  "\xc3\x7d\x08\x2a\x75\x78\xbe\xf8\xcf\x84\x1c\x80\x6b\xed\x95\x79"
+  "\x9d\x82\xf8\xbc\x3a\x9e\xd5\xe7\x8d\x67\x3b\xb1\xfc\xbc\x2d\x6c"
+  "\x87\x7e\xad\x9a\xe4\xc0\x6f\xe0\x8e\xe2\x28\xb3\xfb\xbd\xfd\x10"
+  "\xf1\x42\x2c\xeb\x5b\xb4\x85\x6d\xcf\x18\xcf\xb6\x6f\xd8\xc2\x76"
+  "\x16\x8f\x67\x75\x7e\x79\x44\xd6\x95\xb5\x5b\xad\x63\x2a\xb5\x1c"
+  "\xb7\xe1\xbc\x79\x4c\x65\xf8\x66\x38\x37\xc3\x48\x46\x14\xc3\x6f"
+  "\x48\x33\xec\x57\xd2\x7a\xbf\x75\xb2\x7b\x24\x94\x37\x9f\xed\x8d"
+  "\x92\xe4\xc0\x7d\x28\x4e\xbb\x0f\x1d\x00\x2f\x0c\xf7\xd3\x37\x75"
+  "\xb7\x01\xcf\x76\xb7\xe2\xda\xeb\x70\x3f\xaf\xa6\xfc\x4e\x82\xe5"
+  "\xbd\x19\xdf\x3d\x72\xd5\x04\xd6\x08\x79\x6b\xcc\x6b\xa3\x24\x90"
+  "\x27\x0f\xca\x36\x88\xdb\xa3\x5a\x11\x9d\xa0\x8c\x79\x3e\x2a\x6a"
+  "\xea\x18\xa2\xe2\x3e\xad\xf6\xc7\x48\x80\xf2\xc8\xab\x5b\xd8\x03"
+  "\xd0\x4e\x2d\xb4\xb7\xae\x01\xa2\x6e\xe0\x0c\x81\x36\xe5\x1e\x65"
+  "\xaa\xa6\x43\x7a\x2d\x7c\xaf\x85\xba\xd7\xd1\x3d\x15\x3e\x79\x82"
+  "\xcd\xda\xdd\x0e\xf5\x44\xbb\x8f\x6b\xa6\x91\x53\xab\x43\x24\xd0"
+  "\xee\x3c\xc8\x57\xa7\x9c\x40\xa6\xc0\x75\xef\x41\x3d\xca\xe1\x3b"
+  "\xe6\xe7\x74\x06\xf2\x1f\xa0\xed\xfa\xe4\x41\xfc\x0d\xb2\xd2\x16"
+  "\x8e\x67\x35\x5d\x59\x55\xb9\xb8\x9e\x1d\xb7\xce\x37\xfc\x06\xb9"
+  "\xd4\x41\xde\xdc\x53\xa9\x21\x12\xe8\x7f\x49\x8a\x2d\x65\x86\x63"
+  "\x9d\xb0\x1e\xd8\x07\xfc\x12\xa2\x2f\x73\x6f\x28\x99\xde\x4d\x24"
+  "\x5f\xb6\x13\x52\xb0\x85\x2d\x81\xa3\x00\x8e\xfc\x2f\xe0\xdc\x41"
+  "\x38\xea\x20\xbd\x1e\x3e\xbf\x80\xcf\x83\xed\xdc\x9c\x9d\x0f\xd6"
+  "\x7b\x55\x32\xdb\x31\x23\x9f\xfc\x09\xcb\x07\x6e\x3d\xde\xc6\xd4"
+  "\x56\x63\xdd\x71\xed\x48\x76\xcc\x1e\x3f\xeb\x35\xf6\xde\xcc\x27"
+  "\x70\x1e\x3e\xab\xe8\xa7\xf8\x78\x13\x7a\xb6\x6f\x79\xd3\xef\x6f"
+  "\x85\xc1\xef\x0c\xfe\x3b\x58\xad\xb7\x92\x07\x3f\x6c\xcb\x73\x74"
+  "\xbc\xd5\xe1\x7c\x5e\x67\x8e\x4f\xfc\x9c\xcb\xf7\x76\x09\x61\xde"
+  "\xed\x26\xcc\x5e\x7f\xeb\xf4\xbd\x1e\x34\xad\xa6\x85\xfe\xae\xd1"
+  "\xd1\xcf\x0f\x65\x70\x80\x9c\x3e\x82\xf2\x3f\x0a\xa4\x69\x1f\x85"
+  "\xc0\x67\x01\x1c\x15\xd6\xf7\xff\x04\xae\xff\x64\x36\xe2\xd9\x9b"
+  "\x0e\x76\x1b\xb0\xd4\x31\x55\x06\xc4\x68\x33\xe5\x96\xc4\xcc\x72"
+  "\x69\x7a\xe0\x56\x81\x85\x3f\x6f\xfe\x68\xcd\x9f\x37\x9b\x6d\xf8"
+  "\x93\x8b\xf6\x08\xae\x9b\x5d\x4c\xf9\x52\x7b\x6a\x6d\x04\xfc\x7e"
+  "\xb3\x05\xca\xa9\x55\x3e\x85\x65\xbc\xc5\xf5\x75\x36\x1f\x23\x44"
+  "\xae\x26\x52\xb4\x2f\x9d\xcc\x5b\x53\x90\xb3\x78\x6f\xfe\xbe\xb4"
+  "\x2e\x50\x3f\x48\x2b\xc1\xfa\xad\x84\x72\xe1\x77\x39\xe4\x2b\x69"
+  "\x22\x27\x85\xba\x71\xd7\x64\x3d\x0b\x7c\xe4\xeb\x8b\x65\xe2\x75"
+  "\xac\xa5\x5d\x7a\xbc\x86\xbf\xf7\x21\x48\xc7\xfe\x25\x49\xfd\x8d"
+  "\x8c\xc0\xe7\x9b\x91\x93\xf8\xd9\x64\xf4\x07\x5d\x0a\x24\xe6\xae"
+  "\x50\x32\xc3\x87\xf8\x83\xbe\x8d\x6e\x63\xde\xaa\xbd\x31\x99\xf8"
+  "\x63\x79\x68\xd7\x75\xcc\x5b\x69\xc5\xa8\x8b\xb4\xac\xaf\x08\xb7"
+  "\x4e\x56\x95\xfe\x8b\x58\xc2\xdd\xa7\x08\xeb\x03\xe7\x45\xf7\xcd"
+  "\xc3\xbe\xe4\xe6\x35\xb4\xad\x70\xaf\x72\xb8\xbe\x1a\xdb\x8e\xf2"
+  "\x84\xf3\x35\x47\x99\x6a\x1f\x3c\xc7\xad\xbf\x4d\xdb\x53\x8e\x6b"
+  "\xb4\xa2\x3c\x30\x3f\xee\xd9\x42\xd7\xec\xab\xe2\xd6\x44\x83\xf2"
+  "\xab\x11\x0f\x16\xee\x81\x65\xa4\x1a\x59\x23\x0b\xf6\xa8\x6c\x4d"
+  "\x37\xf8\xff\xb7\x5f\xb6\xc6\xa7\x3a\x56\x8c\x0f\x5c\x57\x0d\xd7"
+  "\x1f\x60\xa1\x8d\x68\x4f\xe0\x9e\x5e\xe8\xf3\x21\x2d\xd7\x9c\x05"
+  "\x65\x24\x76\x73\xe3\x29\x50\xce\x7a\xa8\x4b\x2e\x96\x03\xf5\x39"
+  "\xc0\x97\x55\xbb\x2f\xd9\x1a\x6b\xbe\xbc\x72\xc4\x9c\xd3\xe7\x35"
+  "\x5c\x9b\xc0\x76\xbd\xfd\x48\x11\x3d\x57\x03\x79\x6a\xd8\xde\x40"
+  "\x82\x6b\x9e\x52\x5f\xc2\x9d\xdb\x9b\x7a\x96\xc3\xf7\x00\xb5\x6b"
+  "\x6f\xc7\xad\x5a\xc7\x76\x58\xea\xfd\xb6\x4a\x58\x37\x96\xaf\xf7"
+  "\x5e\xbc\x1f\xbb\x3a\x8c\xf3\xad\x78\x0f\xbc\x9e\x2f\x4f\x8a\xe5"
+  "\x09\xb2\xba\x11\xea\x41\xe5\x55\x3d\x0b\xd2\xcb\x91\x8b\x9c\xdc"
+  "\xc0\x8e\x9e\x4a\x45\x2e\xbe\x3d\x0d\xae\xaf\xcd\xc1\xdf\xab\xf1"
+  "\x77\xb5\x96\xb3\xb1\x7d\xe7\xab\x13\xf0\x7c\x13\xf4\xd3\x37\x3f"
+  "\x07\x5c\x32\x13\xf2\x27\x6f\xe2\x6f\x48\xe7\xda\x56\x65\x58\x3b"
+  "\x57\xb2\xdf\x48\x08\xd6\x13\x64\x54\x03\x75\x6d\x01\xdb\xef\x8d"
+  "\x75\x05\x7b\xbd\x97\x2d\x0b\x25\x58\x67\xb0\x67\x7c\xfd\xde\x99"
+  "\xc7\x63\xbf\x17\xdb\x88\xf2\xbc\x91\xda\x3e\x38\xf7\xee\xcf\x58"
+  "\x77\x4b\xbb\xdf\x51\x8a\x65\xcc\xb5\x1b\x70\x40\xbc\x10\x17\x4b"
+  "\x99\x6f\x23\xf7\x73\xa1\xac\x2a\xfa\x9b\x72\x03\x65\x9d\x3b\x9e"
+  "\xad\xc7\xfc\x96\xbc\xef\x3e\x81\xe7\x52\xe0\xde\x33\x62\x09\xee"
+  "\x81\x21\xc1\xb5\x7f\xa1\xdc\x2a\xdc\x8f\x07\xca\xa8\x41\x99\x42"
+  "\xbe\x3d\xc8\x47\xf8\x5d\xcf\xd7\xbb\x0a\xfc\xf9\x34\x38\x66\x5b"
+  "\xf4\xff\xdd\x42\x6b\x7e\xbd\x63\xab\xff\x88\x77\xae\x39\x35\x90"
+  "\x70\x7c\x88\x27\xca\x13\xcc\xbb\xb7\xf3\xbe\x83\xc7\xfa\xdd\xec"
+  "\xfd\xa0\x2f\x96\x32\xde\xf5\xb6\xc1\xba\x86\xe3\xe3\xea\xf9\xb8"
+  "\x9f\xb1\x04\xae\xad\xa1\xe5\xbc\xc3\xb5\x99\xe3\x53\x3a\xc7\x81"
+  "\x7a\x76\x35\xb4\xb3\x8f\x07\xef\xc4\xf2\x38\xd7\xdb\xc8\x44\xb0"
+  "\x5d\xb5\xb8\x47\x03\xda\xa4\xae\x74\x72\x77\x57\xaf\xc5\x2e\x21"
+  "\xf6\x66\x0e\xfb\x77\x7d\x8a\xa9\xbf\xe5\xed\xd6\x3b\xf4\xfc\x78"
+  "\x2b\x0e\x63\x9b\x16\x70\xfc\xc5\xba\xa4\x86\x61\x5d\x6a\xb8\x7a"
+  "\xa4\x2a\x09\x9c\x3b\x80\xf7\x87\xb2\x82\x79\x7d\x15\xca\xf2\xc3"
+  "\xb2\x36\x80\xad\xc2\x3a\xc1\xbd\xab\x39\xfb\x77\x3f\xd6\x6d\xef"
+  "\x14\xbe\xee\x75\xdd\xe9\x78\xed\x5b\x3e\x67\x19\xee\xda\x3a\xc8"
+  "\xa7\xe9\xa6\xeb\x38\x8f\x81\xeb\x2b\x94\x4b\x31\x7f\x4d\x06\xda"
+  "\x68\xe5\x93\xdc\xf7\x68\xe5\xdf\x81\xab\xc7\x88\x14\xca\xf3\x40"
+  "\x8e\x0a\xbc\xe8\x64\x6a\x16\x43\x8c\x81\x78\x55\x41\x8c\x54\x81"
+  "\xf2\x46\x2e\x43\x8c\x34\xb3\x2b\x6b\xaf\x46\xe0\x2d\xdc\xa7\x00"
+  "\x65\x4f\xf1\xd9\xfb\x15\xf0\xb8\xc6\xc2\xad\xbd\x5f\xf1\x72\xac"
+  "\x00\x39\x7a\xc0\xfd\x1e\xe1\xdb\x55\x01\xf9\x21\x16\xab\xb9\x97"
+  "\xaf\x7b\x3e\x9f\xff\xb8\x80\x03\xaf\xab\xf5\x39\x68\x7f\x39\x0c"
+  "\xde\xcb\xe0\xaf\x2d\xa7\xf7\x7a\xef\x45\x21\x2f\xc6\x88\x74\x7d"
+  "\xf6\xf7\x5e\x44\x3b\x38\x03\xb0\xe7\x6c\x1f\xb7\x57\x15\x4d\x43"
+  "\xdd\xa1\xf7\xa8\x99\xce\xf1\x10\xe2\x1e\x0b\x8f\xde\x0b\xb3\xb1"
+  "\x4f\x68\x8b\x73\x1b\xa1\x0c\xb4\xa7\xc8\x25\xb4\xa9\xd8\x97\x80"
+  "\xf2\x66\xf2\xfa\xc3\xd7\xf9\xbd\x83\xd6\x5c\xa9\xb9\x06\xb8\x32"
+  "\x5d\x54\x76\x8d\x3d\x3f\x57\x4c\x6d\x60\x01\xbd\xe6\xfd\xd1\x7c"
+  "\xdb\xaa\x68\xdb\xf8\xdf\x28\xb7\x14\x94\xdb\x07\x0d\x22\x39\x82"
+  "\xdc\x3e\xb8\x9d\xcf\x5f\x83\xb6\xdc\xa2\xaf\xef\x3f\x2f\xe8\x72"
+  "\x7f\x7b\xf1\xc1\x54\xd4\x07\x4b\xbd\xde\x0f\xb6\xb1\x17\x35\xf6"
+  "\xed\xc5\xfb\x4a\xbe\xbd\x25\x36\xba\x51\x4e\xeb\xce\xfb\x16\xc0"
+  "\xa1\xd1\xd0\xc3\xaf\x45\x5e\x75\x17\xda\x4f\xbc\xb7\xd8\x07\x15"
+  "\x51\xb9\xf2\xba\xfc\xc1\xd5\xfd\x71\x78\xbf\x5d\xac\xcf\x88\x35"
+  "\xda\x04\x2c\x03\x31\xe5\xe2\x4a\x48\xa3\xb8\xbe\x8f\xf1\x6d\xae"
+  "\xd8\x46\x43\xde\x3c\x33\x8b\xfa\xf2\x7e\x87\xb5\x2e\xbe\x1f\xc2"
+  "\xeb\xa2\x70\xef\x0f\x01\x23\x7f\xcb\x7d\x3f\x08\xb3\xb9\x2f\x62"
+  "\x73\x00\xe5\x40\xdb\xf8\xc1\x0e\xc1\xa7\x61\x7e\xb8\x36\x09\xae"
+  "\xc9\xb5\xf1\x8f\xb9\x58\x3f\xb8\x97\x07\x67\xb3\xb6\x70\xb6\x22"
+  "\xa9\x8b\xab\xcf\x07\x79\xc5\xbc\x9f\x80\x34\x7f\x3e\x2d\x9c\xf7"
+  "\x25\x02\x6f\x46\xda\xd4\x49\x6f\x3f\x3e\x7a\xdf\x43\x88\x8f\xb8"
+  "\xb2\x38\x5b\xf4\x81\x81\x6f\x1f\xa6\x4d\xa7\x69\xef\xd5\x62\x5a"
+  "\x0e\x95\x43\x1e\xcb\xf9\xab\xf7\xc2\x79\x7f\x85\xfa\xc5\xe8\x98"
+  "\xbd\xcd\xa8\x63\xf8\x5b\xc7\xd4\x04\x62\xf9\x4d\x69\x3d\xd8\x87"
+  "\xc8\x87\x73\x51\x68\x0f\xd0\x5e\x28\x57\x50\xbb\xa1\x5c\xc8\x7d"
+  "\xbe\x86\x76\x07\xe3\x10\x3c\x0f\xf9\xc2\xd0\x16\x41\xfa\x2e\xdc"
+  "\xd7\x88\xfd\xc5\x03\xca\xad\xd1\xf0\xd7\x7e\xc2\xc5\x0a\xbf\x04"
+  "\x8e\x10\xd2\x84\xeb\x40\xd7\xa3\xf1\x3a\xbc\x5e\xb0\x5f\x68\xbb"
+  "\x8c\x68\x9b\xb8\xfb\x7d\x28\xe1\x39\xce\xf5\x1b\x84\xb8\xa8\x97"
+  "\x11\xe5\xc5\xf5\xa0\x39\x9b\xf6\xe1\x7c\x6a\xcf\x3e\xbc\x0b\xaf"
+  "\xe5\xf0\x03\x5b\x99\x72\x96\xfd\xa1\x38\x9e\x48\x8b\x4e\x72\x31"
+  "\xd6\x6c\x5a\xcf\x0f\xf3\x69\x3b\x3e\x5c\xc2\xb5\x83\xda\xd4\x5c"
+  "\x5a\x97\xaa\xd9\x45\x3d\xdc\xb9\x75\xd8\x16\x3c\xb7\x59\x74\x8e"
+  "\xed\x55\xe1\xb9\xad\x5c\xbd\x6c\xae\x33\xf7\xaa\xfb\xe5\xc7\x7d"
+  "\xba\xc0\x86\x22\x1f\x78\xdb\xfb\x91\x0f\x5f\xcf\x6f\x04\xbb\x0b"
+  "\x72\x89\x40\xdb\xcb\x9d\x5b\xc1\xe7\x59\xc8\x7f\x72\xf6\xfd\xa3"
+  "\x91\x54\xae\x3e\x0c\x2f\xef\x28\xda\x8e\x8f\xb8\xbd\xbf\xd9\x5f"
+  "\x42\x41\xb6\x1f\x1a\x05\xd9\x8a\xbf\xa3\xfe\xc0\xfd\x15\xf8\x9b"
+  "\xe3\x7d\x32\xd7\x87\x2d\xc0\x3c\x58\x27\xea\x23\x6a\x0c\xb6\x31"
+  "\xf5\x51\xa6\xf6\x65\xf4\x4b\x34\x56\xad\x8d\xe3\xc7\x67\x88\x36"
+  "\xbe\x14\xfc\xc2\x47\xb5\x82\x8d\x61\xbb\x02\xa1\xcf\xdf\x86\x75"
+  "\xfc\x04\xd3\x70\x0d\x61\x71\x1e\xb4\x4f\x6f\xf5\xe8\xf8\x32\x3f"
+  "\xca\x17\xec\x06\xda\x92\x46\x43\x1b\x1f\xd3\x7d\x1c\x58\xc4\xdb"
+  "\x92\x13\xcc\xc7\x0f\x5a\xc7\x61\x1f\x3f\x68\x6d\x33\x6a\x17\xdb"
+  "\xda\x0c\x88\x9b\x33\xba\xb2\x3e\xf6\xb5\x8a\x03\x20\x6d\x60\xdb"
+  "\xf1\x91\x1e\x75\x14\xf7\x65\xe0\xec\x13\x37\xe6\xf4\xf1\xdb\x42"
+  "\x9d\xd1\x6e\x9e\x5a\x2b\x8c\x5f\xd4\x2e\xc0\x58\xcd\xe6\x7e\x1a"
+  "\x2b\xdb\x89\xf7\x13\xca\x93\x12\x5c\xd7\x1f\xe4\x80\x63\x2e\x1f"
+  "\x87\xf1\x76\xbe\xc4\xca\x56\xf2\x3e\x0c\xed\xa4\xb5\xaf\xaa\xba"
+  "\xcb\xda\x57\xd5\xde\xde\xdf\x46\xd6\x7a\x38\xef\xab\x3e\xd6\xa1"
+  "\xdd\x12\x6c\xa4\xb5\x2d\xa8\x95\x15\x59\xc5\xb2\x1f\xe7\x09\xb1"
+  "\xac\xc5\x8e\x7e\xec\x87\x36\x0a\xee\x5f\xc3\xdf\x3b\x43\xc7\x54"
+  "\x66\x0a\xf7\xd6\x01\xce\x8d\x4a\xe0\x66\xd6\x6e\x3d\x7c\x57\xf3"
+  "\x31\x20\xa7\x9b\x3d\xdc\xda\xea\x1f\x56\x03\xff\xc6\x20\xcf\xb4"
+  "\x31\x27\x49\xbb\xc5\x57\x1c\x38\xb5\x52\x90\xef\x27\x57\x8b\xe3"
+  "\xc2\xc2\x2d\x6c\x26\xdc\xa7\x53\xdc\xc6\x6c\x48\xdb\xcc\x8f\x21"
+  "\x70\xb2\xe5\xca\xaa\xd5\x16\x6f\xb1\x6e\x1b\x6d\x47\xad\x01\xdb"
+  "\x81\x7d\x22\xb8\xff\x5e\x8c\x7b\x20\xe6\x83\xef\x7b\x67\x15\xf7"
+  "\x71\xfe\x4d\xcd\xd9\x74\x71\x7c\x55\x95\x87\xb6\x92\xef\x7b\xd6"
+  "\x41\xbc\x93\x2b\x1e\x8b\x59\x70\x5f\xb0\x32\x36\x3e\x32\x26\x61"
+  "\xc5\xcd\xca\xc8\x98\xc8\x84\xc8\x25\x51\x91\x6b\x96\x24\x44\xae"
+  "\x8c\x99\x16\xbd\xe4\x99\xc8\x65\xca\xd5\x4b\x56\x29\xfd\x93\xa6"
+  "\x24\x8d\x21\x96\xac\x77\x28\x97\xac\x5a\xf5\x7c\xf4\xf2\x08\x65"
+  "\x4c\xe4\xb2\xe9\xf1\xcb\x57\x2d\x4f\x50\x2e\x89\x5f\xf9\x7c\x4c"
+  "\x84\x72\x4a\xc4\x8d\x53\xfc\x6f\x8d\x18\x23\x1e\x43\xbb\x4e\x41"
+  "\x3a\xcd\x67\x3a\x3a\x36\x9f\x21\x1e\x5e\x92\xd8\x78\xaf\xa4\xc8"
+  "\x18\x3a\x6e\xf7\xcf\xc5\x33\xf2\x48\x2c\xee\x13\x89\x7b\x8c\xb1"
+  "\x59\x9f\xc4\xc2\xa7\x14\xf3\x41\x3b\x95\xf0\xdd\x03\xea\xee\xdb"
+  "\x95\xf5\x4f\xa5\x8e\xf9\xcc\x83\xdb\x3f\x0c\xd2\xa1\x6d\xbe\xec"
+  "\x99\xba\x0e\x88\xd9\x62\xf1\x39\xe2\xe2\x33\xc4\x3b\x37\x91\x48"
+  "\xe1\x90\xc1\xa1\xc0\x7d\x24\xe1\x9a\x10\x1d\xf3\x29\xbf\x3e\xf3"
+  "\x3f\x0d\xfa\xd1\xdf\x67\xb0\x99\xdf\x67\x50\x5c\xfe\xf9\x9b\x30"
+  "\x1e\x1c\xf4\x22\x09\x42\x7e\xb6\x31\xff\xe4\xd6\x96\xd9\x00\x5c"
+  "\xc6\xb1\xd4\x53\xff\x9c\x13\x00\xf1\xe0\x61\xed\x04\xee\xdc\x6f"
+  "\x06\x86\xc8\xa0\x5e\xd2\xfd\xc9\xfe\xe4\x55\xb8\xd7\x2a\x1f\x96"
+  "\x85\x7b\xd4\x08\xe3\x69\xd0\x06\x05\xb4\xa5\x95\x6f\xc7\x36\xae"
+  "\x1d\x5b\x58\xbf\xbc\x71\x50\xbf\x57\xb8\xfa\xb4\x0b\x6d\x80\x7a"
+  "\xb7\x42\x9d\x02\xa1\x9e\x0a\xac\x97\xbd\xb1\x3e\x1c\xef\x3a\xca"
+  "\x7c\x3a\xdd\x9c\x08\x72\x9b\x44\xf7\x95\xd8\x5c\x44\xf5\x0f\xda"
+  "\x15\x51\x0c\xdf\x73\x4e\x12\x59\x36\xee\xf1\x97\x7e\x2d\xdb\x60"
+  "\x30\x92\x26\x75\x2b\xf1\x7a\x81\xd5\xb3\xef\x77\x74\xd0\x36\x7d"
+  "\x1a\x8a\xb6\xe1\xdd\x67\x5b\xa5\xd8\x26\xf0\x15\xb2\xe2\x93\x0e"
+  "\xc7\x16\xa5\xaf\x8e\x67\x0d\xec\x36\x71\xcc\xf5\xe9\x3e\x94\x09"
+  "\xc6\x5b\xa7\xd2\x71\x1f\xb9\x4f\x2b\xe0\xde\x84\x8f\x8d\x0d\x6c"
+  "\x6f\x98\x28\x96\xfa\x14\x79\x66\x70\x50\xb6\x87\x50\x36\xee\x27"
+  "\x88\xd7\x50\xfc\xb5\xd3\xe1\x1a\xbd\xa5\x7c\xad\x87\x6d\xf9\x58"
+  "\x26\x7c\xd7\x0b\xf7\xa1\xfd\xf0\x4f\x31\x26\xd0\x03\x97\xf5\x0e"
+  "\xee\xe7\xf7\xca\x16\xb6\xa5\x09\xd2\x37\x9f\x25\x52\xc8\xdb\x52"
+  "\xbc\x85\x2b\x5f\xad\x63\x3e\xa9\xc7\xf2\x37\x8c\x27\x24\x03\xf2"
+  "\x9c\xca\xfa\x94\x18\xb8\xbd\xfd\xb4\xa0\xff\xbb\xbb\x6d\xc7\xb2"
+  "\x79\x3e\xdf\x61\xc3\xe7\x80\x57\x30\x26\xcc\x83\xf2\x81\x43\x9b"
+  "\x4f\x13\xec\x6b\xd7\xdf\x98\x47\x54\x78\x1f\xf8\xde\x8c\xe3\x21"
+  "\x50\x66\xab\x70\x3f\x16\xf8\x9f\x63\xa6\x63\x30\x3c\xb7\xa6\xe1"
+  "\xf8\x75\x6a\x12\xcb\xee\x07\xfb\x8e\x75\x44\x8e\x75\x65\xed\x93"
+  "\x09\x9c\x02\xae\xb7\x70\xbc\xf2\x26\x2a\x36\x4b\x9b\x5b\x3c\x0e"
+  "\xf2\x01\xaf\x8a\x80\x4f\xc8\x2b\xc8\x3b\x4b\xe0\x14\x70\xad\x19"
+  "\xf3\x41\x1d\xc6\x54\xaf\x09\x90\xa2\x8d\x6c\x67\xf6\xed\x41\x8e"
+  "\xb1\xff\x78\xb8\x95\xfd\xc3\xa2\x56\x8a\xd3\xbe\x3d\x4d\xdd\x14"
+  "\x03\x8b\xdc\xf7\xa5\x89\xe4\xde\x0c\x3c\x1e\x83\x72\xa6\x63\xd5"
+  "\xfb\xf6\x40\xdd\x9a\xb9\x58\x7c\x1d\x60\xc0\xf9\xaa\x7d\x51\x78"
+  "\x3d\x2f\xc3\x7a\x8b\x0c\xf7\xd5\xd9\x93\xa1\x8d\xec\xa4\x74\x6f"
+  "\xc1\x7d\x2d\xa8\x2b\x70\x8d\x51\xd8\x2f\xd0\x1e\x96\x70\x0f\xa9"
+  "\x34\x8f\x78\xe0\x3d\x0e\x78\x63\xfe\xcf\xa6\xd9\xbb\x87\x2d\x8f"
+  "\x0f\x94\x10\x82\x63\xe1\x78\x9d\x9f\x37\xca\xf5\xb3\x08\xbb\xf8"
+  "\x2e\xb3\xaa\x1b\x77\xb0\x59\x9f\xc5\xbe\x3a\x0e\x78\xc3\xd5\xef"
+  "\xb3\x82\x81\xea\xe7\xa7\xa4\x7e\x51\x7b\x1d\xf2\xf9\xb3\x6f\x9a"
+  "\x20\x12\xc0\x34\xfe\xf7\x81\x53\xe0\x6b\x6c\xc7\xf3\x1d\xcf\x2f"
+  "\xec\xbf\xda\x7a\x7e\x61\xbf\xd4\xd1\xfc\x82\xf5\x7d\xf7\x3f\x82"
+  "\xf7\x35\x17\x87\x48\x2c\xf7\xde\x3f\xdb\x6c\xe7\xde\xc2\xf5\x37"
+  "\x96\x88\xfb\x2f\xfb\xb7\x63\x1d\x1a\x71\xbf\xf5\x3f\x86\x48\x58"
+  "\x28\xe7\x00\xe7\xb3\xf7\x97\xd0\x78\x05\xe3\xa0\xfd\x69\x98\xc7"
+  "\xb6\x1d\x7d\x7f\x1e\xde\x68\x2b\xc8\x59\xee\xc7\xc8\xfb\x89\x02"
+  "\x3f\x27\xf5\xe5\x61\xac\x32\x13\xd6\xce\x0f\x19\x21\xd7\x72\xf9"
+  "\x59\xf8\xa3\x49\xfc\x6f\x3d\xf7\x43\xda\x97\xbf\xef\xfc\x10\xfe"
+  "\x46\xd3\xfa\x72\xe5\x75\x13\x09\xfd\xa6\xf4\x11\xe5\x98\x3b\xc0"
+  "\xd5\x2c\x11\x2e\xb1\xf7\x87\x51\x65\x5a\xc8\x48\x28\x6f\x16\x97"
+  "\x99\x65\x8d\x7c\xf9\xc2\x6f\x56\xfc\x1b\x53\xac\x7f\xc3\xdf\x88"
+  "\x30\xd1\x0d\xae\x1d\x11\xc1\x3d\x9e\xf4\xa7\xa8\xbe\x24\xa6\x44"
+  "\x21\xbe\xa5\x82\xa4\x8d\xe4\xbe\x78\xe1\x3f\xdd\x50\x9e\x0a\xce"
+  "\x2b\x43\xfb\x32\x5c\x65\x58\x2f\xca\xfe\x25\xad\xfe\xe4\x8a\x01"
+  "\xda\xe8\xea\xdf\x24\xd1\xf7\x6b\xe9\xc7\x64\xf5\x30\x96\x3f\xf0"
+  "\x9f\xb2\x79\xb4\xf0\xd5\x42\x8f\xc9\x9d\xf6\xb2\x5a\xe4\x7f\xdd"
+  "\x7c\x21\x49\xcc\x50\xcb\xf9\x29\x75\xd6\xbf\xff\x92\x6f\xfd\x7b"
+  "\x6a\xc7\x70\x54\x5d\x8b\xff\xa4\xea\xc6\x02\x66\x7b\xfb\x12\xbd"
+  "\x6c\x54\xc6\x2b\xd7\x46\x85\x2c\x7f\x7c\x6d\x46\x10\x72\xfd\x6c"
+  "\x51\xb2\xd4\x7e\xee\x73\xf3\x37\x61\x3d\xaf\x10\xd7\xea\x15\xfd"
+  "\x4e\xde\x63\x93\x86\xbf\xaf\x50\xf2\x69\x37\xed\xeb\x97\x9f\x4b"
+  "\x53\x8a\x7e\x4b\x02\xe0\x9f\x12\xe0\x7f\x77\xff\xbc\x97\xff\x2e"
+  "\xff\x39\xf1\x27\x41\xfd\xb8\xfc\x77\x8e\xfe\x58\xea\xc5\xc1\x12"
+  "\x71\x1f\xf8\x1f\xdb\x67\x28\x59\xfe\x04\xcb\x27\xb0\xfc\x97\x61"
+  "\xf1\xe3\x97\xff\x2e\xff\x5d\xfe\xbb\xfc\x77\xf9\xef\xf2\xdf\xe5"
+  "\xbf\x4b\xe0\x4f\x22\xee\x58\xe3\xba\x8e\xa3\xf8\x4f\x71\xff\x47"
+  "\xc2\x1f\xe2\x34\x66\x28\xd7\xb1\xfc\x1f\x49\x0b\xd0\x2a\x4b\xc2"
+  "\x75\x8a\xdc\xe0\x66\xff\xea\x58\xbd\x47\x66\x60\x9d\xaa\x42\xdd"
+  "\xe1\x93\x1f\xda\x3a\xab\x26\xa9\x5b\x9a\x31\xf7\x80\x5f\x79\x44"
+  "\xbb\x77\x5e\x48\xcb\xcc\xbd\x09\x06\x99\x66\x7e\xfd\xb4\xaa\xa8"
+  "\x4e\xdf\x82\xb0\xc3\xb3\x6b\x93\x8d\x4c\xfa\x9c\xcf\xae\x2b\x5d"
+  "\xda\x36\xee\x95\x47\xbf\xbe\xf9\x9d\xf8\x93\x63\xb2\x1e\xfa\xe2"
+  "\xfa\xca\x67\x8f\x4d\x78\xfd\xc9\x6f\xef\xf8\x68\x4d\xcf\x15\x1b"
+  "\xef\xff\xef\x3f\xef\x5c\x71\x74\xfc\x96\xbf\xff\xef\xad\xef\x27"
+  "\x9e\xf1\xcc\x59\xd8\x78\xe3\x9b\x31\x27\x26\x15\x3d\xf5\xdd\xdd"
+  "\xff\x4c\x31\x4b\xd6\xdf\xbb\x6f\xf2\xf6\x25\x3f\x8c\x7d\xf9\x91"
+  "\xaf\x6e\x7a\x3b\xee\xb7\xd1\x9b\x1e\x3c\x38\x75\x57\xe4\xcf\xd7"
+  "\x6c\x7d\xe2\xd0\xed\x1f\xbe\x70\x76\xe4\x8b\xf3\x3e\x9f\xb2\x63"
+  "\xf9\x8f\x57\xbf\xf6\xd8\x37\xb7\xbc\xf7\xfc\x69\x79\xf6\x82\x86"
+  "\xe9\x7b\xa2\x8f\x4f\x2c\x5c\x7c\xe4\xae\x4f\xd6\x99\x46\x6c\xb8"
+  "\x6f\xff\x9f\xca\x96\xfd\xe7\xaa\x57\xff\xf6\xff\xfe\xfa\xee\xaa"
+  "\x53\x57\xbe\xf4\xf0\x97\x37\xec\x7e\xee\x97\x3f\x6e\x5b\xf4\xef"
+  "\x3b\x3f\x5e\xdb\x3b\xea\xbf\x1e\xf8\x9f\xbf\xbc\xf1\xcc\x4f\x7f"
+  "\xf8\xc7\xe3\xff\xba\xed\x83\xd5\x5d\x5e\x9b\x83\x9a\x66\xbc\xb5"
+  "\xf2\xd7\x6b\x8b\x9f\xfe\xfe\x9e\x4f\x53\xd9\xa1\xc8\x8f\x30\x6d"
+  "\xfb\xcf\x37\x6e\xf4\x63\x63\x9d\x3b\xd7\xb3\x8c\x84\xc7\x9d\x26"
+  "\xa4\xdd\x42\x24\x1e\xe4\x0a\xa9\x1b\x3d\x05\x77\xdb\xeb\xe0\x4f"
+  "\x29\xbe\xde\x99\x3f\x7c\x2f\xec\x26\x38\xfe\x0a\xc7\x1f\xb9\x14"
+  "\x4b\xef\x7f\x92\xdd\x2b\xce\xc7\x9f\x04\xda\x3a\x02\x6a\x32\x92"
+  "\x5c\x01\xd2\xf1\x20\xa3\xc9\x18\x72\x25\x91\x11\x39\xf1\x24\x5e"
+  "\x44\x41\xc6\x92\x71\xe4\x2a\xe2\x4d\xae\x26\xe3\xc9\x1f\x88\x0f"
+  "\xb9\x86\x4c\x80\xda\xfb\x92\x89\xf6\xeb\x9c\x46\x02\x7c\xe0\x1f"
+  "\xf8\x3f\x98\x04\x70\xbf\xc3\x2f\xa7\x9f\xd7\x74\x2d\x9f\xde\xcc"
+  "\xa7\xeb\x2e\xa7\x9f\xd7\x74\xe5\x05\xfe\x9c\x7c\x41\x3f\x25\x10"
+  "\x1a\xd0\xe8\xc0\x2a\x46\xe8\xfb\xb3\x4d\x95\xf0\x7f\x7d\xbf\xc9"
+  "\x20\xd7\xf7\x2b\xcf\xfa\x7a\xdb\xbf\x00\x38\x66\xd2\xaf\xa9\x84"
+  "\xd0\xf9\x04\x56\xfc\x67\xdc\x22\xf9\x4c\x3a\x36\x0d\xa7\x46\x3c"
+  "\x88\x37\xf7\xef\xe0\x7f\x3b\x7c\xe1\x50\xc1\x01\x45\xef\xb8\x0d"
+  "\x8e\xfb\xe0\x58\x20\x94\x0d\x95\x4a\x23\x12\xa6\x06\x0e\x5f\x22"
+  "\x19\x11\x02\x47\x07\x91\x5c\xa1\x26\x92\x91\x2a\x22\x19\x65\x19"
+  "\xcf\x97\x28\x6a\xfa\x6a\x29\xf1\xe4\xd3\x95\xf0\xfd\xaa\x00\xd1"
+  "\xcd\x5c\xf5\x5b\x35\xf3\x42\x02\x95\x37\xdd\x38\xf3\xc6\x99\xb3"
+  "\x96\x2a\xa7\x4f\x57\xde\xec\xef\x7f\xfb\x8c\x9b\x6e\x9e\x71\xd3"
+  "\x2c\xe5\x4d\xb7\xdc\x71\xf3\xad\x77\xdc\x32\x4b\x19\xfd\x42\x7c"
+  "\xe4\x4d\xfe\xcf\x2c\x57\xae\x88\x8c\x8f\x5e\xbd\x24\x7e\xb9\x13"
+  "\x8d\x76\xfd\x0f\x9a\x42\x26\x9a\x68\x35\xc5\x08\x49\xc8\xb5\x84"
+  "\xf9\x52\x4f\x98\xef\x33\x89\xe5\x8c\x8a\x3f\xac\xff\x24\x9b\x40"
+  "\x6e\x1b\xa3\x88\x64\x7d\x2b\x91\xac\x6d\x27\x92\x84\x5c\x22\x79"
+  "\x03\xd2\xca\x41\xae\xc5\x15\x44\xb2\xb5\x80\x48\x5e\xf1\xef\x9f"
+  "\x56\x3d\x97\xa6\x7d\x79\x80\x48\xfe\xbb\x9b\x48\xb4\xcd\x44\xf2"
+  "\xa1\x8a\xa6\xfd\x2f\xe4\xf9\xaa\xae\xdf\xbd\x2e\xec\x9f\xab\x38"
+  "\x4b\xfe\x3f\xad\xf6\xc8\xeb"
   ;
diff --git a/sys/dev/mxge/ethp_z8e.h b/sys/dev/mxge/ethp_z8e.h
index b117015ee0e..eb4ba35aaa0 100644
--- a/sys/dev/mxge/ethp_z8e.h
+++ b/sys/dev/mxge/ethp_z8e.h
@@ -28,7074 +28,7291 @@ POSSIBILITY OF SUCH DAMAGE.
 $FreeBSD$
 ***************************************************************************/
 
-static unsigned int ethp_z8e_uncompressed_length = 370268 ;
-static unsigned int ethp_z8e_length = 113057 ;
-static unsigned char ethp_z8e[113057 + 1] = 
-  "\x78\x9c\xec\xbd\x7f\x7c\x94\xc5\xb5\x3f\x7e\xb2\x59\x60\x93\x06"
-  "\x76\xc5\x48\x57\x44\x5d\x14\xda\xa8\xfc\x88\x8a\x2d\x5a\xd0\x28"
-  "\xd1\x42\x2f\x3f\xa2\x82\x4d\x2b\x9a\xa0\x09\x06\x8d\x10\x21\xc2"
-  "\x82\x21\x1b\x16\xb4\x09\x0d\x24\xd5\xd4\xa2\x84\x04\x5b\x6c\x51"
-  "\xc2\x0f\x2d\xf6\xe6\x0a\xea\xd2\x44\xa5\xf7\x26\xd9\xd8\x4b\xbf"
-  "\xdf\x5c\xbf\x78\xbb\x70\x23\x8d\xdc\x05\x56\xb2\x90\x35\xd9\xdd"
-  "\xf9\xbc\xcf\xcc\xf3\x24\xbb\xcb\x06\xe5\xf6\xbe\xbe\x9f\x7f\x9a"
-  "\xd7\x6b\xf3\x3c\xcf\x3c\x33\x67\xce\x9c\x39\x73\xe6\x9c\x99\x33"
-  "\xe7\x21\xfa\x3b\xfe\x0c\x87\x3a\xfe\x9e\xe2\xff\xf8\xfb\xc7\xdf"
-  "\x3f\xfe\xfe\xf1\xf7\x8f\xbf\x7f\xfc\xfd\xe3\xef\xff\xce\xdf\x59"
-  "\x83\x91\xfe\x58\x4d\xd4\xe3\x34\x59\x3d\x74\xa6\xe4\x57\x2f\x89"
-  "\x20\x92\x13\x3c\x64\xb2\xf2\x55\xfb\xd1\x8b\x48\x37\x54\x93\xe9"
-  "\x3a\x0b\xa5\xcc\xd8\x46\x54\x33\x4a\x78\x5f\x7a\x59\xf8\xd6\xbf"
-  "\x2c\xbc\x99\xaf\x13\x35\x8f\x23\x7a\x69\x94\xf0\x03\xce\x42\x0f"
-  "\xfd\xa4\x93\xe1\xac\xc7\x33\xbf\xdf\x30\x4a\xf8\x90\x5e\xec\xa1"
-  "\x9f\x2e\xe4\xf4\x75\xa3\x00\x2b\x95\xc8\xf9\xb2\x08\x44\xc0\x35"
-  "\x71\x79\x86\x99\x39\x56\xe2\xb3\x23\x06\x0e\xc3\x68\x04\x8c\x23"
-  "\x17\x81\x91\xa2\xe3\xe5\x37\x50\x02\xc3\xeb\x76\x92\xd5\xef\x74"
-  "\x5d\x81\xb2\x7e\xb4\x29\x8d\xcb\x56\x21\x8f\x70\x52\x62\xb3\x3d"
-  "\x48\xb6\xeb\x28\xe1\x04\x25\x7d\x81\xab\x01\xd7\xcf\xb8\xbd\xeb"
-  "\x55\xb9\x71\x0c\x03\x65\x13\x7a\x9c\x49\xe9\xfd\x65\x01\xdb\x56"
-  "\x4a\x46\xe4\x7d\xcb\x6f\x70\x19\x54\x5e\x4b\x92\x96\xd7\x80\xbc"
-  "\x0b\xf5\xbc\xea\x9d\x61\x96\xf6\xee\x5b\x78\x67\x8f\x7e\x67\x7c"
-  "\x51\x7b\x97\x82\x77\x35\x31\xf8\x19\xdd\xbd\x41\x42\x3d\x8c\x8b"
-  "\xcd\x83\x6b\x13\x7a\x46\xc3\x8d\x71\x6a\x46\xfe\x32\xce\x9f\x69"
-  "\x13\xc1\xf9\x36\x92\xb8\x30\xed\x90\x77\x66\xd3\x76\x95\x17\xf7"
-  "\x63\xb8\xbc\x76\x6f\xc3\xbd\x4c\xd7\xea\xbd\xac\xc7\x99\x9c\x12"
-  "\x8d\x13\x91\xf6\x6e\x24\xde\xa5\x45\xbf\x7b\x3f\x5d\x7b\xf7\x6d"
-  "\xbc\xcb\x8c\x7e\x97\xa0\x97\xb3\xe2\x5d\xae\xfe\x2e\xb2\x9f\x14"
-  "\xc7\x19\xf1\x1b\x62\x22\x1a\x8a\xdf\x30\x93\xde\x77\x2b\xac\x22"
-  "\xec\xb8\x92\x8c\x62\xe3\x9b\x3b\xc3\x4e\x41\x6e\x7b\x80\x6c\xa3"
-  "\xc9\x71\x9c\x92\xdb\x01\x97\x36\xaf\x21\x93\xa3\x48\x04\xdc\x76"
-  "\x2f\xb5\xf9\xbc\xe4\xf0\x89\x2e\x77\xf0\x1c\x95\x9e\x23\x93\x3b"
-  "\x78\x8a\x4a\x9f\x21\x6b\x73\xc9\xe7\x14\x8f\x2f\xc2\x06\x41\x8e"
-  "\x31\x5c\xb6\x93\xda\x6a\x3b\xc9\x51\x1b\x5d\xd6\x71\x35\x59\x5b"
-  "\xf1\x0c\x9a\x9b\x19\x8f\x66\x5b\x90\x82\xc9\x6f\xee\x2c\x79\x85"
-  "\x8c\x8e\xb1\x64\x68\xcd\x73\x69\xb8\x7c\x6b\x0b\xe3\xb2\xe1\x24"
-  "\x99\x7e\xb3\x18\x7d\x7f\x92\xf1\x7d\x7b\xe7\xde\x35\x01\x43\x93"
-  "\x75\x36\x35\x59\x8f\x52\xb3\x75\x3a\x35\xdb\x33\x69\xf3\x49\x4a"
-  "\x69\x0a\x4c\xa3\x66\xe3\x7d\x18\x1b\x99\xe4\xf6\xe2\xde\x16\x42"
-  "\x1e\x3f\xd9\x56\x12\xfa\xf5\x5b\xe5\x35\x4f\x92\xc9\xa3\x60\xa2"
-  "\x3f\xbf\x55\x73\xa8\x98\x88\x69\xc6\xcf\xf1\xda\xb1\xe2\x4a\xb2"
-  "\x02\xbf\x2e\xe0\x72\x3b\x70\x69\x1d\x67\xa5\x74\xe0\x3c\xcc\xbd"
-  "\x25\x48\xc6\x12\x4a\x1a\x64\x4c\xa4\x86\x9d\x72\x6c\x7a\xeb\x5e"
-  "\x16\x5d\xcc\x5b\xdd\xcf\x65\x63\x7c\xa5\x18\x51\xf7\x0e\xae\x6f"
-  "\x33\xc6\xa8\xe3\x35\x32\x76\xaf\xca\x4e\xa8\x7f\x59\x74\xe2\x9d"
-  "\x4d\x7f\x07\x7e\xef\xc4\xfb\xae\xc9\xa9\x64\x71\x07\x33\xe8\x83"
-  "\xde\x2e\x23\xc3\x18\xe1\xa7\x04\x86\x67\xb6\x53\x22\xda\x33\x04"
-  "\xf8\x7c\x59\x8f\xf4\xeb\x91\x0f\xe5\xd1\xff\x1b\x77\x72\x79\xf1"
-  "\xed\x87\xfd\xe1\x6f\x3f\x7c\x2e\xfc\xab\x87\xbb\xc5\xaf\x1e\x3e"
-  "\x1b\xfa\xd5\xc3\x5f\x3a\x56\x93\x29\xf4\xed\x87\x7d\x6d\x45\xb2"
-  "\x0f\x2c\x6d\x45\xe8\x83\x10\x99\xd6\x9e\x22\xcb\xa3\xcf\xa0\xef"
-  "\x83\x9f\xd1\xda\x25\x64\x0d\x27\xbd\x95\xeb\x0e\xfe\x85\x1e\x2d"
-  "\x21\x81\xfb\xa2\x78\xed\xeb\x4e\x7e\xbb\x4b\xf1\xac\x89\xdb\xd4"
-  "\xe1\x31\xbc\xb1\x9d\xeb\xf5\x25\xbd\xdb\x85\x9f\x17\x3f\x1f\x7e"
-  "\x7e\x91\xfc\xb6\x1f\xb4\x72\x8c\x58\x97\x40\x75\xbd\x44\x93\xc3"
-  "\x94\x80\x2e\xf2\x03\x7f\xcb\x20\x74\x1b\x13\xde\xf8\x61\xfb\x77"
-  "\xcb\xa8\xb4\xa7\xa7\x80\x58\xa6\xb0\x3c\x61\xf9\xd2\xe3\x1c\x9e"
-  "\x81\x7a\x3c\x92\xf7\x5f\x16\x80\xfd\x61\x3b\xd2\xbb\xfc\xcf\x15"
-  "\x24\xf8\x9e\x2b\x30\x74\x27\x7f\xf8\xef\xc8\x93\xe7\x31\xbc\x69"
-  "\xd5\x68\xd8\xc5\xb0\x30\x4e\x7c\xc3\x83\x94\x08\x98\x45\xff\x7c"
-  "\xbe\xc3\xb8\xed\x65\x71\x14\xf9\x2a\xfb\x61\x01\x36\xe0\x80\xfe"
-  "\xc3\xb7\xeb\x69\xa0\x75\xe7\x26\xe4\xe3\xf2\xee\x40\x06\xcb\x5d"
-  "\x8f\xbb\xb0\x8b\xcc\x41\x4a\x16\x7d\xaa\x3e\xe4\xe9\x62\xf9\x38"
-  "\x3c\x40\x43\x7b\x9c\x94\xc5\xb0\xb9\x9c\xdb\xdb\x45\x28\xf7\xef"
-  "\xc2\x51\x00\xb9\x44\x73\x7b\x44\x41\x02\x64\x71\x67\x13\xca\xab"
-  "\xba\x47\x98\x74\x1c\xb9\x0e\xee\x6b\x89\x27\xf8\xa1\xa9\x30\x40"
-  "\xc3\xb7\x50\x22\xca\x3d\xc8\xf0\x18\x16\xf8\xc0\x83\xb6\xfe\x7b"
-  "\x53\xa1\x8f\xc2\x22\x0a\xa6\x47\x83\x97\x1d\x05\x0f\xe9\x02\xf0"
-  "\x98\xff\x9a\x51\x66\xf8\x76\x09\xef\x81\x7f\x0e\x33\xbc\x00\x19"
-  "\x6d\x12\xdf\x87\x18\x46\x0f\xcb\x34\xc0\x74\xad\xbc\x87\xbc\x34"
-  "\xc2\xe5\x73\x14\x24\xb6\x95\x10\x71\xf9\xbd\xa5\x5d\x43\x44\x77"
-  "\x76\x22\xf3\x1c\xbf\x77\x07\xcf\x72\x9e\xd7\x44\x77\x41\xe2\x70"
-  "\x2f\x19\x19\x67\x94\xb7\x33\x9e\x91\x7d\xf9\xc0\xbd\x0f\x4d\xa7"
-  "\x87\x32\x67\x65\x4e\xa7\x39\x77\xcf\x98\x4e\xe9\xb7\x4f\x4c\xbf"
-  "\xf5\xfb\x53\x6f\xa5\xac\x1f\x3f\x30\x9d\xb2\xe6\x4e\xa7\x07\xf1"
-  "\xcb\xbe\x6f\x16\x1e\x66\x4c\xbf\x39\xfd\x87\x13\xb3\x66\xcc\xba"
-  "\x97\xee\x9f\x7f\x4b\xfa\x2d\xb7\xd0\xdd\xf7\xce\xbe\x39\x3d\x5d"
-  "\xbb\xde\x9c\xce\x59\x7e\x3a\xf5\xde\x07\x27\x66\x2d\x5f\x56\xbc"
-  "\x6c\xe2\xdc\x59\x33\x22\xe7\xc4\xb4\xd0\xf9\x30\xd3\xd4\x2f\xce"
-  "\xcc\xa4\x30\x64\x44\x1d\xfa\x1a\x3f\xaf\xab\xf4\x38\xc6\xba\x65"
-  "\x6d\x1d\xf7\x91\x94\x93\x23\x8e\x62\x7c\x1b\x7b\x9c\xe6\x0d\xa0"
-  "\x55\x36\xd3\x0a\x73\x0f\xf2\x5c\xb1\x08\xef\x8e\x69\xb2\x79\x08"
-  "\xde\xef\x88\x7e\x7f\x99\x1d\xef\xff\xd6\x66\x23\x72\xe3\x07\xfa"
-  "\xfa\x21\xf3\x40\x47\x1f\x75\x3b\xb2\x87\x80\x8f\x13\x50\x47\x27"
-  "\xc6\x20\x68\x61\xf6\x44\x8c\xed\x4e\xf4\x43\xbb\x6d\x0d\x25\x9e"
-  "\x26\xf3\xbf\xb4\x15\x67\x10\xf7\x87\xbb\x58\x83\x71\xae\x1f\x46"
-  "\xb2\x84\x81\x3e\x06\x9c\x23\x0a\x8e\x25\x2d\x42\x0e\x78\x18\xce"
-  "\x66\xbc\xd3\x60\x85\xda\x20\x0f\x20\xaf\xdf\x0e\x3b\xd2\x48\x24"
-  "\xbf\xb9\x2f\xdc\x97\x26\xe7\x16\x94\xcb\xd5\xf9\x17\xf9\xfd\xcd"
-  "\x45\xc8\xf7\x9b\x99\x09\xe8\xef\x04\xcc\x9d\x68\x8b\xb9\x10\x7c"
-  "\xec\x0f\x6f\x7c\x37\x20\x7a\xb2\x49\xa5\x59\x1a\x44\x32\x9e\x37"
-  "\xbe\xfb\x95\x70\x20\x6d\x8d\x4c\xdb\xcd\x69\xe8\xdb\x44\x1e\x83"
-  "\xe2\x39\x99\x9e\x08\x5a\x8c\x05\x7e\x1d\x21\x2e\x7f\x46\x96\x1f"
-  "\x86\xb4\x04\xe4\xfd\x2a\x9c\xfc\x6e\x2f\x78\x85\xd3\x30\x9f\x5f"
-  "\x51\x06\x78\x7d\x61\x91\x4d\x22\x65\x28\xc3\x0e\xba\xd6\x78\xe9"
-  "\x44\x11\x19\x3c\x78\x17\x76\x00\x66\x5f\x7f\xfd\xed\x5c\x16\x75"
-  "\x19\x7b\xfa\x0a\x30\x87\x5a\x8e\xb0\x2e\x10\x62\x7c\xce\xf4\xe7"
-  "\x71\x71\x9d\x3c\x8e\xd1\x17\x5e\xf4\x53\x52\x8f\xf3\xb2\xd9\x31"
-  "\xfd\x94\x07\x38\x5f\x81\xee\x1d\x80\x71\x30\xdc\x8d\x3a\xf0\x0c"
-  "\xb8\x06\x0d\xae\x0e\xc3\xaf\xf8\xe0\xb2\xca\x18\x3e\xb8\x17\xb0"
-  "\xcf\x45\xbc\x6f\x88\x79\x7f\x03\xde\xf7\x6a\xef\x31\x9e\x2e\x6b"
-  "\x89\xa9\x1f\xf2\x70\x44\x18\xf5\xfb\x31\x5e\x12\x51\x5f\x56\x1d"
-  "\xeb\x69\x03\xf9\x83\xd1\xf9\x47\x5a\xbb\x9d\x66\x96\x21\x2c\x0b"
-  "\x65\xfe\x7a\x8d\x57\x55\xfd\x23\x27\xc4\xe4\x07\x0f\x9b\x87\x81"
-  "\x1f\xf8\x7a\x39\xf2\x0c\x83\x2c\x32\x62\xde\x38\xda\x54\xc2\x7a"
-  "\xdb\xc8\x85\x31\xf9\x4b\x90\x6f\x34\xd3\x51\xd2\xe0\x8c\xa4\x41"
-  "\x96\xa6\x67\xf1\x58\x30\xa1\x4c\x75\x4c\x99\x7d\x28\x73\x5d\x58"
-  "\xd1\x2d\xb1\xa7\x3b\x6e\x99\xe6\x98\x32\x9d\xb2\xff\x55\x3d\x46"
-  "\xe6\x17\xbd\x8c\x94\x2d\x7d\x51\x30\xb8\x6d\xd0\xc7\x2e\x37\x45"
-  "\xc3\x48\xed\x44\xbd\x37\x6e\x52\xe3\xf8\x5b\xe8\xf3\x5b\x90\xf6"
-  "\x17\xc0\x0d\x31\x9f\x30\x2f\xbb\x7d\x01\xc8\xbe\x99\x29\x6a\x0e"
-  "\xbf\x7c\x89\xb9\x84\xf8\x7e\x22\xdf\x33\x6c\xd1\x37\x5b\xe3\xf1"
-  "\xcb\x97\xe0\xca\xe9\xb2\x4e\x1e\x5b\xa2\xef\x9f\xc2\x0a\xe6\xe5"
-  "\x9b\x30\x06\x0d\x78\x0e\x69\x75\xb4\xe2\x39\x01\xfc\xd9\x0b\xb9"
-  "\x0a\x9e\x9c\xc9\xfc\x36\x05\xe9\x1f\x6a\xef\xdf\xe3\xfc\xb8\xbf"
-  "\x59\xbb\x67\xbe\xec\xd5\xf8\x12\x7c\x9e\xfa\x8e\xac\x5b\xf2\xba"
-  "\x2a\x1f\x56\x7c\x3d\x03\xef\x5e\xc3\x75\x16\xae\x9b\x70\xbd\x1f"
-  "\xd7\x25\x8e\x73\x64\x75\x84\xa0\x47\xa8\xe7\x05\xb8\x3e\x80\xeb"
-  "\xdd\xb8\x3e\x88\xeb\x44\x1e\x97\xbe\x55\x05\x14\xc3\x13\xde\xb0"
-  "\x1a\x8b\xc3\x54\x7f\xa4\x8e\xd1\xc6\x87\x1a\x9f\x67\x06\xd2\x84"
-  "\x4a\x33\x40\x9e\x0f\xa4\xf5\xcd\x64\xba\x64\xa1\xed\x01\xae\x5f"
-  "\x1b\xd7\x43\x54\xbf\xa8\x3c\x61\x55\x4e\xeb\x3b\x2d\x4d\xe5\x4b"
-  "\x88\xac\xd3\x43\x97\xb7\x94\xfa\x85\xc0\xb5\x91\xe9\x8a\xf4\x83"
-  "\xa0\x09\xf4\x99\xcb\x2b\x99\x4e\x03\xfd\x7d\x79\x5a\x44\x7f\x43"
-  "\x9f\x4d\x0d\x44\xf7\xb7\x25\x8b\x69\xc6\xfd\xad\xe3\xcb\xb8\x63"
-  "\x4e\xe1\x79\x6a\xa8\xc2\xdf\x92\x05\xb9\xee\xe5\xbe\x4f\x2c\xe2"
-  "\xf1\x70\xc5\x34\x0f\xed\x90\x32\x91\xdf\xf9\x93\x3e\xca\xe2\xf2"
-  "\x89\x85\xf2\x5d\x36\xe4\x65\x87\xfe\x8e\xeb\xe6\x71\x98\x58\x2c"
-  "\xdf\x15\xeb\xe5\x20\x33\xdb\x65\x59\xcc\x71\x3c\xe7\xf3\xdc\x8d"
-  "\x39\xb4\x0b\x79\xb6\x78\x68\xb8\x65\x30\xfb\x46\x94\xbf\xe9\x9a"
-  "\x58\x46\x86\xeb\xcb\x68\x88\x3b\x78\x94\xe6\x05\x45\x68\x22\x51"
-  "\x92\x3b\x38\x8d\x6e\x20\xba\xcc\x1d\x3c\x42\x68\xf0\x58\x77\xb0"
-  "\x06\x73\xe4\x06\x7e\xff\xc1\x8d\x94\x90\x80\xab\xe3\x26\x32\x24"
-  "\xb8\x83\x3b\x90\xbe\x9f\xae\x27\x63\xc2\x0f\x87\x88\x1e\x77\x70"
-  "\x0a\x9e\x8b\xe9\xbe\x21\xe2\xaf\x39\x21\xb2\xcc\x7e\x5e\x38\xdc"
-  "\xc1\x3c\xba\xef\xf9\xb0\x70\x07\x5b\xf0\xae\x90\xe6\x85\xbe\x12"
-  "\xf3\x42\x3d\x42\x98\xde\x6c\x9f\x17\x3a\x83\xfb\xbf\x0a\xd0\x12"
-  "\xd7\x0f\xf0\x73\x08\x37\x74\x5d\x51\xf1\xa6\x2b\x67\xb5\x81\xfa"
-  "\x30\xaf\x88\xa4\x37\xdb\xd1\x3e\x4f\x9f\x28\x48\xc4\x9c\xf0\xd7"
-  "\xbe\x3e\x5c\x37\xbe\xf9\x9f\xf2\xb9\xfc\x4d\x1f\xe0\x78\x26\x41"
-  "\xf1\x67\xfc\xdd\xc1\x4e\xca\x81\xec\x98\xb7\xda\x27\x18\xf7\x11"
-  "\xeb\x04\xcd\x5b\xfd\x81\x80\xdc\x32\xcf\x5b\xed\x10\x78\x67\x02"
-  "\x3c\x8f\x3b\xe8\xe5\x3a\x7c\x80\x77\x4a\xc2\x2b\xdf\x65\x41\x5e"
-  "\x1f\xe7\x8b\x84\xc3\x30\x38\xef\xbc\x10\x99\x45\xc5\x2e\x4b\x5f"
-  "\xc5\x2e\xc2\xcf\x86\x5f\x96\x48\xde\xf5\x58\xd8\x99\x7a\x88\xe7"
-  "\x28\x94\x2f\xc2\x73\xd9\x57\xe0\x13\x49\xc7\x10\x0d\x43\xfe\x22"
-  "\xf4\x79\x66\x8f\xc4\x77\xd7\x76\x89\xef\xc6\x5d\xf5\x5f\xc9\x76"
-  "\xec\xaa\x53\xed\xd8\xb5\x8d\xd3\xfd\xe0\x5b\xdc\xbb\xfc\xea\xdd"
-  "\x07\x28\x37\xbf\x47\xe1\xe5\x12\xa6\x5d\xac\xef\x24\xce\x0b\x89"
-  "\x32\xa6\x21\xe8\x5a\xc6\x74\x64\xbb\x05\x75\xb8\x44\xd2\xae\x76"
-  "\xe0\x03\xbd\x68\xd7\xd9\x3e\xc1\xf3\x66\x03\x7d\xa5\x60\x0b\xc0"
-  "\x59\xd8\xc3\x30\x4d\x0d\xc0\xb1\xc1\x12\x34\xd8\x40\x0f\x11\x98"
-  "\x17\x5c\x17\xcc\x59\x4d\x89\xee\xe0\x87\x94\x56\x56\x96\xe0\xb6"
-  "\x17\xa3\x9d\x95\x80\x99\x87\xf7\x74\x39\xea\xfa\x40\x24\x35\x10"
-  "\xd7\x27\x2a\x1a\x2c\x80\x39\x1c\xb0\xf2\x18\xa7\x5e\x27\xf1\xb3"
-  "\xad\x57\xe2\xd7\x90\x11\x2e\x6f\xc8\x0d\x9b\x1a\xb2\x74\xfe\x61"
-  "\xde\x51\x74\x63\x9e\xd9\xcd\x69\x16\x9d\x4f\x42\xe5\x0d\xe9\x37"
-  "\x11\x59\xe6\xfa\x45\x90\x79\x65\x32\x15\x25\xb4\xf9\x8f\x80\xd6"
-  "\x26\x6a\x2b\xda\x4f\x37\x12\xdb\x4f\x7e\x6a\xf3\xd7\xe0\x79\x1b"
-  "\x31\x7e\x6d\xfe\x0d\xd4\xea\xdd\x41\x73\x8b\xfc\xeb\x42\xa6\x86"
-  "\x7d\xad\xde\x39\x84\xf2\x1f\x00\xc7\xf0\xa3\x45\xc6\xb2\xb6\x22"
-  "\x3f\x3f\x3b\x5a\xbd\xe0\xcf\x90\x08\x05\xcb\x1b\x6c\x41\x53\x83"
-  "\x6b\xee\x39\xe1\x9b\xe3\x2d\x1b\x82\xb4\x3e\x73\x82\x08\x9a\xed"
-  "\x0e\xd1\xea\xad\xa4\x47\xcf\x51\x42\x6b\xc1\x7e\xc9\xa7\x8f\x16"
-  "\x15\x91\x2c\x7f\x2e\x68\x7e\xc4\x5b\x46\x8f\x14\xd0\x08\xe4\x3f"
-  "\xc3\x3c\x2b\x46\x94\x51\x4b\x67\x21\xcd\x39\x15\x4c\x9c\x7b\xae"
-  "\x4f\xb4\xe4\xd6\x50\x6b\x41\x0d\xd3\x23\x83\xed\x8c\x39\xa7\xba"
-  "\xc5\xdc\x73\x3d\xa2\xb5\x60\x37\xb5\xe4\xee\xa7\xd9\x9f\xbb\xcc"
-  "\xa1\x8a\x86\xf4\x70\x52\x43\x56\xb8\xa2\x21\x37\x94\xd4\xb0\x2f"
-  "\x58\x01\x5c\x92\x1a\x5c\x62\xe3\xee\x74\xd0\x2f\x49\xf6\x45\xf2"
-  "\xee\x49\xb8\xb7\xc9\xfe\x35\xed\xce\x10\xe5\xbb\x73\xfb\x2a\x76"
-  "\x67\x49\xbe\x4f\xda\x9d\xe1\x0e\x32\xff\xef\xce\x45\xbe\x5c\xc5"
-  "\x23\xbb\x8b\x14\xef\xef\x5e\xc6\xfd\x8a\xbc\x65\xf8\x55\xe3\xb7"
-  "\x1d\xef\x7c\x80\x75\x19\xc3\x0d\x97\xef\xa1\xb0\x69\x37\xc6\xc3"
-  "\x1e\x0b\xec\x12\x43\x9b\x7f\x07\x85\x20\x5b\xdb\xfc\x21\x9a\xfb"
-  "\x4c\x00\x7d\x8b\x3e\xb0\x87\x40\xcf\xa3\xf4\xe8\x33\xe4\x70\xdb"
-  "\x8f\x92\x78\xbf\x9a\xe9\x61\x9e\xfb\xcc\x07\x22\x5c\xb1\x47\xbe"
-  "\x9f\xfb\x8c\x03\xb6\x11\xe0\x24\xed\xb1\x84\x37\xee\x49\xd7\x74"
-  "\x25\xe0\xb1\x67\x32\xe3\xd1\xd7\x03\x1e\xc3\x3c\x8e\xf7\x19\x48"
-  "\x7b\x9b\xe7\x8e\x30\xf3\x5d\xf9\x9e\x7d\xc2\xb4\xd7\x32\x67\x88"
-  "\xf0\x85\x5e\x20\xc9\x03\xe1\x3b\x85\x60\xdb\x2b\xc7\x4e\xdb\xe5"
-  "\x98\x0a\x8d\x2e\x13\x49\x7b\x2d\xa2\x62\xcf\xbe\xf0\xc6\xb7\x1e"
-  "\x00\x9c\x44\xb1\x8a\xcb\xbe\x95\xa5\x78\xe6\x33\x39\xf6\x44\xc5"
-  "\x5b\x59\xdf\xd4\xce\xef\x71\x8e\x2e\xf1\xd0\x1e\x29\x83\x71\x5f"
-  "\xee\xa1\xbd\x13\xb4\xfb\x1a\x0f\xd5\x1c\x95\xf2\x11\x72\xae\xa8"
-  "\x94\xae\x38\x49\x57\xcd\x04\x4d\x08\xf7\x29\xb8\x9f\x3d\xef\x06"
-  "\xb4\xbb\xfc\x6c\x1a\xfa\xbc\x87\x65\x8e\x70\x4e\x81\xbe\x41\x19"
-  "\x68\xaf\x49\xf4\xa4\xa5\x88\xe4\x03\x2f\x88\x3e\x2b\xdb\x92\x66"
-  "\x3c\x8f\x00\x5d\xc7\xe1\x3a\x72\xdb\x79\x4a\xc5\xcf\xba\xcd\x19"
-  "\x2e\x63\x99\x8c\xfb\x74\xb1\xca\x9a\xbc\x79\x25\x4d\x30\xfb\xc9"
-  "\x54\xef\x0c\x67\x9b\xd7\x59\xd8\xa6\x4a\xe5\x7b\xe1\x7c\x85\xea"
-  "\xcf\x93\x91\xe7\x96\x70\x12\xea\xb3\x9b\x85\x58\x91\x46\xf5\xcb"
-  "\x21\x8f\x9c\x64\xad\x77\x8a\x7d\xa1\x9e\x34\x03\xe3\xa9\xe3\xc2"
-  "\xb8\x01\xcf\xab\x81\xe7\xc2\x05\xab\x33\xe8\x43\x3b\xc5\x5d\x8b"
-  "\xe8\x71\x5e\xd5\xdf\xfe\x41\xde\xd7\xea\x34\x19\xe4\xfd\x41\x9d"
-  "\x4e\x83\xd9\xfb\x3c\xce\x43\xe7\x85\xaf\x6a\x29\x31\x2d\xac\x8e"
-  "\xa0\xf8\x2f\xd8\x24\x65\xa5\x21\xba\x7a\xde\xea\x6b\x85\xdb\x27"
-  "\x5c\x6e\xfb\x29\xb9\x5e\x57\x8f\x3c\xa5\x41\x11\x66\xfb\x96\x6d"
-  "\xdb\x1a\xb6\x55\x2b\x0e\x14\x88\x8a\x03\x79\xdd\x2b\x45\xb0\x4e"
-  "\xda\xa3\x63\xd2\x3d\x74\x5b\x91\xea\x9b\x86\x0c\xcc\x85\x9d\xdd"
-  "\xa6\x03\x79\x80\x7d\x19\xc3\x6e\x2b\x12\xae\x70\xd2\x81\x42\xe4"
-  "\xc3\xfc\xf7\x6e\x75\xe4\x9a\x1d\xe6\x35\xef\x86\x97\x79\x6e\x1b"
-  "\x83\xf9\xef\xda\xf9\x17\xac\x09\xc9\xd5\x45\x42\xbf\xd8\x06\x16"
-  "\x25\x13\x34\xf6\xd1\xff\x2c\xf8\x65\xc4\x7f\x3d\x30\x37\x36\xb8"
-  "\xba\x61\x77\x39\xd6\xd2\x18\xf4\xc3\x55\x27\x69\xcc\x17\x0e\xbb"
-  "\x38\x21\x9c\x63\xca\x7e\xb3\x26\x00\x9d\x60\x8c\xdf\x43\xeb\x0a"
-  "\x06\x9f\x5b\x21\x17\xcf\x8b\xae\xaa\x95\xfd\x34\x3b\x36\x6f\x75"
-  "\x58\xf0\x3d\x8f\xb3\x7a\xa4\x33\x3d\x7a\x9c\x57\x4f\xd3\x69\x31"
-  "\x08\xfd\x8d\xa2\xfc\x80\x5d\xe9\x80\x57\xd7\x0a\xa7\x20\xd7\x35"
-  "\xbc\x8e\x77\xf5\x36\xa9\x07\x95\xef\xce\xea\x86\x1c\xe1\xf5\x0e"
-  "\xe8\xcc\xfe\x15\x56\x01\xfd\xe6\xea\x6a\x0f\x8d\xf7\x68\x76\x96"
-  "\xdf\x1d\xbc\x97\x65\x4a\xd6\x60\xeb\xa4\x03\xf0\xaf\x39\xd8\x06"
-  "\x8d\x88\x65\x92\x30\x7d\x54\x53\xaa\xf0\x0e\x30\x5c\x57\xe9\x59"
-  "\xea\xc4\xfb\x15\x7e\xd1\x25\xca\x3f\x2a\x67\x3d\xc4\xb5\xb2\x97"
-  "\xd3\xde\x03\x0f\x0b\xd7\x72\xc6\xe9\x9a\xf7\x5c\xd7\xf4\xd2\x09"
-  "\xe8\x78\xd0\xef\x7c\xca\xe6\xba\x66\x67\x53\x31\x69\x76\xdc\x35"
-  "\xb0\xff\xbe\xbb\x53\xc7\x0b\xb2\x43\x80\xbe\xa8\x9f\xe5\x9e\x97"
-  "\x78\x0d\x6d\x45\x89\x08\x00\xd7\x0c\xe4\x9d\xaf\xb7\x81\xdb\xa7"
-  "\xda\x75\x4d\x41\x64\xbb\x80\x83\x0f\xfa\xb2\xa4\xc1\x8a\xd5\x64"
-  "\xb2\x29\x5a\x9b\xb8\xbd\xdc\x16\x6e\xb3\x6c\x0b\xf4\x0b\x9e\x57"
-  "\xdc\xc1\xdb\xa0\x7f\xc9\xf4\x5c\xc0\xda\xef\xa1\xef\x64\x2a\xdd"
-  "\xea\x1a\xa9\xd7\xc5\xed\x47\x53\x83\xc5\xf1\x15\x5d\xe3\x08\x8b"
-  "\xe3\x27\xe8\x5a\xd6\x69\x13\xf9\x2a\xe7\xe4\x00\xf8\xd7\x74\x28"
-  "\x93\xe7\x62\x77\xc9\x39\xc8\x6f\x99\xf7\x72\xe4\xed\x44\x9e\x9b"
-  "\xb5\xbc\x37\xab\xf5\x5d\x79\x1d\xc6\x57\xb1\xb1\x61\x38\x78\x77"
-  "\x26\xaf\x49\x80\xce\x59\xfa\xb3\xc0\x33\xae\xe8\xab\x43\x99\xf1"
-  "\x71\xd9\x6b\x09\xab\xb1\xe8\x45\x3d\xdf\x66\x9e\x72\xac\xa6\x2b"
-  "\xc1\x97\xc7\x4a\xd7\xd2\xe5\xcc\x4f\x22\xe9\xc0\x06\x45\xf7\x6b"
-  "\x6b\x84\xb3\x8c\xdc\x90\x9e\x45\x2b\xe9\x2a\x8c\xbf\x92\x93\x74"
-  "\xed\x1b\x39\x25\x36\xe0\x4a\x54\x75\x9a\x48\xca\x9a\xa4\x03\xd0"
-  "\x27\x3e\xa7\xfa\xd3\x6c\x6b\x5d\x7b\x58\xe7\x45\xdc\x1f\xb9\x98"
-  "\x5c\x00\x5d\xab\x95\xad\x60\xbb\x9b\xd7\xcb\x8e\x93\x6d\x02\xb7"
-  "\x17\xbf\x04\xa4\x5d\x2d\xce\x8b\x85\x82\xf5\x37\xcc\x57\x1e\xb2"
-  "\x65\xe3\x5a\x2d\x7f\x4e\xca\xd5\x9e\xcb\x90\x2f\x45\x9c\x0f\x73"
-  "\x1e\xf0\xab\x6d\x9c\x70\x26\xf0\x98\x38\xd8\xe3\xb4\x65\x79\x68"
-  "\x6a\xb9\xea\x1b\xdb\x18\x86\x35\x08\x0e\x65\xe8\x5b\x62\xde\x04"
-  "\xac\x7f\xb1\x95\x26\x30\x1e\x9b\xe4\xb8\x00\xac\x7a\x83\x92\xcf"
-  "\x61\xe0\x5a\xe7\x0c\x17\x40\x16\x17\x84\x37\x36\xed\x94\xf7\xda"
-  "\x3b\xc6\x23\x8c\xfa\xe3\xc3\xff\xa8\xc6\x35\x9a\x79\x7c\x6c\xaa"
-  "\x82\xf3\x51\xb9\x6b\xf4\x49\x7e\xbe\x82\x9f\xfd\xa6\xe6\x9d\xee"
-  "\x2d\x19\xa8\xff\x24\xea\x1d\x9b\xaa\x6c\x80\xb1\x57\x74\xa3\x8e"
-  "\x1e\xe7\xd8\x54\x0f\xa5\xed\x57\x6b\x87\xcd\x3b\x07\x19\x7b\x3c"
-  "\x57\x8b\xd6\x5a\xd2\xc6\xf4\x75\xff\xc2\xeb\x18\x68\x57\x51\xc8"
-  "\xb4\xbb\x5a\x93\x1b\x6c\x57\x7d\xeb\x38\x5d\xd7\xd8\x56\x20\xf9"
-  "\xdb\x20\x0c\x63\x8b\xf7\x84\x7d\x06\x5e\xdf\x55\xe2\xeb\xba\xc6"
-  "\x0b\x7f\x63\x77\xe0\xb7\x1f\x3f\x97\xf6\xdc\x82\x9f\x07\xf7\xe9"
-  "\x92\x6e\xdd\x79\xb0\x73\xae\x6b\xc4\x5c\x5f\xcd\xcf\x1e\x1a\xdb"
-  "\x20\xba\xc7\x19\xc2\xda\x7d\xdd\x97\x6c\x63\x8c\xed\x00\xfd\xf3"
-  "\x54\x3f\x30\x0c\x4a\xc0\x58\x64\x9a\x0b\xc7\x16\x11\x68\x2e\xf5"
-  "\x33\xce\xa6\xe6\x2d\x7e\xb2\x7d\x87\xdb\x7e\x5d\xca\x8a\x2d\xc2"
-  "\xe7\x07\xed\xf9\xca\x6d\x6b\xaa\x0d\x12\xaf\x31\xf7\x38\xaf\x1b"
-  "\xe7\xa1\xc7\x6a\xa4\xcc\x4f\xfe\x68\x1f\xc3\x13\x49\x92\x1f\x84"
-  "\xde\x76\x25\xcf\x9a\x77\x72\x3f\xe2\xf9\x27\x68\xb7\xf9\x34\x5d"
-  "\x27\xfb\xb3\x09\x6d\xdf\x06\x99\xc2\xb6\x53\xbd\x94\xff\xd7\x41"
-  "\xfe\xdb\x9a\xf5\xf5\xd0\x4d\x78\x07\xbb\xc9\xdb\x5a\x10\x20\x86"
-  "\x11\x02\xec\x2a\xb9\x26\xd4\xb4\x73\xad\x57\x04\x3e\x28\xed\x32"
-  "\x62\x3e\x46\x7f\x37\xef\xe4\x3a\x1d\xd0\x83\x5d\x4b\x65\xbd\x19"
-  "\x90\x55\xfe\xb8\xfd\xdf\x8f\xdb\xf5\xef\x35\x8d\x93\x72\xb1\x08"
-  "\x3a\x56\x59\x74\xbf\x5c\x7f\x50\xf5\xc9\xf5\xa6\xe8\x3e\xb9\xfe"
-  "\x20\x7e\xb3\xf1\xcb\xc3\xaf\x58\x7b\x8e\xfc\x4d\x8d\xb8\xdf\xd0"
-  "\xe3\xbc\x3e\x13\x63\xdf\xa3\x68\xcd\x69\xc0\x95\x79\xe0\x4b\x32"
-  "\xb1\xed\xcd\xfb\x0a\x9c\xce\xfc\xca\xe9\x61\xe8\x25\x78\xce\xc6"
-  "\x7b\x0b\x8f\xc5\xaa\x30\x45\xbd\x77\x6f\x00\x4f\xad\xe9\x65\xdc"
-  "\xdf\x90\xeb\x05\xeb\xca\xcb\x99\x0f\x91\x67\xa1\x39\x58\x5e\x8e"
-  "\xfa\xf6\xeb\xf4\x43\x5a\x2d\xbf\x8f\xaf\x1f\x5c\x7f\xb4\x5f\x8f"
-  "\x82\x7e\xc9\xb2\xc5\x4b\xe3\xba\x20\x7f\xd0\x57\x4d\xdb\xd5\xbc"
-  "\x31\xee\x0b\x7e\x86\xdc\x3b\x86\xfb\xce\x56\xc8\x97\xde\x8d\xef"
-  "\x76\xf5\x19\x68\x58\xaf\x81\x32\x82\x1b\xcf\xce\x0e\x26\xbf\xed"
-  "\x77\x77\xed\xa7\xb6\xe0\xdb\x64\x7b\x52\xc2\xf8\xcc\xcd\xfc\xbc"
-  "\x5a\x84\xf6\xf6\xee\x84\xad\x75\x86\x75\xb4\x6b\x4f\xd2\x38\xd9"
-  "\xf6\x9f\x1f\xc7\x0c\xfe\xa8\x84\xad\xd1\xe2\x6c\xda\xe6\xc5\x22"
-  "\xb8\xf9\x04\xc6\x47\x9f\x35\x79\x53\x2f\x4d\x78\x75\x0d\xa5\xd7"
-  "\xf6\xd2\xb8\xba\x5e\x4a\x13\x7f\x4b\x33\xd4\x42\xd7\x7a\xf4\x9c"
-  "\x85\x30\xbe\xb3\x47\x14\x91\xa9\x6e\x0d\xc9\x3e\x0f\x55\x40\xe7"
-  "\x0a\x42\xe7\x3a\x93\xc6\x72\xae\x5f\xe7\xea\xeb\x63\x9d\xeb\x40"
-  "\x97\xe2\x8b\x03\x5d\xc3\x0b\x28\x21\x25\x97\x2c\xc0\xcf\x71\x9a"
-  "\xc6\x5d\x9d\xd2\x09\x7d\x0f\x6d\xf6\x68\xed\xc5\x35\xdd\x5c\x40"
-  "\xc3\x64\x5b\x21\x7b\x45\x45\xd3\xf6\x41\xe7\x54\x03\xf3\x8e\x9f"
-  "\xf7\x80\xd0\x86\xf1\xb7\xf1\x3e\xc6\xfe\xd1\x01\xe3\x8a\x5a\xf0"
-  "\x1d\xd2\x8b\xc7\x8a\x00\xd2\xc7\x70\xdd\xfb\x90\xde\xe3\x1c\x9f"
-  "\xe9\x31\xfc\xb6\x79\x30\x79\x6b\x5e\xa7\xcf\xfb\xe3\x3f\x14\x86"
-  "\x32\xd6\xb7\xd3\xd7\x06\x85\xcf\x7d\x9a\xc7\xe0\xf8\xe6\x79\x85"
-  "\x22\x68\x5b\xca\x7b\x4a\xe3\xf7\xf3\x7e\x17\xaf\x73\xef\x81\x9e"
-  "\xf2\x75\x7b\x5c\x2c\xfb\xa1\x8f\x67\x98\x0b\x01\x13\xfa\xbe\x70"
-  "\xa4\x51\xb4\xee\x1d\x5f\xef\xe6\xbd\xd1\x97\xe4\x3e\xec\x78\xf0"
-  "\xcf\x7d\x52\x0f\x63\x7d\x8f\x65\x20\xf4\xa6\xcb\x4f\xd0\x77\xa6"
-  "\xb2\x5d\xdf\xe3\xfc\xce\x18\x0f\xcd\xd0\xf7\xf5\xe4\xfe\x2e\xd2"
-  "\xa0\xff\x65\x16\x72\x5a\xf1\x58\xb2\x16\xdb\x44\xd7\x60\xba\x8f"
-  "\xdc\x73\x35\xd0\xb7\x51\x26\x4f\x87\x83\xf9\xe6\xcd\x6e\xc3\x82"
-  "\x05\x48\xb3\xeb\x70\x90\xe7\x0a\x3c\x97\xf7\xe7\x51\x65\xb6\x44"
-  "\x94\x59\xd0\x6d\xb8\xf1\x4d\xa4\x35\xc4\x94\x39\x18\x53\xa6\x25"
-  "\xa2\x4c\x99\x56\x8f\x27\xa6\x8c\x2f\xba\xcc\x77\xe9\x42\xdc\xbe"
-  "\x9b\x1a\x5d\xe6\xbb\xe3\x62\xca\x4c\xb9\x10\xb7\xef\xce\x8c\x29"
-  "\x93\x1d\x53\xa6\x20\x82\x96\xbc\xb7\x0a\xfb\xec\xbb\x25\x31\x65"
-  "\x2a\x63\xca\xd4\xea\xcf\x83\xed\x71\xaf\xd8\x46\x56\xf0\x65\x17"
-  "\xf7\x27\xf4\x76\x6f\xf7\xaf\x9e\xea\xd1\xca\x76\xc4\x69\x97\x37"
-  "\xa6\xbe\x60\x74\x7d\x69\x29\x17\xb6\x2b\xcd\x16\x5d\x26\x2d\x3d"
-  "\xa6\x4c\x46\x44\x99\xed\xaa\x9e\xb4\xf9\x31\x65\xf2\x62\xca\x14"
-  "\x5f\xc8\x57\x69\xe5\x31\x65\xb6\xc4\x94\xd9\xf9\x35\xb4\xe0\xf9"
-  "\x58\xf9\x22\x8c\x62\x9d\xf7\x1e\xcc\xf5\x37\x5c\xc6\xb6\x0c\xe6"
-  "\x12\xdf\x6f\x7a\x03\x43\x78\x4e\xe1\xf9\xa7\xc9\x1e\x80\xbe\x94"
-  "\x16\xf0\xd0\xa4\x22\x7d\x0e\xe2\x7d\x4c\x1e\xcf\x4a\x57\x4e\xeb"
-  "\x18\x4c\xa7\xe4\x7a\x74\xdf\x04\xae\xab\x69\x0c\xeb\x5e\x37\x64"
-  "\xf6\xeb\xb6\x6a\xbf\x9e\x14\x9c\x1b\x5e\x61\x38\x5c\x7f\xbd\xda"
-  "\x1f\x4d\x60\xdd\xba\xc9\x2e\xcb\xd8\x23\xf4\x61\xae\xdf\xbf\x7f"
-  "\x4d\xc0\x18\x8d\xc7\x0d\xd9\x17\xc1\x23\x05\x3a\x8e\xbd\x0d\xfa"
-  "\x07\xef\x03\xb5\xd6\x42\x97\x81\xfe\xce\xb8\x1d\xa7\x1b\x3c\x52"
-  "\xb7\x5a\xda\x4b\x7c\xef\x2e\xb9\x43\xee\x13\x29\xdd\xf2\x46\x6b"
-  "\x33\xea\x67\x1d\xbc\xb9\xe8\x2c\x75\x4b\xfd\x9f\x75\xb0\x1b\xef"
-  "\x6d\x2a\xf1\x01\xaf\x1b\x2d\xfa\xbe\xa9\x87\x6e\xcc\x94\x7a\x43"
-  "\xf9\x47\x45\xbc\x87\xc5\xeb\xbe\x4d\xfe\xa9\x9c\x07\xfc\x7f\xc3"
-  "\x18\xbd\xbd\xb0\x01\x31\xa6\x6e\xf0\x5e\x8c\x66\xaa\x0f\x6f\x2c"
-  "\x8c\xe6\xc9\x21\xe0\x95\x1b\xcb\xa2\xfb\xfd\xc6\xea\xe8\x7e\xbf"
-  "\x71\x7b\x34\x4f\x1a\xc0\x93\x37\xee\x8f\x29\xd3\x1c\x53\xe6\x48"
-  "\x44\x99\x6a\xad\x9e\xae\x98\x32\x81\xe8\x32\x37\x99\x22\x9e\xd1"
-  "\xc6\x9b\xac\xfd\x36\x8c\xdc\x93\xbf\x29\x2d\xe2\xd9\x50\x23\xe5"
-  "\xe7\x4d\xd3\xf4\x34\xde\x47\xab\x7b\x59\xed\x09\x6b\xf0\xb2\x63"
-  "\xc6\x3b\xe7\x2f\x8c\xc6\xe1\xa6\x92\x18\x1c\xfa\xc7\x7f\x95\xb2"
-  "\xc1\xfe\x78\x82\x26\xe4\x49\x1e\xc2\x18\xc1\x7c\x3d\x8f\x9f\x01"
-  "\x6b\x0b\xf2\x83\x0e\x37\x1d\x8c\x81\xd7\x12\x03\xef\x68\xc4\xb3"
-  "\x05\xcf\xde\x88\x36\x58\x12\xad\xd2\x2f\x06\xfa\xd8\x04\xa3\x9e"
-  "\xce\xb6\x21\xf0\xed\x72\xc8\x79\x26\x83\x7d\x1d\x46\x1e\xa7\x9b"
-  "\xbe\x64\x3b\x52\xc1\x9c\x10\x39\xfe\x49\xb5\x6b\x42\x66\x34\x1e"
-  "\x13\xe6\x47\xe3\x31\x21\x2f\xa2\x5d\x7e\xf3\x3a\xba\xdf\x1c\x7c"
-  "\xe0\x27\xac\xe3\xb0\x0f\x8d\xf4\x39\x58\x0b\xbd\xec\x1c\x59\xd8"
-  "\xd7\xe3\x44\x31\x25\xba\xed\x5d\xb0\xc9\x0e\x74\x0e\xca\x4f\xc9"
-  "\x1f\x95\x69\xfe\x29\x36\xc0\x6f\xd6\xf9\x31\xbc\xf1\x23\xd8\x04"
-  "\x7f\xac\x44\x1a\xe4\xdf\x8d\x59\x6a\x8d\xfd\x50\x87\x70\x64\x6f"
-  "\x01\x3d\x61\xdf\x4c\xfc\x50\xb3\x07\x6a\xd8\x67\x01\xb2\xa7\x0b"
-  "\xf3\x7b\x8a\xda\xdf\x9a\x98\x12\xc1\xd7\x7e\xdb\x9a\xbb\xc4\x71"
-  "\x9a\xf8\x09\xcf\xff\x3c\x46\xd9\xf7\xa1\x29\xe8\x23\xb6\xa1\xdd"
-  "\xc1\x93\x52\x47\xc3\xfb\x76\xad\xec\xcc\x88\xb2\x3e\xcd\xc6\xed"
-  "\xe2\x77\x93\x83\x64\x6c\xf2\xfb\x08\x70\x52\x95\x5e\x37\xf1\x93"
-  "\x26\x8c\x57\x94\x29\xd1\xcb\xb0\x3d\xcc\x65\xcc\xc5\x64\x9c\x54"
-  "\x42\x46\xd7\x9a\xe3\x12\xb6\xd6\xf7\x5d\xac\x1f\xbb\x4b\xba\xc8"
-  "\xed\xef\xe0\xb5\x29\xa3\xda\x4b\x9e\xd8\x9e\x18\x20\x53\x77\xc5"
-  "\x47\x45\x1e\xdc\x87\x2a\x3e\xb2\x03\x37\x8c\x9f\x09\x52\xce\x45"
-  "\xd2\xee\xde\x7b\xb3\x1e\x98\x37\x67\xe2\x8f\x1f\x98\x35\xff\xde"
-  "\x3b\x6c\xf3\x97\x3c\x9d\x9f\x37\x71\xd9\xb3\xc5\xb6\x55\xcb\x97"
-  "\x14\x2f\x59\xfa\x84\x2d\xdd\x3e\xde\x6e\x5b\x54\xac\xae\x69\x85"
-  "\x8b\x56\x14\x4f\xe7\xdb\x09\xb6\xa2\xe5\xf9\x2b\xe5\xed\x0d\xc9"
-  "\x14\x0d\x64\x49\x71\xfe\x72\xdb\xf8\xbc\x09\xb6\xfb\x16\x2d\x29"
-  "\x7c\x76\x79\x7e\x5c\x58\x77\xd8\x96\xe7\x2f\xcf\x5f\x94\x67\x9b"
-  "\x6e\x4b\x67\xc8\x91\xe0\x22\xfa\x33\x5d\x9f\xc7\x78\xfe\xaa\x72"
-  "\x8a\x76\x6d\x3e\xf3\x28\xfe\x99\xb4\xe3\xc2\xb9\x6c\x52\x63\x34"
-  "\xcf\x4d\x3a\x1c\xcd\x73\x93\x3a\x2e\x9c\xcb\x26\xc5\xcc\x7f\x93"
-  "\x62\xe6\xbf\xc9\x29\x17\xce\x65\x93\x63\xe6\xbf\xc9\x31\xf3\xdf"
-  "\xe4\xfe\xf9\x0f\xbc\xe4\x59\x2f\xe5\xc2\xe4\x98\xf9\x6f\x72\xcc"
-  "\xfc\x37\xb9\x38\xe6\x79\x43\xc4\xf3\xe5\x78\xae\x89\x9c\x1f\xf1"
-  "\xbc\x43\x1f\x9f\x03\xf2\x65\x72\xa3\x9e\x87\x65\x3d\x64\x73\xa7"
-  "\x96\xb7\x3d\x22\x6f\x97\x96\xb7\xb3\x7f\xfc\x81\x8f\xd8\x47\x44"
-  "\xd9\xdd\xe9\xb3\x58\xa6\xb3\x7f\x08\xcf\x4d\x18\x1f\xd7\x9e\xa6"
-  "\xc9\x87\x18\x16\xf3\xb0\x5c\x3f\xfc\xd5\xc3\x3d\xf5\x23\xc9\xc4"
-  "\x65\xea\x5f\x24\xa3\x70\x4e\x3c\x8a\x2b\x21\x2d\x05\x3f\xc8\x94"
-  "\xf4\x0c\x8f\xe1\x77\x35\x6a\xbe\x48\xaf\x96\xfa\x3e\xca\x68\xf0"
-  "\x7f\xc1\xcf\x80\x63\x45\x19\x53\x95\x9a\x8b\x3b\x71\x9f\xc2\x3c"
-  "\x8d\xf2\x46\x61\x98\x34\x16\x57\x42\x9a\x05\xbf\x54\xc0\xab\xd6"
-  "\xe1\xf1\x3e\x58\xbc\xf1\x1f\xbb\xbe\xdc\x6f\xf3\x19\xc8\x5c\xe5"
-  "\x0c\x77\xb8\xc3\xac\x57\xa7\x37\xab\x35\x82\x03\xb0\x19\x3e\xc8"
-  "\xae\x47\x7a\x7c\x1b\xe9\x66\xe8\x7f\xe9\x8d\x6a\xdd\xe4\x66\xf4"
-  "\xff\x7d\x9d\x6a\x6d\xf3\x80\x09\xf2\xb6\xf7\x04\xdd\xfc\x3a\xae"
-  "\x7d\xb8\x56\xe8\xf0\x5d\xd2\x76\xbe\x99\xd7\x3c\x1e\x64\xb8\x31"
-  "\xe9\xd3\x20\xdf\x7a\xcd\xc1\xb2\xec\x38\xef\xb2\x85\x33\xf1\x81"
-  "\x38\xe9\x45\xd0\x19\x7a\x3d\x74\xf3\x0e\xc6\x37\x22\xbd\x5c\x38"
-  "\x47\xcc\xe7\xfc\x1e\xae\x0f\x65\x06\xd3\xb5\x75\x7f\x30\xe5\x77"
-  "\x79\xf3\x91\x98\x76\x7c\x75\x82\x6e\xb9\x5f\xb5\xe3\x96\xdd\x31"
-  "\x75\x7b\xe3\xb7\xe3\x16\x23\xda\xf1\x55\xfc\x76\xdc\x62\x93\xb4"
-  "\x35\xa0\x2d\x86\x0b\xde\x4d\x43\x5b\xbe\x92\x74\x8f\x4e\x9f\xaf"
-  "\xe9\x42\x7e\xd8\x60\x16\xbc\x93\x65\x1f\x2c\xa1\xd8\x7c\x25\xe6"
-  "\x2d\x94\x15\xa7\xce\x1a\xe1\x1c\xf6\xa0\x87\x6e\x69\x91\x70\x06"
-  "\xd2\x1b\x14\x2e\xa0\x93\x41\xd2\xc9\xcb\xe5\x06\xeb\x6f\xdd\x2e"
-  "\x51\xeb\x1a\xb7\x80\x67\x6f\xde\xa7\xaf\x49\xae\x28\x11\x3e\x9d"
-  "\x8e\x3d\xce\x5b\xad\x31\xef\x02\x11\xef\xa6\x44\xbd\x5b\xdb\x9f"
-  "\x3e\x5b\x4f\xff\x66\xfd\x74\x6b\x49\x4c\x3f\xa1\x7f\xa6\x0c\x8f"
-  "\x6e\xf7\xad\x95\xaa\x7d\xe8\xa3\x0b\x68\x7d\xeb\x4e\xf4\x51\x5f"
-  "\xfc\x3e\xba\xb5\x39\x3e\xaf\xdd\x7a\x54\xc2\x1b\x49\xf1\xe0\x05"
-  "\xd0\x77\x7d\x92\x07\xb5\x7e\xba\xb0\x7f\xa6\x8c\xd1\xfb\xe7\x9b"
-  "\xb5\x71\x4a\x6e\x4c\x1b\x43\x80\xf1\x99\x6a\xeb\x6d\x13\x63\x60"
-  "\xdb\xe3\xf3\xe2\x94\x6a\xb4\x33\x14\xbf\x9d\x53\x1a\x06\xe7\xc5"
-  "\x29\x87\xd1\x9e\xd0\x85\xbc\x88\xee\x93\x65\x28\x5e\x99\xa0\x70"
-  "\xc6\xab\xe7\xb6\x54\x47\x90\xf5\xdc\xdb\x66\xf3\x1a\x52\x44\xfa"
-  "\x84\x68\xfe\x43\x1b\xb8\x1c\xd3\x2f\xa8\xe4\x2c\xf7\xc3\x09\x1b"
-  "\x19\xbe\x8e\x27\x7b\x9c\xb7\x55\xc6\xd0\xea\xcc\x09\xfa\xde\xf0"
-  "\x6e\x43\xc2\x0e\x45\xaf\xef\x7d\x12\x83\xd3\xce\xf8\xf4\xba\xcd"
-  "\x05\x7a\x9d\x89\x4f\xaf\xdb\x8e\x0e\x4e\xaf\xdb\xb8\xff\xcf\x5c"
-  "\x48\xaf\xef\x59\x22\xe9\x05\x5d\x57\xb6\xef\x7a\x2b\x78\xa3\x2f"
-  "\x47\xf0\x1a\x1c\x68\x62\x31\x83\x57\x54\x19\x2f\x97\xc9\x34\x07"
-  "\x14\x9f\x40\x87\x34\x9d\xa6\xef\x4d\xd0\xc7\xff\x88\x2d\x34\x4c"
-  "\xf4\x3d\x2c\x00\x2f\x81\xcb\xb9\xed\x67\x5c\xee\x60\x3a\xb1\xfd"
-  "\x11\x53\x6f\x79\x7c\x59\xf0\xbd\xed\xa0\xe9\x8b\x71\xd2\x1b\x95"
-  "\x4f\xc8\xf7\x7c\xd1\x32\xe2\x7b\xed\xd1\x7d\x04\xba\xa1\x1c\x0d"
-  "\xf8\xb4\x5f\xf4\x77\xf1\x3e\xfb\x7e\xc6\x85\x7d\xf6\xfd\x63\xaa"
-  "\xbf\xbe\x7f\x28\x1a\xbf\xef\x67\xc7\xef\xaf\xef\x17\x0d\xde\x5f"
-  "\xdf\xaf\x1c\xbc\xbf\xbe\xcf\xeb\xa1\x67\x3c\xf4\x7d\x4f\xf4\xbc"
-  "\xf1\x7d\x57\x74\x7b\x51\x2f\xca\x09\xc3\xd0\xcb\xf9\xf9\x9b\xb6"
-  "\x5b\xff\xb1\x8c\xe3\xbe\xaa\x2f\x25\xf0\x72\xc2\x58\xc6\xf1\x52"
-  "\x61\x0c\x0a\x1b\x34\xac\x5e\x13\x7f\x7f\x94\x6d\xdc\xb6\x2d\xc4"
-  "\x7b\xe1\x64\xbb\x86\x75\xf7\xa9\xef\x84\x0d\xd4\x81\x7b\xc3\x09"
-  "\xba\x63\x5d\xd8\x60\x28\x61\x3f\x4b\xe9\x5f\x29\xd7\x10\xa6\xb6"
-  "\x44\xf6\x05\xfb\xe2\xb0\x6d\xba\x59\xd9\x4e\x7f\x3d\x41\xb7\x2f"
-  "\x50\xfd\x72\xc7\xa2\x68\x3a\x4e\xf5\xc5\xef\x97\xdb\x4d\xe8\x97"
-  "\xbf\xc6\xef\x97\xdb\xc7\x0d\xde\x2f\xb7\x67\xa0\x5f\xfe\x7a\xe1"
-  "\x38\xba\x3d\x5b\x1b\x47\xeb\xb9\x8c\x6d\x29\xdb\xe3\xb7\xff\x89"
-  "\xf3\xe0\x1e\x63\xe4\xf6\xb7\xf8\xfd\x44\x2f\x45\xf4\xe5\xed\x95"
-  "\x80\x25\xeb\xd7\xf2\x94\x6b\x30\x22\xe1\xee\x33\x7b\xe3\x8d\x93"
-  "\xdb\x0f\x73\xde\x49\x45\x64\x02\x0d\xb3\xb7\x31\x8c\xe5\x44\xa7"
-  "\xe9\x8e\xab\x39\x1f\xa7\x4f\xf2\x47\x8e\x93\xdb\x03\x7a\x3e\x96"
-  "\x75\x2a\xef\xed\x3e\xd1\x53\x40\x9c\x2f\x1a\xf6\x1d\x5a\xfb\x87"
-  "\xc9\x79\x84\xf3\x73\xbe\x98\x3c\x33\xd5\x78\xbc\xa3\x32\x7a\x3c"
-  "\xde\x91\x1b\xcd\x9f\xa0\x3f\xca\x85\x21\xe7\x70\xbf\x1f\x38\x7c"
-  "\x63\xfe\xba\xf8\xd8\xbc\xe3\x68\xcc\xd8\x04\x0f\xfc\x60\xad\xe2"
-  "\x81\x1f\x3c\x12\x83\xab\x3f\x3e\x0f\xfc\x20\x65\x70\x1e\xf8\x41"
-  "\xda\xe0\x3c\xf0\x83\x4c\xe6\x01\x0f\xfd\xa0\x24\x7a\x6c\xfe\x60"
-  "\x61\x74\xdb\xef\xf0\xab\xb1\x49\x97\x5d\xca\xd8\x84\x2e\x74\xf9"
-  "\x60\xe3\x90\xc7\x14\xea\x4e\xa8\xef\xd5\xf7\x33\xbe\x11\xcd\x4c"
-  "\x18\x57\xc0\x6f\x9a\x85\xd7\x94\x20\xe3\xa7\x32\x0d\xeb\xe4\x59"
-  "\x9b\x69\xe3\x22\xe9\xb8\x59\x9d\x7b\x71\x20\xef\x1b\xbc\x3f\xac"
-  "\xe8\x39\xfd\x99\xe8\xf6\x4f\xcb\x8c\x4f\xcf\x69\x0b\x41\x4f\x47"
-  "\x7c\x7a\x4e\xb3\x0f\x4e\xcf\x69\x35\xec\xb3\x7f\xe1\x98\x9a\xd6"
-  "\x60\x5b\x29\x75\x14\x59\xe6\x34\x4d\x1f\xf2\xcd\xe6\xa7\x69\x9d"
-  "\xd1\xf3\xd3\xb4\x96\x4b\x9f\x9f\xa6\xa7\xc5\x9f\x9f\xa6\x67\xc4"
-  "\x9f\x9f\xa6\x67\xab\xf1\x30\xbd\x3a\x7a\x3c\x4c\x2f\x8a\xe6\x09"
-  "\xd0\xee\x7f\x6d\x7e\x9a\xee\x89\x19\x03\x55\x27\xe8\xce\x45\xd0"
-  "\x29\xca\x54\xbf\xdd\x35\x3e\x06\xc7\x60\xfc\x7e\xbb\x33\x15\xfd"
-  "\x56\x15\xbf\xdf\xee\x4c\x1f\xbc\xdf\xee\x9c\x8d\x7e\xab\xba\xb0"
-  "\xdf\xee\xcc\xbb\x74\x9d\xe2\xce\x2d\xd1\x7d\x76\x67\xd9\xa5\xf7"
-  "\xd9\x9d\x47\xe3\xf7\xd9\x9d\xfe\xf8\x7d\x76\x57\x8a\xea\xb3\xbb"
-  "\x32\xa3\xfb\xec\xae\x71\xd1\x7d\x36\x3d\xf8\xf7\xf6\x19\xfa\x27"
-  "\x45\xf9\x19\xdc\xf5\x3a\xec\xf6\x61\x3d\xce\xbb\x6a\x3d\x94\xa1"
-  "\xed\xe1\x66\xa8\xb9\x43\xf5\xe1\x5e\xe4\xa9\xbe\x70\x1e\xb8\xab"
-  "\x51\x4b\xfb\xf1\x85\xfd\x70\xd7\x11\xc8\x68\x6f\x73\x89\xdc\xd7"
-  "\x52\x7d\xc8\x34\x47\x3e\xd7\x1a\xde\x9b\xba\xcb\xcf\x65\xd1\xc7"
-  "\xc2\x1d\x08\x12\xcb\x75\xe4\xf7\x33\x1c\x3e\xab\x14\x0d\x2b\xc3"
-  "\x76\x29\x73\xfc\x45\x7c\x63\x52\x5c\xa5\xb7\x00\xde\xdd\xb7\x29"
-  "\x5e\xcd\x88\xd5\x7f\xeb\xf1\x2e\x49\xf1\xe9\x3d\x7f\x89\xc1\x61"
-  "\x47\x7c\x3e\xcd\x38\x88\x36\xd4\xc7\xe7\xd3\x8c\x8e\xc1\xf9\x34"
-  "\x83\x65\x66\x7d\x84\xed\x33\xf2\xd1\xa0\x27\x86\x67\xef\xb6\x9a"
-  "\xfd\x8a\x77\xa4\x4e\x54\x71\x20\xa5\xc7\x79\x77\xac\xfe\x87\xbe"
-  "\xb9\xfb\x3d\x0d\xe7\x77\x62\xca\x0f\xa2\xff\xdd\xcd\xfa\xdf\xde"
-  "\xf8\x38\xdf\x7d\x11\xfd\xef\x6e\xd6\xff\xf6\x5e\x38\xb6\xee\xd6"
-  "\xf4\xbf\x78\x36\xde\xdd\x47\xe3\xf7\xff\xdd\x31\xfd\x4f\xd9\xc5"
-  "\xb0\x87\x65\xf9\xa8\x7c\xf7\x8c\x89\xcc\xc7\x3e\x46\x9c\x97\x79"
-  "\x24\x4e\xde\x99\xb1\x30\x07\xc9\x57\x74\x01\xef\xb1\x4f\x54\x5c"
-  "\xde\xbb\xa7\x56\x8d\xc7\x7b\xfc\xd1\xe3\xf1\x9e\xfd\xd1\xe3\xf1"
-  "\xee\xec\x98\x72\x47\xa2\xdf\x83\x7f\xfe\xd7\x64\xec\x8c\xcc\x18"
-  "\x1e\xf8\xe0\x04\xcd\x38\xa4\x78\x20\xf3\xca\x68\x3c\x66\x2c\x8c"
-  "\xcf\x03\x33\x8a\xd1\xfe\x0f\xe2\xf3\xc0\x8c\xea\xc1\x79\x60\x46"
-  "\x03\x68\xf9\x41\x24\xdf\x3e\x58\x92\x31\x2c\x26\x4f\x7b\x7c\x99"
-  "\x37\xa3\x2b\xfe\x1a\x41\x26\x29\x1a\x67\x4e\x8d\xa6\x71\xa6\x35"
-  "\x9a\x86\x68\xcb\xdf\x4f\xc3\xfe\xb3\xbe\x3d\xce\xcc\xd8\xf1\xef"
-  "\x3e\x41\xf7\x6a\xe3\xff\xbe\x18\x59\x97\xb9\x43\xe1\x12\x6f\x5d"
-  "\x24\x93\xed\x5f\x77\x7c\x5a\x66\x1e\x1d\xa4\xcd\xec\xd3\xe6\x0e"
-  "\x5f\x30\x96\xee\x4d\x41\xfa\x83\xbc\x1e\xca\xeb\x21\x75\x48\x7f"
-  "\x30\x48\x26\x39\x5f\xf5\xcf\x4b\xf7\xf2\xd9\x4b\xc1\xf4\x67\xfe"
-  "\x35\x8f\xa1\x2c\x9e\x83\x18\xaf\x9c\x12\xe9\xb3\x60\xde\xc0\xbc"
-  "\x7e\x1d\xf3\xfa\xbd\x52\xff\xe3\x7d\x16\xf6\x07\x34\xdb\x29\xcb"
-  "\xed\x0f\x92\xce\xef\x9c\x3f\x06\x76\x25\x8f\x0b\xce\xaf\xe7\x55"
-  "\xeb\x66\x65\xb1\x78\xee\x8f\xdf\xc7\xf7\xb6\x0c\xce\x3b\xf7\x76"
-  "\xa9\x7e\xbe\x6f\x4c\x74\x3f\xdf\x07\xfd\x6f\xc4\x7c\x6e\x2b\x78"
-  "\xe0\x92\xc6\x49\xb1\x4d\xf8\x06\x95\xf7\xeb\x1f\xee\x28\x2a\xa5"
-  "\x6b\x4e\xd2\x7d\x1b\x64\x7d\x06\x11\x30\xaf\x4b\xa0\x66\x29\x03"
-  "\xee\xfb\x0f\x89\x27\xf2\xe4\x04\xc9\x20\xd6\x3f\xd5\xc1\xef\xea"
-  "\x9d\x22\x80\x7c\xed\xbc\x27\xc0\x67\xfd\xc0\x0b\x97\x1f\xa7\xfb"
-  "\xb6\x45\x95\x37\x12\xb9\x15\x8c\x8e\x7a\x39\x1e\xef\x3b\xa2\xaf"
-  "\xe9\x6e\x18\xc4\x3f\x08\x79\x02\xba\xef\x83\xf2\xfd\xba\x6f\xd0"
-  "\xfd\x4b\xc6\x89\xfd\xe3\x19\xa7\x8b\xcb\x81\x1f\xce\xd6\xf9\x57"
-  "\xf9\x4c\xfe\x70\xe1\x80\x4f\xde\x0f\x0b\x3c\xf4\xc3\x41\xcf\x73"
-  "\x44\x8f\x83\x1f\xd6\x44\xc2\x51\xe7\xdd\x7f\xb8\x53\xf7\xab\xc3"
-  "\xfd\xfe\xaf\x81\xa5\xe3\x73\x34\x06\x1f\x2f\xf4\x94\x66\x0d\x46"
-  "\xe0\x62\x30\xb8\xcf\x15\xcf\x32\x3f\xcc\xb4\x5c\x6c\xcd\x2f\xd1"
-  "\x4a\x59\x2f\x5d\xc0\x5b\x33\xa5\xbe\xc4\x30\x2e\x8e\xe3\xcc\xb2"
-  "\x28\xdb\x42\xee\xdd\xf3\xde\xd6\xac\x39\x6a\xdc\xcf\x8a\x59\x23"
-  "\x9c\x59\x2b\xfd\xa6\xb4\x71\xff\x68\x30\x76\x1c\xcc\x3c\xa8\xcf"
-  "\xd1\x31\xe9\x47\xf4\x71\x0f\xbb\x96\xe1\xc6\xac\xb3\xce\xf4\xab"
-  "\xb1\x30\x6b\x76\x38\x29\xd2\x5e\x9b\x25\xf5\x3f\x7d\xbd\xd4\x83"
-  "\x7c\xd1\xe5\x66\xc5\xac\xff\xcd\xac\x15\x83\xaf\xd3\xa7\xa0\x7f"
-  "\xfd\xbc\xb7\xa5\xce\x0e\xcf\x2a\x89\x59\xaf\xf0\x6d\x96\xe7\x44"
-  "\x3f\x05\xdc\x1f\x69\x72\xef\x47\x5f\xc6\xd4\x57\xeb\x38\x75\xb1"
-  "\xf6\xcf\x1a\xa4\xfd\xb3\x06\xda\xbf\x54\xc2\x8d\x59\x4b\x9c\x25"
-  "\xdb\x1f\xba\x40\xfe\xfd\x28\x05\xf2\x4b\xa7\x1b\x74\xee\x1f\xe5"
-  "\xeb\xba\x3a\xaf\x1f\x0c\xae\xab\xff\x68\x60\xfd\x4f\x95\x1b\x58"
-  "\xff\xf3\xc5\xd3\xd5\x3d\x24\xf7\x56\xa3\xeb\x2e\x37\xd7\xc6\x6b"
-  "\xcb\x8f\x06\x59\xff\xfb\x91\xb6\xfe\xf7\x4f\x96\x68\x79\xf6\xa3"
-  "\xf6\xe8\x3e\x9c\x15\xd3\x87\x3f\xf2\x45\xf7\xe1\xac\xda\xff\xe9"
-  "\xbc\xc6\x13\x67\x62\x62\xa2\x21\x31\xc1\x90\x90\x88\xd7\x68\x22"
-  "\x0d\x4b\x34\x26\x0e\xc1\x6f\xa8\x76\x1d\x66\x48\x34\x18\xf1\x1b"
-  "\xa2\x5d\x87\xc6\x3c\x0f\xe3\xb2\xf8\x19\xb5\xeb\x90\x98\xe7\xa1"
-  "\x5f\xf3\x7e\x98\x56\xaf\x5e\xbf\x31\xe6\x79\xc8\xd7\xbc\x1f\xfa"
-  "\x77\x96\xa7\x0b\x9e\xa3\xfd\xd0\x66\x2d\x5d\xb9\xa8\x70\x49\x9e"
-  "\xdc\x2f\xce\xb7\x2d\x7a\xfc\xf1\xfc\x15\x2b\x6c\xc5\xcb\x6c\xf7"
-  "\xdc\xfd\xc0\x2d\x77\xd8\xd4\xb6\x73\xe1\xf4\xf1\x79\xc9\x34\x67"
-  "\xd5\x72\x7e\x31\xe7\xc1\x59\xd9\xb6\xac\x7b\xee\x8e\x7e\xa9\x83"
-  "\x91\xdb\xcb\x17\x83\x12\x31\xfe\x32\x2a\x46\x11\x55\x8e\x92\xb2"
-  "\xa7\xb3\x75\x3b\x91\x5a\xf3\xb8\x7f\x51\x0b\xb4\x09\xd1\xeb\x10"
-  "\xae\xeb\x78\x4f\x7f\x8e\xf4\x11\x9e\xb8\xbd\x8c\x8a\x16\xf3\x79"
-  "\x93\x39\x37\x8b\xf7\x7d\x64\xfb\x11\x19\x8e\xd3\x43\xcf\x34\x43"
-  "\xab\xe5\x67\x77\x67\x90\x6c\x0e\x32\xa1\xfc\x65\x78\x97\x20\xee"
-  "\x0c\x23\xcd\xaf\xf9\x34\x67\x8d\x95\x69\xef\x97\xe9\xf9\xcc\x27"
-  "\x68\xce\x5f\xc4\xfb\x42\x3e\x8b\x3b\xab\xb5\x7c\x73\xde\x08\x3b"
-  "\x67\x17\xb0\x6c\xa8\x7d\x91\x8c\x75\x2f\x12\xbd\x32\x92\x4c\xaf"
-  "\x8c\xe2\x33\xf4\x73\x6a\xf5\xbd\xd0\x0a\x3c\x7b\xe8\xa1\x22\xae"
-  "\x9b\xf3\x86\x0d\xb3\x5f\x94\xf9\x47\x46\xe5\x6f\x19\xd8\x8b\x9d"
-  "\x53\x6b\x40\xbe\x79\x9f\x93\x39\x90\xfc\x76\x97\xbb\xa4\x8c\xcc"
-  "\x21\xf1\xe5\xa4\x99\x94\xd0\x86\xd9\x77\x75\x50\x04\x5d\xcb\x4f"
-  "\xa2\xfe\xb9\x57\x9a\x57\x8b\x2f\xdd\x18\xfd\x73\xbc\x0e\xb1\xf9"
-  "\x14\x19\x31\xae\x13\x5c\xcb\xd9\x4f\x61\x2e\xd5\x7d\x45\x46\xd0"
-  "\x60\xcc\x49\x9a\x97\x5e\x32\x47\x84\x1c\x73\xc8\xf8\xaf\x76\xf6"
-  "\x37\x3c\xf0\xc2\xe6\x3f\x93\x71\x57\x6f\x99\xa1\x57\x58\xa9\xa4"
-  "\x58\x74\x09\x8e\xad\xe1\x17\x01\xf6\xd7\x6f\xc9\x0d\x71\x9e\x95"
-  "\x3d\x0e\x2b\xb5\x15\xfb\x69\xed\x51\x11\x28\xff\xb3\xf2\xf3\x6f"
-  "\xf5\xfa\xd9\x7f\xd1\xb4\x76\x0e\x25\x9e\xc8\x26\x43\x6b\xc1\x16"
-  "\x72\x2f\xf4\x53\xc9\x51\xd1\xd5\x92\xfb\x39\xb5\x15\xec\xa3\x9c"
-  "\x0e\x32\xb4\x74\x7e\x46\x32\x3e\xc4\xc6\xb3\x19\xa5\xe7\xc8\xba"
-  "\x76\x09\xa7\x9d\xa3\x35\x6b\x69\xf8\x9a\xbf\x90\xd9\xdd\xd5\x81"
-  "\x7a\x4e\xd1\x4f\x8f\x50\x02\xe0\x19\x9e\xfb\x8c\xac\xcf\xfd\x84"
-  "\xfd\x79\x33\xa8\xb6\x94\xac\xc2\x91\x96\xd2\xeb\x48\xb3\xf4\x8a"
-  "\xb4\x91\x3d\x8e\xb4\xd4\xb6\x22\xe4\xef\x7c\x8f\x46\x74\x50\xea"
-  "\xfb\x27\x3b\x0c\x5b\xce\xd2\x18\xdb\x5c\xee\xff\x79\x13\x6a\xcf"
-  "\x22\xff\xc6\x8f\x5d\x61\x94\x8d\x2c\x13\x4c\xfa\xb8\xc3\x9d\x1d"
-  "\xa0\x30\x60\x6d\xe9\xa5\x31\xb5\xbd\x64\x0d\x57\x7c\xec\x62\x5a"
-  "\xf4\x6d\x7c\xb7\x0b\xb2\x70\xd8\xde\xc7\x1a\x8d\xee\x16\x2f\xb5"
-  "\xfa\x7b\xa9\x8d\x3e\x25\xb7\xfd\x6f\xae\x5d\x8f\x35\x0e\x09\x83"
-  "\xf9\x5d\x6b\x3a\x01\x5f\xf1\x8c\xa3\x95\xcf\x25\x96\x51\x55\x29"
-  "\xa5\x14\xad\xa1\x61\x27\x91\xae\x6c\xfa\xdd\x3e\x77\xf0\x6f\xae"
-  "\x35\xd2\x07\xf7\xa1\xa2\xd2\x56\x4a\x6c\xf3\x6f\x61\x5f\x4f\x43"
-  "\x28\xf9\x6c\x86\xdb\xdf\x4e\xee\xa2\xbf\xba\xc2\xa6\xb3\x69\x95"
-  "\x61\x32\xed\x3e\xdf\x6e\x70\x1b\xcf\x93\x3b\xdb\x4f\x1f\xa0\x6e"
-  "\xb1\xf1\xec\x6c\xc8\xab\x8c\x36\x7f\x80\xcf\x25\xa5\x8b\x6e\x6b"
-  "\x72\xd5\x72\x9a\x50\x77\x96\xc6\x6d\x3b\x4b\x69\xa2\x27\xcd\xc0"
-  "\x7e\xb5\x8f\x9c\xb2\xd0\x36\x5c\x53\x3a\xc9\x84\xf6\x2a\x9f\xea"
-  "\x24\xcd\xbf\xb6\x2f\x8d\xea\x7b\x07\xfc\x6b\x7b\xbb\x07\xfc\x6b"
-  "\xc1\x4b\xdb\xd9\xc7\x16\xe3\x22\x9b\xf9\xb9\xea\x34\x19\xd7\x9f"
-  "\x26\x9a\x54\x66\x20\xdb\x63\x7c\x3e\xe2\xfe\x21\xee\xbc\x53\xf2"
-  "\xfe\x38\x65\x1d\xc4\x35\x05\xbf\x04\x8c\x01\xb9\x9e\xdd\xa9\xf1"
-  "\x2d\xd2\x0c\x48\x7b\x1d\xd7\x44\x5c\xb7\x39\x6a\x85\x4f\x94\x1f"
-  "\x9c\xd6\x6d\xa0\x64\xe6\x5f\xe5\xcb\x7b\x70\x5a\x8f\x33\x0b\xfa"
-  "\x4f\x7e\xaa\xce\xc7\x4a\xa6\xcf\xd9\xfe\xc1\x89\x53\x1c\xaf\xc5"
-  "\x27\xf1\xe9\x2b\x48\xe0\xd8\x2d\x5a\x3a\x70\xc8\x0a\x71\xbd\xa8"
-  "\xdf\x83\xab\x19\x3f\x8c\xcb\xac\x62\xbd\x6c\x77\x5f\x01\xd7\x79"
-  "\x0e\xe9\x42\x4f\x47\x7b\x8d\xfc\xee\xf7\x27\x4e\x19\x54\x9e\x34"
-  "\x03\x60\x06\x34\xf8\x18\xeb\x73\x32\x79\x4c\x77\x1b\xcc\xa2\x29"
-  "\x6f\x0a\xd5\x8e\x12\xed\xdb\x5e\x16\xcd\x6a\xac\xdd\x3f\xd5\x43"
-  "\x8b\x6d\x8c\x23\xe6\xed\xe6\x4a\xbc\x6b\xb2\x11\x31\x5d\x9a\x73"
-  "\xd9\x7f\xec\xfe\x6c\x0f\x25\x1f\x8d\x6c\x83\x70\xfe\xd3\x4c\x9e"
-  "\x3b\xf7\x94\xba\x86\x08\xc3\xec\x99\x6d\x1e\x2f\xed\xea\xed\x1a"
-  "\xe2\xf8\x13\x19\xdc\xc1\xe3\x34\x39\x95\xac\xac\xff\xd5\xbf\x2c"
-  "\x3c\xb8\x76\xb1\x3f\x27\xf8\xe4\xea\x93\x74\xff\xeb\x37\xa5\x52"
-  "\xea\xbf\xd9\x49\x93\x47\xf7\xbf\x17\x21\x8f\xee\x6d\xed\x6c\x8c"
-  "\x90\x45\x0b\xce\x5d\x28\x8b\xe6\x7f\xa9\x64\x91\x08\x2a\xd9\x13"
-  "\xf2\x68\xe9\x9f\xc5\xa4\x6b\x7e\x21\xf3\x0f\xc5\xa4\x07\xb4\xf4"
-  "\xdd\x31\xe9\x3e\x95\xfe\xe0\x29\x5d\xd6\xb5\x31\x1e\xab\x58\xd6"
-  "\x3d\xf8\x09\xcb\xba\xb6\x3c\x4d\xd6\x49\x1f\xc3\x07\xdf\x11\xbf"
-  "\x2e\x23\x3e\x7b\x84\xfb\x4d\x8c\xbf\x78\x9f\x74\xdc\x93\x90\x36"
-  "\x87\xd3\xaa\x3f\x25\x23\x7e\x52\xce\x09\xe7\xec\xbd\x2c\xe7\x58"
-  "\xc6\xb1\xdf\xc9\xd6\x51\xa2\x63\xeb\xcb\xe2\x48\xed\xcb\xa2\xa5"
-  "\xc7\xf9\xc0\x41\x5d\xde\xfd\x1c\x69\x95\x48\xfb\x39\xde\xb3\xdc"
-  "\x63\x9a\xb4\x66\x37\xf2\x39\xfd\x4e\xf0\xf1\x06\x73\x02\x15\x6d"
-  "\x06\xcf\xf3\x79\xc0\x0d\xa0\xaf\x1b\x32\x89\xcf\x72\xc9\x38\x27"
-  "\x86\x74\xc8\xa8\x4e\x1e\x6f\xa3\xd6\x63\x7c\xb9\xed\x9f\x53\xa9"
-  "\x5f\x9c\xe4\x73\x71\x8c\x43\xce\xea\x1f\x71\x1c\x8f\x84\xe6\x02"
-  "\x22\xf6\x01\x67\x7f\x15\xc8\x5d\x63\x35\x70\x6a\x2a\xe4\xbe\x7e"
-  "\x10\xf6\xff\x2b\xda\x79\xa4\x87\x8a\x38\x2e\xd0\x71\x7a\xa0\x1c"
-  "\xf6\x5d\x80\xdb\x66\x0e\x95\x11\x9f\x5f\xc1\x18\x65\x1b\xaf\x60"
-  "\x2b\x7e\xd5\xfa\x19\x16\x8e\xed\x84\x3c\xee\x8e\x00\x31\xce\x1e"
-  "\x7a\xe0\x48\x6b\x49\x23\x97\xb7\x33\x6d\x84\xd3\xa1\xc3\x48\x90"
-  "\x67\x60\x9c\x64\xe2\x33\x30\x1e\x7a\xb0\x40\x96\x4f\x7e\xb7\xab"
-  "\x75\xa1\x8f\x58\xce\xbb\xbb\x00\xa3\xe4\xb8\x82\x01\x58\x02\x72"
-  "\x3f\xea\x9d\x06\x7f\xf8\x5a\xf1\x25\xe0\x67\x72\x7f\xf1\xb9\x45"
-  "\xde\x5f\x03\x5d\x52\xd8\x2f\x5e\xe9\x9e\x0f\xb4\xd6\x7f\x4a\xa4"
-  "\x9d\xbd\x04\xbf\x3d\xd0\xc2\xe7\x8d\xf8\xbc\xa5\x3c\x6b\x69\x98"
-  "\x42\x62\x55\x5a\x4a\xff\x79\xcb\xff\x1f\xce\x5a\x82\xfe\xd6\x3a"
-  "\x83\xd8\x07\xfc\x5b\xf8\xbc\x25\xf0\x9f\xc0\x7c\xa8\xb5\xa9\xfd"
-  "\x97\x3f\x95\x34\x4f\xe5\x34\xd8\x8a\x87\xf5\xfe\xe7\xf6\x72\x5b"
-  "\x8e\xd3\xfd\x01\xa5\x13\x8a\x76\x0f\xcd\x6f\xe7\xf7\x48\xeb\xe4"
-  "\xfc\x93\x21\xc7\xdc\x79\x21\xda\x7b\x22\x64\xa8\x5a\x43\x46\x25"
-  "\xd3\x16\x7c\xc1\xe5\x95\x4c\x5b\xb0\x7d\x40\xa6\x2d\xf8\xa5\x92"
-  "\x69\x8a\xc6\x4a\xa6\x2d\xa8\x50\x32\x6d\xc1\x3a\xb9\x0f\x06\x99"
-  "\xc6\xef\x58\xae\xe9\x32\x6d\xdb\x28\x71\x98\x65\x47\x8f\x73\x41"
-  "\x91\x2e\xdb\x36\x21\x8d\x65\x07\xe3\xa8\xe4\xd4\x83\x87\xc5\xff"
-  "\x97\x46\xca\xcf\x80\xef\x0b\xf8\xac\x42\x97\x76\x8f\x7e\x59\x70"
-  "\x4c\xc9\xb8\x05\xcd\x03\x32\x6e\xc1\xcc\x81\xb2\x2c\xe3\x16\xfc"
-  "\x87\x92\x71\x2a\xbd\xfe\xa7\x2c\xe3\x1e\x3c\xcc\x34\xd0\xe0\x1b"
-  "\x78\xcd\x4e\xcb\x0f\x3a\xde\xdf\x1e\x29\xe3\xa2\xc7\xd7\x43\x63"
-  "\x74\x19\xc7\xb2\x0d\xcf\x13\x20\xd3\x64\x9c\x31\x1e\x67\x35\xa0"
-  "\xb9\x3e\xee\xb8\x0f\xb8\xcd\x1c\xff\x87\xe9\x36\xe3\x14\x0d\xd3"
-  "\xce\xfd\x68\xed\x7e\xa8\x40\xf7\x75\xf4\xd0\x82\xa2\x78\x7a\xb3"
-  "\xae\xa7\x81\x1f\xaf\x0d\x61\xbc\xb9\xcb\x30\x97\x6e\x11\x65\x6d"
-  "\xc1\x23\xf4\x68\x31\x19\xc2\x89\x4f\x1d\xe3\xbe\x85\x9d\x31\x94"
-  "\xaf\x2c\x7b\x30\x87\xee\xce\xf1\xd3\x50\xd8\xe6\xc7\xaa\x0c\x78"
-  "\x67\xa7\x1f\x44\xbc\xfb\x13\xd7\x13\x51\x6e\x62\xc4\xbb\xcf\xa5"
-  "\x8e\x77\x9a\x63\x3f\x3d\x54\x3d\x98\xed\x7f\x69\xb8\xfc\xf8\xf6"
-  "\xc1\x71\xf9\xf1\x82\xc1\x71\xf9\xb1\xd4\x03\x26\x7a\x29\x01\xb6"
-  "\xd9\x65\xa7\xe9\xc7\x72\x3d\x46\xc6\xae\x58\x1f\xb7\x9e\xd7\xb4"
-  "\xf7\x43\x22\xde\x47\xd6\x75\x28\x4e\xf9\xc8\xfa\x8e\x5d\x1c\x7e"
-  "\x76\xc2\xc5\xe1\x67\x8f\xbd\x38\xfc\xec\xbb\x59\x06\x82\x76\xe6"
-  "\xb0\x21\x3a\xdf\xa4\xa0\x1c\x83\x87\xf9\xdc\x1d\xf2\x2d\xd1\xd6"
-  "\x7c\x8e\x39\xc6\x4a\x5b\x50\x9e\xcd\xda\x8c\xf7\x7c\x96\x9c\xe5"
-  "\x73\xe6\x6a\x22\xb5\x47\xdd\x5f\x66\x5b\x2c\x6e\x23\x82\x3a\x6e"
-  "\xf2\xfd\x7b\xb1\xb8\xe1\xfd\xc4\x88\xf7\x9f\x0d\xf4\x7b\xf6\x45"
-  "\xfd\xeb\xdd\x5b\x88\x38\x86\x5e\x13\xcc\x17\xcc\xc9\x1c\x8f\x4b"
-  "\x5b\x9f\xf9\xc9\x14\xc8\xf9\xb2\x08\xbf\x5d\xf6\x39\xbb\xb6\xcd"
-  "\xcf\xe7\x54\xfd\x32\x56\x0a\xda\xf2\x6d\xcc\x27\x23\xf9\xac\x0e"
-  "\x9f\xdb\xc9\x09\x65\x19\x54\x4c\x9c\x9f\x14\xe9\x65\x07\x5b\x07"
-  "\xe2\x7a\xb5\x3a\xd9\x07\xd6\x8f\x32\x3b\xf4\x32\x0c\x9b\xfd\x28"
-  "\x31\x0f\x5c\x2b\xcf\xae\x06\xbd\x2c\x77\xbf\x0d\x3d\x79\xa4\xaa"
-  "\x27\x97\xb4\x7a\x60\xc7\xfe\x38\xe5\x62\x67\x47\x06\x6f\xdf\x4f"
-  "\x53\x2f\xbd\x7d\xa4\xb5\xef\xa7\x59\x5f\xd3\xbe\x8b\xd5\x5b\x79"
-  "\xe9\xf5\x5a\xf4\x7a\x0f\x5f\x3a\x5d\x7f\x1a\xfc\xe6\x74\x4d\xd7"
-  "\xe8\xfa\x70\xfa\xd7\xd0\x35\x4e\x3d\x0f\xe7\x7d\xf3\x7a\x6c\x7a"
-  "\x3d\x5b\xe2\xd5\x43\xf2\x6f\xd0\x73\x5d\x26\x3d\x36\x1d\xc7\x85"
-  "\x54\x31\xa9\x1e\xf6\x44\xc6\xce\x54\xf1\x22\x1f\xf6\xeb\xb1\x33"
-  "\xb5\x18\x96\x98\x5b\x16\x5e\x96\xb3\x9d\xf5\x11\x11\xf6\xd0\xc2"
-  "\x54\x8e\x7b\x98\xb9\x36\x32\xc6\xe4\xc2\xb4\x8b\xc5\xec\xe4\x58"
-  "\x39\x42\x64\x53\xd3\x16\xe9\x0f\x80\x79\x68\xe1\x22\x3e\x1f\xa0"
-  "\xf6\x33\x17\x16\xaa\x31\xb9\xb0\xd0\x43\x0f\x37\x0e\x0e\xe3\xa3"
-  "\x7d\x3b\x4a\xd3\x87\x0c\xe6\xf3\x8f\xf2\x0d\x1e\x7a\x42\xae\x5f"
-  "\x86\x36\x36\x37\x8a\x33\x56\x2d\x16\x57\x4e\x52\x44\xac\x30\xcc"
-  "\xdd\x8f\xde\xae\x9d\x4d\x00\x0d\xca\x40\xcb\x85\x9d\x3a\x0d\xf4"
-  "\x74\xa4\x05\x74\x1a\x40\x5f\x49\x71\x6f\x0f\xf2\xd9\x21\xbf\x3a"
-  "\xef\xfd\xc8\xd5\xa2\xe2\x23\xed\x7c\xe4\x23\x6a\x9f\x21\xb9\xb9"
-  "\xd1\xff\x9c\xd5\xa0\x97\x1f\x67\x73\x7c\xc5\x3c\xec\x4b\xfa\x68"
-  "\x7b\x8f\xf3\x91\x4c\x1d\xbe\x60\xbc\xc4\x40\xbe\x7a\xe9\x97\xf4"
-  "\x08\xfa\xff\xe1\x69\x92\xaf\x51\x87\xc4\xdd\x40\x89\x61\xe0\x8f"
-  "\x36\x18\xdc\x45\x7e\xd6\x53\xbd\x21\xb4\x9f\x65\xdd\xfe\xa5\x1e"
-  "\x23\xe7\x91\xba\xc3\x99\x34\x83\x8a\x73\xf6\xc8\x7b\xe1\x33\x1c"
-  "\x6f\x43\xe2\x95\x82\x36\x9b\x18\x27\x0f\xae\xbe\xe7\xd2\x68\xde"
-  "\x39\xd2\x68\xf1\xc8\xeb\x61\xa4\x87\x57\x0c\xe0\x50\x27\xcf\x78"
-  "\x3c\xd2\xa5\xe3\x10\xe6\xfa\x7b\xac\x06\xe8\x62\x5c\xaf\xb4\xf1"
-  "\xb8\xee\xc9\x1c\x97\x8a\x63\x59\xac\x4a\x23\xc6\xa1\xc7\xf9\xe8"
-  "\x18\x9d\xde\x5a\x19\xbd\x8e\x96\xb0\xac\x5b\xd1\x46\xd1\xb9\x09"
-  "\xfa\xe0\xa3\xb3\x2f\xa4\xf3\xa3\xb9\x11\x74\x4e\x64\xbe\xe2\x35"
-  "\x16\xf4\x51\x88\xe9\xcd\xfb\x1a\xb6\x95\xac\x57\x3d\xfa\x8b\x26"
-  "\xbf\xf4\x3b\x49\x61\xb8\x61\xd0\x9f\x61\x00\xee\xb7\x14\x8d\x1f"
-  "\xdd\xd9\x4f\x63\xd4\x2d\xd0\x17\xeb\xd5\x99\x14\xf6\x7d\x87\xec"
-  "\x78\xf4\x70\x7f\x3d\x8c\xab\xc3\x6a\x08\x0b\x2b\xc7\xb5\xf3\x31"
-  "\xae\xc5\x36\x11\x60\xbd\x52\xfa\x31\xa1\xad\xfb\x4b\x3b\x8c\xd0"
-  "\x2d\x0d\xb2\xae\xee\x34\xd6\xef\x4d\xf2\x1e\x75\x0d\xc2\xdf\x5f"
-  "\x71\xec\x38\xbd\x5d\x68\x8b\x89\x79\x0b\xb8\x43\xff\xcb\x1d\x2e"
-  "\xf9\x65\x25\xf7\x53\xce\x97\x9c\xa6\xe7\xc3\xf3\x87\x9c\x4f\x7f"
-  "\xc6\x3b\xf0\x57\xce\xf3\x68\x57\x32\xe3\xe9\xe3\x78\x79\xb2\xcd"
-  "\xb9\x69\x0c\xa3\xc7\x99\x53\x1d\xd5\xce\xbe\x6c\xa3\xce\x77\xbc"
-  "\x47\xd4\x6c\x0b\x48\xd9\xa9\x68\x9b\x73\x50\x1f\x93\x5c\x5e\x8d"
-  "\xb1\x9c\xf6\x48\x5e\xf4\x3b\x06\xf8\xa0\x78\x2c\x99\x8c\x36\x8e"
-  "\x77\x97\xb3\x4f\xc5\xd5\xcd\x09\xc6\xf6\x17\xbf\xe3\xd8\x70\x1a"
-  "\x0d\x79\x3c\x59\x8e\x53\x8e\x8f\xdb\x86\x77\x99\x17\x9b\x2f\x39"
-  "\x46\x1b\xc7\xdb\x7b\x49\x8d\x23\xd0\x65\xd1\x92\x97\xd4\xf9\x1e"
-  "\xbf\x8a\x91\x96\xfb\xb4\x30\xbc\x26\xfb\x8b\xfd\xf2\x64\x3c\x0c"
-  "\x19\x7b\x22\x97\x7d\xdc\xc4\x88\xa2\xd7\x64\xac\x44\xcd\x67\xcf"
-  "\xd7\x5c\x14\x94\x71\xd6\x1c\xc5\x7c\x0e\x36\xc8\x36\x99\xf4\x49"
-  "\x6b\x2a\x0e\xd2\x83\x01\xa6\x6d\xee\x41\x3e\xaf\xee\x97\xb4\xc8"
-  "\x3d\xac\x9f\x51\xe7\xb8\x6f\x1c\x4b\x70\x72\x90\x12\x59\xa7\xb0"
-  "\x39\x38\xb6\xc0\xa2\xed\xac\x93\x28\x9a\x82\xef\x0d\xa2\x5d\xf1"
-  "\xf2\xa2\xcb\x38\x36\xa3\xda\x5f\x3a\x0e\xfe\x4e\xfc\x1b\xf2\xde"
-  "\xa0\xd6\x65\xf4\xb1\xb6\xe8\x35\xde\x63\xf2\x68\x30\x7a\x9c\x8b"
-  "\x30\xff\x2f\xac\xb9\x70\x5c\x2c\xba\x4c\xb7\x31\xf8\x5c\x9c\xda"
-  "\xaf\x1a\x80\x87\xf2\x72\x5d\x7a\x40\x36\xfd\x91\x61\x95\x5d\x38"
-  "\x66\x16\xd5\xe8\xbc\x5c\x74\x1d\x9f\xab\xce\xcd\xe6\xfa\x07\x93"
-  "\x99\xc2\xf1\x13\xee\x27\xd3\x09\x1b\x25\x7e\xdd\x79\x89\x81\xfd"
-  "\xaf\x45\x01\xbd\x0d\x3a\x4d\x54\x1b\x1e\xbb\xbf\x3b\xf9\x80\x65"
-  "\xa0\xed\x8f\xdd\x2f\x69\x31\xf0\xbe\x22\x82\x36\xfc\x5c\xae\xf8"
-  "\xee\xb1\x99\xe0\x0f\x6d\xcd\x46\xa5\x89\xe4\x8f\x7e\xc3\x71\x1a"
-  "\x15\x8e\x4b\x48\xe7\x77\xe4\x2d\xf6\xd0\x89\x34\xb5\x0f\xf5\x18"
-  "\xda\xbf\xa8\x5d\x2b\x37\x86\x71\x89\xdb\xce\x28\x1c\x1f\x27\x9e"
-  "\x63\x55\xdc\x82\xc7\x13\x18\x5f\xdb\x77\xb8\x8f\x1f\x6b\xe5\x7a"
-  "\x99\x27\x44\x5f\xc1\x10\x7f\x5f\x1a\x75\xf7\x15\x60\xfc\xa4\x19"
-  "\x50\x0f\xe4\xdf\xe7\x46\xad\x4e\xbf\x8e\x2b\xe3\x06\x5d\xd1\xd4"
-  "\x23\x96\xc4\xa7\x2f\xd7\xcb\xe3\xbd\xaf\x60\x18\x7e\x26\xfc\x86"
-  "\x7e\xd3\xf9\x18\x7a\x6d\x97\xaf\xe2\x50\x49\x78\xa5\x38\x3c\x2f"
-  "\x28\xc2\xb0\x0b\xba\xaa\xc0\xbf\x23\xd6\xb9\x68\x84\xff\x11\x43"
-  "\xce\x6a\xca\x80\x6d\x4b\xe2\xbc\x98\x5a\x17\xc6\x75\xa5\x98\xc2"
-  "\xf1\x68\xf1\x9c\xae\x3d\x4f\xe0\xe7\xee\x95\x62\x61\x8f\xf3\xf1"
-  "\x9d\xfa\xde\x9d\x8a\x3d\xf3\x78\x63\x7f\x1c\x9e\xc4\x87\xf9\x9c"
-  "\x0f\xcd\xb3\xa3\x8e\xc4\xa7\xba\xb8\xde\x1c\x9e\x3b\x50\x1f\xf2"
-  "\x61\xfe\x5f\x38\x85\xf3\xf9\x12\x6f\x1c\x89\x5f\xda\x20\x7b\x9c"
-  "\x5d\x8c\x57\x77\xd2\xa1\x12\x1d\xd7\x11\xfe\x0c\xc3\x37\xc3\x2d"
-  "\x2f\x53\xc7\x0d\xe9\x87\xab\x54\x7a\x90\x63\x91\xb1\x0f\x22\xde"
-  "\xe7\xe9\xb8\xea\x38\x70\x7d\x7c\xae\x52\x24\x1f\xb0\x71\x6c\x17"
-  "\xae\xcf\xf7\x5c\x01\xe7\xad\xd6\xf1\xfd\xfa\xb3\x3f\xf1\xe9\xee"
-  "\xa1\xbc\xa3\x8a\x27\xf3\x8e\xea\xf3\x17\xee\xbb\xa2\xf7\x7b\xf3"
-  "\xda\x63\x65\xd9\x63\xcb\x96\x15\xe7\x2c\xcf\xe7\x4b\xda\xf8\x67"
-  "\x6f\x48\x8e\xb4\x49\x59\xbe\xa9\xd8\x00\xf9\x7c\xf6\x89\x5e\x1a"
-  "\xa9\xef\x5f\xe6\xf7\x9f\x7f\xd2\xfc\xa4\xef\x62\x5d\x95\x75\x3a"
-  "\xbc\x5b\x78\xa8\x64\x2d\x83\x49\x38\x66\x22\xc3\x60\xb2\x93\xe5"
-  "\x45\x77\xd2\xa9\x22\x49\x8f\x4d\x46\x0f\xca\xf5\xaf\x7f\x0e\xe2"
-  "\x27\x96\x1b\xda\x78\x98\xcf\x66\x72\x8c\x23\xc3\xef\xd7\x74\x18"
-  "\x78\x0e\x2f\xc5\x3d\xdb\x4e\x52\x6f\xd0\xe2\xe6\xbc\x7f\xb6\x03"
-  "\x72\x38\xbf\x4b\x54\x1c\xc0\x3c\x9c\xef\x19\x14\x87\x88\x3d\x76"
-  "\xf6\xc9\xea\xa4\xc5\x34\xe8\x7e\x78\x79\xf3\x61\x35\x0e\x17\x2f"
-  "\x68\xb6\x12\xe3\xf1\xb3\xe3\xb4\xf8\x7e\xa3\x15\xb2\x76\x34\xfd"
-  "\x0e\xf7\xd2\xd6\xe5\x77\x51\xfd\x75\xf5\xa9\xed\xc6\x44\x61\x10"
-  "\x42\x24\x08\xf5\x47\x46\xed\x26\x11\x3f\x83\x48\x90\xbb\x45\x89"
-  "\xa0\xd4\xb0\xa1\x46\x32\x8f\x48\x31\x5d\x7b\xcd\x18\xeb\x5d\x77"
-  "\x4e\x9b\xea\x28\x2d\x01\x77\x07\x03\x66\x11\x19\xe7\xe9\x94\x65"
-  "\xc1\x0d\x65\x24\xfd\x05\x2a\x4e\xc5\x8d\xdd\xbc\xc9\x29\x8a\xf8"
-  "\x6c\x6e\x78\x84\x31\xcb\xf1\x2c\x19\xf6\xf6\x7a\x0c\x1c\x3b\x98"
-  "\xe7\x68\x8e\x59\x06\x5c\x8f\x7d\x80\x34\xb4\xdf\x2e\x2a\x8d\x59"
-  "\x6a\x3f\xf0\x89\xb1\xe1\xcd\xc6\xac\x01\xf8\x46\x62\xf8\x8e\x57"
-  "\xc8\xb0\xa3\xb4\xcb\xe0\x36\xde\x49\x6e\x9b\x9f\x3e\xc0\xfd\x20"
-  "\xfd\x59\x04\xfa\x13\xc3\xa8\x77\x86\xcb\x1d\x5f\x91\x41\x3b\x5f"
-  "\x67\x38\x4d\x4f\xfc\x64\xdf\x20\xe5\xf8\x3c\x6b\x77\xf2\xa1\x7b"
-  "\x7a\x9c\x4f\xa0\xff\x7f\xe0\xd7\xe6\x04\xc8\xae\x27\x60\xff\xe5"
-  "\xab\xe7\xe4\x43\x1c\xb3\x87\xd3\x1a\xf5\x3c\xf1\xe7\x05\x5e\x73"
-  "\x14\x2e\xee\x57\x71\xfe\x8b\x2e\xf6\xdd\x1f\x64\x9f\x7f\x98\xdb"
-  "\x7e\x0b\xef\xb3\x0c\x19\x11\xa0\x14\xc7\x39\xd1\x07\xbb\x3d\x15"
-  "\x6c\x6b\x08\xc1\xf6\x0a\x9e\x17\xd9\xad\xde\xb3\xc4\xb1\xfe\x78"
-  "\xbf\x76\xcf\xe2\x3f\x1a\xdc\x81\x33\x2e\xf7\x86\x30\xb5\x61\x7e"
-  "\x76\xd7\x9e\x71\xb5\x7a\x8f\xe0\x3e\x44\xad\xf4\x29\xb5\xda\xff"
-  "\xdf\x32\xb9\x56\x52\x2b\xca\x98\xce\x7d\xe7\xc5\x7c\xb7\xf1\xff"
-  "\x21\x8e\x57\xcf\xb2\x02\x74\xb7\x9d\xa6\x82\x75\xef\x03\xce\xde"
-  "\xff\x04\x2c\x19\xdb\x69\x3a\x7d\x80\xfb\x1e\x67\x41\xa5\x2e\x47"
-  "\xe2\xc6\xd1\x48\x70\x6d\x32\xdb\x1f\x31\x84\x21\x93\x38\x06\x17"
-  "\x64\xd1\x14\x6e\x17\x9e\xd3\xf9\x19\xd7\x09\x7c\x35\xaf\x73\x6d"
-  "\x33\x07\x1f\x61\x19\x95\xcd\xf2\x07\xe9\xf3\xeb\xcf\x4b\x99\x95"
-  "\xa5\x3d\xcf\xd6\x9e\x67\x6a\xcf\x99\xda\x73\x86\xf6\x3c\x8d\x9f"
-  "\x95\x6c\x5b\x62\xeb\x97\xbb\x86\x61\xed\x78\x4e\xd7\xfb\x02\xf8"
-  "\x0c\x37\xdb\xd7\x4a\x19\xa9\xe1\x31\x45\xc3\x2b\x5d\x7b\xd6\xf1"
-  "\xb9\xda\x1c\x5c\xfb\xbf\x85\xcf\xbe\x18\x7c\x5c\x11\xf8\x90\xd9"
-  "\x9e\xf1\x4d\xf0\xb1\x98\x39\x5e\xf3\xdf\x81\x0f\xe3\xc2\x69\x3d"
-  "\xce\x27\x33\xa2\xf1\x79\x32\x4b\xc7\x27\x2e\xbf\xad\x14\x5d\x3c"
-  "\x3f\xac\xb8\x52\xc6\xaa\x1c\xc6\xb2\xbf\xbe\x57\x8f\xa7\xf6\x64"
-  "\xe5\xc5\xe2\xa9\x61\x2c\x58\x91\x07\xed\x7f\x72\xa1\x36\x0f\x1e"
-  "\x54\xfa\xd2\x93\xcd\xba\x6f\x0c\xda\xba\xb3\x4a\xb5\xb5\x61\x03"
-  "\xc7\x14\x5b\x4d\x57\x39\xec\xa2\x0b\xfa\xff\x7f\x35\xdb\x7c\x51"
-  "\x63\xa0\xb0\x78\xc5\x8a\xa7\xef\xb0\x15\x2e\x5a\x9a\x6f\x1b\x9f"
-  "\x67\x5b\x51\xb0\x64\x71\x71\x7e\xf4\x7e\xb1\x45\x8b\x97\x2f\xfd"
-  "\xe0\x59\x27\xe5\x31\xc0\xfc\xcf\x76\xbc\xf2\x5d\x7c\xea\x79\xe1"
-  "\x7c\x92\xcf\xca\x9a\xea\x5e\x24\x23\xef\x51\xf4\x38\x9f\x9a\xaf"
-  "\xcf\x09\x2a\x3e\x34\x25\x18\x2c\xac\x73\x3d\x05\xfb\xf7\x09\x6f"
-  "\x44\x3a\xe7\x2d\xd3\xd3\x18\xbe\x26\x9b\x86\x1d\xa7\xa7\xc6\x72"
-  "\x9d\x71\x69\x78\x5e\x6c\x87\xad\x9b\x00\x7b\x84\x6d\x43\xc1\xf1"
-  "\x83\xf8\x7c\x19\xca\x09\xe0\xf3\x09\xcb\x5e\xfe\x06\x84\xd2\x7d"
-  "\x05\xe3\xf8\x39\xca\xec\x40\x9a\x71\x33\xf2\x42\x9f\xee\xe2\x72"
-  "\x48\x0f\xf1\x39\x7f\xa4\x9b\xb4\x98\x48\x48\x2b\xbc\x8c\xcf\xe1"
-  "\x23\xcd\x12\x91\x36\x9e\xe3\xf4\x22\xcd\xa6\xe0\x15\xde\xc6\x74"
-  "\xc6\x73\x86\x66\x73\x73\x9e\x59\x5a\xbd\x65\x91\x38\x73\x14\xf5"
-  "\x5b\x26\xa5\xdb\xe6\x3f\xf8\xbd\xe9\x77\x3e\xbe\x6c\xe9\xe2\x64"
-  "\x92\x64\x4f\x4b\xb7\x8f\x4f\xbf\xc5\x7e\xc3\x1d\xb6\xa2\xfc\xfc"
-  "\xe5\xb6\x55\xf9\x4b\x8b\x6d\x8b\x56\x2d\x5a\x9d\x4c\x8b\x97\x2d"
-  "\x7f\x9c\x4f\x91\x73\xb7\xac\xc8\x79\x7c\xf1\x13\xbc\xa9\xaf\x72"
-  "\x27\x47\xcd\xc7\xf3\x59\xb6\x69\x71\x17\x0e\x43\xe6\x06\x44\xd2"
-  "\x87\xe5\xb8\xe7\x3d\x0b\x2b\xae\xcd\xf8\x1d\xc4\xaf\x11\xbf\x23"
-  "\xf8\xb5\x9f\xa4\xe5\xa9\xb8\xee\xef\x71\x16\xfa\x75\xbd\x60\x80"
-  "\x87\x9e\x36\xe9\x3c\x84\x79\x7c\xbf\x9a\xdf\x9e\x9e\xda\x16\x94"
-  "\xe3\xa7\x9f\xa7\xaa\xce\x0f\xf0\x94\x8c\x77\xc8\x3e\x2b\x2b\xf1"
-  "\x1e\x3c\xcc\x76\x2c\x68\x9e\xc4\x74\x3b\x41\x45\x13\x61\xfb\xb7"
-  "\x70\x2c\x10\x5c\x9b\xc1\x2f\x2d\x2a\xfe\xc6\xd3\xfb\x91\x6f\x2c"
-  "\xea\x38\xa8\xd5\xa1\x9e\x47\x89\xc3\x6c\xe7\x1f\xd7\x9e\x95\x4d"
-  "\xbc\xec\x43\xbe\xe7\xab\xb6\x57\x64\x66\xff\x3f\x65\x5b\xe9\xef"
-  "\x96\x3e\xa2\xd5\xe1\x02\x2d\xca\xea\x9c\xa2\x7f\x9f\x83\xd7\x98"
-  "\xcc\x09\x77\x09\xe0\x73\x26\x9c\xf8\x70\x87\x8c\xd3\x57\xd6\x0b"
-  "\x19\x71\xeb\xad\x6e\xbb\xcc\x9f\xc0\x6b\x50\x73\x8b\x44\x98\xe3"
-  "\xa2\x86\x13\x9f\xea\xe0\x72\xc2\xf4\x61\x79\x78\xf3\xf0\x0c\xa5"
-  "\x0b\x70\x7c\xb4\xa5\x9a\x1f\xa8\x08\x30\x6d\x4f\x52\xe1\x17\xca"
-  "\x9e\x59\x9e\xaa\xf4\xac\xa5\x99\xba\x2f\x19\xc6\x68\x1a\x9e\xe7"
-  "\xeb\x32\xc0\x43\x4b\x6d\x9a\xdf\x8f\x4b\xb5\x7f\x69\xa5\xf6\xdc"
-  "\xa8\xe1\x98\xc0\xb1\x1e\x80\x7f\x3b\xf7\x1d\x6c\xc3\x46\xdc\x1f"
-  "\x01\x7d\x5a\x14\x7d\x96\xca\x35\x06\xe8\x35\xfc\xfe\x08\xc7\x9d"
-  "\xc7\xbb\x23\x2a\x8e\xc2\xd3\xcd\xdc\xe6\x01\xdf\xc0\xda\x0c\xd0"
-  "\xef\x43\xde\x53\xc3\x58\x6a\x74\x9f\xe7\xf1\xf9\xb4\x0b\xf0\xf6"
-  "\xe9\x72\x87\xe5\x4c\x4e\x08\xe3\x54\xea\xa5\x4b\x83\xba\xbc\x19"
-  "\xe0\x83\x65\x96\x78\xb2\x24\x5e\xbf\x6b\x7d\xb3\x5a\x38\x0b\xe7"
-  "\x03\xa7\x7d\xb2\x0f\x38\x6e\xe4\xf9\x7e\xfd\xb7\x4f\xc9\xc8\x65"
-  "\xfd\xfa\xaf\x8e\x07\xc7\xbb\xf5\x30\x6e\xbd\x72\x9f\x53\x93\x1b"
-  "\xcb\x2a\x75\xb9\xa1\xc3\x31\x27\x88\xb0\xd9\x8e\x7f\xe5\x07\x18"
-  "\x6f\x39\x5f\x4a\x7d\x04\x70\x46\x9c\x53\x67\x7c\xc2\x15\x07\xd0"
-  "\x8e\x65\x99\x90\x31\x46\xa9\xa3\x3a\x0b\x9f\x18\x90\x45\xcb\x3c"
-  "\x91\x30\x85\xe9\x40\x90\xe1\xb2\x3c\x62\x9d\x24\x27\x64\xe4\x38"
-  "\x1b\x41\x6d\x7e\x81\x0c\x2e\xb2\xe8\xb8\x82\x86\x87\x75\x7c\xb5"
-  "\x6f\x7c\xc0\xc6\x5e\x56\x34\x2f\xd4\xc7\xbe\xae\xcd\xaa\x3f\x9f"
-  "\x91\xf2\x06\xef\x1a\x50\x76\xb6\x87\x9e\xda\xae\x8d\xa1\x16\x94"
-  "\x6f\x68\x2a\xcd\x44\x9e\xa2\x02\xcd\x5f\xb3\x1d\xfd\x7b\x24\x82"
-  "\xf7\x1f\x89\xb0\x97\x8f\xa8\x3e\xbc\xb3\xec\x38\x15\xed\x8c\x48"
-  "\xd7\xfa\xb6\x29\xeb\x38\x3d\xf3\x88\xb2\x3d\x0f\x68\xe5\x8b\xa4"
-  "\xcf\xa6\x8e\x23\xcb\x02\x3e\x8f\xc4\x63\x5c\xd2\x5e\xf6\x71\x91"
-  "\x47\x9f\x2f\x00\x6b\xbf\xa4\xf9\x28\x71\x90\xe9\xa4\xe2\x19\x14"
-  "\xbe\xa0\xe8\xf4\x8c\x29\x8a\xf6\x3c\x6f\xa2\x1e\xa6\xd3\x88\x75"
-  "\x22\x3c\xc2\x9f\x20\x72\x56\x1b\x65\xec\x66\x1e\xe3\xbc\x37\x01"
-  "\xfe\x90\x7a\x95\xa2\xdb\x33\x33\x75\xba\xe9\x7d\xc7\x74\xf2\x50"
-  "\x51\x23\xd3\x36\xba\x8d\xc3\xda\x8f\xeb\x6d\x07\x4d\x79\xbd\x14"
-  "\xcf\x0b\xb5\x71\xd1\xe2\x1a\xcd\x7b\xe5\x4f\x2f\x6a\x32\x7e\x8f"
-  "\x9a\xec\x53\x48\xd1\xf6\x19\xd8\x7f\x4f\x99\x64\x3b\x14\xac\xc3"
-  "\x4c\x5f\x1e\x2b\xc0\x33\xa0\xc5\x16\x3a\xac\xfc\x35\x9e\x5e\x08"
-  "\x7d\x3f\x20\xc7\xf2\x4a\x19\x03\x82\xe3\x8b\xb6\x33\x8d\x58\x2e"
-  "\xf2\x58\xe2\x31\xc0\xe3\x49\xd1\x68\xb9\x31\x82\x46\xcd\x4c\x1f"
-  "\x8d\x4e\xfb\x63\x64\x79\xbe\xad\x70\xba\x92\xc5\xb6\xb4\xf1\x79"
-  "\x93\x65\x20\x0f\xdb\x7d\x33\xee\xb0\x65\x4d\x1f\x6f\x2f\x98\x30"
-  "\x57\x5d\x66\x64\xcd\xe6\x6b\x72\xb4\xfd\x64\x43\x3d\x85\xd1\x36"
-  "\xd8\x2a\xaf\x92\x1f\xcb\x37\x78\x28\xe8\x93\xb4\x5b\x29\xbc\x55"
-  "\x67\x89\x42\x4c\xc3\xa5\xe8\xd3\xf2\x03\x5b\xe6\x41\x06\xcf\x5b"
-  "\x2d\xbe\xaa\x47\x3a\xc7\xa8\x65\x5e\x04\xcf\x73\x0c\x1c\xf2\x25"
-  "\x9d\xb2\xf8\x92\xbc\xed\xbe\xa4\x43\xf3\xef\xbd\xc1\x21\x00\xab"
-  "\x5d\x6f\x0b\xdb\xc5\x82\xcb\xdb\x45\x88\xe9\x92\x63\x47\x7f\xa3"
-  "\x1c\xdb\xc8\xc8\x17\xc0\x1c\x90\xa1\x6c\xc3\x15\x68\x7f\xe1\x0e"
-  "\x4d\x7e\x65\xe1\x39\xd5\x43\xe9\x92\x8f\xc3\x4e\x2b\xaf\xcf\x19"
-  "\xc3\xeb\x6f\x7c\x40\x54\x78\xdb\x75\x98\x80\x35\x54\x8b\x3d\x27"
-  "\xe1\x7d\x53\x5f\xc1\xf0\xc6\x83\xd5\xe6\x04\x15\xe7\x0e\xe3\xba"
-  "\xac\xde\x10\xce\xee\xf7\x05\xc0\xbb\x11\xeb\x2c\xec\x2b\x90\x0d"
-  "\x7e\x2b\xe3\x3c\xfa\xbb\x2a\x67\xd8\x53\x65\x08\x07\xd0\x77\x16"
-  "\xa5\x33\x7b\x59\x66\xc2\xfe\x5c\xe1\xd2\xe7\x32\x39\x07\x1a\xa8"
-  "\x4c\xd9\x30\x2b\xe4\x1e\xdf\x59\xa7\x91\x20\xa7\x17\x5e\x97\x2a"
-  "\xed\x92\x40\xd8\x99\x40\xca\x3f\x73\xc5\x3b\xba\x5c\xe5\x3d\x16"
-  "\xf3\x3a\xe1\xe3\xf5\x35\x73\x50\xf8\x78\xbf\x45\xce\x17\x74\x92"
-  "\xdc\x25\x3d\x65\x1c\x87\x54\xea\x3d\xa8\x57\xcd\x15\x21\x35\x57"
-  "\xa0\x7e\xd8\xf2\xb9\x98\x13\x12\x4e\xd2\x8a\x0d\x8c\x3f\xd3\x86"
-  "\xd7\x70\xc3\xa0\x95\x9b\xe7\x46\xa6\x4f\xf2\xfb\x16\xde\xe7\xe7"
-  "\xb6\x9a\x83\x68\x73\x64\xbb\x0c\x61\xcf\x66\x27\xda\x65\x40\xbb"
-  "\xec\xa7\x78\x9c\x04\xd8\xff\x02\x63\x6c\x94\x8c\xb5\x2b\x6d\xec"
-  "\xe2\x1d\x91\x6d\x64\x99\xaf\xda\x50\xfc\x61\xbc\x36\x0a\x03\xb7"
-  "\x91\x69\x50\xfc\x8a\x36\xc6\x24\x9e\x2c\x33\xbc\x54\x9c\x3d\x62"
-  "\x1d\xfb\x3d\x1c\xd8\x02\x3e\x9a\xc1\x7d\x88\x39\xb3\x9a\xf1\x8c"
-  "\xd7\x5f\x0c\x4f\xc1\x7a\x36\xcf\xbc\xae\x2c\xb7\xc7\xf9\x6c\x7a"
-  "\x7c\x7a\x3f\x7b\xff\xc5\xe9\xfd\xec\x78\x2e\xcf\x78\xb0\x1f\x88"
-  "\x39\x08\x03\x1d\x7c\x0b\x1b\xad\x3c\x5e\xbd\x23\xd6\x6d\x67\xbc"
-  "\xe2\xbe\x83\xdc\xf1\x56\x69\x72\x07\x7c\x28\xe6\xe1\xc7\x72\x08"
-  "\xb8\xb5\xe8\x32\xc8\x9c\x60\x4b\x94\x32\xc1\x20\xaa\xe3\xc1\x30"
-  "\xaf\xab\x66\xbf\x8b\x19\xa8\x3f\xee\x7b\xd0\xd8\x06\x1a\x95\x87"
-  "\xd7\xdf\x74\x9d\x39\x81\xee\xf2\x25\xde\x94\x6c\xb6\x07\xc7\x31"
-  "\x0d\x01\xd3\x8e\xb1\xfb\x1f\x6c\x9b\xaa\xd8\x58\x2b\x31\xff\xbf"
-  "\x20\xd7\xf3\x7c\x49\x07\xca\x55\xfc\xac\x95\xd9\x1e\xaa\x3c\xaa"
-  "\xaf\x6b\xe2\xb9\xc0\x43\x9f\x6a\xeb\x55\x57\xbd\x2a\x36\x1e\xb2"
-  "\x85\x9d\x66\x61\x5b\x63\x86\xee\xb8\x8a\xe3\x90\x1b\x44\xf2\x21"
-  "\xdb\x00\x9f\x28\x9f\x10\x9d\x4f\x50\x7e\x67\x7c\x1e\x58\xf9\xa7"
-  "\x8b\xf3\xc0\x4a\xb9\x5f\xcc\x74\x57\xf6\xc9\x4a\x9f\xae\x9b\x88"
-  "\xf5\x57\xbd\x6a\x2b\xe5\xfa\x57\x6e\x50\x75\x33\x4d\x32\x78\xad"
-  "\x7e\x36\xe8\x52\xd6\xe3\x5c\x35\x46\x97\x03\xcc\x2f\xe6\x10\x25"
-  "\xb0\x2c\x62\x5e\xc1\xbb\xa9\x90\x33\x5b\xd4\x1a\xe2\xa1\x0e\xf9"
-  "\x8d\x28\xe7\x72\x9b\xcf\x51\xb0\x95\x7d\x38\xfd\x49\x07\xd1\xe6"
-  "\x55\x0b\x3d\xf4\x87\x71\x32\x8f\xe9\x40\x00\x30\x82\x35\x23\x31"
-  "\x2f\x2b\x5f\xa6\x14\x1e\xd3\x1c\xf7\x86\xc7\x35\xd2\x52\x81\x37"
-  "\xc7\xc0\x81\x8d\xb3\xaa\xa6\x7f\x2e\x72\x66\x40\x56\x08\x39\x1f"
-  "\x62\x2e\x1a\xd3\x0d\xda\xfd\xd2\x10\xde\x79\x7e\xb2\x95\xb8\xcd"
-  "\xe7\xd7\x8f\xde\xf9\xb3\x49\x64\xfc\xc8\xfa\x18\x15\xdd\x42\xa9"
-  "\xeb\xbe\x67\xa4\xff\x9e\x4a\x06\xa6\x83\x87\x56\xed\x50\xb4\x5b"
-  "\xd5\xa9\xf7\x8f\x87\x56\xce\xe6\xfe\xe0\xf5\xb7\x79\x41\xf1\x95"
-  "\x5a\x23\xb4\x43\xfe\xe5\xb9\xd4\xfb\xe5\xf6\xd8\x75\x1f\xd6\xe1"
-  "\x6d\x4b\x56\xd8\xf2\x96\xad\x5a\x3a\x76\x6c\x94\x7d\x64\x94\xe7"
-  "\x3a\x9c\x76\xab\x9a\x43\xed\xb3\x75\xbc\x59\x17\xc1\x33\xda\xbf"
-  "\xfc\x82\x38\xdf\xb3\x73\x34\xd7\xdd\x9c\x74\x1a\xb8\xbf\x99\x66"
-  "\xdf\x1c\xf1\x78\x2b\xcd\xbe\xe5\xd6\x9c\x07\xf2\x17\xe5\xad\x8e"
-  "\x48\xbd\x2d\x72\x4d\xae\xea\x55\xd4\x9d\x38\xfa\x1e\xc8\x8a\x84"
-  "\xb9\xcf\xf1\x7c\xb2\xfa\xee\xd2\xa0\xf8\x1b\xe4\xf5\x54\x8c\xb1"
-  "\x9c\xd6\xe2\x20\xb5\x42\x96\x89\xab\x58\x86\x0f\x53\xe7\xd5\xa0"
-  "\x43\x81\xb7\xcc\x68\xbb\x0f\xba\xdc\x39\x5e\x93\x41\xb9\xfc\xb6"
-  "\x2d\x1c\x7b\xf6\xd0\x42\xa5\x57\xac\xb6\x21\xfd\x32\x5c\x67\xe1"
-  "\x3a\x14\xd7\x39\xb6\xa5\xb0\x75\xd8\x3f\x78\x25\xfb\x07\xaf\x66"
-  "\x3c\x12\x26\xf9\xcb\x68\xd2\x72\xd6\xd3\xed\x1d\xac\x77\x78\x68"
-  "\x75\x39\xef\x0f\x70\x5e\x94\x19\x6b\x7b\x92\xd2\xf9\x2a\xe4\xbe"
-  "\xca\x6a\x9b\xa8\x38\xb4\x50\x6c\xcd\xe6\x6f\xb7\x8c\x43\xfa\xf3"
-  "\x89\x09\xc7\x28\xd1\x3a\xec\x87\x3d\xce\xd5\x98\xff\xf2\xe5\xd8"
-  "\x18\xec\x7b\x6f\xac\x6b\xf0\x98\x1f\xd0\x45\xa0\x0b\x42\x17\xc9"
-  "\xb1\x6f\x24\xdc\x1b\x07\xf4\x90\xd5\xed\xfd\x3a\xad\x81\x92\xf1"
-  "\xec\xd1\xf9\x1d\xf7\x5e\x9d\x1f\xa3\x62\x83\x2d\x2d\xce\x5f\x9e"
-  "\x9f\x67\x1b\xbf\x22\x99\x22\x22\x83\x15\xe4\x2f\xb5\x2d\xcf\x7f"
-  "\xe6\xd9\xfc\x15\x32\xaa\x17\xbf\x8d\x9a\xcf\x53\x45\xf2\x07\xd5"
-  "\xfa\x99\x15\xdb\x68\xa6\xe3\x9a\xfb\x39\x9e\x94\xd8\xe8\xb2\xf0"
-  "\xbe\xa7\xd4\x3f\x52\x8c\x05\xd1\xb6\xc4\x73\x9d\x4a\x87\x3b\x34"
-  "\x5b\xd9\x31\xcf\xad\xe6\xe7\xe3\xb4\x26\x38\x10\x83\x7a\xcd\x6e"
-  "\xfe\x0e\x82\x46\x9f\x8e\x1e\xe7\x9a\x1d\x3a\x7d\x3c\x54\xa2\x9f"
-  "\x23\xf0\x4a\x39\x81\xb9\x14\x72\x2e\x6a\x1e\x55\xdf\x73\x5b\xd3"
-  "\xc0\x7b\xac\x72\x4d\x36\xe9\x50\x16\xd7\xc5\x30\x4f\xa0\x3c\xfa"
-  "\x61\x36\xe4\x23\xcb\xb1\x72\x1d\x1e\xea\xac\xe1\xfa\x34\x1b\xe7"
-  "\xdb\x27\xe9\x39\xb9\x67\x1d\x2e\x3f\x94\xc5\xb2\x63\x92\xd4\x39"
-  "\x00\x47\xee\x63\x95\x4c\x60\xfd\x51\xc6\x41\x07\x2c\x5e\x83\x85"
-  "\x0c\xc8\xe5\x6f\xff\x71\x9a\x8a\x6b\xb5\x5a\xfa\x09\xa2\xae\x99"
-  "\x3d\xce\xe7\xf2\x06\xfc\xb2\x4b\x26\xb0\x4e\xc9\x70\x3d\xf4\x5c"
-  "\x1a\xc3\x53\x71\xbb\x9e\x03\x2e\xf6\x9d\x03\xba\xd1\x73\x2d\x11"
-  "\x36\x17\xf0\x51\x78\xfa\x81\x8b\x8c\x11\xa9\xfc\xe6\x64\xbb\x59"
-  "\x4e\xd6\x68\x6d\xd7\xdb\x03\x78\x1d\xe0\xb9\x1a\x7d\xdf\xd5\xa3"
-  "\xb5\x9b\xf1\x63\xdc\x23\x71\x56\xf8\xae\x61\xb9\x84\x31\x5c\x62"
-  "\x89\x18\xc3\xbc\xe6\x32\x04\x69\xe3\x06\xfc\x71\xd7\x14\xc6\xca"
-  "\x87\x7b\x16\x3d\xfe\x14\x1b\xe9\xb3\xd3\x27\xd8\x58\x56\xe4\x3c"
-  "\x70\xef\x8c\x87\x72\x66\xcc\x5b\x30\x77\xbe\xf4\xbf\xef\x7f\x9f"
-  "\xb9\x34\x7e\x86\x68\xbe\xb2\x80\x37\x66\xa2\xbf\x86\x1c\xa7\x52"
-  "\x8f\x8a\xcf\x5c\xb2\x33\x3a\x3e\x73\x89\x0b\xbf\xa3\xf8\x41\x33"
-  "\x59\xeb\xc1\x0f\x7a\x64\xe9\x11\x8d\x5f\xbc\xc0\xf7\xc8\x00\xbf"
-  "\x94\xca\x35\x6f\xf6\x4b\x50\x6b\xa9\x25\x90\xff\x6b\xc6\x45\xbe"
-  "\x1b\xb0\xfd\xd6\xa6\xf4\xdb\x7e\xfd\xb2\x60\xed\x54\xdd\x0e\x44"
-  "\xda\x7c\xd8\x80\x49\x6c\x03\xaa\xb5\x9f\x52\xa9\x63\xc5\xda\x6a"
-  "\x03\x76\x9a\x89\x74\x1b\x90\x63\x43\xf2\xbe\xa7\x1a\xa3\x6b\x8b"
-  "\x23\x6c\x2c\xbf\x8c\x17\x78\x5e\xd9\x84\x5c\x4e\xae\xb5\xa5\x18"
-  "\xe7\xf3\xfa\x33\xf4\xda\x99\x98\xe3\x31\xef\xf4\x08\x31\xdc\x38"
-  "\x5f\xc3\x69\x3f\xaf\x47\xb3\xbe\xab\xec\xbd\x92\xa9\x2c\x7f\xc5"
-  "\xfa\xd1\xf7\xcc\x0b\xc9\x58\x6a\x90\xbd\x6b\x3b\x06\x78\xae\xd4"
-  "\xc3\x7d\xc9\x34\x00\x1f\x74\x82\x0e\xc6\x81\x36\x97\x52\x7f\x9b"
-  "\xb5\x75\x0c\x7d\x0d\x43\xd5\x55\x7a\x6c\xb0\xf6\xc5\x6f\x5b\x69"
-  "\xd6\xd7\xb6\x8d\xbf\x99\x83\x71\xa1\xb7\xf1\xc2\xf6\x95\xd6\xc4"
-  "\xb4\x2f\xfb\xc2\xf6\x95\x36\xf6\xef\xbb\xf4\xaf\x4b\x94\x1e\xe3"
-  "\x76\x32\x1f\xa0\x9d\x87\x13\xad\xa6\xef\x44\xdc\x4f\x88\x27\x57"
-  "\x47\xac\x33\x68\x67\x40\x1c\xb7\x35\x8f\x91\x76\x5a\xe0\x25\x43"
-  "\xb8\xe0\x25\x27\x7e\xb8\xb2\x9e\x3d\xa0\xab\x8a\x80\xc2\xcf\x31"
-  "\xa5\x19\xb2\x97\xd7\x5a\x06\x3b\xdb\x06\x9a\x1d\xd5\xd7\x01\x70"
-  "\xdf\xc1\xf6\xe4\xbc\xd0\x5d\x82\xd3\x99\x06\xb0\x49\x7c\xe0\xab"
-  "\x0e\xa5\xb7\x39\x36\xf4\xcb\xec\xef\x3c\xbe\x2f\x71\x1d\xd9\x9a"
-  "\x6a\x6f\xe1\xf4\x5a\xf4\x9d\x5c\x1b\x94\xdf\xc8\x1b\x04\x66\x4e"
-  "\x28\x83\x06\x81\x7b\x54\x87\x3b\xd8\x39\xc8\xc8\xb4\x65\x4b\x6d"
-  "\x05\x8b\x96\xe6\x2d\x5b\xbc\x78\x82\xed\xd9\xa5\x8f\x15\x2e\x7b"
-  "\xfc\x29\x16\xfc\x2b\x8a\x9f\xc5\xf8\x95\xe3\x36\x73\xf6\xec\x9c"
-  "\x7b\x16\x3c\xf8\x93\x28\x1d\xc0\x54\xed\x0c\x97\xcb\x6f\x64\xad"
-  "\x7f\x72\x4d\x8f\xb3\x0c\xfd\xff\x84\x5d\xcd\x37\x65\x98\xff\x1f"
-  "\x4f\x51\xba\xd6\xc3\x5d\xea\xec\x67\x59\x63\x84\x5c\x1b\x81\xe7"
-  "\x66\xfe\xd6\xc1\xc0\x1a\x48\x59\x75\xa4\x0e\xd1\x2d\xbf\x53\x57"
-  "\xb6\x43\x8f\x83\x50\x3c\x96\x0c\xc6\xb1\xd5\x54\x63\x10\x65\x1e"
-  "\x2a\x3b\x0c\x7b\xf1\x28\xde\x37\x7b\xa8\x60\x8b\x66\x3f\x1e\xe5"
-  "\x3d\x56\xb6\x1f\x43\xb0\x25\xe7\xad\x76\xdd\x95\xb3\x3a\x81\x7d"
-  "\x88\xe5\x77\x13\x82\xe7\x45\x27\xef\x73\xf2\x9e\x11\x7f\x37\xa1"
-  "\xea\x49\x69\x4f\x26\xca\x3c\xb8\xaf\x3a\x41\xd2\xb6\xc2\x7b\x5b"
-  "\xfd\x09\xf9\xed\x46\xd8\x1f\xeb\xc6\xe9\xba\xa7\x79\x9d\x4d\x9e"
-  "\x49\xdd\xac\xfa\xa3\x83\xfb\x82\xeb\xcb\x59\xed\x52\x75\xa0\x0f"
-  "\x50\xd6\xac\xd6\x7d\xd6\x2d\xbc\xe8\x7a\x76\x92\x77\x30\xfe\x01"
-  "\xcf\x97\x0d\x7b\x49\xc5\x2b\x66\x3f\x38\x9f\xee\x87\xc5\x3e\x59"
-  "\x80\xbb\x3f\xd6\xa7\x4b\xf9\x25\xac\x6b\xd1\xfd\x41\x70\xdf\xd1"
-  "\xaf\x2f\xf3\xb7\x36\x60\xe7\xd8\x4a\xd7\x0d\x3d\x4d\xeb\x5e\xa9"
-  "\x1f\x64\x5d\x59\x3f\x83\xaa\xf9\x4d\x0d\xeb\x71\x3a\xc7\xf4\xfb"
-  "\x92\xe0\x99\xc7\xf8\x80\x3f\x98\x73\xaa\xee\x4f\x24\x7d\xc8\x30"
-  "\x67\xf1\xf7\x3c\x4e\x90\xf3\x27\xf2\xfb\x21\xd7\xf1\x9a\xb0\xd3"
-  "\xde\x2c\x7d\xd9\x9c\x79\x91\xb8\x28\x3c\x9c\xe3\x79\xdd\x92\xdf"
-  "\x47\xe2\x62\x5f\xf4\xec\x92\xc9\xf6\xc5\x4b\x6c\x8f\x17\x2c\x29"
-  "\xca\x59\x22\xe3\x86\xca\x90\xa4\xc5\xab\x8b\x78\x95\xfe\x86\xe4"
-  "\x98\xb9\x42\xf3\x3b\xeb\xf7\xaf\x91\xbe\x67\xce\xcf\x40\x0f\x83"
-  "\xf2\x3d\x5b\xdf\xae\xe6\x43\x67\xd7\x85\x7e\x16\xce\xa0\xee\x67"
-  "\x01\xbe\xb2\xd4\xa8\x78\xe5\x9a\x6f\x06\xf3\xdd\xfa\x31\x17\x96"
-  "\x59\x9f\xde\xef\x67\xc4\xfe\x2e\x7d\xd9\xf2\x8c\x80\x8c\x2d\xfd"
-  "\x22\xf7\x9b\x73\x83\xdb\x7e\x2f\xef\x11\x6b\xfc\xbc\x3e\x57\xe7"
-  "\x67\xdd\x47\x8d\x61\xf1\x19\x85\xc9\x81\x48\xff\x94\xf5\x1f\x62"
-  "\x6e\xb1\xf6\xb7\xe3\x39\x03\x31\xee\x7e\x83\x8b\xf1\xd8\x11\x8b"
-  "\x07\xf0\x1b\x8b\xf4\x08\xff\x1f\xbd\x9d\xeb\xa1\xff\x6d\xb8\x40"
-  "\xc7\xbb\xfb\xde\xd9\x50\xe6\x56\xe4\x17\x27\xd3\x8c\x45\x85\x85"
-  "\x3c\xae\x17\xe5\x17\x3e\xbb\x7c\xd9\x8a\x9c\x25\x4b\x97\x20\xf5"
-  "\xee\xc5\x1c\xce\x55\x66\xb9\x43\x7b\x63\x5b\x9a\x9f\x9f\xa7\x92"
-  "\xb4\x6e\x88\xde\x1b\x51\xfb\xdf\x1b\x32\x3c\xb4\x2e\x30\xa0\xb7"
-  "\x6c\xd8\x22\x0c\xeb\x8f\xe2\xf7\x37\x39\xa6\xa5\x4e\xb1\x21\x2f"
-  "\xda\x2e\xd8\x50\xac\xf3\x83\xec\x3f\x07\xfb\x88\xbc\xfb\x55\xb7"
-  "\x90\x7b\x09\xe8\xb3\xe7\xff\xc4\xdf\x3d\xf5\xd0\xf3\x87\x59\x1f"
-  "\x8e\x80\xd3\xd0\x4f\xcb\xf5\x0f\x77\x30\x2f\x32\x3c\xfe\xde\x1b"
-  "\x9f\xcd\xc6\x7b\xf0\xff\xba\x32\xc5\xff\x1b\xfa\xf9\xbf\xdb\x90"
-  "\x08\x1b\x67\x43\x97\xae\x07\x47\x8f\x99\xe7\xe9\xc2\xb1\xc4\x3e"
-  "\x83\xcf\x5b\x75\xda\xea\xfd\xac\x78\xeb\xf9\x77\xf4\xb5\xc9\x7a"
-  "\x2d\xb6\x38\xdf\x73\x59\xd6\x71\xc5\x88\xe1\x77\xb1\x0f\xf4\x71"
-  "\x7a\x7e\x83\xe2\x97\xe7\x73\x23\x7c\x79\x2c\x27\xe9\x79\xcd\x9e"
-  "\x7d\xde\xae\xe3\x87\x76\x4e\xe1\x34\x86\xa1\xc6\xfe\xfa\x90\xe2"
-  "\x9d\xe7\x6b\x75\xda\xb2\xdd\x88\xe7\x86\x81\x39\x7d\xc3\x6c\x9e"
-  "\xeb\xb4\xb3\xe9\x7d\xdc\x7e\xc0\x99\xa0\xc3\x41\x5e\x3c\x9b\x9a"
-  "\x75\x5a\xe9\x79\x22\x79\x62\xc6\xa2\x22\x18\x75\x4b\x16\x2f\xce"
-  "\x5f\xbe\x42\x8f\xd7\x9b\xb6\xac\x30\x4f\xc5\xe7\xbd\x03\xdd\xbf"
-  "\x0a\x23\x70\x3a\x87\xf8\x45\xaa\xba\x8d\xb1\x01\x26\xb0\x1d\x2e"
-  "\xfd\xbd\xa4\xfe\xbf\xf1\xb6\x3a\xcd\x16\x38\x4e\x3f\x9b\x82\x2b"
-  "\xe4\xc1\x0b\xe7\x94\x5e\x96\x74\xa6\xc7\xf9\x42\xa1\xae\x97\x75"
-  "\x0f\x9d\x0a\xfb\xfa\x85\x12\xfd\x3b\x4c\xba\xae\xc0\x67\x51\x5c"
-  "\x4b\x39\xf6\xf9\xc6\x57\xc2\x15\x07\xec\x22\xf9\x4d\xd6\x49\x52"
-  "\x98\xef\x87\x7b\x39\x2e\x3a\xc7\x8b\x79\xe1\x30\xeb\x32\x2c\x4b"
-  "\x38\xc6\x79\x27\xbd\xb0\x85\xbf\xdd\xec\xa1\x8d\xb5\xbe\xa4\x03"
-  "\xf6\x0d\x6b\xc8\xb4\xed\x65\xf9\xfd\x5b\x4f\xf3\x76\xa6\xe3\x0b"
-  "\x9d\x87\x4a\xd4\xf7\xb4\xf9\x3b\xc4\x9b\xf0\x0e\xf6\xf0\x3e\x6d"
-  "\x2d\xb9\x52\x5b\xc7\xab\xec\x71\xfe\x0c\xfa\x5f\x4a\xa3\xe2\xcb"
-  "\x86\x6b\xbf\x5b\x46\x76\xfe\x3e\x9b\x8a\xf5\xd2\x7c\x58\x94\x37"
-  "\xd8\xa0\xc7\xf8\xa0\xff\x40\xcf\x7e\xa1\x50\x54\x34\xd8\x54\x9c"
-  "\x68\xe6\x8b\x17\x16\x72\x3b\x01\xaf\x86\xd7\x77\x78\x6d\x47\x83"
-  "\xcb\x71\xab\x12\xa0\xc7\x65\xb2\x2e\x87\xe7\xa2\xf0\xf9\x53\xdb"
-  "\x31\x77\x9b\x30\x57\xf9\xb4\xef\xfe\x14\xf3\x9a\xe7\x88\x75\x1e"
-  "\xcc\x45\xd7\x8a\x9c\xa0\x85\xf7\x1a\x86\xeb\xdf\x55\xe2\x75\x4f"
-  "\xe0\xb6\x73\x60\x0f\x01\xe5\x41\x13\xf0\x63\x59\x27\xfd\x4c\xfa"
-  "\xfa\x33\x2f\x32\xed\x7a\x41\x2f\xfe\xfe\xae\x38\x7f\x6a\x1f\xec"
-  "\xd0\xe1\x27\xe8\x67\x9f\x33\xdd\x78\xdf\x8f\xfd\x75\x90\x66\xe6"
-  "\xf8\xd1\xe8\x9f\x4f\x98\x66\x8c\x8b\x28\xdf\x55\x16\xec\xc9\xfe"
-  "\x21\x9f\x21\x64\x79\xb4\xb6\x04\xba\xdf\x62\x1e\xcb\x15\x0b\xd8"
-  "\x9e\xe3\x6f\x7e\xf0\xbd\x23\x4f\x84\x25\xcd\xd7\x30\xcd\x2b\x16"
-  "\xac\xed\x12\xe1\xaf\x9c\x24\x0e\xfb\x89\xbe\x32\x50\x30\x60\x48"
-  "\x60\xbc\x0d\x8e\x53\x7c\xce\x71\x3b\xb9\xed\xe5\x84\x7a\x4d\x9b"
-  "\xd7\x90\x85\xcf\x85\xf2\xf7\x2c\xda\xfc\xb5\xd4\x56\x54\x4b\xff"
-  "\x1a\xac\x21\xd7\x4a\x3e\xe7\x5f\x11\xfc\x37\x7b\x0d\xef\xa5\x24"
-  "\xe1\xfe\x3d\xdb\x43\x5c\x57\x79\xcd\xbf\x1d\xf9\x33\xfd\x9b\xeb"
-  "\xcf\x64\xfb\xa9\x7c\xde\xd1\x92\xfd\xaf\xd4\x92\xf1\xaf\xe4\xe8"
-  "\x14\x61\xb6\x09\x4a\x9f\xe6\x3a\xca\x01\x6b\x3b\x9f\xa7\xb4\x84"
-  "\xbb\xad\xc9\x68\xbf\x71\x9e\x9d\xa8\xcd\xef\x03\x0f\xbd\xcb\x38"
-  "\x8e\xaf\x3b\x4b\x26\xd7\xd2\x3f\xca\x7b\xa5\xab\x9f\xda\xee\xce"
-  "\xeb\x60\x3d\x29\xc8\xe7\x47\x79\xef\x09\xba\x6e\xb8\x8a\x71\x0c"
-  "\x29\xbc\xf9\x3b\xd2\x7a\x79\xe8\x51\x5a\xf9\x72\xb9\xc6\xbb\x8d"
-  "\xe9\x01\x9c\x5a\xe7\x2b\x9a\xb4\x74\x80\xa6\x0f\x69\xf4\xc9\x8e"
-  "\xa4\x4f\x79\x26\xd3\x87\x63\x0f\x86\xd1\x5f\xc0\x2d\x03\x34\x08"
-  "\xeb\x75\x00\x67\x93\xb6\x6e\x67\xda\x7c\x96\x52\x5c\x4b\xf9\xdb"
-  "\x44\x15\x6f\x98\xb3\x8c\xa6\xf0\xf9\xd3\xfb\xaa\xce\x91\x91\xfb"
-  "\x8d\xd7\xe7\xab\xe4\x7b\x49\xf3\x4a\xee\xb3\xc8\xef\x99\x33\x1f"
-  "\xf2\x37\xcd\xd1\x5f\xe5\xc0\x61\x1c\xfa\x6a\x3b\x5f\x15\x6f\x37"
-  "\xd8\xf8\x7c\xbd\xa6\xcb\x0f\xa4\x83\xb7\x83\xfc\xdd\x41\xb9\x2e"
-  "\x51\x31\x2e\x0c\xde\x66\x7b\xbe\xee\x45\x4a\x09\x3b\x9f\xf7\x6d"
-  "\x83\xac\xa9\xc5\x5c\x56\x37\x92\x2c\xbc\x96\xf5\xaa\xf4\x1f\xde"
-  "\x98\xa6\xcb\x9e\x8d\xa3\xf8\x4c\x52\xc5\x7c\x83\xfc\xbe\xdc\x81"
-  "\x6a\x8d\xcf\xab\x91\x67\xb6\x87\xae\xd8\xa1\xe4\xef\xc6\x6c\x7d"
-  "\x2c\x41\x4f\xf2\xe9\xfc\x8f\xf1\x59\xe4\x63\x7e\x97\x7e\x08\x1e"
-  "\xd8\xb0\x66\xc1\xbe\x9d\x03\xdf\x54\xdb\x58\xad\xf3\x39\xda\x56"
-  "\xc4\x72\x82\xc7\xf4\x60\x7a\x36\x74\xbc\x16\xb1\x35\x9b\x36\x9f"
-  "\x24\x4a\x59\x27\x7c\x29\x9d\x66\xd1\xe6\x6f\x91\xe7\xd9\xf8\xfb"
-  "\x89\x75\x48\xc7\xfb\x84\xb9\x7e\x9f\x19\x3a\x61\x3b\xd3\x5f\x4f"
-  "\xe7\xfd\x05\x5e\x8f\x99\xeb\x17\xbe\x79\xab\xcd\xfc\x7d\xb7\x31"
-  "\x72\xcd\x59\x4b\x6f\xb3\xf2\xbe\x83\xcf\x0c\xfa\x05\xfb\x61\x75"
-  "\x67\x27\x32\x9e\xc8\x9b\xda\x9f\xb7\x3b\xdb\xe8\xb6\xab\x3a\x23"
-  "\xd2\x86\xcc\xb3\xa3\x2c\xf7\xb7\x96\xa6\x74\xc9\x9f\x17\xf5\xdb"
-  "\x47\x1c\xa7\xaf\x1b\x73\xdf\x8a\xec\x84\x70\x77\xb6\x21\x04\xd8"
-  "\x18\x3f\x16\xf9\x9d\xb9\xa0\x4f\xfb\xd6\x4b\x17\x64\x40\x07\x89"
-  "\x4d\xc6\x22\xe4\x33\x32\x5c\x3e\x13\xcd\x71\xf2\xc5\xf0\xa1\x71"
-  "\xf5\x47\x51\x7e\x36\xcd\x55\xfa\x53\xf0\x64\xa5\x9d\x65\x42\xc8"
-  "\x74\xb0\xcc\xf6\x24\xeb\x18\x3f\xff\x92\xfb\x3f\x84\x71\x1a\x4a"
-  "\x3a\x58\x36\xb9\x8b\x12\xf8\x7b\x7f\x6a\x4d\xa3\xf2\x32\x3e\x03"
-  "\xee\x08\x0b\xe8\x6d\x95\x92\xf7\xcc\x5e\xf6\xab\x3a\xb8\x41\xfa"
-  "\x32\x25\x9f\xb6\xb9\x03\x5d\xd4\x52\xf6\x29\xb5\x04\xdd\x65\x07"
-  "\xcf\xfa\x8c\xca\xa7\xc9\x08\xb8\x95\xe3\xf9\x9d\x03\xfc\x9e\x13"
-  "\xda\x4e\x83\xad\x29\xb3\xad\x87\x79\xe8\xaf\xca\x86\xaa\xb4\xeb"
-  "\x36\xde\xd7\xb4\xa1\x9d\xcf\x91\x0b\x61\xa5\xf0\xc6\x16\x1b\x70"
-  "\x71\x88\x9e\x34\x9a\xbc\x86\xd7\x78\x2a\x77\x42\x77\xcf\xd0\xe0"
-  "\x9e\xd1\xe0\xb6\x5f\x0c\x2e\xf3\x4c\xcb\x16\xb9\x9f\x81\x36\xb5"
-  "\x58\x42\x80\x1d\x4a\x6e\xc9\x82\x0c\x77\x38\xbe\xe2\xb5\xbe\xcd"
-  "\x57\xa3\x1e\x4b\x5b\xb0\x9d\x38\x26\x45\x5d\x18\x73\xdc\x19\x2b"
-  "\x69\xfe\x5b\x8e\xd3\xb4\x89\xd7\xaa\x2d\xb0\x45\x79\x1d\xdf\xc1"
-  "\x72\x92\xed\xda\xd2\x10\x0d\x75\x43\xab\xe1\xf3\xd4\x80\x71\xd9"
-  "\x87\xbc\x67\x02\x59\x13\x12\x56\xc3\x7b\xe7\x3d\xc4\x3e\x1a\xf2"
-  "\x7c\xf5\xfa\xab\x5e\x1d\xb1\x8e\xee\x12\x06\xb3\xf4\xcf\x0b\x57"
-  "\x78\xd3\xd0\xb7\x76\x89\xcf\xc6\x03\xb5\x11\xbe\x62\x89\xa8\xeb"
-  "\x79\xf6\x15\x13\xa6\x03\x79\xb5\xbc\x87\x91\x74\x9a\x7c\x49\x5e"
-  "\x9f\x40\xdf\xf5\x38\x37\x35\x7a\xe8\xe7\x72\xcd\xb6\x92\xfd\xab"
-  "\xa5\xbc\xde\x3c\xde\x97\xf4\x31\xef\x49\xf0\xd9\xab\x84\xf0\xca"
-  "\xd0\xbe\xaa\x2f\xc9\xa8\xe8\xb2\x79\x48\x9b\xb7\xc7\x25\xca\x3f"
-  "\x0e\xf0\xd9\x19\xad\x0e\x33\xea\xf8\x8b\xa8\xf8\x38\xe0\xa1\xcd"
-  "\x9a\xcc\xe0\xfb\x4d\x3e\x7e\x1f\xec\x4b\x83\x6e\xb4\x29\xaf\xb6"
-  "\x97\xd7\x92\x37\x59\x84\xf3\x5a\x57\xb7\xe9\xe3\xc0\x83\x56\xd6"
-  "\x8f\x36\x4f\xf5\x24\xec\x0f\x6a\xeb\x4b\xf2\xcc\x78\xec\xba\x50"
-  "\x7f\x5f\x6e\xb5\x26\xbb\x01\x04\xf6\x5e\xea\x49\xaa\x7e\xa3\xd7"
-  "\x49\x86\x3e\xe8\x75\xbd\x06\xe8\xef\x5b\xb3\x53\x36\x8f\xa6\x74"
-  "\xbc\x1b\x7d\x92\x36\x6f\x0a\x1a\x28\x15\x3f\x8b\xef\xaa\x82\x24"
-  "\xc0\xcd\xe0\xb5\xb7\xd6\xb3\xbc\xd6\xb2\xf9\x94\xd4\xbb\x5e\xa5"
-  "\x71\x61\xc0\xe3\xfd\x82\xaa\xd1\x34\x8e\xd7\xbf\x90\x96\x96\x13"
-  "\x52\xfb\x66\xba\xad\xbe\x7e\x34\x4d\x88\xae\x77\xb3\x76\x16\xbc"
-  "\x5a\xae\xa5\xaf\xf2\xd1\x35\x45\x77\xf2\x77\x01\xab\x0a\x84\x33"
-  "\x51\x88\xab\xac\x06\xb5\x9f\x5d\x75\xbf\x79\x8b\xe2\x3f\xb9\x4f"
-  "\x04\xbe\xe3\x7d\x38\x6d\x4f\x22\x41\x9e\x95\x4f\x3e\x64\x11\x7d"
-  "\x69\x86\x88\xf5\x47\x8b\xc4\x43\x3b\xe7\x1a\x5a\x7f\x63\x2e\xc3"
-  "\x60\x7c\x72\x16\xa9\xfd\x0c\x3e\x03\x0b\x1a\xcb\x78\xac\x95\xaf"
-  "\x52\xca\xcf\x5f\x25\x4b\xeb\x62\x6e\x57\x95\x2a\x63\x30\x12\xe3"
-  "\x1b\x2e\xe7\xf1\x06\xde\x00\xde\x5c\x9f\xfc\xa6\x6e\xf0\x8c\xcb"
-  "\x51\x2c\xc2\xae\x27\x59\xaf\xac\x3a\xe4\x5a\xde\x40\xf3\xf8\xcc"
-  "\x30\x9f\x17\x5a\x48\xbe\x7a\xc0\xab\x1f\x4d\x16\xc0\x6a\x75\x17"
-  "\x12\xaf\x77\x5f\xe7\x5a\xbe\x9f\x61\x1f\xe3\x79\x65\x13\xe8\xa3"
-  "\xe6\x97\xea\x1a\x77\xa0\x83\x5a\x31\xce\xe7\x16\x89\x10\xc3\x39"
-  "\x41\xd5\x57\xca\xf6\x6e\xb5\xda\x72\xd4\x39\x65\xd9\xd6\xfe\x7d"
-  "\x22\xad\x1d\xee\xb3\x0c\xaf\x7a\x82\x3b\x17\xf6\xad\xd6\x26\x9d"
-  "\xd6\x8a\xbf\xaa\x97\xb8\x96\xef\x20\xee\x1f\xce\x8f\xe7\x6c\xb7"
-  "\x17\x79\x4f\x45\xf7\x0b\xe7\xc1\xbb\x0a\xc0\xfd\xfe\xc0\x5e\x27"
-  "\xef\xc1\x0d\xe4\xa9\x7d\x95\xcf\x43\x6c\x6e\xd9\x0a\x1a\xa9\x35"
-  "\xe3\xaa\x73\x8c\x2b\x46\x91\xdf\x5d\xfc\x69\x7c\x3f\x46\xc8\x00"
-  "\xf0\xfd\xba\x36\xb9\xe7\x53\xfd\xf9\xdc\x60\x58\x28\xb9\xf6\x8b"
-  "\x2d\x61\xc8\x03\x0f\xae\x2c\x13\xa4\x5c\x99\xc4\xbe\x23\xbf\x78"
-  "\xc5\x9c\xa0\xfa\x97\xdb\xc2\xba\x4f\xbc\x3e\x8e\xd8\x8f\xb2\x30"
-  "\xae\x7a\x1f\xf3\x37\xcd\xc2\xbc\xa7\x38\x1a\xf4\xee\xb3\x92\xe2"
-  "\x3f\x51\x0d\xb8\x9a\x7f\xfc\x01\x2d\x9e\xc1\x81\xa3\xdd\x49\x07"
-  "\x2b\xc5\x73\x56\xd2\xfd\x49\x31\x7e\xcb\x73\x94\x8f\xae\x95\x65"
-  "\x55\xbd\x41\x8d\x1d\xc6\x51\x2b\xdb\xa1\xf6\xf1\x7f\x91\x8d\xf2"
-  "\x71\xe3\x27\x89\x44\xc8\x1f\x27\xc4\x35\xda\xc3\xf3\xa7\x80\xcc"
-  "\xc2\xbc\x30\xd4\xed\xef\xd5\xbe\x1d\xf7\xe2\x15\xd0\x99\x87\xf2"
-  "\xd9\x04\x1d\xb7\x4b\xdb\x3b\xfa\x85\x47\xd9\x29\x2f\xda\xf4\xb5"
-  "\x17\x61\x02\x8d\x9d\x66\xc1\x67\x78\xd8\xd7\xdc\x9f\x74\x36\xdd"
-  "\x37\xdc\x98\xab\xc6\xcd\x8b\x33\x45\x92\x92\xbb\x39\x01\x2a\xe3"
-  "\x76\xf1\xde\x20\x6c\xa0\xa1\xdc\x66\xc0\x29\xf0\xd0\xe2\x16\x35"
-  "\xaf\x2b\xd8\x83\xae\x7d\xe8\x6d\x43\x9b\x64\xdb\xd0\x46\xd9\x36"
-  "\xed\x9b\x2b\xa8\x4b\x9e\xdd\xbd\xb4\xf6\xbc\xa8\xe9\xfb\x67\xd3"
-  "\xf9\xbb\x90\x27\xa8\x66\xad\xf4\xb7\x46\x9f\xa8\xf5\xf5\x97\xa6"
-  "\x8a\xe4\x9f\x27\x5f\x1a\xcc\x97\x8c\x12\x66\xa5\x31\xf7\x97\x1c"
-  "\x9f\x4d\xfb\x6e\x13\x60\xe7\x43\xa6\xf3\x3a\xbd\xbf\x1b\xf5\xf1"
-  "\x37\xef\x06\xe4\xd0\x4b\x5d\xdc\x57\x93\x1a\x28\x43\xf1\xe1\x4b"
-  "\x9f\xd5\xa9\x6f\xee\x40\x37\x78\xa9\x12\x7c\xaf\xbe\x59\xd3\xef"
-  "\x7b\x9c\x20\x7d\x8f\x23\x65\xec\x25\xe2\x28\xe5\x9d\x48\xfe\xef"
-  "\x76\xdc\x97\xf0\x7e\x3a\xe3\xbb\x2a\xa8\xcb\xbf\x97\x4a\xf4\xbd"
-  "\x25\xb9\x9f\xbc\x1a\xbc\x52\xaa\xce\x2e\xf6\x38\x6b\xc6\xe8\xba"
-  "\x8a\xfc\x4e\x8f\x53\x1c\xe6\x7c\xf3\x56\x9f\x91\xfb\xcd\x55\xf2"
-  "\x9c\xee\x49\xed\x8c\x4b\xcd\xcd\xda\xda\x44\x1a\xfb\x7d\xa3\x2c"
-  "\xf4\xbf\xfd\xd2\x8f\x9f\x69\xc0\x75\x4b\xdc\xe5\xb7\x72\x6a\x8a"
-  "\x07\xf6\x13\x5e\xca\x92\xe9\xd2\x17\xb2\xa6\x52\xe7\x11\xb4\x77"
-  "\xa8\x8a\x97\xf7\xe2\xb9\xa6\x09\x24\x79\xa0\x5b\x58\x93\xaf\xaf"
-  "\x65\x9e\xac\xd9\x1f\x49\xa7\x79\xc1\xb0\x43\xc9\xa0\x97\x6a\x85"
-  "\x1c\xeb\x2f\xd5\x7e\xbd\x5e\xf1\xcb\x24\x5d\x27\x51\x74\xb6\x40"
-  "\xbe\xfc\xea\x88\xa4\x75\xf9\x2e\x17\xc7\x32\x78\xae\x94\xe3\xb1"
-  "\xfc\xf2\x4f\x1c\xeb\x26\x58\xbe\xcb\x13\xe2\xf3\x50\x8b\xd9\x27"
-  "\x65\x97\xef\x44\x11\x19\x72\x8a\x78\x0f\xe5\x63\x17\xdb\x6a\xc2"
-  "\x01\x9d\x20\x19\x7a\x0a\xc6\xf9\xda\x25\x64\x7e\xa4\x00\xb0\x1d"
-  "\x69\xa9\x1c\x8b\x86\xe3\xd0\x70\x3c\xa9\x90\x23\x6d\x24\xee\x47"
-  "\x41\xaf\xb3\xf0\xb7\xe1\xd9\xdf\x22\xe4\x14\x90\xc7\x47\x39\x1e"
-  "\x8e\xc1\xed\x0b\xd0\xda\x53\x64\xe2\x58\x37\xc1\x8a\x8f\x3b\xda"
-  "\xfc\x9f\x49\x3b\x65\x44\x11\x74\xf3\x30\x8d\x01\xcd\xad\xe1\xa4"
-  "\x8f\x5d\x98\xe3\x9b\x55\xbb\xcf\x08\xd5\x6e\x85\x37\xe3\xaf\x64"
-  "\xdc\x6e\x5f\xa9\xc4\xfd\x57\x4f\x07\x01\x3f\x5c\xfe\xb6\x37\x54"
-  "\xfe\x76\x97\x3a\x47\xd5\x42\xa5\xc5\xa2\xcb\x0d\x1d\x99\x7d\xfe"
-  "\xf8\x4c\x19\xfb\x73\x70\x1b\xb9\x7d\x5c\xf7\xbf\x9d\x3d\x25\x63"
-  "\xf7\x04\xf1\xec\x28\xd4\xca\x78\x51\xc6\xdb\x42\xbd\xe5\x6f\xcb"
-  "\xb6\xb7\xf9\x55\xd9\x1c\x79\xcf\xe5\x23\xe8\xa0\xb5\xb9\x9f\x0e"
-  "\x68\x3b\xb7\x8f\xdb\x1f\x64\x9a\x80\x06\x5a\x5b\xad\x7d\x5a\x3b"
-  "\xb9\x8d\xff\x8a\x59\xe7\x55\xb4\x13\x6d\x95\xed\xec\x43\x3b\x0f"
-  "\x17\x10\x05\x36\x9e\xcd\xf8\x2a\xf9\xed\x2e\xb6\x35\x1d\x9f\x40"
-  "\x9f\x2e\xa9\x26\xd8\x94\xc6\xdd\xa5\xd5\x86\x8d\xd0\x4d\x4a\x7d"
-  "\xb0\x2d\x7d\xa2\x8b\xf5\x7e\x77\x11\x7e\xc1\x5a\xf9\xcd\x4d\xa9"
-  "\x27\xf3\x37\x13\x9f\x41\x9b\xc2\x9f\x53\x69\x97\xe8\x82\x8e\x0a"
-  "\xfd\x07\x79\x0a\xd0\x7e\xd8\xa2\x27\x34\xfc\x39\xef\xda\x2f\x55"
-  "\xbb\xcc\x85\x94\xfa\xc1\x4f\xcb\x0d\xee\x8e\x72\xd2\xdb\xf2\x28"
-  "\xf2\xa1\x3d\x56\xc0\x92\x71\xe3\xc2\x68\xe7\x56\xe0\x19\x88\x68"
-  "\x53\xab\x37\x00\x98\x7f\xa1\xe4\x2c\x4a\x78\xf5\x34\xda\x71\x9a"
-  "\xac\xd5\xa5\xd0\xbf\x1e\x60\xbd\xf1\xe5\xd7\xbf\x95\x4d\xe3\x3c"
-  "\xf4\x4b\xf5\xbd\x8a\xfe\xef\x9a\xff\xaa\x55\x8f\x9f\x11\xe6\xf8"
-  "\x43\x49\x1f\x1f\x65\x3e\x92\xb1\x34\x78\xce\xe8\x01\xcf\xb0\x2f"
-  "\xc6\x2a\xd4\xd1\x93\x36\x4a\xe2\xe3\x54\xf1\x37\xf0\xcc\x73\x5e"
-  "\x2a\xaf\x2f\xa0\x5c\x87\x00\xcd\x18\x3e\xf4\xb9\x66\xbe\x32\x0d"
-  "\xe3\x9e\x4f\xd8\x43\x90\x75\xd0\x35\x61\x47\xef\x2b\xf5\x19\x9e"
-  "\xdf\x43\x13\x2e\x4d\xa6\xfc\x2a\x38\x98\xfc\xe6\x75\x7d\x86\x87"
-  "\xb6\x8d\x3c\x49\x5b\x8e\x45\x8f\x31\x9b\x94\x65\x4a\x0e\x6e\xd9"
-  "\xc9\x6b\xe9\x97\x56\xef\x16\x15\xb7\xc7\x29\xca\x2f\xb1\x5c\x83"
-  "\x8e\x07\xee\x0b\x06\xc3\xfd\xd2\xe9\xf0\x8a\x71\x30\x58\x9b\x5e"
-  "\x96\xb1\x94\x1c\x9b\x5f\x86\xbc\x80\xae\xd0\x64\xe5\xb8\xb6\x98"
-  "\x3b\x77\xf8\x69\xc5\x36\x32\x39\x4e\xf1\xfa\xce\x1c\x6a\xaa\x4d"
-  "\xa7\x3a\xd8\xf7\xa2\x3b\x6d\xe4\x4b\x67\x79\x4f\x5d\xc9\x10\xd6"
-  "\x49\xdb\xfc\x28\xb3\x22\xcd\x52\xf5\xb2\xae\xc3\xbf\xd2\x5a\x72"
-  "\x8e\x0c\xea\xbb\x01\xaf\xb4\x64\xda\x44\xb0\xc6\x10\x2e\xa8\xe5"
-  "\xd8\x32\xc9\xde\x2c\x8e\x2d\xa3\xc7\x5a\x91\xba\x8f\x1d\x63\xae"
-  "\xdb\x9a\xbc\x69\x39\x4d\xe0\xb8\x50\x66\x9f\xd2\xe5\xd4\x7c\xfd"
-  "\x0a\xcb\x58\x8b\xb6\x8f\x6c\x51\xf1\x57\xb6\x64\xd6\x9f\x45\x5d"
-  "\xf2\xfd\xab\x13\x43\xb0\x65\x24\xdc\xe5\x34\xae\xf6\x2c\xa5\xb1"
-  "\x1e\x94\xf3\xb9\xd2\xd9\xd8\x3e\x9c\xe3\x35\x8b\xd0\x7f\xa7\xd1"
-  "\xb6\x93\x03\x71\xa3\x7c\x2b\x38\xd6\x94\xb0\x0e\x76\x46\xb4\x6a"
-  "\x94\xf4\x19\x91\x31\x00\xd4\x77\xa5\x88\x6a\x5e\x24\x23\x7f\x47"
-  "\x91\xd7\xea\x78\x9d\x97\xcf\x8a\xa8\x39\xe4\xd5\x5a\x3d\xae\x4e"
-  "\x7c\x59\x7e\x9a\xcf\x78\x42\xc7\x3a\x7d\x89\x7c\xf4\xea\xc1\x41"
-  "\x6d\x15\xc0\x64\x3e\xf8\x9f\xc1\xdd\x9a\x7a\x11\xbd\xc6\x18\x2e"
-  "\x57\xb6\x59\x78\x28\x6c\x46\x5f\x8f\xcb\xb5\x92\xe7\xb7\xad\xd5"
-  "\x7c\x96\x66\xc0\x1e\xdb\xfa\x0c\xbf\xe3\x34\xf6\xf5\xce\x90\xfd"
-  "\xbe\xb5\x91\x6d\x34\xcd\xce\xfd\xc0\xd6\x9f\xa6\xf4\x2d\x9e\x77"
-  "\x99\x5e\xf5\x6a\xfd\x7a\x44\x8f\x73\xeb\x11\x7d\xee\x65\x1d\x44"
-  "\x7d\x6f\x72\x6b\x97\x27\xe1\x9f\x07\x3d\x57\xa7\xaf\xe7\x4b\x9f"
-  "\x2e\x8e\xeb\xe3\xac\xb5\xea\x73\xb1\xfc\x9e\xc0\xfa\xd1\xf7\xac"
-  "\x58\x4d\x63\x1e\xbc\x92\xf7\xb4\xe5\x99\x88\x2e\xa5\x23\xd4\x66"
-  "\x0c\xec\x8d\x65\x48\xde\x90\xdf\x0a\x63\x7b\xc8\x00\x7d\x41\xc5"
-  "\xb3\xf2\x2a\x5d\x41\x3f\x0f\x5b\xfb\x48\x44\x3d\x65\xfd\x73\x3e"
-  "\xea\x60\xdf\x06\x86\xaf\xf4\xa8\xda\x29\x5c\x07\xdb\x81\x4a\x17"
-  "\xa8\x9d\x72\x11\xfa\xa6\x31\x7d\xc3\x9a\xed\xeb\xf6\xfe\x4d\xd1"
-  "\xd7\x4e\x89\x93\x6b\xc8\xfa\x41\xa9\xc7\x88\x39\x26\xc1\xb6\x9c"
-  "\xcc\xa8\xff\x13\x7e\xcf\xe3\xd2\x35\x89\xd7\x20\xb7\x4d\x74\xb3"
-  "\x8e\xd1\x97\x9d\x32\x97\xd7\x27\xa4\xdd\xb0\x6d\xcc\x44\x94\x43"
-  "\xda\xc8\xf7\x4f\x07\x8c\x55\x6b\x68\x02\x7f\x93\x0f\xe9\xd2\x07"
-  "\xc1\xf7\xed\xa7\x7a\xae\x4f\x25\xeb\xf5\x35\xec\xef\xbe\x2d\xd3"
-  "\x93\xf0\x8e\xf2\xfd\xe5\xfa\x37\x1b\xab\x39\x96\xd7\xde\x5e\xcf"
-  "\x10\xd5\x57\xdb\x8e\xe1\x39\x2d\xe2\x79\xad\xbe\x87\xe0\xa1\x6d"
-  "\x1e\xb9\x0f\xc9\x3e\xbd\xd2\xdf\xd5\x1b\x18\xf0\x95\xd9\x76\x4c"
-  "\xc3\xe5\x58\x53\x11\xd1\x36\x3e\xc7\x30\x4a\xb4\xa3\x3e\xe8\x3f"
-  "\x5b\xfd\xda\x1a\x52\xbb\xe4\x2b\xd6\xcd\x5f\x60\x7b\xf1\x6f\xae"
-  "\x4d\xc8\xc7\x73\x5a\x8e\x9d\x32\x94\xbd\x71\xca\x12\x06\xff\x0c"
-  "\xb4\x7f\xdb\x1c\x5e\xe3\x8c\x2b\xbf\x5f\x25\x92\x65\x2a\xbc\x53"
-  "\xa5\x7f\xd5\xa6\xa1\x3e\x5c\x4d\x18\x0b\xfc\x2e\x05\x3c\xc7\x57"
-  "\x0b\xae\x6c\xeb\xa5\x42\xcf\x6d\x67\xbe\x84\xbd\x6d\x85\x4d\xc3"
-  "\x7b\x9a\xe9\x83\x9d\xc5\x63\xda\xb8\x37\x3c\x44\xca\x5f\xb4\xae"
-  "\xb9\xd5\x07\x5d\x12\xe4\x5c\x11\x14\xbd\xb6\x6b\xf8\xcc\x4b\x5d"
-  "\xb3\x63\x1b\xfb\x7b\xd4\x6d\x89\xf6\xf7\xa8\x6b\xc4\x2f\x00\x0e"
-  "\x9f\x8d\x1f\xf4\xc8\xba\xe6\x81\x5f\x7d\x63\x8f\xb3\x0e\xf3\xdd"
-  "\x36\xb9\x16\x71\x69\xe3\xb5\x4e\x7e\x23\xae\x8a\x6d\xb8\xa4\x16"
-  "\x52\xed\x35\x66\xe0\xd9\x24\x86\x1b\xcb\xb4\xf6\x5a\xf1\x6c\xb1"
-  "\x39\x30\x07\x27\x81\x26\xa3\xd1\xe6\xe1\x43\x7d\xdc\x5e\xc6\xb7"
-  "\x3b\xe9\x74\xd4\x39\x44\x86\xc9\xed\xf7\x25\xa1\x1c\x68\x29\xbe"
-  "\xf3\xf8\x3e\x9d\x9e\x1a\x9d\x78\xbf\xca\xd0\x0d\x18\x4a\x67\x43"
-  "\x7e\xc0\xd0\xf3\xf7\xd3\x7e\x34\xc7\xc7\x47\x9f\x22\x1f\xec\x77"
-  "\x93\x7e\xc6\xb1\xc7\x59\xbf\xef\x50\xa1\xda\xcb\xe0\xb2\xfe\x88"
-  "\xb2\x7c\x36\x3e\xaa\xfc\xf0\x88\xbe\x1b\x8d\xb6\x24\x7d\xec\x53"
-  "\x7d\xe7\xcd\xd0\x70\x49\x95\xb8\x24\x79\x7d\x27\xa8\xee\x43\x85"
-  "\x4f\xfd\x8e\xc1\xc6\x58\xe9\x58\xe8\xa8\x90\xc8\x93\x95\xed\x3a"
-  "\xcd\x3d\xc6\x4f\xee\xda\x30\xf4\x96\x53\xe9\x19\xa5\xc2\x75\x82"
-  "\xb6\xaf\x6d\x0b\x74\x5d\xa2\xcc\xdc\x2e\xe3\x54\x89\xde\x32\x72"
-  "\x97\xdc\x22\xbf\x51\x7b\x9a\x5e\xdb\xed\xf6\xc9\x58\xcf\x7c\x2f"
-  "\x7d\x78\xd9\x17\x83\xe7\x37\x8e\x7d\xa6\xaf\x13\x84\x91\xb7\x8e"
-  "\xd3\x91\xe6\xf6\xfb\x64\x8c\xb5\x01\x5f\x6a\xaf\x55\x8d\xb5\xd7"
-  "\xf2\xe5\xf9\x6d\xc6\x37\xf8\x43\x17\xe3\x8c\x31\x66\xe5\x36\x38"
-  "\x60\xc3\xba\x83\x3d\x2e\x1e\x2b\xb6\x95\xbc\xee\xf9\xda\xdd\xe0"
-  "\x47\x11\xae\xf0\x5a\x2f\xad\x0d\xaf\xc9\x18\xc1\x8e\xa0\x38\xed"
-  "\x4b\xf2\x5a\x59\xaf\xaa\x2a\x1d\x62\x9a\x51\x2b\x5c\xdd\xc9\xa7"
-  "\xd2\x7b\x9c\xaf\xe5\x1d\xb2\xab\x3e\xbb\x44\xb8\x79\x7a\xdb\xeb"
-  "\xb4\xb6\x83\x5e\x92\x67\x27\x6f\x51\x31\xe5\x90\xa7\x76\xf0\xb9"
-  "\xec\x94\x85\xe7\x32\xf6\xf3\xd4\x68\xe1\xed\x9f\x33\x2e\x0d\x8f"
-  "\xc1\x63\x63\x0f\xd4\xd1\xa7\xea\xf8\x75\xd6\xff\xac\x8e\x5f\x67"
-  "\x5d\xac\x0e\xc8\x8c\xab\x4f\xd2\xaf\x8f\x5e\xba\xfd\xfb\x6b\x69"
-  "\xff\x86\xcb\x4f\x59\x95\x2c\xdd\x31\x27\x04\x1b\x34\x98\x62\xcc"
-  "\x90\xdf\x93\x31\x50\x99\xdb\x13\xa4\x60\x79\x0b\xb5\xda\x7b\xc9"
-  "\xb5\xf2\xcf\xd4\x49\xbf\x91\xf1\x5f\x5b\x21\x7f\x60\x2b\x97\xf5"
-  "\x6d\x3c\x55\xd6\x67\xf8\xf5\x04\xa6\xf7\x36\x8e\xdf\x17\xc1\x67"
-  "\x6d\xfe\x3f\x93\x3b\x97\xd7\x8a\xdb\x79\x8d\xbe\x0c\x72\x23\x23"
-  "\x0c\x99\x01\x3b\x23\x24\xe9\x01\x1d\x4c\xd9\x8c\x67\xd3\xa4\xcd"
-  "\xe8\x93\xe7\xf2\x86\x43\x77\x4f\x11\xce\xc5\x1b\x78\x1d\x3f\xd4"
-  "\x97\x6d\xeb\x71\x52\x16\xc7\xd2\xe3\x35\x74\x61\x3a\x50\x32\x2f"
-  "\x98\x28\xa4\x4d\x08\xfb\x85\x63\xea\xb9\xfd\x1e\x0a\xc1\x16\xa8"
-  "\x3d\x4f\xa9\xb5\xd0\x9f\x21\xcb\xa5\xbc\xaf\xd7\x62\xea\x6d\x3a"
-  "\x3f\x10\x53\xaf\x8e\xd7\xab\x3a\x70\x7f\x9e\x8c\xa1\x8a\xb3\x69"
-  "\x5b\xcf\xd3\xb8\x6d\x2b\x29\x6d\x2b\xaf\x47\x7e\xa1\xf4\x37\xd6"
-  "\x37\x64\x7c\xbd\x65\x69\xbc\x37\x31\xa0\xbf\xad\xe2\xb8\x9f\xfd"
-  "\xf2\xcc\x28\xd7\x71\x2e\x89\xde\x3b\xe4\x37\x02\x82\xe5\xde\xa9"
-  "\xc1\x94\xa1\xbe\xbe\x8d\xa7\x91\xf6\x9b\xd9\x7d\x86\xd7\x0e\xc7"
-  "\xeb\x5b\xdd\xd7\xaa\x26\x22\x26\xe2\xa1\x71\x4a\xee\x03\xd6\xe0"
-  "\x71\xd9\xb6\x66\xd3\x64\x2f\xa5\x2b\xff\x89\x24\xcc\x95\x3b\xfc"
-  "\xbc\x9f\x5f\xfa\x34\x59\x43\x5b\x17\x26\x38\x5e\xa3\x44\xfe\x7e"
-  "\x31\xff\x4a\xbf\x14\x5d\x93\x0b\x29\x9d\xf7\x52\xd8\xc7\xc2\xf6"
-  "\x9c\xcc\xff\xe1\xb8\x12\x4a\x8f\x84\x3d\x53\x39\x3f\xdd\x61\x9b"
-  "\xb5\xf4\xf1\x65\x4f\x17\x2d\x2a\x5e\xf2\xd8\x92\xc2\x25\xc5\xab"
-  "\xef\x90\xc1\x84\xe5\xbf\xfb\xc6\xe7\xcd\x97\x9b\xe0\x11\x7a\xc7"
-  "\xb8\x81\x35\xc5\xd7\xd7\x86\x78\x0d\xe4\x92\xe8\xf5\xfa\x4c\x6d"
-  "\x5f\xd1\xb7\x4d\xee\xb3\xbd\x5e\xed\x49\xf8\x43\xa6\x5a\xdb\x38"
-  "\x4d\x9b\x54\x3c\x94\x2e\xd7\x75\x21\x86\x2f\xf3\x86\x2b\x8d\xed"
-  "\xe0\xe5\x69\xc7\x69\xe7\x42\xde\xdf\x41\x7f\x99\xdc\x25\x27\x09"
-  "\x3a\xca\x34\xde\x37\x6a\xe5\x35\x19\xa9\xc3\xff\x56\x9d\x61\x38"
-  "\x2d\x63\x03\xed\x38\x8e\x67\xf6\x55\x0f\x8b\xec\xad\xa1\x65\xd6"
-  "\x1d\xe1\x65\xd6\xdf\x0a\x91\xfd\x6a\xf8\x4c\xc1\x56\x71\xa6\xe0"
-  "\xd5\x81\x73\xfd\xbf\xbd\x22\xe8\xa4\x44\xfc\xc0\x0b\xbb\xd3\x23"
-  "\xf6\x10\xf9\xdd\xed\x0c\xb3\x68\x39\xfb\x72\xfd\x96\xfd\xa3\x61"
-  "\xfb\xef\x9e\xec\x73\x14\x24\xce\xee\x04\xcf\xab\x7a\xf3\xdd\x1b"
-  "\x4e\x90\xda\x37\xfe\x6d\x9e\x4b\xae\x73\xff\x36\xc4\xe5\x78\x9f"
-  "\x91\xf5\x7e\x19\x3f\xd4\xf0\xba\xf4\xe5\x63\x9d\x7f\xdb\x48\xb2"
-  "\x54\x8f\xa4\x94\x1e\xe7\x6f\xfb\xfd\xbf\x84\x49\xcd\xad\x3c\xbf"
-  "\x71\xbc\x5b\xc8\x98\x1e\x9e\x2b\x19\x0f\xe6\x4b\xc0\xe4\xf3\x59"
-  "\xa9\xea\xdc\xcf\x6f\x0f\x43\x8f\xdc\x79\xe9\x32\xf6\xb7\x72\x4d"
-  "\x5e\x18\x1c\x62\x72\x25\xe5\xca\xfd\x61\xe5\xa7\x68\xc4\x38\x2c"
-  "\x52\xed\xd9\x79\x9b\xdc\xdb\x5f\x79\x6a\x3b\xc6\x49\x59\x7d\x2f"
-  "\xa5\x84\xcb\x0f\x14\xb3\x3e\xd3\x5a\x22\xf7\xd5\x4d\x28\xb7\x8f"
-  "\xf7\xdd\xe5\x59\x39\x19\x3f\xf9\xcf\x54\x7f\x8e\x8c\x9d\xf4\xbb"
-  "\x4c\xde\x1f\x18\xa0\xed\xef\x5e\xe1\x7d\x21\xb1\xf1\xcd\x9d\xe6"
-  "\x12\x43\x39\xc3\x08\x9f\x3f\x3d\x55\x2f\x87\x39\x7c\x18\x97\x3b"
-  "\x4e\xbf\x5b\x2b\xcb\x71\x5e\xf9\xed\x3d\xcb\x42\xcc\x5b\x53\x39"
-  "\x7f\x10\xcf\x75\x61\x4b\x96\xc0\xf8\x0a\xad\x0c\xed\xc3\xbb\xf9"
-  "\xe1\xf2\xd3\x26\xa4\x65\xcb\x75\xe9\x3e\x2b\xc9\x18\x1d\xa6\x8f"
-  "\x03\x6e\xcf\xdf\x5c\x12\x1f\xf6\x57\x2d\x86\x2c\x92\xfa\xdf\xef"
-  "\x3e\xa9\xfb\x42\xc6\x75\x46\x1f\xee\xcc\xd3\x78\x64\xa7\xc2\x6f"
-  "\x67\x7e\xf7\xc6\xb7\xbb\xba\x4d\xa7\x4c\x7e\x83\x89\x9a\xac\x01"
-  "\x96\x81\xed\x4d\xd6\x5e\xd8\x10\x3b\x27\x78\x0c\x6f\x5a\x95\xee"
-  "\xa1\xca\xf1\xbe\x14\xf4\x52\x6f\xa2\x75\x44\x1f\xde\xcf\xd6\xfd"
-  "\x3b\xf8\x7b\xd5\xbc\x2f\xe5\xa1\xdf\x8d\x63\xba\x81\xcf\x5b\xe4"
-  "\xde\xc4\xfa\x87\xbb\xd0\x9e\xa1\xec\x83\xc7\x74\xe6\xf3\x07\x66"
-  "\xdc\x8b\x95\x62\xaa\x39\x98\x61\xa8\x97\x67\x0d\xe5\x19\xf6\x29"
-  "\x5a\x9c\x91\x74\x2d\xee\xc8\x04\x7e\x56\x67\xe0\x77\xee\xd7\xcf"
-  "\x9c\x73\x6c\x15\xed\xbc\x98\xf4\xeb\x93\x31\x47\xce\xaa\xbd\x5d"
-  "\xf6\xeb\xe3\x35\x4d\xf6\x93\xe7\xfd\x57\x94\xf3\x46\xf8\xc6\x27"
-  "\xe0\x39\xa8\xc7\x1a\xe9\x71\xbe\x61\xea\xf7\x17\x42\xdb\xbb\xcb"
-  "\x4f\x91\x3f\xc5\xd8\xee\x2f\xf7\x62\xfe\x7e\x63\x1c\x64\x51\xe1"
-  "\x45\x6c\x27\x23\x9f\x3d\xe4\xf8\x12\xe1\xe4\x03\xb5\x1c\x63\x82"
-  "\x63\x59\x29\xff\xf6\x37\x9e\xd7\xce\x74\x27\x9e\xa6\x37\xee\x1e"
-  "\xd8\x07\x0d\x69\x6b\x77\x6f\x34\x28\xbd\xeb\x8d\x06\xb9\x76\xb7"
-  "\xd1\xeb\xf9\xcd\x9a\x80\x61\xdf\x1a\x8f\xa1\x4e\x9e\xef\x7a\x03"
-  "\xb4\xdb\x5b\xa8\xfb\xc8\x20\x5f\x2e\xc3\x8a\x3f\x4f\x1e\xca\x56"
-  "\x30\xdf\x94\x31\x4a\x07\xec\x9b\x37\xd5\x77\x8f\xd6\x8f\xce\x0d"
-  "\xf3\x9c\x97\xdc\x62\x91\xbe\x25\x45\x67\x79\x0d\x6f\xa8\xb2\xb5"
-  "\x54\x1e\xcd\x2f\xf3\xf2\x93\xd1\xcf\x23\xf9\x59\xd1\xec\xcd\x74"
-  "\x7d\x3f\x60\xb3\x21\xec\x31\x27\x90\x70\x6c\x17\x7e\x8e\x61\x06"
-  "\x7d\xca\xe7\xc6\x1c\x8a\x3a\x04\xe4\xc3\x30\x94\xc9\x67\xda\xab"
-  "\x31\xf4\xa6\xfc\xbe\x47\xd8\x79\x97\x70\xb0\x1e\xe9\x63\xdf\x96"
-  "\xb3\x84\x7c\x97\x21\xdf\x2f\x9a\x4b\xbc\xec\x3b\x53\xc0\xb1\xc1"
-  "\x3a\xb5\xba\x7d\x49\x87\xb2\xaf\x4f\xa1\x5c\xd4\xb9\xc3\x43\x25"
-  "\x25\x97\x3e\xb6\xdf\x1c\x54\x97\x1d\x68\xd7\xae\xd4\x81\x3e\xf9"
-  "\xab\xd6\x27\xbb\x52\xbf\x6e\x0f\x59\xd3\x49\xae\x38\x49\xbb\x87"
-  "\xb0\xdd\x8c\xfb\x6b\x4f\x52\x83\xdc\xa3\x54\xbe\xc8\x0d\x7f\xd2"
-  "\xee\x51\x47\xc3\x5b\xda\xfd\x55\xb8\x7f\x45\xbb\x1f\x8d\xfb\x75"
-  "\xda\x3d\xe8\xdd\xb0\x44\xbb\x4f\xc5\xfd\xfd\xda\x3d\xc6\x67\xc3"
-  "\xed\xda\xfd\x28\xdc\x8f\xd5\xee\xaf\xc4\x7d\x92\xb6\xf7\x66\x02"
-  "\xbe\xe7\x2e\x5d\x2f\xda\xe5\x52\xfb\x3b\xbc\xaf\xf6\xfa\x04\x35"
-  "\xa6\xfb\xd3\x52\x61\x5f\xce\xd7\xd7\xd7\x91\xde\xc8\xf5\x20\x7d"
-  "\x02\xf8\x2f\x3d\x22\x7d\xa7\x96\x3f\x13\x7a\x56\x75\x44\x7a\xad"
-  "\x96\xbe\x10\xf9\x1b\x23\xd2\xab\xb5\xf4\x62\x0f\xd5\x1c\x8d\x48"
-  "\xdf\xa0\xa5\x57\xea\x7b\xda\x5a\xba\x5d\x4b\x47\xff\x57\x6e\x88"
-  "\x48\xd7\xe2\x09\x36\x1c\x44\x1f\x77\x46\xa4\xe7\x4a\x9e\x95\x71"
-  "\xe1\xcc\xa2\xa9\x64\x0a\xc6\x7c\x83\xc7\x43\x2f\x96\x44\xe4\x99"
-  "\xaf\x95\x0d\x78\xe8\x17\x3b\x22\xd2\x67\xaa\xf4\xdd\xb8\xff\x74"
-  "\x67\x44\xfa\xb4\xc1\x78\x28\x61\x0b\xe5\x0e\xb6\xce\xc5\xdf\xf7"
-  "\x90\x7e\x71\xd2\x27\x72\xcf\x1c\x3e\x23\x63\xde\x26\x8e\xdb\x4a"
-  "\x85\x38\x4e\x7b\xa6\x68\xbe\x62\x79\xec\x1f\xc4\x67\x8a\x3a\x69"
-  "\xcf\xd5\xf2\xfc\x09\xc7\x45\xe3\x73\x46\x6b\xf8\x9c\xd1\x6e\x19"
-  "\xe7\x75\xb2\xbd\x4c\xc5\x4c\x53\xfe\x86\x5e\x69\x2b\x69\x7b\x61"
-  "\xc8\xc3\xdf\x0f\x25\x86\xc3\xeb\x2c\xee\xe2\x5e\xe9\x17\xc7\xba"
-  "\x2a\xa7\xb1\xcd\x20\xcf\xa4\x44\xe8\xac\x6a\x3c\xee\x99\x13\xe6"
-  "\xf3\xc0\x4e\x65\x57\x55\xa9\x58\x7c\x5e\xf6\xe3\x88\xcc\xeb\xa1"
-  "\x3d\xb3\xf9\x9a\x68\x35\x1f\xeb\x71\xee\x99\x30\x70\xae\x62\xf7"
-  "\x06\x2d\xdd\x83\xf4\xcc\x88\xf4\x0b\x62\xfb\x0e\xc8\xa7\x37\x5d"
-  "\xc2\xf4\xa6\xaf\xef\xbc\xf0\x07\xcf\x8b\xc0\xe6\xff\x04\xde\x8b"
-  "\xe5\x79\x83\x6b\x42\xe5\xbb\x48\x3b\x5b\x7f\x2c\xb8\x52\xf8\xa0"
-  "\xa7\x71\xac\xee\x6f\xcd\x85\x5d\x37\xb7\xa8\x47\x6c\x7a\x8c\xfd"
-  "\xba\xce\xc9\x38\x33\x0e\x2f\xc7\x05\x65\x3f\x1f\x3f\xef\x21\xa4"
-  "\xb4\x41\xf6\xd4\x2d\xe6\xf7\x9f\xd1\x9c\x02\xe8\x3f\x05\x21\xaa"
-  "\x03\xec\x6d\x8f\xe9\x3e\x45\x7b\x3a\xfb\x7d\xe7\x80\x03\xd7\xe7"
-  "\x90\xb1\xf6\xf7\x4a\x3d\x9f\xbf\x21\x24\x36\x0d\x23\xf1\x47\xd6"
-  "\x2b\xbc\x36\xf3\x3a\xb2\x41\xe6\xda\x70\x6f\x91\x3f\x7e\x87\xf4"
-  "\xc1\xda\xa4\xc6\xe9\x5e\xf5\x5d\xcf\xf2\x5d\x45\x4a\x16\xec\x5d"
-  "\x28\x7e\xcd\xe7\x2d\xf6\xe6\xa2\x6c\x07\xec\xc2\xb8\xfb\xb8\x6b"
-  "\xb7\x91\xa1\x6f\x23\xe6\x8c\xd3\x8d\x06\x25\x7b\xf6\xcd\x0e\x1b"
-  "\x4c\xeb\x78\x3d\x47\xc6\xdb\xde\x78\xa0\xa1\x61\x69\xc0\xd0\xba"
-  "\xa6\x93\x9e\xbb\x92\xac\x0b\x03\xec\x17\xbc\xb7\x75\x44\x31\xc7"
-  "\xf8\xf1\x7a\xa0\x0f\x18\x7e\x8f\xf7\xef\x2f\x6d\x34\x04\xe5\x3c"
-  "\xb2\x6f\xb6\x5c\x03\x28\x3f\xb0\x81\xf7\x10\xdc\x1d\x21\xd6\x65"
-  "\x52\xa0\xcb\x14\x8b\x15\x69\xa6\xd0\xaa\x82\x91\xc1\x15\x05\xdf"
-  "\xda\xb6\x9c\x52\x42\x2b\xd2\x52\x5f\x3a\x4f\x53\xf5\x38\xde\xb0"
-  "\x11\xd2\x45\x8f\x35\xb9\x6a\x25\x4d\x60\x1b\x62\x44\x82\x45\xee"
-  "\xcb\xf0\x7d\xd8\xf0\xab\xae\xba\x95\x17\xff\x66\x40\x08\xb6\x03"
-  "\xc7\xfb\x65\x5c\xe2\xb5\xb5\xf2\x55\xd8\x23\xda\x59\xbc\xd2\xcf"
-  "\x69\x14\xf4\x0f\xc3\x88\x73\xc2\x75\xb2\x90\x0c\x1c\x6f\xbd\x34"
-  "\x5f\xda\xe9\x43\x5a\x0b\x82\xe4\xb6\x7f\x4a\xa5\xcb\xb9\x8f\xf6"
-  "\xbd\xc6\xf3\x27\xfb\xe9\x21\xbf\xe5\x24\xed\x7b\xcb\x1c\x20\x03"
-  "\x7e\x09\xae\x27\x59\xe7\xde\xf7\x21\xeb\xfd\x1e\x7a\xcb\xc4\xbe"
-  "\xc2\xae\xe5\xf7\x70\xda\x31\xc7\xe7\x72\x1f\xbd\x40\x9d\xd7\xdb"
-  "\x77\x90\x9f\x1d\x7c\x36\x30\xd9\x55\xbd\xa7\x37\x30\x44\xd9\x82"
-  "\xfb\xde\x53\x7d\xe6\x6d\x47\x9f\x8d\x01\xec\x41\xd7\x85\xc3\xe5"
-  "\x7b\x79\x0f\xf6\x5a\x77\x6d\x90\xe6\xfa\x85\x47\xee\x79\xf1\x99"
-  "\x68\xfb\x5d\x2e\x71\xbe\x9a\xd4\x79\xa0\xb7\xd6\x85\x2b\xf6\x5a"
-  "\xd8\x27\x00\xf7\xf2\x5c\x9b\x5c\x53\xaa\xd8\x6b\x53\xeb\x30\x7b"
-  "\xd3\xd5\x9a\xd2\xde\x8c\xf5\xa3\xd9\x5f\xf5\xad\xb2\xee\xa4\xbd"
-  "\x59\xb8\xce\xef\x4e\x6e\x6e\x1f\x7c\xae\x69\xc8\xb0\x5d\x43\xa9"
-  "\xbc\x96\xc9\xbe\xa7\xf5\xca\xe7\x14\x75\xbc\xbd\x41\x54\xc8\x77"
-  "\xd7\x1e\x2f\xa2\x44\x5e\xff\x41\xbd\x9f\x4c\xae\x25\x1b\x70\x1d"
-  "\x2e\x4c\x7b\x7c\xd2\x0f\xa8\x7c\x2f\xb9\xbd\xc2\xc5\x7e\x68\x6a"
-  "\xcd\xf9\xed\x6a\x91\xb4\xc7\xa7\xf2\xbf\x3d\xb6\xcd\x8b\x36\x98"
-  "\xf6\xb8\xdc\x81\x53\xda\x5c\xfd\x36\x78\x7f\x8f\x4b\x94\xef\x69"
-  "\x57\x67\x6c\xdf\x7e\x46\x97\xab\x8a\x47\xdf\xce\x57\x74\x6b\xc8"
-  "\x50\x74\x7b\xbb\x5a\x9b\x97\xae\xe5\x7b\xe8\x09\xe9\x6a\x3f\xf7"
-  "\xed\x85\xba\xee\xe2\xd1\xf2\x70\x19\xdc\x67\x28\x59\xfb\x76\x09"
-  "\xda\xae\xed\x03\xbf\x6d\xe3\x34\xb4\x0f\x73\xd3\x5b\x8d\xdc\xae"
-  "\xc1\x64\xab\xa4\x45\x09\x25\x02\x67\x4f\x58\xc5\x58\xf5\xbb\xfd"
-  "\x77\xb9\xd4\x37\xc0\xf6\x5f\x29\xcf\x20\xa2\x1e\xf4\x8f\x81\xe5"
-  "\x26\xc7\x3a\x60\x78\x11\xf8\x87\x74\x5c\xb8\x3e\x7e\x87\xb6\xba"
-  "\xb8\x3f\xc3\x68\x33\xe7\xe1\x7e\x85\xbd\x9e\xc8\xf6\xb7\x6b\x25"
-  "\xfb\x94\xec\x4f\x63\x9a\x28\x9a\xed\x97\xfb\x3e\x55\xfd\xfd\xf0"
-  "\xfb\xaf\xa2\xe9\xa1\x9e\xc3\x26\xc8\x86\xe5\xec\x5b\xb0\x3f\x4d"
-  "\xa3\x9f\x57\xd5\xff\xfb\xbf\x68\x36\x14\xde\xfd\x7e\x53\x44\xd9"
-  "\xab\xfb\xf3\xaa\xef\xcd\x19\x78\x9f\x8e\xd7\x42\x15\xbf\xfe\xbe"
-  "\x31\xa2\x5c\x63\xce\x97\x19\xc4\xf1\xf8\xf9\xfb\x60\x4c\xf3\x1e"
-  "\xe7\xef\x5b\x06\xe8\xad\xe0\xc4\xa9\xe3\x1a\xbd\x0e\x0f\xfd\xbe"
-  "\x52\xc7\x13\xf7\xb9\xaa\x4f\xf6\x5b\x06\xfa\xe4\xf7\xe9\x7a\x39"
-  "\xf6\xeb\x46\x1f\x1d\xe5\xb3\x5f\x71\xe5\x20\xaf\xb9\x8f\x81\x0c"
-  "\x0e\xde\xe5\x92\xfc\x48\xfb\xcb\xd9\x7f\x12\x74\xf5\x28\x1e\xda"
-  "\x5f\xa8\xe6\xc2\xfd\xf2\x4c\x3b\xaf\x67\x37\x05\x98\x47\xf6\x97"
-  "\x01\x6e\xad\x86\x73\x8d\x86\x43\x0d\x70\xa8\x1c\xf4\xdc\x4c\xff"
-  "\xd9\xb5\xfd\x07\x23\xce\xeb\x95\x28\xda\xbe\xc3\x67\x65\xf7\x6f"
-  "\x56\xb6\x43\xe3\x66\xf4\x8f\xe3\x1c\x8d\xe6\x98\xfa\xa5\x45\xe2"
-  "\x64\x5b\x11\xec\x19\xd3\x81\xc3\x90\x0d\x2d\xa5\xe7\x28\x99\xf7"
-  "\xe0\x59\xb6\xb0\xaf\x9f\x48\x42\x7a\xc5\x81\x96\x81\xb3\x4a\x7f"
-  "\xb0\xf2\xd9\xbf\x4d\x1c\x33\xe9\x14\x8d\x56\x7b\xea\xef\xdc\xcb"
-  "\x36\xb4\x70\xc0\x6e\x2e\x3f\xd0\xce\x67\xd7\xda\xa0\x95\x0b\x47"
-  "\xc1\xab\xe1\x8a\x03\xed\x80\xeb\x71\x3c\x4d\x23\x79\x2e\x63\x5b"
-  "\x5c\xf1\xc7\x3b\x01\xc0\xf5\x70\xdc\x26\xd8\xde\x09\xc2\x74\x70"
-  "\x5c\xd8\x74\x68\x3e\xc3\xe5\xba\xc1\x53\x86\xe3\xf4\xce\x2f\x45"
-  "\xd2\xc1\x71\xfc\x6d\x2f\xb6\xb5\xdd\x01\xe0\x59\x71\x70\x1c\xde"
-  "\x8d\xc0\xbb\x43\xb8\x86\x39\x86\x13\xc7\xa0\x05\x7c\x2b\xc3\x17"
-  "\xe5\x07\xc7\x29\xdc\x7d\x32\xef\x71\xfa\xc3\x95\x9c\x47\x8f\x0d"
-  "\x15\x76\x64\x27\xf2\x7b\x6e\x43\x08\xe5\xdc\x76\xe0\x29\xcb\x74"
-  "\xc8\x32\x1e\x6e\x1f\xca\x69\x7e\x1b\x36\xb5\xe7\xf6\x07\x8b\xbe"
-  "\x77\xe4\xa1\x77\xf2\x18\xe7\xf8\xf1\x43\xff\x30\x35\x3a\x96\xc7"
-  "\x3f\xf3\x59\x51\x4e\xcf\xd2\xe3\x6f\xe0\x1e\xe3\x7f\xbf\x3a\x3f"
-  "\x1f\x11\x4b\x67\x73\x44\x5c\x2e\x87\x4f\xfc\x17\xe3\x02\x3e\x4d"
-  "\x04\xbd\x77\x8a\x8a\x43\xf3\xd5\x39\x8b\x3f\xc8\x31\x84\x36\xb1"
-  "\xdd\x6c\x56\xe7\x82\xff\xf0\x2f\x1a\x3f\xe6\xce\x0b\x05\xcd\x1e"
-  "\xd4\x89\xb1\x9b\x3b\xf0\xfc\x87\x7d\xe0\x4f\x0b\xf2\x7d\xa1\xe2"
-  "\x56\xfd\x61\x67\x74\x7e\xf9\xbe\x2c\xe6\x39\x23\xe6\xd9\xe6\x47"
-  "\xdf\x0c\xb6\x47\xb6\x69\xb4\x5c\x17\xd8\x30\x62\x1d\x15\x39\xbe"
-  "\xa0\x44\xf4\xd5\xe7\x8c\x5b\x5b\x97\x97\xdb\x64\x16\xce\x74\x72"
-  "\x77\x05\x95\xae\x82\x39\xe2\xf8\x38\xe4\xf9\x82\x46\xb1\xcf\x29"
-  "\xc7\x02\x47\xfe\x93\x2a\x6e\x69\xe3\x2f\x16\x3e\x9b\x4c\xe1\x27"
-  "\xb2\xbf\x25\x0c\xff\x34\x13\xf3\x81\x69\x77\xaf\x67\x08\xaf\x4b"
-  "\x97\xbe\x42\x63\x38\xfe\x05\x78\xb3\x93\xbf\x13\xc3\xdf\xed\xfd"
-  "\x4d\x6f\xd7\x10\x77\xf0\x53\x2a\x7a\x92\x0c\x27\xa9\x71\x83\xb1"
-  "\x84\x8c\x55\x27\x88\xf7\x03\x83\x4d\xc1\xa9\xa4\x9f\xeb\xad\x1d"
-  "\xa9\xce\x47\xc2\x2e\xf7\xad\xb0\x8a\x40\x8f\xf3\x9f\xa1\xff\xbe"
-  "\x9a\xad\xf9\xf0\xf8\x2b\x55\xbc\x6f\x23\xea\x9f\x63\xd0\xce\x30"
-  "\x2b\xda\x36\x5e\xad\xce\x69\x8c\xfc\x4e\x8f\xb3\x31\x75\x40\x9f"
-  "\x6b\xdc\xae\x68\x78\xc8\xae\xc6\x57\xe3\xf6\x26\x58\xfe\x1b\xd4"
-  "\x5e\x63\x2a\xf2\x66\xf4\xef\x35\x4a\xfb\xb4\x71\x3b\xfa\xd0\xae"
-  "\x74\xbd\x43\xf6\x9c\x90\x49\x1b\x03\x9c\xfe\xa6\x8b\xcb\xa2\x9c"
-  "\xd9\x2f\x6d\xc9\xc6\x92\x01\x5e\x6b\xe4\xef\xa5\x27\xa0\x4d\x29"
-  "\xe8\xd7\x46\x6e\x17\xd3\x04\xf9\x8c\x78\x3e\xd8\xb4\x63\x90\xf8"
-  "\x85\xa6\x5d\x45\x41\xa7\xdc\x37\xeb\x00\x3f\x9d\x42\x1f\x5c\xce"
-  "\xf1\x4a\xdc\xa8\xa7\xb5\xae\x97\x5a\xad\xdd\xd4\x96\xc7\x67\x4a"
-  "\xa0\x2f\x3f\xf9\x5f\xd4\x69\x8b\x2f\xbf\x20\x03\x7d\xd0\xdd\x88"
-  "\x61\x41\x4e\x74\xb1\xcf\x88\xbb\x04\xf2\xcc\xc7\xdf\xa7\x21\x09"
-  "\xa3\x35\xdc\x45\xad\x76\xe8\xed\x95\xc3\xa8\xad\xee\x53\x6a\xb3"
-  "\xfe\xbb\xac\x87\x75\x0c\xd7\xf2\xee\x8b\xc0\xde\xc5\x3e\x45\x36"
-  "\x0d\xb6\x17\xb0\x53\x07\x85\x5d\xee\xb5\x5d\x1a\xec\x4b\xc0\xbb"
-  "\xdc\x6b\xb9\x14\xd8\x90\x65\xc5\x6e\xab\x3a\x97\x52\x7a\x25\x0d"
-  "\x0f\x9d\xe7\xf8\x74\xd7\x0a\xe5\x83\xf7\xee\xb3\xf2\xec\x8a\x53"
-  "\xfa\x38\x16\xc9\x33\x2c\xa7\x49\xfa\x51\xa9\x73\x2b\x9f\x13\xef"
-  "\x6b\xf6\x38\xdf\xcd\x1d\xd0\xbd\xfb\xd7\x95\x21\x63\xde\xdd\xa0"
-  "\x7c\xad\x0e\x14\x29\xbe\x7a\xf7\x76\x86\x15\x1f\x8f\x83\x65\xca"
-  "\x67\xef\xdd\xf7\x74\x5b\xbd\x3b\xe9\x60\x99\x06\xcb\x16\xbb\xdf"
-  "\xa8\x7f\x18\x2e\xdf\x5e\xac\x7f\x63\xae\x58\x3b\xbe\xf6\x40\xfe"
-  "\xe3\xf9\x4b\x56\xe6\xe7\xd9\xe6\x3f\xbb\x7c\xe9\xc4\x65\x8b\x17"
-  "\xdb\xe6\xe4\xaf\x58\xb1\xe8\x89\xfc\x64\x9a\xbf\x7c\xd1\xd2\x15"
-  "\x4b\x8a\x97\x2c\x5b\x6a\xb3\x65\xde\x9a\x53\xb0\xac\x78\xe2\x9d"
-  "\x99\xe9\x31\xe7\x9d\xf8\xac\xd3\x51\xd6\xe9\x1c\x6b\x31\x3e\x43"
-  "\x74\x19\xc7\x9e\x30\xaf\x16\xae\xe7\x60\x4f\x80\xff\x4e\xf2\xba"
-  "\x3a\xc6\xed\x31\xd6\x35\x39\xd6\x15\xe6\xcd\x96\xad\x2f\x8b\xf6"
-  "\x13\xd4\x72\x0e\x7a\x0a\x7f\x9f\x94\xe3\x36\x1d\x85\x8d\xe7\x53"
-  "\xdf\x41\x6a\xf9\x84\x63\x32\xfd\x1c\x69\xbe\xa4\x43\xf6\xaa\xff"
-  "\x24\x23\xe6\x1e\xe8\xb9\x98\x4b\x0c\xc3\x44\xe5\x28\xd1\x2c\xfe"
-  "\xcb\x4a\x5a\x4c\x59\x83\xdb\x13\xe0\xfd\x37\xd3\xbc\xa0\x43\xb0"
-  "\x3c\x55\x63\xeb\xc0\x27\x8a\x2e\x7b\x35\x5f\xc6\x96\xb7\x58\x27"
-  "\x5e\x2f\xbf\x53\x75\x00\xe3\x7f\x5f\xf6\x80\x9c\x6e\x0e\x6a\xba"
-  "\x48\x07\xe8\xbe\xea\x38\x9e\xd5\x19\xfb\x83\x29\xd1\x7b\xae\xef"
-  "\x79\x89\xfe\x64\x53\x3f\x2e\xf3\xa7\x0c\xf5\xe3\xfb\xc8\x5f\x4b"
-  "\x8d\xfa\xc5\xa6\xff\xbd\x3f\xbd\xfe\xff\x69\xf9\x0f\xf7\x5f\xfc"
-  "\xf7\x4d\xea\x97\xed\xfe\xbf\xd8\xfe\xbf\xa7\xfc\x87\x07\x2f\xf6"
-  "\x63\x7e\x03\x6f\x1d\xfd\xf9\x7f\x92\x09\xfc\x59\x03\xfb\xda\xe8"
-  "\xf8\x8c\xac\x25\x41\xd1\xe9\x78\x84\xc6\x94\x7e\x41\xfc\x9d\xa0"
-  "\xae\x62\xbb\xe8\x2c\x3d\xcf\x7a\xcf\x87\x9b\xc0\xbf\x8d\x9b\x8f"
-  "\x53\xca\xa6\xe3\x64\x69\x2b\xe6\xef\x05\x72\x7c\x1a\xc8\x19\x60"
-  "\xea\xc6\x73\xcb\xca\x00\xfd\x9b\xef\x4b\xf6\x53\x70\xb5\x41\x9b"
-  "\x6c\x3d\xfa\x7f\xd8\x7b\xff\xb8\xa8\xab\x7c\x7f\xfc\xcc\x9b\x51"
-  "\x47\x1d\x60\x34\x34\x34\xb4\xc9\xac\x9d\x5c\x2b\x6a\xad\xf5\xee"
-  "\x5a\xcb\xa6\x7d\xaf\xdb\xd5\x60\xcd\xae\x6c\x59\x62\x62\x8b\x1b"
-  "\x2a\x21\x11\x9a\x02\x8e\x86\x03\x0e\x88\xae\xed\xc5\x02\xa4\xbb"
-  "\xee\x5e\xda\x6b\xc5\xee\xda\x5d\x4a\xaa\x41\xb1\xd0\x80\xa1\x16"
-  "\x0b\x0b\xb7\x89\xd0\xc8\x45\x9b\x60\x94\x11\x66\xde\xe7\xf3\x7a"
-  "\x9d\xf3\x7e\x33\x33\xc0\xc0\xcc\x80\x66\xdf\xf5\x8f\xf7\xe3\x3d"
-  "\xef\xf3\x3e\x73\xde\xe7\xbc\x5e\xcf\xf3\x7a\xbd\xce\xaf\xd7\x0b"
-  "\x63\x2d\xd2\x2a\x75\x1c\x09\x2b\x9c\x48\x2b\xa8\xfe\xc9\x14\x2a"
-  "\x3c\x19\x0f\x69\x0d\xaf\x8b\x51\x23\x5e\xdf\x50\x3d\x02\x63\x2a"
-  "\x35\x93\x77\x76\x4a\xd8\x74\xf2\x73\x0c\x55\xcc\x3e\x87\x7e\xd2"
-  "\xc0\xfd\x20\x1e\x59\xcf\xf5\xf9\x91\x5f\x48\xf3\x17\xf0\xbb\x8a"
-  "\xcd\xb5\x41\x3b\xca\x31\xae\x1a\x96\xf9\x9a\x58\xce\xe2\xaa\xbd"
-  "\xbe\x21\x6a\xc4\xc6\xe5\x44\xa8\xb3\x9c\x21\x87\x41\x0e\x62\x8c"
-  "\x2e\xe8\x77\xfb\xa1\x9f\x95\x15\x4d\xa4\xf9\x50\x3f\x63\xf1\x44"
-  "\x6a\x80\x3a\x95\x76\xea\xdf\x05\x3b\xa8\xdc\x26\xcd\xaf\x9a\xa0"
-  "\x5f\xec\xcf\x85\x3c\xd1\xcf\x90\xeb\x73\x21\x5f\x1e\xe4\x43\x5b"
-  "\x8c\xd7\xef\xd0\x11\xa0\xc1\x01\xf8\x66\xbd\xf6\x71\x7c\x36\xb1"
-  "\x79\x28\xfc\x36\xb4\x43\xdb\x4c\x4c\x31\xa0\xdb\x94\xf8\x0d\xf9"
-  "\xbb\x50\x3e\xc8\xbf\x37\xf7\xb3\x39\x71\x48\xe7\xe5\xbc\xcb\x63"
-  "\xba\x1b\x0e\xe2\x7c\x8e\xbc\x4f\xdc\x9a\xbb\x01\x74\x7a\x17\xf3"
-  "\xd5\xb6\x1b\xc7\xef\x68\x63\x30\xbb\x02\xc6\xf1\x7c\xbc\x09\xb6"
-  "\x45\x02\xc8\x01\xb0\x27\xd8\xfe\x4b\xb0\x25\xa0\x2e\xbb\x31\xf6"
-  "\x1c\xbe\x87\x71\xc0\x01\xd0\xcb\x65\x68\x07\x3c\x7e\xfe\x01\x82"
-  "\x67\xb7\xc0\x1e\x50\xae\x5b\x4a\xed\xdc\x47\xfe\xbb\x6d\xb2\x2d"
-  "\x80\x32\x08\xf5\x7f\x2e\x8c\xe9\xbb\x81\x87\x80\x81\x6a\xb0\x2d"
-  "\xc6\x81\x96\xd4\x49\xb4\xaf\x66\x3a\x3f\x95\xf9\x16\x0d\xe2\x32"
-  "\xda\x74\x17\xb4\x4f\x0d\xdf\xa8\xb6\x90\x5a\x26\x27\xb8\x8c\x31"
-  "\xcd\x93\xf5\x38\x8e\xa1\x2c\x50\x06\x05\x59\x26\xbd\x83\xf6\xff"
-  "\x2d\x5c\xfe\xa6\x85\xbc\x6b\x93\x68\x56\x03\x34\xc3\x32\xd9\x79"
-  "\x5a\xb0\xb9\xd2\x38\x6d\x4c\x68\x1f\x84\x49\xff\x2d\x94\xcb\xc5"
-  "\x71\x9e\x08\x76\x05\xd2\x0b\xe9\x04\xdf\x20\x92\x1c\x6b\xe0\xf6"
-  "\xcb\xa1\x57\xa5\x75\xb4\x7c\xe0\xf5\x56\x17\xfd\x4d\x16\x77\xfa"
-  "\xc3\xff\xb7\x4a\xbc\xfc\x95\x1b\xef\xc0\xfe\x3e\x14\x89\xf3\x6e"
-  "\x50\xc7\x0a\x3e\x67\x50\x39\x09\xfd\xfb\xa0\x0f\x51\xa0\x71\x85"
-  "\x11\xfd\x55\x82\x6c\xde\xf2\x0f\x22\xc5\x3c\x3c\x34\x89\xdb\xa7"
-  "\x95\xe5\x3c\x2e\x58\x25\x9b\xab\x6b\x81\x7a\xf1\x98\x60\x95\x52"
-  "\x4c\xb0\xca\xcd\xee\x71\x0e\x5d\x31\x0e\x2b\xd3\x5c\x7b\xa0\x4d"
-  "\xfb\xf8\x78\xcc\xb4\x0f\xe7\x54\x58\xfe\xee\x04\xac\x5b\x13\xf6"
-  "\x4b\xb9\xad\x18\xef\x10\xd2\x71\xae\xaf\x09\xf9\x26\xa7\xa3\xaf"
-  "\x4b\xe0\x93\x1a\xea\x34\x4e\xaa\x53\x1b\x3c\xab\xe0\xdb\x6c\x4e"
-  "\x0a\x63\x1f\xee\xc0\xff\xa4\xbb\xfe\x83\xfd\x06\x30\x1c\x0a\xff"
-  "\x19\x0d\x77\x2a\xe7\xe5\x31\x11\x2b\xf3\x7f\xdb\x85\x73\x2a\x95"
-  "\xa5\x72\x4c\x44\x8c\x87\x88\x32\x23\xf7\x71\x0f\xda\x23\x6d\xf6"
-  "\x03\xaf\x18\xee\x0e\x3b\xca\x81\xde\x87\xc0\xfe\x7f\x35\x8a\xb7"
-  "\xab\x32\x5f\xaa\x9f\x89\xfb\x4e\x7f\xab\xba\x78\x97\x7c\x96\xfb"
-  "\x50\x5a\xcf\x3a\x5f\x8f\x6d\x59\x99\x8f\x98\x84\xb2\x6a\x90\xff"
-  "\x68\x27\x42\xbe\x92\x1e\x6c\xb1\xf3\x8a\x87\xd0\x8f\x52\x9a\x54"
-  "\x7f\xc4\x8b\x42\xa2\x5d\xb5\x7b\xbf\x73\xef\xe7\x50\x46\x0b\xf4"
-  "\xf1\x1e\x0c\xc8\xfd\x5a\x92\x39\x93\xa4\x39\xa0\x46\xf4\x35\x09"
-  "\xe5\x9a\xd0\x06\xe7\x7a\xf5\x70\xdb\xe1\x26\x07\xce\xc9\x36\xc0"
-  "\x33\xf4\xef\xc3\xd5\x1d\x63\xaa\x5a\xb7\x32\xb9\x71\x18\xc6\x3f"
-  "\xb7\xb0\xf9\x63\xa4\x8b\xdc\x5f\x77\x00\x7d\x30\x9e\x20\xeb\xb3"
-  "\x69\x2d\xa4\xce\xde\x46\xa4\xfd\xc5\xd0\x67\x4f\xe1\x1c\xe7\x19"
-  "\xc0\x90\x0a\xfb\x2f\xf0\x77\x3f\xfa\x45\x05\x3a\xd6\x6f\xfd\x1d"
-  "\xeb\xb7\x6a\xec\xb7\xdd\x78\x06\x1d\xbe\x53\x15\x17\x45\x0e\xa7"
-  "\x99\x58\x3f\x46\xdf\x02\x2f\x01\xed\x30\xfe\x20\x7c\xfb\x80\xbc"
-  "\x2f\x12\x31\x82\xbe\x04\x38\x4e\xde\x75\x60\x5f\x96\x68\xa7\x84"
-  "\x7c\x4d\x72\xdf\x73\xf1\x9f\xe7\xe9\xd5\xdf\x42\x79\x7f\xab\x52"
-  "\xcb\xb4\x76\xb0\x7e\x5c\x59\xea\x80\x7e\xec\x4e\x53\xa4\x27\xd2"
-  "\x15\xf2\x42\xfb\xdf\x8c\x91\x69\xea\x46\xcf\x57\x24\x9e\xd7\xf3"
-  "\x39\x8b\xaa\x44\x69\x3e\xa3\x87\x86\x12\xfe\x1a\xb0\x4f\x6d\xc1"
-  "\xb6\x83\x6e\xc0\xef\x23\x46\x5e\x92\x64\x56\x95\x15\x31\x52\x05"
-  "\xfd\x7f\x41\xa3\x4b\x76\x54\xee\x67\x63\x16\xe0\x13\xe7\x4f\xd5"
-  "\x71\x76\x5e\xbf\x1f\xd9\x01\x38\xd9\xed\x92\x4f\x55\x2d\x32\x1d"
-  "\x64\x4c\xca\xfd\x1e\x74\xca\x1d\x9e\xf2\xe7\xc8\x04\x28\x63\x3c"
-  "\xca\x37\x97\x0d\x75\x64\xba\xa7\x7c\x3b\xa2\x46\xf9\x86\xb8\x4e"
-  "\x4a\xc5\x39\x1b\xae\xaf\x2c\xe4\x9d\x03\x9e\x32\xe9\x9d\x57\xf8"
-  "\x1a\x20\xb7\xb9\x10\x5b\x49\x8f\xf3\xfc\xa8\xc3\x20\x3f\xdb\x97"
-  "\x2c\xe9\x3c\xf4\x7f\x85\x69\x25\x12\xbd\x9a\x20\x7f\x15\x9e\xd5"
-  "\xc2\xb3\xde\x63\x9b\xf8\x58\x0f\xe4\x74\x05\xfa\x99\x85\x7c\x71"
-  "\x75\x60\xe7\x77\x67\x71\xd9\x2d\xcb\x0a\xba\x22\x76\xec\xb3\xad"
-  "\x64\x74\xd2\xbd\xf4\xcb\xd3\xe4\xbd\x9f\x43\x9f\xb1\xa3\xdf\x33"
-  "\x28\x5b\x7b\x9a\x1c\x1d\x0d\xdf\x0d\x93\xee\xe1\xa7\x49\xf5\xb7"
-  "\x70\x9f\x04\xf7\x13\x70\xbf\x0e\xee\x95\x90\x5f\x94\xf2\x47\xc2"
-  "\xf3\x2b\x90\xfe\x23\xe9\x0e\x75\x7c\x6f\x36\xdc\x63\x24\xdb\x11"
-  "\xd3\x37\xe1\x33\xdc\x57\x4b\x3c\xaf\xe1\x3c\x7f\x0f\xf7\x5c\x61"
-  "\x1f\x6d\x34\x37\xb1\xb2\x92\x20\xcf\xad\x58\x36\x9e\xa1\x3c\x4d"
-  "\xde\xff\xc2\xcd\x06\x85\x72\xde\x0f\x86\xfb\x2c\xf8\xdf\x87\x70"
-  "\x4f\x81\xfb\x1f\x24\x1a\xd4\xa3\x6c\x88\x4f\x43\xda\x56\x99\xb4"
-  "\xdc\xde\x8d\x91\xfb\x3c\xea\x61\x97\xec\x30\x91\xf8\xa5\x9c\xdf"
-  "\x90\x97\xe1\x00\xf2\xfe\x1c\xf3\xc2\x7d\xae\x74\x8f\x92\xee\xf7"
-  "\x4b\xf7\x7f\x97\xee\xf3\xa4\xfb\x7c\x0b\x79\xaf\x54\xb2\x31\x80"
-  "\x2e\xef\x95\xb2\xfd\x0d\x86\x83\xd2\xda\xf8\xfb\xd5\x38\x46\x06"
-  "\x39\x8e\x7a\x30\xa8\x53\xff\xfe\x1c\x79\xbe\x0d\xe7\x69\xbb\xf5"
-  "\x6f\x7d\xf9\x12\xf3\xdb\xf0\xfe\x62\x37\xd9\x36\x5f\xad\x88\x22"
-  "\x60\x03\x4d\x28\x14\x40\xff\xf3\x72\x10\xc7\x6c\x0d\x51\xf2\x61"
-  "\x1d\x84\xbe\xa2\xd8\x78\x28\x58\x89\xeb\x35\x4d\x6c\x2e\x12\x7d"
-  "\x24\x8d\xae\x5c\x00\x57\x2c\x8c\x0d\x96\xca\xf2\x1b\xc7\x3d\x92"
-  "\xaf\xab\x89\xf0\x2d\x93\x6b\xac\xfe\x7e\x12\x5f\x93\x99\x00\x7d"
-  "\xff\xfd\x46\xb7\xf4\x99\x58\x67\xa0\x67\x23\xb4\x67\x56\x33\xa9"
-  "\x46\x3a\xde\xd9\xc2\xdb\x1c\x29\xb7\x59\xe2\x47\x92\x4c\xdf\x16"
-  "\xf2\x5e\x19\xc8\xc2\x64\xc4\x70\x73\x8f\x9c\x7d\x8f\x9d\x41\x92"
-  "\x30\x02\xbc\x7c\x6f\x15\xf2\xd4\xd5\x7f\x3c\x64\x50\x58\xa7\xbe"
-  "\x3a\xce\x53\xa6\x98\xe2\x50\xa6\x20\x36\x40\x7e\x23\xaf\xa3\x7a"
-  "\xf5\x3f\x35\xf6\x3f\xde\xef\xaa\x0b\x3d\xff\x7b\x44\xed\xe0\xfd"
-  "\xae\x11\x70\x06\xf8\x7c\x0f\xfd\xf4\x81\x9e\xaa\xde\x28\xf5\xe9"
-  "\x46\xe8\xd3\x77\x41\xba\x8a\xd7\x95\xa7\x4b\xdf\x02\x9c\xbd\x87"
-  "\xed\xbe\x4e\x4e\x97\xda\x0b\xe5\x1c\xb1\x23\xbf\xe5\x74\xa9\x7c"
-  "\xc0\xe3\x11\x2b\xf6\x13\x39\x5d\x6a\x13\xd8\x51\x47\x67\xc9\xf2"
-  "\xc4\xc8\xf0\x76\xb8\x42\xfe\x1f\xf2\x0d\xfd\xda\xf0\x39\xe3\xa3"
-  "\x5a\xe8\xab\x25\xa8\x1f\xb6\x3c\x4e\xd4\xcf\x16\x90\x60\xde\x2f"
-  "\x8f\x6a\x3d\x65\xe4\x07\x6f\x52\x7d\xa8\x83\xaa\x2a\xe7\xd5\x3a"
-  "\x66\xc9\xf6\x6a\x21\x7c\xa7\x50\x8e\xbf\xe9\xf2\x87\x7d\xf4\x43"
-  "\x8c\x5b\xee\x56\x17\x93\x5c\x17\x97\x7e\xe6\x3c\xc0\xba\x61\x59"
-  "\x5b\xc0\x5e\xb7\x81\x5c\xe0\x72\xfb\xa8\x55\x8e\x4b\x9c\x27\xe9"
-  "\x2d\x16\x1b\x37\x95\xc7\xc6\x45\xdd\x88\x6b\xf9\x22\xce\x63\xa5"
-  "\x39\x49\x5d\x12\x8c\xe5\xd3\x4e\x91\x65\xeb\xc7\xa0\xef\x88\x58"
-  "\xa8\x6b\x11\xd4\x6d\x9f\x44\x23\xe8\x37\x1f\x6c\x96\x68\x89\xf2"
-  "\x6a\x1f\xca\xf0\x2d\xe9\x3c\x96\x05\xce\xdd\x60\x7f\xf8\x2d\xea"
-  "\xad\x70\x6a\xaf\x2a\xc4\xbe\x71\x2c\x49\xb6\x41\xa1\x7e\x25\xdc"
-  "\x06\x3c\x7c\x92\xf9\x32\x31\x54\xce\xe3\x73\x7f\x1f\x8c\xe3\x6d"
-  "\x3d\x66\xe7\xeb\xa4\xcc\x1f\x1c\x3e\xb7\x04\x85\x87\x25\xf3\xfd"
-  "\x16\x6f\x89\xc5\xac\xaf\x1d\x33\xf5\xf2\x17\x25\x40\x5a\x83\xec"
-  "\xef\xd2\x65\x2f\x72\x9a\xc0\x3b\xab\xab\x5f\x1c\xdb\x8f\x65\x41"
-  "\x99\x9b\x3a\xf5\x1f\xa8\x5c\xe9\x87\x9b\xa4\x39\xaf\xf9\x21\x9b"
-  "\xa3\x70\x1f\xc9\x04\xf4\x11\xcb\xeb\xf0\x41\x02\xab\x13\x9b\xf7"
-  "\x80\xfe\x29\xf5\x61\xa4\x35\xea\x6d\xd6\x8f\xa1\x0f\x63\x5f\xee"
-  "\xce\xae\x5c\x00\x17\xef\xbb\x5c\x3f\xdb\x59\xdf\x65\xfd\xf6\x83"
-  "\x34\xd7\xf7\x3e\x88\x64\x73\x5f\xc8\xd3\xe7\xc2\xd5\xf0\x6e\xb7"
-  "\x85\xbc\xa5\x92\xea\x38\x47\xaa\xcb\x3c\x78\x5f\xc8\xf7\x6a\x1c"
-  "\xbb\x95\xdb\x42\xc7\x66\x22\xbe\xcc\x80\x19\xb8\x17\xf0\xb8\x81"
-  "\x1f\xd4\xcb\x98\x81\xfe\x14\x7f\x9a\xd4\x2c\xdf\x3d\x91\x16\x00"
-  "\x6f\x0a\xa0\x0f\x24\xc2\xf3\x42\xb8\xc7\xf3\xbb\x42\x83\x77\x09"
-  "\xdb\x05\x9d\xfa\x1a\xb5\x1c\xdf\x15\xdb\x63\x1b\xdd\x16\x83\xf8"
-  "\xc8\x83\xba\x23\x46\xd8\x7a\x62\x12\x8f\x9b\x8c\xf8\x40\x6c\x84"
-  "\x6e\x7e\x80\xe1\x83\x9d\x55\x86\x74\x56\x27\xc0\x07\x94\x15\x2b"
-  "\xfb\x9a\x84\xf6\x39\xf8\xbc\x7e\x4d\xa2\xfb\xde\x36\x28\x53\x5b"
-  "\xa5\x85\x71\x8d\x61\x7f\x54\xca\x0d\x64\x42\x95\x96\xf9\x94\xfb"
-  "\xdc\xec\xb8\x9f\xe0\x7f\x70\x5d\x86\xcb\xb9\x09\x4b\xe0\xbf\xa5"
-  "\x2e\x7a\x99\xd8\x5a\xc5\xe1\xa5\x6c\x2e\xf1\x1a\x78\x57\xe5\x3e"
-  "\x4e\xb0\x90\x83\xf5\x38\x56\xc0\x3d\x38\x37\x86\x11\x2d\xe0\x10"
-  "\xe4\x50\x4d\xab\x6c\x97\xde\x1e\x86\xeb\xbb\x07\xf1\x2c\x24\x8e"
-  "\x81\x81\x5e\x07\x13\x60\x2c\xd8\xef\xfe\x44\xc0\xc7\x2c\x9c\xab"
-  "\x91\xe2\x40\x34\xe1\x3c\x14\xfa\xcd\x3e\x4d\xea\xd7\xd7\xa2\x1f"
-  "\x81\xb5\x7d\x7d\x8b\xa6\xa7\xd1\xf3\xe8\x5f\x54\x9b\x4c\xae\x69"
-  "\x26\xf5\x4b\x71\xde\x27\xe3\x5b\x9c\x63\xa9\x4d\xf2\x9c\x63\xa9"
-  "\x35\x49\x57\x03\x21\x75\xb3\xdd\xae\x6a\xe9\x3e\x6f\x90\xcb\x22"
-  "\xe5\x85\x11\x78\x9d\x5d\xa2\xd5\x7f\x75\xea\x6b\x7b\xfc\x1f\x22"
-  "\xa6\xb0\xaf\xe2\xba\x3e\xce\x19\x29\x1c\x04\xfd\x16\x00\xbf\xa0"
-  "\xde\x5b\x66\x2c\x32\x6d\x40\x3c\xd5\x8d\x60\xb6\xbf\xe0\xef\xb9"
-  "\xaa\x3a\xb6\x0e\xc6\x7d\xec\xd5\x56\xc3\xb7\xff\x07\x63\xc3\x27"
-  "\x25\x93\x29\x38\x7f\x1d\xea\xa4\x26\x1c\xa3\x22\x36\xf6\xb2\xf8"
-  "\x0b\x75\x47\x53\x36\x11\x01\xde\x5f\x0f\xbf\xcb\x65\x3b\x07\xfe"
-  "\xa3\x09\xb2\x93\x30\xb4\x6f\xe6\x6e\x22\xd7\x77\xea\xeb\x76\xcb"
-  "\xbc\x42\x1b\x00\xe7\xd1\xa4\xb9\x00\xa8\x6b\x2d\x5b\x3b\x43\xdf"
-  "\xc8\x16\x46\x37\x26\x47\xb1\x0c\xc0\x6e\x5d\x66\x90\x8d\x68\xb8"
-  "\xee\xa8\x03\xfd\x77\x50\xb2\xf9\xea\x0a\xa1\x0f\x34\xb8\xd5\xf3"
-  "\x84\xeb\xf7\xc4\x49\xf8\xff\x50\x1b\xda\x57\xde\xe8\x63\xbe\x49"
-  "\xa6\x0f\xee\x2b\x0b\x05\x3b\x9f\xf1\xdb\x41\xdb\xa0\x6e\x35\x49"
-  "\x1b\x88\xea\x0c\xa9\xbf\x69\xef\xef\xd8\x79\x97\x6a\x3e\xbf\x5e"
-  "\x3f\x49\x1e\x47\xf3\x7a\x9b\x4f\x85\x6e\x0e\x62\x31\xb5\x31\xc6"
-  "\x27\x8b\xa3\xfd\x4d\x38\xb3\xbd\xcd\x8e\x39\xc4\x94\xfe\x13\xcc"
-  "\x73\x5c\x96\xa5\x1d\x19\xe1\xe4\x70\xf8\x1c\xe8\xcf\xe6\x12\xe8"
-  "\x33\xfb\xfd\xdf\xfb\x64\x96\xe6\xed\xf9\x19\x29\x7c\xc6\xf3\x4c"
-  "\xcc\xbf\x3c\x5b\x27\x35\x3f\x8d\xba\x61\xab\x14\x9f\x19\x75\x6e"
-  "\xa7\xbe\xbe\xc7\xfe\xe7\x71\xa9\xcd\x49\xbc\x0c\x5c\x1f\x34\x27"
-  "\xe2\x39\x72\x36\x0e\xe0\xf9\xd5\x7c\x0e\xbf\xbe\x67\xfe\x1f\xf3"
-  "\xe1\xff\xf8\xfe\x24\xf3\xbc\x65\x4e\x05\xd0\xd8\x3c\x0f\xdb\xca"
-  "\xb1\x39\x11\x78\x5b\x9f\xe4\xea\xc7\x75\x6c\x9f\xd0\xe1\x36\xf7"
-  "\x7e\x5a\x9f\xef\x1a\x3f\xd6\xce\xba\x75\x37\xe9\x77\xdf\x45\x52"
-  "\x08\xd1\xfc\x53\x45\x1e\xda\xb1\x83\x96\xe4\x0b\xe2\x7d\x5b\xf2"
-  "\x88\x5a\x61\x04\x32\x62\xbf\x4b\x8d\x9b\x70\x9a\x7c\x38\x2e\x54"
-  "\x7d\x6d\xcc\xdc\x94\x51\x34\x3d\x9c\x08\xb9\xed\xa3\x54\x37\xd8"
-  "\xaf\x2d\xa1\x41\x33\x16\x2d\x4c\xb1\x13\xed\x6f\xf2\xc9\x57\x89"
-  "\x24\x68\x2e\x58\xee\x37\xaa\x09\xd4\xe9\xef\x11\x78\xee\xec\xb0"
-  "\x1a\xed\x89\xbf\x47\x60\x99\x1b\x0b\x89\x6a\x63\x0b\x6d\x35\x3e"
-  "\x39\x42\x05\xb2\x5d\xf3\x12\x60\x6e\xac\xfa\xda\x92\x6e\x28\xa3"
-  "\x32\x8e\xfd\xaf\xcc\xff\xba\x25\x4d\x84\xba\xbd\xea\x5f\xdd\x1a"
-  "\x2a\x5c\x75\x6b\xa8\x18\xe6\xba\x69\x5c\x75\x4b\x80\xba\x7d\xf4"
-  "\x0b\xff\xea\xf6\xf1\x52\x57\xdd\x3e\x5e\xea\x63\xdd\xf6\xfb\x5f"
-  "\xb7\xb4\x6b\xa1\x6e\xa7\xfc\xab\xdb\x27\x0e\x57\xdd\x3e\x71\x0c"
-  "\xa5\x6e\x38\x36\x4f\x8f\xa0\xa7\x98\xaf\xe3\x64\xa2\xc6\xbd\x5d"
-  "\xa7\x49\xc3\xfd\xe9\x85\xec\x79\x3c\xfc\x56\x48\xfd\xdd\x9a\x61"
-  "\xa3\x5f\x72\x3b\xe6\xef\xab\x6f\x4b\xc2\x3d\xcd\x7f\x8f\x07\x2c"
-  "\xab\x39\xa6\x1b\x98\xad\x9d\x61\xa5\xd2\x5e\xc3\xbf\xe7\x16\xb3"
-  "\xfd\x0a\x47\x24\xfb\xe2\xef\xf5\x1d\x63\x2a\x33\x71\xaf\x80\x08"
-  "\xfd\x9b\x8e\xa9\x34\x62\x5c\xb7\xd7\x93\xad\x02\xd5\xa3\x1f\x22"
-  "\xf4\x95\xa4\x24\x34\xa7\xb2\xf0\xf5\x64\xbb\x80\x7e\x03\xb6\xb0"
-  "\x73\x78\x7f\xaf\x96\xcf\x98\xc8\xdf\xb0\x8e\x3e\x92\x0f\xe9\x16"
-  "\x8b\x14\x6b\x91\x0a\x60\x9b\x8c\xae\xdc\x8a\xe5\x43\xba\x5d\x8e"
-  "\x87\x08\x78\x97\x63\xb2\xd8\x42\xed\x03\xc9\xc1\x86\x5b\x65\x39"
-  "\x38\x37\x85\x84\x62\x3c\xb4\x1d\xe9\xa3\x70\x0d\x11\x6c\xaa\xbf"
-  "\x57\x20\xdd\xa3\x6d\xa3\x68\xe8\x46\x12\x84\x67\x6b\x70\x0f\x97"
-  "\x39\xdc\x4a\xa6\x6f\x24\x23\xa2\xd3\xa0\x4c\x3b\x89\x0b\x4d\x83"
-  "\xf2\x80\xd6\xdc\xd6\x6f\x60\xe7\xe0\x76\x43\x79\xb8\xb7\x35\x28"
-  "\x85\xa8\xe7\x86\x67\xd0\x2d\x7b\x88\x12\xcf\xe1\xe0\x79\x1a\x7e"
-  "\x96\x66\xa4\xaa\x53\xdf\x50\x2a\xb7\xcf\x07\xfe\x84\x70\xfe\x1c"
-  "\x3f\xe5\xe2\xcf\xf1\x97\xfb\xf2\xe7\x78\x30\xe7\xcf\x71\xa5\x8b"
-  "\x3f\x1f\xcf\xf7\xe4\xcf\xf1\x5b\x3d\xf9\x73\x3c\x29\x30\xfe\x1c"
-  "\x4f\x70\xf1\x87\x7f\x83\xf3\xe7\x78\x66\xff\xfc\x39\x5e\xe0\xe2"
-  "\xcf\xf1\x99\xbe\xf1\xe7\x78\xad\x77\xfe\x1c\x5f\x3a\x00\x7f\x46"
-  "\xf6\xcf\x9f\x8f\xa7\xf8\xce\x9f\x8f\xe7\xfb\xc1\x9f\x60\xce\x9f"
-  "\x4f\x9e\x77\xf1\xe7\x93\x9f\xf7\xe5\xcf\xc7\xaf\x72\xfe\x7c\xbc"
-  "\xcf\xc5\x9f\x4f\x5a\x3d\xf9\xf3\x71\xad\x27\x7f\x3e\xd1\x04\xc6"
-  "\x9f\x4f\x54\x2e\xfe\xf0\x6f\x70\xfe\x7c\xa2\xed\x9f\x3f\x9f\xcc"
-  "\x76\xf1\xe7\xe3\x1a\xdf\xf8\xf3\xc9\x6a\xef\xfc\xf9\xd8\xe1\x3f"
-  "\x7f\x3e\x79\xbb\x17\x7f\x34\xde\xf9\xf3\x49\xab\x1f\xfc\x09\xe5"
-  "\xfc\x39\x71\x93\x8b\x3f\x8d\x5f\xf4\xe5\x4f\xe3\x42\xce\x9f\xc6"
-  "\x79\x2e\xfe\x9c\x30\x78\xf2\xa7\x71\xb5\x27\x7f\x1a\xcb\x02\xe3"
-  "\x4f\x63\xa9\x8b\x3f\xfc\x1b\x9c\x3f\x8d\xa6\xfe\xf9\xd3\xd8\xe8"
-  "\xe2\x4f\x63\xa2\x6f\xfc\x39\x11\xec\x9d\x3f\x8d\x85\x03\xf0\x67"
-  "\x54\xff\xfc\x39\xf1\x98\xef\xfc\x39\x61\x18\x88\x3f\xfe\xd9\x7e"
-  "\x27\x98\x5d\x35\x0c\xe5\xb4\x78\x2b\x07\x69\x87\xfb\xd3\x44\xfd"
-  "\x89\x96\x62\x71\x24\x8b\x25\x05\xbf\x0b\xb5\x1b\xc8\xcf\x9a\xc9"
-  "\xa7\x77\x14\x8b\x23\x54\x54\x5f\x1c\x27\xea\x4b\xb4\x74\xf3\x48"
-  "\xa5\xb8\x79\x94\x12\xcf\x46\xf6\x57\x16\xdf\x2f\xf9\xe9\xce\xa0"
-  "\x49\x64\x2a\x9e\x77\xd9\x02\xf6\x33\xfe\xee\xd4\x7f\x5a\x08\xb6"
-  "\xa0\x6e\xa0\x73\x17\xb8\x77\xe9\xf0\x56\x1c\xf7\x7e\x5a\xdd\x73"
-  "\x5e\x5d\x4f\xd3\xd0\x47\x51\xd2\x34\xdc\x63\xff\xa9\x15\xfd\xfa"
-  "\x52\x43\x85\x2e\x6a\x1a\xfd\x1c\xc7\x22\xa7\xc9\x67\x67\x69\x76"
-  "\x85\x0e\xf1\x00\xb6\xfb\x35\x67\xc8\x67\xb3\x7b\xf6\x74\xd1\xd8"
-  "\x17\xa5\x39\xbf\x06\x9e\xf7\xe4\x63\x34\xfb\x60\x03\xc6\xbf\x5b"
-  "\x97\x8e\x71\xdd\x4e\xde\x0f\xb6\xef\xcd\xf8\x0d\xf4\xbf\xb2\x17"
-  "\xee\xb8\xef\x85\xef\xdd\xfb\x8c\xf9\xcd\x42\x1f\x6f\x7c\x4f\xff"
-  "\xc9\x5b\x65\xdc\xc1\x77\xc6\xc0\xf3\x04\xc9\xbe\xc7\xfc\x63\xcf"
-  "\x90\x26\xa7\xdb\x7b\x35\x3c\x7f\x01\x65\x8f\x93\xde\x07\xc3\xf3"
-  "\x11\xb4\xb3\xd9\xf9\xfb\xbc\x4c\x69\x8f\x69\x53\x29\xa4\x69\xa4"
-  "\x3c\xe3\x20\x4f\x2e\xda\xee\x52\x19\xe3\xe1\xf9\x69\x1c\x13\x4b"
-  "\xef\xc3\xe0\xf9\x61\x5c\x0b\x90\xde\x4f\x80\xe7\x7f\x83\xe7\x1f"
-  "\xf0\xf3\x0e\xdd\x52\x1f\x6d\x52\x06\x76\x66\xb3\x89\x8d\xff\x78"
-  "\x9c\x76\x1c\x0b\x34\x2d\x70\xed\xe7\xf9\xac\xad\xd7\xbb\x04\xb7"
-  "\x77\x4d\xf2\x3b\xbe\xe7\xac\x69\xab\xdb\xbb\x9a\x5e\xef\x4a\xdc"
-  "\xde\x55\xf4\x2a\xb3\xc2\xed\xdd\xfe\x5e\xff\x6b\x74\x7b\x57\xd0"
-  "\xeb\x9d\xcd\xed\x9d\x41\x7a\x17\xd4\xa9\x3f\xa9\x76\xad\xc9\x7d"
-  "\x96\x26\xa5\x0b\x90\xee\x16\xff\xe0\xb3\x04\x29\x1d\xbe\x7f\x72"
-  "\x8e\x85\xe4\x1f\x90\xd2\x19\xef\x79\xf9\x27\x17\xbb\x95\x3f\x9b"
-  "\xcf\x7d\x9c\x4c\xe8\xd9\x0b\x37\xa6\xb2\x51\xec\x8e\x7d\x11\xde"
-  "\x69\x11\x57\xee\xd8\x5e\x93\xaa\x7d\xe2\x99\x5f\x6b\x93\x57\xa6"
-  "\xe0\x76\x94\xd5\xab\x52\xb4\xab\xd7\xc6\xaf\xf4\xf0\xbb\x1c\x86"
-  "\x7e\xcb\x30\xae\x0f\xfa\x54\x90\x7c\x84\xb7\xf6\xf8\xc6\x07\xb9"
-  "\x0a\xdf\x82\xf1\xff\xcf\x98\x0f\xf6\xdd\xdc\x3f\x71\x35\xfa\x64"
-  "\xe0\xfe\x17\xc8\x03\xcd\xe4\xe4\x09\xc9\xff\x82\xa9\x53\xff\x0f"
-  "\xe2\xdd\xff\xc2\xe7\x4d\xcc\x47\x1a\xe4\xe3\xfe\x17\x3e\xb7\x40"
-  "\x3f\x9f\x4b\xc7\x70\x3f\xf9\x3c\xbe\xce\x3f\x64\xdb\xc4\xba\xec"
-  "\x22\xf3\x33\x96\xc9\xe7\x36\x7a\xfb\x7e\xac\x50\xe1\xff\xa4\xf5"
-  "\x4f\x95\xdb\xff\x13\xf9\x7b\x59\x3f\x48\xdf\x34\x54\xa0\x7f\xdb"
-  "\x31\xcd\xf0\xcc\xe6\xe3\xd9\xbb\x7f\x70\x3f\x2e\xd9\x15\x1a\x6c"
-  "\x13\xb6\xdb\xb3\x6d\xc2\x92\x66\xf2\x8f\x37\xdc\xda\xd6\xe4\xe6"
-  "\x4f\x4a\x6e\x03\xf7\xd9\xd5\xb7\xad\xec\xbc\x0e\x55\x55\x68\xf0"
-  "\xdb\x28\xcf\xf8\x5e\x77\x78\xce\xae\x50\xcb\xf5\x71\xab\x9f\x06"
-  "\xc7\xf9\x50\xbf\x2f\x38\x4d\x40\x7e\x00\x4f\xa5\x36\xbc\x4c\xf5"
-  "\x27\xb7\xb2\xbd\xdb\x78\x76\x0f\x63\x17\x30\x5d\xf5\x79\xa2\x3c"
-  "\x57\x89\x3a\x8a\xfb\xc2\xfe\xdc\x65\xff\xa1\x9f\x9f\x6c\x59\x7f"
-  "\x7d\xee\x66\xff\xf1\x6f\x42\xda\x7e\x77\x0c\xb9\x7d\xef\x04\x7e"
-  "\x0f\xf2\x2d\xe6\xfb\xc5\x2b\x98\xcc\x80\x67\xe6\x47\x14\xff\x8b"
-  "\x75\xf4\x16\x0b\xca\x9b\x1f\x36\x17\x1d\x2d\xd3\x65\x3a\xee\x66"
-  "\xb1\x4a\x2c\xb3\xe4\x79\x3c\x76\x5e\x05\xf2\x60\xdf\x42\xf9\x44"
-  "\x55\xe7\x48\x95\xf6\x3c\xd4\xc9\x92\xb0\x9b\xfb\x1a\x6b\xbc\x5d"
-  "\x4d\xe2\x38\x8d\x2d\x4f\xa3\xac\xc7\xbe\xc3\x65\xbe\xa5\x5e\xe2"
-  "\x7d\x02\x6f\x87\x65\x0f\xa6\xbb\xf6\x69\x5b\xac\x72\x3e\x59\x3e"
-  "\xf3\x75\x28\xcb\x51\x96\x8f\xc7\xaa\x4c\xe2\xbc\xff\x81\xa6\x99"
-  "\x58\x9a\xa4\xfc\x6c\xef\x28\xf7\xaf\x61\xb1\xd3\xec\x23\x49\x50"
-  "\xe7\x56\x0b\x39\x29\xed\x33\xe6\xdf\x85\x7b\x13\xd6\x05\x69\x85"
-  "\x67\x3f\x69\xae\xb2\x11\xf8\x94\xe0\x2d\x3e\x3a\xdf\xdf\xde\xcc"
-  "\x7c\x10\x61\x2c\x08\x9c\x83\xe5\x32\xb9\xf9\x19\x7a\x81\x96\xa3"
-  "\x8f\x4f\xc8\xa3\x96\xf3\x70\x19\xce\xde\xb1\xfd\xc8\x49\xa9\x38"
-  "\x4f\x24\xbd\x4b\xc5\xf3\x71\x3d\xbf\x47\xba\xfd\x1e\x81\xbf\x69"
-  "\x2a\x2d\xdb\xb1\x81\xe9\x58\xa5\xeb\xec\x6d\x73\x0a\x3c\xab\x7b"
-  "\x3d\x87\x79\x3c\xaf\x27\x11\x6c\x5f\xad\x8d\xb6\xb0\xfd\xc7\x52"
-  "\xba\x54\xf6\x68\x56\x9f\x54\x3a\x1b\x30\x12\x81\x67\x29\xa5\xfe"
-  "\x18\x81\x67\x30\x43\x1d\x8f\xb1\xf3\x97\x18\xeb\x5d\xba\x47\x4a"
-  "\xf7\x99\x3c\x4e\x60\xf3\x4c\x57\xac\x5f\x9c\xab\x69\x9e\xe3\x2d"
-  "\xf6\xb0\x1c\x9b\x59\x8e\x3d\x8c\xe7\x37\xa5\x18\x45\x4b\xe1\x7f"
-  "\x29\x03\xc5\x79\x86\xf7\xbb\xe5\xb3\x98\x4e\xc3\x41\x93\x68\x38"
-  "\x8b\x7e\x5f\xaf\x47\x9f\x43\x19\x6d\xe8\xb3\xc1\x46\xcc\xa4\x8b"
-  "\x98\x53\x3a\x33\x31\x4e\x5d\x1d\x8f\x4f\x17\x82\xfc\xc0\xb3\x40"
-  "\x68\x43\xd6\x25\x9d\x65\x31\xea\x9e\x6d\x23\x11\x49\xf7\xd2\x16"
-  "\xa0\x81\xdd\x99\x7d\xd0\x24\xe1\x68\x0f\xe8\xc2\xa9\x67\xc8\x97"
-  "\x4c\x36\xb3\xb8\xaa\x6d\x6c\x3d\x4b\x75\x9a\x7c\x69\x60\x79\x68"
-  "\xec\x1e\x4e\xbb\x2f\x99\x7e\xd8\xab\x97\xe3\x90\x7d\x19\x29\xc7"
-  "\x3a\xb5\x90\x2f\x8d\xe7\x47\xbf\xdf\x0a\x69\xf3\x3c\xf7\x42\x7f"
-  "\x89\x31\x59\x43\xb1\xee\x90\x87\x60\xd9\x90\xc7\x25\xff\x21\xfd"
-  "\x59\x07\x99\x0c\xf5\x3a\x2d\x97\x0f\xef\x0d\x16\xf2\x05\xd3\x31"
-  "\x58\xe6\xf9\xec\x73\x1a\x48\x2b\xb4\x08\x79\x26\xbe\x97\xfa\xcb"
-  "\x52\x0b\x29\x3c\x30\x90\x2d\x04\x7d\xa1\x04\xfa\x52\xa9\x68\x38"
-  "\x52\xc0\xfc\x03\x8f\x3e\x52\xc2\xe7\x1e\xbf\x3c\x8f\xfb\xb5\x76"
-  "\x5c\x20\x4a\x9c\x0b\xe4\x98\x6d\x61\xe7\x0a\x31\x0d\x64\x76\x29"
-  "\xf4\x11\x36\x67\xe0\x9f\xfe\x6f\xe1\xe7\x20\xda\x89\x2a\x2f\x59"
-  "\xf6\x6f\xdc\x12\xe3\xe6\x6b\x5d\x3a\x1f\xd1\xb2\xbe\x2e\x8d\xad"
-  "\x63\xb3\x3a\xf6\xae\x03\xd6\x17\xe8\x64\xf3\x6a\x6b\xaa\x8e\x14"
-  "\xb0\x35\x97\x9c\xca\xfd\x7c\xef\x69\x4b\x65\x50\xf8\xa4\xe7\xe0"
-  "\x5b\x15\xf2\x5c\x22\xe6\xc9\xc3\x18\xa0\x50\x7e\x4f\x3b\x93\xd9"
-  "\x37\x5a\x78\x5f\x6f\xb1\x8b\xd9\x47\x0a\xb0\x0e\x52\xba\xbd\xce"
-  "\x61\xc7\xb3\xdb\xfd\xfa\xc1\x61\xf1\x9d\x70\xaf\x77\xce\x91\x02"
-  "\x3c\x5f\x72\xbb\x5d\xae\xf3\x29\x3b\x9e\x6b\xc0\x3a\x73\xda\x9e"
-  "\x3a\x2b\xd3\x31\xb7\x1d\xca\x4e\xff\x94\xb4\x90\x53\xcf\xe0\x7e"
-  "\x38\x3c\xa7\x83\x7d\x98\xd3\xe0\xd4\x33\x2c\x5f\x57\x4f\x1e\xe6"
-  "\xef\x82\xc5\x0c\x81\xf2\x8b\x59\x7c\x21\x68\x03\xf0\xc2\x94\x8e"
-  "\x67\x76\x4f\xb1\xb1\xdd\x96\x64\xc2\xdb\xcd\xf6\xbf\x9e\x8e\xe0"
-  "\x58\x39\x75\x40\xd6\x19\x16\x29\x6d\x07\x7e\x3b\xb5\x8b\x9c\x23"
-  "\xa7\x5e\xc0\x18\xbf\x40\x8f\x52\xf4\x1f\x55\x67\x83\x7e\x92\xd6"
-  "\x85\x58\x28\xc5\x38\x72\xa0\x53\x76\x73\x3d\x87\x34\x3f\x95\x86"
-  "\xdf\x47\xda\x02\xef\xac\x40\xd3\xec\x4e\xfd\x69\x8d\x4c\xd3\xbc"
-  "\x89\x38\xee\x39\x35\x73\x20\x1d\xe1\x84\x3a\xd7\x81\x75\x65\x9a"
-  "\xfc\x29\xd6\xef\x84\x38\xe6\x48\x01\xee\xb5\x86\xdf\x9b\x24\xd9"
-  "\xce\x78\xc7\xfb\xd2\xe9\x3f\xc3\x37\x0e\xe0\xbe\x05\x94\x95\xe8"
-  "\xe3\x08\xd2\x62\x25\xfa\x31\x3f\xf7\xf9\xa9\x9c\x0e\x3c\xff\x57"
-  "\x6a\x3e\x6f\x3c\xe9\x2d\xa8\x97\xdb\xfa\xcf\x57\xcc\xdf\x4a\xb1"
-  "\x14\x97\x1b\xde\x55\xb9\xd5\xd9\xc6\xce\x49\xb6\xe3\x9c\xdf\xe9"
-  "\x44\xfc\x56\x2e\xfa\xf7\x41\x5c\x9c\x71\xc7\xff\xe9\x85\x58\x4f"
-  "\xdc\xcb\xeb\x1c\x5d\xb9\x1f\xf4\x6e\x19\xd2\x19\xfe\xb3\x15\xfa"
-  "\x42\xc1\x00\x3a\x91\xc5\x92\xea\xd4\x7f\x35\x5b\xd6\x89\x30\xce"
-  "\x00\xbd\xd0\x7a\x07\x1b\x7f\x82\x5d\x6d\x16\xd1\xae\x69\x8d\x44"
-  "\xdc\x80\x9c\x55\x4a\x32\x16\x74\xfd\x57\x89\xf2\x9a\x98\x13\xcf"
-  "\x43\x9c\x63\xeb\xb8\x36\x39\xde\x12\xf7\xa7\xf5\x55\xbe\xeb\xfc"
-  "\xc4\x57\x85\x7d\xce\x4f\xe0\xb9\x91\xdf\xb1\x18\x3f\xfb\x51\xa7"
-  "\xd4\xb6\xb5\xa0\x8e\x60\xff\xc7\x33\x15\xe9\x30\x36\xe7\x67\x4f"
-  "\x5a\x70\x9e\x9e\xc5\x47\xc0\xba\x70\x9f\xf8\xcd\xec\x37\xe0\x56"
-  "\x89\x77\x8e\xa5\x56\xd2\x13\xb3\x17\xf8\x8d\x6b\x70\x87\x95\xff"
-  "\x1f\x31\x4d\x43\x7d\xdd\x7a\x07\xc6\x9f\x85\x3c\xd3\xe5\xd8\xb3"
-  "\x2c\xd6\x2c\xdf\xaf\xe8\x2d\x76\x8d\x7a\xc7\x6d\x24\x12\x7d\x62"
-  "\xe0\x39\x2c\x46\x03\xb5\x32\x0d\xfd\xc6\xa2\x0f\x3c\xd3\x06\x8c"
-  "\xdf\xd0\xfa\xc5\x6f\x27\xb2\xb3\xac\x36\xd3\x6d\xed\xb8\x26\xd1"
-  "\x76\x7a\x23\xf3\x8b\xa2\x8a\x4e\x73\x50\xfc\x1f\xb3\x2b\x82\x95"
-  "\xb8\xdf\xaf\x8d\xf9\x4f\xc7\x32\x03\xf6\x81\xda\xba\x5f\xb2\x51"
-  "\xdb\x40\xee\x5f\x0b\xbc\x62\xeb\x1a\xf0\x7b\xe2\x19\x72\x66\x34"
-  "\x8f\x87\xc8\xfd\x79\x4b\xfb\xac\x47\xf2\x33\xf2\x40\x33\xe6\x2b"
-  "\xf4\xeb\x4d\xda\x19\x18\x3b\xf4\xeb\xcd\xcc\xa7\xae\xa1\x22\x4c"
-  "\xe2\x69\xd8\x0e\x5e\xaf\xd0\x65\x69\x02\xab\x23\xd6\xcf\xbf\xba"
-  "\x7d\x3d\x5f\x1a\x4f\x8c\xec\xd4\x7f\x6d\x94\xcf\xd6\x73\xbb\x8a"
-  "\xfb\xda\xe5\xbc\xf8\x5a\x3a\x63\x56\x11\x2e\x7d\x3b\x7c\x18\xbe"
-  "\x5d\xc5\xcb\x3c\xd8\xc6\xfd\x0d\xb7\x26\x01\x5f\x61\xfc\x70\x26"
-  "\x4c\x1e\xd7\x48\x67\x83\x66\xf2\xf1\xd6\x99\x99\xae\x71\x4d\x6b"
-  "\x9f\x73\xbe\xf7\xad\x5d\x9b\xa2\x8d\x5f\xb5\x2e\x69\x79\xca\x8a"
-  "\x04\xed\xca\xe4\xe4\xb5\xc9\x5a\x74\x96\xe2\xde\x7f\x78\x7c\x93"
-  "\x33\x51\x52\x3c\xaf\x52\x57\x3c\xaf\x33\x06\xf7\xb8\x73\x16\x72"
-  "\xc6\x38\x3c\x73\x18\x67\x4a\xbd\x95\x93\x2f\x88\x65\x70\x95\xc3"
-  "\x65\x82\xab\x1a\xe7\x34\x96\xd9\x49\x14\xe8\x7a\x66\x1f\xca\xbe"
-  "\xd8\x45\xfd\x19\xf4\x71\x1c\xd5\x4c\xfe\x39\xa2\x58\x54\x12\xe6"
-  "\x03\x44\x2f\x96\x61\xfe\xbd\xf0\x7f\xb8\x4c\x70\x55\xc3\xc5\xfe"
-  "\x27\x1e\x62\xe7\xaa\xcb\xdc\xdf\xf1\x7d\x21\x69\x91\x98\x87\x6e"
-  "\x56\xb2\xf5\x5f\x71\x17\xcf\xd7\xab\x0e\x02\xd5\x7f\x59\x21\xe5"
-  "\x63\xfa\x35\x64\x33\xd1\xf6\x93\x2f\x88\xea\x3f\x2d\x93\xf2\xb1"
-  "\xfd\x2e\x72\x7b\xd0\x6f\x39\xe4\x97\xf3\x29\xa9\xbe\x75\x9e\x94"
-  "\x8f\xc9\x4d\x51\x2f\xf4\xf7\xdd\x11\x54\xff\xbf\x3a\x29\x9f\xc6"
-  "\xbd\x3c\xb7\x3c\x23\x45\x7d\xfd\x7e\xcc\x23\x6e\x56\x72\xbf\x09"
-  "\xfa\x33\xa5\x90\xbf\xdf\x79\x1d\xff\xf8\xd4\xd6\xc7\xff\x53\xd2"
-  "\x8a\x55\x2b\x7f\xb2\x6a\x4d\x2a\x46\xa0\x49\x59\xfb\x4c\x0a\xde"
-  "\xd7\x2c\x7f\x8a\xdd\xd6\x2e\x7b\x72\x05\xff\x91\x92\x18\x89\x3f"
-  "\x12\x01\x6f\x78\x8f\x7f\x26\x09\x6f\x2b\xd6\xe2\x63\x5a\xc2\xcc"
-  "\x67\x56\xc8\xa1\xa8\xdd\x71\xa8\xeb\xd4\xb7\xd9\x01\x1b\xad\x5c"
-  "\xce\x9e\x55\x5a\xc8\xa7\x4c\x2e\x63\x4c\x8a\x23\x3a\x07\x91\xe7"
-  "\xb7\x38\xff\xdb\x62\xb8\x6f\xc6\xb3\xe3\x8a\xc5\x51\xaa\xd0\xcd"
-  "\x49\x2b\x42\x1d\xab\x56\x82\xce\x68\x82\xff\x46\x59\xc8\x8a\xf9"
-  "\x5c\x36\x56\x4c\x67\x7e\x08\xf5\x6d\xf9\xd2\x9e\x4d\xa5\x68\x38"
-  "\xd8\x88\xbe\xc0\xe1\x99\xc5\x7c\x15\x41\x1f\x40\x3e\x2d\x3c\x63"
-  "\xac\xd7\x30\x78\x6f\xc1\xb9\x29\x78\xc6\x18\xaa\x11\xa2\xe1\x35"
-  "\x2b\x9e\x45\x85\x67\x2d\x3c\x4f\x87\xf2\x4b\xe4\x7e\xd1\xbf\xad"
-  "\x7c\xd6\x24\xc7\xa1\xe5\x31\x67\xcf\xd6\xf7\xc4\x9c\xc5\x38\x33"
-  "\xe9\x1a\x16\x97\x86\xdb\x20\x67\x6d\x41\xe1\xd7\x8d\x81\x3c\xb6"
-  "\x9e\x38\x3c\x6c\xde\xe3\x9c\x52\xde\x2f\xc3\xe7\x35\xce\x85\xb9"
-  "\xc5\xee\xc5\xe7\xe9\x72\xec\x5e\x9c\xf7\x62\xb1\xd1\xe0\x4e\xf5"
-  "\xe8\xef\x91\x96\xf6\x3b\xa7\xc7\x62\xea\x9d\xcb\x46\x3f\x9f\xd6"
-  "\x8c\x78\xc5\x8d\xc5\x38\x97\x06\xcf\xdc\xc7\x1b\x3d\x47\xce\xb1"
-  "\xfd\xd7\xb2\xff\x27\x77\x9f\x03\xfd\x9e\x73\xfa\x08\x6c\x06\x16"
-  "\x33\x24\x71\x6d\xa8\x63\xf9\x4a\x6e\x07\x9e\xfb\x9a\xcb\xaf\xca"
-  "\x7a\x6e\x2f\x9c\x6b\xa0\x8b\x78\x9c\x05\x0b\xf9\x26\x16\xc7\x2c"
-  "\xa1\x8a\xc4\xb5\x14\xfe\x1b\x9a\xb6\x7c\x25\x4b\x83\x7c\x5b\xc0"
-  "\x56\x93\xea\xf7\xa6\x39\x02\xcf\x47\x8a\x92\x2f\x85\x73\xe5\x8f"
-  "\x4f\xc9\xc4\xef\xa8\x98\x1d\xf2\x11\x51\x63\x6c\x3b\xac\x5b\xb1"
-  "\x9b\x7f\xaa\x1d\x90\x86\x7b\x43\x3b\x16\x11\x35\xfa\xe9\x94\xea"
-  "\x52\xce\x63\x0d\x7d\x13\x23\xfb\x8a\xb1\x40\x5a\xef\xf6\x2c\x7a"
-  "\x88\xa1\xf2\xa6\x15\x33\x63\xee\x87\x5f\x33\xa5\xb0\xaa\xee\xd8"
-  "\x8c\xe8\x18\x73\xb8\xa4\xe3\x8f\x2b\xfe\xc6\x63\x00\x7e\x53\x02"
-  "\xe5\xb0\xb1\xb6\x88\xe3\x92\xce\xd8\x02\xbe\xb7\xf4\x9b\x13\xe8"
-  "\x17\x53\xd4\xa3\x3d\x89\xe7\x6b\xbf\x61\xf2\x8b\xaa\x2a\x1b\xf6"
-  "\x6e\x42\x7f\xb1\x0a\xa0\xf1\x37\x6f\xe3\x3b\xc9\xe7\x8e\xc0\x7c"
-  "\xd4\x38\x49\x38\x3b\x5f\x0a\x36\x0a\xfa\x97\x39\x4d\xda\xdf\x40"
-  "\xbb\x03\xe7\x95\x44\xfd\x37\xf1\x88\x5b\xe0\x31\xfa\x9a\xb0\xd1"
-  "\x31\x07\xab\xe8\xe8\x43\x29\x88\x63\xb4\x75\xcd\x1a\xa4\x99\x15"
-  "\x75\xce\x5c\xb8\x96\xf0\x78\x16\x8f\xb6\xca\x65\xa2\x5f\x24\xb0"
-  "\xa1\x9a\xe0\x0e\x63\x17\x6b\xac\x5b\xac\x2e\xe9\x3c\xad\x75\x3d"
-  "\xfa\x6b\xc2\xb2\xb9\xed\xdc\xfe\x32\xb7\x41\xac\x5b\x2d\x24\x74"
-  "\x0e\xef\x8b\x56\xb0\x7f\x32\x67\x4a\xbf\xc1\xfe\x99\x59\xd2\xab"
-  "\x8c\x53\xf2\x9c\x29\xc7\xb4\x15\xe7\x1e\xe6\xc2\xb5\x04\xf2\xd7"
-  "\xc8\xf1\x9a\xb7\x08\xec\xfc\xe3\xe9\xa0\x70\x3c\x17\x6d\x6d\x91"
-  "\xd3\x47\x28\xa2\x80\xa6\x56\x9b\xdc\xf7\x3b\xc6\x54\x96\x77\xea"
-  "\xbf\x55\xca\x73\x2d\x7c\xee\xe5\xdb\x30\xb7\xe7\x2a\x78\x9e\x2e"
-  "\x3f\xc3\xef\x48\x59\x56\xc0\x6f\x18\xff\x66\xb4\x49\xbf\xe7\x5b"
-  "\x88\xbe\x54\xfa\xbd\xd8\x22\xe4\xc7\xcb\xf5\x16\xf5\x41\xa1\xbc"
-  "\xee\xed\x46\x31\xfb\xac\x16\x63\x64\x43\x9e\x34\x0b\x39\xcb\xf6"
-  "\x75\xa0\x7f\x24\x63\x97\x66\xb1\x79\x2b\xd8\xc4\x4f\x22\x96\xda"
-  "\x59\xdf\xc8\xdd\xa0\x89\x41\x7b\x12\xfd\x40\x30\x5f\x5a\xe8\x3f"
-  "\xce\x41\x46\x32\xbf\xe3\xd9\x67\x35\xcc\xdf\xf6\xb3\x3a\xb5\xec"
-  "\x3b\x0e\xe4\xcc\x46\x2a\x3c\xb9\x15\xfd\xc9\xb1\xf8\x02\x9d\xba"
-  "\x10\xe6\x43\x4e\xf2\x1d\x57\x94\x4a\xc2\x0a\x45\xee\x3b\x8e\xf9"
-  "\x88\x18\x09\xe3\x8f\xd4\xfe\xfd\xc7\x51\xfd\xcb\xf5\xb2\xff\x38"
-  "\x7a\xc1\x69\x87\xdf\xd3\x81\xe7\x4a\xb8\xf3\x67\xf4\x21\xc7\x7d"
-  "\x07\x2b\xfb\xf5\x27\x27\x80\x3c\x13\xb8\x3f\x39\xff\xf4\x40\x7b"
-  "\x2c\xc7\x44\x7b\x81\x1c\x3b\xda\x2d\x0d\xec\xf3\x73\x52\xfc\x33"
-  "\xab\xe4\x1b\xa6\x1d\xe4\x5f\x46\x94\xb4\x47\xd2\x8a\xf3\x62\xbb"
-  "\xd9\xdc\xd7\x37\x0e\xda\x9d\xb0\xa7\x3f\x59\xd2\x1e\x32\xd2\xda"
-  "\xce\xf6\x02\x76\x80\xed\xdb\xc1\xf8\xc4\xc7\x88\x1d\xa4\x77\x7f"
-  "\x7d\x62\xc5\xda\xf8\x95\xcb\x7e\xb3\x3a\x49\xbb\x68\xf1\x5c\x16"
-  "\x18\x6d\xa6\x76\x55\xca\x4a\xa6\x6a\xb4\x8b\xee\xbf\x2f\x3a\x7a"
-  "\xf1\xb2\x87\x16\xff\x7c\xf1\xc3\x0f\xdd\xc3\x4f\x18\x2e\x4e\x5e"
-  "\x8f\xc1\xf5\x52\xd6\x6a\xf1\x4f\x4f\x48\xa1\x6f\x37\xac\x4c\x5e"
-  "\xdb\xbb\x9f\x87\xb1\xf9\x2b\x81\xcd\xd9\xda\xf0\x37\x9f\x23\xeb"
-  "\x28\x94\xe7\xae\xb8\x4c\xeb\xc8\x45\xda\xb2\x58\x87\xfa\x8e\x30"
-  "\xb4\x9b\xa4\x18\xc3\xa8\x4f\x94\xd8\x57\x51\xaf\x40\x5b\xaa\x7b"
-  "\xe2\xa1\xf6\xcc\x9f\x75\xb4\x09\xf8\x3f\xa9\x8f\xf2\x34\x9b\x82"
-  "\x4e\x9e\x9c\xc1\xfd\xf0\x77\x38\xe4\x79\x6d\x4c\x93\xeb\xd0\x8c"
-  "\x79\xf4\x1d\xf7\xbb\x62\x72\xda\xa6\xbb\xe2\xce\x91\x3e\x34\x22"
-  "\x04\xcd\x94\x11\x60\x83\x8c\x84\x6b\x14\x5e\xf3\x7b\xe4\x76\x2a"
-  "\x6d\xc4\xb1\x58\xa8\x02\x74\x6b\x5a\x10\x8f\x79\x93\xd5\xc0\xfc"
-  "\xb3\x47\x3b\x1d\x41\xcb\x9c\x02\xdc\x83\xe8\x32\xa7\x92\x8d\xff"
-  "\x68\x2a\x6d\x40\x5f\x68\xf0\xbf\x7a\x8c\xed\x04\x38\x36\x44\x3b"
-  "\xd2\x0d\xd1\x4e\xea\x58\x06\x76\x39\xdc\xbf\xc2\x33\xde\xd1\xce"
-  "\xaf\x28\x8b\x6b\x01\x79\xf3\xb8\xff\xaf\x6a\x3c\x8f\xfa\x38\x60"
-  "\xb8\xb8\x9d\xc7\xf5\x8c\x5e\xff\xcd\xe7\xcb\xd6\x5b\x78\x5c\xcf"
-  "\x73\x3c\x7e\x2d\x8f\xcb\x4b\xd2\xa1\x9c\xa3\xcb\x9c\x41\xda\x68"
-  "\x67\x37\xe5\xe7\x54\xcf\xab\x06\x8a\xd5\x89\xb2\x73\xdd\x24\x22"
-  "\xe0\x3c\x8a\xb3\xf8\xa1\x48\xf4\xf5\x95\x61\xa5\x76\xf4\x4d\xf2"
-  "\x6e\x57\xa3\xa0\x4d\xc5\x38\x48\xe7\x6f\xad\x4b\x8a\xec\xff\x9c"
-  "\x72\x96\xd9\x46\x73\xb7\x55\xd1\xac\x8f\xaa\x68\xae\x61\x1e\x35"
-  "\x1c\x2a\x41\x39\x4e\xb3\x8e\xef\x86\x67\x48\x6f\x8c\xa7\xb9\xd9"
-  "\xf3\x68\xd6\x67\xb3\xe0\x0e\xcf\xff\x50\xd2\xdc\x1c\x78\x2e\xaf"
-  "\x81\xff\x99\x68\xd6\x9b\xf8\xbf\x28\x9a\xf5\x56\x05\xdc\xe1\xf9"
-  "\xe0\x01\xc8\x07\xcf\x15\xfb\xe1\x0e\xcf\x6f\xef\x3b\x4d\xce\xdb"
-  "\xe1\x3f\x90\x66\x69\xe0\xdf\xfa\xb2\x81\x7d\x2b\xeb\x74\x03\xff"
-  "\xc6\xd7\x0d\xfc\x1b\x6d\x0d\xfc\x1b\xdf\x34\xf0\x6f\xbc\x53\x08"
-  "\xf9\xab\x69\x96\x49\x0d\xf9\xe6\xd3\xac\xca\x8d\x70\x87\xe7\x43"
-  "\x6d\x90\x0f\x9e\xab\x96\xc2\x1d\x9e\x8f\x40\x5d\x72\xe0\xf9\xfd"
-  "\x39\x90\xbf\x86\x66\x55\x97\x41\xbe\x05\x34\xeb\xd8\x74\xb8\xc3"
-  "\xf3\x07\x05\x90\x0f\x9e\x6b\xa1\x9c\x6c\x78\xae\xcb\x84\xfc\xf0"
-  "\xdc\x8e\xf5\xa9\xa7\x59\x36\x2c\x37\x86\x66\x5d\xc0\xfc\xf0\xdc"
-  "\x09\xe5\x65\xc3\xf3\xc5\x14\xb8\xc3\x73\x77\x04\xe4\x87\x67\x07"
-  "\xb4\x75\x5b\x03\xcd\x12\x93\x20\xdf\x62\x9a\x43\x20\xdd\xd0\x40"
-  "\x73\x14\xd5\x90\x0f\x9e\x83\x30\x3f\x3c\x8f\xd0\x42\x7e\x78\x1e"
-  "\x89\x34\x6a\xa4\x39\xa3\x67\x42\xbe\x58\x9a\x33\xd6\x08\x77\x78"
-  "\x0e\xc6\xfa\xc3\xb3\x66\x01\xdc\xe1\x79\x3c\xd0\x2a\x07\x9e\x27"
-  "\x40\xfd\xb6\x35\xd1\x9c\x6b\xb1\xfc\xa5\x34\x67\x12\xd2\x07\x9e"
-  "\x23\x66\x43\x3e\x78\x9e\x0a\xf4\xc8\x86\xe7\x1b\x08\xe4\x5f\xda"
-  "\x2f\x3f\x73\x6e\x6c\xa4\x9b\x47\x12\x9a\x33\x33\x81\x6e\x1e\x05"
-  "\xf7\xdb\xc2\xe9\xe6\x11\x3a\x9a\x73\x47\x1a\xa4\xc3\xfd\x36\x2b"
-  "\x3c\xcf\x94\x9e\xe1\x7e\x7b\x35\x3c\x47\x4a\xcf\x70\x8f\x2c\x81"
-  "\xe7\x59\xd2\x33\xdc\x7f\xa4\x83\xe7\xd9\x34\x67\x16\x81\x67\xb8"
-  "\xff\x68\x37\x3c\xcf\x91\x9e\xe1\x7e\x57\x15\xdc\x1d\xd6\x29\x8b"
-  "\x0c\xd6\xe0\x25\x51\xd6\xe0\xed\x65\x88\x49\x67\xde\x36\x93\x18"
-  "\x62\x88\x02\x7d\x3a\x32\xe3\x3c\xc6\xce\xb4\x1f\x41\x99\x62\xde"
-  "\x68\x61\x71\xc3\x24\xdf\x73\x23\x9b\x49\x67\x25\xd8\x3e\xb3\x31"
-  "\x06\x3a\xb4\xdd\x41\xf5\x23\xda\xa1\xcd\x1b\xa9\x7e\x6c\x33\xdc"
-  "\xe1\x79\xdc\x47\xd0\x66\x78\xbe\x3b\x07\xee\xf0\xfc\xe8\x7d\xd0"
-  "\xf6\x8d\x9d\x7a\xbb\xd6\x42\xce\x73\x5f\x60\x7f\x5c\x51\x16\xea"
-  "\xc8\xa0\xd1\x0e\xd0\x1d\x7b\x76\x25\x85\x3a\xe2\x80\x3e\xc6\x98"
-  "\x50\xf4\xeb\x5f\xb4\xa8\x9a\x86\x2c\x61\x75\xc2\xd8\x1d\xb4\x7b"
-  "\xba\xc0\xbf\x3d\x96\x36\x13\xfb\x42\xf4\x31\x4f\x43\xd6\x7a\x7b"
-  "\xbf\x9a\xbd\x9f\xbc\x2b\x93\xbf\x57\x11\xd7\xfb\x47\xf1\x7d\x6e"
-  "\x28\xfa\x3f\x9e\xfa\x00\x7b\x6f\xb6\xb5\x4a\xed\x0a\xc2\x77\xaf"
-  "\x60\x5e\x0b\xb1\xd7\x70\x19\xde\x59\x4f\xf5\x41\xa4\x43\x75\x28"
-  "\x1f\xea\xde\x04\x75\x0f\x93\xe6\x2d\x1a\xa9\xea\x60\x13\xf7\x95"
-  "\x71\xa4\xdf\xb8\x08\x38\x36\x15\x8d\xf9\xa5\xb9\x20\x07\x71\xbc"
-  "\x0b\xfa\x50\xd0\xa6\x4f\x2f\x6f\x26\x5d\xa5\x45\x6c\x1e\x63\xd7"
-  "\x7c\x2e\x1f\x2f\xae\xee\xce\x39\x54\xa5\xdd\x10\x0a\xdf\xef\x7a"
-  "\x25\xc3\x4e\xcf\x9b\xd2\xd1\xef\x10\xa6\x1f\x96\xfc\xfe\xb1\x3c"
-  "\x6d\x7c\x2f\x28\xfb\xdd\xc8\xe7\x97\xbb\x4a\xf1\xbf\xee\xe3\x0b"
-  "\x67\xd6\xb4\xd9\x62\xc8\xae\x18\xbe\x76\x7e\xf1\xe9\xb7\x45\x8b"
-  "\x10\x9a\x42\x46\x68\x37\xbc\x0b\xe5\x5f\x2c\xf7\x18\x8b\xf6\xe4"
-  "\x65\xef\x8a\xde\x81\xbc\x2f\xb1\x79\xa3\x8b\xd5\x3d\x31\x55\xa1"
-  "\x0d\xdb\x51\x17\x0a\x24\x0a\xf5\x33\xb7\x6d\xbb\xe6\xa3\xaf\x4a"
-  "\x87\xda\x18\xe9\x30\x2e\x89\x74\x1a\x77\xcd\xa7\x79\xbb\x62\x42"
-  "\x1c\x0a\xc2\xf7\xe0\x77\x6d\xba\xdd\x8e\xb6\xe4\x31\xcc\x7b\x97"
-  "\x38\xf2\x87\xf6\xdb\xd2\x88\x60\x4a\xfe\x14\x9f\x9f\xa1\x59\x77"
-  "\x94\x98\xdb\x1a\x89\x29\x99\x95\x95\x42\xb3\xee\xd9\x2a\x8e\xfc"
-  "\xf1\xd2\x62\xb4\xc9\xd3\x70\x4e\xed\x23\xa4\xcb\x45\xe0\x0b\xe8"
-  "\x95\xae\xc5\x3d\xf1\x7e\x81\x96\xb9\x40\x3b\xb4\x97\xd1\x7f\xc5"
-  "\x32\xa7\x13\xfd\x8b\x19\x2c\x40\x07\xce\xaf\xae\xd9\x18\x2b\x59"
-  "\xfa\x6e\xae\x38\xe6\x50\x59\xdd\x52\x5c\x27\x54\xa1\xbf\xa6\xf3"
-  "\xec\xcc\xbb\x03\xe3\xa7\xa1\xee\xe1\x79\xdd\x79\xb7\x7a\x45\xd2"
-  "\xb2\x0d\x49\x6b\x93\x53\x96\x3d\x93\xf4\x13\x2d\x0c\x12\xb5\x6b"
-  "\x9f\xd4\xae\x5e\xb9\x7a\x6d\xf2\xfa\xde\xfa\x16\xc6\x4a\x5d\x6d"
-  "\x80\x13\x16\x4f\xf5\x28\xd8\xea\x7c\xae\xde\x51\x81\xbc\xde\xf3"
-  "\x3b\xee\xfb\xbe\x53\xdf\xad\x81\xf1\x1c\x5b\xd3\x10\x0b\x76\x25"
-  "\xd0\xc2\x45\xd5\xd9\xe8\xb7\xe3\x19\xf4\xad\x6e\x25\x66\xd2\xce"
-  "\x63\x16\xb2\xb8\x5c\x30\x76\x48\xdd\x44\x4d\xa9\xed\xd8\x0f\xe6"
-  "\xd3\xdc\xed\xb1\xb4\xe8\x21\xcd\xc5\xdc\x25\xa5\xcd\xc4\x51\x72"
-  "\x31\x77\xfb\x7c\x39\xae\x8a\xd3\xb8\xbd\x54\x54\xe7\x9b\x30\xae"
-  "\x4a\x37\x0d\x27\xb5\x40\xcb\x2e\xc3\xa1\x42\xd0\x03\x05\x45\x7a"
-  "\x5a\xee\x84\xb1\x14\xf3\x4d\xf3\xc7\x15\xf9\x4e\xaa\x53\x3a\xf5"
-  "\x44\x05\xf7\x10\x1a\xb2\xd3\xda\xad\x36\x46\xe1\x7b\x8c\xa7\xe2"
-  "\xec\xd6\x91\xf4\x06\x2a\x3e\x92\x00\xb8\xd1\x13\xca\x62\x51\x26"
-  "\x9c\x25\x90\x3e\x46\xcc\xdb\x5e\x7f\x7a\x3e\x11\x30\x2f\xd8\x7b"
-  "\x64\x29\xfc\xde\xb8\x9c\x04\x43\xbe\xd0\x8d\x47\x21\xbd\x53\x37"
-  "\xc6\x91\xa1\x53\x75\x65\xe8\xc6\x74\x53\x9d\xda\xdc\x62\x27\xdd"
-  "\x37\xad\x28\xb9\xd5\x4a\x94\x7b\xc0\x2e\x2c\x12\xa1\x0f\x16\x2e"
-  "\x2a\x73\x3e\xa7\x1b\xe9\x78\x4e\xa7\xec\xee\xd6\xa9\x1c\xcf\xea"
-  "\x94\x5d\xcf\xea\x46\x76\x77\xea\x54\xe6\x78\x2b\x39\x66\xfd\x13"
-  "\xa9\x6b\x69\x65\xf3\xb9\xdd\xc1\x3b\x1d\xdd\xc1\xdb\x9b\xd4\x2d"
-  "\x24\xec\xb6\x24\xb0\x0b\xf5\x44\xf1\x22\x8c\x01\x00\x13\x6a\xc7"
-  "\x1f\x56\xe4\xd3\xdc\x9d\x25\x40\xdf\xe7\xef\xbf\x85\x7e\xe3\xcc"
-  "\x52\xc4\x68\x1f\x00\x79\xb5\x59\x19\x0e\x69\x80\x9f\x60\xd0\x59"
-  "\x63\x54\x74\xb3\x32\x02\x2e\x90\x31\x8c\x0f\x84\x66\x11\x25\xce"
-  "\x27\x60\x5e\x9e\x6f\x24\x60\x09\xef\xc2\x3e\x16\xef\x51\xdf\x75"
-  "\xa0\x88\xd9\x24\x8e\x9e\xf8\xef\x55\xca\xfe\x7d\x83\x40\x9e\xa6"
-  "\x9e\xb1\xb9\x08\x32\x27\x77\x5b\xbf\x7b\x62\xd9\x79\x12\xfc\x76"
-  "\xde\x36\x4b\xbe\xd8\xe3\x87\x15\x64\xa6\x73\x04\xf4\x9f\x4c\xf6"
-  "\xce\x68\x8c\x49\xff\x96\x04\xe1\xbb\xb2\x0b\x76\x01\x9f\xb5\xc9"
-  "\x0a\x6a\xb6\xd9\x09\xfc\x47\x49\x23\x16\x55\x97\x5d\xb0\x0a\x88"
-  "\x97\x3a\x48\x83\xff\x4e\xc9\xbf\x20\x95\x5b\xb0\x2b\x29\xe3\x69"
-  "\xc2\xe2\x0f\x60\xbc\x15\xc4\x51\x7e\x3a\x8c\x2d\x31\x36\x4c\x32"
-  "\xca\x30\xe7\xaf\xe0\xb7\x0a\xf3\x51\xb5\x31\x46\x84\x32\x00\x4b"
-  "\xe5\x34\xd8\x38\x5b\xcc\xdd\x6e\x02\xd9\x9a\x49\xa7\x3c\xa4\x13"
-  "\xf7\xec\x8a\xed\xd4\x3b\xcb\x80\x1e\xd5\xf2\x5c\x45\x5d\xa9\x83"
-  "\xa0\xff\x26\x7a\x9f\x83\x1c\x49\x39\x8f\xbe\x37\x83\xac\xa3\x0f"
-  "\x95\x58\x83\xf3\x4b\xad\xc1\x3b\x4b\xc4\xdc\x7c\x2b\x5c\xb6\xa4"
-  "\x64\x5c\x97\x14\x53\x9c\x7a\xee\x8b\x3a\xfa\x5b\xda\xc9\xf6\xa0"
-  "\xeb\x71\x7e\x97\xfb\x7f\x63\x3e\xa9\xa5\x58\x34\x2c\xfe\x0c\x8c"
-  "\x1f\x80\xa7\xd3\x31\x06\x4d\xd1\x05\xc0\xc7\x05\x12\x2e\xc7\x17"
-  "\x29\x92\xfc\x4e\xe7\xa5\xba\xc6\x0d\xd2\x78\x20\x8c\xc7\x12\xd9"
-  "\xc3\x7c\xe8\x32\x99\x85\xfe\xe2\x70\x6c\xb0\x4e\x87\x31\xd2\x5d"
-  "\xfe\xe2\x3a\x75\x02\xd8\x7b\xf5\xcc\xde\x03\xec\xb0\xb8\xf6\xb9"
-  "\x46\x1d\xc6\x11\x40\xbb\xae\x88\xf9\x3f\x15\x4b\x64\xbb\x0c\xe5"
-  "\x88\x33\xfb\xd0\x7e\xb8\x4a\x21\xbd\xdc\xa2\x18\x67\x91\x65\x0c"
-  "\xe8\x9e\x38\x31\xe7\x67\xc6\x4e\x3c\x13\xd5\x9d\xf0\x33\xcc\x0b"
-  "\x74\xcb\x87\x6f\x05\x39\xbb\x13\xe6\xc0\x75\x0f\x5c\xf7\x3a\x73"
-  "\x8d\x91\xce\xdc\xed\x31\xce\xdc\x9d\x99\xce\xdc\x25\xf1\x70\x25"
-  "\xc0\x95\x08\x57\x12\x5c\x29\x70\xa5\xd1\xdc\x25\x1b\xe1\x8e\xef"
-  "\xb7\xc2\x65\x80\xcb\x08\x57\x3e\x5c\xbb\x9d\x7b\x76\xc5\x89\x80"
-  "\x4f\xb8\xb4\x70\x45\x38\x73\xf3\x5b\xe1\x2a\xef\xdf\x6f\x49\x9b"
-  "\x8e\xf9\x46\x1f\xf1\x39\x0d\xc5\x38\xa0\x1b\xcf\xa3\x1f\x41\xdd"
-  "\x11\x9d\xcd\x4f\x1f\xd1\x34\xd1\xdb\xbc\x08\x96\x0f\xfd\xab\xdb"
-  "\xcf\xf2\x2a\xbc\xce\xb3\x84\xef\x4a\x70\x44\x3c\xa4\x71\xe8\x49"
-  "\x26\xf4\x69\x45\x5d\x5c\x0b\x89\xb6\x92\x8c\x9a\x96\x2e\x92\x11"
-  "\x2f\xf9\x77\xde\x88\x67\x59\x9e\xdc\x8a\x38\x76\xd2\x58\x6d\xb7"
-  "\x71\x7b\xac\x53\x9d\x9f\x49\xd5\xf9\xe5\xcc\x67\x21\xc8\x1f\x8c"
-  "\xa7\xd4\x33\x2e\x45\x5c\xc1\xd8\xb4\xb6\xed\x3c\x79\x2e\x9e\x8a"
-  "\xb5\x09\x60\x9b\x34\x3a\xf1\xfc\xcf\xcb\x88\x31\x79\x6c\xfa\x1f"
-  "\x4d\x34\x13\xf0\x32\xda\x09\x74\x13\x71\x4c\x0a\xd8\xc2\xf1\xa9"
-  "\x8c\x2f\xd0\x67\x1a\x39\x06\x0d\x15\x68\x0c\xbc\x53\x62\x8c\x9a"
-  "\x42\x18\x93\x16\xa6\x92\xe9\x85\xf0\x8e\xc5\x13\x84\x7a\x3f\x98"
-  "\x14\x4a\xc5\xa7\x74\xa4\xf8\x37\x44\x15\x7c\x96\xc7\xa8\x74\x02"
-  "\xed\x7b\x7c\x9c\x1b\x97\x94\x2e\x3c\xab\x25\x47\x74\x27\x41\x2f"
-  "\x95\x81\xfc\x5e\x52\xda\x0d\xb2\x1b\x68\xe9\xf4\x8b\x96\x0a\x85"
-  "\xea\x52\xd1\xb2\x3b\x62\x51\x19\xa7\x67\x1c\x41\x9a\xf5\xa6\x27"
-  "\xd2\x78\x43\x0b\xd0\x13\xe8\x6a\x6e\x70\x92\x10\x05\x59\x2e\xd3"
-  "\xf3\x25\xa0\x27\xd0\x34\x1c\x69\x0a\xf4\x60\x34\xa5\x12\x4d\x8b"
-  "\xdd\x68\x0a\xf2\x89\xf9\x77\x44\x9a\x8a\x40\xd3\x62\x2f\x34\xed"
-  "\x19\xdf\x03\x4d\xf7\xfa\x44\xd3\xd2\x21\xd0\x54\x58\xea\x8d\xa6"
-  "\x0e\xd4\x99\x79\x4b\x4a\x28\xc8\x3c\xb3\xe3\x18\xf3\x55\x0a\xf6"
-  "\x8e\x0d\xec\x36\xab\xa8\xde\x5e\x0a\x34\x51\xe3\xfa\x3f\xc6\x44"
-  "\xca\x48\xa3\x5f\x64\x94\xd2\x8b\xce\xbc\x5d\x6c\x4f\x00\xc8\xae"
-  "\x84\xdb\xd1\x5f\x5b\x92\x85\x14\x0b\xb4\xbc\xee\x82\x8d\x9c\x56"
-  "\x8c\x78\xa1\x0b\x6d\xce\xbc\x5d\x3f\x13\x69\x02\x41\x39\xf2\xf8"
-  "\x2d\x44\xd9\x05\xb2\x22\x29\x95\x5c\x9f\x0f\xf2\xae\x0b\xe4\xe7"
-  "\x19\x45\x50\xe4\xfd\x49\x22\x85\x2b\x03\x7d\x6e\x8a\xc1\xf9\x56"
-  "\x90\xd7\x8c\xbf\xc8\x33\x5c\x57\xac\x7d\xfc\x10\x94\xa7\xbc\xe1"
-  "\x83\x38\x07\xc9\x48\xe8\xcb\x5f\x31\x23\x56\xeb\x34\x0e\xde\x4f"
-  "\x30\x2e\xdb\xc6\x56\xe4\x6b\x19\x31\xb7\xb8\xfa\x89\xf8\x2c\x97"
-  "\xc3\xc8\x0b\xec\x17\xd8\x47\x76\xb8\xc9\x5f\x90\xed\x9a\x22\xc9"
-  "\xc7\xbf\x13\xe4\x6f\x11\xfa\x30\x07\x5e\xa2\xef\xff\x7e\xfb\xc7"
-  "\x73\xd0\x3f\x36\xb0\xb8\x2c\xe1\x40\x8f\xb2\xae\x4e\xce\x43\xe4"
-  "\x99\xd9\x51\xcd\xf8\x97\x2f\xc9\x7b\x4e\xf7\xfc\x83\x94\xc6\x12"
-  "\x27\xd4\x5d\xcc\xdb\x69\xa5\x9d\x09\x63\x70\x0e\x12\xc6\xcf\x91"
-  "\xa1\xf1\x60\x3b\x7c\x03\xfa\x60\x0d\xe0\xeb\x1c\x99\xbe\x77\x0d"
-  "\xd8\x03\x9d\x18\x0b\x0a\xea\xb3\x9e\xc7\xd0\x14\xf5\xf4\x00\xbc"
-  "\x63\xeb\xa1\xa2\xec\x43\xb4\x43\x87\xe3\x7e\xd7\x7c\xd1\x5a\x9d"
-  "\xe0\xfa\xe6\xfb\x26\xa7\xaa\x5d\xc7\xce\xc7\x2b\x94\x7c\xae\x57"
-  "\xf5\x2a\x9e\xc9\x25\x6d\x8a\x11\x11\x7c\xee\xf7\x2f\xb8\xcf\x71"
-  "\xd4\x19\x85\xf2\x43\x9a\xf3\x56\x6b\x12\xc6\x05\x96\xdf\x65\x40"
-  "\x5d\xf5\x05\xf6\xdb\x32\x49\xa6\x33\xbb\x7d\xbe\x39\xed\x2c\xfa"
-  "\xe9\xf3\x4f\xf6\x2a\x94\x6c\x2f\xb8\xd3\xf0\x7e\x15\xd0\x29\x4a"
-  "\xcc\x79\xbf\x06\x64\x4a\x24\x7d\x0a\xda\xfa\x1b\x68\xeb\x19\xa0"
-  "\xeb\x19\x68\xeb\xb3\x52\x5b\xa5\xf8\x58\x22\xd0\x1f\xde\xf5\xaf"
-  "\xff\xe4\xb6\x3e\x85\xb1\x16\xfe\x64\xda\x74\x96\x5c\x43\xa7\xe1"
-  "\x5a\x2e\x3b\xff\xd8\x69\x76\x9c\x24\xf8\x5d\xa6\x9f\x8d\x4b\xd2"
-  "\x1e\x06\x3c\x22\xcd\xc1\x26\xb0\xd0\x90\xed\xf5\x32\x1f\xb0\x3e"
-  "\xb4\x3b\x61\x4c\xf1\x1a\xa8\x0f\xd2\xfe\x1c\x99\x89\xfd\x19\x68"
-  "\x3f\xbd\x18\xe9\xef\x19\xa3\x36\x8c\xf1\x40\x00\x1e\xac\x91\x78"
-  "\x90\x2d\xf1\x00\x6c\x45\xd0\xd5\x38\xc7\x11\x5e\xac\xe7\x3c\xf0"
-  "\x8f\x46\x23\xd5\xc3\xdc\x5f\x95\xde\xfb\xeb\xe8\x5f\x74\xf1\x31"
-  "\xa4\x02\x7d\x99\xd2\x90\x5d\x73\xc5\x6e\xe8\xb7\x79\x52\xbf\xa5"
-  "\x09\xf7\xca\x7d\xf6\xb4\x62\xe4\x29\xdf\xfa\xec\xa8\xe3\xff\xa2"
-  "\x7d\x36\xec\xd2\xf6\x59\x55\x91\x67\x9f\x55\xd5\x7b\xf6\x59\xd5"
-  "\xf3\xae\x3e\x2b\xbd\x1b\x96\x3e\xab\x2a\xfc\x6e\xfa\xac\xaa\xb0"
-  "\x9f\x3e\xdb\xe2\x43\x9f\x0d\xf7\xd2\x67\xc3\x2f\x5d\x9f\x1d\x6d"
-  "\xba\x7c\x3a\x36\x18\x63\x7d\xf7\xd5\xb1\xcf\xb9\xe9\xd8\x60\xd4"
-  "\xb1\x63\x76\xf7\xd7\x5f\xbb\x0b\xa1\xbf\xaa\xa5\xfe\xfa\xc8\x5b"
-  "\x50\xde\xd8\xdc\x63\x4d\x83\xf7\x57\x47\xa1\xcb\x7e\xf2\xda\x67"
-  "\x13\xb0\xcf\x96\x12\xb3\x85\xf5\xd9\xe5\x72\x9f\x2d\x94\xc6\x3b"
-  "\x03\xf4\xdb\x30\x6f\xfd\x16\xe3\xed\x60\xac\x9d\x01\xfb\xad\x64"
-  "\x2f\x75\x4f\xc1\x7e\x6b\xba\xc2\x74\xad\xfa\x61\xcf\x7e\xab\x36"
-  "\x78\xf6\x5b\xf5\x3d\xae\x7e\x2b\xbd\x1b\x96\x7e\xab\x5e\xfc\xdd"
-  "\xf4\x5b\xf5\xe2\xef\x8f\xae\x0d\x4e\xbb\x7c\xba\x56\xf3\x36\xeb"
-  "\xb7\xde\x74\x6d\x86\xa4\x6b\x83\x51\xd7\x86\xfc\xd2\xb7\xbe\x1b"
-  "\xfa\x8b\x7f\xf1\xbe\x7b\x89\x75\xae\x66\x9c\x67\xdf\xd5\xcc\xf3"
-  "\xec\xbb\xa1\x17\x5d\x7d\x57\x7a\x37\x2c\x7d\x57\xa3\xf9\x6e\xfa"
-  "\xae\x46\xf3\xfd\xd1\xb9\xe3\xbc\xc6\x2f\xd5\x4e\x25\x99\xcd\x8a"
-  "\x71\xb9\xe6\x42\xb6\xdf\x2e\xd3\xec\xf8\x09\x61\x7b\x54\x14\xe3"
-  "\xde\x30\x87\xcf\x26\x62\xce\xe1\x70\x8c\xd5\x81\x7b\x65\x7e\xeb"
-  "\xb6\x17\x85\xad\xe9\x2a\xc6\x1d\x97\xf7\xd2\xec\x95\xe2\x79\x0c"
-  "\xb4\x97\x86\x1a\x0e\x71\x7f\x56\x8a\xf1\x1a\x8e\x8d\x43\xfb\xe5"
-  "\x67\xe6\x57\x46\x31\x3e\x8c\x66\x1f\xda\x67\x1d\x7d\x68\x9f\xb7"
-  "\x75\x92\x90\xcd\x94\xe2\xfe\x91\x8e\xa9\x2b\xa2\x3a\x72\x08\xc9"
-  "\xc7\x35\x88\xac\xf1\x0b\xa0\x8d\x29\x6c\xdf\x44\xc8\x28\x6d\x87"
-  "\x3e\x86\x40\x5a\x9c\x9c\xc6\x62\xdf\xea\x83\xa8\x08\xef\x40\x86"
-  "\xa8\xf7\xa6\x13\x15\xfa\x2a\xbe\xed\x02\x62\x71\x7c\x12\xc8\x08"
-  "\xb6\x37\x84\xad\xe3\x5f\x7b\x9d\xad\xb8\x9d\x28\xeb\xb6\xb2\x3d"
-  "\x72\xb8\x07\xa7\x24\x0f\xf1\x1f\x34\xa3\x80\x0a\x4a\x22\x16\x3d"
-  "\x14\x4e\x83\xf3\xed\x6c\xcf\x30\x60\x45\xde\x97\x83\x71\xbc\xc4"
-  "\x29\x8b\xca\x65\x7f\xb9\x14\xea\xf7\x4e\x3a\x9e\x2d\x0d\xa2\xc5"
-  "\xc9\x44\x03\x97\x9a\xe6\xe6\xdb\xa1\x5e\x76\x79\xfe\xd0\xeb\xfe"
-  "\x6f\x8c\xdf\x79\x5d\xb8\x52\xda\x03\x84\x7e\x06\xd8\x39\xb2\x1d"
-  "\x82\x68\x70\x42\x3a\xd5\x67\x50\x73\x9a\x83\x84\x02\x2d\x70\x0d"
-  "\x1f\xe4\x94\x20\x16\xaf\xc0\xd8\x0e\xe4\xb5\x0d\xad\x02\xee\xe7"
-  "\x70\xfe\xd7\x75\x36\x53\xfa\x9d\xb8\xc6\xcf\xfc\xcc\x9f\x56\x5c"
-  "\x73\x3e\xfa\x6b\x1e\xab\xf3\xb4\x22\x4c\x81\x6b\x0f\x0b\xe1\x19"
-  "\xd7\xc8\xc5\x8e\x70\x25\xe6\x85\x3c\xaf\x9a\x52\x3f\x25\xa1\x49"
-  "\x6c\x5f\xbd\x8a\xe7\xbd\x66\x23\xe6\xb5\x28\xc2\xd8\xfa\x3b\x3c"
-  "\xe7\xe3\x7c\x39\xee\xbd\x67\x67\x34\x0a\x1f\x0a\x67\xf2\xc1\x98"
-  "\x6f\x17\xa7\x3c\xc4\xf7\x88\x42\x3b\x77\x40\x9b\x21\x8f\x1a\xf7"
-  "\xe6\xb0\x7b\x3a\xd1\xec\x86\x34\x2c\x07\xee\x6a\xb6\x3f\x58\x71"
-  "\x4d\x22\x96\xed\xf5\x5c\x81\x3a\xdf\x4e\x01\xdb\xfc\x9c\x8d\xe2"
-  "\xc3\x66\x45\x58\x49\xa8\x82\x52\x5a\xb8\xa8\x7c\x0b\xce\x63\xe3"
-  "\x5e\x6e\xdc\x9f\xae\x08\x5b\x0f\xe5\x2b\x91\x16\x9d\x59\x61\xb1"
-  "\x16\xc5\x35\xca\x9e\xfd\x08\xd3\x58\x7b\xcb\xf0\x3b\xf8\x1f\x29"
-  "\x3f\x8f\xfd\x09\x75\xd6\xa6\x07\x51\x78\xde\xc3\xf7\x7b\xab\x96"
-  "\xc3\xff\x0b\x7a\xf6\x7b\xf3\xff\x01\x96\xc2\xf6\x03\x36\x99\x6f"
-  "\x23\x7c\xf6\xba\xff\x58\xe2\x5b\x6d\x38\x60\xa3\x37\xef\x64\x8c"
-  "\x00\x2e\x64\x8c\x60\x7d\x5f\x4f\xb7\x08\x4c\x1f\x29\x26\xb0\x33"
-  "\x09\x79\xc0\x43\xe7\x4b\xe1\x4a\x36\x37\xdd\x8d\x7c\x69\xc6\x77"
-  "\xdf\x22\x5f\x76\x80\x2e\x90\xf2\x86\xb9\xea\x8f\xcf\x13\x19\x3f"
-  "\x45\xe0\x05\xdb\xdf\xa4\x98\x70\x84\xc5\xf4\x01\x99\x81\xfb\xd2"
-  "\xab\x40\x73\x53\xc4\x2d\x60\xe4\xb5\x64\xbb\x50\x9c\xca\xd3\xdf"
-  "\x69\xb7\x0b\x3b\xce\x10\x94\x2d\x24\xf7\x37\x44\x09\x7a\x48\x89"
-  "\x65\xd2\x88\x45\xe5\xb7\xcb\x7c\xdc\x00\xbc\x4b\x05\xec\x02\xcd"
-  "\x77\x00\xfd\x8a\xbb\xd8\x5a\x4d\x79\xb1\x48\xd4\x22\xe4\xb3\x28"
-  "\x26\x12\x28\x4f\x83\x71\x04\x71\xff\x34\xd0\xf0\x99\xce\xac\x09"
-  "\x4d\x32\x0d\xb1\x4e\xb8\xff\x19\xe3\x09\x5a\x14\x13\x62\x39\x86"
-  "\x26\xe8\xe4\x36\x7b\xa3\x67\xee\x6b\x24\x22\xf7\x36\x32\x5b\x54"
-  "\xb5\xe9\x68\xd0\x75\x25\x38\xdf\xfc\x20\x7a\x1b\x4a\x6a\x25\xd1"
-  "\xcf\x7f\x4e\xcd\x56\x27\x11\x47\xb7\xe9\x70\x1d\xc2\xb9\x65\xc6"
-  "\xf8\xe8\xf5\x40\x2f\xd0\xf7\x19\x76\xa2\x31\xa7\x5b\x79\x4c\x30"
-  "\xf2\x2d\x71\xae\x03\x19\x0e\x72\x1d\x74\xaa\x32\xe3\x5b\x32\x09"
-  "\xe9\x25\x06\x6f\x8f\x05\x9a\xfd\xf9\xe1\x14\x92\xe9\x9f\x1c\x9d"
-  "\xc8\xfc\xb1\xa1\x7d\x01\x32\x5f\x60\xb1\xb2\xad\x60\x9f\xe4\x6e"
-  "\x8f\xf5\xb3\x9c\x2a\x6f\x32\x12\xdb\x2d\xe2\x3c\xb4\xd4\xe6\x68"
-  "\x6c\xb3\xcd\x4e\x70\x2e\xff\xc1\xa7\xd1\xdf\xf1\x79\x22\x66\xb7"
-  "\xe9\xb0\xcd\x60\xeb\x34\xfa\x3d\xa7\xaf\xb8\x36\x6a\xa0\x6f\x53"
-  "\xa0\xb7\xb8\xe5\xba\x12\x51\x9d\xdf\x88\xdf\xc6\x3a\xe0\x99\x9e"
-  "\x07\xcf\x13\x46\x77\xa4\xbf\xd9\xee\x24\x74\xb4\x7b\x1d\x1c\xfe"
-  "\xd6\xc1\x7b\xfb\x6f\x23\x11\xc6\xd7\x38\xdf\x9d\x5b\x24\x1a\x24"
-  "\xe0\x3a\x58\x7e\x63\x5d\x92\x95\x3c\x88\x75\xb0\x9e\x25\x0b\xcf"
-  "\x12\xc6\x7f\xb3\xae\x8d\x38\x83\x66\x8c\xc7\x3d\x07\xc8\xff\x74"
-  "\x07\xf0\xff\x82\x1d\x7d\x24\x59\xcd\x99\x17\x09\xda\x2f\x8e\x0e"
-  "\x9d\xd0\x97\xff\xe1\x7f\x7e\x38\xcd\x5f\xfe\x87\x0f\x13\xff\xc3"
-  "\xaf\x80\xf6\x4f\x0a\xa0\xfd\x93\x86\xa9\xfd\x93\xae\x80\xf6\x4f"
-  "\x0e\xa0\xfd\x93\x87\xa9\xfd\x93\xbd\xb6\x7f\xee\x24\x91\xb2\xbd"
-  "\x28\x21\xdb\x4c\xa8\x03\xb8\xbe\xba\xee\x15\xdc\x77\xc2\xce\x70"
-  "\x49\xcf\x84\x9f\xe9\x52\xf5\x7a\x56\xf7\x7a\xd6\xf4\x7a\x0e\xeb"
-  "\xf5\x1c\xde\xeb\x39\x42\x7e\x06\x3d\x32\xe2\x9c\xe2\xba\x49\x60"
-  "\x97\x66\x5a\x14\xd7\x1d\x90\xde\x4f\x47\x1f\x62\xa0\xd3\xa7\x0f"
-  "\x10\xdb\xf0\xba\x33\x8a\x08\x2d\xa3\xd3\x96\xc9\x3a\xba\x21\x93"
-  "\x88\xc6\x25\x5b\x1f\xdc\x04\xb2\x0b\xf8\x47\xbb\xc3\x47\x82\x8d"
-  "\x70\x2d\xfa\xa9\xc3\x7d\x07\xda\xe4\x77\x69\xb3\x22\x22\x18\xdb"
-  "\x77\x5b\x92\x89\x88\x41\x33\xd8\x7a\xbe\x98\xbb\x64\xab\x35\x68"
-  "\xc6\x64\xba\x67\x57\x5c\x9e\x20\xaa\xf2\xf4\xa2\x76\x93\x95\x5a"
-  "\x17\x7c\x0b\x72\xe8\x3c\xfa\x7e\x07\x1e\xa7\x50\xab\x29\xf9\x2c"
-  "\xd4\x37\xe2\x99\xda\x8d\x50\x36\x7c\x07\xbe\x05\xe3\xb8\x25\xf1"
-  "\x3c\x2e\xf2\x92\xad\x75\xb6\x6a\x82\x71\x67\xa4\x32\x33\x69\xf0"
-  "\x92\x78\x2c\xb3\x5f\xfb\xd4\xb8\xcd\x06\xdf\xfc\xc9\xc3\x3a\x25"
-  "\xa1\x9b\x95\x61\xfe\xf1\x34\xa2\xc0\xab\xdd\x6b\x34\xa4\xf0\x72"
-  "\x55\x81\x94\x6b\x1d\xa0\x5c\xa9\xbe\x9a\x00\xca\x9d\x32\xdf\x7b"
-  "\xb9\xd9\x52\x7d\xb5\x81\x94\x5b\x32\x40\xb9\x52\x7d\xa3\x02\x29"
-  "\xd7\xee\xbd\xdc\x1c\xa9\xbe\x99\x01\x94\x3b\xd5\x7b\xfc\x6f\xc0"
-  "\x43\x60\x58\x98\xea\x35\xfe\x27\x62\x21\x30\x1c\x4c\x1d\xa0\xfd"
-  "\x06\x5b\x60\x18\xb8\x7e\xc1\x40\x18\x08\x8c\xff\xd7\x0f\xc8\xff"
-  "\xc0\x78\x7f\xbd\xf7\x33\xba\xc0\xfb\xc0\xf8\xae\xf5\x8a\x7f\xb4"
-  "\xe5\x81\xf7\x65\x34\x64\x57\x8c\x98\xb7\xa4\x4c\x0c\xd9\xf6\x97"
-  "\x2d\x62\x14\x99\x0b\x32\x2c\xb4\x80\x8c\x8b\x62\xe3\x63\x6d\xd3"
-  "\xa6\x42\x22\xc0\x78\x57\x78\x75\x43\xa3\x60\x76\xcc\x46\x9d\xe3"
-  "\xdc\x97\x6a\x57\xdc\x08\xe9\x95\xa0\xb3\x6c\x60\x77\xf2\x72\x96"
-  "\x94\xe5\xa5\x47\x11\xc9\x4f\x86\x0d\xfd\xa5\x46\x83\x1c\x33\x17"
-  "\xd8\x71\xdf\xca\x38\xf8\x9f\x03\xf0\x0b\x65\xd8\xc9\xeb\xa2\x55"
-  "\x11\x95\xcc\xf2\x59\xd9\x59\xbc\xbc\x6d\x7f\xa1\x19\x3a\xf4\x97"
-  "\x68\x3d\xad\xb8\xe1\xfe\x20\x2b\x11\xd0\xaf\x51\x67\xd6\x0d\x51"
-  "\x16\xc5\xb4\x48\xe9\xec\x69\x1b\xf3\xf3\x09\xf5\xc5\x73\x9d\x98"
-  "\x17\xfd\x7d\xde\x96\x44\x04\xf4\xa1\x0e\x79\x13\xd1\xf7\xe7\x40"
-  "\x67\xb8\x9d\xc6\xfc\xdd\xf8\x7f\x6a\x04\x1d\x7a\x96\x08\x78\x6e"
-  "\x93\x46\x3c\xa4\xc9\x83\x31\xc4\xfd\xb7\xe0\x9c\x47\x3b\x49\xdf"
-  "\x44\x45\x9c\x7f\xa2\xea\xed\xf3\x71\x6f\x1c\xdb\x37\xae\x98\xa6"
-  "\x2a\xe6\xfb\xc8\xed\x2c\xb6\x2c\x3c\xb3\x71\x0c\xee\x8d\x51\x2f"
-  "\x99\x4d\xf3\x82\xa3\xea\x6c\xed\x2c\xe6\x4f\xb3\x62\xda\x68\xf4"
-  "\xb9\xd8\xa1\xce\xcf\xb7\xa9\xf3\x0b\x3a\xb3\xa6\x29\xe5\x36\xe0"
-  "\xf7\xe5\x74\x1c\xb7\x61\x3e\x78\x3f\x5d\x3e\xd3\xdd\xbf\x6f\x84"
-  "\xc9\xe3\xa3\xc3\xa9\xb5\xc7\x97\x86\xe2\xc6\x6c\xa4\x3d\xd8\x0a"
-  "\x06\x5b\x86\x6e\x2a\x9f\xc7\x98\x56\x86\xe3\x61\xa8\x77\x0a\x1f"
-  "\x9b\x2e\x49\x61\x3e\x74\x41\x07\x3c\xac\x13\xfc\xb4\x5b\xa7\x31"
-  "\xfd\x6f\x9a\x8a\x3a\xf2\xc6\xa7\xa1\xfc\x9f\x42\x9b\x1a\xf8\x58"
-  "\x6c\x89\x81\x9d\x65\x54\x4c\x4b\x82\x6f\x18\xe0\x39\x12\xf3\xc1"
-  "\x7b\x9b\xf4\x3e\xdf\xed\x7d\x3e\xee\x95\xe4\xef\x6f\x94\xc6\x72"
-  "\x4b\x76\xbb\xbd\xdf\x9d\x34\x15\xe7\x26\x6e\x9c\x83\x6d\x00\x3a"
-  "\x26\xa1\x6e\xeb\xf1\x0d\x12\xbc\x24\x49\xca\xb7\xb5\x4d\x71\xe3"
-  "\xc3\x1d\x80\x2d\x78\x6f\x74\xfb\xbf\xf1\x70\x5a\x24\x99\x5b\x84"
-  "\x34\xbc\x31\xc1\x22\xe4\x57\xf0\xf1\xec\x34\xde\x76\xf5\x92\x04"
-  "\xf7\xf2\x2c\x8a\x1b\x67\x41\x99\x09\x36\xb0\xa3\x20\xcf\x52\xfc"
-  "\xa6\x3b\xbd\xe5\x13\x95\xda\xf8\xd5\xcb\xb5\x2b\xd6\x3e\xb3\x06"
-  "\x4f\xc4\x79\xc6\xa2\xd7\xe0\x99\x51\xd1\x68\x4c\x33\x17\xe0\x19"
-  "\x36\x0d\x3b\xfb\xbd\x1b\xf7\x4d\x85\xec\x2c\x73\xe6\xed\x8c\x12"
-  "\x43\xb6\xc7\x99\x36\xdc\x47\xce\x29\x6e\x64\xe7\x49\xcd\x60\x21"
-  "\x60\x9c\x6e\xd3\x86\x63\x90\x36\x9d\xf9\xbf\xc2\xd8\x50\x6c\xcc"
-  "\xbe\x41\x45\xaa\xb4\xed\x6c\xdc\x0f\xef\xee\x67\x73\x1c\xe7\x89"
-  "\xe0\xd0\xab\xc8\x5f\xd3\xeb\x85\x0a\xd1\x22\xfc\x55\x6c\x64\xfb"
-  "\x74\x0f\x87\x57\x93\xdb\xd3\x54\x18\x6b\x4f\x78\x17\xc6\xd2\xf8"
-  "\x1e\xdf\xc9\x67\x11\xe0\xff\x2f\xb0\x3d\xbb\xd3\xf8\xef\x8c\x02"
-  "\xfa\xc5\xe1\x70\xc9\x3f\x85\xe2\xc6\xaf\xb1\xae\xe8\xbb\x03\xe8"
-  "\x78\x16\xeb\x07\xb4\x68\x0b\x2a\x64\x7b\x97\xd5\x90\xff\x84\x98"
-  "\x6b\x4c\x43\x79\xe0\xc8\xba\xb1\x84\xea\xd5\x7f\xc4\xf3\x74\x85"
-  "\xd2\x19\xbb\xce\xac\xe9\x55\x6e\x67\x47\xd5\x1d\x02\xf9\x19\xa4"
-  "\x35\xca\x67\x1b\x30\x56\x99\x37\xf9\x62\x07\x1b\xef\x62\xc4\xa2"
-  "\x02\x51\x6d\x04\x5e\x18\xd3\xaa\xe7\x11\x9c\x77\x51\xe0\x9e\xd9"
-  "\x36\xc5\xcd\xf5\x34\xd8\x98\x90\x8e\x7d\x3a\x6f\x7b\xdc\x9f\x70"
-  "\xdf\x1f\xd0\x71\x3f\xee\xf3\x03\x5a\xbe\x02\xcf\xc7\xe6\x97\x12"
-  "\xed\x22\xb4\x9d\x6e\xfa\xc5\x7f\xc4\x53\xc7\x8c\x18\x13\xa9\x69"
-  "\xf9\x0b\xf9\xa0\xa1\x9a\xa8\x97\x92\xa0\x0c\x0b\x75\xb2\x36\xa6"
-  "\x10\x21\xda\x42\x82\xd2\xcf\x63\x9f\x76\xb2\x58\xe1\x75\xf6\x5a"
-  "\xb0\x87\x9e\xdc\xfa\x6a\x7a\xeb\x08\xed\x83\x84\x40\xdf\x63\x6b"
-  "\xcc\xec\x9c\x8f\x95\x9d\x87\x0e\xc6\xf9\x6e\xb7\xf3\x3d\x99\x1b"
-  "\xe3\xa8\xb8\xe9\x2c\x51\xd5\x26\x9c\x24\xd1\x71\x41\x94\x9d\xef"
-  "\x49\x83\x8c\x56\xe0\xfd\xb3\xba\x10\xe7\xb3\xba\xf1\x7b\x2e\x90"
-  "\xb0\xba\x14\x0b\xd8\x66\xd5\xe4\xa5\x64\x12\x46\x3b\x13\x46\xd7"
-  "\x54\x1f\x23\x34\xe7\x9c\xf6\xf5\x74\xd3\x08\xa7\x8a\xef\xaf\x0a"
-  "\xdd\xac\xc0\xf9\xcd\x10\x23\xee\xb3\xba\x40\x22\x97\x9d\xca\x64"
-  "\x73\xb2\x38\xff\xed\xe8\xd4\x69\xbb\x3b\x75\xd3\xba\x9e\xd5\x4d"
-  "\x95\xe7\xcd\x1f\x3b\xab\xc1\x75\x82\x58\x9a\x75\xad\x01\xf7\xf6"
-  "\xe1\x38\xc0\x31\xba\x5d\x87\x73\xe4\x88\x61\xf8\x7e\x84\xb8\x42"
-  "\x47\x6e\xb7\xb2\xb3\x47\x38\x6f\xaf\x29\x7e\x02\xeb\xda\x4e\xd8"
-  "\x5e\xa1\xd1\x7c\xaf\x90\x1d\xd7\xac\xd5\xf9\xad\x0b\x57\x69\x49"
-  "\xd7\x94\x45\x05\xe6\xb4\x3f\x91\x8c\x8b\xf4\x0b\x66\xc7\xa7\x01"
-  "\x6e\xb3\xa6\x5b\x69\x70\x7e\xeb\x11\xdd\x71\xd4\x27\xb3\xfc\x97"
-  "\x0f\x37\xb3\xf5\x5f\xa4\x0d\xf0\xa9\x6c\x7f\x3b\xf2\x6d\x7b\xdc"
-  "\xff\x26\x5b\x85\x07\x5a\xa8\xa3\x36\xfe\x4f\xe4\x83\xc6\x7a\x0f"
-  "\xfe\x30\x7e\x42\x3e\xe4\x13\xf2\x08\x79\xe5\xe2\xd3\x71\xc6\xa7"
-  "\xfd\x22\xe7\x53\x97\x7a\x5b\x99\xcc\x2b\x7b\xe1\xa2\x52\x5f\xf8"
-  "\x55\xd3\xd2\x3f\xbf\x80\xce\x3d\xfc\x7a\xb1\x9d\x84\x99\xdb\xc0"
-  "\x5e\x06\x7e\x3d\xf0\x4b\x42\x1e\x78\x85\x8a\xb5\xf3\x3f\xea\xe1"
-  "\x9b\xc3\xe0\x85\x6f\x5f\xbb\xf8\x06\xfc\x1f\x80\x6f\xe1\x6a\x7f"
-  "\xf8\x56\xd3\xc2\xf9\xe6\x90\xf6\x78\xe9\xaa\x88\x60\x7f\x56\x27"
-  "\x14\x5c\x20\xb3\x91\x7f\x0b\x4e\x69\xc9\x91\xc5\xb5\xc0\xb3\xbf"
-  "\x78\xf0\x4f\xcc\xcd\x37\x00\x0f\x0a\x90\x87\x81\xf5\xbb\x19\xf3"
-  "\x7d\xef\x77\xba\xca\xab\xfd\x6e\xb8\xfa\x9d\x2e\x61\x68\xfd\x6e"
-  "\x46\xd8\xd5\x7e\xf7\x5d\xf7\xbb\x19\x9a\xde\xfd\xae\xc7\x6e\x48"
-  "\x5e\xb9\x7a\xf9\xaa\x35\x78\x3c\xf1\x89\xf5\x29\x2b\xd7\x71\xeb"
-  "\xc1\xc3\x7e\x08\x77\xa6\x47\x09\xe8\x53\xae\xa6\xa0\x9e\xbc\x3e"
-  "\xb9\x5e\x70\x7e\x15\xae\xa4\x46\x65\x92\x68\x1c\x69\x47\xdf\xa0"
-  "\xd8\x3f\x31\xb6\xfd\x69\x45\x64\x4d\x5d\x04\x8f\xab\x89\xbf\x99"
-  "\xed\x14\xf1\x90\x0e\xd7\x6b\xb6\x74\xc1\xb5\x81\x28\x43\xed\x44"
-  "\x65\x9a\xca\xde\xdf\x82\xbe\x12\x69\xd1\x43\xba\x62\x8c\x39\xdf"
-  "\x45\x94\x36\xf5\x92\xc8\xad\x50\x9e\x35\xd8\x98\xa6\xd4\x12\xa1"
-  "\x33\x6b\x26\xd4\xfd\xc6\xf2\x1e\x1f\x4a\x8a\xdb\xdb\xe8\xc8\x1f"
-  "\x36\xa2\x6c\xc0\x73\x72\xe7\x14\x33\xdf\xbe\x88\xeb\x1d\x60\x53"
-  "\x3f\x7c\x0b\x7c\x6b\xca\xa2\x52\xe6\x53\x01\xe4\x04\x7f\x7f\x1b"
-  "\x8b\xb7\x7d\xd1\xb8\x3d\x0e\x6d\x8e\x0e\xf5\xce\xb2\x0e\xe3\xce"
-  "\xa8\x63\x1b\x0b\x24\x39\x31\xf3\xeb\x07\x0a\xb8\x9c\xa8\x0d\x07"
-  "\x1c\x2e\x00\x1c\xc6\x0e\x26\x27\xdc\xf0\x37\xd5\x3f\x39\x81\x78"
-  "\x43\xdc\x21\xe6\xc6\x02\xe6\x10\x87\x32\xee\x7e\x2b\xe1\x2e\xb4"
-  "\x89\x68\x18\xf6\x1c\x1c\x7b\x78\xa6\xb9\x36\xcd\x85\x3b\x67\x6f"
-  "\xdc\x5d\xe8\x85\x3b\x41\xc2\xdd\xb3\x9e\xb8\x7b\xf4\xa4\x86\xbc"
-  "\xc4\xe5\x85\x0b\x77\xd9\xed\x3a\x19\x73\x88\x3f\xc4\x9a\xf8\x6b"
-  "\x1d\xa9\x6d\x6b\xef\xc1\x5f\xf1\x93\x7c\xcd\x95\xed\xe9\x15\x68"
-  "\xd9\xc5\x67\x25\x79\x71\x56\x96\x17\x2f\x7a\xd1\xd3\x27\x03\x94"
-  "\x17\xb7\xb1\xf5\x67\xe4\x55\x17\xf0\x0d\xf9\xf5\x40\x38\xc8\x89"
-  "\xf0\xff\x26\x1f\x2c\xbe\x42\xf8\x93\x3c\x3c\xfc\x41\x7f\xb7\x50"
-  "\x97\x7e\x78\x34\x31\x6c\x30\x1e\x21\x7f\x90\x4f\x8c\x3f\xc0\x27"
-  "\x79\x5d\x1c\xd7\x49\x91\x57\xc8\x9f\xdb\x36\x12\x01\xf9\x55\x9c"
-  "\xca\x65\x04\xca\x02\xb6\x0f\xbb\x97\x8c\x07\x9a\x47\x21\xcf\xd8"
-  "\xd8\x5a\x1f\xbc\x66\x37\x9e\x23\x1e\x2f\xdb\xd1\x91\xea\xbe\x76"
-  "\x74\xa4\xb6\xc7\xf7\xa5\x62\x26\xf3\x1d\x65\x9a\xfc\x13\xe8\x9f"
-  "\x33\xe3\xf8\x78\xc9\xa8\xe3\x36\xfc\x1d\x9b\x24\x19\xa0\xc1\xb1"
-  "\x2b\x1b\xa7\x3a\x61\x9c\xaa\x86\x71\xaa\x11\xc6\xa9\x69\xad\xdc"
-  "\x4f\x82\x22\x72\x3d\x91\xce\x37\xd3\xe0\xed\xf3\x61\x8c\x34\x1b"
-  "\xe9\xca\xd6\x7c\x83\xf3\x31\x3e\x5f\x1b\xcd\x85\x31\xf0\x7f\x0b"
-  "\x04\x9e\x0b\x8e\xe8\x9c\x7e\x62\x2a\xb2\x40\x5a\xd3\xde\x97\xb4"
-  "\x01\xf7\x3b\xdc\xc1\x7d\x0b\x2a\x66\x32\xff\xd2\x6c\x3d\x50\x10"
-  "\x4b\x9c\x5b\x3c\xd7\x03\xdd\xd7\x8b\x5f\x4f\xb7\x4a\x6b\x81\x77"
-  "\xb0\x78\x93\x28\x4f\x50\x0e\xbe\x0a\x63\x1a\xd7\x7a\xe0\x47\xf8"
-  "\xfe\x97\x9e\xeb\x81\x77\x4c\xc7\xfc\x16\xc5\x1d\x1b\x71\x0f\x0c"
-  "\x3c\xcf\xe6\xe9\x33\xa3\xdc\xd3\x5d\xeb\xed\x3c\x5d\x14\x58\xfc"
-  "\x15\x9c\x2f\x68\xe3\xf3\x04\x77\xec\x96\xc7\xe3\x5e\xec\x27\x3f"
-  "\xe4\xf4\xdd\x06\x97\x9c\xbe\x9b\xef\xd5\x0a\xdf\x15\x5b\xdb\x47"
-  "\x4e\x7f\x0a\xef\xef\x3a\xf5\x20\xca\x69\xe3\xf6\x18\x5e\xbf\x3b"
-  "\x6f\x00\x9a\x04\x61\xfc\x4b\x4c\xc7\xf3\x47\x28\xaf\x8b\xf0\x6c"
-  "\x0e\x93\xe1\xbb\xe6\x6f\x65\xeb\xfe\x77\xce\xf3\x94\xdd\x77\x95"
-  "\x7a\xca\xee\x3b\xd7\x0f\x2c\xbb\x67\xdd\x35\xb0\xec\xbe\xf3\x0f"
-  "\x57\x65\xf7\x70\xcb\x6e\xd9\xd6\x0b\x54\x76\xcf\x22\x57\x65\xf7"
-  "\xe5\x96\xdd\x3f\x72\xb8\xc9\xee\x5f\x79\xca\xee\xbb\xaa\xfb\xca"
-  "\xee\xbb\x9a\x5c\xb2\xfb\xce\x18\x97\xec\xbe\x53\xe5\x29\xbb\x7f"
-  "\xfc\x6f\xbe\xc9\xee\xbb\xef\xba\xb4\xb2\xfb\xee\xc5\x9e\xb2\xfb"
-  "\xc7\xd3\x25\xdd\xf2\xb5\xff\xb2\xfb\xc7\x23\x06\x96\xdd\x3f\x0e"
-  "\xf6\x94\xdd\x77\x5b\xb8\x8c\xfe\xf1\x6c\x2e\xbb\xef\xb6\x49\x32"
-  "\xbd\xd5\x3d\xdd\x25\xbb\x79\x7a\x5f\xd9\xfd\xe3\x98\x41\x64\xb7"
-  "\xce\x29\xca\xb2\xbb\x11\x64\x77\xa3\x20\xfe\xda\x9b\xec\x9e\x53"
-  "\x56\x8b\xb2\x3b\x19\x65\xf7\x9c\xb2\x81\x65\xf7\x9c\x22\x94\xd1"
-  "\x80\x63\x52\x88\x7e\x91\x01\x97\xa6\x27\x3f\xc5\xf9\xeb\x16\xc4"
-  "\xed\x69\xc5\x4f\xcf\x3f\xb8\xd1\x5d\xb6\xff\xd8\xd9\x23\xdb\x21"
-  "\x5d\x9c\xe4\x29\xdb\x51\xae\xa3\x7c\x2f\xfa\x1d\xb5\x14\xff\x8e"
-  "\x36\x75\x66\xcd\xd6\xc9\x32\x3e\x17\xd2\x30\x66\x12\xfa\x3b\x2a"
-  "\xba\xc0\x2e\x25\xd0\xa0\x65\x0b\x7c\x17\xff\x03\x79\x17\x7b\xea"
-  "\x83\x9f\x96\x3b\xb2\xdc\xf5\xc1\xec\x6c\xd4\x07\x46\x7e\x46\x9d"
-  "\xe9\x01\x47\xd1\xa2\x52\xd4\x0d\xfc\xfd\x4f\xee\x1f\x58\x1f\xcc"
-  "\x7e\xe3\xbb\xd2\x07\x28\x6b\xc6\xba\x8d\x21\xbd\xe9\x03\x9c\x53"
-  "\xad\x8d\xbf\x3c\xfa\x00\xe5\x0c\xca\x17\x94\x35\x28\x77\x50\xce"
-  "\xa0\xcc\x71\x48\xe7\xf3\x0a\xf5\x3e\xe8\x03\x90\x2b\x74\xa4\x2e"
-  "\x81\xe9\x03\x45\x20\xfa\xe0\x27\x9a\xef\x95\x3e\x40\xfe\x6c\xbc"
-  "\xb4\xfa\x40\x1e\xe7\x23\x7f\x90\x57\x32\x8f\xe4\xb1\x3e\xf2\x07"
-  "\xf9\x84\xfc\x41\xdb\x48\xd6\x07\xb7\xa6\x71\x7d\x50\x34\xa8\x3e"
-  "\xf8\x89\xba\x47\x1f\x08\x5c\x1f\xb0\x39\xf1\xf1\xa8\x0f\x7e\xda"
-  "\xd8\x57\x1f\xfc\xb4\xcd\xa5\x0f\x66\xc7\x49\xf2\xb1\x05\x7d\x2f"
-  "\x80\x3c\x68\xf1\xd4\x09\xf7\x2c\xf7\x4d\x27\xcc\xf9\x45\x1f\x9d"
-  "\x00\xb4\x35\xf2\x75\x33\xd4\x07\xf9\xa8\x0f\x1c\xa8\x17\x02\xd2"
-  "\x09\x73\x12\x5c\x7a\xeb\xc7\x55\x5c\x16\xcf\x51\x7a\xea\x89\x7b"
-  "\x16\x48\x32\xed\x0f\xee\x7a\x42\x0c\xf2\x45\x4f\xdc\x73\xab\xac"
-  "\x27\x50\x0e\xbf\x8a\x6b\x16\x3d\x7a\x02\xe5\xea\x3d\x77\x99\x52"
-  "\x9b\xdd\xf4\xc4\x3d\x3c\xb6\xa8\xe2\x9e\x38\x27\xd3\x13\xf7\x44"
-  "\x48\xfa\x66\x9f\x7b\xba\x4b\x4f\xf0\x74\xa7\xbb\x9e\x68\x45\x3d"
-  "\x71\x4f\xda\x20\x7a\x62\x96\xef\x7a\x62\x6e\x8c\x4b\x4f\xcc\x8d"
-  "\x19\x58\x4f\xcc\xbd\x07\xf5\x04\xf3\xb7\x0b\xbc\x07\x9c\x2b\xf3"
-  "\x26\x72\x1d\x81\x73\x34\xa0\x3b\x2c\xe8\xf3\x03\xf2\xdd\xc2\xfc"
-  "\xeb\xc3\x05\xef\x5b\x8d\xf8\x5b\x64\xff\x69\x0a\xb5\x12\x15\xea"
-  "\x0c\xe3\x69\xa2\xc4\x58\x75\x9c\x4e\xf7\x3d\x5f\x88\xf1\x4f\x7b"
-  "\xf4\xcb\xbd\x8f\xf9\xa8\x5f\x1a\x40\xbf\xd4\x77\x66\xdd\x6b\x70"
-  "\xd3\x2f\x18\xef\xaf\xbe\x97\x7e\xb1\x80\x7e\x69\x91\xff\x03\xf9"
-  "\xcb\xdd\xf3\x63\xfd\x58\xfe\xd3\xec\xc2\xfc\x8d\x90\xbf\x89\xeb"
-  "\xa3\x7b\x5b\x3c\xf5\xd1\x7d\xf3\x45\x8f\xf1\xc9\xcf\x26\xc9\xfa"
-  "\x08\xf5\xb9\xd8\x47\x1f\x45\x1d\xef\xd1\x47\x13\xdd\xf4\x51\x9a"
-  "\xac\x8f\x7e\x76\xff\x15\x3f\x3e\x19\x82\xbc\xbb\xd4\xfa\x48\x04"
-  "\xbd\xd3\x5b\x1f\xa1\x8e\x92\xc7\x27\x62\x40\xfa\x28\xaa\xe4\x7b"
-  "\xa5\x8f\x2e\xc3\xf8\xa4\x37\x6f\x64\x9e\x21\x7f\x90\x37\xc8\x17"
-  "\xf4\xf9\x8d\x3c\x43\x7e\x21\xaf\x6e\x4d\xf2\xd4\x45\x8c\x5f\xa0"
-  "\x8f\xfa\xac\x1d\x00\xaf\x80\xe6\x85\xc8\x2f\x77\x7d\x54\x3c\x5e"
-  "\xd6\x47\xf7\x25\xf4\xd5\x47\xf7\x6d\x74\xe9\xa3\x7b\xd9\xfe\x2a"
-  "\xe6\xff\x50\x71\xef\x3c\x4f\x5d\x34\x4f\xe1\x9b\x2e\xba\xef\x78"
-  "\x3f\xba\x88\xf9\x99\x36\xfe\xce\x63\x6c\x92\x0f\xfa\x28\x00\x5d"
-  "\x74\x9f\x8d\xd7\x11\xf7\x82\xdf\x1b\xc6\xe5\xfd\x7d\xf9\x2e\xfd"
-  "\x74\x4f\x9b\x7b\x9a\x4b\x3f\xcd\x6d\x93\x74\x6a\xad\xff\xfa\x69"
-  "\x2e\xfb\x0f\xee\x13\x7f\xb5\x9d\xeb\x00\x4f\xfd\x34\xf7\xb8\xa7"
-  "\x7e\x9a\xcb\xfd\x2a\x29\xe6\x11\xae\x9f\xe6\x56\x48\x7a\xab\xc6"
-  "\x3d\xdd\xa5\x9f\x78\x7a\x5f\xfd\x34\x2f\x7c\x10\xfd\xa4\xee\x2e"
-  "\x5c\x54\xda\x65\xdc\x99\xef\xd8\xb7\x22\x6a\xe6\xd2\xeb\x9d\xbd"
-  "\xfb\x13\xef\x47\x4e\x82\xfd\xaa\x67\xbd\xed\x3f\x09\xe9\x56\x6f"
-  "\x2b\x13\xa5\xf3\xd4\x5d\x11\x8b\x0a\x4e\x27\x42\x9f\x6a\xf3\xde"
-  "\xa7\xa0\x3f\xa9\xe4\xfe\x54\x9b\x70\x8a\x40\x1f\x13\x70\xbd\xed"
-  "\x45\xe8\x4b\x66\x5b\x23\xeb\x5b\xea\x16\x2d\x41\xdf\x96\xc1\x6d"
-  "\x44\x13\xac\x50\x8c\xfc\x8f\x5f\x41\x9f\x85\x7e\x75\xff\x2d\x54"
-  "\x9c\xd1\xa4\x25\xc1\x09\x24\x04\xfb\xd6\x6b\xd2\x7a\x0e\xfa\xc2"
-  "\xc0\x75\x1c\xc0\x75\xe4\xb2\x0f\x79\x9f\x7a\x11\xae\x2e\xde\xa7"
-  "\xa6\x76\x75\xea\xa6\x79\x5b\xc7\x31\xa7\x59\xd8\x3a\x0e\x9e\x55"
-  "\xc2\x33\x62\x22\xf6\x21\x5c\xc7\xb1\x73\xdb\x0e\xea\xab\xd9\xcb"
-  "\xd6\x71\x9a\x3d\xd6\x71\x7e\xd8\x44\x04\xf4\x93\xf1\x92\xfb\x3a"
-  "\x8e\xae\xb6\x8f\x5d\x87\xfd\x0b\xfb\x93\xff\x32\xef\xfe\xdd\x03"
-  "\xed\xa5\x72\x00\xad\x9d\xea\x9d\xf9\xf4\xc5\x5d\x99\xff\xdb\x6c"
-  "\x57\xa0\x4f\x51\x27\xf0\x4e\x04\xd9\x46\x55\xbd\x64\x5b\xb7\xc4"
-  "\x87\x6e\xce\x07\xe0\xa1\xea\x71\x1b\xa1\xcb\x1c\xd0\x7f\xba\x25"
-  "\xbf\xa2\x76\x0b\xe0\x50\x37\xbe\x68\x03\xd2\x3d\x9c\x14\x49\xbe"
-  "\x45\xc5\xe7\x12\x46\x8b\x40\x6b\xaa\x17\xc8\xab\x17\xec\x6c\xdd"
-  "\xd3\xd8\x45\x66\x82\x2c\x0b\x46\x59\x06\xd8\x1d\xb3\xb7\x0b\xe8"
-  "\xfe\x05\xa7\x3b\xfa\x7b\xc3\xbb\xe3\x39\x9d\x16\xca\x9e\xd6\xdd"
-  "\x0d\xb2\xcc\xce\x69\xff\xf8\xd3\x1a\xc2\xfc\x91\xe2\xda\x27\xd8"
-  "\x0d\x75\xc0\x6f\x26\xcb\x6c\xa1\x14\xe3\x81\x88\x5f\xe9\xd0\xf7"
-  "\x55\xc4\xed\x36\xa0\x7d\xb7\x0e\xb1\xa1\x29\x3e\x8d\x6b\x9f\x9f"
-  "\x7a\xac\x7d\x5a\x9f\x73\xad\x7d\xd6\x95\x1e\xe7\x7b\x55\x3c\xe6"
-  "\xc3\xe6\xcd\xec\x2e\xe2\x3a\x87\xcd\x87\xa5\xf8\x4b\xfb\x7f\xd7"
-  "\x7c\x77\xb4\xd7\x7c\xcf\x69\x7f\x7f\xd3\xd0\x68\x3f\xdf\xab\xaf"
-  "\xf8\x4b\x4f\x7b\xd5\xf7\x9c\xf6\xff\x1e\x3b\x34\xda\x3f\xe0\xd5"
-  "\xff\x11\xd2\x1e\xc7\x30\xf2\xf8\x45\x1e\xbb\xa0\x0e\xe3\xfa\x7a"
-  "\x41\xa1\x6b\xdc\xb2\xa0\x50\x5e\x43\x06\x9a\x29\x73\xd1\x77\x37"
-  "\xd0\x22\xe9\x49\x72\xfd\x19\xc5\x82\x71\xf2\xfa\x71\x3e\xc6\x90"
-  "\x41\x3e\xbe\x08\x7c\x5c\x83\x67\x8d\x24\x1e\x82\xce\x59\x66\x03"
-  "\xbd\x30\x65\x51\xa9\x33\x17\x74\xd2\x1f\x56\x44\x79\xe1\xa7\x80"
-  "\xfa\x24\x38\x85\x68\x1e\x4f\x72\xf1\x55\x7c\x0e\xf8\xd9\x05\xb6"
-  "\x99\xbd\x95\xe0\xf9\xe1\xd0\x56\xb0\x5b\xbb\x13\x46\x2f\x85\x31"
-  "\x80\xcc\xd3\xd7\x52\xed\xcc\x2e\xeb\x97\xa7\x7b\x3c\x79\xda\xd1"
-  "\x0f\x4f\x1f\x5b\x05\xfd\x54\x90\x6c\x67\xc6\x53\x4b\x0f\x4f\x99"
-  "\x1e\x79\x4e\x17\x81\x7c\x95\x79\x8a\x7a\x84\xf1\xb4\x8d\xeb\x91"
-  "\x1e\x5f\x4b\xcf\xb9\x6c\xe7\x9a\xb8\x93\xfd\xf0\x74\x7e\x83\x07"
-  "\x4f\xe3\xfc\xe5\xe9\x7f\x34\x79\xda\x5f\x0b\x7f\xe1\x9b\xfd\xb5"
-  "\xe0\x57\x68\x5f\xb9\xdb\x5f\xf8\xdc\x01\xf6\x96\x33\x38\x7f\xb7"
-  "\x2d\xa0\xf1\xff\x82\x04\x4f\x5b\x6a\xe1\x2c\x5e\xa7\x07\x9e\xf7"
-  "\xdf\x96\x5a\xc8\xe2\x2f\xbe\xfa\x62\x7f\x76\xd4\xc2\x29\x9e\x76"
-  "\xd4\x02\x2b\xb7\x97\x16\xce\xef\xd0\xa3\x1d\xb5\x50\xc9\xd3\x1f"
-  "\xd8\xea\x9e\xee\xb2\xa3\x78\x7a\x07\xfa\x9f\xcb\x5a\xb8\xd8\x3f"
-  "\xdb\xe9\xda\xef\xd8\x76\x0a\x1f\xc0\x76\x0a\xff\x17\xb1\x9d\x1e"
-  "\xac\xbf\xaa\xbf\x03\xd5\x21\x0b\x13\x86\xa6\x43\x62\xbc\x9e\x7f"
-  "\xb8\xaa\xbf\x07\xa3\x7d\x74\xf8\xd0\x68\xff\xcb\xea\xc0\xf5\xf7"
-  "\xe2\xa5\x2e\xfd\xbd\x78\xa9\x77\xfd\xfd\xd0\x87\x57\xf5\xb7\x3f"
-  "\xfa\x3b\x66\xf7\xd0\xf4\xf7\x43\x85\x9e\xfa\xfb\xe1\xd1\xbe\xe9"
-  "\xef\xc5\x93\x86\x5f\x7f\x2f\xd6\x79\xea\xef\xc5\x3c\x36\x81\x62"
-  "\xd1\xfd\xfe\xeb\xef\xc5\xc7\xbd\xeb\xef\xc5\x27\x3d\xf5\xf7\xe2"
-  "\x32\xae\xa7\x1f\x56\x71\xfd\xbd\xb8\x8a\xa7\x2f\x9a\xe7\x9e\xee"
-  "\xd2\xdf\x3c\x9d\xeb\xef\x87\xc3\xfc\xd3\xdf\xa1\xdf\xb1\xfe\xd6"
-  "\x0c\xa0\xbf\x35\xff\x22\xfa\xfb\x3f\xf3\xaf\xea\x90\x40\x75\xc8"
-  "\xc3\xba\xa1\xe9\x90\x58\xaf\xfe\x1f\x07\xd7\x21\x8f\x94\xb8\x74"
-  "\xc8\x23\x25\xde\x75\xc8\x23\x13\xae\xea\x10\x7f\x74\xc8\x7f\x36"
-  "\x0e\x4d\x87\xfc\xca\xe2\xa9\x43\x1e\x5d\xe8\x9b\x0e\x79\xe4\xb1"
-  "\xe1\xd7\x21\x8f\x24\x7a\xea\x90\x47\x67\xf3\x3a\xc5\x66\xfb\xaf"
-  "\x43\x1e\x9d\xe4\x5d\x87\x3c\x7a\x83\xa7\x0e\x79\xc4\xc6\x75\xc5"
-  "\xa3\x0b\xb8\x0e\x79\x54\x4a\x8f\x35\xb8\xa7\xbb\x74\x08\x4f\xe7"
-  "\x3a\xe4\xd1\x58\xff\x74\xc8\xa8\xef\x58\x87\xa8\x06\xd0\x21\xaa"
-  "\x7f\x11\x1d\xb2\xb4\x21\x70\x39\xb6\x2c\xc1\x25\xc7\x96\x25\x78"
-  "\x97\x63\x8f\x9f\xbc\x2a\xc7\xfc\x91\x63\x8f\x26\x0e\x4d\x8e\x3d"
-  "\x5e\xea\x29\xc7\xe2\x26\xf8\x26\xc7\x96\xdd\x34\xfc\x72\x6c\xd9"
-  "\x2c\x4f\x39\x16\x27\x9d\x7f\x7d\xec\x97\xfe\xcb\xb1\x65\x5f\x78"
-  "\x97\x63\xcb\xbe\xf6\x94\x63\xcb\x2a\xb8\xbc\x8a\x0b\xe3\x72\x6c"
-  "\x59\x3d\x4f\x7f\x2c\xc6\x3d\xdd\x25\xc7\x78\x3a\x97\x63\x71\xda"
-  "\xc1\xe4\x18\xf6\x8b\xda\xf0\x5e\xfd\xe2\x29\xb9\x5f\x3c\x91\xff"
-  "\x41\xa1\xdc\x2f\x9e\x60\x36\x9a\x58\xf8\x90\x6e\x7b\x2a\x51\x1a"
-  "\x31\x76\x0c\xc8\x88\xa4\x47\xb0\x5f\x3c\x31\x02\xf7\x89\xa8\x9b"
-  "\x40\xee\xb5\x48\x72\x30\x0d\xe4\x60\x0b\x3c\xa3\x5f\xb5\x29\x0f"
-  "\xe9\x50\x7e\x61\x4c\x0d\x7c\xe6\xf2\xd0\x3a\x02\x63\xd7\xb0\xb5"
-  "\x79\xb7\x7e\xc3\xfa\x4a\x87\xd4\x57\x3a\x78\x5f\x91\xcf\xee\x6d"
-  "\x6c\xa1\xa2\x73\x9d\x6e\x7c\x74\x7c\x10\xc5\xfe\xc3\xce\x84\x41"
-  "\xff\xa1\xeb\x74\x21\x85\xc9\xd0\x67\xac\xad\x04\x7d\xe7\x63\x9f"
-  "\x09\xde\xac\x08\xa1\x1d\x09\xa3\x41\x26\x72\xd9\x27\x56\x8f\x70"
-  "\xa0\x1f\xac\x75\x20\xfb\xda\x41\xf6\xb5\xbb\xfa\x0a\xae\xb7\x77"
-  "\xac\xd3\x69\x6d\xeb\x74\x53\xbb\x3b\x40\xf6\x59\x7b\xf7\x93\x89"
-  "\x61\x7b\xdb\x51\xf6\xb5\xb2\x7e\xc2\x64\x1f\xf4\x0d\xb1\x03\x64"
-  "\xdf\xaf\x25\xd9\xd7\xa1\x43\x59\xaf\xd9\xfb\x24\xc8\xbe\xb8\x33"
-  "\x5c\xf6\x49\x36\xdc\x8d\x28\xfb\xd6\xe9\x84\xdf\xb6\x4b\xb2\x6f"
-  "\x39\xca\xbe\x23\xd0\x47\xde\xf2\x94\x7d\xc1\x81\xca\xbe\xe5\xf5"
-  "\x9e\xfd\x64\xc5\x3d\xbe\xf5\x93\x27\x16\x7a\xeb\x27\xdd\xb9\x81"
-  "\xf6\x93\x27\x96\x7a\xf6\x93\x15\x72\xdf\x5d\xe5\x7f\x3f\x59\x31"
-  "\xba\xa7\x9f\x3c\xd5\xbb\x9f\xac\x18\xe7\xd9\x4f\x9e\xe0\xb1\xe2"
-  "\x15\x2b\xe6\xf0\x7e\xf2\x84\x9d\xa7\xc7\x25\xb8\xa7\xbb\xfa\x09"
-  "\x4f\xe7\xfd\x64\xc5\xfc\xab\xeb\xe5\xdf\x37\x7d\x1f\xef\xd5\xff"
-  "\xd3\xd5\xf5\xf2\xc1\xc6\x8c\x2b\x96\x0e\x6d\xcc\xf8\x64\xd4\xd5"
-  "\xf9\xf6\x40\x69\xbf\x52\x3d\x34\xda\xff\xda\x6b\xfc\x9f\xab\x73"
-  "\x25\x83\xd1\xfe\x49\xc3\xd0\x68\xbf\x6a\xf6\x60\x63\x0c\xef\xb6"
-  "\xd4\x53\x2d\x35\x3d\x63\x8c\xa7\x5a\xe4\x7d\xbe\x7d\xc7\x18\x4f"
-  "\xfd\xca\xf3\x1c\xdf\xaa\xaf\x7b\x9f\xe3\x1b\x6c\xec\xe1\xb8\x3a"
-  "\xf6\x00\x5e\x27\x28\x87\x36\xf6\x78\x6a\xba\xa7\x4d\x95\xb8\xd3"
-  "\x37\x9b\xea\xa9\x97\xbd\xd9\x54\x8e\x80\xc7\x1e\x4f\x95\x79\xda"
-  "\x54\x89\x1b\x25\x6c\xbc\xe1\xbf\x4d\x95\xf8\x98\x77\x9b\x2a\x71"
-  "\xa5\xa7\x4d\x95\x38\x9b\xdb\x4e\x89\xf9\xdc\xa6\x4a\x5c\xc0\xd3"
-  "\x57\x1d\x70\x4f\x77\xd9\x54\x3c\x9d\xdb\x54\x89\x85\x57\xd7\xd1"
-  "\xbf\x6f\x36\xd5\x9a\xf0\xab\x7a\x3d\x50\xdd\x92\x58\x36\x34\xdd"
-  "\xb2\xf6\x3b\xdc\xff\xf9\x7d\xd7\xeb\x6b\xe2\x86\x46\xfb\xa7\x07"
-  "\xdc\xff\x39\xb0\x5e\x5f\x57\xe1\xd2\xeb\xeb\x2a\xbc\xeb\xf5\x75"
-  "\x77\x78\xea\xf5\xa7\x2b\xaf\xea\xf5\x40\xf4\xfa\xda\xa6\xa1\xe9"
-  "\xf5\x64\x87\xa7\x5e\x4f\x59\xe5\x9b\x5e\x5f\xb7\x7e\xf8\xf5\xfa"
-  "\x3a\x83\xa7\x5e\x4f\x59\x2c\x61\x23\xd7\x7f\xbd\x9e\x72\x97\x77"
-  "\xbd\x9e\x72\x8f\xa7\x5e\x4f\xd1\x70\xfd\x9d\x92\xc0\xf5\x7a\xca"
-  "\x74\x9e\xfe\xb4\xd1\x3d\xdd\xa5\xd7\x79\x3a\xd7\xeb\x29\x29\x57"
-  "\xd7\xd7\xbf\x6f\x7a\xfd\x19\xaf\xfe\x8f\xaf\xea\x96\xc1\x74\x4b"
-  "\xca\x10\xc7\x8c\xcf\x7a\x8d\xff\x3b\xb8\x6e\xd9\x10\xee\xd2\x2d"
-  "\x1b\xc2\xbd\xeb\x96\xf5\xb9\x9e\xba\x25\x6d\xca\x55\xdd\x12\x88"
-  "\x6e\x49\x9d\x3d\x34\xdd\xb2\x3e\xd6\x53\xb7\x6c\x38\xe2\x9b\x6e"
-  "\x59\x7f\x7c\xf8\x75\xcb\xfa\x16\x4f\xdd\xb2\xa1\x8c\xd7\xe9\xd9"
-  "\xaf\xfd\xd7\x2d\x1b\x76\x7a\xd7\x2d\x1b\xf6\x78\xea\x96\x0d\x89"
-  "\x5c\x87\x6c\xa8\xe2\xba\x65\x43\x26\x4f\x7f\xb6\xd5\x3d\xdd\xa5"
-  "\x5b\x78\x3a\xd7\x2d\x1b\xea\xaf\xae\xbb\x7f\xdf\x74\xcb\xc6\x01"
-  "\xf7\xff\x0e\x2c\xdf\xd2\xed\x2e\xf9\x96\x6e\xf7\x2e\xdf\xd2\x57"
-  "\x7b\xca\xb7\x8d\xce\xab\xf2\x2d\x10\xf9\xb6\xa1\x65\x68\xf2\x2d"
-  "\x7d\xb6\xa7\x7c\xcb\xf8\x83\x6f\xf2\x2d\xfd\x8d\xe1\x97\x6f\xe9"
-  "\x55\x9e\xf2\x2d\x23\x5f\xc2\xc6\x51\xff\xe5\x5b\xc6\xd3\xde\xe5"
-  "\x5b\xc6\x7a\x4f\xf9\x96\xb1\x80\xcb\xb1\x8c\x7d\x5c\xbe\x65\xc4"
-  "\xf1\xf4\x8d\xd5\xee\xe9\x2e\xf9\xc6\xd3\xb9\x7c\xcb\x28\x1b\xda"
-  "\x7a\xbc\x7e\xb6\x6b\x3d\x5e\xcf\x78\x21\x16\xec\x8a\xed\xbb\x1e"
-  "\xbf\xf9\x55\x4f\x7f\x41\x99\x77\xb0\xb5\x79\xec\x33\x36\xee\xd3"
-  "\xa1\xdf\x75\xfa\x49\xbb\x62\xaf\xae\xd3\x5f\xca\x75\xfa\xcd\x69"
-  "\x9e\xfd\x47\x7f\xca\xb7\xfe\xb3\xf9\xfc\xf0\xaf\xd3\xeb\x7b\xf9"
-  "\x61\xd1\xd7\x4b\x7d\xfa\xa2\xff\xfd\x47\xff\x67\xef\xfd\x47\xff"
-  "\xa6\x67\xff\xd1\x4b\x63\x4c\x7d\x0b\xef\x3f\xfa\x12\xa9\x5f\xd9"
-  "\xdd\xd3\x5d\xfd\x87\xa7\xf3\xfe\xa3\xb7\xfa\x62\x1f\x38\xd4\x3b"
-  "\x77\xa3\xbe\x9f\xd9\x74\xbd\xb3\x07\xe7\x29\x12\xce\xfb\xb3\x0f"
-  "\x9e\xe0\xfa\x82\xd9\x06\xfb\x56\xcc\x1b\xd4\x3e\x68\x91\xec\x83"
-  "\xf8\xbe\xf6\x81\x6c\x1b\x14\x02\xbe\x5f\xf4\x69\x8d\x5e\xc2\x3b"
-  "\xda\x06\x17\xfc\xb5\x0d\x26\xb9\x6c\x83\xec\x5e\xb6\xc1\xaf\x7b"
-  "\xd9\x06\x0c\xef\xcd\x1e\x78\xef\x63\x1b\xf4\xe0\x7d\xb8\x6c\x83"
-  "\xad\x09\x57\xd7\xe8\x03\x1d\x77\x6e\x51\x0e\x6d\xdc\xf9\x7c\xcb"
-  "\xd5\xb9\xfc\x40\x69\xbf\x75\x88\x73\xf9\xdb\xe2\xae\xce\xb7\x04"
-  "\x4a\xfb\xac\x21\xfa\x72\x30\x34\x05\x3e\x1e\xd9\x5e\xea\x1a\x8f"
-  "\x6c\x2f\x95\xed\x2b\x94\xbb\xcc\x67\x16\xc8\xda\xdc\x64\xb8\x2e"
-  "\x10\xb2\x3d\x99\xc5\x3c\x50\x99\x5b\x8e\x93\xa4\x74\xb4\xb9\xb6"
-  "\x4f\x89\x4e\x73\xb7\xb9\xb2\x5f\x96\xed\xad\x68\xb4\xc5\xc0\xb6"
-  "\x42\xbb\x4a\x1e\x83\xe4\xb7\x0f\xb2\x7f\xf8\xa6\x15\xf3\x70\xcc"
-  "\xd2\x1d\xbc\x73\xf7\xbf\xee\x78\x65\x5b\xe9\xd0\xc6\x2b\x39\xad"
-  "\x9e\xf6\x96\xf1\x61\xdf\xec\xad\xed\x2b\x87\x7f\xbc\xb2\x3d\xc5"
-  "\xd3\xde\x32\x46\x49\x38\xf9\x95\xff\xf6\x96\xf1\x06\xef\xf6\x96"
-  "\xf1\x16\x4f\x7b\x6b\xbb\x83\xdb\x55\xc6\xc5\xdc\xde\x32\x6a\x78"
-  "\x7a\x76\xac\x7b\xba\xcb\xde\xe2\xe9\xdc\xde\x32\xc6\xf9\x68\x6f"
-  "\x15\x0c\xc1\xde\x9a\xff\xfd\xb1\xb7\x26\x5f\xe1\xf6\x56\x6e\xa3"
-  "\x0f\x7a\x67\x77\x2f\xbd\x33\xef\xaa\xde\x41\x59\x63\x4c\x19\x9a"
-  "\xde\xd9\xb1\x78\x50\xda\x1b\xdd\x68\x8f\x32\x5f\xa2\xbb\x73\xfa"
-  "\x8a\x79\x01\xd3\x1e\x64\x7d\x51\xfa\xf7\x99\xee\x79\xda\xa1\xd1"
-  "\x3d\xbf\xe6\xaa\xad\x15\x28\xed\x77\x14\x0e\x8d\xf6\xbb\x06\x8c"
-  "\xff\x38\xb0\xad\xf5\xc2\xac\x0f\x7a\x6c\xad\x17\x66\xf5\xb6\xb5"
-  "\xd0\xb6\x5a\x68\xe7\x36\xd7\x76\xb0\x95\x72\xd6\x80\xdd\x95\x4a"
-  "\x88\xb9\xe5\x6d\x62\x04\xdb\x2b\xe7\x1c\xd8\x5f\x89\x60\x7f\x39"
-  "\xfe\x20\xd9\x5f\xbb\x5f\xf1\xb4\xbf\x7e\x7b\x43\xbf\xf6\x57\xb0"
-  "\xcb\xfe\x72\x80\x6d\xd5\xfd\x87\x15\xf3\xf2\xcf\xb9\xd9\x62\xbf"
-  "\xe9\x6b\x8b\x75\xe5\xee\x2c\xe8\xba\x69\xc5\xfc\x6e\xb0\xc7\x06"
-  "\xb2\xc5\x18\x26\xfa\xb1\xc7\xfe\xff\x61\x8b\xed\x0c\x1b\x9a\x2d"
-  "\xb6\x3b\xc5\xd3\x16\x7b\xe1\x0b\xdf\x6c\xb1\xdd\xdf\x7a\x9d\xfb"
-  "\x0a\xd8\x16\x7b\x81\x78\xda\x62\x2f\xd4\xf0\x3a\xed\x3a\xe2\xbf"
-  "\x2d\xf6\xc2\xab\xde\x6d\xb1\x17\xde\xf0\xb4\xc5\x5e\x90\xce\x9e"
-  "\xbe\x60\xe1\xb6\xd8\x0b\x85\x3c\x7d\x57\x95\x7b\xba\xcb\x16\xe3"
-  "\xe9\xdc\x16\x7b\xa1\xcd\xc7\xb5\xb1\xdd\x0e\xd0\xe9\xdf\xfd\x7e"
-  "\xca\x81\xd6\xc6\x86\x6b\x3f\xe5\xa4\x2b\x7c\x6d\xec\xbf\x06\x9f"
-  "\xff\xba\x6a\x13\xf4\x23\x6b\x7e\x47\x86\xa6\x97\x0a\x2c\x57\x6d"
-  "\x82\x40\x69\xff\x5f\x43\x9c\xfb\x7a\x71\x69\xe0\x36\x41\x91\xce"
-  "\x35\xff\x52\xa4\xf3\x6f\xfe\xa5\xb0\xc8\x53\xff\xbf\xd4\xbf\xfe"
-  "\xbf\x3a\xff\xe2\x87\xce\xdf\xa3\x1b\x9a\xce\x2f\x4c\xf0\xd4\xf9"
-  "\x45\xc7\x7d\xd3\xf9\x85\xa7\x86\x7f\xfe\xa5\xd0\xe6\xa9\xf3\x8b"
-  "\x4c\xbc\x4e\x2f\x9e\xf0\x5f\xe7\x17\xbd\xec\x5d\xe7\x17\xbd\xe2"
-  "\xa9\xf3\x8b\x36\x72\xdd\x5e\xd4\xc0\x75\x7e\x51\x3e\x4f\x7f\xb1"
-  "\xd1\x3d\xdd\xa5\xf3\x79\x3a\xd7\xf9\x45\x16\xff\xd6\xbb\x42\xaf"
-  "\xd0\xf5\x2e\xcd\xbf\xc8\x7a\xd7\xde\xd8\xab\x7a\x27\x50\xbd\x53"
-  "\x64\x1b\x9a\xde\x29\x19\xd4\xff\x87\x77\xbd\xf3\xfb\x12\x97\xde"
-  "\xf9\x7d\x89\x7f\x7a\xe7\xf7\x13\x3c\xf5\xce\xcb\x7b\xae\xea\x9d"
-  "\xa1\xea\x9d\xbd\x25\x43\xd3\x3b\xff\x6d\xf1\xd4\x3b\xfb\x7c\xf4"
-  "\x7f\xf4\x7b\xaf\xfe\x8f\x02\xd7\x3b\xbf\xef\xe5\xff\x68\x9f\xe4"
-  "\xff\xe8\xe5\x00\xfc\x86\xec\x9b\xe4\x5d\xef\xec\xeb\xe5\xff\xe8"
-  "\xf7\x92\xff\xa3\x7d\x92\xff\xa3\x7d\x52\xfa\xcb\x31\xee\xe9\x2e"
-  "\xbd\xf3\xb2\x9b\xdf\x90\x7d\x57\xfd\x1f\x7d\xef\xf6\x61\xfe\x61"
-  "\x08\xf2\xaf\x34\xd3\x25\xff\x4a\x33\xbd\xef\xc3\xfc\x9f\xf3\x9e"
-  "\xfb\x30\xff\xf8\xfc\xd5\x7d\x98\x81\xc8\xb7\x7d\x43\xf4\x8b\xf4"
-  "\x3f\x26\x4f\xf9\xf6\xca\xad\xbe\xc9\xb7\xd2\x7b\x86\x5f\xbe\x95"
-  "\x2e\xf0\x94\x6f\xaf\x84\x4b\xd8\x08\x40\xbe\x95\x5e\xf4\x2e\xdf"
-  "\x5e\x51\x78\xca\xb7\xd2\x06\x2e\xc7\x5e\x99\xc9\xe5\x5b\x69\x2b"
-  "\x4f\xff\x63\x8c\x7b\xba\x4b\xbe\xfd\xd1\x4d\xbe\xbd\x32\xdb\xbf"
-  "\x75\xcd\x80\xec\xea\xcb\xb0\xae\x39\x5c\x76\xf5\x95\xbe\xae\xf9"
-  "\xa7\xb2\xab\xf3\x68\x81\xd8\xd4\xaf\x2c\x18\x9a\x4d\xbd\x5f\x17"
-  "\xb8\x4e\x79\x5d\xed\xd2\x29\xaf\xab\xbd\xad\xef\xe4\x00\xee\x8c"
-  "\x60\x13\x67\x9f\x23\xca\xed\xb8\xbe\xd3\x50\x4b\x72\x71\x7d\x67"
-  "\x8d\xbc\xbe\x53\x24\xd9\xd9\xaf\x6d\xf6\xb4\xb3\x5f\x55\xf4\x67"
-  "\x67\xa3\x7d\xed\x04\xdb\xd9\xd1\x7b\x5d\xe7\x91\xfe\x75\x51\x57"
-  "\xf0\xce\x82\x8b\x7f\x58\x31\xdf\x5f\x5d\xf4\xd2\x06\xae\x8b\x5e"
-  "\xfc\xde\xeb\xa2\x3f\xd9\x87\xa6\x8b\x5e\x5b\xe0\xa9\x8b\x5e\x7f"
-  "\xd3\x37\x5d\xf4\xda\xd1\xe1\xd7\x45\xaf\x35\x7a\xea\xa2\xd7\xf7"
-  "\xf1\x3a\xed\x0f\x20\xb6\xe4\xeb\xcf\x7b\xd7\x45\xaf\xe7\x7a\xea"
-  "\xa2\xd7\xe3\xb8\xce\x79\xbd\x9c\xeb\xa2\xd7\x53\x78\xfa\xfe\x7d"
-  "\xee\xe9\x2e\x5d\xc4\xd3\xb9\x2e\x7a\xbd\xca\xbf\x39\x9e\x51\x57"
-  "\xe8\x1c\x8f\xea\x5f\x64\x8e\xe7\xcf\x73\x02\x97\x89\x07\x48\x4d"
-  "\xcf\xf9\x8d\x03\xa4\xcf\x3c\x43\x2a\xd8\xdb\xed\x7c\x9d\xbb\x67"
-  "\x9e\xc1\x72\x52\x92\x7f\x7f\x7d\xc6\x53\xfe\xfd\xc5\xab\xfc\x1b"
-  "\x68\x2d\x1b\xe7\x15\x9c\x20\x1b\x31\x46\x66\xc0\x6b\xd9\xa9\xdf"
-  "\x77\x99\xf7\xfa\x10\xfd\x2b\xff\x35\xca\x53\xe6\x1d\x78\xd5\x37"
-  "\x99\xf7\xd7\xb7\xbd\xca\xbc\x80\xcf\x71\xfc\xb5\xc6\x53\xe6\x1d"
-  "\x28\xe0\x75\xfa\xf3\x9b\xfe\xcb\xbc\x03\xeb\xbd\xcb\xbc\x03\x9b"
-  "\x3d\x65\xde\x81\xc5\x5c\xb6\x1d\xd8\xcf\x65\xde\x81\x04\x9e\xfe"
-  "\xe7\x72\xf7\x74\x97\xcc\xe3\xe9\x5c\xe6\x1d\x28\x1f\x48\xe6\x51"
-  "\xe3\x92\x82\x7c\x41\x2c\x83\xab\x1c\xea\x38\x09\xb0\x61\x82\xdf"
-  "\xd5\xc0\xe3\x71\xf0\xdb\x6b\xac\x17\x6b\xf0\x92\x02\x51\x0f\x75"
-  "\x16\x88\xc2\x6c\xfd\xc6\x64\x9a\xec\x80\xef\xbe\x21\x9d\x59\x5b"
-  "\x52\x10\xea\x18\x35\x5f\xa4\x09\x04\xf8\x52\xc0\xe2\x67\x42\x7e"
-  "\x3c\x1f\xa4\x4d\x25\x21\xe7\x14\x6f\xc4\xca\xf9\xa0\xbe\x21\xcd"
-  "\x8a\x37\x26\x60\x19\x9d\x59\x6f\xc4\x43\x5b\xaa\xbc\xd6\x15\xca"
-  "\x8a\x7e\x65\x2a\xd9\xe4\xa0\x5f\x99\xd6\xb4\x93\x16\xc5\x1b\xaf"
-  "\x86\xb6\x8d\x9a\x4f\x33\x62\x09\xda\x72\x65\x93\xad\x4a\x2c\xd3"
-  "\xb4\xa6\x0b\xdf\xe5\xe3\x3b\x27\xd4\x31\x7d\x35\x11\xf2\xda\x47"
-  "\xa9\x40\x4e\x8c\xc8\xb0\xd1\xd6\xb5\x0e\xa8\x33\x60\xf3\xdd\xa9"
-  "\x8d\xca\xd7\x5f\x84\x34\x27\x09\xc7\x78\xa6\x58\x06\xd8\xb3\x58"
-  "\x9f\x3f\x17\x43\xfe\xfe\xea\xf0\xfc\x6b\x64\xe6\x88\x5b\xa8\xc5"
-  "\x3f\xdc\xfc\x9f\xd2\x1b\x1d\x43\x37\x4f\x25\xa6\x19\x40\x3b\x2d"
-  "\x11\xfa\x7b\xef\xe7\x77\x06\x3a\xff\xae\xc2\x18\xc9\x19\x7b\x88"
-  "\xb0\x43\x1c\xa5\x3a\xbc\x91\xc5\x28\xb6\x76\x66\xfd\x5f\xa3\x45"
-  "\x71\x9d\x12\x69\x8e\x71\x2d\x31\xbe\x36\xe0\x86\x40\xba\xb5\x32"
-  "\x8d\x90\xde\xbc\x48\x8e\x5f\xbd\x5c\x9b\xb2\x6a\xf5\xca\xb5\xcf"
-  "\xa4\x68\x6f\x8a\x1f\x43\x16\xaf\x5d\xab\x5d\xbd\x7c\xcd\x7a\xad"
-  "\xfb\x9b\x9f\x68\xe3\x57\xad\x5b\xfe\x44\xe2\xca\x5b\x57\xaf\x48"
-  "\x1a\x83\xc2\xd7\xad\x1e\x61\x58\x17\x31\xeb\xff\x1c\xc5\xbb\x08"
-  "\xf9\xed\x78\xa2\xc4\x7a\x75\x66\xfd\x2d\x4e\x8e\x7b\x9a\xf7\x3b"
-  "\x6a\x13\x20\x4f\x06\xc8\xc7\x1d\xe9\xa3\x30\x6f\xe2\x5e\xa8\x57"
-  "\x31\xd4\x1b\xea\x08\x75\xfe\x9b\x51\xae\xb3\x8c\x89\x0c\xc4\x44"
-  "\x7a\x3b\x60\xf0\x6f\xaf\x86\xda\x47\xfd\x3b\xa5\xb1\xd8\x3e\x1b"
-  "\xf4\x13\x05\xa4\x39\x99\x2e\xcb\x5d\x52\x00\xff\xad\x96\x31\x86"
-  "\xff\xa5\x79\x4b\xe2\x3a\xb1\x9f\xd0\x84\x7b\x79\x9f\x2a\x2f\x79"
-  "\x58\xa7\x20\x3c\xee\xea\xdf\x6c\xae\xb8\xab\xe5\x6c\xae\x1a\xea"
-  "\xd1\xd6\x99\x55\xae\xb6\x90\x36\x0b\xa6\x63\xbc\x60\x8c\xdf\x8d"
-  "\x75\x86\x76\x81\x2e\xa5\x26\xaa\x97\xb0\x6f\xf8\x93\x49\x34\xbc"
-  "\x6f\x37\x2b\x2f\x90\x68\x07\xed\xa6\xd9\x7f\x32\xd5\xd9\x6c\x24"
-  "\x74\x73\xd2\x0a\x3a\xf2\x6f\x20\xb3\x57\xad\xdc\x3b\x1e\xfa\x50"
-  "\xf6\xfb\x76\x9a\x5d\xd9\xf4\xf0\x2d\x44\x03\x65\xbb\xc7\x7f\x55"
-  "\xfa\xc7\xff\x72\xc6\x7f\xe4\x23\xd4\x47\xe2\x63\x79\x79\x65\x4a"
-  "\x5f\x3e\xf6\xe0\xef\x15\x91\x1c\x01\x2c\x50\xf5\x36\x4b\xb4\x93"
-  "\xd3\x11\xfb\x6e\x47\x46\x02\xb9\x9d\xd1\xee\xcd\x24\x31\x6f\x9b"
-  "\x49\x34\x6e\xb3\x53\xe3\xb6\x16\xa0\x59\x5a\x5e\x2a\xd1\x2e\x73"
-  "\x6a\x48\xee\x05\x12\x69\xcd\xdd\x66\x09\x56\x64\x2a\xc0\x1e\x11"
-  "\x40\x9f\x44\x82\xcc\x88\x94\xfa\x7b\x1a\xd2\xf1\xfd\x36\x42\x1e"
-  "\x5c\x47\xc8\x57\x73\x48\x50\x31\xfc\xcf\xbf\xf6\xbc\xc9\xf4\x3f"
-  "\xcd\x2a\xb7\xed\x85\xff\x62\x5c\x5f\x3f\xff\xbf\xd1\x6b\xbf\xeb"
-  "\x69\xb7\x21\xae\xff\x76\xbf\x95\x20\xe6\x19\xa2\x44\xa3\x21\x8d"
-  "\x1a\x0d\xf1\x7d\xdb\x6d\x88\xe3\xed\x1e\xd1\x3e\xfc\xed\x7e\x8b"
-  "\xfb\xbf\xce\x7a\xb3\x2d\xb0\x76\xbf\x95\xe2\x43\xbb\xbd\xf0\xfb"
-  "\x60\x1c\xb4\x1b\xf8\x6d\x00\x7e\x1b\xfa\xe1\xb7\x41\xe2\xf7\xd8"
-  "\xe6\xe1\x6f\xf7\xc1\x99\xbc\xdd\x6f\xb5\x04\xd6\xee\x83\x5e\xe5"
-  "\x9f\xab\xdd\xd9\x5e\xf8\x5d\x11\x2b\xe6\x65\x03\xbf\xb3\x81\xdf"
-  "\xd9\xfd\xf0\x3b\x5b\xe2\xf7\xb8\x8f\x86\xbf\xdd\x15\xdc\xff\x61"
-  "\xd6\xc1\xa6\xc0\xda\x5d\x11\xef\x43\xbb\xbd\xf0\xfb\xed\x18\x68"
-  "\x37\xf0\x3b\x1b\xf8\x9d\xdd\x0f\xbf\xb3\x25\x7e\xdf\x9d\x33\xfc"
-  "\xed\x7e\x3b\x82\xb7\xbb\xa2\x21\xb0\x76\xbf\xed\x75\xff\x8b\xab"
-  "\xdd\x39\x5e\xf8\xfd\xce\x7c\x31\x2f\x07\xf8\x9d\x03\xfc\xce\xe9"
-  "\x87\xdf\x39\x12\xbf\x1f\xbd\x6f\xf8\xdb\xfd\x4e\x18\x6f\xf7\xdb"
-  "\x35\x81\xb5\xfb\x1d\xaf\xfb\xdf\xdd\xe4\x79\x2b\xc8\xec\x3e\x3c"
-  "\x37\xa7\xcd\x26\xb7\x5d\xc0\xf6\xbf\x5b\x4e\x83\xb7\xb5\x8e\xdd"
-  "\x9c\xa9\x70\xa8\xb7\xb5\x8d\x85\xb1\xdc\x4b\x7a\x31\x21\xd4\x42"
-  "\x46\x43\x5b\x13\x68\x9e\x31\x13\xef\x22\x94\xe3\x00\xd9\xef\x54"
-  "\x6f\x6b\xe9\x32\x2e\x49\xdb\xfe\x24\xd1\x66\x58\x89\xa6\x2e\xdd"
-  "\x42\xd2\x93\xa8\xb5\x8e\x7c\x41\x82\x2d\x44\xc0\xf9\xb2\x0f\xda"
-  "\xca\xc9\x9a\x64\x4a\xa1\xec\x97\x71\x8c\x99\x77\x9a\x44\x82\x4d"
-  "\x9c\x49\x41\x7f\xe4\x8b\x44\x0b\xe5\x47\x22\x2d\xa1\x6c\x7d\xe8"
-  "\x62\xa2\x78\xe7\x09\x3b\x41\x7a\x22\x6d\x61\x3c\x1a\xc9\xe8\x6a"
-  "\x23\xe4\x3f\x1e\xe5\x74\x7d\xe9\x49\x7f\xe9\xfa\x2e\x5f\xff\x33"
-  "\x1a\x88\xd9\xd2\x85\x31\x03\x34\x78\xe6\x1e\xd2\x75\x75\x49\xed"
-  "\x30\x16\x79\xa7\x86\xe6\x6e\xb3\x8a\xa0\xb3\xfc\x2c\xd7\xab\xff"
-  "\x6b\x37\x79\x9a\x00\x32\xb3\x0f\xd6\x5c\xf4\xae\xd4\xd1\x60\x43"
-  "\x02\xa7\xb7\x21\x71\x6c\xd3\x88\xf6\xfe\xe9\x6d\x48\x70\x80\xce"
-  "\x71\xaa\x0d\xf1\xbe\xd3\xbb\x72\x9c\x27\xbd\x0d\x51\x97\x87\xde"
-  "\x26\x29\xfe\xa9\x21\xd3\x93\xde\xa6\x02\x4e\x6f\xd3\x1c\x9a\x6b"
-  "\x48\x12\x41\x57\xfa\x57\x6e\xe5\x2c\x1f\xe8\x0d\xf8\xee\xab\xc3"
-  "\x5c\xf4\x3e\x04\x63\x4e\x83\x84\x6f\x03\xe0\x7b\x6c\xb3\x17\x7a"
-  "\x03\xbe\x0d\x80\x6f\x83\x1f\xf8\x3e\xb4\xb9\x17\xbd\x2f\x13\xbe"
-  "\x0f\x49\xf3\x7f\xd9\xbd\xf0\x7d\x48\xc5\xe9\x5d\xb9\x1f\xe8\x0d"
-  "\xf8\x36\xf8\x89\xef\x43\xfb\x7c\xd0\x1f\x80\xef\xbe\xba\xd3\x45"
-  "\xef\x2a\x15\x0d\xce\x96\xf0\x9d\x0d\xf8\x1e\xf7\x51\xff\xf4\xce"
-  "\x06\x7c\x67\x03\xbe\xb3\xfd\xc0\xf7\xe1\x6f\x3d\xe9\x9d\x7d\x99"
-  "\xf0\x7d\xb8\x42\xa2\x77\x2f\x7c\x1f\x4e\xe3\xf4\x3e\x1c\x41\x73"
-  "\xb3\x01\xdf\xd9\x7e\xe2\xbb\x2a\xcc\x07\x7a\x03\xbe\xfb\xea\x6c"
-  "\x17\xbd\x8f\xa4\x01\xbd\x25\x7c\x67\x03\xbe\xef\xce\xf1\x42\x6f"
-  "\xc0\x77\x36\xe0\x3b\xdb\x0f\x7c\x1f\x59\xde\x8b\xde\x97\x09\xdf"
-  "\x47\xb8\xfd\x67\xcc\xe9\x85\xef\xaa\x56\x4e\xef\x2a\x23\xd0\x1b"
-  "\xf0\x9d\xed\x27\xbe\x8f\x6c\xf5\xc1\x4e\x00\x7c\xf7\xb5\x15\x5c"
-  "\xf4\x7e\xaf\x95\x06\xe7\x48\xf8\xce\x01\x7c\x3f\x7a\x5f\xff\xf4"
-  "\xce\x01\x7c\xe7\x00\xbe\x73\xfc\xc0\xf7\x7b\x1f\x7a\xd2\x3b\xe7"
-  "\x32\xe1\xfb\x3d\x29\xfe\x65\x4e\x2f\x7c\xbf\x17\xcb\xe9\x7d\xc4"
-  "\x41\x73\x73\x00\xdf\x39\x7e\xe2\xfb\x3d\x5b\x20\xf6\xc9\xba\x22"
-  "\xa2\xf2\xa4\x79\xf5\xd2\x4b\x67\xa3\x54\xdf\xff\xdd\xd8\x28\xd5"
-  "\x9a\xfe\x6d\x94\xf7\x6b\x38\xcd\xdf\x4f\x0a\xcc\x46\xa9\xf6\x7a"
-  "\xfe\x61\x20\x1b\xa5\x2f\xcd\x8f\xd6\x5f\x3a\x3b\xe5\xe8\x9b\xdf"
-  "\x8d\x9d\x72\x74\x6b\xff\x76\xca\xd1\x28\x4e\xf3\xea\x96\xc0\xec"
-  "\x94\xa3\x5e\xfd\x1f\x0c\x64\xa7\xf4\xa5\xf9\x07\xf3\x2e\x9d\xad"
-  "\xf2\xc1\xad\xdf\x8d\xad\x72\xcc\xde\xbf\xad\x72\xec\x00\xa7\xf9"
-  "\xb1\xd8\xc0\x6c\x95\x0f\x62\x02\xb1\x55\xfa\xd2\xbc\xa6\xfc\xd2"
-  "\xd9\x2b\x35\x2f\x7f\x37\xf6\x4a\x4d\x62\xff\xf6\x4a\x8d\x34\xfe"
-  "\xf9\xa0\x26\x30\x7b\xa5\xc6\x87\xf1\x4f\x5f\x7b\xa5\x2f\xcd\xeb"
-  "\x66\x5e\x3a\x9b\xa5\x6e\xc2\x77\x63\xb3\xd4\x5a\xfa\xb7\x59\x6a"
-  "\x0b\x39\xcd\x6b\xa3\x02\xb3\x59\xea\xbc\xc6\x3f\x19\xc8\x66\xe9"
-  "\x4b\x73\x73\xc9\xa5\xb3\x5b\xcc\xd9\xdf\x8d\xdd\x62\x5e\xdc\xbf"
-  "\xdd\x62\xd6\x70\x9a\xd7\x1d\x08\xcc\x6e\x31\xef\x0f\xc4\x6e\x41"
-  "\x5a\x23\xcd\xd1\x56\xe1\x34\xff\x28\x89\x86\x6c\x33\x75\x83\x3d"
-  "\x12\x0c\x74\x0f\x6e\x23\x42\x11\xd2\xbc\x91\xd3\xdc\x19\x62\xcc"
-  "\x04\xfa\x24\x20\xcd\x58\x3b\xfe\x19\x1e\xe2\x34\x6e\x6b\xa3\x02"
-  "\x81\xb6\xa8\xc8\x69\x45\xfd\x26\x87\x9e\x84\x68\xd3\x37\xc3\xef"
-  "\x8f\x96\x63\x1e\x6d\x7a\xd6\x49\x68\x63\x10\xae\x51\x38\x72\x97"
-  "\x68\x9d\xc1\xdb\x4b\x4e\x2b\x3e\x7c\x9b\x4e\x79\x48\xdb\x0d\xb6"
-  "\x04\x7d\x2a\x3c\xcc\xdc\x56\x46\xcc\x8e\x63\xa4\xae\xf1\x2d\x22"
-  "\x86\x18\xf5\xb7\x3b\x88\x8e\xfe\x53\x17\x56\x93\x62\x21\xce\x15"
-  "\xe1\x6a\x73\x5a\x35\xe0\xe2\x2f\x24\xba\x95\x5e\xa0\x5f\xea\xd4"
-  "\xdd\xc1\xf9\x16\x67\xb0\x31\xce\x99\xbb\xb3\xd4\x11\x9c\x5f\xff"
-  "\x6a\xaa\x45\x50\xdb\x89\x2e\xb1\x85\xd2\xbc\x27\x88\x32\xaf\x99"
-  "\xa8\x76\x3c\x41\xd4\x3b\x9a\x89\xa6\xa6\xa5\x91\xd4\x9e\xa9\x26"
-  "\xb5\xed\x27\x48\xed\x05\xb8\xba\xe0\x12\xe1\xca\x3c\x41\x6a\xda"
-  "\x08\x59\x78\x96\x90\x8c\x16\x6a\xfd\x61\x13\x09\xab\x71\x34\x12"
-  "\xed\xe3\x84\x9c\x53\x7c\xf8\x4b\x75\x1c\x09\xa3\x5f\x86\x13\xba"
-  "\x22\x5c\x80\x77\x4a\x4c\x37\x3b\xac\xa4\xa6\xc5\x8e\xef\x23\xe1"
-  "\xbd\x32\xa3\x05\xca\x17\xab\xd1\x97\xa1\xb5\x26\xf3\x28\xb4\x6f"
-  "\x94\x06\xe8\x6c\x97\x6d\xb2\xbc\x2e\x12\xb9\x03\xd8\x8c\x98\x89"
-  "\xa6\x1c\x33\x7b\xbb\xfc\xc5\xcc\x87\xdc\xff\xfb\x53\xe1\xe3\x81"
-  "\xde\x93\xc5\xa7\x62\x35\x0f\x9e\xf8\x9c\xe2\x7e\x30\x5c\x9f\xa9"
-  "\xb3\x1d\x23\xb8\x66\x1d\xbd\x9e\x90\x05\x4e\x42\x90\x26\xb8\x96"
-  "\xfc\x60\x12\x09\xc5\x7d\x6a\xe2\x3f\x75\xe3\xcd\x2d\x56\xb2\xc9"
-  "\x01\x75\x3d\x67\xef\xa9\x6b\xdd\xd6\x3a\x02\xef\x26\xd7\x25\x58"
-  "\x88\x3a\x89\x68\x90\xce\x60\x8b\xb6\x3e\xd8\x4a\x46\xaf\xb1\x51"
-  "\x8a\x34\x46\xda\x22\x9d\xb1\x3c\x99\xf6\xe6\x78\x2b\xc9\xb0\x13"
-  "\x8d\x39\x1d\xee\x69\xd4\x6a\x26\xdf\x12\xa8\x63\x3c\x0d\x1e\xa5"
-  "\x01\x7c\x6c\x45\x4c\x58\x14\xf5\x29\x80\x83\xf1\x34\xab\x5e\x57"
-  "\x0c\xed\xc5\xb5\x7d\xff\xda\xfc\x91\x2f\xeb\x1f\x7d\x6c\x42\x17"
-  "\x9e\x0d\x09\x1c\xcf\xc7\xa3\x68\x88\x21\xaa\x1b\x6c\x3d\x8e\xe7"
-  "\x11\xed\x83\xe3\xd9\x90\xe8\xc2\xf3\xdf\x17\xba\xf0\x7c\xfc\x0e"
-  "\xef\x78\x6e\xc8\x95\xf0\x9c\x79\x65\xe2\xb9\xe1\x86\x81\xf1\xdc"
-  "\x40\xbc\xe3\xd9\x90\x26\xdb\xbb\xc3\x83\xe7\x86\xd8\xcb\x87\x67"
-  "\x43\x42\x60\x78\x6e\x98\xe5\x89\xe7\xbf\xcf\xe3\x78\xfe\xc8\x1e"
-  "\x18\x9e\x8f\x7b\xf5\x7f\x3c\x90\xbd\xed\x86\x67\x49\x3e\x37\x6a"
-  "\x00\xcf\x20\x9f\x0d\x92\x7c\x1e\xdb\xec\x03\x9e\xdd\xe4\xf3\xc7"
-  "\x53\x5c\x78\x6e\x54\x78\xc7\xf3\x27\x8f\x71\x3c\x67\x5f\xa1\xf2"
-  "\xf9\xe3\x6f\x07\xc6\xf3\xc7\xf5\x03\xe0\xd9\x2e\x8f\x25\x86\x07"
-  "\xcf\x9f\xe8\x2e\x23\x9e\x03\x94\xcf\x9f\x28\x3d\xf1\xfc\x71\x18"
-  "\xc7\xf3\xf1\xea\xc0\xf0\xdc\x18\x11\xc8\x58\xc6\x85\xe7\x6c\x49"
-  "\x3e\x7f\x6a\xa1\x21\xd9\x20\x9f\xb3\x25\xf9\x3c\xee\xa3\xc1\xf1"
-  "\x9c\xed\x26\x9f\x1b\xcf\xba\xf0\xfc\xe9\x87\xde\xf1\xfc\xe9\xad"
-  "\x12\x9e\xaf\x50\xf9\x7c\xa2\x72\x60\x3c\x9f\x28\xf1\x8e\xe7\xec"
-  "\x34\x79\x9c\x36\x3c\x78\x3e\x61\xbf\x7c\x78\xce\x0e\x50\x3e\x9f"
-  "\x68\xf0\xc4\x73\x63\x0b\xc7\x73\x63\x41\x60\x78\xfe\xb4\x2d\x90"
-  "\x71\xa2\x1b\x9e\x25\xf9\x7c\xb2\x0c\xf0\x0c\xf2\x39\x5b\x92\xcf"
-  "\x77\xe7\xf8\x80\x67\x37\xf9\xfc\xd9\xdb\x2e\x3c\x9f\x7c\xd9\x3b"
-  "\x9e\x9b\x9c\x1c\xcf\x39\x57\xa8\x7c\x6e\xda\x39\x30\x9e\x9b\x92"
-  "\x06\xc0\xb3\x5d\x1e\x03\x0f\x0f\x9e\x9b\xaa\x2f\x23\x9e\x03\x94"
-  "\xcf\x4d\xfb\x3c\xf1\xfc\xd9\x01\x8e\xe7\xcf\x12\x02\xc3\xf3\x49"
-  "\xaf\xf1\x5f\x07\x1a\x83\xbb\xf0\x9c\x23\xc9\x67\x4b\x26\x0d\xc9"
-  "\x01\xf9\x9c\x23\xc9\xe7\x47\xef\x1b\x1c\xcf\x39\x6e\xf2\xf9\x1f"
-  "\xb9\x2e\x3c\x5b\x9e\xf6\x8e\xe7\xcf\x6b\x25\x3c\x5f\xa1\xf2\xf9"
-  "\xf3\xe5\x03\xe3\xf9\xf3\x28\xef\x78\xce\x49\x93\xe7\x17\x86\x07"
-  "\xcf\x9f\x17\x5c\x3e\x3c\xe7\x04\x28\x9f\x3f\x4f\xf1\xc4\xf3\x3f"
-  "\xb6\x72\x3c\xff\x63\x76\x60\x78\xb6\x18\x87\x67\x7e\xe3\xcb\x4c"
-  "\x9c\xdf\xe8\xc2\xf9\x0d\xd7\xde\xbf\x84\xd0\x7a\x8e\xe7\x6e\xc0"
-  "\xf3\x4b\xee\x78\xfe\xac\xf7\xfc\xc6\x17\x8f\x89\x3d\x78\xfe\xb2"
-  "\x0f\x9e\x45\xc0\x73\x37\xc3\x73\x73\xb6\x3c\xbf\x61\x6e\x2b\x01"
-  "\x9c\x9c\x21\xe6\x18\xc0\x72\x9e\x84\xe5\xcf\x00\xcb\x40\x43\x11"
-  "\x68\x5c\xd3\xd4\x48\xa2\xad\x9c\x96\x5d\x40\x63\xd1\x1d\xc7\x5d"
-  "\xad\x02\xe2\x17\x71\x2b\x63\xb8\x76\x0d\x60\x37\xf9\x43\x52\x9b"
-  "\x0a\xd7\x06\xb8\xd2\xe1\x22\x1f\x92\x9a\x56\xc0\xee\x2a\x77\xec"
-  "\xd6\x4b\xd8\x6d\x9e\x32\x30\x76\xbf\x70\x5c\xbe\xb9\x8c\x66\x3e"
-  "\xff\xf5\x59\xac\x26\xfa\x97\x9f\x53\x73\x5a\xa3\x84\xcf\x33\x24"
-  "\xda\x41\x42\xe9\xa3\xba\xf1\xea\x58\xa2\x79\xce\x49\x84\xdc\x27"
-  "\x88\x26\xf7\x53\x68\xb7\xdc\x7f\x9b\x89\xfa\x98\xfd\x2d\x52\xd3"
-  "\xde\x48\x6a\x2e\x1c\x25\x35\x22\x5c\x67\xe0\x82\xba\x46\xaf\x74"
-  "\x6f\xb7\x55\x6a\xf7\x97\x13\xa0\xac\xe9\xde\xdb\xdd\x6c\x63\xed"
-  "\x8e\x87\x76\x77\xb9\xda\x6d\x86\x7e\x00\xfc\x99\x2c\x4a\xf3\x21"
-  "\xd1\x56\x32\x7a\xad\x83\xd2\x2e\x09\xff\xc8\x9f\x63\x0d\x76\x12"
-  "\x9d\x04\x3c\x5b\x01\xf8\x6f\x29\x25\x19\x1b\x01\xff\x5d\x76\xc4"
-  "\x9d\xd5\x9c\x79\x11\xf0\xdf\x1c\x49\x81\x7e\xdd\x88\xff\xcf\x10"
-  "\xff\x5f\x2c\x16\x19\xfe\xbf\x50\x05\x86\xff\x2f\x7d\xc0\xbf\x2f"
-  "\xf3\x21\xa7\x33\x71\x3e\xa4\x0b\xe7\x43\x5c\x7b\x40\x07\xc1\xbf"
-  "\xfb\x7c\x48\x8b\x1b\xfe\x4f\x0f\x80\xff\x53\x32\xfe\x33\xbf\x7b"
-  "\xfc\x9f\x1a\x04\xff\x2d\x03\xe0\x7f\xb8\xe7\x3e\x4e\x5d\x46\xfc"
-  "\x9f\x1e\x04\xff\xa7\x7c\xc0\xbf\x21\x21\x30\xfc\x9f\xea\x85\xff"
-  "\x16\x09\xff\x2d\x01\xe2\xff\xb4\x2f\xf8\xf7\x61\xfe\xe4\x6b\xc4"
-  "\x3f\xc8\x7f\x43\x8b\xdb\x5e\xe0\xc1\xf0\xef\x26\xff\xbf\x72\xc3"
-  "\xff\xd7\x03\xe0\xbf\x35\x5b\x9e\x3f\xf9\xee\xf1\xdf\x3a\x08\xfe"
-  "\xbf\x1a\x08\xff\xc3\x3c\x57\xd2\x7a\x19\xf1\xff\xf5\x20\xf8\x6f"
-  "\xf5\x05\xff\x01\xca\xff\xd6\x5e\xf8\xff\x4a\xc2\xff\x57\x01\xe2"
-  "\xff\x6b\x1f\xf0\xef\xcb\x7c\x4b\x5b\x26\xce\xb7\x74\xe1\x7c\x8b"
-  "\x6b\x4f\xf8\x20\xf8\x77\x9f\x6f\x39\xe3\x86\xff\xb6\x01\xf0\xff"
-  "\x4f\x19\xff\x57\x80\xfc\xff\xe7\x20\xf8\x3f\x33\x00\xfe\x87\x7b"
-  "\x6e\xe5\x9f\x97\x11\xff\x6d\x83\xe0\xff\x9f\x3e\xe0\x3f\x3b\x40"
-  "\xf9\xff\xcf\x5e\xf8\x3f\x23\xe1\xff\x4c\x80\xf8\x6f\xf3\x05\xff"
-  "\x3e\xcc\xcf\x7c\x83\xf8\x07\xf9\x9f\xdd\xe2\x76\x36\x60\x30\xfc"
-  "\xbb\xc9\xff\xb3\x6e\xf8\xff\x66\x00\xfc\x9f\xcb\x96\xe7\x67\xbe"
-  "\x7b\xfc\x9f\x1b\x04\xff\x67\x07\xc2\xff\x30\xcf\xc5\x9c\xbb\x8c"
-  "\xf8\xff\x66\x10\xfc\x9f\xf3\x05\xff\x01\xca\xff\x73\xbd\xf0\x7f"
-  "\x56\xc2\xff\xd9\x00\xf1\xff\x8d\x0f\xf8\xf7\x65\x3e\xa7\x9d\xcd"
-  "\xe7\x74\xe1\x7c\x8e\xeb\x8c\xc8\x20\xf8\x77\x9f\xcf\xb1\xba\xe1"
-  "\xbf\x7d\x00\xfc\x7f\x2b\xe3\xff\x0a\x90\xff\xdf\x0e\x82\x7f\xeb"
-  "\x00\xf8\x1f\xee\xb9\x9b\x6f\x2f\x23\xfe\xdb\x07\xc1\xff\xb7\x3e"
-  "\xe0\x3f\x27\x40\xf9\xff\x6d\x2f\xfc\x5b\x25\xfc\x5b\x03\xc4\x7f"
-  "\xfb\x30\xcd\xff\xd8\x74\x38\xff\x23\xaa\xb7\xb5\x74\x17\x3e\xa4"
-  "\x15\x8d\xf9\x96\x50\x85\x96\x38\xd4\xdb\x4b\xcc\x29\x36\xf2\xe0"
-  "\x79\xe0\x49\xd2\x79\xf2\xf8\x79\x0d\xc6\xb2\xac\xa7\x30\xfe\xf7"
-  "\x38\x23\x0a\x97\xc3\x38\x4a\xb3\x63\x0d\x51\x3a\x43\x8c\x7a\x4c"
-  "\x33\x9f\xb6\x13\x6c\xf3\x26\xa4\xc1\x19\x17\x0d\x70\x0e\x8e\x7e"
-  "\xa3\xd3\x14\xeb\x21\x4f\x97\x85\xb4\x00\x5e\x6a\x5a\x2c\x40\xfb"
-  "\x0d\x0c\x5b\xc8\x8b\xd3\x8a\x8e\xea\xbd\xe7\x88\xd2\xf1\x65\xf8"
-  "\x64\xe0\x71\x58\xf0\xb3\x44\x11\xd1\x42\x45\xe4\x25\xf2\x08\xf9"
-  "\xaa\xdd\x80\xfb\x95\x6c\x37\xd4\x01\xbe\x1d\x5f\xea\x26\x17\x43"
-  "\xbe\xe1\x9f\x97\xe9\x68\xe3\xe7\xf1\x3b\x4c\x35\x4d\x40\xcb\xac"
-  "\x8e\x00\xf9\x64\xf3\xe5\xfc\x8b\x0f\xf3\x14\xe7\xeb\x71\x9e\x42"
-  "\x54\x1b\xe2\x7d\xe3\x93\x21\xc1\xe3\x4c\xeb\xb0\xf3\xe9\x7c\x92"
-  "\x6f\x7c\x3a\x7f\xd4\x93\x4f\xc3\x3d\x7f\x70\x7e\x37\xe7\xd3\xf9"
-  "\x04\xce\x27\x5b\x59\x60\x7c\x3a\x1f\xd0\xfe\xdf\xbe\xe3\xe9\xce"
-  "\x34\x1c\x4f\x03\x9f\x7c\xec\x4f\x86\x56\x8f\x33\xb8\xc3\xce\xa7"
-  "\xce\x70\xdf\xf8\xd4\xf9\x74\x2f\x3e\x0d\xf3\x38\xb7\x73\x0e\xe7"
-  "\x53\xa7\x86\xf3\xe9\x42\x6c\x60\x7c\xea\xf4\xe1\xfc\x87\x2f\xe3"
-  "\xbe\x8b\x5a\x1c\xf7\x89\x30\xee\xf3\x8d\x4f\xd9\x09\x1e\x67\x86"
-  "\x87\x9d\x4f\x76\x93\x6f\x7c\xba\x38\xc9\x93\x4f\xc3\x3d\x1e\xb3"
-  "\xb7\x70\x3e\xd9\xcb\x39\x9f\xec\x24\x30\x3e\x5d\x9c\x39\x3c\xe3"
-  "\x93\xae\x6a\x1c\x9f\x00\x9f\x7c\xec\x4f\xd9\xad\x1e\x67\x9c\x87"
-  "\x9d\x4f\x5d\x09\xbe\xf1\xa9\xab\xb2\x17\x9f\x86\x79\xdc\xd0\x25"
-  "\xc5\x03\xee\x8a\xe3\x7c\xba\x58\x1a\x18\x9f\xba\xbc\xfa\x3f\xf5"
-  "\xcf\x8e\x76\x24\xa1\x1d\x2d\x82\x1d\xed\x1b\x9f\x72\x12\x3c\xce"
-  "\x64\x0f\x3b\x9f\x1c\x1a\xdf\xf8\xe4\x58\xe5\xc9\xa7\xe1\xb6\x6f"
-  "\x1d\xb3\x38\x9f\x1c\x2a\xce\xa7\xee\x98\xc0\xf8\xe4\xf0\x61\xff"
-  "\x67\xff\xe7\xb0\xfa\xda\x7c\x62\xc4\x95\x65\xf3\x39\x2b\x7c\xe3"
-  "\x95\x38\xe1\xd2\xda\x7c\x4e\x0b\xe7\x95\xf3\x00\xe7\x95\xc3\x11"
-  "\x18\xaf\x44\xaf\xfe\x1f\x07\x3b\xbf\xd5\xd7\xee\xa3\xd5\x57\x96"
-  "\xdd\x47\x7d\x94\x7f\xb4\xf2\xd2\xda\x7d\x54\x92\x7f\x54\x92\x7f"
-  "\x62\x80\xf2\x8f\xfa\x20\xff\xfa\x3f\xf7\xd5\xc7\xf6\x13\x14\x29"
-  "\x57\x94\xed\x27\x28\xc2\x7c\xe2\x95\xa0\x58\x7d\x49\x6d\x3f\x41"
-  "\xc1\xce\xbf\xc0\x5d\xcd\x78\x95\x43\x16\x07\xc4\x2b\x41\x91\x19"
-  "\xe8\x79\xb1\x3e\xf6\x9f\x10\x74\x65\xd9\x7f\x82\xe0\x9b\xfd\x27"
-  "\x04\x5d\x5a\xfb\x4f\x10\xb8\xfd\x27\x08\xdc\xfe\xcb\x11\x02\xb3"
-  "\xff\x84\xa0\x80\xec\xbf\x5e\xbc\x92\xfa\x95\xb2\xe6\x8a\xb2\x01"
-  "\x05\x65\xa2\x6f\xbc\x52\x1e\xb9\xa4\x36\xa0\xa0\xcc\xe7\xbc\x52"
-  "\xc6\x73\x5e\x05\xed\x0f\x8c\x57\x4a\xaf\xf1\x6f\x07\x3b\x9f\xd6"
-  "\xc7\x0e\x14\x46\xa6\x5d\x51\x76\xa0\x30\xd2\xb7\xf1\xaf\x30\xf2"
-  "\xe9\x4b\x6a\x07\x0a\x23\xf9\xf8\x57\x18\xc9\xc7\xbf\x39\x23\x02"
-  "\x1b\xff\x0a\x23\x7d\x18\xff\xfa\x30\xef\x27\xa8\x1a\xd1\x06\x74"
-  "\x1a\xb7\xb5\x84\x02\xfd\x43\xd3\x88\xd0\x15\x01\xfc\x52\x03\xbf"
-  "\x36\x6b\x49\xb7\x11\xf8\x65\x75\x90\x07\x9f\xfe\x9c\xd6\xb5\x39"
-  "\x49\x17\xf0\xea\x22\xd8\x81\x66\x6b\x2b\x9e\xd1\xfb\x69\xb3\xa0"
-  "\x7a\xfa\xd1\xa7\x35\x04\xf9\x85\xf4\x77\xaa\x47\x69\x28\xf0\x8b"
-  "\xf1\x4f\xbd\xb3\xd4\x61\x34\xc6\x2d\x3c\xfb\x39\x5d\x6b\xa1\xb4"
-  "\x36\xc1\x8e\xbe\x23\xb5\xb5\x09\x8d\x24\xba\x85\x8c\xd6\x2e\x42"
-  "\xbe\xa8\x6e\xc0\x74\xb3\xb5\x91\xa0\xdf\x4f\x36\x07\xfe\xb9\x2e"
-  "\xcc\xf1\x89\x4e\x8d\xfe\x9b\xf0\x5c\xa1\xec\xa3\xc9\x7c\xa6\x80"
-  "\xf1\xbf\xf7\x9c\x2a\xe3\xff\x27\x3a\xcd\x4b\x78\x3e\x71\xb8\x6d"
-  "\x41\x61\x14\x9b\xff\x13\x3f\x0f\x9f\x2c\xd7\x71\x6d\x22\xa5\x50"
-  "\xc7\xf1\x75\x36\x2b\xc1\x7a\xd6\xd9\x4c\x24\x23\x85\x68\xea\xba"
-  "\x5a\x49\xba\x8d\x5a\xeb\x32\xbf\x26\xd1\xe7\x71\x5d\x00\xf1\xa4"
-  "\x5a\xc5\xf9\x3d\x6a\xb7\xf8\xb9\x6e\xb2\x45\x50\xc5\xd5\xd5\x13"
-  "\x12\xba\x19\x68\xed\x20\x02\x3b\xaf\x29\x10\x15\xd0\x2b\xc1\x9c"
-  "\xd9\x4c\x80\x76\x16\xb3\xe3\x53\xa4\x67\x02\xbc\x9f\xd3\xb3\xde"
-  "\x10\x62\x6c\xc6\x34\xa4\x2d\xee\x33\x35\x27\x59\x59\x1e\xf9\x3d"
-  "\xe7\x5d\x26\x31\xa7\x75\x91\x3a\x07\x21\xf0\xbd\xa8\x0f\x62\x1b"
-  "\x01\x5f\xa3\x02\x94\xdb\xaa\x96\x61\x99\xaf\x14\xc6\xce\x46\xbb"
-  "\xd5\x69\x34\xc4\xf3\x3a\x8e\x68\x1f\x1c\x5f\x86\x04\x17\xbe\xc6"
-  "\x7c\x38\x34\x7c\x8d\xd9\x3c\xbc\xf8\x1a\x66\xfb\x55\x18\xb3\x60"
-  "\x68\xf8\x1a\x73\x94\xe3\x6b\xb4\x8d\xe3\x6b\x8c\xc9\x85\xaf\x11"
-  "\xed\x97\x0e\x5f\xa3\x4b\x38\xbe\x46\xc7\x05\x86\xaf\xb1\xf3\x86"
-  "\x65\x9e\x55\x08\x2e\x40\x5b\x1b\xf0\x25\xc9\xaf\xb1\xcd\x3e\xe0"
-  "\xcb\x4d\x7e\x05\xdf\x31\x34\x7c\xa9\xbf\x18\x66\x7c\x0d\xb3\xcd"
-  "\xad\xde\x3f\x34\x7c\x05\xdf\xc2\xf1\xa5\x5e\xcc\xf1\x15\xac\x75"
-  "\xe1\x6b\x6c\xf3\xa5\xc3\x97\x9a\x70\x7c\x8d\x35\x05\x86\xaf\xe0"
-  "\x80\xfc\x5f\xf5\x1d\x1f\x84\xda\x71\x7c\xe0\x34\x66\x4b\xf2\x6b"
-  "\xdc\x47\x83\xe3\x2b\xdb\x4d\x7e\x85\xee\x1c\x1a\xbe\x42\x7f\x3e"
-  "\xbc\xf8\x1a\xee\x71\x42\xa8\x7a\x68\xf8\x0a\xcd\xe6\xf8\x0a\x39"
-  "\xc0\xf1\x15\x9a\xe9\xc2\xd7\xb8\x8f\x2e\x1d\xbe\x42\xe2\x38\xbe"
-  "\x42\xb4\x81\xe1\x4b\xe3\xdd\xff\xb3\x3f\xf3\xda\xc2\xf8\x58\x1c"
-  "\xd3\x00\xbe\x24\xf9\x75\x77\x8e\x0f\xf8\x72\x93\x5f\xe3\xbe\x1d"
-  "\x1a\xbe\xc6\xbd\x3c\xcc\xf8\x1a\xe6\xb1\xcd\xb8\xc4\xa1\xe1\x6b"
-  "\xdc\xd7\x1c\x5f\xe3\xc2\x38\xbe\xc6\x59\x5c\xf8\xba\x3b\xe7\xd2"
-  "\xe1\x4b\x63\xe2\xf8\xd2\x64\x06\x86\xaf\xf1\x3e\xf8\x7f\xf5\x61"
-  "\x3e\x5e\x08\x2b\xc7\x71\x98\xd3\x98\x23\xc9\xaf\x47\xef\x1b\x1c"
-  "\x5f\x39\x6e\xf2\x2b\xec\x97\x43\xc3\x57\x98\x62\x78\xf1\x35\xdc"
-  "\xe3\xb1\x6b\x6a\x86\x86\xaf\xb0\x5f\x70\x7c\x5d\x93\xc2\xf1\x15"
-  "\x16\xe5\xc2\xd7\xa3\xf7\x5d\x3a\x7c\x5d\xa3\xe5\xf8\x1a\x6f\x09"
-  "\x0c\x5f\x61\x3e\xf8\xff\xf1\x71\x1d\x41\xb8\x36\x62\x68\x63\xc8"
-  "\x89\x6f\x0c\x0d\x63\x13\x57\x5e\xd9\x63\xc8\x89\x91\x43\xc3\xd8"
-  "\xc4\x57\x39\xc6\x26\x34\x72\x8c\x4d\xdc\x77\x79\xc6\x90\x13\xb6"
-  "\x72\x8c\x4d\x98\x17\x18\xc6\xae\x1d\xbe\xf5\x0f\x61\x52\xe6\xd0"
-  "\xc6\x91\x93\x26\x0d\x0d\x63\xe1\x47\xaf\xec\x71\x64\xf8\xee\xa1"
-  "\x61\x6c\xd2\x38\x8e\xb1\xf0\x39\x1c\x63\x93\x54\x97\x67\x1c\x79"
-  "\x6d\x2b\xc7\xd8\xb5\x81\xad\xdb\x08\x93\x02\x3a\xff\xd2\xff\xba"
-  "\xcd\x75\x2d\x43\x1b\x4b\x5e\xb7\x69\x68\x18\xbb\xee\xd6\x2b\x7b"
-  "\x2c\x39\xd9\x3e\x34\x8c\x5d\xf7\x0c\xc7\xd8\xe4\x12\x8e\xb1\xeb"
-  "\x12\x2f\xcf\x58\x72\xf2\x02\x8e\xb1\xc9\xea\xc0\x30\x76\x9d\x75"
-  "\xf8\xd6\x9b\xa6\xce\x1f\xda\x78\x72\xca\x17\x43\xc3\xd8\x94\x9d"
-  "\x57\xf6\x78\x72\xca\xd2\xa1\x61\x6c\xca\x09\x8e\xb1\x29\x4a\x8e"
-  "\xb1\x29\xf5\x97\x67\x3c\x19\x51\xc6\x31\x16\x91\x14\x18\xc6\xa6"
-  "\xfa\xe0\xff\xdf\xd7\x75\x32\xed\xfe\xa1\x8d\x29\xb5\xf7\x0f\x0d"
-  "\x63\xd7\x9f\xbf\xb2\xc7\x94\xd7\x9b\x86\x86\x31\xed\x3d\x1c\x63"
-  "\xd7\x27\x70\x8c\x69\x67\x5d\x9e\x31\xe5\xf5\x61\x1c\x63\x53\x1b"
-  "\x02\xc3\x98\xb6\x7c\xf8\xd6\xf7\x6e\xd4\x0c\x6d\x5c\x39\xed\x95"
-  "\xa1\x61\x6c\xda\xaf\xae\xec\x71\xe5\xb4\xe9\x43\xc3\xd8\xb4\x97"
-  "\x39\xc6\x6e\xa8\xe1\x18\x9b\x56\x70\x79\xc6\x95\x37\xa4\x71\x8c"
-  "\xdd\x10\x98\x3f\x0a\xe1\xc6\x3e\xfe\xaf\x56\xad\x49\x5d\x9e\xb8"
-  "\x2a\x5e\xbb\x6a\x4d\x4a\xf2\xd3\xda\x75\xab\x36\xac\xbc\xe7\xa6"
-  "\x67\x66\x6a\x93\xd3\xb4\xc9\xab\xd6\xfc\x5a\x4a\x88\x1f\x43\x16"
-  "\xad\x4c\x5c\x9e\x86\x29\x90\xfb\xd7\x6b\x56\xaf\x5c\x93\xa2\x4d"
-  "\x5e\xf9\xf4\x33\xab\x92\x57\xe2\xef\x75\xda\x27\xd7\x26\x43\xc2"
-  "\x8a\x95\xab\x52\x57\x6a\x9f\x78\xe6\xc9\x27\x57\x26\xaf\x1b\x43"
-  "\x16\x3e\x93\x98\xb2\x2a\x29\x71\xa5\x76\xde\xc2\x9f\xdf\xba\xf8"
-  "\xfe\x87\x16\xff\xec\x67\x18\x9c\xcc\x2d\x36\x59\x04\x35\xee\x2c"
-  "\x01\xcc\x29\x4f\x0b\x33\x27\xd5\x85\x13\x16\x1f\x77\x47\x3b\xd1"
-  "\xe4\x24\x13\x65\x76\x3b\x51\xe5\xb6\x13\xb5\xf6\x37\x24\x8a\x66"
-  "\xd7\x90\xbc\x76\x12\x46\xf3\x96\xe8\xc4\x5c\x65\x14\xcd\x55\x66"
-  "\x5a\x47\x9f\x0d\x87\x34\x8d\x98\xdd\x36\x1b\xfe\x13\x06\xb4\x55"
-  "\xd2\xdc\x91\xd6\x66\xe1\x87\x8d\xd6\xd1\xe7\x54\x19\x5f\x13\x81"
-  "\x8e\x99\xbe\xe0\x35\xd1\x2a\x54\x62\x84\x26\x68\x3b\x11\x6e\x8a"
-  "\x87\x2b\x86\x08\x37\x13\xb8\x34\x70\x45\xc0\x35\x0f\xae\x05\x70"
-  "\xc5\xc1\x95\x08\x17\x8c\x92\x6f\xce\x84\xcb\x00\x57\x3e\x5c\x05"
-  "\x44\xf8\x41\x18\x5c\xb3\xe0\x82\xbc\x3f\x58\xca\xcb\xf9\x41\x02"
-  "\x5c\xbb\xe1\xaa\x80\xab\x81\x08\x3a\xc8\xaf\x2b\x25\xc2\x2d\x3a"
-  "\xb8\x9b\xe0\xaa\x81\x0b\xd3\xed\x90\x86\xff\x4f\xe4\xef\x6e\xa9"
-  "\x27\xc2\x0c\x35\x81\x7a\x0e\x7e\xcd\x98\x09\x17\x7c\x77\x46\x2c"
-  "\x5c\xe5\x90\x06\xf5\xfd\x61\x62\xaf\x7c\x07\xdc\x7e\xd7\x0f\x52"
-  "\xa6\x35\x74\xf3\xf5\x16\x16\x03\x4f\xb8\xa9\x92\xea\x49\x10\xcd"
-  "\x3e\xa7\x4a\x9a\x41\x14\x67\x84\x9b\x72\xcd\x5b\x51\xce\x28\xa3"
-  "\x58\x4c\x47\x78\x46\x9a\x75\xe6\xdc\x64\xb4\x90\x27\x4b\x31\xa6"
-  "\x99\x7f\x78\xbb\xc9\x28\xfd\xbf\xc6\x42\x1c\x56\x16\x03\x2e\xa7"
-  "\xb2\x91\x66\xc4\xbe\xc4\x62\xbf\x01\x0d\xf1\x5c\x16\x35\x54\x2e"
-  "\xa6\xaa\x0a\xd6\xe7\x4d\x1b\x58\xbd\x56\xf2\xfe\x05\xef\xa1\x6e"
-  "\xd6\xe0\x25\x3a\xa8\xa7\x12\x9f\x69\xf6\xd9\xf0\xae\xe0\xfc\x4c"
-  "\xfc\x7d\xb1\x68\x51\x19\x35\xe6\x97\xe2\x38\xdb\x94\xfe\xdf\xa4"
-  "\x19\xfe\xd7\x15\xbc\x6b\xbe\x76\x51\x28\x6d\xe6\x65\x0b\x90\xcf"
-  "\x2e\x97\xd5\x15\xbc\x24\x92\x16\xec\x4a\xa2\xb9\x80\x21\xa9\x3c"
-  "\x11\xca\xa3\x46\x63\x8c\x45\xb8\x79\x31\xa6\xd3\xc2\x45\xd5\xf2"
-  "\x6f\xb8\xc7\xd0\xbc\x7c\x2b\xde\x43\x37\x13\x1b\x7b\xd6\x47\x11"
-  "\x7e\xd7\x10\x94\x75\x6d\xc2\xcd\x17\x6f\xaf\x27\x0a\xd3\x22\xac"
-  "\xf7\xcd\x55\x19\xf5\x54\xd4\xa6\x07\xc1\xf7\x6f\x3e\xd2\xf3\xdd"
-  "\x49\xbb\x12\x30\x7e\xaa\x98\x73\xe3\x52\x8c\xc1\x87\xff\xc5\xba"
-  "\xbd\x38\x9e\x28\xf7\xee\x22\x2a\x6c\x63\x67\xce\xcd\x56\x39\x0e"
-  "\x1d\xfe\x47\x80\xfc\x0f\xfc\x32\x83\xba\x95\xfd\x36\xe5\xed\x89"
-  "\xe3\x34\xfd\x81\xd6\x42\xba\x1a\x30\xbf\x76\x1a\xa3\xe5\x4a\xe9"
-  "\x7d\x3c\xf2\x13\xcb\x17\x73\x77\x96\xe0\x33\xc6\xb9\x0b\x05\x54"
-  "\x68\xd3\xa7\x97\x73\x1a\xe5\x97\x62\x39\x98\x5f\xcc\xdb\x0e\xbf"
-  "\x6f\x56\x8a\xd0\x5e\xa7\x9e\xe8\xb4\x6b\x48\x54\xb3\xf0\x83\x5c"
-  "\x67\xf6\xa1\x02\x78\x0f\xfd\xee\x50\x21\xe4\x37\x31\x7a\xe7\x1a"
-  "\xa3\x2c\xc2\x0f\x32\xe1\x5d\x61\x4f\xec\x4b\x4e\x67\x85\x98\x7d"
-  "\x68\x3f\xd4\xe9\x80\x45\x31\xce\x22\xb7\x81\xc9\x38\x57\x3e\x89"
-  "\xa7\x3f\x28\xb5\x8e\x3e\xb4\xbf\x3b\x95\xd6\xef\xf8\x94\x10\xf8"
-  "\x26\xed\xba\x40\x6b\x36\xc6\x50\x7b\xde\x7f\x12\x52\x13\xd7\x44"
-  "\x32\x96\x93\x88\xb1\x9b\xa9\x35\xda\x49\x42\xc7\x36\x85\xd2\xda"
-  "\x98\x26\x90\xd1\xe7\xc9\xc6\x7a\xda\x5a\x97\x54\x41\x36\x9e\x22"
-  "\xea\x4d\xab\x48\x58\x46\x0c\xb5\xa6\xd7\x50\xbb\x39\xad\x89\xd4"
-  "\xd9\xe0\x4a\xaa\x85\x7c\xc7\xe1\xaa\x20\x19\xeb\x89\xf2\x41\x90"
-  "\xa7\xe9\xe7\x89\xba\x2e\xe9\x3c\xa4\x9d\x25\x1b\xe3\xa8\xa3\xb6"
-  "\x06\xf3\x1d\x21\xd1\x0e\x6b\xe8\xa6\xb3\x44\x59\xfc\x9f\x78\xb6"
-  "\xec\x24\xd9\x0b\x75\xe9\x0a\x56\x26\x5d\xcc\x1d\x69\xef\x48\xa5"
-  "\x8e\xce\x1c\x5d\xa6\x85\xdc\x95\xe4\xd1\x16\xac\x33\xc6\x0d\x85"
-  "\xf6\x62\x1e\x31\xd7\xa8\x5b\xe6\x40\x9c\xeb\x52\x40\x16\x13\xf9"
-  "\x3d\xbe\xb3\x06\x1b\x01\x3f\xba\x92\x68\x07\xed\xc4\xfc\xd8\x6e"
-  "\xa0\x51\xa9\xd4\xfe\xd2\xa0\x24\xa2\x84\x6f\xb4\x58\x14\x61\x15"
-  "\x6e\x3c\x44\x9e\x8c\x94\xbf\xc7\xf3\xdc\xa2\xb2\x28\xae\x61\xb1"
-  "\x17\x45\xfe\xce\x8a\x79\x21\x5d\x0b\xff\x55\xf3\xfa\xe9\x5a\x31"
-  "\x4d\x92\xa5\x58\x8e\x5d\xc4\x7e\x6d\x38\xd8\xe0\x0c\xce\x2f\xa3"
-  "\x02\xb5\x03\x9e\xe7\xd3\x8e\x70\xf5\x83\x0e\x6a\x17\x73\xb7\x47"
-  "\x81\xbc\x54\x63\x9c\x54\x9e\xff\x96\x37\xe1\x7d\x8c\x36\x95\xfd"
-  "\x7e\x19\xbf\x23\x16\x2d\x2a\x41\xd9\x1a\x5d\x8f\xf9\x97\x94\xe4"
-  "\x25\x83\xec\xcd\xcd\x2f\xc1\x7e\x28\x06\x1b\x63\x2f\xee\xd9\x15"
-  "\x83\xfd\x9b\x02\xc6\xa8\x71\x49\x4c\x4f\x39\x7a\x32\xc2\x22\xdc"
-  "\x92\x46\xe1\xff\xd4\xb8\x3d\x4a\xaa\xcf\x72\x8e\xcd\x5b\x52\xb0"
-  "\xdf\x41\xbd\x1a\x21\x7d\x44\xb3\x30\x83\xe0\x19\x4d\x6a\xa8\xd0"
-  "\xb0\x58\x92\xc2\x8c\x11\x1c\x33\x07\x1b\x3c\x9e\x05\xa4\x1f\xf4"
-  "\x49\x90\x03\xdc\xbe\x98\x71\x93\xab\x5f\x70\x1c\xf3\xfe\xbd\x1d"
-  "\xea\xf4\x83\x38\x51\x1f\x24\x42\x3e\x45\x33\xa7\x83\xd0\x35\xfa"
-  "\x50\x49\x67\xce\x8c\x18\x0b\x39\xbf\xd8\x83\x9f\x39\x6f\xd9\x31"
-  "\x6e\x25\xd4\x25\x08\xca\xdc\x04\xf7\x51\x70\xdf\x7c\xb8\x1e\x75"
-  "\x2d\x2b\x77\x2c\xfe\x7e\x71\x22\xb5\xce\x5b\x48\x30\x46\x25\xd0"
-  "\x7d\x46\x81\x85\xfc\xaa\x05\xcb\xc9\xc1\xd8\x9d\x90\x86\x79\x20"
-  "\xbd\xcc\x42\x1e\x69\xe0\xe5\xdf\xbc\xd8\x86\x32\xcb\xb3\xfc\xe3"
-  "\xbc\x7c\x5e\x2e\x96\x27\x97\x5d\xf4\x3b\xda\x26\x95\x6d\x93\xcb"
-  "\xce\x85\x34\xb9\xfc\x79\xab\xe5\x6f\xfc\x30\x0c\xbe\xb1\xd4\xbd"
-  "\x0d\x7b\x7e\x47\x6d\x58\x06\xbc\x8b\xb4\x90\xe5\xfb\xf1\x5d\x36"
-  "\xa4\xe1\x7f\xdd\x30\x15\x74\x38\x06\xca\xa8\x61\x65\xc4\x5a\x48"
-  "\xdc\x2c\x77\xb9\x01\x34\x0a\x96\x65\xad\x54\xd6\x46\xb9\x2c\xb7"
-  "\x72\x24\x4c\xbd\x27\x63\x0c\xcb\x55\x63\xb9\x90\x7f\xbf\x85\x2c"
-  "\x4d\x73\x6f\x3b\xd0\x3c\x5f\x7a\x57\x0d\x74\x0f\x73\xaf\xb3\x24"
-  "\x57\xcb\xe1\xff\x0a\xa9\xac\x5c\x94\x59\xf2\x7b\x8c\xeb\x49\x73"
-  "\x6e\xdc\x8a\xfd\x06\xe4\x23\x81\x7e\x16\xd9\x99\x33\x53\xd3\x4b"
-  "\x3e\x2a\x31\x1f\xc8\xd4\x37\x59\x5c\xd3\x89\xb4\x15\xf2\xcc\xf2"
-  "\x88\xe5\x29\x90\x7b\x21\x6d\xbe\x1c\x53\x34\x0f\xf2\x80\x0d\xe4"
-  "\xd5\x67\x62\xfa\x0d\x44\x30\x17\x5a\xd0\x5e\x45\xcc\xcd\x31\x47"
-  "\xd8\x88\xb9\x50\x24\x62\xf1\xa2\xfa\xa8\x74\x6a\x02\x1b\xe5\x08"
-  "\xc6\x88\xf6\x4f\x07\xce\x64\xfb\xff\x68\x17\xd8\x71\x1b\xef\x24"
-  "\xa8\xf7\xce\x09\xb7\x9e\x37\x5b\xdb\x59\xdf\x83\xdf\x5f\xe0\xfb"
-  "\xdf\x82\xdd\x87\xb6\x1f\xd8\xdb\x09\xf9\x02\xb7\xff\x44\xc8\x5b"
-  "\x8c\xe9\x68\x1b\x82\x5d\xba\xd7\xed\x1d\x2d\x5e\x64\xe0\xb4\xbb"
-  "\xf5\x55\xa4\x23\xab\xaf\xe3\xdf\x4d\x58\x67\xb1\x70\x91\x01\xdb"
-  "\x90\x91\x46\x45\xb3\xa3\xd3\x84\xb1\x76\xb5\xa9\x68\xb7\xde\x9a"
-  "\x1d\x5d\x44\x28\xf4\x6d\x83\x7f\x6d\xb8\x95\x8d\x7f\xc1\x36\x3f"
-  "\x67\x9d\xb2\xc8\x80\xb1\x95\x77\xa4\x8f\x50\xcd\x2d\xa4\xa6\x8e"
-  "\xa9\x8b\xea\x3b\x73\x6e\xdd\x2f\xc7\xae\xf5\xb3\xdc\xfd\x72\xdb"
-  "\x8b\xa5\xb6\x43\x1a\x5b\xb3\xbe\xbd\x80\xc5\xd4\xc6\x67\xaf\x7b"
-  "\x9d\x40\xbe\x94\xe3\x7f\xa1\xed\x51\x7b\x65\x3a\x39\xac\x18\x53"
-  "\x7c\xdc\x19\xe1\xb6\xf5\xd1\x1b\x4d\x84\xf9\xc9\xcf\xdd\x5e\xee"
-  "\x5f\xbd\x6e\x63\xfb\x5f\xea\x60\x5c\x10\xed\x78\x97\x72\xb9\x78"
-  "\xdb\xcb\x0f\x4a\xe5\xe1\x3b\x99\x57\xc5\x92\xbd\x1e\xc0\x37\x4a"
-  "\x7d\x68\x97\xa6\x6f\xbb\x6e\xff\x65\xe0\xed\xba\x3d\xa2\x6f\xbb"
-  "\x6e\x5f\x3f\xbc\xed\xba\x3d\xd3\x87\x76\x69\xfb\xb6\x2b\xf2\x96"
-  "\x21\xb4\xcb\xd6\xb7\x5d\x91\xbf\x1c\xde\x76\x45\xc6\xfa\xd0\xae"
-  "\xc8\xbe\xed\xba\x43\x11\x78\xbb\x22\x6b\xfa\xb6\xeb\x8e\x5b\x86"
-  "\xb7\x5d\x77\x44\xfa\x2d\x0f\xf3\x76\x12\x2e\x0f\xef\x38\xee\xbf"
-  "\x3c\xbc\xa3\xa4\xaf\x3c\xfc\xd1\x08\x97\x3c\xbc\xf3\xdb\x80\xe4"
-  "\x61\xde\x12\xc9\xd6\xb8\xf3\xed\x3e\xf2\xd0\xb8\x24\xaa\x7f\x79"
-  "\x78\xe7\x1e\x26\x0f\x73\x97\x44\xf9\xd7\x86\x3b\xe3\x7b\xe4\x61"
-  "\xf0\x92\x28\x0f\x79\x18\xb2\x13\x74\xde\x9d\x15\x81\xc9\xc3\x3b"
-  "\x2b\xfa\xca\xc3\x3b\x23\x3c\xe5\xe1\x9d\x5e\x63\x7d\xc1\x38\x66"
-  "\x76\x7f\xf2\x30\xda\xf1\x0d\xe5\xd8\x30\xce\xf6\xaf\x3e\x3f\xf2"
-  "\xea\xff\x1d\x30\x6f\x1a\xf8\x5b\xdb\x4d\x7e\x7e\xcb\xeb\xfc\x17"
-  "\x55\x1d\xb4\x81\x0d\xa2\xd9\xf4\x32\x11\x4e\x6f\x24\x42\x5d\x44"
-  "\x23\x31\xa7\xd9\xc9\x6d\x49\x80\x09\x3d\x99\x53\x57\xd8\x46\xea"
-  "\x22\x4e\x13\x3a\xfa\xa0\x8d\xfe\x71\x45\x4c\x54\x32\x62\x73\xd6"
-  "\xd3\xe6\x14\xbb\x9f\xd8\x9c\x35\x47\xc6\x66\x9d\x03\xb0\x99\x8a"
-  "\x78\xbc\xeb\x65\x73\xdb\x19\x09\x9b\x77\xe5\xf6\xf0\x47\xcf\xf1"
-  "\xd9\x2f\x36\xa1\x4f\x78\x62\x73\x7b\x19\xc7\xe6\x5d\xbf\xea\x8b"
-  "\xcd\xed\x65\xfd\x63\xf3\xae\xbb\x38\x36\xb7\x97\xf9\xd7\x86\xbb"
-  "\x88\x0b\x9b\xdb\xcb\x3c\xb0\x79\xf3\x8a\x98\xce\x9c\xbb\x62\x03"
-  "\xc3\xe6\x5d\xb1\x72\xdb\x8b\xa4\xb6\x03\xbd\xca\x3d\xb1\x79\x57"
-  "\xbe\x57\x1e\x1a\xfe\x64\x02\x79\xa8\x3e\x23\xdc\x1d\xe7\x04\x9b"
-  "\x56\x34\xb4\xeb\xa2\x9d\xb4\x13\x63\xb4\x53\x61\x16\xa1\xcf\xea"
-  "\xd4\x9d\x30\xde\xec\xec\x4c\x50\xd1\x31\x07\xb3\x68\x77\x38\x81"
-  "\xba\x87\xd2\x4e\x5d\x08\xd0\x6c\x3a\xdc\xc7\x17\xa5\x92\x30\xb8"
-  "\xc2\x8b\x24\xba\xc2\xef\x48\xfa\x6c\xf8\x98\xbc\x54\x32\x33\xd4"
-  "\x46\x54\x50\x87\xd8\xd0\xcd\x1a\x12\xea\x20\x61\xf8\x9b\xea\xf7"
-  "\x90\xbd\x17\x88\x12\xe7\x1a\xc5\xd1\xf0\xbd\xb4\x50\x4a\xd7\xe9"
-  "\xc8\xde\x64\xa8\x8f\x40\xc2\xf7\x0a\xb4\xcc\xf9\xac\x4e\xa0\x21"
-  "\xf9\x07\xe9\x73\xb1\xac\x4e\xe2\xf4\x15\xf9\x80\xa1\x7c\x9a\x91"
-  "\x80\xdf\x8d\xc2\x58\xc1\xf4\xe6\x15\xbb\x69\x67\xf8\x98\xdc\x0b"
-  "\x64\xe6\xde\x54\x32\xbd\x38\x95\xe8\x68\xb7\x4e\x00\x1a\xc4\x3e"
-  "\xfe\xb4\x06\xf9\x1e\x4b\x05\xf8\x56\x2a\x7c\x0b\x78\xe9\xcc\x86"
-  "\x6f\x39\xe0\x5b\xdf\xc0\xb7\xce\xc1\xb7\xf4\xf0\x2d\x3d\xff\x96"
-  "\x7f\x34\xbf\xbb\x66\xa0\x39\xe1\xe8\x4d\x53\xd1\x77\xed\x57\xa1"
-  "\x69\xa3\xe6\xe3\xfc\x70\xc7\x73\x09\x7e\xe2\xfd\xc7\x5e\xcf\xff"
-  "\xec\x78\x8d\x44\x50\x55\x9b\xee\xc1\xe7\x3f\xa7\xd1\x0e\x42\x9e"
-  "\x7f\x8d\xcc\xc4\x3e\x57\x67\x3f\x0b\xfd\xac\x4d\x77\x44\xd7\xe6"
-  "\xef\xb7\x0a\xbc\x7d\x2b\x47\x4f\xeb\xbb\x23\x70\xbc\x98\x5f\xbd"
-  "\x43\xa0\x69\x5d\x11\x8b\x4c\xc7\x1a\xba\xc8\xb2\x34\x9c\x83\xa6"
-  "\x69\xda\x47\x88\xaa\x59\xb8\x77\x41\xc6\x09\x9c\xcf\x9b\x1d\xe1"
-  "\x39\x9f\x37\x3b\x8a\x08\xff\xd6\x42\x84\x9f\x86\x11\x61\x4e\x21"
-  "\x81\x7c\x9e\xd7\x3d\x0d\xd1\xaf\x4c\x25\xe9\x0e\xfa\x15\x8c\x53"
-  "\x0b\xf2\x60\x2c\x1c\x7d\x8b\xc2\x62\x4a\xc5\xf9\xad\x7f\x3b\x09"
-  "\xf4\xfb\x27\xe8\xa0\x50\xfc\x8d\xe5\x25\x25\x93\x6b\xce\x08\xff"
-  "\xd6\x14\x6a\x1b\x35\xdf\xa1\xce\x6f\x75\xc0\xf8\xad\x3b\xfc\xff"
-  "\xb1\xf7\x3e\x00\x51\x57\xd9\xe2\xf8\x99\x61\xd0\x81\x40\x50\xa9"
-  "\xd8\x56\x6d\x34\x6a\xa9\xfc\x83\x86\x65\xad\x16\x9a\x16\x96\x7f"
-  "\x48\x31\xc7\x34\xc5\xc4\x1a\x8a\x10\x01\x75\x44\x64\xc6\x91\x0a"
-  "\x58\x54\x2a\x32\x2c\x04\x2a\xdb\x47\xbd\xf6\xe5\xbe\xaf\xfb\x1e"
-  "\xdf\xdf\x73\xb7\xd9\x95\x5e\x58\xc2\xb8\xfb\x73\x7f\xb1\x3d\x7b"
-  "\x3b\x11\x12\xf9\x50\x27\x19\x63\x84\x99\xb9\xbf\x73\xee\xfd\x7c"
-  "\x98\xcf\x0c\x33\xfe\x29\xeb\xed\x6e\x51\xe3\xcc\xe7\xde\x73\xcf"
-  "\x3d\xf7\x9c\x73\xcf\x3d\xf7\x7e\xee\x3d\xf7\x85\xb4\xf3\x15\x95"
-  "\xf5\xfd\x34\x9f\x7d\x8c\xec\xc0\xb4\x3f\xc7\xa8\xcc\x38\x6f\x3d"
-  "\x9b\xc8\x58\x3c\xad\xd9\xea\x6b\xf0\x43\xb2\xe7\x72\x8f\xfc\x7d"
-  "\x2c\xe9\x07\xe9\x62\x9d\x48\x8f\x25\x7d\xdc\x25\x8d\xd9\x8e\xb0"
-  "\x5b\x78\x1f\xf0\x60\x79\xd3\x09\x18\x65\x3b\xee\x01\xd4\x69\xfd"
-  "\x2a\x8f\x96\xfa\x91\xde\xfa\xc8\x9f\xa0\x33\x17\xd4\xa6\xaf\x20"
-  "\x1a\x75\x28\x8a\xfa\x83\x17\xfb\xc3\xc2\xe3\x31\x2e\xec\xd7\xde"
-  "\xe2\x73\x10\x43\x76\x82\xe2\x22\xdb\xba\xed\xe0\x3d\x93\x38\xec"
-  "\xd5\x1c\x88\x73\x9f\x31\x8c\x70\x9c\x31\x8c\xdc\xe3\x85\xb8\x61"
-  "\xb9\x10\xbb\x37\x07\x75\x77\x1d\xf6\x8f\xd3\xd8\x3f\xba\x45\xff"
-  "\x18\xd0\xd7\x67\x7f\xe3\xa6\x33\x37\xbc\x6f\x94\x49\x7d\x63\x53"
-  "\x22\xe9\xf0\x40\xdf\x70\xaf\x4b\x54\xef\x55\x33\x40\x1a\x91\xef"
-  "\x77\x44\xd5\x15\x0f\x25\xbb\x9f\xc2\xc6\x2c\x4e\xa2\xb9\xd9\x42"
-  "\x37\x73\xbf\x8b\xb2\x08\xbf\x59\xad\x63\x3b\x2a\xbb\x3e\x4c\xeb"
-  "\x02\xdf\x9c\xee\xee\xf9\x7d\xa3\x17\x59\x75\x8b\xd8\x99\x76\xf5"
-  "\x9d\xc7\x30\x5d\xab\x7b\xf8\x67\xb1\x28\xc7\xf9\x62\x0e\x78\xf7"
-  "\x3c\x5a\x23\xb0\xab\xef\x6c\x40\x5c\x40\xef\x25\x3e\xe2\x6b\x92"
-  "\x3f\x8f\x42\x58\xf0\x20\xcf\xdd\x51\x4b\xd3\xbc\x51\x95\x8d\xd6"
-  "\x27\xfb\x78\xdf\xec\x47\x19\x74\x66\x83\x7a\x55\x37\xf2\xc6\x83"
-  "\xbc\xe9\xe5\x36\x23\x8d\xdb\x8c\xd2\xff\x30\x17\xd9\x99\x77\x61"
-  "\x66\x18\x43\xbe\x68\x6d\x46\x0f\xac\xcc\x05\xb6\xf5\x14\xf2\xc8"
-  "\xd9\x46\xf6\x65\x98\x77\x93\xb0\x21\xaf\x22\x7f\xa2\xbb\x21\x96"
-  "\x95\x9f\xd6\xfd\x4b\x71\x73\xb8\x07\xf5\x9c\xec\x48\xcc\x36\x55"
-  "\x04\xca\x6a\x58\x05\xf5\x73\xec\xf7\x31\xdb\xb8\x5d\xe3\xb2\x75"
-  "\x6f\x4a\x1c\xd7\xbf\x29\x51\x87\x9f\x31\xb2\xad\xa1\xbb\xb8\xf6"
-  "\x92\x9d\x29\xbf\xa3\x80\xec\x8c\xcd\x68\x07\x37\xf2\x72\x18\x8d"
-  "\x4b\x9b\x12\x47\x71\x9e\x3e\x81\x3c\x7d\x1c\xb4\x93\x5c\xa0\x42"
-  "\xba\x62\x91\x66\x68\x31\xb4\xd3\xba\x47\xbc\x07\xfb\x11\xf1\xb9"
-  "\x9f\x6c\x10\xea\x1a\xfa\x29\x69\xf3\xb3\x74\xf0\x7e\xe2\x9f\x81"
-  "\x62\x2b\x99\xce\xb3\xcf\x68\x4d\xd4\x66\x74\x03\x8b\xae\xec\x62"
-  "\x7c\x1d\xe9\xce\x77\x3e\x4c\x73\x41\x68\x9d\x9e\xfe\x92\x4f\xa7"
-  "\xa7\xbf\xe4\xd3\xe9\xe9\x7c\x0f\x8a\x52\xaf\xcf\x57\xa3\x5e\x47"
-  "\x29\xf5\xfa\xe7\xbf\xfa\x4e\xf5\x7a\xc1\xe5\xeb\xf5\x9e\xd3\x0a"
-  "\xbd\x2e\xfe\xdf\xd1\xeb\x8f\xf4\x5c\xaf\xc3\xfa\x47\x73\x7d\xdd"
-  "\x6f\x73\xff\x2b\xd8\xd5\xd3\xcd\xb2\xde\x1e\x7e\x9b\xf4\x76\x46"
-  "\xd3\xdf\xaa\xde\x9e\xef\x4d\xd4\xe1\xe7\x8a\xeb\x2d\xe2\xbc\x64"
-  "\xbd\xfd\x48\xdf\x07\x32\xff\x48\x7f\x59\x69\x77\xa2\xce\x04\xf7"
-  "\xa0\x9d\x98\x17\xb3\x6d\x0c\xb4\x70\x1e\xde\x3d\x4f\xf7\x30\xf3"
-  "\xb6\xab\x67\x78\x48\x9f\xfa\x2c\x8c\x79\xa3\x2a\xf4\xa6\x3f\x42"
-  "\x2c\xd6\x51\x6f\x73\xff\x0a\x62\x72\xe9\x1d\xcf\xd2\x44\x16\x3d"
-  "\xc4\x41\xef\x82\x90\x1e\x0d\xbd\xff\xf1\x94\x9d\xd6\x7a\xd0\x9e"
-  "\x78\x76\x3c\x5f\xef\x2d\x3b\x02\xde\x68\xf1\x8e\x88\x45\x9c\x8a"
-  "\xef\x2d\xbf\x7b\x9e\xfc\xfe\x22\xa8\x6f\x12\xf5\x7c\x3d\xf6\x17"
-  "\x4d\xa7\xfa\x9e\xb9\xf8\xad\x46\x3a\x4e\xe0\x77\x18\x7e\xff\x86"
-  "\xe8\xb8\xbc\x71\xee\x6e\xe1\xf3\x55\x54\x3a\x25\x3b\xb8\x8d\xf7"
-  "\xc1\x5b\x20\xfa\xa4\xf4\x1b\xe9\x39\x2e\xbf\x0f\x19\x80\xf7\xf1"
-  "\xc3\x48\x75\x23\x4f\x34\xe2\x1d\x8d\x78\x56\xe0\xdb\xcc\x9f\x41"
-  "\x33\x0a\xdb\x9f\x41\xef\x52\x51\x97\x54\xbd\xcc\x70\xb7\xf4\x3d"
-  "\x83\xbf\xd3\x41\x3e\x90\x9f\x27\xd9\x5a\xb3\xa8\xf7\x9e\x74\x1c"
-  "\x87\xdb\x94\xf5\x06\xe3\x87\x5d\x7d\x4f\x6e\xa8\xbc\xcb\xe3\xc5"
-  "\x3d\x21\xf7\x7f\xcd\x49\xf4\xb0\xcb\xc4\x15\xf2\xfc\x2b\x1b\xb5"
-  "\xc8\xbc\xb0\xc1\x63\xf5\xf6\xeb\x63\xde\x2f\x3a\x75\x99\x7e\x49"
-  "\x4a\xc8\xf9\xaf\x27\xaa\x22\x77\xe1\xcd\x63\xc0\x53\xb3\xc8\x4c"
-  "\x6b\x9d\xe4\x6b\xb5\x26\xba\x81\xfc\xad\xb7\x9e\xb4\xab\xfb\xd1"
-  "\x67\x1c\x86\xfd\x71\x81\xf3\x3d\xb6\xeb\x24\xfa\xa8\x9b\xf4\x31"
-  "\x3b\x9f\x84\xe9\xee\x33\xf1\x91\xbf\x40\x1b\xd4\x87\xf6\xa0\xef"
-  "\x8c\x21\xa6\x35\xd7\x05\xde\xbd\x8b\xcc\x36\x77\x33\xd4\x21\x1c"
-  "\xd9\x5f\xa2\xf7\xfc\x19\xfd\xb0\xf2\x1c\xe0\xef\x36\xac\x8f\xbd"
-  "\x8d\xf6\x77\xe6\xe4\xf0\xad\x68\x73\xd0\x66\x70\x3b\xfc\x0d\x6c"
-  "\x70\xdf\xf6\x5b\x32\xe6\xaf\x60\xae\xd6\xe3\x7f\x02\x53\x0b\xc4"
-  "\x9a\x36\x40\x34\xe1\xb7\xb9\x5b\x84\x5d\x5e\x86\x76\x19\x9f\x6b"
-  "\x15\x76\x99\xaf\xa9\x07\xd8\x65\xf2\xbf\x5b\x3b\xba\x60\x98\x13"
-  "\x86\x2e\x70\xc6\xb8\x8a\x9d\xcc\x4b\xfe\x38\xbd\x47\x41\x98\x61"
-  "\xb2\x8d\x7e\x05\xfd\x8e\xfe\x75\xc2\x3e\xef\x95\xec\xf3\x2b\xa7"
-  "\xbf\xbd\x7d\x7e\xc5\x82\xf6\x19\xfd\xbd\x3d\x64\x9b\xd1\x2e\xbf"
-  "\xd3\xe9\x50\xbb\xd1\x16\x5f\x9e\x6c\x67\x45\x85\x92\xed\x02\x1c"
-  "\x3f\x49\xa6\xa4\x3b\x2d\x0d\x6e\x7a\xc7\xff\x85\x67\xd8\x73\x56"
-  "\x1a\x1f\xfb\x70\x6c\x7c\xeb\xc9\x36\xf5\x30\x23\xca\x36\xf7\x3d"
-  "\xe6\xce\xd7\xc7\xb0\x7e\x7d\xb4\xa7\xa2\x22\xd7\xdd\x1f\xaf\xed"
-  "\xef\x47\xf9\xa2\xbd\xc0\xf1\x2a\xd6\xb1\xc5\xc0\x79\xe2\x1d\xbd"
-  "\xc8\xec\x7d\x76\x54\x29\x8e\x4d\xd3\x6a\x4f\x43\x32\xdb\xf1\x9c"
-  "\xdd\xbd\xe3\xb9\xee\xfe\x1d\xcf\x75\xa0\x5e\x0e\x43\xff\x11\x65"
-  "\x7e\xde\xea\xdd\x51\x0a\xde\x9d\xe5\x56\x4f\x74\x45\xae\x23\xfa"
-  "\xb9\x2e\xef\x8e\xe7\x5c\xde\x2d\xa8\x07\x85\xa4\x07\xef\x83\x6e"
-  "\x01\x8d\xc3\xf7\xde\x19\x4c\x0f\xf6\x58\x2e\x6f\x2c\x9e\xaf\x47"
-  "\x3d\x68\x43\x3d\xf8\x4a\xa9\x07\xbf\x05\xb7\x45\x1a\xa3\x97\x08"
-  "\x5d\x40\xbe\xf3\xb9\xcc\xc0\x38\xbd\xe8\xc3\xe0\xfa\x70\xfc\xd2"
-  "\xf4\xa1\xef\x8c\xbf\x3e\xd4\x7c\x43\x7d\xc0\xf1\x35\xbe\x16\xe7"
-  "\x4d\xe7\xcf\x24\xaa\x6b\x48\x1f\xfe\xec\xd3\x87\x7f\xfe\x6f\x87"
-  "\xba\xff\xb2\xf5\x61\x76\xc8\xfb\xbf\x82\xeb\x43\x69\xca\xb7\xd4"
-  "\x07\xbb\x4f\x1f\x4a\x33\xdc\x3b\x4a\xb3\xfb\x77\x94\x66\xfa\xf4"
-  "\xe1\x1c\xe9\x83\xd9\xa7\x0f\xa5\x06\x7c\x36\x0e\xd6\x87\x39\x73"
-  "\xbf\x5f\x7d\x08\x3f\xfb\xc3\xd0\x87\xfb\x42\xce\x7f\x43\xe8\xc3"
-  "\xb7\xb4\x0f\xa3\xa7\x29\xf4\x01\xed\x43\x29\xda\x87\x52\x85\x7d"
-  "\x38\x85\xfa\x50\xa6\xb0\x0f\xa5\x68\x1f\x4a\x83\xd8\x87\xfb\x97"
-  "\x7d\xbf\xfa\x70\x55\xfb\x0f\x43\x1f\x52\xa7\x5f\x9e\x3e\x94\x7d"
-  "\x4b\xfb\x30\xba\xd2\xa7\x0f\x65\x68\x1f\xca\xd0\x3e\x94\x29\xec"
-  "\xc3\xa7\xa4\x0f\x0a\xfb\x50\x86\xf6\xa1\x2c\x88\x7d\x98\x9b\xf5"
-  "\xfd\xea\xc3\xf0\x3f\xfd\x30\xf4\xe1\x81\x90\xeb\xdf\x21\xf4\xe1"
-  "\xdb\xda\x87\x2e\x85\x3e\xa0\x7d\x28\x43\xfb\x50\xa6\xb0\x0f\xbf"
-  "\x45\x7d\x28\x57\xd8\x87\x32\xb4\x0f\x65\x41\xec\xc3\x83\x9b\xbf"
-  "\x5f\x7d\xb8\xbd\xfc\x87\xa1\x0f\xf3\x56\x5c\x9e\x3e\x94\x7f\x4b"
-  "\xfb\x30\x26\xc5\xa7\x0f\xe5\x68\x1f\xca\xd1\x3e\x94\x2b\xec\xc3"
-  "\x56\xd2\x07\x85\x7d\x28\x47\xfb\x50\x1e\xc4\x3e\xcc\x2f\xfb\x7e"
-  "\xf5\x61\xf9\xac\x1f\x86\x3e\x2c\xc8\xbe\x98\x3e\xc8\xba\x40\x7a"
-  "\x41\xba\xd0\x6f\xd2\x03\xcd\x33\xde\x3a\x29\xf4\x81\xf4\x80\xeb"
-  "\x44\x8f\x3e\xc6\x83\xba\xe0\xde\x82\xba\xd0\x27\x74\x81\x78\x41"
-  "\xfa\x40\xf3\x0a\x9a\x4f\x90\x4e\x78\x70\x4e\xe1\x8e\xc6\x39\xc5"
-  "\x36\x4d\x1c\xe9\x41\x5f\xd4\x45\xe6\x15\x7d\xc0\xe7\x7e\x34\xc7"
-  "\x3b\xad\x5e\xf8\x7c\x30\x3d\x78\xe5\x32\xd7\xf8\x06\xe6\x97\x7e"
-  "\x7a\xf0\xbe\x4f\x0f\x96\x85\x98\x57\x3c\x1c\x42\x0f\xec\x97\xa0"
-  "\x07\xa7\x07\xcf\x33\xbf\xad\x1e\xf4\xad\x93\xf4\x80\xe6\x99\x5e"
-  "\x69\x9e\xf9\x18\xce\x33\xa3\x2f\x57\x0f\xd2\x0a\xbe\x99\x1e\x94"
-  "\xa5\x5c\x9e\x1e\x8c\xae\x24\x3f\x41\xe8\x41\x59\xb6\x3b\x1a\x7d"
-  "\x05\x3f\x3d\xb8\x80\xbf\xe0\xa7\x07\x0f\xed\xf9\x7e\xf5\x20\xc0"
-  "\x5f\xf8\x87\xd5\x83\x45\x21\xe3\xbf\x7a\x51\xee\x64\xef\x69\xdd"
-  "\x9e\xce\x6e\x0c\x73\x88\x75\x23\x3a\xc3\xb1\x2b\x07\x12\x68\x8c"
-  "\xf0\x6c\xd2\xc7\x54\x9c\x86\xe9\x65\x39\xa0\x71\xe7\xa3\xfc\xf3"
-  "\x40\xd3\xa7\x06\xe8\xcb\x37\xc4\x1c\xe9\x70\x88\x35\x24\xa3\x15"
-  "\xea\x10\xbe\xbf\x42\xac\x21\x79\x7a\xf4\xc3\xca\xce\x02\xdf\xf7"
-  "\x6a\x5d\xf9\x3a\xca\x76\xf1\x86\x60\xb2\x7d\xf5\x32\x6c\x7d\x9f"
-  "\xd2\xd6\x9f\xf2\x97\xad\xd2\xce\xd7\x58\x14\x6b\x48\x0b\x42\xac"
-  "\x21\x5d\x82\x4c\xf9\xda\xfe\x69\x61\xe7\x07\xd6\x90\xbe\xe5\x1a"
-  "\x7f\x3f\xda\xf8\x57\xd4\xfe\x36\xfe\x9b\xc9\x34\x3d\xed\x42\xeb"
-  "\x8e\xd4\xbf\xa9\x5f\xcb\x7d\x7a\x60\x8c\xa7\x7e\x8c\xf2\x3e\x5f"
-  "\xf1\x5c\x13\x1f\xeb\xb7\xf8\xfa\x34\xf5\x65\xea\xd7\xd4\x8f\xf9"
-  "\x58\x4f\x71\x7e\x9f\x1d\x53\x5d\xab\x58\x3b\xf2\x44\x4b\x76\x3e"
-  "\x88\x8d\xf7\x5e\xd0\xc6\x2f\x09\x2a\xff\xbf\x07\x1b\x4f\x7a\x20"
-  "\xf7\xef\xbf\xbd\xbe\xfd\x70\xe8\xfd\x5f\x97\xa4\x07\xa5\xb3\x2f"
-  "\xae\x07\xa5\x29\xa8\x07\xdd\xb5\x8a\x35\x23\x4f\x74\x29\xda\x79"
-  "\xb1\x66\x24\xf4\xc0\xb7\x66\xe4\x0d\x5c\x33\xf2\xd3\x83\xa5\x5b"
-  "\xbf\x5f\x3d\x08\x58\x33\xfa\x87\xd5\x03\x7d\xc6\xb7\xd4\x83\x4b"
-  "\xb0\x07\xa5\x68\x0f\xae\x4f\x51\xe8\x01\xda\x83\x52\xb4\x07\xa5"
-  "\x0a\x7b\xe0\x5b\x2b\xf2\x06\xae\x15\xf9\xe9\xc1\xb2\x67\xbe\x5f"
-  "\x3d\x08\x58\x2b\xfa\x87\xd5\x83\x47\x0c\xdf\x4e\x0f\xca\x2e\xc1"
-  "\x1e\x94\xa1\x3d\xb8\xbe\xaa\x56\xb1\x46\xe4\x89\x96\xfc\xbe\x20"
-  "\x3e\x9f\xf7\x82\x3e\xdf\xf2\x1d\x7f\xaf\x3e\xdf\xdf\xb6\x1e\xac"
-  "\x08\xf9\xae\xf4\x12\xf5\xe0\x12\xec\x41\x19\xd9\x83\x2e\x85\x1e"
-  "\xa0\x3d\x28\x43\x7b\x50\xa6\xb0\x07\xbe\xb5\x21\x6f\xe0\xda\x90"
-  "\x9f\x1e\x3c\xfa\xd2\xf7\xab\x07\x01\x6b\x43\xff\xb0\x7a\xb0\xd2"
-  "\xf8\xed\xf4\xa0\xfc\x12\xec\x41\x39\xda\x03\xdd\xf4\x5a\xc5\x9a"
-  "\x90\x27\xba\x1c\xed\x41\xb9\xc2\x1e\xf8\xd6\x84\xbc\x81\x6b\x42"
-  "\x7e\x7a\xb0\x6a\xef\xf7\xab\x07\x01\x6b\x42\xff\xb0\x7a\x90\x11"
-  "\x72\x5f\x85\xac\x03\x03\x6b\x00\xcc\xa7\x07\x5c\xf6\xf9\xfa\x98"
-  "\xbe\xa8\xe7\x9a\xe4\xf9\x7f\xc5\xa0\xf9\xff\x98\xea\x90\xeb\x40"
-  "\x01\xef\x97\xf9\xdc\x60\xe7\x73\x56\x31\x4f\xa8\xc8\x25\xf9\xff"
-  "\xa2\x50\xcc\x13\x75\x0f\x93\xfc\x57\x07\x97\xff\xe5\xae\x09\x66"
-  "\xa2\xfc\x3b\x2e\x20\xff\x47\x43\xcc\x13\x1e\xf9\x76\xf2\xa7\xfd"
-  "\x8e\xfd\x67\xae\xa0\xfc\xe5\x35\xc1\x4f\x41\xfd\xca\xb7\x9a\x2f"
-  "\x3e\x16\x52\xfe\x41\xf7\x93\x34\x88\xfd\x24\xb4\x97\xa4\xb5\xab"
-  "\x0b\xca\xbe\x86\xd8\x61\xd9\x42\x27\xf8\x9e\x12\xd4\x89\x8a\x93"
-  "\x30\xdd\x2d\xda\x36\xb0\xa7\x84\xe2\xa2\x0b\xbb\x60\xe5\x7b\x4a"
-  "\xe4\xf5\x80\x81\xfd\x24\x2b\x69\x3f\xc9\x9a\x6d\xdf\x7a\x2d\x80"
-  "\xf6\x93\x14\xa0\x8c\x9d\x28\xe3\x73\x24\xdf\xf7\xfd\xfa\xb5\xdf"
-  "\x1a\x40\xa8\x7d\x24\x97\xb2\xae\xf3\x1d\xec\x23\xe1\x6b\x00\x57"
-  "\xa4\x4f\x67\x86\x8c\xff\x42\x72\x24\x79\xda\x12\xdd\x7c\x5d\x57"
-  "\xee\xe3\x36\xe3\x51\x28\xeb\x83\x58\x79\xfd\x5f\x96\x29\xd9\x7b"
-  "\x86\x7a\xc0\xce\xe8\xa3\x49\xa6\xbf\xc8\x41\x3b\xbf\xce\x67\xe7"
-  "\xbd\x43\x46\x95\xee\x2d\x44\xfb\x5e\x08\xc9\x9c\x47\xc3\xca\xad"
-  "\x62\x3d\xa0\x22\x97\xfa\x3b\xf5\x67\x16\xfd\x9c\xab\x5f\xea\xef"
-  "\x42\xde\x2d\x40\x72\xe6\xf7\x67\xaa\xd7\x6e\xa0\xbe\x47\x32\x1f"
-  "\x26\xc9\xbc\x36\x84\xcc\xb9\xbc\x55\xb1\x14\x8b\x83\xce\x99\x0d"
-  "\xc8\xdc\xbd\x5d\xb1\xfe\xa3\x94\xb9\xb4\xee\xe3\xc5\xbe\x7c\x49"
-  "\xfb\x87\x2e\x51\xee\x57\x6c\x7d\x1f\xe5\x5e\x2b\xc9\x7d\x60\x7d"
-  "\xff\x5b\xc9\xfd\xf1\xd0\xe7\x5f\xfc\xe4\x5e\x9a\x72\x05\xe4\x6e"
-  "\x1f\x2c\x77\x9a\xff\x93\xdc\x4b\x33\x69\x9e\xcf\xa2\x4b\x8d\xfd"
-  "\xd2\xbe\x91\xc1\x72\x7f\xe2\xe9\xef\x5e\xee\xe1\x67\x7f\x18\x72"
-  "\x37\x84\x8c\x7f\x1e\x20\xf7\x2b\xd0\xdf\x47\x4f\x0b\x22\x77\xa9"
-  "\xbf\x97\x76\xd0\xbc\x1e\xe5\x2e\xf5\xf7\x53\x41\xe4\x9e\xb5\xf6"
-  "\xbb\x97\xfb\x55\xed\x3f\x0c\xb9\x3f\x19\x72\xff\x87\xbf\xdc\xcb"
-  "\xae\x40\x7f\x1f\x5d\x39\x58\xee\x65\x52\x7f\x2f\xcb\xa4\x79\x3c"
-  "\x8b\x2e\x93\xfa\xfb\xa7\x41\xe4\xfe\xd4\xa3\xdf\xbd\xdc\x87\xff"
-  "\xe9\x87\x21\xf7\xec\x90\xf7\xff\x06\xc8\xfd\x4a\xf4\xf7\xae\x20"
-  "\x72\x97\xfa\x7b\x59\x07\xcd\xdb\x51\xee\x52\x7f\xff\x6d\x10\xb9"
-  "\x3f\xbd\xe4\xbb\x97\xfb\xed\xe5\x3f\x0c\xb9\xe7\x84\xdc\xff\xe7"
-  "\x2f\xf7\xf2\x2b\xd0\xdf\xc7\xa4\x0c\x96\x7b\xb9\xd4\xdf\xcb\x33"
-  "\x69\x9e\xce\xa2\xcb\xa5\xfe\xbe\x35\x88\xdc\xd7\xcd\xff\xee\xe5"
-  "\xbe\x7c\xd6\x0f\x43\xee\xb9\x09\x17\x7b\x5f\x2f\xcb\x5e\x5e\xb3"
-  "\xe1\xef\x67\xd1\xbf\x97\xe5\x4d\x7a\x40\x32\x27\x5d\x50\xca\x9c"
-  "\xef\xe1\x59\x27\xf6\xf0\x90\xdf\xce\x70\x2e\xce\x86\xf0\xfd\x1b"
-  "\x2e\x3e\x6f\x97\xfc\x78\xa6\xd2\xc4\x91\x2f\x1f\xda\x8f\x5f\x3f"
-  "\x43\x96\xf7\x37\x9d\xbb\x5d\x4c\xde\x81\x73\xf2\xbf\x15\x79\x2b"
-  "\xe7\x6f\x57\x46\xde\x79\x71\xdf\x4c\xde\x65\x29\x97\x27\xef\xb2"
-  "\x0c\x21\x6f\xbe\x4f\xc3\xe8\x93\x77\x59\xa6\x90\x77\x99\x21\xf4"
-  "\x78\x9e\x3f\xe1\xbb\x97\xb7\xff\x9a\xfc\x3f\xae\xbc\x0b\x42\xde"
-  "\xff\x41\x6b\x30\x24\x6b\x92\xfb\xae\x27\x21\xe1\x17\x4f\x8a\xb5"
-  "\x15\xf7\x99\x78\xb2\xf9\x1a\x92\x3f\x9d\xf1\x19\x86\x3a\xf0\x91"
-  "\xde\x01\x7d\xbd\x7a\xa0\xb3\x3c\xb4\xef\xa2\xd5\x60\x07\x9b\xf1"
-  "\x43\x28\xcb\x83\xd8\x23\x19\x67\x61\x41\x03\xeb\xb7\x1d\xb7\xd2"
-  "\x19\x6f\x8d\xb5\xf0\x43\x60\xeb\x12\x23\x57\x3a\x41\x7d\x5a\x5d"
-  "\x70\x90\xf6\x6d\x4c\x74\x22\x4f\xe8\xbc\x0f\xca\xbc\xec\x34\xc0"
-  "\xfb\x05\x00\xba\xc7\x49\xd6\x1b\x7e\x12\xbe\x21\xc8\x39\x9f\xcb"
-  "\x59\x97\x51\xae\xbd\x06\x91\xf5\xab\xea\x2b\xb3\x37\x43\xde\x97"
-  "\xe1\xb7\x2e\xf3\x6d\xcf\x5f\x5e\xb1\xbd\x19\x1b\x42\xc6\x72\xa2"
-  "\xfd\x36\x24\x4f\xea\xd3\xee\x9d\x62\x5d\xc6\x66\x6c\x06\xda\x57"
-  "\x43\x7d\xd8\xd3\x13\xaf\xdd\x52\x80\x7d\xbd\x4d\xf4\xf5\x5f\x9c"
-  "\x45\xd8\x8c\x4f\x80\xf4\x43\xc8\xb6\x5f\xc8\xf6\x2c\xc9\xf6\x13"
-  "\x60\xf9\x89\x91\xa7\xd5\x1b\xab\x48\xbe\x24\x57\xd3\x5f\x20\x76"
-  "\x15\xc5\x45\x21\x1b\x8f\xf6\x1d\xe5\x3c\xad\xee\x49\x48\xa6\xfe"
-  "\xef\xd9\xf1\x5c\x87\x7b\x87\xd8\xa3\x41\x76\xbf\x3f\xaa\xb2\xab"
-  "\x3c\x4f\x92\xff\x23\x24\xff\x4d\x41\xe5\xff\xea\x37\x5d\x7b\x97"
-  "\xe4\xff\x8d\xcf\xf5\xfc\x6f\xf5\xf7\x75\x57\xaa\xbf\x6f\x0a\x19"
-  "\x13\xc5\x5f\x0f\xc4\x3a\xcd\xe5\xe9\x41\x6f\x10\x3d\x30\xd6\x0c"
-  "\xd6\x83\xd2\x0c\xd4\x03\xbb\xbf\x1e\x94\x66\x0a\x3d\x28\x35\x60"
-  "\xbe\x71\xb0\x1e\x6c\x1e\xfb\xfd\xe8\xc1\x25\x9e\xe7\xf9\xbb\xd7"
-  "\x83\xcd\xee\x4b\xd4\x83\x6f\x60\x0f\xce\x04\xd1\x83\xc2\x7d\x41"
-  "\xf4\x00\xed\xc1\xe8\x69\x01\x7a\x20\xd9\x83\x52\xb4\x07\xa5\x41"
-  "\xec\xc1\x96\x9b\xbf\x1f\x3d\xb8\xc4\x73\x3c\x7f\xf7\x7a\x50\x14"
-  "\x72\xfc\xf7\xd7\x83\xb2\x6f\x60\x0f\xfe\x1a\x44\x0f\x8a\xde\x19"
-  "\xac\x07\xe8\x0b\xa2\x1f\xe8\xaf\x07\x65\x92\x3d\x28\x33\x90\x7f"
-  "\x38\x58\x0f\xb6\x4e\xfe\x7e\xf4\xe0\x12\xcf\xef\xfc\xdd\xeb\x41"
-  "\x71\xc8\xf3\xbf\x01\x7a\xf0\x0d\xec\xc1\x7b\x41\xf4\xa0\xf8\x40"
-  "\x10\x3d\x20\x7b\xd0\x15\xa0\x07\x92\x3d\x28\x43\x7b\x50\x16\xc4"
-  "\x1e\x98\xee\xfc\x7e\xf4\xe0\x12\xcf\xed\xfc\xdd\xeb\x81\x39\xe4"
-  "\xfc\xcf\x5f\x0f\xca\xbf\x81\x3d\x30\x05\xd1\x03\xf3\xc1\xc1\x7a"
-  "\x50\x8e\xf6\x60\x4c\x8a\xbf\x1e\x94\x4b\xf6\xa0\x1c\xed\x41\x79"
-  "\x10\x7b\xb0\x6d\xe6\xf7\xa3\x07\x97\x78\x5e\xe7\xef\x5e\x0f\x2c"
-  "\x21\xcf\x7f\x2b\xf5\xa0\x7f\x60\xbe\xd0\xc8\xf5\xa0\xbc\x50\xe8"
-  "\xc1\x56\xd2\x83\x2e\xb1\x7f\xa7\x42\xd2\x83\x81\xb9\x42\x47\xa0"
-  "\x0e\x58\xac\x03\x3a\xf0\xa5\x6f\xae\xd0\x8f\xf2\xe6\xeb\x41\xd2"
-  "\x3c\x41\x5e\x07\xe2\xf3\x04\x9c\x27\x96\x9f\x95\xe4\xcf\xd7\x04"
-  "\xb6\x07\x97\xff\x65\xcc\x13\xfd\xf6\x68\x04\xca\xff\x6f\xfc\x9c"
-  "\xce\xa0\x75\x81\xbf\x7c\xdb\xbd\x19\x25\x97\x28\x7f\xd9\x2f\xb8"
-  "\x54\xf9\xff\x35\x88\xfc\x4b\x82\xc8\xbf\x2c\x43\xc8\x7f\x74\xa5"
-  "\xec\x0f\xc8\xeb\x42\xdc\x1f\x18\x24\xff\x67\xbe\x27\xf9\xff\x6d"
-  "\x9e\xcf\xb9\xf2\xf2\x7f\x36\xa4\xfc\x3d\xd8\x07\xf6\xaa\xbd\xfb"
-  "\x2b\xd5\xde\x46\xfc\x58\xf1\xd3\x8c\x69\xe1\x98\x76\x94\xca\x54"
-  "\x4a\x79\x9e\x72\xa0\xd8\x49\xd6\x18\x55\x06\xf1\x9b\x60\x86\xc8"
-  "\x30\x31\xdb\x20\x05\xdb\x26\xe0\xd4\x60\xc6\x74\x6b\xf4\xb6\x94"
-  "\x21\x08\xdf\xcc\xca\xef\xa9\xc0\xb4\xa1\x04\xcb\xb6\x69\xe2\x39"
-  "\xbc\x8a\xc7\xce\x94\xe0\x55\x14\x2b\xcb\x4a\xb0\x08\xa7\x95\xe0"
-  "\x38\xbd\x4c\xad\x86\xba\xc1\xb4\x45\x48\x30\x3a\xaf\x05\x74\x4a"
-  "\x1a\xa3\x55\x29\x1c\x97\x04\x17\xe9\xb1\x1c\x7d\x87\x60\x3d\xdb"
-  "\x34\x09\x4a\x38\x36\x0b\x08\xaf\x0c\x77\x95\x84\x2f\xd1\xaf\xbd"
-  "\xe3\x00\xa2\xb7\xe9\x38\xbe\xe8\x6e\x35\x48\xf4\xa1\x4e\xdc\x9d"
-  "\xc1\xe1\x55\x9a\xf1\x7e\xf0\x43\x40\xd9\x8e\x68\x36\x64\xac\x59"
-  "\x82\x4b\xf2\xaa\x81\xc7\xda\xc1\x74\x8d\x92\xd7\x12\xec\x30\x99"
-  "\x8f\x14\xd3\x49\xd9\x5e\x0f\xb6\x7f\xaf\xa0\x31\xc6\xf3\xac\xae"
-  "\x52\x6a\xcb\x34\x65\xbd\x04\x87\xe5\x26\x4b\x32\x89\xc5\x76\x4c"
-  "\x1f\xc0\x57\xb1\xb4\x5a\x86\x43\x9d\xfd\x09\xca\xc8\x6a\x33\x00"
-  "\x48\xed\x1e\xce\xca\x53\x74\x52\xdb\x53\xfc\xf9\xa8\xb2\xcb\x7c"
-  "\x44\xf9\x1d\x43\xd8\x11\x08\x33\x5b\xc6\xeb\xb1\xf0\x38\x5a\xa2"
-  "\xdd\x16\xf7\x48\xd2\x8b\x96\x2e\x80\x5a\xd1\x9e\x91\x12\xce\x54"
-  "\xd1\xe6\x58\xd8\x3b\x20\x6b\x0d\xe5\x59\x25\xb8\x38\xde\x9e\xc8"
-  "\x05\x07\x3c\x2a\xcd\xbc\xc1\xb0\x5a\x25\xec\xd5\x02\x76\x56\x3a"
-  "\xc2\xa6\x0d\x86\x8d\x55\xc2\x5e\x23\x60\x67\x67\x22\x6c\xfa\x60"
-  "\x58\xf7\x08\x05\xec\xb5\x02\xf6\xbe\x02\x84\xd5\x0f\x86\xd5\x29"
-  "\x61\xe3\x05\x6c\xda\x41\x84\x5d\x31\x18\x36\x45\x09\xfb\x13\x01"
-  "\x9b\x5a\x82\xb0\x19\x83\x61\xcd\x4a\xd8\xeb\x04\xec\x03\x55\x08"
-  "\x9b\x19\x08\x5b\xc7\xf5\x00\xc6\x49\x7a\xf0\x53\x01\x3b\x6f\x1f"
-  "\xc2\x1a\x82\xb4\x2d\x8c\xe3\x15\xb0\xa3\x04\x6c\x8a\x11\x61\xb3"
-  "\x83\xc8\x42\x09\x3b\x5a\xc0\x66\x34\x23\x6c\x6e\x10\x59\x28\x61"
-  "\xc7\x08\xd8\xf4\x6a\x84\x2d\x08\x22\x0b\x25\xec\xf5\x02\xf6\xe1"
-  "\x7a\x84\x35\x06\xe1\xaf\x0f\x36\x52\xdf\x80\x30\x45\xc8\x93\xa3"
-  "\x41\x78\xab\xc4\x39\x56\xe0\x7c\x64\x3f\xc2\x9b\x83\xf0\x56\x09"
-  "\x3b\x4e\xc0\xae\x68\x44\xd8\x92\xc1\xb0\xa0\xda\x2b\xf8\x3b\x45"
-  "\xe2\xef\x0d\x02\x7e\xa5\x15\xe1\x4b\x83\xf0\x97\xf2\xad\x52\x5f"
-  "\x4b\x10\xb0\x8b\x9a\x10\xb6\x22\x08\x7f\x95\xb0\x37\x0a\xd8\xdc"
-  "\x6c\x84\xad\x0c\xc2\x5f\x25\xec\x4d\x02\x36\xb3\x06\x61\xab\x82"
-  "\xf0\x57\x09\xfb\x33\x01\xfb\x38\xe9\x4e\x75\x10\x7a\xc7\x29\x60"
-  "\x13\x05\xac\xa1\x02\x61\x6b\x82\xc8\x42\x09\x7b\xb3\x80\xcd\x5b"
-  "\x81\xb0\xf5\x41\xe4\xa1\x84\xbd\x45\xc0\x3e\x49\xba\xbe\x2f\x88"
-  "\x3c\x94\xb0\xb7\xb2\xc8\xec\x22\xc9\x2e\x36\x04\xc2\xa2\xec\x85"
-  "\x4d\xb4\xc0\x78\x16\x99\x53\x80\xbf\x09\x8e\xc7\xca\x1f\xc0\x67"
-  "\x71\xdf\x46\xf6\x46\xb2\x61\x13\x58\xe4\x63\xcd\x12\xbe\xfd\x83"
-  "\xea\xb6\x68\x94\xb0\x13\x59\xa4\x25\x53\x82\x3d\x30\x18\x56\xab"
-  "\x84\x9d\xc4\x22\x37\x26\x4b\xb0\x8d\x83\x61\x63\x07\x60\x59\xa4"
-  "\x71\x3a\xc2\x1c\xac\x95\x6c\xa3\x82\xce\x29\x0a\x7c\x93\x59\x64"
-  "\xe1\x6c\x09\x9f\x75\x30\x3e\x9d\x12\x76\x0a\x8b\x2c\x91\xe9\x6c"
-  "\x1a\x0c\x9b\xa2\x84\xbd\x8d\x45\x16\xcd\x93\x60\x9b\x07\xc3\x9a"
-  "\x95\xb0\xc9\x2c\xb2\x38\x5d\x82\x3d\x32\x88\xf7\xd4\x0f\x2c\xe8"
-  "\x0b\x08\x9b\x34\x95\x45\x9a\x57\x48\xb0\x7e\x7e\x80\x62\x1c\xbe"
-  "\x5d\xc8\xbd\x60\x1e\xca\xfd\x18\x1f\x6f\xb6\x69\xda\x82\xf9\x18"
-  "\xb9\xb7\xc0\x55\x27\xd5\xbb\x62\xc5\x98\x24\xdf\x7b\x55\xc9\xed"
-  "\xad\xb7\x66\x51\xfd\x42\x27\x73\x2b\xd3\x76\xa9\xd9\xd1\x49\x4e"
-  "\xd0\xf0\xbb\x54\xa2\x2b\x9b\xed\x98\xee\x18\xbd\xc8\xda\x5b\xbe"
-  "\x6b\x94\x5d\xf5\x53\x2b\xc5\xf1\xc3\xdf\x89\x76\xc8\xac\xa1\xdf"
-  "\xbb\x2c\x8c\xee\xe8\x50\x79\x76\x2e\xcd\xb0\x79\xbb\xd1\x97\x63"
-  "\x2e\xc4\xe1\x42\x5f\x2e\x4c\x87\xf3\x4a\x93\x91\xf5\xd9\x8c\xdd"
-  "\xd0\xa9\xde\xf5\x34\x5b\x67\x98\x8e\x34\x98\xb1\xbe\xcc\x76\x7c"
-  "\xe6\x34\xa0\x0f\x84\x63\x65\x91\x35\x8f\xe2\x88\xee\xda\xeb\x88"
-  "\x7e\xde\xcc\xb6\x2f\xef\xca\x2d\x86\xeb\x91\x6e\xde\x57\x78\x8c"
-  "\xc1\x33\x86\xbb\xbd\xd1\x4b\x8b\x28\xf6\x20\xab\x7e\x21\x43\xc4"
-  "\x25\xdc\xc5\xef\x76\x44\x1a\x8e\xb2\x51\x8b\x2a\xbd\x7d\x25\x66"
-  "\xba\x57\xcd\x5a\x7c\x12\xda\x15\x79\x8e\x9f\xbc\xc0\x63\x16\x62"
-  "\x9b\x2a\x3d\xa5\xff\x71\xdc\xab\xfd\x8f\x36\x56\xfa\xbe\xd5\x96"
-  "\x6d\x07\x71\xe7\x4b\xe5\x32\x36\x6c\x99\xcd\x5b\xfa\x1f\x56\x4c"
-  "\xdf\x6f\x73\xf6\xf1\xf4\x76\x75\x65\x02\xf9\x97\x3d\xda\x3f\x54"
-  "\xb2\xd2\x3f\x54\x59\xaf\xeb\x83\x0e\x75\x25\xf7\x27\x28\x9d\x95"
-  "\xbd\x6f\x25\xfe\x78\xcb\xde\xdf\x1f\x16\x0f\x9a\x9e\x88\x3f\x54"
-  "\xf6\x96\x57\xce\x96\xef\x1e\x91\xeb\x22\xbc\x76\x09\x57\x88\x7d"
-  "\x1f\x31\x6c\xc7\xd2\x6a\x2c\x6b\x46\x7f\x71\x85\xe0\x71\x65\x85"
-  "\x1d\x9c\xf3\xa4\xdf\xd5\x76\xe8\x4d\x90\x7e\xef\xb3\xab\x46\xe8"
-  "\xa4\xdf\xfb\xe5\x98\x8e\xc1\x63\x4c\x2e\xcd\x46\xde\x96\x78\x5f"
-  "\xd5\x6b\xc9\xd7\x25\xff\x9d\x45\x2f\xcd\xd6\x8d\xa1\xfb\xfa\x9e"
-  "\x4f\xc5\x3a\x4b\x44\x7c\xff\xe7\xa3\xf1\x3b\x46\xfa\x76\x48\xdf"
-  "\x8c\x60\xb8\xde\x8c\x5a\x1c\xcb\x2a\x7e\xa1\x27\xde\x16\x7b\x98"
-  "\x17\xf1\x36\x20\x9f\x1a\x6d\xc6\x2e\x89\x7f\xcf\xdf\xc9\xfd\x7e"
-  "\x92\x1d\xca\x97\x45\xbc\xdf\xc8\xeb\xda\xf1\xbc\x59\x49\x17\xc2"
-  "\x40\xd2\xe4\x29\xb7\x25\x4f\xbd\xfd\x8e\x69\x77\xae\x7e\x6c\x4d"
-  "\xe6\xda\xc7\x9f\x30\x64\x3d\xf9\x54\xf6\xd3\x39\xeb\x72\xd7\xe7"
-  "\xe5\x17\x6c\xd8\xb8\xc9\xb8\xb9\x90\xe0\x06\xda\xf0\xea\x6c\x95"
-  "\x53\x0d\x58\xcf\x2c\xaa\x87\xdf\x7b\x4d\x69\x42\xfe\xcf\xd7\x68"
-  "\x74\xc1\x7d\x6b\x1b\x7a\xbb\x74\x87\x4c\xb7\xfa\xf9\xf3\x74\x9f"
-  "\x0d\xea\x99\xca\x56\x73\xbf\x95\xee\x18\xeb\x50\x3f\xdf\xdd\xea"
-  "\xb8\xdf\x4a\x77\xdc\x1d\x8a\xef\x82\x84\x71\x74\x0f\xd9\xf3\x6d"
-  "\x94\x5f\x77\x13\x40\x13\x96\x0d\x86\x73\x5c\x2c\xc4\xbf\x78\x0d"
-  "\x73\x54\x5d\xc3\xba\x09\x7f\xd5\x6e\xd6\xe5\xd8\x62\x80\x9d\xf8"
-  "\x8c\xba\x1e\xdb\xa9\x7e\xe1\x57\x87\x46\xf1\xbb\x9a\x46\xd5\xee"
-  "\x66\x1d\x25\xd7\xb0\x8e\xed\xbb\x59\x77\xdd\x35\xcc\x9e\x50\x05"
-  "\x51\xbd\xe5\x2f\x64\xd8\xd5\xcf\x37\xf2\x7e\x83\xf9\xde\xc8\xe7"
-  "\xf5\xbb\x30\x6f\x92\x1b\xc2\xea\xf0\x19\xd3\x9c\x87\x74\x82\xee"
-  "\x77\xcf\xba\xc2\x11\xdf\x6c\xd6\x9f\xad\xda\x89\xf5\x08\x39\xbd"
-  "\xf0\xc7\x26\x1c\xc9\xb1\x3e\x87\xcd\xd5\x0e\x76\xf5\x0b\x47\xeb"
-  "\xbe\xe6\xf5\xc5\xd8\xaa\xbb\x81\xf0\xfd\x4b\x9e\x2b\x3c\xff\x3a"
-  "\xe6\x46\xd8\xfd\xde\x2d\xd9\x2a\x84\xa9\x40\xdc\x4e\x65\x7b\x12"
-  "\x1f\x7f\xba\x40\x97\xb3\x21\x3b\xfb\xe6\x48\x48\xe4\xdf\x7e\xf7"
-  "\xe3\xd1\x7d\x49\xf0\xe2\x6e\xd6\x84\xed\xb4\x62\x7b\x9b\x5b\xd0"
-  "\x83\x47\x9d\x01\x6c\x53\x65\xa7\xfa\xc5\x1b\x31\xfd\x20\xfe\x3e"
-  "\x88\xb4\x37\x8b\x3b\xd5\xf6\x3d\xc4\xca\x5f\x38\x8e\x74\x36\xd3"
-  "\x3d\x1b\x14\x93\xb6\x67\x53\xba\x0a\xdb\x5d\x85\x70\xcd\xba\xeb"
-  "\xe0\x46\x2c\xf7\x2b\xa4\x63\x1f\xfe\x26\xf8\x65\x24\x47\x84\x6f"
-  "\x12\xed\xda\x37\x93\x9e\x91\x57\xd6\xbd\xd7\xb0\x8a\xde\xf2\x17"
-  "\x4b\x29\xd6\x36\xbf\x93\x08\x9f\x91\x2f\xcd\x08\x5b\xd9\x63\x4a"
-  "\x57\xe1\x5c\x50\x55\xe7\xc3\xa9\x27\x9a\x88\x0e\x9a\x5f\x7e\x84"
-  "\x1e\x9c\xb7\x5f\x0f\x13\x5c\xa0\xfa\xa8\x03\xa0\x66\x37\xab\xc7"
-  "\x4f\x0d\x7e\xaa\x3f\xc4\xbc\xc3\xf8\x69\xc6\xf4\x23\xf8\xfd\x21"
-  "\x7e\x1f\xc6\x0f\xce\x4f\xe3\x89\xee\xfc\x22\xd6\x35\xa9\x1a\x6e"
-  "\x20\xfc\xa8\x5b\x4b\xdb\xd5\x6f\x34\x10\xed\x14\xcb\x9e\x45\x56"
-  "\x05\xc4\xff\x7e\xa9\x12\x30\x1f\xbf\xf7\x89\x6f\xe5\xe7\xa5\x6e"
-  "\x50\xef\x8e\x12\xbf\x77\xa7\xe3\x73\x91\xf4\xdb\x80\x9f\x82\x8b"
-  "\x7f\x02\xf1\x85\xfa\xec\xb6\x5f\x3a\xec\xa5\x7c\xf6\x8d\xba\x34"
-  "\xb8\xea\x6a\x9c\x11\x3b\x40\xfd\x6a\xa2\x7f\xfa\xab\x20\xd2\xea"
-  "\x8e\x88\xe7\xba\x36\xf1\x5d\xaf\xc1\x0f\xf2\xe9\x35\xc4\xff\x5a"
-  "\x8a\x48\x7b\x6d\x1e\x7e\x57\xe1\xa7\xde\xbf\xfe\x7d\x58\x7e\x5f"
-  "\x32\xc9\xb3\x9f\xee\x77\x43\x59\xda\xd5\x2f\x76\x93\x8c\x76\x09"
-  "\xdd\x52\x79\x19\x4f\xeb\x42\xdd\xaa\xf1\xe9\xcf\x4b\x9f\xfa\xeb"
-  "\xcf\x4b\xcd\x01\xfa\x53\x49\xf6\x08\xcb\x25\xd7\x09\x7d\x39\xd8"
-  "\xb3\x25\x13\x9f\x5f\x3a\x82\x78\x0e\xd2\xba\x47\xa7\x7a\x37\x9f"
-  "\x87\xed\x3a\x89\x73\x4f\x03\x68\xc8\xbe\x74\xab\x77\x8f\x26\x9d"
-  "\xa5\xba\xa5\x7a\x05\x2d\x48\x1f\xa6\xd5\x13\x7d\xeb\x10\x2f\x3e"
-  "\xef\x43\xb8\x7a\x1b\x9c\x95\x69\xe3\x65\xca\x9f\x44\x7d\x94\xe8"
-  "\x25\x9c\x54\x8e\xf9\xda\xd5\x45\x65\xa4\xba\xff\x88\xe9\x34\x57"
-  "\xa5\x33\x4d\x61\x36\xb7\x1d\x48\x27\xe9\xdb\xe6\x4e\xc2\xbe\x94"
-  "\x0a\xde\x5e\x3d\x4c\x8a\x87\x24\xec\x6f\x11\xed\xea\xdd\x07\x26"
-  "\x16\x41\x12\xe1\x23\xbb\x6e\x57\xef\x36\xd6\x51\x5f\x14\xb8\x0e"
-  "\x53\x3b\x08\xff\x87\xb9\xc0\xeb\xa9\x25\x7a\x30\x5f\x51\x6f\x15"
-  "\xcd\x45\x77\x15\x8a\xb6\x62\x5d\xfb\xb0\xfc\x7e\x6a\x3b\xf1\x13"
-  "\xf3\x1b\x3b\xd5\x2f\xc7\x52\x1e\xbf\x0f\x48\xb4\x67\x1f\xdd\x19"
-  "\x41\xfc\x20\x78\xba\xb3\x51\xc4\xfe\x7e\x71\x2a\xe7\x1b\x96\x27"
-  "\x79\x30\xac\x83\x70\x98\xdc\xcc\xcd\xd0\x1e\xbd\x51\xe8\x42\xdf"
-  "\xa2\xba\xcc\x5f\x3e\x2f\x1b\x94\xf2\xc1\x72\xfb\xb1\x7c\x13\xc3"
-  "\x36\x92\x3d\xc1\x3a\x63\xe8\x9e\x38\x4c\xab\xf4\x96\x23\x8e\x8d"
-  "\x2e\xbe\x56\x83\x78\x36\x23\x2d\x95\x84\x07\xe9\x69\x92\x70\x1d"
-  "\xf8\x7d\x91\xbf\xac\x25\x7c\xfb\x48\xe6\xbc\x3f\x17\xf2\x36\xa1"
-  "\xed\xaa\x9e\x5b\x2b\xf2\x1a\x11\xa6\x91\xf5\xa7\x02\xdd\xc1\x20"
-  "\xc6\x12\x9e\x77\xc0\x74\x9e\xcb\xb7\x49\xd8\xb5\xea\xac\xfc\xad"
-  "\xac\xcb\x47\x77\xb5\x4e\xbe\xc7\x42\xa2\xfb\x00\xd5\xc7\x36\xad"
-  "\xe0\x63\x2b\xd5\x41\xe5\x05\xbe\x97\xdd\x84\x4f\xe6\xd5\x44\xa4"
-  "\x43\xf0\xeb\xe5\x24\x4c\xdf\x47\xba\xc8\xf9\x86\x76\xb4\xc7\x44"
-  "\xba\x58\x9d\x80\xe5\x0f\xee\xa4\xe7\x4d\xf4\xfc\x72\x23\xb7\xb1"
-  "\x03\xf9\x2f\x67\x53\xbe\x0d\xe7\xfa\xbb\x9e\x42\x5d\xf2\x02\xdc"
-  "\x10\x07\x49\x4e\x0b\x6f\xdb\x3b\xce\x2d\xb3\x55\x87\xdc\x00\x44"
-  "\x27\xf2\xa8\x11\x69\x3d\x82\xb6\x9f\xdf\xd5\x87\xf6\xfa\x00\x7b"
-  "\x43\x0f\x44\x33\xda\x33\x89\xbe\x3d\x33\x24\xd9\x1f\xa0\x36\x12"
-  "\x3f\x27\x0a\xdb\x87\x79\xaf\x7c\x46\xb4\xfb\xda\xbd\x27\x5e\xc9"
-  "\x63\xde\x6e\x94\x03\xc9\x8b\xe4\xe2\xc3\x59\x4d\xba\x5f\x89\xb8"
-  "\xa4\xfb\x17\x85\x6e\x10\xaf\x2b\xaf\x61\x47\x08\xde\x07\xfb\xca"
-  "\x43\x94\x57\x8c\x75\x4f\xca\xc5\x31\x1d\xfb\x05\xdd\x45\x82\x78"
-  "\xdf\xa1\xfb\x38\x11\x07\xf7\x21\x10\xee\x4d\xd2\x47\x7c\x3e\x22"
-  "\xd1\xbd\x0f\xc7\xf3\xf1\xf8\x99\xee\xeb\xff\xaf\xbc\xe4\xaf\x5f"
-  "\x7b\x02\xfb\x3f\xc9\xbb\xd2\x6b\x4a\x05\xae\x0f\x79\xa0\x3b\xad"
-  "\x7e\x65\xb2\x34\x76\x48\xb2\x7e\xe5\x99\x43\xd8\x5f\x7c\x38\x5e"
-  "\x89\x0a\x90\x75\x23\xd7\xc7\x4d\xf3\x54\xd4\x66\x2c\xdb\x28\xf0"
-  "\xec\xe1\x6d\xe6\xfa\x64\xe1\x3a\x70\x84\x6d\xc2\x76\x0e\xe8\xc1"
-  "\x1e\x83\x24\xe7\x23\x01\x3c\x91\x6d\xd7\x01\xba\x33\x8e\x6c\x12"
-  "\xfa\xb9\x77\xf7\xf6\xfb\xec\x12\xc9\xde\xcb\x65\xff\x4a\x6c\x9d"
-  "\x18\x6f\x25\xbb\xb5\x47\xe4\x5f\xe3\xa7\xc3\xd4\xa6\x39\x5c\x7f"
-  "\x89\x16\xd3\x0a\xa2\xa5\x91\xd3\x61\xd2\x01\xe6\x1d\xa4\xfa\x11"
-  "\x57\xaa\xd4\x5f\x65\x5c\xa3\x08\xd7\x76\xb4\x55\x44\x13\xd6\xdd"
-  "\xc0\xed\xdf\x7d\x44\xdb\xab\xa3\x25\xda\x9b\x5d\x16\x2a\xbb\x3b"
-  "\xf6\xbc\x9a\x97\xc5\x79\xc1\x4b\x25\x2e\x71\xaf\x4c\x24\x96\x6f"
-  "\xa0\x58\xfe\x9d\xea\xba\x22\xb2\xd1\xf4\x1e\x09\x7f\xaf\xa5\x33"
-  "\x9f\x68\x53\x34\x88\x4f\x4b\x3a\x2a\xeb\x45\xb7\xba\x6e\x09\xcd"
-  "\x19\x90\xd7\xef\xa0\x8f\xd4\x40\xfc\x26\x5d\x46\x1f\x29\xb9\xb7"
-  "\xfc\xd5\x12\x59\x6f\xb1\x9e\x1a\xe2\xbd\x90\xcf\xab\x87\x51\x8f"
-  "\x1b\x7d\xba\xf5\xea\x61\x89\x8f\x0d\xc8\x47\x2d\xd6\x37\x57\x6a"
-  "\x57\x03\xc2\xa3\x2f\x56\x77\xa7\x44\x7b\xb5\x04\x7f\x42\x96\x83"
-  "\xd4\x57\x8f\xec\x24\xfb\xcb\x65\x50\x53\x24\x95\xdd\x27\xea\xaa"
-  "\xd9\x2a\xc3\x92\x8f\x28\xee\x8b\xaa\xd9\x4a\x76\x70\x12\xca\x9e"
-  "\xdb\x3e\x7e\x57\xad\x48\xa3\xbe\x23\xea\xa8\xbb\x91\xeb\x21\xfa"
-  "\x3d\x3e\x3d\xaa\x49\x0f\xb0\x4f\x64\x8b\x2b\x5b\x11\x07\xd9\x53"
-  "\xd2\x25\xb2\xa9\x34\x67\x41\x7c\xe3\xa5\xfe\x23\xd1\x5c\xf3\x7b"
-  "\x7f\x5d\xa9\x1b\x8e\xba\x32\x41\x81\x7b\x7f\xb0\x71\xae\x4e\xd8"
-  "\xc0\x1a\x51\x66\xaf\x4a\x6a\xdb\x3b\xa2\x6d\xd2\x33\xf1\xad\x98"
-  "\xf8\x56\xfb\xbe\x82\x8f\xc8\xb7\xda\xc9\x12\x7c\x23\xd9\x72\x5f"
-  "\x7f\xdd\xfb\xb4\xdc\x97\x07\xdb\x8b\xda\xb1\xd4\x1f\x7c\x74\xed"
-  "\x4d\x0d\xb0\x17\x8d\xc1\xed\xc5\xde\x78\xa9\xbd\xf5\x01\x7d\x63"
-  "\x9f\xa0\x5d\x1a\x5b\x50\x0e\xad\x38\x27\x13\x77\x23\xbd\x38\x95"
-  "\xec\x27\xd5\xad\x1c\x83\x6a\x05\x5f\xa5\xbe\x5c\x1b\x3d\x58\x0e"
-  "\x7b\x8f\x2b\xfb\x33\xc9\x9a\x6c\x02\xe1\x20\x99\x72\xbf\x12\xd3"
-  "\x84\x5c\xf7\x1e\x20\xdb\xa0\xb4\xd1\x08\x5b\xe5\x65\xd4\x5f\xf6"
-  "\xda\xfd\xfb\xe2\xde\x79\x52\x5f\x94\xeb\xfe\x35\xca\x28\xc9\x57"
-  "\x6f\x6d\x7a\x40\xbd\x24\x9b\x26\xe2\x83\x68\x63\xed\x5e\x79\x4c"
-  "\x23\x78\x2c\x6b\xc4\x32\xa5\x01\xe3\x63\x25\xd1\x87\x75\x71\x1f"
-  "\x9c\xe8\x41\x5b\x61\xec\xe5\xf4\xd4\x56\xd4\x49\xe3\x04\xa6\x25"
-  "\x49\x69\x7a\x69\x2c\x91\xf4\xa6\xd6\x13\x40\x53\x57\x70\xff\x68"
-  "\x2f\xc8\xfe\x11\xc7\xc5\x6d\x51\x6d\xb7\xd4\x3e\x4a\x9b\x20\xd2"
-  "\x6a\x0e\x50\xda\x4e\xc1\x87\x2a\xc6\xc7\xab\x1a\xbd\x34\x5e\x51"
-  "\xff\x52\xdb\xd5\xaf\x36\x53\x1f\xa3\x67\xbb\xba\x2e\x85\xf0\xdb"
-  "\xcc\x7d\x44\x7f\x35\xe6\x65\x92\x3d\x20\x7b\x41\x7b\x53\xf9\xf7"
-  "\x02\xfe\xbd\x83\xec\x0e\xf9\x21\x94\x8f\x70\xe9\x64\x8b\x30\xfd"
-  "\x35\xdd\x03\xe8\x17\xfc\x8f\x16\xf1\xd6\x95\x48\x65\x7f\xc3\x7d"
-  "\x85\xff\x49\x0d\x93\xd3\xe4\x72\xd8\xd7\xd7\x52\x39\x2a\x2f\xdb"
-  "\x2f\xb2\x5d\x6e\xb2\x4d\xa2\xbe\xf3\x92\x8e\xf3\x79\x83\xec\x17"
-  "\xf5\xab\x15\xb0\x74\xa7\x0c\xb7\x69\xf5\xb3\x85\x3d\xab\x9f\x4a"
-  "\x65\xb9\xfc\xd0\x56\x16\x9f\x67\x9f\xd5\xe5\x81\xa6\xf6\x2c\xf7"
-  "\xb1\x92\x05\x9d\xf5\x95\xa2\x1d\xf5\xcb\x78\x3b\x84\x4d\xad\x14"
-  "\xb4\xbc\x98\x5c\xdb\xc7\xf3\x36\x50\x5b\x28\x6f\x97\x22\x8f\xf5"
-  "\x27\x52\xde\xf3\x9c\xae\x80\x72\xde\x7e\xc3\x20\xf8\x3a\x71\x27"
-  "\xb0\xb6\x76\xb7\x6c\x7b\x5f\x8b\x95\xe8\x6c\x91\xed\x2e\xf2\x65"
-  "\x05\xd9\x5e\x9e\xf7\xb8\x04\xb3\x40\xfa\xe6\xf6\xbd\xde\x23\xf8"
-  "\x1a\xaf\x96\xf8\x9d\x29\xda\xf1\xda\x70\x3e\xcf\xfe\x1f\x3d\xf2"
-  "\xb6\xde\x29\xf3\x56\xf9\x9b\xfa\x0f\xd6\x4f\xe3\x92\xb0\x2b\x45"
-  "\x7c\x0e\x5b\x43\x30\x44\x93\x18\x23\xea\xba\x03\x7d\xea\x4e\xf5"
-  "\x1b\x65\x34\x2e\x09\x5f\xf5\x8d\x2c\x69\x0d\x08\xac\x79\xaf\xe3"
-  "\xb8\xf0\xda\x01\xd9\xc6\xb0\xde\x54\x9c\xf3\xb7\x13\xad\xfc\x3e"
-  "\x0c\xba\x27\x44\x09\x43\xf6\xe9\xdd\x3e\xbb\x84\xf3\xb5\x4a\xd9"
-  "\x6e\x90\x2d\x69\x75\xb6\x4b\x3e\xdd\xeb\x29\xb5\x92\x2d\x39\xad"
-  "\x7e\x7d\xa6\xbf\x1f\xf6\xfa\x4c\x7f\x9b\xf1\xc6\x92\x40\x9b\x81"
-  "\x7e\x73\x49\x6f\xf9\xeb\x71\x7e\x7e\x00\xa6\x5d\xd8\x76\xbc\xd6"
-  "\x45\x7d\x94\xee\x89\xe3\xf6\x89\xaf\x6b\xbd\xfe\x96\x4c\x33\xd9"
-  "\xcd\x9e\x2d\xf2\xfa\xc5\x1b\x73\xc8\x57\x0b\xa8\xaf\xc4\xcf\x76"
-  "\x52\x7d\x32\x3e\x0d\xd0\x3d\x63\xc8\x07\x5a\x73\x79\x3d\x5d\xb2"
-  "\xf3\xf5\x7e\xb6\x52\x1a\xc3\xc8\x4e\xfa\x8f\x55\x2f\x4e\xf5\x1f"
-  "\xab\xde\x98\x3c\xd8\x46\xbe\x01\x97\x3e\x56\xbd\xde\x46\x76\x4b"
-  "\xb6\x91\xfe\xb6\xe0\x0d\x4d\xad\x9f\x2f\xfb\x7a\x85\xec\xcb\xfa"
-  "\xec\xe8\xeb\xa3\xc8\x46\x61\xfd\x8d\x52\xdd\x45\x76\xf5\xf3\x66"
-  "\xb9\x6e\x3b\xca\xb9\x55\x87\xba\x59\xfe\x42\x17\xfe\xce\x90\x7c"
-  "\x40\xde\x37\xfb\xf8\x9d\x44\xf5\x74\x87\x53\x24\xe9\x99\x35\xe7"
-  "\x2c\x74\xf8\xc6\x8a\xa6\x9e\x75\x32\x7f\xf7\x45\x2b\xfd\xc2\xbd"
-  "\xbb\x59\x29\xd6\xd3\xa1\x6c\xe3\x0e\x4c\xdb\x25\xad\x21\x70\xde"
-  "\x72\x5c\x6f\x34\xd6\xed\xf6\x6f\x9b\x68\xc7\x1b\xdd\xd4\x0e\x9a"
-  "\x13\x61\xfd\xef\x90\xdf\x83\x3e\x1f\xfe\x7e\x35\xa9\x6e\x40\xe7"
-  "\x5f\x2a\x39\x6f\x51\xfa\x57\x2f\x92\x3f\x7e\x50\x9a\x7b\x36\xa3"
-  "\xbf\x53\xa9\x5c\x8b\x99\x7f\x6f\x9a\x2e\x37\x2f\x2b\xa7\xe0\xf1"
-  "\x29\xba\xac\x9c\xac\x82\xac\xd5\xd9\x59\x85\xab\x0b\xb2\xd6\xe5"
-  "\x8c\x7f\x7a\xf5\x13\x59\x6b\x74\x9b\x56\xe7\xeb\x92\x8c\x37\x1a"
-  "\x23\xc1\x07\x7a\x97\x6e\x75\x7e\xfe\x86\xa7\xd7\x66\xea\x72\xb2"
-  "\xd6\x4c\xc8\x5b\x9b\xbf\xb6\x40\xb7\x3a\x6f\xdd\x86\x9c\x4c\xdd"
-  "\x8d\x99\x13\x6f\x4c\xba\x3d\x33\x52\xb9\x86\x36\x2e\x16\xba\xbd"
-  "\x5f\x7f\xd9\xb5\xeb\x6b\xd0\xc6\xa8\x72\xf3\x62\x8c\x59\x39\x62"
-  "\xdd\xee\xcd\x25\x93\xaa\x20\x97\xee\x89\xa7\x3b\x8f\x59\xf9\x3e"
-  "\x03\x7e\x6b\x08\x0e\xdb\xa9\xa3\x7b\xe2\x91\xf6\x51\xbd\xe5\x6f"
-  "\xc6\xdb\xd5\x6f\x71\x9e\x21\x2f\x74\xd8\xb6\x51\xec\xeb\xc3\x5d"
-  "\xe8\xb3\xe5\xd2\x3b\xf3\xba\xaf\x21\xae\x72\x23\x68\xf0\x13\x85"
-  "\x9f\x58\xba\x47\x1e\xcb\xcc\xb3\xab\x7f\x69\x10\xf7\xbe\xbc\xd9"
-  "\xed\x88\x38\x54\xcd\x4a\x0f\x49\x7e\xcd\x9b\x5f\xca\x6b\xcd\x0b"
-  "\x9f\x81\x85\xa4\x9f\xed\xea\x37\xbb\xb8\xac\x50\x97\x69\xcd\xb6"
-  "\xe7\x77\xb3\x52\xd0\x1f\x3c\x4e\x6b\xae\x98\xf7\xa5\x53\x0d\x51"
-  "\x48\x97\xe6\x50\x51\x12\xbc\x88\x75\xe5\xc7\x33\x86\x75\xec\x97"
-  "\xd7\xd3\xb0\x0d\xb1\xd8\x96\x36\xa9\x1d\x2f\xf2\x76\xec\x66\x09"
-  "\x55\x23\x90\xbe\x17\x38\x3d\xc7\xe5\x36\x20\xdd\x6d\x48\x53\x0a"
-  "\xd2\x19\x4b\x74\x05\x5b\xeb\xa3\xf5\xae\x4e\xf5\x2f\x6f\xf4\x6e"
-  "\x44\xbe\x8d\x11\xf7\xdc\xed\xaa\x15\xfd\x0f\xdb\xb5\xa2\x0e\x7f"
-  "\xef\x3c\x0b\x51\x3b\xe8\x8e\x72\xcb\xf5\xac\xc5\xe9\x06\x9b\xa1"
-  "\x0d\x62\x36\x33\x07\xfb\xb7\x2f\xbb\x44\x9b\x7e\x99\x46\xb6\xe1"
-  "\xff\x3c\xd9\xa6\xa1\x36\xe1\x58\x11\x55\x77\x36\xe4\xda\xa2\xe6"
-  "\xc5\x6b\x98\x93\xbd\xaa\xf4\xb9\x7e\xf9\x7f\x89\x27\xe4\x6f\xf5"
-  "\x58\xe8\x5e\xeb\x5f\xd6\x23\xdd\x2e\xc9\x37\x76\xb2\xfe\x15\x0a"
-  "\x5f\xea\x97\xa4\x67\xce\x10\xb8\xb5\x32\x6e\xba\xfb\x9c\xca\x08"
-  "\xf9\xff\xd3\x8d\x58\xc6\xe1\xc3\xff\x4f\x10\x88\x9f\x70\xe2\x6f"
-  "\x87\x5c\x8f\x98\x87\xff\x92\x7c\x02\x07\xea\xb2\x23\x44\x7d\x09"
-  "\x2f\xec\x66\xc7\x6c\x98\xbe\xeb\x3c\x68\x10\xf6\x58\xdd\x6e\x8e"
-  "\x3f\xc3\xae\xde\xd7\x44\xf8\xb7\x5f\x03\x50\x82\x30\x3d\xe5\x6f"
-  "\xba\x9c\xfc\x1e\xf2\x7f\xc2\xfe\xff\xc2\xa0\xb5\x6c\x49\x9f\xef"
-  "\x0a\xd0\xe7\x94\x17\xc8\x27\xac\x42\xfc\xa8\x43\xbb\xce\x01\xd9"
-  "\x9b\x23\x13\xab\x20\x91\xea\xc1\xdf\x47\x69\x3d\x04\x71\x1e\x95"
-  "\xeb\x63\xa8\xff\x3b\xbd\x62\x0d\x46\xd2\xad\xf1\xb4\x7e\x6d\x32"
-  "\x32\x76\x08\xed\x3b\xd1\x48\x3a\xd6\x5b\xde\xa0\x91\x75\x0a\x75"
-  "\xfd\x18\xd7\xab\x38\x48\x64\xe5\xff\x54\x5a\x37\x02\xe1\x50\xaf"
-  "\x6a\x51\x9f\x48\xaf\x10\x36\x49\xd6\x29\xd4\xb5\xa3\x04\x87\x34"
-  "\x44\xee\x2f\x4c\xd1\x90\x8d\xec\x50\x37\xbc\x49\x3a\xc6\x5e\x7e"
-  "\xb0\x8d\x5d\xbb\xbc\x4d\xc8\xa9\xe1\x4d\x9b\x4b\xc8\xc0\xc7\xf7"
-  "\x06\xa3\x82\xef\x47\x51\x8f\x23\x89\xcf\x62\xad\xba\xe1\x4d\xa4"
-  "\xed\x28\xf7\xc5\xb7\xa2\x0c\xf8\x58\xd5\x90\x49\xe5\x25\x1e\x1e"
-  "\xf1\xf1\xb0\xc1\x1a\x8c\x87\x01\xbc\xd3\x88\xbb\xce\x1b\x8e\x50"
-  "\x5f\xc1\x32\x4e\xf9\xfe\xf2\x60\xb2\xc4\x3a\x34\x9a\x2a\xd0\x52"
-  "\x1d\x4d\x71\x04\xff\x56\x42\xb0\x3a\x02\xf5\xb8\xa9\x1e\x80\xd6"
-  "\xc2\xa9\x5c\x42\x1c\xf1\xf5\xad\x15\x41\xe5\xbb\xc6\x8f\x36\xfe"
-  "\x61\xe5\x6f\x19\x5e\x1c\x81\x7a\xc3\xe9\x7b\xab\xea\x42\xf4\x25"
-  "\xe8\xc4\xb8\x68\x1d\x47\xfa\xfc\x56\x8b\xad\x1a\x80\xd2\xa4\xe7"
-  "\x83\x3d\x38\xd6\x04\xae\xe7\x87\x7e\xbf\xf0\x76\xb4\xff\xfb\x85"
-  "\xb7\xdc\xa1\xde\x2f\xf8\xd7\xfb\xf6\x5c\xaa\xd7\x5b\x97\xae\xf2"
-  "\xd5\xfd\x76\xb2\x37\x48\xdd\x72\xf9\x89\xf5\xca\xf9\xcb\xdb\x7b"
-  "\x88\x86\x56\x1c\x97\xd8\x4f\xd3\x55\x0c\xf1\x34\xf1\x31\xfb\xed"
-  "\x6a\xe1\xaf\x90\x1f\xf4\xb6\x91\x60\x02\xdb\x31\xf0\xa7\x8d\xa3"
-  "\xb9\x22\x9c\xe7\x0f\xe1\xf7\x01\xbd\xf1\x83\xeb\x0c\x72\xb6\xda"
-  "\x0f\x18\x58\x90\x87\x28\x80\x9f\x72\x78\x86\x7f\x22\x49\x7a\x76"
-  "\xf0\x07\xcd\x00\xfc\x40\xfe\xb7\xf8\x8b\x10\xf4\x72\x7c\x2e\x50"
-  "\x49\xf5\x95\x2a\x20\x66\x5f\xa0\x34\x03\xb9\x48\xb0\xbf\xf5\xf8"
-  "\x31\xa7\x87\x23\xbe\x06\x0e\xcc\x98\x5b\xc2\x2f\x3f\x33\xe5\x33"
-  "\xa5\xf8\x3f\xe3\x5f\xd8\x0a\x45\x05\xd7\x87\x65\xf2\xed\x4e\x63"
-  "\x9a\x07\x92\xd4\xf5\xb1\xfe\x95\x9a\xc3\xf9\x57\x0c\xfd\x63\x44"
-  "\x7c\x89\x98\xff\x53\x1f\x7c\x98\x73\x9b\x02\xf8\x23\x41\xfe\xe8"
-  "\xd0\x6d\xb8\xfc\xbf\x31\x8a\xdf\xd7\x8b\xaf\x51\xd6\x2b\x59\xc1"
-  "\x05\xff\x74\x47\x23\xe4\x9f\x3e\xf5\x18\x9d\x1a\x0c\xd4\xc7\xff"
-  "\xd1\x32\xbf\xfd\xe4\xe9\xcb\x1f\x9b\xe0\xff\x3c\xae\xc9\xff\x39"
-  "\xc1\x7d\x25\x48\xb7\xd2\x3f\x26\x3b\xce\x79\x6e\xf0\xc9\x2b\x26"
-  "\xa0\xcb\xc4\x54\x06\x74\x21\xdf\x9f\x44\x4d\x18\xc0\x8d\x69\x8a"
-  "\x64\x4d\x70\xe8\xef\xe6\xef\xba\x6d\x12\x03\xaf\x77\xc4\x0e\xca"
-  "\x0c\x4c\xa3\xe7\x21\x3a\x29\x6d\xf2\xef\x07\xc1\xf3\x34\x9d\xe2"
-  "\x59\x95\x82\xff\xd4\x63\xc1\xf4\x2b\x41\xeb\x8f\x7f\x3f\xc0\x3f"
-  "\x15\xf5\x8f\x1f\xff\xbe\xa3\x3f\x26\x46\x71\xb4\x44\xfc\x8b\xfe"
-  "\x63\x03\x86\x92\x49\x19\x4c\x4a\x60\xd2\x8f\x2b\x32\x8e\xff\xf8"
-  "\xf7\xe3\xdf\x8f\x7f\x3f\xfe\xfd\xf8\xf7\xe3\xdf\x8f\x7f\xff\x00"
-  "\x7f\x2a\x3e\x8f\x60\xd2\x9f\xfc\x5b\xe4\xd1\x14\x68\x75\x07\x4f"
-  "\x03\x5f\x3e\xce\x7d\xa7\x82\x4a\x0b\x43\x34\x57\xd2\xc7\xd3\x0d"
-  "\x10\x74\x09\xc0\xb4\x27\x97\xde\x67\xdc\x86\x9f\x9f\x2a\xd2\xc7"
-  "\x04\x07\xff\x1e\xfe\x54\xc8\xac\x30\x9c\x03\x86\xc3\x10\x18\x0a"
-  "\x5a\x88\x80\x48\xb8\x0a\xa2\x20\x1a\x86\xe1\xdc\x32\x16\x86\xc3"
-  "\x08\x18\x09\x71\x70\x35\x5c\x03\xd7\x42\x3c\xfc\x04\xae\x43\xca"
-  "\x47\xc1\xe8\xe0\x34\x9b\x21\x25\x1e\xff\xc1\xff\xd3\x20\x85\x3f"
-  "\x67\xfc\x98\xfe\xbd\xa6\x5b\xa5\xf4\xa3\x52\xba\xfd\xc7\xf4\xef"
-  "\x35\x5d\xf7\xbf\xfc\x3d\xf6\x7f\xf5\x5b\x85\x66\x59\x58\x66\x55"
-  "\x50\x7b\x18\x98\xaa\x92\xfe\x06\x9e\xe1\x22\xe5\x07\xe1\xf3\x2f"
-  "\x1f\xf8\x97\x82\x9f\x64\xf1\xd3\x04\x20\xd6\x72\x99\xf2\xef\xa2"
-  "\x2b\x73\x46\x03\x7e\x0a\xf0\x63\xc6\xcf\x76\xfc\xec\xc2\xcf\x1e"
-  "\x19\x8f\x80\xd1\xe2\xc7\xae\x01\x38\xfa\x0e\xc0\x1f\x3b\xf0\x93"
-  "\x0a\xf0\x27\x84\xff\x7f\xe3\x00\xfe\xbf\x74\x80\x63\x07\x00\x3e"
-  "\x76\xfa\x70\x76\x54\xfa\xa8\x6b\x37\x8b\xdf\x3a\xfc\x7c\x41\x67"
-  "\x5f\x51\x93\xce\xd2\x3b\xc6\xc6\x39\xe9\xa9\xba\xc9\x13\x93\x27"
-  "\x26\xdf\xa6\x9b\x90\x36\x41\x37\x25\x29\xe9\xce\x49\x49\x53\x27"
-  "\x4d\xb9\x5d\x37\xe5\xb6\xbb\xa6\xde\x7e\xd7\x94\x69\xba\xa7\x37"
-  "\xe7\x65\x4d\x4e\x7a\x62\xad\xee\xf1\xac\xbc\xa7\x37\xad\xce\x5b"
-  "\x7b\xb1\xd6\x7c\xa3\x3f\x22\x6d\xb4\x17\x38\xf7\xfd\x39\x1d\x03"
-  "\xea\x7f\xed\x02\xf5\xa1\x7a\x18\xc8\x51\x55\x4a\xab\xf8\x89\xd2"
-  "\xc7\xff\x4f\x95\x91\x0c\xaa\x47\x47\x81\x4a\x9f\x0e\xaa\x45\xb1"
-  "\xa0\x7a\x20\x0d\x54\xa6\x26\x50\x15\x55\x81\x6a\xd3\x01\x50\xad"
-  "\xd7\x83\x2a\xcb\x3c\x38\xad\x2c\x41\xa4\xfd\x12\xcb\xbe\x86\x9f"
-  "\x57\xf6\x81\xea\x85\x4a\x91\xf6\xeb\x12\x50\xbd\x93\xfb\x9d\xb4"
-  "\xfd\x9b\xff\x5d\x8a\x3f\x70\xe1\x3f\xb5\xbd\xe9\x0a\xd0\xf1\xe3"
-  "\xdf\x8f\x7f\x3f\xfe\xfd\xf8\xf7\xe3\xdf\x8f\x7f\x3f\xfe\x7d\xcf"
-  "\x7f\x67\xd5\x1a\xf8\x03\x7a\x44\xbd\x16\x6d\xbc\x5d\x15\xf9\x0e"
-  "\xed\x0f\x01\x3a\xf7\x04\x5a\x1e\xe7\x44\xfa\x28\xf7\x96\x44\xdd"
-  "\xbb\x17\x80\xce\x6e\xbe\xb8\x9b\x39\xe8\x5c\xe6\xec\x37\x01\x9a"
-  "\x12\x00\x68\xbf\x0a\xe2\x59\x61\x87\x6c\x8d\xd8\x9b\xc4\x9c\x94"
-  "\x4f\xfb\x9b\x30\xbd\x00\xd3\x8b\x2e\xb0\xdf\x85\xef\xad\x22\x9c"
-  "\xb3\xc7\x72\x7a\xf6\x05\xe0\x21\x1c\x8d\x98\xe6\xbc\x00\x8e\x28"
-  "\x99\x2e\xa7\x1a\x54\x84\xaf\xc7\x02\xf1\x4e\x8b\xf5\x6a\x2c\xeb"
-  "\xc4\x36\x25\x4a\x7b\x83\xba\x99\x05\xc2\x9a\x8c\x6e\x3a\x23\xaa"
-  "\xea\x84\x88\x2f\xf1\x5b\x8d\xdf\xe2\xfc\x9b\x28\x97\x40\x38\xb0"
-  "\xac\xaa\xd7\x12\x91\x34\x50\x16\x71\xf3\x73\xde\x10\xf1\x6b\xa7"
-  "\xda\xaa\x16\xb0\xb1\x11\x12\xac\x1a\x61\x57\xc8\xb0\x22\x4f\x3d"
-  "\x57\xca\xbb\x0a\xf3\x8c\xfe\x79\x9a\x17\xa4\xbc\x28\xcc\xab\x0a"
-  "\xa0\x4f\x63\xeb\x73\x03\xd6\x43\xb4\xe8\xec\xf8\x4d\xe7\x92\x24"
-  "\xda\x88\xa6\x26\x84\xe7\xfb\x3c\x67\xeb\x98\x3b\x5d\x07\x9c\x16"
-  "\xe2\x1d\xc2\xa6\x92\xc7\x4b\xcf\xf8\x7b\x14\x95\x97\x7e\xeb\x68"
-  "\x9f\x14\xfd\x96\xea\x1d\xde\x6b\x89\x8c\xf2\xa7\x09\x40\xca\x1b"
-  "\x81\x79\x89\xfe\x79\xbf\x4b\x92\xf2\xae\xc5\xbc\xd9\xfe\x79\x2a"
-  "\xb9\x5c\x3c\xe6\x65\xc8\x79\x83\xf7\xd9\xe0\x34\x04\xc2\x71\x42"
-  "\x32\x04\x3f\x43\xb5\xb2\xec\xf2\xe3\x99\xd7\xf4\x13\xda\x4f\xf5"
-  "\x9f\x0e\xaf\x85\x81\xcd\xe8\x02\xdd\x75\x60\x6a\x87\xc8\xa3\xb4"
-  "\x5f\x67\x67\x21\x68\x4d\xb9\xcc\x45\x67\xe0\x5b\x1d\xdd\x60\x72"
-  "\xb0\x2e\x8a\x7f\x54\x7c\x0e\xb4\x14\xc7\xa8\x78\x3d\xc4\x37\x15"
-  "\x9d\x08\xba\x47\xc8\x4b\xf1\x8a\x47\x51\xd9\x0e\x68\xad\xe9\x00"
-  "\x53\x8d\x7f\x59\xd3\x68\x88\x6f\xa1\x58\x4a\x16\x88\x21\x3a\x9a"
-  "\x74\x6e\x70\x47\xfe\xa7\xa3\x68\x0f\x68\x4c\x63\x41\xdd\x92\x69"
-  "\x95\x68\xb9\xaa\x9a\x68\x29\x39\x09\xda\x37\x1e\x47\xd9\x9f\x24"
-  "\x7a\x5b\x1d\xef\x16\xba\xd4\x87\xe2\xe7\xc1\xa1\xf8\xe3\xd0\x14"
-  "\x3f\x03\x9a\x8c\xb3\x61\xe7\x49\x88\x3a\xe4\x9a\x0e\x4d\x9a\xfb"
-  "\xb0\x6f\xcc\x06\x5b\x37\xfe\xd6\x79\x10\xc6\xc9\xcf\x5f\x74\xc2"
-  "\x55\xa5\x55\x4f\x82\xd6\x2e\x70\xa2\x3c\xaf\xaa\x92\xcf\x12\xd0"
-  "\x73\xb0\x76\xe4\xff\x04\xe2\x91\xbe\x2e\xa4\xe5\x4e\xa4\xa5\x25"
-  "\x21\x1e\x92\x90\xe6\xa1\xb6\x6a\x37\x68\x8a\x20\x22\x44\x9f\x88"
-  "\xe3\xe7\x90\x51\xa7\x6a\x77\xb3\x2e\xd2\xad\x9e\x2d\x7a\xec\x5f"
-  "\x51\x1a\xac\x7b\x9f\xb4\x3f\xaf\xdb\xf4\x1a\x68\x7a\x36\xe9\x69"
-  "\x5f\x72\x07\xe6\xe9\xe4\x3c\x3a\x5f\x4d\xe7\xa6\x27\xc5\xd1\x5d"
-  "\x76\x29\xf0\x5e\x5f\x17\xed\xfd\xeb\xa6\xfd\x98\x84\x2f\xc6\x08"
-  "\x61\xd8\x9e\x70\xa4\xe7\xab\x3a\x4c\xbf\x01\xe1\xb0\x3c\xca\xff"
-  "\x9f\xf8\x99\x7b\x76\xed\x72\xa7\xf7\xda\xe5\xe7\xbc\x2f\x2f\xef"
-  "\x61\x2f\x2f\x3f\xeb\x79\x79\xf9\x57\xa6\xcd\xa0\xf5\x5c\xbb\xdc"
-  "\xd1\x9a\xcb\x65\x10\xdb\x9a\x7b\x8a\xf6\xf1\x69\xb7\x9e\x82\xd8"
-  "\x95\xeb\x51\xf6\xee\x4f\x61\x6b\x16\xc4\x7b\x23\x5a\x1a\xe8\xce"
-  "\xbb\x95\x45\xc0\xf0\x77\x63\xb0\xf6\xf5\x44\xda\x92\x84\xce\x6a"
-  "\xa9\x4d\x6d\x76\xf5\xfb\x5d\x54\xaf\x23\xe2\xe3\x24\xfc\x24\xe3"
-  "\x67\x1a\x7e\xa6\xb3\x48\xdb\x74\xe4\x95\x69\xd8\x36\x15\xd0\xf9"
-  "\x81\x49\x5e\x50\xa1\x88\x9c\x74\xcf\x42\x08\xbe\x8d\xf2\x96\x9f"
-  "\x88\xfd\x99\x19\x8a\x7b\x7b\x0d\x74\x8e\xdb\x41\xf6\x84\xec\x4b"
-  "\xaf\x25\x3a\xc5\xae\xfe\x4f\xa1\xfb\xbb\x99\x93\x45\x9e\x88\xc5"
-  "\xf4\x2e\xe7\x16\x83\xca\xb1\xc5\xa0\xee\x89\x3c\x31\x12\x61\x32"
-  "\x11\x26\x43\xe2\x61\x17\xe1\xc2\x7e\xe2\x88\x76\x43\x18\xe2\xcc"
-  "\xfd\xf7\xaf\xdb\x34\x7b\x77\xb3\xe3\x08\x57\x31\x80\x0b\x71\x23"
-  "\x1e\xe4\x7f\x74\xbd\x9c\x86\xbc\xee\xd8\x81\x70\x54\xde\xe6\x4a"
-  "\x21\xbb\x6b\xb7\x65\x77\xd1\xfe\xd9\x48\xd6\x2f\xea\x43\x18\x3a"
-  "\x5b\xe9\x88\x76\xc1\x90\x5e\x0b\xa4\x11\x6e\x2a\x67\xeb\xee\x02"
-  "\x2c\x37\x92\x99\x0c\x68\x97\x60\x41\x2f\x33\xa8\xe8\x2c\xfd\x21"
-  "\x2c\x2f\xea\x1e\xa6\x95\x69\xa4\x3a\xf8\x59\x7a\xa2\x13\xf5\xe1"
-  "\x50\xb6\x0b\xa2\xab\x21\x0c\xcb\x2d\x26\x7c\x84\x0b\xf5\xc0\x8e"
-  "\x6d\x1d\x79\x28\xdb\x01\x5e\xe6\x87\xd3\x2e\xe1\xd3\xfb\xe1\xc3"
-  "\x74\x86\xf8\x48\xff\x9a\xb0\x4c\x74\x3d\xc7\xb7\xe8\xdf\xbd\x84"
-  "\xcf\x05\x1a\x1d\xa7\xf7\x61\xc2\xc1\x63\x53\x20\x4e\xeb\xc6\x59"
-  "\xd0\x0d\xc3\xac\x0e\x93\x21\x8c\xef\xe3\xc3\xf2\xef\x16\x77\x85"
-  "\xb3\x1e\x7d\xd8\x30\xbe\x87\x6f\x16\x50\xfc\x04\x84\x79\x8d\xf5"
-  "\x18\xc2\xa2\xbb\x41\x43\x34\xd3\x39\x1e\xa2\x53\x29\xcb\x45\x73"
-  "\x1e\x9e\x01\x0f\xcf\x9e\x3b\x7b\x06\xcc\x9f\x79\xef\x0c\x48\xba"
-  "\x73\x42\xd2\x6d\x77\x4c\xbb\x0d\xd2\x96\x2e\x9a\x01\x69\x0b\x66"
-  "\xc0\x62\xfc\xe8\xef\x9b\x8b\x0f\xf7\xce\x98\x9c\x74\xff\x84\xb4"
-  "\x7b\xe7\xce\x81\x87\xd2\xa7\x24\x4d\x99\x02\x33\xe7\xcc\x9b\x9c"
-  "\x94\x24\x7d\x4f\x4e\x22\x90\x47\xa6\xcd\x59\x3c\x21\x2d\x6f\x5d"
-  "\xc1\xba\x09\x0b\xe6\xde\x0b\x73\xe6\xcc\x48\x0b\x18\x1b\x13\x3d"
-  "\x5f\x7b\x88\xb7\x4e\x76\x26\x95\x62\x25\x40\x2d\xca\x1c\x3f\xdd"
-  "\xfc\x0c\x06\xc4\x3e\x53\x4b\xb2\xe2\xf6\x72\xd8\x71\xec\xe7\x9a"
-  "\x5e\x4b\x0c\xc9\xbf\x9e\x78\x46\xf1\x0a\x3a\xe1\xea\xbd\x98\xf7"
-  "\x99\x64\xa3\xc3\x31\xff\x1d\xff\xfc\xe1\x66\xcc\xff\x82\xf6\xf4"
-  "\xdb\xf0\x83\x7c\x76\xa2\xed\x43\x7e\x3a\xa0\xc7\xa4\x0f\xe7\x67"
-  "\x2a\x51\xc6\xb4\xd7\x15\xcb\x76\x29\xfa\x78\x07\xed\x89\xd5\x15"
-  "\x42\xd8\x69\x88\xf9\x7d\x6b\x41\x0a\x9d\x7b\x01\x5b\x81\x84\xe3"
-  "\xdc\x00\x8e\x48\xe9\x5c\xa6\xbd\x96\xf6\x1b\x73\x3c\xb1\x49\x0a"
-  "\x7b\x60\x27\x3c\x3b\x31\x4f\xe0\x8a\x0d\x6f\x45\xbb\x80\x76\xbb"
-  "\xcf\x6b\x4a\x04\x16\xf9\x9f\x2e\x6f\x7f\x22\x1f\x63\xb0\x9c\x41"
-  "\xd6\xe3\x9d\xb4\x97\x35\x17\xe1\xde\x48\x55\xd1\x5e\x50\xbe\x2f"
-  "\x14\x62\x0a\x50\x9f\x9d\xde\xf2\x8f\x53\xf8\x99\x65\x9e\x16\x7b"
-  "\x80\x45\xe2\x73\xf9\xc7\x33\x99\x49\x9c\x63\xc6\xb4\xdf\x50\x1a"
-  "\xca\x38\x8c\xfa\x22\x3f\xa7\x89\x75\x23\x2f\x6e\x46\xfa\xda\x3c"
-  "\x54\xfe\x0c\x2f\x3f\x14\xd3\x22\x10\x76\xa6\x37\xf2\xe3\x59\xa8"
-  "\x33\x94\x86\xe3\xfa\xd5\x07\x11\xdf\xbd\x74\x86\x9c\x45\x25\x10"
-  "\xee\xd9\xd6\xc2\x6e\x1e\x27\xcf\x8e\x79\x5e\x13\xe2\xec\x1f\xa8"
-  "\xbf\x8d\xca\x62\x5d\x9a\xde\x7e\x03\x8e\xa5\xb1\xc7\xc9\x27\xf0"
-  "\x10\x3d\x67\x06\x60\x9a\xa9\x4e\xea\xcf\x28\x8b\x6e\x94\x53\x44"
-  "\xaf\x65\x78\x7a\x80\x9c\xb2\x11\xcf\x4c\xe4\x7b\x1b\xe2\x68\xf2"
-  "\xf6\x60\x1d\xf8\x8c\x78\xd5\x12\x5e\x19\x87\x53\xe8\xc1\xf0\xaa"
-  "\x00\x3d\xd8\x86\xb8\xcf\x29\xf2\x0f\x04\xe4\xaf\xc5\xfc\x3e\x29"
-  "\x1f\xfb\xd5\xf0\x63\x01\xf5\x13\x6d\x5e\xac\xdf\x89\xfd\x26\x0c"
-  "\xeb\xa3\x73\x65\x0e\x1f\xfc\x08\x8d\x3f\xfc\x08\xf4\x0d\x62\xc8"
-  "\x96\x90\x4d\xe4\xf0\x75\x92\xae\x8a\xfa\x47\x24\x07\xc0\xbb\x11"
-  "\x7e\x28\xc5\xda\xc0\xef\x91\x08\x33\x14\x6d\x92\x06\xc7\x8f\xe3"
-  "\x87\x8a\xc8\x7f\x1b\x91\x19\x00\x5f\x82\x70\xd7\x11\x1f\x39\x0f"
-  "\xce\x70\x1e\xe8\x25\x7f\x8b\xfa\x82\x16\xcb\x54\x07\x94\x69\xc4"
-  "\x32\xe3\xbc\x82\x6f\x61\xbd\x3d\x41\xcb\x1c\x09\x28\xd3\xcd\xe5"
-  "\x2f\xea\xd1\x90\xbe\xc8\x65\xb8\x8d\xe9\xf7\xc3\x41\x6d\x43\xbf"
-  "\x6c\x64\xac\x3f\x8e\xb8\x6e\xac\xf7\x96\x1d\xa2\x1f\x5f\x85\x32"
-  "\x9f\x82\x69\x9f\x22\xde\x39\xa4\x27\xa4\xcb\x36\x87\x0b\x6d\x60"
-  "\x6a\x94\x18\xcb\x47\xae\x8f\x29\x02\xfa\x3d\x81\x7e\x13\x6e\xd6"
-  "\x3f\x4f\xd2\xf1\x91\xeb\xf1\x9b\xd2\x79\x9d\xd4\xb7\x58\xff\x83"
-  "\x5e\x81\x73\xe4\x4b\xd8\x07\xd5\xf8\xec\x91\xea\xf8\x33\x9d\xe7"
-  "\x45\xfd\x9c\x85\xf6\x15\xe8\x4c\x32\xa6\x27\x63\x7a\x8b\x94\xff"
-  "\x3e\xc1\xe3\xef\xc9\xd2\x6f\xd2\xcb\x59\x92\x5e\xa2\x9e\xc7\xfd"
-  "\x96\xd7\xcd\x75\x5d\x94\xf7\x0a\xbd\xbe\x17\xf3\xde\xc2\xef\xb9"
-  "\xf8\xfd\x12\x7e\x3f\x84\xdf\xeb\x29\x06\x83\xc9\x83\xfe\x84\x78"
-  "\x7e\x14\xbf\x17\xe1\xf7\x5c\xfc\x5e\x8c\xdf\x53\xa9\x5f\x3a\x36"
-  "\x19\x20\x40\x27\xba\xbd\xa2\x2f\x0e\x15\xf2\x88\x4b\x90\xfa\x87"
-  "\xe8\x9f\x67\x7c\x69\x4c\xa4\xa9\xd1\xae\xfb\xd2\xfa\x53\x89\x2f"
-  "\x69\x88\x9f\xc7\x0c\x91\xfa\x75\xb8\x90\x8b\x80\xf1\x8a\x72\x92"
-  "\xec\xa4\x34\x01\xa7\x52\xd6\x69\x87\x91\xc7\x8a\x9d\x8c\xe1\xb7"
-  "\x95\xc7\x6f\x80\xb8\x26\xe4\x09\xfa\x35\x23\xab\x88\x4f\x3e\x79"
-  "\x8f\x4c\x52\xc8\x1b\xfd\xda\xab\x21\xa0\x2f\x25\xa3\xbc\xa7\x73"
-  "\x79\x23\xef\x64\x9a\x89\x7e\x1c\x5f\x68\xcc\x1a\x22\xda\x10\xab"
-  "\x47\xdb\xde\xed\xb3\xcd\x57\xa7\xfa\xe3\x89\xd5\x63\x99\x03\xd2"
-  "\x58\x36\xa0\x67\xa4\x2f\x61\xb9\xd4\x87\xae\x46\xff\xff\xf7\x47"
-  "\xf8\x59\x1e\xcc\x73\x46\x9c\xa8\xa4\x3a\xc3\xb2\x79\x1e\xfa\xff"
-  "\x57\xb5\xc9\x79\x20\xce\x4b\x39\xc3\x0a\x78\xde\x7e\xb9\x1c\x2b"
-  "\xff\x20\x9e\x97\xc5\xf1\x91\xfc\x05\x1a\xf7\x71\xfc\xed\x42\x98"
-  "\x63\x76\x88\x8e\x0d\x19\xc3\xa8\xf4\x03\xed\x04\x33\xa8\x6f\x30"
-  "\x43\xb8\xcd\x7d\x1c\x16\xba\x99\x67\x02\x40\x84\xcd\x3d\x1d\x6e"
-  "\x06\x18\x6e\x73\x1f\xa3\xc5\xf0\xb1\x36\x77\x15\x8e\xaf\x25\x94"
-  "\xff\xde\x2d\xa0\x52\xe1\xb7\xe9\x56\x50\xab\x6c\xee\x7d\x98\x7e"
-  "\x00\x6e\x00\x8d\xea\xfe\x70\xd6\x6b\x73\x27\xe3\x73\x01\xdc\x17"
-  "\xce\xfe\xba\xca\x03\xb1\xf3\x9e\x61\x26\x9b\x3b\x13\xee\x7b\xc6"
-  "\xcb\x6c\xee\x23\x98\x97\x0d\x0b\x3d\xe7\xd9\x42\x4f\x2f\x63\xda"
-  "\x0f\xe2\x17\x7a\xce\xe0\xef\xbf\x32\xe4\x1b\x7e\xbf\x87\x1f\x13"
-  "\xb3\xa1\x9f\xcc\xca\x3e\xd0\xae\xda\xac\x86\x7e\xba\x3f\x27\xe2"
-  "\x83\x78\x6c\x5f\x62\x3f\x33\x84\xb1\xc8\x0f\x7e\xd6\xdf\x8f\xdf"
-  "\xe5\x1f\xdc\xc4\x9f\x4b\x3f\x98\x86\x78\x12\x27\xe2\xa4\x81\xe8"
-  "\xb7\xb9\x3b\x60\x15\xda\x9b\x85\x9b\x1d\x8c\x68\x1f\xb6\x8d\xc1"
-  "\xc2\xcd\xef\x31\xb4\x75\x31\x0b\x37\x9b\x18\xe6\x69\x11\x5f\xa2"
-  "\xcd\xdd\x4d\x75\x4c\x43\x7c\x53\x39\xbe\xd2\x0f\xf4\x08\xeb\x20"
-  "\x38\x25\x1e\xc2\x41\xb0\x0b\x3d\x10\x83\xf0\xfa\xfe\xb2\x0f\x52"
-  "\xf1\x63\xc0\x4f\x35\x96\x7d\xdb\x6b\x89\xfb\x3d\x8d\x6b\x58\xbe"
-  "\x11\x9f\x9b\xcf\xf3\x38\x0b\xc7\x09\x7e\x28\xc2\x37\xa2\xcc\x67"
-  "\xf7\x0a\x7a\xbb\x38\xbd\xe5\x1f\x7c\x71\x5e\xb4\xa3\x53\x6a\xc7"
-  "\x09\x4a\x77\xa2\xae\xb3\xf2\x66\xad\x93\xe7\x35\x0f\xc5\x72\xe9"
-  "\xbc\x5c\x69\xb3\x96\x69\x9b\xe3\x51\x6f\xc3\x16\x7a\x98\x99\x78"
-  "\x88\x7c\x35\x13\x1f\x69\xce\xc3\xca\x30\x3f\xa2\x39\xbe\xbf\xac"
-  "\x39\x11\xcb\xdf\xd5\xcf\x68\xac\x6d\x4e\x3d\xcf\x71\x37\xdf\x8f"
-  "\x78\x56\xf4\x12\x4e\x6d\x73\x2a\xe2\xd2\xbb\xd5\x3a\xe4\x07\x73"
-  "\x2d\x74\x6f\x73\xaf\xda\x4c\xb1\x50\xde\x87\x44\xb3\x59\x65\x33"
-  "\x16\x60\x3b\x2b\x10\x67\x26\xe6\xc3\x48\xac\xeb\x3d\xc4\x9b\x4a"
-  "\xf5\x61\x1d\x7a\xc4\xb9\x04\x71\x65\x12\x4d\x7d\x16\x88\xc5\x67"
-  "\x43\x9f\xa0\xaf\xd4\x5b\xda\xdc\xe0\xd5\x36\x57\xcb\xfa\x43\xba"
-  "\x23\xf8\x46\x3a\xf3\x2b\x4a\x8b\x95\xf5\xc4\x53\xda\x6c\xbc\x15"
-  "\x20\x76\x81\x93\xb9\x49\x57\x26\x41\xae\xaa\xd5\x79\x0c\x79\xad"
-  "\x85\xd6\xdc\x03\x70\x0b\xd0\xdc\xcb\x09\xad\xce\x2a\x7c\xde\xcb"
-  "\xef\x9d\x6e\x75\x96\x40\x4b\xf7\x3e\x58\x90\xeb\xdc\xe6\xd1\x36"
-  "\xbb\x5a\xba\xe7\x03\x96\x7f\x0f\x69\xf4\xae\xcc\xd5\x98\x5b\x73"
-  "\x9d\xf4\x6c\x6a\xe9\x46\xfd\xf4\x30\x8f\xbb\xb4\xd9\xe0\xd6\x1e"
-  "\xd6\x2e\x38\xc7\x1c\xf3\xbb\xcd\xe1\x98\xd6\x1f\xa3\x62\xee\x18"
-  "\xa3\x89\xb5\x74\x57\xc0\xca\x73\xa0\x6a\x31\x1c\xe0\x7a\xba\x32"
-  "\x37\x17\x78\xf9\x73\xee\x98\x47\xbb\xcd\xf0\xa8\x01\x86\x21\xfc"
-  "\x19\xd2\x59\x36\xcc\x0c\x47\x3a\xb2\x61\xfe\x29\x77\xd8\x82\x73"
-  "\xfd\xec\x48\x46\x15\xb4\x18\xaa\x88\x1f\xa5\x34\x47\x99\x7f\xaa"
-  "\x87\x2d\x38\xd7\xcb\x5a\x0c\xbf\x82\x23\x19\x07\x60\xde\x09\x6b"
-  "\x8c\xa7\xac\xd9\xe8\x8d\x68\xae\xf6\x96\x35\x37\x78\x22\x9a\x5d"
-  "\xee\x32\xa4\x25\xe2\xb0\x96\x95\x1f\x36\x22\xff\x22\xb8\x2c\x22"
-  "\x0f\x6f\xc4\xdf\x3a\x2e\x5f\xed\xe1\x52\x56\x7a\xb8\xa1\xbf\xec"
-  "\x70\x35\xd7\xfb\x88\xc3\xa5\x36\x37\xe9\xff\xe1\x06\x84\x6b\x10"
-  "\x3a\x72\xb8\x51\xe8\xfe\xe1\x7f\x27\xb9\x22\x6c\x33\x7e\xda\xf0"
-  "\xd3\xc5\xca\x3f\x9c\x86\xb8\x86\x13\x5e\x6f\xe9\x87\xa9\x5e\xed"
-  "\x87\xd8\x1f\x3e\xd4\xe3\x9c\x46\xdd\xea\xdc\x07\x1e\xb4\xc7\xad"
-  "\x4e\x0f\x2c\x58\xef\x42\xd9\xa2\x0c\x8c\x1e\xe4\xe7\x71\x58\xb9"
-  "\x1e\x4c\x36\xe3\x71\x60\xbf\xab\x24\x7e\xc4\x2c\x58\xff\x1e\xf3"
-  "\x96\x7d\x98\x4a\xf9\x0b\xd6\x9b\x70\x5e\x85\x78\x22\x3e\xd4\x7b"
-  "\xcb\x3f\x34\x4a\xfe\x15\xd2\xf1\xe1\x26\xa2\xa3\xbf\x37\x91\xce"
-  "\xb9\x69\x30\xbf\x14\xd3\xfa\x68\xbc\xf1\x92\xde\x95\x7e\xe8\x62"
-  "\xda\x8f\xf4\xf3\xc3\x99\xc3\xf3\x2c\x70\x1d\xf0\xde\xcd\x18\xcd"
-  "\xdb\x56\x19\xa1\x9e\xf7\x29\xcf\x75\x66\x16\xf1\x91\x9e\x95\x7d"
-  "\xe8\xf2\x96\xb7\xbc\x82\x78\xc2\x28\x36\x30\x2b\x6d\xa9\x16\x3a"
-  "\xf3\x29\xef\x7b\xac\xac\xa5\xda\x7f\x8d\x20\xf8\xfa\x40\xaf\xe5"
-  "\xba\x03\x76\x68\xe5\xe7\x20\xf1\xb7\xd5\x0e\xb6\xe9\xd2\xef\x23"
-  "\x76\xf8\x57\xbe\x4e\x44\x36\x2e\xb7\x18\xae\x3e\x09\x3f\x35\x23"
-  "\x3f\x00\x7f\x47\xe1\xef\x92\x85\x37\x63\x9b\x2b\x86\x1b\x51\xde"
-  "\xbd\x64\x6f\x98\x25\x19\xfd\x13\x48\xc1\xb6\x6a\x59\x2f\xc5\x48"
-  "\xfe\xe4\x01\x8a\x91\x4c\x31\x91\xf1\x79\x18\xf2\x34\x01\xbf\x47"
-  "\xec\xfd\x1a\xe2\xf0\x13\xbf\x57\x8a\xc7\x8c\xbf\x93\xd8\xa6\xf8"
-  "\xc8\x9d\x1b\x61\x7c\x8c\x53\xc4\x42\xa6\xd8\xcd\xe8\xf7\xc4\xd1"
-  "\x6f\x66\xf9\xb7\xc4\xba\xaf\xa5\x78\xc8\xd1\x58\x1f\xc5\x43\xce"
-  "\x4f\x84\xba\x3c\x1e\x9b\x2e\xbe\xce\xc2\xf6\x7b\x7a\x13\xd5\x44"
-  "\xa7\x4c\x0b\xd1\x86\x74\x8e\x46\x3a\xab\x96\x6c\x4e\x81\xf7\x8d"
-  "\xc1\xcf\x39\xf5\x5a\x7e\x3a\xd0\xfe\x10\xf9\xc7\x64\x9e\x84\xc8"
-  "\x77\xca\x7c\x0a\xb5\x4e\x40\x7d\xdc\xf3\x35\xeb\xde\x95\x23\xce"
-  "\xd5\x99\xdc\xec\x73\x9c\xc3\x98\x8b\x71\x6e\xbe\xd0\xe8\x62\x36"
-  "\x07\xb3\xda\x8c\xa7\xf8\x3a\x5f\x1d\xc2\x14\xbb\x99\x97\xe6\xc5"
-  "\x34\x27\xa6\x18\x6e\xde\xb2\x4f\xc6\xb3\xb2\x4f\x12\x7b\x36\x32"
-  "\x77\x2d\x9f\xc7\x8e\x32\xd8\xe1\xee\x0c\x21\x9b\xe6\x52\x1c\x07"
-  "\x3b\x7a\xb4\x9f\x24\x22\xee\xe1\x84\xbb\x35\x97\x59\xbd\x11\x9f"
-  "\x24\x21\x5c\xa5\x1d\x3e\xd9\xa7\x5c\xeb\xc3\x31\xad\xbb\x64\x37"
-  "\x8d\x6b\xa3\xde\xb1\xc3\xf5\xa5\x83\xd6\x92\xc4\xdb\x4b\xb3\xdf"
-  "\xf9\x0a\x15\xf8\x9f\x16\xa1\x93\x19\x29\xc1\xb3\x7d\xe3\xe2\x61"
-  "\x2d\xc5\xb5\x33\x6d\x85\x51\x28\x87\x9f\x9e\x84\xd1\x63\x4d\x46"
-  "\xd6\xc9\x2c\xa3\x1a\xdf\x28\x74\xa1\x0f\x31\x7a\xbc\x1d\x5e\x6b"
-  "\x0b\xc5\x37\xef\xd7\xac\x03\xdb\xd6\xb0\x0b\xfd\x40\x6a\x37\xf1"
-  "\x6d\xa1\x91\x79\xb1\x7d\x9f\x51\x1f\xab\xdb\x48\xbe\xf0\xe8\x5c"
-  "\x99\x0f\xa1\xce\xfa\xb1\xd2\x4f\xa6\x0b\x7f\x71\xf4\x51\x66\x61"
-  "\x60\x1d\x43\x6b\x7f\xa3\xff\xc8\x7d\xa6\xd2\xc3\xd5\x3d\x68\x3f"
-  "\x68\x8d\x84\x62\xd0\xe5\xc7\x33\x17\xe2\x6c\xb2\xc3\x4d\x49\xd2"
-  "\x9c\xcc\x69\x73\xcf\x21\x5b\x12\xf4\x0c\x2e\x3f\x0b\x38\x80\x7f"
-  "\x8c\xa3\x75\x14\xdd\x55\x87\x76\x47\x7b\xe2\x58\xb1\x90\xb3\x8b"
-  "\xf0\xd2\x59\xd6\x0e\xcc\xcf\x77\xb2\x2e\x56\x7a\x82\x62\xc5\x39"
-  "\xe9\x5c\x1d\xa6\x7d\x85\xfa\xcb\xac\x79\x44\xd3\x98\xaf\xac\x63"
-  "\xfa\xa0\x13\xfd\x41\x3a\xbb\x2a\xe6\x67\x63\x8e\x1f\x2a\x00\x69"
-  "\xce\x37\x66\x85\x1d\x12\x8f\xc8\x74\xa1\xcd\x60\xc8\x5b\xe2\x73"
-  "\x29\x8d\xaf\xb4\xee\x96\x5f\xc4\x5c\x48\x6b\x29\xc2\x96\xca\x6d"
-  "\xa0\xf6\x89\x76\x8d\xa9\x51\xb6\x0b\x69\x70\xa0\x6f\xcd\x79\x90"
-  "\xbf\x19\xb4\x3c\x26\x96\x87\xc6\x8e\x39\xbc\x2d\xd4\x66\xde\x16"
-  "\xf4\x2b\x68\x3c\xb1\xb9\xa7\xa2\xdf\xc5\xd3\x1b\x10\x17\xce\x7f"
-  "\x7f\x36\x4d\xf8\x54\x63\x78\xbc\xe3\xa0\xbe\x91\xb6\x59\x6f\x3a"
-  "\x0f\x63\x4c\x5e\xd6\xde\x09\xd7\x6f\x40\x3e\x85\xd1\x37\x1f\x8b"
-  "\x5d\xa8\xbb\x5a\x7b\x14\x8d\xc1\xb6\xa2\x73\x68\xb7\x39\xec\x48"
-  "\x84\xed\x40\x98\xb5\x12\xec\x5a\xb1\x26\xcc\xbf\x87\xd2\x37\x8e"
-  "\xc9\x4b\x50\x6f\x8b\x68\x1d\x03\xf9\x5c\x29\x3f\x33\x7c\xc6\xef"
-  "\x64\x56\x66\x8f\x0a\x4e\xcb\x47\x7a\xaf\xd4\x0f\xb1\x9e\x6b\x49"
-  "\x8f\x4c\x9b\xe1\x27\xa8\x93\x9f\x15\x6f\x85\xab\x49\xc7\x58\xc4"
-  "\x27\xa9\x82\xef\xd7\x37\x33\x8b\x19\xe8\x1c\x6c\xee\x46\xf8\x29"
-  "\xf6\xbd\x94\x93\x70\xfd\xa7\xab\x8a\x74\x48\x2b\xc0\xae\xd3\x40"
-  "\xe3\xe4\x5f\x11\x7e\xb6\xcd\x7d\x82\xee\xba\x43\x5d\xbc\xde\x2d"
-  "\xeb\x62\xaf\x45\xa7\xbd\x90\x4d\x40\xbe\xb6\x89\x79\x85\x6e\x03"
-  "\xad\xb1\xb5\x83\x8e\xe2\x85\x86\xe1\x47\x85\x69\x0f\xb1\xaf\xd9"
-  "\x28\x8a\x51\x88\xbc\x6e\xb6\x83\xae\x02\xbf\xdb\xf8\xc7\x02\x66"
-  "\xe9\xb9\x19\xe1\x52\xd8\xd7\x1e\x82\xc1\x79\xb0\x0e\x6d\xa4\x8a"
-  "\xfa\x49\x0d\xd6\x5d\x62\x87\x99\x46\x21\x1b\x5d\x1a\xe1\x0a\x41"
-  "\x03\xc5\xab\x13\xf1\x31\x41\x77\x4a\x57\xac\x22\x3a\x78\x3c\x1f"
-  "\xc2\x55\xa7\x16\xb6\xd9\x8b\xb4\xd6\x5a\xbc\x06\xb4\xc3\x06\x6f"
-  "\x79\xbb\x95\xff\x96\xf2\x88\x0e\x2f\xd6\x1f\x1c\xff\x89\x63\x3c"
-  "\x1e\x29\x8c\x4d\x15\x78\x4e\x34\x5b\xaf\x3b\x49\xcf\x3c\x0e\x92"
-  "\x53\xfb\xb9\xd5\x56\x9d\x22\x62\xa1\x22\x8c\xf0\xf3\xc7\xce\xed"
-  "\xc1\x3a\x7a\x2d\x63\x53\xed\x70\x8b\x56\xac\x37\x7e\x6e\x0d\xd1"
-  "\xf7\x62\xa9\xef\xb4\xd4\x80\xd4\xa7\x6f\x08\xa7\x35\x0f\x6c\x57"
-  "\xa3\x47\x7b\xb8\x4d\xb2\xb3\x34\x07\xbb\xaa\x1d\x6e\xd0\xb4\x1a"
-  "\xb8\x7e\xab\x99\x7a\x6c\x83\x5f\xac\x44\xcc\x1b\xfc\x19\xdb\x86"
-  "\x9f\x2e\xfc\x38\xc5\x33\x12\x07\xe3\x90\x82\x71\x99\x9c\x6f\x3d"
-  "\x99\x38\x27\xba\x41\xe3\x8d\x40\x99\x94\x92\x8c\xc6\xda\x59\x4f"
-  "\x82\x1a\x7d\x11\xfe\xbb\x6e\x3d\xcd\x2d\xc6\x45\x21\xff\xab\x85"
-  "\x1c\x08\x07\xa8\xb0\x2f\x12\xcf\x99\xa9\x9a\xb9\x9a\x8a\x9d\x48"
-  "\xf3\xb8\xe9\x4d\xd5\x4e\xd0\xdd\x44\x6d\x1f\x97\x42\xed\x71\x22"
-  "\xef\xe9\x3b\xbf\x9a\x39\x0e\xd5\xb8\x81\xd6\xa5\x11\x97\xde\x0e"
-  "\x96\xd9\x62\x9e\xd2\x09\x84\x4f\xd2\x07\x26\xb7\x5d\xf0\xf8\x73"
-  "\xab\x6e\xa3\x8a\x70\xbd\x49\x6b\x12\x34\x67\xf2\xad\xf5\x8c\xdb"
-  "\x8b\x7d\xfc\x1e\x8a\xa3\x7a\x1a\xc6\xfd\x99\xe0\x0f\x19\x78\x3c"
-  "\xb6\xee\xbd\x7c\x3c\x18\x77\x10\xe9\x75\x49\x71\x27\xba\xe9\x4c"
-  "\x3d\xe1\xc3\x79\x54\x57\x8b\xc1\x01\x1e\x6c\x2b\x3f\x73\x8f\xf2"
-  "\xd9\xda\xcd\x5c\xef\x6d\x74\x69\x78\xfd\x39\x3c\x16\x9a\x33\xa6"
-  "\x00\xf5\x01\x65\x85\xf3\x5e\x17\xd6\x55\x10\x18\xd3\x53\x11\x4b"
-  "\x56\xa2\x39\x21\xe2\x50\x02\xb7\x97\x8d\x5e\xe4\x8b\xbf\xbc\x12"
-  "\xb4\x42\x56\x37\xa4\xfb\xcb\x2a\x01\x7d\x97\x1b\xaa\xf1\xb3\x1f"
-  "\x3f\x56\xf1\xac\xfc\xdc\x50\xa2\xf8\x7d\xb4\xd7\x72\x03\x8e\x7f"
-  "\xba\x38\x21\x03\x4a\x43\x1a\x49\x37\xbe\xc2\xf1\x05\xe7\xef\xf4"
-  "\x8e\x82\xd2\x49\x8f\x29\xdd\x8b\xbe\x0a\xf2\x76\x1f\xe6\xc7\x52"
-  "\x1f\xa5\x18\x76\xca\xfc\x81\x58\x25\x70\xc3\x39\xbe\xe6\xb0\xad"
-  "\xb4\x94\xf4\x13\xcb\x34\xc4\xb8\x4b\xd1\xee\x26\x80\xcc\x43\x4c"
-  "\xeb\xa2\xfc\xe0\x3e\x43\x42\xe2\x80\x6f\x85\xfe\x26\xc9\xa7\x1b"
-  "\x6e\x4c\x46\xbb\x84\xf6\xb8\xbd\x51\x8c\x27\x37\x4e\xa5\x67\xb4"
-  "\x87\x9f\xe1\xef\xa4\x16\xb4\x3b\x7d\xe5\x1f\x27\xf5\xab\x61\x68"
-  "\x9f\x1a\x52\xdc\x3b\x87\xd7\xb8\x23\x6d\xd3\x6d\x5d\x07\xa0\xd5"
-  "\xfd\xaf\xa0\x7b\x92\xe3\xb8\x99\xe2\x26\x9a\x36\x33\xcf\xbb\x7d"
-  "\x0d\x38\xf7\x3a\x63\xe5\x71\x8a\xe1\x46\xde\xf6\x5f\xb4\x8b\x3b"
-  "\x34\x3a\xa5\x67\x16\x35\xdc\xb8\xf3\x71\xe6\xde\xd9\x49\xb1\x14"
-  "\xe2\x23\x77\xf4\xc1\xf8\x57\x0a\x21\xa9\xa6\x0f\x12\x6a\xfb\x20"
-  "\x91\x7d\x41\x77\x4c\x78\xf5\x2b\xcf\xc5\x52\xfc\x7e\xfd\xb0\x5c"
-  "\xd0\xd6\x16\xa2\x1f\xe6\x06\x95\x67\x07\xfa\x61\x74\xd7\xc6\x99"
-  "\x44\xb2\x7f\x03\x7e\x58\x7f\x3f\xf9\x61\x9f\xec\xe7\xf1\x75\xcb"
-  "\x3e\xd9\x1f\x6d\x00\x55\x54\x06\xc4\x22\x7d\xa6\xd3\x90\x90\x15"
-  "\xd5\x81\x3e\x20\xb6\xd9\x2e\xb5\x17\xf9\x5b\x14\x63\x80\xa1\xbc"
-  "\xad\x68\x93\x59\x59\x7b\xd0\xf7\x11\x7c\xac\x55\x93\xee\x38\xa9"
-  "\x7f\x50\x1b\xb6\xd1\x3b\x91\x03\xd7\xb9\x34\xf9\x35\xcc\x45\xe9"
-  "\x05\x63\x49\xf7\x6e\x34\x50\xdd\xfb\x31\xbd\xd7\x72\x63\xa5\x5d"
-  "\x7d\x28\x2a\x94\x1d\x8e\xd9\x26\xfb\x03\x37\x0d\x67\x6a\x33\xf9"
-  "\xdf\xc6\xad\x6e\xe6\xb0\x9d\xa6\xbe\x79\x53\xec\xc2\x6c\xe6\xd6"
-  "\xe5\xd0\xfb\xa9\x9b\x80\xde\x9d\xd1\x9a\xf9\xbf\xa0\xef\x72\xb1"
-  "\xf7\x65\x34\x26\xa0\x7f\x5e\x1a\x93\x8d\x38\xd1\xff\x67\xa6\xc4"
-  "\x20\xe7\xe2\x83\xfb\xe3\xf4\xae\xf5\x45\xfe\x5e\xf7\xa6\x79\x76"
-  "\x48\x73\x49\xf1\x11\xbb\x85\x7d\xfc\xd9\x78\x9a\xe7\xfb\xf7\xeb"
-  "\x9f\x01\x9d\xf3\xef\x29\xfd\xf8\xa0\x75\x0c\xd9\xf2\x9b\xce\x0b"
-  "\xdf\xe6\xe3\x46\x61\xdb\x6f\xfa\x8b\x58\xa3\xbb\x09\xc7\xff\xdb"
-  "\x39\x2f\x72\xc7\x91\x4e\xdc\x74\x8c\x45\x7e\xfc\x1f\x04\x37\xd1"
-  "\x0c\xe6\x75\x6e\xc8\x60\x65\x1f\xf3\x98\x6a\x36\xf7\x69\x60\x2f"
-  "\x3f\xd5\x4b\xef\x64\x9d\xd7\x2e\xef\xc5\xb1\x1e\xfd\xcf\x8f\x0f"
-  "\x52\x1d\x0e\x84\x41\xbe\x47\x88\x77\x6b\x37\x39\xec\x90\x3c\x5d"
-  "\xe8\xfb\x4d\x4d\x62\xed\xe8\xa6\xa6\x1e\x2c\x8b\xbe\xdf\xc8\x5e"
-  "\xcb\xcf\x62\xed\x30\xff\x88\xe4\x7f\xf2\x77\xda\x98\x96\x60\x87"
-  "\x85\x7c\x3d\xa5\x60\x2c\xc4\x17\xe8\x58\x57\x48\xdf\xcd\xaf\x9d"
-  "\x89\x6f\xf1\xf7\xce\x6a\xb8\x16\x71\x18\x64\xbc\x38\x7e\xbe\xdd"
-  "\xa3\x5e\x82\x73\xeb\x9f\x15\xc9\x78\x11\xe6\x6a\x7c\xae\x18\x80"
-  "\x11\x65\x6a\x14\x65\x96\xf4\xa8\x6f\x79\x1b\xd3\xf6\x07\x94\xb1"
-  "\x06\x94\x39\xaa\x28\x63\x96\xea\xe9\x08\x28\xe3\xf4\x2f\x93\xa8"
-  "\x19\x4c\x5b\x62\xbc\x7f\x99\xc4\xc4\x80\x32\xd3\x06\xd3\x96\x38"
-  "\x2f\xa0\xcc\x8a\x80\x32\xd9\x0a\xde\xd2\xfb\x65\xf4\xf7\x13\xcd"
-  "\x01\x65\x2a\x03\xca\xd4\xcb\xcf\xe8\x4b\x5a\xc5\x58\x8f\xfa\x84"
-  "\x32\x45\xb9\x1e\xc4\x7c\x6c\xff\xb4\xf1\x17\xda\x07\x80\x3a\x73"
-  "\xc0\xb4\x57\xc4\x99\x26\x1b\x4a\x73\x0a\xb2\xdb\x68\xef\x69\xbd"
-  "\x9e\xc7\x8c\xa3\xba\x3a\xe1\xe6\x53\xa4\x43\xbd\x96\x9b\xe3\x06"
-  "\xf3\xe3\xe6\x44\x7f\x3a\x6f\x9e\xe6\x4f\xe7\xcd\xa9\x83\xf9\x71"
-  "\xf3\x8a\x80\x32\xd9\x01\x65\x8a\x14\x65\xea\xa5\x7a\x2a\x03\xca"
-  "\xd4\x07\x94\xd9\x3f\x58\x3f\x6f\x6e\x0a\x28\x73\x2c\xa0\x4c\x87"
-  "\x8f\x87\x37\xf3\x3d\x1d\xd4\x1f\x30\x1d\x9f\x6f\xbf\xd0\x3e\x8c"
-  "\x58\x59\x9f\xe5\xfd\x18\x42\xaf\x6f\xd9\x56\x25\xf6\x25\xf0\x18"
-  "\x1f\x1d\x70\x0b\x8f\x15\x4a\xe3\xef\x1b\x7d\xae\x70\x1a\x73\x91"
-  "\xb7\x5d\x87\x8c\x2e\xf4\x31\x6f\xc9\xb0\x43\x52\xb6\xfc\xee\x93"
-  "\xde\x17\xf3\x98\x50\x7c\x7e\x71\x4b\x8a\xe8\x7f\xb7\x54\x49\x6b"
-  "\xb2\xd4\x1e\x9c\x37\xdc\x52\xf5\xcd\xe8\xba\x75\x2a\xd1\x45\x31"
-  "\x52\x10\x47\xdb\xc0\xdc\x61\x80\x56\xaa\xf3\xd6\x99\x32\xad\x75"
-  "\xe2\x9d\x35\xc5\xe3\x71\x50\xbc\x9a\x5e\xcb\xad\x51\x8a\xf9\x06"
-  "\xd1\xea\x3c\x50\xe8\xd2\x04\xd0\xdc\x2d\x68\xbe\x35\x45\xd8\xa8"
-  "\x5b\x53\x64\x7b\x12\x52\xff\x4a\x4f\x34\xb6\xa2\xcf\x47\xef\xe9"
-  "\x5a\x6a\xd0\x7f\xc4\x39\x13\xd1\xdd\x0e\xb7\x96\x72\x7f\x36\xa7"
-  "\x0f\xe8\xb7\xad\xe8\x2e\xfe\x1e\x4f\x6a\x8b\x95\xe2\x92\x93\x9f"
-  "\xd2\x94\x7b\x16\x7a\xf8\x9c\x8b\x6c\xe3\xad\xa7\x0e\x15\x39\x88"
-  "\xd6\x46\xf9\xfd\x36\xd2\xc2\x69\xea\x29\x3d\xb1\x9f\xde\x31\xd2"
-  "\xba\xfc\x21\xe7\x34\x82\x39\x8e\xbc\xad\x97\x79\x40\x31\xce\x11"
-  "\xb6\x2a\xd4\xdc\x47\xc9\x57\x41\xc3\xc4\x65\x42\x7f\xc6\x27\xf8"
-  "\xf7\x87\x70\xd4\xd3\xf1\xd3\xfc\x75\x6e\x7c\xaa\xbf\xce\x8d\xd7"
-  "\xfb\xf7\x07\x35\xf6\x87\xf1\xd9\x01\x65\x8a\x02\xca\x54\x28\xca"
-  "\x54\x4a\xf5\xd4\x07\x94\xd9\x1f\x50\x46\x69\xff\xb0\xcd\xe3\x8f"
-  "\x0e\xcc\x23\xb9\xbd\x1f\x6f\x57\x3c\xab\xab\xf8\x38\x35\xde\x29"
-  "\xa7\xd1\x7b\x4f\xf4\x3b\xf9\xbb\x7c\x81\x6f\x42\x6c\x80\x8d\x42"
-  "\xf8\x09\x09\xfe\x34\x4c\x48\xf6\xa7\x61\xc2\x6c\xf9\x79\x97\x98"
-  "\x07\xff\xa1\x13\x26\x94\x49\x7a\xe6\x8c\xd9\x06\x0f\xc5\xb8\x17"
-  "\x2d\x23\x3f\x8c\xc6\x27\xbe\xc7\x62\x2b\xfa\x8e\xe7\x20\x96\xf6"
-  "\xb6\x74\x16\x40\x18\xc5\x4d\xb2\xc3\xc4\x4a\x9c\x9f\x51\x4c\xd7"
-  "\x6e\xf4\xa7\x16\x22\x8e\x74\xac\xbf\x1a\xeb\x40\xde\x4d\x68\x08"
-  "\xa0\xa1\x31\x80\x86\x66\xc5\x73\x2c\x3e\xb7\x29\xda\x1d\x1b\x16"
-  "\xcf\xf7\x40\xa1\xcf\x3c\xc1\x21\xa7\xd3\x9c\x1e\xdb\xd8\x65\xe2"
-  "\x7e\x40\x0a\xed\x6b\x19\xd1\x0e\x13\x3e\x25\x3f\x58\xe0\x9c\x38"
-  "\x4a\xc9\x5b\xc1\x8b\x89\x49\xfe\x74\x4c\x4c\xf1\xa7\x63\x62\x9a"
-  "\xcf\xd6\x4c\x48\x17\x7d\x64\x62\x26\xda\x68\xae\xab\xc8\x0b\x5d"
-  "\x8c\x5b\x37\xd2\x3a\x8e\x7c\xd2\x89\x65\x4e\x6c\x2f\x7b\x56\x3d"
-  "\x42\x7a\xe6\x31\x07\xd9\x38\x5a\xff\x3f\xd1\x1c\x4a\x47\x7b\x22"
-  "\x4f\x58\xa5\xbd\x49\x3a\xc4\x6d\x95\x75\xdc\x5b\x7e\xc2\xea\x2d"
-  "\xfb\xcc\x88\x69\x68\xff\x6e\x75\x89\xb9\x87\xbd\x09\xf5\xb9\x1a"
-  "\x65\x82\xf3\xd4\x49\xbf\x97\xe6\x75\xc7\x68\xbf\x0a\xda\x1a\x8a"
-  "\xb7\x16\x25\xde\x69\x4e\xd2\x2a\xfa\x8a\x53\x57\x78\x0f\x6b\x87"
-  "\x49\x2d\xe4\xaf\x91\x2d\xa0\x7d\x2f\x87\xdc\x0e\xa0\xb5\x10\x9b"
-  "\xfb\x24\xf7\xa9\x31\xff\x88\x54\x76\xb6\xa2\xac\x43\x5a\xab\xe8"
-  "\xa2\xbc\x49\x6e\xd0\x1c\x72\x3a\x28\xae\x74\x9c\xf0\xc3\x27\xb5"
-  "\x1c\x42\x1b\x80\x65\x8c\x72\x19\x5a\xd7\x90\xe6\x23\x9a\x89\x45"
-  "\x74\xf7\x5c\x3b\xc7\x0d\x22\xf6\x5e\x17\xce\x67\xba\x6d\x45\x5d"
-  "\x60\x73\xb6\xd1\xfa\xa2\x46\xec\x1f\x98\x74\x24\xcc\x05\xda\x9e"
-  "\xb2\x13\xd8\x1f\x26\x1d\xf1\x94\x9d\x68\x44\xda\x50\xf7\x27\x72"
-  "\xbb\xa6\xe4\xdd\x9c\x39\x69\x8b\x16\xce\x9f\xb0\x74\xd1\xdc\xf4"
-  "\x39\x77\xe9\xd2\xb3\x9e\x5e\x9b\x39\x61\xdd\x86\x02\xdd\xa6\xbc"
-  "\xac\x82\xac\x9c\x27\x78\x28\x3c\xdd\xea\x02\xf1\x9d\x98\xbd\x3a"
-  "\xbf\x60\x06\xfd\x1c\xaf\xcb\xcd\x5b\xbb\x91\xff\xbc\x39\x12\xfc"
-  "\x91\x64\x15\xac\xcd\xd3\xdd\x98\x39\x5e\x77\xdf\xea\xac\xec\x0d"
-  "\x79\x6b\x83\xe2\xba\x4b\x97\xb7\x36\x6f\xed\xea\x4c\xdd\x0c\x5d"
-  "\x12\x61\x56\xa2\x53\xc8\x33\x49\xb6\x39\xf9\x38\x46\xa3\x5f\xdc"
-  "\x45\xb6\x87\xc6\xea\x4e\x98\xf2\x6b\xf2\xcb\x78\xec\x3a\xd4\x2d"
-  "\xb4\xf3\xf6\x5e\x4b\xd2\xfe\xc1\x63\x73\x52\xc0\xf8\x97\x14\x30"
-  "\xfe\x25\x75\x0c\x1e\x9b\x93\x5c\xfe\x65\x26\x6b\xfd\xcb\x4c\x8e"
-  "\x1f\x3c\x36\x4f\x1e\x1f\x50\x66\x7a\x40\x99\x79\x03\xb6\x03\x69"
-  "\xdd\xce\x6d\xcd\xe4\x8c\x80\x32\xb9\x01\x65\xcc\x01\xcf\x4a\xff"
-  "\x07\xfd\xd1\xc9\xf5\xca\xf1\x1e\x9f\xf7\xcb\xfd\xd7\x67\xb3\x26"
-  "\x37\xc9\x30\x34\x9e\xd4\xd1\x1d\x19\x02\xf6\xb8\x02\xb6\x4b\x82"
-  "\x75\x0c\xd8\xaa\xdd\x7c\xce\xdc\x25\x7c\xee\x29\xab\x25\x7b\x45"
-  "\x77\x66\xc8\xe3\x62\x07\xca\xe2\xfa\xd3\x30\xb9\xa5\x4e\xc0\x3a"
-  "\xf8\xda\xf0\xcb\xcb\x7b\xeb\x46\x80\x96\xca\x52\xec\x36\x66\x99"
-  "\xc4\x63\x04\x62\x5a\x14\x7e\xd0\xf6\x4c\x49\xc7\x39\xcc\x71\xaa"
-  "\x83\xde\x47\xda\x61\x0a\xd7\x65\x2a\x57\xc2\xf7\xbf\xf0\xfa\x5a"
-  "\xe8\xee\x0f\x8a\x87\x48\x36\x91\xea\xa5\x98\x82\x54\x37\xe2\xd0"
-  "\x30\x75\xd2\x68\x29\x36\x5c\x2c\x7e\xe2\x10\x67\x83\x8c\x13\xf1"
-  "\x71\xbb\xb2\x5d\xda\xdb\x29\x7c\x99\x29\xcd\xb2\xcf\x40\xfe\x7f"
-  "\x30\xdb\x11\x7c\x3f\x20\xc4\xec\xb2\x78\xdb\xac\xc5\x1d\x44\x93"
-  "\x8b\x7c\x4b\x5b\xbc\x1b\x5a\x6b\xdc\x38\x27\x85\x58\x3e\x47\x32"
-  "\x9e\x02\x5b\xbd\x9b\xbf\x47\x59\x65\x04\x73\x9d\xda\xdb\xc6\x06"
-  "\xca\xd1\xbc\xeb\x36\xfe\x4e\xb9\x84\xd2\xb1\x3c\xce\x0f\x1c\xb4"
-  "\x6f\x30\xd4\xbd\x34\x04\x67\x1d\x47\x73\xb8\xdb\x0c\x92\x3f\x5b"
-  "\x5a\x87\xb8\x82\xee\x69\x53\x83\xad\xd7\x72\xdb\x3e\x3b\x3c\x52"
-  "\x29\xdb\xe1\x43\xd5\xdc\xf6\xa9\x31\xfd\x20\xf2\xa2\x3b\x94\xef"
-  "\x21\xd9\xec\x5c\xda\x8f\x81\xb0\x5d\x17\x82\x25\xba\x0f\x61\xbb"
-  "\xb1\x2f\x5a\xdf\x28\x4e\x0a\x97\xec\x2b\xce\xfb\x93\x75\x72\xb9"
-  "\x4b\x69\x9f\xb4\xef\xd6\x81\x7d\xd5\x29\xe6\x7f\x53\x5f\x7a\x91"
-  "\xef\x93\x4b\xc6\xf9\xcf\x6d\x15\x52\x1b\xae\xc2\x67\xb4\x7f\xb7"
-  "\xf1\xfd\xbb\xf4\x4e\x9c\xe6\xc9\xf9\xb9\xe8\x87\xc5\x3b\xd1\x36"
-  "\x26\x57\xc9\x79\x7c\xdd\x98\xf2\x8a\x98\xeb\x50\x7c\x07\xe5\xed"
-  "\x1f\xc8\xa3\x72\x44\xb7\xd1\x4d\xe9\xcd\x72\xba\xf0\x03\x92\xdb"
-  "\x02\x9e\xbb\xe4\x67\xfc\x8d\xe3\xff\x6d\x2b\x24\xfc\x0e\xb4\xb9"
-  "\xb4\x0f\x41\xd5\x0e\x53\x97\xd4\xf2\x7e\x33\x35\x4e\xce\xe7\x6b"
-  "\x5f\xaf\xe1\xfc\xda\xed\x04\x6f\xe4\xc7\x56\xee\x47\x61\x19\xba"
-  "\x4b\x06\xe7\x0d\x2a\xd6\xcf\xf7\x44\x74\x13\x1e\xea\x33\xfc\x3e"
-  "\x07\x7c\x46\x5c\xb4\x3e\xef\x20\x1d\xd9\xe4\x86\x51\xb9\x77\xd3"
-  "\x1a\xf1\x54\x11\x3b\xd9\xc2\xf5\x87\x11\x3e\x93\x5b\xe0\x26\x7c"
-  "\x74\xe7\x0d\xeb\x31\x20\xad\x53\xa9\xfd\xcd\xa1\x64\x85\xf9\x07"
-  "\x14\xbc\x0c\xc7\xe7\x26\xff\xb6\x4e\x3d\x16\xf0\xdc\x21\x3f\xd3"
-  "\x7a\xac\xd0\xbd\xa9\x6d\x22\xef\x76\xb8\x50\x5d\x34\xa7\x45\x98"
-  "\x04\xff\xfa\x6e\x4f\xf6\xc7\x7f\xfb\xec\x80\xe7\x74\xf9\xb9\x8a"
-  "\xbf\x07\xb8\x3d\x53\xae\x43\xac\xc7\x7d\x6c\xdd\x57\xec\x08\xbf"
-  "\x34\xfd\xb9\xe3\xb7\x42\x7f\x6e\x6f\x50\xd0\x30\x04\x9f\x1b\x7d"
-  "\xf2\xbc\xbd\x49\xc6\x8f\xbf\x8f\x2a\xe0\xb0\x8f\xdc\x6e\x0f\xd4"
-  "\x97\x7c\x23\xe9\x19\xe9\xcc\xed\xee\x20\x79\x2e\x91\x77\x47\x7c"
-  "\x70\x3d\xbb\x23\x49\x91\x2e\xcd\x3b\xee\x78\x49\x1a\xab\xc9\x46"
-  "\x3a\xe9\x4e\x1d\x29\xae\x2f\xd7\x0b\x8a\xf7\x29\xdd\xf3\x81\xba"
-  "\x75\x47\x6e\x20\x5e\xba\x9b\x61\x00\x87\x0f\xa7\x34\xbf\xb8\xa3"
-  "\xde\xd7\xb6\x3b\xde\xb1\xc3\xd4\x7a\x59\x6f\xc5\x9a\xdb\xed\x35"
-  "\xa1\xfc\x79\x84\x3f\xee\xcf\xb3\x3b\xba\x7d\x3c\xbb\xc3\xe5\xc3"
-  "\x3b\x4d\xa3\x80\xfb\x00\x9f\xe3\x7c\x70\xd3\x74\x17\xd3\x0f\xb1"
-  "\xd7\x7f\x5a\xaa\x7f\x5d\xd3\xf4\x0a\x1c\x99\x8a\xba\x72\x15\x70"
-  "\x6d\xf8\x6c\x0e\x2d\x9f\x69\x35\xa1\xe5\x33\xad\x31\xb8\x7c\xa6"
-  "\x1d\x55\xd4\x7b\xfc\xe2\xba\x7d\x27\x28\xe8\xa9\xc3\xe7\x58\x7f"
-  "\x5d\xbe\x53\x17\xf0\x3c\x20\x7f\x86\xfd\x77\x5f\x61\x4a\x38\xa5"
-  "\x17\x8c\x85\x58\xa1\xeb\x77\xa6\x29\xf3\xdf\xed\x13\xf9\x44\x23"
-  "\x7f\x57\x45\xef\x01\x05\x9c\x31\x10\x8e\x60\x14\xf9\xd5\x32\xed"
-  "\x25\x21\x62\xd0\xca\x63\x90\xcd\x4b\x63\xd0\x9d\x07\xc4\xfb\x8d"
-  "\x36\xe4\xc5\x7b\xfa\x50\xe3\x09\xe2\xc5\xf1\xff\xce\x06\xc1\x9f"
-  "\x3b\x51\xff\x1f\xe2\xef\x53\x59\x69\x9b\x13\xf5\xa9\xaf\x13\xee"
-  "\xa2\x3d\x61\xfd\xf8\xbd\xd9\x7f\x8c\xbb\x2b\x8e\x59\x54\x8b\xeb"
-  "\x2c\x81\x63\xdf\x5d\xe3\xd1\xa7\xef\x8b\x71\x9b\xf5\x41\xf2\x52"
-  "\x99\x25\x6c\x51\x90\xf4\x0c\x94\x57\x9f\x1d\xee\xaa\x22\x7a\x15"
-  "\xe9\x46\x66\x19\x96\x4e\xf0\x76\xaa\x0f\xcb\x84\x92\x9b\xbc\xff"
-  "\x5d\xe8\xde\x5d\x4d\x01\xed\x38\xdf\x09\x3f\x9f\x29\xda\xf1\xf3"
-  "\xbd\x01\x75\x1f\x0f\xd1\x0e\x9a\xa7\x9d\x0f\xde\x8e\x9f\x8b\xbb"
-  "\xfe\xd4\xd8\x96\x41\x63\xff\xcf\xc7\x63\x5b\xce\x73\xbe\xfb\xa7"
-  "\xcf\x96\xe7\x7f\xa6\xf3\x38\xaf\x56\x03\x2f\xbb\xb8\xc8\x27\x37"
-  "\x09\x2e\x3b\xa6\x1a\xd2\x82\xd4\x59\xc2\x2c\x43\x17\xdb\xe1\xe7"
-  "\x07\xe5\x31\x43\x4a\xaf\x11\xb4\x20\x9f\xd4\x9c\x4f\xc7\xa9\x5c"
-  "\x28\x79\xcb\xfd\x53\xbc\x93\xf9\x39\xf6\xff\xbb\x64\xfb\xe1\xc4"
-  "\x31\xd5\x21\xf3\xb1\xd7\x32\x5d\x1b\x90\xe7\x52\xe4\x25\xf8\xe5"
-  "\x6d\x1d\x48\x9f\x2e\xa7\x5f\x9a\x9c\xa6\x67\x07\xc8\x09\xe5\x33"
-  "\xdd\xe3\xdf\xee\xe9\x45\xa2\x7d\x28\xa3\x41\xbc\x9e\x5e\x8d\x32"
-  "\xea\x0f\x2e\xa3\xe9\x07\x82\xeb\xda\x74\xe1\x7b\x8e\x80\x60\xf8"
-  "\xba\x50\x76\xfd\x5c\x07\x25\x39\x0d\x96\xcf\x8c\x28\x59\x3e\x97"
-  "\xd6\xc6\x19\x69\x01\x6d\xf4\x20\x8e\x16\xd1\xd6\xbb\x47\x07\xe0"
-  "\x36\x04\xd7\xc5\x19\x66\x6c\xa7\x27\x78\x3b\x67\xd4\x84\xd6\xc5"
-  "\x19\x74\x5f\x8e\x67\xb0\x2e\xce\x90\xef\x63\x0e\x56\xa6\x9b\x59"
-  "\x82\xd5\x73\xb7\x86\x7c\x13\x3b\xdc\x3d\x9d\xde\x73\x29\xd2\x47"
-  "\xf9\xeb\x1f\xb6\x81\xca\x11\xff\xdc\x62\x2e\x41\x72\xe8\xd4\x81"
-  "\xfa\x62\x3a\xd9\x6b\xb9\xbb\x28\x80\x57\x67\x10\xbf\xa7\x47\xad"
-  "\xbe\x4f\xf0\xeb\x9e\xdf\x07\xd0\x54\x1d\x9c\x5f\x77\xef\x47\x7e"
-  "\x9d\x09\xce\xaf\xbb\x8f\x84\xe6\xd7\xdd\x24\xff\x33\x83\xf9\x75"
-  "\x0f\x28\xf9\x45\x77\x01\x52\xfb\x6e\x88\x47\xdd\xe8\x5f\xc5\xea"
-  "\x84\x2d\x8f\x8d\x41\x5d\x11\x65\xba\xa9\x4c\x72\x8c\x4b\xe8\x89"
-  "\xee\x3a\xd0\x9e\x86\x7b\x46\xc9\xfd\x7f\x58\x35\x0c\x65\xfd\xcb"
-  "\x19\xdd\xe3\x43\xe5\x6c\xc6\x33\x56\xba\x83\x8c\xd6\xf1\x02\xea"
-  "\x35\x06\xb7\x05\xf7\x54\x22\x4f\x5f\x08\x92\xde\x20\xd6\x22\xef"
-  "\xb1\xfb\xdb\x88\x7b\xac\xfe\x32\x42\xbe\xa9\x79\x14\x5d\xd5\xa5"
-  "\x7c\x2e\x2c\xb3\x94\xa4\xc1\x32\x4b\xf9\xa3\x90\x57\xca\xaf\xfd"
-  "\xe9\x4b\x49\x0d\x2e\xaf\x94\x8c\xd0\xf2\x4a\x29\x0a\x2d\xaf\x94"
-  "\x6a\x92\x97\x1d\x52\x8e\xfa\x8f\x1b\x29\xfb\xfd\xdb\x8b\xf5\x62"
-  "\x39\xa6\x1e\x32\x92\x9e\x2f\xb5\xdd\xf2\x87\x6c\x1c\xc9\xaa\x0e"
-  "\xfd\x2b\xa4\x7f\x2c\xd1\x78\xb9\x38\x42\xe2\x46\x1e\x56\x16\x86"
-  "\x8c\x57\x1f\xd5\x8a\x73\x3b\xda\xaf\xc6\xef\x13\x85\x99\x6f\x7a"
-  "\xd5\xaa\xbb\xf0\xb7\xba\x13\xee\x5d\xef\x55\x87\x99\xe9\x3c\x09"
-  "\x3f\x47\xc2\xd7\xfd\x67\x1e\x54\xca\x82\xf6\x0f\xd3\x1a\xef\x4e"
-  "\xb1\x7e\xf8\xd7\x4e\x98\x35\x47\xc8\xe5\xde\x87\xfc\xf9\x38\xd3"
-  "\x1e\x5c\x2e\x33\x5d\x28\x97\xbf\x06\x97\xcb\xac\xb8\xd0\x72\x99"
-  "\x45\x67\xcf\xfe\x3a\xb8\x1f\xcd\x4a\x95\xfa\xd1\x76\x2a\xa3\xcb"
-  "\x21\x7f\x75\xd6\xff\x25\x18\xfc\x8d\x7d\x64\xd6\x6b\x94\x3f\xa1"
-  "\x5b\xee\x47\xbc\x4c\x11\xe2\xe2\xf5\x4b\x30\x46\x09\x87\x12\x6f"
-  "\x7d\x4c\x77\xb0\x7e\x32\x8b\xdf\x6d\x3c\x31\x17\xb4\xc8\x43\xfd"
-  "\x5e\xc2\x91\x07\x70\x1a\xee\x8d\x26\x38\x4a\xa7\xd8\xdf\x0a\xf8"
-  "\x2e\x19\x8e\x6c\x9d\x80\x9d\x65\x67\xbd\x06\x7e\xa7\x89\x3f\xee"
-  "\x7b\xa5\xf6\x0f\xe5\xe3\x08\xc1\x13\x5c\x00\xcc\x34\xd1\x1f\xef"
-  "\x2d\xf2\xef\x8f\xf7\xa6\xf9\xeb\x27\xf2\x1f\xcb\x79\xd1\xce\xe1"
-  "\xef\x7d\x1e\x8b\xea\xae\x2b\xd3\x37\xef\x3d\x12\xd0\x37\x51\x07"
-  "\x66\x3f\x2d\x74\x60\xf6\xfc\x00\x5a\x3b\x82\xeb\xc0\xbd\xee\xd0"
-  "\x3a\x30\x3b\x3e\xb4\x0e\xcc\x4e\x26\x1d\xb0\xc3\xec\x6c\xff\xbe"
-  "\x39\x7b\x9e\x7f\xdb\xb1\x5e\xde\x37\x61\xf8\xe5\xf4\x4d\xf4\x85"
-  "\x46\x86\xea\x87\x92\xff\xaf\xa2\xfb\x7b\x2e\x83\x67\xe2\x3e\x0a"
-  "\x98\x03\xf4\x6e\x06\x6d\xbc\x81\x78\x58\xcb\xe7\x68\x73\xe2\x94"
-  "\x7c\xdc\x29\xe6\x5a\x26\x84\xdd\x43\x7b\xdb\x04\x3f\xef\x5b\xed"
-  "\xdf\xfe\x39\xc9\xc1\xf9\x39\x67\x1e\xf2\xd3\x14\x9c\x9f\x73\x0c"
-  "\xa1\xf9\x39\xa7\x84\xce\x28\x0e\xee\x53\x73\xe8\x0e\x32\xad\x3c"
-  "\x36\x9d\x86\x39\xe7\x2e\x6d\x7c\x9a\x73\xcc\x7f\x7c\x9a\x73\xf0"
-  "\xf2\xc7\xa7\xfb\xe2\x83\x8f\x4f\xf7\x25\x05\x1f\x9f\xee\x4b\x15"
-  "\xfd\xe1\x3e\xb3\x7f\x7f\xb8\x2f\xc3\x5f\x27\x90\x77\x57\x6c\x7c"
-  "\xba\xef\x68\x40\x1f\xd8\xd5\x09\xf7\x3f\x84\x3e\xc5\x33\x42\x6e"
-  "\xa9\x57\x07\xd0\xd8\x1d\x5c\x6e\xf7\x6b\x50\x6e\xbb\x82\xcb\xed"
-  "\x7e\x5d\x68\xb9\xdd\x4f\x67\x4b\x77\x0d\x96\xdb\xfd\xe9\x97\xef"
-  "\x53\xdc\x5f\xea\x2f\xb3\xfb\x73\x2f\x5f\x66\xf7\x1f\x09\x2e\xb3"
-  "\xfb\x3b\x82\xcb\xec\x7e\xe9\xcc\x7f\x6a\xb2\xbf\xcc\x52\xe3\xfc"
-  "\x65\x86\x7c\xbb\x62\x32\x4b\x2d\x09\x90\xd9\xba\x4e\x98\x8b\xf3"
-  "\x66\xf5\x51\x21\xb3\xb9\x87\xfd\x69\x4c\xad\x0f\x2e\xb3\xd4\x46"
-  "\x94\xd9\xba\xe0\x32\x4b\x3d\x16\x5a\x66\xa9\x0e\x94\xd9\xba\xc1"
-  "\x32\x9b\xab\xbd\x7c\x99\xcd\x9d\xee\x2f\xb3\xb9\x09\x97\x2f\xb3"
-  "\xb9\xe6\xe0\x32\x9b\x5b\x1d\x5c\x66\x73\xf7\x0b\x99\xcd\xed\xf2"
-  "\x97\xd9\xdc\x66\x7f\x99\x21\xdf\xbe\xa5\xcc\x50\x3e\x2e\xb1\xaf"
-  "\xf5\x81\xb9\x3d\x7c\x5d\xf9\x81\x14\x3b\x3c\xa8\x15\xeb\xf2\x0f"
-  "\x70\xdd\x91\x64\xf8\x2e\xc2\x24\x0f\x1e\xbb\x1f\x58\x21\xa5\x2d"
-  "\x1d\x2c\x87\x07\x8c\x38\xae\x76\x37\x15\xf1\xfd\x52\x42\x86\xc4"
-  "\x73\x84\x13\x6b\x64\x0f\x54\x53\x59\x94\x31\xb3\xb9\xdc\x40\x63"
-  "\x31\xc2\x3b\x09\x0f\x9d\xa7\x0f\xc0\xd5\x74\x39\x7e\x59\xe8\xbd"
-  "\xd8\x6d\x2e\x6b\xf1\x14\xc4\xf7\xe0\x5f\x84\xae\x3e\x18\xe8\xff"
-  "\xd6\x61\xde\xaf\x84\x9e\xce\x0f\x58\x33\x79\x30\x84\xff\xfb\x20"
-  "\xf9\xbf\x75\xc1\xf5\xf4\xc1\x0b\xf8\xbf\x0f\x92\xff\x5b\xa7\x98"
-  "\xaf\x8e\x58\xe9\xb6\x07\xcc\x57\x1f\x3c\x18\xe3\x14\xba\xc3\xfd"
-  "\xd8\xb2\x36\x17\xd2\xdc\x11\x40\x33\xca\x66\xde\x6a\x89\xe6\x65"
-  "\x01\xe5\xdd\xc1\x69\x9e\x17\x87\x34\xbf\x1b\x9c\xe6\x79\x49\xa1"
-  "\x69\x9e\x37\x0f\x69\x7e\x77\x70\xdf\x9a\x97\x29\xe9\x41\x90\x79"
-  "\xf9\x3c\x73\x70\xf9\xcf\x0b\x90\x3f\xe8\x0b\x8a\x98\x83\x97\xf7"
-  "\x87\xb3\x2a\xe1\x68\x4f\x3b\xc1\x92\x8e\x04\x81\xed\x0e\xc4\x19"
-  "\x1c\x6e\x7e\xdc\x20\xdd\xa3\x3d\xf8\x41\x75\x6f\x7e\x8a\xe8\x8f"
-  "\xf3\xab\xfd\xfb\xe3\x7c\xbd\x7f\x7f\x7c\xd0\x1d\x50\xce\x18\x90"
-  "\x9f\x7a\xe5\x6c\xec\xfc\xae\x00\x1d\x78\xaf\x13\x16\xac\x15\x3a"
-  "\xb0\xe0\xb7\xfe\x74\x2c\x80\xe0\x3a\xb0\x20\x1e\xdb\xff\x5e\x70"
-  "\x1d\x58\x90\x1c\x5a\x07\x16\xa4\x21\x2f\xdf\x53\xea\xed\xe2\xa2"
-  "\x94\xa1\x01\x30\x05\xc1\x6d\xde\x82\x8a\xe0\xeb\x3a\x0b\xf6\x09"
-  "\x1e\x2f\x38\xee\xcf\xe3\x05\x07\xfd\x79\xb8\x00\xae\x00\x0f\x07"
-  "\xe2\xd1\xf4\x5a\x16\x06\xf6\x7f\x5b\x27\x2c\x94\xfa\x7f\xda\x9b"
-  "\xfe\x34\x2e\x94\xe6\x3f\xc1\xd6\xb2\x16\x66\x22\x2f\x6d\xc1\x79"
-  "\xb9\xd0\x1c\xbc\xcd\x0b\xab\x71\x0c\xb2\x79\x07\xf5\xa5\x85\xfb"
-  "\x31\x7d\x31\xbf\x53\xec\x3c\xc4\xd6\x62\xfa\x62\x37\x68\xf9\x78"
-  "\x35\x30\x2e\x2d\x3c\x46\x6b\xe4\x7c\x8d\x19\xf5\x37\x66\x14\xa4"
-  "\xd1\x18\x44\x74\xad\x2a\x0a\x7c\x2f\xc9\x43\x19\xf0\x33\xa7\x74"
-  "\xfe\x24\xc6\x08\x69\x36\xa7\x1b\x64\x7d\x27\x78\x7f\xdc\x69\x49"
-  "\xd4\x2f\x08\x5e\x86\x15\x6b\x9d\xe6\x00\xdb\x94\xa6\x0f\x2e\xe3"
-  "\xb4\xdc\xd0\xba\x93\x56\x21\xe4\x9c\x66\xf5\x97\x73\xda\x3e\xaf"
-  "\x65\x58\x3a\xb5\xd5\x8e\x7c\xbe\x1c\x19\xd3\xfb\xcb\x90\xf6\x7e"
-  "\xfb\xf2\xb6\xdc\x62\x18\x73\x12\x1e\x4a\xe4\xf5\xa9\x19\xce\x89"
-  "\x55\xd0\xc4\x6d\xc0\x43\xfc\x0e\x63\x82\x59\xe5\x06\x35\xdb\xfe"
-  "\x54\x1b\xe5\xd5\x59\x98\x8b\xdf\x99\x66\x61\x47\x29\x1e\x05\xea"
-  "\xc2\xc8\x76\x78\x68\xa6\x5f\x79\x0d\x80\x4d\xe0\x28\x12\xeb\xfb"
-  "\x0f\x19\xe5\x75\xf8\x50\xeb\xfb\x08\x53\x23\xef\xa7\x15\xef\xc2"
-  "\x1e\xaa\x0c\x39\x2e\x23\x4d\x74\x0e\x93\x68\xba\xb0\x1d\x78\xc8"
-  "\x21\xeb\xaf\x38\xa3\xb3\x08\x7c\x67\x40\x16\x45\x61\xde\x81\x0b"
-  "\xac\xe7\x2a\xfa\xc1\xa2\x69\x4a\x3c\x22\x26\xd3\xa2\x79\xf2\x39"
-  "\x0e\xfc\xad\xbf\x08\x2e\x89\x9e\x45\xe6\x00\x7a\x2a\xd1\xb7\x3c"
-  "\x20\xe1\xa8\xb9\x08\x8e\x38\xdb\xbe\xbb\x60\xa2\x17\xc2\x4e\x42"
-  "\xfa\x97\x55\xb4\x4f\xa6\xa6\x0b\xa2\xdc\xa0\x11\x73\xbb\x45\x5f"
-  "\xb5\xc4\xd3\x1a\x0e\x9d\xcf\xbd\xc7\x4a\xef\xe0\xf8\x7b\xfc\xf8"
-  "\x7b\xac\x2d\x46\x8f\x14\x7b\x67\x31\xd7\x89\x16\xc3\x19\x6b\xcd"
-  "\x6e\xd6\xb5\x97\x9f\x55\x5b\xec\x37\xff\xab\xa0\x3d\x38\xb4\x17"
-  "\xa2\x18\xee\x41\xf8\x3d\xa2\xaf\xa7\x07\xf8\xa4\x8b\x43\xcc\xff"
-  "\x16\xd3\xfc\xef\x9e\xe0\xfd\x7c\xf1\x05\xe6\x7f\x8b\x69\xfe\x77"
-  "\x8f\x72\xdc\x14\xef\x79\x16\xd7\x28\x7d\x52\x8a\x8b\xa2\x7b\x9c"
-  "\xfc\xcc\xf4\xe1\xb7\x56\x01\xdd\xc7\xcb\xa8\x6f\xda\xba\x9a\xa8"
-  "\xbf\xc6\xb6\x38\x1a\xe9\x4c\xb3\x96\xee\x7a\x15\x63\x19\xf5\xd7"
-  "\xc5\x76\x3e\x96\xb9\x45\x5f\x34\x19\x99\x63\x7c\x07\xea\xd0\x3a"
-  "\x83\x84\x6b\xf1\x91\xad\x06\xc6\xf7\x42\x0c\xeb\x80\xa1\xb6\x2e"
-  "\x3e\x2e\xaa\xc8\x5f\xe5\x7e\xab\xfb\x1c\x10\xde\x43\x45\x2d\x40"
-  "\x78\xbd\x03\xe3\x24\xe1\x4e\x9f\x4e\x7d\x9c\x70\x12\xee\x56\x84"
-  "\x23\xbc\x04\x27\xb7\x43\x9c\x23\x49\xcf\x54\xb6\x9d\xaf\xbf\x60"
-  "\xdd\x98\xfe\x1a\xad\xab\xd8\xa8\x9c\x69\x39\x9b\xd8\x41\xef\xcc"
-  "\xce\x58\x99\xe9\x29\x36\x31\x8f\xd6\xc4\xd2\xbf\xa2\x72\xef\xfe"
-  "\xb7\x3d\xbc\x60\x2c\x68\xa5\xb4\x77\x9a\x74\x2e\xd4\xe3\x74\x87"
-  "\xbf\x8d\x48\x0f\xf0\x7f\x17\xf3\x79\xa6\x1d\x16\x51\x6c\x00\x90"
-  "\xf6\x85\x92\x3d\x60\x36\x77\x2f\xd7\x8f\x0b\xed\x6b\xa0\x77\xd2"
-  "\xb4\x2f\x49\xc4\xfd\x59\x32\x2d\x60\xed\xcd\xb1\x93\xef\x6d\xf9"
-  "\x04\xeb\x5d\xf2\xbe\xd0\x91\x87\xdf\xf7\x97\xe9\x12\xbd\xe9\x14"
-  "\xbd\x0b\x12\xe3\xc1\x4a\x77\xa0\x7d\x5c\x62\x94\x7d\xb7\x80\xf4"
-  "\x4a\x79\x3c\xd0\xe5\x70\xbc\x01\xe3\xcc\x12\xee\xff\x7b\x06\x8d"
-  "\x0b\x4b\x9a\xb1\x7d\x7e\x3a\xd9\xca\x75\x68\x89\xbd\xc5\x89\x7a"
-  "\x93\x47\xfa\xff\xf0\x32\x84\xd9\x46\x67\xf3\xf0\x79\xe8\x69\x78"
-  "\x38\xd6\x63\x01\x6d\x8b\x83\x9f\x3d\x8a\x45\x1d\xe1\x7a\x4b\xe3"
-  "\xc6\x24\xb1\x27\x28\xa0\x8e\x87\xc7\xcb\x3c\x27\x98\xd6\xbc\x4f"
-  "\x40\xec\x69\x20\x5d\x78\x18\x68\x7f\xc4\xb0\x6e\x18\x4a\xb8\x64"
-  "\x1d\xb2\xb9\xdb\xa0\xd5\x1d\x38\xe7\x79\xb8\x20\x78\xdb\x1f\xa6"
-  "\xf1\xff\x05\x3b\x3c\xdc\xe1\x2f\xdb\x87\xf9\xf8\x2f\xbf\xd7\xb1"
-  "\x23\x0f\x02\xca\x35\xf9\xcb\x7e\x89\x9e\xf2\x43\xee\xb3\x29\x6d"
-  "\xa3\xf7\xbb\xab\x9c\x7c\xcf\xd5\x52\xec\xff\x4b\xe2\x2e\x64\x07"
-  "\x99\xb6\xcd\xed\x45\x58\x69\xbf\x2d\xda\xad\xa5\xa9\x7e\x6b\x46"
-  "\xd7\xf0\x35\xa3\x55\x9d\xb0\x54\x7a\xf7\xa3\xdf\xe1\x4f\xdf\xd2"
-  "\xcc\xd0\xbe\xc1\x52\x7a\xff\xb3\x2a\xb8\xcd\x58\x5a\x13\xdc\x37"
-  "\x58\x7a\x40\xb2\x0b\xab\x58\x44\xa0\x1e\x2c\x3d\x8a\x32\xe6\x65"
-  "\xe4\x39\x2c\xad\x85\x86\x9e\xc3\xea\x61\x60\x0e\x9b\x47\xf6\x60"
-  "\x69\xd7\xc0\x1c\xd6\x11\x6c\x0e\x6b\x0f\x22\x4f\xfd\xec\xe0\xf2"
-  "\xd4\xaf\x08\x3e\x87\xd5\x17\x88\x71\x5e\xdf\xe0\x2f\x67\x7d\x85"
-  "\xef\x9d\xf0\xd2\xcc\x2b\xe7\x0f\xeb\x5d\x83\xfd\xe1\x65\x1b\x84"
-  "\xac\x96\xfd\xc6\x9f\xb6\x65\xb1\xc1\x6d\xfb\xb2\xc4\xd0\xfe\xf0"
-  "\xb2\xd9\xa1\x6d\xfb\xb2\x8c\xc1\xfe\xb0\x6e\x48\x00\x4c\xc9\x80"
-  "\xaf\xe4\xe7\x9b\x2d\xab\x11\x7c\x5a\x46\xfe\x5c\x98\x02\xfe\x80"
-  "\xbf\xbe\x2f\xa3\xfe\x16\x83\xb6\xed\x24\xd9\x34\x59\x67\x42\xf1"
-  "\x84\x62\x98\xdc\x50\x05\x11\xd8\x07\xde\xeb\xb5\x3c\x32\xa0\xff"
-  "\xb4\x97\x8e\xea\x21\x1b\x19\x72\x4f\x9b\x5a\xa6\x8f\xe8\x78\x64"
-  "\xfa\x85\xde\x97\x86\xc5\x43\xda\x8b\x83\xf8\xf1\x08\xf7\xff\x08"
-  "\xc7\x85\x65\xf6\xc8\x3b\x01\x7d\xcc\x29\xf6\xc2\x2e\xdf\x2c\xe4"
-  "\xb6\x3c\x60\x2e\xfb\x48\x33\x3f\x17\x17\xd2\xde\x3e\xd2\x15\x5c"
-  "\x47\x97\x0f\xf0\x0b\xf5\x9f\xf0\xde\x19\x90\xaf\x13\x32\x58\x6e"
-  "\xf4\x46\x28\xd7\xba\x97\x4f\xf3\xb7\x49\xcb\x75\x01\xe5\x02\xe6"
-  "\x7f\x8f\xd0\xd9\xca\x50\x7b\x1c\x02\xc6\x9b\xe5\x0d\xa1\xc7\x9b"
-  "\x15\x53\x45\xfb\x1f\x0d\x78\xbf\xbc\xbc\xf9\xc2\xe3\xcd\xf2\x10"
-  "\xed\x5f\x01\xfe\xe3\xcd\x8a\x80\x77\xf4\x2b\x74\xc1\xc7\x9b\x15"
-  "\xd3\x64\x3b\x23\xec\xc6\x8a\xe7\x2f\xcd\xde\xac\xc8\xf5\xb7\x37"
-  "\x2b\xf4\x17\xb3\x37\x87\x06\xd9\x9b\x15\x07\x62\x6a\x82\xb6\xe5"
-  "\x48\x70\x7b\xb3\xa2\x43\xc8\xf0\xd1\xe9\xfe\xf6\x66\x85\xdb\x5f"
-  "\x86\x2b\x02\x64\xf8\x68\xc0\xfb\xef\xe5\xcd\xdf\xd4\x26\x85\x85"
-  "\x85\xa9\xc3\x54\x6a\x55\x18\xd0\xc5\x26\x2a\x18\x1a\xa6\x09\x0b"
-  "\xc7\xcf\x10\xe9\x7b\xa8\x3a\x4c\xad\xc1\x4f\xb8\xf4\x3d\x24\xe0"
-  "\x79\x28\x95\xc5\x8f\x46\xfa\x0e\x0f\x78\x1e\x72\x91\xfc\xa1\x52"
-  "\xbd\x72\xfd\x9a\x80\xe7\xf0\x8b\xe4\x0f\xf9\x96\xe5\x61\xd0\xb3"
-  "\xff\xf9\xc2\xb9\x39\x1b\x57\x67\x67\x65\xf2\xbd\xe5\x6b\x75\xab"
-  "\xd7\xac\x59\x9b\x9f\xaf\x2b\x58\xa7\x9b\x35\x73\xd1\x94\xbb\x74"
-  "\x62\x8b\x7a\xf6\x8c\x1b\x33\x23\x61\xfe\xa6\x3c\xca\x98\xbf\x78"
-  "\xae\x5e\x97\x36\x6b\xa6\x7f\xa6\x8c\x86\x6f\x45\xbf\x10\x16\xe5"
-  "\x5d\xd8\x65\xd7\x00\x54\x5c\xc3\xed\x4e\x47\x4b\x3d\x80\x98\x4f"
-  "\xac\x29\x3b\x82\x5e\x07\xeb\x33\x31\x3a\xaf\xd0\x0e\xab\x66\x50"
-  "\x23\x26\xd4\x9b\x21\xf7\x71\x8a\x2f\xb2\x6a\x19\xfb\x9d\x03\x74"
-  "\x0f\x80\xba\x1d\x0c\x7b\x9a\x70\xf6\x4f\xcf\xb6\x0e\x37\xe8\x4c"
-  "\xe4\xdb\xae\xb9\x13\xf3\x54\xec\x6e\x2f\xa6\x39\xa5\x73\xec\x8f"
-  "\xcd\xe5\x69\xbf\x33\xcb\x70\x31\x9d\xb0\xca\xc3\x7e\xc7\xf8\x33"
-  "\xbb\xbb\x52\x82\x5b\xf5\x47\xaf\x65\x65\x25\xd9\x85\x1a\x71\x5f"
-  "\x36\xec\x19\x01\xda\x3d\xd7\x50\xac\xc5\x55\x4d\xf2\xde\xe8\x32"
-  "\x7c\xb6\x83\xa1\x9a\xea\x26\x58\xaf\x7a\xe5\xff\xc3\xe1\x47\xf8"
-  "\xc1\x3b\x7d\x7b\xa9\x57\x35\xd1\xdd\xf2\x0b\x4f\xe0\x90\x1f\x69"
-  "\x4b\xb2\x15\x99\x21\xc6\xc3\xbe\x9a\x98\x0a\xaa\xd6\x12\x80\xcd"
-  "\x6e\xe6\xb6\xe6\x9d\xc4\xfa\x33\x66\xc6\x6c\x66\x5f\xd9\xd0\x6f"
-  "\x9c\xdf\x6d\x62\x3b\x4f\x81\x06\xfb\xb4\xca\x9a\x47\x67\x1a\x32"
-  "\x12\x6b\xcf\x83\x06\x79\x30\xea\x24\xac\xd6\x17\xcd\x67\x1e\xd3"
-  "\x7c\xd0\x7c\x68\xa4\xb3\xa4\x9f\x3c\xb0\xf3\x4f\xa0\xf9\xe7\x3e"
-  "\xb3\xba\x8f\xc5\x43\x51\x01\xeb\x62\x14\x83\xd5\xc9\x5c\xb4\xef"
-  "\xf5\x48\x86\x87\x60\xee\xea\x35\xc5\x43\x6b\x81\x13\xb6\x1e\x67"
-  "\xae\xd2\x3f\x89\xd8\x0e\x2d\xdd\x4e\x3a\x9b\xaa\xdd\x3a\x1f\xc2"
-  "\x3a\xf5\xa0\x6e\x31\x54\x83\x6d\x85\x13\x8a\x8e\xb3\xae\x23\x19"
-  "\x27\xa0\xd5\xb0\x1f\x56\xb5\x81\xfa\x48\xc7\xa7\xc0\xe3\x88\xee"
-  "\x1c\x5e\x59\x7c\x0e\xe2\xb7\x66\x51\xda\x39\x28\xdc\x0a\xd1\x85"
-  "\x7f\xa6\xb9\x50\x1b\xd6\x73\x0a\x1e\x39\x06\x2a\xc4\xa7\xde\xf2"
-  "\x29\xc4\x6f\x59\x46\x67\xb5\x53\xa0\xa6\x18\xe2\x99\x29\x31\xaa"
-  "\xcf\x94\x18\xdb\xc7\x12\x47\xf4\x9a\x12\xe3\x5a\x73\x11\xbe\xe3"
-  "\xb7\x30\xac\x0d\xe2\x7e\x77\xb2\x4d\x5d\x7d\x16\x46\xe9\x16\x90"
-  "\xfc\x57\xa7\xd7\x9c\x45\xf8\xf2\x2f\x62\xbd\x58\x56\x59\xc6\x1d"
-  "\xf1\x45\xa2\x4d\xef\x02\x2f\xe2\xaa\xee\x83\x51\x35\x7d\x10\xef"
-  "\x2d\xfb\x22\x96\x78\xd1\x5f\xfe\x71\x12\xda\xc1\xa1\xef\x3e\xd6"
-  "\xa8\xb1\x1d\xe9\x86\x16\x67\x1f\xb4\xc2\x27\x60\x33\x7e\x61\xfd"
-  "\xe7\xc7\x1a\xc3\xd1\x8f\x54\x59\x0b\x69\xff\xb9\xd0\x19\x53\x0b"
-  "\xc5\xa0\x32\xc3\xae\x62\x88\xca\x2d\x84\xa1\x27\x31\x9d\xdb\x9c"
-  "\xd2\x0f\xa7\xd9\xdc\x5f\x58\x0b\xf9\xf9\x6a\x43\x75\x71\x0b\x84"
-  "\xb5\x3a\xab\xe9\x1c\xaf\xda\x33\x6c\x78\xa5\xcd\x79\x14\x6c\xb9"
-  "\x7f\xb5\x7a\xa3\x86\x1b\x2b\xbc\xa0\xfd\xd5\xd7\x47\xd5\x36\xcd"
-  "\xd7\x60\xd3\x3b\xe1\x3d\xac\x9b\xed\x1c\x5e\x83\xb6\x2a\xa5\xd5"
-  "\xe9\xa2\x38\x34\x49\xac\x27\x3e\x72\x57\x1e\x8c\xaf\x3d\x0b\x09"
-  "\x7b\xcf\x42\x22\xeb\x4d\x54\xd3\x99\xe9\x47\x4f\xc5\xc2\x5e\xfc"
-  "\x8e\xc2\xb9\x17\xb6\x97\x9f\x9d\x66\xd1\xd2\xd9\xe9\xfe\x44\xa8"
-  "\xeb\xf3\x9d\x9d\xee\xeb\xf1\x9d\x9d\x46\x5d\x6a\xa6\xf3\xd3\xd8"
-  "\x2f\xcc\xa4\xcf\xbb\x4e\x83\x66\xfb\x69\x80\x89\x66\x35\xe8\x1e"
-  "\xa3\x98\x18\x6b\x26\xd8\x32\x4f\xf1\xdf\xed\xf0\x58\x07\x7e\x47"
-  "\xe1\x07\xe7\x6f\x8f\xf1\xf3\xbe\x1d\x92\xde\x62\x9a\x1a\xd3\x5a"
-  "\xf0\x3b\x0c\xbf\xdf\x37\xd5\x30\x07\x2b\xfd\x2f\x0d\xfa\x26\x91"
-  "\xa4\xbf\xe2\x9c\xf6\x7f\x69\x7a\x2d\x8f\x1d\xb4\xc3\x2f\x2a\x64"
-  "\x3d\x16\xf6\x7c\x55\xf3\x7b\x9d\xa7\x28\xae\xaf\x83\xd3\xd3\x6f"
-  "\x50\x51\x8c\x5f\x29\x9d\x68\xb8\x91\xea\x6d\x87\x35\x5a\xfc\x8e"
-  "\xc1\x0f\xf6\xcb\xc7\x6a\xe4\xb2\x3d\xfd\x06\xac\x73\xcd\x68\x4c"
-  "\x67\x72\x3a\xb6\x57\x43\x79\xff\xa7\xf3\x94\x5a\xc0\x24\xaa\x11"
-  "\xa7\x4b\xc2\x8f\x7d\x7d\x55\x36\xf5\xe9\x1e\x75\x0c\x3b\x94\x99"
-  "\x0c\x35\xd7\xb0\xa3\x7b\x77\xb3\x26\xd1\xd7\xd6\x64\xd8\xa1\x82"
-  "\xc7\x54\xc0\x31\xbb\xa9\x02\xf3\x0e\xe1\xe8\x49\x7c\x69\xca\xa0"
-  "\xfd\xa4\x6b\xcc\x76\x88\x3c\xae\x6c\x03\xb3\x3c\x9a\x4b\xe3\xe6"
-  "\xbf\x14\x5b\xc3\x99\x7a\x65\x6e\xab\xbd\x1b\xfe\xb9\xaf\x2b\xdc"
-  "\x74\x18\xd4\x36\x77\x3b\x4c\x8a\x83\x78\x5a\x83\xa9\xdb\xcd\xec"
-  "\xf8\xdd\x85\x9f\x6e\xd4\x93\xd1\x27\x61\x4d\xcb\xad\x71\x10\xf7"
-  "\x91\x11\x24\x7b\xb4\xe6\x84\xc2\x1e\x3d\xdd\xd2\xd1\xa8\xb0\x45"
-  "\x86\xd1\x83\x6d\xd1\x13\x3f\x11\xb6\x88\xb9\x85\xed\xf1\xd8\xa5"
-  "\xf4\xf0\x80\x74\xe9\xcc\xc8\xe3\x5f\x06\xa4\xbb\xa4\xf4\x3f\x07"
-  "\xa4\x3b\xa4\xf4\xab\x65\x5b\xd7\x4a\x74\x6c\x22\x5b\xb7\xf6\x3c"
-  "\xd9\xba\xd6\x4c\xc9\xd6\xf1\x33\x8e\x6b\x3f\x65\xaf\x9b\xc5\x3d"
-  "\xee\xb0\xf6\x37\x44\x3f\xfb\x1d\xc8\xb4\x47\x60\xda\x06\x4a\xab"
-  "\xfc\x04\x34\xf8\xe1\x76\x8e\x59\x56\x7e\x4c\x76\x8e\x6c\x1c\x9d"
-  "\x45\x79\xf5\x1a\xd6\xf6\xea\x6e\x76\xac\x66\x37\x3b\xd2\x6b\xc9"
-  "\xec\x90\xed\xdd\x2f\x30\xad\x02\xd3\x7e\x81\xf9\x64\xf7\x88\x27"
-  "\x2d\xfa\x46\x8a\xe3\xd8\x81\x7a\x9c\x1a\xa3\x82\xdc\x9d\xa8\xf3"
-  "\x14\xff\xa9\x04\xf9\x6b\x43\x9b\x44\x7b\x72\x79\x3c\x5c\x75\x12"
-  "\xda\xa8\x0e\xea\x6f\xd7\x6c\xf7\xd2\xba\xc4\x09\x28\x76\xb2\x93"
-  "\x74\x3e\x84\x68\x58\xb5\xf9\x01\x8a\xf3\xaa\x6a\x32\x00\xd0\xf9"
-  "\x7e\x3a\xbf\x82\x76\x57\x53\x89\x34\x1d\xca\x26\x59\xaf\xcd\xb6"
-  "\xc3\xbf\x65\x0b\x59\x1b\x78\xfc\xe8\x76\xc8\xdc\xcf\x2c\x68\x0b"
-  "\xb1\x6d\x31\x1e\x33\x50\xcc\x12\xec\xa3\xb4\xce\x6a\x78\x15\x3f"
-  "\x95\x72\xdc\x12\x8a\x01\x8e\x30\xb6\x36\x17\x10\xcd\x76\xc8\x74"
-  "\xb7\x14\x35\x52\xf9\x7a\xe2\x0d\xb3\x98\x64\x1c\x2a\x1e\xf7\x04"
-  "\xe7\xf0\x14\xf7\xc4\x0e\x6b\xc5\x99\xba\xc8\x8f\x93\x5a\x56\x38"
-  "\x80\xec\xbc\xad\x0b\x71\x14\xb5\x0b\x1c\x88\x8b\xa1\xdd\xf7\xcb"
-  "\x93\xf0\x47\x6f\x65\x5f\x21\xfe\x6c\x92\x17\xc5\xa9\xa2\x7d\x49"
-  "\xc8\x97\x28\x8a\x79\x20\xfc\xce\xcc\x73\x75\x9f\x00\x48\xb1\xb6"
-  "\x50\xdf\x32\x9d\x14\xcb\x8a\xe2\x6b\xf1\xd8\x5a\xea\x64\x60\x9b"
-  "\x12\xa3\x06\xe2\x6b\x7d\x0f\xb1\xb5\x90\xff\xf1\xb5\x6a\xb6\x1f"
-  "\xe9\x77\x52\x7c\x2d\xa4\x3f\x9d\xf4\x50\x6a\x93\xeb\xa5\x47\x38"
-  "\xcf\xa7\x53\xda\x2e\x0b\x6b\x96\xe5\x4f\xed\xa5\xb6\x60\x9e\x4e"
-  "\xf8\x83\xec\xa8\x1d\x1e\x77\x51\x3e\xa6\x45\x11\xfc\x24\xb4\x63"
-  "\xb6\x4c\x0f\xbc\xdb\xe9\x51\xef\x2a\x04\x8d\xb0\x69\x86\xe1\x54"
-  "\x5e\xd8\xb4\x27\x9a\x7d\x36\xed\x89\xdf\x0a\x9b\x26\x78\x2c\x6c"
-  "\xda\x13\xbf\x16\x36\xed\x89\xb7\xf8\xfe\x21\xb4\x69\x94\x47\x76"
-  "\x4d\xb6\x69\x7b\xaf\x61\xcd\x64\x3b\x7a\x2d\x4f\x54\xcb\xb6\x6d"
-  "\x07\xa6\x91\xed\x20\x1a\x85\x9d\x5a\xeb\x60\xff\x95\x08\x62\x7f"
-  "\x26\xfd\x36\x50\x1c\x8a\x2e\xe9\x37\x8d\x23\x11\xc2\xc6\x3d\xd1"
-  "\xed\xb3\x71\x4f\xe4\xfa\xca\x92\x8d\x33\xa8\x84\x8d\x13\xe9\x75"
-  "\x8f\x90\x8d\x5b\xeb\x20\x1e\x48\xf8\xd5\xf4\xde\x4c\x82\x47\x3e"
-  "\xae\x71\x29\x6d\x9c\x7f\xff\x32\xcc\x96\x6d\x1c\xd9\x36\x7c\x4e"
-  "\x47\x9b\xc6\xe3\xd1\x53\x3f\xab\x42\x9e\xcb\xfd\x8e\x64\x40\x6d"
-  "\xa6\x38\xd1\xc4\xb7\x7b\x4f\xc1\x50\x29\xa6\x8b\xd4\x6e\x43\xa5"
-  "\x7c\x2e\xd2\x0e\x4f\x54\x07\xfa\xcc\xf4\x62\x42\x71\x76\xeb\x7a"
-  "\x0f\xad\xed\x9a\xdb\xc1\x56\xcd\xcc\xad\xee\xe3\xe0\xdd\xfe\xd4"
-  "\x67\x24\x57\x9c\x5f\x0c\xa1\x6f\xb2\x3b\x38\x7e\xfe\x71\x95\x93"
-  "\xaf\xd7\x7f\xb6\x4b\x8d\x79\x46\xf8\xb9\x22\xef\x14\xd5\xa1\x28"
-  "\x37\xc1\x97\x97\x15\x41\x79\xb4\xc6\x88\x70\x8d\xa1\xd6\x14\x2e"
-  "\x9d\x8e\xac\x65\xa1\xe9\xc8\xda\x70\x01\x3a\x9e\xe7\x74\xa0\xbf"
-  "\x85\xf3\xa3\xe1\xa7\x21\x2b\x85\x9e\x79\x6c\xd1\xe0\xf5\xfc\x5e"
-  "\xca\x0f\x53\xe4\x2b\xeb\xfa\x2c\x48\x79\x45\x7d\x4f\xaa\x2e\x8c"
-  "\xff\xc9\xb1\x17\xc6\xff\xe4\xcc\x8b\xe0\x5f\x4d\xb6\x8f\xce\xde"
-  "\x79\x2c\xfe\x70\x13\xdd\xbc\xef\x35\x53\x8c\x25\x84\x2b\x93\xde"
-  "\xb7\x7c\x66\x1a\xcb\xe7\x7f\x3c\xde\xce\x4e\xcc\xe7\xf1\x3a\xd1"
-  "\x2e\xcf\xde\x0c\x20\xf6\xf4\x0d\x94\xf9\x6d\x20\x6d\xc3\xdc\x32"
-  "\x6d\x3c\xff\xd3\x40\xda\x30\x7f\x82\x22\xdf\xe3\x93\xf9\x93\xc6"
-  "\x0b\xac\x23\x45\xd9\x50\x3b\xe9\x8e\x85\x43\x38\x6d\xa1\xb3\x3e"
-  "\x55\x03\xef\x46\x9e\x42\xfd\x37\xf0\x77\x3b\xd2\xd9\x5e\xda\x2b"
-  "\x73\x7d\xab\x93\x62\x92\x39\xe5\xb3\x20\xd7\xe2\x38\x32\x82\xe2"
-  "\xaf\xd0\x7a\xfa\x2a\x4f\x9a\x5a\xc4\x4a\x7e\xaa\x52\x2e\x1b\x6a"
-  "\xed\x91\xea\x95\xea\xe4\xe7\xa4\xb0\x4c\x93\x5c\x86\x70\xd3\xd9"
-  "\x20\xb4\xff\xd7\xf3\x38\x65\xee\x6e\xb2\xb7\xd7\xa2\x7f\x3c\x42"
-  "\xd4\x93\x01\x52\x3d\xd8\xb7\xb3\x92\x2e\x50\xcf\x05\xda\x97\x9d"
-  "\x7c\xf9\xed\x03\xa9\x7d\xd9\xb9\x17\x69\xdf\x85\xea\x7d\xe7\xf2"
-  "\xeb\x8d\x95\xeb\xed\xba\x7c\xbe\x3e\x3d\xea\xd2\xf9\x9a\x24\xf1"
-  "\xf5\xe9\xb4\x8b\xf0\x35\x58\x3d\x25\x97\x5e\x8f\x4e\xae\xa7\x31"
-  "\x58\x3d\xc0\xff\x42\xc6\xe9\xd1\xca\x77\x17\xd0\xbd\x21\x22\x56"
-  "\x79\x0e\x28\xef\x56\x11\xf7\x89\xe4\xc4\xc9\x77\xab\xf8\xce\x99"
-  "\xe5\x4c\x5e\x55\x4f\x7e\x08\xf3\xda\x21\x27\x99\xd6\x02\x67\x6f"
-  "\x55\xde\x41\x92\x93\x7a\x91\x3b\x5d\x28\x36\x4e\x0a\xd5\xcd\x18"
-  "\x8f\xc1\xe2\x14\xf1\xf2\x72\xca\x28\x4e\x83\xd8\x53\x94\xd3\x28"
-  "\xfa\x66\x4e\x95\x1d\x9e\xe6\x71\x16\x29\x06\x73\x8f\x49\x82\xbf"
-  "\x8e\xc6\xd0\x01\x98\x46\x19\x26\xe8\x9a\x64\x79\x27\xec\x2b\x4e"
-  "\xf2\x3b\x63\x38\x27\x2f\x6f\x5d\xde\x5d\xba\xfc\xa7\x1f\x9b\x90"
-  "\x5f\xb0\xba\x60\x43\x3e\x3f\x8c\x1e\x09\x98\xa0\x2b\xc8\x7a\x7a"
-  "\xed\xba\x0d\x05\x89\x9b\x56\x67\x89\xc3\xeb\x37\x23\xa0\x12\x08"
-  "\xfc\x62\xfb\xc7\xa3\x0d\x3a\xca\xd4\x3c\x76\x44\x37\x8f\x81\x49"
-  "\xf1\xdf\xa5\xb3\xb9\x4d\xf1\x00\x4e\x9c\x1f\xf5\x5a\xd6\xad\xb0"
-  "\xc3\xa2\x06\x99\x8f\x14\xa7\x10\xfd\xa4\xf8\x93\xb0\x6e\x33\xc9"
-  "\x7e\x21\xba\xbc\x75\x22\x1e\x04\x3f\xff\x6f\x2b\xc0\x84\x56\xd0"
-  "\x5a\x37\xd2\x3a\xef\x3a\xd4\x81\x1c\x3b\x8f\xbb\x58\x48\xf3\xef"
-  "\xdc\xab\x65\xbf\x84\xde\x5b\x89\xf7\xcc\xd7\xdf\xd3\x0e\xeb\xe6"
-  "\x50\xbd\xd4\x6f\x6a\xd1\xff\x25\x5c\xcc\x92\xe3\x22\x1f\x18\x9f"
-  "\xb5\x48\x83\x5d\xf6\x7d\x91\xde\x28\x16\x71\x02\x7d\x86\xdc\xb8"
-  "\x3f\xc4\x3a\x40\x3a\xcf\xad\xad\x15\x67\xb7\x71\x3e\x95\x1b\x35"
-  "\x00\x6b\x41\xd8\xb2\x13\x14\x7b\x33\xe8\xbb\x72\x16\xf9\xb9\xdd"
-  "\xdb\xaf\x0f\x57\xb6\x19\xe7\xec\x28\x9f\xdc\xf7\xb1\xed\x71\x24"
-  "\x6b\x29\x8e\xc8\x10\x4c\xfb\x15\xdd\x7f\xc0\xca\x3f\xb7\x63\xda"
-  "\x10\xfc\x76\x91\x4c\x29\xce\x01\xe6\xd1\x5e\x1f\x55\x6b\xd1\x19"
-  "\xeb\xa1\xf8\x76\xd4\xeb\x5c\xb4\x7f\x7a\x41\x03\xd6\xc1\xb0\x0e"
-  "\x9b\xb9\x0f\x9a\x74\xcc\x4a\x6b\x80\x48\xfb\xf1\x26\x9d\x13\x58"
-  "\xd8\xf2\xcf\xa8\x1c\xf6\x8b\x78\x93\x91\x7c\x1f\x4c\xe7\xe7\xff"
-  "\x72\x8f\xca\x3c\x2f\xd0\xb1\x53\x04\x13\x6a\xdd\x9a\xc6\xe0\x5d"
-  "\x7c\x2c\x39\x0b\xb4\xc7\xab\x03\x72\x9d\x81\xf6\xfe\xc6\xcc\xbb"
-  "\x74\x99\xab\x0b\x74\xd9\x59\x39\x6b\x75\x99\x59\x99\xba\x9c\x75"
-  "\x05\xba\x27\xd6\xd1\x02\x12\x2d\x19\xf9\xe9\x84\x97\xda\xb7\x49"
-  "\x1f\x2e\xbf\x23\xef\xd9\x64\x18\x82\xed\x47\x9e\xe4\xcd\xef\xe9"
-  "\x35\x0c\xf5\xe7\x49\xde\x64\xa1\xc7\xeb\x71\xfe\x97\x9b\x20\xce"
-  "\x17\x86\x75\xe1\x33\xb6\x3f\xb7\xcb\xbf\xef\xe5\x6d\x95\x60\xdf"
-  "\x91\x61\xb9\x5e\x8c\x3b\x39\x90\xb7\x4b\xd2\xc7\x3a\x71\x16\x99"
-  "\xc7\xab\xa9\xe3\x67\x04\xd6\xdb\x43\x96\xa1\x18\x5d\x85\xb0\xe6"
-  "\x34\xac\x3f\xcc\x2c\xeb\xe3\x24\x1d\xd2\x7a\x4b\x3f\x77\x48\xfa"
-  "\x83\x3a\x91\xa7\x1b\xac\x3f\x79\x45\xa4\x3f\xac\x57\xaf\xe5\xfb"
-  "\x49\xdc\x2e\xb4\x53\xf8\x8c\xe3\xa9\x1d\xd6\x97\x50\x3b\x9c\x9b"
-  "\xf4\x5a\xd3\x1e\x3e\x5e\x7f\x49\xef\x66\x0f\xb9\x78\x8c\xa5\x08"
-  "\xd4\x0d\x94\x51\x5e\x81\x2c\x23\x19\x3e\x78\x1f\xe6\xfa\xe2\xaf"
-  "\x63\x82\x9f\x2d\x5c\xc7\xd0\x2f\x40\x9a\xd4\xb2\x5f\x40\x63\x00"
-  "\xd2\xd6\x51\xb0\x95\x31\xac\xa3\x4d\xa1\x07\xa7\x83\xe9\x01\xca"
-  "\x76\x4d\xf6\xba\x35\x4f\x61\x47\xcf\x5b\x5b\xb0\xc6\x40\xf1\x2b"
-  "\xc8\x0e\xf0\xe0\x18\x37\x66\xea\x36\xe4\xaf\x5d\x13\x09\xc1\xa0"
-  "\x06\x32\x95\xf2\x8f\xf5\xa2\xbe\xf6\xf4\xe8\xc3\xe9\x0c\x87\x38"
-  "\xb3\x51\xb0\xb7\x27\x1f\xe7\x3d\x7e\x72\x2f\x78\xde\x16\x9f\x84"
-  "\x7e\x62\x12\x70\x9f\x1f\x79\x26\xf6\x21\x14\xfc\x99\xf8\xd0\xa3"
-  "\x56\xe1\x78\x90\x5f\x25\xeb\x00\xfe\xae\xc7\x36\x95\xfa\xf6\x80"
-  "\x14\x1c\xeb\x51\x87\x1f\x27\xfb\x23\xf6\x9b\x9c\x44\x3b\x10\x53"
-  "\xd7\x0e\xf9\x64\xfb\xe9\xae\x0e\x2a\x7f\x4c\x2e\xb3\x73\xe0\x1c"
-  "\x75\xc1\x74\x59\x4f\x14\x65\xde\xa7\x34\x31\x7f\xce\xe3\x32\x67"
-  "\x42\xf6\x1a\x19\x0e\xf9\xca\xea\xb8\x1d\x29\x48\x0c\xb4\x0d\x7f"
-  "\x88\xa5\x77\xee\x82\x1e\xae\x7f\xda\xcf\x45\x6c\x14\xf4\xf1\xda"
-  "\xa1\x60\xaa\xb4\xff\xe5\x28\x1f\xd3\x8d\x88\xcb\x25\x70\x31\x4b"
-  "\xfe\x35\x72\x5d\x2c\xe2\xf3\xe6\x3a\xae\x67\x05\xa5\xbe\x35\xc9"
-  "\x82\x64\x9a\x9b\xb3\x1e\xfd\x10\x3b\xe4\x17\x70\xdd\xc2\xdf\x05"
-  "\x3f\x11\xb1\xd7\x48\xdf\xa8\x9d\xa4\x57\x3e\x9d\x2a\x68\x96\xe5"
-  "\x4d\x6d\xc6\x72\x45\x3a\x1e\x6f\xb7\xc0\x2e\xf3\x32\x54\x3c\x19"
-  "\xde\x6f\xb5\x48\x4b\xaf\xe8\xbb\x7c\x5e\x29\xe2\x02\xd1\x39\x9a"
-  "\x30\xa4\xd1\xd1\x09\x1b\xbe\xa2\xb3\x01\x31\x2e\x9a\xa7\x7d\xee"
-  "\xa0\xf8\x08\x22\xbe\xd0\x86\x14\xd4\xe1\x64\xe9\x7c\x30\x3d\xe3"
-  "\xf8\x9f\x9f\x2c\x64\xb7\x61\x85\xa2\xef\x39\xa4\xfd\x06\x43\x89"
-  "\x47\x64\xcf\x6c\xc6\x39\xbc\xbf\x8a\x73\xc5\x1b\x4a\xe5\x72\x3c"
-  "\x96\x80\x5b\x8c\x89\xa7\x61\x43\x03\x8d\x11\x44\x9f\x1d\x36\x24"
-  "\x52\xfd\xd4\x3e\x1a\x73\xb9\xde\xc4\xd3\x9d\x04\x1b\x9a\x02\x68"
-  "\x38\x26\xe3\x92\x70\x77\xc8\xcf\x14\x2f\xcc\x0e\x9b\x72\x9b\x46"
-  "\x61\x9f\x72\xf2\x36\x5c\xd5\x54\x80\x7d\xcb\x49\x70\x1b\xa3\x64"
-  "\x1e\x62\xba\x19\x9f\xd1\xff\x59\xa7\x13\xef\x9c\x4e\x48\xb6\x68"
-  "\x53\x36\xc5\xa2\x32\xe9\x28\x9e\xe0\x74\x61\x6f\x78\xbc\x1c\x9e"
-  "\x77\xb3\xd4\x67\x23\xe8\x0c\x12\xdf\x77\xe3\x74\x73\xdb\x20\xe2"
-  "\x2b\x60\x3e\xf6\x91\x5e\x71\xef\x49\x84\xa0\x6d\xa3\x79\xa0\x0e"
-  "\xd4\x89\x26\xfe\x8e\x73\x63\xae\x88\x57\x32\xf4\x28\xe6\xd7\xcb"
-  "\xf2\xa3\x18\xd0\xd4\x6e\x2c\xa7\x6d\xe2\x31\xbe\x36\x1e\x94\xe9"
-  "\x95\xf2\xd4\x5c\x1f\x38\x0f\x36\x0e\xf4\xff\x9e\x11\x1c\xb6\x4b"
-  "\xae\x87\xc3\x22\x1c\xc1\xd3\x5d\x75\xbd\x96\x4d\x9a\x01\x3c\x22"
-  "\x4e\x8a\x96\xea\x69\xaa\xe7\x79\x3a\x9f\xad\xda\xc0\xdf\x19\xf1"
-  "\x7d\x71\xd8\x0e\xc7\x16\x9c\x67\x93\x0c\x74\x10\x86\x65\x34\x84"
-  "\x4f\xe8\xe2\xa6\x74\xb9\x4c\x98\x8a\xf8\xb8\x29\x53\xae\x5b\xc6"
-  "\x41\xf4\x5f\xd0\xe6\x89\xb6\x68\xa8\x8f\x10\x2c\xe1\xe5\x3a\xc1"
-  "\xef\xba\xd9\x74\x8a\xeb\x20\x6f\xe7\x26\xab\x52\xd6\xc2\x17\xdb"
-  "\x74\x4c\xa1\x0f\x44\xcf\x80\xfc\xed\x60\x8c\x13\x63\xc9\x26\x97"
-  "\x82\xc6\x94\x5e\x8b\x51\x3b\x20\x87\x72\x2e\x23\xba\xb7\x22\xe8"
-  "\x3d\x62\xbc\xaf\x20\x8c\x97\x71\x3a\x49\x1e\x38\x17\x9b\x06\x4d"
-  "\xd5\x14\xb7\xe9\x73\x07\xf2\x04\x69\x34\xee\x20\xbd\x42\xbc\x19"
-  "\xfe\xba\x69\xcc\x55\xd0\xab\x22\xbb\x8e\x69\x25\x32\x0c\xd2\xc7"
-  "\xf7\xb2\xc8\xfc\xc4\xbc\xfa\x01\x39\x4e\xe1\xb0\xfb\x65\x3a\x2f"
-  "\x32\x66\x48\xbc\x32\x7e\x29\xd5\xd1\x25\xd7\x81\xbf\xd1\x3e\x6c"
-  "\x1a\xe4\xab\x3e\xb6\xb9\x60\xad\x08\x60\x44\x83\xfc\xea\x35\x4f"
-  "\xad\xcd\x1c\xaf\x5b\xfd\x38\x85\x3a\xca\xcf\x5e\xbb\x36\x97\xbf"
-  "\x24\xf2\xf7\x03\xe3\x78\x7d\xc8\x07\xe1\xcb\x16\xae\x7f\x51\xec"
-  "\x8f\xa1\x7e\x41\xfd\x9d\xce\x15\x0c\x3d\x54\x74\x96\xcf\x4d\x6c"
-  "\xe6\x29\x60\x73\x31\x33\xf9\xef\xdc\xf6\x51\xfb\xe3\x9d\x62\x1c"
-  "\x40\x79\xd2\x18\xd9\x6b\xd9\x5c\xe9\xcf\xaf\xcd\xf5\xfe\x7d\x79"
-  "\xf3\xfe\xe0\x76\x62\xf3\x43\xdc\x4e\x94\x0a\xbd\x20\xfb\x44\x67"
-  "\x0b\x08\x2f\x96\xe9\x08\xc0\xe9\xf4\xd9\xa8\x42\x90\x6d\x94\x18"
-  "\x27\x0a\x13\x70\x0c\xaa\x14\x75\x15\x8e\xf2\xe9\x4d\x61\x8d\xd0"
-  "\x9b\xc2\x24\x3b\x54\x64\xcb\x73\x15\x31\x76\x6c\xe6\xfe\x23\xd9"
-  "\x74\xcc\x4f\x93\xf1\x55\x8d\xa0\x71\xa3\x30\x63\xb0\xff\x50\x18"
-  "\x45\xfe\x03\xed\x7b\x24\x5e\x20\xad\x5a\xd1\x6f\x0a\x2b\x14\xf6"
-  "\x27\x16\x9f\x6b\x82\xc9\xfa\x31\x1a\x8e\x27\xd0\xeb\xbc\x09\x6b"
-  "\x72\x0a\x66\x50\x18\xaa\xb5\xc6\xdc\xb5\x6b\x0a\xd6\x66\x06\xbe"
-  "\xc7\x4b\x94\x7d\x31\x39\x2e\xbd\x23\x82\xf8\x51\x88\xed\xdf\x3a"
-  "\x4a\x6e\x03\xb7\x53\xe8\x3b\x4a\x36\x2e\xaa\x13\x8a\xbe\xac\xe3"
-  "\xfb\x00\xb7\x8c\x92\xf5\x84\xe0\xee\x35\x32\x2f\xa6\x61\xfb\x37"
-  "\xcb\x77\xb4\x21\xae\x2d\x29\xf2\xb3\xaf\xfc\x96\x67\xf8\xd8\xb7"
-  "\x9b\xef\x19\x44\x9e\x16\x69\x14\xfe\x16\x3e\x6f\x39\x2e\x3d\xf3"
-  "\x58\x4b\x14\x17\xac\x1b\xb6\xec\x11\xfc\xdd\x82\xf2\x37\x4a\xb6"
-  "\xa2\x48\xec\xbb\xd9\x0d\xf0\x46\xb1\x23\xbc\x8e\xbf\x4f\xd8\xb2"
-  "\x5f\xae\x0f\xcb\x1f\x57\xd6\x49\xe3\x56\x20\x3e\x3b\x6c\x29\xa1"
-  "\xef\xed\x3c\xf6\xdb\x96\xee\x20\xb4\xe6\x2a\xe1\x7a\x2d\x45\xb1"
-  "\x58\xff\x41\xb9\xcd\x8b\x8d\x3c\x2d\xe1\x02\x6d\xec\x96\xda\x58"
-  "\x4f\xba\x45\xf5\x93\xfe\x4b\x34\x94\x48\x71\x4f\xec\x74\x57\x18"
-  "\xd1\xcf\x63\xa0\xc5\x53\xbf\x2e\x32\xe2\x38\xdf\x2d\xb7\x83\xda"
-  "\x78\xa0\xd8\xa1\x91\x63\x4f\x89\xf2\x45\x8f\x06\xd0\xf6\x8e\xa2"
-  "\x4c\x97\x75\x1c\xbd\x2b\x28\x9a\xc3\x2c\x85\x0d\xa4\x87\x14\x93"
-  "\xaa\x6a\x40\x0f\x8b\xda\x06\xeb\x5d\xd1\x6c\xd2\x3b\xa5\x2e\x65"
-  "\x4d\x59\x83\x9a\x94\xbf\xb6\xe0\x2e\xee\xdd\xa3\x63\x47\xa1\xcd"
-  "\x56\x17\x64\xad\xcb\xc9\x1f\xaf\xcb\xcf\x5c\x2d\x75\x7a\xbf\x3e"
-  "\x6f\xe1\x73\x77\xa7\xdc\xcf\x7a\x2d\x5b\x67\xfb\x6c\xcb\x56\x9f"
-  "\xfe\xd3\x1e\x30\x7e\xa7\xe8\xd6\x3d\xa2\x3f\x6d\xcd\x56\xf4\x5d"
-  "\x5e\x9e\xfa\x68\x1d\xf7\xd9\xb6\x2a\xc7\x7f\x9a\x1b\x47\x9c\x86"
-  "\xad\x53\x25\x9e\x3a\x05\x8f\xb7\x7e\xc6\xdb\xc9\x63\x6e\x15\x39"
-  "\xa9\x9d\x3c\xbe\x0c\xf7\xcf\xb6\x36\xcb\xed\xf5\xcd\x1b\xb6\xda"
-  "\xb9\x1f\x25\xf9\x6b\x17\x9a\x97\xfb\xfc\xd3\xe2\x22\x69\xcd\xad"
-  "\x4d\x9e\xe3\xc9\xfe\x35\xd2\x92\x29\x7c\xd5\xe2\xa9\x0b\x8b\x58"
-  "\xff\x2a\x23\xc5\xa2\x23\x19\x14\xaf\x96\x7d\x4b\xbe\x3f\xb0\xec"
-  "\x73\x1c\xb7\x8b\xf5\x4a\x3b\xc1\xc2\x9e\x6a\x93\x7c\x44\x69\x8f"
-  "\xf4\x55\xff\xde\x8e\x75\x21\x6d\xda\x0b\xd0\x86\xed\x2a\x46\xfb"
-  "\xb7\x93\xc7\xd7\x24\xff\x9a\xf5\xc4\x4b\xf7\xae\x99\x78\x4c\xf6"
-  "\x5a\xc4\xed\x40\xd9\x22\x1c\xfa\x7f\x5b\xb9\x6e\x78\x51\x47\x69"
-  "\x6f\x90\x53\xf6\x91\xa0\xf8\x1c\x8d\x45\xf8\x1b\xf5\xd6\x24\x9d"
-  "\x49\x34\xa5\x3a\xf2\x13\xa1\xa7\x27\x5e\xdd\x93\xaf\xd7\xd0\x7a"
-  "\x01\xf1\xc2\x56\xe3\x02\xa1\x3f\xa6\x78\xb4\x53\xcd\x4a\x7c\x12"
-  "\x2e\xe2\xa9\x86\xe8\x60\xf9\xf1\x6a\xd2\x6f\x7e\x8f\x57\x4f\x22"
-  "\xda\xd1\x62\x3b\xcb\x4f\x54\x87\x88\xaf\x75\xa1\x76\x46\xd1\xbd"
-  "\x66\x74\x47\x1d\xd9\x2b\x11\x67\xdf\xfc\xe6\x8b\x62\x6d\x40\xaa"
-  "\xd7\xf4\x16\x53\xbf\xc6\xc7\x95\x9d\x7c\x5c\x61\x20\xee\x60\x30"
-  "\x35\xf3\x7d\xba\xb9\xaf\xf1\xfb\x05\xa5\xf3\xdf\x8e\xa6\x5c\x37"
-  "\xbf\x9b\xcc\x54\x40\x7e\x9a\x9b\xde\x53\xf1\xf3\xcd\x87\x0a\xdc"
-  "\xb0\xd8\x45\x3a\x69\x72\x51\xdc\x76\x27\xf7\x17\xcc\x1a\x39\x56"
-  "\x3b\xdd\x95\x46\xf7\xef\x61\xbb\xc2\x48\xee\x3a\x13\xc5\xd8\x37"
-  "\xd3\xfd\x6a\x20\xe6\xe3\xf1\xb0\x13\x7d\x7a\x21\x03\xf3\x7c\xba"
-  "\xcf\x50\xcc\x15\xda\x51\x2e\x61\x5f\x20\xec\x5a\xf1\xae\x5a\xb6"
-  "\x13\xe6\x4f\x69\xef\xbb\x5d\xc2\x81\x75\xe1\xf8\x5f\x5c\x2a\xea"
-  "\x42\x7c\xbd\xb2\x3c\xcd\xf3\x07\xaf\x6f\xf8\xf0\x61\xf9\x79\x92"
-  "\x5f\x00\x62\xed\xea\x0f\x84\xeb\xa0\xbc\x76\xe5\xf3\x7d\xcc\x47"
-  "\xe5\xb5\x2b\x11\x33\xda\x54\x45\xf5\x87\x5a\x23\x62\xa6\x65\xa4"
-  "\xf7\x5a\xf2\xe1\x42\xfa\x13\x38\xbe\x13\xed\xb2\x5f\x28\xe4\xb3"
-  "\x2d\x8b\xfc\xc3\xa6\x22\x31\xaf\xed\x11\x77\xb1\xa1\x0f\xb0\xad"
-  "\x40\x8c\x65\xdb\xf4\xf2\x58\x86\x65\x0f\x48\xb6\x42\x1a\xe7\xb6"
-  "\x0d\xcc\x7f\x83\xef\xfb\xdf\x56\x25\xf3\x48\xe6\xb9\xe0\xd1\xb6"
-  "\x53\x3d\x91\x7f\xc9\xf6\xf1\x76\x1b\x7f\x77\xe1\xcb\xb7\xdc\xa8"
-  "\xe0\x3d\x3d\x27\x08\xbb\xb9\x0d\xc7\x7f\x53\xba\x18\x53\x44\x1a"
-  "\x8b\x3c\xd1\x43\x77\x27\x0a\x1e\x64\xf1\xb5\x19\x87\x29\x11\x69"
-  "\xb3\xc4\xda\x55\xaa\x7d\xc2\x96\x59\x70\xfc\xdb\x16\x25\xca\x6d"
-  "\x6b\x24\x5a\x94\xf4\x2e\xc9\x79\x2a\x67\xdd\xa6\x1c\x5a\x50\xdb"
-  "\x90\xaf\x5b\xb3\x2e\x73\x6d\x64\x90\xf5\x90\x78\xba\x2f\xd5\x59"
-  "\x35\x10\xd7\xea\x99\x44\xda\xa7\x2f\xee\x0f\x78\xe6\x66\xdd\x4d"
-  "\xa4\x5f\x96\x1d\xb4\x56\xc0\xef\x70\xa0\xd8\xa8\x62\xdd\xa0\x8b"
-  "\xca\x0b\x5e\x3f\x73\x75\xcf\x26\x83\xe4\x63\x95\xfc\x91\xf8\x28"
-  "\xcd\x39\x58\x27\x6c\x8f\x90\xc7\x21\xa2\x8f\xfb\xe6\xfd\x89\xdc"
-  "\x2e\x7a\xfb\x0d\x1a\xce\xaf\xfe\x44\x1c\x6f\x2c\x5d\x76\xf4\xc5"
-  "\xa5\x76\x39\x65\x7e\x50\xfb\xd1\xd7\xd5\xf6\xb2\x2c\xd4\xd1\x67"
-  "\x12\x25\x5c\xc4\x3f\xc4\x6d\x39\x28\xef\x13\xa7\x78\xa1\xd6\x8d"
-  "\x14\xff\x77\xfb\x39\x6f\x19\xd9\x9b\xed\xd3\x64\xbb\x44\x63\x91"
-  "\x17\xf1\xbc\xfb\xb5\x23\x1c\xfb\x0d\xc5\x1d\xba\xa6\x1d\x4a\x4a"
-  "\xc4\x7d\x00\xdb\x33\xfd\xef\x03\x28\x49\xc1\x4f\x89\xf4\xd9\xa7"
-  "\xf8\x7d\xa1\x8f\x5c\x26\xd7\x97\xb6\xdd\x1a\x00\xb3\x0f\x69\x3a"
-  "\x32\xe0\xaf\x88\x98\xa5\x52\xdc\x62\xba\xc3\xa2\x24\x82\xe2\x82"
-  "\xfa\x74\x63\xfb\x04\xc9\x07\xe9\x22\xde\xd1\x78\x8b\x30\x7c\x2f"
-  "\x37\x2b\x47\xdd\x60\x7a\xa0\x36\xb1\xde\x2c\xe4\x4f\x49\x82\x4f"
-  "\x0f\x04\x8f\x30\x6d\x9a\xcf\x4f\x29\x89\xa2\x32\x4a\x3e\x60\x1d"
-  "\x33\xc5\xdc\xb4\x24\x43\x1e\xb3\x29\x26\xaa\xb8\x0b\x62\xfb\x91"
-  "\x03\xc5\x5d\x38\xe7\x2f\x29\xf2\xe1\xd8\x7e\x44\x5a\x8b\xd0\x30"
-  "\xb5\x25\xa9\x8e\xcf\xd9\x4a\x6a\x7c\x6b\x02\xdb\x8f\x90\xdd\xe5"
-  "\x38\x22\x3b\xc1\xe6\xe4\xf7\x93\xaa\xe4\xbb\x87\x11\xb6\x59\xf6"
-  "\x51\x64\x5c\x4d\x62\xcd\x89\xc7\xb1\xc4\x3e\x58\x89\x30\xdd\x03"
-  "\xeb\xb1\x74\xff\x90\x3c\x07\x34\x62\x3f\xe6\xbe\xf7\x33\x51\xbe"
-  "\xb9\x9e\xe5\x1d\x6e\x6f\x2c\x03\x78\x70\x7e\xf4\x0c\x04\xce\xdb"
-  "\xd0\x7f\xd0\x65\xe5\x64\xa1\xfb\xf0\x44\xee\xba\x19\x38\x75\x78"
-  "\x22\x37\x6b\x06\x6d\x29\x9b\x3f\x7b\x2e\xff\xc6\xce\x31\x23\xc8"
-  "\xfa\xf1\xc0\x1d\xa4\xb4\x66\x84\xf3\x5c\x5a\x3b\xed\x15\x77\x14"
-  "\x0e\x95\xbe\xb5\xd2\xf7\x10\x1c\xf7\x5c\xd8\x07\x7e\x45\x77\xd0"
-  "\x20\x0d\x56\xe9\x5e\x48\x79\xcc\x46\x5b\xfe\xcc\x9b\xf2\x7b\x32"
-  "\xbe\xc7\x9e\x62\x15\xd2\x1d\xa3\xdb\x9f\xfa\x0c\xdb\x34\xb0\xfe"
-  "\x21\xd6\x17\xc5\x7b\x2f\x4c\x77\xc9\xe9\xf2\x7a\x6c\xaf\xe5\xd9"
-  "\x28\x79\xed\x55\xc0\x3e\x3b\xca\x57\xd6\x6f\x6d\x3b\x4e\x7e\xbf"
-  "\x86\x30\x29\x32\xcf\x64\x3c\x26\x1d\x3b\x2d\xf9\x49\x61\xdc\xaf"
-  "\xb6\x3c\x93\xcc\xe3\x83\x92\x2f\xce\xd7\x99\x9f\x2d\x90\xeb\xa1"
-  "\x39\x02\xd1\x2d\xbd\xbb\xe1\xfd\x9e\xe2\x80\x8a\x38\xa2\xcf\x0e"
-  "\xc8\xff\x52\xee\x05\xeb\xdf\xc8\x9a\xdc\x5f\xb3\xc6\x9d\x9f\x60"
-  "\x9f\x7d\x1c\xc0\xbd\x91\xed\xef\xff\x9a\x1d\x20\x5e\xef\x7c\x0c"
-  "\x60\xc7\x7f\x03\x78\xc2\x96\x7f\xd9\x87\x7c\x5f\x70\xce\x7b\x9a"
-  "\xee\xc2\xab\x43\xb8\x05\xce\x33\xac\x16\xcb\x2c\xc8\x65\xa7\x6b"
-  "\x11\x6e\xfe\xa9\xd3\x6c\x2f\xc2\xce\x37\x60\xbb\x37\x32\xb7\x27"
-  "\xec\xa9\x2f\x75\x0f\x93\x1d\x7a\x2e\xc9\x51\x66\x9f\xcd\x2c\xea"
-  "\x5d\x6c\xfb\xad\xb7\xf4\x5a\x9e\x9b\x3e\x70\xa7\x15\xe2\x25\x1e"
-  "\x2d\x34\xd2\xef\xa7\xbe\xc4\x36\x7d\xb9\x0a\xc7\x50\x94\xc1\x97"
-  "\x08\x87\xf3\xff\x1c\x6e\x6f\x1c\x61\xb7\x8c\xc0\x4f\x62\x30\xbb"
-  "\x8f\xb4\x36\x79\x36\xb2\xc6\x5d\x2b\x91\xfe\x93\x48\xff\xd7\x6c"
-  "\x3f\xb6\xe1\xc0\xce\x4e\x00\xa2\xdf\x43\x38\x3d\x10\xb6\x6a\xb3"
-  "\x6a\x78\x1d\xe6\xaf\x32\xc6\x42\x1d\xc2\xae\x74\xc2\xf0\x5a\x84"
-  "\x59\xb9\x7e\x38\x70\xfa\xbb\x91\xee\x08\xfb\x6c\x0f\xd6\x4d\xf4"
-  "\x63\xfd\x1d\x32\x9d\x72\xfd\x44\xaf\xac\x83\xab\x68\xbd\x2b\xf2"
-  "\x2f\xff\x3f\x7b\xef\x03\x1f\x55\x71\xee\x8d\xcf\x6e\x02\x6c\xc2"
-  "\x26\x1b\x30\xe2\x8a\x41\x57\x89\xed\x6a\x11\xa2\xd2\x7b\x73\xbd"
-  "\x28\xa9\xe0\x7b\xd3\x5e\x34\xd4\xab\xf7\x4d\x6f\xd1\x84\x0a\x36"
-  "\x58\x84\x35\x84\xb0\x60\x48\xc2\x42\x73\x43\xcc\xbf\x2a\xda\x00"
-  "\x21\xa4\x2d\xda\xd0\xf2\x27\xf6\x62\x6f\x6c\xa9\xae\x25\x6a\x94"
-  "\x24\x1b\x2d\xb6\x31\xd2\xba\xc4\x10\x02\x2e\xb0\x92\x25\xbb\x24"
-  "\xbb\x67\x7e\xcf\x77\xe6\x9c\xec\x86\x26\xd4\xd8\xde\xdf\xbd\xef"
-  "\xe7\x7d\xf3\xf9\x6c\xce\x99\x39\x73\xe6\xcc\x3c\x33\xf3\xcc\xf3"
-  "\x3c\xf3\xfc\xd9\x87\x76\x4b\x19\x7e\xe9\x0c\xef\x9a\x1c\xe6\x8d"
-  "\xfa\xca\xad\x6e\x56\x9a\x8a\x35\x84\xfe\x78\x69\x4e\xa9\x76\x6f"
-  "\xa7\x35\x18\x48\x7e\xb2\x74\xa1\xd6\xbf\xc8\x7e\x2d\x5e\x9d\x2b"
-  "\xe4\xa8\x4b\x1f\xcb\x5b\x91\xbf\x94\xb8\xb3\x58\x66\x43\x96\xe0"
-  "\xdf\x96\x2f\xb3\xac\x5e\x65\x79\x7c\xe9\x8a\x95\xab\xf3\x97\xe7"
-  "\xce\x12\x2c\xf7\x9a\xe5\xab\x96\x41\xbc\x9a\xbb\x34\xd7\x16\x7b"
-  "\x19\xcd\x5d\xea\x5e\x08\x7d\x44\xe0\xb2\x5e\xf6\xcc\x0c\x55\xb6"
-  "\x18\xe0\x8e\x34\xc1\xbb\xc9\x75\x50\x7a\xda\xb2\x21\x0d\xcf\xa7"
-  "\xc8\xbd\xe6\x99\x24\xd1\xaf\xfe\x74\xed\x3d\xa1\xbb\x2b\x68\x54"
-  "\xe4\x0f\xa5\xb3\xb0\x0e\xf9\x33\x33\xb8\x9e\xfa\x44\x7d\x96\x74"
-  "\x6a\x0f\x53\x6d\xf9\xde\xee\x66\x65\x21\xea\x27\xce\x0a\x3a\x04"
-  "\x1d\x28\x6c\x8e\xca\xce\xf2\xad\x3d\x34\xb7\x27\x1a\x01\x87\x4a"
-  "\xc9\x47\xea\x4d\xba\x62\x1d\x68\xa1\xdd\x7a\x25\x05\x67\x82\xbb"
-  "\x1d\x4a\x4a\x58\x87\xa7\x74\x31\x68\x5a\x21\x5b\x17\xeb\x60\x6b"
-  "\x81\x36\xbf\xf5\xb0\x29\xd9\x3c\xfd\x2e\x89\x9b\xb7\x6e\x42\x79"
-  "\x1a\xa7\xbb\x64\xfb\x45\xdc\x56\xda\x8f\xca\xb6\x2a\xf1\x33\x9d"
-  "\xa1\x35\x66\x35\x76\xf1\x87\xcd\x4a\xd9\x87\x87\x42\xb4\x6f\x2b"
-  "\x44\x8b\xf2\xca\xe4\x05\xa1\xb2\x0f\x0f\x28\xeb\xac\x7a\xe0\xef"
-  "\x22\x3b\xc1\x67\x75\x4e\x2c\x3f\x9f\x33\x39\x84\x78\x7b\x65\x1f"
-  "\xfe\x92\x73\x7a\x37\xf6\xc3\xb7\xb0\x47\x52\xba\x49\x4d\xb7\x20"
-  "\xad\x10\x2d\x46\x79\xed\x94\xee\x10\xb1\xfd\xb4\xf2\x23\xcb\xbe"
-  "\x8f\xb4\x49\x27\x74\x04\x53\x88\xf6\x9d\x87\xbe\x6a\x7d\x14\x3c"
-  "\x00\xe4\x10\xc3\x7d\x29\xdb\xa2\xe5\x83\x36\x95\x74\x22\x7b\x8c"
-  "\x60\x5a\x23\x71\xd6\x70\xb9\x47\xb4\x3e\x0b\x58\x96\x7d\x48\xbc"
-  "\x1e\x8d\x1f\xe2\x31\x6f\xbe\xee\x56\xae\x2f\x7d\x0c\x7b\x43\x46"
-  "\x48\x9c\x55\x31\x79\xb6\x51\x76\x58\x83\x1f\x74\xe1\xb1\x3f\xd0"
-  "\x38\x59\xb3\xbc\x2c\x56\xae\xcf\xb2\xe3\x11\x3c\x88\x87\x8b\xf9"
-  "\x5c\x26\xec\x4c\xb8\xde\xb0\x59\xa6\xb7\xce\x93\xfb\xd9\x33\x06"
-  "\xad\x2c\xe5\x09\x1d\x20\x9c\x59\xd1\xfc\xf7\xd4\x5d\x66\x9f\x39"
-  "\x16\xfe\xa1\xf6\xaa\xfe\xce\x9f\x79\x48\xa3\x0d\xe8\x3e\x7b\xa4"
-  "\x0d\xe7\x33\xe9\x97\x9f\x31\x7d\x67\xf5\xea\xbc\xac\xdc\xe5\xb8"
-  "\x58\x6f\x5e\x7b\xcb\xe5\x7b\x85\x51\xc6\x91\x79\xc6\x8e\x7e\x03"
-  "\x7f\x4a\x5b\x88\x67\x9a\x22\xf8\x3d\xc8\x9c\xe6\x03\xef\xe3\xac"
-  "\x98\x9e\x1d\x7b\xa3\x60\xa3\xa0\x37\x4e\x18\x98\x7e\x2c\x1d\x06"
-  "\xe1\x57\x3b\xce\xe8\x14\xeb\xbb\x22\x39\xc5\xef\x28\x37\x6a\x3a"
-  "\x47\xa3\xfb\x7e\xe8\x4a\x0e\x95\x9d\x5a\x6c\x99\x2e\x62\xe4\xe9"
-  "\xff\x63\x43\xa7\x1e\xf4\x45\x21\xdd\x43\x27\x43\xc8\xb1\xd4\xd8"
-  "\x6b\xaf\x5d\xe8\x24\x3c\x52\x9e\xcd\xb7\x76\x11\xed\x50\x9e\x39"
-  "\x66\x1b\x22\xec\x66\xe5\x19\x5c\xf9\x98\x3a\x17\xbc\xb4\xc7\x20"
-  "\xe7\x4a\x79\x9b\x38\x0b\x9a\xce\xfe\xbd\x9b\x95\xbf\x13\x6d\x26"
-  "\x3e\x65\x3a\xfb\x29\xdd\xb7\x89\x7d\xdf\x3c\x72\x8f\x66\x33\x3c"
-  "\xf5\xd1\x51\x9c\xd6\x04\xd7\x71\xf9\x47\x44\x86\xfc\x8b\xa2\x9f"
-  "\x9e\xeb\x84\xf6\x79\x14\x41\x6a\xd2\xc4\x68\x66\x8a\x37\x1a\x6e"
-  "\xb8\x3e\xc9\x3c\xff\x9e\x79\xa9\x45\x85\x05\x76\xae\x04\x03\x26"
-  "\x1e\x11\x27\xb0\xdc\x98\xfd\xf0\x2d\xc5\x12\x17\x56\x18\xb3\x47"
-  "\x6b\x6b\x85\x83\x43\x87\x93\xd1\x7a\xad\x2f\x5a\xcb\xf4\x07\x07"
-  "\xdd\x7a\xd0\x2a\xc0\xaf\x88\x77\xd9\xcd\x2a\xbe\xf5\x3a\xe5\x51"
-  "\xff\xed\xbc\x7c\x66\xbd\xb4\x2d\xa8\xd8\xae\x54\xce\xac\x0f\xd7"
-  "\x1f\xcd\x50\x3f\xd1\xc3\xfa\x3d\x85\x7d\x7a\x57\xf4\x3d\xcc\x65"
-  "\xf1\xb1\xd7\xe9\x7e\x8c\xf1\xb4\x41\xf6\x82\x3a\x08\xef\x94\x16"
-  "\x5d\x22\x7c\x64\x17\x72\x50\xfd\x39\x56\xf1\x5e\xe3\x18\xef\x89"
-  "\xb3\x8c\x58\x77\xac\xdf\x51\x49\xe3\xbf\xb0\x47\xdd\xef\x89\x1e"
-  "\xa9\x4c\xd2\xd6\x04\x3d\x8f\x91\xf2\xd8\xca\x14\xad\xcc\xe8\xfc"
-  "\x12\x74\x18\xb9\x13\xe3\xca\x07\xfa\xfa\xe0\x43\x6d\x0c\x9e\x17"
-  "\xb1\xd7\xef\x03\x0d\xd3\x46\x18\x22\x7e\x53\x02\xce\x4a\x09\xaf"
-  "\xa4\x3c\x69\xda\x94\xb2\x22\xde\x77\x35\x33\xd9\x1f\xd1\x99\x82"
-  "\x5f\xd7\xed\x7a\x81\x77\x80\xc6\xc3\x59\x03\x70\x4b\xdc\xa6\x94"
-  "\xa5\x5c\x3f\xef\x4e\xc4\xb6\x8a\xf3\x7c\x4d\xa7\x38\xe6\xde\x09"
-  "\xbf\x68\xd5\xd3\x78\x27\x95\x3b\x4e\xe5\x20\x6b\xea\xa1\xb2\xad"
-  "\xbd\xac\xf2\x33\xba\xb6\xc4\x6d\xe2\xbb\xe3\x3c\x5c\x99\x5d\xcc"
-  "\xa2\xd4\xfa\x5a\x45\x6c\xf9\x21\xc1\xeb\x4e\x08\xf3\xba\x55\x89"
-  "\x21\x07\x9b\x98\x31\x81\xbf\x4e\x75\xb4\xf0\x01\xa5\x65\x97\x22"
-  "\xfc\x43\xe1\x3c\xe8\x18\xe1\x91\x63\x73\xb6\x11\x6f\x83\x38\x91"
-  "\xeb\x69\x2c\x03\x01\xd0\x35\x4e\xfa\x46\x33\xe1\x89\xc3\x1b\x9f"
-  "\x62\xfa\x10\xbd\x43\x7b\x44\xd4\x39\x56\xf5\x64\x7b\x5f\x27\x7c"
-  "\x6a\x2f\x08\xd3\x6a\xd5\x42\x2e\x57\xf1\x02\x77\x42\x8f\xf7\xe0"
-  "\x39\x2f\xe2\xac\xb7\x60\xcd\x40\xa7\x11\xf9\x94\x3e\x3c\x7b\x1b"
-  "\xb3\xba\x3c\x7d\xac\x9d\xa8\x34\x5e\x64\xd6\x53\xfe\xe1\x59\x5e"
-  "\xa2\x27\xa8\x6e\xe8\x6f\xd3\x9a\x6f\x8d\xf3\xb0\x09\xd4\x97\xc3"
-  "\x82\xc6\x5a\x67\x4d\xa6\xf7\x9c\xb7\x51\xdb\x68\xcf\x4f\x3a\x38"
-  "\xd8\xa9\x17\x36\xbf\xd3\x78\x47\x9c\x8f\x25\x0b\xdc\x20\x7c\x96"
-  "\x59\xbf\x44\xef\x36\x13\x1d\x7d\x0c\xf5\x42\xb6\x40\xe9\x0e\xd4"
-  "\x71\x8e\x55\x7f\x93\xaf\xb6\x46\xe3\x1b\x44\x13\x38\x2d\x8f\xe3"
-  "\xcc\xa6\x7a\x56\x7b\x5f\x80\x21\xbf\x8a\xda\x47\x73\xde\x89\x76"
-  "\x52\x5f\x9b\xfc\x8e\xea\x79\x9a\xad\x36\xf6\x47\x4a\x2f\xd2\xe6"
-  "\x0b\xe1\xe3\x26\x69\x4f\x5a\xf5\x75\xc0\x84\xda\x7f\x4c\x19\x50"
-  "\xfa\x14\x6a\x1b\xea\xe1\x6b\xcc\xd1\xd4\x7e\x5d\x46\xd0\xcf\xa9"
-  "\x0f\xc7\x32\xec\x7e\x8e\x7a\x2d\xab\x04\xdc\x6e\xe6\x6b\x10\x93"
-  "\xa8\xfa\x10\x68\x63\xc0\x5c\xee\xe7\x55\x4f\xc6\x6d\x4a\x28\x89"
-  "\xf3\x5c\x4d\x78\xb9\x6a\xcb\xae\x01\xec\xa1\xd5\x4e\xed\x9b\x63"
-  "\xac\x89\x80\x8b\xf0\x81\x32\xc0\xfb\x40\x0b\x49\xfd\x8b\x6a\x5f"
-  "\x96\x3d\x2a\x8d\xfa\xa8\xa7\xb6\x60\x1c\xa7\xd1\xbe\x32\x1f\xfa"
-  "\x35\xd4\x06\xa2\x83\x7f\x90\x78\xa5\x18\x9d\xd4\x57\x33\x95\x21"
-  "\xfe\xa7\x5a\xfa\xe9\xcf\xe7\xb5\x52\xf6\xf0\x83\x61\xfb\x77\x3e"
-  "\xc0\x0b\xaa\x0a\xc5\x77\x8b\xb7\xe4\x8b\x6f\x20\x6e\x63\x5f\x9e"
-  "\x85\x9f\x68\xb6\x78\xc7\x5a\x13\xd4\x9f\x1f\x54\x6b\x36\xef\x68"
-  "\x3b\xad\xe7\x62\x89\x1b\x9e\x8d\x89\xdf\x34\x9f\xc7\xfb\xee\xbc"
-  "\x13\x67\x9f\xbb\xf5\x42\xd7\x47\xee\xab\x12\xff\xdf\x40\xe3\x7b"
-  "\x1e\xe3\x4c\xb4\x5d\x27\x74\x26\x5c\x3e\x2e\x78\x05\x11\xcb\x9a"
-  "\xb0\x18\xf4\xe5\x20\x87\xa3\x6f\xf8\x86\x79\xd7\x11\xdf\xf8\xc1"
-  "\xbe\xcb\x71\xef\xe2\x05\x5f\x5f\x6e\x59\x09\x1d\x98\x94\x3b\xec"
-  "\x16\xeb\xcd\xcb\xe6\x08\xe5\x18\xcb\xff\x5a\x70\x97\x65\x31\x31"
-  "\x36\x39\xb3\x1e\x90\x97\x05\x8b\x17\xe1\x7a\x99\xac\xd4\xe2\x77"
-  "\x3c\x7b\xd9\xfe\xf7\xc3\xa0\xdc\x23\x9f\xb5\xbb\x75\xd7\xc8\x18"
-  "\x1d\xa5\x5d\x4b\x08\x4e\x1e\x6f\x9c\x31\x5b\x8d\xc1\xb6\x84\xee"
-  "\x2d\xde\x18\x77\x12\x62\xa9\x9a\x36\xf1\x80\x29\x38\x89\x63\x8e"
-  "\x22\x86\x2a\xcd\xa1\xbe\xaa\x0b\x82\x27\x63\xf7\xdd\x52\xc4\x33"
-  "\x42\xdc\xb5\xfb\x02\xc6\xed\xd9\x56\x6d\x4c\x04\x7d\x4b\xf5\x52"
-  "\xbf\x87\x50\x27\x8d\xb5\x01\xf5\x82\xc6\xa5\x72\xd4\xff\x8a\x26"
-  "\xb9\x3f\x3f\x47\x73\xe9\x07\x76\x75\x0e\x2f\xa6\x74\x82\x9b\xdd"
-  "\x21\xf4\x8a\x14\x87\x19\xbe\x03\xa2\x95\xcd\xb7\x3e\x48\x78\xd8"
-  "\xa2\xd5\x49\x75\x19\xb5\x76\xa2\x3e\xf6\x39\x6d\xbf\x94\xb2\x8f"
-  "\x32\x41\x37\xc1\xc6\xc2\x64\xd7\x21\x8e\x40\xe6\x30\x6d\x48\xcf"
-  "\x08\x07\x82\x5e\xcc\x8c\xf7\xe9\x8a\x51\x26\x4c\x53\x29\xee\x2a"
-  "\xbd\x12\xa0\x3d\x36\x41\xc6\x35\xf5\xa8\x32\xe3\xe7\x0e\x8f\x3e"
-  "\x8e\xcf\x09\x1d\xc7\x0b\x8e\x68\xea\xdb\xb3\x8b\x6f\x4a\x94\xeb"
-  "\x40\x71\xe8\x98\xb4\xb7\x7b\xee\x65\x71\x8e\x29\x75\x46\x6e\x20"
-  "\xf8\x7a\x21\x1f\x34\x11\x7e\x80\x2e\x9d\x82\xf9\xc3\xce\x30\x57"
-  "\x81\xbf\x18\xf1\x44\x35\x9e\x92\xf8\x23\xa5\xdd\x16\xa2\xe7\xdf"
-  "\x13\xbe\x85\x88\x56\xcb\xa6\xf5\xa4\x3b\xc3\x9e\x2b\x46\xfb\xc5"
-  "\x38\x3a\x98\x51\x21\x58\x89\x33\x7b\xc0\x27\xf6\x78\x27\x74\xb7"
-  "\xd1\x57\x53\x90\xfa\x1c\xd9\x2f\xbd\xe2\xae\x74\x50\xbf\xf4\xd4"
-  "\x2f\xfb\x59\x26\xd6\xaa\xfd\x24\x68\x98\x69\x61\x3f\xd8\xdb\xea"
-  "\x23\xfb\xa8\xc0\x7f\xbd\xe8\xc3\xb6\x37\x46\xeb\x23\xd7\xa3\x8f"
-  "\x80\xc1\x36\xcd\x27\xbb\x68\x27\xe8\x06\x0f\xdb\xf6\x50\xfc\x26"
-  "\xe8\xb2\x77\x2d\xa1\xbd\x78\x01\xc6\xb0\xce\xc1\xab\xd1\xce\xd1"
-  "\xc6\x0b\xf5\xc9\xba\x9e\xcf\x36\x6d\x2a\xce\xf6\x3b\x9e\x9f\x35"
-  "\x3a\xbc\x9f\xbf\xff\xca\xf0\x7e\xfe\x46\xbc\x8f\x76\x40\xb7\xdf"
-  "\x04\x27\x0d\x34\xbf\x69\x9f\x2c\x1d\xed\xbb\xf1\x9b\xea\xd1\xae"
-  "\x51\x9f\xd1\xdc\xf7\x54\xe5\x8e\x5c\x13\x4a\x1d\xe2\x7c\x9f\x85"
-  "\xfe\x3b\x93\xfc\xde\xf3\xc7\xc2\xb1\x96\xbb\xb6\x98\x74\x96\x28"
-  "\xd0\x01\x02\xbf\x51\x7f\x47\xab\xd7\xa4\xab\x86\x9f\x97\x05\x84"
-  "\x57\x46\x7d\x4e\xeb\xc0\x42\x34\xf5\x4d\x54\xdf\xa2\xf8\x4d\x8c"
-  "\x13\x6f\x18\x1b\xef\x0b\x26\x03\xae\xd4\x56\x3b\xad\x6b\xf0\xbf"
-  "\x7a\xc9\x0f\xbe\x40\xf4\xef\x8f\x9b\x05\xbf\x19\xd3\xb5\x48\x9e"
-  "\x7d\xbc\x90\xe3\x66\x3f\x1b\x96\xd5\x52\xda\xee\x66\x97\xe6\xc9"
-  "\xb5\x7a\xdd\x0e\x5e\xf6\x71\x9f\xe2\x30\x71\xcb\x06\x13\xf1\x39"
-  "\x3f\x9c\x42\xfc\x87\x9e\xc7\x7e\xdc\x17\x9e\x3b\x52\xf7\x5f\x9b"
-  "\x3b\xf4\x7e\xd3\xe8\xf3\xe2\x85\x0f\xaf\x3c\x2f\x5e\xd8\xaf\xf2"
-  "\x19\xd9\x52\xbf\xe0\x87\x4c\xdb\x3f\x88\xcf\xd8\x61\x29\xc4\xf7"
-  "\x5f\xd8\x26\xbf\x4d\x30\x09\xa6\x01\xcf\x2c\x22\xb8\x15\x53\xd9"
-  "\x59\x1a\x6e\xc0\x1c\x32\x85\xb0\x7f\x31\x31\xcf\xe9\x59\x3a\xe1"
-  "\x11\xf5\xfc\xdc\xdd\x4c\xb8\x2f\x49\x71\x3c\x9b\xe8\x2d\xca\xd9"
-  "\x09\xfd\x3a\x5f\x4c\x17\xed\x8f\x3f\x5c\xe9\x66\xbf\x17\x31\x88"
-  "\xb9\xa1\xcb\x49\x75\x34\x8b\xf3\x2a\x69\xb3\x62\xc4\x3a\x47\xbc"
-  "\x13\xac\x75\xca\x4b\xa4\x76\x23\xf6\x09\xed\x35\x3f\xdc\xa3\xd1"
-  "\xfa\x8a\x23\x0d\xf0\x16\x36\xf2\xc4\xef\x24\xf5\x13\xec\x9e\xd7"
-  "\x2b\x0d\x03\x73\xcc\x0c\x7d\x1e\xd8\x3c\xbd\xe1\xdf\x67\xb3\xe8"
-  "\xb7\xcc\xdf\x61\xb6\x3b\x58\xe2\xa6\xbf\x8b\x66\x9f\xa6\x32\x3d"
-  "\xe0\xe0\x66\x3f\x3c\x24\x61\xf7\x43\x9f\x36\x3e\x6e\xf6\xc2\x12"
-  "\x8c\x07\xf8\xfb\x8c\x20\xef\x97\xf2\x8a\x1a\xda\xff\x9e\x51\x63"
-  "\x25\x3f\xbb\x72\x94\x3d\xe1\x3e\xcb\x8a\x35\x96\x65\xab\xd7\xad"
-  "\xba\xf1\xc6\x11\x32\xdf\x68\x21\xbf\x73\xd4\x58\xe5\x19\x4a\xcd"
-  "\x92\x08\xfe\x96\xf6\xb6\x1a\xea\xff\xb3\xe9\x97\xef\xab\x8b\xb2"
-  "\x54\x13\xcd\xac\x14\x16\xbe\xbf\x9d\x2d\xba\x3d\x22\x79\x27\x5b"
-  "\x74\xc7\x9d\x59\x0f\x2e\x5f\xba\x6c\x7d\x44\xee\x57\x23\x79\xa5"
-  "\xaa\x1d\xf4\xed\xa8\xe9\xf7\x12\xfe\xd0\x3d\xf0\x34\xf6\x9a\xed"
-  "\xdf\x2c\x0c\xf2\x53\x34\x77\x53\xe1\x17\xa1\x2d\x2f\xc8\xda\x08"
-  "\xbf\xf1\xeb\x80\xd7\x27\x49\xdf\x60\x21\x06\x1e\xc6\x44\x7d\xf7"
-  "\xd2\xfe\x7c\x51\xea\x97\x6d\x5f\xdb\x5e\x43\x34\x4f\xa9\x3b\x59"
-  "\xf2\x1b\xdb\x53\x28\x7f\x0a\x5d\xbf\x25\xcf\xc8\xb6\x3f\x42\x74"
-  "\x4a\x9a\xb0\x03\xcd\x87\x1d\xe8\xf6\xfb\x00\xa3\xd9\xbe\x62\x26"
-  "\xfd\x91\xd4\xf4\xc1\x4f\xa8\x9b\x6d\x17\x36\x3e\x28\x4b\xef\xdc"
-  "\x6e\x79\x82\xa5\xe0\x8a\xf3\x66\x7a\x96\xc2\xb7\xba\x93\xf9\xce"
-  "\x4c\x9c\x1b\x24\x53\xfe\xf3\x51\xba\x13\x2c\xca\x3c\xe9\x9f\xfc"
-  "\x8e\xed\xdb\x08\xfe\x7d\xea\xd9\xc1\xe8\x36\x07\xea\x1e\x18\x4f"
-  "\xb8\x3b\xde\x67\xe2\x59\xb0\xa9\xd6\x81\xce\xf3\xd0\x3a\x5e\x2c"
-  "\x74\x9f\xb1\x27\x4a\x7c\xb0\x7d\x58\xfe\x03\x5b\x13\x4a\xfb\xb4"
-  "\x39\xef\x77\xec\x60\xda\x9c\x1c\xa1\x2b\xbb\x2a\x6f\x79\xee\xf2"
-  "\x65\x96\x9b\xd7\xc4\xb2\x88\x88\x51\x39\xcb\x57\x59\x72\x97\x3f"
-  "\xb5\x76\xf9\x1a\x11\xed\x09\x4f\x2f\x93\xd3\xc4\xfe\x29\x73\x38"
-  "\x26\x9f\xd0\xd7\xdd\xb1\x1c\x74\x3b\x2f\xfb\x53\xa7\x88\x87\x81"
-  "\x3d\xc7\x38\xb3\x49\xa9\x8c\x4b\x93\x3c\x1f\x62\x29\xef\x0c\xc8"
-  "\x73\x0b\x77\xa2\x94\xf7\xef\xac\x40\x9a\xf2\x13\xc2\x31\xa6\x77"
-  "\xbc\x01\xf9\x8a\x0a\x23\xa2\x61\x76\x34\x69\x30\x72\xb3\xda\x34"
-  "\x55\x96\xed\x11\xb8\x82\xf6\x58\x93\x8c\xd3\x33\x8c\x2f\xe6\x28"
-  "\xd8\xa7\x76\x40\x87\x34\x4a\xf0\xcb\x31\x6e\x33\xbe\x85\x3a\x7b"
-  "\xe9\x7d\x1a\x8b\x44\xc2\x93\x84\x6b\xa8\x15\x6a\x7d\xf4\xcd\x06"
-  "\x7c\x0f\xf8\x83\xf6\xb9\x6b\xce\xb0\x9d\xa2\x2e\xa5\xd4\x6d\x06"
-  "\xfe\x80\xdd\x81\xb2\x95\xea\x11\xe7\x73\xb5\x69\xe0\xd3\x45\xbc"
-  "\x1a\xaa\x0b\xfc\x31\xe1\x01\xeb\xc1\x0d\x01\x3d\xf2\x64\x4c\xa3"
-  "\x1d\x90\x6b\x12\xbe\x70\x27\xf8\x1d\x3b\xed\x61\xd9\x76\x6d\x1a"
-  "\xe4\x3f\xa8\xd7\xcd\x76\xce\x43\x7d\x52\xb7\x60\x67\xad\x9b\xd5"
-  "\x34\x85\x69\xa7\x9d\x6e\x6d\x5f\x92\xed\x91\xed\xf4\x51\x5b\x44"
-  "\x8c\x42\x69\x23\x25\xfa\x0d\x5c\xb9\x4d\xed\xbb\xd6\x1f\xaa\xcf"
-  "\x43\xf3\x4e\x9c\xed\x70\x21\x4b\x96\xfd\x46\xfb\xd0\xf6\xc8\x36"
-  "\xab\xed\x35\x4b\x39\x7c\x6d\x72\xa4\x9c\x4a\xc6\x80\xa9\x4d\x0d"
-  "\xdb\x5e\xee\x28\xbe\x1c\x47\xdc\xbb\xf4\xb1\xef\x41\x49\x76\x51"
-  "\xca\x2c\x0b\xf0\x45\xd6\x83\xf7\x2d\xf8\xd7\xac\x05\x19\x0f\x3f"
-  "\xf0\x90\x38\x51\x1f\x7e\xbe\x70\xd5\xe8\x05\x46\xce\xab\x04\x1a"
-  "\x15\xcc\x85\x09\xdd\xac\xce\x27\xcf\x55\x6a\x0f\x8f\x3c\x57\xa9"
-  "\x3d\x46\x3f\x2f\x63\xbb\x8c\xf4\xf3\xd1\xae\x44\xd9\x75\x7d\xea"
-  "\x7c\xf1\x50\x7b\xfb\xc2\xf3\xa5\x4e\xe8\xf9\x42\x9e\x2d\xf9\xdc"
-  "\x5d\xc4\x6b\xec\x48\x8d\x7c\x16\xa6\xe9\x77\x59\x86\x69\xfa\x61"
-  "\x7c\xb0\x6b\x91\x46\xdf\x53\x5e\x12\xd1\xf6\x93\x40\xdb\x4b\x3f"
-  "\x81\x75\x22\xce\x32\xf8\x0d\xf0\x16\x26\x1d\xe2\x02\xc9\xf5\x09"
-  "\x1a\x2a\x8b\xf6\x13\xc4\x61\x07\x9f\x21\xe8\x78\xe8\x8d\x8b\x35"
-  "\xba\xab\x54\x5b\xa3\xa0\xe7\x45\x1c\xb9\x01\x11\xb3\xfd\xbc\xca"
-  "\x1b\x32\x5a\x37\x7b\x20\x1b\x20\xba\x38\x01\x32\x5b\xf0\x4e\x3c"
-  "\x6e\xe6\x1e\xb5\x4d\x2d\x90\x15\x80\x1e\x16\xf2\x22\x47\xed\x22"
-  "\xa1\x63\xb9\x79\xfa\xbd\x42\x66\x26\x74\x2c\x77\x79\xc2\x73\xae"
-  "\xce\x87\xb1\x04\x0c\x68\x1e\x04\x84\xbe\xd5\x70\x9f\xeb\x12\x87"
-  "\xfb\x9c\x4f\xfd\x1c\x14\x76\x7f\x93\xd4\x58\xd7\xa2\x8f\x63\xf5"
-  "\x6f\xf4\xbe\xd5\x2d\xfb\x8b\x7d\x73\xb0\x09\x58\x17\x5a\x1f\xff"
-  "\xbc\x7f\x75\x0d\x97\xf5\x6f\xe5\x9f\xf7\xaf\xae\x75\x58\x26\x26"
-  "\xd7\x08\xf1\x7a\x75\x17\xd1\x4f\xcc\x03\xea\xe7\xf1\x28\xb3\xe1"
-  "\x4b\x11\xf7\xb3\x46\xc3\xad\xf1\x9b\xf4\xaa\xbd\xff\xee\xaf\xe3"
-  "\xbc\x07\x75\x3d\xa7\x57\x72\x9e\x73\xd0\x8f\xae\xc0\xb1\x61\x1a"
-  "\x96\x07\x64\xfb\x76\xa7\x37\xdb\x3d\xd8\x9b\x03\x63\xea\x59\xe4"
-  "\xf3\xe3\x80\x25\x60\x92\x11\xf2\xce\x87\xbf\x6a\xbf\x63\x77\xf1"
-  "\x30\x6e\xfe\x52\xb1\x37\x6a\x13\xb3\x1c\xa9\xbd\x03\xf9\x35\x6e"
-  "\xb6\x9b\xa9\x7a\x24\xbe\xcb\xdf\x25\x78\xa7\xa9\xef\x3b\xb5\xf7"
-  "\x2f\xf7\x23\x27\x0c\x1d\x56\x2e\xcd\x5f\x7e\x97\xb0\x61\xb0\xaa"
-  "\xa1\xf7\x46\xae\xab\xb2\x3f\xdc\x0b\xd9\x04\x8d\xfb\x24\x9c\x4d"
-  "\xcb\xfd\xaf\x3e\x07\xf1\x50\xe9\xd9\x42\x2e\xf4\xf4\xbf\x21\x62"
-  "\x54\xd2\x18\x7d\x43\xe8\xae\x16\x30\x95\xff\xa8\x9f\x17\x61\xdf"
-  "\x20\x74\xc1\x5c\x05\x42\x7f\x82\xc6\x67\x77\x47\x58\x27\xac\x7e"
-  "\x59\x04\xfe\x30\x46\xb6\x71\xf5\x2a\x4b\xce\xd2\x55\xcb\x56\x3f"
-  "\xfe\xf8\x2c\xcb\xda\x55\xe2\x64\x00\x1b\xcb\x9a\xbc\xb5\x84\x1f"
-  "\x04\x5e\x58\xb8\x68\x51\xd6\xbd\x0f\xff\xcb\xb7\x46\xd0\x19\x86"
-  "\x6a\x87\x52\x4a\xf5\x12\xff\x53\xe1\x95\xfb\x58\x7d\x8b\x9b\x7d"
-  "\x5f\xd2\xbc\x44\xcb\xd0\xd8\xcf\x38\xc3\x7e\x94\x1c\x81\x2f\xe3"
-  "\x29\x9d\xc2\x1d\xf5\x79\x18\x0b\xb5\x5d\xc1\x48\xfa\x84\xd6\x40"
-  "\x94\xdf\xf1\xa3\x04\xcd\x9f\x6d\xde\x8d\x4c\x1f\x7d\x63\x35\xdb"
-  "\xa6\xe7\x34\x46\x3f\x9a\x4b\x7b\xee\x71\x7a\x9e\x42\x74\xe7\x32"
-  "\x41\x8b\x61\x4c\x24\x2d\xee\x34\x05\xe7\x0b\x5a\x3c\x6b\x3d\xd3"
-  "\x81\x0e\xd7\xd6\x47\x88\xf8\xda\x50\x3e\xef\xc9\x0a\xb2\x04\xcc"
-  "\xf3\xaa\x55\x98\xeb\x37\xf0\xe0\x00\x77\x67\xad\x37\xb0\xdd\x94"
-  "\xae\x3c\xc3\x58\xbb\x2f\xc8\x1e\xbd\x48\xfc\x08\xdd\x57\xf5\xd2"
-  "\xda\x08\x2a\x70\x2c\x0b\x9d\x0e\x82\xf3\x8f\xf6\x68\xb4\xae\x69"
-  "\x93\x45\xf8\x1b\x84\x8c\x1c\x73\x01\x34\x40\x56\xc8\xe4\x94\xfc"
-  "\xef\x8f\x5a\xaf\x28\xb7\x88\x33\xa6\x8f\x96\x4f\x6d\x6c\x46\xbb"
-  "\xa8\x9d\x8d\xd4\xae\x43\x68\x4f\xe5\xe3\xe8\x57\xd4\x9d\xa6\x60"
-  "\x8a\xb0\xb3\x43\x3b\x1f\xf5\xb1\x3b\xd1\xbe\x47\x9f\xba\x93\xd5"
-  "\x3d\x2e\xe6\x87\x38\x83\x54\x75\x1b\xa2\x69\xee\x4c\xea\x65\x3f"
-  "\x2e\xf6\x89\xf8\x4f\x3f\xce\x74\x33\x43\xb3\xa4\x87\xa5\xfc\x0b"
-  "\x65\xf0\x4c\xce\xb1\x1f\x17\xcb\x98\xbb\x3f\x2e\xd6\xca\x45\xb6"
-  "\x6d\xc1\x52\x1b\x11\x98\x2b\x1e\x7f\x7c\x79\xee\x1a\x2d\x9e\xa4"
-  "\x75\xf5\xca\x65\x77\xab\xb6\x39\xab\x96\xaf\xcb\x5a\xb1\x4c\xe8"
-  "\xfe\x51\xae\xbc\xbd\x8c\x16\x99\x05\x9e\x40\xe8\xd3\x08\x3a\xe4"
-  "\xa5\x0f\xeb\x54\x9a\xa4\x9b\xfd\x04\xbe\x99\x69\x7f\xff\xc9\x0f"
-  "\xe4\xfe\x10\x73\xde\xef\xf8\x89\x41\xdb\x1f\xfa\x27\xa6\x12\xad"
-  "\xff\x13\xda\x8b\x7f\xd4\x19\x89\xb3\x60\xff\xec\x5c\x05\x1d\x80"
-  "\x9f\xde\xad\x6c\xed\x9a\xc7\x63\xdf\xf2\xd2\x9a\x34\x82\x7e\x86"
-  "\x2c\x4b\xfa\x09\xfe\xc9\x32\xe0\x54\xe8\x10\x20\xae\x6f\x0f\xfb"
-  "\xc9\x5c\xa2\x45\x68\x4e\xfd\x34\x8d\x78\xa1\x79\x5b\x36\x30\xc3"
-  "\xae\x17\x78\x0f\x64\x94\x52\xbf\xf8\x27\xc5\x6f\xd0\x7a\x52\xcf"
-  "\x28\xdc\x15\xf4\xcc\xcd\x7e\x22\x7d\xe6\x97\x76\x2d\x56\xe5\x0c"
-  "\x8b\xa9\x5c\x83\x9b\x19\x9b\xe4\x3e\xf4\xb6\x59\xc8\x2b\x05\xde"
-  "\xf9\x49\x2b\x2f\x7b\xbb\x41\xc8\x80\xca\xde\x36\x2b\x3c\x27\x0a"
-  "\x69\xa2\x73\x62\xa9\x1e\x03\xe2\xb8\xab\xba\x12\x51\x04\xf3\x00"
-  "\xfa\x4b\xf5\x66\xc2\x3e\x1c\x7c\xbd\x5a\x7f\x26\x78\x76\xda\x57"
-  "\x8c\xd8\x5b\x78\x4c\xd7\x5c\x3e\xe0\xa9\xa7\xfd\x0d\x74\xa6\x37"
-  "\x7e\x53\x90\x51\x5e\xaa\xa0\x37\x7d\x37\x70\xda\xeb\x42\xc2\x2e"
-  "\x6d\x3d\x8b\x1b\x49\x67\xee\x59\xa4\xcd\x3f\x05\xef\x0f\x30\x23"
-  "\xb5\xb1\xb8\x87\xed\x11\x3a\x3c\x90\xdd\x02\x86\x83\x04\x37\x82"
-  "\x5d\x80\xbe\xd1\x48\xb4\x71\x5c\x2f\xdb\xb3\x15\xf0\xab\x54\x68"
-  "\xbe\x0f\x0a\x7a\xd9\x84\x38\xa7\xdd\x6c\xcf\x5a\xc0\x0e\x75\x51"
-  "\x9f\x5b\x82\xfe\xcc\x7f\x82\xff\x0a\xf4\x7d\x63\x01\xed\x45\x8f"
-  "\xa3\xff\x2f\x5e\x02\x7d\x49\xb4\xb5\xb8\x2f\x5a\xc6\x15\x01\x7b"
-  "\xa1\xcf\xf0\xe2\xa5\x8d\x7d\x5c\xb9\xe4\x60\xbc\x85\x76\xf5\x4b"
-  "\x7a\x16\x0c\x10\x1f\x08\xb9\x6d\xd1\x59\xf8\xd8\xa8\xa7\xb9\x5d"
-  "\xca\xe8\xbb\x86\xca\x0d\x2c\x01\x3e\x49\x8a\x6c\x3c\xd0\xee\xab"
-  "\x65\xed\xb6\x5a\xf6\x6e\x70\x1b\x73\xe6\xe3\x6c\xf0\xa5\xfa\xa3"
-  "\xf6\x6d\xd0\x1f\x8b\xa1\xfb\xa5\x96\x7f\x15\xdf\x4a\x3d\x7a\xec"
-  "\x7d\x76\xd4\xf9\x3e\xb3\xfc\x9b\x48\xa7\xb7\x66\xbe\xcb\x5a\xd3"
-  "\xde\x65\x45\x3d\x5c\x01\x8d\x52\xf8\x24\xbe\x51\x4a\x75\xd5\xc3"
-  "\x97\x47\x82\xd2\x6f\x8e\xa5\xfe\x47\x67\xd8\xb1\xde\xbd\x34\x97"
-  "\x7e\x85\x36\xbe\x53\x77\x81\x19\x9c\xab\x7e\x2b\xee\x25\xed\xe0"
-  "\xa9\x77\x2d\xeb\x14\x67\xc9\xf0\x5d\x82\xd8\xc0\xb4\xf7\x2a\x55"
-  "\x68\x63\x48\xb6\x9b\xe0\x15\xad\xbd\xbf\xbb\x70\xf8\x7d\xe1\x2b"
-  "\x75\x17\xe0\x41\x6d\x6a\x7b\x48\xc2\xa4\xb5\x93\x60\xfa\xaf\x2a"
-  "\x7c\x32\x23\xe1\xb3\xa7\x0f\xf0\x81\x9e\x88\x92\xef\xa9\xa7\xb6"
-  "\xa5\x11\x0c\x14\xed\x1b\x18\x7f\x6a\x2b\x47\xfd\x95\x17\x98\xd1"
-  "\xb9\x0a\x7a\x24\x2f\xdd\x6f\x5a\x1c\x6d\x50\x06\xce\x36\x56\x5d"
-  "\x64\x42\x86\x8b\x7d\xa8\x4a\x3c\x47\x9d\x2f\xe1\x4c\x30\xc1\x1b"
-  "\xf3\x87\x14\xfa\xcd\xa5\x5f\x2a\xe6\x21\x5d\xe7\xd1\x78\x95\x52"
-  "\x1b\x5a\x68\xac\xea\x71\x95\x73\xbc\x25\x07\x7e\x9d\x54\xda\x22"
-  "\x9c\x5f\xd6\xf2\xdd\x20\xcd\x65\x45\xf0\x4a\x2f\xb6\x28\x5b\x7b"
-  "\x54\xdd\xcb\x1f\x97\xef\xa2\x7d\xa5\xf6\x59\x61\xb7\x66\xac\x9b"
-  "\x2a\xe2\x83\xb2\x1d\x42\xbf\xf5\xa5\xe1\xfd\xbf\x4c\xc4\x1d\x7d"
-  "\x31\xa0\x17\x67\xc7\x5d\x0f\xa9\xf3\xfc\x21\x2a\xe3\x75\xb3\xab"
-  "\xdd\x72\xcf\x78\x29\xa8\xad\x29\xc2\xd7\x5e\x6d\xfe\xd3\x3a\xa5"
-  "\x76\xd3\x7c\x17\xb2\x47\x62\x0e\x83\x37\x0c\xcb\x1e\xe5\x3c\xff"
-  "\xe9\x5c\x6d\x9e\x53\xdf\x8c\xc0\x17\x58\xdb\x63\xed\xfb\x84\x57"
-  "\x5b\x71\x9e\xcf\xaf\xcb\x64\x46\xa2\x97\x8c\xd9\x26\xee\x0a\x36"
-  "\x63\x1e\x1a\xc5\xfa\x91\xcf\x88\xde\xf1\x9a\x08\x17\x77\x50\x7e"
-  "\xb4\x96\x0f\xbc\xac\x10\x8f\x08\xfe\x34\x63\xbd\x89\x17\x5e\x64"
-  "\x49\x42\xd6\xa3\xe5\xaf\xf7\x9a\xda\xcd\x0c\xfa\x7d\x41\xd8\xbc"
-  "\xe2\x1d\xca\x8f\x22\x3c\x7e\x98\xbe\xeb\xa4\xf2\x89\x5a\x79\xde"
-  "\x9f\x19\xed\xb2\x37\x8b\x3e\xc0\x8f\x83\x86\xd7\x29\x7f\x42\x86"
-  "\xdd\x6b\x12\xe3\xae\xe5\xad\xc9\x14\xfb\x10\xec\xeb\x88\xbe\xe2"
-  "\xa2\x3d\xbd\x22\x5f\x47\x74\x9b\x88\x8d\x1a\x91\xa7\x87\x2d\x23"
-  "\x7c\xf0\x44\xe4\x45\x51\x9b\xd9\x70\x9a\xbe\x5d\xf5\x84\xa0\x23"
-  "\xcd\x19\xeb\xa9\x3e\x7c\xe7\x09\xf5\xdb\xeb\x39\x93\xbe\xbd\x64"
-  "\x9e\xdc\xf3\x1a\x6a\x86\x69\x46\xd0\x3f\xfd\x99\xe2\xdb\x4a\x7f"
-  "\xa6\x3e\xd4\x9f\x19\x85\xef\xa3\x2e\xc8\x19\x45\x8c\xd6\x60\x1f"
-  "\x83\x5f\x49\x5e\x31\xd3\xc9\xa1\xcf\x49\xf5\x8a\xf6\xd8\x89\x8f"
-  "\x8f\x4b\x4e\x1b\xf5\xac\xaa\x7c\x8a\xdd\x59\xf8\x6f\xb4\x2e\xf6"
-  "\x62\xee\xb3\x90\xe1\xa3\x74\xcb\x13\x38\x03\xda\x7b\x2d\xe6\x60"
-  "\x88\x70\x45\x28\xe6\xa3\xf4\x39\x7d\x4c\x57\x48\xeb\x4f\xf2\x79"
-  "\x7b\xff\x01\x3e\x90\x8a\x14\xce\xe9\x7e\x16\xe6\xbf\xc9\x43\xfc"
-  "\xc8\xd6\x8f\x16\x89\xb3\xb7\xf8\x38\x9b\x2b\xd0\xc7\x5a\x8b\xbb"
-  "\x58\x6b\xd0\x55\x7c\xf8\x82\x37\x5a\x9e\xc1\x45\xa3\xde\xfb\xf1"
-  "\xac\x88\xd6\x5c\x56\xa8\x7e\x4c\x59\x1c\xe8\x5f\x82\xdd\xc7\x12"
-  "\xbf\xef\xad\xd7\xe8\xde\xbf\xd0\x87\x00\xfc\x28\xe1\x8c\x5e\x29"
-  "\xfb\x14\xe7\x80\x45\xdc\x6f\x65\x73\x36\x80\xef\xdd\xdb\x11\xef"
-  "\x63\x69\x6a\xbd\xe7\xd5\x7a\x03\x57\xaa\x17\xf3\xb6\xb5\x46\xc8"
-  "\x7e\x99\x12\xfb\x69\x76\x88\xea\x0e\xc5\x7e\x5a\x4f\xfb\x48\x51"
-  "\xd1\x25\xc8\x40\x7e\x7e\x1f\x7d\x27\xbb\x3d\xd8\xc1\xe0\x8f\xad"
-  "\x4e\xa1\xfd\xf6\xbc\x99\xa9\xe7\x8d\x45\xe7\xd8\xcf\x6e\x51\xb8"
-  "\x35\x81\xe8\x73\xc8\x3c\x8b\x80\xab\x41\xeb\x17\x86\xd8\x44\x57"
-  "\x9e\x9b\xc1\x9f\x10\xd5\xf1\x0f\x6f\x42\xbe\x4c\xf8\x2e\xc4\xcd"
-  "\xfa\xdf\x0c\xb8\x59\x15\xed\x01\xc2\xbf\xd0\xe6\xeb\x76\xc4\x6f"
-  "\x62\xf3\xb9\xde\x24\xce\x93\x95\x8a\xc9\x76\x1a\xdb\x16\xd1\x9e"
-  "\xb2\xae\xec\x88\xb3\xcd\x28\xfa\xd6\x7e\x9c\x6d\x72\x43\x97\xb5"
-  "\x16\xf2\xde\xb8\xb8\xc5\xde\x38\x63\x1a\xa7\xb1\xf3\x3b\x7e\xe6"
-  "\x76\xb3\x06\xb1\xaf\x97\x43\x97\x56\xec\x19\x3f\xbf\xdf\x1b\x73"
-  "\x0a\x3e\xa3\x11\x6b\x49\xa7\xe4\x07\x1b\xab\x3e\x23\xfa\x45\xc0"
-  "\xe5\xe7\xb7\xb5\x7b\xfc\x4e\x5e\x7a\x2a\x1d\xeb\x49\xfd\x86\x89"
-  "\xbe\x11\xe2\x5b\x4f\xa5\xbb\xd9\xcf\xd5\xbd\x59\xdc\x9b\xf1\x3c"
-  "\x38\x04\xdd\xdf\x9f\x95\xd7\x0e\x42\xc6\xf6\xb3\x54\xa2\xef\x9c"
-  "\xfd\x86\x53\xe9\xff\x62\x2e\xa6\xfd\xfd\xe7\xd9\x6e\x5d\x87\x4d"
-  "\xe5\xb9\x85\xcf\xa4\x31\xcf\xb7\x77\x9a\x63\x5d\x54\x09\xd1\xaa"
-  "\x89\x67\xd8\xfe\xf7\x06\x1d\x4c\x3f\x44\x7b\xf4\xa0\x9e\xe8\xf4"
-  "\x9d\x99\xc6\xca\xe9\x2c\x85\x9e\x4d\x3f\xc3\x7e\xfe\x4a\x50\xcf"
-  "\x12\xe9\x97\xe0\xbd\x2e\x27\x86\xea\x4d\x83\x3c\xa2\xed\x02\xf8"
-  "\xcf\x7d\xd2\x4e\x78\x07\x4b\x56\xa8\x3e\xc8\x51\xab\xa6\xb3\x64"
-  "\xc8\x04\x28\xcf\x9a\x15\x92\x67\x0c\x1a\xff\xb2\x79\x3a\x9b\x35"
-  "\xf2\xbb\x3f\x57\x7d\x21\xed\x17\x31\xe3\xd6\x79\xd9\xf5\xb6\x7b"
-  "\x78\x37\xd5\x0b\x1f\xb4\x9c\x5f\x67\xd6\xcb\xb3\xb8\x7d\xeb\x4d"
-  "\x35\x72\xfe\x09\x99\x3a\xcd\x3b\x9c\x59\xa8\xb2\x5a\x9d\xf0\x15"
-  "\x15\xfb\x71\x27\x74\x2f\x23\x64\x32\x09\xa2\x1d\xaa\x9f\x97\xd0"
-  "\xe6\x5b\xb3\x51\x07\xda\x93\xb5\x54\xca\x79\xe1\x03\x86\xe0\x2a"
-  "\xfc\xf8\x96\xef\x60\xc6\x67\x76\xb0\x84\xb6\xc7\x45\xbf\x1a\xe4"
-  "\x9a\x8c\x66\x68\xaf\x52\x8a\xf5\x46\x73\x83\xda\x8d\xef\x61\x8e"
-  "\xb4\x07\xcf\x3b\x8b\xf2\xb8\xe2\x7c\x02\xf6\x87\xfb\x4e\x3b\x73"
-  "\xf7\xb1\x0c\xf8\xcc\x81\xdd\xfc\x12\xe6\xdd\x4d\xf5\xed\x9e\xce"
-  "\x12\xa8\xae\x8b\xae\x95\xc0\xb9\xe6\x9b\x9c\xb9\x87\xa8\xee\xfd"
-  "\x31\xd8\xdb\x2a\x08\x3e\x72\x8f\xdb\x7f\xd8\x15\xe8\x64\xf0\x91"
-  "\xfb\x80\x8d\x87\x50\x0f\x95\xf9\x9a\xe8\xef\x4e\xb3\x25\x4b\xfa"
-  "\xe9\x11\x7d\x1d\x96\x9f\xab\xfd\x70\x5d\x10\xf5\x3d\xe4\xca\x26"
-  "\xba\x5c\xed\x93\x06\x6b\x39\xbf\xf6\xff\xc0\x99\xbb\x87\x61\x7c"
-  "\x50\x9e\xd2\xc5\x2e\x0f\x95\x3d\x3b\x72\x5c\x50\x86\x9e\xbd\x4c"
-  "\xf5\xfe\x7d\xf8\x5c\x08\xe7\x15\xe1\x32\xb5\xd4\x1f\x82\x95\x6f"
-  "\x27\xc1\x48\xca\xd1\xf6\xcf\x40\x5b\x69\xec\x92\x5c\x79\x5d\xa3"
-  "\xeb\x3c\x13\x0e\xa0\x79\xbf\xa9\x5d\xc8\xc2\x0f\xc4\x3d\x10\x54"
-  "\xb8\xc4\x6b\x07\x9c\x44\x03\x66\xbb\xe9\x0a\x9c\x20\xf0\xca\x6c"
-  "\xf8\x5f\x3a\xf0\x86\x49\x27\xc7\x17\x7d\x01\xfd\x35\xda\x18\x47"
-  "\xc8\xe9\x13\xd0\x56\x6d\x8c\xb9\x71\x8a\x5d\xc1\xf9\xcb\x74\x82"
-  "\xf7\x90\x99\xc9\xf9\xc7\xab\xa9\xde\x97\x55\x1a\x77\x8f\xba\x37"
-  "\xef\xe9\x8f\xf9\xe8\x21\xfe\xb4\x99\x69\xfa\x0f\xb4\x7e\x17\x67"
-  "\x49\x9d\x12\x33\x70\xd5\x6e\x3d\x57\xe3\x9c\x1c\x70\xaa\xef\xd6"
-  "\x4b\xbf\x63\x07\x8a\xe9\xfd\xfa\x51\xfb\x1b\x35\x1d\xbe\x56\x8b"
-  "\xe0\x93\x48\x9c\x93\x13\xce\xa2\x7d\x61\xa2\xcb\x37\x28\x6c\x54"
-  "\x7a\xd9\xc1\xbb\x11\xaf\x16\x7a\xe8\x5a\xdb\xc6\x27\x53\x3f\x68"
-  "\x90\xb2\xb5\x83\xe9\x1a\xdf\xc8\x8d\x04\x63\x87\x49\xf8\x4b\xc5"
-  "\xb9\xab\x2f\x6e\x4a\xb1\x37\x6e\x66\xa3\x5c\x37\x07\x6d\x3c\x4e"
-  "\xe2\xdd\xac\x00\x2b\x46\xbf\x54\xfe\x69\x22\xfa\x4c\xf5\x54\x13"
-  "\x4f\xbb\x50\xd2\x16\xb2\xee\x31\x7d\x10\x6b\x7d\xa3\x3e\x89\xbe"
-  "\x51\x1f\x45\xdf\x60\x83\x2b\xfa\xd6\x18\x27\x64\x59\xe3\xeb\x4f"
-  "\xa7\xdc\x83\xa6\x14\x3b\xa7\xa3\x8e\x97\x5f\x14\xfa\x41\x34\x26"
-  "\x52\xe6\xd8\x98\xcd\x63\x9f\x89\x1d\x5f\x9d\x8d\x52\xaf\xb8\x7c"
-  "\x66\xe3\xf3\x88\x11\x20\x74\x92\x61\x37\xf2\x72\x05\xe1\xf4\x46"
-  "\x11\x33\x99\xbe\x47\xf3\x23\x02\x0f\xbd\x9c\x80\xb1\x9a\xbd\x8f"
-  "\xa5\xc9\x79\xf8\xf2\x04\xc8\x94\xa4\x8f\xf8\xc6\x43\x34\xef\xa5"
-  "\x7c\x6a\x58\x57\x46\x27\x74\x65\x22\x71\xec\x38\xdb\x28\x63\x64"
-  "\xc6\x4f\xb6\xd0\xfd\x1e\xa1\x23\x48\xed\x5d\x17\xd4\xf0\x5f\xe3"
-  "\x1e\x3e\xc0\x7b\x20\xf3\x03\xfd\x94\x05\x5c\x56\x28\x7d\x78\xf8"
-  "\x1d\x2f\x2f\xd4\x68\x15\xd0\xd6\xd0\x85\x42\x39\x1a\xfb\xf3\x28"
-  "\x23\x7d\x0c\x9c\x51\xed\x19\x5e\xfe\x96\x6a\xab\x60\x85\x9e\x12"
-  "\xbd\x4b\xf8\xee\x98\x18\x6f\xc0\x00\xdf\x16\x6d\xd7\x43\x9e\xf5"
-  "\x72\x6d\x58\xc6\xda\x28\xf4\xa2\xa4\xbd\xd1\xcb\x87\xb4\x39\x42"
-  "\xfd\x9d\x28\xfd\x02\x37\xce\x38\x42\x50\xc6\x1c\xe8\xe7\xe6\xd8"
-  "\x99\xb5\x98\x93\x2f\x1f\x8f\x84\x53\x46\x50\x29\x92\x38\xa8\xb1"
-  "\x99\x8b\xb5\xde\xd8\xfc\x97\xe9\x8a\x5f\xdc\xae\xd1\x24\x12\xce"
-  "\x09\x84\x5f\x0e\x05\x05\xac\x4b\x5b\x0c\xf0\xe5\xf5\x74\x21\xfc"
-  "\x11\xfe\xe2\x33\xf8\x7a\x0c\x96\xb6\x58\x43\x45\x66\xf8\x91\x67"
-  "\x4a\x69\x4b\x6a\xaf\x8d\xe9\xb3\x6c\x90\x2b\x9f\x4a\x00\xbf\x48"
-  "\xfc\x68\x02\x8f\x25\x3a\x85\xd6\xf9\xc6\x15\xcc\xf4\x48\x0e\xd5"
-  "\x5d\x64\x4d\x84\x2f\x46\xf8\x61\x84\x2f\xd5\x50\x91\x75\x2a\xdd"
-  "\x4f\x23\xba\x2e\x81\x1b\x5a\xcc\x38\x9b\x0e\x39\x38\xe1\xe3\xe3"
-  "\xf0\x07\xa9\x77\x79\x03\x6c\xe3\x59\x66\x80\xaf\xc7\xe0\xd6\x53"
-  "\xd6\x76\xdf\x1f\x05\xaf\x14\x6f\x63\x89\x44\x87\x24\x11\xcc\xcd"
-  "\x4a\xcc\x29\xa2\xe3\x4f\x25\xca\x7e\x9f\xe7\xb2\xdf\xb2\xdd\x68"
-  "\xbf\xc0\x71\xa5\xef\xa6\x16\x8a\xb6\x1f\x7a\x3e\x48\xf5\x2b\xa5"
-  "\xae\xb9\xa1\x52\x57\x8a\xb4\x99\x69\x65\x85\x79\xbc\xcf\xe5\x6b"
-  "\x25\xfe\xed\xa2\x88\x7d\x81\xb3\x6f\xf4\x11\xfd\xc3\xb7\x8f\x5e"
-  "\x38\x2b\x7c\x57\x06\x29\x5d\xb4\x52\x7d\xc7\x43\xef\x78\x5a\xd9"
-  "\x60\xa9\x4b\xf4\xbd\xdd\x27\xdf\xcd\x12\xf7\x78\x3f\x02\x0e\x6a"
-  "\x9f\x87\xe1\x40\x7d\x47\xff\xd0\xff\x20\x60\x42\x30\x50\xfb\x6a"
-  "\x1e\x52\xfb\x89\x3e\xbe\x4b\xbb\xce\x0e\xea\x27\xf5\x55\xf4\x73"
-  "\x88\xfa\xd9\x92\xc3\x58\xa0\x72\x4a\xf5\xa5\x58\x57\x0a\xf8\xdd"
-  "\xa2\xf7\x88\x96\x2f\xa8\x66\xc4\xd7\x46\xef\x2f\xac\xd6\x97\x11"
-  "\x6d\x52\xe8\x25\xfe\xd6\xcb\xfb\xda\xa9\x4f\x2e\x1b\xfd\x82\xb5"
-  "\x0c\x34\x8e\x46\xb7\xd3\xb7\xcd\x47\x95\x93\xac\xb0\x8f\xf7\x11"
-  "\x8d\x1a\x70\x05\xa9\x4c\x0e\xf5\x9f\xf8\xe1\x5e\xb5\xfd\x28\xbb"
-  "\xf1\x33\xd9\x2f\xd3\x4a\x96\xf8\xfa\xbf\x95\xea\x5d\x9d\xa5\x4c"
-  "\xeb\xcb\xa3\x54\x8e\xfa\x63\xa6\xba\x44\xcc\x45\x85\xfa\xb9\x93"
-  "\xda\x19\x88\xe8\x53\x9b\x27\x40\x75\x7e\xc0\x62\x17\x33\xdd\x8e"
-  "\x73\xd4\x8f\x73\xcc\x5c\x5d\x48\xf4\xd7\x83\xa0\x1b\xff\xa3\x6d"
-  "\x72\x26\x4b\x76\xb3\x5f\xc8\x78\x5d\xd2\xb7\xdc\xd5\x67\xd8\xa1"
-  "\x8b\x9a\xff\x38\x05\xfe\x37\x63\x4e\xcd\xc2\x3c\x12\xbe\xe4\xb0"
-  "\x67\xf8\x69\xce\xe0\x8c\x7a\x1d\x7d\xc3\x6f\x9d\x26\xda\xe3\x90"
-  "\xfe\xe7\x28\x0d\x5f\xd8\xd0\x47\xd7\xd1\x7b\x56\x4e\x30\x43\xfd"
-  "\x44\xcf\x25\xe2\x0a\x18\x8e\xaa\x3b\x74\x80\xa5\xd2\x37\xb2\xc1"
-  "\xcb\x37\x16\x7a\xf5\xdf\x3f\xc0\x66\x8d\x0f\xa7\xbc\x92\x3c\x16"
-  "\xfe\x86\x4c\x12\xf5\x51\xdf\xa6\x9e\x61\xbf\x8c\x19\xb9\xc6\x2c"
-  "\x02\x97\x49\x3c\xf8\x4a\x07\x64\x7e\xe3\xfc\xae\xf4\x5b\xe9\xe0"
-  "\xa5\xe3\x7c\xef\x98\xd6\x0e\xba\x1f\x33\xd6\xc8\xf8\xe1\xf0\xcb"
-  "\x59\x63\xd5\x55\xf1\x82\xb0\x8d\x2b\xaa\x7c\x81\xf0\x05\xd1\x0a"
-  "\x88\xed\x0e\xba\xae\x79\x8f\x8f\xad\xd9\xc5\x0c\x45\x67\x21\x63"
-  "\xba\x9f\x1d\xa9\x4d\x61\x75\x17\xe0\x13\xc2\x3a\xf5\xb9\x0b\x38"
-  "\x67\x94\x38\x04\x34\x29\x64\xa7\x7c\x8d\x35\xa1\xea\x05\x8d\x86"
-  "\xff\xe5\xc5\x82\x8b\x4c\x2f\xe3\x8d\xfe\xd2\xb7\xd0\xc2\x83\xdb"
-  "\xf4\x4a\x4e\x2d\x7c\x2b\xc6\x4f\xae\x87\x6f\x45\xcd\xd7\xa0\xa0"
-  "\x7d\xec\xb4\xe6\xfa\xcd\xb1\x15\xb9\x6c\x16\xfc\xa2\x9a\xbc\x92"
-  "\x96\x93\xfb\xf5\x7f\x26\x53\xfb\x12\xd4\xb3\xb5\x04\xe9\x7f\xf0"
-  "\x95\x95\xbb\x2f\x08\x79\x27\x9e\x3f\x1c\x22\x5e\x46\xd4\x9b\xcb"
-  "\x92\x6b\x2f\x30\x2b\xe8\xa0\xac\x93\x92\x66\x03\x7f\x78\xbf\xc7"
-  "\xc4\x43\x9f\x5a\xd9\xae\x33\x61\xbf\xa9\xde\x35\xf0\xb5\xca\xcd"
-  "\x63\xd9\x03\x56\x4d\x13\x67\xe9\xc2\x17\x16\xf4\x03\x28\xcd\xb6"
-  "\x3d\xcb\xa2\x8f\x24\x31\x06\xb9\x21\xce\xe5\x8e\x04\xa5\x3d\x86"
-  "\xdf\xf1\x9f\xcd\x9a\x5f\xc9\xd1\x71\x79\xdc\x62\xd8\x29\xf2\x8a"
-  "\xb8\xc5\xe3\x1b\xb7\xff\xec\x19\x93\x57\xa1\x3a\x31\x0f\xbe\x58"
-  "\xbd\x4d\xf3\xae\x40\xd7\x44\x2b\xa5\x92\x37\x53\x26\x12\xcf\xe8"
-  "\xf5\x3b\xa5\x3f\xa4\xa6\x26\xd7\x16\x25\x82\x1f\x6b\xda\x8e\x67"
-  "\xc8\x83\x8f\x89\x34\x31\xee\x4d\x6e\xf0\x68\x2a\x9f\xfb\xba\x45"
-  "\xcb\x53\xf9\x5c\xec\xbb\x80\xd7\x6e\xe9\xb3\x2a\xde\xef\x68\x0a"
-  "\x6a\x7b\x2f\x68\x10\x29\x8f\x7e\x35\xc1\xad\x7b\xff\x4a\x7e\xc2"
-  "\x12\x84\xff\x2c\xe8\xba\xc0\xaf\xa5\xe3\xd5\x34\x6d\x2f\x16\x76"
-  "\xae\x9b\xa7\xdf\xbb\x66\x3d\x4b\xfa\x97\x6b\x0d\x0c\xe7\x52\x54"
-  "\xb6\x4f\xd2\x08\xaf\xe6\x84\x65\xf8\x69\x62\x6e\xc0\x5e\x4a\xf0"
-  "\x43\xf0\x43\x24\xfd\xb9\x7a\x34\x7f\x44\x92\x56\x78\xf5\xfb\x11"
-  "\xdf\x69\x18\xde\xf3\xe9\x1b\x38\xef\x45\xfd\x92\x8e\x7a\x75\x89"
-  "\xd0\xb9\xa7\x72\x92\x16\x78\x75\xc9\x15\xe0\x6b\x05\x7c\x15\x95"
-  "\xf7\x75\x79\x4e\x49\xf8\xda\x59\x14\xf4\x5a\x5f\x2f\x74\x47\xc7"
-  "\x4b\x3f\x83\x26\xfa\xfe\x25\x3c\xc7\xba\x74\xce\x86\x1c\xf4\x57"
-  "\x0f\xbb\x40\x63\x0c\x65\x1a\x1f\x80\x7c\x42\xf0\x0d\xbf\x5a\x08"
-  "\x9d\x53\xca\x9b\xfa\xda\xb9\x40\x74\xd5\x06\x36\x4b\xfa\x75\xfa"
-  "\x95\xb0\x13\xf3\x5e\xf3\x3d\xff\xcc\x44\x66\x9e\xb9\x8d\x59\xfd"
-  "\x8e\x5f\xad\x24\x5e\x58\xe8\x0e\x8b\xef\x57\xce\x74\x0b\x1d\xd8"
-  "\x41\xf7\x04\x39\x56\xbf\x8e\xa1\xb4\x35\x9c\xfe\xd5\x8b\xea\xf9"
-  "\x4d\x87\x9b\xfd\xda\xb0\xfb\x9c\xa0\xa5\x3a\x84\x4c\xac\xdc\x98"
-  "\x1e\xd6\x1f\xf8\xb5\xf4\xc3\x41\xd7\x23\x36\xc6\xa0\x4f\x5a\x37"
-  "\x8d\x77\xd0\xf7\x88\xfe\x79\x35\x49\x95\x21\x75\x88\x79\x05\xda"
-  "\xbc\x04\xfc\xe2\x29\x27\x74\x52\xb1\xa7\x11\x2d\x97\x26\xf8\x0d"
-  "\xa2\xcb\x15\x9a\x3f\xe1\xfe\xff\x6a\x2d\xe4\xac\xa3\xe2\xef\x1d"
-  "\x8c\x89\x77\x2a\x26\x97\x0a\xbd\x93\x8a\xe4\x54\xba\x1a\x68\x2d"
-  "\x80\xcf\x36\xd2\x9c\xc3\x35\x81\xae\x8b\xe9\x9a\x48\xcf\x2d\x98"
-  "\x97\xc4\x6f\x9b\x11\x8f\xa7\x3f\x6e\x72\xf1\x58\xba\xe3\x80\x8d"
-  "\x6b\xcb\xbf\x32\xa9\x5b\xf7\x6b\x0f\x62\xb1\x64\xec\x62\x6c\x4d"
-  "\x90\x0f\x5a\xae\x67\x93\xa8\xbf\x9e\xa2\x5d\x38\x03\xff\xb5\x73"
-  "\xe4\x19\xf8\xaf\xdd\x8c\x1d\xb6\xd0\x8f\x72\x0e\x13\x1d\xf9\x6b"
-  "\x4f\xf8\x77\xd8\xed\x77\xfc\xda\x43\x70\x94\xbe\xa6\xc6\xb5\x5e"
-  "\x7f\x2d\x62\xe4\x55\x81\x87\x8b\xf9\x74\xb1\xec\xef\xcc\x6a\x4a"
-  "\x1b\x78\xdc\xcc\x0e\xb5\xbf\x39\x94\x4e\xb0\x14\xd1\x1e\x1c\x47"
-  "\x30\x99\x4e\x7d\x8e\x4b\x4e\x45\x7f\xd1\xde\xfe\xb8\xb8\xcc\x48"
-  "\xbd\x79\xd4\x89\xfe\x7b\xe3\xe8\x3d\x82\x25\xff\x52\xb1\x57\x83"
-  "\xa7\x0a\x27\xe8\x1a\xeb\xfb\xa9\x0e\x49\xb3\x51\x79\xaa\x43\x2b"
-  "\x3f\x0c\x7b\x2a\x27\x78\x5a\x2a\x47\xfc\xbb\x41\xd3\xc9\xf7\x3b"
-  "\x0e\x77\xbe\xb1\x52\x9e\xab\xe0\x5d\x5f\xc4\xbb\xb0\x83\x1e\xf1"
-  "\x7e\x5c\xc4\xd8\x4d\x87\xaf\x80\x53\x69\x72\xec\x26\x57\xab\x6d"
-  "\x49\x94\x6d\x31\xa6\xd1\x1c\x3b\x2b\xdb\x73\xb8\x75\xac\x35\x56"
-  "\x78\x23\xd1\xa8\x44\xb9\xcf\x91\xbc\xeb\x3c\x57\x92\x8f\xb9\x6a"
-  "\x15\xa6\x54\x1a\x8b\xd3\x0a\xb9\xb3\x97\xfd\xe6\xc5\xf6\x40\xdf"
-  "\x38\xf7\xf4\xdf\xc8\x18\x69\x83\xc5\xcc\x55\x70\x07\xce\x69\xd9"
-  "\x39\xf6\xda\x07\x2e\xaf\xb0\x51\xc2\xbd\xd0\x87\xc4\xf9\x34\xf6"
-  "\x37\xf8\xfe\xd5\xe4\x04\x0a\x95\xad\x43\x3e\xe5\xc1\x6e\x72\x77"
-  "\xc4\x33\x5e\x39\x39\x47\xae\xb5\xd7\x2a\x40\x1f\x89\xf6\x06\xff"
-  "\xc9\x89\x36\x2b\xe5\x93\x73\xd0\x87\x22\xe8\x0e\x07\xfd\x4e\xac"
-  "\x15\x4b\x3e\xe4\x9e\xaf\xad\xa0\xf9\xc8\x95\x8a\xc9\x39\xe3\xeb"
-  "\xc3\x6b\x73\xf1\xcd\xa2\x20\x3f\xe7\x8d\x9b\x0c\xb9\xbf\xbe\xaa"
-  "\x70\x82\x61\x41\x2d\x77\xf6\xc7\x1b\x8b\xfd\x8e\xd7\xca\xdf\xb0"
-  "\xcb\x31\x1b\x67\xbd\xe5\x5a\xdf\xeb\xd4\xbe\x13\xbc\xc4\x9c\x9d"
-  "\x53\x23\x7d\x2a\x53\x99\xe6\xb1\xf7\x32\x63\x36\xf6\x32\xda\x33"
-  "\x2e\x49\x58\xbc\x9e\x38\xbc\x67\x8c\xab\x1d\xaf\x27\x7e\x8e\x6f"
-  "\x0c\xa9\xdf\xb0\x7f\xc1\x6f\x8c\x6d\x1f\x23\x79\xf4\x19\xc4\xfd"
-  "\x47\x8f\x9f\xff\x7d\x5d\xf0\xbf\x84\x57\x73\x24\x2e\x7d\x63\x6d"
-  "\x88\x78\xd0\xa0\x71\x66\xb5\x88\x43\xad\x67\xc5\x2e\x77\x90\x05"
-  "\x4b\x3f\x5d\xdc\x66\x1f\x64\xce\xfc\xf7\x59\x0f\x73\x8a\xf8\x07"
-  "\x6d\x79\xe0\x3b\x67\x76\x0c\x55\x1a\x3b\x86\xf4\xaf\x23\x56\x4f"
-  "\xce\x2e\xf8\xaf\x8e\x98\x67\xed\xbe\xf7\x99\x2b\x1b\xb2\xe2\x0e"
-  "\xc8\xe8\x3b\x08\x6f\x54\x2b\x84\x33\x88\xcf\x08\x09\x78\x10\x0d"
-  "\x26\x78\x46\xe2\x3b\x05\xcf\xe8\x15\x7e\xdd\xe2\x88\x76\x37\x72"
-  "\x47\x79\x10\x72\xfc\xd0\x50\xa6\xc5\xef\x60\x8b\xe1\x4b\x1a\x32"
-  "\x74\x6e\xe8\x4a\xcb\x08\x46\x71\xc1\x13\x12\xff\x02\x9f\xd2\x2e"
-  "\x9f\x9b\x85\x88\x17\xa8\x1d\x60\x89\xb5\x44\x3f\x13\x2e\x4f\x00"
-  "\xbe\xdf\xad\xfa\x94\xae\x18\x08\xfb\x94\xae\x83\xbc\xaa\x93\xee"
-  "\x07\x58\x74\xa8\x62\x8a\x7d\xe7\x00\x4b\xde\x95\xcf\xac\x3b\x21"
-  "\x8f\x3c\x2d\xe9\x37\xd0\x1b\xc2\xbf\xf4\x6a\x2b\xce\x45\xc2\xf4"
-  "\x1b\x6c\xec\xc2\xf8\x2c\x5a\xc8\x71\xc6\x05\xef\x37\x84\x4e\x56"
-  "\xb0\x7c\x72\x69\xd0\x98\x9c\x3a\x54\x19\x97\xe9\x66\xce\xbc\x21"
-  "\xfd\x6b\xa3\xfa\x88\xd0\xf4\x4f\xb6\x45\xf8\x04\x7f\x23\x59\xe2"
-  "\x7d\xaa\x6b\x4c\xdf\xc4\xa1\x9d\x99\x6c\x8e\x87\xa5\x48\xfb\x96"
-  "\x18\xda\x2b\x7f\x9b\x04\x9d\xc4\xc2\x27\x99\x39\xb4\x73\x89\xae"
-  "\xe8\x47\x2c\xca\x15\x4c\x63\xf8\x15\x7e\xc6\xfb\xe6\xac\x64\x29"
-  "\x38\x4b\xc1\xb9\x8f\xe5\x69\x94\x7f\xe3\x6c\x72\x01\x4b\x89\xac"
-  "\xfb\xc9\xf5\xb9\x2b\x6e\x4f\xf9\xee\x72\xcb\xe3\x2b\x72\x9f\x5c"
-  "\xb7\x34\x77\x39\x4b\x97\x2a\x1c\xc2\x65\xe6\x7a\xe8\x6f\xac\x5b"
-  "\x91\x97\x63\x79\x6c\x6d\x6e\xee\xf2\x55\x79\x96\xfb\x17\x2c\xfe"
-  "\x73\xbf\x49\x3b\xcd\x7b\x84\x9f\x3c\xa1\xdb\x77\xa4\x8d\xff\xf0"
-  "\x2b\x03\x95\xf9\x2c\xda\xb4\xe9\xbe\x87\x4c\xc1\x74\x8b\x8c\x2b"
-  "\x71\xc4\x0b\x5d\x5a\x5e\x94\x59\x23\x69\xed\x23\x9f\x49\x9e\xd0"
-  "\xdd\x22\x6d\x36\x8f\x08\x39\x31\xf7\xa7\x27\xc9\x35\x75\x44\x17"
-  "\x95\xc7\x70\xff\x24\xee\x4d\x79\xac\xd4\x39\x1d\xe7\xf5\x47\xe4"
-  "\xb9\xca\xce\x45\x3a\xad\x9c\x56\x46\x3e\xff\xad\x1b\xcf\xeb\x84"
-  "\x0f\xb1\xdf\x5a\x09\x3e\x53\xfd\x8e\x23\x66\xb7\xfe\xad\x7a\xcd"
-  "\x6e\x5d\xea\xdf\x1d\x11\x7e\x84\xf8\x0f\xaf\x1b\x50\xeb\x59\x4c"
-  "\xdf\x9b\x4c\x65\x17\xd2\x18\xb4\xaa\x7a\x7a\x37\x74\xab\xed\x92"
-  "\xba\xb0\xbf\xbd\x4b\xea\x9a\x1c\xc9\x89\xb0\xd7\x13\xb6\x8a\xd8"
-  "\x33\x55\x5a\xd5\xaf\xd6\x57\xae\xe1\x04\x2a\x5f\x43\xf4\x9e\x65"
-  "\xfc\xb8\xf0\x88\xb4\xab\x1c\x61\x1f\xae\xc2\x69\xa7\xf9\x25\xc2"
-  "\x0f\x49\x67\xd8\x6f\x8b\x2f\x9f\x2f\xc3\x23\xf8\xf5\x55\x8f\xad"
-  "\x7e\xd2\xb6\x34\x6f\xc5\x77\x56\xac\x5c\x91\xb7\xfe\x2e\x11\x20"
-  "\x45\xfc\xfb\x5f\x37\x2f\x7b\xe8\x72\x9f\x97\xb3\x20\x27\x82\x6d"
-  "\x14\x78\x7d\xc8\xe7\xa0\x63\x21\xe5\x75\xcd\x5b\x85\x6f\xbb\x71"
-  "\xb5\xbd\x59\xb5\x9f\x6c\xde\xe6\xd6\xbd\x27\x75\x1d\x88\xcf\x70"
-  "\xde\x14\x42\x7d\xe2\x59\xbf\x31\xd9\x62\x99\xce\xe6\x75\xb3\x96"
-  "\x79\x38\xb3\x23\xf8\x65\x62\x3f\xac\xdc\x80\x7d\xcb\xcd\xda\x82"
-  "\x77\xa8\x71\xed\xde\xdc\x0e\x18\x80\x56\x24\x18\xec\xe9\x66\x6f"
-  "\x4a\x1e\xfb\xbc\x79\x0f\x74\x97\x94\xf3\xe6\x97\x30\xb7\xd0\x5e"
-  "\x85\x67\xee\xe4\x3c\x73\x87\x72\x3e\x67\x27\x3f\x9f\xb3\x23\xec"
-  "\x6f\xe7\xcd\x3c\x7a\x77\x1f\xbd\xbb\x1e\xfe\xfb\x2b\xcf\xb1\x7d"
-  "\xd0\x07\x40\xda\x94\x97\xc0\x42\x46\xe3\x62\xb4\xc7\xd5\x97\x22"
-  "\xe8\xf0\x1e\x2a\xef\xf2\xdd\xc1\x88\xc6\xcc\x84\x3e\x86\x3c\x7b"
-  "\x24\x3a\x90\xde\x73\x51\xbb\x5c\x7d\x83\xe0\xeb\x17\x2b\x44\x0b"
-  "\x52\x5f\xf7\xd0\xfe\x59\x8c\x7a\xa1\x0f\x42\xf4\x2a\xd1\x67\x6f"
-  "\x96\xbb\xd9\x6f\xb5\x33\x4f\xa1\x0b\x32\x72\x1c\xdf\xdc\x4f\x70"
-  "\x9e\xa4\xf9\xf8\xc4\x5e\x02\x9e\x21\x6c\x17\xf9\xe6\x07\xe8\x23"
-  "\xce\xf3\x1f\xf0\x71\xa5\x4e\x3c\x7b\xc7\x1e\x71\xbe\x8e\x32\xc2"
-  "\xbf\x35\xf4\x59\x6c\x1b\x10\xe7\xf4\xad\x29\x72\xbe\xbc\xb3\xce"
-  "\x5b\x94\x13\xa5\xd6\x1b\x42\xbd\xf0\x23\x23\x61\xf9\xd6\xed\xae"
-  "\x2d\xe7\x34\x3d\x12\x6a\xc7\x5b\x1f\xa8\x75\x78\xb0\x96\x15\xc7"
-  "\x91\x20\x74\xa9\x85\xdf\x48\x69\x8b\xa4\x23\xfe\x14\x7e\x8a\x12"
-  "\xea\xa6\x4a\xff\xb2\x7e\xc7\x5b\xc3\xf3\x9f\x1b\x25\x2d\x08\x7a"
-  "\x0c\xf1\x49\x30\xff\x41\xdb\xa1\x7d\x98\xff\x54\xff\x36\x9c\xdb"
-  "\xcb\x75\xf0\x56\xfd\x17\x5b\x07\x6f\xd5\x6b\xb0\x90\xfc\xe3\x5b"
-  "\x29\x5c\x5f\xc4\xe7\x94\xb3\x6c\xa1\x5f\xa1\xda\xdb\xd1\x1e\x32"
-  "\x57\xe2\x96\x96\x19\x42\x37\x26\xdf\x53\x4f\x38\xbe\x78\xf7\x20"
-  "\x33\x2a\xa5\x5d\xa9\xa0\xc5\xdb\x0a\x84\x5e\x8a\x81\xde\x6b\x84"
-  "\xde\x0a\xf4\xf0\xe2\x45\xec\x9b\xf7\xd9\xee\x8b\x2c\xba\x87\xbd"
-  "\x6d\xc5\xd9\x56\x78\x1c\xde\xde\x88\x33\x4d\x5e\xf6\x96\xd7\x54"
-  "\xa0\x2f\x45\x1d\xca\xc0\xd9\x54\xed\x3d\xd8\xc5\xe1\xbd\x6e\xf6"
-  "\xf6\x52\xf1\x1e\xca\x02\x66\x85\x09\x4b\x88\xe6\x12\xe5\x83\x44"
-  "\x8b\xd5\x29\x09\x8b\x39\xed\x0d\xa1\xfc\x60\x23\x3d\x7b\x48\x29"
-  "\x8f\xcb\xa4\xbc\x4c\x71\xa6\x32\x64\xc6\x99\x2b\xe3\x86\x53\xe9"
-  "\xae\x9e\x53\x4e\xd1\x1e\xe8\x9f\xe6\xd1\x3e\x2a\x78\x97\xb7\x5f"
-  "\xa9\x3b\x4d\xe3\x31\x4d\xc4\x06\xa1\x71\x6e\x11\xf1\xe8\x68\x2e"
-  "\x36\xc8\x36\xb6\xdc\xd7\x5f\xe6\x4a\xe9\xa7\xb9\xea\xd3\x1b\xd8"
-  "\x11\x33\xcd\xd5\xf2\x64\xcb\x11\xf3\x20\x8d\x55\x4b\x22\xe1\x3e"
-  "\x55\xbf\x41\xbe\x87\x39\x1a\x65\x8e\x1f\xa2\x67\x29\x9a\x9e\x94"
-  "\xd4\x55\x7a\xdb\x00\x98\xd1\x7c\x6e\x69\x5f\x09\x7d\x37\xa5\x95"
-  "\xbe\xc1\x42\xf9\xca\x71\x9c\xf7\xc3\xa6\x00\xfc\x4e\x86\x9d\xf7"
-  "\x83\x7f\x83\x1d\x16\xce\xf8\x61\xa3\xb8\x8b\xf8\x5f\xd4\x4b\x75"
-  "\x6e\xd1\xec\x08\x2b\x28\x4f\xcc\xfb\xa8\x6f\x9f\xae\x7c\x42\xac"
-  "\x39\xe8\x86\x1a\xc5\xf9\x46\xd4\xf7\x4e\xd3\xbc\xee\xaf\x3b\x27"
-  "\xce\xe5\xfa\xeb\xd4\x7a\xe0\xa7\x80\xea\x68\xd1\xea\x50\xf2\x79"
-  "\x0f\xf4\xf2\x42\x03\xdc\x2d\xdf\x97\xfa\x1b\x0f\xf8\x14\x61\x23"
-  "\x83\xf7\xa5\x1e\x47\x4b\x30\x42\x2f\x9e\xf0\xce\x3b\x46\xcd\x8f"
-  "\x01\xdd\x9b\x35\x7e\x1d\x30\xea\x2f\x37\x2e\xf6\xd1\x5a\xf7\x95"
-  "\x4f\x26\x3a\xf5\x9d\xb9\x84\xef\xb7\x5d\x41\x46\x10\x0d\x9c\x08"
-  "\xbb\x5f\x25\xb6\x2b\x1b\xb6\xbf\xf0\xb5\x29\x75\xdb\xdf\x79\x5e"
-  "\xb5\x03\x8e\x3a\xc7\xde\xf9\x66\xf8\xbc\x3f\xa4\xca\xa8\xdf\x39"
-  "\x2c\xf9\x8b\x77\x0e\x0b\x19\x75\xa5\x31\xe5\x27\x1b\x02\xfa\xc6"
-  "\x0d\x6e\xbd\xf4\xed\xfa\x4e\xa3\x9b\x38\x00\x4d\x2f\x8d\xca\xd9"
-  "\x50\xd7\xe8\xf6\xd2\x6e\x8b\xac\xf3\x5d\xc1\x47\x87\xf9\xf8\x77"
-  "\x85\x5f\x39\x9c\xcd\x2b\xa0\xed\x62\x3f\xcd\x86\x3e\x97\xcb\x76"
-  "\x01\xb2\xea\x89\x52\xa6\x20\xcb\xa8\xba\x93\x57\x9d\x19\x99\x9e"
-  "\x8a\xb4\x84\xd9\xbb\x69\xda\xb9\x57\xa5\x5e\x71\x9b\x74\x8c\x17"
-  "\xd5\x13\xee\xb3\xf9\xe0\x7f\xc0\xeb\x22\x5a\x11\xb1\x45\x6d\xb9"
-  "\x88\x63\xf4\xee\x5a\xf8\x34\x97\xeb\xed\x5d\x61\x37\xa7\x38\xe6"
-  "\xf3\x22\xf0\x4b\x5e\x8f\xf0\xb7\x40\xe5\xa6\x50\xb9\x1f\x35\x17"
-  "\x78\xa0\xa7\x36\x0b\x71\xb6\x7a\xd4\x6f\x7b\x63\xdc\x96\x99\x46"
-  "\x46\xbc\xdd\xbb\x87\xdc\xac\xb6\x7a\xfc\x38\xe1\xdd\x43\x57\x92"
-  "\xc7\xca\x7e\x1d\x4d\x0e\x8f\xc9\xc7\xea\x98\x1c\x4d\xfe\x4b\xba"
-  "\x12\x2a\xed\x7d\xf5\x19\xd6\x76\x35\xe4\x43\x74\x7f\xc3\x19\xd6"
-  "\x2a\x70\xad\xd4\x43\x6e\xfd\x50\xbd\xa7\x6f\xb4\xbe\xa1\xde\x5f"
-  "\x47\xf7\x7b\xd5\xfb\xe9\x74\xff\x03\xf5\x9e\xe0\xdd\xba\x5e\xbd"
-  "\x4f\xa4\xfb\xa5\xea\x3d\xad\xe3\xd6\xaf\xab\xf7\xd3\xe8\xfe\x76"
-  "\xf5\xfe\x5a\xba\xbf\x56\x3d\x63\x36\xf4\xb2\xd6\x09\xe3\xa7\xff"
-  "\x8f\x76\xc8\xbd\xb7\x35\x81\xd6\xb2\xea\x47\x67\x38\x2f\xd9\xcd"
-  "\x9a\x0a\xb4\x73\x24\xca\x6f\xc1\x77\x28\x7f\x1e\xcd\xbf\xb4\x88"
-  "\x7c\xd5\x37\x7b\xeb\x43\xc4\x4f\x34\x45\xe4\xef\x53\xf3\x57\x52"
-  "\xf9\x96\x88\xfc\x7a\x35\x9f\xd6\xff\x2f\xa2\x23\xf2\xb7\xa9\xf9"
-  "\xb5\x9a\xee\x86\x9a\x5f\xaa\xe6\xd3\xf8\xef\xdd\x17\x91\x5f\xa0"
-  "\xe6\xb7\xd2\x18\xfb\x22\xf2\x05\xcf\x2c\x7d\xed\x99\xf8\x91\x82"
-  "\xb9\x84\xdb\x5a\xbd\x6e\x76\x70\x4f\x44\x99\x65\xf2\xdd\x36\x82"
-  "\xc1\x81\xd6\x88\xfc\x4c\x35\x9f\xf6\xea\x4b\xe5\x11\xf9\x8b\xc6"
-  "\x9a\x43\xba\x1a\x36\xaa\x3c\x07\x72\x5c\xd0\x8d\x42\x17\x55\xd0"
-  "\x91\xed\x8f\xc0\x3e\xc6\xb4\x8b\x77\x5b\x0a\x39\xef\x66\xed\x0b"
-  "\x55\xbd\x4c\xab\xdc\xaf\x30\xe7\xdb\x6f\x13\xb6\x27\xf0\xf5\x06"
-  "\x3b\xa3\x0d\xb0\x33\x6a\x13\x67\xe6\x73\xec\xc5\xd2\x0f\x9c\xe6"
-  "\x53\x18\x32\x01\xf5\xcc\x97\xca\x7c\x08\xd9\x29\xea\xc1\x1e\xee"
-  "\xca\x1b\x94\x3e\x02\x89\x77\x40\x1e\x78\x63\x61\x8f\x12\xc1\x9b"
-  "\xc9\xf5\xd8\xfe\x88\x32\x08\x5b\x3e\x29\x3f\xc0\x5e\x8f\xf2\xd0"
-  "\x57\x8a\x2c\xeb\x66\xed\x42\xb6\x18\x65\x36\x9d\xf0\x3b\xda\xe7"
-  "\x85\x6d\x2a\xda\xb6\xa9\xf9\x44\xc7\xb4\x3f\x14\x91\xff\x67\xb4"
-  "\x66\x18\x3f\xd1\xde\x61\x78\x3b\x75\x68\x80\xfb\x82\x03\x3c\x50"
-  "\xf9\x27\xa9\x77\x4c\x38\xe8\xfa\x50\xe9\xdb\xe9\xb0\xa9\x40\xac"
-  "\xa1\x60\x3e\xf7\x42\x27\x8e\xf2\x27\x3f\xe0\xf3\x12\xee\xf7\xf3"
-  "\x8a\xef\x40\x87\xf2\x22\xc3\x99\x5c\x91\x07\x71\x20\x4c\x1c\xb6"
-  "\xab\x1b\xcf\x32\x63\x3b\xe1\x1e\xe8\x27\xe3\xbc\xec\xfe\x1c\x2f"
-  "\x6b\xcb\x09\xb1\x3a\xaa\x7b\xd7\x77\x34\xbc\xdf\xee\x0b\xdb\x47"
-  "\xbe\x8d\x33\xcc\xeb\x8b\x44\x4c\x35\x97\xf0\x9f\x86\x78\xed\xbc"
-  "\x22\x39\x9d\xff\x16\xf4\xc8\x64\x9b\x69\x13\xa3\x39\xe0\x4a\xa1"
-  "\xfb\x6c\xf9\xa3\x67\x94\x3f\x56\x9f\xe4\x3a\x75\xad\x54\xcf\xaf"
-  "\x9a\x24\x2e\x70\xad\xe4\x3f\x86\xad\x85\xcb\x46\xb8\xc4\x4a\xb4"
-  "\xcf\xa8\x3e\x80\x36\xee\x62\xfa\xa1\x32\xda\x33\xce\x35\xe9\x25"
-  "\xee\xe9\x58\xa2\xe8\x0d\x9b\x20\xb7\x14\x71\x95\xca\xba\x6c\xfb"
-  "\x56\x05\xf4\x6d\x1b\x7a\xd8\xd3\xd7\x32\xf3\x92\x80\x9e\xca\xb8"
-  "\xfe\x18\x9f\x47\xdf\xa6\xbd\x82\x68\x07\xfd\x7f\xd0\xf3\xd7\x56"
-  "\x35\xe9\x83\x62\x1f\xe9\x58\x22\x64\x5d\xa5\x5d\xe9\x38\x2b\x73"
-  "\x75\x86\x40\xf7\x18\x89\xee\x49\xe5\x6b\xac\x86\xd0\xba\x9c\xa9"
-  "\xc1\x35\x39\x93\x77\xe5\x32\x63\x68\x8d\x35\xf1\xb9\x01\x96\xaa"
-  "\xc5\x6b\x22\x5e\x38\x85\xfb\xcd\xb1\x55\xf9\x6c\x16\x78\xe5\x78"
-  "\x5d\x82\x38\x7f\xc4\xbd\xa2\x7f\x25\xa1\x2e\xff\xca\xb1\xe1\x42"
-  "\xc4\x23\x23\x1e\x16\xda\x32\x5a\x5f\xcb\x77\x10\xdf\xad\xda\xe2"
-  "\x15\x9e\x64\xd3\x6c\x8f\x33\x7d\xfc\x45\xee\x3c\xb3\x92\xe9\x11"
-  "\x57\xab\x70\xb9\x90\x47\x4d\x68\xcb\x09\x32\x97\xbd\x8b\x15\xe6"
-  "\x62\x8c\x3a\x5e\xc6\xfe\x09\x9d\x58\x2a\x9f\x70\x86\x75\xbc\x61"
-  "\x0a\x30\x3d\xfc\x62\x3b\x9f\x00\xdf\xd1\xf1\x81\x4f\xf8\x6d\x79"
-  "\xcf\x0c\xdb\x39\x67\xee\xbd\xc8\xfb\xac\xe8\xa4\xd0\x17\x99\x25"
-  "\xed\xf5\x3a\x5a\x91\x2e\x82\x6d\x60\xec\xc7\x99\x07\x06\x03\x13"
-  "\xa4\xcc\xa3\xa3\x4d\xc5\xfd\x16\xc9\x27\x75\x8c\x29\xe3\x53\x4a"
-  "\x8f\x66\x72\xc4\xe8\xa8\x05\x5d\xc1\xdd\xe2\x6c\x57\xc4\xb7\x9e"
-  "\xef\xe4\x03\xd5\x4c\xda\x02\xbd\xf7\x03\x65\xeb\xd1\x4c\xe8\xbe"
-  "\xd0\xbd\x88\x65\x23\x64\xa7\x5b\x8f\xe6\x08\x79\xe3\xd6\xa3\x76"
-  "\x21\x3b\xdd\x7a\xb4\x74\xf3\x74\xe8\x88\xbf\x57\xdd\x1f\x73\x94"
-  "\xf8\xbe\xf7\x96\xf5\xc7\xf6\x8c\x7a\x26\x29\xf6\x9a\xd2\x96\x52"
-  "\xcb\xf5\x2c\x11\x32\xfb\xac\x90\xf4\x67\x24\xd7\xf0\xfb\xdb\xf8"
-  "\x56\xf1\xec\x86\x6e\x1b\x8b\x92\xb4\xfb\x7b\x27\xe6\xd4\x32\x0b"
-  "\xb5\x35\x8e\x1b\x8e\xa6\x0a\x7d\xb7\xd2\xa3\xe9\x2e\x0f\xfc\x8f"
-  "\x87\x98\xa4\x8d\xdf\xaf\xe7\x31\x47\x53\x65\xf9\xf7\x6f\x6f\xf7"
-  "\x50\x1f\x0c\x47\x0d\xae\xc0\x59\x75\xaf\x7e\x3f\x85\xda\x48\x73"
-  "\xfb\xa8\x59\xda\xd8\xbe\xbf\x49\xc3\xab\x72\x8e\xbe\xbf\x56\xce"
-  "\xf5\x96\x52\x09\xb7\xf7\xeb\xd5\x7d\xe9\x06\xdc\x13\x9d\x90\x22"
-  "\xf5\x16\xde\x5f\xa9\xd1\x2e\x6e\xb5\x0c\xde\xa1\xfb\xc5\x12\xd7"
-  "\xbe\x4f\xfc\xcf\x7b\xc9\xea\xf3\x14\xe4\x51\xff\x08\x2f\xbf\xd7"
-  "\x82\x7e\x8d\x85\x5b\x05\x2c\x0a\x58\x14\xb5\xd9\x0a\x7d\x61\xf0"
-  "\x77\x2e\xdf\x7c\xa7\x4b\x8c\xc1\xb1\x5b\x84\xfd\x21\x7d\x07\xb1"
-  "\x02\x80\x37\xa9\xce\x68\xd4\x17\x6e\xff\xef\xe2\xb4\xb6\xe0\x7b"
-  "\x78\x46\x7d\x15\xfa\xf1\x04\x2b\xa1\x67\x8f\x71\xed\xb5\x41\x56"
-  "\x72\x91\x60\x06\xdd\xa9\x63\xa9\x80\x89\x84\xd9\xb1\x44\x95\x1f"
-  "\x52\xc7\xe1\x58\xcc\x48\x78\xc8\xb4\x62\x20\xdc\x90\x0b\x1d\x9a"
-  "\x63\xa9\x2a\xfc\x54\xdf\xb9\xbf\x3b\x29\xe0\x25\x9e\xfd\x6e\x57"
-  "\xc4\xbb\x33\x86\xcb\x52\xbb\xa1\xf3\x88\xf3\x68\xc8\xfc\xe5\x7c"
-  "\xfd\x5d\x4b\xc4\x7b\x2d\x59\x9f\xa5\x31\xc4\x5d\xdb\xfc\x82\x88"
-  "\x45\x92\xe2\x77\xfc\xee\x78\x18\xde\xb2\x9e\x51\xbe\x71\xbd\xf6"
-  "\x0d\x37\xfb\x5d\xad\xd6\x4e\xba\xb7\xc9\x31\x39\x66\x09\x8f\xc9"
-  "\xef\xd2\xb4\xf7\xc0\x37\xd3\x18\x79\x10\xd7\x67\x0c\x7f\xa7\x3a"
-  "\x57\x12\xe1\xe0\xe0\x7c\xa7\x98\x8f\xec\x58\x0d\xf4\x94\x09\xae"
-  "\x56\x39\x87\x8e\x15\xc8\xbd\xf0\x98\x90\x57\xe0\xdc\x46\xfa\xbf"
-  "\x3e\x56\x4d\xf5\xee\x53\xdb\xbc\x47\x6d\xc3\x1e\x6a\x43\xed\x98"
-  "\x76\x2d\xc3\x76\x6b\xc7\x5a\x23\x6c\xf5\x16\x4a\xd8\x7e\x60\xe6"
-  "\x03\x7c\x1b\x6c\x0b\x78\x3e\xaf\xa9\xa4\xf1\x29\xba\xc8\xae\x81"
-  "\x2f\x94\x42\x1b\x3f\xd5\x6e\x23\xbe\xc7\xd0\x55\x4d\xb8\x61\x5b"
-  "\xe1\x45\x36\x09\xba\x26\xc0\x2d\x90\x25\xf0\x98\x2e\xf8\x06\xd8"
-  "\x16\xb6\x27\xfa\xfd\x2c\xd8\xfd\x11\x3f\x8e\x98\x97\x0d\x18\x6b"
-  "\xe8\x1f\xf7\xb2\xdf\xd3\x1a\xee\x6a\xa0\x67\x79\x15\x82\x27\xeb"
-  "\xf2\x84\x0c\xee\xa4\xa2\xb3\x6c\xa2\x88\x4b\x61\x0f\x30\xcb\x13"
-  "\xb0\x3b\xf9\x60\x3d\xd5\xe9\xa1\xfc\x78\x91\x1f\x08\xc0\x76\x1c"
-  "\xb6\x0b\xf1\xf4\xec\x15\xba\x2a\x54\x87\xbd\x92\xda\x5d\x78\x96"
-  "\x5d\x4f\x6d\xe9\xa3\xef\x78\xa8\x9d\xbd\x45\x4f\xb2\x69\xed\xb6"
-  "\x3e\xd0\xd4\x54\x9f\x9b\xa9\xfe\x15\x3c\xdd\xec\xf7\xb7\x51\xbf"
-  "\xec\xe0\x2d\x61\xab\x57\x41\xd7\xc2\x10\x8b\x2f\xdc\x48\x7b\xda"
-  "\x46\xfa\x3e\x95\x47\x3d\xf0\xa9\x20\xdb\x42\x7d\x83\x5c\x82\xea"
-  "\xdd\xe8\xe1\xbd\x54\x77\x5f\x9b\x87\xea\xb3\x77\x8a\x3a\xdd\xe8"
-  "\x23\xd5\xab\xea\x28\x59\xe4\xf9\xf2\xef\x93\xb5\x73\x52\x37\xfb"
-  "\x60\x21\xfa\x39\xba\xdf\xd2\xdf\x2f\x1a\xe9\xeb\xe3\x0f\x49\xf0"
-  "\x9b\x48\xf9\xcb\x34\xbf\x1c\x74\x6f\xa3\xba\x1a\xc5\x18\x45\xf8"
-  "\x48\xa9\x8c\xf0\x91\x52\xe4\xe5\x27\xd0\x16\x9b\x88\xc1\xf5\xfb"
-  "\xc3\x7c\xab\x3b\x49\xfa\xfe\xfc\x83\x58\xa7\xd4\xe7\xe3\x94\x36"
-  "\x49\xd9\xe1\xef\xdb\xd4\x39\xd9\x90\x11\x0a\x9a\xdc\xf4\x4d\x5a"
-  "\xbf\x0d\xe1\xf4\xef\x9b\x61\x9b\x48\xe5\x42\xd2\x87\xda\xef\x0f"
-  "\x8f\x2c\x2f\x9e\x17\x5f\x96\x4e\xbb\x2c\x6d\xf1\xd1\x78\x8e\x75"
-  "\x1e\x5c\x31\x5d\xc8\x11\xd2\xe3\x37\x31\x5b\xd1\x69\x16\x45\x70"
-  "\x3e\x89\xb6\xb5\xf7\x09\x1b\x19\x13\x77\xa4\x30\x57\x5f\x50\xd2"
-  "\x2b\xb4\x4f\x74\x27\x53\x99\xd3\x6c\x1a\xf4\xab\xe1\x1b\x95\xca"
-  "\x9f\x91\xfe\x50\x3b\x5f\x5c\xb2\x36\x96\x29\xdf\xcd\x9c\xcc\xf5"
-  "\x8f\xd8\x68\x4f\x30\xec\x1f\x74\xc3\xa7\xa8\xae\x70\x3b\x4b\xc2"
-  "\x18\xd2\x58\xf6\x20\x26\x28\xbd\xe3\xf9\xc9\x60\xdf\x04\x57\xb0"
-  "\x8b\xd9\x68\x6e\x9d\x61\x9d\x35\xd1\x05\xc4\xef\xf7\xb2\x04\xe2"
-  "\xb9\x83\x47\x82\xa9\x4c\xb3\xeb\xad\x9d\x2a\xed\x23\x6b\x69\xcd"
-  "\xae\x31\xf3\x80\xdf\xf1\x07\xa2\x7f\xfe\xb3\x58\xb3\xdb\x2b\x97"
-  "\xfe\x4e\xa3\xe9\xfb\x4b\xf5\xaa\x0d\xb3\x84\x6d\xe7\xed\xd2\x3e"
-  "\x6a\xea\x97\xfc\x8e\x4e\x6b\x98\xa6\xeb\x3c\xa4\xca\x61\xd3\xe4"
-  "\x1a\xeb\x3c\x74\x84\xa8\xe8\x2d\xf2\x5c\x3d\x91\xca\x3e\x34\x7c"
-  "\xae\x2e\x78\xd4\xce\x43\x34\x86\x69\x92\xde\x73\xa7\x65\x85\x0c"
-  "\xea\xbe\x82\xfc\xb7\x0d\x78\x97\xde\x33\xc9\xb8\x0d\x9d\xd5\xe1"
-  "\xb9\xd6\x89\x3d\x56\x47\x7d\x22\xbe\xfc\x0f\xad\xe8\x17\x60\x42"
-  "\xe5\xa2\x29\xdd\x71\x64\xcf\x18\x7e\x7d\x0d\x6f\x37\x05\x1d\xe2"
-  "\x8c\xd8\x4a\xf3\xe9\x2c\x8d\xc1\x55\xf0\x63\xe2\xa2\xef\xb4\xd5"
-  "\x0d\xb2\x36\x73\x3f\x6b\x5f\x06\x5b\x2e\xa2\x99\x9f\xf8\x84\xf5"
-  "\x58\x46\xc7\x61\x84\x07\x53\xa9\xcd\xe9\xa8\x0b\xeb\x04\xfa\x51"
-  "\x2e\xe2\x34\xda\xbd\x88\x45\xca\x44\x1d\x6d\x4a\x1f\x6b\xb3\x9f"
-  "\x80\xec\x24\xbd\xbd\xae\x8b\xb5\x9b\x7f\x27\xbe\x03\x3a\xc3\x99"
-  "\xdb\x7f\xa5\xba\x33\xa9\xee\x1c\xb5\x6e\x0f\xd5\x9d\x38\x76\xdd"
-  "\x93\x6d\xe3\xac\x7b\x1c\xed\x9e\x9c\x3d\x9e\xba\x8b\x6a\x78\x88"
-  "\x70\x4b\x1c\xe1\x8f\x54\xf8\x55\x82\x6d\x58\x68\x00\x3e\x08\x6e"
-  "\xe0\x52\xe7\xb4\x6b\x2b\x68\x6c\x71\x96\xb8\xb5\x6b\xae\xb0\x1b"
-  "\x3b\xc7\x84\xcf\x1a\x57\xf0\x24\x83\x0c\xc8\xef\xe8\xca\x1b\xa6"
-  "\xbf\xc3\x67\x28\x44\xff\x74\xd5\x48\xbd\xc2\xae\xb9\x72\x5e\x75"
-  "\x7d\x13\xf5\x8c\x4e\x67\x7f\x94\x2e\xf5\x53\xbb\xde\xd3\xf8\xf5"
-  "\xfe\x98\x8f\xd2\xd5\xba\x2c\x97\x9f\xad\x6b\x41\xc0\x97\xdb\xf3"
-  "\xb4\x78\xe2\xd2\xa8\x30\x96\x3d\xb8\xfc\xb1\xe5\x2b\xf2\x97\x2f"
-  "\xb3\x3c\xb4\x36\x77\xd5\x6d\xab\x1f\x7f\xdc\x72\xff\xf2\x35\x6b"
-  "\x96\x7e\x77\x79\x2c\x7b\x28\x77\xe9\xaa\x35\x2b\xe0\x0c\xde\x62"
-  "\x59\x78\x67\x56\xce\xea\xbc\xdb\xee\x59\x98\x72\x99\x9d\x21\x6c"
-  "\x0c\x8f\x83\xae\x23\x7c\x3b\x8d\x70\xef\x14\xf8\x9f\x30\xad\xe7"
-  "\xce\xa7\x89\xa7\xa0\xf9\x77\x06\x67\x48\xb4\x6e\x4f\x80\xde\x24"
-  "\xfa\xe3\x18\x7c\x8f\xed\x7c\x81\x77\xf4\xb2\xb3\x5f\x23\x5a\xa5"
-  "\x13\x7e\xc6\x88\xd7\x3a\x4e\x7c\x9e\x57\xc6\xbc\x3d\x3b\x83\xca"
-  "\x34\x3f\x43\x79\xde\x18\x77\x5a\xd5\x9f\x58\x34\xed\x3f\x44\xeb"
-  "\x7e\x44\x6b\x7f\x12\x2f\x9f\xc6\x9b\xf9\x27\x66\xa6\xfa\xfb\xd3"
-  "\xbb\xdc\x01\x9c\x35\x1b\x32\x82\x45\x1c\xf8\x54\xae\xad\x8f\x4e"
-  "\xca\x35\x7a\x34\x53\xea\xed\x7a\x42\xa0\x8b\x37\x8b\x18\x02\x1f"
-  "\xd1\x9a\xec\xc8\x09\xe3\xe9\x93\xb3\x54\x7a\xa4\x93\xe0\xbe\xae"
-  "\x9b\xd2\xd2\xc6\xfe\xb8\x65\xa4\x7e\x01\x31\x51\xec\x74\x8e\xfc"
-  "\xe1\x9d\xd3\x79\xf2\x87\xfb\xc8\x1f\x6d\x28\xe2\x77\x79\xfe\x5f"
-  "\xfb\xd3\xbe\xff\x85\xeb\xe8\xf9\x0b\xbf\xcf\xf1\x7d\xd1\xef\xff"
-  "\xc6\xfe\xff\x55\x75\x78\xae\xf4\xc3\x7c\xa3\xb9\x75\xfc\x99\x3f"
-  "\x31\x03\xcd\xcf\x6d\xc4\x63\x47\x17\xfd\x91\x99\x0b\x82\xbc\xa7"
-  "\xe8\x11\x96\x54\x78\x9a\x21\x26\x6c\x5f\x9e\x9d\xf7\x14\x0e\x80"
-  "\x17\x3b\xf9\x1b\x9a\xbf\x4d\x95\xdd\xcc\x58\xd1\xcd\x12\xda\xf3"
-  "\xa4\xef\x59\xc8\x3e\x61\xd3\xe0\xa2\x74\x6b\x7e\x80\x1d\xf5\x7e"
-  "\x86\x33\x0e\x67\x7b\x36\xe1\x9d\xe3\x8c\x61\xfe\x1a\xb3\x59\x62"
-  "\xed\x34\x7e\x98\x3b\xca\x89\x77\x2f\xc7\x77\x8f\x1d\x54\xd2\x26"
-  "\x1c\xdc\xd0\x32\x01\xf1\x73\xbb\xd9\x9f\x5e\x54\xe7\xe6\x6d\xd2"
-  "\x66\xe7\xe4\x6d\xaa\x3c\xff\x18\xd1\xbe\xb4\x37\x9d\xdc\x2b\xf7"
-  "\xf3\x93\xeb\x55\x19\x06\xee\x85\x5f\x58\xea\x47\x13\x62\x68\xa3"
-  "\xce\x03\x4a\x93\x88\xa1\x7d\x70\x43\xda\x84\x82\xa5\x4c\xdf\xee"
-  "\x3e\x23\x4e\xc3\x70\xee\x42\xeb\x6e\x1f\xad\xb3\xc6\x5d\xd3\x78"
-  "\x35\xb5\xaf\xbc\x6e\x1a\x2f\xa5\x36\x35\xf8\x1d\x1f\x27\xba\xd9"
-  "\x87\x06\x55\xc6\xea\xa4\x75\xb1\xaf\x82\xca\x64\xac\x65\x37\x54"
-  "\x50\xb9\x4a\x2a\x07\xda\x4d\xb6\xef\x93\x38\x82\xc1\x21\xfa\x66"
-  "\x87\xe5\x51\xa4\xdd\x42\x06\x86\x6f\x53\x3f\x2c\xdd\xcc\x2d\xe4"
-  "\x22\xf8\x86\xf6\x5d\xaa\x9f\xf0\xdf\x87\x4e\x55\xde\x5d\x2d\xeb"
-  "\xf9\x58\xe5\x87\xba\x9a\xaa\x86\x63\x9c\x77\x35\x55\x6c\xa0\x3d"
-  "\x9d\x78\x6a\xfa\xc6\x36\xfa\x86\xd3\xb4\x89\x71\x13\xec\xea\x8e"
-  "\x07\x89\xde\x53\x54\xfd\x2f\xf7\xf7\xd5\x77\x05\x0d\x22\xe8\x0e"
-  "\xe2\xf5\x25\x4f\x4a\xb4\x47\x0e\xe1\x09\xa2\x37\x84\x2e\x32\xd1"
-  "\x1a\xc8\xa7\x6f\x6c\x83\xdf\x3f\xe2\x15\x0e\xd1\xbe\xdd\x08\x3a"
-  "\xe1\xd1\x8b\xdf\x60\x22\x16\x20\xd1\x0a\x6b\xec\x3c\x20\x63\x03"
-  "\xb8\x2d\x1a\xad\x80\xf9\x01\xfa\xa0\xe2\x51\x16\x3d\x44\x63\x4c"
-  "\x73\xa4\x85\x68\x8f\x29\x67\x98\x7b\x89\x3a\x36\x2d\x82\x26\x50"
-  "\x63\x22\x49\x1c\xee\x5e\x41\x7b\xbb\x91\xbe\xd1\xe2\x66\x67\x85"
-  "\xec\x4c\xe2\x20\xb7\x5d\xdb\xe7\x65\x5c\x3f\xf7\x12\x4e\xb8\x8e"
-  "\xe0\x76\x68\x56\xb6\x8e\xe8\xd0\x8f\x9d\x34\x16\x87\x50\x16\x76"
-  "\xe3\x54\xbe\x81\xf6\xfc\x59\xea\x98\x1c\xaf\xc8\x07\x0d\xe0\x4e"
-  "\x41\x3b\xe8\x9d\x56\x82\x35\x7d\xab\xdb\xad\xe2\xb1\x63\x92\x7e"
-  "\xe9\x7e\x47\x83\x3d\x8d\xf5\x96\x30\xfc\xdd\xbe\x48\xf8\x13\x2c"
-  "\xb6\xc8\x31\xe8\x5e\x1b\x31\x76\x44\xaf\x77\x2f\x82\xec\x8d\xbe"
-  "\x77\x58\xca\x0d\x4e\xdc\x06\x1f\x3f\x34\x67\x0e\x13\x2c\x0e\x53"
-  "\xb9\x26\xe0\xe6\xcd\x7f\x62\x6a\x7c\xfb\xee\xaf\x4a\xfa\xf4\xc4"
-  "\x31\x19\x03\xfa\x84\x1a\x03\xda\x3d\x57\xc6\x7f\x3e\xf1\xa2\x8c"
-  "\xff\x7c\x62\x57\x64\x4c\xfb\x70\x3c\xfb\x13\xe5\x9a\xbe\x3f\xe6"
-  "\x00\xc6\x9e\xfa\x38\x57\xf2\x66\x27\xca\x21\x5f\x11\xef\x0d\xe5"
-  "\xa0\x8d\xc7\xb1\x3e\xb5\xe7\x88\x71\x4f\xf9\x2c\x02\x36\x73\xd5"
-  "\x31\x69\x92\x71\x2f\xba\x6f\x93\x6d\xeb\x36\x50\xda\x40\x6d\x10"
-  "\xfc\x1d\xe2\xdd\x57\xe1\x9d\xc2\xf0\x3b\x58\x3f\x34\x97\x4d\xf4"
-  "\xce\xcd\x74\xe5\x5a\xd9\xdd\x83\x28\x73\x62\xdf\x73\x83\x90\xaf"
-  "\x9c\x68\xee\x1f\xb2\xea\xe9\xbb\x01\xfa\xae\x1e\x73\x03\xf3\x42"
-  "\xab\xa3\x4a\xc2\x68\x1f\x8d\x9f\x98\x5f\x47\x82\x4d\x04\xf7\x6e"
-  "\xe2\xff\xdb\x16\x4b\xda\xee\xc4\x3e\xb5\x7d\x4e\xe9\xdf\xb6\xeb"
-  "\x38\xe2\x0d\x4a\x7f\x33\xdd\xdb\x86\xcf\x0a\x87\x69\xcc\x13\xfb"
-  "\x30\xf7\xa8\xae\x56\x75\x4e\x98\xa8\xdc\xe1\xe1\x39\x24\xec\x84"
-  "\xbb\xe7\x81\xce\x54\xdb\x8f\xb9\xf7\x55\x09\x3b\xf7\x71\xcc\x01"
-  "\xa2\xe1\xd3\xe4\x38\xbb\xe7\x82\x4e\x95\xf3\xf0\x13\xa6\xd5\x21"
-  "\x6d\x8d\x4f\x94\x2b\x54\x87\x36\x57\x22\x71\x03\x95\x9d\x45\x34"
-  "\xe9\xf0\xbc\xd1\x70\x81\xac\xb3\x67\xb9\x4a\x87\x58\x69\x6c\xe0"
-  "\x93\xd1\x09\xba\x5d\xce\xcb\x9e\xd4\x23\xbe\xa0\x88\x81\x4d\xed"
-  "\x22\x9c\xf0\xc9\xf3\xfd\xb1\x3d\xd6\xf0\xdc\xfe\x64\x8b\x36\xb7"
-  "\x23\xc6\x55\xcc\xed\x2d\x02\x1f\x7d\x42\xfc\xef\x57\x16\x69\x73"
-  "\x1f\xeb\x1c\xb1\xe8\xab\xf2\x65\x9c\x7a\xc8\x40\xc4\xba\x0f\x78"
-  "\x04\x7f\x81\xf1\x6c\xb7\xf7\x08\xbf\x96\x88\x53\xdf\xee\x3b\x09"
-  "\xbe\xf1\x0c\xd6\xbf\xb6\xc6\x31\x36\xf4\x2d\x27\xd5\xd7\xb1\x85"
-  "\x70\x20\xd6\xa0\x8f\xda\x84\xf8\x8f\xf0\xdb\xd1\xbc\x24\x4d\xc4"
-  "\xb0\x3f\x92\x8d\x71\xeb\x49\xd6\xf4\x8b\xab\x24\x0e\x30\xaa\xf3"
-  "\x45\xb4\xf1\x32\xb8\x9a\x24\x5c\x7b\x32\x47\xae\xef\x13\x01\xac"
-  "\xef\x48\xb8\x02\xa6\x80\x2d\x95\xa5\xfe\x7f\xb8\x4c\x83\x6b\x04"
-  "\x4c\x2f\xaa\xf3\x51\xc5\xad\x3d\xa3\xe2\x56\xf8\x07\xa5\x76\x35"
-  "\x6d\x46\x5f\x68\x4f\xc1\xf7\x85\x9f\x6d\x95\xef\x69\xf6\x62\x4e"
-  "\xf5\xf4\xb9\x59\x16\xd3\xf0\x18\xcd\x15\xe1\x73\x09\x63\xa5\xe1"
-  "\x0e\xc8\x10\x64\xdb\x4f\x26\x6a\xe3\x81\x76\x47\xe2\x04\xda\x63"
-  "\xc4\x59\x4c\xb8\xcf\x27\xef\xa3\xf7\xa6\x02\xb7\x85\xe9\xab\x93"
-  "\x0f\x8d\xec\xfb\xc9\x79\xe8\x3b\xe6\x84\x2d\x1f\x72\x04\xb9\x97"
-  "\xb9\xd9\x9f\x5a\x46\xe2\xab\x3f\xfd\x46\x9e\x11\x4a\x7a\x0c\xf8"
-  "\xde\xf6\xa8\x2c\x8f\xfd\x8d\xca\x3b\xc5\x5e\x27\xf7\xc3\x59\xd8"
-  "\xff\x28\xef\x90\x0a\x83\xe3\x54\xbe\x19\x36\x8b\xf0\x49\x31\xf9"
-  "\xb8\xe4\x03\x09\x47\x1f\xa6\xbd\xc3\x49\xe5\xf2\xda\x89\x07\x08"
-  "\x4e\x64\xac\x56\xa5\x37\x81\x27\xf8\xba\xcc\xc9\xeb\xfa\x58\x8c"
-  "\xed\x1e\xfe\x49\x2f\xeb\x7d\x8a\xd6\x51\x00\x67\xf9\x54\xb7\xa5"
-  "\x97\x9d\xfe\x26\x7d\x37\x51\xbd\x9a\xe9\xfa\x0f\x74\xbd\x96\xae"
-  "\x37\xd2\xf5\x3a\xba\xc2\xf6\x54\x51\xcb\xa7\xf4\xb2\xbe\xcf\x28"
-  "\xff\x4e\xf5\x4a\x6d\xec\xcd\xa1\xeb\xe2\x67\x40\x57\x3e\x2a\xf2"
-  "\xdf\x44\x9a\xae\xaf\xa8\xfd\x6e\x95\x6b\xbb\xf7\x79\xaa\xc7\x8e"
-  "\x72\xd8\xd7\x28\xcf\x46\x65\xd6\xa3\x6e\xd8\x12\xd3\xfd\x6d\x11"
-  "\xf4\x29\xd5\x73\xea\x5b\x74\x9d\x4b\xd7\x19\x74\xcd\xa3\xf7\x4f"
-  "\xa0\x5e\xf8\xba\x0d\xe3\x0b\xf7\xdc\x65\x76\x39\x9e\x34\xd6\x8d"
-  "\x58\xef\x1a\x3e\xc0\x7c\x1a\x51\x6e\x89\x2c\x27\x79\x57\xd8\x86"
-  "\xc8\xb1\x0b\xca\x79\xdb\x1c\xa4\xb1\xa3\xfa\xbf\x86\xf7\xe9\xba"
-  "\x40\xbd\xa6\xa9\xd7\xfb\xd4\xeb\x3f\xa9\xd7\x85\xea\x35\xdd\xcd"
-  "\x7a\xdd\x2a\x6d\x42\x30\xeb\x75\x03\x26\xb4\x76\x57\xca\xef\xf6"
-  "\x25\x82\xb7\x26\xfc\xff\xd5\x7e\xc4\x52\x70\x9c\x2a\xd5\x64\x75"
-  "\x90\xf1\x0e\x39\xba\xfc\x3b\x85\xde\xc4\xa9\xfa\x08\x5c\x98\x60"
-  "\xd4\xa5\x31\xa2\x9d\x26\xd6\xea\x89\x6e\x10\xf5\x9c\x0a\xe8\xd5"
-  "\xf3\x47\xf8\x5c\x46\x8c\x88\xac\xa0\x41\xda\xc2\xc5\xcd\x6c\xc2"
-  "\x7a\x15\x72\x4c\xf8\x56\x8a\x71\x27\xd2\x0f\x7e\x3e\x92\x35\x7c"
-  "\x0f\x7e\x49\xf5\x91\x35\xcd\xef\xe8\x33\x86\x79\xfc\x53\x87\xe5"
-  "\x79\xce\xd5\x84\x9f\xfa\x92\x23\xf2\xed\x68\x33\xc1\xba\x93\xfa"
-  "\x33\xb7\x9b\xf5\x2d\xa2\xeb\x1d\x3d\xb2\xcf\x29\x5a\x9f\xd5\xb1"
-  "\xb2\x69\x30\xef\x61\xbd\x7d\x84\x0f\x73\x31\xbf\xbb\x87\xf1\x72"
-  "\xaf\x38\xd7\x55\xe7\x0f\x8d\x73\xef\x76\x8c\x77\x04\x3e\x99\x15"
-  "\xc6\xd3\x7d\x0d\x23\xc7\xc5\xdd\x10\x94\xf4\x42\x27\xad\x4b\xcc"
-  "\x01\xdb\x65\xeb\x72\x1e\xd6\xa5\xfa\x6e\xcf\x48\x1c\x7f\x72\x1e"
-  "\x70\xbc\xda\x46\x9a\xb7\xbd\x8b\x31\x36\x6e\xd6\xd7\xac\xee\x49"
-  "\x9d\xb4\x47\x7e\x95\xf2\x55\xb9\xa8\xcc\x57\xbf\x45\xf3\xaf\x17"
-  "\xfe\x00\xaf\xd3\xf2\xd5\xf9\x8d\x7a\xac\x18\x6b\x2d\x5f\xad\x9f"
-  "\xe6\x69\xaf\x05\xeb\x47\xcb\x97\x73\xf2\x13\x3b\xf0\x0d\xde\x45"
-  "\x7f\x40\x33\x3b\x1f\x6d\xa6\x76\x9f\xde\x43\xf4\x45\x3d\xd6\xf3"
-  "\xe6\x0d\xcc\xb8\xae\x86\xc5\xc9\xb5\x79\xfa\x4d\xed\x5d\x29\xeb"
-  "\x3c\xdd\xa4\xe1\xa8\x2a\x81\xcf\x7a\x66\x8d\xc4\x95\x9e\x09\xdc"
-  "\x61\x0a\x06\x0d\x6e\x63\x5b\x70\xae\xc0\xb9\xb4\xee\x6b\xe9\x3d"
-  "\xaf\x9b\x95\xd7\xa8\x7b\x49\xab\x94\x23\x9f\xb9\xb9\xad\x5e\xe2"
-  "\x2e\x59\xf7\x99\x61\xfc\x17\x41\x87\x08\x5c\x8f\x6f\xa1\x2e\xda"
-  "\x57\x12\x7c\x45\x99\x93\x25\xfe\x3e\xb3\xd0\xcd\x62\x8f\x6b\xb8"
-  "\x15\xfb\x93\x49\xc7\x6c\x95\x8f\xca\xfd\x49\x81\xfc\xcb\xe6\x13"
-  "\x7e\x84\xda\x6d\x1e\x86\x7d\x13\x7e\x5e\xb3\xd6\xc7\xc2\xd7\x4b"
-  "\x66\x2f\xfb\x14\xf1\xf6\xf6\xa8\x70\xa4\xf5\xf3\x69\x9b\x3a\x0e"
-  "\xc7\xe9\xfb\x7b\x80\xcb\x37\xe7\x4b\x3f\xe5\x90\xfd\x08\x3f\xf8"
-  "\xa0\x51\xcd\x3c\xd0\x5c\x8b\x35\x72\xa6\x39\x42\x9e\x55\x2f\xd7"
-  "\xc5\xe9\x57\x45\x4c\x85\x52\xb7\x51\xca\x0e\x3f\x5d\x2a\xf3\x3f"
-  "\x55\xcf\x5a\x85\x3f\x39\xa4\x53\xa2\xcc\x89\xb9\x32\xee\xcc\x47"
-  "\x53\x25\xfd\xf1\x69\xe2\x65\x7e\xa1\xf4\x94\x67\x0d\xfb\xcc\x3c"
-  "\xad\x9e\x73\x7f\x1a\x71\xfe\xf9\xa9\x88\x1f\x46\x75\x6d\xa4\xfc"
-  "\xe1\xf3\x4f\xb9\xd7\xb8\xad\xaa\xbc\x2c\x61\xf2\xa6\x34\x46\xb8"
-  "\x79\xe2\x4e\x87\xb6\x7e\x3f\x3d\x24\xda\xa3\xae\x5f\xf4\x19\xf3"
-  "\x01\x6b\x38\x08\x5f\x3c\xb4\x86\xb1\x96\xe9\x3e\x31\xa8\xad\x5d"
-  "\x49\xdf\xcd\x12\x6b\x57\xac\xdb\x4f\x9b\x23\xda\x51\xa0\xce\xd5"
-  "\xe3\xfd\x8f\x99\x8d\xf4\xcc\xed\x66\x5d\x49\xf2\xd9\x99\x6a\xb5"
-  "\x1d\x46\x7a\x5e\xeb\x2c\xfc\x2d\xc6\x7e\x93\x5c\x13\x67\x8a\x31"
-  "\xef\x5c\x34\x57\x68\xbf\xa8\x91\x31\xe6\x3d\x49\xda\x5c\xa1\x35"
-  "\xb5\x8c\xe6\xd4\xfe\x6d\xd3\x78\x0d\x8d\x09\xf4\x31\x57\x52\x1a"
-  "\xeb\x75\x99\xbc\xea\x12\x70\x55\xe7\x68\x0d\xbd\x4b\xfb\x7f\xac"
-  "\x36\x26\xc7\x7d\x71\x93\xeb\xc5\x9c\x28\x84\x6e\x4c\x8a\x38\x8f"
-  "\xc4\x9c\xc0\x7c\x10\xe7\x92\x34\x37\x4c\x9b\xbe\xc1\x30\x2f\x84"
-  "\x3d\x3f\xa5\xd1\x26\xcc\x0b\xaa\x6b\x8f\xe6\xa3\xd2\xcd\x3c\xe9"
-  "\x12\xf6\x9e\xa6\x48\x1d\x41\xaa\xdb\xd2\x6c\x21\x7e\xa7\xb4\xa5"
-  "\x34\xef\x46\x76\x35\x62\x84\xc3\x17\x1d\x62\xae\xe3\x1d\x9c\xe9"
-  "\x48\x3c\x77\xf5\xff\xa6\x77\x7d\x61\x78\xb9\x85\x5f\x81\x23\x4b"
-  "\x84\x0c\xf2\x2a\xbf\xe3\x6c\xc2\x48\x5c\xf1\x51\x8f\xa0\x07\x69"
-  "\x5f\x9d\x99\xc8\x2c\x34\xff\x68\x8f\x38\x3b\x57\xa3\x63\xe7\x24"
-  "\xe2\x6c\xf8\x23\xf0\x17\xe0\x61\x3b\xe8\xbe\x00\xfb\xeb\x18\xb2"
-  "\xe2\xb9\x90\xf1\x60\xad\x43\x66\x04\xf9\x15\x7c\xca\xf7\x32\xef"
-  "\x9b\x6d\xf0\xb5\xb1\xfa\xcf\xfd\x92\x16\xda\xf9\x45\xf8\x7e\xb1"
-  "\xe4\xb2\xab\xba\x99\x17\xb1\x80\x3b\x8b\x3e\x83\x6c\xe6\xec\x65"
-  "\xfe\x0f\xcf\x19\xd5\x9f\x85\x7e\x5b\xc2\xbf\xf3\x89\xea\x7d\xf5"
-  "\x95\x7f\xe7\x67\xc9\xb2\xe7\x09\xe7\x9d\x5f\xa8\xc2\xea\x87\x7e"
-  "\xc7\x39\x8b\x06\x2b\xe0\x02\xe0\x46\xe8\x04\x40\xd6\xa4\x0b\x32"
-  "\xf8\x12\xa0\xf1\xa2\x76\x6f\xbe\xf5\x41\xe7\x06\xf0\xa2\xe7\x84"
-  "\x4e\x13\xfc\x68\x8e\x4f\xff\xe4\x9c\x38\x03\x94\xbe\xf9\xce\x25"
-  "\xd2\xb7\x7f\x5a\x75\x8e\x45\xdb\x72\xd9\x0c\xc8\xbd\x4d\x21\xee"
-  "\x04\xef\xaa\xc6\x35\xef\x38\xc3\xce\x5f\x9d\xb7\x91\xe9\xe9\xf9"
-  "\x0d\x74\xaf\xc5\xd7\x3c\x4e\xef\x24\x44\x05\x58\x22\x68\x9f\x05"
-  "\x1b\xd9\x0d\xd4\x7e\xb7\x36\x56\xa0\x0f\x20\x7f\x53\x65\x08\x68"
-  "\xeb\x8d\x78\x0f\xbe\x96\xdd\x02\x6e\x2a\xce\x39\x07\x79\xf3\xb9"
-  "\xd6\x28\x1f\x4b\x90\xfb\xc7\x79\xda\xff\x3e\x52\xe9\xc1\x73\x7d"
-  "\xb4\x06\x8e\x45\xb4\xf3\xc3\xf0\xfd\xb4\x6b\xf1\xbe\xc9\x07\xda"
-  "\x6b\x2c\xf8\x9c\x7f\x4a\x83\x0f\x74\x53\x89\x9f\xb7\x89\xf1\x0e"
-  "\x72\x0f\xb5\xad\xd5\xb6\x81\x19\xce\x30\xef\x53\x88\x59\x40\xeb"
-  "\xa6\x45\xca\xe5\xbd\xcb\x35\xfe\x5a\xb6\xdb\x7b\xbb\x69\x53\x14"
-  "\x83\x3c\x3d\x2b\x64\x11\x67\x7e\xfc\xbc\x59\xc8\xd0\x5d\xc1\x79"
-  "\xcc\x59\x78\x17\xca\xdc\xa8\xee\x41\xc7\xfb\x8b\xcc\xec\x88\x79"
-  "\x1e\xad\xe7\xf3\x1e\xb7\xee\xfd\x2f\xa0\x4b\x79\xde\x23\x79\x1b"
-  "\x69\x47\x88\x34\x6c\xfe\x08\x9e\xad\xf2\x9c\xfb\xfc\x6f\xb0\x27"
-  "\x80\xc7\xa7\xfd\xa0\x19\xfb\xae\xdf\xe1\x1d\xa6\xff\x09\xdf\x13"
-  "\x7e\x3a\xaf\x9e\xbb\xe0\x6c\xf1\x7c\x13\x7c\x2d\xa8\xba\xaf\x28"
-  "\x6f\x94\xb2\x7f\x6f\xf9\x30\xdd\x4c\xe5\xf0\x9e\xd4\x6d\x3a\x5f"
-  "\x9d\x15\x82\x4c\xe0\x7c\x35\xfa\x2a\xe7\xe6\x34\x1a\x5b\xef\xe1"
-  "\xf0\x3a\x3e\x27\x68\x89\x23\x9e\xc8\x75\xea\x3d\x1e\xe6\x37\xcf"
-  "\x16\xdf\xb6\x8d\x59\x46\x5b\x97\xb6\x78\x96\xf0\xa9\x81\xfd\x4b"
-  "\x55\x15\xaf\xaf\xd6\x2b\xf7\x6e\xae\x64\x46\x5d\x39\x81\x11\xeb"
-  "\x2e\x3f\xfb\xea\x5e\xf6\xd9\x23\x26\xe3\x35\x8b\x17\xe4\x4d\xe2"
-  "\x85\x66\xa6\xaf\xb8\x30\xc9\x70\x63\xe0\x9a\x7a\x1e\x75\xeb\x83"
-  "\xf7\xe7\xe1\x6c\xaf\x9a\x9d\x5a\xc9\xa2\x16\x84\xe8\xdb\x46\x66"
-  "\x73\xb3\xfe\x1c\xd8\x66\x1e\x31\x82\xa6\xe8\x87\xee\xcc\xbd\x05"
-  "\xb5\xcc\x50\xd0\xc3\xfb\xca\x1f\x9f\x60\xa0\x7d\x34\x81\xf0\x7f"
-  "\xe9\x64\xe3\x35\xf5\x43\x54\xc7\x1b\xd9\xe2\xbd\xc6\xf1\xb7\xcd"
-  "\x36\x8d\xda\x76\x69\x7c\x6d\xf3\x35\x84\xdb\xe6\x6b\xf8\x1b\xb7"
-  "\x2d\x21\xdc\xb6\x1c\x6a\xdb\x85\xe7\xc7\xd7\xb6\x8b\x7d\xe1\xb6"
-  "\x5d\xec\xfb\x9c\x6d\xdb\x37\xfe\xb6\xd9\xaf\xe9\x65\xfd\xb7\x8f"
-  "\xaf\x6d\x7e\x6b\xb8\x6d\x7e\xeb\x5f\xd3\xb6\xc2\x5a\x7e\xb2\x3d"
-  "\x49\xc6\x23\x05\xde\xef\x65\xbe\xaf\x6e\x4c\x42\xbb\xd8\x54\x6a"
-  "\xd7\xe9\xa2\x5a\xfe\x89\xa4\x59\xfa\xf7\xcb\xbd\xae\x9f\xf6\xbf"
-  "\xb3\x99\x72\x1e\xfb\x04\xcf\xab\x44\x4d\x6f\xe0\x0e\x1e\x9c\xed"
-  "\x83\xbe\x53\x10\xfe\x08\xe0\xbb\x37\xfd\xe0\x40\x40\xcf\x63\xdd"
-  "\x99\xbb\x2f\x44\x23\x0e\x1f\xd1\x2d\xfd\x6e\xcd\xbf\xa0\xf6\xae"
-  "\xa9\xe6\x4a\xf8\xc9\x77\xf5\x82\x1c\x66\x02\x7e\xc2\x15\xb1\x67"
-  "\xaa\x0a\x27\x19\x16\x7c\x06\x7a\xc0\x37\x4b\xb3\xcf\xd2\xea\xca"
-  "\xe8\x9b\xc4\x4d\x05\x2c\x0a\x36\x62\xc2\x6f\x99\xd9\xcb\x92\x0b"
-  "\xd8\x84\x0c\x3b\xd5\x1f\x60\xd9\x26\x3b\xd5\x4d\xf0\x90\x34\xb9"
-  "\xef\xa9\xa8\x95\xcc\xb8\x8d\xea\xc6\x75\x81\xb9\x88\x6f\xde\xce"
-  "\xa2\x61\x4b\x06\x9b\x30\x69\x0f\x36\xd1\x40\xdf\xd9\xa6\x7d\xe7"
-  "\x2f\xc0\x2f\x5e\xc2\xef\xe2\xda\x30\xfc\x2e\xde\x12\x86\x9f\xef"
-  "\xac\x84\x9f\xaf\x27\x0c\xbf\x8b\xc7\xc6\x07\xbf\x8b\x96\x30\xfc"
-  "\xe4\xbb\x57\x86\xdf\xc5\x87\xc7\x86\xdf\xc5\x95\x61\xf8\xc9\xba"
-  "\xc6\x80\xdf\xc4\xd1\xe1\x77\xf1\xe5\xcf\x07\xbf\x8b\xc7\x3e\x27"
-  "\xfc\xe2\x24\xfc\x06\x5e\x09\xc3\x6f\x60\x45\x18\x7e\x03\xb7\x49"
-  "\xf8\x0d\x24\x87\xe1\xe7\x4f\x1c\x1f\xfc\x06\xb2\xc3\xf0\x93\xef"
-  "\x5e\x19\x7e\x03\xcf\x8f\x0d\xbf\x81\x7d\x61\xf8\xc9\xba\xc6\x07"
-  "\xbf\x81\xcf\x08\x6e\x09\x2a\xfc\x12\xc6\x86\x9f\x3f\xf1\x73\xc2"
-  "\xcf\x24\xe1\xe7\xbf\x18\x86\x9f\x7f\x6f\x18\x7e\xfe\x27\x25\xfc"
-  "\xfc\xcb\xc2\xf0\x0b\x3c\x34\x3e\xf8\xf9\xeb\xc3\xf0\x93\xef\x5e"
-  "\x19\x7e\xfe\x0f\xc6\x86\x9f\xdf\x13\x86\x9f\xac\x6b\x0c\xf8\x4d"
-  "\x1a\x1d\x7e\x81\xdb\x3f\x1f\xfc\x02\x0f\x5d\x09\x7e\xe3\xa3\x3d"
-  "\x02\x39\x6c\x0c\x1d\xbc\x71\xd6\x33\xb6\xdf\x35\xc4\x72\xba\xc4"
-  "\xf4\x8a\x23\xd0\x58\xa7\x4c\x34\xe0\xbc\x96\xee\x21\xbb\x9a\xdf"
-  "\xcd\x02\xa1\x3a\x65\x82\x81\x3b\x7e\x5d\xaa\x38\x7e\x93\xce\x37"
-  "\x4d\x8c\x56\x36\x4d\x8a\x86\xfd\xea\x68\x75\x49\x5d\xbf\x4b\x8f"
-  "\x44\x5d\xcb\xae\x87\x5d\xc7\x66\xa2\xdf\x70\xef\x77\x5c\xca\x21"
-  "\x5a\xe4\xcf\xfc\xec\x2f\x5b\xb1\x66\xe9\x77\x56\x2e\xb7\xe4\x2e"
-  "\x5f\xb6\x76\xd5\xb2\xa5\xab\xf2\x2c\x4b\x1f\xfb\xde\x9a\x91\xbe"
-  "\x8e\x45\xec\xcd\x2d\x18\xbf\x4b\xfb\x86\x7d\x0d\x38\xb8\x1d\xfe"
-  "\xa5\x6c\x37\xb1\x98\x33\xec\x92\x47\xf8\x88\x8e\x75\x37\xf3\xa1"
-  "\xcc\x1d\x69\x33\xf9\xeb\xc2\x6f\xd6\x50\xce\x0e\xe2\xb3\x6a\xe0"
-  "\x5f\x40\x3d\x4f\xaa\xe9\x65\x43\x17\x79\x4c\x0f\x68\x4b\x9f\xd4"
-  "\x39\x1f\x14\xbe\x18\xe0\x77\x80\x1b\xba\xbc\x4a\x69\x4f\x0b\xdf"
-  "\xda\xe3\x04\x0c\xda\xe1\xb3\x28\x3f\xea\x86\x6e\x16\xda\xc3\x63"
-  "\xba\xbc\x54\x97\x4f\xad\x07\xfe\x70\x7d\x69\x1b\xf8\xc7\xa8\x4f"
-  "\xa5\xbd\x11\xff\xd0\x29\xe9\xc1\xc1\x4d\xa6\x4d\x96\x28\x94\x85"
-  "\xef\x30\xf8\xd4\xd2\x62\x8b\xa0\xdd\x28\x4b\xf4\xf9\x7c\x7a\x7f"
-  "\xfe\x6e\x11\x3b\x44\xad\x43\xb6\xe9\x2a\x6a\x53\x93\xe8\x4b\x69"
-  "\x57\x6d\xff\xd3\x99\x3b\x50\x8f\x84\x6b\x68\x2b\x7d\xbb\x16\x75"
-  "\xc0\xa7\x0f\xde\x55\xdf\x99\x41\xef\x48\xdf\x25\x9b\xaf\xdb\x21"
-  "\xeb\x08\x3d\xa5\xb5\x8b\x68\xea\x58\x4a\x7f\x2b\xe2\x1b\x93\x29"
-  "\xfd\xb5\x88\xe7\x46\x4a\xdf\x4c\x74\xe8\x14\xf5\x79\x1c\xa5\x11"
-  "\xef\xcc\x28\xfa\x55\x59\xac\xea\x73\x06\x3d\x94\x97\xa0\x96\x99"
-  "\x72\x86\x05\x11\x8b\x78\xaa\x5a\xc7\x54\x4a\xbf\x02\x1e\x52\x7d"
-  "\x9e\x48\xe9\xed\x90\xef\xab\xcf\xaf\xa6\xf4\x46\x4a\x7f\x59\x7d"
-  "\x4e\x74\xfe\x90\xf4\xb5\x65\xe8\xea\x43\x9f\x08\xf6\x0d\x22\x96"
-  "\x78\x4c\x57\x1f\xe5\xd5\x10\xff\x5a\x84\x71\x44\x3f\x9d\x1b\xe0"
-  "\xe7\x60\xa8\x0d\xb6\x1e\x72\xac\x7a\x54\x3f\x11\xfa\x4c\xca\x87"
-  "\x1c\x27\x2a\x5e\xc4\x23\xe8\x69\xc0\x3d\xb5\xf5\x6b\x80\xa1\xfa"
-  "\x2d\xe2\x91\x86\x7c\xea\x38\x13\xec\xe0\x7f\x92\x15\xa3\x5e\x69"
-  "\xe7\x30\xa4\xda\x39\x04\x8d\x5f\xcc\x26\x39\x68\x14\xfd\xa0\xb9"
-  "\x07\x19\x88\x37\xa6\x6b\x8b\xb0\xc3\xa7\xf9\xa7\xcd\x03\xcc\x01"
-  "\xae\xbf\x94\x27\xe5\x2b\xc1\xbc\xb0\x1f\xfa\xa1\x63\xaa\x8c\x85"
-  "\x49\x1e\x20\x18\xa1\xff\x33\x24\xd6\x7e\xc4\xb3\x7d\x11\xcf\x32"
-  "\xb5\x67\x52\x47\x2d\xd8\x12\xf1\x2c\xfd\xb2\x67\x3d\x11\xcf\x52"
-  "\x47\xd6\x19\x62\x11\xcf\xac\x23\xdf\x0b\x25\x45\x3c\x4b\xbc\xec"
-  "\x59\x6a\xc4\xb3\x68\xf5\x59\x14\xe5\x2f\x0e\xfb\xec\x1a\xf4\xa9"
-  "\xf9\x84\xc7\x43\x39\x11\xf9\x3d\x6a\x3e\xbe\x5f\xec\x66\xfb\x55"
-  "\x58\xc8\x39\x4c\x73\xe4\x4b\xea\x37\x6a\xc3\xdf\x18\x54\x75\xae"
-  "\xba\xb6\xc8\xb1\x1a\x9c\x65\xd2\x59\x26\x61\xbe\x98\x36\x15\x23"
-  "\x6e\x45\xb5\xf4\x4f\x23\xd7\x98\x88\xd3\x46\x57\x7a\x6f\xd6\x58"
-  "\x78\x6f\x74\x1d\x3e\x25\x41\xb3\x7b\x0a\x95\x76\x95\x2a\xe5\x46"
-  "\xf8\x12\xbd\x01\x7e\x6c\x8a\x3c\xf0\x03\xe0\x63\x2e\x36\xc8\x5c"
-  "\x79\xfe\x62\xc4\x89\x6a\x97\xf1\xa1\xe2\x71\xfe\x06\xbd\x7b\xf8"
-  "\xe2\x69\xb7\x9d\x15\x31\xa2\xd6\x79\x58\x92\xed\x1e\xde\xd3\xcb"
-  "\x94\xbc\xd0\xd6\xae\x52\xd5\x96\x77\xbb\xb4\x47\x53\x64\x7f\xc0"
-  "\xb3\x7a\x84\xfc\xd7\xd0\xcb\x78\xb4\x28\xc3\x33\xb7\xcb\x3e\x72"
-  "\x01\xd7\xdd\x0e\x2d\xe6\x8f\xb2\x4f\x8b\x8d\xe6\x66\xdc\x70\x31"
-  "\xe6\x54\x2a\xe5\x39\x47\xea\x1c\x2a\x1f\xa2\x4e\xb4\xdd\xcd\x94"
-  "\x02\xd4\x4d\x65\x7a\x86\x75\x0e\x29\x7f\x5d\x90\x4d\xa7\x76\xf5"
-  "\x6a\xf5\xfb\x1d\x3c\xda\xcd\x42\x82\x8f\x44\x9d\x17\x2b\xe2\xb2"
-  "\x29\xcf\xec\xd6\xff\xcc\x23\x75\x16\x39\xd1\x3f\xaf\xfe\x59\x1c"
-  "\xe2\x11\x3a\xd9\x86\x1e\x37\x2f\xed\xe9\xa3\x35\xdc\x29\xf4\x2b"
-  "\x63\x7a\xdc\x92\x57\xe7\x4f\x41\x2f\x02\x31\xef\xc0\x3b\x4b\x3c"
-  "\xc2\xe5\xf9\x07\xe5\xd1\x18\x35\x10\xbe\x15\xbc\xeb\xf8\xd6\x1c"
-  "\x17\x30\xa9\xba\xc0\x0c\x95\xb9\x9a\xcf\x5c\xde\x1a\xe1\x4b\x5c"
-  "\xd5\x45\xe6\x17\xdb\xed\xe2\x4c\x48\xb4\xf1\xf2\x36\xa0\xbd\x54"
-  "\x97\x6d\xcc\xbd\xd1\xd0\xd3\x29\xe4\x93\x65\xee\x1c\xa1\xdf\xa5"
-  "\x63\x77\x47\x99\xaf\x7d\xda\x5f\xc2\x52\x35\xde\x1b\x65\x2a\x07"
-  "\x19\x53\xa8\xfe\xe1\x7e\xe6\x06\x51\x36\x5b\xc8\xcf\x75\x2c\x8f"
-  "\xf0\x52\x27\xda\xa0\xe6\xe7\xb5\x07\x03\xb0\xa9\x1c\xd5\xb7\x8a"
-  "\x88\xa3\x02\x9d\xca\xb2\x1e\xc4\x8c\xf1\xcd\x09\xa8\x6d\xd6\xe9"
-  "\xf2\xa0\x43\x8c\x36\x0b\xd8\xea\x74\x2b\x34\x38\x56\x5c\xa0\xba"
-  "\x0b\xbb\x58\x8f\x8e\x7d\x06\xbd\x13\xe8\xc4\x57\x6d\x50\x75\xa1"
-  "\x28\x4f\x94\x1b\x1c\x2e\x23\xf4\xfa\x61\x0b\x08\xfc\x58\x27\xe2"
-  "\x78\x50\x1f\x68\x2c\x84\x5d\xb9\x4e\xf7\x0f\x42\x8e\x99\xcb\x64"
-  "\xbf\xa1\x67\xa6\xd3\x09\x3d\x65\x7f\x89\x2e\xc5\xad\xd3\x09\xfb"
-  "\x21\xb7\x9a\x57\x85\x6f\xe7\x0f\xb2\x73\x3a\xdd\x14\xc4\xdd\x23"
-  "\x78\xf4\xc1\x27\x51\xbb\x8f\xd6\x89\x7d\x10\x73\xa1\x0f\x31\x9b"
-  "\xa8\x7c\x82\xc4\xf7\x04\x73\x1d\xf3\xe1\xfb\x80\x2d\x8d\x9d\x97"
-  "\x60\xba\x95\xea\x2e\xd7\x60\x8a\x58\xb9\x54\xa6\x61\xac\x71\x01"
-  "\x8c\x42\xd4\x66\xd8\xd0\x3b\xa7\x77\x51\xfb\xf4\x0f\x2b\xb1\x3d"
-  "\x9d\xd0\x69\xa4\xb6\x5e\x92\xb8\x42\x8e\x9d\x58\x4b\x3a\xfd\x6d"
-  "\xf4\x8d\x43\x38\x03\x84\x8f\x5d\x11\x0f\x59\xa7\x3b\xa6\xc2\x4f"
-  "\xf8\x70\xaf\xce\x97\x70\x50\xcb\xab\xf2\xd2\x6b\x7f\xe5\x2f\xd1"
-  "\x87\xcf\x7f\x28\x5f\xc8\xcc\xa6\x49\x5b\x6f\x7a\x96\x16\xd1\x66"
-  "\x9f\xb0\x49\xa2\xba\xa8\xaf\x7d\xf8\x56\x05\x7c\xc6\x60\x5e\x9c"
-  "\x89\x98\xff\x3a\xdd\x3b\x68\x27\x74\xe6\x42\x31\xee\x1c\xbe\xd5"
-  "\xbd\x12\x70\xa6\xba\x19\xad\x85\xce\x31\x62\x2e\x8a\x78\x2d\xf4"
-  "\xbd\x46\x8d\x06\x22\xda\xe7\x86\x33\x3a\xfd\x09\x29\x9b\x92\xfe"
-  "\xd2\x60\xdf\x3b\x9c\x57\x91\x6c\xa5\xf5\xde\xaa\xd2\x2c\xad\x63"
-  "\xfa\xda\x9a\xcd\x52\x60\xc7\xae\xc6\x17\xf5\x71\xe3\xcc\x16\xf8"
-  "\xef\x84\x2f\x32\xe7\x86\x3b\xa8\xbd\x51\x3f\x78\x6e\x9a\xb0\xb5"
-  "\xf2\x39\x67\x5f\x80\xee\x8c\xa7\xb7\x40\xf8\xa7\x30\x64\xd8\x83"
-  "\x5c\xd8\x63\xc3\x4e\x2b\x6e\x66\x0b\x9e\x09\x3f\xd6\xa8\xf3\x8b"
-  "\xfa\xa2\xd4\x45\x2d\x51\x69\x13\xd8\xee\x5e\x73\x46\x17\x25\x64"
-  "\x93\x74\x3f\xed\x8c\x2e\xfa\x55\x19\xaf\x4b\xfa\x55\x56\x75\x00"
-  "\x27\x4a\x1b\x4e\x2f\x13\x3e\x1b\x75\xd1\xb7\x59\x6e\x65\xcc\xa3"
-  "\x8b\xbe\x5d\xf8\x36\x2d\xed\xd2\xf4\x89\x8e\x57\xc9\x76\x99\xb2"
-  "\xec\x7a\xd1\x46\xb4\x6f\x9c\x6d\x0b\xa8\x7b\xd7\x44\x7f\x49\xf4"
-  "\x3c\xcd\xf6\x53\xf4\x5f\xf5\x79\xea\xbc\xe9\x02\xda\xb0\x57\xdd"
-  "\xaf\xdc\xea\xb7\xdd\x7f\xfd\xb7\xa3\xf3\xd4\x3a\x0f\x09\xbf\xaf"
-  "\x04\x17\xaa\xf7\x10\xb5\xa3\x59\xdb\x43\x55\xbd\xf5\x59\x62\x6f"
-  "\x2f\x89\x3e\x3e\xbc\x7f\xaa\x30\x1c\x11\xa3\x68\xf5\xea\x3c\x0b"
-  "\x11\xe0\xb6\xa5\x79\x8f\xe5\x58\x96\xe7\xe6\xae\xce\xb5\xc0\xc1"
-  "\x41\xe4\x1a\x13\xba\x29\x25\xd1\x5e\x35\xd6\x4c\xc3\x70\xac\x99"
-  "\x92\x09\xa9\x91\x31\x91\xdc\xba\x09\x63\xfa\x34\x1b\x5f\x1f\x27"
-  "\x8c\x19\x2b\xb9\x5a\xaf\x34\xd2\xaf\x89\x7e\x4e\xfa\x09\x5f\xd8"
-  "\x59\x01\x96\x46\xfb\xa3\xb0\xd3\xd4\x7c\x62\x2b\x25\x13\x12\x70"
-  "\x3e\xdd\xad\x9b\xf0\x4a\x9d\x12\xcd\x84\x3d\xbb\x43\x81\x8e\x07"
-  "\x7c\xf4\x36\xd1\xcf\x49\xbf\x16\xfa\x49\x9f\x2f\xbf\x15\x76\x7f"
-  "\x8d\x91\xcf\x70\x66\xcc\x1d\x35\xf0\xf5\xdb\xc1\x37\x45\x8b\x33"
-  "\x06\xe5\x59\x59\xee\xb2\x36\xe8\x89\x8f\x4d\x55\xcb\x89\xfd\x34"
-  "\x7e\x13\xb3\x8c\x52\x2e\x8a\x3b\x2e\x6d\x53\xcb\x09\xbf\xb6\x5a"
-  "\x7f\xe0\x3f\x9a\xca\x6b\xe5\xa2\x79\x89\xde\xa7\x96\x13\x74\xa5"
-  "\xe2\xd0\x8f\xf6\xdd\x09\xdc\x71\x54\xfb\x6e\x42\x64\x7d\x11\x65"
-  "\x26\x2a\x0e\x6f\x00\x65\x94\x4d\xd1\x82\x7e\xe3\x25\x13\x32\xa9"
-  "\xfc\xa8\x7e\xf7\xc6\x37\x4e\x93\xd8\xe5\xe3\x64\x7b\x6c\xc5\xf2"
-  "\xbb\x56\xac\xca\x47\x54\x92\xbc\xd5\x6b\xf3\x70\x5d\xb5\xf4\x7b"
-  "\xe2\xb2\x3a\xeb\xf1\xc7\xe4\x4d\xde\xca\x14\xdc\xac\xa4\xf9\x86"
-  "\xeb\xb2\xb5\x36\x5c\x1e\x5b\x8d\xa4\x3d\x67\xd6\xda\xc7\xb4\x30"
-  "\xaa\x91\xf3\xd0\xea\x2f\x99\x44\xfb\xc7\x04\x71\x16\x47\xf7\x87"
-  "\x88\x9f\x15\x71\x6f\x4c\x9b\xdc\xec\x4d\x6b\x90\x69\x3c\xac\x1c"
-  "\xff\x49\x4c\xf8\xc8\xd3\x4d\x7a\xa3\x4e\x99\x64\x30\x6d\xb2\x3d"
-  "\x66\x0a\xae\x58\x4e\x78\xb6\x85\xde\xf5\xba\x59\x89\x1a\x47\xa4"
-  "\xcb\x23\xfc\xc1\x95\x4c\x4a\xd3\xf4\xfe\x94\xd2\xae\x7a\xf8\x64"
-  "\x16\x7a\x40\xcf\x0a\x1f\x08\xad\x94\xee\xa3\x34\xe2\x2c\x24\x52"
-  "\xba\x81\xd2\x5e\x4a\x9b\x29\x9d\xa4\x94\x1e\x4d\x85\xad\x14\xa5"
-  "\x2d\x94\x4e\xf6\x97\x18\x16\x6b\xeb\x22\x12\x36\x6a\x90\x9f\xbb"
-  "\x46\xe5\x77\x47\xfa\x14\xa1\xb5\x65\xd8\xa6\xc5\x52\x14\x71\x13"
-  "\x4b\x0c\xc3\xe7\x7f\x32\x2e\x49\xc2\x12\xb1\xaf\x89\xbd\x3d\xe6"
-  "\xc6\x28\xf3\x75\xb1\x82\xf6\x2e\x31\xb4\x6a\x67\xb4\x82\xb6\x2e"
-  "\x31\x1c\x8f\x88\x39\x89\xb4\x67\x38\xe6\xa4\xa4\x45\x77\x08\x5a"
-  "\x54\x17\x33\x97\x97\x18\x96\x0c\xc7\x05\x2a\x89\x19\x71\xfe\xeb"
-  "\xa6\xe7\xe0\x69\x28\x7f\x56\x78\x1f\x34\x20\x6e\x7a\xd4\x68\xf1"
-  "\x35\x11\xd3\x3b\x6b\x3d\xd1\xdf\x74\x55\x69\x71\x8b\xe0\xb5\x1c"
-  "\xf0\xfb\xc7\x1b\x46\x95\x1b\x5c\x2f\xfa\xf2\x2a\xfc\x3d\x7a\x8b"
-  "\x96\xe9\x66\xd6\x31\x9d\x48\x4b\x5f\x5f\xfc\x9c\x2e\x46\xd8\x0f"
-  "\x6a\x7e\x80\x22\x6d\x72\x47\xb5\x01\x78\x9f\x31\x19\xbf\x62\xe5"
-  "\x6a\x53\x70\xe9\x72\x49\xbb\xc5\x5e\xab\x9e\xff\x96\xcb\x3d\x3e"
-  "\x36\x9a\x3f\x28\xfd\xed\xbb\x75\xb1\xa5\x88\xe3\x61\xd2\xad\x5c"
-  "\xcd\xe9\x5d\x93\x7d\xe9\x72\x91\x47\xe5\x36\x23\x2e\xb3\x6c\xdf"
-  "\x69\x57\x52\x1f\xe3\x03\x21\x69\x6b\xac\x8b\xe9\x7b\x74\x46\x31"
-  "\xbe\x63\x10\xb4\xc3\xfb\xcc\x88\xb8\x4c\x68\x5b\x5d\x84\x9f\xa2"
-  "\x2a\xca\x83\x6e\x54\xff\x83\xcc\x08\x7f\x8d\xb2\x2d\x31\x7d\x22"
-  "\xfe\x4d\x49\x6c\xb1\xe6\x4b\x81\xe0\xdc\x77\x79\x7f\x1e\xfc\x17"
-  "\xb1\x2a\x6e\x7e\x6c\xd6\xe2\xfb\xe8\x6e\x96\x1a\x72\x30\x72\xbe"
-  "\x24\xf5\xc7\x76\x37\xf5\xbf\x54\xec\x17\x71\xb3\x4a\x62\x3b\xa8"
-  "\x9e\x3c\x31\xc6\x9b\xbf\x7d\x1a\xf8\x44\xf8\x62\x08\x31\xb3\xb0"
-  "\x7f\x52\x7c\x22\x36\x59\xaf\x2e\x6e\x3b\x7c\x26\x0a\x5f\x44\x25"
-  "\xb1\xdb\x30\xee\x34\x56\x62\x8f\x57\xca\xba\xca\xb1\x16\x30\xbf"
-  "\x94\xad\x27\xb2\x5d\x09\xe8\xfb\x64\x2b\xe1\xd1\x05\xf4\xfb\xdf"
-  "\x32\x3e\xc1\xb7\x4f\x6b\x75\xc2\x57\x08\xcd\xa7\x16\xba\x26\xf8"
-  "\x4b\x26\x0f\xcf\xff\x61\xbb\x31\xdd\xe4\xa7\xe0\xcf\x04\xfe\x1a"
-  "\x24\xdd\x1a\xf7\x7d\x49\x4b\x4e\x2e\x70\x33\xd3\x42\xb9\xa6\x27"
-  "\x13\xbf\x52\x5f\xaf\xde\xd3\xfc\x9f\x5d\x7b\x59\x1d\x7f\xd4\xe4"
-  "\x15\x72\xde\x4f\x6e\xa2\xf9\xb7\x80\x7e\xff\x9b\xca\x37\x6b\x71"
-  "\x49\x37\xeb\x85\x8d\x4f\x6f\x94\x99\xa5\x50\xfe\x71\x2d\x7f\x82"
-  "\x2e\x8d\x60\x33\xd9\xa3\xe1\x90\xfe\x58\x77\x1e\xa5\x09\xe6\xac"
-  "\x58\x4d\x17\xfb\x4b\x8c\x46\x2d\x4d\xf7\x66\x0d\xc7\xd0\x3d\xd1"
-  "\x7f\xbb\xfb\xd4\xfb\x14\x37\xfb\x91\x96\x3f\xcf\xad\xdf\xd7\xa8"
-  "\xb5\x53\x71\x44\x99\x64\x5b\xe3\x6c\x4a\x85\xd1\x86\xd8\xaf\x54"
-  "\x26\x9b\xd6\x8a\xf4\x1d\x90\xef\xa9\x2f\x1f\x4c\x78\x08\x71\xdb"
-  "\x9d\x8f\x63\x0e\xc4\x09\xff\x61\x15\x1b\x12\x16\x83\x7e\x83\x7d"
-  "\xb3\x88\xe3\x03\xff\x5f\x41\x36\x51\xf8\x8d\xae\x30\x66\x0b\x7f"
-  "\xc9\xeb\xac\x46\xcd\xf7\x17\xad\xb9\x34\xae\x2f\x0f\xc2\x1f\x98"
-  "\x90\x73\xf9\xad\xf1\xc2\x07\x98\xea\xfb\x6b\x57\x3e\x4b\xac\x55"
-  "\xa4\xef\x2f\x61\xfb\x3c\x91\x68\xfd\xfc\xd1\xfd\x7f\x71\xc7\x6b"
-  "\x01\xcd\xff\x17\x62\x3d\xd3\xbd\x95\x0f\x04\x91\x27\xfc\xf3\xab"
-  "\x7e\x5f\xa3\x47\xf5\x05\xa6\x27\x1c\xa8\x97\xbe\xc0\xc6\xb7\x77"
-  "\xc4\xcd\x93\xe3\x1f\x57\xa0\xc5\x43\x8d\xc8\xab\xa6\xf9\x2b\xf5"
-  "\x4c\x74\x93\x6d\x6a\x1e\xe1\xbf\xdd\x0f\x0d\xd3\x59\x84\xbb\x20"
-  "\xef\xa3\xf5\xe9\xe3\x45\x39\xdb\x23\xd7\x8b\xd0\x06\x60\xd8\x86"
-  "\x27\xd0\x1e\x3b\x91\x7e\x93\xf0\x4b\x1f\xc6\x0b\x03\xbc\x53\x8d"
-  "\xdb\x17\x34\xd9\xa3\x78\x46\x30\x18\x95\x15\xd4\x1d\x13\xb1\x09"
-  "\x43\x4c\x9f\x11\x0a\xc2\xa6\x38\x3a\x38\xc0\x8f\x65\x84\xfa\x79"
-  "\xd5\xe3\x88\x2f\x06\x5f\xa6\x37\xf0\xac\x50\xb5\x88\xd5\xa7\xe4"
-  "\xf3\x0e\xd0\xf8\xa1\x01\xde\x1a\xca\xe7\x2d\x34\x06\x46\xf0\x0f"
-  "\xf0\xb5\x12\xaf\x0b\xb0\x78\x5b\xd4\xeb\x0f\x5c\x7c\x9d\xc3\xcf"
-  "\x0a\xe2\xde\x28\x25\x01\xf8\x7d\xd1\x65\x05\xa3\x8a\x5d\xc1\x1e"
-  "\xe1\x73\x3a\xc3\x3e\x9f\x67\x84\x26\x71\xc2\x93\x51\x22\x66\x4d"
-  "\x3e\x6f\xce\x58\xcf\xfb\x45\x3c\xb3\xf5\x44\x57\xaf\xef\xe7\x88"
-  "\x8f\x46\x75\xb7\x64\xd9\x6f\x42\x3c\xb4\xc1\x0c\xbb\x52\x94\x65"
-  "\xd7\x51\x5b\x3e\xe1\x19\xf6\x4f\xa8\x3d\x29\x54\x6f\x02\xa5\xe7"
-  "\xf3\xdd\xa2\x9d\xc5\x82\x8f\xa1\x3e\x3a\xab\x64\x3b\x9b\xa8\x8d"
-  "\x87\xe0\x0b\x36\x2b\xe8\x2c\x16\xf1\xd7\xd4\x18\xc9\x19\xf6\x21"
-  "\x8e\xef\xd1\xb7\x52\x33\xd6\xb3\xf9\x59\xeb\x6f\x28\x16\xfc\xe0"
-  "\x39\xf8\xac\xb1\xd0\x77\x8b\x01\x0f\x23\x62\x14\x0a\x9b\xa5\x12"
-  "\x93\xf5\x4a\xb1\xd5\x80\x63\xd6\x5c\xcb\xf4\xe0\xf5\x43\x75\x36"
-  "\x1b\x7c\xbf\x14\x79\x79\x00\x32\xb9\xd7\x07\x3b\xf5\x96\xfc\x68"
-  "\xc2\x97\xa6\xfb\xdb\x6d\x29\xa3\xdb\xac\x95\x7c\x9a\xc3\x2b\x5e"
-  "\x24\xda\xe7\x5c\x2a\x5d\xb7\xf0\xd2\x13\xc0\xd1\x44\xaf\x7c\x66"
-  "\xe0\x15\x2f\x51\x7e\x7f\x27\x5d\xb7\xf0\x92\x81\x06\x5e\xf1\x53"
-  "\x4a\x5f\xb2\xd3\x95\xd2\xc7\xd2\xa8\x3c\xe3\x25\x1f\xe0\xbd\x62"
-  "\x5e\xf2\xfb\x14\x2a\x47\xe9\x3f\x58\xe9\x4a\xe9\x4e\x0b\x95\xa3"
-  "\xf4\x87\xe6\x5e\x5d\x82\x99\xee\x29\x2f\x98\x2e\xbf\xc5\xd3\xc5"
-  "\xb7\xca\xf4\xe9\xe2\x1b\x65\x13\xd2\xc5\x37\xca\x0c\xe9\xe2\x1b"
-  "\x65\x93\xd3\xe5\x37\xba\x12\xa8\x1c\xb5\xf1\xa3\x62\xba\x96\xf2"
-  "\x92\xe3\x5e\x2a\x47\xe9\x3f\x65\xd3\x95\xd2\x1f\x77\x50\x39\x4a"
-  "\x9f\xa0\xb6\xfc\x94\xd2\xdd\x8d\x54\xce\xc8\x4b\x7a\x92\xe9\x5a"
-  "\xce\x4b\x4e\xd6\x50\x39\x4a\x9f\x32\xd2\x95\xd2\x7d\x54\xcf\x4f"
-  "\x29\x7d\xda\x47\xd7\x72\x5e\x16\x8f\x76\x24\xf0\x32\x13\xd5\xfb"
-  "\x62\x35\x2f\x9b\x82\xf2\x94\xbe\x8a\xea\x7b\x89\xd2\x89\x7d\x54"
-  "\x8e\xd2\xd3\xaa\xe9\x4a\x69\x33\xfa\x9a\xc8\xcb\xae\xed\xa1\xeb"
-  "\x36\x5e\x76\x1d\xe5\xbf\x44\xe9\x19\xf3\xe8\x4a\xe9\xeb\x51\x9e"
-  "\xd2\x96\x6d\x74\xa5\xf4\x4d\x80\x91\x99\x97\x25\xd7\xd3\xb5\x86"
-  "\x97\x7d\x99\x51\x39\x4a\xdf\x82\xf6\x53\xfa\x2b\x4e\x2a\x47\xe9"
-  "\xd9\x80\x15\xa5\x53\xd0\xcf\x24\x5e\x76\x07\xea\xaf\xe5\x65\x5f"
-  "\x05\x5c\x28\xfd\xf7\xfb\xe8\x4a\xe9\xbb\x08\x1e\x3f\xa5\xf4\xbc"
-  "\x3c\xba\xd6\x8e\x3a\x9e\x65\xf3\x17\xf1\x4d\x13\x19\x2f\x4b\x2f"
-  "\xe5\x9b\x26\xd1\xf5\x1b\xa9\x7c\xd3\x04\x2b\x2f\xbb\xbf\x86\xf2"
-  "\xe9\xfa\xcf\x09\x94\x9e\xa5\xa6\xe9\xfa\xcf\x7d\x94\x4e\x51\xd3"
-  "\x74\x5d\xe4\xa4\xf4\x5c\x35\x4d\xd7\x8c\x74\x4a\xa7\xf2\xb2\xc5"
-  "\x16\x4a\xd3\x35\xe3\x10\xa5\xe7\xa9\x69\xba\x7e\xb3\x87\xae\x41"
-  "\xef\x8c\xd5\x2d\xde\xb8\xbc\x62\x6f\x5c\x83\xd0\x33\x0a\x55\xbe"
-  "\xc8\x94\xf8\x17\x8b\x69\xdf\x99\x58\x74\x91\x4d\xea\xd5\x4d\x3d"
-  "\x09\x5a\xd1\x55\xe0\x16\xf1\x92\x54\x5f\x44\x13\xbb\x75\x53\x4e"
-  "\xd0\x5e\x9f\x8a\x78\xb8\xd4\xe7\x79\xdc\x31\xe1\x02\x5d\x0f\x73"
-  "\xc7\xe4\x6e\xea\x33\xa5\xa7\xbc\x4f\x57\x4a\xff\x5d\x19\xf5\x99"
-  "\xd2\xdf\xbe\x97\xae\x87\xfd\x25\x53\xd3\xdc\x3a\x93\xdc\x6f\x5f"
-  "\x2a\xf6\x9a\x82\x45\x84\x53\x08\xe7\x6e\x3f\xd8\x68\x0a\x66\x13"
-  "\x9c\xf7\x56\x9b\xe0\xcf\x7c\x97\xcd\xc0\xe3\xf3\x44\x9b\x10\xb3"
-  "\x80\x0f\x25\xeb\xe5\xb7\x27\xf3\x6e\xdd\xd4\x27\x21\xbb\xe4\xf1"
-  "\xe5\x63\x3d\xaf\x10\xcf\xa7\x1f\x74\xca\xe7\x06\x16\x7e\xfe\x6d"
-  "\x3c\xdf\x6f\x82\xbc\xf9\xfa\xef\x8a\xe7\x2e\x5f\x9f\xda\xaf\x28"
-  "\x3c\x7b\x07\x65\xdd\xba\xa9\x1e\x29\x8b\x9a\x42\x7c\x6a\x14\xeb"
-  "\x37\x9c\x28\xa0\xb6\x13\x8e\x35\xcd\x55\x69\xe1\x7a\x6e\xe8\xda"
-  "\x23\xed\xaa\x4f\x8e\xba\x46\xc1\x0b\x2a\xe5\xfb\xfb\x2a\x1c\xbc"
-  "\x03\xfc\x25\xed\x23\x7a\x4b\x61\x72\x53\xb7\x2e\x11\x7a\x2f\x3e"
-  "\x6e\x3c\x58\x0a\x7b\x9c\x6e\xdd\x55\x15\x43\x65\x27\x1a\x11\xcb"
-  "\x9c\x9e\xbd\x53\x14\xe0\x17\x9d\x85\xf7\xd2\x7e\x27\xf2\x3d\x42"
-  "\xc7\x5b\xde\x77\x0a\xfd\x1e\x79\xdf\x2c\x64\xa0\x54\x17\xde\x8d"
-  "\xa4\xe7\x43\x25\x77\xef\x53\xe2\x0f\x56\x8b\xf3\x28\xdd\x55\x3f"
-  "\xf8\x8d\xe2\xd6\x9b\xf2\xd8\x04\xcb\x86\xd7\xa9\xfe\xab\x3a\x47"
-  "\xf2\x7e\x5a\x59\xf1\xec\x37\xaf\x51\xd9\x9d\x42\x4e\x73\x55\x9f"
-  "\x26\xd7\xe5\xd4\x87\x67\xe0\x2f\x5a\xcf\xd2\xb0\xb7\x49\x5a\x2e"
-  "\x31\x07\x7e\xce\x82\xc6\xbd\xb6\x60\x79\x9e\x2d\x54\x7e\xb0\x94"
-  "\x57\x1e\xac\x8e\x0f\xea\x98\xd0\x8f\xd7\x25\xee\x9a\x13\x80\xfc"
-  "\xec\x5d\x94\x7d\x58\x99\xf8\x4f\x2b\x67\xdb\x99\xde\x99\xdb\x85"
-  "\xf4\xf3\xbc\xe4\xfe\x44\x97\xa7\x93\xc1\x6f\x23\xa5\xb7\xf1\x92"
-  "\xcc\x80\x32\xf1\xc1\x8e\x3a\xd0\xa0\x76\xc8\x7d\xde\x47\xfe\xb5"
-  "\x34\x2e\x44\xdf\x27\xe6\x45\xc4\x6e\xef\xa8\x20\xd8\x81\x3e\x84"
-  "\x2d\x73\x56\x28\x04\x7f\x33\xa5\x6e\x82\x83\x1c\xaf\xc4\x4c\xe0"
-  "\x6d\xf5\xbb\xfb\x95\xd8\x13\xb5\xf0\x40\x63\x0a\x1a\xe0\xbf\xe3"
-  "\xa2\xb0\x7f\x0c\x22\x6e\x14\xf6\x4b\x59\x76\x84\xaf\xca\xc7\x6c"
-  "\x59\x1b\x6c\xab\x73\xf3\xb2\xd6\xda\xee\xb2\x20\x86\xf5\xea\xc7"
-  "\x2d\x4f\x2e\x7f\x72\x75\xee\xfa\xcb\xe9\x48\x83\xbf\xe4\x6a\xa2"
-  "\x7f\xae\x32\xa3\x5d\xef\x10\x6d\x2a\xe4\xc9\xba\x69\xc7\x31\xd6"
-  "\xdb\x5f\x90\x3e\xbf\xa9\x0c\xd1\x3f\xff\x2e\x7c\x0c\x28\x35\x07"
-  "\x1b\x78\xad\xcd\xb0\x15\x36\xdc\x6b\x41\xff\x7b\x99\x8b\x5d\xa0"
-  "\xb6\xc9\x98\x55\xed\x41\xa2\x95\xf3\x0b\xb8\x33\xff\x02\xd6\x41"
-  "\x29\xaf\x68\xa8\xa1\x75\xb0\xf8\x52\x45\x5e\x5f\xb7\x6e\x9a\xf3"
-  "\x52\x45\x43\xa9\x16\x4f\x22\x54\xde\xd0\xa7\x18\x0f\x88\x78\x12"
-  "\x43\xdc\xcc\xda\x08\x96\x83\xa5\x27\x4a\x69\x1f\xd8\xb2\xcb\x41"
-  "\xfb\x18\xf1\x0e\xc2\x57\xc1\x4b\xc5\x1d\x21\x6e\x8d\x0e\x39\x98"
-  "\x81\xae\xf1\x3c\xfe\x60\xca\x90\x71\x6f\x31\x9e\x23\x8e\x44\x68"
-  "\xc8\xca\x0a\x8f\x71\xe5\xdf\x72\x68\xde\x38\x18\x17\x71\x00\x73"
-  "\xce\x32\xca\x8f\x55\x2a\xf7\x26\xf4\xa6\x33\x3d\xca\x12\x9d\xc4"
-  "\x96\xd0\x7d\xc1\x52\x16\x47\xe5\x4c\x05\xef\x50\xbe\xdf\x1a\x1b"
-  "\x2c\xb2\x1a\x06\x8b\xac\xb1\x43\xdc\x6a\x74\xf5\x04\xd8\xd0\xcd"
-  "\xc5\xee\xdb\xbc\x2c\x7a\x3b\xd1\x53\xbb\x14\x5a\x83\xb5\xab\xbd"
-  "\xa1\xa7\xad\x13\x83\x4f\x5b\xa3\x87\x86\xac\x86\xe0\x3a\x6b\xf4"
-  "\xe0\x3a\xeb\xc4\x21\xbf\xd5\xe0\x5a\xe6\x65\xef\x7a\x7f\xc6\xda"
-  "\x7b\xfa\x84\xcc\x71\x28\xee\xe0\xbc\xa1\xb8\xbd\x49\xc6\x1e\x96"
-  "\x38\xdb\xc6\x40\x3f\xeb\x76\x10\xad\x4c\x73\xc2\x18\x7c\xb1\x98"
-  "\xf6\x8c\x03\x6e\x82\xef\x8b\xf7\xdd\xc2\xcf\x87\x4a\x92\xec\x96"
-  "\x6f\x10\xbe\xda\x14\x9d\x44\x79\x34\x7f\xac\x7d\xbc\xe4\xe6\x14"
-  "\xe2\xd5\x09\xbf\x45\x27\xbb\xe5\x38\xd0\x3e\x76\xdd\x2c\x4a\x27"
-  "\xa1\xac\x2c\x77\x63\x81\x5b\x5c\x67\xb4\x8a\x58\x7b\x25\x89\xc7"
-  "\x76\x09\x1e\x6e\x5a\xa7\x46\x87\x37\x47\x8f\x6e\x27\x4e\x65\x82"
-  "\xc3\xbc\xb0\x42\x38\xa7\x62\xcf\xa8\xbe\x57\x79\xd9\x87\xfb\x70"
-  "\xfe\xa8\x10\xdc\x7a\x75\xd7\x3c\x09\x9f\x36\xbc\x28\x5d\xe5\x3f"
-  "\xaf\x49\xc3\x3c\x85\x6d\x35\x64\x14\x6a\x9e\x3c\xe3\xd7\xa7\xc1"
-  "\xef\x72\x13\xfc\x08\x41\x26\x41\xf3\xba\xc5\xad\xbb\xa6\x18\xb1"
-  "\x8e\x89\x8f\x6b\xa4\x5f\x13\xfd\x9c\xcf\x41\x56\xe1\x60\xf7\x69"
-  "\x72\x9c\xd1\xdb\x7a\x4d\x83\x9b\x95\x56\x87\x79\xd9\x6b\x9a\xa8"
-  "\xae\x84\x71\xeb\xf2\xe9\xae\x19\xd3\x57\xac\xf0\x5b\x07\x18\x57"
-  "\xbe\x68\xa9\x56\x86\x7d\x15\xd2\xde\x60\x8e\x43\x5c\x71\xf1\xac"
-  "\x7c\x6f\x75\xe1\x67\x2c\x0a\xcf\x1a\xa1\xab\x40\x69\x4b\xae\x8e"
-  "\xbb\x7c\x01\x46\xef\x44\xf3\x24\x9b\xa1\x71\xc0\xab\xc7\xba\x68"
-  "\xa7\x3c\x7a\xf7\xe6\xea\x01\xb5\xde\x9a\x83\x8d\x45\x4f\x31\xe1"
-  "\x5f\x1e\xf1\x34\xb0\x5e\xaa\x0b\x89\x67\x44\xec\x8f\x5c\xe0\x6a"
-  "\xf3\x52\xba\x37\xa0\x1c\x37\xee\xad\x56\xa8\x0e\x5a\x33\x01\x1e"
-  "\xb7\xd7\xae\x54\xec\xa5\x3d\x64\xb5\x93\xcf\xb0\xe5\x28\xdb\x0f"
-  "\xd6\xf8\x4b\xcc\xd4\xff\x69\x82\x27\x81\xbf\x12\xc8\x41\x42\xc4"
-  "\x8f\xb7\x37\x04\x19\xbf\x37\xc8\xde\xcc\xbb\xc8\xbc\x31\x27\xca"
-  "\xbd\x71\xfb\xfb\xbc\x71\x07\xdc\xa1\xb8\x03\x29\xf4\x9b\x6b\xcb"
-  "\x65\xc6\x33\xba\x6b\x0b\x42\x0e\xe9\x6b\x38\xe3\x33\xee\x17\xfa"
-  "\x93\x0e\xf8\x06\x93\x7e\x8f\x84\xcf\x61\x35\xd6\x08\xd5\x99\x2c"
-  "\x62\x8c\x10\x8f\x11\x5a\x47\xbc\xc5\x00\xad\x83\x01\x66\xd6\xe2"
-  "\x47\xec\x52\xfd\x0a\x57\xe6\x87\xf9\x0a\x95\x67\x48\xc4\x7d\x48"
-  "\xff\x4b\xeb\x2e\xf8\x49\x02\x6e\x86\x9f\x24\xf0\x0f\x6b\xac\xf0"
-  "\x43\x18\xf6\x93\xe4\xb7\xea\x89\x66\xed\x20\x7a\x55\xd0\xad\xc2"
-  "\x77\xa1\xd0\x01\x67\xc6\x50\xdc\xde\x1c\xe0\xb4\x2c\xbb\x53\xf8"
-  "\x2e\x04\xed\x8a\xbd\xc6\x5f\x72\x6d\x93\x46\x8f\x02\x7f\x86\xb6"
-  "\x9e\xa8\xa1\xdf\x36\xca\x27\xfe\xf7\x36\x83\x86\x5b\x69\xcf\xad"
-  "\x0f\xc5\x7e\x7b\x9f\x1f\x7a\xfd\x43\x39\xf3\x51\x96\xe0\xd8\x81"
-  "\xf8\xef\xa1\xa1\x9c\x79\xf4\xbb\x9b\x7e\xf7\x84\x2a\x1a\xaa\x43"
-  "\x15\x07\x9c\xa1\x8a\xbc\x3d\xf4\x6b\xa0\xdf\x3e\xfa\x35\xd2\xef"
-  "\x10\xfd\x9a\x78\x45\xde\x61\xba\xe2\x79\x33\xfd\x5a\xe8\xd7\x4a"
-  "\xbf\x0e\xfa\x1d\x0b\x6d\x3f\x58\x1f\xd2\x45\x27\xd1\x2f\x99\x7e"
-  "\x16\xaa\xc7\x1a\xaa\xd8\x1f\x08\x55\xec\xb5\x09\x7b\xcb\x92\xe9"
-  "\xcb\xb4\xb9\x3a\xba\xdf\xea\xc9\x76\xe1\x1b\x7b\xc2\xc7\xdc\x84"
-  "\x18\x94\x05\x17\xe1\x77\xcb\xfe\xa6\xd5\x37\x3e\x1f\xe9\xba\xe9"
-  "\xdb\xc6\x9a\xdb\xa8\x9f\xf0\xcc\xd0\x38\xeb\x1b\x33\xfe\x85\x62"
-  "\x3e\xd8\x10\x4c\xb2\x2d\x0e\x3a\x58\x31\xe1\x36\x5d\x7b\x76\x0f"
-  "\xcb\xf0\xb2\xa2\xd6\x9e\x41\x56\xb4\x8c\x87\x04\x1e\x28\x80\x9e"
-  "\x76\x79\x10\xf3\x3c\xc4\x33\x2d\x43\xe5\x0d\x35\x21\xe3\x7e\x27"
-  "\x37\xee\x0f\x08\x5f\x5e\x84\x4f\x10\x4f\x67\x98\xaf\xc5\xbc\x23"
-  "\xde\xb6\xcd\x73\x91\x3d\xbd\x8c\x2b\x6d\x39\x44\xa3\x75\xd2\xe4"
-  "\xd3\xb1\x1f\x89\xf9\xa7\xf2\xb6\xff\x7c\x9c\x17\xd3\x7c\x8a\x09"
-  "\x11\xdc\x14\xf0\xb4\x34\xf7\xc0\xdf\x6a\xf3\x8f\xf6\xf5\x04\x2d"
-  "\x06\x09\x9f\x38\xdd\x4e\xcf\xa2\x11\xa3\xa4\x96\x78\xdb\xda\x7c"
-  "\x96\x5c\x4b\xcf\x44\x3c\x39\x6a\xf7\x03\x36\x13\x57\xbe\x67\x65"
-  "\x75\x4f\x30\x43\xdc\x59\x19\xa3\x30\x44\xb0\x0f\xfb\xb8\xce\xeb"
-  "\xbb\xff\xac\x85\xbd\x69\xfd\x23\xed\xcf\x8d\x34\x2e\x79\x7d\x43"
-  "\xb4\x87\x11\x2c\x43\xe3\x83\x65\x52\xca\x7f\x15\x2c\x87\x92\x56"
-  "\x7b\x25\x3c\xb3\x19\x60\x76\x39\x3c\x01\xe3\x0d\x3d\x04\x4f\x82"
-  "\xab\xeb\x58\x88\x78\x54\xb6\x54\x83\xe7\x4e\x82\x27\xc1\xd4\x0c"
-  "\x98\x12\x3c\x04\x4c\xb9\x0a\xd3\xba\x08\x98\x12\xfe\x12\x7e\xcf"
-  "\x00\x53\x85\x60\x5a\x37\x06\x4c\x87\x65\x04\x04\xd3\xdd\x9f\x0b"
-  "\xa6\x0d\x7f\x05\x4c\x67\x6c\x19\x0b\xa6\x41\xd0\x0e\x95\x79\x6e"
-  "\x4e\xb8\xd1\x15\x7c\x57\xf8\xf0\xe3\xe5\x07\xe6\x2a\xe5\x07\x52"
-  "\x14\x63\x43\x1f\x62\xcf\xe2\xac\x1e\x31\x71\x8a\xec\xfc\x44\x51"
-  "\x03\xbf\x14\xaa\x3c\x98\x86\x3c\xc2\x6d\x39\x73\xa0\xff\x63\x73"
-  "\xd3\xfe\xc5\x9b\xda\x07\x7c\xb4\xa7\x59\x7e\x33\x08\xda\xbb\xf2"
-  "\x60\x91\xc2\x73\x18\xf0\xca\xa3\xb7\xb0\xe8\x41\xc2\x1d\xb6\x7c"
-  "\x76\x43\x35\xe1\xc3\xc1\x8a\x03\x73\xcf\xe8\xae\xcf\xbc\xcf\xa6"
-  "\x70\xfa\x15\xc1\x17\x9d\x42\x78\x97\xf0\xb9\x18\x5f\x8c\x19\xce"
-  "\x00\xdb\x1e\xfd\x2d\xd5\x77\xc3\xd7\x8f\x66\x07\x59\x51\xce\x9f"
-  "\x8f\xaf\x52\x94\x69\x09\x95\xff\xe5\x75\x82\xb8\x5c\x05\x7d\x18"
-  "\xd7\x46\xe6\xea\x09\xaf\x13\x45\xc5\xd3\x18\x0b\xac\x0b\xac\x91"
-  "\xaa\x08\xfc\x4c\xb8\x3f\x61\x97\xea\xe3\x3d\xe4\x20\xfc\x0c\x3f"
-  "\xc0\x34\x96\xf0\xfd\x3e\xea\xfa\x78\x9a\xd6\xc7\x06\x11\x97\xc3"
-  "\x4c\xf0\x68\x1c\xf4\xcb\x31\xc4\x98\xb9\x82\x2d\x62\xfc\xaa\xd5"
-  "\xfd\x40\xc2\x7d\xff\x10\xe7\x99\x44\xd3\x4d\xb1\x2b\x95\x07\x53"
-  "\xb8\x3f\x27\x16\xb1\x59\x76\x9f\xa3\xf9\xb4\x8c\x68\xa8\xf3\xb4"
-  "\x5f\xac\xa2\xf9\x75\x8e\x25\xef\x5e\x45\x74\x91\x1f\xb1\x80\xa8"
-  "\x3d\xeb\x65\x0c\x45\xa5\x64\xfa\x71\x7a\x26\x7c\xeb\x29\x9a\x6f"
-  "\xbd\x7e\x2b\x64\x1b\x61\x99\xd3\x6a\xab\x3e\xfc\xcd\x53\x09\x21"
-  "\xe3\x14\xbb\xb0\x0b\xd5\x59\xa4\x3f\x67\xc3\xbb\xa9\x80\xab\x47"
-  "\x67\x59\x28\x65\xbe\xae\x79\xb6\x42\x36\xe9\x8c\xee\x86\x4b\xbc"
-  "\xec\x0f\x29\x36\xc4\x85\xd5\x9e\x15\x65\x02\x0e\x96\xd9\xc5\xac"
-  "\x38\x54\x31\xa5\x06\xf1\x82\x79\x51\xce\x38\x71\xaf\x45\x9c\xc1"
-  "\x84\x4a\x4f\x25\x12\x9c\xd2\x94\xb2\x53\x49\x84\x53\x52\xf8\xf7"
-  "\xa8\xaf\x4f\x50\x5f\xcf\x10\x5c\xcf\x50\x5f\xd7\xa9\x7d\x55\xe3"
-  "\x23\x29\x04\x7f\x7a\x36\xfa\xfe\xa8\xf5\xf5\x7b\x04\xef\xd2\xb7"
-  "\x0d\x1b\xcf\xb2\xab\x38\xd1\xe4\x6d\x1e\x61\xdb\xe3\x77\x05\xff"
-  "\xc8\xf0\x5d\xb1\x7f\x97\xe7\x35\x3d\x4c\xf3\x11\x30\x27\x5a\xdb"
-  "\xc2\xe3\xf7\x26\x68\xe3\x80\xf6\xf0\xa1\x9c\xd8\xba\x55\xd4\x1e"
-  "\xc0\xfe\x1c\x9b\x85\xf5\x4c\xb0\x4f\xae\x03\xfc\x47\xc6\x28\x4d"
-  "\x14\x63\x30\x91\xc6\x60\x95\x3a\x06\x15\xea\x18\x10\xcd\x4c\x7b"
-  "\x31\x64\x3d\xe6\x3a\x87\x1c\x83\xf1\xc1\xe8\xc6\xb9\x7f\xe3\xf5"
-  "\xba\x70\xec\xf5\x9a\xfc\xd4\xa0\xe4\xa5\x75\xf0\xf1\x47\x7c\xc2"
-  "\x66\x65\x88\xd6\x6d\xa5\xba\x6e\x79\xce\x3d\xda\x9a\xed\xd5\xdd"
-  "\x14\xf7\xf9\xd6\xec\x4d\xa1\xff\x4b\xd7\x6c\xe2\x7f\xed\x9a\x9d"
-  "\xf9\xe6\xc8\x35\x3b\x33\x30\x72\xcd\xce\xdc\x1f\x5e\xb3\xea\xb3"
-  "\xbf\xc9\x9a\x9d\xd9\xfc\xdf\xb3\x66\x67\x36\x8f\xb2\x66\x93\x3f"
-  "\xc7\x9a\x35\x8f\xb1\x66\xcd\xff\x75\x6b\x36\xf9\xcf\xce\xa4\xfe"
-  "\xeb\xf6\x58\xeb\x2d\x83\xfa\x51\xf6\xd8\xa7\x23\xf6\xd8\x38\xec"
-  "\xb1\x37\x1f\x1e\x6d\xbd\x0e\xd5\xd2\x7a\x35\xaa\xeb\xf5\xdf\x7e"
-  "\x45\xf5\x7d\xe9\x95\x77\x8f\xff\xe5\xf5\x1a\xac\x0d\xd3\x4f\x63"
-  "\xae\xd9\x1c\xac\xd9\x06\xe6\x72\x8b\x35\xbb\x54\x5b\xb3\xb5\x2a"
-  "\x3f\x74\x85\x75\x9b\x38\xd6\xba\x45\xbc\x15\xc4\x5a\xb9\xe2\xba"
-  "\x55\xe9\xa5\xa1\x19\x58\xb7\xce\xff\x61\x7b\xed\x97\x37\x8e\x5c"
-  "\xb7\x5f\x6e\x1c\xb9\x6e\xbf\xbc\x3c\xbc\x6e\xd5\x67\x7f\x93\x75"
-  "\xfb\xe5\x82\xff\x9e\x75\xfb\xe5\x82\xff\x73\xf6\x5a\x6b\xfd\xff"
-  "\x7f\x7b\xed\x57\x4e\x8a\x75\x3b\xd6\x5e\x5b\xa4\xee\xb5\x71\xd8"
-  "\x6b\x6f\x59\xff\xf9\xd6\xee\xad\x4f\xfd\x5f\xbe\x76\xff\x8b\xf7"
-  "\xdc\xaf\xfc\xc3\xc8\xb5\xfb\x95\x95\x23\xd7\xee\x57\x6e\x0c\xaf"
-  "\x5d\xf5\xd9\xdf\x64\xed\x7e\x25\xf5\xbf\x67\xed\x7e\x25\xf5\xff"
-  "\x9c\x3d\x77\xd6\x98\xf1\x2b\x2d\xd7\xb3\xe2\x6e\xdd\xac\x57\x5c"
-  "\xb5\x42\xcf\xaf\xd8\x15\xbc\x8b\x49\xdd\x94\x59\x7f\x74\x99\x53"
-  "\x99\x52\xd6\x2d\x7c\xd8\x43\x47\xe6\xb9\x08\x1d\x14\xa9\xef\x32"
-  "\x2b\xa4\xe9\xd0\xec\x56\xfd\xdc\x5f\x49\x87\x86\x97\x9e\xd8\x26"
-  "\xdf\xbb\x2d\x55\xce\x8d\x13\x35\x5a\x5a\xf8\x9b\xd2\xdd\x36\x8f"
-  "\x6f\x3d\x51\xed\x8d\x39\x51\x3d\xd6\x79\x51\xfc\x26\xce\xa1\x6f"
-  "\xd2\x7f\x7d\x71\x71\x7f\x19\x63\xd5\xe2\x2c\xe6\xb6\x3c\xea\xa3"
-  "\xd0\xef\xe8\x8f\x4f\xce\xee\x77\x2c\x66\x94\x57\xaa\xe5\x89\xd8"
-  "\xa7\x8e\x28\xae\xd0\x33\xc2\x21\x8b\x76\x17\x32\x03\xfc\x77\xce"
-  "\x1e\xc0\x5c\xbc\x0d\x38\x42\xe8\x92\xc0\xaf\x3f\xbf\xe6\x3a\x5f"
-  "\xdd\x05\x16\xdd\xbe\x45\xc8\x9f\xa1\x7b\x53\x5f\x89\xf9\x1f\x75"
-  "\x6b\x0d\xd7\x47\x33\x65\x97\x2d\x93\xc7\x1d\x48\x15\xfa\xbd\x34"
-  "\x57\x34\x7d\x1c\xc4\xc2\x51\x66\xac\x0e\x68\x3e\x24\x39\xb5\xef"
-  "\xb5\x42\xaf\x1e\xf1\x74\xeb\x72\x59\x02\xfd\x8c\xbc\xe2\x40\xaa"
-  "\xbf\x64\xb6\x45\x93\x27\x8e\xa9\xab\x8d\xf8\x8d\xd7\x99\xa3\x55"
-  "\xdd\x1f\xd8\xd0\x4a\xbd\x68\xbd\x52\x1a\xa2\x7c\xee\x28\x12\xf1"
-  "\x57\x4c\x04\x0b\xe8\xd7\x12\x9e\xd2\x2b\x75\xc5\xc5\x9b\xa7\x33"
-  "\x76\x60\x43\x9f\x1e\xfa\x20\xa1\x1f\x5e\xe7\x73\x16\xde\x21\xe2"
-  "\xa9\xc3\x47\x71\xaf\x6e\xce\x8c\x8c\xd3\x32\x56\x23\xdd\xdf\x82"
-  "\x33\x98\xfb\x29\x0d\xfd\x00\xa5\xdf\x1c\x8d\xb2\xbd\xba\xd9\x1f"
-  "\x38\xf3\xbb\x98\xc9\x26\x74\xe0\xa5\x2f\x6e\xdd\xec\x3d\x28\xeb"
-  "\xd6\xcd\x11\xb6\x1c\x94\x6e\xc2\xb9\x01\xf4\xe4\xa1\xdf\xc4\x6b"
-  "\x6d\x99\x02\x3f\x94\x1f\x48\x55\x66\xd8\x32\x85\x6e\x2a\xf5\xb3"
-  "\x8a\xfa\x4c\x65\x8c\xd0\xe5\x11\xd7\x42\x96\xb0\x8d\xf2\x50\x0f"
-  "\x5d\x8d\xce\x55\xd0\x57\x99\xbd\x0d\x75\x8f\x69\x03\x60\x3c\x40"
-  "\xf3\x22\x9a\x49\xbb\x1c\xdd\x7b\xdd\xba\x39\x2d\x26\x1d\xe7\xbc"
-  "\x76\x75\x60\x33\xe4\xdc\xd0\xbb\x16\xba\xe4\x73\x7e\x44\xf5\x47"
-  "\xef\x16\x72\xdc\x39\xc5\x6e\xdd\x6c\xcd\x8f\x8b\x8c\x0f\xa1\x9b"
-  "\xd3\x89\xef\xe0\x1d\xb5\xbc\x8c\xfd\x48\x6d\xb6\x14\x46\x71\x4a"
-  "\xbf\x21\x75\xb3\x0d\x4b\xe9\x7d\x67\x58\x27\x4d\xbc\x47\x73\x69"
-  "\xce\x31\x1a\x33\xa1\x57\x82\xf4\x98\x7a\xcf\xea\xb8\xb5\x99\x69"
-  "\x6e\x5c\x3e\x76\xda\x1c\xa1\x79\xa1\xcd\x11\xb4\xf7\x60\xa1\x5b"
-  "\x2f\xcf\x38\x52\x84\x1f\xac\x4a\x1a\xc3\xd0\x4e\x33\x7c\x14\x32"
-  "\x65\x08\xe3\x02\xfd\xf9\xdb\xaf\xc5\xb8\x54\xd1\x5e\xa0\x96\x9d"
-  "\x17\x6e\x3f\xd2\xb7\x8b\xf1\x54\x68\x2c\xa4\x3e\x54\xca\x59\x11"
-  "\xeb\x82\x70\x06\x74\xc8\x9b\xed\x0c\xe7\xc5\x99\x9c\xe6\xc8\x81"
-  "\xdc\x80\xbe\x2e\x5f\xe6\xbf\x76\x21\xa0\x87\x3e\x09\xe4\xe1\x15"
-  "\x4f\xb0\x68\xc8\xd5\x51\x27\x4f\x5a\x1d\x98\xa3\x8d\xe3\x06\x1a"
-  "\xbb\x7c\x9a\xbb\x04\xf3\x2a\x82\x5f\xdd\xa0\x38\xb3\x0a\xd4\x29"
-  "\xcc\xa8\x50\x39\xb7\xee\x76\x2b\xd5\x97\xb0\x6b\x1a\xf7\x42\x6f"
-  "\x9b\x60\xb8\xd6\x5f\x72\x7b\xb4\x06\x43\xb4\x09\x7a\xd7\x15\x42"
-  "\xff\x3e\xa5\x58\xce\xa1\x94\xc5\x5a\x9f\xc7\x82\x67\xc5\x01\x96"
-  "\x54\x31\x9b\xa5\x2a\xc6\xc9\x76\x1e\x75\x5d\x3d\xe4\xcd\x0f\x78"
-  "\x18\x83\xcf\xee\x8c\xef\x7f\xcc\x5d\xde\x10\x53\xe2\x26\xdb\x71"
-  "\x3e\x11\xda\x7c\xeb\xd4\x8c\xf5\x88\x77\xdd\x50\x53\x14\x60\x09"
-  "\xae\x42\xaf\x8c\x95\xc3\x3e\x63\xa1\x35\x84\xc3\x09\xaf\xd3\x9e"
-  "\x1a\x5d\xf4\x19\xbb\x16\xf0\x52\xe2\x1a\x6a\x08\x66\x1f\x3e\x9c"
-  "\xc7\x8a\xc7\x87\x47\x6f\x17\xfe\xd3\x41\x5f\x10\xce\xd7\x8b\x58"
-  "\xc9\x5e\xa2\x4f\x2a\x1a\x6a\xc6\x59\x8f\x67\x2c\x1c\x89\x7e\x2b"
-  "\x90\x43\xab\x7d\xce\x40\x9f\x7d\x01\x06\x59\xfe\x03\x4f\xc1\x07"
-  "\xe8\x45\xa6\x54\x4c\xb6\xa3\xcf\x44\xeb\x98\xc7\x2f\xd3\xbf\x63"
-  "\x4c\xfb\x4f\x7c\x9b\x13\xbc\x95\xcd\xd7\xd5\x2b\xc6\x03\x66\x7c"
-  "\x1b\x6d\x80\xfd\xcd\x03\x17\x99\x80\x3b\xe0\xef\x0a\x84\x18\x8f"
-  "\x8b\x6c\x43\x70\xbc\x6d\x18\xbb\xff\xb3\x59\x52\xf9\x01\x39\xee"
-  "\xa1\xcd\x2a\x0c\x72\x70\x4e\x76\xc0\xdc\x6e\xf3\xb2\x07\xd0\x06"
-  "\xef\x59\x76\xff\x59\x26\xc6\xdf\x65\xf5\xb0\x50\xd4\xad\x53\xa1"
-  "\x7b\x81\xf1\x2f\x0c\xd2\xf8\x0f\x04\xe0\xff\xc3\xeb\x2a\xbe\xc4"
-  "\x40\xbf\x04\xfb\xad\xfa\x3f\x1f\xff\x3b\x3f\x7c\xd8\x3e\xde\xf1"
-  "\xbf\xf3\x6f\x34\xfe\x77\xfe\x0f\xe8\xff\xdc\x2f\xd0\xff\xb9\x7f"
-  "\xa3\xfe\xcf\xfd\x1f\xd0\xff\xaf\x7e\x81\xfe\x7f\xf5\x6f\xd4\xff"
-  "\xaf\x8e\xd9\xff\x05\xd7\x2a\x5c\xe8\xe4\xc4\xbf\x08\x1b\x33\x75"
-  "\x7f\xfb\xbb\xf7\xa0\x7f\x23\xec\xad\xd4\x34\x93\xf6\x57\x86\xcb"
-  "\xd2\xc6\xcb\xd2\x09\x97\xa5\x13\x2f\x4b\x9b\x2f\x4b\x27\x69\x69"
-  "\xda\x47\x26\x9c\xd3\xfd\xdd\xd7\x88\x2e\xa5\xfd\xf4\xef\x8e\xab"
-  "\xcf\x93\xe1\x1f\x87\xf6\xf4\xe4\xb1\x62\x7e\xc5\xe9\x18\x1f\xd2"
-  "\x73\x26\x62\x71\xe9\xfe\x7e\xf1\xa0\x83\x71\x1e\x35\xdd\x8a\x98"
-  "\x4a\x4a\x79\x5e\xf3\x03\xeb\x11\x83\x3e\x40\x74\xbe\x79\x22\xd5"
-  "\x7d\x4d\x06\xe1\x69\x8c\xab\x25\x17\xfa\x35\x7f\x7f\x37\xfa\x39"
-  "\xdb\xe6\x64\x4a\xd4\xad\x42\xbf\x41\xa9\xc8\x6b\xf6\x46\xdd\x3a"
-  "\x9d\x6f\x3f\x58\x5f\xe1\x50\x0c\x2e\xcf\x31\x56\xa9\x57\x2c\x05"
-  "\x05\x34\xbe\x9e\x43\xec\x69\x0f\xef\x2b\x08\xf2\x80\x6b\x89\x93"
-  "\x15\x79\x11\x8f\xa1\x85\xb5\x7b\x8f\x89\x98\x0c\x22\xf6\x84\xf7"
-  "\x10\x03\xfd\x53\x84\x32\x94\xd7\xee\xdd\xc7\xda\x28\xed\x5c\x75"
-  "\x92\xfa\xf9\xf7\x67\x5d\x9e\x7d\xc4\x2f\xe5\x39\x15\x63\xde\x1e"
-  "\x6e\xcc\x6b\x68\xf3\x20\x6e\x5f\xde\x3e\xb4\xb5\x9d\xda\xe1\x0a"
-  "\x36\x81\xcf\xda\x27\xea\xf5\x75\x08\x9e\x14\xe7\xb6\x4a\x1c\x95"
-  "\x8f\xcb\x6b\x40\xfb\xd0\xb6\xd1\xcf\x61\x5f\x9c\x4b\x6d\xbf\xeb"
-  "\x61\x6b\x34\x83\x8d\xc4\xf8\xe6\x48\x6a\xc2\x98\x74\x74\xf9\x8b"
-  "\x87\x64\xbd\x86\x2f\x52\xef\x98\xf8\x9f\x97\xbf\xa4\xb6\x37\xe1"
-  "\x8b\xd4\xeb\xbc\x42\xbd\x6a\x7b\x2d\x5f\xa0\xde\x7f\x30\x8f\x5d"
-  "\xef\x4f\xd5\xf6\xa6\x7d\x91\x7a\xc7\xb6\xd1\x2c\xff\xa9\xda\xde"
-  "\xe2\x2f\x52\x6f\xcb\x15\xc6\x6d\xee\x17\x9b\x0b\x77\x25\x5d\x69"
-  "\x2e\x7c\xb1\x79\x70\xd7\x15\xfa\xff\xd2\xdc\x2f\x36\x07\xee\xba"
-  "\x42\x4c\xf0\x97\x0e\x7d\xb1\xf1\xff\xc7\x2b\x8e\xff\x17\x1b\xfb"
-  "\x7f\x5c\x79\xa5\xb1\xff\x62\xe3\xfe\x8f\x63\xce\x7f\xf0\x06\xbc"
-  "\x7c\x8f\x97\xc7\x1f\xac\x56\x2a\xf3\xbc\x4a\xfc\x9e\x0b\x9b\x95"
-  "\x34\xb6\x60\x23\x63\xa6\x1a\x36\x65\xc1\x2e\xc6\x36\xd6\x32\x3d"
-  "\xf1\xce\xfa\xfd\x1b\x3a\xf5\xae\x60\x2a\xf0\x55\x68\x4f\x7e\x40"
-  "\x37\x93\xf2\xdf\xa0\x15\xeb\x23\x1a\x56\xd6\x91\xe7\xad\x2c\x4c"
-  "\x63\xc2\x6e\x8e\xf8\x07\xf8\x15\xcc\xf8\x8c\x70\x6a\x4d\x00\x3a"
-  "\x32\x53\xe8\xbd\x20\xcd\x5d\xaa\x23\xc0\x0e\x2a\x5e\x5d\x5a\xae"
-  "\x28\xe7\x15\x7a\xee\x95\x7b\x2e\xf0\x22\x2b\xfc\x8a\x79\x7b\x75"
-  "\xf3\x5e\x8d\xf2\x32\x7d\x1d\xd1\xe6\xfe\x92\x79\x87\xdc\xba\xbb"
-  "\xf7\xa8\x36\xa7\x1e\xe1\x0f\x8f\xda\xba\x99\x78\x04\x94\x85\x5f"
-  "\xbc\xd9\x36\xa6\x87\xaf\x61\x2a\xeb\x86\x8f\xbc\x2b\xd9\x6e\x87"
-  "\xca\xf7\x1f\xc3\xfb\xbc\x9c\xf6\xe3\xb3\x4c\xdf\xee\xf3\x32\x9e"
-  "\x64\x5b\x5c\x49\xfc\xc8\x7d\xb7\x40\x7e\x72\x81\x15\x6e\xe4\x0a"
-  "\x64\x59\xdc\xd8\x50\x0a\x7d\x43\xe1\x77\x5d\x77\x77\x01\x78\x7b"
-  "\x35\x76\xe4\xf4\x33\x94\x16\x3c\x11\xf4\x6e\x8c\x79\x76\x5e\x19"
-  "\x97\xd6\xee\xbb\x20\x62\x6a\x74\xeb\xee\xde\x08\xdf\x64\xfd\xc6"
-  "\xfd\x1d\x3e\xe3\xfe\x4e\x7f\xc9\xdd\x76\xad\x0f\xf8\xbe\x96\x0f"
-  "\x1e\x10\xe5\xe8\x79\x8d\x66\xcb\x3d\xea\xb8\x6f\x9e\x3e\x35\xc3"
-  "\xcc\xbd\x80\xab\x6c\xcb\x3d\x21\xc0\x9e\x97\xef\x6f\xf1\x15\x59"
-  "\xaf\x97\x32\x91\x7b\x92\xc1\x5b\x53\xbb\x0f\x49\x3e\x37\xef\x90"
-  "\x88\xcb\x41\xf8\xff\x61\xab\x7e\x9c\x34\xf0\xdd\x22\x86\xb4\xf3"
-  "\x7a\xec\xb7\xf7\x9c\xa4\xfa\xff\xb1\x5b\x77\x4f\xba\xe4\xeb\xf2"
-  "\x5a\xa4\x3d\xe6\xdd\x3d\xf4\x8d\x16\x4a\xdb\x50\x8e\x9e\xe7\xa8"
-  "\xcf\x3b\x22\x9e\x77\x40\xff\x54\x7d\x5e\xaa\x3e\x3f\x16\xf1\xfc"
-  "\x98\xed\x7a\xc8\x39\xee\x69\x44\x1f\x08\x8e\x8d\xf4\xbc\x59\xf8"
-  "\x39\x10\xb1\xe6\xf2\x1a\xd5\x72\xcd\x1e\xdd\x3d\xef\xf4\xd3\xdc"
-  "\xa2\xe7\xad\x11\xef\xb7\x1e\xb1\xa7\x30\xcc\x51\x7f\xc9\x3d\xc7"
-  "\xdd\xfa\xfd\x06\xc9\x1b\xdf\xdd\x27\xfa\x4e\x7b\x66\x64\x7d\x6e"
-  "\xdd\x3d\x0d\xd8\x17\x7d\x44\x93\x51\x99\x0e\x7c\x33\x12\xde\x9a"
-  "\x55\xa8\x65\xd9\x93\x4b\x2d\x8f\xad\x5e\xbb\x0a\x56\x7d\x23\xed"
-  "\xd5\x12\x60\xf7\xaa\x94\xef\x6d\x72\xd5\xc0\x0e\x2f\x41\xd8\x7c"
-  "\x6f\x83\x4e\x56\xfc\x01\x6f\xa8\xf2\x40\xb1\x12\xdf\x50\xef\xdc"
-  "\x70\x2f\x3b\xa7\x9b\x2f\xfc\x01\xb9\x2c\x8c\x95\xd3\x73\xe7\x86"
-  "\x77\x91\x27\x62\xa9\x21\xf6\x8a\xe0\xff\x37\x18\x58\xb3\xe5\x82"
-  "\x90\x21\xd0\xb3\x57\x85\xbc\xe4\x22\xd3\x07\x1d\x06\xf6\x1f\x85"
-  "\x1d\xfa\xc3\x8a\x5b\xff\x1f\x4a\xa7\xd0\x7d\x3e\x62\x6e\x61\x73"
-  "\xec\x06\xc4\xb3\xd2\xbf\x4e\x7c\x39\x9e\xe3\x99\x16\xd7\xec\x9c"
-  "\x2e\x2d\x46\xe8\x41\xdf\x24\xef\x8b\x6a\xf8\x89\x23\x66\xaf\x6a"
-  "\x0f\x3e\xff\x11\xb4\x15\x7a\x8d\x1e\xdd\xfc\xa5\x68\x9f\x5b\x37"
-  "\x3f\x3b\xaa\x56\xe8\x83\x1b\xa9\xfc\xfd\x4a\xc5\xde\x26\xe0\x82"
-  "\x60\xc9\xfc\x44\xee\x30\xbe\x04\x9b\xc0\xda\x67\x35\xfb\xd7\xb4"
-  "\x48\xfb\x57\x63\xbf\x9e\xcd\xa7\xbc\x45\x9a\x8f\x0b\xc4\x02\x1a"
-  "\x0b\xb7\x04\x88\x5e\xbc\x94\xb4\xba\x53\x31\xee\xa5\xb1\xd8\xdb"
-  "\x84\x08\xc3\x26\x11\xbf\x78\x90\xda\x72\xef\x42\x1e\xb7\xb7\xa1"
-  "\x10\x6b\xba\xb2\xa1\xfe\x67\xd0\x31\x24\x38\xee\x83\x4e\x21\xc1"
-  "\x72\x2f\xa5\xdf\x4d\x6f\x60\x96\x07\x41\x7f\xa5\xfd\xe6\x9f\x97"
-  "\xf1\xe0\xad\x8b\x9d\xac\xb5\xe7\x17\xec\xe8\xb1\x16\x66\x5c\xc2"
-  "\xa2\x8a\xdc\x3c\x24\xfa\x98\xc7\xf4\x19\x6e\x16\x05\xdf\x4a\xf0"
-  "\x8b\x0e\x9b\x8c\xf6\x40\x1b\xd1\x44\xe5\xc1\xfd\x85\x7d\x13\x2c"
-  "\x0f\x30\xa2\xa5\xe4\x79\xb5\xb0\x39\xf2\x0a\x9b\xee\x38\xc8\xce"
-  "\x23\x6c\x8d\x16\x16\x64\x73\x65\xe3\x59\x66\x68\xcb\xf9\x23\xcb"
-  "\xc8\x8e\xe2\xc2\xd6\xc8\x4e\x05\xbd\x34\xf6\xeb\xa4\x5e\xe0\xf6"
-  "\x01\x96\xd8\x9e\xe7\x66\x2e\x4f\x0b\xdb\x99\xcb\x12\xb9\x3f\x27"
-  "\xa6\xb5\xe5\x5d\x46\x38\xc0\x76\xb0\xd0\x39\x21\x64\x94\xba\x5a"
-  "\xa6\x4d\x3a\xc8\x4a\xe3\xcb\xa1\xb3\x35\xc0\x52\xb2\x4e\x16\x0b"
-  "\xf9\x2e\x64\xe9\x41\xbf\xd5\x32\xe4\xb7\xde\x34\xb8\xce\x7a\xbd"
-  "\x26\x83\x7f\xe4\x6c\x02\xce\x1c\x32\x79\xc9\x1d\x8d\xb0\x53\x02"
-  "\xed\x19\x8c\x9b\x62\x87\xbc\x5d\xf8\x8a\x59\x67\x4d\x52\x1e\xb3"
-  "\xb2\x39\x5e\x61\x07\x85\x33\x80\x84\xba\xef\xa0\xad\x17\x98\xd0"
-  "\x3b\x8a\x93\x7a\x47\x01\x9c\x7f\x1b\x0f\x58\xef\x5f\x61\x61\x83"
-  "\x33\x56\x77\xba\xec\x3f\x63\x45\x97\xf8\x09\xc1\x13\x20\xb6\x72"
-  "\x49\xda\x32\x1e\x77\xc0\xfa\xa6\xf5\x03\xec\x25\xa9\xe3\xc7\x0f"
-  "\xf7\x0a\xfa\x0f\xb0\xa1\x71\xf2\xee\xbb\x80\x71\x6b\xa8\xff\x79"
-  "\xae\x57\xff\x8d\x1e\x1e\x6c\x5b\xf6\x33\x76\xb4\xb3\x63\xc4\xf8"
-  "\x88\xf1\xa4\x72\x18\x27\x8c\x11\xc6\x2a\x3c\x4e\x1f\x88\x71\xda"
-  "\xa7\xc8\x71\x1a\x34\xee\xf1\x6a\x63\x15\xa8\x5d\xdd\xf7\x79\xc6"
-  "\xab\xb5\x67\xf4\xf1\x22\x38\x0f\x8f\xd7\x8e\x0b\x2c\xd1\xe5\x21"
-  "\x3a\x99\xc6\xeb\x1b\xdf\x64\xec\x1b\x7b\xb9\xd2\x96\xfe\xfe\xf0"
-  "\xb8\x05\xcb\xc7\x18\xb7\xd3\xe1\x71\xa3\xf1\xbf\xc2\xb8\xdd\x39"
-  "\x77\x3c\xe3\xd6\xda\x23\xc7\x2d\xa8\xea\x8b\x59\x9b\x99\x3e\xb0"
-  "\xce\xaa\xaf\x19\x60\xa9\x18\xbf\x45\x27\x2d\xec\xcd\x87\xda\x68"
-  "\xcc\x7e\x31\x62\xfc\x94\x8a\xfd\x2d\x34\x06\x46\x8c\xe1\x17\x5b"
-  "\x77\xf7\x1d\xfe\xfc\xeb\x6e\xe1\x57\xff\xdf\xba\xfb\x5b\xad\xbb"
-  "\x05\xc7\xff\xba\x75\x77\x5f\xe9\xff\x5b\x77\xff\xdd\xeb\xee\xbe"
-  "\x2d\x97\xaf\xbb\x61\xba\x21\x77\xf9\x93\x4b\x57\xac\x5a\xb1\xea"
-  "\xbb\x96\xef\xac\xcf\x5b\xbe\x46\x52\x0f\x23\xe8\x07\x73\xa8\x30"
-  "\x4d\x8f\xd8\xd0\xad\x35\x1d\xec\xe0\xf4\x0e\x7d\xe8\x94\x39\x9a"
-  "\x97\xcf\x74\x2a\xe5\xc9\x69\x88\x13\x8d\xf5\x89\xf8\xd1\xbd\xba"
-  "\x45\x69\xf0\x3b\x28\x7d\xbc\x2c\x12\x76\x07\x44\xa7\xe6\xe0\xec"
-  "\x67\xf3\x20\xfd\x36\xb0\x68\x53\x80\x19\x9c\xd7\xe3\xf9\x3f\xef"
-  "\x82\x8f\x34\xbe\xcb\x96\x53\x87\xb8\xce\x83\x2c\xda\x67\xcc\xfb"
-  "\xff\xda\xbb\x1e\x80\xa8\xaa\xac\x7f\xe7\x39\x2a\x2a\x03\xa3\x4b"
-  "\x86\x2e\xda\x54\xd8\x8e\xad\x26\x15\xb9\xda\x5a\x4b\xae\x16\x95"
-  "\x8a\x96\x6e\x58\x96\x5a\x5a\x58\x28\x84\x88\xa4\x08\x48\x66\x48"
-  "\xfc\xab\xcc\xcf\x3f\xfc\x6b\x3f\x05\xdc\x45\xc4\xd6\x0a\x4b\x73"
-  "\x4c\xdc\x25\x05\x86\x5a\xfa\x96\x5a\xdc\x26\x22\x23\x43\x9d\x00"
-  "\x05\x61\x66\xde\x77\xce\xbb\xef\x31\xef\x0d\x33\x30\xff\x44\xdd"
-  "\xa0\x9e\x33\x73\xdf\x79\xf7\xdd\x7b\xce\xef\xfe\xce\xb9\xf7\xbe"
-  "\x77\x6f\xe4\x26\xc8\x4f\xaf\xd8\x5b\x2a\x57\xe1\xbb\x2c\x0f\x41"
-  "\x5c\xf4\x87\x09\x5d\x6b\x27\xc9\x1e\x5d\xc2\x0e\x7a\x68\x16\x72"
-  "\x03\xbe\x7b\x78\x5e\x16\x7c\xe7\x65\x9c\x3b\x81\x98\x7a\xc1\x78"
-  "\xb8\xd7\x98\x88\x46\x6e\x5d\x08\xe0\x09\x7a\xfe\x61\x6e\x7d\xcd"
-  "\xcb\xa9\x85\x79\xdc\x1e\xdb\x9e\xc5\xfa\x96\xd4\xe2\xc4\x93\x71"
-  "\xdb\x79\x9e\x08\x7e\xfa\x91\xed\x94\x27\x2a\x7d\x01\x87\xb3\x00"
-  "\x87\xa1\xbd\xf1\x84\x08\x7f\x63\x1d\xe3\x09\xc4\x1b\xe2\x0e\x31"
-  "\x37\x0c\x30\x87\x38\x14\x70\xf7\x36\x8f\x3b\xef\x3a\xa2\xe4\xb0"
-  "\x67\xa0\xd8\xc3\xf7\xa9\x2b\x63\xcd\xb8\x33\x5a\xe2\xee\x92\x05"
-  "\xee\x18\x1e\x77\x6b\xa5\xb8\x7b\xea\xb4\x92\xec\xa2\x7c\x61\xc6"
-  "\x5d\xda\xf0\x58\x01\x73\x88\x3f\xc4\x9a\xe9\x05\x35\xa9\x6c\x6a"
-  "\xee\xc2\x5f\xce\xf3\x74\xfe\x96\x7b\x3e\x98\x61\x4b\x2e\xaf\xe5"
-  "\xf9\xe2\x9c\xc0\x17\x3b\x6d\xf8\xe9\xd3\x4e\xf2\xc5\xc3\xdc\xfb"
-  "\x1f\x68\xab\x0e\xb0\x1b\xda\xeb\x11\x5f\xe0\x09\xdf\x3f\x93\x53"
-  "\xf3\xaf\x11\xfb\x44\xb9\xc7\x3e\xb8\xbf\x2e\x94\xc5\x8a\x8d\xee"
-  "\x9c\xd6\x9b\x8d\xd0\x3e\x68\x27\xce\x3e\x60\x27\x61\x8e\x1d\xe7"
-  "\x5c\xd1\x56\x68\x9f\x3b\xe2\x08\x83\xf6\xca\x89\xa1\x1c\x81\x5c"
-  "\xc0\x3d\xd3\x6d\xc1\xf1\xa0\xf3\x83\x68\x33\xae\x5f\x9d\xa4\x58"
-  "\xb5\x75\x84\x79\x6f\x9a\xb6\xcd\x8f\x26\x76\x8f\xa3\x1f\xdd\xda"
-  "\xb5\x56\x9c\x2c\x98\x9b\xb3\xd5\x8c\xbe\x17\xda\xe7\x43\x74\x8d"
-  "\xc3\xd4\xbd\x61\x34\x86\x9f\xf5\x33\xcf\x01\x73\xb1\xef\xca\xf5"
-  "\x53\x8d\xd0\x4f\xf5\x84\x7e\x6a\x2a\xf4\x53\x71\xdc\x90\x5b\x6b"
-  "\xe1\xd1\x73\x74\x4e\x0f\xfa\xa5\x8a\xc2\x64\xe8\x23\x71\x6b\x30"
-  "\x72\xf3\xc7\x8a\x7d\xd5\xdc\x1e\xf2\x69\xd0\x07\xfe\x33\x43\xe0"
-  "\x77\xed\x09\xb5\xd1\x41\x4c\xcd\xf2\xe4\xe7\xc7\x33\x23\xd7\xe1"
-  "\xb3\x13\xb3\xea\x68\xf9\x1e\xe2\xd6\x18\xe3\xe6\x16\x19\x53\x9e"
-  "\xf1\x55\xe9\xdc\xa2\x78\xee\x79\x7f\xbc\x9e\x9f\x57\x9c\xc5\xed"
-  "\x99\x85\x7c\x82\x3c\xb8\x0f\xfa\x34\xe6\xb9\xc5\x2f\xf0\xfc\x09"
-  "\xe9\xdc\xe2\x2c\x2e\x4f\x28\x83\x1e\x9f\xa7\x81\xdf\x45\x34\xfd"
-  "\xa1\x83\xe2\x74\xf3\xdc\x3d\x4d\xc7\x77\xb8\xf8\xf1\x82\x26\x3a"
-  "\x4e\x30\xdb\x43\xe8\x8f\xdb\x88\x9f\x1c\xe0\xe9\x79\x06\x33\x4f"
-  "\xcf\x33\x70\xba\xf1\xdd\xbf\xbd\xb2\x1b\x4f\xe3\xba\x5d\xf3\x16"
-  "\xce\x41\x9e\x4e\x2d\xa4\xfb\x41\xc8\x66\xbf\x03\x3a\x19\x80\xfb"
-  "\xcb\x61\x3a\xbe\xeb\x84\x7c\x9d\x0d\xd7\x65\x73\x1c\xbe\x3f\x79"
-  "\x13\xf7\x0c\xc1\xec\x52\x29\x77\xcf\xf3\x93\x72\xf7\xec\x73\x3d"
-  "\x73\x77\xc8\xde\x9e\xb9\x7b\xce\xa8\x7e\xee\x76\x37\x77\x0b\xb1"
-  "\x9e\xb3\xdc\x1d\x12\xdd\xcf\xdd\x7d\xcd\xdd\x21\x91\x22\xee\x5e"
-  "\x28\xe5\xee\x79\xd3\xba\x73\xf7\x3c\xf3\xfa\x9f\xb2\xd9\x65\x66"
-  "\xee\x9e\x1d\x27\xe5\xee\xc7\xf6\xd9\xc7\xdd\xf3\xf6\x5e\x59\xee"
-  "\x9e\x57\x2e\xe5\xee\xc7\x78\x9e\x9c\xfd\xb4\xe3\xdc\xfd\xd8\x2b"
-  "\x3d\x73\xf7\x63\x1b\xa5\xdc\xfd\xd8\x7c\xca\xd1\x8f\x15\x51\xee"
-  "\x7e\x2c\x8c\xa6\xcf\x5e\x24\x4e\x37\x73\x37\x4d\xef\xce\xdd\x8f"
-  "\x95\xf5\xc2\xdd\x6a\xa3\x49\xe0\xee\x5a\xe0\xee\x5a\xc6\xf4\x82"
-  "\x2d\xee\x0e\xf5\xaf\x44\xee\x8e\x42\xee\x0e\xf5\xef\x99\xbb\x43"
-  "\x87\x23\x47\x03\x8e\x49\xd6\x36\xb6\x11\xd7\xa1\xd4\x3c\xff\x35"
-  "\x8e\x5f\x37\x20\x6e\xcf\xc8\x9e\x58\x31\x27\x4e\xcc\xed\x8f\xbf"
-  "\xdc\xc5\xed\x90\x6e\x1a\x25\xe5\x76\xe4\x75\xe4\xf7\xec\x6d\xac"
-  "\x2e\x67\x1b\x5b\xd7\xb6\xf9\xf1\x2c\x81\xe3\xd3\x20\x0d\xf7\x16"
-  "\xc1\x35\x93\xb2\x2f\x71\x87\x1c\x74\xd0\xf0\x2a\xdc\x17\xaf\x01"
-  "\xd9\x72\xa9\x3f\x78\x62\x82\x61\xb3\xd8\x1f\x3c\x6e\x44\x7f\x90"
-  "\x4a\xdf\xfb\xe7\xfc\x80\x21\x3b\xa2\x11\x7d\x03\x3d\xbf\xe0\x50"
-  "\xcf\xfe\x60\xfe\xf8\xab\xe5\x0f\x90\x6b\x86\x89\xfa\x90\xb6\xfc"
-  "\x01\x8e\xa9\x56\x2e\xeb\x1b\x7f\x80\x3c\x83\xfc\x82\x5c\x83\xbc"
-  "\x83\x3c\x83\x9c\x63\xe0\xdf\xf5\xcb\x4a\xb2\xc3\x1f\x00\xaf\xb0"
-  "\x83\xfe\x58\xc7\xf9\x03\x99\x33\xfe\x60\xc1\xa6\xeb\xca\x1f\xa0"
-  "\x7d\xe2\xae\xac\x3f\x10\xfa\xf9\x68\x1f\xb4\x95\x60\x23\xa1\xaf"
-  "\x8f\xf6\x41\x3b\xa1\x7d\x30\x36\x12\xfc\xc1\xc4\x58\xea\x0f\xb2"
-  "\x7b\xf5\x07\x0b\x12\xbb\xfc\x01\x43\xfd\x01\x37\x26\x3e\x02\xfd"
-  "\xc1\x13\xb3\xba\xfb\x83\x27\x96\x98\xfd\xc1\xe3\x35\x3c\x3f\x36"
-  "\xe0\x7a\x16\xc0\x07\xa1\x52\x9f\x10\xfa\xa5\x7d\x3e\xe1\x89\x23"
-  "\xdd\x7c\x02\xe8\x36\x95\xce\x9b\xa1\x3f\xa8\x46\x7f\x60\x40\xbf"
-  "\xe0\x94\x4f\x78\xa2\xce\xec\xb7\x1e\xa7\x7b\xe0\xc9\x9e\x88\x95"
-  "\xfa\x89\x50\x0d\xcf\x69\xa3\xc4\x7e\xc2\x34\xc0\x1e\x3f\x11\xfa"
-  "\xae\xe0\x27\x90\x87\xf7\xe1\x9c\x45\x97\x9f\xe0\x78\x75\xaf\x26"
-  "\xa6\x5e\xe4\x27\x42\xe3\x68\x19\x42\x6b\x8c\x9c\x9f\x08\xcd\xa4"
-  "\xe9\x8f\xfb\x8a\xd3\xcd\x7e\x82\xa6\x1b\xc5\x7e\xa2\x11\xfd\x44"
-  "\x68\x53\x2f\x7e\x22\xd0\x7e\x3f\xf1\x4c\x99\xd9\x4f\x3c\x53\xd6"
-  "\xb3\x9f\x78\xe6\x00\xfa\x09\x6e\x9d\x5d\xb0\x3d\xe0\x5c\x9e\x3e"
-  "\x92\xfa\x08\x1c\xa3\x01\xdf\xa1\xc3\x75\x54\x40\x2e\x3b\x17\xfd"
-  "\x08\x1c\x70\xbe\x31\x15\xbf\x9b\xb8\x6b\xea\xbc\xf5\xc4\x03\x7d"
-  "\x46\xea\x19\x22\xc7\x3d\x9d\xa8\x9e\x9e\xbe\x0c\xd7\xd6\x9a\xfd"
-  "\xcb\xc2\xcf\xed\xf4\x2f\xb8\x07\x7d\x75\xdb\xe6\x85\x06\x91\x7f"
-  "\xc1\x7d\xb1\xaa\x2d\xfc\x8b\x0e\xfc\x4b\x83\x70\x4d\xdb\xe6\x27"
-  "\x27\x88\xe5\xb1\x7c\x9c\xfc\x19\xee\x40\xf9\xda\x57\x71\xaf\x37"
-  "\xce\x1f\x3d\x19\x2a\xf5\x47\x4f\x1f\x36\x49\xfa\x27\x4f\xa6\x09"
-  "\xfe\x08\xfd\xb9\xa9\x9b\x3f\x5a\xf4\x70\x97\x3f\x1a\x29\xf2\x47"
-  "\xb1\x82\x3f\x7a\xf2\xd0\x35\xdf\x3f\x71\x81\xef\xae\xb4\x3f\x32"
-  "\x81\xdf\xb1\xf4\x47\xe8\xa3\x84\xfe\x89\xc9\x29\x7f\xb4\xc8\xe7"
-  "\xba\xf2\x47\x7d\xd0\x3f\xb1\xb4\x8d\x60\x33\xb4\x0f\xda\x06\xed"
-  "\x82\x6b\x7d\xa3\xcd\xd0\x5e\x68\xab\x89\x91\x52\x5f\xc4\xd9\x0b"
-  "\xfc\x51\xb7\xb9\x03\xb0\x15\xe8\x5c\x89\xf6\x12\xfb\xa3\x9c\x11"
-  "\x82\x3f\x7a\xba\xae\xbb\x3f\x7a\x5a\x6f\xf6\x47\x4f\x2e\xe3\x78"
-  "\x9e\x5b\x8b\x71\x61\xa9\xd4\x17\x2d\x5e\x63\x9f\x2f\x7a\xe6\x61"
-  "\x2b\xbe\x88\x5b\x47\x33\x75\x9b\xa4\x6f\x52\x0d\xfe\xc8\x09\x5f"
-  "\xf4\x4c\x18\x2d\x23\x3e\x57\xbe\x30\x99\xf2\xfd\x33\x72\xb3\x7f"
-  "\x5a\xb8\x44\x9c\x66\xf6\x4f\x8b\x97\xf0\x9c\xf8\x80\xe3\xfe\x69"
-  "\x31\x77\x0d\x3e\x73\xbe\xaf\x99\xfa\x00\xa9\x7f\x5a\xfc\xb0\xd4"
-  "\x3f\x2d\xf6\xa3\x65\x58\x1c\x4d\xfd\xd3\xe2\x00\x9a\xbe\x30\x48"
-  "\x9c\x6e\xf6\x4f\x34\xbd\xbb\x7f\x5a\x9c\xda\x8b\x7f\xf2\xec\xcc"
-  "\x8a\x68\xec\x48\x2d\xae\x36\xec\x4e\x4c\x9c\xb0\xe8\x26\xa3\x65"
-  "\x7b\xa2\xed\xc8\x48\xf7\x13\x12\xe6\xdb\xfe\x44\x48\xa7\xe7\x6e"
-  "\xbd\x89\x7f\x37\xbb\xc3\x2f\xa2\xf6\x4c\x38\xb4\xa9\x26\xdb\x6d"
-  "\x0a\xda\x93\x87\xd0\x9e\x2a\xc3\xbe\x27\xd0\xc6\x18\x9c\x6f\xdb"
-  "\x09\x6d\x49\xdb\x5a\xcb\xb5\x2d\xcf\x06\x15\xc1\x75\x36\x15\x4d"
-  "\x44\xa9\x90\xc9\x06\x3d\xba\x10\xda\x2c\xb4\xab\x99\xe3\x59\xd3"
-  "\xed\x75\x2a\xa2\x08\x23\x5e\xd8\xb6\x8a\xf9\xf9\x1c\x5c\x57\x03"
-  "\xe7\x71\x00\xd7\x01\x8b\x3f\xa7\x6d\x6a\x27\x1c\x1d\xb4\x4d\x8d"
-  "\xed\x68\x53\xdf\x62\x6b\x1e\x47\x1b\xab\xe3\xe6\x71\xf0\xbd\x27"
-  "\x7c\xdf\xcc\x84\x6d\x08\xe7\x71\xda\x69\x6c\x07\xe5\x55\xe6\x72"
-  "\xf3\x38\xf5\x92\x79\x9c\xdf\xd6\x11\x06\xd7\xdc\xd8\x25\x9e\xc7"
-  "\x51\x57\x76\x8b\xeb\xb0\x7d\x61\x7b\x72\x9c\xf3\x96\x7a\xf4\xf4"
-  "\x1c\x95\x01\x74\x6d\xf4\x2c\xae\x66\x77\xee\xd7\xfc\xb5\xbe\x5d"
-  "\x86\xeb\x9b\x1a\xc1\x76\x26\xe0\x36\xd6\xd3\x82\xdb\x3a\x79\x3b"
-  "\x74\x52\x3b\x80\x0d\x3d\x9e\x69\x25\xec\x62\x03\xb4\x9f\x4e\x7e"
-  "\x8d\xd3\x76\x1d\xe0\x50\x3d\x22\x7b\x1d\xea\xdd\x97\x64\xf3\xeb"
-  "\x9c\x9a\xd6\x87\x0d\x31\x81\xae\xd9\x24\x86\xec\xbb\xd4\xce\xcd"
-  "\x7b\xa6\x76\x90\x09\xc0\x65\xb8\x76\x93\x17\x60\x77\x68\x6e\x07"
-  "\xe8\xfd\x5b\xaa\x77\x5c\x43\x0f\x3f\x0d\xeb\xd5\x2a\xc8\xfb\x96"
-  "\xce\x4e\xe0\xb2\x76\xaa\xfb\x67\x5e\x56\x12\x6e\x6d\x54\x9c\xfb"
-  "\x84\xb8\xa1\x0a\xec\xcd\x71\x59\xab\x37\x8b\xfb\x80\x98\x7e\x50"
-  "\xe3\x7a\x62\x7e\x93\x5a\x71\xcf\x17\x35\x62\x43\x99\x73\x06\xe7"
-  "\x3e\xbf\x96\xcc\x7d\xea\xd7\x9b\xe7\x3e\xab\x0a\xbf\xa4\xcf\xaa"
-  "\x48\xc6\xc3\x16\xe7\x75\x66\x53\x9f\xc3\x8d\x87\x45\x3b\xaa\xfb"
-  "\x67\x6d\xae\x7f\x72\xe5\x75\xaf\xbc\xce\x75\xbf\x74\xae\x6b\xba"
-  "\x47\xd7\x71\xb5\x74\xef\x71\x9d\xeb\xfe\xd9\x0a\xd7\x74\xbf\x3c"
-  "\xae\x27\xdd\x63\x1f\x46\xe8\xbf\x08\x7d\x17\xf4\x61\xd4\x5f\x87"
-  "\x29\xcd\xfd\x96\x30\xa5\x30\x87\x0c\x3a\x93\xa7\xe1\xfa\xdf\xa0"
-  "\x8b\xc8\xe7\x71\x5f\x8d\x17\x5e\x13\xe6\x8f\x33\x71\xef\x18\xb4"
-  "\xe3\x4e\xb0\xe3\x2a\x7c\x6f\x89\xb7\x21\xf8\x9c\xc5\xad\xe0\x17"
-  "\xc6\x44\x34\x1a\xd3\xc0\x27\xed\x49\x4c\xb4\x61\x4f\x06\xfd\x89"
-  "\x22\x9a\x28\x9f\x89\x34\xdb\xd5\xb4\x1e\xec\xd9\x01\xb1\x59\x7b"
-  "\x23\xc1\x77\x91\xbd\x1b\x21\x6e\xed\x0c\x1b\xb2\x08\xfa\x00\x82"
-  "\x4d\x8b\x63\xda\xb9\xb8\xcc\xaa\x4d\x77\x48\x6d\xda\x62\xc5\xa6"
-  "\x4f\xaf\x80\x76\xca\xf0\xb1\x33\x67\x53\x5d\x97\x4d\x39\x3f\xb2"
-  "\x5e\xed\x87\x76\x15\x6c\x8a\x7e\x84\xb3\x69\x13\xf5\x23\x5d\xeb"
-  "\x36\xad\x37\xc7\xce\x15\x4b\x4e\x5b\xb1\xe9\xb2\x60\x89\x4d\x97"
-  "\x38\x6a\xd3\x17\xe6\x4a\xe3\xaf\xb0\x23\xf6\xc5\x5f\x2f\x54\x62"
-  "\x7c\x25\x8e\xbf\xf0\x77\x0b\xc4\x5b\x46\xc5\xbe\x9a\x56\xa7\xfa"
-  "\xff\x2f\xd4\x49\x63\xa9\xb0\x42\x5a\xa6\xe5\x97\x1d\x8f\xa5\xc2"
-  "\xb8\x75\xeb\xf7\xed\xb4\x16\x47\x85\xbd\x29\x8d\xa3\xc2\x96\xd1"
-  "\x78\x29\xec\x70\x4b\x12\xc6\x51\x61\xb1\x34\x7d\x79\xbb\x38\xdd"
-  "\x1c\x47\xd1\x74\x6e\xcf\xfa\xcd\x61\xe5\x8e\xc5\x4e\x37\x5e\xe5"
-  "\xd8\xc9\xb7\x87\xd8\xc9\xf7\x17\x12\x3b\xbd\x38\xa3\xdf\x7f\x3b"
-  "\xeb\x43\xc2\xea\x5c\xf3\x21\x2f\xf5\xf8\xfc\x7f\xbf\xff\xee\x49"
-  "\xf7\x2f\xa6\xba\xa6\xfb\x95\x36\xf7\x0a\xea\xdd\x7f\x47\x54\x9b"
-  "\xfd\x77\x44\xb5\x6d\xff\x1d\x31\xb3\xdf\x7f\x3b\xe2\xbf\xc3\x3d"
-  "\x5c\xf3\xdf\x11\x4a\xa9\xff\x8e\xdc\x60\x9f\xff\x8e\x48\x73\xbf"
-  "\xff\x8e\xc8\x92\xfa\xef\x48\xbe\x4c\x2b\x0f\x39\xee\xbf\x23\x1f"
-  "\xb6\xed\xbf\x23\xe7\x49\xfd\x77\xa4\x3f\xf5\xd3\x91\x71\xd4\x7f"
-  "\x47\x4e\xa1\xe9\x2b\x4b\xc5\xe9\x66\xff\x4d\xd3\xa9\xff\x8e\x4c"
-  "\x76\xcc\x7f\x7b\x5f\x65\xff\xad\xec\xc1\x7f\x2b\x7f\x21\xfe\x3b"
-  "\x4a\xde\xef\x43\x9c\xf5\x21\x91\x59\xae\xf9\x90\xd5\x89\xce\xfb"
-  "\x90\x18\x1f\xb3\x0f\x89\xf1\xb1\xed\x43\xd6\x6c\xe9\xf7\x21\x8e"
-  "\xf8\x90\xa8\x59\xae\xf9\x90\x35\xf3\xa5\x3e\x24\xe6\x98\x7d\x3e"
-  "\x64\xcd\xe7\xee\xf7\x21\x6b\x74\x52\x1f\x12\x53\x44\xcb\xb4\xda"
-  "\xe8\xb8\x0f\x89\x49\xb3\xed\x43\x62\xde\x91\xfa\x90\x98\x30\xea"
-  "\x2b\x62\x34\xd4\x87\xc4\xc4\xd1\xf4\xd5\x06\x71\xba\xd9\x87\xd0"
-  "\x74\xea\x43\x62\x2a\x1c\xf3\x21\x83\xaf\xb2\x0f\xf1\xe8\xc1\x87"
-  "\x78\xfc\x42\x7c\x48\x6c\xb0\xf3\x3c\xb6\xae\xce\xcc\x63\xeb\xea"
-  "\x6c\xf3\xd8\xba\x79\xfd\x3c\xe6\x08\x8f\xc5\xe8\x5c\xe3\xb1\x75"
-  "\x7e\x52\x1e\x5b\xbf\xc5\x3e\x1e\x5b\xb7\xc3\xfd\x3c\xb6\xae\x50"
-  "\xca\x63\xeb\xa3\x69\x99\x62\x4f\x38\xce\x63\xeb\x17\xd8\xe6\xb1"
-  "\xf5\x4f\x4b\x79\x6c\x7d\x00\xe5\xab\xf5\xc9\x94\xc7\xd6\xcf\xa0"
-  "\xe9\xb1\x65\xe2\x74\x33\x8f\xd1\x74\xca\x63\xeb\xb7\xf6\xc6\x63"
-  "\xd8\x2e\x2a\x7d\x2d\xda\xc5\x4b\x42\xbb\x88\x97\x9f\xca\x12\xda"
-  "\x45\x3c\x17\xa3\x99\xb2\x22\xc3\xde\x88\x21\xf2\x54\xdc\x8f\x07"
-  "\x38\x22\xf2\x49\x6c\x17\x1b\x5e\xc1\xe7\x44\x3c\xeb\x80\xf7\x1a"
-  "\x78\x1e\x8c\x05\x1e\x6c\x80\xdf\xb8\x46\xdb\x98\xc8\x30\xe4\x2f"
-  "\xdc\xbf\x03\x7f\x53\x3e\xd4\x0f\xc4\xfd\x80\xb8\xb9\x79\x51\xbb"
-  "\xe1\xda\x4a\x0b\xdf\x56\x5a\x68\x5b\x11\xde\xdd\x8b\x6b\x60\x4d"
-  "\xc6\xd5\xea\x11\x21\xcb\x06\xb0\xd8\x7e\xb8\x77\xc2\xa0\xfd\xb0"
-  "\xab\xd5\x5e\x59\x51\xd0\x66\xf4\x8d\x04\xd7\xe1\xc7\x36\xa3\xd8"
-  "\x28\xf3\x62\x5b\xc2\x86\x00\x27\x52\xee\x33\x95\x0f\x34\xe0\x9a"
-  "\x5a\xab\x81\xfb\x9a\x81\xfb\x9a\xcd\x6d\x05\xe7\xdb\x5b\x56\xab"
-  "\x55\xad\xab\xd5\x63\x3b\x5b\x80\xfb\xf4\x96\xed\xe4\xce\x69\xb9"
-  "\xcd\xc8\x7d\x8d\x5c\x3b\xe1\xb8\x0f\xda\x86\xa9\x05\xb8\xef\x05"
-  "\x9e\xfb\x5a\xd4\xc8\xf5\xca\xdc\xe7\x81\xfb\x96\x9c\xa5\xdc\xc7"
-  "\xc7\x70\xb7\x22\xf7\xad\x56\x33\x6f\x37\xf3\xdc\xb7\x14\xb9\xef"
-  "\x04\xb4\x91\x8f\xa4\xdc\xa7\x70\x96\xfb\x36\xcc\x90\xb6\x93\xf8"
-  "\x03\xf6\xb5\x93\x0d\xc7\x6c\xb5\x93\xce\x34\x67\xdb\xc9\x86\x6a"
-  "\x69\x3b\x89\xcf\xe2\xdb\xee\x69\xc7\xdb\x49\xfc\x86\xae\x76\xf2"
-  "\x92\x65\x3b\x89\x7f\x4d\xda\x4e\xe2\x43\x69\x7b\x88\x2f\xa1\xed"
-  "\x24\x3e\x9c\x6f\x3f\x75\xe2\x74\x73\x3b\xa1\xe9\xb4\x9d\xc4\x1f"
-  "\xee\x9f\x2f\xbf\xde\xfc\x7d\xe2\x94\xfe\xf9\x72\x67\xfb\x8c\xf1"
-  "\xd5\xae\xf5\x19\x37\x1e\xec\x1f\x6f\x77\x56\xf7\x89\x89\xae\xe9"
-  "\xfe\x55\x9b\xfb\xdf\xf4\x8f\x95\xf4\xa6\xfb\x8d\x06\xd7\x74\xbf"
-  "\xa9\xa8\xb7\x3e\x86\xed\x58\xea\xf5\xd0\x8a\xae\x3e\xc6\xeb\xa1"
-  "\xc2\x73\xbe\xdd\xfb\x18\x9b\x2b\xa5\xef\xf1\xbd\xf6\xb4\xe5\x7b"
-  "\x7c\xbd\xf5\x3d\x0c\xfd\x7d\x0f\xb0\xf5\xab\xb1\xae\xf5\x3d\x36"
-  "\x6f\x97\xc6\x54\xc9\x03\xed\x8b\xa9\x5e\xbf\xc1\x56\x4c\x65\x70"
-  "\xba\xef\xf1\xba\xbf\x34\xa6\x7a\x5d\xcf\x63\x63\xbc\xe3\x31\xd5"
-  "\xeb\x9f\xdb\x8e\xa9\x5e\xff\x4a\x1a\x53\xbd\x5e\x44\x63\xa7\x64"
-  "\x39\x8d\xa9\x5e\xd7\xd0\xf4\xd7\xd4\xe2\x74\x73\x4c\x45\xd3\x69"
-  "\x4c\x95\xac\xec\x9f\x47\xbf\xde\x62\xaa\x2d\xa9\xfd\x7e\xdd\x59"
-  "\xdf\x92\xec\xef\x9a\x6f\x79\xe3\x2a\x3e\xff\x79\xbd\xfb\xf5\x2d"
-  "\x35\xae\xe9\x3e\xb5\xc7\xe7\x3f\x7b\xf6\xeb\x19\x01\x66\xbf\x9e"
-  "\x11\x60\xdb\xaf\xa7\xef\x91\xfa\xf5\xb4\x7b\xfa\xfd\xba\x33\x7e"
-  "\xfd\x8d\xb9\xae\xf9\xf5\xf4\x48\xa9\x5f\xcf\x38\x6d\x9f\x5f\x4f"
-  "\x3f\xe7\x7e\xbf\x9e\x6e\x90\xfa\xf5\x8c\x72\x1e\x1b\x32\xc7\xfd"
-  "\x7a\xc6\x5e\xdb\x7e\x3d\xe3\x80\xd4\xaf\x67\x6c\xa2\xfe\x3b\xa3"
-  "\x8e\xfa\xf5\x8c\xed\x34\x3d\x8d\x88\xd3\xcd\x7e\x9d\xa6\x53\xbf"
-  "\x9e\xd1\xd8\x3f\xbf\x7e\xbd\xf9\xf5\x37\x97\xf5\xfb\x16\x67\x7d"
-  "\x4b\x86\x8b\x7d\xc6\xb7\x74\xce\xfb\x96\x77\x52\xcd\xbe\xe5\x9d"
-  "\x54\xdb\xbe\xe5\x1d\x99\xd4\xb7\xbc\xfd\x66\xbf\x6f\x71\xc6\xb7"
-  "\xbc\x59\xe4\x9a\x6f\xd9\x5a\x21\xf5\x2d\xdb\xa6\xda\xe7\x5b\xde"
-  "\x79\xd8\xfd\xbe\xe5\x9d\x50\xa9\x6f\xd9\xe6\xcf\x63\xe3\x69\xc7"
-  "\x7d\xcb\xb6\x81\xb6\x7d\xcb\x36\x85\xd4\xb7\xbc\xa3\xa3\x3e\x64"
-  "\xdb\x14\xea\x5b\xde\x69\xa5\xe9\x6f\x2f\x12\xa7\x9b\x7d\x0b\x4d"
-  "\xa7\xbe\x65\xdb\x8c\xfe\x79\xf7\xeb\xcd\xb7\xfc\x4f\x8f\xcf\xff"
-  "\xf6\xcc\x6f\x3b\xc3\xcd\xfc\xb6\x33\xdc\x36\xbf\xed\xf8\x56\xca"
-  "\x6f\xdb\x5f\xee\xe7\x37\x67\xf8\x6d\x5b\xa8\x6b\xfc\xb6\xa3\x48"
-  "\xca\x6f\xbb\x46\xd9\xc7\x6f\x3b\xc7\xbb\x9f\xdf\x76\x4e\x91\xf2"
-  "\xdb\x2e\x39\x8f\x8d\xfb\x1c\xe7\xb7\x9d\xdf\xdb\xe6\xb7\x9d\xe7"
-  "\xa4\xfc\xb6\x53\x43\x79\x6c\x97\x2f\xe5\xb7\x9d\x35\x34\x7d\xfb"
-  "\x34\x71\xba\x99\xdf\x68\x3a\xe5\xb7\x5d\xfe\xae\xcd\xc7\x67\x17"
-  "\x99\xe7\xe3\xb3\x39\x5b\x98\xb6\xef\xdf\xde\x7d\x3e\x3e\xfb\x66"
-  "\xe9\x7a\x41\xbb\xf6\x70\x73\xf3\xd8\x66\x5a\xe9\x9a\x0e\x56\xe7"
-  "\xe9\x47\xed\xdf\xde\x3f\x4f\x7f\x25\xe7\xe9\xb3\x9a\xa4\xed\x27"
-  "\x67\xa1\x7d\xed\x27\x7b\x85\xfb\xe7\xe9\xb3\x2d\xd6\x61\xc9\x99"
-  "\xc1\x63\x65\xa5\xe3\xed\x27\x67\x9c\xed\xf6\x93\x33\x51\xda\x7e"
-  "\x72\xf8\x3e\x66\x4e\x28\x6d\x3f\x39\x3e\x34\x7d\x57\xb8\x38\xdd"
-  "\xdc\x7e\x68\x3a\x6d\x3f\x39\xcb\xec\x89\x0f\x0c\x9e\xc5\x35\xe8"
-  "\xef\x27\xd4\xdd\x64\xec\xc2\x79\x34\x8f\x73\x6b\xf1\xc1\xb3\xd4"
-  "\x5f\x70\xb1\xc1\xee\xc4\x4d\xbd\xc6\x07\x0d\x7c\x7c\xb0\xac\x7b"
-  "\x7c\x20\xc4\x06\x59\x80\xef\x9d\x76\xcd\xd1\xf3\x78\xc7\xd8\xe0"
-  "\x92\xa3\xb1\x41\xa0\x39\x36\x48\xb3\x88\x0d\x5e\xb0\x88\x0d\x38"
-  "\xbc\xd7\x4b\xf0\xde\x2d\x36\xe8\xc2\xbb\xbb\x62\x83\xdc\xba\xfe"
-  "\x39\x7a\x67\xfb\x9d\x39\xb1\xae\xf5\x3b\xdf\x0d\xed\x1f\xcb\x77"
-  "\x56\xf7\x79\x2e\x8e\xe5\xff\xb9\xa6\x7f\xbc\xc5\x59\xdd\xbf\xeb"
-  "\xe2\x5a\x0e\xbb\xe7\x3a\xdf\x1f\x29\xf0\x33\xf7\x47\x0a\xfc\x84"
-  "\xf8\x0a\x79\x97\x5b\x33\x0b\xb8\x36\x2d\x0a\x8e\x4b\x84\xbc\x11"
-  "\xc5\xed\x79\xe0\xa1\x6d\xf8\x12\xf7\x7c\x83\x98\x2b\xff\xcd\x90"
-  "\x58\x71\xcc\xb5\xe7\x06\x21\xde\x0a\xc1\x58\x0c\x62\x2b\x8c\xab"
-  "\x84\x3e\x48\x66\x73\x2f\xcf\x0f\x8f\x4b\xdc\x84\x7d\x96\x4e\x45"
-  "\x71\xcd\x2f\xb7\xbf\xf2\xbf\x7e\xae\xf5\x57\xf2\x17\x49\xe3\xad"
-  "\x82\xcf\xec\x8b\xb7\xf2\xbf\x72\x7f\x7f\x25\xbf\x51\x1a\x6f\x15"
-  "\x1c\xa4\x65\xda\x5d\xe9\x78\xbc\x55\xf0\x8e\xed\x78\xab\x20\x5b"
-  "\x1a\x6f\x15\x44\xd2\xb8\xaa\xa0\x9c\xc6\x5b\x05\x9b\x68\xfa\xee"
-  "\x0a\x71\xba\x39\xde\xa2\xe9\x34\xde\x2a\xa8\xb1\x33\xde\xaa\x75"
-  "\x21\xde\x4a\xbe\x7e\xe2\xad\x7b\xae\xf1\x78\x6b\xef\x2c\x3b\xfc"
-  "\x4e\x8d\x85\xdf\xd9\xd4\xef\x77\x90\x6b\x0a\x1a\x5d\xf3\x3b\x7f"
-  "\xb1\xb9\xff\x61\x97\xee\x53\x45\xba\x47\xce\xe7\xf5\x6e\xf4\x4f"
-  "\xdc\xe4\xb4\xee\x81\xeb\xb3\xe3\xaf\x67\xbd\xef\xdd\xea\x9a\xde"
-  "\x8b\x82\xfa\x63\x2d\x67\x75\xff\x57\xa5\x6b\xba\xdf\x77\xd8\xf9"
-  "\x58\xab\xa4\xf0\x54\x57\xac\x55\x52\x68\x19\x6b\x61\x6c\x35\xbb"
-  "\x9d\xc6\x5c\x6f\x40\xac\x94\xb2\x0a\xe2\xae\x18\x42\xb4\x0d\x47"
-  "\x48\x2a\xc4\x5e\x29\xe7\x21\xfe\x0a\x87\xf8\xcb\xb0\x87\x8f\xbf"
-  "\x4a\xc6\x48\xe3\xaf\xe2\x77\xac\xc6\x5f\x0a\x73\xfc\x65\x80\xd8"
-  "\xaa\x73\x4f\xe2\xa6\xcc\xf3\xa2\x58\xec\xc5\xee\xb1\x58\x47\x5a"
-  "\x71\x6d\xc7\xb8\xc4\xe4\x4e\x88\xc7\x7a\x8a\xc5\x38\x4c\x58\x89"
-  "\xc7\xfe\x3b\x62\xb1\xa2\x64\xd7\x62\xb1\xfd\x8d\xd2\x58\xec\xc0"
-  "\x02\xfb\x62\xb1\x92\xe5\x36\xc7\xbe\x9c\x8e\xc5\x4a\xa2\xa5\xb1"
-  "\xd8\x81\x20\x1e\x33\x53\x1d\x8f\xc5\x0e\xdc\x6c\x3b\x16\x3b\x30"
-  "\x5e\x1a\x8b\x95\xf0\xef\x9e\x1e\x98\x4f\x63\xb1\x03\x4a\x9a\x5e"
-  "\x3c\x45\x9c\x6e\x8e\xc5\x68\x3a\x8d\xc5\x0e\x2c\xb1\x73\x6e\xac"
-  "\xc6\x00\x3e\xfd\xea\x3f\x4f\xd9\xd3\xdc\x98\xbb\x9e\xa7\x0c\xbc"
-  "\xc6\xe7\xc6\xde\xeb\x7d\xfc\xab\x3f\x26\xb0\xc2\x35\x07\xa2\x5d"
-  "\xf3\x4b\x07\xe7\xf7\xc7\x04\xce\xea\xfe\x6f\x2e\x8e\x7d\xbd\x5f"
-  "\xed\x7c\x4c\x50\x9a\x65\x1e\x7f\x29\xcd\x72\x6c\xfc\xa5\x74\xb8"
-  "\xd4\xff\x7f\x60\xdd\xff\xf7\x8f\xbf\x38\xe0\xf3\x0f\x66\xb9\xe6"
-  "\xf3\x3f\xac\x93\xfa\xfc\x43\x0f\xdb\xe7\xf3\x4b\x17\xba\x7f\xfc"
-  "\xa5\x34\x4c\xea\xf3\x0f\x05\xf2\x38\x99\xed\xb8\xcf\x3f\x74\x83"
-  "\x6d\x9f\x7f\x68\x8c\xd4\xe7\x97\xea\xa9\x6f\x3f\x14\x4c\x7d\xfe"
-  "\x21\x39\x4d\xff\x60\x96\x38\xdd\xec\xf3\x69\x3a\xf5\xf9\x87\xe6"
-  "\x3b\x36\xdf\xe5\x7d\x8d\xce\x77\x29\x7f\x21\xf3\x5d\x1f\x55\xf4"
-  "\xfb\x1d\x67\xfd\xce\xa1\x30\xd7\xfc\xce\xe1\x5e\xd7\xff\xb0\xed"
-  "\x77\x8e\xfa\x98\xfd\xce\x51\x1f\xc7\xfc\xce\x27\x5b\xa4\x7e\xe7"
-  "\x88\xa2\xdf\xef\xb8\xea\x77\x3e\xf6\x71\xcd\xef\x7c\x62\xb1\xfe"
-  "\xd1\x51\x3b\xd7\x3f\xfa\xc4\xe6\xfa\x47\xce\xfb\x9d\x4f\x74\x52"
-  "\xbf\x73\x94\x5f\xff\xe8\xb0\x13\xeb\x86\x1c\x4d\xb3\xed\x77\x8e"
-  "\x5a\xac\x7f\x74\x94\x5f\xff\xe8\x28\xbf\xfe\xd1\x51\x7e\xfd\xa3"
-  "\xc3\x65\xe2\x74\xb3\xdf\x39\x2c\x5a\x37\xe4\x68\xff\xfa\x47\xd7"
-  "\xdd\x73\x98\xc7\x5c\xe0\xbf\xe3\xad\x66\xfe\x3b\xde\x6a\xfb\x39"
-  "\xcc\xe3\x2b\xa4\xcf\x61\x1e\xbb\xdc\xff\x1c\xa6\x33\xfc\x76\xd4"
-  "\xc5\x75\x91\x8e\x07\x4a\xf9\xad\xec\x5d\xfb\xf8\xed\xf8\x01\xf7"
-  "\xf3\xdb\x71\x8d\x94\xdf\xca\x52\x79\x6c\x38\xc1\x6f\x65\x2b\x6d"
-  "\xf3\x5b\xd9\x1a\x29\xbf\x95\x05\x53\x1e\x2b\xcb\xa3\xfc\x56\xb6"
-  "\x88\xa6\x1f\x2b\x13\xa7\x9b\xf9\xed\x98\x88\xdf\xca\x8a\x1c\x9b"
-  "\xd7\x74\x2a\xae\xee\x83\x79\x4d\x77\xc5\xd5\xd7\xfa\xbc\xe6\xdf"
-  "\xfd\xfb\xc7\xd1\x9c\x89\xa9\xcb\x34\xae\xc5\xd4\xff\xc8\x72\xde"
-  "\xa7\x9c\x4c\x34\xfb\x94\x93\x89\xb6\xe6\x77\x52\x00\x77\xa9\x10"
-  "\x13\x6f\x39\x4f\xe4\x6f\xe0\xfc\x4e\x4d\x25\x49\xc3\xf9\x9d\x55"
-  "\xc2\xfc\x4e\x36\x1f\x67\x7f\x76\x51\x1a\x67\x97\xaf\xb1\x16\x67"
-  "\x63\x7c\x6d\x84\xd8\xd9\x60\x39\xaf\xf3\xa4\x75\x5f\xd4\xa1\x28"
-  "\xae\xbd\xbc\x27\x31\xd9\x51\x5f\xb4\x6b\x1d\xf5\x45\x3b\xaf\x7b"
-  "\x5f\xf4\xf7\x70\xd7\x7c\xd1\x67\x1a\xa9\x2f\x3a\x35\xd1\x3e\x5f"
-  "\x74\xf2\x3e\xf7\xfb\xa2\x93\xb3\xa4\xbe\xe8\x94\x2f\x8f\x15\x27"
-  "\xf6\x96\x3c\x79\xd9\xb6\x2f\x3a\x25\x93\xfa\xa2\x93\x35\xd4\xe7"
-  "\x9c\x9a\x40\x7d\xd1\xc9\x46\x9a\x5e\xee\x2b\x4e\x37\xfb\x22\x9a"
-  "\x4e\x7d\xd1\xa9\x29\x8e\x8d\xf1\x0c\xbe\x46\xc7\x78\x3c\x7e\x21"
-  "\x63\x3c\x15\x25\xce\x73\xa2\x36\xba\xa2\xeb\xfd\x0d\x6d\x74\xb7"
-  "\x71\x86\x18\x88\xb7\x9b\xe9\x3c\x77\xd7\x38\x83\xee\x34\xcf\x7f"
-  "\x55\x3f\x4a\xf9\xaf\xd2\x26\xff\xf5\x34\x97\x8d\xe3\x0a\x46\xe0"
-  "\x46\xdc\x23\xd3\xe9\xb9\xec\x98\xeb\x9d\xf3\x4e\xb9\xb8\xbe\x72"
-  "\xd5\x41\x29\xe7\x55\xdf\x6c\x1f\xe7\x69\xef\xb4\xc9\x79\x4e\xbf"
-  "\xc7\xa1\x0d\x92\x72\x5e\xb5\x27\x8f\x8f\x89\x8e\x73\x9e\xf6\x9c"
-  "\x6d\xce\xd3\x5e\x94\x72\x9e\xb6\x9c\x72\x5b\xb5\x8a\x72\x9e\xb6"
-  "\x8e\xa6\x57\x4e\x10\xa7\x9b\x39\x8f\xa6\x53\xce\xab\x9e\xd0\x13"
-  "\xe7\xb1\xa9\xd1\xb5\x99\x8c\xa9\x04\x8e\x52\x28\xe3\x28\xc0\x86"
-  "\x06\xbe\x97\x83\x8d\x47\xc0\x77\x9b\xf3\x4b\x7a\x45\x74\xad\x29"
-  "\x09\xca\xcc\x10\x99\x56\x7f\x41\xa3\x19\x6d\x40\xdb\xf0\xef\xac"
-  "\x45\xd7\x7a\x1b\x06\x07\x9b\xd8\x30\x02\x76\xa9\xe5\xf6\xcf\x04"
-  "\x79\x7c\x3f\x48\x15\x43\xbc\xce\xcb\xaa\x2b\x04\x39\x28\xaf\x57"
-  "\xbd\xac\x7a\x0b\xe6\x01\x65\xad\x85\xba\x4c\xb1\x59\x56\xc8\x2b"
-  "\x64\xef\x58\xb2\xc1\xc0\xfe\xa0\x59\xd5\x4c\x1a\x64\x9f\xdf\xec"
-  "\xdd\x34\x38\x98\x4d\x08\x25\x18\xcb\x95\x8c\xd6\xcb\x31\x4f\xcd"
-  "\xaa\x0e\x3c\x27\xc7\x73\x46\x28\x63\xfc\x4a\xc2\xa4\x37\x0f\xf6"
-  "\x00\x9e\x18\x98\xd0\xca\x36\x46\x18\xa0\xcc\x80\xcd\xa3\x63\x6b"
-  "\xe5\xfb\x77\x42\x9a\x91\xf8\xe2\x7e\xa6\x98\x07\xc4\xb3\x50\x9e"
-  "\xcf\xc7\xe5\x80\xbc\xb5\x32\xbc\x56\x4c\x26\x0c\x1c\xcf\xea\x1c"
-  "\xc3\xcd\xe7\xb1\xb6\xf4\xe8\xbd\x71\x2c\xd1\xdc\x0e\xba\x53\x11"
-  "\xc6\xda\x79\x07\xef\xa3\xeb\x81\x2f\x3d\x70\x8f\xe4\x84\x1d\x84"
-  "\xc9\x30\x0d\xf6\x38\x1e\xc7\xed\x51\xac\x6f\xdb\xfc\xc5\x2c\x9d"
-  "\x6c\x32\xb7\xe7\x2f\xee\x6b\x89\xfb\x6b\x03\x6e\x08\xa4\x2f\x3b"
-  "\x06\xa5\xb6\xb4\x45\xd4\xb2\x95\x4b\x55\xd1\x2b\x56\x2e\x8f\x58"
-  "\x13\xad\x1a\xb7\x6c\x28\x99\x1f\x11\xa1\x5a\xb9\x74\xd5\x2b\x2a"
-  "\xf1\x99\x7b\x55\xcb\x56\xac\x5e\xfa\x6c\xf8\xf2\x89\x2b\x9f\x8b"
-  "\x1c\x8a\x2f\x21\x89\xca\xe1\x83\x65\x31\x6d\xfe\x22\x32\xe7\x2d"
-  "\x42\xde\x1e\x41\xe4\x58\x2e\xb8\x5f\x8d\xb0\xef\x69\xfa\x36\xb6"
-  "\x95\x01\x99\x04\xe0\xc7\x8c\xf8\xc1\x20\xfb\xb9\x2e\x17\xca\x95"
-  "\x03\xe5\x86\x32\x42\x99\xff\x49\x84\x32\x0b\x98\x48\x40\x4c\xc4"
-  "\x37\x03\x06\xff\x79\xb3\x77\xfb\xe0\x87\x58\x36\x14\xeb\x87\xef"
-  "\x43\xcb\x20\xed\x65\xce\x97\xa5\x45\xd7\xc2\xb5\xd3\x04\x8c\xe1"
-  "\xb5\x6c\x7a\x74\x5e\x1b\xb6\x13\x36\xec\x7e\xda\xa6\x6a\x7c\x16"
-  "\xa8\x65\x84\xee\xbb\xfa\xcf\x30\xf3\xbe\xab\x35\xdc\x58\x35\x94"
-  "\xa3\x09\xd2\x13\x75\xb2\xc1\x99\x98\x8e\xfb\x05\xe3\xfe\xdd\x58"
-  "\x66\xa8\x17\xf8\x52\x56\xc3\x26\xf1\xd8\x4f\xfe\x87\x87\x29\xf9"
-  "\x87\x60\xad\xfc\x12\x09\x31\xb0\x9d\xec\x96\x7f\x78\x54\xb5\xb6"
-  "\x12\xef\x8d\x91\xcf\xb1\x83\xbe\xd8\xe8\x6d\x58\xb1\x3c\x77\x04"
-  "\xb4\xa1\x2d\x3f\x04\xb3\x5b\x74\xe5\x0b\xc6\x13\x25\xe4\x2d\xde"
-  "\xff\x55\xee\x98\xfd\xff\xc9\xd9\x1f\xed\x08\xe5\xe1\xed\x58\x33"
-  "\xe1\x58\x74\x77\x3b\x76\xe1\x6f\xaf\x89\x9c\x00\x2c\xb0\x9e\x7b"
-  "\x54\x21\x46\xaa\x47\x6c\xbb\x2d\x09\x61\x64\x12\xa7\xbb\x9a\x06"
-  "\x53\xfa\x1e\xe8\xe3\xed\x99\xc2\xa6\xee\xf1\x07\x9d\x95\xa6\xc7"
-  "\x10\xd5\x62\xa3\x92\xa4\x5d\x22\x01\xfa\xb4\x3d\x2a\x85\x2c\x51"
-  "\x06\xf1\x08\x03\xfe\x24\x00\x38\x23\x80\x6f\xef\xa5\xa8\xc7\x7f"
-  "\x34\x11\x32\x67\x35\x21\x3f\x4c\x23\x03\x72\xe0\x3a\xc7\xea\x53"
-  "\xc3\xf9\x7f\x76\x73\x4d\x58\x2e\x5c\x8b\xfb\xfa\x3a\x78\xbd\xde"
-  "\x66\xbb\x33\xd7\x3b\xcf\x7a\xbd\xbf\xac\x83\x7a\x27\x42\xbd\x4b"
-  "\xa1\xde\xbb\xad\xd4\x3b\x8f\xd6\x7b\x60\xb3\xfb\xeb\xfd\x25\x5d"
-  "\xff\x7a\xf3\x97\x4b\x9c\xab\xf7\x97\x8d\xbd\xd7\x3b\xdf\x86\xbd"
-  "\xff\xaf\xc6\x94\x9e\x0f\xf6\xce\x07\x7b\xe7\x5b\xb1\x77\x3e\x6f"
-  "\xef\x61\xf5\xee\xaf\xf7\xff\xe5\xd1\x7a\xff\x5f\xa8\x73\xf5\xfe"
-  "\x3f\x9b\xfc\x27\xaa\xb7\x0d\x7b\xff\xab\x02\xea\x0d\xf6\xce\x07"
-  "\x7b\xe7\x5b\xb1\x77\x3e\x6f\xef\xe1\x5f\xb8\xbf\xde\xff\xa2\xeb"
-  "\x1f\x6e\xfe\xd7\x5c\xe7\xea\xfd\xaf\xda\xde\xeb\x5d\x60\xc3\xde"
-  "\xb5\x65\xa6\xf4\x02\xb0\x77\x01\xd8\xbb\xc0\x8a\xbd\x0b\x78\x7b"
-  "\x4f\x4e\x71\x7f\xbd\x6b\x33\x69\xbd\x6b\x83\x9d\xab\x77\xad\xcd"
-  "\xf8\x44\x54\x6f\x1b\xf6\xfe\xea\x30\xd4\x1b\xec\x5d\x00\xf6\x2e"
-  "\xb0\x62\xef\x02\xde\xde\x4f\x4d\x77\x7f\xbd\xbf\x4a\xa6\xf5\xfe"
-  "\x2a\xc8\xb9\x7a\x7f\x65\xf3\xf9\x77\x11\xaf\xa9\x81\xbb\xba\xd9"
-  "\x5c\x1b\x3b\x85\xdc\x71\x09\xeb\xff\xef\x09\xac\x62\x8f\x7a\xd8"
-  "\xc6\x44\x99\xc1\x73\xcf\x84\x61\xd0\x97\xdb\x95\x64\x0a\xf3\xd6"
-  "\x91\x21\x50\xd7\x30\x36\x7d\xaf\x06\x3f\x4d\x90\x8f\x01\xb8\xdf"
-  "\xe8\xb9\xc7\xbf\x23\x35\xba\xf4\x8d\xe7\x89\x2a\x41\x4f\x94\x55"
-  "\xf1\x3a\x12\x1f\xc9\xea\xab\xc8\xb7\x44\xa1\x23\x0c\x8e\x97\x9d"
-  "\x6a\x2a\x25\xab\xa2\x58\x16\xf2\xbe\x01\xfb\x98\xe9\x67\x48\x00"
-  "\xc4\xc4\x89\x2c\xf8\x8f\x4c\x13\x51\x41\xfe\x01\xa8\x4b\xc8\xfb"
-  "\x53\xef\xf9\x44\xf6\xc9\xb3\xed\x04\xf5\x89\xba\x85\xfe\x68\x00"
-  "\xa7\xd7\x56\x42\x1e\x7d\x8a\xea\x75\xd7\xf3\x8e\xea\xf5\x6b\x3a"
-  "\xff\x97\xba\x27\x48\xab\xeb\x20\x10\x5b\x2a\xf1\x9d\x7b\x48\xcf"
-  "\xaa\x8a\x6c\x86\xbe\xc8\xd7\x41\x6c\xda\x9e\x00\x13\xf8\x2c\xc7"
-  "\xf2\xfd\xb7\xcd\xf5\xaf\x45\xfa\x2e\x04\x7d\x77\xc3\x9a\x59\xdf"
-  "\x75\x59\xa0\xef\x42\x5e\xdf\x45\xc3\xea\x06\x36\xdb\xd0\x77\x21"
-  "\xe8\xbb\x14\xf4\xbd\xdb\x7e\x7d\xd7\xbd\x66\xa1\xef\xc4\xbe\xd1"
-  "\x77\x1d\xbf\xff\xe9\x1e\x8d\x54\xdf\x75\x9e\x54\xdf\xff\x2e\x01"
-  "\x7d\x97\x80\xbe\xf3\x1c\xcc\xb7\xd0\x0e\x1e\x07\x7c\x77\xf7\x61"
-  "\x66\x7d\xff\xc7\x93\x55\xe4\xf3\xf8\xce\x07\x7c\x0f\xab\xb7\xae"
-  "\xef\x7c\xc0\x77\x3e\xe0\x3b\xdf\x01\x7c\x9f\xbe\x28\xd5\x77\x7e"
-  "\x1f\xe1\xfb\x34\x3f\xfe\x97\x6f\x81\xef\xd3\x71\x54\xdf\xa7\x55"
-  "\x6c\x5a\x3e\xe0\x3b\xdf\xc1\x7c\xff\xe3\x6b\x87\xbe\x01\xdf\xdd"
-  "\x7d\xa7\x59\xdf\xdf\xc4\x81\xbe\x79\x7c\xe7\x03\xbe\x87\x7f\x61"
-  "\x43\xdf\x80\xef\x7c\xc0\x77\xbe\x03\xf8\xfe\x66\xb9\x85\xbe\xfb"
-  "\x08\xdf\xdf\x04\xf0\xfa\xb6\xc0\xf7\x7f\x9a\xa8\xbe\xff\x93\x09"
-  "\xfa\x06\x7c\xe7\x3b\x88\xef\x6f\x92\xed\xf0\x5b\x80\xef\xee\x3e"
-  "\xdb\xac\x6f\x5d\x13\xab\x28\xe0\xf1\x5d\x00\xf8\x9e\x9c\x62\x5d"
-  "\xdf\x05\x80\xef\x02\xc0\x77\x81\x03\xf8\xd6\x7d\x29\xd5\x77\x41"
-  "\x1f\xe1\x5b\x47\xe3\xbf\xd4\x02\x0b\x7c\xeb\x16\x51\x7d\xeb\x08"
-  "\x9b\x56\x00\xf8\x2e\x70\x34\xdf\x76\x3b\xf4\x0d\xf8\xee\x1e\x2b"
-  "\x98\xf5\x5d\xbf\x08\xf4\xcd\xe3\xbb\x00\xf0\xfd\xd4\x74\x1b\xfa"
-  "\x06\x7c\x17\x00\xbe\x0b\x1c\xc0\x77\xfd\x4c\x0b\x7d\xf7\x11\xbe"
-  "\xeb\xf9\xfd\x2f\x0b\x2c\xf0\xfd\x6d\x05\xd5\xf7\xb7\x91\xa0\x6f"
-  "\xc0\x77\x81\x83\xf8\xae\x0f\x73\x26\x3e\x59\x9d\x4d\x3c\xa4\x3a"
-  "\xff\xae\xfa\xca\xc5\x28\xdf\x1d\xba\x3a\x31\xca\x77\x9b\xac\xc7"
-  "\x28\xdf\x05\x51\x9d\xd7\x37\x38\x17\xa3\x7c\x67\xf3\xfd\x87\x9e"
-  "\x62\x94\xee\x3a\xff\x7e\xc6\x95\x8b\x53\xbe\x9f\x78\x75\xe2\x94"
-  "\x86\x76\xeb\x71\x4a\xc3\x41\xaa\xf3\x86\x50\xe7\xe2\x94\xef\x6d"
-  "\xae\x7f\xd0\x53\x9c\xd2\x5d\xe7\x67\x4a\xaf\x5c\xac\x72\xe6\xdd"
-  "\xab\x13\xab\x9c\x09\xb7\x1e\xab\x9c\x51\x53\x9d\x7f\x5f\xe1\x5c"
-  "\xac\x72\xa6\xcc\x99\x58\xa5\xbb\xce\x1b\x27\x5c\xb9\x78\xa5\xf1"
-  "\x86\xab\x13\xaf\xfc\xa0\xb3\x1e\xaf\xfc\xc0\xf7\x7f\x7e\x08\x72"
-  "\x2e\x5e\x69\xb4\xa3\xff\xd3\x3d\x5e\xe9\xae\xf3\x1f\xf3\xae\x5c"
-  "\xcc\xf2\xe3\x96\xab\x13\xb3\xfc\x38\xdf\x7a\xcc\xf2\xa3\x92\xea"
-  "\xbc\xf1\xa0\x73\x31\xcb\x8f\x36\xf7\x3f\xe9\x29\x66\xe9\xae\xf3"
-  "\x9f\x7c\xae\x5c\xdc\x72\xd6\x78\x75\xe2\x96\xb3\xe5\xd6\xe3\x96"
-  "\xb3\x9b\xa8\xce\xcf\xaa\x9d\x8b\x5b\x7e\x52\x39\x13\xb7\xa0\xae"
-  "\x51\xe7\x18\xab\x50\x9d\x9f\x6b\x60\xbd\xf6\x90\x4e\x88\x47\x14"
-  "\xa0\x77\x45\x13\x61\xb2\x51\xe7\xb5\x54\xe7\x46\xaf\xbd\x1a\xd0"
-  "\x4f\x18\xea\x8c\xab\xc7\x4f\xbe\x5e\xc6\xd4\x3d\x13\x58\x86\x40"
-  "\x5d\x3c\x08\xd8\xec\x67\x43\x12\xf1\x52\xc5\x6f\x84\xef\xe7\xbe"
-  "\x44\x19\x55\xfc\xe6\xd3\x50\xc7\x01\x38\x47\x61\x48\x8b\x5e\x62"
-  "\x54\x14\xea\xe0\xdc\x9d\xec\x98\xc8\x25\x9d\x10\x4b\xb0\x2f\xf9"
-  "\xfa\x68\x9b\x4a\x88\xd6\x70\x92\x54\xd5\x7e\x44\x4c\x5e\x7b\x3f"
-  "\x9d\x64\x20\x6a\xf6\x27\xb5\x4f\x45\xb4\x8e\x18\x9f\xf3\xf5\xd4"
-  "\xc6\x96\x03\x2e\xde\x23\x21\x8d\xec\x25\xf6\x3b\xb5\x67\xa7\xa2"
-  "\x58\x65\x54\xec\xcd\x33\xa6\x15\x37\x1a\x14\xc5\xca\x7d\x31\x3a"
-  "\xc6\xb3\x9d\xa8\xc3\x1b\x58\x36\xfd\x59\x22\x4f\xaf\x27\x1e\x19"
-  "\xcf\x12\xcf\x8c\x7a\xa2\xac\x68\xa8\x25\x95\xa0\xf6\xca\xe6\xaf"
-  "\x48\xe5\x25\x38\x3a\xe0\x30\xc1\x91\xf8\x15\xa9\x68\x22\x64\xf6"
-  "\x39\x42\x12\x1a\x58\xfd\x6f\xeb\x88\x4f\x85\xa1\x96\xa8\x9e\x21"
-  "\xe4\xbc\xac\xe9\x84\xe7\x12\xe2\xc3\x7e\xe7\x4b\xd8\xe7\x7c\x19"
-  "\x38\x27\xc7\x74\xad\x41\x4f\x2a\xc0\x25\xc3\xf9\xdd\x70\x5e\x9e"
-  "\xd0\x00\xf9\x9b\xca\x71\x2d\x43\x7d\x45\xe2\x67\x50\x3f\xff\xb9"
-  "\xa0\xe7\x29\x42\x4c\x96\xde\x41\x02\x32\xc0\xcc\x88\x99\x10\x96"
-  "\x62\x26\xb7\xc3\x51\xcc\x34\xd1\xf5\xdf\x5f\xf2\x1d\x01\xfa\x1e"
-  "\x6d\x7a\x29\x54\x39\xe7\xab\x6f\x58\x7c\x1e\x0c\xe7\x67\xaa\x5a"
-  "\x4f\x12\x9c\xb3\x0e\x79\x85\x90\x59\x46\x42\x50\x27\x38\x97\x3c"
-  "\x27\x92\x78\xe3\x73\x6a\xa6\x9f\xd4\x23\xb4\x0d\x7a\xb2\xc1\x00"
-  "\x65\x3d\xdf\xde\x55\xd6\xaa\x4d\x55\x04\xce\x8d\xae\x0a\xd3\x11"
-  "\xcf\x48\xa2\x44\x3d\x43\x5c\xa4\x9e\xd3\x48\x86\xac\x6a\x65\x59"
-  "\xd4\x31\xea\x16\xf5\x8c\xf9\x09\xba\xd7\x2e\xd3\x93\x84\x76\xa2"
-  "\xd4\xc6\xc3\x67\x2c\xab\xd7\x92\x9f\x09\x94\xb1\x96\x55\xf8\xcf"
-  "\x05\x7c\x94\x21\x26\x00\x8f\x8d\x80\x83\x11\xec\xe6\x9f\xb2\x72"
-  "\xa0\xbe\x38\xb7\xef\x58\x9d\xcf\xd9\x33\xff\xd1\x2d\x26\x14\xe1"
-  "\xb9\x90\xe2\x59\x7f\x10\xf0\x9c\x08\x78\xde\x4d\xf1\x3c\xb0\xd9"
-  "\x0e\x3c\x17\x99\xf1\x7c\xfe\x98\x19\xcf\xfa\x3d\xb6\xf1\xac\x97"
-  "\xf1\x78\xd6\x5c\x9b\x78\xbe\xf0\x4e\xcf\x78\xbe\x10\xdd\x03\x9e"
-  "\x4b\x85\x78\xd7\x3d\x78\xbe\x50\xd1\x87\x78\x2e\x74\x0e\xcf\x17"
-  "\x0a\xa5\x78\x3e\x5f\x4a\xf1\x7c\x3e\xdc\x39\x3c\xeb\x35\xce\xc4"
-  "\xdb\x66\x3c\xe7\xf3\xfc\xdc\xb2\x89\xf5\xca\x07\x7e\xce\xe7\xf9"
-  "\x79\x58\x7d\xef\x78\xce\x17\xf1\xf3\xcf\x6f\x9a\xf1\xdc\xb2\xc6"
-  "\x36\x9e\x9b\x3f\xa7\x78\xce\xbf\x46\xf9\xb9\x79\x79\xcf\x78\x6e"
-  "\x9e\x61\x1b\xcf\xf9\x53\x84\xbe\x84\x7b\xf0\xdc\x9c\xd5\x77\x78"
-  "\xce\x77\x92\x9f\x9b\x63\xa5\x78\xfe\x39\x99\xe2\xf9\xe7\x69\xce"
-  "\xe1\xb9\x25\xd3\x99\xbe\x8c\x08\xcf\x3c\x3f\x5f\x9a\x0f\x78\x06"
-  "\x7e\xce\xe7\xf9\x79\xf8\x17\x76\xe0\x59\xc4\xcf\xad\x4b\xcd\x78"
-  "\xbe\x34\xd3\x36\x9e\x2f\xbe\xcb\xe3\xf9\x1a\xe5\xe7\x8b\xf7\xf4"
-  "\x8c\xe7\x8b\x3e\x3d\xe0\xb9\x54\xe8\xa7\xb9\x07\xcf\x17\xc3\xfb"
-  "\x10\xcf\x4e\xf2\xf3\xc5\x60\x29\x9e\x5b\x43\x29\x9e\x5b\x3d\x9d"
-  "\xc3\xf3\xa5\x25\xce\xf4\x13\xcd\x78\x2e\xe0\xf9\xf9\xb2\x3f\xeb"
-  "\x55\x00\xfc\x5c\xc0\xf3\xf3\xe4\x94\xde\xf1\x5c\x20\xe2\xe7\xb6"
-  "\x3b\xcd\x78\xbe\x7c\x83\x6d\x3c\xb7\xbf\x4c\xf1\x5c\x70\x8d\xf2"
-  "\x73\xfb\xc0\x9e\xf1\xdc\xd6\x60\x1b\xcf\x05\x53\x84\x3e\xb0\x7b"
-  "\xf0\xdc\x3e\xad\xef\xf0\x5c\xe0\x24\x3f\xb7\xfb\x4a\xf1\xdc\xa6"
-  "\xa6\x78\xbe\x54\xe7\x1c\x9e\x2f\xdb\xdc\xff\xb5\xa7\x3e\xb8\x08"
-  "\xcf\x3c\x3f\x77\xb6\x02\x9e\x81\x9f\x0b\x78\x7e\x7e\x6a\xba\x1d"
-  "\x78\x16\xf1\x73\x87\xcc\x8c\xe7\xce\xef\x6d\xe3\xb9\xf3\x01\x1e"
-  "\xcf\xd7\x28\x3f\x77\x7c\xd9\x33\x9e\x3b\x0e\xf6\x80\xe7\x52\x61"
-  "\x7c\xc1\x3d\x78\xee\xf4\xec\x43\x3c\x3b\xc9\xcf\x1d\x8d\x52\x3c"
-  "\x5f\x6e\xa7\x78\xbe\x5c\xe4\x1c\x9e\xb1\x0b\xec\x8e\xf1\x0d\x53"
-  "\x2b\x8e\x6f\x74\xe0\xf8\x86\xf9\xd9\xbf\x30\xef\x6a\x8a\xe7\x4e"
-  "\xc0\xf3\x2e\x31\x9e\xff\x6d\x39\xbe\x61\xf8\xdc\xd4\x85\x67\x53"
-  "\x37\x3c\x9b\x00\xcf\x9d\x1c\x9e\x8d\x46\x61\x7c\x43\xdb\x94\x07"
-  "\x38\x39\x4b\xb4\x73\x01\xcb\xe9\x3c\x96\xff\x0d\x58\x06\x1d\x9a"
-  "\x40\xc7\x15\x75\xb5\x24\x44\x4f\x75\xd9\x01\x3a\x36\x89\x71\xdc"
-  "\xd1\xc8\x20\x7e\x11\xb7\x02\x86\x2b\x57\x01\x76\xa3\x3e\x27\x95"
-  "\x31\x70\xac\x83\x23\x1e\x0e\xf2\x39\xa9\x68\x04\xec\xae\x10\x63"
-  "\xb7\x9a\xc7\xae\xf1\xcd\x9e\xb1\x6b\x8c\xec\xbb\xb1\x0c\x23\x1d"
-  "\xff\xfa\x77\xa8\x32\x64\xde\x37\xac\x36\xb6\x96\xc7\xe7\x59\x12"
-  "\x62\x20\xde\xec\x53\xea\x11\x9e\xa1\x44\xb9\xde\x48\x98\xb4\x67"
-  "\x89\x32\xed\x6b\xa8\xb7\xd0\x7e\xeb\x89\xe7\xc9\xf6\x8f\x48\x45"
-  "\x73\x2d\xa9\xb8\xf4\x19\xa9\x30\xc1\x71\x16\x0e\x28\x6b\xc8\x72"
-  "\x71\xbd\xf5\x7c\xbd\x4d\x5b\x20\x2f\x7f\xdb\xf5\x36\x85\x71\xf5"
-  "\x5e\x06\xf5\xee\x30\xd7\x5b\x0b\xed\x00\xec\x33\xda\xc4\x8f\x87"
-  "\x84\xe8\xc9\x90\x08\x03\xcb\x76\xf0\xf8\x47\xfb\x9c\xac\x69\x27"
-  "\x21\x91\x60\xb3\xe7\x00\xff\x0d\x85\x24\x21\x0e\xf0\xdf\xd1\x8e"
-  "\xb8\xd3\x6b\x13\x2f\x03\xfe\x8d\xbb\x59\xd0\x5f\x27\xe2\xff\xdf"
-  "\x88\x7f\x43\xb9\x89\xc3\xbf\x21\xce\x39\xfc\xb3\xf6\xe0\xbf\xf7"
-  "\xf1\x10\x46\x86\xf8\x4f\xec\xc0\xf1\x10\xf3\x33\xa0\xbd\xe1\x5f"
-  "\xc4\xe7\xac\x19\xff\x8c\xcc\x36\xfe\x19\x22\xe0\x5f\x73\xd5\xf1"
-  "\xcf\x90\x9e\xf1\xcf\x90\x9e\xf0\xef\xde\xb1\x0f\x86\xf4\x1d\xfe"
-  "\x19\x59\xcf\xf8\x67\x64\xf6\xe0\xbf\xd0\x29\xfc\x33\xc4\x02\xff"
-  "\x2c\x8f\x7f\xd6\x39\xfc\x33\x8c\x1d\xf8\xb7\x63\xfc\x84\x91\xb7"
-  "\xe2\xf8\x49\x07\x8e\x9f\x98\x9f\x05\xee\x05\xff\xa2\xf1\x13\x86"
-  "\x11\xe1\x5f\xde\x03\xfe\x07\x18\x85\xf1\x93\xab\x8f\xff\x01\xbd"
-  "\xe0\x7f\x40\x0f\xf8\x77\xf3\x58\x09\x33\xa0\x0f\xf1\x2f\xef\x05"
-  "\xff\x72\x3b\xf0\x9f\xef\x1c\xff\x33\x03\xa4\xf8\x67\x18\x8a\xff"
-  "\x14\xc6\x49\xfc\x0f\xb4\x07\xff\xbd\x8f\xb7\x30\x83\x11\xff\xc0"
-  "\xff\xf9\xbb\x45\xcf\x84\xf7\x86\x7f\x33\xff\x33\x03\x45\xf8\x1f"
-  "\xdc\x03\xfe\x07\x09\xf8\xbf\x06\xf8\x7f\x50\x2f\xf8\x1f\xd4\x13"
-  "\xfe\xdd\x3b\xb6\xc2\x0c\xea\x43\xfc\x0f\xee\x05\xff\x83\xed\xc1"
-  "\xbf\x93\xfc\x3f\xc8\x02\xff\x03\x79\xfc\x0f\x74\x12\xff\x1e\x76"
-  "\xe0\xdf\x8e\xf1\x19\x66\x28\xf6\x67\x81\xff\x0b\xfc\x45\xef\x06"
-  "\xf4\x82\x7f\xd1\xf8\x0c\xe3\x21\xc2\xff\xd0\x1e\xf0\x3f\xc4\x28"
-  "\x8c\xcf\x5c\x7d\xfc\x0f\xe9\x05\xff\x43\x7a\xc0\xbf\x9b\xc7\x62"
-  "\x98\x21\x7d\x88\xff\xa1\xbd\xe0\x7f\xa8\x1d\xf8\x2f\x70\x92\xff"
-  "\x87\x58\xe0\xdf\x83\xc7\xbf\x87\x93\xf8\x1f\x66\x0f\xfe\x7b\x1f"
-  "\xcf\x61\x14\xdc\x78\x4e\x07\x8e\xe7\x98\xdf\x11\xe9\x0d\xff\x22"
-  "\xfe\x1f\x26\xc2\xbf\xa2\x07\xfc\x7b\x0a\xf8\xbf\x06\xf8\xdf\xb3"
-  "\x17\xfc\x7b\xf6\x84\x7f\xf7\x8e\xdd\x30\x9e\x7d\x88\x7f\x45\x2f"
-  "\xf8\x57\xd8\x83\x7f\x27\xf9\xdf\xd3\x02\xff\xc3\x78\xfc\x0f\x73"
-  "\x12\xff\x5e\xee\x19\xff\x61\xbc\xb3\x70\xfc\xc7\xe4\xb9\xc7\xbf"
-  "\x33\x2b\x72\x89\x29\xb5\x58\xe5\x2d\x53\x11\x83\x67\xa1\x4e\x1b"
-  "\xdd\x4a\xe6\x5c\x04\x9b\x44\x5e\x24\xcf\x5c\x54\x12\x63\x6a\xb1"
-  "\x92\x85\xfe\xbf\xe4\x1d\x51\x38\x0c\xa9\xfe\x73\x33\x56\x11\xb9"
-  "\xd1\x6b\xef\xa7\x98\xa6\x3d\xd3\x4e\xb0\xce\x1b\x50\x07\x67\xcd"
-  "\x3a\xc0\x31\x38\xf6\x82\x5a\x99\x93\x04\x32\x1d\x3a\xd2\x00\x78"
-  "\xa9\x68\xd0\x81\xee\xd7\x71\xd8\x42\x5b\x40\x79\xa6\xe5\x9e\x27"
-  "\x72\xc3\x77\xbe\xa3\xc1\xc6\x3e\x8a\xb5\x44\xe6\xd7\xc0\x9a\xd0"
-  "\x96\x68\x23\xb4\xab\x6a\x1d\xcb\x82\xdc\x3b\x55\x80\x6f\xc3\x77"
-  "\xea\xd1\x39\x20\xe7\xf6\x71\x19\xc6\x9b\x9b\xff\x80\xcf\xc0\x8a"
-  "\x3a\xd0\x65\x8a\x97\x93\x76\xf2\xb6\xe3\xfd\x17\x7b\xc6\x29\x86"
-  "\xcf\xc0\x71\x0a\xb0\xd3\x6e\x3b\xed\x54\x28\x79\xa7\xd5\xed\x76"
-  "\x52\x36\xd8\x67\xa7\xe1\xf7\x59\xd8\xc9\xcd\xe3\x07\xc3\x3d\xa8"
-  "\x9d\x94\x75\xd4\x4e\x4a\x7f\xe7\xec\x34\xdc\xa9\xe7\x7f\xbb\xf7"
-  "\xa7\x47\x34\x61\x7f\xda\x04\xfd\x69\xfb\xec\x94\xaf\x96\xbc\x83"
-  "\xeb\x76\x3b\x8d\x48\xb5\xcf\x4e\x23\xbe\x97\xda\xc9\xdd\xfd\xdc"
-  "\x11\x25\xd4\x4e\x23\x36\x51\x3b\x0d\xaf\x70\xce\x4e\x23\xec\x78"
-  "\xff\xc3\x9e\x7e\x9f\xcf\x56\xec\xf7\x81\x9d\xec\x6c\x4f\xf9\x85"
-  "\x92\x77\x86\xdd\x6e\x27\x9f\x40\xfb\xec\xe4\x93\x66\x61\x27\x37"
-  "\xf7\xc7\x7c\x42\xa9\x9d\x7c\x26\x50\x3b\xfd\x2a\xda\x39\x3b\xf9"
-  "\xe4\xb9\xa7\x7f\x32\x72\x1a\xf6\x4f\x4c\xd0\x3f\xb1\xcf\x4e\x05"
-  "\x6a\xc9\x3b\xce\x6e\xb7\xd3\x0d\x75\xf6\xd9\x69\xe4\x3d\x52\x3b"
-  "\xb9\xbb\xdf\x30\x92\x50\x3b\xdd\x50\x43\xed\x74\x83\x9f\x73\x76"
-  "\x1a\x69\x73\xfd\x53\xc7\xe2\xe8\x1b\x1b\x30\x8e\x06\x3b\xd9\xd9"
-  "\x9e\x0a\x0a\x25\xef\x64\xbb\xdd\x4e\x37\x6e\xb2\xcf\x4e\x37\x9e"
-  "\xb6\xb0\x93\x9b\xe3\xdb\x1b\x0b\xa9\x9d\x6e\x8c\xa3\x76\x1a\x59"
-  "\xe6\x9c\x9d\x6e\xb4\xe7\xf9\x4f\xab\xef\x61\x75\x8f\xf9\x46\x65"
-  "\x5e\x5b\x31\xdf\xa8\x00\xfb\x6c\x35\x6a\xcb\x95\x8d\xf9\x46\xcd"
-  "\xa7\xb6\x1a\xa5\xa6\xb6\xf2\x8d\x74\xce\x56\xa3\x6c\xae\xff\xd8"
-  "\xdb\xfb\x5b\xdd\xe3\xbe\x5f\x4f\xbb\xb6\xe2\xbe\xd1\x76\xf2\xdf"
-  "\xaf\xef\xb9\xb2\x71\xdf\xaf\x79\xfe\x1b\xcd\xf3\xdf\x68\x27\xf9"
-  "\xef\xd7\x76\xf0\x9f\xf5\xf7\xbe\xba\xc7\x7e\x7e\x8d\xd7\x56\xec"
-  "\xe7\x97\x6c\x9f\xad\xfc\xbe\xbd\xb2\xb1\x9f\x5f\x11\xb5\x95\x5f"
-  "\x22\xb5\xd5\xaf\xcb\x9d\xb3\x95\x5f\xab\xb3\xef\x8b\x75\x8f\xff"
-  "\xc6\x5e\x63\xf1\xdf\x58\x3b\xe3\xbf\xb1\x57\x38\xfe\x1b\xcb\xc7"
-  "\x7f\x63\xf9\xf8\x6f\x8c\x93\xf1\xdf\x58\xa7\xe2\x3f\xa9\xad\x84"
-  "\x18\x50\x15\x74\x6d\xc5\x80\x37\xe9\xec\xb3\x95\x6a\xea\x95\x8d"
-  "\x01\x55\x72\x6a\xab\x9b\x6a\xa9\xad\x6e\x52\x39\x67\x2b\x95\xcd"
-  "\xfd\x6f\x7b\x7b\x3f\xad\x7b\x1c\x78\x73\xd3\xb5\x15\x07\xde\x6c"
-  "\x67\xff\xf7\xe6\xef\xaf\x6c\x1c\x78\x33\xdf\xff\xbd\x99\xef\xff"
-  "\xaa\x9c\xec\xff\xde\x6c\x47\xff\xd7\x9e\x71\x3f\xff\x59\x18\x03"
-  "\x1a\x53\xf7\xf8\x7b\x83\xfe\xbd\x63\x09\xd3\xe1\x07\xf6\xf2\x04"
-  "\x7b\x6d\x54\x91\xce\x54\xb0\x97\xde\x40\xe6\xbc\xfc\x0d\x5b\xd5"
-  "\x64\x24\x1d\x60\xab\xcb\x10\x07\x6a\xf5\x8d\xf8\x8e\xde\xef\xeb"
-  "\x99\x5b\xbf\x7f\xea\x65\x25\x41\x7b\xa1\xfe\x8d\x9e\xfe\x73\x59"
-  "\xb0\x17\x67\x3f\xcf\xe2\x46\x43\xea\xde\xbc\xd9\xe7\xbe\x61\x23"
-  "\x74\x2c\x5b\x19\xd6\x8e\x6b\x47\x2e\xa9\x0c\xab\x25\x21\x0d\x64"
-  "\x88\xea\x31\xb4\xcb\xad\xef\x60\xba\x56\x5f\x4b\x70\xdd\x4f\x6e"
-  "\x0c\xfc\x1b\xb5\x8f\xe1\x5f\x6a\x4f\x5c\xbf\x09\xdf\x2b\x14\xd6"
-  "\x68\xd2\x9e\xdd\xce\xd9\xdf\x72\x4c\x95\xb3\xff\xbf\xd4\xca\x5d"
-  "\xf8\x7e\xa2\xdb\x63\xc1\x5b\xb9\xf1\x3f\xd3\x37\xbe\xa3\x85\x32"
-  "\x46\x84\xb3\x2c\x94\x71\x44\x55\xab\x9e\x60\x39\xab\x5a\x35\x24"
-  "\x21\x9a\x28\xab\x3a\x1a\x49\x7c\x2b\xab\xaf\x4a\xfc\x91\x84\x5c"
-  "\xc4\x79\x01\xc4\xd3\xad\xa7\xa9\xbd\x6f\xf5\x30\x7d\xa3\x1e\x0d"
-  "\x9f\x35\x55\xd5\x84\x78\x6f\x04\x5d\x1b\x08\xc3\xbd\xaf\xc9\x10"
-  "\x0f\xd0\x57\x98\x36\xb1\x9e\xb0\x5e\x7f\x51\x69\x0d\x5f\xa3\x3e"
-  "\xc3\xe0\xfc\xb4\xae\xf9\x06\xaf\xbf\xdc\x82\x69\xa8\x5b\x7c\xce"
-  "\x54\x1b\xa9\xe7\x64\x84\xf3\xd4\x76\x89\x44\x1b\xdb\x41\xaa\x0c"
-  "\x84\xe8\x98\x5b\x0e\x9e\x0a\xad\x05\x7c\xdd\xe2\x24\x6f\xfb\x87"
-  "\xba\x67\xbc\xf2\xb6\x22\x8c\x5b\x01\x5f\xbb\x69\x19\x07\x36\xdb"
-  "\x81\xaf\x42\x33\xbe\x6e\x9b\xe9\x1a\xbe\xc6\x5d\x74\x33\xbe\xdc"
-  "\x1c\xbf\x8e\xd3\xb8\x86\xaf\xdb\xee\xa3\xf8\x1a\x17\x46\xf1\x75"
-  "\x5b\xa0\x19\x5f\x03\x9b\xaf\x1c\xbe\xc6\xf9\x50\x7c\xf9\xd7\x38"
-  "\x87\xaf\xdb\x4a\xdd\x33\xce\x3a\xde\x13\x63\x6d\x63\x6a\x3e\xcf"
-  "\x5f\xc3\xea\x7b\xc7\x57\xbe\x88\xbf\xd4\x7b\x5c\xc3\x97\x7a\x81"
-  "\x7b\xf1\xe5\xee\x98\x5b\xad\x72\x0d\x5f\xea\x6c\x8a\xaf\xdf\x94"
-  "\x53\x7c\xa9\xb7\x9a\xf1\x35\xac\xfe\xca\xe1\xeb\x37\xd1\x14\x5f"
-  "\xbf\x09\x74\x0e\x5f\xe3\x9d\x5a\xff\xaa\x7b\xff\xe0\xb7\xe1\xd8"
-  "\x3f\x00\x7c\xf1\xfc\x35\xfc\x0b\x3b\xf0\x25\xe2\xaf\xdf\x0e\x74"
-  "\x0d\x5f\xb7\xbf\xef\x66\x7c\xb9\xb9\x9f\x70\x7b\xa2\x6b\xf8\xba"
-  "\xdd\x48\xf1\x75\xbb\x9a\xe2\xeb\xf6\x56\x33\xbe\x86\x7f\x71\xe5"
-  "\xf0\x35\xbe\x86\xe2\x6b\xfc\x56\xe7\xf0\xf5\x5b\xdb\xeb\x3f\x3b"
-  "\x34\xae\x3d\xb1\x02\xfb\x34\xc6\xd4\x02\x9e\xbf\x26\xa7\xf4\x8e"
-  "\xaf\x02\x11\x7f\x4d\x5c\xee\x1a\xbe\x26\xde\xe0\x5e\x7c\xb9\xbb"
-  "\x6f\x33\x41\xe7\x1a\xbe\x26\x3e\x4d\xf1\x35\x21\x99\xe2\x6b\xe2"
-  "\x7c\x33\xbe\x26\xa7\x5c\x39\x7c\x4d\x08\xa4\xf8\xfa\x6d\xab\x73"
-  "\xf8\x9a\x68\xcf\xfa\xaf\x76\x8c\xc7\x07\x4c\xc0\x7e\x18\xe0\x8b"
-  "\xe7\xaf\xa7\xa6\xdb\x81\x2f\x11\x7f\x4d\x3a\xe1\x1a\xbe\x26\xad"
-  "\x71\x33\xbe\xdc\xdc\x1f\x9b\x14\xe4\x1a\xbe\x26\x1d\xa1\xf8\xba"
-  "\xa3\x91\xe2\x6b\xd2\x41\x33\xbe\x9e\x9a\x7e\xe5\xf0\x75\xc7\x56"
-  "\x8a\xaf\x3b\xe6\x3b\x87\xaf\x00\x7b\xd6\x3f\xb5\x73\x1e\xe1\xae"
-  "\x4c\xd7\xfa\x90\x77\x8d\x77\x0d\x63\x77\x7e\x75\x6d\xf7\x21\xef"
-  "\xdc\xed\x1a\xc6\xee\xba\x99\x62\xec\xce\x59\x14\x63\x77\xf9\xf6"
-  "\x4d\x1f\x32\xa0\x9d\x62\x2c\xa0\xd4\x39\x8c\xdd\xe5\xc6\xf9\x8f"
-  "\xc0\x56\xd7\xfa\x91\x81\x69\xae\x61\x2c\xf0\xbe\x6b\xbb\x1f\x19"
-  "\xe8\xe1\x1a\xc6\x02\x5f\xa3\x18\xbb\xbb\x84\x62\x2c\x30\xae\x6f"
-  "\xfa\x91\x77\x2f\xa2\x18\xbb\xdb\xc9\x79\x9b\x7b\xec\x78\xfe\xcd"
-  "\xde\x79\x9b\xdf\x85\xba\xd6\x97\x9c\xfc\xb3\x6b\x18\x9b\xfc\xee"
-  "\xb5\xdd\x97\x9c\x1c\xee\x1a\xc6\x26\xff\x48\x31\x36\xd9\x87\x62"
-  "\x6c\xb2\xae\x6f\xfa\x92\xf7\x68\x28\xc6\xee\x49\x74\x0e\x63\xbf"
-  "\x5b\xe6\xbe\xf9\xa6\xa9\x87\x5d\xeb\x4f\x4e\x5d\xe0\x1a\xc6\xa6"
-  "\x0e\xbc\xb6\xfb\x93\x53\xaa\x5d\xc3\xd8\xd4\xd9\x14\x63\x53\x62"
-  "\x29\xc6\xa6\xce\xe8\x9b\xfe\xe4\x14\x7f\x8a\xb1\xdf\x35\x38\x87"
-  "\xb1\xa9\x76\xac\xff\x6f\xef\x3c\xd9\x34\x95\x6b\x7d\xca\xdf\x1f"
-  "\x72\x0d\x63\xbf\x5f\x71\x6d\xf7\x29\x7f\x1f\xe8\x1a\xc6\x7e\x7f"
-  "\x80\x62\xec\xde\x3a\x8a\xb1\xdf\x17\xf6\x4d\x9f\xf2\xde\x64\x8a"
-  "\xb1\x7b\x83\x9d\xc3\xd8\xb4\x09\xee\x9b\xdf\xbb\x7f\x93\x6b\xfd"
-  "\xca\xfb\xc7\xb8\x86\xb1\xfb\x2a\xaf\xed\x7e\xe5\x7d\xdb\x5d\xc3"
-  "\xd8\xfd\x37\x50\x8c\xdd\x17\x44\x31\x76\xbf\x67\xdf\xf4\x2b\xa7"
-  "\x35\x51\x8c\x4d\x73\x6e\x3d\x0a\xe6\xfe\x6e\xeb\x5f\xad\x58\x15"
-  "\xb3\x34\x7c\xc5\x32\xd5\x8a\x55\xd1\x51\x2f\xab\x56\xaf\x58\xb7"
-  "\xfc\xbe\x71\x6b\x26\xa8\xa2\x62\x55\x51\x2b\x56\xbd\xc0\x27\x2c"
-  "\x1b\x4a\x1e\x5b\x1e\xbe\x34\x16\x53\x40\xfa\x85\x55\x2b\x97\xaf"
-  "\x8a\x56\x45\x2d\x7f\x79\xcd\x8a\xa8\xe5\xf8\x7d\xb5\xea\xf9\x88"
-  "\x28\x48\x78\x6e\xf9\x8a\x98\xe5\xaa\x67\xd7\x3c\xff\xfc\xf2\xa8"
-  "\xd5\x43\xc9\xec\x35\xe1\xd1\x2b\x22\xc3\x97\xab\x66\xcc\x7e\x60"
-  "\xe2\xfc\x99\x8f\xcf\xff\xc3\x1f\x70\x73\x32\xd1\xde\x64\x7e\x6c"
-  "\x6a\xb1\x0e\x30\x27\x3f\xc3\x04\x4f\xad\xf2\x25\xdc\xfe\xb8\x19"
-  "\xcd\x44\xb9\x25\x8a\xc8\x93\x9b\x89\x47\x5a\x33\xf1\x54\xbd\x48"
-  "\x82\xd8\x2d\x3f\xcd\x85\x74\x1f\x36\xed\xd6\x4c\x36\x3d\x3a\x0c"
-  "\x3e\xab\xf5\x0a\xcf\x30\x94\x65\xd3\x86\x25\xe3\x39\xd0\xad\x9c"
-  "\x4d\xf3\x9f\x52\xcf\x3c\xd4\xae\x57\x28\x42\x13\x7e\x24\x0c\x3b"
-  "\xf4\x0f\x9a\x62\x93\x9e\x39\x86\x3b\x52\x42\xdd\x09\x13\x54\x0b"
-  "\x47\x19\x61\x1e\x88\x86\x63\x13\x1c\x99\x70\x94\xc2\xa1\x81\xa3"
-  "\x06\x0e\x1d\x1c\x4d\x70\xb4\xc2\x01\x3d\xb8\xe9\x72\x38\x3c\xe1"
-  "\x48\x86\xa3\x10\x0e\x90\x9d\x5e\x4d\xf3\x99\x5e\x47\x98\x3f\x7a"
-  "\xc0\x31\x17\x0e\xc8\x6b\x46\x22\x1c\x45\x84\x99\x39\x0b\x3e\x2b"
-  "\xe0\x68\x84\x43\x0f\xbf\x7d\xe0\x00\x2b\x4c\xd7\xd1\x73\x33\x21"
-  "\xed\xc1\x09\x04\xca\xd9\xfb\xf1\x20\xc8\x3f\x38\x1f\x0e\xe8\xb9"
-  "\x3f\x08\xf7\x7c\x68\x1a\x1c\xa9\x16\x72\x35\xa2\xef\xfa\x9e\xf3"
-  "\x0b\x56\x7a\x6f\xbc\x49\xc7\xed\x81\xc7\x3c\x70\x8f\x31\x89\x0c"
-  "\x30\xa6\x29\x42\x23\x6f\x27\xb2\xb3\xcc\x03\x32\xed\x26\xe4\x99"
-  "\x5b\x33\xb9\x3d\x1d\xe1\x37\xea\xac\x2d\xe5\x01\xa2\x23\x69\x2a"
-  "\xdc\xd3\xcc\x31\xbc\x3d\x40\xf8\xeb\x83\x74\xb2\x1b\xdb\xb9\x3d"
-  "\xe0\x52\x74\x65\x6c\x42\xe8\x2e\x6e\xef\x37\xd4\x21\xb6\x83\x64"
-  "\x9d\x1f\xeb\xf1\x75\x39\xb6\x79\xcd\x3a\x2c\x57\xd0\x57\x6c\x12"
-  "\xf1\xd2\xc1\x79\x16\xca\xa6\x57\x44\x87\x41\x39\xe5\xf8\xdb\x98"
-  "\xe6\x19\x76\x59\xb1\x4f\x83\xdf\xdb\xb3\x23\xf4\x6c\xea\xbe\x46"
-  "\xec\x67\x6b\xe2\xdf\x22\xf5\x70\xdd\x65\xc5\xfe\x64\xd5\x23\xde"
-  "\x6c\x3d\x5e\x9b\x44\x18\x28\x43\x38\x6d\xab\x41\xb5\x97\x15\xd1"
-  "\x91\xc6\xed\xfb\x4b\x20\x5d\x6e\x4c\x8b\x0e\xa3\xf9\x7b\x86\x19"
-  "\x53\xf7\x66\x82\x5c\x39\x97\x9e\x15\xe9\x21\x7c\x87\xcf\x32\x63"
-  "\x7a\x71\x00\x7e\x2a\x36\x92\x56\xee\x77\x52\x10\xa1\x9f\x4a\xa2"
-  "\x7a\x84\x90\x26\x66\xfa\xca\x49\xe5\x44\xa6\x79\x04\xcb\x3d\x7d"
-  "\x4a\x42\x39\x6b\x52\xc5\x0f\x80\xfb\x4f\x9f\xda\x75\xdf\x51\xfb"
-  "\x0b\x71\xff\x54\x36\xe5\xfe\xea\xdc\xb7\x08\xc1\x6b\xb1\x6c\x3b"
-  "\x46\x10\x79\xf6\x5b\xc4\x03\xeb\xd8\x96\x32\x7d\x99\xb0\x0f\x1d"
-  "\x5e\xc3\x80\xfc\xc3\x0f\x27\xb0\xa2\xbc\xef\x34\x72\xf5\x09\xaa"
-  "\xa1\x3a\x9d\xbe\x55\x27\xf3\x69\x45\x79\xd5\x2d\x9c\x2e\xbf\xe2"
-  "\xcf\xd7\xa2\x3d\x31\x7f\x36\xad\x58\x87\xbf\x71\x9f\x3b\xef\x72"
-  "\xc2\xa8\xe2\xfd\x4b\xa9\x8e\xf6\x35\x62\x3e\x28\xcf\xa6\x17\xc2"
-  "\xf7\x07\x62\xd9\x34\x4e\xc7\x6a\xd5\x2a\x12\x54\xcf\xfc\x51\x66"
-  "\xdc\xf2\xed\x26\xc8\x03\xda\xdd\xb7\xc9\x97\x15\xc5\x84\xd3\x77"
-  "\xda\xde\x44\x1d\x33\xbd\x15\xce\x25\x77\xed\x7d\x49\xf5\x2c\x03"
-  "\xb9\xed\x6d\x29\x7f\x54\xeb\x64\x13\x3d\x38\x3b\xc7\xb0\x35\xb8"
-  "\xc7\x66\x4b\x0c\x6b\x08\x31\x7c\x63\x02\xae\x22\x70\x3e\x58\x47"
-  "\xee\x5f\x22\xd4\x91\xda\xbe\x2b\x9f\xaf\xf0\xb7\x7e\x08\x97\x4f"
-  "\xa4\xb5\x7c\x74\xcc\x1f\xa7\x2c\x36\xa8\x64\x1d\x97\xd8\xea\x8c"
-  "\x3f\xa1\x1e\x09\xdb\x11\xc3\x56\x6c\x08\x66\xdb\xd3\xbf\x20\xa4"
-  "\x32\xac\x8e\x40\x9b\xf7\xf3\x92\xb1\xfa\x90\x57\x88\xb7\x57\xa4"
-  "\x37\xfb\x59\x79\x1d\x59\x1f\xcc\x36\xe2\xbe\xbf\x55\xad\x0d\x24"
-  "\xee\x2b\xe2\x99\x50\x49\x7c\xe2\x82\x59\x7d\xc5\x92\x3a\x42\xd3"
-  "\x2b\x49\xc2\xb7\x44\xbe\xbe\x8c\x6d\x9f\x03\xfc\x7f\xaa\x0e\xd3"
-  "\x1b\x08\xee\x51\x99\xd0\xc8\x1a\xe2\x9f\x26\x9e\xf8\xbd\xb2\x0c"
-  "\xd3\xbf\x27\x09\xe7\x88\x3c\x24\x56\xef\x9d\x03\xf7\xc4\xeb\x73"
-  "\xa1\x2c\xa6\x4b\xec\xe1\x8c\x4b\x84\xac\x5f\x48\x7c\xe3\x96\x12"
-  "\x65\x88\x91\xb0\x5a\xc3\xfb\x24\xc4\xc8\x82\x7f\x39\x41\x36\xac"
-  "\x20\x1e\x21\x06\x7c\x8f\xed\x4b\x82\xfb\x7e\xe7\x82\x2c\xd4\x4d"
-  "\x83\x75\x5b\x7f\x9a\xf8\xe2\x3e\xe8\xf4\x9a\x23\xfc\x35\xa7\x09"
-  "\xea\xec\xb2\xe2\x56\x4d\x7b\x9a\x7f\x10\xd4\x7d\x1a\xea\x00\xee"
-  "\x53\x6d\xc2\xeb\xe0\xfa\x8c\x28\x4e\x07\xb2\xc5\x06\xe2\x69\x4c"
-  "\xdb\x1b\xb6\x38\x56\xc3\xe5\xab\x63\x66\xc4\xe6\x46\x71\x65\x92"
-  "\xc8\x86\x18\xd8\x16\xbd\x62\x2f\xe0\x7e\x46\x5e\x48\xec\x1f\x58"
-  "\xbc\x16\x6c\xb9\xb5\x2d\x65\x86\x4e\xd0\xb7\x60\x17\x90\xa9\x01"
-  "\x5b\x6c\x1d\x10\x49\xe4\x6d\x29\x33\x89\x4e\x36\xa9\xc1\x8c\xb5"
-  "\x07\xc2\xc1\xe6\x83\x04\x59\x5e\xc6\x5f\x27\xbb\x63\x82\x08\x8f"
-  "\x88\xaf\x2e\x19\x38\x3f\x03\xf2\x08\xa4\xf7\x98\x29\x47\x19\x9e"
-  "\xfb\x05\xd9\x01\x6c\xf2\xd7\x59\x46\xc5\x3e\x3d\xcb\xb0\xed\x80"
-  "\xc7\x64\xb6\xc5\xd7\x73\x8e\x81\x6d\x37\xa5\x15\x26\x02\xbf\x7b"
-  "\xe2\xbe\xae\x54\x7e\xe6\x97\x70\x3e\x53\x15\xc3\x7d\x6f\xc4\xfb"
-  "\xb0\xa9\xd1\x99\x5d\xe7\x92\xc8\x40\x36\x3b\x42\x07\xbe\x43\x19"
-  "\x52\xce\xb6\x43\x5b\xd7\xa5\x47\xa1\xef\xd8\xa7\xc3\x76\x6d\x52"
-  "\xec\xdd\xde\xbe\x63\x3f\xb6\x79\x82\x6d\x84\x4d\x2d\x4c\xa4\xd7"
-  "\x3e\xb0\x12\xdb\x0d\xe5\x9a\x99\x45\x46\xc8\x03\xca\x94\x07\xe7"
-  "\x06\xd6\x33\x0f\xaa\xf0\x7d\x52\xf8\x5d\xcb\xed\x7b\xc9\x3c\x38"
-  "\x8e\xe2\xf7\xeb\x2c\xc9\x6f\x06\x75\x07\xed\x09\x38\x0b\xf9\x01"
-  "\xd2\x67\x9a\xdb\x30\xa7\x37\x86\x72\x51\x61\x26\xe5\x91\x01\x26"
-  "\x90\x93\xd5\xf3\xed\xf1\xf2\x90\x6f\x53\xdb\x52\x1e\x04\xfc\x7b"
-  "\x47\x4b\xda\x49\xca\xbf\x82\x70\x8f\x4d\x28\xcb\x00\xc8\x33\x1b"
-  "\x3e\x07\xc3\xe7\xbb\xc7\xcb\xd1\xde\x5c\xbe\xc3\xf0\xfb\x8e\x91"
-  "\xac\x7e\xc6\x4c\x82\xfb\x69\x42\x7b\x7b\xb0\x54\x47\xc2\xe5\x98"
-  "\xcf\x16\xdc\x67\x14\xd2\x50\x06\xd2\xab\x21\xbd\x95\xe6\xff\x40"
-  "\x6c\x2b\x94\xd5\x22\xff\x8b\x34\x7f\x9a\x2f\xe6\x27\xe4\x9d\xbd"
-  "\x8d\x6d\xa2\x79\x3f\xe4\x23\xe4\x9d\x06\x69\x42\xfe\x33\x56\x0a"
-  "\xf7\x78\x28\x10\xce\xc7\x89\xeb\xb0\x7d\x1b\xdb\x8a\x79\xc0\xb9"
-  "\xb9\x3a\x92\xd8\x88\xe7\x92\x21\x0d\xaf\x15\xe1\x6a\xc0\xf1\x60"
-  "\xc8\xa3\x8c\xcb\x23\x56\x47\x12\x22\x2d\x38\x4e\x21\x70\x1c\x9f"
-  "\x57\x96\x90\x97\x39\x1f\x01\x4f\xdf\xeb\x79\xbb\x62\xbe\x9e\x98"
-  "\x2f\xc8\x57\xe8\xc8\xaa\x32\x71\xdd\x41\xe7\x71\xfc\xb9\x46\xd0"
-  "\x7b\xa0\xb4\x1d\x4c\xaf\x61\xd3\xf7\xb5\x23\xc7\xf1\x79\xc9\x90"
-  "\xaf\x85\xf3\xb8\x07\x29\xf0\x7a\x3b\xb6\x25\x8e\xdb\xd3\xf6\x46"
-  "\xb6\xa5\x04\x07\x58\x70\xb9\x1c\xe5\x8c\x29\x7f\x98\x98\x8d\x7b"
-  "\xb0\x8e\x64\x1b\x41\x66\xbe\x64\xdf\x51\x86\xdc\x0f\x69\x5d\xfb"
-  "\x9f\xa6\x83\x8c\x8e\xf9\xc3\x12\x5b\x7d\x82\xf8\x9b\x09\xa3\x85"
-  "\x9a\x43\x6c\x8d\x98\x9b\xa6\xf5\x6b\x25\xda\x2c\x13\x31\xe5\x44"
-  "\x2a\x83\xe2\x59\x0d\xc4\x53\xdf\xe3\x7e\xd6\x8e\xf9\xeb\x60\xba"
-  "\xff\x67\x07\xc4\x9c\x71\x77\x11\xf4\xd1\xe7\x99\x47\x6e\xd0\xea"
-  "\x9b\xb9\x76\x07\xdf\xb9\x78\xe0\x6d\x88\x51\x31\x4e\x85\xbe\x41"
-  "\x58\x26\x43\x63\x55\x13\xc8\xe6\x60\x3a\xc6\xb1\xc0\xa1\xb9\xa2"
-  "\x73\x6c\x4e\x44\x39\xd5\xdd\xc3\x95\x9c\xaf\xc0\xf2\x1a\x1e\xd2"
-  "\x60\x99\x4d\x59\x11\xe5\x58\x87\x84\x58\xd6\xa4\x35\xb4\x69\x90"
-  "\x67\x55\x31\x18\x63\x3f\xbc\x37\x24\x9b\xb0\xa6\xec\x88\x72\xc7"
-  "\xea\xf0\x30\xb7\xf7\x38\xf4\x23\xce\xeb\xc7\x44\x94\xe3\x3e\xd0"
-  "\x19\xf1\x03\x3d\xfe\x98\xc5\x6a\x5a\xc6\x46\x2a\xdb\x52\x1e\xae"
-  "\x10\xf6\xd9\x75\x30\xdf\x0a\xa1\xee\x39\x7c\xdd\x21\x8d\xeb\xb3"
-  "\x4d\xda\xce\xed\xff\x0d\xbf\x1f\x91\xdb\xb2\x17\x70\x4c\x3b\x5e"
-  "\x0b\x75\x0f\xca\x15\xf4\x64\xd0\xe3\xfe\xe7\xc3\xcf\x32\x8f\xec"
-  "\x08\x89\xd3\x10\x6e\x4d\xff\xb4\xc2\x76\xc7\xca\xf5\x08\x37\xfe"
-  "\x55\x05\x7d\x98\x10\xc3\x51\x96\x72\xe2\x23\xc7\xe6\xf0\xf9\xe1"
-  "\x39\xc1\x56\x39\x7c\xdf\xc2\x89\x7b\xd8\x1c\xff\x10\xd5\x4b\xd9"
-  "\xbd\x5e\x8f\xbe\xec\x7c\xbd\x1e\x9d\xd6\xbd\x5e\x8f\xee\x70\x6f"
-  "\xbd\x1e\xcd\xb3\xa3\x5e\xaa\xee\xf5\x9a\xf5\xb0\xf3\xf5\x9a\xe5"
-  "\xd3\xbd\x5e\xb3\x5e\x76\x6f\xbd\x66\xd9\x7c\xfe\x41\x54\xaf\x80"
-  "\xee\xf5\x9a\x7d\xb3\x0b\xf5\x6a\xea\x5e\xaf\xd9\x0f\xbb\xb7\x5e"
-  "\xb3\x6d\xbe\xff\x6b\x93\x0f\xd3\x8b\x83\x28\x1f\xce\xbe\xe8\x38"
-  "\x1f\xce\xd6\x74\xe7\xc3\x90\x71\x66\x3e\x0c\x19\xee\x14\x1f\xa6"
-  "\x47\xf3\xf1\xc6\x9c\xd3\xdd\xf8\x30\x35\x3a\xd1\x3a\x1f\xce\x39"
-  "\xc4\xf1\x61\x5a\x74\xa2\x63\x75\x98\xb3\xa9\x8b\x0f\x15\xd1\x89"
-  "\x12\x3e\xf4\x2a\x0e\x6a\x4b\x99\x53\xe7\x1c\x1f\xce\xa9\xeb\xce"
-  "\x87\x73\xa6\x49\xf9\x30\xc4\xc7\x36\x0e\xf7\xc6\x5a\xe3\xc3\x10"
-  "\xc3\x05\x96\x62\x63\x6f\xac\x63\xe5\x09\x09\xef\xe1\x5e\xa4\x97"
-  "\x7b\x39\x88\x8b\x10\x9b\xcf\x7f\x40\x3f\xf6\x30\xc4\x20\xca\x0d"
-  "\xef\x12\xe6\x4c\x1c\x61\xaa\xfc\x6a\xa1\x8f\xd0\x4e\xee\x88\x04"
-  "\x4c\x24\x91\x69\x55\x59\x4d\xa4\xca\xef\x0c\x61\x87\x7c\x7d\x98"
-  "\xcd\x4f\xcc\x0c\x8a\x42\x6c\xce\x7d\x53\x1b\xdd\xee\x60\x19\xe6"
-  "\x2e\x12\xb0\x59\x65\x00\x6c\xc6\x20\x1e\xe7\x1d\xd3\x36\x9d\xe5"
-  "\xb1\x39\x6f\x5f\x97\x7d\x92\x28\x3e\xad\x62\x13\xda\x84\x14\x9b"
-  "\x85\x7c\xcc\x34\xef\x95\xee\xd8\x2c\xd4\x5b\xc7\xe6\xbc\x05\x14"
-  "\x9b\x85\x7a\xc7\xea\x30\x4f\x65\xc6\x66\xa1\x5e\x82\xcd\xdb\x12"
-  "\x33\xdb\x52\xe6\xc5\x3a\x87\xcd\x79\xb1\x42\xdd\xb3\xf9\xba\x83"
-  "\xbe\x6a\xa5\xd8\x9c\x57\x62\xd3\x86\xc9\xff\xf0\x00\x3e\xf4\x3c"
-  "\xcb\x3c\x96\x68\x84\x98\xd6\x94\x3a\x3c\x16\xfa\x64\x6d\xb8\x9f"
-  "\x3c\xcb\x04\x12\x76\xad\xda\xb3\x0d\xfa\xc6\x6d\x6d\x61\x1e\xec"
-  "\xd0\xaf\x1f\x61\x3b\x7d\x09\x94\xdd\x9b\x6d\x53\x7b\x81\xce\xfc"
-  "\xe1\x73\x44\x76\x0c\xf1\x81\xc3\x37\x9b\xd7\x2b\x7c\x0f\x60\xd7"
-  "\xfa\x0e\x4d\x8f\x21\x13\xbc\x5b\x89\x07\x94\x21\xd4\x7b\xa3\x92"
-  "\x78\x1b\x88\x0f\x7e\x67\x93\x3e\x50\x43\xdf\x4d\x8e\xe3\xa2\x26"
-  "\x05\xdc\x2f\xd6\x9b\x65\x57\xab\x09\xf4\xe3\xe0\x9e\xc4\x37\x97"
-  "\x61\x4b\x8c\x6b\xd5\x0c\xeb\xb5\xaf\x93\x5d\x1f\xca\x95\xc9\xe4"
-  "\x9f\x58\x0d\x18\xaa\x66\x13\xc2\xf0\xbe\x41\xb8\xaf\x31\x7b\x5b"
-  "\x62\x0d\xdb\xe6\x3b\x34\xed\x12\x99\x90\x1b\x43\xfc\x73\x62\x88"
-  "\x9a\xed\x54\x33\xa0\x83\xd0\x67\x5e\x56\xa2\xdd\x43\x59\x06\xee"
-  "\x15\x03\xf7\x02\x5b\x1a\xd3\xe0\x5e\x06\xb8\xd7\x05\xb8\xd7\x79"
-  "\xb8\x57\x12\xdc\x2b\x89\xde\xcb\x31\x9d\x3f\xd6\xd4\xd3\xf8\x75"
-  "\xc8\x86\xb1\xb8\xce\xee\x0f\xde\xb1\x83\x83\x71\x2c\xbb\x65\x7d"
-  "\x98\x83\x78\x7f\xdc\xe6\xfb\x2f\x19\xc5\xc4\x8f\xf5\x1c\x16\x3b"
-  "\xe7\xb5\x6f\x58\xec\x63\xbf\x56\x4c\x26\x60\x9b\xab\x6a\x3f\x47"
-  "\x58\xc5\xb0\xd8\x13\xea\x26\x47\xef\x65\xf3\xf9\xe7\x94\x24\xb6"
-  "\xba\xd3\x0f\xfa\x85\xa9\xc5\x1e\x19\x0c\x1b\xdb\xe1\x17\x49\x4e"
-  "\xd6\x74\x90\xc5\xb1\x38\x5e\xce\xc6\xaa\x9e\x24\x1e\xf5\xcc\x93"
-  "\xe1\x09\x5f\xe1\xd8\xe3\xfc\x69\xd2\xb1\xc7\xf9\x4b\x08\xf3\x27"
-  "\x39\x61\x9e\x08\x24\x4c\xe8\x61\x02\x72\xd2\x63\x61\x6b\xc8\xde"
-  "\xb1\x24\xde\xc0\xfe\x00\xfd\xd9\xda\x74\xe8\x07\x87\x8c\x97\xe9"
-  "\x34\x31\x38\x16\xb7\xc0\x08\xfa\xfb\x09\x7c\x90\x37\x7e\xc7\xfc"
-  "\x22\xa3\xc8\xaf\xce\x32\x0b\x0c\xde\xad\x83\x83\x0d\x9e\xc5\x6a"
-  "\x03\xf4\xdf\x3a\x7d\xf7\x67\x5e\x4e\xdd\xa7\xeb\xc4\x3e\xed\xb3"
-  "\xc8\x03\xf3\x2f\x7a\xcb\x12\xa1\xaf\x3d\x3c\x96\x65\x7d\x71\x7c"
-  "\x39\x34\x0b\x0e\xb4\x3d\x67\xf7\xa1\xdf\xd4\x22\x3e\x10\x8b\xb9"
-  "\x34\x5d\x89\x78\xcc\xe0\x7d\xb6\x7e\xc0\xed\x4b\xb0\x0d\x18\xe1"
-  "\xfa\x84\xef\x89\x9f\xb6\xce\x48\x00\xd3\xa1\x8b\x8d\x1e\xd8\x8e"
-  "\x42\x35\x4f\x7e\x41\xce\x44\x12\x26\xe1\x67\xa2\x00\x0c\x79\x62"
-  "\x7b\x30\x41\x7b\x08\xa9\xf3\x6e\x87\x76\x6d\x8a\xbf\x48\xbc\x91"
-  "\x27\x70\x0d\x67\x6d\x93\x8e\x98\x2e\xa8\xbd\x76\xad\x22\x3e\x86"
-  "\x0b\x61\x23\xf4\x17\xc2\x7e\xb5\xc3\x44\x7c\xbc\x22\x89\x32\x7b"
-  "\x15\x60\x37\x02\xda\xc7\x79\x68\x1f\x4d\xb4\x7d\x74\xe1\x75\xf3"
-  "\xe7\x91\xf8\x7e\x10\xd7\x36\xd2\xf8\xb6\xb1\x16\xf0\x1a\x63\x6e"
-  "\x1b\x86\x08\x35\x93\xcd\xb0\x04\xca\x08\x7a\x7f\x7c\x42\x6e\xfc"
-  "\x60\x8c\x75\x12\xd9\xb1\x91\x91\xc0\xbb\x50\x57\xd6\xb0\x1f\x6c"
-  "\x31\x70\x3c\xa3\x82\x3e\xbf\xfa\xe4\xdc\x46\x62\xee\xd3\x3d\xb9"
-  "\xb2\x63\x4c\x24\x51\x3d\xc6\x5e\xa8\x67\x16\xb4\x42\xba\x87\xea"
-  "\x4f\xbf\x51\x82\x1d\x57\xd2\x3e\xe0\x93\xe1\x38\x9e\xa0\x63\x16"
-  "\xe0\x7a\x40\x04\xe7\x50\x4e\x71\xe3\xa7\x4f\x4c\x00\x59\x62\x04"
-  "\x9d\x1b\x3c\xa3\x33\x4d\x9e\xfb\xda\x35\x2f\x76\x70\x6d\xb3\x13"
-  "\x6c\x70\x06\x2c\xba\xb8\x09\x74\x63\x04\xdd\xb4\x71\x9c\x31\x97"
-  "\xe3\x8c\xe4\xaf\x67\xc4\xe9\x58\x53\xc8\xb2\x01\x2c\xe8\xc5\x03"
-  "\xc7\x90\x9e\x89\x24\xec\x86\x73\xa0\xa3\xd6\x5a\xe4\x17\x2f\xd3"
-  "\x5a\xca\x21\xbb\x40\x3f\x8a\x26\xa2\x64\xd3\x15\x91\xc5\xf1\xe5"
-  "\x03\x8d\x80\x73\xe4\x11\xef\x8d\xb2\x21\x60\x2b\xaf\x54\x6c\xe7"
-  "\xd0\xee\xbd\x37\x72\xbc\xc6\xd9\xd6\xb0\x56\x7d\x4b\xe7\x5a\xb5"
-  "\x0a\x8e\xb1\x02\xd7\xe0\xbe\x61\xd9\xc8\x33\x29\x8f\x6f\x45\x9e"
-  "\xd1\x42\xcf\xda\x00\xba\xf4\x42\xbf\xb4\x56\xed\xc7\xe9\xf4\x05"
-  "\xd0\xe9\xf3\xc4\x63\x52\x3b\x91\x41\xb9\x94\x50\x66\x52\x19\x56"
-  "\x4f\x50\xc7\x46\x68\x47\xa8\xe7\x4e\xe4\x20\xc0\x1a\xc4\x29\x99"
-  "\xb3\x57\xa8\xc8\x09\xf5\x97\x04\xd7\x81\x4a\xb8\xcc\x7e\x8b\xe3"
-  "\xb7\xda\x58\x03\xb4\xb9\x62\x35\xea\x16\xf4\x55\x71\x72\x6e\x3b"
-  "\xb1\x8d\xe9\xd0\xf7\xcd\x98\x0e\x7d\xdf\x8c\xe9\xd0\x83\xdc\xfc"
-  "\x87\x08\xd7\x97\xb7\x03\xae\x3d\xc5\xb8\x7e\xa2\xf2\x8a\xe2\x7a"
-  "\x8e\xe3\xb8\xde\x71\x5e\x84\xeb\xf8\xab\x83\xeb\x53\xa1\x1c\xae"
-  "\x07\x74\x8e\xe1\xf0\x5a\xad\x35\xbc\x47\x74\x4c\x68\x9e\x80\xdb"
-  "\xcf\xfe\x82\xb8\x5d\xd8\x70\xad\xe2\xf6\x72\x9b\x5a\x05\x87\xdb"
-  "\x71\x0b\x79\xda\x8d\xdb\x53\xa1\x1d\x44\xd0\x1f\xe2\x97\x4d\x1d"
-  "\x16\xab\x4a\x20\x7f\x00\x9e\x08\xf7\xde\x38\x96\x54\x72\x3a\x7c"
-  "\x32\x5c\xf5\x27\xd6\x04\x1c\x31\x06\xf1\xd4\x91\xc4\xb2\x26\xcf"
-  "\xbd\xdb\x13\x3e\x27\x4a\xb8\x87\x4e\x6b\xd8\x47\xbc\x23\x71\x3e"
-  "\x2a\x3a\x8c\x55\xf8\x4f\xe1\xe6\xac\x18\x22\x37\xa5\x0d\x4b\xc6"
-  "\xb1\x2b\x1c\x5b\x34\xa6\x15\xeb\x4c\x5b\x7e\x9a\x6b\x52\xdc\x9a"
-  "\x89\xf3\x59\xac\xc2\x33\xac\x2d\xe5\xc9\x70\x61\xae\xc5\x6a\x6c"
-  "\xe2\x59\xac\x83\xf6\x22\x3f\xc3\x3c\xb5\x02\x3e\x19\xf8\x1c\x08"
-  "\x9f\x03\xa0\x3c\xdc\xbe\x75\x8e\xf9\xb9\x27\xb9\xfe\x2f\xf8\xb2"
-  "\x40\x9e\x07\xdf\xe5\xda\xe0\xed\x44\x71\x96\xff\x0e\xe5\x31\x08"
-  "\x73\x37\x66\xf9\x2e\x7d\x6c\xc7\x7b\x83\x4e\xe4\x74\x3e\x89\xfe"
-  "\x16\xe5\xb7\x83\xfb\x4d\xe4\x2a\xa8\x7f\x1e\xce\xfb\x02\x96\x64"
-  "\x6d\x6c\xd8\xfd\xfc\xe7\x7d\x88\x55\x1c\x83\xc5\x38\x8f\xe7\xda"
-  "\x3c\x7a\xdf\xa7\xa2\xc1\x0f\x4b\xee\x6b\x4d\x1f\x3a\xe6\x29\x9b"
-  "\x7b\xfa\x38\xa6\x8b\xa7\x6c\xee\xff\x38\x53\x6d\x64\x1d\xcc\xcb"
-  "\xe6\xfb\x9f\xac\x5f\x84\x26\xa4\xd0\xa8\x31\x75\x86\x7a\x9f\x88"
-  "\x3b\xe7\x60\x5c\xb2\xc8\x66\xff\xd7\xe8\xb9\xb7\x24\x64\xfc\x58"
-  "\x62\xcc\x8a\xd0\xe0\x58\x27\xc6\x5a\x55\x6a\x03\xc1\x78\x6b\xef"
-  "\x8b\x3a\xa6\x13\x62\x46\x2f\x68\x8f\x73\x5a\x8f\xb2\x19\x67\x21"
-  "\x46\x5d\x1b\xea\x9d\xfe\x22\x99\x66\xb8\xe0\x3b\xf4\x0d\xe0\xa0"
-  "\x0e\xe0\x83\x8e\x0b\x61\xde\x55\x91\xed\xc4\x94\x1d\xa1\xd1\x1a"
-  "\xca\x49\x2e\xc8\x21\xff\x62\x79\x2f\x5f\x08\xf5\x4a\x59\x85\xf3"
-  "\x17\x17\x89\xe6\xd9\xbf\x00\xff\x3e\x3d\x6f\xe0\x06\xe0\x1c\xe0"
-  "\x0c\x8e\x87\x9d\xe0\xe0\x8e\x57\x6f\x5f\x32\x7b\x11\xdb\x5e\x55"
-  "\xf7\x05\x49\xa8\x24\xca\x84\x35\x44\x81\xf9\x6b\x0d\x95\x94\x97"
-  "\x17\x02\x2f\xc3\xef\x1c\x11\x2f\x73\xcf\x17\x58\xf0\x32\xc6\xdf"
-  "\x55\x0d\x8d\xc4\xab\x95\x0c\x9e\xd3\xea\xdd\x1e\xdf\xca\x9a\x30"
-  "\x1e\xd7\x1a\xce\xe1\xbb\xc7\x5e\x02\x47\xef\x84\xb8\xa3\x33\x82"
-  "\xf2\x73\x36\xcf\xcf\x3b\xcf\xbb\xce\xcf\x3b\x93\x80\x9f\x21\xde"
-  "\xdb\x81\xdc\x0c\xbc\x5c\x74\x46\xcf\x18\x80\x8b\x1d\xb3\xed\x33"
-  "\x36\x9f\xff\x98\x03\xfe\x13\x6d\x8a\xd8\xa9\x2c\x34\xe0\xf3\x08"
-  "\x3f\x18\xbd\xf6\x10\xf4\x8f\x1d\xe0\x1b\xf7\xbe\x58\xcb\x78\xc5"
-  "\x82\x6d\x23\x8f\xb2\x86\xd5\xa1\xde\x6c\x67\xa8\xc2\x98\xba\xb7"
-  "\xc4\xd0\xe9\xeb\xd1\xd9\x09\xf6\x05\xbe\x00\x7f\xa5\xd4\xaf\x0f"
-  "\xe3\x74\x62\x1a\x13\xa1\x31\x6d\x9e\x42\xc0\x37\x4d\xc9\x39\x4f"
-  "\x02\xd9\xb4\x3d\x2a\x43\xda\x9e\x09\x9d\x69\x7b\xfc\x01\x97\x5e"
-  "\x97\x53\xd1\xe6\x97\x35\xa6\xb4\x3d\x41\xa6\xf4\x42\x62\x54\xec"
-  "\x2d\xd1\x2b\xf6\xa8\xe1\xf7\x14\xd3\x7a\xc0\xc1\x3a\xc2\xcd\x69"
-  "\xa9\xe6\xa0\x1f\x5e\xbc\xd0\x1a\x0e\x76\x24\x39\xe6\x8b\x67\x87"
-  "\x02\x0e\x6a\x01\x07\x3f\x8b\x71\x70\x84\x18\x92\x78\x1f\xbd\x80"
-  "\x62\x01\xf4\xce\xf5\x65\xba\xfc\xf4\x63\x27\xad\xe3\xa1\xce\x3e"
-  "\x3c\x74\x5c\x90\xe2\x21\xcb\x49\x3c\x80\x7f\xf5\xcd\x81\x7e\xd3"
-  "\xe5\x0b\x6a\x26\x0b\xf1\xf0\xa5\x19\x0f\x7f\xfd\x8f\x9e\xe9\x74"
-  "\x18\x0f\x4b\xa6\x39\x88\x87\x44\x17\xf1\x10\x2a\xc2\x43\x1e\xe0"
-  "\xa1\x08\xf0\xb0\xdb\x8c\x87\x8b\x88\x07\x8d\x08\x0f\x85\xf0\xbb"
-  "\xb4\x3b\x1e\x96\xae\xe8\x5b\x3c\x0c\x6c\xfe\x65\xe0\xe1\x59\x9b"
-  "\xfd\x5f\xeb\x78\xc8\x77\x95\x1f\x4a\xcc\x78\xc8\x07\x7e\xc8\x07"
-  "\x7e\xc8\x17\xf1\xc3\x39\xc0\x43\xbe\x88\x1f\xf2\x81\x1f\xf2\xad"
-  "\xf0\xc3\x73\xaf\xf4\x2d\x1e\x86\xd5\xff\x32\xf0\xb0\x6c\x91\x83"
-  "\x78\x70\x91\x1f\xa6\x7a\x88\xf0\x00\xfc\x90\x0f\xfc\x90\x2f\xe2"
-  "\x87\xd3\x88\x07\x11\x3f\xe4\x03\x3f\xe4\x5b\xe1\x87\xe5\x5b\xfa"
-  "\x16\x0f\xc3\xbf\xf8\x65\xe0\xe1\x79\x9b\xe3\xdf\xd6\xf1\x50\xe0"
-  "\x22\x3f\x4c\x5d\x62\xc6\x43\x01\xf0\x43\x01\xf0\x43\x81\x88\x1f"
-  "\x8e\x00\x1e\x0a\x44\xfc\x50\x00\xfc\x50\x60\x85\x1f\x5e\xd8\xd1"
-  "\xb7\x78\x98\x9c\xf2\xcb\xc0\x43\x58\x9c\x83\x78\x70\x95\x1f\x4a"
-  "\x45\x78\x00\x7e\x28\x00\x7e\x28\x10\xf1\xc3\x06\xc4\x83\x88\x1f"
-  "\x0a\x80\x1f\x0a\xac\xf0\xc3\x8a\xbd\x7d\x8b\x87\xa7\xa6\xff\x32"
-  "\xf0\xf0\x62\x6a\x6f\x78\x10\xb0\x80\xb8\x40\x2c\x74\x26\x84\x12"
-  "\xec\x67\xec\x3d\x4b\xf1\x80\x38\xe0\x30\xd1\x12\xea\x6d\x04\x2c"
-  "\x18\xd6\x03\x16\x3a\x28\x16\x50\x17\x88\x07\xec\x57\x60\x7f\x02"
-  "\x31\x61\x84\x3e\x85\x41\x01\x7d\x8a\x8d\x72\x5f\xc4\x41\x87\x67"
-  "\x2f\xfd\x8a\x0e\xc2\xf5\xfd\xb0\x8f\x77\x9e\x79\xe9\x80\x35\x1c"
-  "\xec\x74\x70\x8c\xaf\xab\x7f\x29\xc1\xc1\x09\x33\x0e\x16\xda\xe8"
-  "\x57\xfc\xc9\x06\x0e\x74\x76\xe0\xe0\x7c\xf7\x7e\xa6\xab\x38\xe8"
-  "\x88\xe0\x71\x80\xfd\x4c\x13\xdf\xcf\x7c\x16\xfa\x99\x0a\x47\x71"
-  "\x10\xbe\xd5\x39\x1c\xe4\x27\x3a\x86\x83\xa9\x1e\x18\x27\x50\x1c"
-  "\xe4\x17\x19\x14\x10\x2b\x48\x70\xd0\x43\xbc\x20\xc1\xc1\xca\x43"
-  "\x7d\x8b\x03\x8b\x78\xe1\xbf\x16\x07\xab\x6c\xbe\xff\x6b\x02\xbb"
-  "\x23\xdf\xe3\xb8\x3d\xbe\x67\xe2\xa5\xa7\xe3\x46\xf8\xbe\x49\xc6"
-  "\x2a\xe2\x8f\x3e\xc2\xb8\x36\xd4\x3b\xf5\x3c\x99\xb6\x65\x15\x91"
-  "\x1b\x56\x83\xfd\xa3\x88\xbc\x83\x21\xa4\x63\x75\x98\x77\x45\x83"
-  "\x9e\x8e\x21\xe1\xf3\xa8\x20\xdf\x99\x4a\xc7\x90\x8c\x2d\xa1\x5e"
-  "\x5b\x9a\xe9\x33\xb0\x9a\x67\xfe\x0c\xb6\x8d\x78\xc7\x9a\x6d\x77"
-  "\x39\xc0\xf5\x1d\x62\xae\x3f\x27\xb5\xad\x98\xe7\xb3\x92\x44\x63"
-  "\x48\x73\x6c\x8c\x21\xd9\x61\x53\x6e\x6c\xff\x3c\xe5\xf9\xae\x31"
-  "\x24\x17\xc7\xf8\x3b\x81\xe3\x77\x32\x52\x8e\x77\xce\xa6\x91\x91"
-  "\x3d\x8d\x3b\x62\xfb\xc6\x76\x2d\xb4\xe9\x2e\x1f\x8f\xed\x18\xec"
-  "\x7d\x39\x75\x8f\x9c\xf3\xf5\xeb\xcd\x6d\x1a\xdb\x32\xb6\x6b\x6c"
-  "\xc7\x9c\xaf\xc7\x35\x89\x37\xdf\xab\xcc\x11\x8d\x1d\x19\x15\x3c"
-  "\xcf\x5b\xe1\x78\x53\x8f\x1c\xff\xb2\x55\xfb\x5f\x0f\x1c\x8f\x38"
-  "\x10\xda\xf7\xb5\xd7\xb6\xa3\x6c\x3f\xff\x65\x1f\x0e\x36\xd9\x81"
-  "\x83\x44\xc0\xc1\x32\x11\x0e\xf2\x00\x07\xc0\xf3\x74\xcc\x88\xe2"
-  "\xc0\x3c\x66\x64\xb2\x1c\x33\x92\xe0\x60\x75\x76\xdf\xe2\xc0\x62"
-  "\xcc\xe8\xbf\x16\x07\xd1\x89\xae\xe1\x20\xdf\x0e\x3e\xc8\x47\x3e"
-  "\x28\xcd\x11\x8d\x15\x19\x15\xf9\xc0\x07\xf9\x22\x3e\x30\x8f\x15"
-  "\x99\x2c\xc7\x8a\x24\x38\x58\xb3\xa7\x6f\x71\x60\x31\x56\xf4\x5f"
-  "\x8b\x83\x98\x64\x17\x71\x60\x07\x1f\xe4\x03\x1f\xfc\xde\x53\x84"
-  "\x03\xe0\x03\x3e\xee\xb3\x12\xf3\x99\x7a\x8c\xf9\xd6\xee\xbb\x5e"
-  "\x63\xbe\x6b\x1b\x07\xb1\x36\xe7\x4a\xed\xc3\x41\x81\x1d\x7c\x50"
-  "\x00\x7c\xf0\xfb\x25\x39\xa2\xb1\x21\xa3\xa2\x00\xf8\xa0\x40\xc4"
-  "\x07\xe6\xb1\x21\x93\xe5\xd8\x90\x04\x07\xaf\xbc\xdf\xb7\x38\xb0"
-  "\x18\x1b\xfa\xaf\xc5\xc1\xba\xed\x2e\xe2\xc0\x0e\x3e\x28\x40\x3e"
-  "\x38\x28\xc2\x01\xf0\x41\x01\xf0\x41\x81\x88\x0f\xcc\x63\x42\x26"
-  "\xcb\x31\x21\x09\x0e\xd6\x1f\xe9\x5b\x1c\x58\x8c\x09\xfd\xd7\xe2"
-  "\x20\xce\xe6\x73\x15\x02\x06\xba\xc6\x00\x58\x33\x0e\x38\xdb\xaf"
-  "\x0e\xf5\xee\xf0\xdc\x23\x17\xfa\xff\xa9\xdd\xfa\xff\xf7\x2a\x6d"
-  "\x8e\x03\x59\xcc\x2f\x73\x7d\x83\xf4\x3d\x84\xf6\x13\xf6\x96\xa0"
-  "\xfd\xdf\x58\x47\xfb\x89\xaa\x3f\xa1\xfd\x37\x58\xb7\xbf\xa3\x63"
-  "\x82\xcb\xc0\xfe\x0d\x3d\xd8\xff\x69\x1b\xfd\x84\x27\x5d\xb3\x3f"
-  "\x3e\xef\xd8\x79\xc1\x8d\xf6\x17\xc6\x04\x4f\x13\x66\xa7\x4b\xfd"
-  "\xc5\x78\x9b\xf6\xb7\xfa\x3c\x49\x21\x7d\x9e\x04\x9f\x25\xa9\x6a"
-  "\x6c\x24\x5b\x2e\x11\xa5\x57\x38\xc5\x04\xf7\x4c\x09\x60\x22\xf5"
-  "\x2c\x99\x66\xa0\x75\xeb\x7a\xa6\x04\xd7\x70\xa7\xbc\xa0\xe1\x9e"
-  "\x29\x11\xc6\x03\xba\x9e\x27\x79\x06\x9f\x27\x49\x78\xd7\xe5\xb1"
-  "\x00\x7c\x9e\x24\x1a\x6c\xdc\x0a\x36\xbe\x88\xf6\x3d\x21\x69\xd7"
-  "\x92\x31\x00\x5b\xcf\x91\xd8\x33\xae\x73\x05\x9e\x23\xe1\xc6\x00"
-  "\xdc\xd2\xa6\x13\xa3\x6d\x72\x3b\xd8\x11\xed\xa9\x55\x1b\xb8\x71"
-  "\x5d\xa1\x8d\x6b\x63\xab\xc9\x96\x0e\xa2\x14\xc6\xff\x05\x9b\x22"
-  "\xdf\xb3\x80\x03\xf6\x42\xa8\x02\x6d\xfa\xc6\x2a\xe0\xf9\x08\x33"
-  "\xcf\x9b\x06\x4d\x21\xd9\xeb\x80\xdf\xd7\x91\x40\x4e\x47\x5e\x85"
-  "\x84\x8e\x07\xec\x2d\xc1\xf6\x8e\xed\x99\x55\xec\x99\xd2\xc9\xb7"
-  "\x77\x6a\xef\x4a\x82\x76\xa6\x7b\x7d\x6e\x7c\x07\xdb\x1e\xda\xdc"
-  "\x8b\xb7\x79\x8e\x0d\x9b\x73\xf6\x96\x29\x71\xdd\x10\x7c\xcf\xac"
-  "\xcb\xe6\x86\x57\x45\xe3\x3f\x62\x9b\xf3\xe3\x3e\x26\x68\xcb\x76"
-  "\x3d\x3f\x64\xa7\xdd\xdd\x36\xbe\x0f\x76\xcf\xe1\xed\xde\x35\xbe"
-  "\xef\x92\xdd\x93\x6c\xbf\xff\x22\xb5\x7b\xa2\x1b\xec\x1e\x6a\xc5"
-  "\xee\x79\xbc\xdd\x77\x63\x3f\x1f\xec\x5e\xda\xc9\x3f\x37\xd2\xdd"
-  "\xee\xaf\xa6\x5d\x79\xbb\x0f\x6c\xfe\x65\xd8\x7d\x93\xcd\xf5\xcf"
-  "\xa4\x76\xcf\x77\x47\x7b\x2f\xe9\x6e\xf7\x7c\xbe\xbd\xe7\xfb\x63"
-  "\xbf\x9e\x55\xe4\xf3\xed\xfd\x9c\x15\xbb\xbf\xf6\xda\x95\xb7\xfb"
-  "\xb0\xfa\x5f\x86\xdd\x37\xdb\x7c\xfe\xc3\xc2\xee\x6e\x68\xef\x53"
-  "\x3d\xac\xd8\x9d\x6f\xef\xf9\xbb\xb1\x1f\x0f\x76\xe7\xdb\xfb\x69"
-  "\x2b\x76\x7f\x7d\xc3\x95\xb7\xfb\xf0\x2f\x7e\x19\x76\x4f\x9e\x6f"
-  "\x9f\xdd\x0b\xdc\xd0\xde\xa7\x2e\xe9\x6e\xf7\x02\xbe\xbd\x17\xf8"
-  "\x63\xbf\x9d\x55\x14\xf0\xed\xfd\x88\x15\xbb\x6f\x59\x73\xe5\xed"
-  "\x3e\x39\xe5\x97\x61\xf7\x14\x9b\xcf\xff\x59\xd8\xdd\x1d\xed\xbd"
-  "\xd4\x8a\xdd\xf9\xf6\x5e\xb0\x1b\xfb\xe9\x60\x77\xbe\xbd\x6f\xb0"
-  "\x62\xf7\x37\x56\x5e\x79\xbb\x3f\x35\xfd\x97\x61\xf7\xd4\x19\xbd"
-  "\xcd\xd7\x0b\xb6\x17\xc6\x6c\xb8\xf9\x59\x88\xef\x05\x7b\x23\x0e"
-  "\xd0\xe6\x88\x05\xb1\xcd\xb9\x67\x78\x22\xe8\x33\x3c\x18\xb7\xb3"
-  "\xd0\x17\x67\x07\x71\xcf\x6f\x4c\xe1\xfa\xed\x7c\x1c\xcf\xca\xe4"
-  "\xbe\x18\xcb\xdb\x8e\xe3\xd3\x9e\x16\xec\xed\x6c\xdf\xad\x37\x7b"
-  "\x5b\xf6\xc9\xaf\x15\x7b\x8b\xfb\x6f\xee\xb1\x77\x7a\xa0\x73\xf6"
-  "\xce\x4f\x74\xcc\xde\xf9\x79\xd4\xde\xdc\x73\x1a\xa5\x66\x7b\xe7"
-  "\xef\xa6\xf6\xce\x2f\xb4\xed\xcf\x33\x66\x5f\x79\x7b\x4b\xc7\xe4"
-  "\xff\x7b\xed\x9d\xe9\xdf\xd3\x18\x0c\xda\x1a\xed\x9e\xf1\x22\xf1"
-  "\x7f\xe3\x45\x3a\xb6\x62\xb8\xe0\x8b\x9c\x2f\x47\xfb\xe3\x3b\x3e"
-  "\x5e\x80\x81\x53\xa1\x7a\xd2\xd1\x16\x4a\xf0\x5d\x1e\x7c\xee\xa2"
-  "\x2a\x4c\x47\xb4\xb1\x27\xc9\x96\x28\xa2\xac\x58\xd2\x4c\xe6\x14"
-  "\xb2\x9d\xda\x3a\x0d\xbe\xe3\x2d\xd7\xac\x3b\x49\xd8\x08\xf5\xd0"
-  "\x67\x5a\x09\x73\x9e\xc9\xac\xc3\xe7\x36\xee\x68\x05\x9d\xe0\xfb"
-  "\x3e\x60\xf3\x2d\xe7\x09\x39\x11\x4d\x88\xea\x79\xb4\xf5\x9b\x53"
-  "\x07\xae\xb1\xf2\x9e\x8f\x23\xe3\x32\xe2\xb1\x57\x2b\xb6\xde\xc5"
-  "\xb8\xe7\xd9\x0c\xe1\xb9\x0c\xc9\xb8\x8c\xab\xef\x5f\xba\xed\xd9"
-  "\x8c\xb7\x3c\x7b\x7a\xde\x06\xed\x89\x6d\xda\x90\x4e\xc7\x65\xb4"
-  "\xb1\xe5\x04\x9f\xab\xc1\x36\x6c\x6c\xf1\xf5\x58\x1f\x0d\x6d\xbd"
-  "\x96\xb6\xf5\x37\x9a\x41\x76\xc9\xd7\x04\xf1\x41\x6d\xdb\x49\x6d"
-  "\xdb\x8c\xb6\xfd\x9a\xb0\xab\xd5\x43\xcf\x33\x6f\x1d\x44\xfb\xa2"
-  "\x5d\x13\xbe\x22\xca\xc5\xb8\x2e\x0a\x72\x3c\xf0\x3b\xd8\x79\x4a"
-  "\xee\x8b\x24\x10\xdb\xbf\x31\x6d\x8f\xbf\x21\x8d\x3e\xa3\x81\xbc"
-  "\xdf\xe9\x59\xac\x4e\x89\xe2\xed\xff\x24\xda\xff\x6d\xab\xf6\xdf"
-  "\xe5\xec\xd8\x3b\x6f\x7f\xa7\xdf\xeb\xb9\x5a\xed\x3d\xc2\x5d\xed"
-  "\x7d\xab\xcd\x35\x51\x2c\x70\x90\xe8\x38\x0e\xda\xac\xe0\x60\xeb"
-  "\x61\x2b\x38\xc8\x03\x1c\x84\x5a\xe0\x60\x37\x8f\x83\x42\x38\x5f"
-  "\xda\x1d\x07\xef\x3c\xd0\x37\x38\xb0\xf3\x7d\x9e\xeb\x1e\x07\xdb"
-  "\xfc\xec\xc3\x41\xbe\x13\x7c\x70\xc1\x0a\x0e\xb6\x95\x75\xc7\x41"
-  "\x3e\xf2\x41\x89\x14\x07\xf9\x3c\x1f\xe4\x03\x1f\xe4\x5b\xe1\x83"
-  "\xff\x79\xb8\x6f\x70\x60\xe7\x7b\x3c\xd7\x3d\x0e\xb6\xdb\xf4\xff"
-  "\x16\x38\x70\x82\x0f\xbe\xb1\x82\x83\xed\x15\x56\x70\x90\x87\x71"
-  "\xa0\x05\x0e\x78\x3e\xc8\x2f\xc4\xf8\xb0\x3b\x0e\x76\xcc\xeb\x1b"
-  "\x1c\xd8\xf9\xfe\xce\x75\x8f\x83\x9d\x36\xdf\xff\x95\xe2\xa0\xc0"
-  "\x09\x3e\x38\x6a\x05\x07\x3b\x6b\xba\xe3\xa0\x00\xf8\x60\xea\x12"
-  "\x29\x0e\x0a\x78\x3e\x28\x00\x3e\x28\xb0\xc2\x07\xbb\x16\xf6\x0d"
-  "\x0e\xec\x7c\x6f\xe7\xba\xc7\x41\x96\xcd\xfe\x9f\x05\x0e\x9c\xe0"
-  "\x83\x04\x2b\x38\xc8\xaa\xb3\x82\x03\xe4\x83\x52\x0b\x1c\xf0\x7c"
-  "\x50\x00\x7c\x50\x60\x85\x0f\xb2\x97\xf6\x0d\x0e\xec\x7c\x5f\xe7"
-  "\xba\xc7\x41\x8e\xcd\xf7\xbf\xc5\x38\xe8\xec\xea\x2f\x94\x72\x38"
-  "\x48\x59\x47\x71\xb0\x01\x71\xd0\x48\x9f\xdf\x49\xe5\x71\xd0\xd5"
-  "\x57\x68\xb0\xc4\x40\x8e\xae\x0b\x03\x3f\x9a\xfb\x0a\x9d\x60\x6f"
-  "\x6e\x3c\x88\xef\x27\x08\xe3\x40\x5c\x3f\x01\xfa\x89\x29\xcd\xbc"
-  "\xfd\xb9\x31\x81\x5c\xeb\xf6\x77\xa0\x9f\x28\x79\x46\xc3\xd2\xfe"
-  "\xd7\xf8\x7b\x3a\xdd\xc6\x05\xbe\x72\xf5\xd9\x8c\x3c\x3b\xed\x2f"
-  "\xc4\x05\xf6\xda\xff\x1b\x2b\xf6\xcf\xb3\x62\xff\xfc\x3c\x6a\xff"
-  "\xa9\x1e\x42\x3c\x20\x8c\x0b\x71\xf1\x40\x37\xfb\xbf\xdb\x47\xf6"
-  "\xbf\x36\xdf\xcf\x71\xbf\xfd\xff\x6c\xd3\xfe\x99\x8c\xa9\x04\x8e"
-  "\x52\x38\x34\x70\x94\x1b\x19\x32\x33\x9b\x31\x71\x7b\x33\xe1\x1a"
-  "\xe2\xd9\x49\xdd\xce\x0f\x62\x07\xdd\x98\x85\x32\x60\x43\xae\xff"
-  "\x29\xe4\xc1\xa6\x10\xd4\xa3\x46\x21\x5b\x82\xeb\x5f\xa1\xec\x60"
-  "\x21\x2f\xc5\x46\x12\x24\xe4\x05\xf5\x4b\x04\xbd\x6b\xbc\x37\x06"
-  "\x0d\x02\xf9\x72\x36\xe5\xa9\x22\x90\xf5\xe0\xf2\xdc\x28\xe7\xfa"
-  "\x32\x82\xac\x31\x49\x86\x6b\x36\x69\xbc\x65\x20\x4b\xf3\x1c\xc2"
-  "\xcb\xa9\x4c\x49\x44\xc5\x95\x93\x61\xf0\x7e\x96\xe5\x1c\xca\xcb"
-  "\xf9\x8b\xcb\xa8\xd8\x18\xc4\xe5\xc7\xcb\x0c\x63\x19\x7d\x3b\x5f"
-  "\x17\xb5\x58\xce\x38\x9d\x60\x9e\x82\x9c\x27\x9f\xd7\x04\x89\xcc"
-  "\x9f\x09\xf1\x96\xa9\x68\xf9\x62\x19\xc2\x97\x4f\x81\xb2\xc6\xa1"
-  "\x4f\x26\x1a\x65\xf2\x00\x13\x43\x02\x24\xd7\x6c\x26\x9c\x3c\x2f"
-  "\xeb\xc5\xc9\x0e\x9a\xd6\x0a\xb2\x81\xbc\xce\xe5\x62\x9d\xf3\x72"
-  "\xde\x82\x1e\xc5\xe7\x8c\x49\x0c\xe6\x85\xe7\x95\xec\xa0\x69\x1e"
-  "\x50\x87\x69\x82\x9c\x70\x3f\x6d\x18\x21\x9c\x2c\x43\xee\xe4\x6d"
-  "\x32\x1c\xea\x11\x24\xc8\xe1\x3a\x6a\x82\x2c\xe0\x7a\x54\xae\x59"
-  "\x37\x23\x8c\x29\x8b\x82\x8c\x1b\xe5\x33\x2c\xf3\xf4\xde\x28\xd3"
-  "\xa1\x5c\x65\x23\x97\x37\xda\xaf\x15\xe4\x7f\xc5\xeb\x28\x98\xda"
-  "\x44\xd9\x65\x13\x23\x63\xc0\x73\x9a\x1c\x5a\x56\x1f\x5e\x6e\x56"
-  "\x77\x39\xb9\x58\xee\x06\xaa\xc7\x17\x6b\x40\x37\x73\xbb\xcb\x7a"
-  "\x88\x65\x47\x52\xd9\x67\xa2\x41\x76\x7e\x77\x59\xa5\x58\xf6\x46"
-  "\x2a\xbb\x64\x13\xc8\x86\x5a\x29\xeb\x08\x91\xac\x2f\x95\x7d\x76"
-  "\x2b\xc8\x2e\xea\x2e\xab\x12\xcb\x8e\xa2\xb2\xe1\x75\x20\xbb\xa4"
-  "\xbb\x6c\x90\x58\x76\x34\x95\x5d\xb6\x1b\x64\x97\x75\x97\x4d\x14"
-  "\xcb\xfe\x9a\xca\x3e\x7f\x10\x64\xc3\x2c\x65\x73\xa9\x6d\x6f\xe1"
-  "\x6d\xeb\x47\x65\xc3\xca\x40\x36\xdc\x4a\xdd\x06\x70\xf9\x52\xd9"
-  "\x31\x54\x76\xd1\x76\x90\x8d\xb4\x62\x0b\xb1\xec\x58\x2a\x1b\xd7"
-  "\x08\xb2\xd1\x56\x6c\x21\x96\xbd\x89\xca\x46\x96\x82\x6c\xac\x15"
-  "\x5b\x98\x65\x87\x46\x69\x40\x26\x0e\xea\x59\x6d\x45\xb7\xe2\x3c"
-  "\x6f\xa6\x79\x46\x97\x83\x7c\xa2\x15\xdd\x8a\x65\x6f\xa1\xb2\x31"
-  "\xd5\x20\xbb\xc9\x8a\x6e\xc5\xb2\xb7\x52\xd9\xd8\x5a\x90\x4d\xee"
-  "\x2e\x0b\xed\x8d\xea\xf7\x2e\x5e\xbf\xfe\x54\x7e\x9d\x0e\xe4\x53"
-  "\xad\xe8\x17\xf3\x13\xda\xec\x38\x2a\xbb\xaa\x01\x64\x33\xad\xe8"
-  "\x57\x2c\x7b\x1b\x95\x4d\x4d\x05\xd9\xad\x56\xf4\x2b\x96\xfd\x0d"
-  "\x95\x4d\x3c\x0c\xb2\xdb\xad\xe8\x57\x2c\xab\xa6\xb2\x49\x88\x9d"
-  "\x2c\x2b\xe5\xbd\x45\x24\x3b\x9e\xca\x6e\x2a\x02\xd9\x3c\x2b\xf6"
-  "\x10\xcb\xde\x4e\x65\xd3\xe3\x40\x76\xb7\x15\x7b\x88\x65\x7f\x4b"
-  "\x65\x37\x23\xd6\x0b\xad\xd8\xa3\x4b\x16\xfc\xc2\x04\xe3\xd0\xe4"
-  "\xac\x5c\x94\x97\xc9\xb9\x35\xd4\x58\x86\xf3\xef\x9c\x2c\xe0\x44"
-  "\xc3\xf3\xdd\x44\x9a\x67\x0a\xb6\x4b\x6e\xed\x5d\x94\xa9\x6c\xe7"
-  "\xf8\x08\xfc\x8b\xe1\xee\x5c\x33\x77\xdf\x41\x65\xe3\x11\xbb\x07"
-  "\xc5\x1c\xca\x32\x72\xb1\xdc\x24\x2a\x97\x83\xbc\x50\x2a\x95\xf3"
-  "\x30\xcb\x0d\x7d\x6b\x3e\x9c\x3f\x9c\x63\xc1\xc7\x50\x4e\x71\x5e"
-  "\x77\xd2\xbc\xb6\x2e\x02\x59\x8d\x54\xce\x70\x97\x48\xee\x2e\x2a"
-  "\xb7\x6d\x19\xc8\x95\x49\xe5\x54\x62\xb9\xbb\xa9\x5c\x1e\x96\xad"
-  "\x5c\x2a\x17\x24\x96\x0b\x34\xa6\x6c\x0f\xe7\x64\x37\xca\x2b\x2c"
-  "\xf5\x07\xba\xbe\x4b\xe4\xd3\xee\x31\xa6\xec\x8c\xe6\x65\xab\x05"
-  "\x1d\x72\x7a\xa6\x98\x67\x78\xcc\x4f\x36\xa6\x64\xc5\xf1\x72\x35"
-  "\x62\x3f\x20\xf2\xb5\xbf\x63\x87\x66\x86\xf3\x7e\x94\xee\x31\xb2"
-  "\x51\x5e\x67\x2d\xde\x88\xbc\x9d\x0c\x3b\xcb\xfc\x75\x1a\xf5\x3d"
-  "\xc2\x7e\x5d\x45\x74\xdf\xe4\xac\x08\x5d\x48\x2b\x6b\x10\xa7\x65"
-  "\x30\x6c\xf5\xa4\x56\x22\xc7\x35\x53\x59\x45\x31\xc4\x32\x45\xbb"
-  "\xf5\x63\x22\x49\x5b\xca\x5f\x83\x75\xb2\xc9\xdc\x5e\x1d\xf0\x7d"
-  "\xbe\x8e\x24\x67\xe2\xf7\x8c\x24\xb6\x1d\x74\x22\xc3\xfd\x5d\x72"
-  "\xe1\x7b\x3a\x1c\xdc\x9e\x2a\x10\xd7\xb1\x9b\x49\x90\x26\xc6\x40"
-  "\xce\xc4\x12\xc6\x94\x1e\x9d\xa7\x8a\xc2\x75\x05\xff\xfa\x2e\xbb"
-  "\x36\x6c\x1a\x94\x45\x03\xf7\x5d\x56\x0f\xbf\xb9\xb2\x40\xfd\xc1"
-  "\x37\x1e\xd6\x44\xe1\xda\xa2\x7f\xfd\x52\xaf\x28\xd6\xb0\xaf\x3e"
-  "\xf5\x63\x64\x3c\xb9\x09\xca\x5f\xd3\x02\xdc\xd0\xb2\x36\xec\x7e"
-  "\xcc\xc3\xa4\x88\x3e\x0c\xe5\xcd\xc4\x35\x09\xd9\xed\xfb\xf3\xe8"
-  "\x7a\x85\x45\xdc\x7a\xee\x50\x9e\x6a\xd6\x2f\xa2\xda\xd4\xb1\x29"
-  "\x11\xf7\x86\xd3\xc4\x9f\x25\xf5\xa2\x73\xfa\x51\xfb\xb9\xb5\x0c"
-  "\xa1\x7e\xd5\xc6\xe4\xaf\x77\x9b\x3c\xbe\xce\x63\x93\xbf\x27\xda"
-  "\x70\x1d\xa1\x7b\xc1\x14\xed\x61\xbd\x16\x6a\x4d\xc9\x5f\x27\xb3"
-  "\xc9\x0d\x7a\x6d\x6b\x07\x97\x0e\x79\x2c\xc2\xb8\xb3\xc5\xe3\xdb"
-  "\x38\x36\xf9\xdb\x44\xcd\xe8\x0e\xd2\xc0\x14\x71\xfe\x01\xd3\xd9"
-  "\x2d\xdf\x13\xd4\x95\x69\x4b\x83\x7e\x80\x2f\x91\xb7\x0c\xf9\x36"
-  "\xae\x2d\xa5\x28\x4e\xd8\x93\x44\xb8\x17\xe6\xab\xe3\xf3\x82\xf3"
-  "\x59\x3a\xd9\x8d\x4a\xba\x4e\xe2\x5f\x6b\x7a\x78\x46\xc4\x9b\x4d"
-  "\x8b\xae\x05\xf9\x0a\x88\x2d\xe3\xa8\x0d\x8a\x6a\x75\x32\x45\x1d"
-  "\xff\xbd\x41\x27\x1b\x3e\x83\xff\xae\xd7\xc9\x26\x06\xf3\xdf\xbb"
-  "\xd6\x7f\xb4\xbe\x1e\x65\x74\x11\xe8\xbc\xcc\xb4\x2b\xd4\x03\xe3"
-  "\x62\x8c\xf5\x59\x45\x74\x91\x6a\x2c\xee\x43\xb8\x6f\x2b\xdc\xb3"
-  "\x8c\xee\x05\xb0\x6f\x21\x7c\x7a\xf3\x9f\x7a\xfe\x93\x45\x19\x0e"
-  "\x57\x7e\x91\x73\xd9\xd4\xc2\xed\xa8\xef\x78\x23\x6b\x82\x7c\x1b"
-  "\x41\x77\xed\xda\xd8\x46\x5e\xa7\xfb\xb8\x3d\x90\x39\x9b\x82\xdd"
-  "\xd9\x21\x0d\xed\xdc\xbd\xd2\x8a\x35\xe2\x72\x05\xdc\x79\xd7\xdd"
-  "\x81\xf7\x4c\xfe\xdd\x94\xa9\x4b\x9f\x7d\x6e\xd9\xf2\xe7\x5f\x08"
-  "\x5b\xf1\xe2\x4b\xe1\x2b\x57\x45\x44\xbe\x1c\xb5\x3a\x7a\x4d\xcc"
-  "\xda\xd8\x57\xd6\x41\x3e\x5d\x7b\xd0\xb1\xbb\x66\xc8\x5a\x19\x02"
-  "\xf7\x98\x8e\xf7\xb8\xc8\x95\x05\xd2\x28\x1e\xf6\x35\xc8\x55\xd6"
-  "\xf5\xa9\xf5\x85\x7e\xcf\x2d\xb8\xff\x57\xf1\x03\xb8\xef\x0d\x60"
-  "\x4f\xa6\xcd\x7a\x48\x83\xfb\xa6\x35\x30\xc5\x81\x55\xfa\x87\x34"
-  "\xb8\x6f\xdf\x71\xdf\x46\xe2\x7f\x0b\xee\xad\x56\xac\xc2\xf3\xb9"
-  "\xb7\x11\x52\x06\xd7\x5a\xcb\xf3\x16\x25\xf1\x7d\x7b\x24\xab\xdf"
-  "\x3a\x92\x6d\xc2\xfc\xb7\x6e\x63\x1b\xf5\xeb\xc3\x48\x3a\xfc\x06"
-  "\xcc\x2a\xcf\x30\xc5\x17\x8f\x43\xa4\x0d\x31\xb4\x5f\xce\x36\xb6"
-  "\x61\xd3\x48\xb6\xe1\xd5\x6d\x6c\x53\xee\x48\x56\xe7\xbf\x95\x78"
-  "\xb6\xa5\x14\x17\xea\x98\x62\x6e\xbd\xf4\x0c\x38\x6f\x1a\xba\x2f"
-  "\x2f\x03\xce\x4d\x32\x90\x01\xb9\xf0\x1b\xd2\x5a\x8f\xab\x68\xb9"
-  "\xf7\x37\xb7\x0f\x84\xfc\x52\xd9\xce\x70\x59\x3a\xdc\x87\xda\x68"
-  "\xff\xa8\x32\xf0\xfe\x70\x3f\xbd\xb6\xbd\x1e\xb0\xb8\xdf\x17\xf7"
-  "\x93\x82\xfb\x79\x6b\xb7\x37\x11\xcc\xaf\x38\xaa\x7d\xe0\xea\xd1"
-  "\xac\x01\xae\x6d\x37\xad\x0f\x97\xc1\xfd\x6a\x20\xef\x56\x71\x7d"
-  "\xd4\xcf\xaf\x8c\x56\xad\x5a\x13\x1e\x3e\x7e\x28\x51\x73\x9f\x92"
-  "\x3d\xff\xa2\x71\x2d\xda\xb7\xb7\xb1\x65\x50\x4f\x0d\xd4\xb7\xbc"
-  "\x12\xa2\x7d\xc0\x0b\x81\x3a\x65\x42\x19\x56\x42\xfa\x61\xf8\x7e"
-  "\x18\xca\x5e\x4e\xf7\x89\xd3\xec\x60\x53\xf6\xfb\x43\x39\xd1\xdf"
-  "\xa8\x70\xed\xda\x96\xb5\xf3\x65\x50\xef\xad\x20\x57\xae\x1a\x4d"
-  "\xc6\xc1\x75\x17\xa1\x1c\xbb\xe1\x3b\xca\x73\x7c\x00\xf2\x3c\xf6"
-  "\x34\x5b\xf0\x37\xe8\x4a\x93\x3d\x92\x4d\x6d\x4b\xd9\x5f\x8d\x6b"
-  "\x72\x73\x7b\x17\xc1\x6f\xd0\x4b\x39\xc8\x66\xb6\x24\xcc\x97\x41"
-  "\x9f\x51\x96\x6b\xce\x33\x0f\xcb\x84\xe5\xc0\x7e\xe8\x29\x88\xfa"
-  "\x4c\x9d\xa1\x64\x62\x3b\x91\x9d\x6a\x20\x24\x6b\x1b\x9b\x07\x47"
-  "\x16\x1c\xdb\x4f\xc2\xb9\xcf\xe0\x28\x87\xf4\x0a\xf8\x3c\x09\x9f"
-  "\x9f\xc1\x01\xfd\x58\x5f\x2c\xf7\xea\x38\xb6\x71\xd2\x76\x72\x2b"
-  "\xe6\x0f\xd8\x7a\xa2\x9e\x39\xaa\xc7\xb2\xe3\x9a\xf7\xec\xd0\x92"
-  "\x65\xd2\x75\xc2\x0f\xd4\x12\x38\x0f\x9f\x4d\xf4\x53\x7c\xbc\x17"
-  "\x08\xc7\x7c\xfe\x7b\x16\xc8\x94\xf1\xdf\x4b\xe0\x38\xdc\xfb\x61"
-  "\x99\x9f\xad\xe3\x6f\x6a\xfb\x65\xed\x39\x34\xcb\xec\x93\x3b\xa8"
-  "\x23\xcc\x87\xd0\x0b\xfe\x30\x52\x9a\xfe\x61\x30\x4d\x3b\xec\x43"
-  "\x7f\x1f\x56\xf1\x9f\xb3\xe0\x00\x3d\x1d\x81\xfc\x8f\x24\xd3\xb4"
-  "\x23\x5b\xe1\xb3\x0e\x8e\x46\xe9\xfd\x35\x70\xbd\x26\x0e\xed\xd9"
-  "\x99\x04\xfe\x02\x6c\xa9\x63\x4a\x02\xd1\x46\x19\x14\x5b\x32\x13"
-  "\xcb\xa5\x05\x00\xb6\xb2\xcc\xf8\x79\x6f\x9c\x14\x3f\xef\x29\x2d"
-  "\xf0\x93\x89\x5c\x04\xed\x25\x2e\x97\xe2\xe5\x70\xcb\xfa\x65\xf0"
-  "\xfb\x3d\x1f\xc8\xe7\x30\x8e\x8f\x40\x1e\x5c\xac\x9a\x71\x96\x10"
-  "\x45\x18\x91\x23\xbf\x34\x31\xef\x2d\x47\xcc\xe2\xbd\xf9\xfb\xd2"
-  "\xb2\x40\xf9\x20\x2d\x0f\xcb\x17\x01\xf9\xc2\xef\xdd\x20\x97\xa7"
-  "\x25\xcd\x42\xd9\xb8\x6b\x52\x5e\x04\x3c\xf2\xe5\xc5\x3c\xf1\x3a"
-  "\xd6\x5c\xaf\x00\xbc\x86\xde\xfb\x6f\xa3\x20\x1d\xfb\xb5\xf8\xee"
-  "\xd3\x00\xad\x41\x47\x10\x93\xf8\xa9\x35\x04\x40\x5b\x0a\x26\xa6"
-  "\xb6\x50\x32\xc9\x97\x04\x40\x7b\x1b\x52\xcf\xbc\x67\xb8\x23\x8e"
-  "\x04\x60\x7e\xc8\xe9\x50\x0f\x4d\x2e\xb6\x45\x9a\x17\xe7\x07\x31"
-  "\xff\x93\x91\x84\xbb\x4f\x0e\x96\x07\xce\x8b\xee\xbb\x15\xfb\xb0"
-  "\x19\xeb\x68\x5d\xe1\x5e\xbb\xe1\xfa\x12\xac\x3b\xea\x13\xce\x97"
-  "\x42\x3e\xa1\x78\x8e\xdb\x37\x88\xd6\x67\x37\xee\x2d\x81\xfa\x40"
-  "\x79\xdc\x87\x92\xae\x11\xbe\x7f\x03\xa7\x37\xb8\x1e\xed\xc1\xc2"
-  "\x3d\x30\x8f\x04\x03\x6b\x60\x81\x8f\xfe\x77\x5d\x3b\xc4\x1d\x07"
-  "\x3f\x97\xda\xe7\x6f\x25\x62\xfb\xc0\x75\x25\x70\x7d\x19\x0b\x75"
-  "\x44\x3e\x81\x7b\x7a\x63\xac\x01\x69\x99\xa6\x14\xc8\x23\xa6\x9d"
-  "\x1b\xd3\x81\x7c\x8e\x41\x59\x32\x31\x1f\x28\x4f\x19\x9f\x97\xe1"
-  "\x58\x9c\xd4\xd6\x7c\x7e\xbb\xd1\xe6\x5c\x7b\x5e\xc7\xd5\x09\xb8"
-  "\xeb\xe0\x9b\x39\xf4\x5c\x29\xc8\x94\xb2\x9d\xc1\x04\xf7\x6a\xa0"
-  "\xbe\x84\x3b\x77\x30\xe1\x32\x67\xdf\x32\xca\x6b\x07\x0f\xac\xde"
-  "\xc0\x36\x9a\xcb\x7d\x30\x4c\xd8\xef\x82\x2f\xf7\x41\xbc\x1f\xbb"
-  "\x76\x11\xe7\x57\xf1\x1e\x78\x3d\x9f\xdf\x0c\xcc\x4f\xd0\xd5\x1d"
-  "\x50\x0e\xaa\xaf\xbf\xc5\x42\xfa\x6e\xc4\x22\xa7\x37\xe0\xd1\x96"
-  "\x04\xc4\xe2\xc1\x70\xb8\xfe\x70\x3a\xfe\x5e\xcb\xfd\x26\x1c\xc7"
-  "\x76\x9d\xff\xdb\x41\x3c\xaf\x6d\x04\xbb\xbd\x04\x58\x32\x11\x72"
-  "\xab\x0f\x09\x68\x4d\xe2\xea\x56\xd4\xba\x7e\x86\xec\xb8\x81\x10"
-  "\x2c\x27\xe8\xa8\xb4\x2d\xe5\x7d\x1f\xe0\xfe\xf9\x58\x56\xe0\xeb"
-  "\x83\xec\xff\x86\x12\x2c\x33\xf0\x19\x5f\xbe\xf7\x5f\xe3\x6d\x7f"
-  "\x10\xeb\x88\xfa\xbc\x83\x72\x1f\x9c\xfb\x70\x3c\x96\xdd\x5c\xef"
-  "\xf7\x97\x88\x75\xcc\xd5\x1b\xec\x80\xf6\x42\xbb\x88\xf2\x44\xec"
-  "\x67\x42\x5e\x45\xf4\x37\xc5\x06\xea\x3a\x73\x24\x5b\x81\xf2\x66"
-  "\xd9\x0f\x76\xe0\xb9\x78\xb8\xf7\xa4\x48\xf0\xe9\xd0\x2e\x70\xcf"
-  "\x12\xc8\xb7\x08\xf7\x18\x85\x3c\x4a\x51\xa7\x20\x77\x0e\xf1\x08"
-  "\xbf\x2b\xf8\x7b\xe0\xfe\x76\x13\xe0\x98\x66\x6e\xff\x1f\x9c\x96"
-  "\xe2\xeb\x03\xcb\xf6\x8f\xf6\xce\x34\x25\x04\x13\x0e\x0f\x51\x44"
-  "\x75\x9e\xf9\xe0\x15\xde\x77\xf0\xb6\xfe\xa0\xf2\x38\xb4\x17\x51"
-  "\x1e\xf3\x2d\x6c\x5d\xca\xe1\x71\xed\x2c\x19\xd6\x19\xae\x2d\xe5"
-  "\xf3\xe1\xea\xcc\xe1\x29\x89\xc3\x40\x05\xbb\x16\xea\xd9\x85\x83"
-  "\xf7\x4b\x78\x3b\x57\x58\xe8\x84\x2f\xfb\x01\x03\xee\x2d\x87\x9c"
-  "\xd4\x96\x44\xee\x6f\xeb\x34\xf3\x12\xda\xde\xc4\xd9\xfe\x83\xd0"
-  "\x5c\xea\x6f\x79\xde\xfa\x80\x9e\x1f\x29\xc1\x30\x96\x25\x8d\xc3"
-  "\x2f\x96\x25\x61\x11\x96\xa5\x94\x2b\x47\x82\x8a\x9c\x67\x3e\xe4"
-  "\x38\x0d\xae\xcd\xe4\xdb\x2b\x9f\xd7\xfb\xcb\x30\xaf\x57\x81\xab"
-  "\xb0\x4c\x3a\xe6\x80\x9e\xe3\xbf\x07\x39\x1c\x2c\xe7\xcb\x5e\xde"
-  "\x9e\x84\xd7\xbe\x17\x7a\x99\xe1\xae\x2d\x07\xb9\x8a\x76\xba\xff"
-  "\xcc\x50\xb8\xbe\x10\xd7\xfc\x3f\xc3\x7c\x5c\x86\x1c\x8d\xf3\x4d"
-  "\xf0\x7d\x1f\xbe\x1b\x0a\x9c\x22\x87\xfc\x3c\x10\xa3\x02\x2e\x9a"
-  "\x98\x8f\xb3\x71\x6d\x7c\xd0\x75\x11\xc4\x48\x85\xa8\x6f\xc4\x32"
-  "\xc4\x48\x81\x6d\x29\x1f\x56\x08\xb8\x85\xfb\x64\xa1\xee\xa9\x7d"
-  "\x4a\x87\x03\x8e\x4b\xcd\xd8\x2a\x1d\xce\xeb\xb1\x10\xf4\xe8\x01"
-  "\xf7\x7b\x93\xaf\x57\x21\xc8\x43\x2c\xf6\xf1\x46\xbe\xec\xfc\xfe"
-  "\xa5\xa5\x13\x05\x3b\xf0\x6d\xb5\x22\x1d\xf9\x97\xb3\x41\x69\x19"
-  "\x7f\xed\x6e\xfe\x5e\x27\x04\x59\x8c\x11\xe9\xbe\x52\xa5\x27\x90"
-  "\x07\x27\x81\xed\x39\xee\xe3\xf6\xdf\xa5\x69\xd8\x76\xe8\x3d\x3e"
-  "\xe6\xf6\xa3\x78\x15\xe2\x1e\x33\x8e\x4a\xb3\x2c\xf8\x09\xb9\x38"
-  "\xb3\x0a\xf2\x40\x3e\x45\x2c\x21\xa7\x62\x1f\x06\xf2\x8b\xe6\xdb"
-  "\x0f\x5f\xe6\x43\x43\xa4\x58\xf9\x78\x21\x60\x65\xa2\x28\xef\x76"
-  "\x6b\x7e\x2e\x97\x72\x60\x16\xbd\xe6\xd0\xc3\x7c\xdd\x8a\x68\xdd"
-  "\xf8\xdf\xa8\xb7\x78\x4e\x6f\x0a\x91\x1e\x41\x6f\x1f\xbd\xc2\xcb"
-  "\x97\x22\x97\x9b\xdb\xeb\xa1\xf7\x85\xb6\xdc\x9d\x2f\x3e\x5a\x81"
-  "\xed\xc1\x5c\xae\x43\x99\x16\x7c\x51\x6a\x9d\x2f\x0e\x2d\xe1\xeb"
-  "\x9b\x67\xd1\x36\x76\xf3\xf1\xee\x06\xc1\x0e\x55\xd0\x47\xa3\x7b"
-  "\x28\xed\xdf\x80\xfc\x89\xf7\x16\xfb\xa0\x1c\xaa\x57\xbe\x2d\x7f"
-  "\xb4\xa0\xbb\x1d\x3e\xf2\x17\xb7\x67\xb4\x35\x72\x02\xe6\x81\x36"
-  "\xe5\xe2\x4a\x48\xa3\x76\x3d\x64\x40\x6e\x10\x73\x34\xc8\x6e\x35"
-  "\xb1\xd8\x5e\x3e\x52\x4b\xdb\xe2\xa1\xad\x7c\x5b\x14\xee\x7d\x19"
-  "\x6c\x14\x20\xba\x6f\x96\xc5\x7d\xd1\x36\x65\xa8\x07\x5a\xc7\x8f"
-  "\xbe\x17\x7c\x1a\xca\xc3\xb5\xb1\x70\x4d\xb5\x85\x7f\xcc\xc4\xf2"
-  "\xc1\xbd\x82\x39\xce\xda\xc6\x71\x45\x6c\x1b\x2d\x4f\x4d\x2e\xef"
-  "\x27\x20\x2d\x80\x4f\xcb\xe3\x7d\x89\x80\x9b\x99\xd2\x32\x7d\x1c"
-  "\x60\x3d\x3e\x3a\x14\x2c\xc4\x47\x5c\x5e\x1c\x17\x7d\x1c\xc8\xd7"
-  "\x0f\xd3\x26\xd2\xb4\x52\x03\xa6\xa5\x53\x3d\x6c\x65\x39\x7f\x55"
-  "\x9a\xc7\xfb\x2b\x6c\x5f\x0c\xfc\x56\x62\x1b\xc3\xdf\x90\x47\x32"
-  "\xe6\xaf\x4d\xec\x40\x9f\xb6\x5d\xc7\x7c\x58\x84\x7c\x80\x7c\x81"
-  "\xcf\xb0\x72\x9f\x73\xb8\xcf\x2f\x91\x77\x30\x0e\xc1\xf3\x20\x97"
-  "\x85\x5c\x04\xe9\x3f\xe2\x5e\xad\xec\x4f\x1e\x90\xef\xc7\x15\xfc"
-  "\xb5\x46\x2e\x56\xf8\x29\x78\x80\x90\x26\x5c\x07\xbc\xb5\x0f\xaf"
-  "\xc3\xeb\x05\xfe\x42\xee\x32\x20\x37\x71\xf7\x3b\xfc\x00\x8f\x71"
-  "\xae\xdf\x20\xc4\x45\x9d\x8c\x48\x16\xf7\x9e\xe1\x38\xed\x70\x2a"
-  "\xe5\xb3\xc3\x1b\xf0\x5a\xce\x7e\xc0\x95\xf1\x97\xd9\x6f\x73\xa3"
-  "\x88\x3c\xa7\x19\x79\x71\x7f\x1c\x2d\xe7\xe1\x5a\x5a\x8f\xc3\xef"
-  "\x72\xf5\xa0\x9c\x9a\x49\xcb\xb2\x3f\x2e\xa7\x83\x3b\x77\x04\xeb"
-  "\x82\xe7\x32\x44\xe7\xd8\x4e\x35\x9e\xe3\xf6\x58\xb6\xbc\xce\xd4"
-  "\x19\xd6\x4d\x1e\xf7\x1e\x06\x0e\xf5\xc8\xd9\x26\x70\xef\x91\x50"
-  "\x5a\xce\x23\x37\x08\xbc\x0b\x7a\xd9\x8d\xdc\xcb\x9d\x7b\x9e\x97"
-  "\x99\xc3\x7f\x72\xfc\x7e\x64\x26\xd5\xab\x2f\xc3\xeb\xbb\x88\xd6"
-  "\xe3\xc8\x42\xae\x9f\xfd\x53\x28\xe8\xf6\xc8\x34\x41\xb7\xe2\xef"
-  "\xd8\x7e\xe0\xfe\x68\x63\xca\x2b\x71\x5c\x1f\x36\x0b\x65\xb0\x4c"
-  "\xd4\x47\x1c\x0e\xb4\x8c\xa9\xcf\x30\x47\x3f\x47\xbf\x44\x63\xd5"
-  "\xa3\x07\xf8\x71\x21\xa2\x89\xfa\x33\xf8\x85\x23\x06\x81\x63\xd8"
-  "\xb6\x60\xe8\xf3\xd7\x63\x19\xb9\xbd\x94\x70\x3f\x11\xb1\x0c\xf2"
-  "\xd3\xfe\x0e\x1d\x9f\xe7\x91\x5a\x81\x37\x90\x4b\xaa\x5a\xeb\xf9"
-  "\x98\xee\x93\xe4\x1c\x9e\x4b\xce\x33\x9f\x6c\x91\xc6\x61\x9f\x6c"
-  "\x91\x72\xc6\xd1\x6c\x4b\xce\x80\xb8\x79\x53\x5b\xca\x27\x8b\x24"
-  "\x71\x00\xa4\xf5\xcc\x1d\x9f\x04\x60\x1b\xc5\xfd\xe4\x38\x7e\xe2"
-  "\xc6\xba\x3e\xf9\x59\x28\x33\xf2\x66\xcb\x7a\x61\xfc\xe2\x68\x1a"
-  "\xc6\x6a\x16\xf7\xab\x90\x70\x27\xde\x4f\xc8\x4f\x4e\x70\x3f\x32"
-  "\xd0\x03\x8e\xb7\x7c\x92\xc5\xf3\x7c\x9e\x84\x2b\x79\x1f\x86\x3c"
-  "\x29\xf5\x55\xfb\x37\x48\x7d\xd5\xd1\x57\xba\x73\xe4\xd1\x60\xfb"
-  "\x7d\xd5\x51\x15\xf2\x96\xc0\x91\x52\x2e\x38\x3a\x2b\x47\x12\xcb"
-  "\x7e\x52\x23\xc4\xb2\x66\x1e\xfd\x64\x19\x72\x14\xdc\xbf\x94\xbf"
-  "\x37\xc4\x1e\xfb\xca\x85\x7b\x03\x8e\x0c\x55\x2a\xc0\x66\xca\xfe"
-  "\x00\xf8\x5e\xc8\xc7\x80\x5c\xdb\xec\xe0\xf6\x2e\x3a\xac\x07\xfc"
-  "\x0d\x45\x9c\x69\x56\x35\x93\x06\xb3\xaf\x28\x6b\x89\x10\xf4\xab"
-  "\x59\x20\x8e\x0b\xb3\xb7\xb1\xc9\x6d\x29\x9a\x09\xe2\x3a\xa6\x41"
-  "\x5a\x06\x3f\x86\xc0\xe9\x96\xcb\x4b\xc3\xf5\x17\xc4\x75\xa3\xf5"
-  "\xd0\x04\x62\x3d\xb0\x4f\x04\xf7\x6f\xc5\xb8\x07\x62\x3e\xf8\xfe"
-  "\x61\x6c\x6e\x17\xe6\x0f\x54\x5c\x4e\x12\xc7\x57\xfb\x6b\x90\x2b"
-  "\xf9\xbe\x67\x39\xc4\x3b\x99\xe2\xb1\x98\xd9\x7f\x9c\xab\x8a\x8c"
-  "\x5a\xb1\x2a\xfa\xf9\xbb\x54\x2b\x56\xad\x88\x5e\xb1\x34\x7c\xc5"
-  "\xba\xa5\xd1\x2b\x22\x56\x4d\x58\xb9\xf4\x85\x15\xcf\xa9\xd6\x2e"
-  "\x5d\xad\x0a\x88\x1d\x17\x3b\x94\x98\x45\xef\x55\x2d\x5d\xbd\x7a"
-  "\xcd\xca\xe5\xcb\x54\xab\x56\x3c\x37\x31\x6a\xf9\xea\xe5\xd1\xaa"
-  "\xa5\x51\x11\x6b\x56\x2d\x53\x8d\x5b\x76\xc7\xb8\x80\xc9\xcb\x86"
-  "\x8a\xc7\xd0\x6e\x51\x92\x26\xd3\xa5\xc6\xc6\x8c\x4b\xc4\xc3\x5b"
-  "\x16\x19\xe5\x1d\xbb\x62\x15\x1d\xb3\x3b\x96\x3d\x69\x2b\x89\x84"
-  "\xf3\x9e\xb8\x37\x32\x9b\xa2\x29\x81\x4f\x39\xca\x41\x3d\x55\xf0"
-  "\xdd\x03\xca\xee\xd7\x96\x72\x6c\x89\x8e\x39\xc1\x8d\x37\x82\x2e"
-  "\x54\x50\x37\x3f\xf6\x52\x79\x23\xc4\x6c\x91\x38\xb7\x9e\x7b\x89"
-  "\xf8\x64\xc6\x10\x39\x1c\x9e\x70\x28\x19\x25\x8e\x75\x1d\xdb\xaa"
-  "\x63\x3e\x2d\xa1\xe3\x9e\x9f\x06\xea\x87\xd4\x1f\x64\x93\xeb\x0f"
-  "\x52\xbb\x7c\x7a\xa7\x30\x0e\x1d\xf2\x1a\x09\x41\x7c\xd6\x33\x9f"
-  "\x72\x73\xba\xaf\x02\x96\x71\x0c\xb7\xe5\x93\xe9\x41\x10\x0f\xd6"
-  "\xe1\x18\x2c\x9c\xbb\xb3\x95\x21\x9e\x50\x2e\xf9\xf1\xb8\x00\xf2"
-  "\x36\xdc\x6b\xb5\x2f\xcb\xc2\x3d\xda\x85\xf1\x34\xa8\x83\x12\xea"
-  "\x52\xcb\xd7\xe3\xdf\x5c\x3d\xb6\xb1\xfe\x5b\x47\x40\xf9\xde\xc2"
-  "\xf2\x7c\xea\x2f\xd4\x01\xca\x5d\xab\x63\x8e\x25\x43\x39\x95\x58"
-  "\x2e\x6b\x63\x7d\x38\xde\x05\xe5\x5c\x69\x8a\x01\xbd\x8d\xa5\xfb"
-  "\xe1\x65\xe4\xd0\xf6\x07\xf5\xd9\x9d\x0b\xdf\xd3\x9b\x89\x67\x1a"
-  "\xee\x5b\x9e\x74\x13\x5b\xd9\x6a\x20\xda\xb0\x5a\xe2\xfd\x0a\xab"
-  "\x67\x3f\x68\x6c\xe4\xeb\xb4\x1d\xb9\xe1\x6f\x2f\xd6\xca\xb1\x4e"
-  "\xe0\x2b\x3c\x73\x9b\x6d\x8e\x2d\xca\xdf\x1e\xc9\xb6\xb2\xbb\xc4"
-  "\x31\xd7\x71\x6e\x3f\x67\x8c\xb7\x5a\x92\x70\xff\xeb\x4f\x1b\xe1"
-  "\xde\x41\x7c\x6c\xdc\xca\x76\x2e\x12\xc5\x52\x9f\x22\xce\x5a\x6d"
-  "\xe4\xed\x21\xe4\x8d\x7b\xa4\xe3\x35\xd4\xfe\xc7\x57\xc2\x35\x7a"
-  "\x73\xfe\xc7\x83\x2d\xf3\xc7\x3c\xe1\xbb\x5e\xb8\x0f\xed\x87\x1f"
-  "\xc7\x98\x40\x0f\x58\xd6\xdb\xb8\x9f\xff\x5b\xdb\xd8\x1a\x2d\xa4"
-  "\x67\x5c\x26\x72\x90\x85\x18\x85\xcb\xbf\x10\xf4\xee\x89\xf9\xbf"
-  "\x3a\x92\x90\x4d\x20\xd3\x92\xf2\x69\x50\x2b\xb7\x5f\xf9\x71\x68"
-  "\xff\xfb\xa7\x58\x8e\x63\xf3\x78\xbe\xd7\x02\xcf\x41\x6f\x61\x4c"
-  "\xb8\x15\xf2\x07\x0c\x65\x5c\x04\x3f\x0c\xbf\xef\xd8\x4a\xd4\x78"
-  "\x1f\xf8\x5e\x8d\xe3\x21\x6d\x29\x65\xbe\xc2\xfd\x58\xc0\x7f\xba"
-  "\x89\x8e\xc1\xf0\xd8\x9a\x80\x63\xd7\x09\xb1\x2c\x7b\x1c\xf8\x1d"
-  "\xcb\x88\x18\x83\x6b\x66\x09\x98\x02\xac\xd7\x70\xb8\xf2\x21\x6a"
-  "\x36\xe5\x78\x75\xee\x08\x90\x03\x5c\xe5\x00\x9e\x10\x57\x20\x1b"
-  "\x2b\x60\x0a\xb0\x56\x8d\x72\x50\x86\xa1\x25\xeb\x82\xe4\xc8\x91"
-  "\x0d\x4c\xd9\x39\xc4\x18\xfb\x3f\x8f\xd6\xb2\x37\x3e\x55\x4b\xed"
-  "\x54\x76\x4e\xdb\x4e\x6d\x60\xd6\x7b\x99\x46\xa4\xf7\x6a\xc0\xf1"
-  "\x50\xd4\x33\x1d\xab\x2e\x3b\x07\x65\xab\xe6\x62\xf1\x0d\x60\x03"
-  "\xce\x57\x95\x15\xe1\xf5\xbc\x0e\x2b\xcc\x3a\x3c\xe1\x61\x4d\x87"
-  "\x16\xba\x93\xd3\x3d\xd1\x4f\xf8\x60\x5b\x81\x6b\xa6\x09\xfb\x9c"
-  "\x5b\xb3\x25\xdc\x43\x2e\xdf\x4a\x3c\xf0\x1e\x65\x3e\x9c\x7c\xb8"
-  "\xb5\x7b\x58\xe2\xb8\x2c\x8f\x10\x1c\x0b\xc7\xeb\xfc\x7d\x50\xaf"
-  "\x27\x76\x5b\xb5\xef\x73\x92\xb2\x71\x07\x94\xad\xe4\xed\x11\x80"
-  "\x1b\x5a\xbe\xba\x9e\xca\xe7\xaf\xa2\x7e\x51\x73\x0b\xe2\xf9\xef"
-  "\x37\x68\xb7\x13\x82\x69\xfc\x6f\x79\x0b\xf8\x1a\xcb\xf1\x7c\xdb"
-  "\xf3\x0b\x7f\x5f\x20\x9d\x5f\xf8\xfb\x0c\x5b\xf3\x0b\x16\xf7\x7d"
-  "\x13\xef\x6b\xca\x9d\x2f\x13\xdd\x3b\xce\x64\xe5\xde\xc2\xf5\x77"
-  "\xe4\x89\xfb\x2f\x7f\xff\x16\xcb\x50\x05\xde\x86\xfd\xf5\x7c\x19"
-  "\x0b\xf9\x94\x71\x3e\xfb\xef\x3a\x1a\xaf\x60\x1c\xf4\x77\x0d\xca"
-  "\x58\xd6\xa3\xeb\xcf\xc3\xe7\x18\x7e\x5c\xe6\x7e\x0c\x7c\x90\x28"
-  "\xf1\x73\x74\x9e\x70\x9a\x91\x08\x13\xd6\xca\x0f\x4f\x42\x7e\xcd"
-  "\xc9\xb3\xf0\x47\x93\xf8\xdf\x7a\xee\x87\xbc\x4b\xbe\xeb\xbc\x0b"
-  "\x7f\x43\x68\x79\xb9\xfc\xda\x89\x8c\xbf\x9f\x46\x24\x31\xa3\x87"
-  "\xab\x59\x22\x5c\x62\xed\xef\x65\x38\x12\xe7\x0f\x84\xfc\x74\x9c"
-  "\x30\xcb\x1a\xf8\xfc\x85\xdf\xac\xf8\x37\xa6\x48\x7f\xc3\xdf\x80"
-  "\x45\xa2\x1b\xdc\x34\x60\x19\xf7\x58\xd4\x58\x43\x57\x12\x93\xa7"
-  "\x94\xde\x34\x71\x20\xf7\xe1\x8d\xff\xc4\x42\x7e\x6a\x38\xef\x67"
-  "\x3e\x3d\xa0\x75\xa3\x48\xf8\x14\x2d\xfe\x98\x29\xb6\x2b\xe1\xf0"
-  "\xdf\x58\xd1\xf7\x9b\xe8\x87\x5f\xbb\x55\xc9\x2b\xf1\xa7\xaa\x1e"
-  "\x22\x7c\x35\xc3\x63\x4c\x9c\x35\x51\xb3\xfe\xc7\xd4\x09\x49\x62"
-  "\x7b\x9a\xcf\xdf\x1c\x2a\xfd\x7d\xab\x52\xfa\x7b\x5c\xb0\x3b\x8a"
-  "\xae\xc1\x7f\x12\x74\xc3\x81\x39\x7c\xba\x12\xbd\x2d\x9a\x8c\x77"
-  "\xa6\x45\x13\x32\xff\xf1\xa5\x19\x00\xe5\xc9\x12\x25\xcb\xad\x4b"
-  "\x5f\x99\xbf\xd1\x1b\x79\x05\xde\xa4\x57\x76\x3b\x69\x99\x86\xbf"
-  "\x07\xa9\xf8\xb4\x3b\x8f\x75\x93\xe7\xd2\x54\xa2\xdf\xb2\x20\xf8"
-  "\x27\x0f\x2e\x4c\x76\x47\x59\xfb\xff\x7e\x81\x7f\x32\x6c\x1f\xfd"
-  "\x7f\x57\xe8\x8f\xa5\x5e\x1c\x98\x88\xfb\xc0\xff\xd8\x2e\xa2\x64"
-  "\xf9\x13\x2c\x9f\xc0\xf2\x5f\xdc\xe2\xc7\xfb\xff\xfa\xff\xfa\xff"
-  "\xfa\xff\xfa\xff\xfa\xff\xfa\xff\xfe\x0b\xfe\x64\xe2\x8e\xb5\x07"
-  "\x1c\x83\xf9\x4f\x71\xff\x47\xc6\x1f\xe2\x34\xc6\x95\xeb\x58\xfe"
-  "\x8f\x24\x06\x69\x54\x79\x4b\x74\xca\xcc\xb9\xd5\x01\x25\x91\x7a"
-  "\x8f\xe4\xe0\x72\x75\x61\x58\xa3\xef\xf6\xd0\xda\x29\xa5\xb1\xed"
-  "\xf2\x4d\x33\xca\xfc\x77\x2f\x6b\xf0\xd9\x3a\xbf\x26\xf0\x60\x74"
-  "\xab\x67\xea\xac\x8a\x09\x45\xe1\x4d\x7e\x59\x8b\xea\xa6\x1d\x8e"
-  "\x33\x30\x49\xd3\x3f\xbd\xe5\xcf\xcf\xd6\x8f\x78\xeb\xb1\x2f\xee"
-  "\x7a\x2f\xaa\x79\x68\xca\x23\x27\x6f\xff\xcb\x8b\x67\x47\xef\x7c"
-  "\xf2\xeb\x7b\x3f\x5a\xd7\x31\x68\xf3\x83\x7f\xbf\x2d\xff\xf9\x33"
-  "\x23\xb7\xfd\xe9\xff\x26\x7f\x10\x73\xc9\x2b\x7d\x4e\xd5\x1d\xc5"
-  "\xab\xce\x8f\xcd\x79\xe6\x3f\xf7\x7f\x12\x6f\x92\x6d\x7c\xe0\xd8"
-  "\xcd\xef\x2e\xfd\x76\xf8\x9b\xf3\x3e\xbf\xf3\xc0\xcb\x3f\x0f\xd9"
-  "\xf2\xf0\x67\xe3\xf7\xae\xf8\x71\xd4\x8e\x85\x5f\x4d\x3d\xf4\xca"
-  "\xe5\x81\xaf\xcd\x3c\x31\x6e\xcf\xf2\xef\x6f\x78\x67\xc1\x97\xf7"
-  "\xbc\xbf\xe6\xa2\x22\x6d\x76\xe5\xc4\x7d\x2b\xcf\x8d\xc9\x7e\xfa"
-  "\xf4\x7d\x47\x36\x18\x07\xbc\xfa\xc7\xe3\xb7\xfe\xef\x73\xdf\xfd"
-  "\xea\xed\xc7\xff\x79\xf7\xdf\x56\xb7\x0c\x7b\xe3\xd1\x53\xbf\xfd"
-  "\xeb\x4b\x3f\xfd\x7a\xd7\x53\xff\xfe\xfd\xc7\xeb\x3b\x07\xbf\xfe"
-  "\xd0\x3f\x7e\x53\xf0\xc2\x0f\x37\xfe\xcf\x13\xff\xfa\xdd\x87\x6b"
-  "\xdb\xbc\x33\x42\xb4\x93\xf6\x47\x5c\xb8\x29\x77\xf1\x37\x7f\x38"
-  "\x9a\xc0\xba\xa2\x3f\xc2\x7c\xff\x5d\x5f\xdb\x8d\x7e\x6c\x4c\x74"
-  "\xe6\x7a\x96\xb7\x3a\xfd\x99\x78\x0f\x91\x79\x90\x41\x72\xa7\xfa"
-  "\x09\xce\xd6\xd7\xc6\x9f\x4a\x7c\x7d\x6f\x7f\x38\x6f\x81\xf3\x19"
-  "\x77\xc3\xf1\x6b\x2e\xc5\xdc\xf3\x1f\x6b\xf5\x8a\xbe\xf8\x93\x41"
-  "\x3d\x07\x40\x49\x06\x92\x41\xa0\x19\x0f\x32\x84\x0c\x25\xc3\x88"
-  "\x27\x51\x10\x2f\xe2\x4d\x94\x64\x38\x19\x41\x7e\x45\x7c\xc8\x0d"
-  "\x64\x24\xb9\x91\xf8\x92\x51\x64\x34\x94\xde\x8f\x8c\xb1\x5e\xe6"
-  "\x44\x12\xe4\x0b\xff\xc0\xff\x73\x49\x10\xf7\x7b\x49\x7f\x7a\x9f"
-  "\xa6\x6b\xf8\xf4\x6a\x3e\x5d\xd7\x9f\xde\xa7\xe9\xaa\xab\xfc\x79"
-  "\xf3\x55\xfd\x94\x41\x58\x40\x23\x03\x49\x7c\xd0\xf5\x67\x99\x2a"
-  "\xe3\xff\xba\x7e\x93\x5e\xae\xef\x96\x9f\xf4\x7a\xcb\xbf\x20\x38"
-  "\x02\xe9\xd7\x04\x42\xe8\x5c\x02\x2b\xfe\x33\xd8\xba\x52\xf8\xdb"
-  "\x1e\x0b\xc7\x26\x38\x32\xe1\x78\x1b\x8e\x5c\x38\xf6\x0a\xf9\x10"
-  "\xa2\x6f\x27\xa4\x19\xb8\xfd\xe7\xad\xf0\x59\x41\x48\xcb\x12\x42"
-  "\x2e\xea\x08\x69\xcd\x23\xa4\x4d\x25\x2a\xb8\xa7\xb9\x44\x46\xfe"
-  "\xae\x70\x5a\xc6\x6c\x15\xdd\xcc\x51\xff\x54\x3a\x73\x7e\xb0\xea"
-  "\xce\x3b\x02\xef\x08\xbc\x5b\x35\x71\xee\x44\xd5\x5d\x01\x01\x53"
-  "\x27\x05\xdc\x33\xe9\xae\xc9\xaa\xbb\xee\xbe\xf7\x9e\xc9\xf7\xde"
-  "\x35\x45\xb5\xf2\x95\xa8\x15\x77\x06\xbc\xb0\x5c\xf5\xfc\x8a\xa8"
-  "\x95\x6b\x97\x46\x2d\xef\xad\xc6\x4e\xfd\x41\x55\xc8\x18\x23\x2d"
-  "\xa6\xd8\x1a\x32\x1c\x21\xd7\x06\x10\xa6\xbe\x94\x74\x9d\x91\x65"
-  "\xf2\x55\x51\xf3\x87\xf4\x4f\xb6\xbe\x90\xc8\x62\x33\x89\x6c\x75"
-  "\x39\x91\xad\xdc\x44\x64\xcb\xcb\x88\x6c\xd7\x14\x22\xdb\xee\x41"
-  "\x64\x6f\xab\x89\x2c\xb5\x82\xc8\x36\xb5\x76\x4f\xdb\xbd\x9d\xa6"
-  "\x1d\x83\x6b\x0f\xc3\xf1\x81\x2f\x91\x15\xcb\x69\x5a\x45\x3b\x91"
-  "\xfd\xa3\xe1\x8a\xd4\xdd\xf9\x3f\x47\xed\x2d\xfb\x7f\xef\xcc\x0b"
-  "\xc7"
+static unsigned int ethp_z8e_uncompressed_length = 377100 ;
+static unsigned int ethp_z8e_length = 116536 ;
+static unsigned char ethp_z8e[116536 + 1] = 
+  "\x78\x9c\xec\xbd\x7f\x7c\x54\xd5\xb5\x37\xbc\x32\x19\x60\x12\x03"
+  "\x13\x31\xd2\x29\xa5\x3a\x5a\xb4\xd1\x0b\x12\x15\xdb\x68\x41\xa3"
+  "\x80\xc5\x36\xfc\x50\xd1\x46\x45\x03\x0a\x34\x68\xc4\x08\x01\x06"
+  "\x08\x99\x61\xc0\xeb\x24\x02\x49\x15\x31\x42\x20\xb1\xe2\x2d\xb7"
+  "\xa5\x8a\x35\x40\x6c\xa3\x8e\x25\xf4\xa5\x95\x64\x62\x5f\x7c\x9e"
+  "\xdc\xbe\x78\x3b\xf2\x44\x9a\xf2\x04\x18\xc9\x90\x19\x93\x99\xb3"
+  "\x9f\xef\xda\xfb\x9c\x64\x66\x98\xa0\xdc\xde\xcf\xf3\xfe\x53\x3e"
+  "\x9f\x30\xe7\xec\x1f\x6b\xaf\xbd\xf6\x5a\x6b\xaf\xbd\xf7\xda\xeb"
+  "\x10\xfd\x03\xff\x4c\x1f\xd5\xfc\x23\xd5\xff\xf9\xef\x9f\xff\xfe"
+  "\xf9\xef\x9f\xff\xfe\xf9\xef\x9f\xff\xfe\xf9\xef\xff\x9f\x7f\x67"
+  "\x4d\x66\xfa\x7d\x35\x51\xc8\x6d\xb1\xf9\xe9\x4b\xfb\x2b\x2f\x89"
+  "\x08\x92\x53\xfc\x64\xb1\xf1\xaf\xfe\x47\x2f\x22\xdd\x54\x4d\x96"
+  "\xab\x33\x29\x63\xca\x0e\xa2\x2d\xa3\x44\xd7\x4b\x5b\x45\x60\xfd"
+  "\x56\xd1\x35\xf5\x0d\xa2\xe6\xb1\x44\x2f\x8d\x12\x41\xc0\x99\xeb"
+  "\xa7\xc7\xb6\x30\x9c\xf5\x78\xe7\xfc\x0d\xa3\x44\x00\xe9\xa5\x7e"
+  "\x2a\xcc\xe0\xf4\x75\xa3\x00\x2b\x8b\xc8\xbd\x55\x84\x63\xe0\x5a"
+  "\xb8\x3e\xc3\x9c\x7a\x95\xc4\x67\x57\x02\x1c\x86\xd1\x08\x18\x1b"
+  "\x2e\x00\x23\xc3\xc0\x2b\x68\xa2\x14\x86\xd7\xed\x26\x5b\xd0\xed"
+  "\xbd\x1c\x75\x83\xe8\x53\x36\xd7\xad\x42\x19\xe1\xa6\xd4\x66\x47"
+  "\x84\xec\x57\x53\xca\x09\x4a\x7f\x0d\xbf\x26\xfc\xbe\xcc\xfd\x5d"
+  "\xaf\xea\x8d\x65\x18\xa8\x9b\x12\x72\xa7\xe5\xf4\xd7\x05\x6c\x7b"
+  "\x39\x99\x51\x76\x71\xd0\xe4\x35\xa9\xb2\x99\x69\x7a\x59\x13\xca"
+  "\xce\x35\xca\xaa\x3c\xd3\x3d\x7a\xde\x25\xc8\x73\xc4\xe7\x99\x5f"
+  "\xd4\xf3\x32\x90\xb7\x25\x01\x3f\xb3\xaf\x37\x42\x27\x28\x6d\x0f"
+  "\x70\xb1\x1f\xc4\xa8\x70\x1d\xbd\xfc\xa5\x28\xdf\x1c\x0f\x8b\x48"
+  "\xcf\x1b\x89\x3c\x7f\x7c\xde\xfb\x39\x7a\xde\x37\x90\x17\x89\xcf"
+  "\x4b\x31\xea\xd9\x42\xee\x74\x5b\x92\x7e\x72\xfb\x29\xaa\x6d\xee"
+  "\x43\xfa\x24\x94\x71\x71\x99\x39\x76\x17\xf1\x58\x71\xde\xc1\xfa"
+  "\xfe\xf6\xb9\xcc\x3c\x03\x8e\x1f\xf5\x63\x68\x0a\x5a\xa6\x97\x19"
+  "\xf5\xa7\xda\x19\x06\x49\x1a\x32\x1c\x3f\xa5\x4d\x67\x38\xfc\x8e"
+  "\xe7\x31\xdc\x6f\xfd\xd9\xce\xfd\x8b\x1d\x73\x22\x33\xc0\x0e\xb1"
+  "\x10\x0d\xc5\xdf\x30\x8b\xc1\x03\xcb\x6c\x42\x73\x7e\x93\xcc\xa2"
+  "\xb2\x61\x9e\xe6\x16\xe4\x73\x84\xc9\x3e\x9a\x9c\xc7\xe9\x12\x1b"
+  "\xf0\xa3\xcd\xab\xc9\xe2\x2c\x11\x61\x9f\xa3\x8b\x5a\x03\x5d\xe4"
+  "\x0c\x88\x4e\x5f\xe4\x1c\x95\x9f\x23\x8b\x2f\x72\x8a\xca\x9f\x25"
+  "\x5b\x73\xd9\xe7\x94\x8c\xbf\x34\x93\x20\xe7\x18\xae\xdb\x41\xad"
+  "\xb5\x1d\xe4\xac\x8d\xaf\xeb\xfc\x36\xd9\x5a\xf0\x8e\xb1\xb3\x32"
+  "\x1e\xcd\xf6\x08\x45\xd2\x1b\xe6\x95\xbd\x4a\x66\xe7\x55\x64\x6a"
+  "\x59\xe0\x35\x70\xf1\x33\x2e\x1b\x4e\x92\xe5\xf5\x45\xe0\xa1\x93"
+  "\x8c\x6f\xd3\xbc\xb7\x56\x87\x4d\x07\x6d\xf9\x74\xd0\x76\x8c\x9a"
+  "\x6d\x93\xa9\xd9\x31\x95\x36\x9f\xa4\x8c\x83\xe1\x49\xd4\x6c\xbe"
+  "\x1b\x32\x36\x95\x7c\x5d\x78\xb6\x47\x51\x26\x48\xf6\x15\x04\xfe"
+  "\xb8\xa4\x6d\xcb\x93\x64\xf1\x2b\x98\xa0\xef\x25\xc7\x3e\x2c\x25"
+  "\x62\xfa\xf2\x7b\xb2\x7e\x2c\xfb\x26\xd9\x80\x5f\x27\x70\xb9\xf5"
+  "\x38\x65\x5c\x3e\xd6\x46\x39\xc0\x79\x98\xaf\x26\x42\xe6\x32\x4a"
+  "\x1b\x44\xb6\xb2\x34\xb7\x94\xf1\xae\x9d\x5b\x45\x27\xf3\x68\xf7"
+  "\x9a\x02\xc8\x69\x46\x3e\xda\xee\xe2\xf6\x36\x43\xd6\x9d\xaf\x91"
+  "\xb9\x7b\x65\x41\x4a\xdd\x56\xd1\x81\xbc\x22\x23\x0f\xfc\xd4\x81"
+  "\xfc\xce\x09\x59\x94\xe9\x8b\xe4\xd1\x07\xbd\x9d\x66\x86\x31\x22"
+  "\x48\x29\x0c\xcf\xea\xa0\x54\xf4\x67\x08\xf0\xb9\xb5\x0e\xe9\xdf"
+  "\x41\x39\xd4\xdf\xed\xa7\x9f\xcd\xe3\xfa\xe2\x1b\x8f\x04\xb5\x6f"
+  "\x3c\x72\x4e\x7b\xe5\x91\x6e\xf1\xca\x23\x67\xa3\xaf\x3c\xf2\x85"
+  "\x73\x15\x59\xa2\xdf\x78\x24\xd0\x5a\x22\xc7\x20\xb3\xb5\x04\x63"
+  "\x10\x25\xcb\xda\x53\x94\xf9\xd8\xb3\x18\xfb\xc8\xa7\xb4\x76\x31"
+  "\xd9\xb4\xb4\xdf\xd9\x7c\x91\x4f\xe8\xb1\x32\x12\x78\xce\x4e\xd6"
+  "\xbf\xee\xf4\xa6\x7a\x25\x43\x16\xf4\x69\xb8\xdd\x6f\x7a\xa7\x80"
+  "\xdb\x0d\xa4\x35\xd7\xe3\x6f\x17\xfe\x76\xe3\x6f\x8f\x48\x6f\xda"
+  "\x03\x5a\x39\x47\xac\x4b\xa1\x9d\xbd\x44\x13\x34\x4a\x39\x49\xc3"
+  "\x27\x01\xff\xcc\x41\xe8\x36\x46\xab\xf4\x55\x7f\xd7\x45\xe5\xa1"
+  "\x50\x11\xb1\x6e\x62\xbd\xc4\x7a\x0a\xed\x78\xd0\x4e\x8d\x94\xc5"
+  "\xad\x22\x28\xd2\x7d\xd5\x48\xef\x0c\xae\x29\x4a\x09\xac\x29\x32"
+  "\x75\xa7\xfb\x5e\x42\x99\x3d\x28\xd3\xa6\xd3\xb0\x93\x61\x41\x26"
+  "\x02\xc3\x23\x94\x0a\x98\x25\x07\x7a\xda\xcd\x3b\xb6\x8a\x63\x28"
+  "\x77\xb4\x1f\x16\x60\x03\x0e\xe8\x3f\xbc\xd3\x48\x03\xad\x3b\x36"
+  "\xa1\x1c\xd7\xf7\x85\xf3\x58\x7f\xfb\x7d\xc5\x9d\x64\x8d\x50\xba"
+  "\xe8\x53\xed\xa1\x4c\x27\xeb\xd9\xe1\x61\x1a\x1a\x72\xd3\x6c\x86"
+  "\xcd\xf5\x7c\x5d\x9d\x84\x7a\x2f\x09\x67\x11\xf4\x1b\xcd\x0c\x89"
+  "\xa2\x14\xe8\xf4\x8e\x83\xa8\xaf\xda\x1e\x31\xdb\xc0\x91\xdb\xe0"
+  "\xb1\x96\x78\x82\x1f\x0e\x16\x87\x69\x78\x0d\xa5\xa2\xde\xfd\x0c"
+  "\x8f\x61\x81\x0f\xfc\xe8\xeb\x4b\x07\x8b\x03\xa4\x89\x38\x98\x7e"
+  "\x1d\x5e\x7d\x1c\x3c\xa4\x0b\xc0\x63\xfe\x6b\x46\x9d\xe1\xf5\x12"
+  "\xde\x7d\x07\x34\x86\x17\x26\xb3\x5d\xe2\xfb\x20\xc3\x08\xb1\x8e"
+  "\x01\x4c\xef\x8a\xbb\xa8\x8b\xac\x96\x80\xb3\x28\xb5\xb5\x8c\x88"
+  "\xeb\xbf\x55\xde\x39\x44\x74\x17\xa4\x32\xcf\x71\xbe\x2f\x72\x16"
+  "\x65\x46\xfc\x5d\x74\x17\xa5\x0e\xef\x22\x33\xe3\x8c\xfa\x0e\xc6"
+  "\x33\x76\x2c\xef\x9b\xf6\xe0\x64\x7a\x70\xea\x3d\x53\x27\xd3\x8c"
+  "\x3b\xa7\x4c\xa6\x9c\x5b\xc7\xe7\xdc\xfc\xfd\xdc\x9b\x69\xf6\x4f"
+  "\xee\x9b\x4c\xb3\x67\x4e\xa6\xfb\xf1\x37\xfb\xfe\x69\xf7\x4d\x9d"
+  "\x76\xff\x64\x2a\xb8\xfb\x1e\xbc\x4d\x99\x7c\x63\xce\x0f\xc7\xcf"
+  "\x9e\x72\xcf\x34\xba\x77\xce\x4d\x39\x37\xdd\x44\x77\x4e\xcb\xbf"
+  "\x31\x27\x47\xff\xbd\x31\x87\x8b\x3c\x9c\x3b\xed\xfe\xf1\xb3\x97"
+  "\x3e\x53\xfa\xcc\xf8\x99\xf7\x4c\x49\x98\x67\xb3\xa3\x3d\x1a\xd3"
+  "\x37\x28\xce\x4c\x27\x0d\xfa\x62\x27\xc6\x1d\x7f\x5d\xde\xf2\xe3"
+  "\x90\xfb\xcc\x8f\x77\xf2\x78\x49\xbd\x6a\xe5\xb9\xca\x1c\x72\x5b"
+  "\xdb\xfd\xa6\x86\x4c\xa6\x1b\xe6\x33\x94\xb9\xfc\x1c\xf2\xae\xd3"
+  "\xe7\x8d\x21\xc8\x0f\xc7\xe7\x5f\x7a\x04\xf9\x13\x5a\xed\x44\x3e"
+  "\xfc\x81\xd6\x41\xe8\x3f\xd0\x34\x40\xdd\xce\x82\x21\xe0\xe9\x14"
+  "\xb4\xd1\x01\x79\x6c\x0b\xb9\x33\x27\xc6\xc8\x79\x07\xc6\xa4\xcd"
+  "\xbe\x9a\x52\x4f\x53\xe6\xf0\xd6\xd2\x3c\xe2\xb1\xf1\x95\xea\x30"
+  "\xce\xf5\xc3\x48\x97\x30\x30\xde\x80\x73\x54\x87\x53\x16\xa3\x13"
+  "\xfc\x0c\x67\x33\xf2\x74\x58\xf7\xb6\x42\x37\x40\x77\x3f\xa9\x39"
+  "\xb3\x49\xa4\x37\x14\x69\x7d\xd9\x72\x3e\x40\xbd\x06\x83\x97\x51"
+  "\x3e\xd8\x5c\x82\x72\xaf\x4f\x4f\xc1\xd8\xa7\x60\x9e\x42\x5f\xac"
+  "\x5e\xf0\x74\x50\xab\x6c\xde\x2b\x42\x05\xa4\xd2\x2e\x05\x0c\xbc"
+  "\x57\x36\xbf\x2d\x9c\x48\x5b\x2d\xd3\x52\x38\x0d\xe3\x9c\xca\xf2"
+  "\x28\xd6\xc8\xf4\x54\xa4\x2f\x07\x7e\xed\x51\xae\x7f\x46\xd6\x1f"
+  "\x86\xb4\x07\x50\xf6\x6d\x2d\xbd\xf9\x37\xe0\x1b\x4e\x83\x8d\x30"
+  "\x2a\x0b\xf0\xde\xd1\x44\x01\x89\x8c\x4c\x0f\x9e\x1b\xbc\xab\xbb"
+  "\xe8\x44\x09\x99\xfc\xc8\xd3\x9c\x80\xd9\xd7\xdf\xfe\x58\xae\x8b"
+  "\xb6\xcc\xa1\xbe\x22\xcc\x6f\x97\x66\xf3\x5c\x18\x65\x7c\xce\xf4"
+  "\x97\xc9\xe2\x36\x59\xa6\x31\x16\x13\x31\x4e\x69\x21\xf7\xa5\xf5"
+  "\x09\xe3\xd4\x08\x38\x6f\x83\xee\xed\x80\x91\xa9\x75\x17\x71\xbf"
+  "\xde\x06\x5c\x93\x0e\xd7\x80\x11\x54\x7c\x70\xa9\x3f\x81\x0f\xfe"
+  "\x03\xb0\x27\x0f\xe4\x8f\xa4\x84\xfc\xf7\x90\x7f\x97\x9e\x0f\xd9"
+  "\x1a\x69\x8f\xcf\x1f\x39\x09\xf9\x77\xa3\xfd\x20\x64\x27\xd5\x4f"
+  "\x99\xbb\x76\xb2\xed\x37\x50\x7e\x76\x42\xf9\x62\x94\xff\x11\xc6"
+  "\x36\xc8\x7a\x9d\xcb\xd7\xe9\xbc\x8a\xf2\x16\x94\x77\x25\xb4\xbf"
+  "\x03\xe5\xef\x8f\xc1\x2f\xa1\xff\x97\x15\x21\xbf\x80\x79\x0b\xbf"
+  "\x0b\x50\x66\x18\xcb\x2b\xeb\x8a\x83\xc5\x6c\x2b\x8e\x6c\x4b\x68"
+  "\x9f\x69\xf9\x94\x66\xd0\xa8\x9b\x69\x94\xb9\x4b\xb7\x43\x8e\x29"
+  "\x1c\x2e\x33\x27\xb4\x31\x16\x75\x96\x81\x7f\xde\x36\x78\x23\x49"
+  "\x9d\xdc\x84\x3a\x05\x92\xb7\x54\x3b\xfa\x18\xab\x3a\xba\x1e\x8a"
+  "\x85\xc1\x7d\x83\x6d\x74\x59\x59\x42\xdf\x0b\xd0\xee\x9a\x4d\x4a"
+  "\xce\x2f\x01\x4f\xdc\x84\xb4\x7b\x00\x73\x1f\xf3\x11\xf3\xba\x2f"
+  "\x10\x86\x9e\x9c\x9e\xa1\xe6\xfb\xcb\x3e\xb5\x96\x11\x3f\x8f\xe7"
+  "\x67\x86\x2d\xfa\xf2\x75\x19\xb8\xec\x53\xfc\x72\x7a\x33\xa7\xb3"
+  "\xec\x89\xbe\x1f\x6b\x0a\x66\x56\x0a\x64\xd4\x84\xf7\xa8\xde\xc6"
+  "\x9d\x78\x4f\x01\xfe\xbf\x81\x0e\x06\xcf\x4e\x67\x7e\x9c\x88\xf4"
+  "\x5b\xf5\xfc\x1b\xb9\x3c\x9e\x6f\xd4\x9f\x99\x6f\x7f\xa3\xf3\x2d"
+  "\xe4\xe0\xf2\xeb\x64\xdb\x52\x16\x54\x7d\x4d\xf1\xfd\x14\xe4\x5d"
+  "\x8e\xdf\x7b\xf0\xcb\x78\xdd\x8b\xb6\x3f\x75\x9e\x23\x9b\x33\x0a"
+  "\x9b\x43\xbd\xff\x11\xbf\xf7\xe1\x77\x1f\x7e\xef\xc7\xef\x6b\x2c"
+  "\xb7\x81\x95\x45\x94\xc0\x33\x5d\x9a\x92\xd5\x61\x6a\x0c\xb3\xaa"
+  "\x75\xf9\x51\xf2\x7b\x66\x20\x4d\xa8\x34\x93\xa2\xb9\x9e\xd6\x37"
+  "\x9d\xdb\x9f\x0d\xf8\xc5\xdc\xbe\x2e\xf7\x43\xd4\x38\xa9\x32\x9a"
+  "\xaa\x67\x56\xe3\xad\xa7\xa9\x72\x29\xb1\x6d\xe2\x37\xaf\x3c\x28"
+  "\x04\x7e\xc7\x31\x5d\xfd\x74\x79\x0e\x68\x62\xc6\x3b\xeb\x3e\x93"
+  "\x2c\x2f\xe1\x5e\x56\x1b\x33\xde\xb0\xc5\x2f\x2f\x8e\x1f\xef\xcc"
+  "\x5d\x4c\x33\x1e\x6f\x03\x5f\xc6\x1d\xfc\xcc\x73\xda\x50\x83\x67"
+  "\xc0\xdb\x5d\xd0\x8f\xc1\xd4\x32\xe6\xbb\xcb\xf7\xfa\xe9\x97\xd5"
+  "\xd2\x0e\xaa\x6c\xde\xcf\xf9\x41\xe8\x19\xe6\x8d\xd4\x12\x96\x97"
+  "\xcb\xdb\x8c\x7c\x99\x97\xd6\x96\xc9\xf0\x53\x8b\x65\x5e\x97\x1f"
+  "\xec\x62\xe4\x31\x6e\x2c\xc7\xa9\xa5\x9c\x37\xca\x32\x00\xb7\xc1"
+  "\xa3\xc3\x4d\x65\xfb\x81\xed\x00\xcc\xc7\x9d\x28\x33\xce\x4f\xc3"
+  "\x0b\x06\x5b\x73\x09\x4f\x83\x63\x3c\x91\xe9\x7a\x17\x0d\xf1\x45"
+  "\x8e\xd2\xac\x88\x88\x8e\x77\x51\x9a\x2f\xb2\x87\xc0\x20\x97\xfa"
+  "\x22\xc7\xe8\x7a\xa2\xab\x7c\x91\x2d\x98\x6f\x77\x71\xfe\x07\xd9"
+  "\x94\x92\x82\x5f\xe7\xb5\x2e\x53\x8a\x2f\xb2\x81\xc6\xba\xcc\xf8"
+  "\x2d\xa6\xbb\x87\x88\x90\x2f\x92\x8f\x72\x0b\x68\x56\x54\x9c\x99"
+  "\x3a\x44\xfc\xb5\x30\x4a\x99\xf9\xcf\x09\xa7\x2f\x02\xdb\x37\x72"
+  "\x04\xe9\x9a\x98\x15\xfd\x12\x7f\x21\xa1\x79\x1a\x3c\xb3\xa2\x67"
+  "\xc4\x94\xe7\x3e\xc0\xfb\x5f\x85\x30\x91\xf0\x45\x26\x51\x6b\x30"
+  "\x88\x72\x4e\x21\x2a\x1a\x1c\x8f\x9d\x33\x51\x1f\xe6\x4e\xad\xa2"
+  "\x01\xba\xba\xa1\xa6\x0f\xfd\xc3\xbc\xf2\x4a\xdf\x1a\xfc\x56\x36"
+  "\x6c\x95\xef\x9e\x86\xdd\xc2\xd2\x50\x73\x03\x16\x12\xdc\x07\x5f"
+  "\xa4\x83\x0a\x61\x0a\xcf\x5a\x15\x10\x8c\xff\x88\x75\xbc\x8e\x98"
+  "\x44\xd0\x7d\xd6\x59\xab\x9c\x02\x79\x16\x91\xd6\x50\xe3\x8b\x74"
+  "\x11\xda\xd8\x0d\x78\x6f\x48\x78\x9e\x86\xc3\x28\x1b\xe0\x72\xb1"
+  "\x70\x18\x06\x97\x9d\x15\x25\x2b\xca\x1f\xee\x4b\x6b\x68\xc4\x5f"
+  "\x7b\x5f\xda\x3e\x8b\x48\xdf\x37\x5a\xb8\xb3\x3e\x14\x98\xe7\x84"
+  "\x67\x5f\x36\xde\x73\x43\xb0\xdb\x25\x2d\xa3\x34\x4c\x54\xec\xcb"
+  "\x06\x5f\x4c\x05\x6f\x01\xdf\x7d\x05\x12\xdf\xca\x7d\x3f\x09\xc9"
+  "\x7e\xec\x7b\x50\xf5\x63\xdf\x03\x9c\xde\x8d\x39\x1e\xcf\x8e\x6e"
+  "\x95\xb7\x12\xf5\xe6\xc8\x7a\x9e\x7d\x0e\x61\xd9\xe7\x09\x43\x66"
+  "\x40\x57\x17\xd3\x11\x74\x75\x31\x2d\x01\xdf\xe1\x73\x6c\x24\x91"
+  "\xb6\xcf\x03\x7c\x6a\x50\xff\x97\x7d\x72\xee\xdd\xd7\x18\x52\xb0"
+  "\x0f\x00\xce\x5c\xf0\x65\x2a\x60\x34\x02\xd6\xe1\x3e\xb7\x9d\x66"
+  "\xad\x12\xe1\x59\x91\x75\x91\xc2\x55\x94\x3a\x8e\x5c\xc0\xf7\x3d"
+  "\xd0\x68\x01\xfa\xd9\x8c\xdf\xa9\xc8\xa7\xcb\xd0\xd6\x07\x80\xdb"
+  "\xc8\xed\xa1\x9d\xc3\x80\x79\x08\xb0\x16\x30\x4e\x5f\xba\x29\x13"
+  "\xef\xed\x5f\x2a\xfc\xc2\x9a\x67\xbf\x4d\xb3\xec\xb7\x18\x3c\xc4"
+  "\xfc\xa3\xe8\xb6\x85\x66\x06\x45\xc4\x17\xd9\x41\xe0\xb1\xcc\xd6"
+  "\xe0\x31\xce\x87\xad\xbf\x07\xe3\xcc\x3c\xb5\x01\xbf\xbb\x88\xf9"
+  "\xa7\xb5\x64\x39\x97\xfd\x80\x79\x68\x66\x49\x70\xdd\x78\x2a\x49"
+  "\xc1\xbb\xb3\x30\x62\xa1\xc7\x4a\xcc\xae\xa8\x67\x5f\x67\x6b\x09"
+  "\x8f\xcb\x51\xd4\xe1\x7a\xc5\x64\x4d\x81\xbd\x9b\x22\x22\x56\x47"
+  "\xc0\x3c\xbc\xc8\x29\x5a\x83\xf9\x28\x5b\x42\xdc\x1f\xe6\x23\x2e"
+  "\x3f\xa3\x4b\xf8\xa3\x96\xfd\x35\xdc\x37\x31\xc2\x45\x2d\x5d\xb7"
+  "\x10\xaf\x39\x5a\xba\x76\x31\x9f\x6a\xc2\xb2\xbf\x08\x3c\xda\x37"
+  "\xa3\xcb\x35\xe4\xb1\x73\x94\x82\xb4\x68\x4b\xd1\x1e\xe4\x37\xa3"
+  "\xdc\x11\xc9\xb7\x33\xcf\x45\xac\x11\xcb\xbe\xf6\x88\x67\xbf\x63"
+  "\xe6\xb9\x3e\xd1\x52\xb4\x85\x1e\xed\x72\x81\x56\x7b\x68\xc6\xa9"
+  "\x48\x6a\x6b\xc9\x02\x94\x09\x21\x7d\x97\xe4\xff\x19\xa7\xba\xc5"
+  "\xcc\x67\xc5\x99\x99\xe7\xfe\x2a\x66\x14\x89\x0f\x0a\x1d\x34\xe2"
+  "\x92\x75\x42\x63\xb9\x38\xd2\xb1\x87\x2e\x39\xe6\x27\x96\x89\xfc"
+  "\xf9\x9a\x98\x71\xea\x8c\x78\xec\x59\xa6\xcd\x24\x6a\x29\x82\xfc"
+  "\x38\xb6\x30\xbd\xc3\x2d\x45\x4d\x68\x7f\x2a\xe0\x3a\x85\xcf\xb1"
+  "\x03\x65\xbd\xd6\x47\x4f\x65\xd2\x91\x8e\x2d\x14\x49\xdb\xd7\x1e"
+  "\xad\xd8\xd7\xa9\xa5\xed\xb7\x68\x15\xfb\x6d\x22\x6d\x7f\x51\xa4"
+  "\x62\xbf\x23\x9a\xb6\x1f\x3c\xb0\x1f\x72\x0f\x3b\x04\x63\xde\x8b"
+  "\x35\x38\xde\x4f\xf4\xf2\xf8\x7b\xf6\x87\x85\xe5\x80\x0d\xfa\x4e"
+  "\x28\xde\xdf\x2f\xd7\xd1\x22\xed\x80\xad\x2f\xed\x80\x45\x54\xe2"
+  "\x57\xf2\xde\x81\x6c\xe6\x4b\x39\xdf\x54\x1e\xf8\x2e\xe6\x87\x54"
+  "\xe4\xe7\xe2\x6f\x3a\xfe\x30\x67\x1e\xd8\x0d\xf8\x97\x4a\x9e\xf2"
+  "\x1c\xd8\x2d\x6e\xaf\x86\xed\x78\x8e\x79\xd2\x09\x58\x87\x67\x45"
+  "\x73\x9d\xa0\x23\x64\xe5\xc0\x6e\xad\xe2\x40\x23\xe0\x75\x86\x25"
+  "\xff\x1f\xf8\x1b\xc3\xef\x5b\x93\xcd\x6b\x6c\x33\xf2\xc3\xa2\xb2"
+  "\xf1\xc9\x10\xf3\xab\xa5\xb1\x48\xb3\x34\x1e\x16\x9e\x46\xc7\x8f"
+  "\x9f\x13\x81\xa8\xa7\xb1\x46\xf3\x34\x7a\x22\x43\x61\x97\x3a\x9a"
+  "\x88\x75\x54\xe4\x7d\x01\x3a\x1c\x02\x4d\x76\x49\x1e\xf0\x39\x20"
+  "\x07\xab\x46\xbb\x5a\xba\xc0\x0f\x25\xbf\x96\xfa\xa9\x35\x78\x54"
+  "\xd2\x55\xa4\x35\x16\x31\x5f\xf1\x18\x3f\x56\x42\x2e\x51\xd1\xe8"
+  "\xd0\x2a\x1a\x3d\xd1\x0a\xc0\x4d\x43\x3b\xe9\xbf\x4b\x0f\x4b\x99"
+  "\xfd\x1d\x78\xb6\x09\x75\x0e\x91\xe2\xf3\xdf\x59\x06\xd3\x93\xac"
+  "\xaf\x58\x47\xcd\x8a\x84\x99\x6f\xfe\xc6\xba\x4d\xe9\x2a\x2a\x34"
+  "\x74\x15\xeb\x29\xb6\xf5\x59\x57\x69\xba\xae\xd2\x74\x5d\x25\xdf"
+  "\x2d\xd0\x37\x9e\x86\x1a\xd6\x49\xb3\x1c\x4a\xd7\xcc\x8a\xe6\x08"
+  "\xf0\x47\x06\x60\xd4\xa8\xf1\x40\x99\xca\x86\x37\x64\x79\x49\xa7"
+  "\x86\xc3\x1a\x74\x0e\xfe\xda\x35\xa5\x73\x6c\xba\xce\x31\x19\x3a"
+  "\x27\x8a\xf9\x0b\x72\xa5\x25\xd3\x39\x9a\xae\x73\xa2\x42\xe9\x1c"
+  "\x4d\xd7\x39\x9c\x1e\xd5\x75\x4e\x34\x89\xce\xd1\x3c\xfb\xb8\xbf"
+  "\xa9\xba\xae\x71\xb1\xae\xe1\xfe\x6a\x15\xfb\x3c\x9a\xd2\x35\xbb"
+  "\x61\xe7\x9b\x58\xd7\x44\x51\x47\x33\x74\x4d\x48\xd6\x3f\xcc\xfa"
+  "\xa6\xef\x5f\x09\x3a\xd4\x4e\xac\x67\xa4\x4e\x89\x5c\x15\x61\x9d"
+  "\x02\xfa\xdd\x91\xa8\x53\x00\xaf\x1d\xcf\x99\x4a\x57\xed\xb7\x58"
+  "\xd7\x89\x88\x66\xd9\xd7\x39\xcb\x11\xc4\x58\x7f\x8a\xb5\x2e\x74"
+  "\xb7\xa3\xd4\xe5\x73\x44\x28\x0a\x7d\x23\x5a\x5d\x04\x1c\xc1\xc3"
+  "\x51\xe8\x0b\x22\xc8\x66\x51\x04\x72\x0e\x3e\x77\xb4\x96\x7c\x42"
+  "\x51\xc8\xeb\x8c\xae\x6e\xdf\x63\xc1\xec\xcc\x19\xa7\x44\x00\xf4"
+  "\xf1\x3f\x56\xe2\x82\x8e\xc9\x0e\xb4\x74\xbd\x47\xf9\x1d\x42\xcb"
+  "\x9f\xe7\xb7\x43\x0e\x1c\x33\x16\x7b\xad\x8f\x3d\x9b\x09\x59\x13"
+  "\x5e\xe8\xc6\xff\x77\xc6\xa9\x4c\xeb\xdc\x0e\xba\x22\x7f\xbe\xd0"
+  "\xa2\x90\x35\xf4\xb7\x13\xfd\x0e\x43\xce\x2c\x51\xc8\x1b\x64\xad"
+  "\x28\x92\x20\x6b\x22\x7d\xff\x09\x3c\xdb\x15\xfd\x0e\xd8\xd0\x87"
+  "\xb0\x26\xe7\xb4\x0e\xb9\xbe\x02\xbf\xdb\x78\xef\x09\x30\xc2\x90"
+  "\x0b\x29\x6f\x9a\x50\xf2\xa6\x31\xfd\x4c\xba\xbc\x61\x2c\x90\x9f"
+  "\x8b\xbf\xe9\xf8\x4b\x2e\x6f\x25\x09\xf2\xf6\xac\x2e\x6f\x69\x4a"
+  "\xde\x30\xae\xa9\xd1\x35\x4a\xe6\xb8\x0d\x5e\x87\xf5\xcb\x5c\x7a"
+  "\x63\x91\x60\xdb\x51\xf2\x8f\x94\x3b\xcc\x2f\x8d\x35\x90\x39\x0f"
+  "\x64\x0e\xf0\x44\x80\xf5\x27\xf8\xf3\x3f\x79\xce\x9b\x59\x22\xfe"
+  "\xb3\x30\x3a\xda\x05\x99\xaa\x81\x4e\xfb\x2b\xf4\xe9\x7f\x3e\x16"
+  "\xa4\x7a\xc8\x54\x11\x64\xc9\x01\x99\xf2\x40\xb6\x58\xa6\x2c\xd1"
+  "\x35\x0c\xf3\x77\x96\x7e\x18\x72\xce\x8c\x97\x29\xb5\x73\x9d\x7c"
+  "\xff\x2f\xe4\xbe\x02\x9a\x71\x7f\x13\xdb\x2b\x78\xee\xf4\xd3\x81"
+  "\x6a\xfd\x39\xe8\xa7\xed\x1b\xa5\xad\x03\x59\x2c\x29\xa7\xcb\x4f"
+  "\xd2\x95\xbb\xc1\xf7\x84\xe7\x0c\x3c\xef\x99\x75\xdd\x07\xb0\x29"
+  "\xfa\x98\xb7\x42\x2c\x8f\xc2\x3d\x11\x6b\x0b\xca\x03\x3f\x5a\x44"
+  "\x28\x3b\x43\xa4\x1f\xba\x5d\xf4\xd9\x78\x8f\xc9\x8a\xf7\x11\xa0"
+  "\xc1\x58\xfc\x8e\xdc\xd1\x43\x59\xf8\xb3\xed\x70\x6b\x2e\xb6\xaf"
+  "\xf0\x9c\x23\x56\xda\xd2\x37\xaf\xa0\x71\xd6\x20\x59\xea\xdc\x5a"
+  "\x81\x75\x5d\x26\xef\xb5\x64\xf1\xb3\x70\xd7\xed\xad\xeb\x21\x33"
+  "\xdb\x91\x5a\x1a\xda\x73\x58\x85\x58\x96\x4d\x75\x4b\xa1\x27\xdc"
+  "\x64\xab\x73\x8b\xbd\xd1\x10\xd3\xa1\xc1\x61\xe0\xc2\xb8\x01\xcf"
+  "\x6f\x03\xcf\xa6\x07\x56\xe5\xd1\x21\x07\x25\xdd\xa3\x0c\xb9\xaf"
+  "\xec\xef\xff\x20\xf9\x11\x83\x26\xc9\xf3\xed\x63\x0c\x3a\x0d\xb2"
+  "\x9f\x65\xe6\xf9\x3a\xba\x42\x04\xaa\x9e\x24\xa6\x85\xcd\x19\x11"
+  "\xff\x0b\x74\x74\x95\x47\xe9\xdb\xb3\x56\x5d\x29\x7c\x5d\xc2\xeb"
+  "\x73\x9c\xa2\x3a\xe4\x97\x97\x09\x4d\x4b\x3b\x04\x19\x39\x34\xa6"
+  "\x7b\x85\x88\xec\x90\x76\xaf\xdd\xe5\xa7\xdb\xec\x6a\x2c\xf6\x85"
+  "\xe5\xba\xce\x72\x68\x0c\x60\x5d\xca\xb0\x5a\x50\x3f\x5a\x71\x68"
+  "\x2c\xca\xed\xf6\x53\xb3\x3c\x33\x80\x2e\x08\x97\xac\xa6\x6f\x9d"
+  "\x24\xbb\x5f\xda\xf6\x9e\x43\x13\x59\x2f\x20\x2d\x13\x69\x5d\x80"
+  "\x9f\x8b\xf2\x58\x1f\xef\xf5\x2b\x5b\xd7\xde\x65\x94\xc3\xb3\x97"
+  "\x9f\xe3\x78\x48\x9e\x6a\x10\xc6\xcb\x3e\x70\x18\x92\xa2\xb3\x95"
+  "\xf1\x2f\x13\x7f\x79\xc9\xb3\x07\xf4\xfa\x7e\x07\xec\x2e\x72\xae"
+  "\xa5\x31\x18\x1f\xe0\x77\xd5\x7c\xa7\x43\x9c\x10\x6e\x7b\xf8\xf5"
+  "\xd5\x61\xac\x0b\xae\x2a\xf6\xd3\xf3\x1d\x83\xdb\xcf\xb0\x7b\x7a"
+  "\x44\x67\xd5\x8a\x7e\x5a\x7e\x36\x6b\x95\x26\xf8\x99\xf5\x52\x1d"
+  "\xd2\x99\x6e\x80\xd3\x60\xd0\x6c\xf0\x71\x39\x94\xa3\xd6\x81\x57"
+  "\x67\x09\xb7\x20\xef\x15\x7c\x7e\x70\xf5\xe5\x8a\x0e\x07\x2c\xdd"
+  "\xd0\x27\xbc\x3f\x5a\x07\x7a\x2f\xb3\x89\x70\xc8\x7d\x35\xec\xff"
+  "\xeb\xab\xf5\xbd\x98\xa0\x2f\x32\x8d\x75\x4c\xd2\xf9\x8b\xcf\x67"
+  "\x06\xe0\x7f\x67\x62\xeb\x18\xe8\x23\xa9\xa3\xda\xe6\x94\x2b\xbc"
+  "\xc3\x0c\xd7\x5b\x7e\x96\x3a\x90\xbf\x2c\x28\x3a\x85\xa7\x6d\x3a"
+  "\xaf\x35\xbc\x2b\x7a\x39\xed\x16\xf0\xb6\xf0\x2e\x65\x9c\xbe\x73"
+  "\x8b\xf7\x8a\x5e\x3a\x81\x75\x1e\xd6\x78\x01\xb5\x2f\xf3\x1d\xfb"
+  "\xc1\x52\xd2\xf7\x7a\xae\xae\xf7\xd3\xb8\x02\x03\x2f\xb6\x37\x40"
+  "\x5f\xa6\x55\x98\xed\x0e\xde\x73\x5f\x56\x26\xc2\x6c\x7f\xa0\xec"
+  "\x11\xa3\x0f\xdc\x3f\xbd\x5f\xfe\xd8\x7e\x01\x87\x00\xd6\xcc\x92"
+  "\x06\xcb\x56\x91\xc5\xae\x68\x6d\xe1\xfe\x72\x5f\xb8\xcf\xb2\x2f"
+  "\x52\xd7\x62\xae\x88\xdc\x82\x35\x98\x4c\xb7\x85\xdc\xdf\xc1\xfa"
+  "\xe7\xfa\xa0\xe2\xa9\xab\xeb\x13\xf9\xa8\x7f\x1c\x2d\xfb\x0e\x3b"
+  "\xbf\xa4\x2b\x9c\x9a\x38\x0e\x98\xef\x82\x4e\xa9\xfc\xab\xb1\xcd"
+  "\x1d\x66\xfe\xfd\x88\x78\x6e\xf6\x95\x9d\x63\x5b\x9b\xcb\x5e\x86"
+  "\xb2\x1d\x28\xf3\xef\x7a\xd9\x7f\x57\xe7\x2d\xf2\x77\x18\xff\x62"
+  "\x3e\x3b\x04\x3c\xbc\x01\x39\xef\xb7\x65\x1a\xef\x02\xef\xf8\x75"
+  "\x88\x8a\x8f\x92\xea\x00\xe8\xe2\xc3\x3c\xaf\x45\x7b\x44\x17\xda"
+  "\xf9\x06\xf3\x94\x73\x15\x7d\x13\x7c\xf9\x59\xf9\x5a\xba\x8c\xf9"
+  "\x49\xa4\x1d\x9a\xa4\xe8\x3e\x36\x43\xb8\x61\x87\x42\xab\x96\xac"
+  "\xa0\x6f\x41\x8e\x26\x9e\xa4\xb1\x57\x15\x96\xd9\x81\x2b\x51\xd5"
+  "\x69\x22\xa9\x83\xd2\x0e\xe5\xfa\x22\x9f\x53\xdd\x69\xde\x6f\x19"
+  "\x9b\x67\xf0\x22\x9e\xf3\x2f\xa4\x2f\x40\xd7\xe9\x6a\xbf\x60\xec"
+  "\xbb\xbc\xbf\x7e\x9c\xc6\xee\xe2\xfe\xe2\x2f\x05\x69\x2f\x8b\x1e"
+  "\x31\x57\xa8\xb9\x2d\xd7\x4f\x63\xdb\xf0\x3b\x5d\xfe\xb9\x69\x9e"
+  "\xfe\x9e\x8b\x72\x1b\x44\x8f\xc6\x65\xa6\x23\xad\x56\xb8\x53\x58"
+  "\x26\x9a\xd0\xf6\x61\x3f\x4d\xce\x55\x63\x33\x76\x0b\xc3\x1a\x04"
+  "\x87\x5c\x8c\x2d\x31\x6f\x9e\xa0\x6b\x6e\xb4\x97\xa7\x00\x8f\x6b"
+  "\x86\x48\xb9\x00\xac\x3a\x93\xd2\xdb\x1a\x70\xdd\xe9\xd6\x8a\xa0"
+  "\xa3\x8b\xb4\xca\x96\x22\xf9\xac\xe7\x09\x7d\x3e\x4d\x0e\xbf\x6d"
+  "\x8e\x77\x34\xf3\xf8\x35\x1b\x15\x9c\xb6\xe9\xde\xd1\x27\xf9\x7d"
+  "\x13\xbf\x07\x2d\xad\x45\xbe\x9a\x3c\xb4\x7f\x92\xdb\xdd\xa8\xf6"
+  "\x01\xae\xd9\xd4\x8d\x36\x42\xee\x6b\x36\xfa\x69\xfc\x02\x75\xd6"
+  "\xd0\x5a\x34\x88\xec\x65\xb2\xec\xb0\xcc\x29\x99\xfe\xee\x8c\x96"
+  "\x7a\x29\x7f\xd9\xdd\x96\x03\xd3\x75\xbd\xc1\x7b\x2b\x19\xc7\xe9"
+  "\xbb\xf9\x2d\x36\xc9\xdf\x26\x61\xba\xa6\xeb\x4d\x2d\x60\xe2\xf3"
+  "\x20\xa5\xbe\xbe\x9b\x7f\xfe\xdf\xb5\x50\x80\xd7\xe6\xe0\x6f\x92"
+  "\xfe\x3e\x1d\x7f\x73\xf1\xb7\x07\xef\x93\x24\xed\xb6\x2f\x48\xf1"
+  "\x23\xaf\x1b\xf6\x3b\xbf\xfb\xe9\xda\x6c\xb1\x7d\xac\x09\x6b\x01"
+  "\xf9\x5c\xf7\x4d\xde\x4b\xb8\x76\x0e\xc6\xe0\x98\x1a\x0b\x86\x43"
+  "\x29\xc0\x8d\xe9\x2e\x9c\x35\x22\xdc\x5c\x1e\x04\xde\xd7\x6e\x68"
+  "\xae\x09\x92\xfd\x5a\xee\xff\xb5\x1e\xee\x53\x10\xf4\xe7\xdf\x65"
+  "\x35\x22\x70\xb0\x36\x42\x7c\x2e\x05\x58\x90\xff\x9f\x4e\x55\xfb"
+  "\x12\x6d\x25\x0c\x4f\xe7\x09\x61\xf4\x5f\xe9\xb4\xd6\x22\x1e\x4b"
+  "\xc0\xfa\x04\x7d\xb7\x9e\xa6\xef\x5e\x2e\xd2\x5b\x8a\x0e\x16\x11"
+  "\xed\x80\x1e\xc1\x5c\x23\xf7\xcb\xa1\x97\x18\x26\xe6\xff\x6b\x26"
+  "\x19\xe7\x28\x9b\x90\xbf\x19\x79\x98\x7b\x02\x2d\x45\x61\x62\x58"
+  "\x51\xee\x1f\xea\xbf\xa7\x05\xcc\x98\xab\x31\xe6\xad\x45\xe5\x25"
+  "\xd0\x33\xfd\x7a\xeb\xda\xa6\xb5\xa7\x44\xd8\xe8\x1f\x9f\x55\x86"
+  "\xdc\xdf\x05\xff\x2f\x9e\x37\x28\xff\xf7\xe3\x9c\xbd\xf8\xe0\x58"
+  "\x35\x66\x1a\xe8\x12\x3f\x66\xd9\x45\x6a\xbc\xbe\x5b\x1b\x3f\x5e"
+  "\xd9\xe8\xc9\x77\x3b\xf0\x17\xc1\x73\x86\x7a\x8f\xfd\xfb\x6e\x5b"
+  "\xcc\x3b\xb8\x23\x7b\x0e\xf0\xc1\xfc\x3f\xb6\x40\x8d\x03\xa7\xa3"
+  "\x1f\xcc\x23\x5f\x90\x85\xf7\xe7\xf8\x9c\x92\xd3\x99\x9f\x39\x5d"
+  "\x83\x3d\x83\xfe\x04\x90\x9f\xc9\xb2\x5a\xa5\x51\x5c\xbe\x6f\x03"
+  "\x78\x6e\x75\x2f\xe3\x7f\xa7\xdc\x53\x5c\xe7\xf1\x30\x9f\xa2\x4e"
+  "\xd0\x1a\xf1\x78\x42\xee\xec\x7c\x83\xae\xa8\x37\x91\xf3\x99\x27"
+  "\x91\xbe\x00\x74\xa9\x97\xe7\x90\x58\xfb\x25\xb7\x35\xb2\x3d\xfd"
+  "\x36\x99\xe5\xc0\x6e\xd6\x47\x5d\x74\xdd\x16\xe8\x2c\x8c\x6d\xcb"
+  "\x3c\x35\xd7\x5c\xf7\x32\xbf\x43\x57\x7e\x86\xe7\xea\x16\xe8\xa4"
+  "\xde\xca\xe6\xfa\x3e\x13\x0d\xeb\x35\x51\x5e\xa4\xb2\xef\x58\x24"
+  "\xbd\x69\x8f\xaf\xb3\x81\x5a\x23\xbf\x21\xfb\x93\x12\x46\x85\x0f"
+  "\x3d\x77\xae\x12\xd1\xb7\x7a\x77\x9b\x7d\x91\x33\x5e\xcc\xcd\x57"
+  "\x9e\xa4\xeb\x24\x3d\x5e\x38\x8e\x59\xff\x31\x09\x5b\xa7\x4f\x5f"
+  "\xe3\xe6\x45\x22\xb2\xf9\x84\x08\xc2\xbe\x4b\xdf\xd4\x4b\xe3\xb6"
+  "\xad\xa6\x9c\xda\x5e\x1a\xbb\xb3\x97\xb2\xc5\xdf\xb2\x4d\xb5\xb0"
+  "\xdb\x1e\x3b\x97\x49\xd0\x09\x05\x23\x4a\xc8\xb2\x73\x35\x49\x1e"
+  "\x89\x56\xc0\x7e\x8b\xc0\x7e\x3b\x93\xcd\xba\xb1\xdf\x7e\xeb\x93"
+  "\xb6\xf1\xa1\x5d\x8a\x8f\x0e\xed\x1a\x5e\x44\x29\x19\xf3\x28\x13"
+  "\xf8\x39\x4f\x53\xf6\x1f\x33\x3a\x60\x3b\xa2\xcf\x7e\xbd\xbf\xa0"
+  "\xdd\x31\x6b\x11\x0d\x93\x7d\x85\xbe\x16\x15\x2d\xf3\x06\x9d\x87"
+  "\x4d\xcc\x53\x41\x96\x1b\xee\xc3\x67\x7c\x56\xda\x30\x3a\x6c\x5e"
+  "\x56\x2b\xc2\x9c\x5e\x7a\x95\x08\x23\xfd\x30\xb7\xbd\x17\xe9\x21"
+  "\xf7\x75\x01\xbf\x69\x6f\xd9\x60\x3c\x8a\x75\x92\xae\x57\xae\x7f"
+  "\x56\x98\x5c\xcc\xa3\x9d\x6b\x23\xb0\xbf\x4f\xb3\xcc\x5e\x5f\x32"
+  "\xab\x58\x44\xec\x4b\xf8\xdc\xfa\x7a\x79\xa6\xce\x67\x69\x6f\xc2"
+  "\xb6\xf9\xaa\x73\x74\x9e\x2f\x78\xbd\x60\x2d\x06\xcc\xca\x03\x9d"
+  "\x02\xeb\xf4\xaf\x6b\xc7\xb3\x2f\xc7\x4b\xd2\x6f\xe4\xfa\x3d\x7e"
+  "\xfa\xb1\x99\x71\xe7\x33\x53\xd6\x9d\xb0\xb7\x2e\x03\x5e\x9d\x41"
+  "\xd0\x01\xf9\x98\xff\x7f\xd8\xae\x9f\x7b\x4a\x7f\x14\xa4\x61\xfe"
+  "\xbf\x67\x0c\xa7\x95\x5e\x45\xb6\x52\xbb\xe8\x1c\xcc\x66\x92\x3e"
+  "\x22\x26\xfa\x46\xc8\xfd\x2f\x59\x06\x1c\xcc\x53\xbf\xec\x36\x3d"
+  "\xf0\x00\xd2\xb2\x0d\x38\x28\x73\x39\xde\x73\xfb\xcb\xa8\x3a\xd3"
+  "\x63\xea\x3c\xd0\x6d\xba\xfe\x97\x48\x9b\x9b\x50\xa7\x38\xa1\x4e"
+  "\x59\x4c\x1d\x97\xde\x4e\x75\x42\x9d\xfa\x84\x3a\x7b\x93\xe0\xd6"
+  "\x9c\x50\xe7\x68\x42\x9d\x8e\x24\xb8\x85\xe3\xeb\x8c\xb3\xc4\xd7"
+  "\x19\x67\x8b\xa1\x25\xfb\x6b\xe4\x20\x6d\x5c\x42\x9d\x49\x09\x75"
+  "\xf2\x8d\xf7\xc1\x7c\x72\x96\xed\x20\x1b\x78\xb3\x93\xc7\xf3\x25"
+  "\x8c\x4f\xf7\x2b\x4f\x85\xf4\xba\x9e\xf3\xfb\x35\xae\x36\xa1\xbd"
+  "\x3d\x09\xed\x35\x9d\xdf\xaf\x71\x6d\x09\x75\xfc\x09\x75\x02\x31"
+  "\x75\xea\x55\x3b\xe3\xcd\xf1\x75\xc6\x67\xc5\xd7\x19\x3f\xf6\x7c"
+  "\xbe\x1a\x9f\x9b\x50\x67\x7a\x42\x9d\x82\xaf\xa0\x05\xcf\xe3\xca"
+  "\x77\x6a\x14\xdb\xca\x77\xc1\x46\x18\xff\x21\xfb\x04\x54\xa1\x8d"
+  "\xd7\x7b\xc3\x43\xf8\xfc\x83\xe7\xab\x83\x8e\x30\xe6\x96\xf1\xd0"
+  "\x0f\x37\xdb\x8d\x39\x8b\xfd\x25\x58\xa6\x95\x8d\x3d\xde\x33\x98"
+  "\x2d\xca\xed\x18\xbe\x54\xdc\xd6\xc1\x31\x3c\x4f\x8d\x0f\xf6\xdb"
+  "\xc4\xca\xbf\x88\x14\x9c\x1b\xee\x61\x38\xdc\x7e\x9d\xf2\xc3\x48"
+  "\x61\x9b\xfc\xa0\x83\xeb\xdc\x90\x1d\x63\x47\x73\xfb\xc1\x86\xd5"
+  "\x61\x73\x3c\x1e\x37\x58\x2e\x80\x47\x06\x6c\xa3\xdc\xd6\x5a\x22"
+  "\x3e\x63\x6e\xa9\x85\x0d\x04\xbb\x9f\x71\x3b\x4e\x37\x54\x4b\x9b"
+  "\x6c\x49\x2f\xf1\xb3\xaf\xec\x36\x79\x06\xad\x6c\xd2\x1b\x0e\x37"
+  "\xa3\x7d\xb6\xdd\x9b\x4b\xce\x52\xb7\x9c\x7f\xd9\x76\xbb\xe1\xdc"
+  "\xc1\xb2\x00\xe3\xe5\x35\xfc\x33\xfc\x74\x43\x50\xda\x1a\x9e\xb6"
+  "\x1c\x3e\x1f\xe7\x33\xa3\x83\xc1\x5c\x2e\x03\xfe\x1f\x7f\xc4\xe8"
+  "\x2f\xe6\x7a\xf0\xc0\x0d\xb5\x17\xa2\x99\x1a\xc3\x09\x63\xe2\x79"
+  "\x72\x08\x78\x65\x42\x4e\xfc\xb8\x4f\xc8\x8b\x1f\xf7\x09\xb3\xe3"
+  "\x79\xd2\x04\x9e\x9c\xb0\x20\xa1\x4e\x69\x42\x9d\x0d\x31\x75\xaa"
+  "\xf5\x76\x6a\x12\xea\xec\x4e\xa8\xd3\x18\xf3\x8e\x3e\x4e\x38\xdc"
+  "\xbf\xf6\x91\xbe\x3f\x13\xda\x63\xde\x4d\x5b\xa4\xfe\x9c\xd0\x65"
+  "\xa4\xf1\x1e\xd2\xce\xad\xca\xf7\x44\xc1\xcb\xb1\x24\xc8\x3b\xca"
+  "\xe7\x8c\x89\xc7\x21\x67\x5c\x3c\x0e\x39\xfd\xf2\x5f\xa5\xd6\x6e"
+  "\xbf\x3f\x41\x37\x66\x49\x1e\x82\x8c\x60\xce\x9e\xc5\xef\x80\x55"
+  "\x83\xf2\xa0\x43\x4e\x71\x02\xbc\xb2\x04\x78\x1b\x63\xde\x33\xf1"
+  "\x5e\x1b\xd3\x87\xcc\x54\x9b\xf4\xe3\x83\xfd\x96\xd3\x60\xa4\xf3"
+  "\x9a\x12\xf8\x76\x3a\xe5\x5c\x93\xc7\x3e\x55\x23\x8f\x53\xce\x6b"
+  "\xbc\xfe\xd4\x61\xc6\xca\x3f\xe9\xfd\x0a\xc6\xe3\x71\xa3\x39\x1e"
+  "\x8f\x1b\xb3\x62\xfa\x15\xb4\xae\xa3\x7b\xad\x91\xfb\x1e\x62\xdb"
+  "\x87\x7d\xe1\xa4\x6f\xd3\x5a\xd8\x6c\xe7\x28\x93\x7d\xca\x4e\x94"
+  "\x52\xaa\xcf\xd1\x89\xb5\xdc\xa1\xfa\x41\xf9\x29\xbd\x2d\x4f\xf7"
+  "\xcb\xb3\x03\x7e\xa9\xc1\x8f\x5a\x65\x5b\x9e\x56\x71\x24\x1f\x69"
+  "\xd0\x7f\x13\x48\xd9\xb9\x1f\xd5\x08\x67\x41\x0d\xe8\x89\x75\xd1"
+  "\x4d\xcb\xf5\x75\xc4\x1c\xf6\x8d\x82\xee\xe9\xc4\x1c\x9f\xa1\xce"
+  "\xc6\x6f\x6c\x8a\xe1\xeb\xa0\x7d\xf5\x1d\xe2\x38\xdd\xb4\x8e\x6d"
+  "\x00\x96\x51\xf6\xb1\x3a\x18\x09\x10\xaf\xbd\x7d\x91\x93\xd2\x76"
+  "\x43\xbe\x4b\xaf\x1b\x8e\xa9\x1b\xd0\xd7\xc6\x3c\x8f\x9a\x27\x44"
+  "\xc8\x7c\x30\x18\x20\xc0\xc9\x52\xf6\xde\x4d\xeb\x0e\x42\x5e\x43"
+  "\xee\x9b\xc6\x19\x75\x78\x1d\xcd\x75\xac\xa5\x64\xbe\xa1\x8c\xcc"
+  "\xde\xd5\xc7\x25\x6c\x7d\xec\x3b\x61\x4b\x77\xf9\xca\x3a\xc9\x17"
+  "\x6c\xe7\xbd\x2e\xb3\xf2\x53\xb9\xc9\x95\x1a\x26\x4b\x77\x45\x1b"
+  "\x64\xe8\x26\x57\xb4\xa2\x2d\x17\xb8\x41\x5e\x6e\xdc\xc5\xfa\x26"
+  "\x96\x76\xd3\xa6\xcd\xbe\x6f\xd6\x8c\xf1\x3f\xb9\xef\x9e\x39\xd3"
+  "\x6e\xb3\xcf\x59\xfc\xf4\xc2\x05\xe3\x9f\x59\x5e\x6a\x5f\xb9\x74"
+  "\x71\xe9\xe2\x25\x3f\xb5\xe7\x38\xae\x71\xd8\xe7\x97\xaa\xdf\xec"
+  "\xe2\xf9\xcb\x4a\x27\xf3\xe3\x38\x7b\xc9\xd2\x85\x2b\xe4\xe3\x75"
+  "\xe9\x14\x0f\x64\x71\xe9\xc2\xa5\xf6\x6b\x16\x8c\xb3\xdf\x3d\x7f"
+  "\x71\xf1\xf2\xa5\x0b\x93\xc2\xba\xcd\xbe\x74\xe1\xd2\x85\xf3\x17"
+  "\xd8\x27\xdb\x73\x18\x72\x2c\xb8\x98\xf1\xcc\x31\xe6\x31\x9e\xbf"
+  "\xaa\xdc\xa2\x4d\x9f\xcf\xfc\x8a\x7f\x6e\x9e\x73\xfe\x5c\x76\x73"
+  "\x51\x3c\xcf\xdd\xec\x88\xe7\xb9\x9b\x3d\xe7\xcf\x65\x37\x27\xcc"
+  "\x7f\x37\x27\xcc\x7f\x37\x37\x9d\x3f\x97\xdd\x9c\x30\xff\xdd\x9c"
+  "\x30\xff\xdd\xdc\x3f\xff\x81\x97\xfc\xeb\xa5\x5e\x98\x98\x30\xff"
+  "\x4d\x4c\x98\xff\x26\x8e\x4d\x78\x9f\x18\xf3\x7e\x19\xde\xa7\xc6"
+  "\xce\x8f\x78\x9f\x63\xc8\xe7\x80\x7e\x99\x58\x64\x94\x61\x5d\x0f"
+  "\xdd\xdc\xa1\x97\x75\xc5\x94\xed\xd4\xcb\x6e\xe9\x97\x3f\x3e\xfb"
+  "\x46\xba\x5a\xaf\x4f\xfc\x92\x75\x3a\xfb\xa1\xf1\xdc\x04\xf9\xb8"
+  "\xf2\x34\x4d\x7c\x96\x61\x31\x0f\xb3\x5f\xa2\x78\xe5\x91\x50\xdd"
+  "\x48\xb2\x70\x9d\xba\x17\xc9\x2c\xdc\x37\x6d\xc4\x2f\x21\x2d\x03"
+  "\x7f\xd0\x29\x13\x61\xff\xbe\x9d\xaf\xe6\x8b\x5b\xf2\xa4\xcd\x8f"
+  "\x3a\x0a\xfe\x2d\x72\x5d\x03\x38\x36\xd4\xb1\x54\xa9\xb9\xb8\x03"
+  "\xcf\x19\xcc\xd3\xa8\x6f\x16\xa6\x9b\x3e\xc6\x2f\x21\x2d\x13\x7f"
+  "\x59\x21\xf7\x2d\x79\x06\x3c\x3e\x23\x4f\x26\xff\x89\x76\x6e\xff"
+  "\x7a\xd0\x44\xd6\x2a\xb7\xd6\xee\xd3\xd8\xb6\xbe\xa5\x54\xed\x2d"
+  "\x34\x7b\x85\xfb\x83\x82\x3a\xa4\x27\x5f\x27\xdd\x02\xfb\xef\x96"
+  "\x22\xb5\xdf\x72\x0b\xc6\xff\xc7\x5b\xd4\xde\x69\xb3\x17\xfa\xb6"
+  "\xf7\x04\x7d\xef\x01\xfc\xf6\xe1\xf7\x56\x03\xbe\x57\xae\xb7\x6f"
+  "\x39\x2a\xdc\x29\xf7\x33\xdc\x84\xf4\x2e\xe8\xb7\x5e\x6b\xc4\x55"
+  "\x70\x7e\xde\xf7\xb0\x86\x49\xbd\x2f\x49\xba\x1d\x36\x43\xaf\x9f"
+  "\xbe\x37\x87\xf1\x8d\x49\xcf\x15\xee\x11\x73\xb8\xbc\x9f\xdb\x43"
+  "\x9d\xc1\x6c\x6d\xc3\xef\x54\xf9\x89\x7f\x6f\x43\x42\x3f\xbe\x3c"
+  "\x41\xdf\x4f\x51\xfd\xf8\xfe\xa3\x09\x6d\xd7\x26\xef\xc7\xf7\x1a"
+  "\xd0\x8f\x2f\x07\xe9\x47\x9b\xa4\xad\x09\x7d\x31\x9d\x97\xc7\xf6"
+  "\xcf\x97\x92\xee\x71\xe9\xdf\x37\xeb\xb6\x50\x10\xeb\xb0\x4c\xe4"
+  "\xc9\xba\xf7\x97\x0d\x8c\x9b\x5e\x6e\x9c\xb5\x86\x66\x9f\xdf\xe6"
+  "\xf7\xa7\x0a\xf7\xb0\xfb\xfd\xf4\xfd\x32\x09\x67\x20\x7d\xae\xc2"
+  "\x05\x74\x32\x31\x9d\xd0\x1f\xd4\x1b\x6c\xbc\x8d\x75\x89\xda\x0b"
+  "\xf9\x3e\xe4\xff\x7b\xf3\x8c\xbd\xcc\x65\x65\x22\x60\xd0\x11\x79"
+  "\x87\x13\xf2\xc2\x31\x79\x1d\x71\x79\x6b\xfb\xd3\x23\x46\xfa\xd7"
+  "\x1b\xa7\xdc\x71\x09\xe3\x84\xf1\xc9\x7d\x2f\xbe\xdf\xb9\x93\x54"
+  "\xff\x30\x46\xe7\xd1\x3a\xb7\x00\x63\xd4\x97\x7c\x8c\x72\x4b\x93"
+  "\xf3\x5a\xae\xdc\x47\x13\x23\x29\x19\xbc\xdd\x18\xbb\x3e\xc9\x83"
+  "\xfa\x38\x9d\x3f\x3e\xb9\x47\x8c\xf1\xf9\x7a\x7d\xbc\x35\x33\xa1"
+  "\x8f\xd1\x13\x74\xeb\x26\xd5\xd7\x5b\x3f\x8d\x87\x7d\x6b\x76\x72"
+  "\x5e\xbc\x35\x0f\xfd\x8c\x26\xef\xe7\xad\x73\x07\xe7\xc5\x5b\x1d"
+  "\xe8\x4f\xf4\x7c\x5e\xbc\x55\xf9\x30\xe9\x3c\x98\x90\xb7\x47\xb8"
+  "\x93\xb6\xd3\xec\x8c\xb0\x9d\x7b\x6b\x84\xf7\x97\x62\xd2\x8f\xc5"
+  "\xf3\x1f\xfa\xc0\xf5\x98\x7e\x11\xa5\x67\x79\x1c\x4e\xd8\xc9\xf4"
+  "\x55\x3c\x19\x72\xdf\x36\x29\x81\x56\x67\x4e\xd0\x6d\xef\x75\x9b"
+  "\x52\x76\x29\x7a\xfd\x60\x5d\x3c\x4e\xb7\x15\x24\xa7\xd7\x6d\x25"
+  "\xa0\xd7\x99\xe4\xf4\xba\x6d\xe3\xe0\xf4\xba\x8d\xc7\xff\xcc\xf9"
+  "\xf4\xba\xcd\x1b\x4b\x2f\xd8\xba\xb2\x7f\xdf\xb1\x81\x37\xfa\x0a"
+  "\x45\x1d\xf7\x35\x4a\x99\x56\xf0\x8a\xaa\xd3\xc5\x75\x82\xd6\xb0"
+  "\xe2\x13\xd8\x90\x96\xd3\x74\xdb\x31\x43\xfe\x47\xd4\xd0\x30\xd1"
+  "\xf7\x08\xfb\x14\xa5\x70\x3d\x9f\xe3\x8c\xd7\x17\xc9\x21\x5e\x7f"
+  "\xc4\xb7\xfb\x83\xdc\xe4\xba\xe0\x07\xb3\x41\xd3\x17\x93\xa4\x17"
+  "\x29\x7f\xb2\x1f\xd4\xc7\xeb\x88\x1f\xb8\xe2\xc7\x08\x74\x43\x3d"
+  "\x1a\xb8\x83\x73\xc1\xbf\x0b\x8f\xd9\x0f\x02\xe7\x8f\xd9\xa4\x9f"
+  "\xa9\xf1\x9a\xf4\x6c\x3c\x7e\x93\x2c\xc9\xc7\x6b\x92\x7d\xf0\xf1"
+  "\x9a\x34\x69\xf0\xf1\x9a\x54\xc0\xe3\xe5\xa7\x49\xd5\xf1\xf3\xc6"
+  "\xa4\x92\xf8\xfe\x4e\x92\x32\x2c\x4c\x43\x2f\xe3\xf7\xaf\xdb\x6f"
+  "\xe3\x8f\x75\x1c\x8f\x55\x5d\x39\x81\x97\x53\xae\x62\x1c\x2f\x16"
+  "\xc6\xa0\xb0\x41\xc3\xea\xd5\xc9\xcf\x5b\x79\x8d\xdb\x5a\x43\xc4"
+  "\xe7\xc8\xf6\x2b\xd8\x76\x9f\xbc\x50\x33\x51\x3b\x9e\x4d\x27\xe8"
+  "\x8e\x1b\x35\x93\xa9\x8c\xcf\x3c\xa5\xef\xb6\xdc\x43\x98\x5c\x16"
+  "\x3b\x16\x7c\xf6\xc9\x6b\xd3\xcd\x6a\xed\xf4\xd7\x13\x74\xfb\x10"
+  "\x35\x2e\x77\x5c\x1a\x4f\xc7\xc9\xf5\xc9\xc7\x65\x72\x23\xc6\xe5"
+  "\xaf\xc9\xc7\x65\xf2\xd1\xc1\xc7\x65\x72\x00\xe3\xf2\xd7\xf3\xe5"
+  "\xe8\x76\x8b\x2e\x47\xeb\xb9\x8e\x7d\x09\xaf\xc7\x6f\x5f\xc5\x65"
+  "\xf0\x0c\x19\xb9\x7d\x3e\xe7\x8f\xef\x32\xe4\x48\xd6\x99\x04\x58"
+  "\xb2\x7d\xbd\x4c\xae\x0e\x23\x16\xee\x3c\x6b\x57\x32\x39\xb9\xdd"
+  "\xc1\x65\x6f\x28\x21\x0b\x68\x58\xb0\x83\x61\x2c\x25\x02\x8c\x16"
+  "\x2e\xc7\xe9\x58\xe1\xc7\xc8\xc9\xed\xbb\x8d\x72\xac\xeb\xf4\xb2"
+  "\xf5\x22\x54\xc4\x3b\x01\x89\x6d\xea\xfd\x1f\x26\xe7\x11\x2e\xcf"
+  "\xe5\x12\xca\x84\x95\x3c\xde\x31\x29\x5e\x1e\xef\xc8\x8c\xe7\x4f"
+  "\xd0\x1f\xf5\x34\xe8\x39\x3c\x2f\x00\x0e\x5f\x9b\xbf\x2e\x2c\x9b"
+  "\x77\x6c\x4c\x90\x4d\xf0\x40\xde\x78\xc5\x03\x79\xc3\xe3\x71\xbd"
+  "\x63\x57\x72\x1e\xb8\xa3\x69\x70\x1e\xb8\xa3\x7d\x70\x1e\xb8\x23"
+  "\xc8\x3c\xe0\xa7\xbc\x71\xf1\xb2\x99\x97\x11\xdf\x77\xb4\x2b\x65"
+  "\x93\x2e\xbd\x18\xd9\x84\x2d\x74\xd9\x60\x72\xc8\x32\xc5\x3e\x24"
+  "\x75\xbd\xc6\x59\xc7\xd7\xa2\x99\x05\x72\xc5\xf8\x79\x79\x4f\x09"
+  "\x3a\x3e\x97\x69\xb8\x53\xde\x0d\xcc\x3b\x1a\x4b\xc7\xcd\xea\xfe"
+  "\x9a\xf3\x04\xdd\xf9\x10\x9f\x2b\x2b\x7a\xde\x75\x55\x7c\xff\xf3"
+  "\x82\xc9\xe9\x79\x67\x06\xe8\xe9\x4c\x4e\xcf\x3b\xb3\x07\xa7\xe7"
+  "\x9d\x53\xf9\x6e\xd0\xf9\x32\x75\xe7\x5c\xfb\x0a\x69\xa3\xc8\x3a"
+  "\xa7\xe9\xce\x7d\x5f\x6f\x7e\xba\x73\x4b\xfc\xfc\x74\x67\xd9\xc5"
+  "\xcf\x4f\x77\xb6\x27\x9f\x9f\xee\x0c\x24\x9f\x9f\xee\xb2\x28\x79"
+  "\xb8\x2b\x2f\x5e\x1e\xee\xb2\xc7\xf3\x44\x5e\xf0\xbf\x6f\x7e\xba"
+  "\xab\x3a\x41\x06\xaa\x4e\xd0\x94\x4b\x61\x53\xb8\xd4\xb8\x4d\xf9"
+  "\x24\x01\xc7\x3d\xc9\xc7\xed\xae\x66\x8c\x5b\x55\xf2\x71\xbb\xcb"
+  "\x3f\xf8\xb8\xdd\x15\xc1\xb8\x55\x9d\x3f\x6e\x53\xb2\x2e\xde\xa6"
+  "\x98\x32\x3d\x7e\xcc\xa6\xe4\x5c\xfc\x98\x4d\xd9\x98\x7c\xcc\xa6"
+  "\xec\x4a\x3e\x66\x53\x9a\xd4\x98\x4d\x09\xc6\x8f\xd9\x94\xa3\xf1"
+  "\x63\x06\xba\xfd\x83\x63\x86\xf1\x69\x56\xfe\x09\x53\x1f\xc0\xba"
+  "\x7d\x58\xc8\x3d\x35\xdf\x4f\xd3\xb2\xd4\xda\x7a\x9a\x9a\x3b\xd4"
+  "\x18\xbe\x85\x32\x79\xe7\xcf\x03\x53\x8b\xf4\xb4\x9f\x9c\x3f\x0e"
+  "\x53\x37\x40\x47\x77\x35\x97\xc9\xb3\x2d\x35\x86\x4c\x73\x94\xf3"
+  "\xae\xe6\xf3\xa9\xa9\xd2\x7f\x1d\x63\x2c\x7c\xe1\x08\xb1\x5e\x47"
+  "\xf9\x20\xc3\xe1\x3b\x91\x09\xb0\xda\x2e\x66\x8e\x1f\xdc\xa7\xa6"
+  "\xb9\xd9\x5b\x7e\x13\xe0\x4d\xfb\x5c\xf1\xea\xb4\x44\xfb\xb7\x0e"
+  "\x79\xef\x2a\x3e\xfd\xe1\x73\xf1\x38\x4c\x9b\x93\x9c\x4f\xa7\x15"
+  "\xa3\x0f\x75\xc9\xf9\x74\x9a\x67\x70\x3e\x9d\x86\xf1\xa7\xba\x98"
+  "\xb5\xcf\xc8\xc7\x22\xfe\x84\xb5\xcf\xb4\xc3\xd6\xa0\xe2\x1d\x69"
+  "\x13\x55\x34\x37\x03\xe7\x44\xfb\x0f\x63\x73\xf7\xd3\x3a\xce\x0b"
+  "\xe3\xeb\xdf\x3d\x88\xfd\x77\x37\xdb\x7f\x6f\x25\xc7\xf9\xee\x0b"
+  "\xd8\x7f\x77\xb3\xfd\xf7\xd6\xf9\xb2\x75\xb7\x6e\xff\x25\x5b\xe3"
+  "\xdd\xbd\x31\xf9\xf8\xdf\x9d\x30\xfe\x54\x50\x8a\xf5\xb0\xac\x1f"
+  "\x5f\xee\x48\x6c\x39\xf6\x4d\xe2\xb2\xcc\x23\x49\xca\x86\x13\x61"
+  "\x26\x2f\xf7\x43\xfb\x79\xbc\xc7\xbe\x54\x49\x79\xef\x87\xf9\x4a"
+  "\x1e\x7f\xb8\x2b\x5e\x1e\x7f\xb8\x20\x5e\x1e\xef\x4e\x18\xbb\x1f"
+  "\x6e\x88\xcf\x07\xff\xfc\xb7\xe9\xd8\x1f\x06\x13\x78\xe0\x83\x13"
+  "\x34\xfd\x59\xc5\x03\xd3\xff\x18\x8f\xc7\xf4\x8c\xe4\x3c\x30\x7d"
+  "\x2c\xfa\xff\x41\x72\x1e\x98\x9e\x37\x38\x0f\x4c\x67\x1f\x9f\x0f"
+  "\x62\xf9\xf6\xfe\xb2\xbc\x61\x09\x65\x5c\xc9\x75\xde\xf4\x9a\xe4"
+  "\x7b\x04\xd3\xf7\x2a\x1a\x4f\xef\x8c\xa7\xf1\xf4\xc3\xf1\x34\x44"
+  "\x5f\xfe\x71\x1a\xf6\xc7\x26\x08\xb9\xef\x49\x94\x7f\xdf\x09\xba"
+  "\x47\x97\xff\x1f\xbd\x1d\x8f\xe3\x3d\x73\x14\x2e\xc9\xf6\x45\xee"
+  "\xe1\xf5\xaf\x2f\x39\x2d\xef\xd9\x98\xbc\xcf\xf7\xec\xc2\x1c\xe4"
+  "\xd3\xce\x93\xa5\x7b\x9a\x90\x7e\x3f\xef\x87\xf2\x7e\xc8\x4e\xa4"
+  "\xdf\x1f\x21\x8b\x9c\xaf\xfa\xe7\xa5\x7b\xfc\xec\x8b\xc2\xf4\x67"
+  "\xfe\xb5\x8e\xa1\xd9\x3c\x07\x31\x5e\x85\x65\xd2\x6f\xc1\xba\x81"
+  "\x79\xfd\x6a\xe6\xf5\x1f\x49\xfb\x8f\xcf\x59\xd8\x8f\xd0\xea\xa0"
+  "\xd9\xbe\x60\x84\x0c\x7e\xe7\xf2\xf1\xb0\x7f\x34\x89\xe5\x82\xcb"
+  "\x1b\x65\xd5\xbe\x99\x2b\x81\xbf\x7f\xb4\x20\xf9\x18\xff\xa8\x6c"
+  "\x70\xde\xf9\x51\x8d\x1a\xe7\x1f\x1d\x89\x1f\xe7\x1f\xed\xd5\xdc"
+  "\x23\xe6\x70\x5f\xfd\xa0\xf3\xc5\x8c\x71\xa9\x5d\x04\x06\xd5\xf7"
+  "\xeb\x1f\x69\x2f\x29\xa7\x2b\x4e\xd2\x8f\x27\xca\xf6\x4c\x22\x6c"
+  "\x5d\x97\x42\xcd\x52\x07\xfc\xb8\x42\xe2\x89\x32\x85\x11\x32\x89"
+  "\xf5\x4f\xb5\x73\x5e\x9d\x5b\x84\x51\xae\x8d\xcf\x04\xf8\x4e\x31"
+  "\x78\xe1\xb2\xe3\xf4\xe3\x19\x71\xf5\xcd\x44\x3e\x05\xc3\x53\x27"
+  "\xe5\xf1\xc7\x1b\x8c\x3d\xdd\x0d\x78\x4f\xbe\xef\xfb\xe3\xdd\x86"
+  "\xef\x83\xf2\x19\xfb\xf1\xa0\xe7\x97\x8c\x13\xdf\x9b\x61\x9c\x2e"
+  "\xac\x07\x7e\x1c\x31\xf8\x57\xf9\x5a\xe6\x67\x0c\xf8\xf2\xe5\xdb"
+  "\x90\xe7\xbd\xc0\xde\x60\x8c\x1c\xe4\x4f\x8d\x85\xa3\xe2\x73\xe4"
+  "\x17\x18\xfe\x78\x78\x5e\xf0\x15\xb0\x74\x7c\xf2\x37\x26\xe0\x53"
+  "\x0b\x3b\xa5\x54\x87\xb1\xfb\x42\x30\x78\xcc\x15\xcf\x32\x3f\xe4"
+  "\x7b\x2f\xb4\xe7\x97\x6a\xa3\xd9\x2f\x9d\xc7\x5b\xf9\xd2\x5e\x62"
+  "\x18\x17\xc6\x71\x46\x4e\xdc\xda\x42\x9e\xdd\xf3\xd9\xd6\x8c\xa8"
+  "\x92\xfb\x19\x09\x7b\x84\x33\xf2\xa5\x3f\x95\x2e\xf7\x8f\x45\x12"
+  "\xe5\x60\x46\xb1\x31\x47\x27\xa4\x6f\x30\xe4\x1e\xeb\x5a\x86\x9b"
+  "\xb0\xcf\x3a\x63\x97\x92\x85\x19\x11\x2d\x2d\x76\xbd\x36\x43\xda"
+  "\x7f\xc6\x7e\x29\xf2\x77\x25\xd4\x4b\xd8\xff\x9b\x91\x2f\x06\xdf"
+  "\xa7\xcf\xc0\xf8\x06\xf9\x6c\x4b\xc5\x28\x98\x39\x2e\x61\xbf\x22"
+  "\xb0\x59\xde\x41\xff\x0b\xe0\xce\xd4\xf5\xde\xac\xd7\xe2\xdb\x9b"
+  "\x99\xef\x3c\x75\xa1\xfe\xcf\x1c\xa4\xff\x33\x07\xfa\xbf\x44\xc2"
+  "\x4d\xd8\x4b\x9c\x29\xfb\x1f\x3d\x4f\xff\xcd\x6c\x82\xfe\x32\xe8"
+  "\x06\x9b\x7b\xd6\xe5\x86\xad\xce\xfb\x07\x83\xdb\xea\x33\x07\xf6"
+  "\xff\x64\xbd\x99\x03\xfb\x7f\x81\x64\xb6\xba\x9f\xe4\xd9\x6a\x5c"
+  "\xdb\xb3\x72\xad\xb5\xc9\xfa\x32\x6b\x90\xfd\xbf\x59\xfa\xfe\xdf"
+  "\x2c\x6f\xbc\x3e\x9b\xe5\x8a\x1f\xc3\x99\x09\x63\x38\xab\x3e\x7e"
+  "\x0c\x67\xe6\xff\x57\xe7\x35\xbc\x53\x6a\x6a\xaa\x29\x35\xc5\x94"
+  "\x92\x8a\x6c\x74\x91\x86\xa5\x9a\x53\x87\xe0\x6f\xa8\xfe\x3b\xcc"
+  "\x94\x6a\x32\xe3\x6f\x88\xfe\x3b\x34\xe1\x7d\x18\xd7\xc5\x9f\x59"
+  "\xff\x1d\x92\xf0\x3e\xf4\x2b\xf2\x87\xe9\xed\x1a\xed\x9b\x13\xde"
+  "\x87\x7c\x45\xfe\xd0\x7f\xb0\x3e\x9d\xf7\x1e\xef\x87\x76\xcf\x92"
+  "\x15\xf3\x8b\x17\x2f\x90\xe7\xc5\x0b\xed\xf3\x9f\x78\x62\xe1\xb2"
+  "\x65\xf6\xd2\x67\xec\x77\xdd\x79\xdf\x4d\xb7\xd9\xd5\xb1\x73\xf1"
+  "\xe4\x6b\x16\xa4\xd3\x8c\x95\x4b\x39\x63\xc6\xfd\xf7\x14\xd8\x67"
+  "\xdf\x75\x67\x7c\xa6\x01\x46\x1e\x2f\x5f\x08\x4a\x8c\xfc\xe5\x55"
+  "\x8c\x22\xda\x38\x4a\xea\x9e\x0e\xf6\xf3\x55\x7b\x1e\x0f\x5e\x7a"
+  "\x04\xdc\x2f\x7a\x9d\xc2\x7b\x35\x9f\xe9\xdf\x7b\x88\x3b\x31\xbe"
+  "\xde\x45\x25\x8b\xf8\xfe\xca\xbd\x9f\x89\xf7\x03\x64\xff\x11\x99"
+  "\x8e\xd3\x23\x57\x35\x4f\x47\x59\xbc\xfb\x3a\x22\x64\x77\x92\xe5"
+  "\x04\x3d\xf0\x21\xf2\x52\xc4\xed\x1a\xd2\x82\xba\x2f\xf4\x9c\x8f"
+  "\x65\xda\xfb\x2e\xa3\x9c\xf5\x04\xdd\xf7\x9c\x78\x5f\xc8\x77\xbe"
+  "\x27\xa4\xca\xdd\xf7\x90\xe6\xbe\xd7\xc6\xba\xa1\xf6\x45\x32\xef"
+  "\x7c\x91\xe8\xd5\x91\x64\x79\x75\x14\xc7\xea\xb8\x2f\xdf\x38\x0b"
+  "\xad\xc0\xbb\x9f\x1e\xb1\x73\xdb\x5c\x56\x33\xdd\x7b\x97\x2c\x3f"
+  "\x32\xae\x7c\xd9\xc0\x59\xec\x7d\xf9\x26\x94\x9b\xf5\x39\x59\xc3"
+  "\xe9\x4d\xf5\xbe\x32\x17\x59\xa3\xe2\x8b\x1b\xa6\x53\x4a\x2b\x2c"
+  "\xe1\x55\x11\x11\xf1\x2e\x3d\xc9\xed\xff\xd1\xba\x4a\x7c\xe1\x83"
+  "\xb6\x9e\xd1\xe5\x14\x9b\x4f\x91\x19\x72\x9d\xe2\x5d\xca\x7e\x0a"
+  "\xf7\xed\xdd\xf9\x25\x99\x41\x83\x31\x27\xe9\x7e\x7f\xd9\x0c\x11"
+  "\x75\xce\x20\xf3\x9f\x1c\xec\x73\x78\xe8\xf6\xcd\x7f\x26\xf3\xaf"
+  "\x7a\x5d\xa6\x5e\x61\xa3\xb2\x52\xd1\x29\x38\x86\x4f\x50\x84\xd9"
+  "\xcf\xff\xc8\xbc\x28\x97\xb9\x21\xe4\xb4\x51\x6b\x69\x90\xd6\x1e"
+  "\x13\x61\xcf\x9f\xd5\xfd\x80\x96\xae\x20\xfb\x30\x5a\xd6\xce\xa0"
+  "\xd4\x13\x05\x64\x6a\x29\xaa\x21\xdf\xdc\x20\x95\x1d\x13\x9d\x47"
+  "\xe6\x7d\x4e\xad\x45\x7b\xa9\xb0\x9d\x4c\x47\x3a\x3e\x25\x19\x87"
+  "\xa6\xb2\xaf\xad\xfc\x1c\xd9\xd6\x2e\xe6\xb4\x73\xb4\x7a\x2d\x0d"
+  "\x5f\xfd\x09\x59\x7d\x9d\xed\x68\xe7\x14\x3d\x7c\x94\x52\x00\xcf"
+  "\xb4\xe6\x53\xb2\xad\x79\x88\x7d\x7d\xf3\xa8\xb6\x9c\x6c\xc2\x99"
+  "\x9d\xd1\xeb\xcc\xce\xec\x15\xd9\x23\x43\xce\xec\xac\xd6\x12\x94"
+  "\xef\x78\x8f\x46\xb4\x53\xd6\xfb\x27\xdb\x4d\x35\x67\x69\x8c\x7d"
+  "\x26\x8f\xff\xfd\xc7\x6a\xcf\xa2\x7c\xe5\xc7\x2e\x0d\x75\x63\xeb"
+  "\x44\xd2\x3e\xae\xf1\x15\x84\x49\x03\xac\x9a\x5e\x1a\x53\xdb\x4b"
+  "\x36\xad\xe2\x63\x17\xd3\xa2\xaf\xb2\xb9\x1e\xba\x70\xd8\x5b\x8f"
+  "\x37\x9a\x7d\x47\xba\xa8\x25\xd8\x4b\xad\xf4\x17\xf2\x39\xfe\xe6"
+  "\xfd\xd5\xe3\x8d\x43\x34\x30\xbf\x77\x75\x07\xe0\x2b\x9e\x71\xb6"
+  "\xf0\x7d\x65\x17\x55\x95\x53\x46\xc9\x6a\x1a\x76\x12\xe9\x6a\x4d"
+  "\x7f\x60\xb7\x2f\xf2\x37\xef\x6a\xe9\x87\xfb\x88\xbd\xbc\x85\x52"
+  "\x5b\x83\x35\xec\xef\x69\x8a\xa6\xf7\xb5\xf9\x82\x6d\xe4\x2b\xf9"
+  "\xab\x57\xb3\xf4\x35\x6e\xd4\xc8\xf2\xeb\x9e\x36\x93\xcf\xdc\x43"
+  "\xbe\x82\x20\x7d\x80\xb6\x45\x65\xdf\x31\xe8\xab\xbc\xd6\x60\x98"
+  "\xef\x39\xe5\x88\x6e\x5b\x7a\xd5\x52\x1a\xb7\xf3\x2c\x8d\xdd\x71"
+  "\x96\xb2\x45\x28\xdb\xc4\xbe\xb5\x7c\x3f\x75\x07\x7e\x33\x3a\xc8"
+  "\x82\xfe\x2a\x3f\xec\x34\xdd\xc7\xb6\x2f\x9b\xea\x7a\x07\x7c\x6c"
+  "\x7b\xbb\x07\x7c\x6c\xc1\x4b\xb3\xd9\xcf\xf6\x38\xdd\x67\x61\x7e"
+  "\xae\x3a\x4d\xe6\xf5\xa7\x89\x6e\x70\x99\xc8\xfe\x38\xdf\xab\x78"
+  "\x60\x9f\x6f\xc1\x29\xf9\x7c\x9c\x1e\x28\xc6\x6f\x06\xfe\x52\x90"
+  "\x2e\xf7\xb3\x3b\x74\xbe\x45\x9a\x09\x69\x0f\xe0\x37\x15\xbf\x33"
+  "\x9c\xb5\x22\x80\x36\xc2\xdd\x26\x4a\x67\xfe\xd5\xfd\x79\xc3\x21"
+  "\xf7\x03\xb0\x7f\x9e\x2c\x36\xf8\x58\xe9\xf4\xfb\x66\x7f\x70\xe2"
+  "\x14\xc7\x85\x0a\x48\x7c\xfa\x8a\x52\x38\x46\x94\x9e\xce\x38\xfc"
+  "\x9a\xdb\x45\xfb\xd5\xf8\xb5\xe2\x8f\xe5\x72\xac\x51\xb7\xbb\xaf"
+  "\x88\xdb\x7c\x03\xe9\xc2\x48\x47\x7f\xcd\x9c\xf7\xce\x89\x53\x26"
+  "\x55\x26\xdb\x04\x98\x61\x1d\x3e\x64\xfd\xde\x20\xcb\x74\xb7\xc9"
+  "\x2a\x0e\x2e\x98\x48\xb5\xa3\x44\xdb\x8e\xad\xa2\x59\xc9\xda\x03"
+  "\x68\xfb\xa9\xbd\x8c\x23\xe6\xed\xe6\x8d\xc8\x3b\x88\x55\x2c\xd3"
+  "\xa5\x79\x1e\xfb\x8f\x3d\xc8\x71\xa3\xc6\xc6\xf6\x41\xb8\x67\x85"
+  "\x79\xee\x7c\xb3\xdc\x3b\x44\x98\x66\x87\x5b\xfd\x5d\xf4\xab\xde"
+  "\xce\x21\xce\x3f\x92\xc9\x17\x39\x4e\x13\xb2\xc8\xc6\xf6\x5f\xdd"
+  "\x56\xe1\xc7\x6f\x27\xfb\x73\x82\x4f\xbe\x7d\x92\x1e\x7c\xe0\x5f"
+  "\xb2\x28\xeb\x23\x07\xe9\xfa\xe8\xc1\xa7\x07\xf4\xd1\xc3\xe7\x5a"
+  "\x3a\x1a\x63\x74\xd1\xc3\x6f\x9c\xaf\x8b\x1e\x7a\x4d\xe9\x22\x11"
+  "\x51\xba\x27\xea\xd7\xd3\x37\x25\xa4\xeb\x7e\x21\x0f\x3d\x9b\x90"
+  "\x1e\xd6\xd3\x1f\x4d\x48\x0f\xa8\xf4\x82\x1d\x86\xae\x6b\x65\x3c"
+  "\x56\xb2\xae\x2b\x58\xc7\xba\xae\x75\x81\xae\xeb\xa4\x8f\x61\xc1"
+  "\x42\xf1\x73\x17\xf1\x9d\x25\x3c\x4f\x66\xfc\xc5\xfb\x64\xe0\x9e"
+  "\x76\x82\x7e\x12\xe5\xb4\xea\xbf\x90\x19\x7f\x52\xcf\x09\xf7\xbd"
+  "\x85\xac\xe7\x58\xc7\xb1\xdf\xc9\xf6\x51\xa2\x7d\xfb\x56\x71\xb4"
+  "\x76\xab\x38\x12\x72\xff\xa4\xd8\xd0\x77\x2f\x20\x6d\x23\xd2\x5e"
+  "\x40\x3e\xeb\x3d\xa6\x49\x4b\x41\x23\xc7\x71\xe8\x00\x8f\x4d\xb2"
+  "\xa6\x50\xc9\x66\xf0\x3c\xdf\x2f\xdc\x00\xfa\xfa\x4a\xf9\xde\x6a"
+  "\x94\x64\x3c\x25\x53\x0e\x74\x54\x07\xcb\xdb\xa8\xf5\x90\x2f\x9f"
+  "\xe3\x73\x2a\x0f\x8a\x93\x7c\xcf\x8e\x71\x28\x5c\xf5\x23\x8e\x11"
+  "\x94\xd2\x0c\xeb\x82\xfd\xc0\xd9\x5f\x05\x7a\xd7\x5c\x0d\x9c\x54"
+  "\x8c\x94\x9f\x60\xfd\x5f\xa7\xdf\x63\x7a\xc4\xce\xf1\xc7\x8e\xd3"
+  "\x4f\x72\xb1\xbe\x0b\x73\xdf\xac\x51\x17\xf1\xbd\x17\xc8\x28\xaf"
+  "\xf1\x8a\xb6\xe3\xaf\xda\xb8\xfb\xc2\xb1\xe8\x50\xc6\xd7\x1e\x26"
+  "\xc6\xd9\x4f\x3f\xd9\xd0\x52\xd6\xc8\xf5\xb3\x99\x36\xc2\xed\x34"
+  "\x60\xa4\xc8\xbb\x33\x6e\xb2\xf0\xdd\x19\x3f\x15\xc8\x18\x82\x22"
+  "\xbd\xb9\xbe\x65\x6e\x80\x58\xcf\xfb\x3a\x01\xa3\xec\xb8\x82\x01"
+  "\x58\x02\x7a\x3f\x2e\x4f\x87\x3f\x7c\xad\xf8\xe2\x38\x3d\x18\xe4"
+  "\xf1\xe2\x7b\x90\x7c\xbe\x06\xba\x64\xb0\x6f\xbc\xb2\x3d\x7f\xb2"
+  "\xb6\xee\x2f\x44\xfa\x5d\x4e\xf0\xdb\x4f\xca\xf8\x9e\x12\xdf\xdf"
+  "\x94\x77\x37\x4d\x13\x49\xac\xcc\xce\xe8\xbf\xbf\xf9\x7f\xe1\xee"
+  "\x26\xe8\x6f\xdb\x69\x12\x7b\x81\x7f\x19\xdf\xdf\x04\xfe\xc7\x98"
+  "\x0f\xf5\x3e\xb9\x5e\x7e\x98\x69\xfe\x60\x33\xa7\x61\xad\x78\xd8"
+  "\x18\x7f\xee\x2f\xf7\x05\x79\xbb\x95\x4d\x28\xda\xfc\xf4\x90\x8b"
+  "\xf3\x91\xb6\x85\xcb\x4f\x80\x1e\xf3\x2d\x88\xd2\x5b\x27\xa2\xa6"
+  "\xaa\xd5\x64\x56\x3a\xed\xe1\x57\xb9\xbe\xd2\x69\x0f\xcf\x1e\xd0"
+  "\x69\x0f\x4f\x53\x3a\x4d\xd1\x58\xe9\xb4\x87\x6f\x55\x3a\xed\xe1"
+  "\x1b\xe5\x39\x18\x74\x1a\xe7\xb1\x5e\x33\x74\xda\x8e\x51\xe2\x30"
+  "\xeb\x8e\x90\xfb\x61\xbb\xa1\xdb\x36\x21\x8d\x75\x07\xe3\xa8\xf4"
+  "\x54\x81\x43\xfc\x7f\xd9\xa4\xfc\x0c\xf8\xb9\x88\xef\x2b\x74\xea"
+  "\xcf\x18\x97\x87\x7f\xa6\x74\xdc\xc3\xa5\x03\x3a\xee\xa1\xf0\x40"
+  "\x5d\xd6\x71\x0f\x57\x28\x1d\xa7\xd2\xeb\x1e\x66\x1d\x57\xe0\x60"
+  "\x1a\xe8\xf0\x4d\xbc\x67\xa7\x97\x67\x3a\xba\x62\x75\x5c\xbc\x7c"
+  "\x3d\x7c\xc4\xd0\x71\xac\xdb\xf0\x0e\x1b\x24\xfd\xb0\x94\x37\x94"
+  "\xdb\x02\x9a\x1b\x72\xc7\x63\xc0\x7d\xe6\x38\x63\x4c\xb7\x29\xa7"
+  "\x68\x98\x7e\x57\x48\xef\xf7\x23\x36\xc3\xd7\xd1\x4f\x0f\xdb\x93"
+  "\xd9\xcd\x86\x9d\x06\x7e\xbc\x32\xca\x71\x3a\x5c\x98\x4b\x6b\x84"
+  "\xab\x35\x72\x94\x1e\x2b\x25\x93\x96\xfa\xd4\x67\x3c\xb6\x58\x67"
+  "\x0c\xe5\x5f\xd6\x3d\x98\x43\x1f\x2d\x0c\xd2\x50\xac\xcd\x3f\xab"
+  "\x32\x21\xcf\x41\x3f\x88\xc9\x5b\xc5\xed\xc4\xd4\x1b\x1f\x93\x27"
+  "\xe3\x51\x8e\x3f\xcd\x31\xe6\x1e\xc9\x1b\x6c\xed\x7f\x91\xb8\xfc"
+  "\x7d\x70\x5c\xe6\x0e\x19\x1c\x97\xb9\xd2\x0e\x18\xdf\x45\x29\x58"
+  "\x9b\x5d\x7a\x9a\x1e\x91\xfb\x31\x32\xee\xcd\xfa\x64\xed\xcc\xbd"
+  "\x57\xcf\x1f\x12\x93\x1f\xdb\xd6\xb3\x49\xea\xc7\xb6\xf7\xb3\xaf"
+  "\x80\xff\xf6\x57\xc0\xff\xf8\x2b\xe0\x7f\xc1\x3a\x10\xb4\xb3\x6a"
+  "\xa6\xf8\x72\x37\x44\xa4\x0c\x1e\xe6\xfb\x7a\x27\xe9\xd1\x6f\xea"
+  "\x7b\x3e\x9f\x39\xaf\x92\x6b\x41\x79\x6f\x6b\x33\xf2\xf9\x5e\x3e"
+  "\xeb\xe7\xa9\x18\x41\x75\x46\xdd\x5f\x67\x46\x22\x6e\x23\x22\x06"
+  "\x6e\x32\xff\xe9\x44\xdc\x90\x3f\x3e\x26\x7f\xd3\xc0\xb8\x3f\x7a"
+  "\x41\xff\x7a\x5f\x0d\xc9\x18\x9c\x07\xb1\x7c\xc1\x9c\xcc\x71\xff"
+  "\xf4\xfd\x99\x47\x3b\xa0\xe7\x73\x62\xfc\x76\xbb\xa0\xdb\xaf\xe4"
+  "\xf8\x0b\x6c\xfb\x56\xa9\xf5\xf0\x37\x30\x9f\x8c\xe4\xfb\x3a\x7c"
+  "\x77\xa7\x30\x3a\xdb\x74\xb0\x8c\x65\xe8\x31\xbb\x51\x77\xb0\x7d"
+  "\x20\x6e\x57\x6f\x93\x7d\x60\x83\xa8\x33\xc7\xa8\xc3\xb0\xd9\x8f"
+  "\x12\xf3\xc0\x95\xf2\xce\x6b\xa4\x8b\xf5\xee\x37\x60\x27\x8f\x54"
+  "\xed\xcc\x23\xbd\x1d\x0f\xea\x0c\x7a\x57\xfd\xc2\xfd\x7b\xac\xf9"
+  "\xe2\xfb\x47\x7a\xff\x0a\xe9\x2b\xfa\x77\x81\x76\x0b\x27\x5d\x7c"
+  "\xbb\x99\x46\xbb\x8e\x8b\xa7\x6b\xe1\x9e\xaf\x4f\xd7\x1c\x9d\xae"
+  "\x85\xfe\xaf\xa0\x6b\x92\x76\xe6\x65\x7d\xfd\x76\xec\x7a\x3b\xf3"
+  "\xa6\x27\x6b\x87\xe4\xbf\x41\xef\x75\x59\x8c\x18\x98\x1c\x0f\x56"
+  "\xc5\xbb\x9b\x57\x1d\x1b\xeb\x57\xc5\x89\x9d\xb7\xcb\x88\xf5\xab"
+  "\xc7\xa2\xc5\xdc\x32\xef\xc3\xc2\x7a\xb6\x47\x84\xe6\xa7\x79\xcd"
+  "\x1c\x5f\x75\xea\x5a\x75\x67\x5c\xaf\xd3\x7e\xa1\x18\xc3\x1c\x67"
+  "\x4b\x88\x02\x3a\x58\x23\xfd\x01\x30\x0f\xcd\xbf\x94\xef\x07\xa8"
+  "\xf3\xcc\xf9\x63\x94\x4c\xce\x1f\x03\xd8\x45\x83\xc3\x68\x2b\xd9"
+  "\x55\x9e\x33\x64\x30\x9f\x7f\xd4\x9f\xeb\xa7\xa7\xe7\x70\xfd\x68"
+  "\x65\xab\x43\x9c\xb1\xe9\x71\xfe\x9e\x78\x37\x26\x0e\x21\xe6\xee"
+  "\xc7\xff\xae\xdf\x4d\x00\x0d\x5c\xa0\xe5\xfc\x2d\x06\x0d\x8c\x74"
+  "\xa4\xed\x36\x68\x00\x7b\x25\xc3\x57\x1f\xe1\xbb\x43\x41\x75\x4f"
+  "\x7c\x7e\x8b\xa8\x68\xd3\xef\x48\x3e\xae\xce\x19\xd2\x5b\x1d\xc1"
+  "\x35\x36\x93\x51\x7f\xac\xdd\xf9\x25\xf3\x70\x20\xad\x6d\x1e\x60"
+  "\x05\x0d\xf8\x82\xf1\x12\x03\xe5\xea\xa4\x5f\xd2\xe3\x18\xff\x42"
+  "\x15\xdf\x11\x6d\x48\xdc\x4d\x94\xaa\x01\x7f\xf4\xc1\xe4\x2b\x09"
+  "\xb2\x9d\xda\x15\x45\xff\x59\xd7\x35\x2c\xf1\x9b\xb9\x8c\xb4\x1d"
+  "\xce\x64\x9b\x54\x0c\xc5\xc7\x9f\xd6\xce\x70\x4c\x1c\x89\x57\x06"
+  "\xfa\xdc\xc8\x38\xf9\xf1\x1b\x58\x93\x4d\xb3\xce\x91\x4e\x8b\xc7"
+  "\x1f\xd0\x90\xae\x2d\x1b\xc0\x61\xa7\xbc\xe3\xf1\x78\x8d\x81\x83"
+  "\xc6\xed\x87\x6c\x26\xd8\x62\xdc\x6e\xa7\xbc\x6b\x89\xb6\x27\x70"
+  "\x4c\x3b\x8e\x8d\xb1\x32\x9b\x18\x07\xd4\x39\x62\xd0\x5b\xaf\x63"
+  "\xb4\x51\xa6\xc9\xb6\x15\x6d\x14\x9d\x0f\xc2\x1e\x7c\x3c\x72\x3e"
+  "\x9d\x9f\xc8\x8c\xa1\x73\x2a\xf3\x15\xef\xb1\x00\xff\x5f\x33\xbd"
+  "\xf9\x5c\xc3\xbe\x82\xed\xaa\x27\xee\x3c\x18\x94\x7e\x27\x19\x0c"
+  "\x57\x03\xfd\x19\x06\xe0\x5e\xa2\x68\xfc\x44\x41\x3f\x8d\xd1\xb6"
+  "\xc0\x58\xac\x57\x77\x52\xd8\xf7\x1d\xba\xe3\x09\x47\x7f\x3b\x8c"
+  "\xab\xd3\x66\xd2\x84\x8d\x63\x66\x06\x18\xd7\x52\xbb\x08\xb3\x5d"
+  "\x29\xfd\x98\xd0\xd7\x86\xf2\x76\x33\x6c\x4b\x93\x6c\xab\x3b\x9b"
+  "\xed\x7b\x8b\x7c\x46\x5b\x83\xf0\xf7\xdb\x1c\x97\xd2\xe8\x17\xfa"
+  "\x62\x61\xde\x02\xee\xb0\xff\x16\xbc\x27\xf9\x65\x05\x8f\xd3\x82"
+  "\xd7\x38\xcd\x28\x87\xf7\xe5\x5c\xce\x78\x47\x1e\xf8\x6b\xc1\x2d"
+  "\xe8\x57\x3a\xe3\x19\x70\xca\xd8\x2f\xe8\xf3\x82\x76\x86\x11\x72"
+  "\x2f\xc8\x8b\xeb\x67\x5f\x81\xd9\xe0\x3b\x3e\x23\x6a\xb6\x87\xa5"
+  "\xee\x54\xb4\x5d\x50\x6c\xc8\x24\xd7\x57\x32\xb6\xc0\x15\xcb\x8b"
+  "\x41\xe7\x00\x1f\x94\x5e\x45\x16\xb3\x9d\x63\x69\x2e\x98\xa7\xe2"
+  "\x80\x2f\xd8\x93\x38\x5e\x9c\xc7\x71\x27\x75\x1a\xb2\x3c\x65\x1e"
+  "\xa7\x05\xf5\xdc\x37\xf0\x5a\xf0\x42\xf3\x25\xc7\x84\xe4\x58\x9e"
+  "\x2f\x29\x39\x02\x5d\x16\x7d\xf3\x25\x75\xbf\x27\xa8\xe2\x2b\x2e"
+  "\xfc\xb6\x30\xbd\x26\xc7\x8b\xfd\xf2\x64\x1c\x0d\x79\xf7\x7b\x21"
+  "\xfb\xb8\x89\x11\x25\xaf\xc9\x38\xac\xba\xcf\x5e\xa0\xb9\x24\x22"
+  "\xe3\xf0\x39\x4b\xf9\x2e\x6c\x84\xd7\x64\xd2\x27\xed\x60\x69\x84"
+  "\xee\x0f\x33\x6d\x17\x16\xf3\x1d\xf7\xa0\xa4\xc5\x42\x87\x71\xaf"
+  "\x9d\xe3\x4c\x72\x9c\xd2\x09\x11\x4a\x65\x9b\xc2\xee\xe4\x98\x04"
+  "\x8b\x66\xb3\x4d\xa2\x68\x0a\xbe\x37\x89\x36\xc5\xcb\x0b\x3f\xe4"
+  "\x7b\xec\xea\x7c\xe9\x38\xf8\x3b\xf5\x6f\xc7\x69\xe1\x7f\xa8\x7d"
+  "\x19\x43\xd6\x16\xdd\xcb\x67\x4c\x7e\x1d\x06\xda\xc2\xfc\x3f\x7f"
+  "\xea\xf9\x72\xb1\xf0\x43\x63\x8d\xc1\xf7\xe2\xd4\x79\xd5\x00\x3c"
+  "\x3f\x2d\x94\xfb\xd2\x03\xba\xe9\xf7\x80\xb5\x28\xe7\x7c\x99\x59"
+  "\x34\xd5\xe0\xe5\x92\xab\xf9\x6e\xf5\x42\x0b\xb7\x3f\x98\xce\x14"
+  "\xce\x87\x78\x9c\x2c\x27\xec\x94\xfa\x55\xf7\x25\x06\xce\xbf\x16"
+  "\xed\x36\xfa\x60\xd0\x44\xf5\xe1\xa7\x29\xdd\xe9\xcd\x87\x07\xfa"
+  "\xfe\x53\xe5\x6f\x36\x90\x7f\x6b\x0c\x6d\xf8\x3d\x57\xf1\xdd\x22"
+  "\xac\x29\x9e\x68\x56\xbc\xa8\xd2\x44\x7a\xdb\x13\x1c\x03\x56\xe1"
+  "\xb8\x98\x0c\x7e\x0f\xb9\x7f\x3a\xd6\x4f\x67\x8e\xa8\x73\xa8\x9f"
+  "\xa2\xff\x8b\x5c\xaa\xde\xa2\x23\x8c\x4b\xd2\x7e\xc6\xe3\xb8\x97"
+  "\xe7\x58\x15\xeb\xe0\xa7\x6f\x33\xbe\xf6\x6b\x79\x8c\x7f\xba\x96"
+  "\xdb\x95\x71\x0f\xfa\x8a\x86\x04\xfb\xb2\xa9\xbb\xaf\x08\xf2\x93"
+  "\x6d\x42\x3b\xd0\x7f\xa7\x77\xeb\x6d\xee\x32\x70\x65\xdc\x60\x2b"
+  "\x5a\x42\x62\x71\x72\xfa\x72\xbb\x32\x1e\x53\xd1\x30\xfc\x59\xf0"
+  "\x37\xf4\xeb\xce\xc7\xb0\x6b\x3b\x03\x15\x1f\xe5\x6a\x2b\xc4\x61"
+  "\x8e\xff\x85\x75\x41\x67\x15\xf8\x77\xc4\x3a\x2f\x8d\x08\x3e\x6a"
+  "\x2a\x5c\x45\x79\x58\xdb\x92\xe8\x11\xb9\x3b\x35\xfc\xae\x10\x13"
+  "\x39\xee\x35\xde\x73\xf4\xf7\x71\xfc\xde\xbd\x42\xcc\x0d\xb9\x8b"
+  "\x0a\x8c\xb3\x3b\x15\xb3\xa6\xa8\xa8\x3f\xce\x4f\xea\x23\x7c\xcf"
+  "\x87\x63\x42\x69\x22\xf5\xa9\x4e\x6e\xb7\x90\xe7\x0e\xb4\x87\x72"
+  "\x98\xff\xe7\xc9\x18\x39\x81\xd4\xeb\x47\xe2\x2f\x69\x8c\x6e\xae"
+  "\xc3\x78\x75\xa7\x7d\x94\x6b\xe0\x3a\x22\x98\x67\xfa\x9a\xb8\x05"
+  "\x0d\xdc\x90\x7e\xb8\x4a\xa5\x47\x38\x46\x21\xfb\x20\x86\xdc\x8b"
+  "\xb3\x0c\x5c\x0d\x1c\xb8\x3d\xbe\x57\x29\xd2\x9b\xdb\x39\x26\x0c"
+  "\xb7\x17\x58\x53\xc4\x65\xf3\x0c\x7c\xbf\x2e\x2f\x97\xd7\x0a\xc1"
+  "\x73\x0b\x9f\x27\xd9\x47\x13\xb5\x06\x59\xa7\x2c\xde\x72\xb0\x36"
+  "\xc8\xf1\x3f\xff\x82\x36\xfe\xa3\x5b\x14\x91\xd6\x57\x94\x74\x8c"
+  "\xb9\x0e\xca\xb7\x49\xfd\x50\xd9\xfc\x1f\x9a\x98\xce\x31\x80\xff"
+  "\xc2\x71\x57\x61\x6b\x42\x6e\x17\x47\x9a\xcb\x3a\xf9\x2e\x24\x74"
+  "\xce\x62\x8e\x13\xda\xce\xb6\x06\xd6\x29\x1c\xbf\x22\x95\x75\x93"
+  "\x77\xc5\x44\x86\x11\x35\x3b\xc8\xdc\xec\xf8\x7a\xf1\xf4\xfd\xf4"
+  "\xe4\x44\x25\x3b\x4f\x4e\x34\xe6\x59\x3c\xe7\xc5\x9f\x4b\x3f\x99"
+  "\x9d\xa8\x73\x1f\x7f\xe6\x99\xd2\xc2\xa5\x0b\xf9\x27\xfb\x9a\xe5"
+  "\xd7\xa5\xc7\xae\x9d\x59\x0f\xab\x38\x06\x4f\x16\xf0\x3e\xd5\x4b"
+  "\x23\x8d\x73\xd6\x27\x6b\x8c\xbd\x32\xdd\x9f\xfb\x0e\xb6\xa9\xd9"
+  "\xf6\x44\x5e\xc3\x87\x65\x2c\x3a\x94\xf2\x99\x85\x4c\x89\xed\x2d"
+  "\x9a\x5f\x3a\xbf\xf8\x36\x3e\x51\x49\x4f\xd6\xce\xe1\xf8\x76\x9e"
+  "\xa2\xfe\x76\x94\x1e\x0c\x9a\xb8\xdc\xa6\x11\x25\x22\x2d\x94\xa9"
+  "\xee\xd2\x3e\x35\xd6\xd8\x03\x49\xee\x07\x77\xc8\x16\xad\xfc\xd8"
+  "\xcb\xe3\xe2\x5c\x4b\xa6\x77\x56\xb7\x9b\xd8\x46\x29\xc7\x33\xaf"
+  "\x0d\xa5\x5d\xa4\xc7\x13\x7a\xff\x6c\x3b\xe6\x99\xa7\x1c\xa2\xe2"
+  "\x90\xcd\x4f\x4f\x95\x0c\x36\x3f\xc5\xfa\x10\xb0\xcf\x59\x07\x3d"
+  "\x55\x3d\xe8\x79\xbf\xa7\xd5\xa3\xf4\xcc\x53\x9f\x37\xdb\x88\xc7"
+  "\xfd\xf9\xe3\xf4\xd4\x67\x66\x1b\xe6\x92\xd1\xf4\x0b\x3c\x7f\xce"
+  "\x75\x39\x2f\x6e\x9c\xbf\x7d\xaa\xde\x0c\x2e\x04\x37\xa6\x08\xf5"
+  "\x8f\xcc\xfa\x43\x2a\xfe\x4c\x22\x45\x9e\x86\xa5\x82\xc2\xc3\x86"
+  "\x9a\xc9\x3a\x22\xc3\x72\xe5\x15\x63\x6c\x77\xdc\x3e\x29\xd7\x59"
+  "\x5e\x06\xe9\x8d\x84\xad\x22\x36\xfe\x55\x4f\xe3\x03\xd7\xb9\x48"
+  "\xfa\x43\x54\xf4\x34\x26\xc3\x75\x93\x5b\x94\xf0\xdd\x63\x6d\xc4"
+  "\x70\xbf\x73\x39\x99\xde\xea\xf5\x9b\x38\x06\x3b\xdb\x20\x1c\xa3"
+  "\xff\x38\x15\x3f\xfb\x01\xd2\xd0\x7f\x87\xd8\x38\xdc\xaf\xce\x3b"
+  "\x8b\xdf\xd6\x36\x0f\xf7\x0f\xc0\x37\x13\xc3\x77\xbe\x4a\xa6\x5d"
+  "\xe5\x9d\x26\x9f\xf9\x76\xf2\xd9\x83\xf4\x01\x9e\x93\xd2\x12\x6d"
+  "\x0a\x8e\xfb\x0a\x18\x75\x6e\xcd\xe3\xfc\x92\x4c\xfa\xfd\x41\xd3"
+  "\x69\x2a\xfe\xfb\xde\x41\xea\xf1\x7d\xdd\xee\xf4\x3f\x69\x21\xf7"
+  "\xd3\x18\xff\xbc\x5d\xfa\x9c\x07\xdd\xfc\x34\xf8\xff\x29\x39\xdf"
+  "\x21\x3f\xda\x2d\x63\xfe\x3e\x3d\xdd\x28\x93\x7c\xde\xe3\x3d\x55"
+  "\xe1\xe5\x71\x15\x3d\x7f\xef\xe4\xbb\x09\x83\xf8\x31\x0c\xf3\x39"
+  "\x6e\xe2\x73\xa4\x21\x23\xc2\x94\xe1\x3c\x27\xfa\xa2\x6e\xca\x02"
+  "\xbb\x9b\xa2\x58\x5b\x46\x7a\x44\x41\x4b\xd7\x59\x19\x9b\x92\xf5"
+  "\xc7\x9b\x8b\x7e\x6f\xf2\x85\xcf\x78\x7d\x1b\x34\x6a\x85\xfd\xe1"
+  "\xab\x3d\xe3\x55\x31\x2c\xa3\xd4\x42\x7f\xa1\x16\xc7\xff\x74\xc9"
+  "\xbd\xa0\x5a\xe1\x62\x3a\xf7\xf5\x88\x39\x3e\xf3\xff\x20\xfe\x86"
+  "\x08\xeb\x42\xd0\xdd\x7e\x9a\x96\x5c\xfa\x3e\xe0\xbc\xf5\x9f\x80"
+  "\x25\x63\x5e\x4d\xa6\x0f\xf0\x1c\x72\x2f\x19\x63\xe8\xc9\xa4\xb1"
+  "\x42\x52\xbc\x9b\xac\x8e\x47\x4d\x1a\x74\x2e\xc7\x26\x83\xae\x9d"
+  "\xc8\xfd\xc2\x7b\x0e\xbf\xe3\x77\x1c\xff\x5a\xd7\x79\x77\x58\x23"
+  "\x8f\xb2\x0e\x2e\x60\xfd\x8a\xf4\x39\x75\x3d\x52\x27\xcf\xd6\xdf"
+  "\xf3\xf5\xf7\xe9\xfa\xfb\x54\xfd\x3d\x4f\x7f\x9f\xc4\xef\x4a\x77"
+  "\x2f\xd9\xdb\x3f\xaf\x98\x86\xb5\xe1\xdd\x6b\x8c\x05\xf0\x19\x6e"
+  "\x75\xac\x95\x73\x80\x8e\xc7\x44\x1d\xaf\x1c\xfd\xdd\xc0\xe7\xdb"
+  "\xd6\xc8\xda\xff\x26\x7c\x9e\xc9\x8b\xc7\xe7\x99\xd9\x31\xf8\x90"
+  "\xd5\x91\xf7\x75\xf0\xc9\xb4\x72\xac\xfb\x7f\x00\x1f\xc6\x85\xd3"
+  "\xd0\x7e\x5b\x02\x3e\x7e\x03\x9f\xa4\xfc\xb6\x42\x74\xf2\xfc\xb7"
+  "\xec\x9b\x32\x46\xef\x30\x9e\xdb\xea\x7a\x8d\x38\x73\x25\x63\x2e"
+  "\x14\x67\x0e\xb2\x60\x43\x19\xf4\xff\x99\x2e\x7d\x9e\x6f\x52\xf6"
+  "\x60\xc9\x1c\xc3\xf7\x07\x7d\xdd\x5d\xa5\xfa\xba\x67\x03\xc7\x5a"
+  "\x5b\x45\xdf\x72\x3a\x44\x27\xd6\x37\xff\xab\xd9\x1e\x88\x93\x81"
+  "\xe2\xd2\x65\xcb\x9e\xbe\xcd\x5e\x3c\x7f\xc9\x42\xfb\x35\x0b\xec"
+  "\xcb\x8a\x16\x2f\x2a\x5d\x18\x7f\x1e\x9e\xa9\x7f\x77\x44\xfa\xf9"
+  "\xb3\xcd\xcd\x32\xc0\xfc\xcf\x7a\x5b\xf9\x66\x3e\x7b\xb9\x70\x97"
+  "\xb8\x58\xd7\xef\x7c\x91\xcc\x7c\x06\x03\x7c\x3a\x0c\x1d\xaf\x62"
+  "\xeb\x53\x0a\xeb\x78\xa4\xc3\x86\x7b\xba\x2c\x26\x1d\x65\x9f\xcd"
+  "\x34\xd2\x18\xbe\xae\x9b\x86\x1d\xa7\x92\xb7\xb9\xcd\xa4\x34\xec"
+  "\x11\xf5\x98\x5f\x53\xb0\xde\xe2\xb5\xaf\xe0\xb8\x49\x7c\x7f\x0e"
+  "\xf5\x04\xf0\x91\x67\x8a\xfc\x6d\x1b\x65\xdb\x0b\xc6\x71\x39\xea"
+  "\xec\x42\x9a\x79\x33\xca\x62\xbd\xd0\xc9\xf5\x90\xbe\x89\xe3\x18"
+  "\x20\xdd\xa2\xc7\x83\xe2\xb4\xd7\x38\xce\x00\xd2\x32\x63\xd2\xf6"
+  "\x71\x0c\x73\xa4\xd9\x75\x78\x87\x98\xce\x78\xcf\xd3\xf7\x14\xb8"
+  "\xcc\x7f\xe8\xed\xba\x62\x71\xe6\x8f\x50\xdc\x74\x43\x8e\x7d\xce"
+  "\xfd\xdf\x9b\x7c\xfb\x13\xcf\x2c\x59\x94\x4e\x92\xec\xd9\x98\x2e"
+  "\x73\x6e\x72\x5c\x77\x9b\xbd\x64\xe1\xc2\xa5\xf6\x95\x0b\x97\x94"
+  "\xda\xe7\xaf\x9c\xbf\x2a\x9d\x16\x3d\xb3\xf4\x09\xbe\x25\xcf\xc3"
+  "\xb2\xac\xf0\x89\x45\x3f\x65\xa7\x05\x55\x3a\x3d\x6e\x1e\x9f\xc3"
+  "\xba\x4d\x8f\x2b\x71\xb8\x8a\x6d\x8d\x34\xdf\x6c\x3c\x73\xbc\x25"
+  "\x1b\x7e\x9b\xf1\xd7\x84\xbf\x46\xfc\x1d\xc5\x5f\xdb\x49\x5a\xc9"
+  "\xdf\x0e\x68\x08\xb9\x97\x6e\x30\xec\x89\x01\x1e\x5a\x5a\x63\xf0"
+  "\x10\xe6\xff\x06\x35\xbf\x2d\x3d\xdc\x1a\x91\xf2\xd3\xcf\x53\x55"
+  "\x3d\x03\x3c\xc5\xf1\x22\x5b\xd9\x27\x67\x05\xf2\xc1\xc3\xbc\x4e"
+  "\x07\xcd\xd3\x98\x6e\x27\x68\xf9\x7b\x75\x5b\xc5\x11\x8e\x75\x82"
+  "\xdf\x66\xf0\xcb\x11\x15\x5f\x64\xd9\x54\x94\xbb\x0a\x6d\x34\xa9"
+  "\x36\xf4\xf7\x51\xe2\x30\xef\x63\x1c\xd7\xdf\xd5\x9a\x7f\xf9\x03"
+  "\xfc\xcc\xbf\xfa\x59\x98\x95\xfd\x1b\xd5\xda\xd1\xc8\x5b\x76\x4a"
+  "\x6f\xc3\x0b\x5a\xb8\x76\xba\xa5\xcd\x2d\xd7\x58\xbc\x87\x66\x4d"
+  "\xb9\x43\x00\x9f\x33\x5a\xea\x23\xed\x32\x7e\xa1\xab\x17\x3a\xe2"
+  "\xe6\x9b\x7d\x0e\x59\x3e\x85\xf7\xd8\x66\x96\x08\x8d\x63\x4a\x6b"
+  "\xa9\x4f\xb5\x73\x3d\x61\xf1\xcd\xc6\xdc\x95\xa7\x6c\x01\x8e\x1b"
+  "\xb7\xec\xb0\x0e\x33\xcc\xb4\x3d\x49\x4b\x57\xa9\xf5\xda\x4a\xfd"
+  "\x7b\x03\xcb\x8e\x1a\xbe\x72\x90\xd1\x6c\xbc\x77\x18\x3a\xc0\x4f"
+  "\xcb\xf6\xea\x7e\x4d\x5e\xd5\xff\xd2\x31\xfa\x7b\xa3\x8e\x63\x0a"
+  "\xc7\xb2\x00\xfe\x6d\x3c\x76\x58\xfb\x36\xe2\xf9\x28\xe8\x73\x44"
+  "\xd1\xa7\x54\xda\x80\xb0\x6b\x38\xff\x28\x7f\xb3\x03\x79\x47\x55"
+  "\x9c\x88\x65\x73\xb8\xcf\x03\xbe\x8f\xb5\x79\xc0\xf5\x01\x3e\x33"
+  "\x84\x2c\x35\xfa\x7a\x58\x3e\x97\xcd\x06\xbc\xbd\x86\xde\x61\x3d"
+  "\x53\x18\x85\x9c\x4a\xbb\xbb\x74\xa3\xa1\x6f\x06\xf8\xa0\xb4\x3e"
+  "\x99\x2e\x49\x36\xee\xfa\xd8\xa4\x09\xf7\xb3\x1d\xc0\x69\xaf\x1c"
+  "\x03\x8e\xa7\xd9\xd3\x6f\xdf\xf7\x29\x1d\x59\x1a\xec\x5f\x8b\xe8"
+  "\x78\x70\x9c\x6e\x3f\xe3\xd6\x2b\xcf\x71\x75\xbd\xb1\x7c\x8c\xa1"
+  "\x37\x0c\x38\xd6\x14\xa1\x59\x1d\xf8\xcf\x73\xa8\x91\xf7\x90\x79"
+  "\xbe\x94\xf6\x08\xe0\x8c\x38\xa7\xee\x30\x69\x15\x87\x1a\xfd\x54"
+  "\x7a\x14\x3a\xc6\x2c\x6d\x4e\xf7\xb3\xa1\x01\x5d\xb4\xbc\x24\x16"
+  "\xa6\xb0\x1c\x6a\x64\xb8\xac\x8f\xd8\x26\x29\x8c\x9a\x39\x8e\x48"
+  "\xa3\x3e\xbf\x40\x07\x2f\xaf\x37\x70\x05\x0d\x0f\x1b\xf8\xea\xdf"
+  "\x4a\x3a\xec\xa7\xe5\xc0\xbd\x8f\x7d\x79\x9b\xd5\x78\xae\x94\xfa"
+  "\x06\x79\x7b\x50\xf7\x98\x9f\x9e\xcd\xd1\x65\xe8\x08\xea\xef\x39"
+  "\x58\x3e\x15\x65\x96\x87\x75\x7f\xd4\x36\x8c\xef\xd1\x01\xde\x5f"
+  "\x7a\x2a\x66\x3f\xe0\xa8\x1a\xc3\xdb\x5d\xc7\x69\x45\x6e\x4c\xba"
+  "\x3e\xb6\x07\x67\x23\xfd\x94\x5a\x5b\x1f\x72\xa8\xfa\x2b\x94\xef"
+  "\xae\x8e\x23\xeb\x02\xbe\x6f\xc5\x32\x2e\x69\x2f\xc7\x78\x45\x89"
+  "\x31\x5f\x00\x56\x83\xa4\xf9\x28\xd1\xc4\x74\x52\xf1\x1a\x96\x8e"
+  "\x52\x74\x5a\x51\x13\x47\x7b\x9e\x37\xd1\x0e\xd3\x69\xc4\x3a\xa1"
+  "\x8d\x08\xa6\x88\xc2\x55\x66\x19\x47\x93\x65\x9c\xcf\x5e\xc0\x1f"
+  "\xd2\xae\x52\x74\x5b\xd1\x6e\xd0\xcd\x18\x3b\xa6\x93\x9f\x56\x4c"
+  "\x67\xda\xc6\xf7\x71\x58\xdb\x71\xa3\xef\xa0\x29\xef\x07\xe3\xbd"
+  "\x4b\x97\x8b\x23\xde\xd1\xec\x0b\xb0\xf4\x8b\x83\xe6\xef\xd1\x41"
+  "\xc7\x44\x52\xb4\x5d\x99\xeb\xa7\x92\x9a\x98\x75\xc3\x61\xa6\x2f"
+  "\xcb\x0a\xf0\x6c\xd0\x63\x27\x1d\x56\xfe\x28\x4b\x39\x26\x6d\x83"
+  "\x94\xe5\x15\x32\xc6\x05\xc7\x5d\x6d\x63\x1a\xb1\x5e\x64\x59\x62"
+  "\x19\x60\x79\x52\x34\x5a\xb9\x25\x86\x46\xcd\x4c\x1f\x9d\x4e\x0d"
+  "\x09\xba\x7c\xa1\xbd\x78\xb2\xd2\xc5\xf6\xec\x6b\x16\x4c\x90\x81"
+  "\x4a\xec\x77\x4f\xb9\xcd\x3e\x7b\xf2\x35\x8e\xa2\x71\x33\xd5\xcf"
+  "\x94\xd9\xf9\xfc\x9b\x1e\xbf\xee\xb2\xa3\x9d\x48\xfc\xda\x6d\xad"
+  "\x47\xe9\x0f\x47\x96\x3f\x65\xa8\xdc\x7b\xe0\xb8\xa1\x55\x4b\x88"
+  "\xa2\xc0\x7b\xf3\x49\x8c\xa9\xe5\xd0\x1c\x8e\x53\x3b\x0b\x6b\xc6"
+  "\x99\xe7\xc4\x97\x75\xc8\xdb\x89\xf4\x11\x25\x1c\xeb\xfe\xaf\x42"
+  "\x4b\x3b\x34\x87\xd7\xf6\xa2\x62\xbf\x2d\x90\xd6\xd3\x88\x3f\x57"
+  "\x20\xed\xa3\xcc\x69\xd7\x39\x05\xe0\x16\x1b\xfd\xe2\x3d\x00\xd0"
+  "\x69\xce\x2c\x87\x88\x32\x8d\x0a\x1d\x1c\x4f\x1a\xb0\x53\x79\x0f"
+  "\xc0\x81\xfe\x17\xb7\xa9\xf5\xa5\x03\xfc\xbf\x74\xa2\xae\xcb\x66"
+  "\xe3\x9d\xe3\x5f\xcc\x96\xe3\xea\xb6\xc9\x38\xd4\xda\xfa\xeb\xef"
+  "\xc3\x7a\xc0\x65\xc0\x04\xac\xa1\xfa\x39\xb6\x84\xf7\x75\xfd\x22"
+  "\xb5\xca\x3f\xe4\x5b\x53\x54\x5c\x3f\xc8\xb8\xab\xce\xa4\x15\xf4"
+  "\xfb\x3d\x20\x6f\xc4\xba\x4c\xf6\x8b\x28\x00\xef\xb9\xb8\x8c\x91"
+  "\x57\xe5\xd6\xfc\x55\x26\x2d\x8c\x71\xcc\x54\xf6\x73\x17\xeb\x4f"
+  "\xac\x2d\x57\xf5\xef\xff\xcb\xf9\xd0\x44\x2e\xb5\x9e\x59\x25\xf7"
+  "\x7d\xce\xba\xcd\x04\x9d\xdd\x75\x75\x96\x5c\xa3\x84\x35\x77\x0a"
+  "\x29\x5f\xd4\x55\xf7\x1a\x3a\x96\xcf\x93\xac\xeb\x44\x80\xf7\x12"
+  "\xad\x11\x11\x90\x31\xd3\x79\xee\xa0\x93\xe4\x2b\x0b\xb9\x38\x56"
+  "\xab\xb4\x81\xd0\xae\x9a\x37\xa2\x6a\xde\x40\xfb\x81\xd4\xeb\xe7"
+  "\x61\x7e\x48\x39\x49\xab\xec\x8c\x3f\xd3\x86\xf7\xab\x35\xd0\xca"
+  "\xc7\xf3\x24\xd3\x27\xfd\xff\x39\xc2\x3e\x0d\xdc\x57\x6b\x04\x7d"
+  "\x8e\xed\x97\x49\xf3\x6f\x76\xa3\x5f\x26\xf4\xcb\x71\x8a\x65\x26"
+  "\xcc\xbe\x26\x90\xb7\x51\x32\x1e\xb1\x5c\x3f\xaf\xce\x8b\xed\x23"
+  "\xeb\x7f\xd5\x87\xd5\xf3\x93\xf5\x51\x98\xb8\x8f\x4c\x83\xd5\xb7"
+  "\xe8\xf2\x26\xf1\x64\xfd\xd1\x45\xab\x82\x23\xd6\xb1\x8f\xc7\xa1"
+  "\x39\xd0\x6f\x53\x78\x0c\x31\x7f\x56\x33\x9e\xc9\xc6\x8b\xe1\x29"
+  "\x58\x6b\x60\x43\xbb\xe6\x01\x97\x23\xc9\xe9\xbd\xfa\xd4\x85\xe9"
+  "\xbd\xfa\x43\xae\xcf\x78\xb0\xcf\x8b\x35\x82\xc5\x3a\xf8\x16\xeb"
+  "\x35\x4f\xb2\x76\x47\xac\xab\x67\xbc\x92\xe6\x09\x96\x17\x5d\x07"
+  "\x81\x0f\x05\xe4\x44\xb0\x4e\x0a\xb9\xd7\xf4\xef\x7f\x59\x53\xec"
+  "\xa9\x52\x3f\x98\x44\x75\x32\x18\xd6\x75\xd5\xec\x63\x32\x05\xed"
+  "\x27\xcd\xd7\xf8\x3b\x0c\x9e\x43\x79\xda\xfa\x7f\xb9\xda\x9a\x42"
+  "\x77\x04\x52\xff\x25\xdd\xea\x88\x8c\x65\x1a\x02\xa6\x03\x72\xbc"
+  "\x9c\xd7\xa9\x6a\xef\x62\x0d\xec\xff\x8d\x72\x5d\x1a\x48\x3b\x94"
+  "\xa7\x62\x85\xad\xc1\xfc\xf7\x52\xff\x1e\x6e\xc8\x5d\x66\xf6\x53"
+  "\xc7\x18\x25\x97\xdf\xda\x26\x2a\xff\x74\x4c\x73\x5b\x85\x7d\xb5"
+  "\x15\x76\x64\xd9\x0e\x4d\x70\x5c\xfe\x3f\x1d\x1b\xe0\x13\xe5\xff"
+  "\x62\xf0\x09\xea\x4f\x4d\xce\x03\x65\x0b\x2f\xcc\x03\x65\x72\x6f"
+  "\x96\xe9\xae\xd6\x2a\x65\x1b\x0d\x3b\x45\xac\xff\xd6\x36\x7b\xb9"
+  "\x6c\xdf\xae\xda\x66\x9a\xe4\xf1\xb9\x44\x3e\xe8\xe2\x42\xd9\x46"
+  "\x43\x0f\x30\xbf\x58\xa3\xfc\xcd\x02\x92\x3c\x8d\x3c\xd8\x3f\x25"
+  "\xd9\x6a\xbf\xf4\xa3\x1a\xf9\xdd\x3d\xf7\xca\xbd\x01\x67\xd1\x76"
+  "\xf6\x57\x0d\xa6\x1d\x6a\x42\x99\xb0\x9f\x3e\x90\x31\x49\x31\x07"
+  "\x37\x00\x46\xe3\x96\x91\x98\xa3\x95\xdf\x56\x06\xcb\x34\xc7\xf8"
+  "\x61\xb9\x46\x5a\x16\xf0\xe6\x78\x3f\x58\xef\xac\xcd\xe9\x9f\x97"
+  "\xdc\x79\xd0\x15\x42\xfa\xe9\x60\x5e\x1a\xd3\x0d\xda\xbd\x6c\xd2"
+  "\x76\xf7\x4c\xb0\x11\xf7\xb9\x67\xfd\xe8\xdd\xcf\xdf\x40\xe6\x3f"
+  "\xd8\x1e\xa7\x92\x9b\x28\x6b\xdd\xf7\xcc\xf4\xbf\x73\xc9\xc4\x74"
+  "\xf0\xd3\xda\x3c\x45\xbb\xb5\x2e\x63\x7c\xfc\xb4\x46\xee\x8b\xf2"
+  "\x5e\xe3\xac\x88\xf8\x52\xed\x87\xae\x85\xfe\x7b\xd2\xa6\xf2\x1d"
+  "\xe7\x9d\xff\xb3\x3d\x6f\x5f\xbc\xcc\xbe\xe0\x99\x95\x4b\xae\xba"
+  "\x2a\x6e\xad\x64\x96\x77\x58\xdc\x6b\x1b\xd4\x7c\xba\xb6\xd3\xc0"
+  "\x9b\xed\x12\xbc\xa3\xff\x2b\xcf\xdb\xb7\xcc\x2f\xd4\xdd\x94\x0b"
+  "\x73\x68\xe0\xf9\x46\xca\xbf\x31\xe6\xf5\x66\xca\xbf\xe9\xe6\xc2"
+  "\xfb\x16\xce\x5f\xb0\x2a\x26\xf5\x96\xd8\x7d\xbd\xaa\x6d\x68\x3b"
+  "\x75\xf4\x5d\xd0\x15\x29\x33\xd7\xf0\xdc\x52\xfe\x69\x79\x44\xfc"
+  "\x0d\xfa\x9a\xe3\x00\x17\xb6\x94\x46\xa8\x05\xba\x4c\x7c\x8b\x75"
+  "\xf8\x30\x75\x37\x0f\xf6\x14\x78\xcb\x8a\xbe\x07\x60\xd7\x9d\xe3"
+  "\xfd\x99\x13\xe4\x4c\x69\xad\xe1\x98\xbc\x1f\xd9\x94\x8d\x51\xde"
+  "\x84\xf4\x4b\xf1\xfb\x39\x7e\x87\xe2\xf7\xef\xf6\x25\x58\xf7\xb0"
+  "\x2f\xf4\x0a\xf6\x85\x2e\x97\xbe\x1e\x37\x04\x5d\x74\xc3\x52\xb6"
+  "\xd9\xcb\x4b\xd9\x06\xf1\x93\x93\xbf\x8b\x47\x5c\x16\x69\xef\xd9"
+  "\x9f\xa4\x1c\xfe\x15\xf2\x0c\xa9\xbc\x49\x54\x7c\x64\x13\xdb\x0b"
+  "\xf8\x1b\x57\x63\xd1\xe6\x55\xa9\x29\x9f\x51\xaa\x6d\x58\x28\xe4"
+  "\x76\xb2\xff\xd3\x51\xa6\xd3\x60\xdf\xd0\x64\x3a\x27\xda\x87\x03"
+  "\xb6\x61\x25\x49\xfb\x56\xb7\xe7\x76\xca\x79\xc1\x59\x1a\x63\xd3"
+  "\xf1\x99\x60\xba\xb2\x4f\x44\x54\xd9\xa7\xce\x2d\x86\x1c\xe0\xb9"
+  "\xde\xe0\xd3\xb8\xf8\x68\x4b\x4a\x17\x2e\x5d\xb8\xc0\x7e\xcd\xb2"
+  "\x74\x8a\x89\x8e\x56\xb4\x70\x89\x7d\xe9\xc2\x67\x97\x2f\x5c\x26"
+  "\x23\x9b\x71\x6e\xdc\x9c\x9f\x25\xd2\xff\x98\x6f\xdc\xdb\xb1\x8f"
+  "\x66\xfa\xba\x86\x70\x4c\x2d\x51\xf9\xc7\x23\x7c\xf6\x2b\x6d\x94"
+  "\x8c\xe1\xe1\xf8\xf5\xc6\xba\x1a\x65\xe7\x7d\x64\x51\x6b\x9d\x75"
+  "\xe3\xf9\xfd\x38\xb9\xf6\x0e\xc4\xef\x76\xcd\x07\x2d\x4d\x8a\x6e"
+  "\x16\x7f\xc8\xed\x2a\x30\xe8\xe6\xa7\x75\x7e\xdd\x96\xea\x92\xfa"
+  "\x03\x73\x2c\xf4\x5f\xdc\xfc\xaa\xbe\x9d\xe9\x62\xfd\x9b\x2a\xf7"
+  "\x7b\xd3\x3e\xca\xe0\xb6\x18\x26\xda\xf3\x63\x7c\x2c\xd0\x9b\xac"
+  "\xdf\x3c\x06\x3c\xb4\x39\x9d\xdb\xd3\xd7\x41\xdf\x38\x49\xeb\xec"
+  "\x52\x3f\x7a\x3e\xca\x60\x9d\xc2\x67\xa7\x5a\xc5\x47\xfa\xb7\xd2"
+  "\xd6\xf9\xd9\xc6\x94\x31\xe4\x01\x8b\xf7\x69\xa1\x1b\xc6\xf0\x77"
+  "\x56\x39\x4d\xc5\xf6\x72\xee\xe1\xbd\x61\xb4\x05\xf9\x58\x67\x1b"
+  "\xf0\x4d\x5f\xe7\x67\xbb\x93\xe1\xfa\xc9\x75\x8c\xe1\xa9\xd8\x65"
+  "\xeb\x26\x81\x77\xa6\x0e\xd8\x4f\xeb\x5c\x31\xeb\x32\xc6\x47\xe2"
+  "\x19\x04\x2e\x32\x4e\xa6\xf2\x1d\x94\xfd\x66\xfd\xb9\x45\xef\xbb"
+  "\xd1\x1f\xc0\x83\xfe\x73\xe6\x18\x67\xcf\x7e\xbd\xdf\x8c\x1f\xe3"
+  "\x1e\x8b\xb3\x8e\x6f\x23\xe3\x8b\x7a\xcd\x31\xb2\xcd\xfb\x32\x43"
+  "\x90\xd6\x3e\xe0\x93\xec\xb2\x27\xea\x8d\x67\x96\xd8\x8b\x17\x2f"
+  "\x79\xaa\x70\xe5\xfc\xa7\x16\x16\x2e\x2f\x19\x67\x5f\xbe\xe4\xf1"
+  "\xe2\x67\x9e\x78\x8a\xb9\x66\x59\xe9\xf2\x27\x9e\xb2\xb3\x66\x29"
+  "\x9c\x9a\x9f\x5f\x78\xd7\x03\xf7\x3f\x94\x4e\x77\xcd\x47\x1a\x56"
+  "\xfe\xf9\x39\xe3\x54\xd6\x7d\xd3\xa6\x3c\x58\x38\x65\xd6\x03\x33"
+  "\xe7\xc8\x4b\x0b\xfd\xf9\x53\x97\x24\x2f\x10\xc7\x87\x99\xe0\x25"
+  "\x33\xc6\x77\xc8\x71\x7a\x6e\xae\x8a\x77\xed\xde\x18\x1f\xef\xda"
+  "\x8d\xb5\xac\xdb\x8b\xbf\x63\x44\x1b\x32\xf1\x87\x75\xea\x73\xb3"
+  "\x15\x7f\xa5\xdd\x13\x72\xbb\x1b\x07\xf8\xeb\x39\x19\x53\x89\x7d"
+  "\x39\xd4\xfe\xac\x1b\xfa\xdf\xd9\x1e\x9b\x37\xb0\x9e\x74\x07\xfa"
+  "\xd7\x93\xfd\x3a\x65\xfd\x18\x63\x6d\x89\xb4\x4c\xac\x2b\xd3\x78"
+  "\x5d\xa9\xf6\x93\x9e\x7b\x54\xf2\xd4\xa0\xf2\x6d\x21\x63\x5d\xc9"
+  "\xb2\xcd\x67\xc5\x6a\xfd\xb1\xbe\x20\x56\xc6\x65\x8c\x45\x5d\xc6"
+  "\xb9\x9e\xdc\xbf\xcb\x18\xde\xc1\x7b\xda\xb0\x8f\xcd\xb0\x15\x30"
+  "\x7f\x85\x84\x18\x3e\xbc\x43\xc7\xa9\x86\xf7\xb8\xd9\x6e\xd6\xf9"
+  "\x69\xc4\x49\x5a\xff\x89\x70\xaf\xeb\x52\x6b\x4a\xf7\xb7\x59\xaf"
+  "\x8b\xf5\xa3\xef\x9a\x15\x95\xf1\xe8\xc0\xb3\xeb\x8f\x0c\xf0\xec"
+  "\x73\x73\x99\x17\x06\xd6\xb2\xeb\xe3\xf4\x7f\xb7\xfc\x56\xe3\xfa"
+  "\x88\x71\x5f\xbf\xf4\x2a\x32\x99\xaf\xaa\xa6\x2d\x26\x81\xf9\x68"
+  "\xfd\x1e\x6e\x83\xe9\xe9\x27\xf7\x61\x94\x35\x0f\xd0\x6f\x43\x4e"
+  "\x3f\xfd\xf4\x7d\x16\x63\x8f\x45\xe1\xfd\xdc\xa3\x83\xd1\x2a\x39"
+  "\x9d\x36\xb8\xbe\x92\x4e\x6e\x1a\xc2\x32\x69\xd0\xeb\x7c\x5a\x6d"
+  "\x68\x3e\x9f\x56\xcf\x5d\x1e\x43\xab\xc9\xe7\xd3\x6a\x43\x38\xe6"
+  "\xdc\x47\xdf\x47\x79\xee\x51\xa6\x19\xf3\x18\xfa\xbd\x07\x7c\xb6"
+  "\x7e\x80\x7e\xcf\x65\x9f\x4f\xbf\xe7\x26\x25\xa7\xdf\x86\xf6\xab"
+  "\xe3\xe1\x54\x24\x9b\x37\x46\xac\x33\xe9\xf7\x79\x9e\x7b\xbb\x79"
+  "\x8c\x5c\x93\x86\x5f\x32\x69\x45\x2f\xb9\xf1\x87\x5f\x5e\x47\x0c"
+  "\xd8\xe2\x22\xac\xd3\x77\x6f\x33\xd6\xbc\xbc\xaf\x74\x81\xb9\xe8"
+  "\x98\xb1\xe7\x81\xe7\x76\x5e\x3b\xcf\x8a\xde\x21\x38\x9d\xe9\xc9"
+  "\xdf\x8a\x02\xbf\xb7\x2b\xbb\xf4\x5f\xa9\x7f\xcf\xe5\xda\xa7\xf3"
+  "\x52\xd7\x91\xfd\x60\xed\x4d\x9c\x6e\x03\x0f\x49\xdf\x27\xf9\x2d"
+  "\xd5\x41\x60\x16\x46\xf3\x68\x10\xb8\xfd\xfc\x3f\xd8\x9d\xd6\x04"
+  "\x7d\x54\x34\x7f\xc9\x82\x67\x16\x2d\xfa\x6a\x55\x14\xeb\x3f\x56"
+  "\xed\xd6\x3c\x21\xfe\x56\xe2\xfa\x27\x57\xa3\x4d\xb6\xff\x2d\x6a"
+  "\xde\xfc\x57\xe8\xbf\x9f\x36\x29\x5b\xf2\x91\x4e\x75\x8f\xf7\xf9"
+  "\x89\x31\xfa\x19\x3c\xf2\x7c\x9e\x70\xff\x6b\xd9\xc0\x18\x3f\x9f"
+  "\x71\xfe\x18\x3f\x6f\x4f\x3e\xc6\xcf\x4f\xd5\x56\xf0\xbd\x8a\xe7"
+  "\xb1\xfe\x59\x22\x6d\x4d\x7e\xe7\xf3\x72\xac\x99\x3b\xb1\x5e\xee"
+  "\x9a\xb5\xca\x7b\x47\xe1\xaa\x14\xf6\x07\x97\xdf\xce\x88\xf4\x88"
+  "\x0e\x3e\xb3\xe6\xf3\x31\xfe\x76\x06\x7f\x33\x87\xbf\xa1\x2a\xcb"
+  "\xe0\xb9\xea\x04\xc9\xb5\x23\xf2\xed\x75\x27\xe4\x37\x7e\x61\x2b"
+  "\x3c\x5f\x6f\xd8\xd6\x56\x4c\x6f\x7c\xbf\x78\xb3\x1a\x8f\x76\x1e"
+  "\x0b\x6e\xaf\x70\x95\x57\xb5\xd1\xc3\xdf\xc7\x22\xab\xb2\x21\x9e"
+  "\x6f\xbf\xe0\xde\x7d\x5a\xcf\x60\xb1\x6a\x21\x2f\xae\x61\x2f\xa9"
+  "\xd8\xd3\xec\xd3\x18\x30\x7c\xea\xd8\xbf\x2e\xe4\xf6\xe4\x24\xfa"
+  "\xe7\x29\x1f\x13\xcf\x74\xc3\xb7\x07\xcf\x73\xfa\xd7\x03\xfc\xbd"
+  "\x15\xac\xe3\xec\xe5\xeb\x86\x9e\x26\xcf\xe5\x75\x83\xec\xa1\x1b"
+  "\xf7\x89\x75\x1f\xb8\x61\x80\x51\xd3\xef\x17\x84\x77\xd6\x17\x03"
+  "\xbe\x7d\x9e\x06\xc3\x37\x4c\xfa\x03\x62\xee\xe5\x6f\xba\x9c\x20"
+  "\xcf\x27\xf2\x1b\x32\x57\xf3\xfe\xb7\x27\xd8\x2c\xfd\x12\x3d\xfe"
+  "\x58\x5c\x74\x3c\x5e\xe3\x3d\x5a\xce\x8f\xc5\xc5\x31\x7f\xf9\xe2"
+  "\x09\x8e\x45\x8b\xed\x4f\x14\x2d\x2e\x29\x5c\x2c\x63\xc0\xca\xf0"
+  "\xb2\xa5\xab\x4a\xf8\x44\xe2\xba\xf4\x84\x39\x4c\xf7\x21\xec\xf7"
+  "\x95\x92\x7e\x84\x15\x0f\x81\x1e\x26\xe5\x47\x58\x99\xaf\xe6\xf5"
+  "\x8a\x05\xe7\xfb\xcc\x54\xf4\xfb\x7f\x81\xaf\x32\xb7\xa8\xd8\xf3"
+  "\xba\x9f\x0d\xf3\x5d\x45\x4d\x92\x3a\x7b\xfa\x7d\xc6\xd8\x77\xa9"
+  "\xaf\x40\xde\xf7\x90\x71\xc2\x5f\xe4\x71\xab\x20\x9f\x63\x1a\xc7"
+  "\x3a\xd5\xf9\xb9\xe2\x98\xc1\xcf\x86\xbf\x21\xc3\xe2\xfb\x26\x13"
+  "\xc2\xb1\xbe\x46\x95\x77\x62\xce\xb3\xf5\xf7\x63\x8d\x89\x18\xf7"
+  "\xa0\xc9\x0b\x3c\x2a\xed\x89\x78\x00\xbf\xab\x90\x9e\x3b\xe0\xcb"
+  "\x65\xf4\xb3\x32\x1f\xcf\xe7\xd9\xaa\x77\x4e\xcb\x87\x51\xba\x6c"
+  "\x61\x69\x3a\x4d\x99\x5f\x5c\xcc\x72\x3d\x7f\x61\xf1\xf2\xa5\xcf"
+  "\x2c\x2b\x5c\xbc\x64\x31\x52\xef\x5c\xc4\xa1\x79\x65\x91\xdb\xf4"
+  "\x1c\xfb\x92\x85\x0b\x17\xa8\x24\x7d\x18\xe2\xcf\x81\xd4\xd9\x7d"
+  "\x65\x93\x9f\x3c\xa5\x03\xf6\xd7\x0b\x59\xc2\x54\x59\x80\xbf\x27"
+  "\xa4\x4c\x4b\xdb\xa8\xd2\x1f\xbf\xee\xa9\x0c\x18\xfc\x20\xc7\xcf"
+  "\xc9\xfe\x3e\xcd\x6f\x77\x0b\x79\x6e\x82\x31\xdb\x38\x8d\xbf\x8f"
+  "\x8d\x35\xd9\x54\xb6\xf7\x07\xe0\xbc\xd0\xaf\xff\xf9\x7e\xfd\x7a"
+  "\xe5\x27\x60\xe6\x6f\x7a\xf2\x3d\x7b\xe4\x83\xff\x9f\x8f\x28\xfe"
+  "\x7f\xa1\x9f\xff\xbb\x4d\xa9\x58\xc3\xbd\xb0\xc0\xb0\xe7\xe3\x65"
+  "\xe6\x85\xb2\xf3\x65\x89\xfd\x3f\x5f\xd8\x62\xd0\xd6\x18\x67\xc5"
+  "\x5b\x1b\x6f\x34\xf6\x61\xeb\xf4\x38\xf1\xfc\xcc\x75\xd9\x56\x17"
+  "\x23\x86\xdf\xc1\xfe\xec\xc7\x69\xa3\xce\x2f\x2f\x1c\x8b\xf1\xcb"
+  "\xca\x3c\x49\x2f\x44\xd4\x38\xbd\x10\x34\xf0\xf3\xd3\x0b\xf2\x3c"
+  "\x80\x61\x28\xd9\xaf\x5c\xa5\x78\x67\xa3\xcd\xa0\x2d\xaf\x8b\xf1"
+  "\x9e\x3d\x60\x5b\x54\x1e\x96\x3e\x12\x2a\xce\x40\x1f\xf7\x1f\x70"
+  "\x76\x1b\x70\x50\x16\xfd\xb7\x34\x1b\xb4\x32\xca\xc4\xf2\xc4\x94"
+  "\xf9\x25\x58\xb4\x2e\x5e\xb4\x68\xe1\xd2\x65\x46\xec\xe5\xec\x67"
+  "\x8a\x17\xa8\x58\xcb\xb7\x61\xf8\x57\x42\x02\x27\x73\xb8\x66\xa4"
+  "\xaa\xc7\x04\x1b\x72\x1c\xef\x33\x48\xdf\x3d\xb9\x8e\xf9\xd9\x8d"
+  "\x3b\xf5\x35\xcd\x71\xda\xd4\xac\x7c\x5f\x36\x3d\xa7\xec\xc5\x4b"
+  "\x9e\x05\x4e\x9d\x86\xbd\xc8\xfb\x97\xdd\x64\x0f\xf3\x3d\x22\xf6"
+  "\x5f\xde\xb1\x55\x74\xf0\x7e\x65\xc8\xbd\x29\xc3\xf8\x3e\x17\xdb"
+  "\x22\x9b\xd4\xb7\xcd\x03\xde\x25\x1c\xdb\xfe\x67\xf7\x6a\x15\x87"
+  "\x72\x44\x7a\xc3\x3c\xd8\x3c\x19\x2c\x0b\xc3\xbb\x38\xee\x3d\xc7"
+  "\x03\xda\x54\xc0\xb6\x12\xeb\x17\x8e\x61\xdf\x41\x9b\xb2\xb1\xbe"
+  "\xc9\xf4\xd3\xcf\xe6\x04\xd2\x0e\xe5\x6c\x58\x4d\x16\x6e\x03\xba"
+  "\xc9\xdf\x5c\xcf\xb4\xdd\x54\xfa\x21\x74\x8f\xbe\xbf\xeb\xe7\x76"
+  "\xfc\xb4\x29\x4f\xdf\x4b\x9f\xaa\xef\x5d\x4e\x45\xb9\x5a\x3f\x0d"
+  "\xd7\x63\x82\xef\xfb\x9f\xdf\x75\x91\x83\xbf\xdb\xa7\x62\xf9\xb4"
+  "\x7a\x84\x67\x5f\x3b\x7f\x1b\x0f\xf6\x15\xd6\x10\x1b\x3b\x45\xc5"
+  "\xbe\x76\x15\x07\x9c\x79\x65\xf3\x9d\xca\xb7\x78\x63\x3b\xd3\x00"
+  "\x70\x67\xeb\x70\x67\x03\x2e\xc6\xff\x5b\xf3\x14\xaf\x6e\x26\xa3"
+  "\x0d\xcc\x29\x01\xd8\xa2\xc4\xf6\x28\xf0\xce\xc6\xdf\xb8\x2a\x79"
+  "\x3e\xed\xc7\xba\xc5\x2a\xd8\x6f\x68\xe0\x1b\x64\x9b\x73\x8d\xf9"
+  "\x85\xdb\xd6\x71\xe7\x7b\xe8\x16\xde\x3b\xd3\xdb\xca\xe7\xf5\xb5"
+  "\x01\x13\xef\xd9\x5a\xcf\xa9\x7a\xc0\xb4\x60\xae\x0c\xe8\xdf\x9e"
+  "\x1a\x57\x75\x96\x7d\xcc\xfc\x98\x0b\xaf\x14\x85\x91\x4c\x3e\xd7"
+  "\x19\x6e\x7c\xdb\xab\xee\x2c\xd3\x6b\xf3\xae\x81\xf3\x1a\xd4\x07"
+  "\xfd\x21\x0f\xae\x0e\xda\xfc\x1e\xb7\xcb\xb2\xc0\x63\xd9\x8b\xb1"
+  "\xe1\xef\xc4\x8b\x9e\x53\x7b\xb1\xce\x1f\x0e\x1a\x7c\xc6\x63\xc4"
+  "\x67\xac\xec\xfb\x85\x34\x2b\xc7\x22\x3f\x4e\x9b\x5b\x78\x7c\x18"
+  "\x17\xd0\x30\x37\x12\x2a\xf8\x21\xdf\x47\x65\x7d\xb8\xb6\x0c\x76"
+  "\xec\x22\xd6\x25\xd5\xf7\xf2\xba\x98\xbf\x21\xc3\xcf\xce\x05\x42"
+  "\x93\xe3\xbb\x9a\xc7\xb7\xfa\xde\xb5\x9d\x42\xfb\xd2\x4d\xe2\x70"
+  "\x90\xe8\x4b\x13\x45\xc2\xa6\x14\xc6\xdb\xe4\x3c\xc5\x77\x66\xeb"
+  "\xa1\x87\x3d\x84\x76\x2d\x9b\x57\x53\x26\xdf\x31\xe6\xef\xa3\xb4"
+  "\x06\x6b\xa9\xb5\xa4\x96\xfe\x14\xd9\x42\xde\x15\x1c\x33\xa2\x3a"
+  "\xfc\x91\x63\x0b\x9f\x5b\xa5\xe1\xf9\x5d\xfb\x83\xdc\x56\x55\xf5"
+  "\x47\x47\xff\x4c\x1f\x79\xff\x4c\xf6\x87\xe5\x7b\xfd\x91\x82\x3f"
+  "\xd1\x91\xbc\x3f\x91\xb3\x43\x68\xbc\x56\x2a\x7f\x9a\xdb\xf0\x00"
+  "\x56\x3d\xdf\xcd\xcd\xd4\xba\x6d\xe9\xe8\xbf\x99\xf7\xe4\x5b\x83"
+  "\x01\xf2\x2e\xf9\x2d\xe3\x78\xd5\xce\xb3\x64\xf1\x2e\xf9\xbd\x7c"
+  "\x56\x6b\x98\x53\xf5\xbe\x05\xed\x6c\xa7\x45\xf8\x2e\x32\x9f\xf3"
+  "\xc1\x6e\xd7\xaa\x18\xc7\xa8\xc2\x9b\xbf\xa5\x6e\xd4\x87\x1d\xa7"
+  "\xd7\xaf\xea\xe0\xfa\x3b\x98\x1e\xc0\xa9\x65\x8e\xa2\xc9\x91\x76"
+  "\xd0\xf4\x41\x9d\x3e\x05\xb1\xf4\xa9\xca\x63\xfa\x70\x1c\x4b\x0d"
+  "\xe3\x05\xdc\xf2\x40\x03\xcd\x68\x03\x38\x5b\xf4\x7d\x51\xcb\xe6"
+  "\xb3\x94\xe1\x5d\xc2\xdf\xc7\xaa\x7e\xc3\x3a\xdb\x6c\xd1\x7a\x4e"
+  "\xef\xad\x3a\x47\x66\x1e\x37\x3e\x0b\xa9\x92\xf9\x92\xe6\x1e\x1e"
+  "\xb3\x40\x5a\x73\x3d\xfe\x76\xe1\x6f\x37\xf3\x1d\x7e\xf7\x60\xbc"
+  "\x3c\xc0\xc1\x8e\xb1\xaa\xe7\x5f\xc5\x8b\xfb\xda\x39\x56\x83\xbe"
+  "\x2e\x19\x48\x87\x1c\x45\x84\xfc\x1e\x2d\x64\xa6\xda\xae\x41\x8e"
+  "\x78\x5f\x64\xe7\x8b\x94\xa1\xb9\x37\x16\xef\x80\xae\xab\xc5\x5c"
+  "\xba\x73\x24\x65\xf2\x5e\xe1\x36\xe9\x8b\xfe\xb3\xb1\x86\xee\xab"
+  "\x1c\xc5\xf7\xdb\xaa\x67\x9b\x78\x2f\xc5\x73\x68\xba\xce\xe7\xd3"
+  "\x51\x06\xfa\x7f\x94\xfe\xfd\xb1\x4d\xd2\xef\x98\x65\x7f\x30\x1b"
+  "\x1d\xf6\xe1\x11\xb1\xbd\x80\xf8\x4c\x25\x63\x9d\x08\x64\x74\x58"
+  "\x45\x6b\xf0\x88\xbc\xd7\xd8\x1a\x8c\xca\x33\x15\xe4\xa7\xcc\x0c"
+  "\x06\xac\xb0\x27\xdb\x98\x76\x46\x3a\x9f\xc7\xf0\x5e\xd5\xcc\xa0"
+  "\x08\xcc\x5a\x65\xe5\xef\x03\x8e\x91\xfb\xf1\x7a\x7a\xab\x0d\xb6"
+  "\xf8\xaa\x80\x15\x7d\x8f\xf4\xc3\xea\x2e\x48\x65\x79\x43\xd9\xac"
+  "\xfe\xb2\xdd\x05\x66\xfe\xee\x2d\xb7\x19\x93\x36\x64\x96\x03\x75"
+  "\x79\xac\xf4\x34\x65\x87\xbe\x98\xdd\xbf\x4e\xe3\x78\x8d\xdd\x98"
+  "\x37\x97\x15\xa4\x68\xdd\x05\xa6\x28\x60\x83\xf7\x33\xe5\x77\x0a"
+  "\x23\x01\xfd\xbb\x3f\x9d\x90\xdf\x76\x12\x9b\x46\x70\x39\x33\xc3"
+  "\xe5\xbb\xf1\xfc\xbd\x04\x31\x3c\xd3\x93\xdc\x8f\xad\xaf\xd1\x5b"
+  "\xfe\x30\xf8\xe9\xa5\x1c\x96\xe7\xa8\xe5\x0f\x93\xec\x4f\xb2\x7d"
+  "\xf2\xe2\xbf\x33\x3d\xa3\x90\xb1\x68\xda\x1f\x26\x4d\xe8\xa4\x94"
+  "\x72\xf0\xad\xda\xd7\x79\xf1\x8f\x1c\x0b\xc0\xa9\x09\xd8\x7c\x2f"
+  "\x36\x31\xdf\x58\xbb\xd8\xff\xec\x0f\x79\xd2\xe7\x2b\x3d\xb4\xd7"
+  "\x17\xee\xa4\x23\xae\xbf\xd0\x91\x88\xcf\xd5\x74\x36\x60\x56\xbe"
+  "\x5f\x66\x86\xfb\x29\xe7\x39\xc1\xab\x85\xd1\x7a\x1a\x6c\xbf\x9d"
+  "\xd7\x9c\x98\xc3\xfe\xaa\xd6\x5f\x2f\xe5\x18\x6b\xcd\xaf\xe8\x83"
+  "\x87\xe3\x09\x08\x61\x23\xad\xf2\x13\x3f\x70\x71\x8a\x50\x36\x4d"
+  "\x58\xcd\xfb\x5c\x2f\xcd\x83\xdd\x9f\xa7\xc3\x3d\xa3\xc3\xf5\x5c"
+  "\x08\x2e\xf3\xcc\x91\x1a\x79\xd6\x83\x3e\x7d\xd2\x16\x05\xec\x68"
+  "\xfa\xff\xc8\x84\x8e\x77\x3a\xbf\xe4\x7d\xd0\x2d\x2d\x68\xa7\xad"
+  "\x35\xd2\x46\x1c\x9b\x64\xa7\x86\xf9\xf1\x8c\x8d\x74\x3f\x37\xe7"
+  "\x69\x7a\xe9\x5d\x4d\x64\x67\x62\x0d\xcc\x7b\x6c\x4e\xd6\x71\xbc"
+  "\xbe\x2e\x8f\xd2\x50\x5f\xa9\x9f\xf8\x5e\x3d\x60\x7c\x78\x88\xcf"
+  "\x93\xa0\x27\xa2\xc2\x66\x7a\xaf\xc7\x4f\xec\xcb\x22\xef\xd9\xaf"
+  "\xff\xd6\xb6\x11\xeb\xe8\x0e\x61\xb2\x4a\x3f\x46\xad\xe2\x5c\x27"
+  "\xc6\xd6\x22\xf1\xa9\x3c\x54\x10\xe3\x53\x97\x7a\x9a\xb6\x4c\x66"
+  "\x9f\x3a\x61\x39\x34\xa6\x56\xee\xe5\xfd\x61\x52\xc8\xbd\xa5\xc8"
+  "\x4f\x2f\x3a\x98\x7f\x36\xb2\x7f\xbd\xd4\xb1\x5b\x3e\x09\xa4\x7d"
+  "\xbc\x57\xa8\xbb\x77\x29\xda\x8a\xe8\xde\xaa\x2f\xc8\xac\xe8\xb1"
+  "\x65\x5f\x6b\x57\xc8\x2b\x3c\x1f\xef\xe5\xbb\x53\x3a\x6c\x2b\x60"
+  "\x3f\x27\x2a\x3e\xde\xeb\xa7\x2d\x2a\x9e\xa1\x47\x3e\xd7\x73\x7e"
+  "\xa4\x2f\x1b\x73\xd9\x16\x8e\x79\x60\xf1\xd3\x4b\x87\x85\xfb\x4a"
+  "\x6f\xb7\xe5\xe3\xbd\xf7\xdb\xd8\xa6\xda\xd2\xe9\x4f\x79\xbf\x41"
+  "\xdf\x5b\x93\x31\x03\x12\xf7\xc4\xfa\xc7\x70\xbb\x2d\xdd\x07\x20"
+  "\x58\x23\x66\x9d\xa4\x57\x1e\xea\x75\x93\xa9\x0f\xb6\x60\xaf\x09"
+  "\x36\xff\xf6\x82\x8c\xcd\xa3\x29\x07\x79\xa3\x4f\xd2\xcb\x93\x23"
+  "\x26\xca\xc2\x5f\x66\xe0\x5b\x45\x69\x80\x9b\xc7\xfb\x8e\x2d\x67"
+  "\x79\xdf\xe8\xe5\x1d\xd2\x56\xdb\x46\x63\x35\xc0\xe3\x33\x94\xaa"
+  "\xd1\x34\x96\xf7\xfe\x90\x96\x5d\x18\x55\x67\x89\xc6\xfa\x7e\xfd"
+  "\x68\x1a\x17\xdf\xee\xcb\x7a\x2c\x80\x57\x0a\xf8\x77\x65\x80\xae"
+  "\x28\xb9\x9d\xbf\x27\xb9\xd5\x26\xdc\xa9\x42\x7c\xcb\x66\x52\xe7"
+  "\xfd\x5b\x53\xac\x35\x8a\xef\xe4\xd9\x19\xf8\x8d\xcf\x26\xf5\x73"
+  "\x9a\x14\x19\x2b\x21\xfd\x4f\x47\xf8\xfb\xbc\x31\x7b\xaf\x99\x12"
+  "\x0f\xfd\x9e\x73\x74\xfd\xf5\xf3\x18\x06\xe3\x53\x38\x5f\x9d\xf1"
+  "\xf0\x1d\x68\x3f\xbd\x2c\xe3\xf1\x6e\xdc\x46\x19\x2f\x6c\xa3\xcc"
+  "\x96\x45\xdc\xaf\xad\x39\x4a\x16\xcd\xc4\xf8\x6a\x1e\x96\x33\xf0"
+  "\x04\xf0\xe6\xf6\x98\x37\x5a\x23\x67\xbc\xce\x52\xa1\x79\x9f\x64"
+  "\x5b\x74\xeb\xb3\xde\xa5\x7b\x68\x16\xdf\x19\xe7\xfb\x62\x73\x29"
+  "\x50\x07\x78\x75\xa3\x29\x13\xb0\xd6\xfa\x8a\x89\xcf\x00\xae\xf6"
+  "\x2e\x6d\x60\xd8\x3f\xe3\xb9\x60\x13\xe8\xa3\xe6\x84\x57\xa6\xfa"
+  "\xc2\xed\xd4\x02\xf9\x9e\x59\x22\xa2\x0c\x07\x65\xfe\x28\xfb\xbb"
+  "\xdd\x66\x2f\x54\xf7\xd4\x65\x5f\xfb\xcf\xce\xf4\x7e\xf8\xce\x4a"
+  "\x78\xc7\x7c\xf3\x60\xe3\xe9\x7d\x32\x68\xad\xf8\xeb\x95\x6f\x7a"
+  "\x97\xee\x22\x1e\x1f\x2e\x8f\x77\x8b\xaf\x0b\x65\x4f\xc5\x8f\x0b"
+  "\x97\x41\xde\xad\x80\xfb\xfd\x81\xf3\x5f\x3e\x97\x1c\x28\x53\xbb"
+  "\x8d\xef\xc3\xbc\x5c\xb6\x1d\x34\x52\xfb\xe5\x5b\xdf\x60\x5c\xfd"
+  "\xb4\x75\x97\xaf\xf4\x2f\xc9\xfd\x3c\x21\xfb\xe0\xfb\x75\xad\xf2"
+  "\x1c\xec\x95\x97\x67\x46\x34\xa1\xf4\x59\xcd\x74\x0d\x7a\xc0\x8f"
+  "\x5f\xd6\x05\x52\x9f\xdc\xc0\xbe\x35\x35\xf7\x58\x53\xd4\xf8\x72"
+  "\x5f\xd8\x5e\x49\x36\xc6\x31\x67\x74\x99\x8c\xab\x31\xc6\xfc\x5d"
+  "\x3b\x8d\xcf\x59\x47\x83\xde\x7d\x36\x52\xfc\x27\xaa\x01\x57\xbf"
+  "\x1f\x71\xa8\x46\x9f\xcb\x6a\xba\xd3\xfe\x30\x5d\xac\xb1\x91\xe1"
+  "\x6f\x0b\xf9\x9d\x5a\xa8\x7c\x98\x6d\xac\xa3\xea\x4c\x42\x8f\xb7"
+  "\x57\x33\x5d\xaf\xbb\x45\xf9\x39\xd4\x58\x50\x7f\x4b\xd2\xfe\xa6"
+  "\x42\xef\xb8\xa1\xa6\xd1\x1f\xb6\x23\x05\x74\x15\xe6\x83\xa1\xbe"
+  "\x60\xaf\xfe\x4d\xc1\x9a\x43\xb0\xa9\x87\xf2\xdd\x14\x03\xb7\x8b"
+  "\x3b\x4f\xab\xa9\x56\x6b\x9b\x9a\x36\x63\xbf\x46\x58\x40\x63\xb7"
+  "\x55\xf0\x1d\x2e\xbe\x6b\x10\x4c\xeb\xf3\x06\x86\x0f\xd7\xbf\x31"
+  "\x5b\x13\x86\x9d\x2a\xf5\x6d\x61\x98\xbf\xe9\xde\xd3\xc8\xe7\xa5"
+  "\x58\x37\x0d\xe5\x3e\x87\xdc\xaf\x62\xfd\x53\x3c\x57\xcd\xe7\x35"
+  "\x83\xfa\x5e\xcb\x35\x93\xd1\x37\xf4\x49\xf6\x0d\x7d\x94\x7d\xd3"
+  "\xbf\xb9\x73\x82\x5e\x95\x77\xb7\x2f\xae\x3f\xaf\xce\x53\xb4\xed"
+  "\xf3\xf2\xf7\x44\x4f\xd0\xf6\xf1\xf2\xfe\x01\xc6\x44\x9d\x2d\xbc"
+  "\xda\x29\xd2\x5f\x48\xbf\x48\x98\x0d\x12\xe6\xc6\xe1\x81\x97\x39"
+  "\x3e\x9f\xfe\xdd\x2e\xc0\xbe\x5c\x6c\x1a\xce\xeb\xc9\x60\x37\xda"
+  "\xe3\xef\x1e\x0e\xe8\xa1\x6d\x35\x3c\x56\x37\xec\xa1\x3c\xc5\x87"
+  "\xdb\x36\xf1\xfe\xad\x5a\xe7\x6d\x9b\x04\xbe\x57\xeb\x93\x7e\xdf"
+  "\xec\x14\xe9\x9b\x1d\xab\x63\x2f\x0e\xc7\x6d\x52\x96\x45\xfa\xb9"
+  "\x6a\x3c\x8f\x63\x1f\x03\xc6\x77\x65\xc4\xd0\x7f\xdb\xc6\xb1\x9f"
+  "\x4f\xff\x19\xfb\x2a\xf0\x4a\xb9\xba\xbb\x0a\x7c\x8e\x18\x36\x8a"
+  "\xfc\x4e\x93\x5b\x1c\xe6\x72\xb3\x56\x9d\x91\x67\xf0\x55\xf2\x9e"
+  "\xf6\x49\xfd\x8e\xd3\xb6\xcf\xf4\xfd\x8c\x6c\xf6\x8b\x0f\xb9\xb7"
+  "\xa3\xed\x26\xe9\xcf\xc3\x34\xe0\xb6\x25\xee\xf2\x5b\x49\xdb\xc7"
+  "\x0e\x9c\xa5\x6c\x93\xe7\x13\xca\x57\x74\xfb\x24\x83\x47\xd0\xdf"
+  "\xa1\x2a\x5e\xe2\xab\x6f\x1c\x1c\x47\x92\x07\xba\x85\x2d\xfd\x3b"
+  "\xb5\xcc\x93\xdb\x17\xc4\xd2\x69\x56\x44\x73\x2a\x1d\xb4\x2d\x5f"
+  "\x48\x59\xdf\x96\xff\xd5\xf6\xc4\xf6\x77\x0d\x5b\x44\xd1\x39\x13"
+  "\xfa\x65\xe7\x06\x49\x6b\xcf\x3e\x07\xc7\xb2\x58\x53\xce\xf1\x78"
+  "\x6a\x57\x71\xac\xa3\x88\x67\x5f\x4d\x94\xef\xc3\x61\x9e\xd5\x3c"
+  "\xfb\x76\x9f\x28\x21\x53\x61\x09\x9f\x1f\x7d\xec\xe2\xf5\x95\x70"
+  "\xc2\x16\x48\x87\x7d\x02\x39\x5f\xbb\x98\xac\x8f\x16\x01\xb6\x33"
+  "\x3b\x8b\x63\x11\x71\x1c\x22\x8e\x27\x16\x75\x66\x8f\xc4\xf3\x28"
+  "\xd8\x73\x99\xc2\xb2\xcf\xc3\x3e\x28\x51\xb7\x80\x3e\x3e\xc6\xf1"
+  "\x90\x4c\xbe\x40\x98\xd6\x9e\x22\x0b\xc7\x3a\x8a\x54\x7c\x5c\xd3"
+  "\x1a\xfc\x54\xae\x2d\x46\x94\xc0\x9e\xd6\x68\x0c\x68\x6e\xd3\xd2"
+  "\x3e\x76\x61\x8e\xdf\xa0\xfa\x7d\x46\xa8\x7e\x2b\xbc\x19\x7f\xa5"
+  "\xe3\x0e\xec\x2e\x97\xb8\xef\xfc\x76\x04\xf0\x35\x4f\xd3\xae\xa8"
+  "\xa7\xa9\x5e\xdd\xa3\x3b\x42\xe5\xa5\xa2\xd3\x07\xdb\x98\x7d\x22"
+  "\xf9\x4e\x21\xfb\xb8\x70\x1f\xb9\x7f\xdc\xf6\x47\x67\x4f\xc9\xd8"
+  "\x4d\x11\xbc\x3b\x8b\xf5\x3a\x5d\xa8\xd3\x75\x84\x7a\x3d\x4d\xb2"
+  "\xef\xad\x41\x55\xb7\x50\x3e\x73\xfd\x18\x3a\xe8\x7d\xee\xa7\x03"
+  "\xfa\xce\xfd\xe3\xfe\x47\x98\x26\xa0\x81\xde\x57\x5b\x9f\xde\x4f"
+  "\xee\xe3\x9f\xc0\xa9\xdb\xd0\x4f\xf4\x55\xf6\xb3\x0f\xfd\x3c\x5c"
+  "\x44\x14\xae\xec\x6b\xfb\x32\xbd\xa9\x9e\xd7\x87\xce\x8f\x61\x47"
+  "\x97\x55\x13\xd6\x81\xe6\x5f\x97\x57\x9b\x2a\x61\x9b\x94\x07\xb0"
+  "\x1e\x0c\x88\x4e\xb6\xf7\x7d\x25\xf8\x8b\xd4\xca\x6f\xb1\x4a\xfb"
+  "\x98\xbf\x9b\xf9\x2c\xfa\xa4\x7d\x4e\xe5\x9d\xa2\x13\xb6\x69\xd8"
+  "\x17\x41\x99\x22\xf4\x1f\xeb\xc7\x13\x3a\xfe\x5c\x76\xed\x17\xaa"
+  "\x5f\xd6\x62\xca\xfa\xe0\x61\x8f\xc9\xd7\xee\x21\xa3\x2f\x8f\xa1"
+  "\x1c\xfa\x63\x03\x2c\x19\x37\x5e\x43\x3f\xb7\x03\xcf\x70\x4c\x9f"
+  "\x5a\xba\xc2\x80\xf9\x09\xa5\xcf\xa6\x94\x6d\xa7\xd1\x8f\xd3\x64"
+  "\xab\x2e\x87\xfd\x75\x1f\xdb\x8b\x3b\x1e\xb8\xa4\x80\xc0\xf7\xb5"
+  "\xea\x7b\x25\x2a\xb6\xca\xe5\x27\x69\xe7\x5a\x23\x7e\x8a\xc6\xf1"
+  "\xa7\xd2\x3e\xae\x65\x3e\x92\xb1\x54\x78\xce\x08\x81\x67\xd8\x3f"
+  "\x65\x25\xda\x08\x65\x8f\x92\xf8\xb8\x55\xfc\x15\xbc\xf3\x77\x74"
+  "\xb2\x78\x4f\x00\xf5\x6a\x04\x68\xc6\xf0\x61\xcf\x6d\xe0\x5f\xa6"
+  "\x61\xd2\xfb\x1b\x6f\x52\x2e\xda\x28\xe0\xb5\xef\xde\xf2\x80\xe9"
+  "\xb9\x37\x69\xdc\xc5\xe9\x94\x9d\x7b\x06\xd3\xdf\x7c\x16\xc0\xf0"
+  "\xd0\xb7\x91\x27\xa9\xee\x67\xf1\x32\x66\x97\xba\x4c\xe9\xc1\xba"
+  "\x02\xde\x7f\xbf\xb8\x76\xeb\x54\xdc\x26\xb7\xf0\x5c\x64\xbd\xb9"
+  "\x06\x1e\x78\xb6\x0d\x86\xfb\xc5\xd3\xa1\xae\x61\x30\x58\x9b\xb6"
+  "\xca\x58\x5a\xce\xcd\x5b\xd9\xc7\xaf\xaf\xf1\xa0\x8d\xe3\x1a\x63"
+  "\xee\xdc\x15\xa4\x65\x3b\xc8\xe2\x3c\xc5\x7b\x32\x33\xe8\x60\x6d"
+  "\x0e\xed\xc4\x9a\x5c\x74\x67\x8f\x7c\xe9\x2c\xfb\x13\x28\x1d\xc2"
+  "\x36\x29\xdf\x63\x13\xcb\xb2\x33\xab\xb6\x1a\x36\x7c\xfd\xda\xb2"
+  "\x73\x64\x52\xdf\x8d\xa8\x2f\x9b\x6a\x17\x91\x2d\x26\xad\xa8\x96"
+  "\x63\x0b\xa5\xf7\xb0\x9d\x52\x64\xc4\xda\x91\xb6\x8f\x03\x32\xd7"
+  "\x6d\x4b\xdf\xb4\x94\xc6\x71\x5c\x30\x6b\x40\xd9\x72\x6a\xbe\xae"
+  "\xdf\x03\xfc\x32\xf5\x33\xf4\x4c\x15\x7f\x67\x67\xb0\xee\x2c\xda"
+  "\x52\xf9\x9f\x46\xb1\x86\x91\x70\x97\xd2\xd8\xda\xb3\x94\xcd\x76"
+  "\x50\xe1\xe7\xca\x66\xe3\x75\xe1\x8c\x2e\xab\x88\xfe\xef\x6c\xda"
+  "\x71\x72\x20\x6e\x58\x60\x19\xc7\x1a\x13\xb6\xc1\xee\x08\x57\x8d"
+  "\x92\x7e\x34\x32\x06\x84\xfa\xae\x18\xd1\x96\x17\xc9\xcc\xdf\xd1"
+  "\xe4\xbd\x3c\xde\x1b\xe6\xbb\x34\x6a\x0e\x79\x2d\xdf\x88\xab\x34"
+  "\xe8\xd9\x9c\x47\xad\x77\xb4\xa1\x58\x7f\x05\x42\x5e\xef\x0a\x9e"
+  "\x33\x5e\xdb\xc2\xf7\x77\x06\xd6\x38\xaf\x2d\xe7\x3c\x4e\x63\xff"
+  "\xf2\x3c\x49\xcb\xd7\x9a\x78\xdd\xa3\xaf\x19\x3f\xb0\xf7\xa7\x29"
+  "\x1b\x86\xe7\x32\xc6\xa1\x4e\xed\x23\x8f\x00\x2e\xed\xc6\x7c\xc6"
+  "\xf3\xba\xfa\x86\xe7\x6b\x5d\xfe\x14\x6f\xd7\x05\xf0\xcb\xd4\xbf"
+  "\x81\x6b\xea\xe6\x58\x49\xee\x9f\x8f\x31\xe6\x37\xf9\x8d\x86\xf5"
+  "\xa3\xef\x5a\xb6\x8a\xc6\xdc\xff\x4d\x3e\xf3\x96\xf7\x30\x3a\xd5"
+  "\xbc\xfb\xf3\xa9\x03\x67\x54\x79\x92\xde\xf2\xfb\x6b\xbc\xc6\x30"
+  "\x61\x0e\x56\x31\xc2\xba\xd4\xfc\x6b\xdc\x31\xfe\xf9\xfc\x98\x76"
+  "\x36\xf4\xcf\xa3\x68\x83\x7d\x25\x18\xbe\xb2\x4d\x7e\x9e\xcb\x6d"
+  "\xf0\xda\x4a\xcd\xaf\x3f\xcf\xbd\x80\x2d\x96\xcd\xf4\xd5\xf4\xf5"
+  "\xa4\xaf\xeb\x6f\x8a\xbe\x0e\x4a\x9d\xb0\x85\x6c\x1f\x94\xfb\xcd"
+  "\xec\xa7\x6a\x5f\x4a\x56\xb4\xff\x09\xe7\x33\xaf\x7b\x6f\xe0\xbd"
+  "\xb8\xd7\x6f\xf4\xf1\xbc\xdd\x57\x90\x31\x93\xd7\xfa\xd2\x16\x7f"
+  "\xdd\x3e\x1e\xf5\x90\x36\xf2\xfd\xd3\x61\x73\xd5\x6a\x1a\xc7\xdf"
+  "\x39\x44\xba\xfc\x36\x58\xe0\x1b\x4f\x85\xbe\x93\x45\xb6\xef\x6c"
+  "\x61\x1f\xfb\xd7\xa7\xfb\x53\x3e\x50\xe7\x80\xdc\xfe\xe6\x11\x76"
+  "\x8e\x8f\xf6\x56\xaf\x7f\x88\x1a\xab\xd7\x3f\xc7\x7b\x76\xcc\xfb"
+  "\x3a\x63\x2f\xdf\x4f\xaf\x77\xc8\xf3\x40\xf6\x23\x5e\xc2\xf3\x75"
+  "\x4f\xfd\x80\xef\xcd\xeb\x9f\xeb\xb8\x7c\x7e\xb0\x84\x78\xaf\xfa"
+  "\xe8\xce\x51\xa2\x0d\xed\x41\x37\xbc\x16\xd6\xf7\x63\xda\x24\x5f"
+  "\xb1\xbd\xfb\xaf\xbc\x06\xfb\x1b\xc7\x66\x3d\xca\xf3\x44\xa1\x83"
+  "\xf2\x94\x0d\xdf\xd3\xa8\x81\x7f\x06\xfa\xff\xfa\xbd\xbc\xd7\x97"
+  "\x54\x27\xc2\xc4\x91\x75\x2a\xce\x85\xa5\x1f\xd7\xa6\x4c\x17\x7e"
+  "\x61\xdb\x87\xea\xf1\x9b\x01\x9e\xdb\x8b\xdf\x4c\xfc\xee\xc6\x6f"
+  "\x96\xd8\x34\x62\x1e\xf3\x25\xd6\xb0\x36\xac\x13\x2c\xdd\x69\xe7"
+  "\x02\x83\xdd\xff\x63\xda\xf8\x36\x3c\x48\xca\x2f\x75\xd7\xe1\x96"
+  "\x00\xec\x33\xac\x94\x97\x45\x44\xaf\xfd\x0a\xbe\x67\xb3\xeb\xb0"
+  "\x73\x07\xfb\x83\xec\x4a\xf8\xfe\xf9\xae\x26\xfc\x41\xd2\xde\x98"
+  "\x8d\x3f\xe8\x8c\x5d\x87\x07\xfe\xde\x68\x0a\xb9\x77\x1d\xf6\xd3"
+  "\x2e\x69\x63\x5d\x9c\x4e\xdc\xa5\xee\x52\xf0\xba\x28\xed\x13\xaf"
+  "\xea\xef\xf0\x36\xbc\x5b\xc4\xf0\x11\x99\x7a\x7f\xbd\x78\xcf\xb4"
+  "\x3b\x31\xaf\xa5\x81\x26\xa3\xd1\xe7\xe1\x99\x2e\xee\x2f\xe3\xdb"
+  "\x9d\x16\xaa\x8f\xbd\xfb\xc8\x30\xb9\xff\x81\xb4\x1e\x86\x47\xe2"
+  "\xda\xa7\xf3\x0c\x7a\xea\x74\xe2\x73\x23\x53\x37\x60\x28\x3b\x08"
+  "\xe5\x01\xc3\x28\xdf\x4f\xfb\xd1\xfc\xcd\x01\x8c\x29\xca\x61\x4d"
+  "\x6c\x31\xee\x55\x86\xdc\x6f\x34\x7c\x58\xac\xce\x0f\xb8\x6e\x30"
+  "\xa6\x2e\xc7\x1b\x48\x56\x1f\x6d\xca\xfa\x8c\xeb\x09\xda\xf5\x47"
+  "\xd5\xee\x1b\xbb\x07\x93\xa5\xf2\xab\x60\xdf\xd5\xfa\x39\x26\x01"
+  "\xdb\x43\x93\x7c\x63\x82\xe4\xab\xd5\x30\xe7\xf7\xb4\xe5\x95\x0b"
+  "\xef\x09\xfa\xb7\xc5\xad\xe1\xce\x8b\x9c\x0f\xff\x4d\x9e\xbf\x8b"
+  "\x5e\x17\xf9\xca\x6e\x92\xdf\xf7\x3d\x4d\xbf\x78\xd5\x17\x90\x71"
+  "\xb2\xf9\xf9\x39\xce\x67\xdf\x07\x9e\x1b\x38\x6e\x9c\xb1\xc6\xd6"
+  "\x50\x76\x27\xa7\x23\xcd\x17\x0c\xc8\xf8\x74\x03\xbe\xd9\xe7\xda"
+  "\x95\x4c\xfd\xe2\x5e\x79\xf7\x9d\xf1\x8d\xfc\xd0\xcb\x38\x6b\x9e"
+  "\x73\xed\xdc\x07\x27\xd6\x7f\xbe\x48\xc8\xcb\x32\x61\x5f\xc1\x7b"
+  "\x85\xbf\x18\x0f\xbe\x13\x5a\xc5\xb9\xf6\x8b\xec\x83\xbc\x3b\xe1"
+  "\x8c\x88\xd3\x81\xb4\x73\xbc\xc7\x6c\xaa\x2a\x1f\x62\x99\x52\x2b"
+  "\xbc\xdd\xe9\x3d\x90\xcb\x5f\xcc\xfe\xd0\x41\xff\x05\x3e\xfc\xc5"
+  "\x6c\xa3\xef\x3b\xf5\xbe\xa3\x2d\xb9\x7e\x9a\x50\xa3\xe2\xf1\xa1"
+  "\xcc\xa0\xdf\x79\xe6\x71\x66\x7b\x80\xfd\x46\x75\x5a\xb4\xf7\xcf"
+  "\x0d\x17\x87\x47\xfb\xd7\x68\xa3\x4f\xb5\xb1\x7b\xd2\x7f\xad\x8d"
+  "\xdd\x93\x2e\xd4\x06\x74\xc3\xb7\x4f\xd2\xee\xc3\x17\xbf\x76\xdc"
+  "\xbd\x45\xf2\x8a\xa7\xc7\xab\x74\xe6\x2f\x6f\x8d\x62\xfd\x16\xc9"
+  "\x18\xde\x26\xbf\xc5\x63\x22\x97\xcf\x1f\xa1\x88\xe7\x13\x6f\x8b"
+  "\xa3\x97\xbc\x2b\xfe\x4c\x1d\xf4\xef\x72\xdf\xa8\x05\x7a\x46\x6c"
+  "\x1c\x91\xd9\x57\x19\xb2\xf7\x99\x76\xdb\x98\xde\x3b\x38\xf6\x61"
+  "\x0c\x9f\xb5\x06\xff\x4c\xbe\x79\xbc\xbf\xda\xc6\xfb\xda\x99\x62"
+  "\xf8\xf0\x36\x0d\xba\x01\x36\x7a\x54\xd2\x03\xf6\x8b\x5a\x6f\xf5"
+  "\x35\xca\xf5\x56\x40\xde\xf9\x1b\x0e\xbb\x37\x43\xb8\x8b\xb3\x78"
+  "\xef\x3b\xda\x57\x60\x0f\xb9\x69\x36\xc7\x21\xe4\x7d\x67\x61\x39"
+  "\x34\x71\x56\x24\x55\xc8\xf5\x14\x6c\x7f\x8e\x47\xe8\x0b\xfa\x29"
+  "\x0a\x3b\xba\xb6\x87\xb2\x6a\x61\x7b\x42\x67\x67\xb2\x5e\xaf\xd3"
+  "\xe3\x11\x6e\xea\x19\x88\x47\xb8\x93\xf7\x7a\xda\xf1\xdc\x43\xe6"
+  "\x68\x45\x5f\xe3\xf6\x1e\x1a\xbb\x63\x05\x65\x6f\xe7\xbd\xbc\xbf"
+  "\x2b\xdb\x87\xed\x0a\x19\x9b\xf0\x99\x6c\xde\xcf\x1f\xb0\x7d\x56"
+  "\x72\xcc\xd4\x7e\xbd\x65\x96\x7b\x20\x17\x45\xef\x5f\xca\x79\x30"
+  "\xe2\x39\x17\x8e\x64\x64\xba\x40\xbb\x7a\x3f\xfd\x7b\x6e\x9f\xe9"
+  "\x17\x0d\xc9\xc6\xd6\xf0\x6d\xda\x12\x13\x4f\xf2\xc3\xb1\x4a\xbf"
+  "\x03\x56\xd9\x60\x3c\x11\xdd\x5e\x40\x13\xba\x28\x47\xf9\x2b\xa4"
+  "\x61\x4e\xfc\xa5\x9f\xcf\xcf\xcb\x9f\x26\x5b\x74\xfb\xdc\x14\xe7"
+  "\x6b\x94\xca\xdf\x7e\xe6\xbf\xf2\x2f\x44\xe7\x84\x62\xca\xe1\xf3"
+  "\x07\xf6\x69\xb0\xaf\x91\xe5\xdf\x1e\x5b\x46\x71\x67\x31\xd3\x95"
+  "\xb3\xd1\x6d\xf6\x7b\x96\x3c\xf1\xcc\xd3\x25\xf3\x4b\x17\x3f\xbe"
+  "\xb8\x78\x71\xe9\x2a\x19\x36\x60\x9c\xfc\xef\xee\x6b\x16\xcc\x91"
+  "\x87\xce\x31\xf6\xc5\xd8\x81\xfd\xb8\x5f\x2d\x8e\xf2\xfe\xc1\x45"
+  "\xd1\xeb\x57\x13\xf5\x73\xb4\xc0\x0e\x79\xae\xf4\xab\x32\xd8\x0c"
+  "\xd2\x67\x60\x93\x8a\x23\xd3\xa9\xfc\x18\x54\x39\x6d\xe3\x08\x8e"
+  "\xd1\x33\xe9\x38\xbd\x59\xc0\xe7\x21\x18\xab\xbd\xbe\xb2\x93\x04"
+  "\x3b\x64\x12\x9f\xb3\xb4\xf0\x5e\x86\xb4\x7d\x7f\xf5\x77\x39\x87"
+  "\x9d\x96\x31\x95\x76\x1d\xc7\x3b\xfb\xbd\x6b\xa2\x60\x7b\xf4\x19"
+  "\xdb\x2e\xed\x19\xdb\xbf\x09\x51\xb0\x4d\x3b\x53\xb4\x5d\x9c\x29"
+  "\xda\x26\x3c\xfb\x0e\x43\xc6\xc6\x9c\xa4\x5f\x45\x23\x6e\xfa\x06"
+  "\xfe\x86\x0d\xc4\x10\xd8\x73\x69\x7e\x87\xe8\xc3\x9f\x26\x3c\xfb"
+  "\x3b\x63\xce\xd0\x38\x4f\xde\xd9\x28\x59\xca\xbe\x54\x7b\xa6\x71"
+  "\xdb\xa2\x72\xff\xdf\x02\xce\xa2\x54\x94\x8f\x2a\x5c\xf6\xcc\xf7"
+  "\x6d\x38\x41\xea\xdc\x74\xcf\x3c\xaf\xdc\x33\xde\xf3\x25\xd7\xe3"
+  "\x73\x36\xb6\xa1\x65\x2c\x56\xd3\x2f\xbb\xd8\x0f\x8f\xed\xe7\x1d"
+  "\x23\x29\xb3\x7a\x24\x65\x84\xdc\x7b\x36\xf6\xfb\x58\x58\xd4\x9c"
+  "\xca\xf3\x1a\xc7\x0e\x86\xce\x09\xf1\x1c\xc9\x78\x30\x9f\x02\x66"
+  "\x23\x9f\xc1\xa9\x7b\x45\x7b\x9a\x61\x3f\xe6\x5e\xbc\xce\xdd\xd3"
+  "\x2c\xe7\x0f\x93\x53\x4c\xd8\x48\xf3\xe4\xf9\xa8\xf2\x39\x34\x43"
+  "\x2e\xb3\x55\x7f\xde\xbc\x51\x9e\x9f\xaf\x38\x55\x0f\xb9\x71\xd5"
+  "\xf5\x52\x86\xe6\x39\x34\x8e\xed\x98\x96\x32\x79\xae\x6c\x41\xbd"
+  "\xbd\x7c\xee\x2c\xef\xe5\xc9\x58\xd4\x7f\xa6\xba\x73\x64\xee\xa0"
+  "\x5f\xe7\xf1\x5e\xfb\x00\x6d\x7f\xfd\x32\x9f\xad\x88\xca\x86\x79"
+  "\xd6\x32\x93\x87\x61\x68\x3d\xa7\x73\x8d\x7a\x98\xbb\x87\x71\xbd"
+  "\xe3\xf4\xeb\x55\xb2\x1e\x97\x95\xdf\x31\xcc\x9c\x8b\x79\x2c\xcc"
+  "\xe5\x23\x78\xdf\xa9\x65\xce\x16\x90\xb7\xe8\x8a\xe8\x5e\xe4\xcd"
+  "\xd1\x3c\xa1\x7a\xa4\x15\xc8\x3d\x5e\xac\xcb\x65\xbc\x13\xcb\xc7"
+  "\x7b\x7d\xfe\xbf\x79\x25\x3e\xec\xc7\x5a\x0a\xdd\x24\xed\xbe\x5f"
+  "\xb7\xec\xfc\xbb\x8c\x91\x8d\x31\x7c\x73\x9e\xce\x37\xbb\x15\x7e"
+  "\x6f\xce\xef\xae\x6c\xaa\xef\xb6\xf4\xec\x0d\x9a\x2c\x74\xd0\x16"
+  "\x66\x9d\x38\xef\xa0\xad\x17\x6b\x87\x37\xb3\xfd\xa6\x77\xda\x94"
+  "\xcd\xa1\xea\xf1\xd9\x0e\xec\xd1\xae\x54\x5b\xe6\x74\xe4\x4f\x37"
+  "\xfc\x2b\xf8\xdb\xdf\x7c\xc6\xe3\xa7\x5f\xdb\x99\x6e\xe0\xfb\x06"
+  "\xb9\xcf\xbf\xfe\x91\x4e\xf4\x67\x28\xfb\xc0\x31\x9d\xf9\x7e\x83"
+  "\x15\xcf\x62\x85\xc8\xb5\x46\xf2\x4c\x75\xf2\x5e\xa3\xbc\x2f\x3f"
+  "\x51\x8f\xd9\x92\xa3\xc7\x70\x19\xc7\xef\xea\xbe\xfd\x9b\xfd\xf7"
+  "\xff\x39\x4e\x0d\xfb\x0e\x44\x75\xbf\x3a\x19\xbf\xe5\xac\x3a\x1f"
+  "\x65\xbf\x3a\xde\x1f\xe4\xfb\x81\x7c\x86\x89\x7a\x9d\xfd\x7e\x8e"
+  "\xf2\x5e\xcc\x9b\x61\x23\x6e\x4b\xc8\xfd\x96\xb9\xdf\x5f\x07\x7d"
+  "\xef\xf6\xf4\xec\x0e\x66\x8c\x98\x17\xf4\x9c\xc3\xda\xe6\x2d\x3b"
+  "\x74\x53\xc1\x05\xd7\x74\x1c\x8f\x76\x39\x99\xb4\xf4\x43\x05\x1c"
+  "\xcf\x82\xe3\x82\x29\x3f\xf9\xb7\xd6\xe9\xf7\xc7\x53\x4f\xd3\x5b"
+  "\x93\x07\xce\x12\xa3\xfa\x3e\xd8\x5b\xbb\x95\x1d\xf6\xd6\x6e\xb9"
+  "\x0f\x56\xd9\x53\xfd\xfa\xea\xb0\x69\xef\x6a\xbf\x49\xdd\x13\x78"
+  "\x0b\x16\xd8\x81\x36\xc3\x1f\x05\xe5\x38\x5e\x43\xd2\x98\x49\xc2"
+  "\xf3\x51\x96\x82\xb9\x57\xee\x61\x0c\xac\x6b\xf6\xaa\x73\xb2\xf5"
+  "\xa3\xe7\x69\x3c\x07\xa6\x7f\xd2\x26\x7d\x2b\x4a\xce\xf2\x7e\xd8"
+  "\x50\xb5\xc6\x52\x65\x74\xbf\xc8\xcb\x4e\xc6\xbf\x8f\xe4\x77\x45"
+  "\xb3\xbd\xe3\x8c\xbd\xf5\xcd\x26\xcd\x6f\x4d\x21\xe1\xac\x17\x41"
+  "\x8e\x07\x07\xfb\x2a\xe0\xc3\x9c\x8a\x36\x04\xf4\xc3\x30\xd4\x99"
+  "\xcf\xb4\x57\x32\xb4\xf7\x13\x89\x93\xfb\x0e\xe1\x64\xbb\x32\xc0"
+  "\xbe\x1d\x67\x09\xe5\x2e\x45\xb9\x4d\xcd\x65\x5d\xec\x9f\x62\xe7"
+  "\x38\x6b\x1d\x7a\xdb\x81\xb4\x8f\xb2\xbe\x93\x41\xf3\xd0\x26\xf8"
+  "\xc7\x3d\xef\xe2\x65\x7b\x6f\xfd\x85\x6c\x0c\x35\xe7\xe5\xd1\x60"
+  "\xeb\x14\x5e\x87\xde\x80\xf6\x67\x08\xc6\xff\xed\x4d\x11\x53\x98"
+  "\xfa\x4c\xc3\xc4\xbf\xb8\x1c\x14\x71\x0f\x13\xd1\xd5\x18\xaf\x6e"
+  "\x1b\xec\xd8\x23\xd4\x1a\x69\x96\xbe\x1f\x90\x59\x6b\x79\x50\x9c"
+  "\xf5\x45\x1a\xa4\x2f\xac\xba\x33\xfe\xf6\x73\xbe\xc8\x7b\xd4\x5a"
+  "\x12\x20\xd6\x0b\xc7\xe9\x6d\x19\xeb\xf4\x86\x12\x17\x71\x4c\x4f"
+  "\xe4\xe7\xa8\xf9\xef\xed\x8d\xfa\xef\x5c\xd1\x9d\x1d\x77\x66\x74"
+  "\xf7\xf2\x25\x4f\x94\x2e\x7e\x66\xc9\xf8\xfc\x85\x2b\x16\x16\xdb"
+  "\xef\x53\xae\x74\x71\xf3\x92\x65\x20\xf6\xf1\x6f\xe4\x5c\xc1\x36"
+  "\x08\xc7\x40\x96\xf1\x8f\xdd\x13\xa9\x3f\xf6\x31\xdb\x22\xff\x17"
+  "\xe2\x1f\x1b\x36\x06\xc7\x3e\x1e\xd8\xc3\x7e\xc7\xd6\x2f\x03\xda"
+  "\x07\x21\x7e\xe7\x7b\x92\x9a\xfb\x6d\xbe\xa3\x25\xbf\x25\x10\x72"
+  "\xff\xa6\x3a\x36\xee\x0f\xfb\xd8\xf1\xbe\x07\xd2\x77\x1b\x77\x52"
+  "\xc1\x8b\x98\x2b\x7e\xd3\x38\x70\x47\xe6\x37\xd0\xff\x6f\x9b\x95"
+  "\xfc\xca\xb2\x47\x8d\xb3\x5e\xfd\x1b\x53\xf2\x6c\x5a\x73\x9f\x0b"
+  "\xaa\xfd\x95\xdf\xfc\xc7\x4e\x6d\x98\x45\xed\xed\xbf\x43\xc6\xfd"
+  "\x2b\x25\x9b\x1f\xe8\xb2\xf9\x8e\xed\x42\xe7\xf1\x03\xb2\xf1\xce"
+  "\x9c\x01\xb9\xfe\xab\x51\x77\xce\x57\x9d\xe5\xeb\x76\xee\xe5\x27"
+  "\x69\xdf\x62\xde\x73\xc1\xf3\x95\x78\x96\xf7\x3e\x95\x2f\xfa\xbe"
+  "\xf1\xfa\x33\xda\xd8\x77\xb9\xfe\xfc\xad\x93\xd4\x10\xd5\x9f\x47"
+  "\xe3\xf9\x73\xfd\x19\x32\xdb\xd0\xa2\x3f\x67\xe1\x79\x9f\xfe\x0c"
+  "\x1d\xdf\xb0\x43\x7f\x1e\x85\xe7\xe7\xf4\xe7\x6f\xe2\xf9\x69\xfd"
+  "\x19\x32\xd8\xf0\x80\x7e\x2e\x6a\x39\x41\x0d\x77\x5e\xbc\xdd\xdd"
+  "\x90\xa1\xce\xde\x1a\xf2\xa1\xeb\xf5\xbb\x6a\xfd\x69\xf3\x30\x36"
+  "\x7b\x0d\xfa\x22\x9d\xf7\x06\x2d\x48\x77\xf8\xe9\xb5\x82\x81\xf4"
+  "\x77\x82\x7a\xf9\x6a\xe8\xb9\x71\x31\xe9\x9d\x7a\xfa\x6e\xd8\xf7"
+  "\x65\x31\xe9\xc7\xf4\x74\x2f\xca\x37\xc4\xa4\xb7\xe9\xe9\xed\x7e"
+  "\xda\xbe\x31\x26\xbd\x59\x4f\x0f\x18\x7e\x08\x7a\x7a\xa3\x4a\xdf"
+  "\xc7\x3e\x03\x93\x62\xd2\xf7\xe8\xe9\xd0\xff\xef\x8c\x8d\x49\x97"
+  "\x7a\xa5\x4a\xde\xdb\xb2\x8a\x83\x65\x2c\x5b\xfb\xa6\xfa\xe9\xd5"
+  "\x58\x9c\xb7\xe8\x75\xe7\xfa\xa9\x66\x4e\x4c\xba\x7e\xbf\x7a\x5f"
+  "\xa9\x9f\x3a\x62\xd3\x07\xb5\x7d\x53\x6a\x28\x69\x7c\x47\xde\x93"
+  "\xe4\x6f\xf2\x48\xff\x47\x69\x33\xee\x7f\x9b\xef\x74\x59\x77\x88"
+  "\xe3\xf6\x72\x21\x8e\xd3\xfe\x1a\xdd\xef\x6f\x0c\xfb\x61\xf1\xdd"
+  "\xb8\x0e\xda\xbf\x4e\xde\x97\xe2\x58\x86\x7c\x5f\x6e\x35\xdf\x97"
+  "\xdb\x2f\xe3\x3c\x4f\x70\xb8\x54\x9c\x43\xe5\x57\xda\x25\xd7\xe8"
+  "\xfa\xf9\x25\xca\x8c\xe7\x3d\x4b\x86\xc3\xfb\x78\xbe\xd2\x5e\xe9"
+  "\xeb\xc8\x6b\x24\x4e\xe3\xb5\xaa\xbc\x43\x15\xb3\x56\x52\x7a\x7f"
+  "\xff\xdb\x1a\xdf\x71\x77\xab\xf5\x7c\x95\x8a\x9f\xd9\xc5\x3e\x37"
+  "\xb1\x65\xfd\xb4\x5f\xae\x73\x53\x6d\x97\xbe\x1a\x72\xef\xaf\x1e"
+  "\xb8\xd7\xb3\xaf\x53\x4f\xaf\x41\xfa\xee\x98\xf4\xa3\x83\xeb\x76"
+  "\xe8\x3b\x4b\xc3\xee\xbe\x1e\x11\x8c\xf4\x88\xf0\xe6\xff\x04\xde"
+  "\x8b\xe4\x1d\x95\x2b\xa2\x9e\x86\x46\x3d\x5e\xc4\x67\x91\x15\x22"
+  "\x00\x9d\xcd\xf1\xf5\x2f\x99\x19\x0c\xd0\xcc\x92\x90\xd8\xf4\x38"
+  "\xfb\xcf\x9d\x93\xb1\x93\x9c\x5d\x1c\xcb\x97\x7d\xb2\x82\x7c\xee"
+  "\x93\xd1\x8a\x39\x6e\xe7\x22\xce\xff\x94\x66\x14\xc1\xf6\x2e\x8a"
+  "\xd2\x4e\xc0\xde\xf1\xb8\xe1\x0f\x79\x60\x7a\xbf\x8f\x22\x70\xe0"
+  "\xf6\x9c\xf2\xfb\x18\x07\x64\x6c\x0e\xfe\xee\x97\xd8\x94\x59\x2d"
+  "\x7e\xcf\xf6\xeb\x39\xbf\x75\x1d\x81\xaf\x0e\x6c\xc0\x73\x9b\xfc"
+  "\xe3\x3c\xa4\x0f\xd6\x27\x25\xcb\x07\xbc\x4a\xd7\xec\xcb\x56\xfa"
+  "\xe2\x80\x57\xfc\x9c\xef\xe8\x1c\xe0\xfb\x2f\x1e\xd8\xca\x49\xfd"
+  "\xaa\xd6\xee\x20\x53\x5f\x25\x6c\x93\xd3\x8d\x26\xa5\x9f\x1a\xf7"
+  "\x6a\x26\xcb\x3a\xde\x2f\x94\x31\xf2\x2b\x0f\x15\xed\x59\x12\x36"
+  "\xb5\xac\xee\xa0\x35\xdf\x24\xdb\xdc\x30\xfb\x7f\x37\xde\x38\xa2"
+  "\x94\xe3\x56\xf5\x54\xc3\xee\x34\xbd\x83\xfc\xf7\x97\x34\x9a\x22"
+  "\xd2\x5e\x69\xdc\x2b\xf7\x98\x3c\x87\x26\xf1\x1c\xe2\x6b\x8f\xb2"
+  "\xcd\x9c\x01\x9b\x79\x1c\xf4\xbf\x25\xba\xb2\x68\x64\x64\x59\xd1"
+  "\x25\x3b\x96\x52\x46\x74\x59\x76\xd6\x4b\x3d\x94\x6b\xcc\x3f\x58"
+  "\x9b\xe6\x88\x90\x2d\xbd\x0a\x73\x0a\xaf\x5d\x47\xa4\x64\xca\xb3"
+  "\x34\x7e\xd6\x4c\x3b\x6b\x76\xae\xb8\xf0\x77\x3e\xa2\x58\xb3\x72"
+  "\x8c\x6e\xc6\x25\x59\x5f\x37\x6e\xc3\x3a\x58\xbf\x53\x5a\xfe\x39"
+  "\x8d\x82\x9d\x6b\x1a\x71\x4e\x78\x4f\x16\x93\x89\xbf\x91\x50\xbe"
+  "\x50\xee\x0f\x0d\x69\x29\x8a\x90\xcf\xf1\x17\x2a\x5f\xca\x63\xf4"
+  "\xee\x10\xb6\xd3\xd8\x1f\x12\xe5\x33\x4f\xd2\xbb\x97\x5b\xc3\x98"
+  "\x33\xc2\xb0\x9d\x9f\xe4\xb5\xde\xbb\xd7\xf1\x7a\xd3\x4f\xef\x16"
+  "\xb3\x4f\xb8\x77\xe9\x5d\x9c\x36\xcd\xf9\xb9\xf4\x7d\xb0\xab\x7b"
+  "\xa7\xef\xda\xf9\xdd\xc9\x77\x5c\xd3\xff\x94\xff\x66\x6f\x78\x88"
+  "\xda\x83\x78\x57\xff\x66\x4a\x8f\x4b\xad\xb9\xde\xb5\x0f\xc6\xbb"
+  "\x9a\xa7\xf1\xb0\xe0\x38\xcb\xb5\x11\x9a\x19\x14\x7e\x79\x4e\xc9"
+  "\x77\xfb\x1d\x77\x78\x45\x4f\x35\xa9\xfb\x68\xef\x7e\xae\x55\x34"
+  "\x1e\x56\x31\x00\xdf\xfd\x94\x94\x8f\x11\xe6\xc8\xc6\x76\xb5\x47"
+  "\xdb\xd8\xa9\xf6\x2c\x1b\xc3\xeb\x47\xb3\x0f\xf2\xbb\x1d\xdd\x69"
+  "\xef\x42\xb7\xbd\xdb\xd8\x9d\xde\x5a\x3d\xf8\x7c\xb4\x2f\x6c\xbf"
+  "\x82\xb2\x78\xaf\x9c\xfd\x89\xeb\x94\x1f\x31\xda\xf8\x2d\xfb\x15"
+  "\x73\xde\x95\xc7\x4b\x28\x95\xf7\x17\x91\x76\xcb\x84\x5a\xb2\x03"
+  "\xd7\xe1\xc2\xd2\xb8\x5b\xfa\x6e\x79\x1a\x1b\x7d\x5d\xc2\xcb\x3e"
+  "\x83\xea\x4c\xe3\xb7\x41\x91\xd6\xb8\x5b\x2f\xff\x5c\x6b\x17\xfa"
+  "\x60\x69\x74\xf8\xc2\xa7\x74\x9b\xf0\xb7\xe0\xfd\x46\x87\xf0\x34"
+  "\x7a\xd4\x5d\xf1\xdf\x7e\x62\xe8\x55\xc5\xa3\xbf\xfd\xa3\xce\xeb"
+  "\x61\x45\xb7\xdf\x06\xf5\xf9\xea\x4a\x7e\xc6\xdc\x9d\xa3\xce\xe0"
+  "\x7f\xeb\x35\x6c\x64\xbf\x5e\x86\xeb\xe0\x59\x8f\x85\xf3\x5b\x3f"
+  "\xfa\xee\xd0\xf3\xe5\x77\x0b\xd0\x3f\xd0\xe3\xb7\x63\xb8\x5f\x83"
+  "\xe9\x56\x49\x8b\x32\x4a\x05\xce\x35\x9a\x8a\x8b\x1c\xf4\x05\xef"
+  "\xf0\xaa\xef\xf6\x35\xad\x95\x77\x66\xd1\x0e\xc6\xc7\xc4\x7a\x93"
+  "\xef\xf8\x32\xbc\x01\xfc\x7f\x37\xdf\xc0\x85\xdb\xe3\x3c\xf4\x95"
+  "\xe3\x28\x33\xad\xe4\x7a\x90\xc7\xf5\x44\x09\xef\x5d\x9c\x03\xcd"
+  "\xd8\x0f\xa8\x69\x23\xd3\x44\xd1\xac\x49\x7e\x1b\xac\xaa\x7f\x1c"
+  "\x9a\x1e\x8d\xa7\x87\x7a\xd7\x2c\xd0\x0d\x4b\xd9\x1f\xa4\x69\xa3"
+  "\x4e\xbf\x2e\xd5\x7e\xd3\xad\xfa\x5a\x1d\x79\xbf\xfb\x22\xa6\xee"
+  "\xb7\xfb\xcb\xaa\x6f\x44\x9a\xf8\x6c\x95\xf7\xda\x15\xbf\x36\x8d"
+  "\x19\xa8\xd7\x34\xa6\xf0\x0b\xb6\x91\x1b\x1c\xfc\x4d\x3f\xa6\x79"
+  "\xc8\xdd\x94\x33\x40\x6f\x05\x27\x49\x1b\x57\x18\x6d\xf8\xe9\x77"
+  "\x01\x03\x4f\x3c\xeb\x73\x70\x53\xe9\xc0\x98\xfc\x6e\x8b\x51\x8f"
+  "\xfd\xf7\xf1\x9e\xc7\xf7\x05\x93\xea\x41\x3e\xd3\x01\x76\xad\x91"
+  "\x3b\xbc\x92\x1f\xa9\xa9\x8b\x7d\x5d\x41\xd7\x1a\xc5\x43\x4d\x6d"
+  "\x6a\x2e\x6c\x92\xb1\x5b\xf8\xbc\xe4\x60\x98\x79\xa4\xa9\x03\x70"
+  "\xf5\xfd\xf2\xa6\xb0\x8e\x03\x78\xe4\xdd\x40\xe2\xba\xee\xae\xf9"
+  "\x0b\xe4\xc5\xd8\xf1\xcb\x4b\x12\xe3\x54\x5a\x06\xee\x40\xbe\x37"
+  "\x31\xe6\x0e\x69\xae\xa2\xf7\x7b\x2e\xac\x53\xff\x0f\x7b\xef\x03"
+  "\x17\x65\x95\xfd\x8f\xdf\x19\x46\x1d\x74\x80\xd1\x25\x1b\x0d\x6d"
+  "\x2a\xdc\x1d\x5b\x2c\x2a\xeb\x4b\xad\xed\x52\xe9\xe6\xf6\xd1\x70"
+  "\x5b\x6b\x69\x23\x85\xc2\xc2\x5d\xd4\x09\x91\xd0\x10\x10\x59\xbe"
+  "\x60\x03\x2a\xa0\x1f\x05\x44\xdb\x9f\xbb\x6b\x9f\xd5\x62\xfb\xb8"
+  "\xdf\x1f\x7d\xbe\x56\x94\xb0\x8b\xf2\x67\xb0\xb0\xb0\xc5\x1c\x09"
+  "\x0d\x5d\xb4\x11\x46\x19\x61\xe6\xb9\xbf\x73\xee\x7d\x1e\x66\x06"
+  "\x18\x18\x06\x34\xfb\xad\xbc\x5e\xcf\xeb\xe1\xb9\xcf\x9d\xfb\xdc"
+  "\x7b\xce\xfb\x9e\x73\xee\xbf\x73\x0e\xe6\xf1\x71\x6b\x79\x1e\xf0"
+  "\x2c\xed\x32\x99\x8a\xb1\x31\x52\xf5\xf4\x7c\xbd\x1e\xc6\xd2\xca"
+  "\xaa\x4c\x90\x17\xd9\xa9\x97\xc9\x78\xdc\x4b\x81\xf2\x06\xf7\x6a"
+  "\x52\x5f\x48\xcf\xa9\xca\x76\x9c\x53\xfb\xa8\x10\xc6\xb6\xfb\x72"
+  "\x61\x2c\x9b\x76\x81\x4c\xe5\x7b\x23\x3e\xf8\x00\xe7\x74\x68\x5a"
+  "\x64\x91\x90\x5d\x65\xc0\x33\x90\xf5\x30\x22\xa4\x69\x71\x45\x42"
+  "\x4e\x95\x01\xca\x2d\x49\x5b\x41\x26\xa1\x7e\xc3\xb9\x21\x8e\x99"
+  "\x8f\x12\xa1\xdc\x12\xf4\x4f\x26\xd0\x48\x19\x7c\xdf\x24\x28\x6b"
+  "\xd4\xb9\x02\x61\x7b\xbf\x01\x67\xf2\x16\xf2\xa1\x1f\x7c\xdf\x84"
+  "\x31\xfa\x70\x9e\xc7\x68\xb5\xa2\x0f\x05\x13\xbc\xf3\x87\x77\x0f"
+  "\xc3\x5d\x40\x5f\x65\xe8\x4b\x1a\xca\xd7\x60\xf9\xf0\x2d\x13\xaf"
+  "\x3b\xf3\x21\x62\x82\x7c\x2b\x30\x8f\xe4\x03\x4d\x48\x8b\xf4\xc1"
+  "\xf7\x78\xa6\xd6\x0e\xbf\x33\x02\xe7\xf9\x6f\x9a\x7a\x7f\x23\xda"
+  "\xcf\xd0\x97\x3f\x5a\x41\x37\xd5\xef\x83\xbc\xe5\xb8\xd7\x94\xdb"
+  "\xb2\x1f\xc5\x89\x7d\x1d\xec\xe3\x8f\x96\x8b\xff\xab\x7a\xf3\xa6"
+  "\x45\x92\xd4\xab\x44\xc3\xd6\x4b\x5f\xf7\x01\xd9\xfb\xd1\x36\xa0"
+  "\x03\xce\x2f\x34\xb1\xf1\xb8\xfc\x83\xde\x73\x39\xa5\xec\xec\xce"
+  "\x87\xbd\xfe\xdf\x80\x37\x95\x9b\xb9\xcf\xbc\x6a\x01\xff\x4f\x62"
+  "\x67\xe6\xc6\xe3\x38\x03\xe7\x0e\x96\xae\xdd\xd3\x7b\xc6\x81\x8f"
+  "\xc1\x3f\xd2\x3a\xf9\x8a\x62\xbf\xc5\xb1\x38\xfe\x36\xc2\x46\x2f"
+  "\x6f\x16\xf3\xe2\x6f\x23\xd6\x2e\xa5\xf8\x5b\xf8\xcd\xe2\xde\xdf"
+  "\xb8\x9c\x91\xf9\x88\x63\x1d\xda\x80\xff\x9b\xa1\xce\xe2\x1e\x24"
+  "\x2d\x5f\x3f\xfe\xc8\x20\xad\xd9\x9a\xc8\x07\xcd\xc8\xb7\x81\x7d"
+  "\x21\x7f\x74\xd0\xd5\x6f\x4f\x45\x26\xfa\x14\x82\xf4\x5a\xc9\xbf"
+  "\x0e\xfc\x0f\xdf\xfb\x80\xef\x83\x73\xf2\x9b\x95\xe7\xe4\x83\x2f"
+  "\xcd\x4c\xbf\x46\x7e\x40\xff\xf5\x01\x4b\x2f\x98\xe6\xd4\xa8\xf9"
+  "\x39\xa3\x8a\x35\x58\xcf\x16\x52\x31\x17\x9e\x03\xf8\xf9\xfe\x8a"
+  "\x07\x79\x3f\xfd\x3f\x9a\x08\xbb\x2d\xc0\x04\xdf\xc4\x33\x33\x4e"
+  "\xcf\x21\xd0\x6f\xd5\x90\x6f\x19\xf7\x51\x57\x11\xdc\x27\x3f\xbe"
+  "\x4f\xef\xf3\x1c\xde\xe7\x59\x6b\x01\x7c\xba\x5b\x9b\xce\x9d\xca"
+  "\xe6\xe5\xe6\xf8\x6f\x20\xfa\xb4\x73\xc4\x07\xf0\x7a\x06\xeb\x56"
+  "\xdf\xd6\x8e\x6d\x0a\xa0\x19\xa1\xc4\xd8\x66\xe3\x36\x1c\xe8\xce"
+  "\x96\x60\xc8\x73\x8e\x4c\xc6\x7d\xd3\x18\xd7\x00\xf2\x9f\xe7\x3e"
+  "\x98\x3f\xf1\x8b\x5a\x33\x9e\x08\xaf\x46\x4e\xa0\xf2\x08\xd4\x93"
+  "\xca\x03\xdd\xa6\x31\xb8\x4e\x94\xba\x93\x04\xa1\x7f\x1b\xe8\x9f"
+  "\xad\x18\xf3\x0a\x63\x90\xff\x3f\xdd\x6d\x63\x8c\xb6\x2f\x89\xfe"
+  "\xb7\x44\x7e\x9e\x7c\x42\x14\x29\x44\xb1\xf9\x2c\x51\x03\x5f\x6d"
+  "\x87\x6d\x61\x44\x3a\x9f\x5f\x32\x89\x9f\x2d\x2e\x01\x39\xb6\x5a"
+  "\x43\xad\x5d\x19\x1f\x83\xfd\xff\x96\x52\x1a\xcb\x1a\x78\xec\x02"
+  "\xc5\x59\xf2\xf1\x11\xb9\xe8\x8b\x80\xd3\xf6\xe3\x9d\xfc\x9c\x52"
+  "\xe0\xad\xf0\x1b\x27\xfb\xf7\x93\x20\x4e\xc3\x9a\xd9\x5c\xc6\x7c"
+  "\x12\x74\x38\x96\x60\xcc\x1a\x5c\xe3\x0f\x84\xbc\x87\x7a\xd7\xf8"
+  "\xd9\xfc\xd0\x27\xa0\xd3\x6a\x66\x73\x1b\xb8\x66\xf6\x52\xbb\x52"
+  "\x94\x03\x98\x7e\x30\x19\x7f\x0b\xbf\x0b\xb0\xb0\xb9\x9c\x8f\xad"
+  "\x0e\xac\x7d\x5c\x81\xb2\x15\xda\xa4\x82\xff\x67\x63\xbb\x90\x26"
+  "\x90\x4f\x01\xcf\x61\x87\xf7\xba\xf1\x55\xaa\xfc\x9b\xce\xc6\xe6"
+  "\x1a\xae\x64\x03\x9e\x2e\x00\x0f\x7e\x80\xfe\x88\x8c\xf0\x9d\xba"
+  "\xd2\x6e\x52\xa7\xe9\x24\xf5\xf0\x3f\xee\xe5\xad\xf8\xed\xd7\xa4"
+  "\x55\x3b\xb0\x5c\x07\xdd\xb0\x0f\xea\x5c\x8e\x65\x81\xac\x6c\xc3"
+  "\xfd\x4f\x46\x18\x11\xd5\x9b\x31\xd6\x16\x61\x65\xd4\x09\x6d\xa4"
+  "\x2e\x19\xc6\x33\x06\xf5\x96\xfa\xd2\x2f\x49\xbd\xe6\x33\xf6\x1d"
+  "\xb4\xbd\x2a\x12\x3a\x07\x2b\xbb\x1a\xca\x6e\x12\xcb\x6e\x87\xb2"
+  "\x03\xdd\x96\x9d\x7d\xd9\x34\xcc\xb2\x3d\xaf\x77\xf6\xe5\x86\xe1"
+  "\x94\x0d\xf2\x32\xc4\xa8\xe1\xe7\xa2\x52\xa7\x10\x3f\xfb\x15\xf4"
+  "\x45\x79\x3b\xe5\xfb\x49\x0f\x5f\x62\x67\xa7\x32\xd8\x7e\x5d\x1d"
+  "\x3b\x43\x75\x91\xb0\x3d\x81\xfc\xdc\xd4\x19\x82\xfb\x09\xba\x32"
+  "\x0e\x37\x3b\xc6\x24\xbd\xeb\x3c\x60\x13\x56\xf2\x3d\x9a\xd9\x55"
+  "\x3a\x8e\xab\xc3\x7f\xc3\xb2\x06\xae\xc7\xdf\xe7\xf0\xfd\xa7\x95"
+  "\x0f\x4b\xf3\x1c\x9d\xbe\x7f\x9f\x23\x96\xa5\xed\x3b\x7f\x26\x05"
+  "\xb9\x5c\x96\x9c\x28\xc5\xcb\x4c\x14\x8f\x6f\x3e\xb3\xec\xe5\x65"
+  "\xcb\x93\x96\xc5\x6a\x17\xaf\x49\x58\x39\x6b\xd5\x2b\xaf\x68\x17"
+  "\x2e\x5b\xbd\x3a\xe6\xd5\x65\xe3\xc9\xe2\x84\x98\x95\xab\x97\xe3"
+  "\x1c\x97\x56\x3b\xf7\x81\xa5\x71\xab\x12\x67\xfd\x74\x6e\x68\x9f"
+  "\x39\x2e\x3c\xeb\xd7\x8c\xb6\x6e\xda\x7a\xe8\x9f\x76\x32\x11\x7d"
+  "\xcb\x04\xac\xa5\x15\x6f\xc0\x38\x0b\xf0\x77\x1e\xf5\x01\xf4\xdb"
+  "\xd3\x68\x83\xa3\x5f\x3b\x90\xdf\xb5\xc5\xdb\x69\xc3\x59\xf2\xf9"
+  "\x5f\xc1\x7e\x6b\xda\xcd\x7d\xb4\x35\xc3\xd8\xd7\xcc\x63\xba\x7d"
+  "\x8e\x7b\x59\x2b\xdf\x84\x34\xb3\x6f\xcd\xec\xcd\x5f\x11\x05\xe8"
+  "\x19\xb0\xff\xf1\x1c\xdb\x38\x6a\x98\x4c\x2b\xe9\xd7\x1a\x22\xfa"
+  "\x9d\x96\x1b\x4d\x56\x5c\x0f\x57\x46\xd8\xd2\x28\xca\x53\xde\xb7"
+  "\xaa\x16\x72\xba\x94\x57\xf3\x7d\xb9\x9f\xaf\xc0\xb1\xc2\x46\x16"
+  "\x73\xaf\x0a\xfa\x7f\xf9\x21\x87\x9c\xae\x4f\x16\x6d\x34\x5c\xaf"
+  "\x7e\xbd\x05\x9e\xb9\xef\x8b\xaa\x6c\xd7\xbd\x0e\xff\x00\xfd\xf7"
+  "\x69\x09\xbf\xf0\x37\x9f\x1e\xe2\x17\xfe\xef\x7c\x7d\xbe\x88\x5f"
+  "\x7d\xd3\x47\x7a\x49\xdf\xf7\xf6\xf7\xc6\xd0\xc1\x2f\x4f\xbe\xcf"
+  "\xda\xfd\x1d\xb6\x7f\x24\xbf\x37\x86\x0d\x76\x21\xde\x00\x5b\xcd"
+  "\x6f\x7e\x45\x94\x80\xcf\xc2\xdc\x97\x00\xd3\x27\x89\x26\xc5\x46"
+  "\x5b\xd3\x5e\x24\x41\xa9\xe7\x08\xc6\x3c\x6b\x4b\x4c\xa6\xad\xa9"
+  "\x57\xd0\xf6\x33\xfa\x02\x7e\xcb\xf3\x5a\x88\x2a\xb7\x85\xa8\xeb"
+  "\x13\x31\xf6\x29\xfa\x9f\x82\xd2\xc0\xd2\x35\xc2\x73\x6d\x92\x95"
+  "\xd4\x98\x2f\xe1\xfe\xa0\x8a\xfa\x68\x90\x3b\xcd\x18\x37\x96\x56"
+  "\xaa\xa2\x49\x60\xc9\x64\x7a\x88\x66\xc4\x2b\xa8\xfc\x77\x16\x48"
+  "\x6b\x7c\x57\x08\x1f\xf3\xee\xba\xea\x31\x18\x1f\xae\x85\x54\xfb"
+  "\x89\xd8\x5c\xcb\xcf\xe4\xd4\xb3\xf9\x0a\xe8\x27\x8d\x7c\xfe\xba"
+  "\xfe\x32\xd7\xe7\xf5\x55\xe2\xbc\x0e\xfe\xcf\x6c\x32\x68\x47\x39"
+  "\xc6\x88\xc4\x32\xdf\x11\xca\x59\x8c\xc8\x77\xd7\x85\x8f\x49\x89"
+  "\x21\xf2\x7a\xd3\x79\x72\x18\xe4\x20\xc6\x1b\x84\x7e\xb7\x1f\xfa"
+  "\x59\xd9\xae\xc9\x74\x0b\xd4\xcf\x50\x3a\x99\x66\x43\x9d\xf6\x75"
+  "\x65\x54\xa7\x80\xce\xd2\x8b\xeb\x1b\x15\xd0\x2f\xf6\xe7\x42\x9e"
+  "\x88\x35\xe4\xf6\x5c\xc8\x97\x07\xf9\xd0\x1e\xe5\xf5\xab\x7d\x0c"
+  "\x68\x70\x10\xbe\xd9\xa0\x5d\x82\xcf\x47\xd8\xdc\x10\x7e\x1b\xda"
+  "\xa1\x6d\x21\x47\x6a\x41\xb7\x29\xf0\x1b\xd2\x77\xa1\x7c\x90\x7f"
+  "\x87\x75\xe2\xfa\xea\x16\x5e\xce\x11\x25\xef\xaf\x55\xfb\x37\x3b"
+  "\x62\x78\xee\xcf\x5d\x07\x3a\xbd\x9b\xf9\x65\x2c\xc4\x79\x0d\xb4"
+  "\x31\x98\x5d\x61\x27\x01\x7c\x1c\x0e\xb6\x45\x1c\xc8\x01\xb0\x27"
+  "\xd8\x5e\x62\xb0\x25\xa0\x2e\x85\x18\x47\x13\xdf\xc3\xf8\xe8\x20"
+  "\xe8\xe5\x32\xb4\x03\x96\x5c\x7e\x8a\xe0\x5c\x36\xd8\x03\x8a\xd5"
+  "\x51\xd4\xca\xe3\x7d\x1c\x89\x93\x6c\x01\x94\x41\xa8\xff\x73\x93"
+  "\x88\xa2\x07\x78\x08\x18\xa8\x06\xdb\x62\xe2\x79\x72\x64\xaf\x48"
+  "\xfb\x6a\xa6\xf3\x93\x98\x1f\x61\x1f\x2e\xa3\x8f\xfc\x15\xda\xa7"
+  "\x82\x6f\x54\x9b\xc8\xe7\x2c\xc6\x37\x97\x31\x47\x2a\x24\x3d\x8e"
+  "\x63\x4b\x13\x94\x41\x41\x96\x89\xef\xa0\xfd\x15\x85\xd2\x37\xe1"
+  "\x9d\x5e\xa4\x59\x2d\xd0\x0c\xca\x3c\xca\xce\x93\x83\xcd\x35\x5b"
+  "\xa4\x4d\x0a\xda\x15\xfc\xb7\x47\x35\x52\xb9\x38\xfe\x15\xc0\xae"
+  "\x40\x7a\x21\x9d\xa0\x9c\x14\x51\x8e\x35\x72\xfb\xa5\x76\xa6\xb8"
+  "\xae\xbd\x05\x78\x9d\xe9\xa0\xff\xd1\x28\x67\xfa\xc3\xef\x33\xf9"
+  "\x77\x6a\x8e\x3b\xf1\x0e\xc6\x20\x35\xfb\x71\x3e\x12\xea\x78\x88"
+  "\xcf\xa5\x1c\xdd\x86\xfe\xbb\xd0\x5f\x30\xd0\xf8\x90\x01\x7d\xd3"
+  "\x82\x6c\xde\xf8\x15\x11\xe3\xb7\xd6\x6c\xe3\xf6\x29\xd4\x9b\xc5"
+  "\x38\xac\x99\x86\xcf\xad\x50\x2f\x1e\xdf\xb0\x66\x0c\x8f\x6f\x78"
+  "\xd4\xee\x1c\xb3\xd5\x11\xaf\xf5\xa8\xc5\xb1\x9f\xff\xa8\x96\x8f"
+  "\x53\x8f\x6a\x71\xae\x89\xe5\xef\x89\xc3\xba\x35\x63\xbf\x94\xda"
+  "\x8a\xb1\x5b\x21\x1d\x6d\xff\x66\xe4\x9b\x94\x8e\x7e\x6d\x81\x4f"
+  "\x2a\xf8\x66\xae\x58\xa7\x38\x78\x56\xc2\xb7\xd9\x3e\x1a\x8c\xe3"
+  "\xba\x19\x7f\x93\xea\xf8\x0d\xf6\x1b\xc0\x70\x00\xfc\xe6\xf7\x70"
+  "\xa7\x52\x5e\x1e\xdf\xb5\x46\x55\xd0\x8d\x73\x4d\x35\xc1\x52\x7c"
+  "\x57\x8c\xed\x8a\x32\x23\x77\x89\x0b\xed\x91\x36\xfb\x81\x57\x0c"
+  "\x77\x87\x6d\xe5\x40\xef\x1a\xb0\xff\xff\x26\xfa\x92\xab\x51\x89"
+  "\xf5\xab\xe0\x71\x0f\x2a\xe7\x96\xe6\x4b\xbe\x0c\x6a\x2c\xbd\xe3"
+  "\xa1\x5e\xdb\xb2\x46\x85\x98\x84\xb2\x6a\x91\xff\x68\x27\x76\x65"
+  "\xd4\x06\xf5\x62\x8b\x9d\x97\xad\x29\x41\xfb\x52\xac\x3f\xe2\x65"
+  "\xbd\x48\xbb\xb9\xce\xfd\xce\xb9\x9f\x43\x19\xd1\xd0\xc7\x7b\x31"
+  "\x20\xf5\x6b\x8e\x83\xba\x6d\xa2\x4d\x91\x8d\x7e\x65\xa1\xdc\x0a"
+  "\xb4\xc1\xb9\x5e\xad\x8b\x3b\xdc\x6c\xc3\xb9\xea\x46\x78\x86\xfe"
+  "\x5d\x37\xb7\x73\x7c\x7d\x59\x26\x93\x1b\xb5\x30\xfe\xb9\x87\xcd"
+  "\x9f\x23\x5d\xa4\xfe\xba\x79\x09\x8e\xfd\x42\x79\x9f\x4d\x6e\x25"
+  "\xf5\xd6\x76\x22\xee\x95\x87\x3e\x7b\x06\xd7\x28\xcf\x03\x86\x94"
+  "\xd8\x7f\x81\xbf\xd8\xff\x51\xe6\x34\x64\x6e\x67\xfd\x56\x85\xfd"
+  "\xb6\x07\x7d\x30\xc0\x77\x2a\xa3\xc3\xc9\xe1\xe4\x0a\xd6\x8f\xd1"
+  "\xb7\x46\x31\xd0\x0e\x63\xa9\x76\x65\xd4\x85\x4a\x7b\x7c\x11\x23"
+  "\xe8\x4b\x43\xc4\x49\x32\xf6\x65\x91\x76\x0a\xc8\x17\x29\xf5\x3d"
+  "\x27\xfe\xb3\x3c\x7d\xfa\x5b\x00\xef\x6f\x75\xd9\x12\xad\x6d\xac"
+  "\x1f\xd7\x04\xdb\xa0\x1f\x3b\xd3\x14\xe9\x89\x74\x85\xbc\xd0\xfe"
+  "\x4f\x6a\x25\x9a\x3a\xe8\x59\x3f\x43\xe4\x79\x03\x9f\xcb\xa9\x6b"
+  "\x13\xe7\x79\x7a\x69\x28\xe2\xaf\x11\xfb\xd4\x46\x6c\x3b\xe8\x06"
+  "\xfc\x3e\x62\xa4\x58\x94\x59\x95\x66\xc4\x48\x3d\xf4\xff\x5f\x66"
+  "\x3b\x64\x47\x8d\x8e\x8d\x59\x80\x4f\x9c\x3f\xf5\xbf\x64\xfe\x2a"
+  "\x06\x90\x1d\x26\x52\xab\x76\xc8\xa7\xfa\x68\x89\x0e\x12\x26\xa5"
+  "\x7e\x0f\x65\x1c\x70\x95\x3f\xf5\x5b\xa1\x8c\x49\x28\xdf\x1c\x36"
+  "\x54\xfd\x1e\x57\xf9\x56\x9f\x8d\xf2\x0d\x71\xad\x4f\xc2\xb9\xac"
+  "\x7a\xd1\xf7\x75\x75\xa8\xab\x4c\xaa\x9e\xc1\xd7\xe0\xb9\xcd\x85"
+  "\xd8\xd2\x2f\xe1\xf9\x51\x87\x41\x7e\x16\xa7\x44\xd4\x79\xe8\xbf"
+  "\x18\xd3\x24\x5f\xd8\xcd\x90\xbf\x12\xcf\x1d\xa2\xaf\x81\x09\xcd"
+  "\x7c\xac\x07\x72\xfa\x10\xfa\x94\x36\x91\x7f\x34\xd7\x43\x2f\xec"
+  "\xc9\xe2\xb2\x5b\x92\x15\xf4\xe5\xc8\x09\xaf\xb7\x11\x5f\xfd\x4f"
+  "\xe9\xd7\xa0\xb3\xd1\xb7\xa0\x15\xfd\x1a\x42\xd9\xda\xb3\xe4\xd3"
+  "\xdf\xc3\x77\x03\xc5\xbb\x06\xee\x2b\xe0\x3e\x05\xee\xcf\xc2\xfd"
+  "\x36\xb8\x3f\x0a\xf9\x05\x31\x7f\x28\x3c\xcf\x80\xf4\x07\xc4\x3b"
+  "\xd4\xd1\x78\x10\xee\x8b\x44\xdb\x11\xd2\x8f\x5d\xc5\x67\xb8\x9f"
+  "\x13\x79\x5e\xcb\x79\x6e\x3c\x0d\xe5\x24\x43\xfd\x9b\x8c\xcd\xac"
+  "\x2c\x3d\xe4\x79\x1b\xcb\xc6\x73\xc0\xf0\xff\x8b\x4e\x36\x28\x94"
+  "\xd3\x90\x03\xf7\xd9\x70\x5f\x08\xf7\x44\xb8\xdf\x21\xd2\xa0\x01"
+  "\x65\x43\x6c\x32\xa3\xf9\x1c\x2d\xb7\x77\x17\x49\x7d\x1e\xf5\xb0"
+  "\x43\x76\x1c\x49\x89\x8d\xe2\xfc\x36\x91\x3a\x86\x03\xc8\xfb\x18"
+  "\xe6\x85\xfb\x13\xe2\x3d\x5c\xbc\xcf\x13\xef\x4f\x8a\xf7\xb9\xe2"
+  "\x7d\xbe\x89\x34\x04\x8b\x36\x06\xd0\xa5\x21\x98\xed\x2f\xca\xae"
+  "\x8a\xe5\xdf\x38\x36\x17\xc7\xc8\x20\xc7\x1f\x84\xf2\x7d\xba\x32"
+  "\x1a\xca\xa5\x79\x48\x9c\xf3\xe9\xc9\xa8\x5c\x5a\xcc\xd6\x8f\x1b"
+  "\x1a\x9c\x64\x9b\x42\x25\x0b\x27\x60\x03\xdd\x52\x22\x07\xfd\xcf"
+  "\xcb\xd1\xc9\xc5\xf5\x57\xd1\x5f\xbd\x0f\xfa\x70\x63\xe3\x21\x3f"
+  "\x3f\x9c\xbf\x6d\x66\x73\xb4\xe8\x6f\xcc\xb7\x46\x09\x57\x20\x8c"
+  "\x0d\x34\x92\xfc\xc6\x71\x8f\xe8\x1b\xf2\xc3\xae\x8c\x63\x73\x1c"
+  "\x63\xf5\x86\x76\xbe\x56\x75\xeb\x1d\x90\xbe\xd8\x29\x7d\x1f\xd6"
+  "\x19\xe8\xd9\x04\xed\x99\xdd\x42\x8e\xa5\xc0\xfd\xfe\x56\xde\xe6"
+  "\x50\xa9\xcd\x22\x3f\xf4\x12\x7d\x5b\x49\x43\x08\xc8\xc2\x04\xc4"
+  "\x70\x4b\xaf\x9c\x6d\x60\x67\xd2\x44\x8c\x00\x2f\x8d\xe8\x03\x33"
+  "\xcd\xa9\x0f\x3a\xcb\xa0\x40\xa8\x47\xb3\xab\x4c\x39\xd2\x8c\x32"
+  "\x05\xb1\x01\xf2\x1b\x78\x6d\x3c\xd4\xa7\xff\x65\x63\xff\xe3\xfd"
+  "\xee\x53\x8d\xeb\x6f\xeb\xb3\x6d\xbc\xdf\x35\x01\xce\x00\x9f\xc6"
+  "\x12\xe4\x8f\x89\x1c\xb3\x8a\x7d\xba\x09\xfa\xf4\x83\x90\x2e\xc6"
+  "\x06\xe6\xe9\xe2\xb7\x00\x67\x46\x6c\xf7\x6d\x52\xba\xd8\x5e\x2c"
+  "\x27\x11\xf9\x2d\xa5\x8b\xe5\x03\x1e\x8d\xf1\xd8\x4f\xa4\x74\xb1"
+  "\x4d\x60\x47\x7d\x5a\x26\xc9\x13\x03\xc7\x5b\x98\xf4\x3b\xe4\x1b"
+  "\xfa\x75\xe2\x73\xe9\x9f\x96\x40\x5f\xdd\x83\xfa\x61\xe3\x12\xa2"
+  "\x7a\x7d\x07\xf1\xe3\xfd\x12\xc7\x14\xce\x32\xf2\xf8\x7a\x9a\x11"
+  "\x60\xa3\xca\x1a\x52\x67\x9b\x2d\xd9\xab\x25\x5d\x19\x9f\x69\xa4"
+  "\x58\xc2\x0e\xdf\xf7\x9f\x2d\xac\xdb\xd3\x4b\x5f\xa8\xcb\x67\x73"
+  "\xa4\xba\x38\xe9\x67\xc6\x03\xac\x1b\x96\xb5\x11\xec\x75\x0b\xc8"
+  "\x05\x2e\xb7\x3f\x8b\x97\x62\xac\xe7\x89\x7a\x8b\xc5\xf9\x4e\xe2"
+  "\x71\xbe\x51\x37\xe2\x5e\x1a\x01\xe7\xb1\x92\xed\xa4\x5e\x0f\x63"
+  "\xf9\xe4\x33\x64\xe9\xda\xf1\xe8\xbb\x24\x12\xea\x1a\x03\x75\xdb"
+  "\x6b\xc7\x39\xf6\x95\x38\x4e\x3d\x7e\x8b\x3d\x89\x5a\x45\x9a\x41"
+  "\x3f\x6a\xbc\x2a\xd2\x16\xe5\xd7\x5e\x94\xe9\x1b\x53\x79\x1c\x1b"
+  "\x9c\xcb\xc1\xfe\x51\x80\x7a\x4c\x43\xad\x95\x25\xd8\x57\x3e\xb3"
+  "\x49\x36\x29\xd4\x77\x0f\xb7\x09\xeb\x9e\x67\xbe\x7d\xb2\x6b\x44"
+  "\x9f\x43\x8d\x39\xbc\xed\x8d\x7a\xbe\x9e\x5c\x23\x9e\xed\x69\x8c"
+  "\xf2\xd1\x4c\xfe\xdf\x7c\xff\x53\xe5\x3a\xbe\x77\xa3\x71\x41\xef"
+  "\xde\x0d\x87\xad\x98\xc8\xfd\x2e\x35\xc6\x39\xfa\x44\x63\x18\xfe"
+  "\x0e\x7e\x5f\x04\xe9\xe9\x8e\xf4\xba\x48\x71\xbe\x4b\xe1\xbf\x21"
+  "\x1c\xf7\x70\xdd\x82\xfe\x9f\xc5\xef\x99\xd8\xf7\xd9\x9c\x47\x4d"
+  "\x6f\xff\x45\x3a\xa3\xce\x66\x7d\x18\xfa\x2f\xf6\xe3\x9e\x9c\x1a"
+  "\x25\x5c\xbc\xdf\x72\xdd\x9c\xc8\xfa\x2d\xeb\xb3\x8d\x66\xa7\x7a"
+  "\xec\x63\xf3\x5e\xc8\xcf\x37\x34\xaa\xae\x8c\xe3\x2a\xb0\x57\xc5"
+  "\x38\x09\x9f\xb1\xfd\xc7\xe8\x9f\xc3\x76\x85\x9a\x71\x0d\x19\xd7"
+  "\x14\xf1\x8c\x53\x00\xa0\x1b\x7d\x6a\x48\x6b\xc2\x0b\xdb\xd3\xa8"
+  "\x1d\xd7\x77\xae\x50\xcb\x96\x5e\xff\xf3\xc7\x23\x1d\xfe\x71\x3e"
+  "\x2b\x17\xdb\x85\xf6\x4c\x09\xdf\x73\xf5\xd9\xdb\xdc\xa6\xfa\x6c"
+  "\x1f\xe2\xd4\x08\xd8\x83\xfb\x0e\x1e\x4b\xf5\x78\xa1\x84\x3d\xe8"
+  "\x97\xb1\x67\xc9\xe7\x33\x0a\x27\xd3\x1d\xc0\xd3\x1d\xd0\x97\xe2"
+  "\xe1\x79\x22\xdc\x63\xf9\x5d\xa6\xc6\xbb\xd8\x47\x76\xc0\x6f\x1b"
+  "\xa4\x98\xd7\x48\x1b\x8b\xef\x15\xb6\x4e\x9b\x07\x74\x40\xac\xb1"
+  "\xf5\x5a\x3d\x8f\x25\x8f\x38\x43\x8c\x05\x6c\x78\x8a\xe1\x8c\x9d"
+  "\xdf\x87\x74\xac\x2f\xe2\xac\x2b\xe3\xf3\x20\xc9\xf7\xac\x89\x1c"
+  "\xaf\xe0\xeb\x26\x9f\x87\x4a\x7b\x56\x71\xcd\x26\xf1\x0e\x72\x0b"
+  "\x94\xab\xad\xd4\x32\xff\x8e\xa7\x8c\xb6\x79\x04\xf3\xe2\x7a\x17"
+  "\x97\x93\xb7\x26\xc2\x6f\x62\x1d\x34\x3f\xc2\xf6\x6d\x1c\x8e\x62"
+  "\x73\x91\x3f\x80\x77\xe9\xce\xe3\x0c\x13\xa9\x5a\x80\x63\x0d\xdc"
+  "\x43\x77\x57\x20\xc1\xd8\xf4\x20\xc7\x3e\xdf\x2b\xd9\xb5\xf7\x06"
+  "\xe2\xba\x79\xa5\x15\xea\x87\x63\x68\x68\x6b\x65\x2b\x8c\x25\xab"
+  "\xdd\xcc\x19\xcf\xc6\xb9\x1e\x31\x66\x4c\x33\xce\x63\xa1\x8f\xfd"
+  "\xb3\xe4\xcb\x19\x75\x3b\x80\x9f\xab\xfa\xfb\x1e\x4e\x4d\xa6\x97"
+  "\xd1\xff\xb0\x36\x81\xfc\xa0\x85\x7c\x89\xe3\xc1\xa6\xb4\x4b\x38"
+  "\x47\xf3\x45\x88\xeb\x1c\xcd\x17\x29\xe2\xb5\x05\x2e\x8b\xe3\x6a"
+  "\xca\x14\xef\x64\x88\xab\x84\xe7\x6d\xda\x07\xd7\x41\x91\x56\x07"
+  "\xbb\x32\xbe\xe8\x9d\xff\x45\x5c\x62\xdf\xc6\xfd\x12\x38\xe7\x24"
+  "\xb3\x11\xf4\xdd\x01\x7c\x82\x7a\x6f\xbc\xfb\x99\x8a\x75\x88\xa3"
+  "\x2f\x58\x0c\x47\xf4\x8b\x3b\xbc\x3d\x3b\x5f\x30\x7e\x72\x1f\x95"
+  "\x5f\x64\xc2\xb7\x2b\x37\x5f\x24\x0a\x7d\x02\x99\x86\xf3\xdf\x01"
+  "\x76\x5a\x81\x63\x5c\xc4\xc4\x6e\x16\xab\xa5\xe9\xf7\x89\xeb\x89"
+  "\x1c\xde\xdf\x0e\xff\x27\x4a\x76\x12\xfc\x46\xed\x63\x25\x81\x68"
+  "\x1f\x3d\xb1\x9e\xdc\xde\x95\xd1\xb4\x48\xe2\x15\xda\x10\x38\x0f"
+  "\x27\xce\x25\x60\x5d\xd9\xde\x44\xf4\x9d\x6e\x62\x74\x63\x72\x18"
+  "\xcb\x80\x7e\xd7\x34\xc7\xc7\x42\xd4\x5c\xf7\x34\x01\xfe\x2b\x45"
+  "\x9b\xb1\x29\x12\xb0\xdf\xe8\x54\xcf\x2b\x8e\xff\x35\x0f\xe1\xef"
+  "\x03\x2c\x68\x9f\xb9\xa3\x4f\xd3\x69\x89\x3e\xb8\x2f\x34\x00\xc6"
+  "\x09\x8c\xdf\x36\xda\x0e\x75\xab\xd5\xaf\x23\xca\xf3\xe4\xc4\xb1"
+  "\xdd\xdb\xd9\x39\xb5\x6a\x3e\x3f\x7f\xa2\x4a\x1a\x87\xf3\x7a\x9f"
+  "\xd8\x1a\xb0\xc1\x87\xe0\xbc\x3a\xfa\x0b\x63\x7b\xea\xbe\xd5\xb0"
+  "\xb9\x74\xa3\x6d\x0e\xa9\x48\x7d\x04\xf3\x48\x76\x55\x73\x67\x9a"
+  "\x86\x1c\xd6\xcc\x81\x7e\x7c\x22\xca\x24\xab\x88\x1d\xfe\xde\xc5"
+  "\x13\x51\x22\x7d\x6b\xf9\x9a\xff\x89\x59\xa8\x4b\x32\xc5\xd8\xf4"
+  "\xa8\xa3\xa1\xec\x72\xa9\xdf\x80\xde\xa8\x84\xdf\x84\x70\x19\x83"
+  "\xeb\xac\x27\x98\x7f\x11\x36\x6e\xe0\xf9\x55\x7c\xce\xff\x44\x7b"
+  "\xaf\x2d\x0d\xf9\xf0\x77\x7c\x2f\xd8\x09\xb2\xd4\x2e\x03\x9a\x9e"
+  "\x60\x6d\xe3\x58\xd4\xcc\xe9\xca\xf8\x32\xc8\xd1\x6f\x9b\x98\x6c"
+  "\x3e\xdc\xee\xdc\x2f\xbf\x9c\xe3\x18\x6f\x7e\x6e\x9e\x55\x48\xb4"
+  "\x03\xf5\x43\xbd\x3f\x51\xff\x4b\x49\x7e\xb5\x79\x33\xdd\xb3\x45"
+  "\x2e\x3c\xbe\x31\x8f\xa8\x64\x06\x20\x1b\xf6\xb3\xa4\xe8\x5b\xa0"
+  "\x3f\x7e\x10\xa0\xba\x75\xd1\x13\x89\xe3\x68\xaa\x86\xc8\x73\x3b"
+  "\xc6\x29\xef\xb0\xde\xba\x87\xfa\xdc\xfd\xcc\xc2\x44\x2b\xd1\xfe"
+  "\x76\x0b\xf9\x26\x9e\xf8\x3c\x61\x87\x6f\xab\x88\xde\x44\x9a\xab"
+  "\xf1\xcc\xe5\x61\x15\xda\x1f\xcd\xd5\x58\x66\x4a\x09\x51\xa6\xb4"
+  "\xd2\x36\xc3\x2b\x63\x94\xa0\x0f\xd4\xc5\x80\xb1\x09\xaa\x5b\xf7"
+  "\xf4\x40\x19\x1f\x47\xb3\xdf\x95\x0d\xbf\x6e\xfa\xc9\x67\xc9\x3f"
+  "\x9f\x1f\x5e\xdd\xbe\x8a\x73\xd4\xed\xab\xb8\x51\xae\x9b\xda\x51"
+  "\xb7\x38\xac\xdb\xe5\xe1\xd5\xcd\xa4\x74\xd4\xcd\xa4\xf4\xb0\x6e"
+  "\xfb\x87\x5f\xb7\xe4\x5b\xcf\x92\xe6\xad\xc3\xab\xdb\xe9\x7d\x8e"
+  "\xba\x9d\xde\x37\x92\xba\xe1\x58\x3e\x35\x88\x9e\x61\x3e\xce\x13"
+  "\x88\x0a\xf7\xc8\x9d\x25\x27\x2f\xa5\x96\xb0\xe7\x49\xf0\xff\x01"
+  "\xb1\x7f\x9b\xd3\x2c\xf4\x6b\x6e\xe7\x9c\x9c\x72\x8f\x1e\xf7\x95"
+  "\x9e\x54\x03\x96\xab\x39\xa6\xbf\x62\x7b\x3b\xd3\xcc\x54\xdc\xd7"
+  "\x79\xf2\xe1\x52\xb6\xef\xc3\x18\x29\x3e\xa7\x74\x8e\xaf\x99\x83"
+  "\x7b\x2e\x04\xe8\xcf\x74\x7c\xcd\x7c\x8c\xf9\xf8\x6e\x82\x59\x4e"
+  "\x33\xd0\xf7\x16\xfa\xcb\x53\x10\xba\xa9\x26\xf2\xdd\x04\xab\x1c"
+  "\x7d\x66\x6c\x64\xe7\x65\x4f\x26\x4a\x67\xc4\xa4\x6f\x98\x7d\x8d"
+  "\x91\x90\x6e\x90\xe2\xcc\x52\x39\xd8\x33\xbe\x35\xe1\x58\x3e\xa4"
+  "\xef\x95\x62\xc1\x9a\xc8\xc9\x30\x51\x36\x58\x02\xac\x83\xc9\xbd"
+  "\x93\x27\x24\xb9\xf7\x44\x22\x09\xc0\x58\x89\x9b\x53\xc7\xe1\x9a"
+  "\x23\xd8\x3f\x27\xe3\x90\xee\x11\x96\x71\x34\x20\x85\xf8\xe0\xd9"
+  "\x38\xdc\x0b\x67\xd4\x98\x49\x70\x0a\x19\x13\x91\x0c\x65\x5a\x49"
+  "\x74\x40\x32\x94\x07\xb4\xe6\x63\x83\xaf\xd8\x1c\x5f\x21\x94\x87"
+  "\xeb\xdf\x3e\x89\x44\xf5\x84\x26\x8d\x6e\xdc\x49\x14\x78\x8e\x0e"
+  "\xcf\xc3\xf1\xb3\x70\x63\x95\x5d\x19\x5f\x2d\x96\xda\xe7\x01\x7f"
+  "\xfc\x39\x7f\x4e\x6d\x75\xf0\xe7\xd4\xc2\xfe\xfc\xf9\xea\x7d\xce"
+  "\x9f\xaf\xca\x1c\xfc\x39\x65\x71\xe5\xcf\x57\x27\x5c\xf9\x73\x2a"
+  "\xc8\x3b\xfe\x9c\x0a\x74\xf0\xe7\x94\xc5\xc1\x9f\x53\x21\x03\xf3"
+  "\xe7\xd4\x5c\x07\x7f\xbe\x6a\xf2\x8c\x3f\xa7\xd6\xba\xe7\xcf\x29"
+  "\xe5\x20\xfc\x19\x3b\x30\x7f\x4e\x1d\xf1\x9c\x3f\xa7\x2c\xc3\xe0"
+  "\x8f\x1f\xe7\xcf\xe9\xfb\x1c\xfc\x31\x5d\xe8\xcf\x1f\xd3\xf3\x9c"
+  "\x3f\xa6\x45\x0e\xfe\x9c\x2e\x74\xe5\x8f\x69\xad\x2b\x7f\x4c\x87"
+  "\xbc\xe3\x8f\xe9\xa0\x83\x3f\xfc\x1b\x9c\x3f\xa6\xda\x81\xf9\x63"
+  "\x6a\x75\xf0\xc7\x94\xec\x19\x7f\x4e\x4f\x71\xcf\x1f\xd3\xbe\xe1"
+  "\xf3\xe7\xf4\xf2\x3e\xfc\x51\xbb\xe7\xcf\xe9\xc2\x61\xf0\x27\x80"
+  "\xf3\xa7\xe5\x98\x83\x3f\x2d\xb9\xfd\xf9\x73\xfa\x2a\xe7\xcf\x69"
+  "\xb3\x83\x3f\x5f\xcf\x76\xe5\x4f\xcb\x14\x57\xfe\xb4\x44\x79\xc7"
+  "\x9f\x96\xc5\x0e\xfe\xf0\x6f\x70\xfe\xb4\xc4\x0f\xcc\x9f\x96\x4c"
+  "\x07\x7f\x5a\x34\x9e\xf1\xa7\xe5\x7d\xf7\xfc\x69\x99\x3f\x08\x7f"
+  "\xc6\x0d\xcc\x9f\xaf\x7d\x3d\xe7\xcf\xd7\xb3\x07\xe3\xcf\xf0\x6c"
+  "\xbd\xaf\x99\x0f\xad\x51\x28\xc7\x7d\x7c\x60\xa0\x1d\xee\xf3\x13"
+  "\x32\xbe\xde\x52\x2a\x8c\x55\xf2\xb3\x10\x5f\xcf\xd7\xae\x23\x3f"
+  "\x6b\x21\x5f\x9f\x2c\x15\xc6\x28\x69\xc6\xde\x58\x21\xe3\x4f\x2a"
+  "\xba\x61\xac\x42\xd8\x30\x4e\x81\x67\x9b\xdd\xc7\x9e\x6e\x7d\xd4"
+  "\x67\x0a\x99\x8e\xe7\xd3\x36\x82\xbd\x8c\xff\x77\x65\xb4\xce\x07"
+  "\x5b\xd0\x30\xd8\x39\x29\xdc\xeb\x74\x38\x13\xc7\xb7\xad\x89\xbd"
+  "\x7e\x25\x32\x68\x32\xfa\xe7\xd2\xdf\x89\xe7\x19\x5a\x4b\xd0\x0f"
+  "\x36\x8c\x57\x5b\xc3\xef\xa4\xa7\x70\xec\x71\x96\x9c\xd9\x49\x73"
+  "\xaa\xd0\x0f\xaf\x05\x6c\xf5\x1f\x40\x9e\xd6\xde\x7d\x70\x34\xb2"
+  "\x48\x9c\x23\xdc\xc2\xf3\x7e\xe3\x0b\x79\xb7\x60\x6c\xcc\xd5\xa9"
+  "\x18\xf3\xf1\xec\x25\xb0\x7d\x7f\x88\xdf\x40\xdf\x43\xbb\xe1\x8e"
+  "\xfb\x64\xf8\x1e\xc8\x33\xec\xec\x2a\xfa\x35\xe4\x7b\xce\xce\x9e"
+  "\x90\x70\x07\xdf\x19\x0f\xcf\x1f\x8b\xf6\x3c\xe6\x9f\x00\xcf\x6f"
+  "\x3b\xbd\x57\xc1\x73\x2e\x94\x3d\x51\x7c\xef\x07\xcf\xaf\xa1\x9d"
+  "\xcd\xfc\x64\xe4\xa5\x8b\x7b\x75\xcf\x2e\x86\x34\xb5\x98\x67\x22"
+  "\xe4\x79\x18\x6d\x77\xb1\x8c\x49\xf0\x3c\x0d\xc7\xc0\xe2\xfb\x40"
+  "\x78\x46\xbf\x52\x0a\xf1\xfd\x2d\x50\xc7\x33\xf0\xfc\x23\x7e\xb6"
+  "\xa4\x47\xec\xa3\x67\xca\xbc\x3b\x73\x7d\x86\xfb\xe2\x92\xb3\xb9"
+  "\x20\x18\x0b\x9c\x71\xda\xff\x73\x66\x87\xeb\xbb\xb3\x81\x4e\xef"
+  "\xb2\xa5\x77\x7c\x8f\xda\xd9\x50\xa7\x77\xc9\x7d\xde\x2d\x70\x7a"
+  "\x17\xd7\xa7\xcc\x38\xa7\x77\x91\x7d\x7e\x97\xe9\xf4\x6e\x6e\x9f"
+  "\x77\x7b\x9c\xde\xcd\x16\xdf\xf9\x40\x7a\xb9\x63\x0d\xef\x4c\xb0"
+  "\x98\x2e\x87\xf4\x06\xa7\xf4\x40\x31\x1d\xbf\xdf\x66\x22\xff\x19"
+  "\x2b\xa6\x33\xde\xf3\xf2\xbf\x21\x8e\xf2\x5b\x5b\xf9\x1c\xc7\x37"
+  "\x81\xbd\x7b\xe7\xc6\xd7\xec\x10\x7a\x22\x8b\xe0\x5d\x2d\xe2\xca"
+  "\x19\xdb\x2b\x93\xb4\x2f\xad\x79\x55\x9b\xb0\x2c\x11\xb7\xaf\xac"
+  "\x58\x9e\xa8\x5d\xb1\x2a\x76\x99\x8b\x9f\xf2\x40\xf4\xd9\x87\x71"
+  "\xbe\xd0\xf7\x89\xe8\x53\xbf\xad\x37\x0e\x05\xc8\x55\xf8\x56\xba"
+  "\x89\xcc\x65\xeb\x63\x85\xdc\x9f\x77\x35\xfa\x4e\xe1\x7e\x52\xc8"
+  "\x53\x2d\xe4\x9b\xdf\x8b\x7e\x52\x2a\x20\xef\x7e\xf7\x7e\x52\xce"
+  "\x65\x33\xff\x80\x90\x8f\xfb\x49\x39\x67\x80\x7e\xfe\x04\x1d\xcf"
+  "\xe3\x4a\xf0\x78\x5b\xdf\x48\xb6\x89\x79\xe9\x55\xe6\x63\x2f\x9d"
+  "\xcf\x65\xf4\xf5\x77\x5a\x55\x89\xbf\x13\xd7\x4b\x2b\x1d\xbf\x6f"
+  "\xd3\xf0\xf7\x92\x7e\x10\xbf\x99\x5d\x85\xe3\xe6\xf1\x2d\xf0\xcc"
+  "\xe6\xef\xd9\xbb\x36\x3e\x97\x97\x53\x55\x8b\x6d\xc2\x76\xbb\xb6"
+  "\x4d\xfe\xeb\x16\xd2\x16\xe3\x68\x5b\x5b\xb6\x93\x2f\x35\xb1\x0d"
+  "\x6d\x65\xbc\x8f\xf6\x6b\x2b\xdb\x9f\x48\x95\x55\xb5\xf8\x6d\x94"
+  "\x67\xfc\xcc\x00\x3c\xe7\x54\x55\x4b\xf5\x71\xaa\x1f\xce\xdf\x2a"
+  "\xa0\x7e\xb9\x9c\x26\x20\x3f\x80\xa7\x62\x1b\x16\xd2\x8c\x6f\x42"
+  "\xd9\x1e\x78\x3c\x6b\x8b\x71\x42\x98\xae\x3a\xd7\x1b\xff\x07\x75"
+  "\x14\x9f\xc3\x3c\xe7\xb0\xff\xd0\xc7\x55\x8e\xa4\xbf\xce\x39\xd9"
+  "\x7f\xfc\x9b\x90\x16\xe9\x8c\x21\xa7\xef\xfd\x1e\xbf\x07\xf9\x08"
+  "\xdf\x77\x5f\x85\x34\xb1\x98\x48\x5b\x25\xee\xc5\xc4\xdf\x62\x1d"
+  "\xdd\xc5\x86\x73\xe7\x83\xd0\x41\xc7\x73\x0d\x12\x1d\x0b\x59\x8c"
+  "\xa2\x73\x26\x69\xbe\x8e\x9d\xfb\x81\x3c\x85\xbd\xb1\x92\xcf\x33"
+  "\x3f\xe6\xd4\xe0\x1f\x77\xaf\x8a\x44\x73\xda\x9e\xbf\x05\x65\x3c"
+  "\xf6\x19\x2e\xeb\xcf\x27\x8a\x3c\x0f\xe5\xf5\x3f\xff\x28\xa6\x3b"
+  "\xf6\xb9\x9f\x2f\x94\xf2\x49\x72\x99\xaf\x57\x9d\x5f\xc1\xf2\xf1"
+  "\xf8\xb5\x61\x9c\xe7\x3f\x52\xb7\x90\xf3\xe9\x62\x7e\xee\x1f\x95"
+  "\xf9\xbf\x39\x5f\x42\x73\x8c\x61\x5d\x19\xe7\x61\xfc\xf3\xcd\x7c"
+  "\x4e\x47\xfe\x5d\xb8\xa7\x63\x5d\x90\x46\x78\x46\x9b\xe6\xfa\xc7"
+  "\x01\x7f\x06\xf4\xab\x2c\xee\x9f\xbe\xfd\x3c\x69\xe7\x36\x84\x9c"
+  "\x5a\x71\x8e\x95\xb7\xb5\x7d\x8a\xd3\x1e\x63\x95\x94\x87\xcb\x6e"
+  "\xf6\x8e\xed\xdd\xd6\x27\xe1\x7c\x90\xf8\x2e\x09\xcf\xb1\xf6\xfe"
+  "\x3f\xd6\xe9\xff\x31\xf8\x3f\x4d\xa2\x65\x9b\xd7\x31\xdd\xaa\x70"
+  "\x9c\x91\x6f\xd7\xc0\xb3\xaa\xcf\x73\xa0\xcb\xf3\x5a\x12\xc4\xf6"
+  "\xdf\x5a\x68\x2b\xdb\xab\x2d\xa6\x8b\x65\xfb\xb2\xfa\x24\xd1\x30"
+  "\xc0\x06\xc6\xf8\x88\x12\xfb\x61\x13\x9e\x95\x0e\xb0\xbd\xc8\xce"
+  "\x49\xc3\xfb\xd9\xe2\x3d\x54\xbc\x87\xf0\xd8\xa1\xff\x72\x8a\xff"
+  "\x8d\x73\x34\xff\x32\xb9\x8b\x47\x2e\xc5\x6b\x97\xe2\x91\xe3\x39"
+  "\x6b\x31\x7e\x6a\x54\x57\x46\xbb\x66\xb0\xd8\xef\xf0\x3e\x4c\x3a"
+  "\x33\x6d\xcf\xae\x4a\x11\xb2\xaf\x54\x63\xac\x4a\xf4\xb3\x95\xd6"
+  "\x8e\xbe\x56\x2c\xc4\x48\xba\x89\x31\xb1\x2b\x1d\xe3\x55\xd6\x5b"
+  "\x99\xef\x62\x3c\x6b\x2a\xc3\x79\x73\xb4\x1d\xeb\xf5\x17\x58\xac"
+  "\xca\xd7\xdb\x49\x90\xfe\xa7\xb4\x15\x68\x50\x62\xcf\xa9\x4a\x11"
+  "\x71\xb4\x13\x74\xe0\x74\xa0\x05\x9b\x2f\x66\xb1\x96\xdb\xd9\xba"
+  "\x97\xf2\x2c\xb9\x10\xc2\xf2\xd0\xc8\x9d\x9c\x76\x17\xd8\xdc\xd7"
+  "\xee\x0c\x29\x1e\x61\x7b\x6f\xfc\x63\x13\xb9\x10\x7a\xd9\xf7\xd8"
+  "\x3e\x48\x6b\x73\xdd\x33\x7d\x81\x95\x89\x75\x37\x91\xf6\xbd\x58"
+  "\x76\x57\xc6\x05\x55\x6f\x9f\x85\xf4\xd7\x6d\x64\x2a\xd4\xeb\xac"
+  "\x54\x3e\xbc\x87\xfe\x7f\xbe\x1c\xdf\x63\x99\x97\x73\xba\xa0\xdc"
+  "\x0b\xe1\x26\xf9\x8e\x64\xbe\xe7\xfa\x02\xe8\xbf\x3f\x94\x0f\x66"
+  "\x03\x41\x5f\x88\x83\xbe\xa4\x17\xb2\x8d\xd1\xcc\x17\xb6\xaf\x31"
+  "\x8e\xcf\x31\x5e\xd8\x89\xfb\xba\x36\x5f\x21\x0a\xdc\x03\xc1\x31"
+  "\x7b\x81\x9f\xef\x81\x34\x90\xd5\xfb\xa0\x8f\xb0\xfd\x3b\xc3\xd3"
+  "\xfb\x17\x98\x8f\x9f\xcd\x1d\x44\x99\x97\x20\xf9\xf2\xbe\x60\x71"
+  "\x8a\x3f\x20\x9e\x2f\xb9\x38\x0d\x57\xca\x37\x77\xf3\x3a\xf6\xad"
+  "\x03\xd6\x17\xca\xda\xe1\xd6\xc6\x54\x1a\xa3\xd9\xfa\xcc\xa6\x9a"
+  "\x38\xbe\x47\xf5\xe2\x32\x1f\xcd\x6d\xdb\xbb\x32\x2e\x46\xf7\xc6"
+  "\x5d\x80\x3c\x79\xb8\xf7\x1e\xca\xef\x6d\x67\x02\x7e\xe3\x62\x36"
+  "\xef\xeb\x17\x4b\x84\x1c\x23\xc6\x57\x50\x88\xe9\x25\xf5\x36\x2b"
+  "\xfa\x58\x18\xd0\x4f\x15\x8b\xe7\x86\x7b\xc2\x37\x19\xa3\xf1\x7c"
+  "\xce\xbd\x56\xa9\xce\xdf\x96\xe0\xb9\x10\xac\x33\xa7\xed\xb7\x5b"
+  "\x25\x3a\xe6\x76\x40\xd9\xa9\x5f\x92\x56\xf2\xed\x14\xdc\x37\x87"
+  "\xe7\x9c\xb0\x0f\x73\x1a\x7c\xcb\xc6\x7c\xec\xfb\x2c\xcf\x45\x36"
+  "\xf6\x67\xb1\x75\xa0\xfc\x52\x16\x1f\x0c\xda\x00\xbc\xa8\x48\xc5"
+  "\xb3\xf5\xdf\xb2\x33\x3e\x1b\x13\x08\x6f\x37\xdb\x27\xfb\xad\xb8"
+  "\x4e\xf2\x6d\xa4\xa4\x2b\x4c\x62\xda\x66\xfc\x76\x52\x37\xb9\x48"
+  "\xbe\x7d\x18\xe3\x7e\x03\x3d\xf4\xe8\xdf\xad\xde\x02\xfd\x24\xb9"
+  "\x1b\xb1\xa0\xc7\x78\x92\x90\x3f\x8c\xeb\x37\xa4\xf9\xb7\x41\xf8"
+  "\x7d\xa4\x2d\xf0\xce\x0c\x34\xdd\x0b\x65\x1f\x94\x68\x9a\x37\x19"
+  "\xc7\x3b\x17\x1b\x06\xd3\x0d\x76\xa8\x73\x3d\x70\xae\x62\xea\x97"
+  "\x50\x3f\xf3\x7a\x61\xbc\x31\x1a\xf7\x64\xc3\xff\xe2\xd9\x34\xce"
+  "\x3b\xde\x97\xcc\xcf\xc2\x37\x8c\xb8\xbf\x01\x65\x25\xfa\x20\x83"
+  "\x36\xd9\x44\xfa\xb1\x78\x0c\x5b\x92\x38\x1d\xc4\xfc\x65\x7c\xbe"
+  "\xf8\xb6\xe3\x5d\x19\xe6\x05\x8e\xf9\x62\x33\xd3\xdd\x88\xb7\x52"
+  "\x36\x26\x34\xc7\x39\xd5\xd9\xc2\xce\x99\x76\xe0\x5c\x9f\x59\x8d"
+  "\xdf\xca\x45\xff\x5b\x88\x8b\xf3\xce\xf8\xff\xf6\x12\xd6\x13\xf7"
+  "\xfc\xda\x7d\x6b\xe2\x40\xdf\xc6\x23\x9d\xe1\x37\x3a\xe8\x0b\xee"
+  "\xce\xc5\xa2\x2e\x64\xb1\xe0\xe0\x9b\xcd\x92\x2e\x84\xf1\x05\xe8"
+  "\x85\x4b\xc7\xd9\xb8\x13\xec\x69\xa3\x80\xf6\xcc\xa5\x46\xc4\x0d"
+  "\xf4\xf5\x0a\x51\xc6\x82\xfe\xbc\xa4\x96\xd6\xbc\xec\x78\x6e\xe2"
+  "\x22\x5b\xef\xb5\x48\x31\xce\xb8\xbf\xbb\x4b\xb3\x1d\xe7\x2c\x2e"
+  "\x85\xf7\x3b\x67\x81\x67\x6c\xb6\xb3\x58\x58\xfb\x51\xa7\xd4\xb5"
+  "\xb7\xa2\x8e\x60\xbf\xc7\xb3\x17\xa9\x30\x26\xe7\xe7\x74\x5a\x71"
+  "\x7e\x9e\xc5\x0c\xc1\xba\xf0\xd8\x0d\x2d\xec\x7f\xc0\xad\x02\xef"
+  "\x1c\x4b\x97\xf6\xf6\xc6\xf1\x06\x7e\xe3\x5a\xdb\x61\xc5\xcf\x49"
+  "\xc5\x9d\xa8\xaf\x2f\x1d\xc7\x98\xd4\x90\xa7\x5a\x8a\x47\xcd\xe2"
+  "\x4f\xf3\xf6\x0c\xe8\x87\x87\xf9\x35\xbc\x87\x84\xe2\xb9\x7c\x3c"
+  "\xc7\xc6\x68\xa0\xf2\x57\xa2\xaf\x64\xf4\xfb\x58\xb1\x0e\x63\x9a"
+  "\x74\xfc\xbe\x60\x32\x3b\x0b\x6c\xa9\xb8\xa7\x03\xd7\x2d\xdb\xcf"
+  "\xa6\x30\x7f\x46\xca\x88\x64\x1b\xc5\xdf\x31\x7b\xc2\xcf\x1f\xf7"
+  "\x04\xb5\xb3\x58\x01\x58\xa6\xd7\x7e\x7f\x3b\x16\x89\xb6\x69\x3b"
+  "\xc8\xfd\x5b\xcf\x93\x0e\x66\xbb\xc3\xff\x93\xcf\x93\xce\x03\x3c"
+  "\x2e\x2a\xf7\x5d\x2f\xee\xc7\x1e\xcb\x7d\x59\x00\xcd\x98\x6f\x81"
+  "\xce\x3b\xb4\x77\x63\x0c\xe1\xce\x19\xcc\x8f\x74\x76\x55\x83\x48"
+  "\x83\x86\xcd\xbc\x5e\x01\x4b\x93\xe5\xac\x8e\x58\xbf\x61\xd6\xad"
+  "\x5d\x1c\x47\x8c\xed\xca\xe8\x0c\x95\x7c\x60\x70\x7b\x8a\xfb\x97"
+  "\xe6\xbc\xe8\xdc\x25\xda\xcf\x8d\xe2\xb7\x1b\x47\xfe\xed\xce\x38"
+  "\xb1\xcc\x7d\xdc\xc7\x76\x47\x20\x94\x0b\x7a\xa7\xb3\x5c\x1a\xcf"
+  "\x88\x67\x88\x42\xf8\x38\xab\xb3\xc1\x31\x9e\xe1\x34\x74\x39\xdf"
+  "\xb6\x6a\x55\xa2\x36\x76\xf9\x6a\x7d\x4c\xe2\xcb\x71\xda\x65\x09"
+  "\x09\xab\x12\xb4\xe8\xe4\xc8\xb9\xff\xf0\x38\x40\x9d\xad\x62\xcc"
+  "\xbc\x7d\x8e\x98\x79\x96\x10\xe7\x38\x93\x26\x62\x09\x1d\x9d\xb9"
+  "\x0b\xcb\x02\x77\xe5\x6c\x91\x0b\x65\x70\x95\xc3\x55\x01\x17\xda"
+  "\x18\x64\xa9\x95\x84\x83\xae\x67\x32\xcf\xe1\xdb\xc1\x82\x7e\x40"
+  "\xc3\x5b\x88\xe5\xed\x52\x41\x41\x98\xaf\x9e\x0c\x81\xf9\xda\xdc"
+  "\x0d\xbf\x87\xab\x02\xae\x6a\xb8\xd8\xef\x84\x4f\xd8\xb9\xf4\x32"
+  "\xe7\x77\x7c\xff\xc8\xfa\x5a\xcc\x43\x37\xe0\x10\x11\xf2\xe5\xf3"
+  "\x7c\x7d\xea\x20\xa7\x19\x17\xa2\xc5\x7c\x6c\x2c\xe9\xbf\x81\x68"
+  "\x07\xc8\xe7\x43\x33\x5a\xa3\xc4\x7c\x6c\xdf\xb1\xd4\x1e\xf4\xd5"
+  "\x0f\xf9\xa5\x7c\x0a\x9a\x71\xa9\x4d\xcc\xc7\xf6\xc8\x09\x19\xf2"
+  "\x81\xbe\x3b\x86\x66\xfc\x77\x9c\x98\x4f\xed\x5c\x9e\x53\x9e\xb1"
+  "\x42\xc6\x97\xe8\x13\xbf\x41\xd8\xa0\x08\xe4\xb6\x93\x65\x01\xe4"
+  "\x1f\xd0\xc7\xe9\xf0\xf8\x74\xd9\xd2\x97\x4f\xfa\x97\x97\x2f\x7b"
+  "\x64\xf9\xca\x24\x8c\xd4\x94\xb8\x6a\x4d\x22\xde\x57\xc6\xfc\x8e"
+  "\xdd\x56\x2d\x7d\xe5\x65\xfe\x4f\x62\x7c\x28\xfe\x13\x0f\x78\xc3"
+  "\x7b\xec\x1a\x3d\xde\x5e\x5e\x85\x8f\xc9\x71\x21\x6b\x5e\x96\xc2"
+  "\xd3\x3b\xe3\x50\xd7\x95\x71\xa5\x04\xb0\x61\xe0\x72\xf6\x0a\xe8"
+  "\xc5\xaf\xd9\x7e\x2f\x8c\x47\x54\xa5\xb3\x11\x69\x5e\xcb\xd5\xb7"
+  "\xc7\x95\xbf\xa1\x6f\x8f\x80\x0d\xfa\x97\x03\x6c\xcb\x97\x81\xce"
+  "\x28\x81\xdf\xb6\x9a\xc8\xab\x56\x51\x36\x9a\x98\x9f\xd0\x8c\x2b"
+  "\xb3\xc5\xbd\x9d\x0a\x21\xbb\x0a\xf7\x7c\xef\x80\x67\x16\xfb\x19"
+  "\x9e\x2b\xe0\xb9\x19\x9e\x31\xe6\x73\x20\x3c\x97\xe0\x9c\x14\x3c"
+  "\x6b\xe0\x39\x48\xc8\x2e\xdf\x87\x67\x79\xe1\x59\x0b\xcf\xc1\x5d"
+  "\x19\x5d\x73\xa5\x7e\x31\xb0\xad\xdc\x15\x2b\xc5\xa3\xe6\xb1\xa7"
+  "\xbb\x12\x7b\x63\x4f\x63\x3c\xa4\x54\x75\x14\xd3\xbf\xcc\x06\xe9"
+  "\xda\xe1\xa3\x99\x86\x65\xee\x90\xf4\x25\x9f\xef\xe8\xda\x27\xf9"
+  "\x29\xe1\xf3\x19\x5d\xe5\x4e\x31\xbc\xf1\xb9\x5a\x8a\xe1\x8d\xf3"
+  "\x5d\x2c\x86\x20\xdc\x69\x06\xfa\x63\xa5\xfb\x06\x9c\xcb\x63\xb1"
+  "\x27\xad\xb3\xd0\xb7\xad\x39\x2d\x56\x76\x57\x29\xce\xa1\xc1\x33"
+  "\xf7\xcd\x48\x2f\x92\x2e\xe6\x6b\x44\xf2\xdb\xe6\xec\xb3\x61\xc0"
+  "\xf3\x50\x9f\x82\xcd\xc0\xe2\x45\xc5\xaf\x0a\xb0\xc5\x2c\xe3\x76"
+  "\xa0\x35\x97\xcb\xaf\x1a\x03\xb7\x17\xac\xc9\xf4\x19\x1e\x53\xc4"
+  "\x44\xac\x36\x1c\xb3\x04\xc8\xe2\x57\x51\xf8\x6d\x40\x72\xcc\x32"
+  "\x96\x06\xf9\x36\x82\xad\x26\xd6\xef\x45\x63\x10\x9e\x25\x15\x44"
+  "\x5f\x14\xd6\xa8\x25\xd3\xd2\xf1\x3b\x4a\x66\x87\x7c\x4a\x54\x18"
+  "\x03\x12\xeb\x56\xea\xe4\x57\x6e\x33\xa4\xe1\x1e\xd2\xce\x67\x88"
+  "\x0a\xfd\xe8\x8a\x75\x89\xe2\xf1\xb7\xac\x16\xc9\xa7\x13\x7c\x2f"
+  "\xaa\x6f\x7b\x9e\xf9\x15\x43\xe5\x8c\x97\x43\x16\xcd\x83\xff\x42"
+  "\xc4\x30\xca\xce\xd8\x0c\xea\x1c\x5f\x17\xdd\xf9\xa7\x15\x4f\xf2"
+  "\x58\x99\x57\x61\xfc\xdf\xd5\xc6\xf6\xb0\xe0\xb8\xa4\x2b\x72\x07"
+  "\xdf\x83\x7a\x75\x3d\xfa\xad\x15\x32\xd0\x9e\xc4\xf3\xc9\x57\xe3"
+  "\x11\xb3\x54\x59\xb3\x65\xf7\x7a\xf4\x91\x2c\x03\x1a\x5f\x8d\xc1"
+  "\x77\xa2\x6f\x2c\x39\xf3\x25\x65\x27\x1a\x76\x16\x17\x6c\x14\x3c"
+  "\x83\x7a\x96\xd8\x56\xa0\xdd\x81\xf3\x49\x42\xc6\x55\x25\xe2\x16"
+  "\x78\x8c\xbe\x3a\x2c\x74\x7c\x55\x3a\xf5\xad\x9d\x8d\x38\x46\x5b"
+  "\xd7\xa8\x46\x9a\x5d\x6d\x84\xef\x3e\x01\xd7\xaf\x79\xec\x96\x17"
+  "\xda\xa4\x32\xd1\x7f\x19\xd8\x50\x25\x70\x57\x43\xbd\x6d\x4e\x31"
+  "\xed\xc4\xb3\xc7\xdd\xd3\xd0\xaf\x1a\x96\xcd\x6d\x67\xdb\xf3\xdc"
+  "\x06\xe9\xd6\x99\x48\xc0\x16\xde\x17\xbb\xc1\xfe\xc9\xda\x27\xfe"
+  "\x0f\xf6\xcf\x7d\x8b\xfa\x94\x91\x23\xcd\x95\x72\x4c\x77\xc7\x02"
+  "\x46\x9f\x80\xeb\xd7\x90\x5f\x2f\xc5\x6d\xdf\x28\x67\xe7\x24\xcf"
+  "\xfa\x68\xf0\x5c\x79\x77\xb6\x94\x3e\x46\x16\x0e\x34\xed\xde\x21"
+  "\xf5\xfd\xce\xf1\x35\x89\xf0\xbc\x4f\x9a\x63\xe1\x73\x2e\xdd\xe5"
+  "\x4e\xcf\xe9\xf0\x5c\x2d\x3d\xc3\xff\x8d\x92\xac\xc0\x71\x62\x27"
+  "\x8c\x25\x71\xdc\xf9\xb2\x06\xec\x42\x0d\x8e\xf3\xba\x81\xff\x59"
+  "\x71\x3c\x6f\x0f\xd8\xa0\x39\xc1\xe2\xff\x2a\x93\xbc\x28\x48\x6a"
+  "\x8b\x90\xe1\x13\xc0\xdb\x63\x9b\x2b\xe4\x5c\xa9\x36\xfb\x56\x85"
+  "\x43\x1e\xd0\xff\x5d\xbc\xbd\x49\x17\xf6\x18\xba\xd5\x8b\x71\xc7"
+  "\x63\xc5\x2b\x88\x2f\x1b\xdb\x87\x95\xbb\x4e\xbd\x08\x6d\x4c\xf4"
+  "\xad\xc1\xfc\xe0\xa1\x2f\x48\x1b\x19\xcb\xfc\xef\xe7\x5c\x29\x67"
+  "\x7e\xe7\x5f\xd7\xa9\x24\x3f\x90\x20\x5b\x66\x53\x79\x7c\x20\xfa"
+  "\x86\x64\x71\x36\xba\x74\xfe\xcc\x1f\xa4\xe8\x07\x72\x57\x12\x09"
+  "\x2c\x11\xb8\x1f\x48\xe6\x77\x63\x2c\x8c\x49\x92\x06\xf6\x05\x49"
+  "\x33\xfe\x7c\x48\xf2\x05\x49\xaf\xd8\xad\xf0\x7f\x30\xb4\x1d\xe3"
+  "\x8f\xeb\xd8\xb3\xc3\x87\x93\x62\x40\xdf\x90\x72\x90\x71\x72\xee"
+  "\x1b\x72\x78\xba\xc1\xa6\xe6\x38\xb1\x2d\x92\xe2\xca\x3b\xa5\x81"
+  "\xfc\xb3\x8a\xb1\xb1\xba\x83\xc4\xb4\x64\x13\xf9\xfd\x21\x71\x7f"
+  "\xa5\x19\xe7\xc8\x0a\xd9\x3c\xd8\xd5\x3d\xb4\x27\x6e\xe7\x40\xf2"
+  "\xa5\xc3\x5f\x9d\xde\xc1\x7c\x3e\xd8\x80\xf7\x76\xc6\x27\x3e\x6e"
+  "\xb4\x95\xf7\xed\xc3\x2f\xbd\xbc\x2a\x76\xd9\xd2\xdf\xae\xd0\x6b"
+  "\x9f\x59\xfc\x04\x0b\x2a\x18\xa2\x5d\x9e\xb8\x8c\xa9\x1f\xed\x33"
+  "\xf3\x1e\x8f\x88\x58\xbc\xf4\x57\x8b\x1f\x5b\xfc\xec\xaf\x1e\xe5"
+  "\xa7\x13\x17\x27\xac\xc5\xc0\x94\x89\xab\xb4\xf8\xa3\x97\xc4\x68"
+  "\xd6\xeb\x96\x25\xac\xea\xdb\xf7\x03\xd9\x9c\x96\x9c\xcd\xdf\x5a"
+  "\xf0\x7f\x3e\x6f\x66\x5f\x2c\xcd\x67\x71\x39\x67\x9f\x87\xb4\x65"
+  "\x71\x42\x33\x6c\xb5\x68\x4b\x89\x71\xc6\x51\xc7\x28\xb0\xff\xa2"
+  "\xae\xe9\xca\xb0\xa7\x3b\xfb\xbb\x12\x7f\xbb\x57\x8e\xbf\x13\xfb"
+  "\xad\x98\xf6\x3e\x9d\x3a\x35\x8d\xfb\xac\xb2\x1f\x94\xe6\xb8\x31"
+  "\x4d\xaa\x43\x0b\xe6\xc9\xb0\xd9\x1d\xf1\x6c\xed\xcd\x8e\x98\x8d"
+  "\xec\xcf\x85\x46\x84\xa0\xe9\x32\x06\xec\x92\xb1\x70\x8d\xc3\x6b"
+  "\x7e\xaf\x2c\x4f\xa2\x4d\x38\x3e\x0b\x90\x81\xbe\x4d\xf6\xe1\x31"
+  "\x9f\xb2\x1a\x59\x9c\x82\x08\xbb\xcd\x67\xa9\x5d\x0e\x77\x1f\xba"
+  "\xd4\xae\x60\x63\x42\x9a\x44\x1b\xd9\xb9\xfa\x24\xda\x80\xb1\xcd"
+  "\x00\xc7\xd9\x11\xb6\xd4\xec\x08\x3b\xb5\x2d\x05\x5b\x1d\xee\xdf"
+  "\xe0\xf9\xf0\x08\xfb\x37\x94\xc5\x77\xc1\x73\xf4\xdc\x77\x5f\x35"
+  "\xee\x97\x5c\x02\x18\x2e\xed\xe0\x31\x71\x23\xd6\x7e\x7b\x6a\xe9"
+  "\x5a\x13\x8f\x89\x7b\x91\xc7\x91\xe6\xb1\xb6\x49\x2a\x94\x73\x64"
+  "\xa9\xdd\x47\x1b\x61\xef\xa1\xfc\x8c\xab\x50\x31\x58\x9c\x5b\x94"
+  "\xa7\xab\xa7\x10\x39\xce\xad\xd8\x4b\xa3\x2a\xd0\x4f\x5f\x9a\x99"
+  "\x5a\xd1\xdf\xcb\x47\xdd\x4d\x72\x6d\x12\xc6\x01\x13\xce\xd4\xeb"
+  "\x43\x07\x3e\xe3\x9c\x75\x62\x3f\xcd\xdd\xba\x98\x66\x35\xa7\xc0"
+  "\xbd\x91\x66\xd7\xe2\xb8\x57\x46\xb3\x4e\x2d\xa0\xb9\xf9\x90\xde"
+  "\x12\x04\xf7\x46\x9a\xd5\xda\x4e\x73\x0b\xe0\xf9\x9b\x43\x70\x87"
+  "\xe7\x4f\x32\x21\xff\x22\x9a\x75\x18\x7f\xd7\x40\xb3\x2a\x13\x21"
+  "\x1f\x3c\x57\xc5\xc3\x1d\x9e\xff\x1e\x0b\xf9\xe0\xf9\x1f\x51\x67"
+  "\x09\x2d\x83\xff\x21\xed\xbc\x81\x7f\xeb\x82\x81\x7d\x2b\xcb\x6c"
+  "\xe0\xdf\xe8\x34\xf0\x6f\x5c\x31\xf0\x6f\x5c\x35\xf0\x6f\x54\x2f"
+  "\x86\x7c\x91\x34\xeb\x48\x25\xdc\x9b\x68\x56\xcd\x6c\xc8\x07\xcf"
+  "\xb5\x7b\xe1\x0e\xcf\xf5\x81\x90\x0f\x9e\x8d\x50\x97\x02\x78\x6e"
+  "\xb0\x40\xbe\x28\x9a\xf5\x69\x1c\xdc\x9b\x69\xd6\x67\xcd\x90\x0f"
+  "\x9e\x8f\x2f\x82\x3b\x3c\x7f\x0e\xe5\x14\xc0\x73\x53\x18\xdc\xe1"
+  "\xd9\x86\xf5\x88\xa6\x59\x02\x94\xbb\xd5\x44\xb3\x28\xe6\x8f\xa6"
+  "\x9b\x64\x50\x5e\xbe\x89\x6e\xf2\x09\x81\x7c\xf0\xac\x68\x84\x3b"
+  "\x3c\x8f\xc5\xb6\xc6\xd2\x4d\x4a\x1d\xdc\x5b\xe9\x26\x5f\x48\xcf"
+  "\x87\xe7\x09\xe9\x70\x87\x67\x3f\xcc\x0f\xcf\xfe\x4d\x70\x87\x67"
+  "\x35\xd2\x28\x8e\x6e\x9a\xd4\x0a\xf7\x36\xba\xe9\x96\xb9\x90\x0f"
+  "\x9e\x6f\xc5\xfa\xc3\xf3\x54\x05\xe4\x83\xe7\x20\xa4\x15\x3c\x4f"
+  "\xc7\x76\xc6\xd3\x4d\x77\x60\xf9\xed\x74\xd3\x5d\x48\x17\x78\x9e"
+  "\x61\x86\x3b\x3c\xeb\x80\x1e\x05\xf0\x7c\x77\x39\xdc\xdb\x07\xe4"
+  "\xe7\xa6\x59\x5b\xe8\x86\xb1\x84\x6e\x7a\x48\x4b\x37\x8c\x83\xfb"
+  "\xff\x02\x5b\x7a\x8c\x8e\x6e\xfa\x49\x28\xa4\xc3\x3d\x6c\x1f\x3c"
+  "\x87\x88\xcf\x70\x7f\x38\x1d\x9e\x43\xc5\x67\xb8\x3f\x12\x09\xcf"
+  "\xb3\xc5\x67\xb8\xcf\x31\xc1\x73\x18\xdd\xf4\x68\x39\x3c\xe3\x1d"
+  "\x6c\xed\x31\x73\xc4\x67\xb8\xff\x2c\x05\xee\x36\xf3\xb4\x28\x8d"
+  "\xd9\x2f\xba\xc1\xec\xb7\x0d\xed\x01\x62\xcf\xdb\xba\x48\xf0\xdf"
+  "\x8a\x7b\xd0\xc7\xa6\x5d\x26\xe3\xce\xca\xe4\xeb\x51\xa6\x18\x53"
+  "\x4c\x2c\x6e\x9e\xe8\x37\x72\x6c\x8b\x4c\xb6\x16\xec\xa1\x30\x90"
+  "\xe1\x72\x68\xb3\x81\x66\x8c\xe9\x80\xb6\xaa\x68\xc6\x84\x16\xb8"
+  "\xc3\xf3\xc4\x4f\xa1\xad\xf0\xfc\xd0\x26\xb8\xc3\xf3\x0b\x8f\xd3"
+  "\xdc\x42\x55\x57\x96\xac\xc9\x44\x28\x8f\x21\xfb\xa7\x15\xe1\x01"
+  "\xb6\x34\x1a\x61\x03\xdd\xb1\xb3\x04\x64\x7f\x34\xa1\xb9\xdb\x4c"
+  "\x01\x18\xdf\x62\x57\x54\x24\xf5\x8f\x61\x75\xc2\x18\x36\xb4\x27"
+  "\x58\xce\xbf\x3d\x81\xb6\xc8\xe4\x63\x30\xd6\x02\xf5\x5f\xeb\xee"
+  "\xfd\x0c\xf6\x7e\x6a\x89\x9a\xbf\x57\x12\xc7\xfb\x17\xf0\xfd\xbc"
+  "\x00\xf4\x59\x3e\x7d\x31\x7b\x6f\xb4\xb4\x89\xed\xf2\xc1\x77\x31"
+  "\x98\xd7\x24\x93\xf3\xf3\x02\x32\x59\x36\xcd\xf0\x21\x9d\xca\xda"
+  "\x45\x5d\x59\xf2\x42\x13\x11\x6a\x45\x7b\xbd\x90\x2a\xab\x76\x70"
+  "\xbf\x21\xc6\x01\xfd\x5b\xe1\x78\x55\x30\x14\x85\xe5\x82\x1c\xc4"
+  "\x31\x30\xe8\x43\xb9\x36\x35\xb8\xbc\x45\xa6\x88\xde\xc5\xe6\x36"
+  "\x8a\x9b\x98\x7c\x94\xf9\xcc\xe8\xd9\x54\x9b\xa9\x5d\x17\x00\xdf"
+  "\x57\xc4\xa4\x59\xe9\xe5\x8a\xd4\xc7\xc9\x59\x9e\x5e\xc1\xce\x0b"
+  "\xf1\xff\xf7\xb3\x7d\xa0\xfc\xff\x1d\x6c\xce\x19\xca\xc2\xdf\x3a"
+  "\x8f\x39\xec\x59\x3f\x36\x0b\xfe\xc5\x26\xb6\x8e\x2e\xf3\x99\xf9"
+  "\x81\x60\x92\x07\x24\x92\x31\xda\x75\x1f\x41\xf9\x3e\x7a\x97\xf1"
+  "\x69\x6f\x5e\xf6\xee\xd9\x0f\x21\x6f\x31\xce\x25\x65\xf9\xa4\xf7"
+  "\xc6\x23\x86\x36\xbc\x89\xba\x50\x4e\xc2\x51\x3f\x33\x7b\x57\xa6"
+  "\x60\x7e\x66\x6d\xaa\x6d\x15\x36\x43\x74\x85\xdd\x50\xdc\x44\xf3"
+  "\x8a\x4d\xfe\x36\x19\x61\xfb\xf5\x65\x8a\x07\xef\xb5\xa2\x7d\x79"
+  "\x14\xdb\x77\x41\x18\xfb\x60\xd9\x3d\xc9\x44\x5e\x91\xf0\x25\xfe"
+  "\x76\x16\xcd\xfa\x49\xa4\xb1\xbd\x89\x54\x24\xb0\xb2\x42\x68\xd6"
+  "\x93\x73\x84\xb1\x8f\x05\x96\xa2\x9d\x9e\x8c\xf3\x6c\x9f\xe2\xef"
+  "\xfe\x0a\x7c\x51\x74\x65\x29\x54\xbd\xb1\xb2\x81\x96\xb9\x40\x3b"
+  "\xb4\xa1\xd1\xf7\xc5\x52\xbb\x1d\x7d\xb6\x65\x9b\x80\x0e\x9c\x5f"
+  "\x3e\x66\x8c\x33\xce\xbf\xab\x98\x27\x8c\xaf\xd5\xd7\x47\xe1\x9a"
+  "\xa1\x12\x7d\x60\x5d\x66\xe7\xe5\x6d\x18\x3f\x10\x74\x8f\x98\xd7"
+  "\x99\x77\x2b\x5e\xd6\x2f\x5d\xa7\x5f\x95\x90\xb8\x74\x8d\xfe\x11"
+  "\x2d\x0c\x1c\xb5\xab\x5e\xd1\xae\x58\xb6\x62\x55\xc2\xda\x7e\x7e"
+  "\x77\xa0\x5e\x7b\x01\x27\x6c\x3f\xfc\x11\xb0\xdf\xd9\xfc\xbd\x6c"
+  "\x6c\x22\xf2\x7a\xe7\x76\x1e\xaf\x02\xf2\x80\xfd\x17\xc7\xc6\x47"
+  "\xc2\x8e\x62\x2b\x2d\x89\x8a\xcc\x41\x9f\x1f\x6b\x30\x1e\x82\x99"
+  "\x18\x49\x07\x8f\x61\xcb\xe2\xd3\xc1\x78\x22\x69\x3d\xad\x48\xea"
+  "\xc0\x7e\x00\xb2\xa8\xb0\x0d\xfa\xc1\x9e\xab\xb9\x31\x61\x2d\xb2"
+  "\xb1\x91\x57\x73\x0b\x9b\xa4\xf8\x42\x76\xc3\xb6\x30\x41\x55\xb4"
+  "\x08\xe3\x0b\xf5\x50\x0d\xa9\x03\x5a\x76\x67\xd7\x46\x81\x1e\x88"
+  "\xdc\x95\x41\xcb\xed\x30\xbe\x62\xbe\x7d\xfe\xb4\x42\x6b\xa7\x3a"
+  "\x85\x3d\x83\x28\xe1\xee\x4f\xfd\x8b\xd3\x7b\x54\xdb\x1a\xf0\x3d"
+  "\xc6\x15\xb2\xf7\xe8\x48\x6a\x23\x15\x7e\x13\x07\xb8\xc9\x20\x94"
+  "\xc5\x51\x8d\xbb\x40\x20\x7d\xbc\x90\xb7\x2d\xfa\xec\x7c\x22\xc7"
+  "\xbc\x60\xef\x91\x28\xf8\x3f\x25\x86\xf8\x41\xbe\x80\x94\x23\x90"
+  "\xde\xa5\x1b\x6f\x4b\xd3\x29\xbb\xd3\x74\xe3\x7b\xa8\x4e\x65\x6c"
+  "\xb5\x92\x9e\x19\x2b\x42\x67\x99\x89\x62\x27\xd8\x85\xbb\x04\xe8"
+  "\x83\x25\x51\xe1\xf6\x37\x74\x63\x6d\x6f\xe8\x14\x3d\x3d\x3a\xa5"
+  "\xed\x75\x9d\xa2\xfb\x75\xdd\xd8\x9e\x2e\x9d\xd2\x18\x6b\x26\x47"
+  "\xcd\xff\x45\xea\x5b\xdb\xd8\x1c\x6f\x8f\x5f\xb1\xa1\xc7\x6f\x5b"
+  "\xbc\xaa\x95\x04\xde\xa3\x07\xbb\x10\x6c\xe3\x22\x18\x17\x00\x26"
+  "\x54\xb6\x3f\xae\xd0\xd2\xdc\xe2\x50\xa0\xef\xa3\xf3\x66\xd2\x6f"
+  "\xed\x59\x13\x94\xda\xa7\x40\x5e\x6d\x50\x68\x20\x0d\xf0\x73\x6b"
+  "\x32\xcd\xfa\x41\x05\xdd\xa0\x08\x82\x4b\x6b\xe2\x7c\x20\x34\xcb"
+  "\xf7\x10\xce\x31\x60\x5e\x9e\x4f\xad\x32\xb1\xbb\x2a\x8a\xc5\x3b"
+  "\xcd\x52\xc4\xef\x42\x9b\x24\x6b\xac\x5e\xb2\x49\x2a\x15\x03\xfb"
+  "\x15\x81\x3c\x85\xbd\xe3\x75\x01\x64\x4e\xee\xd6\x70\xb7\xbe\x77"
+  "\xf1\xdb\x79\x5b\xf5\x5b\x84\x5e\x1f\xca\x20\x33\xc7\x7e\x00\xfd"
+  "\x27\x9d\xbd\x33\x6c\x33\xa5\x5e\x22\x3e\xf8\xae\xec\x8a\x55\x8e"
+  "\xcf\xda\x04\x19\x35\x5a\xac\x04\x7e\xa3\xa0\x41\x51\x91\x65\x57"
+  "\xcc\x72\xc4\x4b\x3d\xa4\xc1\x6f\x8f\x6f\xb9\x22\x96\xbb\xa3\x84"
+  "\xa4\xbd\x46\x58\xcc\x10\x8c\x3b\x84\x38\xda\x92\x0a\xe3\x4d\x8c"
+  "\x91\x94\x80\x32\x6c\xdc\x44\xf8\x5f\x89\xf9\xa8\x6a\x9b\x49\x80"
+  "\x32\x00\x4f\xf3\xa9\xdf\xb6\x6a\x21\x77\xdb\x22\xc0\x94\x9a\x4e"
+  "\x8b\x2a\x17\x76\x16\xb7\x75\x65\x8d\x8b\x03\x7a\xa4\x4b\xf3\x17"
+  "\xf5\xfb\x6c\x04\x7d\x62\xd1\xc7\x6d\xa4\x2a\xf1\x32\xfa\xcd\xf5"
+  "\x31\xfb\xd6\x46\x9b\xfd\x8a\xc2\xcc\x7e\xc5\xa1\x42\x6e\x51\x3a"
+  "\x5c\x99\xfa\x04\xa2\x3a\x2f\x53\x86\xf4\xfa\x74\xbd\x74\x83\xf8"
+  "\x74\x05\x3b\x8f\xd9\x7b\x80\x1d\xb4\xdf\xa0\xbd\xe5\x18\xfb\x03"
+  "\xed\x3a\x94\xb9\x5d\x59\xca\xde\xf3\x2f\x28\x47\xec\x39\xb5\xf1"
+  "\x70\xc5\x41\xba\xde\x24\xbb\x6d\x87\x24\x63\xa8\x7f\xb4\x59\xd8"
+  "\xf4\x8b\xb9\x5d\x78\x9e\xaa\x27\xee\x67\x98\x17\xe8\x86\xbe\xe5"
+  "\x7c\xec\x3d\x71\x73\xe0\x7a\x14\xae\x9f\xda\x73\xb7\x55\xd8\x73"
+  "\x0b\x4d\xf6\xdc\x62\xb5\x3d\x37\xda\x02\x97\x15\x2e\x9b\x3d\x37"
+  "\x86\xc0\xa5\x80\x4b\x49\x73\x63\x54\x70\x87\xf7\x31\x81\x70\x69"
+  "\xe0\x0a\x82\x4b\x0b\x57\xb0\x7d\x67\xb1\x59\x00\x7c\xc2\xa5\x85"
+  "\x0b\xd2\x8b\x92\xe1\x9a\x3f\xb0\xcf\x93\xcb\x6d\x2c\xce\xc1\x98"
+  "\x53\x34\x00\xe3\xe0\xa6\x5c\x46\x9f\x8d\x6d\x55\x3a\xcb\xf0\xfc"
+  "\xbd\xcb\x7c\x83\xdd\xcd\x95\x60\xf9\xd0\xbf\x7a\x86\x59\x5e\xa2"
+  "\xdb\xb9\x17\x4d\xb1\xd5\x16\x14\xb5\xc7\x96\x41\xd2\xa1\x4f\xcb"
+  "\xea\xa3\x5b\x49\x84\x99\xa4\xd5\xb6\x76\x93\xb4\x58\xd1\x37\x7b"
+  "\x0a\x9e\x63\x89\x0f\x44\x1c\xdb\x69\xa4\xb6\xc7\x50\xd8\x66\x57"
+  "\x15\xa9\xa9\xaa\x68\x3e\xf3\x03\x09\xf2\x07\xe3\x8a\xf5\x8e\x4b"
+  "\x11\x57\x30\x36\xad\x6b\xbf\x4c\xde\x88\xa5\x42\x5d\x1c\xd8\x26"
+  "\x4d\x00\x30\x19\x79\x0b\x31\x26\x8d\x4d\xff\xa3\x99\xa6\x03\x5e"
+  "\x7c\xed\x40\x37\x01\xc7\xa4\x80\x2d\x1c\x9f\x4a\xf8\x02\x7d\xa6"
+  "\x96\x62\x31\xd1\xb1\xbe\x4a\x78\xa7\xc0\x58\x4d\x25\x30\x26\x2d"
+  "\x49\x22\xc1\x25\xf0\x8e\xc5\xd5\x84\x7a\x3f\xad\x0f\xa0\xc2\xef"
+  "\x74\xa4\xf4\xb7\x44\xe9\x77\x81\xc7\x6a\xb5\x03\xed\x7b\xe3\x15"
+  "\x18\x62\xc2\x16\x5e\xd0\x92\x2a\xdd\x49\xd0\x4b\x65\x20\xbf\x63"
+  "\xc2\x7a\x40\x76\x03\x2d\xed\xc3\xa3\xe5\xf8\x8a\x6b\x45\xcb\x9e"
+  "\xa0\xa8\x70\x4e\xcf\x68\x82\x34\xeb\x4b\x4f\xa4\xf1\xba\x56\xa0"
+  "\x27\xd0\xd5\xd8\x68\x27\xfe\x32\x12\x23\xd1\xb3\x18\xe8\x09\x34"
+  "\xd5\x20\x4d\x81\x1e\x8c\xa6\x54\xa4\x69\xa9\x13\x4d\x41\x3e\x31"
+  "\x9f\x99\x48\x53\x01\x68\x5a\xea\x86\xa6\xbd\xe3\x7b\xa0\xe9\x6e"
+  "\x8f\x68\xba\x6f\x04\x34\x55\xf5\x5b\x6f\x90\x68\x6a\x43\x9d\x99"
+  "\x17\x13\x4a\x41\xe6\x19\x6d\x47\x99\xff\x57\xb0\x77\x32\xc1\x6e"
+  "\x4b\x17\x54\xdb\xc2\x80\x26\x2a\xdc\x13\x80\xb1\xc1\xd2\x92\xe9"
+  "\xe9\xb4\x7d\xf4\xaa\x3d\xaf\x78\x0b\xa6\x81\xec\x8a\xbb\x17\xfd"
+  "\xdd\xe9\x4d\xa4\x54\x4e\xcb\xeb\xaf\x58\x40\xc7\x04\x2c\xec\x46"
+  "\x9b\x33\xaf\xd8\x28\xd0\x38\x82\x72\x64\xc9\x4c\xa2\xe8\x06\x59"
+  "\xa1\x4f\x22\xb7\x6f\x01\x79\xd7\x0d\xf2\xf3\xbc\x4c\xd5\x36\x4f"
+  "\x2f\x50\xb8\xd2\xd0\x8f\xa9\xe0\x57\x94\x4e\x77\x70\xfe\x22\xcf"
+  "\x70\xad\xb1\x6e\xc9\x27\x50\x9e\xdf\x89\x9a\x68\x1b\x49\x8b\xeb"
+  "\xcf\x5f\x21\x2d\x52\x6b\x37\x0c\xdd\x4f\x30\x3e\x61\x4a\x1b\xf2"
+  "\xb5\x8c\x18\x5b\x1d\xfd\x44\x78\x9d\xcb\x61\xe4\x05\xf6\x0b\xec"
+  "\x23\x9b\x9d\xe4\x2f\xc8\x76\xf5\x2e\x31\x5e\x87\x1d\xe4\xef\x2e"
+  "\x8c\x3f\x00\xbc\xc4\x38\x1e\x03\xf6\x8f\x37\xa0\x7f\xac\x63\xb1"
+  "\x94\x34\x40\x8f\xb2\xee\x2e\xce\x43\xe4\x99\xd1\x56\xcd\xf8\xb7"
+  "\x45\x94\xf7\x9c\xee\x45\xff\x41\x69\x24\xb1\x43\xdd\x85\xbc\xe2"
+  "\x74\xda\x15\x37\x1e\xe7\x25\x61\xfc\x1c\x1a\x10\x0b\xb6\xc3\xb7"
+  "\xa0\x0f\x56\x02\xbe\x2e\x92\xe0\xdd\x2b\xc1\x1e\xe8\xc2\x98\x68"
+  "\x50\x9f\xb5\x3c\x96\xac\x90\xe5\x1b\x0f\xef\x98\x5f\x56\x41\xf2"
+  "\xcb\xda\xa9\xc3\x71\xbf\x63\xbe\x68\x95\x4e\xee\xf8\xe6\xb1\x74"
+  "\xbb\xb2\xa7\x9c\x9d\xad\x97\xf9\xbf\xc5\xd7\xb2\xff\xdf\x7d\x48"
+  "\xd7\x76\x99\x3f\xf7\x47\x9f\x7d\x68\xbf\x3e\x95\x8c\x3b\x2f\xf3"
+  "\xcf\xa1\x9b\x2a\xf7\xe8\x31\x2e\xb6\xf4\x2e\x2d\x12\xe9\xb0\xef"
+  "\x9e\x74\x92\x6e\xcf\xe9\x69\x32\x26\x5f\x40\x3f\x87\xc3\x94\xbd"
+  "\xfe\x7b\xb0\x2c\x7b\xf6\xb1\x4c\xa0\x53\xb8\xb0\xe9\x98\x01\x64"
+  "\x4a\x28\xfd\x1d\xb4\xf5\xb7\xd0\xd6\xf3\x40\xd7\xf3\xd0\xd6\xd7"
+  "\xc5\xb6\x8a\x71\xe2\x04\xa0\x3f\xbc\x1b\x58\xff\x49\x6d\xfd\x1d"
+  "\xfa\x34\x3f\x98\xbc\xfe\x02\xf9\x01\xbd\x13\xd7\x77\xd9\xd9\xc7"
+  "\x2e\xa3\xed\x24\xc1\xef\x32\xfd\x6c\x88\x51\x3e\x0b\x78\x44\x9a"
+  "\x83\x4d\xa0\xa7\xfe\xdb\xa2\x25\x3e\x60\x7d\x68\x4f\xdc\xf8\xd2"
+  "\x95\x50\x1f\xa4\xfd\x45\x82\xf1\x24\x02\x81\xf6\xc1\xa5\x48\x7f"
+  "\xd7\x58\xcd\x81\x8c\x07\x63\x81\x07\x2b\x45\x1e\xe4\x88\x3c\x00"
+  "\x5b\x11\x74\x35\xce\x71\x68\x4a\x33\x38\x0f\x86\x47\xa3\x80\xca"
+  "\x51\xee\xaf\x85\xee\xfb\xeb\x0f\x64\xdd\x7c\x0c\x29\x43\xff\xb0"
+  "\x60\x1f\x7f\x26\xf4\x40\xbf\xcd\x13\xfb\x2d\x8d\xfb\xa9\xd4\x67"
+  "\xcf\xca\xd4\xbb\x3c\xeb\xb3\x13\x73\xff\x4d\xfb\x6c\xe0\xb5\xed"
+  "\xb3\x93\x9e\x75\xed\xb3\x93\xb2\x5d\xfb\xec\xa4\x47\x1d\x7d\x56"
+  "\x7c\x37\x2a\x7d\x76\xd2\xe2\xef\xa6\xcf\x4e\x5a\x3c\x40\x9f\x4d"
+  "\xf4\xa0\xcf\x6a\xdc\xf4\x59\xcd\xb5\xeb\xb3\x3f\x48\xbe\x7e\x3a"
+  "\x76\xf2\xfb\xdd\xf2\x01\x74\xec\x1b\x4e\x3a\xd6\x0f\x75\x6c\xe0"
+  "\x82\x81\xfa\x6b\x4f\x09\xf4\x57\x95\xd8\x5f\x7f\xf3\x3f\x50\xde"
+  "\x2d\xf3\x8e\x36\x0f\xdd\x5f\x6d\x25\x0e\xfb\xc9\x6d\x9f\x8d\xc3"
+  "\x3e\xbb\x8f\x18\x4d\xac\xcf\xc6\x48\x7d\xb6\x44\x1c\xef\x0c\xd2"
+  "\x6f\x03\xdd\xf5\x5b\x8c\x9d\x85\x71\xb3\x06\xed\xb7\xa2\xbd\xd4"
+  "\x33\x0d\xfb\x6d\xc5\x0d\xa6\x6b\x27\xfb\xb9\xf6\xdb\xc9\xe1\xae"
+  "\xfd\xf6\x96\xcb\x8e\x7e\x2b\xbe\x1b\x95\x7e\x3b\x59\xf5\xdd\xf4"
+  "\xdb\xc9\xaa\xef\x8f\xae\xbd\xd5\xed\x5e\x99\xd1\xd7\xb5\x53\xd7"
+  "\xb0\x7e\xeb\x4e\xd7\xa6\x89\xba\xd6\x0f\x75\xad\xc6\xd7\xb3\xbe"
+  "\x3b\x45\xf6\x6f\xde\x77\xaf\xb1\xce\x9d\x72\xc4\xb5\xef\x4e\xb1"
+  "\xb9\xf6\xdd\x29\x7f\x75\xf4\x5d\xf1\xdd\xa8\xf4\xdd\x29\xd5\xdf"
+  "\x4d\xdf\x9d\x52\xfd\xfd\xd1\xb9\x53\xdb\xdd\xf5\x5d\xed\x74\x92"
+  "\xde\x22\xbb\x6d\x9e\xb1\x84\xed\xc1\x4b\x37\xda\x1e\x21\x6c\xdf"
+  "\x8a\xec\xb6\x15\x46\x4d\x18\x11\x36\xd5\x36\x61\xfc\x13\xdc\x3f"
+  "\x53\xe0\xb4\x3f\x85\xad\xe9\xca\x6e\xcb\x95\xf6\xd7\xec\x16\x63"
+  "\xa4\x0c\xb6\xbf\x86\x66\xd7\xc6\x89\xbf\xab\xe6\xd8\xa8\x8d\x97"
+  "\x9e\x99\x2f\x19\xd9\x6d\xb5\x34\xa7\x36\xd6\xec\x5b\x1b\xeb\x6e"
+  "\x9d\xc4\x7f\x03\xa5\xb8\xa7\xa4\x73\x7a\x7c\x43\xe7\x26\x42\xb6"
+  "\xb0\x35\x88\x20\x05\xfc\x96\xc5\xaf\xe9\xf4\x57\x97\x75\x66\x2c"
+  "\x22\x90\xa6\x91\xd2\x58\xbc\xea\x0c\x1f\x2a\xc0\x3b\x90\x21\x25"
+  "\xbb\x53\x89\x12\xfd\x1c\xdf\x73\x05\xb1\x18\xa4\x03\x19\xc1\xf6"
+  "\x8b\xb0\x75\xfc\x5b\x6f\xb3\x94\x76\x10\x45\x7d\x26\xdb\x37\x87"
+  "\xfb\x72\xf6\xe4\x21\xfe\x7d\xee\xde\x41\xe5\x0a\x22\xec\x8a\xda"
+  "\x47\xfd\x8a\xb2\xd9\x3e\x62\xc0\x8a\xb4\x57\x07\x63\xf0\x09\xd3"
+  "\xa2\xe6\x4b\xbe\x76\x29\xd4\xef\xc3\x54\x3c\x67\xea\x43\x4b\x13"
+  "\x88\x1a\x2e\x15\xcd\x2d\xca\x86\x7a\x95\x49\xf3\x87\x6e\xf7\x84"
+  "\x63\xcc\xdd\xdb\x34\x0a\x71\x5f\x10\xfa\x1c\x60\xfb\xd6\x37\xcb"
+  "\x85\x6c\x3b\xa4\xd3\x8c\x34\x6a\x4c\xb6\x91\x00\xa0\x05\xae\xe1"
+  "\x63\xec\x2e\xa1\x34\xbe\x61\xe3\x54\x42\xde\x59\xd7\x26\xc7\xfd"
+  "\x1c\xf6\xff\xbc\xcd\x52\x91\x7a\x3f\xae\xf1\x33\x3f\xfd\x67\x65"
+  "\xd3\x0e\x44\x9c\xe3\xf1\x75\xe1\xff\xf7\x71\xed\x61\x21\x3c\xe3"
+  "\x1a\xb9\xd0\xa9\x51\x60\x5e\x48\x5f\x56\x91\xf4\x25\x09\xd0\xb3"
+  "\xbd\xf6\x4a\x31\xef\x6c\xcc\x6b\x92\x4d\x63\x7b\x14\xe0\x79\x3e"
+  "\xce\x97\xe3\x7e\x7c\x76\x6e\xa3\x24\x6a\x1f\x93\x0f\x86\xa2\x6c"
+  "\x68\x3f\xdb\xe3\x89\xed\xdc\x0c\x6d\x86\x3c\x2a\xdc\xaf\xc3\xee"
+  "\xa9\x44\x5d\x08\x69\x58\x0e\xdc\x55\x6c\xcf\xb0\x6c\x5a\x30\x96"
+  "\xed\xf6\xac\x81\xaa\x28\x9b\x02\xb6\xf9\xd9\x1b\xd9\xb1\x16\xd9"
+  "\x74\xe8\x2b\x94\xc2\x37\xe7\x6f\xc4\x79\x6c\xdc\xdf\x8d\x7b\xd6"
+  "\x65\xd3\xef\x83\xf2\x15\xbb\xd9\xbc\xed\x74\xf8\x46\xd0\xa1\xde"
+  "\xfd\x08\x6c\xad\x65\x7a\x1c\x7e\x07\x7f\x23\xe6\x67\x7b\x09\xb0"
+  "\xce\xda\x54\x1f\x0a\xcf\xbf\xe4\x7b\xc0\x95\xd1\xf0\xfb\x45\xbd"
+  "\x7b\xc0\xf9\xef\x00\x4b\xd3\x63\x81\x67\x4d\x6c\xff\x9b\x7c\xe0"
+  "\x39\x7f\xb6\x27\x59\xe4\x5b\x9d\x06\xb0\xd1\x97\x77\x12\x46\x00"
+  "\x17\x12\x46\xb0\xbe\xef\xa6\x9a\xe4\x4c\x1f\xc9\xa6\xb3\xf8\x13"
+  "\x79\xc0\x43\x7b\xb1\x46\xc1\xe6\xa6\x7b\x90\x2f\x2d\xf0\xee\xf6"
+  "\xb7\x91\x2f\x9b\x41\x17\x88\x79\x6b\x1d\xf5\xc7\xe7\xdb\x19\x3f"
+  "\x05\xe0\x05\xdb\xf3\x24\xbb\x7d\x3d\x8b\x93\x04\x32\x03\xf7\xaa"
+  "\x57\x82\xc5\x4d\x11\xb7\x80\x91\x77\x12\xac\xf2\xd2\x24\x9e\xfe"
+  "\x61\x87\x55\xbe\xf9\x3c\x41\xd9\x42\x72\x7f\x4b\x14\xa0\x87\x14"
+  "\x58\x26\x0d\x8a\x9a\x7f\xaf\xc4\xc7\x75\xc0\xbb\x24\xc0\x2e\xd0"
+  "\x7c\x33\xd0\xaf\xb4\x9b\xad\xd5\xcc\x2f\x15\x88\x4a\x80\x7c\x26"
+  "\xd9\xed\xe5\x50\x9e\x1a\x63\x82\xe2\x9e\x6a\xa0\x61\x62\x57\xd6"
+  "\xed\x85\x12\x0d\xb1\x4e\xb8\x27\x1a\xe3\x83\x42\x5e\x35\xc7\xd0"
+  "\x74\x93\xd4\x66\x77\xf4\xcc\x7d\x87\x04\xe5\xde\x43\xc2\x04\xe5"
+  "\xe5\x36\xea\x73\xdb\x1e\x9c\x6f\x7e\xba\x1d\x7d\x56\xb5\x91\x88"
+  "\xdf\x9f\xa2\x46\xb3\x9d\x08\xbe\x97\xdb\x70\x1d\xc2\xbe\xf1\xee"
+  "\x49\x11\x6b\x81\x5e\xa0\xef\xd3\xac\x44\x6d\x4c\x35\xf3\x78\x7e"
+  "\xe4\x12\xb1\xaf\x06\x19\x0e\x72\x1d\x74\xaa\x22\xed\x12\x99\x82"
+  "\xf4\x12\xfc\x0a\xdb\xce\xca\xb4\xcb\x9f\x4d\x24\xe9\xc3\x93\xa3"
+  "\x5a\x76\x7e\x13\xed\x0b\x90\xf9\x72\x16\xdf\xde\x0c\xf6\x49\x6e"
+  "\x61\xdb\x30\xcb\x71\x1b\x2f\x0b\xdb\x2d\xe0\x3c\xb4\xd8\xe6\x08"
+  "\x6c\xb3\xc5\x4a\x70\x2e\xff\xe9\xd7\xd0\x57\xf2\x65\x22\xe4\x5c"
+  "\x6e\xc3\x36\x83\xad\x13\x37\xfc\x39\x7d\xad\x75\xb0\x6f\x53\xa0"
+  "\xb7\xb0\xf1\xb6\x3d\x82\xaa\x28\x0e\xbf\x8d\x75\xc0\x73\x3e\x4f"
+  "\x5f\x26\x8c\xee\x48\x7f\xa3\xd5\x4e\xa8\xaf\x73\x1d\x6c\xc3\xac"
+  "\xc3\x1d\xee\xdb\x7f\x0f\x09\x32\xbc\xc3\xf9\x6e\xdf\x28\xd2\x20"
+  "\x0e\xd7\xc1\x8a\xe2\x30\x06\xe1\xd3\x58\x07\xf3\x05\xb2\xf0\x02"
+  "\x61\xfc\x37\xea\xda\x89\xdd\xe7\xee\x49\xb8\xe7\x00\xf9\x9f\x6a"
+  "\x03\xfe\x5f\xb1\xa2\x7f\x24\xb3\x31\xfd\x2a\x41\xfb\xc5\xd6\xa9"
+  "\x93\xf7\xe7\xff\x9d\xcb\x9f\x4d\x1e\x2e\xff\xef\x1c\x25\xfe\xdf"
+  "\x79\x03\xb4\xff\x2e\x2f\xda\x7f\xd7\x28\xb5\xff\xae\x1b\xa0\xfd"
+  "\xc1\x5e\xb4\x3f\x78\x94\xda\x1f\xec\xb6\xfd\x4f\x4c\x11\x28\xdb"
+  "\x8b\xe2\xbf\x75\x11\xea\x00\xae\xaf\x66\xc4\xe0\xbe\x13\x76\xae"
+  "\x4b\x7c\x26\xfc\x9c\x97\xb2\xcf\xb3\xaa\xcf\xb3\xba\xcf\x73\x60"
+  "\x9f\x67\x4d\x9f\xe7\x20\xe9\x19\xf4\xc8\x98\x8b\xb2\xe0\x63\x60"
+  "\x97\xa6\x9b\x64\x33\xe2\xc5\xf7\xc1\xe8\x3f\x0c\x74\x7a\xf0\x20"
+  "\x31\x25\x6f\x3b\x2f\x9b\xc1\xce\x69\xd3\x8d\x53\x75\x74\x5d\x3a"
+  "\x11\x0c\x31\x81\x4f\xaf\x07\xd9\x05\xfc\xa3\x3d\x9a\xb1\x60\x23"
+  "\xdc\x8a\x3e\xea\x70\xdf\x81\x36\x01\xf7\x93\xcc\xa8\xc2\xf6\xdd"
+  "\xa3\xaf\x20\x82\xcf\xdd\x6c\x3d\x5f\xc8\x8d\x09\x34\xfb\xdc\x3d"
+  "\x95\xee\x2c\x36\xe7\xc9\x05\x65\x5e\x86\xa0\x5d\x6f\xa6\xe6\x05"
+  "\xa0\x25\x23\x2e\xa3\xdf\x78\xe0\x71\x22\x35\x57\x24\x5c\x80\xfa"
+  "\xfe\x70\x56\x5d\x0a\x94\x0d\xdf\x81\x6f\xc1\x38\x2e\xda\xc2\x63"
+  "\x9c\xc7\x04\xd6\x5b\xaa\x09\xc6\xed\x11\xcb\x54\x53\xbf\x68\x0b"
+  "\x96\x39\xa0\x7d\x6a\xd8\x9a\x09\xdf\x7c\xe4\x59\x9d\x82\xd0\x0d"
+  "\x8a\xc0\xe1\xf1\xf4\x87\x8b\xdc\xda\xbd\x86\x7c\x05\x2f\x57\xe9"
+  "\x4d\xb9\xfb\x06\x29\x57\xac\xaf\xda\x8b\x72\x7f\xd4\x6f\x3f\xa5"
+  "\xa3\xdc\x02\xb1\xbe\x5a\x6f\xca\x8d\x1c\xa4\x5c\xb1\xbe\xe1\xde"
+  "\x94\x5b\xe6\xbe\xdc\x42\xb1\xbe\xe9\x5e\x94\xab\x53\xba\x2f\x77"
+  "\x6b\xa6\x77\x58\xd0\xf5\xdb\x93\xef\x8c\x05\xef\x70\xa0\x1b\xa4"
+  "\xfd\xf9\x99\xde\x61\x60\xa6\x62\x30\x0c\x78\xc7\xff\x99\x83\xf2"
+  "\xdf\x3b\xde\xcf\xdc\x3f\x18\xef\xbd\xe3\xfb\xdd\x6e\xf1\x8f\xb6"
+  "\x3c\xf0\x3e\x9c\xfa\x17\x9b\x84\xbc\x98\x70\xc1\x7f\xeb\xe3\x1b"
+  "\x85\x70\xf2\x04\xc8\xb0\x80\x1d\x64\x62\x38\x1b\x1f\xdf\x5d\xb8"
+  "\xbe\x84\xc8\x61\xbc\x2b\x3f\xb0\xae\x49\x6e\xb4\x85\xa1\xce\xb1"
+  "\xef\x4d\xb2\xca\xee\x82\xf4\x8f\x41\x67\x59\xc0\xee\xe4\xe5\xc4"
+  "\x84\xe7\xa5\x86\x13\xd1\x67\x86\x05\x7d\xa4\x46\x80\x1c\x33\xee"
+  "\xb0\xe2\xbe\x95\x89\xf0\x3b\x1b\xe0\x17\xca\xb0\x92\x77\x05\xb3"
+  "\x2c\x3c\x81\xe5\x33\xb3\xf3\x79\x79\x5b\x1f\xa7\x69\x3a\xf4\x9d"
+  "\x68\x86\x6f\xda\x7d\xcc\x44\x8e\x3e\x8e\xba\xb2\xee\xb6\x9a\x64"
+  "\x3f\x6e\x13\xcf\xa3\xb6\x33\x1f\x9f\x50\x5f\x3c\xeb\x89\x79\xd1"
+  "\xd7\xe7\x3d\x7a\x22\x47\xff\xeb\x5d\x59\x3f\x0e\x46\xbf\x9f\x83"
+  "\x9d\xeb\xb6\x1b\x8a\x82\xf1\xf7\x40\xcf\xb6\xd4\x0b\x44\x8e\x67"
+  "\x39\x61\x1c\xb0\x27\x0f\xc6\x10\xf3\x66\xe2\x9c\x47\x07\x49\x5d"
+  "\x4f\x05\x9c\x7f\xa2\xaa\xc2\x26\xdc\x1b\xc7\xf6\x8d\xcb\x7e\x5c"
+  "\x51\xca\xf7\x91\x5b\x59\x4c\x5f\x78\x66\xe3\x18\xdc\x1b\xa3\x8a"
+  "\xae\xa6\x79\x7e\xe1\xf5\x96\x0e\x16\x2f\xa8\x45\xf6\xe3\x8f\xd1"
+  "\xff\x62\xa7\xaa\x48\x6b\x51\x15\xe9\xa0\x5e\x87\xa4\x36\xe0\xf7"
+  "\xa5\x74\x1c\xb7\x61\x3e\x78\xdf\x2c\x9d\xf3\x76\x13\xe3\x7a\x52"
+  "\x84\x86\x9a\x7b\xfd\x6a\xc8\x66\x3d\x86\xb4\x07\x5b\x41\x63\x49"
+  "\xd3\x4d\xe7\xf3\x18\x21\x71\x38\x1e\x86\x7a\xf3\xb8\x9c\xb9\x31"
+  "\x0a\xe6\x83\x17\x74\xc0\xb3\x3a\xf9\x30\xed\xd6\x10\xa6\xff\x2b"
+  "\xa6\xa3\x8e\x9c\x35\x13\xca\xff\x49\x8b\x2c\xc4\xc0\xc7\x62\x31"
+  "\x1a\x76\xbe\x51\x16\xa2\x83\x6f\x68\xa8\x21\xba\x02\xf3\xc1\xfb"
+  "\xfd\xe2\x7b\xad\xd3\x7b\x2d\xee\x95\x14\xdf\x8b\x63\xb9\x98\x60"
+  "\xa7\xf7\xc1\xfa\xe9\x38\x37\x11\x62\xc1\x36\x50\x55\x0c\xd3\x6d"
+  "\xbd\x7e\x42\xfc\x62\x88\x98\x2f\xb0\x5d\x36\xcb\xaf\x13\xb0\x05"
+  "\xef\x83\x9c\x7e\x1f\x74\x38\x39\x94\x3c\xb1\x0b\x69\x38\x4b\x6b"
+  "\x92\x17\x25\xf2\xf1\x6c\x48\x08\x6b\xbb\x2a\xda\xea\x5c\x1e\xa4"
+  "\xb7\x83\x5e\xb4\x5a\xc0\x8e\x82\xff\x03\xf1\x9b\xce\xf4\x96\x4e"
+  "\x59\x6a\x63\x57\xc4\x68\x5f\x5e\xb5\x66\x25\x9e\x92\x1b\xef\xb2"
+  "\xc7\x51\x8d\xe7\x48\x05\xc3\x76\xa5\x71\x07\x9e\x6b\x53\xb3\xf3"
+  "\xe0\x85\xb8\x6f\xca\xbf\x38\xdc\x9e\x57\xd4\x20\xf8\x17\x9a\x2b"
+  "\xd6\x3d\x4e\x2e\xca\x66\xfd\x15\xdb\x6b\xd4\x12\x62\xd8\x8e\x7e"
+  "\x3c\x8e\x62\x1a\xf3\x57\x8a\x71\xa5\xd8\x98\x7d\x9d\x92\x54\x6a"
+  "\x3b\xd8\xb8\x1f\xde\xd9\xd9\x1c\xc7\x65\x22\xb7\x65\x28\xc9\x7f"
+  "\xa7\x36\xc8\x0f\x09\x26\xf9\x7f\x0b\x4d\x6c\x9f\xee\x61\x4d\x35"
+  "\xb9\x37\x59\x89\xb1\x0a\xe5\x1f\xc1\x58\x1a\xdf\xe3\x3b\xe9\x2c"
+  "\xc2\x45\xd9\x3d\x0b\xd9\x9e\xdd\x3b\xf9\xff\x69\x3b\xe8\xe9\xc3"
+  "\x1a\xd1\x67\x85\x6c\xd6\x5b\x58\x57\xf4\xe7\x01\x74\xfc\x23\xd6"
+  "\xcf\x24\x9b\xb5\xd7\xa7\x84\xed\x5d\x56\x41\xfe\xad\x42\xee\x76"
+  "\x26\x0f\x6c\x59\xb3\x22\x69\x86\x6a\x2f\x9e\xb1\x2b\x11\xcf\xdd"
+  "\x75\x65\xdd\x93\xe2\x74\x9e\x14\x7d\x91\xfc\x0c\xd2\xb6\x48\x67"
+  "\x1b\x30\xce\x99\x3b\xf9\x62\x05\x1b\xef\x6a\x50\x94\x4e\x50\x6d"
+  "\x03\x5e\x6c\x57\x56\xcf\x25\x38\xef\x22\xc3\x3d\xb3\xed\xb2\xd0"
+  "\x6c\xea\xb7\xcd\x9a\x8a\x7d\x3a\xaf\xd0\xfc\x5f\xb8\xef\x0f\xe8"
+  "\xb8\x1f\xf7\xf9\x01\x2d\xdf\x86\xe7\xa3\xf3\xf7\x11\xed\x33\x68"
+  "\x3b\xdd\x2b\xfb\x8f\x58\x6a\xbb\x7b\x51\x05\xa9\x6d\x7d\x8f\xd4"
+  "\x34\x56\x13\x55\x14\xf1\x49\x33\x51\x3b\x6b\x63\x22\x91\x47\x98"
+  "\x88\x4f\xea\x65\xec\xd3\x76\x82\xe7\x07\xea\xad\x75\x60\x0f\xc5"
+  "\x07\x1e\x48\x6d\x1b\xa3\x7d\x9a\x10\xe8\x7b\x6c\x8d\x99\x9d\xf3"
+  "\x31\xb3\x33\xd2\x7e\x38\xdf\xed\x74\xbe\x27\x2c\x25\x9a\x0a\xeb"
+  "\x2f\x10\x65\x5d\xdc\x49\x12\x11\xed\x43\xd9\xf9\x9e\x64\xc8\x68"
+  "\x06\xde\xbf\xae\xf3\xb7\xbf\xae\x9b\xb4\xf3\x0a\x09\xac\x4f\x34"
+  "\x81\x6d\x56\x4d\x8a\x13\x48\x20\xed\x8a\xf3\xad\xad\x3e\x4a\xe8"
+  "\xa6\xae\xb2\x77\x53\x2b\xc6\xd8\x95\x7c\x7f\x55\xc0\x06\x19\xf6"
+  "\x45\x7f\x03\xee\xb3\xba\x42\x42\x97\x9e\x49\x67\x73\xb2\x38\xff"
+  "\x6d\xeb\xd2\x69\x7b\xba\x74\x77\x76\xbf\xae\x9b\x2e\xcd\x9b\xbf"
+  "\x78\x41\x8d\xeb\x04\x91\x34\xeb\x8e\x70\xdc\xdb\x87\xe3\x00\x9b"
+  "\x6f\x4f\x39\xce\x91\x23\x86\xe1\xfb\x41\xc2\xcb\x3a\x72\xaf\x99"
+  "\x9d\x3d\xc2\x79\x7b\x75\xe9\x4b\x58\xd7\x0e\xc2\xf6\x0a\xf9\xf2"
+  "\xbd\x42\x56\x5c\xb3\x56\x15\x25\x2f\x5c\xae\x25\xdd\xd3\xa2\x74"
+  "\xc6\xe4\xff\x22\x69\x57\xe9\x69\x66\xc7\x27\x03\x6e\xb3\xee\xc1"
+  "\xb9\xbd\xe4\x2a\xdd\x71\xd4\x27\xb3\x87\x2f\x1f\x42\xd9\xfa\x2f"
+  "\xd2\x86\xe6\x01\xbf\x3a\x90\x6f\x85\xe6\xbf\x24\x98\xe5\x4f\xb5"
+  "\x52\x5b\x5d\xec\x7f\x91\x9a\xa6\x06\x17\xfe\x30\x7e\x42\x3e\xe4"
+  "\x13\xf2\x08\x79\xe5\xe0\xd3\x71\xc6\xa7\xfd\x02\xe7\x53\xb7\x6a"
+  "\x6b\xb8\xc4\x2b\x6b\x49\x54\x98\x27\xfc\xaa\x6d\x1d\x98\x5f\x40"
+  "\xe7\x5e\x7e\x15\x75\x90\x40\x63\x3b\xd8\xcb\xc0\xaf\xa7\x7e\x49"
+  "\xc8\x53\x6f\x53\xa1\x6e\xfe\xa7\xbd\x7c\xb3\x65\xbb\xe1\xdb\x39"
+  "\x07\xdf\x80\xff\x83\xf1\xad\x72\x38\x7c\xab\x6d\xe5\x7c\xb3\x89"
+  "\x7b\xbc\x74\x95\x44\x6e\x7d\x5d\x27\xdf\x71\x85\x84\x21\xff\x16"
+  "\x9c\xd1\x92\xaa\xc5\x75\xc0\xb3\xf7\x5c\xf8\x27\xe4\x16\x69\x80"
+  "\x07\x8b\x90\x87\xde\xf5\xbb\xd9\xc4\xf3\x7e\x77\xff\xda\x9b\xfd"
+  "\x6e\xb4\xfa\xdd\xfd\xda\x91\xf5\xbb\x07\x6a\x6f\xf6\xbb\xef\xba"
+  "\xdf\x3d\x50\xdd\xb7\xdf\xf5\xda\x0d\x09\xcb\x56\xc4\x2c\x5f\x89"
+  "\xc7\x13\x5f\x5a\x9b\xb8\x6c\x35\xb7\x1e\x5c\xec\x07\x8d\x3d\x35"
+  "\x5c\x8e\xfe\xe5\x6a\x77\x34\x90\x77\xa7\x36\xc8\xed\xdf\x68\x14"
+  "\xd4\xe0\x4f\x04\x83\x3a\x1b\xfd\x84\x62\xff\x2c\x44\x1f\x1e\xb2"
+  "\x47\x32\xeb\x83\x78\x4c\x4e\xfc\x9f\xd9\x4e\x41\x51\xe5\xb8\x5e"
+  "\xb3\xb1\x1b\xae\x75\x44\x11\x60\x25\xca\x8a\xe9\xf8\xfe\xe1\xd3"
+  "\xe8\x37\x91\xee\x8a\x2a\x2f\x85\x77\xe8\x87\xc7\xa2\x8a\xae\xc8"
+  "\x84\xf2\xcc\x7e\xdb\x95\x0a\x2d\x9e\xbb\x78\x28\x1c\x74\xbe\xbe"
+  "\xd7\xaf\x92\xec\xe1\xbd\x74\xec\x83\x5b\x50\x36\xe0\x39\xb9\x8b"
+  "\xb2\x87\xd6\x5c\xc5\xf5\x0e\xb0\xa9\x9f\x9d\x09\xdf\x9a\x16\x15"
+  "\xc6\xfc\x2c\x80\x9c\xe0\xef\xc3\x58\x0c\xb2\xab\x86\x42\x33\xda"
+  "\x1c\x9d\xaa\xe2\xf0\x4e\x43\x51\xc3\xd1\x94\x1d\xa2\x9c\x78\xe8"
+  "\xad\xa7\x76\x70\x39\x51\xa7\x01\x1c\x2e\x00\x1c\x46\x0e\x25\x27"
+  "\x9c\xf0\x37\x7d\x78\x72\x02\xf1\x86\xb8\x43\xcc\x4d\x00\xcc\x21"
+  "\x0e\x25\xdc\x15\x88\xb8\x0b\x68\x26\x6a\x86\x3d\x1b\xc7\x1e\x9e"
+  "\x73\xae\x4b\x76\xe0\xce\xde\x17\x77\x57\xfa\xe0\x4e\x2e\xe2\xee"
+  "\x75\x57\xdc\xbd\x70\x52\x4d\x8a\x19\xee\xb4\x0e\xdc\xe5\xf4\x94"
+  "\x4b\x98\x43\xfc\x21\xd6\x84\x57\x75\xa4\xae\xbd\xa3\x17\x7f\xa5"
+  "\xaf\xf0\x35\x57\xb6\xa7\x57\x4e\xcb\xae\xbe\x2e\xca\x8b\x0b\x92"
+  "\xbc\x28\x72\xa3\xa7\x4f\x7a\x29\x2f\xfe\x17\x5b\x7f\x46\x5e\x75"
+  "\x03\xdf\x90\x5f\x4f\x69\x40\x4e\x68\xfe\x40\x6a\x16\xdf\x20\xfc"
+  "\x49\x18\x1d\xfe\xa0\xef\x5b\xa8\xcb\x00\x3c\xba\xbd\x76\x28\x1e"
+  "\x21\x7f\x90\x4f\x8c\x3f\xc0\x27\x69\x5d\x1c\xd7\x49\x91\x57\xc8"
+  "\x9f\x7b\x52\x88\x1c\xf9\x55\x9a\xc4\x65\x04\xca\x02\xb6\x0f\xbb"
+  "\x8f\x8c\x07\x9a\x5b\x91\x67\x6c\x6c\x9d\xe1\x17\x5f\x88\xe7\x88"
+  "\x27\x49\x76\xf4\xc3\x95\xfd\xed\xe8\x87\x9b\x7a\xfd\x60\xca\x1e"
+  "\x62\xfe\x55\x2a\xa6\x3e\x02\xfd\xf3\x21\xee\xc3\xd1\xb0\xad\x9c"
+  "\xdb\xf0\x3f\x79\x50\x94\x01\x7b\x70\xec\xca\xc6\xa9\x76\x18\xa7"
+  "\xaa\x60\x9c\x6a\x80\x71\x6a\x72\x1b\xf7\x9d\x20\x7b\xe4\x3e\x22"
+  "\x9e\x6f\xa6\x7e\x85\x4d\x34\x37\x9a\xf9\x2d\x64\x6b\xbe\x7e\x45"
+  "\x5a\x5c\xa3\xa2\xb9\x30\x06\xfe\x83\x1c\x6c\x80\x22\x5d\x95\xce"
+  "\x3e\x4c\x4c\x3d\xb2\x48\x5c\xd3\x8e\xd5\xaf\xc3\xfd\x0e\x3f\xd1"
+  "\xf2\xfa\x3d\xc8\x62\xda\xb0\xf5\x40\xb9\xb0\xc7\xbe\xd1\x75\x3d"
+  "\xd0\x79\xbd\xf8\xdd\x54\xb3\xb8\x16\xf8\x13\xe6\x2b\x11\xe5\x09"
+  "\xca\xc1\x03\x30\xa6\x71\xac\x07\x7e\x8a\xef\x7d\x5d\xd7\x03\x1f"
+  "\x61\x3e\xe6\x4c\xb2\x9f\xcc\xc6\x3d\x30\xf0\x6c\xe6\xe9\x0f\x5a"
+  "\x9d\xd3\x1d\xeb\xed\x3c\x5d\x90\xb3\x98\x2b\x38\x5f\xd0\xce\xe7"
+  "\x09\x7e\xb2\x40\x1a\x8f\xbb\xb1\x9f\x86\x21\xa7\xc3\xc3\x1d\x72"
+  "\x3a\x9c\xef\xd5\xd2\x14\xb7\xd5\xf5\x93\xd3\x5f\xc2\xfb\x9f\xed"
+  "\x7a\x1a\xe5\xb4\xa1\xd0\x24\xf2\xf4\x04\xd0\xc4\x07\x63\x67\x62"
+  "\x3a\x9e\x3f\x42\x79\xbd\x0b\xcf\xe6\x30\x19\x5e\xdc\x94\xc9\xd6"
+  "\xfd\x7f\x62\x73\x95\xdd\x3f\x8b\x76\x95\xdd\x73\xee\x1b\x5c\x76"
+  "\x3f\x7a\x61\x70\xd9\x3d\xe7\xc5\x9b\xb2\x7b\xb4\x65\xb7\x64\xeb"
+  "\x79\x2b\xbb\x1f\x2d\xbf\x29\xbb\xaf\xb7\xec\x7e\xf4\xa0\x93\xec"
+  "\xfe\xb5\xab\xec\xfe\x59\x7a\x7f\xd9\xfd\xb3\x42\x87\xec\x9e\xa3"
+  "\x74\xc8\xee\x9f\x54\xb8\xca\xee\xf0\x4b\x9e\xc9\xee\x9f\x5d\xb8"
+  "\xb6\xb2\x3b\x5c\xe5\x2a\xbb\xc3\x9b\x45\x39\xf4\xd6\xf0\x65\x77"
+  "\xf8\x07\x83\xcb\xee\xf0\x2a\x57\xd9\x1d\xbe\x83\xcb\xe8\x70\x33"
+  "\x97\xdd\xe1\xfb\x45\x1d\xb0\xc7\x39\xdd\x21\xbb\x79\x7a\x7f\xd9"
+  "\xfd\x98\x72\x08\xd9\xad\xb3\x0b\x92\xec\x6e\x02\xd9\xdd\x24\x17"
+  "\x5e\x75\x27\xbb\x7f\x1e\x57\x87\xb2\x3b\x01\x65\xf7\xcf\xe3\x06"
+  "\x97\xdd\x3f\x7f\x16\x65\x34\xe0\x98\x94\xa0\x8f\x64\xc0\x65\xc5"
+  "\x2b\x5f\xe2\xfc\x75\x2b\xe2\xf6\xac\x6c\xde\x81\xa7\x53\x9c\x65"
+  "\xfb\x63\x7f\xeb\x95\xed\x90\x2e\x4c\x71\x95\xed\x28\xd7\x51\xbe"
+  "\xef\xda\x4e\x4d\xa5\xdb\x69\x33\xb4\xcb\x24\xc9\xf8\x5c\x48\xc3"
+  "\x78\x49\xe8\x03\x69\xd7\x15\x76\x29\x80\x06\xad\x1b\xe1\xbb\xf8"
+  "\x9b\xae\xac\xc7\x55\xae\xfa\x60\x9e\xde\x96\xe5\xac\x0f\x1e\x7f"
+  "\x0c\xf5\x81\x81\x9f\x51\x67\x7a\xc0\xb6\x2b\x2a\x0c\x75\x03\x7f"
+  "\xff\x84\x7d\x70\x7d\xf0\xf8\x8a\xef\x4a\x1f\xa0\xac\x99\xe0\x34"
+  "\x86\x74\xa7\x0f\x70\x4e\xb5\x2e\xf6\xfa\xe8\x03\x94\x33\x28\x5f"
+  "\x50\xd6\xa0\xdc\x41\x39\x83\x32\xc7\x26\x9e\xcf\x2b\xc9\xf0\x40"
+  "\x1f\x80\x5c\xa1\x63\xef\xd7\x32\x7d\x20\xf3\x46\x1f\x3c\x51\xfd"
+  "\xbd\xd2\x07\xc8\x9f\x94\x6b\xab\x0f\xa4\x71\x3e\xf2\x07\x79\x25"
+  "\xf1\x48\x1a\xeb\x23\x7f\x90\x4f\xc8\x1f\xb4\x8d\x24\x7d\x30\x2b"
+  "\x99\xeb\x83\x5d\x43\xea\x83\x27\x2a\x7b\xf5\x81\x9c\xeb\x03\x36"
+  "\x27\x3e\x09\xf5\xc1\xbc\x2d\xfd\xf5\xc1\xbc\xbd\x0e\x7d\xf0\xb8"
+  "\x46\x94\x8f\xad\xe8\x7b\x01\xe4\x41\x89\xab\x4e\x78\x72\x8a\x67"
+  "\x3a\xe1\xe7\xb2\x7e\x3a\x01\x68\x6b\xe0\xeb\x66\xa8\x0f\xb4\xa8"
+  "\x0f\x6c\xa8\x17\xbc\xd2\x09\x3f\xd7\x3a\xf4\xd6\x63\x29\x5c\x16"
+  "\xcf\x3b\xe4\xaa\x27\x9e\x54\x88\x32\xed\x45\x67\x3d\x21\xf8\x78"
+  "\xa2\x27\x7e\x7e\x46\xd2\x13\x28\x87\x0f\xe0\x9a\x45\xaf\x9e\x60"
+  "\x72\xf5\x42\x45\x52\x8b\x93\x9e\xf8\x79\x05\xaf\xc3\x93\x1a\x3b"
+  "\xd3\x13\x3f\x6f\xe4\xe9\x8f\x45\x39\xa7\x3b\xf4\x04\x4f\xb7\x3b"
+  "\xeb\x89\x36\xd4\x13\x4f\x86\x0e\xa1\x27\x66\x7b\xae\x27\x16\x2a"
+  "\x1d\x7a\x62\xa1\x72\x70\x3d\xb1\xe0\x32\xea\x09\xe6\x83\x17\x78"
+  "\x0f\x38\x57\xe4\x4d\xe6\x3a\x02\xe7\x68\x40\x77\x98\xd0\xe7\x07"
+  "\xe4\x3b\xcd\x7c\xed\xc3\x05\xef\xdb\x0c\xf8\xbf\xc0\x7e\xd3\x1c"
+  "\x60\x26\x4a\xd4\x19\x86\xb3\x44\x81\x71\xea\x38\x9d\x16\x3c\x5a"
+  "\x82\xb1\x53\x7b\xf5\xcb\xfc\x5b\x3c\xd4\x2f\x8d\xa0\x5f\x1a\xba"
+  "\xb2\xe6\x87\x3b\xe9\x17\x8c\xf5\xd7\xd0\x47\xbf\x98\x40\xbf\xb4"
+  "\x4a\xbf\x81\xfc\x7a\xe7\xfc\x58\x3f\x96\xff\x2c\xbb\x30\x7f\x13"
+  "\xe4\x6f\xe6\xfa\x68\x7e\x89\xab\x3e\x5a\x40\x04\x97\xf1\xc9\xfc"
+  "\x63\x92\x3e\x42\x7d\x2e\xf4\xd3\x47\x4f\xe5\xf6\xea\xa3\xc9\x4e"
+  "\xfa\x28\x59\xd2\x47\xf3\xed\x37\xfc\xf8\x64\x04\xf2\xee\x5a\xeb"
+  "\x23\x01\xf4\x4e\x5f\x7d\x84\x3a\x4a\x1a\x9f\x08\x5e\xe9\xa3\xa7"
+  "\x22\xbf\x57\xfa\xe8\x3a\x8c\x4f\xfa\xf2\x46\xe2\x19\xf2\x07\x79"
+  "\x83\x7c\x41\x3f\xe0\xc8\x33\xe4\x17\xf2\x6a\x96\xde\x55\x17\x31"
+  "\x7e\x81\x3e\xea\xb7\x76\x00\xbc\x02\x9a\x2f\x46\x7e\x39\xeb\xa3"
+  "\xd2\x49\x92\x3e\x5a\xa0\xed\xaf\x8f\x16\xcc\x76\xe8\xa3\xf9\x6c"
+  "\x7f\x15\xf3\x7f\x28\x7b\xd2\xe6\xaa\x8b\x16\xbe\xef\x99\x2e\x5a"
+  "\x90\x3b\x80\x2e\x62\x7d\xd6\xb0\xdd\x65\x6c\xa2\x05\x7d\xe4\x85"
+  "\x2e\x5a\xb0\x9f\xd7\x11\xf7\x82\x3f\x59\xcb\xe5\xfd\x82\xf9\x0e"
+  "\xfd\xf4\xe4\x5e\xe7\x34\x87\x7e\x5a\xb8\x57\xd4\xa9\xbf\x1f\xbe"
+  "\x7e\x5a\xc8\x7e\x83\xfb\xc4\x0f\x74\x70\x1d\xe0\xaa\x9f\x16\xe6"
+  "\xba\xea\xa7\x85\xd1\xbc\x0e\x0b\xcb\xb9\x7e\x5a\x98\xc8\xd3\x9f"
+  "\xcc\x74\x4e\x77\xe8\x27\x9e\xde\x5f\x3f\x2d\x6c\x18\x42\x3f\xa9"
+  "\x7a\x4a\xa2\xc2\xba\x0d\xc5\x5a\xdb\xde\xf8\x86\x90\xa8\xdb\xed"
+  "\x7d\xfb\x13\xef\x47\x76\x82\xfd\xaa\x77\xbd\xed\x39\x42\x7a\x54"
+  "\x5b\xc3\x05\xf1\x3c\x75\x77\x50\x94\xee\x6c\x3c\xf4\xa9\x76\xf7"
+  "\x7d\x0a\xfa\x93\x52\xea\x4f\x75\x71\x67\x08\xf4\x31\x39\xae\xb7"
+  "\x15\x41\x5f\x32\x5a\x9a\x58\xdf\x52\xb5\x6a\x09\xfa\xb6\xf4\x6b"
+  "\x27\x6a\x3f\x99\x6c\xec\x7f\x3c\x0f\x7d\x16\xfa\xd5\xbc\x99\x54"
+  "\xb8\xbb\x59\x4b\xfc\xe2\x88\x3f\xf6\xad\x77\xc4\xf5\x1c\xf4\x85"
+  "\x81\xeb\x38\x80\xeb\xd0\xa5\xc7\x78\x9f\x2a\x82\xab\x9b\xf7\xa9"
+  "\xe9\xdd\x5d\xba\x3b\xdd\xad\xe3\x18\x93\x4d\x6c\x1d\x07\xcf\x2a"
+  "\xe1\x19\x31\x01\xfb\x10\xae\xe3\x58\xb9\x6d\x07\xf5\x55\xef\x66"
+  "\xeb\x38\x2d\x2e\xeb\x38\x3f\x6e\x26\x72\xf4\x93\x51\xec\xbc\x8e"
+  "\xa3\xab\xeb\x67\xd7\x61\xff\xc2\xfe\x34\x7c\x99\x17\xe1\xd6\xff"
+  "\x35\xdb\x3b\x01\xb4\xb6\xab\x8a\xb5\xb4\xa8\x44\xfd\x97\x16\xab"
+  "\x0c\x7d\x8a\xda\x81\x77\x02\xc8\x36\xaa\xec\x23\xdb\x7a\x44\x3e"
+  "\xf4\x70\x3e\x00\x0f\x95\x4b\x2c\x84\x2e\xb5\x41\xff\xe9\x11\xfd"
+  "\x8a\x5a\x4d\x80\x43\xdd\xa4\x5d\xeb\x90\xee\x1a\xb2\x4b\xf4\x2d"
+  "\x2a\xbc\x11\xe7\x2b\x00\xad\x69\x86\x9c\x1c\xb8\x62\x65\xeb\x9e"
+  "\x86\x6e\x12\x02\xb2\xcc\x0f\x65\x19\x60\x77\xfc\xee\x6e\xa0\xfb"
+  "\x69\x4e\x77\xf4\xf7\x86\x77\xdb\x1b\x3a\x2d\x94\x7d\x67\x4f\x0f"
+  "\xc8\x32\x2b\xa7\xfd\x92\xd7\xd4\x84\xf9\x23\xc5\xb5\x4f\xb0\x1b"
+  "\xea\x81\xdf\x4c\x96\x59\x02\x28\xc6\x08\x11\xbe\xd1\xa1\xef\xab"
+  "\xa0\x7b\x2d\x40\xfb\x1e\x1d\x62\x43\x5d\x7a\x16\xd7\x3e\xbf\x74"
+  "\x59\xfb\x34\xbf\xe1\x58\xfb\xac\xdf\x77\x9c\xef\x55\x71\x99\x0f"
+  "\x5b\xd8\xda\xb3\x8b\xeb\x1c\x36\x1f\x96\x38\x5c\xda\x2f\xaa\xfe"
+  "\xee\x68\xaf\xfe\x9e\xd3\x3e\xa2\x70\x64\xb4\x7f\x66\xee\x77\x47"
+  "\x7b\xe5\xf7\x9c\xf6\xbf\x54\x8f\x8c\xf6\xbf\xaa\x18\x8c\xf6\x38"
+  "\x86\x91\xc6\x2f\xd2\xd8\x05\x75\x18\xd7\xd7\xcf\x2d\x76\x8c\x5b"
+  "\x9e\x5b\x2c\xad\x21\x03\xcd\x14\xb9\xe8\xcf\x1b\x68\xa1\x7f\x85"
+  "\xdc\x7e\x5e\xf6\xec\x11\x69\xfd\x78\x0b\xc6\x95\x41\x3e\x16\x01"
+  "\x1f\x57\xe2\x59\x23\x91\x87\xa0\x73\x96\x5a\x40\x2f\x4c\x8b\x0a"
+  "\xb3\xe7\x82\x4e\xfa\x63\x7c\x83\x1b\x7e\xca\x51\x9f\xf8\x25\x12"
+  "\xf5\x12\xbd\x83\xaf\xc2\x1b\xc0\xcf\x6e\xb0\xcd\xac\x6d\x04\xcf"
+  "\x0f\x07\xb4\x81\xdd\xda\x13\xe7\x1b\x05\x63\x00\x89\xa7\xef\x24"
+  "\x59\x99\x5d\x36\x20\x4f\x77\xba\xf2\xb4\x73\x00\x9e\xbe\xb8\x1c"
+  "\xfa\xa9\x5c\xb4\x9d\x19\x4f\x4d\xbd\x3c\x65\x7a\xe4\x0d\x5d\x10"
+  "\xf2\x55\xe2\x29\xea\x11\xc6\xd3\x76\xae\x47\x7a\x7d\x2d\xbd\xe1"
+  "\xb0\x9d\x6b\xa3\x4f\x0e\xc0\xd3\x67\x0c\x2e\x3c\x8d\x1e\x2e\x4f"
+  "\x9f\x2d\x74\xb5\xbf\x7e\x2d\xf3\xcc\xfe\x7a\x6e\x22\xda\x57\xce"
+  "\xf6\x17\x3e\x77\x82\xbd\x65\xf7\x2b\x0a\xb6\x78\x35\xfe\x7f\x4e"
+  "\xeb\x6a\x4b\x3d\xd7\xce\xeb\xb4\xf8\xd1\xe1\xdb\x52\xcf\xd5\x61"
+  "\x9e\x03\x45\x03\xd9\x51\xcf\x1d\x77\xb5\xa3\x9e\xdb\xc7\xed\xa5"
+  "\x5f\xe3\x79\x5c\xb0\xa3\x9e\x3b\xc4\xd3\x17\xcf\x71\x4e\x77\xd8"
+  "\x51\x3c\xbd\x13\xfd\xcf\x65\xfd\x5a\x35\x3c\xdb\xe9\xd6\xef\xd8"
+  "\x76\xd2\x0c\x62\x3b\x69\xfe\x4d\x6c\xa7\xc8\xec\x9b\xfa\xdb\x5b"
+  "\x1d\xf2\x6b\xed\xc8\x74\xc8\x6f\xdc\x9e\x7f\xb8\xa9\xbf\x87\xa2"
+  "\x7d\x64\xc3\xc8\x68\xff\x42\xba\xf7\xfa\x7b\x49\xa0\x43\x7f\x2f"
+  "\x09\x74\xaf\xbf\x5f\xcc\xb9\xa9\xbf\x87\xa3\xbf\x7f\xb3\x60\x64"
+  "\xfa\xfb\xc5\xc5\xae\xfa\x7b\xc9\xc7\x9e\xe9\xef\x17\x8f\x8d\xbe"
+  "\xfe\x7e\xd1\xe4\xaa\xbf\x97\xec\xe7\x75\x7a\xc1\x3e\x7c\xfd\xbd"
+  "\x24\xd7\xbd\xfe\x5e\xb2\xcd\x55\x7f\x2f\x89\xe3\x7a\x7a\x49\x05"
+  "\xd7\xdf\x4b\x52\x78\xfa\x0b\x36\xe7\x74\x87\xfe\xe6\xe9\x5c\x7f"
+  "\x2f\xa9\x1d\x9e\xfe\x0e\xf8\x8e\xf5\xb7\x7a\x10\xfd\xad\xfe\x37"
+  "\xd1\xdf\xd1\x6e\xe3\x9f\xdf\xd4\x21\x43\xe9\x90\x25\xa6\x91\xe9"
+  "\x90\x18\xb7\xfe\x1f\x87\xd6\x21\xb1\x91\x0e\x1d\x12\x1b\xe9\x5e"
+  "\x87\xbc\x5c\x77\x53\x87\x0c\x47\x87\x44\x6f\x19\x99\x0e\x79\x79"
+  "\x87\xab\x0e\x59\x36\xc6\x33\x1d\x12\x7b\xcb\xe8\xeb\x90\xd8\x60"
+  "\x57\x1d\x12\x6b\xe6\x75\x7a\xe9\xb1\xe1\xeb\x90\xd8\x63\xee\x75"
+  "\x48\xec\x09\x57\x1d\x12\xbb\x9f\xeb\x8a\x65\x0a\xae\x43\x62\x2b"
+  "\x78\xfa\x4b\xe1\xce\xe9\x0e\x1d\xc2\xd3\xb9\x0e\x59\xa6\x1e\x9e"
+  "\x0e\x19\xf7\x1d\xeb\x10\xe5\x20\x3a\x44\xf9\x6f\xa2\x43\x5e\x31"
+  "\x78\x2f\xc7\x96\x6b\x1d\x72\x6c\xb9\xd6\xbd\x1c\x8b\xdb\x76\x53"
+  "\x8e\x0d\x47\x8e\x2d\x0b\x1e\x99\x1c\x8b\x8b\x76\x95\x63\xcb\xeb"
+  "\x3c\x93\x63\x71\x27\x47\x5f\x8e\xc5\xb5\xbb\xca\xb1\xe5\x62\x9d"
+  "\x5e\xf5\x1d\xbe\x1c\x5b\xbe\xd3\xbd\x1c\x5b\xfe\x96\xab\x1c\x5b"
+  "\x9e\xc8\xe5\xd5\xf2\x5a\x2e\xc7\x96\x67\xf3\xf4\x57\x95\xce\xe9"
+  "\x0e\x39\xc6\xd3\xb9\x1c\x5b\xde\x34\x94\x1c\xc3\x7e\x51\xa7\xe9"
+  "\xd3\x2f\x7e\x27\xf5\x8b\xf8\xf9\x35\x25\x52\xbf\x88\x67\x36\x9a"
+  "\x50\x12\x55\xfe\x66\x12\x51\x18\x30\x76\x0c\xc8\x08\xfd\x6f\xb0"
+  "\x5f\xfc\xee\x03\xdc\x27\xa2\x6a\x06\xb9\xd7\x2a\xca\xc1\x64\x90"
+  "\x83\xad\xf0\x8c\x7e\xd5\xa6\x45\x95\xa3\xfc\xc2\x98\x1a\xf8\xcc"
+  "\xe5\xa1\x79\x0c\xc6\xae\x61\x6b\xf3\x4e\xfd\x86\xf5\x95\x4e\xb1"
+  "\xaf\x74\xf2\xbe\x22\x9d\xdd\x4b\x69\xa5\x82\x7d\xb5\x6e\x52\x44"
+  "\xac\x0f\xc5\xfe\xc3\xce\x84\x41\xff\xa1\xab\x75\xfe\x25\x09\xd0"
+  "\x67\xcc\x6d\x04\x7d\xe7\x63\x9f\xf1\xdb\x20\xf3\xa7\x9d\x71\xbe"
+  "\x20\x13\xb9\xec\x13\xaa\xc7\xd8\xd0\x0f\xd6\x6a\x90\x7d\x1d\x20"
+  "\xfb\x3a\x1c\x7d\x05\xd7\xdb\x3b\x57\xeb\xb4\x96\xd5\xba\xe9\x3d"
+  "\x9d\x20\xfb\xcc\x7d\xfb\xc9\xed\xb5\xbb\x3b\x50\xf6\xb5\xb1\x7e"
+  "\xc2\x64\x1f\xf4\x0d\xa1\x13\x64\xdf\xab\xa2\xec\xeb\xd4\xa1\xac"
+  "\x57\xef\x7e\x05\x64\x5f\xf4\x79\x2e\xfb\x44\x1b\xee\x2e\x94\x7d"
+  "\xab\x75\xf2\x82\x0e\x51\xf6\xc5\xa0\xec\xab\x82\x3e\xf2\x3f\xae"
+  "\xb2\xcf\xcf\x5b\xd9\xf7\xbb\x6c\xd7\x7e\x12\x7f\xd9\xb3\x7e\x12"
+  "\x3f\xc6\x5d\x3f\xe9\xc9\xf5\xb6\x9f\xc4\x07\xba\xf6\x93\x78\x71"
+  "\x4f\xd1\x6f\xef\x18\x7e\x3f\x89\xff\xb8\xb7\x9f\xfc\xae\x6f\x3f"
+  "\x89\x3f\xe2\xda\x4f\xe2\x4b\x78\x7f\x88\xb7\xf0\x7e\x12\x5f\xc6"
+  "\xd3\x7f\xab\x75\x4e\x77\xf4\x13\x9e\xce\xfb\xc9\x0a\x72\x73\xbd"
+  "\xfc\xfb\xa6\xef\x57\xba\xf5\xff\x74\x73\xbd\x7c\xa8\x31\xe3\x8a"
+  "\xc0\x91\x8d\x19\x57\xb9\xf5\x7f\x77\x73\xbe\x7d\x28\xda\xaf\xac"
+  "\x1c\x19\xed\x5f\x73\x1b\xff\xe7\xe6\x5c\xc9\x50\xb4\xd7\x87\x8f"
+  "\x8c\xf6\x09\xe6\xa1\xc6\x18\xee\x6d\xa9\x35\x25\xb5\xbd\x63\x8c"
+  "\x35\x25\xd2\x3e\xdf\xfe\x63\x8c\x35\x13\x5d\xcf\xf1\xad\x7e\xab"
+  "\xef\x39\xbe\xa1\xc6\x1e\xb6\x9b\x63\x0f\xe0\xf5\x6b\x87\x46\x36"
+  "\xf6\x48\x6c\x76\xb5\xa9\x92\x7e\xe1\x99\x4d\xb5\xe6\x79\x77\x36"
+  "\x95\xcd\xeb\xb1\xc7\x9a\x38\x57\x9b\x2a\x69\xb6\x88\x8d\x15\xc3"
+  "\xb7\xa9\x92\x6e\x71\x6f\x53\x25\x4d\x73\xb5\xa9\xd6\x98\xb9\xed"
+  "\x94\x34\x9f\xdb\x54\x49\x0a\x9e\xbe\x3a\xde\x39\xdd\x61\x53\xf1"
+  "\x74\x6e\x53\x25\x2d\xbe\xb9\x8e\xfe\x7d\xb3\xa9\x5e\x6f\xb8\xa9"
+  "\xd7\xbd\xd5\x2d\x49\x71\x23\xd3\x2d\x6b\xbf\xc3\xfd\x9f\xdf\x77"
+  "\xbd\x9e\xac\x19\x19\xed\xd7\x0d\xba\xff\x73\x70\xbd\xbe\x3e\xd1"
+  "\xa1\xd7\xd7\x27\xba\xd7\xeb\x29\xe7\x5c\xf5\xfa\x1b\x6b\x6f\xea"
+  "\x75\x6f\xf4\xfa\xda\xc2\x91\xe9\xf5\x94\x83\xae\x7a\x3d\xf5\x0e"
+  "\xcf\xf4\xfa\xfa\xfb\x46\x5f\xaf\xaf\x0f\x77\xd5\xeb\xa9\x2a\x11"
+  "\x1b\xf3\x86\xaf\xd7\xd7\x5f\x70\xaf\xd7\xd7\x5f\x76\xd5\xeb\xeb"
+  "\xab\xb9\xfe\x4e\xd5\x72\xbd\xbe\xbe\x99\xa7\xbf\x31\xd7\x39\xdd"
+  "\xa1\xd7\x79\x3a\xd7\xeb\xa9\x21\x37\xd7\xd7\xbf\x6f\x7a\x3d\xcd"
+  "\xad\xff\xe3\x9b\xba\x65\x28\xdd\x92\x3a\xc2\x31\xe3\x06\xb7\xf1"
+  "\x7f\x87\xd6\x2d\x1b\x1b\x1c\xba\x65\x63\x83\x7b\xdd\xb2\x71\x9e"
+  "\xab\x6e\xd9\x70\xfc\xa6\x6e\xf1\x46\xb7\xa4\x99\x47\xa6\x5b\x36"
+  "\xaa\x5d\x75\x4b\xe6\x7a\xcf\x74\xcb\xc6\xdc\xd1\xd7\x2d\x1b\x4b"
+  "\x5c\x75\x4b\xa6\x18\x37\x68\xc3\x5b\xc3\xd7\x2d\x99\xbf\x70\xaf"
+  "\x5b\x32\x7f\xe9\xaa\x5b\x32\x83\xb9\x0e\xc9\x4c\xe1\xba\x25\x33"
+  "\x8c\xa7\x6f\xd8\xe3\x9c\xee\xd0\x2d\x3c\x9d\xeb\x96\xcc\xec\x9b"
+  "\xeb\xee\xdf\x37\xdd\x92\x35\xe8\xfe\xdf\xc1\xe5\x5b\x76\x99\x43"
+  "\xbe\x65\x97\xb9\x97\x6f\xd9\x33\x5c\xe5\x5b\xd6\xdf\x6e\xca\x37"
+  "\x6f\xe4\x5b\x66\xc9\xc8\xe4\xdb\xff\x36\xbb\xca\xb7\x9c\x17\x3d"
+  "\x93\x6f\xd9\x2b\x46\x5f\xbe\x65\xa7\xb8\xca\xb7\x9c\xf9\x22\x36"
+  "\x36\x0c\x5f\xbe\xe5\xcc\x74\x2f\xdf\x72\xee\x73\x95\x6f\x39\x0a"
+  "\x2e\xc7\x72\xa2\xb8\x7c\xcb\xd1\xf0\xf4\xac\x74\xe7\x74\x87\x7c"
+  "\xe3\xe9\x5c\xbe\xe5\xc4\x8d\x6c\x3d\xfe\x4d\xb3\x63\x3d\xfe\x4d"
+  "\xc6\x0b\x61\x47\x71\x5b\xff\xf5\xf8\x37\x97\xb9\xfa\x0b\xca\x39"
+  "\xc7\xd6\xe6\xb1\xcf\x58\xb8\x4f\x87\x01\xd7\xe9\xa7\x14\xb7\xdd"
+  "\x5c\xa7\xbf\x96\xeb\xf4\x6f\x86\xba\xf6\x1f\xc3\x2e\xcf\xfa\xcf"
+  "\x9b\x07\x46\x7f\x9d\xfe\xcd\x3e\x7e\x58\x0c\x62\x1c\xb4\x9c\xbf"
+  "\x0e\xbf\xff\x18\x96\xbb\xef\x3f\x86\xd7\x5c\xfb\x8f\x41\x1c\x63"
+  "\x1a\x4a\x78\xff\x31\x44\x8a\xfd\xaa\xcc\x39\xdd\xd1\x7f\x78\x3a"
+  "\xef\x3f\x86\x7d\x9e\xd8\x07\x36\x55\x71\x30\xea\xfb\x90\xe6\xdb"
+  "\xed\xbd\x38\x4f\x14\x71\x3e\x90\x7d\xf0\x12\xd7\x17\xcc\x36\xd8"
+  "\x1b\xdf\x38\xa4\x7d\xd0\x2a\xda\x07\xb1\xfd\xed\x03\xc9\x36\x28"
+  "\x01\x7c\x17\x79\xb4\x46\x2f\xe2\x1d\x6d\x83\x2b\xc3\xb5\x0d\xee"
+  "\x74\xd8\x06\x39\x7d\x6c\x83\x57\xfb\xd8\x06\x0c\xef\x2d\x2e\x78"
+  "\xef\x67\x1b\xf4\xe2\x7d\xb4\x6c\x83\x3c\xed\xcd\x35\x7a\x6f\xc7"
+  "\x9d\x86\x43\x23\x1b\x77\x6e\x2e\xb9\x39\x97\xef\x2d\xed\xf3\x46"
+  "\x38\x97\xbf\x55\x73\x73\xbe\xc5\x5b\xda\x6f\x1e\xa1\x2f\x87\xfc"
+  "\x42\xef\xc7\x23\xdb\xa2\x1d\xe3\x91\x6d\xd1\x92\x7d\x85\x72\x97"
+  "\xf9\xcc\x02\x59\x9b\x9b\x00\xd7\x15\x42\xde\x4c\x60\x31\x0f\x94"
+  "\xc6\xd6\xe3\x44\x9f\x8a\x36\x57\xe1\xf1\x88\x64\x67\x9b\xab\xe0"
+  "\x79\xc9\xde\x8a\x40\x5b\x0c\x6c\x2b\xb4\xab\xa4\x31\xc8\x96\x8e"
+  "\x21\xf6\x0f\xcf\x88\x6f\xc4\x31\x4b\x8f\x5f\x71\xf0\xbf\xef\x78"
+  "\x65\x6b\xf4\xc8\xc6\x2b\x85\x7b\x5c\xed\xad\xed\x7e\x9e\xd9\x5b"
+  "\xdb\xa6\x8d\xfe\x78\x65\x5b\x88\xab\xbd\xc5\xfc\x27\x23\x4e\x26"
+  "\x0e\xdf\xde\xda\x76\xc2\xbd\xbd\xb5\xed\xb4\xab\xbd\xb5\xed\x20"
+  "\xb7\xab\xb6\xab\xb8\xbd\xb5\xad\x9a\xa7\x17\xa8\x9d\xd3\x1d\xf6"
+  "\x16\x4f\xe7\xf6\xd6\x76\x8d\x87\xf6\x96\x6e\x04\xf6\x56\xd3\xf7"
+  "\xc7\xde\xba\xeb\x06\xb7\xb7\xfe\x73\x8b\x07\x7a\x27\xb8\x8f\xde"
+  "\x69\xbc\xa9\x77\x50\xd6\x6c\x0f\x19\x99\xde\xd9\xa9\x1a\x92\xf6"
+  "\x06\x27\xda\xa3\xcc\x17\xe9\x6e\x0f\x8e\x6f\xf4\x9a\xf6\x20\xeb"
+  "\x77\xa5\x7e\x9f\xe9\xfe\x9f\x4d\x23\xa3\x7b\x51\xe6\x4d\x5b\xcb"
+  "\x5b\xda\xef\x5c\x3c\x32\xda\xe3\x10\xc3\x5b\x5b\xab\xb4\xbd\xa6"
+  "\xd7\xd6\x2a\x6d\xef\x6b\x6b\xa1\x6d\xb5\xd0\xca\x6d\xae\x37\xc1"
+  "\x56\xda\xb4\x12\xec\xae\x24\x42\x8c\xad\x1f\x10\x03\xd8\x5e\x9b"
+  "\x2e\x82\xfd\x15\x0f\xf6\x97\xed\x8f\xa2\xfd\x55\x1a\xe3\x6a\x7f"
+  "\x95\x9c\x18\xd0\xfe\xf2\x73\xd8\x5f\x36\xb0\xad\x7a\xfe\x18\xdf"
+  "\xb8\xe5\xa2\x93\x2d\xf6\xdb\xfe\xb6\x58\x77\x6e\xb1\xae\x7b\x46"
+  "\x7c\x53\x0f\xd8\x63\x83\xd9\x62\x0c\x13\x03\xd8\x63\xff\xff\xb0"
+  "\xc5\x8a\x6a\x47\x66\x8b\x95\x86\xb8\xda\x62\xbb\x77\x7a\x66\x8b"
+  "\x95\xbe\xed\x76\xee\xcb\x6b\x5b\xac\xb4\xdc\xd5\x16\xdb\x9d\x29"
+  "\x62\x66\xfd\xf0\x6d\xb1\xdd\xcb\xdc\xdb\x62\xbb\x57\xb8\xda\x62"
+  "\xbb\xc5\xb3\xa7\xbb\x77\x70\x5b\x6c\xf7\x62\x9e\x5e\x92\xe2\x9c"
+  "\xee\xb0\xc5\x78\x3a\xb7\xc5\x76\xef\xf5\x70\x6d\x2c\xd8\x06\x3a"
+  "\xfd\xbb\xdf\x4f\x39\xd8\xda\xd8\x68\xed\xa7\xbc\xf3\x06\x5f\x1b"
+  "\x7b\x6b\xe8\xf9\xaf\x9b\x36\xc1\x00\xb2\x66\x77\xf9\xc8\xf4\xd2"
+  "\x1f\x76\xdc\xb4\x09\xbc\xa5\xfd\x5b\x23\x9c\xfb\xda\x1b\xe8\xbd"
+  "\x4d\xf0\x27\x93\x63\xfe\xe5\x4f\xa6\xe1\xcd\xbf\xfc\xe9\x59\x57"
+  "\xfd\xbf\x77\x60\xfd\x7f\x73\xfe\x65\x18\x3a\xff\x0f\xa6\x91\xe9"
+  "\xfc\x3f\x69\x5d\x75\xfe\x9f\x73\x3d\xd3\xf9\x7f\xda\x35\xfa\xf3"
+  "\x2f\x7f\xda\xef\xaa\xf3\xff\x9c\x2c\xe2\x64\xeb\xf0\x75\xfe\x9f"
+  "\x9f\x77\xaf\xf3\xff\x1c\xe3\xaa\xf3\xff\x3c\x9b\xeb\xf6\x3f\x1b"
+  "\xb8\xce\xff\xf3\x7c\x9e\xbe\x77\x8b\x73\xba\x43\xe7\xf3\x74\xae"
+  "\xf3\xff\xbc\x63\x78\xeb\x5d\x01\x37\xe8\x7a\x97\xfa\xdf\x64\xbd"
+  "\xeb\x6d\xf5\x4d\xbd\xe3\xad\xde\xf9\xf3\xfe\x91\xe9\x9d\xff\x1a"
+  "\xd2\xff\x87\x7b\xbd\x73\x20\xd2\xa1\x77\x0e\x44\x0e\x4f\xef\xec"
+  "\xaf\x73\xd5\x3b\x7f\xf9\xe5\x4d\xbd\x33\x52\xbd\xf3\x76\xe4\xc8"
+  "\xf4\xce\xfe\x3e\xfe\x8f\xde\xf1\xd0\xff\xd1\x01\xb7\xfe\x8f\xbc"
+  "\xd7\x3b\x07\xfa\xf8\x3f\x3a\x20\xfa\x3f\xfa\x8b\x17\x7e\x43\x0e"
+  "\x1c\x73\xaf\x77\x0e\xf4\xf1\x7f\x74\x40\xf4\x7f\xf4\x8e\xe8\xff"
+  "\xe8\x80\xe8\xff\xe8\x2f\x4a\xe7\x74\x87\xde\xf9\x8b\x93\xdf\x90"
+  "\x77\x6e\xfa\x3f\xfa\xde\xed\xc3\x7c\x77\x04\xf2\xef\xbd\x30\x87"
+  "\xfc\x7b\x2f\xcc\xfd\x3e\xcc\xbf\x1e\x70\xdd\x87\x59\xf6\xe8\xcd"
+  "\x7d\x98\xde\xc8\xb7\x77\x46\xe8\x17\xe9\xaf\xc9\xae\xf2\xed\xbd"
+  "\x33\x9e\xc9\xb7\xbf\x5e\x1e\x7d\xf9\xf6\x9e\xc2\x55\xbe\xbd\xd7"
+  "\x20\x62\xc3\x0b\xf9\xf6\xde\x5f\xdd\xcb\xb7\xf7\xde\x77\x95\x6f"
+  "\xef\x19\xb8\x1c\x7b\xaf\x95\xcb\xb7\xf7\xf6\xf0\xf4\x32\xa5\x73"
+  "\xba\x43\xbe\x95\x39\xc9\xb7\xf7\xcc\xc3\x5b\xd7\xf4\xca\xae\xbe"
+  "\x0e\xeb\x9a\xa3\x65\x57\xdf\xe8\xeb\x9a\x07\xe3\x6e\xce\xa3\x79"
+  "\x63\x53\xff\xb7\x62\x64\x36\xf5\xdf\x4c\xde\xeb\x94\xf2\x4a\x87"
+  "\x4e\x29\xaf\x74\xb7\xbe\xb3\x09\x70\x67\x00\x9b\x38\xe7\x22\x51"
+  "\xbc\x89\xeb\x3b\x8d\x75\x24\x17\xd7\x77\x56\x4a\xeb\x3b\xbb\x44"
+  "\x3b\xbb\xfc\x61\x57\x3b\xfb\xff\xbc\x3f\x90\x9d\x8d\xf6\xb5\x1d"
+  "\x6c\x67\x5b\xdf\x75\x9d\xdf\x0c\xac\x8b\xba\xfd\x8a\x75\x57\xff"
+  "\x18\xdf\x34\x5c\x5d\x54\xbc\x8e\xeb\xa2\xa2\xef\xbd\x2e\x3a\x58"
+  "\x36\x32\x5d\x54\xae\x70\xd5\x45\xef\xbf\xe6\x99\x2e\x2a\xdf\x30"
+  "\xfa\xba\xa8\x7c\x8b\xab\x2e\x7a\x3f\x4a\xc4\x8a\x17\xb1\x25\xdf"
+  "\x7f\xd4\xbd\x2e\x7a\x7f\x9e\xab\x2e\x7a\x5f\xc3\x75\xce\xfb\x7a"
+  "\xae\x8b\xde\x0f\xe1\xe9\xff\x27\xca\x39\xdd\xa1\x8b\x78\x3a\xd7"
+  "\x45\xef\xa7\x0c\x6f\x8e\x67\xdc\x0d\x3a\xc7\xa3\xfc\x37\x99\xe3"
+  "\xf9\x1f\x8b\xf7\x32\xf1\x83\xf2\xda\xde\xf3\x1b\x1f\x94\xf7\x9b"
+  "\x67\x48\x02\x7b\xbb\x83\xaf\x73\xf7\xce\x33\x98\x4e\x8a\xf2\xef"
+  "\x83\x59\xae\xf2\xef\xff\xba\x95\x7f\x83\xad\x65\xe3\xbc\x82\x1d"
+  "\x64\x23\xc6\xc8\xf4\x7a\x2d\x3b\xe9\xfb\x2e\xf3\xde\x1f\xa1\x7f"
+  "\xe5\x43\x56\x57\x99\xf7\xe1\x32\xcf\x64\xde\x07\x6b\xdc\xca\x3c"
+  "\xaf\xcf\x71\x7c\x90\xe9\x2a\xf3\x3e\x5c\x24\xe2\xe3\xb5\xe1\xcb"
+  "\xbc\x0f\xef\x73\x2f\xf3\x3e\x7c\xd8\x55\xe6\x7d\xa8\xe2\xb2\xed"
+  "\xc3\x58\x2e\xf3\x3e\xd4\xf2\xf4\xff\xab\x77\x4e\x77\xc8\x3c\x9e"
+  "\xce\x65\xde\x87\xfa\xc1\x64\x1e\x35\xc4\xe8\xb6\xc8\x85\x32\xb8"
+  "\xca\xa1\x8e\x53\x00\x1b\x15\xf0\x7f\x35\xf0\x78\x22\xfc\xef\xd6"
+  "\x47\x8d\xd9\x2f\x46\x27\x64\x40\x9d\xe5\x44\x66\x34\x7f\x5b\x51"
+  "\x31\xd5\x86\xf5\x14\xcf\xac\xc5\xe8\x02\x6c\xe3\xe6\x0b\x34\x8e"
+  "\x00\x5f\x74\x2c\x7e\x26\xe4\xc7\xf3\x41\xda\x24\xe2\x7f\x51\xf6"
+  "\x91\x5a\xca\x07\xf5\xf5\x6f\x91\x7d\x58\x87\x65\x74\x65\x7d\x14"
+  "\x04\x6d\x49\x71\x5b\x57\x28\x2b\xe2\xed\xe9\x64\xbd\x8d\x7e\x53"
+  "\xb1\xb2\x83\xb4\xca\x3e\x5a\x16\xd0\x3e\x6e\x3e\x4d\x8b\x24\x68"
+  "\xcb\x95\x4d\x35\x2b\xb0\xcc\x8a\x95\xdd\xf8\x6e\x3e\xbe\xb3\x43"
+  "\x1d\x53\x57\x10\x79\x5e\xc7\x38\x25\xc8\x89\x31\x69\x16\xda\xb6"
+  "\xca\x06\x75\x06\x6c\x7e\x34\xbd\x49\xf1\x6e\x11\xa4\xd9\x89\x06"
+  "\xe3\x99\x62\x19\x60\xcf\x42\x7d\x3e\x5a\x5e\x0a\xf9\x07\xaa\xc3"
+  "\xef\xdf\x21\x21\x63\x66\x52\xd3\xf0\x70\xf3\xd1\x21\x77\x74\x0c"
+  "\xd8\x30\x9d\x54\xdc\x0d\xb4\xd3\x12\xf9\x40\xef\x87\xf7\x9d\x8a"
+  "\xc1\xce\xbf\x2b\x31\x46\x72\xda\x4e\x22\xdf\x2c\x8c\x53\x1e\x4e"
+  "\x61\x31\x8a\xcd\x5d\x59\x15\x5b\x4c\xb2\xe0\x43\x48\x73\x8c\x6b"
+  "\x89\xf1\xb5\x01\x37\x04\xd2\xf7\x7d\x0c\x23\xdf\xbe\xbc\x48\x88"
+  "\x5d\x11\xa3\x4d\x5c\xbe\x62\xd9\xaa\x35\x89\xda\x19\xb1\xe3\xc9"
+  "\xe2\x55\xab\xb4\x2b\x62\x56\xae\xd5\x3a\xbf\x79\x44\x1b\xbb\x7c"
+  "\x75\xcc\x4b\xf1\xcb\x66\xad\x78\x59\x3f\x1e\x37\x2e\x39\xd5\x23"
+  "\x10\xeb\x22\x64\x55\x1c\x2c\xcd\x27\xa4\x60\x12\x51\x60\xbd\xba"
+  "\xb2\x3e\xd6\x48\x71\x4f\xf3\xb6\x53\x8b\x1c\xf2\xa4\x81\x7c\xdc"
+  "\x9c\x3a\x0e\xf3\x06\xef\x86\x7a\x95\x42\xbd\xa1\x8e\x50\xe7\x8f"
+  "\xe7\x4a\x75\x96\x30\x91\x86\x98\x48\xed\x00\x0c\x7e\xbc\x2c\xc0"
+  "\x3a\xee\x49\x4a\x23\xb1\x7d\x16\xe8\x27\x32\x48\xfb\x1b\xd3\x65"
+  "\xb9\x31\x3a\xf8\x6d\xba\x84\x31\xfc\x2d\xcd\x8b\x36\x77\x61\x3f"
+  "\xa1\x71\x3f\xe5\x7d\xea\x93\xc8\x67\x75\x32\xc2\xe3\xae\x7e\xbc"
+  "\xdf\x11\x77\xf5\x13\x36\x57\x0d\xf5\x68\x87\xf4\x4a\x13\xb9\x92"
+  "\x89\xe9\x18\x2f\x18\xe3\x77\x63\x9d\xa1\x5d\xa0\x4b\x69\x05\xcd"
+  "\x10\xb1\x9f\x7d\x30\x59\xc8\x3e\x56\x66\x54\x5c\x21\x11\x36\xda"
+  "\x43\x73\x0e\x26\xd7\x5b\x2c\x24\x60\x83\xfe\x65\x3a\xb6\xa2\x2a"
+  "\xc0\xb6\x7c\xd9\xee\x49\xd0\x87\x72\x8e\x95\xd1\x9c\x9a\x92\x67"
+  "\x67\x12\x75\x57\xd6\x27\xce\xf1\x5f\x15\xc3\xe3\xff\x27\x8c\xff"
+  "\xc8\x47\xa8\x8f\xc8\xc7\x4f\xf4\x1f\x27\xf6\xe7\x63\x2f\xfe\xde"
+  "\x16\x48\x15\x60\x81\xaa\xb6\xea\x23\xec\x9c\x8e\xd8\x77\x3b\xd3"
+  "\xe2\xc8\xbd\x8c\x76\x87\x75\x42\xde\xd6\x45\x82\x61\x6b\x36\x35"
+  "\x6c\x4d\x04\x9a\x29\xf3\x92\x88\x76\xa9\x5d\x4d\x72\xaf\x90\x50"
+  "\x73\xee\x56\xbd\x9f\x2c\x5d\x06\xf6\x88\x1c\xf4\x49\x28\xc8\x8c"
+  "\x50\xb1\xbf\x2b\x91\x8e\xff\x68\x27\xe4\xe9\xd5\x84\x7c\x33\x87"
+  "\xf8\x94\xc2\xef\x86\xd9\x1e\xa6\xff\x69\xd6\x27\xfb\x77\xc3\x6f"
+  "\x31\xae\xef\xf0\x7e\x7f\x78\xb6\xdb\x7e\xe7\x68\xb7\x79\xe0\x76"
+  "\x57\x6a\xa1\xdd\x0d\x82\x21\x1f\x64\xe4\x56\xcb\x00\xed\x36\xf3"
+  "\x76\x8f\xe9\x18\xfd\x76\x1f\xe6\xfe\xaf\xb3\x0e\xef\xf5\xae\xdd"
+  "\x95\x21\x43\xb7\x3b\xdf\x0d\xbf\xab\x34\x42\x5e\x3e\xf0\x3b\x1f"
+  "\xf8\x9d\x3f\x00\xbf\xf3\x45\x7e\x4f\x68\x19\xfd\x76\x57\xb6\xf2"
+  "\x76\x57\x96\x78\xd7\xee\x2a\xb7\xf2\xcf\xa9\xdd\x6e\xf8\xfd\x77"
+  "\x35\xb4\x1b\xf8\x5d\x00\xfc\xce\x1f\x80\xdf\xf9\x22\xbf\x27\x7e"
+  "\x3a\xfa\xed\xae\xe2\xfe\x0f\xb3\xaa\x0a\xbd\x6b\xf7\xdf\x83\x86"
+  "\x6e\x77\x81\x1b\x7e\xff\x43\x29\xe4\x15\x00\xbf\x0b\x80\xdf\x05"
+  "\x03\xf0\xbb\x40\xe4\xf7\x43\x9b\x46\xbf\xdd\x7f\x6f\xe4\xed\xfe"
+  "\xbb\xc1\xbb\x76\xff\xc3\xed\xfe\x17\xa7\x76\xbb\xe1\x77\x35\x81"
+  "\x76\x03\xbf\x0b\x81\xdf\x05\x03\xf0\xbb\x40\xe4\xf7\x0b\x8f\x8f"
+  "\x7e\xbb\xff\x51\xcb\xdb\xfd\x8f\x4c\xef\xda\x5d\xed\x76\xff\xbb"
+  "\x93\x5c\x4b\x06\x99\xdd\x8f\xe7\xc6\xe4\x30\x72\xcf\x15\x6c\xff"
+  "\x11\x3d\xf5\xdb\x9a\x3c\x61\x43\xba\xcc\xa6\xda\x9a\x32\x01\xc6"
+  "\x72\xc5\x19\x42\x5c\x80\x89\xf8\x42\x5b\xe3\x68\xde\x76\x35\xde"
+  "\x05\x28\xc7\x06\xb2\xdf\xae\xda\x9a\xd8\x6d\x88\x51\xbe\xf9\x0a"
+  "\xd1\xa6\x99\x89\xba\x3e\xd5\x44\x52\xf5\xd4\x5c\x4f\x4e\x13\x3f"
+  "\x13\x91\xe3\x7c\x59\x4d\x7b\x39\x59\x99\x40\x29\x94\xfd\x3c\x8e"
+  "\x31\xf3\xce\x92\x50\xb0\x89\xd3\x29\xe8\x8f\x2d\x02\xd1\x42\xf9"
+  "\xa1\x48\x4b\x28\x7b\x52\xc0\x62\x22\xfb\xf0\x25\x2b\x41\x7a\x22"
+  "\x6d\x61\x3c\x1a\xca\xe8\x0a\x12\xff\x3f\x5e\xe0\x74\x2d\x7e\x65"
+  "\xb8\x74\x3d\xc2\xd7\xff\x0c\x5b\xb7\x18\x4d\xdd\x04\x6c\x4b\x35"
+  "\x9e\xb9\x07\x7a\x99\xea\xf5\x1d\x30\x16\xa9\xce\xa4\xb9\x5b\xd3"
+  "\x05\xd0\x59\xc3\x2c\xd7\xad\xff\x6b\x27\x7a\x5b\x81\xde\xfd\xb0"
+  "\xe6\xa0\xf7\x51\x13\xd0\xdb\x2a\xd2\xdb\x36\xa1\x79\x4c\x87\x1b"
+  "\x7a\x5b\x6d\xa0\x73\x80\xde\x16\xcf\xe9\x7d\xf4\x48\x1f\x7a\x37"
+  "\x5c\x1f\x7a\x1f\x15\xe3\x9f\xe6\xab\x5d\xe9\x7d\x74\x11\xa7\xf7"
+  "\x11\x0b\xcd\xcd\x87\xf1\xff\x56\xf3\x30\xcb\x6d\xf7\x40\x8e\x03"
+  "\xbe\xfb\xeb\x30\x07\xbd\x6b\x17\x51\xbf\x7c\x11\xdf\xf9\x80\xef"
+  "\x09\x2d\x03\xd3\x3b\x1f\xf0\x9d\x0f\xf8\xce\x1f\x06\xbe\x6b\x1f"
+  "\x76\xa5\x77\xfe\x75\xc2\x77\xad\x38\xff\x97\xdf\x07\xdf\x35\x15"
+  "\x9c\xde\x35\xb1\x40\x6f\xc0\x77\xfe\x30\xf1\x5d\x1b\xe5\x01\xbd"
+  "\x01\xdf\xfd\x75\xa7\x83\xde\x75\x15\x40\x6f\x11\xdf\xf9\x80\xef"
+  "\x89\x9f\xba\xa1\x37\xe0\xbb\x00\xf0\x9d\x3f\x0c\x7c\xd7\xbd\xdd"
+  "\x87\xde\xd7\x09\xdf\x75\xdc\xc7\xa4\xa1\xa0\x0f\xbe\xeb\x42\x39"
+  "\xbd\x6b\x1b\x69\x6e\x01\xe0\x3b\x7f\x98\xf8\xae\xab\xf5\x40\x6f"
+  "\x01\xbe\xfb\xeb\x6c\x07\xbd\x8d\xa1\xd4\xaf\x40\xc4\x77\x01\xe0"
+  "\xfb\xa1\x4d\x03\xd3\xbb\x00\xf0\x5d\x00\xf8\x2e\x18\x06\xbe\x8d"
+  "\x53\x5c\xe9\x5d\x70\x9d\xf0\x5d\xdf\x2a\xd2\xbb\x0f\xbe\xeb\xf7"
+  "\x70\x7a\xd7\xcf\x05\x7a\x03\xbe\x0b\x86\x89\x6f\xe3\x1c\x0f\xe8"
+  "\x0d\xf8\xee\x6f\x2b\x38\xe8\xdd\xb0\x07\xe8\x2d\xe2\xbb\x00\xf0"
+  "\xfd\xc2\xe3\x6e\xe8\x0d\xf8\x2e\x04\x7c\x17\x0c\x03\xdf\x0d\x39"
+  "\x7d\xe8\x7d\x9d\xf0\xdd\x20\xc6\xbf\x2c\xec\x83\xef\x06\x35\xa7"
+  "\xb7\xf1\x20\xcd\x2d\x04\x7c\x17\x0c\x13\xdf\x0d\xfb\xbd\xb1\x4f"
+  "\x56\xef\x22\x4a\x57\x9a\x7f\x1a\x78\xed\x6c\x94\x63\xf6\xef\xc6"
+  "\x46\x39\x56\x3d\xb0\x8d\x72\x2c\x93\xd3\xfc\x98\xce\x3b\x1b\xe5"
+  "\x53\xb7\xe7\x1f\x06\xb3\x51\xfa\xd3\xfc\xb3\xec\x6b\x67\xa7\x7c"
+  "\xf6\xda\x77\x63\xa7\x7c\x36\x67\x60\x3b\xe5\x53\x2b\xa7\xf9\xa7"
+  "\x25\xde\xd9\x29\x9f\xb9\xf5\x7f\x30\x98\x9d\xd2\x9f\xe6\x8d\xb6"
+  "\x6b\x67\xab\x34\x9e\xf9\x6e\x6c\x95\xc6\xb2\x81\x6d\x95\xc6\x78"
+  "\x4e\xf3\x46\xb5\x77\xb6\xca\x71\xa5\x37\xb6\x4a\x7f\x9a\x7f\xae"
+  "\xbf\x76\xf6\xca\xe7\xcf\x7f\x37\xf6\xca\xe7\xc1\x03\xdb\x2b\xc7"
+  "\xc5\xf1\xcf\xf1\x4c\xef\xec\x95\xcf\x3d\x18\xff\xf4\xb7\x57\xfa"
+  "\xd3\xfc\x8b\xd6\x6b\x67\xb3\x7c\x51\xf7\xdd\xd8\x2c\x5f\xec\x18"
+  "\xd8\x66\xf9\x62\x31\xa7\xf9\xe7\x56\xef\x6c\x96\x2f\xdc\xc6\x3f"
+  "\x19\xcc\x66\xe9\x4f\xf3\x13\x91\xd7\xce\x6e\x39\xf1\xd8\x77\x63"
+  "\xb7\x9c\x50\x0d\x6c\xb7\x34\x55\x73\x9a\x37\xc5\x7b\x67\xb7\x9c"
+  "\x88\xf5\xc6\x6e\x41\x5a\x23\xcd\xd1\x56\xe1\x34\x6f\xd6\x51\xff"
+  "\xad\x8b\x7a\xc0\x1e\xf1\x03\xba\xfb\xb5\x13\xf9\x2e\xa4\x79\x13"
+  "\xa7\xb9\xdd\x7f\xbb\x1a\xe8\x13\x87\x34\x63\xed\xf8\x97\xc6\xdf"
+  "\x6e\xd8\x9a\x42\xe5\x04\xda\xa2\x24\x67\x65\x5f\x3e\x68\xcb\x20"
+  "\xfe\xda\xd4\x0d\xf0\x7f\xf3\x14\xcc\xa3\x4d\xcd\x3a\x09\x6d\xf4"
+  "\xc1\x35\x0a\x5b\x6e\x74\x99\xdd\x6f\x5b\xe8\x59\xd9\x3f\xd7\xd0"
+  "\x69\x51\x65\x3d\x60\x4b\xd0\xdf\x69\x02\x8d\xed\x65\xc4\x68\x3b"
+  "\x4a\xea\x9b\xfe\x87\x08\xfe\xdb\x27\xdd\x6b\x23\x3a\xfa\x2f\x5d"
+  "\x60\x6d\xa2\x89\xd8\x5f\xd6\xa8\x8c\xc9\xd5\x80\x8b\xf7\x48\x44"
+  "\x1b\xbd\x42\xbf\xd6\xa9\x7a\xfc\x8a\xf4\x50\x8e\xd9\x9e\x5b\x1c"
+  "\x66\xf3\x2b\x8a\x3e\x90\x64\x92\xab\xac\x44\x17\xdf\x4a\x69\xde"
+  "\x4b\x44\x91\xd7\x42\x94\x9b\x5f\x22\xaa\xcd\x2d\x44\x5d\xdb\xda"
+  "\x44\xea\xce\x57\x93\xba\x8e\x13\xa4\xee\x0a\x5c\xdd\x70\x09\x70"
+  "\xa5\x9f\x20\xb5\x30\x5a\x5f\x78\x81\x90\xb4\x56\x6a\xfe\x71\x33"
+  "\x09\xac\xb5\x35\x11\xed\x12\x42\x2e\xca\xfe\xe9\xab\x8a\x26\x81"
+  "\xf4\x6b\x0d\xa1\x2f\x6b\xe4\xf0\x4e\x81\xe9\x46\x9b\x99\xd4\xb6"
+  "\x5a\xe1\xfd\x97\x6d\xf0\x5e\x91\xd6\x0a\xe5\x0b\xd5\xe8\xcb\xd0"
+  "\x5c\x9b\x7e\x04\xda\xa7\xde\x03\x74\xce\x96\x6c\xb2\xbc\x6e\x12"
+  "\xba\x19\xd8\x8c\x98\x89\xa0\x1c\x33\xbb\xbb\x87\x8b\x99\x7f\xb2"
+  "\xf3\xc0\x40\xa7\x49\x40\xef\xa9\xc2\xef\x22\xd5\x4f\x9f\x38\x45"
+  "\x71\x3f\x18\xae\xcf\xd4\x5b\x8e\x12\x5c\xb3\x8e\x58\x4b\xc8\x02"
+  "\x3b\x21\x48\x13\x5c\x4b\x7e\x5a\x4f\x02\x70\x9f\x9a\xf0\x2f\xdd"
+  "\x24\x63\xab\x99\xac\xb7\x41\x5d\x2f\x5a\x7b\xeb\x5a\x9f\x59\x4f"
+  "\xe0\xdd\xd4\xfa\x38\x13\x51\xe9\x89\x1a\xe9\x0c\xb6\x68\xf2\xd3"
+  "\x6d\xc4\x77\xa5\x85\x52\xa4\x31\xd2\x16\xe9\x8c\xe5\x49\xb4\x37"
+  "\xc6\x9a\x49\x9a\x95\xa8\x8d\xa9\x70\x4f\xa6\x66\x23\xb9\x44\xa0"
+  "\x8e\x41\xd4\x4f\xbd\x07\xf0\x11\x88\x98\x30\xc9\xbe\x0c\x01\x1c"
+  "\x4c\xa2\x59\x27\x4c\xa5\xd0\x5e\x5c\xdb\x1f\x5e\x9b\x9b\x3d\x59"
+  "\xff\xe8\x67\x13\x3a\xe1\xd9\xca\xf1\xfc\x95\x15\xf0\xdc\x00\x78"
+  "\xb6\x70\x3c\x8f\xe9\xf0\x00\xcf\x36\x07\x9e\x4f\x8e\x71\xe0\xf9"
+  "\xab\x73\xee\xf1\xfc\xd5\x3c\x8e\xe7\x7c\xf5\x8d\x89\xe7\x93\x27"
+  "\x06\xc7\xf3\xc9\x72\xf7\x78\xce\x57\x4a\xf6\xee\xe8\xe0\xf9\x2b"
+  "\xf5\x75\xc4\xb3\xd5\x3b\x3c\x9f\x6c\x77\xc5\x73\xb3\x8d\xe3\xb9"
+  "\xb9\xcc\x3b\x3c\x9f\x72\xeb\xff\x78\x30\x7b\xdb\x81\xe7\x7c\x51"
+  "\x3e\x9f\xae\xa6\xfe\xf9\x20\x9f\xf3\x45\xf9\x3c\xa1\x65\x68\x3c"
+  "\xe7\x3b\xc9\xe7\x53\xc7\x1d\x78\x3e\xfd\xbe\x7b\x3c\x9f\xbe\x45"
+  "\xc4\xf3\x0d\x2a\x9f\x4d\x6f\x0f\x8e\x67\x53\xf6\x20\x78\xce\x96"
+  "\xc6\x12\xa3\x83\x67\x93\xe9\xfa\xe1\x39\xdf\x4b\xf9\x6c\x3a\xe4"
+  "\x8a\xe7\x53\xb5\x1c\xcf\xa7\xd2\xbd\xc3\xf3\xe9\x46\x6f\xc6\x32"
+  "\x4e\x78\x16\xe5\x73\xeb\x0e\xc0\x33\xc8\xe7\x7c\x51\x3e\x4f\xfc"
+  "\xd4\x03\x3c\x3b\xc9\xe7\x96\x3f\x3a\xf0\xdc\x9a\xe3\x1e\xcf\x5f"
+  "\x9f\xe1\x78\x2e\xb8\x41\xe5\xf3\xd7\x6b\x07\xc7\xf3\xd7\x91\xee"
+  "\xf1\x5c\xa0\x94\xc6\x69\xa3\x83\xe7\xaf\xcb\xae\x23\x9e\xbd\x94"
+  "\xcf\x5f\x1b\x5c\xf1\xdc\x52\xc2\xf1\xdc\xb2\xc8\x3b\x3c\xb7\xee"
+  "\xf5\x66\x9c\xe8\xc0\x73\x81\x28\x9f\xbf\x89\xa3\xfe\x05\x20\x9f"
+  "\x0b\x44\xf9\xfc\xd0\xa6\xa1\xf1\x5c\xe0\x24\x9f\xcf\xac\x71\xe0"
+  "\xf9\x9b\xe7\xdd\xe3\xf9\xec\xdf\x44\x3c\xdf\xa0\xf2\xf9\xec\x2f"
+  "\x06\xc7\xf3\x59\xdd\x20\x78\xce\x96\xc6\xc0\xa3\x83\xe7\xb3\xe9"
+  "\xd7\x0f\xcf\x05\x5e\xca\xe7\xb3\x51\xae\x78\x3e\x13\xcf\xf1\x7c"
+  "\x46\xeb\x1d\x9e\xbf\x71\x1b\xff\x75\xb0\x31\xb8\x13\x9e\x45\xf9"
+  "\x7c\x3e\x0c\xf0\x0c\xf2\xb9\x40\x94\xcf\x2f\x3c\xee\x01\x9e\x9d"
+  "\xe4\x73\xdb\x3c\x07\x9e\xcf\xcf\x74\x8f\xe7\x73\xbf\xe7\x78\x2e"
+  "\xbc\x41\xe5\xf3\xb9\x29\x83\xe3\xb9\xcd\xea\x1e\xcf\x85\x4a\x69"
+  "\x7e\x61\x74\xf0\x7c\x6e\xd1\x75\xc4\xb3\x97\xf2\xf9\x5c\x88\x2b"
+  "\x9e\xdb\xe6\x70\x3c\x7f\x63\xf6\x0e\xcf\xe7\xe7\x8e\xce\xfc\xc6"
+  "\x85\x30\x9c\xdf\xe8\xc6\xf9\x0d\xc7\xde\xbf\xb8\x80\x06\x8e\xe7"
+  "\x1e\xc0\x73\xb1\x33\x9e\xff\xd9\x77\x7e\xe3\x5f\xb7\x08\xbd\x78"
+  "\xbe\xd0\x0f\xcf\x02\xe0\xb9\x87\xe1\xb9\xfd\x31\x69\x7e\xc3\xd8"
+  "\xbe\x07\x70\x72\x9e\x18\x17\x01\x96\xf3\x44\x2c\xff\x13\xb0\x0c"
+  "\x34\x14\x80\xc6\xb5\xcd\x4d\x24\xc2\xcc\x69\xd9\x0d\x34\x16\x9c"
+  "\x71\xdc\xdd\x26\x47\xfc\x22\x6e\x25\x0c\xd7\xad\x04\xec\x26\x1c"
+  "\x23\x75\x49\x70\xad\x83\x2b\x15\x2e\x72\x8c\xd4\xb6\x01\x76\x97"
+  "\x3b\x63\xb7\x41\xc4\xee\xbf\x8e\x0f\x8e\xdd\x7f\x1d\xbc\x7e\x73"
+  "\x19\xed\x7c\xfe\xeb\x9f\x91\xea\x88\x5f\x9e\xa2\xc6\xe4\x26\x11"
+  "\x9f\xe7\x49\x84\x8d\x04\xd0\x17\x74\x93\x54\x91\x44\xfd\x86\x9d"
+  "\xc8\x73\x5f\x22\xea\xdc\x2f\xa1\xdd\x52\xff\x6d\x21\xaa\xa3\xd6"
+  "\xff\x21\xb5\x1d\x4d\xa4\xf6\xca\x11\x52\x2b\xc0\x75\x1e\x2e\xa8"
+  "\x6b\xc4\x32\xe7\x76\x9b\xc5\x76\xb7\xd7\x41\x59\xc1\xee\xdb\xdd"
+  "\xbe\x9f\xb5\x3b\x16\xda\xdd\xed\x68\xb7\x11\xfa\x01\xf0\x67\xaa"
+  "\x20\xce\x87\x44\x98\x89\xef\x2a\x1b\xa5\xdd\x22\xfe\x91\x3f\x47"
+  "\x1b\xad\x24\x42\x0f\x3c\x7b\x19\xf0\xdf\xba\x8f\xa4\xa5\x00\xfe"
+  "\xbb\xad\x88\x3b\xb3\x31\xfd\x2a\xe0\xff\x5f\x6d\x14\xe8\xd7\x83"
+  "\xf8\xff\x27\xe2\xff\x5f\x2a\x81\xe1\xff\x7c\x85\x77\xf8\xbf\xe0"
+  "\x09\xfe\x3d\x98\x0f\x31\x23\xfe\x1b\xba\x71\x3e\xc4\xb1\x07\x74"
+  "\x28\xfc\x3b\xc9\xf3\x8b\x4e\xf8\x37\x0f\x82\xff\x6f\x1f\x93\xe6"
+  "\x43\xbe\x7b\xfc\x5f\x1c\x02\xff\x17\x07\xc1\xff\x68\xcf\x7d\x7c"
+  "\x7b\x1d\xf1\xff\xed\x10\xf8\xff\xd6\x13\xfc\x5b\xbd\xc3\xff\xc5"
+  "\x3e\xf8\xbf\x28\xe2\xff\x82\x97\xf8\x37\x7b\x80\x7f\x4f\xe6\x4f"
+  "\x3a\xc3\x70\xfe\xa4\x1b\xe7\x4f\x1c\x7b\x81\x87\xc0\xbf\xf3\xfc"
+  "\xc9\x25\x27\xfc\x77\x0e\x82\xff\x0e\x09\xff\x37\x80\xfc\xbf\x34"
+  "\x04\xfe\x2f\x0d\x86\xff\x51\x9e\x2b\xe9\xb8\x8e\xf8\xef\x18\x02"
+  "\xff\x1d\x1e\xe0\x3f\xdf\x4b\xf9\x7f\xa9\x0f\xfe\x2f\x89\xf8\x37"
+  "\x7b\x89\xff\x4e\x4f\xf0\xef\xc1\x7c\xcb\x15\xc4\x3f\xc8\xff\x7c"
+  "\x8b\xd3\x9e\xf0\xa1\xf0\xef\x24\xff\x2d\x4e\xf8\xbf\x32\x08\xfe"
+  "\x2f\x3f\x26\xcd\xb7\x7c\xf7\xf8\xb7\x0c\x81\x7f\xcb\x20\xf8\x1f"
+  "\xed\xb9\x95\xcb\xd7\x11\xff\x97\x87\xc0\xff\x65\x4f\xf0\xef\xa5"
+  "\xfc\xb7\xf4\xc1\xbf\x45\xc4\x7f\xa7\x97\xf8\xbf\xe2\x01\xfe\x3d"
+  "\x99\x9f\xb9\x8a\xe3\x59\x90\xff\x05\x89\x4e\x67\x03\x86\xc0\xbf"
+  "\xf3\xfc\x4c\x97\x13\xfe\xaf\x0e\x82\x7f\xab\x84\xff\x1b\x40\xfe"
+  "\x77\x0d\x81\xff\xae\xc1\xf0\x3f\xca\x73\x31\xd6\xeb\x88\x7f\xeb"
+  "\x10\xf8\xb7\x7a\x80\xff\x02\x2f\xe5\x7f\x57\x1f\xfc\x77\x89\xf8"
+  "\xbf\xe2\x25\xfe\xaf\x7a\x82\x7f\x0f\xe6\x73\x6c\x6c\x3e\xa7\x1b"
+  "\xe7\x73\x1c\x67\x44\x86\xc2\xbf\x93\xfc\xef\x76\xc2\xbf\x6d\x10"
+  "\xfc\xf7\x3c\x26\xcd\xe7\x7c\xf7\xf8\xef\x1e\x02\xff\xdd\x83\xe0"
+  "\x7f\xb4\xe7\x6e\x7a\xae\x23\xfe\x7b\x86\xc0\x7f\x8f\x27\xf8\xf7"
+  "\x52\xfe\x77\xf7\xc1\x7f\xb7\x88\xff\xab\x5e\xe2\xdf\x36\x4a\xf3"
+  "\x3f\x76\x13\xce\xff\x08\xaa\xad\x89\x3d\x25\x51\x65\x82\xa1\x48"
+  "\x1f\x20\xd3\x12\x9b\x6a\x5b\xa8\x31\xd1\x42\x9e\xbe\x0c\x3c\xd1"
+  "\x5f\x26\x4b\x2e\xab\x31\x96\x65\x34\x85\xf1\xbf\xcb\x19\x51\xb8"
+  "\x6c\x06\xf5\x9e\xcd\x2b\x89\xc2\xee\xbf\x7d\x12\xa6\x19\xcf\x5a"
+  "\x09\xb6\x79\x3d\xd2\xe0\xbc\x83\x06\x38\x07\x47\xbf\xd5\xa9\x4b"
+  "\x33\x20\x4f\xb7\x89\xb4\x02\x5e\x6a\x5b\x4d\x40\xfb\x75\x0c\x5b"
+  "\xc8\x0b\xa8\x4f\xfa\xee\x8b\x44\x61\xfb\x5a\x33\x15\x78\x1c\xe8"
+  "\xf7\x3a\x91\x05\xb5\x52\x01\x79\x89\x3c\x42\xbe\x6a\xd7\xe1\x7e"
+  "\x25\xfb\x89\x7a\xc0\xb7\xed\x6b\xdd\xd4\x52\xc8\x37\xfa\xf3\x32"
+  "\xf6\xbd\xfc\x3c\xbe\x3d\xb9\xb6\x19\x68\x99\x65\xf3\x92\x4f\x76"
+  "\x0f\xce\xbf\x78\x32\x4f\x41\xb3\x71\x9e\x02\xf8\x64\xf1\x90\x4f"
+  "\x56\x97\x33\xad\xa3\xce\x27\xaa\xf3\x8c\x4f\x74\x83\x2b\x9f\x46"
+  "\x7b\xfe\x80\x2e\xe0\x7c\xa2\x5a\xce\x27\x21\xce\x3b\x3e\x51\xaf"
+  "\xf6\xff\xf6\x1b\x4f\xcb\x65\xa1\x38\x9e\x16\x60\x3c\xed\x19\x9f"
+  "\xf2\x93\x5d\xce\xe0\x8e\x36\x9f\xe4\xa4\xc1\x23\x3e\xc9\x65\x33"
+  "\xfb\xf0\x69\x74\xc7\xb9\x72\xc2\xce\x7f\xc3\xbd\x9a\xf1\x69\x13"
+  "\x51\x7b\xc5\x27\xb9\xcc\x83\xf3\x1f\x1e\x8c\xfb\xe4\xf2\x26\x1c"
+  "\xf7\x01\x9f\x3c\xec\x4f\xf9\x56\x97\x33\xc3\xa3\xce\x27\x79\xb2"
+  "\x67\x7c\x92\x1f\x73\xe5\xd3\x28\x8f\xc7\xe4\xf2\x12\xce\x27\xb9"
+  "\x9e\xf3\x49\x56\xee\x1d\x9f\xe4\xad\xa3\x32\x3e\x91\x2b\xd2\x71"
+  "\x7c\x22\xc0\xf8\xc4\x33\x3e\x15\x24\xbb\x9c\x71\x1e\x75\x3e\x29"
+  "\xb4\x9e\xf1\x49\xb1\xb6\x0f\x9f\x46\x77\xdc\x20\x57\xf0\x78\xc0"
+  "\x72\x85\x86\xf3\xc9\x27\xda\x3b\x3e\x29\xdc\xfa\x3f\x1d\x96\x1d"
+  "\x2d\x1f\xab\x43\x3b\x1a\xf8\xe4\x61\x7f\x2a\xb0\xba\x9c\xc9\x1e"
+  "\x75\x3e\x8d\xa9\xf6\x8c\x4f\x63\xef\x70\xe5\xd3\x28\xdb\xb7\xf2"
+  "\x31\xed\x9c\x4f\x63\x2a\x38\x9f\xc6\x28\xbd\xe3\xd3\x58\x4f\xf6"
+  "\x7f\x0e\x78\x0e\xab\x9f\xcd\x27\x1f\xd7\x78\x43\xd9\x7c\xf2\x71"
+  "\x89\x9e\xf1\x6a\x5c\xdd\x35\xb5\xf9\xe4\xe3\x76\x70\x5e\x8d\x8b"
+  "\xe7\xbc\x1a\x7b\xd0\x3b\x5e\x8d\x33\x79\x7b\x7e\xab\x9f\xdd\x27"
+  "\xf7\x4d\xbf\xa1\xec\x3e\xb9\xaf\x87\xf2\xcf\x77\xed\x35\xb5\xfb"
+  "\xe4\xbe\xa2\xfc\xf3\x15\xe5\x9f\xd2\x4b\xf9\xe7\xeb\x81\xfc\x1b"
+  "\xf8\xdc\x57\x7f\xdb\x6f\x42\xc8\x8d\x65\xfb\x8d\xaf\xf5\x8c\x57"
+  "\x13\x66\x5c\x5b\xdb\x6f\xbc\x99\xf3\x6a\x7c\x25\xe7\xd5\x78\x95"
+  "\x77\xbc\x9a\x10\xe6\xed\x79\xb1\xfe\xf6\x9f\xea\x06\xb3\xff\x54"
+  "\x1e\xda\x7f\xaa\x6b\x6c\xff\xa9\x44\xfb\x4f\x25\xda\x7f\x13\xbc"
+  "\xb4\xff\x54\x5e\xd9\x7f\xae\xbc\x92\x6c\x40\xff\xcc\x1b\xcb\x06"
+  "\xf4\x0f\xf6\x8c\x57\xfe\xeb\xaf\xad\x0d\xe8\x3f\x9f\xf3\xca\x3f"
+  "\x88\xf3\xca\x2f\xd6\x3b\x5e\xf9\xbb\x8d\x7f\x3b\xd4\xf9\xb4\xfe"
+  "\x76\xa0\x3a\xf4\xc6\xb2\x03\x03\x3c\x1c\xff\xaa\x67\x5e\x5b\x3b"
+  "\x30\x40\x1c\xff\x06\x88\xe3\xdf\x00\x2f\xc7\xbf\x6a\x0f\xc6\xbf"
+  "\x1e\xcc\xfb\xc9\x27\x6d\x41\x1b\xd0\x6e\xd8\x9a\x18\x00\xf4\x0f"
+  "\x48\x26\xf2\xee\x20\xe0\x97\x0a\xf8\xb5\x41\x4b\x7a\x0c\xc0\x2f"
+  "\xb3\x8d\x3c\xfd\xda\x29\x5a\xdf\x6e\x27\xdd\xc0\xab\xab\x60\x07"
+  "\x1a\xcd\x6d\x78\x46\xef\x27\x2d\xf2\x49\x33\x5f\x78\x4d\x4d\x90"
+  "\x5f\x48\x7f\xbb\x4a\xbd\x87\x02\xbf\x18\xff\x54\xc5\x61\x36\xc3"
+  "\x36\xf3\xc2\x0b\xa7\xe8\x2a\x13\xa5\x75\x71\x56\xa8\x53\x74\x59"
+  "\x5d\x5c\x13\x89\x68\x25\xbe\xda\x67\x90\x2f\x13\x4f\x60\xba\xd1"
+  "\xdc\x44\xd0\xef\x27\x9b\x03\x3f\xa5\x0b\xb4\x7d\xa1\x53\xa1\xff"
+  "\x26\x3c\x57\x28\xf9\x68\x32\x9e\xdf\xc1\xf8\xdf\x77\x4e\x95\xf1"
+  "\xff\x0b\x1d\xce\xcf\x87\x8e\xbe\x2d\x38\x91\xcd\xff\x09\xa7\x34"
+  "\x53\xa5\x3a\xae\x8a\xa7\x14\xea\x38\xa9\xde\x62\x26\x58\xcf\x7a"
+  "\x4b\x05\x49\x4b\x24\xea\xfa\xee\x36\x92\x6a\xa1\xe6\xfa\xf4\x73"
+  "\x24\xe2\x32\xae\x0b\x20\x9e\x26\xdd\xc1\xf9\x3d\x71\x81\x70\x4a"
+  "\x37\xd5\x24\x9f\xa4\xa9\x6f\x20\x24\x60\x03\xd0\xda\x46\xe4\xec"
+  "\xbc\xa6\x9c\x28\x81\x5e\x71\xc6\xf4\x16\x02\xb4\xd3\x1b\x6d\x5f"
+  "\x22\x3d\xe3\xe0\xfd\x9c\xde\xf5\x06\xff\xed\x09\x98\x86\xb4\xc5"
+  "\x7d\xa6\x46\xbd\x99\xe5\x91\xde\x73\xde\xa5\x13\x63\x72\x37\xa9"
+  "\xb7\x11\x02\xf8\xb0\xd6\x44\x36\x01\xbe\xd4\x5e\xca\xed\x49\x25"
+  "\xa3\x32\x5f\x29\x0f\x34\xa3\xdd\x0a\xf8\xb2\xf0\x3a\x8e\xe9\xf0"
+  "\x00\x5f\x56\x07\xbe\x02\x73\x46\x86\xaf\xc0\x87\x47\x17\x5f\xa3"
+  "\x6d\xbf\x06\x2a\x46\x86\xaf\xc0\x0d\x1c\x5f\x3f\xd8\xcf\xf1\x15"
+  "\x98\xec\xc0\xd7\x98\x8e\x6b\x87\xaf\x1f\x44\x72\x7c\xfd\x40\xe3"
+  "\x1d\xbe\x02\x6d\xa3\x33\xcf\x7a\xeb\x22\xb4\xb5\xed\x86\x7c\x51"
+  "\x7e\x4d\x68\x19\x1a\x5f\xf9\x4e\xf2\x6b\xf2\xb9\x91\xe1\x6b\xf2"
+  "\xce\x51\xc6\xd7\x28\xdb\xdc\x93\x63\x47\x86\xaf\xc9\xa7\x39\xbe"
+  "\x26\xab\x38\xbe\x26\x37\x39\xf0\x35\xa1\xe5\xda\xe1\xeb\x96\x72"
+  "\x8e\xaf\x5b\x92\xbd\xc3\xd7\xad\x5e\xf9\xbf\xea\x3f\x3e\x98\x52"
+  "\x86\xe3\x03\xc0\x97\x28\xbf\x26\x7e\xea\x01\xbe\x9c\xe4\xd7\x94"
+  "\x5f\x8c\x0c\x5f\x9a\xab\xa3\x8b\xaf\xd1\x1e\x27\x68\x2a\x47\x86"
+  "\xaf\x29\x8f\x71\x7c\x69\xe2\x39\xbe\xa6\x84\x39\xf0\x35\xf1\xd3"
+  "\x6b\x87\x2f\x8d\x86\xe3\xeb\xd6\x26\xef\xf0\x35\xc5\xbd\xff\xe7"
+  "\x61\xcd\x6b\x07\xa9\x71\x4c\x63\x37\x14\x88\xf2\xeb\xa1\x4d\x43"
+  "\xe3\xab\xc0\x49\x7e\xdd\xf6\xf6\xc8\xf0\x75\xdb\xf3\xa3\x8c\xaf"
+  "\x51\x1e\xdb\xdc\x16\x3c\x32\x7c\xdd\xf6\x16\xc7\xd7\xd4\x5a\x8e"
+  "\xaf\xdb\x76\x38\xf0\xf5\xd0\xa6\x6b\x87\xaf\xa9\xc9\x1c\x5f\x53"
+  "\xc3\xbc\xc3\x57\x90\x27\xfe\x5f\x3d\x98\x8f\x9f\xae\xc7\x71\x18"
+  "\xe0\x4b\x94\x5f\x2f\x3c\xee\x01\xbe\x9c\xe4\xd7\x74\xdf\x91\xe1"
+  "\x6b\xda\xfb\xa3\x8b\xaf\xd1\x1e\x8f\x4d\xcb\x1c\x19\xbe\xa6\xcb"
+  "\x38\xbe\xa6\x85\x70\x7c\x4d\xb3\x3a\xf0\xf5\xc2\xe3\xd7\x0e\x5f"
+  "\x41\x4d\x1c\x5f\x41\x3b\xbc\xc3\xd7\x74\x4f\xfc\x9f\x7a\xb8\x8e"
+  "\xa0\x6d\x1c\xd9\x18\x52\xbb\x62\x64\x18\xd3\x4e\xbb\xb1\xc7\x90"
+  "\xb7\xb7\x8d\x0c\x63\xda\x65\x1c\x63\xb7\x6f\xe1\x18\xd3\x46\x5d"
+  "\x9f\x31\xe4\xed\x73\x38\xc6\xa6\xdb\xbc\xc3\x98\x76\x14\xd7\x3f"
+  "\xee\x0a\x1b\xd9\x38\xf2\xce\x63\x23\xc3\xd8\x9d\x1b\x6e\xec\x71"
+  "\xe4\x9d\x0b\x46\x86\xb1\x3b\x8f\x70\x8c\xdd\x61\xe1\x18\xbb\xb3"
+  "\xe2\xfa\x8c\x23\xef\xd8\xc3\x31\x76\x87\x97\xeb\x36\x77\x79\x75"
+  "\xfe\x65\xe0\x75\x9b\x19\x25\x23\x1b\x4b\xce\x78\x70\x64\x18\x0b"
+  "\x3e\x73\x63\x8f\x25\x83\xcb\x46\x86\xb1\x19\xb3\x38\xc6\x82\x23"
+  "\x39\xc6\x66\x04\x5f\x9f\xb1\x64\xb0\x82\x63\xec\xae\x4a\xef\x30"
+  "\x36\x63\xdf\xe8\xad\x37\xe9\xc8\xc8\xc6\x93\x3f\xda\x39\x32\x8c"
+  "\xfd\xe8\x17\x37\xf6\x78\xf2\x47\x81\x23\xc3\xd8\x8f\xb6\x72\x8c"
+  "\xfd\xf0\x10\xc7\xd8\x8f\xb2\xaf\xcf\x78\xf2\x87\x71\x1c\x63\x3f"
+  "\xd4\x79\x87\x31\x9d\x07\xfe\xff\x3d\x5d\x27\xbb\x3b\x76\x64\x63"
+  "\xca\x99\xf6\x91\x61\x6c\xe6\x81\x1b\x7b\x4c\x39\x33\x79\x64\x18"
+  "\x9b\x79\x99\x63\x6c\xa6\x96\x63\x6c\x66\xfb\xf5\x19\x53\xea\x6a"
+  "\x39\xc6\x74\x06\xef\x30\x76\xb7\x7e\xf4\xd6\xf7\x42\xaa\x47\x36"
+  "\xae\x0c\x89\x19\x19\xc6\x42\x26\xde\xd8\xe3\xca\x1f\x37\x8f\x0c"
+  "\x63\x21\xcf\x73\x8c\xfd\x38\x93\x63\x2c\x64\xd1\xf5\x19\x57\xfe"
+  "\x38\x94\x63\xec\x6e\xef\xfc\x51\xc8\x43\xfa\xf9\xbf\x5a\xbe\x32"
+  "\x29\x26\x7e\x79\xac\x76\xf9\xca\xc4\x84\xd7\xb4\xab\x97\xaf\x5b"
+  "\xf6\xe8\x8c\x35\x21\xda\x84\x64\x6d\xc2\xf2\x95\xaf\x8a\x09\xb1"
+  "\xe3\xc9\x33\xcb\xe2\x63\x92\x31\x05\x72\xbf\xba\x72\xc5\xb2\x95"
+  "\x89\xda\x84\x65\xaf\xad\x59\x9e\xb0\x0c\xff\x5f\xad\x7d\x65\x55"
+  "\x02\x24\xbc\xbc\x6c\x79\xd2\x32\xed\x4b\x6b\x5e\x79\x65\x59\xc2"
+  "\xea\xf1\x64\xe1\x9a\xf8\xc4\xe5\xfa\xf8\x65\xda\xb9\x0b\x1f\x9b"
+  "\xb5\x78\xde\xaf\x16\xff\xec\x67\x18\x9c\xcc\x29\x36\x59\x10\x35"
+  "\x14\x87\x02\xe6\x14\x67\xe5\x0f\x1e\xab\xd7\x10\x16\x1f\x77\x73"
+  "\x07\x51\x6f\x4a\x20\x8a\x9c\x0e\xa2\xcc\xed\x20\x2a\xed\x6f\x49"
+  "\x38\xcd\x39\x5e\x91\xd7\x41\x02\x69\x5e\x74\xb9\x90\xeb\xd7\x40"
+  "\x73\xfd\xd5\x66\xdf\x2b\x98\xa6\x16\x72\x2e\x5b\xe1\x37\x81\x40"
+  "\x5b\x05\xcd\x55\xa7\xb7\xc8\x1f\xdc\x62\xf6\xed\xda\x93\x76\x8e"
+  "\xc8\xe9\xf8\x7b\x14\xef\x08\x66\xf9\xc7\xe8\x59\x06\xda\x4e\xe4"
+  "\xf7\x06\xc1\xa5\x84\xab\x1c\xae\x6a\xb8\x1a\xe1\x82\x91\x5a\xa8"
+  "\x02\x2e\x0d\x5c\xc1\x70\x85\xc2\x05\x54\x0b\x0d\x87\x6b\x3e\x5c"
+  "\x8b\xe0\xaa\x85\xab\x1d\x2e\xc8\x7b\x5f\x20\x2f\xe7\x3e\x2d\x5c"
+  "\x0b\xe0\x4a\x84\xcb\x40\xe4\xf7\x43\xfe\xfb\xa3\xe1\x32\xc1\x05"
+  "\x23\xed\xfb\x33\xe1\xc2\xf4\x32\xb8\xe0\xf7\xf7\x05\xf3\x77\x0f"
+  "\x64\xc3\x55\x49\xa0\x9e\x43\x5f\x0f\xb4\xc2\x05\xdf\x9d\xad\x86"
+  "\x4b\x0f\x17\xd4\xf7\xc1\xe0\x3e\xf9\xe2\x9d\xfe\xcf\x1e\xa2\xcc"
+  "\x7d\x01\x1b\x6e\x37\xb1\x18\x78\xf2\x7b\xd7\xd2\x0c\xe2\x43\x73"
+  "\xba\xf6\xe8\xef\x26\xb2\xf3\xf2\x7b\xe7\x19\x33\x51\xce\xf8\x35"
+  "\xb0\x98\x8e\xf0\x8c\x34\xeb\xda\x74\xef\x5c\x13\x89\x0f\xc3\x98"
+  "\x66\xc3\xc3\xdb\xbd\x73\xc5\xdf\x67\x9a\x64\x63\xf7\xb1\x18\x70"
+  "\x9b\x6a\x76\xd0\xb4\xc8\x62\x16\xfb\x0d\x68\x88\xe7\xb2\x68\x76"
+  "\x8d\x9a\x2a\xab\x0e\x61\x9f\xaf\x58\xc7\xea\x35\x8d\xf7\x2f\x78"
+  "\x0f\x75\x33\xfb\x45\x97\x43\x3d\x15\xf8\x4c\x73\xae\x54\x74\xfb"
+  "\x15\xa9\xf1\xff\xab\xbb\xa2\xc2\xa9\xa1\x28\x0c\xc7\xd9\x15\xa9"
+  "\x7f\x20\x2d\xf0\xbb\x6e\xbf\xe2\x26\xed\x33\x01\xb4\x85\x97\x2d"
+  "\x87\x7c\x65\x52\x59\xdd\x7e\xd1\x15\x74\x47\x09\xa1\xb9\x80\x21"
+  "\xb1\x3c\x01\xca\xa3\x86\x6d\x26\x93\x3c\x54\x85\xe9\xb4\x24\x2a"
+  "\x52\xfa\x1f\xee\x20\x77\x8a\xd2\xf1\x1e\xb0\x81\x58\xd8\x73\x46"
+  "\x38\xe1\x77\x35\x41\x59\xd7\x2e\x0f\xfd\xeb\xbd\x0d\x44\x56\xf1"
+  "\x0c\xd6\x3b\x34\x25\xad\x81\x0a\xda\x54\x1f\xf8\x7e\xe8\xfa\xde"
+  "\xef\x4e\x29\xb6\x62\xfc\x54\x61\xd3\xac\x40\x8c\xc1\x87\xbf\xc5"
+  "\xba\x15\x4d\x22\x8a\xdd\xf9\x44\x89\x6d\xec\xda\x14\xba\x4f\x8a"
+  "\x43\x87\xbf\x91\x43\xfe\xa7\x7e\x99\x46\x9d\xca\x5e\x43\x79\x7b"
+  "\x34\x9c\xa6\xa1\x4d\x26\x99\xc2\x80\xf9\xb5\x77\x32\x5a\x4e\x13"
+  "\xdf\x07\x21\x3f\xb1\x7c\x21\xb7\x38\x14\x9f\x31\xce\x5d\x40\x03"
+  "\x91\x6b\x53\x83\xcb\x39\x8d\x8a\xc2\xb0\x1c\xcc\x2f\xe4\x6d\xc3"
+  "\xff\x0f\x09\xd0\x5e\x7b\x06\xd1\x69\x57\x92\xf0\x16\xf9\x7d\xf3"
+  "\xec\x39\xb5\x91\xf0\x1e\xfa\x5d\x6d\x14\xe4\x5f\xc4\xe8\x9d\xbb"
+  "\xad\xc1\x24\xbf\x2f\x0c\xde\x45\xf5\xc6\xbe\xe4\x74\x96\x09\x39"
+  "\xb5\xf1\x5d\x9b\xee\x8b\x37\xc9\x6e\xdb\x21\xb5\x81\xc9\x38\x47"
+  "\x3e\x91\xa7\xf7\x45\x9b\x7d\x6b\xe3\x7b\x92\x68\xc3\xe6\x2f\x09"
+  "\x81\x6f\xd2\xee\x2b\xb4\x36\x65\x11\xb5\xe6\x3d\x47\x48\x6d\x74"
+  "\x33\x49\x8b\x21\x41\x13\x36\x50\xd0\x73\x24\x60\x42\x73\x00\xad"
+  "\x5b\xd4\x0c\x32\xfa\x32\x49\x69\xa0\x6d\xf5\xfa\x43\x24\xe5\x0c"
+  "\x51\xad\x5f\x4e\x02\xd3\x16\x51\x73\x6a\x2d\xb5\x1a\x93\x9b\x49"
+  "\xbd\x05\x2e\x7d\x1d\xe4\x3b\x0e\xd7\x21\x92\xb6\x96\x28\x9e\x06"
+  "\x79\x9a\x7a\x99\xa8\xea\xf5\x97\x21\xed\x02\x49\x89\xa6\xb6\xba"
+  "\x5a\xcc\x57\x45\x22\x6c\xe6\x80\xf5\x17\x88\xa2\xf4\x39\x3c\x5b"
+  "\x76\x92\xec\x86\xba\x74\xfb\xf9\x93\xab\xb9\xea\xec\xce\x24\x6a"
+  "\xeb\xda\x74\x7f\x98\x89\x3c\xa2\x75\x69\x0b\xd6\x19\xe3\x86\x42"
+  "\x7b\x31\x8f\x90\xbb\xad\x7c\xa9\x0d\x71\x7e\x7f\x08\xc8\x62\x22"
+  "\xbd\xc7\x77\x66\xbf\x6d\x80\x9f\xfb\x23\x23\x6c\xb4\x0b\xf3\x63"
+  "\xbb\x81\x46\x71\x62\xfb\xe3\x7c\xf4\x44\x01\xdf\x28\x31\xc9\xa6"
+  "\x27\x3a\xf1\x10\x79\x32\x56\xfa\x9e\x98\xa7\xc2\x24\x0b\x62\xb1"
+  "\x17\x05\xfe\x6e\x1f\xe6\x85\x74\xe0\xff\xb4\x4a\x5e\xbf\xfb\xf7"
+  "\x60\x9a\x28\x4b\xb1\x9c\x32\x01\xfb\x75\x76\xd5\x16\xbb\x5f\x51"
+  "\x38\x95\x53\x2b\xe0\xb9\x89\x76\x6a\x54\x4f\xdb\xa8\x55\xc8\x2d"
+  "\x6c\x00\x79\xa9\xc2\x38\xa9\x3c\xff\x03\xaf\xc1\x7b\x93\x36\x89"
+  "\xfd\xff\x3c\x7e\x47\xd8\x15\x15\x8a\xb2\x35\xa2\x01\xf3\xc7\x84"
+  "\xe6\x25\x80\xec\xcd\x2d\x0a\xc5\x7e\x28\xf8\x6d\x6b\xbb\xba\xb3"
+  "\xd8\x84\xfd\x9b\x02\xc6\xa8\x21\xda\xd4\x5b\x4e\x06\x19\x63\x92"
+  "\x3f\x10\x4a\xe1\xf7\xd4\x50\xd8\x20\xd6\x67\x0a\xc7\xe6\x03\x21"
+  "\xd8\xef\xa0\x5e\x85\x90\x3e\xa6\x45\xfe\x40\x39\x9e\xd1\x84\xe7"
+  "\x5a\x16\x4b\x52\xfe\xc0\x07\x1c\x33\x55\x5b\x5c\x9e\xe5\x48\x3f"
+  "\xe8\x93\x20\x07\xb8\x7d\xf1\xc0\x49\x47\xbf\xe0\x38\xe6\xfd\xbb"
+  "\x10\xea\x74\x9f\x46\xc8\xf0\x11\x20\x9f\xac\x85\xd3\x41\xde\xed"
+  "\x5b\x1b\xdd\xb5\x69\xb6\xd2\x04\x92\xcd\x85\x9f\x9b\x2a\xcb\x30"
+  "\x6e\x25\xd4\xc5\xe7\xac\x7c\xf6\x83\x70\x1f\x07\xf7\x87\x0f\x37"
+  "\xa0\xae\x65\xe5\x4e\xc0\xff\x8b\x26\x53\xf3\xdc\x85\x04\x63\x54"
+  "\x02\xdd\x67\x2f\x32\x91\x25\x85\x58\xce\x26\x8c\xdd\x09\x69\x98"
+  "\x07\xd2\xe3\x4c\x64\x69\x26\x2f\x3f\x54\x65\x41\x99\xe5\x5a\x7e"
+  "\x2e\x2f\x9f\x97\x8b\xe5\x49\x65\xef\xda\x4e\xdb\xc5\xb2\xf7\x4b"
+  "\x65\xe7\x42\x9a\x54\xfe\xdc\x15\xbd\xdf\xa8\x85\x6f\xb8\xb4\x61"
+  "\xe7\x76\x6a\xc1\x32\xe0\x5d\x9b\x89\xbc\xf2\xff\xb1\xf7\x3e\x70"
+  "\x51\x55\xe9\xff\xf8\x33\x97\x41\x07\x02\x19\x8d\x6c\x6a\xa9\x46"
+  "\xd3\xa2\xf2\x0f\x96\x96\x19\x26\xa5\x16\x96\x0a\xa5\x15\x25\x29"
+  "\x16\xb6\x58\xa8\x04\xa4\xa3\xa2\xe0\x64\xfb\x45\x16\x95\x94\x75"
+  "\x31\x11\x68\x63\x5b\x2b\xdb\xdc\x5d\x3f\xdf\x2f\xfb\xfa\xd5\x36"
+  "\xfb\x91\x5e\x3f\xb6\x15\x86\xcf\x7e\xed\x1b\x96\xd5\xe4\x97\x75"
+  "\xc9\x50\x27\x19\x9d\x11\x66\xe6\x7c\x9f\xe7\x9c\x7b\xe1\xde\xe1"
+  "\x8e\x4a\xb9\x7d\xf6\x4f\xd4\x75\xee\x3d\xe7\x39\xcf\x39\xe7\x79"
+  "\xde\xcf\x73\xfe\xdc\x73\xce\xcd\xa4\xb8\x4d\x18\x46\x69\x55\x98"
+  "\x8a\x38\x90\x8e\x3c\x0e\x12\x8f\x49\x66\x17\x64\xb7\xab\xfd\x06"
+  "\xca\x28\x56\xf1\xb5\x82\xd7\xa4\x89\x0a\x2f\x15\x1f\x19\x53\xad"
+  "\x59\xb2\x4e\x89\x6f\x0c\xf1\x45\xfa\x6c\x17\x2c\x4e\x54\xd7\x1d"
+  "\x65\x9e\x2e\xc7\x95\xb8\x20\x78\x50\x5d\x66\xd9\xaf\xa6\x62\x7a"
+  "\x83\xcc\x6b\x26\xf9\x2c\x25\x9e\xbe\xeb\xc9\xca\xc6\x26\x93\xdd"
+  "\xa0\x7f\x04\xb4\x33\x07\xf2\x69\x0a\xf1\x8f\x46\xa2\x43\x9f\xfa"
+  "\x3c\xff\xae\xe9\x70\xd6\x81\x34\x9d\x9a\x6f\x79\x4a\x70\xb7\xb7"
+  "\xec\x76\x50\xbe\x29\xba\x05\x69\x5c\xd2\xd8\xb0\x67\x26\xae\x1f"
+  "\x01\x92\xb3\xda\x45\xfd\x55\xc2\x5c\xb2\x33\xc1\x03\xce\xea\x20"
+  "\x04\x6b\x32\xb3\x52\xd6\x33\xc7\x31\xe9\xf6\x75\xf4\x8d\xe8\x81"
+  "\xb5\x81\xb7\xf3\xf5\x7f\xac\x1b\xfb\x71\x45\xb7\x02\xb5\x7b\x27"
+  "\xa5\x3b\xde\x76\xba\x4f\x73\xdb\xc3\xfb\x9d\x14\xbf\x1d\xfb\x7d"
+  "\xd4\xf7\xc3\xfe\x76\x4e\x85\x24\xfa\x7f\x41\xa4\xad\xa1\x70\xea"
+  "\x1b\x62\xbf\xb4\x56\x15\xc7\x6a\x32\x2d\x42\x76\x77\x2c\x21\x39"
+  "\xf2\xf2\xfa\xef\x77\x50\x99\x83\xd5\x99\x16\xaa\x43\xb1\x8d\x05"
+  "\x9d\x7e\xaf\x83\xbe\xb5\x6b\x5d\x49\xfd\xd6\x3b\xee\x49\xdb\x0d"
+  "\x0c\x6d\xdb\x32\xb0\x3a\xdc\xc1\xc7\xbf\xd8\x37\x3f\xe9\xbe\x26"
+  "\xd3\x42\xdf\x56\xde\xba\x3e\xd2\x34\xbd\x9a\x39\xba\xae\xcd\x44"
+  "\xdb\xba\x23\x5b\xf9\x76\xed\x00\xf9\x66\x2b\x75\xaf\x91\xeb\x8e"
+  "\xf2\xe2\xef\xac\xc7\x57\xf1\x6f\x6a\xe3\xf3\x1d\x61\xd7\x3a\x61"
+  "\xbb\x9d\x4a\x69\xb1\xee\x29\xb5\x8a\x9c\xfc\x6e\xfa\xa6\xf8\xd0"
+  "\xe3\xd2\xe4\x09\x69\x45\x0e\xe0\xe7\xe4\x6f\xfe\x59\xea\x00\xcb"
+  "\xc5\xd7\xbf\xb4\xe0\xb8\x20\xcd\xff\x3e\x13\x7e\x71\xf2\xe3\x73"
+  "\x65\x7e\x14\xa7\xe8\xaa\x46\xee\xaf\x0f\x3c\x8f\xc9\x59\x17\x51"
+  "\x2f\x73\xff\x7a\xdd\x19\xf5\xed\xeb\x35\xf9\x50\xff\x7a\xdd\x39"
+  "\xe1\xd2\xd6\xeb\xce\xb0\xeb\xbf\x55\xf5\xb2\xea\xd4\xeb\xcb\x6f"
+  "\x5f\xaf\x3b\xf7\xf6\xaf\xd7\x94\xa8\x4b\x5b\xaf\x29\xe6\x8b\xa8"
+  "\x57\x52\xff\x7a\x4d\xf9\xfd\xb7\xaf\xd7\x94\x8d\x3a\xf5\xfa\xf2"
+  "\x12\xd7\xab\x63\xc0\xfe\x70\xcb\x2b\x15\xc2\x1f\xde\xb5\x79\xe0"
+  "\xfe\xf0\xae\x8c\xfe\xfe\x30\xf9\xbd\x3e\x7f\x98\xfc\xc6\xb7\xf2"
+  "\x87\x5b\xb2\xe4\xbe\x46\xf2\x0b\xfd\xfc\x61\x79\x56\xab\xbe\x3f"
+  "\x4c\x7e\x88\xfb\xc3\xcd\x59\xad\x03\xab\x43\x72\x42\xaf\x3f\x8c"
+  "\xcd\x6a\xd5\xf8\xc3\x21\xaf\x54\x78\xcb\x92\x0b\xbf\x9d\x3f\x4c"
+  "\x2e\xec\xef\x0f\xef\x3a\xa4\xf5\x87\xc9\x61\xbf\xf5\x85\x38\x6c"
+  "\xd2\xf3\x87\x69\xfe\x53\x4c\xc6\x46\xd3\xc0\xca\x33\x35\xec\xf9"
+  "\xef\x98\x57\xfa\x05\xf2\x4a\x1f\x60\x5e\x61\xe7\xbf\x70\x6c\xb8"
+  "\x0f\xfb\x20\xe6\x75\xaf\x82\x74\xac\x08\xa4\x96\x84\x36\x70\xda"
+  "\x7c\x30\x2e\x0f\x31\x61\x87\xe4\x96\xea\x4e\x68\x49\x38\x06\x2c"
+  "\xea\x83\x7d\xec\xf5\x5c\x57\x4a\x3e\x61\xf3\xee\x9b\x9c\x85\xbe"
+  "\x01\x62\x73\xaa\x47\xc1\x66\x8b\x1f\xb1\xb9\x92\xf0\x38\xed\x71"
+  "\x67\xe7\x71\x19\x9b\xd3\x66\xf6\xea\xc7\x2e\xf0\xa9\x8b\x4d\xb4"
+  "\x09\x2d\x36\x7f\x96\x22\xb0\x39\x6d\x68\x7f\x6c\xfe\x2c\x45\x1f"
+  "\x9b\x77\x9f\x10\xd8\xfc\x59\xca\xc0\xea\x70\x77\x43\x1f\x36\x7f"
+  "\x96\xa2\xc1\xe6\x0d\xb9\x2e\x6f\xd9\x34\xf3\xb7\xc3\xe6\x34\xb3"
+  "\x52\xf7\xdd\x72\xdd\x31\xaf\x3c\x2d\x36\xa7\xa5\x86\xd5\x61\xe9"
+  "\x7e\x1b\xfa\xc3\x98\xe3\x52\x8a\x25\x80\x7d\xda\x60\x69\x4f\x43"
+  "\x5a\x80\x79\xe9\x1b\xed\x4c\x9a\x08\x6c\x55\x62\x8c\x17\xc7\x9b"
+  "\x5e\x6f\x8e\x89\x45\x7f\x70\x37\xeb\xb1\x00\x96\x3d\x8e\x79\x13"
+  "\x87\xa0\xcc\x46\xe1\xef\xb0\xdd\x2b\x21\x1e\x2f\xcb\x6e\x59\xae"
+  "\x78\x9f\xc4\x56\x59\xa2\xb7\xac\x84\x31\x71\x1e\xa0\xef\xdd\x64"
+  "\xc4\x6d\x30\x43\x9c\x1f\xe2\xe9\x9e\xd9\x6b\xf7\xd5\x9e\x05\x23"
+  "\xcd\x35\x06\xa3\x30\x3f\x5b\x1c\x63\x05\x89\x50\x9b\x8f\xe5\x91"
+  "\xc0\x52\x2b\xb1\x7d\x81\x55\x89\x12\x1b\xf2\xca\x83\x6c\x6d\x06"
+  "\x2f\x53\x70\xd4\x32\x2b\x7b\x1d\xaf\xe2\x1c\xca\x37\x85\xbe\x15"
+  "\xcc\x6e\x58\x86\xf9\x5b\xa2\x37\x9f\x85\x31\xb5\x2b\x61\x54\xcd"
+  "\x4a\x48\x64\x3d\x89\x12\xca\x20\x63\xe1\xf3\x66\xd2\x7b\x06\x93"
+  "\x30\xaf\x95\x98\x17\xea\x32\xb0\x09\xf3\xf2\x63\x5e\xa7\x30\xaf"
+  "\x93\x98\x97\x1d\xf3\xb2\x8b\xbc\x06\x26\xf3\x94\x8d\xe7\x9b\x13"
+  "\x4e\x5b\x77\x2d\x9d\x5d\xfb\xb7\x38\xdb\xe0\x54\x9a\x1f\xee\x5a"
+  "\x9b\x33\x40\xbc\xa7\x84\xdd\xff\xb3\xf5\xd7\x90\xc0\x4c\x67\x3a"
+  "\xe6\xbe\xf4\x05\x4b\xc3\xde\xd0\x4b\xbf\x86\x31\x64\x73\x2d\xbe"
+  "\x13\x68\x67\x67\x3a\x3e\x48\xec\x1c\x60\x5e\xf7\xa4\x87\xcb\xab"
+  "\xcc\xce\x5a\x7b\x12\x68\xbc\xf8\x4a\xc6\x56\x89\xd9\xba\x13\x32"
+  "\xd3\x3f\x3c\xd4\x0d\x8b\x6c\x34\x07\xcd\x6c\xd6\x27\xc0\x74\x54"
+  "\x4a\x35\x16\x1f\xa6\xf9\xbc\x7b\x0e\x69\xe7\xf3\xee\xf1\x81\x34"
+  "\xbd\x1a\xa4\x19\x07\x41\xba\x6f\x3e\x20\x9d\xf6\xba\xbf\x3c\xed"
+  "\x8d\x6b\x61\xbd\x9f\xfd\x8d\x95\x2f\x4e\xdc\x82\x63\xe1\xb4\x9b"
+  "\x0c\x2e\xc7\x4a\x9a\xdf\x9a\xfe\x33\x94\xdf\xd7\xd8\x06\xc5\xd1"
+  "\x3d\xf1\xcb\xcb\x87\xcb\x8f\x4b\xd3\x2b\xe3\x3c\x83\x53\xfd\x31"
+  "\xaf\xd8\xfc\x38\x7e\xeb\xb1\xec\x72\x9d\x2b\x7f\x25\xa9\x87\xc6"
+  "\xb3\x4f\x91\x1f\xb8\x77\x73\x9c\xa1\x04\xc7\xad\x3d\x0d\x8c\x59"
+  "\x68\xce\x36\xa3\x1a\x2f\xd2\x3d\xd7\x7b\xf4\x87\x07\x09\x1f\x84"
+  "\xc5\x5a\x11\x4e\xdf\x7c\xca\xd8\x2a\xb7\xd9\xee\x88\x9b\xb3\xc8"
+  "\x06\x02\x98\xbe\xf8\xaf\x90\xe0\x3c\x12\x00\xc4\x74\xc6\xa2\x80"
+  "\x89\xec\x28\xc3\xf1\xc4\x5f\xe0\x58\x1e\x48\xc5\xdf\x40\x2c\x62"
+  "\x28\x86\xec\x21\x88\xf6\x90\x76\x24\xce\x87\x76\x1d\x5c\x7f\x06"
+  "\xe2\xc8\x4f\xd0\xb9\xc8\xce\x4e\x1c\x5d\x9d\x4a\x1c\xb2\x6b\x39"
+  "\xc4\xfb\x4f\xe5\x0c\x73\x9f\xca\xb9\x7c\x67\x10\xe2\x87\xe4\x81"
+  "\x79\xf7\x72\xc4\xee\x0a\xb4\x8f\x93\x68\x1f\x9d\xc2\x3e\x7a\xf1"
+  "\xfa\x93\xf7\xf7\xd3\x9e\x1b\x6e\x1b\x9b\x64\xdb\x58\x85\x78\x5d"
+  "\xd9\x67\x1b\xfe\x15\x89\xd2\x6e\x89\x01\x96\x11\xe5\x9e\xd2\x58"
+  "\xbb\x7e\xb0\x89\xc6\xf4\xec\xda\x4c\x07\x8d\xcd\xd2\xfc\xcc\xff"
+  "\x0e\xea\x22\xf2\x26\xc9\xca\x36\xbf\x62\xfb\x30\xbd\x03\xfa\xc6"
+  "\x74\xa9\x91\xdd\xd7\x64\xa6\x5b\x1f\x66\xa7\x8e\x4a\xd3\xcb\x31"
+  "\xdc\x64\x7d\xf4\x46\x33\xea\x31\x52\x8c\x01\x53\x8d\x34\x47\xe0"
+  "\x92\xa6\x67\x21\x2f\xa0\xf7\x12\x7f\xe6\x73\x92\x33\x1a\x91\x16"
+  "\x02\x28\x73\x7f\x4c\x96\x2b\x18\xf3\x4a\xaa\xe3\xd9\x6e\x6e\x9b"
+  "\x3d\xa8\x83\x63\xb9\x20\x2d\xea\x44\xd9\x04\x50\x36\x5e\xee\x33"
+  "\xd2\xb9\xcf\x28\xfd\x60\x72\x91\x8b\x05\xd3\xb2\x23\x18\xca\xc5"
+  "\xe4\xb4\x05\x60\x61\x1e\xb0\x75\x27\x50\x46\x9e\x36\xf2\x2f\x43"
+  "\x82\xab\x84\x0f\xd9\x85\xf2\x89\xed\x04\x33\x2b\xf3\xee\xfb\xf5"
+  "\xfa\xa6\xc8\x00\xe2\x9c\xfc\x48\xdc\x06\x43\x14\xea\x6a\x48\x39"
+  "\xd9\x39\xda\x7d\xdc\x06\xee\xd7\xb8\x6e\xfd\xab\x12\x47\xf6\xac"
+  "\x4a\xb4\xe2\x75\xad\xe2\x6b\xe8\x5b\x5c\xbb\xc9\xcf\x94\xdd\x43"
+  "\xf4\x46\xa7\xcd\x05\x7e\x94\xe5\x10\x6a\x97\x56\x25\x26\x70\x99"
+  "\xfe\x18\x65\xfa\x0c\x98\xc6\xfb\xc0\x80\xe5\x32\x63\x99\xa1\x39"
+  "\xe7\x28\x90\x8c\x03\x68\x47\x24\xe7\x1e\xf2\x41\x88\x35\xec\xa7"
+  "\xb8\xe6\x2c\xb5\xc2\x07\x89\x1f\x01\x9d\xad\x54\x7c\x8e\x7d\x49"
+  "\x73\xa2\x4e\x9b\x1f\x58\xec\x2b\x36\xc6\xe7\x91\xa6\x67\x7f\x98"
+  "\xee\x83\xf0\x98\xbe\x6f\x4e\x1f\xa6\xef\x9b\xd3\x87\xe9\xfb\xf8"
+  "\x1a\x14\x35\xae\xcf\x55\x21\xae\x63\xd4\xb8\x9e\xb9\xe4\xef\x8a"
+  "\xeb\xb9\x03\xc7\xf5\xce\x93\x2a\x5c\xaf\xff\xef\xc1\xf5\x9f\x33"
+  "\x38\xae\x23\x7a\xae\xe1\x78\xc5\x7e\xce\x6f\xc1\x25\xdd\x37\x59"
+  "\xc1\xed\x9f\xde\x24\xdc\xde\x5f\xf4\x8f\x8a\xdb\x73\xde\x44\x2b"
+  "\x5e\x97\x1c\xb7\xc8\xf3\xa2\x71\xfb\xe7\x8c\x6e\x50\xe4\x47\xf8"
+  "\x65\xa5\x67\x3a\xac\xc5\x30\x0d\xfd\x84\x31\x6e\xc3\xb5\xd0\xcc"
+  "\x65\x98\x6a\xb4\x3e\xca\x82\x47\xa5\xfb\xff\x83\xf0\xd4\x6d\x67"
+  "\x2c\x18\xf3\xb3\x8e\xe2\xff\x02\x73\xb0\x7c\x71\x92\xd3\xff\x36"
+  "\xc4\xe5\xd1\x3b\x9e\xac\x06\x16\x6b\x2e\xa1\x77\x41\x58\x1e\x23"
+  "\xbd\xff\x09\x6c\xf2\xd6\x05\xd0\x9f\x04\x36\xef\x4a\x0a\x6e\xfa"
+  "\xc8\x11\x8c\x15\xef\x88\x58\xd4\x59\x87\xb7\x2c\xd5\xa8\xbc\xbf"
+  "\xd0\xed\x9b\xc4\xec\x4a\x42\x7b\x31\x1e\x93\x66\x19\xf0\x57\xc2"
+  "\x72\xec\xc6\xdf\x08\xfc\x5d\x46\xe5\x18\x58\x3b\x97\xca\xc7\xbf"
+  "\xd8\x96\x6d\x94\xfd\xe0\x9d\xdc\x06\x6f\x86\xd8\xe3\xf2\x3d\x96"
+  "\xa7\x52\x79\x1f\xd2\x4b\xdf\x27\x0f\x2a\x4b\x04\xca\xc4\x28\xde"
+  "\xd1\x88\x67\x15\xbf\x09\xfc\x19\x8c\x09\x58\x7f\x37\xbd\x4b\x45"
+  "\x2c\x19\xbc\x2c\xe7\x6e\xf9\x77\x2a\x7f\xa7\x83\x72\xa0\x7e\x9e"
+  "\xec\x6b\x27\x8b\x7c\x67\xc5\x60\x3b\x5c\xa1\xce\x57\x4f\x1e\x2e"
+  "\x69\x56\x62\xb8\xb8\x81\xc9\x62\x56\xd8\xf5\x5f\x33\x13\x03\x6c"
+  "\x80\xbc\xc2\xee\x7f\x65\x09\x99\xe6\xb4\x3d\x01\x47\xb0\x27\x23"
+  "\xee\x83\xa2\x13\x03\xec\x97\xcc\x0a\x3b\xfe\x0d\xc4\xec\x80\xb4"
+  "\x9b\xae\x85\x40\x75\xa6\x99\xe6\x3a\xa9\xaf\xd5\x92\xe8\x07\xea"
+  "\x6f\xbd\xf1\xac\x4b\xea\xc1\x3e\xe3\x10\xb4\xc7\xb9\x9e\xf7\xd9"
+  "\xd6\xe3\xd8\x47\x5d\x95\x11\xb7\xe5\x59\x48\xf6\x9f\xb2\x44\xff"
+  "\x14\x7d\x50\x37\xfa\x83\xee\x53\x39\x71\x2d\x79\x3e\x08\xee\xce"
+  "\x34\x3b\xfd\x4d\x50\x8b\x74\xe4\x7f\xa9\xbc\xe7\x4e\x65\x0c\x29"
+  "\x5b\x0e\xfc\xdd\x86\xe3\xa9\x37\xd1\xff\x3e\xf0\x55\xe4\x3a\xf4"
+  "\x39\xe8\x33\xb8\x1f\xfe\x16\x3e\xb8\xfb\xc5\x9b\xb3\xe6\x64\x32"
+  "\x5f\xcb\x91\xbf\x40\x71\x33\x98\x8b\x5f\x80\x58\xe2\xef\xf4\x37"
+  "\x0b\xbf\xfc\x38\xfa\x65\x7c\xae\x51\xf9\x65\x3e\xa7\x1e\xe2\x97"
+  "\xa9\xff\xdd\xd2\xde\x01\x43\x3c\x30\x78\xae\x27\xce\xb7\xde\xc3"
+  "\x82\xd4\x1f\xa7\xf7\x28\x48\x33\x44\xf1\xd1\xaf\x60\xbf\xa3\x67"
+  "\x85\xf0\xcf\xbb\x65\xff\xfc\xca\xc9\xef\xee\x9f\x5f\xb1\xa3\x7f"
+  "\xc6\xfe\xde\x4e\xf2\xcd\xe8\x97\xf7\x1e\x73\x4b\x7e\xf4\xc5\x03"
+  "\xd3\xed\x83\x8d\xe1\x74\x3b\x17\xdb\x4f\xd2\x29\x61\xa7\x79\x8f"
+  "\x9f\xde\xf1\xff\x2d\x30\xe4\xe5\x74\x6a\x1f\xbb\xb1\x6d\x7c\xe3"
+  "\xd9\x36\x69\x88\x0d\x75\x9b\xf7\x3e\xf3\x17\x64\xc4\xb1\x9e\x8c"
+  "\xd8\x40\xf9\x0e\xf0\xf7\x58\x4c\x3d\x3d\xa8\x5f\xf4\x17\xd8\x5e"
+  "\x99\xdd\x6b\x73\xb8\x4c\x82\xd7\x64\x9a\x83\x3f\xb9\x21\x05\xdb"
+  "\xa6\xc9\x35\x27\x61\x22\xdb\xfc\x72\x9e\x7f\xf3\xcb\x45\x3d\x9b"
+  "\x5f\x2e\x44\x5c\x0e\xc1\xfe\x23\xea\xfc\x9c\x23\xb8\xf9\xe5\x8a"
+  "\xe0\x96\xca\xf4\x40\xec\x0e\x70\xc7\xbe\x6c\xc3\xe7\xd2\xe0\x5a"
+  "\xc4\xc1\x1a\xc2\xc1\x07\x60\x9d\x4b\xed\xf0\xec\x6f\xf4\x70\xb0"
+  "\xd3\x3e\xb0\xb6\x78\x4e\x06\xe2\xa0\x0d\x71\xf0\x8d\x1a\x07\xef"
+  "\x81\xdf\x2e\xb7\xd1\x8f\x08\x2c\xa0\xdc\xf9\x58\xa6\xb7\x9d\x7e"
+  "\xf8\x43\x7d\x3c\x1c\xb9\x38\x3c\x74\x9f\xd2\xe2\xa1\xfa\x5b\xe2"
+  "\x01\xdb\x57\x4b\x0d\x8e\x9b\xce\x9d\x4a\x94\xaa\x09\x0f\x1f\xf5"
+  "\xe1\xe1\xad\xcf\xdd\x52\xcf\x80\xf1\x30\x27\xec\xf7\xbf\xc2\xe0"
+  "\xa1\xf5\x3b\xe2\xa1\x4a\x85\x07\x37\xe2\xc1\x8f\x78\xf0\xf4\xe1"
+  "\xe1\x0c\xe2\x61\x9b\x59\x85\x07\x1f\x3e\x9b\xfa\xe3\x21\xcd\xf0"
+  "\xfd\xe2\x21\xf2\xf4\xbf\x07\x1e\xd2\xc2\x8e\x7f\xf5\xf1\xb0\xed"
+  "\xbb\xfa\x07\x77\x1f\x1e\xb6\xa1\x7f\xd8\x86\xfe\x61\x9b\xca\x3f"
+  "\x9c\x20\x3c\xa8\xfc\xc3\x36\xf4\x0f\xdb\x74\xfc\xc3\x43\x43\xbf"
+  "\x5f\x3c\x5c\x76\xf4\xdf\x03\x0f\x0f\x79\x06\x88\x87\xef\xe8\x1f"
+  "\x6e\x4c\x55\xe1\x01\xfd\xc3\x36\xf4\x0f\xdb\x54\xfe\xe1\x33\xc4"
+  "\xc3\x76\x95\x7f\xd8\x86\xfe\x61\xbb\x8e\x7f\x98\x37\xe2\xfb\xc5"
+  "\xc3\xd0\xbf\xfc\x7b\xe0\x61\x7e\xd8\xf9\x6f\x7d\x3c\x6c\xff\x8e"
+  "\xfe\xe1\xc6\xba\x3e\x3c\x6c\x47\xff\xb0\x1d\xfd\xc3\x76\x95\x7f"
+  "\x78\x8f\xf0\xa0\xf2\x0f\xdb\xd1\x3f\x6c\xd7\xf1\x0f\x8f\x4c\xf8"
+  "\x7e\xf1\x70\x7b\xd9\xbf\x07\x1e\x1e\x8d\x1f\x20\x1e\xbe\xab\x7f"
+  "\xf0\xa9\xf0\x80\xfe\x61\x3b\xfa\x87\xed\x2a\xff\xb0\x0e\xf1\x50"
+  "\xa9\xf2\x0f\xdb\x69\x6d\x8f\x8e\x7f\x78\xec\x9e\xef\x17\x0f\x0b"
+  "\xee\xfd\xf7\xc0\x43\xc6\xa8\x0b\xe1\x41\xc1\x02\xe1\x82\xb0\xd0"
+  "\x53\x9c\x01\x34\xce\x78\xe3\xb8\xc0\x03\xe1\x80\x63\xa2\x2b\x23"
+  "\x2e\x80\x58\xf0\xaf\x45\x2c\x74\x0b\x2c\x90\x2c\x08\x0f\x34\xae"
+  "\xa0\xf1\x04\x61\x22\x80\x63\x0a\x7f\x2c\x8e\x29\x36\x18\xe3\x09"
+  "\x07\xdd\x31\x17\x18\x57\x74\x03\x1f\xfb\xd1\x18\xef\xa4\xf4\xf8"
+  "\x2c\x3d\x1c\xbc\x32\xc0\x39\xbe\xde\xf1\xa5\x06\x07\x1f\xf4\xe1"
+  "\xe0\xf1\x30\xe3\x8a\x47\xc3\xe0\xc0\x75\x11\x38\x38\xd9\x7f\x9c"
+  "\xf9\x5d\x71\xd0\xbd\x42\xc6\x01\x8d\x33\x83\xf2\x38\xf3\x29\x1c"
+  "\x67\xc6\x0e\x14\x07\x4f\x8c\xf9\x76\x38\xd8\xd6\x3a\x30\x1c\xdc"
+  "\x98\x4a\xfd\x04\x81\x83\x6d\x7e\x7f\x2c\xf6\x15\x34\x38\x38\x4f"
+  "\x7f\x41\x83\x83\x05\x0f\x7d\xbf\x38\x08\xe9\x2f\xfc\xcb\xe2\x20"
+  "\x33\xec\xf9\xaf\x41\xd4\x3b\xf9\x7b\x9a\xb7\xa7\xbd\x1b\x43\xdc"
+  "\x62\xde\x88\xf6\x70\x6c\x5d\x0e\xa3\xa8\x8d\x08\xac\xca\x88\x2b"
+  "\x3f\x09\xc9\x9b\x96\x83\xd1\x5f\x80\xfa\xcf\x07\x63\xb7\x04\xd0"
+  "\x5d\x90\x13\x77\xb0\xdd\x2d\xe6\x90\x6c\x0e\xa8\x45\xfa\x9e\x72"
+  "\x31\x87\x14\xe8\xca\x18\xb2\xe9\x34\xf0\x75\xaf\x8e\x85\xbf\x40"
+  "\xdd\x3e\x39\x56\x4f\xb7\xbb\x06\xe0\xeb\xbb\xd5\xbe\xfe\x84\x56"
+  "\xb7\x6a\x3f\x5f\x6d\x57\xcd\x21\xcd\x0d\x33\x87\x74\x11\x3a\xe5"
+  "\x73\xfb\x27\x85\x9f\xef\x9d\x43\xfa\x8e\x73\xfc\x3d\xe8\xe3\x5f"
+  "\x91\xb4\x3e\xfe\xdb\xe9\x74\xa1\xe9\x7c\xf3\x8e\x64\xdf\x64\xd7"
+  "\x8a\x4d\xf7\xb6\xf1\x64\xc7\xa8\xef\x73\xe5\x2f\xcf\xe7\x6d\xfd"
+  "\xda\x3e\x9b\x26\x5b\x26\xbb\x26\x3b\xe6\x6d\x3d\x9d\xf3\xfb\x93"
+  "\xc4\xf4\x1a\xd5\xdc\x51\x20\x56\xf6\xf3\x3a\x3e\x3e\x78\x5e\x1f"
+  "\xbf\x48\x57\xff\xff\x0c\x3e\x9e\x70\xa0\xd8\xf7\x3f\x9e\x6d\x67"
+  "\x85\x5f\xff\x75\x71\x38\x38\x74\x11\x38\x68\x45\x1c\xd4\xab\x70"
+  "\xe0\x46\x1c\xa0\x9f\x17\x73\x46\x02\x07\x7d\x73\x46\xc1\xd0\x39"
+  "\x23\x0d\x0e\x16\x4f\xfa\x7e\x71\x10\x32\x67\xf4\x2f\x8b\x83\xa7"
+  "\x2c\xdf\x0d\x07\xdb\x2e\xc2\x1f\x6c\x23\x7f\xe0\xab\x51\xcd\x15"
+  "\x05\x62\xb7\xa1\x3f\xd8\xa6\xf2\x07\x7d\x73\x45\xc1\xd0\xb9\x22"
+  "\x0d\x0e\x9e\x9e\xfa\xfd\xe2\x20\x64\xae\xe8\x5f\x16\x07\xd9\xd6"
+  "\xef\x88\x83\x8b\xf0\x07\xdb\xd0\x1f\xdc\x34\x5b\x85\x03\xf4\x07"
+  "\x72\xbf\x4f\xa7\xcf\x17\x3c\x6f\x9f\x6f\xc9\xcc\x7f\xd6\x3e\xdf"
+  "\x3f\x36\x0e\x9e\x09\xfb\xae\xf4\xe2\x70\xb0\xfd\x22\xfc\xc1\x76"
+  "\xf4\x07\x37\xd5\xd5\xa8\xe6\x86\x02\xb1\xdb\xd1\x1f\x6c\x57\xf9"
+  "\x83\xbe\xb9\xa1\x60\xe8\xdc\x90\x06\x07\x3f\x9e\xf3\xfd\xe2\x20"
+  "\x64\x6e\xe8\x5f\x16\x07\x39\x49\xdf\x11\x07\x17\xe1\x0f\xb6\x93"
+  "\x3f\xf0\xa8\x70\x80\xfe\x60\x3b\xfa\x83\xed\x2a\x7f\xd0\x37\x27"
+  "\x14\x0c\x9d\x13\xd2\xe0\x60\xe9\x23\xdf\x2f\x0e\x42\xe6\x84\xfe"
+  "\x65\x71\xf0\x6c\xd8\x75\x15\x0a\x06\x7a\xe7\x00\x58\x1f\x0e\xb8"
+  "\xee\x0b\x32\xe2\xba\x63\x5e\x9e\xaf\x8c\xff\xcb\xfb\x8d\xff\x13"
+  "\xd3\xc3\xce\x03\x85\xbc\x5f\xe6\x63\x83\x2d\x2f\xa7\x8b\x71\xc2"
+  "\x0e\x20\xfd\xff\x74\x8d\x18\x27\x5a\x1f\x25\xfd\x3f\xa7\xaf\xff"
+  "\x81\xce\x09\x66\xa3\xfe\xdb\xcf\xa3\xff\x27\xc3\x8c\x13\x9e\xf8"
+  "\x6e\xfa\xa7\xf5\x8e\x3d\xa7\x2e\xa1\xfe\x95\x39\xc1\xcf\x40\x7a"
+  "\xe5\x3b\x8d\x17\x73\xc3\xea\x5f\x77\x3d\xc9\x1e\xb1\x9e\x84\xd6"
+  "\x92\xb4\x74\x74\xc0\xa6\xb3\x60\x1e\x92\x2b\x30\xc1\xd7\x94\x20"
+  "\x26\xca\x8f\x43\xb2\x5f\xd4\xad\x77\x4d\x09\x9d\x8b\x2e\xfc\x82"
+  "\x83\xaf\x29\x51\xe6\x03\x7a\xd7\x93\x2c\xa4\xf5\x24\xcb\xee\xfc"
+  "\xce\x73\x01\xb4\x9e\xa4\x10\x75\xec\x41\x1d\x9f\x21\xfd\x7e\xa0"
+  "\xb1\x6b\xcd\x1c\x40\xb8\x75\x24\x17\x33\xaf\xf3\x77\x58\x47\xc2"
+  "\xe7\x00\x2e\x89\x4d\x2f\x0f\x7b\xfe\x0b\xe9\x91\xf4\xe9\x4c\xf4"
+  "\xf3\x79\x5d\xc5\xc6\x9d\xb6\x56\xd8\xd4\x0d\x66\x65\xfe\x5f\xd1"
+  "\x29\xf9\x7b\x86\x38\x60\xa7\x32\x62\x49\xa7\x3f\x5d\x8e\x7e\x7e"
+  "\x45\x9f\x9f\x0f\x0e\xba\x21\x65\xf7\x1a\xf4\xef\x6b\x60\x22\x97"
+  "\xd1\x90\xca\x74\x31\x1f\xb0\x03\xc8\xde\xc9\x9e\x59\xec\xcb\xa5"
+  "\x3d\xb2\xbd\x0b\x7d\x37\x03\xe9\x99\x7f\x3f\x53\x5a\x31\x96\x6c"
+  "\x8f\x74\x3e\x44\xd6\x79\x4d\x18\x9d\x73\x7d\x1b\xcc\x74\x16\x07"
+  "\xed\x33\xeb\xd5\xb9\xff\x45\xd5\xfc\x8f\x5a\xe7\xf2\xbc\x4f\x10"
+  "\x6d\xf9\xa2\xd6\x0f\x5d\xa4\xde\x2f\xd9\xfc\x3e\xea\xbd\x46\xd6"
+  "\x7b\xef\xfc\xfe\x77\xd2\x7b\x5e\xf8\xfd\x2f\x5a\xbd\xb7\x5e\x02"
+  "\xbd\x57\xe9\xe8\xdd\x2d\xeb\xdd\x43\xe3\x7c\x16\xbb\xcd\xd4\x23"
+  "\xaf\x1b\xe9\xaf\xf7\xe7\x47\xff\xfd\xf5\x1e\x79\xfa\xdf\x43\xef"
+  "\xcf\x87\x3d\xff\x5c\xab\xf7\x6d\x97\xc2\xde\xdd\xfd\xf5\xbe\x4d"
+  "\xb6\xf7\x6d\x85\x34\xae\x47\xbd\xcb\xf6\x7e\x42\x47\xef\x05\xd7"
+  "\xfc\xfd\xf5\x7e\xd9\xd1\x7f\x0f\xbd\x17\x84\x5d\xff\x11\xa2\xf7"
+  "\x4b\x60\xef\x37\xa6\xea\xe8\x5d\xb6\xf7\x6d\x1e\x1a\xc7\xb3\xd8"
+  "\xed\xb2\xbd\x7f\xa6\xa3\xf7\x17\xae\xf8\xfb\xeb\x7d\xe8\x5f\xfe"
+  "\x3d\xf4\xfe\x42\xd8\xef\xff\x6a\xf5\xbe\xfd\x12\xd8\xfb\x8d\x75"
+  "\xfd\xf5\xbe\x5d\xb6\xf7\xed\x85\x34\x6e\x47\xbd\xcb\xf6\xfe\x9e"
+  "\x8e\xde\x57\xc5\xfe\xfd\xf5\x7e\x7b\xd9\xbf\x87\xde\x57\x85\x5d"
+  "\xff\x17\xa2\xf7\x4b\x61\xef\x3e\x1d\xbd\xcb\xf6\xbe\xdd\x43\xe3"
+  "\x74\x16\x5b\x29\xdb\xfb\x3a\x1d\xbd\xaf\x8e\xfc\xfb\xeb\x7d\xc1"
+  "\xbd\xff\x1e\x7a\x5f\x7d\xe4\x42\xef\xeb\x15\xdd\x2b\x73\x36\xfc"
+  "\xfd\x2c\xf6\xef\x15\x7d\x13\x0e\x48\xe7\x84\x05\xb5\xce\xf9\x1a"
+  "\x9e\x15\x62\x0d\x0f\xf5\xdb\x19\x8e\xc5\xd9\x20\xbe\x7e\xa3\x94"
+  "\x8f\xdb\xe5\x7e\x3c\x33\x18\xe3\xa9\x2f\x1f\xbe\x1f\xbf\xe6\x8c"
+  "\xa2\xef\x6f\x3b\x76\xbb\x90\xbe\x43\xc7\xe4\xff\x28\xfa\x56\x8f"
+  "\xdf\x2e\x8d\xbe\xd7\x1e\xfc\x76\xfa\xde\xd6\x3a\x30\x7d\x6f\x73"
+  "\x0b\x7d\xd3\x3a\x8d\xed\xa6\x3e\x7d\x6f\xf3\x08\x7d\x6f\xf3\x85"
+  "\x6f\xcf\x8b\xfe\xfa\xf7\xd7\xb7\x76\x4e\xfe\x5f\x57\xdf\xeb\xc2"
+  "\x7e\xff\x83\xe6\x60\x48\xd7\xa4\xf7\xad\xcf\xc2\xa8\x9f\x3e\x2b"
+  "\xe6\x56\xfc\xa7\x2c\xe4\xf3\x8d\xa4\x7f\xda\xe3\x33\x04\x31\xf0"
+  "\xe7\x0c\x37\x74\x7b\x33\x80\xf6\xf2\xd0\xba\x8b\x96\x1c\x17\x38"
+  "\x6d\x1f\xc2\xa6\x7c\x30\x1f\xcc\x3a\x0d\x73\xf7\xb0\x1e\xe7\x11"
+  "\x07\xed\xf1\x36\x3a\xd6\x7c\x08\x6c\x45\x62\xf4\x42\x0f\x48\x27"
+  "\xa5\xf5\x85\xb4\x6e\x63\x9c\x07\x65\x42\xfb\x7d\x50\xe7\x9b\x4e"
+  "\x02\x7c\x50\x08\x60\x7d\x86\x74\xbd\xfe\xbf\x22\x5f\xd0\xd9\xe7"
+  "\x33\x90\x79\x19\xf5\xdc\xab\x8e\xae\x77\x49\x97\x66\x6d\x86\xb2"
+  "\x2e\x43\x33\x2f\xf3\x5d\xf7\x5f\x5e\xb2\xb5\x19\xc5\x61\xcf\x72"
+  "\xa2\xf5\x36\xa4\x4f\xb2\x69\xff\x16\x31\x2f\xe3\xb4\x35\x01\xad"
+  "\xab\x21\x1b\x0e\x74\x59\x4c\x6b\x0b\xd1\xd6\xdb\x84\xad\xff\xf4"
+  "\x34\xd2\x66\x7d\x02\x84\x0f\xa1\xdb\x1e\xa1\xdb\xd3\xa4\xdb\x4f"
+  "\x80\x15\x24\x46\x9f\x94\x4a\x66\x93\x7e\x49\xaf\xc5\x87\xc1\xbc"
+  "\x88\xce\x45\x21\x1f\x8f\xfe\x1d\xf5\x3c\xb9\xf6\x59\x98\x48\xf6"
+  "\x1f\xd8\xfc\x72\xa1\x7f\xb3\x58\xa3\x41\x7e\xbf\x27\xe6\x15\x5b"
+  "\x59\xbe\xac\xff\x27\x48\xff\x25\xba\xfa\xdf\xf5\x6d\xe7\xde\x65"
+  "\xfd\x7f\xeb\x7d\x3d\xff\x5d\xf6\xbe\xe2\x52\xd9\xfb\x86\xb0\x67"
+  "\xa2\x84\xe0\xa0\x75\xe0\x38\xf0\xea\xe0\xc0\x3e\x5f\x07\x07\x6e"
+  "\xc4\x41\x55\x08\x0e\x3c\x32\x0e\x7c\xd8\x36\x98\xfa\xe3\xc0\x7e"
+  "\xf8\xfb\xc1\xc1\x45\xee\xe7\xf9\xa7\xc7\xc1\x8b\xfb\x2f\x0e\x07"
+  "\xdb\xbe\x85\x3f\x38\xa5\x83\x83\x8d\x99\xfd\x71\xb0\x8d\xfc\x81"
+  "\x5b\x8b\x83\x6d\xb2\x3f\xd8\x86\xfe\x60\x9b\x8e\x3f\xd8\xf8\xe5"
+  "\xf7\x83\x83\x8b\xdc\xc7\xf3\x4f\x8f\x83\x97\xc2\xb6\xff\x21\x38"
+  "\xf8\x16\xfe\xe0\x0b\x1d\x1c\xfc\x24\x5b\x07\x07\x6e\xea\x07\x86"
+  "\xe0\x40\xf6\x07\xdb\x7c\xd4\x3f\xec\x8f\x83\x9f\x7c\xf5\xfd\xe0"
+  "\xe0\x22\xf7\xef\xfc\xd3\xe3\xe0\x7f\x84\xdd\xff\xab\xc5\xc1\xf6"
+  "\x6f\xe1\x0f\xde\xd7\xc1\x41\x69\x6e\x7f\x1c\x6c\x47\x7f\x70\x63"
+  "\x9d\x16\x07\xdb\x65\x7f\xb0\x1d\xfd\xc1\x76\x1d\x7f\x50\xfa\xcd"
+  "\xf7\x83\x83\x8b\xdc\xb7\xf3\x4f\x8f\x83\x4d\x61\xc7\x7f\x21\x38"
+  "\xf8\x16\xfe\xa0\x58\x07\x07\x65\x85\x3a\x38\x20\x7f\xe0\x0b\xc1"
+  "\x81\xec\x0f\xb6\xa3\x3f\xa8\xd4\xf1\x07\x65\xe7\xbe\x1f\x1c\x5c"
+  "\xe4\x7e\x9d\x7f\x7a\x1c\xfc\x34\xec\xfe\x6f\x35\x0e\x7a\x7a\xc7"
+  "\x0b\x0d\x1c\x07\x65\x6b\x04\x0e\xd6\x11\x0e\x3a\xc4\xfa\x9d\x72"
+  "\x19\x07\xbd\x63\x85\xf6\x50\x0c\x94\xdb\x7a\x31\xf0\x55\xdf\x58"
+  "\xa1\x07\xf5\xcd\xe7\x83\xe4\x71\x82\x32\x0f\xc4\xc7\x09\x38\x4e"
+  "\x2c\x3b\x2d\xeb\x9f\xcf\x09\x94\xeb\xeb\x7f\x00\xe3\x44\xcd\x1a"
+  "\x8d\x50\xfd\xff\x83\xef\xd3\xe9\x37\x2f\x70\xf8\xbb\xae\xcd\xd8"
+  "\x7c\x91\xfa\x57\xfa\x05\x17\xab\xff\x2f\x74\xf4\xbf\x45\x47\xff"
+  "\xdb\xdc\x42\xff\x37\xa6\x2a\xfd\x01\x65\x5e\x88\xf7\x07\xfa\xe9"
+  "\x7f\xcb\xf7\xa4\xff\x7f\xcc\xfd\x39\x97\x5e\xff\x5b\xc3\xea\x3f"
+  "\x80\x36\xb0\x5b\x0a\xee\xab\x90\x82\x0d\x78\x39\xf0\x6a\xc2\xb0"
+  "\x48\x0c\x6b\xa5\x34\x15\x72\x5c\xa0\x0c\xe8\xec\x24\x47\x9c\x21"
+  "\x8b\xe4\x4d\x34\x83\x14\x9a\xb8\x0d\x90\x82\x75\x13\x74\x12\x94"
+  "\x60\xb8\x23\x76\x43\xca\x20\xa4\x6f\x62\x65\xb3\x66\x60\xd8\x60"
+  "\xa2\x65\x1b\x8c\x7c\x0d\x79\x9c\x81\x9f\x9d\x29\xd3\x1b\xe8\xac"
+  "\x2c\x07\xd1\x22\x9d\x49\xa6\x13\xe7\x94\x4b\x12\xd4\xf6\x2f\x5b"
+  "\x94\x4c\x63\x0d\xda\xc1\xaa\x2e\x63\xac\x21\x85\xf3\x92\xe9\xa2"
+  "\x03\xf6\x4f\x32\x88\x36\xb0\xc1\x38\x4a\x4d\xc7\xee\x05\xe2\xab"
+  "\xd0\x5d\x26\xf3\x4b\xd4\xd4\x77\x24\x40\xec\x06\x2b\xe7\x17\xdb"
+  "\x29\x81\x5c\x3e\xc4\x44\xaa\x85\xd3\x1b\x8c\x63\x34\xf4\x83\x40"
+  "\x5d\x8f\x58\x36\xe8\x96\xc9\x32\x5d\x52\x50\x02\xbe\x46\x12\xc3"
+  "\x8d\x6a\x59\xcb\xb4\x43\x14\x39\xd2\x99\x4e\xea\xfa\x06\xb0\xfe"
+  "\xbb\x45\x19\xe3\x02\x3f\xb9\x39\x55\xae\xcb\x64\x75\xbe\x44\x87"
+  "\xe9\x26\xc8\x3a\x31\x63\x3d\x92\x7b\xf9\x95\x2f\x4e\x54\xe8\x10"
+  "\xb3\x57\xa1\x8e\x1c\xce\x1c\x00\xb9\xde\x43\x51\x37\x6d\x72\xdd"
+  "\x53\xb4\x72\x34\xb8\x14\x39\x22\x4d\x39\xd2\x0e\x43\x9a\x19\x0a"
+  "\xdf\x80\x9d\x9f\xa3\x25\xea\x6d\xf7\x5f\x4e\xb8\x68\xee\x00\xa8"
+  "\x11\xf5\xb9\x5c\xe6\x99\x2a\xea\x6c\x86\xdd\xbd\xba\x36\x52\x9c"
+  "\x43\xa6\x8b\xe7\xf5\x89\xce\xc8\x0d\x18\x8c\xb3\xfb\xd3\x9a\xd4"
+  "\xb4\x57\x08\xda\xd9\x31\x48\x9b\xde\x9f\xd6\xac\xa6\x1d\x2e\x68"
+  "\xe7\x26\x20\xed\xfc\xfe\xb4\xfe\x61\x2a\xda\x2b\x05\x6d\xfa\x18"
+  "\xa4\xcd\xe8\x4f\x6b\x55\xd3\x5a\x04\xed\x13\x85\x48\x9b\xd9\x9f"
+  "\x36\x45\x4d\x7b\x95\xa0\x7d\x38\x19\x69\xb3\xfa\xd3\x96\xa8\x69"
+  "\xaf\x16\xb4\xf3\x67\x23\x6d\x76\x28\x6d\x2d\xc7\x01\x8c\x94\x71"
+  "\xf0\x23\x41\xfb\x68\x26\xd2\xe6\xe8\xd4\x2d\x82\xf3\x15\xb4\x09"
+  "\x82\xf6\x81\x24\xa4\xcd\xd5\xd1\x85\x9a\xf6\x1a\x41\xfb\x6c\x09"
+  "\xd2\xe6\xe9\xe8\x42\x4d\x7b\xad\xa0\x5d\x98\x8e\xb4\x85\x3a\xba"
+  "\x50\xd3\x5e\x27\x68\xb3\x32\x90\xd6\xa6\x23\xdf\x3e\xda\xe8\xa7"
+  "\xb2\x90\xa6\x08\x65\xd2\xaa\x23\x5b\x35\xcf\x11\x82\x67\x76\x0e"
+  "\xd2\x97\xe8\xc8\x56\x4d\x3b\x52\xd0\x3e\x93\x87\xb4\x1b\xfb\xd3"
+  "\x82\x61\xb7\x90\xef\xad\xb2\x7c\xaf\x17\xf4\x39\x36\xa4\x2f\xd5"
+  "\x91\x2f\xc5\x3b\x64\x5b\x1b\x25\x68\x33\x8b\x90\xb6\x5c\x47\xbe"
+  "\x6a\xda\xd1\x82\x76\xcd\x28\xa4\xad\xd0\x91\xaf\x9a\xf6\x06\x41"
+  "\xbb\x7c\x3e\xd2\x56\xea\xc8\x57\x4d\x7b\xa3\xa0\xcd\x23\xec\x54"
+  "\xe9\x94\x77\xa4\x8a\x36\x51\xd0\xe6\xcf\x40\xda\x6a\x1d\x5d\xa8"
+  "\x69\x6f\x12\xb4\x45\xf1\x48\x5b\xa7\xa3\x0f\x35\xed\xcd\x82\xb6"
+  "\x90\xb0\x5e\xaf\xa3\x0f\x35\xed\x2d\x2c\x7a\xe5\x44\xd9\x2f\xee"
+  "\x09\xa5\x45\xdd\x0b\x9f\x68\x87\x31\x2c\xda\x36\x06\xef\x89\x8e"
+  "\xcf\x71\xf6\xf2\xb3\xfb\x6f\x23\x7f\x23\xfb\xb0\xb1\x2c\x3a\xb7"
+  "\x44\xe6\xb7\xaf\x5f\xde\x76\xa3\x9a\x76\x1c\x8b\x2e\x4f\x90\x69"
+  "\xf7\xf7\xa7\x35\xa9\x69\xc7\xb3\xe8\xe2\x4e\x99\xb6\xa1\x3f\xad"
+  "\xb9\x97\x96\x45\x6f\xa0\xbe\xcc\xbb\x35\xb2\x6f\x54\x95\xf3\x56"
+  "\x15\xbf\x09\x2c\xfa\x45\xbf\xcc\xcf\xd1\x9f\x9f\x55\x4d\x7b\x2b"
+  "\x8b\xde\xa2\x94\xb3\xb1\x3f\x6d\x8a\x9a\xf6\x36\x16\xfd\x13\xa3"
+  "\x4c\xdb\xd4\x9f\xb6\x44\x4d\x3b\x91\x45\x97\xc6\xc8\xb4\x07\xfb"
+  "\xc9\x9e\xec\xc0\x8e\x7d\x01\xe1\x93\x26\xb1\xe8\xb2\x78\x99\x56"
+  "\xd3\x0f\x50\xb5\xc3\xb7\x0b\xbd\xaf\x37\xa2\xde\x79\xff\x02\x7d"
+  "\x7e\x9b\x5e\x1f\x23\xef\x66\xb8\xec\xb8\x54\xd5\x24\xda\x24\xe5"
+  "\xbb\x57\xaf\xf0\x7d\x85\xc1\xea\xcc\xa4\x34\x0f\xf3\xab\xc3\xb6"
+  "\x4a\xac\x75\xbc\x07\xf8\x39\xa9\x2c\xf6\x95\x0c\x17\x86\xbb\xaf"
+  "\xc9\x4c\xf7\x96\x55\x1d\x72\x19\x46\xdb\xe8\x1c\x3f\xbc\x77\xb9"
+  "\x60\x29\xff\xe6\xc5\x56\x3b\xf3\xd1\xf9\x95\x81\x2d\x59\x6e\x67"
+  "\xb0\x13\xfb\x72\xcc\x87\x3c\x7c\xd8\x97\x8b\xb0\xe2\xb8\xb2\xd8"
+  "\xc6\xba\x9d\xb6\x4e\x38\x26\xed\x1c\xcd\x56\xe4\x24\x63\x19\xcc"
+  "\x98\x5f\xf6\x51\x7c\xe6\x65\xc0\x3e\x10\xb6\x95\x31\x8e\x7c\x3a"
+  "\x47\x74\xe7\x23\xee\xd8\x5d\x66\xf6\xe2\x82\x8e\xbc\xf5\x70\xdd"
+  "\x71\x69\x27\x6f\x43\xf8\x19\x83\xa7\x72\xee\x0e\xc6\x2e\x8e\xa1"
+  "\xb3\x07\x59\xd5\x2e\xb7\x38\x97\x70\x27\xff\xb6\x23\x96\xa1\x95"
+  "\x25\x64\x5a\x83\xdd\x1b\x4b\xe8\xbb\x6a\x8e\xf5\xc7\xe1\xa8\x2a"
+  "\xce\x7d\xd5\x2e\x7e\x66\x21\xd6\xc9\x1a\x28\xfd\xa0\x2a\x68\xfa"
+  "\xa0\x92\x95\x3a\x4b\x9d\xb9\x2e\x10\xdf\x7c\x79\x65\x28\x1b\xf2"
+  "\xb8\x33\x58\xfa\x41\x11\x86\xdb\x9c\x9e\x6e\x1e\x8e\x3c\x8e\x50"
+  "\xff\xb2\xcb\x74\x30\x9d\x95\x1e\x9c\xef\xb8\xba\x1b\xda\xa5\x9d"
+  "\xfc\xec\x3e\x0a\x67\x9b\x9c\xa5\x24\x9f\xe0\x26\xa7\x2d\xc2\x02"
+  "\xc6\xae\xa8\x83\x28\xa7\x9d\x7e\xe5\xdb\x23\x4a\x5e\xc4\xd7\x25"
+  "\xf3\x0a\xb3\xee\x23\x8e\x6d\x5e\x9c\xe8\x2d\xa3\x6f\x24\x55\xc4"
+  "\x0b\x19\xbf\x32\x03\xf9\x18\xe5\xfb\x74\x97\x01\x8e\xc8\xf7\x99"
+  "\x2e\xc3\x8f\xda\xe4\xfb\x1c\xe5\x4c\x47\xfd\x33\x26\xb3\xfc\x28"
+  "\xdb\xf8\xe0\xae\x0c\x13\xf5\x75\xa9\xff\xce\x62\xb3\xfc\xd6\x6b"
+  "\xe9\x7b\x7d\xbb\x00\xf3\x8c\x17\xe7\xfb\xbf\xf2\x01\xfe\xc6\xc9"
+  "\xbf\x6e\xf9\x97\x11\x0d\xc7\x4d\x42\x66\x1d\x2b\xaf\xec\x20\xd9"
+  "\xae\x0f\xb0\x20\x8b\x59\x3c\x19\xe5\x54\xe2\xb4\x75\x28\xf2\xfb"
+  "\x86\xf7\xfb\x49\x77\xa8\x5f\x16\xe5\x2c\xe1\x79\x6d\xde\x65\x56"
+  "\x97\x8b\x98\x25\x4d\xb8\xf5\xb6\x89\x93\x6e\xbf\x63\xf2\x9d\x8b"
+  "\x9f\x7a\x3a\x7b\xc9\x33\x3f\xce\x59\xfa\xec\x73\xb9\xcb\x96\xaf"
+  "\xc8\x7b\x3e\xbf\xa0\xf0\x85\x95\xab\x6c\xab\xd7\x10\x5d\x6f\x1d"
+  "\x76\xcd\x30\x78\x24\xc0\x7c\xee\xc5\x7c\x76\xf1\xef\x5e\x53\x98"
+  "\xd0\xff\xae\xf9\x46\xab\x7e\xdf\xda\x89\xbd\x5d\xfa\x86\x4c\xa7"
+  "\xb4\xeb\x37\xf4\x3d\x1b\xc4\x99\xc1\x59\x7d\xbf\x83\xbe\x31\xd6"
+  "\x2e\xed\xaa\x6f\x71\xdf\xef\xa0\x6f\xdc\x1d\xb0\x74\xc0\xa8\x91"
+  "\xf4\x1d\xb2\x5d\x15\x14\x5f\x7b\x03\x40\x23\xa6\xd5\xe3\x39\xd2"
+  "\x0c\x96\xed\xc3\x99\xbb\x72\x38\xeb\x24\xfe\x95\x3b\x58\x87\x7b"
+  "\x6d\x0e\x6c\xc1\x67\xc4\xba\xf9\x98\x54\xbd\xe4\x40\x02\xff\x56"
+  "\x53\x42\xcd\x0e\xd6\xbe\x71\x38\x6b\x7f\x71\x07\xeb\xac\x1d\xce"
+  "\x5c\xa3\x2a\x21\xc6\x5b\x56\x6d\x71\x49\xbb\xf2\xb8\xdd\x60\x7c"
+  "\x30\x7a\x97\x79\x2b\xc6\x8d\xf7\x43\x44\x2d\x3e\x63\x98\xe7\x80"
+  "\x55\x94\xfb\x9d\xd3\xbe\x48\xac\x9f\x9f\xf5\xe4\x1a\xb6\x60\x3e"
+  "\x42\x4f\xd5\x9b\x1a\xb1\x25\xc7\xfc\xdc\x4e\xdf\x51\x70\x49\xd5"
+  "\xa5\xb5\x67\x79\x7e\x71\xce\xaa\x4e\x20\x7e\xbf\xce\xf7\x45\x16"
+  "\x5c\xcd\xfc\x48\x9b\x13\x5c\x9b\x6b\x40\x9a\x19\xc8\xdb\xa3\xae"
+  "\x4f\xe2\x33\xcb\x0a\xad\xcb\x5f\xc8\xcd\xbd\x29\x1a\x12\xf9\xaf"
+  "\xe6\xfb\x78\x85\x74\xc6\xec\xf6\x1d\xac\x11\xeb\xe9\xc0\xfa\x36"
+  "\x35\x63\x0f\x1e\x31\x03\x58\xa7\x0a\xe4\xfb\x19\x86\xbf\x8b\xf7"
+  "\xef\x62\xd9\x9b\xc4\x37\xd5\x7e\x1d\xc5\xca\xaa\x2b\xb1\x9c\x4d"
+  "\xf4\x9d\x0d\x3a\x93\xb6\x6b\xd5\x7c\x03\xd6\xbb\x12\xe9\x9a\xac"
+  "\x57\xc3\xe8\x63\xd2\xee\x25\x58\x8e\x7a\xbc\x27\xfa\xa1\xa4\x47"
+  "\xa4\x6f\x14\xf5\x7a\xfb\x1c\x3d\xa3\xac\x1c\xbb\x87\xb3\x72\x6f"
+  "\xd9\xee\x14\x3a\x6b\x9b\x7f\x93\x08\x9f\x51\x2e\x4d\x48\x5b\xd1"
+  "\x55\x3c\xdf\x80\x63\x41\x43\x6d\x1f\x4f\x33\x95\x89\xca\x41\xe3"
+  "\xcb\x3f\x63\x0f\x2e\xd8\x93\x01\x63\x7d\x60\xf8\x73\x3b\x40\xf5"
+  "\x0e\x56\x87\x57\x35\x5e\x55\x1f\x62\xdc\x9f\xf0\x6a\xc2\xf0\x83"
+  "\xf8\xfb\x21\xfe\xfe\x09\x2f\x1c\x9f\x5a\xa8\xdc\x05\x45\xac\x63"
+  "\x7c\x15\x5c\x4f\xfc\x11\x5b\x8f\x1d\x95\xde\xce\xa2\xb2\xd3\x59"
+  "\xf6\x2c\x7a\x77\xc8\xf9\xdf\xb5\xa9\x80\xf1\xf8\x9b\x29\x7e\xd5"
+  "\x57\x6d\x3d\x5e\x8d\xe2\xbe\x2e\x06\xef\x27\xca\xf7\x56\xbc\xc6"
+  "\x5c\xf8\x0a\xe5\x17\xee\xaa\xab\xba\x78\xda\x8b\xba\x0e\x5d\x1c"
+  "\xdd\x2f\xd2\x41\xaa\xdf\x83\x97\x4b\x1b\x5e\xdf\x20\xc2\xde\xd8"
+  "\x28\x9e\xdf\xa8\x90\x7f\xdf\x05\xe9\x4d\x94\xd3\x9b\xc8\xff\x4d"
+  "\x9f\x08\x7b\xcb\x88\xbf\xb3\xf1\xca\x08\xc9\x9f\x78\x76\x92\x3e"
+  "\x7b\xe8\xfb\x6e\xa8\x4b\x97\xb4\xbb\x9e\x74\xb4\x55\x60\xcb\x10"
+  "\x64\x3c\xac\x0e\xb1\x55\xdd\x87\x9f\xda\x9f\x69\xf1\x53\x5b\x12"
+  "\x82\x9f\x0a\xf2\x47\x68\x0b\x9d\xb5\x02\x2f\xef\x76\xad\xcd\xc6"
+  "\xe7\xda\x8d\xc8\xe7\x5d\x9a\xf7\x40\x1e\x3e\xde\x5e\x1c\xc7\xb1"
+  "\x67\x0e\x18\xc9\xbf\x74\x4a\xb5\x1f\x11\x66\x29\x6f\x39\x5f\x51"
+  "\x16\x2c\x1f\x86\xd5\x51\xf9\x56\x20\x5f\x7c\xae\x47\xba\x3a\x27"
+  "\x9c\x56\xca\xc6\xd3\x94\x3d\x8b\x78\x94\xcb\x4b\x3c\x29\x1d\xeb"
+  "\xab\x57\x1d\xa5\x11\x79\xd7\x6d\xc2\x70\x1a\xab\xd2\x9e\xa6\x08"
+  "\x27\xb6\x20\x84\x49\xfa\x75\xfa\x93\xd0\x96\x52\x21\xe8\xcd\x80"
+  "\xf1\x16\xa0\x73\x79\xa3\x8e\x4a\x75\xb9\xe3\x8a\x20\x89\xf8\x91"
+  "\x5f\x77\x49\x75\x49\xb5\x64\x8b\x82\xd7\x06\xaa\x07\xf1\xff\x30"
+  "\x0f\x78\x3e\x35\x54\x1e\x8c\x57\xe5\x5b\x49\x63\xd1\xad\x6b\x44"
+  "\x5d\x31\xaf\x7a\x4c\xbf\x8f\xea\x4e\xf2\xc4\xf8\x06\xe4\xd3\x44"
+  "\x71\xfc\x7b\x40\xa2\x3e\xf5\xf4\xcd\x08\x92\x07\xd1\xd3\x37\x1b"
+  "\xc5\xd9\xdf\xd5\x27\xb8\xdc\x30\x3d\xe9\x83\x61\x1e\xc4\xa3\xd8"
+  "\xcf\xfc\x0c\xfd\xd1\x6b\x6b\x7c\xd8\xb7\xf8\xc5\x3d\x5a\xfd\xbc"
+  "\x6a\x55\xeb\x07\xd3\xed\xc3\xf4\x8d\x0c\xeb\x48\xfe\x04\xf3\x8c"
+  "\xa3\xef\xc4\x61\x58\x45\xb0\x0c\x79\xac\xf4\xf1\xb9\x1a\xe4\x33"
+  "\x01\xcb\x52\x41\x7c\xb0\x3c\x8d\x32\xaf\xdc\x3f\x16\x69\x75\x2d"
+  "\xf3\xab\x27\x9d\x73\x7b\x5e\xc3\xeb\x84\xbe\xeb\x17\x86\x1a\x11"
+  "\xd7\x80\x34\x0d\xac\x27\x15\xe8\x1b\x0c\xa2\x2d\xe1\x71\xfb\x8b"
+  "\xcf\x71\xfd\x36\x0a\xbf\xf6\x8b\x11\x05\xeb\x58\x87\xaa\xdc\x6d"
+  "\xca\x77\x2c\xe4\x72\xef\xa7\xfc\xd8\xaa\x4c\xde\xb6\x52\x1e\x94"
+  "\x5e\xf0\x7b\x75\x3f\xf1\x53\x64\x35\x0e\xcb\x21\xe4\x55\xd7\x81"
+  "\xe1\xf5\x84\x45\x2e\x37\xf4\xa3\x5d\xc5\x84\xc5\x57\x8f\x60\xfa"
+  "\x77\xb7\xd0\xf3\x2a\xfe\x9c\xc7\x7d\x6c\x5f\xfc\x28\x8a\x77\x62"
+  "\xef\x63\xeb\x73\x88\xa5\x20\xc0\xf5\xf1\x90\xe4\xb1\xf3\xba\xed"
+  "\xf5\xac\x9d\x61\x38\xe0\x07\xa0\x72\xa2\x8c\x1a\xbc\x65\xbf\xd8"
+  "\x88\x6d\x0d\xff\x56\x1f\xfa\xeb\xfd\xec\xb5\x0c\xa0\x32\xa3\x3f"
+  "\x93\xcb\xf7\x8b\x33\xb2\xee\xf7\x53\x1d\x49\x9e\xe3\x84\xef\xc3"
+  "\xb8\xfa\x9d\x54\xf6\xbe\x7a\xff\xa2\x55\x2d\x63\x5e\x6f\xd4\x03"
+  "\xe9\x8b\xf4\xa2\xe2\x49\xd8\xaf\x40\x5e\x7b\xc5\xb3\xc0\x06\xc9"
+  "\xba\x62\x38\x3b\x48\xf4\x7d\xb4\xf5\x51\x14\xb7\x1e\xf3\x1e\x9f"
+  "\x87\x6d\x3a\xda\x05\x7d\x8b\x04\xf9\xee\xa5\xef\x71\x22\x8f\x06"
+  "\x92\x29\xd2\x3d\x49\x78\xc4\xe7\x83\x22\xdd\x6b\x99\xd8\x9e\x8f"
+  "\xc1\x2b\xb9\xcf\xfe\xeb\xe7\x68\xf1\xf5\x5a\xa8\xfd\x93\xbe\x2b"
+  "\x82\xc5\xa9\xc0\xf1\x90\x0f\xd6\x93\xd2\x6b\x5f\xc9\x6d\x87\xac"
+  "\xeb\xfa\xa9\x07\xd0\x5e\x54\x3c\x1a\x43\x74\xdd\xc0\xf1\xb8\x6a"
+  "\xb6\x81\xea\x8c\x69\x1b\x64\x3e\xbc\xce\x1c\x4f\x76\x8e\x81\x83"
+  "\x6c\x15\xd6\xb3\x17\x07\xaf\x59\x65\x3d\x1f\x0c\x91\x89\xe2\xbb"
+  "\x72\xe9\x9b\x71\xe4\x93\xb0\x9f\x7b\xb7\xb7\xa7\xcf\x2f\x91\xee"
+  "\x83\x5c\xf7\xaf\x35\xd5\x8a\xf6\x56\xf6\x5b\xaf\x89\xf8\xe1\x1a"
+  "\x0c\x53\x59\x02\x1c\xbf\x54\x96\xe2\x4c\x2a\x4b\x03\x2f\x47\xb1"
+  "\x15\x4e\x4a\xf5\x85\x94\xbf\x4b\xaa\x07\xd9\x5e\x65\x5e\xbf\x38"
+  "\x44\xbc\x5e\x44\x5f\x45\x65\xc2\xbc\xb3\xb8\xff\xbb\x8f\xcb\xe4"
+  "\x23\xb9\xec\x4d\x3e\x3b\xa5\xad\x6d\x3a\x27\xf1\xb4\x4d\x78\x9f"
+  "\xec\x13\xdf\x95\x89\xc6\xf4\x7b\xe8\x2c\xff\x63\xd2\x1b\x13\xc9"
+  "\x47\xd3\x7b\x24\xbc\xbf\x86\xf6\x7c\xa2\x4f\x31\x22\x3f\x13\x61"
+  "\x54\xc1\x45\xa7\xf4\x46\x2c\x8d\x19\x50\xd6\x7b\xb1\x8f\xb4\x87"
+  "\xe4\x4d\x58\xc6\x3e\xd2\x44\x6f\xd9\x2f\x93\x15\xdc\x62\x3e\xd5"
+  "\x24\x7b\xa1\x9f\x5f\x6e\x40\x1c\x37\xf4\x61\xeb\x97\x1b\x64\x39"
+  "\xee\x41\x39\x9a\x30\x3f\x83\x5c\xaf\x3d\x48\x8f\x7d\xb1\x3d\xdf"
+  "\xc8\x65\xaf\x92\xe9\x77\x2b\x7a\x90\x6d\xf5\xe0\x16\xf2\xbf\x5c"
+  "\x07\xaf\x4f\x94\xd3\xd6\x8b\xbc\x5e\x9f\xa4\xd0\x52\x1f\x51\x7c"
+  "\x2f\xea\xf5\x49\xe4\x07\xc7\xa3\xee\xb9\xef\xe3\xdf\xaa\x15\x61"
+  "\x64\x3b\x22\x8f\x3d\x9f\x71\x1c\x62\xbf\xa7\x0f\x47\xaf\xc7\x84"
+  "\xf8\x27\xf2\xc5\x15\x2d\xc8\x83\xfc\x29\x61\x89\x7c\x2a\x8d\x59"
+  "\xb0\x8c\xed\xb2\xfd\xc8\x65\x7e\x7d\xb5\x16\x2b\x7b\xfe\x84\x58"
+  "\x19\xab\xe2\x9d\xa3\xd7\xce\xd5\x0a\x1f\x58\x2d\xd7\xed\xf7\x72"
+  "\xdd\xf6\xca\x75\xfb\xbd\x5c\xb7\x3d\x98\x07\xca\x6d\xcf\x3a\x95"
+  "\x1c\x51\x6e\xbf\xfa\x4a\xa6\x6f\x20\x5f\xde\x67\xaf\xbf\x1a\xad"
+  "\xd8\x72\x7f\x7f\xf1\xab\xc3\x64\x0f\x7d\xe5\xfa\x15\x84\xf8\x8b"
+  "\x06\x7d\x7f\xf1\x7a\xab\x5c\xdf\xba\x10\xdb\xa8\x97\xfb\xbb\x27"
+  "\x14\x3d\xb4\xe0\x98\x4c\x7c\x1b\xa9\xfa\x04\xf9\x4f\xca\x5b\xdd"
+  "\x06\xd5\x08\xb9\xca\xb6\xfc\xab\x0f\xfa\xeb\xe1\x57\x95\x6a\x7b"
+  "\x26\x5d\x93\x4f\x20\x1e\xa4\x53\xde\xaf\xc4\x30\xa1\xd7\x5f\xe5"
+  "\x92\x6f\x50\xfb\x68\xa4\xad\x0c\x32\xb2\x97\x5f\x55\x69\x6d\xf1"
+  "\x57\x46\xd9\x16\xe5\xbc\xf7\x2c\x45\x1d\x25\xf5\xe5\xbb\x27\x26"
+  "\x24\x5f\xd2\x4d\x23\xc9\x41\xd6\xe9\x23\x4a\x9b\x46\xf4\x98\xd6"
+  "\x86\x69\x52\x42\xda\xc7\x0a\x2a\x9f\x4b\x7a\xbd\x81\xfb\xac\x1d"
+  "\xdc\x57\xd8\xbc\xbc\x3c\x7b\x66\xd4\xca\xed\x04\x86\x25\xc9\x61"
+  "\x66\xb9\x2d\x51\x70\xf3\x1f\x21\x65\xaa\xd3\xef\x1f\xbd\xde\xa0"
+  "\xf4\x8f\x38\x2f\xee\x8b\xf6\xd4\xcb\xf5\xa3\xb0\xb1\x22\xec\xf5"
+  "\x5c\x0a\xdb\x22\xe4\x50\xc9\x78\x7b\xf5\xba\x59\x6e\xaf\xc8\xbe"
+  "\x24\x97\xf4\xcb\x12\xb2\x31\x7a\x46\x1e\x3e\xe2\xef\x2c\xe9\xa6"
+  "\x31\x44\x15\xc6\x25\x90\x3f\x20\x7f\x41\x6b\x53\xf9\xef\x5c\xfe"
+  "\x3b\x93\xfc\x0e\xf5\x43\x28\x1e\xe9\x62\xc8\x17\x61\xf8\xe3\xd6"
+  "\x07\xb0\x5f\xf0\xb5\x09\xf9\xbe\x91\x2c\xa7\x5d\xc6\xfb\x0a\x5f"
+  "\xa7\x46\x28\x61\x4a\x3a\xb4\xa3\x6b\x28\x1d\xa5\x57\xfc\x17\xf9"
+  "\x2e\x3f\xf9\x26\x91\xdf\x6f\x64\x8c\xf3\x71\x83\xd2\x2f\xea\x91"
+  "\x54\xb4\xf4\x4d\x19\xe1\xd3\xfc\xb2\x3f\x3b\x41\x69\xb9\xfe\xd0"
+  "\x57\xae\x3f\xc7\xbe\xac\xcd\x07\x63\xcd\x69\xf2\x8b\xd5\x9d\xa2"
+  "\x9c\x6f\xa6\x8a\x7a\xbc\x39\x94\xd7\x43\xf8\xd4\x0a\x51\x96\xea"
+  "\xce\x9a\x6e\x1e\x37\x96\xea\x42\x71\x5b\x55\x71\xac\x27\x91\xe2"
+  "\x66\xf1\x72\x85\xa4\x0b\xf6\xe4\xf4\xa3\xaf\x15\xdf\x04\x36\xd5"
+  "\xec\x50\x7c\xef\x9b\x4d\xa2\x9c\x6f\xbe\xa4\xf8\x5d\x94\x4b\x3c"
+  "\xf9\x5e\x1e\xf7\x8c\x4c\x33\x57\xfe\xe5\xfe\xfd\xcd\xff\x10\x72"
+  "\xb5\x48\xb2\xbc\x13\xe4\x7a\xfc\x89\x8f\xb3\xbf\xce\x40\xd9\xbe"
+  "\xb9\x57\x91\xad\xfa\x9e\xec\x07\xf3\x27\x9c\x09\xbf\x52\xc4\xc7"
+  "\xb0\xd5\x44\x43\x65\x12\x6d\xc4\x1b\xf5\xa1\x7d\x6a\x1c\xeb\xdd"
+  "\x43\xed\x92\xe8\xab\xbe\x3d\x42\x9e\x03\x02\x47\xfe\x2f\xb0\x5d"
+  "\x78\x2b\x57\xf1\x31\xcc\x9b\x8a\x63\xfe\xa3\x48\xf3\x16\xff\x1e"
+  "\x06\x7d\x27\x44\x4d\x43\xfe\xe9\x9d\x6e\x97\xcc\xf3\xad\x54\xc5"
+  "\x6f\x90\x2f\x69\xf1\x1c\x95\xfb\x74\x6f\xf9\x6a\x64\x5f\x72\x52"
+  "\x7a\xeb\x9c\xb6\x1f\xf6\xd6\x39\xad\xcf\x78\x3b\x36\xd4\x67\x60"
+  "\xbf\x79\xa3\xb7\xec\xad\x83\x9a\x7e\x00\x86\x9d\xdf\x77\xbc\x55"
+  "\x47\x36\x4a\xdf\x89\xe3\xfe\x89\xcf\x6b\xed\x5d\xac\x94\x99\xfc"
+  "\x66\xd7\x5a\x65\xfe\x62\x6f\x80\xfa\x6a\xda\xfc\xf6\x26\x6b\x7c"
+  "\x27\xe5\xa7\xf0\x33\x02\x7d\x67\x0c\xe5\x40\x73\x2e\x7b\x63\x64"
+  "\x3f\x5f\xa7\xf1\x95\x72\x1b\x46\x7e\x52\xdb\x56\x55\x9f\xd0\xb6"
+  "\x55\x7b\xbf\xea\xef\x23\xf7\x36\x5c\x7c\x5b\xb5\xb7\x82\xfc\x96"
+  "\xe2\x23\xb5\xbe\x60\x2f\x9f\x1f\xe8\xeb\xcb\xee\x9d\xa1\xf4\x65"
+  "\xfb\xfc\xe8\x5b\x87\xc8\x47\x61\xfe\x0d\x22\xef\xb7\x27\x62\xbb"
+  "\x3f\x59\xc9\x1b\xe3\x73\x5b\xb0\xe7\xc4\xca\xaa\xeb\xf0\xde\x22"
+  "\xf7\x01\xb9\x6d\x76\xf3\x6f\x12\xbd\x49\xdf\x70\x8a\x26\x9c\x39"
+  "\x96\x9f\x86\xf6\xbe\xb6\xa2\xb1\x6b\x85\x22\xdf\xb7\x3f\x50\xf7"
+  "\x0b\x77\xef\x60\xa5\x98\x4f\xb5\xba\x8e\x9b\x31\x6c\xab\x3c\x87"
+  "\xc0\x65\xcb\x79\xbd\x9d\x57\xbb\x43\x5b\x37\x51\x8f\xb7\xeb\xa9"
+  "\x1e\x34\x26\xc2\xfc\xb3\xa9\xdf\x83\x7d\x3e\xbc\xaf\xef\xa8\xed"
+  "\xc5\x7c\x6d\xf2\x39\xbb\xba\x7f\xb5\x7b\x06\xf9\x4a\x79\xec\xd9"
+  "\x84\xfd\x9d\x0a\xf5\x5c\xcc\x9c\xe9\xe9\xd6\xbc\xfc\xa5\xcb\x0b"
+  "\x9f\xb9\xd5\xba\x74\xf9\xd2\xc2\xa5\x8b\x73\x97\xae\x59\x5c\xb8"
+  "\x74\xc5\xf2\x31\xcb\x16\xff\x78\xe9\xd3\xd6\x55\x8b\x0b\xac\x49"
+  "\xb6\xd1\xb6\x68\xe8\x23\x9d\x62\x5d\x5c\x50\xf0\xc2\xb2\x25\xd9"
+  "\xd6\xe5\x4b\x9f\x1e\x9b\xbf\xa4\x60\x49\xa1\x75\x71\xfe\x8a\x17"
+  "\x96\x67\x5b\x47\x67\x8f\x1b\x9d\x74\x7b\x76\xb4\x7a\x0e\x6d\xa4"
+  "\x19\x3a\x83\x67\xbf\xea\xd8\x7a\x16\x4c\x71\x86\xbc\xfc\x38\xdb"
+  "\xd2\xe5\x62\xde\xee\x9d\xd8\xf1\x95\x90\x47\xdf\x89\xa7\x6f\x1e"
+  "\xb3\xb2\x5f\x5b\xf1\xd7\x48\x74\x58\x4f\xba\x37\x61\xd9\x13\xbc"
+  "\x65\xbf\x6e\x75\x49\xbf\x6d\xe0\xdf\x33\xc6\x70\xac\x5b\x02\x3b"
+  "\xfb\xa7\x0e\xec\xb3\xe5\xd1\x3b\xf3\xda\xb3\x10\x5f\xb1\x12\x8c"
+  "\x78\xc5\xe0\x65\xa6\xef\xc8\x7b\xcb\xde\x41\xff\xb3\x4f\xfe\x96"
+  "\xf9\x3b\xf5\xee\xa8\xe6\x0c\x56\xda\x9c\x21\xf4\xf2\xce\xab\xca"
+  "\x5c\x73\xda\x4b\x90\x46\xf8\x3c\x2a\xbd\xc3\xdf\x75\xbc\x88\x58"
+  "\xa6\x39\xdb\xae\x3f\xdc\x9b\x82\xfd\xc1\x23\x34\xe7\x8a\x71\xaf"
+  "\x7a\x24\x88\xc1\x72\x19\x0f\x14\x25\xc1\x76\xcc\xab\xc0\xc2\x18"
+  "\xe6\x91\xa3\xcc\xa7\x61\x1d\xcc\x58\x97\x36\xb9\x1e\x0f\xf2\x7a"
+  "\xec\x60\xa3\x2a\x87\x61\xf9\xb6\xf1\xf2\x54\x2a\x75\xc0\x72\xb7"
+  "\xb9\xa4\x5f\xfb\xb0\x9c\x66\x2a\x97\xde\x5c\x1f\xcd\x77\x61\x39"
+  "\x3f\x0b\xae\x44\xb9\x5d\x2b\xbe\x73\xb7\xb5\x46\xd8\x1f\xd6\x2b"
+  "\xbe\x16\xef\xb7\x9c\x86\x98\xcd\xf4\x8d\x72\xfb\x75\xac\xd9\xe3"
+  "\x07\x67\x4e\x1b\xc4\xad\x66\x6e\xf6\x3f\xbf\xea\x10\x75\xda\x67"
+  "\x22\xdf\xf0\xbb\x67\xdb\x8c\x54\x27\x6c\x2b\x62\x6a\x4f\x87\x9d"
+  "\x5b\x34\x6e\x1f\xce\x3c\x6c\x97\xba\xcf\xb5\xef\x79\x92\x09\xf5"
+  "\xb7\xba\xec\xf4\x5d\xeb\x7d\x19\x28\xcb\x7d\x72\xdf\xd8\xc3\x7a"
+  "\x32\x55\x7d\xa9\x7d\x84\x33\x4f\x18\xde\x26\x85\x37\x7d\xfb\x9c"
+  "\xd2\x08\xfd\xef\xfb\x0c\xd3\xb8\x55\xfc\x1b\x42\xf9\x13\x4f\xbc"
+  "\x77\x2b\xf9\x88\x71\xf8\x3e\xea\x13\xb8\x11\xcb\xee\x30\xf9\x8d"
+  "\xda\xb6\x83\x1d\x72\x62\xf8\xd6\x73\x40\xfd\x23\xb4\x75\xe2\xff"
+  "\x1b\x0b\xca\xbd\x88\xf8\xbf\x38\x1c\x60\x23\xd2\x74\x95\xbd\xb3"
+  "\xcf\xc3\xbf\x43\xfe\x1b\xb4\xff\xea\x7e\x73\xd9\x32\x9e\xa7\x84"
+  "\xe0\x39\x65\x1b\xf5\x09\x2b\x91\x3f\x62\x68\xeb\x19\x6c\x87\xf1"
+  "\x79\x5c\x25\x24\x52\x3e\x78\x4f\xfd\xca\x26\xe4\x59\xaa\xe4\xc7"
+  "\x10\xff\x5b\x82\x62\x0e\x46\xc6\xd6\x18\x9a\xbf\x2e\xb6\x31\x76"
+  "\x00\xfd\x3b\x95\x91\x30\x86\x69\xde\x55\x30\x85\x58\x3f\xc4\x71"
+  "\x15\x0f\x89\xac\xec\x37\x29\xb5\xc3\x90\x0e\x71\x55\x83\x78\x22"
+  "\x5c\x21\x6d\x87\x82\x29\xc4\x5a\x2b\xd1\x61\x19\xa2\xf7\xad\x49"
+  "\x31\x92\x8f\x6c\x97\x7e\xfb\x24\x61\x8c\xfd\xfc\xc1\x36\x76\xe5"
+  "\x82\x36\xa1\xa7\xdf\x3e\xe9\xf4\x09\x1d\xf4\xc9\xfd\xb7\x49\x2a"
+  "\xb9\xb7\x22\x8e\xa3\x49\xce\x62\xae\xfa\xb7\x4f\x62\xd9\x5a\x79"
+  "\x5f\x7c\x1d\xea\x80\xb7\x55\xbf\x4d\xa0\xf4\xb2\x0c\x0f\xf6\xc9"
+  "\xf0\xb7\x36\x3d\x19\x86\xc8\xce\x28\xbe\x75\xfe\xdb\x8d\x64\x2b"
+  "\x98\x66\xaf\xf2\xfd\x72\x3d\x5d\x62\x1e\x46\x63\x25\x98\x28\x8f"
+  "\xc6\x78\x4e\x7f\x44\x2f\x8f\x50\x1c\x37\xa2\x35\xd3\x5c\x38\xa5"
+  "\x1b\x15\x4f\x72\xfd\x5d\xbc\xae\x7e\x9f\xd6\x94\x8d\x5f\xac\xec"
+  "\x77\xd6\xed\xc3\x10\x37\xbc\x7c\xbf\x9b\x7d\xbe\xf2\x8d\xb2\x8a"
+  "\x76\xd1\x31\x92\xf0\xfc\xbb\x97\x9c\x55\x00\x14\x26\x3f\x17\x76"
+  "\x61\x5b\x13\x3a\x9f\x1f\xfe\xfd\xc2\xef\x3e\xd0\xbe\x5f\xf8\xdd"
+  "\xfe\x70\xef\x17\xb4\xf9\xee\x37\x50\xbe\xc1\xda\xf9\x06\x55\xde"
+  "\x9d\x41\x9d\xbc\x95\xf4\xe3\xea\xd4\xe3\x97\xfd\x0f\x51\x19\x5a"
+  "\xb0\x5d\x62\x3f\x9a\x6f\x60\xc8\xa7\x91\xb7\xd9\xfb\xd3\x45\x7f"
+  "\x85\xfa\x41\xfb\x93\x88\x26\xb4\x1e\xbd\x7f\xa6\xf8\x3f\xd2\xcf"
+  "\x39\xfe\x10\x79\x1f\xd0\xdb\x3c\xb8\xb6\x49\x89\x96\x34\xc4\xc0"
+  "\x74\x1e\xb0\xaf\x7c\x1d\xa7\x67\xf8\x27\x82\xe4\x67\x37\x7f\x30"
+  "\xf6\xd2\xf7\xc6\x7f\x87\xbf\x28\x51\x5e\xce\xcf\x07\x06\x39\xbf"
+  "\x0e\x15\xc5\x8c\xf3\xa4\x66\xa0\x24\xd1\xfb\x23\xaf\x59\x32\x3f"
+  "\x12\xc0\x6a\xe2\xc4\x8c\xf9\x45\x44\xef\x33\x53\x3f\x53\x88\xf6"
+  "\x19\xff\x22\x32\x55\x19\x5c\x17\x91\xcd\x97\x3b\x5d\x9f\xd2\x1b"
+  "\x24\xd5\x99\xd5\x59\x9a\xa1\x24\x92\xdf\xc4\xd1\x3f\x3e\xe4\x97"
+  "\x88\xf1\xd6\xc4\x5e\x82\xcb\x3d\x1b\x54\xe4\x7f\x16\xc5\x1f\x61"
+  "\x3b\x4f\x1d\x07\xfa\x77\xad\xea\xfe\x3a\xf1\x33\x62\xf2\x25\xe4"
+  "\x7f\xfe\x3f\x6b\x6b\x94\x72\xdb\x07\x8f\x11\x0e\x3d\xd2\x3e\xf9"
+  "\x8f\xb4\x2a\x41\x6a\x84\xf6\xc5\x8f\xae\xd6\x3e\xdf\x98\xa1\x7d"
+  "\xbe\x69\xcf\x25\x28\x39\xf0\x42\x16\xbb\x86\xa2\xce\x0a\x7b\x03"
+  "\xe3\x42\x4c\x26\xae\x22\xc4\x84\xfa\xfe\xe4\xd2\x44\x60\x79\xfc"
+  "\xaa\x60\xa3\x3e\xf5\xdf\xe7\xef\xea\x0d\xb2\x41\x5c\xe7\x36\xf7"
+  "\x8b\x9c\x16\x12\x46\xcf\x83\xac\x72\xd8\x84\x3f\xf6\xa3\xe7\x61"
+  "\x56\xd5\xb3\x21\x05\xff\xa9\x43\xfc\x1f\xbc\x14\x65\xfd\xe1\xef"
+  "\xdf\xf0\xcf\x40\xf6\xf1\xc3\xdf\xdf\xe9\x8f\x89\x56\x1c\x3d\x11"
+  "\xff\xa1\xff\x58\xaf\xa3\x64\x72\x04\x93\x03\x98\x7c\x73\x49\xda"
+  "\xf1\x1f\xfe\x7e\xf8\xfb\xe1\xef\x87\xbf\x1f\xfe\x7e\xf8\xfb\xe1"
+  "\xef\x5f\xe0\xcf\xc0\xc7\x11\x4c\xfe\x53\xee\x45\x1c\x0d\x81\x9e"
+  "\xa9\xe4\x61\x92\x01\xfa\x28\x70\xb8\x3d\x09\x0c\x26\x18\x64\xbc"
+  "\x74\xbd\x3c\x6b\x6f\x81\x2e\x32\x01\xed\xf3\x99\x80\xd7\x6d\x78"
+  "\xfd\x48\x15\x7e\xad\x3e\xf9\xf7\xf0\x67\x40\x81\x45\xe0\x38\x30"
+  "\x12\x06\xc1\x60\x30\x41\x14\x44\xc3\x65\x10\x03\xb1\x30\x04\xc7"
+  "\x97\x66\x18\x0a\xc3\xe0\x72\x88\x87\x2b\x60\x38\x5c\x09\x16\xb8"
+  "\x0a\xae\xc6\x92\x27\xc0\x35\xfa\x65\x2e\x81\x14\x0b\xfe\x83\xff"
+  "\xa7\x43\x0a\x7f\xce\xfa\x21\xfc\x7b\x0d\x77\xc8\xe1\xad\x72\xb8"
+  "\xeb\x87\xf0\xef\x35\xdc\xfa\xdf\xfc\x3b\xe2\xbf\xf5\xd7\x80\xae"
+  "\x59\x78\x67\x83\xae\x4f\x0c\x0d\x35\xc8\x7f\xbd\xcf\x70\x81\xf4"
+  "\xfd\xf8\x69\xd3\x87\xfe\xa5\xe0\x35\x51\xdc\x16\x03\x88\xf9\x5c"
+  "\xa6\xfe\xf3\x87\x4b\xa9\xfc\xad\x37\xe2\x65\xc6\x2b\x01\xaf\xeb"
+  "\xf0\xba\x05\xaf\x49\x0a\x1f\x41\x43\x53\xb2\x5f\xed\x03\xf8\x24"
+  "\x03\xe0\xd3\x0a\xfc\xf5\x00\x1c\x19\x83\x97\x03\x38\x2e\x3e\xcf"
+  "\x02\xf8\xb2\xae\x8f\xe7\xc9\x89\x7d\xa5\xeb\x1c\x25\xee\xad\x78"
+  "\xb9\xe9\x7c\x16\x4c\xe1\x57\x68\x1b\x66\xce\x4f\xb5\x4e\x18\x37"
+  "\x71\xdc\xc4\xc9\x4f\x59\xc7\xa6\x8f\xb5\xde\x9a\x94\x74\xe7\xf8"
+  "\x09\xb7\x8e\x9f\x30\xd9\x3a\x61\xd2\x94\x5b\x6f\x9f\x32\x69\xb2"
+  "\x75\xd9\xea\xfc\xa5\x13\x92\x7e\xbc\xc4\xfa\xcc\xd2\xfc\x65\xab"
+  "\x16\xe7\x2f\xb9\x50\x95\xbe\xcd\x1f\x15\xef\x9a\x20\x70\x0d\x68"
+  "\xa5\x7d\x1d\x48\xef\xd6\x81\xd4\x9c\x05\xbd\x31\x86\x0a\x79\xae"
+  "\x34\x51\xbe\xb4\x7f\x86\xa5\x9d\x60\x78\xe6\x10\x18\x9e\x8a\x01"
+  "\xc3\x82\x26\x30\xcc\x37\x81\x61\x53\x11\x18\x7e\x32\x1b\x0c\x1b"
+  "\x72\xc1\xb0\xd6\x0c\x86\x82\xc9\xfd\xc3\xb6\x1d\x11\x61\xef\x60"
+  "\xda\x37\xf1\xaa\xcf\x04\x43\x75\xaa\x08\xfb\xff\x92\xc1\xf0\x3f"
+  "\xfb\xe7\xf5\xdf\xfb\x77\xb1\xfd\x82\xf0\x7f\xd2\x37\xfb\x2f\x41"
+  "\x39\x7e\xf8\xfb\xe1\xef\x87\xbf\x1f\xfe\x7e\xf8\xfb\xe1\xef\x87"
+  "\xbf\xef\xf9\xef\xb4\x64\x84\xff\xc4\x1e\x91\xd7\x6e\xb2\xb8\x0c"
+  "\x3f\xca\xa6\x75\x22\x40\xfb\x9f\xc0\xc4\xcf\x3b\x91\x2f\xf5\x1a"
+  "\x93\x98\xe9\xbb\x01\x68\x0f\xe7\xf6\x1d\xcc\x4d\xfb\x33\x67\xfc"
+  "\x12\xa0\x11\x7b\x8a\xb4\x6e\x05\xf9\x64\xba\xe0\xf9\xd9\x62\x8d"
+  "\x12\xf3\x50\x3c\xad\x73\xc2\xf0\x42\x0c\x6f\x3c\xcf\xba\x17\xbe"
+  "\xc6\x8a\x78\xce\x18\xc1\xcb\x53\x1f\xc2\x87\x78\x34\xb8\x20\x3f"
+  "\xf9\x3c\x3c\x62\x94\x72\x79\x24\x30\x10\xbf\x2e\x3b\x58\x3c\x76"
+  "\xc7\x15\x98\xd6\x83\x75\x4a\x94\xd7\x08\x75\x32\x3b\x44\x34\xda"
+  "\xfc\xb4\x57\xd4\x70\x0c\xa2\x5f\xc5\x5f\x09\x7f\xc5\x3e\x38\x91"
+  "\x6e\x14\xf1\xc0\xb4\x06\xaf\x3d\x2a\xa9\x37\x2d\xf2\xe6\xfb\xbd"
+  "\x21\x7a\xa9\x47\x72\x48\x82\xd6\x1c\x25\xd3\x4a\x48\x9b\xa9\xd0"
+  "\x8a\x38\x69\x96\x1c\x77\x19\xc6\xd9\xb4\x71\xc6\x6d\x72\x5c\x0c"
+  "\xc6\x55\x86\x94\xcf\xe8\xec\xf6\xc3\x31\x88\xda\x8b\x65\xb1\xd2"
+  "\xde\x24\x4a\x23\xd3\x0f\x45\xfa\x46\x2d\x2f\x00\x39\x6e\x18\xc6"
+  "\xb9\xb4\x71\x7f\x48\x92\xe3\xae\xc4\x38\xbf\x36\xce\xa0\xa4\xb3"
+  "\x78\xed\xd1\x16\x9d\x7a\x52\xfe\x06\x91\x37\xd5\x21\x3a\x19\x69"
+  "\x4a\x88\x66\xbe\xb5\x04\x48\x57\x14\x77\xa0\xae\x37\x7f\xa2\xc9"
+  "\x52\xf8\xb8\x30\xbd\x4a\xa6\x28\xcb\xe8\x22\x25\xfd\x0c\x2b\xf1"
+  "\x00\x2e\x43\xe2\xe3\x82\xa8\x54\xe2\x43\xcf\x78\x9f\x40\xf5\x96"
+  "\xef\xad\x54\x3f\xed\xda\x1d\x1c\xfa\x40\x24\x0e\x6e\x06\xe1\x35"
+  "\xd8\xa4\x60\xa0\xc0\xc2\x82\xc5\x57\xd1\xfa\xac\x8f\x9b\x82\x76"
+  "\x06\x4e\x9b\x0f\xac\x57\x43\xf1\x51\xb8\xcc\x42\xeb\x7f\xb6\xac"
+  "\x01\x53\x71\x1e\xf3\xd1\x9e\xfa\x16\x77\x27\x14\xbb\x59\x07\x9d"
+  "\xa7\xb4\xfe\x0c\x98\xe8\x5c\xa4\xf5\xcf\x83\xa5\xb1\xe8\xaf\xba"
+  "\x6b\x8e\x82\x74\xfe\x71\x02\xa5\x6d\x87\x96\xea\x76\x28\xae\xd6"
+  "\xa6\x2d\xbe\x06\x2c\xcd\x74\x36\x93\x1d\xe2\xa8\x1c\x8d\x56\x3f"
+  "\xf8\xa3\x3f\x6e\x2a\xda\x09\xc6\xe2\x11\x38\x0a\xc9\x76\x28\x65"
+  "\x71\x51\x59\x36\x1e\x07\xd3\x6b\xcf\x20\x86\x8e\x53\x79\xbf\x68"
+  "\x7a\x67\x8d\x4f\x3a\x60\x99\x0d\x07\x2c\x47\xa0\xd1\x32\x15\x1a"
+  "\x6d\x33\x60\xcb\x71\x88\x39\xe0\x4b\x86\x46\xe3\x7d\x68\x63\x33"
+  "\xc0\xd9\x89\xf7\xd6\x00\xd2\x78\xf8\x7e\x8e\x63\x70\x59\x6b\xe5"
+  "\xb3\x60\x72\x09\x9e\x28\xdf\xcb\x8e\x28\x7b\x13\xe8\x59\xaf\x1e"
+  "\x05\x57\x81\x05\xcb\xd7\x81\x65\xb9\xf3\x28\xc4\x5c\x31\xca\x02"
+  "\x49\x58\xe6\xc1\xce\x2a\x3f\x18\x8b\x20\x2a\x8c\x6d\xc5\xf3\x7d"
+  "\xcd\x88\xcd\x9a\x1d\xac\x83\x30\xda\xb5\x36\x03\xed\x34\x66\x36"
+  "\xe6\xdd\x29\xaf\xf7\xeb\x2c\x7e\x15\x8c\x5d\xab\x32\x68\x9d\x73"
+  "\x3b\xc6\xe5\x28\x71\xb4\x5f\x9b\xf6\x61\x8f\x8f\xa7\x6f\xe3\xa5"
+  "\xc0\xfb\xdd\x1d\xb4\x96\xb0\x93\xd6\x77\x12\xbf\x38\x1b\x44\x60"
+  "\x7d\x22\xb1\x3c\x77\xd6\x62\xf8\xf5\x48\x87\xe9\xf7\xb8\x60\x3f"
+  "\xc7\x11\xbb\x72\x81\x27\x78\xe5\x82\x33\xc1\x9f\x2f\xe8\x62\x3f"
+  "\x5f\x70\x3a\xf0\xf3\x05\xdf\x14\xaf\x06\x53\xe0\xca\x05\xee\x96"
+  "\x3c\xae\x03\x73\x4b\xde\x09\x5a\x17\x68\x5a\x77\x02\xcc\x0b\x9f"
+  "\x47\xdd\xfb\x3f\x83\x75\x4b\xc1\x12\x8c\xfa\xbc\x84\xbe\xa1\xb7"
+  "\xb0\x08\x18\xde\x57\xe8\xd5\xaf\x2b\xda\x65\x12\x36\x64\xc2\x3a"
+  "\xc5\x5a\x5d\xd2\xff\x71\x50\xbe\xee\xa8\x0e\x13\x5e\x31\x78\x99"
+  "\xf1\x8a\x67\xd1\xae\x78\x94\x55\xf1\x90\x0d\x06\xa0\xfd\x08\xe3"
+  "\x83\x60\x38\x0e\xb1\xc9\xf4\xdd\x86\x30\x72\x4b\x08\x96\x9d\xb5"
+  "\xde\x58\x02\xeb\xbd\xde\x1c\xda\x17\xee\x26\xbf\x44\x7e\x0a\xf3"
+  "\x29\x75\x49\x1f\x73\x5d\xa1\x7f\xf3\xb0\xe8\xb3\x56\x0c\xef\xf0"
+  "\xac\xcd\x31\xb8\xd7\xe6\x48\x5d\xd1\x67\xaf\x47\x9a\xbd\x48\x33"
+  "\x59\x96\x61\x07\xf1\x42\x9b\x70\xc7\xfa\x21\x02\x79\xe6\xfd\xaf"
+  "\xb3\x6d\xc6\xdd\x3b\xd8\x11\xa4\x3b\xd4\xcb\x0b\x79\x23\x1f\x94"
+  "\x7f\x6c\x87\x12\x86\xb2\x6e\xdf\x8c\x74\x94\xde\xe9\x4b\x21\xff"
+  "\xed\x72\xe6\x76\xd0\x7a\xdc\x68\xd6\x23\xf2\x43\x1a\xda\xab\xe9"
+  "\x8e\xf5\xc1\x20\xaf\x1d\xd2\x89\x37\xa5\x73\x76\x76\x00\xa6\xbb"
+  "\x9e\x15\xe7\xa0\x7f\x83\xb9\x5e\x96\x63\xa0\xbd\xf9\x07\x30\xbd"
+  "\xc8\x7b\x48\xba\x52\x46\xca\x83\xef\xcd\xa7\x72\x22\x1e\x0e\xe4"
+  "\xfa\x20\xb6\x0a\x22\x30\xdd\x3c\xe2\x47\xbc\x10\x07\x2e\xac\xeb"
+  "\xf5\x07\x72\xdd\x10\x64\x1a\x9e\x2e\x99\x5f\x9d\x86\x1f\x86\x33"
+  "\xe4\x47\xf8\x6b\xc4\x34\xb1\x75\x9c\xdf\xc3\xff\x2b\x48\xfc\x7c"
+  "\x60\xb4\xf2\xf2\x3e\x4a\x3c\xf8\x59\x17\xc8\xd3\xb1\xf2\x5e\xe8"
+  "\x84\x38\x93\xbb\x38\x27\x82\xaf\x0b\xc4\xf4\xef\xac\xef\x88\x64"
+  "\x5d\x19\x11\x43\xf8\x9a\xc0\x7b\x81\xce\x63\xe8\x84\x21\x5f\xb1"
+  "\xae\x9c\x88\xd8\x4e\x30\x52\x99\x69\x5f\x10\x95\x53\xad\xcb\x87"
+  "\x67\x3e\x3a\x15\x1e\x9d\x31\x6b\xc6\x54\x98\x73\xcf\xf4\xa9\x90"
+  "\x74\xe7\xd8\xa4\xdb\xee\x98\x7c\x1b\xa4\x3f\xf6\xf0\x54\x48\x9f"
+  "\x3b\x15\xe6\xe1\x95\x3e\x6f\xe6\xc3\x33\x66\xce\x9b\x0a\x19\xf7"
+  "\xcd\xc2\xa7\xe9\x53\x27\x24\xdd\x3f\x36\x7d\xfa\xac\x99\xf0\xd0"
+  "\xfc\x5b\x93\x6e\xbd\x15\xee\x99\x39\x7b\x42\x52\x92\xfc\x3b\x21"
+  "\x89\x48\x9e\x98\x3c\x73\xde\xd8\xf4\xfc\x15\x85\x2b\xc6\xce\x9d"
+  "\x35\x1d\x66\xce\x9c\x9a\xae\x6d\x6b\x13\x03\x67\x03\x24\x63\x0f"
+  "\x3b\x95\x4a\x67\x30\x40\x0d\xea\x1e\xaf\x4e\xbe\xb7\x03\xcc\x1f"
+  "\xd5\x90\xce\xb8\x6f\x8d\xa3\xf6\xca\xe8\xb5\xc7\x1d\x41\xd9\xf1"
+  "\x73\x46\xe8\x1c\x84\x63\x30\x7c\x34\xc6\xdd\x24\xb7\x1d\x91\x18"
+  "\xef\xd7\xc6\x0f\x6d\xc5\xf8\xf1\xb4\x57\xc0\x89\x17\xca\xdb\x83"
+  "\x3e\x10\xe5\xea\x86\xae\xe2\x8c\x48\xbe\x57\x13\x75\x4d\x6b\x68"
+  "\xbd\x76\xf3\x64\x95\xad\xb7\xd3\x5a\x5b\xeb\x1a\x88\x38\x09\xe6"
+  "\xa1\x2d\x85\x29\xb4\x9f\x06\x9c\x85\x32\x8f\x33\xbd\x3c\xa2\xe5"
+  "\xfd\x9e\xae\x1a\x5a\xc7\x2c\xf8\x94\xa8\xfc\x82\x8b\xf8\x6c\xc1"
+  "\x38\x99\xd7\x23\x2d\xe8\x1f\xd0\x7f\xff\x25\x58\x9c\x08\x2c\xfa"
+  "\xe3\xd6\x60\x4f\x22\x6f\x13\x30\x5d\x83\x82\xe7\x2d\xb4\x46\x36"
+  "\x0f\xe9\x5e\x4b\x35\xd0\x1a\x53\xbe\xde\x14\xe2\xe8\xcc\x05\x4f"
+  "\xb0\xac\xc3\xc2\xf7\x42\xf3\xb0\xa1\x46\x16\x8d\xcf\x65\x1d\x57"
+  "\xb1\x62\xb1\x3f\x1a\xc3\x22\x29\x0c\x75\x1d\x41\x36\xc9\xf7\x7f"
+  "\x62\xde\x18\xbe\x1a\xcb\xd7\x16\xa0\xf4\xa7\x78\xfa\xc1\x18\xf6"
+  "\x38\xd2\x5e\x15\x8c\xee\xb8\x1a\xb1\x43\x61\xd8\x4f\x18\x3e\x03"
+  "\xf9\xfd\x88\xf6\xa6\xb3\x98\x49\x56\xbc\x4f\x70\xac\xe9\xe4\xe7"
+  "\xef\xb9\x30\x2e\x58\x8c\x3c\x7b\x7a\xf3\x4f\xa4\xb4\x98\x97\xd1"
+  "\xdb\x93\x83\x6d\xdc\x50\x7e\xf6\x5a\x80\xca\x73\xaa\x97\xc6\x42"
+  "\x79\x92\x5d\xa3\x2e\x26\xa2\x9e\xa2\xbc\xf6\xa1\xf5\x21\x7a\x7a"
+  "\x17\xf9\x5c\x85\x72\x6f\x43\x1e\xf1\xc1\x2e\xcc\x03\x9f\x91\xaf"
+  "\x24\xf3\x55\x78\x78\x04\x0e\x86\xb6\x87\xe0\x20\x0a\x79\x4f\xed"
+  "\x8b\x1f\x66\xd4\xc6\x5f\x71\x02\xe3\xef\x95\xe3\xd1\xbe\x86\x8d"
+  "\xd2\xc6\x0f\x4b\xc1\xf8\xfb\x30\x7f\x0f\xda\x4f\x84\x0b\xcc\x7b"
+  "\x6a\xa8\xff\xd7\x47\x3f\x3f\x84\x3e\x0f\xe9\x1f\xa0\x75\xf0\xe4"
+  "\xdb\x89\xbe\x56\xc6\x2a\xd2\x9b\x90\x7e\x63\x48\xfe\xcd\x48\x3f"
+  "\x4f\x55\xbe\x90\xfa\x5f\x9e\x8b\xf1\x19\x84\x2d\xfc\xcd\x46\x9a"
+  "\xc1\x64\xb3\xe4\x2f\x0e\xe4\x52\x7f\x71\xd8\xa1\x90\xfc\x89\xee"
+  "\xb9\xa0\x22\xa3\x2e\x92\x91\x79\x8f\xdc\x17\x39\x22\xca\x70\xb9"
+  "\x29\x24\x8f\x44\x4c\x53\x80\xf8\xb9\x4a\xc1\x86\x4e\x9a\xe4\x90"
+  "\x34\x99\x1c\x5b\x22\x1f\x59\xc7\x22\x8d\xec\x8b\xd4\x3c\xa8\x6e"
+  "\xd8\x3f\xba\xbc\x24\xa4\xee\x99\x98\xef\xda\xcd\xc2\xce\x2f\x43"
+  "\x4c\xdc\x8a\x61\x73\x90\xe7\x35\x84\x23\xc2\xba\xd3\xed\x43\x5f"
+  "\x99\x1a\x23\xda\xfc\xcb\xbf\x8c\x2b\x02\xba\x1f\x4b\xf7\xc4\x9b"
+  "\xf5\xcc\x96\x6d\xe0\xf2\x2f\xf1\x97\xc2\xf9\x99\x45\x64\x7b\xac"
+  "\xe7\xc1\xa0\xe0\x19\x1f\x89\x36\x2a\xe1\x73\x40\xce\x63\x26\xed"
+  "\x23\xc6\xf2\x5f\x8d\x7e\x18\x68\x2f\x34\x86\x4f\xc4\xf0\xa9\x72"
+  "\xfc\x24\xa2\xc7\xfb\x09\xf2\x3d\xe1\xf6\x6a\x19\xb7\x68\x07\x57"
+  "\x8c\xe5\x79\x73\x5b\x10\xe9\x83\x02\xf7\xd3\x31\xee\x2a\xfc\x9d"
+  "\x85\xbf\x91\xf8\xfb\x10\xe6\xfd\x25\x9d\xfd\x50\x1c\xc0\x7e\x87"
+  "\x78\x6e\xc6\xdf\x87\xf1\xf7\xf7\xf8\x3b\x0f\x7f\x7f\x49\x76\xeb"
+  "\x5e\x95\x03\x21\x98\xe9\x0c\x0a\x5b\x1d\x2c\x74\x18\x5f\x29\xdb"
+  "\x8f\xb0\xdf\x53\x7d\x61\x4c\x84\x49\x42\xe6\x72\x58\x4f\x2a\xc9"
+  "\x25\x1d\xf9\xe7\x51\xfe\xb2\xdd\x47\x0a\x3d\x09\x9a\xa0\x48\x67"
+  "\x14\xfa\x96\xc3\x04\x9d\x41\x9d\x27\xfe\xce\x58\xef\x61\x0c\x7f"
+  "\x93\xf8\xb9\x11\x70\xc5\x44\x94\x89\x11\x9f\x8d\x24\x27\x4e\xcf"
+  "\xf9\x5e\x5e\xa7\xd2\x37\xf6\xc7\xaf\xc8\x0b\xd1\x77\x3d\xea\x7b"
+  "\x33\xd7\x37\xca\x4e\x29\x33\x95\x1f\x31\x4d\x6d\xdb\x20\x05\x37"
+  "\x88\xef\xce\x3e\xdf\x7d\x45\x83\x96\x8f\x79\x0f\xa6\x29\xc7\xfc"
+  "\xf8\x99\x7e\x74\xfe\x4d\x44\x11\x61\xf4\x0a\xec\xff\x37\xf3\xf3"
+  "\x8e\x30\xfe\x5a\xe2\xe3\x29\xe6\xe7\xec\x78\x22\xf2\xc8\xb6\x86"
+  "\x83\x12\xcf\xe3\xa2\xce\xd6\x51\x59\x22\x72\x79\x5c\x82\x0b\xa1"
+  "\xa5\xc4\x81\xd8\xbf\xe5\x89\x28\xe4\x71\x93\xfb\xf8\x7e\xec\x96"
+  "\xf9\x46\x50\x7f\x83\xfa\x0d\xd8\x7e\x77\x20\x0d\x8e\x7f\x62\x33"
+  "\xc2\x9e\xa9\x54\xfa\xb1\x0b\x41\x23\xdd\x5c\x02\x91\x4e\xff\x21"
+  "\x48\xf3\xb3\xc0\xd8\x12\x88\x72\xfa\xf7\xc2\x4d\x00\x43\x9d\xfe"
+  "\x23\x70\x33\xc0\x08\xa7\xbf\x12\xdb\xe7\x7a\x8a\x7f\x3f\x11\x0c"
+  "\x06\xfc\x2d\xbe\xa1\x44\x32\x38\xfd\x1b\x61\x54\x89\x11\x7f\x73"
+  "\xe1\xbe\x48\xe6\x75\xfa\x67\x23\x5d\x36\xa4\x05\xd8\xa9\x19\x91"
+  "\xec\x8b\x45\x01\x30\xcf\x7e\x89\x15\x3b\xfd\xd8\x57\xf6\x1f\xc4"
+  "\xf0\x20\x4b\x0b\x9c\xc3\xcb\xcb\x82\xa5\x1f\xbb\xd3\x02\xa7\xd8"
+  "\xf4\x97\xde\xc7\xe7\x2f\x18\x93\x80\x39\xfd\xc9\xd0\xe2\xf1\x20"
+  "\x5d\x31\x63\x9b\x3e\x76\x2d\x3c\x23\x41\x0f\x9d\x77\xb4\xe9\x63"
+  "\x37\x2b\x6b\x83\x1e\xac\x1f\xb6\x41\xac\x67\x2d\xfe\x96\x7d\x1c"
+  "\xe4\xcf\xa5\x6d\x66\x66\x6a\x83\x71\x38\xf0\xa0\x3a\x38\xfd\xed"
+  "\xb0\x08\xbb\xce\x69\xab\xdd\x8c\xca\x3f\x64\x03\x8d\x3b\x92\xe9"
+  "\xac\x84\xb8\xb4\xd5\xc5\x0c\xe3\x4c\x2c\xaa\x0d\xe9\x3a\x81\x6d"
+  "\xc2\xb4\xd1\x6d\xb1\x9c\x5f\x69\x5b\x12\xd2\xba\x89\x4e\xcd\x87"
+  "\x78\x10\x6d\x5a\x00\xe2\x90\x3e\xa9\x27\xaa\xcd\x8a\x57\x0a\x5e"
+  "\x79\x98\xd6\xce\xec\xf1\x7f\xa4\xfd\xae\x98\xbe\x02\x9f\xeb\xbc"
+  "\x74\x36\x13\xc9\x32\x00\x83\x91\xbe\x02\xf1\x33\x03\x71\x88\xe5"
+  "\x6d\x73\xf0\xf2\x96\xb5\xbd\xef\xe5\xf5\x68\xfb\x83\xa8\x47\xdb"
+  "\x7b\x14\xde\x85\x98\xc2\x7b\x57\x97\x88\xfb\x02\xd3\xcd\xe7\xe9"
+  "\x4a\xdb\x5c\x58\x3f\xb7\x0f\xed\x0b\xe5\x5a\x42\x72\x44\xb9\x96"
+  "\x90\x2c\x91\xbf\xcb\x69\x2b\x07\xac\x8f\xbb\x27\xea\x30\x62\xf6"
+  "\xf0\xb0\x1e\xde\x4e\x1f\xb6\x7a\x39\xef\xc3\xd7\x21\x9f\x4c\xc4"
+  "\x6f\x04\x33\x1d\xb6\xb2\xd2\xc3\x49\x3d\x76\x2b\xa4\xad\x66\xbe"
+  "\x34\xff\x06\xff\xa2\xd5\x10\x31\x06\x4a\xb0\xbc\xef\xa1\x8c\xb2"
+  "\xb1\x9e\x8d\xf8\x3b\x03\xe3\xe1\x72\xcc\xeb\x7d\x16\x75\xd8\x4a"
+  "\xf9\xb1\x4d\x87\x93\x90\xe7\x58\xe4\x95\x4d\x65\x3a\x67\x07\x94"
+  "\xdb\xe1\x94\x73\xbc\x7c\x87\xb3\x82\xa5\x87\x4b\x82\xa6\xc3\x79"
+  "\x0a\x86\x08\x3f\x42\x6e\x95\x30\xd7\xc3\xfc\x4e\xff\x6e\x40\x8c"
+  "\x99\x5b\x3c\x47\x28\x1e\xc7\x06\x7b\x51\xcf\x84\xa9\x8d\xf8\x5b"
+  "\x0f\x84\x9f\x96\xbc\x17\x88\xf6\x7d\xc2\xd0\xdc\x3c\xcf\x86\xb1"
+  "\x90\x67\xc0\xe7\xe2\x45\x7e\x13\x2c\xcc\x33\x96\x04\x4a\x0f\xa7"
+  "\xb7\xe4\x91\x5e\x0e\x61\x1a\x4a\x97\x0b\x71\x06\xec\x1f\x1b\x98"
+  "\x3f\xce\xe6\x36\xc6\xe6\x14\xb3\x16\xcf\x6c\xa4\xcd\x03\xaa\x0f"
+  "\xe1\x88\xe8\xe7\x74\x32\x57\xc0\xf4\x09\xaf\x1b\x1b\x52\x02\xcd"
+  "\x9d\x93\x80\xc6\x28\xcd\x9d\xf5\x84\xd3\x20\xca\xa5\x15\x31\xda"
+  "\x33\xa7\xb3\x24\x72\xe1\x19\x30\x60\x58\xa0\x39\x67\x2f\xc6\x37"
+  "\x22\xdd\x41\x8e\xdb\xb9\x67\xfc\x71\x7e\xd3\xe1\x14\x7f\xe9\x61"
+  "\xd7\xdc\x33\x3d\xac\x39\xa7\x12\x9e\xec\x2c\x41\x59\xed\x85\x39"
+  "\x27\xfc\x11\x2d\x79\xd9\x48\xe3\xc5\xf0\x7a\x8e\xff\x39\x27\xba"
+  "\xd8\xdc\xe7\xd9\xa9\xb9\x67\xbe\x60\x73\x72\xd8\xfb\x8b\x6c\x30"
+  "\xe4\xb2\x0d\x2c\x48\x76\x71\xb0\x7d\x2f\x5c\x76\x84\xce\xc2\x99"
+  "\x01\xb3\x17\x07\xd9\x9c\x13\xa7\xd8\xc2\xe7\x49\x36\xc9\xd0\x9c"
+  "\x83\xf6\x63\xab\x24\x79\x67\x35\xe7\xbc\x8b\xf9\xcf\x40\xbe\xc5"
+  "\xcc\x69\xdb\x8d\xb4\x8e\xb8\x27\x4f\x98\xe1\x60\x7b\x25\xf8\xa3"
+  "\x0e\xa7\x04\x36\x1d\x4e\x0f\x46\x1d\xce\x0b\x6e\x3a\x5c\x82\x7a"
+  "\x6a\xf5\x6f\x3a\xec\x0a\x44\x7d\x82\x18\xf8\x24\x1d\xf5\x14\x45"
+  "\x3a\xef\xc6\x31\x3b\x3e\xcf\xed\x26\xfd\x97\x7e\x92\xc5\x4c\x9f"
+  "\x94\xa0\x6f\x64\x02\xfb\x9f\x64\xd1\xb8\x9b\x45\x7d\x52\xd2\x13"
+  "\xf5\x49\x1e\xd2\x95\x08\xfb\xfa\xa4\x82\x70\xc9\xdb\xa6\xb2\x4f"
+  "\xb6\x62\x5b\x12\x81\xf1\x75\x78\xed\xc3\xcb\xc1\xca\x3e\xc5\xb1"
+  "\x20\x0c\xe5\x98\x2a\xfd\xd4\xcc\xee\xae\xc0\x7e\xe6\x19\xc2\x64"
+  "\x31\x8b\xfa\x34\x29\x2d\x30\xb9\x18\xe5\x88\xb6\xf2\xa9\x39\xb8"
+  "\xe9\x53\x2b\x8b\xfe\x34\xdd\xc7\xf1\xff\x69\x1a\xf1\xef\x59\x9b"
+  "\x48\x63\x72\x23\xc6\x67\x61\xd8\x5f\xbc\x84\x57\xd3\xa7\xad\x41"
+  "\xd3\x91\x24\xe4\xe7\x7a\xf0\x25\xe6\x0e\x94\x1e\x81\x60\xe9\xa7"
+  "\x6e\xff\x20\xec\xc3\xda\xde\x05\xf2\x51\xfe\x3f\x30\x94\xc3\x07"
+  "\x28\x93\x7a\x8e\x01\xa7\x0d\xed\x60\xf5\xd5\x25\xcd\x9d\x88\x87"
+  "\xbc\xb7\xb9\x7f\x6a\xf1\x1c\xe2\x72\xc5\x72\xb4\x12\xae\x48\xc7"
+  "\x0b\xf3\xa0\x04\xf3\x72\x61\x59\xdc\x81\x4d\xc8\x37\x0a\xf3\x89"
+  "\xfe\x3c\xdf\xc7\x6d\xf6\x73\xc4\xec\xbb\xfc\x7b\xeb\x02\xe7\x9f"
+  "\xe7\x85\xf3\x93\xe4\xaf\xc8\x47\xa5\xf9\x7d\x84\x9b\xbf\x91\x6f"
+  "\x13\xbe\x0a\x16\x29\xbe\x8a\xfc\x14\x8d\x0b\xc8\x57\x05\x65\x5f"
+  "\x15\x94\x7d\x15\x7f\x36\xa1\xbf\x29\x6d\xe3\x3e\x29\xcd\x26\x7c"
+  "\x4d\x5a\x20\x89\x21\x3e\x62\xd0\x96\x41\xe8\x03\x69\xca\xda\x62"
+  "\x39\x3d\x97\x53\x5b\x52\x10\x7d\x0e\x5e\x29\x41\xe1\x73\x4a\x64"
+  "\x9f\x23\x29\x3e\x27\x60\xa7\xb3\xac\x09\x5f\xfd\x7d\x4e\x50\xf6"
+  "\x39\x01\x26\x7c\x4e\x50\xf6\x39\x14\x1e\x90\x7d\x4e\x40\xc7\xe7"
+  "\x04\x4b\xdb\xa8\xbe\x11\xb2\xaf\x29\x21\x5f\x43\xf5\x0d\x6e\x6a"
+  "\x73\x07\x85\xaf\x31\xe3\x98\x40\x22\x5f\x13\xc0\x34\x41\xc5\xd7"
+  "\x78\xb9\x4f\x48\x22\x7f\xd3\xf3\x13\x40\x1f\x6a\x05\xf2\x33\xdc"
+  "\xa7\xf8\x47\xf8\xc9\xa7\xa0\xfc\xa6\x85\xfa\x14\xe4\x97\x82\xf7"
+  "\x66\xd9\x57\xe5\xc5\x6d\x60\x7e\xf4\x29\xe9\x69\x36\x0f\xca\xe5"
+  "\x33\x1c\x1b\xa3\xef\xb6\x15\x96\x38\x6d\x7e\x40\x5f\x50\xc2\x5a"
+  "\x4a\x10\x23\x87\x11\xc3\x01\xf4\x17\x00\x68\x9b\xad\x7e\xb4\x73"
+  "\xcc\xdb\xd5\x92\xf7\x11\x04\xd0\x5e\xe7\x74\x76\x39\x17\x7a\x12"
+  "\xcd\x73\x4e\x30\x37\xca\xc7\xb5\x30\xaf\x04\x7d\x4c\xa2\xbb\xb9"
+  "\xf3\x3d\x98\xdd\xce\x82\xb3\xb3\x5c\x56\x2c\x87\x6b\xce\x52\x47"
+  "\x1c\x9d\xa7\x3d\xf7\x0c\x73\xa0\x6f\xfc\xdf\x73\x4e\x98\xe3\x32"
+  "\xdb\xe1\xda\xd9\x8b\x59\x30\x80\xb6\x86\xf5\x4d\x47\x3b\xcb\xc2"
+  "\xb2\xe7\xa1\xdd\x95\xa0\xad\xb5\xfa\x43\x6c\x0d\xed\x66\x2e\xde"
+  "\x5b\x85\xfc\x3e\x29\x41\x5b\xcb\x0a\xf2\x36\xad\x9d\x8f\xc5\xd0"
+  "\xde\x4a\x68\xae\x0a\xed\x2d\x2b\xb8\x49\xd8\x5b\x50\xa4\xab\x08"
+  "\x92\xfc\x24\xd9\xde\x50\x17\x18\x5f\x87\xd7\x3e\xbc\xf4\xed\x2d"
+  "\x2f\xc4\xde\x9e\x97\xed\x2d\x4a\xd8\x1b\xea\x35\x22\xb0\x56\xd8"
+  "\x1c\xe5\x41\x63\xb6\x5e\x9b\x8b\xfe\xb4\x95\xce\xf6\x11\xf8\x21"
+  "\xbb\xfb\x14\xdb\x97\x23\x28\xd3\x4f\xdd\xc1\xd2\x23\xc8\x8f\xb9"
+  "\xc9\x7f\x22\x3e\x3f\xa7\x36\x6f\x6e\x1e\xfb\x7c\x51\xe0\x6a\xf4"
+  "\x31\x47\x00\x7d\xda\x17\xe8\x4f\x3f\x5f\xe8\x81\x3a\xe4\xd5\x8a"
+  "\xf9\xb9\x02\x68\x57\xc1\x4d\xdc\xa6\xf2\x02\x6b\x89\xe7\xe7\x79"
+  "\xbd\x3c\x78\x9b\xa9\xb5\x29\x31\xd3\xad\x3f\x5f\xe8\xb5\x5f\x17"
+  "\xe3\x82\x23\xe2\x3c\x48\xfb\x75\x16\x17\x7c\xb6\x57\xbe\x1f\xe5"
+  "\x82\x3f\xf0\x70\xb2\xc5\xbc\xf5\x70\xc5\x71\xb8\xae\x0d\x71\x0f"
+  "\x78\x1f\x83\xf7\x47\xd2\x6e\x7a\x9f\x05\xcb\x47\x66\x60\xde\x5e"
+  "\xb2\x47\x66\x9f\x88\xe3\x10\x48\x41\x3c\x9a\x98\x97\xce\x60\xff"
+  "\x7a\x24\x9d\xc1\x4e\x67\xae\xe3\xf3\x10\x94\xc1\x28\xfc\x1d\xb6"
+  "\xfb\x2c\xc4\xe3\x65\xd9\x2d\x9f\xf7\x8e\xf7\x49\x6c\x95\x25\x7a"
+  "\xcb\x4a\x18\x13\xe7\x11\x67\xad\xd3\xd9\xf0\x71\x7e\x88\xa7\x7b"
+  "\x66\xff\x4f\x7f\xed\x59\xf9\xbc\xf5\x58\xcc\x8f\xce\x5b\x2f\x48"
+  "\x84\xda\x7c\x7e\xf6\xa5\xa5\xd6\xce\xf6\x05\xbc\x24\x87\x8f\x5d"
+  "\x4a\x59\xa8\x6c\x58\xce\x6b\xb0\x9c\x9d\x8f\xac\x4e\x81\x0f\x6c"
+  "\xfa\xfb\x28\xbd\x76\x6b\x6f\xfd\xc3\xc4\x8f\x51\x64\x12\x26\x7e"
+  "\xb6\x22\xa7\x70\xfb\x59\xa9\xbd\x0e\xac\x64\x9d\x74\x06\x07\xed"
+  "\xbb\x2d\xf6\xb3\xff\x8b\x72\x2c\x59\x1f\x00\x53\x9a\xcd\xc7\x9c"
+  "\x9d\xcc\xe1\xb4\x9d\x80\x5a\x3a\x17\xa4\x88\x05\x83\x51\x5f\x23"
+  "\x6e\xbe\x86\xae\x95\xcc\x4f\x73\x1f\x98\xc7\x3e\x17\x4c\xdf\x23"
+  "\x74\x71\x38\x8b\x8f\x01\x4d\x5f\x13\xaf\xa1\xc4\xab\x19\xd3\x07"
+  "\x36\x7d\x4d\x65\xc1\xb1\xf1\x71\x0f\xa7\x33\x1d\xce\xca\x5b\x03"
+  "\x3f\x3a\x0e\x23\xf8\xb9\xac\xac\xf4\x6b\x0b\xf9\x05\x0c\x33\x63"
+  "\x58\x02\xf2\x4f\xf0\xda\x47\x98\x5c\xf0\x7f\xfc\xa2\xaf\x3b\x22"
+  "\x41\xa1\x73\x81\x95\x76\x6c\x6a\xe6\x4e\xe5\xd5\x12\x25\x9a\x7d"
+  "\x5d\x06\xd0\xee\x52\xa3\x9c\x52\xf4\xa3\xfb\xfc\xfa\x61\x17\x9d"
+  "\xa7\x59\xbc\x0e\x12\x50\x3f\x54\xbe\x97\x8b\x6d\xec\x18\xb3\x8f"
+  "\x48\x7c\x6d\x8d\x0f\xc7\x10\x23\xaa\x5d\xf0\xeb\xc2\x70\xf2\x0c"
+  "\x9e\x65\xed\xc8\xa3\x64\x2b\x8e\x03\x49\x3e\x24\x4f\xb4\x9b\x20"
+  "\xca\xe1\x4b\xf2\x4b\xb5\x2b\x69\x2c\x3c\xc2\xa5\xc8\x2b\xbc\x4e"
+  "\xbe\x8e\x17\xe3\xc5\x91\x29\xcc\xce\xc0\x71\x2d\xbd\x6b\x18\x79"
+  "\x8f\x90\xc1\x27\x79\x5d\xe8\x4b\x68\x2e\x95\xce\xbe\x2c\xb0\x30"
+  "\x9f\xd7\x3e\x72\xa2\x0b\x6e\x6e\x95\xe7\x6c\x3c\x4e\xff\x4c\xf2"
+  "\x2f\xba\x6d\x17\xdf\x83\xdc\xcb\xff\xfa\xac\x96\x04\xfa\x46\x26"
+  "\xf9\xa7\xb3\xed\xeb\x85\xfe\x7d\xc4\x97\xf6\xd0\xb7\x63\x7c\x81"
+  "\x87\x75\xb0\xd2\xb3\x6d\x34\xce\xa0\xfd\xbc\x18\xb6\x18\x71\xcd"
+  "\x1c\xf9\x54\xa6\xeb\x17\x3b\xae\xed\x86\x63\x38\x1e\xa4\x3d\xf3"
+  "\x62\xfe\xe6\xfa\xd9\x07\x0a\x41\x9e\x13\x1a\x79\xd0\x05\x63\x73"
+  "\x95\x72\x51\x5f\x03\x65\x6b\xa2\xbe\x07\xf5\x39\x68\x7e\xbe\xa0"
+  "\x88\xf9\xa8\xef\x81\xb4\x3e\xa5\x0e\x54\x3f\x51\xaf\xeb\x63\xd4"
+  "\xf5\xc2\x32\xb8\x71\x6c\xcd\x65\x50\xb0\x1a\x4c\xfc\x2c\xbe\x00"
+  "\xcd\xef\xcf\xe4\x75\xa1\x3a\xf3\xba\x70\x3f\x8b\xed\x84\x7f\x12"
+  "\x8e\xa5\x78\x78\x09\xf2\xca\x70\xc1\x2d\x6d\x02\x4f\x23\xc3\x7e"
+  "\xbf\x06\xb1\x99\x54\x7c\x0e\xae\x2d\x0e\xb2\xa3\xc8\xf3\xaf\x28"
+  "\xa7\x08\xfa\x0d\x52\x7f\xdb\x47\xd8\x75\xfb\xa9\x5d\x76\x16\x9d"
+  "\x41\xdf\xcd\x69\x2f\x47\xda\x76\xa4\xf9\x48\xa6\xfd\x48\xbc\x9b"
+  "\xe1\xbf\x83\xe9\x17\xdb\xb2\xb1\x58\x8e\x4e\x37\x6f\xf3\xcf\xd6"
+  "\x29\xcf\x0c\x9f\xf1\xb7\x9e\x6d\x72\xeb\x8f\xc7\xb0\x0f\x44\x6d"
+  "\x5a\xe0\x2c\xeb\xc4\x7c\xae\x24\x1c\x15\xaf\x86\xab\x10\x93\x5f"
+  "\xae\x5f\x07\x57\x10\xc6\x58\xd4\xd7\x56\x21\xf7\x51\x93\x99\x1d"
+  "\xfb\xa0\xe8\x51\xf3\x56\xc2\x8f\xd0\x86\x2c\xc7\x61\xd4\x9c\x45"
+  "\x45\x56\x2c\x2b\xc0\xd6\x93\x40\xfd\x94\x2f\x90\x3e\xc1\xe9\xff"
+  "\x2b\x7d\x63\x13\xb1\x38\x2a\x57\xc1\x22\xde\xdb\xce\xe7\x2b\x50"
+  "\xae\xfb\xc4\xbc\xc2\xa8\xbf\xd2\x5c\xfc\x51\x18\xd5\x4a\xf5\xc5"
+  "\xcb\x80\x61\x7f\x64\x67\x59\x02\x13\xed\x5a\x9d\x0b\x46\xf9\xf1"
+  "\x77\x1f\xbf\xd0\x97\xc8\xcf\x75\x48\xb7\x8f\x9d\x0d\x10\x0d\xfa"
+  "\x8c\x51\x4d\xcc\x6e\x20\x3b\xa9\xc6\xbc\x3d\x2e\xb8\xcf\x21\x74"
+  "\x33\xca\x41\xbc\xc2\x94\xa1\x8e\xf1\xfd\xec\xa7\xb1\xbe\xa3\x9f"
+  "\xb4\xae\x37\x60\x39\x46\x4f\xe0\x76\x81\xbc\x6a\x25\xe1\xb3\x83"
+  "\x58\xd6\x1a\x7b\x30\x07\xfd\x73\x4e\xb0\xac\x4b\xdc\xcb\x71\x4c"
+  "\x6e\x4b\xf5\xf9\x9f\x6d\xe7\xe7\x20\xc3\xe8\x06\xc1\xe7\x6c\x9b"
+  "\xe3\xea\xe3\xf4\xcc\xcf\x15\xf3\x98\x3c\xfb\x9c\x55\x29\xe2\x0c"
+  "\x66\xa4\x11\xe3\xfc\xd1\xbf\xef\xc2\x3c\xbc\xf6\xd1\x0d\x2e\x18"
+  "\xb7\x47\xbc\x97\xf0\xe8\xf2\xa7\xf3\x16\xc8\x76\xc8\xe6\x84\x4d"
+  "\xdf\xb8\xb9\xb9\x8e\xdb\x5f\x05\x62\x7e\x9f\xec\x7f\x69\x0e\x26"
+  "\xe6\x28\xdc\x58\xde\x6c\xe1\xf8\x96\x98\x74\x83\x45\x73\x46\x2b"
+  "\xc6\xf5\xbf\x6e\x98\x8d\x57\x26\x5e\x39\xf2\x33\x52\xdf\x50\x8a"
+  "\x57\x1b\x3e\x17\x71\xd9\xed\xca\x36\xb8\x30\xae\x0b\xfb\xee\xf4"
+  "\xec\x82\x1b\xe6\xb3\x5d\xa3\x24\xe5\xbe\x76\x27\xcd\x23\xdc\x80"
+  "\xfa\x1a\x6d\x12\xba\xb8\x91\x9f\x3f\x8f\x65\x23\xb9\xb3\xe2\x2a"
+  "\xe6\x6b\x5c\xef\xc1\x72\xdf\xb0\xaf\xb1\xca\x03\xd6\x1b\xa8\xfe"
+  "\x37\xec\xa7\x3a\x79\x50\xfe\xf4\x5b\x50\xc5\xdc\x07\xaa\xfd\x40"
+  "\xef\xb0\x90\x17\xda\xff\xff\x28\x17\x73\x12\x5e\x33\xf1\x93\x31"
+  "\xc1\x94\xfa\x0b\x39\x7b\xf6\x59\x57\x1a\xe8\xf9\xaa\x1a\x31\xef"
+  "\x52\xde\x37\x1f\x7c\xe3\x50\xb4\xf3\x69\x74\x86\xf3\x49\xb8\xf1"
+  "\x11\x86\xb2\x3e\x90\xc3\xcf\x82\x74\xd3\xfc\x4b\x0d\x9f\xd7\xb8"
+  "\x11\xfd\xdf\xe8\x1c\xf9\xdc\x1b\x37\xf7\x35\xc8\x73\x0b\xc6\x61"
+  "\x7b\xd4\xd9\x9c\xe3\x83\x00\xd5\x19\xd3\xbe\x77\xd6\x67\x8c\x2b"
+  "\x04\xc3\xfa\x3c\xf4\x3b\x58\x0e\x86\xba\x12\xbe\xec\x86\x8e\x75"
+  "\x27\x98\x4f\xa9\x33\xbd\xeb\x44\xbe\xe5\x2e\xa8\xa8\x0a\x6b\x13"
+  "\xbd\xf5\x48\x7c\xe3\xc0\x28\xa1\xc7\x20\xca\x4a\xab\xc7\xc4\x3d"
+  "\x42\x87\x37\x1e\xd1\xea\x30\x71\x0f\x5e\x98\x2a\x31\x19\xaf\xd9"
+  "\xf2\xb3\xfa\x32\xab\xee\x51\xaf\x89\x95\x5e\x7b\x62\x02\xda\xc7"
+  "\x46\xa1\x9b\x44\x3e\xff\xc3\x08\x37\xdf\x60\xdb\xd3\x93\x01\xf4"
+  "\x9e\x93\xc2\x09\xe3\x14\x1e\xc4\xfe\x0d\x3e\x27\x61\xbc\x99\xec"
+  "\x97\xce\xd5\x54\xc7\xf7\x9e\x9f\x04\x89\xfc\xbc\xc1\xb8\x0d\xa5"
+  "\xa5\x84\x5d\xa4\x99\x18\xe7\x2f\x2d\xc5\xfc\xca\x15\xb9\x62\x58"
+  "\x21\xc5\x13\x4e\x31\xbc\x1e\xe5\xc2\x7d\x85\x07\xc7\x82\xfa\x7d"
+  "\x8f\xc4\xa6\xde\x3e\x9a\xe9\x53\x33\xe9\xb2\x13\x6e\x3a\x84\x7e"
+  "\x0c\xfd\x77\xd7\x1e\xd1\xfe\xdc\xf4\x11\x3d\xa3\xff\xfc\x12\xef"
+  "\x5b\x9b\xd1\x4f\x75\x97\x75\x98\x7a\x24\x18\xdc\x2d\x41\x8a\x7f"
+  "\xcb\xc8\x22\x7f\xb4\x2b\xde\xd9\xb1\x1f\x5a\xfc\xbf\x05\xeb\xb3"
+  "\x9c\xc7\x9f\xe8\x7c\xd7\xe2\xd5\x2c\xf0\x4e\xf7\x1e\xa3\xd3\x7f"
+  "\xca\xc1\xcf\x53\x17\xfb\xe5\x0d\x3f\x3d\x2a\xbe\xf5\x73\x4c\x7e"
+  "\x66\x31\x23\x33\xb6\x3c\xc3\xfc\x5b\x8e\xd1\x99\x2f\x96\xe8\xcd"
+  "\xdd\x30\xe6\x95\x35\x90\x54\xdd\x0d\xa3\x6a\xba\x21\x91\xfd\x8d"
+  "\xbe\x85\x13\xcc\x58\x78\xc6\x4c\xdf\x19\xc9\x18\x92\x07\xa6\x9a"
+  "\x35\xd8\x9f\xf3\x83\x21\xb0\x19\xfb\x73\xf4\x4d\xa0\x53\x89\xe4"
+  "\x2f\x7b\xfb\x73\x3d\xbc\xaf\xfc\x75\x39\x3f\x07\x7c\xd3\xd7\xe5"
+  "\xb1\x39\x60\x88\xc9\x02\x33\x96\xaf\xf8\x24\xdc\x14\x15\xd3\x8e"
+  "\x7d\x49\xac\xb3\x4b\xae\x2f\xfe\x26\xc4\xe5\xc0\x60\x5e\x57\xf4"
+  "\xe1\x6c\x53\xd7\x9e\xb0\x6d\xb3\x44\x98\xf2\x90\x2d\x61\x1d\x6e"
+  "\x1e\x41\xef\x5a\xf7\x5f\xed\x33\x16\x54\x33\x1f\x85\x17\x8e\x60"
+  "\x3e\x0c\x37\x51\xde\xfb\x30\xdc\x6b\xbf\x39\xc9\x25\xfd\xef\xf6"
+  "\x70\x18\xc5\x71\x93\xec\x6b\x6e\xfe\x0d\x93\x4a\x10\xa3\x9f\xa6"
+  "\xaf\xf3\x63\x7f\xfc\x24\xd9\xf1\xcd\xfb\xd2\x72\x99\xdf\xba\x9c"
+  "\xde\x7b\xdf\x5c\x47\xef\xe4\xe9\x5d\xdc\xaf\xb1\xaf\x73\xa1\xf7"
+  "\xf0\xd4\x86\xd0\xf8\x21\x2e\x17\x79\x96\x7d\x9a\xce\x70\xdc\x7e"
+  "\xb1\xfd\x7a\x5a\x0b\xb2\x9d\xaf\x3b\xb9\xb9\xd3\x05\x8f\xa6\xc8"
+  "\xe7\xb8\x76\x0a\x7f\x7a\xcb\x41\x0f\xca\x40\xeb\x03\x6e\xa9\xa3"
+  "\xf3\x48\xba\x4a\x3b\x2a\x1d\xd7\x92\xef\xbf\x65\xa7\xe8\x0b\x75"
+  "\x54\x88\xb6\xe0\x96\xd5\x62\x4e\xff\x96\x64\x17\x4c\xe1\x98\xcb"
+  "\x1b\x49\x98\xb8\xa5\x90\x45\x77\x6c\x27\xba\x71\x25\x50\xb2\xc2"
+  "\x0f\xd8\x17\xe8\xa8\x60\xdc\x56\x4e\x02\xfb\xf9\x73\x5e\x5a\x4b"
+  "\xe1\xb9\x72\x81\x17\xfb\x06\x07\x31\xae\x92\xf2\x70\x23\x0d\xca"
+  "\x3d\x4a\xbc\xb3\xbf\xa5\xc2\x05\x77\xca\xfe\xf0\x96\x6c\x31\xd7"
+  "\x7c\x4b\x76\x17\xa6\xc5\xbe\xe2\xe5\x18\x8f\xf6\x32\x2f\x5e\x7e"
+  "\xb7\xcb\xd7\xdc\x60\x58\xa3\x0b\xe6\xf3\x79\xd6\xc2\x11\x60\x29"
+  "\xb4\xb2\x8e\xb0\x7d\x3d\x4d\x3d\xc7\xce\xe2\xeb\x62\x24\xb8\xd2"
+  "\x6b\x1f\x63\x52\xf8\x62\x7b\xfb\x66\x97\xf4\xc8\x23\x18\x96\xa0"
+  "\xf0\x45\x9a\x2b\xf0\x79\x4c\x2f\x8d\x48\x93\xac\x4a\xf3\x48\x97"
+  "\x74\xf3\x9b\x18\x96\x1e\x92\x26\x2b\x24\x4d\x9e\x2a\x4d\x89\x9c"
+  "\xcf\xc6\x90\x34\x95\x21\x69\xea\x75\xca\xd6\x10\x92\xa6\x29\x24"
+  "\x4d\x9b\x4e\xd9\x3a\x43\xd2\xf8\xb5\x69\xc6\xc6\xa8\x64\x4b\x6b"
+  "\x54\x92\x30\xcc\xaa\x4d\x33\x36\x29\x24\x4d\x8a\xf2\x8c\x7d\xcf"
+  "\x2c\xd1\x37\x40\x3c\xa1\x4e\x51\xaf\xe8\x43\xc7\x62\xfd\xa7\x86"
+  "\xed\xc3\x13\x36\x11\x33\xe5\xc5\xbb\xc5\x79\xf8\xe4\x57\x69\xfe"
+  "\x9c\xfc\x39\xf6\x8b\x3b\x09\x13\xd4\xef\xa4\xbc\x8e\xc1\xb8\xcd"
+  "\x84\x21\xe4\xb9\xbf\xbf\x3c\xc6\x36\x85\x94\xb3\x2d\xa4\x9c\x1d"
+  "\xfd\xe5\x31\xd6\xaf\x4d\x33\x2e\x46\x9b\x66\x5c\x82\x2a\x4d\x9d"
+  "\xc8\x67\x5c\x52\x48\x9a\x94\x90\x34\xe9\xfd\xf1\x39\x2e\x3b\x24"
+  "\x4d\x61\x48\x9a\x8d\x7d\x32\x1c\xc7\xbf\xe9\x42\xf6\x80\xe1\x38"
+  "\xfe\xb9\xeb\x7c\xeb\xc4\xcc\x0a\x9e\x95\xf5\x62\x02\xd7\xe3\x47"
+  "\x54\x8a\x75\x53\xfc\x2c\xa2\x76\x18\x2f\xce\xa0\xc5\xf2\xbc\xd6"
+  "\xed\x8b\xa4\x77\x4a\x28\xdb\x8e\x03\x36\x1f\xb6\xb9\xe3\xb1\x8d"
+  "\x9a\xd4\xbb\xa6\x82\xd6\xa1\xf0\xb3\xeb\xf8\x78\x64\x9c\x4b\xd8"
+  "\xdf\xf8\x89\xf2\x3b\x1c\xaa\x0f\x8e\x33\xc6\x4f\xfc\x96\xe5\xfa"
+  "\x88\xca\x45\x67\x39\x21\x0f\x5b\xef\x58\xa3\xb7\xac\x94\xe7\xf8"
+  "\x2f\x95\xb2\xd6\x8a\xb5\x30\x74\x6e\x98\x9b\xce\xd5\xc2\x34\x7b"
+  "\x55\xe3\x13\x2a\xab\x67\xff\x1a\x9f\x51\x5b\xe6\xf1\xe5\x72\x99"
+  "\x5d\xc2\x47\x8d\x77\x29\xfe\x24\x2c\xfe\x4a\xcf\x36\xb5\xa0\xd4"
+  "\xe9\xbd\x7f\x73\x35\xf6\x37\x71\x8c\x45\xe5\x3e\x0a\x49\x89\xbc"
+  "\xff\xbb\xbc\x1b\xe8\xde\x59\x34\x85\xaf\x0b\x10\x75\x49\xca\xa2"
+  "\xef\x27\x50\xdf\xa7\x31\xef\x34\x74\xf1\x31\x1a\xf9\xc6\xa4\xcd"
+  "\x07\x8a\xdc\x58\xd6\xa4\x0c\x65\xdd\x8c\x0b\x92\x44\xbf\xae\xf4"
+  "\xac\x83\xd6\x2c\xd0\x7b\xbc\x03\x9e\xc9\x44\x53\x84\xe5\x4c\x51"
+  "\x64\x40\xdf\x62\x40\xda\x89\xe1\xc6\x4a\x6a\xb9\x8a\x32\xdc\x7a"
+  "\x4e\xe0\x27\xa9\x51\x6b\x0f\x91\x88\xd3\xa4\x36\x2d\xe6\x92\x3a"
+  "\xb4\x98\x4b\xf2\x69\xed\x41\x42\x7b\x98\x10\xa3\x4d\x33\x21\x41"
+  "\x9b\x66\xc2\x18\x55\x9a\x0a\x91\xcf\x84\x94\x90\x34\xe9\x21\x69"
+  "\xd4\xfe\x0f\xeb\x3c\x21\xaf\x77\xdc\xc9\xfd\xfd\x84\x12\xd5\xb3"
+  "\x54\xc9\xdb\xa9\x09\x95\x4a\x18\xcd\xdd\x51\x1f\x95\x70\x23\xf3"
+  "\xdb\x17\xe2\xa3\x88\xbe\x31\xa4\x0c\x87\x42\xca\xd0\xae\x3c\x6f"
+  "\x15\xe3\xe6\xff\x44\xd9\xdd\x24\xe3\xcc\x13\xb7\x01\x1e\x8a\xf3"
+  "\x3f\xfc\x38\xf5\xcd\xa8\x7d\xe2\x6b\xb7\xd6\x61\x9f\xf2\x0c\x98"
+  "\x69\xcd\xdc\xb1\x42\x88\xa0\xf3\xdd\x5c\x70\x5b\x26\x8e\xe7\xe8"
+  "\x8c\xc7\x4e\xec\x4f\xa5\x1d\x83\x09\x94\x7f\x15\xe6\x81\xb2\xbb"
+  "\x35\x55\x5b\x86\x5b\x33\xb4\x65\xb8\x35\x47\xf5\x6c\xc6\x67\x9b"
+  "\xaa\xde\xe6\x08\x0b\x5f\xa3\x89\x7d\xeb\x5b\x2b\x94\x70\x9a\x03"
+  "\xc0\x3a\x76\x14\xf3\x7e\x40\x0a\xad\x97\x1b\x76\x14\x6e\x5d\x47"
+  "\xf3\x05\x32\xcf\x77\xd5\xb2\x15\xb2\xb8\xb5\x35\xa4\x1c\xae\x90"
+  "\x72\xb8\xfb\x7c\xcd\x04\x8f\xb0\x91\xdb\x8c\x2e\xb8\x3b\x89\xc2"
+  "\x50\x16\xd6\x38\xbf\xf5\x72\xc7\x48\xea\xa7\xde\xf6\x90\x07\xeb"
+  "\xcb\x7e\x22\x0d\x93\x9f\x1f\x61\x23\xa9\xdf\xfd\x75\x29\xfa\x67"
+  "\x5a\x13\x79\x1d\x86\x65\x0a\xbd\xde\x86\xf5\xbf\x2b\x55\xf0\xbd"
+  "\x8d\xbf\x83\x25\x5a\xbc\x4f\x64\x51\x67\x75\xbf\x27\x44\x78\xee"
+  "\x8a\x3e\xdb\x2a\xaf\xd7\xb4\x22\x8f\x72\xc5\x1e\x82\x65\x67\x5b"
+  "\x83\x9b\x4e\xe7\x60\x18\x8e\x95\x92\xaa\xc4\x98\xe6\x9b\xfd\x88"
+  "\xfd\x2a\xd4\x1f\x8e\x81\x27\xca\x63\x99\xb3\xed\xb4\x66\x0e\xfd"
+  "\x12\x9d\x21\x19\x23\xd6\x4b\xdc\x76\x48\x65\x57\x1e\xeb\x9a\x69"
+  "\xec\x28\x4c\xdc\x49\x7d\x3b\xf2\x1b\xb4\xf6\xee\x80\xdf\x0d\x34"
+  "\xcf\xe2\xf4\x1f\xe7\x7d\x72\x8c\xaf\x12\x69\x27\x9a\x55\x69\xdd"
+  "\xf2\x3c\x48\x07\xc5\x8d\xf7\x83\xf1\x80\xc7\x4d\x67\xe5\xc7\x8b"
+  "\x7e\xfc\xc4\x9d\x07\xd0\x5f\x60\x9a\x19\x4a\x1a\x9a\x33\xa1\x34"
+  "\x38\xe6\x31\x8e\x2b\xa2\xef\x69\x1e\xe5\xbc\xe5\x77\xd2\x7c\x7c"
+  "\xe4\x2c\xea\x00\xa7\xa7\x8d\xe6\x34\x8d\x62\xed\xd2\xc4\xaa\x08"
+  "\x1f\x98\xba\x36\x9d\x75\xb8\xf0\x3e\xb0\xe9\x6c\x13\x96\x0d\xf5"
+  "\x76\xdb\xbb\xe4\x03\xd5\xb2\x9b\x39\x33\xfd\xe1\xb4\x39\x63\x1f"
+  "\x7b\x78\xd6\xfc\x99\x53\xac\xf3\x97\x2e\x5b\x92\x3d\x76\xc5\x0b"
+  "\x85\xd6\x55\xf9\x4b\x0b\x97\x2e\xff\x31\x3f\xde\xd3\xba\xb8\x50"
+  "\xfc\x26\xe6\x2e\x2e\x28\x9c\x4a\xb7\x63\xac\x79\xf9\x4b\x56\xf2"
+  "\xdb\x9b\xa2\x41\xcb\x64\x69\xe1\x92\x7c\xeb\xe8\xec\x31\xd6\xfb"
+  "\x16\x2f\xcd\x7d\x21\x7f\x89\x2e\xaf\x29\xd6\xfc\x25\xf9\x4b\x16"
+  "\x67\x5b\xa7\x5a\x93\x88\xb3\x9a\x9d\x4a\x9f\x49\x8a\x7f\x2a\xc0"
+  "\xf6\x1c\xfb\xd0\x1d\xe4\xa7\xa8\x5d\x3f\x06\x77\xac\xa3\x3e\x1c"
+  "\x3f\x8f\x13\x71\x88\x6d\x82\xcb\x6b\x9f\x54\xd4\xbf\x1d\x9f\x54"
+  "\xa1\xc5\xef\xa4\x3a\x2d\x7e\x27\xed\xeb\xdf\x8e\x4f\x0a\xb1\xff"
+  "\x49\x21\xf6\x3f\xa9\xbd\x7f\x3b\x3e\xc9\xa7\x4d\x73\xbb\x49\x9b"
+  "\xe6\x76\x4b\xaf\x9f\xc1\xb2\xbe\xc8\xfd\xd2\xed\x63\x42\xd2\x24"
+  "\x87\xa4\x99\x1d\xf2\x9c\xa9\x7a\xc6\xbe\xeb\xed\xb9\xea\xbe\x01"
+  "\x3e\x17\x29\xb6\xde\xe7\xdf\x6e\xaf\x50\x68\xa8\xed\xa9\xa5\xef"
+  "\xfe\x08\xda\x3d\x2a\xda\x0e\x99\xb6\xd7\xfe\xc9\x27\xd1\x9a\x45"
+  "\xd1\x3f\xbf\x63\xac\xec\xdb\xe8\x3b\x40\x4a\x1b\xda\x8e\xba\xb8"
+  "\xee\x24\xdc\xbe\xb3\x56\xd0\xba\x69\x1d\x2b\xfb\xf9\x02\x6f\xed"
+  "\x30\x30\x51\x5a\x3a\x8f\x92\xd9\x27\xd6\xd3\x59\x89\x18\x16\x83"
+  "\x17\xfa\xa9\x3b\xac\x2e\xe9\xd0\x7e\xca\x83\xd6\x34\xb8\xe0\x0e"
+  "\x8e\x65\x4a\xb7\x91\xaf\xbd\xe3\xf9\xed\xa4\xef\x19\xd1\x19\xaf"
+  "\xe4\x3f\x29\x5f\x3a\x27\x95\xf2\x46\x1e\x46\x26\x4d\xfc\x4a\x3e"
+  "\xef\xd2\x8c\x57\x3c\xf2\x2c\x54\x78\x22\x3f\x2b\x88\x73\x75\xf9"
+  "\x3a\x75\xd1\xef\xb9\xa3\x52\xe9\x5f\xd0\x58\x41\xcf\x77\xe8\xaf"
+  "\x49\x86\xb8\xad\xf6\x60\x9b\x63\x7d\x3b\x95\xa9\x91\xfa\xa1\x4e"
+  "\x8b\x1f\x5a\xaa\xfd\x38\x7e\x05\x33\x1f\x4f\xd9\x4e\x80\xb3\xce"
+  "\x0f\x34\x3f\xbc\xc8\x06\x25\xb5\x52\xb0\x8d\xf5\xa6\xa3\x31\xda"
+  "\x1d\x7c\xcd\xff\x46\x0a\xc7\xf4\x38\x96\x70\xd3\xda\xe5\x70\xdf"
+  "\xda\x22\x3a\xc7\x48\x1a\xef\x4d\x9e\x28\xf7\x7d\x4b\x6b\x91\x97"
+  "\xee\xba\x5a\x09\x9c\x5e\xfb\x64\x6c\xff\x16\xb5\x29\x3e\xfb\x40"
+  "\x15\xf7\x7d\x12\x86\x97\xa2\x2c\x1a\xc2\xf5\x53\x64\xff\x9e\x47"
+  "\x6b\xbd\x90\x76\xff\xf9\x68\xa9\xdc\x07\xb0\xde\x68\x8b\x55\xaf"
+  "\xad\x4f\x8a\x94\xfd\xab\x09\xd3\x75\x2a\xe9\x2e\xa6\x7e\xf2\x1e"
+  "\x02\x37\xda\xaa\x47\x8c\x15\xa7\x2c\xde\xce\xd7\xea\xde\x89\xfd"
+  "\xbf\xc9\x8a\x1d\x5c\x86\xcf\xe8\xff\x26\xf3\xbe\x0e\xad\xab\xa1"
+  "\x31\x75\x41\x1e\xf6\xd9\x2c\x1e\xf4\x8d\x77\x66\x29\x71\x7c\x9e"
+  "\x88\xe2\x8a\x98\xef\x80\xa5\x9d\xe2\x8a\x7a\xe3\x28\x1d\x95\xdb"
+  "\xe6\xa7\xf0\x4a\x25\x5c\xb4\x2d\x77\xd6\x87\x3c\xef\x57\x9e\xf1"
+  "\x1e\x7d\xe6\xe4\xde\x75\xfa\xe8\x73\x69\x8d\x93\xe1\x28\x4c\x19"
+  "\x51\xc3\xed\xe6\x4e\x97\x12\xcf\xe7\xd4\x5e\xa5\x77\x63\x1e\x08"
+  "\x46\x77\x54\xf1\x3e\x17\xa6\xa1\xef\x63\xe1\x18\xc3\xc0\x7a\xf8"
+  "\x7a\xab\x4e\xe2\x43\x36\xc3\xbf\x51\x83\xcf\x47\xe1\x4e\x3a\x5f"
+  "\xda\x4d\x18\x59\xe5\x87\x84\xbc\xbb\x69\xfe\x79\x0a\xc7\x2d\x85"
+  "\x11\x5f\xe2\x47\x6d\x22\xf1\x26\x7e\xf4\x1d\x2f\xd6\x95\x83\x65"
+  "\x9d\x42\xf5\xaf\x0c\xa7\x2b\x8c\x2f\x51\xc9\x32\x12\x9f\x2b\xb4"
+  "\x75\x9d\x52\x17\xf2\xbc\x4f\x79\xa6\xb9\x5e\x81\xbd\x29\xf5\x72"
+  "\xdc\xc1\xf3\xe5\x45\xe3\x5f\xa4\x71\x6b\xf3\xbb\x0b\xb4\xfc\xef"
+  "\x32\x87\x3c\x5b\x95\xe7\x4a\xfe\x8e\xe1\xae\x24\x25\x0f\xae\x33"
+  "\xc4\x58\xfd\x7a\x77\xe4\xf9\xce\x6f\xc5\x34\xd9\xaa\x3c\x07\xe1"
+  "\x73\x61\x9f\xfe\xee\x2a\x51\xf8\xe1\x7d\xb9\x8a\x0e\xfb\x25\x77"
+  "\x55\x2b\x74\xe2\xfd\xc6\x5d\x7b\x55\xe9\x1a\x2e\x50\xd7\x10\xec"
+  "\x4e\x8d\x14\xd8\xbd\xcb\xad\x2d\x4b\x32\xf4\xf1\x4c\x8e\xe9\x2b"
+  "\x4b\xb2\x45\x45\x87\xf6\x99\x9c\x18\x8a\xd5\x02\x1b\x61\x9c\xf0"
+  "\x9a\x3c\x43\x27\xce\x27\xc7\x65\xe9\x63\x3c\xd9\xa6\x0a\x97\xc7"
+  "\x47\xc9\x9f\xc9\xfd\x04\xf2\xcf\x1e\xfa\x46\x99\x7c\x4e\x3a\xc7"
+  "\x24\x9d\x9f\x2c\x7f\x37\x09\x71\x9d\xdc\x10\xca\x97\xbe\x75\xd3"
+  "\xcb\xa3\x8f\x67\xa9\xe8\xe3\x25\x77\xa8\xea\xe6\x71\xc1\x14\xe5"
+  "\x3d\x91\xf8\xfe\x21\xdc\xd5\x1e\x6e\xdc\xe1\xb5\x4f\x1d\xa5\x95"
+  "\xd9\xd4\x89\x7d\x32\x9b\x9a\xd2\xc7\x77\xea\x6c\x15\xdd\xff\x8f"
+  "\xcf\x99\x2a\xba\x9c\x0b\x61\x53\x60\x65\x6a\x45\x48\x5e\x75\x2a"
+  "\x1e\x7b\x55\x79\x35\xa8\xe8\xda\xf0\xb9\x29\xbc\x7e\xa6\xb6\x87"
+  "\xd7\xcf\xdd\xa0\xaf\x9f\xbb\x2d\x7d\xf9\xde\x3d\xea\xc2\x76\x75"
+  "\x77\xaa\xaa\x3c\xb5\xf8\x9c\xa1\xb5\xa3\xbb\x73\x42\x9e\x7b\xf5"
+  "\xcf\xd0\x77\xd4\xaf\x49\x89\xa4\xf0\xc2\x11\x60\x16\x76\x76\x77"
+  "\x95\x3a\xfe\x9d\x6e\x11\x4f\x65\xe4\xef\xe0\xe8\xfd\xa6\xa0\x73"
+  "\x84\xd2\x11\x8d\x2a\xde\xa5\x94\x7d\x63\x98\x33\xbd\x95\xf6\xcf"
+  "\x19\xa4\xf6\xef\x6e\xbf\x78\x6f\xf3\xd5\x41\x66\x7f\x3f\x23\x5c"
+  "\x5b\xe6\xb5\x4f\x9b\x8c\x63\x06\xb7\x90\xcf\x34\xc4\xff\xa3\xbc"
+  "\x6f\xc2\x4a\xbf\xa2\x6f\x13\x75\x1f\x83\x69\x9f\xe1\x6f\x0f\xfe"
+  "\xfe\x51\xdb\xbe\x4e\xcb\x64\x76\xc3\xbc\x5a\x7b\x68\xbb\x3b\xad"
+  "\x10\xc7\x1e\xdd\x71\xfe\x92\x0c\x9d\xb8\x0a\x66\x8f\x78\x58\x27"
+  "\x9c\xce\xcc\xef\x76\xc1\xb4\x23\x54\x5e\x55\xb8\x83\xd9\x87\xcc"
+  "\x27\x7a\x17\xe5\x87\x69\xc2\xe9\x4d\xd9\xff\x23\xb0\x97\x12\x13"
+  "\x52\x8f\x73\xc7\x20\x65\x93\xa8\x47\xca\x5f\xb5\x79\xa7\x8c\xd2"
+  "\xaf\x47\x4a\x32\xd6\xe3\x9c\x7e\x3d\x52\xf8\xb7\xa9\x99\x84\x75"
+  "\xe9\xd7\xef\x48\x29\xc4\xba\x9c\xe3\x72\xd7\x86\x97\x2b\xe3\xd4"
+  "\xe2\x73\x38\xfe\x97\x80\xa7\x9d\x57\xd4\xa7\x37\x99\x6e\x7f\x5c"
+  "\x15\xa4\xeb\xe4\x89\x7a\x1c\x3c\xcf\x05\xf7\x18\x95\xf6\x4a\x0e"
+  "\x6f\x17\x65\x41\x39\x49\x24\x27\xac\x0f\xa6\x0b\xa7\x6f\xc5\x3e"
+  "\xc5\x7b\xa6\x7b\xd0\xfe\xa7\x75\x28\x6d\x3a\xb6\xe7\x6e\x45\x8e"
+  "\x18\x97\x1e\x12\xe7\x53\xc5\xe5\x6a\xe2\xd6\xf5\x86\x6f\x54\xc2"
+  "\x2f\x4e\x4f\xf7\xec\x0f\xd1\x13\xea\xe7\xde\x99\xda\x7a\xdf\xd3"
+  "\x28\xea\x87\x3a\xea\x27\xeb\x7b\x5c\xa8\xa3\x1e\x7d\x1d\xdd\xe3"
+  "\xd7\xc7\xda\xbd\xf1\x9c\xdf\x30\xd0\xe1\x77\x2f\xed\x19\xeb\xe1"
+  "\x18\x94\xf5\xd4\x5f\x3f\xf7\xce\x57\xf4\x73\x71\x75\xbc\xb7\x2a"
+  "\xa4\x8e\x81\x63\x30\xfd\x0a\x51\xd7\xe9\x4b\x42\x78\xef\xd3\xc7"
+  "\xe2\xbd\x4d\x58\xcf\x80\x7e\x3d\xef\x6d\x0f\x8f\xc5\xe9\xf4\x3e"
+  "\x24\xd0\x1f\x8b\xd3\x2d\x22\x0d\xe8\xa5\x99\xc8\xec\x7a\xf9\x4c"
+  "\x9f\x4d\xfd\x22\x17\x4c\xdf\x48\xef\xe9\x54\xe1\xd9\x5a\xfc\x61"
+  "\x1d\x28\x1d\xc9\xcf\x2f\xc6\x31\xa4\x87\x63\x56\x90\x2e\x84\x49"
+  "\xaf\x7d\x7a\x63\x88\xac\x4e\x1d\x83\x19\x33\xbb\x24\xe9\x3e\x21"
+  "\xaf\x99\x51\x21\x65\x72\xe9\xcb\x6b\xba\x0f\xe5\x75\x4a\x5f\x5e"
+  "\x33\xe2\xc3\xcb\x6b\x06\xe9\xff\x54\x7f\x79\xcd\x48\x55\xcb\x8b"
+  "\xbe\xad\x4a\xf5\xbb\xde\x82\xd8\xe8\x59\xc4\x6a\x85\x2f\x37\xc7"
+  "\x21\x56\x44\x9a\x4e\x4a\x53\x14\xe7\x13\x38\xb1\x5e\x0d\xa6\x93"
+  "\x30\x23\x5b\xb1\xff\x21\x55\x30\x98\xf5\x2c\xa0\xb5\xda\xf4\xad"
+  "\x06\xb3\xd3\x76\xca\x41\xdf\x74\xa4\xf9\xc6\x90\x7c\x1d\xfa\xbe"
+  "\x60\x06\xf6\xf9\x23\xb6\xe9\x84\xbb\xc5\x9c\xe9\xcc\x44\xad\x8f"
+  "\x98\x69\xd2\xea\x08\xe5\x26\xf1\x53\xc9\x0d\x17\x73\x9d\x5f\x67"
+  "\x33\x6d\xfd\x75\x76\xdf\x55\xb2\xbe\xce\x69\xcb\x37\xb3\x42\x5f"
+  "\x5f\x33\xf7\x84\xd7\xd7\xcc\xc6\xf0\xfa\x9a\xe9\x22\x7d\xb9\xe0"
+  "\x3e\x8b\xb6\xdd\x98\xe9\xd3\xd6\x17\xf3\xc5\x74\x4c\x1a\x74\x39"
+  "\x3d\x5f\x6c\xbd\x95\x8b\x7c\x1c\xe9\xaa\x16\xfb\x57\x58\xfe\x11"
+  "\x54\xc6\x81\xf2\x08\xcb\x1b\x65\x58\xb1\x26\xec\xf7\x3f\x62\x5a"
+  "\x70\x5c\x49\xeb\xf3\xf8\xf7\x99\xe1\xbe\x13\x41\xc9\x30\x05\xef"
+  "\xa5\x63\x90\xfa\xfb\xa0\x14\x51\x42\x6b\xc9\xf8\xfe\x39\xfe\x7e"
+  "\xe2\x7e\xa3\x5a\x17\xb4\xa6\x8c\xe6\xa2\xb7\x88\x79\xce\x2f\x8e"
+  "\xc1\xfd\x9b\x85\x5e\x52\x77\x6a\xe5\x78\x7f\xa2\xbe\x5e\xee\x4f"
+  "\x41\xbd\x7c\xa1\xaf\x97\xfb\x33\xc3\xeb\xe5\x7e\x1b\xea\xe5\x8b"
+  "\xfe\x76\x74\x7f\x85\x6c\x47\x2f\x52\x1a\xeb\x72\xea\xaf\xa6\xd2"
+  "\x73\x1c\xde\xa3\x8d\xdc\xcf\xbf\x3f\x34\xb6\x53\xb1\x23\x9e\x86"
+  "\xc6\xff\x3c\x7f\x99\xc6\x21\xf3\x50\xf3\xed\x88\xeb\xd4\xb3\x93"
+  "\x54\xbe\x66\x60\x5c\x1e\x98\x50\x86\x19\xbb\x89\x47\x3e\xc0\x49"
+  "\x48\x7d\x84\xe8\x28\x9c\xbe\xa5\xa0\xa2\x4f\x52\xe8\xf8\xbc\xa8"
+  "\xa0\x4d\x64\xde\x1c\xfe\x8d\xa8\x10\xde\x72\xfd\x07\xf3\x76\x84"
+  "\xe8\x89\x2e\x84\xa6\x44\xd8\x63\x6a\xa3\xd6\x1e\x53\xab\xb4\xf8"
+  "\xbc\x9f\xde\x4f\xc4\x05\xd1\xcf\x21\x96\x3b\x03\x76\xc3\x94\x4b"
+  "\x63\x9b\xb3\xe2\x43\x6c\x13\x31\x30\xeb\x3f\x04\x06\x66\xfd\x4c"
+  "\x5b\xd6\x59\x63\xf4\x31\x30\x6b\x46\x78\x0c\xcc\xca\x0a\x8f\x81"
+  "\x59\x45\x84\x01\x17\xcc\xda\xaf\xb5\xcd\x59\x95\xda\xba\x63\xbe"
+  "\xdc\x36\x61\xe8\x40\x6c\x13\xfb\x42\x97\x87\xb3\x43\xb9\xff\x6f"
+  "\xa0\xef\xa1\x0d\x40\x66\xe2\xfb\x3e\xf0\x40\x2a\xbd\x43\x42\x1f"
+  "\x9f\x43\x32\xac\xe1\x63\xb4\x07\x32\xd5\x72\xdc\x22\xc6\x5a\xc5"
+  "\x48\xfb\x25\xad\xd9\x13\xf2\x7c\xf0\x0d\x6d\xfd\x1f\x28\xd2\x97"
+  "\xe7\x03\x95\x28\xcf\x62\x7d\x79\x3e\xb0\x2f\xbc\x3c\x1f\x38\x48"
+  "\x7b\xb4\xfb\xdb\xd4\x03\xed\xf4\xad\x4b\xa5\x6d\x3a\x09\x0f\x4e"
+  "\xbd\xb8\xf6\xe9\xc1\x04\x6d\xfb\xf4\xa0\x71\xe0\xed\xd3\x83\x59"
+  "\xfa\xed\xd3\x83\x36\xfd\xf6\xe9\xc1\x0a\x61\x0f\x0f\x36\x69\xed"
+  "\xe1\xc1\x3d\x5a\x4c\xa0\xec\x2e\x59\xfb\x34\xdb\x12\x62\x03\x5b"
+  "\x8f\xc1\xec\x9d\xd8\xa7\x78\x49\xe8\x6d\xce\x93\xda\x32\xce\x9e"
+  "\xa8\xaf\xb7\xd9\xb3\x51\x6f\x5b\xf5\xf5\x36\x3b\x27\xbc\xde\x66"
+  "\x6f\x44\xbd\x6d\xed\xaf\xb7\xd9\xd5\x03\xef\x53\xcc\x6e\xd5\xea"
+  "\x6c\x76\xc3\xc0\x75\x36\x27\x5e\x5f\x67\x73\xc6\xe8\xeb\x6c\xce"
+  "\x0c\xa1\xb3\x39\x45\x5a\x9d\xcd\xc9\xd4\xea\x6c\xf6\xc4\x4b\xa7"
+  "\xb3\x39\x07\x43\x74\xb6\xe2\x18\xcc\x9d\x83\x3a\x6b\x15\x3a\x4b"
+  "\x1b\x1a\x52\xc6\x0e\x7d\x9d\xcd\xc5\x01\x23\xac\xd0\xd7\xd9\xdc"
+  "\x84\xf0\x3a\x9b\x3b\x19\x75\xb6\xa2\xbf\xce\xe6\xa6\x0f\x5c\x67"
+  "\x73\x37\x6a\x75\x36\x37\x77\xe0\x3a\x9b\xdb\xa4\xaf\xb3\xb9\x2e"
+  "\x7d\x9d\xcd\xf5\x09\x9d\xa5\x25\x69\x75\x96\x66\xd6\xea\x0c\xe5"
+  "\xf6\x1d\x75\x86\xfa\x69\x15\xeb\x75\xd3\x5e\xee\xe2\x73\xda\x69"
+  "\xa5\x2e\x48\x4f\x17\xef\x04\xd2\x39\x76\x64\x1d\xbe\x83\x34\x45"
+  "\xfd\xdb\xee\xb4\x7a\x39\xec\xb1\xfe\x7a\x48\x73\x60\xbb\xda\xd9"
+  "\x58\xc4\xd7\x75\x09\x1d\x92\xcc\x91\x4e\xcc\x91\xa5\xb9\x28\x2d"
+  "\xea\x98\x39\x7d\x7e\xa0\xb6\x18\xe9\x3d\xc4\x87\xce\x13\xd1\xf2"
+  "\x4a\x8f\x19\x48\xbf\x2c\xfc\x1a\xf3\xaf\x5a\x1d\xeb\x6f\x45\x7e"
+  "\x0f\x8d\x10\x58\x4d\x0f\xed\xff\xd6\x62\x5e\x67\x04\x4e\x1f\x0e"
+  "\x99\x33\x49\x0f\xd3\xff\x4d\xa7\xfe\x6f\xad\x3e\x4e\xd3\xcf\xd3"
+  "\xff\x4d\xa7\xfe\x6f\xad\x6a\xbc\x3a\x6c\xa1\xdf\x15\x32\x5e\x7d"
+  "\xc8\x18\xe7\x11\xd8\xe1\xfd\xd8\x4d\x5f\xb5\x7a\xed\x0f\x8d\x09"
+  "\x29\x33\xea\xe6\xa1\x37\xe4\x32\xbf\x1a\x92\x7e\x86\x7e\x99\x1f"
+  "\xca\xc4\x32\xbf\xa3\x5f\xe6\x87\x6c\xe1\xcb\xfc\x50\x25\x96\xf9"
+  "\x9d\xfe\xb6\xf5\xd0\x5e\x19\x07\x3a\xe3\xf2\x87\x9a\xf4\xf5\xff"
+  "\x50\x88\xfe\x21\xa3\xb0\x88\xb9\x79\x7a\x0d\xdd\xc3\x26\x35\x1d"
+  "\xad\xd5\x27\x5a\xc2\x88\x0e\xed\xc4\x50\x9e\x61\xe8\x32\xfb\x61"
+  "\x8f\xf6\x16\xe8\x62\xef\xe1\x52\x61\x8f\x0f\xbb\xb4\xf6\xf8\x70"
+  "\x9d\xd6\x1e\x51\xd6\xda\x74\x0e\x6d\x7c\x7a\xc5\xa5\xf3\xb1\xf3"
+  "\x92\x42\x30\xf0\xfe\x31\x98\xf7\xb6\xc0\xc0\xfc\x48\x6d\x39\xe6"
+  "\xa5\xea\x63\x60\x5e\x16\xd6\xff\x7d\x7d\x0c\xcc\x2b\x0a\x8f\x81"
+  "\x79\x55\x28\xcb\xf7\xd5\xb8\x9d\x57\x94\x32\x38\x84\xe6\x5d\x7d"
+  "\x9f\x37\xef\x90\xfe\xbc\xce\xbc\x4e\x21\xe3\xf9\xa3\xb4\x32\x9e"
+  "\x6f\xd4\xca\x10\xeb\xf2\xdd\x65\xd8\x7b\xae\x97\xd7\x3e\x3f\xd4"
+  "\xfe\x9d\x98\xa7\x6c\xff\x8f\x9c\xd0\x96\x71\xbe\x3c\xfe\xd1\x9b"
+  "\xcb\x9a\xbf\x17\x65\xe9\xd4\x97\xe5\xfc\x26\xfd\x3a\xcf\x77\x61"
+  "\x1b\xe4\x0c\xf6\xb3\xa5\xf9\x3e\x0c\x9f\xc7\xbf\xd1\x78\x0e\xcc"
+  "\x35\x18\x3e\xcf\x0f\x26\xde\x5e\xf5\xb6\x4b\x8f\xd0\xbe\x03\xc6"
+  "\xe7\x98\x11\xbf\x71\x09\x90\x4e\x6d\x10\x95\x6b\x51\x51\xe8\x3b"
+  "\xd1\x47\x94\x6f\xe9\x7a\x68\x5f\x4d\x9c\x0d\xd2\x9d\x1e\x3f\x28"
+  "\x78\x27\xfa\x10\xde\x36\xb2\x0b\xa2\x57\x68\xc5\x5c\x67\x49\x88"
+  "\x6f\x7a\xa4\x4e\x5f\xc7\x8f\x34\x84\xc7\xce\x23\x87\x84\x9e\x1f"
+  "\x35\x69\xf5\xfc\x48\x67\xd0\x3e\x64\x3e\xd5\x15\x31\x30\x20\x3b"
+  "\xa1\x77\xa7\x61\xfd\xfd\x8b\x0b\xda\xf2\xd6\xc3\xb5\xc7\xe1\xd1"
+  "\x3c\x9e\x9f\xc4\x7c\x71\x1b\x0c\xd0\xc8\x7d\xc0\xa3\xe2\xdb\x80"
+  "\x48\xb3\xc8\x0f\x12\x7b\xf1\xb9\x36\x8a\xab\xb5\x33\x1f\xff\x06"
+  "\xa5\x9d\xb5\xd2\x79\x3c\x88\x85\xcb\x8f\xc2\xa3\x9b\x34\xe9\x11"
+  "\x95\x4e\xc1\xa3\x51\xcc\xef\x3f\xea\x50\xe6\xe1\xc3\xcd\xef\x23"
+  "\x4d\xbb\xb2\xee\x57\xbc\x0b\x7b\xb4\x2d\x6c\xbb\x8c\x65\xa2\x3d"
+  "\xe4\x54\xa6\xf3\xfb\x81\xc7\x26\x2b\xf8\x15\xef\xe6\x1e\x4b\xed"
+  "\xdb\xdb\xf2\xd8\x7c\x8c\xf3\x9f\x67\x3e\x57\x65\x07\x8f\x95\xa8"
+  "\xf9\x88\xb3\xed\x1e\xab\x54\xf6\xa7\xe0\x7d\xdd\x05\x78\x29\xe5"
+  "\x69\x0a\x29\x0f\xea\xf3\x41\xbf\xcc\xa3\xfd\x02\x3c\xe2\x9d\xf5"
+  "\x53\x60\x5c\x10\x22\x8e\xc3\x13\x13\x2a\x69\x8d\x4e\x75\x07\xc4"
+  "\xf8\xc1\x28\xc6\x76\x19\x77\xd2\xde\x10\x1a\x1b\x3a\xfd\xd3\x1c"
+  "\xf4\x0e\x8e\xaf\x21\xb0\x4c\x73\x34\xdb\x02\xf2\xd9\x63\x19\xfc"
+  "\x7b\xdb\xcd\x39\xa7\x1c\xd5\x3b\x58\xc7\x6e\x7e\xe6\x54\x86\x66"
+  "\xfc\x57\x4e\xeb\x7f\x68\x1d\xc6\x7a\x98\x86\xf4\x5f\x0a\x5b\x7f"
+  "\x22\xa4\x4f\x9a\x11\x66\xfc\x97\x41\xe3\xbf\x69\xfa\x76\x9e\x71"
+  "\x9e\xf1\x5f\x06\x8d\xff\xa6\xa9\xdb\x4d\xf1\x9e\x27\xa3\x5d\xdd"
+  "\x27\xa5\x73\xa1\xac\xcf\x50\x3f\xf3\xf1\xc7\x6f\xa9\x04\xb3\x9f"
+  "\xde\x69\xa3\x6d\x3a\x3b\x1a\xc9\x5e\xcd\xcd\xee\x06\x3a\x8f\xc1"
+  "\x44\xdf\xce\x16\x6d\x19\xd9\xeb\xe3\x7c\xbe\x30\xce\x2f\x6c\xb1"
+  "\xd8\xc6\xdc\x63\xda\x11\x43\x2b\x72\x14\x5e\xf1\xeb\x72\xc4\xbe"
+  "\x8f\x21\xed\x30\xd8\xd9\xc1\xdb\x45\x03\xf5\x57\x79\xbf\xd5\x7f"
+  "\x06\x88\xef\x81\xa2\x66\x20\xbe\xc1\xde\x76\x92\xf3\xde\x48\x36"
+  "\x4e\x3c\x89\x77\x0b\xd2\x11\x5f\xa2\x53\xea\x21\xf6\xc6\x3c\xbe"
+  "\x57\x5d\x77\x3e\xff\x82\x79\x63\xf8\x57\x34\xaf\xe2\xa4\x74\xc5"
+  "\x0b\xd8\xb8\x76\x7a\x67\x76\xca\xc1\x8a\x9f\x63\xe3\xf2\x69\x4e"
+  "\xec\x89\x3b\x29\xdd\x3b\x9f\xbb\x22\x0b\x47\x80\x49\x84\x3d\xee"
+  "\x69\xb4\xfa\xc0\x05\x4f\x4c\xd6\xfa\x88\x27\x42\xfa\xbf\x19\x7c"
+  "\x9c\x89\xbf\x31\xb4\x3e\x51\x5e\xbf\x4a\xfe\x80\x39\xfd\x5e\x8e"
+  "\x8f\xf3\xad\xa9\xa0\x77\xd2\xb4\x26\x4a\x9c\x7b\xf6\x44\x49\xc8"
+  "\xdc\x9b\x7b\x0b\x5f\x57\xf3\x09\xe6\xbb\x20\x56\x60\x24\x33\x56"
+  "\xab\xd3\x27\xea\x8a\x4f\xd0\xbb\x20\xd1\x1e\x2c\xf4\x87\xfa\xc7"
+  "\x27\x1c\x4a\xdf\x2d\x24\xbc\x4d\x69\x0f\xac\xcb\x89\xef\x82\x90"
+  "\x76\xe6\x09\xde\xff\x0f\xf4\x6b\x17\x16\xd0\x3e\x2a\x0d\x26\x5b"
+  "\x38\x86\x16\x24\x36\x7b\x10\x37\xf9\x84\xff\x05\xaf\x22\xcd\x06"
+  "\xda\x73\x88\xcf\x83\x4f\xc2\x82\x8c\x80\x1d\x4c\xcd\x6e\xbe\xa7"
+  "\xca\x8c\x18\xe1\xb8\xa5\x76\x63\xbc\x58\x8f\xe4\x09\xc9\xa3\x50"
+  "\x91\x39\xd1\xb4\xe4\x7f\x02\x62\x3d\x05\x61\x61\x41\x2a\xad\xcd"
+  "\x18\xd2\x09\x83\x89\x97\x82\x21\xa7\xbf\x0d\x5a\xfc\xa1\x63\x9e"
+  "\x05\xef\xea\xd7\x7d\x01\xb5\xff\xdb\x5c\x90\x39\x46\xab\xdb\x05"
+  "\xbc\xfd\x57\xde\xeb\xa0\xee\x7d\xda\x74\x99\x31\x5a\xdd\x3f\x41"
+  "\x7b\xb3\xc2\xbe\x27\xeb\x2a\xfd\xea\x10\x8e\x67\x16\x79\xf8\x7a"
+  "\xaf\x4c\xb4\xff\x27\x32\xcf\xe7\x07\x99\xe9\xab\x43\x41\xa4\x95"
+  "\xd7\x05\xa3\xdf\xca\xac\xd0\xcc\x19\x0d\xe7\x73\x46\x8b\x8e\xc1"
+  "\x93\xf2\xbb\x9f\x27\x3f\x0a\x29\xdf\xde\xf0\x7d\x83\x4c\x7a\xff"
+  "\xb3\x48\xdf\x67\x64\xb6\xeb\xf7\x0d\x32\xfd\xb2\x5f\x58\xc4\xa2"
+  "\x42\x71\xf0\xa4\x05\x75\xcc\xd3\x28\x63\x58\x9a\x0b\x0d\x3f\x86"
+  "\x7d\x32\xb5\x77\x0c\x9b\x4f\xfe\xe0\xc9\xa4\xde\x31\xac\x5b\x6f"
+  "\x0c\xeb\xd2\xd1\xe7\x93\xe5\xfa\xfa\x7c\xb2\x5e\x7f\x0c\xfb\xe4"
+  "\xbb\xa2\x9d\x7f\xd2\xad\xd5\xf3\x93\x87\xfa\xde\x09\x67\xee\xbd"
+  "\x74\xfd\xe1\x85\x29\xfd\xfb\xc3\x0b\xdf\x13\xba\x5a\x18\xd0\x96"
+  "\x6d\x61\x86\xbe\x6f\x5f\x98\x17\xbe\x3f\xbc\xb0\x3c\xbc\x6f\x5f"
+  "\xb8\xa7\x7f\x7f\xd8\x3a\x28\x84\xe6\x60\x6f\x5f\x49\xd3\x37\x5b"
+  "\xd8\x2e\xe4\xb4\x88\xfa\x73\x11\x2a\x7a\xbf\x16\xef\x58\x66\xe4"
+  "\x87\xbe\xed\x38\xf9\x34\x05\x33\xe1\x64\x42\x67\x33\x5d\x5f\x09"
+  "\x51\x68\x03\xef\x7b\xed\x8b\x7a\xf1\x4f\xeb\xf8\x28\x1f\xf2\x91"
+  "\x61\xd7\xd3\x49\x4a\xf9\xa8\x1c\x8b\x36\x9e\xef\x7d\x69\x84\x05"
+  "\xd2\xb7\xf7\x93\xc7\x22\xde\xff\x23\x1e\xe7\xd7\xd9\x22\x4f\x88"
+  "\x8d\x79\xc4\x3a\xdc\xac\x3f\x0a\xbd\x65\x85\x8c\x65\xb3\xcc\x7c"
+  "\x4f\x5f\x58\x7f\x9b\x95\xa4\x8f\xd1\xac\xd4\x5e\x7f\x9b\xcf\xf9"
+  "\x6e\x08\x89\xcf\x11\x3a\xc8\x72\x04\xa3\xd4\x73\xdd\x59\x25\x5a"
+  "\x9f\x94\x95\x13\x92\x2e\x64\xfc\x97\x45\x3e\x31\xdc\x1a\x87\x90"
+  "\xf6\x26\xcb\x1d\xbe\xbd\x59\xbc\x4e\xd4\xff\xa9\x90\xf7\xcb\x8b"
+  "\xcd\xe7\x6f\x6f\x16\x87\xa9\xff\xe2\x54\x6d\x7b\xf3\x54\xc8\x3b"
+  "\xfa\xc5\x39\xfa\xed\xcd\xe2\x12\xc5\xcf\x08\xbf\xb1\xf8\xf0\xc5"
+  "\xf9\x9b\xc5\x0d\x5a\x7f\xb3\xb8\xee\x42\xfe\xe6\x40\x3f\x7f\xb3"
+  "\xd8\x1f\x57\xad\x57\x97\xa7\xe2\xf5\xfd\xcd\x53\x63\x84\x0e\x9f"
+  "\xda\xa8\xf5\x37\x4f\xcd\xd0\xea\x70\x71\x88\x0e\x9f\x0a\x79\xff"
+  "\xbd\xd8\xfc\x6d\x7d\x52\x44\x44\x84\x14\x61\x90\x0c\x11\x40\x1f"
+  "\x89\x32\xc0\xe0\x08\x63\x44\x24\x5e\x83\xe4\xdf\xc1\x52\x84\x64"
+  "\xc4\x2b\x52\xfe\x1d\x14\xf2\x3c\x98\xd2\xe2\x65\x94\x7f\x23\x43"
+  "\x9e\x07\x5d\x20\x7e\xb0\x9c\xaf\x92\xbf\x31\xe4\x39\xf2\x02\xf1"
+  "\x83\xbe\x63\x7a\xe8\xf7\xac\xdd\x07\x39\x6b\xf9\xca\xc5\xb9\x4b"
+  "\xb3\xf9\xba\xf6\x25\xd6\xc5\x4f\x3f\xbd\xa4\xa0\xc0\x5a\xb8\xc2"
+  "\x7a\xef\x3d\x0f\xdf\x3a\xc5\x2a\x96\xc7\xe7\x4e\x1d\x9d\x1d\x0d"
+  "\x73\x56\xe5\x53\xc4\x9c\x79\xb3\x32\xac\xe9\xf7\xde\xa3\x8d\x54"
+  "\xd8\xf0\x65\xf0\xe7\xe3\xa2\xb2\xbd\x94\x4d\xc3\x01\xca\x87\x73"
+  "\xbf\xd3\x4e\x7b\xcf\xc5\x78\x22\xe7\xbf\x0e\xd6\xe3\x78\xa2\xbb"
+  "\x98\xd1\xbe\x8a\xa3\x90\xfd\x12\x55\x62\x6c\x5d\x09\xe4\x3d\x43"
+  "\xe7\xa9\x64\xbf\xca\xfe\xe0\x06\xeb\x03\x20\x1d\x85\x65\x5f\x36"
+  "\xe2\x28\x9a\x9e\x9d\xed\x7e\xb0\x16\x53\xdf\x36\x67\x03\xc6\x19"
+  "\xd8\xdd\x41\x0c\xf3\xc8\xfb\xf3\x7f\xfc\x32\x0f\xfb\x43\x89\x42"
+  "\x17\x77\x0c\x96\xcc\x64\x7f\x60\xfc\x99\xce\xad\x11\x74\x4b\xae"
+  "\x0a\xda\x9f\x6e\x23\xbf\x50\xbd\x0d\x8c\x35\xdb\x00\x76\x0e\x03"
+  "\xd3\xce\xe1\x74\xd6\xec\x92\x18\x65\x5d\xf6\x26\x7c\x76\xc1\x32"
+  "\x17\xe5\x4d\xb4\x41\x29\x5b\xe2\xf4\xc3\x34\xf4\xc9\x7d\xeb\xb8"
+  "\x97\xc4\x48\x48\x97\xf6\x57\x88\xf3\x45\xbb\x4c\xce\xa2\x12\x88"
+  "\x0b\xb0\x6f\xc6\xa5\x82\xa1\x05\x2d\x63\xb5\x9f\xf9\x1d\xf9\xc7"
+  "\x29\xff\x4d\x71\xab\xd9\x37\x4e\xec\x37\xce\xe9\x2c\x66\x5b\x4e"
+  "\x80\x11\x6d\xda\xe0\xc8\xa7\xfd\x14\x4b\xf2\x6a\xce\x81\x11\x65"
+  "\x90\x70\x1c\x9e\xa9\x2b\x9a\xc3\x02\xc5\x73\xc0\xf8\xa1\x8d\xf6"
+  "\xbc\x7e\x3d\x72\xcb\x5f\xc0\xf8\x56\x77\x89\xd4\xcd\x2c\x50\x54"
+  "\xc8\x3a\x18\x9d\x41\xed\x61\x3e\x5a\x73\x7b\x30\x2b\x40\x34\xc3"
+  "\xbc\xc5\x16\x68\x29\xf4\xc0\xba\x23\xcc\x57\xfa\x17\x71\x66\x45"
+  "\x73\xa7\x87\xf6\xd0\x9a\xd6\xcd\x81\x88\x63\x19\x20\x35\xe7\x54"
+  "\x81\x33\xd3\x03\x45\x47\x58\xc7\xc1\xac\xbf\x42\x4b\xce\x3e\x58"
+  "\xd4\x06\xd2\xc1\xf6\xcf\x80\x9f\xa3\xbc\x65\x64\xde\xfa\x33\x60"
+  "\x59\xb7\x94\xc2\xce\xc0\x9a\x75\x10\xbb\xe6\x23\x1a\x0b\xb5\x61"
+  "\x3e\x27\xe0\x89\x43\x60\x40\x7e\xd2\xda\xcf\xc0\xb2\xf6\x71\xda"
+  "\x6b\x9e\x02\xd5\xeb\xc1\xc2\x8a\x13\x63\xba\x8b\x13\xcd\xdd\x2c"
+  "\x11\xcb\x91\x18\xdf\x92\x87\xf4\xed\xef\xc1\x90\x36\x88\xff\xc3"
+  "\xf1\x36\xa9\xea\x34\x24\x58\xe7\x92\xfe\x9f\xa9\xae\x3e\x8d\xf4"
+  "\x65\x3e\x6b\x10\xd3\xaa\xd3\xf8\xa3\x7c\x93\x9d\x19\x3e\x08\x22"
+  "\xaf\xaa\x6e\x48\xa8\xee\x06\x4b\x70\x93\xcf\x4a\xb2\xe8\x29\xeb"
+  "\xa0\xf9\x92\xc1\xef\x3c\xd5\x60\x74\x1e\xec\x84\x66\x4f\x37\xb4"
+  "\xc0\x27\xe0\xb4\xfd\xcd\xf1\xd6\x53\x0d\x91\xd8\x8f\x34\x38\xd6"
+  "\xd0\xda\x77\x81\x99\xe2\x66\x3a\x3f\xaf\x04\xb6\xae\x87\x98\xbc"
+  "\x35\x30\xf8\x38\x86\x73\x9f\x53\xfa\x29\x8e\xbd\xfe\xe6\x58\xc3"
+  "\xf7\x81\x2f\x73\xad\x6f\x86\x88\x16\x4f\x15\xed\x37\x96\x02\x43"
+  "\x46\xe6\x39\x3d\xad\xe0\xcc\xfb\xc2\x11\x8c\x19\x99\x51\x1e\x04"
+  "\xd3\xdb\x67\x5b\x25\xa7\xf1\x2c\x38\x33\x3c\xf0\x3e\xe6\xcd\xb6"
+  "\x8c\xa4\xf1\x4f\x4a\x8b\xc7\x47\xe7\xee\x24\xb1\x2e\x4b\xf4\xd6"
+  "\x7c\x18\x53\x73\x1a\x46\xed\x3e\x0d\x89\xcc\x9b\x28\xd1\xde\x6e"
+  "\x3a\x2f\x6d\x37\xfe\xc6\xe0\xd8\x0b\xeb\xcb\xf7\x78\xb3\x58\x79"
+  "\x8f\x77\x4f\x22\xd4\x76\xf7\xed\xf1\xee\xee\xea\xdb\xe3\x8d\x58"
+  "\x32\xd3\x3e\x6f\xb4\x8b\x26\xc2\xf3\xd6\x93\x60\x7c\xf1\x24\xc0"
+  "\xb8\x12\x09\xac\x4f\xd1\x59\x1f\x39\x2f\x38\xb3\x4f\xf0\xfb\xa3"
+  "\x90\x33\x06\x7f\x63\xf0\xc2\xf1\x5b\xce\x08\xaa\x5f\xbb\x8c\x5b"
+  "\x0c\x93\x30\xec\x0a\xfc\x8d\xc0\xdf\xd8\xe2\x6a\xe6\xc6\x3c\xe8"
+  "\xcc\x99\x68\xc2\xaf\xbc\x9f\xdc\xe5\xb5\xe7\x18\x5d\xf0\xf2\xbb"
+  "\x0a\x8e\x85\x3f\x5f\x62\x7e\xff\xd8\x09\x3a\xd7\xdc\xcd\xcb\xd3"
+  "\x93\x63\xa0\x33\xce\xe5\x70\x2a\xc3\x32\xca\x17\xf3\x4f\xc7\xdf"
+  "\x38\xbc\xd0\x2e\x7f\xdc\xae\xa4\xed\xea\xc9\xa1\x3c\x97\x60\x38"
+  "\x53\xc2\xb1\xbe\x46\x8a\xfb\xdd\xb1\x13\x92\xa0\x49\x94\x90\xa7"
+  "\x4f\xe6\x8f\xb6\x9e\xbd\x9f\x6c\xba\x4b\x8a\x63\x07\xb2\x27\x42"
+  "\xf5\x70\xd6\xba\x7b\x07\x6b\x14\xb6\x96\xb3\xc7\x05\xdb\xf9\x79"
+  "\xbf\xd8\x66\x37\x96\x63\xdc\x01\x2b\x00\xc9\xa5\x31\x8b\xd6\x93"
+  "\xe6\x34\xb9\xe0\xb2\x51\xea\x3a\x30\xfb\x53\x0d\xd4\x6e\xfe\x7a"
+  "\xbd\x23\x92\x49\x4f\x37\xb4\xb8\x3a\xe1\xad\xee\x8e\xc8\xe2\x3f"
+  "\x81\xe4\xf4\x1f\x85\xf1\xf1\x60\xa1\x39\x98\xda\x1d\xcc\x85\xbf"
+  "\x1d\x78\x75\x22\x4e\xae\x39\x0e\x4b\xaf\xb8\x25\x1e\xe2\xff\x6c"
+  "\x03\xd9\x1f\x2d\x1d\xab\xf2\x47\xff\xd1\xdc\xde\xa0\xf2\x45\xcb"
+  "\x96\xf4\xf7\x45\xb9\x8b\x85\x2f\x62\x7e\xe1\x7b\x02\x2e\x39\x7c"
+  "\x4e\x48\xb8\xbc\x5f\x25\x77\x42\x48\xb8\x4f\x0e\xbf\x26\x24\xdc"
+  "\x2d\xc2\x9f\x7b\x52\xf1\x75\x2d\x54\x8e\x55\xe4\xeb\x9e\xbb\x87"
+  "\x7c\x5d\x4b\xb6\xec\xeb\xf8\x5e\xcc\xe7\x46\xb3\x5f\x94\x00\x9d"
+  "\xa3\x73\x0c\x9e\x0d\x50\xf9\xd9\x1f\x40\x29\x7b\x14\x86\xbd\x47"
+  "\x61\x15\x9f\x80\x11\x2f\xee\xe7\x98\x3d\xfb\x3a\xf2\x73\xe4\xe3"
+  "\x68\x1f\xcc\xae\xe1\xac\x6d\xd7\x0e\x76\xa8\x7a\x07\x3b\xe8\xb5"
+  "\x3f\x3b\x46\xf1\x77\x3f\xc5\xb0\x72\x0c\xfb\x29\xc6\x93\xdf\x23"
+  "\x99\x34\x67\x34\xd0\xb9\xa2\xed\x88\x31\x6b\x9c\x01\xf2\xb6\x20"
+  "\xe6\xe9\xbc\xab\x8d\x28\x5f\x67\xa1\x87\xef\x39\xe1\xe7\x81\x4b"
+  "\x49\xe8\xa3\xda\xc9\xde\x86\xbf\x18\xa4\x79\x89\xbf\xc2\x7a\x0f"
+  "\x3b\x4e\x7b\x53\xa8\x0c\x8b\x56\x3f\x40\xe7\x5b\x1b\x1a\xb1\x77"
+  "\x44\xe7\x10\xd0\xde\x19\xf4\xbb\xc6\x0a\x2c\x93\x38\xdf\xf7\xd9"
+  "\xfd\xd8\x73\x49\x11\xba\x5e\xc6\xcf\xcf\x3f\x0a\x4b\x7d\xcc\x8e"
+  "\xbe\x10\xeb\x16\x17\x28\x01\x3a\x8b\x05\x6d\x94\xe6\x59\x73\x76"
+  "\xe1\x55\xa1\x9c\xc7\x42\xdf\x52\x40\x1a\x67\x9b\x0f\xa8\xcc\x2e"
+  "\x78\x76\x46\x73\x51\x03\xa5\xef\x20\xd9\x30\x7b\xb1\xc2\xc3\xc0"
+  "\xcf\x73\xc1\x31\x3c\x9d\xe7\x82\x74\x7c\xce\x90\x45\x77\x98\x9a"
+  "\x33\xdd\x40\x7e\xde\xd9\x81\x3c\x8a\x8e\x0a\x1e\xc8\x8b\xa1\xdf"
+  "\xd7\xc4\xc9\xfc\x63\xd7\xb1\x6f\x90\xff\x7e\xd2\x17\x9d\xcb\x45"
+  "\xeb\x92\x50\x2e\x31\x74\x36\x83\xe8\x77\x3e\x3b\xb5\xf6\x13\x00"
+  "\xf9\x6c\x31\xc4\xdb\xb3\xc9\x74\x76\x17\x9d\x27\xc6\xcf\x12\x93"
+  "\x26\x02\x5b\x95\x18\xd3\x7b\x9e\xd8\xf7\x70\x96\x18\xca\xdf\x52"
+  "\x23\xb1\x7d\x58\xfe\x64\x3a\x4f\x0c\xcb\x5f\x4d\x38\x94\xeb\x94"
+  "\xf2\xb3\x27\xb8\xcc\x37\x52\xd8\x56\x3b\x6b\x52\xf4\x4f\xf5\xa5"
+  "\xba\x60\x5c\x8e\xe8\x0f\xb2\x56\x17\xe4\xa6\x50\x3c\x86\xcd\x27"
+  "\xfa\xf1\xe8\xc7\x9c\xd9\x01\x78\xe7\x58\x40\xda\xba\x06\x8c\xc2"
+  "\xa7\x2d\x7b\x9c\xd2\x0b\x9f\xb6\xcc\xdc\xe7\xd3\x96\x45\x0a\x9f"
+  "\x26\x64\x2c\x7c\x5a\xee\x39\xe1\xd3\x72\xbf\xe1\xeb\x87\xd0\xa7"
+  "\x51\x1c\xf9\x35\xc5\xa7\xed\x1e\xce\x9a\xc8\x77\x78\xed\xb9\x2e"
+  "\xc5\xb7\x6d\xc6\x30\xf2\x1d\x54\x46\xe1\xa7\x9e\x9b\xcc\x3e\x4d"
+  "\x04\xb1\x3e\x93\xee\x73\xe8\xbc\x8c\x0e\xf9\x9e\xda\x91\x87\x84"
+  "\x8f\x5b\x36\xb1\xcf\xc7\xe5\x36\xf4\xa5\x25\x1f\xb7\x6c\x96\xf0"
+  "\x71\x22\xbc\xf6\x09\xf2\x71\xcf\x4d\x26\x19\xc8\xfc\x25\x7a\x6f"
+  "\x26\xd3\x93\x1c\x53\xd4\x3e\x4e\x6b\x5f\xcb\xca\x15\x1f\x47\xbe"
+  "\x0d\x9f\xab\x5d\x10\xdd\xc4\xed\x0d\xe9\x2a\x51\xe6\x8a\xdd\x91"
+  "\x0e\xa8\xce\x74\x4e\x3e\xc9\x6d\xfa\x09\x18\x2c\x9f\x53\x23\xd7"
+  "\x7b\x59\x9b\xb2\x27\x13\xe5\xef\x0a\xed\x33\xe3\x73\x6f\x3f\x0d"
+  "\x75\x7d\x1d\x9d\xe1\xe8\x2c\x39\x0a\xce\x2a\x56\xd2\xe2\x3f\x02"
+  "\xc1\x17\x9f\xfb\x92\xf4\x8a\xe3\x8b\x41\xf4\x4b\x7e\xe7\x38\x2c"
+  "\xbf\x6a\x91\x87\xcf\xd7\x7f\xb9\x55\xc2\x38\x1b\xdc\xa5\x8a\xe3"
+  "\x7b\xec\x55\xe9\xc6\xaa\xe2\x1e\xa2\x38\x9a\x63\xc4\x7b\x08\x37"
+  "\xa7\x30\x80\x72\xbc\x7a\x9e\x72\xbc\x77\x9e\x72\x1c\xe6\xe5\xc0"
+  "\xfe\x16\x8e\x8f\x86\x9e\x84\xe5\xf2\xde\x10\xbc\x74\xf3\x59\x11"
+  "\x25\xc7\x47\xa8\xe2\x55\x79\xad\xb8\x49\x27\xbd\x2a\xbf\x15\xb3"
+  "\x2e\xc0\x7f\xe9\x05\xf8\x6f\xba\x00\xff\x37\xc8\xf7\xd1\xbe\xbf"
+  "\x80\x5d\x4b\x37\xce\xcf\x6d\xaf\x89\xce\x8e\x42\xba\xff\x92\xdf"
+  "\xb7\x7c\x59\x3c\x82\x8f\xff\xf8\x79\x41\x5b\x30\x9e\x9f\x93\x8b"
+  "\x7e\x79\xc6\x6a\x00\xb1\xa6\x4f\x49\x93\x17\x19\x5a\xb6\x21\x7e"
+  "\xa5\x6c\x3c\x7e\x74\x68\xd9\x30\x7e\xac\x2a\x7e\x66\x9f\xce\x57"
+  "\x38\xce\x33\x8f\x14\xe3\xac\x02\xfe\xed\x98\x03\x38\x6c\xa1\xbd"
+  "\x3e\x95\xbd\xef\x46\xf2\x10\xff\xcb\xf8\xbb\x1d\x79\x5f\x71\x27"
+  "\xfa\xf4\xeb\xe8\x1c\x50\xea\xf3\xca\x7b\x41\xae\xc4\x76\x64\x18"
+  "\x9d\x13\x43\xf3\xe9\x8b\x02\xe9\xd2\x81\x22\xb2\x9d\xbc\x36\x25"
+  "\x6d\xb8\xb9\x47\xca\x57\xce\x93\xef\x93\xf2\xda\x9f\x8f\x51\xd2"
+  "\x10\x6f\xda\x1b\x84\xfe\xff\x3a\x7e\xfe\x9a\xbf\x93\xfc\xed\x95"
+  "\xd8\x3f\x1e\x26\xf2\xc9\x02\x91\xcf\xf3\x29\x2e\x58\x6e\x3b\xdf"
+  "\x3e\xac\xf0\xf5\x7b\xbe\x68\xe0\xf5\x03\xb9\x7e\xcf\x37\x5c\xa0"
+  "\x7e\xe7\xcb\xd7\x33\xf0\x7c\xcd\x72\xbe\xf9\x49\x03\x97\x6b\x7e"
+  "\xf6\xc5\xcb\x35\x49\x96\x6b\x7e\xd5\x05\xe4\xaa\x97\xcf\xc1\x8b"
+  "\xcf\xc7\x2a\xe7\x53\x00\x7a\xf9\x00\xff\x0b\x7b\x9e\x90\x49\xf9"
+  "\x76\x0b\x7d\xc7\x48\x7c\xa3\xa1\x20\x55\xfd\x8d\x2a\xf1\x7d\xa3"
+  "\x82\x4c\xe5\x1b\x55\x7d\xfb\xcc\x0a\x56\x2f\xaa\xa3\x7e\x08\x0b"
+  "\xba\xa0\xa0\x88\xe6\x02\x67\xac\x13\xe7\x17\xca\x69\x2a\x2e\xf0"
+  "\x6d\x2c\x3a\xc3\x87\xce\x8a\xf1\x30\xc6\xcf\x8a\xf1\x88\x73\x00"
+  "\x0b\xfe\x8b\xf6\x0c\x8a\x35\x45\xfc\xd0\x2f\xe2\x85\x63\xd8\x02"
+  "\x7e\x7e\x3b\x9d\x2d\xdf\x55\x2c\xd3\x5f\x4d\x6d\xa8\x42\x53\x08"
+  "\x0a\x8d\xee\x9c\x64\x99\xd7\x5c\xbf\x3e\x49\xb3\xbf\x71\x66\x7e"
+  "\xfe\x8a\xfc\x29\xd6\x82\x65\x4f\x8d\x2d\x28\x5c\x5c\xf8\x42\x01"
+  "\xdf\x08\x1f\x0d\x18\x60\x2d\x5c\xba\x6c\xc9\x8a\x17\x0a\x13\x57"
+  "\x2d\x5e\x2a\x36\xce\xdf\x84\x84\x6a\x22\xd0\x7c\xd3\xc4\x82\x3e"
+  "\xa8\x95\x49\xfc\x8c\x8b\x4e\xaa\x13\x9d\x75\xa2\xec\x0b\x6e\xb4"
+  "\x00\x78\x70\x7c\x84\x65\xac\x77\xc1\x63\x6e\x45\x8e\x74\xfe\x22"
+  "\xf6\x93\x2c\xc7\xa1\xf0\x8f\xa4\xfb\x34\xec\xf2\xd6\x8a\x73\x2b"
+  "\xf8\xd9\x03\xce\x42\x0c\x68\x01\x93\x63\x25\xcd\xf3\xbe\x30\x39"
+  "\x68\x2f\x4c\xe4\xe7\x49\xae\xa1\xf1\xf7\x0b\x4f\x2a\xfd\x12\x7a"
+  "\x6f\x25\xde\x33\x5f\x37\xed\x28\x14\x6e\xa6\x7c\xc9\x6e\x6a\xb0"
+  "\xff\x4b\xbc\x98\xbd\x30\x85\xfa\xc0\xf8\x6c\xf2\xda\x5f\x48\x54"
+  "\xfa\xbe\x58\xde\x18\x16\xe5\x45\xb9\xbd\x90\xf9\x9f\x66\x37\xc8"
+  "\x7b\xc9\x4d\x35\x62\xdf\xb8\x11\x69\xe7\xf7\xd2\xda\xe9\x6c\x65"
+  "\x2f\xb5\xd3\xba\xef\xca\x59\xb4\xa7\x35\xd8\x93\x11\xa9\xae\x33"
+  "\x8e\xd9\x51\x3f\x2b\x63\xb1\xee\xf1\xa4\x6b\xf9\xbc\x93\x41\x58"
+  "\xf6\x33\xe2\x7c\x67\x4f\x2b\x86\x0d\xc2\xdf\x0e\xd2\x29\x9d\xb1"
+  "\x80\x71\xb4\xd6\xc7\xd0\x52\x74\xca\x71\xc0\x72\x14\x71\xfd\x02"
+  "\xcd\x5d\x8f\x12\xfb\xe2\x90\x1e\xf3\x70\x96\x74\x43\xa3\x95\x39"
+  "\x68\x0e\xd0\x05\x2b\x47\x35\x5a\x3d\xc0\x22\x16\x7c\x49\xe9\xd0"
+  "\x2e\x2c\xc5\x36\xea\xfb\x60\x38\xdf\xff\xb7\xd2\xa2\xc8\xbc\xd0"
+  "\xca\x4e\x10\x4d\xb8\x79\x6b\x6a\x83\xb7\xf2\xb6\xe4\x34\xd0\x1a"
+  "\xaf\x76\x58\x99\x1c\xea\xef\x47\x67\x4f\xb1\x66\x2f\x2e\xb4\xe6"
+  "\x2e\x5d\xbe\xc4\x9a\xbd\x34\xdb\xba\x7c\x45\xa1\xf5\xc7\x2b\x68"
+  "\x02\x89\xa6\x8c\x34\x98\x08\x52\xfd\x56\x65\x44\x2a\xef\xc8\xbb"
+  "\x56\xe5\x0c\xc2\xfa\xa3\x4c\x56\xfd\xac\xcb\x9b\x33\x58\x2b\x93"
+  "\x55\xf2\x59\x5c\x2b\x71\xfc\xf7\x42\xae\xd8\x5f\x18\xd1\x81\xcf"
+  "\x58\xff\x95\x49\x5a\xdb\x5b\xf5\x81\x4c\xeb\x51\x68\x39\x2e\x46"
+  "\x1e\xef\x8d\xdb\x2a\xe3\xb1\x56\xec\x83\xe6\xe7\xea\xd4\xf2\x3d"
+  "\x02\xab\x12\xc3\xa6\xa1\xb3\xc4\xd6\xc0\xd3\x27\x61\xd5\x50\x66"
+  "\x5f\x99\x29\x63\xc8\x14\x2c\xf5\xb8\x64\xfc\x20\x26\x56\xe5\xf4"
+  "\xc7\xcf\xaa\x46\xc2\x0f\xf3\x66\x98\xf8\x7a\x12\xbf\x0f\xfd\x14"
+  "\x3e\x63\x7b\x8a\x65\x3f\x48\xf5\xf0\xac\xca\x30\x15\xef\xe4\xed"
+  "\xf5\x57\xf4\x6e\xf6\x80\x8f\x9f\x05\x15\x85\xd8\x40\x1d\xad\x7a"
+  "\x57\xd1\x91\x42\xaf\x6f\xc3\x1c\x2f\x5a\x8c\x71\x79\xda\xae\xe0"
+  "\x18\xc3\x7e\x01\x96\x49\x52\xfa\x05\xd4\x06\xb8\xc0\x36\xa6\x70"
+  "\x1d\x63\x5e\xbb\xcd\xaa\xc2\xc1\x49\x3d\x1c\xa0\x6e\x9f\xce\x5d"
+  "\xf1\xf4\x73\x68\xe8\xf9\x4b\x0a\x9f\xce\xa1\xb3\x33\xc8\x0f\xf0"
+  "\x83\x39\x46\x67\x5b\x5f\x28\x58\xf2\x74\x34\xe8\x51\xf5\x46\xaa"
+  "\xf5\x6f\x0e\x22\x5e\xbb\xba\x32\x22\x69\x0f\x87\xd8\xb3\xb1\xfa"
+  "\xaf\x5d\x05\x38\xee\xd1\xe8\x7d\xf5\x61\xa7\x25\x09\xfb\x89\x49"
+  "\xc0\xfb\xfc\x28\x33\xb1\x0e\x61\xcd\x35\x24\x87\x2e\xc9\x80\xed"
+  "\x81\xed\x88\x82\x01\xbc\x47\x6c\xaf\x6a\xed\x5b\x03\xb2\x26\xa1"
+  "\x4b\x8a\x3c\x42\xfe\x47\xac\x37\x39\x8e\x7e\x20\xae\xf6\x28\xac"
+  "\x4e\x21\x9d\xd6\xf0\xf6\x64\x75\x82\x92\x66\x4b\xef\x3e\xea\xd5"
+  "\x1b\x15\x9c\xa8\xd2\xc4\x52\x98\x18\x3f\xdb\x26\x93\xce\x99\xd0"
+  "\xbd\x51\xa1\x43\xb9\xb2\x5a\xee\x47\x56\xe7\x85\xfa\x86\xff\x34"
+  "\xd3\x3b\x77\x51\x1e\x8e\x3f\x93\xa7\x81\x9f\xcb\x82\x7d\x3c\xe4"
+  "\xbd\x4e\x5e\xff\xd2\xca\xdb\x74\x1b\xf2\xf2\x09\x5e\x98\xd7\x42"
+  "\x25\x2f\x16\xe5\x69\xa8\xe5\x38\x5b\xdd\xda\x37\x27\xb9\xba\x88"
+  "\xc6\xe6\xac\x2b\x63\x10\xea\xf3\x5d\x8e\x2d\xbc\x2f\xbc\x4a\x9c"
+  "\x11\x47\x78\xa3\x7a\x12\xae\xfa\x30\xb5\xc6\xac\xe8\x9b\xea\x8c"
+  "\xe9\x1a\xad\xfc\x1c\xe1\x35\x89\x8a\x2c\xc3\x9d\x65\xc3\xed\xd6"
+  "\x84\x65\xf1\x0a\xdb\xe5\xe3\x4a\x71\x7e\x11\xed\xa3\x89\xc0\x32"
+  "\xba\x8e\xc1\xda\x3b\x69\x6f\x40\x9c\x8f\xc6\x69\x1e\x17\x9d\xcd"
+  "\x20\xf6\xba\xaf\x29\x45\xfe\x45\x7d\x7b\xdf\xd7\x60\xfb\x6f\x2b"
+  "\x12\xba\x5b\x53\xaf\xb2\x3d\xb7\xbc\xde\x60\x30\xc9\x88\xfc\x99"
+  "\xd3\x36\x93\xdb\xab\xd8\x57\xbc\xa6\x55\x49\xc7\xcf\x31\xf0\x8b"
+  "\x36\xf1\x24\xac\xa1\x79\x1e\x37\x95\x0f\x65\x9d\x47\xf9\x53\xfd"
+  "\xa8\xcd\xe5\xb8\xb1\xd0\xb7\x56\xd6\xc6\x68\xcb\xb0\x36\x41\xe1"
+  "\x25\x78\xaf\x1d\xa3\x3c\xd3\xb9\x66\x2e\x28\x6a\x68\x4c\x40\x9b"
+  "\xf2\xf0\x3a\x5c\xd6\x88\x4d\x6a\xa3\x87\xd3\xcd\x57\x64\x88\xe1"
+  "\x25\xf8\x8c\xfd\x9f\xc2\x1c\xf1\xce\xc9\x2b\x7f\xe7\xa9\x68\x3f"
+  "\x9d\x99\x55\x6c\xa5\x73\x0f\x93\x85\xbf\xe1\x67\xf5\xf0\xb8\xe7"
+  "\x65\x9b\x8d\xa2\x3d\x48\x7c\xdd\x8d\xc7\xcf\x7d\x83\x38\xdb\x01"
+  "\xe3\xd1\x46\xbc\xe2\x7b\x4f\x51\x72\xd9\x9a\x7a\xf3\x40\x4c\x34"
+  "\xf2\x77\x9c\x6b\x1b\xc4\x59\x29\x83\x91\x76\x6d\x87\xa2\xbf\x8d"
+  "\x3b\x30\x0c\x79\x62\x3a\x53\x23\x3f\x8b\xac\xc8\xa8\x94\x57\x8e"
+  "\x93\x38\x1e\xb8\x0c\x8a\x7a\xed\xbf\x6b\x18\xa7\x4d\x52\xf2\xe1"
+  "\xb4\x48\x47\xf4\xf4\xcd\x4f\x8c\x9b\xdd\xcb\x47\x9c\xd1\x42\xdf"
+  "\xd1\x33\x34\xd6\xf1\xb8\x9c\x3e\x5f\xb5\x96\xbf\x33\xe2\xeb\xe2"
+  "\xb0\x1e\xee\xb5\x39\x51\x5c\x07\x56\xa0\xef\x90\x18\x89\x9f\xc0"
+  "\x62\x51\xb5\x92\x26\xc2\x40\x72\x2c\xda\xab\xe4\xad\xf0\xa0\xf2"
+  "\x9f\xd7\xe7\x89\xba\x18\xc9\x46\x88\x96\xf8\x72\x4c\xf0\x6f\x7c"
+  "\xad\x9b\xc4\x31\xc8\xeb\xb9\xce\xa4\xd6\xb5\xe8\x8b\xad\x4b\x50"
+  "\xe1\x01\xcb\xf3\xff\x88\x7b\x1f\xb8\xb8\xaa\x6b\x5f\x7c\xcf\x30"
+  "\x24\x03\x02\x33\x2a\xc6\x49\x24\x71\x54\xbc\x77\xb4\x51\x51\xc9"
+  "\x7d\xa9\x9f\x58\x69\x8d\xf7\xa6\x7d\x6a\xd2\x36\xde\x47\x6f\x53"
+  "\x21\x06\x2c\xa9\x31\x19\x09\x21\x93\x48\x18\x98\x10\x3a\x20\x10"
+  "\xd4\x68\x31\x21\x04\xdb\xd4\xc6\x1a\x2b\xbd\x8d\x2d\xb1\x51\xc7"
+  "\x06\x5b\x54\xc2\xa0\x8d\x15\x15\xeb\x88\x88\x84\x90\x38\x84\x81"
+  "\x99\xc0\xcc\xd9\xbf\xef\xda\xfb\x1c\x66\x12\x21\x36\xb7\xef\xf3"
+  "\x7b\x7c\x3e\xc3\x39\x67\x9f\x7d\xf6\x9f\xb5\xd7\x5e\x7b\xad\xb5"
+  "\xd7\x5e\x6b\xcb\xe4\xf8\xfb\xd8\x96\x15\x72\x2d\xd9\x92\x15\xd3"
+  "\xc6\x2c\x3c\x2f\x9b\x1c\x87\x6a\x31\x46\x14\xf7\x69\xca\x38\x8a"
+  "\x62\xae\x20\x8f\xc2\x45\x3b\x69\x3c\x20\x8b\x2d\x64\x6d\xa0\x7b"
+  "\x34\x57\x00\x13\x6a\xe3\xbb\x84\x57\x28\x77\xdf\x99\xb8\xb9\xa5"
+  "\x35\xa6\xbd\x3a\xa2\xeb\x48\xeb\xd0\xf2\xa0\x7d\xc2\x96\x45\x83"
+  "\x27\xde\x0d\x4c\x8e\xe3\x4d\x22\x6f\x48\x6b\xe7\x57\xac\x19\x2a"
+  "\xac\x4a\x6f\x94\x75\x94\x66\x68\x75\xe0\x7e\x11\xe6\xc0\x97\x78"
+  "\xd5\xfb\x36\x15\xe5\x4b\xe7\x49\xb4\xc8\xaf\x5c\xf5\x40\x7e\xde"
+  "\x7c\xeb\xca\xfb\xc9\xcd\xd2\xfa\x35\xf9\xf9\x76\xb1\x49\x74\x26"
+  "\x1f\x98\x2a\xea\x03\x1c\x24\x2f\xeb\x3c\xf8\xb8\xb4\x8f\xa1\x79"
+  "\x41\xf3\xdd\x4f\xf3\xfd\x70\xc9\x29\x21\x9b\x78\xcb\x6e\x62\xde"
+  "\x10\x2f\x23\xfe\x5d\xd0\x3e\xea\xbf\x25\x20\xd7\x01\x8c\x27\xad"
+  "\x91\x68\x5b\xf7\x99\xf0\x2a\x1d\x38\x73\x2e\x97\x86\xa6\xa6\x13"
+  "\xa5\x4f\x09\x3a\xe1\x96\x78\x41\xf4\x89\xce\x16\x50\xb9\x41\x97"
+  "\x73\xfe\x99\x65\x3a\x17\x45\x69\x94\x73\x89\x46\xa3\xe4\x3a\xe1"
+  "\x5c\x83\x35\xa8\x5e\xd6\xe5\xcc\x8b\xe2\x8d\xb3\x4f\xe2\x8d\xd3"
+  "\xe1\x63\x8f\x1d\xd5\x64\x15\xb9\x76\x94\x2e\x21\xfe\x91\x68\x3a"
+  "\xde\x37\x68\xe5\xed\xb8\x88\xd6\x0d\xe7\xbe\x2f\xf3\x0f\xce\xe5"
+  "\xc4\x3f\x90\xdd\x23\xc1\x02\x6d\x35\xca\x79\xe3\x3c\x1a\x43\x7f"
+  "\xcc\x78\xee\x9b\x6a\xac\xef\xa3\xe5\xf8\x3a\xda\xce\xbb\x6e\xd5"
+  "\xda\xa2\x5b\xc9\x05\x56\xbe\xc3\x9e\xbf\xaa\x28\x3f\xef\xec\x7d"
+  "\x3c\x9b\xc6\x8b\xd1\x1e\xfa\x0e\xcc\x7b\x7f\x02\xc1\xa3\x0c\xfd"
+  "\x77\xe5\x69\x7d\x10\x74\x0a\xbc\xa3\x4a\xe3\x92\xfa\x99\xeb\xc6"
+  "\x3d\xc2\x0e\xb0\x2c\x4f\xc3\x13\xca\x77\xbb\x83\x2b\x48\x43\xff"
+  "\x4b\xed\xaa\xbc\x04\x99\xb4\xcc\xad\x3d\x47\xbf\x2f\x3b\x22\xd6"
+  "\xbe\x27\x85\xcd\x20\x60\x5a\x7e\x67\x0c\xbf\x45\xcf\xe9\xea\xb3"
+  "\xf0\xf3\x44\x3e\xc9\x86\x58\xd9\x27\x12\xbe\x65\x18\xff\x2d\x2a"
+  "\xad\x70\x49\xbb\x9b\x27\x19\xfb\x45\xa9\x3f\x7e\x8f\xd8\x4f\x28"
+  "\x0b\x69\xf5\xe1\xfb\x9e\xd8\x3a\x69\xdd\x3a\xbb\x3c\x1f\x2b\x13"
+  "\x3e\xdc\xb7\x0a\x1f\x75\xe5\x99\x53\xb4\xb5\x35\x36\x1f\xf2\x64"
+  "\x23\x8f\x41\xeb\xf3\xf7\x1d\x22\x6d\xcd\x39\xfa\x38\xa4\xf6\x91"
+  "\xe8\xa6\xa8\x9f\xf0\x5f\x6d\x43\x87\xea\xf7\xc4\x47\x31\x12\xa9"
+  "\xfd\xc2\xff\x9a\x85\xe6\x75\xb9\x07\xeb\x59\xa6\xd6\x0f\xea\xe3"
+  "\x81\x52\xbf\x41\xf3\x7b\x25\xbf\x2f\xff\xe5\x59\x6d\x0b\xc4\x7c"
+  "\x33\xe0\xb9\x92\xf6\x0a\xca\x6b\xb9\xcb\x49\x72\x0c\xf9\xbd\x32"
+  "\xee\x98\xc4\x43\x97\xf5\xcb\x78\x57\x5e\x43\x78\x17\x8b\x4b\xab"
+  "\x6f\x5a\x05\x4c\x5a\x9f\x5f\x74\x8b\xe0\xee\xc1\xd8\x91\x5b\xb5"
+  "\x95\x45\xab\xd7\xad\x5d\x3f\xdf\xba\x3e\x6f\xa5\x3a\xe9\xcf\x98"
+  "\xf3\x2e\x21\xbb\x07\xb4\x79\x86\xba\x6a\xa2\xb4\xc5\x15\xc5\x7f"
+  "\xb2\x01\x13\xb1\x99\x5d\x9f\xc8\xf9\xe4\x3a\x10\x33\x77\xc5\xf7"
+  "\x34\x47\xf7\x08\x9e\xcd\x15\xbb\xfe\x93\x6c\x9c\x70\x92\xb9\xb6"
+  "\xa8\x30\x0d\x48\x18\x6f\xbd\x46\xf4\x53\xf8\xfb\x72\x2d\xa2\x7e"
+  "\x0a\xff\x32\x82\x3f\xdb\x6a\xd6\xfa\x1b\x95\x1b\xb6\xda\x04\x1f"
+  "\xa5\xf2\x6b\xe7\x92\xcb\xa3\xfc\xe9\xd6\x36\x55\xe7\xd6\xad\xc9"
+  "\x78\x1a\x7f\x8d\xb6\xe4\x49\x5e\x75\xeb\x96\xa5\x25\x7c\x22\xc7"
+  "\x41\x7e\xf0\x68\x0c\xb6\x3e\xab\xf1\x96\xc2\x3e\xb0\x2a\xe0\x41"
+  "\x7b\x9a\x63\xe9\x04\x8f\x7b\xa0\x5b\xe5\x11\x3d\x52\x76\xbd\xe0"
+  "\x0f\xbd\xa8\x0b\x6d\x33\x9e\xa3\x6d\xd4\x2f\xd0\xbf\x1d\x7b\xa9"
+  "\x1c\xe2\xaf\xf9\x88\x45\xe5\x43\x2a\x1e\x15\xfc\x2e\xca\xf6\x63"
+  "\x6c\x83\xae\x0a\xf0\x7f\x5b\x05\x6e\x28\xc0\x51\xb2\x0d\x0a\x68"
+  "\x3c\x12\xab\xb8\x95\xd6\x22\xdc\x03\x6f\x2b\xd4\x33\x89\x15\xf5"
+  "\xfe\xf5\x36\x36\x32\x62\xd1\x8f\xac\xcf\x36\x90\xbe\x80\x60\xe1"
+  "\x6d\x0c\x31\x89\x3f\x15\xb9\xc0\x3b\x73\x6c\x79\x6a\x59\x04\x53"
+  "\x03\xb5\x83\xaf\xb7\xe8\x09\xbf\x45\x7c\xc2\x11\x1b\xf0\xab\xc2"
+  "\xc6\xd7\xdb\xf4\xd3\xf8\xf6\x3a\x57\x3f\x93\x28\xc6\x23\xc5\xe6"
+  "\x24\x7a\x25\xe3\x07\x6c\x3b\xf1\xb8\xd4\x0d\x68\xf5\x0e\x73\xfd"
+  "\xd3\x62\x5d\xa9\x13\xeb\x0a\x67\xd2\x1f\xfb\x36\xe1\x2b\x3f\xc5"
+  "\xfe\xb4\x88\xab\xaa\x9e\xff\xf6\xb7\xd9\xc3\xa2\xcd\xce\x22\xe2"
+  "\xd3\xc2\xb4\x4f\x25\xce\x37\x1f\x2e\x0a\xb3\xef\x87\x08\x27\xb7"
+  "\x65\x91\x2f\xfa\x80\xe0\x17\xb6\xdd\xa9\xf9\x9f\xa7\xb8\x91\x14"
+  "\x77\x14\xfd\x8a\xa3\x71\xb7\x3a\x29\x76\x40\x25\xc5\x65\x65\x52"
+  "\x1e\xb7\xb0\x3a\xf0\xf4\x72\x0c\xb6\x3d\x41\x71\x5c\xa5\xac\xd0"
+  "\x8b\x71\x89\xfb\xbc\x97\x6d\x7b\x5e\xee\x55\x6b\x74\xa2\xf2\x6a"
+  "\xb2\x7d\xf7\xa9\x65\xa0\x2e\xac\xff\x5b\xa5\x8f\x50\x5a\x3b\x83"
+  "\xda\x78\x6e\x7b\xe2\xcb\xfa\x8d\x68\x79\x3e\xb6\x6d\x87\xca\x17"
+  "\x30\xa9\xbb\xfa\x13\xca\xaa\x34\x68\xba\xab\x28\xef\x53\x69\xd1"
+  "\x74\x57\xd2\xb7\x75\x45\x0f\xd5\x3f\x9d\x8e\x88\x3b\x7f\x40\x78"
+  "\x6f\x24\x1e\x6e\x5a\x7e\x02\xeb\x3b\xb5\x5d\xe3\x0b\xe5\xf8\x54"
+  "\xfe\x96\xf8\xc3\xb6\x12\x29\xd7\x8e\xc8\x18\x93\xe0\x01\x2a\x0f"
+  "\xc9\xb5\xac\xb2\x59\x5b\xcb\xf0\xed\x01\x95\x56\xa8\xeb\x5c\xe5"
+  "\xa4\xfc\x3b\xb5\xdd\x7f\x65\x8f\x06\x23\x0d\xe6\x12\x46\x3f\x5d"
+  "\x30\x92\x38\xb8\x38\x0a\xdb\x9f\x8a\xbd\x8b\x98\xf7\x0f\xc6\xc0"
+  "\x9e\x9e\xd7\x48\xba\xf9\x53\xac\xff\x15\x8d\x72\x4d\x91\x69\x3c"
+  "\x31\x18\x47\x31\x63\x25\x0c\x56\x0b\xdd\x8c\xdf\x69\x43\xdb\x7e"
+  "\x9a\xed\xd3\x5d\xb4\x4c\xd2\xb2\x9f\x62\xfd\xab\x5c\xae\x7e\x27"
+  "\xc6\x3f\xb6\xbd\xf7\xac\x7d\x60\xed\xba\x8d\x6b\x49\xa1\xb6\x61"
+  "\xbd\x75\xd5\xba\xbc\xfc\xc4\x29\xf4\x21\x16\x8a\x17\x1d\xd8\x31"
+  "\xe9\xd7\xaa\xda\x4e\x76\xfa\x32\x26\x42\xf5\x43\xd6\x7f\x21\xfc"
+  "\xfa\xe9\xbb\xa4\x2b\x10\xb1\x29\xc8\x87\xab\xd4\x1b\x0c\xd0\xf7"
+  "\x12\xd6\xd5\x3f\x1a\xd9\x58\xa0\xf2\x58\xd5\xb3\x09\x8e\xaa\xcc"
+  "\xc1\xfb\x99\xfb\xbb\xda\x3a\x44\xed\x13\xbc\xf9\x84\x4d\xd0\x45"
+  "\x65\xa2\xc0\x20\xe0\x35\x61\xc3\x7a\xe3\xce\xf0\xe9\x2e\x9c\x2f"
+  "\xfb\xe5\x5e\xa4\xc1\x83\xfa\x0f\x5e\xd7\x18\xe4\xab\x81\xa3\xd5"
+  "\x76\xb5\x2c\xa2\x9f\x54\xb6\x41\xb3\x13\x27\x5f\xa5\x9e\x62\xf2"
+  "\x53\x5c\x75\xab\x52\x45\xf4\xc6\x5d\xa6\xd1\x25\x5a\x8b\x14\x94"
+  "\xf3\xc2\x98\x3f\x1e\xf3\xe6\x9b\xf8\x76\x56\x2f\xab\xea\x90\xf1"
+  "\x0c\xdc\xfb\xcf\x8c\x67\x50\xe5\xc6\xaf\x43\xfd\x0d\xc5\xdc\x9f"
+  "\xeb\xa7\x7d\xd3\x1a\x93\x66\x3c\x2b\xcf\x50\xd0\x55\x95\x3a\xc9"
+  "\xaf\x48\x7f\xa9\xaa\x7f\x65\x8a\xcd\x51\xf5\x5d\xf2\x49\x1a\xc5"
+  "\x0d\xf7\x06\x95\x07\x19\x20\xd8\xd1\x7a\x8b\x3c\xc2\x96\x1b\x30"
+  "\x89\x23\x1d\x2d\xf5\x89\x07\x57\xa3\xaf\x55\x6b\xa2\x78\x20\x61"
+  "\x84\xb4\xb2\x28\x9f\x52\xb5\x9c\xbe\x89\x85\x03\xea\xf8\xa6\x94"
+  "\x4d\xab\xf6\x69\x6b\x36\xf9\x63\x95\xf1\x2d\xaa\x52\x0f\x94\x0e"
+  "\x40\xe6\xaf\x6a\x8b\x29\x23\x55\xd5\x45\x18\xb8\xfe\xa7\x8e\x3d"
+  "\x42\x66\xab\xea\x8b\xea\x04\xaa\x52\x89\xee\x8a\x32\x12\x83\x66"
+  "\x6f\x40\xc4\x65\xd6\x69\xb1\xd7\x83\xae\x6a\xb3\xc6\xa3\x68\x65"
+  "\xb5\x49\x9d\x93\xf0\xa1\x89\x39\x58\x8f\x3c\x99\x93\xfa\x58\xa4"
+  "\x4d\xca\x80\x0e\xcc\x63\xc1\x7b\x57\x2f\x8f\xca\x7a\x3f\x15\x3e"
+  "\x76\x85\x1c\x28\xcb\x81\x9c\x55\xbd\xe4\x6c\xb9\x0d\xfc\x83\x75"
+  "\xf5\xda\xd5\x60\x1f\x7e\x6c\x5f\x77\x2b\x44\x87\x1f\xdb\x57\xdf"
+  "\x4a\x26\x65\x77\x2d\xfe\xb6\xb8\x62\x72\xdc\x3a\x85\xfe\x78\x32"
+  "\xf6\x32\xe9\x8c\x20\xe7\x92\xee\x34\x28\x63\xaf\xce\x54\xaf\x46"
+  "\xf5\x3a\x03\xeb\xde\x00\xf0\x7e\x94\x62\xeb\xf8\xd8\x23\x46\x35"
+  "\xde\xad\xb6\x66\x83\x96\x57\x9f\xd0\xf6\xc9\x84\x8d\x3d\xf9\x49"
+  "\xa4\xd8\xca\x5b\x1f\xf8\x24\xe8\x7a\x64\x52\xff\x21\xf5\x8b\x72"
+  "\xdf\x0b\xe9\x59\x5a\xba\xa6\x8f\x45\xda\x72\x4d\xf7\x2a\xf3\x3e"
+  "\x92\x17\xfd\xf6\x0c\xdd\x76\xaa\xb6\xbf\x86\x3c\x6e\x0d\x66\x5a"
+  "\x39\x4e\x2b\x3f\xa9\xf2\x49\x71\x82\xaf\x76\x55\x97\x08\xdf\xa4"
+  "\xc4\x8b\x0b\x3d\xf3\x23\x87\xb4\x7a\x48\x46\xa0\x76\xab\x7b\x37"
+  "\x62\xde\x93\x0f\x52\xe9\xc3\xf4\x91\xc9\xf1\x3f\x73\x8f\x63\xea"
+  "\xfd\x8d\x89\x62\xde\x16\x1e\xe3\xad\x75\x1f\x60\xce\xde\xcf\x58"
+  "\xb8\x98\xb7\x4c\x8c\xf1\x03\x04\xeb\xba\xfb\x18\xab\xfd\x3b\x63"
+  "\x91\xb8\x1f\x1e\x1b\x07\xdc\xef\x1e\x55\x4e\x52\x7c\xbd\x3d\xc8"
+  "\x77\x77\xe0\x0b\xde\x84\x6f\xee\xb6\xf3\x93\x4d\xc8\x77\xd7\x89"
+  "\x93\x7c\x37\xf2\xde\x55\x80\x7e\x17\xf3\x70\x24\xee\x81\x63\xd6"
+  "\xff\x24\x3a\x54\xe3\xf0\x57\x0d\x67\x72\x97\x7e\x3b\xdf\xfa\xb5"
+  "\x6b\x83\xae\x9a\x8a\xc9\x98\x5e\x28\x97\x60\xb4\xd4\x41\xf7\x0f"
+  "\x1c\x43\x9f\x8e\xe5\x60\x0d\xc5\x18\x1c\x43\x3e\xc8\xff\xeb\x05"
+  "\xbd\xf1\xc7\x5d\x7b\x11\x7e\xb6\xa9\xe8\x3e\xda\xda\x16\x29\xe6"
+  "\xad\xdb\xef\x45\xfb\x07\xd1\xfe\x31\xde\x82\x3e\x1c\xa8\xeb\x67"
+  "\x8c\xda\x1f\xa1\x32\x23\x2c\x2e\x67\x93\xee\xc2\x3d\x78\x9f\xe3"
+  "\x30\xb3\x3d\xc8\x7b\x6f\x80\x5d\xd8\x84\x3c\xf7\x3e\x74\x21\x13"
+  "\xed\x1f\x42\xbb\x13\x86\x33\x23\xa8\x9b\xda\x1f\x74\xd5\xce\xd7"
+  "\xda\xa9\xd5\x4f\xed\xd5\x70\x30\x87\xf4\x5d\x89\x83\x15\xd4\x6e"
+  "\xa9\xc3\xaf\xcd\xf7\xaf\x2f\x60\xfe\xb8\xaf\x5d\xeb\x63\xb5\x65"
+  "\x34\x87\xa8\x3f\x7e\xe0\x94\x7a\xee\xed\x98\x06\x03\x29\x4f\xd6"
+  "\xd6\x68\xfd\x8b\xed\xd7\xb2\x75\x85\x42\x8f\xba\x72\x55\xd1\xea"
+  "\xe2\x95\x90\xce\x12\x99\x9d\x92\x84\xfc\x96\x9f\x67\x5d\xb7\xd6"
+  "\x7a\xff\xca\xd5\x6b\xd6\x15\xe7\x17\xce\x17\x22\xf7\xfa\xfc\xb5"
+  "\x79\xa4\x5e\x2d\x5c\x59\x68\x4f\x3c\x8b\xe7\x76\x0f\x67\x92\x3d"
+  "\x22\xd1\xb2\x7e\x56\x5f\xab\xea\x16\x43\xdc\x95\x25\x64\x37\x39"
+  "\x0f\xea\xbe\x69\xdd\x9c\x45\xef\xcb\xe5\x5a\x53\x5f\xc3\xab\x07"
+  "\xb7\x71\x2e\x62\x42\xeb\x4e\xb2\xfa\x4d\xa2\x9f\x23\x4b\xb4\x72"
+  "\x84\x8d\xbe\xe0\x59\x29\x7d\x62\x09\x8b\xda\x94\xd7\xd7\x72\x3d"
+  "\xfa\x08\x18\xa8\x7c\xab\x5f\x3d\xdb\xf7\x97\x5e\x56\x9f\x8f\x7e"
+  "\xd3\xde\x41\x97\xe0\x0b\xc5\x19\xa4\xfa\x7b\xc0\xf7\x82\x2f\x9b"
+  "\x91\x44\x70\xa9\x93\x72\xa5\xde\xa4\xa3\x38\xb1\xbd\x74\x1e\x32"
+  "\x83\xf6\x08\xf7\xb8\x94\x8c\xa8\x4d\x4f\x6d\x03\xf1\xb8\x42\xd7"
+  "\x2e\xe6\x45\xdd\x51\x0d\xdf\xf5\x74\xc6\x64\xeb\x9c\x5b\x24\xad"
+  "\xae\x13\xfb\xff\x18\xb7\x5b\x64\xfb\x45\x7c\x6a\xac\x4f\xdb\x87"
+  "\xd1\xbf\x4a\xee\x5c\xa2\xfa\x95\xdf\x3e\xac\xa4\x64\x36\x47\xd6"
+  "\x5b\xd4\x98\xee\x83\x4d\x4a\xf5\x60\x5d\x04\xeb\xba\x02\x5e\x95"
+  "\xd7\x2d\xb8\x2a\x52\x3d\xe8\x56\x36\xda\xf4\x44\xdf\x9d\x0e\xc0"
+  "\x6f\x5d\x41\x22\xff\xa2\xe0\x82\xc8\x46\x1b\x78\x80\xc1\x7a\xce"
+  "\xf1\x6d\xe2\x60\xb3\x88\xcd\x5b\x3d\xf8\x98\xfa\xfc\x73\x7a\x56"
+  "\xc0\xab\x21\x6d\x1f\x9e\x7f\xad\xf0\x98\xfc\x67\xe6\xdd\x4f\xcf"
+  "\x26\x9d\xb0\x21\xa4\x18\xd3\x8b\xa8\xef\x5a\x9f\x85\x8c\x40\x7a"
+  "\x8a\xc9\xbe\x6d\x1f\xd2\xd2\x89\x77\x95\x7c\x24\x5b\x05\x18\x33"
+  "\x49\xd3\x26\xf3\xbd\xae\xc1\x40\xc0\xb6\x7a\x10\x73\xaf\xbe\x46"
+  "\xc4\xa9\xdf\x7a\xd9\xb5\x5c\x5f\xfb\x1c\xad\x1d\x4b\x23\x62\x2f"
+  "\x8b\xc9\xbd\x8f\xfa\x74\x0d\x9e\x64\x2b\x4f\xeb\x07\xc6\xcd\x96"
+  "\xe3\x67\x89\x72\xfe\xd6\x2f\x8e\x91\x51\x86\xb8\xc0\xf7\xed\x3d"
+  "\xa2\x5e\xbd\x71\xab\x7c\xae\xdb\x21\xd7\xbb\x7a\xbb\x96\x17\x69"
+  "\x0e\xc9\x93\xd6\x2d\x26\xd9\x8d\xf6\xb6\xe8\xbe\x69\x9a\x73\x9c"
+  "\xa5\x8d\x9c\x13\x2d\x24\xda\x6c\x9d\xc3\x58\x67\x80\xf8\xf6\xfa"
+  "\x8e\xc3\x8d\x01\x26\xc6\x2f\x71\x70\xdb\x08\x2f\x60\xe0\x57\xa6"
+  "\xe4\x53\xe9\x9b\x7e\xf6\xa8\x51\xf0\xe0\xc0\x67\x05\xf8\x8c\x6f"
+  "\x2a\x09\x5f\x4b\x47\xa9\x1d\x8f\x2e\x69\x2b\x19\x20\x3f\xf3\xc0"
+  "\xc3\x47\x97\x10\x6c\x68\x6d\xa8\x73\x89\x33\x7c\x82\x06\x7b\x8a"
+  "\x33\xa9\x8c\x05\x29\x21\x66\xe8\x04\x05\x05\xbc\x43\xf6\x52\x76"
+  "\xe1\x20\xf2\x1b\x8a\x98\x91\xe4\xa3\x7f\x74\x1f\x19\xf5\x55\x48"
+  "\x98\x3c\x5a\xa1\xf1\x40\xb8\xaf\x3f\xf3\xac\xea\xa3\x8e\xb3\xf7"
+  "\xd2\xee\x5b\xb7\xae\x28\xa7\x30\x9f\x2e\xb6\xab\x37\x5c\x73\xf6"
+  "\x9a\x98\x24\xe3\xfa\x3c\xba\x8f\xc6\x8f\xd6\x09\x79\xe6\xe3\xd1"
+  "\x81\x18\xb9\x96\x74\x6b\xb7\xd1\xfa\x46\x7b\xe2\x41\xd7\x63\x86"
+  "\xd7\x4a\xb6\x08\x3c\xf9\xc4\xc8\xf4\x67\xd7\x77\xff\xca\xa2\x95"
+  "\x6b\x6e\x91\xdb\xb7\x5f\xae\xe7\x31\xcb\x99\xf5\x3c\xb6\x6c\xb2"
+  "\x1e\x29\x83\x04\xc4\x1c\xac\x5d\x60\xe6\xc9\x73\x5b\x24\x9d\x7b"
+  "\xac\x48\xb3\xc9\x9a\xda\x37\xc6\x60\x38\x52\x1d\xca\xa5\xf1\x72"
+  "\x6e\x61\xfa\xdf\x6d\xee\xd6\x13\xff\x55\x8a\x7b\xb2\x59\x11\x7a"
+  "\x3e\x35\xe6\xde\x2b\xa7\xba\x41\x67\x1f\x6b\xe7\x55\x83\xc0\xa7"
+  "\xc7\xa6\xb5\x33\x89\x3d\x57\x2c\xf7\x28\x1f\xf3\x4d\x97\x97\xbb"
+  "\x03\x21\x39\x57\x1e\x5f\x20\xf6\xca\xe6\xb0\x9f\xf6\xb2\xc7\x6f"
+  "\x34\x58\x20\xc7\xcd\x61\xbf\xc2\xbd\x90\x17\xe8\xdd\x19\x63\x3d"
+  "\x77\xa8\xd9\x00\xec\x04\x96\xea\xb8\xfc\x03\x13\x26\xff\xc0\x08"
+  "\xe2\x85\x4e\x58\xe7\xc7\x01\xc2\x33\x67\x18\x98\x29\x25\xc9\x78"
+  "\xf9\xbc\x34\xcb\x6d\xdf\x58\xb4\xd0\x59\x5a\xe2\xe0\x4a\x38\x64"
+  "\xe2\x31\xf1\x21\x6b\xe6\x66\xdf\x73\x4d\x99\x5c\x2b\x6a\xe7\x66"
+  "\x4f\xd5\xd6\x5a\x17\xb7\x13\x6f\x0d\x7a\x55\xe6\xdc\xc0\xf4\x2f"
+  "\x8c\xfb\xf4\xc4\xcb\xd1\xfa\xe3\x0d\x7f\x04\x99\xe0\xf1\xd7\x5e"
+  "\x45\x1a\xfa\xef\xe0\x35\x99\x65\xf2\xec\xc5\x0e\x9d\x52\x97\x59"
+  "\x16\x2d\xdf\xc0\xa8\x7c\xc8\x0b\xfa\xbd\xa5\x03\x7a\xaf\xe1\x1b"
+  "\xcc\x6b\x0d\xb0\x57\x71\x3f\x25\x2c\x51\x27\xe9\xa6\xa8\x0c\xd0"
+  "\x61\xb7\xf3\x34\xe8\xb3\x43\xe8\x89\xf5\x27\xd9\x8e\xaf\xb7\x4c"
+  "\xf3\x9d\xd8\xeb\x49\xf4\xf7\x07\x5d\x3b\x30\xfe\xdf\x99\xaf\xf2"
+  "\x43\xe0\xd7\x76\x54\x68\x34\x01\xef\x3f\x93\xfa\xea\x1d\x0d\x5a"
+  "\x9e\xa9\xe5\x49\xb2\xf1\xe4\x1e\x1a\x57\x3e\x36\x30\x40\x3e\xe6"
+  "\xa6\xd1\x09\x2c\xc6\xfa\x3c\x97\xe6\x71\x72\xb9\x79\x46\x4a\x79"
+  "\xc6\x83\x1d\x98\x75\xc9\x43\x97\xb0\x94\xc0\x8f\xa8\xcd\xac\xf1"
+  "\x49\x61\x67\x3c\x40\xfb\x54\x26\x5d\xc6\x6a\x53\x79\xc6\xca\x88"
+  "\x6b\xd1\xcd\xb4\x4e\x9a\x1c\xdf\xd6\x99\xc2\xdf\xd4\x85\x5d\x99"
+  "\x37\xef\x91\x31\x59\x02\xf5\xb3\x78\x37\xbe\xe9\xc1\x37\x3e\xfc"
+  "\x28\xfe\x42\x47\x3f\x7b\xe2\x07\xb8\xb6\x9b\x74\x7c\x8f\x09\x23"
+  "\x79\x43\x99\x88\x51\x49\x34\xba\x83\x27\x82\xc7\x9c\x10\xba\x80"
+  "\xf8\xa8\x2e\xe0\x89\x12\x8c\xdb\x8c\x3b\xb7\xf1\x57\x51\x56\x7b"
+  "\x64\x4c\x69\x6f\x3a\xc9\x98\xaa\xf3\x3e\x8a\x39\x7a\x74\xfe\x0e"
+  "\x66\x51\x6d\x45\xf5\x1d\xe1\x76\xa2\xc5\x74\xb6\xba\x0d\x75\x1e"
+  "\xc2\xaf\xd5\xba\x96\xc5\x9d\x64\x4f\x1c\x21\xfe\x23\xca\xc3\xfe"
+  "\xec\x0e\x55\x1e\xf1\x5c\x8f\xef\xb7\x3c\x48\x38\x31\xa0\x0f\xa3"
+  "\x7c\xf0\xfc\xed\xde\x82\x76\x61\x0b\x43\xb6\xd8\x94\x07\x75\xd8"
+  "\xbc\xa1\x76\xa6\x70\x8b\x1e\xcf\xad\x64\x5b\xc8\x91\xb7\xd3\xd1"
+  "\xcd\x3a\xed\x21\xd0\xd8\x0e\xf0\xc0\xb6\x74\xb4\x47\x94\x87\xf7"
+  "\x47\x5f\xc0\xf8\x5a\xc1\xef\xa1\xbc\x2e\xb2\xad\xa1\x33\xca\x7c"
+  "\xbd\xed\x5f\xf0\x7d\x1b\x64\x68\x3d\x95\x7f\x92\x3d\xf9\x2e\x1f"
+  "\xb1\xd9\x6e\x18\x92\x31\x1b\x7b\xd9\x93\xfb\xd1\xce\x79\x31\xed"
+  "\x5c\x80\xf6\x1b\x40\x57\x3d\x28\xf3\x10\x2f\x46\x9d\x7d\xa8\x13"
+  "\xf2\x08\xf0\x37\x1d\xf2\xae\x81\xda\xdc\x49\xed\x75\x44\xc8\xfe"
+  "\xd5\xb0\xfd\x14\x33\x60\x2e\x78\xf6\xe0\x8a\xfe\x1f\x00\x4f\x96"
+  "\x16\x74\x3d\xe9\xd1\xce\xb9\x13\x2f\x81\xe7\x2e\x0d\x97\x6a\x91"
+  "\x07\x6d\x6c\x45\xbb\x0e\x25\x0f\x31\x92\x71\xe2\x81\xa7\xf1\xa8"
+  "\x77\x26\xc6\xaa\x15\xb0\xfb\x2d\x60\x7d\x88\xfa\xa4\x8c\x29\x03"
+  "\x0a\xca\xdb\x3e\x86\x36\xad\xb7\x18\x92\xfa\x28\xa6\x75\x90\x03"
+  "\xde\x47\x97\x3a\x82\x9c\xec\x64\xd1\x67\x82\x77\x2d\xfa\x6a\xf0"
+  "\xb1\x9f\xad\x21\x79\xa3\x9f\x3d\x59\x24\x63\x4e\x3e\xe9\x50\xf7"
+  "\xb4\x8e\x4a\x3d\xd3\x13\x47\x08\xf6\xd4\xaf\xa4\x72\x73\xa5\x77"
+  "\xc0\xcf\x92\xfa\x2e\xc1\xfa\xf6\x84\xbf\x51\x21\x1e\xe5\x67\x93"
+  "\xfa\xff\x69\xe6\x58\xc8\x0b\xfa\xa2\x8c\xf1\x01\xe2\x3d\xa5\xbd"
+  "\xcb\xcf\xf6\xe7\x38\xe2\xb2\xc0\x67\xea\xd1\x4e\x3a\xab\x31\x0b"
+  "\xeb\xf4\x6d\x64\xcf\x84\xf6\x41\xee\xf8\x59\xc7\xb9\x62\xbd\x02"
+  "\x3e\x16\xe4\xf1\xa3\xed\x22\xa6\x1f\xc5\xc2\x94\xba\x9e\x06\x83"
+  "\xe6\x6f\x80\x8f\xf1\x92\xed\xa5\xa2\xde\xb2\x8a\x62\x51\x07\xc5"
+  "\xff\x1c\x28\xb2\xf2\x4f\xda\xac\xfe\x69\xf5\x6e\x31\x76\x3c\x7e"
+  "\x35\xa6\x98\xd8\xd3\x3c\xd3\x8e\xa7\x61\x4d\x8c\xdc\x48\xfb\x9a"
+  "\x65\xb4\x77\x2b\xfd\xc2\x34\x08\x5b\xcc\xa5\x0e\xe9\xff\xc2\x1b"
+  "\x1a\x52\x79\xcb\x86\x83\x22\xce\x10\xf1\x35\xc2\xf6\x67\x50\xb5"
+  "\xd7\x69\xf8\x2e\xd5\xd1\x76\x56\x2c\xe3\xfc\xb5\x2b\xef\x5b\x93"
+  "\x2f\x55\x29\xd7\xfd\xa4\x68\xe5\x8f\xcf\xe4\x7f\x0d\x42\x2e\x76"
+  "\x35\xb4\x49\xdd\x64\x43\x38\x86\x4f\x34\x4c\xea\x96\xf4\xec\x80"
+  "\xd4\x2f\x3d\x95\x36\x95\x7e\xe9\xdb\x3f\x5e\xbb\xae\x50\xd4\x21"
+  "\x4c\x9b\xf2\xe5\xe9\xa7\x44\x76\xcf\xe2\x6f\x2f\xbe\x6e\x7d\x7e"
+  "\x91\x08\x1e\x22\x95\x39\x2b\xf3\xf2\x0a\x55\xc3\xa7\xd5\xf4\x15"
+  "\xbd\xb9\x7f\xa3\xf8\xd4\xfe\x40\x91\x34\x99\x5a\xbf\x66\x65\x71"
+  "\xbe\x5a\x44\x6c\x5b\xd3\x88\x5e\xb6\x35\x0a\x99\x39\x51\xee\xd3"
+  "\x3e\xb5\x3f\x66\x5f\x27\x56\x8e\x9c\x8d\x77\xed\xda\x3b\xfb\x95"
+  "\x84\x2b\x3b\xaf\xeb\x6c\x16\x3e\x1b\x0c\x87\x7f\x4e\xf0\xdd\x49"
+  "\xfb\xc4\xf1\xb4\x66\x2b\xfa\xa7\x6c\x4d\xea\x59\xa6\xa0\x6b\x27"
+  "\x8b\xea\x06\x76\x1f\x52\x6d\x1f\xfa\xa8\x3e\xaa\x1b\xef\xad\x31"
+  "\xf6\x00\x7d\x3e\xf6\xd4\x00\x95\x41\xfb\xd6\x22\xbe\x04\x78\x22"
+  "\xf5\x2c\xbb\xbe\xf3\xe7\xb4\xb6\x34\xce\x27\x3a\xaa\xb8\x47\xcd"
+  "\x72\x1e\xec\x5a\xc9\xab\xfd\x9f\xdf\x10\x60\xa9\x92\x0e\xec\x7c"
+  "\x1e\xe9\x17\x9f\x64\x3b\xdd\x48\x1f\x00\x2d\x89\x27\x7e\x44\xea"
+  "\xbf\x77\x3e\xaf\xea\x0a\xa8\xcf\xf1\x31\x6d\xd8\x1b\xd5\x27\xec"
+  "\x3e\xe4\x4f\x18\x35\x57\xc8\xfd\x7e\xb1\xb7\x29\xf7\x97\x77\x4e"
+  "\xf6\x9f\xa3\x6e\x75\x3f\x2f\xb5\x1f\xf9\x79\xd5\xa8\x59\xdd\x63"
+  "\xa3\xbe\x67\x51\xbf\xa5\x9d\xd6\xce\x70\x2c\x5f\x2b\xfd\xf9\xfb"
+  "\x3f\x27\x5e\x58\xca\x01\xbb\xae\x11\xbc\x0b\xe9\x2e\xc6\x09\x86"
+  "\xbb\x6e\xc5\x7b\xac\x5f\xbb\x32\x7d\xac\xa1\x3b\x16\x66\x45\x0e"
+  "\x2c\xf0\xf8\x8e\xd6\x33\xb4\x69\x26\xf2\x64\x47\xdb\xbc\x4b\xf8"
+  "\x89\x20\x59\x41\xf2\x15\xbb\x4e\x88\xf8\x63\x01\xf4\x4f\xb5\x19"
+  "\x20\x98\xcb\x78\x04\xbb\xea\xb5\xef\x94\xc4\x51\xb2\xd7\x20\x3a"
+  "\xdb\x27\x61\xb7\xeb\xed\x38\xdd\x27\x62\x0f\xf4\x86\x10\x6b\x46"
+  "\xda\x0c\xa4\xbd\x4e\xf9\xa8\x1d\x42\x57\x81\xf6\x53\x7d\x0a\xf8"
+  "\xe0\x38\xcb\x8c\x5b\x51\x9e\x0f\x74\x26\x3d\x3a\x7e\xbb\xf6\x45"
+  "\xf5\x43\x4f\xdd\x2b\xf5\x43\x8d\x06\x0d\x0e\x14\x47\x48\x9d\x0b"
+  "\xf1\xda\x7e\x39\xde\xa7\xc7\xc2\x5f\xd0\x39\x15\x9e\xdc\xf5\xd4"
+  "\xfa\xa8\xdc\xd5\x78\xe7\xe4\x5e\x11\xda\x11\xa5\xf5\x8d\x0f\x11"
+  "\x1c\xa9\xdd\xf6\xcd\xa4\x4b\xde\xbd\x57\xf4\x43\xee\xc7\xfc\x09"
+  "\x63\xf4\x04\x07\x5f\x40\x6b\x24\xc9\x00\x34\xbe\x94\x57\xc6\x18"
+  "\xda\x7d\x57\x93\xd4\x79\x3e\x89\xfb\xef\x2a\xfa\xa9\xf0\xa3\xb1"
+  "\x2d\xd6\x3e\x50\xc2\x78\x77\x92\x42\x65\x02\x7e\x54\x16\xd6\x8d"
+  "\x49\xbb\x67\x59\x6e\x63\x04\x65\xfe\xac\x3f\xda\x1f\x3f\xaf\x56"
+  "\xe1\x48\xe3\x28\xe0\xb2\x1b\xf3\xbf\x41\xe8\x6d\x9c\xcd\xfc\xc4"
+  "\x3a\x94\x21\x63\x7f\xee\x5e\xc4\x69\x6c\xd4\xfc\x7e\x92\x9d\xd0"
+  "\x76\x79\x76\x0b\xf8\x06\xf9\x83\xda\xa9\x54\x8f\x1a\xa9\xed\xb4"
+  "\x0f\x10\x95\x87\x77\x3f\x44\xdf\xfa\x1f\x96\xdf\x6c\x97\xfb\x14"
+  "\x18\xdb\xc6\x67\xf9\xc6\x02\xa6\xea\xc7\x41\x8f\x1b\x53\x09\xb7"
+  "\xa9\x9c\x80\x90\x8b\x76\xbb\x15\xc0\x05\x63\x4a\xed\x3a\xa0\x8d"
+  "\x29\xf2\xd9\xa7\xe3\x63\xa5\x5f\xfe\xdd\x3e\xcd\xf7\x0b\xad\x29"
+  "\x98\xa7\x2a\x0f\xd8\xf4\xb4\xa9\xfc\x36\x6e\x0a\xdf\x7c\x33\xf1"
+  "\x34\x7b\xf4\x42\x56\xd1\xec\xdf\x2e\x07\x9c\xbe\xd0\x6c\x81\x95"
+  "\xad\x3f\xec\x26\xdb\x41\x6f\x48\xda\x0e\x52\xfa\xdd\x01\xae\x74"
+  "\x06\x22\x64\x9f\xdf\x1d\x74\x35\x2d\xd6\xe4\x17\xa2\x4b\x71\xe5"
+  "\x3a\xb4\xb1\x09\xf8\xff\xf8\x7e\x95\x1e\xcd\x1c\x64\x4d\xe5\x6a"
+  "\xf9\x31\x6d\xd8\x1d\x96\xf2\x5f\x53\xb3\x94\x83\x9a\x6a\x40\x5f"
+  "\x2a\xa4\x1c\xd4\xd4\xa0\xb5\x1b\xef\xf3\xce\xee\xe3\xb2\xdb\xbf"
+  "\x9d\x6f\x5d\x43\xa4\x35\xe3\x26\x87\xd5\x76\x75\xde\x0d\xc2\xd8"
+  "\xd4\xfa\xef\xb7\xdf\x62\x5d\x76\xeb\xd5\x8e\x82\xf9\x77\xcb\xcb"
+  "\xed\xcb\xee\xa4\xeb\x59\x7b\x8f\x56\x94\x1f\x3a\x53\xce\xda\xab"
+  "\xb6\x61\x8f\xd9\xa7\xb3\xc9\xb5\xd0\x78\x7c\x21\xc5\x57\xc7\x5a"
+  "\x38\x44\xfc\xed\xd2\xc8\xc7\x9c\x57\xbd\x5f\xc6\x13\x8e\x2f\xf4"
+  "\x27\xcf\xcd\xc6\xcf\xea\x4f\x18\x4e\xa2\xf8\xeb\xa6\x72\x1e\x32"
+  "\x85\x67\x4a\x7a\x88\x67\xf0\x12\x03\xe0\x57\x68\x2c\xd9\x1d\xd7"
+  "\x38\xf9\xd2\x08\xf7\x82\x6f\x01\x5c\xf6\xd8\xb5\xf5\x57\xe8\x8e"
+  "\xdc\xc7\x17\x2e\x75\xf0\x09\xc2\x1d\xac\xeb\x46\x5e\x85\x3a\xe3"
+  "\x48\xd7\xb5\x07\xfd\xdf\x61\x95\xb0\xd8\x03\xfa\xb7\xbb\x5d\x85"
+  "\xef\x32\x3c\x53\xfc\x1b\xb9\x97\xe7\xb2\x08\x1a\xaf\x6c\xbd\xf6"
+  "\x7b\xe0\xe1\xad\x5a\x99\x28\x2b\x49\x3d\x0b\x23\xca\x63\xe7\x38"
+  "\x4b\x1d\xfb\x53\xaa\x87\x32\x49\xe7\x40\xe7\x17\x4d\x0e\x1d\xc5"
+  "\x07\xca\x9e\xd4\xb3\xe0\x5d\x4a\xb9\x99\x74\x2f\xd9\x29\x01\x5d"
+  "\x19\xe5\x89\xea\x23\x14\xdf\x76\xbd\x12\x02\x1f\x60\x96\xb1\xd0"
+  "\x87\xd4\xfd\xd8\xe6\xdc\x49\xfd\xfe\x19\x63\xdf\x2c\xf0\xe1\x94"
+  "\xcb\x00\xdc\x6e\x1a\xb8\x32\x55\xf2\x3c\x8a\x4b\xc7\xe4\x59\xf6"
+  "\xe6\x7b\xc4\xbc\x54\xf1\x11\xf0\xf5\xd3\xde\x9b\x29\xcc\xfd\x64"
+  "\xa7\xae\xc4\x01\x27\xd9\x20\xf3\x96\x04\xcb\x28\x06\xf9\x24\x5e"
+  "\xda\x81\x97\x76\xe0\x25\xed\x93\xa2\x7e\x7f\xdc\xb5\xb9\x98\xb3"
+  "\xba\x41\xd6\x9c\x4e\xed\x27\xd8\x80\xef\x4e\x52\x00\x2b\x61\x0f"
+  "\x47\xf0\x49\x3c\x71\x80\xce\x45\x51\x5f\x4d\x61\x1d\xc9\x34\xd1"
+  "\x7e\xe9\x15\x5f\x9d\x0b\xfd\xd2\xa3\x5f\x8e\x13\x42\xde\xa7\xf3"
+  "\x6a\xa0\x25\xb3\xa2\x31\x26\x9e\x5e\x1c\xdb\x47\x85\xe2\xd2\x88"
+  "\x3e\x3c\x9d\x3f\x55\x1f\xb9\x9e\xfa\x48\x30\x78\xfa\xeb\xea\x3e"
+  "\x89\x68\x27\xd1\xad\x21\xd6\x1c\x4a\x29\xa7\x73\x62\xc7\x17\x82"
+  "\x5f\xbd\x9d\xc6\xb0\xc9\xc5\xeb\xa9\x9d\x53\x8d\x17\x95\x27\xcb"
+  "\xfa\xb9\xc1\x54\x5e\x96\x8b\xb6\x74\x4d\x0d\xef\xa7\x87\xcf\x0d"
+  "\xef\xa7\x5f\xa7\xef\xa9\x1d\x74\x6e\xce\x44\x0e\x90\x80\xdf\x90"
+  "\xb1\xdc\x53\xd5\x9b\x52\xde\x4c\xed\x9a\xf2\x1d\x70\x7f\x68\x7b"
+  "\xe1\x99\x73\x42\x69\x0a\x31\x82\xdf\x1e\xa4\x4b\x5d\xea\xcf\x1d"
+  "\x93\x3a\x5f\xf7\xf1\x5c\x93\xce\x1a\x47\x73\x4c\xf0\xb2\xe8\xef"
+  "\x54\xe5\x9a\x74\xf5\xe4\x43\xed\x76\xd0\xaa\x29\xdf\x63\x1e\x58"
+  "\xf9\xd6\xaf\x5d\x89\xf2\xd2\x53\xca\x75\xdc\x1f\xf7\xb5\xc4\x94"
+  "\x40\x38\x9d\xe0\x8a\xb6\x3a\x30\xc7\x6b\xc5\xfa\x2c\x74\x10\x3f"
+  "\xc7\xfc\x7f\x21\x57\xe8\x72\x13\x8e\xa7\x4b\xbb\x82\x5f\x24\xf9"
+  "\xd8\xef\x7d\x51\x1b\xa1\x5f\xa4\xf9\x74\x09\x6d\x72\xae\x5e\xb6"
+  "\x13\x6b\x5a\x9b\xe2\x32\x71\xeb\x66\x13\xef\x67\xbf\x78\x51\xe1"
+  "\x36\x3d\xd6\xad\xb6\x28\xee\xc8\x73\x75\x1a\xee\xe0\xfb\x15\x53"
+  "\xe3\xc5\x2f\xb6\x9c\x1b\x2f\x7e\xf1\x5d\x55\x47\x97\x2b\x6d\xf7"
+  "\x7e\xb1\x57\x93\x15\xf8\xd6\xcb\x76\x5a\x4b\x45\xfd\x0b\x65\xdd"
+  "\x80\x49\x38\x8b\xe8\xcc\x9d\x80\x5b\x19\xf2\x76\x69\xb4\x81\x70"
+  "\xc8\x14\x21\x39\x86\x09\x3c\xc7\xbb\x21\xd0\x1e\x19\x23\xbb\x7a"
+  "\xf8\x00\xf1\x98\x8a\xab\x69\x3f\xd6\xaf\x5d\x64\xbb\x1e\x48\x38"
+  "\xbe\x37\xe8\xda\x6b\xf6\xb1\xfe\x0a\x95\xfe\x35\xa2\x8c\x66\x61"
+  "\x0b\x22\xcf\x83\x26\xd1\x3c\xa7\x38\x66\x34\xd7\x91\x96\x8a\x76"
+  "\x53\x4c\x33\xf0\xf6\x7b\x97\x68\x6b\xbf\xe2\xca\x22\x78\x0b\x3e"
+  "\x43\x4f\x7c\x2c\x60\xf7\x84\x5e\xd9\x37\x76\x83\x85\x51\x9f\xc7"
+  "\xb6\xce\xd9\xf7\xd3\xeb\x99\xe1\xcf\x96\xfb\x98\xfd\x26\x96\x5a"
+  "\xfe\x6f\x06\x06\xec\xd6\x13\x1c\x7c\x6c\x6f\xb6\x84\xdd\xde\x06"
+  "\x6d\x7c\x7c\xec\x17\x82\x8e\x92\xee\x7c\x69\x98\x8f\xc8\xbd\x80"
+  "\xbd\xad\x3e\xf6\xa8\xba\xe7\xb5\xc7\x30\xc5\xfa\x70\x87\x75\xf5"
+  "\x7a\x6b\xde\xba\x8d\x6b\xaf\xb8\x22\x71\x0a\x19\x60\x6f\x87\x94"
+  "\x01\x7e\xc9\x62\x65\x00\x3c\xa3\xff\x4d\xbe\xb3\x79\xfe\x3b\x73"
+  "\x54\xf7\x07\x39\x19\x2c\x7a\x7f\x23\xbb\xf3\xc6\x98\xc7\x9b\xd9"
+  "\x9d\x37\xdd\x9c\xf3\xbd\xfc\x95\x79\x9b\x62\x52\x17\xc4\xea\xe7"
+  "\xb6\xef\x44\xdd\x71\x73\xbe\x05\xfa\xa1\xbb\xfb\x61\x5a\x77\x7e"
+  "\x39\x5a\x1a\xe6\x9f\x03\x77\x17\x92\xcf\xa1\x23\x45\x61\x76\x04"
+  "\xf4\x8d\x5f\x46\x74\x7d\xa6\xf4\xbb\x09\xf9\x1f\xb8\x65\x42\xdf"
+  "\xfd\x90\xc5\x46\xa5\xed\xf6\x33\xb3\x3b\x1b\x42\xa0\x13\xc3\xa9"
+  "\x92\xdf\xf9\xe5\x51\xa4\x5f\x88\x6b\x44\xda\x9f\x3c\xa3\x83\x9c"
+  "\x9b\x25\x7c\x2c\x14\x93\x8f\x85\x5f\x8a\x35\xe0\xfa\x40\x19\x93"
+  "\xbe\xbe\x7e\x59\x43\x3e\xb8\x7d\xec\x99\x45\xc4\x5f\x50\x5e\xa4"
+  "\xbd\x6b\xfd\x09\xcb\xa0\x2b\xf1\xbc\x3e\x94\xc9\xab\x86\x53\xf9"
+  "\xae\x6c\xda\x93\x4f\x47\x99\x5f\x27\xbe\x2d\xce\x32\x33\x18\x74"
+  "\x3d\xb3\x50\xe3\x41\xc8\x4e\x74\x3a\xfe\x43\x5b\x07\x53\x40\xbf"
+  "\x53\x02\x26\x9e\x43\x3e\x4b\x74\x2c\x9d\xd6\x07\x93\x63\x99\x38"
+  "\x5b\x44\xeb\x22\xd1\x84\x26\x41\x4b\x9f\xa9\xd7\xe8\x42\x9d\x94"
+  "\x23\x13\xe9\x7b\xac\x9f\x5f\xc8\xf5\xf3\x99\x16\x6d\x2e\xe0\xfe"
+  "\x90\x86\xab\x67\x9c\x4f\x59\x5b\x94\x5f\x98\x9f\x67\xbd\x7a\x7d"
+  "\x22\x8b\x89\x10\x59\x90\xbf\xd6\x5a\x98\xff\xd0\x86\xfc\xf5\x42"
+  "\x40\xa3\xb7\x67\xee\x8d\x80\x06\x45\xe3\xf5\x8a\x33\x32\xbf\xba"
+  "\x82\x64\x58\x53\xf9\x15\x42\x0f\x2e\x78\xa3\xa4\xcc\x06\xa5\x2e"
+  "\x39\x4b\xea\x11\x07\x01\xd7\x7d\xd2\x1f\xb5\x7b\xd8\x40\x7c\x5c"
+  "\x3f\xdb\xb7\x40\xee\xb5\xff\xea\x41\x09\x2b\xa3\x33\xe8\xfa\x55"
+  "\x5e\x94\x5f\xdb\x27\xec\xff\xa4\xcd\xdb\xaf\x4a\x00\xe3\x15\x51"
+  "\x1e\x64\xdf\x67\x44\x07\x05\x3d\xfc\x0a\x5a\xa8\xf2\xce\xa8\x67"
+  "\xdf\x35\xbc\x98\xf7\x6d\x1f\x67\x42\x8f\x47\xbe\xdb\x25\x7d\xfd"
+  "\x55\xb7\x06\x47\xf0\x2f\x7d\xa4\x2f\xd0\x64\xa0\xa5\xe1\xd3\xbc"
+  "\x74\x13\xd3\x93\xce\x80\x27\x0e\x5b\x7e\x53\xe8\xd7\x73\xd7\x33"
+  "\xed\xe0\x65\x48\x27\x14\x68\x52\x6d\xbf\x78\xc2\x30\xe0\xbd\xcf"
+  "\x1a\x95\x0f\xf7\xf5\x09\x3e\x7e\x9c\xf0\xe6\x57\x6d\x39\xb4\x46"
+  "\x48\xda\x7d\xc1\x57\xb5\x97\x27\x4a\x5d\xb9\xa4\x6f\xfb\x72\xd5"
+  "\x3e\x0c\x11\xcd\x52\x6d\x07\xf5\x12\xaf\xf7\xf5\x01\xe7\x0c\x34"
+  "\x16\xa0\xf3\x6e\x0d\x5e\xd4\x5f\x21\x77\x6e\x61\x7a\xd0\x2e\xcb"
+  "\x0b\x9b\x43\x7a\x19\x5b\xf1\x99\xa3\x52\x86\xd9\xd7\x1e\xbb\xe7"
+  "\x23\x65\xa9\x7d\x3d\x51\xbf\x06\xbf\xfa\xd2\x99\x94\x75\x6b\xe9"
+  "\x38\xca\x03\x39\x1b\x57\x3e\x90\x9f\xb3\xc1\x3e\xdf\xba\x61\xad"
+  "\xd8\x52\x13\xe2\x7b\xd1\x86\x55\x0f\x58\x89\x8a\xe4\x2c\xbe\xf3"
+  "\xce\x9c\x6f\xdd\xf3\xfd\x1f\x24\xb2\x6f\xad\x44\x5a\xd1\x3a\xeb"
+  "\x9d\x19\xf3\xe5\xab\xef\xdd\x71\xfb\x7f\xe6\xdc\xbe\xf4\x9e\xbb"
+  "\x97\x4f\x61\xd3\x9a\x04\x9c\x20\x79\x2f\xbe\x97\x3d\x97\x29\x6d"
+  "\x18\x9e\xb5\x9f\x69\xc3\xf0\x2c\xd6\xcf\x67\xf7\xe2\xe7\x61\xec"
+  "\x39\x48\x33\xcf\x65\xe2\x67\x53\xf1\x66\x22\xe8\x7a\xb6\x31\x8a"
+  "\x37\xcf\x09\xff\xba\x24\xf3\x4b\x9d\xe9\xb3\xa0\x7f\xcf\x04\x62"
+  "\xdf\x45\x69\xc1\xaf\x7f\x29\xe8\xa5\x8a\x17\x84\x0f\x39\x61\xa3"
+  "\xc0\x0d\xc9\xaf\x3c\x1b\xd0\x70\x43\x9c\x93\x43\x3a\xe9\xba\xe8"
+  "\x3d\xf0\xbb\x82\xf4\xc2\xc0\x05\xb1\x9f\x49\xe9\x3c\x39\xb3\x42"
+  "\x2d\x77\x3e\xe9\x89\x89\x9f\x55\xf7\x3d\x52\x06\xd9\xaf\x57\x73"
+  "\xd7\x3e\xbf\x94\x05\x9f\xbd\x42\xe0\xcd\xd6\x39\xdf\x12\xfb\x47"
+  "\xe2\x3c\xc2\xaf\x73\xa3\xf8\xf3\x5c\x26\x8d\x0d\xd1\x05\x49\x7b"
+  "\x7f\x5d\x72\x96\xfe\x25\x0e\x69\xf5\x9a\x1f\xec\xa2\x2b\x98\xde"
+  "\x70\x45\x3d\xdb\xa1\xe7\x65\x3e\xf6\xeb\x2c\x69\xc7\xf6\xeb\x16"
+  "\x8d\x7f\xc6\x3d\xe6\xff\xa7\x59\x67\xeb\xad\xea\x62\xf4\x56\xa5"
+  "\x76\xfe\x49\xa7\xdd\x4f\x3c\xb2\xc7\xeb\x17\xfe\x17\x6f\xeb\xb4"
+  "\x07\xc8\x67\x5f\x62\x3f\x7b\x2e\xde\x19\xe1\xe3\xb8\x9f\x83\xbe"
+  "\x89\x35\xe4\x06\xa9\x37\x80\x3c\xf6\xdc\x02\x29\x9b\xc8\x74\x82"
+  "\xbb\x8f\x3d\xbb\x9f\x64\x33\x1a\x1f\xdc\xd7\xc7\x59\x12\x6e\x99"
+  "\x8a\xee\xa5\x94\xeb\x55\x3f\x37\xcf\x55\x91\x8c\x4a\xb0\x7a\x5c"
+  "\xaf\x14\x3c\xee\xc2\x0f\x57\xa2\x7d\x51\xfe\x92\xab\x7b\x0d\xcf"
+  "\xb9\xdb\x1c\x43\xb4\x6e\x86\xa6\xb5\x2f\x2c\xe6\x3d\xda\x78\x2e"
+  "\x8d\xf8\x6f\xa3\xf1\x0a\xba\x9e\xf3\x68\x63\x39\xf2\x2f\x8f\x76"
+  "\xc5\x95\x33\xeb\xe1\xc6\x9b\x28\x1d\xf3\xff\xb9\x2c\xd5\x7e\x32"
+  "\x70\xf6\xb7\xa0\xc3\x59\xf2\xfb\xfd\x4c\xfb\xfe\x6c\xff\xa9\xe2"
+  "\x80\x1f\x29\xa7\x6e\x11\x2a\x2c\x9b\x1a\xee\xf6\x8c\xb3\x3a\x74"
+  "\x06\xb3\x4d\xe2\xa4\xa6\x3b\x33\xcb\xfe\xec\x3f\xad\x54\x43\xfe"
+  "\xae\x1e\x98\xa3\xea\x01\x30\xb7\xf7\xef\xbe\x9e\xb1\x35\x81\x8d"
+  "\xd9\x93\x7a\x12\xd2\x2f\x90\x4f\x34\xb4\xc3\x1d\xa3\xdb\x9a\xb4"
+  "\xf1\xf2\xb1\xfd\x21\xb2\x39\x41\x39\x69\x54\x0e\xcd\x2b\xa9\x9b"
+  "\xd9\xdf\x4a\x3e\x74\x50\xde\x5a\xb1\x77\xe9\xda\x6f\x16\xb8\x07"
+  "\x59\x5b\xc8\xf9\x25\xfc\x73\xd5\x06\x42\xf0\x2e\xf2\x3c\xcf\xfe"
+  "\xa1\x49\x7d\x8f\x38\xdb\xb2\xbf\x80\xec\x3a\x83\xae\xe7\x0d\x53"
+  "\xe9\xf9\x40\x1f\x0a\x56\xae\xcd\x5b\x77\xff\xfd\x5f\x4d\x1a\x62"
+  "\x6d\x2d\xeb\x5d\x8a\x1b\x65\x42\xfe\xdd\x91\x2d\xf1\xf4\x79\xd0"
+  "\xff\x6a\xc9\xeb\x82\x87\xc1\xbc\x99\x3b\xc8\x9e\xf7\x68\xfc\xbb"
+  "\x9c\x47\xcf\x77\x70\xd7\xf3\xe6\xe8\xdc\x78\xbe\xe1\xcb\x73\xe3"
+  "\xf9\xfd\x53\xcf\x8d\xe7\xbb\xb0\xce\xf6\xe0\x7d\x07\xea\xec\x10"
+  "\x34\x9f\xc6\x5b\xf2\xe0\x1e\x53\xf8\x36\xc1\x83\xe7\x6c\x62\x3a"
+  "\xe2\xbf\x49\xa7\x4c\xeb\x41\x04\x72\x6d\x04\x34\x22\x27\xcc\xcc"
+  "\xb4\x16\x6c\x5f\x4b\xfa\xc2\xcb\x79\x78\x8c\xfb\x72\x36\x81\x5e"
+  "\xe0\xb9\x6e\x50\xee\xb3\xde\x3b\x0a\x39\x04\xf7\xdb\xfb\x89\x56"
+  "\x28\xe4\xac\x9d\xc9\xf5\xfa\x37\x59\x1a\x8f\x6b\x2a\xb7\x0a\x1f"
+  "\xbe\x62\xdd\x06\x9e\xd1\xba\x9d\x13\x31\x79\xe4\xba\xfd\x9b\x82"
+  "\x73\xea\xa6\x93\xe7\x66\x4d\x95\x8e\x36\xb6\x51\xbb\xd0\xce\x16"
+  "\xb4\xeb\x00\xb5\xa7\xee\x7e\xea\x57\xdc\xcd\xa6\x70\x86\xd8\x1b"
+  "\xa0\x76\xde\x1b\x60\x37\x53\xfb\xee\x7d\xe8\x66\xd6\x74\x3f\xed"
+  "\xef\x4a\xbb\x1e\x15\x97\x0c\xc0\x99\x99\xfd\xec\x85\xb4\x80\x88"
+  "\xa9\xf8\x1b\x8c\xbd\x51\xf2\xf5\xea\xde\x09\xe5\xa1\x77\x12\x4f"
+  "\x5f\x48\x3b\xec\xa0\x36\xbf\x90\xa6\xe5\x8b\x6d\xdb\xed\x2b\xed"
+  "\x60\x2c\x57\xdf\x7f\x7f\x7e\xe1\x7a\x2d\x3e\xb4\x6d\xdd\x9a\xbc"
+  "\x5b\xd5\xf3\xae\x6b\xf3\x37\xe6\xac\xce\x13\xf6\xf4\x48\x95\xb7"
+  "\x67\xf1\x1a\xf3\x49\x16\x10\x36\xaa\x82\xcf\xf8\xdd\xe9\x26\x95"
+  "\xe7\xe8\x65\x2d\x6e\xb9\xff\xdc\xf2\x4d\xb9\x0e\x5c\xf0\x10\xda"
+  "\xb1\x57\x5b\x07\x48\x1f\x31\xc2\xae\xb0\xd1\xbe\x10\x9d\x61\xa6"
+  "\xfd\x27\xd2\x49\x20\x4f\xbb\x8f\xfd\xa6\x48\xc3\xed\x5a\xa4\xd3"
+  "\xb9\x09\xcf\x5a\xb2\xb5\x3b\x30\x5b\xa9\x3a\x9e\xca\x13\xdf\x6b"
+  "\x07\x0d\x48\xa2\xb5\x81\xf6\x43\xa4\x3f\xfe\x96\x54\xa2\x6d\xa4"
+  "\x37\xf3\xac\x25\xdb\xb5\x17\xfa\xb0\x96\x83\x07\x3e\x90\x06\xb9"
+  "\x28\xb5\x62\x33\x33\x52\x1d\x58\x37\x7c\x52\xcf\xda\x92\xf1\x5a"
+  "\x09\x63\xea\xda\xe1\xab\x15\x3a\xc5\x17\xa4\xcf\x44\xf7\x71\x9b"
+  "\xaa\x73\xb0\x21\x1f\xf0\x3f\x99\xc9\x36\xbf\xe7\x17\xfb\x5e\x82"
+  "\x2e\xb4\x94\xf0\xea\xee\x32\x61\x5f\x58\xfd\x9e\x5f\xe1\x05\x71"
+  "\xf4\x0c\xba\x9c\x88\x72\xf6\x72\xa7\x8d\xa9\x36\x89\x71\xfd\xec"
+  "\xb7\xf1\xb8\x1a\x30\x1e\x3b\x08\x16\x28\x3f\x53\x2d\x3f\x13\xe5"
+  "\x63\xfd\xbb\xac\x5e\xce\xaf\x96\x36\xad\x2e\xe0\xb6\xdf\x9f\xe0"
+  "\x0f\xd3\xfa\x85\xf6\x27\xe1\x67\x96\xfa\x99\x10\xe4\xa4\xcb\x27"
+  "\xf5\x33\x92\x47\x6a\x09\x6b\x38\x49\x75\xab\x7d\xc8\x20\x9f\x2f"
+  "\xa4\x4f\x50\xeb\xca\x20\x5d\x81\x56\x26\x47\x99\x7c\x6c\xa8\x19"
+  "\x6b\x8d\x11\x73\xcc\x9f\x52\x1e\xa6\x34\xb3\xe0\x71\x03\x97\x73"
+  "\xac\x39\x91\x9c\x88\x41\x9e\x37\xdf\xc4\x92\x63\xf9\xdb\xa0\xeb"
+  "\xb7\x6b\xa2\x3c\x19\xca\x18\x03\x2d\x2b\x65\x65\x7d\xec\xb7\xc2"
+  "\xff\x19\xd9\x73\xd0\xb8\x8e\x63\x9c\x30\x56\x5d\xa8\xa7\x05\x7c"
+  "\x79\x32\xe0\xf0\x2c\x8d\x57\x9d\x82\x39\x37\x2e\x78\x75\x13\xc5"
+  "\x4e\xef\x65\xbf\x7d\x82\xc6\x8a\xca\xe2\xee\xee\xe6\x70\x30\xfb"
+  "\x3f\xc8\x2f\x15\xc1\x7a\x4b\x09\x1f\xa0\x3d\x3a\xe0\xd6\x6c\xe2"
+  "\x61\xc1\xd7\x8b\x7b\x67\x1e\x57\xc4\x58\x0b\x3b\xc5\xdf\xcd\xde"
+  "\x32\xc0\x95\xd3\x2e\xc6\xdb\x41\x4b\x4f\xeb\x59\x38\x04\x19\x14"
+  "\xed\xd6\x3b\x4f\x90\xef\xac\x66\xcc\x2f\x37\x43\xbd\xc6\xba\xcd"
+  "\xcc\x4c\xbe\xc6\x9c\x76\x1e\xea\x0c\x34\xb2\x4e\x7b\x23\x7b\x33"
+  "\xbc\x83\x79\x8a\x49\xa7\xf9\x3b\xcf\x5b\x8e\x1d\x64\x17\x9e\x80"
+  "\xfb\x72\xeb\x7f\x52\x5d\xff\x9d\xfd\xd6\xd1\x77\xd8\x5b\x9e\x77"
+  "\x98\xf5\xbf\xc4\x73\x41\x47\xf6\x9b\xac\x23\xeb\x4d\xe6\xec\xe3"
+  "\x0a\xf1\x43\xa5\x0f\x52\x1d\x6e\x94\xd5\x4c\x3e\xba\xcc\xca\x88"
+  "\x25\x11\xfd\x37\x2c\x75\x30\xb1\x0f\xe8\x59\xfb\x12\xda\xf8\xdf"
+  "\xc7\x9a\x4e\x31\xa3\x67\xed\x9f\xc4\xbd\xd0\x2f\xa0\xbf\xde\xbc"
+  "\x6e\x61\x23\x46\x3e\xc9\xbc\x8e\x01\x3a\x5f\xa9\x6c\xa7\x36\x46"
+  "\x64\xbb\x01\x2f\x83\xf6\xfd\x9e\xd2\xc9\xef\x85\xaf\xd8\xdd\x04"
+  "\x0f\xb4\xe9\xc8\x72\x09\x93\x8e\x6e\xc0\xf4\x3f\x55\xf8\x64\xc7"
+  "\xc2\xe7\xbf\x8d\x04\x1f\xb2\xff\x54\x8a\x87\x9a\xd1\xb6\x2c\xc0"
+  "\x40\xd1\xea\x20\x1c\xa0\xfd\x2a\x2a\xbf\xee\x14\x4b\xf2\xac\x25"
+  "\xfb\xd0\xdf\x3d\x68\x5a\x66\x30\x2a\x63\x27\x5a\xb6\x8f\x32\x03"
+  "\x8d\x1b\xad\xb3\xdb\xc5\x7b\x01\xf3\x65\x34\x66\xfe\x84\x01\x23"
+  "\x7e\xc0\xcf\x01\x33\xe1\x1e\xae\xa9\x18\x2f\x37\xe0\x34\x80\xb1"
+  "\x6a\xa6\xab\xc4\xc7\xf7\x69\x3c\xcd\xb4\x96\x01\x57\xa2\xe9\xd5"
+  "\xef\xdf\x16\xc6\xdc\x51\x84\x9c\xf6\xdf\x03\x4a\x55\x20\x24\x6d"
+  "\x05\x5f\xb0\xed\x06\x5f\xdc\xf8\x98\x38\x8f\x9e\x04\x5e\x5e\xac"
+  "\x8b\x3b\xc5\xb9\x95\xdf\x4d\xae\x7f\xd5\x22\x96\xf9\xef\x2c\x7a"
+  "\x61\x13\x76\x7c\xbe\x8a\xeb\xf3\x83\xae\x03\x68\xcf\x2c\x55\xae"
+  "\x6e\x11\x67\x5a\x88\x0e\x4c\xc7\x93\x80\x2e\x77\x90\x8d\x1d\xbf"
+  "\x2c\x9b\x25\xe9\xb8\x3f\x29\xd7\xc4\xbd\xe1\x36\xc2\xa1\x24\x81"
+  "\xfb\xf2\x1d\xf8\x48\xbf\x09\xb4\xbc\x0b\xe9\x06\x2d\x9d\xe8\xba"
+  "\x02\xd9\x92\xe4\xda\xa5\x9b\x4c\xbc\x74\x94\xa5\x09\x1d\x91\x96"
+  "\xbe\xc9\x6f\xea\xb4\x30\xb2\xb9\x0f\x93\x1f\x0a\xfa\x06\xe9\x71"
+  "\x58\x07\x0e\xa1\x5e\x0f\xf2\xa7\x6a\xf9\xf9\x48\xb6\xc1\xeb\x68"
+  "\x13\xf3\x8c\x7c\x2b\x69\xeb\x02\xd2\xe3\x97\x3a\xfc\x26\x31\x66"
+  "\x5a\xda\xfa\x6c\xb1\x8e\xd1\x99\x77\xf0\xa9\x5c\xb4\xa7\x5f\xa4"
+  "\xeb\x20\x67\x8a\x58\xe9\x31\x69\x7a\xf2\x2f\x40\x7e\xf1\x62\xd2"
+  "\xe2\xd0\x66\x36\xf9\x8c\xba\xb7\xff\x44\xec\xd3\x5b\x96\x6e\xa2"
+  "\x3d\x31\xd4\xf3\x13\xb5\xee\x4d\x9c\x49\x7f\x9b\x32\x4d\xae\x99"
+  "\x2f\x16\xc5\xca\xb8\xb4\x47\x41\x75\x2b\x23\xd9\xfa\xc8\x48\x76"
+  "\x1c\xd5\x4f\x65\x91\x7e\x52\xc4\x6c\x0f\x0f\x30\xf2\xf5\xcc\x6b"
+  "\x33\x9b\x39\x9d\xb1\x40\xb9\xa2\x3d\x0e\xc8\xff\xc9\x0b\xac\x53"
+  "\xda\x47\xd4\x5c\x99\xed\x29\xfd\x2f\xe0\xf4\xef\x4b\x88\xa6\x44"
+  "\x8c\x43\xe9\xd6\x9f\x90\xdd\xc1\x8b\xa3\x34\xa6\x11\xcc\xf3\x48"
+  "\xc2\x50\xfa\x0d\x03\x4c\x57\x8a\xb9\x23\xf7\xea\x7e\x7f\x09\xf1"
+  "\x54\x4e\x85\x73\xdc\x1b\x09\x77\x4d\x43\x90\x5b\xaa\x86\x6c\xc2"
+  "\xde\x23\x65\xde\x32\x6f\x68\x80\x75\x94\x7d\xc0\x3a\xc2\xde\xb2"
+  "\x43\xa7\xfc\x06\x69\xf7\x61\x40\xb9\xbf\xbf\x86\xde\x39\x31\x5f"
+  "\x72\x22\xcd\xd3\xcb\x81\x90\x2d\x00\xbb\x8f\xe5\x5a\xf0\xfb\x12"
+  "\x4d\x9e\xf8\x8a\x3e\x1c\x25\xdf\x86\x64\x17\xa7\x54\x87\x69\xad"
+  "\x70\xf2\xa0\x8d\xdd\xb0\x99\xf4\xba\xbf\xdf\x9f\x12\x60\x59\x6a"
+  "\xb9\x5f\xa8\xe5\x1e\x3d\x57\xb9\x84\xb7\x1d\x0d\xd2\xd6\x42\x49"
+  "\x0c\xdb\x23\x28\x3b\x92\x18\x6e\xc1\x5a\xe3\x74\x9e\x26\xdd\x49"
+  "\xeb\x6c\xd4\x63\xef\x0c\x77\x31\xf2\x91\xda\xa4\x60\xbd\xfe\xc2"
+  "\xc2\x54\x1b\x17\xe7\x49\xf6\x87\x78\x85\xdb\xcc\x90\x73\x48\x57"
+  "\xea\x24\x3a\x4b\xba\xe7\xd2\x08\x9b\xe1\xc5\xc8\x92\x8f\x3f\x94"
+  "\x91\xfc\x3a\xe9\xa5\x41\xab\x22\xdc\xa2\x7f\x79\xcc\xc7\xb6\x83"
+  "\x7e\x0b\x9f\x7f\x5b\x2f\xdb\x99\x52\xce\x6e\xe3\x7a\x93\xb0\x61"
+  "\x52\x6a\xd3\xdc\x18\xdb\x7d\xa2\x3d\xd5\xc7\x17\xc5\xd8\xd3\xc4"
+  "\xa1\xae\x2a\xb2\xa7\xe1\xc6\xe3\x64\xa7\x12\xe0\x18\xb3\xa0\xeb"
+  "\x0f\x07\x7c\xec\x45\xc1\x97\xd4\x90\x1e\x40\xd0\xf9\xd6\x2b\xfc"
+  "\x09\xa1\x65\x54\x06\xf9\x02\x52\x8a\xc3\x2d\xdb\x87\x99\x41\xc2"
+  "\xa3\x55\xd7\x39\x14\xf4\x70\x77\x68\x19\xcd\x23\xb5\x6c\x13\xca"
+  "\x7e\x9b\x57\x85\x96\xf9\x58\xab\x55\xd2\x1a\xba\xff\x83\xd8\xeb"
+  "\x08\x4f\xd0\x39\x9c\x3f\x14\x34\x8e\x93\x4e\xee\x0f\xa0\x2b\x97"
+  "\x7b\x46\x8c\xa1\x65\xdf\xb7\x94\x81\x07\x68\xcd\xf4\xe9\x3e\x59"
+  "\x22\xd6\x76\xd5\x7f\xe1\x74\x7b\x50\x7c\x97\x25\xd1\x8b\x42\xc0"
+  "\xe3\xa6\x0e\xb2\x97\x7e\x39\x0e\x39\x7f\x02\x6b\xeb\x38\xe4\x04"
+  "\xbe\x2b\x3b\xa9\x6e\x0e\xcb\xc0\xbb\x39\x83\xac\xb5\x2a\xac\x67"
+  "\xa9\xf8\x99\xfd\x97\x15\x24\xa0\xdc\x2c\xd2\x7f\x1e\x39\x45\xfb"
+  "\xae\xad\x82\xee\x6f\xdf\xc9\xd2\x15\x94\x47\x7a\xd7\xed\x73\x58"
+  "\x3a\xe9\x5c\x91\x66\xcb\x89\xc8\x3d\x09\x4d\xa6\xda\x3a\x87\xcd"
+  "\x3f\xb3\xde\x56\xbb\x94\xe5\x5e\x12\x6b\xfc\x46\x3f\x9b\x67\xff"
+  "\x06\xef\xed\x67\x07\xf3\xb8\x2b\x8e\xf3\xcb\x2c\x7a\x29\x53\x1c"
+  "\xbc\xcb\xd4\x20\xf1\x4e\xe8\xe0\x81\x6f\xb4\xc7\xa1\xea\x76\x75"
+  "\xc2\x6f\x63\xa2\xff\x00\x9d\x83\x10\x69\x3a\x33\xc1\xd2\x2c\xda"
+  "\xa1\xfa\x5c\x8b\x6c\xbd\x96\x62\xbb\x09\x5f\x6b\x39\x2b\xa5\x5e"
+  "\x98\xfc\xb1\x01\xc6\xe2\x3c\x58\xcd\x4e\x96\xf4\xc8\x4e\x66\x3e"
+  "\x72\x3f\xf5\xeb\x60\x89\x9c\x8b\x06\x46\xed\x55\xdc\x34\xcf\x80"
+  "\x13\x68\x37\xd5\x47\xb8\xd1\x19\xfe\xc2\xe3\x2c\xe2\x8a\xe7\x27"
+  "\xe4\x0b\xe0\xe0\xcb\x9e\xc2\xfd\x6c\x29\xf9\xaf\x23\x1f\x36\x2b"
+  "\x98\x7f\x0f\xca\xdb\x33\x87\x99\x51\xd6\x1b\xde\x35\x44\x6b\x2d"
+  "\x57\x7a\x0a\x0f\x50\xd9\x1f\xd1\x7a\x54\x0b\xf8\xc8\x75\xe9\xa5"
+  "\x7a\x6f\xa8\x9b\x91\xbf\xfa\xbb\xed\x3c\x42\xe5\xf4\xb3\x97\x2e"
+  "\x11\xfd\xdd\x65\xb1\xe6\x48\x9f\x79\xa2\xaf\x93\xfa\x76\xb5\x1f"
+  "\xde\x53\x54\xde\x4b\x36\x6f\x2e\x78\x4e\xb5\x4f\x1a\xac\x25\x7e"
+  "\xbd\x94\xef\x29\xdc\xcb\x68\x7c\x28\x3f\x9e\x97\x7b\x87\x90\xf7"
+  "\xc4\x99\xe3\x42\x79\xf0\x6e\x1b\xca\xfd\x5f\xd1\x7d\x24\xda\xdf"
+  "\x88\xe6\x69\x44\x7f\x00\xab\xf6\x5d\x80\x91\xd4\xaf\x1d\x1c\xa6"
+  "\xb6\xfa\xd8\x41\xbf\xb7\xe8\x83\xa9\xcf\x1f\x61\xee\x03\xef\xcb"
+  "\x3b\x85\x6e\xe9\xa5\x4f\xee\x0e\x2b\x5c\xd2\xb3\x3f\xee\x00\xef"
+  "\x06\x3e\xf4\x8f\x3b\x88\x16\x08\x7a\x72\x3d\xed\xfd\xfe\xf1\x09"
+  "\x93\x4e\x8e\x2f\xf5\x85\x78\xa6\xa9\xc6\x38\x46\xaf\x6f\xa6\xb6"
+  "\x6a\x63\xcc\x93\xae\xcc\x56\x68\xbf\x66\x0e\xe0\x3d\x61\x61\x12"
+  "\xff\x78\x3d\xca\xdd\xa6\xf2\x90\x65\xea\x7a\x5a\x36\x92\x30\x94"
+  "\xc1\x1f\xb6\x30\xcd\xd6\x0e\xf3\x77\x7e\x8e\xb4\x5f\xb4\x10\x8d"
+  "\xda\xa3\x97\x73\x87\xda\xa8\x7e\x5b\x22\xf7\x91\xff\xb8\x1c\xdf"
+  "\x97\x4c\xd9\xdf\x38\xd0\x1d\x17\xc8\x34\xfa\x23\xce\x05\x80\x56"
+  "\x61\x3d\x98\xe1\x0d\x8c\x33\xb9\xb7\x7d\xe8\x42\x8a\x1d\x4f\x67"
+  "\xc2\xb4\xb6\x9d\x9f\x0e\xfe\x8f\x3d\x52\x07\x7f\x28\x4d\x93\x37"
+  "\x79\x12\x60\xec\x32\x09\xdf\xe5\xe0\xbb\x94\x40\xf2\x95\xb9\xfe"
+  "\xe4\xcc\x7a\x39\x6f\x0e\x2d\xe6\xc9\x92\xde\xe6\x84\x58\x19\xf5"
+  "\x4b\x95\xbb\x66\x50\x9f\x51\x4e\x9e\xb6\x17\xac\x95\x3d\x6d\x3c"
+  "\x00\xad\x6f\xe8\x93\xe8\x1b\xfa\x28\xfa\x46\xfe\x30\x64\xdf\xc4"
+  "\x79\xdc\xf3\xeb\xcf\x21\x19\x23\xa0\xe6\xca\x5c\xcf\x1c\x2a\xe3"
+  "\x95\x4d\xc2\x16\x1f\x63\x02\xfa\x70\xe9\x20\x7b\x39\x93\x27\x3e"
+  "\x92\x78\x7e\x65\xbe\xcc\x64\x99\x99\xf5\x4f\x80\x06\xcb\xf3\x41"
+  "\x64\xc3\xf2\xca\x4a\xd0\xf2\x7a\x92\x61\x46\x50\x1f\xf0\x23\x86"
+  "\x0e\xbd\xdc\x47\x63\x75\xfd\x7e\x96\x25\xf1\xf0\xe5\xf7\x49\x2f"
+  "\x21\xe3\xb5\xbc\xec\x06\xde\x8b\x33\x78\x51\xbb\x4c\x9d\xb0\xcb"
+  "\x8c\xa5\xb1\xe7\xd9\x46\x29\xd3\xa4\xa4\x65\xe0\xde\x21\xec\x74"
+  "\xd0\xde\x8d\x61\x8d\xfe\xbd\xec\xe0\xa4\x1b\x2e\x55\x75\x84\x44"
+  "\xcb\x4a\xa5\x3f\xad\xa0\xeb\x15\xcb\xa4\x8e\x90\xce\x4f\xba\x78"
+  "\x3b\xe5\xc3\xd8\x7f\x41\x79\xa4\xbf\x9f\x41\xf5\x6c\xe1\x2b\xd7"
+  "\xa9\xe7\x06\x6d\x64\x8f\x84\x6f\x97\xfb\x58\xaf\xe0\x33\x09\x06"
+  "\x54\xb7\x68\xbb\x9e\xf4\x81\xaf\xd8\xa3\x3a\xd9\x97\xc5\x79\x6e"
+  "\x79\xf6\xf7\x15\xb7\x86\x23\xe8\xef\x0c\xe9\xa3\xff\xd0\xf0\xe1"
+  "\xf9\x4c\xe0\xc0\x08\xb7\x24\x5e\xd5\x48\x38\xf9\x4a\x4b\x2c\x9c"
+  "\x96\x86\x15\xa7\xa4\x41\x2f\x37\x70\x31\xd7\x5f\x6e\xf8\x6a\x7e"
+  "\xe2\xd5\x78\x8d\x17\x91\x70\x36\x83\xbe\xbc\xd6\x25\x60\xed\xee"
+  "\xf6\x91\x5f\xcd\x87\x4b\xc9\x37\xf0\xab\xaf\x93\xdf\xe5\xb0\xfb"
+  "\x7d\x16\x71\x5a\x28\xa6\x0b\x53\xdc\xef\x9b\xfb\xed\x4c\x9f\x63"
+  "\x27\x3d\x74\xc8\x4a\x32\x1e\x64\x56\x33\x4f\x04\x7f\x82\x79\xbe"
+  "\x65\x35\x33\xfd\xa8\x00\x65\x3b\x6d\xa9\xe4\x17\x99\x7c\x22\x93"
+  "\x5f\xf3\x88\xd3\x76\x11\xee\x67\x81\x9f\x33\x73\x63\xb7\xd8\xcb"
+  "\x8e\xb8\x38\xe8\x71\x0f\xf9\x66\xd6\x7b\xfd\x21\xb6\xe5\x04\x33"
+  "\x92\xdf\xe5\x70\x55\x68\x61\x67\xe0\x23\x21\xdf\xa4\xd8\x59\x2a"
+  "\xf8\x8f\x34\xc0\xdc\xa2\x24\x84\x20\x87\x86\xd2\x65\xbf\xbf\xe0"
+  "\xb2\xdf\xb2\xdd\xd4\x7e\x41\xe3\xdc\x1f\x9a\x4b\x45\xdb\x5f\x5b"
+  "\x1d\x46\xf9\x8a\xdb\x97\x14\x71\xfb\x8c\xf2\xfc\x6a\x07\x2b\x2d"
+  "\xe2\x03\xde\x40\x07\x64\xae\x51\x11\x87\x8a\xf6\xca\xa9\x8f\xd4"
+  "\x3f\xaa\xfb\xad\x53\x27\x84\x1f\xe9\x30\x9e\x9d\x6b\xd4\x6f\x86"
+  "\xf0\xcd\x50\x07\x1b\x77\xfb\x44\xdf\x3b\x03\xf2\xdb\x1c\x71\x4f"
+  "\xdf\xc7\xc0\x41\xed\xf3\x24\x1c\xd0\x77\xea\x1f\xf5\x3f\x4c\x30"
+  "\x01\x0c\xd4\xbe\x5a\x26\xd4\x7e\x52\x1f\xdf\xc4\xaa\xb3\x13\xfd"
+  "\x44\x5f\x45\x3f\x27\xd0\xcf\xf6\x02\xc6\x42\x75\x57\xda\x4f\x27"
+  "\xfa\x8c\x24\xa3\x3a\xdf\x06\x0f\x5f\x52\xcf\x20\x8b\x1a\x9e\x2f"
+  "\xad\xd7\x57\x83\x37\x29\xf5\x43\x26\xf5\xf3\x01\xb2\x53\xf5\xda"
+  "\xf1\x0b\x37\x32\xe2\x71\x34\x7e\x1d\x75\x5b\xde\x52\x3e\x63\xa5"
+  "\x03\x7c\x00\xbc\x69\xc8\x1b\x46\x9e\x02\xf4\x1f\x32\x6c\xbf\xda"
+  "\x7e\xca\xbb\x65\x58\xf6\xcb\xb4\x86\xa5\xbe\xfa\x5f\x6e\xbd\xb7"
+  "\xdb\xcd\xb4\xbe\xdc\x8b\x7c\xe8\x8f\x05\x65\x89\x38\x34\x0a\xfa"
+  "\xb9\x0b\xed\x0c\xc5\xf4\xe9\xc8\x10\xd9\xca\xbe\xcb\x12\x97\x31"
+  "\xdd\xce\x93\xe8\xc7\x49\x66\xa9\x2f\x05\xff\xf5\x3d\xe2\x17\x3d"
+  "\x4f\x5f\x90\xcd\xd2\x7d\xec\x55\x19\xaf\x55\xfa\x79\xbd\x64\x90"
+  "\xbd\xf6\x86\xe6\xcb\x55\x21\x5f\xd8\x09\xa1\x45\x84\x47\xc2\xaf"
+  "\x2b\xad\x19\x41\xe0\x0c\xed\x69\x6f\x44\x1d\x41\xdb\x2c\xd1\x1e"
+  "\x97\xf4\x05\x8b\x67\xf2\x97\x4f\x67\xc3\x74\xf8\x6e\x21\x07\xcc"
+  "\xa8\x7c\xf0\x73\xa2\x1e\x82\xe1\x94\x76\xa5\xbf\x61\x0b\x51\xc7"
+  "\x22\x92\xbf\x5b\x4a\xfd\xfa\x6d\xbf\x61\xf3\xcf\x8f\xa6\xbc\x16"
+  "\x9a\x8e\x7e\x93\x2e\x93\xca\x43\xdf\x2e\x1a\x64\x7f\xfa\xe8\xcc"
+  "\x39\x66\x15\xb4\x4c\xd2\xc1\x3f\xed\x25\x5d\xe1\xf9\xd5\xfb\x27"
+  "\xc1\xc3\x91\x3d\xc2\x79\x7e\xb7\x4f\x6b\x07\xee\xbf\x64\x47\xa4"
+  "\xb5\xfd\xfc\xe1\x70\x98\x4d\x57\x56\xed\x93\xc2\x66\xd0\x59\xf7"
+  "\x24\xe8\x05\x78\x85\xc3\x16\xda\x77\xc0\xda\xb9\x37\xc0\xd6\xef"
+  "\x66\x46\xe7\x09\xd2\x0b\xdd\xc5\x0e\x37\x66\xb0\xa6\x53\xe4\x9f"
+  "\xc9\x76\xd1\xe3\xa7\x30\x96\x2a\x0d\x21\x9e\x94\x74\xae\x7c\xbd"
+  "\xcd\xbc\xfd\x49\x8d\x87\x3f\xfc\x46\xc9\x28\xd3\xcb\xd8\xdf\x87"
+  "\xdb\x17\x5b\x79\x78\x87\x5e\x29\x68\x24\x3f\xc7\x29\x69\xcd\xe4"
+  "\xe7\x58\xf3\xfb\x2b\x78\x1f\x07\xe6\xdc\x88\x25\xb1\xb6\x90\xcd"
+  "\x27\x1f\xe5\x26\xbf\xe4\xe5\xe4\x7a\x7d\x98\x6c\x37\xcd\xaa\x2f"
+  "\x60\xb3\xea\x0b\x38\x8b\xec\xaa\xe5\xfb\xb6\x6b\x22\x90\x61\x44"
+  "\xb9\x85\x2c\xbd\xf1\x14\xb3\x11\x1f\x94\xf3\x99\xe4\xd9\x48\x2e"
+  "\xbc\x6b\xc8\xc4\x23\xc7\x6d\x6c\xf7\x60\xd4\x87\xb9\x7f\x3d\xf9"
+  "\x3d\xe7\x96\xe9\x6c\x84\xb7\xcf\x12\x7b\xef\xc2\x2f\x25\xe9\xe4"
+  "\xf1\xcc\x76\x3c\xc6\x0c\x87\xc9\x8e\xaf\x59\x9e\x37\x3a\x1c\x96"
+  "\x36\xad\x41\x57\x5b\x83\xe6\xe3\x79\xda\xbd\x65\xb7\x94\x77\x94"
+  "\x19\x90\xbf\xfc\x41\x8f\xf4\xf7\xd7\xe6\xf3\x56\x28\x31\x32\x4e"
+  "\xdb\x6b\xf4\x8e\xd2\xc8\x87\x52\x96\x80\xe5\xeb\x46\x92\x7b\x54"
+  "\x99\xf1\x55\xab\x96\xa6\xca\x8c\xc2\xae\xd8\x22\xf7\xca\xb0\x36"
+  "\xa5\x04\x5d\xaf\xa7\x6b\xeb\x19\xad\xeb\x52\x37\xfc\xfa\x42\x9f"
+  "\xee\xd3\xb2\x73\xb4\xcf\xac\xda\x41\xd3\x3e\x47\x16\xf2\x17\x68"
+  "\xeb\x9b\xd8\xef\xdc\x3a\xe7\x5b\xeb\x37\xb1\xb4\xef\xcf\x36\x32"
+  "\xda\x2b\x43\xde\x01\xb9\xee\xbe\x5e\x1f\xd5\xa7\x67\x09\x78\xd3"
+  "\x79\x60\x21\x63\x90\x9f\x3d\xe9\xaf\x7c\x48\xf3\xb7\x27\xd7\xdf"
+  "\xd7\x9f\x8f\xa9\xa7\x6b\x72\x1d\x45\x1d\x64\x67\x4d\xe5\x4b\xde"
+  "\xe4\xf5\x0a\x71\x66\x0c\xf9\xe4\xfa\xfa\x7a\xc5\x39\x78\x31\x1b"
+  "\xc1\x57\x51\xe5\x49\xef\xd0\xe7\x12\xbe\x0e\x16\x77\xc3\x0e\x66"
+  "\x79\xb5\xd4\x67\x48\x91\x7e\x74\x4d\xbd\xec\xcf\x57\xd0\x7b\xc2"
+  "\x75\xcf\xf5\xa4\x0f\xfc\xf3\x16\x2f\xad\xdb\x13\xd9\x49\x77\x93"
+  "\xac\x2f\x78\xf1\x3f\xaf\xb9\x0e\xdf\x21\xed\xa2\x57\x4e\x86\x0c"
+  "\xdb\x37\xb3\xf9\xd2\x6f\xe1\x9f\x45\x6c\x60\xff\xa5\x0f\x04\xaf"
+  "\x4a\x65\x96\xab\x76\x30\x5b\xd0\xf5\xe7\x1d\x90\x2f\x05\x8f\x20"
+  "\xea\xaf\xcb\xf4\x90\xaf\xf6\x17\xc6\x7d\xf1\x72\xac\xfe\x72\x23"
+  "\x9e\x6d\xd1\xe7\x3f\x1f\x51\xf7\x52\xd0\xf7\xbf\x64\xec\x39\x29"
+  "\xed\xc5\x85\x7e\xa9\x66\x6e\xcc\x5e\xfd\x5f\x6e\x94\x6d\xf9\xcb"
+  "\x8d\x87\x41\x4d\x76\x3f\xc9\x8f\x36\xcd\xe2\x5d\x41\xd7\x5f\x0c"
+  "\x3e\xf6\xfa\x62\x55\x1f\xd3\x25\xf0\x8a\xf8\xdd\x4a\x92\xc1\x3e"
+  "\xf7\xd4\x22\x1f\xad\x13\xe0\x8f\xb2\x04\x0f\x0f\x5e\x57\x01\xfe"
+  "\xc4\xf4\x7f\x37\xe9\x1b\xa7\xa4\x89\x3b\x19\x13\xdf\xd4\xa6\x35"
+  "\x08\xdb\x8f\xda\x05\x16\x5c\x81\x6b\xf3\xb2\x70\x4d\x02\xce\x2d"
+  "\xc3\xd5\x8c\xeb\x12\x5c\x53\xf1\x5e\xc8\x0a\x90\x61\x2d\x14\x6f"
+  "\x6e\x24\x39\xad\x7e\xba\xb3\x3f\x04\x1b\x6f\xc5\x7f\x32\x69\xdf"
+  "\xd6\x9e\x4a\xb1\xc6\x96\xee\x66\x6c\x7d\x98\x8f\x5b\xe7\xb1\x99"
+  "\xbd\x48\x73\xee\xa6\x7d\xe7\xbf\x0c\x9c\xb9\xef\xdc\x6e\xc4\x6f"
+  "\x09\x7e\x8d\xf8\x75\xe0\x97\x1a\xfd\xbd\x61\x0c\xba\xda\x53\x01"
+  "\x47\xe9\x0f\xe2\xbc\x68\x62\xbb\x38\x2f\xbe\x9d\xe4\xa2\x84\x70"
+  "\xae\xec\x6f\xa6\x1d\xcf\x46\x9e\x9c\xd9\xa2\xf6\x37\x17\xcf\x66"
+  "\xab\x13\xeb\x5a\x32\x60\x32\x07\x7d\x4e\x5e\x60\xa1\xfe\x52\x7b"
+  "\x47\x92\xe7\x65\xc5\x9e\x7b\xa2\x32\xa9\xff\xfe\xe4\xb9\x54\x1e"
+  "\xe3\xff\xf2\x68\x97\x06\x4f\x15\x4e\x74\x26\x44\x3f\x82\x32\x24"
+  "\x1f\x84\xfc\x28\x43\xcb\x3f\x09\x7b\xe4\x13\x72\x22\xf2\x41\x26"
+  "\x36\x6a\x67\xaa\x82\xae\x37\xd8\x6b\x6b\xe4\x7e\x06\x7d\x1b\x88"
+  "\xf9\x96\xfc\x7c\x4c\xf5\x3d\xea\x34\xca\x3a\xe7\x65\xf5\xb3\xf6"
+  "\x4b\xd4\x7a\x03\xd3\xcd\xa5\xd2\x2b\xc0\xdf\x35\xfa\xe8\xfc\x0f"
+  "\xf1\x43\x8b\xbc\x69\x01\xe6\x6d\x54\x98\x52\x37\xd7\x9e\x55\xca"
+  "\x3d\xfd\xec\x8d\x17\x3b\x43\x03\xe7\xb9\x1e\xbe\x21\x65\xd1\xf1"
+  "\x32\xe6\x2d\xb9\x49\xd8\xab\x9f\x64\x6f\x7e\xe6\xf5\x8b\xb3\xb5"
+  "\x74\x2f\x7c\x3e\xd3\x7e\x33\xad\x0d\xe4\xc3\x5e\x93\xb1\x15\xe4"
+  "\x6d\xa2\x74\xa4\xd1\xf9\xff\x3d\x31\xef\x78\x5d\x9a\x43\xce\xa9"
+  "\x37\x77\x13\x6f\x21\xda\x1b\xfe\x0f\x0f\xb5\x59\xa9\x49\x73\x50"
+  "\x1f\x9c\x90\xff\x28\xce\x1f\xcd\x09\x6b\x31\xe9\x0a\xdf\xdc\x04"
+  "\xbc\xe3\x4a\x6d\x9a\xe3\xfc\xfa\xf0\xa6\xf0\xc3\xee\x0c\xf3\x93"
+  "\xfe\xe4\x34\x07\xf1\x24\xdb\x4b\xe3\x8d\xb7\x37\x72\xcf\x48\xca"
+  "\x5c\x7b\xd0\xf5\x66\xe3\x6b\x0e\x39\x36\xe7\x59\x6e\xa3\xd6\xf7"
+  "\x26\xb5\xef\x80\x97\xd8\xa3\xba\xa1\x41\xc6\x06\x40\x9e\xa3\xd3"
+  "\xea\xac\x30\xce\xc4\x0f\x60\x6d\x38\x2d\x61\xf1\x56\xfa\xe4\xda"
+  "\x70\x5e\xed\x78\x2b\xfd\x1f\xa8\x63\x42\xad\xc3\xfd\x3f\xac\xc3"
+  "\x7d\xae\x3a\xe4\x5e\x73\x47\xea\xf9\xcb\x8e\x6f\xf9\x04\xae\xd4"
+  "\xcc\xcd\x95\x34\xf3\xc8\xb6\x08\xe4\xb7\x70\x52\xa6\x9d\x78\x1b"
+  "\xb2\x2b\xf5\xfa\xc2\x2c\xec\x0e\xe7\x1e\x71\x8c\x33\x4f\xf1\x3b"
+  "\xac\x8f\x75\xdc\x45\xdf\x1c\x29\x22\x99\x2d\xb3\x65\xa2\x6e\xae"
+  "\x67\x42\xff\x56\x1e\xc1\x7b\x37\xc5\x61\x88\xc1\xb3\xce\xc0\x3b"
+  "\xcc\x9b\x4b\xfa\xd5\x2e\xd2\x6b\xb7\x80\x3e\xd8\x15\xd0\x06\xf0"
+  "\xe8\x11\x01\x0f\xf0\x2f\x42\xde\x82\xcc\x26\xe4\x2d\xbf\xf0\x4f"
+  "\x9a\x0c\xbe\x37\x89\xbb\x1e\xcf\x23\xdd\x77\x64\x22\xdb\x1a\x74"
+  "\xb1\x65\x14\x13\x81\xf4\xce\xdc\x78\xdc\xb2\x34\x1c\xc7\x85\x3c"
+  "\x05\xde\x9f\x62\x23\x78\x03\x3e\x16\x01\x1f\xdd\x38\xc6\x52\x1b"
+  "\xc1\x7b\x82\x66\x9b\x89\xae\xef\x51\x63\x23\xd4\x8e\x45\x63\x23"
+  "\x34\x91\xae\xa7\x1b\xf7\x63\xcc\x10\xa9\xbd\x32\x7b\xd7\x18\x4b"
+  "\xdf\x5d\xcc\x6c\xbb\x48\x97\x77\x4c\xf2\x3e\xc2\x0e\x9c\xe2\x24"
+  "\xac\xb3\xd1\x5e\x42\x94\xf7\xa1\xb3\xe0\x51\xba\x65\x10\x3a\x90"
+  "\xf3\x82\xf7\x11\xb1\x0e\x86\x6b\xd2\x1a\xc2\x49\x0b\x2c\x13\x75"
+  "\xf3\xb2\x7c\xac\xa3\x02\xf0\x9b\x52\xe7\xa5\xd9\x93\xec\x88\x89"
+  "\x6d\xf1\x5a\xba\xa4\xef\x28\xab\x7d\x3a\x9c\x88\xec\xca\x66\x37"
+  "\x0c\xb1\x0c\x79\x0e\x31\x01\x6b\x62\xe7\x7c\xb2\xff\x2b\x7d\x90"
+  "\x59\x22\xbb\x56\xe8\x9c\x4f\xb3\x38\x6f\x38\x8b\xd1\xaf\x74\x98"
+  "\x0f\xdc\xb0\x86\x65\xd0\xfe\x03\xed\x95\x58\x1f\xa6\xfc\x47\x22"
+  "\xe9\x25\x2c\x23\xb6\xec\x07\x37\x15\xae\xbe\x31\xe3\xc7\xf9\xd6"
+  "\xfb\x57\x17\x3e\xb8\x71\x65\x61\x3e\x5b\x22\xcd\x26\x84\xeb\xe7"
+  "\x4d\x64\x33\xb1\x71\x75\x51\x81\x75\xd5\x86\xc2\xc2\xfc\xb5\x45"
+  "\xd6\xbb\x6e\x5f\xf6\x65\xff\x7f\xbb\x2c\x7b\x85\xbf\x57\x61\x43"
+  "\xe7\xfd\x88\xff\xec\x6b\x63\x75\xc5\xcc\x60\x2a\xbf\x63\xb9\x29"
+  "\xbc\xc4\x2a\xe3\x23\x01\x57\xaa\x87\x0f\x70\x67\x76\x83\xe4\x53"
+  "\xbb\x74\xaa\xdd\x53\xab\x3c\x5b\xd1\x25\x75\x32\xc1\x25\x69\x72"
+  "\x4e\x79\x2f\x8c\x2b\x62\x74\xff\x20\xdd\x9b\x8a\x98\xdb\x33\x87"
+  "\xf6\xc3\xbd\x17\x8a\x7c\xbb\xee\xd4\x69\xf9\xb4\x3c\xf2\x7d\xa7"
+  "\x88\x9d\xd8\x24\x7c\x61\x76\x2e\x04\x7c\x2e\x0a\xba\xbc\x36\x9f"
+  "\xfe\x3d\x87\xba\xbf\x3e\x20\xed\xf5\xba\x18\xf9\xc3\xe3\x3f\xbb"
+  "\x6c\x4c\x2d\x27\x17\xf5\x5d\x80\xbc\xcb\x31\x06\x3d\xaa\x5d\xdf"
+  "\xe5\xbd\x6a\xbb\xa4\xdd\x69\xe7\x77\xa4\x7d\x87\xd7\x11\x73\x1e"
+  "\x5b\x9c\xa9\xa7\xb5\x51\xe5\x49\x83\x6a\x79\x8d\x1a\x4d\x40\x7e"
+  "\x8a\x7f\xe3\x3e\x7f\x5a\xe8\x95\xf2\xcf\x19\x7e\x4e\x54\x38\xed"
+  "\xb2\x3c\x03\xfa\x90\x36\xc8\x3a\xeb\xcf\xc6\x97\xc9\x11\xfc\xf6"
+  "\xda\x55\xeb\x1e\xb4\xaf\x2c\x5a\x7d\xdf\xea\x35\xab\x8b\x36\x89"
+  "\x63\xe0\xf3\xc5\xbf\x7f\xbf\x3a\x6f\xf9\xd9\xbe\x9b\xe7\x93\x8e"
+  "\x45\xf5\xf9\x1a\x20\x9b\x06\xa9\xe7\xea\x7a\x22\xec\x62\x97\x9f"
+  "\x5f\xbb\xbb\x72\x85\x3e\x58\xf8\x1f\xe8\xda\xeb\xd3\xf5\xd6\xab"
+  "\xfb\x1d\x43\x2a\xec\xc5\xfb\x91\xa4\x05\x74\x3e\x7b\x51\x2f\x3b"
+  "\xba\x98\xf6\xb9\x00\xbf\x65\xb4\x1e\xd6\x6d\xa6\x75\x0b\xa3\x10"
+  "\xbe\x49\x8d\xcf\xfa\xf6\x6f\x09\x06\xc4\x13\x02\x06\x7b\x7b\xd9"
+  "\xdb\xb3\x05\x0c\xbe\xb0\xec\x15\xbe\x07\xbe\xb0\x3c\x43\xb8\x45"
+  "\x6d\x56\x78\xf6\x2e\xce\xb3\x77\x2a\x5f\x14\xec\xe2\x5f\x14\xec"
+  "\x8c\xfa\x8d\x7b\xbb\x02\xdf\xee\xc7\xb7\x55\x14\x87\xa6\xee\x24"
+  "\xdb\x4f\xfb\xdf\xf4\x6c\x2a\x32\xb3\x48\xd2\xdc\x25\xd4\x1e\xef"
+  "\x40\x86\xe0\xb7\xfb\x90\xdf\x1b\xb8\x89\x81\x97\x5c\x26\xce\x34"
+  "\x8a\xfd\x3a\xf0\x7b\xf8\xce\x8b\x76\x79\x07\xc6\x49\x26\x5e\xa2"
+  "\x80\xe7\x43\x7f\x0f\x60\xfd\xac\xa7\x72\xa9\xcf\xe2\x5c\xf1\x2c"
+  "\xee\x0b\xba\xde\x6e\xf6\xb1\x4e\xbb\xca\x9b\x0a\x7b\x0b\x82\xc1"
+  "\x99\xe3\xf9\xb6\xf0\xe9\x00\x18\x5f\xca\xdd\xef\x67\xc8\x31\x7d"
+  "\x5b\xf8\xba\xb8\xb3\x8f\x7f\x11\x3d\xcf\xfe\xf6\x09\x3c\x4f\xe0"
+  "\xa7\x70\xf7\x07\xcb\x62\xf6\x95\xf1\xee\x9d\x4b\x04\xef\x36\x8b"
+  "\xfb\xed\x9b\x29\x6e\xf7\x3b\x57\x48\xbc\xf9\x60\xa9\xdf\x59\x10"
+  "\x87\x6f\x22\x74\xfe\x52\xc2\xf2\x9d\x6f\x7a\x2b\x4e\x6a\x76\x1a"
+  "\xa8\xff\x9d\x4f\x3c\xf7\x87\x99\x88\x23\xdd\x17\x16\x76\x7f\xaa"
+  "\x8f\x01\x9d\xe2\xea\x22\x3f\x7b\x66\xc8\x76\xb4\x17\x2d\x7c\xa4"
+  "\x07\x5d\xef\x14\x4d\x9e\x13\x4b\x92\xfc\x1e\xf1\x5c\x14\x63\x8b"
+  "\x70\x9f\xf8\x37\x6a\x13\xe1\x3e\xca\x6e\xa6\x3d\x6a\x39\x07\xde"
+  "\xd9\xff\x3f\x9b\x03\xef\x08\xfd\x2f\xca\xca\xe2\x7a\x27\xbf\xa1"
+  "\x86\xe5\x0a\x1b\x82\x70\x80\xce\xcd\x1a\xb0\x6e\xa8\x36\x65\x47"
+  "\xe7\x0a\x3b\x93\xe2\xa1\x66\x3a\x9b\xba\x67\x9c\x25\x29\xee\xe3"
+  "\x66\xe2\xb3\x8f\x94\x08\xdb\x0b\x23\xbe\x6b\x21\xdb\x0c\xb2\xa5"
+  "\x4b\x11\x71\xdb\xde\x61\x7b\x46\x99\xa1\x8f\xfd\x75\x3e\xed\x05"
+  "\x45\x61\xfd\xd7\x72\xda\xfb\xe3\xd5\xef\xb5\x9b\x4a\xf4\x6e\x2a"
+  "\x43\x19\x3b\xb1\x50\xfb\x8e\x62\x04\xd3\x77\xbd\xec\xaf\xf9\xe2"
+  "\x3b\xca\x4b\x3e\x96\x4a\xcd\x2b\xc0\x67\x35\x50\xfe\x30\x9e\x9b"
+  "\x14\x33\x64\x91\x05\x96\x48\x71\xb8\x05\xef\x96\x2b\x35\xf3\xb2"
+  "\x90\x96\x2d\xf6\x20\x26\x2c\xb4\x37\xc9\xb8\x31\xb4\xcc\xeb\xfb"
+  "\xdc\x23\xda\x43\x67\x69\x8b\xb0\x76\x0a\xb9\xe4\xaf\x07\x9b\x8e"
+  "\x89\x78\x72\x18\xcf\xa3\xd2\x77\xe6\x49\xb6\x4f\xb6\xef\xe8\x5d"
+  "\x23\xd5\x3e\xe3\x08\x70\x33\xa0\x37\xb2\xc3\x16\xe0\x66\xcd\x02"
+  "\x5c\xc7\x31\x3e\x47\x53\x41\xeb\x16\x4a\x9e\x58\x7e\xa7\xe1\x64"
+  "\x9c\xc5\xbc\x04\xef\x33\x35\x7b\x24\x0d\x1f\x7d\xec\xaf\x49\x04"
+  "\x37\xe0\x71\x77\xe7\x1a\xb2\x2d\x53\x3a\x50\x17\x8b\x14\x2b\x3d"
+  "\xb4\x37\x4e\x76\xfb\x24\xcf\x2c\x75\xf0\x11\x92\xcf\xe8\xac\x13"
+  "\xed\x87\xd3\x19\xee\xdd\x90\x6f\xa9\x6c\x94\x5b\xa3\x9d\xe5\xae"
+  "\x45\x1a\x95\x4d\xe7\x99\xea\x7e\x22\xe6\x1a\xd9\x70\x26\x89\x3d"
+  "\x81\xb8\x07\x8e\xdd\x1d\xe0\x23\x74\x5e\xfe\x6e\x3b\xae\x6a\x39"
+  "\xe4\x67\x07\x65\x74\x69\x65\x28\x64\xff\x5a\x28\xec\xdc\x7c\xf2"
+  "\x7b\x69\xff\x73\x77\x40\x11\xe7\x50\xe8\x7b\x69\x97\xf3\xae\x61"
+  "\xd2\x86\x52\x9c\x0d\x79\x37\x55\xf3\xc3\x83\x7b\xeb\xe4\xd9\x36"
+  "\xc0\x6a\xa4\x66\xee\x92\x00\xe6\x78\xa0\x26\xad\x1e\xef\x16\x81"
+  "\xc2\xec\x3d\xa7\x8e\x82\xce\xef\x6f\x60\x7a\x25\xf1\xf8\x22\xf2"
+  "\xcd\x40\x67\x3e\xa5\xdd\xf6\xbb\xbb\x55\x3f\x0d\x71\x27\xd9\xbb"
+  "\x3f\x88\xee\x8d\x47\x54\xbd\xee\xbb\x6d\x52\xae\x78\xb7\x4d\xe8"
+  "\x75\xeb\xe6\x66\xfc\x62\x73\x48\xdf\xb2\xd9\xa7\x97\xb6\x8c\xef"
+  "\xb6\xfa\xd8\x47\x43\x51\x5b\xc6\x77\x1d\x54\xd6\xd4\xfe\x2c\x86"
+  "\x55\x9b\xcc\xbf\x89\xf3\xb5\x51\x39\xfd\x6f\x62\x9d\xa3\x7d\x6c"
+  "\x85\x78\xba\xc4\xb0\x9d\xec\x96\xbc\xf6\x53\xa4\xdf\x9d\x21\x75"
+  "\x06\x7f\x53\xe3\x08\x0b\x3b\xc5\x8b\x07\xcf\x7c\xbe\x88\x9e\x25"
+  "\xcc\xfe\xb6\x44\xdb\x2b\xaa\xd3\x2b\x3e\x93\x8e\x71\x67\x33\x68"
+  "\x9e\x3d\x20\xfc\x03\x78\xc1\x23\x52\x6c\x6c\x7b\x21\x9d\x05\xfc"
+  "\xdb\x16\xf2\x1b\x20\xe7\xdc\xdf\xc4\xb9\x24\xc5\x75\x1b\x77\x92"
+  "\x9c\xe4\xa7\x58\x1d\xa7\x18\xf2\x5d\x88\x7c\xcf\xb6\x95\x0c\x91"
+  "\xdd\x97\x81\xe2\x44\xf6\xa9\x75\xfb\x13\x86\xcd\x57\x25\xb1\x5c"
+  "\xd4\x79\xc8\xc7\x9e\x5d\x7c\xfe\xf4\xe0\x6f\x87\xce\xc5\x33\x4b"
+  "\x1e\x2e\x8b\x4d\x27\x77\x93\x5e\xe5\x7a\xd4\x7f\x17\xa7\xf6\xbf"
+  "\xf7\x6c\x58\x1f\x62\x13\xfa\x99\xfc\x6b\x65\x0e\x16\x76\xcd\xe4"
+  "\x91\xcd\x18\xaf\x11\x0b\xe4\xb2\x0e\xd6\x29\x6d\x61\x68\x3f\xdf"
+  "\x54\x1a\xe0\xa7\xbc\xe1\x03\xa4\xd7\xf7\x63\xac\x40\x8f\xde\x7b"
+  "\xda\x1b\x7e\x99\x91\x7d\x32\xd1\x91\x5e\xf6\x9e\xf0\xc7\x74\xbd"
+  "\xbd\x8c\x5d\x77\x52\xbc\xbf\x53\xf2\x73\xef\xed\x53\xaf\x0e\xf2"
+  "\x8f\x19\xdb\xa6\x7f\xdf\xb0\x76\x15\x39\x59\xbd\xee\xce\xfc\xe2"
+  "\xfc\x35\xd6\xef\x91\x0b\xd6\xb3\x6c\x0d\x8d\xd1\xb8\x62\xdd\x45"
+  "\xb4\x46\x12\x4f\x4d\xf1\xc5\x44\x6c\x31\x57\x26\x9b\x8c\x2b\x46"
+  "\xbc\xf5\xff\x0f\xb1\xc5\x34\x9e\x99\xe2\x8a\x45\xf7\x64\xde\xcf"
+  "\x9c\x9c\x03\xca\xab\x41\x7a\x16\xeb\xb2\xeb\x3d\x3a\xa7\x64\x90"
+  "\xeb\x46\xf7\xfe\x58\x1f\x36\x82\x67\xaa\x0a\x2d\x43\x7a\x9b\x76"
+  "\x66\x13\xb8\x98\x84\xe7\xa3\xd1\x33\x22\xdd\x3e\xc0\x4d\x9c\xa3"
+  "\x24\xfb\x05\x3c\xfb\x35\xdb\x05\x35\x66\xb4\xb0\xb5\x50\x2a\x2f"
+  "\xdd\x2f\xf5\x85\xdd\xa3\x4d\xca\x4c\xa3\xdc\xab\x7a\x3f\x4d\x3b"
+  "\x83\x24\xe7\xe6\xab\xea\xdc\x7c\x3f\xf3\x5c\xf6\x25\xd1\xb9\xf1"
+  "\xbe\x3d\x3a\xaf\x3f\xd6\xbe\xb5\x7f\x95\x6d\x8a\x2a\xb7\x5d\x32"
+  "\xc8\x3e\xdc\x46\x3a\x44\x79\xe6\xf8\x43\xe1\x93\x52\xfa\x81\xf8"
+  "\xf0\xdb\xea\x3d\xea\xf8\xf0\x46\xf5\xfe\x32\xdc\xcf\x56\xef\xe7"
+  "\xe0\x5e\xa7\xde\x63\xce\x7e\x70\x4c\xbd\x4f\xc5\xfd\xdb\xea\x3d"
+  "\xd6\x84\x0f\x0e\xaa\xf7\xb3\x70\xff\xb4\x7a\x3f\x1b\xf7\x55\xea"
+  "\x3d\xe6\xe0\x07\x0f\x31\xb9\xcf\x6f\xec\x67\x1f\xfc\xe8\xfc\xe5"
+  "\xc8\x0f\x6c\x72\x2f\xf9\x03\xc8\xdc\x5d\xea\x9a\x32\x99\x56\x82"
+  "\xb1\xe9\xd0\xe0\x8b\x74\x2b\xd5\x83\xf4\x1d\x3e\xd6\xb6\x37\x26"
+  "\xdd\xac\xe6\xc7\xfa\xff\xee\x92\x98\x74\x83\x9a\xde\x06\x79\xb5"
+  "\x3d\x9a\xfe\x7e\x48\x4d\xef\x41\xfe\xae\x98\xf4\x21\x35\x1d\xf4"
+  "\xf2\x95\xee\x98\x74\x9f\x4c\xff\x30\x49\xb3\xab\x51\xd3\x8f\xaa"
+  "\xe9\xe9\x3e\xf6\x7b\x77\x4c\x7a\xbb\x9a\x0e\xfa\xff\x7e\x56\x4c"
+  "\xba\xa0\x2b\xd2\x27\xb1\x89\x1f\x2e\xa1\xb9\xf5\x61\xae\x8f\x1d"
+  "\x72\xc4\xe4\x69\x51\xbf\x75\xf8\xd8\x1f\x9b\x63\xd2\xf7\xaa\xe9"
+  "\xf5\x3e\x5d\x62\x6a\x4c\x7a\xc3\x74\xb4\x4a\xd7\xc0\x72\xa7\xd3"
+  "\xb5\x93\x5c\x22\xec\x8b\x05\xaf\xdc\x73\x84\xce\x34\x99\x76\xf3"
+  "\x5e\x6b\x29\xe7\xbd\xac\xe7\x80\x6a\x4f\x4b\xbe\x05\x86\xe8\x7c"
+  "\x58\x1f\xeb\xd9\xad\xfa\x16\xf0\x8b\x33\x63\x9b\xe9\xcc\x58\x8f"
+  "\xe0\x01\x6f\x70\x94\x49\x7f\xb9\x5a\xec\x05\xd2\x39\xa9\xfb\xf1"
+  "\xc8\xf3\x6d\xd2\xc1\x53\x39\xa4\x97\xf6\x16\x8d\x4b\x5f\xca\x90"
+  "\x4d\x29\x8d\x74\x2f\x04\x8f\x58\x1d\x93\xa4\xfb\x3d\x47\x94\x71"
+  "\x3a\x97\x29\xf5\x53\x34\x17\x29\x3f\xd9\x90\xc5\xe6\xf5\xb1\x1e"
+  "\xe1\xb3\x3a\xce\x72\xe1\x53\x41\x57\xcf\xfe\xe8\x79\x98\x1e\x83"
+  "\x9a\xde\x80\xf4\xb6\x68\xfa\x87\xfe\x69\x69\x3b\xe8\x20\x37\x76"
+  "\x9b\x27\xc6\x78\x20\x3c\xc6\x43\x75\x7f\x97\xb6\xe4\xa0\x75\xf3"
+  "\x22\xee\x6e\x2b\x9d\x17\xa1\x98\x8c\xe1\x62\xee\x27\x3b\x45\xa4"
+  "\x5f\x70\x77\xc0\x0f\x1e\x23\xc8\x6b\xef\x23\x9b\xd4\x51\x46\xfb"
+  "\xa5\xce\x21\x8a\x97\x65\xe2\x74\x0e\x79\xcb\x09\x96\x44\xe7\x49"
+  "\xc8\xe6\x9c\xf6\x32\xef\x2a\xf0\xb3\x23\x05\x11\xd6\x84\xb2\x77"
+  "\xdf\xa7\xf1\x17\x1f\xe5\x45\xcf\xba\xbe\x47\xfb\xcb\xf3\x9c\x22"
+  "\xf6\xec\x47\xc2\x57\xaf\xa9\x9c\xf6\xf9\x17\xd8\xf8\x9f\x88\xe7"
+  "\x4d\x2b\x33\x95\x33\xf0\x1c\x1f\x35\xe3\xde\x2e\x7f\x78\x87\xf4"
+  "\xe9\xfa\x24\xe7\xf2\x47\xd2\xdf\x9a\xbb\xbb\x5e\xd2\x8b\x8f\x7a"
+  "\xf8\xcf\xe9\xfc\xc4\x47\x3e\xd0\x1b\x1b\xf8\xeb\x29\x7d\x25\x6e"
+  "\xd9\xcd\xf4\x13\xd5\xe0\x4d\x4e\xb6\xea\x25\x7d\xfa\x7b\x87\xa2"
+  "\x37\x96\x93\xfe\x5b\xc4\x9f\xac\x3e\x7e\xe7\xfe\xb5\x21\xfd\x91"
+  "\xcd\x7d\xec\xe1\xd9\xcc\xb2\x22\xa4\xa7\x3c\x77\xa5\x14\xa1\x6e"
+  "\xf0\x24\xe0\x53\xf5\xbf\xc3\xfb\x57\xd6\xb6\xea\xc3\x82\x5f\xf9"
+  "\x7b\x87\xd0\x99\xba\x8f\x5b\x69\x0d\xf1\x76\x47\x88\xc7\x4e\x02"
+  "\x8f\x6d\x06\xfd\x37\x46\x36\x16\x5c\x14\x5e\x5f\x70\xc1\xee\x42"
+  "\x96\x14\x59\x6f\x4b\x7d\x7c\x8c\x2d\xd4\xd6\x9f\xdd\xc5\x58\x53"
+  "\x82\x96\xc4\xed\x58\x53\x48\x17\x93\xa2\x33\x8b\xbd\x61\xba\x57"
+  "\xf4\xaf\xf5\x35\x15\x9f\x3b\x86\x6e\x64\xa3\x4d\xf8\x4b\xa0\xb6"
+  "\x4c\xd5\xd7\x9a\x9d\xcc\x10\x51\xcf\x55\x96\x7e\xc6\x66\x81\x2f"
+  "\xd6\xa7\x8c\x72\xcf\xe0\x1a\xa6\xa7\xf8\xa3\xa5\xf9\x42\xdf\x19"
+  "\x7f\xa4\x20\xcc\xbc\x8e\x0f\x58\x69\x21\x8d\xd1\xc7\x57\x10\x9f"
+  "\x46\x36\xc6\xc8\x6f\x1e\x64\x1f\xdf\x68\x0a\x61\xcd\x08\x81\xd7"
+  "\xfe\x09\xc9\xb6\x1f\xdf\x21\xfd\x33\x7c\xec\xa6\x73\x90\x9e\xc2"
+  "\x6f\x51\xda\x4a\xe7\x67\xc2\x96\xc7\x20\xcf\x5e\x7e\xbc\x88\x9e"
+  "\x9d\x74\xce\x33\xd1\x9f\xf9\x9b\xf1\x50\xbc\xd4\xa9\x7d\x7c\xab"
+  "\xba\x3e\x58\xa5\xcc\xf6\xf1\x97\xce\xa8\x4d\xea\xfa\xdd\x3d\x19"
+  "\x9c\x62\x99\x35\x12\xff\xca\x7d\x62\xdf\x9d\xce\xbc\x3b\x6e\xf3"
+  "\xf0\xb1\x7a\xd5\x87\x8e\x4f\xa7\x54\xf5\x64\x48\x3f\x77\x1f\x9f"
+  "\x66\xd2\x66\x0e\x6b\x64\x4f\x96\xd8\x73\xa8\xea\x59\x26\x74\xf0"
+  "\x55\x3d\xb9\x5b\xe7\x90\x8d\xbf\x8f\x8d\x24\xf4\xd8\xd1\xf6\xa3"
+  "\x23\x89\xa3\xd3\xed\xdb\x19\x20\x53\xe6\x5a\xe7\xb1\x54\xda\xfb"
+  "\xc9\x89\x48\x3f\x8f\x72\x0e\x7f\x82\xb2\xc5\xbb\xcb\x7b\xed\x2c"
+  "\x4e\xca\x86\xbe\xef\xde\xd0\xc8\xac\x68\x6b\x32\x37\xf6\x98\x85"
+  "\x2d\xa2\xbb\xc7\xea\x1d\xa2\x38\x2d\x11\x26\xf7\xe8\x3e\x31\xf3"
+  "\x84\x1e\xb3\x9a\xff\xe9\xce\x21\xf4\xc1\xf8\xa1\xcf\x1b\x3a\xa1"
+  "\xf2\x84\xbe\x66\x5e\xf5\xa1\x8f\xbb\x3f\xf4\xcb\xf3\xd2\xbe\x61"
+  "\x8d\xae\x4a\x1c\xf5\x7d\x26\x71\xfd\xfd\x5c\x09\xb7\x4f\xcc\xea"
+  "\x7a\x75\x39\xdd\x63\xed\xce\x90\x36\x25\xbe\x1e\x8d\x47\xf6\xa9"
+  "\x79\xe8\x1b\xf4\xdb\x23\x69\xad\x0f\xe9\x1f\xef\x90\xef\x7d\xcd"
+  "\x94\x86\xfe\x61\xcd\xf2\x2d\xa4\x7e\x4d\x47\x5b\x05\x2c\x4a\x58"
+  "\x1c\xfa\x47\x3c\x2d\xd9\xed\x07\xbc\x81\xdb\x3c\x5e\x31\x06\xbd"
+  "\x4f\x91\xbd\x3d\xd5\x43\x3e\x71\x88\x6e\xa2\x4c\x01\xa7\x68\xfb"
+  "\x3f\xd9\xa2\xb5\x85\xea\xa3\x77\xe8\xab\x88\x63\xa1\xa0\xcf\x94"
+  "\x87\xc6\xb5\xdf\x4e\xba\xb8\x51\xc0\x8c\xec\xda\x7a\xf7\x11\x4c"
+  "\x24\xcc\x7a\x2b\x54\x59\x5d\x1d\x87\xde\x4d\x67\xc2\x43\x3e\x2b"
+  "\x46\xd0\x86\x42\xb2\x6f\xea\xdd\xa7\xc2\x4f\x8d\x31\xd0\x2b\x7c"
+  "\x2b\xa8\xef\x92\x63\xbe\x9d\x3b\x99\x17\xed\x26\xde\x88\x6c\x05"
+  "\x68\xef\x48\xe2\x6b\xef\xc2\x98\xef\x16\xe6\x0c\x83\x47\x06\x0f"
+  "\xb9\xf5\x49\x11\xb3\x2d\x23\xe8\xea\xbd\x33\x0a\x6f\x59\xce\x14"
+  "\x75\xcc\xd3\xea\x40\x9e\x24\xad\x9d\x18\x1f\x75\x0d\xee\xad\x8f"
+  "\x8e\xc9\x27\x2d\xda\x77\xa4\x97\xc1\xf3\x0a\x8a\x7f\x38\x8d\x5f"
+  "\x78\x9d\x37\x0d\x34\x38\x7c\x9b\x47\xe0\x23\xfb\xd4\x48\xb6\xe3"
+  "\xdc\xdd\xa3\xfa\x37\xe8\x55\xf5\x46\x9f\x1a\xa9\x4c\xda\xff\x93"
+  "\x71\x42\x3e\xc5\x2c\xf8\x24\x4d\xd6\xf7\x69\xaa\x6c\xc3\xa7\x90"
+  "\xff\x7c\x49\x67\xcb\x75\xdf\x5a\x99\x67\x5d\x76\xa3\x38\x33\x7a"
+  "\xdd\x06\x3b\x1d\x07\xcd\x8b\x3e\x9c\xc9\x73\x9b\xa3\xbe\xb5\x3e"
+  "\xcd\x9d\xf4\xad\xe5\x1e\xce\x94\xf0\xff\x74\x3f\x1f\xe3\x3b\xe8"
+  "\x3c\x07\x2f\xe6\x0d\x75\x18\x43\xe7\x28\xbb\x94\xe2\xd0\x96\xda"
+  "\xf9\xe7\xe4\x77\x0d\xf4\x72\x0d\xe8\x07\xc5\x61\x9f\x49\xb6\x42"
+  "\x44\x7f\x48\x9f\xc5\x13\x90\x5e\x75\xdc\x1e\x3d\x47\xd6\x4f\x36"
+  "\x5c\x25\xdc\x99\x4d\xf1\xc3\x49\x3f\x25\xe2\x04\xf5\xb3\xfe\x6c"
+  "\xe4\xab\xc0\xbb\xa2\x5a\xa1\x23\x38\xde\x1e\x31\x0e\x27\x39\x4f"
+  "\xb0\x19\x22\xc6\x97\x23\xc4\xac\x3f\xa1\xf3\x46\x7d\xc9\x28\xb3"
+  "\x1d\xe9\x29\x22\x3d\x14\x22\x5f\x01\xed\x78\x97\x82\x77\xdf\xc6"
+  "\x55\x41\x19\x8e\x3a\xb4\xbb\xf4\x04\x9b\x87\xb6\x0c\xa0\x9e\x76"
+  "\xb4\xb3\xdf\xf9\x20\x9b\xd5\x69\x1f\x20\xf9\x0e\xe5\xf9\x98\xea"
+  "\x4f\xa3\x1d\xdf\xed\x46\xbf\x1c\xa4\xeb\xc0\xb5\xa4\x16\xd7\xd2"
+  "\x08\x4b\x29\xdd\x82\x75\x6f\x0b\xea\xa7\x73\x99\x28\x87\x7c\x68"
+  "\xc8\xb6\xa0\x6f\xa4\x1b\x43\xb9\x5b\x86\x78\x3f\xca\x1e\x38\x32"
+  "\x84\xf2\x1c\xdd\x93\x65\xaa\x3c\x35\xe6\x77\xff\x77\x79\xf5\x68"
+  "\x06\xda\xd4\x40\xf6\xd4\x48\x03\x4d\xee\xbf\x33\xca\x0f\xf7\xdf"
+  "\xa5\xde\x27\x4c\xe6\x75\x66\xb3\xd2\xd3\xcc\x22\x6c\x02\x36\xc6"
+  "\x81\x1e\x7f\xd6\x43\xbe\x9a\xa2\xbe\x3b\x3f\x7b\x17\xf9\x16\xa2"
+  "\xcc\x1a\xb5\x4c\x4a\xeb\x8a\xf2\xcf\x9f\x69\x3c\x73\xe2\x64\xde"
+  "\x2f\x95\xd9\xbf\x89\xca\x94\x7e\x95\x3e\xb5\xca\x33\xc9\x9f\xad"
+  "\x98\xf4\x89\x30\xc6\x5b\xe8\xcc\x9d\x52\xcc\x0f\x90\x4e\x82\x74"
+  "\x21\x24\xbf\xd0\xb9\xbb\x9c\x4d\xee\x32\xa1\x8f\x98\x25\x75\xa6"
+  "\x92\x67\xf8\xac\x61\xf2\x8c\xc0\x93\x22\x1e\x81\x3c\x53\x47\xe7"
+  "\xf4\x0a\x85\x3e\x25\xb8\x74\xd3\x46\x27\x7d\x4f\xdf\x22\x7f\x7b"
+  "\xf4\x2c\x53\xbf\x43\xea\xee\x46\x17\xd2\xbd\x5f\x6b\x97\xeb\xd3"
+  "\x0c\xa9\x7b\xfe\x2c\x30\xa9\x7f\x2b\xe6\x6d\x34\x4e\xe2\x8c\x21"
+  "\xd9\x00\x46\x98\x3b\x27\xec\xd6\xce\x0a\x0f\x05\x5d\xfd\xd6\x98"
+  "\xb3\xc2\x43\xa2\x0d\xe3\xe2\x3c\xfe\xc6\xa5\xe1\x8d\x5c\x9e\x21"
+  "\xed\x5f\x1c\xad\xbb\xcf\xaf\xd6\x9d\x41\xf7\x7e\xe9\x13\x8b\x6c"
+  "\x03\xad\xd2\xae\xa3\xdf\xae\xd9\x52\x60\xbe\x75\x13\x7e\x4e\xed"
+  "\xbb\xbf\xbf\xe1\x4c\xff\x3c\x9f\x17\x90\xef\x70\xa4\xc7\x9c\xff"
+  "\xed\xff\xca\xf3\xbf\x4e\x3f\xff\x84\x70\xc8\x2e\xe2\xd0\x7e\x0e"
+  "\x5a\x3b\x9c\x24\xfd\xdf\x7f\x2e\x74\x2e\xbd\xec\x73\x1b\x9e\x4d"
+  "\x72\xdf\xe1\xf3\xd9\x2a\xbd\x29\x5b\x1a\x09\x9b\x7c\xa8\x53\xf8"
+  "\xfb\x89\x3e\x9b\xc9\x7f\x01\xf2\x7d\x5b\xfa\x0d\xfe\xdc\x78\x56"
+  "\x7e\x7a\x7f\x76\xfe\xac\xb3\x9e\xad\x01\xcc\xc3\xe9\x6c\x46\x6a"
+  "\xe7\x08\x7d\xa4\x35\xa5\x9c\xd9\x9d\xc7\x58\x1c\xe6\xc7\x67\xd4"
+  "\xb6\xce\x01\x71\x9e\xcc\xc4\x5d\x19\xcc\x3b\x10\x96\xbc\x28\x78"
+  "\x80\xde\x74\xe4\x39\xc6\x66\xd1\x79\x06\x8a\x0f\x80\xfc\x83\x32"
+  "\x26\xc0\xc0\xf0\x8a\x0d\x89\x4c\xf9\x71\xf6\x05\x5c\x7f\x5f\x2b"
+  "\xed\x59\x3f\x3f\xee\x23\xbf\xfa\xba\xd2\xa7\x58\x1a\xcd\x3d\xcc"
+  "\xc1\x3e\xae\x5f\xd5\x8a\x6f\x86\x7e\x31\x3e\x10\xef\x0d\x7f\xc0"
+  "\xec\xa0\x09\x83\x6c\xa0\xcf\x50\xc2\x0c\xdb\xfb\x99\x19\x78\x16"
+  "\x3e\x1c\x5e\xc8\xb4\xf3\xf7\x8d\x17\xc9\x73\xdd\x8d\xc0\xc9\xf5"
+  "\x16\x1e\x0a\xba\x06\xb2\x20\xab\x2d\xd7\x64\xf2\x1a\xe9\x7f\xcb"
+  "\x80\xfa\x9f\x17\xbe\x02\xe4\x9a\x07\xd8\x0e\x6c\x91\xe7\x19\x53"
+  "\x2f\xc5\x37\x45\x51\x7e\xfd\x18\x53\xf7\x70\x32\x24\x6d\x3c\xc6"
+  "\x0e\xe7\x31\x11\xd3\x68\x44\xf8\x47\x1f\x68\x9e\xb4\xbd\x11\x7a"
+  "\xae\x63\xa0\x07\xc3\x19\x92\x97\x1f\xce\xc8\x89\x18\x55\x9e\xe1"
+  "\x98\x58\x8b\xe8\x5b\x7c\x67\x92\xb1\xcb\x06\x7a\xa2\xb8\x36\xb0"
+  "\x97\xd6\x08\xf4\x09\x32\xde\x80\x85\xfa\x45\x30\x09\x08\x5f\x5b"
+  "\x03\x69\x87\xf7\x4e\x13\xdb\xc2\xd8\x5d\x1f\x16\x3a\x93\xb9\x36"
+  "\xe0\xd3\x09\x8c\xc1\xc5\xe4\x6f\xc8\x8b\x7a\x8e\x34\x8d\xb3\x23"
+  "\x96\x11\xd6\x89\x7b\xb2\xb1\xf7\xfc\xe4\x53\xd6\x67\x9d\x7a\x7d"
+  "\x52\x20\x77\x80\x37\xb7\x52\x59\x44\xdf\xc8\x2e\xd1\x5b\xc2\xc4"
+  "\x4e\x93\xb7\x8f\x89\x32\x8e\x28\x03\xec\x88\xe3\x13\xd2\xc3\xda"
+  "\x3a\x9b\x3e\x60\x9d\x96\xbf\x8a\x7a\x88\x87\xf4\x14\x8e\x9c\xab"
+  "\x6c\xc0\xa3\x3b\x4b\x2d\x7b\x08\x65\xa7\x4e\x5f\x76\x5a\xd9\x79"
+  "\x96\x7d\x1e\xed\x4e\xb3\x9f\x4f\xd9\xce\x06\x1e\xc1\x9a\x90\x0c"
+  "\xba\x6f\x26\x5f\x97\x74\x96\x32\x32\x46\x7e\x42\x2e\xe7\xd2\xd6"
+  "\x7b\xf0\x7d\xa2\x37\xc2\x0e\xa1\xea\x78\x92\x38\x67\x49\xba\x63"
+  "\xf5\x7c\xa5\x37\xfc\x19\x23\x5d\x72\xd0\x35\xd8\x36\x29\x5f\x45"
+  "\xf7\x60\xc1\xdf\x0e\x0e\x48\x9b\xde\xe3\x49\x12\xb7\x06\x85\x4d"
+  "\xc3\xd4\x72\xd4\x50\xba\xb4\x0d\x3f\x7e\x85\xa6\xb3\x19\x49\x18"
+  "\x4a\x57\xcb\xb2\x9e\xad\x0b\x54\x9d\xbb\x58\xf3\x1d\x45\xd6\x8d"
+  "\x85\xab\x8b\xf2\xb5\x83\xc0\x89\xec\x7b\xf9\xab\xf2\x57\x17\xe7"
+  "\xe7\x59\x97\x6f\x28\x5c\x7b\xdd\xba\xfb\xef\xb7\xde\x95\xbf\x7e"
+  "\xfd\xca\x1f\xe7\x27\xb2\xe5\x85\x2b\xd7\xae\x5f\x4d\xfa\x3a\xab"
+  "\x75\xf1\xcd\x39\x05\xeb\x8a\xae\xfb\xc6\xe2\x8c\xb3\xf4\x75\x74"
+  "\x2e\xb8\x87\xf8\x76\xac\x95\xb3\xb0\x6e\x5e\x48\xbe\x62\x4c\x9b"
+  "\xb8\xe7\x61\xc8\x8c\xc0\xc1\x41\x5a\x73\x30\x77\x3f\x21\x79\x82"
+  "\x7c\xc5\x92\xff\xd9\x5d\x4f\xf2\xae\x7e\x16\x79\x1f\xbc\x68\x37"
+  "\xd2\xc8\xd7\x6b\x0f\xe4\x78\x3f\x8d\x01\xd2\x5f\x44\x9e\xb6\x47"
+  "\x90\xe6\x4f\x18\xce\xd8\xfe\x77\x66\x90\xeb\xe6\x50\x26\xd7\xcf"
+  "\xe4\x35\xe4\xb7\xf5\x53\x0b\x53\xfd\x41\xeb\xbd\xbe\x10\xd9\xaa"
+  "\x18\x97\x86\x9d\x9c\x68\xaa\x9c\x5f\x43\x32\x46\x0a\xe4\x10\x69"
+  "\x33\x1f\x79\x82\xe4\x9e\xad\x22\x96\xd6\x10\xe8\xff\xdf\xbb\xa3"
+  "\xb4\x7a\xb4\x44\xe5\x37\xbb\x01\xf7\x8d\xbd\x78\x96\xfe\x2f\x86"
+  "\xce\xf2\x7f\x71\x72\x19\x63\xa7\x5b\xe5\x8f\xbe\x39\xdd\x26\x7f"
+  "\x74\x1f\xfb\x8b\x38\xe4\xef\xec\xf4\x7f\xf6\xa7\xd5\xff\x3f\xfd"
+  "\x7e\x2c\xf3\xdc\xbf\x7f\xa4\x7e\xd1\xef\xff\x87\xfd\xff\x67\xbe"
+  "\x1f\x5b\x74\xae\x1f\xe1\x1b\x70\xab\xe7\x91\xbf\x33\x23\xf0\x73"
+  "\x47\xed\x7d\xc0\xe9\x8f\x98\xa5\x24\xcc\xfb\x9c\x3f\x62\x69\xa5"
+  "\xc7\x98\x9e\xf8\xbf\x22\x07\xef\x2b\x1d\x23\x59\x7b\x2c\x19\xf8"
+  "\xdb\x5a\xd7\xcb\x92\x6a\x7b\x99\xb9\xb3\x48\xc6\x60\xa0\x3d\x14"
+  "\x3a\x4f\xe4\xc5\x73\x47\x71\x88\xbd\xe5\x1f\x26\xdb\x3d\x4f\x67"
+  "\x2e\x68\x4f\x0f\x63\x84\xbf\x49\xb9\x2c\xb5\x71\x16\x3f\xc4\x5d"
+  "\x8f\x2f\xe7\xfa\xc7\x17\x23\xed\xe8\x0b\x4a\x56\xfc\x0b\x9b\xdb"
+  "\xe3\xad\xf7\xd1\x3a\x7f\x72\x54\xc5\xcd\x2d\xf2\xbc\xdc\xa8\x90"
+  "\xc1\x54\x7f\xbd\x58\x9f\x46\x4f\xcb\x35\x7d\xf4\x0d\x55\x47\x45"
+  "\xf7\x42\xe7\x8a\x7e\xb4\x72\xd7\x7d\xad\x54\xe6\x6f\x94\xd6\x78"
+  "\x5a\x33\x5f\xd8\x9c\x15\x5f\xb2\x92\xe9\x3b\x7d\x83\xec\x30\x68"
+  "\x21\xed\xdb\x62\xde\xed\xc7\x3c\x6b\xd9\x3d\x8b\xd7\xa3\x7d\x35"
+  "\xe0\xe7\xdc\x68\xd3\xbe\xa0\xeb\x8b\x3c\xac\x5b\xcb\x55\x5e\xce"
+  "\x83\x79\xb1\xbf\x16\x79\x96\x6e\x60\x97\xd7\x22\x1f\x78\x3b\x37"
+  "\xf1\xdd\xb2\x7d\x23\x3f\x02\x0c\x0e\xa0\xce\x2e\xeb\xbd\xf4\x3c"
+  "\x2c\x78\x0c\xaa\x1b\xfd\xb0\xf6\x32\xbf\xf0\x87\x43\x75\x68\xf5"
+  "\xa2\x7c\xd0\xbf\xc1\x24\x75\xdf\xac\x5e\x96\xf3\x85\xe4\xc3\xdc"
+  "\xc7\x77\x50\x5c\x38\xf5\x3c\xd2\x8e\xda\xcd\x58\xd7\xc7\x99\x11"
+  "\x75\xec\x40\x1d\x1e\x53\x39\xe3\x26\x3a\xcb\xda\x13\x06\xaf\xae"
+  "\xa8\x76\xa2\xfe\x77\xd5\x6f\x05\x1f\x22\x78\x8f\x08\x33\x49\x9d"
+  "\x03\xf8\x8f\x02\xd0\x09\xf0\x1c\xe2\x1c\x00\xf8\x0d\x4a\x47\x1d"
+  "\x3b\xd0\xaf\x2e\xc8\x82\x07\xb0\x76\xb7\x10\xaf\x70\xef\xe8\x77"
+  "\x98\x88\x89\x0d\x7e\x61\xbd\x83\x87\x64\x8c\x2c\xbf\x5d\xe3\x17"
+  "\x08\x3f\x88\x47\xa8\xbd\x97\x19\x26\x30\xc6\xc0\x91\x76\xf0\x1f"
+  "\xe0\xbd\xfd\xfb\xd5\xb1\x69\x17\x7c\x81\x1a\x1b\x54\xd2\x70\xff"
+  "\x41\xac\xef\x49\xa8\x03\xfc\x6e\x44\xf3\xa5\x04\x1a\xe4\x6f\xd7"
+  "\xd6\x7a\x19\xdf\xda\xbf\x9f\x83\xd6\x01\x6e\x07\xe6\xe7\xea\x20"
+  "\xe3\xf9\xcd\x18\x8b\x03\x94\x97\x7c\x3d\x20\x7f\x08\xfc\x98\x66"
+  "\xcf\xd1\x53\x5b\x4c\x7c\x80\xbf\x8c\xda\x81\x6f\x3a\x00\x6b\x1a"
+  "\x0b\x35\x6e\x20\x60\x2f\x78\x98\x91\xd9\x1a\xec\x31\xd6\x15\x51"
+  "\xf8\x0f\x2f\x8e\x85\x3f\x60\x51\x21\xc7\xe0\xd4\xeb\x31\x63\x07"
+  "\x59\xeb\x54\x23\xe9\x56\x51\xdf\x21\xa9\x17\x1a\xde\x42\xfe\xb8"
+  "\x80\x33\x87\x00\x8b\x43\xc8\xd7\x4a\xb4\x79\xeb\xdf\x41\x73\xef"
+  "\x23\x1e\xea\xd4\x36\xc9\xa3\x9e\x4a\x27\x1c\xc6\xb3\x90\xa3\xfb"
+  "\x98\xbf\x82\xca\x03\x6e\x8c\xe2\x0a\x5e\x76\xf8\x84\xb3\x91\x62"
+  "\x56\x1e\xa7\x98\x95\x89\xea\x58\xfb\xd0\xae\x49\xff\x47\x84\x03"
+  "\x34\xf6\xe8\x63\x85\x94\xbd\x87\x7b\x48\x7f\x26\xbe\x9b\x28\xa0"
+  "\x36\xf6\xd0\xfc\xd4\xde\x23\x7d\x80\xfc\x98\xc6\xc0\xa6\x42\x1d"
+  "\x93\x56\x19\xff\xed\xd4\x16\xb5\x6d\xd9\x78\x36\xa2\x0d\x42\xa7"
+  "\x32\x32\x51\x10\xb7\x9d\xbe\x29\x8d\x7e\x43\xf3\x07\xb8\x6c\xc2"
+  "\x37\x1b\x70\xe5\x5a\x5e\xf2\x41\x8e\x76\x84\x1f\x17\xfe\xa4\x4e"
+  "\xa5\x8e\x4c\xd8\xf4\xa8\x37\x84\x7a\xf5\x84\x1b\x84\x17\x5a\x19"
+  "\xdb\x25\x8c\xf6\x63\xfc\x04\x7e\x1d\x0e\xb7\x02\xee\xa7\xc0\xff"
+  "\x7f\xe8\x91\xfc\xdd\x70\x58\x6d\x9f\x47\xc6\x25\x38\x3e\xbf\x49"
+  "\xfa\x7e\xa1\x7c\x93\xf1\x6f\xa2\x7c\xe6\xb0\xf0\x13\x85\xb2\x3a"
+  "\x54\x9c\x30\x05\x5d\x23\x49\x93\x38\x24\xce\xd5\x9f\xaa\x21\x5e"
+  "\x53\x6d\x3f\xe1\xde\x36\x15\x76\xf3\x09\x07\xc0\xc7\x67\xc8\x71"
+  "\xf6\x57\x10\xaf\x2a\xf1\x70\x64\x99\x56\x86\x3c\x9b\x3f\xdc\xa3"
+  "\xa0\x0c\x0d\x57\x62\x69\x03\xf2\x96\x80\x2e\x4c\xe2\x8d\x46\x0b"
+  "\x64\x99\x81\x17\x55\x3e\xc4\x86\xb1\x21\xdf\xd7\x1e\xe1\x9b\x48"
+  "\xe0\x65\xc0\x7d\x38\x10\x66\x8f\x10\x5e\xde\x4b\x34\x61\xe4\xb3"
+  "\x91\xc4\xd1\xac\x28\x6e\x8f\x1c\xd5\x70\x3b\x66\x5c\x05\x6e\x57"
+  "\x08\x7a\x34\x02\x3e\xfa\x06\x6d\xef\xb8\x87\xe6\xb9\x82\x79\xbd"
+  "\xbd\x58\xe8\xbc\x4d\xa4\xe3\x12\xf3\x3e\x34\x24\x64\x0c\x1a\xcf"
+  "\x4e\x47\x9f\xf0\x37\xbe\x55\x61\xc6\xce\xc0\x67\x24\xf3\x0f\xd2"
+  "\xfc\xd7\xe6\x38\x8d\x0d\xea\xf2\x90\x4f\xf8\x0a\xd0\x40\x9a\x83"
+  "\x01\xb4\x89\xe2\xa0\x93\x9f\xae\xb6\x15\x59\x6c\x3d\xc6\xf6\x70"
+  "\x2e\x8d\x5b\xa0\x48\xb3\xed\xdf\x2e\x69\x40\x92\x8a\x2f\xa2\x8d"
+  "\x67\xc1\xd5\x24\xe1\x1a\xd8\x77\xe6\xfc\x3e\xb5\x84\xe6\x77\x2c"
+  "\x5c\x09\xa6\x04\x5b\xe4\x45\xff\x8f\xb5\x68\x70\x8d\xc2\x74\xf4"
+  "\x0e\x15\x1f\x55\xda\x3a\x3a\x25\x6d\xdd\x2e\xfd\xef\xb7\x6e\xa5"
+  "\xbe\x60\x4d\xa1\xfa\x45\x7c\x19\x55\xf6\x69\xf3\x13\x4e\x91\x6c"
+  "\x9d\xb7\x44\xa3\x63\x68\x4f\x3d\xe1\x13\x8d\x95\x46\x3b\x48\xff"
+  "\x23\xdb\x3e\x9a\xa7\x8d\x07\xb5\x3b\x96\x26\xa0\x0d\xbf\xa5\xe7"
+  "\x68\x9f\x47\x9f\xc0\x77\x17\x11\x6d\x8b\xf2\x57\xa3\x7b\xcf\xec"
+  "\xfb\x68\x0d\xf5\x9d\x70\xc2\x5e\x4c\x3a\x20\xb9\x96\xf9\xd8\x17"
+  "\x96\x33\xe9\xd5\x17\xc9\xd2\xd6\x40\xf2\x63\x44\xef\xed\xf7\xca"
+  "\xfc\xb4\xbe\x21\xbf\xd0\x89\xaa\xeb\x61\x09\xad\x7f\x48\x33\xa8"
+  "\x30\xe8\x41\xfe\x36\x3a\x2f\x4c\x3e\x63\x2e\xe8\x91\xb2\x20\x68"
+  "\xf4\x21\x8a\x43\xe0\x63\x27\xdb\x3a\x51\x6a\x78\x06\x63\x8d\x2a"
+  "\xbf\x49\x74\x82\x6f\xcc\xbe\x60\xe3\x00\x4b\xb0\x7f\x83\x7f\x8a"
+  "\xf5\xfc\x35\xcc\xa3\x10\xf9\x30\x44\xd9\xd6\x7e\x76\xfa\x69\xd4"
+  "\x9b\xaa\x5e\x2d\xb8\x56\xe1\x3a\x1b\xd7\x87\x70\xbd\x0c\xd7\x1f"
+  "\x20\xbf\xa2\xe6\xcf\xc0\xf3\x37\x91\x7e\xb3\x7a\x45\x1b\xc7\x5a"
+  "\x71\x5d\xf6\x08\xf1\x95\xf7\x8a\xf4\x4b\xe8\x19\xd7\x78\xb5\xdf"
+  "\x1d\x72\x6e\x8f\x7d\x86\x72\x1c\x94\x8f\xd6\x35\xa4\xd9\xfb\x59"
+  "\xe8\x0d\x2a\x9b\xce\xef\xe3\x7e\x4b\x0c\x7f\x8a\x72\x82\xcf\xe2"
+  "\x9a\x89\xeb\x83\xb8\x16\xe1\x7a\x23\x95\x0b\x18\x74\x45\xe9\x85"
+  "\xbf\x22\xcf\x21\xc7\xd3\xc7\x46\x48\xc6\x4c\xd5\xe8\x01\xe1\xd3"
+  "\x19\xf9\x56\xc8\x7c\x52\x7e\x0d\xe6\x6a\x63\x17\x96\x78\x9b\x1a"
+  "\xc6\xd8\xa1\xfc\x6f\xd2\xf7\xb8\xde\xae\x5e\xb3\xd4\xeb\x1d\xea"
+  "\xf5\x3f\xd4\xeb\x62\xf5\xba\xc4\xc7\x82\x19\x2a\x6f\x02\x98\x05"
+  "\xa9\x0c\xd2\x99\x2d\x91\xf5\x86\xf2\x48\xbe\x06\xfd\x5f\x30\x42"
+  "\x31\xc5\x5c\xc1\x6e\x4d\x17\x4b\xba\x9f\x09\xd7\xf1\xff\xd8\x25"
+  "\x74\x3f\x41\x7f\x0c\x2d\x64\x49\xba\x2c\x06\xde\x69\x46\xa3\x1e"
+  "\x7c\x83\x2c\x67\x89\x5e\xdd\x83\xa6\xd8\x1a\x14\x2b\x8d\x7c\xc7"
+  "\x09\x39\x2a\x39\xb3\x81\xe6\xab\xd0\x53\x57\x91\x2f\x9c\x61\x03"
+  "\x7e\x66\xc8\x14\xa9\x1a\xbd\x27\x79\x49\xf5\x11\xf9\x4a\xd0\x15"
+  "\x5a\x11\x95\xf3\x43\x49\x72\xbf\xee\xd2\x2b\x90\x1e\x23\xff\x07"
+  "\xdb\xa9\xcd\x80\x75\x37\xfa\x93\xd9\xcb\x42\x8d\xb8\xde\xd4\x27"
+  "\xfb\x9c\xa1\xf5\x59\x1d\x2b\xbb\x06\xf3\x3e\x16\x5c\x08\x7a\x58"
+  "\x48\xf8\xdd\x3b\x49\x97\x83\x42\x3f\xad\xe2\x0f\xc6\x79\xec\x18"
+  "\x8d\x77\x0c\x3d\x29\x89\xd2\xe9\x50\xe8\xcc\x71\xf1\x87\xc2\x92"
+  "\x5f\xe8\xc6\xbc\x04\x0e\x8c\x79\xce\x9a\x97\x35\x34\x2f\xe5\xb7"
+  "\xa7\x33\xcf\xa4\xf1\xa3\x35\x44\xe3\xd5\x36\x02\x6f\xc7\x9a\x69"
+  "\x6c\x7c\xec\x74\xaa\xba\x26\x75\x63\x8d\x5c\x80\x74\xb7\x6c\xa7"
+  "\x4c\x57\xeb\x02\xfe\x8d\x95\x11\xfe\x6b\xe9\x2a\x7e\x53\x39\x0e"
+  "\x1a\x6b\x2d\x5d\x2d\x1f\x78\x3a\x66\xa7\xf9\xa3\xa5\xab\x38\xd9"
+  "\x4e\xf4\x86\xbe\x0d\x0b\xbb\x3b\xc8\xdf\xf7\xb6\xa1\xdd\xa7\x49"
+  "\xa7\xd8\x4c\xf3\x79\xeb\x66\x96\xb4\xb1\x81\x25\xcb\xb9\x39\x7e"
+  "\x89\xf6\xad\xd4\x53\x8f\x1b\x35\x1a\xb5\x5d\xd0\xb3\x40\xc9\x99"
+  "\xb4\x32\xfc\x4b\xee\x32\x85\xc3\x46\x7f\xf8\x48\x38\x53\xd0\x5c"
+  "\xcc\xfb\x46\x7c\x97\xe5\x63\x8f\x33\x75\x2d\xe9\x90\xfb\x04\xe3"
+  "\x1b\x8e\x34\x4b\xda\xa5\x96\x3d\x49\xff\x62\xf8\x10\x41\xeb\xa9"
+  "\x2e\x2a\x0b\xeb\x8a\x39\xe0\xcc\xbe\x40\xd2\xef\xf1\x1d\x3e\x76"
+  "\x41\xba\x46\x5b\x69\x7d\x32\xe9\x98\xbd\xee\x5e\xb9\x3e\x29\xa4"
+  "\x03\xb3\x07\x84\xef\xaf\x4e\xfb\x10\xa3\x75\x93\x7c\x32\xe7\x6c"
+  "\x4a\x24\xdf\x48\xd9\x68\x6b\x15\xf8\xb3\xbd\xea\x7e\x03\xe4\xdc"
+  "\xf0\xd7\x49\x96\x55\xe1\x8a\xf9\x14\x9e\xab\x8e\x4b\x0f\xda\xb3"
+  "\x97\x68\xfb\xd6\x62\x19\x9f\x86\xf4\x41\x22\x9e\x11\xf1\xac\x16"
+  "\x1e\x92\xfe\xe5\x27\xd2\x63\x74\x5c\xcd\x72\x9e\x8c\x27\x88\xd8"
+  "\x00\x6e\x7f\x58\xea\x13\x27\x7e\x2b\xd3\x27\x54\x5f\x55\xc3\xaa"
+  "\xaf\xff\x89\xb2\x38\xcb\xac\x9f\x4a\xbd\xf0\xf1\xfb\x24\x3f\x32"
+  "\x51\x14\x63\xc7\x22\x60\x2d\x7d\xcf\x4e\xd4\x44\xe7\xc5\x44\x2e"
+  "\x7d\x83\x6f\x77\x22\x7d\xd2\xff\x97\x5c\x6b\xfc\x0e\x55\x67\xc6"
+  "\x2e\x28\xcf\x62\xa0\xcd\x33\x76\xb9\xb4\xf9\x1b\x16\xfe\x09\xb5"
+  "\xf9\x4b\x7d\x24\x7c\xa0\x39\x1c\x26\xff\x55\x98\xc3\x34\x97\x71"
+  "\x6f\x08\x6b\x73\x57\xf2\x77\x25\x62\xee\x8a\x79\x1b\x4e\x8d\x69"
+  "\x47\x87\x8a\xab\x3d\x23\xab\x2c\x49\x78\x87\x39\x39\xa8\xfa\x07"
+  "\x1a\x97\x32\x46\xd5\xfb\xb9\xca\x18\x0f\x91\x6e\x9a\xf4\x09\xa4"
+  "\xb3\x51\x6d\x2b\x49\xff\x1f\x20\x9f\x5c\xf5\x98\x0f\x51\x3f\x5c"
+  "\x66\xa6\xf9\xe1\x42\x79\x65\x51\xdd\xf1\xb8\x4f\xf6\xcb\x4f\x7c"
+  "\x4b\xa3\xa7\xf4\x4f\x04\xe7\xb7\xe5\x1c\x1b\xef\x22\x3c\xf6\x02"
+  "\xf7\xb0\xfe\x34\x50\xbc\x73\x7c\x7b\x48\xc3\x3d\xcc\xd1\xbc\x7e"
+  "\x16\xb9\x6b\xc7\x2c\xde\x80\x31\x25\xfb\xf0\x35\x78\xfe\x3a\xae"
+  "\x79\xf2\xaa\x33\xd3\x55\xc5\xf9\x06\x7c\x8b\xf9\x9f\xd8\xae\x8d"
+  "\x41\x20\x39\xad\x59\xe0\x58\x29\xd9\xec\x65\x88\xfd\x6b\xc2\x31"
+  "\xc2\x2f\xb1\x8f\x0d\x5c\x33\x95\x7f\x87\x11\x9e\x09\xdf\x1c\x78"
+  "\xa6\xf6\x12\x9e\x05\x5d\x91\xc5\x9a\x1f\x5a\x1f\x0b\x0f\xc8\x3d"
+  "\xa4\x48\xb6\x66\xb3\x4c\x78\x58\x74\x05\xbb\x04\xe5\x5b\xdb\xac"
+  "\x01\xd2\x9d\x7f\xec\x0d\xdf\xc1\x28\x2f\xc1\x4e\xd2\xcb\x4b\x8b"
+  "\xf0\x4d\xcc\xf8\xfb\x85\x0d\xcb\xe1\x15\x42\x9f\x79\x31\xde\xed"
+  "\x3b\x93\xe6\x0c\x65\x0a\xbe\x12\xeb\xf3\x55\xa9\xcc\x0a\xbc\xc5"
+  "\x5a\x13\xe9\xd0\xf8\xe1\x1b\x52\xc9\x86\xe0\xb8\x88\x15\x4e\x3c"
+  "\x09\xee\x3b\x68\x9d\x9e\x46\xef\x9c\x49\xba\x22\xa2\x19\xa4\x7b"
+  "\x22\x3d\x18\x60\x7d\xb4\x5f\xa7\xbb\xeb\x08\xf9\xc9\x59\xf7\x65"
+  "\x5f\xc4\xa5\x0e\x3e\x4a\x7e\x9b\xac\x85\xec\xe2\x5e\x9d\x2e\x83"
+  "\xf4\x4e\xce\x61\xd2\xf1\x28\xcb\xcf\xd4\xf1\x28\x7b\xd5\x5f\x2b"
+  "\x4a\x4a\x8b\xf9\xed\x57\xaf\xb6\xaf\xf8\xb5\xa9\x79\xbb\xf0\xeb"
+  "\x51\x61\x75\x20\xe8\x52\x5a\x35\x58\x11\x4d\x21\x1a\x4b\xb6\x23"
+  "\x34\xcf\x75\x61\x46\x7b\xaf\x18\x27\xb4\x7b\xeb\xb5\xdf\xf3\x6c"
+  "\x26\x99\x56\x11\x36\x50\xe4\x53\xf6\xfc\xec\x97\x14\x31\x9e\xd2"
+  "\xe7\xa7\xb2\x1f\x75\xb7\x6d\x3f\xc9\x0c\xf6\x42\x36\x97\x74\xe8"
+  "\xa6\x08\xf7\x90\x0c\x6c\x92\xf1\xd9\xbb\x06\x19\x7f\xbe\x68\x0b"
+  "\xd3\xe3\xfd\xe5\xb8\x6f\xd4\x78\x29\x7c\x63\x8e\x0b\xb1\x54\xe2"
+  "\xa1\x6e\xdf\xc2\x2e\x0f\xba\xb8\x43\x1b\x2b\xe2\x33\x48\x8f\x17"
+  "\x8d\x1d\xa4\x08\xbb\x2c\xf2\xaf\xee\x13\x70\x53\x69\xd5\x49\xd2"
+  "\x5d\xf3\xbc\xb8\x00\x33\xcb\x75\x88\x03\xff\x8f\x97\x48\x7c\xe1"
+  "\x65\xc0\xfd\xa3\x31\xed\x1c\x8b\xde\x5b\xfe\x8d\xbe\x37\x05\x88"
+  "\x87\x9b\x06\x3e\x3a\x96\xa0\xc1\x87\x6c\xe4\x4d\xe0\xff\xc5\x78"
+  "\x87\xf9\x10\xda\xd6\x61\xdf\xcc\x8c\x83\x3a\x76\x1a\x7d\xa4\x33"
+  "\xa8\xed\x42\xc7\xaf\x63\x27\x34\x39\x5d\xb4\x5b\xc7\x0e\x9a\xca"
+  "\xe3\x18\xe9\xe6\xc9\x37\xa1\xb0\x2f\x04\x4b\x4a\x3c\xbc\x37\xbc"
+  "\x88\x79\x4a\x6f\xa1\x3c\xdb\xd4\xb5\xac\x67\xc4\x69\x61\x87\x2d"
+  "\x8b\x58\xb0\x92\x55\x60\xae\x84\xce\xdb\x8e\x53\xc7\xb4\x7d\xf0"
+  "\x0e\x61\xff\xa0\x63\xf7\xd0\x5a\x42\xba\x01\xac\x23\x6d\xb4\x5e"
+  "\xa3\x6c\x9f\x36\x6f\xb0\x4e\xb4\xe1\x9b\xe5\x92\xc6\xbc\xe7\xc3"
+  "\xfd\x32\xf2\x8f\x22\xe4\x07\x99\x3f\x49\xec\x1b\x54\xea\x52\x27"
+  "\xf9\x6d\xe4\xa3\xef\x84\x5d\x9c\x8e\x7c\x0d\xe9\x18\xbe\xb3\x51"
+  "\xdf\x24\x2e\x5a\x16\x21\xff\xe2\xe8\xbc\xe5\x65\x62\xde\x0e\xc5"
+  "\xcc\xcb\x4a\x5d\x5e\x54\x4e\x55\x2c\xd7\xed\x60\x53\x9e\xcd\xb7"
+  "\xa7\x30\xf3\x71\x23\xfb\xfe\xf6\xed\xbc\xb9\x5e\xaf\x7c\x6b\x6b"
+  "\x1d\xd8\xb3\x1a\x80\x8d\xe6\x59\x71\xee\x25\x98\x8f\x9f\x99\x92"
+  "\x2e\x5d\x76\x7b\xd1\x4c\x5e\x6a\x61\xfa\xda\x53\x33\x8d\x57\x84"
+  "\x2e\x6d\xe6\x71\xd7\x7e\xef\xae\x22\xda\xcf\xad\x67\x9f\xaf\x61"
+  "\x71\xb7\x47\x50\x77\x12\xb3\xfb\x74\x71\x7e\x3a\x4f\x7d\x18\x9c"
+  "\x17\xdd\x53\x99\x25\x8d\xcc\x58\xd2\xc7\x07\x6a\xee\x8f\x37\x62"
+  "\xfd\x35\x63\xdd\x70\x5f\x90\x74\x69\xf3\x04\xca\x78\x2d\x57\x7c"
+  "\xd7\x72\xfe\x6d\xb3\xcf\xea\xd7\xe9\xcb\xcf\xaf\x6d\xf1\x19\xd1"
+  "\xb6\xc5\x67\xfc\x5f\x6e\x9b\x39\xda\xb6\x02\xb4\x2d\x6e\xee\xf9"
+  "\xb5\x6d\x86\x3d\xda\xb6\x19\xf6\x7f\xb0\x6d\xfb\xcf\xbf\x6d\x8e"
+  "\x4b\xd1\xb6\x83\xe7\xd7\xb6\x99\x2d\xd1\xb6\xcd\x6c\xf9\x67\xda"
+  "\x56\xda\xc8\x3f\xeb\x04\x05\x26\x7d\x0e\xd1\xf9\x7e\x9d\xe1\xe5"
+  "\x2d\x69\xc2\x36\xf9\x22\xdc\x3f\xe4\x6c\xe4\x9f\x0a\xde\x46\x67"
+  "\x10\xba\xff\x60\xa5\x61\x3e\xe4\x52\x19\x07\x48\x17\x9f\x26\x6c"
+  "\x37\xe2\xe6\xec\xe3\x2e\x1e\xbe\x3e\x40\x76\x70\x61\xf2\x21\x42"
+  "\xfe\xb9\x17\xbe\x30\x16\xd2\xf3\xc4\xe1\x25\x7b\x4e\x19\xd8\x0b"
+  "\x63\x7e\x3d\xbe\x2d\xd0\xfc\x86\x6a\xdf\x9a\x1a\xce\x45\x8f\x0c"
+  "\xbb\x6f\x2f\x60\x26\xa2\x47\x74\xa5\xd8\x84\xdb\x4b\x67\x1a\x6f"
+  "\x1f\xc6\xba\x5f\x69\x38\xa0\x9d\x0b\xd5\xca\x5a\x3a\x30\x93\x9b"
+  "\x4a\x58\x1c\x9d\x4d\x15\x3e\x06\x2d\x7e\x96\x5e\xc2\xe2\x97\x3a"
+  "\x50\x7e\x88\xe5\x9a\x1c\x28\x1b\xf0\x10\xbc\xbc\xce\x70\x3a\x6e"
+  "\x0d\x4b\xda\x81\xb2\xe9\x7a\xbb\xc5\xc9\xb7\x3e\xc5\x0c\x74\x86"
+  "\x95\xce\xa2\xca\x73\xa8\x33\x8c\xc1\xca\xf8\x34\xad\x9e\xaf\x80"
+  "\x5f\x8a\x84\x5f\x7c\x24\x0a\xbf\xf8\xdf\x46\xe1\x17\xbf\x41\xc2"
+  "\x2f\x7e\x4d\x14\x7e\x33\x56\x9c\x1f\xfc\xe2\xf7\x45\xe1\x27\xbf"
+  "\x3d\x37\xfc\xe2\x3f\x9a\x1e\x7e\xf1\x81\x28\xfc\x64\x59\xd3\xc0"
+  "\x6f\xc6\xd4\xf0\x9b\xf1\xf5\x7f\x0c\x7e\x33\x56\xfc\x83\xf0\x4b"
+  "\x96\xf0\x9b\x79\x6b\x14\x7e\x33\x86\xa3\xf0\x9b\xf1\xa2\x84\xdf"
+  "\x8c\xfd\x51\xf8\xcd\x6c\x3c\x3f\xf8\xcd\x18\x88\xc2\x4f\x7e\x7b"
+  "\x6e\xf8\xcd\x9c\x3b\x3d\xfc\x66\x66\x46\xe1\x27\xcb\x3a\x3f\xf8"
+  "\xcd\xdc\x04\xb8\x99\x55\xf8\x99\xa7\x87\xdf\xcc\xc6\x7f\x10\x7e"
+  "\x26\x09\x3f\xe3\x96\x28\xfc\x8c\x37\x46\xe1\x37\x73\x54\xc2\x6f"
+  "\xe6\x50\x14\x7e\xc6\x9e\xf3\x83\x9f\xd1\x16\x85\x9f\xfc\xf6\xdc"
+  "\xf0\x33\xfe\x68\x7a\xf8\x19\x8b\xa2\xf0\x93\x65\x4d\x03\xbf\x99"
+  "\x53\xc3\xcf\x78\xf0\x1f\x83\x9f\xb1\xe7\x5c\xf0\x3b\x3f\x5e\xc3"
+  "\x38\xad\x5d\xf1\xf9\x95\x93\xb0\x70\xba\x72\x08\x86\x64\x73\xa7"
+  "\x54\x26\x2c\x6c\x52\x66\x18\xe5\xb9\x04\x23\xc5\x3e\xbb\xad\x57"
+  "\x97\xb0\xad\x49\x89\x37\x72\xd7\x5f\x5a\x14\xd7\x1b\xd9\xbc\x7c"
+  "\x86\x41\x29\x9f\x69\xa0\x73\xf3\xd3\xc6\x3a\xd6\x25\x7c\x16\x37"
+  "\x9b\xcd\xa3\xb3\x65\x5b\xc1\xaf\xd1\x7d\xb0\x32\xc1\x0f\x5e\xe4"
+  "\x4b\x7e\xb8\xf3\x56\xaf\x17\x81\x13\x0b\xf3\xf3\x36\xac\xcd\x5b"
+  "\xb9\xb6\xc8\xba\x72\xd5\x03\xeb\xcf\xf4\x6b\x2e\x62\x0e\x56\xd0"
+  "\xf8\x25\x66\x4e\xfa\x32\x01\x1f\x4b\x3e\xe1\xec\x57\xb2\x84\x41"
+  "\x5d\x62\x91\xf0\x35\x9f\x38\x7c\x80\x4f\x64\xef\xcc\xba\x8a\xbf"
+  "\x2a\x7c\xdd\x4d\x14\xec\x84\x3c\x55\x44\xfe\x4b\xd4\xbd\x89\xa2"
+  "\x7e\x5d\x52\x2d\x4f\x18\xf5\x91\x4d\x87\x38\xaf\xa0\x4b\x14\xfe"
+  "\x11\xc9\xaf\x09\x37\x1e\xef\x50\xdc\xa3\x3e\x5e\x35\xda\x4d\x30"
+  "\xe8\x24\x3f\x63\xc5\x71\x97\xf7\xea\x52\x96\xf1\x84\xe3\x1d\x28"
+  "\xab\x4b\x2d\x47\xc4\x17\xce\xda\xcc\x3f\xa6\xf2\x54\x5e\x90\x62"
+  "\x49\x78\x24\x3f\x78\x41\x82\xa9\xdc\x1a\x47\x79\xc9\xdf\x1f\xf9"
+  "\xc1\xd3\xe2\x07\x51\xbb\x29\x2f\xf8\xf1\xdb\xf0\xfd\x6d\x7b\x28"
+  "\x3e\x90\x56\x86\x6c\xd3\xc5\x83\xba\x0b\xb2\x44\x5f\xdc\xc7\x1d"
+  "\x23\x0f\x67\xef\x14\x31\x05\x05\x5c\x53\x16\xa0\x6e\x07\x95\x41"
+  "\x7e\xb8\xe8\x5b\xf5\x9b\xb9\xf8\x46\xd0\x53\xf2\xf1\x29\xcb\x48"
+  "\x99\xab\xb5\x0b\x3c\x74\x22\x9e\xe3\x63\xea\xb8\x60\x50\x97\x7c"
+  "\x22\xe6\x7d\x12\x9e\xdf\x06\x1f\x7a\xa1\xfa\x3e\x19\xcf\x2f\x12"
+  "\x5f\x2a\xfa\x55\x57\x26\xed\x7c\x75\xc9\x0d\x48\x33\xab\x79\x2e"
+  "\x44\x9e\x2d\xc4\xeb\xaa\x65\x5c\x84\xe7\x95\x24\x33\xaa\xef\x53"
+  "\xf1\x7c\x07\xed\x0b\xa8\xef\x2f\xc1\xf3\x35\x78\xfe\x57\xf5\x3d"
+  "\xf8\xfa\xa4\x5c\xd1\x66\xe3\xf1\x36\xea\x13\x60\xef\x21\xb8\x03"
+  "\xd6\x6d\x48\x2b\x82\xbc\xea\xa4\x71\xa4\x7e\x7a\x36\x0f\xb2\x5e"
+  "\x5d\xd2\x3d\x74\xd6\x4c\x8e\xd5\xa8\x4f\xfa\xa1\xd1\x67\x23\x7d"
+  "\x39\xa5\x93\xbd\xb4\x52\x35\xea\xa1\x7b\xc0\xf4\x04\xc1\x50\xad"
+  "\xeb\x72\xd4\x55\xa2\x8e\x33\x60\x47\xbe\x62\x59\xd9\x1e\x75\x2c"
+  "\xd0\xb6\x99\x78\xff\xbe\x66\x7f\xb1\x34\x3c\x21\xcf\xcc\xe8\x92"
+  "\xf6\xfe\x8f\x7c\x23\xe0\x3b\x49\xf7\x92\xfa\xb4\xb8\x72\x48\x13"
+  "\xb1\xea\x09\x3f\x49\xbf\xe2\x4f\x38\x9e\x2b\x7c\x81\x00\x47\x35"
+  "\x5c\x21\x3c\xe1\x33\x12\xc2\x42\x57\x53\x99\x1c\x8d\x7f\xa2\x4b"
+  "\x5a\xa1\xfa\xe2\x67\x52\x4e\x48\x5e\x34\x69\x5f\xa4\xbb\x40\xd0"
+  "\x87\x98\x77\xd9\x31\xef\x7c\xda\x3b\x61\x03\x57\x99\x5c\x14\xf3"
+  "\xae\xeb\xac\x77\xf5\x31\xef\x3c\x67\x95\xb9\x3f\xe6\x5d\xcb\x59"
+  "\xdf\xb5\xc7\xbc\x6b\x3c\xeb\x5d\x5f\xcc\xbb\x1a\xf5\x5d\x1c\xd2"
+  "\xc3\x93\xbe\xf8\x74\x17\x94\xa8\xe9\xa0\xf5\x29\xa9\x31\xe9\x6b"
+  "\xd4\x74\xd4\x9f\x02\xfe\xef\xa5\x16\x35\x5d\xe0\x39\xf0\xe8\x5f"
+  "\x64\x1d\x29\x4b\x62\xea\x58\xa4\xee\x1f\xe7\xca\xf1\x4b\x3c\x60"
+  "\xd2\x59\x67\x12\x4e\x99\xca\xcb\x28\xae\x4b\xbd\xf4\x3b\x25\xe7"
+  "\xa1\x88\xe9\x4b\xf2\x30\xf2\x4d\x47\x1b\xa7\xb4\x11\xac\x4c\x39"
+  "\xa4\x9d\xcd\x8c\xb8\x8f\xe7\x29\x35\x73\x0b\x28\x56\x1c\xf9\xa7"
+  "\x72\x0e\x91\x8f\x92\x00\xf3\xb2\x71\xe6\x2d\x0a\x96\x51\xbc\xb8"
+  "\x4e\x19\x27\x8e\xce\xb4\xe9\xe8\xcc\x06\xf9\xd8\xea\xb4\x9f\x10"
+  "\xb1\xe2\x36\x0e\xb1\x34\xfb\x37\x78\x5f\xbf\xce\x64\x8d\x54\x1d"
+  "\xcf\x53\xfd\x0c\x3c\x25\xce\x42\xeb\x4c\x72\x7e\x90\x1c\x3b\x24"
+  "\x74\xcb\x46\xe4\x6b\x11\x79\x78\xf6\x53\xb2\x8f\x26\x31\x1e\x7b"
+  "\xd4\xf3\x71\xc1\x4a\x53\xf6\x64\xfc\x42\x9d\xe9\xc0\x68\x42\x68"
+  "\x09\xd2\xd6\x9c\x61\xd3\xa8\x33\x6d\xa3\x32\xa9\xed\xc8\x63\xa3"
+  "\xb2\x91\xa7\x7e\xd2\xa6\x11\xe9\x1b\xc3\x6c\x0e\xda\xd5\xaf\x95"
+  "\x8f\xf7\x2d\x3e\x5d\x8a\xb0\x8f\xa6\x32\x47\x6b\xe7\x51\xb9\x6d"
+  "\x3e\xfd\x1f\xc5\xb9\x25\xdc\x77\xf9\xd8\x9f\x0d\xd3\xad\x79\x42"
+  "\x0f\x69\x1c\x0d\x71\xf7\x18\xc3\x3c\xf7\x0b\xbb\xdb\x84\xd1\x90"
+  "\x94\xdf\xcd\x73\xc9\xe6\x82\x62\x20\xd3\x5e\xa3\xa4\x35\xe6\x95"
+  "\x62\xbe\x22\x0d\x63\xb4\x8f\x57\x8d\x09\xbd\xce\xf9\xcd\x43\xf3"
+  "\x7c\x51\xc6\x29\x66\xac\x53\xed\x5c\x83\x95\x66\x47\x4c\x1c\x01"
+  "\x69\xc7\xae\x33\x3f\xdd\xe9\x10\xfb\x4d\xa2\x8d\x67\xb7\x81\xda"
+  "\x8b\xb2\xd2\xa6\x5d\x3f\x8d\xa3\x7e\xa1\xfb\xac\x1e\xce\x16\xf6"
+  "\x63\x3a\xf3\xb1\x38\xcb\x65\x4f\xa2\xae\xbe\xc9\xf8\x09\xc8\x53"
+  "\x37\xce\x98\x82\xf2\x27\xfb\x59\x48\x75\x5c\x28\xf6\x27\x7c\xba"
+  "\x0b\xad\xa0\x5d\x7e\x6a\x83\x9a\x6e\xed\x0c\x87\xe8\xec\xf7\x94"
+  "\xfe\x9d\x68\x5d\x14\xbe\x81\xaa\x47\x45\x6c\xf0\x1b\x42\x5a\x9b"
+  "\x2f\xb2\x92\xfd\x39\xb5\x59\xc2\xf6\xa2\x4b\x34\x38\xd6\x9e\x42"
+  "\xd9\xa5\x1f\xb0\x3e\xdd\x85\xbb\xc9\xa6\x85\xce\x53\x6c\xdf\xac"
+  "\xda\x59\x21\x4d\xe4\x1b\x9f\xcc\x23\x74\xbd\x64\xe3\x4b\x34\xb4"
+  "\x89\xce\xc5\xa3\xcc\x3a\x8c\x85\xf0\x79\xa1\xbb\x50\x9c\x85\xd8"
+  "\x5a\xc8\x64\xbf\xc9\x86\x4d\x77\xd1\x62\x89\x2b\x17\xf6\xf8\x74"
+  "\x17\x2d\x93\x38\x28\xd3\x28\x86\x36\xd9\x1e\x9c\xd4\x5d\xf8\x32"
+  "\xc5\xf4\xe4\xc6\x31\xe1\x17\xad\x33\x80\x79\xe2\xc0\x73\xc2\x98"
+  "\x88\xdd\x06\x38\x1c\x92\x6b\x02\xc1\xfc\x42\xf2\x03\x27\xf6\x75"
+  "\x28\x9e\x29\x60\xba\x37\x58\x79\xd1\x64\xfc\x2f\x8a\x9d\x8a\x3c"
+  "\xcb\xa7\x1b\x17\x82\x51\x04\x6d\x26\xff\x1e\x9e\x39\x1f\xa0\x7d"
+  "\x17\xeb\x94\xc4\x51\x3f\xd9\x4c\xa2\xad\xbf\x94\xb4\x42\x8e\x9d"
+  "\x9c\x4b\x17\xbd\x8f\x3a\xbc\xb4\xbf\x48\xf6\xd8\x22\x0e\xb4\xee"
+  "\xa2\x32\x15\x7e\x22\x9e\x42\x7d\xb1\x84\x83\xcc\x7f\x71\xa6\xd4"
+  "\xc5\x5c\xf6\x2e\xda\xd5\x35\xa9\x8b\x41\xba\xd0\xa3\xa9\x76\xd5"
+  "\x78\x37\x14\xd3\xe6\x80\x38\xcf\x76\x8a\xe4\xe8\x8b\x76\x50\x5d"
+  "\xb5\xe4\xb7\x8a\xf0\x62\x30\x16\xff\x2f\xda\x40\xed\x24\x7b\xbc"
+  "\x48\xc2\x70\x36\xaf\x1a\x5e\x41\x70\xc6\x37\xfb\xc1\x9f\xf8\xa7"
+  "\x89\xb3\x2d\xe2\x05\x05\x2b\x2f\x5e\x11\x13\x03\x15\x6b\xdf\xc5"
+  "\xb5\xda\xda\x46\xeb\x32\xf9\x21\x98\x4c\xab\x5d\x60\xc4\x7c\xdf"
+  "\xa7\xf2\x35\xfb\xa6\xf5\xa1\x77\x3d\xcb\xa0\x33\xb3\x64\x9b\x4d"
+  "\xf8\xc6\x93\x32\xf7\x91\x5f\x5e\xf2\x31\xe8\xd9\x7c\x13\xda\x9b"
+  "\x7a\xeb\xe3\xb3\xc4\x39\xbd\x80\xe7\xfa\x53\x64\x97\x33\xd4\x5f"
+  "\x22\x7c\xe7\x18\x97\x3a\xc2\x7c\x8f\x8c\x73\xec\xe7\xc9\x99\xfb"
+  "\xe8\x9d\xf0\x4b\x4f\x65\xfe\x4f\x7d\xcc\xea\x52\x8d\x2a\xff\x32"
+  "\x04\x5a\x79\x29\xfa\x23\xf6\x0b\x70\x3f\x6b\x50\x77\x49\xbe\x8c"
+  "\xdb\x27\xfd\xa4\xab\xf6\x85\x33\xe4\x39\x73\x3f\x13\xe7\x7e\x75"
+  "\xa9\xef\x5b\xaf\x65\x6c\x48\x97\xfa\x91\xf0\x59\xec\x3e\xde\xaa"
+  "\xc2\xa0\x75\xbb\x6c\x97\x29\xc7\xa1\x17\x6d\xa4\xf6\x9d\x67\xdb"
+  "\xf6\xaa\x6b\xd7\x8c\x60\x65\xea\x80\x76\x3e\x5d\xf4\x5f\xf5\x65"
+  "\xec\xb9\x92\x64\x95\x4b\xee\x51\xd7\xab\x43\x6a\xdd\x87\xfe\xf9"
+  "\xba\x2f\xb1\xaa\x65\xd6\x0b\x7f\xce\x80\x0b\xca\xad\x0f\x56\x5e"
+  "\x62\xd7\xd6\x50\xd5\x2e\x7e\xbe\x5c\xdb\x2f\x71\x47\xd7\x4f\x09"
+  "\xc3\x33\xce\x9e\xac\x5b\x57\x64\x05\x93\x6e\x5f\x59\xb4\xaa\xc0"
+  "\x9a\x5f\x58\xb8\xae\xd0\x4a\xce\x57\x62\xe7\x98\xb0\x7b\xa9\xbc"
+  "\xa4\x51\x8d\xc1\xb5\x6f\x32\x06\x57\xe5\x25\x7d\xb1\xb1\xd1\xd0"
+  "\xb6\x81\xff\x3b\xb2\xcc\xac\x2f\xc5\x5d\xd4\xca\xa9\xd7\x2b\xa4"
+  "\x9b\x6a\xc5\xcf\x83\x5f\x3b\xc9\x36\x39\x21\x96\x85\xf5\x51\xf0"
+  "\x3b\xd1\x73\xd7\x97\x1c\xa2\xbd\xef\x5e\xdd\xac\x95\x4d\x8a\x81"
+  "\x09\xbf\x1b\x2e\x85\xec\x47\xc8\xf7\x76\x2b\x7e\x1e\xfc\xda\xf1"
+  "\x13\xdf\x29\x7f\x12\x67\x46\x5b\x62\xdf\xd1\x7e\x34\x77\xed\xed"
+  "\xa3\x3c\xbc\xdc\x20\xd6\x27\xe5\x31\x99\xef\xac\x36\xe8\x79\xa5"
+  "\x49\xcb\x27\xda\x9e\x52\xce\xac\x53\xe4\x8b\xe3\x95\x89\x69\x6a"
+  "\x3e\x81\xdf\x5a\x7f\xc8\x2f\x3c\xf2\x6b\xf9\x0c\xbc\xf2\xe2\x66"
+  "\x35\x9f\x3c\xcb\xe4\xd2\x4f\x55\x6f\x3c\x77\xbd\x5f\xa1\xe6\x33"
+  "\xc7\x96\x17\x93\x67\x86\x52\x29\xe2\xed\x76\x29\xe5\x06\xb1\xaf"
+  "\xcb\x2b\x67\x19\x90\x7f\xca\x73\x79\xe7\x37\x4e\x97\xee\x3f\x7b"
+  "\x9c\xec\xab\x56\xe7\xdf\xb2\x7a\x6d\x31\x45\x29\x2a\x5a\xb7\xa1"
+  "\x88\xae\x6b\x57\x3e\x20\x2e\xeb\x72\xee\x5f\x25\x6f\x8a\xd6\x64"
+  "\xd0\xcd\x1a\xe0\x1b\x5d\xf3\x36\xd8\xe9\xb2\x6a\x1d\x3d\x3a\x0a"
+  "\xe6\x6f\x58\xa5\x85\x56\x8e\xc5\x43\x5b\xb0\xd2\xb2\x1c\xb8\xb1"
+  "\x58\xf2\x23\x96\x5c\xc8\xbc\x62\xef\xd7\x54\xee\x63\xaf\xdb\x44"
+  "\x0c\x36\xf6\xa5\x73\xf7\x3a\xcb\x83\x74\xee\xde\x54\x6e\x5f\x65"
+  "\x0a\xaf\xce\x07\x9d\x6d\xc5\xb7\x8d\x3e\x56\xa3\xc6\x10\x3a\xde"
+  "\x2e\x7c\x52\x56\x5e\x3a\xa4\xd9\x14\x2a\xee\xe3\x25\xe4\x6b\x5d"
+  "\xd8\x18\x3d\x26\x7c\xb5\xec\xc3\x73\x5b\xd3\x63\x22\xe6\x49\x2a"
+  "\x9e\x2b\xf0\xdc\x81\x67\x0b\x9e\xd3\x14\x77\x8f\x99\xce\xd9\xe1"
+  "\xd9\x8a\xe7\x74\x94\x3f\x19\xff\x3d\x16\x36\x6a\xd0\xaf\x5b\xa6"
+  "\x94\x89\xcf\xf4\x77\x84\xb9\x35\x3b\x4b\x8b\xa9\x2a\xe2\xa7\x56"
+  "\xce\x5e\xa6\xed\x05\xca\x38\x41\xe6\x15\x62\x5d\x13\x6b\xfb\xec"
+  "\x23\x71\x96\xb9\xe9\x92\xf7\x9e\xed\xd0\x7c\x0b\x48\xde\x7a\xb6"
+  "\x3b\x26\xf6\x2c\x3d\x37\x4c\xc6\x9e\x95\xbc\xe8\x4e\xc9\x8b\xce"
+  "\xf6\xf1\xca\xd9\xd1\x18\x7a\x95\xb3\x3d\xb1\x71\xc2\x7c\x78\x4f"
+  "\x32\x0d\xd2\xbb\xa3\xeb\xe0\xec\x35\x54\xe7\x54\x71\x76\x21\x93"
+  "\x3b\x72\x36\x81\xff\xc6\x55\xf0\xe2\x11\x1d\x13\xf2\x18\x9e\xb9"
+  "\x2b\x8b\xfc\xb4\x58\xe9\x1d\xf1\x7e\x53\xea\x19\x28\xce\x9d\x6e"
+  "\xce\x43\xe4\xd3\xd5\xef\xcc\xd3\x5d\xd5\xc4\x74\xe2\x59\xfa\x24"
+  "\xe4\x27\x75\x73\xbe\x49\xb8\xa7\xf9\x2b\x8b\x3d\xdb\x3d\xe5\x79"
+  "\x83\x77\xb4\x7d\xe2\x35\xeb\x4c\xe1\x95\xf9\x92\x8f\x9b\xf3\xb6"
+  "\xba\xdf\x5d\x22\xd7\xfb\x39\x87\xf8\xf7\x64\x2c\x0d\x9f\xee\x32"
+  "\x11\xc7\xce\xa4\x5b\xb3\x8e\xe3\x5b\x93\x63\x65\xbe\x48\x43\xbe"
+  "\xad\xe0\xb5\xd4\xf6\x3d\xed\x4d\x1b\x60\x7c\x2c\x22\xcf\xac\xeb"
+  "\xe6\x34\xdf\x3b\xb7\x8c\xea\x31\x0a\x3e\xe2\x1d\x96\x44\x31\xdb"
+  "\xa8\x6d\x4d\x31\xfe\xd4\xb6\x23\x4d\xc4\x63\xff\x1e\x4b\x22\xff"
+  "\xb1\x6a\x5b\x9a\x45\x1c\xac\xca\xcb\x16\x6a\xbe\x5f\x7c\x48\x3b"
+  "\xbb\x3f\xdf\xfb\xbe\x98\x21\x57\xaf\x9a\xbf\xec\x0e\xdc\xcd\x57"
+  "\xc3\x8d\xc6\xe2\x4e\xda\x48\xe2\xc8\xbe\x91\x67\x1e\x7d\x4f\xc4"
+  "\xeb\xab\xbc\xcc\x8d\x72\xe6\x8b\xf1\xde\xfa\xc3\x63\x44\x5b\xb4"
+  "\x78\xf5\x5e\x25\x80\x7a\xe7\xe5\x0b\xdf\xad\x7a\xc9\x2f\x0a\x9f"
+  "\x69\x95\x97\xdd\xc9\x13\x8f\x17\xc8\x58\x9d\xa7\x96\x61\xfc\xc4"
+  "\xba\x4f\x73\x43\x9c\x03\x34\x53\xdf\x2f\xf3\x81\xa6\xde\x8e\xdf"
+  "\xff\x91\xb1\x47\x7e\x78\x4c\x2b\x97\xfc\x1b\x01\xb7\x5a\x71\x35"
+  "\x07\x2b\xd3\x8c\x93\x76\x41\xda\xd9\x42\x5d\xda\x35\xe4\x7b\x29"
+  "\xca\x9f\xcf\xfb\xae\xe4\x2b\xd3\x32\x7d\xcc\xb4\x43\xce\xef\x34"
+  "\xe0\xff\xf3\x8b\xd4\xfb\x3b\x7d\xec\xe6\x82\xb3\xca\x78\x42\xd3"
+  "\x77\xc8\xb1\x4b\xb3\x03\x17\x6f\xc7\xef\xff\x20\x7f\x89\x16\xab"
+  "\x78\xab\x5e\x9c\x27\xea\x8f\xb3\xb0\x0c\xa4\xef\xd0\xd2\xe3\x75"
+  "\x59\x80\x4d\xda\x5e\x8d\x9e\x8c\x24\x0e\xe7\xe1\xf9\x00\xf8\xcd"
+  "\xf9\xea\xb3\x1d\xcf\x6d\xda\x33\xee\xbb\x34\x7a\x43\x7a\x87\x91"
+  "\x87\xb3\x9f\x22\x79\x6f\x95\x05\x3c\x99\x85\xe4\xab\x34\xbf\x8f"
+  "\xed\xb7\xa9\x79\x21\xff\xfe\xa6\x46\xde\xcf\x45\xff\x5f\x76\x47"
+  "\xe1\x1f\x67\x92\xed\x9f\xb7\x88\x27\xcf\x2d\xa0\x18\xd1\xc8\x33"
+  "\x1f\x73\x49\x7c\x4b\xbe\x8e\x6a\xc6\xcd\xcb\xbd\x15\xe0\x4f\xef"
+  "\x27\xbc\x98\x27\xf6\x4f\x6b\x37\x9b\x85\x5f\x61\x3a\x3b\x2f\x62"
+  "\x6e\x91\xef\xc2\x30\x9b\x21\xfc\xc5\xd7\xce\xcd\x16\x7e\xd2\x37"
+  "\xda\x92\x34\xbf\x85\x98\x93\x16\xae\x7f\x3c\x8f\x7c\x19\x0a\x5d"
+  "\x59\xd0\x96\x22\xfc\x17\xaa\x7e\x0b\x77\x17\xb3\xd4\x46\x45\xfa"
+  "\x2d\x14\xe7\xea\xcf\xe1\xbb\x90\xbb\xde\x9a\xf4\x5d\x48\x31\xe1"
+  "\x71\x6f\xe3\x63\xe1\x10\xae\xe9\x31\xfe\x59\x0c\x53\xfa\x31\xd4"
+  "\x83\x46\xea\xa5\x1f\xc3\xf3\x5b\x5b\xe6\x19\x25\x4e\xcc\x5b\xa2"
+  "\xc5\x4d\x8e\x49\x5b\x01\x9c\x96\xfb\xd3\xba\x34\x9b\x9a\x06\xfe"
+  "\xe7\xb9\x1d\x93\x7c\x18\x68\x1b\xe9\x0c\x31\x67\xf7\x73\x67\xc1"
+  "\x53\xb1\x73\x88\x31\x5a\xa2\xe3\x51\xd6\x0c\xfc\x66\xd2\x6f\xc9"
+  "\x24\x9d\x18\xe3\xdd\x24\x0b\x98\x74\x58\x57\x1c\x71\x7c\x69\x38"
+  "\x1c\x97\x13\xd6\x1d\x25\x1e\x93\xce\x08\x2f\x8d\x84\xe9\xac\xba"
+  "\x61\x69\x64\x84\xe2\x19\x1e\xa5\x73\x62\xdb\xef\xa7\x73\x8b\x97"
+  "\x73\x8a\x75\xb2\x34\xf2\x05\xdf\x23\xcf\x63\x76\x91\x0c\x10\x19"
+  "\xe3\x1d\x91\x62\xde\x8e\x31\x48\x22\xf9\x82\xfc\x45\xa5\xe8\x42"
+  "\x2c\xc5\x1e\xf7\xea\xdd\xa3\xaf\x72\xf2\x15\x45\x71\xae\x94\xca"
+  "\x10\x68\xa2\x55\x97\x13\x8e\x2b\xf3\x86\xfb\x84\xaf\xf9\xa5\x91"
+  "\x99\x7c\xa9\xe3\x56\x2e\xe2\x53\x15\xf3\x36\xd0\xd3\x38\x11\xb3"
+  "\x78\x13\x1f\xc1\xbd\x71\xe9\xa6\x11\x4e\xf1\x14\x51\x76\xfb\xd2"
+  "\xb0\x32\xbe\xd4\xa1\x38\x73\x1c\x3a\x7c\xf7\x29\xbe\xfb\x14\xed"
+  "\xc9\x40\x99\x66\x3c\xdf\xc6\xf7\xdc\x4f\xe7\x9b\xca\x84\x8c\x83"
+  "\x3e\x7a\xd4\x33\xa3\xad\x68\xdf\x01\xf2\x55\x9d\x13\xf6\x94\xed"
+  "\x51\xcf\x80\x8a\x58\x9e\x8e\x09\xae\xd6\xb3\x70\xe9\x26\x76\x5b"
+  "\xce\xa6\xcb\xc5\x59\x52\x3a\x27\xb5\x34\x6c\x45\x9d\x65\x04\x8f"
+  "\x24\x11\x3f\x99\xce\x4a\x55\x5e\xee\x3f\x57\x1c\x46\xb2\x01\x59"
+  "\x3f\x9b\xe9\x49\x0f\x10\x69\x2a\x5f\x46\xbe\xab\x9c\x7e\x1e\x22"
+  "\x9d\xde\xab\xe3\xdd\x7a\x6b\xb1\x01\xf4\xd3\x7a\x49\xa7\x3d\x63"
+  "\xea\xf3\x72\x95\xe1\x2c\x5e\xfb\x62\x1f\xaf\xe4\x66\x5e\xfb\xfb"
+  "\x3c\xee\x3e\x45\x34\x5b\xc7\xab\x75\x3e\x3c\xf7\xf1\x6a\x43\x0b"
+  "\xaf\xfd\x43\x1e\xaf\x9e\x59\x86\x2b\x9e\x13\x97\xf1\xda\xd6\x3c"
+  "\x5e\xf9\x99\x05\xdf\x61\x6d\xeb\xa7\xef\x72\x79\xe5\xe7\x46\x5c"
+  "\xf1\x0c\xba\x5d\xfb\x07\x3c\x0f\x84\x70\xc5\xf3\x31\x7f\xbf\xce"
+  "\x8a\xb2\x5a\x73\x79\x75\xb2\x55\xd4\x55\x6d\xb6\x8a\xba\xaa\x2f"
+  "\xb6\xca\x3a\x66\x59\x65\x1d\xb3\xad\xb2\x8e\x34\xab\xac\x83\xce"
+  "\x83\xbd\x38\xc0\x2b\x87\xb2\x91\xaf\x80\x57\x9e\x68\xc7\x15\xcf"
+  "\x5f\x2c\x44\x3e\x3c\xfb\xf7\xe1\x8a\xe7\x53\x68\x4b\x2b\x9e\x47"
+  "\xdc\xc8\x3f\xc4\x2b\x03\x61\xe4\x5b\xc3\x2b\xc7\xec\xb8\xe2\x39"
+  "\xd8\x87\x7c\x78\x3e\x8d\x72\xfe\x80\xe7\xf1\x0e\xe4\x5f\xc3\xab"
+  "\x2f\xa7\xf6\x00\xa7\xad\x54\xae\x9d\x57\x5f\x49\xf9\xf1\x9c\x8e"
+  "\xf2\xfe\x80\xe7\xab\x3d\xb8\xe2\xf9\x5f\x0b\x90\x1f\xcf\xd7\xa0"
+  "\xaf\x2f\x06\x78\xf5\xb5\x87\x90\xaf\x88\x57\xcf\x47\xfa\xef\xf1"
+  "\x7c\x7d\x2a\xf2\xe1\xf9\x06\xca\x8f\xe7\x1b\xd7\x20\x3f\x9e\x6f"
+  "\x26\x18\x85\x78\xf5\x02\x07\xf2\x39\x78\xf5\xff\xea\xc6\x15\xcf"
+  "\xb7\x50\xfb\xf1\xbc\xa8\x01\x57\x3c\x7f\x03\xb0\x6a\xc5\xf3\x37"
+  "\xd1\xbe\x17\xc1\x3f\xdc\x4e\xe5\x97\xf0\xea\x7f\x27\xf8\xe0\x79"
+  "\x49\x05\xf2\xe1\xf9\x3b\x80\xc7\x1f\xf0\x7c\xd7\x9d\xc8\x3f\x75"
+  "\xac\x99\xea\x65\xe9\xbc\x7c\x06\xe3\xd5\x3f\xc8\xe5\xe5\x33\x71"
+  "\xfd\xa1\x99\x97\xc7\xdb\x78\xf5\xbd\x76\xa4\xe3\xfa\xc3\x01\x3c"
+  "\xcf\x57\x9f\x71\x5d\xe1\xc1\x73\x86\xfa\x8c\xeb\x8f\x1a\xf0\x9c"
+  "\xa9\x3e\xe3\x9a\x6b\xc5\xf3\x42\x5c\x43\x78\xa6\x6b\x0d\x9e\x17"
+  "\xa9\xcf\xb8\xde\x77\x08\xd7\xb0\x7f\x6e\xd9\x3e\x7f\xf2\xb6\x5c"
+  "\x7f\xf2\x41\xb2\x41\x65\x91\xba\x17\x7d\x4a\xca\xef\xc9\x17\xed"
+  "\x0c\xe7\x28\x9b\xd9\xaf\xbb\xea\x79\x5a\x0b\xbd\x25\x3e\x11\x1b"
+  "\x4d\xf5\xa5\x36\xa3\x57\x77\xe5\xb3\x58\xfb\x17\x52\x3c\x69\xf4"
+  "\x35\x8d\xbb\xe2\x4f\xe1\xda\xc8\x5d\x17\xf4\xa2\xaf\x78\xbe\xf0"
+  "\x1d\x5c\xf1\xfc\x6f\xd5\xe8\x33\x9e\x7f\xf8\x2d\x5c\x1b\x83\x95"
+  "\x57\x81\x96\x59\xc5\x3a\xc6\x9f\x79\xb4\xcb\x14\x76\x82\xa6\x80"
+  "\xde\x3e\xe5\x81\xfc\x96\x0b\x1c\x7c\xc9\x6e\xa2\x18\x06\xbb\xcb"
+  "\x06\x78\xca\x36\xd1\x26\x8a\x53\xc2\x27\xd2\xf5\xb2\xee\x0b\x78"
+  "\xaf\xee\xaa\x05\xa4\xd7\xe4\x29\xbb\xa7\x7b\x7f\x8f\x78\x3f\xc7"
+  "\xd3\x2c\xdf\x1b\x59\xf4\xfd\x0f\xe9\xfd\x06\x13\xe9\xa2\xe7\x39"
+  "\xc4\x7b\x6f\x60\x40\xed\x57\x1c\xbd\x7b\x94\xf2\xfa\x74\x57\x1d"
+  "\x90\x7a\xaa\x2b\x5b\xb9\x2b\x8e\x8d\x18\x4f\xad\x41\xdb\xb1\xfe"
+  "\x5d\x1e\x56\xf9\xe4\x12\x6e\x3c\x5e\x26\xcf\xcd\x8f\x4d\xe7\xd3"
+  "\xc3\xa8\xd4\xbc\xd2\x5e\xeb\xe2\x5d\x24\x7b\x62\x0d\xd1\x5b\x4b"
+  "\xd3\x5b\x7b\x75\x57\xd3\xd9\x84\x00\x4f\xf2\x14\xd0\x39\xa0\x5e"
+  "\x5d\xfa\x3d\x13\xd5\xa7\x9a\xad\x9b\x4d\xa8\xff\xea\x47\x9d\x21"
+  "\x3e\xea\x29\xfd\x16\xd6\x3a\x91\xde\x23\x6c\xcb\xe5\xbd\x6a\x0f"
+  "\x24\xee\x0f\x48\xfd\xe8\xd5\xf5\xf4\x6d\x2c\xaf\x1f\xa9\xbc\xbb"
+  "\x42\x49\xf1\xd8\xe5\x7e\x56\xfa\x0f\x5e\x56\x7c\x7a\x53\x11\x8b"
+  "\xb7\x6e\x7e\x15\xe5\xa7\x37\x9f\x29\x17\x6a\x79\xc5\xbb\x6d\xaf"
+  "\x20\xef\x2e\xa1\xc3\x49\x6f\xd1\x74\xbe\x1c\x7d\x78\x44\xf2\x44"
+  "\x59\xb4\xae\x49\xde\xee\xea\x0c\xf2\xd5\x18\x4e\x7a\x69\x59\xb8"
+  "\x66\xdb\xb2\x48\x8d\xa7\x80\xd7\x79\xec\x29\x61\x1d\x13\x76\xf9"
+  "\xba\xab\xf3\x6f\x08\x91\x6e\xed\x4d\xca\x3b\x57\x99\x91\xbd\xf8"
+  "\x7a\x07\xd3\x7b\x0a\x3f\xa0\xe7\x1f\xf1\xca\x1f\x0d\x79\x87\xba"
+  "\x19\xf9\x9b\xc5\xf3\x0a\x5e\xb9\xba\x4b\x99\xb1\x6a\x5f\x13\xf1"
+  "\xa4\x0e\xd2\x09\xbd\x43\x70\xf9\x04\xe3\x02\xde\xff\xea\x45\x5a"
+  "\x5b\xc8\xdf\x7c\x2d\x60\x47\xfc\x22\x9d\xa3\xce\x89\x44\xc8\x8f"
+  "\x11\x78\xba\xab\xeb\xe5\x78\x5d\x6d\x25\xba\xad\xd6\xbb\x41\x49"
+  "\x3c\x55\xd3\xb9\x82\xf6\x4c\x8d\xe4\x17\x66\x54\x9c\xbb\x0c\x53"
+  "\x8c\x38\x5a\x2b\x65\xde\x33\x7c\xec\xae\xb2\xe7\x6c\xb6\xaf\x2b"
+  "\x2c\xca\xd9\x60\xbf\xc5\x4a\xf1\xec\xd7\xdd\x6f\x7d\x30\xff\xc1"
+  "\x75\x85\x9b\xce\xe6\x2b\x8d\x68\xd7\x51\xe0\x89\x58\x8b\xdf\x00"
+  "\x54\xa5\xae\xf9\x5f\xf7\xd2\x58\x3f\xf5\xa4\x8c\x49\x80\x3c\x21"
+  "\xc8\x56\xc2\x26\x49\x69\xf0\xb8\x79\x63\xd9\x40\x15\x9d\x1f\xdf"
+  "\x40\xb2\x81\x9f\x79\xd9\x29\xb4\x4d\xc6\xa7\xeb\x0c\x83\x06\x17"
+  "\x97\x70\x4f\xf1\x29\x9a\x07\xa0\x51\x07\x1d\x7c\x77\x79\xc6\xe9"
+  "\xda\x6d\xed\xbd\xba\x7f\x75\x9f\xae\x3d\x58\xa0\xc5\x90\x89\xd4"
+  "\x1c\x6c\x57\x92\x5e\xf1\x51\x0c\x99\x09\x6e\x61\x47\x00\xcb\x71"
+  "\xf7\x29\x07\xd6\x81\xa2\xdd\x2e\xac\x63\x90\x29\x84\x7f\x8b\x67"
+  "\x1e\x6d\x89\x70\x9b\x21\xe2\x62\x46\x5c\x53\x78\x8a\xc7\x3c\x91"
+  "\xf4\x52\x2e\xbd\xa7\xd8\x31\x91\x09\x1b\x2b\x3d\xca\x95\xff\x2a"
+  "\x00\xde\xb8\x18\x17\xf1\x3a\x0b\x4e\x30\xa4\x27\x2a\x75\x07\xfd"
+  "\xfd\x4b\x98\x9e\xf2\x82\x47\x62\x2b\x70\x5f\xb2\x92\x25\x23\x9f"
+  "\xa9\xe4\x0d\xa4\x07\x6d\x89\x61\xa7\xcd\x38\xee\xb4\x25\x4e\x70"
+  "\x5b\x92\xb7\x2f\xc4\x26\xae\x7e\xd4\x73\x9d\x9f\x19\x9e\x02\x2f"
+  "\xb5\x5b\xc1\x1c\x6c\x2c\xeb\x8a\x3c\x6c\x9b\x11\x7e\xd8\x66\x98"
+  "\x98\xb0\x19\xc3\x1b\x6d\x86\xf1\x8d\xb6\x19\x13\x41\x9b\xd1\x9b"
+  "\xe7\x67\x6f\xfa\x7f\xcd\x3a\xfb\x06\x84\x3e\x72\x22\xd9\x93\x36"
+  "\x91\x7c\x30\x9c\xd4\xc7\x52\xaf\xb7\x83\xa7\x02\x3f\xb9\x13\xbc"
+  "\x33\x70\x22\x29\xfc\xcb\x47\xb1\x9e\xbd\xea\x01\x7c\x1f\xbc\xe3"
+  "\x1a\xfe\x45\xa4\xf2\xba\x2c\xeb\x77\x40\xaf\xca\x0d\x69\x48\x03"
+  "\xfe\x7c\xbd\x85\x57\x2e\x00\x6d\x33\x80\xee\x19\xd2\x7d\x72\x1c"
+  "\xc0\xc7\x7d\x2d\x80\xe7\x34\xca\x2b\xf3\xdd\xb4\xd8\x27\xae\xd7"
+  "\xef\x10\x71\x35\x2b\xaf\x6e\xdc\x2d\xe4\xbb\x7f\x6d\xd6\xf8\xf2"
+  "\x36\xc3\xd4\x67\xd4\x91\xa7\x6d\x52\x4e\x56\x40\x73\x6a\x5f\xec"
+  "\x9a\x9a\x96\x0f\x56\xd0\xfe\xa5\x02\xb8\xf5\xeb\x6c\x0b\xc8\x57"
+  "\x12\x77\x2e\x51\x65\x53\x9b\xe0\xd9\xe8\x5c\x37\xe9\x2f\xd4\x34"
+  "\x69\xe3\xa3\xcf\x22\x7f\xf1\xad\xe4\x9f\x8a\xf4\x15\xc0\xeb\x76"
+  "\x9f\xce\xb6\x04\x70\x88\x87\x5c\xd7\x82\x5f\x2b\x7e\x9e\xc7\x49"
+  "\x8f\xe1\x62\x77\x68\x3a\x9e\xa9\xdb\x6a\x03\xff\x57\xdb\x1d\x95"
+  "\x73\x6d\x65\xe8\x77\xf7\xf9\xdb\xfe\xd9\xa6\x95\x21\x85\xdf\x4d"
+  "\x82\x71\xdd\xef\x59\xbd\x32\xe9\x6f\x15\x6b\x83\xed\x5d\xd0\x89"
+  "\x32\xf1\xae\xe6\x25\x7b\xe9\x30\x8b\xa3\x77\x2d\x64\xeb\x80\x67"
+  "\x6b\xa1\x8e\x7b\x03\x21\xfa\xc6\xc0\xd3\xca\x06\x5a\xc6\xfc\x7a"
+  "\x9a\x17\x9d\x48\xc3\xb7\x27\xea\xc7\xd4\x72\x1b\x3c\xf5\xce\x87"
+  "\x98\x88\x7f\x41\x31\x74\x68\xbe\xd4\x97\x42\x86\xa4\x78\x3f\x85"
+  "\x44\xab\xaf\xb9\x06\xf7\x46\xca\xc7\x93\x5e\xb2\x2b\x28\x03\x73"
+  "\xa6\x9b\x27\xbf\x94\xad\xd4\x1e\xf4\x61\x0d\x69\xe6\x73\xcb\x97"
+  "\x28\x4f\x79\x1c\xc1\xca\x6b\xa8\xff\x42\x1f\x48\x7e\x70\x48\x47"
+  "\x12\x81\xac\xde\xb9\x2f\xcc\xf8\xb7\xc2\xec\xf5\xa2\x51\xe6\x4f"
+  "\x38\x55\xe2\x4f\x7e\xa5\xdd\x9f\xfc\xaa\x27\x92\xfc\xaa\x19\xbf"
+  "\x54\x7b\x21\xed\x15\x5f\xbb\x78\xd2\x9f\xe3\xf0\xb9\xfd\x39\xa2"
+  "\xcc\x74\xcd\xa7\x63\x64\xe3\xf9\xfb\x73\x8c\xe8\xff\x14\xde\x5d"
+  "\xfc\xd5\xfe\x1c\xc1\xb3\x52\x2c\x72\x8f\xe6\xa7\x24\x22\x6c\xcf"
+  "\x59\x52\x24\xf9\xa5\x25\xc2\xd7\x89\xc3\x23\xfc\x95\x10\xef\x4a"
+  "\x6b\x4d\xb0\xf2\xda\x49\xfb\x6f\xa2\x9f\x91\xaa\x53\x6e\xfc\x2a"
+  "\x90\xde\xe0\xd3\xdd\xda\xa5\xd1\x56\xac\xb9\x65\x91\xc4\x35\x15"
+  "\x41\x3a\x4f\x30\x51\x70\x1b\xe5\x05\x1c\x5b\x50\x77\x5c\x64\xa2"
+  "\x60\x11\x7e\xb7\xe2\xf7\x8d\x48\xed\x41\x7b\xa4\xf6\xd5\xe6\x48"
+  "\xed\xb6\x0a\xfc\xdc\xf8\xd5\xe0\x57\x8f\xdf\x0e\xfc\xc0\x1f\x6d"
+  "\x6b\xc4\x95\xde\xef\xc5\x6f\x1f\x7e\xfb\xf1\x6b\xc1\xef\x40\xe4"
+  "\x29\x4f\x59\x44\x67\x48\xc3\x2f\x1d\x3f\x2b\xca\x31\x46\x6a\x5f"
+  "\xe9\x8e\xd4\xbe\xb4\x4c\x9c\xf3\xac\xfc\xda\x7c\x0d\x57\xa7\xf6"
+  "\x1d\x9a\xe6\x16\x3e\xfd\xe3\x3f\xe6\x26\x8a\x37\x5b\x32\x4a\xfe"
+  "\xdc\xdc\xaf\xdb\x02\xe7\x17\xdb\x41\xf7\xb5\x15\xd3\xe1\x36\x95"
+  "\x0f\x3a\x33\x71\x9e\xe5\x7d\x49\xff\x37\xc9\xef\x5b\x3c\xee\x70"
+  "\x5a\x79\x46\xd8\xc5\xca\x40\xdb\x74\x9d\xb9\x7d\x6c\xa9\x9f\x39"
+  "\x3b\xfa\xc6\x99\x33\x8f\x47\x04\x1d\x28\x21\xbb\xee\xc7\xf3\x08"
+  "\xcf\x23\x3c\xdb\x3a\x51\x73\xd0\x11\x49\x7a\xa5\x99\x27\xbd\xd2"
+  "\x2d\x7c\xc4\x81\x9e\x50\x0c\xad\x49\x99\x96\xf0\x0e\x72\xed\x91"
+  "\xa1\x51\xf6\x70\x1e\x57\x8e\x14\x80\x47\xeb\x06\xf2\xe9\xd8\xd3"
+  "\x02\xff\x54\xb9\xf6\x7f\xf7\xf0\x32\xe0\x53\x42\x04\x70\x53\x48"
+  "\x9e\x05\xee\xed\x29\x66\x19\x1a\xfe\x61\x5d\x37\x6b\x71\x87\xf8"
+  "\x8c\xaf\x65\xe1\x9d\x81\xe2\x12\x35\x42\xae\x6d\x2c\x66\xe9\x8d"
+  "\x78\x27\x62\x48\xa2\xdd\x77\xdb\x4d\x5c\x79\xc0\xc6\x9a\x7e\xc2"
+  "\x8c\xc9\x27\x64\x5c\xd2\x08\x60\x1f\xf5\xcd\xbf\xad\xfd\xae\x13"
+  "\x56\xf6\xba\xed\x23\xac\xcf\x2d\x18\x97\x6d\xed\x13\x58\xc3\x00"
+  "\xcb\xc8\xf9\xc1\x72\xfe\xb4\xf1\xaf\xfe\x59\x58\x4e\xa4\x95\x75"
+  "\x49\x78\xe6\x32\x82\xd9\xd9\xf0\x24\x18\x6f\xee\x03\x3c\x01\x57"
+  "\xef\xd1\x08\xe4\x53\xb6\x52\x83\xe7\x2e\xc0\x13\x30\xb5\x10\x4c"
+  "\x01\x0f\x01\x53\xae\xc2\xb4\x29\x06\xa6\xa0\x5f\xc2\x9f\x1e\xc1"
+  "\x54\x01\x4c\x9b\xa6\x81\xe9\xa4\x7e\x00\x30\xdd\xf3\x0f\xc1\x74"
+  "\xdf\x3f\x01\xd3\xeb\xef\x9c\x0e\xa6\x61\xe2\x1d\xea\xb6\x79\x38"
+  "\x68\xa3\x37\xfc\xa6\xf0\x0d\xc9\x6b\x5e\x4d\x55\x6a\x5e\x35\x2b"
+  "\x49\x07\xdb\x29\xce\x34\xed\xe3\x53\x1c\x2c\xa7\x83\x7f\xe2\xdc"
+  "\xc7\x4f\x47\xea\x3c\x56\x4a\x03\x6d\x2b\xb8\x81\xec\x87\xb0\xe2"
+  "\x34\xe9\x79\x6b\xe7\x18\xe9\xd1\x6e\xdc\x36\x4e\xbc\x77\x9d\x27"
+  "\x47\xe1\x05\x8c\xe8\xca\xbd\xd7\x30\xc3\x38\x68\x87\xbd\x98\x5d"
+  "\x5e\x0f\x7a\x38\x5e\xfb\x6a\xea\xa0\xee\x06\xeb\x1d\x76\x85\xe3"
+  "\xe7\x24\x1f\x87\x0a\xe8\x2e\xe8\xb9\x18\x5f\x1a\x33\xda\x1f\x3c"
+  "\x72\xef\x9f\x50\x5e\xc6\x85\x6f\xe5\x86\x99\xb3\xe0\xcb\xe3\xab"
+  "\x38\xb3\xad\x91\x9a\xaf\x9e\x27\x14\x8b\xaf\x64\x80\xc6\xb5\x85"
+  "\x79\xfb\xa2\xf3\x44\x51\xe9\xf4\xff\xc7\xde\xf7\x00\x44\x55\x65"
+  "\xff\xdf\x79\x8e\x85\x36\x03\xa3\x4b\x35\x19\xda\x64\xb6\x3b\xb5"
+  "\x9a\xd4\x6a\x6b\xbb\x56\x54\xba\x91\xa9\x58\x69\x4b\x65\x85\x8a"
+  "\x2e\x18\x22\x29\x2a\xfe\x83\x81\xc0\x90\x06\xc4\x72\x5b\x2a\xfe"
+  "\x6d\x4b\xad\x6d\x56\xee\x2e\xca\xe8\xd7\x64\x2a\xdd\x45\x05\x86"
+  "\x5a\xdd\x68\xb3\x5f\x93\x4b\x46\x86\x36\x01\x09\xc2\xcc\xbb\xbf"
+  "\x73\xde\x7d\x8f\x79\x33\xcc\xc0\xcc\x80\x68\x1b\xd4\x73\x66\xee"
+  "\xbb\xef\xbe\x7b\xcf\xf9\x9c\xcf\x39\xf7\xbe\xfb\xee\x45\x5d\xa0"
+  "\x5d\xa0\x8d\x6c\x91\xf1\x33\x70\xbf\xa6\x48\xdc\x9b\xc2\x91\x01"
+  "\xfc\x8c\x6b\x99\x83\x2e\x71\xcf\x0a\x8f\xf6\xb1\x1e\xec\x63\x9d"
+  "\xb0\x6f\x90\x16\xe4\xb1\xb3\xa3\x8d\xe9\x10\x75\x66\xb1\x57\x09"
+  "\xfa\xcb\x17\xfd\x01\x93\xfb\xfe\x4f\x29\x8d\x86\x98\x6e\x6c\x34"
+  "\x9f\x67\xd6\xd0\xb6\xb8\xe1\xb8\x77\x54\xc9\x19\xc0\x53\x2c\xc4"
+  "\x50\xdf\x82\xbf\x48\x04\x7c\x9d\x21\xe3\x4a\x12\x21\x2e\x6a\xc3"
+  "\xfd\xbf\xa0\x3e\x6b\xd9\xbe\xa9\xfc\xa6\x9f\x97\xc1\x39\x61\xcd"
+  "\x46\x5e\x5a\xb3\xb1\x45\x8f\x63\x1b\xce\xf1\xa6\xe5\x7a\xce\x79"
+  "\xcf\x76\x9d\x43\x35\x36\x5a\x78\x1f\x55\x11\xce\xe6\x01\x05\x7d"
+  "\xaa\x41\xb9\x36\x29\x6e\x56\xb1\x31\x60\x6b\x68\x52\x2a\xce\x13"
+  "\x0a\x7f\x8f\xe6\x34\x06\x25\xe1\x1e\xd0\xd2\xb9\xb4\x68\x94\x43"
+  "\xeb\x4d\x06\x62\x70\xe4\x8e\x4d\xc1\xbd\xc1\x71\x4d\x2e\xff\xb0"
+  "\x18\x5e\x8f\x65\x39\xb2\xdb\xc7\x81\x9c\x22\xf8\x9c\xf6\xf1\xc0"
+  "\x29\xe1\xf4\x29\x68\xeb\x52\x68\xeb\x29\x90\xeb\x29\x68\xeb\x1a"
+  "\xb1\xad\xe2\x9e\x68\x3c\xc8\x1f\xce\x79\xf6\x8f\x52\x5b\x9f\x02"
+  "\x79\x67\x7f\x6c\xdd\x78\x9a\xfc\x84\x42\x4c\x5e\xd3\x24\xbc\x0b"
+  "\xd4\x66\xb1\x7f\x46\xf0\xbe\x82\xff\x36\x66\x15\xcc\x03\x3c\xa2"
+  "\xcc\x21\xd6\x06\x7c\xee\xb1\x49\x7a\xc0\xfa\xd0\xce\xb8\xe1\xc5"
+  "\x89\x50\x1f\x94\xfd\x19\x32\x1e\xed\x19\x64\x3f\xae\x18\xe5\xef"
+  "\xba\x2f\x71\xa8\xa0\x83\x4b\x40\x07\x89\xa2\x0e\x72\x45\x1d\x40"
+  "\xcc\x0c\xbe\x18\xc7\x7a\xb4\xc5\x19\x4c\x07\xfe\xc9\xe8\x66\x7b"
+  "\x3f\xdb\xeb\x38\xef\xf6\x3a\xf9\xb6\x0e\xd6\x97\x56\xe0\xda\x91"
+  "\xd0\x4f\x58\xc4\x77\x82\xdd\xe6\x89\x76\x4b\xe3\xee\x90\x6c\xf6"
+  "\xa4\xe2\x96\x63\xbe\xd9\xec\x2f\x0e\xfe\x48\x6d\x36\xf4\xfc\xda"
+  "\xec\xa4\x5c\x57\x9b\x9d\x64\x76\xb5\xd9\x49\xab\x9c\x36\x2b\x9e"
+  "\xeb\x17\x9b\x9d\x64\xbc\x30\x36\x3b\xc9\xe8\xc1\x66\x95\x3e\xd8"
+  "\xac\xd6\x8b\xcd\x6a\xcf\x9f\xcd\x4e\xf6\xba\x47\x7b\xff\xfb\xd8"
+  "\x29\xdf\x75\x70\x1e\x7c\xec\x7a\x99\x8f\x55\xa3\x8f\xbd\x35\xd3"
+  "\x93\xbd\x76\x16\x82\xbd\xaa\x44\x7b\x7d\x74\x2f\x94\xf7\xcb\x8d"
+  "\x87\x8f\xf7\x6e\xaf\xf6\x42\x67\xfc\xe4\xd5\x66\xe3\xd0\x66\xb7"
+  "\x13\x8b\x55\xb0\xd9\x05\x92\xcd\x16\x8a\xfd\xa1\x1e\xec\x36\xd4"
+  "\x9b\xdd\xe2\x3e\x51\xb8\x47\x54\x8f\x76\x2b\xc6\x4b\x9d\xa3\xd1"
+  "\x6e\xcd\x17\x99\xaf\x9d\x32\xdd\xd5\x6e\xa7\xa4\xb8\xda\xed\x94"
+  "\x09\x4e\xbb\x15\xcf\xf5\x8b\xdd\x4e\x99\x76\x61\xec\x76\xca\xb4"
+  "\x1f\x8e\xaf\xbd\x2d\x6e\xe0\x7c\xed\xd4\xb7\x04\xbb\xf5\xe6\x6b"
+  "\xd3\x44\x5f\xab\x46\x5f\xfb\xab\xbb\x7c\xb3\xdd\x5f\xdf\xf6\x23"
+  "\xb7\xdd\xf3\xec\x73\xa7\x2a\x5c\x6d\x77\xea\x24\x57\xdb\xfd\xf5"
+  "\xd7\x4e\xdb\x15\xcf\xf5\x8b\xed\x4e\x25\x17\xc6\x76\xa7\x92\x1f"
+  "\x8e\xcf\xbd\xdd\xeb\xfe\x8f\xba\x31\xc4\x70\x42\x71\xfb\x46\x4b"
+  "\xa1\x30\x07\xd0\x60\xb1\xff\x8a\xb0\xb9\x2a\xb7\xbf\x66\xd1\x4e"
+  "\x21\x7c\x4e\xb3\x0d\xf7\x46\xc0\x39\x33\x2f\xc8\xe6\xa4\xb0\x39"
+  "\x14\xb7\x1f\x94\xe6\xd4\x94\x88\xfb\x27\xf4\x34\xa7\x86\x66\x37"
+  "\x67\xb2\xeb\xee\x20\x0c\x1b\xcd\xd9\xd2\x6f\x61\x9d\x2b\xc5\x1d"
+  "\x4a\xba\xb9\xd9\x60\x1b\xd6\xec\x71\x8f\x01\x7c\xa6\x10\x9c\x4e"
+  "\x29\xee\x3b\xd4\x32\x66\x6b\x4c\x4b\x0e\x21\xf9\xc2\xb3\x98\x3b"
+  "\xa6\x42\x1b\x63\x85\xb1\xdb\xe0\xc9\x11\x2d\x19\x73\x08\xa4\xcd"
+  "\x91\xd2\x84\xbd\x99\x33\x86\x50\x1e\xce\x01\x87\x8c\x2f\x49\x25"
+  "\x41\xb8\x76\xe8\x4d\x67\x11\x8b\x77\xc4\x00\x47\x84\xe2\xde\x45"
+  "\xb8\x5f\x04\xbd\xf2\xea\xd6\xe2\x66\xa2\xac\xcd\x14\xc6\x9f\x71"
+  "\x2e\x4e\x69\x1e\xe2\x7f\xc8\x8d\x05\x94\x53\x12\xbe\x28\x7d\x0a"
+  "\x55\x57\x6a\x85\xb9\xbf\x80\x15\x69\x7e\x0e\xee\xe7\xc5\x8f\x36"
+  "\xd4\x4b\x6b\x57\x52\xa8\xdf\xfe\x54\x1b\x87\x7b\x68\x17\xaf\x20"
+  "\x1a\x38\x54\x34\xb7\x52\x0b\xf5\x6a\x94\xc6\x13\xbd\xce\xe3\xc6"
+  "\xfd\x65\xaf\xd6\x2a\xc5\xb9\x40\xf8\x0e\xae\xb0\xf7\xc6\x16\x8e"
+  "\xcf\x76\x40\x3a\xcd\x48\x13\xf6\x8f\x0a\x01\x59\xe0\xdc\x5b\xdc"
+  "\xd7\x87\x2f\xde\x8a\x6b\xe9\x93\xb7\xd7\x35\x72\x38\x17\xc4\xf1"
+  "\x87\xab\x5b\xcd\xa9\xb7\xe0\x1a\x15\xc2\x9a\xdd\x27\x15\x77\x7e"
+  "\x19\xf5\x35\xdb\x4b\x16\xbe\x7f\x87\xcf\x60\x66\xc1\x6f\x9c\x1f"
+  "\xc0\xb7\x68\x95\x98\x17\xd2\x8b\xcc\xab\xff\x43\x42\x92\x84\xf9"
+  "\xf1\x41\x62\xde\x04\xcc\x6b\x55\xdc\x29\xbc\x57\x02\xbf\x0d\xf8"
+  "\xdc\x00\xe7\xd0\xe3\x7c\x27\x5a\x98\x3e\x45\xe0\x07\x63\xa5\x96"
+  "\x1f\x9d\x3e\x45\x98\xb7\x0a\xed\xdc\x02\x6d\x86\x3c\x2a\x9c\xdb"
+  "\x23\x7c\xa6\x12\xcd\x36\x48\xc3\x72\xe0\x53\x65\x4e\xc4\xb9\x2a"
+  "\x77\xce\xc7\xb2\xbd\xbe\x1f\xa0\xaa\xd4\xd2\x0c\x25\x61\xef\xf5"
+  "\x28\x3e\x3c\xa1\x88\xc8\x0f\x51\x50\x4a\x0b\x0d\xf5\xcf\xe0\x38"
+  "\x37\xce\xc9\x16\xe6\x99\x47\xc4\x43\xf9\xca\x12\x61\x1c\x37\x22"
+  "\x12\x70\xd4\x2a\xae\xa7\xc1\xf6\x1d\x51\x44\x94\xe2\x7d\xf0\x1a"
+  "\x31\xff\x14\x36\xff\xb9\x52\xab\x4b\x1d\x42\xe1\xf7\x66\x36\x6f"
+  "\x3b\x28\x06\xae\xcf\x76\xce\x57\x13\xae\x03\x2c\x45\x14\x42\x99"
+  "\x1a\x61\x6e\x1d\xe7\xf9\xd9\x87\x30\x27\x5a\xd4\x5b\x8d\x16\xb0"
+  "\xe1\xae\x3b\x09\x23\x80\x0b\x09\x23\x58\xdf\x77\x52\xad\x1c\x7b"
+  "\xc6\x71\xd7\x0d\x98\x2f\x0f\x74\xe8\x78\x45\x8b\x6b\x23\x12\xbe"
+  "\x13\xf5\x82\x73\xeb\xef\xfa\x02\xf5\xb2\x05\x7c\x81\x98\x57\xe9"
+  "\xac\xbf\xf0\x5b\xd0\x27\x0f\xba\x60\x73\xfc\xef\xda\x25\xec\xa1"
+  "\x02\x9c\x81\xf3\xcb\x0f\x40\xa4\x44\x11\xb7\x80\x91\xb7\x57\xb4"
+  "\x73\xc5\xab\x59\xfa\xfe\xe6\x76\x0e\xe7\x92\xe0\x78\x78\xee\x52"
+  "\xa2\xc4\x71\x75\x2c\x93\x86\x19\xea\x27\x4a\x7a\x5c\x07\xba\x5b"
+  "\x0d\xd8\x05\x99\x6f\x01\xf9\x15\x77\x08\xcf\xac\xea\x8b\x79\xa2"
+  "\xe2\x21\x9f\x55\x71\x97\x0d\xca\xd3\x14\x5d\x41\x6d\x38\xa7\x1b"
+  "\x64\x98\xdc\xb6\xe9\xae\x6a\x49\x86\x58\x27\x9c\x93\x9d\x2b\xcc"
+  "\xcd\xbf\x2b\x92\x61\xe8\x2e\xad\xd4\x66\x6f\xf2\xcc\x7d\x9b\x84"
+  "\xe5\xde\x44\xa6\xf0\xaa\xb0\x6c\x3a\xe4\xea\x52\x1c\x6f\x9e\xdd"
+  "\x44\x08\xae\xf3\x1e\x95\xf5\x39\xb5\xd8\x1c\x84\x57\x87\x65\xe3"
+  "\xf3\x09\xc7\x33\x37\x8e\x8c\x5a\x8b\x7b\xdc\xef\x49\x49\x6b\x27"
+  "\x1a\x4b\xaa\x8d\xed\xf5\x45\xbe\x23\x8e\x95\xc0\xe1\xc0\xeb\xe0"
+  "\x53\x95\x69\xdf\x91\xab\x50\x5e\xbc\x7a\x4f\xca\x49\xc5\xdd\x7f"
+  "\x9c\x97\x4c\x0c\xfe\xf1\xe8\xdd\xc2\x3b\x48\x18\x5f\x00\xe7\x73"
+  "\xc2\x5e\xee\x36\x88\x4f\x72\xf7\xf8\xb7\xdf\xb0\xe2\x6e\xaf\xef"
+  "\x17\x61\xbb\x79\x1c\x87\x16\xdb\x1c\x85\x6d\x6e\x6d\x27\x38\x96"
+  "\x3f\xfb\x69\x5c\x7b\xf4\x7b\xc2\xe7\x86\x65\x63\x9b\x79\xf5\xfe"
+  "\x76\xff\xc7\xf4\xef\x09\xef\xe9\xde\x14\xe4\xcd\x3f\x73\x75\x29"
+  "\xaf\xda\xdf\x8e\xf7\xc6\x3a\xe0\xbb\x39\xb3\xbf\x27\x82\xdc\x51"
+  "\xfe\x96\x76\x07\xa1\x6a\x79\x1d\xec\xfe\xd6\xc1\x7b\xfb\x6f\x22"
+  "\x61\xc6\xb7\x99\xde\x1d\xcf\x88\x32\x88\xc3\xe7\x64\xfb\xdb\x71"
+  "\x7f\xb2\xd9\x58\x07\xdb\x69\x32\xeb\x34\x11\xf4\x6f\xd1\x37\x11"
+  "\xc7\x90\x1b\x47\xe2\xdc\x0b\xd4\x7f\xaa\x1d\xf4\x7f\xb6\x1d\xd7"
+  "\x0b\xb1\x59\x0c\xe7\x08\xc6\x2f\xf6\x16\x3d\xd7\x5d\xff\xd3\xfe"
+  "\x38\x2f\xc5\x5f\xfd\x4f\xeb\x27\xfd\x4f\xbb\x08\xda\x3f\x3d\x80"
+  "\xf6\x4f\xef\xa7\xf6\x4f\xbf\x08\xda\xff\x9b\x00\xda\xff\x9b\x7e"
+  "\x6a\xff\x6f\xbc\xb6\xff\x9e\xab\x78\x2a\xcc\xc9\x09\xde\x65\x45"
+  "\x1f\xc0\xfc\xd5\xbd\x2f\xe1\xfc\x1b\xe1\x5d\x2c\xf1\x37\x61\xef"
+  "\x66\x05\xb9\xfd\x56\xb9\xfd\xd6\xb8\xfd\x0e\x75\xfb\xad\x75\xfb"
+  "\x1d\x26\xfd\x06\x3f\x32\xf4\x8c\xe2\xde\x61\x10\x97\x1a\xac\x8a"
+  "\x7b\xcb\xc4\xf3\xe3\x70\x3d\x1d\xf0\xe9\xe3\xbc\xed\x37\xa7\x56"
+  "\x10\xda\xc9\x51\x22\xec\x03\xa7\x88\xd4\x76\x64\x10\x4a\x87\x8c"
+  "\xd2\xe3\x5e\x5d\xbc\x31\xab\x6c\x36\xf0\xb4\xc5\xd6\x0e\x71\xbe"
+  "\xf6\x12\x28\xfb\x4a\xdc\x83\x10\xf5\xaa\x5b\x81\xf3\x6b\x22\x87"
+  "\x62\x3b\x6f\x4a\x32\x13\x7e\xc8\x8d\xc2\xfc\x06\x3e\x37\xab\xcc"
+  "\x36\xe4\xc6\x51\xf4\x25\xb3\x21\x37\x83\x0f\xb2\x34\x1d\x25\x79"
+  "\x1c\xaf\xdb\xb0\x01\xf4\xdb\x54\x4e\xd6\x37\xd1\xc6\x0d\x76\xda"
+  "\x6e\x99\x6f\x26\x69\x36\xdc\xc3\xa3\x8a\xd4\xda\x8e\x0a\xfb\x78"
+  "\x08\xfb\x95\xd8\xca\x09\xc6\x3f\x69\x98\x07\xd2\x6a\x6d\x3b\x48"
+  "\x0d\xfc\x36\x27\x7e\x09\xed\x8c\xdc\x65\x69\xda\x01\xfd\xa5\x2c"
+  "\xe0\xbb\xac\x4c\xaa\xca\xca\xae\x69\xc2\xfd\x47\xb3\x8c\x58\xd7"
+  "\x5a\xa8\x87\xc5\x6e\xc2\x7e\x96\x51\x28\xb7\xb5\x4e\x88\x53\xf1"
+  "\xb9\x2d\xaf\x86\xfc\xea\xac\x6c\xac\x1f\xd6\xcd\xf3\x73\xd8\xdd"
+  "\xa1\x50\xf7\x5f\xcd\xd3\x2b\x09\xbe\x3f\xe1\x1f\x46\x22\xeb\xbd"
+  "\xc6\xd1\xc6\xdd\xdb\x58\xb9\x41\x01\x94\x7b\x9f\x57\xfe\xa7\xc6"
+  "\x0a\xb1\xbe\x9a\x40\xca\xed\x61\xff\xf7\x0a\xb1\xbe\xba\x40\xca"
+  "\xb5\x7a\x2f\xd7\x24\xd6\x37\x22\x80\x72\x67\x78\x5f\xff\xc0\x68"
+  "\x12\xeb\x6b\x08\xa4\xdc\x6e\x7b\x58\xcb\xf1\x10\x18\x16\x66\x34"
+  "\xf4\x84\x85\xc0\x70\x70\x7f\x0f\xed\xaf\x08\x0d\x0c\x03\xf7\x1b"
+  "\x7b\xc2\x40\x60\xfa\xbf\xbf\x47\xfd\x07\xa6\xfb\x99\x93\x7a\xd2"
+  "\x7d\x60\x7a\x9f\xe9\x15\xff\xd8\x37\xa0\xc6\x5d\x75\x34\xd8\x9c"
+  "\xc4\xe7\x65\xd5\xf1\xc1\xbb\x3e\x7a\x86\x8f\x20\xf7\x6c\x24\x24"
+  "\xa4\x80\x8c\xb8\xa7\xe8\x73\x1a\x21\xf4\xb9\x67\xe9\x36\x16\x12"
+  "\x0e\xfa\xd0\xdc\x5b\xeb\xea\x39\x8b\x7d\x0a\xf2\x96\xa3\x6c\x75"
+  "\xbb\xe2\x3a\x48\x7f\x0f\xfc\x60\x2b\xc4\xb2\xac\xac\xac\xba\xbc"
+  "\xd4\x08\x22\xbc\x5b\x07\xfd\x88\xd9\x4f\x7f\x4e\x71\x2d\xc2\xa8"
+  "\xef\x80\x5f\x0b\x70\x6d\x43\x32\x02\xae\xb5\x03\x8e\xa1\x9c\x76"
+  "\xf2\x0e\x6f\x53\xcc\xb6\x09\x79\x6d\xc2\x7c\xf7\xbc\x5d\x1f\x61"
+  "\x5f\x81\xa6\xe9\x71\x9d\x32\x1b\xdc\x7b\xeb\x10\x1b\xe1\x8a\x71"
+  "\xaf\x9d\x4d\xb3\x8c\x56\xc5\xec\x0d\xe2\xfb\xa9\x4d\xc2\x7a\x7a"
+  "\x50\x77\x5c\x4f\xef\x19\xe8\x37\x60\xfe\x9b\x92\x08\x87\x6b\x1e"
+  "\x43\x5e\x13\xae\xb1\xd7\xd3\x7b\xde\x0e\xe3\xfe\x72\xbc\x9e\x1a"
+  "\xc1\x3f\x9f\x26\x5c\x6d\xab\x8d\xd0\xb0\xf4\xf0\x3c\xe8\x9f\x4c"
+  "\xbf\x01\xc7\x53\x9a\x49\xea\x46\xca\xe3\xd8\x16\x55\xed\x89\xc3"
+  "\xf9\x87\xc2\xfa\xef\x8a\xd9\x73\xb1\xaf\x2f\xee\x8f\x34\xea\x14"
+  "\xfc\x16\xfa\x48\x38\x0f\x47\x95\x15\x4d\xf3\xd4\x11\xb5\xad\xcd"
+  "\xc2\xfe\x1e\x27\x14\xb3\xe7\xe1\x5a\x67\x2d\xaa\xfd\x3b\x5b\x55"
+  "\xfb\x4d\x6d\x9b\x66\xcf\x91\xda\x80\xf7\x97\xd2\xb1\x4f\x88\xf9"
+  "\xe0\x7c\x92\xf4\xde\xb7\x97\xbd\x75\x47\x46\x69\xa9\x0d\xe5\xcb"
+  "\xea\x12\x75\x0c\x75\x00\x71\xc8\xf6\xd6\x34\xfd\x18\x36\x46\x32"
+  "\xdb\x8e\x7d\x6d\xa8\xf7\x36\xd6\xef\xcd\xda\x26\xec\x11\x02\xfe"
+  "\x60\x9e\x9e\xf3\x33\x26\x9e\x2d\xec\xe5\x69\x1e\x83\xfe\x37\xea"
+  "\x5d\x28\xff\xd7\x27\x14\x51\x3a\xd6\xcf\xcb\xda\xce\xde\xdd\x9c"
+  "\xbd\x0f\xee\xb1\x1d\x7e\xcf\xc1\x7c\x70\x3e\x42\x3c\xbf\x53\x76"
+  "\x7e\x27\xce\x47\x15\xcf\xc7\x88\xe7\xcb\x65\xe7\xcb\x93\xc6\xe0"
+  "\xb8\x47\x54\x36\xb6\x01\xe4\x98\x0f\xe7\xcb\x84\x35\x11\x84\x3d"
+  "\x0d\xb3\xf2\xc5\x7c\x65\x4d\x8a\xa8\x3f\xb6\x00\xc6\xe0\xfc\x0e"
+  "\xd9\xf5\x3b\x3e\x48\x09\x27\xf7\x14\xa1\x0c\xa3\xca\xad\xdc\xbb"
+  "\xe2\xbb\x16\xb3\xcd\x42\xdb\xc1\x87\xca\xcb\xb3\x2a\xa2\x0c\xe8"
+  "\x27\x5b\x21\x46\x83\x3c\xdb\xf1\x9e\x72\x79\x4b\x6f\x90\xea\x62"
+  "\x97\x2d\xd0\x2d\x5a\xbe\x2a\x11\xdf\x00\x74\x7d\xb7\x4d\x83\xef"
+  "\xc8\xf2\xc6\xbd\x05\x96\x02\x7c\x67\x4f\x23\xbc\x1f\xbe\x0d\xe7"
+  "\x68\x05\x57\xd6\x39\xf2\x2a\x63\xf8\xe0\x3d\x06\xf3\xba\xbb\xc9"
+  "\x19\xc5\x1c\xe1\xf9\x81\x05\xa4\x66\x84\xf3\xe6\x75\x87\x31\x4d"
+  "\xd8\x5f\x09\xf7\x81\x11\xc6\x03\xd6\x05\x91\x03\xba\x66\x61\x4c"
+  "\x01\xce\x6d\x15\xc6\x4f\xbe\x27\x9c\x3d\x23\x88\xfc\x3d\xb5\x8e"
+  "\xdb\xc7\x5b\xb9\xbf\xf3\xf5\xc2\x5c\xe8\x0f\xb4\x55\x64\x62\x4a"
+  "\x10\xee\x89\xc6\x55\x42\x3f\x1d\xcf\xe3\x39\xe9\x1d\x22\xb8\xfe"
+  "\x0b\x61\x5e\xf4\x58\xf6\x3d\xad\x80\x7e\xf1\x81\xd6\x26\xbe\x3b"
+  "\x3e\x67\x32\xd6\x15\xe7\x39\x36\x29\xe6\xdc\x86\xf5\xb3\x2a\xe6"
+  "\x4c\x19\x52\x88\xf3\xa8\x89\xea\x8c\xe2\x81\xeb\xf9\xdc\xbd\x05"
+  "\xc8\x0d\xf6\x4d\x51\x4d\x34\x43\x55\x86\xef\x0f\x16\x3e\x2f\xbd"
+  "\x2b\xfb\x80\x46\xf6\x3e\x9d\xaa\x85\x23\x77\x42\xda\x38\x69\x3d"
+  "\x0c\xdc\x97\xc8\x1b\xd7\xb4\x43\xfc\x78\x2e\xcc\x60\xe2\x55\x7b"
+  "\x41\x17\x7b\x0b\xaa\xa6\x11\x1c\xd3\x51\xe0\xbc\xe4\x26\xc5\x43"
+  "\x61\x54\xbd\x37\x3b\x15\x6d\x3a\x6f\x8f\xe1\x2f\x38\xe7\x10\xe4"
+  "\xb8\x03\xe7\x18\x82\x2c\xdf\x80\xdf\x87\x23\xb7\x13\xdd\x83\x18"
+  "\x8f\x3d\xf0\xfb\xfb\x63\xa9\xfd\xc6\x39\x66\x52\xdd\xf0\x37\x72"
+  "\xe4\x68\x15\x51\xcd\x27\x43\xd2\xac\xd4\x21\xb4\x31\x99\x70\x51"
+  "\x56\x32\x04\xd7\x6a\xc2\xf5\xd9\xf1\x1d\x8d\xda\xf6\x1a\x88\x91"
+  "\x5e\x88\x7d\x2b\xb5\x71\xa8\x6e\x36\x81\xd8\x8a\x3d\xbf\x16\xde"
+  "\x3f\xb2\x09\xef\x7f\xab\x71\x2c\x5d\xf6\xde\x51\xd8\x86\x18\xca"
+  "\x6f\x3c\x4d\x82\x6a\xe2\x3e\x23\x51\x31\x43\xa8\xf0\xde\x51\x0a"
+  "\x64\xb4\x81\xee\xd7\xb0\x79\x82\x2f\x9d\x25\xa1\xb5\xc9\x56\x62"
+  "\x69\xaa\x22\xaf\xac\x20\xa1\xb4\x2d\x6e\x58\x75\xd5\x61\x42\xf3"
+  "\xc6\xcc\x79\x27\xd5\x3c\xd4\xa1\x62\x73\xb7\x42\xd2\x15\x38\x76"
+  "\x1a\x6c\xc4\x39\x5c\x67\x49\xf8\x93\x5f\x1a\x84\xf1\x5e\x1c\x5b"
+  "\xb7\xb7\xe9\x75\x9d\x6d\xfa\xb1\x1d\x6b\xf4\x63\xa4\x31\xf9\xc7"
+  "\x4f\x6b\xf0\x19\x44\x34\xdd\x74\x4f\x0a\xbe\xb3\x84\xb1\xa8\x5d"
+  "\x3d\x36\x1a\xc7\xdf\x85\xb5\x67\xd6\xe8\xc3\xf8\x45\x7a\x32\xd1"
+  "\x26\xbc\x13\x85\xcf\x04\x34\xc5\x0b\xb1\xae\xcd\x44\x98\x87\xa4"
+  "\x66\xf3\x90\xda\xf1\x79\xb8\xaa\x32\x68\x56\xbc\x8e\x74\x8c\x36"
+  "\x98\x2c\x29\x7f\x21\x69\xe7\xe8\x17\x42\x1f\x01\xf7\x8a\xdf\xf4"
+  "\xc0\x54\xaa\xae\x0c\x3a\xa8\x3f\x86\xbe\x65\x8a\xff\xfc\xf0\xa0"
+  "\xf0\xae\x34\xca\x06\xf4\x54\xb7\xa3\x19\xf5\xb6\xc7\xf0\xe6\x0a"
+  "\x1b\x37\xa3\x81\xda\x6b\x62\xff\x42\x8e\xd4\xd7\xb9\xe8\x47\xd0"
+  "\x27\xe4\x43\x3d\xa1\x8e\x50\x57\x4e\x3d\x1d\x13\xf4\xb4\x83\x67"
+  "\x7a\xea\x50\xed\xaa\x93\x74\xd5\x5e\x68\xa8\xf2\x45\x5f\xd5\x0d"
+  "\x9e\xf5\x05\x72\xee\xd2\xd7\xcb\xcd\x24\xd4\xd2\x04\x71\x33\xe8"
+  "\x6b\xc6\x03\x84\xcc\x78\x83\xf2\x35\x91\x1f\x75\xe9\xcd\x6e\xf4"
+  "\xa2\xb7\xaf\x9d\x7a\x03\xfd\xf7\xa4\x37\xbb\x3f\x7a\xab\x6e\x60"
+  "\x7a\xb3\x8b\xf3\xc7\xf4\x07\x08\xd7\xbe\x46\xcf\x15\x9c\x25\x53"
+  "\x50\x7f\x33\xbf\xd4\x91\x83\x73\x6b\x40\x67\x7f\x73\xd1\x1f\x9f"
+  "\xbb\x7f\x3b\xe8\xa0\x01\x75\x18\x98\xdd\x3d\xbc\xcd\x77\xbb\x9b"
+  "\xa7\x1e\xb4\xbb\xfe\xb2\xbb\xb9\xe5\x7d\xb3\xbb\x87\x63\x06\xed"
+  "\xee\x42\xdb\xdd\xc3\xf3\xdd\xed\xae\x2b\x6e\x58\xb1\x78\xd9\x82"
+  "\xf8\xc4\xf8\xc4\xdf\xe9\x16\xae\x4d\x5e\xbc\x92\x45\x0f\x2e\xf1"
+  "\x83\xd6\x91\x1a\xc1\xe1\x1e\xe4\xd5\x05\x75\xe4\x9d\x51\x75\x9c"
+  "\xe3\x2b\xad\x92\x1a\x27\x95\xf2\xc6\xc9\x3a\xdc\x8f\x1c\xed\x13"
+  "\xf7\x29\x3f\xa9\x78\x5c\x8b\xeb\x18\xb2\xf5\x60\x1e\x17\xf6\xb0"
+  "\x80\x38\x35\x12\x9f\x05\x3d\xd3\x01\xc7\x3a\xa2\x0c\x69\x27\x41"
+  "\xe6\x31\x78\x7e\xfe\x2a\x5c\x73\x8d\x16\xa5\x47\x16\xe3\xfe\xe1"
+  "\x1d\x44\xd9\xaa\xca\x9a\x93\x09\xe5\xd9\xd4\x7b\x0b\x94\x3a\x7c"
+  "\xb7\x25\xfa\x28\xf8\x7c\xa5\x73\x9d\xa5\xf9\x53\xe8\x25\xd1\xe3"
+  "\x90\x1b\xf0\x5d\xc4\x33\x8a\x47\x86\x9d\xc3\x67\x29\x10\x4f\xcf"
+  "\xbb\x01\xee\x35\xda\xc0\xd6\x90\x00\x9e\x60\xe7\x1f\x15\x9e\xaf"
+  "\x9d\x33\xee\x31\x08\x7b\xb9\xab\x2a\xeb\x5a\x8c\x95\x31\x87\x37"
+  "\x14\x88\x3c\xf1\xc8\xe4\x19\x05\x8c\x27\x6a\xb4\x80\xc3\x99\x80"
+  "\xc3\xe8\xde\x78\x42\x86\xbf\x31\xfe\xf1\x04\xe2\x0d\x71\x87\x98"
+  "\xbb\x0c\x30\x87\x38\x94\x70\xf7\x82\x88\xbb\x90\xe3\x44\x23\x60"
+  "\xcf\xce\xb0\x87\xef\x6c\xd7\xa4\x38\x71\xe7\x70\xc7\xdd\x59\x37"
+  "\xdc\x71\x22\xee\xd6\xb8\xe2\xee\xb1\xcf\x34\xe4\x15\x01\x77\x77"
+  "\x3b\x71\x97\x3b\x36\x5a\xc2\x1c\xe2\x0f\xb1\xc6\xff\x4e\x4f\x6a"
+  "\x9a\x9a\xbb\xf0\x57\xbc\x84\x3d\xcf\x15\xe6\x0b\x73\x74\xe7\xb9"
+  "\x35\x22\x5f\x9c\x96\xf8\xe2\x65\x2f\x7e\xfa\xb3\x00\xf9\xe2\x51"
+  "\xa1\xff\x8f\xba\xea\x00\xbd\xa1\xbe\x66\x68\x81\x27\xb4\xaf\x92"
+  "\x23\x73\x2f\x12\xfd\xac\xe8\x1f\xfd\xe0\x3e\xce\x50\x17\x4f\x3a"
+  "\x52\xf6\xa6\x23\xd4\x0f\xea\x49\xd0\x0f\xe8\x49\x7a\xe6\x8e\xcf"
+  "\x60\x51\x57\xa8\x9f\x9b\x36\x10\x0e\xf5\x55\xbc\x9a\x71\x04\x72"
+  "\x81\x30\xc7\xdb\x8d\xe3\x41\xe6\x46\xd4\x99\xd0\xcf\xce\x50\x27"
+  "\x6c\x1b\xe9\xdc\x23\xa7\x6d\xd3\xfc\xe8\xee\x71\xf4\xfc\x04\xe7"
+  "\xba\x72\xd1\xc2\xf8\x82\x79\x14\xae\x09\x1e\xbd\x83\xf5\x97\xf6"
+  "\xb2\xbd\x4c\x14\x8f\x1f\x12\x39\x20\x1c\xfb\xae\x42\x3f\xd5\x01"
+  "\xfd\x54\x15\xf4\x53\x8d\xd0\x4f\xc5\x71\x44\x61\x2d\x86\xf9\x07"
+  "\xd9\x33\x3e\xe8\x97\xaa\xf7\xc4\x41\x1f\x29\x1a\xe5\x2a\x3c\x4f"
+  "\x56\xef\xdf\x89\xcf\xbf\x68\x2e\xf4\x81\x5f\xe5\x08\xfc\x36\x1d"
+  "\xd4\x3b\xfc\xc4\xd4\xfc\x06\xf1\x79\xb9\x81\xad\x4d\xf8\x78\x39"
+  "\xab\x5f\xb4\x30\xcf\x51\x78\xd6\xc8\xf1\xa5\x8e\x67\x5c\x9f\x35"
+  "\xca\x9f\x45\xbf\x93\x6a\x13\x9f\x33\x3e\xde\xb5\x0e\x02\xf2\xe0"
+  "\x5b\xd0\xa7\x71\x3e\x6b\xfc\x08\xcf\x17\xb9\x3e\x6b\x7c\x3c\x89"
+  "\x08\xef\x0d\x3e\x5e\x85\xf3\x6b\xe0\x77\x26\x4b\x8f\x36\xca\xd3"
+  "\x9d\xcf\xf2\x59\x3a\xbe\xd3\x25\x8e\x15\x34\xb1\x71\x82\xc7\xad"
+  "\x52\x7f\xdc\x4b\xfc\xe4\x07\x4f\x2f\x3c\xea\xe4\xe9\x85\x47\x05"
+  "\xd9\x68\xcd\x29\x35\xdd\x78\x1a\xd7\xf8\x5a\x78\xf3\x6c\xe4\x69"
+  "\xe3\x9e\x24\x56\xbf\x27\x96\x81\x4c\x86\xe0\x3e\x77\x98\x8e\xef"
+  "\x3e\x21\x5f\x17\xc1\x75\x45\x02\x87\x9b\xe3\x32\x85\x39\x05\x4f"
+  "\xe4\xbb\x72\xf7\x82\x56\x57\xee\x7e\xe2\x60\xcf\xdc\x1d\x93\xde"
+  "\x33\x77\x3f\xf1\xdd\x20\x77\xf7\x37\x77\x4b\xb1\x5e\xa0\xdc\x1d"
+  "\x33\x73\x90\xbb\x07\x9a\xbb\x63\x22\x65\xdc\xfd\x5b\x57\xee\x5e"
+  "\x18\xda\x9d\xbb\x17\xea\x9d\xdc\xfd\x44\xa1\x93\xbb\x9f\x98\xeb"
+  "\xca\xdd\x8b\xb2\x7c\xe3\xee\x85\xe9\xe7\x97\xbb\x17\x96\xba\x72"
+  "\xf7\x22\x89\x87\x26\xfb\xcf\xdd\x8b\x1e\xe8\x99\xbb\x17\x3d\xe2"
+  "\xca\xdd\x8b\xc6\x33\x8e\x5e\x94\xc9\xb8\x7b\x51\x04\x4b\x7f\x62"
+  "\x92\x3c\xdd\xc9\xdd\x2c\xbd\x3b\x77\x2f\x2a\xec\x85\xbb\xf5\x0e"
+  "\x5e\xe2\xee\x7a\xe0\xee\x7a\x8e\xff\x9d\x37\xee\x8e\xb3\xd7\x20"
+  "\x77\xaf\x40\xee\x8e\xb3\xf7\xcc\xdd\x71\x5f\x23\x47\x03\x8e\x49"
+  "\xe1\x8b\xb4\x11\xd7\xac\x34\x2f\xf9\x0f\x8e\x61\x37\x20\x6e\xe1"
+  "\xfc\x5d\xb3\x37\xc8\xb9\x3d\xf6\xbe\x2e\x6e\x87\x74\xfe\x2a\x57"
+  "\x6e\x47\x5e\x47\x7e\x2f\x7a\x91\x5a\x8b\x5f\xa4\xc7\xdb\x36\xc5"
+  "\x26\x4b\x1c\x9f\x0b\x69\xb8\x37\x09\xae\xa9\x54\x74\x56\x38\x94"
+  "\x20\x83\x86\x67\xe0\xbe\x78\x0d\xe4\x2d\x75\xf5\x07\x71\x4a\xfb"
+  "\x26\xb9\x3f\x88\x3d\x86\xfe\xc0\xc8\xd6\x01\x10\xfc\x80\xbd\xc8"
+  "\x50\x85\xbe\x81\x9d\x5f\xb2\xb5\x67\x7f\xb0\x58\x71\xa1\xfc\x01"
+  "\x72\xcd\x65\xb2\x3e\xa4\x37\x7f\x80\x63\xaa\x35\xb1\x03\xe3\x0f"
+  "\x90\x67\x90\x5f\x90\x6b\x90\x77\x90\x67\x90\x73\xec\xe2\xbb\x7f"
+  "\x85\x19\x3e\xf8\x03\xe0\x15\x7a\xc9\xdc\x72\xc1\x1f\x28\x02\xf1"
+  "\x07\x4b\xe6\xff\xa0\xfc\x01\xea\x67\xc3\xf9\xf5\x07\x52\x3f\x1f"
+  "\xf5\x83\xba\x92\x74\x24\xf5\xf5\x51\x3f\xa8\x27\xd4\x0f\xc6\x46"
+  "\x92\x3f\x98\x90\xc2\xfc\x41\x51\xaf\xfe\x60\x49\x74\x97\x3f\xe0"
+  "\x98\x3f\x10\xc6\xc4\x47\xa2\x3f\x88\x1b\xd7\xdd\x1f\xc4\x4d\x71"
+  "\xfa\x83\xd8\x1d\x22\x3f\x36\xe0\xfa\x16\xc0\x07\xe1\xae\x3e\x21"
+  "\xfe\x2d\xdf\x7c\x42\xdc\xef\xbb\xf9\x04\x90\xad\x91\x3d\x3b\x43"
+  "\x7f\xb0\x13\xfd\x81\x1d\xfd\x42\x40\x3e\x21\xae\xdc\xe9\xb7\x62"
+  "\x35\x8c\x8b\xe3\xe6\xb8\xfa\x89\xf8\x02\xd1\x8f\x7d\x27\xf7\x13"
+  "\xfc\x10\x5f\xfc\x44\xfc\x5a\xc9\x4f\x20\x0f\xbf\x85\xcf\x2c\xba"
+  "\xfc\x04\xf2\x6a\x7c\xba\x79\xf5\x09\x99\x9f\x88\x9f\xcb\xea\x10"
+  "\xbf\xc3\x21\xf8\x89\xf8\x38\xd1\x7f\xd8\xe4\xe9\x4e\x3f\xc1\xd2"
+  "\x1d\x72\x3f\xd1\x88\x7e\x22\xfe\x40\x2f\x7e\x62\x92\xef\x7e\x62"
+  "\x79\xa1\xd3\x4f\x2c\x2f\xec\xd9\x4f\x2c\xdf\x8c\x7e\x42\x58\x93"
+  "\x17\x74\x0f\x38\x57\xe6\x5d\xc1\x7c\x04\x8e\xd1\x80\xef\xb0\xe2"
+  "\xba\x2a\x90\x6f\x55\x09\xfa\x11\x38\xe0\x7c\xa3\x11\xbf\xf3\xc2"
+  "\x35\xc7\x43\x6c\x24\x08\x7d\x86\xf1\x24\x51\xe2\x9e\x50\x4c\x4e"
+  "\x89\x1f\xc2\xb5\xf5\x4e\xff\xb2\xf4\x0d\x1f\xfd\xcb\x51\xf0\x2f"
+  "\x75\x6d\x9b\x96\x1e\x95\xf9\x17\xdc\x57\xab\xce\xcd\xbf\x58\xc1"
+  "\xbf\x34\x48\xd7\xb4\x6d\x7a\x4a\x29\xcf\x8f\xf5\x13\xf2\x9f\x14"
+  "\x0e\xcc\x5f\xff\x0c\xee\x11\x27\xf8\xa3\xa7\xc2\x5d\xfd\x51\xe2"
+  "\x36\xde\xa5\x7f\xf2\xd4\x62\xc9\x1f\xa1\x3f\xe7\xbb\xf9\xa3\x65"
+  "\xd7\x76\xf9\xa3\x2b\x64\xfe\x28\x45\xf2\x47\x4f\x6d\xbd\xe8\xfb"
+  "\x27\x7d\xe0\xbb\xf3\xed\x8f\x78\xf0\x3b\xee\xfe\x08\x7d\x94\xd4"
+  "\x3f\xe1\x03\xf2\x47\x09\x4d\x3f\x28\x7f\x34\x00\xfd\x13\x77\xdd"
+  "\x48\x3a\x43\xfd\xa0\x6e\x50\x2f\xb8\x2e\x38\xea\x0c\xf5\x85\xba"
+  "\x9a\x90\xe4\xea\x8b\x04\x7d\x81\x3f\xea\xf6\xec\x00\x74\x05\x32"
+  "\x6f\x44\x7d\xc9\xfd\x51\xf1\x48\xc9\x1f\x25\x96\x77\xf7\x47\x89"
+  "\x55\x4e\x7f\xf4\x94\xb0\xff\x00\x5b\x97\x71\x69\xbe\xab\x2f\x4a"
+  "\x9a\xe5\x9b\x2f\x5a\x7e\xad\x07\x5f\x24\xac\xaf\x69\x7c\xd1\xa5"
+  "\x6f\xb2\x13\xfc\x51\x00\xbe\x68\x79\x04\xab\x23\xce\x33\x5f\x1a"
+  "\xc3\xf8\x3e\xf1\xb8\xd3\x3f\x2d\x9d\x22\x4f\x73\xfa\xa7\xa4\x29"
+  "\x22\x27\x5e\xe5\xbf\x7f\x4a\x12\xae\xc1\x39\xe8\x6f\x35\x33\x1f"
+  "\xe0\xea\x9f\x92\xae\x75\xf5\x4f\xcb\x5b\x59\x1d\x92\x66\x32\xff"
+  "\x94\x24\xa6\x2f\xd5\xca\xd3\x9d\xfe\x89\xa5\x77\xf7\x4f\x49\xb1"
+  "\xbd\xf8\x27\x55\x67\xa1\xa1\xaa\xc3\x58\xb9\xd3\x5e\xb6\x35\x66"
+  "\xfc\xfc\x6b\x1c\xee\xf6\xc4\xec\xc8\xc1\xf6\x27\x92\x9e\xb7\x3d"
+  "\x4c\x48\xa7\x6a\x57\x1d\x2f\xbe\xab\xdd\x11\x66\x30\x9d\x4c\x00"
+  "\x9b\x6a\xf2\x6e\x53\x60\x4f\x41\x92\x3d\xd5\xc4\x7d\x49\xc0\xc6"
+  "\x38\x7c\xde\xf6\x32\xd8\x92\xa5\xb5\x5e\xb0\x2d\x55\x83\x8e\xe0"
+  "\x9a\x9b\xea\x26\xa2\x51\x2b\x14\x97\xdc\xff\x08\xd8\x2c\xd8\xd5"
+  "\xf4\x1b\x28\x7f\xe3\x71\x1d\x51\xc7\x91\x60\xb4\xad\xb7\xc5\xe7"
+  "\x39\xb8\xce\x06\x3e\xc7\x01\x5c\x87\x3f\xf9\x21\xb3\xa9\x97\xe1"
+  "\xe8\x60\x36\x35\xa6\xa3\x4d\x3f\xd6\xdb\x73\x1c\x4b\x8a\x55\x78"
+  "\x8e\x83\xef\x41\xe1\xfb\x67\x3c\xda\x10\x3e\xc7\x69\x67\xb1\x1d"
+  "\xd4\x57\x53\x22\x3c\xc7\x39\xe1\xf2\x1c\xe7\xe7\xc7\x09\x87\x6b"
+  "\x70\xbc\x22\x7f\x8e\xa3\xaf\xe9\x16\xd7\xa1\x7d\xa1\x3d\xf9\xcf"
+  "\x79\x4f\x7b\x9d\xff\x25\xcc\x9d\x00\x59\x3b\x54\x95\x3b\xe9\xcb"
+  "\xe6\xd2\x37\x4f\xb4\x2b\x70\xad\x53\x07\xe8\x8e\x07\x6e\xa3\x2a"
+  "\x37\x6e\xeb\x14\xf5\xd0\xc9\xf4\x00\x3a\x0c\x7a\xa2\x95\xd0\x27"
+  "\xed\x60\x3f\x9d\xe2\x7a\xa7\xed\x56\xc0\xa1\x7e\x64\xd1\x3a\x94"
+  "\xbb\x96\x14\x89\x6b\x9e\xf2\xeb\xe3\x86\xf1\x20\x6b\x9a\xc1\x91"
+  "\xb7\xce\xb6\x0b\xcf\x3d\x8d\x1d\x64\x3c\x70\x99\x1a\xb9\x0c\xb0"
+  "\x3b\xbc\xa4\x03\xe4\xfe\x05\x93\x3b\xae\xa9\x87\x9f\xf6\xf5\x7a"
+  "\x1d\x94\x3d\xb6\xb3\x13\xb8\xac\x9d\xc9\xfe\x89\xa7\x35\x44\x58"
+  "\x27\x15\x9f\x7d\x42\xdc\x50\x0b\xfa\x16\xb8\xac\x35\x84\xe2\x9e"
+  "\x21\xfc\x57\x7a\x5c\x5f\x2c\x6c\x62\x2b\xee\x0f\xa3\x47\x6c\x68"
+  "\x8a\x4f\xe2\xb3\xcf\xff\xb8\x3c\xfb\xb4\xad\x77\x3e\xfb\xac\xdd"
+  "\x7e\x8c\xcd\x55\x71\x19\x0f\x4b\x4a\xe9\x2c\x62\x3e\x47\x18\x0f"
+  "\x4b\xf6\x57\xf6\x2b\xbd\xae\xff\x73\xfe\x65\xaf\xf9\x81\xcb\x7e"
+  "\x85\xbe\x6f\xb2\x4f\xf6\x3a\xff\xf7\xfc\xcb\x3e\xe8\x07\x2e\xfb"
+  "\x95\x65\x7d\x93\xfd\xea\x9e\xf6\x10\x51\x61\x1f\x46\xea\xbf\x48"
+  "\x7d\x17\xf4\x61\xcc\x5f\xa7\x34\x3a\xfb\x2d\x29\x8d\xd2\x33\x64"
+  "\x90\x99\x32\x17\xd7\x07\x07\x59\x24\x2d\xc1\x3d\x38\x52\x1e\x97"
+  "\x9e\x1f\xe7\xe3\x3e\x33\xa8\xc7\x97\x41\x8f\x89\xf8\x1e\x93\xa8"
+  "\x43\xf0\x39\x4f\xb6\x82\x5f\x18\x6d\xa8\x72\xe4\x82\x4f\x7a\x6d"
+  "\x6b\x8c\x17\x7d\x72\xe8\x4f\xd4\xc9\x44\xf3\x44\x92\x53\xaf\xfc"
+  "\x7a\xd0\x67\x07\xc4\x66\xed\x8d\x04\xdf\x4d\x0e\x69\x84\xb8\xb5"
+  "\x33\x6e\xd8\x7c\xe8\x03\x48\x3a\x7d\x7b\x75\xbb\x10\x97\x79\xd4"
+  "\xe9\x4b\xae\x3a\x6d\xf1\xa0\xd3\xc7\xe3\xc1\x4e\x39\x31\x76\x16"
+  "\x74\x6a\xed\xd2\xa9\xe0\x47\xd6\xeb\xc3\x50\xaf\x92\x4e\xd1\x8f"
+  "\x08\x3a\x6d\x62\x7e\xa4\x6b\x1d\xa7\xf5\xce\xd8\xb9\x3a\xe6\x33"
+  "\x0f\x3a\x5d\xa5\x73\xd1\x69\x8c\xbf\x3a\x4d\xd1\xbb\xc6\x5f\x6b"
+  "\x7f\xef\x5b\xfc\x95\xf2\x1a\xc6\x57\xf2\xf8\x0b\x7f\xb7\x40\xbc"
+  "\xe5\x50\xef\x2f\x6f\x0d\xa8\xff\x9f\x52\xee\x1a\x4b\xad\x35\xb0"
+  "\x3a\xad\xfe\xd0\xff\x58\x6a\xad\xb0\x27\xd1\x5b\x2f\x7b\x8a\xa3"
+  "\xd6\xc6\xbb\xc6\x51\x6b\xa7\xb2\x78\x69\xed\xb6\x96\x0c\x8c\xa3"
+  "\xd6\xce\x61\xe9\xab\xeb\xe4\xe9\xce\x38\x8a\xa5\xb7\xe0\x5a\x77"
+  "\x9b\xd6\x96\xfa\x17\x3b\x5d\x79\x81\x63\x27\x6d\x0f\xb1\x93\xf6"
+  "\x47\x12\x3b\xad\xf7\xba\x47\xd5\xa0\xff\xee\xcd\x87\xac\x2d\xef"
+  "\x9b\x0f\xd9\x50\x30\xe8\xbf\x03\x95\xfd\xfa\xd8\xbe\xc9\x3e\x35"
+  "\x34\x70\xff\x6d\xd8\xee\xf4\xdf\x86\xed\xde\xfd\xb7\x61\xf4\xa0"
+  "\xff\xf6\xc7\x7f\x6f\xb0\xf6\xcd\x7f\xa7\x35\xba\xfa\xef\xf4\x79"
+  "\xbe\xf9\x6f\xc3\xe2\xfe\xf7\xdf\x86\x64\x57\xff\x9d\x1e\xc1\xea"
+  "\x94\xba\xd5\x7f\xff\x9d\x7e\xad\x77\xff\x9d\x7e\x83\xab\xff\x36"
+  "\xd8\x99\x9f\x4e\x9f\xcb\xfc\x77\xba\x86\xa5\xa7\xe6\xcb\xd3\x9d"
+  "\xfe\x9b\xa5\x33\xff\x9d\x1e\xe3\x9f\xff\x0e\xb9\xc0\xfe\x5b\xd3"
+  "\x83\xff\xd6\xfc\x48\xfc\x77\xc6\xf1\x41\x1f\x12\xa8\x0f\x49\x4f"
+  "\xee\x9b\x0f\xc9\x8c\x0e\xdc\x87\x6c\x6a\x72\xfa\x90\x4d\x4d\xde"
+  "\x7d\xc8\xa6\x05\x83\x3e\xc4\x1f\x1f\xf2\xcc\xb8\xbe\xf9\x90\x4d"
+  "\xe3\x5d\x7d\xc8\xb3\x2f\xf9\xe6\x43\x36\xbd\xd1\xff\x3e\x64\x93"
+  "\xc9\xd5\x87\x3c\x2b\xae\x8d\x94\x79\xcc\x7f\x1f\xf2\xec\x62\xef"
+  "\x3e\xe4\xd9\x65\xae\x3e\xe4\xd9\x08\xe6\x2b\x9e\x2d\x60\x3e\xe4"
+  "\xd9\xb9\x2c\x3d\xf3\xa8\x3c\xdd\xe9\x43\x58\x3a\xf3\x21\xcf\x96"
+  "\xf9\xe7\x43\x2e\xbd\xc0\x3e\x24\xa8\x07\x1f\x12\xf4\x23\xf1\x21"
+  "\x9b\x75\x81\xf3\xd8\x73\xe5\x4e\x1e\x7b\xae\xdc\x3b\x8f\x3d\x77"
+  "\xc3\x20\x8f\xf9\xc3\x63\xcf\x9a\xfa\xc6\x63\x39\xad\xae\x3c\x66"
+  "\x5c\xe0\x1b\x8f\x3d\xf7\x74\xff\xf3\xd8\x73\x06\x57\x1e\x33\xce"
+  "\x64\x75\xda\x5c\xe4\x3f\x8f\x19\x27\x78\xe7\x31\xe3\x64\x57\x1e"
+  "\x33\x06\x31\xbe\x32\xc6\x30\x1e\x33\x86\xb1\xf4\xcd\x85\xf2\x74"
+  "\x27\x8f\xb1\x74\xc6\x63\xc6\x84\xde\x78\x0c\xed\xa2\x46\xeb\x66"
+  "\x17\x4f\x49\x76\x91\x77\xfc\x48\xa1\x64\x17\x79\x42\x8c\xc6\x17"
+  "\xa6\x47\x3e\xb7\x9a\x28\x8d\xb8\x3f\x0f\x70\x44\xd2\xa3\x68\x17"
+  "\x79\x0f\xe0\x3c\x11\xd5\x71\xe0\xbd\x06\x91\x07\x53\x80\x07\x1b"
+  "\xe0\x37\xae\xd9\x36\x3a\x3d\x12\xf9\x0b\xf7\xf3\xc0\xdf\x8c\x0f"
+  "\x6d\x43\x71\x7f\x20\xe1\xd9\xbc\xcc\x6e\x04\x5b\x69\x11\x6d\xa5"
+  "\x85\xd9\x8a\xf4\xee\xde\x86\x06\xca\x3b\x56\xea\x47\x46\xc5\x0e"
+  "\xa1\x68\x3f\xc2\x3b\x61\x60\x3f\x74\xa5\x3e\xb8\x70\x05\xd8\x8c"
+  "\xad\x91\xe0\xba\xfc\x68\x33\xea\x74\x45\x30\x6d\x89\x1b\x06\x9c"
+  "\xc8\xb8\x8f\xaf\x1a\x6a\xc7\x35\xb6\x56\x02\xf7\x35\x03\xf7\x35"
+  "\x3b\x6d\x05\x9f\xb7\xb7\xac\xd4\xeb\x5a\x57\xea\xc7\x74\xb6\x00"
+  "\xf7\xd9\xba\xd9\x89\xb2\xa4\x19\xb9\xaf\x51\xb0\x13\x81\xfb\xc0"
+  "\x36\xf8\x16\xe0\xbe\xdf\x89\xdc\xd7\xa2\x47\xae\xd7\x94\x2c\x01"
+  "\xee\x8b\x39\xc5\xb8\x4f\x8c\xe1\xae\x43\xee\x5b\xa9\xe7\x5e\x68"
+  "\x16\xb9\x6f\x01\x72\xdf\x41\xb0\x91\xbd\xae\xdc\xa7\x0e\x94\xfb"
+  "\xf2\xc2\x5c\xed\x64\xcb\x66\xdf\xec\x24\xef\x25\x6f\x76\xd2\x99"
+  "\x1b\xa8\x9d\xe4\x6d\x77\xb5\x93\x2d\xc9\xa2\xed\xee\xf2\xdf\x4e"
+  "\xb6\xcc\xeb\xb2\x93\xa7\xdc\xed\x64\xcb\xe3\xae\x76\xb2\x25\x9c"
+  "\xd9\xc3\x96\x6c\x66\x27\x5b\xa6\x89\xf6\x53\x2e\x4f\x77\xda\x09"
+  "\x4b\x67\x76\xb2\x65\xdb\xe0\xf3\xf2\x1f\x9a\xbf\xdf\xaa\x19\x7c"
+  "\x5e\x1e\x68\x9f\x71\xcb\xf6\xbe\xf5\x19\x9f\xf7\xba\xfe\xcd\xe0"
+  "\x78\x7b\x6f\xb2\xdf\x1a\xdd\x37\xd9\x6f\x0b\x1a\x1c\x2b\x09\x54"
+  "\xf6\xcf\x1f\xed\x9b\xec\x7f\x9f\xd9\x5b\x1f\xc3\x7b\x2c\x55\x10"
+  "\x5e\xdd\xd5\xc7\x28\x08\x97\xe6\xf9\x76\xef\x63\xfc\xe1\x35\xd7"
+  "\xf7\xf8\x5e\x9c\xec\xfe\x1e\x5f\x6f\x7d\x0f\xfb\x60\xdf\x03\x74"
+  "\xbd\x6d\x4e\xdf\xfa\x1e\x7f\x48\x72\x8d\xa9\x0a\x3e\xf3\x2d\xa6"
+  "\xfa\xc3\x69\x6f\x31\x95\x3d\xe0\xbe\xc7\x1f\xec\xae\x31\x55\x41"
+  "\x95\x88\x0d\x85\xff\x31\x55\xc1\x1b\xde\x63\xaa\x82\xbf\xba\xc6"
+  "\x54\x05\x99\x2c\x76\x2a\x38\xce\x62\xaa\x82\x02\x96\xfe\x22\x91"
+  "\xa7\x3b\x63\x2a\x96\xce\x62\xaa\x82\xc6\xc1\xe7\xe8\x3f\xb4\x98"
+  "\xea\xe5\xd8\x41\xbf\x1e\xa8\x6f\x29\xb0\xf7\xcd\xb7\xbc\x72\x01"
+  "\xe7\x7f\xfe\xd0\xfd\xfa\xcb\x3b\xfa\x26\xfb\xa2\x1e\xe7\x7f\xf6"
+  "\xec\xd7\x4b\x83\x9c\x7e\xbd\x34\xc8\xbb\x5f\x2f\xd9\xe8\xea\xd7"
+  "\x8b\xd5\x83\x7e\x3d\x10\xbf\x5e\xa8\xef\x9b\x5f\x2f\x89\x74\xf5"
+  "\xeb\xa5\xbb\x7c\xf3\xeb\x25\x07\xfb\xdf\xaf\x97\x1c\x75\xf5\xeb"
+  "\xa5\xa5\xac\x4e\x45\x9f\xf8\xef\xd7\x4b\xd3\xbd\xfb\xf5\xd2\xcd"
+  "\xae\x7e\xbd\x74\x3e\xf3\xdf\xa5\xe5\xcc\xaf\x97\x26\xb1\xf4\xa2"
+  "\x7a\x79\xba\xd3\xaf\xb3\x74\xe6\xd7\x4b\xcd\x83\xcf\xd7\x7f\x68"
+  "\x7e\xfd\xd5\xa9\x83\xbe\x25\x50\xdf\x52\xda\xc7\x3e\xe3\x9f\x4c"
+  "\x81\xfb\x96\xd7\x63\x9d\xbe\xe5\xf5\x58\xef\xbe\xe5\xb5\x4f\x5c"
+  "\x7d\x4b\x59\xfc\xa0\x6f\x09\xc4\xb7\xbc\x9a\xd9\x37\xdf\xf2\x5a"
+  "\x99\xab\x6f\xf9\xf3\x08\xdf\x7c\xcb\xeb\xd7\xf6\xbf\x6f\x79\x3d"
+  "\xdc\xd5\xb7\xbc\x6e\x17\xb1\x31\xd9\x7f\xdf\xf2\xfa\x67\xde\x7d"
+  "\xcb\xeb\x5f\xba\xfa\x96\xd7\x4d\xcc\x87\xfc\x59\xc3\x7c\xcb\xeb"
+  "\xd5\x2c\xbd\x6c\x92\x3c\xdd\xe9\x5b\x58\x3a\xf3\x2d\x7f\x0e\x1b"
+  "\x7c\xee\xfe\x43\xf3\x2d\xdb\x7b\x9c\xff\xdb\x33\xbf\xbd\x39\xcd"
+  "\xc9\x6f\x6f\x4e\xf3\xce\x6f\x7f\xd9\xe3\xca\x6f\x6f\xdc\x37\xc8"
+  "\x6f\x81\xf0\xdb\x9f\xc3\xfb\xc6\x6f\x7f\xc9\x74\xe5\xb7\x37\xbf"
+  "\xf3\x8d\xdf\xde\x54\xf4\x3f\xbf\xbd\xa9\x71\xe5\xb7\x37\x8f\x8b"
+  "\xd8\xb8\xdc\x7f\x7e\x7b\xf3\x5d\xef\xfc\xf6\xe6\x41\x57\x7e\x7b"
+  "\xb3\x80\xf1\xd8\x9b\x36\xc6\x6f\x6f\xee\x60\xe9\x6f\x84\xca\xd3"
+  "\x9d\xfc\xc6\xd2\x19\xbf\xbd\x69\xef\xdb\xf3\xf8\xb7\x33\x9d\xcf"
+  "\xe3\xdf\x16\x74\xc1\x17\x98\x53\xba\x3f\x8f\x7f\xeb\x9c\xeb\x7a"
+  "\x41\x3b\x36\x0a\xcf\xe6\xd1\x66\x5a\xd9\x9a\x0e\x1e\x9f\xd3\x5f"
+  "\x65\x4e\x19\x7c\x4e\x7f\x3e\x9f\xd3\xbf\x75\xc0\xd5\x7e\xde\xb9"
+  "\xd9\x37\xfb\x79\xfb\xae\xfe\x7f\x4e\xff\xb6\xdb\x3a\x2c\xef\x84"
+  "\x89\x58\x99\xee\xbf\xfd\xbc\xed\xf0\x6e\x3f\xef\x0c\x75\xb5\x9f"
+  "\xb7\xc5\x3e\xe6\x3b\xe1\xcc\x7e\xde\x6e\x62\xe9\x3b\xa6\xc9\xd3"
+  "\x9d\xf6\xc3\xd2\x99\xfd\xbc\x33\xd5\x97\xf8\xc0\xae\xaa\x2c\x47"
+  "\x7f\x3f\xfe\xf8\x35\x8e\x2e\x9c\x27\x8b\x38\xf7\x14\x1f\x2c\x64"
+  "\xfe\x42\x88\x0d\xca\xb6\xc6\xf6\x1a\x1f\x34\x88\xf1\x41\x6c\xf7"
+  "\xf8\x40\x8a\x0d\x0a\x01\xdf\x2f\xfb\xf4\x8c\x5e\xc4\x3b\xc6\x06"
+  "\x67\xfd\x8d\x0d\xa6\x39\x63\x83\x5c\xb7\xd8\xe0\x77\x6e\xb1\x81"
+  "\x80\xf7\x13\x2e\x78\xef\x16\x1b\x74\xe1\xbd\xbf\x62\x83\x9d\x5e"
+  "\xf7\x7f\x1a\x7c\x46\xdf\x5b\xbf\xf3\x9d\x39\x7d\xeb\x77\xfe\xcd"
+  "\xeb\xfe\x47\x83\x63\xf9\xbd\xc9\x7e\x67\x1f\xc7\xf2\xff\xbe\x63"
+  "\x70\xbc\x25\x50\xd9\xff\xad\x8f\x6b\x39\xec\xd2\x07\xde\x1f\xa9"
+  "\x68\x75\xf6\x47\x2a\x5a\xa5\xf8\x0a\x79\x57\x58\x33\x0b\xb8\x36"
+  "\x77\x05\x1c\x67\x09\x79\x6e\x85\xb0\xe7\x41\x90\xa5\xe1\x18\xee"
+  "\x01\x07\x31\x57\x45\x7c\x54\x8a\x3c\xe6\xda\x75\x5a\x8a\xb7\xa2"
+  "\x30\x16\x83\xd8\x0a\xe3\x2a\xa9\x0f\x92\xdf\xdc\xcb\xfc\xe1\xeb"
+  "\xb7\xc6\x62\x9f\xa5\x53\x5d\x59\xfe\xe3\xed\xaf\xfc\xbd\xb5\x6f"
+  "\xfd\x95\x8a\x49\xae\xf1\x96\xe9\x8f\xbe\xc5\x5b\x15\x7f\xed\xff"
+  "\xfe\x4a\x85\xd9\x35\xde\x32\x19\x45\x9c\xbc\xe6\x7f\xbc\x65\x5a"
+  "\xe6\x3d\xde\x32\xad\x72\x8d\xb7\x4c\x91\x2c\xae\x32\x95\xb2\x78"
+  "\xcb\x34\x9f\xa5\xef\x2a\x93\xa7\x3b\xe3\x2d\x96\xce\xe2\x2d\xd3"
+  "\x0e\x1f\xe3\x2d\x53\x1f\xe2\xad\xb8\x1f\x4e\xbc\x35\xfd\x22\x8f"
+  "\xb7\xf6\x7a\xdd\xff\x5c\xe6\x77\xca\xdd\xfc\x4e\xec\xa0\xdf\x41"
+  "\xae\x31\x99\xfb\xe6\x77\xfe\xaf\xb4\x57\xd9\x1b\x65\xb2\x47\xce"
+  "\x17\xe5\xee\x18\xb7\x35\x36\x60\xd9\x03\xd7\x17\xa5\xfe\x90\xe5"
+  "\xbe\x37\xa1\x6f\x72\x7f\x57\x3b\x18\x6b\x05\x2a\xfb\xff\x6b\xec"
+  "\x9b\xec\xf7\x6f\x0b\x3c\xd6\x7a\xcf\x70\xa4\x2b\xd6\x7a\xcf\xe0"
+  "\x1e\x6b\x61\x6c\x35\xab\x9d\xc5\x5c\xcf\x41\xac\x94\x93\x08\x71"
+  "\xd7\x6a\x42\x2c\x0d\xef\x12\x23\xc4\x5e\x39\x67\x20\xfe\x4a\x80"
+  "\xf8\xcb\xfe\x9a\x18\x7f\x99\xbf\x77\x8d\xbf\x2a\x97\x79\x8c\xbf"
+  "\xd4\xce\xf8\xcb\x0e\xb1\x55\xe7\x6b\x5b\x63\xf3\xcf\xc8\x62\xb1"
+  "\xa5\xdd\x63\xb1\x8e\xdc\x4a\x53\xc7\xf5\x5b\xe3\x3a\x21\x1e\xeb"
+  "\x29\x16\x13\x30\xe1\x21\x1e\xfb\xdf\x88\xc5\xde\x8d\xe9\x5b\x2c"
+  "\x66\x36\xbb\xc6\x62\xef\x4f\xf0\x2d\x16\x7b\xef\x76\xaf\x63\x5f"
+  "\x01\xc7\x62\xef\xcd\x74\x8d\xc5\xde\xd7\x8a\x98\x19\xe1\x7f\x2c"
+  "\xf6\xde\x39\xef\xb1\xd8\xfb\x0a\xd7\x58\xec\x3d\xf1\xdd\xd3\xf7"
+  "\xc7\xb3\x58\xec\xbd\x46\x96\x5e\xa9\x91\xa7\x3b\x63\x31\x96\xce"
+  "\x62\xb1\xf7\xa7\xf8\xf8\x6c\xac\xdc\x0e\x3e\xfd\xc2\xcf\xa7\xec"
+  "\xe9\xd9\x58\x7f\xcd\xa7\x9c\x76\x91\x3f\x1b\xfb\xa0\xf7\xf1\xaf"
+  "\xc1\x98\xc0\x03\xd7\xbc\x3f\xb3\x6f\x7e\xe9\xe0\xf8\xc1\x98\x20"
+  "\x50\xd9\x7f\xd0\xc7\xb1\xaf\x7f\x6c\x0f\x3c\x26\x38\x94\xec\x1c"
+  "\x7f\x39\x94\xec\xdf\xf8\x4b\xd5\xd7\xae\xfe\xff\x9f\x9e\xfd\xff"
+  "\xe0\xf8\x8b\x1f\x3e\xff\x60\x72\xdf\x7c\x7e\x55\xb9\xab\xcf\x3f"
+  "\x7c\xad\x6f\x3e\xff\xd0\xcd\xfd\x3f\xfe\x72\x28\xc2\xd5\xe7\x1f"
+  "\x56\x89\x38\xb9\xde\x7f\x9f\x7f\xe8\xb4\x77\x9f\x7f\xe8\x7b\x57"
+  "\x9f\x7f\xa8\x8a\xf9\xf6\xc3\x3a\xe6\xf3\x0f\x1d\x67\xe9\xff\x1c"
+  "\x27\x4f\x77\xfa\x7c\x96\xce\x7c\xfe\xe1\xf1\xfe\x3d\xef\x0a\xb9"
+  "\x48\x9f\x77\x69\x7e\x24\xcf\xbb\x8e\x94\x0d\xfa\x9d\x40\xfd\xce"
+  "\xe1\x88\xbe\xf9\x9d\x1a\x5d\xe0\x7e\xc7\xd2\xe4\xf4\x3b\x96\x26"
+  "\xff\xfc\x8e\x65\x81\xab\xdf\xa9\xf9\x72\xd0\xef\xf4\xd5\xef\x1c"
+  "\x69\xea\x9b\xdf\xb1\xb8\xad\x7f\x54\xe7\xe3\xfa\x47\x16\xaf\xeb"
+  "\x1f\x05\xee\x77\x2c\x6e\xeb\x1f\xd5\x89\xeb\x1f\xd5\x04\xb0\x6e"
+  "\x48\xdd\x62\xef\x7e\xa7\xce\x6d\xfd\xa3\xba\x08\xe6\x5f\xea\xc4"
+  "\xf5\x8f\xea\xc4\xf5\x8f\x6a\x0a\xe5\xe9\x4e\xbf\x53\x23\x5b\x37"
+  "\xa4\x6e\x70\xfd\xa3\x1f\xdc\x3c\xcc\x8f\xfa\xc0\x7f\x47\xab\x9d"
+  "\xfc\x77\xb4\xda\xfb\x3c\xcc\xa3\x77\xb9\xce\xc3\xfc\xe8\xc3\xc1"
+  "\x79\x98\x81\xf0\x5b\x5d\x1f\xd7\x45\x3a\xaa\x72\xe5\xb7\x63\x6b"
+  "\x7d\xe3\xb7\xa3\x9b\xfb\x9f\xdf\x8e\x16\xb8\xf2\xdb\xb1\x58\x11"
+  "\x1b\x01\xf0\xdb\xb1\xe9\xde\xf9\xed\xd8\x2c\x57\x7e\x3b\xa6\x63"
+  "\x3c\x76\x2c\x85\xf1\xdb\xb1\x49\x2c\xfd\xa3\x42\x79\xba\x93\xdf"
+  "\x3e\x92\xf1\xdb\xb1\x4c\xff\x9e\x6b\x06\x14\x57\x0f\xc0\x73\xcd"
+  "\xfe\x8a\xab\x2f\xf6\xe7\x9a\xff\xb6\x0f\x8e\xa3\x05\x12\x53\x1f"
+  "\x2b\xe8\x5b\x4c\x5d\x9f\x1c\xb8\x4f\xf9\x34\xda\xe9\x53\x3e\x8d"
+  "\xf6\xf6\x7c\x27\x07\x70\x67\x84\x98\x78\xf3\x19\xa2\x7c\x0e\x9f"
+  "\xef\x1c\xad\x21\xb9\xf8\x7c\x27\x51\x7a\xbe\x53\x24\xc6\xd9\xff"
+  "\xa9\x71\x8d\xb3\x3f\x99\xe5\x29\xce\xc6\xf8\xda\x01\xb1\xb3\xdd"
+  "\xfd\xb9\xce\xa3\x9e\x7d\x51\x87\xba\xd2\x74\xee\xb5\xad\x71\xfe"
+  "\xfa\xa2\x57\xd6\x31\x5f\xf4\xf2\x0f\xde\x17\x7d\x3c\xad\x6f\xbe"
+  "\xe8\x3f\x05\xae\xbe\xe8\xf8\x50\xdf\x7c\xd1\xa7\x97\xf7\xbf\x2f"
+  "\xfa\x74\x9c\xab\x2f\xfa\xd4\xc6\xea\x54\x1f\xc0\xde\x92\x9f\x7e"
+  "\xe8\xdd\x17\x7d\xfa\x89\xab\x2f\xfa\x74\x07\xf3\x39\xc7\x95\xcc"
+  "\x17\x7d\x6a\x66\xe9\xf5\x36\x79\xba\xd3\x17\xb1\x74\xe6\x8b\x8e"
+  "\x6b\xfc\x1b\xe3\xb9\xf4\x22\x1d\xe3\x09\xfa\x91\x8c\xf1\x7c\x96"
+  "\x1d\x38\x27\x5a\x67\x56\x77\xbd\xbf\x61\x9d\xd9\x6d\x9c\x61\x35"
+  "\xc4\xdb\xcd\xec\x39\x77\xd7\x38\x83\xf5\x33\x91\xff\x3e\x7f\xcf"
+  "\x95\xff\xfe\x9f\x57\xfe\xeb\xe9\x59\x36\x8e\x2b\x38\x80\x1b\x71"
+  "\x8f\xcc\x80\x9f\x65\xaf\xfe\xa1\x73\xde\xf1\x3e\xae\xaf\xfc\xb9"
+  "\xd1\x95\xf3\xac\xe7\x7c\xe3\x3c\xeb\x30\xaf\x9c\x17\xf0\x7b\x1c"
+  "\x56\xad\x2b\xe7\x59\x1b\x44\x7c\x0c\xf5\x9f\xf3\xac\x07\xbd\x73"
+  "\x9e\xb5\xc6\x95\xf3\xac\xa5\x8c\xdb\xac\xed\x8c\xf3\xac\xe5\x2c"
+  "\xfd\xff\x29\xe5\xe9\x4e\xce\x63\xe9\x8c\xf3\xbe\x50\xf6\xc4\x79"
+  "\xd4\x98\x65\xca\xe7\xf8\x9d\x70\x98\xa0\x8e\x57\x01\x36\xcc\xf0"
+  "\xbd\x0a\x74\x3c\x12\xbe\xd7\x79\xb3\x3f\x9b\x3a\xcb\xc4\x67\x40"
+  "\x9d\x39\xa2\xb0\xd8\xbe\x35\x9b\x47\xd9\xe1\xbe\x5f\x88\xef\xac"
+  "\x65\x99\x42\xec\x97\x46\xf2\x34\x8e\x80\x5e\x4c\xc2\xfe\x99\x90"
+  "\x1f\xdf\x0f\xd2\xad\x26\xc1\x67\x14\x5f\x94\x49\xf9\xa0\xbe\xc1"
+  "\x27\x14\x5f\x2c\xc0\x32\xa0\xae\x3b\xad\x8a\x2f\x34\x5e\xeb\x0a"
+  "\x65\x45\xbd\x31\x86\x6c\xb4\xd3\xaf\xcc\x89\xcd\xa4\x41\xf1\xc5"
+  "\xb9\x90\xa6\x4b\x23\x69\x5a\x34\xc1\x58\x6e\xe7\x28\x9b\x12\xcb"
+  "\x34\x27\x76\xe0\xb9\xe3\x78\xce\x01\x75\x4c\x5d\x46\xb8\xbc\xe6"
+  "\x4b\x83\x80\x27\x86\xa6\xb5\xd2\xc6\xe5\x76\xa8\x33\x60\xb3\x72"
+  "\x4c\xbd\xf2\x9d\x97\x21\xcd\x41\xb4\xb8\x9f\x29\x96\x01\xf1\x2c"
+  "\xd6\xc7\x51\x0c\xf9\x3d\xd5\x21\xeb\x6d\x32\x7e\xe8\x0d\xd4\xea"
+  "\x1f\x6e\x4e\xcc\xf1\x26\xc7\x90\xf4\x31\xc4\x7c\x23\xc8\x4e\x47"
+  "\x38\x4f\xe7\xfd\xbc\x4f\x4f\xef\xbf\x07\xe1\x1e\xc9\x69\x2f\x11"
+  "\x6e\x0b\x7f\x69\xd0\x07\x1b\x84\x3d\x8a\x6d\x6d\x9b\xfe\x3b\xce"
+  "\xaa\xf8\x4d\x2b\xca\x1c\xf7\xb5\xc4\xfd\xb5\x01\x37\x04\xd2\xa7"
+  "\xbe\x97\x42\x88\xbb\x2e\x56\xc4\x2e\x5b\xa0\x4b\x8e\x5f\xb6\x78"
+  "\xf9\xaa\x64\xdd\xf5\xb1\xc3\xc9\xdc\xe5\xcb\x75\xcb\x16\x24\xae"
+  "\xd5\xc9\xcf\xfc\x4a\x17\x1b\xbf\x72\xc1\xc2\x84\xc5\x13\x96\x2d"
+  "\x4a\x1a\x0e\x75\x22\xb2\x7a\x84\x62\x5d\xf8\x4d\xff\x8d\x2c\x7e"
+  "\x9e\x90\x17\x46\x12\x25\xd6\x0b\xee\xb7\x43\xda\xf7\x34\xef\x45"
+  "\xda\xca\x41\x9e\x34\xe0\xc7\x2d\xa9\x97\x42\xde\x13\xa6\x12\xa8"
+  "\x57\x31\xd4\x1b\xea\x88\x75\xae\x97\xea\x2c\x61\x22\x0d\x31\x91"
+  "\xda\x0c\x18\xfc\xef\xb9\x90\xf6\x4b\xef\xa5\x34\x1a\xdb\xd7\x0a"
+  "\x76\xa2\x38\xa9\x68\xb8\x4f\xf0\x65\xb9\x59\xa6\xb6\x4d\x0d\xa1"
+  "\x12\xc6\xf0\x5a\x9a\x97\x65\x68\x43\x3b\xa1\x71\x77\x30\x9b\x6a"
+  "\x68\x9a\xa7\x57\x10\xb6\xef\x6a\x43\x84\x73\xdf\xd5\x06\x61\xac"
+  "\x1a\xea\xd1\x04\xe9\xd1\x56\x85\x76\x2a\xa6\xe3\x7e\xc1\xb8\x7f"
+  "\x37\xd6\x19\xda\x05\xbe\x94\x9a\x69\x86\x88\xfd\xec\x8f\xad\x7c"
+  "\x76\xfb\x1c\x8b\xf2\x2c\x89\xb2\xd3\x4e\xba\xf9\x63\x6b\x6d\x6b"
+  "\x2b\x09\x49\x4f\x5a\x44\x2f\xf9\xef\x23\x21\xf6\xf8\xc5\x25\x23"
+  "\xc1\x86\x36\xb7\xcf\xa1\x9b\xbf\x33\xcd\xbb\x81\x68\xa0\x6c\xf9"
+  "\xfe\xaf\x4a\xff\xf4\xdf\x20\xe8\x1f\xf5\x08\xf5\x11\xf5\xf8\xa5"
+  "\xf2\xbd\xe4\xee\x7a\xec\xc2\xdf\x1b\x3c\x39\x08\x58\xa0\xaa\xdd"
+  "\x24\xca\xc1\xe4\x88\xb6\xdb\x92\x16\x47\x26\x0a\xb2\xfb\x72\x1f"
+  "\x9f\xb7\xcb\xca\x1b\x77\x6b\xa9\x71\xb7\x12\x64\x56\x90\xb7\x9a"
+  "\xe8\x9e\x74\x68\x48\xee\x59\x12\x6e\xcb\xdd\x4d\xd4\x0a\x83\x02"
+  "\xe2\x11\x0e\xfc\x49\x38\x70\x46\xb8\x68\xef\x05\x28\xc7\x7f\x82"
+  "\xd4\x66\xaf\x24\xe4\xab\xa9\x64\x48\x31\x5c\xe7\x5f\x7b\xbe\x14"
+  "\xfc\x3f\xdd\xf4\x65\x44\x09\x5c\x8b\xfb\xfa\xfa\x79\x7d\x95\x57"
+  "\xbb\x73\xb6\xdb\xe0\xb9\xdd\x27\xcb\xf9\xbc\xdd\x31\xd0\xee\x02"
+  "\x68\x77\xa6\x87\x76\x1b\x58\xbb\x87\x36\xf7\x7f\xbb\x4f\x1a\x58"
+  "\xbb\x4f\x4e\x09\xac\xdd\x27\xcd\xbd\xb7\xbb\xc2\x8b\xbe\xbf\xda"
+  "\x01\xed\x06\x7d\x57\x80\xbe\x2b\x3c\xe8\xbb\x42\xd4\xf7\x65\x27"
+  "\xfa\xbf\xdd\x5f\xa5\xb0\x76\x7f\x15\x1e\x58\xbb\xbf\xf2\xca\x7f"
+  "\xb2\x76\x7b\xd1\x77\x63\x19\x9f\x57\x01\xfa\xae\x00\x7d\x57\x78"
+  "\xd0\x77\x85\xa8\xef\x11\x1f\xf5\x7f\xbb\x1b\xd9\xfa\x87\x9b\x1a"
+  "\xf5\x81\xb5\xbb\x71\x67\xef\xed\x36\x79\xd1\xf7\xd7\x85\xd0\x6e"
+  "\xd0\xb7\x09\xf4\x6d\xf2\xa0\x6f\x93\xa8\xef\x5b\x73\xfa\xbf\xdd"
+  "\x5f\xc7\xb1\x76\x7f\xad\x0b\xac\xdd\x5f\x7b\x9d\xff\x22\x6b\xb7"
+  "\x17\x7d\x9f\xda\xc6\xe7\x99\x40\xdf\x26\xd0\xb7\xc9\x83\xbe\x4d"
+  "\xa2\xbe\x1f\xbb\xbb\xff\xdb\x7d\x2a\x86\xb5\xfb\x94\x36\xb0\x76"
+  "\x9f\xf2\x3a\xff\x5d\xc6\x6b\x41\xc0\x5d\xdd\x74\x6e\x49\x99\x42"
+  "\x6e\x3a\x8b\xed\x6f\x52\x52\xf5\xee\xa0\xcb\xd2\x0d\x0a\xbb\x6a"
+  "\xb7\xea\x32\xe8\xcb\xbd\x92\xc1\xc7\x85\x58\xc9\x30\x68\x6b\x1c"
+  "\xcd\xdb\x5b\x8a\x9f\x3c\x94\x63\x07\xee\x77\xa8\x76\x2b\x3b\x8c"
+  "\x59\x05\xcf\x2d\x21\xba\x34\x1b\xd1\xd4\xa6\x5a\x49\x6a\x12\xb5"
+  "\xd5\x92\x2f\x88\xda\x4a\x38\x1c\x2f\x3b\xd2\x64\x22\x89\x2b\x28"
+  "\x3d\xa9\xf8\xe6\x34\xf6\x31\xf3\x4e\x92\x70\x88\x89\x0d\x14\xfc"
+  "\x47\x3e\x4f\x74\x50\x7e\x38\xca\x12\xca\x7e\x35\x64\x2e\x51\xec"
+  "\x5f\xd8\x4e\x50\x9e\x28\x5b\xe8\x8f\x86\x0b\x72\x6d\x25\xe4\xfe"
+  "\xc7\x98\x5c\x5f\x59\xe2\xaf\x5c\xbf\x61\xcf\xff\x8c\xbb\x75\x16"
+  "\x6b\x07\x81\xd8\x52\x83\xef\xdc\x43\x7a\x72\x6d\x52\x33\xf4\x45"
+  "\xbe\xd1\xd2\xdc\xdd\x1a\x1e\x7c\x96\x7f\xe5\x36\x79\x5d\xff\x5a"
+  "\x26\xef\x6c\x90\x77\x37\xac\x39\xe5\x7d\x3a\x19\xe4\x9d\x2d\xca"
+  "\xdb\x78\xd9\xf1\xa1\xcd\x5e\xe4\x9d\x0d\xf2\x2e\x00\x79\x67\xfa"
+  "\x2e\xef\xd3\x8f\xbb\xca\x7b\x77\xcc\xc0\xc8\xfb\xb4\xb8\xff\xe9"
+  "\xee\x52\x57\x79\x37\x35\x30\x79\x37\x65\x83\xbc\xf3\x41\xde\x06"
+  "\x3f\xcb\x35\xf8\xc0\xe3\x80\xef\xee\x3e\xcc\x29\xef\x33\x0d\x54"
+  "\x5d\x21\xe2\xbb\x02\xf0\x7d\xd9\x09\xcf\xf2\xae\x00\x7c\x57\x00"
+  "\xbe\x2b\xfc\xc0\xf7\x99\x1a\x37\x79\x0f\x10\xbe\xcf\x88\xe3\x7f"
+  "\x15\x6e\xf8\x3e\x33\x97\xc9\xfb\x74\x3b\xcd\xad\x00\x7c\x57\xf8"
+  "\x89\xef\x33\x36\x1f\xe4\x0d\xf8\xee\xee\x3b\x9d\xf2\xb6\xcd\x05"
+  "\x79\x8b\xf8\xae\x00\x7c\x8f\xf8\xc8\x8b\xbc\x01\xdf\x15\x80\xef"
+  "\x0a\x3f\xf0\x6d\xbb\xdd\x55\xde\x15\x03\x84\x6f\x5b\x90\x28\x6f"
+  "\x37\x7c\x7f\x7b\x80\xc9\xfb\xdb\x38\x90\x37\xe0\xbb\xc2\x4f\x7c"
+  "\xdb\x62\x7c\xf0\x5b\x80\xef\xee\x3e\xdb\x29\xef\xef\x0e\x50\xb5"
+  "\x49\xc4\xb7\x09\xf0\x7d\x6b\x8e\x67\x79\x9b\x00\xdf\x26\xc0\xb7"
+  "\xc9\x0f\x7c\x7f\xf7\x96\x9b\xbc\x07\x08\xdf\xdf\xb1\xf8\xcf\x68"
+  "\x72\xc3\xf7\x77\x93\x98\xbc\x6d\xf5\x34\xd7\x04\xf8\x36\xf9\x89"
+  "\xef\xef\xbc\x8e\x63\xc8\xe4\x0d\xf8\xee\x1e\x2b\x38\xe5\xdd\x32"
+  "\x09\xe4\x2d\xe2\xdb\x04\xf8\x7e\xec\x6e\x2f\xf2\x06\x7c\x9b\x00"
+  "\xdf\x26\x3f\xf0\xdd\x32\xda\x55\xde\xa6\x01\xc2\x77\xb3\xb8\xff"
+  "\xa5\xc9\x0d\xdf\xcd\x65\x4c\xde\xcd\x91\x20\x6f\xc0\xb7\xc9\x4f"
+  "\x7c\xb7\x44\x04\x12\x9f\xac\x2c\x22\x41\xae\x32\x6f\xdd\x7e\xfe"
+  "\x62\x94\xd6\xad\x17\x26\x46\x69\x9d\xef\x39\x46\x69\xd5\x32\x99"
+  "\xb7\xec\x0b\x2c\x46\x69\xf5\xfa\xfe\x43\x4f\x31\x4a\x77\x99\x9f"
+  "\x0d\x3b\x7f\x71\xca\xd9\xa1\x17\x26\x4e\xf9\xbe\xce\x73\x9c\xf2"
+  "\xbd\x91\xc9\xfc\xfb\xf0\xc0\xe2\x94\xb3\x5e\xd7\x3f\xe8\x29\x4e"
+  "\xe9\x2e\xf3\xb6\xfc\xf3\x17\xab\xb4\xad\xbd\x30\xb1\x4a\xdb\x34"
+  "\xcf\xb1\x4a\x1b\x61\x32\x3f\x5b\x16\x58\xac\xd2\x56\x18\x48\xac"
+  "\xd2\x5d\xe6\xe7\x94\xe7\x2f\x5e\x69\x3f\x7d\x61\xe2\x95\x76\x93"
+  "\xe7\x78\xa5\x5d\xec\xff\xb4\x6b\x03\x8b\x57\xce\xf9\xd0\xff\xe9"
+  "\x1e\xaf\x74\x97\x79\x47\xca\xf9\x8b\x59\x3a\x16\x5c\x98\x98\xa5"
+  "\x63\xbc\xe7\x98\xe5\x5c\x23\x93\xf9\x39\x63\x60\x31\x4b\x87\xd7"
+  "\xfd\x4f\x7a\x8a\x59\xba\xcb\xbc\xb3\xe9\xfc\xc5\x2d\x9d\xc7\x2e"
+  "\x4c\xdc\xd2\x59\xea\x39\x6e\xe9\x9c\xcf\x64\xde\x49\x02\x8b\x5b"
+  "\x3a\xdb\x03\x89\x5b\x50\xd6\x28\x73\x8c\x55\x98\xcc\xf9\x7d\x34"
+  "\x78\x97\xb5\x13\xe2\x11\x35\xc8\x5d\xdd\x44\xb8\x22\x94\x79\x3d"
+  "\x93\xb9\x23\x78\x6f\x29\xc8\x27\x0e\x65\x26\xb4\xe3\x1b\x6d\xb0"
+  "\xc3\xb8\x5b\x45\x39\x02\x6d\x09\x22\x27\x15\xf6\x43\xf6\x0c\x12"
+  "\xac\x4b\x4d\x87\xef\xfc\x5b\x98\x47\x97\xba\xe9\x33\x68\xe3\x10"
+  "\x7c\x46\x61\xcf\xcd\x8a\x70\xa8\xf7\x98\xe1\xdc\x30\x3a\x3a\x3d"
+  "\xa2\x13\x62\x09\xfa\x94\x36\xd4\xd2\xb4\x93\x58\xec\x87\x49\x6d"
+  "\xfd\x5e\xc2\x07\xef\x7d\x75\xa2\x9d\xe8\xe9\x37\xfa\xd0\xea\x64"
+  "\x2b\x71\x2c\xd2\xaa\x2c\x29\x55\x80\x8b\xbf\x91\xa8\x46\x7a\x96"
+  "\xfe\x57\xaf\xea\x54\x57\x12\x87\x7a\xaf\xc1\x91\x5b\x59\x65\x57"
+  "\xef\xb7\xbd\xb5\xda\xca\xa9\xda\x89\x3e\xa1\x81\xd2\xbc\x85\x44"
+  "\x99\x77\x82\x04\x6d\x59\x48\x54\x5b\x4e\x10\x4d\x75\x43\x3d\xa9"
+  "\x39\x55\x45\x6a\x9a\x3f\x21\x35\x67\xe1\xe8\x80\x83\x87\xc3\xf0"
+  "\x09\xa9\x6e\x22\x64\xd6\x69\x42\xd2\x1a\xa8\xed\xe7\xc7\x49\x68"
+  "\xb5\xbd\x9e\xe8\x9e\x20\xe4\x8c\xc2\x51\xa4\x8a\x21\xa1\xf4\xbf"
+  "\x5a\x42\x17\x69\x39\x38\xa7\xc4\x74\x8b\xdd\x46\xaa\x1b\xda\xf1"
+  "\xfc\x06\x38\xaf\x4c\x6b\x80\xf2\xf9\x2a\x5c\xcb\xd0\x56\x6d\x38"
+  "\x04\xed\x9b\x1c\x0e\x72\xd6\x4a\x31\x59\x5e\x07\x09\xdf\x02\x6a"
+  "\x46\xcc\x44\x51\x86\x99\x92\x0e\x7f\x31\xe3\x60\xeb\xbf\x3f\xa5"
+  "\x1d\x09\xf2\x1e\xc5\x3f\x15\xad\x99\xfd\xc9\xe7\x14\xe7\x83\xe1"
+  "\xf3\x99\xda\xd6\xc3\x04\x9f\x59\x47\xad\x25\x64\xa6\x83\x10\x94"
+  "\x09\x3e\x4b\x9e\x9d\x44\x42\x70\x9e\x1a\xff\x8d\x7e\xa4\xa5\xc1"
+  "\x46\x36\xda\xa1\xae\x67\xda\xbb\xea\x5a\x9b\x59\x4b\xe0\xdc\xa8"
+  "\xda\x38\x2b\x51\x25\x11\x0d\xca\x19\xe2\xa2\xa0\xd9\x8d\x64\x58"
+  "\x62\x2b\xa5\x28\x63\x94\x2d\xca\x19\xcb\x93\x64\x6f\x89\xb5\x91"
+  "\xb4\x76\xa2\xb1\xa4\xc2\x67\x0a\xb5\x59\xc8\x77\x04\xea\xb8\x93"
+  "\xaa\x27\x87\x03\x3e\xca\x10\x13\x56\x85\xdd\x0c\x38\x18\x49\x37"
+  "\xd9\x93\x8b\xa1\xbd\xf8\x6c\xdf\xbf\x36\xf3\xbe\x3c\xff\xe8\x16"
+  "\x13\xca\xf0\x9c\x2d\xe0\x99\x53\x18\x69\xf0\xee\x18\xc0\x73\x26"
+  "\xc3\xf3\xd0\x66\x1f\xf0\x6c\x74\xe2\x99\xbe\xd4\x85\x67\x4e\xb1"
+  "\xd1\x2b\x9e\x39\xf2\x89\x88\xe7\xd2\x8b\x12\xcf\x1c\x59\xd6\x23"
+  "\x9e\x39\x32\xb3\x07\x3c\x17\x48\xf1\x6e\xbf\xe0\x99\x23\x65\x03"
+  "\x88\xe7\xec\x80\xf0\xcc\x11\x83\x2b\x9e\x69\x3e\xc3\x33\x9d\x16"
+  "\x10\x9e\x39\x85\xd7\xf5\x8f\x7b\x8a\xb7\x9d\x78\xae\x60\xfc\xcc"
+  "\x29\xe7\x03\x9e\x81\x9f\x2b\x44\x7e\xbe\xec\x44\xef\x78\xae\x70"
+  "\xf2\x33\xc7\xc5\x3b\xf1\xac\x9c\xe5\x1d\xcf\x43\xde\x60\x78\xae"
+  "\xb8\x38\xf9\x99\x1b\x72\x7b\xcf\x78\x1e\x12\xe6\x1d\xcf\x15\x5a"
+  "\xa9\x2f\xd1\x3f\x78\x1e\x92\x3c\x70\x78\xae\x08\x8c\x9f\xb9\x21"
+  "\x73\x5c\xf0\xcc\x71\x31\x02\x9e\x73\xb8\xd0\xc0\xf0\xac\x8c\x0b"
+  "\xa4\x2f\x23\xc3\xb3\xc8\xcf\x97\x8e\xa7\xc1\x15\xc0\xcf\x15\x22"
+  "\x3f\x8f\xf8\xc8\x07\x3c\x3b\xf9\x99\x1b\x7a\x9b\x13\xcf\x97\x8e"
+  "\xf6\x8e\xe7\x4b\xd6\x8a\x78\xbe\x48\xf9\xf9\x12\x75\xcf\x78\x1e"
+  "\xda\xd4\x03\x9e\x0b\xa4\x7e\x5a\xff\xe0\xf9\x92\x69\x03\x88\xe7"
+  "\x00\xf9\xf9\x12\x9d\x2b\x9e\x87\x86\x33\x3c\x2b\x1b\x02\xc3\xf3"
+  "\xa5\x53\x02\xe9\x27\x3a\xf1\x6c\x12\xf9\x79\x98\x1d\xf0\x0c\xfc"
+  "\x6c\x12\xf9\xf9\xd6\x9c\xde\xf1\x6c\x92\xf1\x73\xd0\x30\x27\x9e"
+  "\x87\x9d\xf6\x8e\xe7\x61\xf7\x31\x3c\x9b\x2e\x52\x7e\x0e\xfa\xac"
+  "\x67\x3c\x07\xed\xf3\x8e\x67\x93\x56\xea\x03\xf7\x0f\x9e\x87\x85"
+  "\x0e\x1c\x9e\x4d\x01\xf2\x73\x90\xcd\x15\xcf\x41\x84\xe1\xf9\xd2"
+  "\xf2\xc0\xf0\x3c\xdc\xeb\xfe\xaf\x3d\xf5\xc1\x65\x78\x16\xf9\x59"
+  "\x55\x4d\x83\x4d\xc0\xcf\x26\x91\x9f\x1f\xbb\xdb\x07\x3c\xcb\xf8"
+  "\x79\xf8\x27\x4e\x3c\xab\xde\xf5\x8e\x67\xd5\x55\x22\x9e\x2f\x52"
+  "\x7e\xbe\xec\xad\x9e\xf1\x7c\x99\xb1\x07\x3c\x17\x48\xe3\x0b\xfd"
+  "\x83\xe7\xcb\x1a\x06\x10\xcf\x01\xf2\xf3\x65\x66\x57\x3c\x0f\xaf"
+  "\x63\x78\x1e\x9e\x19\x18\x9e\x55\xf5\xfd\x32\xbe\xc1\x85\x54\xe3"
+  "\xf8\x46\x07\x8e\x6f\x38\xe7\xfe\xc5\x85\xd4\x31\x3c\x77\x02\x9e"
+  "\x5f\x91\xe3\xf9\x53\xb7\xf1\x0d\x4e\xfd\x06\xdf\x85\xe7\x90\x6e"
+  "\x78\xe6\x01\xcf\x9d\x02\x9e\x83\x8f\x49\xe3\x1b\x96\xa6\x52\xc0"
+  "\xc9\x29\x62\x99\x03\x58\xce\x13\xb1\xfc\x29\x60\x19\x64\xc8\x83"
+  "\x8c\xab\x8f\xd7\x93\x28\x1b\x93\x65\x07\xc8\x98\x97\xe3\xb8\xa3"
+  "\x91\x43\xfc\x22\x6e\x25\x0c\xd7\x24\x02\x76\x57\x7c\x48\x6a\x56"
+  "\xc3\xb1\x0e\x8e\x54\x38\xc8\x87\xa4\xba\x11\xb0\x1b\x2f\xc7\x6e"
+  "\x9d\x88\xdd\xe0\xf8\x9e\xb1\x1b\x1c\x39\x60\x63\x19\x5c\x30\x1b"
+  "\xff\xfa\x34\x5a\x13\xf5\xc0\xe7\xd4\x92\x52\x2f\xe2\xf3\x14\x89"
+  "\xb2\x93\x10\xfa\x98\x7e\xa4\x2a\x9a\x68\xd6\x3b\x08\x97\xbb\x90"
+  "\x68\x72\xff\x03\xed\x96\xec\xf7\x04\x51\x1d\x6e\xdf\x4b\xaa\x9b"
+  "\xeb\x49\xf5\xd9\x43\xa4\x9a\x87\xe3\x14\x1c\x50\xd7\xa8\xc5\xf2"
+  "\x76\xdb\xc4\x76\x87\x2c\x80\xb2\xc6\x79\x6f\x77\x48\x84\xd0\xee"
+  "\x58\x68\x77\x87\xb3\xdd\x16\xb0\x03\xd0\xcf\x28\x5e\x1c\x0f\x89"
+  "\xb2\x91\x61\xcb\xed\x94\x76\x88\xf8\x47\xfd\x1c\x3e\xda\x4e\xa2"
+  "\x92\x40\x67\x8b\x00\xff\x0d\xdb\x49\xda\x06\xc0\x7f\x47\x3b\xe2"
+  "\xce\x66\x31\x9c\x03\xfc\x07\x6f\xa0\x20\xbf\x4e\xc4\xff\xa7\x88"
+  "\x7f\x75\x29\x2f\xe0\x5f\x3d\x37\x30\xfc\x87\xf8\x82\x7f\x1f\xc6"
+  "\x43\x46\x56\xe3\x78\x48\x07\x8e\x87\x38\xe7\x80\xf6\x86\x7f\x19"
+  "\x9f\x6b\x64\xf8\x1f\xd9\x03\xfe\x47\x48\xf8\x2f\xbd\xf0\xf8\x1f"
+  "\xd1\x0b\xfe\x47\xf4\x84\xff\x7e\x1e\xfb\x18\x31\x80\xf8\x1f\xd9"
+  "\x0b\xfe\x47\xfa\x82\xff\xec\xc0\xf0\x3f\xc2\x0d\xff\x1a\x11\xff"
+  "\x9a\x00\xf1\x3f\xd2\x07\xfc\xfb\x32\x7e\x72\x39\xe2\x1f\xf8\xbf"
+  "\x42\x29\x9b\x0b\xdc\x0b\xfe\xe5\xe3\x27\x3f\x91\xe1\xff\xf2\x1e"
+  "\xf0\x1f\x7a\x4c\x1a\x3f\xb9\xf0\xf8\x0f\xed\x05\xff\xa1\x3d\xe0"
+  "\xbf\xbf\xc7\x4a\x42\x07\x10\xff\x97\xf7\x82\xff\xcb\x7d\xc0\x7f"
+  "\x45\x80\xfc\x1f\xea\x86\xff\x9f\x88\xf8\xff\x49\x80\xf8\xbf\xdc"
+  "\x17\xfc\xfb\x30\xde\xa2\xad\xc6\xf1\x96\x0e\x1c\x6f\x71\xce\x09"
+  "\xef\x0d\xff\x32\xfe\xbf\x42\x86\x7f\x6d\x0f\xf8\xbf\x52\xc2\xff"
+  "\x45\xc0\xff\x57\xf6\x82\xff\x2b\x7b\xc2\x7f\x3f\x8f\xad\x5c\x39"
+  "\x80\xf8\xd7\xf6\x82\x7f\xad\x2f\xf8\x0f\x90\xff\xaf\x74\xc3\xff"
+  "\x15\x22\xfe\xaf\x08\x10\xff\x5a\x1f\xf0\xef\xcb\xf8\xcc\xd5\x88"
+  "\x7f\xe0\x7f\x93\x52\xf6\x6e\x40\x2f\xf8\x97\x8f\xcf\x5c\x25\xc3"
+  "\xff\xd5\x3d\xe0\x7f\xd4\x31\x69\x7c\xe6\xc2\xe3\x7f\x54\x2f\xf8"
+  "\x1f\xd5\x03\xfe\xfb\x7b\x2c\x66\xd4\x00\xe2\xff\xea\x5e\xf0\x7f"
+  "\xb5\x0f\xf8\x37\x05\xc8\xff\xa3\xdc\xf0\x7f\x95\x88\xff\xab\x02"
+  "\xc4\xff\xd5\xbe\xe0\xdf\x87\xf1\x9c\x31\xc2\x78\x4e\x07\x8e\xe7"
+  "\x38\xdf\x11\xe9\x0d\xff\x32\xfe\x0f\x93\xe1\x7f\x4c\x0f\xf8\x1f"
+  "\x2d\xe1\xff\x22\xe0\xff\xd1\xbd\xe0\x7f\x74\x4f\xf8\xef\xe7\xb1"
+  "\x9b\xd1\x03\x88\xff\x31\xbd\xe0\x7f\x8c\x2f\xf8\x0f\x90\xff\x47"
+  "\xbb\xe1\x3f\x4c\xc4\x7f\x58\x80\xf8\x1f\xd3\x4f\xe3\x3f\xba\x64"
+  "\x1c\xff\xe1\x55\xbb\x95\x9d\x85\xe9\x11\xbc\xb1\x92\x84\x28\x74"
+  "\xc4\xae\xda\x63\xb6\x24\xb7\x92\xd9\xdf\x83\x4e\x92\xbe\x27\x4f"
+  "\x7c\xaf\xc1\xbd\x2c\x6d\x14\xfa\xff\x2e\xef\x88\xc2\x61\x37\x4e"
+  "\x0e\xdf\x92\x48\x94\x8e\xe0\xbd\xaf\x62\x9a\xe5\x64\x3b\xc1\x36"
+  "\x6f\x44\x19\x9c\x72\xca\x00\xc7\xe0\xe8\xb7\x7a\x4d\x71\x06\xe4"
+  "\xe9\xb0\x92\x06\xc0\x4b\x75\x83\x15\x64\xbf\x4e\xc0\x16\xea\x02"
+  "\xea\x13\x5a\x72\x86\x28\xed\xff\xd5\x8e\x02\x1d\x87\xaa\xd7\x10"
+  "\x45\x58\x03\xe5\x51\x97\xa8\x23\xd4\xab\x6e\x1d\xa5\x90\x6f\x59"
+  "\x2d\xe0\xdb\xfe\x5f\xfd\xa8\x62\xc8\xd7\xff\xe3\x32\x3a\xe1\xf9"
+  "\x07\x7c\x82\x3d\x82\x2c\x73\xae\x09\x50\x4f\x3a\x1f\xde\x7f\xf1"
+  "\x65\x9c\x62\x6c\x18\x8e\x53\x80\x9e\x32\x7d\xd4\x53\xb6\xcb\x3b"
+  "\xad\xfd\xae\xa7\x6b\xf7\xf9\xa6\xa7\xb1\x97\xbb\xe9\xa9\x9f\xc7"
+  "\x0f\xae\xb5\x32\x3d\x5d\x5b\xce\xf4\xa4\xb3\x07\xa6\xa7\xb1\x01"
+  "\xcd\xff\xed\xde\x9f\xbe\xee\x00\xf6\xa7\x79\xe8\x4f\xfb\xa6\xa7"
+  "\x8a\x20\x97\x77\x70\xfb\x5d\x4f\xd7\xc5\xfa\xa6\xa7\xeb\xde\x75"
+  "\xd5\x53\x7f\xf7\x73\xaf\xcb\x66\x7a\xba\x6e\x3e\xd3\xd3\xd8\xb2"
+  "\xc0\xf4\x74\x9d\x0f\xef\x7f\xf8\xd2\xef\xbb\x3e\x01\xfb\x7d\xa0"
+  "\x27\x1f\xed\xa9\x22\xdb\xe5\x9d\xe1\x7e\xd7\xd3\xf5\x2a\xdf\xf4"
+  "\x74\xfd\x62\x37\x3d\xf5\x73\x7f\xec\xfa\x70\xa6\xa7\xeb\x95\x4c"
+  "\x4f\xe3\x66\x06\xa6\xa7\xeb\x53\xfa\xa7\x7f\xf2\xb3\x50\xec\x9f"
+  "\xf0\xd0\x3f\xf1\x4d\x4f\xa6\x20\x97\x77\x9c\xfb\x5d\x4f\x3f\x2d"
+  "\xf7\x4d\x4f\x3f\x53\xbb\xea\xa9\xbf\xfb\x0d\x3f\x65\xfb\x01\x73"
+  "\x3f\xdd\xc1\xf4\x74\x7d\x6b\x60\x7a\xfa\x99\xae\x7f\xe2\x68\xfd"
+  "\x3e\x8c\xa3\x41\x4f\x3e\xda\x93\x29\xdb\xe5\x9d\xec\x7e\xd7\x93"
+  "\x7e\xbe\x6f\x7a\xd2\xef\x72\xd3\x53\x3f\xc7\xb7\x7a\x03\xd3\x93"
+  "\x7e\x2e\xd3\xd3\xcf\x0a\x03\xd3\x93\xde\x97\xf9\x9f\x1e\xdf\xc3"
+  "\xea\x1e\xf3\xdd\x18\x77\x71\xc5\x7c\x37\x06\xf9\xa6\xab\x1b\x17"
+  "\x9c\xdf\x98\xef\xc6\xf1\x4c\x57\x37\x12\xa6\xab\x1b\x22\x03\xd3"
+  "\xd5\x8d\x5e\xd7\x7f\xec\xed\xfd\xad\xee\x71\xdf\xf8\xd0\x8b\x2b"
+  "\xee\xfb\xb9\x8f\xfc\x37\x5e\x7d\x7e\xe3\xbe\x9f\x8b\xfc\xf7\x73"
+  "\x91\xff\x6e\x0c\x90\xff\xc6\xfb\xc0\x7f\x9e\xdf\xfb\xea\x1e\xfb"
+  "\x4d\x30\x5f\x5c\xb1\xdf\x84\x18\xdf\x74\x35\x61\xcf\xf9\x8d\xfd"
+  "\x26\x64\x32\x5d\x4d\x88\x66\xba\x1a\x5f\x1a\x98\xae\x26\x54\x07"
+  "\xfa\xbe\x58\xf7\xf8\x6f\xe2\x45\x16\xff\x4d\xf4\x31\xfe\x9b\x78"
+  "\x9e\xe3\xbf\x89\x62\xfc\x37\x51\x8c\xff\x6e\x0a\x30\xfe\x9b\x18"
+  "\x50\xfc\xe7\xaa\x2b\x29\x06\xbc\x59\x7b\x71\xc5\x80\xe1\x26\xdf"
+  "\x74\x75\xf3\x88\xf3\x1b\x03\x86\x1f\x67\xba\x0a\xdf\xc9\x74\x35"
+  "\xb1\x3d\x30\x5d\xdd\xec\x75\xff\xdb\xde\xde\x4f\xeb\x1e\x07\xde"
+  "\x72\xe0\xe2\x8a\x03\x6f\xf1\xb1\xff\x7b\xcb\xbb\xe7\x37\x0e\xbc"
+  "\x45\xec\xff\xde\x22\xf6\x7f\x6f\x0e\xb0\xff\x7b\x8b\x0f\xfd\x5f"
+  "\x5f\xc6\xfd\x26\x8f\xc3\x18\xd0\x61\xdc\xad\x0c\x01\xf9\x87\xa4"
+  "\x10\xae\x23\x0c\xf4\xa5\x02\x7d\xa5\xeb\x48\xa7\x11\xf4\x65\xb3"
+  "\x93\xd9\x4f\x7f\x4e\x6b\x9b\x1c\xa4\x03\x74\x75\x0e\xe2\x40\x8b"
+  "\xad\x11\xdf\xd1\xfb\xf5\x09\x6e\xd2\xbb\x8f\x3d\xad\x21\xa8\x2f"
+  "\x94\xbf\x43\x35\x39\x9c\x82\xbe\x04\xfd\xa9\x2a\xab\xec\xc6\xbd"
+  "\x86\x59\xa7\x3f\xa7\xcb\xad\x94\xd6\xc4\xb5\xe3\xda\x91\x11\x35"
+  "\x71\xf5\x24\xaa\x81\x0c\xd3\x3d\x88\x7a\x99\xb4\x0c\xd3\x2d\xb6"
+  "\x7a\x82\xeb\x7e\x0a\x63\xe0\x9f\xeb\x43\xed\x1f\xeb\x55\xb8\x7e"
+  "\x13\xbe\x57\x28\xad\xd1\x64\x39\x55\x20\xe8\xdf\x7d\x4c\x55\xd0"
+  "\xff\xc7\x7a\xcd\x2b\xf8\x7e\x62\xbf\xc7\x82\x93\x84\xf1\x3f\xfe"
+  "\x73\xed\x28\xa9\x8e\xcb\x13\x28\x85\x3a\x8e\xac\x6d\xb5\x11\xac"
+  "\x67\x6d\xab\x99\xa4\x25\x13\x4d\x6d\x47\x23\x49\x6d\xa5\xb6\x5a"
+  "\xc3\xd7\x24\xea\x7b\x7c\x2e\x80\x78\x9a\xb4\x8b\xe9\xfb\x17\x56"
+  "\xfe\x73\xfd\x28\x28\x6f\x47\x2d\x68\x2e\x24\x1d\x64\x6d\x27\x9c"
+  "\xf0\xbe\x26\x47\x82\x40\x5e\x71\x16\xc3\x09\x42\x83\xff\x0f\xee"
+  "\xf1\x1f\x94\x67\x1c\x9c\x9f\xda\xf5\xbc\x21\xf8\xff\x38\x4c\x43"
+  "\xd9\xe2\x3c\x53\x4b\x92\x4d\xc8\x23\x9d\x67\xba\x33\x10\x4b\x4a"
+  "\x07\xa9\xb5\x13\x02\xf7\x33\x1e\x89\xae\x07\x7c\xfd\x22\x40\xde"
+  "\x9e\x1c\xde\x3f\xe3\x95\xbf\xcc\xc4\xb8\x15\xf0\x95\xc9\xea\x38"
+  "\xb4\xd9\x07\x7c\x65\x3b\xf1\xf5\xcb\xd1\x7d\xc3\xd7\xad\x35\xfd"
+  "\x8c\xaf\x7e\x8e\x5f\x6f\x2d\xe8\x1b\xbe\x7e\x79\x39\xc3\xd7\xad"
+  "\x11\x0c\x5f\xbf\x54\x39\xf1\x35\xb4\xf9\xfc\xe1\x6b\x72\x13\xc3"
+  "\xd7\xe4\x1d\x81\xe1\xeb\x97\xf9\xfd\x33\xce\x7a\x5b\x03\xc6\xda"
+  "\x0e\x63\x85\xc8\x5f\x97\x9d\xe8\x1d\x5f\x15\x32\xfe\xba\x6d\x63"
+  "\xdf\xf0\x75\xdb\x84\xfe\xc5\x57\x7f\xc7\xdc\x53\xda\xfb\x86\xaf"
+  "\xdb\x56\x31\x7c\x4d\x29\x65\xf8\xba\x2d\xc1\x89\xaf\xcb\x4e\x9c"
+  "\x3f\x7c\x4d\x99\xc9\xf0\x35\x45\x15\x18\xbe\x6e\x0b\x68\xfd\xab"
+  "\xee\xfd\x83\xa9\xd3\xb0\x7f\x00\xf8\x12\xf9\x6b\xc4\x47\x3e\xe0"
+  "\x4b\xc6\x5f\xbf\xfe\xac\x6f\xf8\xfa\x75\x6e\x3f\xe3\xab\x9f\xfb"
+  "\x09\xbf\x8e\xee\x1b\xbe\x7e\x7d\x8c\xe1\xeb\xd7\x84\xe1\xeb\xd7"
+  "\xd5\x4e\x7c\x8d\xf8\xe8\xfc\xe1\xeb\x57\x3b\x18\xbe\x7e\x95\x10"
+  "\x18\xbe\xa6\x7a\x5f\xff\xd9\xaf\x71\xed\x3b\xca\xb0\x4f\xe3\x30"
+  "\x9a\x44\xfe\xba\x35\xa7\x77\x7c\x99\x64\xfc\x75\xc7\xed\x7d\xc3"
+  "\xd7\xed\xa7\xfb\x17\x5f\xfd\xdd\xb7\xb9\xdd\xd4\x37\x7c\xdd\x31"
+  "\x99\xe1\xeb\xf6\x18\x86\xaf\x3b\xc6\x3b\xf1\x75\x6b\xce\xf9\xc3"
+  "\xd7\xed\x2a\x86\xaf\xa9\xd5\x81\xe1\xeb\x0e\x5f\xd6\x7f\xf5\x61"
+  "\x3c\xfe\x2e\x25\xf6\xc3\x00\x5f\x22\x7f\x3d\x76\xb7\x0f\xf8\x92"
+  "\xf1\x57\x44\x51\xdf\xf0\x15\x31\xab\x9f\xf1\xd5\xcf\xfd\xb1\x08"
+  "\x6d\xdf\xf0\x15\xf1\x7b\x86\xaf\x3b\xcd\x0c\x5f\x11\x46\x27\xbe"
+  "\x1e\xbb\xfb\xfc\xe1\xeb\xce\x04\x86\xaf\x3b\xc7\x07\x86\xaf\xbb"
+  "\x7c\x59\xff\xd4\xc7\xe7\x08\xf7\xc4\xf5\xad\x0f\x79\x8f\xa2\x6f"
+  "\x18\xbb\xfb\xaf\x17\x77\x1f\xf2\xee\x0d\x7d\xc3\xd8\xdd\xe7\x18"
+  "\xc6\xee\x1e\xc7\x30\x76\xb7\x6d\x60\xfa\x90\x77\xd5\x31\x8c\xdd"
+  "\x95\x1f\x18\xc6\xee\xe9\xc7\xe7\x1f\xd3\xab\xfb\xd6\x8f\x9c\xbe"
+  "\xb8\x6f\x18\x9b\x7e\xf9\xc5\xdd\x8f\x9c\x66\xed\x1b\xc6\xa6\x3f"
+  "\xce\x30\x36\x2d\x9b\x61\x6c\xfa\xdc\x81\xe9\x47\x4e\x9b\xc4\x30"
+  "\x76\x4f\x80\xcf\x6d\xa6\x07\xf4\xfe\x8b\xe7\xe7\x36\x91\xe1\x7d"
+  "\xeb\x4b\xde\x7b\xa8\x6f\x18\xbb\x77\xed\xc5\xdd\x97\xbc\x77\x5a"
+  "\xdf\x30\x76\xef\x7b\x0c\x63\xbf\x69\x62\x18\xbb\xd7\x34\x30\x7d"
+  "\xc9\xdf\x14\x30\x8c\xfd\x26\x3a\x30\x8c\x45\x4e\xed\xbf\xe7\x4d"
+  "\x33\xb6\xf5\xad\x3f\x39\x63\x42\xdf\x30\x76\xdf\x67\x17\x77\x7f"
+  "\xf2\xbe\xed\x7d\xc3\xd8\x8c\xeb\x19\xc6\xee\x9b\xc3\x30\x36\x23"
+  "\x6c\x60\xfa\x93\x91\x76\x86\xb1\xc8\x7d\x81\x61\x6c\x46\x69\xff"
+  "\x3d\x27\x9b\xd9\xde\xb7\x3e\xe5\xcc\xad\x7d\xc3\xd8\xcc\xbb\x2e"
+  "\xee\x3e\xe5\x4c\x55\xdf\x30\x36\x73\x33\xc3\xd8\xfd\xe5\x0c\x63"
+  "\x33\x0d\x03\xd3\xa7\xbc\x3f\x86\x61\xec\x7e\x5d\x60\x18\x9b\xa5"
+  "\xec\xbf\xe7\x7b\x51\xf3\xfb\xd6\xaf\x9c\xfd\x7d\xdf\x30\x36\xfb"
+  "\xb5\x8b\xbb\x5f\x39\x3b\xa9\x6f\x18\x9b\x7d\x9a\x61\x6c\xb6\x96"
+  "\x61\x6c\x76\xc3\xc0\xf4\x2b\x67\x1d\x60\x18\x9b\x15\xe0\x7a\x14"
+  "\x51\xdd\xd6\xbf\x8a\x4f\x5c\xbd\x20\x21\x3e\x56\x17\x9f\x98\xbc"
+  "\xe2\x69\xdd\xca\xf8\x75\x8b\x6f\xbf\x7e\xd5\x78\xdd\x8a\x14\xdd"
+  "\x8a\xf8\xc4\xdf\x89\x09\xb1\xc3\xc9\x83\x8b\x13\x16\xa4\x60\x0a"
+  "\xe4\xfe\x5d\xe2\xb2\xc5\x89\xc9\xba\x15\x8b\x9f\x5e\x15\xbf\x62"
+  "\x31\x7e\x5f\xa9\x5b\xb2\x7c\x05\x24\x2c\x5a\x1c\xbf\x7a\xb1\x6e"
+  "\xe1\xaa\x25\x4b\x16\xaf\x58\x39\x9c\xcc\x5a\x95\x90\x1c\x9f\x94"
+  "\xb0\x58\x37\x6d\xd6\x5d\x13\xe6\x4e\x7f\x68\xee\x9d\x77\xe2\xe6"
+  "\x64\xb2\xbd\xc9\xc2\xa8\xb1\xd2\x0c\x98\x53\x9e\xe4\x1e\x19\x51"
+  "\x0b\xbd\x7d\xdc\x1f\x77\x4b\x33\xd1\x6c\x5e\x41\x94\xd9\xcd\x24"
+  "\x28\xb7\x99\xa8\x74\x4b\x49\x04\xdd\x6c\x8f\x81\xf4\x50\x9a\x3b"
+  "\x29\x89\xe6\x65\x45\xc2\xe7\x4e\x9b\x7a\x34\xa6\x69\x68\x6e\x58"
+  "\x01\x9e\x03\xd9\x2a\x69\xee\x64\xed\x09\x2e\xba\xce\xa6\x1e\x13"
+  "\x91\xf6\x35\xe1\xe8\xf0\x39\x05\x6f\xf3\x36\xee\x3d\xec\xed\x40"
+  "\xdb\x09\xf7\xc0\x4e\x38\x0a\x09\xf7\xe0\x4c\x38\xe6\xc3\x11\x07"
+  "\x47\x3e\x1c\x05\x70\xec\x80\xc3\x04\xc7\x01\x38\xaa\xe1\x38\x0a"
+  "\xc7\x71\x38\x1a\x08\xf7\x50\x0c\x1c\x06\x38\x20\xef\x43\xdb\x59"
+  "\x39\x0f\x95\xc3\x61\x25\xdc\x5c\x3d\x1c\x50\xd6\xbc\x68\x38\x32"
+  "\x09\xf7\xf0\x38\xf8\x2c\x83\xc3\x0c\x47\x15\x1c\x4d\x90\xa6\x81"
+  "\xbc\x26\x76\xee\x61\x48\xfb\xad\x92\x40\x3d\x7b\x3f\x7e\x0b\xf9"
+  "\x7f\x3b\x1e\x8e\x39\x70\xc0\x3d\xa3\x43\xe1\x88\x75\xcb\xb7\x43"
+  "\xf6\xbd\xaa\x97\x32\x1b\x43\xd2\xaf\xb1\x0a\x7b\xe0\x71\x0f\xaa"
+  "\x1d\x19\x64\x88\x23\x77\x4c\x44\xd2\x8d\x44\x71\x8a\x7b\xe0\x13"
+  "\x4b\x26\xf2\xcc\xa4\x24\x61\x4f\x47\xf8\x8d\x32\x6b\xcb\x79\xa0"
+  "\xde\x4a\x5e\xc8\xc6\x3d\xcd\xfc\xc3\xdb\x03\xf5\xec\xfa\x07\xb5"
+  "\x56\x85\xde\x2c\xec\x01\x97\xf3\x5d\x39\x4d\x8b\x7e\x45\xd8\xfb"
+  "\x0d\x65\x88\x76\x90\xfd\x9d\x8a\x06\x7d\x53\x86\x36\x6f\x5e\x87"
+  "\xf5\x7a\xe0\xaf\x34\x83\x04\xc3\xf5\x3b\x29\xd4\xcd\xa6\xce\xc2"
+  "\x7d\x05\x95\xf8\xdb\x91\x3b\x3a\xe6\x9c\x7a\x7f\x29\x7e\x6f\x2f"
+  "\x32\xd4\x51\xe3\xfe\x2a\xec\x67\x9b\x53\x9f\x27\x27\xe0\xba\x73"
+  "\x6a\x73\x9c\x6e\x46\x08\x3d\x81\xd7\x66\x10\xce\xca\x3d\x38\x8d"
+  "\xd9\xea\x03\x3b\xcf\xa9\xb3\xe6\x38\x0a\xcc\xf9\x90\xae\x74\xe4"
+  "\x66\x45\xb2\xf2\x47\x03\x4f\xee\x4d\x82\x7c\xa5\x42\x7a\xa1\xa1"
+  "\x51\xfa\x0e\x9f\x85\x8e\xbc\x4a\x0d\x7e\xaa\xd3\x49\xab\xf0\x3b"
+  "\x23\x82\xb0\x4f\x0d\xd1\xcd\x20\xa4\x89\x7b\x68\xfa\xc4\x2a\xa2"
+  "\x30\xcf\xc0\x7a\x3f\xa4\x49\xab\xa2\xbc\x2e\x75\x08\xdc\xff\xa1"
+  "\x11\x5d\xf7\xbd\xca\x9c\x8d\xfb\xa7\xd2\x9c\xa8\xed\x25\xcf\x13"
+  "\x82\xd7\x62\xdd\x5e\x1a\x49\x94\x45\xcf\x93\x20\x6c\x63\x5b\xce"
+  "\x43\x53\xa5\x7d\xe8\xf0\x1a\x0e\xf2\xdf\x77\x5f\x1a\x95\x95\x3d"
+  "\xcc\x21\xb4\xe7\x81\x1d\x4c\xa6\x0f\x25\x58\x15\xd7\x0b\x7b\xe5"
+  "\xe9\xc6\x0a\xb2\xfc\xab\x78\x7e\x27\xea\x13\xcb\xa7\xb9\x95\x66"
+  "\xfc\x8d\xfb\xdc\x85\x00\x2a\x74\xa9\xe3\x4c\x4c\x46\xfb\xab\xb0"
+  "\x1c\xcc\x4f\xf3\xf6\xc0\xf7\x07\xe7\xd0\x5c\x41\xc6\x7a\x5d\x22"
+  "\x89\x80\xba\x7f\xe2\xd8\xdc\x9c\x0c\x65\x80\xdd\x35\xa7\x40\x7e"
+  "\xab\x20\xef\xdc\xbd\x31\x56\xee\xa1\x6a\x38\x97\xd2\xb5\xf7\x25"
+  "\x93\xb3\x02\xf2\x65\xb7\xe5\xcc\x25\x56\xc5\xed\x75\x82\x9e\x57"
+  "\xd3\xa3\xb8\xc7\x66\xcb\x6a\x6a\x8f\xb2\x7f\xce\x03\x57\x11\x38"
+  "\xaf\xb3\x92\x7b\xb6\x4b\x6d\x64\xba\xef\x2a\xe7\xaf\xf8\xdb\x36"
+  "\x4c\x28\x27\xd2\x53\x39\x56\x6e\xae\xe6\x49\xbb\x4e\xd1\x71\x96"
+  "\xd6\x6d\x79\x18\xe5\x48\x68\xc7\x6a\x5a\xbd\x31\x92\xb6\xe7\x7d"
+  "\x44\x48\x4d\xdc\x71\x02\x36\x1f\x16\xac\xa0\xb6\xa8\xb5\x24\x24"
+  "\x38\x29\x84\x1e\xaa\x3a\x4e\xd6\x47\xd2\x46\xdc\xf7\xb7\xb6\xb5"
+  "\x81\x6c\xf8\x84\xa8\xd2\x6a\x48\xe8\x86\x48\x6a\xab\x8e\x39\x4e"
+  "\x58\x7a\x0d\x49\xfb\x82\x28\xd7\x1f\xa0\xed\xb3\x81\xff\x8f\x1c"
+  "\xc7\xf4\x06\x82\x7b\x54\xa6\x35\x52\x7b\xea\xe3\x44\x85\xdf\x6b"
+  "\x0e\x60\xfa\x97\x24\xed\x34\x51\x46\xa5\xd8\x42\x8a\xe1\x9e\x78"
+  "\x7d\x09\xd4\x85\x3f\x4b\xf7\x6d\x39\x4b\xc8\xfa\x47\x88\x76\xc3"
+  "\x02\xa2\x89\x72\x10\x6a\xb1\xef\x82\x78\x90\x02\xf7\x1f\x24\x1b"
+  "\xe3\x49\x50\x94\x1d\xdf\x63\x3b\x46\x70\xdf\xef\x12\xc8\x0b\x6d"
+  "\x33\x63\xdb\xd6\x7f\x46\xb4\xb8\x0f\x3a\xbb\xe6\x5d\xf1\x9a\xcf"
+  "\x08\xca\xec\x9c\x7a\x52\x69\x7b\xee\x64\x1d\xb4\x3d\x14\x65\x00"
+  "\xf7\xa9\xe3\xf1\x3a\xb8\x7e\xcb\x0a\x41\x06\x8a\x27\xed\x44\xe5"
+  "\xc8\xdd\x1b\xf9\x64\x8a\x59\x28\xd7\xca\xcd\x9b\x53\xb2\x42\xa8"
+  "\x93\x4b\xde\x28\x3b\x6d\xb1\xa9\xf7\x02\xee\xe7\xa5\x44\xa5\xdc"
+  "\x49\xf1\x5a\xd0\x65\x66\x5b\xce\x3c\x93\x24\x6f\x49\x2f\x90\x67"
+  "\x07\xe8\x22\x73\x48\x12\x51\xc2\xf9\x7a\xab\x22\x62\x87\x13\x6b"
+  "\x0f\x4e\x03\x9d\x5f\x22\xe5\x15\xf3\xd8\xad\x8a\x3b\x5a\x65\x78"
+  "\x44\x7c\x75\xe5\x69\xcb\x79\x38\xcc\xaa\xb8\xd3\xce\xee\x31\xef"
+  "\x38\xe6\x11\xb9\x5f\xca\x3b\x84\x66\x7f\x93\xe2\x50\xef\xaf\xa3"
+  "\x1c\x6d\x07\x3c\xc6\xd1\x16\xad\x6a\xb6\x9d\xb6\xf3\xb9\x7b\x90"
+  "\xe7\x55\xb8\xaf\x2b\xcb\xff\xf0\x5b\x70\x3e\x49\xb7\x5a\xf8\x6e"
+  "\xc6\xfb\x50\x63\x56\x52\xd7\xb9\x0c\x32\x94\x16\x19\xcc\xe0\x3b"
+  "\x34\x51\x55\xb4\x1d\x6c\xdd\x9c\xb7\x02\x7d\xc7\x7e\x33\xda\x35"
+  "\xaf\xde\x9b\xd2\xfe\x92\x39\x09\xf9\x09\x6d\x84\x1a\xf7\xc4\xb0"
+  "\x6b\x1f\x9c\x8e\x76\xc3\xb8\xe6\xe1\x4c\x07\x94\x01\x75\xda\x00"
+  "\xe7\x86\x9e\xe0\x1e\x6e\xc7\xf7\x49\xe1\x77\xb9\xb0\xef\x25\xf7"
+  "\xb0\x83\xe1\xf7\x9b\x14\x97\xdf\x1c\xca\x0e\xec\x09\x38\x0b\xf9"
+  "\xe1\x24\xf7\xdb\xd1\x4e\x1b\x16\xe4\xc6\x31\x2e\xda\x93\xc4\x78"
+  "\x64\x08\x0f\xf9\x14\x27\x44\x7b\x3c\x37\xac\x79\x43\x5b\xce\x6f"
+  "\x01\xff\xba\xa9\x2e\x76\x92\xd3\xa8\xc5\x3d\x36\xa1\x2e\x43\xa0"
+  "\xcc\x55\xf0\x79\x29\x7c\xae\xfd\xa0\x0a\xf5\x2d\x94\x7b\x19\x7e"
+  "\x7f\xe9\x0a\x6a\x9b\x36\x9d\xe0\x7e\x9a\x60\x6f\xbf\xcd\xb7\x92"
+  "\xa7\x67\x62\x39\x9b\x71\x9f\x51\x48\xc3\x3c\x90\xbe\xdd\x4a\x56"
+  "\x88\xe5\x3f\x38\xa7\x15\xea\xea\x56\x7e\x0d\x2b\x9f\x95\x8b\xe5"
+  "\x49\x65\x17\xbd\x48\x9b\xc4\xb2\x9b\xa4\xb2\x73\x21\x4d\x2a\x7f"
+  "\xda\x32\xe9\x1e\xd1\x2a\x38\x7f\x40\xde\x86\x82\x17\x69\x2b\x96"
+  "\x01\xe7\xf4\x56\xb2\x29\x1c\xcf\x65\x43\x1a\x5e\x2b\xc3\xd5\x90"
+  "\x0f\x22\xa1\x8c\x03\x42\x19\x73\xac\x24\xd3\xe4\xc6\x71\x6a\x89"
+  "\xe3\xc4\xb2\x92\xa5\xb2\x9c\xe5\x48\x78\x6a\x13\xf1\x22\x94\xab"
+  "\xc2\x72\x21\x7f\x99\x95\x24\xab\xe4\x6d\x07\x99\x27\x88\xe7\xcc"
+  "\x56\xc5\x35\x76\x57\x3b\x78\x68\x07\xcd\xdb\x5f\x8f\x1c\x27\x62"
+  "\xf5\x13\xe4\x6b\xe9\x3c\xee\x41\x0a\xbc\x5e\x87\xb6\x24\x70\x7b"
+  "\xee\xde\x39\x6d\x39\x8f\x04\xb9\x71\xb9\x12\xf3\x39\x72\xe6\x0c"
+  "\x2d\xc2\x3d\x58\xaf\xa0\x8d\x90\x67\xbc\xcb\xbe\xa3\x1c\xb9\x03"
+  "\xd2\xba\xf6\x3f\xcd\x83\x3c\x56\x6e\x8e\xd7\xf5\x1d\x53\xaf\x25"
+  "\x9c\xa5\xd0\x8a\xb1\x35\x62\x6e\xaa\x25\xac\x95\x58\x0a\x79\xc2"
+  "\x17\x1b\x6c\x11\xa9\xd4\x0c\xf1\xd4\xbb\xb8\x9f\xb5\x7f\xfe\xfa"
+  "\x11\xb6\xff\x67\x07\xc4\x9c\x1b\x6e\x21\xe8\xa3\xcf\x70\x8f\x9e"
+  "\xb6\xd8\x9a\x05\x39\xc2\x77\x21\x1e\x78\x01\x62\x54\x8c\x53\xa1"
+  "\x6f\x10\x97\xcf\xb1\x58\x95\x87\xbc\xc5\x98\x8e\x71\x2c\x70\x68"
+  "\x89\xec\x1c\x2d\x36\x6c\x67\xb2\x7b\xf4\x35\xc1\x57\x60\x7d\xed"
+  "\xf7\x9a\xb1\xce\x7c\xa1\x61\x3b\xb6\x21\x2d\x85\xf2\x16\x7b\x9b"
+  "\x19\x79\x56\xb7\x1a\x63\xec\x47\xd3\xa3\x8a\x08\xe5\x8b\x0c\xdb"
+  "\xfd\x6b\xc3\xa3\xc2\xde\xe3\xd0\x8f\x38\x63\x1b\x6d\xd8\x8e\xfb"
+  "\x40\x6f\x49\x1d\x1a\x74\x4f\x21\x35\xb7\x8c\x31\x00\x5e\x1e\x2d"
+  "\x93\xf6\xd9\xf5\xb3\xdc\x32\xa9\xed\xc5\x62\xdb\x21\x4d\xe8\xb3"
+  "\x4d\x2c\x10\xf6\xff\xc6\xdf\xc7\xbd\xe9\x0b\x38\xa6\x1e\xaf\x85"
+  "\xb6\x47\x94\x48\x72\xb2\xdb\x70\xff\xf3\x11\xa7\xb8\xc7\x9e\x8e"
+  "\xda\x60\x26\xc2\x9a\xfe\xb9\x7b\xea\xfd\xab\xd7\x63\xc2\xf8\x57"
+  "\x2d\xf4\x61\xa2\xec\x95\x94\x71\xe2\x63\x2f\xcd\x16\xcb\xc3\x73"
+  "\x92\xae\x8a\xc5\xbe\x45\x00\xf7\xf0\x3a\xfe\x21\x6b\x97\xa6\x7b"
+  "\xbb\xe6\xdf\x17\x78\xbb\xe6\x87\x76\x6f\xd7\xfc\xa7\xfb\xb7\x5d"
+  "\xf3\xbd\xce\x7f\x96\xb5\x4b\xd7\xbd\x5d\x8f\x5f\xdb\x87\x76\x35"
+  "\x75\x6f\xd7\xe3\xf7\xf5\x6f\xbb\x1e\xf7\x3a\xff\x41\xd6\xae\x70"
+  "\x0f\xed\x3a\x17\x78\xbb\x1e\x3f\xd0\xbd\x5d\x4f\x5c\xdb\xbf\xed"
+  "\x7a\xc2\xeb\xfb\xbf\x5e\xf9\x30\xaf\x52\xc7\xf8\xf0\x89\x1a\xff"
+  "\xf9\xf0\x89\x82\xee\x7c\xf8\xa4\xc3\xc9\x87\x4f\x7e\x1d\x10\x1f"
+  "\xe6\x65\x89\xf1\xc6\x93\xbb\xba\xf1\xa1\x31\x2b\xc6\x33\x1f\x3e"
+  "\xb9\x55\xe0\xc3\xdc\xac\x18\xff\xda\xf0\xe4\xfc\x2e\x3e\x54\x67"
+  "\xc5\xb8\xf0\x61\x70\xa5\xae\x2d\xe7\xc9\xf2\xc0\xf8\xf0\xc9\xf2"
+  "\xee\x7c\xf8\x64\xa8\x2b\x1f\x3e\xd9\xe4\x1d\x87\x7b\xa3\x3d\xf1"
+  "\x61\x94\xfd\x5b\xca\xb0\xb1\x37\xda\xbf\xfa\xc4\x4c\xeb\x01\xf3"
+  "\xd6\x9e\xef\xb5\xc7\xbf\xfd\xe5\xb9\x18\xaf\xf3\x3f\xa0\x1f\x5b"
+  "\x00\x31\x88\x66\xe3\x1f\x09\x77\x72\x03\xe1\x6a\xc3\xea\xa1\x8f"
+  "\xd0\x4e\x6e\x4a\x02\x4c\x64\x90\xa9\xb5\x85\x4d\xa4\x36\xec\x24"
+  "\xa1\xc3\xbe\x29\xa0\xaf\x6f\x4d\x8a\x58\x81\xd8\x5c\x10\x6f\x49"
+  "\x6e\xf7\x13\x9b\x0b\x26\x49\xd8\xac\xb5\x03\x36\x57\x23\x1e\x17"
+  "\xbe\x64\x69\x3a\x25\x62\x73\x61\x56\x97\x7e\x32\x18\x3e\x3d\x62"
+  "\x13\x6c\xc2\x15\x9b\x7b\xea\x18\x36\x17\x3e\xd0\x1d\x9b\x7b\xea"
+  "\x3c\x63\x73\xe1\x04\x86\xcd\x3d\x75\x7e\xb6\xa1\xdd\x89\xcd\x3d"
+  "\x75\x2e\xd8\xfc\xe9\xd6\xa4\xb6\x9c\x85\x73\x02\xc3\xe6\xc2\x39"
+  "\x52\xdb\x8b\xc4\xb6\xc3\xbd\x76\xba\x62\x73\x61\xb6\x57\x1d\x66"
+  "\x7f\x6c\x05\x3e\x54\x9d\xe2\x16\x45\x3b\x20\xa6\xe5\x8d\x63\xa3"
+  "\xa1\x4f\xd6\x86\xfb\xc9\x53\x6e\x12\xa1\x6b\xf4\xaa\x36\xe8\x1b"
+  "\xb7\xb5\xc5\x05\xd1\xe1\xdf\x8c\xa5\x9d\x5a\x02\x75\x0f\xa1\x6d"
+  "\xfa\x60\x90\xd9\x38\xf8\x1c\x59\xb4\x9a\x84\xc2\xa1\x2d\x12\xe5"
+  "\x0a\xdf\xc3\xe9\x1a\xed\xf0\xbc\xd5\x64\x7c\x48\x2b\x09\x82\x3a"
+  "\x44\x87\xa4\x6b\x48\x88\x9d\x84\xe2\x77\x9a\xf1\xbe\x1d\xfa\x6e"
+  "\x4a\x1c\x17\xe5\xd5\x70\xbf\x94\x10\x4a\x57\xea\x09\xf4\xe3\x82"
+  "\x40\x07\xda\x12\x8e\xee\x74\xac\xd1\x73\x34\x78\xff\xa7\x74\x7d"
+  "\xb4\x50\x27\x7e\xdc\xd6\x9d\x80\xa1\x9d\x34\x2d\x0e\xef\x1b\x81"
+  "\xfb\x1a\xd3\x9f\x6e\x2d\xa7\x6d\xda\xe1\xb9\x67\xc9\xf8\x92\xd5"
+  "\x64\x5c\xf1\x6a\xa2\xa7\x9d\x7a\x1c\x67\x8c\x7e\xe2\x69\x0d\xea"
+  "\x3d\x9a\x72\x70\xaf\xd5\x70\x2f\xd0\xa5\x23\x17\xee\x65\x87\x7b"
+  "\x7d\x0b\xf7\x3a\x03\xf7\xca\x80\x7b\x65\xb0\x7b\xf9\x27\xf3\x45"
+  "\x07\x7a\x1a\xbf\x8e\xda\x38\x06\xd7\xd9\xfd\x2a\x24\xe5\xd2\x48"
+  "\x1c\xcb\x6e\x59\x1f\xe7\x27\xde\x63\xbd\xbe\xff\xb2\xe5\x6d\x12"
+  "\x46\x55\x61\xd9\xb3\xb3\x3e\xa7\xd8\xc7\xce\x7a\x9b\x8c\x47\x9b"
+  "\xab\x6d\x3f\x4d\xa8\x3a\x2c\xfb\xa0\xbe\xc9\xdf\x7b\x79\x9d\xff"
+  "\x9c\x93\x41\xeb\x3a\xc3\xa0\x5f\x68\xdc\xdf\xb8\x85\xa3\x29\x1d"
+  "\x61\x06\xeb\xe1\xa3\x1d\xe4\xc9\x14\x1c\x2f\xa7\x29\xba\x47\x49"
+  "\xd0\x09\xee\xa9\x69\x69\x9f\xe0\xd8\xe3\xe2\x50\xd7\xb1\xc7\xc5"
+  "\x70\x87\x25\xc7\x09\x17\xa7\x22\x5c\xfc\x36\x02\xf9\x5c\x8f\xa5"
+  "\xd5\x51\x6f\x8c\x21\xa9\x76\xfa\x15\xf4\x67\x4d\x79\xd0\x0f\x8e"
+  "\xba\x41\x61\x35\xaf\xc6\xb1\xb8\x25\xc7\x40\x7e\xdf\x80\x0f\x0a"
+  "\xc1\xef\x58\x5e\xd2\x0a\xf2\x93\x53\xdc\x92\xa3\x21\xad\x97\x46"
+  "\xda\x55\x95\x41\x76\xe8\xbf\x75\x6a\xcd\x49\xe7\x8c\xfb\xcd\x9d"
+  "\xd8\xa7\x5d\x88\x3c\xb0\xb8\x26\x44\x61\x80\xbe\xf6\xd8\x68\x4a"
+  "\xb5\x38\xbe\x1c\x5d\x08\x07\xea\x5e\xd0\xfb\x70\x5b\x39\xe2\x03"
+  "\xb1\x58\xc2\xd2\x35\x88\xc7\x2d\xa2\xcf\xb6\x0d\xb9\x31\x06\x6d"
+  "\xc0\x01\xd7\xa7\x7d\x49\xc2\x2c\xc7\x1d\x04\x30\x1d\xfd\xa4\x23"
+  "\x08\xed\x28\xda\xfc\xe8\x47\xe4\x64\x12\xe1\xd2\xbe\x23\x6a\xc0"
+  "\x90\x0a\xed\x81\x07\x7b\x88\x3a\x1e\xd2\x0e\x76\xcd\xa7\x7e\x4f"
+  "\x42\x90\x27\x70\x0d\x67\x0b\xf4\x18\xf9\x6f\xf5\xc1\xaf\x24\x92"
+  "\x50\xfb\xb7\x71\x23\x6d\xdf\xc6\xfd\xe4\x25\x9e\x84\x06\x27\x11"
+  "\x4d\x51\x22\x60\x77\x39\xd8\xc7\x19\xb0\x8f\x26\x66\x1f\x5d\x78"
+  "\xdd\x74\x22\x12\xdf\x0f\x12\x6c\x23\x57\xb4\x8d\x35\x80\xd7\xd5"
+  "\x4e\xdb\xb0\x2f\xd7\x73\x45\x1c\x25\x50\x47\x90\x7b\xac\xb2\x24"
+  "\xf5\x52\xe4\xfd\x18\x3a\x26\x7d\x0e\xf0\x2e\xb4\x95\xda\xdf\x01"
+  "\x5d\x0c\xbd\x81\xd3\x41\x9f\x3f\xe8\xf0\x9c\x46\xe2\xec\xd3\x3d"
+  "\x35\xbd\x63\xb4\xc1\xaa\x7b\x90\x7e\x7b\x82\x5b\x52\x0d\xe9\x41"
+  "\xba\x87\x7f\xa6\x01\x3d\x4e\x67\x7d\xc0\xa7\xa6\xe1\x78\x82\x95"
+  "\x5b\x82\xeb\x01\x09\xcf\x50\x8e\x08\xe3\xa7\x71\x4a\xc8\x4b\x1c"
+  "\x20\x73\xbb\x2a\x2b\x89\x57\xed\xaf\x37\x2f\xed\x10\x6c\xb3\x13"
+  "\x74\x70\x32\x81\xa0\x07\xe4\x80\x1b\xd4\xc0\x09\xc8\x19\x73\x04"
+  "\xce\xc8\xfe\x26\x6c\x83\x95\xf2\x51\xb1\x43\x28\xc8\x25\x08\xc7"
+  "\x90\x9e\x48\x22\x74\xe3\x69\x90\x51\x6b\x3d\xf2\x4b\x30\xbf\x86"
+  "\x71\xc8\x2b\x20\x1f\x75\x13\xd1\xd0\xbc\x31\x73\xde\x4e\xad\x1a"
+  "\xea\x00\x9c\x23\x8f\x84\xa4\x2b\x86\x81\xae\x82\x8d\x68\xe7\x60"
+  "\xf7\x21\xe9\x02\xaf\x09\xba\xb5\xaf\xd1\x8f\xed\x5c\xa3\xd7\xc1"
+  "\x31\x46\xe2\x1a\xdc\x37\xac\x08\x79\x26\x27\x36\x01\x79\xc6\x92"
+  "\x62\x25\x76\x90\x65\x30\xfa\xa5\x35\xfa\x30\x41\xa6\xbf\x03\x99"
+  "\x2e\x21\x41\x13\xdb\x89\x02\xea\xa5\x81\x3a\x93\x9a\xb8\x13\x04"
+  "\x65\xec\x00\x3b\x42\x39\x77\x22\x07\x01\xd6\x20\x4e\x49\x9a\x15"
+  "\xaf\x23\x07\xf5\xc7\x08\xae\x03\x95\x76\x8e\x7e\x81\xe3\xb7\x96"
+  "\x14\x3b\xd8\x5c\x25\xf2\x08\xc8\x6d\x49\xd9\xe1\x39\xed\xc4\x3b"
+  "\xa6\xe3\x73\x9d\x98\x8e\xcf\x75\x62\x3a\xde\x28\x3c\xff\x90\xe1"
+  "\xfa\x5c\x01\xe0\x5a\x25\xc7\x75\xdc\x6b\xe7\x15\xd7\xb3\xfd\xc7"
+  "\xf5\x4b\x67\x64\xb8\x4e\xbd\x30\xb8\x3e\x12\x2d\xe0\x7a\x48\xe7"
+  "\x68\x01\xaf\xdb\x2d\xf6\xbf\x11\x2b\x17\x9f\x22\xe1\xf6\xd0\x5f"
+  "\x10\xb7\x4b\xf7\x5d\xac\xb8\x3d\xd7\xa6\xd7\xc1\xd1\xef\xb8\x85"
+  "\x32\x7d\xc6\xed\x91\xe8\x0e\x22\xc9\x0f\xf1\x4b\x8d\x61\xd9\xba"
+  "\x34\x72\x27\xf0\xc4\xb4\x90\xf4\x31\xa4\x46\x90\xe1\x53\xd3\x74"
+  "\x0f\x53\xfe\x04\xb7\xf4\x7b\xc4\x53\x47\x06\xa5\xbc\x6a\x6f\x4a"
+  "\xda\x87\x44\x03\xf7\x30\x5b\xec\x6f\x91\x90\x24\x7c\x1e\x95\x15"
+  "\x49\xd5\x93\xb5\xc2\x33\x2b\x8e\x28\xf9\xdc\xb0\x02\x1c\xbb\xc2"
+  "\xb1\x45\x47\x6e\xa5\x99\xdf\x6c\x8f\xe1\xd5\x93\x92\xf0\x79\x16"
+  "\x55\x8f\x8e\x69\xcb\x79\x6a\x9a\xf4\xac\xc5\x63\x6c\xa2\xaa\x34"
+  "\x83\xbd\x28\x4f\x72\x09\x77\xc1\x27\x07\xf5\xf8\x0c\x3e\x87\xc0"
+  "\xa7\xb0\x6f\x9d\x7f\x7e\xee\x29\x71\xff\xe7\xca\x50\x91\x07\xd7"
+  "\x0a\x36\x78\x23\x51\x9f\x12\xbf\x43\x7d\x8e\x4a\xcf\x6e\x9c\xf9"
+  "\xbb\xe4\x91\x84\xf7\x06\x99\x28\xd9\xf3\x24\xf6\x5b\x56\xde\xd3"
+  "\xc2\x6f\xa2\xd4\x41\xfb\x0d\xf8\xdc\x17\xb0\xa4\x68\xa3\x71\x77"
+  "\x88\x9f\xb7\x23\x56\x71\x0c\x16\xe3\x3c\x91\x6b\x53\xd8\x7d\x13"
+  "\x66\x82\x1f\xae\x93\xdf\xd7\x93\x3c\xac\x5c\x82\xd7\x3d\x7d\xfc"
+  "\x93\x45\x82\xd7\xfd\x1f\xa7\xeb\x1d\xd4\xcf\xb2\xbc\xbe\xff\x49"
+  "\xc3\x0c\xa5\x51\xdb\x1d\x66\xbe\x33\x3a\xe4\xe0\x86\xd3\x7e\xc6"
+  "\x25\xcb\xbc\xf6\x7f\x1d\xaa\xbd\xf9\x51\x37\x8c\x21\x8e\x42\x03"
+  "\x3e\xbb\x52\x61\xac\x55\xab\xb7\x13\x8c\xb7\xde\x58\x6a\xe5\x3a"
+  "\x21\x66\x0c\x06\x7b\x9c\xdd\x5a\x49\xb7\x9c\x82\x18\x75\x4d\x74"
+  "\x48\xde\x52\x32\xd5\xfe\xad\x76\xf8\x73\xc0\x41\x1d\xc0\x07\x1d"
+  "\xdf\xc6\x85\xd4\x26\xb5\x13\xbe\xc8\x50\x6a\xb1\x57\x91\x12\xc8"
+  "\x87\xfc\x8b\xf5\x3d\xf7\x6d\x74\x70\x4e\x22\x3e\xbf\xf8\x9e\x98"
+  "\x17\xfe\x05\xf8\x37\xf1\x86\xa1\x1b\x81\x73\x80\x33\x04\x1e\x0e"
+  "\x80\x83\x3b\x9e\xb9\x31\x66\xd6\x7c\xda\x5e\x7b\xfc\x23\x92\x56"
+  "\x43\x34\x69\xab\x88\x1a\xcb\xb7\xd8\x6b\x18\x2f\x3f\x02\xbc\x0c"
+  "\xbf\x8b\x65\xbc\x2c\xcc\x2f\x70\xe3\x65\x8c\xbf\x6b\x1b\x1a\x49"
+  "\x70\x2b\xb9\x74\x76\x6b\x48\x7b\x6a\x2b\xe5\x31\x1e\xb7\xd8\x4f"
+  "\xe3\xbb\xc7\xc1\x12\x47\xbf\x0c\x71\x47\xe7\x72\xc6\xcf\x45\x22"
+  "\x3f\xbf\x7c\xa6\xef\xfc\xfc\x72\x06\xf0\x33\xc4\x7b\x2f\x21\x37"
+  "\x03\x2f\xef\x38\x69\xe3\xec\xc0\xc5\xfe\xe9\x76\xb9\xd7\xf9\x1f"
+  "\xb3\xc1\x7f\xa2\x4e\x11\x3b\x35\xdb\xed\x38\x1f\xe1\x2b\x47\xf0"
+  "\x2e\x2b\xfa\xc7\x0e\xf0\x8d\x6f\x2c\xad\xe7\x82\x53\x40\xb7\x49"
+  "\x95\xd4\xbe\x32\x3a\x84\x76\x46\xab\x1d\xc6\xbd\xf9\xf6\x4e\x6d"
+  "\x50\x67\x27\xe8\x17\xf8\x02\xfc\x95\xc6\xb6\x3e\x4e\x90\x09\x3f"
+  "\xda\x50\xca\x6f\x8a\xac\x02\xdf\x34\xa5\xf8\x0c\x99\x44\x73\x77"
+  "\x03\xa7\xee\x56\x75\xe6\xee\x56\x02\x2e\x83\xcf\x19\x51\xe7\xe7"
+  "\xcc\x7c\xee\x6e\x1d\x9f\x67\xb2\x3a\xd4\x7b\xf3\x6d\xea\xdd\x41"
+  "\xf0\x5b\xcb\xaf\x07\x1c\xac\x23\xc2\x33\x2d\xdd\x6c\xf4\xc3\x49"
+  "\x37\x7b\xc2\xc1\x4b\x19\xfe\xf9\xe2\x59\xd1\x80\x83\x7a\xc0\xc1"
+  "\x77\x72\x1c\xbc\x8b\xfb\xc9\x30\x2c\xcc\x63\x58\x00\xb9\x0b\x7d"
+  "\x99\x2e\x3f\xfd\xe0\x61\xcf\x78\x38\xee\x1b\x1e\x3a\xbe\x75\xc5"
+  "\x43\x61\x80\x78\x00\xff\xaa\x2d\x86\x7e\xd3\xb9\x6f\xf5\x5c\x21"
+  "\xe2\xe1\x98\x13\x0f\x6f\xfe\x3f\x1b\xd7\xe9\x37\x1e\x9e\x0e\xf5"
+  "\x0f\x0f\xbb\x63\xfa\x86\x87\xfb\x74\x32\x3c\x18\x00\x0f\x46\xc0"
+  "\x43\xa6\x13\x0f\xdf\x23\x1e\x4a\x65\x78\xc8\x86\xdf\x05\xdd\xf1"
+  "\xb0\xe2\xae\x81\xc5\xc3\xd0\xe6\x1f\x07\x1e\x56\x7a\xed\xff\x7a"
+  "\xc1\x43\x1f\xf9\xe1\xbe\x14\x27\x1e\x2a\x80\x1f\x2a\x80\x1f\x2a"
+  "\x64\xfc\x70\x1a\xf0\x50\x21\xe3\x87\x0a\xe0\x87\x0a\x0f\xfc\x90"
+  "\xfc\xc0\xc0\xe2\xe1\xb2\x13\x3f\x0e\x3c\xac\x9a\xe4\x1f\x1e\x2a"
+  "\xfa\xca\x0f\x75\x32\x3c\x00\x3f\x54\x00\x3f\x54\xc8\xf8\xe1\x33"
+  "\xc4\x83\x8c\x1f\x2a\x80\x1f\x2a\x3c\xf0\xc3\xea\x05\x03\x8b\x87"
+  "\x11\x1f\xfd\x38\xf0\xb0\xc6\xeb\xf8\xb7\x17\x3c\xf4\x91\x1f\x66"
+  "\xe8\x9d\x78\x30\x01\x3f\x98\x80\x1f\x4c\x32\x7e\x78\x17\xf0\x60"
+  "\x92\xf1\x83\x09\xf8\xc1\xe4\x81\x1f\x52\x9e\x1e\x58\x3c\xdc\x9a"
+  "\xf3\xe3\xc0\xc3\xda\xb9\xfe\xe1\xc1\xd4\x47\x7e\x98\x61\x90\xe1"
+  "\x01\xf8\xc1\x04\xfc\x60\x92\xf1\xc3\x46\xc4\x83\x8c\x1f\x4c\xc0"
+  "\x0f\x26\x0f\xfc\xb0\x2e\x7d\x60\xf1\xf0\xd8\xdd\x3f\x0e\x3c\xac"
+  "\x8f\xed\x0d\x0f\x12\x16\x10\x17\x88\x85\xce\xb4\x68\x82\xfd\x8c"
+  "\x37\x4e\x31\x3c\x20\x0e\x04\x4c\xb4\x44\x87\x38\x00\x0b\xf6\xf5"
+  "\x80\x85\x0e\x86\x05\x94\x05\xe2\x01\xfb\x15\xd8\x9f\x40\x4c\x38"
+  "\xa0\x4f\x61\x57\x43\x9f\x22\x5d\xa9\x45\x1c\x74\xa8\x7a\xe9\x57"
+  "\x74\x10\xa1\xef\x87\x7d\xbc\x33\xdc\x86\xcd\x9e\x70\xf0\xb2\x9f"
+  "\x63\x7c\x5d\xfd\x4b\x17\x1c\x1c\x74\xe2\xe0\x11\x2f\xfd\x8a\x87"
+  "\xbd\xe0\xc0\xea\x03\x0e\xce\x74\xef\x67\xf6\x15\x07\x1d\xcb\x45"
+  "\x1c\x60\x3f\x93\x17\xfb\x99\x0b\xa1\x9f\xa9\xf6\x17\x07\x1b\x13"
+  "\x02\xc3\x41\x45\x8c\x7f\x38\xb8\xaf\x0e\xe3\x04\x86\x83\x0a\xa3"
+  "\x5d\x0d\xb1\x82\x0b\x0e\x7a\x88\x17\x5c\x70\x90\xba\x75\x60\x71"
+  "\xe0\x16\x2f\xfc\xcf\xe2\x20\xcd\xeb\xfb\xbf\x3c\xe8\x1d\xf9\x1e"
+  "\xc7\xed\xf1\x3d\x93\x60\x1b\x1b\x37\xc2\xf7\x4d\xb6\x24\x92\x71"
+  "\xe8\x23\x1c\x6b\xa2\x43\x8c\x67\xc8\xd4\xcd\x89\x44\x69\x5f\x09"
+  "\xfa\x5f\x41\x94\x1d\x1c\x21\x1d\x2b\xe3\x42\xaa\x1b\x6c\x6c\x0c"
+  "\x09\xe7\xa3\x42\xfe\x4e\x23\x1b\x43\x72\xb4\x44\x07\x6f\x6e\x66"
+  "\x73\x60\xcd\x4f\xbc\x0a\xba\x35\x2c\xf3\xa4\xdb\x57\xfc\xe0\xfa"
+  "\x0e\x39\xd7\x9f\x76\xd5\xad\x9c\xe7\x0b\x33\x64\x63\x48\xb3\xbd"
+  "\x8c\x21\xf9\xa0\x53\x61\x6c\xff\x0c\xe3\xf9\xae\x31\xa4\x3e\x8e"
+  "\xf1\x77\x02\xc7\xbf\xcc\xb9\x72\x7c\x60\x3a\x4d\x8f\xec\x69\xdc"
+  "\x11\xed\x1b\xed\x5a\xb2\xe9\x2e\x1f\x8f\x76\x0c\xfa\x3e\x67\xdc"
+  "\xd5\x20\xf8\xfa\xf5\x4e\x9b\x46\x5b\x46\xbb\x46\x3b\x16\x7c\x3d"
+  "\xae\x49\xbc\x69\x46\x7d\xb1\x6c\xec\xc8\xa1\x16\x79\xde\x03\xc7"
+  "\xf3\x3d\x72\x7c\x86\x47\xfd\xff\x10\x38\x1e\x71\x20\xd9\xf7\xc5"
+  "\x67\xdb\xcf\x78\x9f\xff\xe5\x13\x0e\x76\xc7\xf6\x8e\x83\xdd\x31"
+  "\xfc\xa6\xfb\xc7\xcb\x70\x60\x00\x1c\x00\xcf\xb3\x31\x23\x86\x03"
+  "\xe7\x98\x11\xef\x3e\x66\xe4\x82\x83\xcc\x55\x03\x8b\x03\xb7\x31"
+  "\xa3\xff\x59\x1c\x64\x45\xf7\x11\x07\x3e\xf0\xc1\x6e\xe0\x83\xfb"
+  "\x0d\xc5\xb2\xb1\x22\x87\xba\x02\xf8\xa0\x42\xc6\x07\xce\xb1\x22"
+  "\xde\x7d\xac\xc8\x05\x07\x9b\x36\x0e\x2c\x0e\xdc\xc6\x8a\xfe\x67"
+  "\x71\xf0\x6c\x4c\xdf\x70\x50\xe1\x03\x1f\x54\x20\x1f\x1c\x95\xe1"
+  "\x00\xf8\x40\x8c\xfb\x3c\xc4\x7c\x7c\x8f\x31\x5f\x76\xd6\x0f\x35"
+  "\xe6\xbb\xb8\x71\xb0\xd9\xeb\xb3\x52\x1f\x71\xe0\x03\x1f\x54\x00"
+  "\x1f\xcc\xd4\x17\xcb\xc6\x86\x1c\x6a\x13\xf0\x81\x49\xc6\x07\xce"
+  "\xb1\x21\xde\x7d\x6c\xc8\x05\x07\x39\xb9\x03\x8b\x03\xb7\xb1\xa1"
+  "\xff\x59\x1c\x3c\x97\xd4\x37\x1c\x98\x7c\xe0\x03\x13\xf0\xc1\xcc"
+  "\x0d\x32\x1c\x00\x1f\x98\x80\x0f\x4c\x32\x3e\x70\x8e\x09\xf1\xee"
+  "\x63\x42\x2e\x38\x30\xfe\x7e\x60\x71\xe0\x36\x26\xf4\x3f\x8b\x83"
+  "\x5c\xaf\xf3\x2a\x24\x0c\x74\x8d\x01\x50\x27\x0e\x04\xdd\xaf\x8c"
+  "\x0e\xe9\x50\xed\x6a\x90\xfa\xff\xc6\x6e\xfd\xff\x19\xf5\x5e\xc7"
+  "\x81\xdc\x9e\x2f\x0b\x7d\x83\xbc\x5d\x56\xd6\x4f\xd8\x9b\x8f\xfa"
+  "\x7f\x6e\x1d\xeb\x27\xea\x1e\x46\xfd\xe7\x79\xd6\xbf\xbf\x63\x82"
+  "\xb1\xa0\xff\x86\x1e\xf4\xff\xb8\x97\x7e\xc2\xa3\x7d\xd3\x3f\xce"
+  "\x77\xec\xfc\xb6\x1f\xf5\x2f\x8d\x09\x7e\x46\xb8\x97\xfb\xd4\x5f"
+  "\xdc\xe2\x55\xff\x1e\xe7\x93\x6c\x67\xf3\x49\x70\x2e\x49\x6d\x63"
+  "\x23\xd9\x7c\x96\x68\x82\x13\x18\x26\x84\x39\x25\x80\x09\xe3\x29"
+  "\x32\xd5\xce\xda\xd6\x35\xa7\x04\xd7\x70\x67\xbc\x60\x16\xe6\x94"
+  "\x48\xe3\x01\x5d\xf3\x49\x9e\xc0\xf9\x24\xf9\x6b\xfb\x3c\x16\x80"
+  "\xf3\x49\x92\x41\xc7\xad\xa0\xe3\xef\x51\xbf\x07\x5d\xec\xda\x65"
+  "\x0c\xc0\xdb\x3c\x12\x5f\xc6\x75\xce\xc3\x3c\x12\x61\x0c\xa0\x5f"
+  "\x6c\x7a\xeb\x4c\xaf\xdc\x0e\x7a\x44\x7d\x5a\xf4\x76\x61\x5c\x57"
+  "\xb2\x71\x4b\x4a\x1d\xd9\xdc\x41\x34\xd2\xf8\xbf\xa4\x53\xe4\x7b"
+  "\x0a\x38\xa0\xdf\x46\xab\x51\xa7\xcf\x25\x02\xcf\x2f\x77\xf2\x3c"
+  "\x7f\x49\x64\x55\xd1\x3a\xe0\xf7\x75\x64\x92\x20\xa3\x60\x93\x95"
+  "\x8d\x07\xec\xcd\x47\x7b\x47\x7b\xa6\xea\xdd\xda\x4e\xd1\xde\x99"
+  "\xbe\x6b\x08\xea\x99\xed\xf5\xf9\xfc\x32\xb4\x3d\xd4\x79\xb0\xa8"
+  "\xf3\x62\x2f\x3a\x17\xf4\xad\xd0\xe0\xba\x21\xf8\x9e\x59\x97\xce"
+  "\xed\xcf\xc8\xc6\x7f\xe4\x3a\x17\xc7\x7d\x78\xb0\x65\x9f\xe6\x0f"
+  "\xf9\xa8\xf7\x7e\x1b\xdf\x07\xbd\x17\x8b\x7a\xef\x1a\xdf\xef\x93"
+  "\xde\x5f\xf0\xfe\xfe\x8b\x8b\xde\x77\xc7\xf4\x5d\xef\xf7\xe9\x3c"
+  "\xe8\xdd\x20\xea\x3d\x13\xfb\xf9\xa0\xf7\x82\x4e\x71\xde\x48\x77"
+  "\xbd\x6f\x5b\x7c\xfe\xf5\x3e\xb4\xf9\xc7\xa1\xf7\xdf\x7b\x5d\xff"
+  "\xcc\x4d\xef\xfd\x60\xef\xf7\xa5\x74\xd7\x7b\x85\x68\xef\x15\x4a"
+  "\xec\xd7\x53\x75\x85\x68\xef\xa7\x3d\xe8\xfd\xc5\xc7\xcf\xbf\xde"
+  "\x2f\x3b\xf1\xe3\xd0\xfb\x1f\xbc\xce\xff\x70\xd5\x7b\x45\x7f\xd8"
+  "\x7b\x9d\x07\xbd\x8b\xf6\x5e\x91\x89\xfd\x78\xd0\xbb\x68\xef\x9f"
+  "\x79\xd0\x7b\xc1\xbc\xf3\xaf\xf7\x11\x1f\xfd\x38\xf4\xfe\xd2\x78"
+  "\x1f\xf5\xde\x0f\xf6\x3e\x43\xdf\x5d\xef\x26\xd1\xde\x4d\x4a\xec"
+  "\xb7\x53\xb5\x49\xb4\xf7\x77\x3d\xe8\xfd\xe5\x59\xe7\x5f\xef\xb7"
+  "\xe6\xfc\x38\xf4\xfe\x8a\xd7\xf9\x7f\xae\x7a\x37\xf5\x83\xbd\xcf"
+  "\x30\x78\xd0\xbb\x68\xef\xa6\x4c\xec\xa7\x83\xde\x45\x7b\xdf\xe8"
+  "\x41\xef\x85\xd3\xcf\xbf\xde\x1f\xbb\xfb\xc7\xa1\xf7\xa2\xb0\xde"
+  "\x9e\xd7\x4b\xba\x97\xc6\x6c\x84\xe7\xb3\x10\xdf\x4b\xfa\x46\x1c"
+  "\xa0\xce\x11\x0b\x72\x9d\x0b\x73\x78\x96\xb3\x39\x3c\x18\xb7\x53"
+  "\xe8\x8b\xd3\x4b\x84\xf9\x1b\x5a\xa1\xdf\x2e\xc6\xf1\x54\xa1\xd4"
+  "\x62\x2c\xef\x3d\x8e\x2f\x9e\x2c\xe9\x3b\xd0\xbe\x5b\x6f\xfa\x76"
+  "\xef\x93\x5f\x2c\xfa\x96\xf7\xdf\xfa\x47\xdf\x25\xaa\xc0\xf4\x5d"
+  "\x11\xe3\x9f\xbe\x2b\x0c\x4c\xdf\xc2\x3c\x8d\x02\xa7\xbe\x2b\x32"
+  "\x99\xbe\x2b\xb2\xbd\xfb\xf3\xd2\xeb\xcf\xbf\xbe\x5d\xc7\xe4\xff"
+  "\x77\xf5\x5d\x6a\xef\x69\x0c\x06\x75\x8d\x7a\xdf\xb2\x94\x8c\x7b"
+  "\x6e\x29\x1b\x5b\xb1\x7f\xab\x45\xce\x57\xa2\xfe\xf1\x1d\x9f\x60"
+  "\xc0\xc0\x91\x68\x1b\xe9\x68\x8b\x26\xf8\x2e\x0f\xce\xbb\xa8\x8d"
+  "\xb3\x12\x4b\xca\x61\xb2\x79\x05\xd1\x54\xc7\x34\x93\xd9\xdb\x69"
+  "\xa7\xe5\xb8\x19\xdf\xf1\x56\x9a\xd7\x1d\x26\x74\xb9\x7e\xf8\x13"
+  "\xad\x84\x3b\xc3\xfd\xb1\x1c\xe7\x6d\xdc\xd4\x0a\x32\xc1\xf7\x7d"
+  "\x40\xe7\x9b\xcf\x10\x72\x30\x99\x10\xdd\x12\xd4\xf5\xab\x23\x86"
+  "\xae\xf2\xf0\x9e\x8f\x3f\xe3\x32\xf2\xb1\x57\x0f\xba\x7e\x85\xeb"
+  "\x9f\xb9\x19\xd2\xbc\x0c\x97\x71\x99\xbe\xbe\x7f\xd9\x6f\x73\x33"
+  "\x5e\x6d\xe8\x69\xbe\x0d\xea\x13\x6d\xda\x9e\xc7\xc6\x65\x2c\x29"
+  "\x55\x04\xe7\xd5\xa0\x0d\x3b\x5a\xb4\x41\xeb\x93\xc1\xd6\xeb\x99"
+  "\xad\x3f\xd7\x0c\x79\x63\xfe\x43\x10\x1f\x4c\xb7\x9d\x4c\xb7\xcd"
+  "\xa8\xdb\xff\x10\xba\x52\x3f\xfc\x0c\xf7\x27\x23\xea\x17\xf5\x9a"
+  "\xf6\x09\xd1\x3c\x89\xeb\xa2\x20\xc7\x03\xbf\x83\x9e\xa7\x94\x2c"
+  "\x25\x93\xd0\xfe\x1d\xb9\xbb\x95\xf6\x5c\x36\x47\x03\x79\xbf\x53"
+  "\x55\x19\x94\xb3\x42\xd4\xff\xa3\xa8\xff\x32\x8f\xfa\x7f\x25\xd0"
+  "\xb1\x77\x51\xff\x01\xbf\xd7\x73\xa1\xec\x7d\x79\x7f\xd9\x7b\x99"
+  "\xd7\x35\x51\x5c\x71\xc0\xc6\x69\xfc\xc3\x41\x9b\x07\x1c\xbc\xb6"
+  "\xcd\x03\x0e\x0c\xc0\xfb\x3a\x37\x1c\x64\x8a\x38\xc8\x86\xf3\x05"
+  "\xdd\x71\xf0\xfa\x55\x03\x83\x03\x1f\xdf\xe7\xf9\xc1\xe3\xe0\xf5"
+  "\x56\x1f\x71\x10\x00\x1f\x7c\xeb\x01\x07\x7f\x2e\xec\x8e\x83\x0a"
+  "\xe0\x83\xfb\x52\x5c\x71\x50\x21\xf2\x41\x05\xf0\x41\x85\x07\x3e"
+  "\xd8\x7e\xed\xc0\xe0\xc0\xc7\xf7\x78\x7e\xf0\x38\xd8\xee\xd5\xff"
+  "\xbb\xe2\xa0\x22\x00\x3e\xf8\xdc\x03\x0e\xde\x28\xf3\x80\x03\xe4"
+  "\x83\x3a\x37\x1c\x88\x7c\x50\x91\x8d\xf1\x61\x77\x1c\xfc\xe5\x86"
+  "\x81\xc1\x81\x8f\xef\xef\xfc\xe0\x71\xf0\xa6\xd7\xf7\x7f\xdd\x70"
+  "\x10\x00\x1f\x54\x7a\xc0\xc1\x9b\x3b\xba\xe3\xc0\x04\x7c\x30\x43"
+  "\xef\x8a\x03\x93\xc8\x07\x26\xe0\x03\x93\x07\x3e\xd8\x71\xf3\xc0"
+  "\xe0\xc0\xc7\xf7\x76\x7e\xf0\x38\x78\xcb\x6b\xff\xcf\x15\x07\xa6"
+  "\x00\xf8\x20\xcd\x03\x0e\xde\x2a\xf7\x80\x03\xe0\x83\x19\x06\x37"
+  "\x1c\x88\x7c\x60\x02\x3e\x30\x79\xe0\x83\xb7\x6f\x1b\x18\x1c\xf8"
+  "\xf8\xbe\xce\x0f\x1e\x07\xef\x78\x7d\xff\x5b\x8e\x83\xce\xae\xfe"
+  "\x82\x49\xc0\x41\xce\x3a\x86\x83\x8d\x88\x83\x46\x36\x7f\xc7\x28"
+  "\xe2\xa0\xab\xaf\xd0\xe0\x8e\x81\x77\x4c\x5d\x18\xf8\xda\xd9\x57"
+  "\xe8\x04\x7d\x0b\xe3\x41\x62\x3f\x41\x1a\x07\x12\xfa\x09\xd0\x4f"
+  "\xcc\x69\x16\xf5\x2f\x8c\x09\xec\xf4\xac\x7f\x3f\xfa\x89\x2e\x73"
+  "\x34\xdc\xf5\x7f\x91\xbf\xa7\xd3\x6d\x5c\xe0\x93\xbe\xce\xcd\xf8"
+  "\xab\x8f\xfa\x97\xe2\x02\x5f\xf5\xff\xb9\x07\xfd\xff\xd5\x83\xfe"
+  "\x2b\x0c\x4c\xff\xf7\xd5\x49\xf1\x80\x34\x2e\x24\xc4\x03\xdd\xf4"
+  "\xff\xb7\x01\xd2\xff\xc5\xf9\x7e\x4e\xff\xeb\xff\xef\x5e\xf5\x9f"
+  "\xcf\xf1\x3b\xe1\x30\xc1\x61\x86\xa3\xca\xc1\x91\xe9\x45\x1c\x2f"
+  "\xac\x39\x83\x6b\x88\x17\x65\x74\x3b\x7f\x09\xbd\x44\x1f\x8b\x79"
+  "\x40\x87\x42\xb9\x52\x19\x34\x87\xa0\x1c\xcd\x6a\x45\x0c\xae\x7f"
+  "\x85\x79\x2f\x95\xca\x52\xa7\x93\x08\xa9\x2c\x68\x9f\x01\xe4\x6e"
+  "\x0e\x49\x8f\xb8\x04\xf2\x57\xd1\x9c\x84\x4c\xc8\x1b\x24\x94\x99"
+  "\xae\x14\xc6\xa8\xa5\xbc\x8e\x0c\x05\xae\xd9\x64\x0e\x51\x40\x5e"
+  "\x56\xe6\x30\x31\x9f\x8e\xcf\x20\x3a\xa1\x9e\x1c\x87\xf7\x73\xaf"
+  "\xe7\x70\x31\xdf\x38\x79\x1d\xd5\xe9\x11\x42\x79\x62\x9e\xcb\xe8"
+  "\x25\x0a\x83\xd8\x16\xbd\x3c\x9f\xe3\x6e\x82\x65\x4a\xf9\x54\x62"
+  "\x59\xe3\x5d\xf2\xbc\x4a\x48\x88\x42\xc7\xea\x97\xc2\x11\xb1\x7e"
+  "\x6a\xcc\xeb\x18\xfe\x54\xb4\x43\xa1\x0c\xe7\x39\x12\xee\x72\xcd"
+  "\x26\x22\xe4\x17\xf3\x06\x0b\x79\x2f\x99\x55\x0d\x79\x27\x89\x32"
+  "\x57\xca\x65\x2e\xe6\x0b\x91\xe4\x28\x3f\xe7\xc8\xe0\xb0\x2c\x3c"
+  "\xaf\xa1\x97\xcc\xc4\x36\x4c\x95\xf2\x49\xf7\xb3\xc4\x11\x22\xe4"
+  "\xe5\xc8\xcd\xa2\x4e\x46\x40\x3b\x22\xa4\x7c\xb8\x8e\x9a\x94\x17"
+  "\x70\x7d\x55\x89\x53\x36\x23\x1d\x39\xcb\xb4\x8e\x74\xe5\x34\xf7"
+  "\x32\x43\xd2\x15\x56\xcc\x57\xd3\x28\x94\x8d\xfa\xab\x86\xfc\x3f"
+  "\x11\x65\x14\xc9\x74\xa2\xe9\xd2\x89\x83\xb3\xe3\x39\x73\x31\xab"
+  "\x6b\xa8\x98\x6f\x66\xf7\x7c\x4a\x79\xbe\xcb\x99\x1c\xd7\xef\x00"
+  "\xd9\xcc\xe9\x9e\x37\x48\x9e\xf7\x0a\x96\x77\xf9\x4c\xc8\x3b\xb7"
+  "\x7b\x5e\x8d\x3c\xef\x95\x2c\xef\xd3\xf3\x21\x6f\xb4\x87\xba\x8e"
+  "\x94\xe5\xd5\xb2\xbc\x2b\x13\x20\xef\xfc\xee\x79\x75\xf2\xbc\x57"
+  "\xb1\xbc\x1b\xcb\x21\x6f\x4c\xf7\xbc\x11\xf2\xbc\xa3\x58\xde\x55"
+  "\x1b\x20\x6f\x6c\xf7\xbc\x06\x79\xde\xab\x59\xde\x35\x46\xc8\x1b"
+  "\xe7\x9e\xb7\x84\xe9\x76\xac\xa8\xdb\x30\x96\x77\x6d\x21\xe4\x4d"
+  "\xf0\xd0\xb6\x21\x42\xb9\x2c\xef\x68\x96\x77\x59\x12\xe4\x4d\xf2"
+  "\xa0\x0b\x79\xde\x31\x2c\x6f\xae\x19\xf2\x26\x7b\xd0\x85\x3c\xef"
+  "\x35\x2c\x6f\x7a\x3e\xe4\x4d\xf1\xa0\x0b\x67\xde\xe1\xcf\x14\x40"
+  "\x9e\x0d\xd0\xce\x3a\x0f\xb2\x95\x97\x79\x2d\x2b\x33\xab\x14\xf2"
+  "\x1b\x3c\xc8\x56\x9e\x77\x2c\xcb\xfb\xec\x76\xc8\x9b\xe9\x41\xb6"
+  "\xf2\xbc\xd7\xb1\xbc\x9b\x77\x42\xde\xec\xee\x79\xc1\xde\x98\x7c"
+  "\x6f\x11\xe5\x3b\x8e\xe5\x7f\xce\x04\xf9\x8d\x1e\xe4\x8b\xe5\x49"
+  "\x36\x7b\x3d\xcb\x9b\xb6\x0f\xf2\xe6\x7b\x90\xaf\x3c\xef\x4f\x59"
+  "\xde\xa2\x58\xc8\xbb\xcd\x83\x7c\xe5\x79\x7f\xc6\xf2\x6e\xdd\x06"
+  "\x79\x0b\x3c\xc8\x57\x9e\x57\xcf\xf2\xbe\x80\xd8\x29\xf4\x50\xdf"
+  "\xb1\xb2\xbc\x37\xb0\xbc\xbf\xcf\x84\xbc\xa5\x1e\xf4\x21\xcf\x7b"
+  "\x23\xcb\x5b\x32\x17\xf2\x96\x79\xd0\x87\x3c\xef\xcf\x59\xde\x3f"
+  "\x20\xd6\xb7\x7b\xd0\x47\x57\x5e\xf0\x0b\xe3\x1d\xc3\x5f\x4a\x2e"
+  "\xc1\xfc\x0a\xa5\xb0\x37\x0d\xe5\x04\xff\x2e\xe4\x05\x9c\x98\x45"
+  "\xbe\x9b\xc0\xca\x7c\x05\xed\x52\x58\x8b\x17\xf3\xd4\xb4\x0b\x7c"
+  "\x04\xfe\xc5\xfe\x8b\x12\x27\x77\xdf\xc4\xf2\x6e\x41\xec\x96\xcb"
+  "\x39\x94\x72\x4a\x79\xbe\x89\x2c\xdf\x3b\xc8\x0b\x26\xd7\x7c\x41"
+  "\xce\x7c\xc3\xff\x34\x1e\xce\xef\x2b\x76\xe3\x63\xa8\xa7\xbc\xac"
+  "\x9b\x59\x59\xaf\x4d\x82\xbc\x66\xd7\x7c\xf6\x5b\x64\xf9\x6e\x61"
+  "\xf9\xfe\x3c\x15\xf2\x1d\x70\xcd\xa7\x93\xe7\xfb\x05\xcb\xf7\x57"
+  "\xac\x5b\x95\x6b\xbe\x08\x79\xbe\x49\x8e\x9c\x37\x04\xbe\x06\xde"
+  "\xae\x76\x97\x1f\xc8\xfa\x16\x99\x4f\x9b\xec\xc8\x79\x73\xa6\x98"
+  "\xb7\x4e\x92\xa1\x20\x67\x86\x79\x4e\xc4\xfc\xad\x8e\x9c\xb7\xe6"
+  "\x8a\xf9\x8e\xca\xfd\x80\xcc\xd7\xfe\x92\x0e\xff\xe3\x34\xd1\x8f"
+  "\x0a\xfb\x34\x01\xbf\x1f\xf7\x14\x6f\x24\xdd\x48\x2e\x3b\xc5\xed"
+  "\x0b\x65\xbe\x47\xda\xaf\xeb\x5d\xb6\x6f\x72\xa1\xc1\x1c\xd5\x4a"
+  "\xed\xf2\xb4\x2d\x1c\xad\x9b\xd8\x4a\x94\xb8\x66\x2a\x55\xef\x6f"
+  "\xb4\x42\xba\x6d\xb4\xc1\xda\x96\xb3\x4f\x67\x55\xdc\xbb\x13\xd7"
+  "\xf4\x83\xef\xe3\xad\x24\xb7\x1e\xbf\x6f\xc9\xa0\xed\x20\x13\x05"
+  "\xee\xef\x52\x02\xdf\xf3\xe0\x10\xf6\x54\x81\xb8\x8e\x6e\x22\x11"
+  "\xe6\xd5\x76\x72\x32\x85\x70\x7c\x5e\x96\x41\xb7\x02\xd7\x15\xdc"
+  "\xb7\x96\xae\x89\x9b\x0a\x75\x29\x85\xfb\xc6\x9e\x80\xdf\x42\x5d"
+  "\xa0\xfd\xe0\x1b\x0b\xcd\x2b\x70\x6d\xd1\x7d\x6f\xd9\xd4\x95\xa5"
+  "\xf4\x99\xc7\xbe\x4e\x4a\x25\xd7\x40\xfd\x77\xb4\x00\x37\xb4\xac"
+  "\x89\xbb\x03\xcb\xe0\xd5\x59\x85\x50\xdf\x38\x5c\x93\x90\x16\x98"
+  "\x0d\x6c\xbd\xc2\x7d\xc2\x7a\xee\x50\x9f\x3a\x1a\x66\xd8\xc9\x77"
+  "\x64\x1a\x70\x6f\x38\x73\xea\x29\x72\x42\x76\xce\x76\x95\x59\x58"
+  "\xcb\x10\xda\xb7\xd3\x91\xfd\x8d\x81\x0f\xfa\x66\x03\xcd\x3e\xab"
+  "\xb5\x24\x58\x09\xdb\x0b\xe6\xdd\x8d\x34\xf8\x11\x0b\x9f\xfd\x4d"
+  "\x2c\xa4\x07\x59\x5a\x3b\x84\xf4\x13\xdc\xbb\x93\x30\xee\x6c\x09"
+  "\x6a\x4e\xa0\xd9\xcd\x49\xe6\x51\x1d\xa4\x81\x7b\x37\x02\xcb\xc5"
+  "\x74\xba\xf9\xac\x16\x65\xc5\x6f\x3e\x1b\x34\x44\x4b\x94\x2d\xc3"
+  "\x9a\x13\xda\x72\xde\x9d\x2b\xed\x49\x22\xdd\x0b\xcb\xb5\x8a\x65"
+  "\xc1\xf9\x64\xab\xe2\x67\xf5\x6c\x9d\xc4\x7d\x3b\x7a\x98\x23\x12"
+  "\x42\x73\xb3\x4c\x90\xbf\x0c\x62\xcb\xb9\x4c\x07\xef\xee\xb4\x2a"
+  "\xc6\x94\x89\xdf\xf7\x59\x15\x63\x55\xe2\xf7\x2a\xab\xe2\x0e\x8d"
+  "\xf8\xbd\x6b\xfd\x47\xcf\xeb\x51\x66\x19\x41\xe6\x65\xfc\x2b\xd1"
+  "\x41\x18\x17\x63\xac\x4f\xd5\x59\x46\xdd\x18\xdc\x87\x70\x7f\x02"
+  "\xdc\xb3\x8c\xed\x05\xb0\xff\x66\xf8\x0c\x11\x3f\x6d\xe2\x27\xc5"
+  "\x3c\x02\xae\xc2\xd2\xc3\xa9\x71\x4f\x0a\xca\x3b\xd5\x41\x79\x28"
+  "\xb7\x0a\x64\xa7\xb1\xa4\x34\x8a\x32\xdd\x2f\xec\x81\x2c\xe8\x14"
+  "\xf4\x4e\x87\x9d\xd5\x08\xf7\xca\xad\x2c\x95\xd7\x2b\xfc\xe6\x5b"
+  "\x7e\x31\x69\xf2\xad\xbf\x9c\x72\xdb\x82\x85\x8b\x62\x17\x2f\xf9"
+  "\x5d\x5c\xfc\xd2\xa7\x12\x96\x25\x2e\x4f\x7a\x7a\xc5\xca\xe4\x55"
+  "\xab\xd7\xa4\xac\x5d\x07\xe5\x74\xed\x41\x47\x5f\x99\xa6\x68\xe5"
+  "\x08\xdc\xe3\x6e\xbc\x47\x8d\x50\x17\x48\x63\x78\xd8\xbf\x4f\xa9"
+  "\xf3\x2c\x4f\x8b\x16\xfa\x3d\x63\x71\xff\xaf\xca\xab\x70\xdf\x1b"
+  "\xc0\x9e\xc2\x52\x78\xaf\x19\xf7\x4d\x6b\xe0\x2a\x55\xb5\xb6\x7b"
+  "\xcd\xb8\x6f\xdf\x07\xda\x46\x32\x6e\x2c\xee\xad\xb6\xbf\x1d\xcf"
+  "\x97\xfc\x94\x90\x03\x70\xad\xa7\x32\xc7\x6a\x88\xf6\x85\x2b\xa8"
+  "\x6d\xdb\x15\xb4\x09\xcb\xdf\xf6\x22\x6d\xb4\xad\x8f\x23\x79\xf0"
+  "\x1b\x30\xab\x39\xc9\x55\xd6\x7c\x00\x91\x36\xc4\xd0\x61\xc5\x2f"
+  "\xd2\x86\xcc\x2b\x68\xc3\x33\x2f\xd2\xa6\x92\x2b\xa8\x75\xdc\x36"
+  "\xa2\x6a\xcb\xa9\x34\x58\xb9\xfd\xcc\xa6\xe0\x3c\x3f\x7c\x7f\xca"
+  "\x16\x38\x37\xd1\x4e\x86\x94\xc0\x6f\x48\x6b\xfd\x40\xc7\xea\xfd"
+  "\x4e\x73\xfb\x50\x28\x2f\x96\x76\x26\x28\xf2\xe0\x3e\x4c\x47\x95"
+  "\xdf\x1d\x00\xef\x0f\xf7\xb3\x59\xda\x4f\x10\x2b\x57\x69\xc3\xfd"
+  "\xa4\xe0\x7e\x21\x96\x82\x26\x82\xe5\xbd\xbd\xa2\x7d\xe8\xca\x51"
+  "\xd4\x0e\x79\xeb\xf8\xf5\x09\x0a\xc8\xb3\x03\xca\x6e\x95\xb7\x47"
+  "\xbf\x64\x59\xb2\x2e\x71\x55\x42\xc2\x0d\xc3\x89\x5e\xf8\x74\xd9"
+  "\xf3\x2f\x19\xd7\xa2\x7d\xe1\x45\x7a\x00\xda\x69\x86\xf6\x56\xd5"
+  "\x40\xb4\x0f\x78\x21\xd0\xa6\xfc\x93\x9c\x79\x3a\xa4\xef\x83\xef"
+  "\xfb\xa0\xee\x55\x6c\x9f\xb8\x0f\x9f\xa6\x39\x95\x76\xa8\x27\xfa"
+  "\x1b\x1d\xae\x5d\xdb\xb2\x66\xae\x02\xda\xbd\x0d\xf2\x55\xe9\x46"
+  "\x91\xeb\xe1\xba\x1a\xa8\x47\x19\x7c\xc7\xfc\x02\x1f\x40\xfe\x03"
+  "\xac\x5d\x1f\x2e\xc0\xdf\x20\x2b\x73\xd1\x15\xd4\xd8\x96\x63\xde"
+  "\x8e\x6b\x72\x0b\x7b\x17\xc1\x6f\x90\x4b\x15\xe4\xcd\x6f\x49\x9b"
+  "\xab\x80\x3e\xa3\xa2\xc4\x59\x66\x0a\xd6\x09\xeb\x81\xfd\xd0\x23"
+  "\x10\xf5\xf1\x9d\xd1\x64\x42\x3b\x51\x1c\x69\x20\xa4\xf0\x45\x5a"
+  "\x0a\x47\x21\x1c\x05\x87\xe1\xdc\x21\x38\xaa\x20\xbd\x1a\x3e\x0f"
+  "\xc3\xe7\x21\x38\xa0\x1f\xab\xc5\x7a\xaf\xdc\x40\x1b\x27\x16\x90"
+  "\xeb\xb0\x7c\xc0\xd6\x6f\x4f\x70\x75\x55\x58\x77\x5c\xf3\x9e\x0e"
+  "\x7f\x6f\xaa\xeb\x3a\xe1\xef\xef\x24\x70\x1e\x3e\x0f\xb0\x4f\xf9"
+  "\xf1\x81\x0a\x8e\xf1\xe2\xf7\x64\xc8\x53\x28\x7e\xcf\x86\x63\x5b"
+  "\xef\x87\x7b\x79\xde\x0e\x70\x6d\x3e\xe7\xf5\xe5\xf8\x70\xaa\x6f"
+  "\xf9\x0e\x9a\x08\x57\xa5\x81\x23\xd2\x35\xbd\x4a\xc7\xd2\xaa\x9b"
+  "\xd8\xef\xea\x76\xf6\x09\xe8\xe1\x6a\x40\x4e\xb5\x50\x7e\x6d\x0c"
+  "\x4b\xab\x4d\x80\xcf\x72\x38\xcc\xae\xf7\xff\x10\xae\xff\x70\x2e"
+  "\xea\xb3\x33\x03\xfc\x05\xe8\xd2\xca\xbd\xa7\x42\x1d\x6d\x61\xd8"
+  "\x52\xf0\x54\x48\x0b\x02\x6c\x15\x3a\xf1\xf3\xbe\xc3\x15\x3f\xef"
+  "\x37\xba\xe1\x27\x1f\xb9\xc8\xca\x99\xe7\x96\x30\xbc\xec\x6b\x59"
+  "\x1f\x0b\xbf\xdf\x47\xdb\xdc\x87\xe3\x23\x27\xb9\x0f\x84\xfe\xc5"
+  "\x96\x53\x84\xa8\xe3\x88\x12\xf9\xa5\x89\xfb\xe0\x76\xc4\x2c\xde"
+  "\x5b\xbc\x2f\xab\x0b\xd4\x0f\xd2\x4a\xb1\x7e\xcb\xa1\x5c\xf8\x5d"
+  "\x06\xf9\x4a\x2d\xa4\x59\xaa\x9b\x70\x4d\xce\x52\xc0\xa3\x58\x5f"
+  "\x2c\x13\xaf\xa3\xce\x76\x05\xe1\x35\xe2\xbd\xbf\x83\x74\xec\xd7"
+  "\xe2\xbb\x4f\x43\x2c\x76\x2b\x41\x4c\xe2\xa7\xc5\x1e\x0e\xb6\x14"
+  "\x49\xf8\xb6\x68\x32\x51\x4b\xc2\xc1\xde\x86\x9d\xe0\x3e\x38\x7a"
+  "\xd3\x06\x12\x8e\xe5\x21\xa7\x5b\xb9\x0f\x0a\x4a\xd0\x16\x59\x59"
+  "\x82\x1f\xc4\xf2\x0f\x27\x11\xe1\x3e\xc5\x58\x1f\x38\x2f\xbb\xef"
+  "\x36\xec\xc3\x6e\x59\xc7\xda\x0a\xf7\x2a\x83\xeb\x77\x62\xdb\x51"
+  "\x9e\x70\xde\x74\x92\x3b\x10\x8e\xe7\x84\x7d\x83\x58\x7b\xca\x70"
+  "\x6f\x09\x94\x07\xe6\xc7\x7d\x28\xd9\x1a\xe1\xe6\x79\x82\xdc\xe0"
+  "\x7a\xd4\x07\x85\x7b\x60\x19\x69\x76\x6a\xa7\xc0\x47\x7f\x5a\xd7"
+  "\x0e\x71\xc7\xc1\x37\x5c\xf5\x73\x20\x5b\xae\x1f\xb8\x6e\x27\x5c"
+  "\x7f\x80\x42\x1b\x91\x4f\xe0\x9e\x21\x18\x6b\x40\x5a\x3e\x9f\x03"
+  "\x65\xac\x6e\x17\xc6\x74\xa0\x9c\x97\xa0\x2e\xf9\x58\x0e\xd4\xe7"
+  "\x80\x58\xd6\xd1\xf7\x36\xb8\xea\x5a\x2c\xaf\x0c\x75\x2e\xd8\xf3"
+  "\x3a\xa1\x4d\xc0\x5d\x07\xe3\x8b\xd9\x39\x13\xe4\x31\xd1\xce\x48"
+  "\x82\x7b\x35\x30\x5f\x22\x9c\x2b\x4f\x3b\x27\xe8\xf7\x00\xe3\xb5"
+  "\x83\x9b\x57\x6e\xa4\x8d\xce\x7a\x1f\x8c\x90\xf6\xbb\x10\xeb\x5d"
+  "\x8e\xf7\xa3\x6b\xe6\x0b\x7e\x15\xef\x81\xd7\x8b\xe5\xa1\x0f\x28"
+  "\x97\x64\x75\x13\xd4\x83\xc9\xeb\xc0\x1c\x48\x2f\x43\x2c\x0a\x72"
+  "\x03\x1e\x6d\x49\x43\x2c\x1e\x9c\x06\xd7\xef\xcb\xc3\xdf\x6b\xf0"
+  "\xf7\x81\x7a\x81\x63\xbb\xce\x1f\x30\xe2\x79\x4b\x23\xe8\xed\x29"
+  "\xc0\x12\x4f\xc8\x75\xa1\x24\xbc\x35\x43\x68\xdb\x8e\xd6\xf5\xd3"
+  "\x14\x1f\xd8\x09\xc1\x7a\x82\x8c\x20\x8e\x38\xd8\x04\xdc\x3f\x1e"
+  "\xeb\x0a\x7c\x5d\x4e\xff\x14\x4d\xb0\xce\xc0\x67\x62\xfd\xfe\xf1"
+  "\xb8\xa8\xfb\x72\x6c\x23\xca\xf3\x26\xc6\x7d\x70\xae\x4a\x81\x75"
+  "\x77\xb6\xfb\x1f\x53\xe4\x32\x16\xda\x0d\x7a\x40\x7d\xa1\x5e\x64"
+  "\x65\x22\xf6\xf3\xa1\xac\x1d\xec\x37\xc3\x06\xca\x3a\xff\x0a\x5a"
+  "\x8d\xf9\x9d\x79\xff\xf9\x34\x9e\x4b\x85\x7b\x4f\x4c\x02\x9f\x0e"
+  "\x76\x81\x7b\x96\x40\xb9\x3b\x70\x8f\x51\x28\xc3\x84\x32\x85\x7c"
+  "\x07\x11\x8f\xf0\xbb\x5a\xbc\xc7\x01\xf0\xe7\xe3\xe1\x98\xea\xb4"
+  "\xff\x7f\xee\x72\xc5\xd7\x3f\xdc\xed\x1f\xf5\x9d\xcf\xa7\x45\x12"
+  "\x01\x0f\x2b\x88\xee\x0c\xf7\xcf\x07\x44\xdf\x21\xea\xfa\x9f\xaf"
+  "\x7d\x00\xf6\xe2\x2c\xe3\x9f\xe3\xdd\x74\x6d\x12\xf0\xb8\x66\xa6"
+  "\x02\xdb\x0c\xd7\x9a\xc4\x72\x84\x36\x0b\x78\xca\x10\x30\x50\x4d"
+  "\xd7\x40\x3b\xbb\x70\xf0\x8f\x6c\x51\xcf\xd5\x6e\x32\x91\xb8\xeb"
+  "\x28\xee\x2d\x87\x9c\xd4\x96\x41\xee\x68\xeb\x74\xf2\x12\xea\x9e"
+  "\x17\x74\xff\xcf\xf0\x12\xe6\x6f\x45\xde\xfa\x07\x3b\x7f\x85\x0b"
+  "\x86\xb1\x2e\x8b\x05\xfc\x62\x5d\xd2\xe6\x63\x5d\x4c\x42\x3d\xd2"
+  "\x74\x04\xce\x1d\xc7\xfb\x43\x59\x71\xa2\xbd\x4a\x65\x4d\xc5\xb2"
+  "\x9e\x01\xae\xc2\x3a\xc1\xbd\xab\x04\xfe\xfb\x8d\x80\x83\xdb\xc5"
+  "\xba\x57\xb5\x67\xe0\xb5\x1f\x84\x9f\xe3\x84\x6b\xab\x20\x5f\x59"
+  "\x3b\xdb\x7f\x66\x38\x5c\xbf\x1d\xd7\xfc\x3f\xc9\x55\x17\x22\x47"
+  "\xe3\xf3\x26\xf8\x9e\x85\xef\x86\x02\xa7\x28\xa1\x3c\xe4\x9c\x1d"
+  "\x12\x2e\x9a\xb8\xea\x55\xb8\x36\x3e\xc8\x7a\x07\xc4\x48\xdb\x51"
+  "\xde\x88\x65\x88\x91\x26\xb5\xe5\x54\x95\x49\xb8\x85\xfb\x14\xa2"
+  "\xec\x99\x7e\xaa\xbe\x06\x1c\x9b\x9c\xd8\xaa\xfa\x5a\x94\xe3\x76"
+  "\x90\x63\x10\xdc\x2f\x5e\x6c\xd7\x76\xc8\x0f\xb1\x58\xf5\x23\x62"
+  "\xdd\x0b\x58\xfe\x43\x43\x25\x3d\x88\xb6\x5a\x9d\x87\xfc\x2b\xe8"
+  "\xe0\x50\xa1\x78\x6d\x19\xbb\xd7\xa1\x22\x29\x2f\xc6\x88\x6c\x5f"
+  "\xa9\x43\x45\xc8\x83\x13\x41\xf7\x02\xf7\x09\xfb\xef\xb2\x34\xb4"
+  "\x1d\x76\x8f\x6a\x61\x3f\x8a\x67\x20\xee\x71\xe2\xe8\x50\xb2\x1b"
+  "\x3f\x21\x17\xe7\xd7\x42\x19\xc8\xa7\x88\x25\xe4\x54\xec\xc3\x40"
+  "\x79\x33\x45\xfb\x91\xea\xfc\x85\x2b\x56\xaa\x6f\x06\xac\x4c\x90"
+  "\x95\x5d\xe7\xc9\xcf\x95\x30\x0e\x2c\x64\xd7\x1c\xbe\x56\x6c\xdb"
+  "\x0e\xd6\x36\xf1\x37\xca\x2d\x15\xe5\x76\xe4\x4b\x99\x1c\x41\x6e"
+  "\x47\x1e\x10\xf3\x9b\x90\xcb\x9d\xf6\x7a\x38\x57\xb2\xe5\xee\x7c"
+  "\x71\xe4\x2e\xb4\x07\x67\xbd\x0e\xc7\xb9\xf1\x85\xc9\x33\x5f\x1c"
+  "\x9e\x22\xb6\xb7\xd4\xcd\x36\xc4\x3e\x89\xe8\x5b\x40\x0f\xb5\xd0"
+  "\x47\x63\x7b\x28\x99\xe7\x21\x7f\xe2\xbd\xe5\x3e\xa8\x98\xc9\x55"
+  "\xb4\xe5\x23\x13\xba\xeb\xe1\xb0\x5d\x6e\xcf\xa8\x6b\xe4\x04\x2c"
+  "\x03\x75\x2a\xc4\x95\x90\xc6\xf4\x7a\xf8\x28\x72\x83\x9c\xa3\x21"
+  "\xef\x36\x9e\xa2\xbd\x1c\x21\xae\xb6\x78\x38\x41\xb4\x45\xe9\xde"
+  "\x1f\x82\x8e\xc2\x9d\xf7\x3d\x92\xec\x76\x5f\xd4\xcd\x01\x94\x03"
+  "\x6b\xe3\x91\x77\x25\x9f\x86\xf9\xe1\xda\x14\xb8\x66\xbb\x9b\x7f"
+  "\xcc\xc7\xfa\xc1\xbd\x74\x02\x67\xbd\x28\x70\x45\x4a\x1b\xab\xcf"
+  "\x8e\x12\xd1\x4f\x40\x5a\xb8\x98\x96\x22\xfa\x12\x09\x37\xa3\x5d"
+  "\xeb\x54\x1d\xe4\x39\x3e\x3a\xac\x93\xe2\x23\xa1\x2c\x81\x8b\xaa"
+  "\x55\x62\xfb\x30\x6d\x02\x4b\x3b\x74\x14\xd3\xf2\x98\x1c\xb6\x51"
+  "\xc1\x5f\x1d\x4a\x11\xfd\x15\xda\x17\x67\xe5\xaa\x1a\xd1\xc6\xf0"
+  "\x37\x94\x11\x83\xe5\x5b\x0c\x1d\xd8\x87\x28\x80\x73\x99\xc8\x07"
+  "\xc8\x17\x38\x87\x55\xf8\x9c\x2d\x7c\xbe\x85\xbc\x83\x71\x08\x9e"
+  "\x87\x7c\xc9\xc8\x45\x90\xfe\x1e\xee\xd5\x4a\xbf\x09\x82\x72\xab"
+  "\xcb\xc4\x6b\x8f\x09\xb1\xc2\x37\x91\x43\xa4\x34\xe9\x3a\xe0\x86"
+  "\x2c\xbc\x0e\xaf\x97\xf8\x0b\xb9\xcb\x8e\xdc\x24\xdc\xaf\xe6\x2a"
+  "\x11\xe3\x42\xbf\x41\x8a\x8b\x3a\x39\x59\x5e\xdc\x7b\x46\xe0\xb4"
+  "\x9a\x58\xc6\x67\x35\xf3\xf0\x5a\x41\x7f\xc0\x95\xa9\xe7\xe8\x17"
+  "\x25\x2b\x88\xb2\xb8\x19\x79\xd1\x3c\x97\xd5\xb3\x66\x27\x6b\x47"
+  "\xcd\x5a\xa1\x1d\x8c\x53\xf3\x59\x5d\xcc\x73\x8b\x3b\x84\x73\xbf"
+  "\xc7\xb6\xe0\xb9\x2d\xb2\x73\xb4\x53\x8f\xe7\x84\x3d\x96\xdd\xaf"
+  "\xe3\x3b\xe3\xba\xe5\xc7\xbd\x87\x81\x43\x83\x8a\x5f\x94\xb8\xb7"
+  "\x36\x5c\xac\xe7\x69\x89\x77\x41\x2e\x1b\x90\x7b\x85\x73\x4b\xc4"
+  "\x3c\xb3\xc5\x4f\x81\xdf\x6b\x47\x33\xb9\x6a\x39\x51\xde\x99\xac"
+  "\x1d\xb5\x37\x0b\xfd\xec\x6f\xa2\x41\xb6\xb5\xa1\x92\x6c\xe5\xdf"
+  "\xd1\x7e\xe0\xfe\x1a\xfc\x2d\xe0\x7e\x83\xd0\x87\x2d\xc4\x3c\x58"
+  "\x27\xe6\x23\x6a\x54\xee\x31\xf5\x49\xae\xee\x0d\xf4\x4b\x2c\x56"
+  "\xad\xdb\x2c\x8e\x0b\x11\xf3\x8a\x57\xc1\x2f\xd4\x1e\x95\x38\x86"
+  "\xb6\x45\x42\x9f\xff\x04\xd6\x51\xd8\x4b\x09\xf7\x13\x91\xe7\x41"
+  "\x7e\x7a\xa7\xc3\x2a\x96\x59\xbb\x53\xe2\x0d\xe4\x92\xda\xd6\x13"
+  "\x62\x4c\x67\x89\x29\x16\xb9\xe4\x0c\x67\x59\xe0\x1a\x87\x59\x16"
+  "\xb8\x72\x46\xdd\x2a\x77\xce\x80\xb8\x39\xb3\x2d\xc7\x32\xc9\x25"
+  "\x0e\x80\xb4\x9e\xb9\xc3\x82\x3a\xc9\xc7\xfd\xe4\x04\x7e\x12\xc6"
+  "\xba\x2c\x87\xa4\x3a\x23\x6f\xb6\xac\x97\xc6\x2f\xea\x16\x63\xac"
+  "\xe6\x76\xbf\x32\x17\xee\xc4\xfb\x49\xe5\x29\x09\xee\x47\x06\x72"
+  "\xc0\xf1\x16\x4b\xb2\xc8\xf3\xa5\x2e\x5c\x29\xfa\x30\xe4\x49\x57"
+  "\x5f\x65\x9e\xe7\xea\xab\xea\x1e\xe8\xce\x91\x75\x3a\xdf\x7d\x95"
+  "\xa5\x1d\x79\x4b\xe2\x48\x57\x2e\xa8\x1b\x57\xec\x12\xcb\x5a\x76"
+  "\x48\xb1\xac\x93\x47\x2d\x53\x91\xa3\xe0\xfe\x26\xf1\xde\x80\x9d"
+  "\xfd\xa5\xd2\xbd\x01\x47\x47\x6b\x75\x80\xcd\x1c\x73\x10\x7c\x37"
+  "\x88\x31\xa0\x60\x9b\x1d\xc2\xde\x45\x35\x55\x80\xbf\xe1\x88\x33"
+  "\x73\x62\x33\x69\x70\xfa\x8a\x03\x2d\xcb\x25\xf9\x7e\x38\x41\x1e"
+  "\x17\x16\xbd\x48\xb3\xdb\x72\x3e\x54\xca\xdb\x98\x0b\x69\x5b\xc4"
+  "\x31\x04\x41\xb6\x42\x59\x75\xf5\x25\x2f\xba\xb6\x8d\xb5\xe3\x43"
+  "\x15\xb6\x03\xfb\x44\x70\xff\x6a\x8c\x7b\x20\xe6\x83\xef\x55\x73"
+  "\x4a\xba\x30\xff\x7e\xd9\xb9\x0c\x79\x7c\x65\xde\x81\x5c\x29\xf6"
+  "\x3d\xab\x20\xde\xc9\x97\x8f\xc5\xcc\xba\x67\x8e\x2e\x69\x45\x7c"
+  "\x62\xf2\x92\x5b\x74\xf1\x89\xf1\xc9\xf1\x0b\x12\xe2\xd7\x2d\x48"
+  "\x8e\x5f\x9e\x38\x7e\xd9\x82\xdf\xc5\x2f\xd2\xad\x59\xb0\x52\x17"
+  "\x9e\x72\x7d\xca\x70\xe2\xcc\xfa\x2b\xdd\x82\x95\x2b\x57\x2d\x5b"
+  "\x1c\xab\x4b\x8c\x5f\x34\x61\xc5\xe2\x95\x8b\x93\x75\x0b\x56\x2c"
+  "\x5f\x95\x18\xab\xbb\x3e\xf6\xa6\xeb\xc3\x6f\x8d\x1d\x2e\x1f\x43"
+  "\x1b\xab\x21\x4d\xfc\xd9\xc6\xc6\x2d\x67\x49\x50\x88\x22\x69\x45"
+  "\x48\x4a\x7c\x22\x1b\xb3\xfb\x68\xd5\xc4\x6d\x24\x09\xce\xab\x70"
+  "\x6f\x64\x9a\xf3\x61\x36\x7c\x2a\x31\x1f\xb4\x53\x07\xdf\x31\xb6"
+  "\x0d\x6b\xcb\xf9\x68\x8a\x95\xfb\xb7\x4e\xd8\xf7\x18\xd2\xa1\x6d"
+  "\x61\xf4\x6c\x55\x23\xc4\x6c\x49\xf8\x6c\xbd\xe4\x2c\x09\xcd\x5f"
+  "\x4d\x94\x70\xa8\xe0\xd0\x70\x1a\x1c\xeb\xfa\x28\xc1\xca\xfd\x2b"
+  "\x9b\x8d\x7b\xfe\x4b\x65\x1b\xd6\x52\x46\xb3\x5b\xca\x98\x5e\xfe"
+  "\x35\x4c\x1a\x87\x8e\xca\x22\x51\x88\xcf\x13\xdc\xbf\x82\x04\x5d"
+  "\x01\x96\x71\x0c\xb7\x65\xff\xdd\x11\x10\x0f\x1e\xc7\x31\x58\x38"
+  "\x37\xac\x95\x23\x2a\xa8\x97\xf2\x83\x0d\xe1\xe4\x05\xb8\xd7\x4a"
+  "\x2d\xa5\x70\x8f\x3a\x69\x3c\x0d\xda\xa0\x81\xb6\xd4\x8b\xed\xf8"
+  "\xbb\xd0\x8e\x17\xe9\xb8\x6d\x23\xa1\x7e\xcf\x0b\xf5\xb1\x4b\x6d"
+  "\x80\x7a\xd7\x5b\xb9\x8f\x62\xa0\x9e\x1a\xac\x97\xa7\xb1\x3e\x1c"
+  "\xef\x82\x7a\x4e\xe7\x57\x83\xdc\xc6\xb0\xfd\xf0\xb6\x14\x33\xfb"
+  "\x83\xf6\x6c\x28\x81\xef\x79\xcd\x44\x95\x8b\xfb\x96\x67\x5c\x43"
+  "\x6b\x5a\xed\xc4\x12\x57\x4f\x42\xd6\x52\x1b\xdd\xdd\xd8\x28\xb6"
+  "\x29\x09\xb9\xe1\xef\x4b\xeb\x95\xd8\x26\xf0\x15\xaa\x92\x66\xaf"
+  "\x63\x8b\xca\x17\xae\xa0\xad\xf4\x15\x79\xcc\xf5\x2f\x61\x3f\x67"
+  "\x8c\xb7\x5a\x32\x70\xff\xeb\x7f\x99\xe1\xde\x5a\x31\x36\x6e\xa5"
+  "\x9d\xf3\x65\xb1\xd4\xbf\x10\x67\xad\x5e\xca\x0e\x92\xca\xc6\x3d"
+  "\xd2\xf1\x1a\xa6\xff\xa3\xd3\xe1\x1a\x9b\xb3\xfc\xa3\x3a\xf7\xf2"
+  "\xb1\x4c\xf8\x6e\x93\xee\xc3\xfa\xe1\x47\x31\x26\xb0\x01\x96\x6d"
+  "\x5e\xee\x37\xee\xf9\x17\xe9\x51\x0b\xa4\x6f\x39\x47\x94\x90\xf7"
+  "\x68\xc9\x8b\x42\xf9\x06\xb0\xa1\x06\x2c\xff\x99\x2b\x08\xc9\x84"
+  "\x3c\x2d\x39\xff\xd2\xb6\x0a\xfb\x95\x1f\x05\xfb\x37\x6b\xdc\xc7"
+  "\xb1\x45\x3c\xff\xca\x0d\xcf\x11\xcf\x63\x4c\xb8\x0d\xca\x07\x0c"
+  "\x6d\xf9\x1e\xfc\x30\xfc\xbe\x69\x1b\xd1\xe3\x7d\xe0\x7b\x1d\x8e"
+  "\x87\x40\x99\x36\xe9\x7e\x14\xf0\x9f\xc7\xb3\x31\x18\x11\x5b\xe3"
+  "\x71\xec\x3a\x2d\x85\xd2\x0f\x80\xdf\xb1\x8e\x88\xb1\xb6\x9c\x63"
+  "\xe3\x24\x4c\x01\xd6\x8f\x0a\xb8\x0a\x25\x7a\x9a\x73\x74\x7b\xc9"
+  "\x48\xc8\x07\xb8\x2a\x06\x3c\x21\xae\x20\xef\x1c\x09\x53\x80\xb5"
+  "\x3a\xcc\x07\x75\x18\xbe\x73\x5d\x84\x12\x39\xb2\x81\x3b\x76\x10"
+  "\x31\x46\xff\x70\x7f\x3d\xbd\xf2\xb1\x7a\xa6\xa7\x63\x07\x2d\xed"
+  "\x4c\x07\x4e\xb9\x1f\x2b\x90\xc9\xbd\x0e\x70\x3c\x1c\xe5\xcc\xc6"
+  "\xaa\x8f\x1d\x84\xba\xd5\x09\xb1\xf8\x46\xd0\x81\xe0\xab\x8e\x65"
+  "\xe2\xf5\xa2\x0c\xab\x9d\x32\x3c\x66\xf5\x24\x43\x37\xd9\x29\xd9"
+  "\x9e\xe8\xc7\x9a\xd0\x56\xda\x72\xfe\x1d\x2a\xed\x73\xee\x49\x97"
+  "\x70\x0f\xa5\x72\x1b\x09\xc2\x7b\x1c\x08\x15\xf2\x4f\xf3\x74\x0f"
+  "\x77\x1c\x1f\x28\x25\x04\xc7\xc2\xf1\xba\x71\xa1\x28\xd7\x7f\x6f"
+  "\xf0\xa8\xdf\x45\x2e\x75\x13\x0e\x9a\xf3\xef\xec\x17\x46\x02\x6e"
+  "\x58\xfd\xca\x7b\xaa\xdf\x38\x1d\xf3\x8b\xe6\xb1\x88\xe7\x7f\x9f"
+  "\xb6\x14\x10\x82\x69\xe2\xef\xe3\x2d\xe0\x6b\xdc\xc7\xf3\xbd\x3f"
+  "\x5f\xf8\x78\x82\xeb\xf3\x85\x8f\xc3\xbc\x3d\x5f\x70\xbd\xef\xc7"
+  "\xf1\x78\x5f\xbe\x64\xae\xc2\x79\xef\x8f\xe7\xf2\x1e\xee\x2d\x5d"
+  "\x7f\x53\xa9\xbc\xff\xf2\xf1\x1e\xac\x43\x2d\xf8\x25\x7a\xf5\x5c"
+  "\x05\x85\x72\x0e\x08\x3e\xfb\x63\x13\x8b\x57\x30\x0e\xfa\xb8\x00"
+  "\xf3\xb8\xb7\xa3\xeb\x2f\x28\xf4\x3d\xfc\x38\x27\xfc\x18\xfa\x1b"
+  "\xa2\xc1\xcf\x31\x5d\x79\x38\x97\xcc\x84\x7a\xf8\x01\xb1\xda\x35"
+  "\x42\x7e\x0a\x7f\x2c\x49\xfc\x6d\x13\x7e\x28\xbb\xf2\x77\x9d\xef"
+  "\xc3\xdf\x30\x56\x5f\xa1\xbc\x76\xa2\x60\xdf\x74\x5a\x59\x8e\x69"
+  "\x3d\x5c\x4d\x89\x74\x89\xa7\x3f\x1c\x59\x32\xcc\x85\xfe\xbe\x6e"
+  "\x8a\x90\x99\x52\xbb\x58\xbe\xf4\x9b\xca\x7f\x63\x8a\xeb\x6f\xf8"
+  "\x1b\x32\x5f\x76\x83\x6b\x86\xc4\x0a\xd3\xa2\xae\x4b\xe8\x4a\xe2"
+  "\x4a\x35\xf2\x5b\x6a\x88\x61\xa8\xf0\x25\x04\xff\x69\x87\xf2\xf4"
+  "\x70\x5e\x17\xdd\x95\xe1\x27\xad\xe9\xb2\xec\x47\x58\xf5\xaf\xdd"
+  "\xde\x43\x1b\xfd\xfd\x1b\x23\xfb\x7e\x0d\xfb\xb8\x36\xae\x1f\xcb"
+  "\xef\xf9\x4f\x57\x37\x4c\xfa\xea\x84\xc7\xb5\x4d\x9e\xb2\x3a\xe5"
+  "\x3f\x76\xa6\x94\x24\x47\xa8\xf3\xfc\xf5\x55\xae\xbf\x7f\x56\xe0"
+  "\xfa\xfb\x86\xc6\xfe\xa8\xba\x19\xff\x49\xb3\x8e\x00\x9d\x95\x77"
+  "\x25\x86\xb8\x99\x4c\x48\xbe\x9b\x09\x39\xff\xc4\xda\x0c\x21\xe4"
+  "\xc6\xa9\xb2\x64\xa5\xe7\xdc\xe7\xe7\x6f\x54\xba\x68\x10\xd7\xd8"
+  "\x34\xdd\x4e\xde\xe9\x96\x86\xbf\x2f\xd1\x89\x69\x37\xbf\xd7\x2d"
+  "\xbf\x90\xa6\x93\xfd\x56\x44\xc0\x3f\xa5\x80\xff\xf6\xee\x79\x07"
+  "\xff\x06\xff\x7c\xf8\x53\xa0\x7d\x0c\xfe\x9d\xa7\x3f\xca\xbc\x38"
+  "\x30\x91\xf0\x81\xff\xd1\x2e\xa2\xa4\xe2\x09\x2a\x26\x50\xf1\x4b"
+  "\xbf\xf8\xf1\xc1\xbf\xc1\xbf\xc1\xbf\xc1\xbf\xc1\xbf\xc1\xbf\xc1"
+  "\xbf\xff\x81\x3f\x85\xbc\x63\x8d\x63\xb2\x97\x8a\x9f\xf2\xfe\x8f"
+  "\x42\x3c\xe4\x69\x5c\x5f\xae\xa3\xe2\x1f\x31\x44\x98\x75\xa5\x31"
+  "\x56\x4d\xfe\x9c\xba\xf0\x9d\x49\xb6\xa0\xec\xc8\x2a\xfd\xf6\xb8"
+  "\x46\x6d\x41\x74\xfd\x14\x53\x4a\xbb\x32\x73\xda\x81\x71\x65\xb1"
+  "\x0d\xa1\xdb\xe6\x1e\x9d\x54\x9e\xdc\xaa\x32\xce\xac\x1e\xbf\x23"
+  "\xa1\x29\xac\x70\xfe\xf1\xa9\xfb\x36\xd8\xb9\x8c\xbb\xdf\x1f\xfb"
+  "\xea\xc2\x13\x23\x9f\x7f\xf0\xa3\x5b\xfe\xb6\xa2\x79\x78\xce\x8c"
+  "\xc3\x37\xfe\x65\xe9\xa9\x51\x2f\x3f\xfa\x9f\x5f\xed\x5d\xd7\x71"
+  "\xc9\xa6\xdf\xfc\xe3\xa7\xaf\x2f\x39\x79\xc5\x8b\x0f\xff\xfb\xd6"
+  "\xdd\xab\xcf\x06\xe7\xcd\xae\xbd\xe9\xed\xc4\x33\x63\x8a\x9f\xf8"
+  "\x7f\x77\xec\x4f\xe5\x15\xe9\x77\xbd\x77\xed\x1f\x17\x7c\x31\x62"
+  "\xeb\x03\x1f\xde\xfc\xd7\xa7\xbf\x1b\xb6\xf9\xbe\x43\x37\xbc\x11"
+  "\xff\xf5\x55\x2f\x3d\xf2\xc9\x6d\x7b\xd6\x9e\x1b\x9a\x35\xfd\xe0"
+  "\xf5\xaf\x2d\xfe\xf2\xf2\xdf\xcf\x3b\x36\x79\xd7\xaa\xef\xd5\xb9"
+  "\xb3\x6a\x26\xbc\xb5\xec\xf4\xe8\xa2\xc7\x3f\xbb\xfd\xdd\x8d\x8e"
+  "\x21\xcf\xdc\xf3\xc1\x75\x7f\x5a\xf4\xdf\x9f\xbc\xf0\xd0\xbf\x7e"
+  "\xf1\xf7\x95\x2d\x97\x3d\x77\xff\x91\x9f\xbf\xf9\xd4\x37\x57\xbf"
+  "\xf2\xd8\xa7\xbf\xfe\xbf\xf5\x9d\x97\x3e\x7b\xef\x3f\x7f\xf6\xe7"
+  "\xdf\x7d\x75\xe5\x1f\x7e\xfb\xf1\x2f\x2b\xd6\xb4\x85\x6c\x89\xb2"
+  "\x4c\x7c\x67\xf9\xb7\xd7\x94\x3c\xf9\xf9\x9d\x95\x69\xb4\x2f\xf2"
+  "\x23\xdc\xd9\x96\x81\xd6\x1b\xfb\xd8\x54\x15\xc8\xf5\x94\x53\x88"
+  "\x7a\x67\x09\x86\xc9\x44\x11\x44\x2e\x51\x06\xd0\x53\x08\xb4\xbd"
+  "\x5e\xfe\x74\xf2\xeb\x7d\xf9\xc3\xf7\xd1\xf0\x99\xe9\x2f\xe0\xb8"
+  "\x5a\x48\x71\xf6\xfe\xc7\x78\xbc\x62\x20\xfe\x14\xd0\xd6\x21\x50"
+  "\x93\xa1\xe4\x12\x90\x4e\x10\x19\x46\x86\x93\xcb\x88\x8a\xa8\x49"
+  "\x30\x09\x21\x1a\x32\x82\x8c\x24\x3f\x21\xa1\xe4\x72\x72\x05\xb9"
+  "\x92\x68\xc9\x55\x64\x14\xd4\x3e\x8c\x8c\xf6\x5c\x67\x03\x89\xd0"
+  "\xc2\x3f\xf0\xff\x1c\x12\x21\xfc\x8e\x19\x4c\x1f\xd0\x74\xb3\x98"
+  "\x5e\x27\xa6\x5b\x07\xd3\x07\x34\x5d\x77\x81\x3f\xaf\xbd\xa0\x9f"
+  "\x0a\x08\x0d\x58\x74\xe0\x12\x23\x74\xfd\xb9\xa7\x2a\xc4\xbf\xae"
+  "\xdf\xa4\x97\xeb\xbb\x95\xe7\x7a\xbd\xfb\x5f\xc4\xff\x1f\x10\x9b"
+  "\x40\x98\xf5\x0c\x0c\x90\xf9\x84\xff\xc8\xe0\xcf\x34\xc6\x43\x2c"
+  "\x82\x0d\xa0\xa9\x11\x0e\x06\x11\x30\x49\x18\x2c\x95\x01\x62\x0d"
+  "\x20\x06\x1a\xbd\xd4\x1c\x88\x9d\x81\xd8\x17\x66\x36\xd0\x51\x0d"
+  "\x0c\x8c\x4c\x3b\x80\x58\x86\x81\x91\x39\x04\x88\x5f\x30\x30\xb2"
+  "\x65\x30\x30\xb2\x6a\x30\x30\xb2\x23\xc6\xf3\x19\x05\x76\xc0\x5d"
+  "\xc9\xc8\x07\x15\x57\x00\xb2\x85\x1d\x90\x2c\x23\xb5\xde\xda\xe1"
+  "\x1a\xe2\xa1\x60\xa8\x67\xa2\x67\x62\x91\xa4\xa0\x1b\xa0\xab\x60"
+  "\x64\x60\x60\xa9\x6f\x68\xa4\x6f\x68\xa1\x60\x68\x6a\x65\x64\x66"
+  "\x65\x6a\xa1\x90\x5b\x59\x94\x69\x68\x90\x9e\xaa\x90\x96\x59\x94"
+  "\x5b\x9e\x58\x94\x4a\x84\xaf\x49\x06\x40\xaf\x30\xc8\xfe\x85\x38"
+  "\x13\x39\x86\x18\x19\xe4\x19\x98\x1e\x70\x30\x30\x7d\x5e\xc1\x00"
+  "\x97\x61\x9c\x00\xf5\x8a\x06\x14\xa3\x02\xc6\x1e\x60\x98\x76\x02"
+  "\xc3\xb0\x65\x01\x03\x63\x5d\x0c\x03\x63\xd9\x1c\x06\xc6\x35\x02"
+  "\x0c\x8c\x2b\x1e\x30\x30\x2e\x01\xed\xcc\x5b\xc2\xc0\x38\xf5\x0c"
+  "\xa6\xd8\xd6\x02\x88\xd8\x25\xa0\xde\xb3\x40\x7c\xec\x03\x03\xe3"
+  "\xbe\x3b\x10\xb1\xbb\x17\x18\x18\x6f\xec\xa1\x85\xd7\x29\x00\xa4"
+  "\xc6\x37\x23\x00\x3c\x25\xc4\xe8"
   ;
diff --git a/sys/dev/mxge/rss_eth_z8e.h b/sys/dev/mxge/rss_eth_z8e.h
index 61e5e929e2e..ef10b61f7c5 100644
--- a/sys/dev/mxge/rss_eth_z8e.h
+++ b/sys/dev/mxge/rss_eth_z8e.h
@@ -28,9380 +28,9635 @@ POSSIBILITY OF SUCH DAMAGE.
 $FreeBSD$
 ***************************************************************************/
 
-static unsigned int rss_eth_z8e_uncompressed_length = 544748 ;
-static unsigned int rss_eth_z8e_length = 149961 ;
-static unsigned char rss_eth_z8e[149961 + 1] = 
-  "\x78\x9c\xec\xbd\x7f\x78\x54\xd5\xb5\x3f\xbc\xe6\xcc\x00\x91\x06"
-  "\x66\x12\x23\x1d\x11\x75\x50\x68\xa3\xf2\x23\x2a\x5a\xb4\xa0\x51"
-  "\xa2\x85\x4a\x20\x28\xd8\xb4\xa2\x01\x0d\x18\x34\x42\x48\x22\x04"
-  "\x0c\x99\x30\xa0\x05\x1b\xc8\x24\xa6\x36\x4a\x48\x62\x8b\x2d\xb6"
-  "\xa8\xb4\xa5\xbd\xb9\xbd\x58\xc7\x12\xdf\x87\xde\x26\x99\xd8\x97"
-  "\xbe\x2f\xb7\x2f\xde\x0e\xdc\x48\x23\xdf\x00\x23\x19\xc8\x98\xcc"
-  "\xcc\xfe\x7e\xd6\xde\xe7\x24\x33\xc3\x04\xe5\xf6\x3e\xef\xf7\x9f"
-  "\xe6\x79\x26\xe7\x9c\x7d\xf6\x5e\x7b\xed\xb5\xd7\x5e\x7b\xad\xbd"
-  "\xd7\x5e\x87\xe8\x1f\xf8\xb3\x8c\xdb\xf6\x8f\x14\xff\xe7\xdf\x3f"
-  "\xff\xfe\xf9\xf7\xcf\xbf\x7f\xfe\xfd\xf3\xef\x9f\x7f\xff\x67\xfe"
-  "\xce\x69\x16\xfa\x83\x9b\xa8\xcf\x95\x64\xf7\xd1\xd9\xf2\x1f\xbd"
-  "\x22\x42\x48\x36\xf9\x28\xc9\xce\x57\xfd\x47\xb5\x48\xd7\xdc\x94"
-  "\x74\x83\x8d\x92\xe7\xec\x26\xaa\x1b\x27\x7a\x5e\x79\x55\xf8\xb7"
-  "\xbc\x2a\x7a\xb2\xde\x24\x6a\x9d\x44\xf4\xca\x38\x11\x00\x9c\xa5"
-  "\x3e\xfa\x6e\x17\xc3\xd9\x82\x67\x7e\xbf\x75\x9c\xf0\x23\xbd\xd4"
-  "\x47\xdf\x5b\xca\xe9\x9b\xc7\x01\x56\x1a\x91\xeb\x55\x11\x8c\x82"
-  "\x9b\xc4\xe5\x19\x66\xd6\x44\x89\xcf\x9e\x38\x38\x0c\xa3\x05\x30"
-  "\x8e\x5c\x02\x46\xb2\x81\x57\x40\x23\x13\xc3\xeb\x75\x91\x3d\xe0"
-  "\xf2\x5c\x85\xb2\x01\xb4\x29\x9d\xcb\x56\x23\x8f\x70\x91\xb9\xb5"
-  "\x2c\x44\x8e\x1b\xc8\x74\x92\xae\xf8\x14\x57\x0d\xd7\x8f\xb9\xbd"
-  "\x5b\x54\xb9\x49\x0c\x03\x65\x4d\x7d\xae\x2b\x32\x06\xcb\x02\xb6"
-  "\xa3\x82\x2c\xc8\xfb\xcb\x80\xe6\xd1\x54\x5e\xdb\x15\x7a\x5e\x0d"
-  "\x79\x97\x1a\x79\xd5\x3b\x6d\x9e\xfe\xee\x2b\x78\x57\x16\xfb\xce"
-  "\x52\xab\xbf\x4b\xc6\xbb\xba\x38\xfc\x2c\xde\xfe\x10\xa1\x1e\xc6"
-  "\xc5\xe1\xc3\xf5\x10\x7a\x46\xc7\x8d\x71\x6a\x45\xfe\x4a\xce\x9f"
-  "\xe5\x10\xa1\xc5\x0e\x92\xb8\x30\xed\x90\x77\xee\xa1\x66\x95\x17"
-  "\xf7\x13\xb8\xbc\x7e\xef\xc0\xbd\x4c\xd7\xeb\x4d\xe9\x73\x8d\x4e"
-  "\x8e\xc5\x89\x48\x7f\x97\x8a\x77\xe9\xb1\xef\x7e\x9f\xa1\xbf\xfb"
-  "\x2a\xde\x65\xc5\xbe\x33\x19\xe5\xec\x78\xb7\xcc\x78\x17\xdd\x4f"
-  "\x8a\xe3\x2c\xf8\x8d\x48\x22\x1a\x89\xdf\xa8\x24\xa3\xef\x4a\xec"
-  "\x22\xe2\xbc\x9a\x2c\x62\xa7\xc8\x8d\xb8\x04\x79\xcb\x82\xe4\x18"
-  "\x4f\xce\x13\x34\xba\x13\x70\x69\xe7\x46\x4a\x72\x16\x89\xa0\xb7"
-  "\xac\x87\x3a\xfc\x3d\xe4\xf4\x8b\x6e\x6f\xe8\x3c\x55\x9c\xa7\x24"
-  "\x6f\xe8\x34\x55\xac\x25\x7b\x6b\xf9\x27\x94\x88\x2f\x22\x9a\x20"
-  "\xe7\x04\x2e\xdb\x45\x1d\x0d\x5d\xe4\x6c\x88\x2d\xeb\xbc\x96\xec"
-  "\xed\x78\x06\xcd\xad\x8c\x47\xab\x23\x44\xa1\xb1\x22\xb7\xfc\x35"
-  "\xb2\x38\x27\x92\xd6\x9e\xef\xd1\x71\xf9\x4a\x3d\xe3\xb2\xf5\x14"
-  "\x25\xfd\x64\x25\xfa\xfe\x14\xf0\xad\x1d\x95\xfb\xee\xc6\xa0\x76"
-  "\xc8\x3e\x9f\x0e\xd9\x8f\x51\xab\x7d\x36\xb5\x96\x65\xd1\xce\x53"
-  "\x94\x7c\x28\x38\x8b\x5a\x2d\x0f\x62\x6c\x64\x91\xb7\x07\xf7\x8e"
-  "\x30\xf2\x04\xc8\xb1\x8e\xd0\xaf\x5f\xd9\x56\xf7\x0c\x25\xf9\x14"
-  "\x4c\xf4\xe7\x57\xea\x3e\x28\x25\x62\x9a\xf1\x73\xa2\x76\x94\x5c"
-  "\x4d\x76\xe0\xd7\x0d\x5c\xee\x02\x2e\xed\x93\xec\x94\x01\x9c\x47"
-  "\x79\xeb\x43\x64\x29\xa7\x2b\x86\x19\x13\x69\x11\x97\x1c\x9b\x3d"
-  "\x8d\xaf\x8a\x6e\xe6\xad\xde\x17\x72\x31\xbe\x92\x2d\xa8\x7b\x0f"
-  "\xd7\xb7\x13\x63\xd4\xf9\x06\x59\x7a\xd7\xe7\x9a\x9a\x5e\x15\x5d"
-  "\x78\xe7\x30\xde\x81\xdf\xbb\xf0\xbe\x7b\x7a\x1a\xd9\xbc\xa1\x4c"
-  "\x7a\xbf\xbf\xdb\xc2\x30\xc6\x06\xc8\xc4\xf0\xac\x65\x64\x46\x7b"
-  "\x46\x00\x9f\xcf\x9a\x90\x7e\x23\xf2\xa1\x3c\xfa\xff\xe5\xbd\x5c"
-  "\x5e\x7c\xf5\xb1\x40\xe4\xab\x8f\x9d\x8f\xfc\xe8\xb1\x5e\xf1\xa3"
-  "\xc7\xce\x85\x7f\xf4\xd8\x67\xce\x0d\x94\x14\xfe\xea\x63\xfe\x8e"
-  "\x22\xd9\x07\xb6\x8e\x22\xf4\x41\x98\x92\x36\x9d\x26\xdb\x13\x6b"
-  "\xd1\xf7\xa1\x8f\x69\xd3\x2a\xb2\x47\x52\x46\xa2\xce\xbf\xd0\x13"
-  "\xe5\x24\x70\xef\x48\xd4\xbe\xde\xd4\x51\xf5\x8a\x67\x93\xb8\x4d"
-  "\x47\x7d\xe6\x48\x0e\xd7\xeb\x4f\xb1\xd6\xe3\xd7\x80\x5f\x33\x7e"
-  "\x7b\x44\xea\xa8\x3d\xa0\x95\x73\xec\x66\x13\x35\xf6\x13\x4d\x8f"
-  "\x90\x09\x5d\x14\x00\xfe\xb6\x61\xe8\x36\x21\x52\xfb\x90\xed\xeb"
-  "\x95\x54\xd1\xd7\x57\x40\x2c\x53\x58\x9e\xb0\x7c\xe9\x73\x8d\xc9"
-  "\x44\x3d\x6e\xc9\xfb\xaf\x8a\x80\x48\x7d\xc8\x86\xf4\xee\xc0\x0b"
-  "\x05\x26\xff\x0b\x05\x5a\x6f\xea\x43\x57\x22\x4f\x3e\xf2\x1c\xd6"
-  "\x69\xd8\xcd\xb0\x30\x4e\xfc\x63\x42\x64\x06\xcc\xa2\x7f\xb9\x70"
-  "\xd4\xb2\xfb\x55\x71\x0c\xf9\xaa\x06\x61\x01\x36\xe0\x80\xfe\x63"
-  "\x9a\x8d\x34\xd0\xba\x6b\x07\xf2\x71\x79\x6f\x30\x93\xe5\xae\xcf"
-  "\x5b\xd8\x4d\xd6\x10\x8d\x16\x03\xaa\x3e\xe4\xe9\x66\xf9\x38\x26"
-  "\x48\x23\xfb\x5c\x94\xc3\xb0\xb9\x9c\xb7\xa7\x9b\x50\xee\x4a\xe1"
-  "\x2c\x80\x5c\xa2\x05\x7d\xa2\xc0\x04\x59\xdc\x75\x08\xe5\x55\xdd"
-  "\x63\x93\x0c\x1c\xb9\x0e\xee\x6b\x89\x27\xf8\xe1\x50\x61\x90\xc6"
-  "\xd4\x93\x19\xe5\x1e\x61\x78\x0c\x0b\x7c\xe0\x43\x5b\xaf\x3c\x54"
-  "\xe8\xa7\x88\x88\x81\xe9\xd3\xe1\xe5\xc6\xc0\x43\xba\x00\x3c\xe6"
-  "\xbf\x56\x94\x19\xd3\x2c\xe1\x3d\xfc\x2f\x11\x86\x17\x24\x8b\x43"
-  "\xe2\xfb\x28\xc3\xe8\x63\x99\x06\x98\x9e\x75\xf7\x53\x0f\x8d\xf5"
-  "\xf8\x9d\x05\xe6\x8e\x72\x22\x2e\xff\x6e\x45\xf7\x08\xd1\x9b\x6b"
-  "\x66\x9e\xe3\xf7\xde\xd0\x39\xce\xf3\x86\xe8\x2d\x30\x8f\xe9\x21"
-  "\x0b\xe3\x8c\xf2\x65\x8c\x67\x74\x5f\x3e\xfc\xc0\xa3\xb3\xe9\xd1"
-  "\xac\x79\x59\xb3\x29\xfb\xbe\x39\xb3\x29\xe3\xae\xa9\x19\xb7\x7f"
-  "\x63\xe6\xed\x94\xf3\x9d\x87\x67\x53\xce\x82\xd9\xf4\x08\x7e\xb9"
-  "\x0f\xce\xc3\xc3\x9c\xd9\xb7\x66\x7c\x6b\x6a\xce\x9c\x79\x0f\xd0"
-  "\xa2\xc5\xb7\x65\xdc\x76\x1b\xdd\xf7\xc0\xfc\x5b\x33\x32\xf4\xeb"
-  "\xad\x19\x9c\xe5\x7b\x33\x1f\x78\x64\x6a\x4e\xf1\x9a\xd2\x35\x53"
-  "\x17\xcc\x9b\x13\x3d\x27\xa6\x87\x2f\x44\x98\xa6\x01\x71\x76\x2e"
-  "\x45\x20\x23\x1a\xd1\xd7\xf8\xf5\x78\x2a\x4e\x60\xac\xdb\x36\x35"
-  "\x72\x1f\x49\x39\x39\xf6\x18\xc6\xb7\xa5\xcf\x65\xdd\xea\x33\x8b"
-  "\x24\xa6\x15\xe6\x1e\xe4\xb9\x6a\x39\xde\x1d\xd7\x65\xf3\x08\xbc"
-  "\xdf\x13\xfb\x3e\xa5\x0c\xef\xff\xde\xe1\x20\xf2\xe2\x07\xfa\x06"
-  "\x20\xf3\x40\x47\x3f\xf5\x3a\x73\x47\x80\x8f\x4d\xa8\xa3\x0b\x63"
-  "\xb0\x13\x65\x7d\x51\x63\xbb\x0b\xfd\xd0\xe9\xd8\x48\xe6\x33\x64"
-  "\xfd\xd7\x8e\xd2\x4c\xe2\xfe\xf0\x96\xea\x30\xce\x0f\xc2\x18\x2d"
-  "\x61\xa0\x8f\x01\xe7\x88\x82\x63\x4b\x8f\x92\x03\x3e\x86\xb3\x13"
-  "\xef\x74\x58\xe1\x0e\xc8\x03\xc8\xeb\x27\x23\xce\x74\x12\x63\xc5"
-  "\xb2\xc8\x40\xba\x9c\x5b\x50\x6e\x99\xc1\xbf\xc8\x1f\x68\x2d\x42"
-  "\xbe\x9f\xcc\x35\xa1\xbf\x4d\x98\x3b\xd1\x16\x6b\x21\xf8\x38\x10"
-  "\xa9\xb5\xee\x15\x7d\xb9\xa4\xd2\x6c\xfb\x44\x2a\x9e\x6b\xad\x6f"
-  "\x09\x27\xd2\x36\xca\xb4\xb7\x39\x0d\x7d\x6b\xe6\x31\x28\x5e\x90"
-  "\xe9\x66\xd0\x62\x22\xf0\x3b\x1a\xe6\xf2\x67\x65\xf9\x51\x48\x33"
-  "\x21\xef\x5b\x91\x54\xeb\xcf\xc1\x2b\x9c\x86\xf9\xfc\xaa\x4a\xc0"
-  "\xfb\x45\x44\xe4\x92\xb0\x55\xcd\xc4\xfd\x3e\xcf\xc6\x1e\x3a\x59"
-  "\x44\x9a\x0f\xef\x22\x4e\xc0\x1c\x18\xac\xbf\x93\xcb\xa2\x2e\x4b"
-  "\xdf\x40\x01\xe6\x50\xdb\x11\xd6\x05\xc2\x8c\xcf\xd9\xc1\x3c\x1e"
-  "\xae\x93\xc7\x31\xfa\xa2\x07\xfd\x74\x45\x9f\x2b\x65\x7e\x5c\x3f"
-  "\xe5\x03\xce\x5b\xa0\xfb\x51\xc0\x38\x18\xe9\x45\x1d\x78\x06\x5c"
-  "\x4d\x87\x6b\xc0\x08\x28\x3e\x48\xa9\x8a\xe3\x83\x07\x00\xfb\x7c"
-  "\xd4\xfb\x7d\x71\xef\x6f\xc2\xfb\x7e\xfd\x3d\xc6\x53\x4a\x5b\x5c"
-  "\xfd\xdd\x78\x1f\x41\xfd\x01\x8c\x17\x33\xea\xcb\x69\x64\x3d\x6d"
-  "\x28\x7f\x28\x36\x7f\xaa\xbd\xd7\x65\x65\x19\xc2\xb2\x50\xe6\x6f"
-  "\xd2\x79\x55\xd5\x9f\x3a\x25\x2e\x3f\x78\xd8\x3a\x0a\xfc\xc0\xd7"
-  "\x2b\x91\x67\x14\x64\x91\x05\xf3\xc6\xb1\x43\xe5\xac\xb7\xa5\x2e"
-  "\x8d\xcb\x5f\x8e\x7c\xe3\x99\x8e\x92\x06\x67\x25\x0d\x72\x74\x3d"
-  "\x8b\xc7\x42\x12\xca\xb8\xe3\xca\xec\x47\x99\x1b\x22\x8a\x6e\xe6"
-  "\xbe\xde\x84\x65\x5a\xe3\xca\x74\xc9\xfe\x57\xf5\x58\x98\x5f\x8c"
-  "\x32\x52\xb6\x0c\xc4\xc0\xe0\xb6\x41\x1f\xbb\x32\x29\x16\x46\x5a"
-  "\x17\xea\xbd\x79\x87\x1a\xc7\x5f\x41\x9f\xdf\x86\xb4\xbf\x00\xee"
-  "\xdb\xcc\x27\xcc\xcb\x5e\x7f\x10\xb2\x6f\x6e\xb2\x9a\xc3\xaf\x5c"
-  "\x65\x2d\x27\xbe\x9f\xca\xf7\x0c\x5b\x0c\xcc\xd7\x79\xfc\xca\x55"
-  "\xb8\x72\xba\xac\x93\xc7\x96\x18\x78\x28\xa2\x60\x5e\xb9\x03\x63"
-  "\x50\xc3\x73\x58\xaf\xa3\x1d\xcf\x26\xf0\xe7\xcf\x21\x57\xc1\x93"
-  "\x73\x99\xdf\x66\x20\xfd\x43\xfd\xfd\x7b\x9c\x1f\xf7\xb7\xea\xf7"
-  "\xcc\x97\x3f\xd7\xf9\x12\x7c\x9e\xf6\x1b\x59\xb7\xe4\x75\x55\x3e"
-  "\xa2\xf8\x7a\x0e\xde\xbd\x81\xeb\x3c\x5c\x77\xe0\xba\x08\xd7\x55"
-  "\xce\xf3\x64\x77\x86\xa1\x47\xa8\xe7\x25\xb8\x3e\x8c\xeb\x7d\xb8"
-  "\x3e\x82\xeb\x54\x1e\x97\xfe\xf5\x05\x14\xc7\x13\x3d\x11\x35\x16"
-  "\x47\xa9\xfe\x48\x9b\xa0\x8f\x0f\x35\x3e\xcf\x0e\xa5\x09\x95\xa6"
-  "\x41\x9e\x0f\xa5\x0d\xcc\x65\xba\xe4\xa0\xed\x41\xae\x5f\x1f\xd7"
-  "\x23\x54\xbf\xa8\x3c\x11\x55\x4e\xef\x3b\x3d\x4d\xe5\x33\x45\xd7"
-  "\xe9\xa3\x2b\xdb\x2a\x02\x42\xe0\xda\xc2\x74\x45\xfa\x41\xd0\x04"
-  "\xfa\xcc\x95\x55\x4c\xa7\xa1\xfe\xbe\x32\x3d\xaa\xbf\xa1\xcf\xa6"
-  "\x05\x63\xfb\xdb\x96\xc3\x34\xe3\xfe\x36\xf0\x65\xdc\x31\xa7\xf0"
-  "\x3c\x35\x52\xe1\x6f\xcb\x81\x5c\xef\xe1\xbe\x37\x17\xf1\x78\xb8"
-  "\x6a\x96\x8f\xf6\x48\x99\xc8\xef\x02\x29\x0f\xb9\xb9\xbc\xb9\x50"
-  "\xbe\xcb\x85\xbc\x3c\x6a\xbc\xe3\xba\x79\x1c\x9a\x4b\xe5\xbb\x52"
-  "\xa3\x1c\x64\x66\xa5\x2c\x8b\x39\x8e\xe7\x7c\x9e\xbb\x31\x87\x76"
-  "\x23\x4f\xbd\x8f\xc6\xd8\x86\xb3\x6f\x44\x95\x28\x9a\x5a\x49\xda"
-  "\x8d\x95\x34\xc2\x1b\x3a\x46\x0b\x43\x22\x3c\x95\xe8\x0a\x6f\x68"
-  "\x16\xdd\x44\x94\xe2\x0d\x1d\x21\x34\x78\xa2\x37\x54\x87\x39\x72"
-  "\x2b\xbf\x7f\xff\x66\x32\x99\x70\x75\xde\x42\x9a\xc9\x1b\xda\x83"
-  "\xf4\x03\x74\x23\x59\x4c\xdf\x1a\x21\xfa\xbc\xa1\x19\x78\x2e\xa5"
-  "\x07\x47\x88\xbf\xe5\x85\xc9\x36\xff\x45\xe1\xf4\x86\xf2\xe9\xc1"
-  "\x17\x23\xc2\x1b\x6a\xc3\xbb\x42\x5a\x18\xfe\x5c\x2c\x0c\xf7\x09"
-  "\x91\x2c\x2a\x17\x86\xcf\xe2\xfe\x6f\x02\xb4\xc4\xf5\x7d\xfc\x9c"
-  "\xc2\x0b\x5d\x57\xec\x10\x45\x79\x1b\x34\x1a\xc0\xbc\x22\xc6\x88"
-  "\x4a\xb4\xcf\x3d\x20\x0a\xcc\x98\x13\xaa\x07\x06\x70\xdd\x29\x76"
-  "\xca\xe7\x2a\xd1\x0c\x38\xee\x69\x50\xfc\x19\x7f\x6f\xa8\x8b\xf2"
-  "\x20\x3b\x16\x6e\xf0\x0b\xc6\x7d\xec\x66\x41\x0b\x37\xbc\x2f\x20"
-  "\xb7\xac\x0b\x37\x38\x05\xde\x25\x01\x9e\xdb\x1b\xea\xe1\x3a\x9a"
-  "\x01\x6f\xb7\x84\x57\x25\x3c\xc8\xeb\xe7\x7c\xd1\x70\x18\x06\xe7"
-  "\x5d\x18\x26\x2b\xf2\x7b\x06\x76\x88\xfd\xf8\x75\x0e\xd4\x00\xaf"
-  "\x54\x4a\x8d\xb8\xd2\x3e\xe0\x39\x4a\xb8\xc9\x81\xe7\x8c\xcf\xc1"
-  "\x27\x92\x8e\x61\x1a\x25\x6a\xc8\x81\x3e\xcf\xea\x63\xf8\xb5\x94"
-  "\x23\xf1\xad\xa5\x85\x9f\xf3\x35\x95\x16\x0c\xa8\xf4\x6c\x4e\x0f"
-  "\x80\x6f\x71\x5f\x14\x50\xef\xd6\xa0\xdc\x62\x59\xce\x4d\x45\xc2"
-  "\x46\x95\xe0\x41\xf3\xc2\xb0\xa8\x64\x1a\x82\xae\x95\x4c\x47\xb6"
-  "\x5b\x50\x47\x91\x48\xa1\x4a\xe0\xe3\x46\xf9\x1f\x0f\x88\x74\xc6"
-  "\x6b\xff\xe7\x0a\xf6\xbb\x80\xb3\xb4\x8f\x61\xda\x68\x3f\x60\x79"
-  "\x42\x9a\x03\xf4\x10\xc1\x85\xa1\xcd\xa1\xbc\x0d\x64\xf6\x86\x3e"
-  "\xa4\xf4\xca\x4a\x93\xb7\xac\x14\xed\xac\x02\xcc\x7c\xbc\xa7\x2b"
-  "\x51\xd7\xfb\x80\xbb\x9f\xeb\x43\x1d\x1e\xc0\x7c\x0f\xb0\xf2\x19"
-  "\xa7\x7e\x17\xd9\xf0\xdc\xd9\xaf\xf0\xf3\x47\xdc\x26\x5b\xc4\x66"
-  "\x22\x83\x7f\x98\x77\x14\xdd\x98\x67\xde\xe6\x34\x9b\xc1\x27\x61"
-  "\x37\xf9\x6e\x21\xb2\x2d\x08\x88\x10\xf3\xca\x74\x2a\x32\x75\x04"
-  "\x8e\x80\xd6\x49\xd4\x51\x74\x80\x6e\x26\xb6\x9f\x02\xd4\x11\xa8"
-  "\xc3\xf3\x6e\x62\xfc\x3a\x02\x5b\xa9\xbd\x67\x0f\x2d\x28\x0a\x6c"
-  "\x0e\xdb\x4c\xcb\xda\x7b\xb2\x09\xe5\xdf\x07\x8e\x91\x27\x8a\x2c"
-  "\x95\x1d\x45\x01\x7e\x76\xb6\xf7\x80\x3f\xc3\x22\x1c\x72\x53\x67"
-  "\xc8\x66\x2a\x5a\x70\x5e\xf8\xb3\x7b\x2a\x47\x20\x6d\xc0\x6a\x12"
-  "\x21\x6b\x99\x53\xb4\xf7\x54\xd1\x13\xe7\xc9\xd4\x5e\x70\x40\xf2"
-  "\xe9\x13\x45\x45\x24\xcb\x9f\x0f\x59\x1f\xef\xa9\xa4\xc7\x0b\x68"
-  "\x2c\xf2\x9f\x65\x9e\x15\x63\x2b\xa9\xad\xab\x90\xb2\x4f\x87\xcc"
-  "\x0b\xce\x0f\x88\xb6\x65\x75\xd4\x5e\x50\xc7\xf4\x90\x76\x46\xf6"
-  "\xe9\x5e\xb1\xe0\x7c\x9f\x68\x2f\x78\x9b\xda\x96\x1d\xa0\xf9\x9f"
-  "\x78\xac\xe1\x1a\xf2\x45\x52\x4c\x14\xa9\x31\xd9\xc2\x29\xa6\x65"
-  "\xa1\x1a\xe0\x92\x62\x2a\x12\xb5\x26\x1f\xe8\x77\x85\xec\x8b\x54"
-  "\xd3\x7f\xe2\xde\x21\xfb\xd7\x66\xf2\x0b\xb7\x66\x1b\xa8\xd1\x48"
-  "\xf2\x7d\x8a\xc9\xef\x0d\xe1\x5a\xa3\x81\xc6\x48\x97\xfd\xa8\x39"
-  "\x24\xef\xa4\x6a\xd7\x73\xbf\x22\x6f\x06\x7e\x99\xf8\x41\xd6\x68"
-  "\xcd\x80\x95\xc2\x70\x23\x6e\x6d\x7f\xc4\xa6\x35\x0b\x9b\xe6\x81"
-  "\x5d\xa2\x75\x04\xf6\x50\x18\xb2\xb5\x23\x10\xa6\x05\x6b\x83\x80"
-  "\x8f\x3e\x28\x0b\x83\x9e\xc7\xe8\x89\xb5\xe4\xf4\x96\x1d\x23\xf1"
-  "\x7b\x37\xd3\xc3\xba\x60\xed\xfb\x22\x52\xa3\xed\xe7\xf7\x0b\xd6"
-  "\x3a\x61\x1b\x01\x4e\x8a\xe6\x89\xd4\x6a\x3e\x5d\x57\x62\x3c\xfe"
-  "\xc6\x78\x0c\xf4\x81\xc7\x30\x8f\xe3\xbd\x5f\xd4\x9a\x9f\xe4\xb9"
-  "\x23\xc2\x7c\xe7\x36\x2f\x13\x36\xb3\x27\x7b\x84\xf0\x87\x5f\x22"
-  "\xc9\x03\x91\x7b\x84\x60\xdb\x2b\xaf\x8c\x9a\xe5\x98\x0a\x8f\xaf"
-  "\x14\x29\x66\x8f\xa8\x31\x2f\x8b\xd4\x8e\xd4\x00\xc7\x2c\xd6\x73"
-  "\xd9\x91\x3a\xcf\x7c\x2c\xc7\x9e\xa8\x19\x49\x5f\xd6\xce\xef\x73"
-  "\x8d\x2f\xf7\xd1\x3b\xb9\x2c\xe3\x70\xbf\xcd\x47\xef\x4e\xd1\xef"
-  "\xeb\x7c\x54\x77\x4c\xca\x47\xc8\xb9\xa2\x0a\xba\xea\x14\x5d\x33"
-  "\x17\x34\x21\xdc\x27\xe3\x7e\xfe\xc2\x9b\xd0\x6e\xf7\xfa\x02\xf4"
-  "\x79\x1f\xcb\x1c\xe1\x9a\x01\x7d\x83\x32\xd1\xde\x24\xd1\x97\x9e"
-  "\x2c\x52\x6d\x77\x8a\x01\x3b\xdb\x92\x56\x3c\x8f\x05\x5d\x27\xe1"
-  "\x9a\xba\xfb\x02\xa5\xe1\x67\xdf\xed\x8a\x54\xb2\x4c\xc6\x7d\x86"
-  "\x58\x6f\x1f\xbd\x73\x1d\x4d\xb1\x06\x28\xa9\xc9\x15\xc9\xb5\x6e"
-  "\xb6\xb1\x4d\x95\xc6\xf7\xc2\xf5\x1a\x35\x5d\x20\x0b\xcf\x2d\x91"
-  "\x14\xd4\x57\x66\x15\xa2\x24\x9d\x9a\x8a\x21\x8f\x5c\x64\x6f\x72"
-  "\x89\xfd\xe1\xbe\x74\x8d\xf1\x34\x70\x61\xdc\x80\xe7\xb5\xc0\x73"
-  "\xe9\x92\x0d\x99\xf4\x61\x19\x25\x5c\x8b\xe8\x73\x5d\x33\xd8\xfe"
-  "\x61\xde\x37\x18\x34\x19\xe6\xfd\x41\x83\x4e\xc3\xd9\xfb\x3c\xce"
-  "\xc3\x17\x84\xbf\x7a\x35\x31\x2d\xec\xce\x90\xf8\x2f\xd8\x24\x95"
-  "\x15\x61\xba\x76\xe1\x86\xeb\x85\xd7\x2f\x3c\xde\xb2\xd3\x72\xbd"
-  "\xae\x09\x79\x2a\x42\x22\xc2\xf6\x2d\xdb\xb6\x75\x6c\xab\xd6\xd8"
-  "\xec\xa2\xc6\x96\xd6\xbb\x4e\x84\x1a\xa5\x3d\x3a\x21\xc3\x47\x77"
-  "\x14\xc9\xbe\x01\x6c\xcc\x85\x5d\xbd\x36\x5b\x1a\x60\xa7\x30\xec"
-  "\x8e\x22\xe1\x89\xa4\xd8\x26\x20\x1f\xe6\xbf\xdf\x19\xb6\x6c\x40"
-  "\x9f\xd7\x7a\xb6\xbe\xca\x73\xdb\x04\xcc\x7f\xd7\x2f\xbe\x68\x4d"
-  "\x48\xae\x2e\x12\xfa\xc5\x31\xb4\x28\x69\xd2\xd9\xc7\xf8\xb3\xe1"
-  "\x97\x99\xf8\xf5\xe0\xdc\xe8\x36\x15\xf5\xc2\xee\x72\x6e\xa2\x09"
-  "\xe8\x87\x6b\x4e\xd1\x84\x4f\x9d\x65\xe2\xa4\x70\x4d\xa8\xfc\xc9"
-  "\xc6\x20\x74\x82\x09\x01\x1f\x6d\x2e\x18\x76\x6e\x65\xb9\x78\x41"
-  "\x74\x57\xaf\x1b\xa4\xd9\xf1\x85\x1b\x22\x82\xef\x79\x9c\x35\x21"
-  "\x9d\xe9\xd1\xe7\xba\x76\x96\x41\x8b\x61\xe8\x6f\x11\x6e\x5b\xba"
-  "\xd2\x01\xaf\x6d\x10\x2e\x41\x9e\xeb\x78\x1d\xef\xda\xdd\x52\x0f"
-  "\x72\x6b\xd4\x0b\x39\xc2\xeb\x1d\xd0\x99\x03\x25\x76\x11\x04\x4c"
-  "\xb7\x8f\x26\xfb\x74\x3b\x2b\xe0\x0d\x3d\xc0\x32\x25\x21\xff\xf0"
-  "\x3a\xe9\x10\xfc\xeb\x0e\x76\x40\x23\x62\x99\x24\x6c\x0f\x1d\xa9"
-  "\x50\x78\x07\x19\xae\xa7\xe2\x1c\x75\xe1\x7d\x49\x40\x74\x0b\xf7"
-  "\x43\x87\x59\x0f\xf1\xac\xeb\xe7\xb4\xf7\xc0\xc3\xc2\x53\xcc\x38"
-  "\x5d\xf7\x9e\xe7\xba\x7e\x3a\x09\x1d\x0f\xfa\x9d\x5f\xd9\x5c\xd7"
-  "\xed\x3d\x54\x4a\xba\x1d\x77\x1d\xec\xbf\xaf\xef\x35\xf0\x82\xec"
-  "\x10\xa0\x2f\xd3\xca\xcf\xf3\x2c\xaf\xa1\x95\x94\x8b\xa0\xa8\x31"
-  "\xf9\x91\x77\xb1\xd1\x06\x6e\x9f\x6a\xd7\x75\x05\xd1\xed\x02\x0e"
-  "\x7e\xe8\xcb\x92\x06\x25\x1b\x28\xc9\xa1\x68\x9d\xc4\xed\xe5\xb6"
-  "\x70\x9b\x65\x5b\x70\xe1\x79\xc5\x1b\xba\x03\xfa\x97\x4c\x87\x7d"
-  "\x7f\xdd\x01\x1f\x7d\x2d\x4b\xe9\x56\xd7\x49\xbd\x2e\x61\x3f\xda"
-  "\xc8\xe3\xfc\x9c\xae\x73\x46\xc4\x89\x93\x74\x3d\xeb\xb4\x66\xbe"
-  "\xca\x39\x39\x08\xfe\xb5\x5d\x15\xe0\xb9\xd8\x5b\x7e\x1e\xf2\x5b"
-  "\xe6\xbd\x12\x79\xbb\x90\xe7\x56\x3d\xef\xad\x6a\x7d\x57\x5e\x47"
-  "\xf1\x15\x73\xf3\x7b\xe0\xdd\xb9\xbc\x26\x01\x3a\xbb\x8d\x67\x81"
-  "\x67\x5c\xd1\x57\x57\x05\x12\xe3\x62\xf6\x44\xd4\x58\xec\x41\x3d"
-  "\x5f\x65\x9e\x72\x6e\xa0\xab\xc1\x97\xc7\x2b\x36\xd1\x95\xcc\x4f"
-  "\x22\xc5\x36\x43\xd1\xfd\xfa\x3a\xe1\xaa\x24\x2f\xa4\x67\xd1\x3a"
-  "\xba\x06\xe3\x6f\xca\x29\xba\xfe\xad\xbc\x72\x07\x70\x25\xaa\x3e"
-  "\x43\x24\x65\x4d\x8a\x2d\xc3\x1b\xfa\x84\x9a\xce\xb0\xad\x75\xfd"
-  "\x61\x83\x17\x71\x7f\xe4\x52\x72\x01\x74\xcd\x54\xb6\x82\xe3\x3e"
-  "\x5e\x2f\x3b\x41\x8e\x29\xdc\x5e\xfc\x4c\x48\xbb\x56\x5c\x10\x4b"
-  "\x05\xeb\x6f\x98\xaf\x7c\xe4\xc8\xc5\x35\x53\xfe\x5c\xb4\x4c\x7f"
-  "\xce\x40\xbe\x64\x71\x21\xc2\x79\x32\x91\x36\x49\xb8\x4c\x3c\x26"
-  "\x0e\xf6\xb9\x1c\x39\x3e\x9a\xb9\x4d\xf5\x8d\x63\x02\xc3\x1a\x06"
-  "\x87\x0c\xf4\x2d\x31\x6f\x02\xd6\xbf\x3a\x2a\x4c\x8c\xc7\x0e\x39"
-  "\x2e\x00\xab\x49\x53\xf2\x19\x73\x63\x66\xa3\x2b\x52\x00\x59\x5c"
-  "\x10\xa9\xb5\x17\xc8\x7b\xfd\x1d\xe3\x81\xb9\x2f\x33\x31\xfc\x87"
-  "\x8e\x78\xc6\x33\x8f\x4f\x4c\x53\x70\x1e\x3a\xec\x19\x7f\x8a\x9f"
-  "\xaf\xe2\xe7\x80\xed\xea\x02\x6f\x7d\x26\xea\x3f\x85\x7a\x27\xa6"
-  "\x29\x1b\x60\xe2\x55\xbd\xa8\xa3\xcf\x35\x31\xcd\x47\xe9\x07\xd4"
-  "\xda\xe1\xd5\x05\xc3\x8c\x3d\x1b\x8f\x9d\xf6\x06\xd2\xc7\xf4\x0d"
-  "\xff\xca\xeb\x18\x68\x97\x23\x6c\xd3\x32\x75\xb9\xc1\x76\xd5\x57"
-  "\x4e\xd0\x0d\x2d\x1d\x05\x92\xbf\x31\x6f\x4e\x2c\x7d\x27\xe2\xd7"
-  "\x78\x7d\x57\x89\xaf\x1b\x5a\x2e\xfe\x4d\xdc\x83\xdf\x01\xfc\x3c"
-  "\xfa\x73\x1b\x7e\x3e\xdc\x67\x48\xba\xf5\xe6\xc3\xce\xb9\xa1\x05"
-  "\x73\x7d\x26\x3f\xfb\x68\xe2\x3e\xd1\x3b\x49\x8b\xe8\xf7\x8d\x9f"
-  "\xb1\x8d\x31\xf1\x28\xe8\x9f\xaf\xfa\x81\x61\x90\xa9\xd7\x26\x69"
-  "\x2e\x9c\xf5\x22\xd8\x5a\x11\x60\x9c\x93\x5a\xeb\x03\xe4\xf8\x1a"
-  "\xb7\xfd\x86\xe4\x92\x7a\xe1\x0f\x80\xf6\x7c\xe5\xb6\x1d\x6a\x08"
-  "\x11\xaf\x31\xf7\xb9\x6e\x98\xe4\xa3\x27\xeb\xa4\xcc\x4f\x7d\xc8"
-  "\xcf\xf0\x44\x8a\xe4\x07\x61\xb4\x5d\xc9\xb3\xab\x0b\xb8\x1f\xf1"
-  "\xfc\x5d\xb4\xdb\x7a\x86\x6e\x90\xfd\x79\x08\x6d\xdf\x0d\x99\xc2"
-  "\xb6\x53\x93\x94\xff\x37\x40\xfe\x3b\x5a\x8d\xf5\xd0\x1d\x78\x07"
-  "\xbb\xa9\xa7\xbd\x20\x48\x0c\x23\x0c\xd8\xd5\x72\x4d\xc8\x5e\xb0"
-  "\xa9\x47\x04\xdf\xaf\xe8\xb6\x60\x3e\x46\x7f\x5f\x5d\xc0\x75\x3a"
-  "\xa1\x07\x7b\x56\xcb\x7a\x33\x21\xab\x12\x8f\xb7\x41\xdc\x6e\x7c"
-  "\xef\xd0\x24\x29\x17\x1d\xd0\xb1\x32\x62\xfb\xe5\xc6\x83\xaa\x4f"
-  "\x6e\x4c\x8a\xed\x93\x1b\x0f\xe2\x37\x1f\xbf\x7c\xfc\x4a\xf5\xe7"
-  "\xe8\xdf\xcc\xa8\xfb\xad\x7d\xae\x1b\xb3\x30\xf6\x7d\x8a\xd6\x9c"
-  "\x06\x5c\x99\x07\x3e\xa3\x24\xb6\xbd\x79\x5f\x81\xd3\x99\x5f\x39"
-  "\x3d\x02\xbd\x04\xcf\xb9\x78\x6f\xe3\xb1\x58\x1d\xa1\x98\xf7\xde"
-  "\xad\xe0\xa9\x8d\xfd\x8c\xfb\x5b\x72\xbd\x60\xf3\xb6\x6d\xcc\x87"
-  "\xc8\xb3\xd4\x1a\xda\xb6\x0d\xf5\x1d\x30\xe8\x87\xb4\x06\x7e\x9f"
-  "\x58\x3f\xb8\xf1\xd8\xa0\x1e\x05\xfd\x92\x65\x4b\x0f\x4d\xea\x86"
-  "\xfc\x41\x5f\xd9\x97\xa9\x79\x63\xd2\xa7\xfc\x0c\xb9\x77\x1c\xf7"
-  "\x5d\xed\x90\x2f\xfd\xb5\xd6\xfa\x01\x8d\x46\xf5\x6b\x94\x19\xaa"
-  "\x5d\x5f\x15\x4a\x1d\xb5\xc7\xdb\x7d\x80\x3a\x42\xbf\x22\xc7\x33"
-  "\x12\xc6\xc7\x5e\xe6\xe7\x0d\x22\xfc\x6e\xff\x5e\xd8\x5a\x67\x3d"
-  "\x98\x67\xaf\x3f\x45\x93\x64\xdb\x7f\x70\x02\x33\xf8\x13\x12\xb6"
-  "\x4e\x8b\xf5\x05\x3b\x57\x8a\xd0\xce\x93\x18\x1f\x03\xf6\xd1\x3b"
-  "\xfa\x69\xca\xeb\x1b\x29\xa3\xa1\x9f\x26\x35\xf6\x53\xba\xf8\x7b"
-  "\xba\xd6\x00\x5d\xeb\x89\xf3\x36\xc2\xf8\xce\x1d\x5b\x44\x49\x8d"
-  "\x1b\x49\xf6\x79\xb8\x06\x3a\x57\x08\x3a\xd7\xd9\x74\x96\x73\x83"
-  "\x3a\xd7\xc0\x00\x74\x2e\xb7\xad\x5e\xf1\x85\xad\x7e\x4c\x01\x99"
-  "\x92\x97\x91\x0d\xf8\x39\xcf\xd0\xa4\x6b\x93\xbb\xa0\xef\xa1\xcd"
-  "\x3e\xbd\xbd\xb8\x66\x58\x0b\x68\x94\x6c\x2b\x64\xaf\xa8\xb1\x2f"
-  "\x1b\x76\x4e\xd5\x98\x77\x02\xbc\x07\x84\x36\x4c\xbe\x83\xf7\x31"
-  "\x0e\x8c\x0f\x5a\x4a\x1a\xc0\x77\x48\x2f\x9d\x28\x82\x48\x9f\xc0"
-  "\x75\xef\x47\x7a\x9f\x6b\x72\x96\xcf\x3c\x50\x3a\x9c\xbc\xb5\x6e"
-  "\x36\xe6\xfd\xc9\x1f\x0a\xad\x92\x79\xd1\xb7\x29\x24\xfc\xde\x33"
-  "\x3c\x06\x27\xb7\x2e\x2c\x14\x21\xc7\x6a\xde\x53\x9a\x7c\x80\xf7"
-  "\xbb\x78\x9d\xfb\x1d\xe8\x29\x5f\xb4\xc7\xc5\xb2\x1f\x3c\xe3\xb7"
-  "\x16\x02\x26\xf4\x7d\xe1\x4c\x8f\xd3\xbd\x13\xeb\xdd\xbc\x37\xfa"
-  "\x8a\xdc\x87\x9d\x0c\xfe\x79\x50\xea\x61\xac\xef\xb1\x0c\x84\xde"
-  "\x74\xe5\x49\xfa\xda\x4c\xb6\xeb\xfb\x5c\x5f\x9b\xe0\xa3\x39\xc6"
-  "\xbe\x9e\xdc\xdf\x45\x1a\x64\x4c\x56\x21\xa7\x95\x4e\x24\x7b\xa9"
-  "\x43\x74\x0f\xa7\xfb\xc8\x3d\x57\x8d\xbe\x8a\x32\xf9\x06\x1c\xcc"
-  "\x37\x3f\xef\xd5\x96\x2c\x41\x5a\x99\x01\x07\x79\xae\xc2\xf3\xb6"
-  "\xc1\x3c\xaa\x4c\x7d\x54\x99\x25\xbd\xda\xcd\x3f\x47\xda\xbe\xb8"
-  "\x32\x07\xe3\xca\xb4\x45\x95\xa9\xd4\xeb\xf1\xc5\x95\xf1\xc7\x96"
-  "\xf9\x3a\x5d\x8c\xdb\xd7\xd3\x62\xcb\x7c\x7d\x52\x5c\x99\x19\x17"
-  "\xe3\xf6\xf5\xb9\x71\x65\x72\xe3\xca\x14\x44\xd1\x92\xf7\x56\x33"
-  "\x90\x56\x1e\x57\xa6\x2a\xae\x4c\x83\xf1\x3c\xdc\x1e\x77\xc9\x6e"
-  "\xb2\x83\x2f\xbb\xb9\x3f\xa1\xb7\xf7\xf4\xfe\xe8\xd9\x3e\xbd\xec"
-  "\xd1\x04\xed\xea\x89\xab\x2f\x14\x5b\x5f\x7a\xf2\xc5\xed\x4a\x77"
-  "\xc4\x96\x49\xcf\x88\x2b\x93\x19\x55\xa6\x59\xd5\x93\xbe\x38\xae"
-  "\x4c\x7e\x5c\x99\xd2\x8b\xf9\x2a\x7d\x5b\x5c\x99\xfa\xb8\x32\x7b"
-  "\xbf\x80\x16\x3c\x1f\x2b\x5f\x84\x71\xac\xf3\xde\x8f\xb9\xfe\xa6"
-  "\x14\xb6\x65\x30\x97\xf8\x7f\xd2\x1f\x1c\xc1\x73\x0a\xcf\x3f\x87"
-  "\xca\x82\xd0\x97\xd2\x83\x3e\x9a\x56\x64\xcc\x41\xbc\x8f\xc9\xe3"
-  "\x59\xe9\xca\xe9\x47\x87\xd3\x29\xb9\x1e\xc3\x37\x81\xeb\x3a\x34"
-  "\x81\x75\xaf\x9b\xb2\x06\x75\x5b\xb5\x5f\x4f\x0a\xce\x4d\xaf\x31"
-  "\x1c\xae\xbf\x49\xed\x8f\x9a\x58\xb7\x3e\x54\x26\xcb\x94\x45\xe9"
-  "\xc3\x5c\x7f\xe0\xc0\xc6\xa0\x25\x16\x8f\x9b\x72\x2f\x81\x47\x32"
-  "\x74\x9c\x96\x0e\xe8\x1f\xbc\x0f\xd4\xde\x00\x5d\x06\xfa\x3b\xe3"
-  "\x76\x82\x6e\xf2\x49\xdd\x6a\x75\x3f\xf1\xbd\xb7\xfc\x6e\xb9\x4f"
-  "\xa4\x74\xcb\x9b\xed\xad\xa8\x9f\x75\xf0\xd6\xa2\x73\xd4\x2b\xf5"
-  "\x7f\xd6\xc1\x6e\x7e\xe0\x50\xb9\x1f\x78\xdd\x6c\x33\xf6\x4d\x7d"
-  "\x74\x73\x96\xd4\x1b\xdc\x0f\xed\xe7\x3d\x2c\x5e\xf7\x3d\x14\x98"
-  "\xc9\x79\xc0\xff\x37\x4d\x30\xda\x0b\x1b\x10\x63\xea\xa6\x9e\x4b"
-  "\xd1\x4c\xf5\xe1\xcd\x85\xb1\x3c\x39\x02\xbc\x72\x73\x65\x6c\xbf"
-  "\xdf\xec\x8e\xed\xf7\x9b\x9b\x63\x79\x52\x03\x4f\xde\x7c\x20\xae"
-  "\x4c\x6b\x5c\x99\x23\x51\x65\xdc\x7a\x3d\xdd\x71\x65\x82\xb1\x65"
-  "\x6e\x49\x8a\x7a\x46\x1b\x6f\xb1\x0f\xda\x30\x72\x4f\xfe\x96\xf4"
-  "\xa8\x67\xad\x4e\xca\xcf\x5b\x66\x19\x69\xbc\x8f\xd6\xf8\xaa\xda"
-  "\x13\xd6\xe1\xe5\xc6\x8d\x77\xce\x5f\x18\x8b\xc3\x2d\xe5\x71\x38"
-  "\x0c\x8e\xff\x6a\x65\x83\xfd\xe1\x24\x4d\xc9\x97\x3c\x84\x31\x82"
-  "\xf9\x7a\x21\x3f\x03\x56\x3d\xf2\x83\x0e\xb7\x1c\x8c\x83\xd7\x16"
-  "\x07\xef\x58\xd4\x33\xec\xa6\x5b\x7a\xa2\xda\x60\x33\xdb\xa5\x5f"
-  "\x0c\xf4\xb1\x29\x16\x23\x9d\x6d\x43\xe0\xdb\xed\x94\xf3\x4c\x26"
-  "\xfb\x3a\xa4\x9e\xa0\x5b\x3e\x63\x3b\x52\xc1\x9c\x12\x3d\xfe\x49"
-  "\xb5\x6b\x4a\x56\x2c\x1e\x53\x16\xc7\xe2\x31\x25\x3f\xaa\x5d\x01"
-  "\xeb\x66\x5a\x64\x0d\x3d\xfc\x5d\xd6\x71\xd8\x87\x46\xfa\x1c\x6c"
-  "\x82\x5e\x76\x9e\x6c\xec\xeb\x71\xb2\x94\xcc\xde\xb2\x6e\xd8\x64"
-  "\xb6\xba\x61\xf9\x29\xf5\x21\x8f\xee\x9f\xe2\x00\xfc\x56\x83\x1f"
-  "\x23\xb5\x0f\x79\x22\x35\x5f\x9d\x85\x34\xc8\xbf\x9b\x25\x1f\x8b"
-  "\xda\x71\xdb\x84\x33\xb7\x1e\xf4\x84\x7d\x33\xf5\x43\xdd\x1e\x38"
-  "\xc2\x3e\x0b\x90\x3d\xdd\x98\xdf\x93\xd5\xfe\xd6\xd4\xe4\x28\xbe"
-  "\x0e\x38\x36\xde\x2b\x4e\xd0\xd4\x8f\x78\xfe\xe7\x31\xca\xbe\x0f"
-  "\x87\x42\x7e\x62\x1b\xda\x1b\x3a\x25\x75\x34\xbc\xef\xd4\xcb\xce"
-  "\x8d\x2a\xeb\xd7\x6d\xdc\x6e\x7e\x37\x3d\x44\x96\x43\x01\x3f\x01"
-  "\x4e\x9a\xd2\xeb\xa6\x7e\x74\x08\xe3\x15\x65\xca\x8d\x32\x6c\x0f"
-  "\x73\x19\x6b\x29\x59\xa6\x95\x93\xc5\xb3\xf1\x84\x84\xad\xf7\x7d"
-  "\x37\xeb\xc7\xde\xf2\x6e\xf2\x06\x8e\xf2\xda\x94\x45\xed\x25\x4f"
-  "\xed\x34\x07\x29\xa9\xb7\xe6\xa1\xfd\x3e\xdc\x87\x6b\x1e\x6a\x01"
-  "\x6e\x9d\x3e\x9a\x22\xe5\x5c\x34\xed\x1e\x78\x20\xe7\xe1\x85\xd9"
-  "\x53\xbf\xf3\xf0\xbc\xc5\x0f\xdc\xed\x58\xbc\xea\xb9\x15\xf9\x53"
-  "\xd7\x3c\x5f\xea\x58\x5f\xbc\xaa\x74\xd5\xea\xa7\x1d\x19\x65\x93"
-  "\xcb\x1c\xcb\x4b\xd5\x35\xbd\x70\x79\x49\xe9\x6c\xbe\x9d\xe2\x28"
-  "\x2a\x5e\xb1\x4e\xde\xde\x34\x9a\x62\x81\xac\x2a\x5d\x51\xec\x98"
-  "\x9c\x3f\xc5\xf1\xe0\xf2\x55\x85\xcf\x17\xaf\x48\x08\xeb\x6e\x47"
-  "\xf1\x8a\xe2\x15\xcb\xf3\x1d\xb3\x1d\x19\x0c\x39\x1a\x5c\x54\x7f"
-  "\x66\x18\xf3\x18\xcf\x5f\xd5\x2e\xd1\xa9\xcf\x67\x3e\xc5\x3f\xd3"
-  "\xf6\x5c\x3c\x97\x4d\x6b\x89\xe5\xb9\x69\x87\x63\x79\x6e\xda\xd1"
-  "\x8b\xe7\xb2\x69\x71\xf3\xdf\xb4\xb8\xf9\x6f\x7a\xf2\xc5\x73\xd9"
-  "\xf4\xb8\xf9\x6f\x7a\xdc\xfc\x37\x7d\x70\xfe\x03\x2f\xf9\xb6\x48"
-  "\xb9\x30\x3d\x6e\xfe\x9b\x1e\x37\xff\x4d\x2f\x8d\x7b\xde\x1a\xf5"
-  "\x7c\x25\x9e\xeb\xa2\xe7\x47\x3c\xef\x31\xc6\xe7\x90\x7c\x99\xde"
-  "\x62\xe4\x61\x59\x0f\xd9\xdc\xa5\xe7\xed\x8c\xca\xdb\xad\xe7\xed"
-  "\x1a\x1c\x7f\xe0\x23\xf6\x11\x51\x76\x77\xc6\x3c\x96\xe9\xec\x1f"
-  "\xc2\x73\x13\xc6\xc7\xf5\x67\x68\xfa\x07\x0c\x8b\x79\x58\xae\x1f"
-  "\xfe\xe8\xb1\xbe\xa6\x54\x4a\xe2\x32\x4d\xb5\x64\x11\xae\xa9\xc7"
-  "\x70\x25\xa4\x25\xe3\x07\x99\x92\x91\xe9\x33\x87\xf4\xb5\x98\x0c"
-  "\xb7\xd4\xf7\x51\x46\x87\x5f\xc3\xcf\x80\x63\x47\x99\xa4\x6a\x35"
-  "\x17\x77\xe1\x3e\x99\x79\x1a\xe5\x2d\x42\x9b\x36\x11\x57\x42\x9a"
-  "\x0d\xbf\x34\xc0\x73\x1b\xf0\x78\x1f\x2c\xd1\xf8\x8f\x5f\x5f\x1e"
-  "\xb4\xf9\x34\xb2\x56\xbb\x22\x47\xbd\x11\xd6\xab\x33\x5a\xd5\x1a"
-  "\x81\xb5\x45\xb8\xde\xcf\x6d\x42\x7a\x62\x1b\xe9\x56\xe8\x7f\x19"
-  "\x2d\x6a\xdd\xe4\x56\xf4\xff\x83\x5d\x6a\x6d\xd3\xda\x02\x79\xdb"
-  "\x7f\x92\x6e\x7d\x13\xd7\x01\x5c\xb7\x1b\xf0\x3d\xd2\x76\xbe\x95"
-  "\xd7\x3c\x1e\x61\xb8\x71\xe9\xb3\x20\xdf\xfa\xad\xa1\xca\xdc\x04"
-  "\xef\x72\x85\xcb\xfc\x70\x82\xf4\x22\xe8\x0c\xfd\x3e\xba\x75\x0f"
-  "\xe3\x1b\x95\xbe\x4d\xb8\xc6\x2e\xe6\xfc\x3e\xae\x0f\x65\x86\xd3"
-  "\xb5\x0d\x7f\x30\xe5\x77\x79\xeb\x91\xb8\x76\x7c\x7e\x92\x6e\x5b"
-  "\xa4\xda\x71\xdb\xdb\x71\x75\xf7\x24\x6e\xc7\x6d\x16\xb4\xe3\xf3"
-  "\xc4\xed\xb8\xcd\x21\x69\xab\xa1\x2d\xda\x45\xef\x66\xa1\x2d\x9f"
-  "\x4b\xba\xc7\xa6\x2f\xd6\x75\xa1\x00\x6c\x30\x5e\xd7\x93\x65\x1f"
-  "\x29\x1f\xea\x37\x3d\x5f\xb9\xb5\x9e\x72\x12\xd4\x59\x27\x5c\xa3"
-  "\x1e\xf1\xd1\x6d\x6d\x12\xce\x50\xfa\x3e\x85\x0b\xe8\xa4\x49\x3a"
-  "\xf5\x70\xb9\xe1\xfa\xdb\xb0\x4b\xd4\xba\xc6\x6d\xe0\xd9\x5b\xf7"
-  "\x1b\x6b\x92\x25\xe5\xc2\x6f\xd0\xb1\xcf\x75\xbb\x3d\xee\x5d\x30"
-  "\xea\xdd\x8c\x98\x77\x9b\x06\xd3\xe7\x1b\xe9\x5f\xae\x9f\x6e\x2f"
-  "\x8f\xeb\x27\xf4\xcf\x8c\x31\xb1\xed\xbe\xbd\x4a\xb5\x0f\x7d\x74"
-  "\x11\xad\x6f\xdf\x8b\x3e\x1a\x48\xdc\x47\xb7\xb7\x26\xe6\xb5\xdb"
-  "\x8f\x49\x78\xa9\x94\x08\x5e\x10\x7d\x37\x20\x79\x50\xef\xa7\x8b"
-  "\xfb\x67\xc6\x04\xa3\x7f\xbe\x5c\x1b\x67\x2c\x8b\x6b\x63\x18\x30"
-  "\x3e\x56\x6d\xbd\x63\x6a\x1c\xec\xb2\xc4\xbc\x38\xc3\x8d\x76\x86"
-  "\x13\xb7\x73\xc6\xbe\xe1\x79\x71\xc6\x61\xb4\x27\x7c\x31\x2f\xa2"
-  "\xfb\x64\x19\x4a\x54\x26\x24\x5c\x89\xea\xb9\x23\xcd\x19\x62\x3d"
-  "\xf7\x8e\xf9\xbc\x86\x14\x95\x3e\x25\x96\xff\xd0\x06\x2e\xc7\xf4"
-  "\x0b\x29\x39\xcb\xfd\x70\xd2\x41\xda\x17\xf1\x64\x9f\xeb\x8e\xaa"
-  "\x38\x5a\x9d\x3d\x49\x77\x8e\xe9\xd5\x4c\x7b\x14\xbd\xee\xfc\x28"
-  "\x0e\xa7\xbd\x89\xe9\x75\x87\x07\xf4\x3a\x9b\x98\x5e\x77\x1c\x1b"
-  "\x9e\x5e\x77\x70\xff\x9f\xbd\x98\x5e\x77\xda\xa2\xe9\x05\x5d\x57"
-  "\xb6\xef\x46\x3b\x78\x63\x20\x4f\xf0\x1a\x1c\x68\x62\xb3\x82\x57"
-  "\x54\x99\x1e\x2e\x93\x65\x0d\x2a\x3e\x81\x0e\x99\x74\x86\xee\x9c"
-  "\x62\x8c\xff\xb1\xf5\x34\x4a\x0c\x3c\x26\x00\xcf\xc4\xe5\xbc\x65"
-  "\x67\x3d\xde\x50\x06\xb1\xfd\x11\x57\xef\xb6\xc4\xb2\xe0\xce\x66"
-  "\xd0\xb4\x36\x41\x7a\x8b\xf2\x09\xb9\xd3\x1f\x2b\x23\xee\xec\x8c"
-  "\xed\x23\xd0\x0d\xe5\x68\xc8\xa7\xfd\x92\xbf\x4b\xf7\xd9\x37\x32"
-  "\x2f\xee\xb3\x6f\x1c\x57\xfd\xf5\x8d\x0f\x62\xf1\xfb\x46\x6e\xe2"
-  "\xfe\xfa\x46\xd1\xf0\xfd\xf5\x8d\xaa\xe1\xfb\xeb\x1b\x7b\xb9\xbf"
-  "\x7c\xf4\x0d\x5f\xec\xbc\xf1\x0d\x4f\x6c\x7b\x51\x2f\xca\x09\x6d"
-  "\xe4\x95\xfc\xfc\x65\xdb\x6d\xfc\x58\xc6\x71\x5f\x35\x55\x10\x78"
-  "\xd9\x34\x91\x71\xbc\x5c\x18\xc3\xc2\x06\x0d\xdd\x1b\x13\xef\x8f"
-  "\xb2\x8d\xdb\x51\x4f\xbc\x17\x4e\x8e\xeb\x58\x77\x9f\xf9\x9b\x88"
-  "\x46\x47\x71\xaf\x9d\xa4\xbb\x37\x47\x34\xad\x9c\xfd\x2c\xa5\x7f"
-  "\xa5\x5c\x43\x98\xd9\x16\xdd\x17\xec\x8b\xc3\xb6\xe9\x4e\x65\x3b"
-  "\xfd\xed\x24\xdd\xb5\x44\xf5\xcb\xdd\xcb\x63\xe9\x38\xd3\x9f\xb8"
-  "\x5f\xee\x4a\x42\xbf\xfc\x2d\x71\xbf\xdc\x35\x69\xf8\x7e\xb9\x8b"
-  "\xd7\xc6\xff\x76\xf1\x38\xba\x2b\x57\x1f\x47\x5b\xb8\x8c\x63\x35"
-  "\xdb\xe3\x77\xfd\x91\xf3\xe0\x1e\x63\xe4\xae\x5f\xf2\xfb\xa9\x3d"
-  "\xc6\x38\x92\x65\xaa\x00\x4b\xd6\xaf\xe7\xd9\xa6\xc3\x88\x86\xbb"
-  "\xdf\xda\x93\x68\x9c\xdc\x75\x98\xf3\x4e\x2b\xa2\x24\xd0\x30\x77"
-  "\x37\xc3\x28\x26\x3a\x43\x77\x5f\xcb\xf9\x38\x7d\x5a\x20\x7a\x9c"
-  "\xdc\x15\x34\xf2\xb1\xac\x53\x79\xef\xf2\x8b\xbe\x02\xe2\x7c\xb1"
-  "\xb0\xef\xd6\xdb\x3f\x4a\xce\x23\x9c\x9f\xf3\xc5\xe5\x99\xab\xc6"
-  "\xe3\xdd\x55\xb1\xe3\xf1\xee\x65\xb1\xfc\x09\xfa\xa3\x5c\x04\x72"
-  "\x0e\xf7\x07\x80\xc3\x97\xe6\xaf\x4b\x8f\xcd\xbb\x8f\xc5\x8d\x4d"
-  "\xf0\xc0\x37\x37\x29\x1e\xf8\xe6\xe3\x71\xb8\x06\x12\xf3\xc0\x37"
-  "\x93\x87\xe7\x81\x6f\xa6\x0f\xcf\x03\xdf\xcc\x62\x1e\xf0\xd1\x37"
-  "\xcb\x63\xc7\xe6\x37\x97\xc6\xb6\xfd\xee\x80\x1a\x9b\x94\x72\x39"
-  "\x63\x13\xba\xd0\x95\xc3\x8d\x43\x1e\x53\xa8\xdb\xd4\xd4\x6f\xec"
-  "\x67\x7c\x29\x9a\x25\x61\x5c\x01\xbf\x59\x36\x5e\x53\x82\x8c\x9f"
-  "\xc9\x34\x6c\x94\x67\x6d\x66\x4d\x8a\xa6\xe3\x4e\x75\xee\xc5\x89"
-  "\xbc\x6f\xf1\xfe\xb0\xa2\xe7\xec\xb5\xb1\xed\x9f\x95\x95\x98\x9e"
-  "\xb3\x96\x82\x9e\xce\xc4\xf4\x9c\x55\x36\x3c\x3d\x67\xd5\xb1\xcf"
-  "\xfe\xc5\x63\x6a\xd6\x3e\xc7\x3a\xa9\xa3\xc8\x32\x67\x68\xf6\x88"
-  "\x2f\x37\x3f\xcd\xea\x8a\x9d\x9f\x66\xb5\x5d\xfe\xfc\x34\x3b\x3d"
-  "\xf1\xfc\x34\x3b\x33\xf1\xfc\x34\x3b\x57\x8d\x87\xd9\xee\xd8\xf1"
-  "\x30\xbb\x28\x96\x27\x40\xbb\xff\xb1\xf9\x69\xb6\x2f\x6e\x0c\x54"
-  "\x9f\xa4\x7b\x96\x43\xa7\xa8\x54\xfd\x76\xef\xe4\x38\x1c\x43\x89"
-  "\xfb\xed\x9e\x34\xf4\x5b\x75\xe2\x7e\xbb\x27\x63\xf8\x7e\xbb\x67"
-  "\x3e\xfa\xad\xfa\xe2\x7e\xbb\x27\xff\xf2\x75\x8a\x7b\xea\x63\xfb"
-  "\xec\x9e\xca\xcb\xef\xb3\x7b\x8e\x25\xee\xb3\x7b\x02\x89\xfb\xec"
-  "\xde\x64\xd5\x67\xf7\x66\xc5\xf6\xd9\xbd\x93\x62\xfb\x6c\x76\xe8"
-  "\x1f\xed\x33\xf4\xcf\x41\xe5\x67\x70\xef\x9b\xb0\xdb\x47\xf5\xb9"
-  "\xee\x6d\xf0\x51\xa6\xbe\x87\x9b\xa9\xe6\x0e\xd5\x87\xef\x22\x8f"
-  "\xfb\xe2\x79\xe0\xde\x16\x3d\xed\x3b\x17\xf7\xc3\xbd\x47\x20\xa3"
-  "\x7b\x5a\xcb\xe5\xbe\x96\xea\x43\xa6\x39\xf2\x79\x36\xf2\xde\xd4"
-  "\xbd\x01\x2e\x8b\x3e\x16\xde\x60\x88\x58\xae\x23\x7f\x80\xe1\xf0"
-  "\x59\xa5\x58\x58\x99\x8e\xcb\x99\xe3\x87\xf7\x8d\xb1\x1e\xf4\x54"
-  "\xdc\x06\x78\xf7\xdd\xa1\x78\x35\x33\x5e\xff\x6d\xc2\xbb\x2b\x14"
-  "\x9f\xde\xff\x97\x38\x1c\xf6\x24\xe6\xd3\xcc\x83\x68\x43\x53\x62"
-  "\x3e\xcd\x3c\x3a\x3c\x9f\x66\xb2\xcc\x6c\x8a\xb2\x7d\x52\x9f\x08"
-  "\xf9\xe2\x6c\x9f\xfb\xec\xd6\x80\xe2\x1d\xa9\x13\xd5\x58\x0f\xf6"
-  "\xb9\xee\x8b\xd7\xff\xd0\x37\xf7\xbd\xa7\xe3\xfc\x9b\xb8\xf2\xc3"
-  "\xe8\x7f\xf7\xb1\xfe\xf7\x6e\x62\x9c\xef\xbb\x84\xfe\x77\x1f\xeb"
-  "\x7f\xef\x5e\x3c\xb6\xee\xd3\xf5\xbf\x44\x36\xde\x7d\xc7\x12\xf7"
-  "\xff\x7d\x71\xfd\x4f\xb9\xa5\xb0\x87\x65\xf9\x98\x7c\xf7\x4f\x88"
-  "\xce\xc7\x3e\x46\x9c\x97\x79\x24\x41\xde\xb9\xf1\x30\x87\xc9\x57"
-  "\x74\x11\xef\xb1\x4f\x54\x42\xde\xbb\xbf\x41\x8d\xc7\xfb\x03\xb1"
-  "\xe3\xf1\xfe\x03\xb1\xe3\xf1\xbe\xdc\xb8\x72\x47\x62\xdf\x83\x7f"
-  "\xfe\xc7\x64\xec\x9c\xac\x38\x1e\x78\xff\x24\xcd\xf9\x40\xf1\x40"
-  "\xd6\xd5\xb1\x78\xcc\x59\x9a\x98\x07\xe6\x94\xa2\xfd\xef\x27\xe6"
-  "\x81\x39\xee\xe1\x79\x60\xce\x3e\xd0\xf2\xfd\x68\xbe\x7d\xa4\x3c"
-  "\x73\x54\x5c\x9e\xce\xc4\x32\x6f\x4e\x77\xe2\x35\x82\x2c\x52\x34"
-  "\xce\x9a\x19\x4b\xe3\x2c\x7b\x2c\x0d\xd1\x96\x7f\x9c\x86\x83\x67"
-  "\x7d\xfb\x5c\x59\xf1\xe3\xdf\x7b\x92\x1e\xd0\xc7\xff\x83\x71\xb2"
-  "\x2e\x6b\x8f\xc2\x25\xd1\xba\x48\x16\xdb\xbf\xde\xc4\xb4\xcc\x3a"
-  "\x36\x4c\x9b\xd9\xa7\xcd\x1b\xb9\x68\x2c\x3d\x90\x8c\xf4\x47\x78"
-  "\x3d\x94\xd7\x43\x1a\x91\xfe\x48\x88\x92\xe4\x7c\x35\x38\x2f\x3d"
-  "\xc0\x67\x2f\x05\xd3\x9f\xf9\xd7\x3a\x81\x72\x78\x0e\x62\xbc\xf2"
-  "\xca\xa5\xcf\x82\x75\x2b\xf3\xfa\x0d\xcc\xeb\x0f\x48\xfd\x8f\xf7"
-  "\x59\xd8\x1f\xd0\x5a\x46\x39\xde\x40\x88\x0c\x7e\xe7\xfc\x71\xb0"
-  "\xab\x78\x5c\x70\x7e\x23\xaf\x5a\x37\xab\x8c\x93\x4d\x0f\x1c\x48"
-  "\xdc\xc7\x0f\xb4\x0d\xcf\x3b\x0f\x74\xab\x7e\x7e\x70\x42\x6c\x3f"
-  "\x3f\x08\xfd\x6f\xec\x62\x6e\x2b\x78\xe0\xb2\xc6\x49\xa9\x43\xf8"
-  "\x87\x95\xf7\x5b\x1e\x3b\x5a\x54\x41\xd7\x9d\xa2\x07\xb7\xca\xfa"
-  "\x34\x11\xb4\x6e\x36\x51\xab\x94\x01\x0f\xfe\x87\xc4\x13\x79\xf2"
-  "\x42\xa4\x89\x2d\xcf\x1e\xe5\x77\x4d\x2e\x11\x44\xbe\x4e\xde\x13"
-  "\xe0\xb3\x7e\xe0\x85\x2b\x4f\xd0\x83\xbb\x63\xca\x5b\x88\xbc\x0a"
-  "\xc6\xd1\x26\x39\x1e\x1f\x3c\x62\xac\xe9\x6e\x1d\xc6\x3f\x08\x79"
-  "\x82\x86\xef\x83\xf2\xfd\x7a\x70\xd8\xfd\x4b\xc6\x89\xfd\xe3\x19"
-  "\xa7\x4b\xcb\x81\x6f\xcd\x37\xf8\x57\xf9\x4c\x7e\x6b\xe9\x90\x4f"
-  "\xde\xb7\x0a\x7c\xf4\xad\x61\xcf\x73\xc4\x8e\x83\x6f\xd5\x45\xc3"
-  "\x51\xe7\xdd\xbf\xb5\xd7\xf0\xab\xc3\xfd\x81\x2f\x80\x65\xe0\x73"
-  "\x2c\x0e\x9f\x1e\xe8\x29\xad\x3a\x8c\xe0\xa5\x60\x70\x9f\x2b\x9e"
-  "\x65\x7e\x98\x6b\xbb\xd4\x9a\x9f\xd9\x4e\x39\xaf\x5c\xc4\x5b\x73"
-  "\xa5\xbe\xc4\x30\x2e\x8d\xe3\xdc\xca\x18\xdb\x42\xee\xdd\xf3\xde"
-  "\xd6\xbc\x6c\x35\xee\xe7\xc5\xad\x11\xce\x6d\x90\x7e\x53\xfa\xb8"
-  "\x7f\x22\x14\x3f\x0e\xe6\x1e\x34\xe6\xe8\xb8\xf4\x23\xc6\xb8\x87"
-  "\x5d\xcb\x70\xe3\xd6\x59\xe7\x06\xd4\x58\x98\x37\x3f\x92\x12\x6d"
-  "\xaf\xcd\x93\xfa\x9f\xb1\x5e\xea\x43\xbe\xd8\x72\xf3\xe2\xd6\xff"
-  "\xe6\x36\x88\xe1\xd7\xe9\x93\xd1\xbf\x01\xde\xdb\x52\x67\x87\xe7"
-  "\x95\xc7\xad\x57\xb0\x3f\x75\x8f\xa7\xe2\xaf\x80\xfb\x6d\x5d\xee"
-  "\x7d\xfb\xb3\xb8\xfa\x1a\x9c\xa7\x2f\xd5\xfe\x79\xc3\xb4\x7f\xde"
-  "\x50\xfb\x57\x4b\xb8\x71\x6b\x89\xf3\x64\xfb\xc3\x17\xc9\xbf\x6f"
-  "\x27\x43\x7e\x19\x74\x83\xce\xfd\xed\x15\x86\xae\xce\xeb\x07\xc3"
-  "\xeb\xea\xdf\x1e\x5a\xff\x53\xe5\x86\xd6\xff\xfc\x89\x74\x75\x1f"
-  "\xc9\xbd\xd5\xd8\xba\xb7\x59\x1b\x12\xb5\xe5\xdb\xc3\xac\xff\x7d"
-  "\x5b\x5f\xff\x7b\xc8\x16\x2b\xcf\xbe\xdd\x19\xdb\x87\xf3\xe2\xfa"
-  "\xf0\xdb\xfe\xd8\x3e\x9c\xd7\xf0\xdf\x9d\xd7\x78\xe2\x34\x9b\xcd"
-  "\x9a\xd9\xa4\x99\xcc\x78\x8d\x26\xd2\x28\xb3\xc5\x3c\x02\xbf\x91"
-  "\xfa\x75\x94\x66\xd6\x2c\xf8\x8d\xd0\xaf\x23\xe3\x9e\x47\x71\x59"
-  "\xfc\x2c\xfa\x75\x44\xdc\xf3\xc8\x2f\x78\x3f\x4a\xaf\xd7\xa8\xdf"
-  "\x12\xf7\x3c\xe2\x0b\xde\x8f\xfc\x07\xcb\xd3\x45\xcf\xb1\x7e\x68"
-  "\xf3\x56\xaf\x5b\x5e\xb8\x2a\x5f\xee\x17\xaf\x70\x2c\x7f\xea\xa9"
-  "\x15\x25\x25\x8e\xd2\x35\x8e\xfb\xef\x7b\xf8\xb6\xbb\x1d\x6a\xdb"
-  "\xb9\x70\xf6\xe4\xfc\xd1\x94\xbd\xbe\x98\x5f\x64\x3f\x32\x2f\xd7"
-  "\x91\x73\xff\x7d\xb1\x2f\x0d\x30\x72\x7b\xf9\x52\x50\xa2\xc6\x5f"
-  "\xe6\xf6\x71\x44\x55\xe3\xa4\xec\xe9\x6a\x6f\x26\x52\x6b\x1e\x8b"
-  "\x96\xb7\x41\x9b\x10\xfd\x4e\xe1\xb9\x81\xf7\xf4\xb3\xa5\x8f\xf0"
-  "\xd4\xe6\x4a\x2a\x5a\xc9\xe7\x4d\xb2\x6f\x15\xbf\xf7\x93\xe3\xdb"
-  "\xa4\x9d\xa0\x47\xd7\xb6\x42\xab\xe5\x67\x6f\x57\x88\x1c\x4e\x4a"
-  "\x42\xf9\x14\xbc\x33\x89\x7b\x22\x48\x0b\xe8\x3e\xcd\x39\x13\x65"
-  "\xda\xef\x2b\x8d\x7c\xd6\x93\x94\xfd\x17\xf1\x7b\x21\x9f\xc5\x3d"
-  "\x6e\x3d\x5f\xf6\x5b\x11\xd7\xfc\x02\x96\x0d\x0d\xb5\x64\x69\xac"
-  "\x25\x7a\x2d\x95\x92\x5e\x1b\xc7\x67\xe8\xb3\x1b\x8c\xbd\xd0\xed"
-  "\x78\xf6\xd1\xa3\x45\x5c\x37\xe7\x8d\x68\xf3\x6b\x65\xfe\xd4\x98"
-  "\xfc\x6d\x43\x7b\xb1\xd9\x0d\x1a\xf2\x2d\xfc\x84\xac\xc1\xd4\x51"
-  "\xf5\xde\xf2\x4a\xb2\x86\xc5\x67\xd3\xe6\x92\xa9\x03\xb3\xef\x86"
-  "\x90\x08\x79\x8a\x4f\xa1\xfe\x05\x57\x5b\x37\x88\xcf\xbc\x18\xfd"
-  "\xd9\x3d\x4e\xb1\xf3\x34\x59\x30\xae\x4d\x9e\x62\xf6\x53\x58\x40"
-  "\x8d\x9f\x93\x05\x34\x98\x70\x8a\x16\x66\x94\x67\x8b\xb0\x33\x9b"
-  "\x2c\xff\x5e\xc6\xfe\x86\xb6\x3b\x77\xfe\x99\x2c\xbf\xe8\xaf\xd4"
-  "\xfa\x85\x9d\xca\x4b\x45\xb7\xe0\xd8\x1a\x01\x11\x64\x7f\xfd\xb6"
-  "\x65\x61\xce\xf3\xb5\x3e\xa7\x9d\x3a\x4a\x03\xb4\xe9\x98\x08\x6e"
-  "\xfb\xb3\xf2\xf3\x6f\xef\x09\xb0\xff\x62\xd2\xa6\x6c\x32\x9f\xcc"
-  "\x25\xad\xbd\xa0\x9e\xbc\x4b\x03\x54\x7e\x4c\x74\xb7\x2d\xfb\x84"
-  "\x3a\x0a\xf6\x53\xde\x51\xd2\xda\xba\x3e\x26\x19\x1f\xa2\x76\x7d"
-  "\x65\xc5\x79\xb2\x6f\x5a\xc5\x69\xe7\x69\xe3\x26\x1a\xb3\xf1\x2f"
-  "\x64\xf5\x76\x1f\x45\x3d\xa7\xe9\x7b\x47\xc8\x04\x78\xda\x0b\x1f"
-  "\x93\xfd\x85\xef\xb2\x3f\x6f\x26\x35\x54\x90\x5d\x38\xd3\x93\xfb"
-  "\x9d\xe9\xb6\x7e\x91\x9e\xda\xe7\x4c\x4f\xeb\x28\x42\xfe\xae\xf7"
-  "\x68\xec\x51\x4a\xfb\xfd\xa9\xa3\x5a\xfd\x39\x9a\xe0\x58\xc0\xfd"
-  "\xbf\x70\x4a\xc3\x39\xe4\xaf\xcd\xa6\x08\xca\x46\x97\x09\xa5\x64"
-  "\xdb\xbd\xb9\x41\x8a\x00\x56\x7d\x3f\x4d\x68\xe8\x27\x7b\xa4\x26"
-  "\x9b\x98\x16\x03\xb5\xd6\x7a\xc8\xc2\x51\xef\x3e\xd9\x62\xf1\xb6"
-  "\xf5\x50\x7b\xa0\x9f\x3a\xe8\xaf\xe4\x2d\xfb\xbb\xe7\x17\x4f\xb6"
-  "\x8c\x88\x80\xf9\x3d\x1b\xbb\x00\x5f\xf1\x8c\xb3\x9d\xcf\x25\x56"
-  "\x52\x75\x05\x25\x17\x6d\xa4\x51\xa7\x90\xae\x6c\x7a\xad\xd9\x1b"
-  "\xfa\xbb\x67\xa3\xf4\xc1\x7d\xb4\xa8\xa2\x9d\xcc\x1d\x81\x7a\xf6"
-  "\xf5\xd4\xc2\xa9\xeb\x2b\xbd\x81\x4e\xf2\x16\xfd\xcd\x13\xb1\xad"
-  "\x2f\xa8\x8a\x50\xd2\xdb\x17\x3a\x35\xaf\xe5\x02\x79\x73\x03\xf4"
-  "\x3e\xea\x16\xb5\xeb\xab\x20\xaf\x32\x3b\x02\x41\x3e\x97\x94\x21"
-  "\x7a\xed\xa3\xab\x8b\x69\x4a\xe3\x39\x9a\xb4\xfb\x1c\xa5\x8b\xbe"
-  "\x74\x8d\xfd\x6a\x1f\x3f\x6d\xa3\xdd\xb8\x26\x77\x51\x12\xda\xab"
-  "\x7c\xaa\x53\x74\xff\xda\x81\x74\x6a\xea\x1f\xf2\xaf\xed\xef\x1d"
-  "\xf2\xaf\x05\x2f\x35\xb3\x8f\x2d\xc6\x45\x2e\xf3\x73\xf5\x19\xb2"
-  "\x6c\x39\x43\x34\xad\x52\x23\xc7\x93\x7c\x3e\x62\xd1\x08\x6f\xfe"
-  "\x69\x79\x7f\x82\x72\x0e\xe2\x9a\x8c\x9f\x09\x63\x40\xae\x67\x77"
-  "\xe9\x7c\x8b\x34\x0d\x69\x6f\xe2\x6a\xc6\x75\xb7\xb3\x41\xf8\x51"
-  "\x07\xfb\x33\x8c\x66\xfe\xd5\x7d\x79\x31\x2f\xe6\x40\xff\x59\x91"
-  "\x66\xf0\xb1\x92\xe9\xd9\xcd\xef\x9f\x3c\xcd\xf1\x5a\xfc\x12\x9f"
-  "\x81\x02\x13\xc7\x6e\xd1\xd3\x81\x43\x4e\x98\xeb\x45\xfd\x3e\x5c"
-  "\xad\xf8\x61\x5c\xe6\x94\x1a\x65\x7b\x07\x0a\xb8\xce\xf3\x48\x17"
-  "\x46\x3a\xda\x6b\xe1\x77\xbf\x3e\x79\x5a\x53\x79\xd2\x35\xc0\x0c"
-  "\xea\xf0\x31\xd6\xb3\xb3\x78\x4c\xf7\x6a\x56\x71\x28\x7f\x06\x35"
-  "\x8c\x13\x9d\xbb\x5f\x15\xad\x6a\xac\x2d\x9a\xe9\xa3\x95\x0e\xc6"
-  "\x11\xf3\x76\x6b\x15\xde\x1d\x72\x10\x31\x5d\x5a\x97\xb1\xff\xd8"
-  "\xa2\x5c\x1f\x8d\x3e\x16\xdd\x06\xe1\x7a\x68\x2e\xcf\x9d\xef\x54"
-  "\x78\x46\x08\x6d\xfe\xdc\x0e\x5f\x0f\xfd\xa2\xbf\x7b\x84\xf3\x8f"
-  "\xa4\x79\x43\x27\x68\x7a\x1a\xd9\x59\xff\x6b\x7a\x55\xf8\x70\xed"
-  "\x66\x7f\x4e\xf0\xc9\xb5\xa7\x68\xd1\x9b\xb7\xa4\x51\xda\x9f\xca"
-  "\x48\x97\x47\x8b\xde\x8b\x92\x47\x0f\xb4\x77\xb5\x44\xc9\xa2\x25"
-  "\xe7\x2f\x96\x45\x8b\x3f\x53\xb2\x48\x84\x94\xec\x09\xfb\xf4\xf4"
-  "\x8f\xe3\xd2\x75\xbf\x90\xc5\x1f\xc4\xa5\x07\xf5\xf4\xb7\xe3\xd2"
-  "\xfd\x2a\xfd\x91\xd3\x86\xac\xeb\x60\x3c\xd6\xb3\xac\x7b\xe4\x23"
-  "\x96\x75\x1d\xf9\xba\xac\x93\x3e\x86\x8f\xfc\x46\xfc\xb8\x92\xf8"
-  "\xec\x11\xee\x77\x30\xfe\xe2\xf7\x64\xe0\x7e\x05\xd2\xb2\x39\xcd"
-  "\xfd\x57\xb2\xe0\x27\xe5\x9c\x70\xcd\x7f\x97\xe5\x1c\xcb\x38\xf6"
-  "\x3b\xd9\x35\x4e\x1c\xdd\xf5\xaa\x38\xd2\xf0\xaa\x68\xeb\x73\x3d"
-  "\x7c\xd0\x90\x77\x3f\x40\x5a\x15\xd2\x7e\x80\xf7\x2c\xf7\x98\x26"
-  "\xed\xb9\x2d\x7c\x4e\xbf\x0b\x3c\x36\xc3\x6a\xa2\xa2\x9d\xe0\x79"
-  "\x3e\x0f\xb8\x15\xf4\xf5\x42\x26\xf1\x59\x2e\x19\xe7\x44\xcb\x80"
-  "\x8c\xea\xe2\xf1\x36\x6e\x0b\xc6\x97\xb7\xec\x13\xaa\x08\x88\x53"
-  "\x7c\x2e\x8e\x71\xc8\xdb\xf0\x6d\x8e\xe3\x61\x6a\x2d\x20\x62\x1f"
-  "\x70\xf6\x57\x81\xdc\xb5\xb8\x81\xd3\xa1\x42\xee\xeb\x47\x60\xff"
-  "\xbf\xa6\xcb\xdd\x47\x8b\x38\x2e\xd0\x09\x7a\x78\x1b\xec\xbb\x20"
-  "\xb7\xcd\x1a\xae\x24\x3e\xbf\x82\x31\xca\x36\x5e\xc1\x2e\xfc\xdc"
-  "\xc6\x19\x16\x8e\xed\x84\x3c\xde\xa3\x41\x62\x9c\x7d\xf4\xf0\x91"
-  "\xf6\xf2\x16\x2e\x5f\xc6\xb4\x11\x2e\xa7\x01\xc3\x24\xcf\xc0\xb8"
-  "\x28\x89\xcf\xc0\xf8\xe8\x91\x02\xa5\xd3\x58\xeb\xdb\x97\xfa\x89"
-  "\xe5\xbc\xb7\x1b\x30\xca\x4f\x28\x18\x80\x25\x20\xf7\x63\xde\xe9"
-  "\xf0\xc7\x6c\x12\x9f\x01\x7e\x16\xf7\x17\x9f\x5b\xe4\xfd\x35\xd0"
-  "\x25\x99\xfd\xe2\x95\xee\xf9\x70\x7b\x13\xe8\xaf\x9f\xbd\x04\xbf"
-  "\x3d\xdc\xc6\xe7\x8d\xf8\xbc\xa5\x3c\x6b\xa9\xcd\x20\xb1\x3e\x3d"
-  "\x79\xf0\xbc\xe5\xff\x0f\x67\x2d\x41\x7f\x7b\xa3\x26\xf6\x03\xff"
-  "\x36\x3e\x6f\x09\xfc\xa7\x30\x1f\xea\x6d\xea\xfc\xe1\xf7\x24\xcd"
-  "\xd3\x38\x0d\xb6\xe2\x61\xa3\xff\xb9\xbd\xdc\x96\x13\xb4\x28\xa8"
-  "\x74\x42\xd1\xe9\xa3\xc5\x9d\xfc\x1e\x69\x5d\x9c\x7f\x3a\xe4\x98"
-  "\x37\x3f\x4c\xef\x9e\x0c\x6b\xd5\x1b\xc9\xa2\x64\xda\x92\x4f\xb9"
-  "\xbc\x92\x69\x4b\x9a\x87\x64\xda\x92\x1f\x2a\x99\xa6\x68\xac\x64"
-  "\xda\x92\xed\x4a\xa6\x2d\xd9\x2c\xf7\xc1\x20\xd3\xf8\x1d\xcb\x35"
-  "\x43\xa6\xed\x1e\x27\x0e\xb3\xec\xe8\x73\x2d\x29\x32\x64\xdb\x0e"
-  "\xa4\xb1\xec\x60\x1c\x95\x9c\x7a\xe4\xb0\xf8\xff\xd2\x49\xf9\x19"
-  "\xf0\x7d\x01\x9f\x55\xe8\xd6\xef\xd1\x2f\x4b\x8e\x2b\x19\xb7\xa4"
-  "\x75\x48\xc6\x2d\x99\x3b\x54\x96\x65\xdc\x92\xff\x50\x32\x4e\xa5"
-  "\x37\x7d\x8f\x65\xdc\x23\x87\x99\x06\x3a\x7c\x8d\xd7\xec\xf4\xfc"
-  "\xa0\xe3\xa2\xce\x68\x19\x17\x3b\xbe\x1e\x9d\x60\xc8\x38\x96\x6d"
-  "\x78\x9e\x02\x99\x26\xe3\x8c\xf1\x38\xab\x03\xcd\x8d\x71\xc7\x7d"
-  "\xc0\x6d\xe6\xf8\x3f\x4c\xb7\x39\xa7\x69\x94\x7e\xee\x47\x6f\xf7"
-  "\xa3\x05\x86\xaf\xa3\x8f\x96\x14\x25\xd2\x9b\x0d\x3d\x0d\xfc\x78"
-  "\x7d\x18\xe3\xcd\x5b\x89\xb9\xb4\x5e\x54\x76\x84\x8e\xd0\x13\xa5"
-  "\xa4\x45\xcc\xcf\x1e\xe7\xbe\x85\x9d\x31\x92\xaf\x2c\x7b\x30\x87"
-  "\xbe\x9d\x17\xa0\x91\xb0\xcd\x8f\x57\x6b\x78\x57\x46\xdf\x8c\x7a"
-  "\xf7\x47\xae\x27\xaa\xdc\xd4\xa8\x77\x9f\x48\x1d\xef\x0c\xc7\x7e"
-  "\x7a\xd4\x3d\x9c\xed\x7f\x79\xb8\x7c\xe7\xae\xe1\x71\xf9\xce\x92"
-  "\xe1\x71\xf9\x8e\xd4\x03\xa6\xf6\x90\x09\xb6\x59\xca\x19\xfa\x8e"
-  "\x5c\x8f\x91\xb1\x2b\xb6\x24\xac\xe7\x0d\xfd\xfd\x88\xa8\xf7\xd1"
-  "\x75\x7d\x90\xa0\x7c\x74\x7d\xc7\x2f\x0d\x3f\xd7\x74\x69\xf8\xb9"
-  "\x13\x2f\x0d\x3f\xf7\x3e\x96\x81\xa0\x9d\x35\xa2\xc5\xe6\x9b\x16"
-  "\x92\x63\xf0\x30\x9f\xbb\x43\xbe\x55\xfa\x9a\xcf\x71\xe7\x44\x69"
-  "\x0b\xca\xb3\x59\x3b\xf1\x9e\xcf\x92\xb3\x7c\xce\xda\x40\xa4\xf6"
-  "\xa8\x07\xcb\xec\x8e\xc7\x6d\x6c\xc8\xc0\x4d\xbe\x7f\x2f\x1e\x37"
-  "\xbc\x9f\x1a\xf5\xfe\xe3\xa1\x7e\xcf\xbd\xa4\x7f\xbd\xb7\x9e\x88"
-  "\x63\xe8\x1d\x82\xf9\x82\x39\x99\xe3\x71\xe9\xeb\x33\xdf\x9d\x01"
-  "\x39\x5f\x19\xe5\xb7\xcb\x3e\x67\xd7\x77\x04\xf8\x9c\x6a\x40\xc6"
-  "\x4a\x41\x5b\xbe\x8a\xf9\x24\x95\xcf\xea\xf0\xb9\x9d\xbc\x70\x8e"
-  "\xa6\x62\xe2\x7c\xb7\xc8\x28\x3b\xdc\x3a\x10\xd7\xab\xd7\xc9\x3e"
-  "\xb0\x01\x94\xd9\x63\x94\x61\xd8\xec\x47\x89\x79\xe0\x7a\x79\x76"
-  "\x35\xd4\xc3\x72\xf7\xab\xd0\x93\x53\x55\x3d\xcb\x48\xaf\x07\x76"
-  "\xec\x77\x92\x2f\x75\x76\x64\xf8\xf6\x7d\x2f\xed\xf2\xdb\x47\x7a"
-  "\xfb\xbe\x97\xf3\x05\xed\xbb\x54\xbd\x55\x97\x5f\xaf\xcd\xa8\xf7"
-  "\xf0\xe5\xd3\xf5\x7b\xa1\x2f\x4f\xd7\x0c\x9d\xae\x8f\x65\x7c\x01"
-  "\x5d\x13\xd4\xf3\x58\xfe\x97\xaf\xc7\x61\xd4\x53\x9f\xa8\x1e\x92"
-  "\x7f\xc3\x9e\xeb\x4a\x32\x62\xd3\x71\x5c\x48\x15\x93\xea\x31\x5f"
-  "\x74\xec\x4c\x15\x2f\xf2\xb1\x80\x11\x3b\x53\x8f\x61\x89\xb9\x65"
-  "\x69\x4a\x5e\x33\xeb\x23\x22\xe2\xa3\xa5\x69\x1c\xf7\x30\x6b\x53"
-  "\x74\x8c\xc9\xa5\xe9\x97\x8a\xd9\xc9\xb1\x72\x84\xc8\xa5\x43\xf5"
-  "\xd2\x1f\x00\xf3\xd0\xd2\xe5\x7c\x3e\x40\xed\x67\x2e\x2d\x54\x63"
-  "\x72\x69\xa1\x8f\x1e\x6b\x19\x1e\xc6\x43\xfe\x3d\x15\x19\x23\x86"
-  "\xf3\xf9\x47\xf9\x7d\x3e\x7a\x5a\xae\x5f\x86\x6b\xaf\x2e\x13\x67"
-  "\xed\x7a\x2c\xae\xbc\x2b\xa2\x62\x85\x61\xee\x7e\xe2\x2e\xfd\x6c"
-  "\x02\x68\x50\x09\x5a\x2e\xed\x32\x68\x60\xa4\x23\x2d\x68\xd0\x00"
-  "\xfa\x4a\xb2\xb7\x39\xc4\x67\x87\x02\xea\xbc\xf7\xe3\xd7\x8a\x9a"
-  "\x87\x7c\x0a\xf6\xe3\x6a\x9f\x21\xf5\xea\xb2\xc0\x0b\x76\xcd\x28"
-  "\x3f\xc9\xe1\xfc\x9c\x79\xd8\x9f\xf2\x90\xaf\xcf\xf5\x78\x96\x01"
-  "\x5f\x30\x5e\x62\x28\x5f\x93\xf4\x4b\x7a\x1c\xfd\xff\xd8\x2c\xc9"
-  "\xd7\xa8\x43\xe2\xae\x91\x39\x02\xfc\xd1\x06\xcd\x5b\x14\x60\x3d"
-  "\xb5\x27\x8c\xf6\xb3\xac\x3b\xb0\xda\x67\xe1\x3c\x52\x77\x38\x9b"
-  "\xae\xa9\x38\x67\x8f\xbf\x17\x39\xcb\xf1\x36\x24\x5e\xc9\x68\x73"
-  "\x12\xe3\xe4\xc3\xd5\xff\x42\x3a\x2d\x3c\x4f\x3a\x2d\x1e\x7f\x33"
-  "\x82\xf4\x48\xc9\x10\x0e\x8d\xf2\x8c\xc7\xe3\xdd\x06\x0e\x11\xae"
-  "\xbf\xcf\xae\x41\x17\xe3\x7a\xbb\xe5\x39\x4b\xd4\x3d\x9d\xe3\x52"
-  "\x71\x2c\x8b\xf5\xe9\xc4\x38\xf4\xb9\x9e\x98\x60\xd0\x5b\x2f\x63"
-  "\xd4\xd1\x16\x91\x75\x2b\xda\x28\x3a\x1f\x82\x3e\xf8\xc4\xfc\x8b"
-  "\xe9\xfc\xc4\xb2\x28\x3a\x9b\x99\xaf\x78\x8d\x05\x7d\x14\x66\x7a"
-  "\xf3\xbe\x86\x63\x1d\xeb\x55\x4f\xd4\x1c\x0a\x48\xbf\x93\x64\x86"
-  "\x1b\x01\xfd\x19\x06\xe0\x7e\x45\xd1\xf8\x89\xbd\x83\x34\x46\xdd"
-  "\x02\x7d\xb1\x45\x9d\x49\x61\xdf\x77\xc8\x8e\x27\x0e\x0f\xd6\xc3"
-  "\xb8\x3a\xed\x5a\x44\xd8\x39\xae\x9d\x9f\x71\x2d\x75\x88\x20\xeb"
-  "\x95\xd2\x8f\x09\x6d\x3d\x50\x71\xd4\x02\xdd\x52\x93\x75\xf5\xa6"
-  "\xb3\x7e\x9f\x24\xef\x51\xd7\x30\xfc\xfd\x16\xc7\x8e\x33\xda\x85"
-  "\xb6\x24\x31\x6f\x01\x77\xe8\x7f\xcb\xc6\x48\x7e\x59\xc7\xfd\x94"
-  "\xf7\x19\xa7\x19\xf9\xf0\xfc\x21\xe7\x33\x9e\xf1\x0e\xfc\x95\xf7"
-  "\x22\xda\x35\x9a\xf1\xf4\x73\xbc\x3c\xd9\xe6\x65\xe9\x0c\xa3\xcf"
-  "\x95\xe7\x8e\x69\xe7\x40\xae\xc5\xe0\x3b\xde\x23\x6a\x75\x04\xa5"
-  "\xec\x54\xb4\xcd\x3b\x68\x8c\x49\x2e\xaf\xc6\x58\x5e\x67\x34\x2f"
-  "\x06\x9c\x43\x7c\x50\x3a\x91\x92\x2c\x0e\x8e\x77\x97\xb7\x5f\xc5"
-  "\xd5\xcd\x0b\xc5\xf7\x17\xbf\xe3\xd8\x70\x3a\x0d\x79\x3c\xd9\x4e"
-  "\x50\x9e\x9f\xdb\x86\x77\x59\x97\x9a\x2f\x39\x46\x1b\xc7\xdb\x7b"
-  "\x45\x8d\x23\xd0\x65\xf9\xaa\x57\xd4\xf9\x9e\x80\x8a\x91\xb6\xec"
-  "\x39\xa1\xbd\x21\xfb\x8b\xfd\xf2\x64\x3c\x0c\x19\x7b\x62\x19\xfb"
-  "\xb8\x89\xb1\x45\x6f\xc8\x58\x89\xba\xcf\x9e\xbf\xb5\x28\x24\xe3"
-  "\xac\x39\x4b\xf9\x1c\x6c\x88\x6d\x32\xe9\x93\x76\xa8\x34\x44\x8f"
-  "\x04\x99\xb6\xcb\x0e\xf2\x79\xf5\x80\xa4\xc5\xb2\xc3\xc6\x19\x75"
-  "\x8e\xfb\xc6\xb1\x04\xa7\x87\xc8\xcc\x3a\x85\xc3\xc9\xb1\x05\x96"
-  "\x37\xb3\x4e\xa2\x68\x0a\xbe\xd7\x44\xa7\xe2\xe5\xe5\x29\x1c\x9b"
-  "\x51\xed\x2f\x9d\x00\x7f\x9b\xff\x8e\xbc\x37\xa9\x75\x19\x63\xac"
-  "\x2d\x7f\x83\xf7\x98\x7c\x3a\x8c\x3e\xd7\x72\xcc\xff\x4b\xeb\x2e"
-  "\x1e\x17\xcb\x53\x0c\x1b\x83\xcf\xc5\xa9\xfd\xaa\x21\x78\x28\x2f"
-  "\xd7\xa5\x87\x64\xd3\x1f\x18\x56\xe5\xc5\x63\x66\x79\x9d\xc1\xcb"
-  "\x45\x37\xf0\xb9\xea\x65\xb9\x5c\xff\x70\x32\x53\x38\xbf\xcb\xfd"
-  "\x94\x74\xd2\x41\xe6\x2f\x3a\x2f\x31\xb4\xff\xb5\x3c\x68\xb4\xc1"
-  "\xa0\x89\x6a\xc3\x93\x8b\x7a\x53\xad\x9e\xa1\xb6\x3f\xb9\x48\xd2"
-  "\x62\xe8\xfd\xf6\x28\xda\xf0\xf3\x36\xc5\x77\x4f\xce\x05\x7f\xe8"
-  "\x6b\x36\x2a\x4d\xa4\x3e\xf4\x5f\x1c\xa7\x51\xe1\xb8\x8a\x0c\x7e"
-  "\x47\xde\x52\x1f\x9d\x4c\x57\xfb\x50\x4f\xa2\xfd\xcb\x3b\xf5\x72"
-  "\x13\x18\x97\x84\xed\x8c\xc1\xf1\x29\xe2\x39\x56\xc5\x2d\x78\xca"
-  "\xc4\xf8\x3a\xbe\xc6\x7d\xfc\x64\x3b\xd7\xcb\x3c\x21\x06\x0a\x46"
-  "\x04\x06\xd2\xa9\x77\xa0\x00\xe3\x27\x5d\x43\x3d\x90\x7f\x9f\x58"
-  "\xf4\x3a\x03\x06\xae\x8c\x1b\x74\xc5\xa4\x3e\xb1\x2a\x31\x7d\xb9"
-  "\x5e\x1e\xef\x03\x05\xa3\xf0\x4b\xc2\x6f\xe4\x97\x9d\x8f\xa1\xd7"
-  "\x76\xfb\x6b\xc6\x4d\x89\xac\x13\x87\x17\x86\x44\x04\x76\x41\x77"
-  "\x35\xf8\x77\xec\x66\x0f\x8d\x0d\x3c\xae\xe5\x6d\xa0\x4c\xd8\xb6"
-  "\x24\x2e\x88\x99\x8d\x11\x5c\xd7\x89\x19\x1c\x8f\x16\xcf\x19\xfa"
-  "\xf3\x14\x7e\xee\x5d\x27\x96\xf6\xb9\x9e\xda\x6b\xec\xdd\xa9\xd8"
-  "\x33\x4f\xb5\x0c\xc6\xe1\x31\x3f\xc6\xe7\x7c\x68\x61\x19\xea\x30"
-  "\x3f\xdb\xcd\xf5\xe6\xf1\xdc\x81\xfa\x90\x0f\xf3\xff\xd2\x19\x9c"
-  "\xcf\x6f\xbe\x39\x15\xbf\xf4\x61\xf6\x38\xbb\x19\xaf\xde\x94\x71"
-  "\x53\x0c\x5c\xc7\x06\x32\xb5\x2f\x87\x5b\x7e\x96\x81\x1b\xd2\x0f"
-  "\x57\xab\xf4\x10\xc7\x22\x63\x1f\x44\xbc\xcf\x37\x70\x35\x70\xe0"
-  "\xfa\xf8\x5c\xa5\x48\xb5\x76\x72\x6c\x17\xae\xcf\xff\x42\x01\xe7"
-  "\x75\x1b\xf8\x7e\xf1\xd9\x9f\xc4\x74\xf7\x51\xfe\x31\xc5\x93\xf9"
-  "\xc7\x8c\xf9\x0b\xf7\xdd\xb1\xfb\xbd\xf9\x9d\xf1\xb2\xec\xc9\x35"
-  "\x6b\x4a\xf3\x8a\x57\xf0\x25\x7d\xf2\xf3\x37\x8d\x8e\xb6\x49\x59"
-  "\xbe\xa9\xd8\x00\x2b\xf8\xec\x13\xbd\x92\x6a\xec\x5f\xae\x18\x3c"
-  "\xff\xa4\xfb\x49\xdf\xcb\xba\x2a\xeb\x74\x78\xb7\xf4\x83\xf2\x4d"
-  "\x0c\xc6\x74\x3c\x89\xb4\xe1\x64\x27\xcb\x8b\xde\x94\xe2\xfd\x92"
-  "\x1e\x35\x2f\x3b\x50\x6e\x70\xfd\x33\xb1\x9f\x98\xcd\x16\xae\xcd"
-  "\xce\x74\x8c\x97\x31\x8e\xb4\x5f\x6f\x3c\xaa\xf1\x1c\x5e\x81\x7b"
-  "\xb6\x9d\xa4\xde\xa0\xc7\xcd\xf9\xfd\xb9\xa3\x90\xc3\x2b\xba\x45"
-  "\x8d\xcd\x06\x98\xbe\x61\x71\x88\xda\x63\x67\x9f\xac\x2e\x5a\x49"
-  "\xc3\xee\x87\xbb\xaf\xde\xa6\xc6\xe1\xca\x25\xad\x76\xe2\x33\xa2"
-  "\xdf\x3f\x41\x2b\x17\x59\xec\x90\xb5\xe3\xe9\x67\xb8\x97\xb6\x2e"
-  "\xbf\x8b\xe9\xaf\x6b\x4f\x37\x5b\xcc\x42\x13\x42\x98\x84\xfa\x23"
-  "\x8b\x7e\x63\xc6\x4f\x13\x26\xb9\x5b\x64\x06\xa5\x46\x8d\xb4\x90"
-  "\x75\x6c\x72\xd2\xf5\xd7\x4d\xb0\xdf\x7b\xcf\xac\x99\xce\x8a\x72"
-  "\x70\x77\x28\x68\x15\xd1\x71\x9e\x8a\x73\x96\xdc\x54\x49\xd2\x5f"
-  "\xa0\xa6\x38\x27\x11\xae\x3b\x5c\xa2\x88\xcf\xe6\x46\x52\xb7\xbb"
-  "\x9d\xcf\x93\xf6\x6e\xbf\x4f\xe3\xd8\xc1\x3c\x47\x73\xcc\x32\xe0"
-  "\x7a\xfc\x7d\xa4\xa1\xfd\x65\xc2\xbd\xdd\xad\xf6\x03\x9f\x9e\x18"
-  "\xa9\xdd\xee\x1e\x82\x6f\x21\x86\xef\x7c\x8d\xb4\x3d\x15\xdd\x9a"
-  "\xd7\x72\x0f\x79\x1d\x01\x7a\x1f\xf7\xc3\xf4\x67\x11\xe8\x4f\x0c"
-  "\xa3\xc9\x15\xd9\xe6\xfc\x9c\x34\xfd\x7c\x9d\x76\x86\x9e\xfe\xee"
-  "\xfe\x61\xca\xf1\x79\xd6\xde\xd4\xab\xce\xf5\xb9\x9e\x46\xff\x7f"
-  "\x33\xa0\xcf\x09\x90\x5d\x4f\xc3\xfe\x5b\xa1\x9e\x53\xaf\xfa\xac"
-  "\x57\xc6\xb5\x7c\xba\xc5\xc8\x93\xb0\x8f\x5e\xe6\x35\x47\xe1\xe1"
-  "\x7e\x15\x17\x3e\xed\x66\xdf\xfd\x61\xf6\xf9\x47\x79\xcb\x6e\xe3"
-  "\x7d\x96\x11\x63\x83\x94\xec\x3c\x2f\x06\x60\xb7\xa7\x81\x6d\xb5"
-  "\x30\x6c\xaf\xd0\x05\x91\xdb\xde\x73\x8e\x38\xd6\x1f\xef\xd7\xbe"
-  "\xb3\xf2\x0f\x9a\x37\x78\xd6\xe3\xdd\x1a\xa1\x0e\xcc\xcf\xde\x86"
-  "\xb3\x9e\xf6\x9e\x23\xb8\x0f\x53\x3b\xfd\x95\xda\xcb\xfe\xdf\x4a"
-  "\xb9\x56\xd2\x20\x2a\x99\xce\x03\x17\xc4\x62\xaf\xe5\xff\x21\x8e"
-  "\x57\xcf\xb2\x02\x74\x77\x9c\xa1\x82\xcd\xbf\x07\x9c\x77\xff\x13"
-  "\xb0\x64\x6c\xa7\xd9\xf4\x3e\xee\xfb\x5c\x05\x55\x86\x1c\x49\x18"
-  "\x47\xc3\xe4\xd9\x61\x2d\x7b\x5c\x8b\x40\x26\x71\x0c\x2e\xc8\xa2"
-  "\x19\xdc\x2e\x3c\x67\xf0\x33\xae\x53\xf8\x6a\xdd\xec\xd9\x6d\x0d"
-  "\x3d\xce\x32\x2a\x97\xe5\x0f\xd2\x17\x37\x5d\x90\x32\x2b\x47\x7f"
-  "\x9e\xaf\x3f\xcf\xd5\x9f\xb3\xf4\xe7\x4c\xfd\x79\x16\x3f\x2b\xd9"
-  "\xb6\xca\x31\x28\x77\xb5\x51\x9d\x78\xce\x30\xfa\x02\xf8\x8c\xb1"
-  "\x96\x6d\x92\x32\x52\xc7\x63\x86\x8e\x57\x86\xfe\x6c\xe0\x73\xad"
-  "\x35\xb4\xe9\x7f\x0a\x9f\xfd\x71\xf8\x78\xa2\xf0\x21\x6b\x59\xe6"
-  "\x97\xc1\xc7\x66\xe5\x78\xcd\xff\x00\x3e\x8c\x0b\xa7\xf5\xb9\x9e"
-  "\xc9\x8c\xc5\xe7\x99\x1c\x03\x9f\x84\xfc\xb6\x4e\x74\xf3\xfc\x50"
-  "\x72\xb5\x8c\x55\x39\x8a\x65\x7f\x53\xbf\x11\x4f\xed\x99\xaa\x4b"
-  "\xc5\x53\xc3\x58\xb0\x23\x0f\xda\xff\xcc\x52\x7d\x1e\x3c\xa8\xf4"
-  "\xa5\x67\x5a\x0d\xdf\x18\xb4\x75\x6f\xb5\x6a\xeb\xbe\xad\x1c\x53"
-  "\x6c\x03\x5d\xe3\x2c\x13\xdd\xd0\xff\xff\xab\xd5\xe1\x8f\x19\x03"
-  "\x85\xa5\x25\x25\xcf\xdd\xed\x28\x5c\xbe\x7a\x85\x63\x72\xbe\xa3"
-  "\xa4\x60\xd5\xca\xd2\x15\xb1\xfb\xc5\x36\x3d\x5e\xbe\xf4\x83\x67"
-  "\x9d\x94\xc7\x00\xf3\x3f\xdb\xf1\xca\x77\xf1\xd9\x17\x85\xeb\x19"
-  "\x3e\x2b\x9b\xd4\x58\x4b\x16\xde\xa3\xe8\x73\x3d\xbb\xd8\x98\x13"
-  "\x54\x7c\x68\x32\x69\x36\xd6\xb9\x9e\x85\xfd\xfb\x74\x4f\x54\x3a"
-  "\xe7\xad\x34\xd2\x18\xbe\x2e\x9b\x46\x9d\xa0\x67\x27\x72\x9d\x09"
-  "\x69\x78\x41\x34\xc3\xd6\x35\xc1\x1e\x61\xdb\x50\x70\xfc\x20\x3e"
-  "\x5f\x86\x72\x02\xf8\x7c\xc4\xb2\x97\xbf\x01\xa1\x74\x5f\xc1\x38"
-  "\x7e\x82\x32\x7b\x90\x66\xd9\x89\xbc\xd0\xa7\xbb\xb9\x1c\xd2\xc3"
-  "\x7c\xce\x1f\xe9\x49\x7a\x4c\x24\xa4\x15\xa6\xf0\x39\x7c\xa4\xd9"
-  "\xa2\xd2\x26\x73\x9c\x5e\xa4\x39\x14\xbc\xc2\x3b\x98\xce\x78\xce"
-  "\xd4\x6d\x6e\xce\x33\x4f\xaf\xb7\x32\x1a\x67\x8e\xa2\x7e\xdb\xb4"
-  "\x0c\xc7\xe2\x47\xee\x9c\x7d\xcf\x53\x6b\x56\xaf\x1c\x4d\x92\xec"
-  "\xe9\x19\x65\x93\x33\x6e\x2b\xbb\xe9\x6e\x47\xd1\x8a\x15\xc5\x8e"
-  "\xf5\x2b\x56\x97\x3a\x96\xaf\x5f\xbe\x61\x34\xad\x5c\x53\xfc\x14"
-  "\x9f\x22\xe7\x6e\x29\xc9\x7b\x6a\xe5\xd3\xbc\xa9\xaf\x72\x8f\x8e"
-  "\x99\x8f\x17\xb3\x6c\xd3\xe3\x2e\x1c\x86\xcc\x0d\x8a\x94\xf1\x73"
-  "\x71\xcf\xb1\x88\xec\xb8\xb6\xe2\x77\x10\xbf\x16\xfc\xf8\xac\x7f"
-  "\xe7\x29\x2a\x4e\xc3\xf5\x40\x9f\xab\x30\x60\xe8\x05\x43\x3c\xf4"
-  "\x5c\x92\xc1\x43\x98\xc7\x0f\xa8\xf9\xed\xb9\x99\x1d\x21\x39\x7e"
-  "\x06\x79\xaa\xfa\xc2\x10\x4f\xc9\x78\x87\xec\xb3\xb2\x0e\xef\xc1"
-  "\xc3\x6c\xc7\x82\xe6\x57\x30\xdd\x4e\x52\xd1\x54\xd8\xfe\x6d\x1c"
-  "\x0b\x04\xd7\x56\xf0\x4b\x9b\x8a\xbf\xf1\xdc\x01\xe4\x9b\x88\x3a"
-  "\x0e\xea\x75\xa8\xe7\x71\xe2\x30\xdb\xf9\x27\xf4\x67\x65\x13\xaf"
-  "\xf9\x90\xef\xf9\xaa\xef\x15\x59\xd9\xff\x4f\xd9\x56\xc6\xbb\xd5"
-  "\x8f\xeb\x75\x78\x40\x8b\xca\x46\x97\x18\xdc\xe7\xe0\x35\x26\xab"
-  "\xe9\x5e\x01\x7c\xce\x46\xcc\x8f\x1d\x95\x71\xfa\x2a\xfb\x21\x23"
-  "\x6e\xbf\xdd\x5b\x26\xf3\x9b\x78\x0d\x6a\x41\x91\x88\x70\x5c\xd4"
-  "\x88\xf9\xd9\xa3\x5c\x4e\xd8\xc6\xcf\x8d\xec\x1c\x93\xa9\x74\x01"
-  "\x8e\x8f\xb6\x5a\xf7\x03\x15\x41\xa6\xed\x29\x2a\xfc\x54\xd9\x33"
-  "\xc5\x69\x4a\xcf\x5a\x9d\x65\xf8\x92\x61\x8c\xa6\xe3\x79\xb1\x21"
-  "\x03\x7c\xb4\xda\xa1\xfb\xfd\x78\x54\xfb\x57\x57\xe9\xcf\x2d\x3a"
-  "\x8e\x26\x8e\xf5\x00\xfc\x3b\xb9\xef\x60\x1b\xb6\xe0\xfe\x08\xe8"
-  "\xd3\xa6\xe8\xb3\x5a\xae\x31\x40\xaf\xe1\xf7\x47\x38\xee\x3c\xde"
-  "\x1d\x51\x71\x14\x9e\x6b\xe5\x36\x0f\xf9\x06\x36\x64\x82\x7e\x1f"
-  "\xf2\x9e\x1a\xc6\x52\x8b\xf7\x02\x8f\xcf\xe7\x3c\x80\xb7\xdf\x90"
-  "\x3b\x2c\x67\xf2\xc2\x18\xa7\x52\x2f\x5d\x1d\x32\xe4\xcd\x10\x1f"
-  "\xac\xb1\x25\x92\x25\x89\xfa\x5d\xef\x9b\x0d\xc2\x55\xb8\x18\x38"
-  "\xed\x97\x7d\xc0\x71\x23\x2f\x0c\xea\xbf\x03\x4a\x46\xae\x19\xd4"
-  "\x7f\x0d\x3c\x38\xde\xad\x8f\x71\xeb\x97\xfb\x9c\xba\xdc\x58\x53"
-  "\x65\xc8\x0d\x03\x8e\xd5\x24\x22\xd6\x32\xfc\x73\xdb\xf6\xf1\x1a"
-  "\x2b\xcf\x97\x52\x1f\x01\x9c\xb1\xe7\xd5\x19\x9f\x48\x8d\x6d\x9f"
-  "\x8f\xd6\x64\x41\xc6\x58\xa4\x8e\xea\x2a\x7c\x7a\x48\x16\xad\xf1"
-  "\x45\xc3\x14\x36\x9b\x6c\x0b\xcb\x23\xd6\x49\xf2\xc2\x16\x8e\xb3"
-  "\xb1\x4f\x9f\x5f\x20\x83\x8b\x6c\x06\xae\xa0\xe1\x61\x03\x5f\xfd"
-  "\x1b\x1f\xb0\xb1\xd7\x14\x2d\x0c\x0f\xb0\xaf\x6b\xab\xea\xcf\xb5"
-  "\x52\xde\xe0\xdd\x3e\x94\x9d\xef\xa3\x67\x9b\xf5\x31\xd4\x86\xf2"
-  "\xfb\x0e\x55\x64\x21\x4f\x51\x81\xee\xaf\xd9\x89\xfe\x3d\x12\xc5"
-  "\xfb\x8f\x47\xd9\xcb\x47\x54\x1f\xde\x53\x79\x82\x8a\xf6\x46\xa5"
-  "\xeb\x7d\x7b\x28\xe7\x04\xad\x7d\x5c\xd9\x9e\xb6\x42\x55\xbe\x48"
-  "\xfa\x6c\x1a\x38\xb2\x2c\xe0\xf3\x48\x3c\xc6\x25\xed\x65\x1f\x17"
-  "\xf9\x8c\xf9\x02\xb0\x0e\x48\x9a\x8f\x13\x07\x99\x4e\x2a\x9e\x41"
-  "\xe1\x4b\x8a\x4e\x6b\x93\x62\x68\xcf\xf3\x26\xea\x61\x3a\x8d\xdd"
-  "\x2c\x22\x63\x03\x26\x91\xb7\xc1\x22\x63\x37\xf3\x18\xe7\xbd\x09"
-  "\xf0\x87\xd4\xab\x14\xdd\xd6\xce\x35\xe8\x66\xf4\x1d\xd3\xc9\x47"
-  "\x45\x2d\x4c\xdb\xd8\x36\x8e\xea\x3c\x61\xb4\x1d\x34\xe5\xf5\x52"
-  "\x3c\x2f\xd5\xc7\x45\x9b\x67\x3c\xef\x95\x3f\xb7\xfc\x90\xe5\x4e"
-  "\x3a\x54\x36\x83\x14\x6d\xd7\xc2\xfe\x7b\x56\xc6\x2b\xd7\x61\x71"
-  "\x1c\xcf\x7d\x3c\x56\x80\xe7\x5e\x3d\xb6\xd0\x61\xe5\xaf\xf1\xdc"
-  "\x52\xe8\xfb\x7b\xe5\x58\x5e\x27\x63\x40\x70\x7c\xd1\x4e\xa6\x11"
-  "\xcb\x45\x1e\x4b\x3c\x06\x78\x3c\x29\x1a\x15\x5b\xa2\x68\xd4\xca"
-  "\xf4\xd1\xe9\x74\x20\x4e\x96\xaf\x70\x14\xce\x56\xb2\xd8\x91\x3e"
-  "\x39\x7f\xba\x0c\xe4\xe1\x78\x70\xce\xdd\x8e\x9c\xd9\x93\xcb\x0a"
-  "\xa6\x2c\x50\x97\x39\x39\xf3\xf9\x3a\x3a\xd6\x7e\x82\x5d\x53\x5c"
-  "\x18\x6b\x83\xad\xef\x51\xf2\xa3\x78\xab\xcf\x44\x32\xde\x22\x6c"
-  "\xe5\x9e\xea\x73\x44\x61\xa6\xe1\x6a\xf4\xa9\xdb\x36\x77\x21\x64"
-  "\xf0\xc2\x0d\xe2\xf3\x26\xa4\x73\x8c\x5a\xe6\x45\xf0\xfc\x5c\xb6"
-  "\x79\xfd\x29\xc5\x39\xf8\xd9\xfc\x29\xe3\x2c\x0f\xdc\xe4\x14\x80"
-  "\xd5\x69\xb4\x85\xed\x62\xc1\xe5\xcb\x44\x98\xe9\x92\x57\x86\xfe"
-  "\x46\x39\xb6\x91\x91\x2f\x88\x39\x20\x53\xd9\x86\x25\x68\x7f\xe1"
-  "\x1e\x5d\x7e\xe5\xe0\x39\xcd\x47\x19\x92\x8f\x23\x2e\x3b\xaf\xcf"
-  "\x59\x22\x5b\x6e\x7e\x18\x36\x80\xcd\x80\x09\x58\x23\xf5\xbd\x5d"
-  "\x09\xef\xcb\xfa\x0a\x46\x6a\x53\x32\xad\x26\x15\xe7\x0e\xe3\xba"
-  "\xb2\x49\x8b\xe4\x0e\xfa\x02\xe0\xdd\xd8\xcd\x36\xf6\x15\xc8\x05"
-  "\xbf\x55\x72\x1e\xe3\x5d\xb5\x2b\xe2\xab\xd6\x22\x41\xf4\x9d\x4d"
-  "\xe9\xcc\x3d\x2c\x33\x61\x7f\x96\x78\x8c\xb9\x4c\xce\x81\x1a\x55"
-  "\x2a\x1b\xa6\x44\xee\xf1\x9d\x73\x59\x08\x72\x7a\xe9\x0d\x69\xd2"
-  "\x2e\x09\x46\x5c\x26\x52\xfe\x99\x25\xbf\x31\xe4\x2a\xef\xb1\x58"
-  "\x37\x0b\x3f\xaf\xaf\x59\x43\xc2\xcf\xfb\x2d\x72\xbe\xa0\x53\xe4"
-  "\x2d\xef\xab\xe4\x38\xa4\x52\xef\x41\xbd\x6a\xae\x08\xab\xb9\x02"
-  "\xf5\xc3\x96\x5f\x86\x39\xc1\x74\x8a\x4a\xb6\x32\xfe\x4c\x1b\x5e"
-  "\xc3\x8d\x80\x56\x5e\x9e\x1b\x99\x3e\xa9\xa9\x1e\xde\xe7\xe7\xb6"
-  "\x5a\x43\x68\x73\x74\xbb\xb4\x88\x6f\xa7\x0b\xed\xd2\xd0\xae\xb2"
-  "\xd3\x3c\x4e\x82\xec\x7f\x81\x31\x36\x4e\xc6\xda\x95\x36\x76\xe9"
-  "\x9e\xe8\x36\xb2\xcc\x57\x6d\x28\xfd\x30\x51\x1b\x85\xc6\x6d\x64"
-  "\x1a\x94\xbe\xa6\x8f\x31\x89\x27\xcb\x8c\x1e\x2a\xcd\x1d\xbb\x99"
-  "\x63\xf0\xd9\xe6\x82\x8f\xe6\x70\x1f\x62\xce\x74\x33\x9e\x89\xfa"
-  "\x8b\xe1\x29\x58\xcf\xe7\x5b\x37\x57\x2e\xeb\x73\x3d\x9f\x91\x98"
-  "\xde\xcf\x2f\xba\x34\xbd\x9f\x9f\xcc\xe5\x19\x0f\xf6\x03\xb1\x86"
-  "\x60\xa0\x83\x6f\x61\xa3\x6d\x4b\x54\xef\xd8\xcd\xcd\x8c\x57\xc2"
-  "\x77\x90\x3b\x3d\xd5\xba\xdc\x01\x1f\x8a\x85\xf8\xb1\x1c\x02\x6e"
-  "\x6d\x86\x0c\xb2\x9a\x1c\x66\x29\x13\x34\xe1\x4e\x04\xc3\xba\xd9"
-  "\xcd\x7e\x17\x73\x50\x7f\xc2\xf7\xa0\xb1\x03\x34\x9a\x19\xd9\x72"
-  "\xcb\x0d\x56\x13\xdd\xeb\x37\xdf\x32\xda\x5a\x16\x9a\xc4\x34\x04"
-  "\xcc\x32\x8c\xdd\xff\x60\xdb\x54\xc5\xc6\x5a\x87\xf9\xff\x25\xb9"
-  "\x9e\xe7\x4f\xb1\xcd\x54\xf1\xb3\xd6\xe5\xfa\xa8\xea\x98\xb1\xae"
-  "\x89\xe7\x02\x1f\xfd\x55\x5f\xaf\xba\xe6\x75\x51\x7b\x15\xe6\x7e"
-  "\xab\x70\x6c\xb4\x42\x77\x5c\xcf\x71\xc8\x35\x91\x7a\x55\xe7\x10"
-  "\x9f\x28\x9f\x10\x83\x4f\x50\x7e\x6f\x62\x1e\x58\xf7\xc7\x4b\xf3"
-  "\xc0\x3a\xb9\x5f\xcc\x74\x57\xf6\xc9\x3a\xbf\xa1\x9b\x88\x2d\xd7"
-  "\xbc\xee\xa8\xe0\xfa\xd7\x6d\x55\x75\x33\x4d\x32\x79\xad\x7e\x3e"
-  "\xe8\x52\xd9\xe7\x5a\x3f\xc1\x90\x03\xcc\x2f\xd6\x30\x99\x58\x16"
-  "\x31\xaf\xe0\xdd\x4c\xc8\x99\x7a\xb5\x86\x38\x6e\x9b\xfc\x46\x94"
-  "\xab\xd8\xe1\x77\x16\xec\x62\x1f\xce\x40\x8a\x6d\x3f\xf2\x2c\xf5"
-  "\xd1\x6f\x27\xc9\x3c\x36\xdb\x5e\xc0\xd8\x57\x97\x8a\x79\x59\xf9"
-  "\x32\x25\xf3\x98\xe6\xb8\x37\x3c\xae\x91\x96\x06\xbc\x39\x06\x0e"
-  "\x6c\x9c\xf5\x75\x83\x73\x91\x2b\x13\xb2\x42\xc8\xf9\x10\x73\xd1"
-  "\x84\x5e\xd0\xee\x87\x5a\x64\xef\x85\xe9\x76\xe2\x36\x5f\xd8\x32"
-  "\x7e\xef\xf7\xa7\x91\xe5\xff\xb2\x3f\x49\x45\xb7\x51\xda\xe6\x3b"
-  "\x2d\xf4\xbf\x66\x92\xc6\x74\xf0\xd1\xfa\x3d\x8a\x76\xeb\xbb\x8c"
-  "\xfe\xf1\xd1\xba\xf9\xdc\x1f\xbc\xfe\xb6\x30\x24\x3e\x57\x6b\x84"
-  "\x65\x90\x7f\xf9\x1e\xf5\xbe\xb8\x2c\x7e\xdd\x87\x75\x78\xc7\xaa"
-  "\x12\x47\xfe\x9a\xf5\xab\x27\x4e\x8c\xb1\x8f\x2c\xf2\x5c\x87\xab"
-  "\xcc\xae\xe6\xd0\xb2\xf9\x06\xde\xac\x8b\xe0\x19\xed\x2f\xbe\x28"
-  "\xce\xf7\xfc\x3c\xdd\x75\x37\x2f\x83\x86\xee\x6f\xa5\xf9\xb7\x46"
-  "\x3d\xde\x4e\xf3\x6f\xbb\x3d\xef\xe1\x15\xcb\xf3\x37\x44\xa5\xde"
-  "\x11\xbd\x26\x57\xfd\x3a\xea\x36\x8f\xbf\x1f\xb2\xc2\xb4\xe0\x05"
-  "\x9e\x4f\x36\xdc\x57\x11\x12\x7f\x87\xbc\x9e\x89\x31\x96\xd7\x5e"
-  "\x1a\xa2\x76\xc8\x32\x71\x0d\xcb\xf0\x51\xea\xbc\x1a\x74\x28\xf0"
-  "\x96\x15\x6d\xf7\x43\x97\x3b\xcf\x6b\x32\x28\xb7\xa2\xa3\x9e\x63"
-  "\xcf\x8e\x4b\x56\x7a\xc5\x06\x07\xd2\x53\x70\x9d\x87\xeb\x48\x5c"
-  "\xb3\x1d\xab\x61\xeb\xb0\x7f\xf0\x3a\xf6\x0f\xde\xc0\x78\x98\xa6"
-  "\x05\x2a\x69\x5a\x31\xeb\xe9\x65\x47\x59\xef\xf0\xd1\x86\x6d\xbc"
-  "\x3f\xc0\x79\x51\x66\xa2\xe3\x19\xca\xe0\xab\x90\xfb\x2a\x1b\x1c"
-  "\xa2\x66\x5c\xb2\xd8\x95\xcb\xdf\x6e\x99\x84\xf4\x17\xcd\xa6\xe3"
-  "\x64\xb6\x8f\xfa\x56\x9f\x6b\xc3\x56\xf0\xa4\x1c\x1b\xc3\x7d\xef"
-  "\x8d\x75\x0d\x1e\xf3\x43\xba\x08\x74\x41\xe8\x22\x79\x65\x2f\x13"
-  "\xee\x2d\x43\x7a\xc8\x86\xce\x41\x9d\x56\xa3\xd1\x78\xf6\x19\xfc"
-  "\x8e\xfb\x1e\x83\x1f\x63\x62\x83\xad\x2e\x5d\x51\xbc\x22\xdf\x31"
-  "\xb9\x64\x34\x45\x45\x06\x2b\x58\xb1\xda\x51\xbc\x62\xed\xf3\x2b"
-  "\x4a\x64\x54\x2f\x7e\x1b\x33\x9f\xa7\x89\xd4\xb4\x4c\xe3\xcc\x8a"
-  "\x63\x3c\xd3\x71\xe3\x22\x8e\x27\x25\x6a\xd3\x58\xe7\xee\x51\xb6"
-  "\xc4\xf6\xbd\xb1\xb6\xc4\x0b\x5d\x4a\x87\xbb\x2a\xa4\xec\x98\x17"
-  "\x36\xf0\xf3\x09\xda\x18\x1a\x8a\x41\xbd\xf1\x6d\xfe\x0e\x82\x4e"
-  "\x9f\xa3\x7d\xae\x8d\x7b\x0c\xfa\xf8\xa8\xdc\x38\x47\xd0\x23\xe5"
-  "\x04\xe6\x52\xc8\xb9\x98\x79\x54\x7d\xcf\x6d\xe3\x3e\xde\x63\x95"
-  "\x6b\xb2\x29\xe3\xa4\xcd\xc4\x30\x4f\xa2\xbc\xa8\xb9\x8a\xe5\x23"
-  "\xcb\xb1\x6d\x06\x3c\xd4\x59\xc7\xf5\xe9\x36\xce\x57\x4f\xd1\x0b"
-  "\x72\xcf\x3a\xe2\x1e\x47\x2c\x3b\xa6\x49\x9d\x63\x9c\xfe\xbd\xbe"
-  "\xf2\x29\xac\x3f\xca\x38\xe8\x80\xc5\x6b\xb0\x90\x01\x36\xfe\xf6"
-  "\x1f\xa7\xa9\xb8\x56\x1b\xa4\x9f\x20\xea\x0a\xf6\xb9\x5e\xc8\x1f"
-  "\xf2\xcb\x2e\x9f\xc2\x3a\x25\xc3\xf5\xd1\x0b\xe9\x0c\x4f\xc5\xed"
-  "\x7a\x01\xb8\x94\xed\x1d\xd2\x8d\x5e\x68\x8b\xb2\xb9\x80\x8f\xc2"
-  "\x33\x00\x5c\x64\x8c\x48\xe5\x37\x27\xdb\xcd\x72\xb2\x4e\x6f\xbb"
-  "\xd1\x1e\xc0\x3b\x0a\x9e\xab\x33\xf6\x5d\x7d\x7a\xbb\x19\x3f\xc6"
-  "\x3d\x1a\x67\x85\xef\x46\x96\x4b\x18\xc3\xe5\xb6\xa8\x31\xcc\x6b"
-  "\x2e\x23\x90\x36\x69\xc8\x1f\x77\x63\x61\xbc\x7c\xb8\x7f\xf9\x53"
-  "\xcf\xb2\x91\x3e\x3f\x63\x8a\x83\x65\x45\xde\xc3\x0f\xcc\x79\x34"
-  "\x6f\xce\xc2\x25\x0b\x16\x4b\xff\xfb\xc1\xf7\x59\xab\x13\x67\x88"
-  "\xe5\x2b\x1b\x78\x23\x88\xfe\x1a\x71\x82\x2a\x7c\x2a\x3e\x73\xf9"
-  "\xde\xd8\xf8\xcc\xe5\x1e\xfc\x8e\xe1\x07\xcd\x64\x93\x0f\x3f\xe8"
-  "\x91\x15\x47\x74\x7e\xe9\x01\xbe\x47\x86\xf8\xa5\x42\xae\x79\xb3"
-  "\x5f\x82\x5a\x4b\x2d\x87\xfc\xdf\x38\x29\xfa\xdd\x90\xed\xb7\x29"
-  "\x79\xd0\xf6\x1b\x94\x05\x9b\x66\x1a\x76\x20\xd2\x2c\xb0\x01\xaf"
-  "\x60\x1b\x50\xad\xfd\x54\x48\x1d\x2b\xde\x56\x1b\xb2\xd3\x92\xc8"
-  "\xb0\x01\x39\x36\x24\xef\x7b\xaa\x31\xba\xa9\x34\xca\xc6\x0a\xc8"
-  "\x78\x81\x17\x94\x4d\xc8\xe5\xe4\x5a\x9b\x6d\x7b\x1d\xaf\x3f\xfb"
-  "\x53\xae\x0a\x62\x8e\xc7\xbc\xd3\x27\x44\xca\xf6\x3a\x1d\xa7\x03"
-  "\xbc\x1e\xcd\xfa\xae\xb2\xf7\xca\x67\xb2\xfc\x15\x5b\xc6\xdf\xbf"
-  "\x30\x2c\x63\xa9\x41\xf6\x6e\x3a\x3a\xc4\x73\x15\x3e\xee\x4b\xa6"
-  "\x01\xf8\xa0\x0b\x74\xb0\x0c\xb5\xb9\x82\x06\xdb\xac\xaf\x63\x18"
-  "\x6b\x18\xaa\xae\x8a\xe3\xc3\xb5\x2f\x71\xdb\x2a\x72\xbe\xb0\x6d"
-  "\xfc\xcd\x1c\x8c\x0b\xa3\x8d\x17\xb7\xaf\xa2\x2e\xae\x7d\xb9\x17"
-  "\xb7\xaf\xa2\x65\x70\xdf\x65\x70\x5d\xa2\xe2\x38\xb7\x93\xf9\x00"
-  "\xed\x3c\x6c\xb6\x27\x7d\x2d\xea\x7e\x4a\x22\xb9\x3a\x76\xb3\xa6"
-  "\x9f\x01\x71\xde\xd1\x3a\x41\xda\x69\xc1\x57\xb4\x48\xc1\x2b\x2e"
-  "\xfc\x70\x65\x3d\x7b\x48\x57\x15\x41\x85\x9f\x73\x46\x2b\x64\x2f"
-  "\xaf\xb5\x0c\x77\xb6\x0d\x34\x3b\x66\xac\x03\xe0\xfe\x28\xdb\x93"
-  "\x0b\xc3\xf7\x0a\x4e\x67\x1a\xc0\x26\xf1\x83\xaf\x8e\x2a\xbd\xcd"
-  "\xb9\x75\x50\x66\x4f\xb3\xf9\xcd\x9b\xc9\x71\xa8\xe1\x36\x4e\x6f"
-  "\x40\xdf\xc9\xb5\x41\xf9\x8d\xbc\x61\x60\xe6\x85\x33\x69\x18\xb8"
-  "\xc7\x0c\xb8\xc3\x9d\x83\x8c\x4e\x5b\xb3\xda\x51\xb0\x7c\x75\xfe"
-  "\x9a\x95\x2b\xa7\x38\x9e\x5f\xfd\x64\xe1\x9a\xa7\x9e\x65\xc1\x5f"
-  "\x52\xfa\x3c\xc6\xaf\x1c\xb7\x59\xf3\xe7\xe7\xdd\xbf\xe4\x91\xef"
-  "\xc6\xe8\x00\x49\x6e\x57\x64\x9b\xfc\x46\xd6\x96\x67\x36\xf6\xb9"
-  "\x2a\xd1\xff\x4f\x97\xa9\xf9\xa6\x12\xf3\xff\x53\xc9\x4a\xd7\x7a"
-  "\xac\x5b\x9d\xfd\xac\x6c\x89\x92\x6b\x63\xf1\xdc\xca\xdf\x3a\x18"
-  "\x5a\x03\xa9\x74\x47\xeb\x10\xbd\xf2\x3b\x75\x95\x7b\x8c\x38\x08"
-  "\xa5\x13\x49\xb3\x4c\x74\x53\x9d\xc6\xdf\xcd\xaa\x3c\x0c\x7b\xf1"
-  "\x18\xde\xb7\xfa\xa8\xa0\x5e\xb7\x1f\x8f\xf1\x1e\x2b\xdb\x8f\x61"
-  "\xd8\x92\x0b\x37\x78\xee\xcd\xdb\x60\x62\x1f\x62\xf9\xdd\x84\xd0"
-  "\x05\xd1\xc5\xfb\x9c\xbc\x67\xc4\xdf\x4d\xa8\x7e\x46\xda\x93\x66"
-  "\x99\x07\xf7\xd5\x27\x49\xda\x56\x78\xef\x68\x3a\x29\xbf\xdd\x08"
-  "\xfb\x63\xf3\x24\x43\xf7\xb4\x6e\x76\xc8\x33\xa9\x3b\x55\x7f\x1c"
-  "\xe5\xbe\xe0\xfa\xf2\x36\x78\x54\x1d\xe8\x03\x94\xb5\xaa\x75\x9f"
-  "\xcd\x4b\x2f\xb9\x9e\x9d\x52\x3c\x73\xd8\x18\xe4\xae\xca\x51\xaf"
-  "\xa8\x78\xc5\xec\x07\xe7\x37\xfc\xb0\xd8\x27\x0b\x70\x0f\xc4\xfb"
-  "\x74\x29\xbf\x84\xcd\x6d\x86\x3f\x08\xee\x8f\x0e\xea\xcb\xfc\xad"
-  "\x0d\xd8\x39\x8e\x8a\xcd\x23\xcf\xd0\xe6\xd7\x9a\x86\x59\x57\x36"
-  "\xce\xa0\xea\x7e\x53\xa3\xfa\x5c\xae\x09\x83\xbe\x24\x78\xe6\x31"
-  "\x3e\xe4\x0f\xe6\x9a\x69\xf8\x13\x49\x1f\x32\xcc\x59\xfc\x3d\x8f"
-  "\x93\xe4\xfa\xae\xfc\x7e\xc8\x0d\xbc\x26\xec\x2a\x6b\x95\xbe\x6c"
-  "\xae\xfc\x68\x5c\x14\x1e\xae\xc9\xbc\x6e\xc9\xef\xa3\x71\x29\x5b"
-  "\xfe\xfc\xaa\xe9\x65\x2b\x57\x39\x9e\x2a\x58\x55\x94\xb7\x4a\xc6"
-  "\x0d\x95\x21\x49\x4b\x37\x14\xf1\x2a\xfd\x4d\xa3\xe3\xe6\x0a\xdd"
-  "\xef\x6c\xd0\xbf\x46\xfa\x9e\xb9\x3e\x06\x3d\x34\xe5\x7b\xb6\xa5"
-  "\x53\xcd\x87\xae\xee\x8b\xfd\x2c\x5c\x21\xc3\xcf\x02\x7c\xc5\xdf"
-  "\x6d\x0d\x0c\xf9\x66\x30\xdf\x6d\x99\x70\x71\x99\x2d\x19\x83\x7e"
-  "\x46\xec\xef\x32\x90\x2b\xcf\x08\xc8\xd8\xd2\xb5\xdc\x6f\xae\xad"
-  "\xde\xb2\x07\x78\x8f\x58\xe7\xe7\x2d\xcb\x0c\x7e\x36\x7c\xd4\x18"
-  "\x16\x9f\x51\x98\x1e\x8c\xf6\x4f\xd9\xf2\x21\xe6\x16\xfb\x60\x3b"
-  "\x5e\xd0\x88\x71\x0f\x68\x1e\xc6\x63\x4f\x3c\x1e\xc0\x6f\x22\xd2"
-  "\xa3\xfc\x7f\x8c\x76\x6e\x81\xfe\xb7\xf5\x22\x1d\xef\xbe\x07\xe6"
-  "\x43\x99\x2b\x59\x51\x3a\x9a\xe6\x2c\x2f\x2c\xe4\x71\xbd\x7c\x45"
-  "\xe1\xf3\xc5\x6b\x4a\xf2\x56\xad\x5e\x85\xd4\xfb\x56\x72\x38\x57"
-  "\x99\xe5\x6e\xfd\x8d\x63\xf5\x8a\x15\xf9\x2a\x49\xef\x86\xd8\xbd"
-  "\x11\xb5\xff\xbd\x35\xd3\x47\x9b\x83\x43\x7a\xcb\xd6\x7a\xa1\x6d"
-  "\x39\x86\xdf\xdf\xe5\x98\x96\x3a\xc5\xd6\xfc\x58\xbb\x60\x6b\xa9"
-  "\xc1\x0f\xb2\xff\x9c\xec\x23\x62\x7d\xab\x57\xc8\xbd\x04\xf4\xd9"
-  "\x8b\x7f\xe4\xef\x9e\xfa\xe8\xc5\xc3\xac\x0f\x47\xc1\xd9\x37\x48"
-  "\xcb\x2d\x8f\x1d\x65\x5e\x64\x78\xfc\xbd\x37\x3e\x9b\x8d\xf7\xe0"
-  "\xff\xcd\x95\x8a\xff\xb7\x0e\xf2\x7f\xaf\x66\x86\x8d\xb3\xb5\xdb"
-  "\xd0\x83\x63\xc7\xcc\x8b\x74\xf1\x58\x62\x9f\xc1\x17\xed\x06\x6d"
-  "\x8d\x7e\x56\xbc\xf5\xe2\x6f\x8c\xb5\xc9\x26\x3d\xb6\x38\xdf\x73"
-  "\x59\xd6\x71\xc5\xd8\x31\xf7\xb2\x0f\xf4\x09\x7a\x71\xab\xe2\x97"
-  "\x17\x97\x45\xf9\xf2\xd8\x4e\xd1\x8b\xba\x3d\xfb\x62\x99\x81\x1f"
-  "\xda\x39\x83\xd3\x18\x86\x1a\xfb\x5b\xc2\x8a\x77\x5e\x6c\x30\x68"
-  "\xcb\x76\x23\x9e\xf7\x0d\xcd\xe9\x5b\xe7\xf3\x5c\xa7\x9f\x4d\x1f"
-  "\xe0\xf6\x03\xce\x14\x03\x0e\xf2\xe2\x39\xa9\xd5\xa0\x95\x91\x27"
-  "\x9a\x27\xe6\x2c\x2f\x82\x51\xb7\x6a\xe5\xca\x15\xc5\x25\x46\xbc"
-  "\xde\xf4\x35\x85\xf9\x2a\x3e\xef\xdd\xe8\xfe\xf5\x18\x81\xb3\x39"
-  "\xc4\x2f\x52\xd5\x6d\x9c\x0d\x30\x85\xed\x70\xe9\xef\x25\xf5\xff"
-  "\x97\xef\x68\xd4\x6d\x81\x13\xf4\xfd\x19\xb8\x42\x1e\xbc\x74\x5e"
-  "\xe9\x65\x57\x9c\xed\x73\xbd\x54\x68\xe8\x65\xbd\x23\x67\xc2\xbe"
-  "\x7e\xa9\xdc\xf8\x0e\x93\xa1\x2b\xf0\x59\x14\xcf\x6a\x8e\x7d\xfe"
-  "\xf2\x6b\x91\x1a\x5b\xba\x18\x2b\x72\xa1\x93\x24\x33\xdf\x8f\xe9"
-  "\xe1\xb8\xe8\x1c\x2f\xe6\xa5\xc3\xac\xcb\xb0\x2c\xe1\x18\xe7\x5d"
-  "\xf4\x52\x3d\x7f\xbb\xd9\x47\x2f\x37\xf8\x53\x6c\xe9\x5b\x37\x52"
-  "\xd2\xee\x57\xe5\xf7\x6f\x7d\xad\xcd\x4c\xc7\x97\xba\x3e\x28\x57"
-  "\xdf\xd3\xe6\xef\x10\xef\xc0\x3b\xd8\xc3\xfb\xf5\xb5\xe4\x59\xfa"
-  "\x3a\xde\xac\x3e\xd7\xf7\xa1\xff\x25\xb7\x28\xbe\x24\xef\xd7\x2b"
-  "\xa9\x8c\xbf\xcf\xa6\x62\xbd\x5c\xbd\x4d\xb8\xa9\x13\x7a\x8c\x1f"
-  "\xfa\x0f\xf4\xec\x97\x0a\x45\x0d\x75\xaa\x38\xd1\xcc\x17\x2f\x2d"
-  "\xe5\x76\x02\x1e\xc7\x6e\x4a\xe2\xb5\x1d\x1d\x2e\xc7\x01\x33\x41"
-  "\x8f\x0b\xb0\x2e\x87\x67\x47\xe4\xc2\xe9\x66\xcc\xdd\x49\x98\xab"
-  "\xfc\xfa\x77\x7f\x26\xf1\x9a\xe7\xd8\xcd\x3e\xcc\x45\xd7\x8b\xbc"
-  "\x90\x8d\xf7\x1a\xc6\x18\xdf\x55\xe2\x75\x4f\xe0\xb6\x77\x68\x0f"
-  "\x01\xe5\x41\x13\xf0\x63\x65\x17\x7d\x5f\xfa\xfa\x33\x2f\x32\xed"
-  "\xfa\x41\x2f\xfe\xfe\xae\xb8\x70\x7a\x3f\xec\xd0\x31\x27\xe9\xfb"
-  "\x9f\x30\xdd\x78\xdf\x8f\xfd\x75\x90\x66\xe5\xf8\xd1\xe8\x9f\x8f"
-  "\x98\x66\x8c\x0b\xda\x95\x11\xea\xcb\xfd\x16\x9f\x21\x64\x79\xb4"
-  "\xa9\x1c\xba\xdf\x4a\x1e\xcb\xdb\x97\xb0\x3d\xc7\xdf\xfc\xe0\x7b"
-  "\x67\xbe\x88\x48\x9a\x6f\x64\x9a\x6f\x5f\xb2\xa9\x5b\x44\x3e\x77"
-  "\x91\x38\x1c\x20\xfa\x5c\xa3\x50\x50\x33\x31\xde\x9a\xf3\x34\x9f"
-  "\x73\x6c\x26\x6f\xd9\x36\x42\xbd\x49\x3b\x37\x92\x8d\xcf\x85\xf2"
-  "\xf7\x2c\x3a\x02\x0d\xd4\x51\xd4\x40\xff\x1e\xaa\x23\xcf\x3a\x3e"
-  "\xe7\xbf\x3d\xf4\xa7\xb2\x3a\xb6\xab\xae\xc0\xfd\x7b\x8e\x47\xb9"
-  "\xae\x6d\x75\x7f\x3a\xf2\x67\xfa\x93\xe7\xcf\xe4\xf8\x9e\x7c\xde"
-  "\xd3\x96\xfb\xef\xd4\x96\xf9\xef\xe4\xec\x12\x11\xb6\x09\x2a\x9e"
-  "\xe3\x3a\xb6\x01\x56\x33\x9f\xa7\xb4\x45\x7a\xed\xa3\xd1\x7e\xcb"
-  "\xc2\x32\xa2\x8e\x80\x1f\x3c\xf4\x3b\xc6\x71\x72\xe3\x39\x4a\xf2"
-  "\xac\xfe\x83\xbc\x57\xba\xfa\xe9\x66\x6f\xfe\x51\xd6\x93\x42\x7c"
-  "\x7e\x94\xf7\x9e\xa0\xeb\x46\xaa\x19\xc7\xb0\xc2\x9b\xbf\x23\x6d"
-  "\x94\x87\x1e\xa5\x97\xdf\x26\xd7\x78\x77\x33\x3d\x80\x53\xfb\x62"
-  "\x45\x93\xb6\xa3\xa0\xe9\xa3\x3a\x7d\x72\xa3\xe9\xb3\x2d\x8b\xe9"
-  "\xc3\xb1\x07\x23\xe8\x2f\xe0\x96\x09\x1a\x44\x8c\x3a\x80\x73\x92"
-  "\xbe\x6e\x97\xb4\xf3\x1c\x25\x7b\x56\xf3\xb7\x89\xb6\xbf\x65\xcd"
-  "\xb1\x24\x45\x2e\x9c\xd9\x5f\x7d\x9e\x2c\xdc\x6f\xbc\x3e\x5f\x2d"
-  "\xdf\x4b\x9a\x57\x71\x9f\x45\x7f\xcf\x9c\xf9\x90\xbf\x69\x8e\xfe"
-  "\xda\x06\x1c\x26\xa1\xaf\x9a\xf9\xaa\x78\x9b\x3a\xf9\x7c\xbd\xae"
-  "\xcb\x0f\xa5\x83\xb7\x43\xfc\xdd\x41\xb9\x2e\xb1\x7d\x52\x04\xbc"
-  "\xcd\xf6\x7c\x63\x2d\x25\x47\x5c\x2f\xfa\x77\x43\xd6\x34\x60\x2e"
-  "\x6b\x4c\x25\x1b\xaf\x65\xbd\x2e\xfd\x87\x5f\x4e\x37\x64\xcf\xcb"
-  "\xe3\xf8\x4c\xd2\xf6\xc5\x9a\xfc\xbe\x9c\x2d\x53\xe7\xf3\x4c\xe4"
-  "\x99\xef\xa3\xab\xf6\x28\xf9\xfb\x72\xae\x31\x96\xa0\x27\xf9\x0d"
-  "\xfe\xc7\xf8\x74\xf8\x99\xdf\xa5\x1f\x82\x0f\x36\xac\x55\xb0\x6f"
-  "\xe7\xd0\x37\xd5\x5e\x76\x1b\x7c\x8e\xb6\x15\xb1\x9c\xe0\x31\x3d"
-  "\x9c\x9e\x0d\x1d\xaf\x4d\xec\xca\xa5\x9d\xa7\x88\x92\x37\x0b\x7f"
-  "\x72\x97\x55\x74\x04\xda\xe4\x79\x36\xfe\x7e\x62\x23\xd2\xf1\xde"
-  "\xb4\x20\xe0\xb7\x42\x27\x64\x7a\x58\x8c\x74\xde\x5f\xe0\xf5\x98"
-  "\x05\x01\xe1\x5f\xb8\xc1\xca\xdf\x77\x9b\x20\xd7\x9c\xf5\xf4\x0e"
-  "\x3b\xef\x3b\xf8\xad\xa0\x5f\x68\x10\x56\x6f\xae\x99\xf1\x44\xde"
-  "\xb4\xc1\xbc\xbd\xb9\x16\x6f\x99\xaa\x33\x2a\x6d\xc4\xc2\x32\x94"
-  "\xe5\xfe\xd6\xd3\x94\x2e\xf9\x83\xa2\x41\xfb\x88\xe3\xf4\xf5\x62"
-  "\xee\x2b\xc9\x35\x45\x7a\x73\xb5\x30\x60\x63\xfc\xd8\xe4\x77\xe6"
-  "\x42\x7e\xfd\x5b\x2f\xdd\xe8\xac\xa3\x24\x6a\xb6\xef\x47\x3e\x0b"
-  "\xc3\xe5\x33\xd1\x1c\x27\x5f\xa4\x54\x25\xd4\x1f\x85\x7b\x7d\x81"
-  "\xa7\xe2\x7b\xe0\xc9\xaa\x32\x96\x09\x61\x5b\x4a\x86\xe3\x19\xd6"
-  "\x31\x7e\xf0\x19\xf7\x7f\x18\xe3\x34\x9c\x92\x92\x31\xbd\x9b\x4c"
-  "\xfc\xbd\x3f\xb5\xa6\x51\x95\xc2\x67\xc0\x9d\x11\x01\xbd\xad\x4a"
-  "\xf2\x9e\xb5\x87\xfd\xaa\x52\x66\x48\x5f\xa6\xd4\x92\x65\xde\x60"
-  "\x37\xb5\x55\xfe\x95\xda\x42\xde\xca\x83\xe7\xfc\x16\xe5\xd3\x64"
-  "\x01\xdc\xaa\xc9\xfc\xce\x09\x7e\xcf\x0b\x37\xd3\x70\x6b\xca\x6c"
-  "\xeb\x61\x1e\xfa\x9b\xb2\xa1\xaa\xca\x0c\x1b\xef\x0b\xda\xd0\xc9"
-  "\xe7\xc8\x85\xb0\x53\xa4\x76\x11\xaf\x9d\x3b\x45\x5f\x3a\x4d\xdf"
-  "\xc8\x6b\x3c\x55\x7b\xa1\xbb\x67\xea\x70\xcf\xea\x70\x3b\x2f\x05"
-  "\x97\x79\xa6\xad\x5e\xee\x67\xa0\x4d\x8b\x72\xc2\x80\x1d\x4e\x5d"
-  "\xe4\x86\x0c\x77\x3a\x3f\xe7\xb5\xbe\x9d\xd7\xa2\x9e\x9c\x8e\x50"
-  "\x27\x71\x4c\x8a\xc6\x08\xe6\xb8\xb3\x76\xd2\xfd\xb7\x9c\x67\x68"
-  "\x07\xaf\x55\xdb\x60\x8b\x4a\x5c\x58\x4e\xb2\x5d\x5b\x11\xa6\x91"
-  "\x5e\x68\x35\x7c\x9e\x1a\x30\x52\x3e\xe4\x3d\x13\xc8\x9a\xb0\xb0"
-  "\x6b\xef\x5d\xf0\x11\xfb\x68\xc8\xf3\xd5\x5b\xae\x79\x7d\xec\x66"
-  "\xba\x57\x68\x56\xe9\x9f\x17\xa9\x59\x5b\x80\xbe\x6d\x51\xfe\x62"
-  "\xb6\xf9\x51\xbe\x62\x66\xd4\xf5\x22\xfb\x8a\x09\x9b\x2d\xad\x81"
-  "\xf7\x30\x52\x4a\x32\xfd\x29\xc5\x19\x02\x7d\xd7\xe7\xda\xd1\xe2"
-  "\xa3\x1f\xc8\x35\xdb\x2a\xf6\xaf\x96\xf2\x7a\xe7\x64\x7f\x4a\x36"
-  "\xaf\x7d\xf2\xd9\x2b\x53\x64\x5d\x78\x7f\xf5\x67\x64\x51\x74\xd9"
-  "\x39\xa2\xa3\xa7\xcf\x23\xdc\xd9\x33\xf9\xec\x8c\x5e\x87\x15\x75"
-  "\xfc\x45\xd4\x64\x43\x97\xdf\xa9\xcb\x0c\xbe\xdf\xe1\xe7\xf7\xa1"
-  "\x81\x74\xe8\x46\x3b\xf2\x1b\xfa\x79\x2d\x79\x87\x4d\xb8\xae\xf7"
-  "\xf4\xda\xb2\x67\x3e\x62\x67\xfd\x68\xe7\x4c\x9f\xf6\xaf\x47\xf5"
-  "\xf5\x25\x79\x66\x3c\x7e\x5d\x68\xb0\x2f\x77\xd9\x47\x7b\x01\x04"
-  "\xf6\x5e\xda\x29\x72\xbf\xd5\xef\x22\x6d\x00\x7a\x5d\xbf\x06\xfd"
-  "\x7d\x57\x6e\xf2\xce\xf1\x94\x81\x77\xe3\x4f\xd1\xce\x1d\x21\x8d"
-  "\xd2\xf0\xb3\xf9\xaf\x29\xb8\x02\x70\x33\x79\xed\xad\xfd\x1c\xaf"
-  "\xb5\xec\x3c\x2d\xf5\xae\xd7\x69\x52\x04\xf0\x78\xbf\xa0\x7a\x3c"
-  "\x4d\xe2\xf5\x2f\xa4\xa5\xe7\x85\xd5\xbe\x99\x61\xab\x6f\x19\x4f"
-  "\x53\x62\xeb\xdd\xa9\x9f\x05\x77\xcb\xb5\xf4\xf5\x7e\xba\xae\xe8"
-  "\x1e\xfe\x2e\x60\x75\x81\x70\x99\x85\xb8\xc6\xae\xa9\xfd\xec\xea"
-  "\x45\xd6\x7a\xc5\x7f\x72\x9f\x08\x7c\xc7\xfb\x70\xfa\x9e\x84\x49"
-  "\x9e\x95\x4f\xbd\xca\x23\x06\xd2\xb5\xa8\xf5\x47\x9b\xc4\x43\x3f"
-  "\xe7\x1a\xde\x72\xf3\x32\x86\xc1\xf8\xe4\x2d\x57\xfb\x19\x7c\x06"
-  "\x16\x34\x96\xf1\x58\xab\x5e\xa7\xe4\x1f\xbc\x4e\xb6\xf6\x95\xdc"
-  "\xae\x6a\x55\x46\xb3\x10\xe3\x1b\x71\xf3\x78\x03\x6f\x00\x6f\xae"
-  "\x4f\x7e\x53\x37\x74\xd6\xe3\x2c\x15\x11\xcf\x33\xac\x57\x56\x7f"
-  "\xe0\x29\xde\x47\x0b\xf9\xcc\x30\x9f\x17\x5a\x4a\xfe\x26\xc0\x6b"
-  "\x1a\x4f\x36\xc0\x6a\xf7\x16\x12\xaf\x77\xdf\xe0\x29\x3e\xc0\xb0"
-  "\x8f\xf3\xbc\xb2\x03\xf4\x51\xf3\x8b\xbb\xce\x1b\x3c\x4a\xed\x18"
-  "\xe7\x0b\x8a\x44\x98\xe1\x9c\x24\xf7\xd5\xb2\xbd\xbb\xec\x8e\x3c"
-  "\x75\x4e\x59\xb6\x75\x70\x9f\x48\x6f\x87\xf7\x1c\xc3\x73\x4f\xf1"
-  "\x2e\x83\x7d\xab\xb7\xc9\xa0\xb5\xe2\x2f\xf7\x2a\x4f\xf1\x1e\xe2"
-  "\xfe\xe1\xfc\x78\xce\xf5\xf6\x20\xef\xe9\xd8\x7e\xe1\x3c\x78\xb7"
-  "\x1d\x70\xbf\x31\xb4\xd7\xc9\x7b\x70\x43\x79\x1a\x5e\xe7\xf3\x10"
-  "\x3b\xdb\x76\x81\x46\x6a\xcd\xb8\xfa\x3c\xe3\x8a\x51\x14\xf0\x96"
-  "\xfe\x35\xb1\x1f\x23\x64\x00\xf8\x7e\x73\x87\xdc\xf3\x71\x7f\xb2"
-  "\x20\x14\x11\x4a\xae\xd5\xd4\x47\x20\x0f\x7c\xb8\xb2\x4c\x90\x72"
-  "\x65\x1a\xfb\x8e\xd4\xbc\x66\x35\xa9\xfe\xe5\xb6\xb0\xee\x93\xa8"
-  "\x8f\xa3\xf6\xa3\x6c\x8c\xab\xd1\xc7\xfc\x4d\xb3\x08\xef\x29\x8e"
-  "\x07\xbd\x07\xec\xa4\xf8\x4f\xb8\x01\x57\xf7\x8f\xb7\x55\xe9\xf3"
-  "\x62\x55\x6f\x4a\xca\x2c\xf1\x82\x9d\x0c\x7f\x52\x8c\xdf\x99\x79"
-  "\xca\x47\xd7\xce\xb2\xaa\x49\x53\x63\x87\x71\xd4\xcb\x6e\x53\xfb"
-  "\xf8\x35\xb9\x28\x9f\xf0\xdb\x6e\xc2\x0c\xf9\xe3\x82\xb8\x46\x7b"
-  "\x78\xfe\x14\x90\x59\x98\x17\x46\x7a\x03\xfd\xfa\xb7\xe3\x6a\xaf"
-  "\x82\xce\x3c\x92\xcf\x26\x18\xb8\x5d\xde\xde\x51\x8d\x4f\xd9\x29"
-  "\xb5\x0e\x63\xed\x45\xd8\x40\x63\x97\x55\xf0\x19\x1e\xf6\x35\x0f"
-  "\xa4\xac\x2f\xf2\xa7\x6c\x6f\x56\xe3\xa6\x76\x2e\x74\x5e\x29\x77"
-  "\xf3\x82\x54\xc9\xed\xe2\xbd\x41\xd8\x40\x23\xb9\xcd\x80\x53\xe0"
-  "\xa3\x95\x6d\x6a\x5e\x57\xb0\x87\x5d\xfb\x30\xda\x86\x36\xc9\xb6"
-  "\xa1\x8d\xb2\x6d\xfa\x37\x57\x50\x97\x3c\xbb\x7b\x79\xed\xa9\xd5"
-  "\xf5\xfd\xf5\x45\xfc\x5d\xc8\x93\x54\xb7\x49\xfa\x5b\xa3\x4f\xd4"
-  "\xfa\xfa\x2b\x33\xc5\xe8\x1f\x8c\xbe\x3c\x98\xaf\x58\x14\xcc\xed"
-  "\xcd\x3f\xe4\xf8\x6c\xfa\x77\x9b\x00\x7b\x05\x64\x7a\x33\xdb\x06"
-  "\xbd\xa8\x8f\xbf\x79\x37\x24\x87\x5e\xe9\xe6\xbe\x9a\xb6\x8f\x32"
-  "\x15\x1f\xbe\xf2\x71\xa3\xfa\xe6\x0e\x74\x83\x57\xaa\xc0\xf7\xea"
-  "\x9b\x35\x83\xbe\xc7\x26\xe9\x7b\x1c\x2d\x63\x2f\x13\x47\x29\xef"
-  "\x44\xea\x5a\xd8\x47\xaf\x94\xf3\x7e\x3a\xe3\xbb\x3e\x64\xc8\xbf"
-  "\x57\xca\x8d\xbd\x25\xb9\x9f\xbc\x01\xbc\x52\xa1\xce\x2e\xf6\xb9"
-  "\xea\x26\x18\xba\x8a\xfc\x4e\x8f\x4b\x1c\xe6\x7c\x0b\x37\x9c\x95"
-  "\xfb\xcd\xd5\xf2\x9c\xee\x29\xfd\x8c\x4b\xdd\xad\xfa\xda\x44\x3a"
-  "\xfb\x7d\xa3\x2c\xf4\xbf\x03\xd2\x8f\x9f\x69\xc0\x75\x4b\xdc\xe5"
-  "\xb7\x72\xea\x4a\x87\xf6\x13\x5e\xc9\x91\xe9\xd2\x17\xb2\xae\xca"
-  "\xe0\x11\xb4\x77\xa4\x8a\x97\x57\x7b\xfe\xd0\x14\x92\x3c\xd0\x2b"
-  "\xec\xa3\x6f\x6c\x60\x9e\xac\x3b\x10\x4d\xa7\x85\xa1\x88\x53\xc9"
-  "\xa0\x57\x1a\x84\x1c\xeb\xaf\x34\x7c\xb1\x5e\xf1\xc3\x2b\x0c\x9d"
-  "\x44\xd1\xd9\x06\xf9\xf2\xa3\x23\x92\xd6\x6e\x2a\xe2\x58\x06\x2f"
-  "\x54\x70\x3c\x96\x1f\xfe\x91\x63\xdd\x84\xdc\xe4\x0e\xf3\x79\xa8"
-  "\x95\xec\x93\x02\x5d\xba\x88\xb4\xbc\x22\xde\x43\xc9\x96\xb6\x9a"
-  "\x70\x42\x27\x48\x85\x9e\x82\x71\xbe\x69\x15\x59\x1f\x2f\x00\x6c"
-  "\x67\x7a\x1a\xc7\xa2\xe1\x38\x34\x1c\x4f\x2a\xec\x4c\x4f\xc5\xfd"
-  "\x38\xe8\x75\x36\xfe\x36\x3c\xfb\x5b\x84\x5d\x02\xf2\xf8\x18\xc7"
-  "\xc3\xd1\xbc\xfe\x20\x6d\x3a\x4d\x49\x1c\xeb\x26\x54\x93\x6d\xef"
-  "\x08\x7c\x2c\xed\x94\xb1\x45\xd0\xcd\x23\x34\x01\x34\xb7\x47\x52"
-  "\xb2\x09\x73\xbc\x45\xb5\xfb\xac\x50\xed\x56\x78\x33\xfe\x4a\xc6"
-  "\x69\xcd\x15\x12\xf7\x1f\x3d\x17\x02\xfc\x88\x7b\x54\x43\xd8\x3d"
-  "\xaa\x5e\x9d\xa3\x6a\xa3\x8a\x52\xd1\xed\x85\x8e\xcc\x3e\x7f\x7c"
-  "\xa6\x8c\xfd\x39\xb8\x8d\xdc\x3e\xae\xfb\x4f\xe7\x4e\xcb\xd8\x3d"
-  "\x21\x3c\x3b\x0b\xf5\x32\x3d\x28\xd3\xd3\x46\xfd\xee\x51\xb2\xed"
-  "\x1d\x01\x55\x36\x4f\xde\x73\xf9\x28\x3a\xe8\x6d\x1e\xa4\x03\xda"
-  "\xce\xed\xe3\xf6\x87\x98\x26\xa0\x81\xde\x56\xfb\x80\xde\x4e\x6e"
-  "\xe3\xbf\x63\xd6\x79\x1d\xed\x44\x5b\x65\x3b\x07\xd0\xce\xc3\x05"
-  "\x44\xc1\xda\xf5\x95\x9f\xa7\x8e\xaa\x67\x5b\xd3\xf9\x11\xf4\xe9"
-  "\x72\x37\xc1\xa6\xb4\xbc\x5d\xe1\xd6\x5e\x86\x6e\x52\xe1\x87\x6d"
-  "\xe9\x17\xdd\xac\xf7\x7b\x8b\xf0\x0b\x35\xc8\x6f\x6e\x4a\x3d\x99"
-  "\xbf\x99\xb8\x16\x6d\x8a\x7c\x42\x15\xdd\xa2\x1b\x3a\x6a\xd0\x1b"
-  "\x42\x9e\x02\xb4\x1f\xb6\xe8\x49\x1d\x7f\xce\xbb\xe9\x33\xd5\x2e"
-  "\x6b\x21\xa5\xbd\xff\xbd\x6d\x9a\xf7\xe8\x36\x32\xda\xf2\x04\xf2"
-  "\xa1\x3d\x76\xc0\x92\x71\xe3\x22\x68\xe7\x2e\xe0\x19\x8c\x6a\x53"
-  "\x7b\x4f\x10\x30\xff\x42\xa3\x73\xc8\xf4\xfa\x19\xb4\xe3\x0c\xd9"
-  "\xdd\x15\xd0\xbf\x1e\x66\xbd\xf1\xd5\x37\xbf\x92\x4b\x93\x7c\xf4"
-  "\x43\xf5\xbd\x8a\xc1\xef\x9a\xff\xa8\xdd\x88\x9f\x11\xe1\xf8\x43"
-  "\x29\xd9\x13\x98\x8f\x64\x2c\x0d\x9e\x33\xfa\xc0\x33\xec\x8b\xb1"
-  "\x1e\x75\xf4\xa5\x8f\x93\xf8\xb8\x54\xfc\x0d\x3c\xf3\x77\x54\xd2"
-  "\x78\x7d\x01\xe5\xec\x02\x34\x63\xf8\xd0\xe7\x2c\x7c\x65\x1a\x26"
-  "\x3c\x9f\xf0\x0e\xcd\x44\x1d\xfc\x1d\x0b\x6d\x7f\x85\x5f\x7b\xf1"
-  "\x1d\x9a\x72\x79\x32\xe5\x47\xa1\xe1\xe4\x37\xaf\xeb\x33\x3c\xb4"
-  "\x2d\xf5\x14\xd5\x1f\x8f\x1d\x63\x0e\x29\xcb\x94\x1c\xac\xdf\xcb"
-  "\x6b\xe9\x97\x57\x6f\xbd\x8a\xdb\xe3\x12\xdb\x2e\xb3\xdc\x3e\x03"
-  "\x0f\xdc\x17\x0c\x87\xfb\xe5\xd3\xe1\x35\xcb\x70\xb0\x76\xbc\x2a"
-  "\x63\x29\x39\x77\xbe\x0a\x79\x01\x5d\xe1\x90\x9d\xe3\xda\x62\xee"
-  "\xdc\x13\xa0\x92\xdd\x94\xe4\x3c\xcd\xeb\x3b\xd9\x74\xa8\x21\x83"
-  "\x1a\x61\xdf\x8b\xde\xf4\xd4\x57\xce\xf1\x9e\xba\x92\x21\xac\x93"
-  "\x76\x04\x50\xa6\x24\xdd\x56\xfd\xaa\xa1\xc3\xbf\xd6\x5e\x7e\x9e"
-  "\x34\xf5\xdd\x80\xd7\xda\xb2\x1c\x22\x54\xa7\x45\x0a\x1a\x38\xb6"
-  "\x4c\xea\x5a\x37\xc7\x96\x31\x62\xad\x48\xdd\xa7\x0c\x63\xae\xd7"
-  "\x3e\x7a\x47\x31\x4d\xe1\xb8\x50\x56\xbf\xd2\xe5\xd4\x7c\xfd\x1a"
-  "\xcb\x58\x9b\xbe\x8f\x6c\x53\xf1\x57\xea\xb3\x9a\xce\xa1\x2e\xf9"
-  "\xfe\xf5\xa9\x61\xd8\x32\x12\x6e\x31\x4d\x6a\x38\x47\xe9\xac\x07"
-  "\xe5\x7d\xa2\x74\x36\xb6\x0f\xb3\x7b\xac\x22\xfc\xbf\xd2\x69\xf7"
-  "\xa9\xa1\xb8\x51\xfe\x12\x8e\x35\x25\xec\xc3\x9d\x11\xad\x1e\x27"
-  "\x7d\x46\x64\x0c\x00\xf5\x5d\x29\xa2\xba\x5a\xb2\xf0\x77\x14\x79"
-  "\xad\x8e\xd7\x79\xf9\xac\x88\x9a\x43\x5e\x6f\x30\xe2\xea\x24\x96"
-  "\xe5\x25\x99\xd3\xa5\x8e\x55\x92\x79\x79\xfd\xf6\xfa\xc1\x61\x6d"
-  "\x15\xc0\x64\x3e\xf8\xef\xc1\xdd\x95\x76\x09\xbd\xc6\x12\x71\x2b"
-  "\xdb\x2c\x32\x12\x36\xa3\xbf\xcf\xe3\x59\xc7\xf3\xdb\x2e\x37\x9f"
-  "\xa5\x19\xb2\xc7\x76\xad\xe5\x77\x9c\xc6\xbe\xde\x99\xb2\xdf\x77"
-  "\xb5\xb0\x8d\xa6\xdb\xb9\xef\x3b\x06\xd3\x94\xbe\xc5\xf3\x2e\xd3"
-  "\xab\x49\xad\x5f\x8f\xed\x73\xed\x3a\x62\xcc\xbd\xac\x83\xa8\xef"
-  "\x4d\xee\xea\xf6\x69\x07\x2f\x15\x33\xd4\xa6\x7f\xaf\x55\xeb\xe5"
-  "\xb8\x3e\xae\x06\xbb\x31\x17\xcb\xef\x09\x6c\x19\x7f\x7f\xc9\x06"
-  "\x9a\xf0\xc8\xd5\xbc\xa7\x2d\xcf\x44\x74\x2b\x1d\xa1\x21\x73\x68"
-  "\x6f\x2c\x53\xf2\x86\xfc\x56\x18\xdb\x43\x1a\xf4\x05\x15\xcf\xaa"
-  "\x47\xe9\x0a\xc6\x79\xd8\x86\xc7\xa3\xea\xa9\x1c\x9c\xf3\x51\x07"
-  "\xfb\x36\x30\x7c\xa5\x47\x35\xcc\xe0\x3a\xd8\x0e\x54\xba\x40\xc3"
-  "\x8c\x4b\xd0\x37\x9d\xe9\x1b\xd1\x6d\x5f\x6f\xcf\xdf\x15\x7d\xcb"
-  "\xc8\x3c\xbd\x8e\xec\xef\x57\xf8\x2c\x98\x63\x4c\x8e\x62\xb2\xa2"
-  "\xfe\x8f\xf8\x3d\x8f\x4b\xcf\x34\x5e\x83\xdc\x3d\xd5\xcb\x3a\xc6"
-  "\x40\x6e\xf2\x02\x5e\x9f\x90\x76\xc3\xee\x09\x53\x51\x0e\x69\xa9"
-  "\xbf\x3f\x13\xb4\x54\x6f\xa4\x29\xfc\x4d\x3e\xa4\x4b\x1f\x04\xff"
-  "\x57\x9f\xed\xbb\x31\x8d\xec\x37\xd6\xb1\xbf\xfb\xee\x2c\x9f\xf6"
-  "\xbb\xf9\x72\xad\x8b\xeb\xaf\xdd\xde\xc9\xb1\xbc\xde\xed\xf7\x8d"
-  "\x50\x7d\xb5\xfb\x38\x9e\xd3\xa3\x9e\x37\x19\x7b\x08\x3e\xda\xed"
-  "\x93\xfb\x90\xec\xd3\x2b\xfd\x5d\x8b\x67\x0e\xf9\xca\xec\x3e\xae"
-  "\xe3\x72\xfc\x50\x11\xd1\x6e\x3e\xc7\x30\x4e\x74\xa2\x3e\xe8\x3f"
-  "\xbb\x02\xfa\x1a\x52\xa7\xe4\x2b\xd6\xcd\x5f\x62\x7b\xf1\xef\x9e"
-  "\x1d\xc8\xc7\x73\x5a\x5e\x19\x65\x2a\x7b\xa3\x38\x27\x02\xfe\x19"
-  "\x6a\xff\xee\x6c\x5e\xe3\x4c\x28\xbf\x5f\x27\x92\x65\x6a\xd6\x96"
-  "\x49\xff\xaa\x9a\xaa\x0c\x5c\x93\x30\x16\xe6\xe2\x9a\x0c\x9e\xe3"
-  "\xab\x0d\xd7\x4c\x5c\xd3\x44\xcd\xcb\x36\xe6\x4b\xd8\xdb\x76\xd8"
-  "\x34\x49\xbd\x29\x6b\x8b\x86\x3b\x8b\xc7\xb4\xf1\x6e\x7d\x94\x94"
-  "\xbf\x68\x63\x6b\xbb\x1f\xba\x24\xc8\x59\x12\x12\xfd\x8e\xeb\xf8"
-  "\xcc\x4b\x63\xab\x73\x37\xfb\x7b\x34\xd6\xc7\xfa\x7b\x34\xb6\xe0"
-  "\x17\x04\x87\xcf\xc7\x0f\x7a\x64\x63\xeb\xd0\xaf\xa9\xa5\xcf\xd5"
-  "\xd8\x0a\x3a\x86\xa4\xae\x79\x59\xe3\xb5\x51\x7e\x23\xae\x9a\x6d"
-  "\xb8\x94\x45\x99\xaa\xbd\xdb\x2b\xf1\x9c\x24\x52\xb6\x7b\xf4\xf6"
-  "\xe6\xe2\xd9\xe6\x70\x62\x0e\x4e\x01\x4d\xc6\xa3\xcd\x29\x55\x19"
-  "\xdc\x5e\xc6\xb7\x37\xa5\x64\x6e\xf4\x39\x44\x86\xc9\xed\xf7\xa7"
-  "\x14\xf3\xba\x04\x89\x69\x36\xbf\x41\x4f\x9d\x4e\xbc\x5f\xa5\xf5"
-  "\x02\x86\xd2\xd9\x90\x1f\x30\x8c\xfc\x83\xb4\x1f\x4f\x52\xc7\xe3"
-  "\xba\x60\xbf\x27\x19\x67\x1c\xfb\x5c\x4d\xfb\x3f\x28\x54\x7b\x19"
-  "\x5c\x36\x10\x55\x96\xcf\xc6\xc7\x94\x4f\x89\xea\xbb\xf1\x68\x4b"
-  "\x4a\x76\x86\xea\xbb\xb5\x95\x3a\x2e\x69\x0a\x97\xe2\x8c\x93\xd4"
-  "\xf8\xa1\xc2\xa7\x69\xcf\x70\x63\xac\x62\x22\x74\x54\x48\xe4\xe9"
-  "\xca\x76\x9d\xe5\x9d\x10\x20\x6f\x43\x04\x7a\x4b\x71\x51\x66\x85"
-  "\xf0\x9c\xa4\xe6\x4d\x1d\xc1\xee\xcb\x9c\xd3\x9b\xa5\xdf\xad\xe8"
-  "\xaf\x24\x6f\xf9\x6d\xf2\x1b\xb5\x67\xe8\x8d\xb7\xbd\x7e\x19\xeb"
-  "\x99\xef\xa5\x0f\x2f\xfb\x62\xf0\xfc\xc6\xb1\xcf\x8c\x75\x82\x08"
-  "\xf2\x36\x72\x3a\xd2\xbc\x01\xbf\x8c\xb1\x36\xe4\x4b\xbd\x36\x57"
-  "\x8d\xb5\x37\x56\xc8\xf3\xdb\x8c\x6f\xe8\x5b\x1e\xc6\x39\xe2\x5e"
-  "\x9b\xcb\x6d\x70\xc2\x86\xf5\x86\xfa\x3c\x3c\x56\x1c\xeb\x78\xdd"
-  "\xf3\x8d\xfb\xc0\x8f\x22\x52\xb3\x36\xf7\xf2\xda\xf0\x86\x8c\x11"
-  "\xec\x0c\x89\x33\xfe\x94\xb5\xb9\xac\x57\x55\x57\x8c\x48\x9a\xd3"
-  "\x20\x3c\xbd\xa9\xc5\x45\x7d\xae\x37\xf2\x3f\x28\x53\x7d\x76\x99"
-  "\x70\xf3\x8d\xb6\x37\xea\x6d\x07\xbd\x24\xcf\x4e\xaf\x57\x31\xe5"
-  "\x90\xa7\x61\xf8\xb9\xac\x38\x87\xe7\x32\xf6\xf3\xd4\x69\xd1\x33"
-  "\x38\x67\x5c\x1e\x1e\xc3\xc7\xc6\x1e\xaa\x63\x40\xd5\xf1\xe3\x9c"
-  "\xff\x5e\x1d\x3f\xce\xb9\x54\x1d\x90\x19\xd7\x9e\xa2\x1f\x1f\xbb"
-  "\x7c\xfb\xf7\xc7\xd2\xfe\x85\x5c\xcd\x55\xb2\x74\x4f\x76\x18\x36"
-  "\x68\xc8\xb6\xbd\x52\x7e\x4f\x46\xa3\x4a\xaf\x2f\x44\x21\xf7\xa2"
-  "\xcc\xf6\xb2\x7e\xf2\xac\xfb\x33\x75\xd1\x4f\x64\xfc\xd7\xf6\x52"
-  "\xb6\x3b\xb7\x7b\x06\x6a\x8b\x3d\x03\xda\x8f\xa7\x30\xbd\x77\x73"
-  "\xfc\xbe\x28\x3e\xeb\x08\xfc\x99\xbc\xcb\x78\xad\xb8\x93\xd7\xe8"
-  "\x3d\x90\x1b\x95\x11\xc8\x0c\xd8\x19\x61\x49\x0f\xe8\x60\xca\x66"
-  "\x5c\x5f\x20\x6d\x46\xbf\x3c\x97\x37\x06\xba\x7b\xb2\x70\xad\xdc"
-  "\xca\xeb\xf8\xe1\x81\x5c\x47\x9f\x8b\x72\x38\x96\x1e\xaf\xa1\x0b"
-  "\x9b\x0d\xf4\x34\x0b\x69\x13\xc2\x7e\xe1\x98\x7a\xde\x80\x8f\xc2"
-  "\xb0\x05\x1a\x2e\x50\x5a\x03\xf4\x67\xc8\x72\x1b\xcb\xfb\x26\x3d"
-  "\xa6\xde\x8e\x0b\x43\x31\xf5\x1a\x79\xbd\xea\x28\xee\x2f\x90\x25"
-  "\x5c\xb3\xbe\x60\xd7\x05\x9a\xb4\x7b\x1d\xa5\xef\xe2\xf5\xc8\x4f"
-  "\x95\xfe\xc6\xfa\x86\x8c\xaf\xb7\x26\x9d\xf7\x26\x86\xf4\xb7\xf5"
-  "\x1c\xf7\x73\x50\x9e\x59\xe4\x3a\xce\x65\xd1\x7b\x8f\xfc\x46\x40"
-  "\xc8\xbd\xb6\x2c\x64\xab\xca\x18\xa8\x2d\x99\xeb\xa3\x9f\xcc\x1f"
-  "\xd0\xde\x38\x9c\xa8\x6f\x0d\x5f\xab\xba\xa8\x98\x88\x1f\x4c\x52"
-  "\x72\x1f\xb0\x86\x8f\xcb\xb6\x2b\x97\xa6\xf7\x50\x86\xf2\x9f\xb8"
-  "\x02\x73\xe5\x9e\x00\xef\xe7\x57\x3c\x47\xf6\xf0\xae\xa5\x26\xe7"
-  "\x1b\x64\xe6\xef\x17\xf3\xaf\xe2\x33\xd1\x3d\xbd\x90\x32\x78\x2f"
-  "\x85\x7d\x2c\x1c\x2f\xc8\xfc\x1f\x4e\x2a\xa7\x8c\x68\xd8\x73\x95"
-  "\xf3\xd3\xdd\x8e\x79\xab\x9f\x5a\xf3\x5c\xd1\xf2\xd2\x55\x4f\xae"
-  "\x2a\x5c\x55\xba\xe1\x6e\x19\x4c\x58\xfe\x7b\x70\x72\xfe\x62\xb9"
-  "\x09\x1e\xa5\x77\x4c\x1a\x5a\x53\x7c\x73\x53\x98\xd7\x40\x2e\x8b"
-  "\x5e\x6f\xce\xd5\xf7\x15\xfd\xbb\xe5\x3e\xdb\x9b\x6e\x9f\xf6\x6f"
-  "\x0e\xb5\xb6\x51\x92\xb9\x43\xc5\x43\xe9\xf6\xdc\x10\x66\xf8\x73"
-  "\x15\x2f\xbf\x6c\x03\x2f\xcf\x3a\x41\x7b\x97\xf2\xfe\x0e\xfa\x6b"
-  "\xae\xb7\xfc\x14\x41\x47\x99\xc5\xfb\x46\xed\xbc\x26\x23\x75\xf8"
-  "\x9f\xaa\x33\x0c\x67\x64\x6c\xa0\x3d\x27\xf0\xcc\xbe\xea\x11\x91"
-  "\xbb\x2b\xbc\xc6\xbe\x27\xb2\xc6\xfe\x53\x21\x72\x5f\x8f\x9c\x2d"
-  "\xd8\x25\xce\x16\xbc\x3e\x74\xae\xff\xa7\x57\x85\x5c\x64\xc6\x0f"
-  "\xbc\x60\xf2\x45\xed\x21\xf2\xbb\xbb\x18\x66\x51\x31\xfb\x72\xfd"
-  "\x94\xfd\xa3\x61\xfb\x9b\xfe\xe6\x77\x16\x98\xe7\x77\x81\xe7\x55"
-  "\xbd\x2b\xbc\x5b\x4f\x92\xda\x37\xfe\x69\xbe\x47\xae\x73\xff\x34"
-  "\xcc\xe5\x78\x9f\x91\xf5\x7e\x19\x3f\x54\x7b\x53\xfa\xf2\xb1\xce"
-  "\xbf\x3b\x95\x6c\xee\x54\x4a\xee\x73\xfd\x74\xd0\xff\x4b\xd8\xd4"
-  "\xdc\xca\xf3\x1b\xc7\xbb\x85\x8c\xe9\xe3\xb9\x92\xf1\x60\xbe\x04"
-  "\xcc\x83\xbc\x07\xa9\xce\xfd\xfc\xf4\x30\xf4\xc8\xbd\x97\x2f\x63"
-  "\x7f\x2a\xd7\xe4\x85\xe6\x14\xd3\xab\x68\x99\xdc\x1f\x56\x7e\x8a"
-  "\x16\x8c\x43\x87\x6a\xcf\xde\x3b\xe4\xde\xfe\xba\xd3\xcd\x18\x27"
-  "\x95\x4d\xfd\x94\x1c\x71\xdb\x26\xb1\x3e\xd3\x5e\x2e\xf7\xd5\x93"
-  "\x50\x6e\x3f\xef\xbb\xcb\xb3\x72\x32\x7e\xf2\x9f\xa9\xe9\x3c\x59"
-  "\xba\xe8\x67\x59\xbc\x3f\x30\x44\xdb\x9f\xbd\xc6\xfb\x42\x62\xa7"
-  "\xc8\xb5\x96\x6b\xdb\x18\x46\xe4\xc2\x99\x99\x46\x39\xcc\xe1\xa3"
-  "\xb8\xdc\x09\xfa\xd9\x26\x59\x8e\xf3\xca\x6f\xef\xd9\x96\x62\xde"
-  "\x2a\xe3\xfc\x21\x3c\x37\x46\x6c\x39\x02\xe3\x2b\xbc\x2e\xbc\x1f"
-  "\xef\x16\x47\xdc\x25\x73\x91\x96\x2b\xd7\xa5\x07\xec\x24\x63\x74"
-  "\xd8\xb2\x67\x7a\x7d\x7f\xf7\x48\x7c\xd8\x5f\xb5\x14\xb2\x48\xea"
-  "\x7f\x3f\xfb\xa8\xf1\x53\x19\xd7\x19\x7d\xb8\x37\x5f\xe7\x91\xbd"
-  "\x0a\xbf\xbd\x2b\x7a\x6b\x47\xd5\xf7\xda\x8a\xe7\x06\xb4\x24\x3a"
-  "\x64\x67\xbf\xf8\x97\x6d\x87\xec\xfd\xb0\x21\xf6\x4e\xf1\x99\x23"
-  "\x87\x95\xee\xa1\xca\xf1\xbe\x14\xf4\xd2\x1e\xb3\x7d\xec\x00\xde"
-  "\xcf\x37\xfc\x3b\xf8\x7b\xd5\xbc\x2f\xe5\xa3\x9f\x4d\x62\xba\x81"
-  "\xcf\xdb\xe4\xde\xc4\x96\xc7\xba\xd1\x9e\x91\xec\x83\xc7\x74\xe6"
-  "\xf3\x07\x56\xdc\x8b\x75\x62\xa6\x35\x94\xa9\x35\xc9\xb3\x86\xf2"
-  "\x0c\xfb\x0c\x3d\xce\x48\x86\x1e\x77\x64\x0a\x3f\xab\x33\xf0\x7b"
-  "\x0f\x18\x67\xce\x39\xb6\x8a\x7e\x5e\x4c\xfa\xf5\xc9\x98\x23\xe7"
-  "\xd4\xde\x2e\xfb\xf5\xf1\x9a\x26\xfb\xc9\xf3\xfe\x2b\xca\xf5\x44"
-  "\xf9\xc6\x9b\xf0\x1c\x32\x62\x8d\xf4\xb9\xde\x4a\x1a\xf4\x17\x42"
-  "\xdb\x7b\xdd\xc5\x99\x01\xdb\xcb\xb6\x80\x7b\x2d\xe6\xef\xb7\x26"
-  "\x41\x16\x15\x5e\xc2\x76\xb2\xf0\xd9\x43\x8e\x2f\x11\x49\xb5\xcd"
-  "\xe7\x18\x13\x1c\xcb\x4a\xf9\xb7\xbf\xf5\xa2\x7e\xa6\xdb\x7c\x86"
-  "\xde\xba\x6f\x68\x1f\x34\xac\xaf\xdd\xbd\xb5\x4f\xe9\x5d\x6f\xed"
-  "\x93\x6b\x77\xb5\xc5\x8e\x9f\x6c\x0c\x6a\xfb\x37\xfa\xb4\x46\x79"
-  "\xbe\xeb\x2d\xd0\xee\xdd\x42\xc3\x47\x06\xf9\x96\x31\xac\xc4\xf3"
-  "\xe4\xb8\x24\x05\xf3\xe7\x32\x46\xe9\x90\x7d\xf3\x73\xf5\xdd\xa3"
-  "\x2d\xe3\x97\x45\x78\xce\x4b\x5d\x94\x23\x7d\x4b\x8a\xce\xf1\x1a"
-  "\xde\x48\x65\x6b\xa9\x3c\xba\x5f\xe6\x95\xa7\x62\x9f\x53\xf9\x59"
-  "\xd1\xec\xe7\x19\xc6\x7e\xc0\x4e\x2d\xe2\xb3\x9a\x48\x38\x9b\x45"
-  "\x80\x63\x98\x41\x9f\xf2\x7b\x31\x87\xa2\x0e\x01\xf9\x30\x0a\x65"
-  "\x56\x30\xed\xd5\x18\xfa\xb9\xfc\xbe\x47\xc4\x75\xaf\x70\xb2\x1e"
-  "\xe9\x67\xdf\x96\x73\x84\x7c\x29\xc8\x57\xd3\x5a\xde\xc3\xbe\x33"
-  "\x76\x8e\x0d\xd6\xa5\xd7\xed\x4f\x19\x97\x74\x63\x32\x2d\x43\x9d"
-  "\x7b\x7c\x54\x5e\x7e\xf9\x63\xfb\xe7\xc3\xea\xb2\x43\xed\xfa\x45"
-  "\xda\x50\x9f\xfc\x4d\xef\x93\x5f\xa4\x7d\xd1\x1e\xb2\xae\x93\x5c"
-  "\x75\x8a\xde\x1e\xc1\x76\x33\xee\xaf\x3f\x45\xfb\xe4\x1e\xa5\xf2"
-  "\x45\xde\xf7\x47\xfd\x1e\x75\xec\xfb\xa5\x7e\x7f\x0d\xee\x5f\xd3"
-  "\xef\xc7\xe3\x7e\xb3\x7e\x0f\x7a\xef\x5b\xa5\xdf\xa7\xe1\x7e\x91"
-  "\x7e\x8f\xf1\xb9\xef\x2e\xfd\x7e\x1c\xee\x27\xea\xf7\x57\xe3\xfe"
-  "\x0a\x7d\xef\x2d\x09\xf8\x9e\xbf\x7c\xbd\xe8\x17\x1e\xb5\xbf\xc3"
-  "\xfb\x6a\x6f\x4e\x51\x63\x7a\x30\x2d\x0d\xf6\xe5\x62\x63\x7d\x1d"
-  "\xe9\xfc\x2d\x9e\x24\xa4\x4f\x01\xff\x65\x44\xa5\xef\xd5\xf3\x67"
-  "\x41\xcf\x72\x47\xa5\x37\xe8\xe9\x4b\x91\xbf\x25\x2a\xdd\xad\xa7"
-  "\x97\xfa\xa8\xee\x58\x54\xfa\x56\x3d\xbd\xca\xd8\xd3\xd6\xd3\xcb"
-  "\xf4\x74\xf4\x7f\xd5\xd6\xa8\x74\x3d\x9e\xe0\xbe\x83\xe8\xe3\xae"
-  "\xa8\xf4\x65\x92\x67\x65\x5c\x38\xab\x38\x54\x3e\x03\x63\x7e\x9f"
-  "\xcf\x47\xb5\xe5\x51\x79\x16\xeb\x65\x83\x3e\xaa\xd9\x13\x95\x3e"
-  "\x57\xa5\xbf\x6d\xf3\xd1\x5f\xf7\x46\xa5\xcf\x1a\x8e\x87\x4c\xf5"
-  "\xb4\x6c\xb8\x75\x2e\xfe\xbe\x87\xf4\x8b\x93\x3e\x91\xef\x64\xf3"
-  "\x19\x19\xeb\x6e\x71\xc2\x51\x21\xc4\x09\x7a\x67\x86\xee\x2b\x96"
-  "\xc6\xfe\x41\x7c\xa6\xa8\x8b\xde\xb9\x56\x9e\x3f\xe1\xb8\x68\x7c"
-  "\xce\x68\x23\x9f\x33\x7a\x5b\xc6\x79\x9d\x5e\x56\xa9\x62\xa6\x29"
-  "\x7f\xc3\x1e\x69\x2b\xe9\x7b\x61\xc8\xc3\xdf\x0f\x25\x86\xc3\xeb"
-  "\x2c\xde\xd2\x7e\xe9\x17\xc7\xba\x2a\xa7\xb1\xcd\x20\xcf\xa4\x44"
-  "\xe9\xac\x6a\x3c\xbe\x93\x1d\xe1\xf3\xc0\x2e\x65\x57\x55\xab\x58"
-  "\x7c\x3d\xec\xc7\x11\x9d\xd7\x47\xef\xcc\xe7\xab\xd9\x6e\x3d\xde"
-  "\xe7\x7a\x67\xca\xd0\xb9\x8a\xb7\xb7\xea\xe9\x3e\xa4\x67\x45\xa5"
-  "\x5f\x14\xdb\x77\x50\x3e\x55\x89\x22\x91\x2c\x9a\x07\x2e\x88\x40"
-  "\xe8\x82\x08\xee\xfc\x4f\xe0\xbd\x52\x9e\x37\xb8\x2e\x5c\x25\xf6"
-  "\xeb\x67\xeb\x8f\x87\xd6\x09\x3f\xf4\x34\x8e\xd5\xfd\x95\x05\xb0"
-  "\xeb\x16\x14\xf5\x89\x1d\x4f\xb2\x5f\xd7\x79\x19\x67\xc6\xd9\xc3"
-  "\x71\x41\xd9\xcf\x27\xc0\x7b\x08\xc9\x1d\x90\x3d\x8d\x2b\xf9\xfd"
-  "\xc7\x94\x5d\x00\xfd\xa7\x20\x4c\x8d\x80\xbd\xfb\x49\xc3\xa7\xe8"
-  "\x9d\xae\x41\xdf\x39\xe0\xc0\xf5\x39\x65\xac\xfd\x77\xa5\x9e\xcf"
-  "\xdf\x10\x12\x35\x55\x99\xe2\x0f\xac\x57\xac\x5d\x66\xdd\x4c\x0e"
-  "\xc8\x5c\x07\xee\x73\xd4\x0f\xef\x90\x3e\x5c\x9b\xd4\x38\x7d\x57"
-  "\x7d\xd7\xd3\x4d\x0e\x25\x0b\xde\x5d\x2a\x7e\xcc\xe7\x2d\xde\x5d"
-  "\x06\x59\x62\x87\x0e\x93\x70\x4d\x74\xd3\x6e\xd2\x06\x6a\x31\x67"
-  "\x9c\x69\xd1\x94\xec\xd9\x3f\x3f\xa2\x25\x6d\xe6\xf5\x1c\x19\x6f"
-  "\xbb\xd6\xb6\x74\xdf\xea\xa0\xd6\xbe\xb1\x8b\x5e\xb8\x9a\xec\x4b"
-  "\x83\xec\x17\xfc\x6e\xfb\xd8\x52\x8e\xfd\x56\xec\x80\x3e\xa0\xfd"
-  "\x1a\xef\x7f\xbf\xba\x45\x0b\xc9\x79\x64\xff\x7c\xb9\x06\xe0\xb6"
-  "\xcd\xe0\x3d\x04\xef\xd1\x30\xeb\x32\xc9\xd0\x65\x26\x89\x92\xf4"
-  "\xa4\xf0\xfa\x82\xd4\x50\x49\xc1\x57\x76\x17\x53\x72\xb8\x24\x3d"
-  "\xed\x95\x0b\x34\xd3\x88\xe3\x0d\x1b\x21\x43\xf4\xd9\x47\x57\xaf"
-  "\xa3\x29\x6c\x43\x8c\x35\xd9\xe4\xbe\x0c\xdf\x47\xb4\x1f\x75\x37"
-  "\xae\xbb\xf4\x37\x03\xc2\xb0\x1d\x38\xde\x2f\xe3\x92\xa8\xad\x55"
-  "\xaf\xc3\x1e\xd1\xcf\xe2\x55\x7c\x42\xe3\xa0\x7f\x68\x63\xcf\x0b"
-  "\xcf\xa9\x42\xd2\x38\xde\x7a\xc5\x0a\x69\xa7\x8f\x68\x2f\x08\x91"
-  "\xb7\xec\xaf\x54\x51\xcc\x7d\xb4\xff\x0d\x9e\x3f\xd9\x4f\x0f\xf9"
-  "\x6d\xa7\x68\xff\x2f\xad\x41\xd2\xf0\x33\x79\x9e\x61\x9d\x7b\xff"
-  "\x87\xac\xf7\xfb\xe8\x97\x49\xec\x2b\xec\x29\xbe\x9f\xd3\x8e\x3b"
-  "\x3f\x91\xfb\xe8\x76\x75\x5e\x6f\xff\x41\x7e\x76\xf2\xd9\xc0\xd4"
-  "\xab\x32\xdf\xe9\x0f\x8e\x50\xb6\xe0\xfe\xf7\x74\xd9\x6f\x43\x9f"
-  "\x4d\x00\xec\x61\xd7\x85\x23\x6e\xb3\x47\x70\xcc\xd6\x86\x10\x2d"
-  "\x08\x08\x9f\xdc\xf3\xe2\x33\xd1\x65\xf7\x7a\xc4\x05\x37\xa9\xf3"
-  "\x40\xbf\xdc\x1c\xa9\x31\x7b\xd8\x27\x00\xf7\xf2\x5c\x9b\x5a\x53"
-  "\x32\x77\xaa\x75\x18\xb3\x4f\xad\x29\x99\xfd\x5b\xc6\xb3\xbf\xea"
-  "\x2f\x2b\x7b\x53\xf8\xdc\xea\x2f\x17\xf7\xa6\x5e\xed\x1e\x7e\xae"
-  "\x21\xbf\xe3\x3a\x4a\xe3\xb5\x4c\xf6\x3d\x6d\x52\x3e\xa7\xa8\xe3"
-  "\x57\x5b\x45\x8d\x7c\x77\xfd\x89\x22\x32\xf3\xfa\x0f\xea\xfd\x68"
-  "\x7a\x03\x39\x80\xeb\x18\x61\x33\x37\x4b\x3f\x20\xb7\x79\xbf\xb7"
-  "\x47\x78\xd8\x0f\x4d\xad\x39\xff\xca\x2d\x52\xcc\xcd\x2a\xff\xaf"
-  "\x26\x76\xf4\xa0\x0d\x36\x73\x91\x37\x78\x5a\x9f\xab\x7f\x05\xde"
-  "\x37\x17\x09\xb7\x59\x3f\x63\xfb\xab\xb5\x86\x5c\x55\x3c\xfa\xab"
-  "\x15\x3a\xaf\xfb\x15\xdd\x7e\xe5\xd6\xe7\xa5\xeb\xf9\x1e\x7a\x42"
-  "\x86\xda\xcf\xfd\xd5\x52\x43\x77\xf1\xe9\x79\xb8\x0c\xee\x33\x95"
-  "\xac\xfd\x55\x39\xda\xae\xef\x03\xff\xca\xc1\x69\x68\x1f\xe6\xa6"
-  "\x5f\xb6\x70\xbb\x86\x93\xad\x92\x16\xe5\x64\x06\xce\xee\x88\x8a"
-  "\xb1\x1a\xf0\x06\xee\xf5\xa8\x6f\x80\x1d\xb8\x5a\x9e\x41\x44\x3d"
-  "\xe8\x1f\x8d\xe5\x26\xc7\x3a\x60\x78\x51\xf8\x87\x0d\x5c\xb8\x3e"
-  "\x7e\x87\xb6\x72\xcc\x2e\xa6\x15\x7f\x17\x95\xb8\x5f\x61\xaf\x9b"
-  "\xd9\xfe\xf6\xac\x63\x9f\x92\x03\xe9\x4c\x13\x45\xb3\x03\x72\xdf"
-  "\xa7\x7a\xb0\x1f\x7e\xfd\x79\x2c\x3d\xd4\x73\x24\x19\xb2\xa1\x98"
-  "\x7d\x0b\x0e\xa4\xeb\xf4\xeb\x51\xf5\xff\xfa\x2f\xba\x0d\x85\x77"
-  "\xbf\xde\x11\x55\xf6\xda\xc1\xbc\xea\x7b\x73\x1a\xef\xd3\xf1\x5a"
-  "\xa8\xe2\xd7\x5f\xb7\x44\x95\x6b\xc9\xfb\x2c\x93\x38\x1e\x3f\x7f"
-  "\x1f\x8c\x69\xde\xe7\xfa\x75\xdb\x10\xbd\x15\x9c\x04\x75\x5c\x67"
-  "\xd4\xe1\xa3\x5f\x57\x19\x78\xe2\x7e\x99\xea\x93\x03\xb6\xa1\x3e"
-  "\xf9\x75\x86\x51\x8e\xfd\xba\xd1\x47\xc7\xf8\xec\x57\x42\x39\xc8"
-  "\x6b\xee\x13\x20\x83\x43\xf7\x7a\x24\x3f\xd2\x81\x6d\xec\x3f\x09"
-  "\xba\xba\x15\x0f\x1d\x28\x54\x73\xe1\x01\x79\xa6\x9d\xd7\xb3\x0f"
-  "\x05\x99\x47\x0e\x54\x02\x6e\x83\x8e\x73\x9d\x8e\x43\x1d\x70\xa8"
-  "\x1a\xf6\xdc\xcc\xe0\xd9\xb5\x03\x07\xa3\xce\xeb\x4d\x51\xb4\xfd"
-  "\x0d\x9f\x95\x3d\xb0\x53\xd9\x0e\x2d\x3b\xd1\x3f\xce\xf3\x34\x9e"
-  "\x63\xea\x57\x14\x89\x53\x1d\x45\xb0\x67\x6c\xb6\x32\xc8\x86\xf2"
-  "\x8a\xf3\x34\x9a\xf7\xe0\x59\xb6\xb0\xaf\x9f\x48\x41\x7a\x8d\xad"
-  "\x7c\xe8\xac\xd2\x6f\xed\x7c\xf6\x6f\x07\xc7\x4c\x3a\x4d\xe3\xd5"
-  "\x9e\xfa\x6f\x1e\x60\x1b\x5a\x38\x61\x37\xbb\x6d\x95\x7c\x76\xad"
-  "\x03\x5a\xb9\x70\x16\xbc\x1e\xa9\xb1\x55\x02\xae\xdb\xf9\x1c\xa5"
-  "\xf2\x5c\xc6\xb6\xb8\xe2\x8f\xdf\xb0\xdf\xb7\x9b\xe3\x36\xc1\xf6"
-  "\x36\xa1\xfe\x23\x11\xdb\x38\x0b\xc3\xe5\xba\xc1\x53\xda\x09\xfa"
-  "\xcd\x0f\x51\xff\x11\xfe\xb6\x17\xdb\xda\xde\x60\x90\xcf\x99\x1f"
-  "\xc1\xbb\xb1\x78\xf7\x01\xae\x11\x8e\xe1\xc4\x31\x68\x01\xdf\xce"
-  "\xf0\x51\xd7\x11\x85\xbb\x8c\xb3\x70\xe4\x04\xfd\xf6\x6a\xce\x63"
-  "\xc4\x86\x8a\x38\x73\xcd\xfc\x9e\xdb\x10\x46\x39\x6f\x99\x8f\x54"
-  "\x99\xa3\xb2\x8c\x8f\xdb\x87\x72\xba\xdf\x86\x43\xed\xb9\xfd\xd6"
-  "\x66\xec\x1d\xf9\xe8\x37\xf9\x8c\x73\xe2\xf8\xa1\xbf\x9d\x19\x1b"
-  "\xcb\xe3\x5f\xf8\xac\x28\xa7\xe7\x18\xf1\x37\x70\x8f\xf1\x7f\x40"
-  "\x9d\x9f\x8f\x8a\xa5\xb3\x33\x2a\x2e\x97\xd3\x2f\xfe\x8b\x71\x01"
-  "\x9f\x9a\x41\xef\xbd\xa2\x66\x9c\x45\x9d\xb3\xf8\xad\x1c\x43\x68"
-  "\x13\xc7\x47\xb1\xaa\x73\xc1\xbf\xfd\x57\xc5\x8f\x26\xdb\xc2\x70"
-  "\xc8\xea\x43\x9d\xa2\xc6\x64\x1b\x7a\xfe\xed\x7e\xf0\xa7\x0d\xf9"
-  "\x3e\x55\x71\xab\x7e\xbb\x37\x36\xbf\x7c\x5f\x19\xf7\x9c\x19\xf7"
-  "\xec\x08\xa0\x6f\x86\xdb\x23\xdb\x31\x5e\xae\x0b\xcc\x18\xbb\x99"
-  "\x8a\x9c\x9f\x92\x19\x7d\xf5\x09\xe3\xd6\xd1\xdd\xc3\x6d\xb2\x0a"
-  "\x57\x06\x79\xbb\x43\x4a\x57\xc1\x1c\x71\x62\x12\xf2\x7c\x4a\xe3"
-  "\xd8\xe7\x94\x63\x81\x23\xff\x29\x15\xb7\xb4\xa5\x66\xe9\xf3\xa3"
-  "\x29\xf2\x74\xee\x57\x84\xf6\xd0\x5c\xcc\x07\x49\x6f\xf7\xfb\x46"
-  "\xf0\xba\x74\xc5\x6b\x34\x81\xe3\x5f\x80\x37\xbb\xf8\x3b\x31\xfc"
-  "\xdd\xde\x9f\xf4\x77\x8f\xf0\x86\xfe\x4a\x45\xcf\x90\x76\x8a\x5a"
-  "\xb6\x5a\xca\xc9\x52\x7d\x92\x6c\x0b\x43\x22\x74\x28\x34\x93\x8c"
-  "\x73\xbd\x0d\xa9\xea\x7c\x24\xec\x72\x7f\x89\x5d\x04\xfb\x5c\xff"
-  "\x02\xfd\xf7\xf5\x5c\xdd\x87\x27\x50\xa5\xe2\x7d\x5b\x50\x7f\xb6"
-  "\xa6\x9f\x61\x56\xb4\x6d\xb9\x56\x9d\xd3\x48\xfd\x5a\x9f\xab\x25"
-  "\x6d\x48\x9f\x6b\x69\x56\x34\x1c\x97\xae\xc6\x57\x4b\xf3\x21\x58"
-  "\xfe\x5b\xd5\x5e\x63\x1a\xf2\x66\x0e\xee\x35\x4a\xfb\xb4\xa5\x19"
-  "\x7d\x98\x2e\x75\x3d\xdb\xb8\xf4\xbc\x70\x92\x3e\x06\x90\x0e\x59"
-  "\xc5\x65\x51\xce\x1a\x90\xb6\x64\x4b\xf9\x10\xaf\xb5\xc8\x73\x12"
-  "\x68\x53\x32\xfa\xb5\x85\xdb\xc5\x34\x41\x3e\x0b\x9e\x0f\x1e\xda"
-  "\x33\x4c\xfc\x42\x1b\x39\x42\x2e\xb9\x6f\xc6\x63\xe2\x34\xfa\xe0"
-  "\x4a\x8e\x57\xe2\x45\x3d\xed\x8d\xfd\xd4\x6e\xef\xa5\x8e\x7c\x3e"
-  "\x53\x02\x7d\xf9\x99\xff\xa2\x2e\x47\x62\xf9\x05\x19\xd8\x0c\x9c"
-  "\xf7\x33\x2c\xc8\x89\x6e\xf6\x19\xf1\x96\x43\x9e\xf9\xf9\xfb\x34"
-  "\x24\x61\xb4\x47\xba\xa9\xbd\x8c\xf5\xf6\xaa\xcc\x8e\xc6\xbf\x52"
-  "\x87\xfd\xff\x96\xf5\xb0\x8e\xe1\x29\xee\xbd\x14\x6c\x0f\x60\x77"
-  "\xea\xb0\x7b\x00\x3b\x6d\x78\xd8\x6b\x97\x5d\x26\xec\xcb\xc0\x7b"
-  "\x6d\xce\xe5\xc0\x86\xac\x98\xe4\xb5\xab\x73\x29\x15\x57\xd3\x98"
-  "\xf0\x05\x8e\x4f\x77\xbd\x50\x3e\x78\xbf\x7b\x5e\x9e\x5d\x71\x49"
-  "\x1f\x47\x87\x3c\xc3\x72\x86\xa4\x1f\x95\x3a\xb7\xf2\x09\xf1\xbe"
-  "\x66\x9f\xeb\x77\xcb\x06\x75\xef\xa1\x75\x65\xc8\x98\xdf\x6d\x55"
-  "\xbe\x56\x36\x87\xe2\xab\xdf\xdd\xc5\xb0\x12\xe3\x91\x92\xa1\x7c"
-  "\xf6\x7e\x67\xe8\x6b\x39\xbd\x29\x29\x19\x3a\x2c\x47\xfc\x7e\xa3"
-  "\xf1\x61\xb8\x15\x65\xa5\xc6\x37\xe6\x4a\xf5\xe3\x6b\x0f\xaf\x78"
-  "\x6a\xc5\xaa\x75\x2b\xf2\x1d\x8b\x9f\x2f\x5e\x3d\x75\xcd\xca\x95"
-  "\x8e\xec\x15\x25\x25\xcb\x9f\x5e\x31\x9a\x16\x17\x2f\x5f\x5d\xb2"
-  "\xaa\x74\xd5\x9a\xd5\x0e\x47\xd6\xed\x79\x05\x6b\x4a\xa7\xde\x93"
-  "\x95\x11\x77\xde\x89\xcf\x3a\x1d\x63\x9d\xce\xb9\x09\xe3\x33\x4c"
-  "\x29\x1c\x7b\xc2\xba\x41\x78\x5e\x80\x3d\x01\xfe\x3b\xc5\xeb\xea"
-  "\x18\xb7\xc7\x59\xd7\xe4\x58\x57\x98\x37\xdb\x76\xbd\x2a\x3a\x4f"
-  "\x52\xdb\x79\xe8\x29\xfc\x7d\x52\x8e\xdb\x74\x0c\x36\x9e\x5f\x7d"
-  "\x07\xa9\xed\x23\x8e\xc9\xf4\x03\xa4\xf9\x53\xc6\xa5\x57\xff\x27"
-  "\x59\x30\xf7\x40\xcf\xfd\xb7\x4e\xa1\x8d\x12\x55\xe3\x44\xab\xf8"
-  "\x2f\x3b\xe9\x31\x65\x35\xaf\x2f\xc8\xfb\x6f\x49\x0b\x43\x4e\xc1"
-  "\xf2\x54\x8d\xad\x7f\xfb\x48\xd1\xc5\xec\x51\xbe\x8c\x6d\xbf\x64"
-  "\x9d\x78\x8b\xfc\x4e\xd5\xbf\x61\xfc\xef\xcf\x1d\x92\xd3\xad\x21"
-  "\x5d\x17\x39\x0a\xba\xaf\x3f\x81\x67\x75\xc6\xfe\x60\x72\xec\x9e"
-  "\xeb\x7b\x3d\x44\x7f\x74\xa8\x1f\x97\xf9\x63\xa6\xfa\xf1\x7d\xf4"
-  "\xaf\xad\x4e\xfd\xe2\xd3\xff\xd1\x9f\x51\xff\x7f\xb7\xfc\x87\x07"
-  "\x2e\xfd\xfb\x32\xf5\xcb\x76\xff\x1f\x6c\xff\x3f\x52\xfe\xc3\x83"
-  "\x97\xfa\x31\xbf\x81\xb7\x8e\xfd\xe0\x3f\x29\x09\xfc\x59\x07\xfb"
-  "\xda\xe2\xfc\x98\xec\xe5\x21\xd1\xe5\x7c\x9c\x26\x54\x7c\x4a\xfc"
-  "\x9d\xa0\xee\xd2\x32\xd1\x55\x71\x81\xf5\x9e\x0f\x77\x80\x7f\x5b"
-  "\x76\x9e\xa0\xe4\x1d\x27\xc8\xd6\x51\xca\xdf\x0b\xe4\xf8\x34\x90"
-  "\x33\xc0\xd4\x8b\xe7\xb6\x75\x41\xfa\x93\xff\x33\xf6\x53\xf0\xfc"
-  "\x6f\xf6\xbe\x3f\x2e\xaa\x2a\xef\xff\xcc\x30\x20\x19\xca\xe0\x02"
-  "\xa2\x59\x8d\xad\xba\x63\xf9\x83\x76\x6d\xbf\xd4\xda\x2e\x25\xf6"
-  "\x58\xab\x49\xad\xb6\x54\xa6\x58\xda\xa2\x8b\x3a\x22\x22\x22\x02"
-  "\xa2\xf1\x50\x29\xa2\xa1\x0f\x2a\x22\x3e\x6b\xfb\x50\xf9\x83\x9e"
-  "\xc7\x9e\x07\x5d\xb3\x31\xb1\xd0\x80\xa1\xc2\x1a\x5d\xd0\x11\xc1"
-  "\x25\x42\x9d\x64\x94\x01\x66\xee\xfd\x7e\x3e\xe7\xdc\x3b\x77\xee"
-  "\x30\x03\x0c\x69\xd6\xf3\xec\x1f\xf3\xba\x73\xee\x3d\xf7\xdc\x73"
-  "\xcf\xe7\x73\xde\xe7\x7d\x3e\xf7\x9c\xcf\xa7\x0a\xd8\x64\x65\x2d"
-  "\xc6\x5a\xe4\xcb\x02\x62\x49\x70\x41\x28\x7f\x84\xcf\x7c\x35\x91"
-  "\x57\xbe\x3a\x0f\xce\xd5\x1c\xe0\x22\x7d\x0f\xa4\x94\xfb\x62\x4c"
-  "\xa5\x7a\x72\x74\x93\xa0\x9b\x76\xb6\x8f\xa1\x8c\xf2\x73\xe8\x27"
-  "\x35\xcc\x0f\xe2\x89\x95\x6c\x3c\x3f\xf1\xa4\x60\xbf\x80\xff\x65"
-  "\xd4\xd6\x06\xef\x51\x8a\x71\xd5\xb0\xcc\xfd\x5c\x29\x8d\xab\x76"
-  "\x20\x25\xd2\x37\x75\x2e\x51\x56\x99\x9a\xc9\x71\xc0\x41\x8c\xd1"
-  "\x05\xfd\x6e\x2f\xf4\xb3\x92\x9d\xa1\x7c\x2e\xd4\x6f\x7d\x61\x28"
-  "\x9f\x0d\x75\x2a\x6e\xcb\xfc\x08\x78\x50\xa9\x45\xb0\xaf\xea\xa1"
-  "\x5f\xec\xdd\x00\x79\xa6\x2f\x27\xf7\x6e\x80\x7c\x39\x90\x0f\xb9"
-  "\x18\xab\xdf\xc7\x27\xa0\x0d\x0e\xc2\x33\xab\x35\xb3\x31\xad\xa7"
-  "\x76\x28\x7c\x36\xbc\x87\xa6\x9e\xe8\xa3\x61\x6c\x53\xe1\x33\xc4"
-  "\xe7\x42\xf9\x80\x7f\x87\xf6\x52\x9b\x38\x9c\x67\xe5\x7c\xc4\x62"
-  "\xba\xe7\xaa\x71\x8d\xb0\x18\xf7\xae\x68\x43\x0a\x8c\xe9\x1d\xd4"
-  "\x57\x5b\x1e\xce\xdf\x91\x63\x50\x5e\x01\xf3\x78\x36\xdf\x04\x6e"
-  "\x11\x07\x38\x00\x7c\x82\xae\xbf\x04\x2e\x01\x75\xc9\xc3\xd8\x73"
-  "\x78\x1d\xe6\x01\x07\x61\x5c\x2e\x41\x1e\x30\xfb\xfa\x53\x04\xf7"
-  "\x6e\x01\x1f\x50\x2d\x9b\xc5\x5b\x99\x8f\xfc\x8f\x5a\x44\x2e\x80"
-  "\x18\x84\xe3\xff\x06\x98\xd3\x77\x82\x0c\x41\x07\xca\x81\x5b\x04"
-  "\xc1\x28\xa9\x15\xda\xbe\x9c\x8e\xf9\x49\xd4\xb7\xa8\x0f\xc3\x68"
-  "\xfd\x43\xf0\x7e\x01\xf0\x8c\x72\x13\xa9\xa4\x38\xc1\x30\x46\x1f"
-  "\x25\x8e\xe3\x38\x87\x32\x41\x19\x3c\x60\x99\x70\x0d\xde\xff\x7f"
-  "\xc2\xc4\x67\x9a\xc8\x47\x16\xa1\xcd\x2a\xa0\xcd\xb0\x4c\xba\x9f"
-  "\x16\x38\x97\x96\xb5\x8d\x1e\xf9\x41\xb0\x70\x6f\x81\x58\x2e\xce"
-  "\xf3\x38\xe0\x15\xd8\x5e\xd8\x4e\xf0\x0c\x22\xe0\x58\x0d\xe3\x2f"
-  "\x1f\xef\x13\xbe\xa3\xe5\x82\xac\xd7\x49\xed\xaf\x37\x39\xb7\x3f"
-  "\xdc\xbf\x4e\x90\xe5\xf3\x4e\xb2\x03\xfe\xfd\x71\x38\xda\xdd\xa0"
-  "\x8e\x47\x98\xcd\xe0\xd8\x10\xf4\xef\x83\x3e\x44\xa1\x8d\x8f\xac"
-  "\x47\x7f\x95\x80\xcd\x6b\xcf\x11\x21\xe6\xe1\xc7\x43\x18\x3f\x3d"
-  "\x56\xca\xe2\x82\x1d\xa3\xb6\xba\x06\xa8\x17\x8b\x09\x76\x4c\x88"
-  "\x09\x76\x6c\x8d\x73\x9c\x43\x29\xc6\xe1\xb1\x64\x69\x0d\xb4\x7e"
-  "\x0f\x9b\x8f\xe9\xf7\xa0\x4d\x85\xe6\xef\x8c\xc3\xba\xd5\x62\xbf"
-  "\x14\xdf\x15\xe3\x1d\xc2\x79\xb4\xf5\xd5\xa2\xdc\xc4\xf3\xe8\xeb"
-  "\x12\xe4\x14\x00\x75\x0a\x12\xea\xd4\x02\x69\x7f\x78\x36\xb5\x49"
-  "\x61\xec\xc3\x8d\x78\x4f\x9a\x74\x0f\xf6\x1b\xd0\xe1\x40\xb8\xe7"
-  "\x0e\x38\xf2\x62\x5e\x16\x13\xf1\x58\xee\x5b\x1d\x68\x53\x39\x56"
-  "\x2c\xc6\x44\xc4\x78\x88\x88\x19\x1b\x66\xcb\xda\x1e\xdb\x66\x2f"
-  "\xc8\x8a\xea\xdd\x71\x5b\x29\xb4\xf7\xc7\xc0\xff\xf7\x45\xb2\xf7"
-  "\x3a\x96\x2b\xd4\x4f\xcf\x7c\xa7\x1f\x2e\x2f\xdc\x2c\xee\xe5\xfe"
-  "\x38\xd9\xf1\x9d\xcf\xc1\x2d\x8f\xe5\xa2\x4e\x42\x59\x15\x28\x7f"
-  "\xe4\x89\x90\xaf\xc8\xa1\x5b\x74\xbf\xe2\xc7\xe8\x47\x49\x2b\xd4"
-  "\x1f\xf5\x45\x21\xb4\x5d\xb9\x73\xbf\x73\xee\xe7\x50\x46\x03\xf4"
-  "\x71\x87\x0e\x88\xfd\x5a\xc0\x9c\x21\x02\xa7\x08\x43\x5f\x93\x50"
-  "\xae\x1e\x39\x38\x1b\x57\x8f\xb7\x1c\xaf\xb5\xa1\x4d\xb6\x06\xd2"
-  "\xd0\xbf\x8f\x97\xb7\x0e\x1a\x52\xbc\x8e\xe2\xc6\x71\x98\xff\x8c"
-  "\xa6\xf6\x63\x6c\x17\xb1\xbf\x6e\x84\xf6\xc1\x78\x82\xb4\xcf\x26"
-  "\x37\x90\x2a\x6b\x0b\x11\xd6\x17\x43\x9f\x6d\xc4\x6f\x24\xcd\xa0"
-  "\x43\xfe\xd8\x7f\x41\xbe\x7b\xd1\x2f\x2a\xb4\x63\xf5\xba\xad\xb4"
-  "\xdf\x06\x60\xbf\xed\xc4\x3d\xe8\xf0\x9c\xb2\xd8\x48\x72\x3c\x59"
-  "\x4f\xfb\x31\xfa\x16\xd8\x01\x6d\x87\xf1\x07\xe1\xd9\x07\xc5\x75"
-  "\x91\xa8\x23\xe8\x4b\x80\xe9\xc9\x47\x36\xec\xcb\x42\xdb\xa9\x20"
-  "\x5f\xad\xd8\xf7\x24\xf9\xb3\x3c\x2e\xfd\x2d\x90\xf5\xb7\xb2\x00"
-  "\xb1\xad\x6d\xb4\x1f\x1f\x2b\xb6\x41\x3f\x76\x6e\x53\x6c\x4f\x6c"
-  "\x57\xc8\x0b\xef\x7f\x28\x5a\x6c\x53\xa7\xf6\x7c\x47\x90\x79\x35"
-  "\xb3\x59\x94\xc5\x0b\xf6\x0c\x47\x1b\x0a\xfa\x57\x83\x7d\x6a\x2d"
-  "\xbe\x3b\x8c\x0d\xf8\x7c\xd4\x91\x1d\x02\x66\x95\x99\x51\x47\xca"
-  "\xa0\xff\x4f\x35\x4a\xd8\x71\x6c\x2f\x9d\xb3\x80\x9c\x98\x7c\xca"
-  "\x4e\xd3\xfd\xfa\x6e\xb0\x03\xf4\x24\x4f\xc2\xa7\xb2\x06\xb1\x1d"
-  "\x44\x9d\x14\xfb\x3d\x8c\x29\x0f\xca\xf1\xe7\x44\x08\x94\x31\x08"
-  "\xf1\x4d\xe2\x50\x27\x46\xc8\xf1\xed\x44\x00\xe2\x1b\xea\xb5\x2e"
-  "\x09\x6d\x36\x6c\xbc\x32\x91\xa3\x07\xe5\x98\x74\xf4\x1d\xf6\x0d"
-  "\x90\x71\x2e\xd4\x2d\xdd\x6c\x96\x1f\xc7\x30\xc8\x4f\xd7\x25\x0b"
-  "\x63\x1e\xfa\xbf\xc2\x73\x45\x42\x7b\xd5\x42\xfe\x32\xdc\xab\x85"
-  "\x7b\xbd\xef\xac\x65\x73\x3d\xc0\xe9\x23\xe8\x67\x16\xf2\xc5\x56"
-  "\x01\xcf\xef\xcc\x62\xd8\x2d\x62\x05\xff\x4a\xcc\x9d\x2b\x9a\xc8"
-  "\x1d\xba\xdf\xf2\x17\x2f\x91\x4f\x1e\x83\x3e\x63\x45\xbf\x67\x50"
-  "\xb6\xe6\x12\x39\x79\x07\x3c\x37\x58\x38\x86\x5d\x22\xe5\xdf\xc1"
-  "\x71\x08\x1c\xcf\xc0\xf1\x2e\x38\x1e\x83\xfc\x9c\x90\x3f\x1c\xd2"
-  "\xef\xc0\xf9\x5f\x09\x47\xa8\xe3\x27\x11\x70\x8c\x16\xb8\x23\x9e"
-  "\x5f\x8d\x69\x38\x2e\x12\x64\x5e\xc1\x64\xfe\x09\xae\xb9\x4a\x86"
-  "\xfa\x1b\x0d\xb5\xb4\x2c\x1d\xe4\x19\x8b\x65\xe3\x1e\xca\x4b\xe4"
-  "\xd3\x0b\x4e\x1c\x14\xca\xf9\x74\x00\x1c\x27\xc0\x7d\x9f\xc3\x31"
-  "\x11\x8e\x6f\x0b\x6d\x50\x8d\xd8\x30\x2f\x19\xdb\xb6\x4c\xaf\x61"
-  "\x7c\x37\x5a\xec\xf3\x38\x0e\x4b\xd8\xa1\x27\xf3\x66\x31\x79\x43"
-  "\x5e\xaa\x07\x90\xf7\x31\xcc\x0b\xc7\x49\xc2\x31\x52\x38\x4e\x16"
-  "\x8e\xff\x22\x1c\xa3\x84\xe3\x14\x13\xf9\xa4\x58\xe0\x18\xd0\x2e"
-  "\x9f\x14\xd3\xf5\x0d\xb9\x6a\x61\x2d\xd9\xa7\xe5\x38\x47\x06\x1c"
-  "\xc7\x71\xd0\xa7\x2d\xf3\xd3\x89\xa2\xbd\x0d\xed\xb4\x9d\x99\x87"
-  "\x2f\xee\xa0\x7e\x1b\x3e\x9d\x21\x61\x5b\x88\x35\x40\x11\x49\x80"
-  "\x03\x85\x14\x28\x61\xfc\x67\xe5\xa0\x1e\xd3\x6f\x88\x82\x0f\x6b"
-  "\x1f\xf4\x15\x45\xe7\x43\x41\xaf\x17\x63\x5f\xa5\xb6\x48\xf4\x91"
-  "\x14\x14\x62\x03\x5d\xf3\x87\xb9\x41\x80\x88\xdf\x38\xef\x11\x7c"
-  "\x5d\x85\xc2\xb3\xf4\xd2\x5c\xfd\x53\x1d\xfb\x26\x13\x02\x7d\xff"
-  "\x53\xa3\xd3\xf9\x31\x58\x67\x68\x4f\x23\xbc\xcf\x84\x7a\x52\x8e"
-  "\xed\xf8\xcb\x06\xf6\xce\xe1\xe2\x3b\x0b\xf2\xd0\x89\xed\xdb\x40"
-  "\x3e\x29\x01\x2c\x4c\x40\x1d\xae\x77\xe0\xec\x27\x74\x0f\x92\xa0"
-  "\x23\x20\xcb\x4f\x16\xa0\x4c\xa5\xfe\x23\xc3\xa0\xe0\xb6\xcc\xf2"
-  "\x58\x39\xa6\xe8\x63\x11\x53\x50\x37\x00\xbf\x51\xd6\x91\x2e\xfd"
-  "\x2f\x00\xfb\x1f\xeb\x77\xe5\x05\xf2\x7b\x4f\x04\xd8\x58\xbf\x33"
-  "\x82\x9e\x81\x7e\x7e\x42\xd7\x67\x98\x48\x79\xaa\xd0\xa7\x8d\xd0"
-  "\xa7\x1f\x82\xf3\xfe\xac\xae\xec\xbc\xf0\x2c\xd0\xb3\x4f\xf0\xbd"
-  "\xef\x12\xcf\x0b\xef\x0b\xe5\x9c\xb0\xa2\xbc\xc5\xf3\x42\xf9\xa0"
-  "\x8f\x27\xcc\xd8\x4f\xc4\xf3\xc2\x3b\x01\x8f\x3a\x39\x41\xc4\x93"
-  "\xf5\x54\xdf\x8e\x1f\x11\xef\x43\xb9\xa1\x5f\x1b\x66\x33\x3e\xa9"
-  "\x81\xbe\x5a\x84\xe3\xc3\xda\xd9\x24\x60\x45\x3e\x19\xc0\xfa\xe5"
-  "\x49\x8d\x1c\x23\x3f\x3b\xc4\x67\x06\xda\x78\x75\x88\xa5\xd2\x36"
-  "\x41\xe4\xab\x05\xf0\x9c\x02\x31\xfe\xa6\xe4\x0f\xfb\xe4\xe7\x18"
-  "\xb7\xdc\xa9\x2e\x7a\xb1\x2e\xd2\xf8\xcc\x64\x80\x75\xc3\xb2\xd6"
-  "\x02\x5f\xb7\x00\x2e\x30\xdc\x3e\x69\x16\xe3\x12\xe7\x08\xe3\x16"
-  "\x8d\x8d\x9b\xc4\x62\xe3\xe2\xd8\x88\xdf\xf2\x39\xb4\x63\x25\xdb"
-  "\x49\x95\x0e\xe6\xf2\xc9\x8d\x64\xce\xca\xfe\xe8\x3b\x22\x06\xea"
-  "\xba\x13\xea\xb6\x47\x68\x23\xe8\x37\x9f\xad\x11\xda\x12\xf1\x6a"
-  "\x0f\x62\xf8\xda\x34\x16\xcb\x02\x6d\x37\xd8\x1f\xde\xc2\x71\x2b"
-  "\x8c\xb7\x96\x15\x60\xdf\x38\xa5\x13\x39\x28\xd4\xaf\x88\x71\xc0"
-  "\xe3\x75\xd4\x97\x49\x6e\x88\x85\xd9\xfe\x3e\x0b\x62\xef\x7a\xca"
-  "\xca\xbe\x93\x86\x08\x7e\xb7\x4e\x35\xf8\x84\x05\x27\xb0\xf5\x16"
-  "\x87\xb9\x42\xda\xd7\x4e\xe9\x5d\xfc\x45\x29\xe1\x5c\x8d\xe8\xef"
-  "\x52\xe2\x8b\xac\x4d\xe0\x9a\x59\xea\x17\xa7\xf6\x62\x59\x50\xe6"
-  "\xea\xb6\xcc\xcf\xfc\xa5\xf3\xc7\x6b\x19\x27\x08\xb1\x0e\x5c\x13"
-  "\x89\xeb\x48\x42\xd0\x47\x2c\xab\xc3\x67\x71\xb4\x4e\xd4\xee\x01"
-  "\xfd\x53\xe8\xc3\xd8\xd6\x38\x6e\xd3\x7e\x0c\x7d\x18\xfb\x72\xe7"
-  "\xa6\x10\x5b\xe7\x26\xa1\xef\xb2\xf1\xd9\x4a\xfb\x2e\xed\xb7\x9f"
-  "\x25\x4b\xcf\xfb\x2c\x9c\xda\xbe\x50\xa6\xab\xc2\x02\xe0\x5a\x9e"
-  "\x89\x1c\xf6\x17\xea\x38\x51\xa8\x0b\xfa\x47\x29\x60\x6b\x35\x4e"
-  "\x8d\x65\x5c\xe8\xd4\x18\xd4\x2f\x03\xe8\x0c\x1c\xf3\x59\xdc\xc0"
-  "\xcf\xaa\x45\x9d\x81\xfe\x34\xef\x12\xa9\x98\x9b\x17\xca\xe7\x83"
-  "\x6c\xf2\xa1\x0f\xc4\x43\x7a\x1a\x1c\xe7\xb1\xa3\x42\x8d\x47\x41"
-  "\xb7\xf3\xdb\x32\x2b\x02\xc4\xf8\xae\xf8\x3e\x96\xa0\xa5\xb9\xa8"
-  "\x1f\x39\x50\x77\xd4\x11\xfa\x3d\x51\xc7\xe2\x26\xa3\x7e\xa0\x6e"
-  "\x04\xae\x79\x8a\xea\x07\xdd\xab\x0c\xe7\x69\x9d\x40\x3f\xa0\xac"
-  "\x18\xd1\xd7\x24\xbc\x9f\x8d\xd9\xf5\x2b\xe2\x9d\xd7\xb6\x41\x99"
-  "\x9a\x32\x0d\xcc\x6b\x72\x89\x39\x71\x38\x09\x29\xd3\x50\x9f\x72"
-  "\xe7\x0d\xb6\xc9\x04\xef\xc1\xef\x32\x0c\xe7\x42\xfe\x08\xf7\x16"
-  "\x4b\xed\xa5\xa7\xdf\x2a\x8e\xcf\xa2\xb6\xc4\x9f\xc1\xb5\x32\xe7"
-  "\x79\x82\x89\xfc\xad\x1a\xe7\x0a\xb8\x06\xe7\xe7\xc1\x44\x03\x7a"
-  "\x08\x38\x54\xd1\x24\xf2\xd2\xf1\xc1\xf8\x7d\xf7\x6f\xb8\x17\x12"
-  "\xe7\xc0\xd0\x5e\x7f\x8b\x83\xb9\xa0\xdb\xf5\x89\xa0\x1f\x13\xd0"
-  "\x56\x23\xc4\x81\xa8\x45\x3b\x14\xfa\xcd\xbe\x44\xaa\x57\x56\xa2"
-  "\x1f\x81\x25\x5d\x7d\x8b\xa6\x25\xf3\xd7\xd1\xbf\xa8\x26\x81\xfc"
-  "\xac\x9e\x54\xcf\x42\xbb\x4f\xfa\x77\x68\x63\xa9\xd4\xc9\x6d\x2c"
-  "\x95\x7a\xe1\x57\x43\x48\x55\x84\xd3\xaf\x5c\x38\x46\xf5\xf0\x33"
-  "\x09\x79\x61\x06\x5e\x65\x15\xda\xea\xdf\xda\x32\x2b\x1d\xfe\x0f"
-  "\x51\xa7\xb0\xaf\xe2\x77\x7d\xb4\x19\x29\x6c\x04\xfd\x16\x80\xbc"
-  "\xa0\xde\x6b\xef\x7f\x56\x9f\x82\xfa\x54\xe5\x4b\xb9\xbf\xd2\xdb"
-  "\x7d\x55\x55\xf4\x3b\x18\xf3\xb1\x57\x59\x0e\xcf\xfe\x0f\x8c\x0d"
-  "\xaf\x4b\x20\x77\xa3\xfd\x3a\xd0\xce\xeb\x71\x8e\x8a\xba\xb1\x8b"
-  "\xc6\x5f\xa8\x3a\x99\xb8\x9a\x28\xe1\xfa\xbd\xf0\xbf\x54\xe4\x39"
-  "\x70\x8f\xda\xc7\x4a\x82\x91\xdf\x4c\x5a\x4d\xee\x6d\xcb\xac\xca"
-  "\x13\x65\x85\x1c\x00\xed\x68\x82\x2d\x00\xea\x5a\x49\xbf\x9d\xa1"
-  "\x6f\x64\x13\x6d\x37\x8a\xa3\x58\x06\xe8\x6e\x55\x86\x8f\x85\xa8"
-  "\xd9\xd8\x51\x05\xe3\xdf\xdf\x04\xce\x57\x55\x00\x7d\xa0\xc6\xa9"
-  "\x9e\x67\xa4\xff\xa1\x43\xf0\xfe\x40\x0b\xf2\x2b\x4f\xed\x63\x18"
-  "\x29\xb6\x0f\xae\x2b\x0b\x04\x9e\x4f\xe5\x6d\xe3\x5b\xa0\x6e\x15"
-  "\xba\x14\xe2\xdf\x4c\xaa\x47\xee\xda\x4a\xf7\xbb\x94\x33\xfb\x7a"
-  "\xf5\x10\x71\x1e\xcd\xea\x6d\x68\x0c\x5c\xe3\x43\x63\x6a\x63\x8c"
-  "\x4f\x1a\x47\xfb\x6a\x18\xe5\xde\x06\xdb\x44\xa2\x4f\x7b\x04\xf3"
-  "\x9c\x16\xb1\xb4\x35\x3d\x8c\x1c\x0f\x9b\x08\xfd\xd9\x50\x04\x7d"
-  "\x26\xdb\xfb\xb5\x4f\x06\xc1\x6e\xcf\xf6\x48\x61\x1a\xf7\x33\x51"
-  "\xff\xf2\xf4\x3b\xa9\x61\x29\x8e\x0d\xeb\x84\xf8\xcc\x38\xe6\xb6"
-  "\x65\x56\x3b\xf8\x3f\x8b\x4b\x6d\xa0\x7c\x02\xeb\x0c\xff\xe3\x71"
-  "\x1f\x39\x9d\x07\xb0\xfc\x01\xcc\x86\x5f\xed\xb0\xff\x63\x3e\xbc"
-  "\x8f\xad\x4f\x32\x44\xcd\xb1\x2b\xa0\x8d\x0d\x51\xf8\xae\x4c\x37"
-  "\x43\x41\xb6\xd5\x3a\xa9\x1f\x57\xd1\x75\x42\xc7\x5b\x9c\xfb\x69"
-  "\x75\xae\x34\x7f\xac\x9c\x30\x36\x8f\x68\xdc\xf5\x4b\xdd\x40\xa2"
-  "\xfe\xd6\x9f\xfc\x61\xe3\x46\xbe\x28\x57\xc9\x3d\xbe\x36\x87\x04"
-  "\x28\xd6\x43\x33\x62\xbf\x4b\x8a\x0d\xb9\x44\x3e\x0f\x0a\x0c\x18"
-  "\x1c\x3d\x29\xb1\x1f\x9f\x16\x46\x94\x1b\xae\xf5\xf3\x1f\x6e\x1d"
-  "\x5c\xc4\xfb\xdc\xff\xec\xb4\x44\x2b\xd1\x2c\xcc\x25\xff\x88\x27"
-  "\x3e\x93\x80\xb9\xff\x3c\x80\x40\x9d\xbe\x1c\x86\xfb\xce\x8e\x07"
-  "\x20\x9f\xf8\x72\x18\x96\x99\x5a\x40\xfc\x53\x1b\xf8\xa6\xf5\xaf"
-  "\xfa\xfa\x03\xb6\xab\x77\x80\xce\xdd\x19\x30\xb8\xa8\x13\xca\x38"
-  "\x16\x4b\xef\x2b\xf1\xbe\x6e\xba\x50\xa8\xdb\x3e\xef\xea\x56\x73"
-  "\x44\xaa\x5b\xcd\x91\x9b\x5c\x37\xb5\x54\xb7\x38\xa8\xdb\x17\x4f"
-  "\x7a\x57\xb7\xaf\x66\x49\x75\xfb\x6a\x56\x2f\xeb\xb6\xd7\xfb\xba"
-  "\x25\x0f\x86\xba\x35\x7a\x57\xb7\xaf\x6d\x52\xdd\xbe\xb6\x7d\x9f"
-  "\xba\xe1\xdc\x3c\x6d\x18\xdf\x48\x7d\x1d\x27\x90\x00\x5c\xdb\x75"
-  "\x89\xd4\x4c\x4e\x2b\xa0\xe9\x41\xf0\x5f\x21\xf4\x77\x73\xba\x85"
-  "\xbf\xc8\x78\xcc\x97\x8b\xc6\xe9\x70\x4d\xf3\x97\xf3\x40\x97\x03"
-  "\x98\x4e\xd7\x50\xae\x9d\x6e\xe6\x85\xb5\x86\x5f\x6e\x28\xa4\xeb"
-  "\x15\x86\x46\x0b\xe9\xea\xd6\x41\xa1\xe1\xb8\x56\x80\x83\xfe\xcd"
-  "\x0f\x0a\x9d\x88\x71\xdd\x0e\x24\x98\x95\x7c\x26\xfa\x21\x42\x5f"
-  "\x49\x2a\xc2\x6f\x0e\x9d\x7a\x20\xc1\xaa\x44\xbf\x01\x6b\xe9\x3e"
-  "\xbc\x2f\xcb\xc5\x3d\x26\xe2\x33\xcc\x41\x43\xa3\xe1\xbc\xc9\x24"
-  "\xc4\x5a\xe4\x95\xc8\x4d\x42\x27\x60\xf9\x70\xde\x2a\xc6\x43\x04"
-  "\x7d\x17\x63\xb2\x58\x02\xad\xdd\xe1\x60\xcd\x58\x11\x07\x27\x25"
-  "\x92\x40\x8c\x87\xb6\x31\xad\x1f\x7e\x43\x04\x4e\xf5\xe5\x11\x6c"
-  "\xf7\xe9\x96\x7e\x7c\x60\x2a\xf1\xc1\xbd\x35\xb8\x86\xcb\x10\x66"
-  "\x26\x23\x52\x89\xef\xf4\x64\x28\xd3\x4a\x62\x03\x93\xa1\x3c\x68"
-  "\x6b\xc6\xf5\x6b\xe8\x3e\xb8\x3c\x28\x0f\xd7\xb6\xfa\x24\x92\x80"
-  "\x49\x61\xe9\xfc\xda\x6d\x44\x85\xfb\x70\x70\x3f\x0d\xdb\x4b\xe3"
-  "\xe7\xdf\x96\x59\x53\x2c\xbe\x5f\x2f\xe4\x33\x90\xc9\xe7\x74\xa3"
-  "\x24\x9f\xd3\xbb\xbb\xca\xe7\xf4\x00\x26\x9f\xd3\x2a\x49\x3e\x5f"
-  "\x4d\x91\xcb\xe7\xf4\x58\xb9\x7c\x4e\xeb\xfa\x26\x9f\xd3\x71\x92"
-  "\x7c\xd8\x33\x98\x7c\x4e\x67\xb8\x97\xcf\xe9\x7c\x49\x3e\xa7\xc7"
-  "\xf4\x4e\x3e\xa7\x2b\x3d\xcb\xe7\xf4\xac\x6e\xe4\xe3\xe7\x5e\x3e"
-  "\x5f\xdd\xdd\x7b\xf9\x7c\x35\xc5\x0b\xf9\x0c\x60\xf2\xf9\xfa\x35"
-  "\x49\x3e\x5f\x3f\xd6\x55\x3e\x5f\xed\x63\xf2\xf9\x6a\x8f\x24\x9f"
-  "\xaf\x9b\xe4\xf2\xf9\xaa\x52\x2e\x9f\xaf\xd5\x7d\x93\xcf\xd7\xfe"
-  "\x92\x7c\xd8\x33\x98\x7c\xbe\xd6\xb8\x97\xcf\xd7\x11\x92\x7c\xbe"
-  "\xaa\xe8\x9d\x7c\xbe\x5e\xe4\x59\x3e\x5f\xd9\xbc\x97\xcf\xd7\x1f"
-  "\xba\xc8\x47\xed\x59\x3e\x5f\x37\x79\x21\x9f\x40\x26\x9f\x33\x23"
-  "\x25\xf9\x18\x2f\x74\x95\x8f\x71\x1a\x93\x8f\x31\x4a\x92\xcf\x99"
-  "\x6c\xb9\x7c\x8c\x8b\xe4\xf2\x31\x96\xf4\x4d\x3e\xc6\x62\x49\x3e"
-  "\xec\x19\x4c\x3e\x46\xbd\x7b\xf9\x18\x8d\x92\x7c\x8c\xf1\xbd\x93"
-  "\xcf\x99\x01\x9e\xe5\x63\x2c\xe8\x46\x3e\xfd\xdc\xcb\xe7\xcc\x4b"
-  "\xbd\x97\xcf\x99\xec\xee\xe4\xe3\x1d\xf7\x3b\x43\x79\xd5\x4d\x28"
-  "\xa7\xc1\x53\x39\xd8\x76\xb8\x3e\x8d\xcb\x3c\xd3\x50\xc8\xf9\xd1"
-  "\x58\x52\xf0\xbf\x40\x93\x42\x7e\x57\x4f\xce\x3e\x58\xc8\xf9\xfa"
-  "\xf3\x99\x85\xb1\x5c\x66\x91\x86\x5f\xe3\xa7\xe2\xd6\xf4\x53\xe1"
-  "\xde\x48\x77\x65\xb1\xf5\x92\x67\x37\xf9\x0c\x21\xf7\xe0\x7e\x97"
-  "\xb5\xc0\x9f\xf1\x7f\x5b\xe6\xd9\x02\xe0\x82\xda\xee\xf6\x5d\xe0"
-  "\xda\xa5\xe3\xeb\x70\xde\x7b\xb6\xdc\xb1\x5f\x3d\x93\x4f\x46\x1f"
-  "\x45\xba\xfb\x70\x8d\xfd\x59\x73\x1e\xf5\x79\xa3\x36\x46\xde\xc7"
-  "\x9f\xc7\xb9\xc8\x25\xf2\xf7\xcb\xfc\x26\xb5\x11\xf5\x01\xb8\xfb"
-  "\xcf\x9a\xc9\xdf\x23\x1c\x6b\xba\xf8\x98\xed\x82\xcd\x6f\x1d\xcb"
-  "\x5b\xf7\x12\xe4\x5d\x87\xf1\xef\x96\xa5\x61\x5c\xb7\xba\xc9\xc0"
-  "\x7d\x47\xe1\x33\xd0\xff\xca\x2e\x38\xe2\xba\x17\xb6\x76\xef\xef"
-  "\xd4\x6f\x16\xfa\x78\x63\x6b\xfa\xeb\xc6\x8a\x7a\x07\xcf\xe9\x0f"
-  "\xe9\x10\x81\xdf\x63\xfe\x3b\x9b\x49\xad\xdd\xe9\x7a\x00\xa4\x2f"
-  "\x40\xd9\x41\xc2\xf5\x01\x90\x3e\x81\x3c\x9b\xee\xbf\xcf\xc9\x10"
-  "\xd6\x98\xd6\x16\xc3\x39\xb5\x90\x27\x08\xf2\x6c\x40\xee\x2e\x94"
-  "\x31\x08\xd2\x4b\x71\x4e\x2c\x5c\x0f\x86\xf4\x4c\xfc\x16\x20\x5c"
-  "\x0f\x81\xf4\xc3\x90\xfe\x05\xdb\xef\xd0\x29\xf4\xd1\x5a\x55\xdf"
-  "\xf6\x6c\xd6\xd2\xf9\x1f\x8b\xd3\x8e\x73\x81\xda\xa9\xd2\x7a\x9e"
-  "\xbf\xb7\xb8\x5c\x8b\x73\xba\x56\x2b\x5e\x63\x6b\xce\x6a\xd7\x39"
-  "\x5d\xab\x70\xb9\x56\xe4\x74\xed\x88\x4b\x99\x47\x9c\xae\xed\x75"
-  "\xb9\xcf\xe8\x74\x2d\xdf\xe5\x9a\xc5\xe9\x5a\xb6\x70\xcd\xa7\x2d"
-  "\xb3\x2e\x40\xfa\x26\xf7\xf7\x64\xe1\xbc\x12\xce\x3b\xc5\x3f\xf8"
-  "\x7b\x9c\x70\x1e\x9e\x5f\x37\xd1\x44\x72\x0f\x0a\xe7\xa9\xec\x59"
-  "\xf9\x75\x33\x9c\xca\x8f\x60\xb6\x8f\xba\x38\xc7\x5a\xb8\x41\xa1"
-  "\xd9\x5c\x67\xcc\x76\xb8\xa6\x41\xbd\x72\xd6\xed\xc5\x49\x9a\x97"
-  "\x97\xff\x49\x93\x30\x3f\x11\x97\xa3\x2c\x5a\x90\xa8\x59\xb4\x64"
-  "\xde\x7c\x99\xdf\xe5\x60\xf4\x5b\x86\x71\x7d\xd0\xa7\x82\xe0\x23"
-  "\xbc\xc9\xe1\x1b\x1f\x70\x15\x9e\x05\xf3\xff\xdf\x51\x1f\xec\x79"
-  "\xcc\x3f\x71\x39\xfa\x64\x60\xfe\x17\xc8\x53\xf5\xa4\xee\x8c\xe0"
-  "\x7f\x41\xdf\x96\x79\x8e\x78\xf6\xbf\x70\xbe\x96\xfa\x48\x83\x7c"
-  "\xcc\xff\xc2\x79\x13\xf4\xf3\x49\x7c\x7f\xe6\x27\x9f\xc5\xd7\x39"
-  "\x27\x72\x13\xf3\x9c\x76\xea\x67\x2c\x83\xd9\x36\x5c\x7d\x3f\xaa"
-  "\x4b\xf1\x3e\xe1\xfb\x67\xa9\xd3\xfd\xf1\xec\xba\x38\x3e\x08\xcf"
-  "\xcc\x55\x63\x8c\xb8\xfe\xf5\x90\xa6\xf6\x78\x7a\xed\x1c\xf3\xe3"
-  "\xb2\x49\xad\xc7\x77\xc2\xf7\x96\xbf\x9b\xf2\x8f\xf5\xe4\xdc\x07"
-  "\x4e\xef\x56\xeb\xe4\x4f\x4a\x7c\x07\xe6\xb3\xab\xeb\xbb\xd2\xfd"
-  "\x3a\xbc\x5a\xad\xc7\x67\x23\x9e\xb1\xb5\xee\x90\xde\xa4\x3e\x22"
-  "\xd6\xc7\xa9\x7e\xf8\x3d\x42\x05\xf5\xbb\x40\xdb\x04\x64\xca\x83"
-  "\x4c\x85\x77\xd8\xcd\x67\xd6\xad\xa3\x6b\xb7\x71\xef\x1e\xc6\x2e"
-  "\xa0\x63\xd5\xf9\x78\xd1\x56\x89\x63\x14\xf3\x85\x7d\x5e\xe2\x7f"
-  "\xe8\xe7\x67\x93\x38\x7e\x9d\x77\xe2\x7f\xec\x99\x70\x6e\xaf\xb3"
-  "\x0e\x39\x3d\xef\x0c\x3e\x0f\xf2\xcd\x60\xeb\xc5\xd5\x47\xb0\xbf"
-  "\x43\x9a\xfa\x11\xc5\x7b\xb1\x8e\x9e\x62\x41\x79\xf2\xc3\x26\xb5"
-  "\xa3\x69\x84\xd8\x8e\x79\x34\x56\x89\x69\x82\x68\xc7\xa3\xfb\x55"
-  "\x20\x0f\xf6\x2d\xc4\x27\x5e\xbd\x2c\xb2\x4c\x73\x1d\xea\x64\x8a"
-  "\x63\xb8\xfb\x46\xd8\xf8\x00\x12\xcb\xda\xd8\xb4\x14\xb1\x1e\xfb"
-  "\x0e\xc3\x7c\x53\xb5\x20\x7b\xe1\x1b\x8e\x69\x1b\x9e\x97\xd6\x69"
-  "\x9b\xcc\x62\x3e\x11\x9f\xd9\x77\x28\xd3\x49\x9a\x8f\xc5\xaa\x0c"
-  "\x67\xb2\xff\x85\xba\x9e\x98\x6a\x85\xfc\x74\xed\x28\xf3\xaf\x61"
-  "\xb2\xf2\x9b\x86\x42\x7b\x9a\x9a\x4c\xa4\x4e\x58\x67\xcc\x9e\x0b"
-  "\xc7\x5a\xac\x0b\xb6\x15\xee\xfd\xe4\x37\xbd\x11\x06\x72\xf2\x18"
-  "\x1f\x9d\xad\x6f\xaf\xa7\x3e\x88\x30\x16\x04\xda\x60\x19\x26\xd7"
-  "\x2f\xe7\x6f\xf0\xa5\xe8\xe3\x13\xf2\x04\x88\x79\x18\x86\xd3\x6b"
-  "\x74\x3d\xb2\x2e\x09\xed\x44\xc2\xb5\x24\xdc\x1f\xe7\xf8\xef\xe7"
-  "\xf4\xdf\x17\xff\xf3\x49\x7c\xc9\xc6\x14\x3a\xc6\xaa\xa4\xbd\xb7"
-  "\xf5\x89\x90\x0e\x70\x49\x07\xcb\xd2\x2b\xc9\x30\xba\xae\xd6\xc2"
-  "\x37\xd0\xf5\xc7\xc2\x79\xa1\xec\x3b\x68\x7d\x92\xf8\x08\xd0\x91"
-  "\x0a\xdc\x4b\x29\xf4\xc7\x0a\xdc\x83\x19\x68\x7b\x89\xee\xbf\xc4"
-  "\x58\xef\xc2\x31\x5c\x38\x8e\x61\x71\x02\xeb\xc7\x48\xb1\x7e\xd1"
-  "\x56\x53\x3f\xd1\x53\xec\x61\x31\x36\xb3\x18\x7b\x18\xf7\x6f\x0a"
-  "\x31\x8a\x66\xc1\x7d\x89\xdd\xc5\x79\x86\xeb\x79\xe2\x5e\x4c\x7b"
-  "\xae\x5a\xc7\xe5\x26\x20\x57\xbb\x17\x7d\x0e\xa5\xb7\xa0\xcf\x06"
-  "\x0b\x31\x90\x0e\x62\x48\x6c\xcb\xc0\x38\x75\x55\x2c\x3e\xdd\x40"
-  "\x94\x07\xee\x05\x42\x0e\x59\xa5\xbb\x4c\x63\xd4\xad\x68\x21\xc3"
-  "\x74\xbf\xe5\x1b\xa0\x0d\xac\xf6\x4d\x6a\x9d\xa0\x47\xdb\x60\x2c"
-  "\xbc\xa7\x99\x5c\xa4\xd8\x4c\xe3\xaa\xb6\xd0\xef\x59\xfe\x97\xc8"
-  "\xc5\x6c\x9a\x87\x8f\xd9\xc6\xda\xee\x22\x1d\x1f\x76\x65\x8a\x71"
-  "\xc8\x2e\x86\x8b\xb1\x4e\x4d\xe4\xe2\xfa\xeb\x41\xd3\xb4\x70\x2e"
-  "\x4a\xbe\x16\xfa\x22\xc6\x64\x0d\xc4\xba\x43\x1e\x82\x65\x43\x1e"
-  "\x09\xff\xe1\xfc\x0a\x1b\x19\x0a\xf5\xba\x24\x96\x0f\xd7\xb3\x4d"
-  "\xe4\x02\x1d\x63\xb0\xcc\xeb\x9b\x96\x01\x5e\x5c\x2c\x30\xf9\x5c"
-  "\xd4\xb1\xb5\xd4\x17\x8b\x4d\xa4\xe0\x60\x77\x5c\x08\xfa\x42\x2c"
-  "\xf4\xa5\x38\x2e\x77\x68\x0c\xf3\x0f\x3c\x34\x96\xd9\x1e\x2f\x5e"
-  "\xc7\xf5\x5a\x1b\x6f\x10\x15\xda\x02\x99\xce\x36\xd0\x7d\x85\x78"
-  "\x0e\x30\xbb\x18\xfa\x08\x1b\xd7\xbc\x1a\xff\x1b\xd8\x3e\x88\x6b"
-  "\xc4\x3f\x27\x41\xf4\x6f\xdc\x10\xed\xe4\x6b\x5d\xd8\x1f\xd1\xb0"
-  "\xb2\x2a\x99\x7e\xc7\xa6\x75\x74\xad\x03\xd6\x17\xda\xc9\xe2\x91"
-  "\x6b\xaa\x87\xc6\xd0\x6f\x2e\x9b\x43\x67\xb1\xb5\xa7\x0d\xc7\x7c"
-  "\xc2\x86\xac\x82\x67\x1d\x11\x6d\x89\x98\x27\x07\x63\x80\x42\xf9"
-  "\x8e\xf7\x4c\xa0\xcf\x68\x60\x7d\xbd\xc1\xca\x6d\x1a\x8a\xbe\xe4"
-  "\x55\xc2\x79\x6b\x95\xcd\x8a\x7b\xb7\x3d\xad\xf5\xf6\xa7\x3e\x54"
-  "\x36\x0f\x8d\xc1\xfd\x25\xe3\xad\x62\x9d\x1b\xad\xb8\xaf\x01\xeb"
-  "\xcc\xda\xb6\xf1\xb2\xd8\x8e\x1b\xae\x41\xd9\x69\x67\x49\x03\x69"
-  "\x5c\x8e\xeb\xe1\x70\x9f\x0e\xf6\x61\xd6\x06\x8d\xcb\x69\xbe\x0e"
-  "\x47\x1e\xea\xef\x82\xc6\x0c\x81\xf2\x0b\x69\x7c\x21\x78\x07\x90"
-  "\x85\x3e\x0d\xf7\xec\x36\xd2\xb9\xdd\xda\x04\xc2\xde\x9b\xae\x7f"
-  "\xbd\x34\x8c\xe9\x4a\xe3\x41\x71\xcc\x30\x09\xe7\x36\xe2\xb3\x93"
-  "\x3a\xc8\x15\xd2\xb8\x05\x63\xfc\x42\x7b\xc4\xa1\xff\xa8\x2a\x0b"
-  "\xf4\x93\xe4\x0e\xd4\x85\x38\x8c\x23\x07\x63\x4a\x1e\x1b\xe7\xb0"
-  "\xcd\x1b\x93\xf1\xf9\xd8\xb6\x20\x3b\x33\xb4\xe9\xeb\x6d\x99\x97"
-  "\xd4\x62\x9b\xe6\x84\xe2\xbc\xa7\x71\x4c\x77\x63\x84\x1d\xea\x5c"
-  "\x05\xec\x4a\x3f\xf4\x2c\xd6\xef\x0c\x37\x68\x68\x0c\xae\xb5\x86"
-  "\xff\xab\x05\x6c\xa7\xb2\x63\x7d\xe9\xd2\xfb\xf0\x8c\x83\xb8\x6e"
-  "\x01\xb1\x12\x7d\x1c\xc1\xb9\x18\xa1\xfd\xa8\x9f\xfb\xdc\x24\xd6"
-  "\x0e\x2c\xff\x3f\x02\x98\xdd\x78\xc8\x61\xa8\x97\xd3\xf7\x9f\x7f"
-  "\x50\x7f\x2b\x85\x42\x5c\x6e\xb8\x56\xe6\x54\x67\x0b\xdd\x27\x79"
-  "\x0d\x6d\x7e\x97\xe2\xf1\x59\x1b\xd0\xbf\x0f\xea\x45\xb3\xb3\xfe"
-  "\x5f\x9a\x86\xf5\xc4\xb5\xbc\xf6\xa0\xd0\x59\x30\xee\xc6\x62\x3b"
-  "\xc3\x3d\xeb\xa0\x2f\xb8\x9d\xa7\x08\x63\x22\x8d\x25\xd5\x96\xf9"
-  "\x8f\x08\x71\x4c\x84\x79\x06\x8c\x0b\x4d\x0f\xd2\xf9\x27\xf0\x6a"
-  "\x03\x87\xbc\xa6\x29\x1c\xf5\x06\xfa\xfa\x41\x01\x63\x0f\xc2\x3d"
-  "\xf1\xe2\x37\x31\x3b\xee\x87\xb8\x42\xbf\xe3\x5a\xc4\x78\x4b\xcc"
-  "\x9f\xd6\x3f\x72\xa5\xfd\x13\xff\x28\xe8\xb2\x7f\x02\xf7\x8d\x6c"
-  "\xa5\x31\x7e\xf6\xe2\x98\x52\xd9\xd2\x80\x63\x04\xbd\x1f\xf7\x54"
-  "\xa4\xc1\xdc\x9c\xed\x3d\x69\x40\x3b\x3d\x8d\x8f\x80\x75\x61\x3e"
-  "\xf1\xeb\xe9\x7f\xd0\x5b\x15\x1e\x99\x2e\x35\x11\x47\xcc\x5e\x90"
-  "\x37\x7e\x83\x3b\xae\x7a\x82\xe8\xef\xc3\xf1\xba\xe9\x41\x8c\x3f"
-  "\x0b\x79\x46\x88\xb1\x67\x69\xac\x59\xf6\x3e\xc5\x1e\x7d\xbc\x8d"
-  "\x23\xe1\xe8\x13\x03\xf7\x61\xd1\x36\x50\xbf\x5e\x8a\x7e\x63\xd1"
-  "\x07\x9e\x3e\x05\xe3\x37\x34\x5d\x78\x2b\x94\xee\x65\xb5\xe8\xc7"
-  "\x5d\xc3\xf5\x55\x2d\x97\x52\xa9\x5f\x14\xff\xe9\xc9\x36\x1e\xef"
-  "\xa3\xbc\x22\xe8\xf5\x52\xbc\x46\xfd\xa7\x63\x99\x7d\xf6\x81\xda"
-  "\xb4\x57\xe0\xa8\x2d\x80\xfb\x83\x41\x56\xf4\xbb\x06\xfc\x0f\x6d"
-  "\x26\xcd\x77\xb0\x78\x88\xcc\x9f\xb7\xb0\xce\xda\x8f\xed\x91\x87"
-  "\x36\xa3\xbe\x42\xbf\x59\xad\xb9\x1f\x63\x87\x7e\xb3\x86\xfa\xd4"
-  "\xcd\x55\x97\x09\x6d\x50\xb6\x91\xd5\x2b\x70\x4e\xb2\x92\xd6\x11"
-  "\xeb\xe7\x5d\xdd\xbe\x99\x22\xcc\x27\xfc\xda\x32\xbf\x59\x2f\xee"
-  "\xad\x67\xbc\x8a\xf9\xda\x65\xb2\xf8\x46\xd8\x63\xa6\x2e\x17\x9e"
-  "\x5d\x7e\x13\x9e\x5d\x26\x94\x59\xc0\xfc\x0d\x37\xe9\xa0\xdc\x82"
-  "\xb6\xcc\xe6\x60\x71\x5e\x23\xec\x0d\x1a\xc3\xe6\x5b\xcd\x63\xa4"
-  "\x79\x4d\x53\x97\x7d\xbe\x8f\x2f\x59\x92\xa8\x99\xb7\x60\x99\x6e"
-  "\x6e\xe2\x2b\x71\x9a\xf9\x09\x09\x4b\x12\x34\xe8\x2c\xc5\xb9\xff"
-  "\xb0\xf8\x26\xcd\x91\x42\x3c\xaf\x62\x29\x9e\x57\x73\xb6\x73\xdc"
-  "\x39\x13\x69\x5e\x7f\x73\x6c\x18\xcd\xc5\x9e\xca\xc9\x55\x72\x25"
-  "\xf0\x2b\x85\x9f\x1e\x7e\xe5\x68\xd3\x98\x63\x25\x91\x30\xd6\x53"
-  "\x7e\x28\xfa\x62\xe7\x32\x9b\x63\x71\xed\x50\x3d\xf9\xd6\xb7\x90"
-  "\x53\x11\xea\x03\x24\x93\x2b\xc1\xfc\xbb\xe0\x7e\xf8\xe9\xe1\x57"
-  "\x0e\x3f\x7a\x1f\xf7\x31\xdd\x57\x5d\xe2\x7c\x8d\xad\x0b\x49\x0e"
-  "\xc7\x3c\xfc\x1a\x15\xfd\xfe\xcb\x6d\x66\xf9\x5c\xea\xa0\xe4\x33"
-  "\x2f\x1e\x11\xf2\xd1\xf1\x75\xe0\x1a\xa2\x71\x93\xcf\x87\xcf\x3c"
-  "\x5b\x22\xe4\xa3\xeb\x5d\xc4\xf7\x41\xbf\xe5\x90\x5f\xcc\xa7\xe2"
-  "\x33\x9b\xa2\x84\x7c\x14\x37\xb9\x4c\xa5\xbb\xe7\xfa\xf2\x99\xef"
-  "\x69\x85\x7c\x6a\xe7\xf2\x9c\xf2\xf8\x71\x99\xd5\x7b\x31\x0f\xb7"
-  "\x46\xc5\xfc\x26\x64\x36\x17\x43\x7e\xb7\x7b\x9b\xbd\x93\x53\x4b"
-  "\x17\xff\x4f\xba\x57\x16\xcc\x7f\x64\xc1\xe2\x24\x8c\x40\x93\xb8"
-  "\x64\x79\x22\x1e\x17\xcf\xfd\x33\x3d\x2c\x99\xf3\xea\x2b\xec\x4f"
-  "\x62\x7c\x38\xfe\x89\x07\x7d\xc3\xe3\xbc\xe5\x3a\x3c\xbc\xb2\x04"
-  "\x93\xc9\x71\x63\x96\xbf\x22\x86\xa2\x76\xd6\x43\xe0\x6c\x2d\x56"
-  "\xd0\x8d\x26\x86\xb3\x97\x55\x26\x72\x96\xe2\x32\xc6\xa4\x38\xa1"
-  "\xb5\x11\xd1\xbe\xc5\xe4\xdf\x12\xcd\x7c\x33\x5e\x0e\x2a\xe4\xfa"
-  "\xf9\x07\xae\xd1\xbd\x12\x68\x5b\x30\x1f\xc6\x8c\xf5\x70\x6f\xa4"
-  "\x89\xbc\x32\x45\xc0\xc6\x1a\xea\x87\x30\xb3\x25\x57\x58\xb3\xa9"
-  "\xe2\x72\xd5\xd9\xe8\x0b\x1c\xd2\x34\xe6\x2b\xa4\x0f\x42\xba\x1a"
-  "\xd2\x18\xeb\x35\x18\xd2\xb8\xc6\xc2\x08\x69\x8c\xa1\x3a\x8c\xcb"
-  "\xf5\x29\xc2\xbd\xa8\x90\xd6\x40\x7a\x04\x94\x5f\x24\xf6\x0b\xf7"
-  "\x5c\xf9\xb2\x5e\x8c\x43\xcb\x62\xce\x5e\xae\x76\xc4\x9c\xc5\x38"
-  "\x33\x69\x6a\x1a\x97\x86\x71\x90\xcb\x16\x9f\xb0\xbb\xfa\x43\x1e"
-  "\x8b\x23\x0e\x0f\xb5\x7b\x5c\x51\x89\xeb\x65\x98\x5d\xe3\x4a\xb0"
-  "\x53\xec\x5e\x4c\x8f\x10\x63\xf7\xa2\xdd\x8b\xc6\x46\x83\x23\x9f"
-  "\x89\xfe\x1e\x79\xb7\xe3\x00\x8b\xa9\x77\xe5\x75\xf4\xf3\x69\x4e"
-  "\x9f\xa7\xf8\x79\x21\xda\xd2\x20\xcd\x7c\xbc\xf1\x57\xc8\x15\xba"
-  "\xfe\x5a\xf4\xff\xe4\xec\x73\xc0\xed\x3e\xa7\x2f\x80\x33\xd0\x98"
-  "\x21\xf1\x4b\x02\x6d\x73\xe7\x33\x1e\x78\xe5\x1b\x86\x5f\xa1\x19"
-  "\x8c\x2f\x5c\xa9\xe1\x9f\x65\x71\x16\x4c\xe4\x6a\x0c\xce\x59\x02"
-  "\x15\xf1\x4b\x78\xb8\x37\x30\x79\xee\x7c\x7a\x0e\xf2\xad\x05\xae"
-  "\x26\xd4\xef\x90\x61\x18\xee\x8f\xe4\x04\x5f\x0a\x57\x4a\x67\xdf"
-  "\x9d\x81\xcf\xf1\xa7\x3c\xe4\x0b\x12\x80\xb1\xed\xb0\x6e\x85\x4e"
-  "\xfe\xa9\x36\xc2\x39\x5c\x1b\xda\xfa\x2c\x09\x40\x3f\x9d\x42\x5d"
-  "\x4a\x59\xac\xa1\xab\xd1\xa2\xaf\x18\x13\x9c\x73\x7d\x9f\x67\xff"
-  "\x40\xb5\x72\xe4\x2b\x63\xa2\x27\xc3\xbf\x31\x42\x58\x55\x67\xdd"
-  "\x1c\xd6\x3a\x28\x2c\xb6\x75\xbf\xba\x8d\xc5\x00\xbc\x5a\x04\xe5"
-  "\xb0\x58\xc0\x38\x2f\x69\x8b\xc9\x67\x6b\x4b\xaf\x9e\x41\xbf\x98"
-  "\x5c\x26\xf2\x49\xdc\x5f\x7b\x95\xe2\x17\xaf\x0e\x5d\xb7\x6b\x35"
-  "\xfa\x8b\x55\x40\x1b\x5f\xfd\x10\xaf\x09\x3e\x77\x94\xd4\x47\x8d"
-  "\x9d\x84\xd1\xfd\xa5\xc0\x51\xd0\xbf\xcc\x25\x72\xed\x03\xe4\x1d"
-  "\x68\x57\xe2\x32\xaf\xce\x43\xbd\x05\x19\xa3\xaf\x09\x0b\x3f\x48"
-  "\x9d\xc8\x07\x0d\x1e\x81\x7a\x8c\x5c\xd7\xa0\xc6\x36\x33\xe3\x98"
-  "\x33\x09\x7e\x7f\x64\xf1\x2c\x5e\x6c\x12\xcb\x44\xbf\x48\xc0\xa1"
-  "\xd6\xc3\x51\xdd\x96\x69\x8e\x71\x8a\xd5\x25\xec\xa7\x35\xaf\x44"
-  "\x7f\x4d\x58\x36\xe3\xce\xd7\x76\x33\x0e\x62\x5e\x67\x22\x81\x13"
-  "\x59\x5f\x34\x03\xff\xc9\x18\x23\xfc\x07\xfe\x33\xa6\xc8\xa5\x8c"
-  "\x46\xd1\x66\xca\x74\xda\x8c\xb6\x87\x49\xf0\xfb\x23\xe4\xaf\x10"
-  "\xe3\x35\xaf\x55\xd2\xfd\x8f\x97\x7c\xc2\x70\x5f\xb4\xb9\x41\x3c"
-  "\xef\xab\x88\x84\x36\x35\x5b\xc4\xbe\xdf\x3a\x28\x34\xae\x2d\xf3"
-  "\x3b\x95\x68\x6b\x61\xb6\x97\xef\x82\x9d\xd2\x89\x90\x1e\x21\xa6"
-  "\xe1\x7f\xb8\x88\x15\xf0\x1f\xe6\xbf\xe9\x2d\xc2\xff\x29\x26\x92"
-  "\x59\x2c\xfc\x9f\x61\xf2\x69\xd4\x8a\xf5\xe6\x32\x7d\x02\x59\xdd"
-  "\xaf\xad\xe7\x36\x25\xc4\x62\x8c\x6c\xc8\x93\x6c\x22\x97\xe9\x9a"
-  "\x74\xf4\x8f\xb4\xbe\x43\x3d\xc3\xb0\x0e\x38\xf1\xab\xa8\x4b\xd7"
-  "\x68\xdf\xd8\x90\xa2\x8e\x46\x3e\x89\x7e\x20\xa8\x2f\x2d\xf4\x1f"
-  "\x67\x23\x7e\xd4\xef\xf8\xa6\x84\x68\xea\x6f\x7b\x85\x36\x40\xf4"
-  "\x1d\x07\x38\x32\x86\x57\xbe\xba\x0e\xfd\xc9\xd1\xf8\x02\x6d\xda"
-  "\x81\xd4\x87\x9c\xe0\x3b\x6e\x67\x12\x09\x2e\xe0\x98\xef\x38\xea"
-  "\x23\xc2\x0f\xe6\x1f\x49\xee\xfd\xc7\xf1\x99\xbb\xab\x45\xff\x71"
-  "\xfc\x0d\xbb\x15\xfe\x8f\x00\x99\xab\xe0\xa8\xa5\x69\xf4\x21\xc7"
-  "\x7c\x07\xab\xdc\xfa\x93\x53\x02\x9e\x29\x99\x3f\x39\xef\xc6\x81"
-  "\x6b\x31\x4c\x27\xae\xe5\x8b\xb1\xa3\x9d\xce\xed\x85\xbe\x90\xc7"
-  "\xce\x99\x05\xdf\x30\xd7\x00\xff\xd2\x23\x85\x35\x92\x66\xb4\x8b"
-  "\xe5\x51\xdb\xd7\x55\x1b\xdf\x19\xb7\xcd\x1d\x96\x5c\x1b\xb4\x3e"
-  "\xfc\x1a\x5d\x0b\xd8\x0a\xdc\xb7\x95\xf2\x2d\x36\x47\x6c\x25\xae"
-  "\xfd\xf5\xe5\x57\x96\xcc\x9b\x3f\x67\xe1\x22\x9d\xe6\xd9\x19\x93"
-  "\x68\x60\xb4\x31\x9a\x05\x89\xf3\xe9\x50\xa3\x79\x76\xf2\xe3\xd3"
-  "\xa7\xcf\x98\xf3\x87\x19\x8f\xcd\x98\xf9\x87\x47\xd9\x0e\xc3\x19"
-  "\x09\x2b\x31\xb8\x5e\xe2\x12\x0d\xde\xf4\xb2\x10\xfa\x36\x65\x7e"
-  "\xc2\x12\xd7\x7e\x1e\x4c\xed\x57\x4a\x6a\xb3\xb5\xe0\x7f\x66\x23"
-  "\x6b\x2d\x10\x6d\x57\x0c\xd3\x5a\x37\x60\xdb\xd2\x58\x87\x99\xad"
-  "\xc1\xc8\x9b\x84\x18\xc3\x38\x9e\xa8\xb0\xaf\xe2\xb8\x02\xef\x52"
-  "\xee\x88\x87\xea\xb0\x9f\xb5\xb6\x28\xf1\x3e\xa1\x8f\xb2\x73\x16"
-  "\x05\x3f\x74\x68\x3a\xf3\xc3\xdf\x6a\x13\xed\xda\x78\x4e\xac\x43"
-  "\x3d\xe6\xc9\x6c\x9d\x2c\xc5\xe4\xb4\x8c\x90\xe2\xce\x91\x2e\x6d"
-  "\x44\x08\xd2\x14\x5f\xe0\x20\x7e\xf0\xeb\x87\xbf\x29\x0e\xdc\x4e"
-  "\xe2\x8d\x38\x17\x0b\x54\xc0\xd8\x9a\xec\xc3\x62\xde\x64\xd5\x50"
-  "\xff\xec\xd3\xed\x36\x9f\x39\x76\x25\x1c\x7d\xf8\x39\x76\x15\x9d"
-  "\xff\xf1\x49\x7c\x0d\xfa\x42\x83\xfb\xaa\x31\xb6\x13\xe8\x71\xf6"
-  "\x74\x5b\x5a\xf6\x74\x3b\x6f\x9b\x03\xbc\x1c\x8e\xff\xc0\x3d\xde"
-  "\xd3\xed\xff\xe0\x69\x5c\x0b\xc8\x9b\xc3\xfc\x7f\x95\xe3\x7e\xd4"
-  "\xd9\xa0\xc3\x85\xd7\x58\x5c\xcf\xe9\x2b\xaf\x9e\x9f\xb3\xd2\xc4"
-  "\xe2\x7a\x5e\x61\xf1\x6b\x59\x5c\x5e\x92\x06\xe5\x9c\x9c\x63\xf7"
-  "\xd1\x4c\xb7\x77\xf2\x6c\x9f\xea\x75\xff\xee\x62\x75\xba\xb5\x4b"
-  "\xe4\xdc\x5d\xcd\x6f\x09\x29\xe3\x73\x34\x7b\xf9\x2d\xa1\x51\x7c"
-  "\xee\xe0\xa9\x88\xcd\x7c\xce\xcf\xb3\x21\x0d\xe7\x47\xcd\xe3\xb7"
-  "\x0c\x8e\xe2\x73\x46\x47\xc2\x11\xd2\x63\x86\xf1\x5b\xc2\xa2\xf8"
-  "\x37\x38\x7f\xb8\x4f\xcf\xbf\x01\x63\xe8\x96\xd0\x48\x3e\x87\x34"
-  "\xc1\x51\xcf\xe7\x28\x63\x20\x1f\xa4\x7d\xca\xe1\x08\x69\xdf\x88"
-  "\x4b\xe4\x7a\x05\xdc\x03\xe7\xc6\x59\xd9\xb3\x7e\xa9\xa2\xcf\xca"
-  "\x79\x48\xcd\x9e\x11\x31\x8c\x3d\xe3\x37\x5a\xf6\x8c\xdf\x4e\xa0"
-  "\xcf\xc8\xf1\x2b\x86\xfc\xe5\x7c\x8e\x7f\x1e\xe4\x9b\xc2\xe7\xf4"
-  "\xcf\x80\x23\xa4\x03\xe2\x21\x1f\xa4\x07\xe2\xb3\x20\xad\x8e\x82"
-  "\xfc\x90\x1e\x14\x0e\xf9\x2b\xf8\x9c\x60\x0d\xe4\x9b\xca\xe7\x84"
-  "\x62\xf9\x90\x0e\x23\x90\x0f\xd2\x43\xcc\x70\x84\xf4\x5d\x26\xc8"
-  "\x0f\xe9\xc7\xe0\x9d\x42\xaa\xf9\x9c\xc7\x2d\x90\x2f\x9a\xcf\x89"
-  "\x82\xe7\x85\x42\xfa\x89\x59\x90\x0f\xd2\x53\xe0\xfe\xc1\x90\x7e"
-  "\xb2\x0c\xf2\x43\xfa\xf7\xf0\xae\x21\x35\x7c\xce\x34\x78\x4e\xe8"
-  "\x0c\x3e\xe7\x69\x7c\x67\x48\x47\x17\x41\x3e\x48\x3f\x8b\xf5\x81"
-  "\xf4\x0c\xb8\x2f\x0c\xd2\x33\xa1\x0d\x42\x8c\x7c\x4e\x4c\x3e\xe4"
-  "\x8b\xe1\x73\x5e\x8c\x83\x23\xa4\x67\x47\x40\x3e\x48\xcf\x85\x36"
-  "\x1c\x0c\xe9\x57\x8c\x90\x1f\xd2\xaf\xe2\xfb\xd6\xf2\x39\x0b\x52"
-  "\x21\xdf\x2c\x3e\x27\x3e\x1a\x8e\x90\x5e\x32\x02\xf2\x41\x7a\x29"
-  "\xb4\xdf\x60\x48\x27\x62\x7b\xce\x72\x2f\xcf\xe4\x28\x7e\x8d\x1f"
-  "\xe1\x73\xd6\xee\xe1\xd7\xf4\x83\xe3\x6b\x33\xf8\x35\xbe\x5a\x3e"
-  "\xe7\x75\x15\x9c\x87\x63\x56\x24\xa4\xc7\x08\x69\x38\xfe\xeb\x18"
-  "\x48\x87\x0b\x69\x38\x66\x87\x41\x7a\x82\x90\x86\xe3\x06\x4c\x47"
-  "\xf0\x39\x39\x70\xf4\x83\xe3\x86\x7c\x48\x4f\x14\xd2\x70\xdc\xd8"
-  "\x00\x47\x1b\x9f\xf3\x06\x70\x6e\x5f\x90\xf1\x9b\xb9\x90\x86\xe3"
-  "\xfa\x68\x48\x83\x0c\xd7\x1f\x84\x74\x94\x79\xa4\xaf\x0e\xc7\x6e"
-  "\x7e\x50\x6d\x06\x17\x3a\x34\x32\xfd\x3a\x51\xa2\x4f\x9c\x92\x34"
-  "\x13\xfa\x05\xb9\xb7\x9e\xb4\xbd\x83\x7e\xfc\x31\x8f\x7d\x6b\x88"
-  "\x9e\x0b\x0d\x8d\x84\xf3\x7e\x90\xaf\xdf\x25\x62\xa5\xfe\xa1\x0c"
-  "\xa9\x26\x1a\x47\x4c\xf0\x45\xe7\x07\xf7\x7c\x0e\x5c\x28\x02\x63"
-  "\xa2\x43\xbb\xd9\xf8\x4c\xdf\x6b\xd0\x5e\xa9\x7c\xe6\x9d\xf5\x70"
-  "\x84\x74\xd0\x17\xd0\x5e\x90\xfe\xf5\x1b\x70\x84\xf4\x8b\x8f\x43"
-  "\xbb\xa5\xb6\x65\x5a\x61\xfc\xbb\xce\xc6\xb6\x2c\x9e\x47\xff\xc6"
-  "\xb8\x3f\x92\xf6\xad\x54\x0b\xe1\xb3\x22\x09\x3f\x3c\x4a\x47\xed"
-  "\x8f\x21\xda\xd8\xc0\x64\x48\x8f\xf4\xd3\xf1\x83\x1a\x73\xe9\x3b"
-  "\x64\xc2\xfc\xb9\x73\x84\x92\xd5\xe3\x4e\xbe\x9e\x58\x17\xa0\xff"
-  "\x79\x7e\x90\xdd\xd3\xf5\xd7\xe9\xf5\xfb\xa2\xcc\xec\xba\x9a\x48"
-  "\xd7\xff\x88\xd7\xdf\x09\x44\xdf\xc8\xf7\x59\xcc\x26\x62\xc5\xbd"
-  "\x14\x80\xe9\x6d\x26\x3e\xd3\x87\x18\x2c\x4d\xc2\xfb\xf6\xc3\x7c"
-  "\x9f\xe3\x7d\x9e\xec\x3a\x5c\xde\xd8\xa6\x0d\x80\x7f\x38\xcf\x85"
-  "\x71\x50\xa9\x49\x1b\x51\x5a\x4f\x3a\x8a\x76\x22\x0f\x0a\x9e\x54"
-  "\xc2\x70\xb1\x7d\x7e\xe7\xe6\xc1\xeb\x34\x29\x81\x50\x5e\xc7\xee"
-  "\x74\x2b\x6f\xd1\xa7\xa1\xbf\x21\x7a\x5e\xcf\xf6\xfa\xd0\xff\x7b"
-  "\xd9\x1a\x50\xfa\x3f\x9f\xd9\x95\x3b\x8a\xf0\x5e\xe7\x79\x85\x3d"
-  "\xeb\xd0\x04\x2e\x74\x92\x9e\x7d\x33\x6f\x5f\xf0\x21\x67\x52\x06"
-  "\x26\x12\x5f\x4d\xca\x47\x50\x7e\x7b\x89\x6c\x0e\xea\xc8\x4b\xaf"
-  "\x6d\x39\x0a\x79\x77\x50\x7b\x51\xbb\xde\x11\x4b\x15\xde\xe1\x4d"
-  "\x1c\x03\x95\x04\x63\xf2\xa9\x18\xa7\xed\x88\x44\x1f\x95\xb6\xe0"
-  "\x51\xd5\xb6\xdc\x5a\x9d\x3d\x6f\x52\x09\xbf\x75\x92\x7e\xa0\x4d"
-  "\x41\xd8\xda\xfb\x8e\xe5\xe3\xad\xc8\x21\x4f\x61\xde\xb1\x9c\xdf"
-  "\xc7\xd6\x71\xc9\x44\xa9\x4f\x38\x8b\xe9\x45\x7c\x56\xa5\xc5\xd0"
-  "\x62\x24\xfa\x04\x5a\x56\x3c\x9f\xd5\xb0\x9e\xf3\x33\xda\x0a\x91"
-  "\x8b\x27\xa3\x2d\xed\x0b\x6c\x97\xef\xa0\x9d\x61\x3c\xe9\x98\xea"
-  "\x88\xf3\x0b\x6d\xb9\x01\xda\x0e\x79\x32\xfa\xad\x98\x63\xb7\xa3"
-  "\x5f\xb1\x6c\x13\xb4\x03\x1b\x6b\x3b\xc2\x31\x46\xb2\xf0\xdc\xd7"
-  "\xb8\x41\x83\x75\x55\xb3\xf0\xfb\xa0\x1a\xfd\x34\x59\xe8\x5e\x77"
-  "\x1b\xc6\x4d\xc3\x31\x87\xe5\x75\x96\xdd\x02\x61\x8f\xff\x82\xc5"
-  "\x89\x09\x4b\x35\xcb\x16\xa4\xcc\x7f\x74\xe4\xf2\x31\x9a\x84\x64"
-  "\x4d\x02\x8d\x59\x4d\x4f\xc0\x10\xbd\x2c\x7e\x49\xa2\x06\x63\x07"
-  "\x77\x8d\x5d\x1a\xc6\xab\x07\x4f\xa1\x1c\x52\x41\xe8\xf7\x11\xbe"
-  "\x28\x2a\x2e\x31\x95\xe7\x34\xf7\xf5\x03\xee\xdc\x19\xd9\xae\xec"
-  "\xc0\xfd\x01\x6a\x2e\x53\x23\xfa\x29\x0d\xd8\x36\x88\xe0\x7e\x3c"
-  "\x98\x77\x75\x46\x38\xc6\x44\x05\xc9\x60\xf6\x91\x4e\x78\x7f\xab"
-  "\x59\xf8\x4e\xc6\x7c\xbf\x09\xd7\xd8\x77\xe4\xce\x78\x98\x2b\xd2"
-  "\xef\x25\x7c\xd1\xa4\x72\x36\x1e\x77\xd2\xf1\x9e\xd7\x44\xc5\xf1"
-  "\x7b\xfc\x74\xc0\xe9\x14\xf4\x9b\x9d\xed\x5e\xde\x40\xae\x31\x1f"
-  "\x99\x5b\x7e\x61\x42\x7f\x1b\xf6\xad\x43\x62\xb9\xd0\x5f\x98\xb8"
-  "\xbf\xf6\x0b\x4f\xdf\x4d\x94\x07\xa0\xff\xab\x34\xa0\xdf\xf7\x91"
-  "\x7b\x3f\x4a\x6b\x52\x42\x9d\xf7\x7d\x94\x66\x54\xf2\x79\x43\x23"
-  "\x5a\x47\xf8\x47\x5b\x85\x18\xb7\x06\x9b\x95\x7c\x1a\x45\x70\xae"
-  "\x56\x6a\x09\x09\x4f\xb6\x84\x0c\x99\x62\xdd\x12\x61\xd2\xdf\xf7"
-  "\x4b\x32\x79\x34\x7f\xf5\x93\x32\x42\x5a\x14\x24\xee\x93\x28\x9c"
-  "\x3f\x0c\x8e\xb4\xaa\x07\x47\x59\xb6\xfe\x22\x16\x7d\x27\xb5\x6f"
-  "\x7d\x38\xbc\x23\xf4\x2e\xfd\x71\xc8\x73\x0a\x24\xf7\x99\x06\xf4"
-  "\x77\x38\x51\xb6\x8f\xf2\xd5\x1f\xe8\xc8\x55\x96\x97\x4d\x64\xb6"
-  "\xdd\x58\xe8\x33\x54\x9f\x6c\xcf\x7c\x72\xb0\x8c\xc0\xb3\xc9\x81"
-  "\x8e\x29\xca\x4f\x23\xba\x5c\x5f\xfa\x49\x78\x19\x69\x43\xbf\xa7"
-  "\x30\x7f\x3c\x7a\x36\x9f\xf0\x5b\xc7\x15\xed\x4b\xb1\x2a\x67\x99"
-  "\x88\xb2\xd2\x98\x4f\x52\x1b\xc9\x00\xdb\x55\xad\xea\x3d\xb8\xbf"
-  "\x1d\x63\xa3\x7c\x16\x46\xfd\xe2\xa5\xe9\x69\xfc\xcc\xc0\x2a\xe0"
-  "\x0e\xdc\x55\xad\x5f\xd5\x0c\x3d\x81\xeb\xa3\x6c\xbf\x0f\x23\x95"
-  "\x71\x66\x62\x88\x29\x22\xed\xca\x48\x72\xe8\x85\x22\xb2\x03\xe6"
-  "\x22\x3b\xae\x90\x00\xca\x83\x3b\xb5\x7e\xb6\x4e\xad\xca\xb6\x4a"
-  "\x8b\x7e\x8a\x78\xfe\xaa\xb6\x3f\xf2\x62\xdb\x12\xad\x7f\x95\xb9"
-  "\x88\x8c\x6f\x22\xda\x76\x25\x09\x6c\x5f\xa5\xed\x5f\xa5\xcb\x87"
-  "\xb2\x80\xe8\x42\xbb\xa2\x8f\x34\xf4\x9d\x86\xed\x74\x67\x0c\x99"
-  "\xd1\x42\x6c\xa3\xfb\xd7\x90\x10\x8c\xd7\x82\x5c\x13\xfd\xac\x72"
-  "\xc1\xe3\x8a\xec\xc1\xbf\x88\x4d\xbb\x0e\xf5\x42\xdf\x42\xfb\xd5"
-  "\xd5\xc8\xd5\x81\x87\x28\xf0\x9d\x39\x5e\xdb\x7f\x0e\x1e\x37\xab"
-  "\x47\x21\x5f\xe7\xda\xc2\x30\x9e\x8c\x3f\xd6\x13\xe3\xc4\xae\xbe"
-  "\x00\x6d\x99\xae\x55\x41\xbe\x00\x38\x3f\xd0\xd0\x62\x25\xf6\xb1"
-  "\x6a\xd3\x38\x1d\x8d\xff\x19\x5c\x98\x46\xd4\xb9\x69\x24\x58\xf3"
-  "\x6b\xaa\x4b\x4f\xda\xf7\xa9\xab\xf9\xac\x01\x23\xd0\xe6\x42\xcf"
-  "\x11\x7e\xb4\xe6\x09\x42\x34\xbf\xc4\xff\xdc\xe7\x9a\x47\x40\x86"
-  "\xc1\xe3\x08\x9d\x4b\xd0\x79\x29\x77\x82\xcd\x93\xb8\x0f\xdb\xfd"
-  "\xfe\x18\xc3\x65\xbd\x91\xc8\xad\x51\x0d\xc3\xd8\xbc\x57\x08\xb7"
-  "\x9b\xcf\xd9\x3e\x83\xcf\x8b\x28\x67\xbe\xd6\xb9\x9d\xed\x7e\xfe"
-  "\x30\x06\x6f\x2f\x85\xf2\x27\xb6\x2b\x54\x35\xf0\x33\x0a\xf7\xe7"
-  "\xe1\x7b\xdb\xf7\xf8\x4d\xc1\xf7\xa6\x31\x48\xe0\xbd\xe6\x80\xcc"
-  "\xf8\xd0\xb1\x25\xd4\xa7\x75\x27\xb4\xaf\x10\xab\x11\xdb\x03\xdb"
-  "\x80\xeb\xd4\xf6\xa7\xef\xda\xa9\x0d\x80\xf6\x45\x3f\xa9\x81\x69"
-  "\x73\xe1\x9e\xad\x63\xcb\xe0\xda\xc0\xf6\xe0\xb1\x56\x8c\x05\x64"
-  "\xd0\x99\x89\x7d\xcb\x58\xf4\x55\x1b\xbc\x2d\x05\xfa\x5c\xc8\xd8"
-  "\x12\x7e\xcb\xd8\x0a\xa1\x6f\x11\xac\x27\x97\xb3\x43\xd5\x8e\xfb"
-  "\xe2\xa0\x6e\x50\xbf\x1a\xf8\x19\x4d\x84\x0b\x6b\x1f\xe9\x17\x03"
-  "\x33\x9c\x16\xa8\xeb\x30\x3e\x6b\x64\x14\xfe\x87\x6b\xc3\xa0\x6d"
-  "\x14\xd8\x0e\xd8\x1e\x42\x5b\xb4\x4b\x6d\xf1\x4c\x06\xe4\x6b\xe2"
-  "\xb2\x30\xce\x33\x57\xce\x67\x69\x54\x52\x3e\x7e\xb8\x94\xef\xa5"
-  "\x11\x2c\xdf\xc6\x72\x96\xef\xfe\x54\xb8\xfe\x21\x6b\x6f\x7e\x7e"
-  "\xd7\xf6\xe6\x5f\x92\xee\x9d\x5c\xc1\xee\x4d\x89\x61\xf7\x86\xe0"
-  "\xbd\x5b\xe4\x75\xe2\x37\x48\xf9\x23\x09\xcb\xbf\xdc\x9f\xe5\x57"
-  "\x4f\x71\xca\xf7\x81\x94\xef\xf7\xeb\x59\xbe\xf4\x22\x96\x6f\x68"
-  "\x31\x5c\xff\xce\x4d\x5d\xbe\x91\xee\x59\xa0\x66\xf7\x6c\x3f\xc2"
-  "\xee\x79\x28\x02\xf4\x69\xb8\xac\x2e\x0a\x32\x44\xca\xff\x8a\xf0"
-  "\xde\x5b\xa6\xb2\xfc\xe3\x1b\x9c\xf2\x3d\xc6\xf2\xe1\xf5\x22\xc8"
-  "\xc7\x1d\x69\xf7\x5b\x6c\x61\xf9\x1e\x59\x87\xfa\x08\x79\xe6\x72"
-  "\x59\x03\xf7\xb6\xfb\xdd\x59\x0c\xe5\x94\x80\x6c\xc2\xf0\x08\xb2"
-  "\x0b\xe3\x72\x07\x47\xc2\x7f\x2d\x7e\xbb\x41\xcc\x35\x91\x4e\x7f"
-  "\xc0\x5d\xbb\x5b\xfb\x56\x16\x29\x72\xd8\xd7\x38\xe0\x06\x5b\x42"
-  "\x3c\xfa\xc9\xa3\xbe\xb0\xb7\x86\x98\x72\x39\x16\x2b\x1a\x74\xd4"
-  "\xaf\x5e\x41\x4e\xc2\x58\x98\x81\xd7\xb8\x3c\x6d\x2c\x37\x02\x30"
-  "\xf6\x32\xf1\x31\xa4\x36\x91\x12\xae\x49\x99\xdb\x41\x54\x55\x30"
-  "\xc2\x60\xfe\x12\x18\x53\x35\x8b\x7d\x78\xb8\xe7\x42\xee\x0d\xa1"
-  "\xbc\xa2\x28\x5d\xfa\x22\x16\x8b\x17\x39\x16\x62\x33\xf4\xc7\x00"
-  "\x1a\xd7\x69\x31\xf0\x00\x85\x22\x04\xfe\xfb\xd3\xd8\xcb\xa3\x54"
-  "\xe6\xf6\x7f\x8f\xd2\x75\x6c\x1d\xaa\xef\x1c\xd5\xaf\xba\x3d\x54"
-  "\x1b\x6b\xdb\x3a\xca\x64\xbb\x6f\x92\xa9\xf3\xaf\x7e\x3a\x7b\xe8"
-  "\x5d\x91\xf0\x6c\xc0\xed\x7c\xe5\x7e\x2e\x57\xb9\x3f\xad\x54\x89"
-  "\xe5\x7e\x94\x56\xac\x3c\x9a\x56\xad\x3c\xca\x95\x2b\x3f\x4a\x2b"
-  "\x82\x63\x09\xc6\xf8\xb9\x17\xca\x9e\x7f\x34\x4d\xaf\x6c\xcb\x52"
-  "\xec\x81\x7e\xb0\x5e\xb4\x4f\xf2\x8f\xdb\x48\x55\xb1\x8d\x9c\x48"
-  "\xbc\x4e\xcc\x41\x83\xa7\xc0\x6f\xaa\x39\x64\x6c\x93\x39\x24\xc2"
-  "\x44\xeb\x1c\x3a\x9e\xbe\x23\xee\x2b\x3d\xca\xb1\x3a\x0b\xed\x81"
-  "\x65\x56\x16\x72\x44\x25\xf8\xad\x0c\x68\x56\x28\xb3\x69\xdb\xe4"
-  "\xae\x88\x83\x39\x51\x1b\xdd\x97\xa2\x64\xf1\xa5\x44\xbf\x90\x62"
-  "\x7c\x2a\x1a\x93\xaa\x4d\x8b\xdf\xd9\x47\x60\x5c\xaa\x9d\x37\x48"
-  "\x30\xfc\xc2\xc4\x98\x43\x3b\x05\x5f\xf4\x39\x49\x92\x2d\x41\xb0"
-  "\x11\x04\xb3\xf8\x42\xdb\xa8\x5f\x6d\xca\x67\xd0\x87\x24\xda\x0b"
-  "\x96\x69\xc9\xae\x04\xc9\x5e\x60\x6f\xd3\x2a\x61\x0e\x58\x4d\xe7"
-  "\x80\x30\x7e\xd1\x98\x74\x36\xe0\x67\x5b\x46\x45\xe2\x5c\x0f\xf9"
-  "\x58\x5b\x96\xf2\xa0\x38\x57\x43\x8e\x61\xdf\x34\x38\x06\x7e\x33"
-  "\xe0\x3c\xe0\xc5\x5f\x35\xe2\x79\x7e\x73\x5d\x06\xda\xc9\xed\x7c"
-  "\xdc\x6f\xdb\x70\xaf\x24\x1f\xf7\x3b\xfb\x96\x21\xd1\xf6\x2d\x11"
-  "\x7a\x38\x37\x11\x7e\x8f\xda\x37\xd5\xad\x83\x5f\x36\xfc\xd6\xc3"
-  "\x2f\x17\x7e\x79\xf0\xcb\x87\x5f\x11\xfc\xf6\xc0\xaf\x18\x7e\x7b"
-  "\xe1\x57\x02\xbf\x83\x7c\x50\x5d\x01\xfa\x54\x84\xb2\xf5\x20\xf7"
-  "\x30\xb1\x5c\xa9\x7d\x7d\x1e\x84\xf7\x8d\x44\xfe\xc3\xe5\x6c\x67"
-  "\x3e\x05\x41\xe7\xf9\xb7\x7d\x93\x11\x77\xf9\x91\xfe\xd1\xe6\xe1"
-  "\x51\xb1\xe6\xe1\x93\xca\xcd\x41\x4f\x59\xcd\x41\xbf\x07\x19\xfe"
-  "\xde\xdf\xbc\x65\x1c\x01\xf9\x95\x9b\x43\xc6\xe5\xb6\x65\xf9\xe4"
-  "\x99\x14\xfd\xa9\xbf\x5b\xf8\x5f\x04\xff\xf7\x08\xff\xf7\x9a\x14"
-  "\xfd\xe8\x3a\x5b\x73\xc8\xf8\x68\x48\x1f\x31\x29\xfc\x69\xbe\xd6"
-  "\xd0\x71\x6a\x61\xcf\x65\x06\x9c\xaf\x31\xf9\x70\xd1\x2c\xdf\xa8"
-  "\x6a\xe7\xfe\xb2\xe8\x15\xdd\x9c\x45\x73\x93\xe7\x2c\x8b\x5f\xf0"
-  "\xca\xfc\x65\x8f\x68\x46\xce\xd3\x68\x17\x24\x2c\x9d\xb3\x74\xf9"
-  "\xfc\xe5\xf3\x29\x6d\x82\x53\xa3\xe5\xeb\xcd\x70\xdf\xa4\x6d\xbf"
-  "\xda\xcc\x01\xdf\xaf\x6a\x68\x22\x77\x02\xd7\x5f\xfd\x12\x51\x56"
-  "\x58\x0e\x12\xe0\xe5\x3a\xce\x2f\xf2\x77\x55\xf3\x4c\xe4\x48\xb3"
-  "\x59\x69\x03\x1e\x33\xd5\xac\x87\x7e\xa8\x8d\x1d\xd0\x30\x87\x3f"
-  "\xd2\x6c\x55\x4e\x6d\xd1\x93\xf4\x0b\xc0\x6b\xe6\x59\x49\xe7\x28"
-  "\x3f\xdd\x91\xe6\x12\xe0\xb4\xc0\x6f\x32\x3a\x48\x85\xd5\x06\xfa"
-  "\xfa\x0b\x13\xde\xcb\x03\xbf\xc1\xfc\x38\x97\x40\xdf\xae\xd0\x87"
-  "\xc2\x79\xe8\x4b\x98\xff\x28\x9c\x7f\x5a\xa7\x27\xd3\xa0\xac\xce"
-  "\xd0\x51\x26\x1e\xfa\x12\x7f\x63\x35\x5f\xd1\xa0\x27\x47\x17\x96"
-  "\x28\x3f\x84\xfb\xd1\x76\xc6\xff\x55\x65\xc6\xbe\xc7\x43\x9f\xc3"
-  "\x7b\xf0\x5a\xbd\xc2\x37\x15\xaf\xe3\xdc\xa0\x13\xea\x7b\x00\xca"
-  "\x4b\x5f\x4e\x54\x6c\x0e\xe5\xd2\xa7\x93\x02\xf9\x2b\x0a\xd5\x37"
-  "\xd8\xa7\x79\xa8\x2b\xbe\xc7\x3e\xb8\x77\xff\x42\x2b\xb3\x9f\x5e"
-  "\x47\xec\x30\x11\xc4\x0d\xc4\x0b\x43\x2a\x9b\x53\x95\x70\x46\x98"
-  "\x8b\xf9\xc0\xbd\xbe\x23\xf1\x1a\x70\x73\x0b\xfa\x60\x6b\xcb\xf2"
-  "\x8d\x15\x39\xf1\x9b\x82\xff\xb5\x3b\x6b\x41\x57\x66\x93\x7b\xe1"
-  "\x39\x23\xb1\x4d\xb1\xcd\xf0\xbb\x69\xa7\x9f\x4f\x03\xfa\x78\x28"
-  "\x18\x44\xfc\x3b\xb7\x4c\x2a\xdd\x81\x7e\x32\xb2\x7c\x1d\xf6\x7f"
-  "\x4b\xf0\xa4\x52\x67\x59\x32\x19\x6a\xe6\x2f\x9e\xfb\x72\xfc\xfc"
-  "\x79\xf4\x53\xdb\xdc\x65\xcb\x96\x2f\x9a\xaf\x99\x3f\xf7\x95\x38"
-  "\x0d\xbd\xac\x59\xbe\x0c\xb2\x2c\x48\x5c\xa6\x59\xb2\x62\xb1\x66"
-  "\xd1\xb2\x05\xc8\x98\xe7\x27\x24\x2c\xd7\x25\xf6\x27\xec\x4e\xcd"
-  "\xa2\xe5\xf1\x89\x0b\x74\xf0\x67\xd9\xfc\xc5\xf3\x34\x54\x13\x96"
-  "\x41\x51\xf1\xf1\x1a\xe1\x09\xcb\xe2\xe6\x26\xa0\x72\x2c\xfe\x13"
-  "\x64\x72\xba\x5f\xce\xa7\x03\xd0\xbf\x1d\xae\xbf\xba\xa2\xe8\xa7"
-  "\x28\x53\x01\x0e\xe5\x4d\x2a\xc5\x75\x0b\x90\x26\x74\x8e\x95\xe5"
-  "\x5b\x82\xf6\xe5\xb7\x06\x11\x55\x2b\xf4\x83\xb6\x2c\xbf\x54\xf1"
-  "\xdd\xa8\xbd\x19\x7d\x48\xa2\x7f\x52\x85\xdf\x65\xba\x1f\x18\xfa"
-  "\x04\x5d\xd7\x92\xe5\x7b\x9c\xda\xa1\xb2\xfc\xf6\x3a\xdb\xb8\xa8"
-  "\x4d\x55\xe1\x77\x02\xd7\xd1\x41\xbf\xa0\xfe\x1a\x04\x5f\xec\x0a"
-  "\xb8\xe7\x3b\xbc\x87\xdb\x12\x51\x0e\xf7\x35\x48\x5c\xdd\x0f\x63"
-  "\x06\xa8\x68\xbe\x2c\xbf\x81\x7c\xc8\x38\x02\xe7\x8a\xb0\x5e\x1e"
-  "\xc6\x15\xcd\x0d\x28\xf7\x33\x98\x8d\x3d\x10\x4c\xb4\x37\x36\x0f"
-  "\x4d\x6e\x1b\x34\x38\xb6\x23\x93\xf4\xeb\x80\xbe\x6d\x55\x92\x7b"
-  "\xdb\x41\x2f\x56\x3e\x48\x7c\x56\x4f\x23\xca\x12\xd0\x37\xf4\xd1"
-  "\x5f\x31\x25\x9f\x18\x40\xf2\x06\xeb\x5e\x52\xa1\xaf\x27\x95\xb6"
-  "\x77\x99\x7f\xff\x14\xe4\xda\xfe\xf3\xd1\x47\x5d\xfa\x6a\xde\x7e"
-  "\xe0\xb0\xd9\x77\x3f\xe8\xa3\x26\x81\xdc\x6b\xb0\x9d\xd7\x1b\x52"
-  "\xf7\x10\x43\xb2\x41\x8f\xfe\x41\xa0\xdd\x9e\x39\x0a\xd7\xee\xa8"
-  "\x80\xfb\x9e\x26\xfd\x20\x3d\x19\x9f\x91\xbd\x95\x37\xbe\x1e\xca"
-  "\xd7\xbe\xbe\x95\x37\xad\x0f\xe5\x1b\x40\xa7\x9a\x36\x84\xf2\x2d"
-  "\xb8\x2e\x00\xd7\x3f\xa0\x9e\xea\x92\x48\x58\xb3\xa2\x5f\x2d\x9d"
-  "\xfb\x47\xd1\xf4\x10\x48\xd3\x35\xb9\x86\xe4\xad\x98\x1e\x0a\x69"
-  "\x1b\x4b\x17\x62\xfa\xae\x66\x85\x7f\x00\x4b\x7f\x82\xe9\x61\x90"
-  "\x1e\xc6\xd2\x55\x84\xfa\xb9\x50\xf8\x8f\x61\xe9\xaf\x30\x0d\x6d"
-  "\xef\x3f\x51\x9f\x84\xf5\x3d\x07\x32\xf3\x7f\x32\xbd\x0e\xe6\x6c"
-  "\xc9\x97\x68\x7f\xf8\x28\x2d\x0e\x6d\x13\xd0\x1f\xfa\x55\xa2\xbe"
-  "\x03\x4e\xc5\xfb\x85\xe3\xb1\x9f\x2e\xd0\x4a\xfa\x01\x7f\xba\x13"
-  "\xae\x3d\x8a\x6d\xe7\xd6\x16\xb3\xdf\x7f\xd7\x74\x1b\xaf\xe7\xdf"
-  "\xf6\x8b\xe3\xb7\x68\x4d\xfc\xdb\xfd\x4a\x78\x3a\xb6\x85\x14\x95"
-  "\xa4\x58\xa9\x1f\x62\xe0\xac\xd0\x87\xfc\xa9\xbf\x11\x33\x70\x40"
-  "\x0f\x7e\x49\xd5\xfc\x96\x21\x26\x98\x5b\xc5\x4c\xd3\xda\x70\xbd"
-  "\xb3\xe2\x8a\xe2\x8e\x47\x4f\xc4\x21\x57\x18\xff\x07\x6e\x4f\xbf"
-  "\x12\x2e\x3d\x86\xf0\x23\xfc\xe2\xa6\xc5\xf1\x7a\x18\xb7\x14\xcc"
-  "\x96\xcd\x9f\xc7\x58\xe5\xf4\xb9\x23\xfd\xe2\xb8\x15\x71\x18\xa7"
-  "\x85\xe2\x4b\x1a\x8e\xe1\x49\x80\x07\xab\x62\x02\xed\x5b\xc6\x47"
-  "\x9f\x88\x6b\xf4\x2e\xe6\x87\xe2\x8e\x89\x1e\xd7\x3a\x41\x9d\xd0"
-  "\x57\xa7\x0d\x9e\x63\x83\x77\x45\xbe\xb0\x1f\x78\x01\xf0\x96\xb8"
-  "\x7d\x2f\x1b\x7d\xf9\x15\x31\x81\xf0\x4e\x0f\x1a\xb4\xd7\x49\x55"
-  "\x07\xf6\x95\x3b\x6c\x27\x92\x09\x99\x9c\x6c\xd3\x07\x9a\xa9\xff"
-  "\x64\xb5\x6e\x21\xb9\x87\x0f\x19\x62\x6a\x56\xf4\x9f\xfa\x74\x2a"
-  "\xbc\x03\xbc\xfb\xd1\x7a\xa3\x8a\x83\xf7\x18\x6f\x13\xd6\xd2\x2a"
-  "\xfa\x87\x43\xdb\xc6\x88\x5c\xdf\xcb\xfa\x53\xbd\xe1\x96\xc5\x10"
-  "\xdc\xd7\x7c\x20\x0d\xea\xd7\x19\x13\xc8\xc1\x98\x84\xd7\x4e\x68"
-  "\x2f\x13\x7c\xa6\xd0\xd6\xcc\xd7\xee\x08\x68\x67\x78\x3e\xfa\x6d"
-  "\x16\xdb\x15\xc6\xb5\x70\x7b\x67\x9c\x7b\xf9\x6f\x1d\xaf\x81\xfa"
-  "\x45\xf3\x9b\xea\x74\x6e\xaf\x6f\xae\x9b\xce\xf4\xc3\x37\x1b\x7e"
-  "\xf9\xfc\xee\x49\xd5\xe6\x91\xbe\xc5\x34\xbe\xde\xd6\x51\xd1\x4e"
-  "\x71\xd4\x41\x47\xfa\x57\x62\x1c\x75\xf7\xbe\x05\x97\xc6\xd1\xf8"
-  "\x45\xbe\xe7\xf9\x40\x3b\xc6\x16\xbd\x8e\x3e\xc0\xe3\x4e\x68\x2d"
-  "\x5e\xca\xf4\x4e\xb5\x27\x99\x62\xf9\x30\xcf\xee\xf4\xb2\xbc\x58"
-  "\x8f\x3a\xb2\x07\xda\x45\x5d\xa7\xeb\xe0\xa3\x14\x8c\x8f\x07\xd8"
-  "\xb1\xad\x3a\x81\x4b\xa7\x9c\x26\xca\x0e\x18\x37\xdf\x7b\xae\x48"
-  "\x39\x06\xfa\x1d\x70\x95\x8c\x0a\x63\x05\x99\x3e\x8f\xa4\x57\xb6"
-  "\x5c\x43\xdf\xe9\x34\x2e\x11\xcc\xd9\x34\x7b\x9f\x33\x2b\x31\x26"
-  "\x08\xc6\x21\xaa\xb2\x58\x71\x1e\xae\x3e\xf0\x9c\x55\x69\x5f\x11"
-  "\xa3\xc1\xd8\x11\xf8\x7d\x37\xad\x85\xe7\xe8\xf7\xa5\x56\xe0\x81"
-  "\xad\x30\x47\xcd\x55\x8f\xa9\x88\x2d\xa7\xf1\x52\xd1\xaf\x51\x65"
-  "\xdc\x75\xf2\xd9\xba\xa3\xa4\xc2\x68\xc4\x7d\xd1\xbb\x2b\x1a\x8e"
-  "\x10\xae\x55\x3b\xd0\xbe\x4c\x3b\xa8\x20\x81\x04\x43\x3f\xbd\x83"
-  "\x83\x36\xe6\x97\x09\x71\x28\xaf\x49\x71\x28\x31\xce\x7b\x01\xc6"
-  "\x94\xbc\xac\x26\x36\xbf\xfe\x16\xc8\xaf\xc2\x98\x93\x3b\xaf\x11"
-  "\xed\x8e\x04\x32\x62\x07\x5c\x93\x7d\x5b\xfa\xb3\x16\x6d\xf9\xfe"
-  "\x03\xaf\xb3\x98\xf3\x1c\xc8\x49\x8c\x39\xf9\xf4\x75\x0d\x39\xf2"
-  "\x55\x91\x12\x75\xcf\xbb\x76\x0e\xa0\xfe\x88\x6c\xa1\xe3\x35\xb6"
-  "\xa0\x3a\x9d\x6d\xa4\x1f\xe8\xf0\x9d\x7a\x90\x97\xdb\xf9\x88\xd8"
-  "\xf6\x9d\xe9\x62\xdb\x0f\x7c\x4d\x6c\xfb\x55\xcf\xc3\x5c\xfe\xaf"
-  "\xfd\xc2\xdf\x3d\x9b\x2f\xb5\x7d\x4d\xd7\xb6\x77\x6d\xf3\xfd\x2f"
-  "\x58\x95\x54\x1e\x2f\x00\x07\xfa\xab\xaf\xfe\xdd\x17\x98\x0c\x78"
-  "\x2a\x83\x58\x49\x06\x9d\x20\x83\x4e\x49\x06\x69\x4b\x45\x19\x34"
-  "\x32\x19\xd4\x50\x19\xcc\xa5\x32\x80\xb9\xb5\x7d\x95\x76\xd0\xf6"
-  "\x14\x12\x5c\x90\x42\xc2\xa8\x1c\xd4\x4b\x31\x36\x4c\xff\x0d\x29"
-  "\x04\xd7\xf3\x86\x43\x5f\x14\xe5\x10\x2c\x93\x43\x8a\x20\x87\x0e"
-  "\xa2\xdd\xde\x41\x46\x6c\xcf\x64\x72\x40\x5c\x7f\xda\x12\xc8\x73"
-  "\xdf\x6a\x49\x61\x33\xc8\x61\xa9\x20\x87\x20\x41\x0e\xab\x40\x0e"
-  "\x4b\x41\x0e\xf0\xfe\x27\xb4\xde\x62\xe2\xc0\xe8\xae\x72\x18\x30"
-  "\xb1\x27\x39\x74\x38\xe4\xa0\x1e\x4e\xe5\x00\x5c\x2a\xe5\x19\xb4"
-  "\x4f\xf5\x0b\x7f\xe7\x8b\x5c\xe5\x98\x18\xc0\x1e\x68\xd3\x8a\xa9"
-  "\x65\x64\x7a\x2c\x49\xb7\x81\x4c\xde\xfd\xc2\xaa\xac\x68\x00\x79"
-  "\xcc\x13\xe2\x15\x39\xc9\x83\xb6\xfb\xd6\xb1\x9a\xf7\x20\x8f\xe6"
-  "\x39\xec\x27\xe3\xd4\xfb\xbe\x00\xee\xe8\x26\x7e\x97\xf3\x77\x57"
-  "\x28\x8b\xc3\xd8\xcd\xb8\x56\x0d\xe6\x4e\x03\xb7\xc3\xdc\xa8\x32"
-  "\xae\x8e\x88\xdf\x5f\x3f\xab\xd5\x43\xd9\xda\x41\x9f\xa9\xfe\x9b"
-  "\x9c\xaa\x28\x27\x81\x30\xf7\xde\xc1\x91\xe0\x53\x35\x07\x91\x17"
-  "\xa8\x41\xc7\xef\xb0\x83\x7c\xec\x6d\x61\xfd\xd7\xc3\xfc\x09\xbf"
-  "\xcb\x3a\x7f\x8f\xc5\xb8\xab\x3c\xc8\x06\xce\xab\x6c\x20\x9b\x82"
-  "\x1b\x44\xbb\xed\x06\x19\xb1\x4d\x90\x8d\x23\x1e\xeb\x45\x2d\xd9"
-  "\x59\x4f\xfc\x07\x2c\x60\xb2\xb1\x8b\xb2\x59\xa1\x55\x4e\x5b\xa0"
-  "\x21\x87\xa1\x4d\x4e\x68\x4f\x7b\x29\x9b\x40\xca\x1b\x60\x5e\xa9"
-  "\x81\xf9\x8f\x8e\xa7\xb2\x19\x58\xe6\x49\x36\xf6\x3d\xbe\xd9\x76"
-  "\xf5\x60\xf4\xe7\x7b\x2f\xb7\x64\x86\x82\x83\xb9\x52\x07\xcc\x49"
-  "\x3f\x33\xdb\x48\x2a\xcc\x1b\x52\xea\x88\x9f\x61\xc6\x17\xc4\x60"
-  "\x2a\xa5\xfe\xaf\xd1\xd6\x8b\x31\x28\x0c\xb6\x52\x68\xef\x87\x23"
-  "\x31\xbd\x93\xa6\xcd\x64\xd5\x4b\xc4\x87\xc6\xf7\x8b\x29\x22\xeb"
-  "\x81\x57\xef\x7b\xa1\x48\xc9\xe5\x0d\x8d\xe0\x03\x60\x9e\x9a\x49"
-  "\xf4\x55\x3a\x1b\x62\x51\x40\x65\x5c\x05\xfa\xa3\x3c\x9f\x9e\xcc"
-  "\x5f\xa8\xb2\x40\x99\x66\xbe\xc3\x0e\x63\x43\x61\x26\x5f\x8a\xf1"
-  "\x04\xc6\x27\x53\xce\x8d\x7a\x62\x47\xce\x81\x36\x2f\x7d\xda\x76"
-  "\xe0\x58\x41\x74\x0f\x04\x9c\x53\x54\x2e\xb4\xc0\xf5\xe0\xa5\x58"
-  "\x2f\x66\x7f\x66\xc7\xf1\x18\x07\x2d\xf4\xe1\xb5\x1f\xa6\x99\x55"
-  "\xb9\x30\xd7\x05\x2e\x06\xf9\x82\xa6\xf1\x6c\x1e\x58\x6a\xa8\xb1"
-  "\x52\xdb\xa3\x39\x3d\xce\x2f\x37\x05\xd7\x5b\x61\x6c\x02\x1c\x9b"
-  "\x83\x87\xe3\x1a\x0d\x7e\x0f\x8c\x4b\xa1\xa3\xa2\x4b\x5e\x36\x2b"
-  "\xa5\xf1\x37\x28\x19\xc6\xad\xe2\xc9\x5a\x3e\x1d\x63\x38\x1c\x85"
-  "\xf7\xc2\xf9\xcf\xbb\xf5\x56\xa5\x15\x30\xe4\xbd\x97\xb3\x95\x68"
-  "\x1b\xb1\x82\xfe\x55\x7c\xf5\x9f\x34\xe6\xe2\x25\xc5\xa0\xd7\x4f"
-  "\xc5\xd8\x08\x3e\x7f\xe6\x68\xa2\x82\x32\x8e\xb4\x2b\xf3\xad\xed"
-  "\x7e\x77\x46\xa7\x37\x48\xf1\xe6\x9c\xe3\xca\xa1\x2e\xef\x7b\x19"
-  "\xca\x84\x72\xf6\xd7\x67\x28\x79\x11\xd7\xaf\xa3\x0d\x5b\x8e\x29"
-  "\x95\x2d\x97\x49\x1a\xe8\x71\x65\x5c\x11\x8d\xb3\x31\x10\xf0\x9c"
-  "\x5b\x05\x38\xd2\x09\x73\x7d\xc0\x11\xec\xff\x85\x80\x1b\xdc\x2a"
-  "\x98\xe3\x77\xc0\x1c\x5f\xc0\x0f\xe4\x58\x78\x7c\x09\x74\x34\xb0"
-  "\x1c\xce\x81\x9c\xb8\x4d\xa0\xa3\x80\x1f\x3b\x52\x18\x8e\xef\x44"
-  "\xfc\x00\xfe\xfb\xb4\x0e\xf0\x63\x05\xe0\x47\x12\x8d\x07\x1a\x56"
-  "\xa8\x64\xb8\x71\xb8\x3e\x5b\x99\x2b\xc6\x2e\xa6\xed\xfb\xb3\xbb"
-  "\xab\x50\x3f\x62\x33\xb0\xae\x4a\x3b\xc6\xc2\x58\x15\xe3\x53\x65"
-  "\x01\x1d\xd9\xfa\x70\x38\x9e\xa3\xf8\xb9\x22\xae\x3f\xc7\x74\x2d"
-  "\x12\xdb\x64\xd7\x15\x12\x4e\x63\xe3\x5d\x0d\xeb\xbf\x71\x31\x19"
-  "\x53\x78\x85\x8c\x28\x5c\x4c\xb4\xd0\x5f\x95\x85\x50\x87\xd9\x4b"
-  "\xd5\x84\xc6\xb3\xf0\xbb\x33\x06\xce\xbb\x8d\x67\x01\xfc\x39\xac"
-  "\x10\xfb\xcc\x12\xad\xa3\x4e\xb6\xdc\x69\xc4\x0e\x6d\x47\x7d\xb5"
-  "\x29\x7e\xb6\x9c\xad\xa1\x56\x16\x31\x3e\xff\x33\xc1\xcf\x78\xbf"
-  "\x3d\x30\x27\xe9\xd7\xac\xf8\xd9\x4b\xfc\xe6\xc0\x7c\x5d\x0a\x51"
-  "\x34\x8b\xd7\x80\x63\x72\x20\xab\x71\x19\x24\x83\x0b\x5a\x91\x6d"
-  "\x48\xbe\x8c\x3e\xe3\xbd\xec\x87\x3f\xa3\xdf\x29\xec\xb9\xd3\x54"
-  "\x74\xed\xcf\xe6\x69\x01\xbb\x9a\x49\x38\xff\x67\x90\xc7\x42\x78"
-  "\xd7\x66\x32\xa2\xa0\x19\xde\x75\x05\x7b\x57\x31\x56\x33\x97\xb9"
-  "\x0d\xf1\xda\xbd\xdd\x45\x8c\xfb\xf7\x67\xad\x12\x6d\x42\x80\x61"
-  "\x3f\xe3\xef\xc3\x75\xc5\xd4\x17\x4f\x9b\xc1\x56\x47\xf0\xb9\x68"
-  "\x17\x32\x5c\xa3\x3a\xfd\x0c\xea\x32\x57\x34\xa9\x7a\x4e\x2d\xe8"
-  "\x76\x5b\x1c\xe1\xe1\xff\xd1\x7a\x33\xfa\xbe\xa1\xdc\xce\xa4\x08"
-  "\xca\x40\x3e\xf6\x11\x9c\x43\xdd\x77\xd2\xf9\x0c\xd4\x79\xbc\x4e"
-  "\xf5\x1e\xee\x33\xd4\x36\x12\x2c\xcf\xb9\x1c\x94\xbf\x58\xd6\x25"
-  "\x45\xc8\x43\x58\x16\xea\x02\xda\x73\xb0\xaf\x31\xd9\x97\xe2\x1a"
-  "\xf2\x30\x3e\xf4\x2e\x3d\x4b\x9b\xd1\xb6\xa4\x46\x1d\xa0\xba\x02"
-  "\xe3\x2a\xfa\x4a\xe6\xf9\x18\x1f\xd0\x33\xac\x67\x7f\x90\x77\xb8"
-  "\xa8\x17\x70\x2e\xd8\x55\x37\x06\xae\x51\xe3\xdc\x25\x18\xff\xf7"
-  "\x56\x3f\xbc\x93\x5f\xc8\x04\x8f\xeb\xdb\x46\x00\x8f\x05\xbc\x44"
-  "\xdc\xb4\xb7\x3a\x61\x66\x0b\xc3\x4c\xc4\x24\x11\x37\x29\x36\x51"
-  "\xbf\xff\xa5\xb8\xfe\x34\x8e\xd6\xd1\x4b\xdc\xac\x6c\x91\x70\xf3"
-  "\x69\x9d\x13\x6e\xb6\xf0\x1d\xdc\x48\x77\xb8\x19\xfa\x90\x1c\x37"
-  "\x43\x1f\x96\xe3\xe6\x90\x9d\xae\xb8\xd9\x15\x33\x43\x57\xba\xc3"
-  "\x4b\x98\xaf\xdc\xdb\xac\x18\x32\xd5\x33\x56\x86\xee\xf1\x1e\x2b"
-  "\x07\x7f\x20\xc7\xca\xd0\xa6\xff\xbd\x58\x19\xf6\xa4\x0c\x2b\xd5"
-  "\xbd\xc4\xca\x66\x8a\x95\xc1\xfc\xb7\xd0\x27\x04\xfc\x28\x5c\xe8"
-  "\x01\x2b\x17\xf6\xd0\x17\xfe\xec\x09\x2b\xc3\x76\xcb\xb1\x32\xac"
-  "\x46\x8e\x95\x61\xaf\x4b\x58\x29\x5c\xbb\x29\x58\x19\x56\x74\x7b"
-  "\xb0\x32\x8c\xc6\x39\x30\x5c\x41\xac\x1c\xb2\xba\x67\xac\x0c\xdd"
-  "\xeb\x1e\x2b\xe1\x3c\xc5\xca\xd0\xbd\x12\x56\xd6\xf5\x80\x95\x43"
-  "\xe7\x7a\x81\x95\xc1\x14\x2b\xd5\x1e\xb0\x72\x21\xb4\x95\xa0\x17"
-  "\x54\xf7\x5c\x74\x43\xc0\xca\x30\x07\x56\xf6\x42\x3f\xbc\x93\xdf"
-  "\x50\x8f\xf3\x5f\xc4\x4a\x2e\x97\xf1\x4b\xc4\x4a\x7e\x90\x80\x95"
-  "\xf1\x36\x92\x72\x06\x30\xb2\xa6\x99\xc6\x37\xa1\xeb\x76\xe1\x97"
-  "\xfa\x3c\x62\xd1\x2f\x62\xf7\x43\x7b\x19\x4c\x25\x14\x9b\xe8\xfa"
-  "\xd3\xa9\x88\x55\x25\x90\x37\xdf\xc1\x3b\x29\x76\x9e\x11\xb0\x73"
-  "\x96\x80\x9d\xb3\xbf\x07\x76\xbe\x80\xb2\xbc\x6b\x69\xbb\x52\xc4"
-  "\xce\xcd\x80\x9d\x77\x51\xfe\x80\xdf\x32\x19\x76\xde\x73\x59\xac"
-  "\x17\xda\x2e\x0d\x89\xdb\x09\xab\xd7\xb5\xae\x38\xfa\x14\x2d\xef"
-  "\x84\x7e\x61\x0b\x71\x60\xe9\x2c\x09\x4b\xa1\xac\x9d\x9e\x71\xf4"
-  "\xae\x16\x07\x8e\x66\x02\x8e\x9e\x73\xc2\x51\xb4\x19\x20\xe6\x01"
-  "\x8e\xb6\x51\x1c\x3d\x2c\xe0\xe8\x30\xfb\xa9\x59\x80\xa3\x4f\x89"
-  "\x38\x3a\x2c\xdc\x9a\x99\x6f\xb5\x66\xf5\x8c\xa3\x6d\x14\x47\x75"
-  "\xb7\x1e\x47\xcb\x5c\x70\x14\xe6\xac\x18\xeb\xd8\x2d\x8e\x8a\xfa"
-  "\x48\x71\x34\x43\xc2\x51\xda\xae\x77\x6f\xab\x8a\x85\x76\x8f\xd5"
-  "\xd1\x79\x9b\x03\x47\x75\x25\x0c\x47\xe1\x1c\xfd\xc6\xbf\x0c\x70"
-  "\x14\xf4\x2f\xbd\x12\x7d\xfa\x91\x48\xa8\xa3\x1a\xf1\x75\x17\xf4"
-  "\x19\x6c\x23\x07\x9e\x2e\x84\x3e\x83\x18\xd3\x0a\x7d\x06\x70\x74"
-  "\xf6\x75\x35\xa1\xfd\x25\x0b\xfa\x4b\xb3\x87\x58\x6a\xe2\xba\x59"
-  "\x8f\x78\x7a\xf7\x77\x72\x3c\xbd\x67\x84\x1c\x4f\xef\x3e\x23\xe1"
-  "\xa9\x70\x0d\xf1\x14\x64\x06\xed\x93\x8d\x98\xda\x37\x3c\xbd\xdb"
-  "\xec\xc0\x53\xa5\x80\xa7\x0b\x7b\xc6\x53\xfa\xcd\xcf\x03\x9e\x3a"
-  "\x63\x83\x67\x3c\xbd\xdb\x2c\xe1\xe9\x3d\x95\x0e\x3c\x35\x7a\xc2"
-  "\xd3\xbb\x2c\xee\xf1\x14\xce\x53\x3c\xbd\xcb\xe2\xc0\x53\xa3\x1b"
-  "\x3c\x7d\xca\x19\x4f\xef\xfd\x90\xe1\x69\x09\xc5\x51\xc4\xd4\x2a"
-  "\x0b\xe8\x07\xf6\xb9\xc4\x7c\x8a\xa9\x1c\x60\x2a\x60\x81\x12\x63"
-  "\x2b\xe1\xba\x77\x77\x98\xca\x30\xd7\x44\x10\x57\xb1\x6f\xa6\x4f"
-  "\x83\xf9\x2e\x8c\x45\xd0\x26\x74\xec\x15\xdb\x6f\x97\x13\xbe\xce"
-  "\x59\xa9\x46\x6e\x27\xd3\x15\x4e\xd4\x95\x56\x2d\xae\x95\x95\xe9"
-  "\x8a\x77\xb2\xbc\xf7\x88\x27\x6c\xf5\x34\x77\x3f\x85\x73\xf7\x99"
-  "\x44\xb9\x6a\x26\xe0\x6b\x0c\xce\xdd\x8b\x5d\xe6\xee\xc5\x5d\xe7"
-  "\xee\xa7\xbb\xc7\x51\xaf\xe6\xee\xcf\xa1\x0c\x35\x87\xe4\x38\xaa"
-  "\xf9\x50\x8e\xa3\x23\x1e\xc6\x7a\x31\x1c\x2f\x76\x3f\x77\xa7\xfd"
-  "\x7c\xf8\x1d\x8e\xb9\xbb\x51\x8e\x9f\xd2\xdc\xfd\xe7\xdf\x78\xc6"
-  "\xd1\xe1\x13\x64\x7c\x74\xb6\x80\xa3\x2f\x0b\x38\xfa\xb2\x84\xa3"
-  "\x9f\x7d\x21\xf2\xd1\xfb\x9e\x39\x69\x74\xc6\xd1\xe1\xc9\x0e\x1c"
-  "\xad\xed\x8a\xa3\x22\x86\xd2\xd8\xf0\x50\x0e\xda\xb0\xf6\x02\x4e"
-  "\x1f\x78\x59\x47\x6d\x51\x68\x17\x44\x1b\xac\xc3\x06\xd5\x26\xe2"
-  "\xe9\x75\x92\x36\x0b\xf1\x34\x9f\xe2\x69\x20\xae\xc3\x58\x01\x78"
-  "\x2a\xc4\x8e\xdf\x99\x44\xc2\xb0\x2f\xa2\x7d\x89\x5b\xc1\x62\x3d"
-  "\x8a\x76\x26\x78\x5f\xfa\x9d\xfe\xa5\x3a\x01\x53\x31\x06\x76\x10"
-  "\x8d\x1f\xaf\xdd\x91\xe4\x86\x9b\xae\x02\x4c\x4d\x71\xe2\xa6\xd0"
-  "\xf7\x0f\xbf\xec\x8a\xa9\xf7\x35\x56\xa1\xae\x20\xa6\xca\xe6\xf1"
-  "\xc5\x3f\x82\x79\xfc\xcf\x1f\x95\x63\xe9\xcf\x75\x72\x2c\xfd\xf9"
-  "\x48\x09\x4b\x85\x6b\x37\x85\x9b\xfe\x7c\xe2\xed\xe1\xa6\x3f\x9f"
-  "\x28\xcd\xe3\x47\x0c\x71\x60\x69\x8d\x27\x2c\x1d\x3e\xd1\x3d\x96"
-  "\xc2\x79\x8a\xa5\xc3\x27\x3a\xb0\xb4\xc6\xcd\x3c\x5e\x86\xa5\x23"
-  "\xec\x0c\x4b\x8b\x19\x37\x35\x8a\xdc\xb4\xf8\x27\x38\x8f\x1f\x61"
-  "\xf3\x76\x1e\x7f\xaa\x85\xe1\x27\xe2\x93\x88\xa1\xd2\x3c\xbe\xd8"
-  "\xf3\x3c\xbe\x07\x0c\xf5\x8a\x8b\x52\x0c\x1d\x69\x97\x63\xe8\x28"
-  "\x85\x1c\x43\x47\x2f\x75\xc5\xd0\xae\xf8\x39\xea\x31\x77\xd8\xc9"
-  "\xe6\xf1\xa3\x35\x9e\x71\x73\x54\xbc\xf7\xb8\xf9\x8b\xd7\xe5\xb8"
-  "\x39\xaa\xe4\xff\x06\x6e\x6a\xef\x96\xe1\xa6\xba\x97\xb8\xf9\x83"
-  "\xcc\xe9\xb5\x2e\xf6\x4f\xad\x8b\xfd\x53\xeb\x64\xff\xd4\xde\x44"
-  "\xfb\xa7\xf6\x36\xd9\x3f\xb5\x89\x12\x07\x1d\xfd\x4c\xcf\xb8\x39"
-  "\x2a\xd1\x3d\x6e\xc2\x79\x8a\x9b\xa3\x12\x25\xdc\xec\x89\x83\xde"
-  "\xff\x90\x17\xb8\xf9\x23\x9f\xd3\xdf\xdf\xad\xfd\xd3\xdd\x9c\x1e"
-  "\x71\x93\xe2\xa5\xd1\x65\x4e\x3f\xd3\x79\x4e\x5f\x2c\xcd\xe9\xa7"
-  "\x30\xdc\x32\xd8\x72\xe5\x73\xfa\x9b\x8e\xa3\x0f\x4c\xb6\x3a\xec"
-  "\xa1\x6f\x00\x8e\x3e\x40\x63\x93\x59\x1d\xf6\xd0\x71\x95\x62\xbd"
-  "\xd8\x9c\x7e\x33\x61\xf5\x72\x33\xa7\xa7\xeb\x65\x1f\xd8\xe6\x98"
-  "\xd3\x1b\x5d\xe7\xf4\xe3\x56\x7b\xc6\xd4\x07\xf4\x6e\xe7\xf4\x38"
-  "\xff\xa6\x98\xaa\xa3\x98\x7a\x63\xab\x33\xa6\x8e\xa9\xa3\x98\xfa"
-  "\x84\x88\xa9\x63\x54\x56\xe8\x9b\x56\xbf\x9e\x31\x15\xcb\x91\x30"
-  "\x35\xee\x87\xc1\x54\x7d\xef\x31\xd5\x79\xdf\xe9\x61\x78\x77\x07"
-  "\xa6\xd2\x36\x1e\xbb\xb2\x2a\x16\x31\x35\xce\x65\x7e\x5f\xec\x7e"
-  "\x7e\x7f\x92\x28\xb1\x7d\xc4\xf9\x3d\xca\x80\xe2\xcd\x2d\x9d\xdf"
-  "\x8f\xfd\x5c\x8e\xad\xe3\x54\x72\x6c\x1d\x7b\x48\xc2\x56\xe1\xda"
-  "\x4d\x99\xdf\x8f\xad\xbe\x3d\xf3\xfb\xb1\xd5\x12\xb6\x8e\xdb\xd7"
-  "\x33\xb6\x3e\x50\xee\x1e\x5b\xe1\x3c\xc5\xd6\x07\xca\xbb\xc5\xd6"
-  "\x27\x9c\xb1\x75\xfc\x4e\x11\x5b\xa5\xf9\x3d\xe8\x07\xf6\xbf\xc4"
-  "\xdc\xbe\xcf\xef\x9f\xbc\xdd\xf3\xfb\xf1\x1e\xfd\xbf\xba\x9d\xdf"
-  "\x6f\x05\x9c\x85\xb9\xf8\xaa\xcf\x61\x7e\xff\x8c\x30\xbf\xaf\x2d"
-  "\x72\x99\xdf\x17\x75\x99\xdf\xa7\x3e\x23\x60\x2a\xf4\x29\x8a\xa9"
-  "\x2f\x17\xf7\x7d\x7e\xff\x2c\xca\x30\x7c\x9b\x1c\x53\xc3\x77\xca"
-  "\x31\x75\xc2\x58\xac\x17\xc3\xf4\x22\xf7\xf3\x7b\xda\xcf\xc3\xbf"
-  "\x91\xcd\xef\xa1\x7e\x5d\xe7\xf7\xbf\xaa\x93\x61\xea\x6c\x67\x4c"
-  "\x7d\x30\x58\xc6\x53\xe1\xbd\x10\x53\xdf\x39\xc7\x30\xf5\xdd\x73"
-  "\x4e\x98\xfa\xf4\xbb\x02\xa6\xfe\x72\xf2\xc9\x19\xce\x98\xfa\x60"
-  "\x8c\x88\xa9\x14\x2f\x67\x5b\x95\xe9\x31\x9e\xd7\x9b\xec\x85\xb2"
-  "\x71\x7f\x14\x96\xb9\xef\x5c\x5c\xcf\xeb\x4d\x62\xe4\xeb\x4d\x1c"
-  "\x6b\x4d\x12\x4d\xa4\xa2\x21\x97\xae\x35\x29\x48\x22\xc1\x81\x6b"
-  "\xc8\xf0\x82\x0e\xb6\xe7\x9f\xc6\xe1\xb8\xe1\x7e\xbf\xff\x4b\xcf"
-  "\x4b\x38\x8b\x7b\xfe\x01\x63\xb5\xdb\x6f\xb0\xb5\x3f\x20\xef\xae"
-  "\xfb\xfb\x45\xde\x04\x78\x70\xe8\x9c\x2b\xce\xfe\xf2\x4c\x15\xea"
-  "\xcf\xac\x38\x97\x39\x7f\xd1\x8f\x60\xce\xff\xab\x07\xe5\xf8\xfa"
-  "\xab\x79\x72\x7c\xfd\xd5\x10\x09\x5f\x85\x6b\x37\x85\xbb\xfe\x2a"
-  "\xfc\xf6\x70\xd7\x5f\x85\x4b\x73\xfe\x09\x03\x1c\xf8\x5a\xed\x84"
-  "\xaf\xe7\x9c\xf1\xf5\xc1\x61\x14\x5f\xcf\xb9\xe2\x2b\x9c\xa7\xf8"
-  "\xfa\xe0\x30\x07\xbe\x56\xbb\xcc\xf9\xcf\xb9\xe2\xeb\x84\xef\x28"
-  "\xbe\x82\x2e\xc8\xb9\x6b\x51\xcf\x73\xfe\xda\x1f\xdb\x9c\x7f\x82"
-  "\xd9\xab\x39\x3f\x62\x6a\x3c\xc3\x54\xc4\x2c\x11\x57\xa5\x39\x7f"
-  "\x91\xc7\x39\x7f\x4f\xb8\xea\x15\x57\xa5\xb8\xfa\xd0\x77\x72\x5c"
-  "\x7d\xe8\xba\x1c\x57\x1f\x5e\xe9\x8a\xab\x5d\x31\xf5\xd7\x0f\xb9"
-  "\xc3\x53\x36\xe7\x7f\x58\xeb\x19\x4b\x7f\x1d\xeb\x3d\x96\xfe\xbf"
-  "\x4d\x72\x2c\xfd\xf5\x9e\xff\xbb\x58\x1a\x31\x52\x86\xa5\xea\x5e"
-  "\x62\xe9\x0f\x62\x07\x88\x58\x2d\xc7\xd2\x88\x12\x39\x96\x46\xcc"
-  "\x97\xb0\x54\xb8\x76\x53\xb0\x34\x22\xf5\xf6\x60\x69\x44\xaa\xc4"
-  "\x55\x1f\x7e\xbe\x67\x2c\xfd\x75\x9c\x7b\x2c\x85\xf3\x14\x4b\x7f"
-  "\x1d\x27\x61\x69\x5d\x0f\x58\xfa\xc8\xa3\x5e\x60\xa9\xdc\x0e\xe0"
-  "\x8a\xa5\xb7\xdd\x0e\xf0\x88\xc7\xfd\x0f\x6e\xed\x00\x22\x96\x3e"
-  "\xd3\xd5\x0e\x80\xf8\x4a\xed\x00\xd0\x5e\x22\x86\x51\x3b\x40\x14"
-  "\xc3\x32\x83\x2d\x5b\x66\x07\xb8\xf9\xd8\xfa\x9b\x69\x56\x87\x3d"
-  "\x35\x13\xb0\xf5\x37\xcf\x50\x6c\x75\xd8\x53\x7f\xfb\x8d\x58\x2f"
-  "\x66\x07\x78\x83\xb0\x7a\xb9\xb1\x03\x3c\x4e\xcb\xdb\x2d\xb3\x03"
-  "\x38\x61\x2d\x94\xb5\xcd\x33\xce\xfe\xa6\x5c\x66\x07\xa8\x97\x70"
-  "\xf6\x06\xae\x49\x07\x1c\xa4\x38\x1b\xea\x8c\xb3\x13\xdb\x29\xce"
-  "\x3e\x2e\xe2\xec\xc4\x80\x36\xe8\x9b\x6d\xde\xe2\x2c\xae\x91\x3e"
-  "\x17\x7b\x7b\x70\xb6\xd4\x0b\x9c\x75\xb2\x0d\x1c\x82\xf6\x70\xe0"
-  "\x2c\x6d\xf7\x47\xb7\x54\xcd\x42\x9c\x8d\x75\xb1\x0d\x14\xb9\xb7"
-  "\x0d\x9c\xb8\x1d\xb6\x81\x47\x2f\xcb\xf1\xf6\xb7\x1a\x39\xde\x3e"
-  "\x7a\x5a\xc2\x5b\xe1\xda\x4d\xb1\x0d\x3c\xda\x72\x7b\x6c\x03\x8f"
-  "\xb6\x48\x78\xfb\xdb\x93\x3d\xe3\xed\x6f\xaa\xdd\xe3\x2d\x9c\xa7"
-  "\x78\xfb\x9b\xea\x6e\xf1\xf6\x71\x67\xbc\xfd\xdd\x21\x11\x6f\x25"
-  "\xdb\x40\x91\x60\x1b\xc8\xee\xd9\x36\x50\xeb\xc1\x36\x30\xf9\x76"
-  "\xdb\x06\x7e\xd7\xc5\x27\x61\x77\xb6\x81\xf6\xad\x6c\xdd\xfe\x2a"
-  "\x5c\xb7\xff\x12\xe0\x6f\xf4\x17\xd0\x06\x3d\xaf\xdb\x4f\x15\xd7"
-  "\x9f\xc6\xe6\x0b\x38\x9b\xef\xd6\x36\x70\xaa\xc9\xb3\x6d\xe0\x54"
-  "\x8d\xf3\xfa\xd3\xc8\x0f\xe4\xdf\xad\x22\x0f\x89\xdf\xad\x4e\x7d"
-  "\x85\x38\x1b\x75\x0c\xd3\x5c\xde\xb8\x5c\x8a\xff\x8a\x28\x3d\xd6"
-  "\xd3\xdd\x3a\xfe\xc3\x9c\xf3\xb7\xac\xc7\x42\x1c\xb6\x82\x6a\xc4"
-  "\xdb\x7c\xc2\xf1\x71\x7e\xe8\x17\x9c\xda\x0a\x9e\x43\xdd\x8b\x5a"
-  "\xea\x8c\xbb\x47\xcf\x3a\xe3\xee\x63\x91\x22\xee\xda\x01\x77\x3f"
-  "\xac\xcf\x67\xf6\xd7\x17\xd8\xda\xd4\xbd\x2f\x38\xad\x4d\xfd\xe2"
-  "\x63\x01\x77\x1f\x7f\xf4\xa4\x09\xde\xbf\xbb\xf5\x53\x70\xff\xfe"
-  "\xb3\xbd\x5d\x83\x9a\xef\x76\xed\x94\x80\x4f\x6e\xd7\x4f\x41\x5d"
-  "\xd5\x3b\x85\xbe\x6a\x87\x7e\xba\xd3\x69\xfd\x54\x41\x0a\xf4\x67"
-  "\x61\xef\x55\xb7\xeb\x50\x5f\x90\xd6\xa1\xf2\x79\x63\x2b\x70\x7c"
-  "\xe3\xb6\x8c\xcb\xed\xe0\xe3\x7c\xf8\xe0\xb1\x15\xf8\xfc\xce\x4e"
-  "\x18\x77\x26\xc5\xf8\xb0\x79\xdd\xd8\x12\xc0\x9e\x81\xac\xdd\x1f"
-  "\x4f\xb6\xc3\x58\x63\x87\xb1\x86\xcb\x1b\x5b\x62\x43\x6e\xb2\x75"
-  "\xec\xc1\x02\x98\xe7\xd9\x32\x69\x5c\xd5\xfe\x39\x30\xd7\xdb\x85"
-  "\xf3\xbc\x2b\xd0\x37\xd2\xb5\x4a\xac\x8f\x88\xa3\x81\x4d\xf0\x1e"
-  "\x57\xba\xe7\x72\xb6\xab\x12\x8e\xea\x9f\x3a\x05\xcf\x9c\xb4\xa8"
-  "\x0a\x75\x37\x46\xda\x53\x40\x39\xb3\x87\xb5\xb2\x58\x17\xe6\x2b"
-  "\x11\x74\xe1\x26\xd8\x24\x9c\xeb\x23\xc7\xf5\x49\x27\xe4\xb8\x3e"
-  "\xc9\x2a\xc7\xf5\x49\xfb\x24\x5c\x17\xae\x01\xae\xdb\x33\x19\x8f"
-  "\x86\xb1\xaf\x8f\x3c\x7a\x52\x99\x88\xeb\x9c\x80\xeb\x85\xbd\xc0"
-  "\xf5\x6e\x79\xb4\x13\x2e\x79\xc6\xf5\x49\x65\x92\x4d\x22\x6a\xb7"
-  "\xdb\x35\xb2\x67\x9d\x71\xfd\xb1\x29\x14\xd7\xcf\xba\xe2\x3a\x9c"
-  "\xa7\xb8\xfe\xd8\x14\x8f\xfb\x09\xce\xba\x7e\x4f\x9b\xfc\x1a\xc5"
-  "\x75\xa3\xb0\x46\xb6\xda\x8b\xfd\x04\x46\x86\xe9\x22\x96\xa3\xbd"
-  "\xea\xf6\xda\x24\x26\xaf\xf3\xc6\x26\x41\xb1\xbc\x85\x61\x39\x62"
-  "\xa3\x88\xe7\xbd\xd9\x4f\xd0\x13\x9e\x8b\xbc\x19\xf1\xdc\x13\x6f"
-  "\x96\xe3\xf9\x13\xaf\xc9\xf1\xfc\x89\xd7\xe5\x78\xfe\xd4\x6b\x72"
-  "\x3c\x7f\x6a\x9d\x2b\x9e\x77\xc5\xf2\x27\xce\xb8\xc3\x71\xdd\x73"
-  "\x68\xa3\x78\x6a\x82\x67\x0c\xff\x17\x95\xf7\x18\x3e\x45\xf1\x7f"
-  "\x0e\xc3\xd5\xae\x18\x3e\x65\x22\x62\x90\x3d\xcb\x05\xc3\x17\x0a"
-  "\x18\x2e\xe0\xc8\xae\x66\x81\x0b\xbb\x62\x78\x0b\xbc\x47\x0f\xf3"
-  "\x71\xdb\xb7\xae\x18\xfe\xe4\x83\x32\x0c\x57\xf7\x80\xe1\x0b\x99"
-  "\x1d\x44\xb6\x2e\xd7\x83\x2d\x04\xde\x23\x66\xa7\x07\x6e\x2e\xb6"
-  "\x99\x73\x7d\xe4\x18\xfe\xe4\xeb\x72\x0c\x7f\xf2\x88\x1c\xc3\x9f"
-  "\x5c\x2a\x61\xb8\x70\xed\xa6\x70\xf3\x27\xb3\x6f\x3a\x37\x17\xf5"
-  "\xa3\x5b\x0c\x7f\x32\x5b\xe2\xe6\x4f\xcd\xef\x19\xc3\xff\x25\xc0"
-  "\x3d\x86\xc3\x79\x8a\xe1\xff\x12\xe0\x71\x9f\x43\x17\x0c\xff\xfd"
-  "\x64\x2f\x30\x5c\x6e\x0b\x11\x31\x5c\xb0\x85\xec\x72\xb2\x85\xd8"
-  "\x33\x99\x2d\x64\x67\x33\xd3\x8d\x81\x0a\xa6\xa7\xa0\x3f\x61\x85"
-  "\xca\xee\xe7\x6e\x3b\xfb\x64\x07\xf9\x7d\x94\x37\x76\x10\x8a\xdf"
-  "\xb8\xc7\xe1\x79\xc0\xed\xea\x5e\xee\x71\x98\x22\xee\x71\xc8\xf5"
-  "\xb0\xc7\x41\xc0\xf3\xd9\xdf\x03\xcf\xe9\x1e\x87\xa9\x33\xe5\x36"
-  "\xe6\xa9\xcf\x8b\x36\x66\x86\xe7\xd1\x0b\xe4\x78\x1e\x1d\xe7\xd8"
-  "\xf3\x00\x98\x6f\xd0\x6d\xee\xb2\xe7\xc1\x81\xed\xd4\x0e\x3a\xf5"
-  "\x90\xfe\xb9\x06\xe2\xc0\xf7\x59\x12\xbe\x43\x59\x43\x64\xd8\x5e"
-  "\xef\x8c\xed\x53\x4d\x32\x6c\x3f\x97\x2f\x5f\x1f\x51\xaf\x73\xc2"
-  "\x76\x71\xcf\xc3\xb4\xba\x93\xb5\x3d\x60\x3b\xdc\xdf\xfb\x3d\x62"
-  "\x37\x17\xdb\xc5\xfd\x0d\x6e\xb1\xdd\x79\x7f\x83\xd3\xfa\x07\xc4"
-  "\x76\x1a\x83\x22\xc4\x05\xdb\x57\xc5\x29\xed\xc7\xa1\x3f\x00\xae"
-  "\x63\x1f\xb1\xf3\x80\xed\xb4\xbd\x9f\x0e\x73\xc6\xf6\xce\x4c\x86"
-  "\xed\x3b\x9a\xbf\x3f\xb6\x3b\xf8\xb0\x33\xb6\x3f\x81\xd8\x3e\x3d"
-  "\x84\xed\xbf\xc8\xe8\xdd\xfe\x0b\x97\xf5\x19\x3b\x7a\x61\x7f\xe9"
-  "\x16\xe3\xdd\xd4\x4b\x8e\xf1\xd3\x17\xc9\x31\x7e\x7a\x91\x1c\xe3"
-  "\xa7\xcf\x94\x30\x5e\xb8\x76\x53\x78\xfa\xf4\xf8\xdb\x63\x7f\x99"
-  "\x1e\x2f\x61\x7c\xf4\x93\x3d\xef\xbd\x98\xda\xe4\x7e\x6d\x06\x9c"
-  "\xa7\x18\x3f\xb5\xa9\xdb\xbd\x17\x32\x7b\xf7\x33\x0f\xbb\xdd\x7b"
-  "\x51\xfd\xc3\xad\xcd\x70\xd6\x15\x57\xfb\x4b\xdf\x6d\xdf\xcf\x44"
-  "\x78\x6b\x7f\xc1\xbd\x17\xab\x4e\x3b\xed\xbd\xa8\xed\x79\xef\x45"
-  "\xea\xcc\x5e\xda\x5f\xba\x59\x9b\x71\x2a\xda\x79\xbd\xdb\xb3\x0f"
-  "\xc9\xf1\xfd\xd9\x87\x1d\xf8\xfe\x2c\xe2\xfb\x73\xd3\xe4\xf8\xfe"
-  "\xdc\x54\xac\xa7\xbb\xbd\x18\x87\x65\xdf\x15\x9f\xdd\x22\x5f\xab"
-  "\xe1\x62\x7f\x79\x16\x75\x6f\xa6\x5d\x86\xef\xe7\x9c\xf1\xfd\x59"
-  "\xbd\x3b\xee\x8e\x76\x6f\xba\xa6\x78\xb6\xd3\x9e\xb6\xa7\xc5\xf5"
-  "\x6f\x7f\x38\x79\x32\x06\xde\xdf\xe4\x61\xad\xdb\x6c\xb6\xd6\x8d"
-  "\xae\x6d\x43\x3b\x38\x94\x75\x60\xb6\x4e\x99\x16\xcb\x73\xb8\xd6"
-  "\xcd\x75\x9d\x1b\xae\x7d\xc3\xb5\x6e\x95\x71\xb9\x1e\xd7\xb9\xa1"
-  "\x6e\x7a\x5a\xeb\x06\xf5\x0e\xa6\x58\x7f\x41\xc0\x7a\x61\xad\x5b"
-  "\x41\x92\xb4\xd6\x4d\x86\xf5\x6e\xd6\x0f\x1f\x3a\x97\xe1\x9e\xc7"
-  "\xa7\x4b\x58\xdf\x81\x3c\xfe\x37\x2e\xb6\x18\x2a\x83\x19\xaa\x1f"
-  "\xd4\x16\x43\xb1\x7e\x46\x7b\x15\xea\xf1\x2c\x9d\x1b\x5b\x4c\xd7"
-  "\x35\xce\x3f\x9c\x2d\x66\xe6\x33\x72\x8c\x9f\xb9\x4e\x8e\xf1\x33"
-  "\x1f\x96\x30\x5e\xb8\x76\x53\x30\x7e\x66\xf4\xed\xb1\xc5\xcc\x8c"
-  "\x96\x6c\x31\xcf\x8d\x75\xbb\xfe\x4e\x66\x63\x7f\xb6\xdc\xbd\x8d"
-  "\xfd\x59\x61\xfd\xdd\xb3\xe5\x1e\xf7\x84\x74\xf9\xa6\xf9\xc7\x20"
-  "\x66\x63\xef\xc3\x9e\x90\xda\x1f\x9b\x2d\xe6\x8f\x1e\xfd\x7f\x79"
-  "\xb2\xc5\xd0\xb5\xcd\xa7\x71\x7d\x88\x77\x7b\x42\x7a\xc2\x76\x07"
-  "\x77\xef\xe6\x1b\xa6\x1c\xdb\x63\x82\xe4\xd8\x1e\x13\x22\xc7\xf6"
-  "\x59\x77\xcb\xb1\x7d\xd6\x30\x57\x6c\xef\x8a\xeb\x31\xf3\xdd\x61"
-  "\xba\xee\x59\xb4\xc5\xbc\x58\xe1\x19\xcf\x63\x72\xbd\xc7\xf3\xe7"
-  "\xb7\xfd\x9f\xc6\x73\xb5\x2b\x9e\x3f\x5f\xf3\x83\xda\x65\x28\x9e"
-  "\xbf\x70\x52\x86\xe7\xea\x1e\xf0\xfc\x07\xb3\xcb\xbc\x38\x5c\x8e"
-  "\xe7\x2f\xce\x90\xe3\xf9\x8b\x77\x48\x78\x2e\x5c\xbb\x29\x76\x99"
-  "\x17\x35\xb7\xc7\x2e\xf3\xa2\x46\xe2\xec\x2f\xda\x7b\xc6\xf3\x98"
-  "\x7c\xf7\x78\x0e\xe7\x29\x9e\xc7\xe4\x7b\x5c\x4f\xdd\x05\xcf\x67"
-  "\xd5\x79\x81\xe7\x6e\xd7\xa8\xfc\x38\xec\x32\xb3\x6a\xbd\xb5\xcb"
-  "\x78\xda\xa7\x82\xf8\x2e\xad\x4f\x71\xda\xa7\x12\x29\xee\x53\xc9"
-  "\x90\xaf\x4f\xb9\xe9\xd8\xfe\xd2\x65\x39\xb6\xbf\xf4\x9d\x1c\xdb"
-  "\x5f\x1e\x20\xc7\xf6\x97\x03\xc4\x7a\x32\xbb\x4c\x66\x97\x7d\x2b"
-  "\x72\x9c\x9f\xfd\x8c\xfe\xd9\x06\xe2\x0e\xeb\x2f\x29\xe6\x7e\xe8"
-  "\x19\xe7\x67\x27\x7b\xc2\x79\x5c\xaf\xf2\xde\xec\x38\x37\x38\x3f"
-  "\x67\xcd\xff\x06\x9c\xf7\xb4\x0e\x85\xce\x83\x00\xe3\x11\xef\x29"
-  "\xbe\x0b\x58\x8f\x38\x6f\xff\x9b\x3b\x1b\xcd\x9c\x23\xb7\x0a\xe7"
-  "\x3d\xdb\x68\x62\x0f\x55\xcd\x12\x70\xbe\x37\x7b\x68\x8e\xc9\x6d"
-  "\x34\x05\x0b\x6f\xb5\x8d\x66\x6e\x90\x1c\xef\xe7\x46\xc9\xf1\x3e"
-  "\xb6\x5d\xc2\x7b\xe1\xda\x4d\xe1\xef\x73\xd5\xb7\xc7\x46\x33\x57"
-  "\x2d\xe1\xfd\xdc\xcb\x3d\xe3\xfd\xec\x0c\xf7\x78\x3f\x5b\xf0\xcd"
-  "\x36\x3b\xa3\xf7\x78\xff\xb2\x03\xef\xbb\xee\x9f\xc9\xe8\xfb\x1a"
-  "\x99\xc7\x6e\xb7\x8d\xe6\x65\x8f\xf8\xdf\x9d\x7f\x8c\xbe\xdb\x68"
-  "\x84\x3d\x89\x2f\xbb\xf7\x8f\x71\xb2\x9b\x35\x32\x27\x2b\x9c\xb1"
-  "\xfe\x95\x33\xf2\xb5\x88\xaf\xd4\x89\x6b\x11\x4f\x56\x21\xd6\xc7"
-  "\xf9\xca\xb1\x3e\x4e\xe5\xc9\x46\x73\x88\x73\x5e\x93\x38\xef\x61"
-  "\xb9\x8d\xa6\x48\x6e\xa3\x79\x1a\x75\xef\x4f\x1f\x78\xc6\xfa\x79"
-  "\xf3\xe4\x6b\xc0\xd9\x1e\xc5\x77\x66\x0b\x6b\xc0\x67\x3b\xad\x01"
-  "\x7f\xea\xdf\x05\xac\x9f\xbf\xa6\xbc\xda\x46\xbc\x59\x87\xf8\xfd"
-  "\xd7\x7a\x67\xbb\x5d\x83\x48\xc7\x80\x6e\xd6\x21\xce\x39\xa3\x26"
-  "\x9c\x72\x1b\xda\xdf\xa5\x75\x88\x80\xff\xdb\x95\x2e\xfe\x8b\xdd"
-  "\xad\x43\x9c\xad\xf3\x88\xff\xed\xbc\x84\xff\xdc\xff\x93\xec\x36"
-  "\x1c\xf2\x7c\x2a\x97\xf9\x47\x6e\x95\xdd\xc6\x9d\x9d\x44\xff\x38"
-  "\xe2\xff\xab\xef\x33\x9e\x1f\xf7\x23\xb3\xdb\xfc\xe9\x0e\x39\xee"
-  "\xff\x69\xa2\x1c\xf7\x5f\xfd\x4e\xc2\x7d\xe1\xda\x4d\x59\x8b\xfe"
-  "\x27\xff\xdb\xc3\xf3\xff\xe4\x2f\xd9\x6d\xfe\xd4\xd8\x33\xee\xcf"
-  "\x8b\x77\x8f\xfb\xf3\xe2\x19\xee\xcf\x8b\xef\xd6\x6e\x23\x5b\x1b"
-  "\x19\x77\xf2\x7b\xdb\x6d\x44\x9e\x7f\xdb\xf7\xf5\xc4\x95\x7b\x63"
-  "\xb7\x71\xec\x49\xff\x5e\x76\x1b\xf7\x78\x2f\x72\xfb\x93\xdd\x7c"
-  "\x73\x95\xe3\xfd\x82\x93\x72\xbc\x5f\x50\x29\xc7\xfb\x45\xdf\xc8"
-  "\xf1\x7e\x51\x93\x3b\xbb\x8d\x1c\xeb\x17\xde\xed\x0e\xe7\x75\x4f"
-  "\xa3\xdd\x66\x51\xbe\x67\x8c\x5f\x38\xc5\x7b\x8c\xff\xf3\xfc\x7f"
-  "\x62\xbc\x0b\xc6\xab\x5d\x31\xfe\xcf\x45\x3f\x28\xc7\xa7\x18\x1f"
-  "\xbf\x45\x86\xf1\x37\xd1\x96\xd3\x9b\xfd\x24\x9e\xb9\x7d\xbc\xcb"
-  "\xfa\xf7\x45\x1a\x39\xc6\xc7\x3b\xad\x7f\x17\xae\xdd\x14\x8c\x8f"
-  "\xbf\xf9\xeb\xdf\x7b\x85\xf1\xf1\x4e\xeb\xdf\x17\x9d\xec\x19\xe3"
-  "\x17\x46\xbb\xc7\x78\x38\x4f\x31\x7e\x61\x74\xb7\xdc\x5e\x86\xf1"
-  "\x8b\xf7\xdd\x0a\x5b\xce\xed\xd9\x6f\xb4\x78\xaf\x37\xf6\x9c\xee"
-  "\xfc\x8e\x78\xb4\xe7\x44\x88\xf6\x1c\x9d\x07\x7b\xce\xcd\xc2\xfc"
-  "\x25\x1f\xca\x31\x7f\xc9\x31\x39\xe6\x2f\xfb\x4e\x8e\xf9\xcb\xcc"
-  "\x72\x7b\x4e\x42\x17\x7b\x8e\x1c\xff\x75\xc3\xf5\x4f\x3b\xdb\x73"
-  "\x8a\x9c\xec\x39\xcb\x76\x7b\xc6\x7f\x9d\x47\xfc\xbf\x41\xf1\x3f"
-  "\xd6\x0d\xfe\x2f\xfd\x3f\x82\xff\xb1\xdf\x03\xff\x97\xde\x06\xfc"
-  "\x4f\xd8\xc9\x6c\x3c\xbd\xf4\x93\x72\xc8\x7b\x1b\xcf\xf7\x1b\x07"
-  "\x12\xae\xcb\xc7\x01\x78\x21\xd9\x38\x90\x50\x27\x8d\x03\xc2\xb5"
-  "\x9b\x32\x0e\x24\x58\x6e\xcf\x38\x90\x60\x91\xc6\x81\x65\x9f\xf7"
-  "\x3c\x0e\xe8\x3c\x8c\x03\x3a\x61\x1c\xd0\x79\x31\x0e\x24\x1e\xf3"
-  "\x6c\xe3\xd1\xf5\xdd\xc6\xf3\xf0\xed\xde\x07\x95\xa8\xf7\xca\xc6"
-  "\xb3\x75\xbc\xae\x02\x7d\xa4\x5c\x20\xca\x55\x73\x45\x1b\x8f\xde"
-  "\xc5\xc6\xa3\xef\x62\xe3\x59\x79\x41\xc0\xff\xa9\xc2\x7e\xd3\xa7"
-  "\xbf\x87\x8f\x14\x8c\x9f\xac\x58\xfe\xa1\x7c\xdd\xfc\x72\x8a\xff"
-  "\x92\xff\xbe\x95\xd3\xb0\x5e\x6c\xfc\xd1\x77\xe3\x03\x35\x69\x80"
-  "\xcc\xa6\x33\xd5\x9d\x8f\x94\x64\xd9\xba\x1b\xf9\x7e\xd3\xa4\x08"
-  "\x19\xde\x3f\xcd\xf6\x9b\xbe\xeb\xee\x3b\xad\xc3\x27\xff\x8a\x27"
-  "\xa9\x4f\x7e\x87\x2f\xbf\xa4\xd4\x5e\xf9\x92\x9e\x2d\xf8\x92\x3e"
-  "\x77\x1b\x7c\x49\xf7\xd6\x27\xff\x39\x57\xff\x7d\x2b\x1a\x0d\x15"
-  "\x7a\x52\x85\x3a\x32\xcb\xd5\xf7\xa9\xde\xfd\xde\x7d\xa5\xb0\x77"
-  "\x7f\xf1\xad\xf1\x83\x82\xf5\xa1\x63\xfe\xa0\x15\x19\xfb\xd2\xcc"
-  "\xb4\x3e\x18\xab\x1a\xe4\xbc\xa0\x02\x74\x95\x43\x3c\x4d\x40\x3c"
-  "\x4d\x2e\xa0\x79\x2f\x80\x2e\x0c\xea\x97\x8f\x7a\x9c\xc3\x91\x00"
-  "\x5d\x12\x62\x6b\x32\x5d\xf7\x05\x34\x02\xb0\x95\xe5\x5b\x7d\x81"
-  "\xb7\xdb\x07\x05\xe6\x43\xfd\xfb\xed\x5f\x5c\xed\x5b\x65\xb2\x40"
-  "\xbf\x68\xc6\x3d\xb1\x0a\x83\xad\x4d\x8f\xb2\x38\xba\xb8\x1a\x30"
-  "\x33\xdf\xba\xeb\x55\xe2\xef\x5d\x3f\x4d\x8e\xa3\x7c\x06\xc7\xbd"
-  "\x41\x2b\xd6\xa3\x1f\x10\x91\x5b\x71\x57\x25\xfb\xd6\x4e\x68\x1f"
-  "\x8e\x67\x63\xdf\x9c\x05\x0c\x37\x78\x18\xaf\xa1\x2d\xe9\x1a\x5b"
-  "\xc4\x0d\x1a\xbb\x0a\x70\xa3\xf0\x9a\xf4\x1d\x1b\xcb\xc7\x36\x62"
-  "\x76\x94\x95\xd2\xfa\x17\x93\x27\x6c\x4d\x8a\x74\x8f\xad\x49\x91"
-  "\x0c\x5b\x93\x22\x1d\xd8\x6a\x72\x63\x47\x91\xad\x63\x4f\x11\xd6"
-  "\xbf\xe8\x5d\x38\xb6\xfe\x27\xe8\x1f\x25\xc5\xab\xf5\x2f\x14\x4f"
-  "\xe3\x19\x9e\x22\x5e\x89\x98\x2a\xd9\x51\xf4\x1e\xed\x28\x3d\x61"
-  "\xaa\x57\x7b\xf8\x29\xa6\xae\x0a\x92\x63\xea\xaa\x10\x39\xa6\xa6"
-  "\x6d\x71\xc5\xd4\xae\x78\xba\x6a\xa6\x3b\x2c\x65\xfe\x51\xd2\xa2"
-  "\x3c\xe3\xe8\xaa\x0c\x4f\x38\x4a\xd7\xa7\xcf\x76\x5a\x9f\xee\xc0"
-  "\xd1\xd4\x4d\x72\x1c\x5d\x55\xd6\x5b\x1c\xa5\xb1\x4d\xce\xfd\x00"
-  "\xb1\x4d\xfa\x8c\xa3\x3a\x17\x1c\x5d\x3d\x56\xc2\x51\xd7\xf8\x26"
-  "\x3d\xe0\xe8\xc2\x5b\xe3\x03\x45\x86\xa3\x9c\x99\xd6\x47\xb3\x98"
-  "\xd6\xf5\x7d\x39\x8e\xae\x6e\xf0\x8c\xa3\xab\xd7\x48\x38\xca\xf2"
-  "\xdd\x5a\x1c\x5d\x5d\x22\xc3\xd1\x85\x4e\x38\xfa\xad\x34\x87\xc0"
-  "\x35\x16\x0e\x1c\x5d\xe4\x84\xa3\x0b\x7b\xc2\xd1\xd5\xb4\x8d\x18"
-  "\x47\x4d\x5b\xde\x33\x8e\xae\xca\x76\x8f\xa3\xab\xb2\x19\x8e\xae"
-  "\xca\x96\x70\xd4\x0d\x47\x95\xe1\x68\xfa\xf3\x5e\xe0\xe8\x8f\xdc"
-  "\x37\x0a\x4c\x54\xbc\xf4\x8d\x22\xec\xe9\xec\xea\x23\xf5\x25\xe7"
-  "\x3d\x41\xa5\x2e\x71\x4f\x4a\xbb\xc4\x3d\x59\x29\xee\xf1\x9c\x22"
-  "\xe0\xea\x53\xdf\x03\x57\xe9\x1e\xcf\x8c\x05\xf2\xb5\x27\x19\x8b"
-  "\xc4\xb5\x27\x0c\x57\xd7\x29\xc4\x7a\x49\x71\x4f\x4a\xbb\xf1\x91"
-  "\x9a\xf1\xa1\xcc\x37\xca\x14\x67\xdf\x28\x6b\xdf\xf7\xec\x23\x35"
-  "\xa3\x41\xe6\x1b\xe5\x54\xb1\x23\xee\x89\xab\x8f\x54\x09\x63\xd7"
-  "\x5c\xa7\x18\xeb\xf0\x41\xb5\x46\xeb\xf0\x91\xda\xc3\xbe\x20\x2c"
-  "\x67\x7f\x7d\xdc\xad\xc7\x58\xbd\x17\x18\x2b\x8b\x7b\xe2\xea\x63"
-  "\x2a\x73\x9b\xa1\xbc\x94\x54\xc5\x96\xba\xf1\x8d\x5a\x7a\x5b\x63"
-  "\x9f\x60\xbd\xdc\x63\xed\xda\xbb\xe5\x58\xbb\x36\x9a\xe6\xad\x73"
-  "\x87\xb5\x99\x97\x25\xac\x65\xf9\x56\xd7\xb9\x60\x6d\xad\x07\xac"
-  "\x85\x71\x75\xd7\x25\x6f\xb1\x76\x2d\x8d\x9b\xcd\x65\x0a\x58\xdb"
-  "\x7c\xb3\xb1\x76\xed\x30\x09\x6b\xd7\x5e\xe8\x39\xc6\x54\x46\x8b"
-  "\xfb\x7d\x39\x19\x2d\x0c\x6b\x33\x5a\xba\x8d\x31\x25\x5b\xf3\xb1"
-  "\xee\x73\x31\xc6\x94\x64\x0f\x28\x15\xec\x01\x3f\xe5\x98\x28\xeb"
-  "\xaa\xbd\xb5\x07\x7c\x06\x73\x77\xdc\x77\xb9\x0a\x63\x4e\xcd\xc2"
-  "\x98\x28\x25\x2e\xf6\x80\x92\xae\xf6\x80\xe7\xbb\xc7\x58\xaf\xec"
-  "\x01\x74\xdf\xe5\x6b\x95\x72\x8c\x7d\xed\x73\x39\xc6\xbe\xbe\x40"
-  "\xdc\x67\x89\xf5\xf1\xec\x33\x35\xeb\x6e\x87\x3d\xa0\x56\x8e\xad"
-  "\x92\x3d\xe0\xf5\x21\x9e\x31\x36\x4b\x6e\xff\x7d\xaa\x58\xb6\xcf"
-  "\xf2\xdd\x7a\x67\x3f\xd4\xa2\xff\xa9\x7f\x9d\x7f\xb2\xc6\x19\x63"
-  "\xb3\xd6\xff\x94\xfc\x50\x3b\x7c\x4d\xf5\xb0\x96\xbb\xab\x1f\xea"
-  "\x6c\xc0\xb5\x12\x82\x7b\xdb\x28\xde\xca\x6c\x03\x25\xb7\xc7\x36"
-  "\x50\x5e\xe2\xc1\x36\x90\xfd\x9a\x1c\x67\xb3\x4b\x69\xde\x33\xee"
-  "\x70\x36\x7b\xa6\x84\xb3\x2c\xdf\xea\x33\x2e\x38\x6b\xbc\x99\x9c"
-  "\x36\x7b\xdd\xad\xb5\x0d\x64\xaf\x93\x6c\x03\xaf\xf7\x62\xff\x63"
-  "\x56\xb4\x7b\x9c\xcd\x12\xec\xae\x59\x92\xdd\xd5\xe8\x26\x5e\x8a"
-  "\x0c\x67\xdf\x18\x2b\xee\x7f\xa4\x9c\xb6\x56\xe4\xb4\x25\x3f\xc1"
-  "\x78\x29\x6f\x8c\xf1\xd6\x36\x80\xfb\xdc\x11\x5b\x11\xbb\x44\x7c"
-  "\x95\x6c\x03\x25\x9e\x6d\x03\x3d\xe0\xab\xf7\xb1\xfb\xde\x1c\x2b"
-  "\xc7\xd7\x37\x1f\x94\xe3\x6b\xce\x87\xae\xf8\xda\x15\x5b\xdf\x5c"
-  "\xea\x0e\x57\x99\x6d\x20\x27\xde\x33\xa6\xbe\x59\xe0\x09\x53\xa9"
-  "\x4f\xbf\x7a\x69\x8d\xb4\x84\xa9\xeb\x0f\xc9\x31\xf5\x4d\x53\x6f"
-  "\x31\xf5\xb6\xc4\x4b\xe9\x33\xa6\xc6\xb9\x60\xea\x86\x99\x12\xa6"
-  "\xba\xc6\x4c\xe9\x01\x53\x6f\x95\x9d\xc0\x19\x53\x65\xdc\x75\xc3"
-  "\x19\x39\xa6\xe6\x04\x78\xc6\xd4\x0d\xef\x48\x98\xca\xf2\xdd\x5a"
-  "\x4c\xdd\x60\xbc\xb5\x76\x82\x0d\x46\x89\xbb\xe6\xec\xec\x19\x53"
-  "\xdf\xdc\xe3\x1e\x53\xdf\xdc\xc3\x30\xf5\xcd\x3d\xbd\xdf\x53\xbe"
-  "\x71\x8d\x17\x98\xfa\x23\x8f\xa5\xb2\x31\xc3\x6b\x3b\x01\xda\x5b"
-  "\x11\x4b\x6b\xbf\x9f\xef\x90\x64\xd1\x77\x48\x94\x80\xb1\x4f\x7c"
-  "\x5f\x8c\xcd\xdd\x24\x5f\xd3\x90\xbb\x45\x5c\xd3\xc0\x30\x36\xef"
-  "\x21\x79\x7c\xd4\xae\xbe\x42\xe4\x3e\x54\x73\x1b\x1d\x76\x02\xc4"
-  "\xdc\x28\x67\x3b\xc1\x5b\x8d\x9e\xf1\x76\x53\x80\xcc\x4e\xf0\x89"
-  "\x7b\xbc\xbd\x21\xc3\xdb\xcd\xa3\x29\xde\x3a\x7c\xa8\x6e\x8a\x16"
-  "\x7d\xa8\xf6\xc8\x61\x65\x78\x1b\xfb\xc3\xe0\x6d\x69\xef\xf1\x56"
-  "\x1e\x4b\xc5\xd5\x5f\xea\xe6\x4a\x43\x19\xe0\x2d\xf5\xd7\xe1\xea"
-  "\x33\xb5\x77\xfe\x3a\x6e\x95\xcf\x54\xac\x97\x7b\xdc\x7d\xeb\x19"
-  "\x39\xee\xbe\xb5\x8e\xe6\x75\x8b\xbb\x6f\x0d\x97\x70\x97\xe5\xeb"
-  "\x35\xee\xf6\xc9\x66\xf0\x56\xf4\xad\xb5\x19\xbc\x15\x2d\xe1\x6e"
-  "\x5e\x48\xcf\xb8\xbb\x29\xd8\x3d\xee\x6e\x0a\x66\xb8\xbb\x29\xb8"
-  "\x5b\xdc\x95\xad\x21\xd8\xe2\xeb\xd6\x97\x47\xed\x4f\x3d\xce\xca"
-  "\x16\x55\x5f\x6c\x06\x80\xc1\xca\x54\xf4\xe1\x14\x8b\x6b\x08\x7a"
-  "\xb6\x19\xf4\x84\xb7\xde\xdb\x0c\xb6\x2a\xe4\x78\xbb\xd5\x57\x8e"
-  "\xb7\xdb\xde\xc7\x7a\x75\x6b\x33\xa0\x18\xb0\xf5\x19\x87\xcd\xc0"
-  "\x24\xc7\x59\xc9\x66\xb0\x6d\xae\xe7\x6f\x5f\x5b\x53\x65\xfc\xf6"
-  "\x09\x17\x9f\xd5\xb3\x25\xbc\x3d\x55\x25\xae\x19\xfb\xb7\x7d\x27"
-  "\xa3\x9d\xf1\x76\xab\xbe\x8b\xcf\xea\x19\x37\xd1\x67\xf5\x8c\x9b"
-  "\xec\xb3\x7a\xa6\xdc\x67\xf5\xf6\x1b\xd2\x3a\x32\xef\x7d\x56\xe7"
-  "\x3f\x49\x31\x18\x75\x08\xfd\x56\xf7\xc6\x8e\x70\x8b\x63\xad\xc8"
-  "\xb0\x57\x66\x47\xc8\xaf\x94\x63\xef\x36\xe2\x19\x7b\xf3\x77\x4a"
-  "\xd8\xcb\xf2\xdd\x5a\xce\x9b\x5f\x71\x6b\xed\x08\xf9\x15\x92\x1d"
-  "\x61\xdb\x26\xb7\xd8\x2b\xfb\x36\xb6\x75\x9d\xfb\x6f\x63\x70\x9e"
-  "\x62\xef\xd6\x75\x1e\xed\x08\x5d\xd6\x6f\x6d\x5f\xce\xbe\x8d\x09"
-  "\x9c\xd7\xe4\x85\x1d\xe1\x47\xb7\xc6\x60\x7b\x62\x5f\xec\x08\x88"
-  "\xb7\x88\x67\x22\xe6\xf6\xc6\x8e\x70\xf3\x39\xee\x8e\xe5\x72\xcc"
-  "\xdd\xb1\x52\x8e\xb9\xbb\x86\xb8\x62\x6e\x57\xbc\xdd\x71\xc8\x1d"
-  "\xd6\x32\x3b\x42\x61\xb9\x67\x9c\xdd\xd1\xe0\x11\x67\x5d\xd6\xe6"
-  "\x4a\x38\xbb\x33\x44\x8e\xb3\x05\xda\x3e\xe1\x6c\x6f\x63\xb0\xfc"
-  "\xa8\x70\x36\xd6\x05\x67\x77\xbe\x2f\xe1\xac\x6b\x1c\x96\x1e\x70"
-  "\xf6\x16\xc5\x61\xf1\xcc\x71\x0b\x1f\x92\xe3\x6c\x61\x9c\x67\x9c"
-  "\x2d\xf4\x95\x70\x96\xe5\xbb\xb5\x38\x5b\x38\xe1\xd6\xda\x16\x0a"
-  "\x27\x48\x1c\xb7\xb0\xbd\x67\x9c\xdd\xd1\xe2\x1e\x67\x77\x08\xdf"
-  "\xc5\x76\xb4\x78\xe4\xb8\x5d\x70\x76\x57\x9d\x17\x38\xfb\x23\x5f"
-  "\x83\xb0\xcb\x2b\xff\x17\x4e\xf6\x5a\x3f\x83\xc9\x65\xbf\xc4\x19"
-  "\xe7\xfd\x12\x4e\xb6\x85\x28\xd1\xb6\x20\x8f\xcf\x92\x2c\xda\x6f"
-  "\x23\x05\xdc\x7d\xfc\xfb\xe2\x6e\xd1\xe5\x36\x07\xee\x26\x00\xee"
-  "\x16\xd1\xfd\x11\x6d\x0e\xdc\xdd\xf3\xb6\x58\x2f\x29\x3e\x8b\x07"
-  "\xdb\xc2\x23\x58\xde\xee\xc7\x1c\xb6\x05\xc4\xe1\x48\x67\xdb\xc2"
-  "\x9e\x99\x9e\x31\x78\x77\x9c\xcc\xb6\xf0\xb1\x7b\x0c\xb6\xc8\x30"
-  "\xf8\xdf\xb7\x51\x0c\x7e\x44\xc4\xe0\xdd\x7b\x6f\xc0\xdc\xf2\x46"
-  "\x96\x77\x18\x6c\xa1\x18\x3c\xe5\xf6\x60\xf0\xc1\x9b\x80\xc1\xb4"
-  "\xdd\xff\xf2\xa8\x41\x0f\x18\x3c\x0b\x31\x78\x4a\xef\xec\x0d\x3f"
-  "\x50\x8c\x16\xac\x97\x7b\x2c\xfe\xcb\x31\x39\x16\xff\xc5\x42\xf3"
-  "\xba\xc5\xe2\xbf\x6c\x92\xb0\x98\xe5\xbb\xb5\xf6\x86\xbf\xe8\x6f"
-  "\xad\xbd\xe1\x2f\x7a\x09\x8b\xf7\xbc\xd6\x33\x16\xef\xd6\xb9\xc7"
-  "\x62\x38\x4f\xb1\x78\xb7\xae\x5b\x2c\x7e\xc4\x19\x8b\xdf\x76\x70"
-  "\x5e\x99\xbd\xc1\xf4\x53\x8f\xdd\xf2\xb6\x47\xfe\xab\xb9\x87\x64"
-  "\xd4\x2b\xde\xae\x34\x14\x10\xd2\x9a\x49\x32\x0c\xb6\x47\x08\x9c"
-  "\x83\xf6\x7b\xfb\xba\x21\x2c\x82\x70\x9b\x07\x1b\x11\x8f\xdf\xc2"
-  "\x1f\x70\xdc\x5c\xa5\xd0\xb7\x68\x1b\xff\x95\xae\x77\xc5\xf3\x88"
-  "\xbd\xbb\x9c\xae\xbb\x7b\x16\x9f\x3b\x78\x86\x70\x5f\x34\xdb\x77"
-  "\x33\x38\x46\x4c\xa3\x6e\x9a\x14\x7f\x9d\xc1\x6f\x1a\x1c\x6d\x0e"
-  "\x1a\x1c\xed\xee\xfe\xfb\xd4\xc4\x7f\xe0\x1a\x9e\x2f\xdc\xca\x5b"
-  "\x5a\x47\xf9\xc7\xb6\xbe\x41\x48\xee\x56\xde\xdc\x96\xf5\xd7\xf5"
-  "\xf0\x8e\x07\xff\x0d\xf2\xb5\x0e\x5a\x1f\xdb\x9a\x19\x4d\xe0\x5c"
-  "\x91\x78\x0e\xda\x8d\x70\x99\x3e\x3c\x07\xd7\xf8\xcd\xb5\x53\x77"
-  "\xa5\x01\x56\xa5\x12\x32\xee\x06\xf6\x99\xbf\x96\x80\xce\x04\xe7"
-  "\x40\x99\x1b\xa1\x2c\x7e\xf0\x5d\x16\xd0\x47\x55\xd5\x3a\x82\x7d"
-  "\x3a\x1b\xde\xab\x28\x07\xdb\xde\xe7\x7e\xe8\x4f\x2a\xc2\xbd\xdd"
-  "\xaf\x94\x0f\x09\xd7\x81\x3c\x48\x6e\x02\xa1\x7b\xf8\x37\x42\x3e"
-  "\x5e\x99\xce\x73\x23\xfd\x22\x0d\x36\x0b\xeb\xd3\x50\xbf\xa3\x30"
-  "\x8f\xe5\xe1\xb9\x85\x09\x44\x0d\xbf\x00\x7e\x4b\xb8\xae\x2d\xeb"
-  "\x3f\x22\xe0\x3d\x35\x58\x2f\x4f\xef\xb8\x71\x3b\x8c\x3b\x77\x85"
-  "\xe1\xd8\x41\x9f\x8f\xcf\xa6\xcf\x51\x72\xd9\x76\x38\xcf\x67\xa6"
-  "\xf3\x86\x64\x1b\x09\x84\xb6\xd8\x05\xf5\x46\x7d\xe4\xfe\xea\x1f"
-  "\xbb\x76\x28\x21\xfb\x53\x9a\x94\x06\xa8\xbb\xfd\xdf\xee\xb2\xe8"
-  "\xd3\x7e\x49\xe0\xba\x19\xe7\x2c\x97\x14\xc5\x0f\x4d\xff\x86\x10"
-  "\xc4\x13\xf8\xff\x98\x05\xc6\xb1\x69\x90\xde\x08\xef\xc1\xb5\x86"
-  "\xa9\x30\xef\x25\xc5\x7f\x5c\xd6\x27\x9d\x25\x81\x3a\xe2\x9f\x03"
-  "\xef\xc6\xf2\xfe\xc7\x11\xcc\x6b\x52\x14\x47\x62\x1d\x20\x5d\x0d"
-  "\x69\xbc\x0f\xd7\x90\x11\x7e\x4f\xbf\x52\xaa\x9b\x79\xe1\x3a\x6e"
-  "\x64\xbf\x52\x8a\x7d\xf0\x9e\x1b\xe1\x9d\x21\x4f\x00\xe4\x09\xa0"
-  "\xc7\x34\xa2\xce\x83\x73\x58\x0e\x1c\x03\xf4\x8b\x3b\xb0\xec\xbd"
-  "\x58\xb6\x87\x76\x50\xf1\xc1\xe1\x30\x76\xab\xe8\x98\xaa\x49\x53"
-  "\x7c\x5e\xaf\x28\x36\x05\x2a\x78\x9e\xdf\xe3\x17\xb9\x36\x8d\x04"
-  "\xe4\x72\x84\xe8\x87\x62\x39\xc5\x87\xa0\x7c\x15\xb6\x45\x5b\x56"
-  "\x71\xbe\x49\xf1\x1f\x51\xd8\xbe\x20\x4f\x8b\xe6\x3e\xfa\xbe\x66"
-  "\x7c\x0e\xde\x23\xe4\xa7\xbe\xef\xb1\xce\x9a\x34\x1f\x1e\xd2\x67"
-  "\x7c\x14\x17\x88\x4f\x58\xc0\x0b\x70\xbf\xd1\x44\xe6\xeb\xf0\x7e"
-  "\x13\xbb\x0f\x74\xa9\xb8\x05\x64\x16\x8b\xe7\x30\xed\xa1\xbe\x01"
-  "\xa2\xdc\x2a\xc3\x40\x37\x5c\x65\x27\xea\x08\xe8\x85\xa8\x23\x58"
-  "\xdf\x03\x69\x26\x25\x1d\x87\x15\xef\xd0\x79\x5d\x0e\xc8\xd0\xbe"
-  "\x23\x4c\xb5\x11\xda\x96\xeb\x44\xb9\xd4\xc3\xb5\x77\x1f\x44\xb9"
-  "\x6c\x4c\x01\x99\xb0\xbc\x33\xa4\xfa\x63\xfa\x5d\x2a\x4f\x0e\x64"
-  "\xc1\xf6\x6e\xbe\xeb\x8b\xef\xb3\xf1\x06\xc8\x31\x94\xb7\x94\x25"
-  "\x43\xbd\x50\x6f\x41\x47\xf6\x27\x58\x95\xb8\xae\x0f\xcf\x1f\xbd"
-  "\x66\x55\x6e\x6c\x26\xc8\x2b\xc9\x06\xc0\xe5\x9d\x49\xd0\xe6\x50"
-  "\x26\x3f\xc2\x2f\x72\xbc\x28\xc7\x14\x90\x5d\x12\xe8\x2e\xb4\xf9"
-  "\x46\x68\xbf\x42\xc0\x3c\xfc\x5f\x08\xe3\x0f\x07\xf9\x4c\x8a\x77"
-  "\x23\xa1\x3c\xf5\xce\x50\xde\xbc\x2b\x94\x6f\x81\x36\x5c\xdc\x96"
-  "\xf5\xee\x30\xb1\x0d\xb1\x4e\x1b\xe1\xfc\x06\xb8\x6e\x52\xbc\x93"
-  "\xcf\x74\xe8\x9d\x38\xf1\x9d\x3d\xb5\xe7\xfa\xfd\x24\x62\xc3\x7e"
-  "\x32\xec\x8d\xfd\x64\x62\xea\x3c\xe8\x97\x99\xbf\xe3\x3f\x8b\xb5"
-  "\xc1\x98\xb8\x34\xae\x23\x74\x48\x2c\xf2\x43\x6e\xed\x5d\x45\xaf"
-  "\xed\x27\x63\xf6\xcd\x2e\x52\x4e\x6f\x21\x04\xc7\xf0\xe9\xbe\xe7"
-  "\x79\x83\xee\x3a\xe1\x82\x96\xc6\xd9\xd7\xde\x3f\xe8\xe9\xeb\x84"
-  "\x9c\xd0\x5a\x48\x5a\x22\x8c\xe5\xd7\x9a\x48\x9a\x85\x37\x57\x65"
-  "\x7c\x43\x00\x7b\xa6\xb0\xb6\x7b\xaf\x7a\xfa\x7c\x42\x70\xcf\x20"
-  "\xf7\xad\x96\x0c\x88\x23\xaa\xd4\x33\x24\x2c\xbd\x81\x6f\xb2\x6f"
-  "\x1d\x15\x9d\xb6\x9a\x28\xf7\x5f\x33\x32\xee\xa9\x78\x6f\xf7\x87"
-  "\xf0\x2c\xbe\x2d\x86\xcc\xb1\x09\xe3\x51\x5e\x78\x72\xfa\x02\x32"
-  "\x04\xdf\x27\x90\x72\xaf\xf7\x9e\x84\x76\x4b\xf6\x0e\x9f\xdf\x0b"
-  "\x66\x78\x58\xa7\x4b\x9f\xcf\x37\xc1\x98\xa2\xe4\xd3\xe7\x29\x78"
-  "\x4d\x54\x1c\xbf\xa9\x4e\x67\x50\xdd\x20\x86\x38\x0b\xf9\x08\x9e"
-  "\xed\x65\xb9\xd4\xff\x37\x1d\x3f\xa1\xbe\x33\xb5\x24\x83\xd6\x19"
-  "\xc6\xc9\xc0\x44\xe4\x50\xfc\x79\xac\xf3\x51\x78\x3f\x7e\xf8\xa4"
-  "\x6a\x90\xa5\x0d\xc7\xcc\xe9\x26\x3d\xa9\xb0\xda\xc9\xf6\x66\xda"
-  "\x2e\x7e\xd0\x2e\x2a\xb8\x56\x0d\x6d\xe3\xef\x4e\x56\x28\x27\x2e"
-  "\x77\x69\x1c\xe7\xc3\xe4\x41\x65\x61\x61\xb2\x78\x7a\x29\x81\xb1"
-  "\x13\xe4\xb1\x89\xc9\x83\x0b\x19\x1f\x8b\xf2\xf0\xee\x3d\xf6\x4e"
-  "\xf0\x34\xa6\xe0\xb3\x79\xd0\x09\xd4\x05\x2e\x78\x7c\x2c\x3e\x1b"
-  "\xeb\x80\xdf\xcc\x50\xf6\xd3\x5f\x3b\xcf\x57\xe9\x9a\x88\x01\xde"
-  "\x87\x0f\x72\xae\x83\xcd\xdb\x3a\x78\x8c\x7f\xb6\x7e\x1c\xe8\xea"
-  "\x38\xd0\xd5\x71\x64\xe2\x2a\x13\xd3\xd5\x53\xb5\x4c\x57\xed\x50"
-  "\xaf\x76\xe0\xeb\xab\x66\x12\x25\xd6\x6b\xef\x59\xf4\xcb\x07\xf5"
-  "\x6c\x92\xf4\x75\xda\x65\x68\x23\x51\x67\x7d\xee\x1f\x84\xed\x53"
-  "\x65\x31\x92\x74\xd4\xd9\x0e\x77\x3a\xbb\x7f\xdd\xf4\xb9\x20\x9b"
-  "\x3f\x81\xce\xfe\x43\x4b\x02\x1a\x88\x6a\xf5\x4c\xd0\xd9\x26\x77"
-  "\x3a\xbb\x7f\xe6\x11\x78\x66\x17\x9d\x9d\xef\xac\xb3\xfb\xec\xde"
-  "\xeb\xec\xbe\x72\x87\xce\x2e\xf0\xa0\xb3\xf3\x40\x67\x5f\xc8\xf7"
-  "\x52\x67\xf7\x6b\xbc\xd3\xd9\x7d\x25\x54\x67\x6b\x41\x67\x61\xfe"
-  "\xb1\xfd\x55\xda\x2e\x7e\xd0\x2e\xa0\xb3\xfb\xd6\x41\xdb\xb8\xd5"
-  "\xd9\x1f\x5e\x66\x25\x11\xbd\x97\x59\xc9\x1d\x3d\xcb\xec\xc0\xfb"
-  "\xde\xcb\xec\x40\xea\xad\x91\xd9\x81\x1a\xef\x64\x76\x60\x9e\x67"
-  "\x99\x1d\x88\xf8\xf1\xc8\xec\xfd\x96\xde\xcb\xec\xfd\x0f\x7b\x96"
-  "\xd9\xfb\xf3\xbd\x97\xd9\xfb\xe1\xb7\x46\x66\xef\x67\x7b\x27\xb3"
-  "\xf7\xc3\x3c\xcb\xac\xa4\xc5\x93\xcc\x26\x0d\xe1\x78\x0e\xd7\xc1"
-  "\x85\x86\xe8\x91\xd3\x30\xfe\xf5\x9f\x87\x70\x0e\x08\x69\x95\x98"
-  "\xa6\x1c\x09\xe6\xc9\x2e\xe9\x00\x97\xb4\xda\x25\x1d\xec\x92\x0e"
-  "\x73\x49\x0f\x13\xd3\x20\x23\xdf\x2b\x8a\xff\x1c\x0d\x73\xb0\x0c"
-  "\x93\xe2\x3f\xcb\x84\xeb\x23\xe6\xd8\x35\x38\x8f\x1b\xe1\xae\xee"
-  "\x1b\x33\x79\xab\x2e\x8d\xdc\xd5\xac\xf8\x2f\x26\x83\xb5\x43\xb5"
-  "\x7c\x4a\x06\xe1\x72\xeb\xf6\x3c\xbd\x1a\x75\xc9\x4c\xf8\xce\x30"
-  "\x3f\x68\xa7\xc1\x30\x7f\x34\xa3\x9e\x69\x12\x3e\xe2\xeb\x15\xff"
-  "\x75\x37\xbe\xdf\x38\x9d\x9e\x70\x3e\xf7\x63\x8c\x73\x05\xb7\xa9"
-  "\x6e\x8f\xd9\xe7\xfe\xa1\xfc\xee\xa8\xd8\x1c\x25\xe7\x9f\x93\xc9"
-  "\x69\x56\x9b\x79\xf3\xd4\xef\x60\x8c\x82\x71\xca\xd0\x62\x05\x3d"
-  "\xe4\xcd\xfa\x84\xcb\x50\xdf\xff\x7a\xad\x32\x15\xca\x86\xe7\xc0"
-  "\xb3\x8a\x78\x75\xdd\x3a\x83\xad\x9a\x80\xbc\xf7\x54\x59\xca\x61"
-  "\x2e\x6f\x24\x42\x99\x45\x7c\x50\xdd\x3a\x2c\xd3\xed\x7c\x2b\x2f"
-  "\xc4\x02\xcf\x7c\x64\xa6\x56\x45\xf8\x35\xaa\x60\xef\xf4\xe3\xbf"
-  "\x8a\x3d\xce\xe3\xf2\x42\x13\x59\xb9\xfe\x7d\x28\xf7\x20\xe9\xa6"
-  "\x5c\xa1\xbe\xea\xbe\x94\xeb\x71\xff\x13\x9f\x37\x58\xa8\xaf\xa6"
-  "\x2f\xe5\x96\x74\x53\xae\x50\xdf\xc8\x3e\x94\xfb\x81\xbf\xe7\x72"
-  "\xc3\x84\xfa\x66\xf4\xa5\xdc\x58\xcf\xe5\x86\x58\xfa\xa6\x0b\x1f"
-  "\x1c\xec\x4e\x17\xfa\xa6\x07\xff\xdd\xcd\xfb\x87\x5a\xfa\xa6\x03"
-  "\xff\x3d\xab\x3b\x1d\xe8\x9b\xfc\xff\xbb\x5b\xf9\xf7\x4d\xf6\xff"
-  "\xe3\x71\xfd\x07\xca\xbe\x6f\x72\xff\x1f\x8f\xfa\x8f\x73\x53\x90"
-  "\x7d\x2e\x1f\x3a\x49\xcf\x6d\x6e\xcc\xe5\x42\x43\x36\xaf\xe5\x22"
-  "\xc9\x24\xc0\xb0\xc0\x7c\x12\x14\x49\xed\x3d\xff\xd3\xb2\xba\x80"
-  "\x28\x73\x95\x9c\x72\x5f\x8a\x51\x69\xb0\x45\x90\x74\x1b\x6f\xdf"
-  "\x93\x64\x55\xfc\x1c\xce\x1f\x8b\x23\xc4\xb2\x4c\x4b\x68\x39\x83"
-  "\x1a\x73\x73\xd2\x22\xc9\x74\x3b\x41\xfb\x82\xe5\x38\xb0\x8a\xe9"
-  "\x80\x63\x86\x7c\x2b\x8e\x73\x41\x70\x9f\x0d\xf4\x17\xca\xb0\x92"
-  "\x03\x9c\x59\x11\x99\x40\xf3\x99\x61\x1e\x68\xe6\xb7\x86\x6c\xe6"
-  "\xd3\xb5\x64\x1d\xfc\xbf\xa4\x28\x9d\xe9\x63\x26\xca\x42\x98\x1f"
-  "\xb6\x65\x95\x46\x9b\x14\x87\xc6\xe0\x9c\x11\xe6\xa6\x2d\xe9\xdf"
-  "\xa1\x0d\x7d\x92\x7e\x2d\xcc\x53\x31\xef\x7e\xce\xac\x1c\xa7\x23"
-  "\xca\xe3\x66\x9c\x8f\x97\xa6\x1e\x4b\x24\xa4\x1b\x1b\x8a\x8a\x0b"
-  "\x1e\x5b\x83\xf7\x63\x39\x68\x9b\xdc\xc8\x41\xdb\x06\x87\x27\x63"
-  "\x7d\xf9\xbc\x21\x53\xf4\x29\x38\x2e\x1c\x52\x4d\x1e\xcd\xb7\x09"
-  "\x38\x3f\xb4\x19\xd2\x74\x0e\x9e\xc9\x57\xf3\xea\xda\x64\x3e\x67"
-  "\x40\x64\x95\xe5\x1a\xd1\x27\x75\x90\x7a\xc5\x21\x5f\x7c\x76\x6b"
-  "\xf0\xd8\x6a\x4b\xf0\x58\x63\x5b\xd6\x21\x22\xd6\x17\x9f\x25\x9e"
-  "\x47\x9b\x03\xab\xe3\x21\xcd\xb1\x54\xcf\x75\x84\xb1\x64\xd0\xf4"
-  "\x30\xde\x8c\x6d\xa8\x4f\xbb\x06\x75\x39\xbc\x05\xdb\x99\xcf\x1b"
-  "\x5b\x64\x49\xd7\xde\xc3\x6c\x70\x87\x8e\xa0\x2d\x07\xc6\x81\x3c"
-  "\x6a\x57\xd9\x54\x97\x47\xd7\xcd\x00\xde\xc3\x1c\x9c\xda\xce\xae"
-  "\x28\x0e\xd1\xf8\x81\x33\xb5\x4a\x2f\xe7\x33\x87\xe8\xf8\xaf\xbf"
-  "\x07\xdb\xe1\xf0\x6a\x78\xde\x6f\xe0\x1d\x4d\x02\xd7\x28\xc6\xe7"
-  "\x41\x9e\x78\x78\x66\x31\x9f\x5b\xab\xc3\x7c\xf5\x8a\xc3\x44\xb8"
-  "\x5e\xe2\x74\xbd\x04\xea\xdc\x24\x5c\xd7\x08\xd7\x0f\x3a\x5d\x3f"
-  "\xa8\xbb\x07\xed\x6c\x87\xa7\xe0\x3b\xc1\x58\x96\x8b\xe3\x1a\xda"
-  "\xf0\x99\x9d\xbc\x2e\x57\xc8\xb7\xa7\x45\x71\x78\x6e\x2b\xe8\x15"
-  "\x5c\xdf\xeb\x74\xff\xde\xe3\xc9\xe1\x64\xd2\x4e\x6c\xd3\xc3\x89"
-  "\x26\x9f\xc6\x0c\x66\x9b\x39\xa4\xa3\x6d\xa1\xae\xcb\x76\x2e\xcf"
-  "\xa4\x38\x1c\x09\x65\x66\x5b\x80\xdf\x41\x9e\x18\x7c\xa6\x73\xfb"
-  "\xcf\x4f\x48\x58\x92\xa0\x19\x39\x4f\x33\x6f\xd1\x5c\xcd\x2b\x4b"
-  "\x96\x2f\x4e\x7c\x74\xe4\xbc\xfe\x84\x38\xe9\x8e\x9a\xcf\x0c\xe4"
-  "\xb9\xbc\xd1\x61\x86\x7c\x1b\xe1\x95\x6a\x18\x6f\x3b\x48\x1e\xc8"
-  "\xd5\xb6\x35\xc2\x6c\x0f\x8d\xc8\xb0\x6f\x1d\x62\x4e\xbf\x4e\x94"
-  "\x69\x61\xfc\x05\x7d\xca\xe3\x20\x83\xbf\x0d\xc0\xf1\xde\x00\x6f"
-  "\xbf\x1e\xf4\x55\x9f\xf2\x31\x9e\x1b\x49\x6d\xfc\xb1\xec\xdc\x7f"
-  "\xa5\x95\x2b\x3f\x4a\x33\x2a\x2b\x62\xaf\x91\xe3\x61\x66\x52\xa6"
-  "\xb9\x46\x0a\xf0\x3c\x57\x4d\xbf\xb5\x40\xfe\xe5\xf8\x2c\xb4\x57"
-  "\xe1\x7f\x66\x7b\x3b\xdc\x8e\xcf\xd1\x0c\xc5\x6f\x00\x87\xed\xf8"
-  "\x3c\x78\x3f\x9b\x4f\x01\x51\x00\x9f\x09\x80\x7c\x87\xb8\x2d\xa3"
-  "\xc3\x68\xff\xce\x3a\xbc\xd7\xa6\x0c\xfa\x75\xe1\x66\xe2\xbf\x6b"
-  "\x33\x21\x05\x83\x88\xaa\x2d\xeb\x6f\x7b\x4c\x3e\x36\x6a\x0b\x83"
-  "\xa2\x03\x5a\x95\xe4\x77\x70\xae\xd4\x44\xe6\x07\xe3\x39\xe8\x57"
-  "\x16\x4f\x78\x81\xdf\xbe\xac\x7b\x7c\x33\xb8\xe0\xd1\x80\x49\xa3"
-  "\xc3\xac\x23\x7c\x4b\x02\x75\xa0\x2f\xd0\x6f\xf8\x90\xd1\xfe\x2d"
-  "\x8a\x0f\x0f\x7e\x02\x33\xe2\x34\xec\xa7\xd0\x1e\xef\xdd\xb0\x42"
-  "\x7f\x8d\x30\xef\xbd\x61\x86\x74\x44\xc6\x3b\x49\x56\xe5\xa9\xa8"
-  "\x52\xa2\x79\x16\xf9\xd0\x91\xb1\xbf\x9f\xc7\xdb\xee\x8f\x06\xee"
-  "\xd8\xf0\x9f\xe4\xb3\xda\x72\x12\x30\x8b\xf8\x38\xfc\xb1\x27\x12"
-  "\xe5\x74\x13\xa4\x97\x13\x65\x15\xcc\xd3\xd1\x7e\x9e\xf6\x18\xda"
-  "\xd0\x2b\x09\xda\xd5\x79\xe5\xab\xeb\xf6\x5d\xb3\x02\x2e\x35\xf9"
-  "\xe2\xfe\x6d\x4e\xbd\x22\x0e\xef\x99\x63\x11\xbe\x47\xb5\x0a\xdf"
-  "\xa3\x5a\xe9\xf7\xa8\x70\xfc\x16\x85\xdf\xa0\x52\x63\x79\xce\xbe"
-  "\x4c\x3b\x68\x7a\xac\x0f\x8f\x65\xe2\xf7\xa9\x01\xc0\xf5\xf9\x65"
-  "\xda\x81\xdb\x12\x48\x70\x95\xb9\x89\x18\x9a\xca\xc9\x8e\x24\x12"
-  "\xcc\xb7\xc6\xdd\x51\x51\x76\x8a\xf0\x9b\x97\xc5\x1e\x48\xd3\xfb"
-  "\xda\xd1\x9e\xd1\x1a\xd6\x3f\x70\x8d\x02\x6d\xf1\x03\xd7\x27\x90"
-  "\x31\xbb\xae\x91\xf0\x39\x8d\x19\xd4\x37\x13\xc6\xd1\xb3\xb5\x6a"
-  "\x35\x9d\xad\xda\xfb\x3a\x96\x69\xef\x09\x34\xb3\xef\x57\x2f\x2d"
-  "\x50\x13\xfc\x46\xc5\x67\xed\x4d\xdd\x85\x76\x64\x8b\x99\xd8\x82"
-  "\x56\xc4\xa1\x7e\xc2\x73\x87\xe1\x37\x8f\xf4\x95\x44\xcd\x5d\xd4"
-  "\x92\xca\x96\x6b\x64\x3c\xe8\x0d\xda\xf7\x0b\xeb\x99\x7d\xdf\xbe"
-  "\x69\x69\x1c\xda\xf8\xdb\x96\x69\x95\xd3\x2e\xc3\x78\x95\xf5\xb7"
-  "\xea\x8e\x91\xbe\x19\x27\xb4\x75\x38\x26\x84\x4b\xfd\xfe\xc3\x35"
-  "\x7d\xeb\xf7\x1f\x52\xfb\x3c\x7e\xf3\x02\x39\x99\xf7\x5e\x43\xb9"
-  "\x81\xfc\xae\x99\x95\x4f\x35\xf0\xb6\xca\x86\x77\x41\x3e\x46\x99"
-  "\x7c\xa8\x3c\x13\xac\xca\x4b\xf3\x40\x2e\x8d\x4c\x56\x15\x16\x90"
-  "\xd3\x31\x2c\x63\x9c\x7a\x1f\xc8\x1a\xe6\x39\xca\x0a\x6b\x1d\xf5"
-  "\x2d\x81\xf2\xda\xdb\x51\xee\xdb\x11\x1c\x92\x8b\xdf\x0e\xdb\x46"
-  "\xf8\x16\xb5\xe7\x69\x9b\x3a\x83\xb5\xd6\x6e\xbe\x23\x86\xa3\xbc"
-  "\x56\x2f\x20\xfe\x15\x0d\xa7\x09\x95\xd9\x52\x41\x66\xb8\xde\x6c"
-  "\x85\x76\xa0\xad\x4d\x3b\x68\x1b\xc8\xaa\x2a\xd1\x44\xb6\x5f\x23"
-  "\xc1\x86\x26\x23\x7e\x63\xb9\xe3\xa9\x67\x08\x79\xea\x1d\x9e\xab"
-  "\x2c\x3b\x4b\xe5\xb7\x1f\xe4\x67\x03\xf9\xe1\xb7\x45\x87\xfc\x92"
-  "\x40\x7e\x37\x40\x7e\x97\x25\xf9\xd9\xdb\x40\x7e\x6d\x20\xbf\x15"
-  "\x20\x3f\x8b\xab\xfc\xf6\xa1\x5d\x54\x85\xdf\x79\x50\x7e\xb8\xc6"
-  "\x99\x5b\xa1\x1d\x46\xbf\x3b\xbe\xa2\x25\xbb\x5e\x26\xfe\x63\xad"
-  "\x44\x91\x7e\x8c\xa8\xa1\x9e\xea\x5f\x40\xfb\x42\x79\xa0\xdf\xf5"
-  "\xc4\x50\x6a\x27\xab\x9e\x27\xf7\xa0\x3c\x6d\x82\x3c\x0d\xb6\x0f"
-  "\xc8\x8d\x36\xad\x12\xca\x8c\xd8\x76\x83\x4c\x9c\xda\xa8\x21\x27"
-  "\x66\x54\xc2\x18\xf2\x61\x3c\xb7\x65\x6c\x51\xdf\xfb\xe1\xb1\x89"
-  "\xbd\xef\x87\x1f\x7d\xf0\xcf\x7e\xd8\xd7\x7e\xf8\x51\x8c\xfb\x7e"
-  "\x78\xec\x8e\xbe\xf5\xc3\x63\xfe\xff\xec\x87\x3f\xa6\x7e\xa8\xb7"
-  "\xb8\xf6\x43\x07\x57\x48\x98\xbf\x68\xee\x82\xc5\x0b\x16\xff\x49"
-  "\xf3\xf2\xca\xc4\xf9\xcb\x18\x63\x90\x71\x06\xad\x9d\x8b\x54\xbe"
-  "\x05\xe3\xe9\x67\x61\x46\x72\x60\xa8\x51\xc9\xbd\x18\xa6\xe2\x73"
-  "\x5f\x2f\xe1\x72\xd7\x47\xbc\x05\xdc\x17\xfb\x6b\x1e\xf0\xda\x4b"
-  "\x8a\x4a\xcd\xa7\xc3\x80\xf3\x25\x34\x13\xfc\xcf\xf8\xd2\xef\x09"
-  "\xee\x15\xcc\xdf\xca\x37\xe1\x5e\xc1\x53\x51\x38\xf6\x1f\xdf\x76"
-  "\x67\x0c\x8c\xeb\x2f\x86\x91\xf6\x17\x63\x94\x6f\x9c\x25\xfe\x81"
-  "\x46\x32\x95\xe3\x78\x5e\x9f\xd6\x0c\x5c\xeb\xd4\x3c\xfd\x0b\xcd"
-  "\x44\x93\xe2\x0f\x79\xcb\x8f\x69\x52\xd6\xe0\xf1\x6d\x4d\x4a\xd6"
-  "\x79\x38\xce\xc7\x72\x37\x40\x79\xdc\xa8\x7e\xd5\xf8\x2d\x13\xfa"
-  "\xa2\x72\xe7\x56\xbe\xe1\xc0\x62\x93\x72\x6d\x07\x21\x6b\x53\x88"
-  "\x0a\x7d\x43\xe8\xef\xc1\x7a\x7c\x7a\x62\xba\xed\x3c\xbf\x1e\xae"
-  "\x7f\x74\xc9\xa4\x2c\x84\xeb\xe8\xb7\xd3\xa2\xae\xd5\xad\x83\xba"
-  "\x43\xbd\x4c\xdb\x43\xf9\x5a\x73\xc8\xe8\x30\x95\x86\x28\xdb\xb2"
-  "\x8e\x03\xff\x3a\x5c\x86\x1c\x22\x1b\xae\xbd\x01\xd7\xd8\x77\xb6"
-  "\x4f\x33\xec\x59\x1f\x1b\x11\xa7\x40\x5f\x15\x57\x14\x65\x4f\xb6"
-  "\xc3\x7b\x41\xb9\x66\xac\x0b\xc6\x91\xb5\xbd\xed\x5b\x64\x7f\xdb"
-  "\xb7\xc4\xba\x45\x6b\xed\x08\xd1\x36\x21\x86\xcd\x1c\x4d\xbf\x27"
-  "\x43\xfe\x4f\xe8\xba\xb2\xce\xe0\x21\x66\xe4\xd1\xad\xc1\x11\xe6"
-  "\xd6\xbc\x88\x8c\x53\xa9\x25\x02\x7e\x95\x2d\x7f\x2a\x5f\xc0\xaf"
-  "\x7c\xe8\x1f\x31\x80\x5f\x31\x5d\xf1\x8b\x7d\x7f\xb7\x13\x86\x63"
-  "\x95\x04\xe6\x1d\x0d\xd8\x3f\x90\x0b\xee\xeb\x80\xfe\x03\xba\x8f"
-  "\x3a\x4e\xf1\x0c\xb0\x4c\xec\x07\xd8\x47\x10\xb3\x68\x9f\x74\xe9"
-  "\x13\xd8\x0f\xee\x34\x13\x35\xf6\x03\xc4\x34\xec\x07\xb8\xae\xe5"
-  "\xad\x1b\xac\x1f\x04\xd6\x12\x35\xed\x0b\xb6\x72\xda\x17\xb0\xfe"
-  "\x15\x36\x17\x1c\x73\xea\x07\x1b\xc4\x7e\x20\xe2\x18\xe8\xba\x0d"
-  "\xfb\xc1\x0a\x79\x3f\x78\xb1\x4e\x4d\x28\xc6\x65\xed\x25\x05\xd0"
-  "\x0f\xaa\x74\x66\x62\x17\x71\x0c\xfa\x01\xee\xbb\xa1\x38\xf6\x67"
-  "\x01\xc7\xcc\x70\x1e\xf4\xbf\x70\xa1\x1c\xc7\xda\xdb\x7a\xe2\x13"
-  "\x27\x3e\xef\x1b\x8e\x9d\xa0\xfe\x0f\x50\x56\x28\x37\x94\x17\xca"
-  "\xe8\xa7\x24\x1f\xc4\x29\xbb\x7a\x69\xdc\x00\x90\xcd\x80\x16\x32"
-  "\x10\xf1\x0a\x71\x6a\xa7\x07\xf9\xc0\xbd\x2d\xf0\x7c\x37\x32\x7a"
-  "\x77\x46\x81\x13\x56\x21\x46\x21\x5e\x21\x4e\x21\x66\xe1\xfa\x02"
-  "\xe8\x0b\x4d\x88\x57\xbf\x48\x65\x38\x85\xf8\x95\xde\xc8\xb0\xab"
-  "\x32\x8e\x61\x56\xfa\x64\x72\x0f\xc6\xae\xb2\x07\x2d\x8d\xc3\x38"
-  "\x54\x06\xdb\x75\xd2\x2e\x60\xd6\xf6\x24\x32\x71\xda\x02\x0d\x41"
-  "\xac\x82\xb6\x3f\x72\x42\x7b\x9a\x50\xfe\xaf\xfc\x99\xdf\x4e\xe0"
-  "\xfd\xbb\x80\xf7\xe7\x0d\x22\xfe\x6d\x59\x9f\x16\x75\xe5\xfe\x9f"
-  "\x1e\x14\xb9\x3f\xf6\x59\xec\xbb\x26\x45\x19\xf5\xbf\xa6\x1f\xfa"
-  "\x08\x62\x0e\xfb\xa6\x93\x37\x2a\x92\xd9\xbf\x2b\xa9\x4e\xe0\xbc"
-  "\x59\x9a\x33\x97\x2b\xd8\xf7\x6c\x98\x23\x87\x0c\x99\xc2\x6f\xaa"
-  "\x4d\xc6\xb6\x14\xfa\x78\x0b\xbf\x65\x6c\x35\xea\xd4\x9c\xd1\xc4"
-  "\xdf\xb6\x65\x6c\x8d\x7d\xcb\x58\x23\xd3\xaf\xf2\x07\x4f\x24\x13"
-  "\x32\x33\xd9\x5b\xfd\x2a\x67\xb6\xd7\xbf\xc7\xfc\x8c\x7f\x31\x46"
-  "\xc5\xfd\x3d\xc6\x17\x74\x21\x6c\x89\x3d\x83\xdc\xc8\x7d\xca\x9a"
-  "\x6e\xe3\x9b\x34\x29\xe4\x7e\xa8\xd7\xa6\x53\x30\xdf\x3e\x95\x48"
-  "\x88\x21\x3a\x1e\xe4\xfa\x54\xf2\x01\xce\xac\x32\x29\x8e\xe7\xc3"
-  "\x9c\xbf\x09\xb0\x54\xe5\x8c\xa5\x0c\x37\x8f\xd3\xef\xd1\xd6\xdc"
-  "\xdf\xfb\x63\x59\xd3\xcb\x49\xa0\xe6\x09\x5c\x2f\x77\xea\xa1\x95"
-  "\xab\x09\xee\x01\xf5\x85\xff\x8a\xf6\xcd\x43\x93\xe1\xfe\x81\xfc"
-  "\xdf\x67\x28\x74\x4f\xc0\x78\xf2\xe2\x0c\x05\x7e\xbf\x7f\x37\x2d"
-  "\x5f\xc9\xc1\x39\xb6\x1e\x28\x9f\xe0\xf5\xf5\x1d\x2a\xca\x9b\x38"
-  "\xc8\x53\x65\xc9\x27\xeb\x93\xfc\x09\xe6\x67\x6b\xcc\xf2\x09\xe6"
-  "\xdf\x90\xa0\xa6\xdf\xff\xe9\x7d\xb6\x7c\x82\xf7\xda\xe1\xfc\x9b"
-  "\x5c\x00\xc9\x49\x09\x26\xa7\xa2\xab\x68\x19\xa7\xa2\x3f\x21\x58"
-  "\x06\x62\xf7\xa9\xe8\xa3\x64\x63\x52\x18\xf4\xf1\x7c\xb8\xfe\x15"
-  "\xd9\x78\x65\x18\x1c\x2f\xc1\xef\x06\x69\x56\x9c\x2c\x3a\x15\xcd"
-  "\x91\xc0\x35\xbf\xe3\x01\x5b\x78\x03\xee\x2b\x4c\x23\x7e\x97\x14"
-  "\x27\xe9\x1e\x60\x68\xc3\x5c\xdc\x77\x6e\x30\xe6\x12\x3e\xfd\xc5"
-  "\x16\x8e\x7f\xf1\x32\x97\xfe\xe2\x15\x7c\xbe\x9d\x7f\xf1\x2a\x3e"
-  "\x7f\x43\x8a\x46\x58\x77\x9a\x4f\xd7\xc8\xad\xbf\x31\x82\x60\x7d"
-  "\xf1\xd9\xf8\xcc\x8d\x09\x5a\xe1\xb9\x63\x68\xfd\xf0\xb9\x58\xae"
-  "\xf3\x73\x31\xae\xbb\xe6\x39\x7c\xee\xa9\xe1\x70\x0c\x02\x99\xe4"
-  "\xa1\x2c\xf0\xb9\x1c\x1f\xe3\xcb\xa7\xc7\xf8\xd0\x7b\x92\x9b\xdc"
-  "\xdd\x33\x53\xb8\x27\x97\xce\x9b\xe1\x9e\x0e\x96\x9f\x96\x01\xe3"
-  "\xdd\x52\x3c\xff\x40\x8c\x9e\x74\x95\xe3\x67\x03\xd8\xf8\x77\xaa"
-  "\x8e\x8d\x7f\x4c\xae\x54\x5f\x5e\x8c\xf1\x05\xd9\xa9\x71\xac\x84"
-  "\x32\x3e\x70\x94\xf1\xf7\x18\x1f\x94\x39\xea\x8e\xa8\x4f\xa8\x4b"
-  "\xa2\x1e\xd1\x7a\xea\x08\x71\xd6\x1b\xf8\xef\x2f\x94\x63\x17\xcb"
-  "\x81\x3a\x10\x51\x97\x1e\x80\xeb\x5d\x75\xa9\xe2\x8c\xa4\x4b\x15"
-  "\x2b\xad\x69\x3c\x8f\xba\xa4\x7f\x21\x13\xca\xf9\x6c\xb2\x54\x9f"
-  "\x19\x54\xcf\x7e\x62\xfa\x55\x24\xca\xea\x81\x54\x12\xcc\xde\xa9"
-  "\x62\x08\x7d\xa7\x54\x7d\x30\xd6\x57\x7c\x17\xac\x47\x0e\xa7\x21"
-  "\xe2\xbb\x6c\xec\x18\x01\x65\x5f\x21\xc2\x3d\xd3\xb0\x7c\xb1\x1d"
-  "\x40\x6e\x44\xbc\x47\xcc\x9f\xc3\x69\xa1\xee\x63\xe8\x3d\x4c\xef"
-  "\x2e\xb9\xd1\xa1\x8a\x6d\xae\x7a\x77\x67\x2a\x01\x02\x0b\x9c\xe9"
-  "\x85\x6b\xf8\x1c\x26\xff\xd4\x8f\xec\x1d\xf0\x0c\x90\x83\x52\x38"
-  "\x5f\xe9\xa4\x17\x42\xf9\x56\x77\xe5\xb7\xcb\xca\x8f\x81\xf2\x93"
-  "\xa1\x7c\xe4\x64\x2f\xa0\xfd\xab\x92\xae\x87\x7b\x20\x99\x95\x2f"
-  "\xea\x2e\x9f\x3b\x38\x5a\x97\x82\x6b\x35\x2b\x8f\x30\x5c\x3d\xfe"
-  "\x18\xe6\xa3\x6b\x84\x94\x5c\x11\xe7\xb2\x46\xc8\x79\x0d\xd9\x81"
-  "\x34\xb3\xb0\x3e\xa8\x92\xee\x6d\x02\x9c\xb5\x20\xb7\xdc\x77\xc9"
-  "\xa8\x94\xd6\x08\x9d\xc5\xeb\x6f\xeb\x93\xea\x9d\xd6\x08\x55\x26"
-  "\xb3\xbe\x5f\x59\x0d\x73\x48\x25\xa4\xd7\xb3\xf3\xc7\x23\x9d\xcf"
-  "\x4b\x6b\xf0\xd8\x79\x5c\xdf\x2c\xd8\x5c\x5b\x8e\x97\xa2\xcd\xad"
-  "\xb2\x49\xb4\x73\x7a\x98\xa3\x7a\xc1\x7d\x8d\x5a\x89\xfb\x1a\xb5"
-  "\x9e\xb9\x6f\xd5\x96\xee\xb9\xef\x69\x9d\xc4\x7d\xbf\xfc\x9c\xf5"
-  "\xfd\x2f\x3f\x60\x7d\xff\xcb\xe5\xb4\x2d\x43\xf9\x26\xfb\xbf\x4f"
-  "\x32\x55\xa9\x08\xd5\xa1\x5d\xc0\x31\x0e\xa4\x18\x5d\xb8\x2f\xae"
-  "\xad\xfa\xe2\xf4\xd3\xc0\x7d\x61\x7c\x8b\x66\xed\x50\x55\x07\x6d"
-  "\xef\x63\xb0\x5a\x09\x9e\x87\xb1\xad\x01\x79\xef\x51\xce\xa8\x2c"
-  "\x84\xf6\x83\x9f\xca\x12\x3c\xa9\xc4\x99\x17\xb7\x65\x19\x02\xdc"
-  "\xf3\xe1\x2f\x72\x6d\x32\x3e\x6c\x78\x5e\xe4\xc3\x58\x3f\xe4\xc0"
-  "\xc8\x87\x6d\x68\xc7\x1c\xe9\x5b\x82\x7c\xd8\xb6\xc5\x99\x0f\x7f"
-  "\x1e\xe2\xe0\xc3\xa1\x4e\x7c\x38\x59\xe4\xc3\x86\xd7\xfe\xc9\x87"
-  "\xbf\x2f\x1f\xf6\x34\xaf\xaf\xbe\xd0\x37\x3e\x5c\x6d\xfa\xdf\xc2"
-  "\x87\xdd\xce\xdb\xdd\xc8\x07\xf4\xb9\xc5\xe6\x86\x0f\xf3\xc0\x87"
-  "\x77\x75\xc3\x87\xb1\x1f\x20\x17\xa6\xf3\xf6\x79\xc0\x39\x00\x03"
-  "\x90\x03\x8b\x9c\x18\x79\x30\xf2\x61\xe4\xbf\xc8\x95\xa9\xfc\x82"
-  "\x24\xf9\x75\xe5\xc3\xd5\x15\x12\x1f\x1e\xf4\x5d\x81\x8c\x0f\x7f"
-  "\x51\xd2\x95\x0f\x7f\x51\xd6\x95\x0f\x1b\x34\x12\x1f\xae\x2a\x93"
-  "\xf3\x61\xe3\x99\xae\x7c\xf8\xcb\x20\x4f\x7c\x18\x39\x30\xf2\x61"
-  "\x9c\x2f\x20\x17\x86\xff\x46\x49\xbf\xbe\x7c\xac\x6f\x7c\xf8\xcb"
-  "\xc8\xde\xf1\xe1\x2f\x77\xbb\xe7\xc3\x55\x79\x9e\xf9\x70\x55\x9e"
-  "\x7b\x3e\x7c\xfa\x31\x89\xc3\x9c\x1e\xf0\xe3\xe7\xc3\x35\x25\xee"
-  "\xf9\x4a\xcd\x21\xe4\x04\xd0\x86\x45\xc8\x87\x6f\x2e\x17\xfe\xb2"
-  "\xc8\x3d\x17\x3e\x3d\x96\x71\x86\x2f\xf7\x74\xe5\xc2\x70\x8f\x5b"
-  "\x2e\x7c\x7a\xae\x70\x8f\x83\x5f\x31\x2e\xcc\xca\x80\xf1\x6f\xb5"
-  "\x67\x2e\xfc\xd5\x10\x36\x1e\x9e\xfe\x86\x8d\x87\x4c\xa6\x5d\xb9"
-  "\xf0\xe9\x63\x3d\x73\x61\xa6\x43\xb4\x9e\x1e\xb9\xf0\x57\x77\x74"
-  "\xe5\xc2\x55\x79\xee\xb9\xf0\xd7\x17\x24\x3d\xfa\x7a\x8d\x9c\x0b"
-  "\x7f\xf5\xcc\x4f\x83\x0b\x7b\xd4\xad\x12\x39\x0f\xfe\x7a\xb8\xf7"
-  "\x3c\xf8\xeb\x99\xde\xf1\x60\xd4\x39\x77\x3c\xf8\xeb\xdd\xae\x3a"
-  "\x27\xe7\xc1\x5f\x7f\xe8\x9e\x07\x7f\x7d\x5a\xce\x83\xb1\x7c\x77"
-  "\x3c\xd8\xa8\x90\x95\xdf\x85\x07\x1b\xef\x96\xf3\x60\x96\x4f\xe2"
-  "\xc1\xc6\x32\x81\x6b\x3d\xea\x3d\x0f\x36\xbe\xdd\x3d\x0f\x36\xee"
-  "\x93\xf3\x60\x63\x06\xe3\xbb\x46\x23\xe3\xc1\xc6\x3c\x76\xbe\x6a"
-  "\xa2\xf3\x79\x89\x07\xb3\xf3\x5d\x79\xb0\xd1\xdc\x03\x0f\x8e\xe8"
-  "\x3d\x0f\xbe\x58\x5a\xee\xe0\xc1\x17\x4b\x45\x1e\xcc\x29\x81\x5f"
-  "\xc2\xd8\x0f\xbf\x26\x5c\xf7\x8f\x7d\xee\x92\xe2\xcc\xee\xee\xb9"
-  "\xb0\xc9\x22\x71\xe1\xf3\x93\x59\xdf\x3f\x3f\x9a\xf5\xfd\x73\xdf"
-  "\x38\xb8\xf0\x7d\x93\x4c\x95\xeb\x1c\x5c\xd8\x78\x20\xa5\xda\x85"
-  "\x0b\x63\xdb\x9d\xa3\x5c\x78\xe3\x0d\xba\x5e\xc3\x84\xe3\xf9\xd3"
-  "\xa9\xe7\xf9\xf5\x30\x86\xc3\x18\x66\x62\xed\x7b\xee\xa1\x82\xad"
-  "\x7c\xad\xc4\x97\xcf\x0e\x70\xf0\xe5\x54\x6a\x43\x36\x52\xbe\xfc"
-  "\x6a\xb5\x72\x27\x94\x0f\x3f\x15\x72\x65\xe4\xcc\xc0\x95\x6b\x76"
-  "\x6e\xe5\xab\x0b\xb7\xf2\x15\x6d\x59\x67\x23\x45\xce\xbc\x01\xce"
-  "\xe5\xc0\xb9\x32\x40\xbb\x9d\x37\xe8\x4f\x05\x6d\x5f\xbb\x16\x9e"
-  "\x89\xf7\x41\xde\x78\x31\x2f\x8c\xd3\x35\x8c\x5b\xd7\x59\x38\x3f"
-  "\x67\x6e\x7d\xf6\x90\xc8\xad\x73\xe0\x7d\x91\x43\x89\xdc\x9a\x03"
-  "\x6e\xcd\x87\x30\x7b\xb3\x9c\x5f\xd7\x2e\x17\xf9\x75\x8e\x33\xbf"
-  "\xd6\x89\xfc\xfa\x6c\x63\x1f\xf9\xb5\xf1\x7f\x33\xbf\x46\x6e\x8d"
-  "\x7c\x1a\xb9\x35\x72\x6d\xe4\xd7\xc8\xb5\x39\x81\x5f\x17\x3a\xf3"
-  "\x6b\x3f\x27\x7e\xad\x70\xe6\xd7\xb5\x8f\xf5\x8d\x5f\xd7\x46\x3a"
-  "\xf3\x6b\x90\x9b\xd1\x5b\x7e\x8d\x32\xee\xf2\x3d\x13\xd7\xdb\x80"
-  "\x9c\x50\x26\xdd\x7e\x17\x13\xe4\x85\xf2\x41\xd9\xa0\x8c\x7a\x25"
-  "\x1f\xd0\xaf\x0a\xeb\xed\xe3\xd7\x5a\x17\x7e\x8d\x7c\x1a\xda\xae"
-  "\x01\x79\xb6\x41\x0f\x6d\xb3\x14\xb8\x36\xf0\xec\x9e\x39\x76\xed"
-  "\x18\x67\x8e\x5d\x38\xc8\x99\x63\x9f\x0b\xee\xca\xb1\xcf\x69\x9d"
-  "\x38\x76\x8d\x49\x71\x96\xae\x41\xd7\xbf\x8a\xdc\xf9\x8c\x45\xce"
-  "\xaf\x1b\x16\x74\xe5\xd7\xe7\x96\x7a\xe2\xd7\xb8\x4e\xcc\xd5\xde"
-  "\xcc\x85\x88\xf6\xe6\x73\xbb\xfb\xc6\xaf\xcf\x15\x49\xfc\xff\x4c"
-  "\x35\x1b\x23\xce\x79\xe4\xdc\x6d\x6a\x67\xce\x7d\x3e\x44\xe2\xdc"
-  "\x89\x4e\x9c\xfb\x4c\x91\x67\xce\x7d\x86\x3e\x8f\x57\xff\xde\x1f"
-  "\xcb\x42\xae\x84\xb6\x0a\x0d\xdd\x17\x6e\x3a\x81\x7c\x09\x6d\x10"
-  "\xf0\x4e\xc0\x99\x4c\x9b\x9c\xb9\x37\x7e\xaf\xeb\x8e\x1f\xe9\x5e"
-  "\x25\xf7\x20\x47\x42\x7e\x24\xf2\x59\xcc\x8f\x3c\xe9\xd6\x72\x24"
-  "\x53\xb8\x7b\x8e\x64\x7a\x94\xf2\x5f\xba\x9f\xf0\x7c\x30\x8e\x75"
-  "\x37\x97\x83\x9f\x0f\x76\xcf\xc1\x4d\xef\x33\xbe\x72\x3e\x0c\xe5"
-  "\x22\xe7\xe0\x70\x8f\x5b\x0e\x6e\x6a\x14\xee\x09\x96\x73\x70\x56"
-  "\x46\xbd\xe2\x82\xc2\x33\x07\xbf\xb0\x93\x8d\xc3\x17\x16\xb1\x71"
-  "\x58\x90\x71\x17\x0e\x7e\xc1\xc9\xfe\x1b\xe3\x83\xf2\xef\xca\xc1"
-  "\x99\x4e\xd1\x7a\x7a\xe4\xe0\x17\x36\x74\xe5\xe0\x67\x8a\x90\x83"
-  "\xbb\xd7\xab\x8b\x4b\xe5\x7a\x75\x31\xc8\xca\x89\x5c\xfc\x0d\x2c"
-  "\xaf\xce\x95\x8b\xff\x04\x75\x2d\x5c\xe2\xe3\xf8\x4e\xf5\xef\x7b"
-  "\xc7\xc7\xe9\x3d\x8d\xde\xf1\x71\xd4\x3f\x77\x7c\xfc\xe2\x83\xae"
-  "\xfa\x27\xe7\xe3\x17\xa7\xb9\xe7\xe3\x17\xe7\xcb\xf9\x38\x96\xef"
-  "\x8e\x8f\x5f\xdc\x24\x2b\xbf\x0b\x1f\xbf\xb8\x4f\xce\xc7\x59\x3e"
-  "\x89\x8f\x37\x08\xfb\xb2\xcf\x4c\xf6\x9e\x8f\x37\x3c\xd4\x3d\x1f"
-  "\x6f\x78\x54\xce\xc7\x1b\xd4\x0c\x53\x1b\xe2\xac\x94\x8f\x37\x8c"
-  "\x60\xe7\xcf\x44\x39\x9f\x97\xf8\x38\x3b\x6f\x75\xe6\xe3\x7a\xe4"
-  "\xe3\x0d\x19\x3d\xf0\xf1\xa8\xde\xf3\xf1\xab\x7a\x89\x8f\x5f\xd5"
-  "\x77\xcf\xc7\x1b\x1f\xec\x9e\x8f\xb7\xd8\x24\x3e\xfe\xed\x34\x86"
-  "\x03\xdf\x3e\xc8\x70\xa0\xf9\x3b\x0f\x7c\xbc\xc2\x3d\x1f\x6f\xae"
-  "\x73\xe2\xe3\xb5\xc8\xc3\x61\xcc\xab\x45\x1e\x80\xeb\x35\x80\x87"
-  "\x1b\xf5\x09\x34\xdf\x49\xe4\xeb\xc8\xd1\xe1\xba\x69\x3d\xfe\xe7"
-  "\xe8\x3d\x35\xb8\x1e\x8a\xf2\xf2\x4b\x94\xc3\xd7\x30\x99\x34\x8f"
-  "\x86\x7b\xab\x25\x0e\xdf\xf8\xb9\x0b\x87\xaf\xe8\x86\xc3\x97\x03"
-  "\x87\x2f\x03\x0e\xaf\x6f\xcb\xba\xa4\x72\xe2\xf0\x65\xc0\xe1\xf5"
-  "\x2e\x1c\xde\x08\x1c\xbe\x16\xef\xc3\x7b\x20\xff\x04\x59\x7e\xa8"
-  "\x2b\xcd\x7f\x8d\xfe\x30\x7f\x35\xe4\xaf\x61\x9c\xff\x52\xac\x13"
-  "\xe7\x2f\x67\x9c\xff\x9b\x26\x5e\xc6\xf9\x2f\xed\xf3\x9e\xf3\x37"
-  "\x2d\xe8\x9e\xf3\x5f\x3a\xd3\x47\xce\x5f\xf1\x4f\xce\xdf\x13\xe7"
-  "\x6f\x7a\xa8\x6f\x9c\xbf\x69\x82\x0b\xe7\xaf\xf8\x27\xe7\xff\x21"
-  "\x39\x7f\x93\xc6\xc1\xf9\x33\x07\x7d\xb7\x0b\x39\xff\x66\x91\xf3"
-  "\x37\xfb\x77\xe5\xfc\xcd\xc3\x9c\x38\x7f\xb9\x49\x01\xad\xec\xe0"
-  "\xfc\x8d\xa5\x72\xce\x6f\x5e\xda\x95\xf3\x37\xcf\xef\x1b\xe7\x6f"
-  "\xde\xd2\x37\xce\xdf\x9c\xc7\xea\x87\xdf\x03\x1b\xb3\xd9\x38\xd4"
-  "\x3c\x41\x9a\x07\x34\xc6\x3a\x9f\xeb\x79\x1e\xf0\xed\xdd\xee\xe7"
-  "\x01\x8d\xe1\x9e\xe7\x01\x8d\xe1\x9e\xe7\x01\x2d\x95\x72\xbe\xd6"
-  "\xb2\xed\xa7\x31\x0f\x68\x89\x70\xcf\xcd\x5a\x26\x4b\xf3\x80\x6f"
-  "\x87\xdd\xfc\x79\xc0\xb7\xc3\xdc\xcf\x03\x5a\x0e\x31\x9e\xf4\xad"
-  "\xa6\xeb\x3c\x00\xee\x71\x3b\x0f\x68\xb9\x2c\xdc\x33\x4c\x3e\x0f"
-  "\x60\x65\xd4\x2b\x2e\x3b\xec\xdf\x5d\x65\x7a\xf9\x6d\x36\xfe\x5f"
-  "\x5e\xce\xc6\x7f\x41\xc6\x5d\xe6\x01\x97\xa7\xf5\x3c\x0f\x60\x3a"
-  "\x45\xeb\xe9\x71\x1e\x70\x79\x4b\xd7\x79\x40\x63\xb8\xe7\x79\xc0"
-  "\xd5\x95\x72\xbd\xba\x3a\x44\x3e\x0f\xb8\xdc\xf8\xd3\x99\x07\x78"
-  "\xd4\xb5\x08\xf9\x3c\xe0\xca\x21\xef\xe7\x01\x57\x2e\x7b\x37\x0f"
-  "\x40\xfd\x73\x37\x0f\xb8\xfa\xb0\xab\xfe\xc9\xe7\x01\x57\x67\xba"
-  "\x9f\x07\x5c\x5d\x24\x9f\x07\x60\xf9\xee\xe6\x01\x57\xb7\xc9\xca"
-  "\xef\x32\x0f\xb8\xfa\x81\x7c\x1e\xc0\xf2\x49\xf3\x00\xf3\x2c\xc1"
-  "\x0e\x73\xda\xfb\x79\x80\xf9\xd1\xee\xe7\x01\xe6\xc9\xf2\x79\x80"
-  "\x39\x8c\x61\xaa\x59\xc7\xe6\x01\xe6\x31\xc2\xfc\xa0\xc6\xf9\xbc"
-  "\x34\x0f\x60\xe7\xbb\xce\x03\xcc\xd9\x3d\xcc\x03\x02\x6c\x7b\x7c"
-  "\x8b\x3a\x46\xf8\x96\x74\x06\x47\x54\x3f\xd0\xf0\x3b\xbb\xc3\xbf"
-  "\x7e\x2c\x8c\xe9\xb5\xc0\x1d\xe6\x12\x25\xee\x69\x4f\xfb\x1c\x38"
-  "\xdb\x5c\xb6\x96\x1e\x79\xc2\xfe\x24\xe4\x09\x7a\x5f\xf4\x07\xd8"
-  "\x91\x17\x92\x6b\x1b\xe3\xaf\x47\xae\xd0\xbe\xc7\x37\xc3\x9a\xa7"
-  "\x6d\x6a\xc7\x75\xf4\xf1\x44\x39\xa7\xc5\x3d\x77\x58\x55\xcb\x73"
-  "\xa0\xf3\xfe\xd3\x67\x31\xde\x50\x19\xd7\x48\xf5\x18\x39\x03\xee"
-  "\x75\x30\x58\x8c\x94\x43\x04\xc4\x46\x92\x82\x34\x12\x3c\xa0\x85"
-  "\xa8\x07\x28\x14\x7e\x4f\x41\xeb\xdb\x81\x3f\x4c\x1e\xcd\x73\x0f"
-  "\xcc\x8b\x44\x9f\x34\x03\x19\x87\x28\xf5\xb5\x09\x1c\xe2\xcd\x1b"
-  "\x64\xcc\xce\x24\xe0\x0e\x95\x12\x77\x68\x17\xb9\x9d\x13\x6f\x78"
-  "\xe9\xb2\x9a\xec\xcc\x94\xaf\xa3\xef\xdc\x24\xf1\x06\xe4\x0c\xfc"
-  "\x1c\x2d\x19\x6f\x65\xeb\x24\x52\x9e\x61\x6b\x51\xc7\x34\xc0\xbc"
-  "\x64\x36\xf1\xaf\x88\xad\xc7\xbd\xe6\x61\x15\x0d\x6f\x93\x95\x4f"
-  "\x92\x7b\x6c\xc8\x13\x32\xf9\x92\x8a\x86\x2d\x04\xfd\xed\x01\x5f"
-  "\x8c\xc8\xbf\x41\x26\xe2\x78\x3c\x75\x2e\xe3\x0b\x6c\x2c\xbe\x36"
-  "\xfc\x84\xf6\x04\xf1\x9e\xeb\x5d\xa3\xdf\xdf\x3d\xee\x63\xdd\xe3"
-  "\x5b\x62\x1b\xe1\x9b\x61\x07\x59\x32\x3f\x8b\xe3\xd4\xdc\xbf\x47"
-  "\x99\xf7\x83\x1e\xbe\x57\xdf\xa4\x40\x9f\xd1\x18\x3f\x91\xdb\xeb"
-  "\xaf\x97\xc9\xa6\x53\x90\x4d\x27\x93\x0d\xca\x65\xb6\x8e\xa0\x7f"
-  "\xbe\x81\x28\x13\x83\xd5\x48\xb8\x55\x62\x0c\xc5\x70\x52\xc8\x31"
-  "\x79\xd8\x3b\xe3\xee\xe0\xa0\xed\xd1\x0f\x15\xe8\x03\xe5\x70\xeb"
-  "\x31\xae\xe2\x1a\xc5\x00\xe4\x70\xa0\xdf\xfd\x77\x75\x80\x1c\x2e"
-  "\x30\x39\xf0\x99\x6a\x7a\xb4\xad\xd2\x6a\xa0\xec\xfb\x3a\x3b\x41"
-  "\x16\x56\x57\x59\xec\x4d\xc5\xf8\x8b\xe8\x23\xce\xb6\x89\xf9\xc1"
-  "\xa3\xb2\x58\xa5\x1d\x86\x7e\x26\xe8\x5e\x94\x4e\x2d\xe2\xa5\xba"
-  "\xf0\x12\xee\xa1\x61\x32\xb0\x0b\x6d\x8f\xb1\x18\xb1\xbd\x91\x9f"
-  "\x19\x80\x97\xd1\xbd\x21\x59\xe6\x82\xce\xb7\x7d\x33\x70\x0d\xcb"
-  "\x15\x45\xeb\xce\xbe\xf1\xa0\xd6\x82\xdb\xdf\xf6\x9a\x9f\x60\xdb"
-  "\x5f\x8b\x93\xda\xfe\xfa\x90\xbe\xb5\xfd\xf5\xb0\xdb\xdf\xf6\xea"
-  "\x9f\x60\xdb\xb7\x36\x48\x6d\x7f\xa3\x8f\xfc\xff\x46\x5e\x77\x6d"
-  "\xff\xff\xd9\xfb\xfe\xb8\x28\xea\xfc\xff\x37\x33\x8b\xa2\xa2\x80"
-  "\xc1\xee\x6a\x5a\x6b\x87\xb6\xdc\x69\x62\x61\xe1\x9d\x5e\x58\x78"
-  "\xe1\xa5\x82\xa5\x85\xa6\x89\x8a\xb5\x16\xea\xfa\x1b\x7f\x01\x7a"
-  "\xda\xa9\x87\x08\x05\x7e\xb0\x50\xb1\xac\xd3\x0e\x8d\x3a\xec\xb0"
-  "\xd3\x6b\xbd\xf4\x73\x58\x08\xd8\x47\xef\xac\x83\x6b\xf3\xd0\xd0"
-  "\xd0\x56\x45\xf9\xb5\xbb\xf3\x7d\xbd\xe7\x3d\xcb\xec\xec\xce\x2c"
-  "\x3b\xb3\x4a\xd8\xd7\x3f\xe6\x01\x3b\xf3\x9e\xf7\xbc\xdf\xaf\xe7"
-  "\xf3\xfd\x7a\x3f\x5f\xef\x79\xbf\xdf\x83\xc7\x91\x1c\x63\x48\x8e"
-  "\xf1\x23\xdc\xc7\x91\x58\xc5\x1e\xcb\xcf\x69\xb4\xc7\x3a\xcf\x69"
-  "\x3c\x19\x8b\xd7\x76\x3b\xe6\x34\x36\xce\xf5\x3c\x6e\xd4\xba\x91"
-  "\x1f\x37\x6a\x3e\x4f\x74\x63\xf3\x09\xa2\x1b\x9b\xd9\x35\xde\x78"
-  "\x2d\x4f\xda\x45\x44\x7d\xb0\xcc\x4c\xe1\x3d\x6e\xb7\x40\xff\x8a"
-  "\x6d\x0c\x9a\xeb\xfe\x4b\x7e\xcd\x7e\x78\x4c\xe8\xd3\x9b\x66\x2a"
-  "\x1b\xae\xb1\x7d\xd8\x03\xb1\x96\xa2\xbe\x16\x3f\xdc\x8f\xe1\x7d"
-  "\x45\x19\xa7\xf5\x7a\xb6\x81\xfe\xc5\xd7\xdf\xf5\x2f\x74\xac\xc3"
-  "\xb1\xe5\x45\x57\x59\xf7\x07\x98\x44\x39\x83\xd7\x01\x02\x6f\xf0"
-  "\x9a\x3d\x07\x77\x58\xce\xb4\x40\xdc\xdb\x54\x87\xc7\x0c\x42\x83"
-  "\xea\x50\x30\x03\x9c\x79\x61\x1f\x94\xd3\x99\x37\xd9\x12\xbc\xd9"
-  "\x2e\xe4\xcd\x75\x8e\x37\xc0\x1f\x9e\x37\xfc\x1a\x3e\x24\x8b\x37"
-  "\xf5\x1c\x6f\x72\x5c\x78\x73\x59\x87\xbe\xa8\xae\xe1\x78\x73\x23"
-  "\xc9\x3a\xd0\xc1\x9b\xa6\x93\xc7\xa7\x01\x6f\xa6\xc9\xe5\x4d\x53"
-  "\xb9\x30\x96\xb5\x5f\x75\x8f\x65\x9b\x87\xb9\xc6\xb2\x8e\xd8\xf5"
-  "\x7a\xd8\x90\xaa\xeb\x10\xbf\x36\xb4\xc5\xaf\xcd\x93\x95\xf1\xb7"
-  "\x79\x92\x77\x73\xc2\x9a\x0f\xba\xce\x09\xdb\x9f\x86\xe3\xd2\xc6"
-  "\x14\xcc\x2d\xf1\xb8\x94\x5c\x73\x9f\xcb\xd3\x3a\x85\x9f\xcb\xd3"
-  "\x3a\xb0\xf3\xcf\x09\x6b\x39\x26\x1e\x1f\xb4\x9c\x24\x7a\xb3\xb9"
-  "\xe4\xf6\xac\x91\x68\x2e\x11\x8f\x45\x5b\xc7\x10\xad\xde\x5c\xea"
-  "\x3e\x2f\x0c\xee\x11\x8d\x45\x5b\x57\x70\xf7\x94\x08\x63\x51\x92"
-  "\x07\xf8\x90\x3c\xe9\x58\xd4\x3a\x8c\xf8\x14\xab\x1f\xf1\x29\x04"
-  "\x57\xf7\x58\xb4\xf5\xab\xf6\xe7\x85\x11\x1e\xb1\xe5\x94\x8c\x45"
-  "\xad\x03\xdc\x63\xd1\x46\x83\xf8\xbc\x30\x9b\x8d\xe7\x92\x6d\x87"
-  "\x70\x5e\x98\x75\xee\x9d\x31\x2f\x4c\x92\x5f\xc7\x1c\x58\xf1\x73"
-  "\xc3\x6c\xa3\xe4\xcf\x0d\xb3\x2d\x94\x17\x83\x62\xde\x89\xc5\xa0"
-  "\xb6\x23\xae\xbc\x13\xc6\xa0\xb6\xaf\xc4\x63\x50\xdb\x55\x61\x0c"
-  "\x8a\xf3\x17\x8b\x41\xed\xfd\x05\xf9\xbb\xc5\xa0\xf6\x11\xc2\x18"
-  "\x94\xa4\xe3\x63\x50\x7b\x35\xf1\xa5\x8d\x21\xf2\x63\x50\x3b\x3b"
-  "\xaf\x6d\xff\x9b\xe4\x5d\x8f\x30\xfe\xb4\x1f\x17\xc6\x9f\xf6\x7c"
-  "\xd2\xee\xed\x16\x32\x2f\xcc\x5e\x44\xce\x37\x06\x3b\x9f\xe7\xe3"
-  "\x4f\x72\x1e\xcf\x0b\x23\xf3\xc1\x18\x24\x2f\xee\x1c\xda\x09\xe3"
-  "\xce\x48\x0f\x71\x67\xe4\x9d\x19\x77\x52\x68\xbb\xa2\xb8\x93\x42"
-  "\xf9\x3f\xbe\xfe\xbe\x13\x63\x1f\x26\xb4\x4d\x7f\x53\x54\x98\x22"
-  "\xfd\x42\x51\xa1\x3f\xbe\xed\xef\xc0\xd8\x67\x33\x32\xf3\xb6\xa7"
-  "\x73\x94\xd9\x9e\xce\x56\x1c\xfb\x50\x3d\x62\xda\x62\x1f\xf8\x5f"
-  "\x32\xf6\xa1\x54\x73\x3c\xc6\x3e\x54\xc0\xfa\xb6\xd8\x87\xea\xf2"
-  "\x2d\xab\x53\xa8\x2e\xc7\x59\x9d\x42\x75\xd9\xd0\x6e\xec\x43\xf9"
-  "\xdb\xee\xc6\x3e\x32\x62\x9f\xcd\xd4\xb4\xb6\xd8\x87\xf2\x3f\xa1"
-  "\x28\xf6\xa1\xfc\x85\x6b\xc5\xa9\x1e\x97\xdd\x62\x1f\xaa\xcb\x10"
-  "\xaf\x63\x1f\xaa\xcb\x44\x65\xfc\xed\x92\xe0\x55\xec\x43\x75\xf9"
-  "\x50\x34\xf6\xa1\x54\x06\xc9\xd8\x87\xbb\xe6\xa6\x57\xa9\x80\xc9"
-  "\x6d\x7a\x95\x0a\x18\xd0\xe9\x63\x1f\xaa\xab\x49\x54\x9b\x52\x5d"
-  "\x4f\xb0\x5a\x87\xea\x52\x7c\x5b\x62\x1f\xc8\x57\x34\xf6\xa1\x02"
-  "\x46\xb3\x1a\x91\xea\x52\xe2\x16\xfb\xe0\x7b\xc4\x62\x1f\x2a\x60"
-  "\x29\x77\x4f\xb1\x20\xf6\xe1\xf2\x00\x1f\x92\x23\x19\xfb\x50\xdd"
-  "\x86\x10\x9f\x12\x60\x23\x3e\x85\xe0\xea\x16\xfb\x50\x01\x67\xda"
-  "\x8d\x7d\x38\x1e\xb1\xe5\x94\x8a\x7d\xa8\x6e\xfd\xdd\x62\x1f\x4a"
-  "\x95\x2c\x1a\xfb\x50\xdd\x9b\x79\x2e\x75\xdf\x2e\x88\x7d\xa8\x6e"
-  "\x73\xee\x88\xd8\x47\x9a\x5f\x26\xb7\xd8\x87\xea\x3e\x42\x76\xec"
-  "\x43\x75\x9f\x27\x2b\xf6\x61\x79\x27\x12\xfb\x50\xdd\x0f\xb9\xf2"
-  "\x4e\x10\xfb\x50\xdd\xcf\x88\xc6\x3e\x54\xf7\xcb\x82\xd8\x87\xcd"
-  "\x5f\x24\xf6\xa1\x7a\xf4\x11\xe4\xef\x1a\xfb\x50\x3d\x86\x0b\x62"
-  "\x1f\x2e\x5d\x5b\xec\x43\xf5\x38\x4b\x7c\xa9\xaa\xa7\xec\xd8\x87"
-  "\xea\x71\x48\x32\xf6\xa1\x7a\x1c\x15\xc4\x3e\x54\x8f\x5c\xd2\xee"
-  "\x7b\xd4\xb3\xb1\x0f\xd5\x63\x2f\x39\xaf\x0a\x74\x3e\xdf\x16\xfb"
-  "\x70\xe7\xdb\x62\x9f\xcd\x3d\xac\xf2\x62\x9f\xfb\x3b\x61\xec\xa3"
-  "\xf3\x10\xfb\xe8\xee\xd0\xd8\xa7\x67\x9e\xb2\xd8\xa7\xa7\xc7\xf1"
-  "\xef\xbb\xfa\x5b\x4a\x7f\x07\x06\xf3\xfa\x3b\x28\x44\x99\x7e\x09"
-  "\x0a\x56\xae\xbf\xd5\x26\x5e\x7f\xab\x4d\xd2\xfa\x3b\xe8\xbc\x67"
-  "\xfd\x1d\xaa\xe2\xf5\x77\xef\x99\xa4\xaf\xec\x3d\x86\xf4\x95\xbd"
-  "\xfd\xdb\xd7\xdf\x21\x6b\xee\xea\x6f\x39\xfa\xbb\x67\x35\xaf\xbf"
-  "\x43\xc6\x2a\xd3\xdf\x21\x71\x42\xfd\xad\x99\xe7\xae\xbf\x43\xf6"
-  "\x7b\xaf\xbf\x43\x4e\x29\xe3\x6f\x48\x95\x77\xfa\xbb\xf7\x30\x71"
-  "\xfd\x1d\x54\x27\xad\xbf\xc9\x35\x77\xcd\x74\xcf\x19\x5e\x33\xdd"
-  "\xb3\xbb\xf3\xeb\xef\x7b\x62\xc4\xf5\xd1\x3d\x63\x49\x7f\xdb\x3b"
-  "\xf2\xf6\xe8\xef\xde\x91\xe2\xfa\xfb\x9e\xa3\x44\xa7\xf4\x8e\x72"
-  "\xd7\xdf\x70\x8f\xa8\xfe\xbe\xe7\x06\x77\x4f\xa4\x50\x7f\x93\x3c"
-  "\xc0\x87\x84\x48\xeb\xef\xd0\xfd\xc4\xa7\x84\xae\x21\x3e\x85\xe0"
-  "\xea\xae\xbf\x43\x27\xb7\xaf\xbf\x09\x8f\xd8\x72\x4a\xea\xef\xd0"
-  "\x1d\xee\xfa\x3b\xa8\x56\x5c\x7f\xab\x57\xf0\x5c\x52\xf7\x11\xea"
-  "\xef\x50\xb7\xf9\x6f\x77\x18\xbf\x62\xdc\xf5\x77\x98\xcc\xf9\x6f"
-  "\xec\x3d\xf2\xe6\xbf\xb1\xbc\x13\xd3\xdf\xea\x11\xae\xbc\x13\xea"
-  "\x6f\xb5\xf8\xfc\x37\x4a\x2d\x9c\xff\xc6\xe6\x2f\xa6\xbf\xd5\xdb"
-  "\x05\xf9\xbb\xe9\x6f\xb5\x70\xfe\x1b\x97\x8e\xd7\xdf\x0e\xbd\x1b"
-  "\xb4\x45\xbe\xfe\xd6\x8c\x90\xd6\xdf\x9a\xd1\x42\xfd\xad\x09\x25"
-  "\xed\x5e\x93\x42\xf4\xb7\x46\x4f\xce\x07\x65\x3a\x9f\xe7\xf5\x37"
-  "\x39\xcf\xeb\x6f\xcd\x6a\x79\xfa\x3b\xa8\x13\xea\xef\x60\x0f\xfa"
-  "\x3b\xf8\x0e\xd5\xdf\x7d\xc2\x94\xe9\xef\x3e\x1e\xc7\xbf\x3d\x6b"
-  "\x40\xdd\x31\x5e\x03\xea\x8e\x49\x6b\xc0\x3e\x17\x3d\x6b\xc0\xfb"
-  "\x02\x78\x0d\xd8\x6f\x0e\xf1\xd7\xfd\xc6\x12\x7f\xdd\xaf\x5b\xfb"
-  "\x1a\xf0\xde\xb5\x77\x35\xa0\x1c\x0d\xa8\xc9\xe6\x35\xe0\xbd\xe3"
-  "\x95\x69\xc0\x7b\xc7\x09\x35\xe0\x00\xf7\xb5\x14\xd4\xbd\x1f\x7a"
-  "\xaf\x01\xef\x3d\xa3\x4c\x03\xde\x7b\xda\x3b\x0d\xd8\x6f\xb8\xb8"
-  "\x06\xec\x53\x2f\xad\x01\xc9\x35\xf7\x7e\xbb\x3f\xbf\xaf\x22\xd5"
-  "\xff\xdd\xce\xaf\x01\xfb\xc7\x8a\xf7\xd1\xfd\xc7\x13\x9f\xdf\x2f"
-  "\xea\xf6\x68\xc0\x7e\x51\xe2\x1a\xb0\xff\x71\xd2\x57\xf6\x8b\x76"
-  "\xd7\x80\x70\x8f\xa8\x06\xec\xdf\xcc\xdd\x13\x25\xd4\x80\x24\x0f"
-  "\xf0\x21\x61\xd2\x1a\xf0\xbe\x0f\x89\x4f\xb9\x6f\x2d\xf1\x29\x04"
-  "\x57\x77\x0d\x78\xdf\x94\xf6\x35\x20\xe1\x11\x5b\x4e\x49\x0d\x78"
-  "\xdf\x6e\x77\x0d\xd8\xa7\x4e\x5c\x03\xea\xd6\xf0\x5c\xd2\xf5\x17"
-  "\x6a\xc0\xfb\x2e\xde\x19\x1a\x50\x92\x5f\xb1\xee\x1a\xf0\xfe\x23"
-  "\xf2\x35\xe0\xfd\x57\xe5\x69\x40\xcc\x3b\x31\x0d\xa8\x1b\xe5\xca"
-  "\x3b\xa1\x06\xd4\x4d\x11\xd7\x80\xba\x85\x42\x0d\x88\xf3\x17\xd3"
-  "\x80\xba\x1d\x82\xfc\xdd\x34\xa0\xee\x90\x50\x03\x92\x74\xbc\x06"
-  "\x1c\x40\xd6\x40\x50\x7d\x72\xe4\x6b\xc0\x01\xa3\xa4\x35\xe0\x00"
-  "\xe1\xfa\x07\x6a\x00\x59\xff\x40\x0d\x30\x12\x0d\x38\x80\xac\x7f"
-  "\xa0\xfa\x64\x3b\x9f\xe7\x35\x20\x39\xcf\x6b\xc0\x01\xed\xad\x7f"
-  "\x6e\x47\x37\x44\x04\xf2\xba\x21\x22\xd0\x59\x37\x9c\x38\xe6\xac"
-  "\x1b\x1e\x18\xe0\x59\x37\x0c\x9a\xc4\xeb\x86\xf0\x83\xa4\x8d\x87"
-  "\x6f\x27\x6d\x3c\x9c\xc5\xb2\xf5\xbd\xae\x55\x6b\x4e\x22\xea\xc0"
-  "\x95\x52\xea\x0f\xcb\x90\x2a\x73\x19\xe8\x06\xd0\x6a\xc6\xa9\x58"
-  "\x37\xfc\xec\xd4\xf8\xd5\xdf\x30\x81\x05\xa0\x49\x6b\x39\x8d\x6a"
-  "\x04\x8d\x5a\x0b\xbf\xa1\xbd\x1c\x99\x5f\x4a\x55\x80\x8e\xcc\x06"
-  "\x1d\xc7\xae\x99\x65\xd7\xd3\x9a\xfd\xd9\xef\x1d\x5c\x69\x62\xbf"
-  "\x9d\xe3\xf5\x77\x28\x6a\xb9\xef\x50\x24\x0b\xbf\x43\x81\xbf\x3f"
-  "\x81\xbf\x45\x51\xb0\x08\x85\x62\x8d\x8a\xb5\x44\xaf\xb5\x7e\xbd"
-  "\xf0\xb7\x28\x7a\x35\x10\x1d\xba\xdf\x5e\x46\x74\xe8\x62\x6d\xf7"
-  "\xcc\x6b\x68\xf0\xce\x6b\xbc\x86\x78\x03\xeb\x87\xc5\x7a\x5d\xc3"
-  "\x62\xfd\x7d\xd7\xaf\xeb\x1f\x70\xff\x06\xc5\xfb\x93\xf0\x37\x28"
-  "\xf0\x77\xfb\xac\x9c\x0e\x65\x5e\xd6\xa3\x5d\x2f\x81\xa6\xa9\x47"
-  "\x7e\x0f\xe1\xfd\xc0\xfb\x41\xd9\x4f\xa2\x60\xdb\x75\x7d\x3f\xe7"
-  "\x7d\x0f\xa1\xec\xc1\xf6\xeb\x7a\x54\x9e\xf4\x35\xbb\x4e\xd3\xca"
-  "\xad\xd3\xb4\x2c\xd6\x53\x90\x67\xf4\x9b\x8b\x9c\x74\x68\x98\x43"
-  "\x87\xfe\x6c\x87\x32\x1d\xfa\xb3\x02\xa1\x9e\x88\x38\xe4\xae\x27"
-  "\xc2\xdd\xf6\xff\x96\xd6\x13\xe1\x03\x95\xe9\x89\xf0\x70\xef\xf4"
-  "\x44\xf8\x06\x57\x3d\xb1\x0f\xaf\xb3\xa4\x1e\x08\xc7\x9c\x13\xd7"
-  "\x13\xe4\x9a\x7b\x1f\x30\x68\x20\xdf\x07\x0c\xbc\xda\xf9\xf5\xc4"
-  "\xc0\x5c\x71\x7f\x3f\x70\x07\xbb\xc7\x21\x15\xbe\xfe\x96\xef\x71"
-  "\x08\x79\x8a\x6b\x89\x41\x21\xc4\xe7\x86\xaf\x77\xf4\x35\xbc\x96"
-  "\x80\x7b\x44\xb5\xc4\xa0\x31\xae\xf7\x10\x2d\x11\xbe\x91\x68\x89"
-  "\x41\x33\xa5\xb5\xc4\x20\x1b\xf1\x33\x83\x4e\x12\x3f\x43\x30\x75"
-  "\xd7\x12\x83\xde\x6d\x5f\x4b\x10\x0e\xb1\xe5\x94\xd4\x12\x83\x2e"
-  "\xbb\x6b\x89\x07\x74\xe2\x5a\x42\x7f\x9c\xe7\x91\x7e\x8e\x50\x4b"
-  "\x3c\x38\xfc\xce\xd0\x12\x92\xdc\xca\x15\xea\x08\xbd\xbf\x7c\x1d"
-  "\xa1\x1f\x21\x4f\x47\x60\xce\x89\xe9\x08\xfd\x06\x8e\x3f\x1b\xc5"
-  "\x75\x84\x7e\xb7\xb8\x8e\xd0\x1f\x12\xea\x08\x9c\xbf\x98\x8e\xd0"
-  "\x9f\x17\xe4\xef\xa6\x23\x22\xfc\x84\x3a\x82\xa4\xe3\x75\x44\xc4"
-  "\x1e\x2e\x26\x3b\x21\x5f\x47\x44\x6c\x90\xd6\x11\x11\x5b\x84\x3a"
-  "\x22\x22\x89\xe8\x85\x88\x52\xa2\x23\x22\x96\x70\xfa\xa2\xcc\xf9"
-  "\x3c\xaf\x23\xc8\x79\x5e\x47\x44\x94\xdd\x5d\x3f\xd9\x19\xc7\x92"
-  "\x7e\x31\x53\x59\x1f\xfe\x8b\xa4\x1f\xff\x5d\xee\x1d\xb8\x7e\x72"
-  "\x73\x44\x35\xff\x2e\x77\x70\x8d\x32\xdd\x32\xb8\xfa\xc7\xb7\xfd"
-  "\x1d\x38\x87\x78\xf3\x2f\xf6\xf2\xb6\x7f\x68\x8a\x32\xdb\x3f\xe4"
-  "\xf9\xfb\xb7\x77\xe7\x30\x48\xd8\x7e\x48\x38\x6f\xfb\xa1\x0a\xc7"
-  "\xff\x86\x9e\x56\x3e\x7e\xfd\x58\x2e\x1f\x87\x3e\x96\x2b\x3d\x7e"
-  "\x1d\xb9\xcf\x73\x1c\x1a\x55\xcd\xc7\xa1\x8f\x8c\x22\xfa\xf0\x91"
-  "\x01\x44\x1f\x3e\xcc\xee\xe5\x6f\x7d\xe0\x49\x33\x19\xbf\x36\x89"
-  "\x8c\x5f\x3f\x3c\x05\xef\x7d\xd5\xb6\x27\x16\x15\x79\xde\x79\x4f"
-  "\xac\xbf\xc1\x3d\x77\xc7\xb5\xbd\x19\xd7\x7e\xa8\x90\x1f\xd7\x7e"
-  "\x78\xa0\xb2\x71\xed\x87\xc3\x85\x71\x68\xf4\x68\xf7\x38\xf4\xe1"
-  "\x4d\xde\xc7\xa1\x0f\xef\x57\xc6\xeb\x87\x8b\xbc\x8b\x43\x1f\xe9"
-  "\x29\x3e\xae\x1d\x59\x84\x39\x27\x1e\x87\x92\x6b\xee\xf1\x43\xd4"
-  "\x7e\x3e\x7e\x88\x5a\xd1\xf9\xe3\xd0\xa8\x7e\xe2\xb1\x42\xd4\x40"
-  "\x12\x87\x3e\x12\x78\xeb\xe3\xd0\x47\x02\xc5\xe3\xd0\x28\xee\xfd"
-  "\xef\x23\xc1\xee\x63\xda\x70\x8f\x68\x1c\x1a\x75\x92\xbb\x27\x50"
-  "\x18\x87\x92\x3c\xc0\xaf\x5c\x94\x8e\x43\x87\x6f\x20\x7e\x66\xf8"
-  "\x64\xe2\x67\x08\xa6\xee\x71\xe8\xf0\x21\xed\xc7\xa1\x84\x43\x6c"
-  "\x39\x25\xe3\xd0\xe1\x4b\xdd\xe3\xd0\xc8\xbd\xe2\x71\xe8\x63\xe3"
-  "\x79\x1e\x3d\x7a\x59\x18\x87\x0e\x3f\x72\x67\xc4\xa1\x92\xdc\xea"
-  "\x27\x8c\x43\x1f\xdd\x22\x3f\x0e\x7d\xf4\xa8\xbc\x38\x14\x73\x4e"
-  "\x2c\x0e\x7d\xac\xa7\x2b\xe7\x84\x71\xe8\x63\x11\xe2\x71\xe8\x63"
-  "\xa3\x85\x71\x28\xce\x5f\x2c\x0e\x7d\x6c\x9e\x20\x7f\xb7\x38\xf4"
-  "\xb1\x4d\xc2\x38\x94\xa4\xe3\xe3\xd0\xe8\xc1\x5c\x7f\x36\x51\x7e"
-  "\x1c\x1a\xdd\x53\x3a\x0e\x8d\x0e\x13\xc6\xa1\x8f\xd5\x91\x78\x33"
-  "\x3a\x86\xc4\xa1\x8f\x59\xc9\xf9\xc8\x04\xe7\xf3\x7c\x1c\x4a\xce"
-  "\xf3\x71\x68\x74\xc2\xdd\xf5\x94\x9d\x31\x0e\x1d\x71\x51\x59\x1c"
-  "\x3a\xa2\xee\xc7\xd7\xe3\x77\x62\x2c\x14\x9d\xcc\xeb\xf1\x5f\xcd"
-  "\x51\xa6\x5b\x7e\x95\xfc\xe3\xdb\xfe\x4e\x8c\x85\x7e\x19\xc9\xdb"
-  "\x7e\xe4\xb7\xca\x6c\x3f\xd2\xac\x3c\x16\x8a\x2d\xe4\x63\xa1\xd8"
-  "\x42\xe9\x58\x68\xd4\x41\xcf\xb1\xd0\xe8\x3a\x3e\x16\x8a\x19\x4b"
-  "\x34\x4a\xcc\x10\xa2\x51\x1e\xbf\xdc\x7e\x2c\xf4\xf8\x1c\x61\x2c"
-  "\x34\xea\xea\xdd\x58\x48\x49\x2c\xf4\xab\x22\x3e\x16\x7a\x7c\x98"
-  "\xb2\x58\xe8\xf1\x48\x61\x2c\x34\x66\xbc\x7b\x2c\xf4\x78\x9e\xf7"
-  "\xb1\xd0\xe3\x87\x94\xf1\xfa\xf1\x52\xef\x62\xa1\x98\x3e\xe2\xb1"
-  "\xd0\xa8\x52\xe9\x58\x88\x5c\x73\xd7\xb0\xa3\x0f\xf1\x1a\x76\xf4"
-  "\x86\xce\x1f\x0b\x8d\xd6\x8b\xeb\xd5\xd1\xc3\x48\x2c\x14\xa3\xbd"
-  "\xf5\xb1\x50\x8c\x56\x3c\x16\x1a\xfd\x2e\xd1\x8d\x31\xfd\xdc\x63"
-  "\x21\xb8\x47\x34\x16\x1a\xfd\x15\x77\x8f\x56\x18\x0b\x91\x3c\xc0"
-  "\xaf\xdc\x90\x8e\x85\x9e\xc8\x21\x7e\xe6\x89\x99\xc4\xcf\x10\x4c"
-  "\xdd\x63\xa1\x27\x46\xb4\x1f\x0b\x11\x0e\xb1\xe5\x94\x8c\x85\x9e"
-  "\x58\xeb\x1e\x0b\x8d\x2a\x11\x8f\x85\x62\xf9\xbd\x8a\xa8\x27\x9b"
-  "\x85\xb1\xd0\x13\x27\xee\x8c\x58\x48\x92\x5b\x7a\x61\x2c\xf4\xe4"
-  "\x76\xf9\xb1\xd0\x93\x27\xe5\xc5\x42\x98\x73\x62\xb1\x50\x6c\x1f"
-  "\x57\xce\x09\x63\xa1\xd8\xe1\xe2\xb1\x50\xac\xf3\xfe\xb7\x5c\xfe"
-  "\x62\xb1\x50\xec\x0a\x41\xfe\x6e\xb1\x50\x6c\x9e\x30\x16\x22\xe9"
-  "\xf8\x58\x68\x4c\x34\xd7\x9f\x4d\x97\x1f\x0b\x8d\xe9\x23\x1d\x0b"
-  "\x8d\x19\x20\x8c\x85\x62\x1b\x48\xcc\x33\x66\x1c\x89\x85\xc6\x70"
-  "\xe7\x47\x4d\x73\x3e\xcf\xc7\x42\xe4\x3c\x1f\x0b\x8d\x99\x76\x77"
-  "\x7d\x65\x67\x8c\x85\x7e\x73\x43\x59\x2c\xf4\x9b\x86\xbb\x7a\x5c"
-  "\x89\x1e\x1f\x63\xe4\xf5\x78\xdc\x42\x65\xba\x25\xce\xa8\x5c\x8f"
-  "\x27\x44\xf2\x7a\x3c\x21\x52\x5a\x8f\x8f\x1d\xe3\x59\x8f\x8f\x4f"
-  "\xe5\xf5\xf8\xd3\x5f\x91\x7e\xf2\xe9\x23\xa4\x9f\x7c\x7a\x4d\xfb"
-  "\x7a\xfc\xb7\x37\x84\x7a\x7c\xec\xda\xbb\x7a\x5c\x89\x1e\x7f\x6a"
-  "\x24\xaf\xc7\x7f\x7b\x54\x99\x1e\xff\xad\x49\xa8\xc7\x13\x6a\xdc"
-  "\xf5\xf8\xd3\x03\xbd\xd7\xe3\x4f\x8f\x55\xc6\xeb\xa7\xe3\xbc\xd3"
-  "\xe3\x4f\xef\x13\xd7\xe3\x63\xe3\xa4\xf5\x38\xb9\xe6\xae\xa3\xc6"
-  "\x8f\xe5\x75\xd4\xf8\xb0\xce\xaf\xc7\xc7\x95\x8a\x6b\xa6\x71\x47"
-  "\x89\x1e\x7f\x7a\xef\xad\xd7\xe3\x4f\xef\x15\xd7\xe3\xe3\x87\x13"
-  "\xed\xf2\x74\x91\xbb\x1e\x87\x7b\x44\xf5\x38\x78\x43\x72\xcf\x5e"
-  "\xa1\x1e\x27\x79\x80\x5f\xd9\x20\xad\xc7\x27\x0c\x20\x7e\x66\xfc"
-  "\x55\xe2\x67\x08\xa6\xee\x7a\x7c\xfc\x89\xf6\xf5\x38\xe1\x10\x5b"
-  "\x4e\x49\x3d\x3e\x21\xc4\x5d\x8f\x8f\x8d\x15\xd7\xe3\xf1\x17\x79"
-  "\x1e\xc5\x6f\x12\xea\xf1\x09\x53\xee\x0c\x3d\x2e\xc9\xad\x52\xa1"
-  "\x1e\x8f\x8f\x90\xaf\xc7\xe3\xa7\xcb\xd3\xe3\x98\x73\x62\x7a\x3c"
-  "\x7e\x9f\x2b\xe7\x84\x7a\x3c\xfe\xb8\xb8\x1e\x8f\xaf\x11\xea\x71"
-  "\x9c\xbf\x98\x1e\x4f\xe8\x26\xc8\xdf\x4d\x8f\x27\x0c\x14\xea\x71"
-  "\x92\x8e\xd7\xe3\x09\x65\xc4\x87\xc6\x5d\x96\xaf\xc7\x13\xf6\x49"
-  "\xeb\xf1\x84\x0f\x85\x7a\x3c\x61\x3d\xd1\xdd\x09\xd5\x44\x8f\x27"
-  "\xe4\x93\xf3\x71\xf5\xce\xe7\x79\x3d\x4e\xce\xf3\x7a\x3c\xa1\xfe"
-  "\xee\x7a\xcb\xce\xa8\xc7\x9f\xd9\xa0\x4c\x8f\x3f\xb3\x5e\xb9\x26"
-  "\x9c\xca\xef\xf7\x0d\xff\x4b\x6b\xc2\x67\xa7\x78\xd6\x84\xcf\x67"
-  "\xf2\x9a\x70\xf2\x65\xe2\xab\x27\x9f\x22\xbe\x7a\x72\x4e\xfb\x9a"
-  "\x70\x72\x37\xa1\x26\x7c\x36\xef\xae\x26\x54\xa2\x09\x27\x22\x5e"
-  "\x13\x4e\x3a\xa3\x4c\x13\x4e\x3a\x2d\xd4\x84\x53\xdd\xf7\x01\xa7"
-  "\x26\x8f\xf0\x5e\x13\x4e\x9e\xae\x4c\x13\x4e\x9e\xe6\x9d\x26\x9c"
-  "\x7c\x44\x5c\x13\x3e\x3b\x4d\x5a\x13\x92\x6b\xee\x7d\xf9\xf3\xd3"
-  "\xf9\xbe\xfc\xf9\x88\xce\xaf\x09\x9f\x2b\x17\xef\xb7\x9f\x3b\x43"
-  "\x34\xe1\xe4\xc3\xb7\x5e\x13\x4e\x3e\x2c\xae\x09\x9f\x1f\x4b\xfa"
-  "\xcf\xc9\x26\x77\x4d\x08\xf7\x88\x6a\xc2\xe7\xd7\x70\xf7\x1c\x16"
-  "\x6a\x42\x92\x07\xf8\x95\xed\xd2\x9a\x30\x71\x38\xf1\x33\x89\xfe"
-  "\xc4\xcf\x10\x4c\xdd\x35\xe1\xf3\x35\xed\x6b\x42\xc2\x21\xb6\x9c"
-  "\x92\x9a\x30\x71\xa0\xbb\x26\x7c\x36\x51\x5c\x13\x4e\xe1\xf7\x00"
-  "\xa7\xa6\x08\xf7\x00\xa7\x12\xe7\xdd\x19\x9a\x50\x92\x5b\xe5\x42"
-  "\x4d\x38\x45\xfe\xfe\xdf\xd4\x14\x79\xfb\x7f\xb3\x9c\x13\xd3\x84"
-  "\x53\x8e\xb8\x72\x4e\xa8\x09\xa7\x88\xef\xff\x4d\x4d\x11\xee\xff"
-  "\xcd\xe6\x2f\xa6\x09\xa7\xf6\x17\xe4\xef\xa6\x09\xa7\x0a\xf7\xff"
-  "\xe6\xd2\xf1\x9a\x70\x6a\x35\xd7\x9f\xf9\xc9\xd7\x84\x53\xa5\xf7"
-  "\xff\xa6\xa6\x0a\xf7\xff\xa6\xa6\x92\xfd\xbf\xa9\xa9\x64\xff\x6f"
-  "\x6a\x2a\xd9\xff\x9b\x7a\x16\x39\x9f\xe7\x35\x21\x39\xcf\x6b\xc2"
-  "\x17\xda\xdd\xff\xdb\xb3\x8e\x98\xb5\x87\xd7\x11\xb3\xf6\x38\xeb"
-  "\x08\xe1\xfa\xcb\x17\x76\x7b\xd6\x11\x33\xea\x79\x1d\xf1\x22\xf9"
-  "\xde\x2c\xf5\x22\xf9\xde\x2c\x35\x9d\xc5\xac\x15\xda\x38\x59\x7f"
-  "\x59\x4c\x81\xa6\xe3\xd7\x5f\xbe\x88\x75\xc4\xf4\xb9\xe3\x05\x3a"
-  "\xe2\x85\x6f\xd9\xb5\x98\x58\x4b\x34\x34\x21\x7c\x4d\x7c\x5d\x66"
-  "\x71\xc7\xae\xcb\xbc\xf9\x53\x58\x97\x39\x7d\xb8\x32\xbd\x3a\x3d"
-  "\x4a\xa8\x2f\x66\x4f\x74\xd7\x17\xd3\xb7\x7b\xaf\x2f\xa6\x1f\x51"
-  "\xa6\x2f\xa6\x1f\xf6\x4e\x5f\xbc\xd8\x5f\x7c\x5d\xe6\x0b\x7b\x5a"
-  "\x25\xf5\xc5\x0b\xec\x7c\x07\xf7\x7e\x61\xc6\x11\xbe\x5f\x98\xb1"
-  "\xa9\xf3\xeb\x8b\x19\x83\xc5\xfb\x80\x19\xc3\x89\xbe\x78\xb1\xdf"
-  "\xad\xd7\x17\x2f\x8a\x7f\xef\x92\x9a\xc1\xc5\xff\x2f\xb6\x7d\xbb"
-  "\x92\xd7\x17\x2f\x8a\x7f\xef\x92\x9a\x51\xe3\x7a\x0f\xd1\x17\x2f"
-  "\xea\x88\xbe\x98\xd1\x2c\xad\x2f\x92\xf2\x88\xff\x49\x9a\x43\xfc"
-  "\x0f\xc1\xd4\x5d\x5f\x24\x8d\x6a\x5f\x5f\x10\x0e\xb1\xe5\x94\xd4"
-  "\x17\x49\x1b\xdc\xf5\xc5\x0b\x85\xe2\xfa\x62\x96\x93\x4e\x9d\x69"
-  "\x13\xea\x8b\xa4\x93\x77\x86\xbe\x90\xe4\xd6\x60\xa1\xbe\x98\xb9"
-  "\x43\xbe\xbe\x98\x79\x4a\x9e\xbe\x78\x51\xfc\x1b\x97\xd4\x2c\xae"
-  "\xff\x27\x7c\x71\xd7\x17\xb3\x46\x88\xeb\x8b\x59\x13\x85\xfa\xe2"
-  "\x45\xf1\x6f\x5c\x52\xb3\xd6\x08\xf2\x77\xd3\x17\xb3\xb6\x0b\xf5"
-  "\x05\x49\xc7\xeb\x8b\xd9\x23\xb9\x7e\x6e\xac\x7c\x7d\x31\xbb\xbf"
-  "\xb4\xbe\x98\x3d\x50\xa8\x2f\x66\x35\x11\x1d\x31\x3b\x81\xe8\x8b"
-  "\xd9\x81\xe4\xfc\x0b\x71\xce\xe7\x79\x7d\x41\xce\xf3\xfa\x62\x76"
-  "\x92\x8c\x31\xa7\xd3\x72\xd6\x65\xee\xbf\x29\x1c\x73\x72\x8c\x37"
-  "\x59\x07\x07\x1c\x6b\x1b\x73\x82\xbe\x5e\xea\x9b\xd8\x78\xcc\x09"
-  "\xf7\xdd\xfc\x98\x53\x0d\xeb\xab\xf8\x31\x27\x33\x3b\xe6\x84\xc7"
-  "\x9b\x20\x3e\x6f\x1b\x6f\xb2\x2f\x77\x5f\x93\xb9\xdf\x2e\x7f\xbc"
-  "\xe9\xc5\x85\xc1\x68\x27\xdb\x7f\x1f\x28\x21\xe3\x4d\x67\xdb\xc6"
-  "\x9b\x70\xbf\x6d\x6b\x74\x1f\x6f\xc2\xfd\x35\x3f\xde\xf4\xb5\xc2"
-  "\xf1\xa6\x64\x85\xef\x7f\x93\x3b\xc1\xfb\xdf\x3b\x71\x4d\xe6\xec"
-  "\x25\xfc\xfb\xdf\x97\x14\xbe\xff\x7d\xc9\xe3\xfb\xdf\xbb\xf3\x90"
-  "\xa5\x6c\x3f\x67\x24\x6f\xfb\x97\x2f\x2b\xb3\xfd\xcb\xf5\x3f\xbe"
-  "\xed\xef\xc4\x79\x0f\x2f\x95\xf2\xb6\x9f\x3b\x57\x99\xed\xe7\x1a"
-  "\x94\x8f\x71\x2f\x8c\xe3\x63\xd3\x85\x71\xd2\xb1\xe9\x2b\xa3\x3c"
-  "\xc7\xa6\xf3\xb3\xf9\xd8\x34\xe5\x2a\xd1\x86\x29\x67\x88\x36\x4c"
-  "\xc9\x73\x8c\x71\x93\xd8\xd4\x44\x61\xff\x8e\xc7\xae\x33\xc1\xa7"
-  "\xff\x01\xe2\xb2\x2d\x10\xa7\xfe\x61\x11\xc4\xaa\x46\x14\x50\x59"
-  "\x7b\x04\x19\xd3\x70\xbc\x9a\xd2\x33\x3e\xd5\x39\x5e\x7d\x65\x8b"
-  "\x23\x56\x8d\x87\x7b\x3f\x9d\x6f\xa2\x70\x4c\x6a\x0b\x23\xe3\xd8"
-  "\xd9\x90\x8f\x63\xfc\x1b\xf7\x7f\x07\xe6\x43\x6c\xfa\x8a\x70\x0c"
-  "\xbc\x75\x7f\xc0\xb1\xd6\xb0\xe8\xd3\x78\x1c\xbc\xf9\x5d\xff\x62"
-  "\xc7\x58\xb8\xa7\x31\x70\xcc\x2d\xd7\x71\xf0\x3b\x77\x0c\xdc\x10"
-  "\xc5\x8f\x81\xbf\xfa\x95\xb2\x31\xf0\x57\xcf\x0a\x63\xd4\x85\x37"
-  "\xdc\x63\xd4\x94\x51\xde\xc7\xa8\x29\x33\x95\xf1\x3e\x25\xc9\xbb"
-  "\x18\x35\xe5\xa8\x78\x8c\xfa\x4a\x8c\xf4\x18\x38\xb9\xe6\x1e\x5b"
-  "\xcc\x9f\xc9\xc7\x16\xf3\x87\x74\xfe\x18\x75\x5e\x95\x78\x1c\x31"
-  "\xef\x2b\x12\xa3\xa6\x98\x6e\x7d\x8c\x9a\x62\x12\x8f\x51\xe7\x8f"
-  "\x27\x7a\x3e\xc5\xe4\x1e\xa3\xc2\x3d\xa2\x31\xea\xfc\xb5\xae\xf7"
-  "\x90\x18\x35\xe5\x18\x89\x51\xe7\xef\x90\x8e\x51\x17\x8c\x20\x7e"
-  "\x68\x41\x37\xe2\x87\x08\xa6\xee\x31\xea\xfc\x6f\xdb\x8f\x51\x09"
-  "\x87\xd8\x72\x4a\xc6\xa8\x0b\x22\xdc\x63\xd4\x57\x46\x8a\xc7\xa8"
-  "\x0b\xfd\x78\x1e\x19\x77\x0b\x63\xd4\x05\x0b\xef\x8c\x18\x55\x92"
-  "\x5b\x55\xc2\x18\xd5\x38\x5a\x7e\x8c\x6a\x5c\x2a\x2f\x46\xc5\x9c"
-  "\x13\x8b\x51\x8d\xdc\xfe\xe7\x84\x2f\xee\x31\xaa\xb1\x46\x3c\x46"
-  "\x35\xde\x10\xc6\xa8\x38\x7f\xb1\x18\x75\xe1\x00\x41\xfe\x6e\x31"
-  "\xea\xc2\x51\xc2\x18\x95\xa4\xe3\x63\xd4\x85\x66\xe2\x43\xe7\x9e"
-  "\x97\x1f\xa3\x2e\x3c\x2a\x1d\xa3\x2e\x3c\x21\x8c\x51\x17\x16\x90"
-  "\x58\x74\x61\x03\x89\x51\x17\x16\x93\xf3\x73\x6b\x9d\xcf\xf3\x31"
-  "\x2a\x39\xcf\xc7\xa8\x8b\x54\x32\x62\xd4\xb3\xb7\x28\x46\x2d\xbb"
-  "\xb3\x62\xd4\x62\x43\xc7\xc6\xa8\x8b\x15\x7e\xff\x72\xb1\xb7\xdf"
-  "\xbf\x3c\xdd\x8e\x56\x3f\xf6\xff\x97\x56\x5f\xa4\xe5\xb5\xfa\x52"
-  "\x85\xdf\xbf\x5c\xea\xed\xf7\x2f\x6f\x9b\xed\xef\x3c\xbb\x2f\x76"
-  "\xfa\xf6\xe5\xb2\x2d\xca\xec\xbe\x2c\xf3\x6e\x7c\xaa\xc4\xf6\x4b"
-  "\xa7\xf1\xb6\x4f\xed\xa6\xcc\xf6\xa9\x01\xca\xe3\xd3\x8c\x00\x3e"
-  "\x3e\xcd\x08\x70\x8e\x4f\xcb\x04\x73\xb0\x52\x6b\x3c\xc7\xa7\x6b"
-  "\x12\xf8\xf8\x74\x15\xb7\x3f\xf5\xaa\x3c\xa2\x0b\x57\xb1\xdf\xa2"
-  "\x68\xc6\xf1\xe9\x68\x88\x4f\x2f\x65\xb7\xc5\xa7\x38\x1e\x1d\xdf"
-  "\xf4\x0d\x83\xdf\xa5\x42\x7c\xaa\xda\x74\x05\xa9\x20\x66\x45\x95"
-  "\xd5\x07\x51\x26\xc4\xab\x9b\xaf\x40\xcc\x9a\x02\x31\xab\x75\x07"
-  "\x17\xb3\xae\x3c\x29\x8c\x59\x57\x8c\x16\xc4\xac\xaf\x64\xb3\x31"
-  "\x2b\xc4\xa1\x26\x6b\x5e\x74\x15\x8e\x59\xad\x10\x8f\xb6\x0e\x09"
-  "\x38\x96\x7d\xc5\x25\x7e\x7d\x05\xe2\xd7\x97\x84\xf1\x6b\x4b\x5e"
-  "\xf4\xd9\xe6\xfd\x01\x65\xec\x3c\xae\x81\xde\xc5\xaf\xae\xb1\x6b"
-  "\x01\x37\x87\xeb\xad\x3b\x32\x7e\x5d\x76\x9a\x8f\x5f\x57\x6e\x57"
-  "\x16\xbf\xae\xcc\x17\xc6\xaf\x19\x07\xdd\xe3\xd7\x95\x36\xef\xe3"
-  "\xd7\x55\x03\x94\xb5\x8b\x55\x3a\xef\xe2\xd7\x55\x6b\x5d\xe3\xd7"
-  "\xbd\xec\x1c\xae\x54\x73\xb3\x64\xfc\x9a\x5a\x2d\xfe\x8e\x75\xcd"
-  "\x00\x3e\xee\x58\x7d\xb9\xf3\xc7\xaf\xab\xb3\xc5\x63\x8c\xd5\xdb"
-  "\x49\xfc\xba\x2a\xe3\xd6\xc7\xaf\xab\x32\xc4\xe3\xd7\x35\xdc\xfe"
-  "\x2f\xab\x32\xdc\xe3\x57\xb8\x47\x34\x7e\x5d\x33\xda\xf5\x1e\x12"
-  "\xbf\xae\x5a\x4f\xe2\xd7\x35\xd3\xa5\xe3\xd7\x35\xcd\xc4\x4f\xad"
-  "\x39\x41\xfc\x14\xc1\xd4\x3d\x7e\x5d\xb3\xbb\xfd\xf8\x95\x70\x88"
-  "\x2d\xa7\x64\xfc\xba\xe6\xa2\x7b\xfc\x9a\x5a\x2d\x1e\xbf\xa6\x1f"
-  "\xe5\x79\x94\x3e\x53\x18\xbf\xa6\x0d\xbb\x33\xe2\x57\x49\x6e\x65"
-  "\x0b\xe3\xd7\x74\x3f\xf9\xf1\x6b\xfa\x70\x79\xf1\x2b\xe6\x9c\x58"
-  "\xfc\x9a\xce\x8d\x7f\x10\xbe\xb8\xc7\xaf\xe9\x3b\xc4\xe3\xd7\xf4"
-  "\x83\xc2\xf8\x15\xe7\x2f\x16\xbf\xa6\x7f\x2b\xc8\xdf\x2d\x7e\x4d"
-  "\xb7\x09\xe3\x57\x92\x8e\x8f\x5f\x33\x0a\x89\x0f\x4d\xdd\x20\x3f"
-  "\x7e\xcd\x58\x2b\x1d\xbf\x66\x6c\x12\xc6\xaf\x19\xdc\x7a\xda\x8c"
-  "\x12\x12\xbf\x66\x18\xc9\xf9\xd4\xf5\xce\xe7\xf9\xf8\x95\x9c\xe7"
-  "\xe3\xd7\x8c\x63\xf2\xde\xb1\xfa\xb4\xe7\xd0\xb1\x8e\x9f\xd7\x7f"
-  "\xab\xf6\x1c\x72\xbc\x67\xed\xa8\x79\xfd\xeb\xa6\x2b\x8b\x61\xd7"
-  "\x4d\xbb\x1b\x47\xc9\xd5\xf2\x19\x67\x79\x2d\xff\x3b\x85\xfb\x7f"
-  "\xfe\xce\xe3\xfe\x9f\x77\xe3\x28\x29\xdb\xaf\xdb\xc3\xdb\x7e\xc3"
-  "\x44\x65\xb6\xdf\x90\xa0\x3c\x8e\xda\xe2\xb4\xbe\x79\x8b\x60\x7d"
-  "\xb3\xf0\x3d\xdf\x6b\x03\x3d\xc7\x51\x9b\x9d\xd6\x37\x6f\xe4\xd6"
-  "\x37\x6f\xe4\xd6\x37\x6f\x6c\x5b\xdf\x2c\xef\x3d\xdf\xef\x6f\x08"
-  "\x63\xa6\xd7\x96\xde\x7d\xcf\xe7\x6b\x9c\xb4\xbe\x1f\x1f\x27\xfd"
-  "\x5e\xe1\xfa\xe7\xdf\x9b\x84\x71\xd2\x16\x91\xf5\xcf\x1b\x65\xac"
-  "\x7f\xde\xa8\x70\xfd\xf3\x46\x2f\xd7\x3f\x6f\x74\x5b\xff\x4c\xde"
-  "\xf3\xbd\xa6\x97\x7e\xcf\x47\xae\xb9\xeb\xdb\xcd\x4e\xeb\x9f\x37"
-  "\xdf\x01\xeb\x9f\x37\x49\xac\x51\xdd\xc4\xad\x7f\xde\x78\x1b\xd6"
-  "\x3f\x6f\x94\x58\xff\xbc\x99\x5b\xff\xbc\x71\xaf\x7b\x9c\xb4\x51"
-  "\x62\xfd\xf3\xe6\xb9\xae\xf7\x90\x38\x69\x23\xb7\xfe\x79\xb3\x87"
-  "\xf5\xcf\x7f\xe0\xd6\x3f\x6f\xe6\xd6\x3f\x13\x4c\xdd\xe3\xa4\xcd"
-  "\x5e\xac\x7f\xde\xc8\xad\x7f\xde\xe8\x61\xfd\xf3\x1f\x44\xd6\x3f"
-  "\xbf\x16\x2e\x1e\x27\x65\x3a\xad\x7f\xce\x74\x59\xff\xfc\x87\x3b"
-  "\x64\xfd\xb3\x24\xb7\x5c\xd6\x3f\x67\x2a\x58\xff\x9c\x29\x73\xfd"
-  "\xf3\x46\x89\xf5\xcf\x99\xdc\xfc\xe7\x8d\x12\xeb\x9f\x33\x25\xd6"
-  "\x3f\x67\xba\xac\x7f\xde\x28\xb1\xfe\x79\x4b\x37\x41\xfe\x6e\x71"
-  "\xd2\x16\x97\xf5\xcf\x1b\x5d\xd6\x3f\x6f\xe1\xd6\x3f\x6f\x38\x29"
-  "\x3f\x4e\xda\xe2\x61\xfd\xf3\x16\x97\xf5\xcf\x5b\xb8\x78\x68\x0b"
-  "\xb7\xfe\x79\x0b\xb7\xfe\x79\x43\xb9\xf3\x79\x3e\x4e\x22\xe7\xf9"
-  "\x38\x69\x8b\x9c\xf5\xcf\xa7\xe5\xec\x47\xf4\xe3\xcf\x45\xd5\xdd"
-  "\xa1\x73\x51\xb7\xae\x55\x16\x23\x6d\xcd\xb8\xab\xd5\x95\x68\xf5"
-  "\x2c\xc4\x6b\xf5\x6c\x9b\x32\xcd\x92\x6d\x55\xae\xd5\xf3\xab\x79"
-  "\xad\x9e\x5f\x2d\xad\xd5\x73\x4e\x79\xd6\xea\xdb\xc2\x79\xad\x9e"
-  "\xcb\xed\x5f\x9e\x3b\x97\xf4\x91\xb9\x11\xca\xb4\xfa\x1b\xbb\x85"
-  "\x5a\xfd\xf5\x01\x77\xb5\xba\xaf\x5a\x7d\x6b\x19\xaf\xd5\xdf\x98"
-  "\xa7\x4c\xab\xbf\x91\x22\xd4\xea\xdb\x37\xb9\x6b\xf5\x37\x4e\x79"
-  "\xaf\xd5\xdf\xb8\xa1\x8c\xf7\x6f\x34\x78\xa7\xd5\x73\x27\x8b\x6b"
-  "\xf5\x9c\xd3\xd2\x5a\x9d\x5c\x73\xd7\x58\x79\x37\x78\x8d\x95\x77"
-  "\xb4\xf3\x6b\xf5\xbc\x64\x71\x3d\x95\x37\x8f\x68\xf5\xdc\x49\xb7"
-  "\x5e\xab\xe7\x4e\x12\xd7\xea\x79\xdc\xf8\x6f\xee\x24\x77\xad\x0e"
-  "\xf7\x88\x6a\xf5\x6d\x61\xae\xf7\x10\xad\x9e\x9b\x48\xb4\xfa\xb6"
-  "\x61\xd2\x5a\x7d\xdb\x49\xe2\x87\xb6\xed\x20\x7e\x88\x60\xea\xae"
-  "\xd5\xb7\x2d\x6d\x5f\xab\x13\x0e\xb1\xe5\x94\xd4\xea\xdb\x8e\xb8"
-  "\x6b\xf5\x9c\x2a\x71\xad\x9e\x9f\xc7\xf3\x28\x7f\xb8\x50\xab\xff"
-  "\x8f\xff\x9d\xa1\xd5\x25\xb9\x95\x2c\xd4\xea\xff\x73\x46\xbe\x56"
-  "\xcf\xef\x26\x4f\xab\x63\xce\x89\x69\xf5\xfc\xc9\x1c\x7f\x12\xc5"
-  "\xb5\x7a\xfe\x42\x71\xad\x9e\xbf\x49\xa8\xd5\x71\xfe\x62\x5a\x3d"
-  "\xff\xa0\x20\x7f\x37\xad\x9e\x7f\x4a\xa8\xd5\x49\x3a\x5e\xab\x6f"
-  "\x5f\x42\x7c\x68\xce\x0a\xf9\x5a\x7d\xfb\x64\x69\xad\xbe\x7d\xba"
-  "\x50\xab\x6f\x8f\x24\x9a\x7c\xfb\x46\xa2\xd5\xb7\xc7\x92\xf3\x39"
-  "\xa9\xce\xe7\x79\xad\x4e\xce\xf3\x5a\x7d\x7b\xfe\xdd\xbd\x8a\x3a"
-  "\xe3\x5e\x45\x6f\x0d\x53\xa6\xd7\xdf\x8a\x54\xae\x19\xdf\xb6\xf0"
-  "\x9a\xf1\x6d\x8b\xb3\x66\x14\xee\x55\x54\xe0\xef\x59\x33\x16\x46"
-  "\xf3\x9a\x71\xe7\x76\xe2\xab\x77\xae\x21\xbe\x7a\xe7\x28\x87\x66"
-  "\x94\xde\xab\x68\xc7\x41\xe1\x5e\x45\x05\xa3\xef\xee\x55\xa4\x44"
-  "\x13\x6e\x77\xda\x4f\x7e\xc7\x5a\x65\x9a\x70\x47\x86\x50\x13\xbe"
-  "\xb3\xc3\x5d\x13\xee\x38\xef\xbd\x26\xdc\xa9\x70\xfe\xd7\xce\x00"
-  "\xef\x34\xe1\xce\xb9\xe2\x7b\x15\x15\x04\x48\x6b\x42\x72\xcd\xbd"
-  "\x2f\x2f\xec\xc6\xf7\xe5\xbb\xce\x74\x7e\x4d\xb8\x2b\x55\xbc\xdf"
-  "\xde\xb5\x96\x68\xc2\x9d\x86\x5b\xaf\x09\x77\x1a\xc4\x35\xe1\xae"
-  "\x1b\xa4\xff\xdc\x99\xe2\xbe\x57\x11\xdc\x23\xaa\x09\x0b\x23\xb8"
-  "\x7b\x0c\x42\x4d\x48\xf2\x00\xbf\x32\x46\x5a\x13\x16\x7e\x4b\xfc"
-  "\x4c\xe1\x87\xc4\xcf\x10\x4c\xdd\x35\x61\xe1\xa6\xf6\x35\x21\xe1"
-  "\x10\x5b\x4e\x49\x4d\x58\x78\xca\x5d\x13\x16\xa8\xc4\x35\xe1\xdb"
-  "\xfb\x78\x1e\xbd\x3d\x56\xa8\x09\x77\xf7\xb9\x33\x34\xa1\x24\xb7"
-  "\x52\x85\x9a\x70\xf7\x45\xf9\x9a\xf0\xed\xfe\xf2\x34\x21\xe6\x9c"
-  "\x98\x26\x7c\x7b\xae\x2b\xe7\x84\x9a\xf0\xed\x0d\xe2\x9a\xf0\xed"
-  "\x1d\x42\x4d\x88\xf3\x17\xd3\x84\x6f\x9f\x10\xe4\xef\xa6\x09\xdf"
-  "\x3e\x2f\xd4\x84\x24\x1d\xaf\x09\xdf\xd9\x48\x7c\xe8\x5b\xfb\xe5"
-  "\x6b\xc2\x77\xe6\x4a\x6b\xc2\x77\x16\x0a\x35\xe1\x3b\xb1\x44\xfb"
-  "\xbd\x53\x40\x34\xe1\x3b\x89\xe4\xfc\x5b\x45\xce\xe7\x79\x4d\x48"
-  "\xce\xf3\x9a\xf0\x9d\x22\x79\xeb\x34\x6e\xc9\xf8\x6d\x07\xad\xd3"
-  "\xb8\x55\xe3\xb7\x1d\xbd\x4e\xe3\xdd\xd1\xca\xf4\xe0\xbb\x31\x77"
-  "\xe7\xb8\xc8\x1d\xbb\x7d\xc7\xc4\x8f\xdd\xbe\xa7\xf0\xfb\x37\xef"
-  "\x95\x2a\xd7\xe1\x07\x8a\x79\x1d\x7e\xa0\x58\x7a\xbe\xfa\x1f\xb7"
-  "\x78\xd6\xe1\x7f\x6a\xe2\x75\xf8\xfb\x53\x48\xff\xf8\xfe\x28\xd2"
-  "\x3f\xee\xb3\xb5\x3b\x5f\x7d\x19\x52\x65\x72\xf3\xd5\xff\x80\xe7"
-  "\xab\x9f\x3d\x8e\x32\xaf\x89\xcd\x57\xdf\xb7\x54\x38\x9e\xfb\xc7"
-  "\xab\x62\xf3\xd5\xd9\x79\xea\x79\xd1\xa7\xad\x52\xf3\xd4\x5f\xbc"
-  "\xb5\xf3\xd4\xdf\x02\xed\xee\x18\xd3\xc5\xbe\xe1\xce\xd3\xef\xef"
-  "\x6e\xe4\xf5\xfb\xbe\xd1\xca\xf4\xfb\xbe\x18\xa1\x7e\xff\x60\xba"
-  "\xbb\x7e\xdf\xf7\xae\xf7\xfa\x7d\xdf\x09\x65\xed\x61\x5f\x99\x77"
-  "\xfa\xfd\xfd\x08\xf1\x79\xea\x7f\xcc\x96\x9e\xa7\xfe\xc7\x4c\xf1"
-  "\x79\xea\x7f\x3a\xc1\xeb\xae\x3f\xe5\x75\x7e\xfd\xfe\xa7\x68\x71"
-  "\x8d\xf5\xa7\xd1\x44\xbf\xbf\xaf\xbf\xf5\xfa\xfd\x7d\xbd\xb8\x7e"
-  "\xff\x13\x37\xfe\xf5\xbe\xde\x7d\x4c\x17\xee\x11\xd5\xef\x7f\xba"
-  "\xe8\x7a\x0f\xd1\xef\xef\x0f\x26\xfa\xbd\xc8\x5f\x5a\xbf\x17\xed"
-  "\x26\xfe\xa9\x68\x21\xf1\x4f\x04\x53\x77\xfd\x5e\x34\xb6\x7d\xfd"
-  "\x4e\x38\xc4\x96\x53\x52\xbf\x17\xe5\xb8\xeb\xf7\x3f\x66\x8a\xeb"
-  "\xf7\x03\x73\x79\x1e\x1d\xe8\x26\xd4\xef\x45\x5f\xdd\x19\xfa\x5d"
-  "\x92\x5b\xd1\x42\xfd\xbe\x7f\x9f\x7c\xfd\xbe\xbf\x46\x9e\x7e\xc7"
-  "\x9c\x13\xd3\xef\x07\xb8\xf8\x8f\xf0\xc5\x5d\xbf\x1f\x18\x23\xae"
-  "\xdf\x0f\x4c\x17\xea\x77\x9c\xbf\x98\x7e\x3f\xb0\x49\x90\xbf\x9b"
-  "\x7e\x3f\xf0\xae\x50\xbf\x93\x74\xbc\x7e\xff\x20\x8e\xeb\xdf\x86"
-  "\xcb\xd7\xef\x1f\x44\x48\xeb\xf7\x0f\x86\x09\xf5\xfb\x07\x2a\xa2"
-  "\xd3\x3f\x98\x46\xf4\xfb\x07\x5a\x72\xfe\x8f\x51\xce\xe7\x79\xfd"
-  "\x4e\xce\xf3\xfa\xfd\x83\x14\x79\xf3\x2f\xbc\x1f\xd3\xfd\xf1\xe7"
-  "\x5f\x04\xdf\xa1\xf3\x2f\x3e\xf4\x53\xa6\xdf\x3f\x44\xca\x75\x64"
-  "\xe9\x59\x5e\x47\x96\x9e\x95\x9e\x03\xf0\xe1\x19\xcf\x3a\xf2\x63"
-  "\x1d\xaf\x23\x4b\xd6\x12\x3f\x5d\xc2\xed\xd9\x58\x32\x50\x6a\x0e"
-  "\x00\x5e\xef\xb8\x65\x11\x59\xeb\xd8\x36\x07\xa0\xfa\x0c\xa7\x19"
-  "\xff\xbc\x43\xa8\x19\x3f\x1a\x28\x36\x07\x40\xf4\xdd\xbf\xcb\x7a"
-  "\x46\xdb\x10\xf9\xef\xfe\x7f\x5a\xeb\x19\x3f\xc8\xe0\x75\xe2\x9f"
-  "\xe7\x2a\xd3\x89\x7f\x36\x08\x75\xe2\xa1\x0d\xee\x3a\xf1\xcf\x27"
-  "\xbd\xd7\x89\x7f\xbe\xaa\x4c\x27\xfe\xd9\xe2\x9d\x4e\x2c\x99\x28"
-  "\xfe\xee\xff\xc3\xb3\xd2\xe3\xbc\xe4\x9a\x7b\xff\x7e\xf0\x2a\xdf"
-  "\xbf\x1f\x3c\xd2\xf9\x75\xe2\xc1\x24\xf1\xbe\xfc\xe0\x5c\xa2\x13"
-  "\x4b\x12\x6e\xbd\x4e\x2c\x49\x10\xd7\x89\x07\xb9\xfd\x5f\x4b\x12"
-  "\xdc\x75\x22\xdc\x23\xaa\x13\x3f\x0e\x71\xbd\x87\xe8\xc4\x92\x49"
-  "\x44\x27\x7e\x3c\x44\x5a\x27\x7e\x7c\x82\xf8\x9f\x8f\xb7\x13\xff"
-  "\x43\x30\x75\xd7\x89\x1f\x2f\x6c\x5f\x27\x12\x0e\xb1\xe5\x94\xd4"
-  "\x89\x1f\x1f\x72\xd7\x89\x1f\x9e\x16\xd7\x89\xa5\x39\x3c\x8f\x4a"
-  "\x87\x09\x75\xe2\x5f\xfc\xee\x0c\x9d\x28\xc9\xad\x24\xa1\x4e\xfc"
-  "\xcb\x29\xf9\x3a\xb1\xd4\x5f\x9e\x4e\xc4\x9c\x13\xd3\x89\xa5\x13"
-  "\x39\xfe\x4c\x12\xd7\x89\xa5\xf3\xc4\x75\x62\xe9\x06\xa1\x4e\xc4"
-  "\xf9\x8b\xe9\xc4\xd2\x0f\x05\xf9\xbb\xe9\xc4\xd2\x93\x42\x9d\x48"
-  "\xd2\xf1\x3a\xf1\x90\x91\xf8\xd0\x0f\xd7\xc8\xd7\x89\x87\x26\x4a"
-  "\xeb\xc4\x43\x53\x84\x3a\xf1\xd0\x60\xa2\x07\x0f\xad\x27\x3a\xf1"
-  "\x50\x0c\x39\xff\xe1\x6a\xe7\xf3\xbc\x4e\x24\xe7\x79\x9d\x78\x28"
-  "\xd7\x93\x4e\x64\xb2\x6b\x4a\xb3\x29\x7b\x31\x1c\xa5\x50\xce\x3e"
-  "\xd0\x8f\x99\xe0\xff\x32\xe8\x8f\x82\xe1\xff\x2a\x29\x5d\x62\x09"
-  "\xa9\x29\xb5\x83\xc6\xb0\xc3\x73\x2a\x2d\x3f\x98\x4c\x7d\xad\xf0"
-  "\xec\x4f\x42\x89\xfe\xa8\x29\x0d\xb2\x76\x8d\xb3\x33\x06\xe8\xc3"
-  "\xe1\xff\x54\x38\x07\xe9\x7b\x41\xbf\xa7\x5b\x86\x7a\x5d\xa1\x3e"
-  "\x89\x72\xa4\x83\x32\xf7\x3a\x47\x1d\xba\x8a\xf3\x68\xdc\xfc\x49"
-  "\x0c\xd4\xa7\x50\xb2\xac\x90\x57\xfc\xbe\xfb\xd0\x1a\x2b\xf3\x9d"
-  "\x69\xfe\x35\x54\x4b\x7d\xb2\x29\xa8\xbe\x6b\x1c\xf8\x21\x84\x75"
-  "\x5d\x71\x5f\x8b\x0a\xe7\x69\x9a\xdf\x82\xaf\xa5\xe0\x6b\x36\x28"
-  "\x63\xda\x3c\x44\x65\x5d\xeb\x1a\x00\xfa\xc9\x3f\xbd\x81\xa9\x5b"
-  "\x60\x85\x32\xa7\x5a\xd1\xa7\xf7\x9d\x55\x7d\xf0\xe6\x59\xb6\xef"
-  "\xa9\x68\xb0\xb1\x79\xe8\xe6\xe3\xf2\x7c\xb2\x65\x27\xa4\x17\x2b"
-  "\xc3\x86\x03\x68\xb0\x7f\x04\x63\x96\xd7\xdf\x7d\x62\x96\xb2\x63"
-  "\xd0\xda\xfb\x90\xe9\xe7\x60\x3b\x1d\xa2\xc4\xae\xcb\x7b\xce\x5f"
-  "\xe3\x3c\xe8\xc8\x80\x37\xd4\x4c\x43\xfa\x76\x44\x6d\xb5\x77\x0d"
-  "\xf8\x0c\x58\xb2\x6b\x1b\x63\x69\xdc\xfc\xd7\x12\xb3\xdf\x47\xa1"
-  "\xd8\xe6\xbf\x83\xeb\x5b\xd5\x8c\xe5\xfa\x3a\xcc\x9b\xbf\x96\x1f"
-  "\x85\xbe\xdd\x15\x8b\x45\xc9\xf3\x66\xea\x96\xcc\x9d\x37\x67\xc1"
-  "\xd2\x25\xba\x81\xc9\xdd\xd1\xa4\x05\x0b\x74\xf3\x66\xce\x5f\xa1"
-  "\x73\xbe\xf2\x4b\x5d\xf2\xdc\xc5\x33\x67\xa5\xcc\x19\x32\x6f\xb6"
-  "\xb1\x3b\x16\xb7\x4e\xe5\x08\xc5\x65\xb1\x6f\xfe\xeb\xd9\x9d\xaf"
-  "\x23\xf4\x46\x6f\xa4\xc2\xe5\x6a\xdc\x7c\x78\xa4\x99\xb6\xc6\xe2"
-  "\xe7\x65\x6d\x63\x1a\x28\x48\x93\x0e\x3e\x6d\x6b\x5a\x57\x9c\x36"
-  "\x6e\x17\x94\x6b\x27\x94\x1b\xca\x08\x65\x3e\x6c\x70\x94\xd9\xc1"
-  "\x89\x74\xcc\x89\xb4\x6b\xc0\xc1\xc3\x9b\x82\x9a\xba\x3e\xc5\x30"
-  "\x89\xb8\x7e\x0d\xd0\x56\xfc\x2e\x50\x47\x06\xb0\x5a\x3f\xa7\xa6"
-  "\x14\xee\xdd\xe3\xe0\x98\x3d\x77\x50\x02\xf3\x7a\x4d\x06\x68\x47"
-  "\xbf\x46\xc6\xf0\x6b\xe0\x26\xbe\xff\xea\x50\x84\x32\x98\xc6\x44"
-  "\x76\x4f\x7f\xa6\x11\x38\x4c\x78\x0a\xd7\x8e\x1c\xbb\x4e\xa1\xc7"
-  "\x21\x8f\x3a\x33\x9a\xc3\x3e\xdf\x0c\xe7\xb0\xcd\xed\x85\x4f\x56"
-  "\x4d\xd6\xa3\x8c\x07\x33\x50\x46\x23\xbe\x67\x8f\xff\xde\xa0\x25"
-  "\xc8\x2f\x3e\x95\xf9\x06\xfc\x8e\x1f\x33\xe0\xc9\x2a\xe6\x5d\xff"
-  "\xbd\x66\xea\x70\xb9\x3d\x6f\x50\x02\xd4\xa7\xbe\x71\xf3\x91\x48"
-  "\x33\xaa\x37\xe3\x7c\xb6\x6e\x63\x6d\x5f\x8f\xeb\x0e\xf6\x81\x98"
-  "\x85\x31\x31\xeb\xb8\x36\x94\xc9\x18\xed\xd9\xe3\xa3\x2b\x55\x37"
-  "\x51\xbc\x95\x69\x65\xb6\x30\xc6\x8a\x86\x06\xf0\x69\xc6\xd9\x4c"
-  "\xf7\xbf\x5e\x0c\xb2\xce\x9d\xb3\xab\x37\xb4\xc5\x9c\xf1\xd1\x4c"
-  "\x8e\x3a\x73\x72\x04\x0a\x86\xbc\x33\x1d\xf6\x04\x5b\xaa\xe4\xf1"
-  "\xe8\x48\x36\xae\x13\xe6\x03\x94\x87\xe3\xc3\x91\xea\xa3\x4b\xdc"
-  "\xf9\xd0\xd6\x36\xb7\x85\x99\xac\x4c\xe2\x53\xad\xb9\x61\x4d\x4c"
-  "\x68\x58\x6d\xda\x79\xd4\x05\xdb\xb6\x02\xb4\x7e\xd6\x32\xa4\xdd"
-  "\xf2\x22\xd2\xcd\x58\x11\x8c\x2c\x79\x61\xe6\xa0\xb5\x19\x7e\x60"
-  "\x13\x0a\xfc\x4b\x24\xf8\xcc\xc8\x56\xf5\xa0\x84\xd5\x73\x10\xb5"
-  "\xff\x5c\x31\x85\x75\x32\x9e\xe3\x71\x81\xfa\xdb\x8e\x9d\x70\x1f"
-  "\xf3\x43\x22\xc2\x78\xb0\x58\xfc\x60\x40\xe3\xe7\x42\xff\xfc\x0a"
-  "\x7b\xfd\xd4\x0e\xc8\x53\x5e\xbd\xfe\xc6\xea\x5f\x1b\x60\x35\x14"
-  "\x70\xaa\xac\xb5\xb1\x79\xb2\x58\xa5\xf0\x58\x1d\x81\x72\xf0\x78"
-  "\xfd\x2d\x11\xe3\x2a\x5e\x67\x75\x0c\xa9\xb3\x3a\x95\x09\x55\x27"
-  "\x4b\xd7\x59\x9d\x44\xea\xec\x7f\xcd\x73\x9d\x3f\xcd\xf1\x5c\xe7"
-  "\x4f\x8f\xcb\xaf\xf3\xa7\xd3\xe4\xd7\xf9\xd3\x71\x1e\xea\xcc\xe1"
-  "\xac\x06\x9c\xd5\x1e\x70\x56\x73\x38\xf7\x38\xe7\xb9\xce\xa6\x0d"
-  "\x9e\xeb\x6c\x3a\x24\xbf\xce\xa6\x04\xf9\x75\x36\xc5\x48\xd7\x59"
-  "\xc3\xe1\xac\x01\x9c\x35\x1e\x70\xd6\x70\x38\x87\x7c\xe9\xb9\xce"
-  "\x47\x57\x78\xae\xf3\xd1\xfd\xf2\xeb\x7c\x34\x56\x7e\x9d\x8f\x46"
-  "\x79\xa8\x33\x87\xb3\x06\x70\xd6\x78\xc0\x59\xc3\xe1\xfc\xe8\x66"
-  "\xcf\x75\xfe\xfb\x3c\xcf\x75\xfe\xfb\x6e\xf9\x75\xfe\x7b\xb4\xfc"
-  "\x3a\xff\x5d\x2f\x5d\x67\x2d\x87\xb3\x16\x70\xd6\x7a\xc0\x59\xcb"
-  "\xe1\xfc\xc2\x13\x9e\xeb\xfc\xd9\x4c\xcf\x75\xfe\x2c\x4f\x7e\x9d"
-  "\x3f\x1b\x2c\xbf\xce\x9f\xf5\x93\xaa\x73\x0b\xf8\xed\x40\xa8\x4b"
-  "\xeb\xbf\x12\x9f\xb2\x85\x86\xd5\x07\xd6\x22\xaa\x60\x9d\xdd\x10"
-  "\x54\x87\xba\x41\xdd\x0c\xcc\xb6\x08\x1d\xfe\x6b\x0f\x0d\xab\x6b"
-  "\x09\x0d\x6b\x6a\xee\x5d\x93\xb1\x6a\x3a\xea\x82\xf5\xf8\x26\x3b"
-  "\xd2\xda\x73\xc3\x6a\x33\x9f\x41\xba\x74\x0b\x0a\xae\x48\x33\xa3"
-  "\x34\x23\x63\xa9\x40\xdf\xa2\x9e\x75\x38\xf6\xfc\x1a\x95\xd7\x97"
-  "\xa1\xf9\x8b\x18\xe6\x02\x75\xec\x5b\xfc\x3e\x17\x74\x72\x46\xf6"
-  "\x3f\x91\x0e\x9e\x11\xb9\x13\x0e\x9c\x4f\xd0\x38\xe8\x3f\xb7\x45"
-  "\x3c\xb0\x2b\x0d\x69\xff\xf6\x4a\x1d\xc2\xe7\x77\xc0\x61\xdb\x36"
-  "\x28\x21\x6d\x3a\xa2\x0e\x5c\x3b\x4b\x91\xbe\xf9\xd8\x7e\xd7\xbe"
-  "\x79\xdc\x4c\xb0\xe5\x2c\xf6\x5a\x73\xc1\x33\x72\x6d\x79\x2c\xd5"
-  "\xd1\x77\xb3\xb6\xac\xb6\x91\xfe\xde\xa5\xef\xfe\x1b\x3c\x9f\xb7"
-  "\xe5\x31\x03\xb6\x25\x93\xab\x46\x95\x75\x2d\x38\x6e\x0a\xbe\x90"
-  "\x8a\x28\x38\xaf\xad\x30\x5e\x43\xe2\x36\x56\xc7\xf0\x36\x56\xa7"
-  "\x04\xd6\xfa\x5f\x13\xb7\xb1\xda\xd0\x12\xaa\x4e\x75\xb7\xb1\x3a"
-  "\xd9\x3b\x1b\xff\xef\x18\xdf\x6d\xfc\xbf\x21\xd2\x36\xfe\xdf\xe9"
-  "\xf2\x6d\x7c\xbc\x5a\xbe\x8d\x8f\x97\x73\x36\xce\x10\xda\xf8\xf8"
-  "\x6a\x0f\x36\x76\xe2\xb1\x1a\x78\xdc\xe3\x9c\x84\x8d\x81\xc7\x6a"
-  "\x11\x1e\xab\xbd\xe4\xf1\x3f\xf6\xf9\x6e\xe3\x7f\x2c\x95\xb6\xf1"
-  "\x3f\x8e\xca\xb7\xf1\x3f\x62\xe4\xdb\xf8\x1f\x91\xc4\xc6\x1a\x17"
-  "\x1e\xff\xaf\x59\xda\xc6\x1a\x27\x1e\x6b\x80\xc7\x21\x5f\x8a\xdb"
-  "\x58\x03\x3c\xd6\x88\xf0\x58\xe3\x25\x8f\x4f\xf4\xf4\xdd\xc6\x65"
-  "\x5f\x49\xdb\xf8\xc4\x40\xf9\x36\x2e\xdb\x23\xdf\xc6\x65\xb9\x9c"
-  "\x8d\x5d\x78\x5c\x16\xeb\xc1\xc6\x4e\x3c\xd6\x00\x8f\x1f\xdd\x2c"
-  "\x61\x63\xe0\xb1\x46\x84\xc7\x1a\x2f\x79\xfc\xf9\x42\xdf\x6d\xfc"
-  "\xf9\x28\x69\x1b\x7f\xbe\x49\xbe\x8d\x3f\x0f\x90\x6f\xe3\x13\x4d"
-  "\xc4\xc6\x5a\x17\x1e\x9f\xd8\x2b\x6d\x63\xad\x13\x8f\xb5\xc0\xe3"
-  "\x17\x9e\x10\xb7\xb1\x16\x78\xac\x15\xe1\xb1\xd6\x4b\x1e\x7f\x71"
-  "\xc6\x77\x1b\x7f\xb1\x5b\xda\xc6\x5f\x5c\x96\x6f\xe3\x2f\x52\xe4"
-  "\xdb\xf8\x8b\x69\x9c\x8d\x5d\x78\xfc\x45\xa0\x94\x8d\x5b\x21\x06"
-  "\xec\x09\x36\xee\x59\x8f\xa8\x1d\xd8\xb6\x67\x89\x6d\x6d\xea\x08"
-  "\xdd\x0e\xca\x6e\xc0\x36\x61\xc7\x80\xbe\xd7\xf6\xb2\xe5\x86\xd5"
-  "\x33\x14\xd4\x29\x0d\x8f\xbb\x96\x4f\xb6\xae\x43\xbd\x74\x69\x78"
-  "\xfc\xb7\x82\x5d\x1f\xa6\x4b\x7b\xad\x06\x9e\x47\xe3\x71\x2f\x6b"
-  "\x4e\x75\x92\x2d\xac\x6f\xe4\x05\xea\xe4\x16\x66\x60\x57\x13\xc4"
-  "\x21\x88\x79\x55\x1b\x5a\x59\x5f\x0c\xf6\xf9\x1c\x55\x9c\xfd\x04"
-  "\xd9\xd5\x11\x0f\x0c\xb5\x22\x3d\xf3\xbd\x3e\xb4\x7c\x89\x19\xd9"
-  "\x66\x6b\x03\x2b\x53\xcb\x50\x65\xea\x47\x28\xbe\x8e\xb9\xc9\xfc"
-  "\x57\x1f\xd8\x1a\x36\xd4\x60\x0b\x8b\x40\xb6\xbc\xe8\x3a\x6b\xd8"
-  "\xd0\xc4\xfd\xcb\xcc\x54\x60\x13\xd2\xa7\xd4\x32\x4c\xd6\x2c\xa4"
-  "\xca\x3a\x87\x02\xb6\xce\x42\x81\x5b\xcf\xa1\xe0\xf2\xda\xb3\xe8"
-  "\xe4\xa5\x32\x74\xf2\xda\x57\xe8\xe4\x4d\x38\x5a\xe0\xb0\xc3\x91"
-  "\xf1\x15\x60\x8d\xd0\xf8\xcb\x08\xa5\xd7\x32\x96\x5f\x54\xa3\xd0"
-  "\x72\xeb\x59\x84\xe7\x38\x5d\xa1\x4e\x46\x04\x26\xa1\x50\xe6\xbf"
-  "\x5a\xc4\xcc\xd6\x52\x70\x4d\x85\xcf\x57\x5a\x2d\xa8\xbc\xb6\x09"
-  "\x5f\x0f\x80\xeb\xaa\xf4\x5a\xc8\xdf\x5e\x86\xbf\x77\x68\x29\xcf"
-  "\x38\x01\xf5\xcb\x4c\x60\x70\x0c\xad\x0e\x33\x65\x83\xa9\xed\x8c"
-  "\xf6\x01\xc2\x83\x8a\xd1\x3b\xed\x72\xb1\x3e\x99\xc8\xda\xf8\x55"
-  "\x6d\x6f\xb0\x73\x5f\xfb\xab\x89\xc1\x13\xbe\xfa\x86\xa9\x68\x38"
-  "\x8b\xf0\x58\x42\x45\xc3\xe7\xa8\x72\xbd\x1d\xc5\xaf\x40\x68\x9c"
-  "\x0d\xb1\xb6\xa8\x4c\xad\x43\x13\x8c\x28\x08\x8f\x3f\xdb\xbf\xd7"
-  "\xf7\xae\xac\xb5\xa0\x35\x56\x28\xe3\x95\xa6\xb6\x32\x56\xac\xaf"
-  "\x40\x70\xad\x6f\x85\xc1\x8c\x02\x8d\x28\x18\xdb\xd7\x9a\x1b\x56"
-  "\x37\x01\xda\xcf\xfc\x06\x86\xc1\xb6\xc5\x36\xc5\xf6\xc5\xf9\x39"
-  "\x6c\x5e\x99\x6c\x41\xe9\x4d\x28\xb8\x32\x0d\xfe\xa6\x32\x96\x4a"
-  "\x74\x15\x41\x19\x47\x32\x21\x99\x09\xc0\x8b\x70\xcc\x05\x33\x55"
-  "\x3e\x0e\xf0\xef\x2d\xce\x29\x75\x32\xe1\x94\xff\xb5\xf6\x39\xa5"
-  "\x4e\xe1\x39\x55\xb1\x8f\xe7\x54\xd5\x06\x69\x4e\x55\x7e\xcb\x71"
-  "\x2a\xa3\x73\x72\xaa\x72\x8d\x67\x4e\x55\x4e\x93\xe6\x94\x3a\x95"
-  "\x51\xab\x63\x84\x9c\xaa\xca\x93\xcf\xa9\xca\xa2\x8e\xe3\x94\xda"
-  "\xa0\x8c\x53\x95\xd9\x42\x4e\x55\x14\x7a\xe0\x14\xe7\xa7\x7a\x9c"
-  "\xf3\x82\x53\x4e\x7e\xaa\xca\xc6\x73\xea\xcb\xaf\xa4\x39\xf5\xe5"
-  "\x70\xc2\x29\x4d\x27\xf5\x53\xa7\x4e\x79\xe6\xd4\xa9\x62\x0f\x9c"
-  "\x02\x3f\xa5\x76\xf1\x53\x5f\x5e\x94\xcf\xa9\x2f\x51\x07\x72\x4a"
-  "\xa1\x9f\x3a\x55\x2b\xe4\x54\x55\x83\x34\xa7\x34\x9c\x9f\x0a\xf9"
-  "\xb2\x7d\x4e\x69\x9c\xfc\xd4\xff\x4d\xe4\x39\x75\x66\x88\x34\xa7"
-  "\x4e\x6f\xe2\x38\xd5\x49\xfd\xd4\xe9\x81\x9e\x39\x75\x5a\x25\xcd"
-  "\x29\x0d\xf8\x29\x8d\x8b\x9f\x3a\x33\x4a\x3e\xa7\x4e\x4f\xea\x38"
-  "\x4e\x69\x14\xfa\xa9\xd3\xd1\x42\x4e\xfd\x5f\x9c\x07\x4e\x71\x7e"
-  "\xea\xd1\xcd\x5e\x70\xca\xc9\x4f\x9d\x79\x97\xe7\xd4\xbf\xd6\x4a"
-  "\x73\xea\x9f\x35\x84\x53\xda\x4e\xea\xa7\xfe\xb9\xc2\x33\xa7\xfe"
-  "\x99\xe8\x81\x53\xe0\xa7\x34\x2e\x7e\xea\x5f\x39\xf2\x39\xf5\xcf"
-  "\xbd\x1d\xc8\x29\x85\x7e\xea\x9f\x99\x42\x4e\x9d\x29\x90\xe6\x94"
-  "\x96\xf3\x53\x2f\x3c\xd1\x3e\xa7\xb4\x4e\x7e\xea\x5f\xcd\x3c\xa7"
-  "\xbe\x3a\x23\xcd\xa9\xaf\x86\x71\x9c\xea\xa4\x7e\xea\xec\x49\xcf"
-  "\x9c\x3a\x5b\x24\xcd\x29\x2d\xf8\x29\xad\x8b\x9f\xfa\xea\xbc\x7c"
-  "\x4e\x9d\xb5\x76\x1c\xa7\xb4\x0a\xfd\xd4\x59\xb3\x90\x53\xff\xb2"
-  "\x48\x71\xaa\x05\xc7\x7d\x7e\xc0\x29\x03\xc4\x7d\xc0\xa1\xa0\x2a"
-  "\xc2\xa9\x56\xe0\xd4\x5b\xce\x9c\xfa\xb7\x6b\xdc\xf7\xf5\x78\x7b"
-  "\x1b\xa7\xaa\xa7\xb8\x72\xca\x0e\x9c\x6a\x65\x39\xf5\xef\x85\x8e"
-  "\xb8\xaf\xb2\xbe\x10\xb0\xba\x84\x2a\x13\x80\x4f\xdb\x38\x3e\xfd"
-  "\x1b\xf8\x04\xf5\xb1\x43\x7d\xcb\xab\xcf\xa2\x78\x0b\xa9\x57\x0b"
-  "\xd4\xd7\xee\xcc\xa5\x96\x3a\x0a\x73\x08\x73\xc7\xc1\xa3\x93\xf3"
-  "\x81\x3f\x8b\x4e\xa1\x93\xcb\xe0\x58\x09\x47\x1a\x1c\xe8\x14\x2a"
-  "\xaf\x43\xec\x98\x3d\xcf\x9f\x2a\x8e\x3f\xff\xee\xe9\x99\x3f\x5f"
-  "\xd7\xcb\x8b\xf1\xaa\xe7\xca\xe7\xcf\xbf\x47\x72\x73\xe9\x82\xe3"
-  "\x27\x7e\xc3\xe0\xb9\xae\x84\x23\x97\x50\xbc\x15\x05\x31\x2f\xe8"
-  "\x7b\x07\x26\xa2\xe0\x55\x36\x44\x6d\x99\x85\x82\xb7\x7c\x0d\xf5"
-  "\x75\xb4\x9d\x73\x28\xf0\xf3\xa6\x4f\x50\xf9\xb5\xb3\xa8\xfc\xe6"
-  "\x09\x54\x6e\x87\xe3\x12\x1c\x50\xc6\xf8\x39\xce\xf5\xb5\x38\xea"
-  "\x6b\x83\xbc\xc2\xa5\xeb\xfb\xef\x6a\xb6\xbe\xc9\x50\xdf\x16\xbe"
-  "\xbe\x95\xc0\x45\xc0\xa5\xaf\x9d\x8b\x13\xe3\x2d\xa8\xdb\x02\x2b"
-  "\xc3\xb4\x70\x1c\xc4\xb8\x7c\x7e\xba\x09\xc5\x1b\x01\xab\xd9\xc0"
-  "\xc1\xda\xbd\x28\x7d\x35\x70\xb0\xa5\x09\xbf\xd7\xb7\x54\x66\x34"
-  "\x03\x07\xff\xad\x63\xc0\x6e\xad\x98\x83\xff\xc6\x1c\xfc\x3a\xd6"
-  "\x2e\xc9\x41\x88\x13\x59\x0e\x42\x9c\xd8\x2e\x07\x9d\xe3\xc4\xea"
-  "\x53\x3c\x07\xff\x53\x23\xcd\xc1\x9a\x1b\x8e\x38\xf1\xc7\xe7\x60"
-  "\x4d\x8e\x67\x0e\xd6\x18\xe5\xc5\x84\xff\xb9\x2c\x9f\x83\x35\xa6"
-  "\x8e\xe3\xe0\x7f\xd6\x7a\xe6\xe0\x7f\x92\xda\xe7\xa0\xda\xa0\x8c"
-  "\x83\x35\x7b\x84\x1c\xac\x2e\xf3\xc0\x41\xce\x0f\x42\x5c\xd9\x3e"
-  "\x07\x9d\xfc\xe0\x37\x93\x79\x0e\x7e\x3b\x53\x9a\x83\xe6\x15\x8e"
-  "\xb8\xf2\xc7\xe7\xa0\x39\xcc\x33\x07\xbf\x69\x90\x17\x43\x7e\xbb"
-  "\x50\x3e\x07\xcd\xb1\x1d\xc7\xc1\x6f\xfd\x3d\x73\xd0\x5c\xeb\x05"
-  "\x07\x15\xfa\x41\xb3\x5e\xc8\xc1\x6f\xc6\x49\x73\x50\xc3\xf9\x41"
-  "\x88\x43\xdb\xe5\xa0\x73\x1c\xfa\xed\x57\x3c\x07\xff\x7b\x5e\x9a"
-  "\x83\xe7\x6c\x8e\x38\xf4\xc7\xe7\xe0\xb9\xed\x9e\x39\x78\x2e\x55"
-  "\x5e\xcc\xf9\xdf\x1b\xf2\x39\x78\xae\xac\xe3\x38\xf8\xdf\x4d\x9e"
-  "\x39\xf8\x5f\x43\xfb\x1c\xd4\x28\xf4\x83\xe7\x8a\x84\x1c\xfc\xb6"
-  "\xca\x03\x07\x39\x3f\x08\x71\x6b\xfb\x1c\x74\xf2\x83\xb5\xd3\x79"
-  "\x0e\x5e\x98\x2b\xcd\xc1\xf3\x6b\x1d\x71\xeb\x8f\xcf\xc1\xf3\xfd"
-  "\x3d\x73\xb0\xd6\x2a\x2f\x46\xbd\xb0\x42\x3e\x07\xcf\x8f\xeb\x38"
-  "\x0e\x5e\xe8\xe9\x99\x83\xe7\xeb\xbd\xe0\xa0\x42\x3f\x78\x3e\x52"
-  "\xc8\xc1\xda\x49\xd2\x1c\xd4\x72\x7e\x10\xe2\xdc\x76\x39\xe8\x1c"
-  "\xe7\x5e\xf8\x96\xe7\x60\xdd\x65\x69\x0e\xd6\xf9\x3b\xe2\xdc\x1f"
-  "\x9f\x83\xdf\xed\xf6\xcc\xc1\xef\x32\xe4\xc5\xb4\x75\x36\xf9\x1c"
-  "\xfc\xae\xaa\xe3\x38\x58\x97\xe3\x99\x83\x75\xc6\xf6\x39\xa8\x55"
-  "\xe8\x07\xbf\x2b\x11\x72\xf0\xc2\x59\x29\x0e\xda\x21\x2e\x6e\xdd"
-  "\xd3\xd5\x64\xcf\x1d\x6a\x08\xf2\xd3\x21\x6b\x68\xdf\xc8\xca\x25"
-  "\x0d\x68\xc2\x0d\xb0\x8f\xf1\x06\x7a\xf1\x46\x30\xb2\xe5\x0e\x4d"
-  "\x84\xb8\xb0\xce\x29\x7e\x66\xe7\x96\x59\xb3\x33\x13\xb6\xce\x47"
-  "\x2a\x88\xbf\x1f\xc0\xe7\x2a\x2f\x34\x21\xfc\xfc\x35\xb8\x3c\x97"
-  "\xf8\xf2\xe0\x71\x02\xe6\x07\x7d\x30\xfb\x8e\xb9\xc5\x8c\x6a\x47"
-  "\x22\xba\xbc\xd6\x0c\x76\x58\xc9\xe2\x8b\xed\x72\x81\xba\x58\xb5"
-  "\xeb\x0a\x52\x59\xff\xab\xed\x0b\xf6\x0e\xed\xb9\x1c\xf9\xf5\xab"
-  "\x65\xec\xd8\xae\xd8\x5e\xd8\xc6\xba\x95\xf8\xdd\xf5\xa5\x01\x15"
-  "\xc0\x31\xeb\x7f\xf5\x7d\x77\x42\x3a\xf1\x78\xf5\x52\x84\x7c\x6e"
-  "\x5c\xac\x27\xeb\x16\x2e\x96\x95\x57\x23\xd1\x77\xc7\x76\x88\xdf"
-  "\xbc\xb3\x95\xda\xe0\x14\xe7\xdd\x06\x5b\x5d\xb2\x7a\x67\xab\xef"
-  "\xc7\x0b\x6d\x25\x16\x57\x7d\x3f\x59\xbe\xad\xbe\xd7\x12\x5b\x5d"
-  "\x6a\xf0\x60\x2b\x2f\x79\xa5\xae\x73\x8a\x47\x6e\x83\xad\xea\xf5"
-  "\xde\xd9\xaa\x7e\x85\x8b\xad\x44\xf4\x7f\xfd\x5a\xf9\xb6\xaa\xe7"
-  "\xf6\x43\xaa\xd7\x49\xdb\x4a\xe3\x25\xaf\x34\x06\x27\xdd\x7c\x1b"
-  "\x6c\x75\x79\x92\x77\xb6\xba\xfc\xae\xd0\x56\x62\x3a\xf5\xf2\x7e"
-  "\xf9\xb6\xba\x6c\x24\xb6\xba\x3c\xce\x83\xad\xbc\xe4\x95\xa6\xce"
-  "\x49\xdf\xdd\x06\x5b\x5d\xc9\xf0\xce\x56\x57\x4e\xb9\xd8\x4a\x44"
-  "\x4f\x5d\xf9\x4a\xbe\xad\xae\x70\xdf\x43\xbf\x92\x2a\x6d\x2b\xad"
-  "\x97\xbc\xd2\x1a\x9c\x74\xc8\x6d\xb0\xd5\x0f\x45\xde\xd9\xea\x07"
-  "\x9b\xd0\x56\x62\xfd\xbe\xc5\x5f\xbe\xad\x7e\x28\x23\xb6\xfa\x61"
-  "\x8f\x94\xad\x6c\xb9\x61\xb5\x41\x60\x83\xe6\x6d\x61\xa6\xa0\x54"
-  "\x44\xb5\x84\x83\xdd\x42\xc1\x6e\x6b\x75\xa8\x35\x17\xec\x66\xb1"
-  "\xa2\x09\x0b\xbf\x61\x2a\xea\x6d\xa8\x05\x6c\xd6\x1c\x1a\x56\x57"
-  "\x69\xa9\xc3\x73\x8e\x7e\x75\x8e\xba\x7a\xfe\x85\x85\xc1\x08\xdb"
-  "\x0d\xdb\x01\xdb\x8e\x01\xbb\xb1\x76\x0c\x8d\xae\xb3\x85\x46\xa0"
-  "\xf1\x97\xbf\x61\x16\x98\x19\x06\xd7\x97\x09\xae\x4e\xc2\xef\x05"
-  "\xe2\xeb\x50\x37\xdd\x33\xb8\x4e\x57\xf3\xf0\xf9\x4a\xcb\x59\xd0"
-  "\x07\xd7\x10\xab\xcd\xbe\xd1\x87\xda\x9e\xd7\x07\xda\x2a\x13\x9f"
-  "\x62\x7a\xd7\x64\x58\xd5\x83\x12\xd2\x2f\xa3\x2e\x58\x3f\x64\xd9"
-  "\x91\x76\xcd\x3c\x44\x1d\x78\xc5\x44\xb1\x6b\xd7\x16\xb1\x79\xcc"
-  "\x04\xbb\x68\x99\xeb\x4e\x73\xba\xaf\x1b\x50\xe5\x85\x6c\x16\x37"
-  "\x57\x8d\xc0\xe2\xf6\x2f\x7d\x30\xe8\xcc\x48\x26\x34\xac\x29\xbb"
-  "\x02\xe9\x98\x56\xb0\x31\xbb\x9e\xe8\xda\xf8\x5d\x2d\x72\x6d\x7c"
-  "\x95\x9d\xff\x6d\xd7\x71\xf3\xb7\xc0\x4e\xf8\xf9\xec\xfc\x2d\xa3"
-  "\xd3\xfc\x2d\x28\x33\x3f\x7f\xcb\x62\xc1\xf3\xb7\xec\xdf\x68\xfb"
-  "\x3a\xea\xbe\x20\x85\x61\xa0\xee\xbd\x2b\x1a\x2c\x08\xd7\xbf\xa2"
-  "\xc1\x84\xd2\x97\xa0\xe0\x8a\x96\x3a\x94\xd6\xc0\x58\x2a\x32\x2e"
-  "\xa2\xf8\x1b\x58\x07\x63\xbe\x5c\xad\x21\xb8\x5a\x8a\xed\xdf\xe8"
-  "\xfb\x42\x19\x4e\x57\x80\xc2\x73\x5a\xc7\x63\x00\xcd\x1c\x00\x38"
-  "\x18\x2a\x33\xce\x21\xc0\x04\xec\xf2\x35\xc6\xc9\x00\xd7\x47\xb6"
-  "\xe9\x6b\x75\xc4\x3a\x7c\x0e\x63\x86\xdf\x37\x55\x1a\x2d\x6c\x1a"
-  "\xc7\x75\xcc\x8b\xa0\xd4\x0c\x54\x99\xda\x82\x2a\xac\x78\xcd\xae"
-  "\x65\xda\x17\x89\x67\x25\x78\xa4\x4e\x26\x3c\x52\xc7\x04\xa5\xfa"
-  "\x5f\x6b\x9f\x47\x6a\x03\xcf\xa3\x86\x21\xbe\xf1\xe8\x7a\x8d\xef"
-  "\x3c\xba\xbe\x4f\x39\x8f\xd4\xa9\x42\x1e\x35\xe4\xc9\xe7\xd1\xf5"
-  "\x25\xf2\x79\x74\x3d\xda\x37\x1e\x35\x0c\x24\x3c\xba\xd6\x44\x78"
-  "\xd4\xd0\x8f\xe7\x11\xbb\x36\xea\x36\xf1\xe8\xda\x1e\x0f\x3c\xe2"
-  "\xfc\x91\x1a\xfc\x51\x8f\x73\x5e\xf0\xc8\xc9\x1f\xdd\x5c\xea\x1b"
-  "\x8f\x6e\x0e\xf4\x9d\x47\x37\xae\xfa\xc0\x23\x17\x7f\x74\xb3\x46"
-  "\x3e\x8f\x6e\x1c\x96\xcf\xa3\x1b\x19\xbe\xf1\xe8\xe6\x3c\xc2\xa3"
-  "\x1b\x31\x84\x47\x37\x93\x79\x1e\xb1\xeb\xcd\x6e\x13\x8f\x1a\xea"
-  "\xa5\x79\xa4\xe1\xfc\x91\x06\xfc\x51\xc8\x97\xed\xf3\x48\xe3\xe4"
-  "\x8f\x9a\x8e\xf8\xc6\xa3\xa6\x79\xbe\xf3\xa8\x69\x84\x72\x1e\x69"
-  "\x5c\xfc\x51\xf3\x40\xf9\x3c\x6a\x52\xc9\xe7\x51\x63\x99\x6f\x3c"
-  "\x6a\x3a\x48\x78\xd4\xb8\x91\xf0\xa8\xa9\x88\xe7\x11\xbb\x86\xef"
-  "\x36\xf1\xa8\x31\xca\x03\x8f\x38\x7f\xa4\x01\x7f\xf4\xe8\x66\x2f"
-  "\x78\xe4\xe4\x8f\x5a\xfd\x7d\xe3\x51\xcb\x41\xdf\x79\xd4\xb2\xd6"
-  "\x07\x1e\xb9\xf8\xa3\xd6\x79\xf2\x79\xd4\x32\x4e\x3e\x8f\x5a\x82"
-  "\x7d\xe3\x51\x8b\x8d\xf0\xa8\xb9\x8a\xf0\xa8\xa5\x81\xe7\x11\xbb"
-  "\x2e\xf2\x36\xf1\xa8\x79\xb5\x34\x8f\xb4\x9c\x3f\xd2\x82\x3f\x7a"
-  "\xe1\x89\xf6\x79\xa4\x75\xf2\x47\xb6\xf1\xbe\xf1\xc8\x6a\xf3\x9d"
-  "\x47\xd6\x13\xca\x79\xa4\x75\xf1\x47\xb6\x83\xf2\x79\x64\xcd\x95"
-  "\xcf\x23\x6b\xa2\x6f\x3c\xb2\x8d\x21\x3c\xb2\x6a\x09\x8f\x6c\x23"
-  "\x79\x1e\xb1\x6b\x4d\x6f\x13\x8f\x5a\x8f\x49\xf1\x08\xef\x45\xf0"
-  "\x06\xd9\x17\xa2\x61\xeb\x4a\x14\xbd\x0b\xff\x6d\x41\x91\x8d\x9b"
-  "\x6d\xf5\x47\x57\x93\xfd\x00\xa0\x9c\x92\xfb\x84\xf4\xd8\x07\xb8"
-  "\x84\x86\x99\xe3\x6b\xc8\x1e\x0d\x78\x5f\x90\xeb\xe9\x06\x34\x94"
-  "\xdd\x97\x81\x09\xc7\xfb\x58\xb5\xed\x1d\x10\x2a\xb1\x77\xc0\x54"
-  "\xe9\xbd\x03\x5a\xb6\x39\xd6\xdd\xee\x75\x5a\x77\x6b\xbf\xea\x79"
-  "\xdd\xad\xfd\xab\x1d\x53\xe5\xf2\xc1\xce\xae\xff\xba\xae\x0e\x33"
-  "\x35\x6e\xb6\xd7\x41\x9d\x4d\xa4\xee\x4c\x32\xf2\x6a\x3d\xee\x5e"
-  "\x27\x9e\xd8\x73\x27\x4f\x43\x19\xcc\xe6\x23\x75\x4c\x58\x98\x99"
-  "\xc9\x0b\xb3\xc8\x2b\x0b\x23\xf9\xfd\x0f\x62\x6f\x75\x92\xa8\xbd"
-  "\x69\x94\x4b\xec\xcd\xed\x5b\x10\x2a\xb1\x6f\xc1\x54\xe9\x7d\x0b"
-  "\x44\xed\x4d\x23\xcf\xeb\x9c\x69\x34\x56\xb6\xbd\x69\x14\x4a\xec"
-  "\xad\x8e\x69\xcc\x42\x89\x6d\xf6\xa6\xd1\x69\xd9\xf6\xa6\x91\x8a"
-  "\xd8\xfb\x6f\xd5\x4c\x98\x3a\x89\xc9\x53\x1b\x65\x96\xa5\xb0\x1d"
-  "\x7b\x8b\xf3\x9b\xa6\x54\x9c\xbd\x39\x7e\x4b\xec\x99\x30\x55\x7a"
-  "\xcf\x04\x71\x7b\xfb\x9d\xf2\x6c\x6f\xbf\x43\xf2\xed\xed\xb7\x9e"
-  "\xb3\xb7\xa9\x31\xcb\xaf\x8c\xb7\x37\xe5\xe5\xbe\x02\xce\xf6\xf6"
-  "\x5b\x42\xec\xfd\x69\x15\xd8\x1b\xf8\xad\x96\xc7\x6f\x9a\x0a\xf6"
-  "\x6c\x6f\x8d\x04\xbf\xe9\x25\xc4\xde\xdc\x7e\x0d\xa1\x12\xfb\x35"
-  "\x4c\x95\xde\xaf\x41\xdc\xde\xf4\x68\xcf\xf6\xa6\x23\xe4\xdb\x9b"
-  "\x6a\x20\xf6\xd6\x00\xbf\xe9\x68\xde\xde\x74\x89\x7c\x7b\x53\xb5"
-  "\xc4\xde\xa6\x63\x4c\x98\x06\xf8\xad\x91\xc9\x6f\x3a\xa3\x1d\x7b"
-  "\x4b\xf0\x5b\x55\xcb\xd9\x9b\xe3\xb7\xc4\x5e\x11\x53\xa5\xf7\x8a"
-  "\x10\xb7\xb7\xea\x43\xcf\xf6\x56\x6d\x97\x6f\x6f\x55\x32\x67\x6f"
-  "\xe0\xb7\x6a\x2f\x6f\x6f\xff\x70\xf9\xf6\x56\x4d\x22\xf6\x3e\x5a"
-  "\x0a\xf6\x06\x7e\x6b\x64\xf2\x5b\x65\xf1\x6c\x6f\xad\x04\xbf\xbb"
-  "\x4c\x22\xf6\xe6\xf6\xa9\x08\x95\xd8\xa7\x62\xaa\xf4\x3e\x15\xe2"
-  "\xf6\xee\x32\xc0\xb3\xbd\xbb\x74\x93\x6f\x6f\xff\xd3\xc4\xde\x5a"
-  "\xe0\x77\x17\x2d\x6f\xef\x2e\xb9\xf2\xed\xed\x7f\x8c\xd8\xfb\xef"
-  "\x45\x4c\x98\x16\xf8\xad\x95\xc9\xef\x2e\x49\x52\xf6\x0e\x02\x7b"
-  "\x1f\x07\x1d\x03\xba\xa3\xce\x9e\x0b\x3a\xc5\x26\xb4\x7b\x65\x6a"
-  "\x34\x7a\xe8\x26\xb6\x7d\x40\x0c\xf4\xd5\x75\x1d\xb6\x5f\x06\x1d"
-  "\x10\xe1\xf3\xda\x61\xba\xeb\x0d\xc9\xb5\xc3\x74\xd7\x1a\xd9\x6b"
-  "\x87\xe9\xae\x7b\xdb\x34\x50\x56\xd7\x7a\x1e\xd3\x00\xd6\x7f\xc8"
-  "\x5a\x53\x4c\x77\xcd\x17\xdd\x47\x83\xee\x1a\x87\xd7\x14\x33\x9b"
-  "\x3f\x2b\xb4\xe7\x29\xd0\x46\x74\xc0\xb8\xf6\xb1\x56\x1b\xec\xb9"
-  "\xa0\x91\x24\xb1\xee\x3e\x18\xfa\x2d\x43\x87\xed\xdb\x41\x77\x0f"
-  "\xf3\x1d\xeb\x6e\xdf\x4a\x63\xdd\xed\x84\x7c\xac\xbb\xe5\xf2\xfa"
-  "\xab\xdb\x59\x1e\xeb\xee\xf2\xd7\x8f\xd3\xdd\xd6\x8b\xee\xe7\x41"
-  "\x77\x8b\x22\x58\x1f\x57\xd9\xf3\x94\xe8\xb2\xee\xd1\x5e\x60\x0d"
-  "\xed\x5a\xed\xa1\x5d\x07\x6a\x01\xeb\xba\x0e\xdb\x3f\x84\x0e\xf4"
-  "\xf3\x1d\xeb\x1e\x27\xa5\xb1\xee\x71\x50\x3e\xd6\x3d\x32\x78\xed"
-  "\xd7\xe3\x18\x8f\x75\x60\xa2\x7c\xac\x7b\x18\x45\xf7\x15\xa1\x7b"
-  "\xe8\x08\xd6\xff\x6b\x00\xac\x15\x68\xc2\xc0\xf0\xf6\xb1\xd6\x40"
-  "\xbb\xd6\x78\x68\xd7\xbd\x54\xd0\x5f\x1b\x3a\x6c\x1f\x13\xba\xe7"
-  "\x65\xdf\xb1\xee\x79\x48\x1a\xeb\x9e\xbb\xe5\x63\xdd\x33\x85\xd7"
-  "\x9d\x3d\x8b\x79\xac\x7b\xc5\xca\xc7\xba\xe7\x34\xd1\xfd\x4d\xe8"
-  "\x9e\x81\x04\xeb\x7f\x94\xdb\xf3\x94\xe8\xd1\x5e\x92\xfa\xdf\x09"
-  "\x6b\x68\xd7\x1a\x0f\xed\x3a\xc8\x02\x58\xd7\x75\xd8\x7e\x2a\x74"
-  "\xd0\x57\xbe\x63\x1d\xf4\xae\x34\xd6\x41\x5b\xe4\x63\x1d\x94\xc8"
-  "\x6b\xde\xa0\x02\x1e\xeb\xe0\x48\xf9\x58\x07\xc5\x89\xee\xb3\x42"
-  "\xf7\x6a\x22\x58\x9f\x88\x04\xac\x15\x68\xe1\x20\x6b\xfb\x58\x6b"
-  "\xa1\x5d\x6b\x3d\xb4\xeb\x10\x88\xeb\xb5\x86\x0e\xdb\xd7\x85\x0e"
-  "\x39\xee\x3b\xd6\x21\x39\xd2\x58\x87\xac\x90\x8f\x75\x48\x2c\xaf"
-  "\xb7\x43\x36\xf2\x58\xf7\xee\x27\x1f\xeb\x90\x28\xd1\xfd\x5e\xe8"
-  "\xe0\x5a\x82\xf5\xe7\xb9\xf6\x3c\x25\x3a\x3c\xa4\x4e\x89\x0e\x5f"
-  "\xbc\x03\x05\x08\xf1\xbe\xa7\xbc\x63\xb5\xf8\x3d\x07\x7d\xc7\xfb"
-  "\x9e\xb5\xd2\x78\xdf\x33\x57\x3e\xde\xf7\x44\xf1\x5a\xfc\x9e\x54"
-  "\x1e\xef\xd0\x40\xf9\x78\xdf\x13\x2e\xae\xc5\x7b\x9f\xf6\x4d\x8b"
-  "\xdf\x73\x56\x89\x16\x77\xc7\x3b\xec\x70\xc7\xea\xf1\xb0\x77\x7d"
-  "\xc7\x3b\x6c\xa1\x34\xde\x61\x53\xe4\xe3\x1d\x16\xce\xeb\xf1\x30"
-  "\x03\x8f\x77\x98\x55\x3e\xde\x61\xa1\xe2\x7a\x3c\xf4\x98\x6f\x7a"
-  "\x3c\xac\x4c\x89\x1e\x77\xc7\x5b\x53\xd4\xb1\x9a\x5c\x93\xe7\x3b"
-  "\xde\x9a\x99\xd2\x78\x6b\xc6\xca\xc7\x5b\x13\xca\x6b\x72\x8d\xd3"
-  "\xf8\xb7\xa6\x5e\x3e\xde\x1a\x95\xb8\x26\x57\x97\xf8\xa6\xc9\x35"
-  "\x92\xdf\x3f\xf4\xa4\xc9\xdd\xf1\xee\x53\xd0\xb1\xba\xbc\xcf\x06"
-  "\xdf\xf1\xee\x33\x51\x1a\xef\x3e\x23\xe4\xe3\xdd\x47\xc5\xeb\xf2"
-  "\x3e\x71\x3c\xde\x7d\xe4\xef\x9f\x49\x6b\x1b\xc4\x75\xb9\x76\x8f"
-  "\x6f\xba\xbc\xcf\x5e\x25\xba\xdc\x1d\xef\x7b\x33\x3b\x56\x9b\xdf"
-  "\xbb\xd4\x77\xbc\xef\x1d\x2d\x8d\xf7\xbd\x11\xf2\xf1\xee\xdb\xc0"
-  "\x6b\xf3\x7b\x9d\xc6\xff\xef\x2d\x97\x8f\x77\xdf\x5a\x71\x6d\xde"
-  "\x37\xd7\x37\x6d\x7e\x6f\xbe\x12\x6d\xee\x8e\x77\xff\xd5\x1d\xab"
-  "\xcf\xfb\xcf\xf1\x1d\xef\xfe\xc3\xa4\xf1\xee\xdf\x47\x3e\xde\xfd"
-  "\x6a\x79\x7d\xde\x5f\xcf\xe3\xdd\xff\xb0\x7c\xbc\xfb\x9d\x16\xd7"
-  "\xe7\xfd\xd6\xfb\xa6\xcf\xfb\x6f\xf4\x7d\x9c\x5c\x97\x88\xb5\xb9"
-  "\xdc\xfd\x1f\x2b\x97\x70\x6b\xee\xe8\xfb\xf8\xfd\x1f\x69\x1d\xfb"
-  "\x1d\x48\xd1\xbd\x65\xe8\xfb\xdf\xed\xd4\xfb\x3f\xd2\xf7\x7b\xde"
-  "\xff\x91\xbe\x5f\xde\xfe\x8f\xf4\xfd\x5b\x64\xcf\xc7\xa7\xef\x4f"
-  "\xe4\x63\x84\xfb\x9d\xe2\x7f\x1d\xdb\xae\x3b\xf5\xbe\x90\xf4\xfd"
-  "\xc2\x7d\x21\xe9\xfb\xd8\x7d\x21\x99\xcd\x5f\x34\x29\x8b\x45\x74"
-  "\xc9\xbe\xbf\x17\xf8\x59\x14\x8e\x43\xe4\xee\x43\xc9\x73\x7b\xc0"
-  "\x30\x9e\xdb\x3f\x1b\x28\xcd\xed\x07\xd6\x76\xea\x7d\x28\xe9\x07"
-  "\xfc\x3d\x73\x7b\x40\xad\xac\x3d\x47\xe8\x07\xe4\xef\x7b\x43\x3f"
-  "\x10\xc5\xc7\x43\x0f\x38\xc5\xbf\x3f\x5b\xd2\x71\xdc\x56\xb8\x3f"
-  "\x25\xfd\x80\x56\xc8\xed\x01\x7a\xc2\xed\x8a\x71\xca\xe2\xae\x9f"
-  "\xc5\xf8\xfe\x1e\x64\x50\x30\x8e\xb9\xe4\xee\x87\xc9\x73\x3b\xbc"
-  "\x27\xcf\xed\x41\x7e\xd2\xdc\x1e\x38\xbd\x53\xef\x87\x49\x87\x7f"
-  "\xeb\x99\xdb\xe1\x26\x59\x7b\x99\xd0\x03\xc7\xc8\xe7\xf6\xc0\x60"
-  "\x3e\xf6\x1b\x38\x89\xe7\xf6\xa0\x84\x0e\xe4\xb6\x42\xbf\x1d\xde"
-  "\x20\xe4\x76\xb8\x8a\x70\xbb\xaa\x50\x59\x8c\x39\xa8\x9f\xef\xef"
-  "\x7d\xf4\xf5\x38\xbe\x94\xbb\x2f\x27\xcf\xed\x41\x17\x79\x6e\xeb"
-  "\xdd\xf6\x85\xe2\xb9\xad\x1f\xd1\xa9\xf7\xe5\xa4\x1f\x3c\xe2\x99"
-  "\xdb\x0f\x16\xc8\xda\x23\x85\xd6\x0f\x90\xcf\xed\x07\xeb\xf9\x38"
-  "\x57\x1f\xc9\x73\x3b\x62\x70\xc7\x71\x5b\xe1\x7e\x9d\xf4\x83\x55"
-  "\x42\x6e\x0f\x32\x13\x6e\x7f\xd9\xa0\x2c\x9e\xd6\x37\xf9\xfe\x9e"
-  "\xeb\x17\x65\x38\x96\x96\xbb\x3f\x28\xcf\xed\x88\xe3\x3c\xb7\x7f"
-  "\x71\x48\x9a\xdb\xbf\x08\xeb\xd4\xfb\x83\xd2\x3f\xf7\xbc\xff\x0f"
-  "\xfd\x73\x4f\xfb\xff\xb8\xaf\x15\xa6\x7f\x2e\x7f\xdf\x0b\xfa\xe7"
-  "\x65\x7c\x4c\xff\x8b\x40\x9e\xdb\x83\x03\x3a\x90\xdb\x0a\xfd\xf6"
-  "\xcf\x8b\x84\xdc\x8e\x38\x4c\xb8\x7d\x26\x4e\xd9\xd8\xc1\x2f\x4e"
-  "\xfb\xfe\x5e\xef\xa1\x3d\x78\xdc\x40\xee\x3e\xa5\x3c\xb7\x07\xef"
-  "\xe6\xb9\xfd\x50\x9e\x34\xb7\x87\x5c\xed\xd4\xfb\x94\xd2\x43\x96"
-  "\x7a\xe6\xf6\x90\x49\xb2\xf6\x74\xa1\x87\xc8\x5f\x07\x4f\x0f\xd9"
-  "\xc3\x8f\x5f\x0c\xe1\xe7\xbf\xd3\x0f\xd5\x76\x1c\xb7\x15\xee\x5f"
-  "\x4a\x0f\xd9\x28\xe4\xf6\xe0\x7c\xc2\xed\x7f\x15\x28\x1b\x27\x79"
-  "\xa8\xd8\xf7\x71\x92\x61\xc5\xec\x3b\x4c\x99\xfb\xa5\xf2\xdc\x1e"
-  "\xba\xa6\x6d\x6f\x22\x7a\xd8\x6e\x57\x6e\xb7\xed\x4d\x44\x47\x1e"
-  "\xea\x34\xfb\xa5\xd2\x91\xa3\x3c\xf3\x38\xb2\x9f\xbc\x31\x91\xc8"
-  "\xdd\xf2\x79\x1c\x99\xc2\x8f\x89\x44\x3a\xcd\x7f\x19\xe6\xf8\x26"
-  "\xf9\xed\xdf\xb3\x88\x1e\x36\xc6\xe3\x9e\x45\xf4\xb0\xf0\xdb\xb6"
-  "\x8f\x2a\x1d\x99\x20\xd8\xb3\x88\x1e\xba\xc4\xce\xb6\x85\xaf\x2c"
-  "\xca\xc6\x55\x86\x1d\xf6\x7d\x5c\x25\x8a\xbc\xdf\x95\xb9\x6f\x2b"
-  "\xdf\x16\x1e\xde\xc4\xb7\x85\xa8\xfd\xd2\x6d\xe1\x91\xe3\x9d\x66"
-  "\xdf\x56\xfa\x91\xb1\x9e\xdb\xc2\x23\x7a\x79\x63\x28\x8f\xc8\xdf"
-  "\x07\x86\x7e\x24\x95\x1f\x43\x79\xe4\x30\xdf\x16\xa2\xac\x1d\xd7"
-  "\x16\xa2\x26\x7a\x6e\x0b\x51\x91\xb7\x6d\x3f\x57\xfa\x91\x69\xc2"
-  "\xb6\xf0\x70\x06\x69\x0b\xd5\x4b\x94\x8d\xc3\x44\x29\x7a\xff\x2d"
-  "\x6c\x0b\x8f\x95\xb1\xef\xbe\x65\xee\x1f\xcb\xb7\x85\xe1\x79\x7c"
-  "\x5b\x78\xcc\x4d\xcf\xf3\x6d\xe1\xd1\x53\x9d\x66\xff\x58\xfa\xd1"
-  "\xc9\x9e\xdb\xc2\xa3\x51\xf2\xc6\x5c\x1e\x3d\x24\xbf\x2d\x3c\xea"
-  "\xb4\xfe\xe9\x51\xa7\xf5\x4f\xd1\x01\x1d\xd7\x16\x1e\x9b\xee\xb9"
-  "\x2d\x3c\x36\xf2\xb6\xed\x2b\x4b\x3f\x6a\x10\xb6\x85\xe1\x99\xa4"
-  "\x2d\xfc\xa7\x49\xd9\xb8\xcd\x63\x5e\xe8\xff\xf6\xc6\x6d\x7e\x79"
-  "\x9a\x9d\x17\x20\x73\x1f\x5b\xbe\x2d\x44\xef\xe6\xdb\xc2\x2f\x8f"
-  "\x4b\xb7\x85\x11\x35\x9d\x66\x1f\x5b\x7a\xc4\x4c\xcf\x6d\x61\x44"
-  "\x8c\xbc\x31\x9a\x11\xc7\xe5\xb7\x85\x11\xd9\xfc\x18\xcd\x88\xd3"
-  "\x7c\x5b\xf8\x55\x68\xc7\xb5\x85\x5f\xce\xf5\xdc\x16\x7e\x19\x77"
-  "\xdb\xf6\xb7\xa5\x47\x2c\x11\xb6\x85\xe8\x7c\xd2\x16\xbe\x5d\xad"
-  "\x6c\x9c\xe7\x97\x66\xdf\xc7\x79\x46\x99\xd9\x39\x13\x32\xf7\xd3"
-  "\xe5\xdb\xc2\xaf\xf6\xf3\x6d\x61\xd4\x29\xe9\xb6\x30\xf2\x62\xa7"
-  "\xd9\x4f\x97\x1e\x39\xcf\x73\x5b\x18\x39\x4e\xde\x98\xce\xc8\x53"
-  "\xf2\xdb\xc2\xc8\x02\x7e\x4c\x67\xa4\x99\x6f\x0b\xbf\xd6\x75\x5c"
-  "\x5b\x18\xb5\xd4\x73\x5b\x18\x35\xe9\xb6\xed\xb3\x4b\x8f\xcc\x10"
-  "\xb6\x85\x5f\xed\x21\x6d\xa1\x16\x29\x1b\x17\x1a\x55\xef\xfb\xb8"
-  "\x50\x4c\x3d\x3b\x9f\x44\xe6\xbe\xbe\x7c\x5b\xf8\xf5\x21\xbe\x2d"
-  "\xc4\x48\x7f\xe7\x81\x7e\xfc\x46\xa7\xd9\xd7\x97\x7e\xdc\xf3\xf7"
-  "\x8f\xe8\xc7\x3d\x7c\xff\x48\x6c\x0c\xe8\xf1\x1a\xf9\x6d\xe1\xf1"
-  "\xbd\xfc\x18\xd0\xe3\x4e\xeb\xff\x46\x0f\xee\xb8\xb6\x10\xe3\xf9"
-  "\xfb\x0f\x74\x8c\x17\xdf\x7f\x50\xb8\xdf\x2f\xfd\x78\xa6\xb0\x2d"
-  "\xfc\xba\x98\xb4\x85\x0b\xeb\x95\x8d\x23\xc5\xb4\x3b\xfe\x8f\xe3"
-  "\xfc\xd6\x50\xf7\x71\xa4\xf2\xda\x68\xf4\x8b\xa9\xb8\x2d\x3c\x51"
-  "\x68\xcd\x0b\xab\xc3\xfb\x0b\xdb\xc2\xb9\x3d\x28\xd7\x72\x7b\xbc"
-  "\x34\x58\xc9\x1e\x94\x16\x5b\xdb\x1e\x94\x64\xef\x0f\x44\xe1\xb5"
-  "\xc0\x78\x4d\xb0\x35\x98\xec\x3f\xc9\xe0\x39\x51\x78\x8e\xd4\xb9"
-  "\x32\x76\x7f\x95\xd5\x56\xa8\xfb\x85\x76\xf6\x9f\x4c\x32\xa3\xf2"
-  "\xa4\x95\xc8\x1a\x92\x99\x40\xd6\x09\x3f\x11\xc9\xee\x3f\x39\x43"
-  "\xdb\x37\xeb\x3f\x28\x34\x08\xef\x3f\x99\xc4\xd8\xd3\xcd\x8c\xa5"
-  "\x02\x6a\x5a\x9e\x04\xf6\x9d\xc9\xed\x41\x49\x3f\xb1\x1d\xd7\xdd"
-  "\x3a\x43\xdf\x77\xe7\x7f\x24\xf6\x17\xa6\x9f\x90\xbf\x0f\x2c\xfd"
-  "\xc4\x38\x7e\x7c\xe7\x89\x6c\x9e\xa3\x4f\xb0\x7d\x30\xfc\xd5\x97"
-  "\x27\x82\x8f\xd9\x7c\x31\xa0\x55\xc9\xde\x1b\xf4\x13\x45\xed\x63"
-  "\xc6\xce\x11\x71\xf3\x5f\x3c\x66\xb1\x93\xac\x79\x6a\x3c\x6f\x39"
-  "\xd9\x7b\xcc\xfc\xaf\xdd\x1e\xcc\x9e\xac\xf5\x1e\xb3\xd8\xf1\x42"
-  "\xcc\xc4\xc6\x21\x62\x87\xcb\xc7\x0c\x2f\x5d\x71\x8c\x43\xc4\xc6"
-  "\xf2\x98\xc5\xe6\x12\xcc\x9e\xac\x26\x98\x5d\x8a\x6a\x55\xb4\x7f"
-  "\x47\x6c\x92\x17\x98\xe1\xb9\x0f\x1e\xda\xd9\x6f\x02\x00\xb3\x3a"
-  "\xbc\xdf\xb2\xf7\x98\xf5\x38\x77\x7b\x30\x1b\x93\xef\x3d\x66\xbf"
-  "\xf1\x73\xc1\x4c\x24\x5e\x1e\x23\xff\x9b\x9d\xf4\x98\x12\x3e\x5e"
-  "\x1e\xd3\xc4\x63\xf6\x9b\x38\x82\xd9\x98\x6c\x82\xd9\xf7\xd0\x97"
-  "\x2a\x89\x1f\x7f\x13\xda\x3e\x66\xec\x3b\x7d\x0f\xed\xec\xa9\xc3"
-  "\xd6\x3c\x0d\x9e\x3f\x2c\xa3\x9d\x85\x7c\x79\x7b\x30\x7b\x6a\x9c"
-  "\xf7\x98\x3d\x75\x50\x88\x99\x58\x5c\xf7\xd4\x0e\xf9\x98\x3d\x65"
-  "\xe0\xe3\xba\xa7\x8a\x78\xcc\x9e\xb2\x12\xcc\x9e\x8a\x25\x98\xd5"
-  "\x67\xb6\x2a\xda\x47\xe4\xa9\x76\xc7\xbf\xb0\x0e\x6d\x0d\x75\x8f"
-  "\x73\x78\xcc\xc6\x1a\x01\xb3\x3a\xbc\xff\xb4\xf7\x98\x3d\xba\xf9"
-  "\xf6\x60\x36\x16\x79\x8f\xd9\xd8\xb9\x2e\x98\x89\xc4\x1f\x63\x27"
-  "\xca\xc7\x6c\x6c\x3f\x3e\xfe\x18\x9b\xc4\x63\x36\xb6\x98\x60\x16"
-  "\xd7\x44\x30\xbb\x5c\xda\xaa\x68\x2f\x92\xb1\xab\xdb\xc7\x8c\x7d"
-  "\x07\xeb\xa1\x9d\x3d\x1d\x6e\xcd\xd3\xe2\x79\xdb\x32\xda\xd9\x0b"
-  "\x4f\xdc\x1e\xcc\x7e\x5b\xe2\x3d\x66\x4f\xf7\x17\x62\x26\xa6\x93"
-  "\x9f\x96\xbf\x0f\x36\xfd\xdb\x2a\x5e\x27\x3f\x1d\xca\x63\xf6\x74"
-  "\x32\xc1\xec\xb7\x45\x04\xb3\x2b\xb5\xad\x8a\xf6\x33\x79\x5a\x72"
-  "\xff\x2f\x4f\xba\xd1\x31\x2f\x9f\xc7\x6d\x5c\x75\xe7\xd1\x8e\xe3"
-  "\x52\xbc\xc7\x6d\xdc\x99\xf6\xb5\xe3\xb8\x23\xf2\x71\x1b\xb7\x91"
-  "\xd7\x8e\xe3\xca\x79\xdc\xc6\xf7\x23\xb8\x8d\x4b\xf6\x4d\x3b\x8e"
-  "\x6b\x77\xfd\xab\x98\x76\x74\xc7\x6d\x42\x6e\xe7\xd1\x8f\x13\xc2"
-  "\xbd\xc7\x6d\xc2\x96\xf6\xf5\xe3\x84\xa5\xf2\x71\x9b\x10\xc3\xeb"
-  "\xc7\x09\xeb\x79\xdc\x26\x9c\x26\xb8\x4d\xe8\xe7\x9b\x7e\x9c\x50"
-  "\xa8\x44\x3f\xba\xe3\x96\x30\xae\xf3\x68\xc8\xf8\x6a\xef\x71\x4b"
-  "\x18\xd3\xbe\x86\x4c\x18\x22\x1f\xb7\xf8\x26\x5e\x43\x26\x8c\xe4"
-  "\x71\x4b\xc8\x24\xb8\xc5\x9f\xf6\x4d\x43\x26\x24\x2a\xd1\x90\xee"
-  "\xb8\x3d\xa3\xea\x3c\x3a\x72\x62\xae\xf7\xb8\x4d\xb4\xb5\xaf\x23"
-  "\x27\xca\xff\x66\x31\x3d\xb1\x98\xd7\x91\x13\x1b\x78\xdc\x9e\x21"
-  "\xdf\x60\xa1\x27\x66\xfa\xa6\x23\x9f\x69\x77\xff\x0f\x31\x1d\xe9"
-  "\x8e\xdb\xb3\x87\x3b\x8f\x96\x7c\x56\x86\xfe\x7f\xd6\x55\xff\x8b"
-  "\x68\xc9\x67\x15\xe8\xff\x67\x0d\xbc\x96\x7c\xd6\x49\xff\x3f\xcb"
-  "\xe9\xff\x67\x63\x7d\xd3\x92\xcf\x7a\xa1\xff\xdd\xb5\xa4\x3b\x6e"
-  "\x93\x97\x74\x1e\x3d\x39\x59\xe5\x3d\x6e\x93\xe7\xb5\xaf\x27\x27"
-  "\xcb\xff\x0e\x14\x3d\x59\xc7\xeb\xc9\xc9\xc9\x3c\x6e\x93\x4b\x08"
-  "\x6e\x93\xac\xbe\xe9\xc9\xc9\x19\xed\xe1\x66\x0b\x0d\xab\x63\x44"
-  "\xc6\x21\x4f\x1a\xa2\xb9\xbd\x09\x13\x63\x6d\x61\x61\x75\x72\xbf"
-  "\xef\xe2\xd8\x73\xfa\x04\x30\xf3\x1c\xfd\x7c\x8d\x4f\xfb\x4e\xd3"
-  "\xcf\x6f\xf1\x79\xdf\x69\xfa\xf9\x29\xb7\xec\xfb\x2e\xf4\xf3\xa3"
-  "\x65\xef\x3b\x4d\x3f\x1f\xc8\x6b\xd0\xe7\x13\x78\xac\x13\xd9\xf9"
-  "\x09\xb2\xf6\xa3\xa6\x9f\xab\xf2\x69\x3f\x6a\xfa\xf9\x33\x84\x5f"
-  "\xcf\x65\xb3\xfb\x51\xd3\xcf\x97\x77\xc8\x77\x5f\xe8\xe7\x46\xe2"
-  "\xfd\xa8\x99\xcd\x96\x60\x45\xfb\x23\xd3\x89\x09\xed\xf3\x59\x6d"
-  "\x60\x44\xc6\x68\x79\x3e\xbf\x10\x6a\x0b\x53\x1b\xe4\x7e\x67\x46"
-  "\xc8\xe7\xa9\xfb\x7d\xe3\xf3\xd4\xe9\xbe\xf3\x79\x6a\xc4\x2d\xfb"
-  "\xce\x0c\x3d\x35\x44\x3e\x9f\xa7\x54\xf3\xda\x7c\xaa\x8e\xe7\xf3"
-  "\x0b\x93\xe4\xf3\x79\x4a\xa1\x6f\x7c\x9e\xfa\x2e\xe1\xf3\x94\x24"
-  "\xc2\xe7\xa9\x05\x1d\xf2\xfd\x19\x7a\x4a\x20\xe1\xf3\xb5\x44\x65"
-  "\xfb\x4f\xbf\xa0\xf3\x82\xcf\x75\x8c\xc8\xf8\x35\xcf\xe7\xe9\xb5"
-  "\xc0\xe7\x3a\xb9\xdf\xbb\x11\xf2\x79\xfa\x1a\xdf\xf8\x3c\x7d\x88"
-  "\xef\x7c\x9e\xd6\x7c\xcb\xbe\x77\x43\x4f\xfb\x56\x3e\x9f\xa7\x15"
-  "\xf1\x31\xcb\x34\x0b\xcf\xe7\x17\xc3\xe5\xf3\x79\x9a\xd1\x37\x3e"
-  "\x4f\x5f\x4a\xf8\x3c\x2d\x92\xf0\x79\x7a\x4a\x87\x7c\x07\x87\x7e"
-  "\xa1\x9a\xf0\xb9\xa1\x50\xd9\xfe\xde\xd3\x25\xf7\x3f\xe6\xf9\xac"
-  "\x31\x30\x22\x63\xfb\x3c\x9f\x93\x4a\x6c\x61\x1a\x83\xdc\xef\xee"
-  "\x08\xf9\x9c\xe4\xdb\x77\x2e\xe8\x19\xbe\x7f\xe7\x82\x9e\xe1\xc3"
-  "\x77\x2e\x5c\xbe\xbb\x43\xcf\xf8\x50\x3e\x9f\x67\xac\xe6\x63\xb9"
-  "\x19\x26\x9e\xcf\x49\x0d\xf2\xf9\x3c\x23\xc6\x37\x3e\x27\x91\xef"
-  "\x5f\xd0\x33\x10\xe1\x73\xd2\xc8\x0e\xf9\x1e\x0f\xfd\x62\x11\xe1"
-  "\xf3\xcd\x3a\x65\xfb\xa7\x27\x99\xbc\xe0\x73\x1d\x23\xf2\xde\x83"
-  "\xe7\xf3\xec\xf5\xc0\xe7\x3a\xb9\xdf\xff\x11\xf2\x79\x76\x7f\xdf"
-  "\xf8\x3c\xeb\xa4\xef\x7c\x9e\xb5\xfd\x96\x7d\xff\x87\x9e\xb5\x56"
-  "\x3e\x9f\x67\x8d\xe3\x63\xdc\x59\x4e\xef\xff\x67\x1f\x93\xcf\xe7"
-  "\x59\xbe\x7d\x17\x88\x9e\x1d\x46\xf8\x3c\x93\x7c\x17\x88\x9e\x1d"
-  "\xd8\x21\xdf\x05\xa2\x67\xae\x26\x7c\x6e\x8e\x54\xb6\x3f\xfd\xec"
-  "\xec\xf6\xf9\xac\x35\x30\x22\xef\x84\x78\x3e\xbf\x34\xc9\x16\xa6"
-  "\x35\xc8\xfd\x0e\x91\x90\xcf\x73\x2e\xfb\xc6\xe7\x39\x3b\x7c\xe7"
-  "\xf3\x9c\xb9\xb7\xec\x3b\x44\xf4\x9c\x89\xf2\xf9\x3c\xa7\x1f\x1f"
-  "\xfb\xcf\x71\x7a\xff\xf7\x92\xfc\xef\x13\xd1\xc9\x66\xdf\xf8\x3c"
-  "\xe7\x3c\xe1\x73\x72\x21\xe1\xf3\x9c\xea\x0e\xf9\x3e\x11\x9d\x3c"
-  "\x8e\xf0\xb9\x35\x55\xd9\xfe\xff\x2f\xb5\x3b\xff\x43\x6c\x7c\xc3"
-  "\x31\x2e\xc5\x73\x7a\xae\xde\xf7\x31\x0e\xc3\x51\xdf\x38\x6d\x58"
-  "\xe8\x3b\xa7\x0d\xa3\x6e\xdd\x18\x87\x41\xfe\xb7\xfe\xe8\x97\x2d"
-  "\xfc\x18\x87\x21\x8a\xe7\xf4\x5c\x83\x7c\x4e\xbf\x5c\xe2\x1b\xa7"
-  "\x0d\x87\x08\xa7\x5f\x5e\x42\x38\x6d\x28\xee\x98\x31\x8e\x97\x75"
-  "\xbe\x8d\x71\xcc\x8d\x52\x32\xc6\xe1\xce\xe9\x57\xad\xbe\x8f\x73"
-  "\xbc\x9a\xe7\x1b\xa7\x5f\x1d\xe3\x3b\xa7\x5f\x0d\xb9\x75\xe3\x1c"
-  "\xaf\x34\xcb\xe7\xf4\x2b\xc7\xf8\x71\x8e\x57\x03\x78\x4e\xa7\x8c"
-  "\x94\xcf\xe9\x57\x36\xfa\xc6\xe9\x57\xb7\x10\x4e\xbf\x12\x47\x38"
-  "\xfd\xea\xfa\x8e\x19\xe7\x98\xdb\xe0\xdb\x38\x47\x4a\x80\x92\x71"
-  "\x0e\x77\x4e\xcf\xaf\xf2\x7d\xac\x63\xfe\x5c\xdf\x38\x3d\xbf\x8f"
-  "\xef\x9c\x9e\x77\xfe\xd6\x8d\x75\xcc\x3b\x29\x9f\xd3\xf3\xf2\xf9"
-  "\xb1\x8e\x79\xd5\x3c\xa7\x17\x04\xcb\xe7\xf4\xbc\x69\xbe\x71\x7a"
-  "\xfe\x4c\xc2\xe9\x79\xfd\x08\xa7\xe7\x27\x76\xcc\x58\x47\x4a\x99"
-  "\x6f\x63\x1d\xf3\xab\x95\x8c\x75\xb8\x73\x7a\xe1\x1e\xdf\xc7\x3b"
-  "\x16\x8e\xf2\x8d\xd3\xc6\xcb\xbe\x73\xda\x78\xe8\xd6\x8d\x77\x18"
-  "\x77\xcb\xe7\xb4\xd1\xe9\xfb\x17\x46\xa7\xf5\xff\x0b\x6b\xe5\x73"
-  "\xda\x18\xe9\x1b\xa7\x17\x0e\x27\x9c\x5e\x60\x21\x9c\x5e\x38\xb8"
-  "\x63\xc6\x3b\x16\x14\xf8\x36\xde\xb1\xb0\xdd\xfd\x2f\xc4\xc6\x3b"
-  "\xdc\x39\xbd\x24\xd5\xf7\x31\x8f\x25\x21\xbe\x71\x7a\xf1\x51\xdf"
-  "\x39\xbd\x78\xcb\xad\x1b\xf3\x58\xbc\x54\x3e\xa7\x17\xc7\xf0\x63"
-  "\x1e\x8b\x9d\xe6\x3f\x2d\x29\x95\xcf\xe9\xc5\x2a\xdf\x38\xbd\xa4"
-  "\x1b\xe1\xf4\xa2\x63\x84\xd3\x4b\x50\xc7\x8c\x79\x2c\x32\xfa\x36"
-  "\xe6\xb1\x64\xbd\x92\x31\x0f\x77\x4e\x2f\x1f\xe7\xfb\xb8\xc7\xb2"
-  "\xf3\xbe\x71\x7a\x59\x9e\xef\x9c\x5e\x36\xf3\xd6\x8d\x7b\x2c\x1b"
-  "\x2b\x9f\xd3\xcb\x42\xf9\x71\x8f\x65\x4e\xfb\xdf\x2f\xcf\x94\xcf"
-  "\xe9\xa5\x67\x7d\xe3\xf4\xb2\x1a\xc2\xe9\xa5\xf9\x84\xd3\xcb\x4e"
-  "\x77\xcc\xb8\xc7\xd2\x58\xdf\xc6\x3d\x96\xbb\xcd\x7f\x5b\x3c\x67"
-  "\x7e\xb2\x6e\xc1\x4b\x2f\x2d\x9e\xb3\x44\xb7\x38\x65\xee\xec\x39"
-  "\xa3\x06\x3a\x7e\x8f\x8a\x4c\x1d\x98\xda\x1d\x25\xcf\x9b\x39\x63"
-  "\xd9\xc3\xfc\xc5\x94\x39\xf3\xe1\x4f\x77\x64\x98\xb9\xd8\xa0\x5b"
-  "\xb2\xc2\x38\x47\x87\x7f\xcd\x9b\x6d\x84\x24\x0b\x96\xf0\x67\x9e"
-  "\x99\x93\x32\x33\x75\xee\xfc\x97\x75\x33\x53\xe6\xbe\x3c\x7f\xde"
-  "\x9c\xf9\x4b\x74\x8b\xe6\x2c\x5c\x3a\x77\xd1\x1c\xfc\xff\x62\xdd"
-  "\x4b\x0b\x16\xc1\x89\xd9\x73\xe6\x2e\x9b\xa3\x9b\xb5\xf4\xa5\x97"
-  "\xe6\x2c\x5a\xdc\x1d\x8d\x5f\x9a\xb2\x64\xae\x31\x65\x8e\x2e\x76"
-  "\xfc\xe8\x21\x93\xc6\x3c\x3b\xe9\xf1\xc7\xbb\x23\xa7\x6f\x4f\xeb"
-  "\x98\xdc\x68\x33\x70\x48\x75\x81\xfe\xdd\xe4\x0a\x2d\x42\x5b\x80"
-  "\x9b\x5b\x17\xa1\xe0\xcd\x8b\x90\x6a\xd3\x35\x14\xb0\xe5\x1a\x0a"
-  "\xb4\xbf\x5e\x6d\xd0\xbd\x82\x62\x98\x90\x89\x31\x5b\xaf\xa1\x50"
-  "\x7b\xce\x26\x13\x93\xb3\x29\xc3\x12\xb2\x28\x11\xa7\x65\x42\x16"
-  "\xa6\xe2\xf3\x80\x85\x8a\xc9\xc9\x8c\x3c\x47\xff\x2e\xd4\x12\xb2"
-  "\x38\x2e\xfd\x22\xa2\x98\x5e\xa9\xa5\x07\xec\x16\xea\x28\xde\x35"
-  "\x16\x6c\x85\xe8\x15\x55\x70\x1c\x46\xf4\xca\x14\x38\x56\xc3\x51"
-  "\x06\x87\x05\x8e\x26\x44\xaf\x4a\x86\x63\x2f\x1c\x67\xe1\xa8\x85"
-  "\x03\xce\xad\x0e\x84\x23\x14\x8e\x0c\x38\x0a\xe1\x28\x86\xa3\x8c"
-  "\xe4\xb3\x1a\x8e\x35\x09\x70\xa4\xc2\x91\x8d\xe8\xb4\x58\x38\x20"
-  "\x8f\x34\xc8\x2f\x0d\xf2\x4e\xdb\x08\x07\x3e\x5f\x04\x07\x4e\x7f"
-  "\x9a\x5c\x4b\x2f\x80\x03\x9e\x91\x0e\xf9\x67\x40\xde\x19\x71\x70"
-  "\x4c\x83\xc3\x00\x87\x11\x8e\x5c\x38\x20\x4d\x06\x3c\x6b\x2d\x5c"
-  "\x5b\x0b\xcf\x58\xbb\x04\x8e\x72\x44\xaf\x8b\x84\x03\xca\xf2\xbb"
-  "\x50\x72\xac\x2b\xe3\xff\x67\x8f\x40\x97\xdf\xae\xc7\xe0\xa0\xb5"
-  "\xf7\x9b\x4d\x3f\xb7\x42\xbb\x5d\x39\x84\x59\x87\x68\x26\x67\x71"
-  "\x9c\xf1\xe7\xc8\xef\x12\xbd\xa2\xb9\x12\xbc\x24\x13\xbc\x29\xc3"
-  "\xb4\xb2\x05\xae\xaf\x68\xc6\x36\x6b\xcc\x5a\xd1\x64\x46\x2f\xed"
-  "\xc5\xed\x53\x1e\x3f\x57\x34\x91\xfb\x57\x46\x9b\xfd\x50\x09\xbe"
-  "\x9f\x79\x5d\xbd\x91\x49\x4f\x7c\x0b\xaf\xc3\x85\xfc\xab\xf0\x3a"
-  "\x5d\x26\x5b\xad\x62\x82\x83\x8b\xb1\x8f\x31\xad\xc4\xe5\x5a\x71"
-  "\x8a\xb4\x47\xb8\x0e\x65\xb3\x84\x54\xe3\xf6\xa7\xc2\xbf\x19\xc0"
-  "\x9c\x29\x7c\xb2\x8c\xf8\x9d\x95\x6c\xfc\xd2\x12\x36\x44\x87\xaf"
-  "\x35\xbf\xeb\x6f\x62\xf6\x04\x24\x98\xe6\xb7\xa0\x5a\x7a\xc5\x49"
-  "\xa8\x1b\x05\x3e\x90\x62\x06\xf9\x9b\xec\xdb\x86\xe8\x0e\x01\x0f"
-  "\x70\xba\x4f\xd2\xea\xf0\xdf\x72\x7c\x9d\xc9\x1d\x52\x87\xc7\x81"
-  "\x4c\x69\x6f\x83\x5f\x5e\x71\xaa\x25\xec\xc9\x62\xdd\x33\x41\xcc"
-  "\x39\x7a\xe5\x1c\x28\x1b\x9b\xde\x51\x96\x96\x90\x6a\x23\xce\x9f"
-  "\xd1\xc5\x1a\xe1\x9a\xca\x9e\xb3\x28\x11\xca\xe1\x77\x05\xee\x63"
-  "\xa0\x8c\xa6\x67\xf0\x73\x57\x4d\x87\xb2\x52\xe9\x13\x21\xef\xb7"
-  "\x63\x8d\x1f\xac\x6c\xa2\xf0\x35\x7b\x76\xb5\x01\xf8\x1e\xc8\x64"
-  "\x2d\xcf\x7f\xb3\x37\x52\xed\x7a\x1d\xa1\x9d\xaf\xa3\x80\xc6\xac"
-  "\x55\x93\xcc\xb4\x35\x96\xf8\xbe\x15\x55\x14\xa4\x31\xd3\xab\x22"
-  "\x19\xe0\x2f\xfb\xac\x50\x7d\x92\x87\x67\xed\x6e\x7b\xd6\x36\x7d"
-  "\x12\x7e\x16\xb1\x51\xb5\x81\xfc\x25\x79\xd8\xf7\x74\x31\x62\xfb"
-  "\x61\xdb\x39\xf2\xb0\xe7\x38\xf2\x58\x79\x14\xdf\x0f\xcf\xcc\x65"
-  "\xde\xeb\x62\xb4\x6f\x1b\x6a\x34\xd3\x2b\x8d\xf8\x7a\xd0\x5a\xd4"
-  "\xc0\xc0\x5f\xfc\x7c\x82\x05\xd8\xbe\x0b\xf0\x03\xe3\xc1\x9d\x63"
-  "\xe0\x1c\xdc\x5b\x6d\x5f\xa7\x03\xde\x68\xe2\x08\xae\xab\x23\xe0"
-  "\x8a\x1d\x0e\xdb\xd0\x2a\xe4\x67\x7a\x06\x63\xba\x3a\x4e\x37\xa1"
-  "\x2b\xd8\x75\xf5\xd8\x36\x7b\x0e\x88\xc5\x36\x09\xde\xd5\x1b\xec"
-  "\xb2\xae\xa5\x88\xcd\x03\xea\xe3\x6c\x1f\x5c\x87\xc6\xac\xd5\xa9"
-  "\x2e\x36\x0a\x86\x73\x99\x66\xd4\x52\x8b\xcf\xe9\x1e\x60\xb9\x74"
-  "\x8a\xe1\xf0\xc2\x7c\xc6\xd8\xd9\xf3\xa2\xcd\xf8\xf7\xe4\x08\x14"
-  "\x1c\x54\x85\x28\x5d\x5a\x78\x29\xc1\x78\x48\x1d\x94\xb9\x10\x3f"
-  "\x0b\xfe\xd6\x31\xdb\xfa\x46\xdb\xd6\x41\x1f\xda\xc6\xab\x35\x01"
-  "\xb6\x1c\x4d\x4c\x4b\xd8\x43\x85\xcd\x79\x0f\x26\x31\xd9\x9a\x18"
-  "\xbc\xae\xfc\x1c\xbd\x86\x5d\x6b\xc7\xac\x0b\x40\xe4\x39\x9a\xd8"
-  "\xb4\x14\xc6\x92\x76\x15\xec\xaf\x7e\xa8\xf0\x93\x65\x16\xc0\xe1"
-  "\xc1\x24\x8c\xf3\xa1\x9b\x4d\x14\xde\xeb\x8f\xe9\xb5\xfc\x93\x9d"
-  "\x50\x9f\x1d\x50\x17\xa8\x27\xc2\xf9\x36\x66\xad\x89\xe3\xeb\xb3"
-  "\xba\x1e\x63\x0e\xcf\x48\x24\xcf\x86\x7c\x29\x78\x46\x88\x26\x11"
-  "\xd2\x19\xcd\x7e\xef\xe9\x1c\xf5\x66\x9f\xcd\xa7\xe3\xda\xc8\x9a"
-  "\x64\x0b\xa4\x6d\x5d\xc6\x54\x6d\xfd\x1a\xf2\x5f\x87\x98\x96\x9b"
-  "\x4c\xf9\xea\x04\xa6\x29\xeb\x39\x3c\x7f\xb1\x1a\xa5\xcf\x44\xfd"
-  "\x7a\xac\x65\x2c\xf1\x36\x14\xd4\xa3\x3a\x88\x39\x99\x50\xcd\x7e"
-  "\xf3\x60\x75\x15\x53\x57\x61\x3c\x8c\x56\x9f\x47\x81\x6b\xe6\xa2"
-  "\xd0\xf4\x04\xa8\x4b\x39\xd3\x54\x99\x5a\x8d\x2a\x1a\xe0\x30\x9e"
-  "\x84\x74\x67\xe0\x38\x8c\xd2\x57\x20\xd5\x04\xe8\xcf\xd2\x6e\xa0"
-  "\xc0\x0a\xe3\x0d\x38\x77\x19\xad\x4e\x62\xac\x27\xcb\x71\xba\xe3"
-  "\x28\xde\x6a\x09\x5a\x73\x19\xa9\x76\x3e\x87\xd7\x6a\xd7\xa0\x5d"
-  "\x50\x96\x96\x90\x4d\xc5\xcd\x39\x99\xd1\xd7\x97\x31\xd6\xc6\xac"
-  "\xb4\x91\x66\x34\xdc\x28\xa8\x0b\x2e\x73\x0b\x42\x80\x95\x1f\x4e"
-  "\x63\xcf\x1b\x14\x33\xc3\x8a\xfd\x46\x5a\x24\xe8\x09\xe4\xb8\x8e"
-  "\xaf\x59\xc2\x06\xc5\xc0\xf9\x69\xf1\x56\xa6\x11\x70\x66\xeb\x0d"
-  "\xf6\x9f\xc4\xd5\x7f\x12\x6d\x44\x2a\x78\x46\xa1\xd9\x6f\xaf\x15"
-  "\x3f\x03\xf2\xec\x02\x3c\x9e\x86\xb9\xc1\x5d\x3b\x6c\xf6\xfb\x63"
-  "\x2c\xcf\x17\x16\xff\x2e\x8e\xb2\xc0\xf5\x6a\xb8\x77\x9c\x13\x9f"
-  "\xb0\x7f\x68\xbb\xce\xf5\x53\xd8\xe7\x24\xdb\xb1\xcf\x0c\x0e\x5e"
-  "\x6f\x0b\x1b\x62\x61\x42\x6a\x40\x9f\x68\x03\x19\x8a\x69\x9a\x60"
-  "\x65\x9a\xec\x79\x7d\x70\x1f\x15\x58\x69\x6d\x40\x24\x7d\xfa\x5a"
-  "\x26\xa7\x26\x80\xcc\x0d\x4d\x9f\x8b\xf3\x04\xcd\x92\x9d\x75\x0d"
-  "\x05\xc7\x57\x31\x4d\xb8\x5d\xda\x73\xce\x67\x64\x2d\x42\xa1\x4c"
-  "\xde\x10\xb3\x3d\x4c\x6f\x69\xde\xfd\xa4\x09\xfb\x4e\x26\x2c\xda"
-  "\xcc\x64\xc3\xbd\x5c\x3e\xf0\x5c\x7f\x33\x9d\x1e\x63\x87\xfb\x99"
-  "\xdc\x3e\x31\x1c\x0f\x58\x3f\x47\xfc\x63\x7a\x0c\x33\x10\xae\x65"
-  "\x07\x6f\x84\x6b\xfe\xe7\xe8\xf4\x72\x38\x8f\xe0\xb7\xc9\x94\x76"
-  "\x0d\xe7\x71\x8a\x70\x28\x78\xbd\xe0\x37\x85\xed\xb9\xaa\x1e\xb7"
-  "\x6b\xa2\x2f\xd3\xaf\xf2\xed\xd6\xd1\x4e\xa0\xbd\x86\xf5\x49\x68"
-  "\xcc\xca\x50\x99\xfd\x54\x81\xac\x2f\x87\xfb\x1a\x58\x5f\xb3\x1a"
-  "\x81\x16\x2b\xfb\x2c\x01\xa1\xcf\xca\x11\x82\x34\x7a\xb3\x5f\x97"
-  "\x28\xde\x96\x19\xa3\x71\x5a\xb6\x4d\x42\xdb\x24\xcf\x03\x9e\xc3"
-  "\x3d\xcc\xb6\x87\xb2\xb1\x7f\xc1\x7e\xc6\x4c\x67\x8c\xc4\x3e\x06"
-  "\xda\x67\x13\xf1\xe7\x5d\xe2\xd8\xf6\xf9\xfa\x6f\x53\xa1\x5c\x19"
-  "\xe7\xb8\xb2\x38\x97\xcd\xe1\x4b\x98\x9c\xdf\x36\x91\xb4\x9a\x24"
-  "\x78\xfe\x5e\xb3\x5f\xd7\x40\x67\xae\x91\x7a\xad\xed\x3f\xb4\x1c"
-  "\xfe\x07\xbd\xe1\xc8\x0b\xda\x6a\x00\xf8\xe4\x2f\x31\x07\xb1\xcf"
-  "\xd9\xfe\x3a\xc6\xe3\x69\xd4\x9c\xf3\x34\xf8\xe6\x0c\x8b\xa3\x9d"
-  "\xda\x97\x31\x67\x01\x57\x64\xbf\xc9\x9c\xde\x0a\x58\xc6\xdb\x68"
-  "\x66\x86\x6d\x30\x02\x3d\x6a\xdd\x05\xe7\x77\x2d\xc3\x7a\x2e\x6d"
-  "\x30\xb4\xe5\x00\xf1\xb4\x2a\x84\xd3\xb1\xe9\xb9\xb4\x2d\x21\x4f"
-  "\x23\xb6\xcc\xeb\x68\x3b\x94\xcf\xcf\x51\xa6\x96\x10\xcd\xb8\xc6"
-  "\xac\xb5\x29\x66\x74\x43\x2f\x68\x2f\xaf\x07\xed\x65\x98\x44\xcc"
-  "\x2b\x1a\xea\x92\x03\x7f\xbb\x72\x3c\xed\xf1\x19\xa4\xc0\xab\xb7"
-  "\xaf\x03\xde\x6f\xaa\x19\x0b\xdc\x5f\x64\x46\x53\x58\xff\xb8\x19"
-  "\x7e\xe3\xf3\x38\x0d\x9c\x3f\x66\x46\x53\x4f\x93\x7c\x57\xd5\x63"
-  "\xfc\x5c\xf2\xbd\x48\xf2\x65\xcb\xd2\x03\xe7\x89\xef\xc3\x79\xee"
-  "\xd8\xc6\xd4\xe3\x7c\x1a\xb3\xd6\x05\x38\xf2\xde\x02\xe7\x1c\xf9"
-  "\xc7\xce\x73\x3c\x63\x9d\x1e\x9e\x31\xcd\xb9\xec\xdb\xb7\x31\x0d"
-  "\xa4\x5c\xeb\x62\xcd\x68\x66\x11\xbe\xb6\x09\xce\xe1\x7b\x9d\xda"
-  "\x1b\xcd\x73\x68\x1d\xd4\x3f\x29\xca\xd9\xbf\x03\x46\x3d\x1d\x9a"
-  "\x80\xcb\x2b\xdb\x91\x97\x6b\x3e\x4c\xf6\xd3\xce\xed\x35\x10\xe7"
-  "\x0b\xe9\x4d\x66\x34\x2d\x95\x94\x6b\xa5\xb1\x81\xf0\x1d\xec\xbe"
-  "\xee\x3c\xb6\x3b\xee\x6b\xec\xeb\x38\xdd\xb1\xfb\xc9\x32\x8e\x1b"
-  "\x66\x47\x7f\x04\xb8\x40\x5f\xf4\x3b\x15\xef\xbb\xd7\x9d\xc5\x78"
-  "\x83\x1d\xad\xe0\xff\x83\xb1\x5f\xe2\xda\x64\x33\xee\x83\x1c\x75"
-  "\x87\x7c\x54\xf6\xac\xe5\xd7\x30\xef\xa1\x4f\x43\x4c\xd8\xa0\x2a"
-  "\xc8\x67\x9c\x4b\x9f\xa6\x22\xe9\x52\x1f\xc4\x69\xde\x50\x33\x75"
-  "\x90\xc6\xe8\x48\x83\xaf\x83\x8d\x7f\x0d\xe7\xd6\x9b\xd1\x9c\x50"
-  "\x7c\x2e\x0b\xd2\x98\xe9\x54\xc9\x35\x30\x69\x03\x10\x55\x59\x60"
-  "\xc6\xf1\x21\x6e\xe3\x23\x2b\xfb\x35\xa0\xca\x02\x3b\xb2\xbf\xd7"
-  "\xc5\x12\x93\xc6\x98\x2e\xd0\xeb\xfd\x2a\x9a\xea\x90\x3c\x4d\xf7"
-  "\x3b\xf6\xfb\x45\x4c\x0b\xc4\x31\xab\x1f\x46\xb8\xbf\xbf\x42\x6f"
-  "\x18\x56\x69\xb9\xc6\xfa\x3b\xf8\x9f\x5d\x73\xf9\x06\xc4\x3d\x38"
-  "\xf6\x81\xf8\xd6\x90\x4d\x91\xf8\xc7\x0e\x69\x77\xe2\xf3\x38\x36"
-  "\x82\xb8\x6c\x97\xd3\x35\xe6\x3d\x7f\x23\xb1\xdd\xfa\x8b\xd8\x8e"
-  "\x6c\x79\xad\x4f\x99\x70\x99\xed\x7b\xfc\x8d\xb8\x0e\xe9\xa9\x8c"
-  "\xbd\xd2\xda\x68\xaa\x68\xb0\x21\xdd\x32\x1c\xb7\xad\x3f\x1e\xbf"
-  "\x03\x31\xe0\x0f\x65\xc6\x4d\xeb\xd9\xf9\x0f\x10\xdb\x5e\xb1\x0c"
-  "\xf4\x37\xa6\xdb\x10\xb5\x35\xcd\x3f\xe0\xc9\x02\xc6\x74\x7d\x50"
-  "\x17\xe0\xd5\xfa\xba\xa3\xa9\x08\xc9\xd7\xbb\xeb\xeb\x1c\x75\xdf"
-  "\xc9\xd5\x1d\xce\xb1\xeb\xe5\x87\xe6\x67\xb0\xf5\x35\xd3\x1b\x74"
-  "\x52\x78\x31\xeb\x82\x98\xcf\x0a\xac\x68\x71\x01\xd3\xb2\x78\x07"
-  "\xa2\x6c\xdb\xfa\x9a\x3e\xd8\x79\x16\xfb\xf6\x18\x87\x3d\x59\xdb"
-  "\x41\x4c\x6f\x4c\x43\x41\x97\xe8\x0d\x27\xe2\x57\x23\xf6\x3b\x48"
-  "\x9f\x42\x3a\x79\x65\xdd\xc0\xce\x2f\xa8\x80\x58\x39\xde\xc6\xd8"
-  "\x49\xff\xb4\xe1\xea\x04\x2e\x3f\x7c\xcd\x81\xdf\x4e\x2e\x86\x55"
-  "\xf0\x0c\xc9\xfd\x4f\x3c\xd4\x35\x58\xbc\xae\xaf\x1d\x54\x5e\xd7"
-  "\xd7\x32\xdc\xeb\xfa\x5a\xcd\xad\xad\xeb\x6b\xb5\x0a\xea\xaa\x13"
-  "\xaf\xeb\xef\x77\x2b\xaf\xeb\xef\x53\xdc\xeb\xfa\xfb\x13\xb7\xb6"
-  "\xae\xbf\xaf\x52\x50\xd7\x48\xf1\xba\x6e\xdc\xa2\xbc\xae\x1b\x13"
-  "\xdd\xeb\xba\xf1\xe0\xad\xad\xeb\x46\xc9\xfd\x6f\x19\x2a\x88\xc1"
-  "\xfe\x09\xfc\x52\x4b\x5a\x33\xe8\xba\x6d\x91\x19\x6b\x76\x23\xaa"
-  "\xbc\xa1\x09\x55\xf4\x3b\x8b\x35\x33\xf5\x90\x91\xd5\x3d\x23\x99"
-  "\xd7\xab\x33\x2a\x0a\xea\xe1\xfc\x05\x74\x32\xb5\x09\xc5\x2c\xc2"
-  "\xfe\x77\xd3\xda\xca\x64\xb9\xfe\x77\xd3\xb8\x36\xff\x6b\x7d\x98"
-  "\xf3\xb9\x9b\xf7\x57\xd4\xb7\x20\x5c\x7f\xf8\x7f\x7b\x9b\xff\x5d"
-  "\x47\xec\xed\xea\x7f\xb1\x3d\x2a\x9b\x9a\x04\xfe\x97\xac\x85\xda"
-  "\x3c\xc7\xd5\xf7\x66\x5d\x42\x48\xdc\xf7\x6e\x1e\x8d\x7d\xef\x4e"
-  "\xb8\x2e\xaf\xfc\x9b\x03\x1d\xbe\x37\x1b\x9e\xe9\xec\x7b\x3f\x4b"
-  "\xc6\x7d\xf4\xe6\x64\x65\xbe\x77\x73\xb2\xa3\xde\x3b\xb8\x7a\x83"
-  "\xad\xca\x84\xbe\x77\x73\x81\x37\xbc\x65\xb6\x85\x15\x7e\x70\x5f"
-  "\x93\xbf\x7d\x4f\xd7\x62\xdc\xbf\x35\x82\x4d\xfe\xb2\xb3\x49\x75"
-  "\x81\xfe\x03\x99\xab\xd5\x98\xec\xc7\xec\xe9\x92\x18\xbf\x84\xf9"
-  "\x86\x19\xd8\xb5\x18\x8f\x47\xe2\xb8\x1a\xae\x4f\x64\xde\xed\x92"
-  "\x28\xaf\xdc\x24\x4f\xe6\x3d\x95\x25\x0d\xda\xcb\x07\xcb\x9a\x28"
-  "\xfb\xaa\xc4\x20\xc0\x21\x98\xc9\xeb\x63\x66\x5e\xeb\xb6\xfe\x7a"
-  "\xde\xd0\x84\xe3\xfa\xf3\x08\xa7\x65\xd6\xaa\x46\xfa\x50\xfe\x6a"
-  "\xcf\xe5\xcf\x0c\x51\x50\xfe\x6a\x19\xe5\xaf\xf6\xaa\xfc\x6a\x28"
-  "\x7f\x4b\xb4\x3f\xc4\x82\xd4\xa7\x2d\xd1\x2a\x79\xe5\xc9\x4c\xf1"
-  "\x0a\x63\xdf\x9e\xe1\xb5\xff\x63\xd4\x83\xcc\x1f\xec\xb4\x50\xe0"
-  "\x03\xd8\x3e\x1c\xb7\x3d\xe2\xff\xea\x20\x66\xfe\x86\x21\x3e\xc9"
-  "\x22\xd3\x27\x6d\x91\x5c\xff\xe4\xfe\xfc\x7b\x63\x6e\xc3\xf3\xa5"
-  "\xeb\xef\xea\x13\x0f\x04\x54\x49\xfa\xc4\x6d\x7d\x63\xdc\x7d\x62"
-  "\x56\x9e\x7c\x9f\x98\x95\xe4\xee\x13\xb7\x1e\xe5\x7d\xe2\xd6\xfd"
-  "\xca\x7d\xe2\xd6\x15\xde\xfb\xc4\xad\x93\x95\xf9\xc4\xad\x3a\xcf"
-  "\x3e\x71\x6b\xaa\x32\x9f\xb8\x35\xd5\xdd\x27\x66\x55\x0b\x7d\xe2"
-  "\x56\xc9\x77\xbd\x4c\x26\x63\x84\x3e\x3a\xf0\x12\x9d\x9d\x61\x5d"
-  "\x07\xf1\x6c\xf6\x72\x03\xf4\xb3\x8d\xcc\x16\xc6\x68\xa7\xa2\xb0"
-  "\x5f\x89\x69\x6c\x34\x04\xd8\x97\xeb\x03\x99\xde\xc1\x8f\x32\xad"
-  "\x5a\x3c\x7e\x17\x0e\xe5\x0f\x62\x1a\xf5\xbd\x98\xe5\xfa\xde\x05"
-  "\x37\x51\x28\x1c\xda\x02\xae\x3f\x86\xff\x23\x99\xe5\xda\xee\x59"
-  "\xcb\xd0\xe0\xa0\x06\x14\x00\x65\x48\x0c\x5a\x1b\x8c\xc0\x07\x85"
-  "\xe2\xff\x99\x75\xdb\xd1\xae\x9b\x48\x15\x94\x0a\xd8\x84\xc0\xf3"
-  "\x52\x83\x18\x66\xb1\x1e\xed\x5a\x04\x71\x35\x85\xb4\x3b\x29\xa6"
-  "\xd8\xda\xa8\xa7\x6c\xa1\x0f\x21\x82\x4f\x4e\x14\x1b\x7b\xe5\x0e"
-  "\x29\xb7\xab\x87\x94\xd8\xd2\x0d\x34\xb3\x2a\x91\xc6\x65\xb5\xe5"
-  "\x0e\x29\x66\xb6\xc1\x91\x6e\xe8\x85\x35\x34\xc4\xdd\x91\x4c\xa3"
-  "\xb6\x3b\xc4\xe4\x83\x77\x2e\x43\xe1\x3b\x6e\x22\x3d\x73\x5d\x4f"
-  "\x01\xfe\x89\xf8\x7b\xa2\x60\xa3\x44\x3b\xb5\x1d\xc1\x35\x15\xf6"
-  "\x89\x0c\x7e\xbe\x15\x9e\xdf\x0a\xcf\x6f\xc1\xdc\x46\xda\x5d\xf0"
-  "\x7c\xdb\x72\xbd\xcc\xf6\x92\xc3\xbe\x7b\x70\x94\xcb\x3e\x38\xb8"
-  "\x8a\x39\x00\x07\x2e\x17\xd8\x70\x17\xb6\xc9\x43\xc1\xa7\x71\xd9"
-  "\xb6\xdc\x44\x83\xa1\x9c\xe1\x50\x06\x3d\x3c\x17\xef\xc5\x92\xf8"
-  "\xe2\xc2\x60\xcc\x51\x41\xd9\x6c\x39\x5c\xd9\x7e\xd0\xe3\x3d\x8c"
-  "\xda\xca\x86\x9f\x85\xed\x23\xf5\x9e\x33\x7e\xcd\x7d\xb8\x6d\x7e"
-  "\x17\x94\xda\x35\x0e\xbf\xf3\xbc\xbe\xca\x20\x93\xab\x39\xe5\x52"
-  "\x7c\xd9\x7a\x00\xf5\x63\x82\x17\x1a\x26\x6c\xf8\x86\x89\xb7\x22"
-  "\xb4\xe1\x00\x1a\x5c\x09\xed\xba\xa2\xe9\x32\x62\x42\x16\x1a\x8e"
-  "\xeb\xeb\x65\x3e\xeb\xf5\x68\xa9\x67\x6d\x5e\xc7\x54\xd9\x43\x87"
-  "\x58\x98\xd0\xa1\x71\x5b\xd7\x31\xa9\xad\xe1\xfe\xd9\x2d\xe1\x5d"
-  "\x92\x66\x58\x83\x81\xd7\x4c\xaa\x6e\x11\xd2\x5d\xa0\xf3\xd7\x7c"
-  "\x7e\x1a\xe2\xd2\xa9\x28\xe0\x1c\x9d\x5f\x92\xfe\x15\x7e\x1f\xf4"
-  "\x7a\x99\xf0\x7d\xd0\xeb\xf5\x88\xce\x9d\x86\xe8\xbc\x14\x44\x6f"
-  "\xcb\x46\x90\x4e\x78\xfc\x4f\x11\xc9\x2b\x77\x44\xfc\xbe\xfb\x50"
-  "\x9a\x95\xf9\x8e\xc9\xae\x29\xcd\xa2\x98\xa6\xf8\x08\x3f\xb3\x69"
-  "\x19\x7e\x4f\x92\x3b\x0c\x6c\xfa\x3d\xf4\xb5\x41\x17\xe8\x37\x6c"
-  "\x80\x29\x32\x2e\x42\xf7\x5c\xa2\xdf\xb0\xe2\x76\x13\xd4\xd0\x35"
-  "\xce\x96\x9e\x88\xac\xba\x27\x4d\xad\xb9\x43\xcc\xb6\xdc\x3e\x31"
-  "\xf6\xe0\xe5\x86\xf4\x8b\xa8\x1f\x7e\xbf\x09\x6d\x23\x71\x86\x2d"
-  "\x00\xb7\xc7\x44\xd3\xac\xcf\xd1\x85\x25\x88\x4a\xbf\x81\x7a\x02"
-  "\x37\xdb\xda\xd5\xf8\xfa\xa0\xa6\x35\xf5\x8c\x1d\xb7\x2d\x3c\xbe"
-  "\x0a\xd7\x7a\xa5\xdd\x80\xf8\xde\x52\x87\x0a\x16\xa1\x50\xdb\x62"
-  "\x43\x6f\xcb\x75\xc3\x3d\x6f\xd9\x51\x68\xaf\x06\x14\x5c\x70\x0d"
-  "\x38\xb5\x18\xf8\x74\x0d\xda\x99\x85\xb4\x33\xbc\x9e\x7e\x27\x6e"
-  "\x63\x9b\x3f\x39\xbb\xeb\x1a\x69\x63\x2c\x8f\x70\x1b\x5b\x00\x3c"
-  "\x9a\x8f\xfb\x0f\xe0\xd1\x3a\x68\x63\xd0\x2e\x98\xac\x9c\xa2\x82"
-  "\x75\x0c\x5a\x33\x17\x51\xbb\x2e\x75\xc5\xd7\xfc\xfc\x23\x28\xdd"
-  "\xe7\x09\x4d\x88\x1f\xeb\xc8\x3f\xd8\x32\xb0\x4b\x92\xee\x19\xe6"
-  "\x87\x73\x74\xae\x1e\xce\x07\xe8\x9e\x7b\x30\x18\xec\x7d\x90\x8c"
-  "\xcd\xe5\x97\xe0\xf1\x4e\x33\xd8\x02\xdb\x45\xf7\x0c\x7a\xf0\x1c"
-  "\xfd\xba\x0d\xdb\x71\xf9\x5e\x44\x1b\x7f\xcd\xd4\x82\xfd\x54\x64"
-  "\x4c\xf7\x75\x76\x9f\x02\xfc\x0e\xfd\x0b\xf6\xfd\x14\xb9\xc7\x06"
-  "\x76\xb3\x06\xd7\x04\xd8\x43\x1f\x0a\x36\xbd\xd2\xc2\xfa\x21\x6c"
-  "\xc7\x0b\x29\x88\x9a\x51\x0f\xb6\xb2\x81\xad\x1a\xf5\x81\xe0\x8f"
-  "\x12\xb0\x3f\x62\xb2\x83\x23\x57\x9b\x19\x7b\x7c\x32\xcd\xa4\x2d"
-  "\x44\x01\x95\xa9\x36\xf4\xa2\x11\x31\x6b\x2e\x83\xbd\x1a\xce\x22"
-  "\xf0\x4b\xbd\xc0\x67\xf5\xde\xb1\x0c\x85\x62\x7b\xf5\xac\x07\xad"
-  "\xf2\xfa\xe2\xa4\x03\x69\x65\xfe\x36\xe0\x2f\xf6\x4f\x41\x6b\xfd"
-  "\xba\x41\x3b\xeb\x95\x89\xdb\x23\xb4\xcf\xa0\xb5\xac\xbf\x4c\x2c"
-  "\x80\x76\x68\x5d\xae\x7f\xa0\x75\xb9\x5e\x07\xc7\x7d\x0e\x1f\xe6"
-  "\xf0\x1f\x4c\xd6\xeb\xa1\xd8\x7f\x55\xa6\x9a\x91\x15\x6c\xdb\x0b"
-  "\xf7\x75\xcb\xf5\xfd\x58\x1b\xbf\xac\x47\x43\x9b\x90\x1f\x94\x29"
-  "\x18\xca\x8b\x76\xbd\x84\x02\x4e\x1a\xce\x21\x1b\xb4\x0d\x87\xdd"
-  "\xc7\xcf\xd5\x21\xc8\x97\x3a\xae\x3f\x83\x38\x9b\xf9\x49\xf3\x6e"
-  "\xdb\x26\x9e\x77\xdb\x36\x61\xdb\x11\xde\x6d\xdb\xf8\x53\xe4\xdd"
-  "\x17\x89\x2c\xef\xe8\xd6\x81\x98\x4f\xb9\xaa\x4a\xeb\x47\x60\xa3"
-  "\x6d\x4b\x30\x47\x30\x67\x4e\xbc\x8f\x39\xf3\x3f\x05\x9d\x95\x33"
-  "\xcd\x8d\x7a\x1d\x1c\xb7\x85\x33\x90\x2f\xcb\x19\x6c\xab\x2f\x12"
-  "\x5b\x90\xc3\x46\x6c\x5b\xcd\x5e\x68\xd0\xa5\xa3\xc7\xa1\xad\x96"
-  "\x04\xad\xbd\x0f\x9d\x64\xed\x94\x5f\xa2\x7b\x8e\xb1\x9f\xa3\xff"
-  "\xe7\x4c\xfa\x29\x14\xdc\xb2\x8e\x61\x2a\xad\xfb\x91\x3d\x54\x6f"
-  "\x61\xdf\xf9\x65\x9f\xcf\x80\x98\xd5\xc0\xe0\x77\xed\xeb\x00\x33"
-  "\x23\x1e\xa3\x5f\x94\x68\xcb\x8b\x36\xdb\x73\x16\xa6\x32\x21\x99"
-  "\x91\x36\x68\xd7\xf6\x9c\x89\x31\xf6\x90\x4d\x19\x8d\x59\xf9\xfd"
-  "\xcc\xa8\xa4\x90\x7d\x2f\x90\x3b\xc4\x02\xbe\x01\xfb\x5f\x76\xbd"
-  "\x9f\x85\x7d\x87\x97\x3f\xd2\xf1\x0e\x19\xfb\x04\xee\x3d\x04\xf7"
-  "\x9e\x22\x1f\x63\xd8\x1d\xbf\xa7\xe0\x7c\xca\x10\xc7\x7b\x0a\xc7"
-  "\x6f\x7c\x1d\xee\x8b\xc4\xe3\xaa\x4e\xf7\x15\x71\xe9\xb8\xfb\x5e"
-  "\xff\x10\xfb\x7a\xfe\x3e\xf2\x1b\xfc\x4a\x51\x2b\x85\x02\x44\x35"
-  "\x4e\x68\xb4\x19\xda\x0f\xc4\x46\x6f\x0e\x81\xbf\xd4\x05\x7a\xfb"
-  "\x78\xf8\x4b\xc3\x5f\x76\x1c\x53\x5e\x7f\x95\x5f\x47\xde\x15\x0d"
-  "\x5d\xc2\x95\xfb\x22\xdb\x26\x7f\x8e\x7a\x5e\xe2\xfe\x6f\xcc\xda"
-  "\x1e\xeb\x78\x17\xde\x96\x9e\xc7\x07\x97\x85\x06\x8c\x54\xe4\xfd"
-  "\x3c\xf9\x8d\xe7\xbe\x70\xf9\xb1\xbf\xed\xe1\x01\x09\xa6\xb4\x73"
-  "\xa8\x9e\xde\x5e\x5c\x09\x7d\xb8\x7d\xdb\xd0\x25\x5b\x6f\x42\x1b"
-  "\x48\x6d\xf3\xc9\x17\xa1\x2d\x06\x98\x56\xb2\x69\x72\x58\x9d\x9b"
-  "\x3b\x28\x81\x79\xbd\x26\x03\xc7\x82\x8d\x8c\xe1\xd7\xdc\xdf\x51"
-  "\xb8\x3d\x91\x71\x93\xed\x36\x06\xb0\xc5\xdf\x43\x6f\x9b\x0f\x84"
-  "\xbf\x53\x9e\xa1\xea\x77\x74\x35\xe9\x2b\x1d\xe5\xc5\xdf\x32\xc7"
-  "\xf3\x6d\x1e\xcc\x40\x19\x8d\x22\xdf\x32\xe7\xe7\xe5\x6c\xaf\xb3"
-  "\xe7\x0d\x4a\x68\xcc\x7a\x33\x1a\x30\x48\x75\xae\xb3\x18\x16\x66"
-  "\xfa\xcd\x49\x52\xd7\xe4\xe1\xf0\xa6\x51\x2a\x9f\x31\x7a\x1b\x23"
-  "\x33\x2f\xe9\xf1\x9f\x70\x95\x25\x7e\xaf\xcd\x64\x6f\x4d\x0c\x3a"
-  "\xbe\xfa\xb2\x4c\x6d\xf3\x96\xe4\xfe\xa7\xb6\xdc\x88\xe0\xd6\x41"
-  "\x2a\x0b\x60\x13\x68\x5b\x90\xf8\x54\xc5\x5e\x2b\xda\x37\xbf\x8e"
-  "\xc2\xfe\xb0\xe8\x52\x31\x15\x1f\xc1\x69\xb8\x5a\x14\x8c\xc7\xbd"
-  "\xb0\x96\xcb\xba\x82\xc2\x5b\xd2\x13\x83\x5a\x5a\x13\xd1\x1f\xae"
-  "\xa0\x91\xf6\x97\xb5\xdd\x33\x5f\x42\xaa\x66\xf0\x85\xcd\xdf\x19"
-  "\x82\xbe\xa8\xae\x43\x9f\xc2\xbd\x15\x0d\x66\xb4\x13\xd2\x32\xdf"
-  "\x25\xf6\x7a\x3a\x89\x69\x2a\x4f\xfa\x08\xc5\xeb\x6d\xa6\xb4\x6f"
-  "\x51\x4f\xf0\x89\xc1\x95\xa9\xef\xb2\xef\x76\xfd\x57\x50\xba\x4a"
-  "\xeb\x79\xb4\xe5\x25\xf0\xa5\xe0\x3b\xd3\x27\x43\x9f\x01\x9c\x78"
-  "\xcb\xb9\xcf\x78\xe5\x4d\xbe\xcf\xf8\x01\xfa\x8c\xd7\xa1\xcf\x48"
-  "\xd7\xa2\x0a\xa3\x09\x81\x0f\xeb\x3a\xc1\x18\xd4\x94\x66\x84\xbe"
-  "\x63\x05\xf4\x1d\xa9\xe7\x11\xdb\x6f\xd4\xd7\x21\xf0\xf9\xbd\x76"
-  "\xcc\x47\xa1\x2d\x3f\x40\xdf\xf1\x03\xf4\x1d\x69\xa4\xef\xd8\x7e"
-  "\x05\xfa\x8e\x05\x10\x1b\xcc\x87\xbe\xa3\x5e\xa4\xef\xb8\x22\x1e"
-  "\x17\x38\xfc\x60\xf3\x0f\x7a\x6a\x3b\xf4\x1b\x2b\xcf\x20\x6a\xfb"
-  "\x73\x5d\x65\x72\xa6\x60\x8f\x24\xce\xdb\x86\x3e\x6b\x67\x12\x11"
-  "\xb6\xfb\xca\x26\xe8\x87\x01\x97\x4a\xbd\x15\x05\x9d\xee\x1a\xd7"
-  "\x0c\xe7\x5b\xd5\x61\xa6\xbd\x5f\x5b\x28\x26\xb7\x8f\xb9\x19\x70"
-  "\x5b\xb9\x14\x51\xad\x80\x61\xd1\x33\xd9\x14\x8e\x13\xed\x79\x6a"
-  "\x15\x89\x49\x77\x1e\xc1\x63\x22\x41\x66\x82\x9b\x95\x49\x0c\x62"
-  "\x66\x27\xf6\xdc\x32\x0b\xa9\x6c\xff\xd5\x76\xb7\xcf\xd6\x06\xa4"
-  "\x9d\x41\xc1\x96\xd9\x06\xb0\xd7\x65\xf4\xe9\x97\xd9\xd4\xae\xa9"
-  "\x48\x87\xf7\x3e\x64\x5e\xfb\x73\xfe\xae\x17\x51\xf4\xae\xff\xa0"
-  "\xa8\x9d\x53\xd1\xe0\x1d\x5f\xe3\x3d\xd2\x01\xc3\x3a\xa6\xe9\xa4"
-  "\xe1\x13\xfc\xbe\x3d\x86\xd9\xa6\x35\x31\x61\x11\xc1\xf0\x7f\x74"
-  "\xf6\x54\x88\x1f\xe0\x7a\xbc\xbe\xd9\x54\x99\x7a\x12\x65\x9e\x43"
-  "\x28\xed\x22\x87\x71\x1b\xbe\x35\xc8\x4a\x81\xff\xc0\x9a\x60\x3c"
-  "\xc1\x17\xbf\x07\xc3\x31\x47\x1b\xc6\x2f\xfd\x5d\xa8\x0b\x38\x8c"
-  "\x4f\xd6\x57\x21\xe8\x03\xbb\xb6\xe9\x03\x16\xe3\x1a\xe4\xd0\x06"
-  "\x80\x4d\x2f\xd0\x02\xa1\xcd\xd7\x5d\xf4\xc1\x22\x85\xfa\x80\x8b"
-  "\x6f\xac\x8b\xf5\x54\x01\xc5\xa0\xf4\x93\x88\xca\xb7\xcb\xc5\x78"
-  "\x27\xbb\xff\x23\x1e\xfb\x22\xf3\x60\x76\x8c\xc6\x58\x98\xe9\x1d"
-  "\x31\x93\xf5\x7e\x48\x19\xf6\xea\x98\x76\xb0\x5f\x4f\xb0\x2f\x3c"
-  "\xa4\x0c\x7b\x75\x0c\x60\x6f\x51\x86\xfd\x0d\x99\xd8\xb3\x7b\x48"
-  "\xfe\x44\xb1\x2f\x5c\x2f\xc4\x7e\xd7\x28\x82\xfd\xae\x91\x3e\x60"
-  "\xdf\x4e\xbb\xd7\x70\xed\xfe\xed\x83\x0a\xb1\x87\x76\x5f\x12\xa7"
-  "\x0c\xfb\xcb\x32\xb1\x67\xf7\xa1\xfc\x89\x62\xff\x76\x86\x10\xfb"
-  "\xdd\x23\x08\xf6\xbb\xa3\x95\x63\xaf\x69\xa7\xdd\x6b\xb8\x76\xbf"
-  "\xe7\x43\x65\xd8\x6b\xa0\xdd\x97\x14\x2a\xc3\xbe\x46\x26\xf6\xec"
-  "\x5e\x96\x3f\x51\xec\xf7\xac\x16\x62\xff\xce\x70\x82\xfd\x3b\x51"
-  "\x3e\x60\xdf\x4e\xbb\xd7\x72\xed\xfe\xbd\xfd\x0a\xb1\xc7\xed\xbe"
-  "\x49\x19\xf6\x47\x64\x62\xcf\xee\x87\xf9\x13\xc5\xfe\xbd\x54\x21"
-  "\xf6\xef\x0e\x23\xd8\xbf\x1b\xa9\x1c\x7b\x6d\x3b\xed\x5e\xcb\xb5"
-  "\xfb\xbd\xfb\x94\x61\xaf\x85\x76\x7f\x30\x41\x19\xf6\x6b\x64\x62"
-  "\xcf\xee\xa9\xf9\x13\xc5\x7e\xef\x12\x21\xf6\x7f\x1c\x42\xb0\xff"
-  "\xe3\x60\x6f\xb0\x5f\xe5\x8c\x7d\x75\xd7\x38\x88\xad\x58\x9d\xbf"
-  "\x6f\x2a\x87\xfd\x7b\x80\x3d\xd4\xbf\xe8\xb9\x7c\x17\x8d\xff\xfe"
-  "\x0e\x16\xf7\x24\xc0\x7d\x05\xe0\x0e\xb1\xa1\x03\x73\xc0\xa8\x27"
-  "\xc6\x1d\x63\x9e\x56\x83\x82\x3f\x85\x7b\x31\x3e\x18\x63\xc0\x51"
-  "\xc7\xe2\xdc\xe5\xcf\xf9\x8c\x9f\x2a\x14\xe3\x89\x75\x3f\xc6\xbc"
-  "\x3d\x6d\x8f\x39\xd1\x2e\xe6\x13\x6f\x8f\xbe\x6f\x71\x1d\xff\xbb"
-  "\x55\x98\x9f\x82\x18\x2e\x4d\x2e\xe6\xef\x1b\x84\x98\xef\x1b\x88"
-  "\x71\x30\xd3\xfb\xc2\x95\x63\xae\x89\x91\xc6\xdc\xd1\xc7\x17\xe5"
-  "\xf8\x86\x79\x49\x21\x8f\xb9\x26\xc6\x33\xe6\x35\x0a\x30\xbf\xb5"
-  "\xfd\x7b\xe7\xc2\xbc\x68\x9a\x10\xf3\x3f\xf5\x21\x98\xff\x49\x2b"
-  "\x85\xb9\x1d\xfc\x35\x1e\x53\xc7\x6b\xfc\x6c\x8d\x89\x4f\xb5\x02"
-  "\xae\x78\xad\x1f\x1e\xeb\xdd\x3f\xbf\x94\x6a\x05\xdc\xb7\x2e\x43"
-  "\xe1\x99\xcb\xd0\xc8\xa0\x3a\xe2\xbf\x5b\xc0\x7f\x6f\xba\x89\x54"
-  "\xf6\x57\xb5\xdd\x33\x2f\x21\x55\x0b\xd8\xb8\xe5\x55\x43\x50\x79"
-  "\x92\x05\x7d\x7a\xa5\x94\xc2\x63\xb7\xf8\xbd\x1d\xf3\x7d\x62\xaf"
-  "\xb1\xc9\x4c\x53\x79\xed\xeb\x64\x5c\xe5\xbc\x63\x5c\x65\xbf\x60"
-  "\x5c\xe5\x0f\x97\xb8\x71\x95\x29\x04\xa3\x02\x67\x7c\x5e\x7c\x5b"
-  "\x62\x5c\xa5\xac\xdd\x71\x15\x76\x3c\xe5\x0a\x0a\x6d\x5d\x60\xe8"
-  "\xbd\x9d\x1b\x57\x79\x73\xbe\x6f\xe3\x2a\x2d\x0b\xf4\xd4\x9b\x80"
-  "\xcf\xaa\x29\x80\xcf\xd7\x72\xf1\xd9\x6f\xf5\x76\x5c\xc5\xd1\xc7"
-  "\x3a\xfa\x55\xdc\xe6\x70\xdf\xda\x94\x1b\x76\xcc\x75\x2c\x05\xb7"
-  "\xb7\x2b\x74\x71\x4f\xec\x93\x95\x8d\xa7\x1c\xdc\x7b\xa7\x8d\xa7"
-  "\xe0\x36\xe7\xe8\x67\x3b\x47\x1f\xfb\xc1\x59\x61\xdb\x3b\x90\x43"
-  "\xfa\xd8\x03\xd9\xde\xea\x2b\x69\xcc\xd5\xb1\xae\x63\x28\x04\xf3"
-  "\x8f\xfc\xf0\x98\x8b\xb2\x71\x94\x83\xd6\x3b\x6d\x1c\xa5\xf3\x61"
-  "\xfe\x61\xb9\x10\xf3\xe2\x0d\x04\xf3\xe2\xf5\xb7\x00\xf3\x63\xae"
-  "\x63\x27\x04\xf3\x3f\xdf\xc0\x63\x2d\xca\xc6\x4f\x3e\x56\xa8\xa5"
-  "\x7f\xbc\xf1\x93\xce\x87\xf9\x9f\x4d\x42\xcc\x3f\x5a\x41\x30\xff"
-  "\x28\xd5\x77\xcc\x35\xb1\xae\x63\x26\x04\xf3\x83\x17\xb1\xf6\x52"
-  "\x36\x6e\xf2\xf1\x9e\x3b\x6d\xdc\xa4\xf3\x61\x7e\xb0\x44\x88\x79"
-  "\xc9\x3c\x82\x79\x49\xca\x2d\xc0\xfc\x98\xeb\x58\x09\xc1\xfc\x2f"
-  "\x35\x78\x6c\x45\xd9\x78\xc9\xc7\x77\xdc\x78\x49\xe7\xc3\xfc\x2f"
-  "\x7b\x85\x98\x7f\x3c\x93\x60\xfe\x71\x92\xef\x98\x6b\x63\x5d\xc7"
-  "\x48\x08\xe6\x87\x4e\xe1\x31\x15\x65\xe3\x24\x7f\x19\x77\xa7\x8d"
-  "\x93\x74\x3e\xcc\x0f\x15\x08\x31\x2f\x9d\x4c\x30\x2f\x9d\xe4\x6d"
-  "\xcc\xec\x88\x95\x1d\xf1\x31\x1b\x2b\x87\x82\x66\x77\x19\x1b\x21"
-  "\x78\xff\xf5\x08\xab\xd9\x15\xc7\xca\x07\xf7\xde\x29\xe3\x23\x0e"
-  "\xac\x71\xbc\xdc\x39\x62\xe5\xbf\xba\xbc\xff\xfc\x64\x0c\x89\x95"
-  "\x3f\x89\x95\xc2\x5a\x6c\x2e\x42\x05\xc4\x9a\x8e\xb9\x08\x9b\x96"
-  "\x01\x8e\xc0\x03\x3c\x17\x01\xcf\x49\x10\x9b\x8f\x80\xe7\x21\x38"
-  "\xe6\x24\x38\xcf\x47\x88\x33\x33\x4d\x78\x4e\x02\x8e\x93\xcb\x93"
-  "\x36\x23\xc7\xdc\x04\x3c\x07\x21\xfd\x5b\xd4\x13\x63\x84\xe7\x1f"
-  "\xe0\x78\xf9\x76\xcf\x41\xc8\xb7\x77\x86\x39\x08\x47\xf4\xed\xc5"
-  "\xca\xe3\xf7\xdd\x87\x80\x6f\x6d\xe3\x54\xad\xdb\xc2\x4c\xb8\xcd"
-  "\x61\x8c\x82\xea\x49\x3b\xdc\xff\x5c\x31\x55\x99\x5a\x8a\x36\xad"
-  "\x44\xc1\x8e\xf1\x0b\xdc\x06\xc1\x2f\x07\x59\x01\xcf\xcc\x57\xc8"
-  "\x38\x86\xfd\xfb\xc4\x9e\x96\x57\x0d\x78\xdd\x7e\xf0\xa7\xff\x2c"
-  "\xa6\xf0\xd8\xe3\xae\x97\x50\xd4\x5b\x17\x50\x74\x45\x43\x0d\x62"
-  "\xdb\x54\x5e\x58\x93\x3d\x2f\xcc\xdc\x9a\x17\x11\x6c\x0f\x0b\xab"
-  "\xb5\x84\x85\xd5\x61\xdc\x32\x2f\x21\x84\xdb\x17\xc6\xad\x32\x75"
-  "\x47\x1b\x5e\x2c\x56\x14\x37\xb6\x21\xd9\xa6\xbe\x54\x8c\x59\xc1"
-  "\x15\xc0\x6c\x81\x10\xb3\x1d\x4a\xc7\x37\x1c\xf3\xb9\x17\xe8\xa9"
-  "\x1d\xd0\xa6\x56\x4e\x04\xcc\x9e\x91\x8b\xd9\xdf\x24\xf7\xff\x93"
-  "\xc6\x4c\x1d\xe3\x25\x66\xeb\xbd\xc0\xcc\xe2\x8e\x99\x3a\x15\xee"
-  "\x4d\x22\x98\xa9\x93\x2d\x61\x6a\x03\x8f\xd9\x0d\x2f\x31\x73\x8d"
-  "\x61\x7f\x4a\x98\x99\x24\xf7\x3f\xf7\x80\x99\x97\xed\x4c\xe3\x45"
-  "\x3b\x2b\x89\x13\xc1\x0c\xda\x99\x9a\x6b\x67\x6a\x68\x67\x6a\xa7"
-  "\x76\x76\xd9\x4b\xcc\x5c\x63\xd0\x9f\x12\x66\x7f\x8f\x95\x8f\x99"
-  "\xc6\xcb\x76\xa6\xf1\xa2\x9d\x95\x14\xba\x63\xa6\x81\x76\xa6\xe1"
-  "\xda\x99\x06\xda\x99\xc6\xa9\x9d\xd5\x78\x89\x99\x6b\x0c\xf9\x53"
-  "\xc2\xec\x33\xe9\xf5\xdf\xd2\x98\x79\xd9\xce\xb4\xde\xb4\xb3\x26"
-  "\x11\xcc\xa0\x9d\x69\xb8\x76\xa6\x81\x76\xa6\x71\x6a\x67\x47\xbc"
-  "\xc4\xcc\x35\x06\xfc\x29\x61\x76\xbc\x48\x3e\x66\x5a\x2f\xdb\x99"
-  "\xd6\x8b\x76\x76\x30\xc1\x1d\x33\x2d\xb4\x33\x2d\xd7\xce\xb4\xd0"
-  "\xce\xb4\x4e\xed\x6c\x8d\x97\x98\xb9\xc6\x70\x3f\x25\xcc\xfe\x91"
-  "\x24\x17\x33\x16\x2f\xd0\x8e\xa2\x98\xb5\x08\x75\xa3\x15\x74\x3c"
-  "\x7e\xe7\x25\x8a\xd7\x6b\x7f\xce\x67\xd6\xaa\x42\x31\x56\x58\x0f"
-  "\x62\xbc\x2a\x53\x8f\x23\x31\xdd\x88\xdf\x8b\x01\xee\x08\xbf\x1b"
-  "\x4b\x3f\x2f\x43\x2f\xce\x92\xc2\xaa\xfd\xf7\x61\x05\xf3\x79\xac"
-  "\x1c\xef\xc3\x6e\x29\x56\x5f\xca\xc5\xea\x44\xa0\x32\xac\x34\x31"
-  "\xed\x63\xa5\x59\xef\x19\xab\x92\x42\x1e\xab\x1a\x27\xac\xdc\xfb"
-  "\x31\xef\xb1\x72\xe9\xbf\x7e\x52\x58\x7d\x5e\x2a\x85\x95\x35\x34"
-  "\x22\x18\xaf\x79\x9f\x00\xb1\x2f\x33\x3b\xf1\xa9\xac\x73\x28\x7c"
-  "\xf3\x39\x34\x12\xaf\x6f\xde\xbf\xb2\x89\x82\x3a\x7e\xf7\xf9\xe9"
-  "\x3a\xd4\xfa\xbd\xb6\x3b\x5e\x3f\xc3\xfa\xc9\x57\xb5\x01\x95\x49"
-  "\x16\xd6\x27\x6e\x01\x8c\x2a\x1a\x4a\xc1\x26\x5d\xe3\x2a\x1a\x3e"
-  "\x42\x2d\x8b\x13\xd1\x17\xd5\x97\x00\x17\xa6\xb5\xb2\xbe\x14\xed"
-  "\x82\xeb\xa6\x65\x1f\x21\xfb\xf7\xfa\xee\x33\x52\x11\x75\x85\xfe"
-  "\x62\x35\x8e\x9d\x87\xa6\xa2\xe0\x71\xf5\x4c\x53\x45\xfd\xe7\xe8"
-  "\xad\x59\x28\xfc\x78\x2a\x42\xd8\xd6\x6c\xac\xfc\x0a\x8e\x95\x8f"
-  "\x08\xf0\x79\xd3\x29\x56\x66\xd7\xcb\x1a\x01\x9b\xab\x2e\xd8\x40"
-  "\x2c\x0e\xb6\xee\x3a\xa1\x01\xb0\x69\x70\x60\x73\x19\xa5\x2d\xc4"
-  "\xd8\x98\xf9\x58\x99\xc3\xa6\x00\xfb\x3c\xa3\x53\xac\x7c\xc5\x09"
-  "\x1b\x6e\xad\xaa\x00\x1b\xc7\x58\xc6\x72\x3d\x7e\x47\xee\x16\x2b"
-  "\x2b\x1b\xcb\x28\x97\x5c\x2b\xc2\xb6\x23\x68\x23\x13\xa0\x1d\xad"
-  "\x5e\xc2\xb6\x23\x62\x7f\x75\x18\xf0\xbd\x18\x05\x99\xbb\xc6\x6d"
-  "\x06\x0c\x5a\xa0\xad\xe1\xbe\x28\x1d\xea\x89\xb1\xc4\xb8\x4d\xd8"
-  "\xdb\xda\xfa\x62\x03\xa2\x40\x83\xab\x30\x76\xb6\xef\xb5\x01\x59"
-  "\xd0\x57\x55\x4e\xfb\x1a\xf0\xb9\x86\x2a\x2d\x1c\x36\x2b\xbf\x46"
-  "\x57\xe8\x93\xc1\xcc\xab\xfa\xee\x0f\x01\x4f\xa1\xef\x09\x9e\x81"
-  "\xd7\xbe\x80\xcf\x7b\xeb\x25\x14\x3d\xce\xc8\x34\xb1\x73\x79\xa0"
-  "\x8d\xe1\xfe\x0c\xfb\xc3\x0a\xe3\xdf\x91\x2d\x2f\xac\xb6\x35\x2c"
-  "\x22\xf8\xf8\x12\x84\xb0\x4f\xc4\x58\xf8\x2f\xe5\xb1\xc3\xeb\xf6"
-  "\x9c\xc7\x3a\xdc\x7c\xe1\x2b\x9f\x8b\xb7\xaf\x69\x66\x59\xe3\x1d"
-  "\x05\x5c\xfb\x2a\x50\x3a\xde\xe1\x18\x8f\x02\x0c\xf1\x5a\xbd\xf4"
-  "\x33\x88\x7a\x53\x36\x86\x78\xc7\x57\xb9\x18\xaa\x63\xda\xc7\xb0"
-  "\xd1\x81\xe1\xfa\xf6\x31\xac\x38\xed\x8e\xa1\x3a\xc9\x09\x43\x0b"
-  "\x8f\xa1\x3a\x95\x60\xa8\x4e\xe6\x31\x54\x1b\xda\xc7\xd0\x25\x96"
-  "\xfe\x49\x61\x58\xe9\x79\xfc\x43\x1c\x43\x2f\xda\xe1\x0f\x1c\x86"
-  "\x1a\x2f\xda\x61\x55\xbe\x08\x86\x4e\xed\xb0\x24\xce\x09\x43\xae"
-  "\x1d\xaa\x9d\xda\xa1\xda\x8b\x76\xe8\x12\x5b\xff\xa4\x30\x3c\x55"
-  "\x28\x1f\x43\x8d\x17\xed\xf0\x1b\x07\x86\x5e\xb4\xc3\x2f\xa7\xb9"
-  "\x63\xa8\x71\x6a\x87\xa0\x5d\xda\x30\xd4\x70\xed\x50\xe3\xd4\x0e"
-  "\x35\x5e\xb4\x43\x17\xad\xf2\x93\xc2\xf0\xff\x92\x15\x60\xe8\x45"
-  "\x3b\xfc\x94\xc3\x50\xeb\x45\x3b\x3c\xad\x13\xc1\xd0\xb9\x1d\x36"
-  "\x39\x61\xc8\xb5\x43\x8d\x53\x3b\xd4\x78\xd1\x0e\x5d\x62\xef\x9f"
-  "\x14\x86\x67\x3c\x8f\xff\x8b\x62\xa8\xf5\xa2\x1d\xa6\x3b\x30\xf4"
-  "\xa2\x1d\x9e\xa9\x75\xc7\x50\xeb\xd4\x0e\x0f\x26\xf0\x18\x6a\xb9"
-  "\x76\xa8\x75\x6a\x87\x5a\x2f\xda\xa1\x4b\x2c\xfe\x93\xc2\xf0\x9f"
-  "\xf5\xde\x60\x08\x3a\xdb\x5d\x97\x36\xf0\x18\x3a\xe3\xe7\xaa\x45"
-  "\xe3\x41\xa3\x62\xec\xa6\x59\x11\xe5\x8e\xdf\xbf\xf6\x60\xfc\x06"
-  "\xe3\xf7\x71\x37\x78\x4d\xca\x62\xc7\xbd\xcf\xc1\x98\x1d\x07\x6f"
-  "\x81\xf5\xa9\x43\x8f\xe2\x77\xaa\x6d\x7a\x74\xce\xff\xaf\x7a\xf4"
-  "\xec\x5e\xf9\xd8\x71\xfd\xa0\x24\x76\xc2\xbe\x2f\x1e\xfa\x44\x69"
-  "\xec\xbe\x4a\x72\xc7\x4e\x93\xc4\x63\x47\xfa\x3d\x82\x5d\x49\xa1"
-  "\xa3\xff\x23\xd8\x71\xfd\x9f\x47\xec\x7e\xca\xfd\xdf\xd7\x92\xfd"
-  "\x9f\x6d\x1d\xa2\x76\xac\xb3\x17\x67\x53\xf6\x52\x38\x4c\x70\x94"
-  "\xc1\x39\x7f\x38\xc7\xee\x63\x06\xbf\xd9\x6b\xf6\xee\xec\x5e\x60"
-  "\xa6\x20\xbf\x24\xfc\xdd\x0e\x9c\xa6\x8b\x23\x4d\xd0\x5a\x14\xb3"
-  "\x8b\xcb\x03\xce\x67\xc0\x79\x53\x2f\xbf\x98\x2e\x90\xbe\x8c\xc9"
-  "\x7a\xd3\x08\xe7\xba\xe2\xb4\xcc\x5a\x15\x1b\xd3\x30\x14\x85\xf3"
-  "\x70\x7d\x66\x00\x97\xa6\x9f\xf3\x73\x7b\xae\x8d\xc1\xfb\x80\x38"
-  "\xd2\x74\xb3\x53\x55\x45\x38\x9d\xdd\x4f\xa5\xb3\xaf\x43\x3a\xe7"
-  "\xb4\xcc\x13\x08\xe7\xeb\x48\xdb\x9d\xcb\x2f\xdc\x39\x8d\xed\x6d"
-  "\x84\x7a\xf9\xe9\xd8\x3c\x7b\x19\x29\x5c\x27\x9c\xb6\x07\xd3\x2b"
-  "\xbf\x8c\x4d\xef\xa7\xd2\x0b\xd2\xbf\x86\xd8\xb4\x5c\xba\x40\xa6"
-  "\x4b\x69\x36\x97\x6e\x30\x4e\x07\xe7\x54\xce\xf6\xe3\xd2\xf5\x74"
-  "\xd8\x06\xef\x3d\xee\x5c\x57\xdb\x3a\x0a\xe7\x87\xd3\xf4\xb2\x77"
-  "\xf9\x4b\x21\x57\x97\x28\xe7\x67\xe2\x74\x70\xdf\x30\xce\xce\x41"
-  "\x50\x87\xe8\xb6\xfc\xb2\x6b\x4a\x1d\xe9\xd2\x6d\xa8\xcf\x2e\xde"
-  "\x36\xc1\x4c\xd6\x5b\x2a\xbc\x87\xa0\x2b\x76\xbd\xfc\xfc\xcc\x18"
-  "\xbb\x4a\xf0\xbe\x38\x2d\xd3\xeb\x4d\x8c\x53\x08\x57\x8f\x18\x52"
-  "\x0f\x76\xbf\x15\x82\x35\x65\xbd\x67\x27\x5b\x56\x3f\x1d\x57\xd6"
-  "\xde\x90\x2e\xd6\x91\xaf\x9d\x62\xc7\x31\xb8\xb4\x2a\x36\x6d\x45"
-  "\x0a\xde\x5f\xbf\x2d\xfd\x3d\x38\xad\x2d\x6b\xef\x69\xdb\x5a\x55"
-  "\x9c\x6b\xfe\xb6\x75\x01\xf8\xba\x73\xfe\xa1\x24\x7d\x41\x3d\xa4"
-  "\x1f\xe7\x9e\x3e\xd8\x35\x7d\x18\x49\xbf\xb3\x0e\xd2\x27\xb8\xa7"
-  "\xb7\xf6\x76\x49\xaf\x26\xe9\x0b\x6b\x21\xfd\x24\xf7\xf4\x3a\xd7"
-  "\xf4\x1a\x92\xfe\xfd\x32\x48\x9f\xe8\x9e\x3e\xc6\x35\xbd\x96\xa4"
-  "\x7f\xdb\x0c\xe9\xa7\xb9\xa7\xcf\x70\x4d\xdf\x87\xa4\xdf\x53\x0d"
-  "\xe9\x93\x5c\xd3\xef\x62\xd3\xa2\x07\xb8\xb4\x7d\x49\xda\xf7\xce"
-  "\x42\xda\x64\x91\xba\xd2\x5c\xde\x91\x5c\xfa\x7b\x49\xfa\xb7\xa6"
-  "\x41\x7a\x83\x7b\x7a\x95\x6b\xfa\x7e\x24\xfd\x21\x2b\xa4\x4f\x11"
-  "\xc1\xca\x35\x7d\x7f\x92\xfe\x40\x2c\xa4\x37\x8a\x60\xe5\x9a\xfe"
-  "\x3e\x92\xbe\x38\x1a\xd2\x2f\x11\xb1\xbd\x6b\xfa\xfb\x49\xfa\x8f"
-  "\x06\x43\xfa\x54\x11\xdb\x0b\xd3\x67\x95\xe8\x20\xdd\xea\x9d\x1c"
-  "\x37\x5d\xec\xee\x9a\xf7\x00\x92\xf7\xc7\xa1\x70\x4f\x86\x7b\x7a"
-  "\xe4\x47\xd2\xa3\x87\xb9\xf4\x0f\x90\xf4\xa5\x01\x90\x7e\xbd\x88"
-  "\xed\x7f\x86\xd3\xef\x22\x69\x7f\x46\xd2\x16\x1d\x86\xb4\x1b\x45"
-  "\xec\xee\x9c\x36\x9c\xa4\xfd\xc7\x5e\x48\x9b\x29\x62\x73\xe7\xb4"
-  "\x03\x49\xda\x23\x46\x48\x9b\x2d\x62\x6f\xe7\xb4\x83\x48\xda\x4f"
-  "\xc3\x21\x6d\xae\x48\x79\x1f\x70\x4a\xfb\x20\x49\x6b\xc2\xbc\xca"
-  "\x17\xc1\xc5\x39\xad\x9e\xa4\x3d\x31\x09\xd2\x16\x88\x60\xe2\x9c"
-  "\x36\x82\xa4\xfd\x7b\x26\xa4\x2d\x14\xc1\xc4\x39\xed\xcf\x99\xac"
-  "\x63\x31\x9c\x9f\xde\xe3\x9a\x76\x27\xef\x77\x7f\x61\xef\x75\xbc"
-  "\x81\xf3\x95\x64\x1e\xe6\x3a\xbc\x97\x5d\x5b\xbd\x1e\x71\xf4\x11"
-  "\x76\x0a\x0d\x66\xb2\xfe\x5a\x07\xf7\xe1\x3c\x8b\xdc\x7d\x9b\xea"
-  "\x91\x9d\x7c\x1f\x31\x84\xc9\xfa\x57\x14\xf7\xfc\x62\xf7\xb4\x01"
-  "\xce\x69\x1f\x62\xb2\xca\x0b\xb8\xb4\x25\xee\x69\x83\x9d\xd3\x0e"
-  "\x65\xb2\x2a\x92\xb8\xb4\xa5\x22\xfe\xf5\x61\xa7\xb4\x91\x4c\x56"
-  "\x55\x38\xa4\x3b\x2c\xe6\x5f\x99\x75\xba\x87\xb1\x3f\x70\xf8\x6e"
-  "\x48\x3f\x8c\xd8\xf7\xac\x05\xec\xcb\xce\x3d\x77\xa4\x05\x1c\x1e"
-  "\x76\xea\x2b\x1f\xb6\xf7\x3a\x55\xc7\xd9\xec\x98\x7b\x19\x32\x9c"
-  "\xcb\xf0\x08\xc9\xf3\xff\x8a\x20\xcf\x32\xd7\x32\x70\xfe\x08\xeb"
-  "\x04\x6c\xdf\x28\x5b\xd6\x19\x23\xb6\x2f\xa4\x2d\x17\x68\x04\xca"
-  "\x8f\xc6\x79\x72\xd8\x0e\x67\xb2\xbe\x40\x9c\x0d\x04\xfd\x11\xb4"
-  "\x47\xd6\x1f\x02\xbe\x65\xcc\x6b\x01\xa7\x21\xed\xa3\x5c\xba\xd3"
-  "\xae\xfd\x20\x57\xbe\xc7\xe0\xda\xd9\xb6\x3e\xd0\x4f\x55\x2d\xa6"
-  "\x65\x8c\x3f\x47\x3d\x2e\xd1\xff\x25\xf3\xf1\xdb\xbe\x9d\x75\x9e"
-  "\xd5\x13\xf6\x3d\xfe\xd9\xf1\x0d\x8c\xd5\xf9\xdc\x56\x8a\xa9\x1a"
-  "\xda\x80\x54\x78\x0f\x3e\x26\x6c\x68\x9c\x19\xce\x5b\x06\x76\x49"
-  "\x6a\xcc\xfa\x6f\xb9\xd9\xef\xa3\x2a\xbc\x27\x13\xfc\x7f\xd6\x8c"
-  "\x92\x0b\xf0\xff\x5b\xd7\x31\x4d\xf8\x1b\x08\xb6\xd7\x6b\x32\x2a"
-  "\xed\xf5\x78\x2f\xc5\x26\xc8\xa3\xe9\x82\x11\xd1\xf8\xbb\x71\x78"
-  "\x5f\xd7\xca\xd4\x7a\x74\x81\xae\xed\xcf\x2c\x30\x8c\x84\x32\xe0"
-  "\xbd\xb7\x92\xcf\xc1\x6f\x62\x53\xd0\xbe\xd9\x35\x05\xa6\x45\x78"
-  "\x7f\xba\xda\x39\x96\xb0\x68\x13\xf3\xbb\x17\xea\x8c\x69\xe8\xfe"
-  "\x4b\x74\x6d\xb2\x63\x2f\x2a\x76\xff\xa9\x1f\x0c\xbf\x26\x7b\x4f"
-  "\xd5\x5e\xb6\x87\xd4\x14\xb8\xed\x3d\x55\x18\x9b\x44\xf6\xb3\x3a"
-  "\xcf\xe6\x0d\x65\xab\x62\xc2\xfd\x53\xed\x2d\xeb\x33\xf0\x37\xde"
-  "\x4c\x69\x97\xd0\x39\xee\x1a\xce\x93\xcb\xeb\x08\xce\x03\xe7\xe5"
-  "\xc8\x07\xdf\x67\x19\x10\x9b\x84\xeb\x0e\x76\x48\xf5\x7e\xff\xaa"
-  "\xda\x22\xbc\x7f\x95\x8c\xf4\xc9\x38\xbd\xf8\xbe\xbc\xa0\x71\x72"
-  "\x6a\x4a\x1b\xb3\xce\xc7\x82\x56\xdd\x43\xec\x7e\x3e\xc1\x8c\x1a"
-  "\xc6\x71\xff\x83\xea\xbe\xd9\xc4\xfd\x6f\x30\xfb\xbd\x97\xc4\xfd"
-  "\xbf\xc4\xb1\x5f\x98\x68\xbe\xc1\x35\x99\x60\xef\x3d\xf6\xb7\x12"
-  "\x03\xb0\xb6\x26\xfb\x96\xd6\x64\xea\xee\xc3\xfb\x39\x9f\x6f\x82"
-  "\x67\xee\x21\x76\x39\x7f\x0a\xfe\x06\x71\x7f\x2d\xdc\x5f\x06\xa7"
-  "\x61\xb9\x14\x1a\x99\xca\x64\xf7\x35\x92\xef\xc2\x9c\x67\xf7\x2a"
-  "\x63\xb1\x03\x7c\x99\x90\xbe\x46\x36\xdf\xbc\x68\x93\x73\x19\xf0"
-  "\xa6\x60\x91\xc3\x1e\x7e\x24\x6a\xf8\xa3\x8f\x45\x8f\x98\x39\x6b"
-  "\x76\xf2\x9c\x97\x5e\x36\xcc\x7d\xe5\xd5\x94\x79\xf3\x17\x18\x17"
-  "\x2e\x5a\xbc\x64\xe9\xb2\xe5\xa9\x2b\x56\xe2\x74\x6d\xe5\x7d\x2b"
-  "\xd6\xaf\x81\x42\x80\xdd\x13\xf0\x9c\x0b\xd3\xd9\x67\xc3\x39\x82"
-  "\xf3\x85\x71\x2a\x9d\xb8\x86\xaf\x04\x55\x8d\xbf\xef\x51\x4f\x5f"
-  "\xd8\x87\xbf\x35\x02\x3c\xf3\xab\x2c\x78\xca\x84\xbf\x53\x56\x4b"
-  "\x5f\x28\xa8\xb0\x3c\x65\xc2\xdf\xd5\xfb\x4c\x5b\x87\xc2\x1f\xc0"
-  "\xdf\x32\xbb\xb0\x11\x5f\xdf\x35\x08\xa1\x63\x70\xaf\x58\x9e\x0f"
-  "\x04\x23\xed\x1b\x6a\xc6\x92\xab\x66\xea\x71\xfe\xb9\xdb\x98\x3a"
-  "\xcb\x2a\x03\xca\x82\xdf\xc0\xf5\xe0\x0b\xf4\x77\xd3\x3f\xeb\xc7"
-  "\x7e\x9f\xa8\xdf\xce\x6d\x4c\xed\x7a\x35\x53\xfb\xbb\x6d\x4c\xfd"
-  "\x2e\x35\x63\x0e\xcf\x45\x81\x8d\x59\xdf\x05\x9b\xe9\x0b\x06\xb6"
-  "\xdd\xc0\x75\x7b\xaf\x0b\x01\x5b\xe1\xda\x50\x2b\xa2\x77\xc1\x6f"
-  "\x38\xd7\xf0\x99\x8e\x94\xfb\x83\x6b\x4d\xfe\x50\xbf\x06\xa6\x35"
-  "\xc5\x2f\x0b\x9e\x43\x30\xf9\x6e\xed\x31\xe8\xfd\xe1\x79\x96\xca"
-  "\xa6\x73\xc8\x4c\x7f\x97\xb1\xeb\x26\xfb\xbc\xa0\xca\xfc\x7a\x84"
-  "\xf3\x3b\xb0\xa8\xc9\x7f\x71\x5f\xc6\x0a\x69\x93\xec\xab\x52\xfc"
-  "\x20\xcd\x48\xc8\xbb\xc1\xb9\x3e\xfa\x97\xe6\x2d\xd1\xcd\x5f\x9a"
-  "\x92\x12\xd1\x1d\xe9\xd9\xbf\xc8\xf9\x1b\x7b\x4b\x20\x3f\xf4\xc6"
-  "\x36\xe6\x18\xd4\xd3\x04\xf5\x2d\x3b\x09\xd1\x02\xf0\x03\x41\x9d"
-  "\xb2\x21\xdf\x33\x70\xfe\x30\xfc\x7f\x18\xca\x5e\x46\xbe\xdf\xd5"
-  "\xec\xc7\x64\x7d\x97\x09\xe5\x2c\xc3\xdf\x28\xc0\xfb\x29\x5e\x5f"
-  "\x3e\xc9\x0f\xea\x9d\x0b\xe9\xca\x74\x7d\xd1\xc0\x0b\x74\xdd\x74"
-  "\x28\xc7\x1e\xf8\x1f\xa7\x67\xbf\x09\x0a\xe9\x8f\x91\x7a\x35\x5d"
-  "\xc5\xbf\xc1\x56\xa6\x1d\x6a\x26\xb3\x31\xab\x2e\x1a\xef\xb7\xca"
-  "\x7e\x2f\x06\x7e\x83\x5d\xca\x20\x6d\xf6\xf5\xf4\x49\x7e\xf8\x7b"
-  "\x94\xbb\xf8\x3c\x03\x70\x99\x70\x39\x70\xec\xfa\x05\x78\x0b\x7b"
-  "\x6b\x22\x1a\xd2\x84\xfc\xbe\xa8\x45\xa8\x60\x1b\x53\x08\x47\x01"
-  "\x1c\xf9\x9f\xc3\xb5\x13\x70\x94\xc1\xf9\x72\xf8\xfb\x39\xfc\x3d"
-  "\x51\xcb\xbe\x0b\xd5\xe2\x72\x2f\x5e\xcd\xd4\x0d\xcd\x47\x3f\x63"
-  "\xbf\x77\x99\x86\x9e\x3f\x47\x37\x25\xe2\xb2\xe3\xbd\x95\x99\x5e"
-  "\x75\xe5\xc2\x3d\x60\x2f\xc5\x20\xb8\x0e\x7f\x27\x91\xbf\xce\xc7"
-  "\xa5\x02\x38\x0e\x93\xff\xbf\x57\xc1\xff\x83\xb9\xff\xb5\x70\x84"
-  "\xb7\x7f\xb8\xe6\x27\x75\x7c\x9f\xed\x7d\x5a\xaf\x8e\x72\xef\xd2"
-  "\x5d\x8e\x43\xf4\x0f\x85\x70\x9c\x15\x9e\xff\xa1\x98\x9c\x6b\x58"
-  "\x4d\x7e\x37\x6c\xe4\xfe\x96\x20\xfa\x06\xd8\xe9\x06\xe4\x7f\xc3"
-  "\x42\xce\xdd\x00\xc6\x37\xc5\xc2\x91\xe0\xf2\x7c\x9c\x67\x2d\xc6"
-  "\xb3\x15\xfc\x3d\xc6\xd2\x4c\xd7\x15\x60\x8c\xb6\x12\x6e\xf9\xe1"
-  "\xf9\x0e\x70\x2e\x1f\xb8\x55\xc0\xf3\xe7\xd2\x16\x21\x7f\x2e\xa5"
-  "\xba\xf0\x27\x1b\xfb\x23\x68\x0b\xb5\xbb\x08\x5f\x0e\x5f\x5f\x95"
-  "\x0c\xbf\x2f\xad\x86\x7c\x0e\xeb\x5e\x64\xf3\xb0\xb0\x7d\xc6\x25"
-  "\x84\x7a\x1a\x10\xbb\xfe\xa0\x9e\xbe\x74\x12\x73\x16\x3f\x9b\x7b"
-  "\x2e\x29\x0b\x94\x0f\xce\x15\xe2\xf2\x2d\x80\x7c\xe1\xf7\x1e\x48"
-  "\x57\x58\x89\xae\x39\xca\xc6\xde\xb3\xf9\x15\xe0\x23\x57\x5e\x9c"
-  "\x27\xbe\x8f\xe1\xeb\x95\x8f\xef\x21\xcf\xfe\x7e\x2d\x9c\x8f\x04"
-  "\x1f\x85\xd2\xaf\x22\xba\xd2\x6a\x46\x98\x93\xf8\x6f\xa5\x35\x12"
-  "\xda\x52\x1c\xb2\xe3\xbe\x4e\x8b\x22\xa1\xbd\x75\x3b\x47\x7f\x9f"
-  "\xfc\xd0\x6a\x14\x89\xf3\xc3\x3e\xdc\x4c\x7f\xaf\xdf\x85\xdb\x22"
-  "\xc9\x6b\x05\x62\xf7\x5e\xac\xcb\xff\xdc\x88\xd8\xe7\xec\xc4\xe5"
-  "\x81\xeb\x4e\xcf\xcd\xad\x84\x28\x68\xeb\x4a\x52\x57\x78\xd6\x1e"
-  "\xb8\xbf\x18\xd7\x1d\xdb\x13\xae\x97\x42\x3e\x26\x7c\x0d\x7f\x5f"
-  "\x85\xab\xcf\x1e\xbc\x36\x03\xdb\x03\xa7\xc7\xdf\x7d\x24\x7b\xca"
-  "\x7e\x77\x9e\xb5\x1b\xdc\x8f\xf1\x60\xe0\x19\x38\x8f\x74\x2b\x63"
-  "\x65\xc0\x1f\xbd\xb3\x12\x7f\x47\xe0\xf2\x08\x21\x3e\xf5\x5a\x67"
-  "\x7c\xe0\xbe\x62\xb8\xff\x18\xee\x83\xb1\x3f\x81\x67\x06\xe1\xef"
-  "\xa1\xc1\xb9\x6c\x7b\x16\xe4\xb1\xac\x89\x1d\x07\x82\x7c\x22\xa0"
-  "\x2c\xd9\x38\x1f\x28\xcf\x31\x2e\xaf\x64\xbc\xdf\xa4\x33\xd6\x5c"
-  "\x7e\x7b\x30\xe6\x6c\x7b\x5e\xc9\xd6\x09\x7c\x57\x7d\xf3\x4e\x72"
-  "\xad\x14\xd2\x94\x32\xad\x71\x88\x59\x95\xc8\x7d\x77\x8d\xbd\x56"
-  "\x92\xde\xcc\xe2\x7b\x8c\xf8\xb5\xcb\x7d\x16\xaf\x61\xea\x9c\xca"
-  "\x5d\xe5\xd8\x57\x9d\x2b\x77\x09\x7e\x1e\xb3\x7c\x1a\xdb\x8f\xe2"
-  "\x67\xe0\xfb\xb9\xfc\x8a\x70\x7e\x0e\x5b\x3d\x04\xe5\x20\xf6\xfa"
-  "\xde\x0c\xe7\xf7\x60\x2e\xb2\x76\x03\x3f\x7a\x3d\x1d\x73\xb1\xfe"
-  "\x34\xdc\x7f\x38\x0b\xff\x5e\xce\xfe\x36\xb0\x3e\x96\xbf\xde\x0f"
-  "\x5f\xaf\xac\x03\xdc\x5e\x05\x2e\xd9\x11\xfa\x59\x28\x8a\x6c\x58"
-  "\xc7\xd6\xad\xa8\x61\x55\xac\xdf\x67\x56\x84\x70\x39\xc1\x46\xa0"
-  "\x1b\x2e\xaf\x86\xbe\xe6\x30\x2e\x2b\xf8\xeb\x12\xe6\x9d\x44\x84"
-  "\xcb\x0c\xfe\x8c\x2b\xdf\xe5\xcb\x1c\xf6\x25\xb8\x8e\xd8\x9e\x0f"
-  "\x11\xdf\x07\xd7\x7e\xc8\xc1\x65\xe7\xeb\x7d\xb9\xcc\xd9\xc6\x6c"
-  "\xbd\x01\x07\x8c\x17\xc6\xc5\x29\x4f\xcc\xfd\x6c\xc8\xab\x88\xfc"
-  "\x26\xdc\xc0\xb6\xce\x56\x33\xe5\x38\x3d\x9f\xf6\x07\xf6\xdb\x88"
-  "\x69\xf0\xec\xa1\x46\x1c\xbb\x40\xff\x6c\x6d\x34\x41\xbe\x45\xf8"
-  "\x9b\x9e\x90\x47\x29\xb6\x29\xa4\x9b\x8c\xf9\x08\xbf\xcb\xc9\x7d"
-  "\x57\x26\x41\x7f\x3e\x18\x8e\x91\x7c\xfb\xff\x61\x8c\x90\x5f\x57"
-  "\x5c\xdb\x3f\xc6\x3b\xdb\x9e\x1e\x87\xb8\xef\x19\xeb\xae\xd0\x57"
-  "\xbe\xe5\xfa\x0e\x0e\xeb\x1f\x86\x7f\x06\xed\xc5\x29\x8f\xc3\x2e"
-  "\x58\x97\xb2\x7c\x5c\x3e\xce\x0f\xd7\x19\xee\x2d\xe5\xf2\x61\xeb"
-  "\xcc\xf2\x69\x1d\xcb\x81\x72\x66\x39\xd4\xb3\x8d\x07\x57\xb4\x1c"
-  "\xce\xe5\x2e\x36\x71\xf8\xae\x64\xfc\x9d\x2e\xec\x93\x40\xe3\xfe"
-  "\xba\xb1\x95\xf7\x4b\x18\x7b\x3b\x8b\xfd\x15\xd3\x2e\xd2\xdf\x72"
-  "\x7e\xeb\x0a\xb9\xae\x16\x70\x18\x97\xe5\x06\xcb\x5f\x5c\x96\xf4"
-  "\x69\xb8\x2c\xa5\x6c\x39\xd2\x75\xe8\x0a\xfd\x43\x0a\x7e\x3e\xdc"
-  "\xdb\xc4\xb5\x57\x2e\xaf\xcb\xe5\x38\xaf\xdf\x81\xaf\xc2\x65\x82"
-  "\x67\x27\xb2\xfe\xef\x37\xac\x4d\x4e\x72\x65\x2f\x6b\x5a\x87\xef"
-  "\xbd\x64\x6a\xa6\xd8\x7b\xcb\xe0\xff\xa8\x26\xf2\x9d\x83\xee\x70"
-  "\xff\x5e\xdd\x2c\x9c\xbe\x61\x30\xf6\xd1\xba\xa9\xec\xff\x61\xba"
-  "\xe7\x80\xab\x97\x90\x0a\xf2\x0b\xc0\x1c\x75\xf0\xa2\x9e\x6e\xf0"
-  "\xc7\x31\x03\xd8\xba\x08\x34\xd2\x5e\x6c\x6f\xcc\x65\xd0\x48\x51"
-  "\x8d\x59\x96\x28\x07\x6f\xe1\x39\x05\xd8\xf6\x04\x1f\xcb\x0a\xe0"
-  "\x71\x29\xcf\x2d\xcb\x0a\xce\x8e\x7b\xc1\x8e\x01\x17\xe8\xeb\xcd"
-  "\x5c\xbd\xf6\x42\x7a\xd0\x62\xd7\x2f\x72\x65\xcf\xe7\xd2\xe7\x39"
-  "\x70\xe0\xda\x6a\x79\x16\xf6\xbf\x2c\x06\x57\x07\x73\xf7\xee\x21"
-  "\xcf\xba\x3a\xc4\x91\x16\x6b\x44\xf2\xcd\xb2\xab\x43\xb0\x1f\x1c"
-  "\x0a\xd8\xb3\xbe\x8f\xfd\xde\x2d\x39\x87\xdb\x0e\x79\xc6\xf5\x33"
-  "\x2c\x0f\x41\xf7\xf0\x3c\xba\xaa\x72\xf1\x4f\xd8\x17\x67\x57\xac"
-  "\x27\xdf\x84\xc0\x5c\xc2\x3e\x15\xc7\x26\x50\xc6\x6a\xae\xfd\x70"
-  "\x65\xbe\xba\x50\xc8\x95\xeb\x47\x81\x2b\x43\x9c\xf2\x4e\x12\xeb"
-  "\xe7\x76\x11\x1f\x58\xc0\xd5\xed\x43\xae\x6e\x45\x5c\xdd\x3e\xe4"
-  "\xea\x86\xf7\x08\xc6\x76\x5b\xea\x64\x47\xb0\xdb\xb5\x6f\xb9\xf4"
-  "\xa5\xd8\x97\xf3\xed\xf5\x5a\x7f\x47\x5b\x76\xf7\x17\xd7\x4e\xe1"
-  "\xf6\xe0\x54\xae\x26\x17\x7f\x51\x2a\xee\x2f\xae\x96\x71\xf5\x2d"
-  "\x74\x69\x1b\x5c\x0c\xc2\xf5\x2d\x80\x43\x45\x83\xe3\xdb\x1c\xdf"
-  "\x9d\xc7\xfe\x13\x3f\xdb\xb9\x0f\xda\x49\xec\xca\xb5\xe5\x6b\x47"
-  "\xdc\x71\xb8\x96\xe9\xdc\x9e\x31\xd6\xd8\x27\xe0\x3c\x30\xa6\xac"
-  "\xae\x84\x73\x04\xd7\x6b\xc9\xd8\x37\x38\xfb\x68\x48\x9b\x6b\x67"
-  "\x70\x7b\xb9\x96\x2d\x6c\x8b\x57\xad\x5c\x5b\xe4\x9e\x7d\x7d\x26"
-  "\x60\x14\xc9\x3f\xf7\xba\xca\xe5\xb9\x18\x9b\x63\xec\xde\xcb\x04"
-  "\xd3\xf1\x8e\x3e\x0d\xa7\x87\x7b\x53\xe1\x9e\x68\x97\xfe\x31\x1b"
-  "\x97\x0f\x9e\x55\xcc\xfa\xac\x6d\xac\xaf\x48\x6d\x64\xcb\x73\x7d"
-  "\xe4\x2e\xae\x9f\x80\x73\x91\xdc\xb9\x00\xae\x2f\x71\xf0\x66\xbf"
-  "\x4b\x99\xf2\xc5\xf5\xd1\xd5\x62\x87\x3e\x62\xf3\x62\x7d\xd1\xf5"
-  "\x02\xae\x7e\xf8\xdc\x10\x72\xee\x6a\x32\x3e\x97\x45\xec\x90\xcb"
-  "\xb0\xfd\xd5\xd5\x00\xae\xbf\xc2\xed\x8b\x32\xd3\x96\x54\xdc\xc6"
-  "\xf0\x6f\xc8\xc3\x82\xf3\xaf\xcc\x68\xc1\x31\x44\x3e\x5c\x0b\xc5"
-  "\xfe\x00\xfb\x0b\xdd\x4b\xc4\x6f\xe8\x26\xb0\x7f\x47\x61\xbf\x83"
-  "\x75\x08\xbe\x0e\xe9\xb0\xef\x00\xfd\xd0\x30\x51\xf7\x5b\xd0\x05"
-  "\xdf\x07\x40\xbe\x0d\x51\xdc\xbd\x73\x58\xad\xf0\x7d\x1c\xed\x38"
-  "\xe7\xb8\x0f\xda\x51\x18\xbe\x0f\xdf\xef\xf0\x5f\xd8\x77\x59\xb1"
-  "\x6f\x22\xcf\xdb\xc7\x71\x9c\x8d\x1b\x1c\xba\xa8\x95\x72\x4a\x8b"
-  "\xbf\x57\x40\x7c\x5a\x03\xe7\xcf\xce\xe3\x7b\xff\x1f\x7b\x6f\x03"
-  "\xde\x64\x95\x2d\x0a\xaf\xfc\x14\x0a\x16\x92\xd6\xaa\x19\x68\x21"
-  "\x40\x71\xaa\x96\x52\xa0\x68\x65\x40\xab\x80\x96\x19\xa0\x15\x50"
-  "\x8b\xa0\x2d\xd2\x6a\x2b\xb5\x84\xb6\x40\xc0\xd2\x84\x80\x73\x70"
-  "\xc4\x36\xad\x15\xab\x96\xb6\x8e\x38\x83\x33\x3a\xd6\x73\x38\xe7"
-  "\xf0\x9d\x87\x19\xe3\xd0\xb9\xa7\x33\xd3\x36\xcc\xb9\xcc\xbd\x3d"
-  "\xf3\xe1\x9d\xc8\xd7\xc1\xc8\x2d\x10\x69\x68\x42\x9b\x64\x7f\x6b"
-  "\xed\xfd\xbe\xcd\x4f\x13\xd4\x7b\xbc\xe7\x3e\xcf\xf7\x59\x7d\xc9"
-  "\xfb\xee\x9f\xb5\xd7\x5a\x7b\xed\xb5\xd7\xfe\x5b\x9b\xd7\x1f\xea"
-  "\xca\xba\xeb\xec\xb3\xf6\x2a\x50\xb7\x5d\x25\xbd\xf8\xf9\x80\xc0"
-  "\xf3\x5a\xae\xa0\xe3\xda\x24\x4e\x87\xd0\xa9\x56\x81\xcb\xe7\x03"
-  "\x6d\x23\x3c\x6e\x2e\xd1\x42\x71\x0d\x21\x71\x74\x67\x08\xc6\x3d"
-  "\xc0\xf1\x8a\xc8\x17\x18\x2d\x1b\x97\xbe\x5d\xdc\x83\x4b\x3c\x97"
-  "\x74\xef\x35\x9b\xc0\xf3\xda\x3e\x59\xef\x22\x5f\x12\x48\xf7\xf2"
-  "\xb8\x67\xa4\x34\x6b\xa5\x5f\xae\xdf\xaf\x7d\x20\xf8\xaa\x53\x4a"
-  "\xfc\x4e\x96\xe8\xf8\x84\x8f\xb3\xff\x67\x21\xf2\xf6\xda\x31\x99"
-  "\xb7\xa1\xef\xd4\x7e\xb0\x7c\x2d\x7d\x73\xb9\xaf\xe5\x63\xd8\x56"
-  "\x4a\x43\x38\x89\x3e\xc2\xdd\x1a\x69\x53\xe3\x58\xef\x5e\xea\x97"
-  "\x84\xad\xea\xfd\x9e\x34\x07\x04\xb6\xaa\x9f\x62\xbf\x30\x5c\x22"
-  "\xeb\x18\xe6\xc9\x03\xf2\x59\x7e\x41\x35\x5c\x4a\x61\xe4\xe3\x3e"
-  "\x34\x0d\xe9\xa7\x0f\x47\x1c\x12\xcc\xe1\x5c\x59\x6f\x90\x2e\xe9"
-  "\x73\x9f\x97\x6c\xba\x61\x57\x9b\xa4\x4b\x2e\xab\x86\xbf\x0c\xb7"
-  "\xc3\x86\xbf\x0c\xd7\x19\xde\xb8\x48\x9d\x81\x76\xf3\x41\x4f\xfd"
-  "\x70\x57\x98\x1d\x80\x61\x37\xd6\x1d\xc3\x2d\xd4\x46\xe9\xce\x22"
-  "\xae\x9f\xf8\xbc\x96\x67\xa3\x8c\x33\xe9\xcd\xa1\x17\xe4\xf9\x0b"
-  "\xcf\x35\xb2\xd5\xc2\xcb\xf3\x64\x87\xe9\x4e\x2a\x4f\x86\x87\xd2"
-  "\x4c\xed\xc8\x56\x45\x73\x2e\x1e\xb5\xa4\xe7\x3b\xc2\x74\xa5\xd4"
-  "\x87\x91\x9e\x0c\xef\xab\x3e\xff\x5b\x78\x5f\xe5\xf9\x6c\xbc\x8e"
-  "\xf4\x74\x7e\xfd\xbe\xca\x73\x88\xf4\x96\xac\x23\xc3\x75\x81\xe7"
-  "\x44\x5b\x98\x2d\xeb\x59\x2a\xdb\xb2\x41\x3d\x3a\xdc\x43\x3a\x0a"
-  "\xcb\x3f\x29\xca\xf6\x66\x60\xbf\x9f\x25\x97\x8d\xf1\x25\x7d\x7a"
-  "\x94\xcd\xfa\xcf\x51\x5f\x0c\x6b\x25\x1b\x90\xb7\xcd\x11\x7e\xf7"
-  "\xc7\xb5\x42\x94\xbf\xc9\x24\x67\xb6\xca\xab\x30\x10\xec\x2b\xba"
-  "\x86\xb6\xcb\xfc\xf5\xfe\x3a\xd4\x2e\x3c\x7a\x84\x1d\xc2\x72\x9a"
-  "\x43\x69\x7c\x05\xc3\x1a\xa4\x39\x04\xce\x5b\x0e\xcb\x5b\xd6\x7e"
-  "\x24\x9c\x36\x41\x87\xb7\x95\xe8\xa0\x31\x11\x96\xbf\x99\xec\x1e"
-  "\xba\xb7\xcc\xa1\xba\xe2\x68\x1f\x93\xf9\x8b\xd9\xd7\x2d\xa1\xf6"
-  "\x95\x73\x29\xe9\x4a\x69\xec\xd9\x8d\xf6\x8e\x35\x74\x2e\x66\xcd"
-  "\xf2\x02\xbd\xa1\xaa\xbc\xb2\xe6\x99\x85\xfa\xf2\xca\xf2\x9a\xf2"
-  "\x2d\x15\xe5\x7b\xb7\xd4\x94\x6f\xaf\xcc\x78\x7e\xcb\xb3\xe5\x5b"
-  "\xf5\xbb\xb7\x54\xeb\xb3\x8c\x73\x8d\x93\x21\x98\x74\x89\x7e\x4b"
-  "\x75\xf5\xce\xe7\x4b\x4b\xf4\x95\xe5\x5b\xe7\x55\x95\x56\x97\xd6"
-  "\xe8\xb7\x54\x6d\xdf\x59\x59\xa2\x9f\x5b\x92\x39\x37\xeb\xee\x92"
-  "\xc9\xa1\x73\x68\xb3\xb5\x30\x18\x18\xfe\xc2\xd9\x30\x0c\xf1\x1a"
-  "\x85\xa1\x4a\x63\x2c\xaf\x14\xf3\x76\x23\x71\xf3\x9b\xc1\x40\xf7"
-  "\x8f\xd3\x7d\xb5\xac\xfe\xba\x0e\x7f\xd5\x94\x0e\xe9\xd4\xb7\xd3"
-  "\x1d\xe4\xb7\xb2\x14\x4f\xfd\x75\xa4\xcb\xdf\xc9\xef\x90\xc5\x70"
-  "\xa4\x2d\x85\x0d\xff\xde\x89\x36\x9b\x81\xf6\x67\xb7\x0f\x43\xb2"
-  "\x75\x17\xa8\xf1\x49\xc0\x47\x4b\xf7\x93\x63\x1e\x9f\x43\x35\xaa"
-  "\x13\x3e\xfc\x47\x5a\x5d\x89\xba\x42\x66\xd5\x49\x77\x91\x8f\xbc"
-  "\x21\xcf\x35\xe7\xbf\x08\xf9\x24\x9f\xe7\x55\x23\x7c\xbd\xe5\x00"
-  "\xca\x32\xcd\xbf\x0e\xfd\xe6\xc1\x5c\xb4\x07\xcf\xd9\xa6\xf1\xb8"
-  "\x37\xdc\x4a\x48\x40\xbc\xd4\xa7\x6b\xb3\xe0\x55\x2c\xab\x5a\xc7"
-  "\x98\xa7\x7e\xa4\x58\x9e\x4f\xa3\x7b\xe1\x91\x96\x7e\x89\x8e\xe5"
-  "\x9c\x8e\x23\x2c\xad\x39\x09\xf1\x6b\x22\x7c\x46\x0e\xcb\x34\x20"
-  "\xde\xfd\x0e\xd5\x75\x17\xdd\x0b\x4f\x78\x45\x9b\xeb\xa3\xf9\x2e"
-  "\xc4\xf3\xcf\x81\x5d\xc8\xb7\x19\xe2\xde\xa3\x86\x36\xd1\xfe\x90"
-  "\xae\x84\x76\x7c\xaf\xbf\x0a\x09\xaf\xd0\x3d\xdc\x96\x99\xac\xd7"
-  "\xed\x03\x7b\x59\x3f\x68\xf6\x30\x17\xfb\xa7\x2f\x9c\x82\xa6\x51"
-  "\x3e\xde\xf8\x87\xe7\xfa\xd5\x44\x13\xf6\x15\x09\x74\xa7\x73\x8c"
-  "\xb9\x45\xf5\xab\xb7\x32\x37\x7b\x2b\xd4\xe6\x1a\x2d\x27\x9e\x90"
-  "\xbd\x35\x64\xa1\x7b\xbd\x46\x0b\x90\x97\xc7\x25\xdb\xd8\xcd\x46"
-  "\x37\x87\xd8\x52\xa3\x24\x67\xee\x18\xb0\xe3\x65\xd8\x74\xbf\x37"
-  "\xe5\x11\xf5\x3f\xfa\x67\xcc\xe3\x0a\x81\xdf\x19\x09\x9f\x60\xe2"
-  "\xbb\x4b\x2e\x47\x8c\xc3\x47\xc9\x26\x70\xa1\x2c\xbb\x62\x94\x97"
-  "\xd6\x74\x84\x9d\xb5\x63\x78\xc3\x75\x50\x63\x5a\x1c\xdb\x12\x7c"
-  "\x1f\xb6\x95\xeb\x35\x04\xff\xc0\xad\x00\x07\x31\xcd\x50\xfd\xc8"
-  "\x71\x37\xbf\x23\xda\x87\xed\xff\xf3\x8e\xc8\x79\x6b\x49\x9e\x97"
-  "\x44\xc8\x73\x6e\x13\xd9\x84\xcd\x08\x1f\x65\xa8\xe1\x1a\xf6\xc3"
-  "\xf8\x9d\xd9\x0c\xe9\x54\x0e\xbe\x9f\xa1\xf9\x10\x84\x69\x96\xcb"
-  "\x63\x28\xff\xf5\x01\x31\x07\x23\xc9\x56\x86\xdd\xe8\xa4\xf5\x09"
-  "\x76\x1a\xf5\x3b\xe1\x48\x32\x86\x79\x4e\xc8\x32\x85\xb2\x7e\x96"
-  "\xcb\x55\x32\xa4\xb3\x7a\x5f\x4e\x7b\x12\xa6\x43\xb9\x6a\x43\x79"
-  "\x22\xb9\xc2\xb4\x0e\x59\xa6\x50\xd6\xce\x50\x3a\xc4\x61\x72\xe7"
-  "\xde\x5c\x35\xe9\xc8\x01\x95\xff\x51\x92\x31\xf6\xfa\x8f\xfa\xd9"
-  "\x6d\x9b\xfa\x45\x3d\xf9\x1f\xb5\x7b\x45\x1d\x04\xf9\xee\x4f\x0f"
-  "\xe1\xfb\x19\x94\xe3\xc9\xc4\x67\x31\x57\xed\x7f\x14\x71\x3b\xc3"
-  "\x6d\xf1\x7d\x58\x07\xbc\xaf\xf2\x27\x53\x7e\x89\x87\x3d\x41\x1e"
-  "\xfa\x0d\xd1\x78\x18\xc1\x3b\x7e\x6f\x34\xab\xf7\xd7\x52\x5b\xc1"
-  "\x3c\xc7\xe4\x3b\xa3\xa3\xd5\x25\x96\xa1\x56\x37\x43\x3c\x95\xd1"
-  "\x95\xcc\xd3\x9f\x8d\x56\x46\xa4\x1c\x77\x75\x00\xd0\x5c\x38\xe5"
-  "\x4b\x4b\x26\xbe\x06\x12\xa2\xd6\xef\xd6\x30\xdc\xe2\xc5\x1d\xda"
-  "\x01\xdd\xab\xd2\x1d\xda\x98\x6f\xc5\x8d\xf0\x4b\xd3\x8b\x7e\xd1"
-  "\x36\x9b\xe4\x39\xb0\xcf\x8e\x5a\x84\xc2\xa4\xef\x8a\x21\xec\x6b"
-  "\x22\xe7\xf3\x63\xaf\x2f\x04\x7e\x1d\xbe\xbe\x10\x78\x3f\xd6\xfa"
-  "\x42\x44\xb9\xd7\xa9\xdc\x40\xfb\x06\x45\x48\xd9\x03\x81\x28\x65"
-  "\xcb\xf9\x33\x3b\x42\xc7\x2f\x6c\x15\xe1\xd0\x87\xfd\x12\x9b\xbe"
-  "\x41\xc1\x10\x4e\x17\xef\xb3\x59\x9e\xb0\x57\xc8\x0e\x62\xe9\x94"
-  "\x26\x92\x8e\xb1\xbf\xf8\x64\xb2\xd9\xe0\x3a\xff\x88\x7b\x08\xb4"
-  "\xf4\x3b\xad\x4c\x8e\x56\x86\x25\x06\x16\xe5\x23\x01\x60\x3a\x4f"
-  "\xcf\xf0\x4f\x04\x49\xdf\x2e\xfe\xa1\x1e\x4b\x3f\x16\xff\x1f\xf8"
-  "\x9b\x24\xf0\xe5\xf0\xbc\xa0\x90\xca\x3b\x14\x92\x62\xc5\x0d\x72"
-  "\x33\x90\xb3\x44\xfb\xa3\x51\xb3\x79\x03\xda\x73\xd3\x8f\xf3\xc4"
-  "\x8c\xf9\x24\xf8\xf2\x37\x0b\xfd\xa6\x90\xf0\x6f\xfc\x53\x6d\x0e"
-  "\x29\x60\xa6\xaa\x84\x6f\xab\x9a\xd1\x3d\x16\xa4\xec\xd0\x86\x17"
-  "\x6a\x8e\xe3\x3f\x1a\xfa\xc7\x88\xf0\xd2\x31\x7e\x7a\x30\xbd\xca"
-  "\xbd\x3f\x24\xf1\x1f\x05\xfa\xa9\xb1\x69\xf8\xe6\x7f\x33\x42\xde"
-  "\x67\x8a\x9f\x14\xdb\xb7\x59\xc0\x0d\xff\xf4\x67\x26\xc9\xaf\x41"
-  "\xf1\x48\xcd\x8b\x96\x34\xc8\xff\x54\x99\xdf\x61\xf5\x19\x8c\x9f"
-  "\x95\x16\xfe\x3d\xbb\x2b\xfc\x3b\xcd\xf7\x6d\xa0\x6e\xa3\x7f\x4c"
-  "\x8e\x44\x80\x39\xc1\xfa\xd2\x44\x34\x19\x8d\x35\xa2\x09\x05\xff"
-  "\x24\x6c\x54\x00\x73\x0b\x42\x82\xd5\xd1\x53\xff\xef\xf9\x9b\xb6"
-  "\x5f\x62\xe0\x4c\x97\x76\x5c\x64\x64\x18\x7d\x4f\xd0\x4b\x61\x0b"
-  "\x3e\x19\x97\x9e\x87\xe9\x43\xbe\x15\xb9\xf8\x4f\x07\x66\xdc\xf0"
-  "\x6d\xe0\xfa\xdd\xdf\xff\x0f\xff\x14\xd4\x3e\xbe\xfb\xfb\xdf\xf4"
-  "\xc7\x44\x2f\x8e\x9a\x88\xff\xd0\x7f\x6c\x4c\x51\x32\x29\x82\x49"
-  "\x01\x4c\x7a\xf9\x56\xfa\xf1\xef\xfe\xbe\xfb\xfb\xee\xef\xbb\xbf"
-  "\xef\xfe\xbe\xfb\xfb\xee\xef\xff\x03\x7f\x0a\x3e\x8e\x60\xd2\x9f"
-  "\xfc\x2e\xe2\x68\x08\xb4\x65\x80\x87\x41\x30\x1e\xc7\xbe\x8b\x41"
-  "\x11\x0f\x13\xd4\xdf\xa6\x8d\xa7\x1f\x43\xe8\x6b\x24\xce\xc2\x67"
-  "\x01\x3e\x8b\xf0\x99\x1e\x12\x3e\x23\x7a\xf2\xff\x84\x3f\x05\x32"
-  "\x4b\x85\x63\xc0\x38\x98\x00\x13\x21\x1e\x26\xc1\x64\xb8\x09\x12"
-  "\x60\x0a\x4c\xc5\xb1\xa5\x16\x12\x21\x09\x6e\x86\x64\xb8\x05\x6e"
-  "\x85\xdb\x40\x07\xdf\x83\x69\x88\x79\x0a\xa4\x46\xc7\xd9\x0c\xb9"
-  "\x3a\xfc\x07\xff\x2f\x80\x5c\xfe\x5d\xfc\x5d\xf8\x7f\x6a\xb8\x4d"
-  "\x0a\x3f\x23\x85\x3b\xbe\x0b\xff\x4f\x0d\xd7\xff\x1f\xfe\x9d\xf5"
-  "\x7f\xf4\x57\x81\x6a\x59\x68\x66\x45\x54\x7d\x18\x19\xaa\x90\xfe"
-  "\xc6\xbe\xe1\x2b\xf2\x8f\x83\x17\x9e\x3f\xf2\x2f\x17\x9f\x6c\xf1"
-  "\x6a\x02\x10\x73\xb9\x2c\xf4\xef\x2b\x67\xe6\x8c\x65\xf8\xd4\xe0"
-  "\x63\xc6\xe7\x00\x3e\x0d\xf8\xbc\x21\xc3\x11\x69\xe2\xf1\x71\xa8"
-  "\x01\xce\xbc\x0f\xf0\xa7\x01\x7c\xf2\x00\xfe\x0d\xd3\xff\xd7\x64"
-  "\x80\xff\xb6\x01\xe0\xec\x09\x80\xff\xee\x0e\xc2\x1c\xb0\x06\xb1"
-  "\x3b\x6f\x16\xef\x7a\x7c\x3e\xa7\x3d\x78\x28\x49\x57\xe9\x2e\xf1"
-  "\x93\x2b\x37\xe4\xe9\x17\x64\x66\x67\x66\x2f\xd2\xcf\x9b\xa7\x5f"
-  "\x98\x95\x75\xef\xfc\xac\xc5\xf3\x17\xde\xad\x5f\xb8\x68\xc9\xe2"
-  "\xbb\x97\x2c\xcc\xd1\x3f\xbf\xa7\xaa\x7c\x41\xd6\xb3\xa5\xfa\xca"
-  "\x92\xf2\x6a\xfd\x33\xe5\x55\xcf\xef\xde\x52\x55\xfa\x55\x14\x7d"
-  "\xe3\x3f\x42\x2d\x35\x00\x9c\xfb\xe1\x9c\xd6\x80\x7a\x62\x0b\xa8"
-  "\x75\xc5\x10\x8c\x49\x97\x9e\xa8\x7f\xcf\x3f\xf1\xd8\x5f\xe6\x6e"
-  "\x9a\xfa\xdb\x07\x9e\x9d\xbb\x6c\xf9\x3b\x0d\x9d\xa0\x9c\xd5\x0c"
-  "\xca\xef\x6d\x06\xa5\xa6\x10\x94\xaa\x7e\x50\x0c\x9f\x03\xe5\xa6"
-  "\x64\x50\xae\xeb\x01\x65\xde\x49\x50\x2e\x4b\x07\x65\x56\xca\xf8"
-  "\xb0\xf2\x4e\x11\xf6\x96\x11\x94\x8d\x2b\x40\xf9\x62\x0b\x28\x8d"
-  "\x05\x22\xec\xa3\x3c\x50\xfe\xfc\x5b\x67\xc3\x7f\xf0\xef\xeb\xd8"
-  "\x07\x37\xfe\x53\x2f\x3e\xf8\x2d\xe0\xf1\xdd\xdf\x77\x7f\xdf\xfd"
-  "\x7d\xf7\xf7\xdd\xdf\x77\x7f\xdf\xfd\xfd\x27\xff\x5d\x55\xaa\xe1"
-  "\xb7\x68\xfd\x79\x2c\xf1\x3a\x87\x62\xf2\xfb\xb4\x5f\x04\xe8\x1c"
-  "\x14\xc4\xf3\xf3\x17\xd2\x13\xba\xd7\x24\x61\xf9\x51\x00\x3a\xcb"
-  "\xf9\xea\x11\xe6\xa2\x73\x9a\x2b\xde\x05\xe8\x4a\x03\xa0\xfd\x2b"
-  "\x08\x67\xb3\x03\x2a\xd4\x62\xaf\x12\x73\x53\x3c\xed\x77\xc2\xf0"
-  "\x1a\x0c\xaf\xbd\xc1\xfe\x17\xbe\xd7\x8a\x60\xae\x98\xc5\xf1\x39"
-  "\x16\x01\x87\x60\x9c\xc4\x30\xf7\x0d\x60\x24\xc8\x78\xb9\x95\xa0"
-  "\x20\x78\x43\x16\xd0\xb9\x2d\xb6\x5b\x30\xaf\x1b\x69\x4a\x97\xf6"
-  "\x0a\x0d\x32\x0b\xa8\xba\x8c\x3e\x3a\x33\xaa\xb8\x00\x93\xbe\xc0"
-  "\x5f\x25\xfe\x7e\x0a\x62\x6f\x27\xe5\x4b\x23\x18\x98\x57\xe1\xb1"
-  "\x4c\xca\x1a\xcb\x8b\xb0\xf9\xb9\x6f\x98\xf4\x91\x5b\x69\x53\x8a"
-  "\xb4\xda\x49\x52\x5a\x25\xa6\xdd\x2c\xa7\x15\x71\xca\x55\x52\xdc"
-  "\x4d\x18\x67\x0c\x8f\x53\x37\x49\x71\x09\x18\xd7\x1c\x81\x9f\xda"
-  "\x3e\xe2\x03\x2c\x87\x70\xd1\x3b\xf0\x97\xce\x29\x49\xb8\x11\x4e"
-  "\x5d\x98\xde\x4c\xe9\x57\xe8\x99\x6f\x83\x1e\x38\x2e\xc4\x3b\x4c"
-  "\x9b\x77\xba\x43\xa4\xc5\xf7\x14\xca\x2f\xbd\xeb\x69\xdf\x14\xbd"
-  "\x4b\xe5\x26\x7a\x2c\x93\x13\xc2\x71\x02\x90\xe2\x92\x30\x2e\x3d"
-  "\x3c\xee\x37\x59\x52\xdc\x6d\x18\xb7\x22\x3c\x4e\x21\xe7\xd3\x61"
-  "\x5c\xb1\x1c\x37\x7e\xdf\x0d\x0e\x4b\x20\x0e\x07\x28\x13\xf0\x99"
-  "\x18\x2f\xd7\x5d\xb5\x8e\x05\x4c\xdf\x03\x35\x6b\x9a\xde\x19\xb0"
-  "\x30\xb0\x1b\xbd\xa0\x9f\x06\xa6\xf3\x30\xf9\x0c\xed\xdf\xa9\xdf"
-  "\x0b\xf1\x26\x03\xf3\xd2\x99\xf8\x3e\xd7\x20\x98\x5c\xcc\x49\xe7"
-  "\xce\xeb\xae\x41\x3c\xdd\x33\x54\xb7\x03\x74\x5d\xb5\x7f\x8b\x7e"
-  "\x0f\x2d\xdd\xe3\x93\x42\x79\x07\xa0\xaf\x75\x00\x4c\xad\xe1\x79"
-  "\x4d\xa9\xa0\xeb\xa5\x33\xec\x16\xd0\x10\x1e\x5d\x7a\x1f\xf8\x92"
-  "\xa6\x77\xd6\xbe\x01\x6a\xd3\x2c\x50\xf6\x96\xd8\x24\x5c\x6e\x6a"
-  "\x21\x5c\x0e\x5e\x84\xf8\x77\x9e\xc1\xba\xbf\x48\xf8\xce\xe9\xfc"
-  "\x70\xaf\x57\x79\x5a\xb7\x1a\x4e\xeb\xce\x41\x97\x6e\x19\x74\x19"
-  "\x57\x40\xfd\x45\x48\x38\xed\x5d\x0a\x5d\xea\x87\xb0\x6d\xac\x00"
-  "\xfb\x20\xbe\xeb\xfd\x98\xc6\xcd\xcf\x63\x5c\x80\x9b\x0e\x35\x3f"
-  "\x07\xf1\x0e\x01\x13\xeb\xf3\xa6\x66\xf9\x6c\x01\x7d\x47\xa3\xa3"
-  "\xfa\x7b\xa0\x43\xfc\x9c\x88\xcb\xbd\x88\x4b\x6f\x9a\x0e\xb2\x10"
-  "\xe7\x89\xf6\x16\x1f\xa8\x6b\x61\x52\x8c\x36\x91\xcc\xcf\x25\xa3"
-  "\x4c\xb5\x1d\x61\x4e\x92\xad\xa1\x17\x0a\xb1\x7d\x25\xa8\xb1\xec"
-  "\x63\xd2\x7e\xbd\x41\xd3\xdb\xa0\x1e\xda\x5d\x48\xfb\x94\x07\x30"
-  "\x4e\x2f\xc7\xd1\x79\x6b\x3a\x47\x3d\x3f\x99\xee\x73\xca\x85\x8f"
-  "\x47\x9c\xb4\x17\x70\x90\xf6\x67\x12\x3c\x8d\x11\x54\x48\x4f\x1c"
-  "\xe2\xf3\x65\x3b\x86\xcf\xc1\x74\x98\x1f\xeb\xff\xe7\xfc\xbc\x3d"
-  "\xbb\x6d\x93\x3b\x70\xdb\xa6\x6b\x81\xd7\x37\x0d\xb1\xd7\x37\x5d"
-  "\xf5\xbf\xbe\xe9\x4b\xd3\x1e\x88\xf7\xdf\xb6\xc9\xd5\x67\xe0\x75"
-  "\xa0\xed\x33\x5c\xa2\x7d\x7d\xf1\xe4\x3f\xfb\xa9\x1d\x58\xf7\xbe"
-  "\x4f\xe9\xde\x23\x5d\x20\x71\x76\x99\xdd\xf7\x67\x78\xaa\x16\x18"
-  "\xbe\x1b\xa3\xd1\x37\x94\x34\xc7\x25\x64\x36\x9e\x68\xea\x77\xa8"
-  "\xa7\xf1\xfd\x80\xae\xc4\xbb\x5c\xf8\xb8\xf1\xf1\xe2\xe3\x63\x49"
-  "\x73\x7c\xc8\x2b\xd3\xd4\xfd\x0a\xa0\xf3\x04\xf3\x03\xa0\xc0\x2a"
-  "\x72\x23\xfe\xda\x18\x7c\x4b\x09\x34\x3d\x57\xfc\x7d\x33\xd4\x91"
-  "\x2f\x02\xd2\x29\xa4\x4f\x48\xbf\x78\x2c\x53\x72\xb1\x1c\x27\x97"
-  "\xfd\x23\xcc\xcd\x92\x9e\x2b\xc6\x70\xa7\xfb\x85\x32\x85\xeb\x85"
-  "\x32\xe5\x50\xd2\x73\x5b\x31\x4d\x89\x43\x3d\x5d\x2f\xf1\xd0\x49"
-  "\xb0\xb0\x9d\xb8\xa6\xf8\x40\x85\x30\x0d\xff\x3c\xdc\xaf\x3e\x7a"
-  "\x84\x9d\xc3\x74\x87\xc7\x60\x21\x6c\x84\x83\xfc\x9f\xd2\x21\x87"
-  "\x21\xaf\x07\x5e\xc1\x74\x94\xdf\xee\xcd\x25\xbd\xeb\xb0\x57\x38"
-  "\x69\x3f\xed\x64\x36\x2a\xca\xc3\x34\x74\xd6\xd2\x35\xc5\x0b\x13"
-  "\x3c\x16\x28\x20\xd8\x94\x8f\x7c\x88\x61\xbe\xad\xcc\x54\x86\x7a"
-  "\x09\xd6\x7a\x58\x99\x82\xce\xd6\x9f\xc6\xfc\xa2\xec\xa9\xf1\x32"
-  "\x8e\x54\x06\x3f\x5b\x4f\x78\xa2\x3c\x9c\xae\xf0\xc2\x94\x16\x50"
-  "\x61\xbe\xf5\x04\x8f\x60\xa1\x1c\x38\x90\xd6\xad\xa7\x2b\x5c\x10"
-  "\x60\x61\x30\x1d\x12\xbc\xc2\x30\x78\x18\xce\x10\x1e\xc9\x5f\x17"
-  "\xe6\x99\xd2\xc1\xe1\xad\xfb\xe7\x00\xc1\xf3\x82\x5a\xcf\xf1\x7d"
-  "\x8c\x60\x70\x3f\x15\x08\xd3\xb6\xeb\x41\x18\x84\xa9\x36\x97\xa9"
-  "\x4c\xc5\xf7\xf5\x61\xfe\x0f\xeb\x9c\x71\x6c\xa8\x50\x35\x95\xef"
-  "\xe9\x7b\x10\xc8\x27\x05\xa6\x79\x9b\x0d\x95\xa9\xa6\x0c\x82\x9a"
-  "\x70\xa6\x73\x3d\x84\x67\x68\x5d\xae\x5b\xf9\xd8\x32\x78\x6c\xc5"
-  "\xaa\x15\xcb\x60\xcd\x03\xcb\x97\x41\xd6\xbd\xf3\xb2\x16\xdd\x93"
-  "\xb3\x08\x0a\x1e\x5f\xb7\x0c\x0a\xd6\x2e\x83\xf5\xf8\x14\x3e\xb4"
-  "\x0a\x3f\x96\x2f\x5b\x90\xf5\xf0\xbc\x82\xe5\xab\x56\xc2\x23\x1b"
-  "\x16\x66\x2d\x5c\x08\x0f\xac\x5c\xbd\x20\x2b\x4b\xfa\x5d\x90\x45"
-  "\x49\x9e\xc8\x59\xb9\x7e\x5e\x41\xd5\xf6\x9a\xed\xf3\xd6\xae\x5a"
-  "\x0e\x2b\x57\x2e\x2b\x88\xe8\x1b\xd3\xfd\xc3\x7e\xe2\xad\x9b\x5d"
-  "\xc9\x23\xdf\x09\xd0\x86\x75\x8e\xcf\x20\x3f\x93\x01\xda\x17\xdb"
-  "\xa8\xae\xb8\xbe\x9c\x7a\x0e\xdb\xb9\xda\x63\xd1\x60\xfd\x4f\xe7"
-  "\x3e\x28\xc8\x7f\xc1\x05\xb8\xe5\x28\xc6\x7d\x26\xe9\xe8\x38\x8c"
-  "\x7f\x3f\x3c\x3e\xd1\x8c\xf1\x9f\xd3\x1e\x7f\x3b\x3e\xc8\x67\x37"
-  "\xea\x3e\xe4\xa7\x0b\x86\x4c\x85\x71\xfc\x8c\x25\xd6\x31\xed\x7d"
-  "\xc5\xbc\xce\x90\x36\x4e\xe7\xc3\xcf\xe8\xf7\x82\xea\x32\x68\x3e"
-  "\xe9\xab\xc9\xa5\x73\x30\x60\xaf\x91\x60\x5c\x1b\x83\x31\x59\x3a"
-  "\xa7\xe9\x68\xa3\xfd\xc7\x1c\x8e\x36\x2b\x44\x1f\x38\x08\x4e\x3d"
-  "\xc6\x09\x58\xda\xb8\x3e\xd4\x0b\xa8\xb7\xff\x25\x60\x4a\x07\x96"
-  "\x34\xfd\x64\x60\x34\x9d\xf7\x31\x98\xaf\x4c\x96\xe3\x7a\xda\xdb"
-  "\x6a\xc0\x74\xef\xe4\x29\x68\x6f\x28\xdf\x27\x0a\x9a\x1a\x94\x67"
-  "\x77\xa0\x29\x03\xf8\x19\x66\x1e\xa6\x3d\xc1\x92\xf0\xbb\x29\x43"
-  "\xc1\x4c\xe2\x5c\x33\x86\xfd\x23\x85\x61\x1d\xab\xb8\x5f\x90\x17"
-  "\x78\xb8\x0a\x79\x41\xe7\x9a\xfb\xfd\x94\xff\x0a\xcf\x3f\x11\xc3"
-  "\x26\x61\x5a\x45\x20\x29\x43\x89\x32\x43\x61\xd8\xaf\xdf\x72\x0a"
-  "\xe1\xa9\xe8\x4c\x39\xd3\xbe\x67\xc5\x77\xb5\x6d\xef\x20\xf7\xd1"
-  "\xee\xc0\xb8\x80\x09\x61\x8e\x8e\x95\xdf\x4f\x79\xb1\x2c\xb5\x67"
-  "\xb4\x0c\xfb\x52\x2d\xf7\xbb\xec\x27\x7c\xae\x8c\xa5\xe9\xa6\x32"
-  "\xa9\x3d\x63\x5d\x0c\x62\x3d\x4d\xf2\x58\x12\x37\x44\xd4\x53\x05"
-  "\xc2\xa1\x33\x10\xfd\x08\xa3\x2b\x30\x84\x65\xe0\x37\xc2\x55\x4a"
-  "\x70\x65\x18\x6e\x21\x07\x89\xcd\x11\x72\xb0\x1f\x61\x5f\x0b\x89"
-  "\x3f\x11\x11\x5f\x8a\xf1\x23\x52\x3c\xb6\xab\xc4\xb3\x11\xe5\x13"
-  "\x6e\x01\x2c\xdf\x8d\xed\x46\x85\xe5\x91\x5f\x06\x57\x30\x7d\x92"
-  "\x3a\x3c\x7d\x12\xda\x06\x1a\xd2\x25\xa4\x13\x79\xfa\x76\x49\x56"
-  "\x45\xf9\x49\xd9\x11\xe9\x7d\x98\x7e\x22\xf9\xde\xc0\xdf\x9b\x31"
-  "\xcd\x44\xd4\x49\x74\xb6\xe6\xdc\xe9\x5a\xb2\xdf\x92\x4a\x22\xd2"
-  "\x1f\xc4\x74\xd3\x88\x8f\x9c\x07\x57\x38\x0f\x0a\x25\x7b\x8b\xda"
-  "\x42\x3c\xe6\x69\x89\xc8\x73\x12\xf3\xcc\x0e\x08\xbe\xa9\x3c\x43"
-  "\x51\xf3\xf4\x44\xe4\x19\xe4\xf5\x2f\xca\x51\x93\xbc\xc8\x79\xb8"
-  "\x8e\x19\x0d\x83\x41\xb4\xa1\x5d\x76\xb3\x36\x1c\x46\xf2\x20\x96"
-  "\x7b\xe7\x2b\xa2\x1d\xdf\x84\x75\xbe\x10\xc3\x3e\x45\xb8\x71\x24"
-  "\x27\x24\xcb\x76\x97\x17\x75\x60\x5e\x82\xe8\xcb\x6f\xde\xa1\xa9"
-  "\x05\x7a\x9f\x47\xef\x04\x9b\x8d\xae\x96\x64\xfc\xe6\x1d\xf8\x4b"
-  "\xe1\xbc\x4c\x6a\x5b\x6c\xf4\x47\x01\x01\xf3\xe6\xd7\xb0\x0d\x2a"
-  "\xf1\xdb\x2f\x95\xf1\x67\x3a\xdf\x8b\xf2\xa9\x44\xfd\x0a\x74\x46"
-  "\x19\xc3\xb3\x31\xbc\x57\x8a\xff\x1d\xa5\xc7\xf7\x05\xd2\x3b\xc9"
-  "\xa5\x52\x92\x4b\x94\xf3\x64\xb1\x0f\x9b\xcb\xba\xc8\x1f\x10\x72"
-  "\xbd\x1c\xe3\xde\xc3\xdf\x55\xf8\xfb\x1a\xfe\x3e\x82\xbf\x3b\xc8"
-  "\x27\x83\xc9\x8f\xf6\x84\xf8\x7e\x12\x7f\xd7\xe1\xef\x2a\xfc\x5d"
-  "\x8f\xbf\x8b\xa9\x5d\xba\x76\x97\x41\x84\x4c\x0c\x06\x44\x5b\x9c"
-  "\x28\xea\x23\x39\x4d\x6a\x1f\xa2\x7d\x5e\x09\x86\x31\x11\xa6\x44"
-  "\xbd\x1e\x0c\x1b\xcd\x23\xbe\x14\x20\x7c\xee\x43\x44\x6a\xd7\x71"
-  "\xa2\x5e\x44\x9a\x80\xc8\x27\xd5\x9d\x14\x26\xd2\x29\x42\xcb\x74"
-  "\xc0\xcd\x67\xeb\xdc\x8c\xe1\xaf\x8d\xfb\x73\x80\xe4\x2e\xe4\x09"
-  "\xda\x35\x37\x37\x13\x9f\x82\xf5\x7d\x73\x56\x48\x7d\xa3\x5d\x7b"
-  "\x0b\x44\xb4\xa5\x6c\xac\xef\xa5\xbc\xbe\x91\x77\x32\xce\x84\x3f"
-  "\xf6\x2f\xf4\x3d\x41\xd0\xa0\x2d\x44\xdd\x3e\x18\xd4\xcd\xb7\xe4"
-  "\x85\xc3\xd1\x16\x62\x9e\x1a\xa9\x2f\x1b\x93\x33\x92\x17\x95\x81"
-  "\xda\xd0\x2d\x68\xff\x7f\xd2\xc3\xcf\xf6\x60\x9c\x3b\xf1\x39\x07"
-  "\x95\xa9\xaa\xe0\x71\x68\xff\xdf\xd4\x2f\xc7\x81\x38\x3f\xe5\x56"
-  "\xd5\xf0\xb8\x4e\x39\x1f\xea\xd9\x7e\x9e\x17\xfb\x47\xb2\x17\xa8"
-  "\xdf\xc7\xfe\xd7\x89\x69\xce\x3a\x60\x8a\x36\xa6\xff\x22\xeb\xf4"
-  "\xee\x79\x66\x50\xce\x31\x43\x9c\xdd\x77\x0e\xf2\x7d\xcc\x3f\x0f"
-  "\x60\x92\xdd\xb7\x14\xee\x00\x48\xb4\xfb\xce\xd2\x24\xf9\x2c\xbb"
-  "\xaf\x19\xfb\xd7\x83\x14\xff\xf1\x9d\xa0\x50\xe0\xaf\xe9\x2e\x50"
-  "\x2a\xec\xbe\x63\x18\x7e\x02\xe6\x80\x5a\xf1\x70\x1c\xf3\xd8\x7d"
-  "\xd9\xf8\x5d\x03\x0f\xc5\xb1\xbf\x16\xf9\x41\xbb\xfa\x45\x66\xb2"
-  "\xfb\x4a\xe0\xa1\x17\x03\xcc\xee\xeb\xc1\xb8\x0a\xc8\xf7\x5f\x67"
-  "\xf9\x7e\x0f\x63\xda\xe9\xfd\xf9\xfe\x2b\xf8\xfe\x57\x86\x7c\xc3"
-  "\xdf\x8f\xf1\x31\x31\x3b\xda\xc9\xac\x71\x7a\x77\xd1\x1e\x25\x8c"
-  "\x62\x5f\xc4\x12\xa7\xf7\x23\x7d\xce\x51\x56\xa6\xc2\x7e\xe4\xf3"
-  "\xd1\x51\xfc\x6d\x9a\x7e\x81\x7f\x5b\xa7\x7b\x11\x8e\x33\x13\x07"
-  "\x0d\x84\xbf\xdd\x37\x00\x45\xa8\x6f\xf2\xf7\xb8\x18\xe1\x3e\x75"
-  "\x3f\x83\xfc\x3d\x1f\x33\xd4\x75\x9a\xfc\x3d\x26\x86\x71\xf1\x08"
-  "\x0f\xed\xfc\x41\x2a\xc3\x8b\xf0\xae\x71\x78\xd6\x14\x1d\xa6\x75"
-  "\x51\xba\x50\x38\x04\x83\xd2\xe6\xfb\xc9\x7f\x54\x8a\x6e\xb4\x31"
-  "\x25\x1e\x9f\x74\x7c\x0a\x59\x52\xca\x73\x01\x4b\xf2\x27\xd4\xaf"
-  "\x61\x7e\x23\x7e\x1f\xba\xce\xfd\x2e\x9c\xa3\xf4\x13\x31\xbd\x11"
-  "\xeb\x7c\x85\x87\xe3\x9b\x72\x9c\xe3\xdb\x94\xf2\xf3\xeb\x9c\x8e"
-  "\x94\x9f\x09\x3a\x52\xde\xa5\x70\x37\xca\x3a\xbe\x77\xbb\x45\xdc"
-  "\xbf\x62\xbe\x0d\x1e\x81\x57\x37\xd3\xa6\xf4\xa3\xdc\xaa\xf2\xfd"
-  "\xcc\x4c\x3c\x44\xbe\x9a\x89\x8f\x34\xe6\xc1\x32\xba\x59\x62\x4a"
-  "\x3f\xe2\xe3\xc4\xfc\x23\xa3\x8c\xfa\xda\xd4\xf8\xeb\x1c\x76\xea"
-  "\x44\x84\xb3\xd9\x43\x30\xb5\xa9\x58\xd7\xa9\x3a\x9f\x52\x8f\xfc"
-  "\x60\xde\x7c\xdf\x7e\x5f\xd1\x1e\xf2\x8d\xf2\x3b\x48\x37\x9b\x15"
-  "\x76\x63\x0d\xd2\x79\x18\x61\x96\x60\x3c\xdc\x8c\x65\x7d\xcc\x12"
-  "\x53\xe3\xa9\x3c\xd6\x98\x8a\xed\x31\x15\xc7\xca\x50\x42\x38\x8d"
-  "\x90\x1f\xd0\xa4\xd4\xf4\x11\x8e\x5f\x6a\x5e\xc0\x9a\x5a\x16\xd0"
-  "\xa6\x16\xca\xf2\x43\xb2\x23\xf8\x46\x32\xf3\x01\x85\x69\x65\x39"
-  "\xf1\x5b\x53\x73\xee\x02\xd0\xae\x75\x33\x1f\xc9\xca\x7c\x30\x28"
-  "\xfa\xdc\x67\x91\xd7\xf1\xd0\x67\x38\x01\x77\x02\x8d\xbd\xdc\xd0"
-  "\xe7\x6e\xc6\xef\xa3\x40\xf8\xf5\xb9\x0f\x42\xef\xe0\x31\x58\x6b"
-  "\x70\xef\xf7\x6b\x53\x4f\xf6\x0e\xae\x01\xcc\xff\x31\xdd\xb9\xf3"
-  "\x94\x41\x6d\xee\x33\xb8\xe9\xdb\xd4\x3b\x88\xf2\xe9\x67\x7e\x9f"
-  "\x35\x35\xdd\xa7\x4d\xed\x5e\x7b\x8d\xb9\xd6\x0c\x9a\xe3\x30\x6c"
-  "\x54\xa3\x60\x3e\x8d\xd1\xc4\x7a\x07\x0f\xc3\x53\xd7\x40\xd1\x5b"
-  "\x76\x82\xcb\xe9\x53\x06\x03\xf0\xfc\xd7\x7c\x9a\x27\x07\xcd\xf0"
-  "\x64\x19\x4c\xc5\xf4\x57\x48\x66\xd9\x54\x33\xf4\x0c\x54\xc0\x9a"
-  "\x4b\x3e\xd5\xda\x6b\xa3\xac\xa7\xb8\x19\x7a\xcb\x9a\x89\x1f\x79"
-  "\x34\x46\x59\x73\x69\x88\xad\xbd\xe6\x61\xbd\x65\x1f\x40\x4f\xf1"
-  "\x09\x58\xfd\x37\x9b\xc6\xdf\x98\x9a\x13\x48\x4c\x2d\x0c\x34\xa6"
-  "\x96\xf9\x13\x53\x4f\xfa\x1a\x11\x97\xc4\xd4\x6e\xd6\x34\x23\x07"
-  "\xf9\x37\x89\xd7\x45\xd2\x8c\xbb\xf1\x5d\xcf\xeb\x57\x3b\x23\x8f"
-  "\x59\x67\x94\x8d\x36\xce\x28\xe4\x72\x9f\x38\x23\xcf\xee\x23\xf9"
-  "\x9f\x51\x86\xe9\xca\x84\x8c\xcc\x30\x0a\xd9\x9f\xb1\x9b\xea\x15"
-  "\xd3\x1e\xc2\xa7\x05\x9f\xe3\x18\xe7\x45\x58\x89\x04\x37\x60\x9d"
-  "\x19\x1f\xd0\xce\xc0\xf6\x30\x53\x87\x63\x1a\x65\x9f\xfb\x18\x90"
-  "\x5f\xdc\x3e\xb7\x1f\xd6\xee\xf0\x62\xdd\x62\x1d\x18\xfd\xc8\xcf"
-  "\x73\xf0\xd4\x0e\x30\xd9\x8d\xe7\x80\xfd\xc6\x4a\xfc\xd0\xac\xdd"
-  "\xf1\x31\x0b\x34\xce\x8c\xa7\xf8\xb5\x3b\x4c\x38\xae\x42\x38\x89"
-  "\x33\x75\x81\xa6\x99\x39\x92\x7d\x85\x78\xcc\xbc\x87\xf0\x18\xf5"
-  "\xa4\xd3\xb9\x37\x35\xc6\xe7\x61\xd8\xbf\x50\x7f\x13\x20\xb9\xb3"
-  "\xce\x3c\xc9\xb4\x7a\xdd\x9a\x38\xe6\x22\x9f\xb6\x24\x03\x81\xfb"
-  "\x18\xa3\x71\x5b\x91\x11\x3a\x78\x9b\xf2\x4f\x33\xb3\x44\xbd\x8e"
-  "\x35\xce\x3c\x19\x68\x9a\xfd\x04\xc2\x51\xd1\xbd\x34\xcc\x3a\xbb"
-  "\x50\xc8\xcc\xa7\xbc\xed\xb1\xc6\xd9\x85\xe1\x73\x04\xd1\xe7\x07"
-  "\x3c\x96\x69\x27\x1c\xd0\xc7\xcf\x97\xe1\xbb\xcd\x01\xf6\xa5\xd2"
-  "\x7b\x8f\x03\xfe\x9e\xcf\x13\x91\x8e\x33\xd4\xc1\x2d\x17\x61\xba"
-  "\x19\xf9\x01\xf8\x9e\x80\xef\x07\xf3\xef\x40\x9a\xad\x47\xba\xb1"
-  "\xbe\x3d\xa4\x6f\x98\x25\x9b\xfa\x92\x5c\xa4\x35\x9e\x79\xd2\x13"
-  "\x58\xd2\x7c\x1c\x4b\xe9\x68\x0c\xaa\xc1\xef\xa9\xc8\xd3\x34\xfc"
-  "\x4d\x3a\x3a\x0c\xc9\xf8\x90\x3f\x56\x33\xe9\x63\x7c\xcf\x62\xbb"
-  "\x75\x93\xeb\x77\x41\x86\xc6\x2d\xfc\x2e\x6b\xf6\x6b\x69\x2c\x96"
-  "\x4c\xef\xcc\xf2\x4f\xe9\xed\xc3\xb2\xef\x65\x2c\x2f\xca\xbd\xb5"
-  "\x7e\x4f\xba\x92\xf0\x94\x71\x21\xdc\x10\xcf\x54\xc4\xb3\xf9\xd1"
-  "\x3d\xb9\x40\xf7\x0c\x45\xd3\xdf\x1e\xcb\xf4\x31\xfa\x63\xc4\x9f"
-  "\x95\x79\x12\x23\xde\x2d\xf3\x29\xd6\x3c\x01\xb5\x71\xff\x30\x1b"
-  "\x6c\xa8\x14\xe7\xec\x4c\x3e\xf6\xff\xe0\x18\xc6\x5c\x87\x63\xf3"
-  "\x7c\xa3\x97\xd9\x5d\xcc\x46\xf7\x15\xd1\x38\xb8\x1d\xd3\xd4\xf9"
-  "\x58\x80\xc6\xc5\x34\x26\x26\x9f\x6e\x81\xc6\xcc\x41\xd6\x98\xe9"
-  "\x1c\xda\xc5\x7c\x6d\x7c\x1c\x9b\x52\xe6\x80\xfb\x8a\x45\xdd\xa4"
-  "\xe6\x61\x3f\x38\x30\xa4\xcd\x74\x22\xec\x44\x82\xdd\x67\x60\xb6"
-  "\x40\x62\xa6\x0b\xd3\x59\x1d\x20\x7c\xf5\xc9\x73\x7d\xd8\xa7\x0d"
-  "\x1e\x3c\x42\xfd\x5a\xca\xfb\x0e\x98\x79\x68\xdc\x5c\x92\x58\xbd"
-  "\x34\x87\x9d\xb7\x50\x40\xf8\xe9\x11\x3a\xa9\x91\x1b\x3d\x3a\xd8"
-  "\x2f\xa6\x76\x93\x9f\x3b\xd3\x3e\x48\xc1\x7a\x98\x7e\x11\x52\x67"
-  "\x99\x8c\xec\x02\xb3\xa4\x9c\x7c\x67\xaf\x17\x6d\x88\xd4\x0c\x07"
-  "\xbc\xdd\x1f\x8b\x6f\x81\x61\x36\x80\x30\xca\x1a\xd0\x0e\x24\xba"
-  "\x89\x6f\xf9\x46\x16\x40\xfa\x3e\xa3\x36\xd6\xbe\x8b\x6c\xe1\x54"
-  "\x83\xcc\x87\x58\x67\xff\x98\x35\xd3\x27\xec\xc5\xd4\x33\xcc\xc2"
-  "\xc0\x36\x83\xe6\xfe\x52\xff\xc4\x6d\x26\xeb\x8c\xc2\x21\xd4\x1f"
-  "\x34\x47\x42\x3e\xe9\xaa\x75\x0c\x75\x41\x6a\x97\x03\x6e\xcf\x92"
-  "\xc6\x64\x6e\xbb\x6f\x25\xe9\x92\xa8\x67\x72\xf9\xd9\xc0\x31\xf8"
-  "\x33\x5c\x7d\x29\xd8\xd7\xa2\x2e\x62\xda\x6d\x69\x75\xa2\x9e\xbd"
-  "\x04\x97\xce\xb6\x0e\x60\x7c\xb5\x9b\x39\x99\x75\x1b\xf9\x77\x73"
-  "\xd3\x39\x3b\x0c\xfb\x12\xe5\x97\xd9\xaa\x08\xa7\x19\x5f\xda\x66"
-  "\x8c\xc0\x05\xb4\x07\xe9\x2c\xab\x18\x9f\xcd\x38\x77\xba\x06\xa4"
-  "\x31\xdf\x8c\xcd\x0e\x48\xef\x91\xf1\x42\x9d\xc1\x90\xb7\x58\x3e"
-  "\xe9\xbb\x41\xee\x2b\xb2\xba\x96\x79\x11\xd7\x3c\x4c\x7b\x48\xa6"
-  "\x81\xe8\x13\x74\xcd\x68\x0d\xa5\x0b\x71\x70\xa1\x6d\xcd\x79\x50"
-  "\xbd\x07\xe2\xb9\x8f\x2c\x3f\xf5\x1d\x2b\x39\x2d\x44\x33\xa7\x05"
-  "\xed\x0a\xea\x4f\xec\xbe\xc5\x68\x77\xf1\xf0\x32\x84\x85\xe3\xdf"
-  "\xef\xe7\x08\x9b\x6a\x06\xf7\xa5\x1c\xdd\xb7\x63\xaa\xce\x74\x1d"
-  "\x66\x98\x02\xec\xfc\x05\x98\xb9\x13\xf9\xa4\xa2\x5f\xde\x17\x7b"
-  "\x51\x76\xb5\xd9\x3d\xd4\x07\xdb\x6b\xaf\xa1\xde\xe6\x69\x6f\xc6"
-  "\xb4\x03\x98\xa6\x54\x4a\x5b\x2a\xe6\x84\xf9\xef\x44\xfa\xc5\x3e"
-  "\xf9\x16\x94\xdb\x5a\x9a\xc7\x60\xda\xe7\x1c\xf2\x37\xc3\x6f\xfc"
-  "\xcd\x66\x8d\xd9\x3d\xd1\x71\xd1\xeb\x02\x52\x3b\xc4\x72\x6e\x23"
-  "\x39\x32\xed\x81\xef\xa1\x4c\x7e\x56\xb7\x0f\x6e\x21\x19\x63\x89"
-  "\xf3\xe3\x05\xdf\x67\xa2\x2e\x33\x03\x9d\x8b\x35\xec\x82\xe9\xac"
-  "\x71\x3e\x5c\x84\x99\x9f\x16\xd5\xea\x11\x57\x80\x86\xcb\x40\xfd"
-  "\xe4\x5f\x31\xbd\x9a\xee\x94\x6b\xbf\x4c\xb2\x38\xd3\x27\xcb\xa2"
-  "\xc7\xa2\x8f\xbf\x91\x4e\x40\xbe\xb6\x88\x71\x85\x7e\x27\xcd\xb1"
-  "\x9d\x07\x3d\xf9\x09\x55\xd1\x9d\xe6\x18\xf6\x08\x1b\x66\x29\xe4"
-  "\xb3\x10\x79\x8d\xf5\xa8\x3f\x8c\xbf\x2d\xfc\xb1\x80\x59\xfa\x3e"
-  "\x84\xe9\x72\xd9\xb0\x9f\xd2\xb4\x60\x18\xea\x48\x05\xb5\x93\x56"
-  "\x2c\xfb\xa0\x03\x1e\x30\x8a\xba\xd1\x17\x10\xac\x18\x38\x1c\x62"
-  "\xfc\x9c\xe9\x55\xa4\x57\x7f\x49\x5f\xa7\x20\x3c\x84\x9f\x0d\x84"
-  "\xd5\xae\x14\xba\x39\x80\xb8\xb6\x59\x02\x65\xa8\x87\xcb\x02\x4d"
-  "\xf7\x58\xf9\xbb\x14\x47\x78\x04\xb0\xfc\xe8\xf0\xb7\xa5\xd1\x59"
-  "\xf9\x01\x98\x95\x27\xe0\x6c\xd3\xd9\xa6\x5d\xa4\xef\x55\xf4\xed"
-  "\xd6\xe6\x58\xed\x2d\xb9\xc2\x07\x2a\xa6\x11\x76\xfe\xac\x55\x43"
-  "\x58\x86\xc7\x32\x2b\xcf\x01\x77\xc6\x8b\xf9\xc6\x1c\x6b\x8c\xb6"
-  "\xa7\xa5\xb6\xd3\xdb\x0a\x52\x9b\x9e\x13\x47\x73\x1e\x48\x97\xd1"
-  "\xaf\x9d\xd1\x22\xe9\x59\x1a\x83\xdd\x74\x1e\xe6\xa8\xfb\xca\xb8"
-  "\x7c\x2b\x99\x72\xd6\xf1\x30\xdf\x89\x18\x37\xfe\x99\xd5\x8f\x8f"
-  "\x13\x1f\xb7\xf8\x46\xe4\x60\x36\x62\x30\xbb\x84\xf3\x6d\xa8\x04"
-  "\xc7\x44\x73\xd4\xd8\xc7\xb7\xd0\xb7\x03\x66\x39\xd8\x50\x9a\x12"
-  "\x6d\x11\xfe\xde\xbe\x83\xc6\x16\xb3\x13\x90\xff\x2d\xa2\x1e\x08"
-  "\x06\x28\xb0\x2d\x12\xcf\x99\xa9\x85\x79\xbb\xea\xdc\x88\xf3\xec"
-  "\xa5\x5d\x2d\x6e\xd0\xdf\x4e\xb4\xcf\xce\x25\x7a\xdc\xc8\x7b\xfa"
-  "\xad\x6e\x61\xae\xd3\xad\x3e\xa0\x79\x69\x84\x55\xe8\x00\xcb\x0a"
-  "\x31\x4e\xd9\x56\x40\xf0\x24\x79\x60\x32\xed\x82\xc7\x39\x56\xfd"
-  "\x2e\x05\xc1\x7a\x97\xe6\x24\x68\xcc\x14\x9c\xeb\x99\x7d\x14\xdb"
-  "\xf8\xfd\xe4\x43\xf5\x32\xcc\xe6\x7e\xa1\x4e\x97\x71\xff\x6c\x83"
-  "\x47\x79\x7f\x30\xfb\x14\xe2\xeb\x95\xfc\x50\x0c\xd2\x19\x7b\x82"
-  "\x87\xe3\x28\x67\x6f\x99\x0b\xfc\x48\x2b\x3f\x83\x8f\xf5\xb3\x6f"
-  "\x90\x79\x3f\xde\xe5\x55\xf3\xf2\x2b\xb9\x6f\x34\x37\xf9\x93\x65"
-  "\x58\x57\x38\xee\xf5\x62\x59\x35\x91\x3e\x3e\x43\xfc\xc8\x4a\x38"
-  "\xa7\x4d\x3a\x9d\xc6\xf5\xa5\x11\x6d\xae\x43\xe1\xf5\x95\x16\x2f"
-  "\xea\x6a\xce\x86\xf0\xba\x4a\x43\xdb\x65\x4e\x0b\x3e\x9d\xf8\xd8"
-  "\xc4\x77\xe8\x33\xe7\x60\xc8\xfb\x19\x8f\x65\x0e\xf6\x7f\xfa\x64"
-  "\x51\x07\x14\x86\x38\x92\x6c\x7c\x89\xfd\xcb\x28\xf9\xd7\xbd\x04"
-  "\x14\x4e\x72\x4c\xe1\x01\xb4\x55\x90\xb7\xc7\x30\x5e\x4b\x6d\x94"
-  "\x7c\xda\x85\xc6\x8f\xf9\x2e\x81\x39\xd7\xf8\x9c\xc3\xfe\x43\x87"
-  "\x48\x3e\x31\xcf\x71\x8d\xef\xd0\x21\x8f\x25\x0d\x64\x1e\x62\x98"
-  "\x93\xe2\xa3\xdb\x0c\x69\xe9\x63\xb6\x15\xda\x9b\x54\x3f\x83\x30"
-  "\x37\x1b\xf5\x12\xea\xe3\x7b\x0e\x89\xfe\x64\xee\x62\xfa\x46\x7d"
-  "\xf8\x19\xbe\x67\xf5\xa2\xde\x19\x69\xba\xcb\x35\xaa\x84\x89\x23"
-  "\x4a\xc8\xf5\x35\x1d\x19\xf4\x25\xcd\xf1\xd9\x9d\x27\xa0\xcf\xf7"
-  "\xf7\x40\x77\x23\x22\x8c\x3b\xc8\x8f\xa2\x69\x0f\xf3\x7f\x38\x72"
-  "\x1c\x75\xd3\x15\x1b\xf7\x5b\x0c\x73\x39\xed\x2f\x9f\xc7\x5e\xfd"
-  "\x29\x0e\x5b\xe2\xc5\x91\xee\xfa\x67\x98\xaf\xfe\x02\xf9\x56\xd0"
-  "\x4d\x7e\x65\x04\x32\xde\xdc\x0b\x59\xad\x23\x90\xd6\x36\x02\xe9"
-  "\xec\x73\xba\xcf\x22\x78\x07\xc6\x54\x03\xc4\xb7\xed\x45\x3b\xcc"
-  "\x07\x0a\x7f\x23\xda\x61\x3e\xb4\xc3\xae\xa4\x93\xfe\x1b\xb3\xc3"
-  "\x46\x47\xc9\x0e\x9b\x2f\xfc\xed\x36\xce\x37\x4c\x29\x03\x45\x42"
-  "\x31\x68\x11\x3f\xd3\x65\x48\x2b\x4f\x18\x40\x1b\x10\x69\x76\x48"
-  "\xf4\x22\x7f\x6b\x35\x65\x30\x91\xd3\x8a\x3a\x99\x35\xde\x13\x95"
-  "\x67\xbc\xaf\x55\x92\xec\xb8\xa9\x7d\x10\x0d\xfb\x69\x4d\xe4\xc4"
-  "\x34\xaf\xba\xba\x95\x79\x29\xbc\x66\x16\xc9\xde\xdc\x32\x2a\xbb"
-  "\x13\xc3\x3d\x96\xb9\x56\x87\xfa\xb6\x9e\x58\x7a\x58\xb3\x5f\xb6"
-  "\x07\x6e\x4f\x64\x4a\x33\xd9\xdf\x39\xfb\x7c\xcc\x65\xbf\x4c\x6d"
-  "\xf3\x76\x6d\x7e\x05\xf3\xe9\x2b\x69\x7d\xea\x76\xa0\xb5\x33\x9a"
-  "\x33\xff\x15\xda\x2e\x5f\xb5\x5e\x46\x7d\x02\xda\xe7\x79\x9a\x0a"
-  "\x84\x89\xf6\x3f\x33\xa5\x47\x39\x27\x1f\xdd\x1e\xa7\xb5\xd6\x57"
-  "\xf9\xba\xee\xed\xab\x1d\x50\xe0\x95\xfc\x25\x0e\x0a\xfd\xf8\xfd"
-  "\x0c\x1a\xe7\x87\xb7\xeb\xef\x03\x9d\xfb\x1f\xb2\x66\xd4\xda\x66"
-  "\x90\x2e\xbf\xfd\xba\xb0\x6d\x32\x8c\x42\xb7\xdf\xfe\xef\x62\x8e"
-  "\xee\x76\xec\xff\xef\x4e\x20\x78\x86\xd9\x24\x13\xb7\x9f\x65\x49"
-  "\x19\x2f\x50\xba\x4c\x33\x98\xb7\xfb\xa0\x98\x35\x66\x18\x19\x6f"
-  "\x17\x97\x81\xbd\xbe\xcd\x43\x6b\xb2\xee\xdb\x36\x79\xb0\xaf\xcf"
-  "\xc0\xb8\x5a\x2a\xc3\x85\x69\x90\xef\x93\xc4\xda\xda\xed\x2e\x07"
-  "\x64\x2f\x15\xf2\x7e\x7b\x97\x98\x3b\xba\xbd\x6b\x08\xf3\xa2\xed"
-  "\x77\xb3\xc7\xf2\x7d\xad\x03\xd6\xf4\x48\xf6\x27\x5f\xd3\xc6\xb0"
-  "\x34\x07\xe4\xf3\xf9\x94\x9a\x59\xa0\xab\xd1\x33\x67\x4c\xdb\x2d"
-  "\x8c\xce\xf4\xf7\xf8\xba\xb3\x12\x6e\x43\x18\x65\x32\x5c\xec\x3f"
-  "\x7f\x31\xa4\x7c\xf4\x51\x0c\xab\x95\xe1\x62\x1a\x1c\x6b\x7f\xff"
-  "\xf0\x58\x1a\x91\xa7\x35\x24\xcf\xa3\x43\xca\x3b\x7f\x81\x61\x9d"
-  "\x11\x79\x6c\x11\x79\xce\x84\xe4\x31\x4b\xe5\x0c\x44\xe4\x71\x87"
-  "\xe7\x49\x57\x8f\xc7\x2d\x5d\x17\x9e\x27\x3d\x3d\x22\x4f\xce\x78"
-  "\xdc\xd2\x57\x47\xe4\xd9\x1c\x91\xa7\x22\x84\xb7\xb4\xbe\x9c\x85"
-  "\x61\xe6\x88\x3c\xd6\x88\x3c\x1d\xf2\x37\xda\x92\x36\xd1\xd7\xa3"
-  "\x3c\x61\x9d\x62\xbd\xd6\x62\x3c\xd2\x9f\x93\x71\xa3\x7d\x00\x28"
-  "\x33\x35\xa6\xa3\xc2\xef\x34\xe9\x50\x1a\x53\x90\xde\x46\x7d\x4f"
-  "\xf3\xf5\xdc\x87\x1c\x95\x75\x01\xee\xb8\x44\x32\xe4\xb1\xdc\x91"
-  "\x3c\x9e\x1f\x77\xa4\x87\xe3\x79\x47\x4e\x38\x9e\x77\xe4\x8d\xe7"
-  "\xc7\x1d\x9b\x23\xf2\x54\x44\xe4\xa9\x0d\xc9\xd3\x21\x95\x63\x8d"
-  "\xc8\xd3\x11\x91\xa7\x73\xbc\x7c\xde\xd1\x15\x91\xe7\x6c\x44\x9e"
-  "\x81\x20\x0f\xef\xe0\x7b\x3a\xa8\x3d\x60\x38\x7e\xdf\x7d\xa3\x7d"
-  "\x18\x5a\x59\x9e\xe5\xfd\x18\x42\xae\xef\xdc\xdf\x2c\xf6\x25\x70"
-  "\x9f\x1f\x03\x70\xa7\xf0\x0b\x89\xf8\xbc\x33\xe2\x8d\xa3\x3e\x17"
-  "\x79\xeb\x3c\x6d\xf4\xa2\x8d\x79\x67\xb1\x03\xb2\x2a\xe4\xb5\x4f"
-  "\x5a\x2f\xe6\x3e\xa2\xf8\xf8\xe2\xce\x5c\xd1\xfe\xee\x6c\x96\xe6"
-  "\x64\x89\x1e\x1c\x37\xdc\xd9\xfc\xbf\x86\xd7\x5d\x8b\x09\x2f\xf2"
-  "\x99\x82\x30\xfa\xc7\xc6\x0e\x63\xb8\x52\x99\x77\x3d\x20\xe3\xda"
-  "\x2e\xd6\xac\xc9\x3f\x8f\x8b\xfc\xd7\x78\x2c\x77\x25\x84\x8c\x37"
-  "\x08\x57\xf7\x89\xbd\x5e\x75\x04\xce\x83\x02\xe7\xbb\x72\x85\x8e"
-  "\xba\x2b\x57\xd6\x27\x31\xe5\xcf\xba\x2d\xbe\x0f\x6d\x3e\x5a\xa7"
-  "\xeb\x6d\x45\xfb\x11\xc7\x4c\x84\xf7\x79\xb8\x4b\xd8\xb3\x95\x23"
-  "\x40\xef\xf6\xda\x25\x7c\x1d\x4f\xa2\xc5\x46\x7e\xca\xc9\x4e\xe9"
-  "\x32\x5c\x85\x21\x3e\xe6\x22\xdd\x78\xd7\xa5\xd3\xb5\x2e\xc2\xf5"
-  "\xa4\xbc\xbe\x8d\xb8\x70\x9c\x86\xac\xdb\xf8\x1a\x23\xcd\xcb\x9f"
-  "\x76\xe7\x50\x9a\x73\xc8\xdb\x0e\x99\x07\xe4\xf3\x1c\xd3\x36\xc7"
-  "\x1a\xfb\x84\xf2\x55\xe0\x90\xb9\x51\xc8\x4f\x46\x5a\x78\x7b\x88"
-  "\x43\x39\xcd\xc8\x09\x97\xb9\x8c\xbc\x70\x99\xcb\x28\x0c\x6f\x0f"
-  "\x4a\x6c\x0f\x19\x15\x11\x79\x6a\x23\xf2\x1c\x0e\xc9\x63\x95\xca"
-  "\xe9\x88\xc8\xd3\x19\x91\x27\x54\xff\x21\xcd\x19\x67\xc6\xc6\x91"
-  "\x5c\xdf\x67\x38\x42\xbe\x95\xcd\xbc\x9f\xca\x70\xcb\x61\xb4\xee"
-  "\x89\x76\x27\x5f\xcb\x17\xf0\xe6\x69\x23\x74\x14\xa6\x9f\x97\x16"
-  "\x8e\xc3\xbc\xec\x70\x1c\xe6\xad\x90\xbf\x1b\xc4\x38\xf8\xb7\x17"
-  "\x60\xde\x4b\x92\x9c\xb9\x35\xfb\xe1\x11\x8d\x6f\xdd\x46\xb2\xc3"
-  "\xa8\x7f\xe2\x7b\x2c\xf6\xa1\xed\x78\x0d\xb4\xb4\xb7\xe5\x42\x0d"
-  "\xa8\xc8\x8f\x92\x03\x32\xad\x38\x3e\xab\xc0\x34\x83\x68\x4f\xe5"
-  "\x23\x8c\x0d\x58\x7e\x0b\x96\x81\xbc\x9b\x77\x3c\x02\x87\x93\x11"
-  "\x38\x74\x87\x7c\x6b\xf1\xbb\x3f\x84\x6e\xad\x4a\xc7\xf7\x40\xa1"
-  "\xcd\x3c\xcf\x25\x87\xd3\x98\x1e\x69\x74\x9a\xb8\x1d\x90\x4b\xfb"
-  "\x5a\x92\xce\xc3\xbc\x4f\xc9\x0e\x16\x30\x33\x53\x42\x79\x2b\x78"
-  "\x91\x99\x15\x8e\x47\x66\x6e\x38\x1e\x99\x05\x41\x5d\x33\x6f\x83"
-  "\x68\x23\x99\x25\xa8\xa3\xf9\xda\x2f\xf2\x42\xaf\xf1\xe9\x6f\xb6"
-  "\xcd\x26\x9b\x34\xf3\x25\x37\xd2\xcb\x7e\xac\x4c\x92\xbe\xf9\x3d"
-  "\x34\x6c\x36\xcd\xff\x6f\xd3\xc5\x92\xd1\xa1\xa4\x6d\x5a\x69\x6f"
-  "\x92\x1e\x61\xdb\x64\x19\x0f\x34\x6d\xd3\x06\x1a\xef\xce\xc1\x30"
-  "\xd4\x7f\x77\x79\xc5\xd8\x63\xf1\x41\x94\xe7\x16\xac\x13\x1c\xa7"
-  "\xce\xff\x44\x1a\xd7\xa5\xd1\x7e\x15\xd4\x35\xe4\x7f\x2d\x41\xac"
-  "\x69\xce\x8f\x0f\x69\x2b\x6e\xfd\xde\xfb\xd9\x79\x98\xdf\x4b\xf6"
-  "\x1a\xe9\x02\xda\xf7\x72\xda\xe7\x02\x9a\x0b\xb1\xfb\x2e\x72\x9b"
-  "\x1a\xe3\x7b\xa4\xbc\x2b\x42\xf2\xba\xa4\xb9\x0a\x27\xc5\xcd\xf7"
-  "\x81\xfa\xb4\xdb\x45\x7e\xa6\x93\x85\x1d\x3e\xbf\xf7\x34\xea\x00"
-  "\xcc\x63\x94\xf3\xd0\xbc\x86\x34\x1e\x51\x67\xd6\xd2\xbd\x74\xe7"
-  "\x39\x6c\x10\xbe\xf8\x9c\x38\x9e\x19\xb4\xd7\x3a\xc1\xee\xee\xa7"
-  "\xf9\x45\xb5\xd8\x3f\x30\xbf\x47\xe5\x85\xf8\xa1\xc6\x6d\x28\x37"
-  "\xf3\x7b\xfc\x8d\xdb\x68\xfc\xaa\x47\x19\xe2\x7a\x2d\x94\x77\x2b"
-  "\x57\x16\xac\xcb\x5f\x33\xef\xf1\x75\xab\x36\xac\x5c\xa2\xdf\x50"
-  "\xfe\x7c\x69\xc9\xbc\xed\x3b\x6b\xf4\xbb\xab\xca\x6b\xca\x2b\x9f"
-  "\xe5\xae\xf1\xf4\x5b\x6a\xc4\x6f\x7a\xc5\x96\xea\x9a\x65\xf4\x9a"
-  "\xa1\x37\x54\x95\xee\xe2\xaf\x77\x4c\x86\x70\x20\xe5\x35\xa5\x55"
-  "\xfa\xb9\x25\x19\xfa\x87\xb6\x94\x57\xec\xac\x2a\x8d\x0a\x6b\x89"
-  "\xbe\xaa\xb4\xaa\x74\x4b\x89\x7e\x99\x3e\x8b\x20\x87\x82\x0b\xa9"
-  "\xcf\x2c\x59\xe7\x54\x63\x1f\x8d\x76\xb1\x93\x74\x0f\xf5\xd5\x17"
-  "\x60\xe1\x47\x64\x97\x71\x5f\x76\x28\x5b\xa8\xe7\x1d\x1e\x4b\x56"
-  "\xe7\xf8\xbe\x39\x2b\xa2\xff\xcb\x8a\xe8\xff\xb2\x06\xc6\xf7\xcd"
-  "\x59\xde\xf0\x3c\x0b\xe2\xc3\xf3\x2c\xd0\x8d\xef\x9b\x17\x64\x44"
-  "\xe4\x59\x1a\x91\x67\xf5\x98\xee\x40\x5c\x0f\x70\x5d\xb3\xa0\x38"
-  "\x22\x8f\x21\x22\x8f\x39\xe2\x3b\xd4\xfe\x41\x7b\x74\x41\x47\x68"
-  "\x7f\x8f\xdf\x9d\x72\xfb\x0d\xea\xac\x05\x5d\x72\x1a\xea\x4f\xda"
-  "\xe9\xce\x0c\x91\xf6\x5c\x48\x5a\xa7\x94\xd6\x35\xa6\xab\x8e\xf0"
-  "\x31\xb3\x53\xd8\xdc\x0b\xb7\x48\xfa\x8a\xee\xd0\x90\xfb\xc5\x01"
-  "\xac\x8b\x99\x97\x61\x01\xf9\xf0\xe7\xe3\x6b\x3e\x37\xfc\xfa\x26"
-  "\x4f\x7b\x12\xd0\xbd\x1b\x4e\xf2\xe5\xc6\x2c\xf3\xb9\xcf\x40\x0c"
-  "\x4b\xc0\x07\x75\xcf\xc2\x0d\x0e\xb5\x8e\xdf\x6d\x43\xeb\x91\x0e"
-  "\x58\xc8\x65\x99\xf2\x1d\xe4\xfb\x5f\x78\x79\xbd\x74\x17\x08\xf9"
-  "\x47\x24\x9d\x48\xe5\x92\x8f\x41\x2a\x1b\x61\xa8\x99\x32\x2b\x55"
-  "\xf2\x15\xa7\xc5\x27\x19\x61\x1e\x97\x61\x22\x3c\xae\x57\x0e\x48"
-  "\x7b\x3b\x85\x2d\xb3\xb0\x5b\xb6\x19\xc8\xfe\x8f\xa6\x3b\xa2\xef"
-  "\x07\x04\x4d\x83\x25\xd0\x6f\xab\x1b\x20\x9c\xbc\x64\x5b\xda\x75"
-  "\x3e\xe8\x6b\xf5\xe1\x98\x14\xb4\x7c\x8c\x64\xbc\x04\xf6\x0e\x1f"
-  "\x5f\x47\x29\x32\x82\xb9\x5d\x19\xe8\x67\x63\xf9\x68\xdc\xb5\x88"
-  "\xaf\x29\x1f\xa4\x70\xcc\x8f\xe3\x03\x17\xed\x1b\x8c\x75\x27\x0d"
-  "\xa5\xb3\xcd\xa6\x31\xdc\xa2\x32\xc9\x9e\x3d\xd4\x8e\xb0\xa2\xee"
-  "\x69\x53\x82\xdd\x63\x59\x74\xcc\x01\x4f\x58\x65\x3d\x7c\xba\x85"
-  "\xeb\x3e\x25\x86\x9f\x42\x5e\x0c\xc6\xb2\x3d\x24\x9d\x6d\xa0\xfd"
-  "\x18\x98\xd6\x79\xa3\xb4\x84\xf7\x69\xa4\x1b\xdb\xa2\xf9\x9d\xba"
-  "\xac\x38\x49\xbf\xe2\xb8\x3f\x5b\x2f\xe7\xfb\x3a\xf4\x49\xfb\x6e"
-  "\x5d\xd8\x56\xdd\x62\xfc\xb7\xf8\xb5\x57\xf9\x3e\xb9\x6c\x1c\xff"
-  "\x2c\x3a\x2c\xd1\x70\x13\x7e\xa3\xfe\x5b\xc4\xf7\xef\xd2\x9a\x38"
-  "\x8d\x93\xab\x0d\x68\x87\xe9\xdc\xa8\x1b\xb3\x9b\xe5\x38\x3e\x6f"
-  "\x4c\x71\xb5\xcc\x7b\x5a\x37\x40\x71\x9d\x63\x71\x94\x8f\xf0\x36"
-  "\xfa\x28\xbc\x5b\x0e\x17\x76\x40\x76\x7f\xc4\xb7\x53\xfe\xc6\x77"
-  "\xec\xff\x17\x6d\x96\xe0\xbb\x50\xe7\xd2\x3e\x04\xc5\x79\x58\xfc"
-  "\x68\x1b\x6f\x37\x8b\x93\xe5\x78\x3e\xf7\xf5\x36\x8e\xaf\x7d\x6e"
-  "\x08\x24\x65\x98\xb9\x1d\x85\x79\xe8\x6e\x19\x1c\x37\x28\xd8\x28"
-  "\xdf\x13\x31\x48\x70\xa8\xcd\xf0\xfb\x1d\xf0\x1b\x61\xd1\xfc\xbc"
-  "\x8b\x64\x64\xb7\x0f\x52\x0c\xf7\xd1\x1c\xf1\x62\x2e\xb7\x14\x46"
-  "\x70\x09\x9e\xc9\x27\x60\x13\x3c\xba\x03\x87\x0d\x95\x21\xae\x8b"
-  "\x89\xfe\xee\x58\x75\x85\xf1\x27\x42\x78\x19\x87\xdf\x5d\xe1\xb4"
-  "\x2e\x3e\x1b\xf1\x3d\x20\x7f\xd3\x7c\xac\x90\xbd\xc5\xfd\x22\xee"
-  "\x6e\xb8\x51\x59\x34\xa6\xc5\x34\x69\xe1\xe5\xdd\x9d\x1d\x0e\xff"
-  "\xee\x15\x11\xdf\x1b\xe4\xef\x66\xbe\x0e\x70\x77\x89\x5c\x86\x98"
-  "\x8f\xcb\x30\x1f\xab\x73\xc5\x7d\x3d\xf9\xb9\xe7\xd7\x42\x7e\xee"
-  "\x3e\x1e\x82\xc3\x04\xfc\x3e\x19\xac\xcf\xbb\xbb\x64\xf8\xf8\x7e"
-  "\x26\x24\x1d\xb6\x91\xbb\x1d\x91\xf2\x52\x6d\x24\x39\x23\x99\xb9"
-  "\xdb\x17\x25\xce\x2b\xe2\xee\xd1\x45\x97\xb3\x7b\xb2\x42\xc2\xa5"
-  "\x71\xc7\x3d\xb2\x5f\x7c\xd2\x91\x6e\xba\x63\x47\xf2\xf3\xcb\xe5"
-  "\x82\xfc\x7f\x4a\xf7\x7e\xa0\x6c\xdd\x63\x88\x84\x4b\x77\x35\x8c"
-  "\xc1\x08\xc2\x94\xc6\x17\xf7\x74\x04\x69\xbb\xe7\x7d\x07\x2c\xee"
-  "\x90\xe5\x56\xcc\xb9\xdd\xdd\x1a\xcb\x9e\xc7\xf4\xe7\xc2\x79\x76"
-  "\xcf\x60\x90\x67\xf7\x78\x83\x70\x73\xd4\x21\xe9\xfe\x15\xbf\x93"
-  "\x83\xe9\x72\xf4\x5f\x25\x1f\x62\xaf\x7f\x4e\x5e\x78\x59\x39\x85"
-  "\x21\x30\x4a\x42\xca\x32\x84\xa4\xeb\xc7\x6f\x73\xec\xfa\xc9\x69"
-  "\x8d\x5d\x3f\x39\x27\xa3\xd7\x4f\xce\x99\x90\x72\xcf\x7d\xb5\x6c"
-  "\xdf\x0b\x21\xf8\xb4\xe3\xb7\x36\x5c\x96\xef\xd5\x47\x7c\x8f\xd5"
-  "\x3f\xc3\xf6\x7b\x6c\x6f\x6e\x1c\x85\xd7\xcc\x02\xad\x90\xf5\x7b"
-  "\x0b\x42\xe3\x3f\x1c\x11\xf1\x84\x23\x5f\xab\xa2\x75\x40\x91\xce"
-  "\x18\x99\x8e\xd2\x84\xc4\xb7\xc8\xb8\x1f\x8c\xe1\x93\x56\xee\x83"
-  "\xec\x01\xea\x83\xee\x3d\x21\xd6\x37\xe6\x9d\x60\x96\x8f\x0b\x63"
-  "\xf5\x27\x08\x17\xfb\xff\x7b\x8f\x0b\xfe\xdc\x8b\xf2\xff\x08\x5f"
-  "\x4f\x65\xd6\x79\x27\x50\x9e\x46\x2e\xc0\x12\xda\x13\x36\x8a\xbf"
-  "\x7b\xc2\xfb\xb8\x25\xc9\xcc\xa2\x58\xdf\x6e\x89\xec\xfb\x96\x64"
-  "\xa0\x4d\x3f\xa2\xf1\x99\x0b\xa3\xc4\xe5\x31\x8b\x6a\x5d\x94\xf0"
-  "\x62\xac\xaf\x11\x07\x2c\x69\x26\x7c\x43\xc2\x8d\xcc\x32\x75\x03"
-  "\xa5\x77\x50\x79\x98\x27\x56\xbd\xc9\xfb\xdf\x85\xec\x2d\xe9\x8a"
-  "\xa0\xe3\xfa\x05\xf8\xc1\x03\x82\x8e\x1f\x1c\x8d\x28\xfb\x5c\x0c"
-  "\x3a\x68\x9c\x76\x3d\x3a\x1d\x3f\xd0\x72\xde\x2a\x91\x96\x71\x7d"
-  "\xff\x0f\x32\x90\x96\xeb\x9c\xef\xe1\xe1\x2b\xe4\xf1\x9f\xe9\x3a"
-  "\x8e\xab\x95\xc0\xf3\xae\xaf\x0d\xd6\x9b\x94\xae\x42\xd3\x02\x05"
-  "\x51\xca\x3c\xc8\x2c\x13\xd7\x3b\xe0\x07\xa7\xe4\x3e\x43\x0a\x6f"
-  "\x15\xb8\x20\x9f\x94\x9c\x4f\xe7\x28\x5f\xac\xfa\x96\xdb\xa7\x58"
-  "\x93\xf9\x01\xb6\xff\x25\xb2\xfe\x70\x63\x9f\xea\x92\xf9\xe8\xb1"
-  "\x2c\x8d\x8f\x88\xf3\x86\xc4\xa5\x85\xc5\xed\x1b\x0b\x5f\x2a\x87"
-  "\x7f\xbd\x7a\x5a\x5a\x11\x51\x4f\x58\x3f\x4b\xfd\xe1\x74\x2f\xad"
-  "\x15\xf4\x61\x1d\x8d\xe3\xf5\xd2\x16\xac\xa3\xd1\xe8\x75\xb4\xf4"
-  "\x44\x74\x59\x5b\x2a\x6c\xcf\x24\x88\x06\xcf\x89\x75\x37\xca\x65"
-  "\x50\xaa\xa7\xf1\xf5\xb3\x2c\x41\xae\x9f\xaf\x47\xe3\xb2\x82\x08"
-  "\x1a\xfd\x08\xa3\x57\xd0\x7a\x5f\x6a\x04\xec\xb2\xe8\xb2\xb8\xcc"
-  "\x8c\x74\xfa\xa3\xd3\xb9\xac\x35\xb6\x2c\x2e\xa3\xfb\x73\xfc\xe3"
-  "\x65\x71\x99\x7c\x67\x74\xb4\x3c\x83\xcc\x12\xad\x9c\xfb\xd4\x64"
-  "\x9b\x38\xe0\xbe\xa5\xb4\xce\x15\x12\x9e\x12\x2e\x7f\xcb\xca\x78"
-  "\x3e\xe2\x9f\x4f\x8c\x25\xa8\x1e\x2e\xe8\x41\xf9\x55\x32\xe9\xb1"
-  "\xdc\x57\x1b\xc1\xab\x2b\x08\xdf\x3f\xa4\x54\x3e\x24\xf8\x75\xff"
-  "\x27\x11\x38\xb5\x44\xe7\xd7\x7d\x9d\xc8\xaf\x2b\xd1\xf9\x75\x5f"
-  "\x4f\x6c\x7e\xdd\x47\xf5\x7f\x65\x3c\xbf\xee\x87\x50\x7e\xd1\xdd"
-  "\x80\x44\xdf\x1c\x1d\xca\xc6\x68\x11\x6b\x17\xba\x5c\xab\x41\x59"
-  "\x11\x79\x06\x29\x4f\xb6\xc6\x2b\xe4\x44\x3f\x0d\xe2\x2f\xc3\xfd"
-  "\x29\x72\xfb\x9f\xda\x02\x13\xd9\xe8\x26\x46\xf7\xfa\x50\x3e\xbb"
-  "\xf1\x8a\x8d\xee\x24\xa3\x79\xbc\x88\x72\x8d\xd1\x75\xc1\xfd\x56"
-  "\xe4\x69\x53\x94\xf0\xe3\x62\x2e\xf2\x7e\x47\xb8\x8e\xb8\xdf\x16"
-  "\x5e\x47\xc8\x37\x25\xf7\xaa\xab\xf8\x3a\xcf\x8d\xeb\x2c\x37\x6b"
-  "\x7c\x9d\xe5\xfe\x49\xd4\x57\xee\x47\xe1\xf8\xe5\xe6\x45\xaf\xaf"
-  "\xdc\xe2\xd8\xf5\x95\x5b\x1b\xbb\xbe\x72\x69\xfd\xf8\x8a\x03\x72"
-  "\xcf\x84\xf7\x1b\xb9\x9d\xe1\xf4\x62\xb9\x98\x8f\x29\x27\xdc\x4c"
-  "\xdf\x5f\x97\x6e\xf9\x21\x1d\x47\x75\xd5\x8e\xf6\x15\xe2\x3f\x8b"
-  "\x70\xfc\xa6\x30\x62\xc2\x46\x1e\x5a\xf7\xc6\xf4\x5f\x9f\xd0\xd7"
-  "\x42\xf7\x9d\xf3\xbb\x22\x15\x17\xe0\x81\x77\x03\x4a\xc5\x12\x7c"
-  "\x57\x5e\x80\xe5\x3b\x02\x4a\x95\x99\xce\x93\xf0\x73\x24\x7c\xde"
-  "\xff\x81\x53\xa1\x75\x41\xfb\x87\x69\x8e\xb7\x5e\xcc\x1f\xfe\xf5"
-  "\x02\x3c\xb8\x52\xd4\xcb\xf2\x47\xc2\xf9\xf8\x80\x23\x7a\xbd\x3c"
-  "\xe0\xc5\x7a\xf9\x6b\xf4\x7a\x79\x30\x39\x76\xbd\x3c\x48\x67\xcf"
-  "\xfe\x3a\xbe\x1d\x3d\x98\x27\xb5\xa3\x03\x94\x47\x5f\x49\xf6\xea"
-  "\x83\xff\x17\xa5\xc1\x77\x6c\x23\x0f\xbe\x4d\xf1\xf3\x06\xe5\x76"
-  "\xc4\xf3\xd4\x22\x2c\x5e\xbe\x94\xc6\x28\xc1\x08\x85\xdb\xa1\x19"
-  "\x8c\xd6\x4e\x1e\xe4\x77\x22\x67\x1a\x20\x1e\x79\x58\x78\x94\x60"
-  "\x54\x01\x5c\x86\xe5\x53\x28\x1d\x85\x93\x2f\xf0\x90\xf4\x4e\x39"
-  "\x1d\xe9\x3a\x91\xf6\x41\x07\xdd\x5f\x4b\xe9\xc2\x61\x2f\x97\xe8"
-  "\x9f\xc8\xfb\x11\x4a\xcf\xef\xcb\x0d\x4f\x93\x23\xda\xe3\xf2\xda"
-  "\xf0\xf6\xb8\xbc\x20\x5c\x3e\x91\xff\x98\x2f\x80\x7a\x0e\xdf\x8f"
-  "\xf9\x2d\x8a\x25\xdf\x4e\xdb\x5c\xde\x13\xd1\x36\x51\x06\x56\x3c"
-  "\x2f\x64\x60\xc5\x9a\x08\x5c\x07\xa2\xcb\xc0\x72\x5f\x6c\x19\x58"
-  "\xa1\x8b\x2d\x03\x2b\xb2\x49\x06\x1c\xb0\xa2\x22\xbc\x6d\xae\x58"
-  "\x1d\x4e\x3b\x96\xcb\xdb\x26\x24\x7e\x93\xb6\x89\xb6\xd0\xcd\xb1"
-  "\xda\xa1\x64\xff\x2b\xe8\x3e\x9f\x6f\xc0\x33\x71\x3f\x05\xac\x04"
-  "\x5a\x9b\x41\x1d\x5f\x46\x3c\x6c\xe3\x63\xb4\x95\xc9\xa1\x7c\xac"
-  "\x17\x63\x2d\x13\xa6\x7d\x83\xf6\xb6\x09\x7e\x3e\xb4\x25\x9c\xfe"
-  "\x95\xd9\xd1\xf9\xb9\x72\x35\xf2\xd3\x14\x9d\x9f\x2b\xcb\x62\xf3"
-  "\x73\xe5\x41\x3a\xa3\x38\xbe\x4d\xad\xa4\x3b\xc9\xe2\xe5\xbe\xe9"
-  "\x32\xac\xbc\xf6\xf5\xfa\xa7\x95\x67\xc3\xfb\xa7\x95\xa7\xbe\x79"
-  "\xff\xf4\x90\x2e\x7a\xff\xf4\x50\x56\xf4\xfe\xe9\xa1\x3c\xd1\x1e"
-  "\x1e\x32\x87\xb7\x87\x87\x8a\xc3\x65\x02\x79\xf7\xad\xf5\x4f\x0f"
-  "\x9d\x89\x68\x03\x0d\x17\xe0\xe1\x47\xd0\xa6\x78\x51\xd4\x5b\xde"
-  "\x2d\x11\x38\x0e\x46\xaf\xb7\x87\xd5\x58\x6f\x0d\xd1\xeb\xed\x61"
-  "\x7d\xec\x7a\x7b\x78\x29\xd6\x5b\xc3\xf8\x7a\x7b\x78\xc3\x37\xb7"
-  "\x29\x1e\x3e\x14\x5e\x67\x0f\x1b\xbe\x79\x9d\x3d\xdc\x13\xbd\xce"
-  "\x1e\x1e\x88\x5e\x67\x0f\x4b\x67\xfe\xf3\xb2\xc3\xeb\x2c\x2f\x39"
-  "\xbc\xce\x90\x6f\xdf\x5a\x9d\xe5\x1d\x8c\xa8\xb3\xed\x17\x60\x15"
-  "\x8e\x9b\x95\x67\x44\x9d\xad\xfa\x7d\x38\x8e\x79\x1d\xd1\xeb\x2c"
-  "\xef\x24\xd6\xd9\xf6\xe8\x75\x96\x77\x36\x76\x9d\xe5\xb9\xb0\xce"
-  "\xb6\x8f\xaf\xb3\x55\xf1\xdf\xbc\xce\x56\x2d\x0d\xaf\xb3\x55\x69"
-  "\xdf\xbc\xce\x56\x99\xa3\xd7\xd9\xaa\x96\xe8\x75\xb6\xaa\x53\xd4"
-  "\xd9\x2a\x67\x78\x9d\xad\xea\x0e\xaf\x33\xe4\xdb\x7f\xb0\xce\xb0"
-  "\x7e\x4e\x8a\x7d\xad\x3f\x5c\x35\xc4\xe7\x95\x7f\x98\xeb\x80\x1f"
-  "\xc5\x8b\x79\xf9\x1f\x72\xd9\x91\xea\xf0\x43\x4c\x93\x3d\xbe\xef"
-  "\xfe\xe1\x66\x29\xec\xf1\xf1\xf5\xf0\x43\x23\xf6\xab\x83\x5d\xb5"
-  "\x7c\xbf\x94\xa8\x43\xe2\x39\xa6\x13\x73\x64\x3f\xe4\xf7\x1b\x61"
-  "\x1d\x33\xbb\xd7\x07\xd4\x17\x63\x7a\x37\xc1\xa1\xf3\xf4\x11\xb0"
-  "\xba\xbe\x89\x5d\x16\x7b\x2f\xf6\xbc\x93\xb6\xba\x85\x08\xef\x47"
-  "\xff\x2e\x64\xf5\x47\x91\xf6\x6f\x3b\xc6\x7d\x20\xe4\x74\x4d\xc4"
-  "\x9c\xc9\x8f\x62\xd8\xbf\x3f\x22\xfb\xb7\x3d\xba\x9c\xfe\xe8\x06"
-  "\xf6\xef\x8f\xc8\xfe\x6d\x0f\x19\xaf\x26\x3d\xe5\x73\x44\x8c\x57"
-  "\x7f\x74\x4a\xe3\x16\xb2\xc3\xed\xd8\xc6\x79\x27\x11\xe7\x81\x08"
-  "\x9c\xb1\x6e\x56\x6f\x91\x70\xde\x18\x91\xdf\x17\x1d\xe7\xd5\xc9"
-  "\x88\xf3\x87\xd1\x71\x5e\x9d\x15\x1b\xe7\xd5\xab\x11\xe7\x0f\xc7"
-  "\xb7\xad\xd5\x25\x92\x1c\x44\x19\x97\xaf\x36\x47\xaf\xff\xd5\x11"
-  "\xf5\x0f\x85\x35\xb5\xcc\xc5\xf3\x87\xa7\xb3\x85\xa6\xa3\x3d\xed"
-  "\x94\x96\x64\x24\x4a\xda\xc1\x48\x98\xd1\xd3\xad\x49\x1e\x27\x7b"
-  "\xb4\x07\x3f\xaa\xec\xad\xc9\x15\xed\x71\x4d\x4b\x78\x7b\x5c\x53"
-  "\x18\xde\x1e\x7f\xe4\x8b\xc8\x67\x8c\x88\xcf\xfb\xf6\x74\xec\x1a"
-  "\x67\x84\x0c\x7c\x7c\x01\xd6\x96\x0a\x19\x58\xfb\xeb\x70\x3c\xd6"
-  "\x42\x74\x19\x58\xab\x43\xfa\x3f\x8e\x2e\x03\x6b\xb3\x63\xcb\xc0"
-  "\xda\x02\xe4\xe5\xc7\xa1\x72\xbb\xbe\x36\x77\x62\x44\x9a\x9a\xe8"
-  "\x3a\x6f\xed\xe1\xe8\xf3\x3a\x6b\x8f\x09\x1e\xaf\x3d\x17\xce\xe3"
-  "\xb5\xa7\xc2\x79\xb8\x16\xbe\x05\x1e\x8e\xf9\xa3\xf1\x58\xf2\x23"
-  "\xdb\xbf\xfd\x02\xe4\x4b\xed\xbf\xe0\xdd\x70\x1c\xf3\xa5\xf1\x4f"
-  "\xb4\xb9\xac\xfc\x12\xe4\xa5\x3d\x3a\x2f\xf3\xcd\xd1\x69\xce\x6f"
-  "\xc1\x3e\xc8\x1e\x18\xd7\x96\xf2\x3b\x31\x7c\x3d\xbf\x63\xec\x3a"
-  "\x68\xdb\x30\x7c\xbd\x0f\xe2\x79\x7f\x35\xd6\x2f\xe5\x9f\xa5\x39"
-  "\x72\x3e\xc7\x8c\xf2\xab\x49\x81\x02\xea\x83\x08\xaf\xa2\xda\xc8"
-  "\x75\x49\xee\xca\x80\x9f\x39\xa5\xf3\x27\x1a\x23\x14\xd8\xdd\x3e"
-  "\x90\xe5\x9d\xd2\x87\xc3\x2e\xc8\xa2\x76\x41\xe9\xe5\xb4\x62\xae"
-  "\xd3\x1c\xa1\x9b\x0a\x0a\xa3\xd7\x71\x81\x21\xb6\xec\x14\x1c\x16"
-  "\xf5\x5c\x60\x0b\xaf\xe7\x82\x63\x01\xcb\xd4\x0d\x44\xab\x03\xf9"
-  "\xfc\x4d\xea\x98\xd6\x2f\x63\xea\xfb\x03\x9b\xfa\x0d\x75\x30\xe3"
-  "\x22\x3c\x92\xce\xcb\x53\x32\x1c\x13\x2b\xa0\x8b\xeb\x80\x47\xf6"
-  "\x71\x3c\x31\x4d\x91\x0f\x94\xec\xc0\xb6\x7e\x8a\x6b\xb7\x30\x2f"
-  "\xbf\x43\xcd\xc2\xce\x90\x3f\x0a\x94\x85\x9b\xcf\xc3\x23\x0f\x84"
-  "\xe5\x57\x03\xd8\x05\x8c\x5a\x31\xbf\xff\x88\x51\x9e\x87\x8f\x35"
-  "\xbf\x8f\x69\x5a\xe5\xfd\xb4\x62\x2d\xec\x11\x6b\xcc\x7e\x19\x71"
-  "\xa2\x73\x98\x84\xd3\x8d\xf5\xc0\x23\x2e\x59\x7e\xc5\x19\x9d\x75"
-  "\x10\x3c\x03\xb2\x2e\x01\xe3\x4e\xdc\x60\x3e\x37\xa4\x1d\xac\xcb"
-  "\x09\x85\x23\x7c\x32\xad\x5b\x2d\x9f\xe3\xc0\xf7\xc2\xaf\x80\x25"
-  "\xe1\xb3\xce\x1c\x81\x8f\x15\x6d\xcb\x13\x12\x8c\xd6\xaf\x80\x91"
-  "\x6c\x3f\xb6\x04\x32\x03\xa0\xba\x08\x1b\xbe\x68\xa6\x7d\x32\xad"
-  "\x4e\x48\xf0\x81\x5a\x8c\xed\xd6\x7d\xd9\xab\xa3\x39\x1c\x3a\x9f"
-  "\x7b\xbf\x8d\xd6\xe0\xf8\x3a\xbe\xee\x7e\x5b\xaf\xd1\x2f\xf9\xde"
-  "\x59\xcf\x65\xa2\xb7\xec\x8a\xad\xf5\x08\x73\x1e\xe5\x67\xd5\xd6"
-  "\x87\x8d\xff\x0e\xd3\x1e\x1c\xda\x0b\x51\x07\xf7\x63\xfa\x37\x44"
-  "\x5b\xdf\x10\x61\x93\xae\x8f\x31\xfe\x5b\x4f\xe3\xbf\xfb\xa3\xb7"
-  "\xf3\xf5\x37\x18\xff\xad\xa7\xf1\xdf\xfd\xa1\xfd\xa6\x58\xe7\x59"
-  "\xdf\x1a\x6a\x93\x92\x5f\x14\xfd\x33\x64\x67\x6e\x48\xbc\xab\x19"
-  "\xb4\x3e\x5a\x57\xc6\xb6\x69\x77\x76\x51\x7b\xd5\xf6\xba\x4e\xd2"
-  "\x99\xe6\x78\xba\xfb\x55\xf4\x65\xd4\x5e\xd7\x3b\x78\x5f\xe6\x13"
-  "\x6d\xd1\x64\x64\xae\x8c\x01\x94\xa1\xed\x65\x12\xac\xf5\x3d\xfb"
-  "\xca\x18\xdf\x0b\x31\x75\x00\x26\xda\x9d\xbc\x5f\x54\x90\xbd\xca"
-  "\xed\x56\xdf\x35\x20\xb8\xa7\x6b\x7b\x81\xe0\x06\xc6\xfa\x49\x82"
-  "\xbd\x61\x29\xb5\x71\x82\x49\xb0\xfb\x30\x1d\xc1\xa5\x74\x32\x1d"
-  "\xe2\x1c\xc9\x86\x92\x50\xda\xf9\xfc\x0b\x96\x8d\xe1\x6f\xd3\xbc"
-  "\x8a\x9d\xf2\x99\x36\xb1\xcc\x01\x5a\x33\xbb\x62\x63\xa6\x6d\x2c"
-  "\xb3\x8a\xe6\xc4\x36\x7c\x49\xf9\x3e\xfc\x1f\x8e\xb8\x9a\x59\x10"
-  "\x2f\x85\xbd\xdf\xa5\xf7\xa2\x1c\x6f\x70\x85\xeb\x88\x0d\x11\xf6"
-  "\xef\x7a\x3e\xce\x74\xc0\x3a\xf2\x0d\x00\xd2\xbe\x50\xd2\x07\xcc"
-  "\xee\xf3\x70\xf9\xb8\xd1\xbe\x06\x5a\x93\xa6\x7d\x49\xc2\xef\xcf"
-  "\xa3\x39\x11\x73\x6f\xae\x7a\xbe\xb7\xe5\x2f\x58\xee\xa3\xbf\x13"
-  "\x32\xf2\xd8\xef\xc2\xeb\xf4\xd1\x42\xd3\x25\x5a\x0b\x12\xfd\xc1"
-  "\x53\xbe\x48\xfd\xf8\xa8\x51\xb6\xdd\x22\xc2\xad\x72\x7f\xa0\xaf"
-  "\xe4\x70\x23\xfa\x99\x47\xb9\xfd\xef\x1f\xd7\x2f\x3c\xda\x8d\xf4"
-  "\x85\xc9\x64\x1f\x97\xa1\x47\x1d\xbd\x6e\x94\x9b\x2a\x92\xff\xc7"
-  "\x36\x62\x9a\xfd\x74\x36\x0f\xbf\x27\x5e\x86\xc7\xb4\x7e\x0b\xc4"
-  "\xf7\xba\xf8\xd9\x23\x2d\xca\x08\x97\x5b\xea\x37\xe6\x8b\x3d\x41"
-  "\xee\xf0\x32\x1e\xcb\x90\x79\x4e\x69\xfa\xaa\xfe\x02\x62\x4f\x03"
-  "\xc9\xc2\x63\x40\xfb\x23\xa6\x0e\xc2\x44\x82\x25\xcb\x90\xdd\xd7"
-  "\x0f\x7d\xbe\xc8\x31\xcf\x63\x35\xd1\x69\x7f\x8c\xfa\xff\x26\x07"
-  "\x3c\x36\x10\x5e\xb7\x8f\xf1\xfe\x5f\x5e\xd7\x71\x20\x0f\x22\xf2"
-  "\x75\x85\xd7\xfd\xa3\x85\x14\x1f\x73\x9f\x8d\x75\xde\x29\x1c\xcf"
-  "\x14\xb9\xf9\x9e\xab\xc7\xb1\xfd\x3f\x9a\x7c\x23\x3d\xc8\xb4\xf3"
-  "\x4e\x05\x30\xad\xb4\xdf\x16\xf5\xd6\xe3\x79\x61\x73\x46\xb7\xf2"
-  "\x39\xa3\xa2\x0b\xf0\xb8\xb4\xf6\x53\xf8\x4a\x38\x7e\x8f\x97\xc4"
-  "\xb6\x0d\x1e\xa7\xf5\x9f\xa2\xe8\x3a\xe3\xf1\xd6\xe8\xb6\xc1\xe3"
-  "\x27\x24\xbd\x50\xc4\x12\x23\xe5\xe0\xf1\x33\x58\xc7\x3c\x8f\x3c"
-  "\x86\xa5\xb9\xd0\xd8\x63\xd8\x42\x18\x1b\xc3\x56\x91\x3e\x78\xdc"
-  "\x39\x36\x86\x75\x45\x1b\xc3\x3a\xa2\xd4\x67\xe1\x8a\xe8\xf5\x59"
-  "\xb8\x39\xfa\x18\xb6\xb0\x46\xf4\xf3\x85\xc7\xc3\xeb\xb9\xf0\x70"
-  "\x70\x4d\xf8\xf1\x92\x6f\xcf\x1e\x2e\xf4\x8e\xb7\x87\x37\xee\x14"
-  "\x75\xb5\xf1\x1f\xc3\x71\xdb\xa8\x8d\xae\xdb\x37\xa6\xc7\xb6\x87"
-  "\x37\xae\x88\xad\xdb\x37\x16\x8f\xb7\x87\xf5\x13\x22\xd2\x1c\x1c"
-  "\xb3\x95\xc2\x6c\xb3\x8d\xad\x82\x4f\x1b\xc9\x9e\x53\x85\xa4\x3f"
-  "\x11\x2e\xef\x1b\xa9\xbd\x69\x50\xb7\x5d\x24\x9d\x26\xcb\x4c\x2c"
-  "\x9e\x90\x0f\x93\x39\xcd\x30\x09\xdb\xc0\xc7\x1e\xcb\x13\x63\xf2"
-  "\x4f\x7b\xe9\xa8\x1c\xd2\x91\x31\xf7\xb4\x29\x65\xfc\x08\x8f\x27"
-  "\x96\xde\x68\xbd\x54\xa5\x83\x82\x57\xc7\xf1\xe3\x09\x6e\xff\x11"
-  "\x8c\x1b\xd7\xd9\x13\xef\x47\xb4\x31\xb7\xd8\x0b\xbb\x69\x8f\xa8"
-  "\xb7\x4d\x11\x63\xd9\x27\xba\xf9\xb9\xb8\x98\xfa\xf6\x09\x67\x74"
-  "\x19\xdd\x34\xc6\x2f\x94\x7f\x82\x7b\x6f\x44\xbc\x5e\xd4\xc1\x26"
-  "\x63\x20\x31\x74\xae\x7b\x53\x4e\xb8\x4e\xda\xa4\x8f\xc8\x17\x31"
-  "\xfe\x7b\xa2\x9b\xe2\xbf\x5e\x7f\xb3\xe9\x78\xec\xfe\x66\xf3\x62"
-  "\x41\xff\x93\x11\xeb\xcb\x9b\xba\x6f\xdc\xdf\x6c\x8a\x41\xff\x66"
-  "\x08\xef\x6f\x36\x47\xac\xd1\x6f\xd6\x47\xef\x6f\x36\xe7\xc8\x7a"
-  "\x46\xe8\x8d\xcd\x8d\x5f\x4f\xdf\x6c\x36\x84\xeb\x9b\xcd\x85\x5f"
-  "\xa5\x6f\x4e\x8f\xd3\x37\x9b\x4f\x68\x5a\xa3\xd2\xd2\x13\x5d\xdf"
-  "\x6c\x1e\x10\x75\xf8\xe4\xd2\x70\x7d\xb3\xd9\x17\x5e\x87\x9b\x23"
-  "\xea\xf0\xc9\x88\xf5\xef\x4d\xdd\xff\xab\x3a\x49\xa5\x52\x29\x55"
-  "\x0a\xa5\x42\x05\x74\xd1\x89\x02\x26\xaa\xd4\xaa\x38\x7c\x26\x48"
-  "\xbf\x13\x95\x2a\xa5\x1a\x9f\x38\xe9\x77\x42\xc4\xf7\x44\xca\x8b"
-  "\x8f\x5a\xfa\x8d\x8b\xf8\x9e\xf0\x15\xf1\x13\xa5\x72\xe5\xf2\xd5"
-  "\x11\xdf\x71\x5f\x11\x3f\xe1\x3f\x98\x1f\xc6\x7d\x87\x9f\x2f\x5c"
-  "\x55\xb9\x6b\x4b\x45\x79\x09\xdf\x5b\x5e\xaa\xdf\xb2\x75\x6b\x69"
-  "\x75\xb5\xbe\x66\xbb\xfe\xc1\x07\xd6\x2d\x5c\xa2\x17\x5b\xd4\x2b"
-  "\x96\xcd\x2d\x99\x0c\x6b\x76\x57\x51\xc4\x9a\xf5\xab\x0a\xf5\x05"
-  "\x0f\x3e\x10\x1e\x29\x83\xe1\x5b\xd1\x6f\x04\x25\xf4\x6e\xec\x97"
-  "\x6e\x05\x38\x7c\x2b\xd7\x3b\x03\xbd\x1d\x00\x62\x3c\xb1\xf5\xa5"
-  "\x1e\xb4\x3a\xd8\x88\x89\xd1\x79\x85\xf3\x50\xb4\x8c\x88\x98\xd7"
-  "\x61\x06\xc3\x33\xe4\x5f\xa4\x68\x23\xfb\x8d\x0b\xf4\x3f\x04\xe5"
-  "\x79\x28\x7b\xa3\x0b\x47\xff\xf4\x6d\x1f\xf0\x81\xde\x44\xb6\xed"
-  "\xd6\x7b\x31\x4e\xc1\xee\x0b\x60\x98\x5b\x3a\xc7\xfe\xf4\x2a\x1e"
-  "\xf6\x1b\xb3\x9c\x4e\x73\x01\x8a\xfc\xec\x37\x8c\x7f\xb3\xfb\xac"
-  "\x52\xba\xa2\x3f\x05\x2c\x4f\x59\x49\x2f\xb4\x8a\xfb\xb3\xe1\x8d"
-  "\x24\x88\x7f\xe3\x56\xf2\xb5\x58\xd4\x25\xef\x8d\x7e\x09\xbf\x1d"
-  "\x50\xd6\x42\x65\x53\xda\x80\xf2\xa9\x7f\xe1\xe9\x93\xc2\xd2\xbb"
-  "\x83\x7b\xa9\x8b\xba\xe8\xae\xf9\xfc\xbf\x61\x97\x9f\x34\xc7\x65"
-  "\xaf\x35\x83\xc6\xcf\xbe\xcc\xcc\x03\x45\xdf\x41\x80\x3d\x3e\xe6"
-  "\xb3\x55\x5d\xc4\xf2\x8b\x1f\xd0\xec\x61\x5f\xda\xd1\x6e\x5c\x33"
-  "\x68\x62\xf5\x97\x40\x8d\x6d\x5a\x61\xab\xa2\x33\x0d\xc5\xe9\x6d"
-  "\xd7\x41\x8d\x3c\x48\xb9\x08\x5b\x0a\x6b\xd7\x30\xbf\x69\x0d\xa8"
-  "\xff\x60\xa4\xb3\xa4\xf3\x27\xd7\xff\x1b\xa8\x7f\x39\x62\x56\x8e"
-  "\x30\x1d\xd4\xd6\x30\x27\x23\x1f\xac\x6e\xe6\xa5\x7d\xaf\x3d\xc5"
-  "\x7e\x4c\x93\x39\xe2\x31\xe9\xa0\xaf\xc6\x0d\xfb\xce\x31\xef\xa1"
-  "\x7f\x13\xbe\x1d\x7a\x07\xdd\x74\x36\x35\x7e\xdf\x1a\x50\x5d\x28"
-  "\x04\x65\x6f\x59\x0b\xd8\x37\xbb\xa1\xf6\x1c\x73\xf6\x14\xff\x0d"
-  "\xfa\xca\x3a\xa1\xa8\x1f\x94\x3d\x03\x9f\x02\xf7\x23\xda\x74\xc4"
-  "\x51\x77\x0d\x74\xfb\xca\x29\xec\x1a\xec\xdd\x07\x53\xf6\xfe\x99"
-  "\xc6\x42\xfd\x58\xce\x25\x78\xe2\x2c\x28\x10\x9e\xf2\x85\x4f\x41"
-  "\xf7\xc2\x46\x3a\xab\x9d\x0b\xad\x75\xa0\x63\xa6\xf4\x84\x11\x53"
-  "\xba\x76\x84\xa5\x27\x79\x4c\xe9\xc9\x7d\x06\x4c\x3f\xf0\x6b\x98"
-  "\xda\x0f\xc9\xbf\xb9\xd8\xaf\x6c\xb9\x0a\x29\xfa\xb5\x54\xff\x5b"
-  "\x36\xb4\x5e\xc5\xf4\x4d\x15\xc5\x01\xcc\x1b\x9a\xc7\x97\x58\x61"
-  "\xb4\x17\x7a\x21\x80\xb0\x5a\x46\x20\xa5\x75\x04\x74\x81\xc6\x8a"
-  "\x62\xe2\xc5\x68\xd3\x5d\x2e\xd4\x83\x13\x3f\x7c\xfa\xa4\xda\xde"
-  "\x33\x08\xbd\xee\x11\xe8\x83\xbf\x80\xdd\xf8\xb9\xed\x97\x4f\x9f"
-  "\x8c\x43\x3b\x52\x61\xdb\x4b\xfb\xcf\x85\xcc\x98\x7a\xc9\x07\x95"
-  "\x19\x1a\xea\x20\xc1\xb0\x17\x26\x5e\xc4\x70\xae\x73\xac\x33\x90"
-  "\x67\x9f\xdb\xf6\xf2\xf3\xd5\x65\x2d\x75\xbd\xa0\xea\x73\xb7\xd0"
-  "\x39\x5e\xa5\x3f\xe9\x88\xc3\xee\x3e\x03\x76\xc3\x5f\x6d\x01\xed"
-  "\x91\xee\xc3\x01\x88\xff\x60\xf8\x8c\xd2\xae\x1e\x06\x7b\xa1\x1b"
-  "\x3e\xc6\xb2\x59\xd3\x11\x5a\xb3\xc9\xed\x73\x7b\xc9\x0f\x4d\x16"
-  "\x1b\xd2\x4d\x6e\xa8\x82\x8c\xb6\xab\x90\x76\xf4\x2a\xa4\x33\x4f"
-  "\xba\x92\xce\x4c\x3f\x79\x49\x0b\x47\xf1\x37\x01\xc7\x5e\x48\x2f"
-  "\x3f\x3b\xcd\x12\xa5\xb3\xd3\xa3\xe9\xd0\x3e\x12\x3c\x3b\x3d\x32"
-  "\x14\x3c\x3b\x8d\xb2\xd4\x4d\xe7\xa7\xb1\x5d\x98\x49\x9e\x1b\x2e"
-  "\x83\xfa\xc0\x65\x80\x4c\xb3\x12\xf4\x4f\x93\x4f\x8c\xad\xf3\xec"
-  "\x25\x97\xf8\xfb\x79\x78\x7a\x00\x7f\x13\xf0\xc1\xf1\xdb\xd3\xfc"
-  "\xbc\xef\x80\x24\xb7\x18\xa6\xc4\xb0\x5e\xfc\x55\xe1\xef\xef\x4c"
-  "\xad\xcc\x85\x65\x74\xa1\x6d\x32\x99\xe4\x57\x3a\xa7\xdd\xe5\xb1"
-  "\x3c\x7d\xca\x01\x2f\x1f\x96\xe5\x58\xe8\xf3\xa2\xee\x8f\x2f\x5c"
-  "\x22\xbf\xbe\x2e\x8e\xcf\x68\x99\x82\x7c\xfc\x4a\xe1\x84\xc3\x5c"
-  "\x2a\xf7\x3c\x6c\x8d\xc7\x5f\x0d\x3e\xd8\x2e\x9f\x6e\x95\xf3\x0e"
-  "\x8d\x96\x61\x99\x5b\x53\x31\x9c\xc9\xe1\x48\xaf\x9a\xe2\xfe\xe1"
-  "\xc2\x25\xa5\x48\x93\xae\x44\x98\x5e\x09\x3e\xb6\xf5\xa2\x0a\x6a"
-  "\xd3\x43\x4a\x0d\x3b\x5d\x92\x0d\xad\xb7\xb2\x33\x47\x8f\xb0\x2e"
-  "\xd1\xd6\xb6\x16\x3b\xe0\x30\xf7\xa9\x80\x7d\x76\xd7\x61\x8c\x3b"
-  "\x8d\xbd\x27\xf1\xa5\xab\x98\xf6\x93\x6e\x35\x3b\x60\xf2\xb9\x50"
-  "\x1a\x98\xe5\x49\x03\xf5\x9b\xbf\xaa\xb3\xc5\x31\xe5\x53\x86\x3e"
-  "\xc7\x20\xfc\x72\xc4\x19\x67\xfa\x3d\x28\xed\xbe\xf3\x30\x3f\x19"
-  "\x74\x34\x07\xd3\x7e\x84\x39\xf0\xd7\x89\xcf\x20\xca\x49\xea\x45"
-  "\xd8\xda\x7b\x57\x32\x24\xff\xd1\x08\x92\x3e\xda\xfa\xb7\x10\x7d"
-  "\xf4\x7c\xef\xc0\xc9\x10\x5d\x54\x96\x3a\x5e\x17\x3d\xfb\x3d\xa1"
-  "\x8b\x98\x4f\xe8\x1e\xbf\x43\x0a\x8f\x8b\x08\x97\xce\x8c\x3c\xf3"
-  "\x45\x44\xb8\x57\x0a\xff\x73\x44\xb8\x4b\x0a\xbf\x45\xd6\x75\x7d"
-  "\x84\xc7\x6e\xd2\x75\xa5\xd7\x49\xd7\xf5\x95\x48\xba\x8e\x9f\x71"
-  "\x2c\xfd\x94\xfd\xd4\x2c\xee\x75\x87\xd2\x7f\x24\xfc\xd9\x6f\x40"
-  "\xc6\x7d\x12\x86\xed\xa4\x30\xeb\x5f\x40\x8d\x0f\xd7\x73\xcc\xf2"
-  "\xd4\x7f\x27\x3d\x47\x3a\x8e\xce\xa2\xbc\x75\x2b\xeb\x7f\xeb\x08"
-  "\x3b\xdb\x7a\x84\xf5\x78\x2c\x25\x03\xb2\xbe\x7b\x19\xc3\x0e\x63"
-  "\xd8\xcb\x18\x4f\x7a\x8f\x78\xd2\x5b\x78\x92\xfc\x38\x0e\xa0\x8c"
-  "\xc5\x6b\x14\x60\xa8\x47\x99\x27\xff\x4f\x07\x91\xbf\x76\xd4\x49"
-  "\xb4\x27\x97\xfb\xc3\x55\x66\xa1\x8e\x1a\xa0\xf6\x76\xeb\x81\x00"
-  "\xcd\x4b\xfc\x0d\xea\xdc\xec\x22\x9d\x0f\x21\x1c\x8a\xf6\xfc\x90"
-  "\xfc\xbc\x2a\xba\xca\x00\xe8\x7c\x3f\x9d\x5f\x41\xbd\xab\xb6\x22"
-  "\x4e\xa7\x2b\xa8\xae\x4b\x2b\x1c\xf0\x4f\x15\xa2\xae\xcb\xb8\xff"
-  "\xe8\xf3\x50\xd2\xc9\x2c\xa8\x0b\x91\x36\x8d\xdf\x0c\xe4\xb3\x04"
-  "\xdb\x28\xcd\xb3\x96\xbd\x85\x8f\x55\xf6\x5b\x42\x3e\xc0\x31\x8d"
-  "\xbd\xdf\x0b\x84\xb3\x03\x4a\x7c\xbd\xb5\x27\x29\x7f\x07\xf1\x86"
-  "\x59\x4c\x32\x0c\x05\xf7\x7b\x82\x63\x78\xf2\x7b\xe2\x80\x52\x71"
-  "\xa6\x2e\xe9\x2e\x57\xef\x66\x17\x90\x9e\xb7\x3b\x11\x46\xed\x79"
-  "\x01\x03\x61\x31\xd4\xfb\x61\x71\x12\xfc\x29\xfb\xd8\x97\x08\xbf"
-  "\x82\xea\x8b\xfc\x54\xd1\xbe\x24\xe4\x4b\x02\xf9\x3c\x10\x76\x67"
-  "\xc9\xb5\xf6\xbf\x00\x48\xbe\xb6\x50\xde\x4a\xdc\xe4\xcb\x8a\xfc"
-  "\x6b\x71\xdf\x5a\xca\x6c\x60\xbb\xd3\x13\xc6\xfc\x6b\xfd\x27\xf8"
-  "\xd6\x42\xfe\xeb\xda\x94\xac\x13\xf1\x77\x93\x7f\x2d\xc4\x7f\x03"
-  "\xc9\xa1\x44\x93\xf7\xb5\x27\x38\xcf\x97\x52\x58\x83\x85\x75\xcb"
-  "\xf5\x4f\xf4\x12\x2d\x18\xa7\x17\xf6\x20\x3b\xe3\x80\x67\xbc\x14"
-  "\x8f\x61\x09\x94\x7e\x3e\xea\x31\x7b\x89\x1f\x3e\xbc\xe0\x57\x36"
-  "\xec\x05\xb5\xd0\x69\x65\x89\x94\x5f\xe8\xb4\x67\xbb\x83\x3a\xed"
-  "\xd9\x5f\x0b\x9d\x26\x78\x2c\x74\xda\xb3\x1f\x09\x9d\xf6\xec\x7b"
-  "\x7c\xff\x10\xea\x34\x8a\x23\xbd\x26\xeb\xb4\xa3\xb7\xb2\x6e\xd2"
-  "\x1d\x1e\xcb\xb3\x2d\xb2\x6e\x7b\x05\xc3\x48\x77\x10\x8e\x42\x4f"
-  "\x95\xba\xd8\xff\x9d\x0e\x62\x7f\x26\xbd\x97\x91\x1f\x0a\xa7\xf4"
-  "\x4e\xfd\xc8\x24\xa1\xe3\x9e\x1d\x0c\xea\xb8\x67\x0d\xc1\xbc\xa4"
-  "\xe3\xca\x14\x42\xc7\x89\xf0\xf6\x27\x48\xc7\x95\xba\x88\x07\x12"
-  "\x7c\x25\xad\x9b\x49\xe9\x91\x8f\x5b\xbd\xa1\x3a\x2e\xbc\x7d\x95"
-  "\xad\x90\x75\x1c\xe9\x36\xfc\xde\x80\x3a\x8d\xfb\xa3\xa7\x76\xd6"
-  "\x8c\x3c\x97\xdb\x1d\xd5\x01\xd1\x4c\x7e\xa2\x89\x6f\xcb\x2f\xc1"
-  "\x44\xc9\xa7\x8b\x44\x77\x99\x55\x3e\x17\xe9\x80\x67\x5b\x22\x6d"
-  "\x66\x5a\x98\x08\x39\xbb\x35\xd3\x4f\x73\xbb\xe6\xf3\x60\x6f\x61"
-  "\xe6\x3e\xdf\x39\x08\x1c\xd8\xf6\x19\xd5\x2b\x8e\x2f\x26\xd0\x2f"
-  "\xe9\x1d\xec\x3f\xff\x54\xe4\xe6\xf3\xf5\x9f\x35\x28\x31\xce\x08"
-  "\x3f\x08\x89\xbb\x44\x65\x84\xe4\x9b\x17\x8c\x2b\x9f\x44\x71\x34"
-  "\xc7\x88\xe9\x4e\xc6\x9a\x53\xf8\xfa\x78\x94\x6f\x8c\x8d\x47\xf9"
-  "\xce\x1b\xe0\xd1\xc8\xf1\x40\x7b\x0b\xc7\x47\x89\x97\xa1\x3c\x97"
-  "\xbe\xb9\x6f\xd1\xe8\xe5\x7c\x22\xc5\xab\x42\xe2\x43\xcb\xfa\x2c"
-  "\x4a\xfe\x90\xf2\x9e\x53\xdc\x18\xfe\x73\xb3\x6e\x0c\xff\xb9\x07"
-  "\xbe\x02\xfe\x16\xd2\x7d\x74\xf6\xce\x6f\x09\x4f\x97\xe9\xe3\x6d"
-  "\xaf\x9b\x7c\x2c\x61\xba\x97\xa4\xf5\x96\xcf\x4c\xb3\xf8\xf8\x8f"
-  "\xfb\xdb\xa9\xc7\x78\xee\xaf\x13\xf5\xf2\x8a\x3d\x00\x62\x4f\xdf"
-  "\x58\x9e\x5f\x47\xe2\x36\xd5\x27\xe3\xc6\xe3\x3f\x8d\xc4\x0d\xe3"
-  "\xe7\x85\xc4\xfb\x83\x75\xfe\x9c\xf1\x06\xf3\x48\x09\x76\x94\x4e"
-  "\xba\x63\xe1\x34\x0e\x5b\xe8\xac\x4f\xf3\xd8\xda\xc8\x36\x94\xff"
-  "\x32\xbe\xb6\x23\x9d\xed\x25\xbb\x6b\x66\x9f\x9b\x7c\x92\xb9\xe5"
-  "\xb3\x20\xb7\x61\x3f\x92\x44\xfe\x57\x68\x3e\xbd\xc8\x5f\xa0\x14"
-  "\xbe\x92\xb7\x59\xe5\xbc\xb1\xe6\x1e\xa9\x5c\xa9\x4c\x7e\x4e\x0a"
-  "\xf3\x74\xc9\x79\x08\x36\x9d\x0d\x42\xfd\x3f\x93\xfb\x29\xf3\x0d"
-  "\x92\xbe\xbd\x0d\xed\xe3\x24\x51\x4e\x31\x48\xe5\x60\xdb\x2e\xcf"
-  "\xba\x41\x39\x37\xa0\xaf\x22\xfb\x9b\xd3\x07\x12\x7d\x15\x86\xaf"
-  "\xa0\xef\x46\xe5\xbe\xff\xcd\xcb\xd5\xca\xe5\x3a\xbf\x39\x5f\x9f"
-  "\x4f\xf9\xfa\x7c\xcd\x92\xf8\xfa\x7c\xc1\x57\xf0\x35\x5a\x39\x07"
-  "\xbf\x7e\x39\x7a\xb9\x9c\x93\xd1\xca\x01\xfe\x17\xd3\x4f\x4f\xbc"
-  "\x7c\x77\x01\xdd\x1b\x22\x7c\x95\x57\x42\xe8\xdd\x2a\xe2\x3e\x91"
-  "\xca\x64\xf9\x6e\x95\xe0\x39\xb3\xca\x05\x45\x1d\x64\x87\xb0\x80"
-  "\x03\x2a\xb3\x69\x2e\x70\xc5\xbe\xd0\x3b\x48\x2a\xf3\xbe\xe2\x4e"
-  "\x17\xf2\x8d\xc3\xfd\x5e\x30\xc6\x7d\xb0\xb8\x85\xbf\xbc\xca\x97"
-  "\xc8\x4f\x83\xd8\x53\x54\x79\x52\xb4\xcd\xca\x66\x07\x3c\xcf\xfd"
-  "\x2c\x92\x0f\xe6\x21\x93\x94\x7e\x1a\xf5\xa1\x63\x69\x4e\xca\x69"
-  "\xa2\xce\x49\x36\x6d\x2b\x38\x56\x97\x15\x76\xc6\x70\x65\x55\xd5"
-  "\xf6\xaa\x25\xfa\xea\xe7\x9f\x9e\x57\x5d\xb3\xa5\x66\x67\x35\x3f"
-  "\x8c\x3e\x19\x30\x40\x5f\x53\xfe\x7c\xe9\xf6\x9d\x35\xe9\xbb\xb7"
-  "\x94\x8b\xc3\xeb\x77\x60\xc2\xd0\x44\x10\xe6\xdb\x5f\x87\x3a\xe8"
-  "\x0c\x53\x72\xdf\x11\x83\xdc\x07\x26\xf9\x7f\x97\xce\xe6\x76\xe9"
-  "\x00\xdc\x38\x3e\xf2\x58\xb6\x6f\x76\xc0\xba\xe3\x32\x1f\xc9\x4f"
-  "\x21\xda\x49\xba\x8b\xb0\x7d\x0f\xd5\x7d\x3e\x9a\xbc\xed\xc2\x1f"
-  "\x04\x3f\xff\x6f\xaf\xc1\x80\x3e\x88\xb7\xed\xa2\x79\xde\xed\x28"
-  "\x03\x95\x0e\xee\x77\x71\x2f\x8d\xbf\x0d\xb7\xc8\x76\x09\xad\x5b"
-  "\x89\x75\xe6\x99\xf7\x9f\x87\xed\x2b\xa9\x5c\x6a\x37\x6d\x68\xff"
-  "\x12\x2c\x66\xa9\xf4\x92\x0d\x8c\xdf\xf1\x88\x83\x43\xb6\x7d\x11"
-  "\xdf\x04\x96\xb8\x2d\xd7\x01\x86\xe4\xdf\x6a\x5d\x20\x9d\xe7\x8e"
-  "\x6f\x13\x67\xb7\xd5\x1e\x8b\x21\x61\x2c\xad\x05\xd3\x36\x6e\xcb"
-  "\xa5\xfb\x7a\xa2\xf2\x37\x29\xa7\x33\x30\x5a\x18\x17\x4a\x33\x8e"
-  "\xd9\xb1\x7e\x0c\xbf\x43\xda\x93\xa9\xae\x25\x3f\x22\x13\x30\xec"
-  "\x03\xba\xff\x80\x35\xe5\x74\x62\xd8\x04\xfc\xed\xa6\x3a\x25\x3f"
-  "\x07\x18\x47\x7b\x7d\x14\x7d\xb5\x57\x6c\xa7\x75\xe7\x51\xae\x0d"
-  "\xa8\xff\x0a\xcf\x89\x73\x71\x98\x1e\xcb\xb0\x9b\x47\xa0\x4b\xcf"
-  "\x6c\x34\x07\x88\xb8\x9f\xeb\xd2\xbb\x81\xa9\x36\x7d\x46\xf9\xb0"
-  "\x5d\xe8\x4c\x46\xb2\x7d\x30\x9c\x9f\xff\x33\x9c\x91\x79\x5e\xa3"
-  "\x67\x97\x28\x4d\xac\x79\x6b\xea\x83\x1b\x78\x5f\x72\x15\x68\x8f"
-  "\xd7\x00\x18\xdc\x91\xfa\x7e\x6e\xc9\x12\x7d\xc9\x96\x1a\x7d\x45"
-  "\x79\x65\xa9\xbe\xa4\xbc\x44\x5f\xb9\xbd\x46\xff\xec\x76\x9a\x40"
-  "\xa2\x29\xa3\x30\x99\x08\x10\x7d\xbb\x0b\xe3\xe4\x35\xf2\xa1\xdd"
-  "\x65\x13\x90\x7e\xe4\x49\xd5\x9a\x21\x4f\xd9\xc4\x70\x9e\x54\x2d"
-  "\x10\x72\xbc\x03\xc7\x7f\x86\x34\x71\xbe\x50\xe5\xc4\x6f\xa4\xdf"
-  "\xe0\x0c\x6f\x7b\x55\xfb\xa4\xb4\xef\xcb\x69\xb9\x5c\xcc\xbe\x38"
-  "\x16\xd7\x20\xc9\x63\xbb\x38\x8b\xcc\xfd\xd5\xb4\xf3\x33\x02\x3b"
-  "\x1c\x31\xf3\x90\x8f\xae\xbd\xb0\xf5\x32\xec\xf8\x3d\xb3\xec\x48"
-  "\x96\x64\x28\x3e\x60\xcd\xb1\x49\xf2\x83\x32\x51\xa5\x1f\x2f\x3f"
-  "\x55\xb5\x24\x3f\xcc\x53\x18\xcf\xf7\x93\xf8\xbc\xa8\xa7\xf0\x1b"
-  "\xfb\x53\x07\xec\x38\x48\x74\xb8\x77\x17\xc6\x9b\xde\xe0\xfd\xf5"
-  "\x17\xb4\x36\x7b\xda\xcb\x7d\x2c\x4d\x42\xd9\xc0\x3a\xaa\xaa\x91"
-  "\xeb\x48\x4e\x1f\xbd\x0d\x73\x79\x09\x97\x31\xc1\xcf\x5e\x2e\x63"
-  "\x68\x17\x20\x4e\x4a\xd9\x2e\xa0\x3e\x00\x71\x1b\xa8\xd9\xc7\x18"
-  "\x96\xd1\x1f\x22\x07\x97\xa3\xc9\x01\xd6\xed\xd6\x8a\xed\x5b\xb7"
-  "\x61\x43\xaf\x2a\xad\xd9\x5a\x46\xfe\x2b\x48\x0f\x70\xe7\x18\x73"
-  "\x4b\xf4\x3b\xab\x4b\xb7\x4e\x86\x68\xa9\xc6\x22\x43\xeb\x5f\x1b"
-  "\x40\x79\x1d\x1a\x2a\x8c\xa3\x33\x1c\xe2\xcc\x46\xcd\xd1\xa1\x6a"
-  "\x1c\xf7\x84\xd5\x7b\x4d\xa3\x5d\x97\x85\x76\x62\x16\x70\x9b\x1f"
-  "\x79\x26\xf6\x21\xd4\xfc\x99\xf8\x30\xa4\x54\x60\x7f\x50\xdd\x2c"
-  "\xcb\x00\xbe\x77\x20\x4d\x87\x82\x7b\x40\x6a\xce\x0e\x29\xe3\xce"
-  "\x91\xfe\x11\xfb\x4d\x2e\xa2\x1e\xd0\xb4\x9f\x87\x6a\xd2\xfd\x74"
-  "\x57\x07\xe5\x3f\x2b\xe7\xa9\x1f\x3b\x47\x5d\xb3\x54\x96\x93\x90"
-  "\x3c\xbf\xa3\x30\x31\x7e\xae\x72\x51\x9d\x33\x51\xf7\x6a\x39\x1d"
-  "\xf2\x95\xb5\x73\x3d\x52\x93\x1e\xa9\x1b\x7e\xab\xa5\x35\x77\x81"
-  "\x0f\x97\x3f\x6d\x4e\x0b\xf7\x8d\x82\x36\xde\x79\xa8\x59\x2c\xed"
-  "\x7f\x39\xc3\xfb\x74\x23\xc2\xf2\x0a\x58\xcc\x52\x7d\xab\x5c\x16"
-  "\x4b\xcc\x69\x69\xe7\x72\x56\x73\x28\x38\x27\x59\x93\x4d\x63\x73"
-  "\x36\x54\x38\xc1\x01\xd5\x35\x5c\xb6\xf0\xbd\xe6\x7b\xc2\xf7\x1a"
-  "\xc9\x1b\xd1\x49\x72\x15\x94\xa9\x9a\x6e\xb9\xbe\x89\x66\xcc\x57"
-  "\xab\xe7\xfe\x76\x6b\x1c\x32\x2f\x63\xf9\x93\xe1\xed\x56\x8b\xb8"
-  "\x78\x44\xdb\xe5\xe3\x4a\xe1\x17\x88\xce\xd1\xa8\x10\x47\xdb\x05"
-  "\xd8\xf9\x25\x9d\x0d\xd0\x78\x69\x9c\x96\x63\x23\xff\x08\xc2\xbf"
-  "\xd0\x4e\x6c\x0f\x3b\xb2\xa5\xf3\xc1\xf4\x8d\xfd\x7f\x75\xb6\xa8"
-  "\xbb\x9d\x9b\x43\xda\x9e\x4b\xda\x6f\x30\x91\x78\x44\xfa\xcc\x6e"
-  "\x5c\xc9\xdb\xab\x38\x57\xbc\xf3\x90\x9c\x8f\xfb\x12\xf0\x89\x3e"
-  "\xf1\x32\xec\x3c\x4e\x7d\x04\xe1\xe7\x80\x9d\xe9\x54\x3e\xd1\x47"
-  "\x7d\x2e\x97\x1b\x1d\xdd\x49\xb0\xb3\x2b\x02\x87\xb3\x32\x2c\x09"
-  "\xf6\x80\xfc\x4d\xfe\xc2\x1c\xb0\xdb\xd0\x95\x82\x6d\xca\xcd\x69"
-  "\xb8\xa9\xab\x06\xdb\x96\x9b\xd2\xed\x4a\x90\x79\x88\xe1\x66\xfc"
-  "\x46\xfb\x67\xbb\x5e\xac\x39\x6d\xcb\x15\xba\x68\x77\x05\xf9\xa2"
-  "\x32\xe9\xc9\x9f\xe0\x52\xa1\x6f\xb8\xbf\x1c\x1e\x77\x87\xd4\x66"
-  "\x27\xd1\x19\x24\xbe\xef\xc6\xed\xe3\xba\x41\xf8\x57\xc0\x78\x6c"
-  "\x23\x1e\x71\xef\xc9\x24\x81\xdb\x2e\xf3\x58\x19\x28\x13\x5d\x7c"
-  "\x8d\x73\x97\x41\xf8\x2b\x99\x78\x06\xe3\x3b\xe4\xfa\x23\x1f\xd0"
-  "\x44\x37\xe6\x8b\xef\xe2\x3e\xbe\x76\x9d\x92\xf1\x95\xe2\x94\x5c"
-  "\x1e\x38\x0f\x76\x8d\xb5\xff\xa1\x24\x9e\xd6\x29\x97\xc3\xd3\x62"
-  "\x3a\x4a\x4f\x77\xd5\x79\x2c\xbb\xd5\x63\x70\x84\x9f\x94\x78\x2a"
-  "\xa7\xab\x83\xc7\xe9\x83\xba\x6a\x27\x5f\x33\xe2\xfb\xe2\x90\x0e"
-  "\xd7\x0b\x38\xce\xa6\x3a\xd0\x83\x0a\xf3\xa8\x09\x9e\x90\xc5\xdd"
-  "\x1b\xe4\x3c\x2a\x05\xf1\x71\x77\x89\x5c\xb6\x0c\x83\xf0\xbf\xa1"
-  "\xce\x13\xb4\xa8\xa9\x8d\x50\x5a\x82\xcb\x65\x82\xdf\x75\xb3\xfb"
-  "\x12\x97\x41\x4e\xe7\x6e\x5b\x68\x5d\x0b\x5b\x6c\xf7\xd9\x10\x79"
-  "\x20\x7c\xc6\xea\xdf\x01\xc6\x64\xd1\x97\xec\xf6\x86\xe0\x98\xeb"
-  "\xb1\x18\xe3\x83\xf5\xc0\xeb\x88\xee\xad\x88\x7a\x8f\x18\x6f\x2b"
-  "\x98\x26\xc0\x38\x9e\x54\x1f\x38\x16\xcb\x81\xae\x16\xf2\xdb\x94"
-  "\x63\x43\x9e\x20\x8e\xc6\x57\x48\xae\x10\x6e\x71\xb8\x6c\x1a\x0d"
-  "\x21\xf8\x2a\x48\xaf\x63\xd8\x41\x39\x0d\xe2\xc7\xf7\xb2\xc8\xfc"
-  "\xc4\xb8\x8e\xb1\x7a\x5c\xc8\xd3\x76\xca\x78\x7e\x45\x9f\x21\xf1"
-  "\xca\xf8\x85\x54\x86\x53\x2e\x03\xdf\x51\x3f\xec\x1e\x67\xab\x3e"
-  "\xbd\xa7\xa6\x54\x38\x30\xa2\x4e\x7e\xcb\xd6\x6d\xa5\x25\x19\xfa"
-  "\x2d\xcf\x90\xab\xa3\xea\x8a\xd2\x52\x03\x5f\x24\x0a\xb7\x03\x93"
-  "\x79\x79\xc8\x07\x61\xcb\xee\xdd\xf1\xaa\xd8\x1f\x43\xed\x82\xda"
-  "\x3b\x9d\x2b\x98\x78\xba\xf6\x2a\x1f\x9b\xd8\xcd\x0b\xc1\xee\x65"
-  "\x66\xb2\xdf\xb9\xee\x23\xfa\x75\x6e\xd1\x0f\x60\x7d\x52\x1f\xe9"
-  "\xb1\xec\xb1\x86\xf3\x6b\x4f\x47\x78\x5b\xde\xd3\x19\x5d\x4f\xec"
-  "\x79\x84\xeb\x09\xab\x90\x0b\xd2\x4f\x74\xb6\x80\xe0\x62\x9e\x81"
-  "\x08\x98\xee\xa0\x8e\xda\x0b\xb2\x8e\x12\xfd\xc4\xde\x34\xec\x83"
-  "\xac\xa2\xac\xbd\x29\x41\xb9\xd9\xdb\x2a\xe4\x66\x6f\x96\x03\x0e"
-  "\x57\xc8\x63\x15\xd1\x77\xec\xe1\xf6\x23\xe9\x74\x8c\x2f\x90\xe1"
-  "\x35\x27\x51\xbf\xb1\xb7\x78\xbc\xfd\xb0\x37\x81\xec\x07\xda\xf7"
-  "\x48\xbc\x40\x5c\xe3\x45\xbb\xd9\x7b\x38\x44\xff\x68\xf1\xbb\x35"
-  "\x5a\x5d\x3f\x4d\xdd\xf1\x3c\x5a\xce\x9b\xb7\xb5\xb2\x66\x19\xb9"
-  "\xa1\x2a\x35\x1a\x4a\xb7\xd6\x94\x96\x44\xae\xe3\xa5\xcb\xb6\x98"
-  "\xec\x97\xde\x95\x48\xfc\xd8\x8b\xf4\xef\x4b\x91\x69\xe0\x7a\x0a"
-  "\x6d\x47\x49\xc7\x25\x5c\x80\xda\x2f\xda\xf9\x3e\xc0\x17\x52\x64"
-  "\x39\xa1\x74\xcb\x8d\x2c\x80\x61\x48\xff\x1e\xf9\xae\x43\x1c\x93"
-  "\xbe\x90\x2b\x7f\x07\xf3\xbf\xf0\x22\xef\xfb\x8e\xf0\x3d\x83\xc8"
-  "\xd3\x5a\x75\x88\xbd\x85\xdf\x2f\x9c\x93\xbe\xb9\xaf\x25\xf2\x0b"
-  "\x36\x08\x2f\xbc\x21\xf8\xfb\x02\xd6\xbf\x51\xd2\x15\xb5\x62\xdf"
-  "\xcd\x11\x80\x77\xea\x5c\x71\xed\x7c\x3d\xe1\x85\x4e\xb9\x3c\xcc"
-  "\x7f\x2e\xb4\x4c\xea\xb7\x22\xe1\x39\xe0\x05\xba\x97\x9b\x7c\x2b"
-  "\xa2\x6d\xf9\xc2\x60\x14\x5c\x0d\xa1\xe9\x3c\x96\x5a\x2d\x96\x7f"
-  "\x4a\xa6\x79\xbd\x91\x87\xa5\xdd\x80\xc6\x41\x89\xc6\x0e\x92\x2d"
-  "\x2a\x9f\xe4\x5f\xc2\xe1\xa0\xe4\xf7\xc4\x41\x77\x85\x11\xfe\xdc"
-  "\x07\x9a\x8e\xda\x75\xad\x11\xfb\xf9\x41\x99\x0e\xa2\xf1\x44\x9d"
-  "\x4b\x2d\xfb\x9e\x12\xf9\x6b\x9f\x8c\xc0\xed\xfd\x90\x3c\x4e\xdb"
-  "\x6c\x5a\x2b\xa8\x5d\xc9\x2c\x7b\x8f\x93\x1c\x92\x4f\xaa\xe6\x31"
-  "\x39\xac\xed\x1f\x2f\x77\xb5\x2b\x48\xee\x42\x65\xa9\x7c\xe1\x56"
-  "\x94\xa4\xea\xd2\x9a\x25\xdc\xba\x47\xc3\x8e\x5c\x9b\x6d\xa9\x29"
-  "\xdf\x5e\x59\x9d\xa1\xaf\x2e\xd9\x22\x35\xfa\xb0\x36\x6f\xe1\x63"
-  "\x77\xb7\xdc\xce\x3c\x96\x7d\x2b\x82\xba\x65\x5f\x50\xfe\x69\x0f"
-  "\x18\xbf\x53\x74\xdf\x1b\xa2\x3d\xed\xab\x08\x69\xbb\x3c\x3f\xb5"
-  "\xd1\x76\x6e\xb3\xed\x0b\xed\xff\x69\x6c\x3c\xe9\x32\xec\x5b\x2c"
-  "\xf1\xd4\x2d\x78\xbc\xef\x33\x4e\x27\xf7\xb9\x55\xeb\x26\x3a\xb9"
-  "\x7f\x19\x6e\x9f\xed\xeb\x96\xe9\x0d\x8e\x1b\xf6\x39\xb8\x1d\x25"
-  "\xd9\x6b\x37\x1a\x97\x07\xed\xd3\xba\x5a\x69\xce\xad\x5f\x1e\xe3"
-  "\xc9\xf6\x35\xe2\x52\x22\x6c\xd5\xba\xc5\xf9\xb5\x6c\xb4\xc8\x48"
-  "\xbe\xe8\xa8\x0e\xea\xb6\xc8\xb6\x25\xdf\x1f\xd8\x98\xd3\xe1\xb1"
-  "\xd4\x15\x86\xea\x09\xa6\xda\xd6\x2f\xd9\x88\x1d\x62\xec\x7a\xd3"
-  "\x3f\x9f\xc7\xb2\x10\xb7\xf8\x1b\xe0\x86\x74\xd5\xa1\xfe\xab\xe7"
-  "\xfe\x35\xc9\xbe\x66\x43\x3a\xe9\xde\x35\x13\xf7\xc9\xde\x86\xb0"
-  "\x5d\x58\xb7\x98\x0e\xed\xbf\x7d\x5c\x36\x02\x28\xa3\xb4\x37\xc8"
-  "\x2d\xdb\x48\x50\x77\x8d\xfa\x22\x7c\x47\xb9\x35\x49\x67\x12\x4d"
-  "\x79\xae\xea\x74\x18\x1a\xd2\x29\x87\xaa\x0b\xd5\x34\x5f\x40\xbc"
-  "\xb0\xb7\x7a\x41\xc8\x8f\x49\x87\x7a\xaa\x3b\x14\x9e\x04\x8b\x78"
-  "\xaa\x26\x3c\x58\xb5\x4e\x49\xf2\xcd\xef\xf1\x1a\x4a\x47\x3d\x5a"
-  "\xe7\x60\xd5\xe9\xca\x18\xfe\xb5\x6e\x44\x67\x02\xdd\x6b\x46\x77"
-  "\xd4\x91\xbe\x12\x7e\xf6\xcd\xef\xbe\x2a\xe6\x06\xa4\x72\x4d\xef"
-  "\x31\xe5\xdb\xbc\x5f\xa9\xe7\xfd\x0a\x03\x71\x07\x83\xa9\x9b\xef"
-  "\xd3\x35\xbc\xcd\x7d\x7f\x4a\xe7\xbf\x5d\x5d\x06\x1f\xbf\x9b\xcc"
-  "\x54\x43\x76\x9a\x8f\xd6\xa9\xf8\xf9\xe6\xd3\x35\x3e\x58\xef\x25"
-  "\x99\x34\x79\xc9\x6f\xbb\x9b\xdb\x0b\x66\xb5\xec\xab\x9d\xee\x4a"
-  "\xa3\xfb\xf7\x90\x2e\x15\xd5\xbb\xde\x44\x3e\xf6\xcd\x74\xbf\x1a"
-  "\x88\xf1\xb8\x0e\xea\xd1\xa6\x17\x75\x60\x5e\x43\xf7\x19\x8a\xb1"
-  "\xc2\x79\xac\x17\xd5\xe7\x98\xb6\x54\xac\x55\xcb\x7a\xc2\xfc\x29"
-  "\xed\x7d\x77\x48\x30\xb0\x2c\xec\xff\xeb\x0e\x89\xb2\x10\x9e\x47"
-  "\xae\x4f\xf3\x9a\xf1\xf3\x1b\x41\x78\x98\x7f\xb5\x64\x17\x80\x98"
-  "\xbb\xfa\x2d\xc1\x3a\x25\xcf\x5d\x05\x6d\x1f\xf3\x19\x79\xee\x4a"
-  "\xf8\x8c\x36\x35\x53\xf9\xb1\xe6\x88\x98\x69\x23\xc9\x7d\x3c\xd9"
-  "\x70\x31\xed\x09\xec\xdf\x09\x77\xd9\x2e\x14\xf5\xb3\xbf\x9c\xec"
-  "\xc3\xae\x5a\x31\xae\x1d\x12\x77\xb1\xa1\x0d\xb0\xbf\x46\xf4\x65"
-  "\xfb\x0b\xe5\xbe\x0c\xf3\x9e\x90\x74\x85\xd4\xcf\xed\x1f\x1b\xff"
-  "\x46\xdf\xf7\xbf\xbf\x59\xe6\x91\xcc\x73\xc1\xa3\xfd\x97\x86\x92"
-  "\x32\x33\x82\xbc\xdd\xcf\xd7\x2e\x82\xf1\x96\xb9\x21\xbc\xa7\xef"
-  "\x34\xa1\x37\xf7\x63\xff\x6f\xda\x20\xfa\x14\x11\xc6\x92\xb6\x2d"
-  "\xa7\xbb\x13\x05\x0f\xca\xf9\xdc\x8c\xcb\x94\x8e\xb8\x59\xb4\x0e"
-  "\x85\xe2\x98\xd0\x65\x16\xec\xff\xf6\x27\x88\x7c\xfb\x4f\x12\x2e"
-  "\xa1\xf8\x3e\x5a\xb9\xad\x72\xfb\xee\x4a\x9a\x50\xdb\x59\xad\xdf"
-  "\xba\xbd\xa4\x74\x72\x94\xf9\x10\x1d\xdd\x97\xea\x6e\x1e\xf3\x6b"
-  "\xf5\x62\x3a\xed\xd3\x17\xf7\x07\xbc\x78\x87\xfe\x76\x92\x2f\xcb"
-  "\x2b\x34\x57\xc0\xef\x70\x20\xdf\xa8\x62\xde\xc0\x49\xf9\x05\xaf"
-  "\x5f\xbc\x65\x68\x77\x99\x64\x63\x1d\xfc\x13\xf1\x51\x1a\x73\xb0"
-  "\x0b\x70\x60\x92\xdc\x0f\x11\x7e\xdc\x36\x1f\x4d\xe7\x7a\x31\x30"
-  "\x5a\xa6\xe6\xfc\x1a\x4d\xc7\xfe\xc6\xe2\x74\xa0\x2d\x2e\xd1\xe5"
-  "\x96\xf9\x41\xf4\xa3\xad\x1b\xef\x61\xe5\x28\xa3\x2f\xa6\x4b\xb0"
-  "\x48\x7f\x22\x6c\xcb\x29\x79\x9f\x38\xf9\x0b\xb5\xed\x22\xff\xbf"
-  "\x07\xae\x05\x1a\x49\xdf\x1c\xc8\x91\xf5\x12\xf5\x45\x01\x84\xf3"
-  "\xe1\xb0\x2b\x0e\xdb\x0d\xf9\x1d\xba\xf5\x3c\x1c\x3c\x28\xee\x03"
-  "\x38\x50\x12\x7e\x1f\xc0\xc1\x5c\x7c\x0e\x4a\xcf\xb1\x90\xf7\x1b"
-  "\x3d\x72\x1e\x43\x30\xec\x80\x2d\x22\xcd\x31\xc4\xa9\x67\xcc\x5e"
-  "\x11\x3e\x4b\x25\xbf\xc5\x74\x87\xc5\xc1\x49\xe4\x17\x34\x28\x1b"
-  "\x07\xe6\x49\x36\x88\x93\x78\x47\xfd\x2d\xa6\xe1\x7b\xb9\x91\x27"
-  "\xcb\x69\x8e\x96\x68\x62\x9e\x72\x94\x89\x83\x69\x41\x39\x10\x3c"
-  "\xc2\xb0\x9c\xa0\x9d\x72\x30\x81\xf2\x84\xf2\x01\xcb\x78\x40\x8c"
-  "\x4d\x0f\x16\xcb\x7d\x36\xf9\x44\x15\x77\x41\x1c\xe8\x39\x51\xe7"
-  "\xc4\x31\xff\xc1\xda\x20\x8c\x03\x3d\xd2\x5c\x84\x9a\x29\x2d\x59"
-  "\xed\x7c\xcc\x76\xb0\x35\x38\x27\x70\xa0\x87\xf4\x2e\x87\x91\xb4"
-  "\xad\xc0\xee\xe6\xf7\x93\x2a\xe4\xbb\x87\x31\x6d\xb7\x6c\xa3\xc8"
-  "\xb0\xba\xc4\x9c\x13\xf7\x63\x89\x6d\xd0\x8a\x69\x06\xc7\xe6\x63"
-  "\xe9\xfe\x21\x79\x0c\x68\xc4\x76\xcc\x6d\xef\x17\x13\x82\x63\x3d"
-  "\xcb\xfb\x5c\xdf\x58\xc6\xe0\xe0\xf8\xe8\x45\x88\x1c\xb7\xa1\xfd"
-  "\xa0\x2f\xaf\x2c\x47\xf3\xe1\x59\xc3\xf6\x65\x38\x74\x78\xd6\x50"
-  "\xbe\x8c\xb6\x94\xad\x59\xb1\x8a\xff\x62\xe3\x58\x16\x65\xfe\x78"
-  "\xec\x0e\x52\x9a\x33\xc2\x71\x2e\xcd\x9d\x7a\xc4\x1d\x85\x13\xa5"
-  "\xdf\x78\xe9\x77\x02\xf6\x7b\xdd\xd8\x06\x3e\xa0\x3b\x68\x10\x07"
-  "\x9b\x74\x2f\xa4\xdc\x67\xa3\x2e\x7f\xf1\x5d\x79\x9d\x8c\xef\xb1"
-  "\x27\x5f\x85\x74\xc7\xe8\x81\x6d\x9f\x21\x4d\x63\xf3\x1f\x62\x7e"
-  "\x51\xac\x7b\x61\xb8\x57\x0e\x97\xe7\x63\x3d\x96\x1f\x27\xc8\x73"
-  "\xaf\x22\xed\x8f\x53\x82\x79\xc3\xe6\xb6\x93\xe5\xf5\x35\x4c\x93"
-  "\x2b\xf3\x4c\x86\x63\xd2\xb3\xcb\x92\x9d\xa4\xe2\x76\xb5\xe5\xc5"
-  "\x6c\xee\x1f\x94\x6c\x71\x3e\xcf\xfc\xe3\x1a\xb9\x1c\x1a\x23\x10"
-  "\xde\xd2\xda\x0d\x6f\xf7\xe4\x07\x54\xf8\x11\xfd\xf1\x58\xfd\x7f"
-  "\x9d\x7b\xc1\x46\x77\xb1\x2e\xdf\x30\x3b\x59\xff\x17\x6c\xb3\xcf"
-  "\x00\xf8\x76\xb1\xce\xd1\x61\x76\x82\x78\x5d\xff\x34\xc0\x2b\xff"
-  "\x03\xc0\xaf\xda\xf4\xc5\x08\xf2\x7d\xed\xb5\xc0\x65\xba\x0b\xaf"
-  "\x1d\xd3\xad\x75\x5f\x61\x6d\x98\x67\xad\x81\x5d\x6e\xc3\x74\x6b"
-  "\x2e\x5d\x66\x47\x31\xed\x9a\x32\xa4\x7b\x17\xf3\xf9\x55\xdb\xbe"
-  "\xd0\x3f\x46\x7a\xe8\xef\xb2\x5c\x8d\x8b\xd1\xf6\x52\x36\xb0\x03"
-  "\x77\xdd\xe9\xb1\xfc\xdd\xd2\xb1\x3b\xad\x10\x2e\xf1\x28\xdf\x48"
-  "\xef\xdb\xbe\x40\x9a\xbe\x28\xc2\x3e\x14\xeb\xe0\x0b\x4c\x87\xe3"
-  "\xff\x4a\xae\x6f\x5c\xaa\x3b\x93\xf0\x49\x8f\xa6\xf7\x11\xd7\x2e"
-  "\xff\x2e\x76\xb2\xe1\x29\xc4\xff\x22\xe2\x3f\xcc\x3a\x91\x86\x13"
-  "\xf5\x17\x00\x08\x7f\x3f\xc1\xf4\x83\xaa\x68\x8f\x22\xb1\x1d\xe3"
-  "\x8b\x8c\x5a\x68\xc7\xb4\x4f\xb9\x21\xb1\x0d\xd3\x3c\xb5\x23\x11"
-  "\x38\xfe\x83\x88\x77\xe2\x62\xb5\x1f\xcb\x26\xfc\xb1\xfc\x01\x19"
-  "\x4f\xb9\x7c\xc2\x57\x96\xc1\x22\x9a\xef\x4a\xca\xac\x20\xbc\xc5"
-  "\x1c\xfe\xa1\x54\x57\x75\x19\xb8\x54\x77\xdd\xe9\x80\x43\x39\xd4"
-  "\x86\x88\x1e\x17\xca\x94\x74\xee\xed\x0b\x99\x07\x62\x3c\x79\x68"
-  "\x85\x4c\x5f\x28\x5d\x05\xdb\xab\xf8\x3c\xea\x96\xad\x35\xe5\xbb"
-  "\xb6\xe0\xe8\x6c\x32\x18\x28\x88\x8f\xdf\x4a\x4b\xf4\xdb\x2b\xf5"
-  "\xcf\x6c\x29\xaf\xd8\xbe\xab\xb4\x2a\x83\x0f\xb9\xab\x4b\x2b\x4b"
-  "\x68\x7a\xb5\x6a\x4b\x95\x61\x72\x84\xcd\x6d\x5d\xac\xa6\xfd\x88"
-  "\xa4\xcb\x2e\xc0\xcb\xa9\xd2\xdc\xa2\x97\x59\x72\xf9\xd8\x4d\xb4"
-  "\x83\x43\x5f\xe8\xf7\xe6\x52\x7c\xa2\xe8\x6b\x5e\x4e\xe1\x74\x0d"
-  "\xe5\xc9\xf9\xf8\xde\x5d\x6e\xa3\x52\xf8\x68\x1e\x04\xf7\x90\xbf"
-  "\x9c\xca\x94\x48\x13\xd2\x2c\xd9\xa9\xf2\x59\xbe\x7f\x3d\x0f\x3f"
-  "\xf1\x23\x9d\xb4\x56\x70\x86\xdb\x81\xfc\xcc\xd1\x4f\x68\x0e\xe6"
-  "\x0c\xb3\x4c\x48\x20\x3e\xd4\x8b\x71\xa4\x52\xa3\x30\x2b\xc8\x16"
-  "\x6a\x57\x06\xb2\x68\x4d\xb0\xdd\x12\xc8\x0a\xee\xe1\x39\x44\x36"
-  "\x26\xdf\x9f\xd4\xc6\xdb\xc1\x4b\xb5\xb2\x7c\x2b\xe9\x4c\xc9\x81"
-  "\x69\x4b\x84\x6e\x7e\x69\x3f\xa5\xc7\x7a\x5a\x22\xf0\xe7\xf7\xb6"
-  "\x62\x7f\xf4\x93\x97\x02\x49\xef\x69\xfd\xd5\x3a\xe9\xee\xe2\xcc"
-  "\x83\x81\xa6\xcc\x1a\x3f\xf6\xdb\x01\xb4\x45\x59\xd3\x7b\xaf\xfa"
-  "\x9b\x32\x2b\x03\xbb\xd3\x95\xa4\xbf\x4d\x46\xe4\xcf\xf6\xb2\xc9"
-  "\xec\x4a\xd9\x4d\x7e\xba\x6f\xaf\x29\x73\x17\x63\x98\x37\x29\xf3"
-  "\xc7\xd4\x47\xe2\xb7\x51\xfa\x3e\x44\xdf\x01\xb4\xc5\x30\xac\x1e"
-  "\xbf\xad\xfc\x6e\x3f\x39\x7d\x78\xda\x26\xfa\xd6\x28\xf8\x1e\xc1"
-  "\x2c\xb4\x7d\x97\x12\xad\x32\x8d\x7c\x0c\x40\xf3\x10\x63\xb4\xfc"
-  "\xe4\xa0\x1c\x4e\xb6\xa9\xb0\x13\x61\x2b\xf2\xb4\x45\xe8\xac\xb1"
-  "\x74\x4f\xca\x34\x73\x5e\x36\x65\xe2\x58\x09\xeb\x8f\xee\x63\x3e"
-  "\x30\xfd\x4e\xa6\x3c\xb4\x95\xfa\x86\x7c\x3f\x5f\xab\x02\xb1\xb6"
-  "\xf1\x93\x53\x32\xff\x68\x2f\x3c\xf5\x0f\x58\x4f\xe9\x45\x2e\x98"
-  "\x2c\xda\xe7\x4f\xce\x85\x8c\x41\x06\x19\x97\xe7\x9f\xf0\x73\x26"
-  "\x4c\x19\x7f\x40\x7c\xbf\xb4\x54\xf4\x67\x2f\xc7\xcb\x69\x31\x8c"
-  "\xef\x01\xa2\x35\x2b\x94\xff\xc1\xb6\x88\xf3\x99\xb1\xf4\x0f\xe2"
-  "\x2b\xf9\x3b\x7f\x79\x83\x6c\x1b\xe0\x7b\x71\xf8\x19\xce\x97\xf3"
-  "\x22\xd7\x98\x9e\xde\xbe\xbd\xa6\xa8\xaa\x94\x7e\xd2\xe7\xee\xbc"
-  "\x23\xb2\xaf\x48\x10\xf7\xc8\xbc\x6c\x24\xba\x49\x7f\x8a\xb3\x10"
-  "\x2f\x9f\x0c\x19\xef\xd1\x9c\xd3\xfd\xa4\xf7\x69\xad\x18\xe3\xce"
-  "\x7e\x52\xbb\x8f\xdb\x1b\x9f\xc5\x83\x32\xd6\x1e\x06\xee\x57\x3b"
-  "\xb1\x49\xcb\xdb\x77\xe3\x7b\x66\x8f\xe5\x70\x82\xbc\xe7\x28\xba"
-  "\xef\x87\xcc\x01\x7f\x53\x45\x87\x7e\x1a\xbf\x23\x4f\xf9\x0f\x7b"
-  "\xfb\x95\x64\x5f\xd4\xe1\x3b\xed\xc9\xe0\xf3\x58\xd2\xdd\x6b\xbf"
-  "\xb9\xda\x8f\x7a\xe4\x70\x31\x6b\xcc\x44\xdd\x73\xb8\x30\x26\x0e"
-  "\x21\xe7\x66\xc5\x1a\xdc\xe1\x98\x7b\x2e\x98\x35\xa7\x5f\xc8\xca"
-  "\xe1\x5e\xbe\x16\x34\x0d\xfe\xee\x3c\x1c\xfe\xbd\x5a\x87\xe3\x94"
-  "\x69\xf0\x73\x7c\xef\xe5\xfd\xbe\x2e\xbc\x8f\x86\xd4\xc1\x0e\xb5"
-  "\x8a\x61\x9b\x60\x0a\x26\xfe\xd0\xc8\x10\x7f\x2a\x7c\x94\x4c\xc1"
-  "\x77\x9f\xab\x90\x53\x13\x27\xa8\x41\x33\x35\x21\x7e\xe6\x8c\x14"
-  "\xdd\xfd\xf7\x2d\xcd\x31\xd5\xd5\x1a\x59\xc0\xe7\xd5\xb0\xd0\x7b"
-  "\x02\x1b\x3b\x1f\xbd\xc3\x2c\x74\x61\x63\x63\x67\x34\x5c\x5f\xb1"
-  "\x30\xda\xc3\x09\x81\xa4\xe3\x2e\xd3\x4e\x50\x7e\x38\xe2\x50\x92"
-  "\xad\x42\xfa\x95\xee\xbb\x3c\x0f\xaf\x6c\xfc\x18\xc3\x90\x7e\x23"
-  "\xb3\x1e\x77\x89\xb3\x05\xaf\xbc\x11\x68\x3a\xee\x0a\xc2\x57\x03"
-  "\xc1\x47\x7b\x58\x79\xac\xce\xa9\xb4\xab\xef\x03\xbb\xde\x0d\x1f"
-  "\xe3\x7b\x8c\xfa\x34\xd0\xdc\x0b\xc1\x40\xbd\x73\xc8\x74\x1d\xf5"
-  "\x91\x91\xcf\x83\x2a\x2f\xc3\x2b\x7f\xea\x8c\x91\x8f\xaf\x65\x24"
-  "\x65\xff\xc1\x63\xa9\xc7\xfa\x5f\x31\x20\xf5\xf7\x68\x8f\xd4\xa7"
-  "\xc8\x6d\x02\xe3\x7f\x2f\xe6\x63\xeb\xb3\xe4\x34\x51\xeb\xe8\x27"
-  "\xb4\x87\x91\xd9\xa8\x5e\xd9\xb0\xd3\x49\x3e\xd4\x62\x8c\x79\x73"
-  "\xb1\xff\x89\x23\x1b\xa6\x17\x35\xc4\xd4\xfd\x5a\x5a\x2b\x45\xbd"
-  "\x92\xf5\xbc\x66\x7f\x56\xf9\x54\xf7\x2d\xa0\x31\x3e\xa9\xd0\xf8"
-  "\x56\x29\x8e\x1e\x61\x67\xc8\xc6\xa3\xb5\x06\xd2\x2d\x53\xf6\x67"
-  "\x6d\x61\xca\xa5\x8b\xe8\x6e\xab\x29\x83\x0f\x28\x02\x96\xec\x45"
-  "\xe4\x17\xcd\x7a\x2b\xeb\xc7\x74\xe7\x30\x1d\xcd\x35\x0d\x60\xda"
-  "\x9e\x0b\x50\xff\x25\xfe\x76\x4f\xd9\xcf\xda\xa7\x0c\xb2\x40\xa6"
-  "\x19\x54\x12\xbc\x1e\x7e\xb7\xfc\x28\x1f\xeb\xc6\x05\xc7\xba\x0d"
-  "\xc9\x7e\x0b\x4c\xc8\x8f\x63\x1f\x23\x8c\x6e\x36\x1c\xe8\x3e\x1a"
-  "\xe0\xfe\xa1\x68\x3d\xe8\x2c\xea\x91\xb3\xf3\x9b\x71\x6c\x43\xf7"
-  "\x44\xee\xc1\xba\xf4\x7a\xc9\xae\xb1\x61\x19\x5d\xa8\x27\x4e\xed"
-  "\xdb\x01\x4a\x3f\xe6\xc1\x3e\x42\x75\x19\x1a\x9e\xef\x73\xf6\x93"
-  "\x4f\x6d\x55\xd0\x56\xb3\xf2\x79\xb9\x57\x8e\x30\x1b\xed\xe3\xfd"
-  "\xf0\xb2\x8b\xee\x59\xef\xa6\x36\x43\x7b\x1a\x29\x1c\xbf\x4f\x65"
-  "\x36\x43\xba\x7d\xd0\x09\x7d\x68\xa5\x31\x93\x4e\x89\xe1\xa7\x32"
-  "\x5c\x68\x4f\x20\x6c\xda\xbf\x8d\x6d\xbe\x67\xca\x20\xc4\x21\x2d"
-  "\xa7\xb8\x8d\xb5\x3b\x3d\x0d\xf3\xd9\xe6\x21\x6e\xd8\xe7\xa7\x7c"
-  "\x38\xd2\xaf\xe4\x67\x7e\x6f\x65\x67\xa6\xb8\x21\x8d\xeb\x06\xee"
-  "\xb3\x2c\xfd\x76\xcc\xdb\x85\x76\xf4\x59\x82\x4b\x73\x0b\xf8\x7d"
-  "\x86\x60\x5c\x06\xeb\x23\x6c\x7b\xba\x9a\xca\x40\x9b\xc0\xa6\x7f"
-  "\x86\xd6\x6c\xac\x19\x7d\x4e\x2f\x50\x78\x03\xe2\x87\x32\x6f\x23"
-  "\x3c\x91\xd6\x93\x1e\x8b\x75\xa9\x7c\x56\x9b\xfa\x47\xfc\x5e\x2d"
-  "\xcb\x0b\xea\xe3\x93\xe2\x3c\x69\xc3\x2a\xe2\x09\xe2\x7f\x36\x30"
-  "\x1c\x70\x06\x10\x37\x82\xc3\xaa\x75\x6a\xc4\x5f\x91\xef\xf3\x30"
-  "\xa4\xe1\x6c\xbe\xd1\xc3\x08\xae\xbe\x92\xf3\x6d\x2e\xab\xa6\x3b"
-  "\x89\xac\x27\xc8\x36\x26\x9e\x8b\xfe\xbc\xe1\xf9\x29\xfb\xb5\x3f"
-  "\x9e\x32\x78\x0b\xea\xe5\x86\x83\x47\x87\xa9\x0f\xb5\xda\xe4\x32"
-  "\x63\xb4\x09\xaf\x1d\xf5\x41\x60\x98\xf1\xbb\x48\xc5\xfe\x0b\xab"
-  "\xbb\xc8\xa8\xca\x45\x1a\x95\x88\x0b\xd5\xe3\xad\xd8\xaf\xdc\x4f"
-  "\xfb\x6b\x10\x07\xb4\x83\x1b\x93\x6f\x74\x47\x27\xd2\xaa\xc3\x34"
-  "\x38\xfe\xb1\x0a\x3f\xfd\xbb\x58\xab\x98\x7b\x68\x1c\x3b\xff\xce"
-  "\x86\x59\x6d\x43\x1d\x2f\xd7\x7c\x70\x17\x2f\x83\xee\x6d\x74\xd6"
-  "\xe8\xd9\x67\x5d\x7a\x57\xac\x36\x81\xf4\x34\x5a\xe5\x33\xef\x84"
-  "\x3b\xb6\x67\xb3\xd0\x0d\x4d\x93\xa6\xee\xbf\x9f\x4d\x75\x2f\x5a"
-  "\x44\x6b\x9f\xed\x4a\xbe\xd7\x47\xf4\xab\x42\xff\xcf\xc4\xfa\xbd"
-  "\x42\xf5\x8c\xb6\x5d\x3f\xed\x99\xb0\xbb\x19\x1f\x2b\xf0\xbb\xac"
-  "\x51\x8b\xd1\x7e\x39\x9a\x87\xc3\x32\xdc\x63\x63\xd7\xb0\x32\x1a"
-  "\xdf\x8f\xd4\xbd\x05\xcb\x57\x95\xea\x2b\x68\x0f\x4c\xd6\x42\xa3"
-  "\x3e\x7d\x6e\xc9\x7c\xbe\x39\x46\xff\xd0\xf2\x25\xfa\x02\x1c\xd8"
-  "\x94\x65\xac\x15\x3f\xcb\x0b\x56\xd3\x6f\xc4\x5c\xa9\xde\x63\x69"
-  "\x8a\xe8\xff\x5e\xf7\x89\x3e\xb2\xc9\xe8\x50\x4c\x3f\x25\xe6\x94"
-  "\xe7\xa7\x20\x9f\x06\x5d\x89\x8d\x9d\xd2\x3e\xd8\x14\x7c\x37\xb8"
-  "\x12\xb3\xcf\xd1\x5d\xaa\x9a\xfd\xcc\xab\xf1\x4d\x64\x24\xa3\x74"
-  "\x87\x2a\xca\x90\xb3\xe1\x2a\x1f\x93\xc1\xca\x3b\x4c\x2c\xdf\xcf"
-  "\xec\xed\x57\xa9\xde\x9a\x7a\xe4\x3a\xe1\xf6\x2d\xc2\x45\xba\x47"
-  "\x09\x26\xd6\x75\x3c\xc1\x25\x1b\x17\xd3\x21\xfd\xaf\x9c\x14\xfd"
-  "\xf3\xab\x28\x4b\x8d\x46\x49\x86\x0b\xf0\x5b\xeb\x80\x85\x7c\x5f"
-  "\x51\xc0\xa2\x23\xdf\x01\xea\xc0\x81\x3b\xd7\xa1\x1e\x36\xc8\x30"
-  "\x11\x56\x82\x8c\x27\xc1\x83\xaf\x79\xf6\x2b\xd0\x94\xa5\x23\xbb"
-  "\x89\xce\x58\x68\x8c\x0a\xba\x47\xa0\x70\xcc\x36\xc4\x38\xd4\x81"
-  "\x64\x2f\x16\x4e\x75\x2b\xcc\x94\x26\x68\x53\x05\x1c\x0d\xca\x80"
-  "\x17\xfb\x58\xad\xb8\xd7\x74\x50\x9a\x33\x7e\xf5\x54\xf4\x7a\x7c"
-  "\x95\xef\x71\xbc\x6a\x51\x23\x6d\x4d\x05\xb3\x93\x45\x3b\x08\x58"
-  "\x14\x20\xce\xdb\xbd\xfa\x11\x5f\xc7\x14\x7b\x46\x66\x22\x7f\x5d"
-  "\x34\x3f\xa8\x41\xfd\x40\x7b\xe9\x02\x24\x3f\x70\x11\xec\xb5\x1e"
-  "\x33\xdd\x27\x2a\x8f\x29\x71\x7c\x14\xe8\x33\xf8\x31\x7e\x1b\xf7"
-  "\x2d\x84\xb6\x5a\x31\xb6\x27\xc5\x45\x78\xd5\x4c\xf8\xf3\x7a\xb4"
-  "\x40\x42\x00\x79\xc5\xd7\xec\x89\x3f\x49\x0b\x5a\x68\xef\x36\xd1"
-  "\xaa\xf1\x21\xcd\xa1\x74\x29\x03\x8e\x7a\x0b\xd2\xa5\x44\xba\x8c"
-  "\x97\x80\xb7\x55\xe3\xdf\xc8\x86\xb9\x35\xe8\x07\xbb\xb9\x23\x94"
-  "\xc6\x00\xf9\xaf\xe7\x34\x34\x7f\x12\x8d\x46\xa6\x24\x1a\x89\x07"
-  "\xcd\xb2\x4f\x76\x8e\x27\xd9\x0d\x83\xd0\xbc\x61\xea\x7e\xda\xcb"
-  "\x3e\x3f\x05\xfb\xe2\xe5\x54\x87\x6d\x16\x66\x25\x3c\xa3\xd5\x17"
-  "\xc1\x13\xb0\x5e\x2b\xd6\xec\x37\x17\x7b\x2c\xaf\x65\x44\xe7\xf7"
-  "\x6b\x6b\x6e\xcc\xef\xd7\x66\x51\x7e\xc2\x83\xf6\xf6\x6b\xc8\x49"
-  "\x03\xca\x37\xf6\x93\x87\xa2\x95\x3b\x75\x7f\x07\xe1\x15\x35\x0e"
-  "\x65\x7f\xb0\xa1\x2a\xbc\x4d\x04\xda\xe8\x9e\xef\x4b\xb4\xff\x1d"
-  "\xc4\x78\xef\xb5\xb3\xc1\xbb\x96\xe7\xaf\xd0\x28\xf4\x2a\xb2\x03"
-  "\xb8\x7e\x43\x7a\xa3\xc1\xd5\x28\xac\xe4\xe7\x65\x39\xea\x95\xa8"
-  "\xf1\xd8\x0e\xf4\x68\x53\xcf\x46\x78\x09\x53\xf7\x03\xc3\xb1\xe1"
-  "\xe4\xa9\x6e\x5f\x1a\xf1\x15\x71\x35\x62\xbb\xa6\xf1\xaf\x52\x8c"
-  "\x07\x8f\xa0\xfd\xfb\xd3\x2e\x3e\xde\x4c\x9c\x9f\x20\xd6\x3e\x8e"
-  "\x94\x39\xe0\x17\x63\x73\xb5\xf8\x6d\x74\xc0\xf5\xa5\xa2\xad\x4e"
-  "\x7f\x93\x35\x65\x1f\x0f\x58\x34\x4c\xbf\x57\x83\xe3\x9c\xd7\x13"
-  "\x71\xfc\xa1\x64\x49\xd9\xc7\x83\xb2\x23\xf6\xfe\xcb\xb2\x83\xf9"
-  "\x4f\x46\x97\x8b\x23\xff\x7e\x63\xb9\x38\xf2\x81\x34\xce\x28\x16"
-  "\xfb\x0b\x5e\x07\xb9\xff\xc0\x71\xc6\x9b\xfa\x3a\x2a\xff\x48\xb3"
-  "\x28\x1b\x79\xe2\xcb\x25\x3d\xb3\x1a\xf9\x86\xf6\xf1\xeb\x19\xb2"
-  "\x6e\x20\x19\xd2\xf8\xa9\xff\x02\x2e\xe7\x18\x97\x87\x7a\x44\x5a"
-  "\x3f\x5f\x7c\x10\x75\x1f\xb6\x85\xa6\x64\x97\xa9\xec\x2d\xda\x5f"
-  "\xe7\x4e\x9c\x7f\x08\xd3\xe0\x98\xe6\xbf\xf1\x3b\x88\x99\x76\xbe"
-  "\x19\x61\x1c\xe4\xeb\x55\xe2\xcc\x4a\x02\xb5\x73\xba\xef\x84\xda"
-  "\x3a\x86\x25\x23\xde\x74\xf7\x09\xf6\x35\xaf\x1f\x93\x6d\xfd\x80"
-  "\x25\x97\xf8\xcd\xcf\xc8\xe3\x78\x27\x65\x08\x79\xf7\x9a\x32\x70"
-  "\x7c\x78\xbe\x0e\x88\xe6\xe1\x03\xd3\x8e\xff\x5d\x26\xa8\xff\x8b"
-  "\xee\x69\x30\x2c\x84\xe4\xfd\x77\xab\xe1\x7f\xe6\x80\x92\xf8\xe0"
-  "\x80\xd7\x4f\x08\xde\xbd\xee\x96\xeb\xc7\x01\x47\x36\x53\x7d\xd0"
-  "\xf8\x3e\xdf\xc7\x86\xc4\x7c\x45\x0b\xf6\x7f\x2f\x4b\x77\x25\x37"
-  "\x55\x44\xe9\x13\x56\xea\xcb\xab\xf5\x25\xdb\x77\x57\xce\x9a\x15"
-  "\x36\xe7\xab\xe6\xf3\x77\x96\x96\x74\xb1\x86\xd2\xb2\x39\x64\x7c"
-  "\x8b\x7d\x5b\x0b\xd2\xdf\x94\x17\xd9\xaf\xae\x2e\x92\x8e\x68\x16"
-  "\x65\x41\xf0\x7d\x01\xac\x5e\x10\xf2\xb9\x08\x56\x2f\x5c\x54\xb4"
-  "\xae\x74\x4b\xc9\x9e\x90\xd0\xc5\xa1\x63\xa5\x86\x37\xb1\x6c\xd5"
-  "\xb4\x07\x51\x7f\x28\xd6\xbe\x40\x7d\xcd\x1b\x8f\xd4\xf9\xd8\xe7"
-  "\x28\xbb\x39\xe4\x17\xa1\xb7\xc6\x07\xbd\xa8\xdf\xd8\x74\xd2\xeb"
-  "\x13\x85\x6f\x30\x3f\xd0\x18\x46\x83\xb4\xbb\xb0\x7f\xbe\x26\xf6"
-  "\x97\xbd\xb1\xb3\xaf\x05\x6d\x1e\x6b\xb6\xb4\x7e\xfb\x46\x16\x86"
-  "\x27\xe2\xef\x46\xb1\x46\xf6\xc6\x93\x68\xa7\xe4\xf2\x73\xa0\xbb"
-  "\xe8\x1c\xe8\x1b\x2b\x89\x47\x99\x6e\x33\x08\x7f\x24\x2d\x4e\xf2"
-  "\x13\xea\x80\x37\xf8\x19\x1f\x4a\x8b\x79\x16\xe8\x9f\x83\x2c\xfa"
-  "\xa5\xf5\x66\x8c\xcb\x62\x8d\xd9\x03\xec\xad\x42\x5a\x37\x48\xc3"
-  "\xf0\xd7\x54\x8a\xcf\x40\xa5\x9b\xf8\xb0\xc7\xf2\x46\x33\xf2\xdf"
-  "\x29\xad\x1d\x44\x3f\x73\x20\xf5\x81\x53\x51\x77\x4f\x75\x6b\x58"
-  "\x11\x9d\xa9\x56\x90\x9d\x37\x88\xed\xb8\x80\xef\x7d\xa6\x3e\x51"
-  "\xe8\x83\x37\xc6\xe6\x7f\xe8\xac\x09\x7e\xbb\x65\x99\xf7\x58\xde"
-  "\x04\x59\x26\xc3\xf6\xca\x56\xd6\x94\x56\x95\x96\xe8\xe7\x56\x4f"
-  "\x86\x90\x1b\xa3\xca\x4a\x2b\xf5\x55\xa5\x3b\x76\x96\x56\xf3\xdb"
-  "\x9e\x28\x36\x62\x9e\x26\x69\x91\x6e\xec\x4e\x3e\xbe\x5f\xf7\xcd"
-  "\x52\xb2\xdb\x59\xd3\xa2\x16\x7e\x1f\x06\x9f\x5b\x79\x2f\x3e\x50"
-  "\x3f\x25\x57\x8c\xf9\xe8\x2e\xe5\xb7\xbc\x62\xdd\x22\xfb\xac\x98"
-  "\xef\x7f\xeb\x15\xfa\xc6\x70\x6d\xf0\x8e\xe9\x37\x3f\xa1\xf9\x15"
-  "\x89\x47\x68\xc3\xbc\x79\x52\xe6\x91\x03\x5a\x73\xa5\xb9\xec\x41"
-  "\xae\x2b\xb0\x8f\xd5\x88\x7b\x7a\xc6\xf4\xc5\xfc\x00\xf5\x53\x6f"
-  "\xd2\x9e\x0b\x15\x1f\x2f\x27\x66\xd3\x58\x52\x49\x30\x2f\x60\x7e"
-  "\xac\x8b\xb3\xa8\x27\x51\xd7\xb0\x43\x32\x3c\x2c\xf3\x38\x95\x47"
-  "\xfa\x03\xfb\xb9\xdb\x2e\xc2\x5b\x1c\x56\xc0\x9a\xdd\x4f\xfa\x83"
-  "\xce\x1d\x04\x1a\x11\x0e\x5f\x9f\x6b\xcd\xa5\x71\x3a\xbf\xaf\x06"
-  "\x61\xd1\xf8\x18\x75\x9a\xf3\xc3\xbd\x5e\x25\x85\x89\x3b\x8d\xde"
-  "\xa4\x79\x4d\xd4\x17\xd9\xa8\x77\xde\x32\x06\xe7\xb6\x5b\x73\x69"
-  "\xfe\x87\xe0\x3a\xe0\xad\xa5\x04\x4f\xec\x2d\x78\xab\xd5\x01\x2d"
-  "\x27\x83\xb6\xd3\x5b\x0e\xb9\x5f\x12\xf8\x08\x3c\xdd\x88\x0b\xbf"
-  "\xa3\x50\x9c\x91\xe2\x74\x93\xae\x6c\x96\x68\x97\xe9\x41\x78\x83"
-  "\x28\x77\x7c\x6d\x87\xf1\xb9\x64\x41\x37\xe1\x47\xb8\x87\xe2\x2c"
-  "\xe1\xab\x13\xf3\xf0\xad\x69\xa1\xf3\x54\xe2\x0e\x98\xd6\x9c\xe0"
-  "\xd9\xcb\x37\xcd\x91\x3a\xe2\xc1\x2d\x5b\xb7\xd1\x26\xd9\xd5\x59"
-  "\x19\x7a\xd2\x17\x45\xeb\x56\x2e\x7f\xac\x68\x79\xfe\xa3\x6b\x37"
-  "\xf0\x15\xf5\xb1\xf8\x15\x95\xd1\x13\x84\xcb\x95\x16\x65\x83\xd6"
-  "\x1c\xe3\xce\x43\x9b\x5b\xac\xab\xb4\x9e\x0a\x5f\x57\x69\x3d\x8b"
-  "\x8f\x0b\xe0\x68\x02\x3e\x6e\xec\x95\x30\xb8\xcd\x29\xc9\xcb\x20"
-  "\xe2\xeb\x0c\xca\x4b\x1b\xdf\xe7\x4b\xf3\xd9\x62\x9c\x7b\x14\xc7"
-  "\x1a\x6f\xe6\x84\xc6\x05\x6d\xfa\xa3\xfa\x31\x9b\x7e\x4c\x1f\x1c"
-  "\x5d\x2d\xdb\xf7\x18\x76\x0e\x6d\xfb\x89\x64\xdb\x0b\x3f\x81\x6d"
-  "\xfc\x9e\x65\x1a\x6f\xd0\xd8\x42\xa3\xa0\x7b\x81\x44\xfb\x24\x1b"
-  "\xaa\x08\xfb\x13\xba\x87\x9d\xc6\x19\xdc\x8e\xa7\x7d\xe3\xbc\x8d"
-  "\x1e\x3d\x24\xb7\x51\xb2\xe7\xf9\x3d\x72\xc3\xfc\xce\xf6\x2b\xd2"
-  "\xd8\x10\x98\xf6\xb8\x9b\xe6\x06\xd0\x2e\x3e\x43\x73\xb6\x34\x76"
-  "\x62\x89\xc7\xa5\xbd\x01\x47\xbb\x69\xae\x80\xec\x61\x3e\x5f\x64"
-  "\x69\x5d\xcd\xf7\x58\x1e\x98\xf6\x20\x9f\x33\xe3\x7b\x2c\x8f\x0e"
-  "\x06\x65\xae\xcd\x4d\x75\x49\x3c\x40\x39\xf0\xf2\xfd\x56\x63\x34"
-  "\xb7\x25\x8f\xd1\xbc\x0b\xe9\x1c\xe1\xe7\xfe\x26\x4a\x77\x5d\x73"
-  "\x1a\x63\xd1\x17\x9d\xb6\xb6\x92\xaf\xa4\xcd\x02\x71\xd4\x2e\x64"
-  "\x1a\xc7\xd3\xd7\x76\x3c\x82\xbe\x8a\xf1\xf4\xb5\xf5\x8c\xcd\x89"
-  "\x89\x36\x82\x63\xbd\xb6\x6b\x44\x27\xc9\x01\xd2\x79\x4e\xa5\x8b"
-  "\xbf\x3d\xe4\x3d\x23\x9a\x6e\x9d\xba\x5f\x29\x9d\xf7\x6f\x5f\x45"
-  "\xeb\x3d\x04\xeb\x55\x65\xa0\xec\x55\x0b\x3e\xf8\x4b\x3a\x36\x68"
-  "\xc3\x32\xaf\xc0\xaf\x3d\xaf\xcb\x38\x48\x7d\xb3\x37\xe6\x3e\x8b"
-  "\x5d\xec\x1c\xf1\x92\x78\x92\xef\x77\xdd\x4f\xfe\xaa\x3d\x96\x76"
-  "\xf3\x98\x6e\xce\xcc\xcc\x55\xed\x07\xfd\xe9\xd6\x85\x14\xde\xe2"
-  "\x80\x76\x90\xf6\x91\xb8\x23\xf3\x22\xbf\x73\xa5\xfc\x36\x39\x7f"
-  "\xa4\x1f\x39\x7e\xd0\xa1\x62\xcb\xae\xd2\x25\xfc\x0c\x43\xba\x74"
-  "\xf5\x5e\x78\xbb\x6a\xca\x50\xd2\xdc\x04\xd6\xfb\x44\x5a\x9b\x16"
-  "\xfd\x5f\x47\x19\xdd\x87\x8a\x71\x6a\xc6\xf7\xe9\xff\x90\xdf\x51"
-  "\x89\x75\xf4\x43\xbe\x77\xb5\x16\xa4\xf1\x47\xc7\xd2\x90\xf3\x0d"
-  "\x7c\x2f\x98\xbd\x96\xef\x9f\xc0\xfa\x69\x3f\x13\xdc\x13\xd6\x51"
-  "\x12\xa2\x3f\x12\x42\x71\xdc\x5e\xa9\x2f\xdb\x52\x59\xb2\xfd\x99"
-  "\x67\x32\xf4\x3b\x2b\xf9\xca\x00\x75\x2c\xd5\x35\x3b\x51\x3f\x70"
-  "\xbd\xb0\x62\xf5\xea\xa2\x07\x1f\x5d\xbf\x31\xcc\xce\x88\xb7\x5a"
-  "\x02\x68\x4f\x75\xe0\xf8\xe7\x15\x97\xe8\xc7\x3a\xba\x1d\xf0\xa2"
-  "\xb0\x79\xd1\x96\xc1\xba\x4f\xbd\x08\x6f\xa7\x85\xe8\xcb\xa9\xf8"
-  "\x9d\xc5\x2c\x1d\x35\x54\x17\x12\x5e\xbe\x50\xfb\x04\xdb\x80\xca"
-  "\x63\x79\x5b\x2b\xfb\xb3\xad\x99\x05\x4a\xf5\x2c\x2b\x34\x2b\x19"
-  "\xd6\xd1\xdb\xd9\xd8\xe7\x9e\xc3\xf8\x2c\xb4\x3b\x4b\xb8\x2d\x46"
-  "\x75\x22\x6c\x71\x9b\xc6\x77\x3f\xb7\xc5\x8b\xf6\x80\x82\xec\x70"
-  "\xb9\x7d\xf8\x71\x5c\xeb\xdf\xc5\x06\x8a\x7c\xa0\x25\x39\x6f\xa8"
-  "\x24\x59\x9f\xc9\x7c\xc3\xcc\x51\xb4\x27\x1e\xda\xf1\xbb\xfe\x22"
-  "\x40\x9f\xdb\x07\x4f\x5d\xc3\xf1\x08\xbe\x37\x5c\xc0\xb6\xe1\x0b"
-  "\x90\x63\x59\xda\xd3\x81\x7c\x7e\xfb\x98\x6c\xeb\x6a\xf6\xeb\xb9"
-  "\xbf\x41\x9a\x23\x27\x59\x20\x1b\xa0\xc8\xaf\xb1\x89\xf1\xef\xdb"
-  "\x3d\x37\x9c\xb7\x48\x6c\x6c\x89\x16\x8e\x38\x76\x11\x5e\x88\x67"
-  "\x27\xe2\x75\x82\xf0\xa9\x7f\x86\xe8\x52\x2d\xd2\xf8\xb2\xf8\x39"
-  "\x3b\xc2\xf3\x29\x37\x2c\x22\xfc\x9e\xda\xb1\x08\xda\x9e\xe1\xf2"
-  "\xc1\xd7\x20\xa5\xbd\x0d\x6a\x94\x9d\x89\x17\xe0\xa7\x66\x37\xbf"
-  "\xff\xe9\xa7\x85\x0e\x88\xef\x12\xf6\xb0\x98\xff\xa2\x34\x14\x27"
-  "\x64\xec\xa7\x66\x71\xe7\xee\x4f\xcd\x72\xba\x50\xdc\x96\x6f\x31"
-  "\xa0\x81\x59\xfe\xcc\x33\xa5\x55\xd5\xf2\x7d\x92\xe9\xdb\x2b\x4a"
-  "\x96\x49\x67\x73\x2a\x4b\x77\x17\x95\x97\xf0\xbd\x7f\x18\x2a\x5e"
-  "\x23\x6c\x91\x0c\x1a\x13\xf0\xfd\x34\xdc\x0e\xf9\xd9\xbf\xb7\x49"
-  "\x36\xc9\x79\x78\x87\x7c\x33\x63\xff\xfe\x4e\xa3\xe8\x1f\x26\x5d"
-  "\xf1\x58\xde\x89\x97\xfb\x87\xa1\x09\x39\x68\xeb\xbf\xa3\xc3\x3a"
-  "\xef\x0f\xd5\x59\x74\xfe\xd9\x56\x49\x7b\x00\x7e\xbe\x2c\xd0\x98"
-  "\xe9\x63\x49\xd3\x3b\xb1\x4d\xf2\xf1\x0d\xcd\x65\x09\x3f\xc1\xef"
-  "\x94\x90\x4e\xa5\x3d\x04\x74\xaf\xef\x00\xbc\x93\x8d\xb6\x08\xca"
-  "\xd4\xcf\x73\x5d\x89\x99\xbe\x83\x7b\x21\xfe\xe8\x11\x36\x40\x73"
-  "\x94\x62\x7f\xf1\x3b\xe6\x4f\xb0\x3d\x49\x6b\x14\x8e\x57\x30\xce"
-  "\x01\xef\x08\x9f\xf9\xd6\xf9\x5a\x69\x9e\x41\x8b\xe9\x8e\x3b\x20"
-  "\xe1\xa4\xe8\x87\xa6\xf7\xf3\xf9\x4a\xae\x77\xde\xe9\x61\x4d\x29"
-  "\x65\x7c\x0e\xa8\x69\x7a\x7f\x80\x95\xa9\xe8\x1b\xed\x9c\xc9\x08"
-  "\x27\x9e\xee\x71\x97\xf6\x4a\xa8\x90\xe7\x5e\xa2\x17\xe1\xea\xe8"
-  "\x7c\x38\x8d\xeb\x25\xf8\x3a\x1a\xb3\x63\xbf\xd2\x43\x7d\x0b\x4b"
-  "\xcc\x74\xb3\xe1\xc1\x0e\xec\xdf\xc8\xce\x74\x4d\xdd\xef\xc3\xf1"
-  "\x6a\xa6\x97\xdb\x9b\xee\x99\x0c\xfb\x3a\x3f\x3f\x97\xb6\x07\xa6"
-  "\x84\xdb\x99\xc7\x56\xcb\xf2\x17\xa0\xfc\xc3\x90\x80\x38\x9a\x07"
-  "\xe0\x18\xdf\xc3\x43\x73\xb7\xc4\xc3\x11\xe4\x1b\xf2\xee\x24\x96"
-  "\xd1\x89\xb6\xf1\x94\x0b\x70\xec\x25\xe2\x5f\x7d\x00\xe5\x7d\x84"
-  "\xdb\xcb\x1a\xba\xe7\xf4\x3c\x1c\xdb\x49\xbc\x23\x58\xcc\x9a\x72"
-  "\xc8\xe7\x29\x7c\x98\xfc\x57\x10\xed\xfb\x6a\xb1\x2f\x7a\x86\xe8"
-  "\x7f\xf7\x3a\xd9\x97\x68\x5b\xf3\x77\x53\x09\x0b\x70\xde\xf3\xfd"
-  "\x0c\xef\x5e\xdf\xe7\x64\x81\xeb\x16\x60\xdd\xd8\xab\x5f\x57\x82"
-  "\xcf\x8b\xe3\x40\x9a\xb7\x35\x5d\x22\x1f\x1b\x1d\x28\xdb\x87\x00"
-  "\xcb\x8d\xaf\xdf\x0b\x5a\xf2\x49\x62\x32\x30\x6f\x9f\xbb\x15\xfa"
-  "\x0c\xad\xf0\x07\x5f\x33\xd8\x76\xd1\xda\xe0\xcf\x3a\xfe\x68\x6c"
-  "\xa6\xfd\x63\x93\xf0\x7d\x8b\xfe\x31\x5e\x56\xce\x1f\xcf\xfe\x1b"
-  "\xfc\xd1\xf6\x6f\xa0\x7f\x82\x7f\xe7\xf5\x14\xfe\x01\x7a\x72\xff"
-  "\x00\xa6\x01\x16\x20\x1b\xa5\xee\x79\x2a\xe3\x10\xc2\xea\x20\x5f"
-  "\x1e\xda\xc0\x90\x6e\x32\xd2\xaf\xce\x37\x52\x7b\x77\xa1\x2c\xfd"
-  "\x0b\xe1\xf8\xfb\xb6\xab\x10\x6f\xab\xfc\x2d\x7f\x17\xb6\xc3\x60"
-  "\x87\xbd\xa4\x9f\xaf\x25\x93\xef\x12\xba\x1b\x18\xfb\xde\x40\x03"
-  "\xe1\xe8\x17\x78\x23\xbf\xd4\x72\xfe\xf6\xba\xb1\xfc\xdc\x57\xea"
-  "\x51\xe2\x07\xe2\xd4\xbb\x41\xf0\xa4\xa7\x1f\x79\xfa\x98\xc4\x9f"
-  "\xc2\x50\xfe\x1c\x73\x12\x7f\x68\x9f\x48\x60\xd7\x60\x07\xe2\x96"
-  "\x8b\x3c\x08\xc8\x65\x50\xfd\x23\xae\x8c\xe0\xd7\x5f\x85\x04\x5b"
-  "\x25\xed\x23\xf9\xd9\x1a\x4d\x81\x3a\x3e\x30\x7c\xa9\xb3\xe1\x1a"
-  "\xf0\x39\x5c\xea\x87\x1a\x78\x3c\xc1\xfc\x19\xad\x09\x6a\x5d\x89"
-  "\x77\xb9\xf0\x71\xe3\xe3\x25\x39\xc4\x5f\x1f\xd6\xd7\x21\xc4\xa1"
-  "\x1b\xeb\xaa\x83\x7e\x85\x8c\xa7\xa6\x93\x5f\x27\xc9\xb6\x08\x86"
-  "\x37\xa5\x7e\xdf\x87\xb2\x1c\xe0\x63\xa5\x77\xbb\x03\x8d\x39\xfd"
-  "\x62\x4f\xc1\x4f\x0f\x1f\xc5\x7e\xa5\xb5\x89\x9f\x5b\x4b\x68\x4b"
-  "\xe2\xf7\x83\xc2\x9b\x7c\x7f\xeb\xcf\xc6\xfa\xff\x9f\xf0\x7b\x47"
-  "\xdf\xf5\x2a\xf9\xda\xf1\xfc\x64\x49\xce\x93\x31\x8d\xcb\x01\xb7"
-  "\x38\x44\x9f\xf1\x33\x9f\xdc\xa6\x50\x5f\xbb\x64\xf9\xc7\x76\x8a"
-  "\x78\xa3\xbc\xf3\xb9\x47\x1c\x1c\xfa\x66\x8e\xcd\x3d\x0a\x39\xff"
-  "\x79\xb6\x2c\xe7\x48\x5b\x02\xe9\x0b\x6a\xdb\xb1\xfa\x7d\xd4\xab"
-  "\x3d\xb4\x9e\xcf\xa6\x17\x42\x02\xda\x4b\x09\xc5\x1a\x66\xf7\x75"
-  "\x91\x1c\x26\xf0\xf6\x23\xe2\xd0\xde\x71\x69\x50\x17\x9f\xc1\x70"
-  "\xb5\x1c\x4e\x7a\x39\x80\x63\x44\x1a\x9f\xe6\xef\xd1\xb0\xba\x6b"
-  "\x90\xc2\xe7\x7a\xe4\xf0\x3d\x2e\x4d\x9f\x0e\x68\x7f\x9f\x8f\xce"
-  "\xbc\x52\x1e\x0c\x57\xa1\x1e\x3f\x85\xe5\xda\x30\x7d\xb2\x9c\x9e"
-  "\x0d\x15\xaa\xed\xc6\x2e\x4e\x03\xf9\x71\x90\xf5\x3a\x86\xc7\xe5"
-  "\x1b\x5d\x1a\x5e\xef\x72\x58\x75\x21\xef\x87\xe8\x7c\x1d\xda\x57"
-  "\x8c\xe3\x73\x81\x87\x2b\xd0\x6e\xe3\x77\xa3\x86\x84\x29\xe9\x2c"
-  "\x23\xf9\xe0\x09\x09\x53\x21\xce\x30\xf6\x8d\x65\x37\x3c\xc7\xed"
-  "\x48\x5d\xfe\x1e\x84\x47\xe5\x3c\x27\x95\xbd\x87\x81\xf0\xed\x25"
-  "\xc2\x44\x9f\x77\xbc\x65\xcc\x66\x24\xfb\x67\xa8\x90\x97\x1d\x18"
-  "\x2a\x54\xfa\x87\x0a\x55\x54\x3e\xc1\xa2\x79\x46\x7e\x47\xab\xcf"
-  "\x09\xe4\x57\x92\x35\xbe\xa7\x65\xb4\x9f\x13\xe1\x72\x7c\x8c\x38"
-  "\x8e\x4f\x7c\xcf\x1a\x7d\x3d\xf1\x48\xb7\xad\xee\x09\x6c\x17\xef"
-  "\x91\xec\x83\x5f\x9b\x15\xaf\x7f\x8e\xd6\x80\xde\xfb\x1e\xc9\xa0"
-  "\x1f\x75\x85\x3f\x31\x2b\x7e\xbe\x13\x14\x75\xd8\xfe\xc4\x38\xef"
-  "\xbd\x7b\xc9\x07\x92\x29\xc0\x18\xbe\x67\x90\xfc\x6b\x06\x69\x1d"
-  "\x30\x2b\x81\xaf\xbd\x25\x35\xd9\xec\x5e\x27\xf4\x98\xff\x02\x3d"
-  "\x3e\xbb\xf9\xd4\x55\x97\x5a\xac\xc1\xa9\x09\xee\x1a\x8a\x33\x61"
-  "\x9b\x2b\xf2\x77\xc4\x9c\x8b\x23\xfb\x17\x79\xf7\x57\xa1\xdf\xdf"
-  "\xeb\x90\xed\xde\xaf\xa0\xc1\x4b\x7e\x94\x68\x8d\x3e\xd0\x64\xa0"
-  "\x71\xae\x89\x79\xd2\x61\xfe\x5e\x1a\xf7\xbe\x77\x66\xaa\x1b\x72"
-  "\x25\xb8\x57\x24\xb8\xde\x1b\xc1\x25\xb9\xed\x69\xe1\x73\xbf\x48"
-  "\x93\xa1\xd3\x8f\xb0\xfd\x49\x06\xda\xc3\x67\x32\x5d\xa7\x39\x90"
-  "\x5f\xae\xc4\x72\x3a\xfb\x7c\x67\x80\xfc\xb1\xb5\x05\xb0\xbf\xbd"
-  "\xa2\x03\x69\xbd\xd1\x74\x19\x7e\x71\x47\x80\xa5\x6b\xd1\x3e\xa7"
-  "\x39\x4f\x13\xe9\x6a\xb2\xf5\xeb\xfc\x30\xc1\x5e\xe3\x00\xf2\x27"
-  "\x84\x30\xee\xfd\x1d\xcd\x2f\xa3\xbe\xf3\x33\x9d\xf2\xd7\xc3\x0e"
-  "\x68\xc0\x3e\x80\xfb\x17\x3a\x30\xfd\xcd\xa9\xfb\xe1\x7e\xa6\xd4"
-  "\xf0\xf5\xe4\x40\xa3\x15\xc7\x37\xef\xe9\xc4\xfa\xe6\x7c\x7d\xc8"
-  "\xda\xa6\x0a\xcb\xfa\x80\xd6\x36\x99\x36\xd3\xd9\x4a\xf3\xbd\x89"
-  "\x4d\x1d\xae\xc4\x46\x2b\xc3\xba\xf3\x58\x7e\xe1\x70\xc0\x71\xde"
-  "\xaf\x1f\xa6\xbd\xb4\xbc\xcf\xf8\xe5\x1a\x57\x62\x05\xdd\x89\x45"
-  "\x77\x2d\x29\x02\xbb\x7c\x9d\x0d\x5f\xa2\xfd\xc2\xf9\xf2\xcb\x79"
-  "\x7d\x83\x1e\x1b\xb3\x56\xb4\x50\x7b\x92\xca\xd0\x60\x19\x7e\xd6"
-  "\x58\x81\x32\xf9\x4b\xa9\x6f\xe6\xef\x3a\x8a\xf7\x8d\xd2\xde\xdf"
-  "\x5f\x1c\x6e\x1d\xa1\x39\xb6\x5f\xe4\xa0\x7d\x67\x1b\xd2\x56\xb4"
-  "\xac\xd7\x99\xb1\x7f\xff\x65\xb1\x43\xf9\xe7\xd5\xd2\x98\x9b\xfb"
-  "\x4c\x8a\xb9\xbe\xfd\x96\x6e\xb2\x1d\x81\xa0\xad\x9a\x7c\x11\x3e"
-  "\xf8\xd3\x88\x05\x94\xa3\xd8\x47\x8f\x28\xd1\x4e\x7f\xab\x30\xa1"
-  "\x7e\x1a\x64\x61\xdc\xb4\x8b\xf0\xcb\x7f\xf4\x29\x21\x19\x1f\xad"
-  "\x6b\x7a\xd9\x24\x84\x9b\x4b\xf3\x11\xbd\x57\x69\xfc\xf9\xbe\x38"
-  "\x27\xfc\x26\xa4\x05\x10\x1e\xcd\xa3\x36\x4c\x83\x34\x9a\x13\xc0"
-  "\xb0\xf4\x22\xbf\x58\x63\x90\xc7\x2f\x07\xa6\x41\x46\x78\xb9\xbf"
-  "\x94\x7c\x21\x7d\xc0\xef\x8c\xdb\xed\x82\x19\x86\xfb\xd8\x79\x84"
-  "\x4b\x3e\x68\x19\x9b\xae\x53\x8a\xb5\xb8\xf7\xf7\x68\x5a\x84\xfc"
-  "\xf1\x39\x75\x94\x3b\x5a\xb3\x90\xe6\x6a\x15\xdc\x57\x54\x52\x76"
-  "\x0b\xed\xbd\x0c\x99\x93\xd1\x72\x3c\x24\x3f\x2f\xfe\x03\x77\x16"
-  "\x13\x0c\xc2\xa7\x68\x8b\x98\xe7\x25\x1f\x30\xc8\x57\xee\xc7\xf7"
-  "\xf0\x9b\x90\xf0\xf2\x9b\xa0\xed\x7d\x86\xd3\x75\x5c\xb4\x49\x35"
-  "\x10\xbe\x01\x2b\xb5\x37\x94\x0d\xc4\x9b\xca\x23\x19\xe9\xf3\x5d"
-  "\xb1\x99\x6a\x58\xc0\xf6\x1c\x9d\x3f\x7c\xff\x0b\x5b\xd5\xfb\x90"
-  "\x4f\x3e\x73\xe8\xdc\xfc\x66\x70\xb5\x23\xbc\xf6\x69\xa0\x45\x58"
-  "\xd7\xec\x15\xa4\x73\x75\xb3\x6d\x55\x27\x10\xf6\x07\x93\xa8\x6f"
-  "\x7b\x05\xf9\x23\xfa\xb8\x0f\x4e\xd9\xbd\xfd\x40\x3e\x72\xd7\x1a"
-  "\x98\x9f\xe0\x60\x9a\x07\x38\xbd\x6f\xe9\xf4\x45\xc2\x4f\x0f\xa7"
-  "\x75\x6c\xfe\x5c\xa2\xc3\x7e\x95\xc3\xdb\x60\x2f\x46\xbb\x5c\xa2"
-  "\x49\xe6\xb5\x90\xaf\x0f\x1a\x6d\x55\xc7\x80\xea\x87\xd2\xe3\xb7"
-  "\xd9\x3e\x88\x69\x2f\x85\xd7\x0b\xa5\xc1\xb8\x8f\x10\xee\x3d\xc1"
-  "\x75\x21\x5a\xaf\x08\xa6\x69\x45\x7a\x90\x57\xee\xb7\x90\x47\x62"
-  "\x1e\xed\x83\x54\xc2\x15\xeb\x2e\xc5\x5e\xf3\x97\xe8\x7b\x9e\x51"
-  "\x07\xa0\xdc\xef\xef\xe3\x73\xe1\xbf\x9a\xb2\xd6\x17\x60\x42\xaf"
-  "\xfd\xca\x86\x36\x60\xa7\x03\x7f\x49\x27\x70\xbd\x92\x49\xfe\x97"
-  "\x7e\xf5\x89\x46\x21\xea\x97\x68\x21\xfb\x2b\x5a\x1d\x87\xcc\xd3"
-  "\x6b\x09\x57\xb9\x8e\x99\xf6\x48\x77\x80\xd6\x5f\xa6\x21\xbf\x47"
-  "\x75\x20\xe4\x8f\x59\x11\xee\x47\x92\x8d\x5b\x22\xf5\xcd\x25\x43"
-  "\x89\x59\xc9\xec\x05\x1d\xc8\xfb\x1f\xb0\xfd\x6a\x8b\xc4\x9e\x12"
-  "\x1d\xe9\xaa\x76\x25\x93\xee\x39\xf9\x95\x4d\xca\x5b\x2c\xfc\x8e"
-  "\xfd\xca\x8c\xf9\x8b\xa3\xd2\xab\x9a\x46\xbe\x56\x4d\xe4\x93\x88"
-  "\xaf\x93\xa3\xce\xc2\x7e\x61\x82\xdd\x3d\xc2\xcf\xa8\x5c\x80\x0f"
-  "\x97\xd1\x7d\xb5\xb4\x0f\x5d\xc6\xed\x9b\xcd\xa9\x7f\x18\x2f\xe6"
-  "\xd6\x3e\xcc\x93\xc7\x8d\x4c\x8b\x3c\xb6\x68\xb8\xbf\x54\x5a\x77"
-  "\x75\x27\x1e\x41\x9b\xe2\x3d\x10\xed\xe6\x43\x03\x4b\x14\x7a\xb7"
-  "\xc8\x0b\x66\xa2\x4b\x1a\x3f\x4d\x20\x9a\x11\x8e\x15\xc7\xb4\x2b"
-  "\x84\x6d\x21\x60\xc7\xf4\x41\x2c\xd3\x86\x34\x89\xf3\x4b\x47\xba"
-  "\x39\x6d\x74\x06\x97\xd3\xd6\x39\x85\xcf\x65\x7d\x33\x7a\xfa\x05"
-  "\x6f\x8f\x9c\xb1\x4d\x23\x18\x1f\xbd\xcb\xf7\x07\x61\x9d\x88\x39"
-  "\xc7\xce\x62\x36\xf9\xe5\xc9\xdf\x0c\x66\xa7\xd8\x57\x6c\x7d\x0f"
-  "\x5e\xa3\x3b\x02\xf8\x9e\x64\x3a\x37\xf2\xd1\x2b\xa8\xd3\xf9\xf8"
-  "\x64\x08\xcb\x43\xf9\x08\xd1\x43\x1f\x69\xa9\xae\x32\xdf\x87\x5c"
-  "\x21\x87\x1f\xc5\xd1\x9c\x92\xf0\x11\xdf\x79\x02\xe5\x5e\x9a\x93"
-  "\x93\xf7\xca\x28\xf8\x5e\x99\x50\x1d\xfb\x0d\x71\x14\x77\x64\x26"
-  "\x59\x0d\xf8\x7e\x8c\xef\x11\x44\x7c\x77\xfb\x64\xfd\xd7\x79\x8c"
-  "\x0d\xb3\x01\x9a\xf3\x23\xfb\xa9\x88\x74\x59\x9d\xf0\xe1\xe1\xb1"
-  "\x7c\xb4\x42\xb6\x55\xc8\xb6\xa6\xbd\x50\x94\x0e\xeb\xfe\x0a\xa5"
-  "\x11\x3e\x06\x2e\x4a\xe7\x19\x3e\xda\x28\x9d\x55\x48\xa7\x7d\x4a"
-  "\x98\x17\xf5\xdd\x59\x5e\xdf\xc4\x03\x2a\x9b\xe3\xae\xa4\xf9\xac"
-  "\x8f\x5a\x83\x73\xac\x9d\x7c\x5f\x94\x38\x6f\xf4\xd1\x09\x59\x46"
-  "\x90\xde\x09\xc2\x2f\x70\x67\xea\xe9\x0c\xe0\x32\x30\xc4\x74\x93"
-  "\xe7\xb4\x92\x4c\x7e\x74\x2e\x94\x4f\xf9\xbe\x80\x49\xe8\xa0\xce"
-  "\x2e\xc6\xdb\x7a\x67\xd7\x57\xdb\x15\x7f\xbf\x40\xb6\x49\x04\x9f"
-  "\xb5\xa8\x5f\x4e\xf8\x38\xaf\xad\x29\xdd\xe4\xcb\xeb\x85\x3a\xf2"
-  "\x47\xf8\xf7\x5f\x92\xaf\x47\x9f\x35\xc5\xe9\x37\xe9\xc8\x8f\x3c"
-  "\x04\xac\x29\xde\x0b\x06\x50\x16\x19\x68\x5e\xb9\xa2\x98\xc6\x8b"
-  "\x38\x1e\xd5\xb2\x24\xb4\x53\xb0\x9d\xef\x2b\x07\xcd\x93\x65\x08"
-  "\xdb\x94\x9e\x4c\xbe\x18\xc9\x0f\x23\xf9\x52\xf5\x9b\xd2\x93\xf0"
-  "\xfd\x56\xb4\xeb\xb4\x4c\x9b\xd2\x4f\x6b\xd3\x7e\x0b\x43\x7d\x7c"
-  "\x8e\xfc\x41\x2a\xed\x2e\x2f\xec\xbb\x04\xf1\xe4\xeb\xd1\xd7\x58"
-  "\x61\xec\x73\x7f\xca\xc7\x4a\x53\x0d\x90\x8c\x76\x48\x0a\xf2\x5c"
-  "\x17\x48\xac\x28\xc6\x3e\xbe\x44\xd0\x7d\x85\x09\xba\x05\xde\x84"
-  "\xbf\xd0\x71\x33\xbc\x75\x1c\xf7\x13\xaf\xf9\x10\x7e\xc0\x3a\xc7"
-  "\xed\xb7\xce\x71\x89\x33\x33\x3d\x50\x57\xc3\x9c\x76\x77\x0f\x8e"
-  "\xdf\xae\xf1\xbb\x2f\x68\xed\x9b\x68\x24\xfa\xa8\xec\x3f\x5e\xbd"
-  "\xc4\x7d\x57\xfa\xf0\xdb\x54\x21\xe5\x19\xc4\x3c\x83\x3d\x30\x62"
-  "\x9d\xc3\x69\xef\x73\x8b\xbc\x45\xfc\x9d\xf2\x87\xf0\x41\xa2\x79"
-  "\x8c\x0f\x48\x3b\xd1\x47\xf4\xfb\x88\x27\xc8\x03\x89\x56\xdd\xa8"
-  "\x44\x27\xd1\xf8\x07\xec\x75\xde\x44\x3a\x91\x56\x4e\xe7\x28\xd2"
-  "\xd9\x5d\x06\xe0\x6d\x3a\xe2\xb8\x9e\x34\xc7\x45\xe3\x5d\xd3\x9f"
-  "\xd0\x96\xaf\xb5\x02\x8e\x6b\xd5\x1f\xd4\x59\x95\x3f\x41\xdb\xa4"
-  "\xce\x85\xe3\x5b\x17\x73\xf6\x21\x4d\x76\x03\x3e\xbe\x56\x20\x1b"
-  "\x47\xb6\xdb\xb1\x6c\xdd\x1f\x03\x7f\x83\x3a\x27\x73\xa2\x8d\xea"
-  "\xb5\xfb\x30\x4d\x19\xd2\x8f\xe3\xe1\x0b\x12\xfe\x94\x76\xdf\x97"
-  "\x82\x2e\x4d\x05\x24\x7f\xfc\xc4\x21\xa5\xbd\xff\x10\xc8\xb4\x3c"
-  "\x85\xe9\x90\x1e\x1d\xc2\xe2\x77\x2e\x06\x90\xce\xb7\x10\x4f\x6f"
-  "\x08\x4d\xbd\x83\x5e\x84\xf9\x67\x98\x5c\x00\x8a\x37\x2f\x23\x1d"
-  "\x97\x41\x67\xad\x43\xfb\x6b\x1d\xd9\x8d\xff\xd0\x7b\x53\x21\xa4"
-  "\x39\xe0\xef\xc5\x7d\x5d\xc2\xb7\xdc\x2d\x17\xe1\xc4\x35\xd9\x7f"
-  "\x5c\x80\xfc\x6f\x26\x56\xd4\xfe\xbf\xec\xbd\x7f\x40\x54\x55\xde"
-  "\x3f\x7e\x66\x40\x25\x45\x19\x08\xd9\x51\x29\x47\xc5\x9e\x69\x97"
-  "\x04\x4b\x4d\x7b\xdc\x8d\x12\x7b\x2c\x7f\xd6\xaa\x0f\xb5\xfe\x80"
-  "\xc2\x16\x0d\x6d\x44\x44\x54\x04\xc4\xe2\xb1\x4d\x71\x30\x74\x51"
-  "\x11\xe9\x59\xeb\xc1\x16\x8d\x9e\xb5\x16\xcb\x74\x4c\x6c\xd1\x80"
-  "\x21\x97\x7a\xc8\x25\x1b\x09\x0d\x09\x75\x92\x01\x46\x98\xb9\xf7"
-  "\xfb\x7e\x9f\x73\xef\xdc\xb9\xe3\x0c\x38\xa6\xd9\x7e\xf6\xfb\x07"
-  "\xdc\x39\xe7\x9e\x7b\xee\xb9\xef\x73\xce\xeb\xbc\xdf\xef\xf3\x3e"
-  "\xef\x37\x8e\x23\xea\x4b\x0e\xd7\x8c\x0e\x18\x33\xb8\x47\xbd\x0a"
-  "\xde\xd1\xa1\x0d\xa1\xed\xc9\x62\xfe\xe7\x20\x8d\xbe\xb0\xd1\x1e"
-  "\x5d\x01\xcf\xa5\xf2\x40\x33\xac\x1f\xf8\xb9\x78\xbc\x22\x0d\xdd"
-  "\xda\x0e\x1d\x20\xe3\xe1\x9d\x1a\x94\xe5\x4b\xd3\xcd\xca\x57\x0f"
-  "\x90\x70\xef\x30\xe5\xfd\x30\x4f\xf8\x8d\x3a\x49\xac\x0f\xbe\x2d"
-  "\xa8\x99\x7c\x70\x97\x7c\x8e\x69\x28\x96\x31\x1c\x7c\xbf\x06\x75"
-  "\x7e\x5e\xbe\x97\xf9\xad\xcc\xe2\x37\x7a\xf9\x5c\xad\xd8\x0e\xf8"
-  "\xed\x31\xd6\x88\xf7\x74\xf8\x20\xdc\x53\x5d\x9b\xb7\xd3\xb3\x71"
-  "\x19\x39\xdb\x01\x2f\x80\x57\xc0\xd8\xee\xc8\xd7\x95\xef\xb5\x90"
-  "\x15\xbb\x89\x5f\xc6\x25\xd4\x31\x4d\x27\xc7\x0b\x22\x49\xe1\x55"
-  "\xf4\x09\xa1\x0d\x7a\xe3\x2a\xee\x33\x32\x0c\x41\x9e\x14\x75\xa7"
-  "\xfc\x0a\xad\x6a\xcb\x76\x91\x87\xff\xa0\x2d\xad\x8d\x28\x59\xbc"
-  "\xd1\x0f\x2c\xd1\x1a\xde\x96\xa7\xe4\x12\x0a\xd0\xb7\x62\x90\x1e"
-  "\xe3\x45\x25\x88\xbe\x06\x29\xef\x93\x0a\x73\xae\x55\xdd\x77\x73"
-  "\x12\x09\x47\xbf\xa8\x01\x66\xc6\xcb\xb1\xf5\xfa\xaf\x61\xd0\x3e"
-  "\x95\xb0\xb7\xa6\x62\xfe\x07\xdf\x4f\xdc\x73\x95\xea\x3b\xf1\xfe"
-  "\x1c\x3b\xc8\x32\xb4\xde\x24\x12\x56\x70\x95\x68\x91\x0f\x5a\x78"
-  "\x9e\xf1\x6c\x28\x1f\x4e\x6f\x09\xe0\xed\xdf\x6b\xc9\xee\x66\xc9"
-  "\x6f\xaa\x79\x05\xfa\x5a\xe5\xd5\x9e\xce\x03\x6e\x09\xa1\x7b\xe9"
-  "\xd4\x17\x16\xda\x07\x40\x9a\xe4\x6d\x25\xbe\xc7\x43\x09\x41\xbd"
-  "\x21\xee\xcb\x1d\xb7\xb1\xf3\x18\x1d\x59\x7f\x2d\x17\xfd\x4a\xba"
-  "\xc7\xf2\xad\x45\x11\x94\xc7\xda\x5a\xe4\x5d\xbf\xfd\xb5\xd1\xa3"
-  "\xac\x02\x75\xe2\x38\xb8\xb9\x7a\xcb\x26\x76\xc3\xd7\xf8\x72\x7a"
-  "\x26\x9b\x71\xbd\x41\x66\x34\x77\x18\x98\x3f\xa4\xb2\x32\xe3\x2b"
-  "\x9c\x93\x3c\x56\xb6\x03\xef\x61\x1e\xfa\x98\x88\xa2\xfd\x5e\x66"
-  "\x42\x19\x4d\x90\x73\x8f\x6a\x1c\x79\x8c\xdf\xc2\x75\x17\xe9\xb5"
-  "\x87\xf9\xac\x1a\xd0\x91\x55\x66\x13\xd7\x5e\xe4\x41\x98\x3e\xfa"
-  "\x90\xca\xa4\xfc\xbf\x57\x3c\xd1\x12\xf7\x4c\xa8\xff\x2c\xb4\x75"
-  "\x41\xbf\x96\x59\x87\xa2\xc4\xb5\x98\x9e\x73\xdd\x30\xf8\xf1\x15"
-  "\xab\x49\xe8\x6f\x07\xf9\x11\xdc\x97\x82\xb2\x4d\x8c\x47\x38\x94"
-  "\x20\xe9\xf0\xa3\xe8\xd8\xc0\xf3\x52\x54\x1e\x42\x3f\x44\xcc\x9f"
-  "\x6b\x8b\xe8\x8f\x88\xf1\x0a\x87\x5e\x75\x7a\x4f\xb1\x63\xcd\x87"
-  "\x77\xe0\x7e\x2f\xd6\xcf\xf8\xa8\x43\xf3\xa8\xcd\x3d\x94\x63\xbc"
-  "\xc0\xa1\x79\xdd\xd0\x57\x8b\xf4\xe5\x04\xd9\xd7\xd8\xf2\x1d\xa3"
-  "\x6f\x2a\xf1\x41\xbb\xd6\xa3\xe9\x26\xdf\x01\xcc\xcf\x60\x00\xbc"
-  "\xff\x1a\xde\xc7\x79\x69\x18\x85\x7a\xd0\x0f\xe7\x18\x91\xc7\xe8"
-  "\x8a\xf1\x9f\x81\xfa\x09\x2a\x37\x7c\x18\x8d\x36\xa7\x90\x17\x74"
-  "\xe4\xb2\xd5\x77\xcb\x1a\x12\xce\xfc\x3a\x7d\x48\xcf\x89\x99\x7f"
-  "\xf1\x52\xc7\x88\x60\xa2\x1e\x91\x47\xb4\x1d\x59\x1f\x26\x82\x2c"
-  "\x6c\xa0\xfa\x36\x7c\xff\xd6\x7d\x91\xd4\x06\xb6\xd3\xd4\x8b\xf5"
-  "\xd5\x47\x77\x41\x5a\x2b\xa5\x3f\x7c\x4b\xd8\xbf\x01\xbe\xe8\x23"
-  "\xbf\x3d\x97\x29\x2f\x55\x43\x75\x62\xfa\xdc\x7c\xc9\x7e\xe0\x23"
-  "\xe6\x87\x03\xae\xc7\x75\x84\xa0\x3d\x69\x61\x08\x5f\x03\xef\x03"
-  "\xfe\xe7\x50\xa8\xa0\x43\xaa\xa1\xe3\x0a\x79\xf3\x6c\x94\x17\xbf"
-  "\x33\xa0\x4d\x2a\xae\x69\xc0\xcb\x45\x31\x79\x23\xb7\x94\x83\xf1"
-  "\x23\x7d\xff\x87\x2b\x51\xcf\xea\x16\xbf\x77\x12\x42\x9f\xc9\xd5"
-  "\xd7\x51\xbb\x93\xdc\x7d\x1b\xe1\xea\x07\x73\xa1\x18\xae\xfe\x30"
-  "\xe6\xf0\xaa\x82\x6b\x11\x5c\x83\xe1\xbe\x0e\xc7\x25\xc8\xdb\x6a"
-  "\x8c\xc7\xd3\x1a\xa8\xaf\xf1\x64\x3b\x8e\xb4\x31\xbe\x32\x97\x30"
-  "\xdb\xba\x8f\x5a\x30\x16\xcb\xcc\xdd\x84\xac\xb0\xf1\x9d\x9a\x7b"
-  "\x49\x1f\xf8\xde\x96\x8c\xdd\xb8\x07\xfe\x91\x41\xbe\x07\xfe\x91"
-  "\x89\x90\xc3\x1a\xf8\x83\x9c\xc3\xc0\x47\x7e\xd4\x22\xfd\x1d\x36"
-  "\x75\x64\x7d\xd4\x02\x74\x64\xbe\xa6\xbc\x9a\xaf\x1f\xd1\x18\x79"
-  "\x5b\x50\x86\x0b\xd4\x15\xb1\xef\x2d\x36\x41\xda\x8f\x0f\xdc\xa7"
-  "\x11\xbe\xb7\x0c\xd2\x2a\x4d\x06\xac\xc1\x81\x40\x93\xc1\xf0\xcd"
-  "\x81\xfb\x36\xe2\xf7\x62\x7b\x5b\x03\xb7\x16\x3b\xdb\xcd\x63\x9d"
-  "\xf8\xfd\xe6\x40\x78\x0e\x68\xc9\x8f\x1a\x15\x25\xd2\x53\xa0\x13"
-  "\xda\x1a\x2b\x5b\xa1\x0e\xc6\xb3\x41\x79\xa8\x43\x2c\xef\xa0\xfd"
-  "\x60\xf4\x91\x02\x7d\x0a\xe5\x40\x7e\xf7\x13\x6d\xf2\x3b\xb2\x0e"
-  "\xd7\x1d\x4b\x64\xfb\x2a\xf8\xac\xc5\xe9\x59\x3c\x07\x2d\x7b\x3e"
-  "\xd0\xa9\xef\x06\xa3\xaf\x80\x44\x3d\xeb\x3b\xbd\x49\x68\x4b\x30"
-  "\x6b\x4b\x2e\xc8\xad\x1f\x5d\x62\xed\x39\x5c\xe9\x69\x8e\xa5\x0f"
-  "\x03\x1e\x15\x38\xf7\x08\x26\xbb\x4e\x34\x86\x5a\x88\xb1\x80\x03"
-  "\xbe\x25\xb7\x26\x2a\x9d\x37\x5c\x20\x1f\xbf\x55\x6d\x6d\xf2\x72"
-  "\x4d\xff\x98\xc5\x48\xeb\xcc\x24\xc6\xb4\x07\xa9\x2c\x79\x99\x1c"
-  "\xf9\xc2\x68\xa6\x67\x94\xf0\x37\xb5\x87\xc4\xfd\x69\x5c\xdf\xd0"
-  "\xf7\xaf\xa8\x27\xe0\xa0\x6c\x21\xe6\x43\x1e\x9e\x9b\xdc\xe3\x74"
-  "\x8f\xdf\xaa\x2f\x63\x73\xed\xc8\x66\xe4\x8f\x68\x7b\x6d\xff\x61"
-  "\xc0\x36\x73\x7a\x7d\x19\x7e\x43\x06\xda\x0e\xdb\x3a\x0c\x38\x57"
-  "\x34\x29\xa8\xf7\x3c\xb2\x18\xc6\x23\xcf\xe5\xea\xcb\xbc\xfb\x86"
-  "\x23\x63\xf0\x9d\x19\x36\xfe\xb2\x39\x50\x5f\x86\x7c\xd5\x96\xf4"
-  "\x5e\x7e\x93\x0a\x78\x43\x6b\x50\x2e\xcc\xd7\x23\x9b\x8e\xa5\xb2"
-  "\x3e\xf3\xb2\xde\x4d\xe2\xb7\x17\x0a\xdf\x0e\xf4\xa2\x63\x36\x22"
-  "\x9f\xf9\x54\x86\x32\xe5\x9e\xd7\xb2\xdc\x52\x5c\xcb\x60\xcd\xb8"
-  "\xc6\x68\x71\x34\xd8\xb1\x66\x78\xd5\x8e\xa3\xc1\x37\xf0\x8e\x2e"
-  "\xe1\x1d\xa9\x37\xf9\x8e\x6e\xce\xc7\x50\x9e\xf1\x1e\x90\xfe\x7d"
-  "\xbd\x97\x7f\x8f\xd6\x30\xdb\xa6\xdc\x32\x86\xa5\xc7\x56\xda\x41"
-  "\x06\xb5\xa9\x8a\x4d\x34\x0e\xb5\x92\x64\x1a\x4d\x36\x62\xd3\xeb"
-  "\x8a\xaa\x52\x3b\x89\x21\xe5\x34\x69\x24\x06\x1a\xff\xa0\x2a\x19"
-  "\xe5\xce\x7d\x9a\xae\xad\x5b\x35\x5d\xca\xa3\x18\xab\x27\x61\x37"
-  "\xfa\xaf\x76\x1a\x67\xd5\x96\xd3\xc4\x18\x8b\xba\xe2\x1a\xd4\xd1"
-  "\x03\x46\x14\x9b\x38\xc0\x0c\x90\x33\xec\x94\x1e\xc0\x83\x31\x99"
-  "\x71\x7b\x05\x95\x19\xcd\xd4\xaf\x5b\x7f\xe0\xdd\xfd\xf9\xac\x4d"
-  "\x36\xd4\xe3\xdb\xbb\x62\x34\x1d\x59\x64\x16\xfa\x92\x46\x1d\x3a"
-  "\xaf\x8a\x20\x33\x6d\x3e\x3c\x95\x09\x41\x7e\x41\x9f\xd2\x46\x8b"
-  "\x89\xd8\x41\x16\x28\x68\x27\xc1\x05\xc0\x3f\x03\x96\xab\x10\xef"
-  "\xf7\x08\x3e\xa5\x37\xb7\x4b\x3e\xa5\x0b\x51\x5f\x55\x07\xbf\xdb"
-  "\x89\xaf\x3d\x77\x7b\xc5\xae\x76\x12\xb6\x3b\x85\x68\x77\xa1\x3e"
-  "\xf2\x22\xe3\xdf\x90\xdf\xa0\xfe\xa5\x5f\xd6\xe2\xbe\x88\xc4\xbf"
-  "\xe1\x19\x3b\x09\xcf\x7c\xa9\x1e\xc7\x2b\x7a\x1f\xa3\x36\x59\x36"
-  "\xbd\xbe\xce\xa6\xda\xb7\x11\x68\x07\xeb\xbb\x21\xb9\x4b\x79\xc4"
-  "\xad\xbf\x45\xd1\xfe\x24\xcf\xc9\x27\xf8\xb1\x30\x86\xfb\x50\x97"
-  "\x47\xdf\xc4\xf6\x5d\x31\x24\xa2\x85\x44\xb2\xf3\x2d\x77\xc1\x5a"
-  "\xf9\x49\x28\xda\x24\xa6\x2f\x25\x6a\xfb\xae\x79\x8a\x8c\x37\x89"
-  "\x8f\xd1\x16\x45\xf0\x2f\xfd\x07\xbe\x29\x22\x91\x44\xe2\x5e\x0a"
-  "\xee\xfb\x68\xd6\x62\xf9\x63\x97\xc2\xd2\x48\xa4\x73\xdd\x4b\x57"
-  "\x27\x2d\x1e\x1d\xf9\xfb\x45\x9a\x17\x17\x27\x2d\x5d\x15\x97\xb4"
-  "\x88\x4c\x61\x26\x1c\xd4\x65\xe6\x6a\xb4\xdf\x58\xb5\x38\x39\x41"
-  "\xf3\xc2\xca\xa4\xa4\x45\xcb\x92\x35\xd3\x27\xcd\xba\xde\x6f\xd2"
-  "\x2e\xf5\x5e\xea\x27\x8f\xda\xf6\x1d\xaf\xe2\xff\xf8\xab\xf6\x9c"
-  "\x14\xe2\x1b\xb0\x7e\xf2\xec\x00\xdb\x14\x0d\x8b\x2b\x71\xdc\x8c"
-  "\xb6\xb4\x7c\x46\x4c\x3e\xe3\xb5\x8f\xff\xc0\xe4\x93\xb1\x1b\xd9"
-  "\x99\xcd\xe3\x54\x4f\xcc\x77\x4c\x09\x65\x73\xea\xb8\xc2\x27\x99"
-  "\xe0\xef\xa5\xf8\x3b\x20\x99\x6c\x34\x0c\xc6\xfd\xfa\xe3\x6c\x5f"
-  "\x65\xd7\x34\x85\x58\x4e\x2c\xc3\xee\x7f\x62\xc2\xfb\x85\xd4\x87"
-  "\xd8\x27\x5a\xa0\x4f\x50\x47\xd6\x71\xb5\xc9\x77\x88\x68\xb3\xd4"
-  "\xc4\xec\xef\x8e\x53\x3f\x42\xfc\x1f\x87\xb4\x0b\xf5\xcc\x82\xf7"
-  "\xf5\x83\xb2\xd1\xd0\x07\x95\x82\x9d\xde\xd0\x06\xa1\x5d\xcc\x16"
-  "\xf6\x93\x47\x98\xad\xc9\xf1\x04\xa7\xf3\x7a\xf4\xac\x22\xae\x99"
-  "\x02\xaf\xda\x21\xd4\xb7\x49\xc4\x04\x28\x9f\x0f\xfc\x9e\xc6\x7b"
-  "\x2c\x3c\xce\xce\x55\xca\xce\x87\x0b\x74\xda\xa5\x7e\x1b\xf0\x21"
-  "\xb4\x99\x7c\x92\xe9\x3a\x5e\x1c\x3d\xf8\xe4\xb2\x17\x5e\x5e\xaa"
-  "\x8b\x4b\x5e\xfc\xfc\xe2\xc4\xc5\xc9\xab\x1f\xa1\x01\x52\xe8\xbf"
-  "\x27\x46\xc6\xcf\x76\xf5\x79\x19\x8e\x7a\x22\x3c\x1b\x85\xb2\x3e"
-  "\xea\xe7\xd0\xc6\x82\xe9\xeb\xca\x5f\xa3\xbe\xed\xbc\x6a\x7b\xb9"
-  "\x70\x7e\xb2\x3c\xcf\xa4\xfc\x32\x8f\xe9\xad\xb6\x16\x19\x86\xdb"
-  "\xb1\x3e\x7a\xaf\x55\xb5\x4f\xa7\x19\x4c\x26\x36\x90\x8a\x89\xb8"
-  "\x67\x07\xf4\x2b\xc6\xf5\x30\x67\x0d\xae\x5b\x26\x52\x65\x7b\x50"
-  "\x88\x6b\x77\x62\x07\xd2\x00\x79\x45\xa0\xc1\xde\x06\x72\x82\xc9"
-  "\xd8\x57\xd4\x7b\xd1\x76\x89\xbb\xa2\x7e\x1b\xc7\x16\xb6\x97\xe3"
-  "\x63\x76\xf1\x7c\xcc\x4e\xee\x4a\xc2\x2e\xfe\x4a\xc2\x4e\xc9\xdf"
-  "\xce\x89\x64\x78\xb6\x04\x9e\x5d\x8d\xfe\xfb\x73\x2e\x93\x12\xb4"
-  "\x07\xc0\x74\x40\xb2\x8a\xd8\x55\xb9\x45\xd8\x1e\x63\x53\x24\xe5"
-  "\xc3\x1b\xa1\xbc\xd1\xf2\x20\x01\x1e\xb3\x18\xed\x31\xd8\xde\x23"
-  "\xf0\x81\xf0\x9c\x11\xda\x65\x6c\xea\x44\xb9\xbe\x88\x03\x5e\x10"
-  "\xbe\x75\x2f\xac\x9f\x35\x58\x2f\xda\x83\x00\xbf\x0a\xfc\xd9\x89"
-  "\x4d\x26\xf2\x89\xb8\xe7\x49\x6d\x41\xe4\xfd\x78\x62\x3f\xd0\xb9"
-  "\x8f\xe8\xe3\x13\xd7\x12\x94\x19\xa4\x73\x91\x27\xbe\xc0\x6f\xc4"
-  "\xfd\xfc\x19\x16\x9e\x2b\xa4\xf7\xee\x1d\xef\xb4\xbf\x8e\x65\xa8"
-  "\x7f\x6b\xb4\x67\xd1\xad\xc1\x38\xa7\x9f\x06\xb2\xf1\x72\xef\xc3"
-  "\xe6\x8c\x04\x1f\xa1\x5e\x3b\xd6\x8b\x7e\x64\x18\x2d\x3f\x1d\x6d"
-  "\x7c\xe5\xb2\x68\x47\x02\xed\xf8\xf4\x0b\xa1\x8e\x16\x9c\xcb\x5c"
-  "\xd6\x71\x1b\xda\x52\x53\xbf\x91\xec\x2c\x92\x02\xe4\x53\xf4\x53"
-  "\xa4\x2a\x0c\x62\xfe\x65\x3b\xb2\x3e\x75\x8c\x7f\x5e\xc5\x78\x41"
-  "\xe4\xc7\x30\x3e\x09\x8e\x7f\xe4\xed\xb0\x7d\x38\xfe\xa1\xfe\x3c"
-  "\xdc\xb7\x67\xf3\xe0\xd3\xa2\x9b\x9b\x07\x9f\x16\x89\xb4\x60\xf2"
-  "\xe3\xa7\x91\xbc\x32\x83\x8f\xd8\x44\x62\xa9\x7d\x85\x70\xde\x8e"
-  "\x57\x8d\x12\x7c\x17\x56\xdc\x43\x6d\x63\x52\x5a\x8a\x00\xe3\x33"
-  "\xf7\x74\x12\x7f\x4e\x3f\xca\x8a\xbc\x78\x55\x1a\xb5\x4b\xf1\x83"
-  "\xe7\xa8\xdd\x0a\xda\xe1\x0d\xa0\xb1\x6f\x4e\x93\x3d\x6d\xc4\xb7"
-  "\x91\xfc\x4d\x8b\x7b\x5b\x52\x3f\xfc\x6d\x1d\xee\x69\xf2\x5b\x87"
-  "\x94\x06\xa4\x29\x37\x62\x1d\x5c\xfb\xa5\xf1\xe2\x73\x78\x2e\x0e"
-  "\x9f\x6b\x20\x7f\x8b\xa3\xcf\x61\x59\xa4\x59\xba\x6a\x1e\xf0\x5c"
-  "\x75\x58\xde\x06\xbc\x58\x21\xa7\x9a\xc5\xc3\xda\x60\x4f\xb1\x95"
-  "\xc2\xbd\xd9\x9c\x7e\x6b\x31\xe4\xc5\xd0\x3d\x95\x2e\x35\xee\xb9"
-  "\xc2\x58\x4b\xcc\x37\x36\x7e\x67\xa0\xed\x41\xfb\xd3\x64\x58\x47"
-  "\xa9\xec\xf2\xb7\xf7\x0b\x2f\x42\x7f\x84\xd0\xd8\x20\xd0\xcf\x15"
-  "\x34\x1e\x1d\x8c\xc5\x62\xd6\xc6\x8a\xc9\xad\x5b\x47\x98\x5b\x61"
-  "\xac\x5a\x94\x7e\xe4\xb8\x1a\xed\xdd\xf7\xe9\x8e\xab\x3b\xa1\xaf"
-  "\x2a\x82\x01\xfb\x04\xbf\x1c\xec\x39\x1c\xa3\x3e\xea\x01\x5d\x70"
-  "\x2f\x52\xb4\x93\x62\xb6\x4a\x7f\xf3\x43\x9a\xc1\x78\xae\xa8\x4e"
-  "\x44\x7b\x37\xae\x12\xde\x41\xec\x29\x5c\x3d\xee\xf7\xe3\x99\x02"
-  "\x94\x77\x66\xa6\xf2\xad\x28\xbf\xe1\x39\x2c\xdc\xe3\xc7\x33\x8a"
-  "\xbb\x41\xfe\xc5\x7a\xa1\xce\x57\xc4\x73\x84\x9b\x21\x8f\x8e\x7b"
-  "\x9f\xdf\x5d\xcc\x59\x42\xe7\x1c\xda\x86\xfa\xd3\xfd\x0d\x9f\x97"
-  "\x2e\xc2\xb8\x6e\x2d\xbc\x4c\xf7\xe5\x5a\x0b\x85\x7a\xd0\x4f\x01"
-  "\xd4\x51\x21\xd6\xc1\xa5\xf0\x8d\x68\x97\x67\x6f\xe7\x4d\xec\x79"
-  "\x66\xbf\x31\xc3\xc2\xd1\x33\x32\xf8\x3c\xb3\xe3\xa8\xb0\x39\xd9"
-  "\xc5\x03\xee\x9c\xf4\x17\xfd\x18\xc0\x6f\xb5\x28\xaf\x23\x8d\x5a"
-  "\xf5\xb9\x45\x16\x98\xeb\x16\xbd\x1e\xf8\xd4\x93\x63\x00\xef\xf3"
-  "\xba\xd1\x11\xf8\x22\x26\xe2\xb9\x5f\x2e\x28\x42\x83\x67\x7f\xd1"
-  "\xd7\x26\xb3\x6d\x3f\xb9\x4d\x38\x07\xec\x73\x99\x9c\x7c\x5a\xda"
-  "\xef\xb7\x0b\x3a\xea\x93\x87\x99\x7c\x71\xf2\x30\xd5\x51\x6f\xcd"
-  "\xcd\xfc\xd3\x1a\xab\xb2\x74\x8d\x49\xc9\x7c\xbb\x9e\x84\x7b\xc6"
-  "\x34\xd1\x2e\x0d\xca\xe9\xb0\x2e\xf7\xfc\xe0\x18\x13\xab\xf3\x14"
-  "\x95\xa3\x25\x39\xfe\x14\xf5\x2b\x87\x7b\xf3\x1c\xf2\x76\x41\xba"
-  "\x52\xb4\xe7\x32\xea\xae\xa2\xae\xba\x37\xd3\x29\xb0\x32\x82\xed"
-  "\xe4\xdd\xcd\xf2\x74\x10\xa6\x19\xcd\x4e\x45\x89\xfb\x5e\x39\x4a"
-  "\xce\x14\xa0\x00\xb8\x2a\x02\xec\xd3\x59\xd0\xff\x80\xd9\x08\xbc"
-  "\x22\xc6\x16\xd5\x25\x61\x1c\xa3\x53\x2b\xd1\xa7\x39\x9b\x6f\xa7"
-  "\xe8\xb9\x39\x2e\xeb\x51\x3e\x03\xe5\x25\x33\xfa\x3a\xbf\x4a\xa0"
-  "\x5c\x20\x94\x7b\xb3\x3c\xad\x05\xc6\xe3\xa8\x16\x8c\xb3\xd5\x28"
-  "\xbc\xdb\x1c\x38\xc6\x34\xc2\x9f\xc4\xc2\x3b\x0f\x9a\x48\x81\xde"
-  "\x7b\x4c\x38\x75\xb0\x3b\x7d\x2c\xfb\xae\xcf\xc2\xa4\x3e\xf9\x46"
-  "\xe8\x93\xcf\xc2\x7a\xb2\x95\x10\x78\xef\x81\xcd\xa4\x6a\x20\xea"
-  "\x87\xe0\xf7\xd0\x66\x52\x49\xb1\x96\xd9\x21\x57\x7e\x25\xfc\x86"
-  "\x77\x54\x1e\x13\x7e\x0f\x81\xdf\xfb\x84\xdf\x83\xe1\x77\xae\xf0"
-  "\x1b\xe8\x5d\xb9\x5a\xf8\x1d\x0c\xbf\xe3\x84\xdf\x30\x8f\x2b\x9f"
-  "\x14\x7e\x87\xc0\xef\xd1\xc2\xef\x41\xf0\x7b\x90\xb0\xc7\xec\x77"
-  "\x81\x54\xf6\xf2\x9e\xff\xff\xac\x86\xad\xbd\x95\x2a\x98\xcb\x82"
-  "\x1f\x1d\x47\x5e\x98\x89\x94\xa5\x89\xfb\x48\x90\x5f\x81\xef\x81"
-  "\xfc\x89\x30\xfe\xa2\x9c\xf2\x05\xdf\xec\x95\xb3\x41\x9e\x28\x73"
-  "\xca\x2f\x11\xf2\x13\xa1\x7c\x85\x53\x7e\x91\x90\x0f\xf3\xff\x7f"
-  "\x7d\x9d\xf2\xf3\x84\xfc\x02\xd1\x76\x43\xc8\xdf\x28\xe4\x43\xff"
-  "\xef\x2b\x71\xca\x4f\x13\xf2\x2b\xa1\x8f\x2d\x4e\xf9\x54\x66\x66"
-  "\xbe\xf6\x02\xf8\xe3\x69\x63\x00\xdb\x2a\xcd\x26\xf2\xee\x5e\xa7"
-  "\x32\xf1\xec\xd9\x2a\xa0\xc1\x81\x4a\xa7\xfc\x18\x21\x5f\x63\x22"
-  "\xd7\x36\x39\xe5\x4f\xf3\x34\x86\x14\xf9\xc4\xed\x3e\x02\xea\x71"
-  "\x91\x6f\xa4\xb6\xa8\x94\x8f\xac\x9e\x8f\xe7\x63\x02\x76\xf3\x0d"
-  "\x9a\x74\x9e\x6f\x20\xd5\xd1\xcc\x2e\x73\x54\x13\x5b\xaf\x70\xcc"
-  "\x57\x3f\x40\xcf\x9e\xa0\xaf\x37\x3c\x67\xb4\x06\xcf\x19\x55\xd1"
-  "\x3d\xf3\x88\xd4\x4c\xe6\x07\x4e\xf4\x29\x8c\x3a\x01\x61\xcf\x17"
-  "\xca\x7c\x85\xba\x53\xac\x07\xd7\x70\x63\x72\x27\xf3\x11\x08\xb2"
-  "\x03\xe6\xa1\x6c\x4c\xcf\xa3\x38\xc9\x66\x6c\x3e\x56\xcf\xe7\x3a"
-  "\xf1\x2c\x1f\xd3\x1f\xe0\x5a\x8f\xe5\xd1\x5e\xc9\xb9\xac\x89\x54"
-  "\x53\xdd\xa2\x8f\x3a\xe0\x5c\x47\x56\xf5\x44\xe9\x4c\x45\x55\x9e"
-  "\x90\x0f\x7c\x4c\xf5\x6c\xa7\xfc\xeb\x78\x4d\x09\x9f\x86\x54\xf0"
-  "\xaa\x21\xd6\xae\x76\xde\x62\x6b\xe7\xad\x39\x67\x99\xdd\x31\x60"
-  "\xd0\xbd\x76\x7d\xa8\x1f\x9e\xa9\xc0\x58\x43\xb6\x14\xde\x8c\x36"
-  "\x71\x90\xdf\x6f\x86\xc5\x0c\xd8\xdf\xc1\x6f\x7e\x1e\x6d\x28\xdb"
-  "\x08\xee\xc9\x65\xb4\x60\x1c\x88\x00\x1e\xcf\xae\xae\xbb\x44\xfc"
-  "\xab\x01\x7b\xd0\x3e\x19\xf7\xcb\xa6\x27\x98\x49\x55\x82\x9d\x14"
-  "\x42\xdd\xbb\x9f\x17\x71\xbf\xda\x22\x9d\x8f\x1c\x82\x7b\x98\xf7"
-  "\x66\xd0\x98\x6a\x46\xea\x3f\x0d\xe3\xb5\x83\x8c\x9a\xcf\x7f\x82"
-  "\xfc\x88\xde\x10\xb0\x9e\xc0\x18\x30\x46\xc2\xef\x52\xf6\x07\xf7"
-  "\x20\xdf\xd3\x37\xb1\x79\x6a\x4c\x64\x38\x12\x9a\xca\xb0\xc0\x98"
-  "\xc8\xff\x37\x9e\xb5\x30\xea\x00\x4b\x52\x81\xf7\x49\x75\xf7\xfc"
-  "\xba\xdd\x44\xd9\xb5\x15\xd6\x8c\xcb\x65\x4a\x86\x3d\x35\xf3\x38"
-  "\xa5\xdf\x7a\xd4\x5b\xd2\xb8\x4a\x5b\x23\x22\x4b\x96\x59\x95\x55"
-  "\x6b\x1a\xc9\xda\x41\x44\x3d\xcf\xaa\x84\x32\xc6\xaf\x07\x24\xa3"
-  "\xaf\xba\xdc\x4c\xe0\x1d\x94\x7f\x81\xfb\x47\x96\x95\x29\x6d\x74"
-  "\x1d\xa9\x99\x47\x75\x5d\xfa\x08\x3f\xdc\x2b\x33\xd6\xd9\x91\xef"
-  "\xf1\x07\xbe\xc7\xca\xaf\xd0\xfa\xd9\x57\x25\x04\xd9\x56\x24\xf4"
-  "\xdb\x9d\x44\xfc\xed\x2b\xb4\xc1\x6f\xb4\x93\xf1\x62\xbc\x26\x90"
-  "\x85\x23\xf9\x0e\x75\xdf\x2d\x29\x24\x1c\x65\xe5\x01\x0a\x15\xdd"
-  "\x7f\xc4\xdf\x9c\xf2\x7d\x55\x61\x4a\xf7\xb1\xe1\xec\x20\x23\x63"
-  "\x3c\x2c\x6c\x8b\xbb\x6f\xdd\xb4\x13\xe4\x6e\xe1\x2c\x5e\xfa\x79"
-  "\x12\xa2\x7b\x91\x28\x07\xb4\xf1\x86\xe6\x44\xa2\xc4\xb8\x5a\xe9"
-  "\x8b\xa8\x3e\xaa\x57\x55\x82\x8d\x18\x53\xcf\x90\xf4\x24\xec\xa3"
-  "\x9a\xf7\x70\xfd\x44\x9b\x58\x28\xaf\x6a\x26\x35\xc7\x02\xac\x44"
-  "\x89\x7e\xb1\x0d\x4b\x50\xee\xa8\xf9\xc2\x42\xfd\xb6\x7c\xae\xc6"
-  "\xb3\x73\x86\xa4\xc7\x31\xef\x87\x8c\xf3\xd8\x17\xa3\x5a\xd8\x79"
-  "\xbd\x9a\x4a\x4c\x67\xe0\xd9\xc0\xa0\x31\xea\x03\x9d\xd6\x5e\x4c"
-  "\xe7\x51\x53\x25\x60\xbf\x8e\xc9\x49\x35\x1e\x75\x7c\x9c\x5e\xa3"
-  "\xe6\x31\x46\x47\x01\xf2\x15\xbc\x89\xee\xed\xd2\xf8\xd6\x8f\x1a"
-  "\xf8\x76\x3d\x61\x67\x81\x3e\xcf\xe5\x72\x35\xe8\x9b\x04\x7f\xd3"
-  "\x58\x36\x4c\x77\xaa\xd1\x32\x7d\xa3\x66\x3c\xd3\x9d\x6a\xa6\x6c"
-  "\x18\x8c\x36\xe2\x9f\xeb\x5b\x03\x35\x31\x70\x8d\x6f\x0d\x1a\x6f"
-  "\xf2\xbc\xd6\xdc\x33\x45\x73\x2f\x09\x46\x9d\xfd\x42\x3b\xf3\x67"
-  "\xc4\xe6\xf0\xe9\x3c\x3e\x97\xde\x1b\xda\xa0\x23\x3e\x8c\x77\xff"
-  "\xfc\x5c\x44\x01\xd1\x40\x5b\xfb\xf3\xaa\xa1\x56\x6a\xef\xa6\xd7"
-  "\xf8\x19\x5b\xd0\xff\xb8\x9d\x30\xde\xf8\x74\x11\x1f\x38\xd4\xca"
-  "\xca\x9f\x1e\x5d\xdd\x02\xdf\xa0\x1a\x5a\x61\xb4\x5e\x12\xd6\xea"
-  "\xd3\x30\xf6\x87\x56\xf0\xfa\xa1\x42\xbc\xd6\xd3\xeb\x45\x5c\x65"
-  "\x63\xf4\xf4\x4a\x46\xb7\x7b\xa6\x30\xba\x9d\x2e\x12\xd6\xa5\xa1"
-  "\xf8\x1b\xf8\x84\x48\x66\xb7\x70\x3a\x51\xe4\x5d\x4c\x42\x19\x7c"
-  "\x06\x7e\xcf\x62\x58\x7b\x1a\xe4\x9f\xcf\xc3\x84\xfb\x91\x98\x07"
-  "\xdf\x07\xb8\xfc\x79\x05\x7e\x97\x27\x6c\xa5\xb4\x48\x23\x3e\xd0"
-  "\xe6\x26\xb4\x17\x46\xf9\xce\x68\x79\xd4\x60\xa4\x7d\x50\x7b\x3f"
-  "\x3d\x7f\x08\xef\xc1\x58\x01\x88\x9b\x50\xa7\x2f\xd6\x27\xb5\xff"
-  "\xef\xfd\xc5\xb6\xe0\xfb\xf0\x1e\x7c\x2b\xc6\x75\x05\x5a\x0d\xa5"
-  "\x3c\x3d\xf6\xeb\x05\x1d\xea\x4a\xda\x80\x66\x68\x3b\x55\x3b\x1e"
-  "\x69\xc2\x68\x56\x1b\x2c\xc8\x43\x42\x3f\xd4\xde\x25\xa7\x07\x4b"
-  "\x73\x2a\xc0\x86\x24\xb4\xa1\xa9\x1d\x2f\xd0\x4f\xf0\x9d\xfb\xf7"
-  "\xf3\x94\x5e\xf4\xde\xdf\x77\x3b\x3d\x7b\x8f\xa3\x2c\xb4\x1b\x6d"
-  "\x1e\x71\x3f\x1a\x75\xfe\x6c\xbc\xfe\xbd\xc2\xe9\xb9\x8a\x85\x3f"
-  "\x44\x11\x8c\xbb\xb6\x61\x3b\x8d\x45\x12\xd9\x91\xf5\xf7\x7a\x89"
-  "\xde\xac\x1e\x37\xef\xb8\x57\x7c\x87\x89\xfc\xbd\x40\x6c\x27\xfc"
-  "\xd6\xb1\x3e\xa9\xd5\x48\x7d\xf2\xf7\x28\xf1\x39\x94\x9b\xa1\x8f"
-  "\x5a\x30\xae\x8f\x07\x7f\xa7\x0a\x63\x28\x60\xb0\xed\x51\x03\x1d"
-  "\x8f\xa4\x36\x1f\xed\x94\x81\xae\x4d\x6c\x0c\xd5\xa6\xb1\xb5\xb0"
-  "\x96\xea\x2b\x70\xdf\x86\xf9\xbf\xae\xd5\x43\xbd\x25\x42\x9b\xf7"
-  "\x0a\x6d\xd8\x0b\x6d\xb8\xce\x0f\x9c\xe3\x5c\x8b\xe3\xdc\x5a\x6d"
-  "\xa5\x74\x56\x6f\xac\xb0\x17\xfc\x85\x9a\x6f\xe7\xf3\xf0\x6c\x01"
-  "\x9f\xc2\xe7\xe7\x40\xff\x64\xb4\x91\x5f\xa0\x2f\x94\x74\x1d\xff"
-  "\x5d\xb5\x0e\xe4\x1e\x55\xc4\x2c\xc0\xc7\xd9\xe9\x6d\xa4\x0f\xda"
-  "\x9a\x20\xb6\xa0\x2e\x81\x0f\x84\xfc\xdc\x88\xd9\xd2\x79\xa2\x2f"
-  "\xc3\xf1\xdc\x1f\xc8\xe3\x18\xf3\x32\x01\xfb\x1a\xed\x8f\x2f\x90"
-  "\x2f\x61\x0e\x47\x24\xc0\xbd\xe4\xcd\x54\x26\x8b\x28\xb1\xab\xc6"
-  "\xd4\x67\x5c\x22\xbd\x69\x5c\x8a\x54\x2b\xd1\x2c\xc1\x73\x27\x5f"
-  "\xac\x86\x3a\x4b\x20\x7f\x00\xcd\xb7\x5a\xf1\xec\x78\x09\xdc\x1b"
-  "\x00\xf7\xde\x87\x2b\x07\x75\xa4\xe6\x40\xbb\xd3\x2f\x91\x7b\xa1"
-  "\x2d\x4d\xf0\x9e\x12\x68\xe7\x85\x8c\xa5\x24\xa4\x5a\xd7\x84\x3c"
-  "\x35\xd4\x67\x22\x82\x7f\x85\x92\x06\xf2\xe5\x03\xf0\x5d\xa9\x28"
-  "\x5b\xe2\x59\xbd\xcd\x70\x4d\xb7\x93\x01\xe9\xeb\x60\x4d\x5b\x07"
-  "\xef\x87\xf2\x58\x0f\xfa\x54\x60\x6d\x81\x6f\x43\xbd\x04\xd4\xbb"
-  "\xae\x85\xbf\x00\x75\x37\x55\xb5\x40\x7d\xa9\x75\xb4\x4e\x13\x7e"
-  "\x23\xd4\x2b\xd8\x28\x69\xd8\xfe\xf2\x97\x61\xe2\x3e\xa9\x89\x7c"
-  "\x11\x8d\xdf\xe9\xde\x6f\xe9\x97\xd3\xe4\xbe\x3e\xfe\x2f\x14\xfd"
-  "\x26\x42\x7e\xbc\xe8\x97\x03\x7e\xeb\xa0\xae\x52\xda\x47\x4e\x3e"
-  "\x52\x72\x9c\x7c\xa4\x64\x98\xf9\x73\xd8\x16\x1d\x8d\xc1\xf5\x25"
-  "\xc8\x43\x63\xea\x99\xef\xcf\xff\xa3\xf3\x14\xbe\x19\xd3\x01\x4c"
-  "\x77\xf8\xa5\x80\xd9\xf7\x24\xcc\xb4\xdb\x02\x4c\xf0\x4e\x98\xbf"
-  "\x09\x52\xfa\xcb\x72\x3c\x9b\x08\xe5\xec\xcc\x87\xda\x97\x87\xe5"
-  "\xe5\xe9\xfd\x4c\x97\x74\x94\x4b\x5a\x63\x81\xfe\xf4\xb4\x1f\xbc"
-  "\x19\xf7\x90\x54\x11\x7e\x03\xd6\x13\x5d\xc6\x45\xe2\x03\x74\x3e"
-  "\x8f\x6d\xab\x6e\xa2\x67\x64\x02\xf8\xac\x48\x62\x6c\xb2\x31\x7e"
-  "\x05\xd6\x89\x86\x30\x28\x73\x91\x84\xa0\x7d\x35\xfa\x46\x85\xf2"
-  "\xcd\xcc\x1f\x6a\xdd\x5b\xf3\x56\xf6\x25\xdc\xef\x63\xfa\xf1\xca"
-  "\xf9\x3a\x58\x13\xfc\xf6\x77\x9a\xd0\xa7\xa8\x22\x7d\x07\x09\xc5"
-  "\x3e\x84\xbe\x6c\xc4\x98\xa0\xf0\x4c\xcb\x9f\x3a\x9b\x7a\x19\x6d"
-  "\x67\x88\x0e\xc6\x56\x33\xa9\xcb\xf7\x4d\x03\x79\xff\x02\x51\x81"
-  "\xcc\x6d\x3b\x6e\x1b\x4f\xc4\x73\xbd\x05\x41\xec\x7c\x64\x01\xcc"
-  "\xd9\x15\x6a\xde\xda\x91\xf5\x7f\xc0\xff\xfc\x35\x53\x3c\xb7\xb7"
-  "\x89\xf9\x3b\xf5\x85\xf7\xc7\x29\x85\x33\xcc\x8c\xb6\x75\xa3\xd9"
-  "\xf9\xa8\xa0\xfb\x3a\xb2\xea\xb4\x12\x4f\x57\x77\x50\xd0\xc3\x0a"
-  "\x7e\x67\xeb\x0e\x1e\x07\x2e\xfa\x15\xb6\xaf\x1e\x0c\x65\x67\x3b"
-  "\xf6\xd5\xa9\x8c\x5a\x77\x90\xcf\x1d\x4b\x18\xbf\x37\x96\x2c\xb4"
-  "\xfb\x09\xeb\x0a\xe6\x0f\xa9\xc0\x67\xe1\xb9\x00\x16\xb7\xa1\x4e"
-  "\x2f\x8d\xb5\xba\x18\xc4\x11\xf8\x26\x90\xcb\xff\xaf\x12\xbf\x0b"
-  "\x69\x02\xe5\x7c\x21\x5d\x73\x7c\xaf\x07\xbf\xbe\xaa\xd0\x54\x5b"
-  "\x16\xdd\x23\x4e\x85\xf1\x74\x09\xfa\xe0\x6e\xf4\x63\x62\x84\xf7"
-  "\x54\x15\x76\x92\x2a\x75\x2b\xa9\x8e\xc7\xb3\x5c\xc0\x33\x2f\xf9"
-  "\x96\x34\x6a\xdc\x63\x18\xe0\xa0\x15\xf8\x37\x3f\xac\x0b\xe7\x09"
-  "\xda\x47\x19\x41\xd2\xa8\x36\x63\x2c\x52\x42\xeb\xa8\xe2\x9a\x48"
-  "\x55\x2a\xf2\xee\xfb\xf2\xab\x0b\xcf\x90\x6a\xf5\xdf\xe9\x7b\x90"
-  "\xcf\x30\x24\xb5\x76\x53\x77\xa8\x1a\xea\xd6\x0a\x75\xb7\x40\xdd"
-  "\xc1\x9e\xeb\xd6\x1b\xbc\xab\xdb\x9b\x76\xeb\x4b\xbd\xa9\x3b\x23"
-  "\x9f\xb7\x03\xb6\xf4\x07\x5e\x8a\xfa\x55\xc2\xb3\x61\xf6\x76\xf4"
-  "\x41\x30\x94\x67\x36\xa7\x67\x5e\x43\x1e\x9b\xee\x25\xe6\x8e\xb2"
-  "\xd0\x73\x63\x97\x09\xf5\x59\x63\xb4\x9d\x27\xa8\x03\xea\xc8\x3a"
-  "\x93\x2c\xf1\xdf\x8e\x3d\x14\xe0\x7f\xce\xe4\x33\xbb\xc2\x51\xc2"
-  "\xba\x7c\xe6\x69\xac\xc7\x3d\x9f\x1d\xe9\xc7\xec\x53\xcf\x7c\x2e"
-  "\xca\xeb\xad\x81\x91\x7e\x42\x5d\x1a\xd7\xbd\x75\x31\x08\xf8\xa2"
-  "\xd4\x64\x31\x9e\x38\x3b\x54\xd8\x97\x3c\xb3\xe8\x85\x45\x8b\x53"
-  "\x16\xc5\x6b\x66\xaf\x4c\x5a\xf6\xc0\xcb\x2f\xbe\xa8\x99\xbe\x68"
-  "\xc5\x8a\xb8\xdf\x2f\xea\x4b\x66\x27\xc5\x2d\x5b\xb1\x18\x9d\xc1"
-  "\x6b\x34\xd1\x0f\x2d\x4c\x78\x39\xf9\x81\xdf\x44\x47\xba\x9c\x33"
-  "\xc4\x33\x86\xf5\xc8\xd7\x01\xde\x86\x00\xf6\x06\xa2\xff\x89\x80"
-  "\xd5\xbc\x61\x2d\xc8\x14\x30\xfe\x9a\x71\x0f\x09\xe6\xed\x39\xe4"
-  "\x37\x81\xff\xa8\x45\xdf\x63\xbb\xb6\xf3\x35\x17\xc8\xa5\xc7\x80"
-  "\x57\xa9\x43\x3f\x63\x20\x6b\xd5\x83\x9c\x67\x66\x31\x6f\x2f\xdd"
-  "\x03\x65\xca\x5f\x87\x3c\x73\xe0\x58\xb2\xe5\x2c\xf1\x85\xf5\x07"
-  "\x78\xdd\x7f\xc0\xdc\xef\xc3\x6f\x0a\xe1\xcb\xf9\x6f\xd5\x44\xf0"
-  "\xf7\xa7\x34\x9a\xac\xb8\xd7\xec\x37\xd3\x96\xc1\x23\x9e\xb2\xb9"
-  "\xf5\x8f\xf3\x8c\x2e\x1a\x35\xb3\xdb\x6d\xb1\x23\x5f\xbc\x81\xc6"
-  "\x10\xf8\x07\xcc\xc9\x9a\x04\x09\xa7\xcf\x87\x0b\xfc\x08\xf2\x3a"
-  "\xab\x1a\x20\xcd\xce\xd8\xd7\x6b\xe4\xf6\x05\x20\x44\x91\x8b\x09"
-  "\xec\x0f\x9f\xb9\x98\xcc\xfe\xf0\xb7\xf3\x1f\x2c\x28\xf4\xcf\x35"
-  "\xff\xc7\xfe\x89\xef\xbf\xe9\x3a\x1a\x7b\xf8\xbb\x81\xf7\xd3\xef"
-  "\xbe\x83\xdf\xff\xa3\xea\x68\xe9\xee\x0f\xc7\x1b\x8c\xad\xfa\xd7"
-  "\xcf\x12\x3f\x18\x9f\x79\x20\x63\xfb\x66\x7c\x4d\xd4\x69\x36\xbe"
-  "\x31\x63\x3e\x09\x4d\xbf\x48\x30\x26\x6c\x53\x72\x2a\xdf\x98\xde"
-  "\x8e\xb2\xd8\xf9\x8f\x61\xfc\x96\xe5\x34\x10\xff\xcd\x0d\x44\x55"
-  "\x9d\xcc\x7c\xcf\xa2\xee\x13\xcf\x34\x18\x21\x5d\x99\x62\x25\x9f"
-  "\x99\x7f\xc0\x3d\x0e\x43\x75\x2c\xe0\x4e\x3d\x21\x38\x7e\xfd\x63"
-  "\x49\x70\x41\x08\x7f\x98\xcf\xda\x04\xb2\xfb\x26\x7c\x6f\xed\xbb"
-  "\x5c\x54\xaf\x77\xd7\x54\xf4\xc2\xf8\xb9\x0d\xe4\xec\x5b\xc2\xd8"
-  "\x7c\x80\x9d\xd9\x39\xff\x80\xa0\xcf\xaf\x05\xde\x17\xd6\xa6\xf3"
-  "\xfb\xd8\x7a\x7e\x7e\xb5\xa0\xc3\xc0\xdf\xd4\x2f\x2c\x7c\x47\x19"
-  "\xc6\xd0\xc6\x3a\x0f\x70\x65\x34\x86\xf6\xbb\x6b\xa2\x7a\xa5\xc5"
-  "\x11\x65\xb5\xa9\x99\xee\x86\xe1\xbe\x0b\xcc\xbb\x12\x98\x67\xa5"
-  "\xbb\x43\x78\x3d\xb4\x6f\x53\x61\x08\xbf\x11\xda\x54\xdc\x91\xf5"
-  "\x4d\xb0\x89\x7c\xe5\x27\xe8\x58\x0d\x30\x2f\x4a\x36\x43\x99\x99"
-  "\x2b\xc9\xd0\xcd\x50\x2e\x07\xca\x21\xef\xc6\xda\xf7\x6d\x7f\xa0"
-  "\xc1\x41\x78\x67\x8d\x66\x01\xa6\x4d\x54\x07\x86\xef\x86\xef\xd0"
-  "\x34\x10\x13\xd5\x8b\xe0\x3b\xc4\xf7\x42\xfd\x80\x7f\x5f\x19\x04"
-  "\x7d\xb7\x9e\xd5\xf3\x8d\x20\x0f\x45\xa4\x6e\x91\x62\x9c\xa7\x6e"
-  "\x5e\x03\x6b\x3a\xc8\xd4\xf0\x8e\x3c\x78\x07\xea\x22\xf8\x00\x3c"
-  "\x57\x57\x6f\x03\x7e\x8f\x13\xec\xbf\x4c\xaf\x0a\xcf\x52\x1e\x84"
-  "\xf2\x1d\x20\xeb\x33\x99\x14\x78\x8f\x04\xc0\x09\xe0\x37\xa8\x2d"
-  "\x32\xf0\x1a\x98\x0f\xef\xc8\x43\xbf\x7f\x20\x2b\x1c\x84\x75\xbb"
-  "\x14\xf9\x84\x05\x6d\x4f\x11\x1a\x0b\x10\x78\x85\x15\xa9\xbc\x95"
-  "\xc5\x06\x30\x69\x44\x5e\x01\xc7\x07\xf2\x07\x9b\x17\x10\xdf\x2e"
-  "\xe8\x63\x18\x23\x15\xc0\x7b\x04\x36\x13\xd3\x3c\xa1\x6f\x2a\x28"
-  "\x4f\x20\xc4\x44\x62\x18\x6e\x5a\x0c\x6b\xbb\x3f\xbc\x03\x64\x8a"
-  "\x4b\x54\x77\xc6\x30\xc8\x94\x2a\xae\xf3\x2c\xae\x9f\x69\x1e\x0f"
-  "\x58\x07\x74\x3b\x18\x1e\xab\x00\x3e\xf4\x1b\x03\xf4\xc5\x41\x2c"
-  "\x8b\xe7\xc6\xa1\x7c\x31\xac\xf9\xe1\x42\x9f\xd4\x6f\x4e\x41\x1e"
-  "\xc0\x14\x89\xed\x80\x67\x2a\x81\xd6\xf0\xae\x06\x93\x80\x63\xb5"
-  "\x8c\x7f\x69\x38\x29\xd2\x1e\xfa\xfa\x15\x89\xfe\x26\x8b\x33\xfd"
-  "\x81\x16\xaf\xb0\x3e\x68\x58\xe9\xd4\x77\xc0\xaf\x37\x4c\x43\xdd"
-  "\x1b\xbc\xef\x30\xd3\x1b\x9c\x7b\x00\x7d\xfc\xc0\x98\x39\x0c\xb4"
-  "\x38\x0c\xe5\xca\x10\x9b\x37\x9c\x25\x42\x7c\xfb\x86\xb1\x8c\x3f"
-  "\x3d\x57\xcb\x62\x40\x9f\x13\x62\x40\x9b\xc6\xb0\xf8\xcf\xe7\xde"
-  "\x62\xf1\x9f\xcf\xed\x76\x8e\x69\x2f\xc5\xb3\x3f\xb7\x49\xb4\xf7"
-  "\xc7\x31\x80\x7d\x0f\xdf\x38\x86\xc9\x66\xe7\x36\xa1\x7e\x85\x3e"
-  "\xd7\x95\x80\x6d\xac\xc7\xf9\x29\xde\xc7\x18\xf7\x90\x4f\x9c\x68"
-  "\x33\x46\xe8\x93\x32\x16\xf7\xa2\xe1\x01\xd6\xb6\x06\x3f\x48\xfb"
-  "\x41\x1b\xa8\x7c\x87\xf1\xee\xb7\xe0\x33\xe9\xd2\x33\x38\x7f\x60"
-  "\x2c\x07\xc0\x33\x23\xe1\xca\x8b\x65\xf7\x74\x62\x99\x73\x25\x6f"
-  "\x74\xa2\x7e\xe5\x5c\x79\x6b\x97\x56\x09\xef\xb5\xc2\x7b\x95\x38"
-  "\x36\x70\x5c\x88\x75\x6c\x61\x34\x2a\x81\xfe\xa3\xe3\xeb\xb8\xad"
-  "\x0c\xe8\xde\x00\xf2\x7f\xd5\x2c\xc6\xdb\x9d\x2b\x11\xda\x67\x60"
-  "\xfe\x6d\xcf\xd4\x63\xbc\x41\xe6\x6f\xa6\x21\xcf\xb1\x57\xe8\xe0"
-  "\x31\xcf\x95\xe0\xd8\x83\xba\x2a\x85\x31\x11\x00\xe5\x0e\x3b\xc6"
-  "\x10\x3d\x27\xdc\x30\x11\xf9\x4c\xa1\xfd\x38\xf6\xc6\x32\xda\x99"
-  "\xea\x71\x0c\x58\x80\xf7\x64\xfd\x6c\x1a\x83\x7c\x2a\x1b\x87\xdf"
-  "\x12\xb1\x0e\x76\xd6\xf8\xdc\x26\x0e\xea\x10\xc7\x8a\x33\x36\x40"
-  "\xd9\x70\xe0\x49\x1d\xe3\x46\xc4\x02\x56\x67\xa3\x10\xf7\x22\x37"
-  "\x15\xfa\x06\x7d\x32\x1a\x90\x6f\x67\xe3\xb2\x71\xfc\x71\x8b\x8d"
-  "\xc6\xc0\x86\x76\x01\x26\x7c\xbb\xad\x35\x68\xbc\x55\x1a\xdb\xdf"
-  "\xbe\x22\x8e\x6d\xa7\x7e\xa5\x63\xfb\x15\x8a\x47\xdf\x82\xfc\xfb"
-  "\xab\x69\xe2\xd8\xc7\x79\x8e\xb1\xe8\xb7\xa4\xb0\x38\xf5\xa8\x03"
-  "\xa1\xf3\xde\xda\x42\xe5\x0b\xec\xcf\xea\xd4\x46\xea\xd7\x12\xe3"
-  "\xd4\x57\x5b\xce\xa3\xdc\xd8\x8c\xf3\x5f\x9c\xe3\xd8\x37\xf0\x2e"
-  "\x03\xd4\x57\xf3\x0a\x60\x20\xce\x41\x0b\xb4\x09\xe3\x3f\xa2\xdf"
-  "\x8e\xf2\x79\x51\x34\x86\xfd\xf1\x58\xec\xb7\xc6\x30\xd1\xbe\x78"
-  "\x0b\xc3\x00\x7f\x61\xbc\xd0\x36\xba\xd0\x35\x80\xd1\xb5\x31\x46"
-  "\x3e\xbf\xcf\x59\x71\x7e\x3b\xd3\x15\x69\x8a\xb4\x85\xb2\xf0\xfd"
-  "\x5f\xc5\x8b\x74\x75\xa2\x69\x9b\x30\x1e\x05\x6c\x6d\x74\x8b\xad"
-  "\xe8\x1f\x14\xda\x55\xb6\x01\xbf\x05\xd6\x14\x7c\x3f\xf5\xb3\x2d"
-  "\xc8\x3d\xe5\x66\x1c\x53\x8d\x4d\x26\xb2\x90\x88\x38\x06\x63\x85"
-  "\xfa\x5c\xc2\xbe\x12\xb1\x03\x75\x08\xac\xed\xe7\x83\xc5\xfe\xc0"
-  "\x76\x3b\x63\x02\xac\x31\x74\x2f\x46\xfa\xe6\xf3\x93\xe1\xb9\x20"
-  "\xc4\x36\x89\xbf\x3a\x3f\x5b\xfe\xed\xe7\x27\xe2\xb7\xe3\x98\xd0"
-  "\xa5\xa0\x1e\x81\xad\x65\x26\x72\xb6\x42\x8e\x57\x67\x3f\x66\x7b"
-  "\x84\x8c\x1f\x43\xbc\xd7\x2d\x60\xe5\x71\x7d\x83\xf2\x06\xba\xd6"
-  "\xb1\xf5\x30\x1c\xd7\x3f\xc8\x3b\x28\xd0\xa0\x1e\xca\x97\xe3\x99"
-  "\x45\xf4\x49\xd1\xaf\x9e\xc9\x81\x80\xd1\x87\x61\xed\x30\x40\xb9"
-  "\xe4\x6a\x90\x01\x6c\xbd\x09\x29\x10\xf8\x4d\xc4\x09\x7e\x55\x4c"
-  "\xbf\x55\x4d\xe4\x2e\xdd\x6f\xf8\x6f\x2f\x90\x0b\xcb\x61\x1e\x59"
-  "\x71\x2f\x1f\xea\xd6\x5c\x20\x17\x9f\x86\xf7\x06\x0b\x57\x35\x5c"
-  "\x27\xc0\x75\x10\x5c\x87\xc1\x75\x08\x5c\xf1\xec\x29\x27\x94\x8f"
-  "\xbc\x40\x9a\x7e\x80\xfc\x87\x84\x2b\xb4\xf1\x02\xea\x48\x66\xbd"
-  "\x8e\x7c\xe5\x02\x9a\x7f\x02\xd3\x70\x7d\x5f\xf8\xee\x4a\x36\xb7"
-  "\x2f\x6c\x83\x7a\x52\xb1\x1c\xae\x6b\x90\xa7\x83\x32\xab\xb1\x6e"
-  "\x3c\x4b\x0c\xbf\x1f\x70\xe2\x4f\xa1\x9e\xef\x9e\x85\xeb\x18\xb8"
-  "\xde\x03\xd7\x64\x78\xfe\x1c\xd6\x8b\xbe\x6e\x25\xbc\x30\x8d\x89"
-  "\x4f\x65\xfd\x09\x7d\x5d\x8a\xf3\x5d\xc4\x03\x1c\x4f\xb2\x72\xf3"
-  "\x58\x39\x26\xbb\x7e\xa7\x12\xfb\xce\xc6\xc6\x6d\xb9\x0d\xfa\x0e"
-  "\xea\x7f\x0c\x9f\x87\xeb\x24\xe1\x1a\x25\x5c\x27\x0b\xd7\xff\x10"
-  "\xae\xd1\xc2\x75\x8a\x89\x5c\x30\x09\xbc\x09\xd0\xec\x82\x09\x69"
-  "\x02\x73\x37\x9c\xbd\xb7\x29\x18\x65\x6b\xc0\xff\xb1\xad\x18\x4b"
-  "\x21\xeb\xbb\x8d\xa2\xae\x0e\x75\xbc\x5d\x59\x67\x3a\x76\x51\xbb"
-  "\x89\xef\x8a\x24\x2c\x1c\x53\xe3\xaf\x88\x22\xc0\x3b\xf5\x2e\x50"
-  "\x02\xdf\x40\xeb\xf9\xce\xaa\x14\xf6\x1f\xd1\xe7\x32\xc6\x88\x58"
-  "\x68\xf3\x63\x67\xe1\x02\xf7\xa1\x2c\x5f\x4f\xf5\x98\xe8\x5b\x29"
-  "\x70\x4c\x2d\xfc\x99\xcc\x81\x63\x1a\x45\xbc\x47\x79\x49\xf0\x91"
-  "\x15\xd2\x91\xd5\xe4\x2f\xc9\xf8\xdf\x1d\x66\xfb\x39\x03\x01\x9f"
-  "\x9a\xc2\x9c\xf2\x53\xb1\xcd\x40\xeb\x3a\xf8\x9e\x31\x0d\xa4\x69"
-  "\x1a\x5c\x1f\x6c\x64\xdf\x1c\x29\x7e\xb3\xd0\x57\x3a\x91\xe6\x8d"
-  "\xe4\x42\x13\xe0\x61\x12\x8e\xef\x06\x07\x2e\x5f\xa0\xfb\xba\xc2"
-  "\xf8\x81\x7e\xbe\xb0\x03\xfb\xdb\x09\x4f\xc2\x25\x9c\x6e\x2a\x96"
-  "\xf7\x8b\xa9\xd8\xc6\xf8\x85\x3a\x98\x97\x38\x06\x74\x2e\xf3\x72"
-  "\x22\xce\x4b\xe1\xd9\x46\x39\xc6\x9f\x9f\x88\x18\x2f\xb4\x11\xc6"
-  "\xed\x85\x59\xd8\x37\x26\xd2\x54\x2e\xac\x49\xe8\xd3\x6d\x2c\xe4"
-  "\x0b\x7a\x51\x96\x2f\xbc\x0b\xc6\xdf\x05\xf4\x07\x38\x44\xcc\x17"
-  "\xc6\x37\xd6\xa3\xc5\xbe\x16\xf3\x85\xfa\x61\x9c\x5e\xd0\xe0\xfc"
-  "\x11\xf3\xd9\x98\xfc\x36\x15\xf1\x06\x9f\xc5\xef\x41\x9e\xd9\xb0"
-  "\xa0\x1c\xda\x7d\x71\x2f\xf0\x17\x45\x38\x9f\x37\xac\x21\xfe\xab"
-  "\xf2\x49\x7f\x36\x37\x2f\x9e\x10\x9f\x65\xba\xce\x8b\x65\x22\x46"
-  "\x6d\xa1\x78\xd6\x18\x2e\xc7\xca\x96\x5e\x7c\x56\x80\xcd\xa6\x1a"
-  "\x53\x59\x65\x1b\x43\x31\x17\xe6\x7d\x01\x3c\x67\x36\x91\x4d\xf9"
-  "\xc2\x5a\x52\xc9\xf4\xc8\xcd\x23\xab\x8a\x18\x76\xb1\xba\x9b\x1d"
-  "\xf8\xe7\xc4\x87\x50\xac\xc7\x77\x61\x5d\xb0\xae\xa8\x2c\x19\x31"
-  "\xfd\x18\x7e\x37\x47\x9b\x48\xdf\x7a\x11\x5b\x71\x7d\x0a\x50\x10"
-  "\x5d\xce\x02\xb6\x3e\x71\xa8\xff\xd2\x59\xa8\x1f\xa1\x6a\x5d\x0b"
-  "\xc1\x75\x13\xfd\xbc\x2e\x5c\xdd\x17\x7d\xbd\xc4\x5c\x20\xdf\x63"
-  "\xbc\xbd\xbd\x02\x1d\x61\xfe\x7c\x5f\x25\xf4\x43\x3d\xbc\x7f\x2f"
-  "\x62\xf9\x86\x14\xe6\xa7\x1c\x75\x3f\xd4\x0f\x3e\xf2\xa8\x6a\xde"
-  "\x5a\x5e\x80\x73\xa4\xb9\xdc\x49\x9f\x55\xc4\xe6\xc5\xc5\x43\x34"
-  "\xa6\x82\x7e\x4c\x25\xd3\x1d\x7e\x1f\xc7\xf2\xbf\x17\xf6\x5a\xc7"
-  "\x08\x31\xac\xbe\x8f\xf4\x51\x07\x27\xb1\xb8\x33\xff\x08\x62\xfc"
-  "\xc7\xf7\xc1\x2e\x7e\xa1\x94\x90\xa7\x95\x7c\x66\x5e\x14\xf6\xb9"
-  "\xbf\x77\xda\xff\xfc\x1e\x63\x70\xfb\x42\x5d\xeb\x20\xdf\xb1\xff"
-  "\xc9\xd6\x1a\x93\x96\xf1\x06\x63\x6a\xfa\xad\x8f\x22\x80\xcd\xbd"
-  "\x77\x65\x89\xf3\xf7\xfb\x83\xac\x3d\x6c\xfe\xe2\x37\xe3\x78\xc0"
-  "\x39\x6c\xa3\xbe\x78\xf6\xf9\xe1\x5c\x86\xdf\xb5\x36\x71\xee\x32"
-  "\xfe\x2e\x9c\xce\x5d\x3a\x6f\xbf\x2f\x77\x6a\x47\x9a\x30\x56\xeb"
-  "\x5b\x5f\x50\xfb\xc3\x3d\x93\x89\x9c\x09\x65\xf7\x9a\xf5\x42\x3b"
-  "\x2a\xe1\x7e\x81\x21\xfd\x13\xec\xfb\xf5\x6c\x4e\x34\x67\xe2\xb8"
-  "\x33\xc2\x58\x81\xf5\x22\x9f\xc5\x98\x6f\x09\x15\xc7\x0a\xcc\xa9"
-  "\x78\x18\x53\xfb\xf3\x42\xf8\x7c\xe8\x13\xb4\xc7\x4c\x84\x34\xce"
-  "\xd7\x78\x76\x55\xa8\xf0\x2a\x8c\xd1\x7c\x78\x16\xd6\xff\xbe\x62"
-  "\x9f\xd4\x5b\x02\xf5\x66\x3a\x26\xd2\xd1\x36\x26\x92\xee\x47\xe2"
-  "\x98\xc0\xf1\x40\xf7\x25\x61\x6c\x04\xac\x7f\x8a\xe0\xb8\xa0\xe7"
-  "\xf9\x21\x8d\x6d\xc2\x71\x01\x75\xed\x15\x7d\x54\x9a\x48\xcb\x14"
-  "\x46\xfb\x96\x32\x67\x1b\x41\xa8\x5b\x53\xae\x01\x79\x47\x7f\xcf"
-  "\x94\xe4\x61\x64\x20\xc6\x08\x47\x5f\x74\x18\x73\x1d\x9f\xc1\x3d"
-  "\x1d\x86\x73\x03\xff\x13\x9e\xb5\x48\xf4\x32\x51\xbf\x02\xc7\xe7"
-  "\x51\x1d\xe4\xdd\x1d\x59\x97\x54\x72\xac\xf8\x47\x23\xe5\x07\x61"
-  "\x5d\x1d\x11\x4c\x34\x30\xfe\x60\x8d\xb8\x34\x46\xe4\x63\x23\x82"
-  "\x71\x6f\xf8\x1f\x28\x5f\xa0\x0c\x5b\x03\xbf\xd3\x70\x7d\xf5\xa0"
-  "\x2b\x1e\x83\x3a\x1e\x9c\xeb\xa8\x33\x42\xfd\x15\xfa\x94\xbf\x40"
-  "\xcc\x27\xaa\xd0\xd7\xc6\xcb\xd7\xfb\x25\x4d\x4f\xe5\xdb\xd0\xf7"
-  "\x8b\x26\x89\xdc\xdd\x40\xcc\x18\x0b\xb8\x2e\xe3\x07\xd4\xcd\x5c"
-  "\x72\xf1\x7f\x78\xd9\x5f\xf8\xd3\xc0\xdf\x2b\xd2\xdf\x95\x60\xe1"
-  "\xb7\xbe\xfb\xbf\x2b\xe1\xac\xec\x15\xc0\xbc\x2b\xd1\x02\xad\xfe"
-  "\xd8\x91\x75\x59\x23\xd2\x0a\xb1\x00\xb1\x11\x6d\x02\x50\xd7\xa4"
-  "\xb0\x11\xf4\xed\x01\xfd\x05\xed\xde\xf0\xcb\x67\x0c\x6b\x50\x16"
-  "\xbd\x4c\x6d\x9a\xd0\x8f\xa6\x77\xf6\x27\x97\xe9\x1e\x20\xf3\xcd"
-  "\x77\x39\x18\xde\xfd\x3f\x5b\x2e\x13\x5f\x5d\x12\xb9\x07\xf5\xde"
-  "\x01\x76\xde\x80\xb2\xab\x10\xd7\xbc\xa6\x99\x5c\x19\x98\xbc\x8e"
-  "\x28\xe1\xfe\x50\xf8\x2d\xc6\xd7\xac\x87\x67\x54\x3e\x56\x12\x8c"
-  "\xbc\xcf\xa4\x75\x64\x28\xb4\xdf\x24\xf6\x15\xf2\x07\xa8\x7f\x13"
-  "\x74\x08\xd8\xd6\x61\xf8\x1c\xfa\x5a\x36\x51\xba\x09\x98\x73\x19"
-  "\xf5\xcd\x97\x2b\x7d\x2c\x44\xc5\xd6\x8f\x2b\xb0\xfe\xfd\x43\xe0"
-  "\x07\x2f\x37\xc1\x1c\xa8\x75\x6a\xe7\x57\xd2\xef\x90\x41\xf8\x7c"
-  "\x80\x05\x79\x2f\x4f\xf4\xb9\xb2\x5c\xa4\x0f\xda\xa6\x82\x3c\xaf"
-  "\xa3\xfd\x6d\xe3\x5b\xa0\x6d\x95\xba\x35\xc4\xaf\x99\x98\x97\x63"
-  "\xcc\x02\x98\x37\x15\x4c\x2f\x6f\x5e\x24\xca\xd7\xac\xdd\xe6\xd1"
-  "\x01\xeb\x7d\xa8\x3e\x7d\xa1\x5d\x43\xf7\xfc\xf8\x2b\x6a\xaa\x43"
-  "\x37\xda\x26\x12\x43\xfa\x23\x58\x66\x98\xb0\x06\xd5\xb7\x66\xa8"
-  "\xc9\x71\xf5\x44\x98\xcf\x57\x5a\x60\xce\xd8\xbc\xb7\x9b\xba\xd2"
-  "\xc2\x70\x83\x9d\x23\xc4\x34\x9e\xf9\x03\x7a\x56\xb2\x7d\xee\x2b"
-  "\x1f\xe3\x9a\x80\x32\x3e\xac\x07\xe5\xb8\xee\x76\x64\x99\x1d\xfc"
-  "\x3f\xe0\x3d\xe0\xd3\x15\x61\xdf\x05\xf7\x16\xaf\x94\xa1\xaf\x05"
-  "\xc1\xf6\x15\xcb\xfb\x33\xdd\xbf\x79\x93\x83\x6f\x86\x72\xf8\x1c"
-  "\xb3\x6d\xba\xa2\x5f\x68\x47\x9d\xc0\x15\x3d\x7e\x2b\x1b\x9b\x21"
-  "\xd0\xb7\xe6\xc3\xd2\x3c\xbe\x4c\x79\x89\xe3\x2d\xce\xf3\xd4\x5c"
-  "\x2f\xc9\x9b\x97\x32\x1f\xc8\x23\x1a\x77\xf3\x52\x37\x80\xa8\xbe"
-  "\xf7\x23\xbf\xdd\xb2\x85\x2f\xd2\x2b\xb9\xc7\x37\xe4\x10\x7f\xc5"
-  "\x26\x20\x23\xce\xbb\x94\xd8\x81\x17\xc8\x0f\xf3\x03\xfc\x7f\x31"
-  "\x6b\x52\x72\x1f\x3e\x5d\x4d\x94\x9b\xaf\xf6\xf1\x1b\x66\xfd\x45"
-  "\x11\xef\xf3\xcb\x67\xa6\x27\xe3\xde\x9e\x9e\x7c\x97\x48\x7c\x26"
-  "\xd9\xe1\xdd\xfe\x44\x67\x22\xad\x09\x78\x36\xf3\xb8\x3f\xf2\x14"
-  "\xad\x68\x3b\xf3\x78\x5a\x01\xf1\x4b\x6b\xe4\x9b\x36\xbd\xd8\xcb"
-  "\x0f\xd6\x51\x15\xe0\xff\xc6\x7e\xfe\xbf\x28\xea\x82\x3a\x8e\xc5"
-  "\xd2\xe7\xdc\x9e\x05\xeb\xbe\x6d\xba\x10\x68\xdb\x35\xef\xda\x66"
-  "\x29\x96\xda\x66\x29\xbe\xc5\x6d\x53\x49\x6d\x4b\x80\xb6\x5d\xdd"
-  "\xe6\x5d\xdb\xda\x9a\xa4\xb6\xb5\x35\xdd\x60\xdb\x4a\xbc\x6f\x5b"
-  "\xea\x2f\x2e\x90\xd6\xd1\xde\xb5\xad\x43\x2b\xb5\xad\x43\xfb\x63"
-  "\xda\x96\x5e\xc0\x9f\xaf\x0e\x65\xf1\x48\x11\xf7\x2f\x10\xcb\xd8"
-  "\x75\xa1\xd8\x2e\x12\x04\xed\xba\x98\x51\xc0\x7f\xcb\x78\x96\xd6"
-  "\xfd\x6c\xad\x6b\x85\xf5\xef\x52\x0c\x1b\xc7\x16\x2a\xf3\x72\x3e"
-  "\x83\x8b\xf9\x2c\xde\x36\xca\x82\xf6\x4e\x36\xf4\x47\xa0\xe4\xb7"
-  "\x8e\xf5\x7b\xb7\xdd\xaa\xe4\x83\xc6\xaa\xf7\x5c\xf5\x25\xef\xb6"
-  "\x9b\x81\x6f\x69\x35\x89\xfe\x05\xc5\x67\x03\xf2\xbb\xc3\x27\xcb"
-  "\xc0\x49\x09\x24\x00\xf1\x09\xaf\x18\x7b\x66\x4b\x7a\x1f\xbf\x49"
-  "\x3f\x20\x3f\x60\x09\x17\xcf\x67\x89\x75\xcd\x6c\xea\xc3\x07\xa4"
-  "\x11\x1f\x3c\x23\x46\xfd\x96\xa9\xcd\x24\x2c\x8d\xf4\x9a\x99\x0a"
-  "\xf5\x5b\x49\x6c\x40\x2a\xd4\x0d\xf4\x60\x3c\xb9\x65\xb9\x4f\x22"
-  "\xf1\xcf\x83\xba\xf1\x3a\x49\x9d\xc1\x6f\xd8\x41\x7c\xf1\x2c\x19"
-  "\x9e\x09\x63\xe7\xc1\x7a\xfb\xc1\x7b\xf2\xc4\xf7\xf4\x40\xbf\x01"
-  "\x8c\x7e\x6d\x2b\x25\xfa\xb5\xdd\x2f\xd1\xcf\x72\x89\xd1\xcf\xd2"
-  "\x28\xd1\xaf\xad\xd6\x3b\xfa\xb5\x69\x24\xfa\xb1\x67\xbb\xa7\x5f"
-  "\xdb\x1c\xcf\xf4\x6b\x4b\x94\xe8\xc7\xea\xf2\x40\xbf\xde\xee\xe9"
-  "\xd7\xf6\xde\x8d\xd1\xaf\xad\xf6\x06\xe9\xd7\x9f\xd1\xaf\xfd\x7d"
-  "\x89\x7e\xed\x8b\x25\xfa\xb5\x3f\xc0\xe8\xd7\x1e\x26\xd1\xaf\x23"
-  "\xd8\x3b\xfa\xb5\xc7\x4a\xf4\x63\xcf\x76\x4f\xbf\xf6\x6d\x9e\xe9"
-  "\xd7\x5e\x22\xd1\x8f\xd5\xe5\x1d\xfd\xda\x7f\x00\xba\xa9\x04\xfa"
-  "\xa9\x3c\xd3\xaf\x23\xf8\x06\xe9\x17\xc0\xe8\xd7\xd1\x26\xd1\xaf"
-  "\x63\x9f\x44\xbf\x8e\xa5\x8c\x7e\x1d\xf1\x12\xfd\xac\xb3\xbd\xa3"
-  "\x5f\x47\x91\x44\x3f\xf6\x6c\xf7\xf4\xeb\xf8\xc2\x33\xfd\x3a\x5a"
-  "\x24\xfa\xb1\xba\x3c\xd0\xaf\x8f\x7b\xfa\x59\x47\xdf\x18\xfd\xac"
-  "\xb3\xbb\xa3\x9f\x77\xbc\x87\x35\x81\x78\xb0\xc1\xf3\xb2\x1e\xcf"
-  "\x7e\xd7\x30\x96\xd3\x35\xa2\xe4\xb2\xac\xa5\x85\x5c\x6f\x3f\xdc"
-  "\xaf\x85\xdf\xa8\xbb\x7a\xb4\x81\x58\xed\x85\x5c\x2f\x3f\x3e\xeb"
-  "\xa3\x8d\x5c\xd6\xc7\x53\xf8\xf5\xbd\x7d\xb9\xf5\x7d\x7c\xf1\xfc"
-  "\xaa\xbb\xba\x98\xad\xdf\xb5\xf9\x3e\x83\xc8\xbd\x78\xae\x63\x03"
-  "\xf0\x6f\xf8\xbb\x23\xeb\x5a\x02\xf0\x22\xd7\xf9\xd9\x8f\x5f\xbc"
-  "\x22\xee\xf9\xc4\x45\x9a\xa4\x45\xf1\x2b\x97\xc5\xc7\x2d\x4b\xd6"
-  "\xc4\xbd\xf0\xd2\x0a\xb9\xaf\x63\x1a\x7b\xf3\x15\xec\xbf\x6b\x25"
-  "\x0e\x5f\x03\x59\x7c\x2a\xfa\x97\xd2\x0d\x27\x77\x35\x93\x6b\x2d"
-  "\xd4\x47\x74\xd0\xd8\x57\xf8\xae\x98\x9d\x51\x23\xf8\xa3\xd4\x6f"
-  "\x56\x57\xc2\x4e\x90\xb3\xa8\x7f\x01\x61\x8f\x01\x64\xed\xae\x36"
-  "\x3e\x70\x42\x3e\xda\x65\x30\x9b\xf3\x4e\xea\x8b\x01\xfd\x0e\xf0"
-  "\xaa\x88\x52\x4e\x3f\x21\x9f\xcf\x9d\xa0\x47\x1a\x54\xa3\xcf\xa2"
-  "\x14\x9f\xa1\x0d\xc4\xbe\x97\x0f\x8c\x28\x85\xba\x0e\x0a\xf5\x1c"
-  "\x44\x5b\xb7\xa8\x35\xfc\x37\x58\x9f\xc0\x7b\x63\xfc\x43\x03\xe3"
-  "\x07\x3b\xd7\x07\xac\xd7\xf8\x60\x59\xf4\x1d\x86\x3e\xb5\xc4\xd8"
-  "\x22\xd8\x6e\x2c\x0b\xfc\xf9\xa3\xf0\xfc\xa3\x7b\x68\xec\x10\xa1"
-  "\x0e\xd6\xa6\xbb\xa1\x4d\x65\xf4\x5b\xf4\x11\xf3\x5a\xd7\xc6\xec"
-  "\xc4\x7a\x18\x5d\xed\xaf\xc1\xbb\xe7\x61\x1d\xe8\xd3\x07\x9f\x15"
-  "\x9e\xb9\x07\x9e\x61\xbe\x4b\x36\x0c\xd9\xc9\xea\xb0\x2f\x17\xdb"
-  "\x05\x3c\x75\x5f\x48\x3f\xeb\xf4\x8e\x7e\x90\x7e\xcc\xe9\xbe\x3f"
-  "\xa4\x47\x02\x1f\x1a\x28\xdc\xef\x0f\x69\x8c\x0d\xeb\x4f\xbf\x2b"
-  "\x27\x53\xb0\xe7\xb4\xb5\x40\x9e\x4a\x28\x13\xd8\x4c\x6c\x18\x8b"
-  "\x38\x48\xa8\x23\x08\xd2\xef\xa3\x0c\x29\xdc\x0f\x86\xf4\x0e\xd4"
-  "\xef\x0b\xf7\x07\x42\x7a\x1d\xa4\xff\x4d\xb8\x0f\x7c\x7e\x17\xf3"
-  "\xb5\xa5\x8a\x28\xc6\x6f\x02\xda\xa7\xd2\x58\xe2\x81\x11\xc5\x90"
-  "\x17\x03\xf2\x6b\x06\xf6\x23\x7e\xa7\x61\x0d\xfa\x39\xe8\xaa\xc2"
-  "\xb3\x1e\xac\xaf\x26\xe4\x33\x3f\x11\xca\x18\xc8\x47\x3d\x8e\xcf"
-  "\x00\x1a\x8f\x60\x42\x2a\xfe\x86\xb6\x3e\x86\x34\x14\xde\x05\x32"
-  "\x52\x97\x45\xe8\x67\xa0\x1d\xfa\x9f\x24\x99\x58\x2f\x3b\xe7\xd0"
-  "\x25\x9c\x73\xb0\xf9\xdf\xdc\x99\x64\x9b\x3f\xfd\x0e\x18\x7b\xa8"
-  "\x03\x31\x07\x46\x44\xd3\x73\xf8\x30\xfe\xc4\x71\x80\x63\x80\x57"
-  "\x5e\x4b\x66\xfa\x15\x5b\xb2\xe4\x87\xbe\xab\x56\xd0\xb1\x10\x26"
-  "\x03\xd8\x9c\xec\x7f\xba\xe8\xdc\x77\xba\x57\xe2\x74\x2f\x46\xbc"
-  "\xc7\x6c\xd4\x6c\x15\x4e\xf7\xa6\xb8\xdc\x6b\x74\xba\x37\x5e\x5e"
-  "\xa7\x9d\x38\xdd\xd3\xca\x9f\xb3\x87\x3a\xdd\x0b\x76\xb9\x37\xde"
-  "\xe9\x9e\xaf\x70\xcf\x07\xf2\x67\x49\x3e\xbb\x3a\x2d\x42\x3e\xe0"
-  "\xb8\x3d\xc1\x29\xbf\x51\xc8\xc7\xf7\x67\x9a\xc8\xfe\x7a\x21\x9f"
-  "\x8e\x61\x18\x23\xf7\x09\xef\x28\x90\xde\xd1\x29\xd8\x5c\x45\x44"
-  "\xb3\xbe\xea\x0c\x0f\x50\x68\xfa\xe0\x78\x09\x58\x9f\x89\x71\x2b"
-  "\xf4\xcc\x3f\x0d\x9b\x63\x34\x4e\x1b\x5c\xe1\xb9\x70\x4f\xb8\xe7"
-  "\xde\x86\x8f\x53\x89\xe7\x9e\xec\xfa\x88\x29\x9c\x3e\x17\x7d\x89"
-  "\x0e\x45\x3f\x36\x19\x2d\xe8\x07\xc0\x42\x8c\xa4\x93\x18\x93\x3b"
-  "\x32\x31\x4e\x54\x35\x8b\x0f\x35\x00\xf7\xdf\xd0\xee\x1e\x7d\xf1"
-  "\x54\xeb\x2e\xd1\x18\x51\xab\x5a\x48\xa8\xee\x37\x7c\xe3\x05\xc2"
-  "\x25\xdb\x73\x23\xa6\x08\x67\x79\x77\xb0\xf3\x68\x1c\xfb\x1e\x94"
-  "\x59\x5b\xa8\xfe\xd7\xef\x02\xe1\x7d\x69\x19\x3e\x66\x07\xfb\x46"
-  "\x9e\xd2\x75\x4f\x96\x18\xf3\x87\x2b\x11\x63\xa3\x99\x08\xef\xd7"
-  "\x16\x98\xb8\x11\xf2\x0c\x72\x9b\x43\xee\x2b\xac\x13\xdb\x6e\x22"
-  "\x5c\x1a\xd6\x0d\x65\x1a\x1d\x36\x87\x90\xbf\xca\x46\x06\x43\xbb"
-  "\x2e\x88\xf5\x77\x64\xf1\xbe\x26\x62\xa7\x72\x24\xd6\xd9\x96\xbb"
-  "\xb5\x14\xf2\xd4\x26\x1f\xbe\x88\xd9\x2c\xf2\xc0\xff\x1c\xaa\xef"
-  "\xee\xbc\x17\xcc\x47\xc0\xc7\x09\x65\x30\x87\x8b\xd9\xb9\xcf\x09"
-  "\xa5\x4c\x56\xe7\x97\xa3\x5d\x04\xc6\xbc\x43\xd9\x99\xe1\x08\xcf"
-  "\xf6\x3f\x20\x0f\xfa\xa8\x18\xf0\x96\xea\x13\xbd\x9b\x73\x3c\xa5"
-  "\xc9\x96\xab\xc4\x2f\x27\x49\xf4\x99\xcb\x57\x3a\xf9\x12\x17\x6c"
-  "\x91\xf9\xb6\xea\x54\xba\x27\x44\xdb\xe8\xda\x06\x6c\x2f\xd4\xa5"
-  "\xf3\xb8\x36\xaa\x26\xd0\x18\x28\xd0\x2f\x5a\x6a\xdf\xa5\x20\xbf"
-  "\xf6\x51\x0f\x5a\xdb\x91\x4d\xc6\x8b\xb2\x37\x96\xc9\xe9\x44\xff"
-  "\x4d\x13\x4a\x1d\xdf\x99\x64\xc3\xb2\xb1\x54\x7f\xae\x20\xc9\x80"
-  "\x4b\xc5\xd8\x06\x21\x3f\xb9\xda\x66\xc5\x33\x95\x6e\x7d\xab\xd0"
-  "\x38\x2a\x68\x53\xb9\x75\x02\xea\xbb\x2c\x11\x56\xa1\xcd\x0a\x45"
-  "\x32\xda\x10\x63\x9b\x29\x6d\x15\x8a\xc5\x22\x1d\x37\x5f\x85\xba"
-  "\xd3\xcf\x90\x46\x05\xf9\x01\xed\x4e\xd0\x26\x7e\xcb\x1a\xc1\x16"
-  "\x0a\xf2\x68\xb9\x4e\x47\x19\x6a\xd7\x8f\x67\x01\x11\x1f\x0b\x69"
-  "\x1c\x0f\xf8\x06\xe8\x0b\x7a\xae\x5c\xa1\x98\x40\xf5\x98\x49\x84"
-  "\x7d\x37\xda\x99\x29\x14\xd4\x4e\xb9\x23\x5b\x11\x69\x52\x28\xe8"
-  "\xf9\x21\x93\x90\xb7\x05\xdf\x9d\xd2\x49\x2e\x2b\x14\x81\x18\x77"
-  "\x0f\xe8\x51\x86\x3e\x89\xaa\x2d\x30\x4f\x52\x3b\x71\x2c\x94\x61"
-  "\xcc\x26\x28\xaf\x62\x78\x0f\x34\x57\x10\x0b\xbe\x1f\x69\x0b\x7d"
-  "\x67\x06\x9a\xbe\x06\x75\x6f\x12\x69\x8a\xb1\x72\xa1\x4c\xb1\xa7"
-  "\x7e\x41\x1a\xd9\xa1\xcd\x78\x86\xde\x30\xf8\x0c\xb4\x4f\x39\x87"
-  "\x0b\x9a\x50\x8c\x36\x8d\xd0\xd6\x6b\x0c\x2b\x58\xdf\xd1\xb9\xa4"
-  "\x50\x3e\x00\xef\x38\x88\x7b\x80\xe8\x63\x97\xc6\x43\x56\x28\x6a"
-  "\x05\xfa\x51\x1f\xee\xfa\x14\x46\x07\xa1\xfc\x46\xa6\x67\x19\xf4"
-  "\x61\x47\xb6\x52\xda\xff\x81\x7c\xaa\x33\x0b\x61\x67\xbd\xe1\x5e"
-  "\x94\x53\x9b\x2d\xf4\x4c\x12\xd4\x05\xdf\xda\x84\xef\xda\x8c\x3e"
-  "\x63\x70\x5c\x34\x3b\x8d\x7f\x85\xe2\x24\xb6\x13\x6d\xe6\xec\x81"
-  "\x63\xb5\x7c\xee\xd8\x70\xa4\x33\xd4\x4d\x60\x2e\x14\x7b\x88\xb9"
-  "\x48\xe3\xb5\xc0\xfb\x4a\x45\x1e\x08\x78\x9f\xa1\xcd\x0a\xe5\x39"
-  "\xf6\xad\xcc\x5f\x1a\x9e\xef\x75\xe4\xe5\xee\x83\xf5\x2d\x62\x93"
-  "\xc0\xb3\x6c\xf2\xe8\x6b\x6b\x14\x89\xc4\x73\xec\x42\x7c\x51\x0b"
-  "\xaf\xda\xa7\x46\xff\x9d\xe8\x8b\xcc\xb0\xe6\x41\x68\xaf\x4f\xee"
-  "\x1b\x21\xf4\xac\x95\xc5\x30\xea\x2a\xda\xce\xb4\x5c\x48\xa3\xfe"
-  "\x29\xfc\x66\xa6\xda\x78\x7a\x1e\x1b\xcf\x69\x05\xee\x53\xe3\x3d"
-  "\xea\xc7\x1a\xeb\xbc\x59\x5f\x94\x0a\x9f\x79\x02\x6f\x82\x67\x77"
-  "\x7f\xd1\xac\xf0\xa1\xba\x49\xf8\x1d\xd2\xac\xf0\x3d\xc4\xe2\x75"
-  "\x31\xbf\xca\x82\x0d\x60\x6f\x76\x86\xd3\x4c\xa8\xcf\x46\x85\xef"
-  "\x03\x9a\x5f\x12\xd2\xa2\xf0\x1d\x4d\x7d\x9b\xea\x23\x0a\x04\x1a"
-  "\x14\x6c\x61\xed\x0a\x58\x98\xaa\xa4\x6d\xc4\xf6\x79\xd9\x36\xab"
-  "\xb0\x76\xf5\xee\xc8\xf6\x9d\x28\x9e\xfd\xa4\xdf\x2f\xf8\x3c\x35"
-  "\x0c\xbf\x8a\x6d\xd8\x27\xac\x57\x45\xc2\xbb\x8b\x7e\xfc\xbb\x7d"
-  "\x93\x85\x3a\x93\xa9\xdf\x57\xa0\x0b\xd4\x9b\x0c\xed\x28\x17\xd7"
-  "\x50\xc1\x6e\x3d\x9c\xae\xed\xd9\xbe\xf5\x8e\xf5\x53\xa0\xa1\x2c"
-  "\x46\xd1\xcb\x2f\x27\x6b\x80\x01\xd7\xc5\x25\xbf\x90\xa0\x59\x94"
-  "\x94\xf4\x72\x92\x06\x1d\x1c\x38\xcf\x31\x6a\x9b\x92\xed\x6b\x16"
-  "\x62\xcd\x14\x3b\x62\xcd\x64\xf7\x1a\xef\x1c\x13\xc9\xa4\xe8\xe5"
-  "\xd1\xa7\x99\x77\xdf\xd8\xcb\x63\xac\x64\xbd\x92\x2b\x85\xbf\x32"
-  "\xf8\x33\xc0\x1f\x9e\x4f\x21\x0b\xad\x24\x0a\xd6\x47\x7a\x4e\x53"
-  "\xf4\x89\xcd\x65\xf7\x52\xe1\xfe\x74\x83\xa2\xd7\xfb\x85\x9c\x2f"
-  "\xa1\xe7\xd9\xb3\x38\xb4\xf1\x40\x1f\xbd\x65\xf0\x67\x80\xbf\x0a"
-  "\xf8\x63\x3e\x5f\x3e\xa1\xe7\xfe\x4a\x9d\xef\xe1\x9e\x31\x9f\x95"
-  "\x8f\xbe\x7e\x6b\xf8\xf5\xbe\x74\x8f\x81\xdb\xca\xca\xb9\xb4\x41"
-  "\x09\x72\xec\x78\xa1\x1c\x5d\x4f\x07\xac\x27\x1a\x37\xe5\x7c\xf8"
-  "\xac\x6b\x79\x42\x39\xea\xd7\x56\xfc\x1e\xf4\x1f\x0d\xe5\xc5\x72"
-  "\xbe\x7c\xb6\xd2\x22\x94\xa3\x7c\x25\x97\xa5\x74\xf7\xde\x5e\x7c"
-  "\xd6\x67\xe2\x7b\x55\xce\xf5\x39\x95\xe9\xcd\x65\x99\xad\x58\x86"
-  "\x5b\xef\x4b\xf9\x37\x3e\xbb\x57\x0c\x94\x77\xeb\x77\xcf\xbb\x7e"
-  "\xea\x43\x5c\xfb\x49\xf7\xc2\xe2\x45\x8f\x2c\x5e\x96\x82\x51\x49"
-  "\x92\x5f\x5e\x99\x8c\xd7\x65\x71\x2f\xd1\xcb\xcb\x0b\x5f\x7c\x81"
-  "\xfd\x48\x4e\x8c\xc4\x1f\x89\x30\xde\xf0\x1a\xbf\x52\x87\x97\x17"
-  "\x5e\xc6\x64\x6a\x42\xf8\xca\x17\xc4\x30\xaa\xce\xe3\x50\xdb\x91"
-  "\xdd\x07\xd6\x8c\x5e\x74\x2f\x0e\x7e\x1f\x04\x79\x96\xc6\xbd\x09"
-  "\x58\x6f\x22\x27\xb4\x36\x22\xca\xb0\xac\xff\xfb\x10\xea\x23\x4f"
-  "\xd1\xe7\x58\x21\xd7\xc7\x2f\x60\xbd\xee\x85\x00\xdb\xe2\x45\x80"
-  "\xb3\x1b\xe1\x59\xb3\x89\x64\x0b\x67\x73\x23\x4a\xa8\x3f\xb8\xec"
-  "\x3e\x51\xa2\xdd\x1f\xa7\x8f\x88\x45\x9f\xcc\xd4\x0e\x68\x2b\xfa"
-  "\x40\x88\xd8\x04\xe9\x62\x48\x63\x9c\x85\x60\x48\x27\x40\xba\x14"
-  "\xd2\x6a\x48\x87\x72\xfa\xa1\x56\x3c\x2b\x05\x69\x0d\xa4\xc3\x3a"
-  "\xb2\xfd\x66\x89\xf3\xc2\x99\x36\x42\x90\x9f\x47\xdc\xca\xbb\x72"
-  "\x9f\x22\x30\xb7\xfc\xf2\xc4\x58\x8a\x34\x6e\x62\xb6\x9f\x63\xff"
-  "\x8f\xc5\x25\x51\xcd\xa3\xeb\x1a\x5d\xdb\xef\x1a\xe6\xa3\x1e\xd2"
-  "\x97\xf2\xde\xd9\x7e\x95\xe2\x1e\x2d\xe5\xad\xb3\xfd\xea\x9d\x62"
-  "\x4e\x62\xba\xc5\x11\x73\x92\xf1\xa2\x3b\x29\x2f\xaa\xb8\x6b\x0c"
-  "\x9f\xed\x37\xcf\x11\x17\x28\xfb\x2e\xd9\xfe\xaf\x09\xee\xa3\x4c"
-  "\x03\xf9\xe1\xd2\x3a\xe8\x67\xc0\x77\xba\x8b\xaf\x89\x31\xbd\x17"
-  "\xae\x06\xfe\x1b\xae\x02\x2f\xae\xa1\xb2\x56\x16\xfa\xfd\xe3\xdd"
-  "\xae\x6f\x34\xde\x94\xe2\xae\x43\xe8\xef\xd1\x9c\x11\xaf\x18\x51"
-  "\x48\x14\x34\xcd\x7c\x7d\xf1\x97\x15\x77\xd1\xf3\x83\xa2\x1f\x20"
-  "\xe7\x33\xb9\x6e\xcf\x00\x9c\x26\x84\xc5\xaf\x48\x7c\x39\xc0\x16"
-  "\xb7\x88\xf1\x6e\x7d\x07\x31\xfc\x1c\x3b\x8d\xad\xf1\x7d\x7d\xf9"
-  "\x67\x98\xbf\x7d\x93\xa2\xef\x46\x8c\xe3\x11\xa0\x48\x7c\x99\x87"
-  "\x67\x03\x52\xe3\x16\xd1\x3c\x28\xb7\x01\xe3\x32\xb3\xf6\x5d\x34"
-  "\x86\x36\x11\xbe\xdd\xce\xce\x1a\x2b\xee\x6a\x5a\x70\x4f\x26\xbe"
-  "\xc7\x8f\xf2\x0e\xa7\x89\x3f\xc6\x65\xc2\xb6\x15\x3a\xf9\x29\xda"
-  "\x02\x79\x68\x1b\xd5\xfa\x0c\xf1\x47\x7f\x8d\xac\x2d\x77\x35\xd1"
-  "\xf8\x37\xd9\x7d\x33\x45\x5f\x0a\x40\xe7\x26\xd7\xef\x79\xe6\xb7"
-  "\x74\x56\x8c\x7c\x21\x7c\xd6\x64\xf8\x15\x2e\x84\x1c\x74\x1e\x2f"
-  "\xa1\xad\x41\x0f\x6f\x6c\x3d\x30\xea\x3f\x68\xdc\xac\xec\xbe\x35"
-  "\x50\x4f\x32\xed\xe3\x0d\xbf\xbb\x88\x78\x42\x7d\x31\xd8\x89\x9a"
-  "\x9e\x7f\xe2\x2c\x34\x36\xd9\x05\x45\xff\x1d\xe8\x33\x91\xfa\x22"
-  "\xca\xee\x9b\x87\xfd\x0e\x7d\x45\xd7\x78\x6e\x6b\x04\xc6\x4e\xa3"
-  "\xfe\x3d\xb9\xdc\x71\x1a\xa3\x0a\xbf\xbd\x9f\x16\x70\x74\x12\xfc"
-  "\xfd\x27\x8b\x4f\xf0\xbb\x8b\x62\x9d\xe8\x2b\x04\xc6\x13\xd2\x4f"
-  "\xd5\x91\xdd\xcf\x31\xfe\x1d\xe7\xc6\x14\xfd\x96\xa3\x3f\x13\xf4"
-  "\xd7\xc0\xf8\xd6\xfe\xaf\x32\x5e\xb2\x5f\x9a\x89\x04\x44\xb3\x39"
-  "\xdd\x6f\xa3\x89\x14\x15\x09\xbf\x61\xfc\x8f\x72\xad\xe3\x6b\x51"
-  "\x5f\xc1\xc6\x7d\xbf\x32\x18\x7f\x93\xe0\xef\x3f\xa1\x7c\xb9\x18"
-  "\x97\x74\x83\x92\x9e\xf1\xb9\xe0\xa3\x26\x91\x90\x5f\x2f\xe6\xf7"
-  "\x52\x44\x01\x6d\xfa\xb5\x88\x18\xd2\x1a\x34\x76\x0c\xa4\x81\xe6"
-  "\x24\x53\x48\x47\x75\x64\xfb\xfb\x8b\x69\xf8\xad\x16\x31\x06\x7e"
-  "\x03\xff\xb7\xa7\x49\xf8\x1d\x69\x22\x6f\x8a\xf9\x13\x4d\xbe\x8a"
-  "\x4c\xb1\x9d\x5c\x96\x4f\x00\x6b\x6b\x7f\x1d\x97\x9b\x6b\xc0\xd8"
-  "\xaf\x50\x26\x16\xe6\x0a\xf3\x1d\x90\xd2\x52\xb4\xa9\x53\x35\x1b"
-  "\xe3\xb6\x1b\x5e\xc4\x31\xd0\x9f\xfa\x0f\xdb\xbc\x46\x35\x0b\xf9"
-  "\x37\x3c\xdf\x4c\xe3\xf8\xa0\xff\x2f\x1b\xe9\x4d\xfd\x46\xe7\xe6"
-  "\x96\x52\x7f\xc9\xab\xb4\xfe\xa2\xef\x2f\x98\x73\x80\x77\x9b\x6c"
-  "\xe8\x0f\x8c\xea\xb9\x3a\xb4\x03\xa8\x0f\x30\xc1\xf7\xd7\xee\x14"
-  "\x12\x5c\xc0\x31\xdf\x5f\xf4\xec\x73\x6f\xe0\xf5\x53\xdc\xfb\xff"
-  "\xe2\xb3\x8e\x58\x45\xff\x5f\x18\xeb\x19\x7e\x6b\xf9\x76\x1b\xe6"
-  "\x51\xff\xfc\x82\xdf\x57\x5f\xb7\xbe\xc0\x94\x80\x81\x4a\xe6\x0b"
-  "\xcc\xbb\xb5\xa3\xff\x44\xd6\xff\xfd\xd3\xc4\x78\xa8\x4e\x79\x7a"
-  "\x18\xbf\xcc\xce\x44\xd1\x4f\x27\xe4\x01\xfe\xed\x99\xed\xe0\xb3"
-  "\x00\xbb\x50\xdf\x07\xf3\xd3\xc2\x67\x24\xec\x70\x9e\x2f\xd4\x1a"
-  "\x80\xe0\x32\xdc\x0b\xd6\xd8\xde\xf0\xd7\x07\xff\xa6\x38\x70\xa1"
-  "\x9d\xaf\x13\xe2\xf6\xd9\x02\x52\x7d\xf8\x99\x36\x9b\xcf\x42\x9b"
-  "\xa2\x96\xc6\x26\xb4\x13\xe5\x4c\xbb\x0d\xcf\x14\xfb\xda\xda\xf9"
-  "\xda\x99\xf6\x56\x7e\xcb\x8b\x84\x9e\xd7\x9a\x69\x1f\xca\x2f\xb4"
-  "\xeb\x69\xac\x3e\x2e\x85\xaf\x41\x1e\xdf\xde\xce\x57\xda\x53\xf8"
-  "\x0a\xe8\x03\x7f\x94\x1f\xd0\xd7\xca\x00\x85\x95\x0c\xd0\xf9\x1c"
-  "\x9d\xd1\x76\x94\x47\x3f\x2b\x18\xf7\x86\xcb\xb6\xa2\xdf\x17\xc5"
-  "\x42\x9b\x4f\xa6\xd1\xd6\x48\x7d\x4e\xcf\x4c\x7d\x94\x9f\x69\xef"
-  "\xc3\x03\x4e\xfa\xd0\x98\x35\x29\x7c\xf9\xcc\xd5\x7c\x2b\x8d\x67"
-  "\xb6\x1a\xf8\xea\xd5\xad\x3c\xc6\x47\x83\xba\x2b\x16\xa6\x0e\xc7"
-  "\x78\x68\x9d\x33\x53\xb9\x8c\x85\xa9\x0a\x68\xcb\xb7\xfc\xcc\xd4"
-  "\x6f\xa1\x3d\x91\x50\xaf\x0a\xd2\x8f\xf2\x7b\x68\x3b\x33\xa9\x1c"
-  "\x03\xdf\x68\xd8\xc2\xda\x59\x06\x6d\x3c\x88\xbe\x60\x17\xda\x0c"
-  "\x99\x34\xfe\x9a\x10\x23\x79\x66\x6a\x17\x8f\xef\x83\x77\x8d\x9f"
-  "\xb9\x9a\x3c\xba\x70\xf5\xd0\x4c\x2a\x0f\x5e\x46\x9f\x35\x1a\x78"
-  "\x6f\x26\xd2\xc3\x1f\x63\x14\xd2\x33\x4b\xd9\x01\xda\xee\x62\xab"
-  "\xb9\x95\x9d\x73\x26\x44\xf3\xdb\x1e\x0a\xe6\x73\x26\x6a\xe0\x9a"
-  "\xc7\xeb\xc7\x4d\x41\x3b\x4f\x3e\xe7\x37\x36\x7e\xdb\x18\xc8\x7f"
-  "\xac\x0e\xae\x79\x7c\x4e\xf4\x41\x7e\xdb\x58\x48\xff\x87\x1e\xae"
-  "\x90\x1e\x94\x06\xe5\x55\x7c\xce\xe0\x16\xb8\xea\xf9\x9c\xd0\x79"
-  "\x50\x0e\xd2\xf7\x54\xc2\x15\xd2\x43\x27\x42\x39\x48\x6b\x4a\x2e"
-  "\x28\x02\xa0\xcc\x58\xc8\x7b\x2a\x91\xbd\x6b\x7a\x2a\x7d\x57\xce"
-  "\xac\x57\xd8\x3b\x7e\xab\x67\xef\x98\x5b\xc0\xde\xf1\x6c\x31\x7b"
-  "\xc7\xf0\x50\x28\xa7\xe6\x73\xc2\xfc\xe0\x9a\xcf\xe7\x8c\xb4\x40"
-  "\x39\x48\xff\x9b\x09\xae\x90\xbe\x1f\xde\x35\x16\xd2\xbf\x2a\x83"
-  "\x2b\xa4\x1f\xd8\x0b\xe5\x42\xf9\x9c\x88\x3c\xb8\x16\xf0\x39\xa3"
-  "\xb1\x7e\x48\x3f\x94\x0c\x57\x48\x8f\x8d\x87\x72\x90\x7e\x78\x36"
-  "\x5c\x21\x3d\x0f\xbe\xe9\x21\x0d\x9f\xb3\x20\x01\xae\x45\x7c\x4e"
-  "\x2c\xbc\x6f\x0c\xa4\xe3\x6a\xe0\x0a\xe9\x17\xe0\xf9\xb1\x90\x5e"
-  "\x34\x1e\xae\x90\x7e\x11\xbf\x35\x8c\xcf\x49\xc0\xf7\xec\xe5\x73"
-  "\x96\xe0\x37\x43\x3a\x31\x18\xae\x90\x5e\x8a\xed\x81\xf4\xcb\xf8"
-  "\x1c\xa4\x97\x03\x0d\x1e\xd2\xf2\x39\xc9\xfe\x70\x2d\xe6\x73\x52"
-  "\xea\xa1\x1c\xa4\x57\x97\xc0\x15\xd2\x69\x40\x43\x90\x2d\x73\x32"
-  "\xa6\xc1\x15\xd2\x59\xf8\xbd\xe1\x7c\xce\x2b\x66\xb8\x96\xf0\x39"
-  "\xff\x55\x0e\xe5\x20\xfd\x87\x7c\xb8\x42\x7a\x33\xd0\x0f\xe4\xd0"
-  "\x1c\x7d\x14\x5c\xdd\xee\xdb\xf2\x39\x6f\x94\xf1\xeb\x7b\x13\x3e"
-  "\x67\x4f\x31\xbf\xbe\x0f\x5c\xdf\x04\x5e\xb2\x17\xbc\xe3\x2d\x3f"
-  "\xc8\x87\xeb\x7f\x47\x43\x3a\x5c\x48\xc3\xf5\x4f\x91\x90\x8e\x14"
-  "\xd2\x70\xdd\x1b\x0a\xe9\x31\x42\x1a\xae\xfb\x30\x3d\x9e\xcf\x79"
-  "\x07\xae\xbd\xe1\xba\xaf\x00\xd2\x13\x85\x34\x5c\xff\xdc\x04\x57"
-  "\x1b\x9f\xf3\x76\x2d\xe4\x47\xf1\x39\xff\x93\x07\x69\xb8\x16\xcf"
-  "\x86\x74\x34\x5c\xb1\x3d\xd1\xe6\x91\xc3\x0d\xd4\x07\x5b\xd0\xb5"
-  "\x1a\x2e\xe4\x61\x7d\x46\x1b\x51\xa2\x2e\xb8\x34\xdd\x84\xe7\xc4"
-  "\x87\x36\x28\x02\x4f\xa2\xff\x72\x2c\x63\xdf\xfe\x90\x8a\x0b\x79"
-  "\x48\x0f\xf9\xbd\xa1\x5c\x9f\x0b\x8a\x20\x5c\x23\x89\x31\xcd\x44"
-  "\xe3\x27\x09\xbe\x89\x7a\xc3\x33\x3f\xc0\xda\x3f\x1e\xe3\xe3\x02"
-  "\xbd\xa6\xf1\x59\xbd\xae\xc2\xb5\x92\xcf\xea\xd7\x00\xf4\x82\x74"
-  "\xe0\x69\xb8\x42\x7a\xdc\x1f\x80\x5e\x90\xfe\xdd\xe3\x70\xad\xec"
-  "\xc8\x0e\x9a\x65\x52\x04\x50\x4c\xe3\xb3\x79\x1e\xfd\xba\xe2\x59"
-  "\x19\xc0\x1b\xce\x98\x66\x21\x7c\x76\x14\xe1\x87\xc5\x19\xa8\x8e"
-  "\x6c\xe0\xe4\xd2\x80\x54\x48\x8f\x1c\x61\xe0\x43\x94\x26\xfa\x0d"
-  "\x59\x20\xaf\x76\x85\x29\x59\x3b\xfa\xf1\x0d\x8a\xa0\xd7\x50\xaf"
-  "\xc9\x87\x0c\xf6\x74\x7f\x1f\xbd\x3f\xfc\xf9\x28\x76\x5f\x45\xa4"
-  "\xfb\xff\x89\xf7\x4f\x06\xa0\x2e\xfa\xbe\xa0\x28\x93\x22\x88\xda"
-  "\x5e\xc1\x15\xfd\x86\x13\xa3\xa5\x49\xf8\xde\x3e\x58\xee\x07\x7c"
-  "\xce\x93\xae\x85\xcb\x9b\x3a\x7e\x73\x16\x5f\x83\x72\x25\xac\x1f"
-  "\x4a\x4d\x7a\x58\x59\x83\x22\xd8\xb0\x1b\xf5\x05\xc1\x71\xf4\x1c"
-  "\x4e\x83\xe2\xee\x57\xbb\xb6\x8e\x4b\xc3\x18\xe6\x70\xef\x58\x86"
-  "\x95\xb7\x18\xd2\x1f\x87\x75\x8e\xe6\x97\x51\xdb\x6e\xf6\x7b\x2f"
-  "\xb5\xeb\x61\xbf\xf5\x54\xf7\x09\x75\xe1\xb3\xce\x7c\xbc\x3d\xbb"
-  "\xb6\x98\x0b\x89\x53\xd1\x7d\x28\xc5\xdd\xaf\x7d\xcc\x99\x94\x01"
-  "\xc9\xa4\x97\x66\xcd\x51\xa8\xff\x6e\x17\x99\x4f\x2c\x4b\xef\xbd"
-  "\x7f\x04\xca\xee\xa2\xfa\x99\xbb\x4d\xa2\x3e\x97\x87\x6f\x78\x1d"
-  "\xfd\x44\x2b\x49\x14\xae\x69\x8c\x87\x0b\x8e\x45\xff\x66\xb6\xe0"
-  "\x68\x8d\x4d\x7f\xcd\x60\xcf\x8b\x23\xfc\xf6\x38\xd5\x00\x9b\x82"
-  "\x50\xbb\x78\x45\xf0\xb6\x08\x2b\xea\xcd\x4e\x61\xd9\xe9\x5c\xef"
-  "\xb3\x89\xa3\x52\x89\xd2\x90\x74\x06\xd3\x9b\xf9\xec\x8b\x09\xc6"
-  "\x96\x3a\x82\xfe\x1a\x21\xbd\x89\xff\x03\xfa\xed\xb6\xe8\x0a\x91"
-  "\xf7\x4c\x45\x7d\xcf\x69\xcc\x0f\x04\x3a\x03\x5f\x1f\x9c\xe8\x14"
-  "\xb3\xbd\x66\x33\xd0\x0e\xf9\x42\x3c\xc3\xbc\xd0\x6e\x47\x3f\x33"
-  "\x1b\x4d\x40\x07\xa6\x33\x0c\x9e\x85\x78\x2d\xbc\xf7\x2d\x2e\x68"
-  "\x5c\x02\x7a\x9e\x09\xb0\xa9\xd0\x6f\x07\x8d\x01\x8c\x67\xf4\xb7"
-  "\x70\xb8\x4e\xb2\xb2\xce\x7d\xb7\x58\x38\xef\xb9\x78\x59\x72\xd2"
-  "\x72\xcd\x8a\xc5\x6b\x16\xfd\x7a\xe4\xca\x70\x4d\x52\xaa\x26\x89"
-  "\xc6\x17\xa5\x19\xf1\xe1\x9a\x15\x89\x2f\x27\x6b\x92\x57\xeb\x16"
-  "\x5d\x1f\x3f\x52\xcd\xab\xc6\x45\x33\x5e\x6b\x30\xb5\x75\xe0\x8b"
-  "\xe2\xca\x92\xd3\x78\x4e\x33\xbc\x0f\xf0\xe3\x03\x63\xaf\xf5\x0e"
-  "\xae\xc4\xf3\xdf\x5c\x96\x86\xca\x4e\xe8\xf3\x6e\x47\x10\xc1\xf3"
-  "\x15\x7e\x1d\xd9\x03\x63\x1c\x7b\x1c\x8a\xc1\x45\x4c\x1f\x31\x30"
-  "\xd1\xa4\xb8\x5b\x85\x79\x79\xa2\x2f\x20\xe1\x1e\xdd\x23\xc8\x1e"
-  "\xb8\xc9\x44\xfe\x8b\xf9\x2f\x28\x8a\x63\xf1\x1d\x15\x03\x99\xdd"
-  "\x94\x26\xae\x8c\xdf\x3b\xc2\x00\xbc\x90\x02\xf5\x3c\x34\x26\x1d"
-  "\xb9\x4a\xcf\x80\xf2\xdb\x26\x47\xe2\xd9\x6b\xfb\xf6\x71\xa5\x5c"
-  "\xc8\xe4\x48\xee\xed\xb0\xcc\x8c\x37\x89\xf2\x5d\x98\xff\xbe\x1a"
-  "\x18\xdf\xc3\xc9\xd0\xa3\xe9\x4d\x4a\x68\x73\xd5\xd1\xf4\x3a\x25"
-  "\x9f\x07\xfc\x72\xd8\xc8\x22\x6b\x16\x51\x30\xfa\x5b\xc9\xdf\xa2"
-  "\x09\xca\x26\x65\x96\x81\xd3\x2b\x2c\x03\xc7\xe5\x5b\xb7\xcd\x8d"
-  "\x34\x0c\x7f\x90\x4c\xbe\x9f\xbf\xf2\x69\x39\xea\x92\x06\x6f\xfc"
-  "\x34\x1a\x75\x79\xe3\x26\x5a\x55\xe3\xa2\x2c\xdb\xa3\x4b\xd1\x97"
-  "\xc6\xb5\xed\x73\x33\x3b\x43\x26\xa8\x8e\x43\x99\x53\xc0\xcf\x7f"
-  "\xa6\x81\xf1\x3b\x8c\x28\xaf\xdd\x37\x42\xf5\x6e\xa7\x5e\x59\x51"
-  "\x3e\x91\xe9\x1f\x63\x61\xce\xd0\xf1\x14\xb2\xfc\xd3\x83\xe5\x04"
-  "\xde\x4d\xde\xed\x9c\xa2\xfc\xdb\xf8\xeb\xee\xe7\x7e\x1a\x59\x4e"
-  "\x3a\xd0\x67\x1e\xc8\x4b\x47\xce\xe4\xc3\x78\x9c\x6a\xde\xbf\xc6"
-  "\xaa\x9c\x67\x22\xca\xaa\xba\x7c\x92\x76\x9e\xf4\xb7\x5d\xd1\xfa"
-  "\xfe\x19\x9e\xbf\x86\x31\x21\x3e\x53\x53\x3f\x49\xe9\x06\x1a\xbb"
-  "\x30\xa0\x1a\xf8\x0b\xee\x8a\xb6\x77\xf5\x6c\x03\xb9\x16\x34\xaa"
-  "\xd3\x36\x55\x4d\xaa\x12\xcc\xc4\x18\x53\x44\xae\x29\xa3\xc8\xa1"
-  "\xe7\x8a\xc8\x2e\xe0\xd9\x77\x5d\x26\xfe\x6c\x9f\x54\xdb\xdb\xd6"
-  "\xa5\xf5\xb5\xad\xd5\xa2\xdf\x0a\x9e\xbf\xa2\xed\x8b\xfc\xa4\xed"
-  "\x65\xad\x5f\xb5\xb9\x88\x44\x34\x11\xed\x35\x25\x09\xb8\xb6\x56"
-  "\xdb\xb7\x5a\x97\x0f\x75\x61\xb0\x53\xa2\x40\x9f\x39\xe8\x4b\x07"
-  "\xe9\xd4\x2f\x86\xcc\x6e\x51\x84\x3c\xd9\xb7\x96\x0c\xc4\x38\x15"
-  "\xe8\x73\x09\x7d\xf4\x71\xc1\x53\xcd\xf6\xe0\xe8\xd2\xf4\x36\x68"
-  "\x17\xfa\x9a\x38\x30\x4a\x83\x3c\xee\x02\xc0\x1d\xfc\x66\x8e\xd7"
-  "\xf6\x5d\x88\xd7\xad\xa3\x3a\x91\xcf\xe5\x3a\xd4\x18\x47\xc3\x0f"
-  "\xdb\x09\xf3\xd4\x6f\xdd\x39\xa0\x65\x86\xd6\x17\xca\xf9\x43\xfe"
-  "\x00\x63\x8b\x95\xd8\x1f\x18\x15\x39\x4a\x47\x63\x2f\x06\x17\xa6"
-  "\x13\x95\x3e\x9d\x04\x6b\xc6\xd1\xb1\xb4\xd8\xbe\x7f\x94\x86\xcf"
-  "\xd6\x4e\xe3\xd7\xfb\x86\xb2\xbc\x41\x4f\x6a\x9e\x20\x44\xf3\x20"
-  "\xfe\x56\xff\xa0\x79\x04\xfa\x30\x78\xea\x2c\xca\x83\x53\x39\x4c"
-  "\x7d\x9e\x8d\x71\xf5\xd7\xd7\x7a\x27\x65\x72\xd9\x6f\x15\x70\xeb"
-  "\x7d\x35\x18\x1f\xf5\xb2\x42\x7d\x8c\xcf\xf9\x20\x86\xcf\x9b\x4b"
-  "\xc7\x22\xa4\x3f\xbe\xd6\x7b\x04\xac\x47\x1f\x1c\x86\xfa\xa3\xae"
-  "\x29\x7c\xeb\xe0\xaf\x5e\x78\xfe\x20\x7e\xb7\x7d\xef\x88\x7c\xfc"
-  "\x6e\x1a\x7b\x01\xbe\x6b\x21\xf4\x19\x1f\x32\x95\x50\x5f\xbe\x5d"
-  "\x40\x5f\x21\x46\x1d\xd2\x03\x69\xc0\x75\x69\xfb\xd2\x6f\xed\xd2"
-  "\xfa\x03\x7d\x51\x56\x0b\x48\x8f\x83\x67\xb6\x4f\x0d\x86\x7b\x03"
-  "\xae\x05\x4f\x9d\x82\x31\x50\x8c\x3a\x33\xb1\x6f\x9b\xaa\x42\xff"
-  "\x43\x3b\xd6\xc0\x9c\x1b\x38\x15\xc6\xfd\xd4\x50\x61\x6e\x11\x6c"
-  "\x27\x97\xf3\x57\xa0\x1b\xd4\x09\x6d\x83\xf6\xd5\xc1\x5f\xbd\x49"
-  "\xa1\x1e\x7f\x6d\xe4\x88\x62\xb8\xfa\x43\x5b\x81\x36\x51\x89\xf8"
-  "\x1b\xee\x69\x80\x36\xc3\x90\x0e\x48\x0f\x46\x8b\x41\x83\x24\x5a"
-  "\x24\xe2\x33\x7e\x5c\x76\x11\xac\x1b\xea\x26\x3e\xfb\xdf\xc3\x9d"
-  "\xca\x3d\x26\x95\x4b\x9d\xc6\xca\xbd\x63\x66\xe5\x26\xef\x85\xfb"
-  "\x5f\x33\x7a\x0f\x7a\xf5\x7a\x7a\x0f\x5a\x27\x3d\x1b\x6b\x61\xcf"
-  "\x6e\xcb\x64\xcf\x46\xe2\xb3\xef\xbb\xb4\x69\xbf\x54\xfe\x77\x5a"
-  "\x56\x5e\x1f\xc9\xca\xff\x4a\xe7\x54\xee\x0b\xa9\xdc\x8b\x07\x59"
-  "\xb9\x9d\x15\xac\xdc\xd8\x1a\x18\x1b\x81\xd7\xb7\x65\xf0\x5d\xd2"
-  "\x33\xaf\x8c\x67\xcf\xbc\xdf\xc8\x9e\x99\x15\x0b\xf7\x1f\x93\xb7"
-  "\x65\xf0\x04\xa9\x7c\xba\xf0\xdd\xa5\xc9\xac\xfc\x54\x7f\xa7\x72"
-  "\x71\x42\x39\xb8\xff\x11\x96\xab\xbf\xd6\xfb\x0f\xa1\xac\xdc\x9c"
-  "\x12\x1c\x8f\x50\x66\x3d\x97\x7d\x7f\xed\xb5\xde\xf7\x81\xbc\xfe"
-  "\x8b\x1a\xe8\x9b\x50\xbc\x42\xdf\x85\x72\xfa\x71\x13\xe1\x37\xf5"
-  "\x31\x83\x98\x6b\x52\x0c\xd4\x02\xee\xda\xdd\xee\x57\x66\x0f\x36"
-  "\x38\xf4\x59\x1c\xf0\x06\xdb\x1e\x74\xeb\x37\x09\xc6\x5d\x22\xda"
-  "\x10\x20\xa6\x5c\x50\x0c\x19\x8d\x7e\xa9\xf8\x8c\x29\x82\x0e\x69"
-  "\x08\xd5\x5b\xa2\x7f\x04\xd4\x33\x0a\x79\x6a\xaa\x7b\x84\xb1\x09"
-  "\x72\x62\x19\xfa\x02\x43\xbd\x22\xac\x51\x40\xd3\x21\xd1\x18\xaf"
-  "\xfc\x0d\x25\x57\x0a\x7f\x65\xf0\x67\x78\x03\xf5\x8d\x59\x64\xb2"
-  "\xa8\x8b\x75\xdf\xd6\x21\xb0\xfe\x6d\xd4\x4b\xfa\xa8\x21\x69\x30"
-  "\x7e\x6b\xbd\xb6\xc7\x55\x0c\x49\xeb\x66\x5f\xc8\x97\xfa\xc5\xdd"
-  "\xfe\x50\xa4\x9e\x63\x71\x89\x61\x2e\x02\x3f\x37\xe4\x73\x58\xf3"
-  "\x33\xf1\x1e\x97\x37\xb9\x94\x0b\x83\xb5\xe4\x12\xf1\x31\xa6\x35"
-  "\x91\x52\xae\x49\xa9\xef\x24\xbe\xd5\xb0\x9e\x62\xf9\x52\xe0\x1d"
-  "\x34\xcb\x7c\x80\x8f\x18\x72\x51\xdf\x2e\xd4\x57\x14\x67\xc8\x58"
-  "\xca\xe2\xbd\x22\x2f\x89\x6b\x10\xe0\x8e\x3f\x8d\xdb\xb3\x0c\xf9"
-  "\x9d\xd0\x7b\xe0\xb7\x1f\x8d\xef\xfb\xf6\xf0\xa8\x6b\xff\x1d\x67"
-  "\xe8\x0a\x19\xaf\xea\xbc\x6f\xa4\xe6\x5a\xc8\xe4\x52\xdb\xf6\xe8"
-  "\x48\xdb\xf0\xb8\xc8\xae\xb7\x47\x18\xec\x21\xe3\xf5\xf0\x6e\x58"
-  "\x9f\xf2\x95\x07\x38\xbd\xf2\x40\x7a\x99\x12\xeb\x3d\x9a\x5e\xaa"
-  "\x3c\x92\x5e\xa3\x3c\xc2\x55\x28\x8f\xa6\x17\xc3\xb5\x08\x63\xb8"
-  "\x00\xff\x1a\xba\xf4\x48\xba\x01\xd6\xc7\xd0\x12\xa0\x57\x89\xa8"
-  "\xf7\xe4\x1f\xb7\x91\xea\x62\x1b\x39\x91\xdc\x46\xcc\x81\xe3\xa2"
-  "\xe1\x6f\x8a\x79\xe0\xd4\xf1\xe6\x81\x73\x23\x69\x9b\x43\xa6\xd1"
-  "\x6f\xc4\x33\x51\x47\x38\xd6\x66\x81\x1e\x58\xe7\x17\x85\x1c\x9e"
-  "\x9b\xa2\xfe\xda\xfc\x9b\x15\xf7\xe8\x29\x6d\xf4\xdb\x2b\x40\xe6"
-  "\xeb\xa0\x36\xd5\x4a\x16\x3f\x48\xf4\x87\x26\xc6\x1f\xa2\x31\x87"
-  "\x3a\xb4\xb8\xe7\x1d\x86\x71\x87\x76\xb7\x93\x60\xf8\x53\x8b\x31"
-  "\x65\x76\x0b\xbe\xc6\x73\x52\x24\x5d\x83\xa0\x47\x08\x66\xf1\x63"
-  "\x3e\xd0\xa2\xce\x81\xf2\x6d\xe8\x3b\x0d\x75\x0a\x2b\xb4\xe8\x9b"
-  "\xd4\xa1\x53\xb0\x77\x68\x95\x20\xc7\xd6\x08\x72\xac\x01\xe5\x56"
-  "\x94\xb3\x51\x76\x45\x5e\x67\x61\xaa\x81\xfa\x32\xa5\x7e\x36\xb6"
-  "\x4d\xc2\x33\xaa\x96\x8e\xec\x7b\x1c\xf1\xbf\x91\xb7\xb2\xe7\x8e"
-  "\x9b\x0d\x7f\xb3\x20\x1f\xe6\xf4\xb1\x29\x62\x3e\xbf\xb5\x93\x9e"
-  "\x13\xb3\xf3\x09\xbf\xe9\xc0\xf3\x3e\x7c\xc2\xa3\xf6\x6d\xe3\x8a"
-  "\xec\xdb\xe6\xaa\x20\x6f\x22\xfc\xfd\xda\x9e\xdb\x59\x0b\x7f\x75"
-  "\xf0\x57\x0f\x7f\x26\xf8\x6b\x84\xbf\x26\xf8\x33\xc3\x1f\xd4\xdd"
-  "\x69\x85\x3f\x9b\x3d\xb7\x8b\xc0\x9f\x2f\x97\xdb\xd9\x82\xbe\xc5"
-  "\xf8\xad\x5d\xb8\x1e\xa9\xc5\x7a\x25\x7a\xdf\xfb\x24\x7c\x7f\x14"
-  "\xf2\x7d\xfc\x80\x0f\x92\x79\x98\xef\xfc\x5b\xc3\x2b\x68\xfb\x11"
-  "\x97\xdf\x1a\x59\x64\x1e\x16\x57\x0a\x7f\x6a\x73\xe0\x92\x29\xf0"
-  "\x37\x0b\xfe\x62\xcc\xdb\xa6\xce\x82\xfe\x54\x43\xbf\x9a\x3a\xb2"
-  "\xef\x85\xfe\x1f\x59\xc2\x74\x4f\xf7\x02\x2e\x8c\xac\x14\x7e\x97"
-  "\x9b\x14\xc3\xc7\xe0\x6f\xf3\xc0\x69\x45\x90\xae\x35\x29\x46\xd0"
-  "\x72\xad\x21\x53\x63\x85\x73\x43\x99\x90\xdf\x62\xf2\x1d\x5c\xcc"
-  "\xca\x45\x6b\x70\xaf\xa8\x23\x7b\x28\x11\xe7\xa0\xcc\xc7\xf9\x0b"
-  "\xba\x85\x4b\xe3\x52\x17\xae\x48\x5c\xfc\xc2\xa2\x15\x8f\x68\x46"
-  "\xc6\x6b\xb4\x8b\x93\x96\x2f\x5c\xbe\x72\xd1\xca\x45\x94\x7d\x84"
-  "\xac\xfb\x65\x7b\x45\xc1\x78\x3e\xca\x76\x60\x54\x14\x07\x72\x4f"
-  "\x75\x63\x13\xe9\x07\x32\xcf\xba\xf9\x44\x59\x69\x39\x48\xf8\xe1"
-  "\x71\x06\xae\x77\xd4\xa3\xd5\xf1\x26\x72\xb8\xd9\xac\xb4\x01\x3f"
-  "\x37\xcd\x6c\x80\x79\x3a\xb9\xb4\x7f\xe3\x42\xfe\x70\xb3\x55\x39"
-  "\xad\xc5\x40\x32\xce\x01\x7f\x17\x6f\x25\x5d\xf7\x8d\x30\x1c\x6e"
-  "\x2e\x05\xde\x1e\xf8\xbc\xcc\x4e\x52\x69\xb5\xc1\x78\x9e\x1c\x89"
-  "\xcf\xf2\xc0\xe7\x61\x79\x94\xa9\xd0\xe7\x61\xd7\x7d\x61\x99\xfc"
-  "\xf6\xf1\x2a\x2c\x7f\x04\xf2\x67\xe8\x0c\x64\x3a\xd4\xd5\x15\x12"
-  "\x1d\xc9\xc3\x5c\xe3\xdb\xd3\xf8\xca\x46\x03\x39\xb2\xa4\x54\xf9"
-  "\x31\x3c\x8f\xba\x37\x1e\xe6\x68\x17\xcc\x4d\x68\x57\x24\x3e\x83"
-  "\xf7\x1a\x14\x9a\xbd\x78\x1f\x65\xa4\x2e\x68\xef\xbb\x50\x5f\xc6"
-  "\x4a\xe2\xcb\x64\x49\x97\x39\x9f\x12\x00\x3c\xb0\x26\x10\xe7\x3c"
-  "\x0f\x6d\xc5\xef\xd8\x0f\xcf\x1e\x58\x62\xa5\xcf\x83\x6c\xe9\x83"
-  "\x32\x25\xe2\x0a\xe2\x89\x31\x8d\xc9\x96\xa5\x5c\x1d\xc8\xa4\x3e"
-  "\xf8\xec\x74\xbc\x07\x32\x8a\xa5\x80\xca\x29\x9a\x8d\xa2\x6c\xf0"
-  "\xba\xe0\x93\xa8\x5f\x3d\x8c\x9d\x05\x64\xe8\x65\xc5\xd0\xe9\x48"
-  "\x53\xa4\x19\xee\xd7\x76\xf5\x1e\xea\xbf\x0b\xfd\x19\x05\x11\xbf"
-  "\xae\x6d\x71\x7e\xbb\xd0\xa6\x28\x5b\x53\x21\xf2\xdb\x96\xe0\x38"
-  "\x99\x3e\x86\xf5\xa1\x66\xd1\x32\xdc\x79\x88\xa7\x5b\x7c\x71\x2b"
-  "\x56\xac\x5c\xba\x48\xb3\x28\xee\x85\x04\x0d\xbd\xad\x59\xb9\x02"
-  "\x8a\x2c\x4e\x5e\xa1\x79\x79\xd5\x32\xcd\xd2\x15\x8b\x51\x72\x58"
-  "\x94\x94\xb4\x52\x97\xdc\x97\xb0\x27\x35\x4b\x57\x26\x26\x2f\xd6"
-  "\xc1\x8f\x15\x8b\x96\xc5\x6b\xe8\x48\x58\x01\x55\x25\x26\x6a\x84"
-  "\x37\xac\x48\x88\x4b\xc2\xc1\xb1\xec\xf7\x50\xc8\xe9\x79\xb9\x5c"
-  "\xe1\x8f\x3e\x9f\x70\x2d\xba\xac\x18\x7e\x7f\x39\xac\x3c\x7c\x5e"
-  "\x1c\xf5\x65\x03\x69\x2d\x95\x35\xb3\x35\x75\xb8\x1f\xf3\x46\x10"
-  "\xf1\x6d\x1d\x39\x12\xc6\xf3\xb0\xbd\xe2\xb7\xd1\x38\xef\xe8\x5b"
-  "\x0d\xfd\xf6\x29\x86\x0f\xa4\x67\xdc\x60\x8e\x50\x1b\x94\x6c\xcd"
-  "\xf7\x6c\xff\x62\x58\xad\x93\xaf\x79\x0b\xf5\xf1\xa6\x18\x76\x89"
-  "\xed\x65\x0c\x47\xff\xf6\x44\xf0\x51\xac\xe0\xb3\x87\x0d\xc2\x67"
-  "\xb8\x6d\x73\xd5\x1d\xd9\xc3\xfd\x25\x99\x65\x58\x23\x96\xa7\xe5"
-  "\xb2\x87\x8d\xe3\x07\x4e\x05\xb9\x7e\x18\xee\xf3\xb8\xf5\xb9\x04"
-  "\xe5\x34\xed\x50\xef\x67\xa5\x84\xfc\x2a\x98\x68\xdb\xb7\x4e\xa8"
-  "\xe8\x08\x1a\x17\xd3\x99\x45\xfa\x74\xc2\x5a\x67\x55\x92\xa1\xd7"
-  "\x60\x5c\xac\x1e\x4d\x7c\xd6\x4d\x27\xca\x52\x18\x6f\xe8\xe7\xba"
-  "\x72\x4a\x3e\x31\xc6\x9a\x88\xd1\x5a\x42\x2a\x0d\x0d\xa4\xca\xf6"
-  "\x0e\xf3\x91\xbd\x06\x65\x8e\x11\x9b\xd1\x6f\x53\xc6\x3a\xde\xfe"
-  "\xee\x87\xe6\x5e\x07\x60\x3c\x6a\x92\xc8\x50\xa3\xed\x1b\x83\x31"
-  "\x6d\x2f\x31\xa6\x1a\x0d\x78\xa6\x1d\xe8\xb6\xfa\x08\xdc\xbb\xab"
-  "\x12\x9e\x9b\x41\xfa\x40\x7a\x29\xbe\x63\xe3\x76\xbe\xee\xb5\x10"
-  "\xbe\xfe\xb5\xed\xbc\x69\x53\x08\xdf\x08\x63\xaa\x69\x73\x08\xdf"
-  "\xb2\x19\x63\x34\xa2\x9e\x1f\xda\xa3\x4b\x21\xea\x66\xc5\x08\x5f"
-  "\xaa\x03\x89\xa6\xe9\x41\x90\xa6\x7b\x85\xc6\xd4\xed\x98\x1e\x0c"
-  "\xe9\x30\x96\x2e\xc4\xf4\x10\x48\x8f\x61\xe9\x4f\x31\x1d\x0a\xe9"
-  "\x68\x96\xae\x26\xf4\x7c\xb7\x62\xc4\x6c\x96\xfe\x12\xd3\x40\xfb"
-  "\x11\xf1\x86\x14\x6c\xef\x59\xe8\xb3\x11\xcb\x33\xbe\x06\xd9\x35"
-  "\xf5\x02\x9d\x0f\x47\xd3\x13\x50\x47\x03\xf3\x61\x78\x1b\x8e\x77"
-  "\xc0\xad\xbc\xde\x91\x78\x1d\x9e\x1f\x60\x25\x7d\x80\x8f\xec\x07"
-  "\xf7\x16\x21\xed\xdc\xf2\x35\x07\x46\x5e\x99\x69\xe3\x0d\xfc\x5b"
-  "\x23\xca\xf8\x6d\x4f\x44\x02\x8e\xe2\x9a\x00\x58\xf1\xa0\xb9\x74"
-  "\x8d\x95\xfa\xe7\x04\xde\x1d\xe6\xd0\x08\xea\x27\xc9\x0c\xbc\xb0"
-  "\x07\x7f\x7d\x2a\x7e\xdb\xc3\x91\x20\x63\x16\x4f\xd7\xda\xd0\x1e"
-  "\x10\xf8\xff\xb0\x45\x27\x12\x90\x97\x98\xf6\x27\x6e\xef\x48\xc2"
-  "\x65\xc4\x10\x3e\x6c\x44\xd9\xf4\x04\xde\x00\xeb\x9a\x82\xe9\xc3"
-  "\xf9\x6f\x30\x56\x35\x7d\xef\xc8\x11\x65\xdc\xaa\x04\x8c\xd3\x41"
-  "\xf1\x25\x1d\xd7\xf8\x14\xc0\x83\xb5\x31\x01\xf6\x6d\xd3\x8a\x4e"
-  "\x24\x9c\xf7\x2e\xe6\x8d\x22\x2c\xde\xa3\x5d\x12\xb4\xc9\xce\xc7"
-  "\x10\x1b\xbc\xc7\x06\xdf\x8a\xfc\xc4\x01\xe0\x1b\x80\xaf\x29\xdb"
-  "\xff\x7c\x5d\x2f\x7e\x55\x4c\x00\x7c\xd3\x68\xa3\xb6\x8d\x54\x77"
-  "\xe2\x5c\x19\x19\x76\x22\x95\x90\xc9\xa9\x36\x43\x80\x99\xfa\x15"
-  "\x55\xe9\x96\x90\x7b\xf9\x81\x0f\x47\x36\x2b\x46\x26\xcf\x48\x83"
-  "\x6f\x80\x6f\x3f\xd2\x50\xe7\xcb\xc1\x77\x44\x30\xba\xe1\x73\x31"
-  "\x40\xdb\x62\x51\xe6\xf1\xae\xfd\x23\xe9\xb8\xe1\x56\xc4\x10\x3c"
-  "\xb3\xf7\x6e\x3a\xb4\xaf\x2b\x26\x80\x83\x35\x0a\xef\x9d\xd0\x5e"
-  "\x22\xf8\x4e\x46\xeb\x91\xd4\xf7\x2c\x1f\x06\x74\x86\xf7\xa3\x3f"
-  "\x53\x91\xae\x50\x36\xc6\xde\x95\xe0\xbe\xff\xb7\x4f\xd3\x41\xfb"
-  "\x8a\xf8\xdc\x4e\xf7\xfe\x68\xb7\x76\xee\x61\xe3\x63\x78\x1d\xfc"
-  "\x35\xf1\x6f\xc6\x69\xcc\x23\x87\x5b\x69\x7c\xb5\xed\x93\x8a\x9c"
-  "\xe2\x68\xc3\x18\x19\xd9\x86\x71\xb4\xdd\xfb\xdb\xd2\x57\xd0\xf8"
-  "\x35\xbd\xbe\xe1\x03\x30\x4e\x7c\x5a\x1b\xfa\xc6\xad\x38\xa1\xb5"
-  "\x78\xd9\xa7\xf7\x8d\xf7\xd4\xa7\x58\xff\xe4\xfb\xf9\x2e\x2f\xeb"
-  "\xdb\xe8\x71\x8c\xec\x05\xba\xa8\x3a\x0d\x9d\x7c\xb4\x82\xc9\x25"
-  "\xda\x91\x48\xab\x2e\x90\x29\xd6\x7c\x41\x94\x9d\xb0\x6e\xfe\x79"
-  "\x6e\x91\x32\x1c\xe6\x1d\xf0\x2e\x99\x95\x75\x95\x64\x66\x3c\xc9"
-  "\xa8\x6a\xb9\x8a\x3e\x85\x69\x5c\x1a\x3e\xe4\x29\x5d\xc9\x5c\xb3"
-  "\x12\xfd\xea\x63\x1c\x9a\x6a\x8b\x15\xf5\x11\xb1\xef\xce\xb5\x2a"
-  "\xed\xab\x62\x34\xe8\x53\x1d\xf7\x75\xd3\x5b\x78\x8e\xee\x4f\xb5"
-  "\x02\x9f\xd8\x0a\xb2\xba\x3e\x82\x54\xc6\x56\xd0\x78\x99\xe8\x93"
-  "\xa3\x2a\xa1\x8d\x7c\xf6\xca\x11\x52\x59\x57\x87\x67\xfe\xde\xac"
-  "\x6c\x3c\x4c\xb8\x56\xed\x00\xfb\x0a\x6d\x50\x41\x12\x09\x86\x79"
-  "\x7a\x17\x07\x34\xe6\x57\x08\x71\x08\xaf\x4a\x71\x08\x31\xce\x77"
-  "\x01\xc6\x14\xbc\xa4\x22\xb6\xde\xf7\x85\x42\x79\x5f\x8c\x39\xb8"
-  "\xfb\x2a\xd1\xee\x4a\x22\x61\xbb\xe0\x9e\x6c\x7f\xea\x25\xe0\x25"
-  "\x97\x10\xbf\x01\x6d\x2c\xe6\x38\xc6\x4e\x17\x63\x0e\xce\x68\xd3"
-  "\x90\xc3\x5f\x16\x29\x71\xec\x79\x47\xe7\x7f\xa3\x31\x44\x6c\x21"
-  "\xd3\x74\xb6\xc0\x4e\x83\x6d\xe4\x08\x18\xc3\xf7\x35\x41\x7f\xb9"
-  "\x95\xcb\x44\xda\x77\x65\x88\xb4\xbf\x7f\xbf\x48\xfb\xb5\xcf\x12"
-  "\xe5\xb5\xb7\xc3\x32\xdf\x39\x93\x2f\xd1\xbe\xf6\x7a\xda\xbb\xd2"
-  "\xfc\xc0\x73\x56\x25\xed\x8f\xe7\x80\x07\x7a\x7b\x84\xea\x9d\xe7"
-  "\x58\x1f\xf0\xb4\x0f\x62\xa5\x3e\xe8\x82\x3e\xe8\x92\xfa\x20\x7d"
-  "\xb9\xd8\x07\xe7\x59\x1f\xd4\xd2\x3e\x88\xa3\x7d\xd0\x05\x7d\xb0"
-  "\x56\x1b\xb4\x73\x0d\x09\x2e\x58\x43\xd4\xb4\x1f\x54\x7a\x8c\xaf"
-  "\xd0\x77\xf3\x1a\xe8\x87\x4e\xe8\x07\xab\xa3\x1f\x82\x65\xfd\xb0"
-  "\x46\xe8\x87\x4e\xa2\xdd\xd9\x49\xc2\x76\x66\xb1\x7e\x40\x5c\x9f"
-  "\x61\x09\xe0\xb9\xef\xb5\xa4\xb0\x19\xfa\x61\xb9\xd0\x0f\x81\x42"
-  "\x3f\xac\x85\x7e\x58\x0e\xfd\x00\xdf\x7f\x42\xeb\x2d\x26\xde\x9f"
-  "\x7a\x7d\x3f\x68\xe3\x7b\xea\x87\x4e\x47\x3f\xfc\xea\x49\xda\x0f"
-  "\xc0\x4b\xad\x79\x1a\xf5\x74\x61\x99\xfb\x4e\xeb\x95\xe1\x31\x80"
-  "\x3d\x40\xd3\xca\x69\xe5\x64\x66\x2c\xc9\xb0\x41\x9f\xbc\x73\xda"
-  "\xaa\xac\x6c\x84\xfe\x88\x87\xfe\x58\x23\xef\x0f\x4a\xf7\xed\x4f"
-  "\xe9\xfe\x0c\x65\x34\x73\x71\x9e\x4c\x8d\xdd\x7f\x1a\x78\x47\x37"
-  "\xf1\x9b\x9c\xf7\x6d\xa1\x2e\x0e\x63\xf7\xa2\x8d\x1c\xc8\x56\x03"
-  "\x76\x82\xec\x54\x95\xf0\x35\x11\xf7\x6f\x3f\xab\x37\x40\xdd\xda"
-  "\xa0\xcf\x7c\x3f\x20\xa7\x2a\x2b\x48\x80\x82\x0c\xdb\xc5\x91\xe0"
-  "\x53\xb5\x07\x91\x2f\x50\xc1\x18\xbf\xcb\x0e\xfd\x63\xef\x50\xf7"
-  "\xdd\x04\xf2\x15\xee\xeb\x3a\xef\xe7\x62\xdc\x4d\x1e\xfa\x06\xf2"
-  "\x7d\x6d\xd0\x37\x05\xed\x44\xbb\xa3\x9d\x84\xed\x10\xfa\xc6\x11"
-  "\x8f\xf3\x5b\x2d\xd9\xdd\x40\xfc\xfa\x2f\x66\x7d\x63\x17\xfb\x66"
-  "\x95\x56\x39\x7d\xb1\x86\x7c\x08\x34\x39\xa1\xfd\xc2\xcb\xbe\xf9"
-  "\x15\xb3\x31\x82\xbe\xe1\xa1\x6f\x78\xda\x37\xf7\xb7\x78\xea\x1b"
-  "\xfb\xde\xe1\x75\x76\xd5\xb8\x28\xf4\x23\xcd\xbd\x3c\x5b\xc1\x81"
-  "\xec\xd4\x09\x32\xeb\x67\x66\x1b\x49\x03\xb9\x61\xcd\xd7\xa4\xb7"
-  "\x71\xf6\x69\x62\x34\x95\x11\xf4\xdb\x8a\x3a\x6f\xf4\xcd\x6e\xb4"
-  "\x95\x01\xbd\xe7\xea\x31\xbd\x9b\xa6\xcd\x64\xed\x7c\xe2\x43\xe3"
-  "\xbb\xc5\x14\x91\x4d\xc0\x57\xef\x7f\xae\x48\xc9\xe5\x3d\xbc\x91"
-  "\x57\x0d\x41\x19\xcb\x80\x67\x8c\x00\x8b\xfc\xab\x12\x2a\xd1\x47"
-  "\xdb\x37\x19\xa9\xfc\xb9\x6a\x0b\xd4\x69\xe6\x3b\xed\xb0\x36\x14"
-  "\x66\xf1\x65\xe8\x67\x3b\x22\x95\xf2\xdc\x30\x4e\xc2\x47\x22\xcf"
-  "\x81\xba\x3f\x43\xfa\x4e\xe0\xb1\xc2\xef\xc7\x6f\x83\x3c\x45\xd5"
-  "\x12\x0b\xdc\x8f\xd8\x81\xed\x62\x7a\x78\x76\x8d\xc0\x38\x58\x21"
-  "\x73\xff\xfe\x71\xba\xd9\x57\x0f\xb2\x30\xf0\x62\x58\xcf\x4a\x9e"
-  "\xc9\x85\x7e\xc6\x5a\x2b\xd5\xc1\x9a\x33\x12\x7a\xeb\xd7\x60\x6c"
-  "\x24\xf4\xd9\x8d\x6b\x73\xc4\x93\x18\xbb\x92\xdf\x0b\xeb\x52\xc8"
-  "\xa4\xa2\xd2\xe7\xcd\x4a\x69\xfd\x0d\x2f\x82\x75\xcb\x3a\x59\xcb"
-  "\x67\xa0\x6f\xf3\x23\xf0\x5d\x28\xff\xbc\xd3\x60\x55\x5a\x01\x43"
-  "\xfe\xfc\xfc\x46\x25\xea\x88\xac\x30\xfe\x2a\xbf\xfc\x5f\x1a\x73"
-  "\xef\x82\xe2\x81\xf7\x4e\xc5\xd8\x08\xbe\x7f\xce\xfd\xb8\xcf\x12"
-  "\xde\x78\x4d\xf9\x81\xe6\x5a\xef\xfb\x52\x33\x1a\xa5\x78\x63\xce"
-  "\x71\xc5\x70\x2c\xef\x7f\x1e\xea\x84\x7a\x0e\x34\x64\x2a\x79\x11"
-  "\xd7\xdb\xd0\x26\x5e\x8e\x29\x55\x2d\x97\x48\x3a\x8c\xe3\xaa\x84"
-  "\x22\xea\x7f\x7e\x00\xe0\x39\xb7\x16\x70\xa4\x4b\x1b\xb4\x1b\x70"
-  "\x04\xe7\x7f\x21\xe0\x06\xb7\x56\xdd\x37\xa7\x93\x84\x8b\xf8\x81"
-  "\x3c\x16\x5e\xe7\xc3\x18\x0d\xa8\x80\x3c\xe8\x27\x2e\x17\xc6\x28"
-  "\xe0\xc7\xae\x35\x0c\xc7\x77\x23\x7e\x00\xff\x3b\x43\x07\xf8\xb1"
-  "\x0a\xf0\x23\x85\xc6\x83\x54\x17\x2a\x19\x6e\x7c\xd8\xb0\x51\xa9"
-  "\x17\x63\xd7\x52\xfa\x8e\x9a\x5c\x8d\xe3\x23\x36\x93\x9e\x21\xb3"
-  "\xa3\x8f\xf8\xb5\x31\x3e\xd5\x16\x18\x23\xdb\xe7\x66\x62\x1e\xc5"
-  "\xcf\x55\x09\x7d\x39\x36\xd6\xa2\x90\x26\x7b\x2e\x93\x48\x1a\x1b"
-  "\xed\x8a\xba\xef\x96\x65\x24\xbc\xf0\x32\x09\x2b\x5c\x46\xb4\x30"
-  "\x5f\x95\x85\xd0\x86\x05\xcb\x55\x84\xfa\x79\xef\x7d\x5f\x26\xe4"
-  "\xbb\xf5\xf3\x0e\xfc\xb3\xba\x10\xe7\xcc\xcb\x5a\x47\x9b\x6c\xfa"
-  "\xc4\x58\x3b\xd0\x8e\xfa\x28\x52\x8c\x62\x7e\xa6\x55\xf7\x5a\x19"
-  "\x3f\x3f\x8a\xc5\x58\xd7\x8f\xb0\x81\x4c\xd2\xa7\x59\x31\xea\x55"
-  "\x7e\xeb\xaf\x30\x0e\x91\xa2\x59\xbc\x07\x3c\x26\x07\x7d\x35\x2a"
-  "\x93\x64\x72\x81\xdb\x9b\x8c\xa9\xc0\x23\x65\x24\x78\x39\x0f\x47"
-  "\x51\x3f\xd6\x76\x7d\x62\x3c\x7e\x2f\xb7\x35\x31\x71\x4f\x33\x89"
-  "\xe4\x5f\x82\xfe\x58\x02\xdf\xda\x4c\xc2\x0a\x9a\xe1\x5b\x57\xb1"
-  "\x6f\x15\x63\xf5\x72\x59\x1f\x68\xe1\x9e\x7b\xbd\x8c\x18\xf7\xed"
-  "\x25\x8c\xfb\x36\xa4\x02\x30\xec\x6e\x7e\x38\x81\xb1\x40\xfd\x4c"
-  "\x74\x18\x6d\x5f\x13\x7c\x2f\xea\x8d\x8c\x57\xe9\x98\x5e\x8d\x63"
-  "\x99\x2b\x8a\xd3\x2c\xac\x87\xb1\xdd\x91\x80\x3a\x34\xcd\x91\x06"
-  "\x33\xfa\x75\xa0\xbc\x9d\x49\x11\x5e\x8c\xfc\xd8\x51\xc8\xc3\xb1"
-  "\xef\x34\xe6\x8b\x71\xcc\xe3\x7d\x3a\xee\xe1\x39\x63\xfd\x79\x82"
-  "\xf5\x39\xd7\x83\xfd\x2f\xd6\x75\x41\x11\x39\x1f\xeb\xc2\xb1\x80"
-  "\xfa\x1d\x9c\x6b\xac\xef\xcb\xd0\xde\x5b\xcd\x87\x4c\x50\xb1\xb4"
-  "\x19\x6d\x38\x54\x38\x06\xe8\x58\x81\x75\x15\xfd\x87\xf2\x7c\x8c"
-  "\x0f\x8c\x33\x6c\x67\x5f\xe8\xef\x48\x71\x5c\x40\x5e\xb0\xeb\xd8"
-  "\x18\xb0\x5e\x85\xb2\x4b\x30\xfe\xbe\xd1\xf1\xe1\x5d\xff\x45\x7a"
-  "\x8c\x5f\xcb\x85\x01\x1f\x0b\x78\x89\xb8\x69\x6f\x75\xc2\xcc\x16"
-  "\x86\x99\x88\x49\x22\x6e\x52\x6c\xa2\xbe\xbc\xcb\xd0\xee\x35\x81"
-  "\xb6\xd1\x4b\xdc\xac\x6a\x91\x70\x73\x86\xce\x09\x37\x5b\xf8\x4e"
-  "\x6e\xa4\x3b\xdc\x1c\x3d\x5f\x8e\x9b\xa3\xe3\xe4\xb8\x39\xe6\x84"
-  "\x2b\x6e\x5e\x8f\x99\xa3\xdf\x74\x87\x97\x20\xaf\x0c\x6d\x56\x8c"
-  "\x49\xf6\x8c\x95\xa3\x2b\xbd\xc7\xca\x07\xbf\x96\x63\xe5\x83\xaa"
-  "\xff\x77\xb1\xf2\xa1\xe5\x32\xac\x54\xdd\x20\x56\x36\x53\xac\x0c"
-  "\xe6\xbf\x87\x39\x21\xe0\x47\xe1\x12\x0f\x58\xb9\xa4\x87\xb9\xf0"
-  "\x92\x27\xac\x7c\xe8\xa4\x1c\x2b\x1f\xb2\xc9\xb1\xf2\xa1\xf7\x24"
-  "\xac\x14\xee\xdd\x12\xac\x7c\xa8\xe2\xce\x60\xe5\x43\x15\x14\x2b"
-  "\x2f\x23\x56\x8e\x79\xab\x67\xac\x1c\x5d\xeb\x1e\x2b\x21\x9f\x62"
-  "\xe5\xe8\x5a\x09\x2b\xbf\xee\x01\x2b\xc7\xbe\xe6\x05\x56\x06\x53"
-  "\xac\x54\x79\xc0\xca\x25\x40\x2b\x61\x5c\xd0\xb1\xe7\x32\x36\x04"
-  "\xac\x54\x3b\xb0\xf2\x06\xc6\x87\x77\xfd\x37\xd6\xa3\xfc\x8b\x58"
-  "\xc9\xe9\x19\x7f\x89\x58\xc9\x07\x09\x58\x99\x68\x23\x6b\xbe\x02"
-  "\x8c\xac\x6d\xa6\x3e\xff\xa9\xbd\x2e\xfc\xa5\x3d\x8b\x58\x14\x5d"
-  "\x7a\x00\xe8\x65\x34\x95\x52\x6c\xa2\xf6\xaa\xd3\x10\xab\x4a\xa1"
-  "\x6c\xbe\x83\xef\xa4\xd8\xf9\x95\x80\x9d\xf3\x04\xec\x5c\xf0\x23"
-  "\xb0\xf3\x39\xec\xcb\x71\x3b\xae\x29\x45\xec\xdc\x0a\xd8\x39\x8e"
-  "\xf2\x0f\xb8\xa7\xcb\xb0\xf3\x91\x81\x62\xbb\x50\x77\x69\x4c\xde"
-  "\x49\x58\xbb\xae\x5e\x8f\xa3\x4f\xd1\xfa\x2e\x19\x96\xb4\x10\x07"
-  "\x96\xce\x93\xb0\xf4\x82\x62\xc2\x09\xcf\x38\xfa\x70\xb0\x03\x47"
-  "\xb3\x00\x47\xcf\x3a\xe1\x28\xea\x0c\x10\xf3\x00\x47\x3b\x28\x8e"
-  "\x7e\x28\xe0\xe8\xf8\x91\xa7\xe6\x01\x8e\x3e\x25\xe2\xe8\xc3\x31"
-  "\xd6\xac\x0f\x34\xd6\xec\x9e\x71\xb4\x83\xe2\xa8\xee\xf6\xe3\x68"
-  "\xb9\x0b\x8e\x82\xcc\x8a\xb1\x6e\xdd\xe2\xa8\x38\x1e\x29\x8e\x66"
-  "\x4a\x38\x4a\xe9\x3a\xfe\x58\x75\x2c\xd0\x3d\x56\x47\xe5\x36\x07"
-  "\x8e\xea\x4a\x19\x8e\x42\x1e\xb5\x75\x58\x01\x38\x0a\xe3\x2f\xa3"
-  "\x0a\xfd\x55\x91\x28\x68\xa3\x0a\xf1\x75\x0f\xcc\x19\xa4\x91\x03"
-  "\x4f\x97\xc0\x9c\x41\x8c\x69\x85\x39\x03\x38\xba\xa0\x4d\x45\xe8"
-  "\x7c\xc9\x86\xf9\xd2\xec\x21\xc6\x90\x68\x7b\xeb\x11\x4f\x27\x0c"
-  "\x92\xe3\xe9\x84\x69\x72\x3c\x9d\xa0\x90\xf0\x54\xb8\x87\x78\x0a"
-  "\x7d\x06\xf4\x69\x42\x4c\xbd\x39\x3c\x9d\xa0\x76\xe0\xa9\x52\xc0"
-  "\xd3\x25\x3d\xe3\x29\xdd\x13\xf4\x80\xa7\xce\xd8\xe0\x19\x4f\x27"
-  "\xa8\x25\x3c\x9d\xd0\xe6\xc0\xd3\x3a\x4f\x78\xfa\x70\xa8\x7b\x3c"
-  "\x7d\x38\x94\xe1\xe9\xc3\xa1\x0e\x3c\xad\x73\x83\xa7\x4f\x39\xe3"
-  "\xe9\x23\xe7\x19\x9e\x96\x0a\x7e\x2c\x3a\x6b\xaa\x2d\x30\x3e\x70"
-  "\xce\x25\xe7\x53\x4c\xe5\x00\x53\x01\x0b\x94\x18\xbb\x04\xed\xe4"
-  "\xdd\x61\x2a\xc3\x5c\x13\x41\x5c\xc5\xb9\x99\x31\x1d\xe4\x5d\x58"
-  "\x8b\x80\x26\x74\xed\x15\xe9\xb7\xc7\x09\x5f\x17\xae\x56\x21\x6f"
-  "\x27\x1b\x2b\x9c\x38\x56\x5a\xb5\x68\x0f\x2c\x1b\x2b\xde\xf5\xe5"
-  "\x23\x8d\x9e\xb0\xd5\x93\xec\x7e\x0a\x65\xf7\x39\x44\xb9\x76\x0e"
-  "\xe0\x6b\x0c\xca\xee\xc5\x2e\xb2\x7b\xf1\xf5\xb2\xfb\x17\xdd\xe3"
-  "\xa8\x57\xb2\xfb\x5c\xec\xc3\x7f\x3f\x27\xc7\xd1\x7f\x3f\x2f\xc7"
-  "\xd1\x47\xe3\xb0\x5d\x0c\xc7\x8b\xdd\xcb\xee\x74\x9e\x4f\x1c\xed"
-  "\x90\xdd\xeb\xe4\xf8\x29\xc9\xee\x8f\x06\x7a\xc6\xd1\x89\xf3\x64"
-  "\xfc\xe8\x02\x01\x47\x9f\x17\x70\xf4\x79\x09\x47\x3f\x3b\x2d\xf2"
-  "\xa3\xbf\x5e\x7d\xb2\xce\x19\x47\x27\x16\x39\x70\xb4\xfe\x7a\x1c"
-  "\x15\x31\x94\xc6\x06\x87\x7a\x50\x87\x55\x02\x38\xfd\xee\xf3\x3a"
-  "\xaa\x8b\x42\xbd\x20\xea\x60\x1d\x3a\xa8\x0e\x11\x4f\xdb\x48\xfa"
-  "\x3c\xc4\xd3\x7c\x8a\xa7\x01\x0a\x12\x07\xd8\x37\x40\x8c\x1d\xbe"
-  "\x3b\x85\xa8\x71\x2e\xa2\x7e\x89\x5b\xc5\x62\xa0\x89\x7a\x26\xf8"
-  "\x5e\xba\x8f\x3f\xff\x6b\x01\x53\x31\x8e\x6c\x20\x8d\x1f\xae\xdd"
-  "\x95\xe2\x86\x37\x5d\x0b\x98\xba\xc6\x89\x37\x85\xb9\xff\xe1\xf3"
-  "\xae\x98\xfa\x9b\xfe\xd5\x38\x56\x10\x53\x65\x72\x7c\xf1\xcf\x40"
-  "\x8e\xff\xcd\x22\x39\x96\xfe\x26\x5f\x8e\xa5\xbf\x99\x2e\x61\xa9"
-  "\x70\xef\x96\xf0\xa6\xbf\x89\xbf\x33\xbc\xe9\x6f\xe2\x25\x39\xfe"
-  "\xd1\xc7\x1c\x58\x5a\xeb\x09\x4b\x27\xc6\xbb\xc7\x52\xc8\xa7\x58"
-  "\x3a\x31\xde\x81\xa5\xb5\x6e\xe4\x78\x19\x96\x46\x8d\x64\x58\x5a"
-  "\xcc\x78\xd3\x3a\x91\x37\x2d\xfe\x27\x94\xe3\xa3\xc2\xbc\x95\xe3"
-  "\x4f\xb5\x30\xfc\x44\x7c\x12\x31\x54\x92\xe3\x8b\x3d\xcb\xf1\x3d"
-  "\x60\xa8\x57\xbc\x28\xc5\xd0\xc7\x46\xca\x31\xf4\xb1\xfb\xe5\x18"
-  "\x1a\xbd\xc3\x15\x43\xaf\xc7\xcf\xc7\x16\xbb\xc3\x4e\x26\xc7\x47"
-  "\x4f\xf1\x8c\x9b\x8f\xe5\x79\x8f\x9b\x8f\xbf\x27\xc7\xcd\xc7\xea"
-  "\xfe\x35\x70\x73\xd2\x64\x19\x6e\xaa\x6e\x10\x37\x7f\x12\x99\x7e"
-  "\x92\x8b\xfe\x73\x92\x8b\xfe\x73\x92\x93\xfe\x73\xd2\x2d\xd4\x7f"
-  "\x4e\xba\x43\xfa\xcf\x49\x05\x12\x0f\x1a\xbd\xba\x67\xdc\x7c\xac"
-  "\xc0\x3d\x6e\x42\x3e\xc5\xcd\xc7\x0a\x24\xdc\xec\x89\x07\x9d\x3c"
-  "\xdf\x0b\xdc\xfc\x99\xcb\xf4\x93\xbb\xd5\x7f\xba\x93\xe9\x11\x37"
-  "\x29\x5e\xd6\xb9\xc8\xf4\x73\x9c\x65\xfa\x62\x49\xa6\x9f\xc2\x70"
-  "\xcb\x68\xd3\xcb\x65\xfa\x5b\x8e\xa3\x4f\x2c\xb5\x3a\xf4\xa1\x7f"
-  "\x00\x1c\x7d\x82\xfa\xe5\xb2\x3a\xf4\xa1\x4f\xb6\x89\xed\x62\x32"
-  "\xfd\x56\xc2\xda\xe5\x46\xa6\xa7\x76\xc3\x4f\x1c\x73\xc8\xf4\x75"
-  "\xae\x32\xfd\x93\x6f\x79\xc6\xd4\x27\x9a\xdc\xca\xf4\x28\x7f\x53"
-  "\x4c\xd5\x51\x4c\x6d\xdf\xee\x8c\xa9\x53\x7a\x51\x4c\x7d\x42\xc4"
-  "\xd4\xff\x08\xb7\xc2\xdc\xb4\xf6\xee\x19\x53\xb1\x1e\x09\x53\x13"
-  "\x7e\x1a\x4c\x35\xdc\x38\xa6\x3a\x9f\x5d\xfd\x10\xbe\xdd\x81\xa9"
-  "\x94\xc6\x53\xde\xac\x8e\x45\x4c\x4d\x70\x91\xef\x8b\xdd\xcb\xf7"
-  "\x27\x89\x12\xe9\x23\xca\xf7\xd8\x07\x14\x6f\x6e\xab\x7c\x3f\xe5"
-  "\x9a\x1c\x5b\x9f\x0c\x97\x63\xeb\x94\x73\x12\xb6\x0a\xf7\x6e\x89"
-  "\x7c\x3f\xc5\x7a\x67\xe4\xfb\x29\x56\x09\x5b\x9f\xfc\xa2\x67\x6c"
-  "\x7d\xc2\xec\x1e\x5b\x21\x9f\x62\xeb\x13\xe6\x6e\xb1\xf5\x09\x67"
-  "\x6c\x7d\xea\x84\x88\xad\x92\x7c\x0f\xe3\x03\xe7\x5f\xb2\xfe\xe6"
-  "\xe5\xfb\x27\xef\xb4\x7c\xff\x54\xb9\x57\xf2\xfd\x76\xc0\x59\x90"
-  "\xc5\xd7\x7e\x0e\xf2\xfd\xd3\x82\x7c\x5f\x5f\xe4\x22\xdf\x17\x5d"
-  "\x27\xdf\xa7\x3d\x2d\x60\x2a\xcc\x29\x8a\xa9\xcf\x17\xdf\xbc\x7c"
-  "\xff\x0c\xf6\xe1\xd4\x63\x72\x4c\x9d\x7a\x42\x8e\xa9\x33\xe7\x60"
-  "\xbb\x18\xa6\x17\xb9\x97\xef\xe9\x3c\x9f\x16\x28\x93\xef\xa1\x7d"
-  "\xd7\xcb\xf7\x33\x7b\xc9\x30\x75\x81\x33\xa6\x4e\x9b\x28\xe3\x53"
-  "\xe1\xbb\x10\x53\xf7\x9d\x65\x98\xfa\xce\x59\x27\x4c\x9d\xf1\x8e"
-  "\x80\xa9\xd3\x97\x9e\x9c\xed\x8c\xa9\xd3\x32\x45\x4c\xa5\x78\xb9"
-  "\xc0\xaa\xcc\x88\xf1\x6c\x6f\x52\x02\x75\xe3\x39\x31\xac\x73\xff"
-  "\xd9\x84\x9e\xed\x4d\x62\xe4\xf6\x26\x0e\x5b\x93\x64\x13\xa9\x6c"
-  "\xd4\x53\x5b\x93\x82\x14\x12\x1c\xb0\x9e\x0c\x2b\xe8\x64\x3e\x03"
-  "\xa8\xbf\xc2\x76\xf7\xfe\x02\xe6\x3f\x2b\xe1\x2c\xfa\x0c\x00\x8c"
-  "\xd5\xee\x6c\x67\xb6\x3f\xd0\xdf\xd7\xfb\x08\x10\xf9\x26\xc0\x83"
-  "\x43\x67\x5d\x71\x76\x86\xa2\x1a\xc7\xcf\xbc\x04\x17\x99\xbf\xe8"
-  "\x67\x20\xf3\xcf\x78\x56\x8e\xaf\x33\x36\xc9\xf1\x75\xc6\x63\x12"
-  "\xbe\x0a\xf7\x6e\x09\xef\x3a\x23\xe6\xce\xf0\xae\x33\x62\x24\x99"
-  "\x7f\xe6\x58\x07\xbe\xd6\x38\xe1\xeb\x59\x67\x7c\x9d\x16\x4d\xf1"
-  "\xf5\xac\x2b\xbe\x42\x3e\xc5\xd7\x69\xd1\x0e\x7c\xad\x71\x91\xf9"
-  "\xcf\xba\xe2\xeb\xac\x41\x14\x5f\x61\x2c\xc8\x79\xd7\xa2\x9e\x65"
-  "\xfe\xfa\x9f\x9b\xcc\x3f\x4b\xed\x95\xcc\x8f\x98\x9a\xc8\x30\x15"
-  "\x31\x4b\xc4\x55\x49\xe6\x2f\xf2\x28\xf3\xf7\x84\xab\x5e\xf1\xaa"
-  "\x14\x57\x9f\x1e\x24\xc7\xd5\xa7\xef\x91\xe3\xea\xec\x37\x5d\x71"
-  "\xf5\x7a\x4c\x7d\x7a\xbe\x3b\x3c\x65\x32\xff\xec\x59\x9e\xb1\xf4"
-  "\xe9\x8d\xde\x63\xe9\x33\x87\xe4\x58\xfa\x74\xe5\xbf\x2e\x96\xfe"
-  "\x76\xba\x0c\x4b\x55\x37\x88\xa5\x3f\x89\x1e\xe0\xb7\x6f\xc9\xb1"
-  "\xf4\xb7\x75\x72\x2c\xfd\xed\x66\x09\x4b\x85\x7b\xb7\x04\x4b\x7f"
-  "\xbb\xf7\xce\x60\xe9\x6f\xf7\x4a\xbc\xea\xec\xf5\x3d\x63\xe9\xd3"
-  "\x7a\xf7\x58\x0a\xf9\x14\x4b\x9f\xd6\x4b\x58\xfa\x75\x0f\x58\x3a"
-  "\x67\x91\x17\x58\x2a\xd7\x03\xb8\x62\xe9\x1d\xd7\x03\xcc\xf1\x78"
-  "\xfe\xc1\xad\x1e\x40\xc4\xd2\xa7\xaf\xd7\x03\x20\xbe\x52\x3d\x00"
-  "\xd0\x4b\xc4\x30\xaa\x07\x88\x66\x58\x66\xb4\x6d\x94\xe9\x01\x6e"
-  "\x3d\xb6\xce\x5d\x69\x75\xe8\x53\xb3\x00\x5b\xe7\xd2\xb8\xbd\x56"
-  "\x87\x3e\xf5\xb9\x40\xb1\x5d\x4c\x0f\xf0\x07\xc2\xda\xe5\x46\x0f"
-  "\xf0\x38\xad\xef\xa4\x4c\x0f\xe0\x84\xb5\x17\x14\xcf\x1e\xf3\x8c"
-  "\xb3\x73\xcd\x32\x3d\x40\x83\x84\xb3\xed\x68\x93\x0e\x38\x48\x71"
-  "\x36\xc4\x19\x67\x63\x86\x51\x9c\x7d\x5c\xc4\xd9\xff\x1c\xd3\x01"
-  "\x73\xb3\xc3\x5b\x9c\x45\x1b\xe9\xb3\xb1\x77\x06\x67\xcb\xbc\xc0"
-  "\x59\x27\xdd\xc0\x21\xa0\x87\x03\x67\x29\xdd\x63\x3e\xae\x9e\x87"
-  "\x38\x1b\xeb\xa2\x1b\x28\x72\xaf\x1b\x38\x71\x27\x74\x03\xcf\x0e"
-  "\x94\xe3\xed\xb3\x53\xe4\x78\x1b\x63\x97\xf0\x56\xb8\x77\x4b\x74"
-  "\x03\xcf\x06\xdf\x19\xdd\xc0\xb3\xc1\x12\xde\x3e\xfb\x43\xcf\x78"
-  "\x3b\xd7\xea\x1e\x6f\x21\x9f\xe2\xed\x5c\x6b\xb7\x78\xfb\xb8\x33"
-  "\xde\x3e\x77\x4e\xc4\x5b\x49\x37\x50\x24\xe8\x06\x36\xf6\xac\x1b"
-  "\xa8\xf7\xa0\x1b\x98\x7c\xa7\x75\x03\xcf\x99\xbc\xd1\x0d\x5c\xdb"
-  "\xce\xec\xf6\xd7\xa2\xdd\xfe\x7c\xc0\xdf\x59\xa7\x81\x06\x3d\xdb"
-  "\xed\xa7\x89\xf6\xa7\xb1\xf9\x02\xce\xe6\xbb\xd5\x0d\x9c\x6a\xf2"
-  "\xac\x1b\x38\x55\xeb\x6c\x7f\xfa\xbb\xaf\xe5\xfb\x56\xbf\x3b\x27"
-  "\xee\x5b\x9d\xfa\x12\x71\x76\xe1\x45\x4c\x73\x79\x53\x4d\xcc\x17"
-  "\xe1\xc2\x26\x6c\xa7\x3b\x3b\xfe\x0f\x39\xe7\xbd\xac\x79\xbf\x76"
-  "\xe8\x0a\x6a\x10\x6f\xf3\x09\xc7\x27\xf4\x46\x1f\xde\x54\x57\x30"
-  "\x17\xc7\xde\xc2\x1d\xce\xb8\x7b\xe4\x8c\x33\xee\xce\x4b\x10\x71"
-  "\xd7\x0e\xb8\xfb\x71\x43\x3e\xd3\xbf\x3e\xc7\x6c\x53\x4b\x9e\x73"
-  "\xb2\x4d\x3d\xfd\x89\x80\xbb\xf3\x17\x9d\x34\xc1\xf7\x77\x67\x3f"
-  "\x05\xcf\x1f\x38\x73\xa3\x36\xa8\xf9\x6e\x6d\xa7\x04\x7c\x72\x6b"
-  "\x3f\x05\x6d\x55\xed\x16\xe6\xaa\x1d\xe6\xe9\x6e\x27\xfb\xa9\x82"
-  "\x35\x30\x9f\x85\xb3\x57\xdd\xda\xa1\x3e\x27\xd9\xa1\xf2\x79\x53"
-  "\x43\x71\x7d\xe3\xb6\x4d\x35\x75\xf2\x09\x3e\x7c\xf0\xd4\x50\x7c"
-  "\x7f\x57\x17\xac\x3b\x93\x62\x7c\x04\xb9\x0e\xb1\x67\x00\xa3\xfb"
-  "\xfc\x22\x3b\xac\x35\x76\x58\x6b\xa0\xcf\x88\x0d\x79\x93\xed\x53"
-  "\x7d\x0b\x40\xce\xb3\x65\xd1\x98\x81\x7d\x73\x40\xd6\xdb\x83\x72"
-  "\xde\x65\x98\x1b\x19\x5a\x25\xb6\x47\xc4\xd1\x80\x26\xf8\x8e\xcb"
-  "\xdd\xf3\x72\xb6\x2b\x12\x8e\x1a\x9e\x3a\x05\xef\x5c\xb0\xad\x1a"
-  "\xc7\x6e\x8c\x74\xa6\x80\xf2\xcc\x1e\x6c\x65\xb1\x2d\xcc\xd7\x22"
-  "\x8c\x85\x5b\xa0\x93\x70\x6e\x8f\x1c\xd7\x17\x5c\x92\xe3\xfa\x42"
-  "\x8d\x1c\xd7\x17\x7c\x21\xe1\xba\x70\x0f\x70\x1d\xfa\x8d\xf2\xd1"
-  "\xb0\xf6\xdd\x24\x1f\xbd\xa0\x45\xc4\x75\x4e\xc0\xf5\xc2\x1b\xc0"
-  "\xf5\x6e\xf9\x68\x27\x5c\xf2\x8c\xeb\x0b\x5a\x24\x9d\xc4\xc2\x93"
-  "\x6e\x6d\x64\xcf\x38\xe3\xfa\x3c\x1d\xc5\xf5\x33\xae\xb8\x0e\xf9"
-  "\x14\xd7\xe7\xe9\x3c\x9e\x27\x38\xe3\xba\x9f\x16\xbb\x9f\xe2\x7a"
-  "\x9d\x60\x23\x5b\xe3\xc5\x79\x82\x3a\x86\xe9\x22\x96\xa3\xbe\xea"
-  "\xce\xea\x24\x62\x4b\xbc\xd1\x49\x50\x2c\x6f\x61\x58\x8e\xd8\x28"
-  "\xe2\xf9\x8d\x9c\x27\xe8\x09\xcf\x45\xbe\x19\xf1\xdc\x13\xdf\x2c"
-  "\xc7\xf3\xb8\xfd\x72\x3c\x8f\x7b\x4f\x8e\xe7\x8b\xf6\xcb\xf1\x7c"
-  "\x51\x89\x2b\x9e\x5f\x8f\xe5\xcf\xbb\xc5\x71\xdd\x5c\xd4\x51\x2c"
-  "\x9a\xe7\x19\xc3\x9f\x0f\xf7\x1e\xc3\x5f\xb8\xff\x5f\x0e\xc3\x55"
-  "\xae\x18\xfe\x42\x3c\x62\x90\x3d\xdb\x05\xc3\x97\x08\x18\x2e\xe0"
-  "\xc8\x9e\x66\x81\x17\x76\xc5\xf0\x16\xf8\x8e\x1e\xe4\x71\xdb\xf7"
-  "\xae\x18\x1e\xff\xac\x0c\xc3\x55\x3d\x60\xf8\x12\xa6\x07\x91\xd9"
-  "\xe5\x7a\xd0\x85\xc0\x77\x64\xee\xf6\xc0\x9b\x8b\x34\x73\x6e\x8f"
-  "\x1c\xc3\xe3\xdf\x93\x63\x78\x7c\xa3\x1c\xc3\xe3\x77\x48\x18\x2e"
-  "\xdc\xbb\x25\xbc\x79\x7c\xe9\x2d\xe7\xcd\xc5\xf1\xd1\x2d\x86\xc7"
-  "\x97\x4a\xbc\xf9\xa2\xcd\x3d\x63\xf8\xf3\x63\xdc\x63\x38\xe4\x53"
-  "\x0c\x7f\x7e\x8c\xc7\x73\x0e\xd7\x61\xf8\x8b\x4b\xbd\xc0\x70\xb9"
-  "\x2e\x44\xc4\x70\x41\x17\xb2\xc7\x49\x17\x62\xcf\x62\xba\x90\xdd"
-  "\xcd\x6c\x6c\x0c\x50\xb0\x71\x0a\xe3\x47\x5d\xa8\xec\x5e\x76\xdb"
-  "\x7d\x53\x7a\x90\x17\x13\xbd\xd1\x83\x50\xfc\xc6\x33\x0e\xcf\x02"
-  "\x6e\xd7\xdc\xe0\x19\x87\x29\xe2\x19\x07\xbd\x87\x33\x0e\x02\x9e"
-  "\x2f\xf8\x11\x78\x4e\xcf\x38\xfc\x7e\x9d\x5c\xc7\xfc\xfb\xf5\xa2"
-  "\x8e\x99\xe1\xf9\x4b\xb9\x72\x3c\x7f\x49\xef\x38\xf3\x00\x98\x6f"
-  "\xd4\x6d\xbd\xee\xcc\x83\x03\xdb\xa9\x1e\xf4\xf7\xe7\x0c\x73\x1b"
-  "\x89\x03\xdf\xe7\x49\xf8\x0e\x75\x3d\x26\xc3\xf6\x06\x67\x6c\x07"
-  "\xac\x75\xc6\xf6\xb3\xf9\x72\xfb\x88\x06\x9d\x13\xb6\x8b\x67\x1e"
-  "\x16\xf7\x3a\x59\xdf\x03\xb6\xc3\xf3\x37\x7e\x46\xec\xd6\x62\xbb"
-  "\x78\xbe\xc1\x2d\xb6\x3b\x9f\x6f\x70\xb2\x7f\x40\x6c\xa7\xb1\x2f"
-  "\x06\xba\x60\xfb\xda\x04\xa5\xfd\x38\xcc\x07\xc0\x75\x9c\x23\x76"
-  "\x1e\xb0\x9d\xd2\x7b\x71\x94\x33\xb6\x77\x65\x31\x6c\xdf\xd5\xfc"
-  "\xe3\xb1\xdd\xc1\x0f\x3b\x63\xfb\x13\x88\xed\x4b\x7e\xcd\xce\x5f"
-  "\x64\xde\xd8\xf9\x0b\x17\xfb\x8c\x5d\x37\xa0\x7f\xe9\x16\xe3\xdd"
-  "\xb4\x4b\x8e\xf1\x4b\xb6\xc9\x31\x7e\x49\x85\x1c\xe3\x97\xac\x93"
-  "\x30\x5e\xb8\x77\x4b\xf8\xf4\x25\x79\x77\x46\xff\xb2\x24\x4f\xc2"
-  "\xf8\x97\x96\xf7\x7c\xf6\x22\x41\xe5\xde\x36\x03\xf2\x29\xc6\x27"
-  "\xa8\xba\x3d\x7b\x21\xd3\x77\x27\xc6\xb9\x3d\x7b\x51\xf3\xd3\xd9"
-  "\x66\x38\x8f\x15\x57\xfd\xcb\xcd\xeb\xbe\x13\x63\xbd\xd5\xbf\xe0"
-  "\xd9\x8b\xb5\x5f\x38\x9d\xbd\xa8\xef\xf9\xec\x45\xda\x9c\x1b\xd4"
-  "\xbf\x74\x63\x9b\x71\x6a\x96\xb3\xbd\xdb\xd2\xf9\x72\x7c\x5f\x1a"
-  "\xe7\xc0\xf7\x67\x10\xdf\x97\xaf\x94\xe3\xfb\xf2\x64\x6c\xa7\xbb"
-  "\xb3\x18\x1f\xca\xf6\x15\x97\x7e\x2c\xb7\xd5\x70\xd1\xbf\x3c\x83"
-  "\x63\x6f\xf9\x48\x19\xbe\x9f\x75\xc6\xf7\xa5\x4d\xee\x78\x77\xd4"
-  "\x7b\x53\x9b\xe2\x05\x4e\x67\xda\x66\x88\xf6\x6f\xcb\x7e\x38\x19"
-  "\x03\xdf\x6f\xf2\x60\xeb\xb6\x80\xd9\xba\x51\xdb\x36\xd4\x83\x43"
-  "\x5d\xef\x2e\xd0\x29\xd3\x63\x79\x0e\x6d\xdd\x5c\xed\xdc\xd0\xf6"
-  "\x0d\x6d\xdd\xaa\x12\xf4\x1e\xed\xdc\x70\x6c\x7a\xb2\x75\x83\x76"
-  "\x07\x53\xac\x3f\x27\x60\xbd\x60\xeb\x56\x90\x22\xd9\xba\xc9\xb0"
-  "\xde\x8d\xfd\xf0\xa1\xb3\x99\xee\xf9\xf8\x0c\x09\xeb\x3b\x91\x8f"
-  "\xff\x77\x17\x5d\x0c\xed\x83\x97\xc3\x7f\x52\x5d\x0c\xc5\x7a\xdd"
-  "\xb0\x6a\x1c\xc7\xf3\x74\x6e\x74\x31\xd7\xdb\x38\xff\x74\xba\x18"
-  "\xdd\x6a\x39\xc6\xeb\x4a\xe4\x18\xaf\x8b\x93\x30\x5e\xb8\x77\x4b"
-  "\x30\x5e\x97\x7a\x67\x74\x31\xba\x54\x49\x17\xb3\x7c\x8e\x5b\xfb"
-  "\x3b\x99\x8e\x7d\xa9\xd9\xbd\x8e\x7d\xa9\x60\x7f\xb7\xd4\xec\xf1"
-  "\x4c\xc8\x75\x7b\x9a\x49\x13\x98\x8e\xfd\x26\xce\x84\xd4\xff\xdc"
-  "\x74\x31\x49\x1e\xfd\x7f\x79\xd2\xc5\x50\xdb\xe6\x2f\xd0\x3e\xc4"
-  "\xbb\x33\x21\x3d\x61\xbb\x83\x77\xef\x66\x0f\x53\x8e\xed\x2b\x26"
-  "\xc8\xb1\x7d\xc5\xaf\xe5\xd8\xbe\x6a\xb2\x1c\xdb\x57\x45\xbb\x62"
-  "\xfb\xf5\xb8\xbe\x62\xb3\x3b\x4c\xd7\x3d\x83\xba\x98\x14\x8b\x67"
-  "\x3c\x5f\x51\xe6\x3d\x9e\x27\x1f\xfb\x97\xc6\x73\x95\x2b\x9e\x27"
-  "\xdb\x7e\x52\xbd\x0c\xc5\xf3\x95\x3f\xc8\xf0\x5c\xd5\x03\x9e\xff"
-  "\x64\x7a\x99\x94\x27\xe5\x78\x9e\x92\x26\xc7\xf3\x94\xd1\x12\x9e"
-  "\x0b\xf7\x6e\x89\x5e\x26\x65\xca\x9d\xd1\xcb\xa4\x4c\x91\x78\xf6"
-  "\x55\x23\x7b\xc6\xf3\x15\x06\xf7\x78\xbe\xc2\xc0\xf0\x7c\x85\xc1"
-  "\xa3\x3d\xf5\x75\x78\x9e\xda\xcb\x0b\x3c\x77\x6b\xa3\xf2\xf3\xd0"
-  "\xcb\xa4\xfa\x7a\xab\x97\xf1\x74\x4e\x05\xf1\x5d\xb2\x4f\x71\x3a"
-  "\xa7\x12\x25\x9e\x53\xc9\x94\xdb\xa7\xdc\x72\x6c\x5f\x3d\x50\x8e"
-  "\xed\xab\x07\xc9\xb1\x7d\xdd\x58\x39\xb6\xaf\x1b\x23\xb6\x93\xe9"
-  "\x65\xb2\xae\x3b\xb7\x22\xc7\xf9\xd5\xab\x0d\xcf\x34\x12\x77\x58"
-  "\x7f\x41\x91\x76\xde\x33\xce\xaf\x2e\xf2\x84\xf3\x68\xaf\xf2\xe7"
-  "\x05\x09\x6e\x70\x7e\xcd\xbe\xff\x17\x70\xde\x93\x1d\x0a\x95\x83"
-  "\x00\xe3\x11\xef\x29\xbe\x0b\x58\x8f\x38\x6f\xff\xc8\x9d\x8e\x66"
-  "\x4d\xe3\xed\xc2\x79\xcf\x3a\x9a\xb5\xe7\xaa\xe7\x09\x38\x7f\x23"
-  "\x67\x68\x8e\xc9\x75\x34\x05\x4b\x6e\xb7\x8e\x26\x6d\x82\x1c\xef"
-  "\xd3\x12\xe5\x78\x9f\x36\x4c\xc2\x7b\xe1\xde\x2d\xe1\xdf\xd3\xc6"
-  "\xdf\x19\x1d\x4d\xda\x78\x09\xef\xd7\x0d\xec\x19\xef\x57\x17\xbb"
-  "\xc7\xfb\xd5\x82\x6f\xb6\xd5\xc5\x37\x8e\xf7\xe9\x0e\xbc\xbf\xfe"
-  "\xfc\x4c\xe6\xcd\xdb\xc8\x3c\x76\xa7\x75\x34\xe9\x1e\xf1\xbf\x3b"
-  "\xff\x18\x37\xaf\xa3\x11\xce\x24\x3e\xef\xde\x3f\xc6\xc9\x6e\x6c"
-  "\x64\x4e\x56\x3a\x63\x7d\x86\x42\x6e\x8b\x98\xd1\x4b\xb4\x45\x3c"
-  "\x59\x8d\x58\xbf\xe1\x01\x39\xd6\x6f\x08\xf7\xa4\xa3\x39\xc4\x39"
-  "\xdb\x24\x66\xc4\xc9\x75\x34\x45\x72\x1d\xcd\x0c\x1c\x7b\x59\x5f"
-  "\x7b\xc6\xfa\x8c\x4d\x72\x1b\x70\x76\x46\x71\xdf\x02\xc1\x06\x7c"
-  "\x81\x93\x0d\xf8\x53\xff\x2d\x60\x7d\xe6\xbe\x8a\x1a\x1b\xf1\xc6"
-  "\x0e\xf1\xc7\xdb\x7a\x6f\x74\x6b\x83\x48\xd7\x80\x6e\xec\x10\x17"
-  "\x7e\xa5\x42\x9b\x66\x6d\x61\x8a\x93\x1d\x22\xe0\xff\x4e\xa5\x8b"
-  "\xff\x62\x77\x76\x88\x0b\x74\x1e\xf1\xff\x1a\x2f\xe1\x3f\xf7\xb0"
-  "\xa4\xb7\xe1\x90\xcf\xa7\xfd\x92\xd9\x78\xbb\xf4\x36\xee\xf4\x24"
-  "\x86\xc7\x11\xff\xd7\x7f\xc5\xf8\xfc\x84\x9f\x99\xde\x26\x6b\xb4"
-  "\x1c\xf7\xb3\xe2\xe5\xb8\x9f\x35\x48\xc2\x7d\xe1\xde\x2d\xb1\x45"
-  "\xcf\x8a\xbc\x33\x7c\x7e\x56\xa4\xa4\xb7\xd9\xd0\xbf\x67\xdc\xcf"
-  "\xc8\x73\x8f\xfb\x19\x79\x0c\xf7\x33\xf2\xba\xd5\xdb\xc8\x6c\x23"
-  "\x37\xfc\xf0\xa3\xf5\x36\x22\x9f\x7f\xc7\xcf\xf5\x6c\x30\x7b\xa3"
-  "\xb7\x71\x9c\x49\xff\x51\x7a\x1b\xf7\x78\x2f\xf2\xf6\x27\xbb\xd9"
-  "\x73\x95\xe3\xfd\x2b\x3f\xc8\xf1\xfe\x95\x36\x39\xde\xbf\x16\x28"
-  "\xc7\xfb\xd7\x54\xee\xf4\x36\x72\xac\x7f\x75\xb2\x3b\x9c\xd7\xcd"
-  "\x40\xbd\xcd\x46\x83\x67\x8c\x7f\x55\xe7\x3d\xc6\x67\x6f\xfe\xff"
-  "\x31\xde\x05\xe3\x55\xae\x18\x9f\x5d\xf1\x93\xf2\xf8\x14\xe3\xff"
-  "\xeb\x63\x19\xc6\xdf\x42\x5d\xce\x8d\x9c\x27\xf1\xcc\xdb\x6f\x74"
-  "\xb1\x7f\xdf\xe8\x62\xff\xfe\x5f\x4e\xf6\xef\x1b\xa7\xdc\x3a\x8c"
-  "\xdf\x78\xeb\xed\xdf\x6f\x08\xe3\x37\x3a\xd9\xbf\x6f\xfc\xa1\x67"
-  "\x8c\x7f\x35\xd5\x3d\xc6\x43\x3e\xc5\xf8\x57\x53\xbb\xe5\xed\x65"
-  "\x18\xff\xda\x17\xb7\x43\x97\x73\x67\xce\x1b\xbd\x56\xeb\x8d\x3e"
-  "\xa7\x3b\xbf\x23\x1e\xf5\x39\xe3\x45\x7d\x8e\xce\x83\x3e\xe7\x56"
-  "\x61\xfe\x1f\xce\xcb\x31\xff\x0f\x17\xe5\x98\xbf\x65\x90\x1c\xf3"
-  "\xb7\xa8\xe5\xfa\x9c\xa4\xeb\xf4\x39\x72\xfc\x7f\xfd\x49\xc3\x0c"
-  "\x67\x7d\x4e\x91\x93\x3e\x27\xe7\xa4\x67\xfc\x7f\xdd\x23\xfe\xb7"
-  "\x53\xfc\x8f\x75\x83\xff\x9b\xfe\x45\xf0\x3f\xf6\x47\xe0\xff\xa6"
-  "\x3b\x80\xff\x9b\x4f\x30\x1d\xcf\x0d\xfa\x49\x39\xe4\xbd\x8e\xe7"
-  "\xc7\xad\x03\x39\xf7\xc8\xd7\x81\x9c\x59\xf2\x75\x20\xa7\x97\xb4"
-  "\x0e\x08\xf7\x6e\xc9\x3a\x90\x13\x7a\x67\xd6\x81\x9c\x50\x69\x1d"
-  "\xc8\xb9\xd6\xf3\x3a\xf0\xba\x87\x75\xe0\x75\x61\x1d\x78\xdd\x8b"
-  "\x75\x60\xcb\x45\xcf\x3a\x1e\xdd\xcd\xeb\x78\x26\xdc\xe9\x73\x50"
-  "\x5b\x9a\xbc\xd2\xf1\x6c\x9f\x66\xa8\x44\x1f\x29\xe7\x88\x72\x6d"
-  "\x9c\xa8\xe3\x31\xb8\xe8\x78\x0c\xd7\xe9\x78\x56\x9f\x13\xf0\x7f"
-  "\x9a\x70\xde\x74\xc6\x8f\xf0\x91\x42\xe3\x48\xeb\xcf\xcb\xed\xe6"
-  "\xf5\x14\xff\x25\xff\x7d\x79\x2b\xb1\x5d\x6c\xfd\x31\x74\xe3\x03"
-  "\x35\x77\xac\x4c\xa7\x33\xcd\x9d\x8f\x94\x3c\x99\xdd\x8d\xfc\xbc"
-  "\x69\x6e\xac\x0c\xef\x67\xb0\xf3\xa6\xef\xb8\xdb\xa7\x75\xf8\xe4"
-  "\xdf\xba\x9c\xfa\xe4\x77\xf8\xf2\xcb\xdd\x7b\x43\xbe\xa4\x17\x08"
-  "\xbe\xa4\xcf\xde\x01\x5f\xd2\x37\xea\x93\xff\xac\xab\xff\xbe\x37"
-  "\xfa\x1b\x2b\x0d\xa4\x1a\xc7\xc8\x3c\x57\xdf\xa7\x06\xf7\x67\xf7"
-  "\x95\xc2\xd9\xfd\x65\xb7\xc7\x0f\x0a\xb6\x87\xae\xf9\x41\xdb\x4d"
-  "\xfb\xd3\xcd\xb4\x3d\x18\xb3\x1b\xda\x9a\x5b\x09\x63\x95\x43\x3c"
-  "\x4d\x42\x3c\x7d\xa3\x9c\x96\x3d\x07\x63\x21\x68\x84\x19\xc7\x71"
-  "\x0e\x47\xfc\x75\x29\x88\xad\x6f\x50\xbb\x2f\x60\x23\x00\x5b\x59"
-  "\xb9\x75\xe7\x78\xbb\x3d\xe8\x57\x66\x68\x7f\x9f\x03\xcb\x6a\x7a"
-  "\x55\x9b\x2c\x30\x2f\x9a\x69\x0c\x57\xa3\xad\xc3\x80\x7d\x71\x64"
-  "\x59\x8d\x2f\x0f\xf8\xbb\xe7\x45\xe2\xe7\xdd\x3c\x7d\x43\x4f\xf9"
-  "\x19\x5c\xf7\x82\xb6\xb7\xa0\x1f\x10\x91\xb7\xe2\xae\x48\xfa\xad"
-  "\xdd\x40\x1f\x8e\x67\x6b\xdf\xc2\xc5\x0c\x37\xe0\x7d\x5a\xa0\x25"
-  "\xb5\xb1\x45\xdc\xa0\xb1\xab\x00\x37\x0a\xaf\x4a\xfb\xd8\x58\x3f"
-  "\xd2\x88\xe9\x51\xf2\x24\xfb\x17\x93\x27\x6c\xcd\x4d\x70\x8f\xad"
-  "\xb9\x09\x0c\x5b\x73\x13\x1c\xd8\x6a\x72\xa3\x47\x91\xd9\xb1\x6f"
-  "\x13\xec\x5f\x0c\x2e\x3c\xb6\xe1\x9f\xd0\x3f\xca\x36\xaf\xec\x5f"
-  "\x28\x9e\x26\x32\x3c\x45\xbc\x12\x31\x55\xd2\xa3\x18\x3c\xea\x51"
-  "\x7a\xc2\x54\xaf\xce\xf0\x53\x4c\xdd\x3e\x41\x8e\xa9\xdb\x7f\x2d"
-  "\xc7\xd4\x1d\x1f\xbb\x62\xea\xf5\x78\xba\x7d\x9d\x3b\x2c\x65\xfe"
-  "\x51\x76\x24\x7a\xc6\xd1\xed\xc5\x9e\x70\x94\xda\xa7\x2f\x70\xb2"
-  "\x4f\x77\xe0\xe8\x1f\x0f\xc9\x71\x74\x7b\xcb\x8d\xe2\x28\x8d\x6d"
-  "\x72\xf6\x27\x88\x6d\x72\xd3\x38\xaa\x73\xc1\xd1\xfc\x39\x12\x8e"
-  "\xba\xc6\x37\xe9\x01\x47\x97\xdc\x1e\x1f\x28\x32\x1c\xe5\xcc\xb4"
-  "\x3d\x9a\x65\xb4\xad\x5f\xc9\x71\x74\x87\xbf\x67\x1c\xcd\xdf\x27"
-  "\xe1\x28\x2b\x77\x7b\x71\x34\xbf\x4e\x86\xa3\x4b\x9c\x70\xf4\x7b"
-  "\x49\x86\x40\x1b\x0b\x07\x8e\x2e\x75\xc2\xd1\x25\x3d\xe1\x68\x7e"
-  "\x1d\xd2\x88\xf1\xa8\x3b\x76\xf7\x8c\xa3\xdb\x4b\xdd\xe3\x28\xe4"
-  "\x53\x1c\xdd\x5e\x2a\xe1\xa8\x1b\x1e\x55\x86\xa3\x3b\xd7\x7b\x81"
-  "\xa3\x3f\x73\xdf\x28\x3b\x33\xbd\xd2\x55\x48\x67\x3a\xaf\xf7\x91"
-  "\x3a\xdf\xf9\x4c\x50\x99\x4b\xdc\x93\xb2\xeb\xe2\x9e\xac\x16\xcf"
-  "\x78\x4e\x11\x70\xf5\xa9\x1f\x81\xab\xf4\x8c\xe7\xae\x5c\xb9\xed"
-  "\xc9\xae\x6d\xa2\xed\x09\xc3\xd5\x3d\xf7\x8b\xed\x92\xe2\x9e\x94"
-  "\x75\xe3\x23\x75\xd7\x79\x99\x6f\x94\x29\xce\xbe\x51\x0a\xbf\xf2"
-  "\xec\x23\xb5\xc0\x5f\xe6\x1b\xe5\x54\xb1\x23\xee\x89\xab\x8f\x54"
-  "\x09\x63\x77\xdf\x43\x31\xd6\xe1\x83\xaa\x60\x96\xc3\x47\x6a\x0f"
-  "\xe7\x82\xb0\x9e\x03\x0d\x09\xb7\x1f\x63\x0d\x5e\x60\xac\x2c\xee"
-  "\x89\xab\x8f\xa9\xdd\xc7\x8c\x15\x65\xa4\x3a\xb6\xcc\x8d\x6f\xd4"
-  "\xb2\x3b\x1a\xfb\x04\xdb\xe5\x1e\x6b\x0b\x27\xcb\xb1\xb6\x30\x95"
-  "\x96\xfd\xda\x1d\xd6\x16\x0e\x94\xb0\x96\x95\x5b\xf7\xb5\x0b\xd6"
-  "\xd6\x7b\xc0\x5a\x58\x57\xf7\x5c\xf0\x16\x6b\x0b\x69\xdc\x6c\x2e"
-  "\x4b\xc0\xda\xe6\x5b\x8d\xb5\x85\xd1\x12\xd6\xee\xb9\xab\xe7\x18"
-  "\x53\x05\xc1\xee\xcf\xe5\x14\x04\x33\xac\x2d\x08\xee\x36\xc6\x94"
-  "\xcc\xe6\x63\xcf\x35\x31\xc6\x94\xa4\x0f\x28\x13\xf4\x01\xff\xcc"
-  "\x31\x51\xf6\x58\xbd\xd5\x07\x7c\x06\xb2\x3b\x9e\xbb\x5c\x8b\x31"
-  "\xa7\xe6\x61\x4c\x94\x52\x17\x7d\x40\xe9\xf5\xfa\x80\x67\xbb\xc7"
-  "\x58\xaf\xf4\x01\xf4\xdc\x65\x51\x9b\x1c\x63\x8b\xae\xc9\x31\x76"
-  "\x6f\xae\x78\xce\x12\xdb\xe3\xd9\x67\xea\x9b\x93\x1d\xfa\x80\x7a"
-  "\x39\xb6\x4a\xfa\x80\xbd\x8f\x79\xc6\xd8\x37\xe5\xfa\xdf\xa7\x8a"
-  "\x65\xe7\x2c\xdf\x69\x70\xf6\x43\x2d\xfa\x9f\xfa\xef\xcd\x27\x6b"
-  "\x9d\x31\xf6\xcd\x83\xff\x4c\x7e\xa8\x1d\xbe\xa6\x7a\xb0\xe5\xbe"
-  "\xde\x0f\xf5\x9f\xee\x37\x56\x94\x12\x3c\xdb\x46\xf1\x56\xa6\x1b"
-  "\x28\xbd\x33\xba\x81\x8a\x52\x0f\xba\x81\x3f\xed\x97\xe3\xec\x9f"
-  "\x4c\xb4\xec\x57\xee\x70\xf6\x4f\xeb\x24\x9c\x65\xe5\xd6\x7d\xe5"
-  "\x82\xb3\x75\xb7\x92\xa7\xfd\x53\xc9\xed\xd5\x0d\xfc\xa9\x44\xd2"
-  "\x0d\xec\xbd\x81\xf3\x8f\x6f\xa6\xba\xc7\xd9\x37\x05\xbd\xeb\x9b"
-  "\x92\xde\xb5\xce\x4d\xbc\x14\x19\xce\xbe\x35\x47\x3c\xff\x48\x79"
-  "\xda\x7a\x91\xa7\x2d\xfd\x27\x8c\x97\xf2\xd6\x6c\x6f\x75\x03\x78"
-  "\xce\x1d\xb1\x15\xb1\x4b\xc4\x57\x49\x37\x50\xea\x59\x37\xd0\x03"
-  "\xbe\x7a\x1f\xbb\xef\xed\x39\x72\x7c\x7d\xfb\x59\x39\xbe\xee\x3b"
-  "\xef\x8a\xaf\xd7\x63\xeb\xdb\x3b\xdc\xe1\x2a\xd3\x0d\xec\xcb\xf3"
-  "\x8c\xa9\x6f\x97\x7b\xc2\x54\xea\xd3\xaf\x41\xb2\x91\x96\x30\xf5"
-  "\x7f\xce\xc9\x31\xf5\x7f\xfc\x6e\x14\x53\xef\x48\xbc\x94\x9b\xc6"
-  "\xd4\x04\x17\x4c\x2d\x5e\x27\x61\xaa\x6b\xcc\x94\x1e\x30\xf5\x76"
-  "\xe9\x09\x9c\x31\x55\xc6\xbb\xee\x53\xc8\x31\x75\xdf\x18\xcf\x98"
-  "\x5a\xfc\xb9\x84\xa9\xac\xdc\xed\xc5\x54\x54\x4b\xdc\x4e\x3d\xc1"
-  "\x3e\x22\xf1\xae\xfb\x4e\xf4\x8c\xa9\x6f\x57\xba\xc7\xd4\xb7\x2b"
-  "\x19\xa6\xbe\x5d\x79\xe3\x67\xca\xdf\xd9\xe7\x05\xa6\xfe\xcc\x63"
-  "\xa9\xbc\x53\xec\xb5\x9e\x00\xf5\xad\x88\xa5\xf5\x3f\xce\x77\x48"
-  "\xaa\xe8\x3b\x24\x5a\xc0\xd8\x27\x7e\x2c\xc6\xfe\xf9\x90\xdc\xa6"
-  "\xe1\xcf\x1f\x8b\x36\x0d\x0c\x63\xdf\x9d\x2f\x8f\x8f\x7a\xbd\xaf"
-  "\x10\xb9\x0f\xd5\x92\xfe\x0e\x3d\x01\x62\x6e\xb4\xb3\x9e\xe0\xdd"
-  "\xfe\x9e\xf1\xb6\x64\x8c\x4c\x4f\xf0\xa9\x7b\xbc\x6d\x97\xe1\xed"
-  "\xfe\xa7\x29\xde\x3a\x7c\xa8\x96\xa4\x8a\x3e\x54\x7b\xe4\x61\x65"
-  "\x78\x1b\xfb\xd3\xe0\x6d\xd9\x8d\xe3\xad\x3c\x96\x8a\xab\xbf\xd4"
-  "\xfd\x6d\xc6\x72\xc0\x5b\xea\xaf\xc3\xd5\x67\xea\x8d\xf9\xeb\xb8"
-  "\x5d\x3e\x53\xb1\x5d\xee\x71\xf7\xc0\x6a\x39\xee\x1e\x28\xa1\x65"
-  "\xdd\xe2\xee\x81\x27\x25\xdc\x65\xe5\x6e\x18\x77\x6f\x4a\x67\x70"
-  "\x20\xf5\xf6\xea\x0c\x0e\xa4\x4a\xb8\xfb\xee\xaf\x7b\xc6\xdd\x92"
-  "\x89\xee\x71\xb7\x64\x22\xc3\xdd\x92\x89\xdd\xe2\xae\xcc\x86\xa0"
-  "\xf4\x01\xb7\xbe\x3c\xea\xff\xd9\xe3\xac\x94\x86\xdf\x8c\xce\x00"
-  "\x30\x58\x99\x86\x3e\x9c\x62\xd1\x86\xa0\x67\x9d\x41\x4f\x78\xeb"
-  "\xbd\xce\xe0\xbd\xfb\xe5\x78\xfb\xde\x03\x72\xbc\x3d\xf8\x15\xb6"
-  "\xab\x5b\x9d\x01\xc5\x80\xf7\x56\x3b\x74\x06\x26\x39\xce\x4a\x3a"
-  "\x83\x83\xaf\x79\xde\xfb\x7a\x6f\xaf\x8c\xbf\x7d\xc2\xc5\x67\xf5"
-  "\x02\x09\x6f\x4f\x55\x8b\x36\x63\xff\xfb\xc5\xc9\x59\xce\x78\xfb"
-  "\x5e\xd3\x75\x3e\xab\x67\xdf\x42\x9f\xd5\xb3\x6f\xb1\xcf\xea\x39"
-  "\x72\x9f\xd5\x3b\xdb\x25\x3b\x32\xef\x7d\x56\xff\x65\x39\xc5\x60"
-  "\x1c\x43\xe8\xb7\xfa\x46\xf4\x08\xb7\x39\xd6\x8a\x0c\x7b\x65\x7a"
-  "\x84\xbf\xb4\xc9\xb1\xf7\xa0\xd6\x33\xf6\xfe\xe5\x84\x84\xbd\xac"
-  "\xdc\xed\xe5\x79\xff\x62\xb9\xbd\x7a\x84\xbf\x58\x24\x3d\xc2\xc1"
-  "\x43\x6e\xb1\x57\xb6\x37\xf6\x5e\x89\xfb\xbd\x31\xc8\xa7\xd8\xfb"
-  "\x5e\x89\x47\x3d\xc2\x75\xf6\x5b\xef\xef\x66\x7b\x63\x02\xcf\x6b"
-  "\xf2\x42\x8f\xf0\xb3\xb3\x31\x78\xbf\xe0\x66\xf4\x08\x88\xb7\x88"
-  "\x67\x22\xe6\xde\x88\x1e\xe1\xd6\xf3\xb8\x1f\xec\x96\x63\xee\x07"
-  "\x6f\xca\x31\xf7\xc3\xc7\x5c\x31\xf7\x7a\xbc\xfd\xe0\x9c\x3b\xac"
-  "\x65\x7a\x84\x43\x66\xcf\x38\xfb\x57\x7f\x8f\x38\xeb\x62\x9b\x2b"
-  "\xe1\x6c\xd9\xaf\xe5\x38\xfb\xd7\x59\x37\x85\xb3\x37\x1a\x83\xe5"
-  "\x67\x85\xb3\xb1\x2e\x38\x5b\xf6\x95\x84\xb3\xae\x71\x58\x7a\xc0"
-  "\xd9\xdb\x14\x87\xc5\x33\x8f\x7b\x68\xbe\x1c\x67\x0f\xe9\x3d\xe3"
-  "\xec\xa1\x07\x24\x9c\x65\xe5\x6e\x2f\xce\x1e\x9a\x77\x7b\x75\x0b"
-  "\x87\xe6\x49\x3c\xee\x87\xc3\x7a\xc6\xd9\xbf\x06\xbb\xc7\xd9\xbf"
-  "\x0a\xfb\x62\x7f\x0d\xf6\xc8\xe3\x5e\x87\xb3\x1f\xf5\xf2\x02\x67"
-  "\x7f\xe6\x36\x08\x1f\x79\xe5\xff\xc2\x49\x5f\xdb\xdb\x68\x72\x39"
-  "\x2f\xf1\x95\xf3\x79\x09\x27\xdd\x42\xb4\xa8\x5b\x90\xc7\x67\x49"
-  "\x15\xf5\xb7\x51\x02\xee\x3e\xfe\x63\x71\xf7\xf0\xc0\x0e\x07\xee"
-  "\x26\x01\xee\x1e\xa6\xe7\x23\x3a\x1c\xb8\x7b\xb4\x4a\x6c\x97\x14"
-  "\x9f\xc5\x83\x6e\xe1\x11\x5a\xdf\x62\x87\x6e\x01\x71\x38\xca\x59"
-  "\xb7\x70\x74\x9d\x67\x0c\x3e\xac\x97\xe9\x16\x3e\x71\x8f\xc1\x16"
-  "\x19\x06\x7f\x7c\x8c\x62\xf0\x23\x22\x06\x1f\xae\x6d\x07\xd9\xb2"
-  "\x3d\xdb\x3b\x0c\xb6\x50\x0c\x9e\x72\x67\x30\xf8\xe0\x2d\xc0\x60"
-  "\x4a\xf7\x23\x8b\x8c\x06\xc0\xe0\x79\x88\xc1\x53\x6e\x4c\xdf\xf0"
-  "\x13\xc5\x68\xc1\x76\xb9\xc7\xe2\x23\x17\xe5\x58\x7c\x34\x94\x96"
-  "\x75\x8b\xc5\x47\x0e\x49\x58\xcc\xca\xdd\x5e\x7d\xc3\x91\xa6\xdb"
-  "\xab\x6f\x38\xd2\x24\x61\xf1\xd1\xfd\x3d\x63\xf1\xe1\x7c\xf7\x58"
-  "\x0c\xf9\x14\x8b\x0f\xe7\x77\x8b\xc5\x8f\x38\x63\xb1\xc1\xc1\xf3"
-  "\xca\xf4\x0d\xa6\x7f\xf6\xd8\x2d\x06\x8f\xfc\xaf\xe6\x5e\x92\xd9"
-  "\xa0\x30\xb4\x19\xa1\x44\x6b\x16\xc9\x34\xda\x1e\x21\x90\x07\xf4"
-  "\x3b\x76\x8f\x51\x3d\x9e\x70\x5b\xc7\xd5\x20\x1e\xbf\x81\x7f\xc0"
-  "\xe3\xea\x95\xc2\xdc\xa2\x34\x3e\x46\xed\x5d\x31\x1f\xb1\x77\x8f"
-  "\xd3\x7d\x77\xef\xe2\xf5\xe3\x66\x09\xcf\xa5\xb2\x73\x37\xe3\x66"
-  "\x8b\x69\x1c\x9b\x26\xc5\xb1\x34\x3e\x77\xdc\x34\x73\xe0\xb8\x69"
-  "\xee\x9e\x1f\xae\x22\x7e\x03\xd6\xf3\x7c\xe1\x76\xde\xd2\x7a\xdf"
-  "\xc8\xd2\xd6\x3f\x10\xa2\xdf\xce\x9b\x3b\xb2\x8f\x1d\x84\x6f\xac"
-  "\xff\x23\x94\x6b\x0d\xda\x57\xda\x9a\x35\x8b\x40\x5e\x85\x98\x07"
-  "\x74\x23\x5c\x96\x0f\xcf\xc1\x3d\x7e\xeb\xb5\x82\x3d\xe9\x80\x55"
-  "\x69\x84\x8c\x6a\xc7\x39\x73\xac\x0e\xc6\x4c\x70\x0e\xd4\xb9\x05"
-  "\xea\xe2\x7f\x31\xc4\x02\xe3\xd1\xb7\xfa\x15\x82\x73\x7a\x23\x7c"
-  "\x57\x51\x0e\xd2\xde\xe7\x97\xf9\xbc\xd2\x97\x70\x6f\x8d\xf4\xe3"
-  "\x07\x4e\x37\x40\x7f\x10\x7d\x12\xf1\xc3\xef\xd8\x02\xe5\x78\x65"
-  "\x06\xcf\x8d\x1c\xa1\x37\xda\x2c\x6c\x4e\x43\xfb\x8e\x80\x1c\xcb"
-  "\xc3\x7b\x0b\x93\x88\x0a\xfe\xfc\xf9\x6d\xd3\x0d\x1d\xd9\x9f\xc4"
-  "\xc2\x77\x4e\xc1\x76\x79\xfa\xc6\x2d\x3b\x61\xdd\x19\xa2\xc6\xb5"
-  "\x83\xbe\x1f\xdf\x4d\xdf\xa3\xe4\x36\xda\x21\x9f\xcf\xca\xe0\x8d"
-  "\xa9\x36\x12\x00\xb4\xd8\x03\xed\xc6\xf1\xc8\xbd\x3d\xb2\x74\xc3"
-  "\x60\x42\x0e\xac\x69\x52\x1a\xa1\xed\xf6\x3f\x0e\xb1\x18\xd2\x1f"
-  "\x24\x70\xdf\x8c\x32\xcb\x05\xc5\xf1\xf9\x33\x2f\x12\x82\x78\x02"
-  "\xbf\x17\x5b\x60\x1d\x9b\x0e\xe9\x2d\xf0\x1d\x5c\xab\xda\x17\xcb"
-  "\x42\xfe\x40\x43\xca\x19\x12\xa0\x23\x7e\x39\xf0\x6d\xac\xec\x27"
-  "\x8d\x58\xd6\xa4\x38\x9e\x80\x6d\x80\xb4\x15\xd2\xf8\x1c\xda\x90"
-  "\x11\x7e\xef\x48\x3f\x3a\x36\xf3\xa6\x1b\xb8\x91\x23\xfd\x28\xf6"
-  "\xc1\x77\x6e\x81\x6f\x86\x32\xfe\x50\xc6\x9f\x5e\xd3\x89\x2a\x0f"
-  "\xf2\xb0\x1e\xb8\xfa\x1b\x96\x75\x62\xdd\xb5\x58\xb7\x07\x3a\xf8"
-  "\xf2\xc1\xd3\x0d\x3c\x8c\x6d\x5c\x53\x35\xe9\x8a\xcf\x1b\x14\xe5"
-  "\x7e\x01\x0a\x9e\xe7\xf7\x8e\xd0\x6f\x48\x27\xfe\x7a\x8e\x10\xc3"
-  "\x60\xac\xe7\xf8\x39\xa8\xdf\x17\x69\xd1\x91\x7d\xdc\x60\x52\x7c"
-  "\x92\x88\xf4\x85\xfe\xb4\x68\x86\xe3\x37\x94\xab\xf1\x3d\xf8\x8c"
-  "\x50\x9e\xfa\xbe\xc7\x36\x6b\xd2\x7d\x78\xb8\xaf\xf0\x51\x9c\x23"
-  "\x3e\x6a\xff\xe7\x3a\xb2\xcb\x89\x89\xbc\xde\x84\xcf\x9b\xd8\x73"
-  "\x30\x96\xca\x83\xa1\xcf\x36\x62\x1e\xa6\x3d\xb4\xd7\x5f\xec\xb7"
-  "\x2a\x35\x8c\x0d\xd7\xbe\x13\xc7\x08\x8c\x0b\x71\x8c\x60\x7b\xdf"
-  "\x4d\x37\x29\xe9\x3a\xac\x28\xa7\x72\x5d\x0e\xf4\xa1\x7d\x97\xda"
-  "\x77\x0b\xd0\x96\xeb\xc2\x7e\x69\x80\x7b\x27\x9e\xc5\x7e\xd9\xb2"
-  "\x06\xfa\x84\x95\x4d\x93\xda\x8f\xe9\x13\xb4\x3f\x39\xe8\x0b\x76"
-  "\x76\xf3\xc4\x03\xf8\x3d\x5b\xda\xa1\x1f\x43\x78\x4b\x39\xcc\x36"
-  "\x1e\xc7\x2d\x8c\x91\x03\x49\x56\x25\xda\xf5\x61\xfe\x91\xab\x56"
-  "\xe5\x96\x66\x82\x7c\x25\xd9\x0c\xb8\xbc\x3b\x05\x68\x0e\x75\xf2"
-  "\x61\x23\xf4\x11\x62\x3f\xae\x81\xbe\x4b\x81\xb1\x0b\x34\xdf\x02"
-  "\xf4\x2b\x04\xcc\xc3\xdf\x85\xb0\xfe\x70\x50\xce\xa4\x38\x91\x00"
-  "\xf5\xa9\x76\x87\xf0\xe6\x3d\x21\x7c\x0b\xd0\x70\x59\x47\xf6\x89"
-  "\x68\x91\x86\xd8\xa6\x2d\x90\xbf\x19\xee\x03\x3d\x0d\x6c\x0c\x95"
-  "\xeb\xc5\x6f\xf6\x44\xcf\x4d\x07\xc8\xf8\xcd\x07\x48\xe8\x1f\x0e"
-  "\x90\x89\x69\xf1\x30\x2f\xb3\x1e\xe5\x3f\x8b\xb5\xc1\x9a\xa8\xaf"
-  "\xe8\x0c\x19\x57\x8a\xfc\x21\xb7\x61\x48\xd1\xab\x07\x48\xf8\xfe"
-  "\x05\x45\xca\x99\x2d\x84\xe0\x1a\x3e\xb3\xd7\x37\xbc\x51\xd7\x46"
-  "\xb8\x40\x7d\x85\x7d\xc3\x2f\x83\x66\xb4\x11\x72\x42\x6b\x21\xe9"
-  "\xc9\xb0\x96\x5f\x6d\x22\xe9\x16\xde\x5c\x9d\x79\x91\x00\xf6\x44"
-  "\x33\xda\x7d\x6a\x9d\xb9\x88\x10\x3c\x33\xc8\x7d\xaf\x25\xfd\x13"
-  "\x88\x6f\xda\x57\x44\x9d\xd1\xc8\x37\xd9\xb7\x4f\x2a\x4a\x5f\x47"
-  "\x94\x07\xae\xd6\x31\xde\x53\xf1\xe9\xc9\x8f\xe1\x5d\x7c\x47\x0c"
-  "\x59\x68\x13\xd6\xa3\xbc\xe9\x15\x19\x8b\xc9\x20\xfc\x9e\x00\xca"
-  "\x7b\x7d\xba\x1c\xe8\x56\xe1\x1d\x3e\x7f\x3a\x91\xe1\x61\xa7\x21"
-  "\x63\x11\xdf\x04\x6b\x8a\x92\xcf\x88\x57\xf0\x9a\xb8\x32\x3e\xb7"
-  "\xd3\x60\xf4\x6d\x27\xc6\x04\x0b\x39\x0a\xef\xf6\xb2\x5e\xea\xff"
-  "\x9b\xae\x9f\xd0\xde\x39\x5a\x92\x49\xdb\x0c\xeb\x64\x40\x32\xf2"
-  "\x50\xfc\x37\xd8\xe6\x23\xf0\x7d\xfc\xb0\x38\x0d\x94\x0f\xc3\x35"
-  "\x73\xa6\xc9\x40\x2a\xad\x76\xb2\xb3\x99\xd2\xa5\x37\xd0\xc5\x17"
-  "\xfa\xd9\x0a\xb4\xf1\x73\xd7\x57\xd8\x4f\x9c\x5e\x5f\xc1\xf9\xb0"
-  "\xfe\xa0\x7d\x61\x61\x7d\x31\x63\x39\x81\xb5\x13\xfa\x23\x97\xf5"
-  "\x07\x37\x70\x5a\x29\xf6\x87\x77\xdf\xf1\xb7\x79\x9e\xd6\x14\x7c"
-  "\x37\x0f\x63\x02\xc7\x02\x17\x3c\xad\x14\xdf\x8d\x6d\xc0\x3d\x33"
-  "\xec\xfb\x99\xaf\x7e\xc3\x57\xeb\x9a\x88\x11\xbe\x87\x0f\x74\x6e"
-  "\x83\xcd\xdb\x36\x98\x3c\xb5\x61\xd3\x28\x18\xab\xa3\x60\xac\x8e"
-  "\x22\x13\xd7\x9a\xd8\x58\x3d\x55\xcf\xc6\xaa\x1d\xda\x75\x0d\xf8"
-  "\xf5\xb5\x73\x88\x12\xdb\x55\x72\x06\xfd\xf2\x41\x3b\x9b\xa4\xf1"
-  "\x3a\xfd\x12\xd0\x48\x1c\xb3\x3e\xbf\x0c\x42\xfa\x54\x5b\xea\x48"
-  "\x06\x8e\xd9\x4e\x77\x63\xf6\x64\xc9\xcc\x38\xe8\x9b\xdf\xc3\x98"
-  "\xfd\x4e\x4b\xfc\x1b\x89\xef\xba\x39\x30\x66\x9b\xdc\x8d\xd9\x93"
-  "\xeb\x0e\xc3\x3b\xaf\x1b\xb3\x8b\x9c\xc7\xec\xc9\x91\xde\x8f\xd9"
-  "\x0a\xb3\x63\xcc\x2e\xf6\x30\x66\xe3\x61\xcc\x3e\x97\xef\xe5\x98"
-  "\x3d\x39\xc5\xbb\x31\x5b\x51\x47\xc7\x6c\x3d\x8c\x59\x90\x3f\x76"
-  "\xbe\x48\xe9\xd2\x1b\xe8\x02\x63\xb6\xa2\x04\x68\xe3\x76\xcc\xfe"
-  "\xf4\x7d\xf6\x59\xec\x8d\xf7\xd9\x67\xa3\x7b\xee\xb3\x53\x5f\x79"
-  "\xdf\x67\xa7\xf6\xde\x9e\x3e\x3b\x65\xf3\xae\xcf\x4e\x6d\xf2\xdc"
-  "\x67\xa7\x62\x7f\x3e\x7d\x56\x15\x7c\xe3\x7d\x56\x79\xbe\xe7\x3e"
-  "\xab\xdc\xec\x7d\x9f\x55\xc6\xdc\x9e\x3e\xab\x2c\xf5\xae\xcf\x2a"
-  "\xa3\x3c\xf7\x59\x65\xb0\xa7\x3e\x9b\x34\x88\xe3\x39\xb4\x83\x0b"
-  "\x79\x48\x85\x3c\x0d\xe3\xbf\xaa\xce\xa1\x0c\x08\x69\x5f\x31\x4d"
-  "\x79\x24\x90\x93\x5d\xd2\xfe\x2e\x69\x95\x4b\x3a\xd8\x25\xad\x76"
-  "\x49\x87\x8a\x69\xe8\xa3\x5e\x97\x15\x55\x4f\x83\x0c\x96\x69\x52"
-  "\x54\xb5\x08\xf7\xc3\x16\xda\x35\x28\xc7\x85\xb9\x6b\xfb\x96\x2c"
-  "\xde\xda\x5f\x41\xf8\x2e\x25\x4f\x74\xe9\x64\x48\xb3\xa2\x3a\xb6"
-  "\x33\x0b\x44\x3c\x9f\xc1\x5a\xbe\x33\x93\x70\xfa\x4e\xcb\x8c\xd5"
-  "\x30\xa6\xcc\x20\xf7\x65\xa8\x7b\x43\xdd\xbf\x00\xba\x99\xab\x75"
-  "\x66\xe0\xb3\x8f\xf2\x0d\x8a\xea\xe9\xf8\x9d\xa3\x74\x06\xc2\xf9"
-  "\xfc\x52\x8b\x32\x0e\x97\xdb\x69\x31\xfb\xfc\x72\x30\xc8\x99\xa5"
-  "\x9b\xb3\x38\x3f\x63\x4b\x2d\xc9\x51\x72\x9a\xb4\x34\xe0\xd3\x5b"
-  "\x0e\x92\xb5\x2d\x7c\x53\x9a\x8d\xb7\x1a\xe7\x19\x70\x1f\xb6\xc9"
-  "\x98\x5a\x41\xaa\xcd\xb5\x04\xd7\x33\x1c\x9f\x46\xf3\x41\xb6\xef"
-  "\x8b\x65\x20\xaf\xda\x5c\x42\xaa\x20\x6d\x58\x76\x1e\xbe\xb3\xda"
-  "\x6e\x6c\x29\x21\x76\x7d\xa7\x99\x53\x75\xd6\xf2\xaa\xce\xba\xaa"
-  "\x16\x68\x9b\xbe\xb3\x1e\xdb\x5a\x0d\xed\xa0\x31\x37\x73\x3b\xeb"
-  "\x69\xbd\x96\x1a\xaa\x13\xb0\xe7\x42\xf9\x40\x28\x1f\xd8\x59\x87"
-  "\xed\xc3\xb6\xb9\x95\xdf\xf2\x1e\x8a\x86\xb6\x3f\x32\x47\xeb\x4b"
-  "\xf8\xf5\xbe\x6a\xef\xc6\x9b\x51\xe3\x51\x2e\xcc\x7b\xa8\x9c\xd5"
-  "\xeb\x77\x33\xf5\xa6\x7a\xae\x77\x8c\xd0\x5e\xd5\xcd\xd4\x5b\xd3"
-  "\x4d\xbd\x42\x7b\x35\x37\x51\x6f\x8d\xd6\x73\xbd\x63\x85\xf6\x46"
-  "\xdd\x4c\xbd\x9e\xe5\xee\xbc\xb1\x42\x7b\x33\x6f\xa6\xde\xba\x6e"
-  "\xfa\xed\xff\x63\xef\xec\xe3\xa2\xb8\xae\xff\x7f\x77\x16\x0c\x2a"
-  "\xca\x62\x17\x8b\xd6\x98\x55\xd1\xac\x8d\x46\x54\x30\xd8\x68\x83"
-  "\x11\x2d\xc6\x07\x30\x51\x8b\x4f\x11\x12\x34\x68\xd4\x20\x3e\x04"
-  "\x15\x01\x8d\x1a\x35\x88\x60\x80\x60\x04\xc5\x06\xf3\xc5\x56\x23"
-  "\xa6\xd8\x62\xab\x09\x36\xfa\x0d\x5a\x10\x4c\x35\xc5\x04\xeb\x6a"
-  "\xd0\xa0\x45\xb3\x0a\xca\xd3\xee\xce\xef\xdc\xb9\xb3\xcc\xce\xee"
-  "\xcc\xb2\x33\xab\x04\xbf\x3f\xff\xd8\x97\x38\x0f\x77\x66\xce\xf9"
-  "\xdc\x73\xdf\xe7\xce\xbd\x77\x82\xe4\x69\xe1\xbc\xe8\xf8\x07\xac"
-  "\x05\x79\x3a\x38\x6f\xe7\xf9\xfd\x82\xe4\x69\xe0\xbc\xe8\xfa\x3f"
-  "\x58\x03\xf2\xfc\xff\x8d\x5d\xff\xcb\xf3\xfd\x37\x71\xf6\x7c\x2f"
-  "\xcf\xef\xdf\x88\xea\x1f\xe7\xba\x74\xda\x30\x1d\xdd\x3d\x42\x65"
-  "\xca\xa0\x74\xa6\xee\xc3\xae\xbd\x67\x0a\x44\x63\xd7\x41\x3b\x97"
-  "\x89\x3c\xc7\x66\x23\xb4\x2e\x0b\x51\x29\x94\x89\x3a\xb4\xa6\x82"
-  "\x2a\x33\x04\xe0\x78\x65\xcc\x5d\xd5\xa0\xe8\x07\xdb\x4f\x46\x21"
-  "\x54\xb7\x5c\x8b\x48\x19\x94\x2e\x39\x3e\x10\x85\x18\x11\xee\xab"
-  "\xa8\xfb\x0a\x9e\x24\xe4\x2e\xc4\xd4\xcc\x06\xdc\x66\x7a\xc2\x79"
-  "\x06\xd0\x2e\x94\xd1\x80\x0e\x9b\xf4\x8a\xc0\x18\xe6\x38\x3d\xe4"
-  "\x94\x7a\x3a\x63\xd8\x35\x3a\x41\x8b\x36\xc2\xdf\x37\x14\xff\x3a"
-  "\xa3\xd4\x23\x6a\x0f\xe4\x9a\xf5\x9b\xff\x75\x4a\xa7\xb8\x90\x83"
-  "\xf3\x4f\xc8\x73\x6b\x12\xee\xe2\xfe\xf8\x08\xd5\x7b\x90\xf3\xe2"
-  "\x63\x3f\x33\xe9\xa9\xe7\xa3\x11\xf5\x95\x1e\xe7\xf6\xff\xd2\x9f"
-  "\x5c\x81\x90\x9d\xfe\x18\x17\x93\x7a\xa2\x0f\x3e\x1f\x97\x83\xfb"
-  "\x39\x77\x98\xc0\xae\xea\xc9\xc5\xf8\x7e\xe9\xb4\x11\x99\x45\x6b"
-  "\x70\x1b\x73\x21\x76\xdc\x40\xba\x1e\xb7\x19\xd0\x56\xf4\xbc\x05"
-  "\xff\x67\xf2\xf9\x0d\x74\x39\xad\x6a\x2c\xa6\x93\xbb\x04\x9e\xab"
-  "\xbb\x87\x8a\x56\x35\xa1\x6b\x8a\x0b\xab\xf1\xb5\x6b\xd5\x13\x35"
-  "\x75\xea\x89\xda\xfa\xcd\x17\x56\x98\xef\x17\x5f\xcb\xbc\x1d\xf7"
-  "\x5f\x90\x7b\xbc\x90\x76\x32\x4e\xfc\x1e\xe9\xf7\x7a\x76\x0b\xf1"
-  "\xa6\xf5\xd8\x86\x45\xf1\xf7\xe0\x5e\xbe\xed\x88\xed\x4c\xa7\xbd"
-  "\xa2\xaf\x4b\xd0\xf6\x26\xfd\x79\x17\x7d\x71\xbf\x10\xb4\x05\x55"
-  "\x4c\x1f\x4d\x6a\x53\x15\x33\x06\x07\x62\x3d\xe4\xf3\x79\x98\x77"
-  "\xee\x28\x2e\x18\xf1\x3d\x4f\xd7\x52\x12\x73\xa3\x0b\x0c\xff\x15"
-  "\xf5\xc6\x76\xb8\x78\x17\xae\xf7\xe2\x35\xc5\xc5\x69\x2c\xb7\x34"
-  "\xe0\xeb\xc1\x31\x3a\xb8\x66\x03\x9d\xd2\x58\x84\x8f\x83\xfd\x2b"
-  "\xc8\xfe\x66\xc4\xed\x6f\x06\x4d\x4c\x0c\x60\xf7\xa7\xb1\xfb\x5d"
-  "\x2c\xf6\xbb\x44\xf7\xc6\x7d\x76\x17\x8f\xe3\x67\x82\xf6\x4d\x07"
-  "\xe5\xd7\xe1\xf7\x01\xa4\xcf\xbd\x49\xc7\x5e\xa7\xae\x46\x71\xf1"
-  "\x62\x2d\xe8\x0a\xf6\x1b\x2c\xae\x6f\xf8\x2a\xd6\x17\x61\x7d\xd6"
-  "\x6f\xbe\x58\xad\x73\x51\x54\x90\x7e\x9e\x0b\xc4\x16\xd0\x5e\x5a"
-  "\x96\xa7\x53\x5c\x2c\xc0\x6d\x62\x1d\xb0\x22\x1c\x53\x82\xaf\x69"
-  "\x69\xff\xf9\x31\x31\xef\xc4\x68\xfa\x47\x6a\x22\x97\x44\x68\xde"
-  "\x7c\x67\xe5\xd2\x15\xa3\xfb\x47\x76\x42\xc8\x42\x3b\x2a\x7a\x83"
-  "\x07\x6d\x4a\x1b\x1f\x55\x96\x69\x40\x34\xa5\x82\xb6\xbb\x09\xa5"
-  "\x81\x5f\x0d\x19\x33\x02\x8d\xdd\xa7\x97\x1b\x33\x5e\x08\x4c\xb8"
-  "\x8f\xa8\x78\x6f\xfa\x6a\xd1\x9a\x97\xc1\x07\xdf\xae\xc7\xcc\x80"
-  "\x5b\xcb\x24\xd0\x6b\xd1\x9a\x7f\xe0\x6d\xbb\x98\xf7\x05\xe1\x64"
-  "\xdb\x9f\xe3\x8b\xa9\x2f\xe3\x2b\xa8\x92\xf0\x7b\xe8\x2b\x6f\x3d"
-  "\x3a\xa5\xb9\x87\xb2\xf0\x76\x53\x39\xf3\xde\x06\x8e\xbf\x89\xaf"
-  "\x85\xfb\xbe\xf0\xdf\xa4\x1f\xef\xdb\x25\xf8\x3a\x9a\x9e\xf8\x7d"
-  "\xc2\xb7\xcb\xf0\xf5\x74\x8a\x6f\xa3\x95\x59\x48\x01\x6c\xe4\x7e"
-  "\x47\xf1\xef\xc1\xa6\xf4\xf1\x51\x4c\xdd\xde\xfc\xad\xc6\x40\x79"
-  "\x8e\xd8\xb3\x13\xb9\xed\xdd\x89\x50\x56\x37\xe4\x52\xbf\xf9\xdf"
-  "\xde\x3a\x17\xef\x2c\x6c\x2f\x28\xda\xbd\x96\x42\x2f\xc1\xb6\x41"
-  "\x3a\xf4\x41\x12\xde\x06\xf5\xaa\x4e\x2c\x56\xe0\xf7\x68\x0d\xb9"
-  "\x7d\xcb\x4d\xea\xf1\x61\x34\xd8\xa2\xc1\xa7\x1f\xee\x63\x54\xe0"
-  "\x7a\x43\x7b\x8d\x0f\xab\x51\x5c\xd2\xfe\x6f\x21\x42\xf1\xb8\x9e"
-  "\x82\x3d\xfe\xf4\xa0\x01\xbf\x3f\x0b\x3c\xf8\x40\x0f\xff\x9f\x5e"
-  "\x7e\x60\x55\x03\x75\x36\xa8\x10\x69\x5e\xc5\x4c\xf5\xef\x7d\x13"
-  "\x23\x69\xc3\xaf\x43\x81\x43\xab\x3e\x47\xff\xac\x2c\x46\xee\x73"
-  "\x90\xb2\x65\x6d\xf7\x15\x88\x0a\xd1\xc1\xff\x57\x22\xea\x1c\xe4"
-  "\xfc\xb8\x2f\x3e\x7e\x0c\xee\x8f\x2f\x45\xb8\x8f\x9e\xa6\x92\x0c"
-  "\x87\xee\x35\x40\x5c\xaa\x76\xc5\x73\xc1\x4d\xaa\x8c\x62\x7c\xce"
-  "\xbc\x3a\xf6\xdd\x56\x2d\xfb\x6e\xab\x96\x79\xb7\xe5\x82\xdf\x6b"
-  "\xe1\xf7\x59\x71\xe1\xb4\xc9\xb8\x5c\xdb\x2d\x24\x5c\x49\xe3\x32"
-  "\xf1\xbb\xae\x2e\x90\x37\xd0\xcb\xb5\x5d\x77\xc5\x20\xf5\x39\x7d"
-  "\x35\x2a\xab\x2e\x46\xbb\x57\x21\x35\x5d\x1b\xd5\xb1\xe4\xd4\x59"
-  "\x44\xef\xdc\x59\x74\x38\xbe\xc8\xd5\x88\xfb\x46\x6a\xbd\x3b\x79"
-  "\xac\x57\x60\x2d\x77\x4d\x8a\x41\x83\xf6\xde\x43\xbe\xf3\xae\x27"
-  "\x32\xeb\x3c\xe1\x6f\xf2\x19\x6a\xb5\x9a\xe6\x5a\x6d\xdf\xa6\xe5"
-  "\xda\xde\x1e\x7a\xf2\x2e\x6c\xee\x42\x15\xc2\xef\xbb\xe8\xcd\x5f"
-  "\xe7\xee\xc5\x7d\xd2\x75\x7a\x64\xf0\xcc\x28\xc6\xfa\x84\xeb\xf6"
-  "\xc2\xef\x4f\x12\x56\x23\x95\xe9\x07\x2d\x2a\xad\xb9\x87\x86\x80"
-  "\x6e\xf0\xbb\x82\x3d\xd7\xc8\xbb\x02\x63\x6a\x4a\x31\x7e\x5f\x50"
-  "\xbf\x5c\x4b\x4d\xbe\x0d\x6d\xd5\xe6\x7f\x07\x35\xf5\xef\x5b\x7e"
-  "\x5a\x7b\x19\xb7\x07\x7e\x5c\xbd\xaf\xb8\x2f\xaf\xde\x57\x30\xe3"
-  "\x9f\xf0\xfb\x33\x1a\xf4\x7c\xf0\x1e\xf6\x1b\xf8\xef\x9e\x9e\x7a"
-  "\xa5\x8a\x36\x94\x56\xfd\x11\xfc\x53\xc1\xf3\x0f\xe3\xcf\x98\x06"
-  "\xea\x46\x24\xf8\xe5\x3a\xf1\x55\x49\x1d\xf8\xe9\x24\x2e\x63\x62"
-  "\xf8\x21\xf0\x35\xe4\x4c\x54\x49\xc3\x65\x66\x9d\x0a\xec\xaf\x83"
-  "\x4d\xc5\xae\x4d\xea\x61\x3a\xfc\x1e\xb2\xde\xa7\xaf\xbe\x31\x6d"
-  "\x7c\x40\xb3\x7a\x7c\xb0\x9d\x77\x92\x2e\xd8\x5f\xeb\x16\x22\xb7"
-  "\x92\xaa\x8b\x88\xf1\xd9\x32\xd6\x67\x78\xec\xda\xbb\xda\xae\x86"
-  "\x7a\x6d\xb7\x5d\xe0\xab\x73\x2b\x74\xe8\xe3\x7b\x48\x5d\x56\x5d"
-  "\x81\xdf\xd7\x74\x7c\x65\x2a\x42\xaf\x1c\xa0\x4d\xa5\xa7\xbe\x63"
-  "\xfc\xf7\x19\xf8\xcf\x00\xfe\xc3\xef\x29\x5b\xfc\xb7\x0a\xfc\xf7"
-  "\x00\xfc\x77\x9b\xf3\x9f\xb1\x1e\xfc\x57\x0f\xfe\x7b\x17\xfc\x57"
-  "\x67\xed\xbf\x62\x2d\x7e\x97\x89\xdf\x19\x61\xff\xe1\xf1\xd2\xa6"
-  "\x77\xb5\xbd\x98\x77\x98\x6f\x6a\xd1\xde\x37\x90\xdb\xe0\x06\xa4"
-  "\x48\x38\x89\x54\x70\x9f\xaa\x67\xc1\xbe\x50\x1e\xe8\xfb\x1a\x2a"
-  "\x2b\x34\xa2\xb5\x33\x51\x6f\xec\x4f\x03\xeb\xcf\x32\xc3\x51\xf4"
-  "\xa0\x5e\x4b\x41\x99\x01\xbb\x1e\xa0\x51\x93\xae\x6b\xd0\xe9\x69"
-  "\xa5\x08\xfc\xa1\x33\xa5\xbf\xa2\x97\x5f\x0f\x2b\xf3\x1d\xaf\x87"
-  "\xdf\x0f\x7c\x52\x0f\xe5\xd6\xc3\xef\x4a\x84\xeb\x61\xe5\x3a\x79"
-  "\xf5\xb0\x32\xee\x49\x3d\x6c\x4f\xf5\xb0\x32\xca\xba\x1e\xb6\xb0"
-  "\x42\xcc\xfc\x25\x11\x0b\x97\x2e\x5c\xfa\x96\xe6\x8d\xd5\x2b\xe6"
-  "\x2f\x27\xc4\xc0\x63\x06\xad\xd1\x14\x48\x7d\x08\xed\xe9\x3f\xbd"
-  "\x2b\xd0\xe1\x9e\x15\x94\x69\xb6\xb7\x0b\x9d\x72\x40\x65\x4a\x39"
-  "\x90\xf2\x21\xb0\x2f\xae\xaf\x69\xc0\xb5\x37\x14\xd5\x69\x5f\xf7"
-  "\x02\xe6\x8b\xb9\x85\xf0\xdf\x84\x97\x16\x85\xe2\x79\x87\x99\x19"
-  "\x74\x35\x9e\x77\x78\x36\x08\xb7\xfd\x57\xba\x74\x0e\x83\x76\x7d"
-  "\xb6\x37\x6a\x9c\x1d\x46\x6d\xfb\x0e\xb9\x79\x54\xa0\x49\x26\x13"
-  "\x4d\x17\xc5\xdf\x02\xd6\xba\x5e\x51\x34\xeb\x16\xd2\xac\x71\x83"
-  "\x63\xab\xfc\x35\x6b\xd6\xe3\x7f\x7b\x68\xd6\x6c\xbe\x72\x43\xf1"
-  "\xc3\x25\x5c\xee\x76\x28\xcf\x34\xa0\xbf\x06\xbf\x17\x85\xba\x48"
-  "\x65\x67\xd0\x55\x87\x97\xea\xa8\xf7\x9a\x10\x7a\x6f\x0d\x72\xc1"
-  "\xeb\x4c\x14\xf5\xc6\xf7\xf1\xc3\xc8\x10\xc3\x15\x3a\x09\xf6\x7f"
-  "\x79\x43\x47\xed\x81\xfd\x78\x0d\xd0\x3a\x55\x63\xd1\x46\xb8\x77"
-  "\xb8\x2f\xdd\xc7\xdd\xe9\x4a\xbd\xd7\xf8\x28\x17\x0d\xa2\xea\x37"
-  "\x5f\x89\x06\x0e\x09\xc0\x0c\xb1\x05\xf6\x6d\x83\x7d\xe4\x9d\xdd"
-  "\xb5\x3a\xe3\xe6\xff\x4c\xc2\x71\x0a\xf4\xaa\xb8\xa3\xb8\x72\xa2"
-  "\x11\x9e\x0b\xca\xd5\xe3\x7b\xc1\xdf\xa4\x35\xec\xef\xab\x37\xee"
-  "\xef\x87\x1a\xd2\xc7\x07\x37\x79\x8d\x0f\xc0\x31\x6c\xfa\x40\xe6"
-  "\xdd\x34\x1c\x7f\x95\xf9\x1e\x5f\xb3\xfa\x85\x40\xcc\xd1\xb5\xea"
-  "\x19\x81\xb5\x69\xd3\xcb\xcf\xc6\xe5\xb3\xf1\xeb\xca\xcd\x57\x32"
-  "\xd9\xf8\x95\x09\xf5\x23\x0c\xe2\x57\x98\x6d\xfc\x22\xef\xf2\x8d"
-  "\x88\xc4\xb1\x52\x04\x79\x47\x15\xae\x1f\x98\x05\x0f\x35\x41\xfd"
-  "\x01\xed\x63\x8d\x33\xf1\x0c\x62\x99\xb9\x1e\xe0\x3a\x82\x63\x16"
-  "\x53\x27\xad\xea\x04\xae\x07\x9d\xf5\x48\x85\xeb\x01\x8e\x69\xb8"
-  "\x1e\xe0\x31\x32\x1f\x3e\x20\xf5\xc0\xa3\x12\xa9\x98\xba\x60\x28"
-  "\x66\xea\x02\xbe\xff\x12\x83\x55\x1c\xb3\xa8\x07\xdb\xcd\xf5\xc0"
-  "\x1c\xc7\x40\xeb\x06\x5c\x0f\xde\xe5\xd7\x83\xd9\x97\x55\x88\x89"
-  "\x71\x9b\xbf\xd6\x66\x41\x3d\xc0\xfd\x54\x46\x73\x1c\x83\x7a\x80"
-  "\xe7\xf0\x30\x71\xec\x6d\x36\x8e\xe9\x61\x3b\xe8\x7f\xcf\x22\x7e"
-  "\x1c\x6b\xac\x6f\x8d\x27\xae\x8e\x93\x17\xc7\xae\x32\xeb\x5f\x60"
-  "\x5f\x61\xbf\x61\x7f\x61\x1f\x3d\x4e\xfe\xc1\x71\xca\xa8\x4a\x29"
-  "\xee\x02\xbe\xe9\x52\x83\xba\xe2\x78\x85\xe3\x54\xb6\x88\x7f\xe0"
-  "\xdc\x1a\xb8\xbe\x80\x8f\x4e\xc7\x65\x59\xc4\x2a\x1c\xa3\x70\xbc"
-  "\xc2\x71\x0a\xc7\x2c\x3c\x56\x01\xea\x42\x35\x8e\x57\xcf\xc6\x91"
-  "\x38\x85\xe3\x57\xc2\x75\x12\xbb\x4a\xa3\x48\xcc\x4a\x18\x87\x7a"
-  "\xe3\xef\x60\x19\x3d\x53\x8a\xf1\x37\xad\xca\x0c\xf7\x51\x23\x1b"
-  "\xb3\x3e\x5e\x85\x46\x4d\x5e\xa8\x41\x38\x56\x81\xed\x7d\x4f\x6b"
-  "\x2f\x22\x86\xff\xa9\x5f\x74\xc8\x06\xee\xdf\x0b\xdc\x9f\xd6\x0d"
-  "\xb9\xd5\x6f\xfe\x41\x6d\xcb\xfe\x3f\x68\xcd\xec\x8f\xeb\x2c\xae"
-  "\xbb\x3a\xc5\x95\x8d\x4c\x1e\xd8\xf3\x37\x38\xe6\x90\x77\x9a\x69"
-  "\x63\x53\x48\x5f\xfa\x4d\x46\x13\x38\x6f\xe6\x72\xe6\x1f\x56\x92"
-  "\x77\xe3\x90\x23\x7b\x8d\xc8\xa4\x53\x1b\x8b\xb1\x2d\xd9\x3a\x5e"
-  "\x43\xa7\x4f\xd4\x60\x4d\xcd\x1b\x88\xdc\x0c\xe9\x13\x7d\x8c\xe9"
-  "\x13\xb5\x44\x5f\x3f\xec\x3f\x0d\xd9\xf5\xf4\x58\xa9\xfa\xfa\x81"
-  "\xbc\xff\xf8\x3e\xec\x17\xf4\xec\x30\x17\xd3\xf7\x61\xae\xa0\x05"
-  "\xef\x77\x8c\x89\xe8\x41\xca\xa2\xe0\x04\x03\x5d\xad\x59\x83\x7e"
-  "\x0d\xb1\xcf\xf5\x2c\xb4\xa8\x67\x21\x43\x2d\x0b\x5d\x0c\x7e\x5d"
-  "\x58\x7c\xd8\xa4\x77\x81\xe7\x73\x87\x9c\xbf\x1a\x62\xa9\x8b\x65"
-  "\x2c\x25\x71\xf3\x8a\x3b\x33\x2e\x3b\x65\x51\x18\x2e\x2b\xa4\x18"
-  "\x79\x68\xc6\xe3\xb1\x77\xd7\x0f\xac\x5e\x87\xf0\x7c\x52\x57\xf8"
-  "\x7b\x65\xe3\xce\x91\xc5\x70\x7e\x57\xfa\xfb\x69\x8a\xe8\xf1\xd0"
-  "\x9e\xcc\x9e\xa6\xc0\x63\x01\xfe\x18\x9f\x49\x99\x60\x1b\x19\x5b"
-  "\x94\x89\xf0\xfe\xa4\x26\x17\x86\x9b\x4c\x70\xcc\xb9\xba\x4c\x94"
-  "\xb4\xca\x0d\xe1\xe3\xc9\x78\xb5\x4c\x84\x8f\xdf\x1e\xa3\x62\xc6"
-  "\x12\x30\xe7\x19\x32\x11\x3e\xd7\x08\xdb\x3f\x30\xb9\xa3\xe4\x35"
-  "\x6a\x74\x36\xf4\x1c\x53\xc6\xd9\xd0\xff\x45\xb8\x0c\x1c\xbb\xcf"
-  "\x86\x7e\x81\x76\xac\xf2\x86\x3a\x9e\x09\xfb\xbf\x45\x3b\xee\xf4"
-  "\x82\x7f\x6f\xc0\xef\x01\xba\xa5\xb8\xae\x3e\x1b\x6a\x42\x1e\xeb"
-  "\x5f\xa2\x21\xb6\xd0\x65\x78\x8e\x62\x3c\xea\x00\xf7\xce\xac\x9d"
-  "\xab\x53\x54\xb9\xe0\x39\xec\x65\x15\x29\x88\x4e\x98\x5d\x63\xa2"
-  "\x67\xdf\x36\x25\xcc\xbe\x83\xaf\x6f\xa4\x67\xff\x84\xaf\xbf\x7d"
-  "\x8d\x86\x1d\xc3\x9a\xc9\x8c\xb7\x4b\x7a\xe0\x83\xf0\xfd\xe2\x6b"
-  "\xe3\x6b\xee\x88\xd1\xb2\xd7\x1d\xc4\xdc\x1f\xbe\x2e\x2e\xd7\xf2"
-  "\xba\xf8\x1b\xf1\x9a\x19\xcc\x75\xd3\xe1\x5f\x4f\xf0\x89\x1b\xf6"
-  "\x05\xbe\xae\x89\x0e\x73\xa5\x13\xc2\x94\xcc\x39\xb1\xd5\x42\xe7"
-  "\x9c\x61\xcf\x61\xc6\xa3\xe2\x73\x9a\xc8\xf1\x4c\x19\xd0\xde\x5d"
-  "\xc7\xdb\x9f\x0b\x2b\x42\xb6\x7e\xbc\xb1\x9e\xb4\x7f\x37\xa6\x92"
-  "\xf6\x8f\xf8\x95\xd1\xcb\xec\x30\x57\xf0\x9d\x0a\xb7\x95\xd7\x14"
-  "\x37\x06\xb6\x94\xf1\x7d\x98\x12\xfb\x1c\x6b\xc7\xac\x27\xac\x25"
-  "\xb3\x8e\x98\xfb\x8c\x46\xc8\x52\x37\xf0\xb7\x1b\x5b\xce\x32\x73"
-  "\x39\x70\x0f\xc8\xac\xa5\xe7\x60\xbf\xad\x96\xaa\x27\x73\x5a\xfa"
-  "\xf1\x76\x43\x3c\x4d\x63\x2d\x15\xcd\xda\x80\xcb\x39\xc6\xdd\xcf"
-  "\x34\x05\xd6\xd9\x63\xa6\x2f\xb5\xd9\x57\xcf\xc5\x21\x35\x79\xa6"
-  "\x1f\xb7\x33\xcf\x14\x57\xa4\xc6\xf7\x6b\x7e\x16\x7c\x1f\xc9\x26"
-  "\x0d\x32\x3f\xcb\x8e\x26\x1f\x28\xfb\x0e\x62\xcf\x39\x89\xcb\x37"
-  "\xdb\x01\xfc\x86\xcc\xe7\x98\x8f\x4f\x36\x69\xe1\xde\x07\x31\xe7"
-  "\x10\xdd\xdd\x10\xd0\x50\x75\x17\x6b\xdd\x75\x8e\x43\x00\xb0\xc0"
-  "\x4c\xb3\xee\xc1\x75\xaa\x89\xff\xe3\xbe\x34\x36\xc1\x35\xc0\x0f"
-  "\x14\xbb\x7d\x8c\x85\x2e\xd8\xf2\x1b\x84\xca\x5f\xc2\x2b\x3f\x0c"
-  "\xca\x8f\x85\xf2\x31\x93\xcd\xc2\xfd\x5f\xd5\x5b\x99\x72\x62\x49"
-  "\xf9\x66\xed\xd2\x29\x23\x26\x45\xaf\xc1\xe3\x3e\x6f\xfa\x92\xb8"
-  "\xfa\x9f\xa3\xf8\x38\x66\xbc\x11\x65\xca\x31\x59\x8d\x37\xb2\x1c"
-  "\x8f\x76\x38\x5e\xcf\x8e\x35\xba\xc9\x7c\xdf\x03\xe2\x6c\x1d\x66"
-  "\xcb\x43\x37\x2a\x28\x6e\xbc\xd1\x77\x78\x7f\x8f\xa2\x55\xd7\x2c"
-  "\xc6\x1b\x55\xd7\x90\xba\x7f\x33\x08\x72\x48\x0a\xf6\x23\xb2\xfd"
-  "\x3f\x05\x96\xdb\xb9\xf1\x7c\x64\x3b\x1e\x2b\xcd\xf6\xb9\xd6\x7c"
-  "\x55\x88\xfb\xdc\x6e\xce\x31\xf7\x73\x8a\xe4\xa8\x12\xd8\xb7\x36"
-  "\x8b\x63\xdf\xda\x2c\x71\xf6\xbd\xd5\xd1\x3e\xfb\xea\xab\x38\xf6"
-  "\xfd\x69\x1c\xa9\xfb\x3f\x0d\x24\x75\xff\x0e\xb3\x46\x32\x30\x45"
-  "\xb5\xf1\x0f\x11\xbe\xe7\x20\x9a\x60\x0d\xed\x05\xc6\x38\xbc\xa6"
-  "\xc2\x8a\x7d\xf1\x38\xad\x3b\x13\xa6\x00\xfb\x42\xfb\x96\x43\xec"
-  "\x70\x6b\x2a\xd8\x5e\x59\xd6\xd0\x80\xf0\x76\x68\xdb\xaa\x30\xf7"
-  "\x7e\x61\xaa\xa0\xf6\x80\xfd\xe0\xe7\x52\xa7\x8e\x40\x96\x5c\x5c"
-  "\xbf\xf9\x56\xa2\x30\x0f\xdf\x71\x31\xf0\x78\xf8\x56\xa9\x99\x87"
-  "\xf1\xfd\x61\x06\xc6\x3c\x6c\xc0\xfd\x98\xfd\xfb\x21\xcc\xc3\x86"
-  "\x74\x4b\x1e\xae\xd9\xda\xc2\xc3\xdd\x2d\x78\x38\xd6\xcc\xc3\xb7"
-  "\x1a\x9f\xf0\xb0\xb3\x3c\x2c\x96\xd7\xd7\x4c\x97\xc7\xc3\x35\xd3"
-  "\xfe\xaf\xf0\xb0\x60\xde\x2e\xe0\x1f\xd0\x73\x8d\x41\x80\x87\x69"
-  "\xe0\xe1\xbd\x76\x78\x18\xd7\x03\xcc\xc2\x4c\xde\x1e\x09\xcc\x01"
-  "\x31\x00\x33\xb0\x99\x89\x31\x07\x63\x1e\xc6\xfc\x8b\x59\x99\xf1"
-  "\x9f\x27\xe7\x3f\x5b\x1e\xae\x09\xe4\x78\xb8\xdb\xdd\x2c\x1e\x0f"
-  "\xdf\xf1\xb1\xe5\xe1\x3b\x01\xb6\x3c\x7c\x2b\x8d\xe3\xe1\x5b\x01"
-  "\x7c\x1e\xae\x9b\x6c\xcb\xc3\x77\x36\x89\xf1\x30\x66\x60\xcc\xc3"
-  "\x38\x5f\xc0\x2c\x0c\x7f\x6b\x39\x7d\xdd\x39\x2a\x8f\x87\xef\x14"
-  "\x38\xc6\xc3\x3f\x79\x09\xf3\xf0\x2d\x37\x71\x1e\xbe\xe5\x26\xcc"
-  "\xc3\xfa\xa3\x1c\xc3\xe8\xd7\xb7\x7f\x1e\xd6\xfb\x08\xf3\x8a\x7e"
-  "\x30\x66\x02\x9d\xe2\x27\x35\xe6\xe1\x87\xcb\xc2\x3f\xa9\x85\x59"
-  "\x58\xbf\x8f\x30\xc3\x4f\xde\xb6\x2c\x0c\xe7\x08\xb2\xb0\xfe\x22"
-  "\x7b\x8e\x9a\xcf\xc2\xa4\x0c\x68\xff\xee\x8a\xb3\xf0\xdd\xed\xa4"
-  "\x3d\xbc\x3b\x97\xb4\x87\xc4\xa7\xb6\x2c\x7c\xd7\xbf\x75\x16\x26"
-  "\x1a\x62\xee\x53\x94\x85\xef\xae\xb3\x65\xe1\x5b\x6e\xc2\x2c\x5c"
-  "\x3b\x9d\xd3\xd1\xbd\xfb\x7c\x16\xbe\x7b\xfa\xf1\x60\x61\x51\x6d"
-  "\xf9\xf0\x39\xf8\x5e\xba\x74\x0e\xbe\x77\x46\x1a\x07\x63\xcd\x09"
-  "\x71\x70\xad\x97\xb5\xe6\xf8\x1c\x5c\x3b\x54\x98\x83\x6b\x27\xf0"
-  "\x39\x18\x97\x2f\xc4\xc1\xb5\x2b\x79\xe5\xdb\x70\x70\x6d\x2a\x9f"
-  "\x83\xc9\x71\x1c\x07\xd7\x05\xb0\xfd\x0b\x47\xa4\x73\x70\x5d\x0f"
-  "\xfb\x1c\x5c\xd7\x87\xcf\xc1\xb5\x75\x84\x77\xeb\x26\x11\x0e\xae"
-  "\x63\xb7\xdf\xcc\xb7\xdc\xce\x71\x30\xd9\x6e\xcb\xc1\x75\x91\xad"
-  "\x70\x70\x80\xe3\x1c\x4c\x0f\x2a\x6e\xe1\x60\x7a\x90\x99\x83\x4d"
-  "\x14\xf0\x25\xb4\xfd\xf0\xab\xc6\x73\x08\x70\x9d\xbb\xa1\xb8\xef"
-  "\x65\x9f\x85\x0d\x51\x1c\x0b\x37\x1d\x23\x75\xbf\x29\x9b\xd4\xfd"
-  "\xa6\xb9\x2d\x2c\xdc\x37\xc2\xb7\x74\x63\x0b\x0b\x57\x1c\x5e\x53"
-  "\x6e\xc5\xc2\xd8\x76\x4d\x0c\x0b\xef\x78\xc0\x8c\xd7\xd0\xe1\xf6"
-  "\x7c\x4a\xdc\x15\x3a\x09\xda\x70\x68\xc3\x74\xc4\xbe\x8d\x07\xb2"
-  "\x32\xe8\x4a\x8e\x97\xef\xaf\x6f\xe1\xe5\x38\xa6\x0f\xb9\x82\xe1"
-  "\xe5\x05\xe5\x54\x36\x94\x0f\x3f\x17\xcc\xca\x98\x99\x81\x95\x2f"
-  "\x64\x67\xd0\xe5\x7b\x32\xe8\x92\xfa\xcd\xf7\x0b\xcc\xcc\xbc\x1d"
-  "\xb6\x25\xc3\xb6\x53\x39\x70\xfc\x03\xe6\xe7\x02\xb6\xaf\x7c\x0f"
-  "\xae\x89\xcf\x83\x63\x75\xe6\x63\xa1\x9d\xbe\x40\xd8\xba\x31\xca"
-  "\xd4\xc1\x92\xad\x1f\x0c\x36\xb3\x75\x32\x3c\x2f\x66\x28\x33\x5b"
-  "\x9b\x80\xad\x69\x2f\xd2\xdf\xcc\xe7\xeb\xfa\x9b\x66\xbe\x4e\xb6"
-  "\xe4\xeb\x68\x33\x5f\x3f\x98\x29\x93\xaf\x2b\xfe\x2f\xf3\x35\x66"
-  "\x6b\xcc\xd3\x98\xad\x31\x6b\x63\xbe\xc6\xac\x6d\x62\xf9\x7a\x8f"
-  "\x25\x5f\x77\xb0\xe0\x6b\x85\x25\x5f\xd7\x1f\x95\xc7\xd7\xf5\x05"
-  "\x96\x7c\x0d\x7e\xab\x90\xca\xd7\xd8\xc7\x36\xef\x33\xf1\x78\x1b"
-  "\xf0\x13\xf6\x89\xdd\xf7\x62\xac\xbf\xb0\x7f\xb0\x6f\xb0\x8f\x1c"
-  "\xf2\x0f\xe8\xab\xa4\xe1\xe7\xe3\x6b\xad\x15\x5f\x63\x9e\x06\xdb"
-  "\x55\x61\xce\x2e\x2b\x02\xdb\x2c\x03\xd6\x06\xce\x6e\x9d\xb1\xeb"
-  "\x73\x2c\x19\x7b\x4f\x37\x4b\xc6\x6e\xdc\x62\xcb\xd8\x8d\x59\x16"
-  "\x8c\x7d\x41\xa7\xb8\xcf\xcc\x41\x28\x5a\x80\xd9\xf9\x7e\x14\x9f"
-  "\xaf\xe9\xcb\xb6\x7c\xdd\x78\x5d\x8c\xaf\xf1\x38\x31\xeb\xfe\x66"
-  "\x93\x97\xb9\xbf\xb9\xc9\x4b\x1e\x5f\x37\xa9\x39\xfe\xbf\x1f\x44"
-  "\xda\x88\x46\x51\xe6\xae\x57\x59\x32\x77\xd3\x56\x8e\xb9\x57\x58"
-  "\x30\xf7\x7d\xb5\x38\x73\xdf\x67\xae\x47\xab\x16\x85\xe1\xb2\x30"
-  "\x2b\xe1\xbe\x0a\x0d\x33\xc7\xdc\x30\x12\xf3\x12\xee\x83\x80\x67"
-  "\x02\x66\x32\xb8\x5a\xb2\x37\x7e\x5f\x67\x8f\x8f\xa2\x17\xa0\xde"
-  "\x98\x91\x30\x1f\x99\x79\x16\x1f\x8f\x39\xe9\xd1\x32\x52\x73\xae"
-  "\x30\x23\x35\x1f\x61\xf8\x97\x99\x9b\xd8\xb4\x05\xb7\x75\x0f\x97"
-  "\xc1\x9b\xb6\x08\x33\xb8\xa1\x3f\xe1\x95\xa6\x24\xec\x17\x3e\x83"
-  "\xc3\x39\x82\x0c\x6e\x98\xc9\x9e\xb3\x85\xcf\xe0\xa4\x0c\x68\x77"
-  "\x57\x8a\x33\xb8\xd1\x93\xb4\xc3\x86\xab\xa4\x1d\x66\x7d\x6c\xc3"
-  "\xe0\x86\x63\x96\x0c\x8e\xfd\x6f\xcb\xe0\x44\x53\xcc\x7d\x8a\x32"
-  "\xb8\x51\x61\xcb\xe0\xf7\xd5\x98\xc1\x85\x75\x65\xba\xce\xd7\x95"
-  "\x69\x53\x83\xc9\xcc\xe2\xdb\x70\x79\x53\xad\x59\xfc\x31\xd4\x5a"
-  "\x2e\xc7\xe3\xf8\x99\x4c\xfd\xa5\xf1\x38\x73\xce\x4c\x69\x3c\x8e"
-  "\xf5\x27\xc4\xe3\xa6\xfd\xd6\xfa\xe3\xf3\xb8\xe9\xa4\x30\x8f\x9b"
-  "\x2e\xf1\x79\x1c\x97\x2f\xc4\xe3\xb4\x2b\xaf\x7c\x1b\x1e\xa7\xfb"
-  "\xf0\x79\x9c\x1c\xc7\xf1\x38\x5d\xcc\xf6\x6f\x1c\x93\xce\xe3\xf4"
-  "\x01\xfb\x3c\x4e\x1f\xe1\xf3\x38\xbd\x91\xc4\x54\xba\xb2\x81\xe1"
-  "\x71\x3a\x93\xe5\xfa\x42\xcb\xed\x1c\x8f\x93\xed\x0d\x96\x3c\x5e"
-  "\x84\x79\x9c\xae\x6b\x85\xc7\x83\x1c\xe6\x71\xaa\xb3\x5f\x0b\x8f"
-  "\xc3\xdf\x76\x79\x9c\x42\xfb\xed\xf2\x38\xe5\x16\xdd\xc2\xe3\x54"
-  "\x87\x93\x4c\x1c\xa0\x3a\xec\x67\xe2\x00\xd5\x61\xbe\x08\x8f\x97"
-  "\x08\xf2\x38\xd5\x61\xaa\x05\x8f\x57\x62\x0e\x87\x36\xaf\x12\x73"
-  "\x00\x1e\xaf\x01\x1c\x5e\x51\x14\xc3\x1c\x37\x1a\xf3\x3a\x66\x74"
-  "\xd8\xaf\x4b\xc2\x7f\x9b\x98\x73\x2e\xe0\xf1\x50\x0c\x97\xdf\x60"
-  "\x18\xfe\x02\xe3\x13\xca\x35\x1b\xce\x2d\x6f\x61\x78\x4a\x31\xce"
-  "\x8a\xe1\x4b\xec\x30\x7c\x31\x30\xfc\x29\x60\xf8\xa2\xfa\x6d\x8a"
-  "\x58\x0b\x86\x3f\x05\x0c\x5f\x64\xc5\xf0\x15\xc0\xf0\x95\xf8\x3c"
-  "\x7c\x0e\x1c\x9f\xc7\x3b\x1e\xee\x95\x39\xfe\x1e\xf3\xc3\xc7\x97"
-  "\xc3\xf1\x17\x18\xe6\xdf\xa6\xb8\x60\xc1\xfc\xc5\x0c\xf3\x53\xae"
-  "\x73\x68\x4b\xe6\xa7\xa8\x3e\x92\x99\x9f\x52\x5e\xb6\xcb\xfc\x14"
-  "\x35\x59\x26\xf3\x97\x3c\x61\xfe\x56\x98\x9f\x52\x1e\x90\xc5\xfc"
-  "\x94\x32\xcf\x8a\xf9\x4b\x9e\x30\x7f\x1b\x32\x3f\xa5\x4c\x6b\x61"
-  "\xfe\x0d\xdd\xee\xee\xc5\xcc\xbf\x93\x65\xfe\x6d\xae\x71\x36\xcc"
-  "\xbf\xcd\x35\xc5\x82\xf9\x8b\x75\x94\xa2\xaa\x85\xf9\x29\xc5\x20"
-  "\x1e\xf3\x53\x9d\xaf\xdb\x30\x3f\xe5\x7a\x49\x16\xf3\x53\x1d\x3a"
-  "\xca\x62\x7e\xaa\x83\x1b\xb9\xbf\x6b\x38\xbe\x33\xf3\x22\x74\x94"
-  "\x6b\x5e\x4b\x1e\x40\xa1\x0b\x96\xdb\x5a\xcd\x03\xa8\x0e\xa9\x82"
-  "\x79\x00\x85\x72\x45\xf3\x00\xd8\x27\x9a\x07\x50\x6e\x63\x78\xbc"
-  "\x46\xb9\x75\x79\x2c\xf2\x00\xea\xa9\x83\x82\x6c\x46\x3d\x75\xac"
-  "\x25\x0f\xa0\x3a\xa4\x3c\xf4\x3c\x00\xca\x14\xcc\x03\x28\xb7\xc1"
-  "\x0c\x27\x51\x1d\xd2\x6c\xf2\x00\x7c\x8e\x50\x1e\x40\xb9\x45\xb0"
-  "\xe7\xa4\xf0\xf2\x00\xb6\x0c\x68\xef\x5b\xfa\xbf\x6d\x7d\xda\xb1"
-  "\x07\x69\xff\xdd\x6e\x92\xf6\x9f\xf5\xb1\x75\x1e\x40\xb9\x9d\x6c"
-  "\x35\x0f\x60\x35\xc5\xdc\xa7\x58\x1e\x40\x75\xec\x68\x93\x07\xc0"
-  "\x35\x45\xf3\x00\xaa\xd3\x6d\xbe\xae\x3a\x6d\xe7\xe5\x01\x54\xc7"
-  "\x99\x8f\x4d\x1e\x20\xae\xb5\x83\xbc\x3c\x80\xea\x34\x58\x72\x1e"
-  "\x40\x75\x8a\x90\x94\x07\x30\xfa\x13\xc8\x03\xa8\x4e\x87\xac\xf5"
-  "\xc7\xcb\x03\xa8\x4e\x67\x04\xf3\x00\xaa\xd3\x55\x5e\x1e\xc0\x94"
-  "\x2f\x90\x07\x50\x9d\xbb\xf0\xca\xb7\xce\x03\xa8\xce\x03\x79\x79"
-  "\x00\x7b\x5c\x4b\x1e\x40\x75\x2e\x27\x31\x19\x4d\x90\x9c\x07\x50"
-  "\x9d\x8f\xd8\xcd\x03\xa8\xce\xc7\x78\x79\x00\xd5\x39\x89\xc4\xd4"
-  "\xce\x55\x4c\x1e\x40\x75\xce\x21\xdb\x51\xb0\xe5\xf6\x96\x3c\x80"
-  "\xdd\x6e\x93\x07\x6c\xeb\x6c\x68\x25\x0f\x70\x37\xe4\xf6\xd5\x37"
-  "\xf9\xf4\x43\xcd\xea\x19\x9a\xe7\xaa\x5e\x32\xb6\xac\xd5\x1f\x0e"
-  "\x6d\x7a\x25\xb0\x43\x04\xa2\xf0\xfc\xf8\xf8\xf3\xc0\x6c\x11\x64"
-  "\x2c\x3d\xe6\x84\xcf\x56\x61\x4e\x28\x72\xc5\x6b\x0b\x36\xa5\x0d"
-  "\xd3\x19\x06\x0d\x50\x61\x56\x68\xcc\xed\x5b\xde\x90\x36\x3e\xa0"
-  "\x11\x8f\xa3\x5f\x8c\xa8\x79\x35\xc2\xec\xb0\xb6\x92\x36\x81\xe6"
-  "\xdd\x42\xe6\x10\x6e\x28\x8d\xba\xce\xe8\x18\x33\x03\x9e\xeb\x50"
-  "\x56\x57\xc1\x30\x84\x7b\x78\x20\xca\x8a\x47\xea\x2e\x35\x48\xd5"
-  "\x45\xa1\xe8\xf0\xca\x45\x84\x8c\xc0\x0f\xe3\x06\xd2\xa6\xe7\x22"
-  "\x03\xf1\xfa\x36\x5d\x09\x43\x14\xba\x1a\x58\x86\xf8\xe0\x01\x1a"
-  "\x94\xbd\x0a\xd8\xa1\x94\x63\x87\x46\x33\xdb\x59\x70\xc3\xdc\xdb"
-  "\x2a\x94\xbd\x81\x3f\x8e\xbe\x39\x95\xe3\x06\xcc\x0c\xf4\x3c\x2d"
-  "\x1a\xd2\x40\xc6\x49\xac\x99\x4a\xc6\xa2\x0e\xaa\x82\xbc\xe4\x75"
-  "\xe4\x56\x12\x7e\x0d\xcf\x37\xf7\x2e\xa9\xda\x8f\x56\x4f\x40\xbd"
-  "\x0d\x98\x13\x36\xd0\xf9\x25\x55\xe9\x08\xaf\xdd\x07\xbc\x18\x90"
-  "\xf9\x00\x8d\xc2\xed\xf1\xa4\x08\xc2\x0b\xa4\x2d\xee\x92\x7e\x5a"
-  "\x7b\x1a\x49\x67\xbd\x2e\xcc\xfb\x77\xd1\x39\xac\xb9\xfd\x90\xc1"
-  "\xa7\x6f\xb9\x11\x7c\x49\xd6\x6c\x9c\x18\x6e\xfa\xc3\x1b\x81\x9f"
-  "\x81\x0e\xff\x74\xad\x5a\x81\xd7\x9f\xc6\xdf\x62\x34\x1d\x1c\xa0"
-  "\xe2\xf9\xa6\x99\xf5\x4d\x33\xf1\x0d\xf6\xcb\xeb\xd1\x08\xaf\xf5"
-  "\xd7\x15\xfb\xa4\xac\xa1\x02\x99\xd6\x9a\xbf\xc7\xe8\x8b\xf6\x98"
-  "\x88\x3f\x8c\xcd\x51\x1d\x4d\x60\x7b\xbc\xa6\x15\xe8\x81\x61\xb8"
-  "\x24\xfc\x8d\xc6\xf5\x8a\x2e\x98\xe1\x40\xdf\x9d\xf6\x36\x81\x1f"
-  "\xae\x12\x3f\xd0\x1b\x54\xcc\xbf\x86\xb5\x5a\x0d\x94\xdd\xb7\xb9"
-  "\x19\x7c\xd1\x60\xed\x8b\xaf\x73\xf1\xb7\x1c\xf1\x7a\x73\x86\x54"
-  "\xb2\xa6\x1e\xe3\x8b\xb5\xda\x5e\x78\xcd\x0a\x66\x2e\x4a\xb3\x16"
-  "\xc7\x4b\xd5\x9e\x1b\x78\x0e\x0d\xf1\x81\x91\xb5\x3d\xfe\xae\x23"
-  "\xb6\x37\xe6\xb3\x32\xe0\x32\x66\x6e\xc8\x36\x77\x55\xf3\xfe\xbe"
-  "\xe5\x78\x0c\xcb\x1d\xca\xc3\x53\x1e\x07\x79\xa8\x7e\x7e\xdb\x6b"
-  "\x1e\x43\xdb\x77\xa9\xe4\x6c\xaf\xda\x2e\xcf\xf6\xaa\xa4\x9f\xdf"
-  "\xf6\xaa\xc7\xd0\xf6\x1e\x61\x9c\xed\xbb\xc9\xe4\xff\x6e\x6e\xf6"
-  "\x6c\x8f\xfb\x91\xcc\x7d\x48\xe6\xfe\x23\xdc\xc6\x91\x5c\xa5\x47"
-  "\x61\xcb\x98\x46\xf8\xdb\x72\x4c\x63\x69\x10\x9e\xdb\xcd\x8e\x69"
-  "\xa4\xba\x5d\xb6\xdf\x6f\xd4\xdd\xc0\xf5\x1b\x79\xcd\x24\xdc\xe8"
-  "\x35\x9a\x70\xa3\x9a\x99\xe3\x8d\xe7\xf2\xc4\xdf\x44\xd4\xe1\x55"
-  "\x3a\x0a\xaf\x97\xbb\x1d\xda\x57\x6c\x63\x60\xae\x67\x6e\x51\xea"
-  "\x95\xb8\x4f\xe8\xcb\x07\x3a\x2a\x05\xf6\x31\x6d\x58\xdf\x37\x02"
-  "\x0f\xf6\xd4\x2b\x70\x3b\x86\xd7\x28\xa5\x2d\xe6\xeb\x19\xfb\xf7"
-  "\x43\xb5\xfb\xfb\xea\xcd\xf3\x70\x8c\xe9\x33\x34\x86\x43\x03\x54"
-  "\x82\x9a\xc1\xf3\x00\x41\x37\x78\xce\x9e\x59\x3b\x8c\x66\x9a\x20"
-  "\xef\x6d\xa8\x46\xf8\x9b\x34\x1e\xd5\x48\x45\x83\x66\x66\x1f\x80"
-  "\xfb\xb4\xd4\x4d\x8a\x88\x6e\x76\xf1\x75\x53\xcb\xea\x06\xf4\xc3"
-  "\xe9\x86\x9b\xc3\xa7\x95\xa4\x9b\x1a\x56\x37\xa9\x56\xba\xb9\xad"
-  "\x41\xff\xac\xbc\xcc\xea\x46\x75\xc1\xd0\xdf\xac\x1b\xf5\x98\xd3"
-  "\x73\x40\x37\x73\xa4\xea\x46\x1d\xc8\xcf\x65\x7b\xce\xb7\xcd\x65"
-  "\xd5\xfb\xad\x73\x59\x73\xee\x5a\xeb\x35\x51\x53\x0b\xf9\x6b\x5d"
-  "\x4b\xfe\xaa\x3e\x23\x4f\xbf\xea\x62\x87\xc6\x84\x51\x5e\x03\xad"
-  "\xc7\x84\x1d\x8a\xc7\x79\x69\x37\x1d\xd6\x96\x70\x5e\x4a\xf6\xd9"
-  "\x8c\xe5\xa1\xba\x97\xb6\x8c\xe5\xa1\xba\xef\x6a\xf7\x63\xc2\xa8"
-  "\xee\x01\xc2\xf9\x41\xf7\x31\x84\x37\xbd\xb4\x8f\x64\x8e\x04\x94"
-  "\x2b\x9c\x8b\x76\x3f\x46\x58\xdd\x6b\x90\xcd\xb8\x30\x7c\x8e\x60"
-  "\x2e\xda\xfd\x36\x7b\x8e\x96\x9f\x8b\x92\x32\xae\x51\xbf\xec\x28"
-  "\x9e\x8b\xfe\x72\x3f\x89\x29\xbf\x5c\x49\x62\x0a\xf1\xab\x6d\x2e"
-  "\xfa\xcb\xc9\xad\x8e\x0b\x63\x75\xc4\xdc\xa7\x68\x2e\xfa\xcb\x74"
-  "\xdb\x5c\xb4\x5b\xa5\xe0\xb8\x30\xaa\xc7\x32\x4e\x4b\x3d\x3c\x79"
-  "\xe3\xc2\xa8\x5f\x5e\x7e\x2c\xc6\x85\x89\xeb\x2b\xc0\x66\x8e\x04"
-  "\xe5\x7d\x44\xf2\xd8\x30\xca\xfb\xba\xb4\x1c\x14\xeb\x4e\x28\x07"
-  "\xed\x31\xd4\x5a\x77\xfc\x1c\xb4\xc7\x64\xe1\x1c\xb4\xc7\x7c\x7e"
-  "\x0e\x8a\xcb\x17\xca\x41\x7b\xa4\xf2\xca\xb7\xc9\x41\x7b\x1c\xe2"
-  "\xe7\xa0\xe4\x38\x2e\x07\xed\x49\xd6\x1b\xa6\xba\x6d\x92\x9e\x83"
-  "\xf6\x64\xc6\xb5\x1d\xfa\x98\xbc\xeb\xe1\xe7\x9f\x3d\x47\xf2\xf3"
-  "\xcf\x9e\xee\xa4\xde\xf7\x8c\x64\xc6\x85\x51\x3d\x35\x64\x7b\xb7"
-  "\x8d\x96\xdb\xb9\xfc\x93\x6c\xc7\xe3\xc2\x98\xf1\x60\xdb\x7a\xae"
-  "\x90\x96\x77\x0e\x69\x87\x79\xa7\xaf\x9d\xbc\xd3\xf7\x31\xcd\x3b"
-  "\x7b\x75\x91\x97\x77\xf6\x72\xff\xf9\xf9\xfb\x71\xcc\x7d\x7a\x6e"
-  "\xe1\xf8\xfb\xe9\xad\xf2\xf8\xe5\xe9\x2d\x3f\xbf\xed\x1f\xc7\xdc"
-  "\xa7\xd7\x34\xce\xf6\xcf\xb8\xca\xb3\xfd\x33\xa2\xdf\xff\x68\x3d"
-  "\xf7\x19\x50\xc0\xe5\x3e\x03\x0a\xc4\x73\x9f\x67\x2e\xd9\xcf\x7d"
-  "\xfa\x35\x70\xb9\x4f\xdf\xe9\x84\x53\xfa\x8e\x24\x9c\xd2\xa7\xb1"
-  "\xf5\xdc\xa7\xcf\xb2\x27\xb9\x8f\x94\xdc\xe7\xe9\x72\x2e\xf7\xe9"
-  "\x33\x5a\x5e\xee\xd3\x87\x3f\x57\x9c\x7a\x36\xc2\x36\xf7\xe9\xb3"
-  "\xcf\xf1\xdc\xa7\xcf\x69\x79\xfa\xed\x73\xca\xb1\xdc\xa7\x6f\x7f"
-  "\xe1\xdc\xe7\x99\x4a\xf1\xdc\x87\xec\xb3\xe5\xd5\x7e\x67\x38\x5e"
-  "\xed\x97\xde\xfe\x73\x9f\x7e\x7e\xc2\x6c\xda\x6f\x34\x61\x9d\xbe"
-  "\x3e\x8f\x26\xf7\xe9\xeb\x23\x9c\xfb\xf4\x3b\x4a\x18\xb1\xaf\xd6"
-  "\x36\xf7\x81\x73\x04\x73\x9f\x7e\x37\xd9\x73\x7c\xf8\xb9\x0f\x29"
-  "\xe3\x1a\xe5\xe3\x2a\x9e\xfb\xf8\xec\x23\x31\xc5\x67\x19\x89\x29"
-  "\xc4\xaf\xb6\xb9\x8f\xcf\x84\xd6\x73\x1f\xa2\x23\xe6\x3e\x45\x73"
-  "\x1f\x9f\x54\xdb\xdc\xe7\x99\x0a\xe1\xdc\x67\xc0\x12\x4e\x4b\x03"
-  "\xba\xf0\x73\x1f\x9f\x4b\x8f\x47\xee\x23\xaa\x2f\x3f\xdb\xdc\xa7"
-  "\xff\x21\xe9\xb9\x4f\xff\xab\xd2\x72\x1f\xac\x3b\xa1\xdc\x67\xc0"
-  "\x60\x6b\xdd\xf1\x73\x9f\x01\x13\x84\x73\x9f\x01\x11\xfc\xdc\x07"
-  "\x97\x2f\x94\xfb\x0c\xd8\xce\x2b\xdf\x26\xf7\x19\x70\x80\x9f\xfb"
-  "\x90\xe3\xb8\xdc\xe7\xd9\x49\x24\x96\x3e\xb3\x5e\x7a\xee\xf3\xec"
-  "\x60\xf1\xdc\xe7\x59\x7f\x7e\xee\xf3\xac\x1b\xa9\xf7\xcf\x86\x93"
-  "\xdc\xe7\xd9\x5e\x64\xfb\x33\x89\x96\xdb\xb9\xdc\x87\x6c\xe7\x72"
-  "\x9f\x67\xa3\xa5\xe5\x3e\xcf\xb4\xc3\xdc\x47\x63\x27\xf7\xd1\x3c"
-  "\xa6\xb9\xcf\xc0\x8e\xf2\x72\x9f\x81\x76\xfb\xbf\x9f\xf0\xb7\x18"
-  "\x7f\x3f\xbb\x91\xe3\xef\x5f\x6f\x92\xc7\x2f\xbf\xde\x28\x9f\xbf"
-  "\x87\xf9\x71\xfc\x3d\xcc\x4f\x9c\xbf\x9f\x9b\x69\x9f\xbf\x87\xc4"
-  "\x72\xfc\x3d\xf8\x22\x69\x2b\x07\x1f\x23\x6d\xe5\xe0\xd5\xad\xf3"
-  "\xf7\xa0\xbb\x4f\xf8\x5b\x0a\x7f\x0f\x0c\xe5\xf8\x7b\xd0\x09\x79"
-  "\xfc\x3d\xe8\x38\x9f\xbf\x87\x5d\xb5\xe5\xef\xc1\x7d\x1c\xe7\xef"
-  "\xc1\xe3\xe4\xe9\x77\x70\x90\x63\xfc\x3d\x78\xbf\x30\x7f\x3f\x37"
-  "\x47\x9c\xbf\xc9\x3e\x5b\x66\x1a\x32\x81\x63\xa6\x21\x5e\xed\x9f"
-  "\xbf\x9f\x2f\x10\xe6\xa3\xe7\x4f\x90\xf6\x76\x70\xee\xa3\xe1\xef"
-  "\xc1\xb9\xc2\xfc\x3d\xc4\x9f\x70\xca\xe0\x3c\x5b\xfe\x86\x73\x04"
-  "\xf9\x7b\xc8\x42\xf6\x9c\x5c\x3e\x7f\x93\x32\x20\x86\x6c\x12\xe7"
-  "\x6f\xdf\x3e\x24\xa6\x0c\xb9\x4b\x62\x0a\xf1\xab\x2d\x7f\x0f\x39"
-  "\xd3\x3a\x7f\x13\x1d\x31\xf7\x29\xca\xdf\xbe\x9e\xb6\xfc\xfd\x5c"
-  "\x98\x30\x7f\x0f\xbd\xcd\x69\x69\xe8\x76\x3e\x7f\xfb\xda\x8c\x7f"
-  "\x7b\xcc\xf4\x55\x60\xcb\xdf\x43\x25\x8e\x7f\x63\xce\x91\x38\xfe"
-  "\x0d\xeb\x4e\x88\xbf\x87\x1e\xb2\xd6\x1d\x9f\xbf\x87\x8a\x8c\x7f"
-  "\x1b\x6a\x35\xfe\x0d\x97\x2f\xc4\xdf\xc3\xba\xf0\xca\xb7\xe1\xef"
-  "\x61\x56\xe3\xdf\xc8\x71\x1c\x7f\x0f\x2b\x21\xb1\xf4\x39\x85\x74"
-  "\xfe\x1e\x76\x48\x9c\xbf\x87\x1d\xe5\xf3\xf7\xb0\x2d\xa4\xde\x0f"
-  "\xd3\x11\xfe\x1e\x96\x45\xb6\x3f\x87\x2c\xb7\x73\xfc\x4d\xb6\x73"
-  "\xfc\x3d\x4c\x2f\x8d\xbf\x3d\xda\x21\x7f\xab\xec\xf0\xb7\xea\x31"
-  "\xe5\x6f\xbf\xad\xf2\xf8\xdb\xcf\x6e\xff\xb7\x7d\x06\x1c\x15\xc0"
-  "\x31\xe0\xa8\x00\x71\x06\xf4\x9f\x6b\x9f\x01\x47\xc6\x71\x0c\xf8"
-  "\xc2\x25\x12\xaf\x5f\x38\x41\xe2\xf5\x0b\xeb\x5a\x67\xc0\x11\xf7"
-  "\x9f\x30\xa0\x14\x06\x1c\xee\xc2\x31\xe0\x88\x93\xf2\x18\x70\x44"
-  "\x11\x9f\x01\x47\x09\xcc\xa5\x78\xa1\xbf\xe3\x0c\xf8\xc2\x04\x79"
-  "\x0c\xf8\x42\xb0\x63\x0c\xf8\xc2\x01\x61\x06\xf4\x0f\x17\x67\x40"
-  "\xb2\xcf\xb6\xdd\x1e\xc9\xad\xab\x48\x8d\xec\xd1\xfe\x19\x30\xa0"
-  "\x50\xb8\x8d\x0e\x38\x49\x62\xfe\x0b\x79\x8f\x86\x01\x5f\xc8\x13"
-  "\x66\xc0\x91\x23\x49\x5b\xf9\xc2\x41\x5b\x06\x84\x73\x04\x19\x70"
-  "\xe4\x12\xf6\x9c\x3c\x3e\x03\x92\x32\x20\x86\x6c\x15\x67\xc0\xdf"
-  "\xf4\x27\x31\x65\xe4\x7d\x12\x53\x88\x5f\x6d\x19\x70\x64\x69\xeb"
-  "\x0c\x48\x74\xc4\xdc\xa7\x28\x03\xfe\xc6\xcb\x96\x01\xfd\xe7\x08"
-  "\x33\xe0\x8b\x77\x39\x2d\xbd\x98\xca\x67\xc0\xdf\xcc\x7d\x3c\x18"
-  "\x50\x54\x5f\x85\xb6\x0c\xf8\xe2\x50\xe9\x0c\xf8\xe2\x7c\x69\x0c"
-  "\x88\x75\x27\xc4\x80\x2f\x1e\xb1\xd6\x1d\x9f\x01\x5f\x2c\x15\x66"
-  "\xc0\x17\xaf\xf3\x19\x10\x97\x2f\xc4\x80\xa3\x3c\x79\xe5\xdb\x30"
-  "\xe0\xa8\xc1\x7c\x06\x24\xc7\x71\x0c\x38\x8a\x9d\x03\xe1\xef\x2a"
-  "\x9d\x01\x47\x1d\x11\x67\xc0\x51\x56\xf3\x1f\x46\xb1\xf3\x1f\x46"
-  "\x55\x11\x06\x1c\xc5\xce\x7f\xf0\x77\xb1\xdc\xce\x31\x20\xd9\xce"
-  "\x31\xe0\xa8\xd6\xe6\x3f\xb7\xc2\x0d\x41\x89\x1c\x37\x04\x25\x5a"
-  "\x72\xc3\x99\x53\x96\xdc\x30\x3a\xdd\x3e\x37\x8c\x29\xe6\xb8\x21"
-  "\x70\x20\xa9\xe3\x81\x5d\x48\x1d\x7f\x89\xf1\x65\xf3\xa7\xfd\x35"
-  "\xeb\x4a\x11\xf5\xd9\x9d\x42\xea\x83\x55\xc8\x25\x69\x15\x70\x03"
-  "\xb0\x5a\xf4\x2c\xcc\x0d\x2f\x8d\x9b\x1c\x77\x85\x76\xcf\x02\x26"
-  "\xad\x62\x19\x35\x1a\x18\xb5\x0a\xfe\x0f\xf5\xe5\xc4\xd2\x42\xea"
-  "\x1c\x70\x64\x0a\x70\x1c\x33\x67\x96\x99\x4f\xab\x73\x65\xbe\x77"
-  "\x70\xa7\x81\xf9\x76\x8e\xc3\xdf\xa1\xa8\x62\xbf\x43\x11\xc9\xff"
-  "\x0e\x05\xfe\xfe\x04\xfe\x16\x45\x56\x0c\x52\x63\x46\xc5\x2c\xd1"
-  "\x75\xbd\xa2\x2b\xfe\x16\x45\xd7\x3a\xc2\xa1\x87\x4c\xc5\x84\x43"
-  "\x97\x7b\x77\x4a\xba\x87\x06\xed\xb9\xc7\x31\xc4\x87\x98\x1f\x96"
-  "\x6b\x35\x75\xcb\xb5\xbd\x6b\x6b\xb5\x7d\x6d\xbf\x41\x71\x3a\x0e"
-  "\x7f\x83\xa2\x2c\xb6\x82\xe1\x07\xe6\xdb\x05\x6f\x69\xd1\xde\x05"
-  "\xc0\x34\x35\x48\xf1\x3c\x5e\x0f\xbc\x17\xdc\x7b\x29\x52\x19\x6b"
-  "\xb5\xbd\x2c\xd7\x3d\x84\x7b\x57\x99\x6a\xb5\xa8\x24\xfc\x3b\x66"
-  "\x9e\xa6\x81\x9d\xa7\xa9\x5f\xae\xa5\xa0\xcc\x80\x8f\x63\x2c\x38"
-  "\xd4\xcb\xcc\xa1\x2f\x79\xca\xe3\xd0\x97\x54\x7c\x9e\x18\x37\xd8"
-  "\x96\x27\x5e\xb2\x59\xff\x5b\x9c\x27\x5e\xda\x25\x8f\x27\x5e\xca"
-  "\x74\x8c\x27\x5e\x6a\xb4\xe6\x89\x03\xcc\x3c\xcb\xd1\x99\x58\x73"
-  "\xc2\x3c\x41\xf6\xd9\xb6\x01\x63\x76\x71\x6d\xc0\x98\xf9\xed\x9f"
-  "\x27\xc6\xb8\x09\xc7\xfb\x31\x9e\xcc\x1a\x87\xd4\x4b\x0d\x0f\x7d"
-  "\x8d\x43\x28\x53\x98\x25\xc6\x6c\x22\x31\xf7\xa5\x06\x73\x5b\xc3"
-  "\xb1\x04\x9c\x23\xc8\x12\x63\x8e\x59\x9f\x43\x58\xe2\x25\x03\x61"
-  "\x89\x31\x17\xc5\x59\xe2\xe5\x65\x24\xce\xbc\x3c\x86\xc4\x19\xe2"
-  "\x53\x5b\x96\x78\xb9\x47\xeb\x2c\x41\x34\xc4\xdc\xa7\x28\x4b\xbc"
-  "\x1c\x61\xcb\x12\xa3\xd3\x84\x59\x22\x68\x24\xa7\xa3\xb1\x97\xf8"
-  "\x2c\xf1\xf2\x81\xc7\x83\x25\x44\xb5\xe5\xc6\xe7\x88\xb1\xab\xa5"
-  "\x73\xc4\xd8\x43\xd2\x38\x02\x6b\x4e\x88\x23\xc6\x36\xb2\xfa\x31"
-  "\x08\x73\x44\x90\x97\x30\x47\x04\x0d\xe6\x73\x04\x2e\x5f\x88\x23"
-  "\x82\x66\xf2\xca\xb7\xe1\x88\xa0\x95\x7c\x8e\x20\xc7\x71\x1c\x31"
-  "\xce\x9b\xc4\xd0\xd1\xa3\xa5\x73\x44\x50\xa3\x38\x47\x8c\x53\xf0"
-  "\x39\x22\x88\x9d\x9b\x3e\x6e\x10\xe1\x88\xa0\x6a\xb2\x7d\xf4\x28"
-  "\xcb\xed\x1c\x47\x90\xed\x1c\x47\x8c\x1b\xf5\x64\xfe\x64\x7b\xec"
-  "\x4b\x1a\x7f\x51\x5e\x1b\x3e\x5e\xf4\xfb\xa7\x4f\xe6\x4f\xda\x7b"
-  "\x97\x3b\x2e\x94\x7b\x97\x1b\x3c\x55\x1e\xb7\x04\x87\xfe\xfc\xb6"
-  "\x7f\x1c\xc7\x10\xff\xae\x17\x67\xfb\x09\xa5\xf2\x6c\x3f\xa1\xe4"
-  "\xe7\xb7\xfd\xe3\x38\x86\x21\x38\x93\xb3\xfd\x44\x99\xfd\x7f\x13"
-  "\x83\xe5\xf7\x5f\xbf\xe6\xc6\xe5\xa1\xaf\xb9\x89\xf7\x5f\x4f\x7a"
-  "\xda\x7e\x1e\x1a\x1a\xca\xe5\xa1\x53\x8e\x10\x3e\x9c\x92\x4e\xf8"
-  "\x70\x0a\xb3\x96\xbf\xa1\x6f\x84\x2f\xe9\xbf\x2e\x12\xe8\xbf\x9e"
-  "\x5c\x8a\xd7\xbe\xe2\xd6\xc4\x9a\x34\xd3\x72\x4d\xac\x2f\xe0\x9c"
-  "\x27\xfd\xda\x8e\xf4\x6b\xbf\xa2\xe6\xfa\xb5\x27\xef\x92\xd7\xaf"
-  "\x3d\x39\x93\x9f\x87\xbe\x76\xd4\x36\x0f\x9d\x6c\x74\x3c\x0f\x9d"
-  "\xd2\x47\x9e\xae\xa7\x68\x1c\xcb\x43\xa7\xac\x17\xee\xd7\x9e\xa4"
-  "\xc1\x9a\x13\xce\x43\xc9\x3e\xdb\xfc\x21\xb4\x0f\x97\x3f\x84\xdc"
-  "\x6e\xff\x79\x68\x48\x8a\x70\xae\x10\xb2\x8b\xe4\xa1\x53\x12\x1f"
-  "\x7e\x1e\x3a\x25\x51\x38\x0f\x0d\x65\xdf\xff\x4e\xd9\x68\xdb\xa7"
-  "\x0d\xe7\x08\xe6\xa1\xa1\x63\xd8\x73\x12\xf9\x79\x28\x29\x03\xe2"
-  "\xca\x5c\xf1\x3c\x34\xb4\x91\xc4\x99\xd0\x33\x24\xce\x10\x9f\xda"
-  "\xe6\xa1\xa1\xfb\x5a\xcf\x43\x89\x86\x98\xfb\x14\xcd\x43\x43\x6f"
-  "\xda\xe6\xa1\x93\x7a\x09\xe7\xa1\xaf\x9e\xe4\x74\xf4\x6a\x04\x3f"
-  "\x0f\x9d\x3a\xf4\xf1\xc8\x43\x45\xb5\x95\xc2\xcf\x43\x5f\x55\x48"
-  "\xcf\x43\x5f\xf5\x97\x96\x87\x62\xcd\x09\xe5\xa1\xaf\xae\xb7\xd6"
-  "\x1c\x3f\x0f\x7d\x35\x5b\x38\x0f\x7d\xf5\x28\x3f\x0f\xc5\xe5\x0b"
-  "\xe5\xa1\xaf\x5e\xe5\x95\x6f\x93\x87\xbe\x6a\xe4\xe7\xa1\xe4\x38"
-  "\x2e\x0f\x7d\x8d\x6d\xcf\x26\x9e\x96\x9e\x87\xbe\xb6\x5e\x3c\x0f"
-  "\x7d\x6d\x2b\x3f\x0f\x7d\x6d\x0e\xc9\x37\x5f\x2b\x20\x79\xe8\x6b"
-  "\xd1\x64\xfb\xc4\x53\x96\xdb\xb9\x3c\x94\x6c\xe7\xf2\xd0\xd7\x4e"
-  "\x3d\x99\x4f\xd9\x1e\xf3\xd0\xe9\x73\xe5\xe5\xa1\xd3\xe7\xfc\xfc"
-  "\x3c\xfe\x38\xe6\x42\xaf\x55\x70\x3c\x3e\xe3\x92\x3c\x6e\x99\x51"
-  "\xf1\xf3\xdb\xfe\x71\xcc\x85\xa6\xe7\x72\xb6\x0f\x9b\x2e\xcf\xf6"
-  "\x61\xd3\xe4\xe7\x42\xe1\x6a\x2e\x17\x0a\x57\x8b\xe7\x42\x33\x07"
-  "\xda\xcf\x85\xe6\xce\xe1\x72\xa1\xd9\x27\x08\xa3\xcc\xde\x47\x18"
-  "\x65\x76\x44\xeb\xb9\xd0\xac\x4b\xfc\x5c\x68\xe6\xfc\x27\xb9\x90"
-  "\x9c\x5c\xe8\xf7\x1a\x2e\x17\x9a\xb5\x5f\x5e\x2e\x34\x2b\x97\x9f"
-  "\x0b\x85\x9f\xb4\xcd\x85\x66\x77\x74\x3c\x17\x9a\x3d\x58\x9e\xae"
-  "\x67\x0f\x72\x2c\x17\x9a\xbd\x5d\x38\x17\x9a\x39\x48\x3c\x17\x22"
-  "\xfb\x6c\x19\x76\xee\x60\x8e\x61\xe7\x34\xb6\xff\x5c\x68\x4e\x96"
-  "\x30\xaf\xce\xd9\x4f\x72\xa1\xd9\x49\x0f\x3f\x17\x9a\x9d\x24\x9c"
-  "\x0b\xcd\xed\x41\xb8\x71\x76\x8a\x6d\x2e\x04\xe7\x08\xe6\x42\x73"
-  "\x27\xb3\xe7\x24\xf1\x73\x21\x52\x06\xc4\x95\x85\xe2\xb9\xd0\xeb"
-  "\xae\x24\xce\xcc\xbd\x48\xe2\x0c\xf1\xa9\x6d\x2e\x34\xf7\x50\xeb"
-  "\xb9\x10\xd1\x10\x73\x9f\xa2\xb9\xd0\xdc\xfb\xb6\xb9\xd0\x4c\xad"
-  "\x70\x2e\x34\xcf\x62\xad\xa2\x79\x4b\xf8\xb9\xd0\xeb\xa3\x1f\x8f"
-  "\x5c\x48\x54\x5b\x59\xfc\x5c\x68\x5e\x17\xe9\xb9\xd0\xbc\x31\xd2"
-  "\x72\x21\xac\x39\xa1\x5c\x68\xde\x76\x6b\xcd\xf1\x73\xa1\x79\x07"
-  "\x84\x73\xa1\x79\x27\xf9\xb9\x10\x2e\x5f\x28\x17\x9a\x77\x9b\x57"
-  "\xbe\x4d\x2e\x14\xde\x91\x9f\x0b\x91\xe3\xb8\x5c\x28\xfc\x20\x89"
-  "\xa1\x61\xe7\xa5\xe7\x42\xe1\xdb\xc5\x73\xa1\xf0\x74\x7e\x2e\x14"
-  "\x1e\x45\x72\x9e\xf0\x22\x92\x0b\x85\xc7\x91\xed\x61\xe5\x96\xdb"
-  "\xb9\x5c\x88\x6c\xe7\x72\xa1\xf0\xf2\x27\xf3\x2b\xdb\x63\x2e\xf4"
-  "\xc6\x42\x79\xb9\xd0\x1b\x51\x4f\x78\x5c\x0e\x8f\x87\x57\x71\x3c"
-  "\xfe\xe6\x75\x79\xdc\xf2\x66\x95\x7c\x1e\x7f\x3b\x97\xe3\xf1\xb7"
-  "\x73\xc5\x79\x3c\xf2\x98\x7d\x1e\x8f\xaa\xe1\x78\xfc\xad\xc9\xa4"
-  "\x9d\x7c\x6b\x28\x69\x27\x17\xdc\x6d\x9d\xc7\x17\x2c\xe4\xf3\x78"
-  "\xe4\xfd\x27\x3c\x2e\x87\xc7\xdf\xc8\xe7\x78\x7c\x81\xbf\x3c\x1e"
-  "\x5f\xe0\xc7\xe7\xf1\xc5\x53\x6d\x79\x7c\xc1\x2e\xc7\x79\x7c\xc1"
-  "\x09\x79\xba\x5e\x70\xdc\x31\x1e\x7f\xeb\x69\x61\x1e\x8f\x3c\x2e"
-  "\xce\xe3\x64\x9f\x2d\x47\x45\x9d\xe0\x38\x2a\x6a\x6b\xfb\xe7\xf1"
-  "\xa8\x41\xc2\xcc\x14\xe5\x4f\x78\xfc\xad\x5e\x0f\x9f\xc7\xdf\xea"
-  "\x25\xcc\xe3\x51\x07\x08\xbb\xbc\xa5\xb1\xe5\x71\x38\x47\x90\xc7"
-  "\xa3\x2e\xb3\xe7\xf4\xe2\xf3\x38\x29\x03\xe2\x4a\xa3\x38\x8f\x2f"
-  "\x4c\x27\x71\x66\xe1\x7c\x12\x67\x88\x4f\x6d\x79\x7c\xe1\xe8\xd6"
-  "\x79\x9c\x68\x88\xb9\x4f\x51\x1e\x5f\xb8\xc9\x96\xc7\x23\x0b\x85"
-  "\x79\xfc\xed\xb9\x9c\x8e\x16\x19\xf9\x3c\xbe\xb0\xf4\xf1\xe0\x71"
-  "\x51\x6d\x0d\xe2\xf3\xf8\xa2\x6c\xe9\x3c\xbe\xe8\xbc\x34\x1e\xc7"
-  "\x9a\x13\xe2\xf1\xb7\x9f\xb6\xd6\x1c\x9f\xc7\xdf\x1e\x29\xcc\xe3"
-  "\x6f\x4f\xe5\xf3\x38\x2e\x5f\x88\xc7\xdf\x5e\xc7\x2b\xdf\x86\xc7"
-  "\xdf\xde\xc5\xe7\x71\x72\x1c\xc7\xe3\x8b\x47\xb1\xed\x59\x84\x74"
-  "\x1e\x5f\xfc\xb4\x38\x8f\x2f\xee\xcf\xe7\xf1\xb7\x1b\x08\x77\x2f"
-  "\x0e\x25\x3c\xbe\xd8\x9d\x6c\x8f\x0c\xb7\xdc\xce\xf1\x38\xd9\xce"
-  "\xf1\xf8\xe2\xf0\x27\xf3\x2d\xdb\x23\x8f\x2f\x69\x94\xc7\xe3\x4b"
-  "\x1a\xe4\x33\xe1\x4a\x8b\xf5\xbe\x57\xda\x59\xef\x7b\x69\xa9\x7d"
-  "\x26\x5c\x8e\x38\x26\x5c\x16\x41\x62\xf5\xb2\x71\x24\x56\x2f\x73"
-  "\x6d\x9d\x09\xa3\xd7\xf1\x99\xf0\x9d\x8e\x4f\x98\x50\x0e\x13\x2e"
-  "\x5e\xc1\x31\x61\xf4\x04\x79\x4c\x18\x1d\xcc\x67\xc2\x55\x02\xeb"
-  "\x80\x47\x1f\x72\x9c\x09\xa3\xcf\xcb\x63\xc2\xe8\x72\xc7\x98\x70"
-  "\xd9\x50\x61\x26\x5c\x5a\x2e\xce\x84\x64\x9f\x6d\x5b\x1e\x73\x9e"
-  "\x6b\xcb\x63\xb2\xdb\x3f\x13\xc6\x04\x0a\xb7\xdb\x31\x13\x08\x13"
-  "\x2e\xf3\x7d\xf8\x4c\xb8\xcc\x57\x98\x09\x63\x4e\x90\xf6\x73\x99"
-  "\x9f\x2d\x13\xc2\x39\x82\x4c\x18\x73\x97\x3d\xc7\x97\xcf\x84\xa4"
-  "\x0c\x88\x2b\x5d\xc4\x99\x70\xf9\x01\x12\x67\x96\xaf\x26\x71\x86"
-  "\xf8\xd4\x96\x09\x97\x4f\x6d\x9d\x09\x89\x86\x98\xfb\x14\x65\xc2"
-  "\xe5\xbb\x6c\x99\x70\x69\x89\x30\x13\xae\xb4\x58\x03\x7c\xa5\xd5"
-  "\x1a\xe0\xcb\xaf\x3e\x1e\x4c\x28\xaa\xad\x40\x3e\x13\xae\x90\xb1"
-  "\xfe\xf7\x0a\x89\xeb\x7f\x63\xcd\x09\x31\xe1\xca\xa1\xd6\x9a\xe3"
-  "\x33\xe1\x4a\x91\xf5\xbf\x57\x5a\xad\xff\x8d\xcb\x17\x62\xc2\x95"
-  "\xa9\xbc\xf2\x6d\x98\x70\xa5\xd5\xfa\xdf\xe4\x38\x8e\x09\x57\xb1"
-  "\xeb\x7f\x2f\x5d\x29\x9d\x09\x57\xd9\x59\xff\x7b\x95\xd5\xfa\xdf"
-  "\xab\xd8\xf5\xbf\x57\xb1\xeb\x7f\xaf\x62\xd7\xff\x5e\xba\xc2\x72"
-  "\x3b\xc7\x84\x64\x3b\xc7\x84\xab\x5a\x5d\xff\xdb\x3e\x47\xc4\x7b"
-  "\x73\x1c\x11\xef\x2d\x3e\xff\xf2\x5d\x2f\xfb\x1c\xb1\x36\x9c\xe3"
-  "\x88\xd5\xec\xf7\x66\x57\xb3\xdf\x9b\x5d\xcd\xf8\xac\x19\xea\x38"
-  "\x99\x7f\x99\x4f\x01\xd3\x71\xf3\x2f\x5f\xc7\x1c\x11\x7b\x79\x32"
-  "\x8f\x23\xde\x9d\xce\xcc\xc5\xc4\x2c\x51\xd7\x80\xf0\x3e\xe1\x79"
-  "\x99\xf9\x6d\x3b\x2f\xf3\xc1\xff\x85\x79\x99\xb1\x07\xe4\xf1\x6a"
-  "\x6c\x1e\x9f\x2f\xe2\x4f\xdb\xf2\xc5\xea\x2e\x8e\xf3\xc5\xea\xa1"
-  "\xf2\xf8\x62\xb5\xaf\x63\x7c\xb1\x3a\x55\x78\x5e\xe6\xbb\xde\xcd"
-  "\xa2\x7c\xf1\x2e\x33\xde\xc1\xb6\x5d\x58\x3b\x94\x6b\x17\xd6\x18"
-  "\xdb\x3f\x5f\xac\xc9\x11\x6e\x03\xd6\x1c\x20\x7c\xb1\x3a\xe5\xe1"
-  "\xf3\xc5\x6a\x91\xef\x5d\xae\x65\xf3\xff\xd5\x2d\xdf\xae\xe4\xf8"
-  "\x62\xb5\xc8\xf7\x2e\xd7\x4e\xb5\x3e\x87\xf0\xc5\xea\x34\xc2\x17"
-  "\x6b\x97\x88\xf3\x45\x5c\x47\x12\x7f\xd6\x5e\x22\xf1\xe7\x5d\xe1"
-  "\xef\xde\x53\x6b\x8f\xb4\xce\x17\xab\xd9\xef\x5d\xae\xb6\xf3\xbd"
-  "\xcb\xb5\x8d\xb6\x7c\xf1\xae\x5a\x98\x2f\xd6\x59\x70\xea\xba\x65"
-  "\x7c\xbe\x88\x1b\xf3\x78\xf0\x85\xa8\xb6\x72\xf8\x7c\xb1\xce\x53"
-  "\x3a\x5f\xac\x1b\x27\x8d\x2f\x56\x8b\x7c\xe3\x72\x1d\xdb\xfe\x13"
-  "\xbd\xd8\xf2\xc5\xba\x43\xc2\x7c\xb1\xee\x34\x9f\x2f\x56\x8b\x7c"
-  "\xe3\x72\xdd\x5d\x5e\xf9\x36\x7c\x11\xdf\x85\xcf\x17\xe4\x38\x8e"
-  "\x2f\xe2\xf3\xd9\x1c\xed\x84\x74\xbe\x88\x4f\x15\xe7\x8b\xf8\x5d"
-  "\x7c\xbe\x88\x5f\x4c\x38\x22\xfe\x14\xe1\x8b\xf8\x44\x96\x3b\x8e"
-  "\x5b\x6e\xe7\xf8\x82\x6c\xe7\xf8\x22\xfe\x82\x84\x3e\x27\x1f\x29"
-  "\xf3\x32\x0f\x3d\xe0\xf7\x39\x99\xfb\x9b\x0c\x83\x06\xa8\x5b\xfa"
-  "\x9c\xa0\xad\x17\xfb\x26\x36\xee\x73\xc2\x6d\x37\xd7\xe7\x74\x99"
-  "\x89\x55\x5c\x9f\x93\x8e\xe9\x73\xc2\xfd\x4d\x90\x9f\xb7\xf4\x37"
-  "\x99\xde\xb5\x9d\x93\x79\xc8\x24\xbd\xbf\xe9\xf5\x65\x2a\xb4\x87"
-  "\x69\xbf\xcf\x54\x92\xfe\xa6\x8a\x96\xfe\x26\xdc\x6e\x1b\xeb\x6d"
-  "\xfb\x9b\x70\x7b\xcd\xf5\x37\x7d\x27\xb3\xbf\x29\x51\xe6\xfb\xdf"
-  "\xc4\x76\xf0\xfe\xf7\x71\x9c\x93\x19\x5f\xcd\xbd\xff\x5d\x2f\xf3"
-  "\xfd\xef\x7a\xbb\xef\x7f\x9f\x8c\x43\x16\xb3\x7d\x62\x3e\x67\xfb"
-  "\xf7\x22\xe4\xd9\xfe\xbd\xf0\x9f\xdf\xf6\x8f\xe3\xb8\x87\x0d\x83"
-  "\x38\xdb\x6f\xbc\x2c\xcf\xf6\x1b\x2b\xe5\xf7\x71\x27\x1d\xe7\x72"
-  "\xd3\xa4\xe3\xe2\xb9\xe9\xa6\x23\xf6\x73\xd3\x6d\x2e\x5c\x6e\xba"
-  "\x65\x3e\x61\xc3\x2d\x13\x08\x1b\x6e\xe9\x68\xee\xe3\x26\xb9\x69"
-  "\x11\x85\xe3\x3b\xee\xbb\x4e\x82\x98\xfe\x01\xe4\x65\xdb\x21\x4f"
-  "\xfd\x20\x06\x72\xd5\x68\xe4\x56\x56\x75\x02\x45\xc7\xe3\x7c\xf5"
-  "\xfd\xf5\x21\xb1\x96\xf9\xea\x66\x85\x39\x57\x0d\x81\x73\xbf\x5c"
-  "\x5a\x44\xe1\x9c\xd4\xe8\x45\xfa\xb1\x53\xa0\x1c\x73\xff\x37\x6e"
-  "\xff\x3e\x5b\x0a\xb9\xe9\x22\x7e\x1f\x78\xf3\xa1\x01\xea\x66\xaf"
-  "\x19\x3e\xb8\x1f\xbc\x71\x7f\x3f\x64\xee\x0b\xb7\xd7\x07\x8e\xb5"
-  "\x65\xdd\x0f\xfe\xf8\xf6\x81\xbf\x97\xc7\xf5\x81\xbf\x3f\x59\x5e"
-  "\x1f\xf8\xfb\x93\xf8\x39\xea\xf6\x85\xb6\x39\xea\xfb\x47\x1c\xcf"
-  "\x51\xdf\xbf\x28\x4f\xf7\xef\x5f\x70\x2c\x47\xdd\xe2\x2f\x9c\xa3"
-  "\x6e\x2a\x10\xef\x03\x27\xfb\x6c\x73\x8b\xad\x17\xb9\xdc\x62\xeb"
-  "\xbe\xf6\x9f\xa3\x6e\x0d\x12\xce\x23\xb6\x4e\x26\x39\xea\x16\xbf"
-  "\x87\x9f\xa3\x6e\xf1\x13\xce\x51\xb7\x9e\x24\x3c\xbf\xc5\xcf\x36"
-  "\x47\x85\x73\x04\x73\xd4\xad\xf7\xad\xcf\x21\x39\xea\x96\x00\x92"
-  "\xa3\x6e\xf3\x14\xcf\x51\xb7\x1d\x22\x71\x68\xdb\x3a\x12\x87\x88"
-  "\x4f\x6d\x73\xd4\x6d\xd3\x5b\xcf\x51\x89\x86\x98\xfb\x14\xcd\x51"
-  "\xb7\x65\xdb\xe6\xa8\x9b\xf2\x85\x73\xd4\xa4\x95\x9c\x8e\x92\xbc"
-  "\xf8\x39\xea\xb6\xeb\x8f\x47\x8e\x2a\xaa\xad\x20\x7e\x8e\xfa\xc1"
-  "\x51\xe9\x39\xea\x07\x37\xa5\xe5\xa8\x58\x73\x42\x39\x6a\x12\xbb"
-  "\xfe\x39\xd1\x8b\x6d\x8e\x9a\x34\x55\x38\x47\x4d\x5a\xc8\xcf\x51"
-  "\x71\xf9\x42\x39\x6a\x52\x3a\xaf\x7c\x9b\x1c\x35\xe9\x08\x3f\x47"
-  "\x25\xc7\x71\x39\xea\x76\x36\x27\xdc\x34\x53\x7a\x8e\xba\xdd\x5f"
-  "\x3c\x47\xdd\x3e\x9a\x9f\xa3\x6e\x57\x91\x5c\x74\x7b\x14\xc9\x51"
-  "\xb7\xfb\x90\xed\x9b\xc2\x2c\xb7\x73\x39\x2a\xd9\xce\xe5\xa8\xdb"
-  "\x63\x25\xe4\xa8\xda\x87\x94\xa3\x7a\x3f\x5e\x39\xea\x3f\x53\xda"
-  "\x36\x47\xdd\x21\xf3\xfb\x97\x3b\x1c\xfd\xfe\xa5\x4f\x2b\xac\xae"
-  "\xfe\xff\x8b\xd5\xb7\x27\x71\xac\x9e\x22\xf3\xfb\x97\x29\x8e\x7e"
-  "\xff\xf2\x91\xd9\xfe\xf1\xb3\xfb\x0e\x8b\x6f\x5f\xee\x54\xc8\xb3"
-  "\xfb\x4e\xf4\x24\x3f\x95\x63\xfb\x94\x72\xce\xf6\x1f\xae\x93\x67"
-  "\xfb\x0f\xe3\xe4\xe7\xa7\xbb\xe3\xb8\xfc\x74\x77\x9c\x65\x7e\x5a"
-  "\xcc\x1b\x83\x95\x36\xd5\x7e\x7e\x9a\x79\x8a\xcb\x4f\x3f\x62\xd7"
-  "\xa7\xfe\xa8\x23\xe1\xc2\x0c\xe6\x5b\x14\x8d\x38\x3f\x1d\x03\xf9"
-  "\xe9\xad\x94\x96\xfc\x14\xe7\xa3\x93\x1b\xae\xd0\xf8\x5d\x2a\xe4"
-  "\xa7\x2e\x5b\xef\x20\x17\xc8\x59\x51\x59\xe5\x51\x94\x04\xf9\xea"
-  "\xb6\x3b\x90\xb3\x2e\x86\x9c\xd5\x90\xcd\xe6\xac\x19\x63\xf8\x39"
-  "\x6b\xda\x51\x5e\xce\xba\x28\x85\xc9\x59\x21\x0f\x55\x19\xd2\x67"
-  "\x68\x70\xce\x6a\x80\x7c\xb4\x79\xf0\x00\x75\xca\x1d\xab\xfc\x75"
-  "\x11\xe4\xaf\x0b\xf8\xf9\x6b\x53\xfa\x0c\x6d\xe3\xa1\x01\xde\xcc"
-  "\x38\xae\xfe\x8e\xe5\xaf\xd6\xb9\x6b\x16\x3b\x86\x6b\xf7\x63\x99"
-  "\xbf\xee\x0c\xe6\xf2\xd7\x8c\x2e\xf2\xf2\xd7\x0c\x77\x7e\xfe\x9a"
-  "\x35\xd0\x36\x7f\xcd\x58\xe6\x78\xfe\x9a\x91\x2e\xaf\x5e\x64\xa4"
-  "\x39\x96\xbf\x66\xdc\xb7\xce\x5f\xf3\x98\x31\x5c\x69\xd3\x1a\x45"
-  "\xf3\xd7\xb4\x50\xe1\x77\xac\x99\xe9\x5c\xde\x91\x19\xd1\xfe\xf3"
-  "\xd7\x4c\x17\xe1\x1c\x23\xb3\x0b\xc9\x5f\x33\xea\x1e\x7e\xfe\x9a"
-  "\x51\x27\x9c\xbf\x66\xb2\xeb\xbf\x64\xd4\xd9\xe6\xaf\x70\x8e\x60"
-  "\xfe\x9a\x79\xd4\xfa\x1c\x92\xbf\x66\x34\x90\xfc\x35\xf3\xbc\x78"
-  "\xfe\xba\x6b\x09\x89\x53\xbb\x46\x93\x38\x45\x7c\x6a\x9b\xbf\xee"
-  "\xf2\x6a\x3d\x7f\x25\x1a\x62\xee\x53\x34\x7f\xdd\x35\xd7\x36\x7f"
-  "\x4d\x0b\x15\xce\x5f\x77\xfb\x73\x3a\xfa\xf8\x22\x3f\x7f\xdd\xb5"
-  "\xff\xf1\xc8\x5f\x45\xb5\xe5\xc2\xcf\x5f\x3f\x5e\x29\x3d\x7f\xfd"
-  "\xf8\x80\xb4\xfc\x15\x6b\x4e\x28\x7f\xfd\x98\xed\xff\x20\x7a\xb1"
-  "\xcd\x5f\x77\x7b\x0a\xe7\xaf\xbb\x07\xf2\xf3\x57\x5c\xbe\x50\xfe"
-  "\xba\x7b\x3a\xaf\x7c\x9b\xfc\x75\xf7\x32\x7e\xfe\x4a\x8e\xe3\xf2"
-  "\xd7\x2c\x35\x89\xa1\x1f\x36\x4a\xcf\x5f\x77\xdf\x17\xcf\x5f\x77"
-  "\x1b\xf9\xf9\xeb\x6e\x76\x3e\x6d\x96\x96\xe4\xaf\xbb\xab\xc8\xf6"
-  "\x0f\x1b\x2c\xb7\x73\xf9\x2b\xd9\xce\xe5\xaf\x59\x01\xd2\xde\xb1"
-  "\x3a\xb5\xe6\x90\xba\xed\xc7\xf5\x3f\xac\x35\x87\xcc\xef\x59\xdb"
-  "\x6a\x5c\x7f\xf6\x79\x79\x39\x6c\x76\xf9\x93\x3c\x4a\x2a\xcb\x67"
-  "\x4d\xe2\x58\x7e\xaf\xcc\xf5\x3f\xf7\xda\x5d\xff\xf3\x49\x1e\x25"
-  "\x66\xfb\x3d\xde\x9c\xed\x73\x4e\xcb\xb3\x7d\xce\x29\xf9\x79\x54"
-  "\x9e\xc5\xfc\xe6\x3c\xde\xfc\x66\xfe\x7b\xbe\x7d\xbb\xec\xe7\x51"
-  "\xfb\x2d\xe6\x37\xe7\xb2\xf3\x9b\x73\xd9\xf9\xcd\x9f\xb4\xcc\x6f"
-  "\x96\xf6\x9e\xef\x93\x85\xfc\x9c\x69\xdf\xcd\x27\xef\xf9\x9c\xcd"
-  "\x93\xf6\xa6\x70\x79\xd2\x27\x32\xe7\x3f\x7f\x62\x35\xff\xf9\x80"
-  "\xc0\xfc\xe7\x4f\x24\xcc\x7f\xfe\x44\xe6\xfc\xe7\x4f\x1c\x9c\xff"
-  "\x9c\x6b\x33\xff\x99\xbc\xe7\xdb\x97\x25\xfe\x9e\x8f\xec\xb3\xe5"
-  "\xdb\xfd\x16\xf3\x9f\xf7\x3f\x06\xf3\x9f\xf7\x8b\xcc\x51\xdd\xcf"
-  "\xce\x7f\xce\x7d\x04\xf3\x9f\x73\x45\xe6\x3f\xef\x67\xe7\x3f\xe7"
-  "\xf6\xb2\xcd\x93\x72\x45\xe6\x3f\xef\xbf\x6c\x7d\x0e\xc9\x93\x72"
-  "\xd9\xf9\xcf\xfb\xed\xcc\x7f\xfe\x94\x9d\xff\xfc\x29\x3b\xff\x99"
-  "\xf8\xd4\x36\x4f\xfa\xd4\x81\xf9\xcf\xb9\xec\xfc\xe7\x5c\x3b\xf3"
-  "\x9f\x3f\x15\x98\xff\xbc\x2f\x53\x38\x4f\xca\xb3\x98\xff\xfc\x3f"
-  "\x56\xf3\x9f\x3f\x7d\x4c\xe6\x3f\x8b\x6a\xcb\x6a\xfe\xf3\xff\xc8"
-  "\x98\xff\xfc\x3f\x12\xe7\x3f\xe7\x8a\xcc\x7f\xce\x63\xc7\x3f\xe7"
-  "\x8a\xcc\x7f\xce\x13\x99\xff\x9c\x67\x35\xff\x39\x57\x64\xfe\x73"
-  "\xde\x3a\x5e\xf9\x36\x79\x52\x9e\xd5\xfc\xe7\x5c\xab\xf9\xcf\x07"
-  "\xd8\xf9\xcf\xfb\xc6\x48\xcf\x93\x0e\xd8\x99\xff\x7c\xc0\x6a\xfe"
-  "\x73\x1e\x9b\x0f\x1d\x60\xe7\x3f\x1f\x60\xe7\x3f\xef\x0b\xb4\xdc"
-  "\xce\xe5\x49\x64\x3b\x97\x27\x1d\x90\x32\xff\xd9\x47\xca\x7a\x44"
-  "\x3f\xff\x58\x54\xcd\x63\x3a\x16\xf5\x8f\xf7\xe5\xe5\x48\x7f\xac"
-  "\x7b\xc2\xea\x72\x58\xfd\xc0\x0a\x8e\xd5\x0f\x2e\x93\xc7\x2c\x07"
-  "\xa3\xe5\xb3\x7a\x41\x28\xc7\xea\x05\xa1\xe2\xac\x7e\x68\x9c\x7d"
-  "\x56\x3f\x92\xc9\xb1\xfa\x61\x76\xfd\xf2\xc3\x97\x49\x1b\x79\x38"
-  "\x5b\x1e\xab\x1f\xf6\xe2\xb3\xfa\xa1\xf4\x27\xac\xee\x2c\xab\xff"
-  "\x69\x14\xc7\xea\x9f\x5d\x95\xc7\xea\x9f\xe9\xf8\xac\x5e\x60\xb4"
-  "\x65\xf5\xc3\xe3\x1c\x67\xf5\xc3\x0b\xe5\xe9\xfe\x70\x94\x63\xac"
-  "\x7e\xf8\x8c\x30\xab\x1f\x0a\x16\x67\x75\xb2\xcf\x96\xb1\x8e\x2c"
-  "\xe4\x18\xeb\x88\x7f\xfb\x67\xf5\xfc\x0a\x61\x9e\xca\xbf\x4a\x58"
-  "\xfd\x70\xf1\xc3\x67\xf5\xc3\xc5\xc2\xac\x7e\x84\xed\xff\x3d\x5c"
-  "\x6c\xcb\xea\x70\x8e\x20\xab\x1f\xd9\x6a\x7d\x0e\x61\xf5\xc3\x25"
-  "\x84\xd5\x8f\xec\x17\x67\xf5\xcf\xc7\x90\x38\xf4\xb9\x27\x89\x43"
-  "\xc4\xa7\xb6\xac\x7e\xe4\x66\xeb\xac\x4e\x34\xc4\xdc\xa7\x28\xab"
-  "\x7f\x3e\xd4\x96\xd5\x0f\x05\x09\xb3\x7a\x41\x47\x4e\x47\x7f\x3e"
-  "\xc0\x67\xf5\xcf\x57\x3f\x1e\xac\x2e\xaa\xad\x0a\x3e\xab\xff\x79"
-  "\x82\x74\x56\xff\xf3\x3a\x69\xac\x8e\x35\x27\xc4\xea\x7f\x3e\xc3"
-  "\xea\xa7\x44\x98\xd5\xff\x7c\x5d\x98\xd5\xff\x6c\xe4\xb3\x3a\x2e"
-  "\x5f\x88\xd5\x0b\x06\xf2\xca\xb7\x61\xf5\x82\x71\x7c\x56\x27\xc7"
-  "\x71\xac\x5e\x50\x4d\x62\xe8\xc1\xdb\xd2\x59\xbd\xe0\x8c\x38\xab"
-  "\x17\x9c\xe7\xb3\x7a\x41\x2e\x61\xf2\x02\x03\x61\xf5\x82\x42\xb2"
-  "\xfd\x60\x8d\xe5\x76\x8e\xd5\xc9\x76\x8e\xd5\x8f\xba\x3f\x59\xab"
-  "\xa8\x3d\xae\x55\xf4\x97\xfd\xf2\x78\xfd\x2f\xb9\xf2\x99\xf1\x8b"
-  "\x48\x8e\x19\xbf\x88\xb4\x64\x46\xfe\x5a\x45\x7f\x5d\x6d\x9f\x19"
-  "\xff\x7e\x90\x63\xc6\xbf\x75\x21\xb1\xfa\xd8\x5d\x12\xab\x8f\x1d"
-  "\x31\x33\xa3\xf8\x5a\x45\xc7\x06\xf2\xd7\x2a\xfa\xeb\xd1\x27\x6b"
-  "\x15\xc9\x61\xc2\xa3\x16\xeb\xc9\x17\xde\x97\xc7\x84\x85\x75\x7c"
-  "\x26\xfc\xd2\xd3\x96\x09\x8f\xcd\x74\x9c\x09\x8f\xc9\x1c\xff\x75"
-  "\x2c\xce\x31\x26\x3c\x76\x59\x78\xad\xa2\xbf\xc6\x89\x33\x21\xd9"
-  "\x67\xdb\x96\xff\x7d\x1d\xd7\x96\xff\x7d\x42\xfb\x67\xc2\xbf\xd5"
-  "\x08\xb7\xdb\x7f\xbb\x4f\x98\xf0\x58\xe5\xc3\x67\xc2\x63\x95\xc2"
-  "\x4c\xf8\xf7\x85\xa4\xfd\x3c\xa6\xb3\x5d\xab\x08\xce\x11\x64\xc2"
-  "\xbf\x67\xb3\xe7\x54\xf2\x99\x90\x94\x01\x71\xe5\x98\x38\x13\x1e"
-  "\x9f\x4e\xe2\xcc\xf1\xfe\x24\xce\x10\x9f\xda\x32\xe1\xdf\x8d\xad"
-  "\x33\x21\xd1\x10\x73\x9f\xa2\x4c\x78\x7c\x9c\x2d\x13\xfe\x35\x56"
-  "\x98\x09\xbf\x78\x9a\xd3\xd1\x89\x13\x7c\x26\x3c\xbe\xfd\xf1\x60"
-  "\x42\x51\x6d\xd5\xf0\x99\xf0\xc4\x5c\xe9\x4c\x78\x22\x55\x1a\x13"
-  "\x62\xcd\x09\x31\xe1\x89\xcb\xd6\x9a\xe3\x33\xe1\x89\x46\x61\x26"
-  "\xfc\xc2\x93\xcf\x84\xb8\x7c\x21\x26\xfc\x62\x34\xaf\x7c\x1b\x26"
-  "\xfc\x62\x26\x9f\x09\xc9\x71\x1c\x13\x7e\x61\x60\xdb\xb3\x3e\xd2"
-  "\x99\xf0\x8b\xcb\xe2\x4c\xf8\xc5\x75\x3e\x13\x7e\x51\x48\xd8\xef"
-  "\x4b\x15\x61\xc2\x2f\x4a\xc8\xf6\xbf\x6a\x2c\xb7\x73\x4c\x48\xb6"
-  "\x73\x4c\xf8\xa5\x46\xda\x3c\x8d\x87\xd2\x7f\xdb\x46\xf3\x34\x1e"
-  "\x56\xff\x6d\x5b\xcf\xd3\x28\x3a\x2a\x8f\x07\x8b\x0a\x9e\x8c\x71"
-  "\x91\xda\x77\xfb\xa5\x1f\xd7\x77\xfb\x0f\x99\xdf\xbf\xf9\xc7\x20"
-  "\xf9\x1c\x7e\xd6\x87\xe3\xf0\xb3\x3e\xe2\xe3\xd5\xbf\x52\xd8\xe7"
-  "\xf0\xaf\x17\x73\x1c\x7e\xba\x94\xb4\x8f\xa7\x8f\x90\xf6\xf1\xf4"
-  "\xb2\x56\xc7\xab\xaf\x42\x2e\x49\xec\x78\xf5\x0f\xf0\x78\xf5\x8a"
-  "\xd3\x28\xe9\x9e\xd0\x78\xf5\x53\x37\xf9\xfd\xb9\x5f\xcd\x17\x1a"
-  "\xaf\xce\x8c\x53\x4f\x9f\xe1\x63\x10\x1b\xa7\xfe\xfa\xc3\x1d\xa7"
-  "\xbe\x1b\xd8\xdd\xdc\xa7\x8b\x63\xc3\xe3\xc7\xef\x45\x06\x8e\xdf"
-  "\x4f\x1d\x95\xc7\xef\xa7\x0a\xf8\xfc\x7e\xf6\xbc\x2d\xbf\x9f\xee"
-  "\xe1\x38\xbf\x9f\x1e\x2d\xaf\x3e\x9c\x1e\xe5\x18\xbf\x9f\xce\x16"
-  "\x1e\xa7\xfe\x95\x8b\xf8\x38\xf5\xaf\x90\xf0\x38\xf5\xaf\x47\x73"
-  "\xdc\xf5\x75\xc7\xf6\xcf\xef\xff\x7b\x50\x98\xb1\xfe\xf7\x28\xe1"
-  "\xf7\xd3\x59\x0f\x9f\xdf\x4f\x67\x09\xf3\xfb\xd7\x6c\xff\xd7\xe9"
-  "\x2c\xdb\x3e\x5d\x38\x47\x90\xdf\xbf\x9e\x6b\x7d\x0e\xe1\xf7\xd3"
-  "\x39\x84\xdf\xbf\x5e\x2d\xce\xef\xc5\x5e\x24\x3e\x7d\x7d\x9d\xc4"
-  "\x27\xe2\x53\x5b\x7e\xff\xfa\x44\xeb\xfc\x4e\x34\xc4\xdc\xa7\x28"
-  "\xbf\x17\xbb\xda\xf2\xfb\x57\x48\x98\xdf\xcf\x5c\xe6\x74\x74\x66"
-  "\x1d\x9f\xdf\x8b\x27\x3f\x1e\xfc\x2e\xaa\xad\x83\x7c\x7e\x3f\xf3"
-  "\xb4\x74\x7e\x3f\x33\x55\x1a\xbf\x63\xcd\x09\xf1\xfb\x19\x36\xff"
-  "\x23\x7a\xb1\xe5\xf7\x33\xc7\x84\xf9\xfd\xcc\x79\x3e\xbf\xe3\xf2"
-  "\x85\xf8\xfd\x8c\x91\x57\xbe\x0d\xbf\x9f\xed\xc1\xe7\x77\x72\x1c"
-  "\xc7\xef\x67\x8f\x93\x18\xfa\x8f\x03\xd2\xf9\xfd\x6c\xb6\x38\xbf"
-  "\x9f\xdd\xcf\xe7\xf7\xb3\xb1\x84\xd3\xcf\x96\x13\x7e\x3f\x9b\x44"
-  "\xb6\xff\x23\xcf\x72\x3b\xc7\xef\x64\x3b\xc7\xef\x67\x75\xd2\xc6"
-  "\x5f\x38\xde\xa7\xfb\xf3\x8f\xbf\x50\x3d\xa6\xe3\x2f\x4a\x56\xca"
-  "\xe3\xf7\x92\x15\xf2\x39\xf2\xc2\x24\x8e\x23\x2f\x4c\x12\x1f\x03"
-  "\x50\x3a\xc1\x3e\x47\x9e\x4f\xe3\x38\xb2\xec\x3e\x89\xd3\x65\xec"
-  "\x9a\x8d\x65\xbb\xc4\xc6\x00\xe0\xf9\x8e\xdb\x63\xc8\x5c\xc7\x96"
-  "\x31\x00\x95\x17\x59\x66\x2c\xf3\xe4\x33\x63\xe9\x2e\xa1\x31\x00"
-  "\x82\xef\xfe\xad\xe6\x33\x1a\x07\x4b\x7f\xf7\xff\x7f\x6b\x3e\xe3"
-  "\xd9\x3a\x8e\x13\xcf\x5d\x96\xc7\x89\xe7\x2a\xf9\x9c\x78\xa1\xd1"
-  "\x96\x13\xcb\xc6\x38\xce\x89\x65\xf3\xe5\x71\x62\x59\xa4\x63\x9c"
-  "\x58\x76\x5a\xf8\xdd\x7f\xe9\x24\xf1\x7e\x5e\xb2\xcf\xb6\x7d\x3f"
-  "\x3f\x9f\x6b\xdf\xcf\x0f\x6d\xff\x9c\x58\x7e\x41\xb8\x2d\x2f\xbf"
-  "\x4c\x38\xb1\xec\xd4\xc3\xe7\xc4\xb2\x53\xc2\x9c\x78\x9e\x5d\xff"
-  "\xb5\xec\x94\x2d\x27\xc2\x39\x82\x9c\x78\x7e\x93\xf5\x39\x84\x13"
-  "\xcb\x8a\x09\x27\x9e\xdf\x27\xce\x89\xdf\x8c\x26\xf1\xe7\x9b\x2e"
-  "\x24\xfe\x10\x9f\xda\x72\xe2\xf9\xeb\xad\x73\x22\xd1\x10\x73\x9f"
-  "\xa2\x9c\xf8\xcd\x60\x5b\x4e\x2c\x0d\x16\xe6\xc4\x0b\xae\x9c\x8e"
-  "\xfe\xb5\x9f\xcf\x89\xdf\xac\x7c\x3c\x38\x51\x54\x5b\x17\xf8\x9c"
-  "\xf8\xaf\x71\xd2\x39\xf1\x5f\xab\xa5\x71\x22\xd6\x9c\x10\x27\xfe"
-  "\xeb\x34\xab\x9f\x62\x61\x4e\xfc\xd7\x55\x61\x4e\xfc\x57\x23\x9f"
-  "\x13\x71\xf9\x42\x9c\x78\xa1\x3f\xaf\x7c\x1b\x4e\xbc\x30\x86\xcf"
-  "\x89\xe4\x38\x8e\x13\x2f\x54\x91\x18\x5a\x72\x57\x3a\x27\x5e\x38"
-  "\x2d\xce\x89\x17\x4a\xf9\x9c\x78\x21\x87\xf0\xe0\x85\x06\xc2\x89"
-  "\x17\x0a\xc8\xf6\x12\xbd\xe5\x76\x8e\x13\xc9\x76\x8e\x13\x2f\xba"
-  "\xd9\xe3\x44\x3a\xa5\xd9\x2d\x85\x32\xe5\xc3\xaf\x10\xee\xb3\x07"
-  "\xb4\x63\x45\xf0\x77\x31\xb4\x47\x9e\xf0\xb7\xe8\xdc\x39\xbd\x67"
-  "\xb3\x9b\x09\x18\xc3\x04\xd7\x29\xd3\xff\x54\x54\xd4\xd3\x00\xd7"
-  "\xbe\xb8\x85\xf0\x47\xb3\x9b\x87\xe1\xa9\x60\x13\x1d\x05\x6d\x38"
-  "\xfc\x1d\x0b\xdb\xe0\xf8\xae\xd0\xee\x69\x56\xa1\xae\x77\xa8\x8b"
-  "\x79\xe6\xe3\xe0\x9e\xbb\x5e\xa3\x2e\xce\xc7\x65\xc0\xbd\x16\xe8"
-  "\xa8\x8b\x6a\xd1\x7b\x85\xb2\x42\x0e\xf4\x46\xeb\x0c\xf4\x8f\x45"
-  "\x4b\xef\xa1\x2a\xea\xa2\xd1\xa3\xe6\xa9\x60\x88\x43\x08\x73\x5d"
-  "\x7e\x4f\xbd\x0b\x2e\xb3\x68\x69\x13\xde\xa7\xc3\xfb\x8c\x70\x8f"
-  "\xf1\x4b\x10\x95\x7c\xef\x29\x37\xe0\x27\xd7\x84\x3a\xba\xfa\x1d"
-  "\x03\xdc\x73\xac\x01\x7d\xd9\xbb\xc2\xe5\xf0\xc7\x15\x4c\xdb\x73"
-  "\xae\xce\xc8\x94\xa1\x59\x8a\xef\xe7\x5b\xc5\x1e\x38\x5e\xe8\x1e"
-  "\x36\x7d\x86\x06\xb9\x0e\xa4\x75\xd2\xda\xbb\x6f\x45\xbf\xff\xee"
-  "\xb1\xbe\x37\x2a\xfa\x35\xd8\x4e\x83\x28\xa1\xfd\x12\xaf\x73\xdc"
-  "\x0e\x47\xba\x7d\xd8\x9d\xae\x4b\xd8\x85\xa8\x1d\xa6\xa7\xdc\xbe"
-  "\x82\x98\xb8\x37\x83\xd6\xd7\x6f\xfb\xb7\x56\xa7\x28\x1d\x85\x6d"
-  "\xfe\x1e\xec\xdf\xd1\x9d\xd6\xd7\x6e\xc0\xba\xf9\x77\xe0\x49\x68"
-  "\xdb\xad\x7d\x11\x13\xb9\x24\x42\xb3\x62\xe1\x92\xf9\xef\xac\x5c"
-  "\xa1\xe9\x1f\xd9\x09\x4d\x7b\xe7\x1d\xcd\x92\x88\xa5\xab\x35\x96"
-  "\x7b\x7e\xa3\x89\x5c\xb8\x3c\xe2\x8d\xc5\xf3\x07\x2f\x79\x33\xba"
-  "\x13\x4e\xf2\x2d\xee\x43\x8d\xef\xc5\xb4\xed\xdf\x93\xf6\xec\x44"
-  "\xe8\xc3\x6e\xc8\x05\xdf\x17\x5c\x2f\x5f\xe7\xe2\x9d\x85\xaf\x97"
-  "\x9c\x41\xd7\x51\x70\x4c\x02\xc4\xb4\x1d\xf1\x4f\xc1\xb1\xdf\x1e"
-  "\xdf\x0b\xf7\xb5\x07\xee\x1b\xee\x11\xdf\x73\xa5\xf9\x9e\xcd\x9a"
-  "\x48\xc0\x9a\x88\xbf\x07\x1a\xfc\xb7\xd1\xa3\xe1\xa9\xdf\xd1\x74"
-  "\x18\x7e\xbe\x3a\xa8\x2b\x8a\x1b\x54\x45\x3a\xc3\xfa\xa9\xcd\x6e"
-  "\xf5\xdb\x2a\xbc\xcd\x1a\x33\xa5\x8d\xcd\xa1\x77\x36\x95\x03\x3b"
-  "\x2a\xea\xe9\xa8\xdf\x82\x36\xe1\xfc\x8a\xf9\x43\x10\x4a\xa4\xeb"
-  "\xc3\x98\x35\xfd\xe9\x7a\xd0\x30\xd1\x29\xec\xbb\x14\x50\x4b\xa1"
-  "\x97\xa0\x8c\x39\x3a\xf4\x41\x12\x2e\x43\x07\xdb\xb0\xcd\x4d\x39"
-  "\x11\x9a\xe9\x5a\x94\xf8\x6c\x22\x4a\xac\xc7\xe7\xe4\xf6\x6d\xf0"
-  "\x58\x81\x14\x21\xb1\xf4\x15\x88\x3b\x0a\xba\x4f\x84\x86\xde\xdf"
-  "\xb7\x41\x47\x55\x04\x9a\xd2\xc7\xe6\xc0\xf3\xd4\x40\x39\xb9\x3a"
-  "\xc5\x53\x29\xb8\x9c\x1d\x19\x8c\xed\x6b\xf0\xb3\x83\x7d\x20\x67"
-  "\xa1\x81\x49\xd9\x3a\x94\xf2\xab\x62\x53\xca\xe2\xcc\x32\x97\x07"
-  "\x28\xc4\x40\x37\xd3\xa9\xbf\x2a\x3e\x57\x57\x07\x31\x2d\xfa\x4d"
-  "\xba\xd3\xbf\xe7\x7a\x18\x16\xce\xdf\xdb\x0d\xea\x62\xea\x62\xe0"
-  "\x35\xff\x2d\xd3\x07\x22\x55\xfd\xb6\x4b\xc8\x6c\x4f\xb0\xa5\x8b"
-  "\x34\x1d\x5d\x72\xc1\xcf\x84\xf5\x00\xf7\xc3\xea\xe1\x52\xe8\xc9"
-  "\x15\xb6\x7a\x68\xa9\x9b\x19\xc3\x55\x06\x3a\xec\x77\xcd\x69\xc3"
-  "\x83\x69\xf5\x70\xbf\xf8\xeb\xa8\x03\xb6\xed\x39\x60\xfd\xe4\x55"
-  "\xc8\x7b\xfb\xeb\x48\x33\x6f\xb5\x0a\xe9\xd3\x87\xfb\x7a\xac\x4f"
-  "\x54\x80\x4d\x28\x88\x2f\xbe\x10\x33\x7d\x9b\xbb\x8f\xcd\x89\x9b"
-  "\x8f\xa8\x43\xd7\xf2\x29\xcc\xc9\x78\x8c\xc7\x0d\xea\x3b\xcf\x3d"
-  "\x70\x1e\xfd\x53\x18\xc2\xfe\x60\x7c\xf1\x53\x14\x9a\xbc\x10\xda"
-  "\xe7\x45\xcc\xfe\x71\xd9\x50\xa6\xc4\xe7\x62\xf8\xd7\x08\xbe\x1a"
-  "\x02\x7e\x2a\xab\x32\x32\x65\x32\xbe\x5a\xcc\xf9\xea\x04\xdc\x07"
-  "\xe7\xaf\x4b\x25\xd8\xaf\x22\xcf\x9c\xc2\x3e\x73\x31\x3c\x73\x81"
-  "\x9d\x67\xce\x27\xcf\xec\x7a\xcf\xfe\x33\x7f\xef\x6a\xff\x99\xbf"
-  "\x1f\x29\xfd\x99\xbf\x2b\x97\xfe\xcc\xdf\x15\x89\x3f\xb3\x1f\xeb"
-  "\x67\x3f\xf0\xb3\x9f\x1d\x3f\xfb\xb1\x7e\xee\x7c\xad\x95\x67\x6e"
-  "\xb4\xff\xcc\x95\x83\xa5\x3f\xf3\xf7\xa7\xa4\x3f\xf3\xf7\x05\x76"
-  "\x9e\x99\xf5\xb3\x1f\xf8\xd9\xcf\x8e\x9f\xfd\x58\x3f\x7b\x7e\x63"
-  "\xff\x99\x2b\x6f\xdb\x7f\xe6\xcb\x7d\xa4\x3f\x73\x65\xa1\xf4\x67"
-  "\xae\xcc\x13\x7f\x66\x7f\xd6\xcf\xfe\xe0\x67\x7f\x3b\x7e\xf6\x67"
-  "\xfd\x3c\x62\x9b\xfd\x67\xbe\x7c\xd5\xfe\x33\xff\xc7\x4b\xfa\x33"
-  "\x5f\x3e\x28\xfd\x99\x2f\x67\xd9\x79\x66\xd6\xcf\xfe\xe0\x67\x7f"
-  "\x3b\x7e\xf6\x67\xfd\x3c\xfb\x65\xfb\xcf\xfc\x9f\x8b\xf6\x9f\xf9"
-  "\x4a\x47\xe9\xcf\xfc\x9f\x1c\xe9\xcf\xfc\x9f\x14\xb1\x67\x6e\x82"
-  "\xb8\xed\x0e\xcf\xd2\xfc\xef\xb0\xdf\x19\xd5\xc3\x47\xb9\x57\x21"
-  "\x2a\x6b\x83\x29\xca\xa3\x1a\x75\x84\x67\x8b\xa2\x33\xc6\x47\xe3"
-  "\x7f\x4d\xea\xe1\x01\x4d\xea\xe1\xc1\x8d\xdd\x9a\xca\xd7\xce\x45"
-  "\x1d\x30\x8f\x6f\x35\x21\x6f\x53\xda\x70\xbf\xa4\x57\x91\x26\x41"
-  "\x8f\x54\xe7\xe2\x75\x28\x3e\x9a\xd6\x9f\x43\x57\x51\x97\x6a\x9c"
-  "\x7b\x7e\x87\x4a\x6a\x8a\xd1\xd2\x18\x9a\xbe\x41\xe9\xa6\xe3\xf7"
-  "\xb9\xc0\xc9\x89\x29\xdf\x22\x0d\x5c\xc3\x77\x0f\xfc\x70\x39\x1e"
-  "\x93\xa0\xfd\xcc\x18\x1f\xb3\x37\x1e\x79\x7f\xb1\xa8\x1a\xe1\xed"
-  "\xd9\xf0\x33\x66\x8c\xcd\x89\x9f\x8b\xa8\xcf\xee\x55\x50\xa4\x6d"
-  "\xd6\xf5\xb1\x6e\x9b\x27\x45\x80\x2d\xdf\x60\xf6\x2d\xc9\x7a\x55"
-  "\xaa\x2d\xaf\xd4\x98\xdb\x6e\xc6\x96\x95\x46\xd2\xde\x5b\xb5\xdd"
-  "\x5f\xc0\xf5\x39\x5b\x5e\xa9\xc4\xb6\xa4\xd3\x86\x87\x96\x55\x37"
-  "\xe1\xbc\x49\x75\x23\x16\x51\xb0\x3d\xe9\x5c\xf4\x3d\x24\x62\xe3"
-  "\x14\x0b\x1b\x1f\x77\xaf\x72\xbd\x27\x62\xe3\x42\xb0\x71\xb1\x80"
-  "\x8d\x0b\x1c\xb3\xf1\xd5\x63\xce\xdb\xf8\xea\x26\x71\x1b\x5f\x3d"
-  "\x2f\xdd\xc6\x57\x43\xa5\xdb\xf8\x6a\x20\x6b\xe3\x72\xbe\x8d\x75"
-  "\x7a\x71\x1b\xfb\x59\xe8\xd8\x0f\x74\xdc\xf9\x9a\xb0\x8d\xfd\x40"
-  "\xc7\x7e\x02\x3a\xf6\x73\x50\xc7\x3f\x3c\xed\xbc\x8d\xaf\xdd\x14"
-  "\xb7\xf1\x0f\xfe\xd2\x6d\x7c\xad\x40\xba\x8d\xaf\xe5\x12\x1b\xfb"
-  "\x59\xe9\xf8\xda\x34\x3b\x36\xb6\xd0\xb1\x1f\xe8\xd8\xf3\x1b\x11"
-  "\x1b\x83\x8e\xfd\x04\x74\xec\xe7\xa0\x8e\xab\xd6\x3b\x6f\xe3\xaa"
-  "\xc9\xe2\x36\xae\xda\x25\xdd\xc6\x55\xde\xd2\x6d\x5c\xe5\xc6\xda"
-  "\xd8\x4a\xc7\x3f\x14\x8a\xdb\xd8\xdf\x42\xc7\xfe\xa0\xe3\x11\xdb"
-  "\x84\x6d\xec\x0f\x3a\xf6\x17\xd0\xb1\xbf\x83\x3a\xbe\x7e\xdd\x79"
-  "\x1b\x5f\x3f\x22\x6e\xe3\xeb\x46\xe9\x36\xbe\x1e\x27\xdd\xc6\xd7"
-  "\x17\x13\x1b\xfb\x5b\xe9\xf8\x7a\x2f\x3b\x36\xb6\xd0\xb1\x3f\xe8"
-  "\x78\xf6\xcb\x22\x36\x06\x1d\xfb\x0b\xe8\xd8\xdf\x41\x1d\xff\x38"
-  "\xc1\x79\x1b\xff\xe8\x25\x6e\xe3\x1f\x23\xa4\xdb\xf8\x86\x4e\xba"
-  "\x8d\x6f\x94\xb3\x36\xb6\xd2\xf1\x8d\x44\x31\x1b\x37\x43\x0e\xd8"
-  "\x05\x6c\xdc\xa5\x06\x51\xd9\xd8\xb6\x15\xc4\xb6\xc6\xee\xe3\xa3"
-  "\xb3\x29\x53\x14\xb6\x09\xd3\x07\xf4\x5f\xef\xae\xc6\xb4\xe1\xa3"
-  "\x68\x0a\x9e\x29\x1e\xf7\xbb\xfe\x78\xc6\xb0\x01\x75\xd5\xc4\xe3"
-  "\xfe\xdf\x9b\xcc\xfc\x30\x4d\xfc\xe6\xcb\x70\x3d\x25\xee\xf7\x32"
-  "\xa4\x36\xe6\x1b\xbd\x5e\x48\x84\x7d\x0a\xba\x7f\x7f\x15\xe4\x5e"
-  "\xa1\xf4\xdb\xde\xea\xb2\x9a\x7c\xb0\xcf\x59\x74\xae\xe2\x6f\xc8"
-  "\xd4\x7d\x7c\xcc\x10\x03\xd2\xd2\xff\xd5\xaa\x4b\x56\xe8\x90\xf1"
-  "\x4d\x6f\xf7\xb2\xd8\x62\x54\x16\xfb\x39\x0a\xa9\xa6\x1f\xd0\x3f"
-  "\x68\xdd\x9b\xbd\x26\x15\x1a\xbd\xc6\x87\x1a\xd3\x67\x04\x18\xbc"
-  "\x26\xe5\x1d\x5a\xa5\xa3\xdc\x1b\x90\x76\x71\x15\x4d\x27\xbf\x81"
-  "\x5c\x92\xaf\x21\xb7\x1d\x6f\x20\xf7\x1d\xd7\x90\xaa\xa4\xaa\x02"
-  "\x95\xde\x2a\x46\xa5\xf7\x2e\xa1\xd2\x07\xf0\x6b\x82\x9f\x09\x7e"
-  "\x89\x97\xc0\xd7\x08\x4d\xbe\x8d\x50\x42\x15\xad\x7f\xae\x12\xa9"
-  "\x4b\x0c\x15\x08\x8f\x71\xba\x43\x55\x67\xbb\x87\x23\x35\xfd\x83"
-  "\x37\xa2\xdf\xf4\xa6\x60\x9f\x0b\xde\x5e\x66\xd0\xa3\x92\xaa\x06"
-  "\xbc\x3f\x0e\xf6\xbb\x24\x54\x41\xf9\xa6\x62\xfc\xbd\x43\x7d\x49"
-  "\xe2\x19\x78\xbe\x03\x39\x34\xce\xa1\xbb\x0f\x57\xa5\x80\xa9\x4d"
-  "\xb4\x77\x5f\xa2\x83\x9b\x47\xf7\x98\xa4\xfa\xba\xba\x84\xb1\xf1"
-  "\xdb\xde\xdd\xc0\xce\x3d\x4d\x6f\x87\xa9\xa6\x5c\xba\x42\x9f\xab"
-  "\xab\x40\xb8\x2f\xe1\x5c\xdd\x59\x54\xb6\xd1\x84\x42\x56\x23\x34"
-  "\xc9\x88\x10\xb6\x45\x59\x6c\x35\x9a\x12\x8d\x3c\x70\xff\xb3\xe9"
-  "\xbf\xda\x6e\x65\x55\x7a\xb4\xce\x00\xf7\x78\xa7\xa1\xe5\x1e\xcf"
-  "\x6d\x3c\x87\x60\x5f\xcf\x73\x51\x3a\xe4\x1e\x8d\x54\xd8\xbe\x86"
-  "\xb4\xe1\x01\x53\xa0\xfe\x2c\xad\xa3\x69\x6c\x5b\x6c\x53\x6c\x5f"
-  "\x5c\x9e\xd9\xe6\x65\x91\x7a\x94\xd0\x80\x54\x65\xf1\xf0\x6f\x2c"
-  "\xad\x2f\x43\x77\x11\xdc\x63\x3e\xed\x79\x20\x07\x74\xb1\x02\x6b"
-  "\x41\x47\xfd\x58\x04\xfe\xef\x26\xa2\xa9\x02\xa2\x29\xd7\x7b\x0e"
-  "\x68\xea\x38\xa7\xa9\x5b\x4f\x73\x9a\xfa\x6f\xa3\xb8\xa6\xfe\x3b"
-  "\x9d\xd5\x54\x79\xfb\xd4\xd4\xad\xbb\xf6\x35\x75\xab\xdc\x8e\xa6"
-  "\x8a\x41\x53\x29\x7c\x4d\xd5\x74\x94\xae\xa9\xff\x6a\xda\x50\x53"
-  "\x85\xf2\x34\xf5\x5f\x17\xbe\xa6\x6e\xa9\xc5\x35\xe5\xc7\xc6\xa9"
-  "\xce\xd7\x5a\xd7\x94\x9f\x45\x9c\xaa\x59\xc6\x69\xea\xce\x64\x71"
-  "\x4d\xdd\x3e\x40\x34\xe5\xd7\x4e\xe3\xd4\xed\x71\xf6\x35\x75\xdb"
-  "\x47\x5c\x53\x7e\x10\xa7\xfc\xac\xe2\xd4\x9d\xb9\xd2\x35\x75\x7b"
-  "\x45\xdb\x69\xca\x4f\x66\x9c\xba\x1d\xc6\xd7\x54\x4d\x94\x1d\x4d"
-  "\xb1\x71\xca\xf3\x1b\x07\x34\x65\x11\xa7\xee\x9c\xe6\x34\xa5\xdf"
-  "\x27\xae\xa9\x9f\x8c\xac\xa6\xda\x69\x9c\xfa\x69\x97\x7d\x4d\xfd"
-  "\x14\x6b\x47\x53\x10\xa7\xfc\xac\xe2\x94\xfe\x88\x74\x4d\xfd\x54"
-  "\xdc\x86\x9a\x92\x19\xa7\x7e\x3a\xc8\xd7\xd4\x9d\xe3\xe2\x9a\xf2"
-  "\x67\xe3\xd4\x88\x6d\xad\x6b\xca\xdf\x22\x4e\xdd\xed\xc1\x69\xea"
-  "\xde\x7d\x71\x4d\xdd\x9b\x4a\x34\xe5\xdf\x4e\xe3\xd4\xdd\xdb\xf6"
-  "\x35\x75\xb7\x44\x5c\x53\xfe\x10\xa7\xfc\xad\xe2\x54\xad\xab\x74"
-  "\x4d\xdd\xeb\xd5\x76\x9a\xf2\x97\x19\xa7\xee\x21\xbe\xa6\xee\xaa"
-  "\xec\x68\x8a\x8d\x53\xb3\x5f\x76\x40\x53\x16\x71\xaa\x76\x09\xa7"
-  "\xa9\xfb\x13\xc4\x35\x55\xb7\x9f\xd5\x54\x3b\x8d\x53\x75\x63\xec"
-  "\x6b\xaa\x4e\x63\x47\x53\x10\xa7\xfc\xad\xe2\xd4\xfd\x99\xd2\x35"
-  "\x55\x17\xdd\x86\x9a\x92\x19\xa7\xea\xa6\xf1\x35\x55\x1b\x29\xa6"
-  "\xa9\x26\x9c\xf7\x29\x40\x53\x51\x90\xf7\x81\x86\x3c\xca\x89\xa6"
-  "\x9a\x41\x53\xbb\x2d\x35\xf5\xbd\x75\xde\x77\xff\xa4\xa9\x45\x53"
-  "\xf5\xa5\xd6\x9a\x32\x81\xa6\x9a\x19\x4d\x3d\xb8\x6e\xce\xfb\xca"
-  "\x6a\x72\xc0\x57\xb7\x50\x59\x28\xe8\x29\x83\xd5\xd3\xf7\xa0\x27"
-  "\x78\x1e\x13\x3c\x6f\x49\x65\x05\x0a\xd1\x93\xe7\x6a\x82\xe7\x35"
-  "\x59\x6a\xa9\xa9\x9a\xc2\x1a\xc2\xda\x31\xeb\xa8\x74\x29\xe8\x27"
-  "\xe6\x3c\x2a\x5d\x05\xbf\x35\xf0\x8b\x87\x1f\x3a\x8f\x4a\xaa\x11"
-  "\xd3\x67\xcf\xe9\xa7\x9c\xd5\xcf\x83\xf5\xf6\xf5\xf3\x20\x5c\x5a"
-  "\x8e\x57\x7f\x59\xba\x7e\x1e\xe4\xb3\x63\xe9\x54\x21\x53\xaf\xd0"
-  "\x78\xac\x2b\xd1\xc8\x2d\x14\x62\x40\x1e\xf4\x6c\x6d\x37\xf7\x30"
-  "\xa4\x5a\x6b\x44\xd4\xf6\x37\x90\x6a\xfb\x77\xf0\xbc\xe6\xba\x73"
-  "\x0d\xb9\x9f\x6d\xf8\x1b\x2a\xb9\x57\x81\x4a\x1e\x9c\x41\x25\x26"
-  "\xf8\xdd\x82\x1f\xdc\x63\xc8\x7c\xcb\xe7\xd5\xb3\xcf\x5b\xbf\x0c"
-  "\xca\xf2\x11\x7f\xde\xfa\x50\xe6\x79\x23\xe1\x79\x9b\xb8\xe7\x2d"
-  "\x03\x2d\x82\x5f\x7a\x9a\xd8\x3c\x31\x44\x8f\x3a\xbe\x63\xa0\xe9"
-  "\x26\x56\x83\xd8\x2f\x67\x2f\x34\xa0\x90\x68\xf0\xd5\x9b\xa0\xc1"
-  "\xaa\x3c\x94\x10\x07\x1a\x6c\x6a\xc0\xef\xf5\xf5\x65\x89\x8d\xa0"
-  "\xc1\x07\x69\x34\xd8\xad\x19\x6b\xf0\x7b\xac\xc1\xfb\x85\x26\x71"
-  "\x0d\x16\x10\x0d\x42\x9e\xd8\xba\x06\x2d\xe2\x5a\xc3\x38\x4e\x83"
-  "\x4d\x53\xc5\x35\xd8\xb8\xd0\x9c\x27\xfe\xfc\x1a\x6c\x74\xb5\xaf"
-  "\xc1\x86\x2a\x69\x39\x61\x53\x84\x74\x0d\x36\xfa\xb5\x9d\x06\x1b"
-  "\xef\xdb\xd7\x60\xe3\x05\x07\x34\x58\x28\x4f\x83\x8d\xde\x7c\x0d"
-  "\x36\x8c\x12\xd7\xa0\x1f\x1b\x07\x21\xaf\x6c\x55\x83\x96\x79\x65"
-  "\xd3\x19\x4e\x83\x86\x8b\xe2\x1a\x6c\xbe\x6d\xce\x2b\x7f\x7e\x0d"
-  "\x36\x6f\xb5\xaf\xc1\xe6\x28\x69\x39\xa4\xe1\xba\x74\x0d\x36\x17"
-  "\xb6\x9d\x06\x0d\xab\xed\x6b\xd0\x10\xd6\xba\x06\xfd\x64\xc6\xc1"
-  "\xe6\x2c\xbe\x06\x9b\x8a\xec\x68\x90\x8d\x83\x90\x87\xb6\xae\x41"
-  "\x8b\x38\x68\x9c\xcc\x69\x90\x9e\x29\xae\x41\xd3\x32\x73\x1e\xfa"
-  "\xf3\x6b\xd0\xd4\xc5\xbe\x06\x8d\x35\xd2\x72\x4e\x7a\xa1\x74\x0d"
-  "\x9a\x46\xb5\x9d\x06\x4d\x46\xfb\x1a\x34\x55\x3a\xa0\x41\x99\x71"
-  "\xd0\xa4\xe1\x6b\xd0\x18\x24\xae\x41\x7f\x36\x0e\x42\xde\xda\xaa"
-  "\x06\x2d\xf3\x56\xfa\x7c\x8b\x06\x95\x8a\xcb\xa2\x1a\x54\xa2\xfb"
-  "\xe6\xbc\xf5\x67\xd7\xa0\x12\xa5\xda\xd5\xa0\x12\x45\x4b\xca\x51"
-  "\x95\x8a\xdb\x92\x35\xa8\x44\x45\x6d\xa6\x41\xa5\x62\xbd\x5d\x0d"
-  "\x2a\x15\xe1\xad\x6b\xd0\x5f\x5e\x1c\x54\xa2\x5c\xbe\x06\xe9\x62"
-  "\x3b\x1a\x64\xe3\x20\xe4\xb9\xad\x6b\x90\x8b\x83\x4a\x6a\x3a\xa7"
-  "\x41\x97\x08\x71\x0d\x2a\x57\x9b\xf3\xdc\x9f\x5f\x83\x4a\x2f\xfb"
-  "\x1a\xa4\xea\x24\xe5\xb4\x4a\x97\x65\xd2\x35\xa8\x0c\x6a\x3b\x0d"
-  "\xba\xb8\xda\xd7\xa0\xb2\xca\x01\x0d\xca\x8b\x83\x4a\xa5\x96\xa7"
-  "\x41\x25\x35\x49\x4c\x83\x26\xc8\x8b\x9b\x73\xfb\xab\x4c\x69\x93"
-  "\x0a\x3d\x14\x1a\x64\x50\xbf\x90\x58\xb6\xa2\x0e\x4d\xb9\x0f\xf6"
-  "\x89\xbe\x8f\x5e\xbf\xaf\x42\xc6\xb4\x49\x79\xc0\xe4\x01\x16\xf9"
-  "\x33\x33\xb6\xcc\x90\x72\x20\x67\xc7\x52\xe4\x02\xf9\x77\x0c\xde"
-  "\x56\x76\xa3\x01\xe1\xeb\xaf\xc3\xf7\x73\x8b\xbb\x1f\xdc\x4f\x40"
-  "\xff\xa4\x55\x31\xef\x98\x9b\x74\xa8\x6a\x14\x52\x96\x54\xe9\xc0"
-  "\x0e\x6b\x18\xff\x62\xbb\xdc\x50\xba\x06\xed\xbd\x83\x5c\x0c\x3f"
-  "\x78\xf7\x04\x7b\xab\xbb\xbc\x8b\x14\xbd\xaa\x68\x13\xb6\x2b\xb6"
-  "\x17\xb6\xb1\x66\x0d\x4d\xc3\x71\xe9\xe7\x40\x63\x86\x1f\xb4\x3d"
-  "\xf7\xc0\x71\x82\xf9\xaa\xd2\x35\x5b\xba\x36\x5c\xc3\x99\x79\x0b"
-  "\x4a\xd7\x51\x25\x95\x48\xf0\xdd\x31\xd8\xaa\xc0\x41\x5b\x15\x5a"
-  "\xe4\x79\x8f\xc0\x56\x1d\xa2\x1d\xb3\x55\x87\x93\x56\xb6\xb2\xcd"
-  "\xab\x94\x1d\xce\x48\xb7\x55\x87\x24\x62\xab\x0e\x51\xe2\xb6\xf2"
-  "\x73\x50\x57\x7e\x01\x16\xf9\xc8\x23\xb0\xd5\x53\x59\x8e\xd9\xea"
-  "\xa9\xdb\x7c\x5b\x09\xf0\xbf\xf2\xa9\xfb\xd2\x6d\xf5\x14\x59\x0f"
-  "\x49\xf9\x54\x9a\x1d\x5b\x39\xa8\x2b\xbf\x42\x0b\x6e\x7e\x04\xb6"
-  "\x72\x2b\x76\xcc\x56\x1d\x7b\x58\xd9\xca\x96\x53\x95\x1d\xfb\x48"
-  "\xb7\x95\x5b\x15\xb1\x95\x5b\x91\xb8\xad\xfc\x1d\xd4\x95\x7f\x80"
-  "\x05\xdf\x3d\x02\x5b\x75\xac\x73\xcc\x56\x9d\xc6\xf1\x6d\x25\xc4"
-  "\x53\x9d\x26\x4b\xb7\x55\x27\xf2\x3d\x74\x65\xc7\x1a\x3b\xb6\x72"
-  "\x50\x57\xfe\x85\x16\x1c\xf2\x08\x6c\xd5\x59\xe3\x98\xad\x3a\x2f"
-  "\xb3\xb2\x95\x40\xbb\xdf\x79\xb5\x74\x5b\x75\x1e\x45\x6c\xd5\xd9"
-  "\x5b\xcc\x56\xc6\xb4\xe1\x7e\x1e\x60\x83\xc6\x8c\xe1\x2a\x8f\x58"
-  "\x44\x35\xf9\x80\xdd\xd4\x60\xb7\xf5\x1a\xd4\x9c\x06\x76\xd3\x1b"
-  "\xd0\x94\x65\x57\xe8\x73\x35\x46\xd4\x04\x36\x6b\x54\x0f\x0f\x28"
-  "\xd3\x57\xe3\x31\x47\x2f\x5e\x53\x76\x99\x39\x7b\x99\x0a\x61\xbb"
-  "\x61\x3b\x60\xdb\xd1\x60\x37\xc6\x8e\xea\x19\x01\x46\xf5\xf8\xd0"
-  "\xc9\xb7\xaf\xd0\xef\xe8\x68\x1a\x3f\x2f\xad\x6a\xcc\xc7\xef\x05"
-  "\x42\xaa\x51\x47\xcd\xab\xf8\x99\xba\x74\xc4\xdb\xcb\xf4\x15\xc0"
-  "\x07\xf7\x10\xc3\x66\x57\xb4\x6a\xe3\xef\xb5\xee\xc6\xb2\xb0\xdf"
-  "\xd1\xdd\x9a\xca\x0d\xdd\xc7\xe6\x24\xdc\x46\x1d\x30\x3f\x24\x9b"
-  "\x90\xf7\xba\x25\x88\xfa\x6c\x51\x11\xc5\xcc\x5d\x8b\xc1\x65\xb8"
-  "\x5f\x04\xbb\x78\xd3\xb5\x16\x63\xba\x6b\xa3\x50\xd9\x8d\x14\xc6"
-  "\x6f\xd6\x8c\xc0\xf8\xed\xdf\x5a\x15\x70\xa6\x2f\xad\x1e\x1e\x9c"
-  "\x72\x0e\x69\xe8\x66\xb0\x71\x3c\x73\x3f\x27\xf7\x36\x49\xb5\xb1"
-  "\x3b\x33\xfe\xdb\xa4\x61\xc7\x6f\x81\x9d\xf0\xf5\x99\xf1\x5b\xd1"
-  "\x16\xe3\xb7\xe0\x9e\x5b\xc6\x6f\x29\xdd\x23\xf1\xf8\x2d\xd3\x15"
-  "\xef\x9e\xe6\x67\x7f\x67\x31\x4d\xc3\xb3\x77\x3b\x57\xa7\x47\xf8"
-  "\xf9\xcf\xd5\x15\xa1\x84\x15\x48\x75\xae\xa9\x1a\xc5\xd7\xd1\xfa"
-  "\x73\x89\x37\x51\xc8\x7d\xcc\xc1\x58\x2f\x5d\xa6\x12\xbf\xba\xfb"
-  "\x98\xae\x68\x7b\xea\x94\x5d\x82\xcf\x95\x23\x64\x31\x8f\x27\x0a"
-  "\x98\xd9\x0d\xfc\x10\x55\x96\x78\x0d\x81\x4f\xca\xcb\x0c\xdf\x61"
-  "\x3f\x45\xc1\xfe\x51\x2d\x7c\xdd\x7d\xfc\x37\x78\x1b\xf6\x19\x7e"
-  "\xdf\x54\x16\xad\x67\x8e\x31\xef\xc7\xba\xf0\x88\x4d\x44\x65\xb1"
-  "\x4d\xe8\x9c\x01\x01\x5f\x75\x2e\xff\x67\x58\x85\x98\x8e\x0a\x58"
-  "\x1d\xa5\x78\xc4\xba\xde\x73\x40\x47\x85\x9c\x8e\x3c\xf6\x39\xa7"
-  "\x23\x8f\xa9\xce\xeb\xc8\xe3\x69\x27\x74\x54\xcc\xd7\x91\xaa\xa3"
-  "\x74\x1d\x75\xad\x96\xae\xa3\xae\x07\x9d\xd3\x91\xc7\x2e\xa2\xa3"
-  "\xae\x8b\x89\x8e\x3c\x52\x38\x1d\x31\x73\xa3\x1e\x91\x8e\xba\x7a"
-  "\x8b\xeb\xc8\x8f\x8d\x47\x7e\x10\x8f\x3a\x5f\x6b\x5d\x47\x7e\x16"
-  "\xf1\xc8\xf3\xa6\x73\x3a\xf2\xdc\xe5\xbc\x8e\x3c\xe7\xcb\xd7\x91"
-  "\x9f\x55\x3c\xea\x36\x55\xba\x8e\x3c\x7d\xa5\xeb\x48\x55\xe7\x9c"
-  "\x8e\x3c\xaf\x12\x1d\xa9\x0a\x88\x8e\x3c\x2b\x38\x1d\x31\xf3\xcd"
-  "\x1e\x91\x8e\x54\xe1\x76\x74\xc4\xc6\x23\x3f\x88\x47\x9e\xdf\x38"
-  "\xa0\x23\x8b\x78\xa4\x1e\xea\x9c\x8e\x7e\x71\xd5\x79\x1d\xfd\xe2"
-  "\x90\x13\x3a\xb2\x8a\x47\xea\x5d\xd2\x75\xf4\x8b\x58\xe9\x3a\xfa"
-  "\xc5\x28\xe7\x74\xa4\x1e\x48\x74\xd4\xcd\x40\x74\xa4\xd6\x70\x3a"
-  "\x62\xe6\xf0\x3d\x22\x1d\x75\xcb\x13\xd7\x91\x3f\x1b\x8f\xfc\x21"
-  "\x1e\x8d\xd8\xd6\xba\x8e\xfc\x2d\xe2\x51\xf7\xd5\xce\xe9\xa8\xfb"
-  "\x40\xe7\x75\xe4\x75\x5f\xbe\x8e\xfc\xad\xe2\x51\xf7\xab\xd2\x75"
-  "\xe4\x55\x24\x5d\x47\x5e\x1b\x9d\xd3\x51\xf7\x65\x44\x47\x5e\x41"
-  "\x44\x47\xdd\xa3\x38\x1d\x31\xf3\x22\x1f\x91\x8e\xd4\x7a\x3b\x3a"
-  "\x62\xe3\x91\x3f\xc4\xa3\xd9\x2f\x3b\xa0\x23\x8b\x78\xe4\x7d\xd2"
-  "\x39\x1d\x79\x2f\x73\x5e\x47\xde\xa3\x9d\xd0\x91\x55\x3c\xea\x31"
-  "\x50\xba\x8e\xbc\xdd\xa4\xeb\xe8\x97\x25\xce\xe9\xc8\xfb\x18\xd1"
-  "\xd1\x2f\x93\x88\x8e\xbc\xf3\x39\x1d\x31\x73\x4d\x1f\x91\x8e\x7e"
-  "\x19\x20\xa6\x23\xbc\x16\xc1\x87\x64\x5d\x88\xba\x1d\x6b\x50\xc0"
-  "\x5e\xfc\x6f\x13\xf2\xad\x4f\xee\x11\x7e\x32\x8e\xac\x07\xa0\x53"
-  "\xf6\x60\xfa\x7b\x85\xce\xef\x7c\x00\xfc\xa2\x1e\xee\x1b\x72\x99"
-  "\xac\xd1\x80\xd7\x05\xa9\x4d\x88\x42\x43\xf0\xba\x0c\xca\x9e\x99"
-  "\x78\x1d\xab\x96\xb5\x03\xd4\x22\x6b\x07\xcc\x12\x5f\x3b\xa0\x29"
-  "\xc3\x3c\xef\x36\x8f\x9b\x77\xab\xec\x39\xdf\xee\xbc\x5b\x65\xcf"
-  "\xc9\xd9\xb3\xa4\xea\xa1\x27\x33\xff\xab\xb6\xfb\x70\x55\x7d\x72"
-  "\xcf\x39\xf0\xcc\x7e\xe4\xd9\x7b\x56\x20\x87\xe6\xe3\xe6\x59\xe8"
-  "\xa4\xa7\xdb\xf4\x39\x28\x91\xde\x76\x69\x0e\xed\x35\xdc\x97\x4e"
-  "\x1f\x1e\x28\xf1\x5e\x44\xbf\xff\xc1\xda\x3b\x5f\xd8\xde\xbd\xdc"
-  "\x58\x7b\xa7\xb0\xf6\x16\x5e\xb7\x60\x96\xf8\xba\x05\xc2\xf6\xfe"
-  "\x95\xfd\x79\xce\xca\x5f\x9d\x90\x6e\xef\x5f\x6d\x61\xed\x9d\x52"
-  "\x9f\xfc\xab\x12\xce\xde\xbd\x82\xa5\xdb\xfb\x57\xb1\xc4\xde\xdf"
-  "\x85\x82\xbd\xf3\xc1\xde\x45\xd2\xee\xa5\x97\xda\xbe\xbd\xfd\x44"
-  "\xf4\xfd\x74\x2c\xb1\x37\xbb\x66\x82\x5a\x64\xcd\x84\x59\xe2\x6b"
-  "\x26\x08\xdb\xfb\xe9\x71\xf6\xed\xfd\xf4\x60\xe9\xf6\xee\xd5\x40"
-  "\xec\xed\x07\xfa\x7e\x7a\x14\x67\xef\xa7\x1d\x5c\x57\xc0\xd2\xde"
-  "\xbd\xaa\x89\xbd\xbf\x0f\xa2\xbd\xfc\x40\xdf\x7e\x12\xf5\xfd\xf4"
-  "\xc6\x56\xec\x2d\xa2\xef\xde\xd5\xac\xbd\x59\x7d\x8b\xac\xd7\x30"
-  "\x4b\x7c\xbd\x06\x61\x7b\xf7\x3e\x6a\xdf\xde\xbd\xb3\xa5\xdb\xbb"
-  "\x77\x14\x6b\x6f\xd0\x77\xef\x83\x9c\xbd\x9f\xd1\x4a\xb7\x77\xef"
-  "\x30\x62\xef\xca\x00\xb0\x37\xe8\xdb\x4f\xa2\xbe\x7b\x8b\x7e\xff"
-  "\x93\xd8\xdb\x5f\x44\xdf\x9a\x30\x62\x6f\x76\xad\x08\xb5\xc8\x5a"
-  "\x11\xb3\xc4\xd7\x8a\x10\xb6\xb7\xa6\xbf\x7d\x7b\x6b\xba\x48\xb7"
-  "\xf7\x33\x15\xc4\xde\xfe\xa0\x6f\x4d\x2f\xce\xde\x9a\x4c\xe9\xf6"
-  "\x7e\xa6\x98\xd8\xfb\xf2\x20\xda\xcb\x1f\xf4\xed\x2f\x51\xdf\x9a"
-  "\xc8\x56\xec\x2d\xa2\xef\x3e\xc5\xac\xbd\x59\x7d\x8b\xac\x53\x31"
-  "\x4b\x7c\x9d\x0a\x61\x7b\xf7\x49\xb7\x6f\xef\x3e\xeb\xa4\xdb\xbb"
-  "\x4f\x30\x6b\x6f\xd0\x77\x9f\x24\xce\xde\x7d\xdd\xa4\xdb\xbb\x4f"
-  "\x00\xb1\xf7\x7f\x34\x60\x6f\xd0\xb7\xbf\x44\x7d\xf7\xb9\x20\x66"
-  "\x6f\x0f\xb0\xf7\x69\xe0\x18\x68\x07\x03\x4c\x69\xc0\x29\x46\xbe"
-  "\xdd\xcb\x62\x03\xd0\xf3\x0f\xb0\xed\xfb\x15\x40\xdb\x11\xd0\x66"
-  "\xeb\x65\x28\xfb\x65\x3b\x3d\x77\x58\xd9\x6f\xa1\xe8\xdc\x61\x65"
-  "\xbf\xa9\x92\xe7\x0e\x2b\xfb\xf5\xe2\x18\xa8\x5f\x38\xe7\xd3\x7e"
-  "\x4c\xfc\x90\x34\xa7\x58\xd9\xcf\x5d\x70\x1d\x0d\x65\xdf\xe3\x78"
-  "\x4e\x31\xbd\xed\x8a\xda\x94\x2e\x87\x8d\xfa\x15\x39\xe0\xeb\x42"
-  "\xf0\x43\xbe\xb8\xaf\xfb\xe7\x80\xaf\x0b\xdb\x6c\xdd\x0e\x65\xff"
-  "\xad\xce\xfb\xba\xff\x74\x71\x5f\xf7\x1f\x2d\xdd\xd7\xfd\xdd\x38"
-  "\xfe\xea\x3f\x89\xf3\x75\x7f\x9d\x74\x5f\xfb\x34\x08\xae\xe7\xa1"
-  "\xf4\xc9\x23\xbe\xd6\xc5\x82\xaf\x65\x70\x59\xff\x83\xad\xfb\xda"
-  "\x0f\xea\xb5\x9f\x9d\x7a\xfd\x6c\x12\xb4\x99\x01\x6d\xb6\x7e\x88"
-  "\xf2\xd9\x95\xce\xfb\xfa\xd9\x31\xe2\xbe\x7e\x76\xa0\x74\x5f\x0f"
-  "\xa8\xe3\xd8\xef\xd9\x00\xce\xd7\xcf\x96\x48\xf7\xf5\x80\x2a\xc1"
-  "\x75\x45\x94\x03\xd2\x88\xaf\xaf\x56\x9a\xd2\xe5\x30\xe1\xb3\x99"
-  "\x0e\xf8\x1a\xea\xb5\x9f\x9d\x7a\x3d\x30\x16\x7c\x5d\xd8\x66\xeb"
-  "\x98\x28\x07\x46\x38\xef\xeb\x81\x83\xc5\x7d\x3d\xd0\x4b\xba\xaf"
-  "\xb5\x3a\x8e\x3b\x07\xfa\x70\xbe\x1e\x58\x28\xdd\xd7\xda\x72\xc1"
-  "\xf5\x4d\x94\xda\x44\xe2\xeb\x1f\x02\xc1\xd7\x32\x78\x74\xa0\x28"
-  "\xff\x73\xbe\xf6\x87\x7a\xed\x6f\xa7\x5e\x3f\x17\x09\xac\x10\xd0"
-  "\x66\xeb\xa9\x28\x9f\x9b\xec\xbc\xaf\x9f\xeb\x21\xee\xeb\xe7\x14"
-  "\xd2\x7d\xfd\xeb\x12\x8e\x79\x9f\x53\x71\xbe\x7e\x2e\x57\xba\xaf"
-  "\x7f\x7d\x5c\x70\x9d\x15\xe5\xaf\x17\x13\x5f\x57\xe5\x9a\xd2\xe5"
-  "\xb0\xf0\x73\xd1\x0e\xf8\x1a\xea\xb5\xbf\x9d\x7a\x3d\x18\xf2\x7a"
-  "\xff\xc2\x36\x5b\xd7\x45\x39\x78\xa4\xf3\xbe\x1e\xec\x2a\xee\xeb"
-  "\x41\xb7\xa5\xfb\x7a\x50\x21\xc7\xdb\x83\x0c\x9c\xaf\x07\xa7\x48"
-  "\xf7\xf5\xa0\x3c\xc1\xf5\x5e\x94\x83\xc2\x88\xaf\x6f\xb8\x81\xaf"
-  "\x65\x70\xf8\xe0\x39\x72\x38\x7c\x79\x36\x72\xe3\xfb\x7b\x48\x60"
-  "\xdb\xb2\xf8\x90\x81\xce\xfb\xfb\xf9\xfb\xe2\xfe\x7e\xfe\xb2\x74"
-  "\x7f\x3f\x9f\xc7\xb1\xf8\xf3\x35\x9c\xbf\x87\x24\x4a\xf7\xf7\xf3"
-  "\x99\xc2\x2c\xfe\x7c\xb0\x73\x2c\x3e\x64\x92\x1c\x16\xb7\xf5\xf7"
-  "\x50\xdf\xb6\xe5\xf1\xa1\x3d\x9c\xf7\xb7\xef\x75\x71\x7f\xfb\x96"
-  "\x4a\xf7\xb7\x6f\x26\xc7\xe3\xbe\x95\x9c\xbf\x87\x46\x4b\xf7\xb7"
-  "\xef\x16\x61\x1e\xf7\x0d\x70\x8e\xc7\x87\x8e\x92\xc3\xe3\xb6\xfe"
-  "\x1e\xae\x69\x5b\x26\x1f\xde\xd1\x79\x7f\x0f\xbb\x28\xee\xef\x61"
-  "\x27\xa4\xfb\x7b\xd8\x16\x8e\xc9\x87\x59\xf4\x7f\x0f\x0f\x97\xee"
-  "\xef\x61\xb1\xc2\x4c\x3e\x4c\xeb\x1c\x93\x0f\x17\xfd\xfe\xa1\x3d"
-  "\x26\xb7\xf5\xb7\xbf\xaa\x6d\xb9\xdc\xaf\xd1\x79\x7f\xfb\x9d\x16"
-  "\xf7\xb7\xdf\x21\xe9\xfe\xf6\x8b\xe5\xb8\xdc\xef\x38\xe7\x6f\x7f"
-  "\xe9\xeb\x67\x2a\xfd\xa2\x84\xb9\xdc\xcf\xdb\x39\x2e\xf7\xef\x25"
-  "\x87\xcb\x6d\xfd\xfd\x02\x6a\x5b\x36\x1f\x71\xd3\x79\x7f\x8f\x38"
-  "\x2a\xee\xef\x11\xd9\xd2\xfd\x3d\x22\x8a\x63\xf3\x11\x16\xfd\xff"
-  "\x2f\x04\x4a\xf7\xf7\x88\x30\x61\x36\x1f\xe1\xe6\x1c\x9b\xbf\xe0"
-  "\x2e\x87\xcd\x6d\xfd\x1d\xa0\x6f\x5b\x3e\x0f\xb8\xe4\xbc\xbf\x03"
-  "\xf6\x8b\xfb\x3b\x60\xbb\x74\x7f\x07\x84\x71\x7c\x1e\x90\xc5\xf9"
-  "\x7b\xa4\xaf\x74\x7f\x07\x04\x0b\xf3\xf9\x0b\x0d\xce\xf1\x79\x80"
-  "\xc1\xf9\x7e\xf2\x17\x4b\x30\x9b\x4b\x5d\xff\xb1\x6c\x85\x79\xce"
-  "\xdd\x48\x6e\xfd\x47\xe5\x8b\xcc\x77\x20\x05\xd7\x96\x51\xbe\xd8"
-  "\xa3\x5d\xaf\xff\xa8\xfc\x8d\xfd\xf5\x1f\x95\xbf\x91\xb6\xfe\xa3"
-  "\xf2\x45\x85\xf4\xf1\xf8\xbf\x29\xe1\x72\x84\x17\x2d\xf2\xff\x51"
-  "\x4c\xbd\x6e\xd7\xeb\x42\x2a\x7f\xc3\x5f\x17\x52\x39\x92\x59\x17"
-  "\x92\xde\xf6\xe3\x62\x79\xb9\xc8\x8b\x15\xce\xbf\x17\xf8\x6d\x1e"
-  "\xce\x43\xa4\xae\x43\xc9\x69\x7b\xd4\x7e\x4e\xdb\xbf\xdd\x25\xae"
-  "\xed\xd1\xf7\xdb\xf5\x3a\x94\xca\xd1\xab\xed\x6b\x7b\x74\x98\xa4"
-  "\x35\x47\x94\xa3\xa5\xaf\x7b\xa3\x1c\x9d\xc7\xe5\x43\xa3\x2d\xf2"
-  "\xdf\xdf\x56\xb7\xa1\xb6\xe5\xad\xa7\xa4\x1c\x9d\xc4\xd7\xf6\xa8"
-  "\x2c\xa2\xed\x9b\x45\xf2\xf2\xae\xdf\x8a\x7e\xff\xdd\xf1\xf7\x20"
-  "\x63\x36\xe2\x9c\x4b\xea\x7a\x98\x9c\xb6\x5f\x5a\xcf\x69\x7b\xcc"
-  "\x4a\x71\x6d\x07\x9e\x6f\xd7\xeb\x61\x2a\x03\xa7\xdb\xd7\x76\xa0"
-  "\x9f\xa4\xb5\x4c\x94\x81\xc7\xa4\x6b\x3b\x70\x23\x97\xfb\x05\x16"
-  "\x73\xda\x1e\x73\xaa\xed\xb4\x2d\x73\x9d\x4c\x65\x60\x14\x5f\xdb"
-  "\x2f\xc5\x12\x6d\xd7\xa8\xe5\xe5\x98\x63\x52\x9c\x7f\xef\x13\x14"
-  "\x8e\xf3\x4b\xa9\xeb\x72\x72\xda\x7e\x79\x2e\xa7\xed\x20\x9b\x75"
-  "\xa1\x38\x6d\x8f\x3d\xd4\xae\xd7\xe5\x54\x8e\x1d\x6a\x5f\xdb\x63"
-  "\x55\x92\xd6\x48\x51\x8e\x4d\x97\xae\xed\xb1\xe1\x5c\x9e\x3b\x36"
-  "\x97\xd3\x76\x50\x4e\x1b\x6a\x5b\x66\xdc\x1e\x1b\xc4\xd7\xf6\xcb"
-  "\xd3\x88\xb6\xef\x44\xc9\xcb\xa7\x83\x16\x3b\xff\x9e\xeb\x77\xa3"
-  "\x70\x2e\x2d\x75\x7d\x50\x4e\xdb\xe3\x46\x72\xda\xfe\xdd\x60\x71"
-  "\x6d\x8f\xdf\xda\xae\xd7\x07\x55\x8e\xb7\xbf\xfe\x8f\x72\x9c\x9d"
-  "\xf5\x7f\x84\xe6\x0a\x8f\x97\xb1\xee\xc5\xf8\x51\x5c\x4e\x3f\x3e"
-  "\x91\xd3\xf6\xef\xe2\xda\x4e\xdb\x32\xd7\x0d\x55\x8e\xd7\xf0\xb5"
-  "\x3d\xce\x97\x68\x5b\x7f\x5c\x5e\xdf\xc1\xef\x82\x9d\x7f\xaf\xf7"
-  "\x8a\x37\xee\x37\x90\xba\x4e\x29\xa7\xed\x60\x2f\x4e\xdb\xaf\x74"
-  "\x14\xd7\xf6\x84\xf9\xed\x7a\x9d\x52\x65\xf0\x4d\xfb\xda\x0e\x2e"
-  "\x96\xb6\xa6\xcb\x04\x19\xf3\xe0\x27\x78\x73\xfd\x17\x13\x2c\xc6"
-  "\xbf\xbf\x12\xd6\x86\xda\x96\x19\xb7\x83\x0d\x7c\x6d\x07\xbb\x13"
-  "\x6d\xd7\xaa\xe4\xf5\x93\xbc\xe2\xe3\x7c\x3f\xc9\x64\x1f\xe6\x1d"
-  "\xa6\xc4\xf5\x52\x39\x6d\xbf\x72\x97\x5b\x9b\x68\xb2\x97\xb5\xb6"
-  "\xb9\xb5\x89\x26\x0d\x6e\x37\xeb\xa5\x2a\x27\x1e\xb1\xaf\xe3\x89"
-  "\x29\xd2\xfa\x44\x26\x79\x49\xd7\xf1\x44\x1d\xd7\x27\x32\xc9\x62"
-  "\xfc\xcb\x64\xf3\x37\xc9\xdb\x60\xcd\xa2\x49\xc7\xec\xaf\x59\x34"
-  "\x29\xf3\x91\xad\xa3\xaa\x9c\x78\x8a\xbf\x66\xd1\x2b\xd5\x26\xa6"
-  "\x2e\xdc\x8f\x94\xd7\xaf\x32\xd9\xd7\xf9\x7e\x95\x50\xf2\x7e\x57"
-  "\xe2\xba\xad\x5c\x5d\x98\x6c\xe4\xea\x42\x68\x1f\xf1\xba\x10\x32"
-  "\xb2\xdd\xac\xdb\xaa\x9c\x72\xc2\x7e\x5d\x98\x92\x25\xad\x0f\x25"
-  "\x44\xc6\x3a\x30\x53\x6a\xb8\x3e\x94\x10\x5f\xae\x2e\x84\x46\xb7"
-  "\x5d\x5d\x08\x39\x6d\xbf\x2e\x84\xe4\x3e\xb2\xf5\x5c\x95\x53\xca"
-  "\xf9\x75\x61\x72\x1d\xa9\x0b\xf5\xd5\xf2\xfa\x61\x42\x65\xbd\xff"
-  "\xe6\xd7\x85\xd7\x46\x31\xef\xbe\x25\xae\x1f\xcb\xd5\x85\xa9\x1d"
-  "\xb9\xba\xf0\x9a\x0d\xcf\x73\x75\xe1\xd5\x71\xed\x66\xfd\x58\xe5"
-  "\xd4\x33\xf6\xeb\xc2\xd4\x3c\x69\x7d\x2e\xaf\x0e\x96\x5e\x17\xa6"
-  "\x5a\xcc\x7f\x7a\xd5\x62\xfe\xd3\x6b\x71\x6d\x57\x17\x5e\x3d\x6f"
-  "\xbf\x2e\xbc\x9a\xff\xc8\xd6\x95\x55\x4e\xad\xe4\xd7\x85\xa9\x88"
-  "\xd4\x85\xa6\xc5\xf2\xfa\x6d\x5e\x73\x80\xff\x5b\xeb\xb7\x99\x11"
-  "\xcc\x8c\x0b\x90\xb8\x8e\x2d\x57\x17\xa6\x79\x71\x75\x61\xc6\x48"
-  "\xf1\xba\x30\x7d\x6a\xbb\x59\xc7\x56\x39\xed\xa2\xfd\xba\x30\xad"
-  "\x40\x5a\x1f\xcd\xf4\x91\xd2\xeb\xc2\x74\x17\xae\x8f\x66\x7a\x30"
-  "\x57\x17\x66\x6c\x69\xbb\xba\x30\xfd\xb2\xfd\xba\x30\xfd\xf8\x23"
-  "\x5b\xdf\x56\x39\xad\x9a\x5f\x17\xa6\xb9\x93\xba\x60\xd0\xcb\xeb"
-  "\xe7\x99\x31\xcd\xf9\x7e\x9e\x99\xd3\x98\x31\x13\x12\xd7\xd3\xe5"
-  "\xea\xc2\xef\xfb\x70\x75\x61\xe6\x38\xf1\xba\x10\x36\xb7\xfd\xac"
-  "\xa7\xfb\xfb\xab\xf6\xeb\xc2\xef\x8b\xa4\xf5\xe9\x84\x8d\x93\x5e"
-  "\x17\xc2\x54\x5c\x9f\x4e\xd8\x34\xae\x2e\xcc\x4c\x6b\xbb\xba\x10"
-  "\x76\xd3\x7e\x5d\x08\x2b\x7e\x74\xeb\xec\xfe\xbe\x8e\x5f\x17\x7e"
-  "\xef\x4d\xea\x02\xbd\x42\x5e\xbf\xd0\xcc\x70\xe7\xfb\x85\xe6\x84"
-  "\x33\xe3\x49\x24\xae\xeb\xcb\xd5\x85\x59\x83\xb9\xba\x30\x47\xfc"
-  "\x3b\x0f\xca\xd9\x0b\xdb\xcf\xba\xbe\xb3\xec\x7f\xff\x48\x39\xcb"
-  "\xde\xf7\x8f\x04\xfa\x80\x66\x4f\x95\x5e\x17\x66\xf7\xe2\xfa\x80"
-  "\x66\x5b\xcc\xff\x9b\x93\xd3\x76\x75\x61\xb6\xfd\xef\x3f\x28\x67"
-  "\x3b\xf0\xfd\x07\xb9\xeb\xfd\xce\x46\xfc\xba\x30\xcb\x87\xa9\x0b"
-  "\xc9\x8a\x06\x79\xfd\x48\x73\x5a\xed\xff\xc7\x79\x7e\xb3\xda\xb6"
-  "\x1f\xa9\xa4\x2a\x00\x3d\x37\x0b\xd7\x85\xd7\xd5\x86\xf4\xe1\x01"
-  "\x78\x7d\x61\xa3\x0f\xbb\x06\xe5\x7a\x76\x8d\x97\x3a\x03\x59\x83"
-  "\x52\x6f\x6c\x59\x83\x92\xac\xfd\x81\x28\x3c\x17\x18\xcf\x09\x36"
-  "\xa8\xc8\xfa\x93\x34\x1e\x13\x85\xc7\x48\x5d\x2b\x66\xd6\x57\x89"
-  "\x33\xc0\xb3\xdf\x68\x65\xfd\xc9\x70\x1d\x2a\x09\x5f\x83\x0c\x9e"
-  "\x07\x72\xc8\x3c\xe1\xb9\xb9\xcc\xfa\x93\xf3\xbc\x7b\x26\xff\x07"
-  "\xa9\x3d\xf0\xfa\x93\xe1\xb4\x29\x41\x47\xeb\xcf\x01\x5d\x97\x84"
-  "\x83\x7d\x23\xcc\x6b\x50\xbe\xde\x05\x3f\xbb\x61\x9e\xb6\xe7\x9e"
-  "\xff\x88\xad\x2f\x3c\x57\xc6\x3a\xb0\x73\x8b\xb8\xfe\x9d\xd7\x5d"
-  "\x38\x8d\xbe\xce\xb4\xc1\xb0\x3f\xab\x24\x0c\x62\x4c\xb2\x4b\x5c"
-  "\xb3\xac\xb5\x37\x5e\xd7\x38\xe0\x33\x3c\x46\xc4\x26\x7e\x71\x3e"
-  "\x9b\x57\x0c\x3e\x2b\xc4\xeb\x1c\x3b\xee\x33\xd7\x7b\x8f\xc6\x67"
-  "\xf3\xc2\x1c\xf7\xd9\xbc\x93\x56\x3e\x13\xe8\x87\x98\x77\x40\xba"
-  "\xcf\xe6\xad\xe0\xfa\x21\xe6\x15\x72\x3e\x0b\x77\x23\x3e\x9b\x17"
-  "\x4a\x7c\xe6\x9a\xd7\x2c\x6b\xfd\x8e\x79\xad\xce\xff\xc6\x79\x53"
-  "\xb3\xda\x36\x2f\xe7\x7c\x16\x11\x67\x48\x87\xdc\x1d\xf2\x72\xc7"
-  "\x7d\xd6\xf9\xda\xa3\xf1\x59\x84\xbb\xe3\x3e\x8b\x58\xc9\xf7\x99"
-  "\x50\xbe\x1c\x21\xfd\x9b\x9d\xca\x08\x2d\x97\x2f\x47\x2c\xe6\x7c"
-  "\x16\x71\x9c\xf8\x2c\xc2\x85\xf8\xac\xc3\x85\x66\x59\x6b\x80\x44"
-  "\x6c\x71\xc0\x67\xf8\x9d\xbe\x9d\x7a\xf6\xa6\x2f\xf8\xac\x10\xaf"
-  "\xfb\xec\xb8\xcf\x3c\xbf\x79\x34\x3e\x7b\xa3\xc8\x71\x9f\xbd\x39"
-  "\xd0\xca\x67\x02\x79\xdd\x9b\x9e\xd2\x7d\xf6\x46\x25\x97\xd7\xbd"
-  "\xa9\xe1\x7c\xf6\x66\x34\xf1\xd9\x1b\x85\xc4\x67\x6e\xa8\x59\xd6"
-  "\x3a\x22\x6f\xb6\xda\xff\x85\x39\xb4\x59\x6d\x9b\xe7\x70\x3e\x8b"
-  "\xac\x32\xa4\x43\x2e\x04\x79\x8e\xe3\x3e\x1b\xb1\xed\xd1\xf8\x2c"
-  "\x72\x85\xe3\x3e\x8b\xbc\xcc\xf7\x99\x50\xfe\x11\x79\x5a\xba\xcf"
-  "\x22\x53\xb8\xfc\x23\xf2\x02\xe7\xb3\xf9\x3e\xc4\x67\x91\x8b\x89"
-  "\xcf\x3a\x0e\x6a\x96\xb5\x16\x49\xa4\xde\x01\x9f\xe1\x77\xb0\x76"
-  "\xea\xd9\x82\x4c\xf0\x59\x21\x5e\x07\xdb\x71\x9f\xcd\x7e\xf9\xd1"
-  "\xf8\x6c\x81\xd6\x71\x9f\x2d\x48\xb5\xf2\x99\x00\x27\x2f\x90\xb1"
-  "\x0e\xf6\x82\x20\x8e\x93\x17\x6c\xe1\x7c\xb6\xa0\x82\xf8\x6c\x81"
-  "\x86\xf8\xac\x53\x58\xb3\xac\xf5\x4c\x16\x88\xae\xff\x65\x8f\x1b"
-  "\xcd\xe3\xf2\x39\xbf\x45\x85\xb6\x1f\x76\x7c\x4b\xe7\xb8\xdf\xa2"
-  "\x26\xb4\xce\x8e\x51\x43\xa5\xfb\xed\x2d\x03\xc7\x8e\x51\x81\x9c"
-  "\xdf\xa2\x52\x88\xdf\xde\xaa\x70\x8e\x1d\xa3\x5a\x9d\xff\x2a\xc4"
-  "\x8e\xb6\x7e\x5b\xe4\xd6\x7e\xf8\x71\x61\xa6\xe3\x7e\x5b\xa4\x68"
-  "\x9d\x1f\x17\xde\x94\xee\xb7\x85\x05\x1c\x3f\x2e\x6c\xe0\xfc\xb6"
-  "\x28\x98\xf8\x6d\x61\x8a\x73\xfc\xb8\x48\x74\xfd\x37\x7b\xfc\x68"
-  "\xeb\xb7\xb7\x8b\xda\x0f\x43\xbe\x1d\xea\xb8\xdf\xde\x3e\xd6\x3a"
-  "\x43\xbe\xbd\x4f\xba\xdf\xde\x5e\xcc\x31\xe4\xdb\xf9\x9c\xdf\xf0"
-  "\x66\xec\xb7\xb7\x83\x9d\x63\xc8\xb7\x4b\xe4\x30\xa4\xad\xdf\x96"
-  "\xc4\xb6\x1f\x8e\x5c\xe2\xe6\xb8\xdf\x96\x2c\x6b\x9d\x23\x97\x48"
-  "\xff\x66\xb1\x72\x89\x0f\xc7\x91\x4b\xa2\x38\xbf\x2d\x61\xbf\xc1"
-  "\xb2\x04\x39\xc7\x91\x4b\x5a\x5d\xff\x43\x88\x23\x6d\xfd\xf6\x8e"
-  "\x6f\xfb\x61\xc9\xa5\x12\xf8\xff\x9d\x81\xad\xb3\xe4\x3b\x32\xf8"
-  "\x7f\x69\x25\xc7\x92\xef\x58\xf0\xff\x3b\x2c\xff\x2f\x2d\x74\x8e"
-  "\x25\xdf\x71\x84\xff\x6d\x58\xd2\xd6\x6f\xd1\xd5\xed\x87\x27\xa3"
-  "\x63\x1d\xf7\x5b\xf4\xd5\xd6\x79\x32\x5a\xc6\x77\xa0\xa2\xd3\x38"
-  "\x9e\x8c\xae\xe0\xfc\xb6\x4c\x4b\xfc\x16\x1d\xed\x1c\x4f\x46\x8b"
-  "\xae\xff\x68\xf6\x9b\x51\x3d\x3c\x80\x16\xe8\x87\x2c\x8d\x0a\x60"
-  "\xd7\x26\x5c\x5e\x68\xf4\x1a\x1e\x20\xf5\xfb\x2e\xe6\x35\xa7\xcf"
-  "\x44\x21\x74\x4d\xb9\x7c\xaa\x73\xeb\x4e\x2f\x57\x38\xbf\xee\x74"
-  "\x4c\xe9\xc3\xfb\xbe\x4b\xcc\x51\xe9\xeb\x4e\xc7\x24\x72\x0c\x1a"
-  "\x73\x8a\xf3\xf5\x72\x66\x7c\x82\xb4\xf5\xa8\x63\x82\x9c\x5b\x8f"
-  "\x7a\xf9\x04\xa2\xaf\x18\x17\xb2\x1e\xf5\xf2\xc0\xb6\xf9\xee\xcb"
-  "\xb2\x7c\xbc\x1e\x35\x9d\xdc\x79\xa3\xbc\xf5\x91\x97\x9f\x72\x40"
-  "\xcf\x85\xb4\x40\x1f\x2d\xa7\xe7\x55\x5b\x40\xcf\x85\x52\xbf\x33"
-  "\xc3\xd7\xf3\xaa\x3e\xce\xe9\x79\xe5\x79\xe7\xf5\xbc\x32\xfb\xe1"
-  "\x7d\x67\x66\xe5\x26\xe9\x7a\x5e\x19\xca\xb1\xf9\xca\x34\x4e\xcf"
-  "\xab\x8a\xa5\xeb\x79\xa5\xda\x39\x3d\xaf\xea\x41\xf4\xbc\xe2\x02"
-  "\xd1\xf3\x2a\x55\xdb\x7c\x7f\x66\x45\x22\xd1\x73\x97\x12\x79\xeb"
-  "\x4f\xaf\x4a\x6b\x5d\xcf\x7e\x01\xb4\x40\xff\x35\xa7\xe7\xd5\x61"
-  "\x46\x2f\xbf\x00\xa9\xdf\xbb\xe1\xeb\x39\xf6\xae\x73\x7a\x8e\xdd"
-  "\xe7\xbc\x9e\x63\x97\x3c\xbc\xef\xdd\xc4\x4e\x97\xae\xe7\x58\x0d"
-  "\x97\xb3\xc4\x46\x72\x7a\x5e\x9d\x29\x5d\xcf\xef\x56\x39\xa7\xe7"
-  "\xd8\x9b\x44\xcf\xef\xe6\x12\x3d\xc7\xea\xda\xe6\x3b\x38\xef\x86"
-  "\x12\x3d\xab\xd4\xf2\xd6\xf7\x5e\x2d\xba\xfe\xb1\x85\x9e\x0b\x69"
-  "\x81\xbe\x7d\x4e\xcf\x71\x5a\xd0\x73\xa1\xd4\xef\xee\xf0\xf5\xbc"
-  "\xd6\xc9\xef\x5c\xac\x7d\x08\xdf\xb9\x58\xeb\xc4\x77\x2e\xac\xbf"
-  "\xbb\xb3\xb6\xbf\x74\x3d\xaf\xd1\x73\xb9\xdc\x5a\x3f\x4e\xcf\x71"
-  "\x51\xd2\xf5\xbc\xa6\xc0\x39\x3d\xaf\x65\xbf\x7f\xb1\x66\x05\xd1"
-  "\xf3\xda\xfc\xb6\xf9\x1e\xcf\x1a\x0d\xd1\x73\xb7\x39\xf2\xd6\x4f"
-  "\x8f\xf3\x6b\x5d\xcf\xfe\x01\xb4\xc0\x7b\x0f\x4e\xcf\xf1\x0d\x46"
-  "\x2f\xff\x00\xa9\xdf\xff\xe1\xeb\x39\x3e\xd5\x39\x3d\xc7\x8f\x71"
-  "\x5e\xcf\xf1\x5d\x1e\xde\xf7\x7f\xd6\xdd\x97\xae\xe7\x75\x45\x5c"
-  "\x8e\x1b\x6f\xf1\xfe\x3f\x21\x40\xba\x9e\xd7\x39\xf9\x5d\xa0\xf8"
-  "\xad\x44\xcf\xeb\xd8\xef\x02\xc5\x27\xb6\xcd\x77\x81\xe2\xf4\x44"
-  "\xcf\xea\x5c\x79\xeb\xd3\x27\xb8\x38\xa0\xe7\x42\x5a\xe0\x9d\x10"
-  "\xa7\xe7\xf5\xc5\xa0\xe7\x42\xa9\xdf\x21\xe2\xeb\x79\x7d\x84\x73"
-  "\x7a\x5e\xef\xe9\xbc\x9e\x13\x2f\x3f\xbc\xef\x10\x25\x9e\x96\xae"
-  "\xe7\x44\xf3\xfb\x3f\x88\xcf\x89\x16\xef\xff\x36\xc8\xf8\x3e\x51"
-  "\xe2\x34\xe7\xf4\xbc\x7e\x26\xd1\x73\xa2\x9a\xe8\x79\x7d\x68\xdb"
-  "\x7c\x9f\x28\xa1\x88\xe8\xb9\x7b\x8d\xbc\xf5\xff\xd7\xb7\x3a\xfe"
-  "\x43\xa8\x7f\xc3\xdc\x2f\xc5\x69\x7a\x63\x96\xf3\x7d\x1c\x1b\xfd"
-  "\x9d\xd3\xf4\x7b\xd7\x9d\xd7\xf4\x7b\x47\x1e\x5e\x1f\xc7\x7b\x32"
-  "\xbe\xf5\xf7\x5e\x24\xd7\xc7\xf1\x5e\x1e\xa7\xe9\x8d\x95\xd2\x35"
-  "\xfd\x9e\xd6\x39\x4d\x6f\x1c\x4c\x34\xbd\xa1\x9a\x68\x7a\xa3\x4f"
-  "\xdb\xf4\x71\x6c\x48\x73\xae\x8f\x63\x63\x9e\x9c\x3e\x0e\x5b\x4d"
-  "\xbf\x1f\xed\x7c\x3f\xc7\xfb\x1d\x9d\xd3\xf4\xe6\x63\xce\x6b\x7a"
-  "\xf3\xa6\x87\xd7\xcf\xb1\x79\x89\x74\x4d\x6f\x0e\xe0\xfa\x39\x36"
-  "\xc7\x71\x9a\x7e\x3f\x5f\xba\xa6\x37\x19\x9c\xd3\xf4\xfb\x0a\xa2"
-  "\xe9\x4d\xc7\x89\xa6\x37\x37\xb4\x4d\x3f\xc7\xa6\x28\xe7\xfa\x39"
-  "\xde\x8f\x93\xd3\xcf\x61\xab\xe9\x6d\x41\xce\xf7\x75\x6c\xbd\xec"
-  "\x9c\xa6\xb7\x6e\x77\x5e\xd3\x5b\x67\x3e\xbc\xbe\x8e\xad\x63\xa4"
-  "\x6b\x7a\xab\x3b\xd7\xd7\xb1\x35\x94\xd3\xf4\xb6\x8d\xd2\x35\xbd"
-  "\xa5\xdc\x39\x4d\x6f\xbd\x48\x34\xbd\x25\x85\x68\x7a\x6b\x49\xdb"
-  "\xf4\x75\x6c\x19\xe5\x5c\x5f\xc7\xb6\x50\x39\x7d\x1d\xb6\x9a\xde"
-  "\xee\xed\x7c\x7f\x47\xd2\x11\xe7\x34\x9d\x14\xe1\xbc\xa6\x93\x06"
-  "\x3f\xbc\xfe\x8e\x24\x2f\xe9\x9a\xfe\x40\xc7\xf5\x77\x24\x59\xcc"
-  "\xff\xdf\x1e\x26\x5d\xd3\x1f\xe4\x3a\xa7\xe9\xa4\x03\x44\xd3\x1f"
-  "\x44\x12\x4d\x27\xe5\xb4\x4d\x7f\xc7\x07\x2a\xe7\xfa\x3b\xb6\xb7"
-  "\xba\xfe\x85\x50\x7f\x87\xad\xa6\x77\xd4\x38\xdf\xe7\xb1\x63\x93"
-  "\x73\x9a\xde\xe1\xef\xbc\xa6\x77\x28\x1e\x5e\x9f\x47\xf2\x4d\xe9"
-  "\x9a\x4e\x2e\xe0\xfa\x3c\x92\x2d\xc6\x3f\xa5\x0c\x92\xae\xe9\xe4"
-  "\x58\xe7\x34\xbd\x63\x1d\xd1\x74\x72\x00\xd1\xf4\x8e\x15\x6d\xd3"
-  "\xe7\xb1\xbd\xca\xb9\x3e\x8f\x1d\x0d\x72\xfa\x3c\x6c\x35\xbd\xb3"
-  "\xc8\xf9\x7e\x8f\x9d\x33\x9d\xd3\xf4\xce\x8e\xce\x6b\x3a\xf5\xe2"
-  "\xc3\xeb\xf7\x48\x3d\x21\x5d\xd3\xa9\x5b\xb8\x7e\x8f\x54\x8b\xf5"
-  "\xef\x3f\x44\xd2\x35\x9d\x3a\xc9\x39\x4d\xef\x9c\x4a\x34\x9d\xea"
-  "\x4e\x34\xbd\x33\xb8\x6d\xfa\x3d\x52\x0a\x9d\xeb\xf7\xd8\x69\x33"
-  "\xfe\x6d\xf9\xfc\xa5\x91\x9a\x77\x16\x2c\x58\x3e\x7f\x85\x66\xf9"
-  "\xe2\x85\x6f\xce\x1f\xdd\xdf\xfc\xff\xd1\xbe\xb1\xfd\x63\x3b\xa1"
-  "\xc8\x25\x11\xf3\x56\x0d\xe3\x76\x2e\x9e\xbf\x14\xfe\xe9\x84\xa2"
-  "\x22\x96\x47\x69\x56\xac\x8e\x9e\xaf\xc1\xff\x5b\xf2\x66\x34\x1c"
-  "\xf2\xce\x0a\x6e\xcb\xab\xf3\x17\x47\xc4\x2e\x5c\xfa\x96\x26\x62"
-  "\xf1\xc2\xb7\x96\x2e\x99\xbf\x74\x85\x26\x66\xfe\xb2\x95\x0b\x63"
-  "\xe6\xe3\xbf\x97\x6b\x16\xbc\x13\x03\x1b\xde\x9c\xbf\x70\xd5\x7c"
-  "\xcd\x1b\x2b\x17\x2c\x98\x1f\xb3\xbc\x13\x9a\xbc\x72\xf1\x8a\x85"
-  "\xd1\x8b\xe7\x6b\x82\x26\x8f\x19\x3c\x6d\xdc\x6b\xd3\x5e\x7a\xa9"
-  "\x13\xb2\xf8\xf6\xb4\x86\x4e\x9b\xe1\x0b\x1a\x72\xb9\xa1\xdc\x3b"
-  "\xf3\x9c\x37\x42\xdb\x41\x9b\x3b\x62\x90\x6a\x6b\x0c\x72\xd9\x72"
-  "\x0f\xb9\x6d\xbf\x87\xdc\x35\x8b\x50\x20\xed\x19\x9d\xb3\xe3\x1e"
-  "\x52\xd3\xdd\x1a\x0b\xe9\xd4\x3c\x1d\xed\x79\x40\xa3\xf7\x4c\x2d"
-  "\x84\x6d\x2a\x3a\x35\xa5\x02\xef\x03\x5f\xb8\xd0\xa9\x07\xb6\x5c"
-  "\x53\xee\xf5\xd6\x7b\xee\xcc\x4b\xb8\x89\x28\xba\x6b\xda\xa0\xcf"
-  "\x4c\x7a\xea\x24\x9e\x81\x04\xb6\x42\xca\xf4\x20\xf8\xf9\xc2\x4f"
-  "\x07\x3f\x3d\x52\x66\x04\xc0\x2f\x1c\x7e\x51\xf0\xbb\x80\x94\x1f"
-  "\xf5\x82\xdf\x24\xf8\xc1\xb6\x8f\x56\xc0\x2f\x11\x7e\x5b\xe0\x57"
-  "\x87\x94\x99\x6a\xf8\xf9\xc0\x6f\x14\x29\x27\x13\xff\x4e\x21\xe5"
-  "\x2e\x77\xf8\x05\x22\xe5\xc7\xb0\xfd\x63\x28\x67\x37\x1c\xf7\x31"
-  "\x9c\xf3\x71\x2e\xfc\x0e\xc2\xaf\x1c\x7e\xf8\xfc\x60\xb2\x6f\x77"
-  "\x11\xfc\x0c\x48\x99\x05\xd7\xca\x82\xeb\x67\x2d\x86\x1f\x5c\x27"
-  "\x2b\x09\x7e\x69\xf0\x2b\x84\x1f\x1c\x93\x05\xf7\x93\x0d\xe7\x64"
-  "\x87\xc2\x0f\xee\x25\xbb\x04\x29\xf7\xc0\xbd\xef\xd9\x88\xe0\x19"
-  "\xc9\x6f\x4f\x09\xf7\x37\xf3\x53\x59\xfd\xdf\xfa\xe7\xeb\xb1\xfe"
-  "\x19\x5d\xd1\xaf\x0d\x50\x6f\xd3\xf7\x19\x37\x20\xa5\x31\x75\x67"
-  "\x5e\xf4\xaf\x91\xe2\x96\x32\x7d\x49\x19\x90\x3f\xad\xca\xd3\x15"
-  "\xad\x69\xc2\xfb\x97\x60\x9b\xd5\x27\xa7\x2f\xd6\xa1\xed\x1a\x5c"
-  "\x3f\xa5\xe9\x33\x7d\x31\x7b\xfe\x41\x9d\xe2\x57\xc7\xf1\xf9\xf4"
-  "\x4e\xff\x8d\x74\x42\xd8\x6e\x3c\x0f\xf7\x06\xb6\x21\xae\x37\x29"
-  "\x7e\x95\xb4\x6a\xc8\x16\x1c\x63\x8a\xd6\x30\xf7\x35\x0e\xea\x5b"
-  "\x57\x38\x3f\x88\x06\x3f\xea\x3d\xc1\xe7\x1b\x90\x0b\xf3\xff\xd4"
-  "\xd4\x42\x3a\x27\xc2\x9b\xc4\x9d\x0c\x26\x7f\x69\xf4\x7a\x25\x1a"
-  "\xef\x6b\xd8\xdf\x4f\x45\xe7\xf6\xcf\x29\x5a\xda\x84\xaa\x94\x19"
-  "\x43\x21\xfe\x51\xf4\x80\x7e\x2a\x53\xc6\x2b\xd1\x85\xa0\x01\x7c"
-  "\xcc\xb1\xf8\x6a\xfc\x6f\x20\x3c\x37\x45\xa7\x4d\x0c\xc0\x7d\x40"
-  "\x45\xf1\x3b\x21\x26\xa7\x8f\x6b\xf4\x8a\x40\x9a\x57\x3c\xe8\x6b"
-  "\xec\x7d\xc1\x71\x15\x70\x1f\xcc\x79\x8d\x9e\x8d\x45\xb8\x6c\x63"
-  "\x4e\x44\x11\x6c\x73\xa1\x41\x7b\x70\x0f\x8a\x3b\x70\x9e\x31\xb5"
-  "\xb1\xb0\xe8\x15\xe6\x9a\xa5\x70\x9f\x54\xc2\x04\x28\xfb\x0f\x11"
-  "\x45\x87\xd7\x34\x50\x34\xbe\x77\x55\x63\x21\x68\xdd\xdd\x98\xfc"
-  "\xa1\xfb\xae\x6e\xc8\x25\x7b\x27\x42\x7b\xbb\x21\xb7\xfa\xe4\x8c"
-  "\x53\x3a\x17\xef\x2c\x12\xf7\xd2\x83\x28\x38\x46\xa7\xcc\xc8\xa1"
-  "\xc1\x1f\xcc\xb5\xd2\xc6\xe5\x8b\x5f\xeb\x23\xaf\x96\x6b\x65\x8c"
-  "\xcb\xc7\xd7\x22\xf6\x62\x6c\x45\xfe\x36\x97\x93\xdb\xcf\xce\x3d"
-  "\x7f\xe4\x89\xcb\xd0\x29\x3f\x72\xa1\x3f\xed\x57\x64\xcc\x98\x54"
-  "\x84\xf7\xe1\xe3\x49\x79\xa9\xd0\xa6\xa1\x3a\x1a\xb6\x19\x59\x1f"
-  "\x18\xb1\x0f\x3a\xe0\xf8\x95\x5e\x85\xaf\x07\xe7\x86\x1a\x37\x68"
-  "\x40\x37\x23\x82\x88\x5f\x3f\xca\x8e\x2d\xa6\x4d\xf0\x33\x0e\x29"
-  "\x46\x8a\xa2\x57\xb0\x4f\x3f\x3a\xae\x19\xff\x14\xd8\xf6\xa3\x13"
-  "\xac\x6d\x83\x1a\xfb\x44\x60\xbb\xa8\xc0\x16\xee\xf4\x66\x75\x09"
-  "\x53\x06\xd8\x1b\xdb\x68\x2f\xd8\x08\xec\xe4\x86\xfd\x5f\x9f\xfc"
-  "\x51\x8d\x95\x9d\x80\x83\x32\x91\x4e\xe1\xe5\x82\xb7\x69\xfa\x22"
-  "\xa2\x19\x8b\xe7\xc6\xfe\x35\xa6\xcf\xf0\xc5\xff\x9f\x3e\x10\xa9"
-  "\x3c\x8a\x11\xa5\x89\xf7\x29\x24\x7e\x9e\x18\xc0\xf9\xf6\xa3\x48"
-  "\x3a\xe3\x85\x2d\x70\xbc\x96\xd3\x55\x66\x9c\x31\x75\xc4\x28\x38"
-  "\x4e\xdf\x90\x1e\x94\x4f\xa7\x8c\x18\x85\xe7\x95\x5f\x53\x66\x32"
-  "\x73\xed\xe8\x0d\x6e\x88\x5c\x67\x44\x60\xfc\x62\x5a\x1f\x7f\x17"
-  "\x7c\xd0\x7d\xa2\xfe\xd8\x2a\x3d\xf8\x22\x28\x1f\xfb\xba\xf0\x41"
-  "\x03\x85\xd7\xfa\xa3\xbb\x7e\xf8\xfc\x1e\xe2\x73\x37\x78\x4e\x84"
-  "\xcb\x85\x7b\x3f\xce\x3d\x4f\x66\x38\xf6\x3b\x5c\x63\x1a\xb9\x36"
-  "\x94\x4b\xc1\x35\x3c\x47\x4c\x83\xe3\xaa\x74\x8a\x93\xc1\x4c\xbd"
-  "\x59\x45\x5f\xd8\xd1\x84\x50\xed\x2a\xda\x10\x62\xb8\x62\x82\xf6"
-  "\x16\xd5\x27\xef\x72\xd1\xa1\xdf\x86\x9b\xed\x42\xea\x52\x4b\x39"
-  "\xcc\x1a\x10\x7a\xa6\x9c\x5d\x83\x84\xca\x81\x6b\xd7\xcd\x33\x68"
-  "\x14\x4d\x0f\xe8\xf2\x1d\x33\xe0\xde\x36\x20\xba\x69\x15\x5d\xb2"
-  "\x2e\x98\x6e\x48\xfe\x06\x01\xf3\x54\x22\x88\xa1\xbd\xba\x2a\x68"
-  "\x7d\xc8\x6a\xe4\xd1\x35\xda\x83\x3e\x53\x5c\x89\xd6\x06\xd3\xd5"
-  "\x65\xb1\x46\x74\xae\xae\x0a\xc5\x5d\x42\xee\x09\xa5\x48\x1d\x17"
-  "\x4c\xeb\x4b\xc2\x2b\x11\xd9\x5e\x8a\x12\xae\x22\x97\xb5\xa7\xe8"
-  "\x86\x29\xd0\xfe\xfe\xb3\x12\x6f\xaf\x82\xed\x46\x94\x50\x4d\x1b"
-  "\xe2\xe7\x22\x77\xfc\x77\xe9\x29\xbc\xfd\x3a\x82\x7a\xea\x12\x12"
-  "\xab\xf7\xd8\x03\xd7\xc4\xe7\xef\x85\x7b\x31\x3d\xa0\x8f\xef\x78"
-  "\x80\xd0\xda\x99\xc8\x3b\x2e\x02\xa9\x42\x00\x03\xca\x0c\x47\x51"
-  "\x88\x91\x86\xf6\xfd\x34\x5a\xb7\x10\xb9\x85\x18\xf0\xbc\xf0\x8b"
-  "\xf0\xcb\x46\x7b\xe1\x58\x78\xb6\x22\xfc\x6c\x6b\x2f\x03\xef\xdc"
-  "\x36\x9f\x73\x82\x3d\xe7\x32\xc2\x36\x6b\xf4\x3c\xa0\x6a\x48\x3d"
-  "\x90\x02\xcf\xde\x80\x6d\x00\xd7\x29\x37\xe1\xf3\x1e\x30\xed\x0e"
-  "\xb6\x81\x62\x9e\x01\xea\x6a\xfa\xd8\x94\x79\xb1\x45\x4c\xb9\x3a"
-  "\xe5\xc7\x7e\x7b\x63\x98\x7b\xe2\x1d\x1b\x62\xa0\x6b\xf5\x5e\x63"
-  "\xa1\xac\x8f\xe7\x84\xc4\xbe\x44\x83\xfe\x14\xa0\x89\xd0\xfa\xe4"
-  "\x8f\xb3\xcc\xf6\xd6\xb5\xc4\x92\x8f\x53\xc0\x17\xa1\xca\x68\xe4"
-  "\x02\xfb\x8f\xeb\x14\xa7\x7c\x2c\xb4\x8b\xe3\x51\x07\xf3\xb1\xec"
-  "\x31\x3a\x9d\xe2\x1f\x8b\x2d\x8e\xc1\x7a\x6d\x39\xa6\x3e\x79\x37"
-  "\xe8\xff\xab\x15\xdc\xfe\x8f\xd4\xb4\x45\x19\x6c\xbb\x6a\x2e\x5b"
-  "\x09\xf1\x75\x8e\xd1\x6b\x22\xb4\xa3\x4d\xa1\x74\xad\xb7\x3b\x4d"
-  "\x81\x6f\x0c\x74\x83\x29\x7d\x44\x0a\xb4\x9d\xee\x65\x86\x3a\x44"
-  "\x8e\xdf\xbd\x9f\x4e\x6d\x0a\x23\x63\x59\x77\x6f\xc7\x65\x02\x63"
-  "\xe9\xa0\x1d\x56\x85\x14\xd3\x0d\x38\x2e\x18\xd3\xa9\xf2\xe4\x18"
-  "\x68\x8b\xd3\x27\xfa\x9a\xbc\xc6\x07\x36\xec\x8b\x50\xe1\x58\x4f"
-  "\x7b\xcd\xf0\xa5\x53\xe0\x5c\xb6\x1c\xb8\xae\xab\x4e\xb9\x3b\xd2"
-  "\x08\xe7\xd3\x69\x23\x52\xc8\x76\x12\xb7\x48\x7c\xd9\x1d\x49\xf7"
-  "\x87\x7d\x29\x43\xc2\x61\x9f\xeb\x35\xe5\x6e\x3d\x6c\x47\xf0\xff"
-  "\xcc\xa2\xf8\x7b\xb8\x8c\xfb\x44\xd3\x43\xe6\xf0\xfe\x4f\x61\x7b"
-  "\x7e\x14\x85\x63\x8f\xe6\x15\x5c\x66\x96\x17\x17\x67\x2c\x62\xb6"
-  "\xd7\x88\x9c\xfa\xe4\x2c\xad\x4e\xf1\x0c\xc3\x96\xf8\xbc\x3a\x26"
-  "\x5e\x41\xdc\xea\x13\xe1\xfd\x55\x30\x42\x5f\x9d\xc2\xf5\x28\x6b"
-  "\x92\x4e\xd1\x67\x0e\x67\xcb\xac\xf9\xf8\x58\x26\x86\xe0\x18\x4a"
-  "\x91\x78\x85\xcf\xa1\x33\x26\xea\x70\x1c\xc4\xf1\x50\xa7\xcc\x0a"
-  "\xc7\xb1\x10\xe2\x44\x30\xdb\xfe\x64\x32\xf1\x64\xe7\xc2\x62\xb8"
-  "\xaf\xc4\x6b\xec\xbd\x58\xde\x9b\x39\xf6\xd1\xa9\x8b\x82\xc9\xb1"
-  "\x23\xc2\xe0\xfa\x25\x3a\x45\x5f\x3f\x4b\xbd\x90\xe7\xca\x1e\x0a"
-  "\x9a\xae\x18\x72\x0a\xfe\x0f\x8c\x74\x4d\x99\x11\x46\x27\x7f\x38"
-  "\x1e\xe2\x8b\x1b\xd6\x29\x8e\x91\x99\x3b\x91\x4b\x43\xea\xa2\x30"
-  "\x63\xea\x22\xd0\x5d\xb6\xda\x1c\x57\xf0\x79\xb8\x2e\x40\x6c\x71"
-  "\x63\x62\x86\xd1\xa0\x64\xea\xbb\x11\x0d\x6a\x89\x23\xb0\xad\xd1"
-  "\x73\x51\x28\xbb\xdd\x85\xb9\x9f\x0d\x4a\x13\x5c\x5b\x61\xbe\xf7"
-  "\x46\xcf\x11\xc1\x50\xee\x62\x9d\xc2\x83\xa7\x67\x7a\xe7\x20\x44"
-  "\xd3\x61\x58\x33\x4a\xb8\xcf\x54\xf8\xf7\x29\x56\x83\x9d\xbf\x2a"
-  "\x46\x28\x08\xa2\x4f\x2d\xf8\x72\x57\x77\x5a\x0f\xe7\x1f\xd4\xa1"
-  "\xc5\x4c\xac\xde\x0a\xff\xc7\xdb\xf1\x31\xb0\xfd\x14\x6c\xaf\x23"
-  "\xe5\x7e\x14\x85\x7d\x63\x55\xee\x4d\x52\x2e\x73\x2f\x9d\x71\x99"
-  "\xf8\x3c\x5c\x66\x76\x06\x5d\x83\xcb\xa9\x4f\xde\xe3\x66\x2e\x7b"
-  "\x3b\x6c\x33\x97\x1f\xb4\xc4\x7c\x8d\x3d\x5a\xd8\x1f\x67\x79\xef"
-  "\x99\x19\x74\x1d\xb9\xaf\x3d\x41\x3a\x94\x58\x8d\xf7\x6d\x81\x6d"
-  "\xf8\x5c\xe2\xff\x3d\x11\x58\x1b\x3a\xf2\x3c\x4a\xa2\x91\x3d\xd1"
-  "\x3a\x94\x10\x6d\xd9\xde\x80\x0f\xba\x90\xf6\x70\x67\x1e\x5b\x5e"
-  "\x9a\xb9\x3c\xae\x2c\x52\x06\x9d\xf2\x76\xa0\x45\x7d\x74\xc7\xe5"
-  "\xc3\xf1\xf0\xfc\x4b\x4f\xb1\xcf\x3f\xad\x8e\xe8\x19\x6c\xbf\xe7"
-  "\x26\xb6\x3d\x6e\xfb\xb0\x9f\x99\x6b\xec\x8b\xf0\xc6\x7e\x07\xff"
-  "\x4f\x33\xb7\x8f\xe0\x9b\xa0\xfa\xe4\xbd\x6e\x5c\x5b\xb2\xa7\x12"
-  "\xfb\x1b\xca\x8a\x85\xf6\x28\x1c\xc7\x23\xf6\x9a\x4b\x70\x9b\x68"
-  "\x7e\x7e\x28\xc7\x05\x58\x64\x01\xd6\x35\x66\x11\xda\x2b\x48\x03"
-  "\xe5\x84\x5a\xb5\xb1\x2e\xec\x71\xbb\xf1\x31\x1f\x76\xa7\xab\xe1"
-  "\x98\x15\xe6\x63\xf0\x7e\xb0\xf3\x6f\x61\xdb\x16\x1d\xfa\x20\x09"
-  "\x6f\x4b\x86\x63\x20\x7f\x13\x9d\x93\x13\xdf\x07\x51\x65\x59\x3a"
-  "\x9c\xaf\xe2\x3a\x3c\xaa\xac\x57\x1d\x2a\xcb\x32\x21\xd3\xa7\x3e"
-  "\x81\x81\xf1\x74\xd1\x0d\x65\x8e\xeb\xb9\x86\x6a\x24\x8d\x31\xf7"
-  "\x96\x33\x7a\x6c\x82\xbc\x2a\x6e\x18\xc2\xfc\x71\x47\xb9\xcf\xbf"
-  "\x4c\x7f\x8f\x89\x67\xf0\x37\xb3\x5e\xe4\x87\x90\x87\xe1\x5c\x0c"
-  "\xf2\xed\xa8\x14\x8a\xe4\x63\x26\x38\x76\x0f\xde\x8e\x73\x35\x68"
-  "\xa7\xf6\x5a\xec\xa3\x3f\xed\x5b\x44\x6c\x97\x73\x9b\x89\xeb\xf8"
-  "\x7e\x0d\xbf\x2b\xc2\xf7\x6c\xca\xed\x5b\x84\x9f\x21\x21\x96\x36"
-  "\x95\x19\xea\x8b\x70\x5b\xa6\x59\x85\xf3\xc8\x9c\x33\x21\xd9\x88"
-  "\x36\xed\xef\x2b\x31\x8f\xcb\x61\xc6\x7f\x42\xae\x7d\x47\xdf\xbf"
-  "\x6f\x51\x82\x11\x51\x3b\xe2\x5d\xdd\xc6\x66\xd1\x45\xb5\x03\x7c"
-  "\x02\xeb\x93\x73\x6a\x4e\xc6\x22\x24\x9d\xbf\x73\x6a\xcc\xcf\xbe"
-  "\x87\x7d\x76\xd8\xc6\x7c\xb3\x71\x48\x66\x22\xf3\xbc\x3a\xe5\x3e"
-  "\xd1\xbe\x3e\x7a\x83\x07\xfd\x55\x96\x01\x2d\xcf\xa2\x9b\x96\x67"
-  "\x43\x2c\xcc\x08\x50\x1d\xde\x53\x81\x63\x77\xa0\xd9\x9e\x8c\xed"
-  "\x0c\x7a\x14\x1d\x8f\x3c\x6e\x29\xf7\x95\x86\xc4\x21\xe6\xbb\x4c"
-  "\x5f\xc2\x71\xd2\xee\x75\x1f\x33\xbe\xf2\x1c\xe4\xee\xd0\x5e\x9b"
-  "\x48\xfb\xb3\xef\xfe\x14\xb6\x3c\xbc\xcf\xec\xbf\x3d\x6c\x4e\x2d"
-  "\xe3\x1a\xa2\xdf\x3f\xb2\xf3\xac\x2a\xe1\x67\xfd\xc3\x31\xf9\xcf"
-  "\xfa\x87\x8d\xb6\xcf\xfa\x87\xab\x0f\xf7\x59\xff\x50\x2d\xe3\x59"
-  "\x35\xc2\xcf\xfa\xc9\x7e\xf9\xcf\xfa\x49\xb4\xed\xb3\x7e\x52\xfa"
-  "\x70\x9f\xf5\x13\xd1\xf1\x1f\x76\x9e\xd5\x57\xf8\x59\x73\x53\xe5"
-  "\x3f\x6b\xee\x1c\xdb\x67\xcd\x3d\xf6\x70\x9f\x35\xb7\x48\xf4\x59"
-  "\x29\x0f\x1a\xc7\x27\x88\x4b\x4d\xf1\x8d\xc0\x6d\x19\x93\xcb\xd7"
-  "\xed\x43\x54\x49\x5d\x03\x3a\xd7\xab\x02\x25\xac\x46\xd4\xf3\xd1"
-  "\x10\xf7\x36\xa0\x51\xf4\xce\xc6\xf2\x73\x59\x35\xb0\xfd\x06\x2a"
-  "\x8d\x6d\x40\x81\x31\x38\xfe\xee\xdf\x54\x16\x29\x35\xfe\xee\x0f"
-  "\x6d\x89\xbf\x86\x61\x6c\xcc\xfd\xf4\xc8\xb9\x9a\x26\x84\x9f\x1f"
-  "\xfe\xce\x6e\x89\xbf\x1b\x88\xbd\xad\xe3\x2f\xb6\x47\x59\x43\x03"
-  "\x2f\xfe\x92\xb9\x59\x9f\x2e\xb4\x8e\xbd\xc9\xb7\x10\x12\x8e\xbd"
-  "\x9f\x8e\xc3\xb1\x77\x0f\xec\x97\x76\xff\x9f\xaa\xcc\xb1\x37\x05"
-  "\xae\x69\x19\x7b\xbf\x8a\xc4\x6d\xf4\xa7\x51\xf2\x62\xef\xa7\x51"
-  "\xe6\xe7\xce\x66\x9f\x1b\x6c\x55\xc2\x8f\xbd\x9f\xe6\x38\xa2\x5b"
-  "\x3a\x63\x98\xfe\x70\xef\x06\x57\x53\x6e\x7f\xa6\x7d\xab\x07\x9b"
-  "\xfc\x75\x4f\x83\xcb\x0d\xe5\xff\x68\x98\x3e\xd4\xfa\x48\x05\x9d"
-  "\xdb\x2f\x2f\x64\x05\x7d\x85\xee\xdf\x1f\xe1\xfe\x51\x9c\xe7\xc3"
-  "\xfe\xe9\xf4\xfe\x7e\x79\xd2\xee\x9b\x94\x09\xed\x5f\x60\x3c\xd4"
-  "\x97\xc3\xab\x1a\x28\xd3\xda\x30\x0f\xf0\x83\x8a\x4e\x7f\xc1\x97"
-  "\xde\xec\x73\xb0\x36\x7d\x52\xce\x69\xed\x75\x84\x8f\xa5\xd7\xbb"
-  "\x04\x3a\x71\xff\x3a\xfb\xf7\x9f\xe7\x25\xe3\xfe\x75\x12\xee\x5f"
-  "\xe7\xd0\xfd\x77\x87\xfb\x6f\x0a\x70\x85\xbc\x90\xfa\xb2\x29\xc0"
-  "\x45\xda\xfd\xe4\x89\x7e\xff\xfc\x21\x5e\xc3\xe1\xf8\x47\x77\x0f"
-  "\xf2\x3d\xbc\x47\x4f\x41\x0c\x60\xda\x70\x5c\xf7\x48\xfc\xab\x86"
-  "\x7c\xf6\x0a\x4d\x62\x92\x5e\x62\x4c\x3a\x20\xba\xfe\xa5\xed\xf5"
-  "\x03\x52\x1e\xc1\xf5\xc5\x9f\xdf\x3a\x26\x7e\x36\x40\x23\x1a\x13"
-  "\x33\x5e\x48\xb1\x8d\x89\x7f\xdc\x25\x3d\x26\xfe\x31\xd2\x36\x26"
-  "\xfe\xe9\x34\x17\x13\xff\x74\x44\x7e\x4c\xfc\xd3\x3a\xc7\x63\xe2"
-  "\x9f\x66\xca\x8b\x89\x7f\xf2\xb1\x1f\x13\xff\x14\x27\x2f\x26\xfe"
-  "\x29\xce\x36\x26\xfe\x51\xc7\x8f\x89\x7f\x12\xfd\xd6\x19\x9d\xf2"
-  "\xab\x62\x68\xa3\xdd\x6f\x29\x0f\x6e\x34\x6c\x40\xc8\x94\x92\x51"
-  "\x0c\xed\x6c\x3d\x9d\xfa\xab\x62\x13\xe5\x87\xe3\x4a\x60\x7d\x7d"
-  "\x94\x9b\xe9\x5d\xad\x3b\xdd\x6d\x48\x27\xba\xd9\x1b\xf7\x27\xfa"
-  "\xc0\xfd\x7b\xd0\xf5\xda\xae\xf4\xbb\xda\x6e\x59\x0f\x90\x1a\x7e"
-  "\xde\x59\x6c\x7b\x0c\x7f\xfb\xd2\xef\x7a\x77\x4a\x5e\x85\x06\x79"
-  "\xd4\x21\x37\xb8\x87\x30\x8f\xf5\x2a\x1c\x83\xd4\xf8\x6f\x7a\xc3"
-  "\x5f\xb4\x7b\x1f\x20\x17\x8f\x58\xf0\x8d\x27\x5c\x2f\xd6\x83\xa6"
-  "\x97\x6b\xd1\xde\x18\xe4\x66\xa2\x90\xf7\x1e\x8a\xce\x37\xd4\x6b"
-  "\x29\xa3\x7a\x62\x28\xf1\xcf\xa1\x00\x26\xf7\x4a\x9b\xd8\xcb\xd4"
-  "\x7d\xa2\x8b\x31\x21\x4a\x49\xaf\x0d\x53\xe2\x7b\x35\xa6\x4d\x44"
-  "\x74\x06\xfc\x12\xa2\xba\x62\x86\xde\xbb\x0a\xae\x5d\xef\xdd\x69"
-  "\x07\x5c\x7b\xcf\x2a\xe4\x93\xfd\x00\x69\xe9\x5a\x2d\x05\xfe\x0f"
-  "\xc3\xdf\x37\x05\x1b\x85\x99\xa8\xbf\x68\x61\x9f\x0b\x8e\x89\x34"
-  "\xbe\xbe\x01\xae\xdf\xac\xc5\x7d\x59\xa0\x6d\xe4\xbd\x17\xae\x6f"
-  "\x7c\x57\x2b\xb1\xbe\x1c\x62\xc6\x7f\x9b\xef\xcb\x34\xe8\x79\x0d"
-  "\xfd\x19\xfc\xf0\x7d\x81\x0d\xf7\x62\x9b\x3c\xff\xbc\x0f\xbe\xb7"
-  "\xed\x0f\xd0\x20\xb8\x4f\x1f\xb8\x07\x2d\x5c\x17\xaf\x0d\x13\xf6"
-  "\xfa\x32\x15\xd6\x28\xef\xde\x8c\xa9\xec\xbd\xfd\x04\xf7\x76\x87"
-  "\xbb\x37\x7c\x2d\x6c\x1f\xb1\xf7\xae\x21\xeb\x7a\xe3\xba\xf9\xa3"
-  "\x47\xec\x53\xc1\xf8\x1d\x6c\xed\xda\x28\x89\x5a\x3d\x54\x2e\xa6"
-  "\x97\x1d\x9f\xa1\x5e\xb4\x2a\xa5\x78\xca\xa6\x2b\x34\xee\x2b\xdc"
-  "\xf4\x19\x1a\x54\x06\xf5\xfa\x5c\xc3\x6d\x44\x7b\xa6\x14\x9f\xd6"
-  "\xd6\x48\xbc\xd6\x67\xa2\xf3\xdf\xb7\x6d\xa0\xcb\x4d\xea\x89\x81"
-  "\xb4\x7a\x52\xe6\x8e\x0d\x74\x6c\xb3\x4f\x5f\x5d\x93\x4f\xbf\xfc"
-  "\x79\x06\x15\xe8\x9a\x8e\xd5\xc4\x20\xcd\x0d\x65\xc1\xfa\xb3\x17"
-  "\x20\x2f\x9d\x85\xdc\xae\x29\x0b\x0a\x13\x2e\xe1\xf7\x53\x9f\x95"
-  "\xf0\xdf\x4f\x7d\xa6\x47\xca\xfc\x70\xa4\x3c\x12\x8d\x94\x9f\xa7"
-  "\x21\x38\x8e\xff\xfb\x73\x3e\x29\x2b\x7f\x74\xc8\x81\xde\x28\xde"
-  "\x40\xff\x48\xa7\x34\xbb\x25\x53\x74\x43\xc8\x40\x85\xae\x68\x15"
-  "\x7e\x6f\x93\xef\x0f\x36\xfd\x2f\xb4\xb5\x1e\xf0\xb7\x02\x7c\x8a"
-  "\xa2\x63\xd0\x2f\x6e\x29\xf3\x11\xae\x37\x1e\x75\x4f\x05\x1b\x13"
-  "\xc2\x90\x41\x13\xa1\x6a\x4e\x9b\xe8\x6b\x4c\x1b\x91\x62\x52\x65"
-  "\x14\xe3\xbe\x5e\xfc\xbe\x15\xea\x46\xd8\x3c\xa3\x1b\xae\x8f\x61"
-  "\x45\x6f\x9c\x45\x37\x56\x20\x2a\xe1\x3e\xea\x02\xda\x6c\xa9\x57"
-  "\x93\x6b\x3c\x1a\xd6\xd5\xd0\x26\x5c\xb7\x70\xdf\x2a\xec\xeb\x1a"
-  "\x7f\x1f\xf2\x7b\x7d\x35\xca\x8a\x41\x6a\xe3\xf2\xa8\x6e\xfa\xda"
-  "\xa8\x5f\xec\x36\x21\x75\xd7\x3a\xa4\xca\xba\x07\x9a\x5a\x0e\x7a"
-  "\xba\x07\xf5\x4c\x4f\xea\x19\x9e\xdf\xbf\x07\xd7\xb1\x6d\xdf\x4e"
-  "\xda\x7b\x8f\xd4\x31\x46\x47\xb8\x8e\xbd\x03\x3a\x5a\x8a\xdb\x0f"
-  "\xd0\xd1\x06\xa8\x63\x50\x2f\xe8\xe4\x43\xf9\x59\x1b\x68\xdc\xf7"
-  "\x4b\xed\xbd\xf5\x14\xde\xa7\x70\x1d\x48\x69\xce\x86\x36\x20\xae"
-  "\xaf\xa3\xe0\x58\x53\xff\x7e\xf9\x9a\x57\xe9\x9f\xae\x29\xf3\x07"
-  "\xc1\x76\x37\xcd\x8c\x67\x55\x60\x6f\x76\xee\x51\x41\x21\xee\xcf"
-  "\xd4\x81\x2d\xb0\x5d\x34\xaf\xa2\x67\xaf\x29\x0f\x2b\xb0\x1d\xdf"
-  "\xcd\x43\xca\xe8\xdf\xd2\x55\x60\x33\xa6\x6c\x9d\xf2\x30\xe3\x13"
-  "\xfc\x4e\xff\x9f\xcc\xfb\x32\x72\x8e\x11\xec\x66\x50\x35\x85\x81"
-  "\xbf\xc3\x8b\x16\x35\x31\x71\x08\xdb\xf1\xc6\x62\x44\xcd\xab\x01"
-  "\x5b\x19\xc1\x56\xf5\x5a\x77\x88\x47\xa1\x38\x1e\xd1\x29\x43\x5c"
-  "\xe2\x74\xb4\x29\x24\x52\x49\xc7\x2f\x43\x6e\xb8\x8f\xfb\xf5\x68"
-  "\x44\xaf\xbb\x0d\xf6\xaa\xab\x40\x10\x97\xba\x42\xcc\xea\x96\xbd"
-  "\x0a\xa9\xb1\xbd\xba\xd4\x00\xab\xec\xdc\x59\xf4\x59\x7c\xb1\xab"
-  "\x11\xf4\x8b\xe3\x93\xc7\x7a\x45\x47\xa8\x67\x5d\x93\x70\x7d\x84"
-  "\xfa\xe9\xb1\x9e\x89\x97\x61\x59\x50\x0f\x0d\xef\x6a\xfb\x36\xbf"
-  "\xab\xd5\xc0\xaf\xb7\x39\x86\x99\xe3\x07\x9d\xfc\x99\x37\x8e\x5f"
-  "\x65\xb1\x3a\x64\x00\xdb\x76\xc5\x6d\xdd\xbb\xda\x5e\x8c\x8d\xdf"
-  "\xd2\xa2\x21\x0d\x48\x01\xf7\xa4\x82\xfb\x45\x7b\x17\x20\xb7\xd2"
-  "\xa8\x6b\xc8\x08\x75\xc3\x6c\xf7\xc9\x0b\x35\x08\xca\xa5\x4e\x6b"
-  "\x2f\x22\xd6\x66\x0a\x71\xdd\x7d\xbe\x9d\xd3\xdd\xe7\xdb\xb1\xed"
-  "\x88\xee\x3e\x4f\xfa\xbf\xa8\xbb\x7f\x86\x31\xba\x53\x36\xf7\x67"
-  "\xf4\xe4\x56\x66\xf8\x1c\x6c\xf4\x79\x2c\xd6\x08\xd6\xcc\x99\x3f"
-  "\x62\xcd\xfc\x39\xa7\xbd\x6a\xa6\xb1\x5e\xab\x81\xdf\x23\xd1\x0c"
-  "\x94\xcb\x68\x06\xdb\xea\x9f\x61\x4d\xc8\x6c\x23\xa6\xae\xa6\xa4"
-  "\x14\x6b\x12\xd0\x4b\x50\x57\x0b\x3d\xd6\xf7\x46\xa5\x8c\x9d\x0a"
-  "\x0a\x35\x33\x68\xd3\x35\xe5\x9f\x2f\x25\x9c\x47\xaa\xa6\x0d\x34"
-  "\x5d\x66\x38\x84\x4c\xea\xf1\x81\xb8\xaf\xdd\x94\x46\x95\x43\xce"
-  "\x5a\x48\xa7\x1e\xd0\xe0\x77\xc1\x1e\xd1\xb8\x0f\x3e\xb5\x10\xbf"
-  "\xe3\x33\xa5\xa6\x54\xd0\x9e\x07\xb6\xe0\xf7\x0c\xa6\xd4\xe8\x1c"
-  "\x93\x67\x9e\xae\x3e\xb9\x40\xa3\x43\x17\xf2\x99\xbe\xf0\xb4\x89"
-  "\xb8\xef\x15\xc7\xdf\x09\xe4\x9d\x18\x7e\xa7\x58\x10\x68\x7e\xa7"
-  "\x8d\x63\x02\xfb\x9e\x81\x7d\x0f\x51\x80\x7d\xd8\x09\xbf\x87\x60"
-  "\x63\xca\x50\xf3\x7b\x08\xf3\xff\xf1\x7e\x38\xcf\x8f\x79\xc7\xca"
-  "\x9d\x97\xcf\x1e\xc7\x9e\xf7\xd9\x51\x1c\xeb\xb9\xf3\xc8\xff\xa1"
-  "\x1d\xc9\x6f\xa6\x90\x9b\x20\xe3\xa8\x67\xf8\x42\xfd\x81\xdc\xe8"
-  "\x2f\x43\xe1\x5f\xea\x86\xf2\xe8\x54\xf8\x57\x09\xff\x32\xfd\x98"
-  "\xd2\xda\xab\x82\x1a\xf2\x2e\x68\xd2\x29\xf6\xbe\x6f\x33\x75\xf2"
-  "\xd7\xa8\xcb\x2d\xf6\xef\xfa\xe4\xa3\xc1\xe6\x77\xf3\x2d\xc7\x73"
-  "\xfe\xa9\xc2\xd7\x06\x1f\xb9\x90\xf1\x02\xe4\xff\x78\x2c\x0e\x5b"
-  "\x1e\xf3\x7f\x93\x4f\xff\x9c\xa2\xf8\x6b\xa8\x46\x79\xb4\xa0\x0c"
-  "\xda\x70\x53\xc6\xa4\x53\xf8\x1d\x19\xae\x57\xe6\xeb\x42\x5d\x74"
-  "\x2b\x5a\xc3\x1c\x93\xce\x70\x6e\xda\xd8\x1c\x7a\x67\x53\x39\xce"
-  "\x05\xeb\xe9\xa8\xdf\xb2\xff\x8e\xc6\xf5\x89\xf4\x9b\xfc\x45\x41"
-  "\x83\x6f\xf1\xf7\xd9\x5b\xc6\x27\xe1\xef\xa6\x27\xba\x68\x4e\xc6"
-  "\x91\xb6\xd2\x7c\xbf\xf8\xdb\xea\x78\xfc\xcf\xb3\x89\x28\xb1\x5e"
-  "\xe0\xdb\xea\xdc\x38\xa1\xa3\x35\xa6\xf4\xb1\x39\xf5\xc9\x7f\x19"
-  "\x05\x3e\x88\xb3\x7c\x66\x21\x5f\xe8\x94\x7f\x09\x13\xdb\x27\xcd"
-  "\x0f\x7f\x59\x21\x56\xce\x38\xad\x91\x96\x58\x96\x78\xff\x8f\x4f"
-  "\xdf\xc0\x90\x3c\x63\x91\xa9\x39\xcc\xe3\x74\xdc\x6d\x89\x6c\xf3"
-  "\x57\x6f\xb1\x72\x8d\x69\xe3\xc3\x9b\x07\xf4\x0d\x04\xdf\xb8\x1b"
-  "\xdf\x09\xfb\xdd\xb9\x3c\x03\x3a\xb0\xb4\x9a\xc2\xf1\xf0\xe0\xad"
-  "\x7c\x2a\x64\x20\xcb\x70\x55\xf8\x9d\x2b\x6d\xc2\x2c\x97\x7c\x07"
-  "\xf9\x34\x25\x84\x79\x34\x35\x87\xa1\x0f\xee\xa0\x51\xa6\xb7\xbc"
-  "\x3b\x25\x2d\x40\x2e\x8d\x10\x0b\x1b\x7f\x8c\xf2\xf8\x67\x65\x35"
-  "\xfa\x12\xce\x3d\x57\xa7\x43\x7b\xe0\x58\xfa\xc7\xb0\xae\x40\xcd"
-  "\x0d\x25\xe1\x9f\xa3\x10\xad\xb1\x28\xfe\x2a\xea\x02\x31\x51\x55"
-  "\x16\xbb\x1f\x72\xa8\xdb\xc8\x75\x35\xa5\x29\x33\x5c\x47\xdb\x17"
-  "\x40\x2c\x85\xd8\x99\x30\x1d\xda\x0c\xd0\xc4\x6e\xcb\x36\x63\xd1"
-  "\xc7\x5c\x9b\xf1\x13\xb4\x19\x3b\xa1\xcd\x48\xf0\x46\xe7\xa2\x8b"
-  "\x10\xc4\xb0\xa7\xa6\x44\x7b\x34\xc4\x47\x43\xdb\xb1\x1a\xda\x8e"
-  "\xd8\xeb\x88\x69\x37\x6a\xaa\x11\xc4\xfc\xae\xd9\x4b\x91\xba\xe9"
-  "\x27\x68\x3b\x7e\x82\xb6\x23\x9e\xb4\x1d\xbb\xee\x40\xdb\xf1\x0e"
-  "\xe4\x06\x4b\xa1\xed\xa8\x11\x68\x3b\xee\x08\xe7\x05\xe6\x38\xd8"
-  "\xf8\x93\x96\xda\x05\xed\xc6\x9a\x8b\x88\xda\x35\xe3\x29\x89\x9a"
-  "\x29\x14\x9d\xff\x43\x67\x4c\xfa\xc4\x44\x87\x21\x6c\xf7\x35\x0d"
-  "\xd0\x0e\x83\x5f\xca\xb4\x06\xe4\x71\xe1\xa9\xe0\x46\xd8\xde\xdc"
-  "\x7d\xb8\x2a\xef\x3b\x3d\x45\xa7\xbd\xe0\xdb\x08\x7e\x5b\xb3\x12"
-  "\x51\xcd\xe0\xc3\x83\xaf\xa6\x50\x38\x4f\x34\xa5\x0f\x9f\x46\x72"
-  "\xd2\xbf\x9d\xc4\x7d\x22\x1e\x3a\xe2\x37\x03\x1d\xe6\x41\xbf\x19"
-  "\xd6\x65\xfb\x1b\xc8\xc5\xf8\x83\x77\x27\xd3\x9b\xde\x6e\xf1\x17"
-  "\x91\x4a\xff\x66\x14\xd8\xeb\x36\xfa\xf2\x9b\x14\x6a\xef\x2c\xa4"
-  "\xc1\x6b\x31\xd2\x9b\xcb\x54\x7b\x5f\x47\x01\x7b\xff\x83\xfc\xf6"
-  "\xcc\x42\x83\xb2\xbf\xc3\x6b\xb6\x83\x0f\xab\xe9\x86\xd2\xa8\xbf"
-  "\xa1\xbd\xdf\xa1\x40\x3a\x63\x84\x8a\xf6\x1a\x1f\x0e\x7f\x07\xa4"
-  "\xcc\x82\xfc\x01\xf6\x87\x68\x1b\x8b\xca\x62\x4b\x51\xd2\x35\x84"
-  "\xe2\x6f\xb2\x3e\x6e\xf1\xef\x65\x64\xa0\x20\x7e\x60\x26\x98\x4c"
-  "\xfc\x8b\xdf\x83\xe1\x9c\xa3\xc5\xc7\x0b\xfe\xc1\xe7\x02\xd6\xc7"
-  "\xa5\x35\xe5\x08\xda\xc0\xa7\x5a\xf8\x80\xf1\xf1\x65\x64\x66\x03"
-  "\xf0\x4d\x57\x60\x01\x75\x63\xad\x15\x1f\xc4\xc8\xe4\x03\x36\xbf"
-  "\x31\x2c\xff\x7f\xed\x5d\x0d\x60\x54\xc5\xb5\x9e\xbd\xb9\x24\x4b"
-  "\x48\xb2\x9b\xb0\x09\xcb\xff\x0a\xa1\x8d\x96\x9f\x00\xbb\x0a\x3e"
-  "\xec\x8b\xd6\x9f\xf8\x8a\x8a\x7d\xd4\x46\x45\x1b\x34\x60\x90\xbf"
-  "\x08\x11\x22\x20\x09\x18\x7d\x68\x31\x59\x43\xa0\xa9\x04\x12\x2b"
-  "\xed\xc3\xf7\xa0\x4d\x5b\xb4\xb1\x0d\xba\x4a\xb4\x11\x63\x12\x30"
-  "\x2a\x5a\x6c\x57\x8a\x18\x21\xe0\x42\x56\x13\xf2\xb3\xd3\x73\x66"
-  "\xe6\x66\xef\xde\xdd\x90\xcd\x82\x16\x53\x2e\xdc\xdc\xbd\x33\x67"
-  "\xce\x9c\x99\xef\x9c\x33\x67\x66\xef\xde\x49\x92\x4a\x25\x4a\x72"
-  "\xdf\x21\x52\x89\xa7\xaf\x18\xff\x69\x23\xf3\xb7\x3b\xc6\xee\xe4"
-  "\xcf\xe5\xbc\x7c\x03\x62\xe1\x0c\x7b\xf9\xfa\x1f\x27\xe9\x48\x88"
-  "\xd8\xdb\x7b\xc1\xbe\x91\x63\x5f\xb5\x37\x44\xec\xed\x80\x7d\x66"
-  "\x68\xd8\x7f\xd9\x47\xec\xd9\x3b\x2d\xfb\x29\xf6\x55\x1b\x7c\xb1"
-  "\xff\xf3\xb5\x1c\xfb\x3f\xa7\x84\x8e\xbd\xb5\x17\xbb\xb7\x0a\xbb"
-  "\x7f\xe5\xe5\xd0\xb0\xb7\xa2\xdd\x3b\x42\xc3\xfe\x64\x1f\xb1\x67"
-  "\xef\xc5\xec\xa7\xd8\xbf\x92\xef\x8b\xfd\xde\x6b\x38\xf6\x7b\x67"
-  "\x9c\x07\xf6\xbd\xd8\xbd\x55\xd8\xbd\xe3\xc5\x10\xb1\x07\xbb\x6f"
-  "\x30\x87\x86\xfd\xc7\x7d\xc4\x9e\xbd\x5b\xb3\x9f\x62\xef\xc8\xf3"
-  "\xc5\xfe\xd5\xe9\x1c\xfb\x57\xa7\x85\x8e\xbd\xad\x17\xbb\xb7\x09"
-  "\xbb\x7f\xfd\x77\xa1\x61\x6f\x03\xbb\x6f\xc8\x0a\x0d\xfb\xbd\x7d"
-  "\xc4\x9e\xbd\x9f\xb3\x9f\x62\xff\xfa\x1a\x5f\xec\x5f\xb3\x71\xec"
-  "\x5f\xb3\x9e\x07\xf6\xbd\xd8\xbd\x4d\xd8\x7d\xf5\xee\x10\xb1\x47"
-  "\xbb\xaf\x09\x0d\xfb\x47\xfb\x88\x3d\x7b\xc7\x67\x3f\xc5\xbe\x3a"
-  "\xc7\x17\xfb\x7d\x93\x39\xf6\xfb\x92\x83\xc1\x7e\xb5\x1a\xfb\xc3"
-  "\x11\xa9\x30\xb7\x62\x71\xfe\x0b\x77\x09\xec\x7f\x0d\xd8\x43\xfb"
-  "\x77\xdd\x51\xa2\x89\xf1\xdf\x7c\x8e\xe1\x9e\x0e\xb8\x3f\x02\xb8"
-  "\xc3\xdc\x50\xc1\x1c\x30\x8a\x46\xdc\x11\xf3\xb5\x1f\x13\xe3\xab"
-  "\x50\x16\xf1\x41\x8c\x01\x47\x0b\xc3\x39\xbc\xde\x48\x75\xb2\x19"
-  "\xf1\xc4\xb8\x1f\x31\xef\x2d\xb6\x47\x9d\xe8\x15\xf3\xdb\xbf\x9e"
-  "\xf8\xbe\x5d\xbb\xfe\x77\xa1\x30\x3f\x00\x73\xb8\xb5\x7d\xc5\xfc"
-  "\xcd\x45\xbe\x98\xbf\x71\x39\xe2\xe0\x0c\x7b\x23\x29\x74\xcc\xad"
-  "\xf6\x9e\x31\x57\xc6\xf8\x9a\xcd\xe7\x87\x79\x83\xd9\x8b\xb9\xd5"
-  "\x7e\x6e\xcc\x3f\x0e\x01\xf3\x0b\x3b\xbe\x5f\x5c\x98\xd7\xa4\xfb"
-  "\x62\xfe\x97\x91\x1c\xf3\xbf\x8c\xe8\x09\x73\x0f\xf8\x6b\x5c\x53"
-  "\xc7\xdf\x1c\x76\xb5\xa6\xdd\xd4\x01\xb8\xe2\x6f\x0f\x71\xad\x77"
-  "\xf7\x92\x4a\xa9\x03\x70\x2f\x5c\x41\x12\x37\xae\x20\x33\x0c\x4d"
-  "\xdc\x7f\xb7\x83\xff\x7e\xf2\x2b\x22\x7b\x16\x9a\x23\x37\x1e\x27"
-  "\x72\x3b\xf4\x71\xfb\xc2\x4c\x43\x6d\xba\x8b\xbc\x7a\xaa\x52\xc2"
-  "\xb5\x5b\xfc\xde\x8e\x9e\x48\x8b\xb9\x39\x83\xb6\xd5\x1e\x2d\xe2"
-  "\xeb\x2a\x9f\x2a\xeb\x2a\xbb\x7d\xd6\x55\x7e\x76\x5c\xac\xab\xdc"
-  "\xc9\x31\x2a\x55\xe3\x73\xef\x2f\x7b\x58\x57\xa9\xe9\x75\x5d\x85"
-  "\xad\xa7\x9c\x22\xa6\x8e\xa5\x99\x71\xbf\x10\xeb\x2a\xcf\x2e\x39"
-  "\xbf\x75\x95\xf6\xa5\x49\xd2\xb3\x80\xcf\xea\x3b\x01\x9f\x8f\xfa"
-  "\x8a\xcf\x7e\x12\xec\xba\x8a\x32\xc6\x2a\xe3\x2a\xda\x1c\x8e\xad"
-  "\x6d\xc5\x53\x4d\xda\xb5\x14\xb4\xb7\x53\x61\xb5\xb1\xe8\x93\x43"
-  "\x5b\x4f\x39\x60\xf9\xb6\xad\xa7\xa0\xcd\x29\xe3\xec\xc5\x31\xc6"
-  "\xbe\x7d\xd8\xd7\xf6\xf6\x6f\xe6\x63\xec\xfe\xe2\x60\xe3\xab\x73"
-  "\x60\x5e\xac\x5d\x43\xe1\x98\xd7\x0d\xc0\x35\x97\xd0\xd6\x51\x0e"
-  "\x64\x7f\xdb\xd6\x51\x2e\x3e\xcc\xdf\x69\xf0\xc5\xbc\xf6\x49\x8e"
-  "\x79\xed\x86\xf3\xc7\xdc\x6a\xd2\xae\x9d\x70\xcc\xeb\xcf\xe2\x5a"
-  "\x4b\x68\xeb\x27\x07\x42\x8c\xa5\xff\x75\xeb\x27\x17\x1f\xe6\xf5"
-  "\xd5\xbe\x98\xd7\x3d\xca\x31\xaf\x5b\x73\x01\x30\x2f\xd6\xae\x99"
-  "\x70\xcc\x0f\x9c\xc4\xd8\x2b\xb4\x75\x93\x83\x23\xbe\x6d\xeb\x26"
-  "\x17\x1f\xe6\x07\x2a\x7d\x31\x6f\x78\x88\x63\xde\x90\x75\xfe\x98"
-  "\xdb\x4c\xda\xb5\x12\x8e\xf9\xbb\x9f\xe0\xda\x4a\x68\xeb\x25\x07"
-  "\xbf\x75\xeb\x25\x17\x1f\xe6\xef\xee\xf2\xc5\xfc\xe0\x3c\x8e\xf9"
-  "\xc1\x8c\x0b\x80\x79\xb1\x76\x8d\x84\x63\xfe\xde\x7b\xb8\xa6\x12"
-  "\xda\x3a\xc9\xc1\xea\x6f\xdb\x3a\xc9\xc5\x87\xf9\x7b\xe5\xbe\x98"
-  "\x37\xde\xc9\x31\x6f\x4c\x0b\x76\xce\xac\xcc\x95\x95\xf9\x31\x9b"
-  "\x2b\x9b\x20\x66\xd7\xac\x8d\x70\xbc\x3f\x78\x8d\xc5\xec\x21\xcf"
-  "\x95\x0f\x58\xbe\x2d\xeb\x23\x0a\xd6\x38\x5f\xbe\x38\xe6\xca\x1f"
-  "\x68\xbe\xff\x7c\xff\x66\x3e\x57\x7e\x3f\xb5\x27\xac\x03\x3d\x8b"
-  "\x50\x07\x73\x4d\xe5\x59\x84\x27\x57\x00\x8e\xa0\x07\xf8\x2c\x02"
-  "\x3e\x93\x10\xe8\x79\x04\x7c\x0e\x41\x79\x26\x41\xfd\x3c\x42\xaa"
-  "\x93\xb6\xe1\x33\x09\x38\x4f\xae\x4d\x7f\x8a\x28\xcf\x26\xe0\x33"
-  "\x08\xb9\x9f\x90\x68\xc4\x08\x9f\x3f\xc0\xf9\xf2\xd7\xfd\x0c\x42"
-  "\x89\xe7\x62\x78\x06\xe1\xc3\xf1\xbd\xcd\x95\x6f\x79\x61\x14\x01"
-  "\x7d\xeb\x5e\xa7\xea\xd8\x32\xd5\x88\x36\x87\x18\x19\x9a\xb9\x1d"
-  "\xee\xbe\xa3\x42\xaa\xcf\xa9\x24\x4f\xae\x22\x46\x65\xfd\x02\x6d"
-  "\x10\xfc\xb2\xa1\x13\xf0\xdc\xf8\x20\x5f\xc7\xf0\x9c\x48\x8b\x76"
-  "\x2d\xcc\x34\xe0\x6f\xf7\x5f\x7d\xbf\x42\xc2\xb5\xc7\xb2\xf9\xc4"
-  "\xba\xf5\x18\x99\x56\xe7\xfe\x98\x30\x9b\xda\x3c\x35\x15\xca\x26"
-  "\x77\x6c\xbe\x31\xdd\x13\x3f\xd5\xea\x8a\x9f\x3a\x0d\x71\xdb\x78"
-  "\x9c\x10\xb4\x2f\xc4\xad\x3e\x67\x5b\x37\x5e\x0c\x2b\x49\xac\x6d"
-  "\xf4\x68\x53\x07\x43\xc6\xac\xf4\x14\x60\xb6\xd4\x17\xb3\x6d\xa1"
-  "\xae\x6f\x28\xcf\x73\x2f\x4d\x92\xb6\x81\x4d\xad\xba\x1d\x30\xfb"
-  "\x51\x5f\x31\xfb\xc8\x19\x02\x66\xf6\x20\x31\x6b\x0c\x02\xb3\xcc"
-  "\x00\x98\xd5\x40\xd9\x0a\x81\xd9\x1e\xc0\xac\xd2\x8b\xd9\x97\x41"
-  "\x62\xa6\x9d\xc3\xf6\x27\xcc\x0e\xf7\xb8\xff\x4b\xcf\x98\x59\x83"
-  "\xb4\x33\x6b\x30\x76\xe6\xf0\xc7\xcc\x0a\x76\x66\x15\x76\x66\x05"
-  "\x3b\xb3\xaa\xec\xec\x64\x90\x98\x69\xe7\xa0\xfd\x09\xb3\xbf\xa5"
-  "\x86\x80\x59\x90\x76\x66\x0d\xc2\xce\x1a\xcc\x01\x30\x03\x3b\xb3"
-  "\x0a\x3b\xb3\x82\x9d\x59\x55\x76\xf6\x71\x90\x98\x69\xe7\x90\xfd"
-  "\x09\xb3\xbf\xf7\xfc\xfb\xef\x1e\x31\xb3\x05\x69\x67\xb6\x20\xec"
-  "\xac\x21\xcb\x1f\x33\x1b\xd8\x99\x4d\xd8\x99\x0d\xec\xcc\xa6\xb2"
-  "\xb3\xbd\x41\x62\xa6\x9d\x03\xf6\x27\xcc\x3e\xa9\x08\x01\xb3\x20"
-  "\xed\xcc\x16\x8c\x9d\xd5\x04\xc0\x0c\xec\xcc\x26\xec\xcc\x06\x76"
-  "\x66\x53\xd9\xd9\xa3\x41\x62\xa6\x9d\xc3\xf5\x27\xcc\xfe\xd1\xe3"
-  "\xfe\x4f\x3d\x61\xc6\xf0\x82\xd8\x31\x20\x66\xed\xbe\x71\x63\x27"
-  "\xc4\xf1\xf8\x9d\x57\x40\xbc\x9e\xa8\x37\xd2\x75\xb2\x19\xb1\xc2"
-  "\x78\x10\xf1\xaa\xcf\x79\x83\x04\x8a\x1b\xf1\x7b\x31\xc0\x9d\xe0"
-  "\x77\x63\xb9\x9f\xf6\x21\x5e\xbc\xaf\x27\xac\x7a\xff\x3e\xac\x74"
-  "\x89\x17\x2b\xe5\xfb\xb0\x0b\x8a\xd5\xc1\xbe\x62\xf5\xa9\x31\x34"
-  "\xac\xac\xf6\xde\xb1\xb2\x36\x9e\x1b\xab\x06\xb3\x17\xab\x8f\x55"
-  "\x58\xf9\x8f\x63\xc1\x63\xa5\x19\xbf\xfa\x15\x56\xc7\xaa\x7a\xc2"
-  "\xaa\xd3\x74\x63\x3a\xfe\xe6\xfd\x56\x98\xfb\xd2\xfb\xd3\x6e\x2a"
-  "\x38\x42\x12\x9f\x3a\x42\x66\xe0\xef\x9b\x77\xaf\x6a\x93\xa0\x8d"
-  "\x9f\xed\x6f\x6c\x22\x1d\x27\xcc\x91\xf8\xfb\x19\xe6\x27\x17\x9a"
-  "\xf5\xf5\xe9\x2e\xe6\x13\x9f\x06\x8c\xea\xdc\x95\xd0\x27\x11\xa9"
-  "\x75\xee\xdf\x93\xf6\xe5\x69\xe4\xed\xc3\xc7\x01\x17\xda\x51\xdf"
-  "\x5c\x49\xca\x20\xdf\xb1\xe2\xf7\xc4\x73\x22\x29\xf2\xa7\x39\x44"
-  "\x3a\x15\xf6\x59\x1e\xce\x9d\x27\xe5\x10\xe3\xcc\x66\xda\x56\xd7"
-  "\xbc\x9f\x6c\xbd\x8f\x24\xbe\x91\x43\x08\xf6\x35\x9b\x2b\x3f\x88"
-  "\x73\xe5\xbd\x3e\xf8\x3c\xab\x9a\x2b\xb3\xdf\xcb\x66\x01\x36\xa7"
-  "\x35\xd8\xc0\x5c\x1c\xfa\x3a\xe2\x56\x37\x60\xe3\x56\xb0\x39\x49"
-  "\xd6\x3e\x84\xd8\x38\xbd\x73\x65\x81\x4d\x29\xfa\xbc\x2c\xd5\x5c"
-  "\xf9\x94\x0a\x1b\xf1\x5b\x55\x1f\x6c\x94\xb5\x8c\x95\x49\xf8\x1d"
-  "\xb9\xdf\x5c\x39\xb4\xb5\x8c\xa6\x1e\x7f\x2b\xc2\xec\x08\x6c\xe4"
-  "\x56\xb0\xa3\x35\xd9\xcc\x8e\x78\xff\x27\x4c\x05\x7d\xaf\x20\x06"
-  "\x67\x44\xea\x53\x80\x41\x3b\xd8\x1a\x8e\x45\xb9\xd0\x4e\xc4\x12"
-  "\x71\xbb\x75\x67\x47\xc7\xbd\x6e\x22\x81\xcf\x9a\x8d\xd8\x75\x9d"
-  "\x30\xeb\x0b\x60\xac\xaa\x9f\xf3\x11\xe0\x73\x86\xd4\xbb\x04\x36"
-  "\xab\x3e\x22\xa7\xc2\x3e\x37\xd1\x85\x49\x91\x13\x41\x4f\x61\xec"
-  "\x31\xfe\x14\x7f\xfb\x02\x3e\x6f\xeb\x7c\x32\x6d\x66\x16\x6d\x63"
-  "\xcf\xf2\x80\x8d\xe1\x78\x86\xfe\xb0\x2e\xeb\x75\xd2\xb5\x79\xaa"
-  "\xb5\x23\xfe\xc6\xf4\x37\xb2\x09\x41\x9f\x88\x58\x0c\x78\xd8\x8b"
-  "\x1d\xfe\x6e\x4f\xbd\xd6\xe1\xe7\x0b\x1f\xdc\x1f\xd8\xbe\xe6\x38"
-  "\xfb\xb4\xde\x51\x2a\xec\xab\x34\xd4\xf5\x0e\x65\x3d\x0a\x30\xc4"
-  "\xdf\xea\xe5\xbe\x47\xa4\x67\xfb\x8c\xe1\xf1\x11\x21\x60\x68\xef"
-  "\x1d\xc3\x56\x05\xc3\xc6\xde\x31\x3c\x7e\x28\x00\x86\x15\x2a\x0c"
-  "\x33\x55\x18\xd6\x08\x0c\xf7\xa8\x30\xac\xec\x1d\x43\xcd\x5c\xba"
-  "\x5f\x61\x78\xe2\xdc\xeb\x1f\x01\x31\xb4\x06\x61\x87\x5f\x08\x0c"
-  "\xad\x41\xd8\x61\x73\xa9\x3f\x86\x56\xb5\x1d\x3a\xbc\x18\x5a\x85"
-  "\x1d\x5a\x55\x76\x68\x0d\xc2\x0e\x35\x73\xeb\x7e\x85\xe1\xc9\x1d"
-  "\x21\x60\x18\x84\x1d\xfe\x5d\xc1\x30\x08\x3b\x3c\x95\x1e\x00\x43"
-  "\x95\x1d\x42\xec\xe2\xc5\x50\xd8\xa1\x55\x65\x87\xd6\x20\xec\x50"
-  "\x13\xab\xf4\x2b\x0c\xbf\xc8\xec\x3b\x86\xb6\x20\xec\xf0\x55\x81"
-  "\xa1\x2d\x08\x3b\x74\x25\xfa\x63\x68\x53\xd9\x61\x43\x96\x17\x43"
-  "\x9b\xb0\x43\x9b\xca\x0e\x6d\x41\xd8\xa1\x66\xee\xdd\xaf\x30\x3c"
-  "\x7d\xee\xf5\xff\xc0\x18\x06\x61\x87\xb9\x0a\x86\x41\xd8\xe1\xe9"
-  "\xa6\x00\x18\xaa\xed\xb0\x46\x85\xa1\xb0\x43\x9b\xca\x0e\x6d\x41"
-  "\xd8\xa1\x66\x2e\xde\xaf\x30\x3c\xe3\x0a\x06\x43\x88\xb3\xfd\xe3"
-  "\x52\xb7\x17\x43\x35\x7e\xda\x58\xf4\x36\x88\x51\x11\xbb\x39\x9d"
-  "\x44\xf2\xc7\xaf\x65\x27\xe2\x37\x1e\xbf\x8f\xfb\xd2\x1b\x93\x32"
-  "\xec\xc4\xf7\x39\x88\xd9\x1b\x19\x84\x60\x7c\xaa\xc4\xa3\xf8\x9d"
-  "\x6a\x77\x3c\x3a\xef\xdf\x35\x1e\x75\xef\xea\x3b\x76\x62\x1c\xec"
-  "\x11\x3b\xdf\xb1\xef\x36\x18\x13\x7b\xc6\xee\xcb\x0c\x7f\xec\xac"
-  "\x15\x5e\xec\xf8\xb8\xc7\xb1\x6b\x30\x2b\xe3\x1f\xc7\x4e\x8c\x7f"
-  "\xe7\xc4\xae\x3f\x8f\x7f\x5f\xf5\x38\xfe\xd9\x25\x4f\x05\x9c\x95"
-  "\x70\x3a\xe0\xac\xe9\x92\xc8\x0d\xdb\x24\x0f\x7f\x8e\x91\xeb\xb3"
-  "\x36\x3f\x9c\x3e\x31\x3c\x1d\x69\xe8\x3a\xd9\x84\x74\x0a\x8f\xae"
-  "\x48\x42\x20\xdd\x61\xd0\xa5\xe3\x5e\x23\x48\x1b\xa1\xf0\x32\xac"
-  "\x23\x29\xd0\x66\x4e\x27\x91\x3c\x4e\x97\x12\x8e\x74\xb4\xe0\xa5"
-  "\x6c\x48\xd3\x0b\x9e\x6c\xde\xd3\x25\x49\xc8\x4b\x5b\xf7\x40\x41"
-  "\x63\xe9\x5a\x4f\x2c\xea\xba\x81\x17\xd6\xa9\xd0\x45\x22\x5d\x97"
-  "\xe4\x6a\xeb\xd2\xc9\x89\x6a\x3a\x7a\x1d\x51\xd3\x0d\x12\xfc\x92"
-  "\x7c\xda\x31\x86\x10\x83\xce\xc2\xdb\x92\x23\x29\x6d\x89\x62\x3c"
-  "\x63\xf6\xd4\x02\xcf\xf1\x3e\x3c\xc3\x09\x89\x06\x7a\xe4\x1b\x9d"
-  "\xc9\xe4\x46\xfa\x68\x1a\xde\x28\x33\xfe\x3a\x39\xd9\x23\x91\x64"
-  "\xde\x2e\x22\x6f\xeb\x96\xd9\x42\xec\xbe\x75\xc4\x28\xfd\xa5\xa6"
-  "\x43\x1a\x2a\x75\xd3\x18\x98\x1c\xe1\xef\x9a\x41\x8e\x69\x6a\x39"
-  "\x38\x1d\x99\x2c\xe8\x70\xed\x71\x46\x37\x96\xf6\x8e\x6e\xac\x73"
-  "\xbb\xc8\x50\xc0\xc2\x51\x0f\x5a\x21\xfa\x21\x96\x16\xfc\x51\xe9"
-  "\xff\x14\x35\xcf\x68\x9d\xce\xb9\x4d\xf4\x97\xa7\xe0\xa5\x2a\xa0"
-  "\x8d\xf3\xac\x93\xaf\xef\xe6\xbb\x1e\xdf\x29\x25\xfa\x61\x7d\xe7"
-  "\x60\xc6\xb7\x09\x6c\x4b\xd2\x59\x44\x3f\x0c\x46\x5a\x28\x93\xca"
-  "\xdb\x65\xec\xc6\xb5\x4b\x92\x31\xcf\xa1\xa2\x35\xf1\x3e\xae\x3e"
-  "\x04\x6d\x9b\xe9\x4f\xaf\xd7\xd2\xc7\x73\xfa\x4a\x17\xd0\xcf\xf2"
-  "\xa7\x37\x6a\xe9\x13\x38\xfd\x9f\x9a\x81\x7e\xb6\x3f\x7d\x67\x9c"
-  "\x86\x7e\x08\xa7\xaf\x6a\x02\xfa\x34\x7f\x7a\x8b\x96\xde\xcc\xe9"
-  "\xdf\x44\x1d\x99\xe3\x4f\x9f\xa2\xa5\x1f\xca\xe9\x5f\x39\x0a\xf4"
-  "\xe9\xfe\xf4\x79\x5a\xfa\x61\x9c\xde\xe1\x04\xfa\x0c\x2d\x7d\x19"
-  "\xa3\x25\x63\x04\xed\x70\x4e\xfb\xfa\x61\xa0\xcd\x0c\xd0\xd6\x30"
-  "\xc1\x3b\x59\xd0\x8f\xe0\xf4\x7f\x4c\x07\xfa\x45\x01\xb0\xd2\xd2"
-  "\x8f\xe4\xf4\xef\x13\xa0\xcf\x0a\x80\x95\x96\x7e\x14\xa7\xdf\x9f"
-  "\x0a\xf4\xd9\x01\xb0\xd2\xd2\x8f\xe6\xf4\xb5\x33\x80\x3e\x27\x40"
-  "\xdf\xfb\xd2\xc7\xd4\x25\x03\xdd\x9a\x6d\xeb\x15\xfb\xf1\xe9\x77"
-  "\x2d\xef\xcb\x38\xef\x86\x44\x28\x93\x17\xa0\xdf\xb5\xf4\x63\x38"
-  "\xfd\x41\xb4\xb9\x7c\x7f\x7a\xa2\xe3\xf4\x64\x8a\xa0\x1f\xcb\xe9"
-  "\x1b\xa3\x80\x7e\x43\x80\xbe\xc7\x7c\x87\xb0\xd3\x44\x4e\x5b\xe3"
-  "\x00\xda\x8d\x01\xfa\x5d\x4d\x3b\x8e\xd3\xfe\x63\x17\xd0\xda\x03"
-  "\xf4\xb9\x9a\xf6\x3b\x9c\xf6\xc3\x6c\xa0\x2d\x0e\xd0\xdf\x6a\xda"
-  "\xef\x72\xda\xbf\x26\x01\x6d\x49\x00\x79\xc7\xa8\x68\x93\x38\xed"
-  "\x61\xd4\xab\xd2\x00\xb8\xa8\x69\x2f\xe7\xb4\x9f\xa6\x01\x6d\x79"
-  "\x00\x5c\xd4\xb4\x57\x70\xda\xbf\xd9\x81\x76\x47\x00\x4c\xd4\xb4"
-  "\xdf\xa3\x31\xce\xeb\x85\x6f\xdd\xa9\xa5\x05\x1d\x70\x80\x1f\xaa"
-  "\x01\x5f\x38\x9e\x16\x7c\xd2\x56\xc6\xfd\x1a\x8b\x5f\x14\x1a\x2a"
-  "\x75\x4e\x55\x8d\x03\x13\x68\xc1\x07\xcd\xc2\xff\x55\x68\xf9\x51"
-  "\x49\x56\xd3\x4e\xa4\x05\x2d\xd3\x04\xed\x1e\x7f\x5a\xbd\x9a\x76"
-  "\x12\x2d\x68\x2a\x17\xb4\x95\xfe\xb4\xc6\x6e\x5a\x5a\x70\x3c\x03"
-  "\x68\xaa\xb6\x0b\xbf\xaa\x92\x73\x8a\x8a\xdf\x64\x5a\xd0\x9c\x24"
-  "\xf8\x39\xfc\xf9\x59\xd4\xb4\x53\x68\x81\xdb\x2d\x68\xab\xfd\x69"
-  "\x53\xd4\xb4\x53\x69\xc1\x49\xa5\xfd\x35\xfe\xb4\x79\x6a\x5a\x2b"
-  "\x2d\xf8\xa2\x42\xd0\xd6\x6a\x69\xb7\xf3\x31\x48\x12\x38\xd9\x68"
-  "\xc1\xe9\x6c\x41\xdb\xe0\x33\xc6\x4a\x3a\x66\x63\xdb\x39\xdd\x95"
-  "\x34\xe6\x33\x65\xac\x6c\xf4\x19\x5b\xd7\xeb\xe2\x70\x4c\xd9\x86"
-  "\x78\x3e\x31\xb6\x13\x68\xaf\x12\xfc\x0e\x69\xc7\x3e\x21\xdf\x34"
-  "\xc8\x3b\xac\x8c\x4f\x30\xee\x38\x03\xc5\x3d\x59\x57\x90\x41\xc7"
-  "\xc3\xa8\x8b\xbf\x93\x4a\xec\xfb\x25\xeb\x98\x5f\xf2\xec\x18\xe3"
-  "\xbc\xcd\x4d\x3b\xd5\x69\x85\x12\x6d\x98\xe4\x26\x32\xbe\xaf\x8f"
-  "\xc6\xcf\x2c\x71\x42\xba\x6b\xdc\xd8\x8a\xd6\x02\xda\xe9\xd4\xbd"
-  "\xd3\x86\xef\x6f\x6a\x2d\x82\x58\x8b\x6c\xb0\xe3\xe7\xc2\xf5\xb8"
-  "\x3f\x49\x8a\xae\xab\xa8\xbd\x01\xf7\x33\x29\x83\xfb\x02\x38\xd9"
-  "\xde\x21\x59\x10\x03\x3f\x41\x52\x1c\x2b\x3a\xc9\xb1\x1c\x22\xb1"
-  "\x3d\xf0\x64\xf2\x63\xba\x34\x73\x06\xc8\x62\x84\x7a\x33\x8e\xc0"
-  "\x3d\x93\x05\xf7\x5e\xb0\xb7\x37\x3b\x96\xb5\x23\xcd\x0b\xae\xf8"
-  "\x3b\x8c\xf4\xb1\xbb\x3f\xcf\x5a\x4b\x46\x1f\x97\xc9\x4e\xe5\xfd"
-  "\x55\xec\x9d\x55\x5f\x64\x7e\x9f\xbd\xaf\x4a\xd6\xdd\xe0\x89\x6d"
-  "\x6f\xd6\xbe\xaf\x8a\xd7\xa3\x4b\x6e\xc1\x3d\x7d\xca\xe7\x56\xb0"
-  "\xf7\x61\xc9\x3a\xb6\x8f\x10\xc8\xdb\x40\x13\xc7\xd4\x78\xda\xf3"
-  "\xf3\x70\xcf\x3a\xc7\xda\xe3\xe4\x88\xc8\x43\xfe\x82\xaf\x0e\xf9"
-  "\x21\x5f\x85\x27\x96\x73\x5d\x36\xb7\x02\xfb\x03\xfa\xa6\x26\xe8"
-  "\xf7\x5f\xc9\xc4\xc5\xde\x7f\x55\xa4\x9b\xe1\xd4\x0d\x6b\x64\xef"
-  "\xbf\x52\xda\x13\x3c\x8f\x52\xe4\x11\xf8\x5d\xbf\xc4\x40\x9f\xe9"
-  "\xd0\x03\xff\x52\x88\x7f\x77\x72\x7c\x74\x3b\x9d\xba\xe8\xc3\xe2"
-  "\xf3\x1e\xa7\x2e\xd6\x2c\x3e\x3b\x9c\xba\xd7\x36\x88\xcf\xb5\xca"
-  "\x3b\xc8\x02\xf2\x35\xb6\x1f\x06\x3c\xdc\x9e\xad\x69\x7a\x8c\xd7"
-  "\xf9\xbb\x50\xdb\x0f\x5b\x46\x11\xdd\x31\x59\x9a\x45\x9f\x69\x77"
-  "\xf3\xbe\x92\x2e\x87\xab\x41\x5c\x5d\xe2\x4a\x91\x86\xe9\x9c\xe9"
-  "\x96\x1a\x6a\x9f\xee\x60\xfa\x20\x4b\xd7\x62\x1a\xc3\x16\xf0\xa7"
-  "\xb1\xd3\x1d\x8c\xef\xe6\x3b\x8c\x6a\x19\xf0\xc7\x82\xc9\x93\xa7"
-  "\x4c\xb5\xda\xae\xbc\x6a\xda\xf4\xb9\xf7\xdd\x9f\x31\x6f\xfe\x03"
-  "\x99\x0b\x1e\x5c\xb8\x68\xf1\x92\xa5\x59\x0f\x2d\x5b\x9e\xfd\xf0"
-  "\x8a\x95\x39\x8f\xac\x42\xba\x6e\x79\xb7\x5e\xaf\x73\x4b\x04\xf0"
-  "\xbc\x0e\xeb\x79\x91\xd5\x0d\x69\x1c\x7b\x69\x87\x6c\x09\x3c\x2f"
-  "\xa8\x37\x13\x82\x7b\x86\x34\xcb\x61\x3a\xdc\xc3\x04\xf4\x50\x57"
-  "\x5f\x7a\x93\x03\xf7\x62\x3b\x2a\x4b\xee\x3a\xd7\x4d\x0e\xdc\x3b"
-  "\x70\x9f\xb9\x89\x24\x8e\x21\xba\xe3\xb2\xe4\xc4\xfc\xb2\xef\x10"
-  "\x52\x0d\x65\x03\xf1\x1c\x63\x24\xe6\x4d\x09\xd4\x55\x9c\x40\x9b"
-  "\x91\x7f\xf1\x16\xda\xe4\x5a\x9d\x49\x0a\xe0\x1e\x74\xd3\x78\x4c"
-  "\x0e\x7b\x71\x1f\x44\xff\x9e\xf5\x64\xc4\xf6\x2d\xf4\x68\x7e\x02"
-  "\x3d\xfa\xd8\x16\xda\x5c\x96\x40\x9d\x89\xc5\x24\xaa\xb5\x28\x2c"
-  "\xd3\x29\x4b\x0e\x66\x5f\x90\xef\x89\x93\xd2\x0b\x21\x6f\x52\x27"
-  "\x09\x2b\x83\x7b\x48\x73\xef\xb3\x70\xb9\x7f\x7b\xa6\x6d\x00\xf0"
-  "\x9b\x49\x3b\x16\xe9\x0a\xa0\x1e\x8e\x49\xd8\x87\xf8\xcb\x77\xa8"
-  "\xcf\x55\xdf\x76\x84\x38\xe5\xb0\x43\xb8\xa7\x12\xd4\x67\xa8\x2f"
-  "\x69\x26\xc8\xef\x37\xcb\xda\x06\x2c\x1f\x46\x3b\x81\xb6\xd2\xb3"
-  "\x7a\x91\x0e\x68\x8a\x81\xb7\x5b\xdd\x9e\xa4\xf9\x8b\xb3\x2d\x4b"
-  "\x1e\x5e\xb4\xe8\xf2\x48\x92\xc4\xae\x44\xbd\x8f\x60\x36\xf0\x23"
-  "\x9b\xb6\xd0\x6a\x68\xa7\x03\xda\x5b\xf3\x0e\xcc\x40\x40\x3f\x08"
-  "\xb4\xc9\x7e\x4c\x96\x27\x40\x7a\x15\x7c\xae\x02\xd9\x6b\xd8\x1e"
-  "\x65\x72\xfc\x9d\xb4\x28\xec\x28\xc8\x89\x63\x16\xbe\x53\x90\xb4"
-  "\xac\x9c\xad\x83\x76\x17\x03\x5d\x8d\x65\x18\x19\x07\xe5\x5e\x04"
-  "\x39\x76\xc0\x67\xa4\x9f\x8b\x38\x02\x7d\x35\x6f\x57\x3c\x7b\x97"
-  "\x20\xf4\x95\x63\x5b\x02\xdd\xd8\x5a\x24\xdb\xf1\x1d\xae\x6c\x1f"
-  "\x1a\xb8\x87\x7e\xa9\x01\x5a\x7b\x4b\xee\x6c\x1d\xee\xb9\x59\xe6"
-  "\xe5\x99\x8e\x32\xa1\x1c\x38\x1f\x7e\x1b\x22\x4a\x4f\x47\x1a\x99"
-  "\xd0\x46\x74\x6f\x1f\x25\xa4\x74\x0b\x2d\x87\xb3\x14\xce\x92\xfd"
-  "\x90\xf7\x16\x9c\x35\x90\x5e\x0b\xd7\xfd\x70\x7d\xeb\x28\xfb\x7e"
-  "\xd5\x8c\x72\x2f\x5f\x43\x9b\x26\x95\x90\xb1\x6c\x4f\xcf\xb5\xe4"
-  "\x27\x47\x64\x53\x05\xca\x8e\xef\x6b\xa6\x71\x03\x12\x7d\xde\x2b"
-  "\x2b\x87\x97\x10\xc8\x87\xeb\x2e\x7e\x55\x9f\xe1\xe0\x65\x23\x4c"
-  "\xfc\x73\xc4\x1c\xb8\xcf\x17\x9f\xb3\xe0\x5c\xd3\xfb\xa9\xe5\xd7"
-  "\xd3\x19\xd1\x14\x3c\x6d\x30\x67\x7c\x62\x70\x74\x03\xcb\x89\x3c"
-  "\xa8\x8d\xc8\x51\xc9\xbe\xe9\x51\x7a\x9e\x66\x6c\xe4\xf7\x46\x27"
-  "\xbf\xc6\x46\xc1\x09\xfd\x14\x07\xfc\xe3\x52\x79\x5a\xdc\x6c\xb8"
-  "\x96\xc2\xb9\xd3\xb7\xfe\x78\x28\x1f\x3f\x03\xf1\xec\x80\xf1\x00"
-  "\xb1\x74\xca\xb2\x1b\x31\x2a\xe4\xba\xa5\xc3\x67\x28\x20\xcd\x05"
-  "\xba\x55\xea\xd5\x9f\xf0\x4f\x7d\xf5\x27\xbc\x41\xa3\x3f\x76\xf4"
-  "\x47\x50\x6e\x46\x19\xd7\x97\xaa\x96\xd5\x19\x70\x1f\xde\x08\x7c"
-  "\xaa\x2c\xf7\x22\x8f\x08\x36\xbf\x2b\x3c\x0e\x73\xe1\x4c\x22\xa3"
-  "\x7f\x69\x96\x23\xc6\xa1\xce\x62\xdd\xa2\x5e\x2e\x0b\xc8\x07\x69"
-  "\xe5\x28\xdf\x52\xe0\x0b\xf7\x3b\x80\xae\xbc\x9e\x9c\x51\x64\x63"
-  "\x65\x9e\x7a\x10\xf4\x51\xc8\x8b\x3c\xb1\x1c\xf5\xb6\xcb\x85\x65"
-  "\x44\xdd\x1f\x42\x3a\xce\xb1\x49\xee\x69\x12\x56\xdf\xe9\x24\xa8"
-  "\x93\x78\xad\xef\x4c\x06\x5b\x4a\x25\x1e\x1c\x0b\xcd\x04\xdf\x67"
-  "\x39\xf0\x88\x1c\x51\x35\x71\x0d\x49\x46\x7e\xe8\xc3\x9d\x72\x44"
-  "\x5e\x19\xda\x22\xe7\x75\x00\xdb\x81\xfc\xf7\xc3\xac\x06\xaf\xdb"
-  "\x51\x1e\xc8\x57\xd5\x5b\x8c\x73\xe7\xc2\x55\xbc\xad\x50\xd7\x0e"
-  "\x28\x5f\x81\x6d\xc7\xfe\x84\xfc\xca\x63\xb2\xde\x8c\x79\xb8\x67"
-  "\x8b\x68\xcf\x0e\xfc\xbd\x07\xf6\x07\xd2\xe3\xde\x96\xec\x3d\xb5"
-  "\xb2\x7c\x0d\xeb\x37\x28\x8f\x78\x50\xa8\x03\x79\xe4\x76\xd2\x4e"
-  "\x0a\xfe\xe8\xf9\x55\x6d\x10\x83\x0c\x7c\xc6\x17\x1f\x7d\x96\x1a"
-  "\x1f\x28\x57\x01\xe5\xab\x71\x5c\x46\x7f\x02\x75\x1a\x30\xe6\x80"
-  "\x34\xbb\xa7\x08\x78\xac\x68\x63\x6b\x4b\xc0\x67\x1d\xc8\x62\x47"
-  "\x3e\x20\x4f\xb5\xe0\x55\x85\xef\xb0\x54\x63\x2d\xf8\xed\x40\xcc"
-  "\x99\x3d\xaf\x62\x6d\x02\xdf\x35\xf0\xf6\xed\x3c\xaf\x12\x68\x2a"
-  "\x69\x47\x2a\xa1\xab\xd3\xf8\x5e\x6d\x3c\x6f\x4f\xee\x59\x86\x6f"
-  "\x35\xf7\x6b\x03\x1f\x5a\xfe\x28\x6d\xf2\xca\x3d\x30\x49\x79\x57"
-  "\xbb\x90\x7b\x0f\xd6\x47\x57\xce\x61\xe3\x28\xd6\x81\xe5\x05\x3f"
-  "\x19\xf9\x29\x7d\x35\x11\xe4\xe0\xfd\xa5\x9f\x06\xe9\x3b\x50\x17"
-  "\x59\xbf\x81\x1f\x6d\xc9\x45\x5d\x1c\x38\x1e\xca\x57\x15\xe0\xfd"
-  "\x4a\xbc\xd7\x3b\x98\x8f\xed\xce\xd7\x67\x63\x3e\xae\x4d\x14\x2e"
-  "\x04\x5d\xf2\x10\x32\xd6\x44\x92\xdd\xeb\x59\xdb\x76\xb9\x57\x5f"
-  "\xaf\xdb\xd7\x49\x08\xca\x09\x7d\x54\x09\xb2\x36\x82\xef\x37\xa1"
-  "\xac\xe0\xaf\xf7\xd0\xe7\xd3\x08\xca\x0c\xfe\x4c\xc8\x17\x79\x83"
-  "\xc0\x7e\x0f\xb6\x11\xfb\x73\x22\xf7\x7d\x90\x37\xe8\x73\x94\xdd"
-  "\xdb\xee\x48\x8b\xba\x8f\x59\xbb\x01\x07\xc4\x0b\x71\xf1\xf2\x1c"
-  "\x88\xba\x6f\x07\x5e\xbb\xf8\x3d\xd7\x0d\xec\x6b\x7b\x02\xad\x45"
-  "\x7a\x2f\xed\xa0\x3b\x31\x6f\x2d\xd4\x3d\x29\x0b\xd7\x61\x60\x7c"
-  "\xee\x6c\x75\x00\xdf\x5d\xb8\x6f\x29\xf0\xa8\xc4\x3e\x05\xba\xdd"
-  "\xa8\x8f\x70\x5f\x2b\xe4\xde\x05\xe3\xf9\x78\x38\x67\x78\xed\x7f"
-  "\xd0\x36\x5f\xfd\x8a\xd4\xda\x3f\xe2\x6d\xf7\xe4\xa6\x12\xb1\x67"
-  "\xb3\xe5\x94\x3c\x68\xba\x18\x3b\x04\xd6\x83\x9e\xde\x07\xf6\xe2"
-  "\xe5\x31\xc8\xa4\xc1\xba\x92\xe9\xe3\xca\x99\x3a\x6c\x33\x94\xad"
-  "\xe4\x7c\x22\x59\x9b\x99\x3e\xad\x67\x3a\x50\x4b\x57\x42\x3b\xbb"
-  "\xf5\x20\x32\x4b\xe0\x5c\xab\xe9\x13\xc5\x77\x55\xe1\xde\x5f\xe8"
-  "\x93\x20\x06\xfe\x7e\x6b\x87\xd7\x2f\x21\xf6\x1e\x86\xfd\x20\x73"
-  "\x19\x1f\x6f\x85\xdf\x8a\xe4\xf9\x09\x3e\x3a\x8c\x6d\xba\x85\xe9"
-  "\x2f\xca\x92\x3b\x07\x65\xa9\x64\x72\xe4\x5a\x08\xe4\xb1\xf7\xd6"
-  "\x02\xaf\x59\xc2\x5e\x15\x5e\x89\xc8\xeb\x31\xf0\x55\x28\x13\xd4"
-  "\x5d\xc1\xfc\xdf\x8d\x28\x5b\xd4\x38\x21\x7b\x4d\xdb\x7a\x2c\x1b"
-  "\x61\x3e\x2b\xb1\xb2\x35\x40\xb7\xb1\x8d\xef\x9d\x10\x09\xe5\x77"
-  "\x5a\xee\x43\x7a\x63\x3e\xfa\x68\xcb\x5d\xec\xf3\x62\xcb\x1d\xa0"
-  "\xab\xc7\x89\x0c\xfc\xf4\xa8\xa3\x8a\x5e\x34\xcb\xc6\x7b\x20\xc6"
-  "\x40\xbc\x76\x41\x8c\xb4\x13\xfb\x1b\x75\x19\x62\x24\x6b\x6b\x51"
-  "\xd4\x46\x45\x6f\xa1\x9e\x52\xec\x7b\x8e\x4f\xd4\x01\xd0\xe3\x4a"
-  "\xaf\x6e\x45\x1d\x10\xfd\xb8\x13\xfa\x51\x0f\xf5\xdd\x2e\xda\xb5"
-  "\x13\xe8\x21\x16\x33\x5e\x2b\x64\x2f\x11\xf4\x27\x15\x1c\x84\xad"
-  "\xd6\x16\xa0\xff\x65\x18\x44\xe7\x8b\xb2\x3b\x78\x5d\xd1\x8f\x2b"
-  "\xb4\x18\x23\xb2\x7d\xd0\x20\x0d\xfd\xe0\x24\xc0\x9e\xf9\x3e\xdc"
-  "\xd3\x57\xa4\xa1\xed\xf0\x3a\x8c\x13\x98\x1e\x42\xdc\xe3\xd5\xa3"
-  "\xe8\x39\x1a\xff\x84\xbe\xd8\x5e\x97\xcf\xf7\x99\x40\x5d\x42\x9f"
-  "\x8a\xf3\x15\xe0\x67\x15\xf6\x23\x64\x8e\x7e\xcb\x57\x57\x8c\x43"
-  "\x41\x57\x26\xa8\x78\x57\x06\x1a\xe7\xca\xb8\x0f\x2c\xe5\x65\x62"
-  "\x06\x8a\xb6\xed\xe2\x6d\x13\xf7\xd8\x6f\x6b\xb1\xdf\x0c\xef\xa8"
-  "\xfa\x11\xfa\xcd\x30\x5d\xd0\x57\xa2\x2f\xf7\xda\x6b\xcc\xc3\x8a"
-  "\x2d\xfb\xfb\x0b\xc3\xe5\x68\x0f\x5e\xb9\x62\x66\x69\xfc\x45\x65"
-  "\x60\x7f\x11\x63\x11\xed\x2d\xd7\xd8\xc6\x0e\x2e\xbb\x18\x5b\x00"
-  "\x87\x3a\xb7\xd8\xef\x03\xd2\xd0\x7f\x62\xdd\xea\x31\x68\x3b\xef"
-  "\x57\x61\xcb\x86\x78\x7f\x1c\x62\x8e\xaa\xed\x19\xb1\x46\x9f\x80"
-  "\x3c\x10\x53\x16\x57\x42\x1a\xc7\x35\x06\xe3\x5b\xbb\xda\x47\x03"
-  "\x6d\xb1\x87\xa2\xbd\xc4\x34\xf9\xda\x62\xcc\x6c\x61\x8b\x4a\xdd"
-  "\x2f\x03\x46\xc9\xde\x7a\x0d\x73\x34\xf5\x22\x36\xd5\xec\x7d\xce"
-  "\xac\x8d\x86\x5f\x29\x63\x1a\xd2\x43\xd9\x1c\x28\x63\xd7\x8c\x8f"
-  "\x76\x94\x0f\xea\xd2\x33\x9f\xb5\x85\xf9\x8a\x9c\x56\x26\x8f\xa1"
-  "\xb8\x4c\x8c\x13\x90\x96\x2c\xd2\xd2\xc5\x58\xa2\xe8\xcd\x00\x8d"
-  "\x4c\xae\xc0\xf1\x51\x8c\x5e\x89\x8f\x18\x2f\xe6\x8b\x0c\x6e\xd1"
-  "\x3e\x4c\x9b\xc0\xd3\xa2\xab\x30\xad\x80\xf7\x43\x31\x65\xe3\x55"
-  "\x74\xba\x18\xaf\xd0\xbe\x24\xa7\x1c\xd5\x80\x36\x86\xf7\x4e\xd9"
-  "\x98\x8a\xfc\xeb\xf3\xda\x71\x0e\x51\x02\x79\x8b\xd0\x1f\xa0\xbf"
-  "\xb0\xcc\xe7\x7e\xc3\x72\x2b\xbb\x6e\x46\xbf\x83\x71\x08\xe6\x03"
-  "\xdd\x1c\xf4\x45\x90\xfe\x02\xee\xe1\x49\x4f\xe8\x81\xaf\x71\xa3"
-  "\x28\xbb\x97\xc5\x0a\x27\x52\xc3\x94\x34\xa5\x1c\xd8\xfa\x62\x2c"
-  "\x87\xe5\x15\xff\x85\xbe\xab\x13\x7d\x13\xab\x2f\x56\x27\x74\x9c"
-  "\xcd\x1b\x94\xb8\xa8\x43\x52\xd1\xe2\x1e\x08\xcc\xa7\xc5\xce\xe4"
-  "\xfe\x2c\xf6\x1a\x2c\xcb\xf0\x03\x5f\xb9\xf6\x2c\xfd\xa4\x6c\x19"
-  "\x91\xb7\x9f\x61\x31\xd6\x0c\x2e\x67\x6c\x09\x6f\x47\xec\x5c\xd6"
-  "\x0e\xee\x53\xed\x5c\x16\x79\xc6\xf6\x76\x96\xf7\x28\xb6\x05\xf3"
-  "\x0a\x55\x79\xb8\x0f\x09\xe4\xfd\x82\xc9\xa5\x29\xe7\xe9\xc8\xf4"
-  "\xa3\xc7\xfd\x77\xc1\x87\xa2\x3e\x08\xdf\x1b\x67\x16\x72\xbe\xa7"
-  "\xf8\x5d\xe8\x97\x0c\xf4\xbd\x2c\x6f\xbe\xa0\xb9\x55\x5c\x99\x7f"
-  "\x8f\x1b\xc0\xfb\xd5\x2c\x89\xfe\x5e\xc4\xdb\x11\x37\x94\xcd\xb3"
-  "\x4f\xa4\x41\xdf\xc6\x76\x2a\x7d\xab\xfe\x8c\xf6\x03\xf5\x1b\xf1"
-  "\x9e\xe9\xfd\x1a\x36\x87\x2d\x45\x1a\x94\x89\x8f\x11\x46\xb7\x36"
-  "\xa6\x3e\x26\x9b\x9e\xc1\x71\x89\xc7\xaa\xa6\x87\xc4\x1a\x11\x71"
-  "\x2c\xfb\x25\x8c\x0b\x71\x55\x8a\x8f\xa1\xad\xa9\x04\xdf\x83\x0e"
-  "\xb2\xb0\x3d\xae\xf1\xbd\xf9\x6a\x1a\xf4\x4f\xbf\x6d\x77\x0a\x9e"
-  "\x71\x25\x8a\xdf\x40\x5f\x52\xe7\x3e\x22\x62\xba\xc1\xa9\xdb\x85"
-  "\x2f\x39\x25\x0f\xbe\xd9\x37\x0e\x1b\x7c\xb3\xaf\xcf\x30\xdd\xa3"
-  "\xf5\x19\x10\x37\xe7\xb7\x16\x0d\x1e\xe1\x13\x07\x40\xda\xb9\x7d"
-  "\x47\x9c\x0b\x6d\x14\xf7\x41\x62\xfe\x89\xad\x7b\x0d\xfe\x9d\x22"
-  "\x33\xfa\xcd\x96\xd5\xca\xfa\x85\xe9\x16\x8c\xd5\x34\xf5\x6d\xf4"
-  "\xf1\x9d\x58\x9f\xc2\x4f\x26\x6c\x3f\x2f\xc7\x32\x5c\x73\x19\x3c"
-  "\x47\xf8\xf9\x72\x1f\x5f\x29\xc6\x30\xf4\x93\xbe\x63\x95\x7c\x8d"
-  "\xef\x58\x65\x9a\xee\xef\x23\x4d\xfa\xe0\xc7\xaa\xc1\x4e\xf4\x5b"
-  "\x8a\x8f\xf4\xf5\x05\xa6\xa8\xed\x3e\xb1\xec\xe0\x62\x25\x96\xf5"
-  "\xfa\xd1\xc1\x89\xe8\xa3\xa0\xfe\x4a\x51\x77\xbe\x53\x96\x36\x28"
-  "\x75\x3b\x01\xe7\x3a\x0b\xe8\x66\x51\x98\x0b\x3e\x67\x8a\x18\x90"
-  "\xd9\x66\x3b\xee\x27\x22\xc7\x56\x80\xfe\x45\xa2\x9e\x39\x96\x9c"
-  "\x21\x47\xbd\x63\x45\x75\xcb\x52\xa5\x7f\xe3\xe3\xd5\x71\xe1\xb6"
-  "\x2d\x74\x03\xd4\xd3\xac\x6e\xe3\xd3\x90\x56\x28\xd6\x10\x58\xdf"
-  "\x32\x5e\x26\x47\xd9\x16\xdf\xb6\xf1\x76\x98\xdc\xd8\x0e\x9c\x13"
-  "\x41\xfd\x7b\x30\xee\xc1\xbd\xd0\xc0\x6e\xa6\x95\x75\xeb\x7c\xf8"
-  "\xc6\xb3\xeb\xd5\xf1\x95\x5c\x8c\xbe\x52\xcc\x3d\x6b\x20\xde\xb1"
-  "\xab\xd7\x62\x6e\xf9\xc1\x2c\x4b\xd6\xb2\x05\x4b\xb2\xe7\x4f\xb1"
-  "\x2c\x58\xb2\x20\x7b\xc1\xdc\x45\x0b\x56\xcd\xcd\x5e\xb0\x74\xc9"
-  "\xf8\xc5\x73\x1f\x58\x70\xbf\x65\xe5\xdc\xe5\x96\xe4\x9c\x71\x39"
-  "\x91\xc4\x4b\x7a\xb5\x65\xee\xf2\xe5\x0f\x2f\x9e\x97\x61\x59\xb2"
-  "\xe0\xfe\x09\xcb\xe6\x2d\x9f\x97\x6d\x99\xbb\x6c\xe9\xc3\x4b\x32"
-  "\x2c\xe3\x32\x26\x8e\x4b\xbe\x32\x23\x52\xbd\x86\x36\xc6\x48\x9a"
-  "\x3d\x5f\x35\x35\x15\x7e\x45\xf4\x06\x5d\xd6\x32\x43\xce\x82\x25"
-  "\x7c\xdd\x2e\xe1\x9e\x49\xc5\x24\x0b\xf7\x58\xc7\x3d\x70\x69\x51"
-  "\x7c\x16\x5c\x65\xa4\x83\x76\x5a\xca\x70\x9f\xf5\x04\x3a\xa2\xb5"
-  "\x28\xc1\xe2\x94\x87\xe9\xd9\xbe\xb4\x90\x0e\x6d\x1b\x41\xbf\xaa"
-  "\x69\x82\x98\x2d\x0b\x9f\xf9\x2e\xfb\x8a\x98\xec\x2b\x88\x0c\x67"
-  "\x14\x9c\x46\xdc\x83\x1d\xca\xcc\x76\xca\x43\xb2\xf8\xba\x68\x82"
-  "\xdb\x15\x7b\x55\x3e\xb5\x5f\x95\xcf\x71\x49\x38\xad\xac\x49\xdf"
-  "\xf6\x38\xb9\x0d\xf5\xf3\x88\x9c\xc0\xd6\xb2\x1f\x03\x5d\xc6\x35"
-  "\xd9\x96\x57\xae\x4b\x81\x78\xf0\xb0\x63\x18\xcb\x3b\xed\x96\x48"
-  "\x14\xc8\x25\xef\x5b\x93\x4c\x36\x41\x5d\xcb\xcd\x94\x42\x1d\x95"
-  "\xca\x7a\x1a\xb4\xc1\x08\x6d\x39\x24\xda\xb1\x95\xb5\x63\x0b\x4d"
-  "\x2c\x8e\x03\xf9\x8a\x98\x3c\x47\x95\x36\x80\xdc\x87\x40\xa6\x54"
-  "\x90\xd3\x88\x72\x05\x5a\xeb\xc3\xf5\xae\x63\xf2\x90\x09\x9e\x15"
-  "\xd0\x6f\xa3\xf8\x5e\x4a\x85\xdb\xb9\xfd\x41\xbb\x32\xca\xe0\x73"
-  "\xc1\x19\x12\xf5\x34\xee\xdd\xbd\x7e\x34\x7d\xc7\xdd\x49\xea\x33"
-  "\x0f\x11\xc3\x23\xd4\x45\x5f\x6a\x6a\xe2\x6d\x1a\x92\x86\xbe\xe1"
-  "\x0f\x0f\x1e\x92\xb1\x4d\x30\x56\x44\x95\x9d\xe9\x71\x6d\x51\xde"
-  "\x94\x40\xdd\x74\xab\x3a\xe6\x1a\xf2\x1a\xf6\x09\xc6\x5b\x2d\x30"
-  "\x4e\xb5\x16\x0d\xd9\x09\x75\x13\x11\x1b\xbb\x69\xc7\x1c\x55\x2c"
-  "\x35\x04\xf5\xcc\xdd\x03\x6f\xbd\xc2\x1b\xf7\x04\xc7\x32\x1c\x7f"
-  "\xf3\x04\x28\xe3\xf2\xf2\x37\xeb\xb5\xfc\x91\x27\x7c\x76\x29\xf5"
-  "\xf0\x79\xf8\x10\x8c\x09\x5c\xa0\xcb\xae\x1e\xea\x4b\x2c\xda\x42"
-  "\x1b\xeb\x21\xbd\xf0\x2c\x91\x81\xb6\xb1\x6c\x0b\xe3\x9f\xe9\x94"
-  "\xe3\x6b\x91\xff\x63\x09\x84\xe4\x03\x4d\x4b\xd1\x10\x82\xeb\xbb"
-  "\x90\x07\xf6\x1f\xd6\xa6\x5d\xb7\x16\xfa\x7c\xb5\x46\x9f\x53\x8a"
-  "\x30\x26\x2c\x06\xfe\xa0\x43\x85\x5f\x12\x9c\x6b\xd7\x4e\x2c\x26"
-  "\x49\x58\x0f\x7c\x6e\xc0\xf5\x10\xe0\x79\x48\xa9\x8f\x82\xfe\x17"
-  "\x78\xf8\x1a\x8c\xd0\xad\xf1\xf5\x39\x4d\xb8\xd7\x02\xdd\x07\xfe"
-  "\x1d\x65\x44\x1d\x6b\x2d\x1a\x1a\xa5\xe8\x14\xe8\x7a\x23\xd3\x2b"
-  "\x13\x49\xa2\x45\x66\x7b\x59\x1c\xd0\x81\x5e\x6d\x07\x7d\x42\xbd"
-  "\x02\xda\x69\x8a\x4e\x81\xae\x35\x20\x1d\xc8\x10\x59\xb1\x2a\x45"
-  "\x46\x1f\x79\x54\x1e\xba\x1b\x75\x8c\xfe\xfc\x87\x87\xe8\x90\xbb"
-  "\x0f\x71\x9c\x86\xee\xae\x6f\xe3\x18\x78\xfb\x7d\x68\x9e\xaa\xdf"
-  "\x1b\x40\x8f\x23\xb1\x9f\xf9\x5a\xf5\xd0\xdd\x20\x5b\x03\x8b\xc5"
-  "\x1f\x05\x0c\xd8\x58\x35\x74\x11\x96\x17\x7d\x58\xeb\xed\xc3\xa1"
-  "\x35\x81\xfa\x50\xd3\x77\x6c\x2f\x6a\x5a\x34\xb4\x11\x6d\x05\xca"
-  "\x74\x2a\xfb\x50\x07\xc2\x12\xea\x00\x0f\x46\xf4\x58\x47\xb5\x09"
-  "\xe9\x87\x8d\x0f\x54\x87\x56\x8f\xab\xcb\x09\xc1\xb5\x70\x2c\x97"
-  "\x68\xc2\x7e\x1d\x96\x11\x10\xdf\xfb\x7d\x64\x63\x27\x2d\x1a\x96"
-  "\xb5\x49\xec\xcb\x0d\xe5\x4a\xcf\x25\x5f\xa2\x85\x8f\x8b\x8e\x31"
-  "\xa8\xcf\xc3\xde\xab\x87\x48\x00\xd3\xc4\x7d\x75\x0b\x8c\x35\xda"
-  "\xf5\xfc\x9e\xbf\x5f\x18\x1e\xef\xfb\xfd\xc2\x70\xb9\xa7\xef\x17"
-  "\x7c\xeb\x1d\x7e\x3b\xd6\xeb\x29\x9b\xad\xf3\xd6\x3d\x7c\x86\x27"
-  "\x40\xdd\x4a\xf9\x89\xe5\xea\xf9\xcb\xf0\xe7\x50\x86\x3a\x18\x97"
-  "\xe8\xf0\xd9\x3a\x0a\x7c\xaa\xd9\x98\x3d\xbc\x9c\xc7\x2b\x18\x07"
-  "\x0d\xcf\x43\x1a\x6d\x3b\xba\x0f\xbd\x09\x7d\x05\x39\xcb\x6e\x06"
-  "\xdc\x48\xf0\x97\x68\x64\x58\xb9\x92\x2d\xf9\x10\x13\x1a\xe0\x26"
-  "\x8a\x90\xe1\x8c\x9e\xc2\xc1\x93\xc4\xbd\x8b\xdd\xc8\xdd\xf4\xdd"
-  "\xf9\xe7\x71\x0c\xe4\xf2\x32\x7e\x6d\x44\x27\xea\x73\xa8\x28\xae"
-  "\x3f\x47\x69\x4a\x94\x22\x81\x0e\x8c\x2a\xf3\x66\x0f\x00\x7e\x4e"
-  "\x46\x4c\x69\xa7\xe0\xaf\xdc\x53\xf5\x3d\xa6\xf8\xde\xc3\x11\x36"
-  "\x47\x55\xc1\xe8\xb0\x0c\xf6\xb8\xd6\xa8\xce\xee\x24\xa9\xdc\xe8"
-  "\x5b\x69\xde\x00\x76\x31\xe0\x9f\x1c\xe0\x97\x04\xf9\x23\xbc\xd9"
-  "\x61\xee\x75\x2a\xe2\xb7\xb9\xf8\x23\xa7\xf5\xdc\x88\x3e\x1f\xa3"
-  "\x54\x9f\x47\xf3\xcb\x88\xb6\x80\x94\x5f\xc7\x61\x69\x18\xa8\x7c"
-  "\xf4\xaa\xc7\xc8\x35\x81\x48\xbd\xfd\x3f\xf2\xb0\x92\xa4\xc6\xd3"
-  "\x9b\x7f\x59\x9a\xef\xfd\x58\xa3\xef\xfd\xb8\xd4\x0b\x21\xba\x03"
-  "\xff\xe4\x3a\x63\x09\x7a\x2a\xe5\x30\x68\x4c\xc6\x60\xd7\x98\x90"
-  "\xf7\x10\xd2\x84\x81\x3c\xa5\xaa\x64\x39\x30\xf5\xd7\x73\x0c\x5b"
-  "\x27\x3a\x70\xb4\xcb\xe8\x97\xa9\x4d\xc3\xfb\x70\x8b\x48\x9b\xfc"
-  "\x9a\x1f\x3d\x4b\xb3\xa8\xee\x75\x29\xf0\xa7\x1c\x0a\x6e\xb8\x10"
-  "\xb2\x5e\x3a\xfe\x0d\x0f\x1d\xda\xc7\xa5\xe3\x6b\x3a\x28\x1f\xc5"
-  "\xc1\x13\xb1\x0b\xfe\xa3\xdd\x8e\x92\x8a\x0c\x2a\x12\xa8\xf8\x70"
-  "\x41\xc6\xf1\x4b\xc7\xa5\xe3\xd2\x71\xe9\xb8\x74\x5c\x3a\x2e\x1d"
-  "\xfd\xe0\xd0\xa9\x27\xd6\x7a\x38\x23\xc4\x55\x3d\xff\xd1\x89\x53"
-  "\x9d\x26\x9d\x4f\x39\x2a\x0e\x92\x97\xe2\xb0\x94\xa7\x3b\x8d\xf6"
-  "\x59\x0d\xc9\x15\x59\x2e\xfd\x86\xd4\x9a\xa4\x9d\x99\x4d\xe6\x92"
-  "\xb4\x43\xd3\x2a\x73\xda\xe4\xfc\xeb\xab\x13\x77\x64\x1c\x35\x15"
-  "\xcf\x6e\xb4\xee\xc9\x76\x47\x6d\x9c\x59\x3b\x7e\xd7\xa2\xe6\x11"
-  "\xa5\x73\x0e\xcf\xa8\x5a\xd3\x29\xad\xbf\xee\xf5\x31\xbf\xbc\xef"
-  "\x48\x5c\xd1\x8f\x0e\x4e\xf9\xfd\xb2\x33\x91\x4f\xfd\xd7\xfe\x2b"
-  "\xfe\xef\xc1\xe3\xc3\x9e\xbd\xeb\xa3\xab\xff\xb4\xaa\x3d\xfc\x89"
-  "\x1b\xdf\xfc\xce\xaf\xe7\x1f\x4b\xd8\x72\xc7\xfb\x57\xbe\xb4\xe2"
-  "\xab\x98\x82\x5b\xeb\x26\xfe\x66\xc9\xa9\x51\xdb\xef\xfd\xdb\xf7"
-  "\x5f\x59\xeb\xd1\xad\xbb\xf6\xb5\xcb\x9e\x9b\xfb\x49\xec\x33\xb7"
-  "\x1f\x98\xfc\xbb\x87\x4e\x0f\x7c\xf2\xe6\xb7\x2e\x7f\x61\xc1\xe7"
-  "\x43\x7f\x71\xe7\x87\xd3\x5f\x7e\xe4\xec\x80\xc7\x6f\x78\x63\xdc"
-  "\xaf\xe6\x7d\x1a\xbf\xf9\xc7\xef\xd9\x5e\x7c\xf8\xcb\xe8\xa7\x6f"
-  "\x79\x67\xc2\xee\xc5\x27\x47\x6e\xbb\xe7\xe3\x6b\xf6\x3e\xda\x15"
-  "\xf6\xd8\x0f\xf6\x8d\x7d\xfe\xfe\x7f\x0c\xde\xf4\xdf\xef\x4e\xfd"
-  "\xc3\xf2\x96\x41\x3f\xfb\xe1\xdb\xdf\xfb\xff\x85\x27\x86\x6f\xbd"
-  "\xfb\xaf\xff\xf1\xe7\xd5\x1d\x11\xff\x73\xd3\x5f\xbe\xfb\xbf\x0f"
-  "\x7c\x36\xe4\xe7\x3f\xf9\xe0\xaa\x3f\xae\x6c\x35\x14\xde\x56\x3f"
-  "\xe9\xb7\x4b\xbf\x18\x5d\xf6\xd3\xbf\xff\xe7\xab\xb9\xf4\x7c\xfa"
-  "\x8f\xc8\x0b\xa7\x7e\xd3\xb8\xf1\xcb\xba\xbc\x50\xca\x53\x81\x3a"
-  "\xbf\xcd\xb3\x11\x9d\x9e\x84\xcb\x21\xcd\x13\x42\x6d\x6f\x0f\x87"
-  "\x45\x5d\xbe\xb7\x03\x7f\x17\x87\x7b\x5a\x63\xdf\x0f\x67\x29\xde"
-  "\x99\xff\xa8\x80\x25\xbe\x89\x43\x07\xed\x0c\x03\x49\x06\x90\x70"
-  "\xe8\x19\x3d\x19\x48\x22\xc9\x20\x12\x45\xa2\x49\x0c\x31\x10\x23"
-  "\x89\x25\x71\x64\x30\x31\x91\x78\x92\x40\x86\x10\x33\x19\x4a\x86"
-  "\x81\xf4\x23\xc8\xc8\xc0\x32\xe7\x91\x14\x33\xfc\x81\xff\xb3\x48"
-  "\x0a\xbb\x4f\xbf\x94\xfe\x8d\xa6\x3b\x44\x7a\x83\x48\x77\x5e\x4a"
-  "\xff\x46\xd3\x2d\xff\xe2\xeb\x65\xff\xd2\xab\x0e\xc2\x02\x1e\x19"
-  "\xf8\xc4\x07\xdd\x87\x36\x55\x27\x8e\xee\x7b\xd2\x4b\x79\x3f\x7e"
-  "\xbe\xe5\xb5\x47\x0a\x9c\x56\xfe\x31\x97\x10\xfe\x5d\x02\x55\x1f"
-  "\x9d\x3d\x95\x54\x8e\x92\x1c\x38\xf3\xe1\xb4\xc3\xb9\x09\xce\x32"
-  "\x38\x5f\x50\xf8\x10\xe2\x6a\x23\xe4\x0c\xf8\xf6\xd3\xc5\x70\xad"
-  "\x25\xa4\x25\x9d\x90\x2f\x9d\x84\xb8\xcb\x09\x69\xb5\xa8\x04\x8f"
-  "\xf2\x4a\xd4\x25\x6a\x85\x6c\x9d\x54\xac\xaa\xac\xaf\xe3\x53\xe5"
-  "\x0d\xb3\x53\x2d\x93\x27\x5a\x27\x5a\xa7\x5a\x26\x4c\xb0\x4c\x49"
-  "\x4e\x9e\x3e\x29\xd9\x36\x69\xca\x95\x96\x29\x53\xaf\xb6\x5d\x79"
-  "\xf5\x94\x69\x96\xc5\x8f\x2c\x5b\x30\x39\xf9\x81\x79\x96\x25\x19"
-  "\x0b\x96\x5b\xe6\x2f\x58\xb6\x78\xe5\xdc\x65\xf3\x7a\x6b\x75\x9f"
-  "\x0f\x68\x0a\x19\xd9\xc5\xc5\x54\xa3\xa1\x83\x51\x44\x1e\xeb\x22"
-  "\xf2\x55\x1b\x88\x37\x27\x49\x9c\x7e\xc7\xe2\xbb\xee\xf8\x68\xdc"
-  "\xdd\x31\xaf\x5f\xfb\xc0\xb8\x6b\x7e\xf0\x7c\x61\x05\x91\xae\xd1"
-  "\x13\xc9\xda\x40\xa4\x2b\x6a\x89\x34\x7a\x26\x91\xe2\x66\x11\x69"
-  "\xc5\x06\x22\x2d\x49\x21\x52\xc6\x78\x22\xa5\x95\x12\xe9\x87\x76"
-  "\xff\xb4\xc7\x13\x79\xda\x4b\xcd\x44\xda\x55\x49\xa4\xe7\xa2\x88"
-  "\xb4\xa9\x9a\xa7\xd5\x56\x11\xe9\xf5\xec\x0b\xde\x07\xe7\x7f\xf4"
-  "\x15\x7f\xdd\x3f\x01\x3a\x76\xe1\x43"
+static unsigned int rss_eth_z8e_uncompressed_length = 552620 ;
+static unsigned int rss_eth_z8e_length = 154046 ;
+static unsigned char rss_eth_z8e[154046 + 1] = 
+  "\x78\x9c\xec\xbd\x7f\x7c\x54\xd5\xb5\x37\xbc\x32\x19\x60\x84\x90"
+  "\x99\x04\xa4\x53\x12\x75\xb0\x60\xa3\x97\x1f\x51\xb1\x45\x0b\x12"
+  "\x05\x2c\xb6\x01\xa2\xa2\x44\x05\x13\x34\xd0\xa0\x11\x23\x04\x08"
+  "\x90\x64\x86\x01\xaf\xa8\x40\x26\x11\x34\x42\x20\xb1\xd2\xa7\xdc"
+  "\x96\x6a\x6c\xb1\xc5\x5e\xac\x63\x49\x9f\x97\xde\x4b\x32\xb9\x7d"
+  "\xf1\x7d\x73\xfb\xe2\x75\xe4\x46\x9a\xf2\x04\x18\xc9\x40\xc6\x64"
+  "\xe6\xec\xe7\xbb\xf6\x3e\x27\x99\x19\x26\x28\xb7\xf7\xf3\xbc\xff"
+  "\x94\xcf\x27\xcc\x39\xfb\xc7\xda\x6b\xaf\xbd\xd6\xda\x6b\xef\xbd"
+  "\xf6\x3a\x44\x7f\xc3\x3f\xf3\x8d\x79\x7f\x4b\xf5\xbf\xff\xfb\xfb"
+  "\xbf\xbf\xff\xfb\xfb\xbf\xbf\xff\xfb\xfb\xbf\xbf\xff\xfb\xff\xe7"
+  "\xdf\x05\x93\x99\x7e\xef\x21\xea\x71\x5b\xec\x7e\xfa\xd2\xf1\xfa"
+  "\xab\x22\x8c\xe4\x24\x3f\x59\xec\xfc\xab\xff\x51\x2d\xd2\x4d\x1e"
+  "\xb2\xdc\x68\xa3\x94\x59\x7b\x89\x76\x8e\x11\x5d\xaf\xbe\x26\x02"
+  "\x9b\x5f\x13\x5d\xb3\x7f\x42\xd4\x3c\x9e\xe8\xd5\x31\x22\x08\x38"
+  "\x8b\xfd\xf4\xc4\x4e\x86\xb3\x19\xef\x9c\xbf\x65\x8c\x08\x20\xbd"
+  "\xcc\x4f\x05\x29\x9c\xbe\x69\x0c\x60\x8d\x26\x72\xbf\x26\x42\x51"
+  "\x70\x2d\x5c\x9f\x61\xce\x1e\x27\xf1\xd9\x1f\x07\x87\x61\x1c\x06"
+  "\x8c\x2d\x57\x80\x91\x62\xe0\x15\x34\x51\x12\xc3\xeb\x76\x93\x3d"
+  "\xe8\xf6\x5e\x8b\xba\x41\xf4\x29\x8b\xeb\x56\xa3\x8c\x70\x53\x72"
+  "\x73\x79\x98\x1c\x37\x52\xd2\x69\x1a\xfe\x26\x7e\x4d\xf8\xdd\xc5"
+  "\xfd\xdd\xac\xea\x8d\x67\x18\xa8\x9b\xd4\xe3\xbe\x26\xbb\xbf\x2e"
+  "\x60\x3b\xaa\xc8\x8c\xb2\x2b\x82\x26\xaf\x49\x95\xb5\x5d\xa3\x97"
+  "\x35\xa1\xec\x62\xa3\xac\xca\x33\xdd\xaf\xe7\x8d\x40\x5e\x79\x6c"
+  "\x9e\xb9\x56\xcf\x4b\x41\xde\xce\x38\xfc\xcc\xbe\xde\x30\x9d\xa6"
+  "\x6b\x0e\x02\x17\xc7\x51\x8c\x0a\xd7\xd1\xcb\xa7\xa1\x7c\x73\x2c"
+  "\x2c\x22\x3d\x2f\x1d\x79\xfe\xd8\xbc\xdf\x65\xeb\x79\xdf\x40\x5e"
+  "\x38\x36\x2f\xc9\xa8\x67\xef\x71\x0f\xb7\x27\xe8\x27\xb7\x9f\xa4"
+  "\xda\xe6\x3e\x0c\x9f\x8e\x32\x2e\x2e\xb3\xd0\xe1\x22\x1e\x2b\xce"
+  "\x3b\xda\xd8\xdf\x3e\x97\x29\x34\xe0\xf8\x51\x3f\x8a\xa6\xa0\xe5"
+  "\xf0\x0a\xa3\xfe\x6c\x07\xc3\x20\x49\x43\x86\xe3\xa7\x6b\xe6\x32"
+  "\x1c\x7e\xc7\x73\x26\xf7\x5b\x7f\x76\x70\xff\xa2\xc7\x1c\xc6\x27"
+  "\xc0\x0e\xb1\x10\x0d\xc5\xdf\x30\x8b\xc1\x03\xab\xed\x42\x73\x7e"
+  "\x93\xcc\xa2\x76\x84\x5d\x73\x0b\xf2\x95\x87\xc8\x31\x96\x9c\xa7"
+  "\x68\x84\x1d\xf8\xd1\x8e\x0d\x64\x71\x96\x8a\x90\xaf\xbc\x8b\x5a"
+  "\x03\x5d\xe4\x0c\x88\x4e\x5f\xf8\x22\x55\x5d\x24\x8b\x2f\x7c\x96"
+  "\xaa\x9e\x27\x7b\x73\xc5\xe7\x94\x88\xbf\x34\x93\x20\x67\x26\xd7"
+  "\xed\xa0\xd6\xfa\x0e\x72\xd6\xc7\xd6\x75\x5e\x47\xf6\x16\xbc\x63"
+  "\xec\xac\x8c\x47\xb3\x23\x4c\xe1\xf4\x11\xf6\x8a\x37\xc8\xec\x1c"
+  "\x47\xa6\x96\x22\xaf\x81\x8b\x9f\x71\xd9\x72\x86\x2c\x6f\x2d\x07"
+  "\x0f\x9d\x61\x7c\x47\xd9\xdf\xd9\x10\x32\x1d\xb5\xe7\xd2\x51\xfb"
+  "\x49\x6a\xb6\xcf\xa0\xe6\xf2\xd9\xb4\xe3\x0c\xa5\x1c\x0d\x4d\xa7"
+  "\x66\xf3\x7d\x90\xb1\xd9\xe4\xeb\xc2\xb3\x23\x82\x32\x41\x72\xac"
+  "\x25\xf0\xc7\x88\xb6\x9d\x4f\x93\xc5\xaf\x60\x82\xbe\x23\x4e\x7e"
+  "\x54\x46\xc4\xf4\xe5\xf7\x44\xfd\x58\xfd\x4d\xb2\x03\xbf\x4e\xe0"
+  "\x72\xe7\x29\x4a\xb9\x76\xbc\x9d\xb2\x81\xf3\x30\x5f\x5d\x98\xcc"
+  "\x15\x74\xcd\x20\xb2\x35\x5a\x73\x4b\x19\xef\xda\xf7\x9a\xe8\x64"
+  "\x1e\xed\xde\x98\x0f\x39\x4d\xc9\x45\xdb\x5d\xdc\xde\x0e\xc8\xba"
+  "\xf3\x4d\x32\x77\xaf\xcb\x4f\x6a\x78\x4d\x74\x20\xaf\xd8\xc8\x03"
+  "\x3f\x75\x20\xbf\x73\xca\x68\xb2\xf9\xc2\x39\xf4\x61\x6f\xa7\x99"
+  "\x61\xa4\x06\x29\x89\xe1\x59\xcb\x29\x19\xfd\x19\x02\x7c\xee\x6c"
+  "\x40\xfa\xb7\x50\x0e\xf5\x0f\xf8\xa9\xa6\x90\xeb\x8b\x6f\x3c\x1e"
+  "\xd4\xbe\xf1\xf8\x45\xed\xf5\xc7\xbb\xc5\xeb\x8f\x5f\x88\xbc\xfe"
+  "\xf8\x17\xce\xf5\x64\x89\x7c\xe3\xf1\x40\x6b\xa9\x1c\x03\x5b\x6b"
+  "\x29\xc6\x20\x42\x96\xca\xb3\x64\x7b\xe2\x79\x8c\x7d\xf8\x13\xaa"
+  "\x5c\x41\x76\x2d\x2d\xad\xcd\x17\xfe\x98\x9e\xa8\x20\x81\x67\x7f"
+  "\xa2\xfe\x75\xa7\x8f\xca\x57\x32\x64\x41\x9f\x46\x3a\xfc\xe6\xe1"
+  "\x36\x6e\x37\x90\x96\x91\x8f\xbf\xc5\xf8\x2b\xc4\x5f\x91\x48\x1f"
+  "\x55\x04\x5a\x39\x53\x37\x25\xd1\xbe\x5e\xa2\x29\x1a\x25\x9d\xa1"
+  "\x91\xd3\x81\xbf\x6d\x10\xba\x65\x6a\xb5\x8f\xf8\xbf\xed\xa2\xaa"
+  "\x9e\x9e\x62\x62\xdd\xc4\x7a\x89\xf5\x14\xda\xd9\x8a\x76\xf2\xa4"
+  "\x2c\xbe\x26\x82\x22\xfd\x11\x3f\xd2\x3b\x83\x1b\x8b\x93\x02\x1b"
+  "\x8b\x4d\xdd\xe9\x8f\xfc\x27\xca\x1c\x44\x99\xad\x3a\x0d\x3b\x19"
+  "\x16\x64\x22\x30\x32\x4c\xc9\x80\x59\xfa\x9b\x4b\xed\xe6\xbd\xaf"
+  "\x89\x93\x28\x77\xa2\x1f\x16\x60\x03\x0e\xe8\x3f\xb2\xd3\x48\x03"
+  "\xad\x3b\xb6\xa3\x1c\xd7\xf7\x85\x72\x58\x7f\xfb\x7d\x25\x9d\x64"
+  "\x0d\xd3\x70\xd1\xa7\xda\x43\x99\x4e\xd6\xb3\x23\x43\x34\xb4\xc7"
+  "\x4d\x79\x0c\x9b\xeb\xf9\xba\x3a\x09\xf5\xfe\x53\x38\x8b\xa1\xdf"
+  "\x68\x7e\x8f\x28\x4e\x82\x4e\xef\x38\x8a\xfa\xaa\xed\xd4\x3c\x03"
+  "\x47\x6e\x83\xc7\x5a\xe2\x09\x7e\x38\x5a\x12\xa2\x91\x75\x94\x8c"
+  "\x7a\x0f\x31\x3c\x86\x05\x3e\xf0\xa3\xaf\xff\x79\xb4\x24\x40\x9a"
+  "\x88\x81\xe9\xd7\xe1\x35\xc6\xc0\x43\xba\x00\x3c\xe6\xbf\x66\xd4"
+  "\x19\xd9\x28\xe1\x3d\xf8\x1b\x8d\xe1\x85\xc8\xec\x90\xf8\x3e\xc2"
+  "\x30\x7a\x58\xc7\x00\xa6\x77\xed\xbd\xd4\x45\x56\x4b\xc0\x59\x9c"
+  "\xdc\x5a\x41\xc4\xf5\xdf\xa9\xea\x1c\x22\xba\xf3\x93\x99\xe7\x38"
+  "\xdf\x17\xbe\x80\x32\xa9\x7f\x15\xdd\xc5\xc9\x23\xbb\xc8\xcc\x38"
+  "\xa3\x7e\x39\xe3\x19\x3d\x96\x0f\xce\x79\x64\x06\x3d\x32\xfb\xfe"
+  "\xd9\x33\x68\xde\x3d\xb3\x66\x50\xf6\x9d\x93\xb2\x6f\xff\xee\xb4"
+  "\xdb\x29\x6f\xd1\x83\x33\x28\x6f\xfe\x0c\x7a\x08\x7f\x79\x0f\xcd"
+  "\x79\x70\xf6\x9c\x87\x66\x50\xfe\x7d\xf7\xe3\x6d\xd6\x8c\x5b\xb3"
+  "\xbf\x3f\x29\x6f\xd6\xfd\x73\xe8\x81\x85\xb7\x65\xdf\x76\x1b\xdd"
+  "\x33\x27\xf7\xd6\xec\x6c\xfd\xf7\xd6\x6c\x2e\xf2\xd8\xb4\x39\x0f"
+  "\x4d\xca\x5b\xf5\x5c\xd9\x73\x93\xe6\xdf\x3f\x2b\x6e\x9e\xcd\x8a"
+  "\x5c\xd2\x98\xbe\x41\x71\x7e\x2e\x69\xd0\x17\xfb\x30\xee\xf8\xeb"
+  "\xf2\x56\x9d\x82\xdc\xdb\xfe\x6d\x1f\x8f\x97\xd4\xab\x56\x9e\xab"
+  "\xcc\x3d\x6e\x6b\x3b\xe8\x76\x8c\xe9\x86\xf9\x0c\x65\xae\xbd\x88"
+  "\xbc\x9b\xf5\x79\x63\x08\xf2\x43\xb1\xf9\x69\xc7\x91\x3f\xa5\xd5"
+  "\x41\xe4\xc3\x1f\x68\x1d\x84\xfe\x03\x4d\x03\xd4\xed\xcc\x1f\x02"
+  "\x9e\x4e\x42\x1b\x1d\x90\xc7\xb6\x1e\xb7\x6d\x6a\x94\x9c\x77\x60"
+  "\x4c\xda\x1c\x1b\x28\xf9\x1c\xd9\x46\xb6\x96\xe5\x10\x8f\x8d\xaf"
+  "\x4c\x87\x71\xb1\x1f\xc6\x70\x09\x03\xe3\x0d\x38\x27\x74\x38\x15"
+  "\x51\x3a\xc1\xcf\x70\x76\x20\x4f\x87\xf5\x40\x2b\x74\x03\x74\xf7"
+  "\x8d\x9a\x33\x8b\x44\xfa\x08\x87\xd6\x97\x25\xe7\x03\xd4\x3b\x64"
+  "\xf0\x32\xca\x07\x9b\x4b\x51\xee\xad\xb9\x49\x18\xfb\x24\xcc\x53"
+  "\xe8\x8b\xd5\x0b\x9e\x0e\x6a\xb5\x19\xc5\xa2\x27\x9f\x54\x5a\x1a"
+  "\x60\xe0\xbd\x36\x63\x85\x70\x22\x6d\x83\x4c\x4b\xe2\x34\x8c\x73"
+  "\x32\xcb\xa3\xd8\x28\xd3\x93\x91\xbe\x06\xf8\xb5\x47\xb8\xfe\x79"
+  "\x59\x7f\x18\xd2\x1e\x46\xd9\x15\x5a\x7a\xc6\xd3\xe0\x1b\x4e\x83"
+  "\x8d\x30\x66\x34\xe0\x3d\xa3\x89\x7c\x12\xb6\xd7\xdb\xf1\x5c\xe2"
+  "\xdd\xd0\x45\xa7\x4b\xc9\xe4\x47\x9e\xe6\x04\xcc\xbe\xfe\xf6\xc7"
+  "\x73\x5d\xb4\x65\xee\xe9\x2b\xc6\xfc\x96\x96\xc5\x73\x61\x84\xf1"
+  "\x39\xdf\x5f\x66\x34\xb7\xc9\x32\x8d\xb1\x98\x8a\x71\xba\xa6\xc7"
+  "\x9d\xd6\x18\x37\x4e\x87\x01\x67\x05\xe8\xde\x0e\x18\x36\xad\xbb"
+  "\x98\xfb\xb5\x02\x70\x4d\x3a\x5c\x03\x46\x50\xf1\x41\x9a\x3f\x8e"
+  "\x0f\xfe\x1d\xb0\x67\x0c\xe4\xa7\x53\x5c\xfe\x07\xc8\xbf\x57\xcf"
+  "\x87\x6c\xa5\x3b\x62\xf3\xd3\xa7\x23\xff\x3e\xb4\x1f\x84\xec\x24"
+  "\xfb\xc9\xb6\x7f\x1f\xdb\x7e\x03\xe5\xf3\xe2\xca\x97\xa0\xfc\x0f"
+  "\x30\xb6\x41\xd6\xeb\x5c\xbe\x41\xe7\x55\x94\xb7\xa0\xbc\x2b\xae"
+  "\xfd\xbd\x28\xff\x50\x14\x7e\x71\xfd\x1f\x55\x8c\xfc\x7c\xe6\x2d"
+  "\xfc\x16\xa1\xcc\x30\x96\x57\xd6\x15\x47\x4b\xd8\x56\x4c\x6f\x8b"
+  "\x6b\x9f\x69\xf9\x8c\x66\xd0\xa8\x9b\x69\x64\xdb\xaf\xdb\x21\x27"
+  "\x15\x0e\xa3\xcc\x71\x6d\x8c\x47\x9d\xd5\xe0\x9f\x15\x06\x6f\x24"
+  "\xa8\x33\x2d\xae\x4e\xbe\xe4\x2d\xd5\x8e\x3e\xc6\xaa\x8e\xae\x87"
+  "\xa2\x61\x70\xdf\x60\x1b\x8d\xaa\x88\xeb\x3b\xe6\x1d\xeb\xc6\xed"
+  "\x4a\xce\x47\x80\x27\x6e\x43\xda\xfd\x80\xf9\x2c\xf3\x11\xf3\xba"
+  "\x2f\x10\x82\x9e\x9c\x9b\xa2\xe6\xfb\x51\x9f\x58\x2b\x88\x9f\x27"
+  "\xf1\x33\xc3\x16\x7d\xb9\xba\x0c\x8c\xfa\x04\xbf\x9c\xde\xcc\xe9"
+  "\x2c\x7b\xa2\xef\x87\x9a\x82\x39\x3a\x09\x32\x6a\xc2\x7b\x44\x6f"
+  "\xe3\x1e\xbc\x27\x01\xff\xa7\xa1\x83\xc1\xb3\x73\x99\x1f\xa7\x22"
+  "\xfd\x4e\x3d\xff\x56\x2e\x8f\xe7\x5b\xf5\x67\xe6\xdb\xa7\x75\xbe"
+  "\x85\x1c\x5c\x7b\xb3\x6c\x5b\xca\x82\xaa\xaf\x29\xbe\x9f\x85\xbc"
+  "\x6b\xf1\x7b\x3f\x7e\x19\xaf\x07\xd0\xf6\x27\xce\x8b\x64\x77\x46"
+  "\x60\x73\xa8\xf7\x3f\xe2\xf7\x41\xfc\xbe\x87\xdf\x87\xf0\xfb\x26"
+  "\xcb\x6d\x60\x5d\x31\xc5\xf1\x4c\x97\xa6\x64\x75\x98\x1a\xc3\xd1"
+  "\x1e\x5d\x7e\x94\xfc\x9e\x1f\x48\x13\x2a\xcd\xa4\x68\xae\xa7\xf5"
+  "\xcd\xe5\xf6\xf3\x00\xbf\x84\xdb\xd7\xe5\x7e\x88\x1a\x27\x55\x46"
+  "\x53\xf5\xcc\x6a\xbc\xf5\x34\x55\x2e\x29\xba\x4d\xfc\xe6\x54\x05"
+  "\x85\xc0\xef\x44\xa6\xab\x9f\xae\xcd\x06\x4d\xcc\x78\x67\xdd\x67"
+  "\x92\xe5\x25\xdc\x51\xf5\x51\xe3\x0d\x5b\xfc\xda\x92\xd8\xf1\xb6"
+  "\xed\x67\x9a\xf1\x78\x1b\xf8\x32\xee\xe0\x67\x9e\xd3\x86\x1a\x3c"
+  "\x03\xde\xee\x82\x7e\x0c\x26\x57\x30\xdf\x5d\xdb\xe4\xa7\x9f\x79"
+  "\xa4\x1d\x54\x9b\xb1\x92\xf3\x83\xd0\x33\xcc\x1b\xc9\xa5\x2c\x2f"
+  "\xd7\xb6\x19\xf9\x32\x2f\x6d\x51\x21\xc3\x4f\x2e\x91\x79\x5d\x7e"
+  "\xb0\x8b\x91\xc7\xb8\xb1\x1c\x27\x97\x71\xde\x18\xcb\x00\xdc\x11"
+  "\x39\x3a\xdc\x64\xb6\x1f\xd8\x0e\xc0\x7c\xdc\x89\x32\x13\xfd\x34"
+  "\x32\x7f\xb0\x35\x97\xf0\x8c\xc8\x9e\x44\x64\xba\xc5\x45\x43\x7c"
+  "\xe1\x13\xb4\x20\x2c\x22\x93\x5c\x74\x8d\x2f\x7c\x90\xc0\x20\x69"
+  "\xbe\xf0\x49\xba\x85\x68\x9c\x2f\xbc\x13\xf3\xed\x7e\xce\xff\x30"
+  "\x8b\x92\x92\xf0\xeb\xbc\xc9\x65\x4a\xf2\x85\xb7\xd0\x78\x97\x19"
+  "\xbf\x25\x74\xdf\x10\xd1\xe3\x0b\xe7\xa2\x5c\x11\x2d\x88\x88\xf3"
+  "\xb3\x87\x88\x4f\x0b\x22\x64\xcb\x7d\x41\x38\x7d\x61\xd8\xbe\xe1"
+  "\xe3\x48\xd7\xc4\x82\xc8\x97\xf8\xeb\x11\x9a\x67\x44\xce\x82\xc8"
+  "\x79\x31\xeb\x85\x0f\xf1\xfe\xa9\x10\x26\x12\xbe\xf0\x74\x6a\x0d"
+  "\x06\x51\xce\x29\x44\xcd\x88\xec\x27\x2e\x9a\xa8\x0f\x73\xa7\x56"
+  "\x33\x22\x07\x7d\xcc\xeb\x43\xff\x30\xaf\x2c\xe8\xdb\x88\xdf\xda"
+  "\x11\xf3\xe5\xbb\x67\x44\xa1\xb0\x8d\xc8\x9b\x8c\x85\x04\xf7\xc1"
+  "\x17\xee\xa0\x02\x98\xc2\x0b\xd6\x07\x04\xe3\x9f\xba\x89\xd7\x11"
+  "\xd3\x09\xba\xcf\xba\x60\xbd\x53\x20\xcf\x22\xd2\x46\xe4\xf9\xc2"
+  "\x5d\x84\x36\x0a\x01\x6f\x89\x84\xe7\x19\xe1\x42\xd9\x00\x97\x8b"
+  "\x86\xc3\x30\xb8\xec\x82\x08\x59\x51\xde\xd5\x97\x36\xa2\x14\x7f"
+  "\x1e\xfc\x79\x51\xf7\x4f\xc2\x3d\xfa\x23\x81\x79\x0e\xf5\x61\x17"
+  "\x8d\x08\xf4\xc0\x6e\x97\xb4\x8c\xd0\x30\x94\x67\x9b\x64\x36\x78"
+  "\x0b\xf8\xa6\xd8\x24\xbe\xb5\x29\xd6\x1e\xd9\x8f\x94\x54\xd5\x8f"
+  "\x94\x91\x9c\xde\x8d\x39\x1e\xcf\xd9\xdd\x2a\x6f\x0a\xea\x2d\x94"
+  "\xf5\x3c\x29\xd9\xc2\x96\x92\x13\x82\xcc\x80\xae\x2e\xa6\x23\xe8"
+  "\xea\x62\x5a\x8a\x9a\x94\x6c\x5f\xf9\x36\x12\x69\x29\x39\x7d\x69"
+  "\x29\x79\xa8\xff\x64\x9f\x9c\x7b\x53\x4a\x7b\x14\xec\xe7\x00\x67"
+  "\x31\xf8\x32\x19\x30\x4a\x01\xcb\xd5\xe7\x76\xd0\x82\xf5\x22\xb4"
+  "\x20\xbc\x29\x5c\xb0\x9e\x92\x27\x92\x0b\xf8\x7e\x00\x1a\x15\xa1"
+  "\x9f\xcd\xf8\x9d\x8d\x7c\x1a\x85\xb6\x3e\x04\xdc\x52\x6e\x0f\xed"
+  "\xb8\x00\xb3\x12\xb0\x8a\x18\xa7\x2f\xdd\x64\xc3\xbb\xe7\x4b\x85"
+  "\x5f\x93\xe6\x49\x69\xd3\x6c\x29\x5e\x83\x87\x98\x7f\x14\xdd\x76"
+  "\xd2\xfc\xa0\x08\xfb\xc2\x7b\x09\x3c\x66\x6b\x0d\x9e\xe4\x7c\xd8"
+  "\xfa\x07\x31\xce\xcc\x53\x5b\xf0\xbb\x9f\x98\x7f\x5a\x4b\xd7\x70"
+  "\xd9\x0f\x99\x87\xe6\x97\x06\x37\x4d\xa2\xd2\x24\xbc\x3b\x0b\xc2"
+  "\x16\x7a\xa2\xd4\xec\x8a\x78\x52\x1a\x5b\x4b\x79\x5c\x4e\xa0\x0e"
+  "\xd7\x2b\x21\x6b\x12\xec\xdd\x24\x11\xb6\x96\x07\xcc\x23\x8b\x9d"
+  "\xa2\x35\x98\x8b\xb2\xa5\xc4\xfd\x61\x3e\xe2\xf2\xf3\xba\x84\x3f"
+  "\x62\x1b\x99\xc7\x7d\x13\xa9\x2e\x6a\xe9\xba\x83\x78\xcd\xd1\xd2"
+  "\xb5\x9f\xf9\x54\x13\xb6\x91\x0e\xf0\x68\xdf\xbc\x2e\xd7\x90\x27"
+  "\x2e\x52\x12\xd2\x22\x2d\xc5\x07\x91\xdf\x8c\x72\xc7\x25\xdf\xce"
+  "\xbf\x18\xb6\x86\x6d\x29\x9e\xb0\x67\x64\xf6\xfc\x8b\x7d\xa2\xa5"
+  "\x78\x27\x2d\xe9\x72\x81\x56\x07\x69\xde\xd9\x70\x72\x6b\x69\x11"
+  "\xca\xf4\x20\x7d\xbf\xe4\xff\x79\x67\xbb\xc5\xfc\xe7\xc5\xf9\xf9"
+  "\x17\x3f\x15\xf3\x8a\xc5\x87\x05\xe5\x94\x3a\x62\x93\xd0\x58\x2e"
+  "\x8e\x77\x1c\xa4\x11\x27\xfd\xc4\x32\x91\xbb\x54\x13\xf3\xce\x9e"
+  "\x17\x4f\x3c\xcf\xb4\x99\x4e\x2d\xc5\x90\x9f\xf2\x9d\x4c\xef\xa6"
+  "\x96\xe2\x23\x68\x7f\x36\xe0\x3a\x85\xaf\x7c\x2f\xca\x7a\xad\x4b"
+  "\xce\xda\xe8\x78\xc7\x4e\x0a\xa7\xa5\x78\x22\x35\x29\x8d\x5a\x5a"
+  "\x8a\x57\xab\x49\x69\x13\x69\x23\x1d\xe1\x9a\x91\xd9\x91\xb4\x91"
+  "\xe0\x81\x91\x8d\x18\xa7\x6b\x78\xcc\x7b\xb1\x06\xc7\xfb\xbe\x5e"
+  "\x1e\x7f\xcf\xc8\x26\xf4\xb5\x0d\xfa\x4e\x28\xde\x1f\xd9\xc4\xeb"
+  "\x68\xd4\x6d\xeb\x4b\x1b\xe9\x45\xb9\x36\x25\x5f\x23\xfd\xcc\x97"
+  "\x72\xbe\xa9\x1d\xf9\x29\xe6\x87\x64\xe4\x07\xfa\xd2\x52\x09\x7f"
+  "\x36\x51\x9b\x5a\x08\xf8\x69\x92\xa7\x3c\xa9\x85\xe2\x6e\x0f\x6c"
+  "\xc7\x8b\xcc\x93\x4e\x91\x96\x0a\xbe\x9c\xe6\x04\x1d\x21\x2b\xa9"
+  "\x85\x5a\x4d\x6a\xa9\x48\x4f\x6d\x0c\x49\xfe\x4f\x6d\x60\xf8\x7d"
+  "\x1b\xb3\x78\x8d\x6d\x46\x7e\x93\xa8\xb5\xde\xd8\xc3\xfc\x6a\xb3"
+  "\x3a\x34\x9b\xd5\x25\x3c\xd6\xec\x1f\xbe\x20\x02\x11\x8f\x35\x4f"
+  "\xf3\x58\x73\xc2\x43\x61\x97\x96\x1f\x21\xd6\x51\xe1\xdf\x09\xd0"
+  "\xe1\x0f\xa0\xc9\x7e\xc9\x03\xbe\x72\xc8\xc1\xfa\xb1\xae\x96\x2e"
+  "\xf0\x43\xe9\x2f\xa4\x7e\x6a\x0d\x9e\x90\x74\x15\x69\x56\x07\xf3"
+  "\x15\x8f\xf1\x13\xa5\xe4\x12\x35\xd6\x6c\xad\xc6\x9a\x13\xa9\x01"
+  "\xdc\x34\xb4\x93\x9e\xf6\xfb\x90\x94\xd9\x34\xf0\xec\x11\xd4\xf9"
+  "\x03\x29\x3e\x4f\xf3\x0e\xa6\x27\x59\x5f\xb1\x8e\x5a\x10\x0e\x31"
+  "\xdf\xfc\x85\x75\x9b\xd2\x55\x54\x60\xe8\x2a\xd6\x53\x6c\xeb\xb3"
+  "\xae\xd2\x74\x5d\xa5\xe9\xba\x4a\xbe\xdb\xa0\x6f\x3c\x23\xf2\x58"
+  "\x27\x2d\x28\x57\xba\x66\x41\x24\x5b\x80\x3f\x52\x00\x23\x4f\x8d"
+  "\x07\xca\xd4\x8e\x58\x22\xcb\x4b\x3a\x8d\x70\x69\xd0\x39\xf8\xf3"
+  "\x68\x4a\xe7\xb4\xe9\x3a\xc7\x64\xe8\x9c\x08\xe6\x2f\xc8\x95\x96"
+  "\x48\xe7\x68\xba\xce\x89\x08\xa5\x73\x34\x5d\xe7\x70\x7a\x44\xd7"
+  "\x39\x91\x04\x3a\x07\x32\xcd\xfd\x4d\xd6\x75\x8d\x8b\x75\x0d\xf7"
+  "\x17\xfc\x96\xa3\x29\x5d\x53\x08\x3b\xdf\xc4\xba\x26\x82\x3a\x9a"
+  "\xa1\x6b\x7a\x64\x7d\x17\xeb\x9b\xbe\x7f\x24\xe8\x50\x07\xb1\x9e"
+  "\x91\x3a\x25\x3c\x2e\xcc\x3a\x05\xf4\x9b\x19\xaf\x53\x00\xcf\x83"
+  "\x67\x9b\xae\xab\xbc\xd6\x4d\x22\x0c\x9d\xd2\xb8\xa0\x3c\x88\xb1"
+  "\xfe\x04\x6b\x5d\xe8\xee\xf2\x32\x97\xaf\x3c\x4c\xd0\x05\x6d\xa2"
+  "\xd5\x45\xc0\x11\x3c\x1c\x81\xbe\x20\x82\x6c\x3a\xc2\x90\x73\xf0"
+  "\x79\x76\x6b\xe9\xc7\x14\x81\xbc\xce\xeb\xea\xf6\x3d\x11\xcc\xb2"
+  "\xcd\x3b\x2b\x02\xa0\x8f\xff\x89\x52\x17\x74\x4c\x56\xa0\xa5\xeb"
+  "\x03\xca\xed\x10\x5a\x6e\xa1\xdf\x01\x39\xc8\x9e\xb7\xc2\x6b\x7d"
+  "\xe2\x79\x1b\x64\x4d\x78\xa1\x1b\xff\xef\x79\x67\x6d\xd6\xc5\x1d"
+  "\x74\x7d\xee\x52\xa1\x45\x20\x6b\xe8\x6f\x23\xfa\xdd\x04\xdc\xbd"
+  "\x90\xbb\x36\xc8\x9a\x23\x1c\x27\x6b\x90\x9b\x7d\x78\x76\x28\xfa"
+  "\x8d\x6c\x83\xac\x35\x69\x72\x4e\xeb\x90\xeb\x2b\xb4\xd3\xc6\x7b"
+  "\x4f\x90\xb7\x26\xad\x46\xc9\x9b\xa6\xea\xf9\x35\xa6\x9f\x49\x97"
+  "\x37\x8c\x05\xf2\x03\x90\x1d\xd0\x7a\x10\x79\x2b\x8d\x93\xb7\xe7"
+  "\x75\x79\x4b\x53\xf2\x86\x71\x4d\x8e\x6c\x54\x32\xc7\x6d\xf0\x3a"
+  "\xac\x5f\xe6\xd2\xad\x0e\xc1\xb6\xa3\xe4\x1f\x29\x77\x98\x5f\xac"
+  "\x79\x90\xb9\x1c\xc8\x1c\xe0\x89\x00\xeb\x4f\xf0\xe7\x7f\xf0\x9c"
+  "\x37\xbf\x54\xfc\x47\x41\x64\xac\x0b\x32\x95\x07\x9d\xf6\x29\xf4"
+  "\xe9\x7f\x3c\x11\xa4\x46\xc8\x94\x03\xb2\x94\x0d\x99\xca\x81\x6c"
+  "\xb1\x4c\x79\x23\x1b\x19\x66\x9a\xb7\x1f\x86\x9c\x33\x63\x65\x4a"
+  "\xed\x5c\x27\xde\xff\xeb\x71\x5f\x0f\xcd\xf8\xeb\x23\x6c\xaf\xe0"
+  "\xb9\xd3\x4f\xbf\xf1\xe8\xcf\x41\x3f\xed\xd9\x26\x6d\x1d\xc8\x62"
+  "\x69\x15\x5d\x7b\x86\x6e\x38\x00\xbe\x27\x3c\xa7\xe0\xf9\xe0\x82"
+  "\x9b\x3f\x84\x4d\xb1\xd9\x82\xb6\x7b\x58\x1e\x85\x7b\x2a\xd6\x16"
+  "\x94\x03\x7e\xb4\x88\x9e\xac\x14\xd8\x8f\x97\x44\x9f\x9d\xf7\x98"
+  "\xac\x78\x4f\x05\x0d\xc6\xe3\x37\x7d\xef\x25\x1a\x8d\x3f\xfb\x5e"
+  "\xb7\xe6\x62\xfb\x0a\xcf\xd9\x62\x9d\x7d\xf8\x8e\xb5\x34\xd1\x1a"
+  "\x24\x4b\x83\x5b\xcb\xb7\x6e\xb2\xf1\x5e\xcb\x68\x7e\x16\xee\x86"
+  "\xa6\x86\x4b\x64\x66\x3b\x52\x4b\x43\x7b\xe5\x56\x21\x56\x67\x51"
+  "\xc3\x2a\xe8\x09\x37\xd9\x1b\xdc\xa2\x29\xd2\x23\x65\x33\xdb\xc0"
+  "\x85\x71\x03\x9e\xd7\x01\xcf\x23\x0f\xaf\xcf\xa1\x3f\x94\x53\xc2"
+  "\x3d\xca\x1e\xf7\x0d\xfd\xfd\x1f\x24\x3f\x6c\xd0\x24\x71\xbe\x23"
+  "\xd3\xa0\xd3\x20\xfb\x59\x66\x9e\xaf\x23\x6b\x45\xa0\xfa\x69\x62"
+  "\x5a\xd8\x9d\x61\xf1\x9f\xa0\xa3\xab\x2a\x42\xd7\x2d\x58\x7f\x83"
+  "\xf0\x75\x09\xaf\xaf\xfc\x2c\x35\x20\xbf\xaa\x42\x68\x5a\x5a\x46"
+  "\xbb\xa8\xc9\x38\xd1\xbd\x56\x84\xf7\x4a\xbb\xd7\xe1\xf2\xd3\x5d"
+  "\x0e\x35\x16\x29\x4d\x72\x5d\x67\xcb\x38\x01\x58\x69\x0c\xab\x05"
+  "\xf5\x23\x35\x19\x27\x51\xee\x80\x9f\x9a\xe5\x99\x01\xe4\xb9\xa9"
+  "\x74\x03\x65\x9c\x21\x87\x5f\xda\xf6\x9e\x8c\x2e\xd6\x0b\x48\xb3"
+  "\x21\xad\x0b\xf0\x03\x28\x8f\xf5\x71\x93\x5f\xd9\xba\x8e\x2e\xa3"
+  "\x1c\x9e\xbd\xfc\x1c\xc3\x43\xf2\x54\x83\x30\x5e\x8e\x81\xc3\x90"
+  "\x24\x9d\xad\x8c\x7f\x36\xfc\xe5\x24\xce\x1e\xd0\xeb\x23\xb3\x61"
+  "\x77\x91\xb3\x92\x32\x31\x3e\xc0\x6f\xdc\x52\x67\xb9\x38\x2d\xdc"
+  "\x8e\xd0\x5b\x1b\x42\x58\x17\x8c\x2b\xf1\xd3\x8b\x1d\x83\xdb\xcf"
+  "\xb0\x7b\x2e\x89\xce\xea\xb5\xfd\xb4\xfc\x6c\xc1\x7a\x4d\xf0\x33"
+  "\xeb\xa5\x06\xa4\x33\xdd\x00\xe7\x90\x41\xb3\xc1\xc7\x25\xa3\x53"
+  "\xad\x03\x6f\x1c\x2d\xdc\x82\xbc\xd7\xf3\xf9\xc1\x8d\xd7\x2a\x3a"
+  "\x8c\xf4\x76\x43\x9f\xf0\xfe\x68\x03\xe8\xbd\xda\x2e\x42\x3d\xee"
+  "\x1b\x61\xff\xdf\xe2\xd1\xf7\x62\x82\xbe\xf0\x1c\xd6\x31\x09\xe7"
+  "\x2f\x3e\x9f\x19\x80\xff\xad\xa9\xad\x99\xd0\x47\x52\x47\x2d\xda"
+  "\x5f\xa5\xf0\x0e\x31\x5c\x6f\xd5\x05\xea\x40\xfe\xea\xa0\xe8\x14"
+  "\x9e\x45\x75\xbc\xd6\xf0\xae\xed\xe5\xb4\x3b\xc0\xdb\xc2\xbb\x8a"
+  "\x71\xfa\xd6\x1d\xde\xeb\x7b\xe9\x34\xd6\x79\x58\xe3\x05\xd4\xbe"
+  "\xcc\xb7\x1c\x47\xcb\x48\xdf\xeb\xb9\xb1\xd1\x4f\x13\xf3\x0d\xbc"
+  "\xd8\xde\x00\x7d\x99\xd6\x4d\x6c\x77\xf0\x9e\xfb\xea\x0a\x11\x62"
+  "\xfb\x03\x65\x8f\x1b\x7d\xe0\xfe\xe9\xfd\xf2\x47\xf7\x0b\x38\x04"
+  "\xb0\x66\x96\x34\x58\xbd\x9e\x2c\x0e\x45\x6b\x0b\xf7\x97\xfb\xc2"
+  "\x7d\x96\x7d\x91\xba\x16\x73\x45\xf8\x0e\xac\xc1\x64\x7a\x5b\x8f"
+  "\xfb\x5b\x58\xff\xdc\x12\x54\x3c\x75\x63\x63\x3c\x1f\xf5\x8f\xa3"
+  "\x2d\xc5\xe5\xfc\x92\xae\x77\x6a\xe2\x14\x60\xbe\x0f\x3a\x25\xf3"
+  "\xaf\xc6\x36\x77\x88\xf9\x77\xdc\x61\x9e\x9b\x7d\x15\x17\xd9\xd6"
+  "\xe6\xb2\xa3\x50\xb6\x03\x65\xfe\x49\x2f\xfb\x4f\xea\xbc\x45\xfe"
+  "\x0e\xe3\x5f\xcc\x67\x95\xc0\xc3\x1b\x90\xf3\xfe\xa2\x42\xe3\x5d"
+  "\xe0\x1d\xbf\xe5\xa2\x66\xdc\xe1\xc4\xb8\x58\x5d\x3c\xaf\x45\x2e"
+  "\x89\x2e\xb4\xf3\x0d\xe6\x29\xe7\x7a\xfa\x26\xf8\xf2\xb3\xaa\x4a"
+  "\x1a\xc5\xfc\x24\xd2\x32\x82\x8a\xee\xe3\x53\x84\x1b\x76\x28\xb4"
+  "\x6a\xe9\x5a\xca\x80\x1c\x75\x9d\xa1\xf1\xe3\x0a\x2a\x1c\xc0\x95"
+  "\xa8\xfa\x1c\x91\xd4\x41\x69\x19\xd0\xc7\x9f\x53\xc3\x39\xde\x6f"
+  "\x19\x9f\x63\xf0\x22\x9e\x73\xaf\xa4\x2f\x30\xdf\xe8\xfb\x05\xe3"
+  "\xdf\xe7\xfd\xf5\x53\x34\x7e\x3f\xf7\x17\x7f\x49\x48\xdb\x25\x2e"
+  "\x89\xc5\x42\xcd\x6d\x01\x3f\x8d\x6f\xc3\xfc\x42\xf2\xcf\x4d\x85"
+  "\xea\x7d\x64\x00\xe5\xb6\x88\x4b\x9a\x4c\x47\x5a\xbd\x70\x27\xb1"
+  "\x4c\x1c\x41\xdb\xc7\xfc\x34\x63\x9a\x1a\x9b\xf1\x3b\x19\x56\x62"
+  "\x1c\x46\x06\x30\xb6\xc4\xbc\x79\x9a\x26\xdc\xea\xa8\x4a\x02\x1e"
+  "\x13\x86\x48\xb9\x00\xac\x06\x93\xd2\xdb\x1a\x70\xdd\xe7\xd6\x8a"
+  "\xa1\xa3\x8b\xb5\xda\xf1\xd9\xf2\x59\xcf\x13\xfa\x7c\x9a\x18\xfe"
+  "\xa2\xfd\xde\xb1\xcc\xe3\x13\xb6\x29\x38\x8b\xea\xbc\x63\xcf\xf0"
+  "\xfb\x76\x7e\x0f\xda\x26\x64\xfb\xea\x72\xd0\xfe\x19\x6e\x77\x9b"
+  "\xda\x07\x98\xb0\xbd\x1b\x6d\xf4\xb8\x27\x6c\xf3\xd3\xa4\x22\x75"
+  "\xd6\x30\x21\x7b\x10\xd9\xb3\xb1\xec\xb0\xcc\x29\x99\xfe\xf6\xbc"
+  "\x96\x46\x29\x7f\xfe\x6e\x5b\xaa\xa1\x37\x58\x36\x53\x4e\xd1\xb7"
+  "\x73\x5b\xec\x92\xbf\x4d\xc2\x34\xa1\xeb\x6d\x2d\x60\xe2\xf3\x20"
+  "\xa5\xbe\xbe\x9d\x7b\xf9\xdf\x4d\x50\x80\x37\x65\xe3\x6f\xba\xfe"
+  "\x3e\x17\x7f\x8b\xf1\x77\x10\xef\xd3\x25\xed\xf6\x14\x25\xf9\x91"
+  "\xd7\x0d\xfb\x9d\xdf\xfd\x74\x53\x96\xd8\x33\xde\x04\xfb\x44\x3e"
+  "\x37\x7c\x93\xf7\x12\x6e\x5a\x88\x31\x38\xa9\xc6\x82\xe1\x50\x12"
+  "\xe4\x91\xe9\x2e\x9c\x75\x22\xd4\x5c\x15\x04\xde\x37\x6d\x69\xae"
+  "\x0b\x92\xe3\x26\xee\xff\x4d\x5b\xb9\x4f\x41\xd0\x9f\x7f\x57\xd7"
+  "\x89\xc0\xd1\xfa\x30\xf1\xb9\x14\x60\x41\xfe\x7f\x34\x5b\xed\x4b"
+  "\x2c\xf2\x32\x3c\x9d\x27\x84\xd1\x7f\xa5\xd3\x26\x64\xf3\x58\x02"
+  "\xd6\xc7\xe8\xbb\xf5\x1c\x7d\xfb\x5a\x91\x3e\x3e\xfb\x68\x31\xd1"
+  "\x5e\xe8\x11\xcc\x35\x72\xbf\x1c\x7a\x89\x61\x62\xfe\x9f\x30\xdd"
+  "\x38\x47\xd9\x8e\xfc\x1d\xc8\xc3\xdc\x13\x68\x29\x0e\x11\xc3\x8a"
+  "\x70\xff\x50\xff\x03\x2d\x60\xc6\x5c\x8d\x31\x9f\x90\x5d\x55\x0a"
+  "\x3d\xd3\xaf\xb7\x6e\x3a\x52\x79\x56\x84\x8c\xfe\xf1\x59\x65\x8f"
+  "\xfb\xdb\xe0\xff\x15\x85\x83\xf2\x7f\x3f\xce\x59\x2b\x8e\x8e\x57"
+  "\x63\xa6\x81\x2e\xb1\x63\x96\x55\xac\xc6\xeb\xdb\xf5\xb1\xe3\x95"
+  "\x85\x9e\x7c\xbb\x03\x7f\x61\x3c\xa7\xa8\xf7\xe8\xbf\x6f\xb7\x45"
+  "\xbd\x83\x3b\xb2\x16\x02\x1f\xcc\xff\xe3\xf3\xd5\x38\x70\x3a\xfa"
+  "\xc1\x3c\xf2\x05\x59\x78\x7f\x8e\xcf\x29\x39\x9d\xf9\x99\xd3\x35"
+  "\xd8\x33\xe8\x4f\x00\xf9\x36\x96\xd5\x6a\x8d\x62\xf2\x7d\x5b\xc0"
+  "\x73\x1b\x7a\x19\xff\x7b\xe4\x9e\xe2\xa6\xad\x5b\x99\x4f\x51\x27"
+  "\x68\x0d\x6f\xdd\xda\xe3\xce\xca\x35\xe8\x8a\x7a\x53\x39\x9f\x79"
+  "\x12\xe9\x45\xa0\x4b\xa3\x3c\x87\xc4\xda\x2f\xb1\xad\x91\xb5\xb5"
+  "\xdf\x26\xb3\xa5\x16\xb2\x3e\xea\xa2\x9b\x77\x42\x67\x61\x6c\xc7"
+  "\x67\xa9\xb9\xe6\xe6\x5d\xfc\x0e\x5d\xf9\x19\x9e\x3d\x2d\xd0\x49"
+  "\xbd\xb5\x19\xf9\x7d\x26\x1a\xd6\x6b\xa2\x9c\x70\xed\xe6\x89\xe1"
+  "\xf4\x51\x45\xbe\xce\x43\xd4\x1a\xfe\x25\x39\x9e\x96\x30\x5e\xf2"
+  "\xa1\xe7\xce\xf5\x22\xf2\x4e\xef\x01\xb3\x2f\x7c\xde\x8b\xb9\xf9"
+  "\x86\x33\x74\xb3\xa4\xc7\x2b\xa7\x30\xeb\x3f\x21\x61\xeb\xf4\xd9"
+  "\x6c\xd9\xb1\x5c\x84\x77\x9c\x16\x41\xd8\x77\xc3\xb7\xf7\xd2\xc4"
+  "\xdd\x1b\x28\xbb\xbe\x97\xc6\xef\xeb\xa5\x2c\xf1\x97\x2c\x53\x3d"
+  "\xec\xb6\x27\x2e\xda\x58\x3f\xe4\xa7\x96\x92\x65\xdf\x06\x92\x3c"
+  "\x12\xa9\x81\xfd\x16\x86\xfd\x76\x3e\x8b\x75\x63\xbf\xfd\xd6\x27"
+  "\x6d\xe3\xcc\xc5\x8a\x8f\x32\x17\x8f\x2c\xa6\xa4\x94\x42\xb2\x01"
+  "\x3f\xe7\x39\xca\xfa\x63\x4a\x07\x6c\x47\xf4\xd9\xaf\xf7\x17\xb4"
+  "\x3b\x69\x2d\xa6\x61\xb2\xaf\xd0\xd7\xa2\x66\x7c\xd6\xa0\xf3\xb0"
+  "\x89\x79\x2a\xc8\xf2\xc0\x7d\xf8\x8c\xcf\x4a\x0f\x8d\x0d\x99\x57"
+  "\xd7\x8b\x10\xa7\x97\x8d\x13\x21\xa4\x1f\xe3\xb6\x9b\x90\xde\xe3"
+  "\xbe\x39\xe0\x37\x0f\x9b\x3a\x18\x8f\x62\x9d\xa4\xeb\x95\x5b\x9e"
+  "\x17\x26\x17\x78\x34\xb5\xb1\x32\x0c\xfb\xfb\x1c\xcb\xec\x2d\xa5"
+  "\x0b\x4a\x44\xd8\xb1\x92\xcf\xad\x6f\x29\xe4\x33\x75\x3e\x4b\x7b"
+  "\x1b\xb6\xcd\x57\x9d\xa3\xf3\x7c\xc1\xeb\x05\x6b\x09\x60\xd6\xa6"
+  "\x36\x0a\xac\xd3\xbf\xae\x1d\xcf\xbe\x1c\xaf\x4a\xbf\x91\x5b\x0e"
+  "\xfa\xe9\x87\x66\xc6\x9d\xcf\x4c\x59\x77\xc2\xde\x1a\x05\xbc\x3a"
+  "\x83\xa0\x03\xf2\x31\xff\x7f\xbf\x5d\x3f\xf7\x94\xfe\x28\x48\xc3"
+  "\xfc\x7f\x7f\x26\xa7\x95\x8d\x23\x7b\x99\x43\x74\x0e\x66\x33\x49"
+  "\x1f\x11\x13\x7d\xa3\xc7\xfd\x0f\xa3\x0d\x38\x98\xa7\x7e\xd6\x6d"
+  "\x7a\xf8\x61\xa4\x65\x19\x70\x50\xe6\x5a\xbc\x4f\xeb\x2f\xa3\xea"
+  "\xcc\x8d\xaa\xf3\x70\xb7\xe9\x96\x9f\x21\x6d\x71\x5c\x9d\x92\xb8"
+  "\x3a\x15\x51\x75\x5c\x7a\x3b\x9e\xb8\x3a\x8d\x71\x75\x9a\x12\xe0"
+  "\xd6\x1c\x57\xe7\x44\x5c\x9d\x8e\x04\xb8\x85\x62\xeb\x4c\xb4\xc4"
+  "\xd6\x99\x68\x8f\xa2\x25\xfb\x6b\x60\x7e\x9a\x38\x31\xae\xce\xf4"
+  "\xb8\x3a\xb9\xc6\xfb\x60\x3e\x39\xab\xf7\x92\x1d\xbc\xd9\xc9\xe3"
+  "\xf9\x2a\xc6\xa7\xfb\xf5\x67\x7a\xf4\xba\x5b\x2f\xef\xd7\xc4\xfa"
+  "\xb8\xf6\x0e\xc6\xb5\x77\xe4\xf2\x7e\x4d\x6c\x8b\xab\xe3\x8f\xab"
+  "\x13\x88\xaa\xd3\xa8\xda\x99\x64\x8e\xad\x33\x69\x74\x6c\x9d\x49"
+  "\xe3\x2f\xe7\xab\x49\xd3\xe2\xea\xcc\x8d\xab\x93\xff\x15\xb4\xe0"
+  "\x79\x5c\xf9\x4e\x8d\x61\x5b\xf9\x5e\xd8\x08\x93\x3e\x62\x9f\x80"
+  "\x6a\xb4\xf1\x56\x6f\x68\x08\x9f\x7f\xf0\x7c\x75\xb4\x3c\x04\x1d"
+  "\x3a\x09\xeb\x9f\xdb\x1d\xc6\x9c\xc5\xfe\x12\x2c\xd3\xca\xc6\x9e"
+  "\xb4\x75\x30\x5b\x94\xdb\x31\x7c\xa9\xb8\xad\xa3\x99\x3c\x4f\x4d"
+  "\x0a\xf6\xdb\xc4\xca\xbf\x88\x14\x9c\xc9\xf7\x33\x1c\x6e\xbf\x41"
+  "\xf9\x61\x24\xb1\x4d\x7e\xb4\x9c\xeb\x4c\xce\x8a\xb2\xa3\xb9\xfd"
+  "\xe0\xa1\x0d\x21\x73\x2c\x1e\x93\x2d\x57\xc0\x23\x05\xb6\xd1\xd6"
+  "\xd6\x7a\x22\x3e\x63\x6e\xa9\x87\x0d\x04\xbb\x9f\x71\x3b\x45\x93"
+  "\x3d\xd2\x26\x5b\xd9\x4b\xfc\xec\xab\xb8\x4b\x9e\x41\x2b\x9b\x74"
+  "\xf2\xb1\x66\xb4\xcf\xb6\x7b\x73\xe9\x05\xea\x96\xf3\x2f\xdb\x6e"
+  "\x93\x2f\x1e\xad\x08\x30\x5e\x5e\xc3\x3f\xc3\x4f\x93\x83\xd2\xd6"
+  "\xf0\x2c\x72\xf1\xf9\x38\x9f\x19\x1d\x0d\x4e\xe3\x32\xe0\xff\x49"
+  "\xc7\x8d\xfe\x62\xae\x07\x0f\x4c\xae\xbf\x12\xcd\xd4\x18\x4e\xc9"
+  "\x8c\xe5\xc9\x21\xe0\x95\x29\xd9\xb1\xe3\x3e\x25\x27\x76\xdc\xa7"
+  "\xe4\xc5\xf2\xa4\x09\x3c\x39\xa5\x28\xae\x4e\x59\x5c\x9d\x2d\x51"
+  "\x75\x3c\x7a\x3b\x75\x71\x75\x0e\xc4\xd5\x39\x1c\xf5\x8e\x3e\x4e"
+  "\x39\xd6\xbf\xf6\x91\xbe\x3f\x53\xda\xa3\xde\x4d\x3b\xa5\xfe\x9c"
+  "\xd2\x65\xa4\xf1\x1e\xd2\xbe\xd7\x94\xef\x89\x82\x97\x6d\x89\x93"
+  "\x77\x94\xcf\xce\x8c\xc5\x21\x7b\x62\x2c\x0e\xd9\xfd\xf2\x5f\xad"
+  "\xd6\x6e\xbf\x3f\x4d\xb7\x8e\x96\x3c\x04\x19\xc1\x9c\xbd\x80\xdf"
+  "\x01\xab\x0e\xe5\x41\x87\xec\x92\x38\x78\x15\x71\xf0\xb6\x45\xbd"
+  "\xdb\xf0\x5e\x1f\xd5\x07\x5b\xb2\x5d\xfa\xf1\xc1\x7e\xcb\x3e\x64"
+  "\xa4\xf3\x9a\x12\xf8\x76\x3a\xe5\x5c\x93\xc3\x3e\x55\xe9\xa7\x28"
+  "\xfb\x4d\x5e\x7f\xea\x30\xa3\xe5\x9f\xf4\x7e\x05\x63\xf1\xb8\xd5"
+  "\x1c\x8b\xc7\xad\xa3\xa3\xfa\x15\xb4\x6e\xa2\x07\xac\xe1\x07\x1f"
+  "\x65\xdb\x87\x7d\xe1\xa4\x6f\x53\x25\x6c\xb6\x8b\x64\x63\x9f\xb2"
+  "\xd3\x65\x94\xec\x2b\xef\xc4\x5a\x2e\x33\x7f\x50\x7e\x4a\x5f\xe4"
+  "\xd1\xfd\xf2\x1c\x80\x5f\x66\xf0\xa3\x56\xbb\xc8\xa3\xd5\x7c\x0b"
+  "\xf3\xf2\xad\xd0\x7f\x53\x48\xd9\xb9\x37\xe6\x09\x67\x7e\x1d\xe8"
+  "\x89\x75\xd1\x6d\x6b\xf4\x75\x04\x9f\xb3\xb3\x4f\x4e\x27\xe6\xf8"
+  "\x14\x75\x36\x7e\xeb\x91\x28\xbe\xc6\x1a\x6e\xa6\x38\x45\xb7\x6d"
+  "\x62\x1b\x80\x65\x94\x7d\xac\x8e\x86\x03\xc4\x6b\x6f\x5f\xf8\x8c"
+  "\xb4\xdd\x90\xef\xd2\xeb\x86\xa2\xea\x06\xf4\xb5\x31\xcf\xa3\xe6"
+  "\x29\x61\x32\x1f\x0d\x06\x08\x70\x46\x2b\x7b\xef\xb6\x4d\x47\x21"
+  "\xaf\x3d\xee\xdb\x26\x1a\x75\x78\x1d\xcd\x75\xac\x65\x64\x9e\x5c"
+  "\x41\x66\xef\x86\x53\x12\xb6\x3e\xf6\x9d\xb0\xa5\xbb\x7c\x15\x9d"
+  "\xe4\x0b\xb6\xf3\x5e\x97\x59\xf9\xa9\xdc\xe6\x4a\x0e\x91\xa5\xbb"
+  "\x66\x91\xcb\x8f\xe7\x48\xcd\xa2\xad\xc0\x0d\xf3\xdb\xad\xfb\x59"
+  "\xdf\x44\xd3\x6e\xce\x9c\xbc\x07\x17\xcc\x9b\xb4\xe8\xc1\xfb\x17"
+  "\xce\xb9\xcb\xb1\x70\xc5\xb3\xcb\x8a\x26\x3d\xb7\xa6\xcc\xb1\x6e"
+  "\xd5\x8a\xb2\x15\x2b\x7f\xe4\xc8\x2e\x9f\x50\xee\x58\x5a\xa6\x7e"
+  "\xb3\x4a\x96\xae\x2e\x9b\xc1\x8f\x13\x1d\xa5\xab\x96\xad\x95\x8f"
+  "\x37\x0f\xa7\x58\x20\x2b\xca\x96\xad\x72\x4c\x28\x9a\xe8\xb8\x6f"
+  "\xe9\x8a\x92\x35\xab\x96\x25\x84\x75\x97\x63\xd5\xb2\x55\xcb\x96"
+  "\x16\x39\x66\x38\xb2\x19\x72\x34\xb8\xa8\xf1\xcc\x36\xe6\x31\x9e"
+  "\xbf\xaa\xdd\xa2\x4d\x9f\xcf\xfc\x8a\x7f\x6e\x5f\x78\xf9\x5c\x76"
+  "\x7b\x71\x2c\xcf\xdd\x5e\x1e\xcb\x73\xb7\x6f\xbd\x7c\x2e\xbb\x3d"
+  "\x6e\xfe\xbb\x3d\x6e\xfe\xbb\xfd\xc8\xe5\x73\xd9\xed\x71\xf3\xdf"
+  "\xed\x71\xf3\xdf\xed\xfd\xf3\x1f\x78\x49\xfa\x8f\xf5\xb8\xa7\xc6"
+  "\xcd\x7f\x53\xe3\xe6\xbf\xa9\xe3\xe3\xde\xa7\x46\xbd\x8f\xc2\xfb"
+  "\xec\xe8\xf9\x11\xef\x0b\x0d\xf9\x1c\xd0\x2f\x53\x8b\x8d\x32\xac"
+  "\xeb\xa1\x9b\x3b\xf4\xb2\xae\xa8\xb2\x9d\x7a\xd9\x9d\xfd\xf2\xc7"
+  "\x67\xdf\x48\x57\xeb\xf5\xa9\x5f\xb2\x4e\x67\x3f\x34\x9e\x9b\x20"
+  "\x1f\x37\x9c\xa3\xa9\xcf\x33\x2c\xe6\x61\xf6\x4b\x14\xaf\x3f\xde"
+  "\xd3\x90\x4e\x16\xae\xd3\x50\x4b\x66\xe1\xbe\x6d\x1b\x7e\x09\x69"
+  "\x29\xf8\x83\x4e\x99\x0a\xfb\xd7\x62\x56\xf3\xc5\x1d\x39\xd2\xe6"
+  "\x47\x1d\x05\xff\x0e\xb9\xae\x01\x1c\x3b\xea\x58\xaa\xd5\x5c\xdc"
+  "\x81\xe7\x14\xe6\x69\xd4\x37\x0b\xd3\x6d\xff\x86\x5f\x42\x9a\x0d"
+  "\x7f\xa3\x7b\xdc\x77\xe4\x18\xf0\xf8\x8c\x3c\x91\xfc\xc7\xdb\xb9"
+  "\xfd\xeb\x41\x13\x59\xab\xdd\x5a\xbb\x4f\x63\xdb\xfa\x8e\x32\xb5"
+  "\xb7\x90\x51\x2e\xdc\x1f\xe6\x37\x20\x3d\xf1\x3a\xe9\x0e\xd8\x7f"
+  "\x77\x14\xab\xfd\x96\x3b\x30\xfe\x3f\xdc\xa9\xf6\x4e\x33\xca\xa1"
+  "\x6f\x7b\x4f\xd3\x77\x1e\xc6\x6f\x1f\x7e\xef\x34\xe0\x7b\xe5\x7a"
+  "\xfb\x8e\x13\xc2\x9d\xf4\x10\xc3\x8d\x4b\xef\x82\x7e\xeb\xb5\x86"
+  "\x5d\xf9\x97\xe7\x7d\x07\x6b\x98\xe4\x07\x13\xa4\xf3\x9e\x7f\xaf"
+  "\x9f\xbe\xb3\x90\xf1\x8d\x4a\x9f\x26\xdc\xa9\x0b\xb9\xbc\x9f\xdb"
+  "\x43\x9d\xc1\x6c\x6d\xc3\xef\x54\xf9\x89\x7f\x67\x4b\x5c\x3f\xbe"
+  "\x3c\x4d\xdf\x4d\x52\xfd\xf8\xee\x92\xb8\xb6\xeb\x13\xf7\xe3\x3b"
+  "\x87\xd0\x8f\x2f\x07\xe9\x47\x9b\xa4\xad\x09\x7d\x31\x5d\x96\xc7"
+  "\xf6\xcf\x97\x92\xee\x31\xe9\xdf\x35\xeb\xb6\x50\x10\xeb\x30\x1b"
+  "\xf2\x64\xdd\x87\x2a\x06\xc6\x4d\x2f\x37\xd1\x5a\x47\x79\x97\xb7"
+  "\xf9\xdd\xd9\xc2\x3d\xec\x21\x3f\x7d\xb7\x42\xc2\x19\x48\x5f\xac"
+  "\x70\x01\x9d\x4c\x4c\x27\xf4\x07\xf5\x06\x1b\x6f\x63\x5d\xa2\xf6"
+  "\x42\xbe\x0b\xf9\xff\x4e\xa1\xb1\x97\xb9\xba\x42\x04\x0c\x3a\x22"
+  "\xef\x58\x5c\x5e\x28\x2a\xaf\x23\x26\xaf\xb2\x3f\x3d\x6c\xa4\x7f"
+  "\xbd\x71\x9a\x36\x31\x6e\x9c\x30\x3e\xd3\x3e\x88\xed\xf7\xb4\xe9"
+  "\xaa\x7f\x18\xa3\xcb\x68\x3d\x2d\x1f\x63\xd4\x97\x78\x8c\xa6\x95"
+  "\x25\xe6\xb5\x69\x72\x1f\x4d\xa4\x53\x22\x78\x07\x30\x76\x7d\x92"
+  "\x07\xf5\x71\xba\x7c\x7c\xa6\x1d\x37\xc6\xe7\xeb\xf5\xf1\x4e\x5b"
+  "\x5c\x1f\x23\xa7\xe9\xce\xed\xaa\xaf\x77\x7e\x12\x0b\xfb\xce\xac"
+  "\xc4\xbc\x78\x67\x0e\xfa\x19\x49\xdc\xcf\x3b\x17\x0f\xce\x8b\x77"
+  "\x42\xf6\x29\x72\x39\x2f\xde\xa9\x7c\x98\x74\x1e\x8c\xcb\x3b\x28"
+  "\xdc\x09\xdb\x69\x76\x86\xd9\xce\xbd\x33\xcc\xfb\x4b\x51\xe9\x27"
+  "\x63\xf9\x0f\x7d\xe0\x7a\x4c\xbf\xb0\xd2\xb3\x3c\x0e\xa7\x1d\x64"
+  "\xfa\x2a\x9e\xec\x71\xdf\x35\x3d\x8e\x56\xe7\x4f\xd3\x5d\x1f\x74"
+  "\x9b\x92\xf6\x2b\x7a\x7d\x6f\x53\x2c\x4e\x77\xe5\x27\xa6\xd7\x5d"
+  "\xa5\xa0\xd7\xf9\xc4\xf4\xba\x6b\xdb\xe0\xf4\xba\x8b\xc7\xff\xfc"
+  "\xe5\xf4\xba\xcb\x1b\x4d\x2f\xd8\xba\xb2\x7f\xdf\xb2\x83\x37\xfa"
+  "\x0a\x44\x03\xf7\x35\x42\x36\x2b\x78\x45\xd5\xe9\xe2\x3a\x41\x6b"
+  "\x48\xf1\x09\x6c\x48\xcb\x39\xba\xeb\xa4\x21\xff\xa9\x75\x34\x4c"
+  "\xf4\x3d\xce\x3e\x45\x49\x5c\xcf\x57\x7e\xde\xeb\x0b\x67\x13\xaf"
+  "\x3f\x62\xdb\xfd\xde\xb4\xc4\xba\xe0\x7b\x79\xa0\x69\x6d\x82\xf4"
+  "\x62\xe5\x4f\xf6\xbd\xc6\x58\x1d\xf1\x3d\x57\xec\x18\x81\x6e\xa8"
+  "\x47\x03\x77\x70\xae\xf8\x77\xe5\x31\xfb\x5e\xe0\xf2\x31\x9b\x5e"
+  "\xa3\xc6\x6b\xfa\xf3\xb1\xf8\x4d\xb7\x24\x1e\xaf\xe9\x8e\xc1\xc7"
+  "\x6b\xfa\xf4\xc1\xc7\x6b\x7a\x3e\x8f\x97\x9f\xa6\x7b\x62\xe7\x8d"
+  "\xe9\xa5\xb1\xfd\x9d\x2e\x65\x58\x98\x86\x8e\xe2\xf7\xaf\xdb\x6f"
+  "\xe3\x8f\x75\x1c\x8f\x55\x43\x15\x81\x97\x93\xc6\x31\x8e\x57\x0b"
+  "\x63\x50\xd8\xa0\xa1\x67\x43\xe2\xf3\x56\x5e\xe3\xb6\xd6\x11\xf1"
+  "\x39\xb2\xe3\x7a\xb6\xdd\x67\x2c\xd3\x4c\xd4\x8e\x67\xd3\x69\x9a"
+  "\x79\xab\x66\x32\x55\xf0\x99\xa7\xf4\xdd\x96\x7b\x08\x33\x2a\xa2"
+  "\xc7\x82\xcf\x3e\x79\x6d\xba\x43\xad\x9d\x3e\x3d\x4d\x77\x0f\x51"
+  "\xe3\x32\x33\x2d\x96\x8e\x33\x1a\x13\x8f\xcb\x8c\xc3\x18\x97\x4f"
+  "\x13\x8f\xcb\x8c\x13\x83\x8f\xcb\x8c\x00\xc6\xe5\xd3\xcb\xe5\xe8"
+  "\x6e\x8b\x2e\x47\x9b\xb9\x8e\x63\x25\xaf\xc7\xef\x5e\xcf\x65\xf0"
+  "\x0c\x19\xb9\x7b\x29\xe7\x4f\xea\x32\xe4\x48\xd6\x99\x0e\x58\xb2"
+  "\x7d\xbd\xcc\x34\x1d\x46\x34\xdc\x42\x6b\x57\x22\x39\xb9\xbb\x9c"
+  "\xcb\x4e\x2e\x25\x0b\x68\x98\xbf\x97\x61\xac\x22\x02\x8c\x16\x2e"
+  "\xc7\xe9\x58\xe1\x47\xc9\xc9\xdd\x07\x8c\x72\xac\xeb\xf4\xb2\x8d"
+  "\xa2\xa7\x98\x77\x02\xe2\xdb\xd4\xfb\x3f\x4c\xce\x23\x5c\x9e\xcb"
+  "\xc5\x95\x09\x29\x79\x9c\x39\x3d\x56\x1e\x67\xda\x62\xf9\x13\xf4"
+  "\x47\x3d\x0d\x7a\x0e\xcf\x45\xc0\xe1\x6b\xf3\xd7\x95\x65\x73\xe6"
+  "\xb6\x38\xd9\x04\x0f\xe4\x4c\x52\x3c\x90\x33\x32\x16\xd7\x99\xfb"
+  "\x13\xf3\xc0\xcc\x23\x83\xf3\xc0\xcc\xf6\xc1\x79\x60\x66\x90\x79"
+  "\xc0\x4f\x39\x13\x63\x65\x33\x27\x25\xb6\xef\x68\x57\xca\x26\xa5"
+  "\x5d\x8d\x6c\xc2\x16\x1a\x35\x98\x1c\xb2\x4c\xb1\x0f\x49\x43\xaf"
+  "\x71\xd6\xf1\xb5\x68\x66\x81\x5c\x31\x7e\x5e\xde\x53\x82\x8e\x9f"
+  "\xc6\x34\xdc\x27\xef\x06\xe6\x9c\x88\xa6\xe3\x0e\x75\x7f\xcd\x79"
+  "\x9a\xee\x79\x94\xcf\x95\x15\x3d\xef\x1d\x17\xdb\xff\x9c\x60\x62"
+  "\x7a\xde\x93\x02\x7a\x3a\x13\xd3\xf3\x9e\xac\xc1\xe9\x79\xcf\x6c"
+  "\xbe\x1b\x74\xb9\x4c\xdd\xb3\xd8\xb1\x56\xda\x28\xb2\xce\x39\xba"
+  "\xe7\xbd\xaf\x37\x3f\xdd\xb3\x33\x76\x7e\xba\xa7\xe2\xea\xe7\xa7"
+  "\x7b\xda\x13\xcf\x4f\xf7\x04\x12\xcf\x4f\xf7\x5a\x94\x3c\xdc\x9b"
+  "\x13\x2b\x0f\xf7\x3a\x62\x79\x22\x27\xf8\xdf\x37\x3f\xdd\xeb\x89"
+  "\x93\x81\xea\xd3\x34\x2b\x0d\x36\x85\x4b\x8d\xdb\xac\x8f\xe3\x70"
+  "\x3c\x98\x78\xdc\xee\x6d\xc6\xb8\x55\x27\x1e\xb7\x7b\xfd\x83\x8f"
+  "\xdb\xbd\x61\x8c\x5b\xf5\xe5\xe3\x36\x6b\xf4\xd5\xdb\x14\xb3\xe6"
+  "\xc6\x8e\xd9\xac\xec\xab\x1f\xb3\x59\xdb\x12\x8f\xd9\xac\xfd\x89"
+  "\xc7\x6c\xd6\x11\x35\x66\xb3\x82\xb1\x63\x36\xeb\x44\xec\x98\x81"
+  "\x6e\x7f\xe3\x98\x61\x7c\x2a\x94\x7f\xc2\xec\x87\xb1\x6e\x1f\xd6"
+  "\xe3\x9e\x9d\xeb\xa7\x39\xa3\xd5\xda\x7a\x8e\x9a\x3b\xd4\x18\xbe"
+  "\x83\x32\x39\x97\xcf\x03\xb3\x8b\xf5\xb4\x45\x97\x8f\xc3\xec\x2d"
+  "\xd0\xd1\x5d\xcd\x15\xf2\x6c\x4b\x8d\x21\xd3\x1c\xe5\xbc\x1b\xf8"
+  "\x7c\x6a\xb6\xf4\x5f\xc7\x18\x0b\x5f\x28\x4c\xac\xd7\x51\x3e\xc8"
+  "\x70\xf8\x4e\x64\x1c\xac\xb6\xab\x99\xe3\xaf\xe0\x53\x53\xe1\xad"
+  "\xba\x0d\xf0\xe6\x7c\xae\x78\x75\x4e\xbc\xfd\xdb\x80\xbc\xf7\x15"
+  "\x9f\x7e\xff\x85\x58\x1c\xe6\x2c\x4c\xcc\xa7\x73\x4a\xd0\x87\x86"
+  "\xc4\x7c\x3a\x67\xeb\xe0\x7c\x3a\x07\xe3\x4f\x0d\x51\x6b\x9f\xf4"
+  "\x27\xc2\xfe\xb8\xb5\xcf\x9c\x63\xd6\xa0\xe2\x1d\x69\x13\xd5\x64"
+  "\x54\x00\xe7\x78\xfb\x0f\x63\x73\xdf\xb3\x3a\xce\xcb\x62\xeb\xdf"
+  "\x37\x88\xfd\x77\x1f\xdb\x7f\xef\x24\xc6\xf9\xbe\x2b\xd8\x7f\xf7"
+  "\xb1\xfd\xf7\xce\xe5\xb2\x75\x9f\x6e\xff\x25\x5a\xe3\xdd\xb7\x2d"
+  "\xf1\xf8\xdf\x17\x37\xfe\x94\x5f\x86\xf5\xb0\xac\x1f\x5b\xee\x78"
+  "\x74\x39\xf6\x4d\xe2\xb2\xcc\x23\x09\xca\x86\xe2\x61\x26\x2e\xf7"
+  "\x7d\xc7\x65\xbc\xc7\xbe\x54\x09\x79\xef\xfb\xb9\x4a\x1e\xbf\xbf"
+  "\x3f\x56\x1e\xbf\x5f\x14\x2b\x8f\xf7\xc5\x8d\xdd\xf7\xb7\xc4\xe6"
+  "\x83\x7f\xfe\xdb\x74\xec\xf7\x83\x71\x3c\xf0\xe1\x69\x9a\xfb\xbc"
+  "\xe2\x81\xb9\x7f\x8c\xc5\x63\x6e\x4a\x62\x1e\x98\x3b\x1e\xfd\xff"
+  "\x30\x31\x0f\xcc\xcd\x19\x9c\x07\xe6\xb2\x8f\xcf\x87\xd1\x7c\xfb"
+  "\x50\x45\xce\xb0\xb8\x32\xae\xc4\x3a\x6f\x6e\x5d\xe2\x3d\x82\xb9"
+  "\x4d\x8a\xc6\x73\x3b\x63\x69\x3c\xf7\x58\x2c\x0d\xd1\x97\xbf\x9d"
+  "\x86\xfd\xb1\x09\x7a\xdc\xf7\xc7\xcb\xbf\xef\x34\xdd\xaf\xcb\xff"
+  "\x0f\xde\x8d\xc5\xf1\xfe\x85\x0a\x97\x44\xfb\x22\xf7\xf3\xfa\xd7"
+  "\x97\x98\x96\xf7\x6f\x4b\xdc\xe7\xfb\xf7\x63\x0e\xf2\x69\x97\xc9"
+  "\xd2\xfd\x47\x90\xfe\x10\xef\x87\xf2\x7e\xc8\x3e\xa4\x3f\x14\x26"
+  "\x8b\x9c\xaf\xfa\xe7\xa5\xfb\xfd\xec\x8b\xc2\xf4\x67\xfe\xb5\x66"
+  "\x52\x1e\xcf\x41\x8c\x57\x41\x85\xf4\x5b\xb0\x6e\x61\x5e\xbf\x91"
+  "\x79\xfd\x07\xd2\xfe\xe3\x73\x16\xf6\x23\xb4\x96\x53\x9e\x2f\x18"
+  "\x26\x83\xdf\xb9\x7c\x2c\xec\x1f\x4c\x67\xb9\xe0\xf2\x46\x59\xb5"
+  "\x6f\xe6\x8a\xe3\xef\x1f\x14\x25\x1e\xe3\x1f\x54\x0c\xce\x3b\x3f"
+  "\xa8\x53\xe3\xfc\x83\xe3\xb1\xe3\xfc\x83\x26\xcd\x9d\xba\x90\xfb"
+  "\xea\x07\x9d\xaf\x66\x8c\xcb\x1c\x22\xa1\x3f\x8a\xd4\xf7\x9b\x1f"
+  "\x6f\x2f\xad\xa2\xeb\xcf\xd0\x0f\xa7\xca\xf6\x4c\x22\x64\xdd\x94"
+  "\x44\xcd\x52\x07\xfc\xf0\x25\x89\x27\xca\x14\x84\xc9\x24\x36\x3f"
+  "\xd3\xce\x79\x0d\x6e\x11\x42\xb9\x36\x3e\x13\xe0\x3b\xc5\xe0\x85"
+  "\x51\xa7\xe8\x87\xf3\x62\xea\x9b\x89\x7c\x0a\xc6\xd6\x06\x29\x8f"
+  "\x3f\xdc\x62\xec\xe9\x6e\xc1\x7b\xe2\x7d\xdf\x1f\x1e\x30\x7c\x1f"
+  "\x94\xcf\xd8\x0f\x07\x3d\xbf\x64\x9c\xf8\xde\x0c\xe3\x74\x65\x3d"
+  "\xf0\xc3\xb0\xc1\xbf\xca\xd7\x32\x37\x65\xc0\x97\x2f\xd7\x8e\x3c"
+  "\xef\x15\xf6\x06\xa3\xe4\x20\x77\x76\x34\x1c\x15\x9f\x23\x37\xdf"
+  "\xf0\xc7\xc3\x73\xd1\x57\xc0\xd2\xf1\xc9\xdd\x16\x87\x4f\x3d\xec"
+  "\x94\x32\x1d\xc6\x81\x2b\xc1\xe0\x31\x57\x3c\xcb\xfc\x90\xeb\xbd"
+  "\xd2\x9e\x5f\xb2\x9d\xf2\x5e\xbd\x8c\xb7\x72\xa5\xbd\xc4\x30\xae"
+  "\x8c\xe3\xbc\xec\x98\xb5\x85\x3c\xbb\xe7\xb3\xad\x79\x11\x25\xf7"
+  "\xf3\xe2\xf6\x08\xe7\xe5\x4a\x7f\x2a\x5d\xee\x9f\x08\xc7\xcb\xc1"
+  "\xbc\x12\x63\x8e\x8e\x4b\xdf\x62\xc8\x3d\xd6\xb5\x0c\x37\x6e\x9f"
+  "\x75\xde\x7e\x25\x0b\xf3\xc2\x5a\x5a\xf4\x7a\x6d\x9e\xb4\xff\x8c"
+  "\xfd\x52\xe4\xef\x8f\xab\x17\xb7\xff\x37\x2f\x57\x0c\xbe\x4f\x9f"
+  "\x82\xf1\x0d\xf2\xd9\x96\x8a\x51\x30\x7f\x62\xdc\x7e\x45\x60\x87"
+  "\xbc\x83\xfe\x67\xc0\x9d\xaf\xeb\xbd\x05\x6f\xc6\xb6\x37\x3f\xd7"
+  "\x79\xf6\x4a\xfd\x9f\x3f\x48\xff\xe7\x0f\xf4\x7f\xa5\x84\x1b\xb7"
+  "\x97\x38\x5f\xf6\x3f\x72\x99\xfe\x9b\x7f\x04\xfa\xcb\xa0\x1b\x6c"
+  "\xee\x05\xd7\x1a\xb6\x3a\xef\x1f\x0c\x6e\xab\xcf\x1f\xd8\xff\x93"
+  "\xf5\xe6\x0f\xec\xff\x05\x12\xd9\xea\x7e\x92\x67\xab\x31\x6d\x2f"
+  "\x98\x66\xad\x4f\xd4\x97\x05\x83\xec\xff\x2d\xd0\xf7\xff\x16\x78"
+  "\x63\xf5\xd9\x02\x57\xec\x18\xce\x8f\x1b\xc3\x05\x8d\xb1\x63\x38"
+  "\x3f\xf7\xbf\x3a\xaf\xe1\x9d\x92\x93\x93\x4d\xc9\x49\xa6\xa4\x64"
+  "\x64\xa3\x8b\x34\x2c\xd9\x9c\x3c\x04\x7f\x43\xf5\xdf\x61\xa6\x64"
+  "\x93\x19\x7f\x43\xf4\xdf\xa1\x71\xef\xc3\xb8\x2e\xfe\xcc\xfa\xef"
+  "\x90\xb8\xf7\xa1\x5f\x91\x3f\x4c\x6f\xd7\x68\xdf\x1c\xf7\x3e\xe4"
+  "\x2b\xf2\x87\xfe\x8d\xf5\xe9\xb2\xf7\x58\x3f\xb4\xfb\x57\xae\x5d"
+  "\x5a\xb2\xa2\x48\x9e\x17\x2f\x73\x2c\x7d\xea\xa9\x65\xab\x57\x3b"
+  "\xca\x9e\x73\xdc\x7b\xcf\x83\xb7\xdd\xe5\x50\xc7\xce\x25\x33\x26"
+  "\x14\x0d\xa7\x79\xeb\x56\x71\xc6\xbc\x87\xee\xcf\x77\xe4\xdd\x7b"
+  "\x4f\x6c\xa6\x01\x46\x1e\x2f\x5f\x09\x4a\x94\xfc\xe5\xbc\x34\x86"
+  "\x68\xdb\x18\xa9\x7b\x3a\xd8\xcf\x57\xed\x79\x3c\x92\x76\x1c\xdc"
+  "\x2f\x7a\x9d\xc2\x7b\x23\x9f\xe9\x3f\xf0\x07\xee\xc4\xa4\x46\x17"
+  "\x95\x2e\xe7\xfb\x2b\x0f\x7c\x26\x7e\x17\x20\xc7\x0f\xc8\x74\x8a"
+  "\x1e\x1f\xd7\x3c\x17\x65\xf1\xee\xeb\x08\x93\xc3\x49\x96\xd3\xf4"
+  "\xf0\x47\xc8\x4b\x12\x77\x6b\x48\x0b\xea\xbe\xd0\x0b\xff\x4d\xa6"
+  "\xfd\xce\x65\x94\xb3\x9e\xa6\x07\x5f\x10\xbf\x13\xf2\x9d\xef\x09"
+  "\xa9\x72\x0f\x3e\xaa\xb9\x1f\xb0\xb3\x6e\xa8\xaf\x25\xf3\xbe\x5a"
+  "\xa2\x37\xd2\xc9\xf2\xc6\x18\x8e\xd5\xf1\x60\xae\x71\x16\xfa\x12"
+  "\xde\xfd\xf4\xb8\x83\xdb\xe6\xb2\x9a\xe9\x81\x7b\x65\xf9\xf4\x98"
+  "\xf2\x15\x03\x67\xb1\x0f\xe6\x9a\x50\x6e\xc1\xe7\x64\x0d\xa5\x8f"
+  "\xca\xf7\x55\xb8\xc8\x1a\x11\x5f\x4c\x9e\x4b\x49\xad\xb0\x84\xd7"
+  "\x87\x45\xd8\xbb\xea\x0c\xb7\xff\x47\xeb\x7a\xf1\x85\x0f\xda\x7a"
+  "\x5e\x97\x53\xec\x38\x4b\x66\xc8\x75\x92\x77\x15\xfb\x29\x3c\xd8"
+  "\xb4\xef\x4b\x32\x83\x06\x99\x67\xe8\x21\x7f\xc5\x3c\x11\x71\xce"
+  "\x23\xf3\xbf\x94\xb3\xcf\x61\xc6\xa5\x1d\x7f\x22\xf3\xcf\x7b\x5d"
+  "\xa6\x5e\x61\xa7\x8a\x32\xd1\x29\x38\x86\x4f\x50\x84\xd8\xcf\xff"
+  "\x78\x61\x84\xcb\x9c\xee\x71\xda\xa9\xb5\x2c\x48\x95\x27\x45\x68"
+  "\xeb\x9f\xd4\xfd\x80\x96\xae\x20\xfb\x30\x5a\x2a\xe7\x51\xf2\xe9"
+  "\x7c\x32\xb5\x14\xd7\x91\x6f\x71\x90\x2a\x4e\x8a\xce\xe3\x85\x9f"
+  "\x53\x6b\x71\x13\x15\xb4\x93\xe9\x78\xc7\x27\x24\xe3\xd0\xd4\x6e"
+  "\x76\x54\x5d\x24\x7b\xe5\x0a\x4e\xbb\x48\x1b\x2a\x69\xe4\x86\x8f"
+  "\xc9\xea\xeb\x6c\x47\x3b\x67\xe9\xb1\x13\x94\x04\x78\xa6\x8d\x9f"
+  "\x90\x7d\xe3\xa3\xec\xeb\x9b\x43\xf5\x55\x64\x17\xce\xac\x94\x5e"
+  "\x67\x96\xad\x57\x64\xa5\xf7\x38\xb3\x46\xb7\x96\xa2\x7c\xc7\x07"
+  "\x94\xda\x4e\xa3\x7f\x77\xa6\xdd\x54\x77\x81\x32\x1d\xf3\x79\xfc"
+  "\x1f\x3a\x59\x7f\x01\xe5\x6b\xf3\xdb\x34\xd4\x8d\xae\x13\x4e\xcb"
+  "\xef\xf4\xe5\x87\x48\x03\xac\xba\x5e\xca\xac\xef\x25\xbb\x56\x93"
+  "\xdf\xc6\xb4\xe8\xab\xcd\xc8\x87\x2e\x1c\xf6\xce\x93\x87\xcd\xbe"
+  "\xe3\x5d\xd4\x12\xec\xa5\x56\xfa\x33\xf9\xca\xff\xe2\xfd\xf9\x93"
+  "\x87\x87\x68\x60\x7e\xef\x86\x0e\xc0\x57\x3c\xe3\x6c\xe1\xfb\xca"
+  "\x2e\xaa\xae\xa2\x94\xd2\x0d\x34\xec\x0c\xd2\xd5\x9a\x3e\xb5\xd0"
+  "\x17\xfe\x8b\x77\x83\xf4\xc3\x7d\xdc\x51\xd5\x42\xc9\xad\xc1\x3a"
+  "\xf6\xf7\x34\x45\xd2\x37\x3b\x7c\xc1\x36\xf2\x95\x7e\xea\xd5\x6c"
+  "\x9b\x2d\xdb\x34\xb2\xfc\xe2\x52\x9b\xc9\x67\xbe\x44\xbe\xfc\x20"
+  "\x7d\x88\xb6\x45\xed\xe6\x89\xd0\x57\x39\xad\xc1\x10\xdf\x73\xca"
+  "\x16\xdd\xf6\xe1\xd5\xab\x68\xe2\xbe\x0b\x34\x7e\xef\x05\xca\x12"
+  "\x3d\x59\x26\xf6\xad\xe5\xfb\xa9\x7b\xf1\x9b\xd2\x41\x16\xf4\x57"
+  "\xf9\x61\xa7\xe9\x3e\xb6\x7d\x59\xd4\xd0\x3b\xe0\x63\xdb\xdb\x3d"
+  "\xe0\x63\x0b\x5e\xca\x63\x3f\xdb\x53\xf4\xa0\x85\xf9\xb9\xfa\x1c"
+  "\x99\x37\x9f\x23\x9a\xec\x32\x91\xe3\x49\xbe\x57\xf1\xf0\x7b\xbe"
+  "\xa2\xb3\xf2\xf9\x14\x3d\x5c\x82\xdf\x14\xfc\x25\x21\x5d\xee\x67"
+  "\x77\xe8\x7c\x8b\x34\x13\xd2\x1e\xc6\x6f\x32\x7e\xe7\x39\xeb\x45"
+  "\x00\x6d\x34\x75\x9b\x68\x38\xf3\xaf\xee\xcf\xdb\xd4\xe3\x7e\x18"
+  "\xf6\xcf\xd3\x25\x06\x1f\x2b\x9d\xfe\x60\xde\x87\xa7\xcf\x72\x5c"
+  "\xa8\x80\xc4\xa7\xaf\x38\x89\x63\x44\xe9\xe9\x8c\xc3\x2f\xb8\x5d"
+  "\xb4\xef\xc1\xaf\x15\x7f\x2c\x97\xe3\x8d\xba\xdd\x7d\xc5\xdc\xe6"
+  "\x4f\x90\x2e\x8c\x74\xf4\xd7\xcc\x79\xbf\x3a\x7d\xd6\xa4\xca\x64"
+  "\x99\x00\x33\xa4\xc3\x87\xac\x3f\x10\x64\x99\xee\x36\x59\xc5\xd1"
+  "\xa2\xa9\x54\x3f\x46\xb4\xed\x7d\x4d\x34\x2b\x59\x7b\x18\x6d\x3f"
+  "\xd3\xc4\x38\x62\xde\x6e\xde\x86\xbc\xa3\x58\xc5\x32\x5d\x9a\x0b"
+  "\xd9\x7f\xec\x11\x8e\x1b\x35\x3e\xba\x0f\xc2\xbd\x20\xc4\x73\xe7"
+  "\xdb\x55\xde\x21\xc2\x94\x17\x6a\xf5\x77\xd1\xcf\x7b\x3b\x87\x38"
+  "\xff\x48\x26\x5f\xf8\x14\x4d\x19\x4d\x76\xb6\xff\x1a\x5e\x13\x7e"
+  "\xfc\x76\xb2\x3f\x27\xf8\xe4\xba\x33\xf4\xc8\xc3\xff\x30\x9a\x46"
+  "\xff\x6b\x39\xe9\xfa\xe8\x91\x67\x07\xf4\xd1\x63\x17\x5b\x3a\x0e"
+  "\x47\xe9\xa2\xc7\x7e\x72\xb9\x2e\x7a\xf4\x4d\xa5\x8b\x44\x58\xe9"
+  "\x9e\x88\x5f\x4f\xdf\x1e\x97\xae\xfb\x85\x3c\xfa\x7c\x5c\x7a\x48"
+  "\x4f\x5f\x12\x97\x1e\x50\xe9\xf9\x7b\x0d\x5d\xd7\xca\x78\xac\x63"
+  "\x5d\x97\xbf\x89\x75\x5d\x6b\x91\xae\xeb\xa4\x8f\x61\xfe\x32\xf1"
+  "\x63\x17\xf1\x9d\x25\x3c\xcf\x60\xfc\xc5\xef\xc8\xc0\xfd\x9a\xd3"
+  "\xb4\x28\xc2\x69\x9e\x3f\x93\x19\x7f\x52\xcf\x09\xf7\x03\x05\xac"
+  "\xe7\x58\xc7\xb1\xdf\xc9\x9e\x31\xa2\x7d\xcf\x6b\xe2\x44\xfd\x6b"
+  "\xe2\x78\x8f\x7b\x51\x89\xa1\xef\x5e\x41\xda\x36\xa4\xbd\x82\x7c"
+  "\xd6\x7b\x4c\x93\x96\xfc\xc3\x1c\xc7\xa1\x03\xb6\x55\xd0\x9a\x44"
+  "\xa5\x3b\xc0\xf3\x7c\xbf\x70\x0b\xe8\xeb\x2b\xe3\x7b\xab\x11\x92"
+  "\xf1\x94\x4c\xd9\xd0\x51\x1d\x2c\x6f\x63\x36\x43\xbe\x7c\xe5\x9f"
+  "\x53\x55\x50\x9c\xe1\x7b\x76\x8c\x43\xc1\xfa\x1f\x70\x8c\xa0\xa4"
+  "\x66\x58\x17\xec\x07\xce\xfe\x2a\xd0\xbb\x66\x0f\x70\x52\x31\x52"
+  "\x16\x61\xfd\xdf\xa0\xdf\x63\x7a\xdc\xc1\xf1\xc7\x4e\xd1\xa2\x69"
+  "\x58\xdf\x85\xb8\x6f\xd6\x88\x8b\xf8\xde\x0b\x64\x94\xd7\x78\xc5"
+  "\x7b\xf0\xe7\x31\xee\xbe\x70\x2c\x3a\x94\xf1\xb5\x87\x88\x71\xf6"
+  "\xd3\xa2\x2d\x2d\x15\x87\xb9\x7e\x16\xd3\x46\xb8\x9d\x06\x8c\x24"
+  "\x79\x77\xc6\x4d\x16\xbe\x3b\xe3\xa7\x7c\xbb\xb2\x69\x32\xf2\x5b"
+  "\x16\x07\x88\xf5\xbc\xaf\x13\x30\x2a\x4e\x29\x18\x80\x25\xa0\xf7"
+  "\x63\xf2\x74\xf8\x23\x2b\xc5\x17\xa7\xe8\x91\x20\x8f\x17\xdf\x83"
+  "\xe4\xf3\x35\xd0\x25\x85\x7d\xe3\x95\xed\xb9\xa8\xb2\xe1\xcf\x44"
+  "\xfa\x5d\x4e\xf0\xdb\xa2\x0a\xbe\xa7\xc4\xf7\x37\xe5\xdd\x4d\xd3"
+  "\x54\x12\xeb\xb2\x52\xfa\xef\x6f\xfe\x1f\xb8\xbb\x09\xfa\xdb\xf7"
+  "\x99\x44\x13\xf0\xaf\xe0\xfb\x9b\xc0\xff\x24\xf3\xa1\xde\x27\xd7"
+  "\xae\xc7\x98\xe6\x8f\x34\x73\x1a\xd6\x8a\xc7\x8c\xf1\xe7\xfe\x72"
+  "\x5f\x90\x77\x40\xd9\x84\xa2\xcd\x4f\x8f\xba\x38\x1f\x69\x3b\xb9"
+  "\xfc\x14\xe8\x31\x5f\x51\x84\xde\x39\x1d\x31\x55\x6f\x20\xb3\xd2"
+  "\x69\x8f\xbd\xc1\xf5\x95\x4e\x7b\x2c\x6f\x40\xa7\x3d\x36\x47\xe9"
+  "\x34\x45\x63\xa5\xd3\x1e\xbb\x53\xe9\xb4\xc7\x6e\x95\xe7\x60\xd0"
+  "\x69\x9c\xc7\x7a\xcd\xd0\x69\x7b\xc7\x88\x63\xac\x3b\x7a\xdc\x8f"
+  "\x39\x0c\xdd\xb6\x1d\x69\xac\x3b\x18\x47\xa5\xa7\xf2\xcb\xc5\xff"
+  "\x97\x45\xca\xcf\x80\x9f\x8b\xf9\xbe\x42\xa7\xfe\x8c\x71\x79\xac"
+  "\x46\xe9\xb8\xc7\xca\x06\x74\xdc\xa3\xa1\x81\xba\xac\xe3\x1e\x7b"
+  "\x49\xe9\x38\x95\xde\xf0\x18\xeb\xb8\xfc\x72\xa6\x81\x0e\xdf\xc4"
+  "\x7b\x76\x7a\x79\xa6\xa3\x2b\x5a\xc7\xc5\xca\xd7\x63\xc7\x0d\x1d"
+  "\xc7\xba\x0d\xef\xb0\x41\x54\xbc\x15\x96\xb3\x9d\xa0\xb9\x21\x77"
+  "\x3c\x06\xdc\x67\x8e\x33\xc6\x74\x9b\x75\x96\x86\xe9\x77\x85\xf4"
+  "\x7e\x3f\x6e\x37\x7c\x1d\xfd\xf4\x98\x23\x91\xdd\x6c\xd8\x69\xe0"
+  "\xc7\x1b\x22\x1c\xa7\xc3\x85\xb9\xb4\x4e\xb8\x5a\xc3\x27\xe8\x89"
+  "\x32\x32\x69\xc9\xcf\x7c\xc6\x63\x8b\x75\xc6\x50\xfe\x65\xdd\x83"
+  "\x39\x74\x49\x41\x90\x86\x62\x6d\xfe\x59\xb5\x09\x79\xe5\xf4\xbd"
+  "\xa8\xbc\xf5\xdc\x4e\x54\xbd\x49\x51\x79\x32\x1e\xe5\xa4\x73\x1c"
+  "\x63\xee\xf1\x9c\xc1\xd6\xfe\x57\x89\xcb\x5f\x07\xc7\x65\xf1\x90"
+  "\xc1\x71\x59\x2c\xed\x80\x49\x5d\x94\x84\xb5\x59\xda\x39\x7a\x5c"
+  "\xee\xc7\xc8\xb8\x37\x9b\x13\xb5\xb3\xf8\x01\x3d\x7f\x48\x54\x7e"
+  "\x74\x5b\xcf\x27\xa8\x1f\xdd\x5e\xcd\x57\xc0\x7f\xf7\x2b\xe0\xff"
+  "\xdb\x57\xc0\xff\x82\x75\x20\x68\x67\xd5\x4c\xb1\xe5\x26\x87\xa5"
+  "\x0c\x1e\xe3\xfb\x7a\x67\x68\xc9\x37\xf5\x3d\x9f\xcf\x9c\xe3\xe4"
+  "\x5a\x50\xde\xdb\xda\x81\x7c\xbe\x97\xcf\xfa\x79\x36\x46\x50\x9d"
+  "\x51\xf7\xd7\x99\x17\x8f\x5b\x6a\xd8\xc0\x4d\xe6\x3f\x1b\x8f\x1b"
+  "\xf2\x27\x45\xe5\x6f\x1f\x18\xf7\x25\x57\xf4\xaf\xf7\xd5\x91\x8c"
+  "\xc1\x79\x14\xcb\x17\xcc\xc9\x1c\xf7\x4f\xdf\x9f\x59\xd2\x01\x3d"
+  "\x9f\x1d\xe5\xb7\xdb\x05\xdd\x7e\x03\xc7\x5f\x60\xdb\xb7\x5a\xad"
+  "\x87\xbf\x81\xf9\x24\x9d\xef\xeb\xf0\xdd\x9d\x82\x48\x9e\xe9\x68"
+  "\x05\xcb\xd0\x13\x0e\xa3\xee\x60\xfb\x40\xdc\xae\xde\x26\xfb\xc0"
+  "\x06\x51\x67\xa1\x51\x87\x61\xb3\x1f\x25\xe6\x81\x1b\xe4\x9d\xd7"
+  "\x70\x17\xeb\xdd\x6f\xc0\x4e\x4e\x57\xed\x14\x92\xde\xce\x56\xd4"
+  "\x19\xf4\xae\xfa\x95\xfb\xf7\x44\xf3\xd5\xf7\x8f\xf4\xfe\x15\xd0"
+  "\x57\xf4\xef\x0a\xed\x16\x4c\xbf\xfa\x76\x6d\x46\xbb\xe5\x57\x4f"
+  "\xd7\x82\x83\x5f\x9f\xae\xd9\x3a\x5d\x0b\xfc\x5f\x41\xd7\x04\xed"
+  "\x14\x8e\xfe\xfa\xed\x38\xf4\x76\x0a\xe7\x26\x6a\x87\xe4\xbf\x41"
+  "\xef\x75\x59\x8c\x18\x98\x1c\x0f\x56\xc5\xbb\x2b\xf4\x44\xc7\xfa"
+  "\x55\x71\x62\x0b\xf7\x1b\xb1\x7e\xf5\x58\xb4\x98\x5b\x0a\x3f\x2a"
+  "\x68\x64\x7b\x44\x68\x7e\x2a\x6c\xe6\xf8\xaa\xb3\x2b\xd5\x9d\x71"
+  "\xbd\x4e\xfb\x95\x62\x0c\x73\x9c\x2d\x21\xf2\xe9\x68\x9d\xf4\x07"
+  "\xc0\x3c\xb4\x34\x8d\xef\x07\xa8\xf3\xcc\xa5\x99\x4a\x26\x97\x66"
+  "\x02\x76\xf1\xe0\x30\x16\x79\xf7\x57\x65\x0f\x19\xcc\xe7\x1f\xf5"
+  "\x17\xfb\xe9\xd9\x85\x5c\x3f\x52\x3b\x21\x47\x9c\xb7\xeb\x71\xfe"
+  "\x9e\x7a\x3f\x2a\x0e\x21\xe6\xee\x27\xff\xaa\xdf\x4d\x00\x0d\x5c"
+  "\xa0\xe5\xd2\x9d\x06\x0d\x8c\x74\xa4\x1d\x30\x68\x00\x7b\x25\xc5"
+  "\xd7\x18\xe6\xbb\x43\x41\x75\x4f\x7c\x69\x8b\xa8\x59\xd4\xa4\x60"
+  "\x3f\xa9\xce\x19\xd2\x27\xe4\x04\x37\xda\x4d\x46\xfd\xf1\x0e\xe7"
+  "\x97\xcc\xc3\x81\xb4\x45\x58\xaf\x2c\x0d\x1a\xf0\x05\xe3\x25\x06"
+  "\xca\x35\x48\xbf\xa4\x27\x31\xfe\x05\x2a\xbe\x23\xda\x90\xb8\x9b"
+  "\x28\x59\x03\xfe\xe8\x83\xc9\x57\x1a\x64\x3b\xb5\x2b\x82\xfe\xb3"
+  "\xae\x3b\xb4\xd2\x6f\xe6\x32\xd2\x76\x38\x9f\x65\x52\x31\x14\x9f"
+  "\x7c\x56\x3b\xcf\x31\x71\x24\x5e\x29\xe8\xf3\x61\xc6\xc9\x8f\xdf"
+  "\xc0\xc6\x2c\x5a\x70\x91\x74\x5a\x3c\xf9\xb0\x86\x74\x6d\xf5\x00"
+  "\x0e\xfb\xe4\x1d\x8f\x27\xeb\x0c\x1c\x34\x6e\xbf\xc7\x6e\x82\x2d"
+  "\xc6\xed\x76\xca\xbb\x96\x68\x7b\x0a\xc7\xb4\xe3\xd8\x18\xeb\xb2"
+  "\x88\x71\x40\x9d\xe3\x06\xbd\xf5\x3a\x46\x1b\x15\x9a\x6c\x5b\xd1"
+  "\x46\xd1\xf9\x28\xec\xc1\x27\xc3\x97\xd3\xf9\x29\x5b\x14\x9d\x93"
+  "\x99\xaf\x78\x8f\x05\xf8\xff\x82\xe9\xcd\xe7\x1a\x8e\xb5\x6c\x57"
+  "\x3d\x75\xcf\xd1\xa0\xf4\x3b\x49\x61\xb8\x1a\xe8\xcf\x30\x00\x77"
+  "\x84\xa2\xf1\x53\xf9\xfd\x34\x46\xdb\x02\x63\xb1\x59\xdd\x49\x61"
+  "\xdf\x77\xe8\x8e\xa7\xca\xfb\xdb\x61\x5c\x9d\x76\x93\x26\xec\x1c"
+  "\x33\x33\xc0\xb8\x96\x39\x44\x88\xed\x4a\xe9\xc7\x84\xbe\x1e\xaa"
+  "\x6a\x37\xc3\xb6\x34\xc9\xb6\xba\xb3\xd8\xbe\xb7\xc8\x67\xb4\x35"
+  "\x08\x7f\xaf\xe0\xb8\x94\x46\xbf\xd0\x17\x0b\xf3\x16\x70\x87\xfd"
+  "\x57\xf4\x81\xe4\x97\xb5\x3c\x4e\x45\x6f\x72\x9a\x51\x0e\xef\x6b"
+  "\xb8\x9c\xf1\x8e\x3c\xf0\x57\xd1\x1d\xe8\xd7\x70\xc6\x33\xe0\x94"
+  "\xb1\x5f\xd0\xe7\xa2\x76\x86\xd1\xe3\x2e\xca\x89\xe9\x67\x5f\xbe"
+  "\xd9\xe0\x3b\x3e\x23\x6a\x76\x84\xa4\xee\x54\xb4\x2d\x2a\x31\x64"
+  "\x92\xeb\x2b\x19\x2b\x72\x45\xf3\x62\xd0\x39\xc0\x07\x65\xe3\xc8"
+  "\x62\x76\x70\x2c\xcd\xa2\x42\x15\x07\xbc\xe8\x60\xfc\x78\x71\x1e"
+  "\xc7\x9d\xd4\x69\xc8\xf2\x64\x3b\x45\x45\x8d\xdc\x37\xf0\x5a\xf0"
+  "\x4a\xf3\x25\xc7\x84\xe4\x58\x9e\xaf\x2a\x39\x02\x5d\x96\x7f\xf3"
+  "\x55\x75\xbf\x27\xa8\xe2\x2b\x2e\xbb\x4e\x98\xde\x94\xe3\xc5\x7e"
+  "\x79\x32\x8e\x86\xbc\xfb\xbd\x8c\x7d\xdc\x44\x6a\xe9\x9b\x32\x0e"
+  "\xab\xee\xb3\x17\x68\x2e\x0d\xcb\x38\x7c\xce\x32\xbe\x0b\x1b\xe6"
+  "\x35\x99\xf4\x49\x3b\x5a\x16\xa6\x87\x42\x4c\xdb\x65\x25\x7c\xc7"
+  "\x3d\x28\x69\xb1\xac\xdc\xb8\xd7\xce\x71\x26\x39\x4e\xe9\x94\x30"
+  "\x25\xb3\x4d\xe1\x70\x72\x4c\x82\xe5\x79\x6c\x93\x28\x9a\x82\xef"
+  "\x4d\xa2\x4d\xf1\xf2\xb2\x8f\xf8\x1e\xbb\x3a\x5f\x3a\x05\xfe\x4e"
+  "\xfe\xcb\x29\x5a\xf6\xef\x6a\x5f\xc6\x90\xb5\xe5\x0f\xf0\x19\x93"
+  "\x5f\x87\x81\xb6\x30\xff\x2f\x9d\x7d\xb9\x5c\x2c\xfb\xc8\x58\x63"
+  "\xf0\xbd\x38\x75\x5e\x35\x00\xcf\x4f\xcb\xe4\xbe\xf4\x80\x6e\xfa"
+  "\x3d\x60\x2d\xcf\xbe\x5c\x66\x96\xcf\x36\x78\xb9\xf4\x46\xbe\x5b"
+  "\xbd\xcc\xc2\xed\x0f\xa6\x33\x85\xf3\x51\x1e\x27\xcb\x69\x07\x25"
+  "\x7f\xd5\x7d\x89\x81\xf3\xaf\xe5\x07\x8c\x3e\x18\x34\x51\x7d\xf8"
+  "\x51\x52\x77\x7a\x86\x6b\xa0\xef\x3f\x52\xfe\x66\x03\xf9\x77\x46"
+  "\xd1\x86\xdf\xa7\x29\xbe\x5b\x8e\x35\xc5\x53\xcd\x8a\x17\x55\x9a"
+  "\x48\x5f\xf4\x2b\x8e\x01\xab\x70\x5c\x41\x06\xbf\xf7\xb8\x7f\x34"
+  "\xde\x4f\xe7\x8f\xab\x73\xa8\x1f\xa1\xff\xcb\x5d\xaa\xde\xf2\xe3"
+  "\x8c\x4b\xc2\x7e\xc6\xe2\xd8\xc4\x73\xac\x8a\x75\xf0\xa3\x77\x19"
+  "\x5f\xc7\x4d\x3c\xc6\x3f\xaa\xe4\x76\x65\xdc\x83\xbe\xe2\x21\xc1"
+  "\xbe\x2c\xea\xee\x2b\x86\xfc\x64\x99\xd0\x0e\xf4\xdf\xb9\x03\x7a"
+  "\x9b\xfb\x0d\x5c\x19\x37\xd8\x8a\x96\x1e\xb1\x22\x31\x7d\xb9\x5d"
+  "\x19\x8f\xa9\x78\x18\xfe\x2c\xf8\x1b\xfa\x75\xe7\x63\xd8\xb5\x9d"
+  "\x81\x9a\x71\x01\x6d\xad\x38\xc6\xf1\xbf\xb0\x2e\xe8\xac\x06\xff"
+  "\xa6\x6e\xf2\x52\x6a\x70\x89\xa9\x60\x3d\xe5\x60\x6d\x4b\xe2\x92"
+  "\x98\xb6\x4f\xc3\xef\x5a\x31\x95\xe3\x5e\xe3\x3d\x5b\x7f\x9f\xc8"
+  "\xef\xdd\x6b\xc5\xe2\x1e\x77\x71\xbe\x71\x76\xa7\x62\xd6\x14\x17"
+  "\xf7\xc7\xf9\x49\x7e\x9c\xef\xf9\x70\x4c\x28\x4d\x24\x3f\xd3\xc9"
+  "\xed\x16\xf0\xdc\x81\xf6\x50\x0e\xf3\x7f\xa1\x8c\x91\x13\x48\xbe"
+  "\x25\x1d\x7f\x09\xef\xbe\x73\x1d\xc6\xab\x3b\x6d\x5c\xc0\xc0\x35"
+  "\x35\x98\x63\xfa\x9a\xb8\x05\x0d\xdc\x90\x7e\xac\x5a\xa5\x87\x39"
+  "\x46\x21\xfb\x20\xf6\xb8\x57\x8c\x36\x70\x35\x70\xe0\xf6\xf8\x5e"
+  "\xa5\x48\xcf\xf0\x70\x4c\x18\x6e\x2f\xb0\xb1\x98\xcb\xe6\x18\xf8"
+  "\x7e\x5d\x5e\xae\xaa\x17\x82\xe7\x16\x3e\x4f\x72\x8c\x25\x6a\x0d"
+  "\xb2\x4e\x59\xb1\xf3\x68\x7d\x90\xf7\xa0\x6b\xd1\x46\x4d\xb7\x28"
+  "\x26\xad\xaf\x38\xe1\x18\x73\x1d\x94\x6f\x93\xfa\xa1\x36\xa3\x46"
+  "\x13\x73\x39\x06\x70\x2d\xc7\x5d\x85\xad\x09\xb9\x5d\x11\x6e\xae"
+  "\xe8\xe4\xbb\x90\xd0\x39\x2b\x38\x4e\xa8\x87\x6d\x0d\xac\x53\x38"
+  "\x7e\x45\x32\xeb\x26\xef\xda\xa9\x0c\x23\x62\x2e\x27\x73\x73\xf9"
+  "\xd7\x8b\xa7\xef\xa7\xa7\xa7\x2a\xd9\x79\x7a\xaa\x31\xcf\xe2\x39"
+  "\x27\xf6\x5c\xfa\xe9\xac\x78\x9d\xfb\xe4\x73\xcf\x95\x15\xac\x5a"
+  "\xc6\x3f\x59\x13\xd6\xdc\x3c\x3c\x7a\xed\xcc\x7a\x58\xc5\x31\x78"
+  "\x3a\x9f\xf7\xa9\x5e\x4d\x37\xce\x59\x9f\xae\x33\xf6\xca\x74\x7f"
+  "\xee\x99\x6c\x53\xb3\xed\x89\xbc\x43\x1f\x55\xb0\xe8\x50\xd2\x67"
+  "\x16\x32\xc5\xb7\xb7\x7c\x69\xd9\xd2\x92\xbb\xf8\x44\x65\x78\xa2"
+  "\x76\x8e\xc5\xb6\xf3\x0c\xf5\xb7\xa3\xf4\x60\xd0\xc4\xe5\x6a\x76"
+  "\x79\x45\x5a\x55\xa1\xba\x4b\xfb\xcc\x78\x63\x0f\x64\x10\x3f\xb8"
+  "\xb6\x48\xed\xa3\x36\x1e\x17\x67\x25\x99\x7e\xb5\xa1\xdd\xc4\x36"
+  "\x4a\x15\x9e\x79\x6d\x28\xed\x22\x3d\x9e\xd0\xef\x2e\xb4\x63\x9e"
+  "\x79\xa6\x5c\xd4\x64\xb4\xf9\xe9\x99\xd2\xc1\xe6\xa7\x68\x1f\x02"
+  "\xf6\x39\xeb\xa0\x67\x3c\x83\x9e\xf7\x7b\x26\xe4\x29\x3d\xf3\xcc"
+  "\xe7\xcd\x76\xe2\x71\x7f\xf1\x14\x3d\xf3\x99\xd9\x8e\xb9\x64\x2c"
+  "\xfd\x14\xcf\x9f\x73\x5d\xce\x8b\x19\xe7\xeb\xce\x36\x9a\xc1\x85"
+  "\xe0\xc6\x24\xa1\xfe\x91\x59\x7f\x48\xc6\x9f\x49\x24\xc9\xd3\xb0"
+  "\x64\x50\x78\xd8\x50\x33\x59\x53\x53\x2c\x37\x5c\x9f\x69\x9f\x79"
+  "\xf7\xf4\x69\xce\xaa\x0a\x48\x6f\x38\x64\x15\xd1\xf1\xaf\xaa\x2c"
+  "\x0f\xdf\xec\x22\xe9\x0f\x51\x53\x95\x90\xf7\xb7\xbb\x45\x29\xdf"
+  "\x3d\xd6\xd2\x77\x65\x3b\xd7\x90\xe9\x9d\x5e\xbf\x89\x63\xb0\xb3"
+  "\x0d\xc2\x31\xfa\x4f\x51\xc9\xf3\x1f\x22\x0d\xfd\x2f\x17\x9e\x5d"
+  "\xd9\xea\xbc\xb3\xe4\x5d\xad\x76\x57\xf6\x00\x7c\x33\x31\x7c\xe7"
+  "\x1b\x64\xda\x5f\xd5\x69\xf2\x99\xef\x26\x9f\x23\x48\x1f\xe2\x39"
+  "\x21\x2d\xd1\xa6\xe0\xb8\xaf\x80\xd1\xe0\xd6\xb6\x3a\xbf\x24\x93"
+  "\x7e\x7f\xd0\x74\x8e\x4a\xfe\xda\x34\x48\x3d\xbe\xaf\xdb\x9d\x3e"
+  "\xee\xd7\x3d\xee\x67\x31\xfe\x39\xfb\xf5\x39\x0f\xba\xf9\x59\xf0"
+  "\xff\x33\x72\xbe\x43\xfe\x7b\xdd\x32\xe6\xef\xb3\x73\x8d\x32\x09"
+  "\xc7\xe8\x65\xde\x53\x15\x5e\x1e\x57\x71\xe9\xaf\x9d\x7c\x37\x61"
+  "\x10\x3f\x86\x61\xbe\xf2\xdb\xf8\x1c\x69\x48\x6a\x88\x52\x9c\x17"
+  "\x45\x5f\xc4\x4d\xa3\xc1\xee\xa6\x08\xd6\x96\xe1\x4b\x22\xbf\xa5"
+  "\xeb\x82\x8c\x4d\xc9\xfa\xe3\xed\xe5\xbf\x37\xf9\x42\xe7\xbd\xbe"
+  "\x2d\x1a\xb5\xc2\xfe\xf0\xd5\x9f\xf7\xaa\x18\x96\x11\x6a\xa1\x3f"
+  "\x53\x4b\xf9\xff\xeb\x92\x7b\x41\xf5\xc2\xc5\x74\xee\xbb\x24\x16"
+  "\xfa\xcc\xff\x0f\xf1\x37\x44\x58\x17\x82\xee\x8e\x73\xb4\x32\xed"
+  "\x77\x80\xf3\xce\x7f\x00\x96\x8c\x79\x35\x83\x3e\xc4\x73\x8f\x7b"
+  "\x65\xa6\xa1\x27\x13\xc6\x0a\x49\xf2\x6e\xb7\x96\x2f\x31\x69\xd0"
+  "\xb9\x1c\x9b\x0c\xba\x76\x2a\xf7\x0b\xef\xd9\xfc\x8e\xdf\x89\xfc"
+  "\x6b\xdd\xe4\xdd\x6b\x0d\x2f\x61\x1d\x9c\xcf\xfa\x15\xe9\x0b\x1b"
+  "\x2e\x49\x9d\x9c\xa7\xbf\xe7\xea\xef\x73\xf5\xf7\xd9\xfa\x7b\x8e"
+  "\xfe\x3e\x9d\xdf\x95\xee\x5e\xd9\xd4\x3f\xaf\x98\x86\xb5\xe1\xdd"
+  "\x6b\x8c\x05\xf0\x19\x69\x2d\xaf\x94\x73\x80\x8e\xc7\x54\x1d\xaf"
+  "\x6c\xfd\xdd\xc0\xe7\x3a\x6b\xb8\xf2\xbf\x09\x9f\xe7\x72\x62\xf1"
+  "\x79\x2e\x2f\x0a\x1f\xb2\x96\xe7\x7c\x1d\x7c\x6c\x56\x8e\x75\xff"
+  "\x37\xe0\xc3\xb8\x70\x1a\xda\x6f\x8b\xc3\xc7\x6f\xe0\x93\x90\xdf"
+  "\xd6\x8a\x4e\x9e\xff\x56\x7f\x53\xc6\xe8\x1d\xc6\x73\x5b\x43\xaf"
+  "\x11\x67\xae\x34\xf3\x4a\x71\xe6\x20\x0b\x76\x94\x41\xff\x9f\xeb"
+  "\xd2\xe7\xf9\x23\xca\x1e\x2c\x5d\x68\xf8\xfe\xa0\xaf\x07\xaa\x55"
+  "\x5f\x0f\x6e\xe1\x58\x6b\xeb\x29\xc3\x59\x2e\x3a\xb1\xbe\xf9\xcf"
+  "\x66\x47\x20\x46\x06\x4a\xca\x56\xaf\x7e\xf6\x2e\x47\xc9\xd2\x95"
+  "\xcb\x1c\x13\x8a\x1c\xab\x8b\x57\x2c\x2f\x5b\x16\x7b\x1e\x6e\xd3"
+  "\xbf\x3b\x22\xfd\xfc\xd9\xe6\x66\x19\x60\xfe\x67\xbd\xad\x7c\x33"
+  "\x9f\xbf\x56\xb8\x4b\x5d\xac\xeb\xf7\xd5\x92\x99\xcf\x60\x80\x4f"
+  "\x87\xa1\xe3\x55\x6c\x7d\x4a\x62\x1d\x8f\x74\xd8\x70\xcf\x56\x44"
+  "\xa5\xa3\xec\xf3\x36\x23\x8d\xe1\xeb\xba\x69\xd8\x29\x2a\x7d\x97"
+  "\xdb\x4c\x48\xc3\x4b\xa2\x11\xf3\x6b\x12\xd6\x5b\xbc\xf6\x15\x1c"
+  "\x37\x89\xef\xcf\xa1\x9e\x00\x3e\xf2\x4c\x91\xbf\x6d\xa3\x6c\x7b"
+  "\xc1\x38\xae\x41\x9d\xfd\x48\x33\xef\x40\x59\xac\x17\x3a\xb9\x1e"
+  "\xd2\xb7\x73\x1c\x03\xa4\x5b\xf4\x78\x50\x9c\xf6\x26\xc7\x19\x40"
+  "\x9a\x2d\x2a\xed\x3d\x8e\x61\x8e\x34\x87\x0e\xef\x0f\x4c\x67\xbc"
+  "\xe7\xe8\x7b\x0a\x5c\xe6\xdf\xf5\x76\x5d\xd1\x38\xf3\x47\x28\x6e"
+  "\x9b\x9c\xed\x58\xf8\xd0\x77\x66\xdc\xfd\xd4\x73\x2b\x97\x0f\x27"
+  "\x49\xf6\x2c\x4c\x97\xd9\xb7\x95\xdf\x7c\x97\xa3\x74\xd9\xb2\x55"
+  "\x8e\x75\xcb\x56\x96\x39\x96\xae\x5b\xba\x7e\x38\x2d\x7f\x6e\xd5"
+  "\x53\x7c\x4b\x9e\x87\x65\x75\xc1\x53\xcb\x7f\xc4\x4e\x0b\xaa\xf4"
+  "\xf0\x98\x79\x7c\x21\xeb\x36\x3d\xae\xc4\xb1\x6a\xb6\x35\xd2\x6e"
+  "\xb2\xe3\x99\xe3\x2d\xf1\x6f\x33\xfe\x8e\xe0\xef\x30\xfe\x4e\xe0"
+  "\xaf\xed\x0c\xad\xe3\x98\x06\x87\x7a\xdc\xab\xb6\x18\xf6\xc4\x00"
+  "\x0f\xad\xaa\x33\x78\x08\xf3\xff\x21\x35\xbf\xad\x3a\xd6\x1a\x96"
+  "\xf2\xd3\xcf\x53\xd5\x97\x06\x78\x8a\xe3\x45\xb6\xb2\x4f\xce\x5a"
+  "\xe4\x83\x87\x79\x9d\x0e\x9a\x5f\xc3\x74\x3b\x4d\x6b\x3e\x68\x78"
+  "\x4d\x1c\xe7\x58\x27\xf8\x6d\x06\xbf\x1c\x57\xf1\x45\x56\xcf\x46"
+  "\xb9\x71\x68\xe3\x88\x6a\x43\x7f\x1f\x23\x8e\xf1\x3e\xc6\x29\xfd"
+  "\x5d\xad\xf9\xd7\x3c\xcc\xcf\xfc\xab\x9f\x85\x59\xd9\xbf\x51\xad"
+  "\x1d\x8d\xbc\xd5\x67\xf5\x36\xbc\xa0\x85\x6b\x9f\x5b\xda\xdc\x72"
+  "\x8d\xc5\x7b\x68\xd6\xa4\x99\x02\xf8\x9c\xd7\x92\x1f\x6f\x97\xf1"
+  "\x0b\x5d\xbd\xd0\x11\xb7\xdf\xee\x2b\x97\xe5\x93\x78\x8f\x6d\x7e"
+  "\xa9\xd0\x38\xa6\xb4\x96\xfc\x4c\x3b\xd7\x13\xb6\x9b\xec\xda\x8e"
+  "\x91\x39\xca\x16\xe0\xb8\x71\xab\x8f\xe9\x30\x43\x4c\xdb\x33\xb4"
+  "\x6a\xbd\x5a\xaf\xad\xd3\xbf\x37\xb0\xfa\x84\xe1\x2b\x07\x19\xcd"
+  "\xc2\x7b\x87\xa1\x03\xfc\xb4\xba\x49\xf7\x6b\xf2\xaa\xfe\x97\x65"
+  "\xea\xef\x87\x75\x1c\x93\x38\x96\x05\xf0\x6f\xe3\xb1\xc3\xda\xf7"
+  "\x30\x9e\x4f\x80\x3e\xc7\x15\x7d\xca\xa4\x0d\x08\xbb\x86\xf3\x4f"
+  "\xf0\x37\x3b\x90\x77\x42\xc5\x89\x58\xbd\x90\xfb\x3c\xe0\xfb\x58"
+  "\x9f\x03\x5c\x1f\xe6\x33\x43\xc8\xd2\x61\xdf\x25\x96\xcf\xd5\x79"
+  "\x80\xd7\x64\xe8\x1d\xd6\x33\x05\x11\xc8\xa9\xb4\xbb\xcb\xb6\x19"
+  "\xfa\x66\x80\x0f\xca\x1a\x13\xe9\x92\x44\xe3\xae\x8f\xcd\x35\xc2"
+  "\xfd\x7c\x07\x70\x6a\x92\x63\xc0\xf1\x34\x2f\xf5\xdb\xf7\x7d\x4a"
+  "\x47\x96\x05\xfb\xd7\x22\x3a\x1e\x1c\xa7\xdb\xcf\xb8\xf5\xca\x73"
+  "\x5c\x5d\x6f\xac\xc9\x34\xf4\x86\x01\xc7\x9a\x24\x34\x6b\x39\xfe"
+  "\xf3\x64\x96\xf2\x1e\x32\xcf\x97\xd2\x1e\x01\x9c\xd4\x8b\xea\x0e"
+  "\x93\x56\x93\x59\xea\xa7\xb2\x13\xd0\x31\x66\x69\x73\xba\x9f\xef"
+  "\x19\xd0\x45\x6b\x4a\xa3\x61\x0a\x5b\x66\x29\xc3\x65\x7d\xc4\x36"
+  "\x49\x41\xc4\xcc\x71\x44\x4a\xf5\xf9\x05\x3a\x78\x4d\xa3\x81\x2b"
+  "\x68\x78\xcc\xc0\x57\xff\x56\xd2\x31\x3f\xad\x01\xee\x7d\xec\xcb"
+  "\xdb\xac\xc6\x73\x9d\xd4\x37\xc8\x3b\x88\xba\x27\xfd\xf4\x7c\xb6"
+  "\x2e\x43\xc7\x51\xff\xe0\xd1\xaa\xd9\x28\xb3\x26\xa4\xfb\xa3\xb6"
+  "\x61\x7c\x4f\x0c\xf0\xfe\xaa\xb3\x51\xfb\x01\x27\xd4\x18\xde\xed"
+  "\x3a\x45\x6b\xa7\x45\xa5\xeb\x63\x7b\x34\x0f\xe9\x67\xd5\xda\x3a"
+  "\x33\x5b\xd5\x5f\xab\x7c\x77\x75\x1c\x59\x17\xf0\x7d\x2b\x96\x71"
+  "\x49\x7b\x39\xc6\x6b\x4b\x8d\xf9\x02\xb0\x0e\x49\x9a\x8f\x11\x47"
+  "\x98\x4e\x2a\x5e\xc3\xaa\x31\x8a\x4e\x6b\xeb\x62\x68\xcf\xf3\x26"
+  "\xda\x61\x3a\xa5\x6e\x12\x5a\x6a\x30\x49\x14\xac\x37\x13\xcb\x0b"
+  "\xcb\x38\x9f\xbd\x80\x3f\xa4\x5d\xa5\xe8\xb6\xb6\xdd\xa0\x9b\x31"
+  "\x76\x4c\x27\x3f\xad\x9d\xcb\xb4\x8d\xed\xe3\xb0\xb6\x53\x46\xdf"
+  "\x41\x53\xde\x0f\xc6\x7b\x97\x2e\x17\xc7\xbd\x63\xd9\x17\x60\xd5"
+  "\x17\x47\xcd\xdf\xa1\xa3\xe5\x53\x49\xd1\x76\xdd\x34\x3f\x95\xd6"
+  "\x45\xad\x1b\x8e\x31\x7d\x59\x56\x80\x67\x89\x1e\x3b\xe9\x98\xf2"
+  "\x47\x59\xd5\x25\x6a\x32\x4b\xa4\x2c\xaf\x95\x31\x2e\x38\xee\x6a"
+  "\x1b\xd3\x88\xf5\x22\xcb\x12\xcb\x00\xcb\x93\xa2\xd1\xba\x9d\x51"
+  "\x34\x6a\x66\xfa\xe8\x74\x3a\x14\xa7\xcb\x97\x39\x4a\x66\x28\x5d"
+  "\xec\xc8\x9a\x50\x34\x45\x06\x2a\x71\xdc\x37\xeb\x2e\x47\xde\x8c"
+  "\x09\xe5\xc5\x13\xe7\xab\x9f\x59\x79\xb9\xfc\x3b\x3c\x76\xdd\xe5"
+  "\x40\x3b\xe1\xd8\xb5\x5b\xe5\x56\xa5\x3f\xca\x47\xfb\x93\x86\xcb"
+  "\xb8\x00\x1c\x37\xb4\x7a\x25\x51\x04\x78\xef\x38\x83\x31\xb5\x65"
+  "\xa6\x70\x9c\xda\x05\x58\x33\xce\xbf\x28\xbe\x6c\x40\xde\x3e\xa4"
+  "\xa7\x96\x72\xac\xfb\x4f\x85\x96\x96\x99\xc2\x6b\x7b\x51\x93\xd2"
+  "\x16\x48\xab\xb2\x04\xd2\x2a\xf1\x3b\xee\xd8\x9c\x9b\x9d\x02\x70"
+  "\x4b\x8c\x7e\xf1\x1e\x00\xe8\x94\xb2\xa0\x5c\x44\x98\x46\x05\xe5"
+  "\x1c\x4f\x1a\xb0\x93\x79\x0f\xa0\x1c\xfd\x2f\x69\x53\xeb\xcb\x72"
+  "\xf0\xff\xaa\xa9\xba\x2e\xcb\xc3\x3b\xc7\xbf\x90\xdf\xfe\xd1\xdc"
+  "\x76\x19\x87\x5a\xdb\x7c\xcb\x83\xa2\xa6\xb2\xcd\x80\x09\x58\x43"
+  "\xf5\x73\x6c\x09\xef\xeb\xfa\x45\x6a\xb5\xd7\x99\xad\x49\x2a\xae"
+  "\x1f\x64\xdc\xd5\x60\xd2\xf2\xfb\xfd\x1e\x90\x97\xba\xc9\xc6\x7e"
+  "\x11\xf9\xe0\x3d\x17\x97\x31\xf2\xaa\xdd\x9a\xbf\xda\xa4\x85\x30"
+  "\x8e\x36\x65\x3f\x77\xb1\xfe\xc4\xda\x72\x7d\xff\xfe\xbf\x9c\x0f"
+  "\x4d\xe4\x52\xeb\x99\xf5\x72\xdf\xe7\x82\xdb\x4c\xd0\xd9\x5d\x37"
+  "\x8e\x96\x6b\x94\x90\xe6\x4e\x22\xe5\x8b\xba\xfe\x01\x43\xc7\xf2"
+  "\x79\x92\x75\x93\x08\xf0\x5e\xa2\x35\x2c\x02\x32\x66\x3a\xcf\x1d"
+  "\x74\x86\x7c\x15\x3d\x2e\x8e\xd5\x2a\x6d\x20\xb4\xab\xe6\x8d\x88"
+  "\x9a\x37\xd0\x7e\x20\xf9\x96\x42\xcc\x0f\x49\x67\x68\xbd\x83\xf1"
+  "\x67\xda\xf0\x7e\xb5\x06\x5a\xf9\x78\x9e\x64\xfa\xa4\x5f\xbf\x85"
+  "\x7d\x1a\xb8\xaf\xd6\x30\xfa\x1c\xdd\x2f\x93\xe6\xdf\xe1\x46\xbf"
+  "\x4c\xe8\x57\xf9\x59\x96\x99\x10\xfb\x9a\x40\xde\xc6\xc8\x78\xc4"
+  "\x72\xfd\xbc\x21\x27\xba\x8f\xac\xff\x55\x1f\x36\x2c\x4d\xd4\x47"
+  "\x61\xe2\x3e\x32\x0d\x36\xdc\xa1\xcb\x9b\xc4\x93\xf5\x47\x17\xad"
+  "\x0f\xa6\x6e\x62\x1f\x8f\xcc\x14\xe8\xb7\x59\x3c\x86\x98\x3f\x3d"
+  "\x8c\x67\xa2\xf1\x62\x78\x0a\xd6\x46\xd8\xd0\xae\x42\xe0\x72\x3c"
+  "\x31\xbd\x37\x9c\xbd\x32\xbd\x37\x7c\xc4\xf5\x19\x0f\xf6\x79\xb1"
+  "\x86\xb1\x58\x07\xdf\x62\xbd\xb6\x35\x51\xbb\xa9\x9b\x1a\x19\xaf"
+  "\x84\x79\x82\xe5\x45\xd7\x41\xe0\x43\x01\x39\x11\xac\x93\x7a\xdc"
+  "\x1b\xfb\xf7\xbf\xac\x49\x8e\x64\xa9\x1f\x4c\xc2\x93\x08\x86\x75"
+  "\x93\x87\x7d\x4c\x66\xa1\xfd\x84\xf9\x1a\x7f\x87\xc1\x93\x11\xd2"
+  "\x36\xff\xc3\x8d\xd6\x24\x9a\x19\x48\xfe\x87\xe1\xd6\xf2\xf0\x78"
+  "\xa6\x21\x60\x96\x43\x8e\xd7\xf0\x3a\x55\xed\x5d\x6c\x84\xfd\xbf"
+  "\x4d\xae\x4b\x03\x69\x19\x21\x15\x2b\x6c\x23\xe6\xbf\x57\xfb\xf7"
+  "\x70\x7b\xdc\x15\x66\x3f\x75\x64\x2a\xb9\xcc\xd8\x2d\x6a\xc7\xed"
+  "\xd4\xdc\x56\xe1\xd8\x60\x85\x1d\x59\xb1\x57\x13\x1c\x97\x7f\xdc"
+  "\xce\x01\x3e\x51\xfe\x2f\x06\x9f\xa0\xfe\xec\xc4\x3c\x50\xb1\xec"
+  "\xca\x3c\x50\x21\xf7\x66\x99\xee\x6a\xad\x52\xb1\xcd\xb0\x53\xc4"
+  "\xe6\x8c\xdd\x8e\x2a\xd9\xbe\x43\xb5\xcd\x34\xc9\xe1\x73\x89\x5c"
+  "\xd0\xc5\x85\xb2\x87\x0d\x3d\xc0\xfc\x62\x8d\xf0\x37\x0b\x48\xf2"
+  "\x34\xf2\x60\xff\x94\x66\xa9\xfd\xd2\x1b\xf3\xe4\x77\xf7\xdc\xeb"
+  "\x9a\x02\xce\xe2\x3d\xec\xaf\x1a\x4c\xcb\x2c\x43\x99\x90\x9f\x3e"
+  "\x94\x31\x49\x31\x07\x97\x00\x46\xe9\xce\x74\xcc\xd1\xca\x6f\x2b"
+  "\x85\x65\x9a\x63\xfc\xb0\x5c\x23\x6d\x34\xf0\xe6\x78\x3f\x58\xef"
+  "\x54\x66\xf7\xcf\x4b\xee\x1c\xe8\x0a\x21\xfd\x74\x30\x2f\x65\x76"
+  "\x83\x76\xbb\x4c\xda\x81\x4b\x53\xec\xc4\x7d\xbe\xb4\x79\xec\x81"
+  "\x17\x27\x93\xf9\x7f\xda\x9f\xa4\xd2\xdb\x68\xf4\xa6\xef\x98\xe9"
+  "\x7f\x4d\x23\x13\xd3\xc1\x4f\x95\x39\x8a\x76\x95\x2e\x63\x7c\xfc"
+  "\xb4\x51\xee\x8b\xf2\x5e\xe3\x82\xb0\xf8\x52\xed\x87\x56\x42\xff"
+  "\x3d\x6d\x57\xf9\xe5\x97\x9d\xff\xb3\x3d\xef\x58\xb1\xda\x51\xf4"
+  "\xdc\xba\x95\xe3\xc6\xc5\xac\x95\xcc\xf2\x0e\x8b\xbb\xf2\x90\x9a"
+  "\x4f\x2b\x3b\x0d\xbc\xd9\x2e\xc1\x3b\xfa\xbf\xee\xb2\x7d\xcb\xdc"
+  "\x02\xdd\x4d\xb9\x20\x9b\x06\x9e\x6f\xa5\xdc\x5b\xa3\x5e\x6f\xa7"
+  "\xdc\xdb\x6e\x2f\x78\x70\xd9\xd2\xa2\xf5\x51\xa9\x77\x44\xef\xeb"
+  "\x55\xef\x46\xdb\xc9\x63\xef\x85\xae\x48\x9a\xbf\x91\xe7\x96\xaa"
+  "\x4f\xaa\xc2\xe2\x2f\xd0\xd7\xd3\x20\x63\x05\x2d\x65\x61\x6a\x81"
+  "\x2e\x13\x19\xac\xc3\x87\xa9\xbb\x79\xb0\xa7\xc0\x5b\x56\xf4\x3d"
+  "\x00\xbb\xee\x22\xef\xcf\x9c\x26\x67\x52\x6b\x1d\xc7\xe4\x1d\xa7"
+  "\x9f\x7f\x54\x1d\x41\x7a\x1a\x7e\x3f\xc7\xef\x50\xfc\xfe\xd5\xb1"
+  "\x12\xeb\x1e\xf6\x85\x5e\xcb\xbe\xd0\x55\xd2\xd7\x63\x72\xd0\x45"
+  "\x93\x57\xb1\xcd\x5e\x55\xc6\x36\x88\x9f\x9c\xfc\x5d\x3c\xe2\xb2"
+  "\x48\xfb\xc0\xf1\x34\x65\xf3\xaf\x90\x67\x48\x55\x47\x44\xcd\xb8"
+  "\x36\xb1\x27\x9f\xbf\x71\x35\x1e\x6d\x8e\x4b\x4e\xfa\x8c\x92\xed"
+  "\xc3\x7a\x7a\xdc\x4e\xf6\x7f\x3a\xc1\x74\x1a\xec\x1b\x9a\x4c\xe7"
+  "\x78\xfb\x70\xc0\x36\x7c\x99\xa4\x7d\xab\xdb\x73\xfb\xe4\xbc\xe0"
+  "\x2c\x8b\xb2\xe9\xf8\x4c\x70\xb8\xb2\x4f\x44\x44\xd9\xa7\xce\x9d"
+  "\x86\x1c\xe0\xb9\xd1\xe0\xd3\x98\xf8\x68\x2b\xcb\x96\xad\x5a\x56"
+  "\xe4\x98\xb0\x7a\x38\x45\x45\x47\x2b\x5e\xb6\xd2\xb1\x6a\xd9\xf3"
+  "\x6b\x96\xad\x96\x91\xcd\x38\x37\x66\xce\x1f\x2d\xd2\x1d\x66\xe3"
+  "\xde\x8e\x63\x2c\xd3\xd7\x35\x84\x63\x6a\x89\x5a\xc7\x16\x3e\xfb"
+  "\x55\xeb\x8d\x5d\x73\x63\xd7\x1b\x9b\xea\x94\x9d\x37\xce\xab\xd6"
+  "\x3a\x9b\x26\xf1\xfb\x29\x72\x35\x0d\xc4\xef\x76\x2d\x05\x2d\x4d"
+  "\x8a\x6e\x16\x7f\x8f\xdb\x95\x6f\xd0\xcd\x4f\x9b\xfc\xba\x2d\xd5"
+  "\x25\xf5\x07\xe6\x58\xe8\xbf\x98\xf9\x55\x7d\x3b\xd3\xc5\xfa\x37"
+  "\x59\xee\xf7\xa6\x8d\x6b\xe6\xb6\x18\x26\xda\xf3\x63\x7c\xbc\xd0"
+  "\x9b\xac\xdf\xb6\x1a\xf0\xd0\xe6\x5c\x6e\x4f\x5f\x07\x7d\xe3\x0c"
+  "\x6d\x72\x48\xfd\xe8\x19\xd7\xcc\x3a\x85\xcf\x4e\xb5\x1a\xc0\x91"
+  "\x67\x79\x9b\xfc\x6c\x63\xca\x18\xf2\x80\xc5\xfb\xb4\xd0\x73\x27"
+  "\xf8\x3b\xab\x9c\xa6\x62\x7b\x39\x0f\xf2\xde\x30\xda\x3a\xd2\xe3"
+  "\xde\x64\x1f\xf0\x4d\xdf\xe4\x67\xbb\x93\xe1\xfa\xc9\x75\x92\xe1"
+  "\xa9\xd8\x65\x9b\xa6\x83\x77\x66\x0f\xd8\x4f\x9b\x5c\x51\xeb\x32"
+  "\xc6\x47\xe2\x19\x04\x2e\x32\x4e\xa6\xf2\x1d\x94\xfd\x66\xfd\xb9"
+  "\x53\xef\xbb\xd1\x1f\xc0\x83\xfe\x73\x66\x1b\x67\xcf\x7e\xbd\xdf"
+  "\x8c\x1f\xe3\x1e\x8d\xb3\x8e\xef\x61\xc6\x17\xf5\x9a\xa3\x64\x9b"
+  "\xf7\x65\x86\x20\xad\x7d\xc0\x27\xd9\xe5\x88\xd7\x1b\xcf\xad\x74"
+  "\x94\xac\x58\xf9\x4c\xc1\xba\xa5\xcf\x2c\x2b\x58\x53\x3a\xd1\xb1"
+  "\x66\xe5\x93\x25\xcf\x3d\xf5\x0c\x73\xcd\xea\xb2\x35\x4f\x3d\xe3"
+  "\x60\xcd\x52\x30\x3b\x37\xb7\xe0\xde\x87\x1f\x7a\x74\x38\xdd\xbb"
+  "\x14\x69\x58\xf9\xe7\x66\x4f\x54\x59\x0f\xce\x99\xf5\x48\xc1\xac"
+  "\x05\x0f\xcf\x5f\x28\x2f\x2d\xf4\xe7\xcf\x5e\x99\xb8\x40\x0c\x1f"
+  "\xda\xc0\x4b\xbc\xe6\x18\x72\x8a\x5e\x58\xac\xe2\x5d\xbb\xb7\xc5"
+  "\xc6\xbb\x76\x63\x2d\xeb\xf6\xe2\xef\x24\xd1\x16\x1b\xfe\xb0\x4e"
+  "\x7d\x21\x4f\xf1\xd7\x35\xf7\xf7\xb8\xdd\x87\x07\xf8\xeb\x05\x19"
+  "\x53\x89\x7d\x39\xd4\xfe\xac\x1b\xfa\xdf\xd9\x1e\x9d\x37\xb0\x9e"
+  "\x74\x07\xfa\xd7\x93\xfd\x3a\x65\x73\xa6\xb1\xb6\x44\xda\x31\xac"
+  "\x2b\xaf\xe1\x75\xa5\xda\x4f\x7a\x61\x89\xe4\xa9\x41\xe5\xdb\x42"
+  "\xc6\xba\x92\x65\x9b\xcf\x8a\xd5\xfa\x63\x73\x7e\xb4\x8c\xcb\x18"
+  "\x8b\xba\x8c\x73\x3d\xb9\x7f\x67\xdb\x35\x95\xf7\xb4\x61\x1f\x1f"
+  "\x81\xad\x80\xf9\xab\x47\x88\xb4\x5d\x53\x75\x9c\xea\x78\x8f\x9b"
+  "\xed\x66\x9d\x9f\x52\xcf\xd0\xe6\x8f\x85\x7b\x53\x97\x5a\x53\xba"
+  "\xaf\x63\xbd\x2e\x36\x8f\xbd\x77\x41\x44\xc6\xa3\x83\x4e\xdf\x7c"
+  "\x7c\x80\x67\x5f\x58\xcc\xbc\x30\xb0\x96\xdd\x1c\xa3\xff\xbb\xe5"
+  "\xb7\x1a\x37\x87\x8d\xfb\xfa\x65\xe3\xc8\x64\x1e\xe7\xa1\x9d\x26"
+  "\x81\xf9\x68\xf3\x41\x6e\x83\xe9\xe9\x27\xf7\x31\x94\x35\x0f\xd0"
+  "\x6f\x4b\x76\x3f\xfd\xf4\x7d\x16\x63\x8f\x45\xe1\xfd\xc2\x92\xc1"
+  "\x68\x95\x98\x4e\x5b\x5c\x5f\x49\x27\x37\x0d\x61\x99\x34\xe8\x75"
+  "\x39\xad\xb6\x34\x5f\x4e\xab\x17\xae\x8d\xa2\xd5\x8c\xcb\x69\xb5"
+  "\x25\x14\x75\xee\xa3\xef\xa3\xbc\xb0\x84\x69\xc6\x3c\x86\x7e\x1f"
+  "\x04\x9f\x6d\x1e\xa0\xdf\x0b\x59\x97\xd3\xef\x85\xe9\x89\xe9\xb7"
+  "\xa5\xfd\xc6\x58\x38\x2f\x25\x9a\x37\x52\x37\x99\xf4\xfb\x3c\x2f"
+  "\xbc\xdb\x9c\x29\xd7\xa4\xa1\x57\x4d\x5a\xf1\xab\x6e\xfc\xe1\x97"
+  "\xd7\x11\x03\xb6\xb8\x08\xe9\xf4\x6d\x6a\xc6\x9a\x97\xf7\x95\xae"
+  "\x30\x17\x9d\x34\xf6\x3c\xf0\xdc\xce\x6b\xe7\x05\x91\x99\x82\xd3"
+  "\x99\x9e\xfc\xad\x28\xf0\x7b\xbb\xb2\x4b\xff\x91\xfa\xf7\x5c\x26"
+  "\x67\x7a\x92\x37\x91\xe3\x68\xfd\x6d\x9c\x6e\x07\x0f\x49\xdf\x27"
+  "\xf9\x2d\xd5\x41\x60\x16\x44\x72\x68\x10\xb8\xfd\xfc\x3f\xd8\x9d"
+  "\xd6\x38\x7d\x54\xbc\x74\x65\xd1\x73\xcb\x97\x7f\xb5\x2a\x8a\xf6"
+  "\x1f\xf3\xb8\xb5\xad\x3d\xfc\xad\xc4\xcd\x4f\x6f\x40\x9b\x6c\xff"
+  "\x5b\xd4\xbc\xf9\x8f\xd0\x7f\x3f\x3a\xa2\x6c\xc9\xc7\x3b\xd5\x3d"
+  "\xde\x17\xa7\x46\xe9\x67\xf0\xc8\x8b\x39\xc2\xfd\x8f\x15\x03\x63"
+  "\xfc\x62\xca\xe5\x63\xfc\xa2\x23\xf1\x18\xbf\x38\x5b\x5b\xcb\xf7"
+  "\x2a\x5e\xc4\xfa\x67\xa5\xb4\x35\xf9\x9d\xcf\xcb\xb1\x66\xee\xc4"
+  "\x7a\xb9\x6b\xc1\x7a\xef\xcc\x82\xf5\x49\xec\x0f\x2e\xbf\x9d\x11"
+  "\xbe\x24\x3a\xf8\xcc\x9a\xcf\xc7\xf8\xdb\x19\xfc\xcd\x1c\xfe\x86"
+  "\xaa\x2c\x83\xe7\xea\xd3\x24\xd7\x8e\xc8\x77\x34\x9c\x96\xdf\xf8"
+  "\x85\xad\xf0\x62\xa3\x61\x5b\x5b\x31\xbd\xf1\xfd\xe2\x1d\x6a\x3c"
+  "\xda\x79\x2c\xb8\xbd\x82\xf5\x5e\xd5\xc6\x25\xfe\x3e\x16\x59\x95"
+  "\x0d\xf1\x62\xfb\x15\xf7\xee\xd3\x2a\x07\xbb\xf7\x0c\x79\x71\x0d"
+  "\x7b\x55\xc5\x9e\x66\x9f\xc6\x80\xe1\x53\xc7\xfe\x75\x3d\xee\xad"
+  "\xd9\xf1\xfe\x79\xca\xc7\x64\xeb\x5c\xc3\xb7\x07\xcf\x0b\xfb\xd7"
+  "\x03\xfc\xbd\x15\xac\xe3\x1c\x55\x9b\x86\x9e\xa3\xad\xd7\x36\x0c"
+  "\xb2\x87\x6e\xdc\x27\xd6\x7d\xe0\x86\x01\x46\x5d\xbf\x5f\x10\xde"
+  "\x59\x5f\x0c\xf8\xf6\x6d\x3d\x64\xf8\x86\x49\x7f\x40\xcc\xbd\xfc"
+  "\x4d\x97\xd3\xb4\xf5\x63\xf9\x0d\x99\x1b\x79\xff\x7b\x6b\xb0\x59"
+  "\xfa\x25\x6e\xf5\x47\xe3\xa2\xe3\xf1\x26\xef\xd1\x72\x7e\x34\x2e"
+  "\xe5\x4b\xd7\xac\x98\x52\xbe\x7c\x85\xe3\xa9\xe2\x15\xa5\x05\x2b"
+  "\x64\x0c\x58\x19\x5e\xb6\x6c\x7d\x29\x9f\x48\xdc\x3c\x3c\x6e\x0e"
+  "\xd3\x7d\x08\xfb\x7d\xa5\xa4\x1f\xe1\x4b\x8f\x82\x1e\x26\xe5\x47"
+  "\xf8\x72\xae\x9a\xd7\x5f\x2a\xba\xdc\x67\xe6\xa5\x7e\xff\x2f\xf0"
+  "\x95\x6d\xa7\x8a\x3d\xaf\xfb\xd9\x30\xdf\xbd\x54\x97\xa0\xce\xc1"
+  "\x7e\x9f\x31\xf6\x5d\xea\xcb\x97\xf7\x3d\x64\x9c\xf0\x5a\x1e\xb7"
+  "\x97\xc8\x57\x3e\x87\x63\x9d\xea\xfc\xfc\xd2\x49\x83\x9f\x0d\x7f"
+  "\x43\x86\xc5\xf7\x4d\xa6\x84\xa2\x7d\x8d\x5e\xbe\x07\x73\x9e\xbd"
+  "\xbf\x1f\x1b\x4d\xc4\xb8\x07\x4d\x5e\xe0\xf1\xb2\x23\x1e\x0f\xe0"
+  "\x37\x0e\xe9\xd3\x06\x7c\xb9\x8c\x7e\xbe\x9c\x8b\xe7\xcb\x6c\xd5"
+  "\x7b\xe6\xe4\xc2\x28\x5d\xbd\xac\x6c\x38\xcd\x5a\x5a\x52\xc2\x72"
+  "\xbd\x74\x59\xc9\x9a\x55\xcf\xad\x2e\x58\xb1\x72\x05\x52\xef\x59"
+  "\xce\xa1\x79\x65\x91\xbb\xf4\x1c\xc7\xca\x65\xcb\x8a\x54\x92\x3e"
+  "\x0c\xb1\xe7\x40\xea\xec\xfe\xe5\x23\x7e\xda\x5a\x36\x60\x7f\xbd"
+  "\x32\x5a\x98\x5e\xce\xc7\xdf\x53\x52\xa6\xa5\x6d\xf4\xb2\x3f\x76"
+  "\xdd\xf3\x72\xc0\xe0\x07\x39\x7e\x4e\xf6\xf7\xc9\x58\xd1\x2d\xe4"
+  "\xb9\x09\xc6\x6c\xdb\x1c\xfe\x3e\x36\xd6\x64\xb3\xd9\xde\x1f\x80"
+  "\xf3\x4a\xbf\xfe\xe7\xfb\xf5\x9b\x95\x9f\x80\x99\xbf\xe9\xc9\xf7"
+  "\xec\x91\x0f\xfe\x7f\x31\xac\xf8\xff\x95\x7e\xfe\xef\x36\x25\x63"
+  "\x0d\xf7\x4a\x91\x61\xcf\xc7\xca\xcc\x2b\x15\x97\xcb\x12\xfb\x7f"
+  "\xbe\xb2\xd3\xa0\xad\x31\xce\x8a\xb7\xb6\xdd\x6a\xec\xc3\x36\xe8"
+  "\x71\xe2\xf9\x99\xeb\xb2\xad\x2e\x52\x47\xce\x64\x7f\xf6\x53\xb4"
+  "\x4d\xe7\x97\x57\x4e\x46\xf9\x65\xd9\xce\xd0\x2b\x61\x35\x4e\xaf"
+  "\x04\x0d\xfc\xfc\xf4\x8a\x3c\x0f\x60\x18\x4a\xf6\x5f\x5e\xaf\x78"
+  "\x67\x9b\xdd\xa0\x2d\xaf\x8b\xf1\x9e\x35\x60\x5b\xbc\x7c\x4c\xfa"
+  "\x48\xa8\x38\x03\x7d\xdc\x7f\xc0\x39\x60\xc0\x41\x59\xf4\xdf\xd2"
+  "\x6c\xd0\xca\x28\x13\xcd\x13\xb3\x96\x96\x62\xd1\xba\x62\xf9\xf2"
+  "\x65\xab\x56\x1b\xb1\x97\xb3\x9e\x2b\x29\x52\xb1\x96\xef\xc2\xf0"
+  "\xaf\x83\x04\xce\xe0\x70\xcd\x48\x55\x8f\x71\x36\xe4\x44\xde\x67"
+  "\x90\xbe\x7b\x72\x1d\x53\x73\xeb\x3e\x7d\x4d\x73\x8a\xb6\x37\x2b"
+  "\xdf\x97\xed\x2f\x28\x7b\x71\xc4\xf3\xc0\xa9\xd3\xb0\x17\x79\xff"
+  "\xb2\x9b\x1c\x21\xbe\x47\xc4\xfe\xcb\x7b\x5f\x13\x1d\xbc\x5f\xd9"
+  "\xe3\xde\x9e\x62\x7c\x9f\x8b\x6d\x91\xed\xea\xdb\xe6\x01\xef\x4a"
+  "\x8e\x6d\x5f\xf3\x80\x56\x93\xd1\x29\xd2\x47\xd8\x61\xf3\xc8\x3d"
+  "\xce\x91\x5d\x1c\xf7\x9e\xe3\x01\x6d\xcf\x67\x5b\x89\xf5\x0b\xc7"
+  "\xb0\xef\xa0\xed\x59\x58\xdf\xd8\xfc\x54\xb3\x30\x90\x96\xd1\xb9"
+  "\x65\x03\x59\xb8\x0d\xe8\x26\x7f\x73\x23\xd3\x76\x7b\xd9\x47\xd0"
+  "\x3d\xfa\xfe\xae\x9f\xdb\xf1\xd3\xf6\x1c\xb5\xc6\xca\x08\xab\xbd"
+  "\xcb\x0c\xf0\xd1\xf6\x7a\x3f\x8d\xd4\x63\x82\xa7\x54\x7f\xdb\x45"
+  "\xe5\xfc\xdd\x3e\x15\xcb\x67\x42\x1e\xfa\xe1\xe1\x6f\xe3\xc1\xbe"
+  "\xc2\x1a\x62\x5b\x27\xfa\xe0\x51\x71\xc0\x99\x57\x76\xdc\xa3\x7c"
+  "\x8b\xb7\xb5\x33\x0d\x84\x27\xd3\xa2\xef\x89\x5a\x00\x17\xe3\x9f"
+  "\x51\xa8\x78\x75\x07\x19\x6d\x60\x4e\x09\xc0\x16\x3d\xcc\xf6\x28"
+  "\xf0\xf6\xe3\xaf\xa3\x5a\x9e\x4f\xfb\xb1\x6e\xb1\x0a\xf6\x1b\x1a"
+  "\xf8\x06\xd9\x8e\x69\xc6\xfc\xc2\x6d\xeb\xe7\x00\x66\xde\x3f\xe3"
+  "\xbd\x33\xbd\x2d\x33\xaf\xaf\x0d\x98\xe8\x93\x5f\xbb\x74\xb6\x11"
+  "\x30\x2d\x98\x2b\x03\xfa\xb7\xa7\x3a\xaa\x2f\xb0\x8f\x99\x1f\x73"
+  "\xe1\x0d\xa2\x20\x6c\xe3\x73\x9d\x91\xc6\xb7\xbd\x1a\x2e\x30\xbd"
+  "\x76\xec\x1f\x38\xaf\x41\x7d\xd0\x1f\xf2\xe0\xea\xa0\x1d\x1f\x70"
+  "\xbb\x2c\x0b\x3c\x96\xbd\x18\x1b\xfe\x4e\xbc\xb8\x74\xb6\x09\xeb"
+  "\xfc\x91\xa0\xc1\x67\x3c\x46\x7c\xc6\xca\xbe\x5f\x48\xb3\x72\x2c"
+  "\xf2\x53\xb4\xa3\x85\xc7\x87\x71\x11\x9e\x11\x81\x70\x4f\xfe\xf7"
+  "\xf9\x3e\x2a\xeb\xc3\xca\x0a\xd8\xb1\xcb\x59\x97\x78\x1e\xe0\x75"
+  "\x31\x7f\x43\x86\x9f\x9d\x45\x42\x93\xe3\xbb\x81\xc7\xd7\xf3\x40"
+  "\x65\xa7\xd0\xbe\x74\x93\x38\x16\x24\xfa\xd2\x44\xe1\x90\x29\x89"
+  "\xf1\x36\x39\xcf\xf2\x9d\xd9\x46\xe8\xe1\xad\x84\x76\x2d\x3b\x36"
+  "\x90\x8d\xef\x18\xf3\xf7\x51\x5a\x83\xf5\xd4\x5a\x5a\x4f\xff\x12"
+  "\xde\x49\xde\xb5\x1c\x33\xc2\x13\xfa\xd7\xf2\x9d\x7c\x6e\x75\x0d"
+  "\x9e\xdf\x77\x3c\xc2\x6d\x55\x7b\xfe\xf5\xc4\x9f\xe8\x5f\xbd\x7f"
+  "\x22\xc7\x63\xf2\xbd\xf1\x78\xfe\xbf\xd0\xf1\x9c\x7f\x21\x67\x87"
+  "\xd0\x78\xad\x54\xf5\x2c\xb7\xb1\x15\xb0\x1a\xf9\x6e\xae\x4d\xeb"
+  "\xb6\x0f\x47\xff\xcd\xbc\x27\xdf\x1a\x0c\x90\x77\xe5\x6f\x19\xc7"
+  "\x71\xfb\x2e\x90\xc5\xbb\xf2\xf7\xf2\x59\xad\x61\xce\x36\xfa\x8a"
+  "\xda\xd9\x4e\x0b\xf3\x5d\x64\x3e\xe7\x83\xdd\xae\x55\x33\x8e\x11"
+  "\x85\x37\x7f\x4b\xdd\xa8\x0f\x3b\x4e\xaf\x5f\xdd\xc1\xf5\xf7\x32"
+  "\x3d\x80\x53\xcb\x42\x45\x93\xe3\xed\xa0\xe9\x23\x3a\x7d\xf2\xa3"
+  "\xe9\x53\x9d\xc3\xf4\xe1\x38\x96\x1a\xc6\x0b\xb8\xe5\x80\x06\x9a"
+  "\xd1\x06\x70\xb6\xe8\xfb\xa2\x96\x1d\x17\x28\xc5\xbb\x92\xbf\x8f"
+  "\xe5\xf9\x89\x35\xcf\x6c\xd1\x2e\x9d\x6b\xaa\xbe\x48\x66\x1e\x37"
+  "\x3e\x0b\xa9\x96\xf9\x92\xe6\x5b\x79\xcc\xc0\x93\xf9\xf8\x5b\x8c"
+  "\xbf\x42\xe6\x3b\xfc\x16\x61\xbc\xb6\x02\x07\x07\xc6\xaa\x91\x7f"
+  "\x15\x2f\xa6\x78\x38\x56\x83\xbe\x2e\x19\x48\x87\x1c\x85\x85\xfc"
+  "\x1e\x2d\x64\xc6\xe3\xd0\x20\x47\xbc\x2f\xb2\xaf\x96\x52\x34\xf7"
+  "\xb6\x92\xbd\xd0\x75\xf5\x98\x4b\xf7\xa5\x93\x8d\xf7\x0a\x77\x4b"
+  "\x5f\xf4\x9a\xf1\x86\xee\x7b\x79\x0c\xdf\x6f\xf3\xe4\x99\x78\x2f"
+  "\xc5\x93\x49\x3a\x9f\x83\x47\x6b\xa0\xff\xc7\xe8\xdf\x1f\xdb\x2e"
+  "\xfd\x8e\x59\xf6\x07\xb3\xd1\x61\x1f\x1e\x17\x7b\xf2\x89\xcf\x54"
+  "\x52\x36\x89\x40\x4a\x87\x55\xb4\x06\x8f\xcb\x7b\x8d\xad\xc1\x88"
+  "\x3c\x53\x41\x7e\xd2\xfc\x60\xc0\x0a\x7b\xb2\x8d\x69\x67\xa4\xf3"
+  "\x79\x0c\xef\x55\xcd\x0f\x8a\xc0\x82\xf5\x56\xfe\x3e\x60\xa6\xdc"
+  "\x8f\xd7\xd3\x5b\xed\xb0\xc5\xd7\x07\xac\xe8\x7b\xb8\x1f\x56\x77"
+  "\x7e\x32\xcb\x1b\xca\x8e\xee\x2f\xdb\x9d\x6f\xe6\xef\xde\x72\x9b"
+  "\x51\x69\x43\x16\x94\xa3\x2e\x8f\x95\x9e\xa6\xec\xd0\xda\xac\xfe"
+  "\x75\x1a\xc7\x6b\xec\xc6\xbc\xb9\x3a\x3f\x49\xeb\xce\x37\x45\x00"
+  "\x1b\xbc\x6f\x93\xdf\x29\x0c\x07\xf4\xef\xfe\x74\x42\x7e\xdb\x49"
+  "\xd4\xec\xca\x43\x39\x33\xc3\xe5\xbb\xf1\xfc\xbd\x04\x91\xf6\x7a"
+  "\xc2\x18\x2b\xc2\xb3\xd9\xe2\xad\x7a\x0c\xfc\xf4\xaa\xbc\xe3\x19"
+  "\xb1\x65\x06\x1d\x4f\xb3\x7d\x52\xfb\x4f\x4c\xcf\x08\x64\x2c\x92"
+  "\x96\x19\x9c\xd2\x49\x49\x55\xe0\x5b\xb5\xaf\x53\xfb\x47\x8e\x05"
+  "\xe0\xd4\x04\x6c\xbe\xda\x23\xcc\x37\xd6\x2e\xf6\x3f\xcb\x0c\x49"
+  "\x9f\xaf\x74\x27\xf9\x42\x9d\x74\xdc\xf5\x67\x3a\x1e\xf6\xb9\x8e"
+  "\x5c\x08\x98\x95\xef\x97\x99\xe1\x7e\xc2\x79\x4e\xf0\x6a\x41\xa4"
+  "\x91\x06\xdb\x6f\xe7\x35\x27\xe6\xb0\x4f\xd5\xfa\xeb\xd5\x6c\x63"
+  "\xad\xf9\x15\x7d\xd8\xca\xf1\x04\x84\xb0\x93\x56\xbb\x24\x1b\xb8"
+  "\x38\x45\x4f\x16\x4d\xd9\xc0\xfb\x5c\xaf\x16\xc2\xee\xcf\xd1\xe1"
+  "\x9e\xd7\xe1\x6e\xbd\x12\x5c\xe6\x99\xe3\x75\xf2\xac\x07\x7d\x5a"
+  "\xe2\x88\x00\x76\x24\x7d\x09\x7f\x27\xcb\xe9\xfc\x92\xf7\x41\x77"
+  "\xb6\xa0\x1d\x47\x6b\xb8\x8d\x38\x36\xc9\x3e\x0d\xf3\xe3\x79\x3b"
+  "\xe9\x7e\x6e\xce\x73\xf4\xea\xfb\x9a\xc8\xb2\x61\x0d\xcc\x7b\x6c"
+  "\x4e\xd6\x71\xbc\xbe\xae\x8a\xd0\x50\x5f\x99\x9f\xf8\x5e\x3d\x60"
+  "\x7c\xf4\x07\x3e\x4f\x82\x9e\x88\x08\xbb\xe9\x83\x4b\x7e\xf9\x0d"
+  "\x30\x79\xcf\x7e\x73\xc6\xee\xd4\x4d\x34\x53\x98\xac\xd2\x8f\x51"
+  "\xab\xa9\x9c\x86\xb1\xcd\x57\x7e\x75\x99\xb6\x28\x9f\xba\xe4\x73"
+  "\xb4\x73\x06\xfb\xd4\x09\x5b\x06\xdf\xcb\x0c\x0a\x8c\x59\x8f\x7b"
+  "\x67\xb1\x9f\x6a\xcb\x99\x7f\xb6\xb1\x7f\xbd\xd4\xb1\x3b\x3f\x0e"
+  "\xa4\x3d\x2a\xfb\xc4\xdf\x1c\xd6\xd6\x46\x9a\xaa\xbf\x20\xb3\xa2"
+  "\xc7\xce\xf7\x5a\xbb\x7a\xbc\xc2\xf3\xa8\xfc\x4e\x99\x0e\xdb\x0a"
+  "\xd8\x2f\x88\x9a\x47\x31\x67\xed\x54\xf1\x0c\x3d\xf2\xb9\x91\xf3"
+  "\xc3\x7d\x59\xfc\xcc\x31\x0f\x2c\x7e\x7a\xf5\x98\x70\xdf\xe0\xed"
+  "\xb6\x3d\x4a\x0f\xd9\xd9\xa6\xda\xd9\xe9\x37\xfd\xa1\x5e\xdf\x5b"
+  "\x93\x31\x03\xe2\xf7\xc4\xfa\xc7\x70\x8f\x7d\xb8\x0f\x40\xb0\x46"
+  "\x1c\x7d\x86\x5e\x7f\xb4\xd7\x4d\xa6\x3e\xd8\x82\xbd\x26\xd8\xfc"
+  "\x7b\xf2\x53\x76\x8c\x25\xbe\x67\x3c\xf6\x0c\xed\x9a\x11\x36\xd1"
+  "\x68\xfc\xd9\x02\x19\xc5\xd7\x00\x6e\x0e\xef\x3b\xb6\x5c\xe0\x7d"
+  "\xa3\x5d\x7b\xa5\xad\xb6\x9b\xc6\x6b\x80\xc7\x67\x28\xd5\x63\x69"
+  "\x3c\xef\xfd\x21\x2d\xab\x20\xa2\xce\x12\x8d\xf5\xfd\xe6\xb1\x34"
+  "\x31\xb6\xdd\x5d\x7a\x2c\x80\xd7\xf3\xf9\x77\x5d\x80\xae\x2f\xbd"
+  "\x9b\xbf\x27\xf9\x9a\x5d\xb8\x93\x85\xc8\xb0\x9b\xd4\x79\xff\x6b"
+  "\x49\xd6\x3a\xc5\x77\xf2\xec\x0c\xfc\xc6\x67\x93\xfa\x39\x4d\x92"
+  "\x8c\x95\x90\x3e\x6e\x0b\x7f\x9f\x37\x6a\xef\xd5\x26\xf1\xd0\xef"
+  "\x39\x47\x36\xdf\x52\xc8\x30\x18\x9f\x82\xa5\xea\x8c\x87\xef\x40"
+  "\xfb\x69\x97\x8c\xc7\xbb\x6d\x37\xa5\xbc\xb2\x9b\x6c\x2d\xcb\xb9"
+  "\x5f\xaf\x65\x2b\x59\x34\x13\xe3\xab\x79\x58\xce\xc0\x13\xc0\x9b"
+  "\xdb\x63\xde\x68\x0d\x9f\xf7\x3a\xcb\x84\xe6\x7d\x9a\x6d\xd1\xd7"
+  "\x9e\xf7\xae\x3a\x48\x0b\xf8\xce\x38\xdf\x17\x5b\x4c\x81\x06\xc0"
+  "\x6b\x18\x4b\x36\xc0\xaa\xf4\x95\x10\x9f\x01\xdc\xe8\x5d\x75\x88"
+  "\x61\xd7\xf0\x5c\xb0\x1d\xf4\x51\x73\xc2\xeb\xb3\x7d\xa1\x76\x6a"
+  "\x81\x7c\xcf\x2f\x15\x11\x86\x83\x32\x7f\x94\xfd\xdd\x63\x77\x14"
+  "\xa8\x7b\xea\xb2\xaf\xfd\x67\x67\x7a\x3f\x7c\x17\x24\xbc\x93\xbe"
+  "\x42\xd8\x78\x7a\x9f\x0c\x5a\x2b\xfe\x7a\xfd\x9b\xde\x55\xfb\x89"
+  "\xc7\x87\xcb\xe3\xdd\xe2\xeb\x42\xd9\xb3\xb1\xe3\xc2\x65\x90\x77"
+  "\x27\xe0\x7e\x77\xe0\xfc\x97\xcf\x25\x07\xca\xd4\xef\xe6\xfb\x30"
+  "\xbb\x2a\xf6\x80\x46\x6a\xbf\xfc\xb5\x9f\x30\xae\x7e\x7a\x6d\xbf"
+  "\xaf\xec\xcf\x83\x7c\x27\xb2\x8a\x7d\x3d\x37\xb5\xca\x73\xb0\xd7"
+  "\x77\xcd\x0f\x6b\x42\xe9\xb3\xba\xb9\x1a\xf4\x80\x1f\xbf\xac\x0b"
+  "\xa4\x3e\x99\xcc\xbe\x35\x75\xf7\x5b\x93\xd4\xf8\x72\x5f\xd8\x5e"
+  "\x49\x34\xc6\x51\x67\x74\x36\xc6\xd5\x18\x63\xfe\xae\x9d\xc6\xe7"
+  "\xac\x63\x41\xef\x3e\x3b\x29\xfe\x13\x1e\xc0\xd5\xef\x47\x64\xe6"
+  "\xe9\x73\x59\x5e\x77\xda\x75\x24\x36\xda\xc9\xf0\xb7\x85\xfc\x86"
+  "\x0b\x94\x0f\xb3\x9d\x75\x54\x83\x49\xe8\xf1\xf6\xea\xe6\xea\x75"
+  "\x73\x95\x9f\x43\x9d\x05\xf5\x73\x13\xf6\x37\x19\x7a\xc7\x0d\x35"
+  "\x8d\xfe\xb0\x1d\x29\xa0\xab\x30\x1f\x0c\xf5\x05\x7b\xf5\x6f\x0a"
+  "\xd6\xfd\x01\x36\xf5\x50\xbe\x9b\x62\xe0\x76\x75\xe7\x69\x75\x1e"
+  "\xb5\xb6\xa9\x6b\x33\xf6\x6b\x84\x0d\x34\x76\x5b\x05\xdf\xe1\xe2"
+  "\xbb\x06\xc1\xb4\xcd\xb0\x1f\x76\xe5\x28\xb9\xa9\x0b\x89\x34\xa5"
+  "\x6f\x0b\x42\xfc\x4d\xf7\x2a\xde\x37\xe7\xbb\x61\x43\xb9\xcf\x3d"
+  "\xee\x37\xb0\xfe\x29\x59\xac\xe6\xf3\xba\x41\x7d\xaf\xe5\x9a\xc9"
+  "\xe8\x1b\xfa\x24\xfb\x86\x3e\xca\xbe\xe9\xdf\xdc\x39\x4d\x6f\xc8"
+  "\xbb\xdb\x57\xd7\x9f\x37\x0a\x15\x6d\x37\xdb\xf8\x7b\xa2\xa7\x69"
+  "\xcf\x24\x79\xff\x00\x63\xa2\xce\x16\xde\xe8\x14\xc3\x5f\x19\x7e"
+  "\x95\x30\x0f\x29\x98\xbb\x72\x76\x71\x7c\x3e\xfd\xbb\x5d\x80\x7d"
+  "\x2d\x74\x79\x0e\xaf\x1d\xba\xd1\x1e\x7f\xf7\x70\x40\x0f\xed\xae"
+  "\xe3\xb1\x9a\x7c\x90\x72\x14\x1f\xee\xde\xce\xfb\xb7\x6a\x9d\xb7"
+  "\x7b\x3a\xf8\x5e\xad\x4f\xfa\x7d\xb3\x93\xa4\x6f\x76\xb4\x8e\xbd"
+  "\x3a\x1c\x77\x4b\x59\x16\xe9\x15\x7e\x3c\x4f\x64\x1f\x03\xc6\x77"
+  "\x5d\xd8\xd0\x7f\xbb\x27\xb2\x9f\x4f\xff\x19\xfb\x7a\xf0\x4a\x95"
+  "\xba\xbb\x0a\x7c\x8e\x1b\x36\x8a\xfc\x4e\x93\x5b\x1c\xe3\x72\x0b"
+  "\xd6\x9f\x97\x67\xf0\xd5\xf2\x9e\xf6\x19\xfd\x8e\xd3\xee\xcf\xf4"
+  "\xfd\x8c\x2c\xf6\x8b\xef\x71\xef\x41\xdb\x47\xa4\x3f\x0f\xd3\x80"
+  "\xdb\x96\xb8\xcb\x6f\x25\xed\x19\x3f\x70\x96\xb2\x5b\x9e\x4f\x28"
+  "\x5f\xd1\x3d\xd3\x0d\x1e\x41\x7f\x87\xaa\x78\x89\x6f\xfc\xe4\xe8"
+  "\x44\x92\x3c\xd0\x2d\xec\xc3\xbf\x55\xcf\x3c\xb9\xa7\x28\x9a\x4e"
+  "\x0b\xc2\x9a\x53\xe9\xa0\xdd\xb9\x42\xca\xfa\xee\xdc\xaf\xb6\x27"
+  "\xf6\xbc\x6f\xd8\x22\x8a\xce\x36\xe8\x97\x7d\x5b\x24\xad\x3d\x29"
+  "\xd9\x1c\xcb\x62\x63\x15\xc7\xe3\xa9\x5f\xcf\xb1\x8e\xc2\x9e\x94"
+  "\xbc\x08\xdf\x87\xc3\x3c\xab\x79\x52\x0a\x4f\x97\x92\xa9\xa0\x94"
+  "\xcf\x8f\xf2\xdb\x78\x7d\x25\x9c\xb0\x05\xd2\x61\x9f\x40\xce\x2b"
+  "\x57\x90\x75\x49\x31\x60\x3b\xb3\x46\x73\x2c\x22\x8e\x43\xc4\xf1"
+  "\xc4\x22\xce\xac\x74\x3c\x8f\x81\x3d\x67\x13\xb6\x94\x1c\xf6\x41"
+  "\x89\xb8\x05\xf4\xf1\x49\x8e\x87\x64\xf2\x05\x42\x54\x79\x96\x2c"
+  "\x1c\xeb\x28\x5c\x93\xdf\xd9\x1a\xfc\x44\xae\x2d\x52\x4b\x61\x4f"
+  "\x6b\x94\x09\x9a\xdb\xb5\xb4\xfc\xb6\x40\x5a\xfe\x09\xd5\xef\xf3"
+  "\x42\xf5\x5b\xe1\xcd\xf8\x2b\x1d\x97\x5a\x58\x25\x71\xdf\x77\x5d"
+  "\x18\xf0\x35\xcf\xa8\xc5\x11\xcf\xa8\x7c\x75\x8f\xee\x38\x55\x95"
+  "\x89\x4e\x1f\x6c\x63\xf6\x89\xe4\x3b\x85\xec\xe3\xc2\x7d\xe4\xfe"
+  "\x71\xdb\xff\x7a\xe1\xac\x8c\xdd\x14\xc6\xbb\xb3\x44\xaf\xd3\x85"
+  "\x3a\x5d\xc7\xa9\xd7\x33\x4a\xf6\xbd\x35\xa8\xea\x16\xc8\x67\xae"
+  "\x1f\x45\x07\xbd\xcf\xfd\x74\x40\xdf\xb9\x7f\xdc\xff\x30\xd3\x04"
+  "\x34\xd0\xfb\x6a\xef\xd3\xfb\xc9\x7d\xfc\x17\x70\xea\x6e\xf4\x13"
+  "\x7d\x95\xfd\xec\x43\x3f\x8f\x15\x13\x85\x6a\x37\x3b\xbe\x4c\x1f"
+  "\x95\xcf\xeb\x43\xe7\xbf\xc1\x8e\xae\xf0\x10\xd6\x81\xe6\x5f\x54"
+  "\x79\x4c\x2f\xc3\x36\xa9\x0a\x60\x3d\x18\x10\x9d\x6c\xef\xfb\x4a"
+  "\xf1\x17\xae\x97\x36\x8e\xb4\x8f\xf9\xbb\x99\xcf\xa3\x4f\xda\xe7"
+  "\x54\xd5\x29\x3a\x61\x9b\x86\x7c\x61\x94\x29\x46\xff\xb1\x7e\x3c"
+  "\xad\xe3\xcf\x65\x2b\xbf\x50\xfd\xb2\x96\xd0\xe8\x0f\x1f\xdb\x6a"
+  "\xf2\xb5\x6f\x25\xa3\x2f\x4f\xa0\x1c\xfa\x63\x07\x2c\x19\x37\x5e"
+  "\x43\x3f\xf7\x00\xcf\x50\x54\x9f\x5a\xba\x42\x80\xf9\x31\x0d\xcf"
+  "\xa3\xa4\xdd\xe7\xd0\x8f\x73\x64\xf7\x54\xc1\xfe\x7a\x90\xed\xc5"
+  "\xbd\x0f\x8f\xc8\x27\xf0\x7d\xbd\xfa\x5e\x89\x8a\xad\x72\xed\x19"
+  "\xda\x57\x69\xc4\x4f\xd1\x38\xfe\x54\x5a\x7e\x17\xf3\x91\x8c\xa5"
+  "\xc2\x73\x46\x0f\x78\x86\xfd\x53\xd6\xa1\x8d\x9e\xac\x31\x12\x1f"
+  "\xb7\x8a\xbf\x82\x77\xfe\x8e\xce\x68\xde\x13\x40\xbd\x4e\x01\x9a"
+  "\x31\x7c\x51\x93\x7f\x82\x7f\x99\x86\x09\xef\x6f\xbc\x4d\xd3\x44"
+  "\x7a\x26\xaf\x2f\x4c\x4d\x55\x01\xd3\x0b\x6f\xd3\xc4\xab\xd3\x29"
+  "\xfb\x0e\x0e\xa6\xbf\xf9\x2c\x80\xe1\xa1\x6f\xe9\x67\xa8\xa1\x26"
+  "\x56\xc6\x1c\x52\x97\x29\x3d\xd8\x90\xcf\xfb\xef\x57\xd7\x6e\x83"
+  "\x8a\xdb\xe4\x16\x5b\xaf\xb2\xde\x62\x03\x0f\x3c\xdb\x07\xc3\xfd"
+  "\xea\xe9\xd0\x70\x68\x30\x58\xdb\x5f\x93\xb1\xb4\x9c\x3b\x5e\x63"
+  "\x1f\xbf\xcd\x96\xa3\x76\x8e\x6b\x8c\xb9\x73\x7f\x90\x56\xef\x25"
+  "\x8b\xf3\x2c\xef\xc9\xcc\xa3\xa3\xf5\xd9\xb4\x0f\x6b\x72\xd1\x9d"
+  "\x95\xfe\xea\x05\xf6\x27\x50\x3a\x84\x6d\x52\xbe\xc7\x26\x56\x67"
+  "\xd9\xaa\x5f\x33\x6c\xf8\xc6\xca\x8a\x8b\x64\x52\xdf\x8d\x68\xac"
+  "\x98\xed\x10\xe1\x9d\x26\xad\xb8\x9e\x63\x0b\xa5\x57\xe6\x71\x6c"
+  "\x21\x23\xd6\x8e\xb4\x7d\xca\x21\x73\xdd\xf6\xe1\xdb\x57\xd1\x44"
+  "\x8e\x0b\x66\x0d\x28\x5b\x4e\xcd\xd7\x8d\x07\x81\x9f\x4d\x3f\x43"
+  "\xb7\xa9\xf8\x3b\xfb\x82\x0d\x17\xd0\x96\xca\xff\x24\x82\x35\x8c"
+  "\x84\xbb\x8a\xc6\xd7\x5f\xa0\x2c\xb6\x83\x0a\x3e\x57\x36\x1b\xaf"
+  "\x0b\xe7\x75\x59\x45\xe4\x7f\x65\xd1\xde\x33\x03\x71\xc3\x02\xab"
+  "\x39\xd6\x98\xb0\x0f\x76\x47\xb8\x7a\x8c\xf4\xa3\x91\x31\x20\xd4"
+  "\x77\xc5\x88\x76\xd6\x92\x99\xbf\xa3\xc9\x7b\x79\xbc\x37\xcc\x77"
+  "\x69\xd4\x1c\xf2\x66\xae\x11\x57\x69\xd0\xb3\x39\x8f\x5a\xef\x68"
+  "\x43\xb1\xfe\x0a\xf4\x78\xbd\x6b\x79\xce\x78\x73\x27\xdf\xdf\x19"
+  "\x58\xe3\xbc\xb9\x86\xf3\x38\x8d\xfd\xcb\x73\x24\x2d\xdf\x3c\xc2"
+  "\xeb\x1e\x7d\xcd\xf8\xa1\xa3\x3f\x4d\xd9\x30\x3c\x97\x31\x0e\x0d"
+  "\x6a\x1f\x39\x15\xb8\xb4\x1b\xf3\x19\xcf\xeb\xea\x1b\x9e\x6f\x76"
+  "\xf9\x4d\xff\xd7\x89\x2b\xe0\x67\xd3\xbf\x81\x6b\xea\xe6\x58\x49"
+  "\xee\x1f\x67\x1a\xf3\x9b\xfc\x46\xc3\xe6\xb1\xf7\xae\x5e\x4f\x99"
+  "\x0f\x7d\x93\xcf\xbc\xe5\x3d\x8c\x4e\x35\xef\xfe\x78\xf6\xc0\x19"
+  "\x55\x8e\xa4\xb7\xfc\xfe\x1a\xaf\x31\x4c\x98\x83\x55\x8c\xb0\x2e"
+  "\x35\xff\x1a\x77\x8c\x7f\xbc\x34\xaa\x9d\x2d\xfd\xf3\x28\xda\x60"
+  "\x5f\x09\x86\xaf\x6c\x93\x1f\x4f\xe3\x36\x78\x6d\xa5\xe6\xd7\x1f"
+  "\x4f\xbb\x82\x2d\x96\xc5\xf4\xd5\xf4\xf5\xa4\xaf\xeb\x2f\x8a\xbe"
+  "\xe5\x94\x3c\x65\x27\xd9\x3f\xac\xf2\x9b\xd9\x4f\xd5\xb1\x8a\xac"
+  "\x68\xff\x63\xce\x67\x5e\xf7\x4e\xe6\xbd\xb8\xb7\x6e\xf5\xf1\xbc"
+  "\xdd\x97\x9f\x32\x9f\xd7\xfa\xd2\x16\x7f\xcb\x31\x09\xf5\x90\x96"
+  "\xfe\xbb\x73\x21\x73\xf5\x06\x9a\xc8\xdf\x39\x44\xba\xfc\x36\x58"
+  "\xe0\x1b\xcf\xf4\x7c\x6b\x34\xd9\xbf\xb5\x93\x7d\xec\xdf\x9a\xeb"
+  "\x37\xfd\x4f\xf9\x1d\x52\xd9\x7e\xed\xae\x52\x8e\x8f\xf6\x4e\xaf"
+  "\x7f\x88\x1a\xab\xb7\x3e\xc7\x7b\x56\xd4\xfb\x26\x63\x2f\xdf\x4f"
+  "\x6f\x75\xc8\xf3\x40\xf6\x23\x5e\xc9\xf3\x75\x65\x60\xc0\xf7\xe6"
+  "\xad\xcf\x75\x5c\x3e\x3f\x5a\x4a\xbc\x57\x7d\x62\xdf\x18\xd1\x86"
+  "\xf6\x0e\xfb\xe9\xcd\x90\xbe\x1f\xd3\x26\xf9\x8a\xed\xdd\x7f\xe4"
+  "\x35\xd8\x5f\xbc\xdb\x51\x8e\xe7\x89\x82\x72\xca\x51\x36\x7c\x95"
+  "\x45\x03\xff\x0c\xf4\xff\xad\x07\x78\xaf\x2f\xa1\x4e\x84\x89\x23"
+  "\xeb\xd4\x54\xce\x95\x7e\x5c\x35\xaf\xb7\xe1\x17\xb6\x7d\x55\x00"
+  "\xbf\x29\xf8\xe5\x75\x93\x0d\xf9\x21\xfc\x8e\x86\xed\xd8\xc4\x7c"
+  "\x89\x35\xac\x1d\xeb\x04\x3e\x5b\xcc\x19\xec\xfe\x1f\xd3\xc6\xb7"
+  "\xe5\x11\x52\x7e\xa9\xfb\x8f\xb5\x04\x60\x9f\x61\xa5\xbc\x3a\x2c"
+  "\x7a\x1d\xd7\xf3\x3d\x9b\xfd\xc7\x9c\x7b\xd9\x1f\x64\x7f\xdc\xf7"
+  "\xcf\xf7\x1f\xc1\x1f\x24\xed\x27\x79\xf8\x83\xce\xd8\x7f\x6c\xe0"
+  "\xef\x27\x47\x7a\xdc\xfb\x8f\xf9\x69\xbf\xb4\xb1\xae\x4e\x27\xee"
+  "\x57\x77\x29\x78\x5d\x94\xb6\xc4\xa6\xfa\xbb\xcb\x81\x77\x8b\x48"
+  "\xdb\x55\xa8\xf7\xd7\x86\x77\x9b\xc3\x89\x79\x2d\x0d\x34\x19\x8b"
+  "\x3e\xa7\xbd\xde\xc6\xfd\x65\x7c\xbb\xd3\x30\xa3\x47\xdd\x7d\x64"
+  "\x98\xdc\xff\x40\x5a\x15\xc3\x23\x31\x39\xd3\x63\xd0\x53\xa7\x13"
+  "\x9f\x1b\x99\xba\x01\x43\xd9\x41\x28\x0f\x18\x46\xf9\x7e\xda\x8f"
+  "\xe5\x6f\x0e\x60\x4c\x51\x0e\x6b\x62\x8b\x71\xaf\xb2\xc7\xfd\x93"
+  "\x43\x1f\x95\xa8\xf3\x03\xae\x1b\x8c\xaa\xcb\xf1\x06\x12\xd5\x47"
+  "\x9b\x16\xd5\x66\x55\xe0\x34\xed\xff\xa3\x6a\xf7\x27\x07\x06\x93"
+  "\xa5\xaa\x71\xb0\xef\xea\xfd\x1c\x93\x80\xed\xa1\xe9\xbe\xcc\x20"
+  "\xf9\xea\x35\xcc\xf9\x55\x8e\x9c\x2a\xe1\x3d\x4d\xff\x63\x45\x6b"
+  "\xa8\xf3\x2a\xe7\xc3\xff\x21\xcf\xdf\x45\xaf\x8b\x7c\x15\xb7\xc9"
+  "\xef\xfb\x9e\xa3\x9f\xbe\xe1\x0b\xc8\x38\xd9\xfc\xfc\x02\xe7\xb3"
+  "\xef\x03\xcf\x0d\x1c\x37\xce\x58\x63\x6b\x28\xbb\x8f\xd3\x91\xe6"
+  "\x0b\x06\x64\x7c\xba\x01\xdf\xec\x4a\xfd\xfb\xf0\x3f\x7d\x40\xde"
+  "\x7d\x67\x7c\xc3\xdf\xf7\x32\xce\x90\xa5\x2c\xee\x83\x13\xeb\x3f"
+  "\x5f\xb8\xc7\xcb\x32\xe1\x58\xcb\x7b\x85\x3f\x9d\x04\xbe\x13\x5a"
+  "\x4d\x65\xd6\x55\xf6\x41\xde\x9d\x70\x86\xc5\xb9\x40\x5a\x65\x16"
+  "\xdb\x24\xd5\x55\x43\x2c\xb3\xea\x85\xb7\x3b\xbd\xca\xd1\xe3\xfe"
+  "\x69\xde\x47\xe5\xf4\x5f\xe0\xc3\x9f\xe6\x19\x7d\xdf\xa7\xf7\x1d"
+  "\x6d\xc9\xf5\xd3\x94\x3a\x15\x8f\x0f\x65\x06\xfd\xce\x33\x8f\x33"
+  "\xdb\x03\xec\x37\xaa\xd3\xa2\xbd\x7f\x6e\xb8\x3a\x3c\xda\xbf\x46"
+  "\x1b\x7d\xaa\x8d\x03\xd3\xff\x6b\x6d\x1c\x98\x7e\xa5\x36\xa0\x1b"
+  "\xae\x3b\x43\x07\x8e\x5d\xfd\xda\xf1\xc0\x4e\xc9\x2b\x9e\x2a\x9b"
+  "\xd2\x99\x3f\xbb\x33\x82\xf5\x5b\xd8\xb6\xcb\x21\xbf\xc5\x63\x22"
+  "\x97\xcf\x1f\xa6\xb0\x67\x89\xad\xa5\xbc\x97\xbc\x6b\xff\x44\x1d"
+  "\xf4\x4f\x72\xdf\xa8\xa5\x8c\xd7\x6c\xbb\x0a\xfb\x6a\xab\x4a\xfb"
+  "\x4c\x07\xec\x4c\xef\xbd\x1c\xfb\x30\x8a\xcf\x5a\x83\x7f\x22\x5f"
+  "\x21\xef\xaf\xb6\xf1\xbe\x76\x21\xf4\x83\x43\x83\x6e\x80\x8d\x1e"
+  "\x91\xf4\x80\xfd\xa2\xd6\x5b\x9b\x2d\x72\xbd\x15\x90\x77\xfe\x46"
+  "\xc2\xee\x4d\x11\xee\x92\xd1\xbc\xf7\x1d\xe9\xcb\x07\x8f\x50\x1e"
+  "\xc7\x21\xe4\x7d\x67\x61\xcb\xe8\x5a\x10\x4e\x16\x72\x3d\x05\xdb"
+  "\x9f\xe3\x11\xfa\x82\x7e\x8a\xc0\x8e\xae\xbf\x44\xa3\xeb\x61\x7b"
+  "\x42\x67\xdb\x58\xaf\x37\xe8\xf1\x08\xb7\x5f\x1a\x88\x47\xb8\x8f"
+  "\xf7\x7a\xda\xf1\x7c\x89\xcc\x91\x9a\xcd\x96\x3d\x97\x68\xfc\xde"
+  "\xb5\x94\xb5\x87\xf7\xf2\xfe\xaa\x6c\x1f\xb6\x2b\x64\x6c\xc2\xe7"
+  "\xb2\x78\x3f\x7f\xc0\xf6\x59\xc7\x31\x53\xfb\xf5\x96\x59\xee\x81"
+  "\x5c\x15\xbd\x7f\x26\xe7\xc1\xb0\xa7\x72\x6e\xd8\xf6\x7a\x1b\x68"
+  "\x17\xf0\xd3\x3f\x4d\xeb\x33\xfd\xf4\x50\xa2\xb1\x35\x7c\x9b\x76"
+  "\x46\xc5\x93\xfc\x68\xbc\xd2\xef\x80\x55\x31\x18\x4f\x44\xf6\xe4"
+  "\xd3\x94\x2e\xca\x56\xfe\x0a\xd7\x60\x4e\xfc\x99\x9f\xcf\xcf\xab"
+  "\x9e\x25\x7b\x64\xcf\xe2\x24\xe7\x9b\x94\xcc\xdf\x7e\xe6\xbf\xaa"
+  "\x2f\x44\xe7\x94\x12\xca\xe6\xf3\x07\xf6\x69\x70\x6c\x94\xe5\xdf"
+  "\x1d\x5f\x41\xd9\xd1\xb0\xe7\x2a\x67\xa3\xbb\x1c\xf7\xaf\x7c\xea"
+  "\xb9\x67\x4b\x97\x96\xad\x78\x72\x45\xc9\x8a\xb2\xf5\x32\x6c\xc0"
+  "\x44\xf9\xdf\x7d\x13\x8a\x16\xca\x43\xe7\x28\xfb\x62\xfc\xc0\x7e"
+  "\xdc\xcf\x57\x44\x78\xff\xe0\xaa\xe8\xf5\xf3\xa9\xfa\x39\x5a\x60"
+  "\xaf\x3c\x57\xfa\x79\x05\x6c\x06\x79\xde\xbc\x5d\xc5\x91\xe9\x54"
+  "\x7e\x0c\xaa\x9c\xe6\xd9\xc5\x31\x7a\xa6\x9f\xa2\xb7\xf3\xf9\x3c"
+  "\x04\x63\x05\xbd\x79\x86\x60\x87\x4c\xe7\x73\x96\x16\xde\xcb\x90"
+  "\xb6\xef\xcf\xff\x2a\xe7\xb0\x73\x32\xa6\xd2\xfe\x53\x78\x67\xbf"
+  "\x77\x4d\xe4\xef\x89\x3c\x67\xdf\xaf\x3d\x67\xff\x1f\x42\xe4\xef"
+  "\xd6\xce\x17\xef\x11\xe7\x8b\x77\x0b\x4f\x8a\x0b\x32\x96\x79\x86"
+  "\x7e\x1e\x09\xbb\xe9\x1b\xf8\x1b\x36\x10\x43\xe0\x60\x5a\x6e\x87"
+  "\xe8\xc3\x9f\x26\x3c\x23\x1b\xa3\xce\xd0\x38\x4f\xde\xd9\x28\x5d"
+  "\xc5\xbe\x54\x07\xe7\x70\xdb\xa2\x76\x64\x43\xc0\x59\x9c\x8c\xf2"
+  "\x11\x85\xcb\xc1\xa5\xbe\x2d\xa7\x49\x9d\x9b\x1e\x2c\xf4\xca\x3d"
+  "\xe3\x83\x5f\x72\x3d\x3e\x67\x63\x1b\x5a\xc6\x62\x35\xfd\xac\x8b"
+  "\xfd\xf0\xd8\x7e\xde\x9b\x4e\x36\x4f\x3a\xa5\xf4\xb8\x0f\x6e\xeb"
+  "\xf7\xb1\xb0\xa9\x39\x95\xe7\x35\x8e\x1d\x0c\x9d\xd3\xc3\x73\x24"
+  "\xe3\xc1\x7c\x0a\x98\x87\xf9\x0c\x4e\xdd\x2b\x3a\xd8\x0c\xfb\x71"
+  "\xda\xd5\xeb\xdc\x83\xcd\x72\xfe\x30\x39\xc5\x94\x6d\x54\x28\xcf"
+  "\x47\x95\xcf\xa1\x19\x72\xe9\x57\xfd\x79\xfb\x56\x79\x7e\xbe\xf6"
+  "\x6c\x23\xe4\xc6\xd5\xd0\x4b\x29\x9a\x27\xa3\x83\xed\x98\x96\x0a"
+  "\x79\xae\x6c\x41\xbd\x26\x3e\x77\x96\xf7\xf2\x64\x2c\xea\x3f\x51"
+  "\xc3\x45\x32\x77\xd0\x2f\x72\x78\xaf\x7d\x80\xb6\xbf\xd8\xc5\x67"
+  "\x2b\xa2\x76\x84\xdd\x5a\x61\xda\xca\x30\xb4\x4b\xe7\xa6\x19\xf5"
+  "\x30\x77\x0f\xe3\x7a\xa7\xe8\x17\xeb\x65\x3d\x2e\x2b\xbf\x63\x68"
+  "\x5b\x8c\x79\x6c\x2e\x97\x0f\xe3\x7d\x9f\x66\xcb\x13\x90\xb7\xc8"
+  "\xda\x48\x13\xf2\x16\x42\xdf\x05\x90\x96\x2f\xf7\x78\xb1\x2e\x97"
+  "\xf1\x4e\x6c\x8f\x92\xcf\xff\x17\xaf\xc4\x87\xfd\x58\xcb\xa0\x9b"
+  "\xa4\xdd\xf7\x8b\x96\x7d\x7f\x95\x31\xb2\x31\x86\x6f\x17\xea\x7c"
+  "\x73\x40\xe1\xf7\xf6\xd2\xee\xda\x51\xf9\xdd\xb6\x2a\x0a\x9a\x2c"
+  "\x74\xd4\xce\x7e\xf7\xbb\x9a\x8e\xda\x7b\xb1\x76\x78\x3b\xcb\x6f"
+  "\x1e\xbe\x55\xd9\x1c\xaa\x1e\x9f\xed\xc0\x1e\xed\x4a\xb6\xdb\xe6"
+  "\x22\x7f\xae\xe1\x5f\xc1\xdf\xfe\xe6\x33\x1e\x3f\xfd\xc2\xc1\x74"
+  "\x03\xdf\x1f\x92\xfb\xfc\x9b\x1f\xef\x44\x7f\x86\xb2\x0f\x1c\xd3"
+  "\x99\xef\x37\x58\xf1\x2c\xd6\x8a\x69\xd6\x70\x8e\xa9\x41\xde\x6b"
+  "\x94\xf7\xe5\xa7\xea\x31\x5b\xb2\xf5\x18\x2e\x13\xf9\x5d\xdd\xb7"
+  "\x7f\xbb\xff\xfe\x3f\xc7\xa9\x61\xdf\x81\x88\xee\x57\x27\xe3\xb7"
+  "\x5c\x50\xe7\xa3\xec\x57\xc7\xfb\x83\x7c\x3f\x90\xcf\x30\x51\xaf"
+  "\xb3\xdf\xcf\x51\xde\x8b\x79\x3b\x64\xc4\x6d\xe9\x71\xbf\x63\xee"
+  "\xf7\xd7\x41\xdf\xbb\x3d\x95\xa1\xa0\x6d\x57\x53\xd0\x53\x89\xb5"
+  "\xc9\x3b\x0e\xe8\xa6\xfc\x2b\xae\xe9\x38\x1e\xed\x1a\x32\x69\xe9"
+  "\x99\x36\x8e\x67\xc1\x71\xc1\x94\x9f\xfc\x3b\x9b\xf4\xfb\xe3\xc9"
+  "\xe7\xe8\x9d\x19\x03\x67\x89\x11\x7d\x1f\xec\x9d\x03\xca\x0e\x7b"
+  "\xe7\x80\xdc\x07\xab\xad\xf4\xbf\xb5\x21\x64\x6a\xda\xe0\x37\xa9"
+  "\x7b\x02\xef\xc0\x02\xfb\x4d\x9b\xe1\x8f\x82\x72\x1c\xaf\x21\x61"
+  "\xcc\x24\xe1\x19\xa7\xdf\xcf\x6d\x92\x7b\x18\x03\xeb\x9a\x26\x75"
+  "\x4e\xb6\x79\x6c\xa1\xc6\x73\x60\xfa\x12\x87\xf4\xad\x28\xbd\xc0"
+  "\xfb\x61\x43\xd5\x1a\x4b\x95\xd1\xfd\x22\x47\x9d\x89\x7d\x4f\xe7"
+  "\x77\x45\xb3\xa6\x89\xc6\xde\xfa\x0e\x93\xe6\xb7\x26\x91\x70\x36"
+  "\x8a\x20\xc7\x83\x83\x7d\x15\xf0\x61\x4e\x45\x1b\x02\xfa\x61\x18"
+  "\xea\x2c\x65\xda\x2b\x19\x6a\xfa\x58\xe2\xe4\x9e\x29\x9c\x6c\x57"
+  "\x06\xd8\xb7\xe3\x02\xa1\x5c\x1a\xca\x6d\x6f\xae\xe8\x02\x9f\x65"
+  "\xb4\x73\x9c\xb5\x0e\xbd\xed\x40\xda\xb8\xe3\xdf\x4a\xa1\x42\xb4"
+  "\x09\xfe\x71\x17\x5e\xbd\x6c\x37\x35\x5e\xc9\xc6\x50\x73\x5e\x0e"
+  "\x0d\xb6\x4e\xe1\x75\xe8\x64\xb4\x3f\x4f\x30\xfe\xef\x6e\x0f\x9b"
+  "\x42\xd4\x67\x1a\x26\xfe\xc1\x55\x4e\x61\xf7\x30\x11\xd9\x80\xf1"
+  "\xea\xb6\x43\x1f\x1f\xa7\xd6\x70\xb3\xf4\xfd\x80\xcc\x5a\xab\x82"
+  "\xe2\x82\x2f\x7c\x48\xfa\xc2\xaa\x3b\xe3\xef\xbe\xe0\x0b\x7f\x40"
+  "\xad\xa5\x01\x62\xbd\x70\x8a\xde\x95\xb1\x4e\x27\x97\xba\x88\x63"
+  "\x7a\x22\x3f\x5b\xcd\x7f\xef\x6e\xd3\x7f\x17\x8b\xee\xac\x98\x33"
+  "\xa3\xfb\xd6\xac\x7c\xaa\x6c\xc5\x73\x2b\x27\xe5\x2e\x5b\xbb\xac"
+  "\xc4\xf1\xa0\x72\xa5\x8b\x99\x97\x2c\x03\xb1\x8f\x7f\x29\xe7\x0a"
+  "\xb6\x41\x38\x06\xb2\x8c\x7f\xec\x9e\x4a\xfd\xb1\x8f\xd9\x16\xf9"
+  "\x3f\x10\xff\xd8\xb0\x31\x38\xf6\xf1\xc0\x1e\xf6\xaf\xec\xfd\x32"
+  "\xa0\x7d\xd8\xc3\xef\x7c\x4f\x52\x73\xbf\x5b\xc7\x72\xb4\x4f\xfa"
+  "\x9d\xfd\xd2\x13\x1d\xf7\x87\x7d\xec\x78\xdf\x03\xe9\x07\x8c\x3b"
+  "\xa9\xe0\x45\xcc\x15\xbf\x3c\x3c\x70\x47\xe6\x97\xd0\xff\xef\x9a"
+  "\x95\xfc\xca\xb2\x27\x8c\xb3\x5e\xfd\x1b\x53\xf2\x6c\x5a\x73\x5f"
+  "\x0c\xaa\xfd\x95\x5f\xfe\xfb\x3e\x6d\x98\x45\xed\xed\xff\x8a\x8c"
+  "\xfb\x57\x4a\x36\x3f\xd4\x65\xf3\x57\xf6\x2b\x9d\xc7\x0f\xc8\xc6"
+  "\xaf\x16\x0e\xc8\xf5\xa7\x46\xdd\x85\x5f\x75\x96\xaf\xdb\xb9\xd7"
+  "\x9e\xa1\xf7\x56\xf0\x9e\x0b\x9e\x6f\xc0\xb3\xbc\xf7\xa9\x7c\xd1"
+  "\xdf\x9b\xa4\x3f\xa3\x8d\xf7\xae\xd5\x9f\x33\xce\xd0\xa1\x88\xfe"
+  "\x3c\x16\xcf\x9f\xeb\xcf\x90\xd9\x43\x2d\xfa\xf3\x68\x3c\xbf\xa7"
+  "\x3f\x43\xc7\x1f\xda\xab\x3f\x8f\xc1\xf3\x0b\xfa\xf3\x37\xf1\xfc"
+  "\xac\xfe\x0c\x19\x3c\xf4\xb0\x7e\x2e\x8a\x79\xf5\xd0\x3d\x57\x6f"
+  "\x77\x1f\x4a\x51\x67\x6f\x87\x72\xa1\xeb\xf5\xbb\x6a\xfd\x69\x85"
+  "\x18\x9b\x26\x83\xbe\x48\xe7\xbd\x41\xac\x61\x0f\x95\xfb\xe9\xcd"
+  "\xfc\x81\xf4\x5f\x05\xf5\xf2\x1e\xe8\xb9\x89\x51\xe9\x9d\x7a\xfa"
+  "\x01\xd8\xf7\x15\x51\xe9\x27\xf5\x74\x2f\xca\x1f\x8a\x4a\x6f\xd3"
+  "\xd3\xdb\xfd\xb4\x67\x5b\x54\x7a\xb3\x9e\x1e\x30\xfc\x10\xf4\xf4"
+  "\xc3\x2a\xfd\x3d\xf6\x19\x98\x1e\x95\x7e\x50\x4f\x87\xfe\xff\xd5"
+  "\xf8\xa8\x74\xa9\x57\xaa\xe5\xbd\x2d\xab\x38\x5a\xc1\xb2\xf5\xde"
+  "\x6c\x3f\xbd\x11\x8d\xf3\x4e\xbd\xee\x62\x3f\xd5\x2d\x8c\x4a\xd7"
+  "\xef\x57\xbf\x57\xe6\xa7\x8e\xe8\xf4\x41\x6d\xdf\xa4\x3a\x2a\x1c"
+  "\x6c\x6f\x92\xbf\xc9\x23\xfd\x1f\xa5\xcd\xf8\xeb\x77\xf9\x4e\x97"
+  "\x75\xaf\x38\xe5\xa8\x12\xe2\x14\xfd\xba\x4e\xf9\xfd\x65\x9c\x60"
+  "\x3f\x2c\xbe\x1b\xd7\x41\xbf\xde\x24\xef\x4b\x71\x2c\x43\xbe\x2f"
+  "\xb7\x81\xef\xcb\xfd\x5a\xc6\x79\x9e\x52\xee\x52\x71\x0e\x95\x5f"
+  "\x69\x97\x5c\xa3\xeb\xe7\x97\x28\x33\x89\xf7\x2c\x19\x0e\xef\xe3"
+  "\xf9\xca\x7a\xa5\xaf\x23\xaf\x91\x38\x8d\xd7\xaa\xf2\x0e\x55\xd4"
+  "\x5a\x49\xe9\xfd\x5f\xbf\xab\xf1\x1d\x77\xb7\x5a\xcf\x57\xab\xf8"
+  "\x99\x5d\xec\x73\x13\x5d\xd6\x4f\xbf\x96\xeb\xdc\x64\x7b\xda\x1b"
+  "\x3d\xee\x5f\x7b\x06\xee\xf5\xbc\xd7\xa9\xa7\xd7\x21\xfd\x40\x54"
+  "\xfa\x89\xc1\x75\x3b\xf4\x9d\x6d\x44\x61\xdf\x25\x11\x0c\x5f\x12"
+  "\xa1\x1d\xff\x01\xbc\x97\xcb\x3b\x2a\xd7\x47\x3c\x23\x4a\xf5\x78"
+  "\x11\x9f\x85\xd7\x8a\x00\x74\x36\xc7\xd7\x1f\x31\x3f\x18\xa0\xf9"
+  "\xa5\x3d\x62\xfb\x93\xec\x3f\x77\x51\xc6\x4e\x72\x76\x71\x2c\x5f"
+  "\xf6\xc9\x0a\xf2\xb9\x4f\x4a\x2b\xe6\xb8\x7d\xcb\x39\xff\x13\x9a"
+  "\x57\x0c\xdb\xbb\x38\x42\xfb\x00\x7b\xef\x93\x86\x3f\xe4\x6f\xe6"
+  "\xf6\xfb\x28\x02\x07\x6e\xcf\x29\xbf\x8f\xf1\x1b\x19\x9b\x83\xbf"
+  "\xfb\x25\x6a\x5e\xf7\x8b\xdf\xb3\xfd\x5a\x99\x6d\xdd\x44\xe0\xab"
+  "\xdf\x6c\xc1\xb3\x43\xfd\x21\x0f\xe9\x83\xf5\x49\xc9\xf2\x6f\xbc"
+  "\xfa\x59\x8c\x5f\xe9\x8b\xdf\x78\xc5\x8f\xf9\x8e\xce\x6f\x9a\x51"
+  "\xb7\x3d\x90\x56\x99\xd0\xaf\xaa\x72\x2f\x99\xfa\x6a\x61\x9b\x9c"
+  "\x3b\x6c\x52\xfa\xe9\x70\x93\x66\xb2\x6c\xe2\xfd\x42\x19\x23\xbf"
+  "\x36\xd3\x71\x70\x65\xc8\xd4\xb2\xa1\x83\x36\x7e\x93\xec\x8b\x43"
+  "\xec\xff\x7d\xf8\xd6\xd4\x32\x8e\xd7\x58\xe9\x87\xdd\x69\xfa\x15"
+  "\xf2\x7f\xb7\xf2\xb0\x29\x2c\xed\x95\xc3\x4d\x72\x8f\xc9\x93\xc1"
+  "\xf1\x8d\xad\xbe\xf6\x08\xdb\xcc\x29\xb0\x99\x3b\xa0\xff\x2d\x91"
+  "\x75\xc5\xe9\xe1\xd5\xc5\x23\xf6\xae\xa2\x94\xc8\xea\xac\xd1\xaf"
+  "\x5e\xa2\x69\xc6\xfc\x83\xb5\x69\xb6\xe8\xb1\x0f\xaf\xc6\x9c\xc2"
+  "\x6b\xd7\xd4\x24\x9b\x3c\x4b\xe3\x67\xcd\xb4\xaf\x6e\xdf\xda\x2b"
+  "\x7f\xe7\x23\x82\x35\x2b\xc7\xe8\x66\x5c\x12\xf5\x75\xdb\x6e\xac"
+  "\x83\xf5\x3b\xa5\x55\x9f\xd3\x18\xd8\xb9\xa6\xd4\x8b\xc2\x7b\xa6"
+  "\x84\x4c\xfc\x8d\x84\xaa\x65\x72\x7f\x68\x48\x4b\x71\x98\x7c\xe5"
+  "\x7f\xa6\xaa\x55\x3c\x46\xef\x0f\x61\x3b\x8d\xfd\x21\x51\xde\x76"
+  "\x86\xde\xbf\xd6\x1a\xc2\x9c\x11\x82\xed\xfc\x34\xaf\xf5\xde\xbf"
+  "\x99\xd7\x9b\x7e\x7a\xbf\x84\x7d\xc2\xbd\xab\xee\xe5\xb4\x39\xce"
+  "\xcf\xa5\xbf\x6e\xbb\xba\x77\xfa\xbe\x83\xdf\x9d\x7c\xc7\x35\x7d"
+  "\x9c\xf9\xed\xde\xd0\x10\xb5\x07\xf1\xbe\xfe\xcd\x94\xca\x36\xb5"
+  "\xe6\x7a\xdf\x31\x18\xef\x6a\x1e\xab\x4b\x70\x9c\xe5\xfa\x30\xcd"
+  "\x0f\x0a\xbf\x3c\xa7\xe4\xbb\xfd\xe5\x33\xbd\xe2\x92\x87\xd4\x7d"
+  "\xb4\xf7\x3f\xd7\x6a\xac\x2e\x15\x03\xf0\xfd\x4f\x48\xf9\x18\x61"
+  "\x8e\xb4\x7a\xd4\x1e\xad\xb5\x51\xed\x59\x5a\x9b\x36\x8f\x65\x1f"
+  "\xe4\xf7\x3b\xba\xd3\xac\xd0\x91\xef\x1f\xee\x4e\x9f\x90\x3f\xf8"
+  "\x7c\x94\xd2\xe4\xb8\x9e\x46\xf3\x5e\x39\xfb\x13\x37\x28\x3f\x62"
+  "\xb4\xf1\x5b\xf6\x2b\xe6\xbc\x1b\x4e\x95\x52\x32\xef\x2f\x22\xed"
+  "\x8e\x29\xf5\xc4\x7b\x2a\x23\x85\xcd\x5a\x28\x7d\xb7\x3c\xd6\x52"
+  "\x5f\x97\xf0\xb2\xcf\xa0\x3a\xd3\xf8\x6d\x50\xa4\x59\x0b\xf5\xf2"
+  "\x2f\xb4\x76\xa1\x0f\x36\x6b\xb6\x2f\x74\x56\xb7\x09\x7f\x0b\xde"
+  "\xb7\x66\x0b\x8f\x35\x47\xdd\x15\xff\xed\xc7\x86\x5e\x55\x3c\xfa"
+  "\xdb\x3f\x2a\xba\xa5\x34\x29\xba\xfd\x36\xa8\xcf\x57\x37\xf0\x33"
+  "\xe6\xee\x6c\x75\x06\xff\x5b\xaf\x61\x23\xfb\xf5\x32\x5c\x07\xcf"
+  "\x7a\x2c\x9c\xdf\xfa\xd1\xf7\x72\x3d\x5f\x7e\xb7\x00\xfd\x03\x0f"
+  "\xff\x36\x93\xfb\x35\x98\x6e\x95\xb4\xa8\xa0\x64\xe0\x9c\xa7\xa9"
+  "\xb8\xc8\x41\x5f\x70\xa6\x57\x7d\xb7\xef\x48\xa5\xbc\x33\x8b\x76"
+  "\x30\x3e\x26\xd6\x9b\x7c\xc7\x97\xe1\x0d\xe0\xff\xcf\x4b\x0d\x5c"
+  "\xb8\x3d\xce\x43\x5f\xd9\x0f\x90\x69\x95\xc3\x65\x78\x5c\x4f\x97"
+  "\xf2\xde\xc5\x45\xd0\x8c\xfd\x80\x8e\x6c\x63\x9a\x28\x9a\x1d\x91"
+  "\xdf\x06\xab\xee\x1f\x87\x23\x4b\x62\xe9\xa1\xde\x35\x1b\x74\xc3"
+  "\x2a\xf6\x07\x39\xb2\x4d\xa7\x5f\x97\x6a\xff\xc8\x9d\xfa\x5a\x1d"
+  "\x79\xff\xfc\x45\x54\xdd\xeb\xfa\xcb\xaa\x6f\x44\x9a\xf8\x6c\x95"
+  "\xf7\xda\x15\xbf\x1e\xc9\x1c\xa8\x77\x24\xb3\xe0\x0b\xb6\x91\x47"
+  "\x64\xf3\x37\xfd\x98\xe6\x3d\xee\x23\xd9\x03\xf4\x56\x70\x12\xb4"
+  "\x71\xbd\xd1\x86\x9f\xfe\x39\x60\xe0\x89\x67\x7d\x0e\x3e\x52\x36"
+  "\x30\x26\xff\xbc\xd3\xa8\xc7\xfe\xfb\x78\xcf\xe1\xfb\x82\x09\xf5"
+  "\x20\x9f\xe9\x00\xbb\xd6\xf0\x4c\xaf\xe4\x47\x3a\xd2\xc5\xbe\xae"
+  "\xa0\x6b\x9e\xe2\xa1\x23\x6d\x6a\x2e\x3c\x22\x63\xb7\xf0\x79\xc9"
+  "\xd1\x10\xf3\xc8\x91\x0e\xc0\xd5\xf7\xcb\x8f\x84\x74\x1c\xb0\xfe"
+  "\x7b\x3f\x10\xbf\xae\xbb\x77\x69\x91\xbc\x18\x3b\x69\x4d\x69\x7c"
+  "\x9c\x4a\xcb\xc0\x1d\xc8\x0f\xa6\x46\xdd\x21\xd5\xe3\x91\x7f\xe0"
+  "\xc2\x3a\xf5\xd0\x0e\xb5\x6e\x3d\xbc\x03\x63\xe6\xbc\x48\x63\xf9"
+  "\xdb\x18\x55\xa5\xe2\x4c\x6b\x29\xd6\xd2\xb6\xcc\xe9\xc2\x93\x99"
+  "\x53\x75\x91\x86\xb3\x2f\x05\xeb\x1b\xf6\xd5\x14\x69\x48\xaf\xf9"
+  "\xdf\xec\x7d\x0f\x5c\x54\x55\xda\xff\x99\x01\x0d\x0d\x65\x40\xa4"
+  "\xa9\xa8\x06\x05\x9b\x5a\x2b\x2a\x7a\x17\x5d\xdb\xa5\xc2\xd6\xfa"
+  "\x69\x50\x61\x4b\x85\x8a\x26\x2d\xba\xa8\x13\x22\x22\xf2\x4f\x34"
+  "\xd6\x7a\x15\xd1\xc0\xd0\x10\x69\x5f\x6b\xad\xf5\x0f\xed\xda\xef"
+  "\xa5\x5d\xd3\x31\x71\x17\x15\x18\x2c\x34\x74\x51\x47\x42\x43\x16"
+  "\x75\xd4\x51\x06\x9c\xb9\xf7\xf7\x3c\xe7\xdc\x3b\x77\xee\x30\x03"
+  "\x8c\x69\xb6\xbf\xf7\xe5\xf3\x99\xcf\xe5\xdc\x7b\xee\xb9\xe7\x9e"
+  "\xe7\x39\xdf\xf3\x3c\xcf\x7d\xce\xf3\x04\x47\x49\xfb\xd4\x76\x17"
+  "\x83\x6e\xbb\x79\x25\xe8\xb2\xb9\xe7\xc8\x5d\xcc\x37\xe2\xcb\x2f"
+  "\xd1\xa6\xc3\xe7\xc6\xaf\xe7\x8a\x82\xa3\x71\x0f\x64\x3d\x68\x84"
+  "\x7c\x6e\xf2\x7a\x6e\x75\x70\x34\xb4\x1b\x97\x3b\x87\x04\xe0\xfa"
+  "\x86\xb6\x21\xc6\x33\xbb\xd3\xa0\xdd\x38\x8c\x4f\xc6\xf1\xf1\x0a"
+  "\x78\x7e\x29\xa7\x0a\xa9\x59\xc9\x11\xea\xfb\x0d\x7c\xa6\x6c\x21"
+  "\xbb\x86\xc0\xf3\x4b\x31\x47\x1f\xda\x79\x0c\x16\x0b\xc6\x50\x28"
+  "\x85\x6b\x43\xe1\xda\x18\x38\x72\x18\xab\x0c\x63\x49\x43\xfb\x6a"
+  "\x6c\x1f\x9e\x55\xca\xfa\x4e\x63\x88\x94\x42\xbd\x39\x58\x47\x8c"
+  "\x81\xc6\xe5\xc6\x7b\xe1\x75\xdc\x53\x6b\x83\xfb\x0c\x20\xe9\xb1"
+  "\x7b\x9a\xec\xf7\x08\xf2\x33\xcc\xe5\xdd\x73\xf8\x35\x61\x3a\xa8"
+  "\x5b\x85\xbe\xa6\x4c\x96\xdd\x9d\x2c\xcc\x75\x90\x8f\x77\xcf\x12"
+  "\xfe\xf7\xb5\xd7\xcd\x8d\x27\x39\x5d\x44\x4d\xbf\x97\x2e\xf4\x02"
+  "\xec\xdd\x5d\x02\xe3\x80\xf6\x85\x26\xaa\x8f\x2b\xbf\xb4\xef\xcb"
+  "\x29\xa7\x7b\x77\x76\xd9\xe3\xbf\x01\x6d\xaa\x57\xb1\x98\x79\x35"
+  "\x1c\xfe\x9f\x4e\xf7\xcc\x0d\x46\x3d\x03\x6d\x07\xd3\x16\x55\xd8"
+  "\xf7\x38\x30\x1d\x7c\xb7\xc6\x21\x56\x14\xbd\x17\x75\x71\xbc\x37"
+  "\xc6\xca\x5f\x59\x25\xd4\xc5\x7b\x63\x16\x4d\xe3\xf1\x5e\xb8\x27"
+  "\xce\x7e\x8f\x6c\x8f\xcc\x6e\xc6\xeb\xf0\x0e\xf8\xbf\x09\xfa\x2c"
+  "\xf8\x20\x69\xd8\xf7\xe3\xdd\x2b\xc4\x6f\xb6\x46\xf2\x65\x33\xd2"
+  "\xcd\x75\x2c\xe4\xdd\x3b\xe4\x71\x7b\xf4\xcb\x30\xa6\x10\x9c\xaf"
+  "\x15\xe3\xeb\xc0\xff\xf0\xbc\x2f\x99\x1f\x9c\x43\xdc\xac\x42\x87"
+  "\x18\x7c\xb9\x26\xfe\x3b\xa4\x07\xcc\x5f\x2f\x90\xf4\x42\xf9\xd5"
+  "\x21\x35\x6c\x9f\x91\x7e\x01\xf6\xb3\x85\xe8\xa3\xa1\xec\xc7\xf6"
+  "\xf7\xeb\x9f\x10\xe6\x69\x43\x8c\xcd\xea\x67\x84\x67\xe2\x9e\x19"
+  "\x87\xf2\x68\x98\xb7\x2a\xa8\x97\xc4\x62\xd4\xe9\x43\x9d\xea\xe3"
+  "\xf5\x3c\xa7\x72\x94\x53\x59\x63\x06\xfe\x74\xf7\x6d\x7a\xe5\x5d"
+  "\xd4\x2e\x67\x1e\xba\x84\xe8\x72\xcf\x12\x2f\xe0\xd7\xd3\xd8\xb7"
+  "\xfa\xb6\x0e\x7c\x27\x3f\x3e\x3f\x9c\x18\xda\xac\x4c\x86\x83\xb5"
+  "\xb3\x25\x14\xea\x9c\x25\x41\xe8\x37\x8d\x79\x0d\xa0\x7e\x3b\x8b"
+  "\xc1\xfc\xd5\x90\x84\x05\x83\x09\xf7\xdb\xf8\xdb\x79\x65\x8c\x05"
+  "\xbf\x8d\x6d\xed\x36\x0e\xc0\xef\x44\x39\xeb\x48\x30\xc6\xb7\x81"
+  "\xf9\xd9\x8a\x39\xaf\x30\x07\xf9\x7f\x75\xb7\x0d\x30\x58\x8f\x11"
+  "\xdd\x6c\xa2\x6c\x27\x5f\x11\xef\x2c\xe2\xbd\xea\x0c\x51\x01\x5d"
+  "\xad\x7b\xad\x91\x44\xdc\x9f\x5f\x16\xc0\xf6\x16\x97\x01\x8e\xcd"
+  "\x57\xf3\x96\xce\xfc\x3d\x20\xff\x7f\xe8\x23\xea\xb2\x2b\x58\xee"
+  "\x02\xef\x33\x64\xcf\x7e\xa5\x10\x8b\x80\x8d\xed\x9e\x75\x6c\x9f"
+  "\x52\xe0\x1d\x70\x8f\x83\xfc\xfb\x55\x30\x1b\xc3\x10\x01\xd3\xbf"
+  "\x0a\xde\x3b\x93\x60\xce\x1a\xfc\xc6\x1f\x08\x75\x77\xda\xbf\xf1"
+  "\x53\xfb\xd0\x57\xb0\xa6\x85\x74\x30\x19\x38\xa4\x63\x9a\xcd\x47"
+  "\xc0\x01\x3c\x7f\x7b\x38\xde\x0b\xf7\xf9\x99\xa9\x2d\x67\x8f\x45"
+  "\xe2\xb5\x3d\x7a\xc4\x56\x78\x27\x5f\xf8\x3f\x02\xdf\x0b\xc7\x04"
+  "\xea\x79\x43\x39\x72\xef\x26\x37\xb1\x4a\x55\xb7\x1b\xad\xd4\xd6"
+  "\x90\xdd\x04\xfc\x74\x0e\x68\x30\x0c\xe3\x11\x19\xe0\x39\x75\xe5"
+  "\xdd\xa4\x4e\x7d\x99\xd4\xc3\xff\xe8\xcb\xab\x9f\xfd\x1d\x69\xd5"
+  "\xb8\xc6\x75\x58\x1b\x12\xa1\xcf\x3a\x6c\x0b\xb0\xb2\x0d\xfd\x9f"
+  "\x0c\xa0\x11\xd5\x9b\x30\xd7\x16\xa1\x6d\xd4\x71\x6d\xa4\x2e\x03"
+  "\xf5\x99\xf7\x8d\xf5\xe5\xc7\x48\xbd\xfa\x1b\xfa\x1c\x94\xbd\xf4"
+  "\xa9\x97\x7b\x6b\x1b\x78\xee\xf6\x22\xa1\xed\x0e\x68\x3b\xd0\x7d"
+  "\xdb\xd9\xe1\x1e\xb6\xed\x41\xbf\xb3\x35\x9e\xb4\x0d\x72\x65\xab"
+  "\x41\xcd\xf6\x45\xe5\xdc\x49\x86\xd8\xae\x62\x2c\xca\xfb\x78\xe6"
+  "\x4f\xba\xf7\x22\xdd\x3b\x95\x4f\xf7\x89\x19\xe9\x1e\xaa\xf3\x84"
+  "\xfa\x04\xb2\x7d\x53\xa7\x09\xfa\x13\x74\xe6\xef\x6d\x96\x74\x12"
+  "\xfb\x77\x1e\x90\x09\xab\x99\x8f\x66\xd1\xdd\x46\xc6\x57\x7b\x3f"
+  "\xc7\xb6\x5c\xf7\x23\xd8\xcc\xfc\x4f\xab\xc7\x88\x76\x8e\xcb\xfe"
+  "\xc1\x66\xa1\x2d\x8d\xb3\xfd\x4c\x4c\x72\x99\x94\x91\x26\xe6\xcb"
+  "\x4c\x13\xb6\x6f\xbe\x94\xf4\x46\xd2\xac\xf4\xa4\x99\x9a\xb8\x05"
+  "\xa9\x73\x1f\x9a\xf7\xe6\x9b\x9a\x49\x49\xf3\xe7\x4f\xff\x6d\xd2"
+  "\x60\x12\x97\x3a\x7d\xee\xfc\x59\x68\xe3\xd2\x68\xa2\x1f\x9f\x96"
+  "\x3c\x2f\xed\xa1\x5f\x46\x87\x3b\xd9\xb8\x70\xaf\x5f\x33\xca\xba"
+  "\xb9\xd9\x30\x3f\x6d\xc4\x1f\x63\xcb\xf8\x2d\xe2\xf5\x8b\x41\xcf"
+  "\x02\xfe\x6b\xc7\xf5\x00\xe6\xed\x29\x94\xc1\x31\xae\x1d\xe0\x77"
+  "\xed\x07\x6b\xf9\x86\x33\xe4\xc8\x67\x20\xbf\x35\x6d\x64\x31\xda"
+  "\x9a\x41\xf7\x35\xb1\x9c\x6e\x47\xd0\x97\xb5\xfa\x3f\xe1\x9c\xc9"
+  "\x3f\xa4\x63\xd5\x09\xe2\x0d\xeb\x0c\xc8\xff\xfb\x26\xf2\xca\xdb"
+  "\xf8\x15\x41\x7c\x35\xff\x9d\x9a\x08\x71\xa7\x95\x06\xa3\x05\xbf"
+  "\x87\x83\x5e\x92\xcb\x23\x9e\xb2\xb9\xb5\x6f\x12\x1b\x17\xbf\x3c"
+  "\xe6\x97\x7b\x64\x0e\xea\x0a\x4b\x69\xce\xbd\x7d\x30\xff\xab\x76"
+  "\x4a\x38\x5d\x9f\x21\xc8\x68\x4d\x30\xee\x0b\x5b\xa0\xcc\x62\x5f"
+  "\xec\x5b\x2e\xf7\x75\xf8\x07\xac\x7f\x5f\x97\xb1\x1f\xde\xf3\xf5"
+  "\x4e\xf6\xc3\xff\x1d\x7f\x47\x62\xd9\xcf\xf9\xfc\x0f\xfd\x89\xcf"
+  "\xbf\xde\xfb\x0d\xe1\xbd\xff\xfa\xf3\x7c\xfa\xde\xb7\xf0\xfd\x7f"
+  "\xc8\xfd\x86\xc8\xde\x7e\xc8\x6f\xc0\x5b\xcd\xff\x79\x82\xf8\x00"
+  "\x7f\x16\xaf\x9c\x01\x3c\x7d\x9c\xa8\xb3\xac\x7c\x6b\xee\x14\x12"
+  "\x9c\x73\x96\x60\xce\xb3\xb6\xb4\x0c\xbe\x35\xe7\x2a\xca\x7e\x86"
+  "\x41\xc0\xbf\x55\x85\x2d\xc4\x77\x65\x0b\x51\xd5\xa7\x61\xee\x53"
+  "\x8c\x3f\x05\xad\x81\xa4\x6b\x80\x72\x6d\xba\x85\x1c\x34\x5d\x44"
+  "\xff\x20\x7d\x7d\x22\xe0\x4e\x33\xe6\x8d\xe5\xab\x7d\x13\x49\x60"
+  "\x59\x10\xbf\x93\xcf\x4f\xf1\xe6\x95\xbf\x33\xc3\xb9\xc6\xed\x5c"
+  "\xd4\x80\xed\x99\x35\x03\x30\x3f\x5c\x0b\xa9\x19\x22\xf0\xe6\x22"
+  "\xb6\x27\xa7\x9e\xda\x2b\x60\x9e\x34\x32\xfb\x75\xfd\x15\xb6\x9e"
+  "\xd7\xef\x13\xec\x3a\xf8\x3f\x95\xc9\xe0\x3d\xaa\x30\x47\x24\xb6"
+  "\xb9\x8d\xab\xa2\x39\x22\xb7\x67\x46\x0d\xc8\x9a\x4e\x94\xf5\xc6"
+  "\x76\xb2\x17\x70\x10\xf3\x0d\xc2\xbc\xdb\x02\xf3\x0c\x73\xca\x15"
+  "\x41\xff\x56\x94\x07\xf1\xcb\xa1\x4f\x9b\x3b\xf3\x6b\xb2\x60\xcd"
+  "\xd2\x09\xdf\x37\x30\xce\xcd\x96\x95\x50\x27\x66\x01\xb9\x6f\x25"
+  "\xd4\x2b\x84\x7a\x28\x8f\xb2\xfe\xd5\x3e\x05\x63\xb0\x03\x9e\xd9"
+  "\xa0\x99\x8a\xe5\xfd\xd4\x36\x84\xcf\x86\xf7\xd0\xb4\x90\xfd\xb5"
+  "\xb0\xb6\x79\xe3\x33\xc4\xe7\x42\xfb\x80\x7f\x7b\xb5\xc2\xf7\xd5"
+  "\x22\xd6\xce\x7e\x1f\x36\x5f\x83\x67\xae\x92\x72\x78\xce\x5c\x99"
+  "\x09\x6b\x7a\x37\x8d\xcb\x58\x8c\x76\x0d\x94\x31\xa8\x5c\x61\x23"
+  "\x7e\x4c\x0f\x07\xd9\x22\x19\x70\x00\xe4\x09\xea\x4b\x0c\xb2\x04"
+  "\xf4\xa5\x18\xf3\x68\xe2\x75\xd0\x8f\x76\xc0\xba\x5c\x89\x72\xc0"
+  "\xd4\x2b\xcf\x13\xb4\x65\x83\x3c\xe0\x3d\x3f\x81\xb7\xb0\x7c\x1f"
+  "\xfb\x93\x45\x59\x00\x31\x08\xd7\xff\x95\xe9\xc4\xfb\x1a\xd0\x10"
+  "\x78\xa0\x06\x64\x0b\xff\x76\xb2\x7f\x93\x30\xf6\x35\x74\xcd\x4f"
+  "\xa7\x71\x84\xbd\x18\x46\xef\xff\x0c\xde\xcf\x17\x9e\x51\x63\x24"
+  "\x47\x68\x8e\x6f\x86\x31\xfb\xf5\xe2\x3a\x8e\xba\xa5\x11\xda\xe0"
+  "\x01\xcb\x84\x6b\xf0\xfe\xfa\x62\xf1\x99\x70\x4d\x27\x8c\x59\x2d"
+  "\x8c\x19\xb4\x79\x80\xee\x27\x07\x99\xab\x43\x18\x9b\x2c\x94\x2b"
+  "\xd8\xbd\x07\xd4\x62\xbb\xa8\xff\x72\x20\x57\xe0\x78\xe1\x38\x41"
+  "\x3b\x59\x02\x8e\x35\x32\xf9\xa5\xf6\x01\xe1\xbb\x76\x11\xd0\x7a"
+  "\x99\x34\xfe\x07\x12\x1c\xc7\x1f\xee\x5f\xc6\x9e\x73\xf0\xb0\x03"
+  "\xed\x40\x07\x39\xb8\x05\xed\x91\xd0\xc7\x9d\xcc\x96\x72\xa0\x04"
+  "\xe3\x77\x61\xbc\x60\x18\xe3\x9d\x2b\x30\x36\x2d\x60\xf3\xd2\x13"
+  "\x44\xc8\xdf\x7a\xb0\x84\xc9\xa7\x07\x23\x58\x8e\xc3\x83\xf7\x60"
+  "\xb9\x15\xfa\xc5\xf2\x1b\x1e\x1c\xc0\xf2\x1b\x1e\xb0\x39\xe6\x6c"
+  "\x95\xf2\xb5\x1e\x30\x4b\xfe\xfc\x07\x34\x4c\x4f\x3d\xa0\x41\x5b"
+  "\x13\xad\x7f\x2d\x19\xfb\xd6\x8c\xf3\x52\x7c\x57\xcc\xdd\x0a\xe7"
+  "\x51\xf6\x6f\x46\xba\x89\xe7\x31\xae\x2d\xd0\xc9\x17\x9e\xb9\x52"
+  "\xe8\x53\x32\x94\x7d\xe0\xd9\xd4\x8f\x06\xf3\xb8\xae\xc2\x7b\x72"
+  "\xa4\x7b\x70\xde\x00\x0f\xfb\xc1\x3d\x6f\xc3\x91\x17\xeb\xb2\xfc"
+  "\xae\x07\x7d\xdf\xeb\x46\x5b\xd3\xc1\x50\x31\xbf\x2b\xe6\x76\x45"
+  "\xcc\x58\x39\x55\x36\xf6\x38\x36\x5b\x80\x56\x94\xef\xf6\x5a\xab"
+  "\x60\xbc\x0f\x82\xfc\xff\xb9\x10\x4b\xee\xa0\xaf\xd0\x3f\x3d\xcb"
+  "\x7b\x50\x1d\x5d\xbe\x46\x8c\x65\x70\xd0\x6c\xd7\x87\xec\xb2\xe5"
+  "\x41\x5f\xe4\x49\x68\xab\x16\xe9\x8f\x72\x62\x67\x7e\x6d\xb0\x9d"
+  "\xb7\xe8\x7e\xd9\x83\x65\x28\x5f\x0a\xfd\x47\x7e\xc9\x16\xc6\x2e"
+  "\xda\x71\xde\x39\xce\x73\x68\x23\x11\xe6\xb8\x9d\x07\xc4\x79\xcd"
+  "\xf8\xa0\xae\x44\xb0\x8d\x35\x61\x5c\x59\x68\x57\x8f\x32\x38\x5b"
+  "\x57\xeb\x92\xf7\x36\x5b\xd1\x56\xdd\x08\x65\x98\xdf\x75\xd1\x97"
+  "\x03\xc2\x32\x96\x51\xdc\xa8\x05\xfd\xe7\x61\x6a\x3f\xc7\x71\x11"
+  "\xe7\xeb\xaa\xa9\xa8\xfb\x85\xb3\x39\x9b\xd1\x4a\xea\x2d\x1d\x44"
+  "\xf0\x95\x87\x39\x7b\x1a\xbf\x51\xb6\x03\x0f\xf9\xe0\xfc\x05\xfa"
+  "\x6e\xc1\x18\xc8\x30\x8e\x0d\xcb\xd6\xd2\x79\xeb\x8b\xf3\xf6\x1a"
+  "\xc6\x60\x80\xe7\x54\x27\x46\x91\xbd\x19\x7a\x3a\x8f\x31\xb6\xc6"
+  "\x07\x30\x76\x98\x4b\xb5\x33\xbf\x2e\x5c\xf4\xf1\x45\x1e\xc1\x58"
+  "\x1a\x02\x9f\x64\xe0\x5c\x16\xc6\xce\x1b\xea\xc5\x8b\x73\xcf\x81"
+  "\xfe\xb4\x8e\xd3\x7c\xf3\x63\xf3\xad\x6e\xb9\x38\xd6\x56\x3a\x8f"
+  "\x0f\x86\x5a\x61\x1e\x3b\x8e\x29\x8e\x27\x8e\x2b\xd4\x85\xf7\xff"
+  "\xaa\x56\x1c\x53\x69\x3c\xeb\xc3\x04\x9a\x37\x30\x5b\x4e\x5d\x9b"
+  "\x60\xe7\xb1\x8f\xa1\xc0\x7f\x8d\x38\xa7\x96\xe2\xbb\xc3\xda\x80"
+  "\xcf\x47\x1e\xf9\x40\xc0\xac\x6a\x13\xf2\x48\x3d\xcc\xff\x17\x97"
+  "\x4b\xd8\x71\x50\x4b\x75\x16\xa0\x13\xa3\x4f\xfd\x8b\x34\x5e\x85"
+  "\x0b\xec\x30\x92\x5a\x95\x84\x4f\xf5\x89\xe2\x38\x88\x3c\x29\xce"
+  "\x7b\x68\x63\xab\x1c\x7f\xea\x57\x43\x1b\x01\x88\x6f\x92\x0c\x55"
+  "\x5f\x21\xc7\xb7\xfa\xe5\x88\x6f\xc8\xd7\xba\x74\xb4\x65\xd5\x0b"
+  "\xb1\xaf\x6b\xc2\xe5\x98\x54\x13\xc6\xbe\xc1\x33\x99\x0b\x79\x4b"
+  "\x37\x95\xd5\xc7\x35\x0c\xea\xd3\x3c\x25\xc2\x9a\x97\x81\x6b\x1c"
+  "\x9c\x13\x63\x61\x37\x43\xfd\x6a\xdc\x77\x88\xb1\x06\x6e\x6f\x66"
+  "\xba\x1e\xe0\xf4\x4e\x8c\x29\x6d\x24\xff\x68\xae\x87\x59\x78\xad"
+  "\x80\x61\xb7\x88\x15\xfc\x1b\xf1\xb7\x2f\x6c\x23\x83\x74\xbf\xe4"
+  "\xbf\x83\x35\x1b\x63\x0b\x5a\x30\xae\x21\xb4\xad\x39\x43\xbe\x7e"
+  "\x1b\x9e\x1b\x28\x1c\xd5\x70\x9c\x03\xc7\x3b\xe1\x38\x19\x8e\x77"
+  "\xc3\xf1\x49\xa8\xcf\x09\xf5\xc3\xa1\x1c\x06\xe7\x1f\x17\x8e\xd0"
+  "\x47\xc3\x0e\x38\xc6\x0a\xb2\x23\x9c\x3f\xd4\x85\x65\x38\x9e\x15"
+  "\x68\x5e\xcb\x68\x6e\x38\x05\xed\x64\x40\xff\x9b\x0c\xcd\xb4\x2d"
+  "\x1d\xd4\xf9\x04\xdb\xc6\x7d\xc0\xf0\xff\x14\x07\x19\x14\xda\x69"
+  "\x78\x07\x8e\x11\x70\x9c\x04\xc7\x34\x38\x86\x08\x63\xd0\x80\xd8"
+  "\x30\x33\x83\x8e\xf9\x38\x0d\x93\x77\x63\xc5\x39\x8f\xeb\xb0\x84"
+  "\x1d\xfb\xb3\x66\x26\x30\x7a\x1b\x49\x1d\xe5\x03\xa8\xfb\x14\xd6"
+  "\x85\xe3\x33\xc2\x31\x4a\x38\x8e\x17\x8e\xbf\x16\x8e\xd1\xc2\x71"
+  "\x82\x91\x34\x84\x0a\x32\x06\x8c\x4b\x43\x28\xf5\x2f\x2a\x0a\x0e"
+  "\x66\xcf\x38\x14\x8d\x3a\x32\xe0\xf8\x13\xd0\xbe\x57\x67\x7e\x43"
+  "\x95\x68\x87\x44\x9b\xcf\xb5\xfc\xea\x69\x1f\xd0\xef\xc7\x0d\x0d"
+  "\x0e\xd8\xb6\xd3\x57\x11\x45\x40\x06\x1a\x5e\xa6\x84\xf5\x9f\xb5"
+  "\xa3\x55\x0a\xdf\x5f\x85\x78\xf5\x5e\x18\xc3\x8d\xea\x43\xfe\x25"
+  "\x13\x70\xae\x52\x1b\x2d\xc6\x1b\xf3\x0f\xd1\xc3\xaf\x16\x74\x83"
+  "\x06\x11\xbf\x51\xef\x11\x62\x43\xee\xea\xcc\x3f\x34\x4e\xd2\xd5"
+  "\x1b\x3a\xd8\xb7\xaa\x3b\x42\xe0\x7c\x9c\xc3\xf9\xcd\xd8\x67\x18"
+  "\xcf\x26\x78\x9f\x88\x16\x72\x28\x0b\x8e\x8f\xb5\xb2\x77\x0e\x17"
+  "\xdf\x59\xa0\x87\x4e\x1c\xdf\x56\xd2\x30\x1a\xb0\x30\x15\x79\xb8"
+  "\xc5\x8e\xb3\x0d\x74\x4f\x9a\xc0\x23\x40\x4b\x03\xc6\xc0\xcc\x75"
+  "\x98\x83\x8e\x18\x14\x08\xfd\x68\x96\x63\xca\xfe\x66\xc4\x14\xe4"
+  "\x0d\xc0\x6f\xa0\xb5\x61\xa7\xd3\xfc\x5b\x8e\xf3\x8f\xcd\xbb\xaf"
+  "\xd5\xf2\x7b\xeb\x97\x5b\xd9\xbc\x6b\x02\x3e\x03\xfe\x34\x94\x21"
+  "\x7d\x8c\xe4\x90\x45\x98\xd3\x4d\x30\xa7\x9f\x80\xf3\x42\x6e\x60"
+  "\x76\x5e\x78\x16\xf0\x99\x01\xdf\xfb\x6e\xf1\xbc\xf0\xbe\xd8\x4e"
+  "\x1a\xd2\x5b\x3c\x2f\xb4\x0f\xfc\x68\x48\xc1\x79\x22\x9e\x17\xde"
+  "\x09\xe4\xa8\xaf\x2b\x45\x3c\x59\xc1\xf8\x2d\x52\xbc\x0f\xe9\x86"
+  "\x71\x9d\x98\x2d\xfd\xeb\x32\x98\xab\x15\xb8\x3e\x2c\x9d\x4a\x7c"
+  "\x17\x96\x92\x21\x6c\x5e\xa2\x4e\xe1\x88\x91\x87\xb3\xf9\x7c\x3f"
+  "\x2b\xaf\x0a\xa9\xaa\xb3\x46\x88\xf2\x6a\x59\x67\xfe\x37\x6a\x31"
+  "\x97\xb0\x14\xfb\xfe\x9b\x49\x75\x15\xf6\xf1\x85\xbe\x7c\x33\x4e"
+  "\xec\x8b\xc3\xfa\x4c\x69\x80\x7d\xc3\xb6\x96\x82\xbc\x6e\x06\x5c"
+  "\x60\xb8\xfd\x4d\x8a\x98\x63\xbd\x50\x58\xb7\x68\x9e\xef\x74\x96"
+  "\xe7\x1b\xd7\x46\xf4\xa5\xe1\xd0\x8e\x95\x61\x23\xf5\x3a\xd0\xe5"
+  "\x33\x4e\x93\x69\x8b\x06\x63\xec\x92\x78\xe8\xeb\x74\xe8\xdb\x26"
+  "\x1b\xda\xd8\xe7\xa2\x9e\x7a\x78\xb8\x2d\x9d\xb7\x08\x63\x06\xf3"
+  "\xa8\xb1\x4b\x18\x5b\xc4\xaf\x4d\x88\xe9\x4b\x73\x58\x1e\x1b\xb4"
+  "\xe5\xe0\xfc\x78\x0f\xd7\x31\x35\x6f\xa9\x2e\xc3\xb9\xf2\x8d\x55"
+  "\x94\x49\xa1\xbf\x15\x4c\x26\xac\x7b\x95\xc6\xf6\x29\x0a\xa9\x62"
+  "\xb6\xc0\xc6\x77\xd8\xbb\x37\xea\xd8\xf7\xe4\x10\x21\x56\x7c\x63"
+  "\x82\x97\x3a\xe8\xf7\xcc\xff\xa9\x3a\x93\xf9\x6e\x34\x4e\xb4\xfb"
+  "\x6e\x48\xb2\x62\x1a\x8b\xbb\xd4\x98\x2c\xcd\x89\xc6\x48\xbc\x0f"
+  "\xee\x5f\x0f\xe7\xf3\xa4\xf3\x75\xf1\x82\xbd\x6b\xe7\xd0\x25\x51"
+  "\xe8\xc3\x35\x1c\xe3\x3f\x0b\xcf\x33\xd2\xe7\x53\x9b\x07\xcc\x4d"
+  "\x61\xfe\xe2\x38\xe3\x9a\x4d\xe7\x30\xcc\x5f\x9c\xc7\xd7\x56\x87"
+  "\xe8\xe1\xc7\xe6\x2d\x5b\x9b\xd3\xe8\xbc\xa5\x73\xb6\xd1\xe4\xd0"
+  "\x8f\xcd\xd4\xee\x85\xf4\x5c\xac\xf6\xed\xcc\x3f\xec\x0b\xf2\xaa"
+  "\x90\x27\xe1\x1b\xea\x7f\x8c\xf1\x39\xac\x57\x79\x13\x7e\x43\xc6"
+  "\x6f\x8a\xb8\xc7\xc9\x0f\xb8\x1b\x63\x6a\x88\xdf\x84\x27\x75\xe4"
+  "\xf2\x36\xfc\xbe\x73\x95\x37\x17\xd9\xe3\xcf\x1f\x8e\x97\xe2\xe3"
+  "\x7c\x53\x25\xbc\x57\x15\x3c\xab\x8c\xf9\x5c\x7d\xf3\x09\x93\xa9"
+  "\xbe\xd9\x8c\x7c\x6a\x00\xde\x83\x63\x29\xcb\xa5\x7a\xb8\x58\xe4"
+  "\x3d\x98\x97\x33\xcf\x90\x23\x61\xc5\x41\x7c\x29\xd0\xb4\x14\xe6"
+  "\x52\x0a\x94\xfd\xe1\x38\x93\x1d\x15\x2a\x3c\x0a\x73\xa4\x14\xee"
+  "\x6d\x10\x73\x5e\xe3\xd8\x98\xfd\xb3\x63\x91\xcf\x0a\x61\x1c\x90"
+  "\xd7\xe8\xf7\x5a\x1d\xcb\x25\x8f\x7c\x86\x3c\xe6\xb7\xe4\x79\xca"
+  "\x67\x74\xff\x3e\x9c\xc7\xfe\x22\x9f\x75\xe6\x1f\x09\x16\x63\xcf"
+  "\x1a\xc9\x61\x3d\xfb\x6e\x72\x24\x5c\xf4\x59\xc5\x6f\x36\x69\x21"
+  "\x64\x38\xb4\xab\xa9\xd6\xd0\xf8\x8e\x27\x0d\xd6\xf1\x04\xeb\xe2"
+  "\xf7\x2e\x86\x93\x77\xa4\xc1\x3d\x33\xa5\x31\xdf\x4f\xfd\x36\xf6"
+  "\x26\x50\x5b\xe4\x30\xb8\x96\xe7\xa8\x67\x18\xc9\xbe\x89\xa8\x6b"
+  "\xa0\x0f\xdd\xc8\x40\x82\xb9\xe9\x01\xc7\x8e\x6c\x12\xe5\xda\x47"
+  "\x02\xf1\xbb\x79\xb5\x05\xfa\x87\x3a\x34\xbc\x6b\x75\x2b\xe8\x92"
+  "\xee\x6c\xc6\x11\x68\xeb\x11\x72\xc6\x34\xa3\x1d\x0b\x63\xec\x9f"
+  "\x21\xc7\xc2\xea\x4a\x81\x9e\xf3\x7a\xc6\x1e\xce\xc9\xe0\xaf\x60"
+  "\xfc\x61\x4d\x2a\x19\xd6\x42\x8e\xa1\x3e\xd8\x94\x7b\x11\x6d\x34"
+  "\xdf\x8e\x96\xdb\x68\xbe\xcd\x12\x7e\x45\xf0\x33\x4b\xbf\xa6\x65"
+  "\xc2\x91\xf4\xf1\x2b\x63\x75\x9b\x36\xc3\x6f\x87\x30\x56\x3b\x3a"
+  "\xf3\xbf\xb5\xdb\x7f\x91\x2f\x71\x6e\xa3\xbf\x04\xda\x9c\x14\x56"
+  "\x82\xb1\x3b\x80\x4e\xd0\xef\xa5\x0f\xbe\xa4\xcf\x44\x3e\xfa\x96"
+  "\xe6\x70\xc4\xb8\xb8\x9e\xf9\xec\x7c\x4b\xe9\xc9\x62\x54\x7e\xbb"
+  "\x0c\x9e\x5d\xbd\xea\x3c\xf1\xd6\xa5\x92\x7b\xd0\xfe\xed\x67\xe3"
+  "\xf5\xa8\xe3\x22\x4f\x6c\xa4\xb9\x5a\x9a\xde\x4e\xcb\x26\x4a\xb8"
+  "\x7e\x1f\xfc\x9f\x26\xca\x49\x70\x8f\xca\xcb\x42\x02\x51\x3e\x7a"
+  "\x26\x9b\xdc\xd7\x99\xdf\x14\x2b\xd2\x0a\x65\x08\xb4\xc3\x09\xb6"
+  "\x04\xec\x2b\xf5\x4d\xc4\xd8\xe9\x46\x3a\x6e\x14\x87\xb1\x0d\x98"
+  "\x77\x4d\xe3\xbc\xcc\x44\xc5\xd6\x9e\x26\xe0\xff\x6a\x41\x66\x6c"
+  "\x8a\x07\xde\x6f\x74\xe8\xe7\x55\xe9\x7f\xf5\x7f\xe0\xfd\x7e\x66"
+  "\x94\xcf\xdc\x8d\x4f\xd3\x29\x71\x7c\xd0\x2f\xd4\x0f\xf4\x04\x4a"
+  "\x6f\x2b\xdf\x01\x7d\xab\xd5\x65\x12\x9f\x76\x72\xf4\xd0\xc6\xb5"
+  "\x74\x9f\x5a\x0d\xb3\xcf\x1f\xdd\x27\xea\xe1\xac\xdf\x47\x57\xfb"
+  "\x2d\xf1\x22\x68\x57\xc7\x78\x61\xd4\xa7\xee\x82\x9a\xda\xd2\x0d"
+  "\xd6\x71\x44\x9f\x33\x16\xeb\x88\x72\x55\xf3\xe5\x5c\x35\xd9\xab"
+  "\x1e\x07\xf3\xf8\x68\x82\x51\xf9\x8f\x89\x9e\xfb\x2e\x1e\x4d\x10"
+  "\xc6\xb7\x96\x7d\xf3\x3f\xfa\x10\xae\x25\xcb\x84\xdc\xf4\xb8\x46"
+  "\x43\xdb\x55\xe2\xbc\x81\x75\xa3\x1a\xee\x19\xcd\x30\x06\xbf\xb3"
+  "\x1e\xa5\xf1\x45\xa8\xde\xc0\xea\xfb\x32\x9b\xff\xd1\x0e\xbb\x2c"
+  "\x0d\xf5\xf0\x3e\xe6\x0b\x76\x94\x4c\xb3\x29\x60\x4c\x8f\xd2\x77"
+  "\x63\xbc\xa8\x1e\xd7\x99\x7f\x2c\x58\x9a\xb7\x4d\x14\x9b\xf7\x76"
+  "\x38\xce\xcb\x63\xe3\x24\x7d\xf3\x88\xe9\xa1\x62\xa2\x71\x35\x0f"
+  "\x75\x43\x89\xea\x5f\x3e\xe4\xe5\x55\xab\xf8\x8a\x22\x25\xf7\xf4"
+  "\xd2\x42\xe2\xab\x58\x01\xc3\x86\xf3\x2c\x3d\x71\x38\xcc\xc7\x2f"
+  "\xfd\x7c\xef\x88\x7d\x26\xed\x36\x3e\x47\x4d\x94\x2b\x2f\xdd\xe6"
+  "\x13\x62\xb9\xa3\x82\xf7\x7a\xf0\xa5\x49\x69\x16\xa2\x99\x5d\x44"
+  "\xbe\x4f\x21\x5e\xcf\xd8\xe0\xd9\xbe\x44\x67\x24\xcd\x35\xb8\xe7"
+  "\x72\xaf\x2f\xca\x1f\xcd\x35\xd8\x66\x56\x19\xf1\xc9\x6a\xe5\xdb"
+  "\x56\xbc\x39\xc0\x07\xd6\x03\xd5\x07\xc0\x63\xb7\xfb\xde\x51\x71"
+  "\x0d\xda\xd8\x93\x48\xef\x73\xf9\xad\xbf\xf7\xbe\xe9\x82\xce\x90"
+  "\x7f\xbe\xea\x59\xdf\x4e\x24\x4b\x7d\x3b\x91\x7c\x83\xfb\xa6\x92"
+  "\xfa\x96\x8c\x7d\xbb\xe2\x59\xdf\x8c\x3e\x52\xdf\x8c\x3e\xfd\xec"
+  "\xdb\x16\xcf\xfb\x96\x71\xc7\x19\xd2\xbc\xda\xb3\xbe\x9d\xda\x2c"
+  "\xf5\xed\xd4\xe6\x1f\xd2\x37\xd4\xe5\x73\x82\xf9\xd3\x34\xc6\x79"
+  "\x2a\xf1\x45\x1f\xb9\x33\xe4\xf8\xc5\x9c\x32\x5a\x0e\x80\xff\xb7"
+  "\x0a\xf3\xdb\x94\x6b\xe6\xbf\x63\x72\xce\xf1\x3b\x1f\xd6\xa1\x5f"
+  "\xe9\x71\x15\xf0\x72\x0d\xe3\xe9\x13\xd4\xb7\x33\xd7\xc4\x0b\x7e"
+  "\x9d\xc7\xc7\x94\x53\xbf\x8f\x51\x1a\xa1\x9c\x75\x39\x20\x04\xf3"
+  "\xa3\x77\x70\x30\x9f\xf9\x80\x11\x04\x73\x3e\x6e\x4f\x35\x29\xf9"
+  "\x7c\x8c\xbd\x85\xf1\xf2\xbc\x09\xbf\x66\x84\x6a\x7b\xaa\x45\x89"
+  "\x31\x33\x96\xd2\xfd\xb2\xc7\xd3\xc4\x3d\x62\xe2\x33\x4c\xfe\xa3"
+  "\x34\x70\x7e\x85\x98\x67\x96\x57\xa2\x3c\x13\x62\xc1\xf6\xe1\xfc"
+  "\x26\x31\x17\xac\x91\x1c\x8f\x14\xb0\xc1\xec\x67\xe9\x0d\xf7\x8e"
+  "\x1f\x15\x71\xef\x99\x34\xe2\x87\xb9\x12\x57\xe5\xdc\x86\xdf\x1c"
+  "\x41\xfe\x39\x9e\x8c\xe3\x1e\x63\xbe\x8d\xf7\xcb\x22\x5e\xb8\x37"
+  "\x0e\x7d\xe1\x0c\x6a\x13\x09\xcd\x22\x03\x62\x32\xa0\x4d\x0b\x49"
+  "\xf4\xcb\x80\xf6\x60\xac\x99\x6e\x70\x82\xda\xf8\x8a\xa1\x3d\xfc"
+  "\xfe\xed\x95\x46\x7c\x9f\x51\xe7\xf2\x4b\xd7\x11\x6f\xdc\x47\x87"
+  "\xfb\xe1\xd8\x5e\xb8\x81\x3e\x9d\xf9\x27\xe2\xc4\xf7\xeb\x07\x7d"
+  "\x86\x32\xfa\x9c\x5c\x2d\xd1\xe7\xe4\xa4\x9e\xf4\x39\xf1\x05\xa3"
+  "\xcf\x89\x4a\x89\x3e\x27\xcd\x72\xfa\x9c\x38\x2a\xa7\xcf\xc9\xe0"
+  "\xeb\xa3\xcf\xc9\x40\x89\x3e\x27\xcd\x12\x7d\x4e\x8e\x76\x4d\x9f"
+  "\x93\xd1\x12\x7d\x4e\x34\xf5\x8f\x3e\x27\x17\xb9\xa7\xcf\x49\x9f"
+  "\x5e\xe8\x33\xd0\x35\x7d\x4e\xee\xef\x3f\x7d\x4e\x9a\x3d\xa0\xcf"
+  "\x10\x46\x9f\x53\x8f\x4a\xf4\x31\x9e\xeb\x49\x1f\xe3\xab\x8c\x3e"
+  "\xc6\x58\x89\x3e\xa7\x8a\xe5\xf4\x31\x2e\x92\xd3\xc7\xb8\xf3\xfa"
+  "\xe8\x63\xdc\x21\xd1\x87\x3d\x83\xd1\xc7\x58\xeb\x9a\x3e\xc6\x56"
+  "\x89\x3e\xc6\x8c\xfe\xd1\xe7\xd4\x9d\xee\xe9\x63\xdc\xec\x39\x7d"
+  "\x4e\xcd\x72\xa2\x8f\xca\x3d\x7d\x4e\x15\x7b\x40\x1f\x3f\x46\x9f"
+  "\x96\x43\x12\x7d\x5a\x56\xf6\xa4\xcf\xa9\x2e\x46\x9f\x53\x26\x89"
+  "\x3e\xdf\x45\xc8\xe9\xd3\x72\xa7\x9c\x3e\x2d\x09\xd7\x47\x9f\x96"
+  "\x38\x89\x3e\xec\x19\x8c\x3e\x2d\x29\xae\xe9\xd3\xb2\x4c\xa2\x4f"
+  "\x8b\xba\x7f\xf4\x69\xf9\xc2\x3d\x7d\x5a\x26\xf4\x42\x9f\xdb\x5c"
+  "\xd3\xe7\xbb\x41\xfd\xa7\xcf\x77\x11\xbd\xd1\xc7\x33\x59\xef\x3b"
+  "\x1a\x43\xeb\x06\xb4\xe3\x3e\x3f\x30\x8c\x1d\xfa\xf9\x71\xf9\xdf"
+  "\x15\x95\x73\x03\x7d\xd8\x5e\x88\xef\x26\x68\x32\xc9\xaf\x5a\xc8"
+  "\x77\xc7\xcb\xb9\x01\x3e\x7c\xfe\xa6\x99\x5c\xfe\xc7\xbe\xfc\x92"
+  "\x81\xde\xdc\x92\xdb\xbc\x71\x6f\xb3\xfb\xdc\xd3\xad\x4f\x7a\xdd"
+  "\x49\xee\xc5\xfd\x69\x4b\x41\x5e\xc6\xff\x3b\xf3\x5b\x27\x80\x2c"
+  "\xb8\xa2\xb7\x7d\x52\xe8\xeb\xb4\x77\x19\xea\xb7\xad\x69\xf6\xb8"
+  "\x12\xf9\x7c\x06\xc6\xe7\xd2\x8d\xc0\xfd\x0c\xad\x65\xc5\x34\xde"
+  "\x53\x70\x59\xd4\x08\xfe\x24\xea\x1e\x67\xc8\xe9\x75\xfc\xea\xe0"
+  "\x32\xe4\x07\x90\xd5\x87\x41\x9d\x56\xbb\x1f\x1c\x1f\xbf\x5e\xb0"
+  "\x11\x4e\x60\x75\xbf\x1f\x04\x75\x27\x60\x6e\xcc\xf9\x39\x98\xf3"
+  "\xf1\xcc\x45\x90\x7d\x47\xe1\x33\x30\xf6\xd0\x46\x38\xa2\x9f\x0c"
+  "\xf3\x81\x3c\x4d\xf7\xae\x62\x5c\x43\xe6\x73\x76\xe6\xa8\xc8\x77"
+  "\xf0\x9c\xc1\x50\xde\x23\xc8\xf3\x58\xff\x76\x28\x7f\xe2\x70\xdd"
+  "\x17\xca\x2b\xa1\x6d\x7f\xe1\xfa\x10\x28\xbf\x85\x72\x36\x8d\x93"
+  "\x51\x98\x27\xf8\xea\x9e\x89\x83\x73\x2a\xa1\x8e\x3f\xd4\x19\x83"
+  "\xb2\xbb\xd0\x46\x00\x94\xef\x41\x1d\x58\xb8\x1e\x08\x65\x8c\x2b"
+  "\xe5\x2d\x5c\x1f\x0e\x7d\x3c\x0d\xe5\xfb\xd9\xde\x92\x6b\xc2\x1c"
+  "\x3d\x5d\x79\x7d\x7b\xae\x4f\xb3\x58\x5c\x4a\x6a\x0b\x02\x5d\xe0"
+  "\xb4\x83\xff\xcf\xe9\x52\xf9\xb5\x33\x81\x0e\xd7\x96\x8b\xd7\x98"
+  "\x8f\xda\x99\x70\x87\x6b\x19\x4e\xd7\x26\x3a\x5c\x4b\x76\x6a\x33"
+  "\xd9\xe1\x5a\xbc\xd3\x7d\xcb\x1c\xae\x45\x3b\x5d\xab\x70\xb8\x16"
+  "\x21\x5c\xf3\x82\xf3\x55\xd2\x37\xbc\xd3\xa1\xc2\x79\x25\x9c\x6f"
+  "\x70\x38\x1f\x28\x9c\xc7\xe7\xb7\x19\xc9\xfb\x33\x85\xf3\x94\xf6"
+  "\xac\xfd\xef\x89\xd4\x7e\x6b\x2b\xb3\x71\x7c\x1f\x68\xf7\x9d\x0b"
+  "\x18\x11\xcb\x5d\x8b\x5f\x0f\xd7\x6a\x91\xaf\x1c\x79\x7b\x6e\xba"
+  "\x66\xc6\x82\xdf\x6a\x52\x93\xd2\xd0\x7d\x65\xce\xac\x34\xcd\x9c"
+  "\x79\x33\x93\x64\x71\xca\x03\x31\x66\x1f\xe6\xf9\xc2\xd8\x27\x42"
+  "\x4c\xfd\x36\x7b\x1e\x0a\xc0\x55\x78\x56\x9e\x91\x44\xd3\xef\x63"
+  "\xc5\x2c\x9e\x77\x0d\xc6\x4e\x61\x71\x52\xc8\xf3\x2d\xe4\xfb\xb7"
+  "\x85\x38\x29\x7a\xa8\xbb\xc5\x7d\x9c\x94\xb3\xcb\x69\x7c\x40\xa8"
+  "\xc7\xe2\xa4\x9c\x5d\x01\xf3\xfc\x19\x7e\x30\xcb\x2b\xc1\xf2\x6d"
+  "\x7d\x2f\xca\x26\xa6\x69\x5d\x34\xc6\x5e\x1e\xb3\x65\x38\xc7\x3b"
+  "\x0d\xce\xc2\xfb\x84\xef\xa5\x59\xd2\xfd\x6d\x6a\x76\x5d\x5c\x1f"
+  "\x84\x67\x16\x05\xe7\x41\x79\x70\x0b\x94\xa9\xfd\x9e\x5e\x6b\x63"
+  "\xb6\xbc\xd5\xc1\xcb\xf0\x9d\xf0\xbd\xe5\xef\xa6\xfc\x4d\x0b\x69"
+  "\x9b\x2e\xbd\x5b\xdb\x72\x87\x58\x6a\xc2\x3b\xb4\x55\xb2\x39\xda"
+  "\xe3\x5d\xa9\x7f\x22\xaf\x0a\x5e\x86\xcf\x46\x3c\x63\x7b\x06\xa0"
+  "\xbc\x3a\x38\x4f\xec\x8f\x43\xff\x96\xa1\x5e\x0f\xfd\x5b\x49\xc7"
+  "\x04\x68\xca\x03\x4d\x85\x77\x98\xc4\xe7\x7f\x1f\x4e\x7d\xe0\x71"
+  "\xaf\x2d\xe6\x09\xa1\x6b\xd5\x59\x7b\xfe\x1f\x5c\xa3\x98\x0d\xf3"
+  "\xac\x24\xff\x61\x8c\xab\xd5\xe2\xfa\x75\xd6\x41\xfe\x63\xcf\x84"
+  "\x73\xf1\x8e\x3c\xe4\xf0\xbc\xb7\xf1\x79\x50\x8f\x30\xbf\xfb\xe0"
+  "\x3c\x9c\xef\x46\xd2\x56\x8d\xbe\x98\x78\x2f\xf6\xd1\x5d\x6e\x38"
+  "\x77\x31\x08\xa5\x71\x3c\xdb\x20\x8e\x63\x31\xcd\x51\x74\xd6\x28"
+  "\xda\xeb\xe8\xbe\x1f\xa8\x53\x6c\xcf\x95\xdc\xce\x72\x35\x16\x95"
+  "\x54\x3d\xe2\x4b\x12\xd9\xd8\xb6\x0f\x47\x8c\xc7\x39\xc3\xb0\xbe"
+  "\x3d\x8d\xd1\x3c\x4c\xc8\x3f\xd2\xfe\x24\x9e\x97\xfc\xdc\xdb\x8b"
+  "\xc5\x7a\x22\x2e\xb3\xef\x55\xed\x73\x68\x3d\x96\xbf\x96\x30\x9a"
+  "\xdf\xaf\x6a\x21\xed\xc2\xde\x85\x76\x16\x1f\x95\xc6\xbf\x69\x2f"
+  "\xe3\x57\x8f\x82\x31\x6b\x07\xfd\xe7\xfb\x09\x6c\x1c\xd9\x73\xe1"
+  "\x98\x87\x7d\xc1\x31\xc2\x3d\xda\xfc\xea\x92\x2a\xde\x3f\xcc\x65"
+  "\xee\x13\xc1\x7f\xfa\xbe\x76\xd2\xc1\x64\x08\x25\x6f\x41\x1b\x2b"
+  "\x7b\xd7\x8e\x3b\x1d\x7c\x8c\x7d\xc5\x3a\x0c\xbb\xe9\x35\xea\xbb"
+  "\xad\x4b\x47\x7b\x90\x70\x2d\x1d\xf7\xb1\xda\xff\x1f\xe8\xf0\xff"
+  "\x00\xfc\x9f\x4f\xe7\x2b\x57\x65\xd2\xb5\xd5\x5b\xda\x23\xdf\xa1"
+  "\x86\xb2\xaf\x53\x39\x50\x56\x5e\x44\x82\xa9\xff\xad\x99\x6f\xa5"
+  "\xbe\xda\xc2\x79\xa1\xed\x41\xb4\x3f\xe9\x7c\x24\xf0\x46\x11\xee"
+  "\x79\x16\xe6\x61\x11\xee\x95\xf6\xb3\x4e\xa1\xfb\xa4\xe1\x7a\x84"
+  "\x70\x0c\x17\x8e\xa3\x59\xee\xd0\x7f\x39\xe4\xff\x46\x1b\xcd\xbf"
+  "\x8c\xee\xf2\x91\x8b\xf9\xda\xc5\x7c\xe4\xb8\xcf\x5a\xc8\x9f\x9a"
+  "\xd0\x99\xdf\xa1\xee\x2d\xf7\x3b\x5c\x8f\x14\xf7\x4c\xdb\x8a\x82"
+  "\x23\xb8\xa2\x1c\x35\xe6\xaa\xc4\x38\x5b\xb9\x1d\x18\x6b\xc5\x4c"
+  "\x0c\xa4\x9b\x18\xd2\x3a\xf3\x30\x5f\x65\xbd\x85\xc6\x2e\xc6\xbd"
+  "\xa6\x0a\xb4\x9b\xa3\xec\x58\xaf\x3b\x47\x73\x55\x2e\xec\x20\xc1"
+  "\xba\x5f\xf2\xad\x30\x06\x65\xb6\xd5\xc1\x11\x02\x1f\xad\x83\x35"
+  "\xf0\x5e\x18\x0b\x6a\x2f\xa6\xb9\x96\x3b\xe8\x77\x2f\x9f\x33\xe4"
+  "\xdc\x68\x5a\x87\x8f\x5f\xc7\xc6\xee\x1c\xb5\x7d\x6d\xcc\x17\xf3"
+  "\x11\x76\xd8\xf3\x1f\x1b\xc9\xb9\xf0\x2b\xfe\xf1\x16\x38\xd7\x26"
+  "\xf7\x99\x3e\x47\xdb\xc4\xbe\x1b\x49\xc7\x26\x6c\xbb\x33\xff\x9c"
+  "\xaf\x7d\xce\xc2\xf9\x85\x56\x72\x17\xf4\xeb\x8c\xd8\x3e\x5c\x87"
+  "\xf9\xdf\x5e\x85\xd7\xb1\xcd\x2b\xab\x73\xa0\xdd\x73\x51\x46\xaf"
+  "\x0b\x11\xcc\xe7\xfa\x1c\xac\x7f\x7f\xa8\xea\x4d\x06\x82\xb9\x10"
+  "\x0e\xf8\x19\xc9\x15\x8d\xd2\xb2\x58\xd8\xa3\xc2\x99\x8d\xf1\xdc"
+  "\x3a\xf4\xeb\x5a\x75\x95\x78\xa3\x0f\x04\xe3\xd9\x73\x6c\x7f\x0f"
+  "\x9c\x03\xac\xde\x0c\x73\x84\xea\xfe\x9e\xad\xfb\xe7\x68\x8c\x9f"
+  "\x55\x97\x88\x4f\x61\xaa\x18\xcb\xfb\x9c\xd9\x21\xff\x80\xb0\xbf"
+  "\xe4\xfc\x3d\xf8\xa5\x7c\x55\x37\xeb\xa3\x73\x1f\xb0\xbf\xd0\x56"
+  "\xa9\x5b\x19\x53\x35\x4a\x4b\xbf\xcf\xac\x19\xa1\x61\x3e\xaa\xe7"
+  "\x93\xbc\xd4\x77\xaf\xed\xcc\x3f\x9f\x68\xcf\xbb\x00\x75\x0a\xd1"
+  "\xf7\x1e\xda\xb7\xbf\x67\x2a\x3e\xe3\xfc\x72\x36\xd7\xcf\x97\x71"
+  "\xab\x47\x69\xb1\x0f\xc2\xf9\xb2\x7a\xab\x05\x63\x2c\xb8\x8c\x53"
+  "\x45\xf3\xb9\xa1\x4f\xf8\x9a\x51\x5a\xdc\x9f\xf3\x88\x45\xec\xf3"
+  "\x85\x32\xdc\x17\x82\x7d\x66\x63\x7b\x61\xb5\x38\x8e\x2b\x2f\x41"
+  "\xdb\x39\xc7\x48\x2b\xb9\x70\x27\xfa\xcd\xe1\x3e\x27\x9c\xc3\x6c"
+  "\x0c\x2e\x50\x9d\x8f\x3e\x9f\xd6\x39\x4f\x75\x7f\x9a\x5b\x07\xda"
+  "\x2f\xa7\xf9\xc1\xe0\x1d\x80\x16\xfa\x1c\xdc\x5b\x7f\x81\xee\xf1"
+  "\x59\x9a\x4a\xd8\x7b\x53\x3f\xd9\x0b\xc2\x77\x92\x0b\xf1\xe2\x5a"
+  "\x61\x14\xce\xad\xc2\x67\xa7\x77\x93\xf3\xe4\xc2\x18\xcc\xfb\x0d"
+  "\xe3\x11\x89\xf1\xdd\xea\xcd\x30\x4f\x32\xba\x91\x17\x22\x31\x9f"
+  "\x24\xd4\x8f\x64\xeb\x1b\x8e\xf9\x85\x60\x7c\x3e\x8e\x2d\xd0\xce"
+  "\x04\x63\xba\x09\xda\xde\x21\x8e\x69\x61\x10\xea\x3b\xe7\x1b\x7a"
+  "\x5b\x1b\x6c\xd0\xe7\x7a\xa0\x9c\xfe\xae\x63\xd0\x3f\x53\x36\x17"
+  "\x30\x8a\xc6\x57\x86\xff\x85\xbd\x69\x8c\x76\x6c\x2e\x99\x26\xc3"
+  "\x33\x0c\xe8\xdf\x80\x58\x89\x31\xc8\xe0\x9d\xac\xc2\xf8\xd1\x7c"
+  "\x0c\x45\xe9\x6c\x1c\x84\xfa\xc2\x77\x9e\xbb\x0f\x77\xe6\x9b\x26"
+  "\x4a\xf6\x62\x13\x5d\xbb\x91\xdf\xca\xa9\x4e\x68\x4a\x76\xe8\xb3"
+  "\x99\xee\x33\xbd\x84\xb6\x3e\x93\x0a\x9f\xb5\x12\xe3\x6f\x21\x5f"
+  "\xb4\x3b\xf2\xff\x85\x8b\xd8\x4f\xf4\xf9\xb5\xf9\x8f\x80\xf5\x76"
+  "\x44\x28\x8e\x33\xdc\xa3\x85\xb9\xe0\x52\x3f\x11\xd6\x42\x9a\x0b"
+  "\x0e\x9e\xd9\x2c\xae\x85\xa0\x5f\xc0\xba\x70\xf1\x30\xd5\x3b\x41"
+  "\x9e\x36\x70\x28\xcf\x5c\x6c\x44\xbe\x81\xb9\x9e\x21\x60\x6c\x46"
+  "\x67\xfe\x45\x95\xf8\xcd\xcb\x86\xfb\x26\xce\xd3\xef\xbd\x66\x31"
+  "\xc7\x19\x8b\x77\x77\x31\x42\xda\x67\x71\x31\xaa\xc7\x3e\x0b\xdc"
+  "\x63\xb3\x96\xe6\xc2\xda\x82\x6b\x4a\x5d\x47\x2b\xae\x11\xf4\x7e"
+  "\xdc\x7b\x91\x03\x3a\x39\xdb\xa7\xd3\x8a\xf6\x79\x9a\x33\x04\xfb"
+  "\xc2\x72\x37\xb4\xd0\xff\x81\x6f\xbd\xf1\xc8\x78\xe9\xe2\x26\x7b"
+  "\x1e\x6f\xa0\x37\x7e\x6b\xdb\xeb\xfd\x2c\xd1\x8f\xc0\xf5\xfa\xe2"
+  "\x61\xcc\x49\x0d\x75\x6a\xc4\x7c\xd4\x34\xff\x34\x7b\x9f\x14\xb7"
+  "\x71\x0d\x1f\x26\xe1\xb8\x2f\x1f\xf7\xb1\xd1\x31\x50\x95\xc4\x63"
+  "\xac\x64\x8c\xfb\xa8\xcf\xc4\x9c\x26\x97\xde\x7e\x2f\x88\xee\x05"
+  "\x36\xeb\x1f\xbe\x84\x7e\x58\x1d\x67\xb2\x68\x3c\x23\x9f\x98\x0c"
+  "\x2b\x8f\xf7\x51\x79\xc2\xbf\x04\x63\xfd\x75\xd0\x5c\x01\xd8\xe6"
+  "\x75\xc7\xfd\xbd\x14\x2b\xc8\xa6\x1d\x80\xfb\x77\xb4\x93\x4b\x54"
+  "\x76\x87\xff\x83\xda\xc9\xe5\xad\x2c\x2f\x2a\x8b\x5d\x2f\xf8\x63"
+  "\x0f\x64\xb1\x2c\x60\xcc\x68\x6c\x81\xcb\x21\x9a\x07\x31\x87\xf0"
+  "\xe5\x30\x1a\x47\xba\x28\x78\xb9\x30\x06\xcb\x57\xb1\x7e\xf9\x4d"
+  "\xcb\x50\xd2\x3e\x62\xff\x3c\xec\x5b\x87\xa0\x47\x0c\xec\xcc\xbf"
+  "\x1c\x2e\xc6\xc0\x60\xf2\x14\x8b\x2f\xcd\x68\x71\x79\x83\x20\x3f"
+  "\xaf\x10\x9e\xbd\xe2\x87\x3f\xfb\x72\xb2\xd0\x66\x22\x8b\xb1\x7d"
+  "\x29\x10\xda\x4d\x84\x7e\x54\x89\xfa\x8c\xb0\x87\x68\x34\xd3\xb3"
+  "\x2e\x37\x48\xfa\x0c\x1b\x43\xd9\xfe\xb6\x79\xf3\xd2\x34\x33\x67"
+  "\xcd\xd7\x4d\x4f\x7b\x23\x59\x93\x94\x9a\x3a\x2f\x55\x83\x41\x8e"
+  "\x1c\xe7\x0f\xcb\x03\x74\xb9\x55\xc8\x99\xb7\x59\xca\x99\x67\x1e"
+  "\xed\x98\x67\xd2\x48\xcc\xe1\x37\xc6\x76\x61\x9e\xe8\xae\x9d\x22"
+  "\x25\x57\x09\xbf\x2a\xf8\xe9\xe1\x57\x83\xb6\x8c\x69\x16\x12\x05"
+  "\x6b\x3d\xc5\x3c\x29\xb6\x83\x19\xe3\x80\x46\xb5\x10\xf3\x27\xe5"
+  "\x9c\x37\xa1\xb1\x7a\xf2\x39\xdc\x9f\x89\xf1\xd0\xab\xe0\xa7\x87"
+  "\x5f\x0d\xfc\xe8\x7d\xdc\x57\x74\x5f\x7a\xa5\xe3\x35\xe6\x3f\x92"
+  "\x5d\x8b\x75\xf8\x25\xa8\x22\x62\x4e\x70\x56\xcf\xa9\x0f\x4a\x3e"
+  "\xff\x5c\xa2\x50\x8f\xea\x92\x43\x97\x10\x8d\x8b\x7a\x5e\x7c\x7e"
+  "\x6b\x82\x50\x8f\xfa\x1d\x8b\xef\x83\xb1\xfa\xa1\xbe\x58\xcf\x9b"
+  "\xcf\xbf\xd8\x26\xd4\xa3\x3e\x72\x5c\xbe\xd2\xd5\x73\x07\xf0\xf9"
+  "\x7f\x49\x16\xea\xa9\x1c\xdb\x73\xa8\x33\x90\xcb\x3f\x86\x31\xf1"
+  "\x1b\xb8\x25\xde\x81\x4c\x76\x32\x4f\x84\xfa\x2e\x63\x9c\x7a\x46"
+  "\xa7\x2b\x66\x67\x3a\xe9\xde\x98\x95\x34\x76\xd6\xdc\x74\xcc\xd4"
+  "\x94\x36\x6f\x41\x1a\x1e\xe7\x4e\xff\x1d\x3d\xcc\x9b\xf6\xe6\x1b"
+  "\xec\x9f\xb4\x94\x70\xfc\x27\x05\xf8\x0d\x8f\x33\x17\xe8\xf0\xf0"
+  "\xc6\x3c\x2c\x66\x24\x8f\x5e\xf0\x86\x98\x9e\xde\x91\x0f\xb5\x9d"
+  "\xf9\x57\xcb\x80\x37\x56\x30\x9c\xbd\x0a\xeb\xe2\x77\xd4\xdf\x0b"
+  "\xf3\x11\xed\xd3\x5a\x89\x68\xd7\x92\xc7\xf6\xb8\xfa\x39\xc6\xf6"
+  "\xf0\x5b\xa2\x7b\xc3\xcf\x3a\x2b\x09\xd6\x8c\x38\xb8\xb7\xd5\x48"
+  "\x7e\x6b\x11\xb0\xb1\x94\xc6\x09\xcd\xbf\x1a\x21\xf8\x76\x7a\x73"
+  "\x45\xc1\x13\x31\xfe\x3d\x94\x69\xee\x67\x28\x67\x40\xb9\x18\xca"
+  "\x98\xf3\x39\x10\xca\x71\x68\x93\x82\xb2\x1a\xca\xc1\x5c\x91\x5f"
+  "\x22\xee\xe5\x85\xb2\x06\xca\xa1\x9d\xf9\x9d\xd1\xe2\xbc\x70\x2d"
+  "\x2b\x77\xce\x14\xf3\x51\xb3\xdc\xd3\x9d\x69\xf6\xdc\xd3\x98\x0f"
+  "\x29\x47\x95\x40\xd7\x5f\x2a\x83\x74\x96\x7a\xa9\xef\xc1\x36\x4b"
+  "\xc5\xf5\x92\xd9\x3b\x3a\x37\x8b\x71\x4a\x98\x3d\xa3\xb3\xca\x21"
+  "\x87\x37\x96\x6b\xc4\x1c\xde\x68\xef\xa2\x39\x04\xe1\xc8\xe7\x63"
+  "\x3c\x56\x7e\xb3\x4b\x5b\x1e\xcd\x3d\x69\x79\x08\x63\xdb\x9a\x72"
+  "\x67\x2a\x46\x96\xa3\x0d\x0d\xca\x2c\x36\x23\x7f\x9e\x74\xd2\x58"
+  "\x23\x62\xdc\x36\xc7\x98\x0d\x2e\xf7\x43\x7d\x0d\x32\x03\xcd\x17"
+  "\x95\x32\xcf\xcf\x3a\x3d\x89\xc9\x81\x96\x95\x0c\xbf\x46\x44\x33"
+  "\x79\xc1\x92\xc1\xbf\xc4\x72\x8a\x18\x89\xc5\x8a\x3a\x8b\x9f\x22"
+  "\x65\x1e\x0f\xf7\xfa\x65\x4c\x4f\xa2\xe7\xa0\xde\x52\x90\xd5\x84"
+  "\xfe\x4d\x31\x04\xe3\x5e\x52\x4e\x88\x45\x61\x49\x98\x7a\x4f\x1e"
+  "\x3e\xc7\x87\xca\x21\x5f\x13\x5f\xcc\x01\x89\x7d\x2b\x77\x88\x2b"
+  "\xb7\x0a\xce\xa1\x0f\xe9\xe5\x97\x88\x2f\xc6\xd1\x15\xfa\x92\xc0"
+  "\xf2\x6f\x59\xcc\x62\x4c\x27\x78\x5e\x82\xf3\xfb\xbc\xf4\x32\xe5"
+  "\xca\xb0\x37\x46\xc7\x8e\x87\xff\x46\x0b\x69\x94\x1d\x79\x33\xf8"
+  "\x72\x40\xa8\xf6\xf2\xb6\xe0\xf7\x59\xae\xcc\x2e\xd0\xff\x3b\xdb"
+  "\xa8\x0f\x0b\xea\x25\x9d\xf1\xa5\xcc\x07\xb5\x2b\x1b\xe3\xd6\x72"
+  "\xf9\x28\x4f\xe2\xfe\xe4\xae\x14\xe4\x59\x5e\x35\x62\xc2\xc6\x6c"
+  "\x8c\x91\xac\x80\x31\xee\x9a\x8e\xd7\x84\xd8\x58\x4a\x1a\x4b\xca"
+  "\x46\xd4\x74\x2f\x2e\xc8\x28\xb8\x07\xf5\x0c\xb1\xce\x41\xb9\x03"
+  "\xed\x49\x5c\x7e\x97\x0f\xf2\x2d\xd0\x18\x63\x75\x98\xf9\x80\xe0"
+  "\x48\xde\x7f\x04\x8d\xa5\x86\xb2\xae\x41\x85\x63\xd6\xd5\x08\xcf"
+  "\x7d\x06\x7e\xbf\x61\xb9\x5b\x5e\x6f\x13\xdb\xc4\xf8\x65\x20\x43"
+  "\xc5\xc1\x51\x05\xfd\xb6\x3a\xe4\xb4\x13\xf6\x1e\x77\xdf\x83\x71"
+  "\xd5\xb0\x6d\x26\x3b\x5b\x5f\x65\x32\x48\x37\xc8\xa2\x7e\x45\x6c"
+  "\x2e\x76\x83\xfc\x53\xb0\x59\xf8\x1f\xe4\x9f\x47\x63\x9d\xda\x78"
+  "\x47\xb4\x95\x32\x9e\xee\x9e\x09\x3c\xfa\x0c\xfc\x7e\x03\xf5\x75"
+  "\x62\xde\xf6\xa5\x4a\xba\x4f\xf2\x8c\x97\x1a\xf7\x95\x77\x2f\x17"
+  "\xcf\x0f\x50\x44\xc1\x98\x76\x97\x8a\x73\xff\x72\xc0\x88\xd1\x50"
+  "\xde\x2c\xda\x58\x98\xcd\xa5\xbb\x4a\x2a\x8f\x88\x84\x72\x8d\x58"
+  "\x86\xff\x1b\x45\xac\x40\x3d\xf1\x32\xe8\x92\xa8\x77\xbe\xa1\x06"
+  "\xb9\x50\x8d\x7a\x5e\x37\xd0\xbf\x20\x99\xd5\xbd\x06\x32\xe8\x3b"
+  "\xa1\xc2\xff\xbe\x46\x2f\x53\x87\xf8\x2e\x5c\xbe\x97\x1f\x7b\x1f"
+  "\x6b\x34\xb7\x3a\x47\x6d\xf2\xbf\x1b\xf4\xbd\x6b\xb0\xfe\x77\xb2"
+  "\xf7\x4d\x3f\x57\xb1\xa2\x5b\x15\x87\x1e\x8f\xfa\x37\x91\xbf\xac"
+  "\xd4\x0f\x6b\x65\xa6\x2a\x16\x65\x4c\x8c\xad\x41\xe3\xe0\x61\x2c"
+  "\x48\x2b\x19\x48\xe3\xef\xaf\xce\xf1\xa1\x71\xe7\x17\x6a\x7d\xc5"
+  "\x38\x90\x7c\xd1\xdd\x1d\xbc\x32\x25\x10\x63\x43\xd2\x3c\x1b\x9d"
+  "\xda\xa1\x34\x1e\xa4\x10\x07\x72\x43\x3a\x09\x2c\xe3\x58\x1c\x48"
+  "\x1a\x77\x63\x20\xe8\x24\xe9\xae\x63\x41\xf2\xf9\x7f\xdc\x29\xc6"
+  "\x82\xe4\xaf\xda\x2c\xf0\x7f\x28\xbc\x3b\xe6\x1f\xd7\xd2\xb2\x14"
+  "\xc3\xc9\xdb\x65\x6c\x48\x25\x60\x9c\x92\xc5\x86\xf4\x6c\x6d\xb0"
+  "\xaa\x18\x9f\x58\x63\xc5\xbc\xf2\x0e\xe7\x00\xff\x2c\x42\x6e\xac"
+  "\xee\x60\xe1\x5c\x86\x91\xbc\xbd\x53\xf0\xaf\x34\xa1\x8d\xac\x98"
+  "\xda\xc1\xba\x2a\xf8\x6b\xc9\xeb\x5c\xe1\xcb\xa5\x80\xf7\x1b\x2e"
+  "\xd1\x98\x0f\x56\xa0\xbd\x8d\x62\x1d\xd3\x1b\xad\x55\xce\x73\x78"
+  "\xc6\x1b\xf3\x66\x26\x4d\x9b\x3d\x47\xa7\x79\x29\xee\x19\x9a\x54"
+  "\x70\xb4\x66\x56\x5a\x12\x5d\x7e\x34\x2f\x8d\x7f\x3a\x26\x26\x6e"
+  "\xda\xcb\x71\x4f\xc5\x4d\x7e\xf9\x49\xb6\x3b\x31\x2e\x75\x11\x26"
+  "\xa6\x4c\x9b\xa7\xc1\x9b\x66\x08\xd9\xac\x33\x93\x52\xe7\x39\xcf"
+  "\xfd\x40\x6a\xd3\x52\x52\xfb\xad\x19\xff\x67\x76\x33\x5b\x9c\x68"
+  "\xcf\x62\x38\x67\x1b\x8f\x63\x4b\xf3\x84\xe6\x5b\x6b\x51\x96\x12"
+  "\xf2\x8c\xe3\x1a\xe3\x8d\xf3\x17\xd7\x9a\xce\x7c\x5b\x9e\x63\xbc"
+  "\x2b\xe1\xde\x4d\x4a\xbc\x4f\x98\xb7\xc2\xb9\x2f\xf8\xbb\xee\xca"
+  "\x65\x31\xab\x6c\x3b\x44\x1b\x37\x9e\x13\xfb\xd0\x82\x75\xf2\xad"
+  "\x36\x29\x9f\xad\xad\x59\xca\xd9\x48\xff\x64\x63\x44\x08\x8a\x2e"
+  "\x03\x40\x2e\x19\x08\xbf\xdb\xf0\x37\xc1\x8e\xe5\xe9\x7c\x13\xea"
+  "\x67\x7e\x0a\x58\x6f\x33\xbc\x58\xce\xa7\x82\x46\x9a\xa7\x20\xc6"
+  "\x66\xf5\x9a\x66\x53\xc2\xd1\x8b\x9f\x66\xf3\xa6\x3a\x21\x9f\xce"
+  "\x37\xd2\x7d\xf5\xe9\x7c\x03\xe6\x36\x03\x3e\x5e\x1e\x63\xcd\x59"
+  "\x1e\x63\xe3\xad\xd3\x40\x56\x87\xe3\xf7\xb8\x3f\x3c\xc6\xf6\x3d"
+  "\x4f\xf3\xbb\xe0\x3e\x7a\x16\xbb\xaf\x06\xfd\x25\xa7\x02\x0f\x97"
+  "\x5f\x62\x39\x71\x63\x16\x5d\x38\x39\x6d\x91\x91\xe5\xc4\x3d\xcf"
+  "\xf2\x48\xb3\x5c\xdb\x24\x07\xda\xd9\x3f\xcd\xe6\xa5\x89\xb1\x5d"
+  "\xe3\xd9\x1e\x57\x4e\xdf\x5b\x9e\x5b\x97\xb6\x8a\xc2\x07\x8a\xf9"
+  "\x92\x90\x99\x7c\xe1\x68\x1d\x1c\x5b\xf9\xa2\x91\x81\x88\xd7\x7c"
+  "\xe1\x23\x13\xf9\x92\x11\x70\xfe\x31\x2d\x1c\x5b\xf9\xc2\x27\xbc"
+  "\xf9\x92\x91\x50\xfe\xb9\x11\x8e\x50\x1e\x54\x0b\xf5\x13\xf9\xc2"
+  "\xdb\xc7\xc1\xd1\xc8\x17\xfa\x6e\x81\x7a\x50\x1e\x1a\x0c\x47\x28"
+  "\xfb\xad\x80\x7a\x50\x56\x59\xcf\x10\x7e\x19\xfc\x0f\xe7\xc6\xee"
+  "\x64\xcf\x7a\xb2\x86\x3e\xab\x30\xaa\x91\x3d\xe3\x19\x23\x7b\xc6"
+  "\xb3\x1d\xec\x19\xcf\x59\xd8\x33\x02\x52\xa0\x5e\x32\x5f\x18\x18"
+  "\x0f\xc7\x36\xbe\x30\x28\x1a\xea\x41\x59\x1d\x0e\x47\x28\xdf\x05"
+  "\xcf\x1a\x09\xe5\x60\x1f\x38\x42\xf9\x1e\x33\xd4\x4b\xe1\x0b\xef"
+  "\x6b\x85\x63\x07\x5f\x18\x82\xed\x43\x79\x64\x35\x1c\xa1\x1c\xb6"
+  "\x03\xea\x41\xf9\xfe\x4d\x70\x84\xf2\x24\x78\xa7\x10\x1d\x5f\xf8"
+  "\x42\x15\x1c\x4d\x7c\x61\x2c\x3c\x6f\x04\x94\x5f\xd2\xc0\x11\xca"
+  "\x2f\xc3\xfd\x23\xa1\x3c\x79\x39\x1c\xa1\xfc\x1b\x7c\xd7\x34\xbe"
+  "\x30\x1e\x9f\x63\xe6\x0b\x5f\xc3\x77\x86\x72\xc2\x4c\x38\x42\x79"
+  "\x2a\xf6\x07\xca\xd3\xf0\x3e\x28\x4f\x87\x31\x08\xc9\xe0\x0b\x67"
+  "\x26\xc0\xd1\xc2\x17\xfe\x76\x34\xd4\x83\xf2\x2c\x2b\x1c\xa1\x9c"
+  "\x02\x63\x38\x12\xca\xf3\xca\xe0\x08\xe5\x54\x7c\xdf\x2c\xbe\x70"
+  "\x41\x14\x1c\xad\x7c\x61\x46\x20\xd4\x83\x72\x66\x1b\x1c\xa1\x9c"
+  "\x0d\xe3\x37\x12\xca\x79\x45\x70\x74\x49\x63\xbe\x70\x99\x0f\xbf"
+  "\x64\x20\xe1\x0b\x57\x25\xf3\x4b\x6e\x83\xe3\x6a\x35\xbf\x64\x80"
+  "\x96\x2f\x2c\xae\x81\xf3\x70\x5c\xe3\x0d\xe5\xd1\x42\x19\x8e\x6b"
+  "\x4c\x50\x0e\x17\xca\x70\x7c\xaf\x19\xca\x11\x42\x19\x8e\xa5\x58"
+  "\x8e\xe4\x0b\xd7\xc1\x71\x20\x1e\x13\xa0\x3c\x4e\x28\xc3\xf1\x83"
+  "\xcd\x70\x84\xbe\xad\x2d\x86\xf3\x51\x7c\xe1\xfb\x71\x50\x86\x63"
+  "\x69\x20\x94\xa3\xe1\x98\x01\xe5\x68\x53\x98\xbf\x0a\xd7\x73\x3e"
+  "\xa0\x4d\xc3\x05\x85\x19\x73\xaf\x10\x25\xc6\x19\xaa\xcc\x31\x62"
+  "\xac\x95\xfb\x5a\x14\x8a\xe9\x98\xcf\x02\xeb\xd8\xd6\x86\x24\x72"
+  "\x41\x21\x46\x38\x3f\x10\xea\xdd\x76\x46\xa1\x5c\x80\x18\x63\xc8"
+  "\x32\xd2\x3c\x7a\x42\x1c\xc9\x81\x70\xcf\x3b\x20\x1f\x45\x02\xa6"
+  "\x2b\x61\xbc\xca\xf8\xfc\x01\x97\x60\x9c\x82\xf9\xfc\xdb\x5b\xe0"
+  "\x08\x65\xff\xaf\x61\x9c\xa0\xfc\x1f\xef\xc2\x11\xca\xaf\x3f\xcd"
+  "\x97\x84\x06\x77\x16\x28\xda\x8c\x84\x33\x52\xcc\xd8\x16\x5c\xe4"
+  "\x67\xe5\xf9\x18\x40\x4f\xfe\xc3\x58\x95\x9f\x55\x4f\xf8\x92\x08"
+  "\x58\x13\xa2\x08\xff\x51\x80\x8a\x0f\xb8\x18\x4e\xfb\x9d\x0f\x7a"
+  "\xf4\xb5\x50\x25\x7b\xf6\xed\x7c\x8b\x42\x39\x1c\x73\x2f\xf0\x41"
+  "\x83\xdc\x5d\x7f\x82\x5e\x1f\x11\x5b\xc4\xae\xab\x88\x74\xfd\x37"
+  "\x78\x7d\xb2\x1f\xc6\x30\x1f\x45\x8a\x8c\x0a\x65\x16\xd6\x31\x2a"
+  "\x14\xa5\x7c\xbe\x17\x31\x98\xdb\x84\x77\xbc\x0d\xeb\x65\xe3\x7d"
+  "\xee\xec\x3b\x5c\xf1\x98\xe5\x2b\x01\xf3\x50\xdf\x85\xb5\x4f\xa9"
+  "\xc9\x09\xad\x6a\x51\x78\x4f\xdc\x80\xf2\x50\x60\x4c\x2c\xc5\x42"
+  "\x85\x97\xff\xb5\x35\x23\x27\x6a\x32\xfd\xa0\x3d\xef\x49\xb9\x16"
+  "\xde\xac\xcf\x79\x9a\x9c\x61\xe7\x97\xd3\xbd\x41\xec\xff\x34\xea"
+  "\xf3\xc9\xfe\x4f\xa4\xf6\x65\x68\x0b\xef\x75\xd4\x2f\x6c\x05\x7b"
+  "\x03\xb9\xa0\x98\x44\xfa\xcd\x5c\xe1\x35\xfc\x4b\xce\xa8\xf4\x4b"
+  "\x23\x03\x34\x99\xbb\xa1\x7d\xaf\x04\x99\x2e\x6a\xaf\x4b\xaf\x3d"
+  "\xb5\x0b\xea\x7e\x80\x76\xa3\x02\xaf\x14\x7b\xee\x61\x78\x87\xff"
+  "\xc4\x75\x4f\x49\xa2\x70\x2d\xa6\xb2\xad\xc2\xab\x03\x63\xca\x5a"
+  "\x03\x1f\xd3\x59\x8b\xda\x54\xb6\xe2\x98\x58\x7e\x6d\x4c\xe2\x50"
+  "\xab\x82\x50\xdf\x7c\x85\x77\xc8\x23\x16\x94\x25\x0f\x60\xdd\xa3"
+  "\xdc\xc0\xda\xa6\x87\x33\x88\x52\x9f\x7a\x0c\xca\xde\x77\xf2\x05"
+  "\xdf\x36\x1b\x3a\x9a\x88\x3e\x15\xdb\xf2\x56\xf3\x05\xe7\x1b\xb8"
+  "\x81\x2d\x96\x72\x94\xc9\x33\xd0\xa6\xf6\x35\xde\xb7\x01\xc6\xd9"
+  "\x1b\xfa\x62\xb1\xe7\xc5\x86\xb1\x5c\x09\x63\x87\xf2\x32\xc6\xb9"
+  "\x98\x66\xb3\x61\x7c\xb6\xe5\x46\x18\x07\xba\xbe\x2a\xbc\x68\x7e"
+  "\x77\xf6\x5c\xef\x47\xb9\x80\x91\x91\xf5\x09\xf8\x7d\x50\x85\xf1"
+  "\xae\xcc\x74\x6f\xbc\x15\x73\x05\xc2\x3a\x23\xd4\x75\xa4\xdd\x2c"
+  "\x21\x26\xc0\xac\xb9\x69\xa9\x6f\x69\xe6\xcf\xca\x4c\x7a\x32\x6c"
+  "\xc1\x68\x4d\x6a\x86\x26\x95\xe6\x78\xa7\x27\x60\x59\x9e\x9f\x32"
+  "\x2f\x4d\x83\xb9\xb6\x7b\xe6\xfa\x55\xf3\xaa\x91\x2a\x2a\x4b\x2a"
+  "\x06\x6b\xa8\x3e\x51\x11\xeb\x93\x96\xc5\x73\x9a\x11\xb7\xf1\xe7"
+  "\x15\xde\x1d\x5d\x03\xbd\xe3\x71\xad\xe5\xf2\x35\x44\x88\x2b\xec"
+  "\xbb\x2e\x80\xe0\xfe\x3d\x9f\xce\x02\x6f\x7b\xfc\x17\xa3\x62\x30"
+  "\xb3\x93\x14\x78\x5b\x80\x07\xcb\x84\xef\x64\x2c\x86\x9e\x70\x8d"
+  "\x7e\x47\x2e\x18\xa0\x36\x92\x64\x16\x17\xb2\x22\x26\x99\xae\xc1"
+  "\x8a\x01\x2c\xdf\x99\x26\xd6\x87\xdf\x14\xa0\x02\x39\x4e\x41\xbf"
+  "\xd9\x59\xef\xe3\x0d\xe4\x12\x8b\x69\x5b\xf2\x78\x1e\xc6\xe7\xb0"
+  "\xad\x0d\x23\x5c\xd0\xe3\x79\xdc\xc7\x01\x0d\xb9\x1f\x12\xe5\x76"
+  "\x98\xf3\xde\x1a\xe0\xef\x11\xe4\xbe\xdd\x39\x6d\xca\xf3\x8a\x01"
+  "\xaf\xee\xce\x69\x52\xf2\xc5\x61\x4d\x97\x43\x87\x99\x2c\x42\x4e"
+  "\x68\x83\xd5\x42\xfe\x11\x4d\x50\x67\xab\x32\x0f\x1f\xa7\x36\x0f"
+  "\x0f\x6d\xb3\x94\x44\xe7\xe9\x47\x3c\x46\xc6\x3f\xc0\x5f\xf8\x7b"
+  "\x35\x21\x1d\x8a\xc1\x81\x7f\x8f\x46\x3d\x62\xa4\x8f\x45\x35\xd2"
+  "\xd7\xbc\xf6\x71\x1a\xbb\xaf\x6b\x6d\x74\x43\x77\xd0\xfd\x89\x7b"
+  "\xa1\xce\x01\xd0\x73\x0e\xc2\x48\x61\xbc\xd5\xae\x51\xfe\x89\xdb"
+  "\xbb\x8b\x94\x35\xd5\xe3\x98\x8d\x37\x11\xe6\x0c\xe5\xa7\x01\xb6"
+  "\xbf\xef\xa8\x26\xf0\x6c\xb2\xbd\x7b\x82\xf2\x1f\x91\xce\xd7\x07"
+  "\xde\xf3\xf7\xf0\x6a\xd2\x89\x71\x8a\x41\x8f\xdc\x75\xac\x94\xf0"
+  "\x6b\xc7\x46\x6d\xcd\xb4\x28\x13\x8c\x44\x59\xd7\x54\x4a\xb2\x4e"
+  "\x93\x21\xd6\x0b\x5a\xef\x3f\xc1\xfd\x5d\x18\x57\xf4\xa0\x9a\xc6"
+  "\x17\xcc\xd1\xd3\x7c\xaf\x7e\xf5\x20\x2f\x70\x17\xb4\x03\xeb\xe3"
+  "\xf4\x04\xae\x9f\xb1\xfe\x1f\x35\xa9\x4b\x36\x11\x43\x7c\x05\xe9"
+  "\x52\x46\x91\x2f\x5e\xab\x20\x1f\x80\x4e\xf2\xc1\x79\xe2\x4b\x65"
+  "\xdf\x6b\xda\x81\xd6\x6b\x5a\x6f\xeb\x62\x2d\xc6\x7b\xe2\xf9\x0b"
+  "\xda\xc1\x28\x0b\x5b\xe7\x69\x7d\xea\x4d\x15\xe4\x91\x36\xa2\xed"
+  "\x52\x12\xbf\xae\xc5\xda\xc1\xf5\xba\x52\x68\x0b\x84\x5b\x18\x57"
+  "\x8c\x35\x87\x31\xe8\x70\x9c\x6e\x8f\x27\x71\x1d\x8a\x01\x87\x07"
+  "\x37\x92\xe1\x18\xeb\x14\xe5\x4b\x8c\x8b\xcc\x05\x8e\x8d\xb2\x05"
+  "\x3e\x8e\x39\xa3\xfc\x68\x3c\xa6\x6d\xc1\x3a\x94\xcf\x41\xf6\x50"
+  "\xe0\x3b\x73\xbc\x76\xf0\x34\x3c\xae\xb9\xfb\x0c\xca\xe8\x5c\xa7"
+  "\x1a\x73\x29\xf9\x60\x3f\x31\xaf\x71\xf6\x29\x18\xcb\x5c\xad\x37"
+  "\xd4\xf3\x85\xf3\x43\x0d\x1d\x16\x62\x7b\x28\x38\xef\x61\x1d\xcd"
+  "\x57\x1b\x58\x9e\x43\x54\x45\x39\x24\x50\xf3\x1f\x38\x76\x83\xae"
+  "\xd8\xb6\x06\xeb\xf8\x82\xa0\x6a\xb4\xbd\xb0\x73\x3e\x87\x35\xcf"
+  "\x12\xa2\x79\x8c\xfe\x9f\xad\x19\x0b\x34\x0c\x1c\x53\x41\xf5\x07"
+  "\xd4\x4f\x15\x3e\x6f\x31\x1e\xf7\x99\xd5\x35\x70\xba\x0f\x57\x50"
+  "\x1c\xca\x2d\xf1\x0e\xc6\x5c\xd6\xe7\x15\x3e\x93\xf8\xc2\x8f\xd5"
+  "\x7c\x71\x34\xe5\x45\x28\x3f\xd7\x35\x10\x64\x85\xc2\x8f\xb3\xa0"
+  "\xfd\x71\x5d\x0a\xef\x46\xf8\x35\x09\xf7\x47\xe1\x7b\xdb\x36\xf9"
+  "\xb7\xe1\x7b\xd3\xfc\x3b\xf0\x5e\xd3\x80\x66\x7c\xd0\x98\x58\x1a"
+  "\x93\xfe\x1a\x8c\xaf\x90\x9f\x14\xc7\x03\xc7\x80\xbb\xa6\x1d\x4c"
+  "\xdf\xf5\x9a\xd6\x17\xc6\x17\xe3\x1a\xfb\xe5\x4c\x87\x7b\xd6\x8e"
+  "\x99\x09\xd7\x86\x76\x05\x8e\x29\xc5\x3c\x58\x06\x9d\x89\xd8\x4a"
+  "\xc6\x24\x62\xdc\xbe\x75\x99\x30\xe7\x86\x8f\x89\xe5\x4b\xc6\xa4"
+  "\x08\x73\x8b\x60\x3f\xb9\xc2\x8f\x6b\xba\x70\x1f\x1d\xf4\x0d\xfa"
+  "\xd7\x08\xbf\x26\xa3\xe2\xb6\xea\xae\x30\x7f\x98\x77\xb7\x95\x42"
+  "\x5f\x83\xf9\x82\x87\xcd\xf8\x3f\x5c\x0b\x86\x3e\x6f\xc5\x71\xc0"
+  "\xf1\x10\xc6\xe2\x23\x69\x2c\x5e\x0f\x87\x7a\xc5\x5c\x41\x61\x8d"
+  "\x51\xe1\x93\xc6\x17\x3c\xb0\xc3\xa1\x5e\x9d\x54\xef\xcd\x46\x56"
+  "\x6f\x5d\x06\xab\x17\x31\x1a\xe8\x30\x8b\x8d\xf7\x20\xff\x9e\xe3"
+  "\x3d\x68\x90\x74\x6f\x4c\x16\xbb\x77\x99\x0f\xbb\xf7\x3e\xbc\xf7"
+  "\x29\x79\x9f\x06\x8d\x91\xea\x3f\x57\xc9\xea\xe7\x54\xb1\xfa\x77"
+  "\x5a\x1c\xea\x4d\x97\xea\x4d\x1e\xc7\xea\xbd\x13\xcb\xea\x85\xc6"
+  "\xc3\xf5\x0d\x2e\xfa\x52\x22\xdd\x93\xaa\x67\xf7\x6c\x4a\x61\xf7"
+  "\xfc\xb2\x0d\xae\xd7\x39\xf5\x65\x9f\x54\x3f\x45\x78\xef\x72\x2b"
+  "\xab\x3f\xa6\xd8\xa1\xde\x39\x56\x0f\xaf\x7f\x02\xf5\x7c\x92\xbb"
+  "\x06\x66\x6c\x62\xf5\xa2\x23\x90\x1f\x01\xf7\x86\x70\x05\xea\xb8"
+  "\xae\x81\xc3\xa3\xa0\x9d\x04\xa0\x8d\x1a\x8f\x40\x3b\x35\x57\x34"
+  "\x12\xc6\x63\x20\xc6\x52\x31\x21\xe6\xc2\x9a\xb0\x03\x70\xd7\xe6"
+  "\xd2\xce\x55\x30\x78\xa2\xdd\xce\xc6\x81\x6c\x50\x12\xe2\x32\x9e"
+  "\x25\xcd\x7f\x8c\xf2\xc1\xda\x90\xbc\x22\x8e\xe5\x51\x07\x1e\x05"
+  "\xd9\x66\xf0\x02\x58\x0b\xf3\x68\xfc\xe2\xe2\x08\xc2\x85\x02\xc6"
+  "\x9e\x23\x5e\x86\xac\x36\x52\xc9\xb5\x29\x8b\xba\x89\x77\x3d\xac"
+  "\x33\x58\xbf\x12\xd6\x54\xcd\x5c\x2f\x58\x5f\x07\xaf\x2c\xba\x2a"
+  "\xb4\x57\x11\xab\xca\x9d\xc3\x72\x47\xa3\x5c\x85\xd8\x0c\xf3\xd1"
+  "\x97\xe6\x34\x9b\x8b\x72\xc5\xe0\x3d\xf0\xbf\x0f\xd6\xed\x1a\xa5"
+  "\x2a\xea\xfa\x43\xac\xaa\x3b\x68\x54\x62\xf7\xc7\xc3\x74\xd7\x82"
+  "\x22\xc8\xb5\xb5\x8f\xe5\x59\xff\x10\x93\x67\x1d\x15\xa0\xb2\x05"
+  "\x8d\x32\xc2\xb3\x01\xb7\x4b\x95\xdb\xb8\x4a\xe5\xb6\x1c\xbd\x12"
+  "\xdb\xdd\x9d\x53\xa1\xdc\x95\xd3\xa0\xdc\xc5\x55\x29\x77\xe7\x14"
+  "\xc1\x71\x33\xe6\xb7\x02\x59\xee\x76\xff\x5d\x39\x35\xb0\x6e\xdc"
+  "\x0e\x74\x1e\x1c\x29\xda\x29\xf9\xa7\xad\xa4\x7e\xb3\x95\xec\x4b"
+  "\xbb\x42\x4c\xfe\x23\x55\xf0\x0b\x34\x0d\x1f\xb3\xdc\x34\x3c\x9a"
+  "\xbe\x27\x1f\xf4\x0b\xfa\x8e\xb8\x0f\x75\x17\xc7\xfa\x2c\x8c\x07"
+  "\xb6\xb9\xa8\x9c\x43\x1f\x11\x21\xb6\xb3\xc2\x37\xa2\x47\x6c\x67"
+  "\x25\xcb\xad\x66\x8f\xef\xfc\x63\xc4\x76\x16\x6c\x04\x34\xb6\x33"
+  "\xe8\x7b\x54\xef\x83\xf5\x8b\xe6\x63\xb4\x82\x7c\x56\xf2\xa8\x11"
+  "\xf5\x3b\x94\xc7\x3a\x0b\x7c\x13\x45\xfd\x0c\x65\x0c\xdb\xea\x91"
+  "\x1a\xf8\x81\x3c\xea\x0b\x73\x74\x7b\x83\x78\x9e\x5f\x73\x56\x83"
+  "\xf6\x72\x1b\x9f\xfc\xcb\x4e\xdc\x5b\xc9\x27\xff\xca\x56\x12\x6a"
+  "\xb2\x95\x44\x27\xc2\xb9\x71\xf0\x7b\xd2\xb6\xfa\x6c\x28\xfc\xb4"
+  "\xf0\x1b\x0d\xbf\x70\xf8\x45\xc0\x2f\x12\x7e\x51\xf0\x8b\x86\xdf"
+  "\x04\xf8\x4d\x84\x5f\x2c\xfc\xe2\x78\xff\xb3\xe3\x30\x36\x25\xb4"
+  "\x9d\x08\x74\x57\x8b\xed\x4a\xe3\xeb\x7b\x1c\xde\x37\x0a\xe5\x1f"
+  "\xc0\xab\x08\x9e\xe1\x95\x9a\xff\xc8\x5f\x8d\xb8\xcb\x87\x0d\x33"
+  "\x99\x42\x62\x89\x29\x24\x26\xd9\xe4\xff\x4a\x0d\xfc\x1a\xe0\xd7"
+  "\x64\x2a\x19\x53\x01\xf4\x4b\x36\x0d\x1f\x1b\xde\x59\x30\x04\xe6"
+  "\x4c\x20\xb5\x45\xc0\xff\x13\xe1\xff\x71\xc2\xff\xf1\x46\x85\x8a"
+  "\xca\x0f\x50\x0f\x64\xbf\x21\xc9\x46\x45\x00\xad\x77\x39\x68\x4c"
+  "\xa5\xb0\x27\x33\x0f\xce\x83\xfe\x3f\x58\xc5\xea\x3d\xa6\x73\x9c"
+  "\x2f\x73\xde\xd0\x4d\x9b\x33\x3d\x63\xda\xfc\x94\x59\x6f\x24\xcd"
+  "\x1f\xab\x09\x9b\xa9\xd1\xce\x4a\x7d\x6b\xda\x5b\x0b\x92\x16\x24"
+  "\x51\xb1\x09\x4e\x3d\x20\xf7\x37\xb3\x62\x8e\x00\x90\xef\x87\xb6"
+  "\xf2\x3c\xae\x57\x13\xcd\xc0\x63\x23\x62\x55\x3b\xcf\x9b\x94\x36"
+  "\x90\x5b\x7c\x5b\xf3\x60\xde\x45\x90\x9d\xe7\x2d\x4a\xdf\x56\x0d"
+  "\xe1\x81\xd7\xf1\x9a\xa1\xb5\x41\x90\x63\xbe\x26\xb5\x28\xc7\x40"
+  "\x9d\x6d\x73\x2d\xca\x17\xf0\xfe\x8f\x03\x54\xdb\xe1\x7f\x7e\xed"
+  "\xe3\x79\x78\x1f\x0f\xb2\x0d\x3d\x82\x6c\xc3\xca\xa3\x12\x77\xd1"
+  "\xe3\x63\x79\xbb\x68\xbd\x51\xc6\xdd\x78\xbc\x9a\xcd\xd7\x42\xbb"
+  "\x68\x1b\xe3\x3f\x56\x15\xd1\x3a\x30\xd7\x68\x1d\x98\x67\x2d\x0a"
+  "\xbf\x40\xac\x47\x75\x05\xe8\xe3\x76\xe8\x47\xee\x02\xe2\x2d\xce"
+  "\x5d\xd4\x07\xec\xf3\x37\x1d\xe5\xbc\xa1\xd9\x38\x7f\xb1\x3f\x3c"
+  "\xcc\xd7\xad\x70\xef\xb6\xb9\x4c\x7f\x02\x9d\xc9\x0b\x75\x25\xc4"
+  "\x08\xc4\x06\x43\x56\x03\xbd\xbf\x92\x6b\x00\x5d\xcb\x0b\xef\xfd"
+  "\x12\xaf\x95\x81\x6c\x56\x46\x65\xf1\xa1\x76\xf9\x77\x45\x10\x8b"
+  "\xcd\xe6\x9b\x08\x7c\x31\x83\xdc\x77\x5e\x31\xe4\x10\x8e\x1f\x8e"
+  "\x17\x7e\x2b\xe5\x0b\x86\x14\x61\x5c\x84\x0d\x01\xc4\xc7\x3a\x3c"
+  "\x26\x9e\xda\x56\x0a\xfc\x22\x45\x99\xd2\x1c\x18\x23\x8b\xab\xca"
+  "\xe8\xa5\x49\x9a\x3b\x7d\x46\x4a\xd2\x4c\xfa\x79\x6d\xfa\xfc\xf9"
+  "\x0b\xe6\x24\x69\x92\xa6\xbf\x91\xac\xa1\x97\x35\x0b\xe6\x43\x95"
+  "\x59\x69\xf3\x35\xf3\x16\xce\xd5\xcc\x99\x3f\x0b\xa5\xe3\xa4\xd4"
+  "\xd4\x05\xba\xb4\xc1\x84\xdd\xa9\x99\xb3\x20\x25\x6d\x96\x0e\xfe"
+  "\x99\x9f\x34\x77\xa6\x86\x52\x7d\x3e\x34\x95\x92\xa2\x11\x9e\x30"
+  "\x3f\x79\x7a\x2a\x32\xc2\xdc\xdf\x42\x25\x87\xfb\xe5\xb2\xb3\x2f"
+  "\xc6\xbe\x43\x9f\xab\xf3\x0a\xd5\xba\x6a\x6f\x18\xeb\xe2\x98\x78"
+  "\xf4\x55\x80\x72\x29\xd5\xa7\x0a\xfc\x26\xa0\x4d\xf9\x3d\x78\xc7"
+  "\xcb\xc0\xf3\x9d\x05\xaa\x40\xf1\xdd\xa8\x8d\x19\xe3\x6e\x62\x4c"
+  "\x57\x85\xea\x6d\xba\x37\x18\xf8\x9f\xfa\xb2\x14\xf8\xbd\xce\xc6"
+  "\x42\x15\xed\x68\xc3\xa2\x36\x53\x85\x6a\x0a\xfa\xcc\xc1\x1c\x28"
+  "\x45\x99\x40\xc8\x93\xa0\x80\x7b\xde\xc1\x7b\xb8\x92\xe8\x64\xb8"
+  "\x2f\x4b\x92\xcb\x55\x71\x58\x9f\xd6\x2b\xf0\xfb\x98\x1f\x3e\xa6"
+  "\x02\xce\x45\x62\xbf\xdc\xac\x21\x9a\xab\xd0\xee\xc1\x4a\x42\x7e"
+  "\x16\x48\xb4\x57\xd7\x8c\x9a\xd0\x19\x30\x52\xdb\x9d\x4f\x6e\xeb"
+  "\x86\x79\x6c\x51\x92\xfb\xba\x80\x2f\x16\x3d\x4a\xbc\xb2\x27\x11"
+  "\x65\xe5\xec\x4a\x8c\x1b\x4c\x6a\x27\x94\x12\x03\x20\x92\xc1\xb2"
+  "\x85\xd4\xea\x5b\x48\x9d\xf5\x53\x96\x7b\x23\x13\xe5\x6a\x7f\x1b"
+  "\xc6\xaf\xcb\xcd\xe6\x6d\xdb\xff\x6a\x1a\xb0\xad\xbd\x12\x73\x66"
+  "\xdc\x67\xb0\x9e\xd4\x1b\xb2\x36\x11\x43\x86\x41\x8f\xb1\x43\x60"
+  "\xdc\xce\xee\x82\x6b\x83\x6a\xe1\xbe\x17\xc8\x6d\x50\x3e\x8e\xcf"
+  "\x58\xbe\x96\x6f\x7a\x27\x88\x6f\x7e\x67\x2d\x6f\x04\x9e\x6a\x05"
+  "\x9e\x6a\x5b\x19\xc4\x77\xa0\x2f\x00\xfa\x3c\x20\x9f\xea\xd2\x89"
+  "\xba\x5d\xe1\x9f\x46\x75\xfb\x68\x5a\xbe\x13\xca\x74\xcf\xbc\x21"
+  "\x63\x2d\x96\xef\x82\x72\x31\x2b\x97\x63\xf9\x6e\x28\x6f\x62\xe5"
+  "\xbf\x63\x39\x18\xca\x3b\x58\xb9\x9e\xd0\x18\x18\x0a\xff\x6a\x56"
+  "\x3e\x82\x65\x18\x7b\xff\x46\x7d\x3a\xf6\xf7\x04\xd0\xcc\xff\x54"
+  "\xee\x71\xd0\xcf\x32\xce\xd0\xf9\xb0\x3b\x27\x19\x6d\x0f\x30\x1f"
+  "\xfc\x93\x6e\x6f\x46\xdd\x2e\xc0\x7b\x60\x38\x1e\xfd\x7d\xfc\x2c"
+  "\xe4\x36\x90\x95\x6e\x87\xf7\x39\x8c\x63\xe7\xd2\xd6\xb2\x2d\xf0"
+  "\x57\x31\x56\x5e\xcf\x7f\x14\x00\x7c\x10\x91\xc7\x7f\x34\x2c\x96"
+  "\xa7\xeb\x58\x48\x54\x65\xa6\x85\xc6\x6e\x06\xf9\x14\xe6\x50\x00"
+  "\x8d\x23\x6f\x02\x79\xcf\x4d\x2c\x57\x15\x5f\x12\x96\xc7\x6f\xf2"
+  "\xb7\x4c\xd2\x5a\xd1\xb7\x19\x64\xdc\x80\xc3\xfb\x92\x51\x2e\x18"
+  "\x7b\x99\xdb\x34\x2c\x96\xcb\x8d\x27\x7c\x68\x80\xcf\xa4\x64\x5e"
+  "\x0f\x6b\x94\x82\xd9\xaa\xf9\x93\xf0\xfc\x93\xf4\xb9\x61\x01\x3e"
+  "\xdc\xc2\x64\xcc\xa9\x44\xf1\x25\x07\xd7\xeb\x74\xc0\x93\xc5\xf1"
+  "\x7e\xb6\x92\xb1\xa6\x7d\xc9\xa7\x3d\xcb\xcf\xa3\x08\x70\x1f\x57"
+  "\x1c\xfa\x84\xb1\x4c\xad\xf0\x1c\x2b\xbc\x2b\xca\x06\xdb\xb8\x1a"
+  "\x25\xc8\x28\x3e\x5b\x67\x34\x0d\xe0\x17\xc6\xfb\xc1\x3b\x3d\x6a"
+  "\xd0\x5e\x21\xf5\xdd\x38\x57\x86\x15\xef\xcb\x20\x64\x7c\x86\x55"
+  "\xef\x67\xa2\x31\xa7\x55\xba\xd9\xe4\x5e\x7e\x78\x58\x5e\xbb\x62"
+  "\x58\xeb\x0b\x59\xf0\x0e\xf0\xee\xbb\x5a\x9a\xbc\x39\x78\x8f\x47"
+  "\xd8\xb8\xe1\x7d\x35\xb0\xfe\x58\x44\xb9\xde\xb3\xfe\x0f\xa3\x7c"
+  "\xc3\xcd\x8f\x27\xb8\x67\x79\x3b\xc8\x23\xdc\xb5\x78\x3f\x0e\xd6"
+  "\x1f\xbc\xb6\x4f\x7b\x8e\xe0\x33\xd9\x58\x0f\x63\xb1\x77\x42\x61"
+  "\x9c\xe1\xf9\x18\xeb\x5a\x1c\x57\xa8\x5b\x63\xbb\x96\xec\x9a\xfe"
+  "\x6b\xc7\x02\xed\xfd\x4d\xfc\xea\xb3\x2a\x97\xd7\xd7\xb4\x5d\x60"
+  "\xfc\xe1\xaf\x85\x5f\x24\xff\x61\x8c\x0e\x78\x60\x02\xcd\x79\xb9"
+  "\xf6\x51\x93\x68\x23\x81\xf9\x06\x3c\x12\x98\x54\x09\xba\xb0\xeb"
+  "\xb8\x83\xd9\x91\x34\xd7\xd8\x80\x93\xbc\x9f\x0d\x73\xe8\x5e\xc1"
+  "\xb8\xe9\x91\xfb\xb4\x66\x0f\x69\x1a\xe8\x36\xc7\x1d\xb6\x0f\x3a"
+  "\xf5\x35\x0f\xdb\xb3\xb8\xe5\x91\x4d\x30\x2e\xaa\xb3\xaa\x6e\x3e"
+  "\x5a\xc1\x64\xef\xa0\x0d\x38\x56\x56\x58\x47\x32\x0f\x13\xa5\x05"
+  "\xd6\xcb\x4f\x5f\x59\xae\x1c\x0d\xeb\x8c\x0d\xd6\xfe\xfd\x0d\xd5"
+  "\x24\x66\x22\xc9\xad\x4b\xbe\x44\xc4\x1c\x62\x7c\xd0\xe3\x79\x9f"
+  "\xbc\x62\x52\xe2\x37\x23\xcc\x19\x46\xf5\xd4\xb5\x91\xfa\x3f\x1d"
+  "\xb1\xa0\xee\x56\xb9\xf5\x88\x49\x69\xbd\x1c\xaf\xa1\x71\xdb\x41"
+  "\x27\xcf\x4d\xe6\x39\xfb\x77\x24\xcc\xed\x51\x74\x77\x07\xe6\x64"
+  "\x3e\x18\xdb\x40\xf7\xf8\x1f\x8c\xaf\x26\x07\x9b\x4b\x49\x6d\xeb"
+  "\x71\xdc\xfb\xfc\xe1\xc1\xf8\x22\x94\x17\x87\x5a\x41\x26\xfc\x00"
+  "\x64\x42\x98\xaf\x83\x38\x55\x76\xa4\xf8\x2d\x09\x73\x8c\x89\xf2"
+  "\xa0\x15\xe6\x68\x99\x90\x47\xcc\x5a\x10\xb8\xa2\x4c\xf8\xae\x84"
+  "\xf9\xc5\xd6\xa7\x93\xd0\xf5\x4a\x2e\xde\xd5\x37\xa4\xa1\x6f\x51"
+  "\xff\x68\x35\xe7\x9f\x1d\x29\xe6\x19\x7b\xe1\x2d\x0d\xf9\x1b\xbc"
+  "\xfb\x3e\xad\xa7\x73\x32\x88\xfa\xbf\x58\x81\xef\xac\xc0\x73\x56"
+  "\x18\x4f\xa3\x62\x78\x3c\xd0\xcd\xa5\x0e\x22\xd2\xe0\x5a\xae\x48"
+  "\x03\xf5\x43\x94\x06\xa0\xbb\x2c\x7e\x55\xa0\xc1\x31\xa0\x41\x2b"
+  "\xd0\x20\x9f\xe4\x1d\x88\xab\x25\x31\xb1\x40\x83\x8e\x4b\x18\xf3"
+  "\x9f\xe5\x71\x4b\x63\x63\x4f\x69\x71\xcc\xa4\xac\x37\x33\x1a\x6c"
+  "\x79\x8d\xd1\x60\xdb\x6b\x26\x90\x63\xfc\x13\x3f\x81\xb2\x6d\x61"
+  "\xbc\x06\xf3\x2e\xf1\xf9\x89\x98\x73\x9a\xd1\xe2\x1a\xd0\xe2\x1a"
+  "\xa3\x45\xce\x5b\x40\x8b\xc6\x26\x1a\x87\xea\x60\x73\x2d\xa9\x4d"
+  "\xac\x20\x75\x80\x4b\x40\x8b\xe9\x48\x17\xd4\xab\x6d\x8b\xb5\x01"
+  "\xa0\x47\x07\x96\x65\x12\xb5\x48\x0f\xd0\xdb\x07\xaf\xcc\x24\xe8"
+  "\xd3\x1b\x0e\x73\x53\xa4\x47\x20\xa5\xc7\x39\x81\x1e\xdd\xe8\x17"
+  "\x07\xf4\xe8\x06\x7a\x74\x03\x3d\xf2\x19\x3d\x10\xe7\x5f\x30\xfb"
+  "\xf1\xdc\xbf\xb4\x18\xa7\xa2\x27\x3d\x16\x0b\xf4\x38\x76\x3d\xf4"
+  "\xb8\xc3\xd2\x93\x1e\x41\xcd\x7d\xd1\x43\x9a\x13\x77\x1e\x42\x7a"
+  "\x5c\xab\x10\xe6\xc4\x28\x9c\x13\x79\xca\x9f\xc1\x5a\x84\x63\xba"
+  "\xbf\x61\x27\x9d\x13\xf0\xae\x30\x0f\x2c\xca\xda\x56\xa0\xcb\x4c"
+  "\x21\xb7\x98\x40\x17\x46\x8f\xc7\xf3\x36\x1f\x61\xe3\xaf\x79\x1e"
+  "\xd7\x0c\x9c\x1b\x48\x1f\xa0\x13\xcc\x1f\x57\x39\xf8\x1c\xbf\xb7"
+  "\x42\x9b\x1c\xce\x13\x9c\x23\x38\x1f\xea\x92\x8f\xd3\x9c\xe6\x07"
+  "\x63\x6b\x08\x7e\x77\x3d\x18\xbf\x13\x68\x55\x4a\x6c\x0b\x81\x36"
+  "\xe9\xb8\x8f\x83\x84\x60\x2e\xbe\x83\xf1\xcb\x51\x5e\x50\x01\xcf"
+  "\x0f\xb2\x01\x9d\x6c\x9d\xea\xc1\x2b\x40\x87\xc2\xef\xb1\x8e\xdf"
+  "\x61\x31\xef\x30\x3f\x30\x70\x05\x9c\xf7\xb6\x02\x8d\x60\xee\xc8"
+  "\xe6\x8c\x3d\x1f\xf1\x77\x5a\xb2\xa1\x85\xf8\x0c\x99\xc5\x68\x64"
+  "\x73\x98\x33\x93\x66\xe1\x9c\xc9\x03\x1a\x1d\xf6\x90\x46\x77\xd2"
+  "\x18\x37\x7c\x10\x60\xb5\xff\x59\x15\x1f\x86\x34\x52\xa7\xb8\xa3"
+  "\x91\x6d\x93\xbf\xd6\xa6\x1a\xe9\x8b\xb9\x07\xb8\x79\x71\x0a\x0e"
+  "\xf4\xa5\x6e\xd0\x4b\x0f\x9a\xac\x24\x6b\x0a\x51\x66\x1e\x27\x03"
+  "\x0d\x71\x5f\x13\x83\xb1\x8a\xc6\x0d\x47\x7b\x2f\xe6\xf3\x30\x58"
+  "\xab\x00\xaf\xa2\x8d\x58\xde\x40\xcb\x26\xb2\x78\x0a\xf1\xa2\x39"
+  "\x3a\xe3\x2b\xc8\x0a\xe0\xcf\xad\xaf\x55\x28\xb9\xe2\xb0\x26\x5e"
+  "\x85\x79\x88\x88\xbe\x5e\x67\xc5\x78\x6c\xbe\x75\xc9\xb5\x18\xc3"
+  "\xf2\x64\x6e\x06\x7f\xaa\xde\x0c\x6d\x9a\xf8\x6e\x1b\xac\x19\xe5"
+  "\xf9\x7c\x15\xe6\x66\x78\x04\xd7\x08\x8c\x31\xa7\xb8\x6b\x2b\xca"
+  "\x22\x68\xf7\xd2\xe7\xac\x07\xd9\xeb\xae\xcf\xf0\xdd\xe0\x9c\xa2"
+  "\x6e\xb6\x19\xae\xdf\x1b\x82\xfd\x62\x36\x68\x76\x7c\x04\x63\x7f"
+  "\x07\x8d\x1f\xf9\x65\x8e\xc9\xbb\x08\xf4\x5d\x90\xd1\xb0\x1d\x1b"
+  "\xcf\x74\xc1\x78\x43\xa3\x85\xda\x1f\x4d\xb9\xc9\x03\x8b\x32\xd1"
+  "\xf7\x0a\xf3\x3c\xe0\x9a\x7d\xcf\x21\xf4\xd7\x00\x9e\x9d\xc0\x07"
+  "\x3d\x6a\xaa\x9c\x61\x52\x4a\xeb\xf2\xdd\xb8\x9e\x4d\x18\xaf\xe5"
+  "\x73\x31\x1f\xc6\x2e\x78\x2f\xd4\x83\x3e\x6d\xb1\x50\x4c\xf9\xd3"
+  "\x8c\xe5\x4a\xb4\x8f\x58\x00\x1f\x6a\x8f\xfc\x99\xe6\x4d\x3d\xa3"
+  "\x08\x1e\x73\x20\xde\x4a\xf0\xf9\x93\x1f\xc0\x6f\x0c\x77\xa7\x74"
+  "\x29\x37\x6e\xee\x1a\x18\xd8\x96\xdb\x2a\xe5\x8c\x74\xcc\x0d\x89"
+  "\x38\xb3\x75\x06\xb4\x89\x38\xd3\x92\xa7\x64\xd8\x12\x85\x36\x3a"
+  "\x1f\x67\x6c\xa9\xeb\x38\x47\x72\x80\x8f\xeb\x92\x2b\x68\xce\x92"
+  "\xa1\x80\xef\xdc\x62\xc0\x93\x6b\xa0\xef\x03\x9e\x20\x0e\x94\x03"
+  "\x7e\x70\x8b\x41\xcf\xef\x06\x3d\x5f\xc0\x11\x94\xbd\xf0\x38\x05"
+  "\x78\xd4\xaf\x06\xce\x01\x9d\x38\xc0\x75\xc0\x13\xed\x07\x99\x24"
+  "\xf4\x03\xe0\xd1\x0d\x88\x23\x20\x17\xbf\xa0\x03\x1c\x59\x08\x38"
+  "\x92\x4e\x73\xf7\xaa\xcb\x95\x0c\x3f\xfe\xda\xb2\x5c\x59\x24\xe6"
+  "\xee\xa6\xe3\x1b\x5c\x57\x8f\xfc\x91\x98\x87\x7d\x55\xda\x70\x7d"
+  "\x5a\x1c\xef\x55\x6f\x06\x1e\x59\x1b\xdd\x80\xe7\xe8\xbc\x5d\x98"
+  "\x3c\x98\x63\xbc\x16\x85\x63\xb2\xf1\x3c\x09\xa7\xf9\x2d\x2f\xa8"
+  "\x07\xaf\x9a\x4b\x46\x97\x9f\x27\xa1\xe5\x73\x89\x16\xe6\xab\xb2"
+  "\x1c\xfa\x30\xf5\x2d\x15\xa1\xb9\x41\x06\x06\x9a\xe0\xbc\xcb\xdc"
+  "\x20\x20\x57\xab\xcb\x71\xce\xcc\xd3\xda\xfb\x64\x2d\x8a\x6f\xb0"
+  "\xc1\xd8\xd1\xf8\x6e\x8a\x7b\xc2\x98\x3f\xf5\xd0\x44\x26\xe7\xdf"
+  "\x23\xc4\x19\x1a\x36\x13\x74\x95\xdb\xda\x15\xf7\x0c\xe1\xd7\xdc"
+  "\x1d\xaf\xcb\x24\x8a\x76\xf1\x1a\xc8\x9e\x1c\xd0\xea\xe1\x3c\x92"
+  "\xc7\xf9\x2f\xd5\x1a\x32\xce\x61\xac\x7d\x0f\xe7\xe1\x3d\x74\x5f"
+  "\x9a\xad\x28\xbe\x91\xfa\x01\xad\x89\x6f\xde\xd8\x4e\xc2\xf9\xdf"
+  "\x01\x3d\x66\xc3\xbb\xb6\x93\xd0\xb2\x76\x78\xd7\x85\xec\x5d\xc5"
+  "\x5c\xe5\x5c\xfe\xc6\x4a\xb8\xd6\x6b\x5e\x2d\xd3\xef\x30\xaf\xd6"
+  "\xed\xe1\x80\x61\xc3\xf8\x11\xe8\x63\x4c\xe3\xef\x74\x1a\xac\xc7"
+  "\x09\x3e\x17\x6d\x43\x86\x4b\xc8\xd3\xf7\x2a\x90\x97\xb9\x8a\x18"
+  "\xdd\xb4\x66\xe0\xed\xce\x64\xc2\xc3\xff\xbb\x5a\x4c\x18\xef\x86"
+  "\xca\x7c\x46\xc5\xdd\xe1\x28\xa7\xed\x86\x73\xc8\xfb\x0e\x3c\x1f"
+  "\x8e\x3c\x8f\xd7\x29\xdf\xc3\x7d\x86\xe6\xd3\x04\xdb\x73\x6c\x07"
+  "\xe9\x2f\xb6\x05\xcf\x3b\x8d\x6d\x21\x2f\xa0\x4d\x07\xe7\x1a\xa3"
+  "\x7d\x15\xfa\x93\xab\xf9\xa0\xfb\x13\x59\xd9\x84\x39\x63\x54\xc8"
+  "\x03\x94\x57\x00\xbf\x31\xbe\x32\xcf\xc7\x7b\x01\x9f\x61\x3f\x07"
+  "\x03\xbd\xc3\x45\xbe\x80\x73\x81\xce\xbc\x31\x74\x89\x0a\x75\x9a"
+  "\x40\xfc\xbf\xbf\xfc\xe1\x19\xfd\xee\x6d\x75\xeb\xeb\x16\x0a\xf2"
+  "\x2d\xe0\x25\xe2\xa6\xed\xb2\x03\x66\x76\x30\xcc\x44\x4c\x12\x71"
+  "\x93\x62\x13\xcd\x97\x50\x85\xbe\xa8\xc9\xb4\x8f\x1e\xe2\x66\x5d"
+  "\x87\x84\x9b\x2f\xe8\x1c\x70\xb3\x83\xef\xe6\xc2\x5c\xe1\xe6\x7d"
+  "\xa7\xe5\xb8\x79\xdf\x59\x39\x6e\x8e\x9c\xe4\x8c\x9b\x3d\x31\x53"
+  "\xf3\x80\x2b\xbc\x04\x3d\xe6\xbe\x76\xc5\x08\xab\x7b\xac\xd4\xc4"
+  "\x79\x8e\x95\x21\x49\x72\xac\xd4\x94\xfe\xff\x8b\x95\x21\x5d\x32"
+  "\xac\x54\xf5\x13\x2b\xdb\x29\x56\x06\xf2\xff\x82\x39\x21\xe0\x47"
+  "\xf9\x6c\x37\x58\x39\xbb\x8f\xb9\xf0\x3b\x77\x58\x39\xe2\x45\x39"
+  "\x56\x8e\x58\x26\xc7\xca\x11\x63\x24\xac\x14\xae\xdd\x10\xac\x1c"
+  "\x11\x7b\x6b\xb0\x72\x44\x2c\xc5\xca\xf3\x88\x95\x23\x1f\xea\x1b"
+  "\x2b\x35\x09\xae\xb1\x12\xce\x53\xac\xd4\x24\x48\x58\x79\xbc\x0f"
+  "\xac\x0c\xf5\xf7\x00\x2b\x03\x29\x56\xaa\xdc\x60\xe5\x6c\x18\x2b"
+  "\x81\x2f\x28\xef\x39\xf1\x86\x80\x95\x6a\x3b\x56\xf6\x83\x3f\x3c"
+  "\xa3\x5f\xa8\xaa\x37\xac\xe4\x8a\x98\x7c\x89\x58\xc9\x07\x08\x58"
+  "\x99\x62\x25\x99\x47\x01\x23\x1b\xdb\x69\x5e\x18\xea\xc3\x0b\xbf"
+  "\xac\x57\x11\x8b\x1e\x27\xdb\x60\xbc\x0c\xc6\x4a\x8a\x4d\xd4\x17"
+  "\x75\x22\x62\x55\x25\xd4\x2d\xb5\xcb\x9d\x14\x3b\x8f\x0a\xd8\x99"
+  "\x20\x60\xe7\xd4\x1f\x80\x9d\xaf\x21\x2d\xc3\x42\xba\x94\x22\x76"
+  "\xae\x01\xec\x0c\xa3\xf2\x03\x7e\xcf\x64\xd8\xa9\xdd\x20\xf6\x0b"
+  "\x6d\x9a\x86\xb4\xf5\x84\xf5\xeb\x52\x4f\x1c\x7d\x9e\xb6\xb7\x40"
+  "\x3f\xbb\x83\xd8\xb1\x34\x41\xc2\x52\x68\x6b\x92\x7b\x1c\x0d\x2b"
+  "\xb3\xe3\x68\x3e\xe0\xe8\x09\x07\x1c\x05\xbd\xe9\x4f\x88\x79\x80"
+  "\xa3\x9d\x14\x47\xff\x2a\xe0\xe8\xa8\xad\x07\x12\x00\x47\x9f\x17"
+  "\x71\x34\xcc\x68\xc9\xdf\xb8\xd9\x52\xd0\x37\x8e\x76\x52\x1c\xd5"
+  "\xdd\x7c\x1c\xad\x76\xc2\x51\xd0\x5d\x31\x5f\xb9\x4b\x1c\x15\xf9"
+  "\x91\xe2\x68\x9e\x84\xa3\x74\x5c\xef\x7f\xae\x3e\x11\xc6\x3d\x51"
+  "\x47\x75\x37\x3b\x8e\xea\x2a\x19\x8e\xc2\x39\x6a\x3f\x99\x0f\x38"
+  "\x0a\xfc\x97\x5b\x87\x71\xfc\x48\x14\xf4\x51\x85\xf8\xba\x11\xe6"
+  "\x0c\x8e\x91\x1d\x4f\x67\xc3\x9c\x41\x8c\xb9\x0c\x73\x06\x70\x74"
+  "\xea\x15\x15\xa1\xf3\xa5\x00\xe6\x4b\xbb\x9b\xbc\x74\xa2\xbf\xac"
+  "\x5b\x3c\xbd\xff\x43\x39\x9e\xde\xdf\x28\xc7\xd3\xfb\xdf\x91\xf0"
+  "\x54\xb8\x86\x78\x0a\x34\x83\xf1\xd1\x22\xa6\x5e\x1f\x9e\xde\x5f"
+  "\x61\xc7\x53\xa5\x80\xa7\xb3\xfb\xc6\x53\xfa\xdd\xcf\x0d\x9e\x3a"
+  "\x62\x83\x7b\x3c\xbd\xbf\x42\xc2\x53\x6d\xb6\x1d\x4f\x9b\xdc\xe1"
+  "\x69\xd8\x26\xd7\x78\x0a\xe7\x29\x9e\x86\x6d\xb2\xe3\x69\x93\x0b"
+  "\x3c\x7d\xde\x11\x4f\x1f\x98\xc3\xf0\xb4\x92\xe2\x28\x62\x6a\xbd"
+  "\x19\xf8\x03\xe7\x5c\x5a\x29\xc5\x54\x0e\x30\x15\x73\xf5\x62\x4e"
+  "\x2a\xf4\x81\x77\x85\xa9\x0c\x73\x8d\x04\x71\x15\xe7\x66\xee\x24"
+  "\xd0\x77\x61\x2d\x82\x31\xa1\x6b\xaf\x38\x7e\x1b\x1d\xf0\x75\xda"
+  "\x22\x15\xca\x76\x32\x5e\xe1\x44\x5e\xb9\xac\x45\x1f\x59\x19\xaf"
+  "\x78\x46\xcb\x07\x52\xdc\x61\xab\x3b\xdd\xfd\x00\xea\xee\x93\x89"
+  "\x72\xf1\x64\xc0\xd7\x78\xd4\xdd\x37\x3b\xe9\xee\x9b\x7b\xea\xee"
+  "\x87\x7b\xc7\x51\x8f\x74\xf7\x57\x90\x86\x0f\xce\x92\xe3\xe8\x83"
+  "\x73\xe4\x38\xfa\xd0\x59\xec\x17\xc3\xf1\xcd\xae\x75\x77\x3a\xcf"
+  "\x1f\xfc\xc2\xae\xbb\x37\xc9\xf1\x53\xd2\xdd\x1f\x5a\xe7\x1e\x47"
+  "\x1f\x6c\x95\xc9\xa3\x53\x05\x1c\x9d\x21\xe0\xe8\x0c\x09\x47\x0f"
+  "\x7e\x2d\xca\xa3\xa3\x15\xfb\x9b\x1c\x71\xf4\x67\x5a\x3b\x8e\x36"
+  "\xf7\xc4\x51\x11\x43\x11\x4f\xb1\x1d\xb4\x65\x6d\x01\x9c\xde\x3e"
+  "\x43\xa7\x64\xb6\xda\x44\x1c\x3b\x1f\x67\x5b\x6d\x5d\xc7\x15\x92"
+  "\x93\x80\x78\x5a\x4a\xf1\xd4\x4f\x41\xa6\x03\xf6\x0d\x45\xbf\xff"
+  "\x32\xfc\x66\x9f\xce\xf2\x9c\xa1\x7d\x89\x5b\xc8\xf2\x66\x8a\x76"
+  "\x26\x78\x5f\xfa\xad\x7e\xca\x71\x01\x53\x31\x6f\x3d\xf0\xdc\x07"
+  "\x57\x01\x53\xd3\x5d\xc8\xa6\x8b\x01\x53\x33\x1d\x64\x53\x98\xfb"
+  "\x7f\x9d\xe1\x8c\xa9\xa3\x4b\xea\x91\x57\x10\x53\x65\x7a\xfc\xe6"
+  "\x9f\x80\x1e\x3f\xfa\x9c\x1c\x4b\x1f\xd2\xc8\xb1\x74\xf4\x61\x09"
+  "\x4b\x85\x6b\x37\x44\x36\x1d\xdd\x71\x6b\x64\xd3\xd1\x1d\x92\x1e"
+  "\xff\xd0\x7e\x3b\x96\x36\xba\xc3\xd2\x07\x3b\x5c\x63\x29\x9c\xa7"
+  "\x58\xfa\x60\x87\x1d\x4b\x1b\x5d\xe8\xf1\x32\x2c\x7d\x78\x2b\xc3"
+  "\xd2\xcd\x4c\x36\x6d\x12\x65\xd3\xcd\xff\x86\x7a\xfc\xc3\x5b\x3c"
+  "\xd5\xe3\x0f\x74\x30\xfc\x44\x7c\x12\x31\x54\xd2\xe3\x37\xbb\xd7"
+  "\xe3\xfb\xc0\x50\x8f\x64\x51\x8a\xa1\x8f\x6c\x95\x63\xe8\x23\x9f"
+  "\xc9\x31\xf4\xf1\x10\x67\x0c\xed\x89\x9f\x8f\x5c\x74\x85\x9d\x4c"
+  "\x8f\x7f\xac\xc1\x3d\x6e\x86\x07\x7b\x8e\x9b\x8f\x8e\x91\xe3\x66"
+  "\x78\xe2\xff\x0c\xdc\x7c\xb4\x4e\x86\x9b\xaa\x7e\xe2\xe6\x8f\xa2"
+  "\xd3\x3f\xe6\x64\xff\x7c\xcc\xc9\xfe\xf9\x98\x83\xfd\xf3\xb1\x1b"
+  "\x68\xff\x7c\xec\x16\xd9\x3f\x1f\x0b\x95\x64\xd0\xc7\x15\x7d\xe3"
+  "\x66\x78\xa8\x6b\xdc\x84\xf3\x14\x37\xc3\x43\x25\xdc\xec\x4b\x06"
+  "\x7d\xfc\xb4\x07\xb8\xf9\x13\xd7\xe9\x1f\xef\xd5\xfe\xe9\x4a\xa7"
+  "\x47\xdc\xa4\x78\xd9\xe4\xa4\xd3\x4f\x76\xd4\xe9\x37\x4b\x3a\xfd"
+  "\x04\x86\x5b\x06\x6b\x91\x5c\xa7\xbf\xe1\x38\x1a\x71\xc5\x62\xb7"
+  "\x87\xbe\x0b\x38\x1a\x41\x73\x25\x58\xec\xf6\xd0\xc8\x6c\xb1\x5f"
+  "\x4c\xa7\x5f\x43\x58\xbf\x5c\xe8\xf4\xd4\x67\xf6\x89\xe7\xec\x3a"
+  "\x7d\x93\xb3\x4e\x1f\xf9\x90\x7b\x4c\x7d\x42\xe7\x52\xa7\x47\xfd"
+  "\x9b\x62\xaa\x8e\x62\xea\xd5\xb5\x8e\x98\xfa\x1f\x2b\x29\xa6\x3e"
+  "\x2b\x62\xea\x13\x3b\x2c\x30\x37\x2d\x03\xfb\xc6\x54\x6c\x47\xc2"
+  "\xd4\xe4\x1f\x07\x53\xf5\xfd\xc7\x54\xc7\xfd\xa6\x7f\x85\x77\xb7"
+  "\x63\x2a\x1d\xe3\x9f\x3f\x50\x9f\x88\x98\x9a\xec\xa4\xdf\x6f\x76"
+  "\xad\xdf\xef\x27\x4a\x1c\x1f\x51\xbf\x47\x1a\x50\xbc\xb9\xa9\xfa"
+  "\xfd\xcf\x97\xc8\xb1\xf5\xe7\x3b\xe4\xd8\xfa\xf3\x59\x12\xb6\x0a"
+  "\xd7\x6e\x88\x7e\xff\xf3\xbc\x5b\xa3\xdf\xff\x3c\x4f\xc2\xd6\xc8"
+  "\x29\x7d\x63\xeb\x13\x19\xae\xb1\x15\xce\x53\x6c\x7d\x22\xa3\x57"
+  "\x6c\x7d\xd6\x11\x5b\xc7\x4c\x12\xb1\x55\xd2\xef\x81\x3f\x70\xfe"
+  "\xa5\x15\x5d\xbf\x7e\xff\xdc\xad\xd6\xef\xc7\xb8\x8d\x7f\xe2\x52"
+  "\xbf\x5f\x0b\x38\x0b\xba\xf8\xe2\x43\xa0\xdf\xbf\x28\xe8\xf7\xcd"
+  "\x15\x4e\xfa\x7d\x45\x0f\xfd\x3e\xeb\x45\x01\x53\x61\x4e\x51\x4c"
+  "\x9d\xb1\xf9\xfa\xf5\xfb\x97\x90\x86\x63\x9f\x93\x63\xea\xd8\x49"
+  "\x72\x4c\x7d\xf2\x38\xf6\x8b\x61\x7a\x85\x6b\xfd\x9e\xce\xf3\xb1"
+  "\xeb\x64\xfa\x3d\xf4\xaf\xa7\x7e\xff\xe4\x4a\x19\xa6\x4e\x75\xc4"
+  "\xd4\xb1\xd5\x32\x39\x15\xde\x0b\x31\xf5\x93\x13\x0c\x53\x3f\x3d"
+  "\xe1\x80\xa9\x2f\x7c\x2a\x60\xea\x2f\xae\xec\x8f\x73\xc4\xd4\x5f"
+  "\xf8\x88\x98\x4a\xf1\x72\xaa\x45\x99\x1b\xdf\xd3\xef\x84\xfa\xfb"
+  "\xa0\x2f\x10\xb4\x8d\x7b\xa4\xb0\xcd\xad\x27\x92\xfb\xf6\x37\x89"
+  "\x77\xed\x6f\x62\x48\x33\x92\xda\xd6\x22\xea\x67\x52\x86\x7e\x26"
+  "\x4b\x48\x48\x59\x37\xdb\xeb\x4f\x73\x6f\x5c\x75\xbd\xcf\x7f\xca"
+  "\xab\x12\xce\xa2\x4f\xd6\x07\xe8\x93\x75\x95\xf9\x00\x01\xbd\x7b"
+  "\xee\xeb\x17\xe5\x26\xc0\x83\x2f\x4e\x38\xe3\xec\xb8\x77\xea\x91"
+  "\x7f\x12\x92\x9d\x74\xfe\x8a\x9f\x80\xce\x3f\xee\x94\x1c\x5f\x9f"
+  "\x0c\x94\xe3\xeb\xb8\xfd\x12\xbe\x0a\xd7\x6e\x88\xec\x3a\xce\x78"
+  "\x6b\x64\xd7\x71\x46\x49\xe7\x7f\xf2\x4b\x3b\xbe\x36\x38\xe0\xeb"
+  "\x09\x47\x7c\x1d\x5b\x4b\xf1\xf5\x84\x33\xbe\xc2\x79\x8a\xaf\x63"
+  "\x6b\xed\xf8\xda\xe0\xa4\xf3\x9f\x70\xc6\xd7\x5f\x7e\x48\xf1\x15"
+  "\x78\x41\x2e\xbb\x56\xf4\xad\xf3\x37\xff\xd4\x74\xfe\x5f\x56\x78"
+  "\xa4\xf3\x23\xa6\xa6\x30\x4c\x45\xcc\x12\x71\x55\xd2\xf9\x2b\xdc"
+  "\xea\xfc\x7d\xe1\xaa\x47\xb2\x2a\xc5\xd5\x5f\x7d\x28\xc7\xd5\x5f"
+  "\x7d\x24\xc7\xd5\x67\x1e\x70\xc6\xd5\x9e\x98\xfa\xab\xd3\xae\xf0"
+  "\x94\xe9\xfc\x4f\x37\xb9\xc7\xd2\x28\x95\xe7\x58\xfa\xd4\x53\x72"
+  "\x2c\x8d\x8a\xfb\x9f\x8b\xa5\x4f\x1d\x96\x61\xa9\xaa\x9f\x58\xfa"
+  "\xa3\xd8\x01\x9e\x7e\x48\x8e\xa5\x4f\x27\xca\xb1\xf4\xe9\xe1\x12"
+  "\x96\x0a\xd7\x6e\x08\x96\x3e\x3d\xfa\xd6\x60\xe9\xd3\xa3\x25\x59"
+  "\xf5\x99\x41\x7d\x63\x69\x94\xda\x35\x96\x46\xa9\x19\x96\x46\xa9"
+  "\x25\x2c\x3d\xde\x07\x96\x3e\x73\xce\x03\x2c\x95\xdb\x01\x9c\xb1"
+  "\xf4\x96\xdb\x01\x9e\xe9\xf0\xc8\x0e\x20\x62\xe9\x8b\x3d\xed\x00"
+  "\x88\xaf\xd4\x0e\x00\xe3\x25\x62\x18\xb5\x03\x44\x33\x2c\x33\x58"
+  "\x97\xcb\xec\x00\x37\x1e\x5b\xa3\x6d\x16\xbb\x3d\x35\x1f\xb0\x75"
+  "\x3c\x8d\xab\x6d\xb1\xdb\x53\x27\xac\x13\xfb\xc5\xec\x00\xef\x12"
+  "\xd6\x2f\x17\x76\x80\xa7\xb1\xbd\xf1\x2f\xca\xec\x00\x0e\x58\x0b"
+  "\x6d\x3d\xe7\x1e\x67\xc7\x67\xc8\xec\x00\x2d\x12\xce\x5e\x45\x1f"
+  "\x75\xc0\x41\x8a\xb3\x41\x8e\x38\xfb\xec\x27\x14\x67\x9f\x16\x71"
+  "\x76\xfc\xce\x4e\x98\x9b\x9d\x9e\xe2\x2c\xee\x23\x38\x91\x78\x6b"
+  "\x70\xb6\xca\x03\x9c\x75\xb0\x0d\x7c\x01\xe3\x61\xc7\x59\x3a\xee"
+  "\xbf\x1e\x5f\x9f\x80\x38\x9b\xe8\x64\x1b\xa8\x70\x6d\x1b\xd8\x77"
+  "\x2b\x6c\x03\xbf\xde\x20\xc7\xdb\x5f\x37\xc8\xf1\xf6\xd7\x6f\x4b"
+  "\x78\x2b\x5c\xbb\x21\xb6\x81\x5f\x97\xdd\x1a\xdb\xc0\xaf\xcb\x24"
+  "\xbc\x9d\xb0\xa8\x6f\xbc\x1d\x9f\xe7\x1a\x6f\xe1\x3c\xc5\xdb\xf1"
+  "\x79\xbd\xe2\xed\xd3\x8e\x78\xfb\xdc\x2c\x11\x6f\x25\xdb\x40\x85"
+  "\x60\x1b\x58\xde\xb7\x6d\xa0\xd9\x8d\x6d\x60\xfc\xad\xb6\x0d\x3c"
+  "\x97\xec\x89\x6d\xa0\x6b\x2d\xf3\xdb\x5f\x8c\x7e\xfb\x53\x00\x7f"
+  "\x63\xbf\x86\x31\xe8\xdb\x6f\x3f\x4b\xf4\x3f\x4d\x2c\x15\x70\xb6"
+  "\xd4\xa5\x6d\xe0\x40\x9b\x7b\xdb\xc0\x81\x46\x47\xff\xd3\xe7\x93"
+  "\xe4\xdf\xad\x9e\x9f\x25\x7e\xb7\x3a\x70\x04\x71\xf6\x85\xb7\xb0"
+  "\xcc\x15\x8f\x65\xf1\xcf\x15\x2f\xe8\xb0\x9f\xae\xfc\xf8\xff\xca"
+  "\x39\x7e\xcb\x7a\x7e\x9f\xdd\x56\xd0\x80\x78\x5b\x4a\x38\x3e\x79"
+  "\x20\xc6\x08\xa7\xb6\x82\x57\x90\xf7\x5e\x08\x71\xc4\xdd\x5d\xc7"
+  "\x1c\x71\xf7\x79\x93\x88\xbb\x36\xc0\xdd\x2f\x5b\x4a\x99\xfd\xf5"
+  "\x35\xe6\x9b\xba\xe5\x35\x07\xdf\xd4\xaf\xbf\x12\x70\xf7\xff\x9c"
+  "\xdb\x6f\x84\xf7\xef\xcd\x7f\x0a\xee\xdf\x76\xac\xbf\x3e\xa8\xa5"
+  "\x2e\x7d\xa7\x04\x7c\x72\xe9\x3f\x05\x7d\x55\x6d\x10\xe6\xaa\x0d"
+  "\xe6\xe9\x06\x07\xff\xa9\xb2\x4c\x98\xcf\xc2\xbe\x92\x5e\xfd\x50"
+  "\x5f\x93\xfc\x50\xf9\xe2\x31\x29\xb8\xbe\x71\x25\x63\xc3\xbb\xf9"
+  "\x64\x2f\x3e\x70\x4c\x0a\x3e\xff\xda\x35\x58\x77\x9e\x89\xf7\x12"
+  "\xf4\xba\x58\xc0\x9e\xa1\x6c\xdc\x27\x6a\x6d\xb0\xd6\xd8\x60\xad"
+  "\xe1\x8a\xc7\xc4\x5a\x51\x36\x59\x3b\x26\xae\x0c\xf4\x3c\x6b\x3e"
+  "\xcd\xa5\x3a\xb8\x10\x74\xbd\x8d\xa8\xe7\x9d\x87\xb9\x91\xab\x55"
+  "\x62\x7f\x44\x1c\xf5\x6b\x83\xf7\x38\xdf\xbb\x2c\x67\xbd\x20\xe1"
+  "\xa8\xfe\xf9\x03\xf0\xcc\x49\xf7\xd4\x23\xef\xc6\x4b\x7b\x0a\xa8"
+  "\xcc\xec\xc6\x57\x16\xfb\xc2\x62\x24\x02\x2f\xdc\x00\x9b\x84\x63"
+  "\x7f\xe4\xb8\x3e\x69\x81\x1c\xd7\x27\x6d\x96\xe3\xfa\xa4\x29\x12"
+  "\xae\x0b\xd7\x00\xd7\x81\x6e\x54\x8e\x86\xb5\xef\x3a\xe5\xe8\x49"
+  "\x69\x22\xae\x73\x02\xae\x97\xf7\x03\xd7\x7b\x95\xa3\x1d\x70\xc9"
+  "\x3d\xae\x4f\x4a\x93\x6c\x12\x2f\xbc\xe8\xd2\x47\xf6\x98\x23\xae"
+  "\x3f\x6f\xa1\xb8\x7e\xcc\x19\xd7\xe1\x3c\xc5\xf5\xe7\x2d\x6e\xf7"
+  "\x13\x1c\x73\xfe\x9e\x16\xf3\x04\xc5\xf5\x26\xc1\x47\xb6\xc1\x83"
+  "\xfd\x04\x4d\x0c\xd3\x45\x2c\x47\x7b\xd5\xad\xb5\x49\xc4\x44\x78"
+  "\x62\x93\xa0\x58\xde\xc1\xb0\x1c\xb1\x51\xc4\xf3\xfe\xec\x27\xe8"
+  "\x0b\xcf\x45\xb9\x19\xf1\xdc\x9d\xdc\x2c\xc7\xf3\xd8\x27\xe4\x78"
+  "\x1e\x3b\x46\x8e\xe7\x71\x4f\xc8\xf1\x3c\x2e\xc2\x19\xcf\x7b\x62"
+  "\x79\xec\x3b\xae\x70\x5c\xf7\x0a\xda\x28\x5e\x6e\x75\x8f\xe1\xb1"
+  "\x3b\x3c\xc7\xf0\x17\x3f\xfb\x1f\x87\xe1\x2a\x67\x0c\x7f\xb1\x03"
+  "\x31\xc8\x56\xe0\x84\xe1\xb3\x05\x0c\x17\x70\x64\x63\xbb\x20\x0b"
+  "\x3b\x63\x78\x07\xbc\x47\x1f\xfa\xb8\xf5\x5f\xce\x18\xfe\xd2\x29"
+  "\x19\x86\xab\xfa\xc0\xf0\xd9\xcc\x0e\x22\xf3\xcb\x75\x63\x0b\x81"
+  "\xf7\x30\x6d\x70\x23\x9b\x8b\x63\xe6\xd8\x1f\x39\x86\xbf\x3c\x46"
+  "\x8e\xe1\x2f\xa7\xc8\x31\xfc\xe5\x10\x09\xc3\x85\x6b\x37\x44\x36"
+  "\x7f\x39\xf2\x86\xcb\xe6\x22\x7f\xf4\x8a\xe1\x2f\x47\x4a\xb2\x79"
+  "\xdc\xf0\xbe\x31\x3c\x76\xa7\x6b\x0c\x87\xf3\x14\xc3\x63\x77\xba"
+  "\xdd\xe7\xd0\x03\xc3\xe3\xae\x78\x80\xe1\x72\x5b\x88\x88\xe1\x82"
+  "\x2d\x64\xa3\x83\x2d\xc4\x96\xcf\x6c\x21\x1b\xda\x19\x6f\x0c\x55"
+  "\x30\x3e\x05\xfe\x51\x97\x2b\x7b\xd7\xdd\x36\x5c\x97\x1d\x24\xae"
+  "\x47\xfc\xfb\xde\xec\x20\x14\xbf\x71\x8f\xc3\xab\x80\xdb\x0d\xfd"
+  "\xdc\xe3\x30\x41\xdc\xe3\x50\xe4\x66\x8f\x83\x80\xe7\x53\x7f\x00"
+  "\x9e\xd3\x3d\x0e\xaf\x0c\x90\xdb\x98\x5f\x19\x24\xda\x98\x19\x9e"
+  "\xbf\x76\xa7\x1c\xcf\x5f\x53\xdb\xf7\x3c\x00\xe6\x1b\x74\x6b\x7a"
+  "\xec\x79\xb0\x63\x3b\xb5\x83\xbe\x32\x4b\xff\x4a\x2b\xb1\xe3\x7b"
+  "\x82\x84\xef\x67\x14\xaf\xee\x97\x61\x7b\x8b\x23\xb6\xbf\x52\x24"
+  "\xc3\xf6\x13\xa5\x72\xff\x88\x16\x9d\x03\xb6\x8b\x7b\x1e\x7e\xb3"
+  "\x72\x7f\x73\x1f\xd8\x0e\xf7\xf7\x7f\x8f\xd8\x8d\xc5\x76\x71\x7f"
+  "\x83\x4b\x6c\x77\xdc\xdf\xe0\xe0\xff\x80\xd8\x4e\xf3\x51\x0c\x77"
+  "\xc2\xf6\xc5\xc9\x4a\xdb\x5e\x98\x0f\x80\xeb\x38\x47\x6c\x3c\x60"
+  "\x3b\x1d\xef\xdf\xd4\x38\x62\xfb\xb5\x7c\x86\xed\x1f\xb4\xff\x70"
+  "\x6c\xb7\xcb\xc3\x8e\xd8\xfe\x2c\x62\x7b\xfc\x3e\xb6\xff\x22\xaf"
+  "\x7f\xfb\x2f\x9c\xfc\x33\x3e\xe8\x87\xfd\xa5\x57\x8c\x77\xd1\x2f"
+  "\x39\xc6\xbf\x7a\x8f\x1c\xe3\x5f\x8d\x95\x63\xfc\xab\x03\x24\x8c"
+  "\x17\xae\xdd\x10\x39\xfd\xd5\xe0\x5b\x63\x7f\x79\x35\x58\xc2\xf8"
+  "\x57\xbb\xfa\xde\x7b\xf1\x4a\xa9\x6b\xdf\x0c\x38\x4f\x31\xfe\x95"
+  "\xd2\x5e\xf7\x5e\xc8\xec\xdd\xaf\x9d\x75\xb9\xf7\xa2\xe1\xc7\xf3"
+  "\xcd\x70\xe4\x15\x67\xfb\xcb\xf5\xdb\xbe\x5f\x6b\xf3\xd4\xfe\x82"
+  "\x7b\x2f\x16\x1f\x76\xd8\x7b\xd1\xdc\xf7\xde\x8b\xac\xc9\xfd\xb4"
+  "\xbf\xf4\xe2\x9b\x71\x20\xd6\xd1\xdf\xed\xf5\xd3\x72\x7c\x7f\xfd"
+  "\xac\x1d\xdf\x5f\x42\x7c\x9f\x66\x93\xe3\xfb\x34\x2b\xf6\xd3\xd5"
+  "\x5e\x8c\xbf\xca\xbe\x2b\x26\x8c\x97\xfb\x6a\x38\xd9\x5f\x5e\x42"
+  "\xde\x9b\xb6\x55\x86\xef\x27\x1c\xf1\x3d\x41\xe7\x4a\x76\x47\xbb"
+  "\x37\xf5\x29\x9e\xea\xb0\xa7\xed\x05\xd1\xff\x6d\xca\xa2\xfd\xf1"
+  "\xf0\xfe\x46\x37\xbe\x6e\x53\x99\xaf\x1b\xf5\x6d\x43\x3b\x38\xb4"
+  "\xb5\x7d\xaa\x4e\x99\x93\xc8\x73\xe8\xeb\xe6\xec\xe7\x86\xbe\x6f"
+  "\xe8\xeb\x56\x97\x5c\xe4\xd6\xcf\x0d\x79\xd3\x9d\xaf\x1b\xf4\x3b"
+  "\x90\x62\xfd\x29\x01\xeb\x05\x5f\xb7\xb2\x74\xc9\xd7\x4d\x86\xf5"
+  "\x2e\xfc\x87\xbf\x38\x91\xe7\x5a\x8e\xcf\x95\xb0\xbe\x1b\xe5\xf8"
+  "\x5f\x38\xd9\x62\x28\x0d\xa6\xec\xf8\x51\x6d\x31\x14\xeb\xa7\x7e"
+  "\x52\x8f\x7c\x9c\xa0\x73\x61\x8b\xe9\xe9\xe3\xfc\xe3\xd9\x62\xa6"
+  "\x29\xe4\x18\x3f\x2d\x42\x8e\xf1\x53\xcf\x4a\x18\x2f\x5c\xbb\x21"
+  "\x18\x3f\x8d\xdc\x1a\x5b\xcc\x34\x22\xd9\x62\xa6\x1d\x77\xe9\x7f"
+  "\x27\xb3\xb1\x27\x64\xb8\xb6\xb1\x27\x08\xfe\x77\x09\x19\x6e\xf7"
+  "\x84\xf4\xf8\xa6\x99\xb8\x87\xd9\xd8\xaf\x63\x4f\x48\xf3\x4f\xcd"
+  "\x16\x93\xa8\xf7\xd4\x16\x43\x7d\x9b\x0f\xa3\x7f\x88\x67\x7b\x42"
+  "\xfa\xc2\x76\xbb\xec\xde\xcb\x37\x4c\x39\xb6\x4f\xdf\x23\xc7\xf6"
+  "\xe9\xfb\xe4\xd8\x9e\x54\x27\xc7\xf6\xa4\x5a\x67\x6c\xef\x89\xeb"
+  "\x33\x86\xbb\xc2\x74\xdd\x4b\x68\x8b\x49\xca\x72\x8f\xe7\x33\xa2"
+  "\x3c\xc7\xf3\x37\x9e\xfb\x1f\x8d\xe7\x2a\x67\x3c\x7f\x63\xd9\x8f"
+  "\x6a\x97\xa1\x78\x3e\x73\x91\x0c\xcf\x55\x7d\xe0\xf9\x8f\x66\x97"
+  "\x99\x79\x48\x8e\xe7\x49\xde\x72\x3c\x9f\xf9\x85\x84\xe7\xc2\xb5"
+  "\x1b\x62\x97\x99\xd9\x70\x6b\xec\x32\x33\x1b\x24\x99\x3d\x69\x6b"
+  "\xdf\x78\x3e\x63\x82\x6b\x3c\x87\xf3\x14\xcf\x67\x4c\x70\xeb\x4f"
+  "\xdd\x03\xcf\xdf\x5c\xe9\x01\x9e\xbb\xf4\x51\xf9\x69\xd8\x65\xde"
+  "\x5c\xe1\xa9\x5d\xc6\xdd\x3e\x15\xc4\x77\xc9\x3f\xc5\x61\x9f\x4a"
+  "\x94\xb8\x4f\x25\x4f\xee\x9f\x72\xc3\xb1\xfd\xb7\x1b\xe4\xd8\xfe"
+  "\xdb\x0f\xe5\xd8\xfe\xbb\x2f\xe5\xd8\xfe\xbb\x9d\x62\x3f\x99\x5d"
+  "\x26\xbf\xc7\xbe\x15\x39\xce\x27\x83\x8c\xde\x4a\x5c\x61\x3d\xb4"
+  "\x35\xc7\x3d\xce\x27\x6b\xdd\xe1\x3c\xfa\xab\xfc\x69\x6a\xb2\x0b"
+  "\x9c\x9f\xf5\xe8\xff\x0f\x38\xef\xce\x0f\x85\xea\x41\x80\xf1\x88"
+  "\xf7\x14\xdf\x05\xac\x47\x9c\xb7\xfd\xcd\x95\x8d\x66\x56\xca\xcd"
+  "\xc2\x79\xf7\x36\x9a\xd9\xb3\xea\x13\x04\x9c\xef\xcf\x1e\x9a\x3d"
+  "\x72\x1b\x4d\xd9\xec\x9b\x6d\xa3\x99\xbd\x47\x8e\xf7\xb3\xcd\x72"
+  "\xbc\x9f\xfd\x89\x84\xf7\xc2\xb5\x1b\x22\xbf\xcf\xd6\xdf\x1a\x1b"
+  "\xcd\x6c\xbd\x84\xf7\xbf\xdb\xd0\x37\xde\x27\x87\xbb\xc6\xfb\x64"
+  "\x21\x36\x5b\x72\x78\xff\xf1\x3e\xc5\x8e\xf7\x3d\xf7\xcf\xe4\x5d"
+  "\xbf\x8f\xcc\x53\xb7\xda\x46\x93\xe2\x16\xff\x7b\x8b\x8f\x71\xfd"
+  "\x36\x1a\x61\x4f\xe2\x0c\xd7\xf1\x31\xf6\xf7\xe2\x23\xb3\xbf\xd6"
+  "\x11\xeb\xe7\xbc\x23\xf7\x45\x9c\xb3\x52\xf4\x45\xdc\x5f\x8f\x58"
+  "\xff\xd6\xe7\x72\xac\x7f\x6b\x87\x3b\x1b\xcd\x17\x9c\xa3\x4f\xe2"
+  "\x9c\xb3\x72\x1b\x4d\x85\xdc\x46\xf3\x02\xf2\xde\x5b\x49\xee\xb1"
+  "\x7e\x6e\xa0\xdc\x07\x9c\xed\x51\xfc\x64\xaa\xe0\x03\x3e\xd5\xc1"
+  "\x07\xfc\xf9\x3f\x08\x58\x3f\xef\xd1\x9a\x06\x2b\xf1\xc4\x0f\xf1"
+  "\x87\xfb\x7a\x2f\x77\xe9\x83\x48\xd7\x80\x5e\xfc\x10\xa7\x1d\x55"
+  "\xa1\x4f\x73\x65\x79\xba\x83\x1f\x62\x2f\xf1\x8c\x65\xf8\x3f\x55"
+  "\xe7\x16\xff\xbb\x78\x09\xff\xb9\x9f\x4b\x76\x1b\x0e\xe5\x7c\x4a"
+  "\x97\x79\x29\x37\xcb\x6e\xe3\xca\x4e\xa2\x7f\x1a\xf1\x5f\x37\x9d"
+  "\xc9\xf9\xc9\x3f\x31\xbb\x8d\xee\x0b\x39\xee\xeb\x3a\xe4\xb8\xaf"
+  "\xfb\x50\xc2\x7d\xe1\xda\x0d\xf1\x45\xd7\x55\xdd\x1a\x39\x5f\x57"
+  "\x25\xd9\x6d\xde\x2a\xe9\x1b\xf7\xe7\x06\xbb\xc6\xfd\xb9\xc1\x0c"
+  "\xf7\xe7\x06\xf7\x6a\xb7\x91\xf9\x46\xa6\x2e\xfa\xc1\x76\x1b\x51"
+  "\xce\xbf\xe5\xfb\x7a\x52\x33\x3c\xb1\xdb\xd8\xf7\xa4\xff\x20\xbb"
+  "\x8d\x6b\xbc\x17\x65\xfb\xfd\xbd\x7c\x73\x95\xe3\xfd\xfc\x45\x72"
+  "\xbc\x9f\x9f\x2d\xc7\xfb\x85\xeb\xe4\x78\xbf\xb0\xd4\x95\xdd\x46"
+  "\x8e\xf5\xf3\xeb\x5c\xe1\xbc\xee\x05\xb4\xdb\x2c\x9c\xe0\x1e\xe3"
+  "\xe7\x5b\x3c\xc7\xf8\x05\xc3\xff\x17\xe3\x9d\x30\x5e\xe5\x8c\xf1"
+  "\x0b\x62\x7f\x54\x19\x9f\x62\x7c\xfa\x78\x19\xc6\xdf\x40\x5b\x4e"
+  "\x7f\xf6\x93\xb8\x97\xed\xd3\x9d\xfc\xdf\xd3\x9d\xfc\xdf\xd3\x1d"
+  "\xfc\xdf\xd3\x1b\x6e\x1c\xc6\xa7\xdf\x78\xff\xf7\x7e\x61\x7c\xba"
+  "\x83\xff\xfb\xc2\x45\x7d\x63\x7c\x1a\x71\x8d\xf1\x70\x9e\x62\x7c"
+  "\x1a\xe9\x55\xb6\x97\x61\x7c\xc6\x94\x9b\x61\xcb\xb9\x35\xfb\x8d"
+  "\x32\x12\x3c\xb1\xe7\xf4\x16\x77\xc4\xad\x3d\x27\x52\xb4\xe7\xe8"
+  "\xdc\xd8\x73\x6e\x14\xe6\x2f\x9a\x23\xc7\xfc\x45\x6f\xc9\x31\x3f"
+  "\xfb\x43\x39\xe6\x67\x57\xc8\xed\x39\xa9\x3d\xec\x39\x72\xfc\x5f"
+  "\x74\x48\xff\x82\xa3\x3d\xa7\xc2\xc1\x9e\x93\xfd\xa2\x7b\xfc\x5f"
+  "\xe4\x16\xff\xaf\x52\xfc\x4f\x74\x81\xff\x8b\xff\x87\xe0\x7f\xe2"
+  "\x0f\xc0\xff\xc5\xb7\x00\xff\xb3\x26\x31\x1b\x4f\x3f\xe3\xa4\x7c"
+  "\xe1\xb9\x8d\xe7\x87\xad\x03\x59\x1f\xc9\xd7\x81\xac\x26\xf9\x3a"
+  "\x90\xb5\x52\x5a\x07\x84\x6b\x37\x64\x1d\xc8\xda\x74\x6b\xd6\x81"
+  "\xac\x4d\xd2\x3a\x90\xbd\xa4\xef\x75\x20\xd3\xcd\x3a\x90\x29\xac"
+  "\x03\x99\x1e\xac\x03\x39\x6f\xb9\xb7\xf1\xe8\xae\xdf\xc6\x33\xe6"
+  "\x56\xef\x83\xca\xd1\x79\x64\xe3\x59\xfb\x0b\x55\x2d\xc6\x48\x39"
+  "\x45\x94\x8b\xa7\x8b\x36\x1e\xbd\x93\x8d\x47\xdf\xc3\xc6\xb3\xe8"
+  "\x94\x80\xff\x13\x85\xfd\xa6\x2f\xfc\x80\x18\x29\x34\x87\x72\xee"
+  "\x1c\xb9\xdf\x7c\x2e\xc5\x7f\x29\x7e\x5f\xbe\x0d\xfb\xc5\xd6\x1f"
+  "\x7d\x2f\x31\x50\x73\xbf\x94\xd9\x74\x26\xba\x8a\x91\x92\x2f\xf3"
+  "\xbb\x91\xef\x37\xcd\x6d\x93\xe1\xfd\x0b\x6c\xbf\xe9\xa7\xae\xbe"
+  "\xd3\xda\x63\xf2\xe7\x75\xd1\x98\xfc\xf6\x58\x7e\x79\xa3\xfb\x15"
+  "\x4b\x7a\xaa\x10\x4b\xfa\xc4\x2d\x88\x25\xdd\xdf\x98\xfc\x27\x9c"
+  "\xe3\xf7\x2d\x29\x31\xd4\xea\x49\x3d\xf2\x48\x82\x73\xec\x53\xbd"
+  "\xeb\xbd\xfb\x4a\x61\xef\xfe\xdc\x9b\x13\x07\x05\xfb\x43\xd7\xfc"
+  "\x80\xa5\x9a\xad\x39\x26\xda\x1f\xcc\x57\x0d\x74\xbe\xb3\x16\x78"
+  "\x95\x43\x3c\x4d\x45\x3c\xcd\x9f\x48\xeb\x9e\x02\x5e\x08\x18\x16"
+  "\x8f\x7c\x5c\xc8\x11\x5f\x5d\x3a\x62\xeb\x12\xea\xf7\x05\x62\x04"
+  "\x60\x2b\xab\x97\x7d\x8a\xb7\xd9\x02\xee\x8e\x87\xfe\xdf\xb6\x6d"
+  "\x6e\xc3\x80\x7a\xa3\x19\xe6\x45\x3b\xee\x89\x55\x18\xac\x9d\x7a"
+  "\xa4\xc5\xae\xb9\x0d\xde\x3c\xe0\xef\xc6\x37\x89\x8f\x67\xf3\x34"
+  "\x5f\x4d\xe5\x19\x5c\xf7\x02\x96\x8e\xc6\x38\x20\xa2\x6c\xc5\x5d"
+  "\x90\xec\x5b\x1b\x60\x7c\x38\x9e\xad\x7d\xd3\x66\x31\xdc\x80\xe7"
+  "\x55\xc2\x58\x52\x1f\x5b\xc4\x0d\x9a\xc3\x0a\x70\xa3\xfc\x92\xf4"
+  "\x1d\x1b\xdb\xc7\x31\x62\x76\x94\x7c\xc9\xff\xc5\xe8\x0e\x5b\x61"
+  "\x66\xba\xc4\xd6\x5c\x13\xc3\xd6\x5c\x93\x1d\x5b\x8d\x2e\xec\x28"
+  "\x32\x3f\xf6\xa5\x82\xff\x8b\xde\x49\xc6\xd6\xff\x1b\xc6\x47\x59"
+  "\xea\x91\xff\x0b\xc5\xd3\x14\x86\xa7\x88\x57\x22\xa6\x4a\x76\x14"
+  "\xbd\x5b\x3b\x4a\x5f\x98\xea\xd1\x1e\x7e\x8a\xa9\xcb\xf6\xc8\x31"
+  "\x75\xd9\x3e\x39\xa6\x2e\x1f\xef\x8c\xa9\x3d\xf1\xf4\xed\x01\xae"
+  "\xb0\x94\xc5\x47\xf9\xbd\xd9\x3d\x8e\xbe\x1d\xee\x0e\x47\xa9\x7f"
+  "\xfa\x54\x07\xff\x74\x3b\x8e\x16\x3c\x25\xc7\xd1\xb7\xd3\xfa\x8b"
+  "\xa3\x34\xb7\xc9\x89\x1f\x21\xb7\xc9\x75\xe3\xa8\xce\x09\x47\x0b"
+  "\x8e\x4b\x38\xea\x9c\xdf\xa4\x0f\x1c\x9d\x7d\x73\x62\xa0\xc8\x70"
+  "\x94\x33\xd1\xfe\x68\xe6\x62\x5f\x7f\x3f\x5d\x8e\xa3\xbf\x2f\x76"
+  "\x8f\xa3\xbf\x7f\x54\xc2\x51\x56\xef\xe6\xe2\xe8\xef\x13\x65\x38"
+  "\x3a\xdb\x01\x47\xff\x25\xe9\x10\xe8\x63\x61\xc7\xd1\x39\x0e\x38"
+  "\x3a\xbb\x2f\x1c\xfd\x7d\x22\x8e\x11\x93\x51\x97\x87\xf5\x8d\xa3"
+  "\x6f\x47\xba\xc6\x51\x38\x4f\x71\xf4\xed\x48\x09\x47\x5d\xc8\xa8"
+  "\x32\x1c\x7d\x67\x90\x07\x38\xfa\x13\x8f\x8d\xf2\x8e\x8f\x47\xb6"
+  "\x0a\x69\x4f\x67\xcf\x18\xa9\x53\x1c\xf7\x04\x55\x39\xe5\x3d\xa9"
+  "\xea\x91\xf7\x64\x91\xb8\xc7\x73\x82\x80\xab\xcf\xff\x00\x5c\xa5"
+  "\x7b\x3c\xdf\xbd\x53\xee\x7b\xf2\xee\x3d\xa2\xef\x09\xc3\xd5\x95"
+  "\x9f\x89\xfd\x92\xf2\x9e\x54\xf5\x12\x23\xf5\xdd\x39\xb2\xd8\x28"
+  "\x13\x1c\x63\xa3\xac\x9c\xee\x3e\x46\xea\xbb\xc5\xb2\xd8\x28\x07"
+  "\x36\xdb\xf3\x9e\x38\xc7\x48\x95\x30\xf6\x3f\x3f\xa2\x18\x6b\x8f"
+  "\x41\xf5\x6e\x93\x3d\x46\x6a\x1f\xfb\x82\xb0\x9d\x6d\x2d\xc9\x37"
+  "\x1f\x63\xf5\x1e\x60\xac\x2c\xef\x89\x73\x8c\xa9\x15\xcf\x19\x6a"
+  "\xaa\x48\x7d\x62\x95\x8b\xd8\xa8\x55\xb7\x34\xf7\x09\xf6\xcb\x35"
+  "\xd6\xae\xa8\x93\x63\xed\x4a\x42\xeb\x1e\x77\x85\xb5\x2b\x36\x48"
+  "\x58\xcb\xea\x65\x1f\x77\xc2\xda\x66\x37\x58\x0b\xeb\xea\xc6\x33"
+  "\x9e\x62\xed\x8a\x5a\x8a\xb5\xf9\x02\xd6\xb6\xdf\x68\xac\x5d\x51"
+  "\x2b\x61\xed\xca\xd5\x7d\xe7\x98\x7a\xb7\xcc\xf5\xbe\x9c\x77\xcb"
+  "\x18\xd6\xbe\x5b\xd6\x6b\x8e\x29\x99\xcf\x47\xe1\x12\x31\xc7\x94"
+  "\x64\x0f\xa8\x12\xec\x01\xff\xce\x39\x51\x0a\xf3\x3c\xb5\x07\x1c"
+  "\x04\xdd\x1d\xf7\x5d\x2e\xc6\x9c\x53\x09\x98\x13\xa5\xd2\xc9\x1e"
+  "\x50\xd9\xd3\x1e\xf0\x6a\xef\x18\xeb\x91\x3d\x80\xee\xbb\x5c\x95"
+  "\x2d\xc7\xd8\x55\x4b\xe4\x18\xfb\xde\x9d\xe2\x3e\x4b\xec\x8f\xfb"
+  "\x98\xa9\xab\xea\xec\xf6\x80\x66\x39\xb6\x4a\xf6\x80\x35\xfb\xdd"
+  "\x63\xec\x2a\xb9\xfd\xf7\xf9\xcd\xb2\x7d\x96\x9f\xb6\x38\xc6\xa1"
+  "\x16\xe3\x4f\xad\x1e\xbe\xbf\xd1\x11\x63\x8b\xc6\xfd\x3b\xc5\xa1"
+  "\xb6\xc7\x9a\xea\xc3\x97\xbb\x67\x1c\xea\xd5\x9f\x19\x6a\x2a\x09"
+  "\xee\x6d\xa3\x78\x2b\xb3\x0d\x54\xde\x1a\xdb\x40\x4d\xa5\x1b\xdb"
+  "\xc0\x9a\x27\xe4\x38\xbb\x26\x99\xd6\x3d\xea\x0a\x67\xd7\x0c\x90"
+  "\x70\x96\xd5\xcb\x3e\xea\x84\xb3\x4d\x37\x52\xa6\x5d\x13\x71\x73"
+  "\x6d\x03\x6b\x22\x24\xdb\xc0\x9a\x7e\xec\x7f\x2c\x22\xae\x71\xb6"
+  "\x48\xb0\xbb\x16\x49\x76\xd7\x26\x17\xf9\x52\x64\x38\xfb\xde\x71"
+  "\x71\xff\x23\x95\x69\x9b\x45\x99\xb6\xf2\xdf\x30\x5f\xca\x7b\xcd"
+  "\x9e\xda\x06\x70\x9f\x3b\x62\x2b\x62\x97\x88\xaf\x92\x6d\xa0\xd2"
+  "\xbd\x6d\xa0\x0f\x7c\xf5\x3c\x77\x5f\xf1\x71\x39\xbe\x16\x9f\x92"
+  "\xe3\x6b\xe9\x1c\x67\x7c\xed\x89\xad\x25\x21\xae\x70\x95\xd9\x06"
+  "\x4a\x83\xdd\x63\x6a\xc9\x44\x77\x98\x4a\x63\xfa\xb5\x48\x3e\xd2"
+  "\x12\xa6\xae\x9d\x25\xc7\xd4\x92\xa2\xfe\x62\xea\x2d\xc9\x97\x72"
+  "\xdd\x98\x9a\xec\x84\xa9\xef\x0f\x90\x30\xd5\x39\x67\x4a\x1f\x98"
+  "\x7a\xb3\xec\x04\x8e\x98\x2a\x93\x5d\xdf\x7f\x47\x8e\xa9\xef\xef"
+  "\x74\x8f\xa9\xef\xbf\x2a\x61\x2a\xab\x77\x73\x31\xf5\xfd\xe5\x37"
+  "\xd7\x4e\xf0\xfe\x72\x49\x76\x2d\x9d\xd4\x37\xa6\x96\xc4\xb9\xc6"
+  "\xd4\x92\x38\x86\xa9\x25\x71\xfd\xdf\x53\xbe\xee\x51\x0f\x30\xf5"
+  "\x27\x9e\x4b\x65\x5d\xb8\xc7\x76\x02\xb4\xb7\x22\x96\x36\xff\xb0"
+  "\xd8\x21\x19\x62\xec\x90\x68\x01\x63\x9f\xfd\xa1\x18\xbb\xfe\x29"
+  "\xb9\x4f\xc3\xfa\xf1\xa2\x4f\x03\xc3\xd8\x0d\xa7\xe5\xf9\x51\x7b"
+  "\xc6\x0a\x91\xc7\x50\x5d\x5f\x62\xb7\x13\x20\xe6\x46\x3b\xda\x09"
+  "\x36\x94\xb8\xc7\xdb\xf5\x3b\x65\x76\x82\xbf\xbb\xc6\xdb\xab\x32"
+  "\xbc\xfd\xe0\x28\xc5\x5b\x7b\x0c\xd5\x0f\x88\x18\x43\xb5\x4f\x19"
+  "\x56\x86\xb7\x89\x3f\x0e\xde\x56\xf5\x1f\x6f\xe5\xb9\x54\x9c\xe3"
+  "\xa5\x96\x65\x1b\xaa\x01\x6f\x69\xbc\x0e\xe7\x98\xa9\xfd\x8b\xd7"
+  "\x71\xb3\x62\xa6\x62\xbf\x5c\xe3\xee\x06\x85\x1c\x77\x37\x44\xd0"
+  "\xba\x2e\x71\xb7\xec\x90\x84\xbb\xac\x5e\xbf\x71\xf7\xba\x6c\x06"
+  "\x68\xa2\xb8\x99\x36\x83\x0d\x44\xc2\xdd\x0d\xfb\xfa\xc6\xdd\xf5"
+  "\xd5\xae\x71\x77\x7d\x35\xc3\xdd\xf5\xd5\xbd\xe2\xae\xcc\x87\xa0"
+  "\xfc\x73\x97\xb1\x3c\x9a\xff\xdd\xf3\xac\x94\xef\xb8\x1e\x9b\x01"
+  "\x60\xb0\x32\x0b\x63\x38\x25\xa2\x0f\x41\xdf\x36\x83\xbe\xf0\xd6"
+  "\x73\x9b\xc1\xc6\xcf\xe4\x78\xbb\xf1\x73\x39\xde\xfe\xd7\x74\xec"
+  "\x57\xaf\x36\x03\x8a\x01\x15\x0a\xbb\xcd\xc0\x28\xc7\x59\xc9\x66"
+  "\xf0\x5f\xfe\xee\xbf\x7d\x55\x8c\x96\xc9\xb7\xcf\x3a\xc5\xac\x9e"
+  "\x2a\xe1\xed\x81\x7a\xd1\x67\xec\xc3\x29\xfb\x63\x1d\xf1\xb6\x42"
+  "\xd7\x23\x66\x75\xdc\x0d\x8c\x59\x1d\x77\x83\x63\x56\x4f\x96\xc7"
+  "\xac\x5e\x7f\x55\xf2\x23\xf3\x3c\x66\xf5\x87\x5d\x14\x83\x91\x87"
+  "\x30\x6e\x75\x7f\xec\x08\x37\x39\xd7\x8a\x0c\x7b\x65\x76\x84\x3f"
+  "\x64\xcb\xb1\xf7\x0f\x95\xee\xb1\xf7\x0f\x93\x24\xec\x65\xf5\x6e"
+  "\xae\xcc\xfb\x87\xac\x9b\x6b\x47\xf8\x43\x96\x64\x47\xf8\xaf\xa7"
+  "\x5c\x62\xaf\xec\xdb\x58\x45\x84\xeb\x6f\x63\x70\x9e\x62\x6f\x45"
+  "\x84\x5b\x3b\x42\x0f\xff\xad\x4d\x61\xec\xdb\x98\x20\xf3\x1a\x3d"
+  "\xb0\x23\xfc\xe4\x7c\x0c\x36\x85\x5e\x8f\x1d\x01\xf1\x16\xf1\x4c"
+  "\xc4\xdc\xfe\xd8\x11\x6e\xbc\x8c\xfb\x51\x98\x1c\x73\x3f\x7a\x40"
+  "\x8e\xb9\x9b\xf7\x3b\x63\x6e\x4f\xbc\xfd\x68\x96\x2b\xac\x65\x76"
+  "\x84\xcd\x19\xee\x71\xf6\xa3\x62\xb7\x38\xeb\xe4\x9b\x2b\xe1\xec"
+  "\xc7\xfb\xe4\x38\xfb\x51\xd3\x75\xe1\x6c\x7f\x73\xb0\xfc\xa4\x70"
+  "\x36\xd1\x09\x67\xff\x38\x5d\xc2\x59\xe7\x3c\x2c\x7d\xe0\xec\x4d"
+  "\xca\xc3\xe2\x5e\xc6\xfd\xe3\x69\x39\xce\x6e\x56\xbb\xc7\xd9\x3f"
+  "\x7e\x2e\xe1\x2c\xab\x77\x73\x71\xf6\x8f\xad\x37\xd7\xb6\xf0\xc7"
+  "\x56\x49\xc6\xdd\xfc\x49\xdf\x38\xfb\x51\x99\x6b\x9c\xfd\x48\xf8"
+  "\x2e\xf6\x51\x99\x5b\x19\xb7\x07\xce\x7e\xb2\xd2\x03\x9c\xfd\x89"
+  "\xfb\x20\x7c\xe2\x51\xfc\x0b\x07\x7b\xed\x40\x83\xd1\x69\xbf\xc4"
+  "\x51\xc7\xfd\x12\x0e\xb6\x85\x68\xd1\xb6\x20\xcf\xcf\x92\x21\xda"
+  "\x6f\xa3\x04\xdc\x7d\xfa\x87\xe2\xee\xa7\x1b\x3a\xed\xb8\x9b\x0a"
+  "\xb8\xfb\x29\xdd\x1f\xd1\x69\xc7\xdd\x6d\x93\xc5\x7e\x49\xf9\x59"
+  "\xdc\xd8\x16\xc6\xd2\xf6\x2e\xda\x6d\x0b\x88\xc3\x51\x8e\xb6\x85"
+  "\x6d\x03\xdc\x63\xf0\x9f\xd4\x32\xdb\xc2\x57\xae\x31\xd8\x2c\xc3"
+  "\xe0\x2d\xcf\x51\x0c\x1e\x2b\x62\xf0\x9f\x12\xae\x82\x6e\x79\xb5"
+  "\xc0\x33\x0c\x36\x53\x0c\x9e\x70\x6b\x30\x78\xc7\x0d\xc0\x60\x3a"
+  "\xee\x5b\xce\x19\xf4\x80\xc1\x09\x88\xc1\x13\xfa\x67\x6f\xf8\x91"
+  "\x72\xb4\x60\xbf\x5c\x63\xf1\xd6\xb7\xe4\x58\xbc\x75\x13\xad\xeb"
+  "\x12\x8b\xb7\x3e\x25\x61\x31\xab\x77\x73\xed\x0d\x5b\x75\x37\xd7"
+  "\xde\xb0\x55\x27\x61\xf1\xb6\x27\xfa\xc6\xe2\x3f\x69\x5c\x63\x31"
+  "\x9c\xa7\x58\xfc\x27\x4d\xaf\x58\x3c\xd6\x11\x8b\xb7\xdb\x65\x5e"
+  "\x99\xbd\xc1\xf8\xef\x9e\xbb\x65\xbb\x5b\xf9\x57\x73\x2f\xc9\x6b"
+  "\x51\x6c\xcf\x36\x94\x11\x72\x39\x9f\xe4\x19\xac\x63\x09\x9c\x83"
+  "\xf1\xdb\xfe\x91\x41\x1d\x49\xb8\x35\x23\x2b\x10\x8f\xdf\xc3\x1f"
+  "\xc8\xb8\x45\x4a\x61\x6e\xd1\x31\xde\x4e\xfd\x5d\xf1\x3c\x62\xef"
+  "\x46\x87\xeb\xae\x9e\xc5\x17\x8d\x0c\x66\xf7\x55\x12\xb6\xef\x66"
+  "\xa4\x46\x2c\x23\x6f\x1a\x15\x95\xde\xfc\xea\x91\x6a\x93\xff\x48"
+  "\xb5\xab\xfb\x47\xa8\x88\xcf\xd0\x25\x3c\x5f\xbe\x96\x37\x5f\x1e"
+  "\x15\x48\x2e\xbf\x4b\x48\xd1\x5a\xde\xd4\x59\x50\x39\x0e\xde\x71"
+  "\xe6\xfb\x50\xef\x72\x40\x29\xbc\x47\x2c\x81\x73\xb1\xe2\x39\x18"
+  "\x37\xc2\xe5\x7b\xf1\x1c\x5c\xe3\xd7\x7c\xdf\xb1\x31\x07\xb0\x0a"
+  "\x34\xb7\x87\xaf\xe2\x9c\xa9\x4c\x04\x9e\x09\x2c\x84\x36\x57\x41"
+  "\x5b\xfc\x1d\x77\x9b\x81\x1f\xbd\xeb\x97\x11\x9c\xd3\xcb\xe1\xbd"
+  "\x2a\x0a\x71\xec\xbd\x1e\x2c\xe5\x95\xde\x84\xfb\x68\x58\x3c\x3f"
+  "\x7c\x9c\x0a\xe8\x41\x8a\x52\x09\xf5\xb9\x5b\x05\xf5\x78\x65\x2e"
+  "\x0f\xeb\x88\xd1\x60\x35\xb3\x39\x0d\xfd\xdb\x05\x7a\x2c\x0f\xcf"
+  "\x2d\x4f\x25\x2a\xf8\xf9\xf2\x25\xe3\x54\xd0\xaf\x36\xe8\x57\x03"
+  "\xf6\xcb\xdd\x3b\xae\x5a\x0f\xeb\xce\xdd\x6a\x5c\x3b\xe8\xf3\xf1"
+  "\xd9\xf4\x39\x4a\x6e\xb9\x0d\xce\xf3\xf9\xb9\xbc\x21\xc3\x4a\xfc"
+  "\x60\x2c\x36\x42\xbf\x91\x1f\xb9\x8f\x03\xc9\xd2\xbb\x08\xd9\x96"
+  "\xd9\xa6\x34\x40\xdf\x6d\xef\xdf\x6d\xd6\xe7\x3c\x46\xe0\xba\x09"
+  "\x75\x96\x33\x8a\xcf\x4e\xc7\x9c\x25\x04\xf1\x04\xfe\xbf\x68\x86"
+  "\x75\x6c\x12\x94\x57\xc1\x7b\x70\x97\xd5\xde\x58\x17\xce\x6f\xd0"
+  "\xa7\x1f\x23\x7e\x3a\xe2\x53\x08\xef\x26\xd4\x4d\xc1\xba\x46\xc5"
+  "\x67\x26\xec\x03\x94\xf3\xa0\x8c\xf7\xa1\x0f\x19\xe1\x37\x0d\x8b"
+  "\xa7\xbc\x59\x3c\x4e\xc5\x85\x0d\x8b\xa7\xd8\x07\xef\xb9\x0a\xde"
+  "\x19\xea\xf8\x42\x1d\x5f\x7a\xcc\x21\xaa\x62\x38\x87\xed\xc0\xd1"
+  "\x57\x3f\xb7\x1b\xdb\x4e\xc0\xb6\xdd\x8c\x83\x37\x1f\x38\x4e\xc5"
+  "\x03\x6f\xe3\x9a\xaa\xc9\x51\x1c\x6a\x51\xfc\xb9\xc8\x4f\xc1\xf3"
+  "\x30\xcf\x8d\x4b\x73\x88\x6f\x11\x47\x88\xfe\x2e\x6c\xe7\xcf\xb3"
+  "\xa0\x7d\x6f\x1c\x8b\xce\x82\x3f\xc3\x9c\xaf\x34\xe3\xf8\x02\x3d"
+  "\xcd\x9a\x11\xf8\x0e\x7f\xae\xc0\xe7\xe0\x3d\x42\x7d\x1a\xfb\x1e"
+  "\xfb\xac\xc9\xf1\xe2\xa1\xfc\x8e\x97\xe2\x14\xf1\x52\xfb\x16\xc0"
+  "\xfd\xcb\x8d\x64\x76\x23\xde\x6f\x64\xf7\x01\x2f\xfd\xb9\x0c\xda"
+  "\x54\xe1\x39\x2c\xbb\xe9\xaf\xaf\x48\xb7\x3a\x35\xf0\x86\x33\xed"
+  "\x44\x1e\x01\xbe\x10\x79\x04\xfb\xbb\x3d\xc7\xa8\xa4\xeb\xb0\xe2"
+  "\x2f\x54\xaf\x2b\x04\x1a\xda\x3e\x50\x7b\xaf\x82\xb1\xe5\xae\x21"
+  "\x5d\x5a\xf0\xda\x29\xa4\xcb\xaa\x4c\xa0\x09\xab\xeb\x2d\xf5\x9f"
+  "\x96\x29\x3d\x39\xa0\x05\xdb\xbb\xf9\x97\xcf\xf1\x7d\x56\x5d\x05"
+  "\x3a\x06\xf1\xe6\xea\x0c\xe8\x17\xf2\x2d\xf0\xc8\xb6\x54\x8b\x12"
+  "\xfd\xfa\xf0\xfc\xae\x4b\x16\xe5\xaa\x76\x82\x72\x25\x59\x09\xb8"
+  "\xbc\x21\x1d\xc6\x1c\xda\xe4\x43\xfd\x8d\x8f\x88\x74\xcc\x04\xda"
+  "\xa5\x03\xef\xc2\x98\xaf\x82\xf1\x2b\x07\xcc\xc3\xff\xcb\x61\xfd"
+  "\x01\x99\xce\x68\x54\xfc\xc5\x04\xed\xa9\x36\x04\xf1\xa6\x8d\x41"
+  "\x7c\x07\x8c\xe1\xfa\xce\x82\xbf\xd4\x8a\x63\x88\x7d\x5a\x05\xe7"
+  "\x57\xc2\x75\xa8\x3b\x81\xf1\xd0\x5f\xd4\xe2\x3b\xbb\x1b\xcf\x15"
+  "\xdb\x48\xe4\xca\x6d\x24\xf8\xdd\x6d\x64\xdc\xe2\x56\x98\x97\xf9"
+  "\xbf\xe2\x0f\x26\x58\x61\x4d\xcc\x8e\xec\x0e\x0a\xa3\xdf\xf8\xb9"
+  "\xa5\x77\x57\xbc\xbd\x8d\x8c\xc6\xbd\xb1\x31\x1d\x84\xe0\x1a\x1e"
+  "\x33\xe0\x24\x6f\xd0\x5d\x21\x9c\x7f\x76\xa4\x6d\xe9\x83\x01\x2f"
+  "\x5c\x21\x64\x9f\xd6\x4c\x72\xd2\x60\x2d\xbf\xd4\x46\x72\xcc\xbc"
+  "\xa9\x3e\xef\x2c\x01\xec\x11\xc6\xee\xf3\x15\x31\x49\x84\xe0\x9e"
+  "\x41\xee\x5f\x5a\x32\x24\x99\x78\x67\x1d\x25\xea\xdc\x56\xbe\xcd"
+  "\xb6\xf6\x51\x53\x4e\x36\x51\x6e\xbb\xd4\xc4\x64\x4f\xc5\xe7\x53"
+  "\xbe\xc4\xfd\xa9\x9d\xf1\x64\x9a\x55\x58\x8f\x8a\xc7\xa9\x73\x67"
+  "\x91\x3b\xf1\x7d\xfc\xa8\xec\xb5\xa3\x0b\xc6\x4d\xed\x19\x3e\xef"
+  "\xa8\xa6\xf4\x5c\xfb\x78\xde\xb6\x19\x16\x90\xb7\xce\xaa\x72\x93"
+  "\xf8\x36\x94\xeb\x60\x7d\xa1\xb2\xa0\xa1\xcd\x0a\xb2\xd5\x4c\x58"
+  "\xbf\x8d\x64\x77\x4b\x85\x92\x5b\x7d\x56\xe5\xd9\x33\x3e\xd7\xd2"
+  "\x75\x1b\xd7\x52\xe8\xfb\x64\x2d\xc9\xa3\xfd\x87\x35\xd3\x2f\x0d"
+  "\xe5\x29\xfe\x24\xf6\x7f\x17\xbc\x2b\x1f\x12\xa3\x83\x3e\x6d\xc1"
+  "\xf5\x33\xa6\x59\x4f\x6a\x2d\x36\xb2\xbe\x9d\x8e\xd1\x40\x18\x23"
+  "\x6f\xb8\x96\x07\xe3\xe4\xe3\x8a\x6e\x48\x33\xae\x28\x3b\x92\xf3"
+  "\x62\xb4\xa1\x74\x31\x33\xba\x60\xa6\x2d\x43\x1a\xd0\x66\x35\xa3"
+  "\x0d\x37\xfc\x17\x94\x36\x1e\xbe\x87\xc9\xdd\xfa\x82\xcf\xe6\x81"
+  "\x3f\x90\x2f\xb8\xc0\x5f\x10\x7c\x36\xf6\x01\xbf\x9f\x21\x1f\xc4"
+  "\xbc\x7d\x92\xaf\xd7\xb5\x11\x03\xbc\x0f\xef\xef\xd8\x07\xab\x87"
+  "\x7d\xf8\xbf\x69\xee\xfa\xb0\xe2\x61\xe0\xdb\x87\x81\x6f\x1f\x06"
+  "\xbe\x35\x32\xbe\x3d\xd0\xcc\xf8\xd6\x06\xfd\xea\x02\xd9\x7d\xf1"
+  "\x64\xa2\xc4\x7e\x6d\x39\x86\x31\xfa\xa0\x9f\x6d\x12\xef\x4e\x3a"
+  "\x07\x63\x24\xf2\xaf\xd7\x83\x01\x38\x3e\xf5\xe6\x26\x92\x8b\xfc"
+  "\xdb\xed\x8a\x7f\xab\x26\xc6\x4c\x07\xda\xfc\x16\xf8\xf7\x7b\x2d"
+  "\xf1\x6d\x25\xde\xd9\x93\x81\x7f\xdb\x5c\xf1\x6f\xd5\x3d\x3b\xe1"
+  "\x99\x3d\xf8\x37\xc9\x91\x7f\xff\xfb\x0b\xcf\xf9\xf7\xbf\x97\xd9"
+  "\xf9\xf7\x35\x81\x7f\x67\x39\xf1\x6f\xab\x03\xff\xe2\x7b\x7b\xcc"
+  "\xbf\xff\xdd\xe6\x19\xff\xfe\x77\x8a\x9d\x7f\x41\x2f\x59\xff\x26"
+  "\x1d\xa3\x81\x30\x46\xc0\xbf\xff\x1d\x05\xe3\xe4\x92\x7f\x7f\x7c"
+  "\xfa\xfd\xd5\xb7\xff\xf4\xfb\xe2\x78\xdf\xf4\xfb\x62\x91\xe7\xf4"
+  "\xfb\x22\xfa\xe6\xd3\xef\x8b\xcd\x9e\xd1\xef\x8b\xd1\xee\xe9\xf7"
+  "\x05\xf9\xe9\xd0\xef\x6f\xb5\xfd\xa7\xdf\xdf\x36\xf4\x4d\xbf\xbf"
+  "\x8d\xf1\x9c\x7e\x7f\xf3\xbe\xf9\xf4\xfb\x5b\xb2\x67\xf4\xfb\x6b"
+  "\x87\x7b\xfa\xfd\x55\xef\x8e\x7e\xcf\xdc\xc9\xf1\x1c\xfa\xcd\x05"
+  "\x85\x24\xa2\x0c\xc4\xe4\xb5\x9d\xeb\x50\x67\x84\xb2\xb7\x58\xa6"
+  "\x32\x15\xe8\xd5\x4e\x65\x5f\xa7\xb2\xca\xa9\x1c\xe8\x54\x56\x3b"
+  "\x95\x83\xc5\x32\xd0\x6b\xc0\x79\xc5\xce\x41\xa0\xb3\xe5\x19\x15"
+  "\x3b\x37\x09\xd7\x43\xa7\xd9\x34\xa8\xf7\x85\xba\xea\xfb\xaa\x7c"
+  "\xde\xa2\xcb\x21\x77\xb7\x2b\xbe\x54\x51\x7a\x2c\xbd\x4b\xcb\x67"
+  "\xe6\x11\xa0\x47\xf4\x0b\xd9\xc8\x57\x26\xc2\x5f\x53\x0f\x84\x71"
+  "\xba\x03\xf4\x4d\x13\xf2\x9c\x26\x75\x37\xdf\xa2\xd8\x69\xc3\xf7"
+  "\x7b\x58\xa7\x27\x9c\xd7\x83\xf8\x3d\x42\x01\xf4\x89\x36\x79\x3d"
+  "\x78\x17\xff\x61\x2c\x29\x54\x72\x3e\x85\xf9\x9c\x26\xdb\xc4\x9b"
+  "\x26\x5e\x84\x75\x0c\xd6\x32\x43\x87\x05\x78\x92\x37\xe9\x53\xcf"
+  "\x41\x7f\xbf\x4c\xaa\xcb\x82\xb6\xe1\x39\xf0\xac\x28\x5e\x75\x36"
+  "\xd4\x60\x6d\x20\x3c\xb4\x51\x6f\xae\x01\xdd\xbf\x89\x08\x6d\x46"
+  "\xf1\xfe\x67\x43\xb1\x4d\x97\xfa\x59\x71\x48\x31\x3c\x73\xec\x64"
+  "\xad\x37\xe1\x97\x78\x07\x7a\xc6\x1f\x5f\x2e\x77\xab\xf7\x15\x8f"
+  "\x08\x64\xed\xfa\x5c\x4f\xbb\xc6\x5e\xda\x15\xfa\xab\xba\x8e\x76"
+  "\x77\x45\xba\x6f\x77\xa4\xd0\x5f\xcd\xf5\xb4\x5b\xd4\x4b\xbb\x42"
+  "\x7f\xa3\xae\xa7\x5d\xb7\xf9\x3f\xf8\xe2\x50\xa1\xbf\x79\xd7\xd1"
+  "\xee\xee\x28\xf7\xed\x86\x14\x5f\x1f\x2f\xec\x2e\xee\x8d\x17\xae"
+  "\x8f\x0f\x76\xf7\xf2\xfe\x23\x8a\xaf\x8f\x07\xf4\xe3\x7a\xe3\x81"
+  "\xeb\xa3\xbf\xbe\x57\xfa\x5f\x1f\xed\xf5\xad\xbd\xd1\xfe\xfa\xe8"
+  "\xbe\xc7\x2d\xff\xa3\x2e\x0b\xb4\x0f\xe7\x83\x62\x12\xb9\x35\x17"
+  "\xc3\xb9\xa0\x90\xc7\x96\x72\x51\xe4\x19\xc0\x30\xbf\x52\xe2\x1f"
+  "\x45\xed\x43\x7b\x6a\xb3\xcb\x88\xb2\x48\xc9\x29\xb7\x66\x36\x29"
+  "\x0d\xd6\x48\x92\x6b\xe5\x6d\x9b\xd2\x2d\x8a\x91\x70\x7e\x0f\xac"
+  "\x16\xe6\xf9\x5a\x42\xdb\x09\xb8\x18\x5e\x98\x13\x45\x62\x6c\x04"
+  "\xed\x11\xe6\xbd\x59\x80\x61\x80\x63\x86\x52\x0b\xae\x79\xfe\x70"
+  "\x9f\x15\xf8\x17\xda\xb0\x90\xed\x9c\x49\x11\x95\x4a\xeb\x99\x40"
+  "\x6f\x34\xf1\x6b\x43\x1e\xe3\x73\xb5\x64\x19\xfc\x7f\x46\xf1\xd5"
+  "\x13\x5e\x26\xa2\x2c\x07\x7d\xb2\xb3\xe0\xab\x70\xa3\x62\xaf\x2f"
+  "\xea\x98\xa0\xcb\x76\xe4\x5e\x44\x9b\x7b\x4c\xe2\x52\xd0\x6b\xb1"
+  "\xee\x36\xce\xa4\x7c\x58\x47\x94\x7b\x4d\xa8\xbf\x7f\x95\xb0\x07"
+  "\x24\xf6\x5e\x6c\x2e\xde\x5c\xe0\x98\x34\xbc\x1f\xdb\x41\x5b\xe6"
+  "\x2a\x0e\xc6\x36\x70\x9c\x1a\xfb\x0b\x63\xdc\xa6\xcf\xc4\x75\xe1"
+  "\xab\xd6\xf1\x0f\xf0\x9d\x02\xce\xdf\xd5\x0e\x65\xaa\xb3\xe7\xf3"
+  "\x0d\xbc\xaa\x4d\xcd\x17\x0e\x89\xaa\x37\x5f\x22\xfa\xf4\x6e\xd2"
+  "\xa2\xf8\xea\x34\x3e\xfb\x72\xe0\x18\x9d\x39\x70\x4c\x06\xf4\xc1"
+  "\x28\xf6\x17\x9f\x25\x9e\x47\x1b\x05\xeb\xe3\x5e\xb2\x27\xcb\x7d"
+  "\x1f\x61\x2d\x09\x88\x51\xf3\x26\x1c\x43\x7d\xce\x25\xe8\x4b\xf5"
+  "\x02\x1c\x67\xbe\x78\x4c\x94\x39\x57\x7b\x2f\xb3\xd9\xed\x2d\x43"
+  "\xdb\x0f\xac\x03\x11\xd4\x0e\xb3\xfa\x6c\x04\xf5\xb3\x01\xbc\x87"
+  "\x75\xda\x82\xf2\xca\x79\xc5\x5e\x9a\xff\x78\xb2\x56\xe9\xa1\xce"
+  "\xb3\x97\xae\xff\xfa\x7b\x71\x1c\xaa\xa7\xc0\xf3\x7e\xd1\xa2\xd8"
+  "\xab\x67\x76\xbc\xb3\x13\xf0\x79\x50\x67\x22\x3c\x73\x02\x5f\xd4"
+  "\xa6\xc2\x7a\x70\xdd\x28\x5c\x8f\x75\xb8\x1e\x0b\x7d\x5e\xce\xae"
+  "\x57\x0b\x76\xc0\xb3\x71\x0e\xd7\xe3\x74\xf7\xa2\x5d\xae\x5a\x8b"
+  "\xef\x04\x6b\x59\x38\xae\x6b\x68\xf3\x67\x76\xf5\xb3\xe1\x42\xbd"
+  "\xe8\x0e\x45\xf5\x53\x97\x81\xaf\xe0\xfa\x44\x87\xfb\x27\xee\xcd"
+  "\x08\x27\xcf\x6c\xc0\x31\xad\x8e\x33\x7a\x5d\x8c\x66\xb6\x9c\xbd"
+  "\xb1\x74\x2c\x54\x67\xb5\x8e\xed\x19\x15\xd5\x1a\x68\x53\x6b\x06"
+  "\x59\x0f\xea\x44\xe2\x33\x1d\xc7\x3f\x29\x35\x75\x5e\xaa\x26\x6c"
+  "\xa6\x66\xe6\x9c\xe9\x9a\x37\xe6\x2d\x98\x9b\xf6\x64\xd8\xcc\xc1"
+  "\x84\x38\xf0\x8e\x8a\xcf\xf7\xe3\xb9\xe2\x88\x2a\x43\x29\xc8\x58"
+  "\x4a\x15\xac\xb7\xdd\xa4\x18\xe8\x6a\x5d\x1b\x5d\x64\x0b\x8a\xd6"
+  "\xd8\xd6\x86\x15\xe5\x5e\x21\xca\x1c\x35\x7f\x4a\x9f\xf9\x34\xd0"
+  "\xa0\xfa\x1c\xae\xf7\x06\x0d\x21\x2b\x80\x5f\xf5\x99\x5f\xc1\xb9"
+  "\x7d\x74\x0f\x8c\x21\x91\x9d\xfb\x4b\x4e\x8d\x72\x77\x4e\x93\xb2"
+  "\x36\xf1\x12\xd9\xab\x36\x91\x6a\xcd\x25\x52\x86\xe7\xb9\x06\xfa"
+  "\x6d\x06\xea\x4f\xc6\x67\xa1\x7d\x0b\xff\x67\xb6\xba\xea\xa3\xf8"
+  "\x1c\xcd\x5d\xf8\xcd\xa0\xfa\x38\x3e\x0f\xde\xaf\xd9\xab\x8c\x28"
+  "\x40\x9e\xf1\x85\x7a\xeb\xb8\x92\x88\x2a\x3a\xbf\x0b\xaa\x57\x58"
+  "\x95\xfe\x6f\x96\xaf\x21\x3e\x1b\xd7\x10\x52\x16\x40\xbc\x3b\x0b"
+  "\xf6\x2d\x33\x7a\xfb\x78\xe3\x78\x41\xd3\xbe\x97\x95\xe4\x57\x70"
+  "\xae\xd4\x48\x66\xa7\xe0\x39\x98\x57\x66\x77\x78\x81\xdf\xca\x2c"
+  "\x9b\xfc\x35\x5c\x60\xc4\x66\x1e\xc6\xc2\x12\xea\x1f\xeb\xa7\x03"
+  "\x7e\x81\x79\xc3\x0f\x8f\xd8\xdc\xa1\xf8\x47\xf1\xdf\xab\x08\xc9"
+  "\xc1\x79\x0a\xe3\xf1\xa7\xab\x16\x98\xaf\xd1\x45\x5b\xae\x9a\xa0"
+  "\x1c\xad\xf9\x24\xdd\xa2\x3c\x10\x5d\x45\x34\x2f\xa1\x3c\xf4\xf7"
+  "\x21\xff\x67\x26\x6f\x7d\x30\x16\x64\xc7\xd6\x3f\x93\x83\xcd\x35"
+  "\xc4\x37\x81\x78\xd9\xe3\xb7\xa7\x11\x65\x8c\x11\xca\x0b\x88\xb2"
+  "\x1e\x74\x79\xb4\xb7\xe7\x3c\x85\x36\xf7\x3a\x82\x76\x78\x5e\x99"
+  "\x12\xb8\xf5\x92\x05\x70\xa9\x6d\x00\xee\xf7\xe6\x54\x4b\x7d\xf0"
+  "\x9e\x69\x66\xe1\xfb\xd5\x65\xe1\xfb\xd5\x65\xfa\xfd\xca\x84\xdf"
+  "\xae\xf0\x9b\x55\x56\x22\xcf\xd9\xe6\x6b\x03\x62\x12\xbd\x78\x6c"
+  "\x13\xbf\x67\x0d\x01\xb9\x9f\x9f\xaf\x1d\xba\x2e\x95\x04\xd6\x9b"
+  "\xda\x88\xa1\xad\x86\x7c\x90\x4e\x02\xf9\xcb\xc9\x83\x6a\xab\x0f"
+  "\x10\x7e\x4d\x2e\xd9\x9e\xa3\x1f\x60\x43\x9b\xc7\x65\xf5\x60\xbf"
+  "\x25\x0a\xb4\xdd\x0f\x5d\x91\x4a\x46\x6f\xbc\x44\xc2\xa7\x9d\xce"
+  "\xa3\xb1\x9c\x30\xef\x9e\xf5\xb2\x56\x73\xed\xb2\x76\x44\xf7\x7c"
+  "\xed\xbd\x7e\x26\xf6\xbd\x6b\xca\x2c\x15\xc1\x6f\x5a\x7c\xc1\xff"
+  "\x8d\xdc\x88\x76\x67\xb3\x89\x58\xfd\x97\xfa\x20\x7f\xc2\x73\x83"
+  "\xf1\x1b\x49\xee\x22\xa2\xe2\xbe\xd3\x92\xba\x8e\x4b\xe4\x11\xe0"
+  "\x1b\xfc\x1e\x50\xde\xc2\xbe\x07\xd8\x56\x67\x47\xe2\x37\x81\xce"
+  "\xf9\x5a\xe5\xa4\x73\xb0\x5e\x15\xec\xab\xec\x0e\xf3\xd7\xec\xd3"
+  "\x1e\xc7\x35\x21\x5c\x9a\xf7\xff\x98\x7e\x7d\xf3\xfe\x1f\x89\x78"
+  "\x1f\x7e\x23\x03\x3a\x15\x6d\xb9\x84\x74\x03\xfa\x5d\x32\x29\x9f"
+  "\x6f\xe5\xad\x75\xad\x9f\x02\x7d\x9a\x64\xf4\xa1\xf4\x4c\xb5\x28"
+  "\xcf\xcc\x04\xba\x9c\x66\xb4\xaa\x35\x03\x9d\xf6\x60\x1b\x63\x2a"
+  "\xb7\x02\xad\x41\xe7\x51\xd6\x5a\x8e\xd3\x58\x14\x48\xaf\x2d\xdd"
+  "\x35\x03\xba\x03\x43\xc2\xf1\x5b\x63\x67\xa8\x7f\x54\x57\x71\xc4"
+  "\xf2\x6b\x81\x11\xa5\xbd\x7c\x77\x34\x21\xbd\xb2\x67\x11\x9f\xda"
+  "\xd6\xc3\x84\xd2\xec\x2d\x81\x66\xe8\x9f\xb6\x50\x3b\xd4\xda\xa9"
+  "\x0d\x58\x07\xb4\xaa\x4f\x33\x92\xf5\x97\x48\xa0\xa1\xad\x09\xbf"
+  "\xc9\x0c\x7a\xfe\x45\x42\x9e\xff\x84\xe7\xea\xaa\x8f\x51\xfa\x6d"
+  "\x03\xfa\x59\x81\x7e\xf8\x2d\xd2\x4e\xbf\x74\xa0\xdf\x55\xa0\xdf"
+  "\x39\x89\x7e\xb6\x4e\xa0\x5f\x27\xd0\x6f\x21\xd0\xcf\xdc\x83\x7e"
+  "\x3b\xf1\x7b\x25\x7e\x17\x42\xfa\xa1\x4f\x34\xb7\x50\x1b\x4c\xbf"
+  "\x53\xbe\xa1\x25\x1b\x67\x10\x9f\x87\x2c\x44\x91\xbb\x87\xa8\xa0"
+  "\x9f\xaa\xfb\x61\x7c\xa1\x3d\xe0\xef\x16\x62\xa8\xb2\x91\xc5\xaf"
+  "\x92\x7b\x91\x9e\x56\x81\x9e\x06\xeb\xe7\xe4\x6a\xa7\x56\x09\x6d"
+  "\x46\xae\xbb\x4a\xc6\x4d\x3c\xad\x21\xfb\xe2\xea\x08\xd0\x63\x22"
+  "\x57\x32\x26\xea\xfa\xe7\xe1\xc1\xe0\xfe\xcf\xc3\xfd\x25\xff\x3b"
+  "\x0f\xaf\x77\x1e\xee\x8f\x74\x3d\x0f\x0f\x9c\xbd\xbe\x79\x78\xa0"
+  "\xed\x7f\xe7\xe1\x4f\x69\x1e\x1e\x68\x74\x9e\x87\x76\x59\x21\x35"
+  "\x69\xce\xf4\x59\x73\x67\xcd\xfd\xad\x66\xc6\xa2\xb4\xa4\xf9\x4c"
+  "\x62\x90\xc9\x0c\x5a\x1b\x17\xa5\x7c\x0f\xd6\xd3\x83\xea\x26\xb2"
+  "\xfd\xae\x26\x25\xf7\xba\xda\x9b\x2f\x2a\x89\xe5\x8a\xde\x6f\x7a"
+  "\x0f\x64\x5f\x9c\xaf\xc5\x20\xd7\x9e\x51\x7c\xeb\xf3\x8f\x60\x90"
+  "\xf9\x52\xdb\x09\xfe\xcf\xe4\xa5\x57\x1a\x70\x6f\x61\xe9\x5a\xbe"
+  "\x0d\xf7\x16\x1e\x88\xc6\xb5\xbf\x6e\xd1\xed\xf1\xb0\xae\xbf\xae"
+  "\x26\x5d\xaf\xc7\x2b\xdf\x3d\x46\x7c\xfc\x9a\xc8\x44\x8e\xe3\x79"
+  "\x7d\x4e\x3b\xc8\x5a\x8d\xb1\xfa\xd7\xda\x89\x26\xd3\x07\xea\x7e"
+  "\xfd\x99\x26\x73\x09\x1e\x4b\x34\x99\x05\x27\xe1\x38\x99\xda\x37"
+  "\x82\xf8\x36\x7e\x6d\x04\xb1\x7d\x3c\x4c\x87\xdf\x14\x37\x06\xf1"
+  "\xad\xdb\x40\xb6\xdf\xd6\x6d\x51\x2e\xbd\x04\xfc\x91\x7f\x1f\x8f"
+  "\xdf\x06\xf1\xdb\xe3\xd2\x54\x18\x63\x90\x35\x99\x3c\x78\xe8\x73"
+  "\x9c\x2f\x2b\xd6\xf2\xad\xbb\xce\x34\x29\xf1\xdb\x28\xce\x21\xb3"
+  "\xaa\x4d\xb5\x0c\xde\x05\xfa\x69\x5c\x1f\xc4\x37\x9b\x86\x47\x54"
+  "\x79\x6b\x88\xb2\xb3\xa0\xae\x03\xe4\x92\x4d\x28\x53\x2c\x87\x6b"
+  "\xef\xc2\x35\xf6\x9d\xee\x90\x8e\x1f\x58\x5b\x85\xb8\x05\xfc\xab"
+  "\x38\xaf\xa8\x1f\xd3\x05\xef\xb9\x82\xe9\x02\x6d\x96\x92\x88\x52"
+  "\xeb\x47\xfe\x51\x56\x94\xe3\xc2\xfc\x63\xbb\x87\x47\x2c\xb7\x96"
+  "\x44\x6c\x9e\xfc\x00\xfd\x1e\x0d\xf5\x0d\x57\xf0\x3d\xae\x05\x86"
+  "\x15\x41\x7d\xf3\xe5\xc0\xe8\xa2\xcb\xc5\xd1\x9a\x03\x19\x95\x02"
+  "\x9e\xd5\x27\x3d\x5f\x2a\xe0\x59\x29\xcc\x97\x78\xc0\xb3\xf8\x9e"
+  "\x78\xc6\xbe\xdf\xdb\x08\xc3\xb5\x3a\x02\x6d\xb5\xe2\x7c\x41\xd9"
+  "\x70\x2b\x8c\x05\xce\x05\xe4\x79\x8a\x6f\x80\x6d\xe2\xbc\xc0\x39"
+  "\x83\x18\x46\xe7\xa8\xd3\x1c\xc1\x79\x71\xbb\x89\xa8\x70\x5e\x20"
+  "\xc6\xe1\xbc\x40\xbf\x98\xf7\xae\xb2\x79\xe1\xd7\x4c\x54\x74\x6e"
+  "\x58\x6b\xe8\xdc\x40\xbd\xa0\xd6\xea\x84\x6b\x0e\xf3\x62\xa5\x38"
+  "\x2f\x44\x5c\x03\xde\xb7\xe2\xbc\x58\x28\x9f\x17\xaf\x1f\x57\x11"
+  "\x8a\x79\x05\x9f\xef\x2c\x83\x79\x51\xaf\x33\x11\x9b\x88\x6b\x30"
+  "\x2f\x70\xdf\x0e\xc5\xb5\xdf\x09\xb8\x66\x82\xf3\x30\x1f\xca\x67"
+  "\xcb\x71\xad\xab\xb3\x2f\xf9\xc2\xb0\xe7\xfa\x70\xcd\x40\x75\x08"
+  "\xa4\x15\xd2\x0d\xe9\x85\x34\xfa\x77\xa2\x0f\xe2\x96\x4d\xe5\x06"
+  "\xb7\x5c\xd0\x07\xf8\xb9\x03\xfe\xef\x41\x23\xbe\x60\x87\xb7\x23"
+  "\x76\x21\x66\x21\x7e\x21\x6e\x21\x86\xe1\x3c\x40\xec\xa2\xb8\x05"
+  "\x98\x0e\xe5\xb6\xba\xe4\x16\x8a\x69\xb9\xa7\x89\x2a\x77\x3c\xb9"
+  "\x17\x31\xcc\x60\xbd\x42\x10\xd3\x28\xfd\xfc\x25\xfa\x21\x86\xad"
+  "\x4f\x27\xe3\x26\xcd\xd2\x10\xc4\x2e\x18\xfb\x2d\xfb\xb4\x87\x09"
+  "\xd5\x07\xf2\x87\xfd\x6a\x63\x00\xcc\xdb\x35\xc4\xbb\x38\x80\xf8"
+  "\x74\x16\x1c\x2a\xea\xa9\x0b\x1c\xda\x24\xea\x02\x38\x67\x71\xee"
+  "\x1a\x15\xf5\x54\x87\xd3\xdf\x35\x16\x31\xa8\x8a\x7d\x97\x7e\xd4"
+  "\xc8\x6c\xe3\xdf\xb2\xdc\x0a\xa0\x47\x4b\x3a\xf4\xa1\x8b\xec\x7b"
+  "\x38\xe8\xcc\xc3\x43\xdb\xf8\xd5\x6d\x6a\x1c\x4b\x7c\xb7\x69\x0f"
+  "\x00\xcf\x95\x8c\xd1\xad\xc2\xf1\x29\x01\x7d\xbc\x64\x4c\x86\xc4"
+  "\x5f\x5f\x87\xec\xcb\x20\x64\x72\x86\xa7\xfc\xf5\xb5\x86\xf6\xe1"
+  "\x9f\xf1\xc3\xf8\xd7\xe3\xbd\xb9\x7f\xc6\x0f\x00\x5e\x50\xcf\xb3"
+  "\xe5\x91\xab\x45\xaf\xd4\xe4\x5a\xf9\x36\x4d\x26\x79\x10\x30\x70"
+  "\xc9\x01\xd0\xbf\x0f\xa4\x11\x62\x88\x4d\x01\xba\xbe\x32\x61\x3b"
+  "\x67\xf2\x36\x2a\xea\x32\x36\xc2\x38\x03\xb6\x7a\x3b\x62\x2b\xc3"
+  "\xd1\x3a\x9a\x03\xc0\x52\xf4\x4a\x13\xb6\x15\x53\x43\xfc\x34\xcf"
+  "\xa2\xbf\x5d\x63\xc8\xa2\x6c\x82\x7b\x48\x07\x9c\x51\x7c\x73\xae"
+  "\x6b\xcd\xa8\x09\x70\xff\x50\xfe\x9f\x71\x0a\xdd\xb3\xb0\xbe\xbc"
+  "\x1e\xa7\xc0\xef\xff\x9f\xe6\x94\x2a\x39\x38\xc7\xfc\x89\x4a\x09"
+  "\x5e\x5f\xd1\xed\x4d\xe5\x28\x0e\xea\xd4\x9b\x4b\xc9\x8a\x74\x1f"
+  "\x82\xf5\x99\x8f\x5a\x29\xc1\xfa\x2b\x53\x55\xd4\x7f\x80\xde\x67"
+  "\x2d\x25\x78\xaf\x0d\xce\xff\x27\xe7\x4b\x0a\x33\x03\xc9\x81\xd8"
+  "\x7a\xda\xc6\x81\xd8\xbf\x13\x6c\x03\x78\x1e\xfe\xdf\x45\x56\xa5"
+  "\xab\x61\x8e\x97\xc2\xf5\x23\x64\xd5\xf9\x60\x38\x9e\x81\xdf\x55"
+  "\xd2\xae\xf8\xa6\xe8\x40\x2c\x47\xfc\x96\xfc\x8a\x07\xde\xe5\x0d"
+  "\xb8\x2f\x31\x87\x0c\x84\xbe\xaf\x33\x34\x15\xc1\x5a\xf7\x75\x1e"
+  "\xee\x5b\xe7\x73\x5f\xef\xe0\xf8\xd7\xcf\x71\xb9\xaf\x9f\xc7\x67"
+  "\xdb\xf8\xd7\x2f\xe0\xb3\x57\x66\x6a\x04\x9f\xd5\x52\xea\x5f\xb7"
+  "\xe2\x6a\x28\xc1\xbe\xe2\x73\xf1\x79\xab\x52\xb5\xc2\x33\x47\xd3"
+  "\xbe\xe1\x33\xb1\x4d\xc7\x67\x62\x4e\x78\xcd\x2b\xf8\xcc\xc6\x21"
+  "\x70\xf4\x07\x7a\x2c\x43\x3a\xe0\xf3\x39\x3e\x7e\x00\x9f\x1b\xef"
+  "\x45\xef\xc9\x68\x73\x75\xcf\x53\xc2\x3d\xcc\xaf\x0e\xee\xe9\x66"
+  "\xf5\x69\x1b\xb0\xf6\x4d\xc1\xf3\x3f\x8b\xd7\x93\x9e\x34\x6c\xec"
+  "\x62\x6b\x61\xe3\x7e\xb6\x16\x32\x9a\x52\x5e\x79\x3d\x7e\x00\xd0"
+  "\x4d\x85\xeb\x26\xb4\xf1\xa1\xbd\x8d\x7f\xc6\x7b\x21\xbd\x91\x6f"
+  "\x44\x5e\x42\x3e\x12\x79\x88\xf6\x53\x47\x88\x23\xcf\xc0\xff\x3e"
+  "\x42\x3b\x67\xc5\x76\xa0\x0f\x44\xe4\xa3\x9f\xc1\xf5\x9e\x7c\x74"
+  "\x64\x8f\xc4\x47\x47\xa6\x5b\x72\x78\x1e\xf9\x48\xff\x5a\x3e\xb4"
+  "\x73\xf8\x51\xa9\x3f\x71\x0a\xe4\xb1\x7f\x33\xde\x2a\x42\x3a\xfd"
+  "\x2c\x8b\x04\xb2\xf7\x39\x42\xf3\xe7\xfe\x2c\x4b\x1f\x88\x7d\x15"
+  "\xdf\x03\xfb\x50\xc8\x69\x88\xf8\x1e\xab\xba\x43\xa1\xdd\xf3\x44"
+  "\xb8\xe7\x09\x6c\x5b\x1c\x03\xa0\x19\x11\xef\x11\xeb\x17\x72\x5a"
+  "\xe8\xf7\x68\x7a\x0f\xe3\xb9\x33\x2e\xf8\xe7\xc8\x12\x67\x9e\xbb"
+  "\x3d\x8b\x80\x20\x0b\xb2\xd3\x6b\x97\xf0\x39\x1b\x58\xdf\x76\xdb"
+  "\xba\xe1\x19\x40\x03\xa5\x70\xfe\x73\x07\x9e\x10\xda\xb7\xb8\x6a"
+  "\xff\x94\xac\xfd\x78\x68\x3f\x03\xda\x47\xd9\xec\x35\xb4\x83\x1d"
+  "\xa1\x39\xb0\x7f\x96\xc1\xda\x17\xf9\x96\x2f\x1a\xa9\xd6\x65\xa2"
+  "\x8f\xe7\xb7\x9b\x18\x9e\xd6\x85\x60\x3d\xea\x5b\xa4\xe4\x2a\x38"
+  "\x27\xdf\x22\x47\xdf\xb3\xed\x39\x26\xc1\xaf\xe8\xdb\xb7\xb1\x0e"
+  "\xe0\xab\x19\x65\xcc\xad\x20\x9f\x49\xbe\x45\xc7\xf0\xfa\x4a\x7d"
+  "\x7a\x8b\x83\x6f\xd1\xb7\x54\xdf\x37\x2a\xbe\xad\x02\x5d\x52\x09"
+  "\xe5\x34\x76\xbe\x4e\xe3\x78\x5e\xf2\xdd\x63\xe7\xd1\x2f\x5a\xb0"
+  "\xbd\x76\xec\xad\x42\xdb\xdb\xb7\x0d\xa2\xbd\xd3\x8d\xae\xea\x81"
+  "\x0c\xdc\x12\x2a\xc9\xc0\x2d\xa1\xee\x65\xe0\xa6\xec\xde\x65\xe0"
+  "\x93\x29\x92\x0c\x7c\xbc\x8e\xcd\xfb\xe3\x9f\xb1\x79\x7f\x9c\xc6"
+  "\x43\x2e\x84\xf6\xac\x7f\x88\xc9\xe3\x3f\x0e\x50\x21\x9f\x97\x83"
+  "\x4c\xbb\x3d\xbd\x46\xb9\x15\xf4\x64\x9b\xf2\x3e\x7e\x29\x8c\x1d"
+  "\xc6\x54\x5b\x9a\x09\xeb\xb4\xb5\x91\xd4\x7b\xa3\x0c\x8c\x3e\x5a"
+  "\xcd\x87\xea\x3b\x2c\x04\xd6\x39\x13\x1b\x97\xa6\xa3\x40\x0b\x2f"
+  "\x83\xc5\x42\x68\x3d\xb8\x06\xeb\x5a\x2b\xca\xc0\xbb\xb8\x1a\x65"
+  "\x39\x8c\x29\xfc\xbc\xcd\x81\x31\xb1\x8e\x32\x72\x67\xc1\x51\x1f"
+  "\xd7\xb2\x71\xf3\x0a\x6b\x81\xa3\x6c\x7c\x74\x32\xca\xc6\x68\x23"
+  "\x47\x39\x80\x63\x32\x71\x14\xc8\xc7\xb1\x28\x27\xa3\x6c\xcc\xc9"
+  "\x64\xe3\x7f\xfa\xf7\x2e\x1b\x1f\x5d\xf2\xbf\xb2\xf1\x0f\x95\x8d"
+  "\xdd\xe9\xfc\xc7\x8e\x5f\x9f\x6c\x7c\xac\xf9\x7f\x65\xe3\x5b\x25"
+  "\x1b\x1f\xab\x11\x65\x63\x2e\x7f\xd8\x83\x65\x6b\x60\xbe\xda\x65"
+  "\xe3\xe6\x2d\x3d\x65\xe3\x66\x7d\x4f\xd9\xf8\x68\xb0\x24\x1b\x37"
+  "\xed\x94\xcb\xc6\x2d\x87\x7b\xca\xc6\xc7\x87\xb8\x93\x8d\x01\x97"
+  "\x3a\x50\x36\x46\x9e\x42\x39\x19\xe5\x63\xe8\x67\x06\xe3\xaf\xe3"
+  "\x4f\x5e\x9f\x6c\x7c\x7c\x5c\xff\x64\xe3\xe3\x1b\x5c\xcb\xc6\x4d"
+  "\x59\xee\x65\xe3\xa6\x2c\xd7\xb2\xf1\xc9\x27\x25\x99\xe6\xe4\xa0"
+  "\x9f\xbe\x6c\x7c\x62\x8b\x6b\xf9\xe5\xc4\xe7\x4c\x36\x3e\x5e\x76"
+  "\xe3\x65\xe3\xe3\x65\xae\x65\xe3\x93\x0f\x30\x39\xe2\x78\x45\x4f"
+  "\xd9\x18\xee\x71\x29\x1b\x9f\x9c\x22\xdc\x53\x26\x97\x8d\x59\x1b"
+  "\xb0\x26\x2e\x72\x2f\x1b\x1b\x87\xb3\x35\xf2\xe4\x69\xb6\x46\x32"
+  "\x9a\xf6\x94\x8d\x4f\x7e\xd9\xb7\x6c\xcc\x78\x88\xf6\xd3\xad\x6c"
+  "\x6c\x1c\xd0\x53\x36\x6e\xca\x72\x2d\x1b\x9f\x3a\x2e\xf1\xd1\xa9"
+  "\x6c\xb9\x6c\x6c\x9c\xf4\xef\x21\x1b\xbb\xe5\xad\x2d\x72\xd9\xf8"
+  "\xd4\x3d\x9e\xcb\xc6\xa7\x5e\xf4\x4c\x36\x46\x9e\x73\x25\x1b\x9f"
+  "\xda\xe0\xcc\x73\x72\xd9\xf8\xd4\x17\xae\x65\xe3\x53\x87\xe4\xb2"
+  "\x31\xb6\xef\x4a\x36\x3e\x65\x93\xb5\xdf\x43\x36\x6e\xb9\x53\x2e"
+  "\x1b\xb3\x7a\x92\x6c\xdc\xa2\x17\xe4\xad\x30\xcf\x65\xe3\x96\x0f"
+  "\x7b\x97\x8d\x5b\x3e\x91\xcb\xc6\x2d\x59\x4c\x06\x6e\x69\x64\xb2"
+  "\x71\x4b\x11\x3b\xdf\x14\xea\x78\x5e\x92\x8d\xd9\xf9\x9e\xb2\x71"
+  "\x4b\x47\x1f\xb2\x71\x54\xff\x65\xe3\x73\xd6\x1a\xbb\x6c\x7c\xce"
+  "\x2a\xca\xc6\x98\xe3\xa7\x0c\xe4\xcd\x32\x2a\x1f\x1f\x20\x07\x66"
+  "\x62\x7f\xbe\xdb\xd0\xbb\x7c\xfc\xaf\xd1\x92\x7c\x7c\x36\x9b\xcd"
+  "\xfd\xb3\xd3\xd9\xdc\x3f\x1b\x62\xb7\x11\x83\x6c\x8c\x32\xb2\x60"
+  "\x23\x6e\x5c\x01\xbf\xed\x99\x35\x54\x3e\x46\xff\x75\x94\x91\x51"
+  "\x3e\x46\x39\x19\x65\xdf\xba\x65\x84\xd4\x9b\x2c\xe8\xd3\xd1\xa0"
+  "\xbf\x17\xc7\xf5\xec\x10\x90\xab\x8d\xb0\xb6\x35\xc0\xbd\xc6\xed"
+  "\x97\x2c\xb8\x17\xa2\xb9\xb0\x05\xee\x31\xb2\x7b\xe0\x7a\x13\xde"
+  "\x03\x75\x9a\x19\x2d\xda\x66\xb1\xf5\x53\x94\xaf\x5b\xc7\xc8\xe4"
+  "\x6b\x56\xb7\x51\x94\xaf\x37\x40\x1f\xe0\xe7\x8d\xb2\x35\xca\xd8"
+  "\x20\x5b\xd7\x6e\x58\xcb\xd7\x94\x07\xf1\xd5\x9d\x05\xad\x29\xa2"
+  "\x8c\xbd\x12\xce\x15\xc2\x39\xe8\x47\x43\x75\x05\x21\x5f\x5e\xd2"
+  "\xa3\xec\x60\xdc\x70\x86\x78\x03\xcd\x9a\x96\xc2\xf3\xf1\x7e\xb8"
+  "\xa7\x42\xbc\x07\xd6\xf7\x5a\x26\x93\xb7\x69\x39\x99\xbd\xba\xf5"
+  "\x9c\x5d\x26\x87\x71\x42\x7b\x38\xe6\xce\xa2\x72\x79\x98\x7f\xac"
+  "\x55\x94\xcb\x87\x3b\xca\xe5\x67\x3e\x11\xe5\x72\xdc\x83\x64\x97"
+  "\xcb\xd3\x44\xb9\xfc\xf4\x9d\xd7\x29\x97\x37\xfe\x54\xe4\x72\x5f"
+  "\x85\xc2\xdb\x37\x91\xc9\xe5\x65\xe9\x37\x46\x2e\x47\x99\x1c\xe5"
+  "\x70\x94\xc9\x51\x46\x47\xb9\x1c\x65\x74\x4e\x90\xcb\xcb\x1d\xe4"
+  "\x72\xce\x41\x2e\xe7\x64\x72\xf9\x99\x05\xd7\x27\x97\x9f\x49\xbb"
+  "\x01\x72\xf9\x2d\xa5\xcf\xad\x90\xcb\xb5\x4e\x72\x39\xca\xe1\x30"
+  "\xf7\x5a\x51\x3e\x37\xe8\x61\x6c\xde\x02\x19\x1d\xe4\xf3\xbe\x65"
+  "\xf3\x33\x89\x8e\xb2\x79\x79\x80\xa3\x6c\xde\x36\xa1\xa7\x6c\xde"
+  "\x96\xe0\x20\x9b\xd7\x1a\x15\xad\x95\x14\xf7\x61\x7e\xeb\x67\xa0"
+  "\xdc\xdd\x1a\x2c\x97\xcd\xcf\x6f\xed\x29\x9b\xb7\x7d\xe2\x52\x36"
+  "\x67\xfa\xb7\x5c\x36\x1f\x3e\x26\xcd\x6a\x97\xcd\xdb\x8e\x5e\x9f"
+  "\x6c\xde\xd6\x24\xe9\x0e\xdf\xb5\xb1\xf5\xa5\x2d\xc3\x9d\xbc\xde"
+  "\xa9\x72\x94\xd7\xcf\x4e\x92\xe4\xf5\x34\x07\x79\xfd\xbb\x32\xf7"
+  "\xf2\xfa\x77\x54\x3e\xe4\x54\xaf\x34\x61\x5b\x28\x67\x01\x56\xb6"
+  "\x6a\x52\x51\xd6\x6a\xb7\xa1\xac\x05\xf8\xd4\x8a\x7e\xd1\x50\xde"
+  "\x2f\xca\xed\x54\xbf\x44\xd9\x3d\xf3\xa7\x28\x5f\xb5\x27\xbb\x96"
+  "\xaf\xda\x17\xa0\x1c\xc3\xf6\x9c\x9e\x9d\x08\x63\xf2\xff\xd8\xfb"
+  "\xfe\xb8\x28\xea\xfc\xff\x37\xb3\xab\xae\x86\xb0\x28\x78\x58\x68"
+  "\x0b\xac\xb6\x16\x26\x16\x75\x5a\x7a\xa9\xa7\x17\x76\x2a\x58\xea"
+  "\xe1\xaf\x44\x05\x0f\x0d\x09\x15\x15\x8d\x5f\x9a\x1a\x2a\x22\x16"
+  "\x98\x16\x8a\x76\xd8\xe9\x9d\x1a\xf5\xd1\x3b\xeb\x34\xb1\xf4\x0e"
+  "\x0b\x01\x3b\xbd\xa3\x4e\xaf\xcd\xc8\x03\x43\x5d\x11\x65\x81\xdd"
+  "\x9d\xef\xeb\x3d\xef\x59\x66\x67\x77\x66\xd9\x99\x45\x82\xbe\xfe"
+  "\xb1\x0f\x71\xe6\x3d\xef\x79\xcf\xeb\xf9\x7c\xbf\xdf\xcf\xe7\x7b"
+  "\xde\xf3\x7e\x57\xb5\xad\x7e\xaf\x99\x20\xac\xdf\xaf\xd5\x10\xad"
+  "\x53\x13\x89\x71\xe1\xeb\x77\xb8\x46\x50\xbf\xff\xd8\x8f\xbd\x66"
+  "\x02\x5f\xbf\x93\x3c\xa0\xcf\x1e\x2e\xae\xdf\x7f\xbc\x48\xfa\xf0"
+  "\x1f\xf7\x91\x3e\x9c\x60\xec\xa8\xdf\x7f\x4c\xb5\xd5\xef\x18\x7f"
+  "\x47\xfd\x4e\x38\xc5\x94\x53\x54\xbf\xff\x78\xc6\x51\xbf\x7f\x9f"
+  "\x8f\xf5\xbb\xc9\x86\x57\xf9\x98\x57\xf3\x30\xaf\xae\x1f\xc5\xbc"
+  "\xc2\xfd\xa4\x66\x01\xe6\xd5\xf5\xa9\x46\x8b\x55\xc7\x6f\x82\xfc"
+  "\x6a\xfd\xec\x75\x3c\x6e\x2f\x9c\xf1\x2c\x71\x29\xea\x8f\xb9\x86"
+  "\x79\x66\xc5\x0d\xa7\xc7\x7c\xbb\xb7\x5c\xab\xbd\x20\xcc\xb5\xda"
+  "\xef\x18\x9c\x59\xae\xe1\xf1\x44\xa2\xeb\x99\xe7\xbb\x23\x4d\xd7"
+  "\xe3\x6b\xae\x0f\x92\xa6\xeb\x31\x17\x85\x74\xfd\xf5\xe5\xf6\x5c"
+  "\xe4\xeb\xfa\xeb\xdb\x84\x75\xfd\xf5\x03\x7c\x5d\x8f\xf3\x17\xd2"
+  "\xf5\xd7\x2f\xf2\xf2\x77\xd0\xf5\xd7\x6f\xf1\x75\x3d\x49\xc7\xe9"
+  "\xfa\x1b\x3b\x48\x5b\xfc\xfd\x68\xe9\xba\xfe\xc6\x2a\xb6\x7d\x27"
+  "\xba\xfe\x8a\xbd\xae\xbf\xb1\x86\xaf\xeb\x6f\x4c\x21\xed\xeb\x8d"
+  "\x83\x46\x46\xd7\xdf\x88\x23\xc7\xbf\x1f\x65\x7b\x9c\xd3\xf5\xe4"
+  "\xb8\xd1\x56\xd7\x17\x63\x5d\x7f\xe3\x74\x2b\xba\x3e\xd2\x75\x5d"
+  "\xdf\x34\x96\xd3\xf5\x4d\x63\x9d\xeb\xfa\x9b\xcb\x9d\xeb\xfa\x86"
+  "\x0c\x4e\xd7\xdf\x39\x4f\xda\x84\x3b\x47\x49\x9b\x70\x87\xd1\x40"
+  "\x50\xaf\xb8\x71\xef\x25\xcc\x1c\xeb\x92\xc3\x75\x25\xd4\x07\x4b"
+  "\xd9\x71\xef\xbb\xa0\xe9\x57\x80\x3e\xaf\x27\xfa\x1c\xda\xcc\xd3"
+  "\x58\xd7\x63\xfd\x4d\x34\xfd\x9d\xb9\x70\x4c\x0f\x31\x3f\x0d\x79"
+  "\xe9\x0f\xae\x2e\xa6\xf0\xdc\x2a\x9c\x16\xea\x7b\x65\x16\xf4\x23"
+  "\x70\xbc\x12\xd2\x14\xe3\x6b\xe0\xd8\x85\xe2\xa5\xcc\x75\x13\xb1"
+  "\xf6\x87\xeb\x8a\xe1\xfc\x25\xbb\xeb\x2a\xf0\x75\x65\xc9\x8c\xb6"
+  "\xaf\x20\xd8\xd5\x1f\x82\xe3\xa5\x9c\x0f\x30\x8c\x66\x7c\x40\x3d"
+  "\xeb\x03\x20\x2d\xe4\x55\xc2\xf8\x80\x79\xe0\x03\xa0\xdc\xf0\xb3"
+  "\xf5\x01\xc7\xc1\x07\x1c\x03\xdf\x72\xa4\x61\x83\x21\xc9\xc6\x07"
+  "\x1c\xc3\xba\x1f\x7b\x00\xac\xfd\xa1\x5f\x3b\x82\x7d\xc1\x89\x26"
+  "\x3d\x05\x18\x5f\x00\x1f\x50\x89\xaf\xb7\xb9\xb6\xc8\xf6\x5a\x9c"
+  "\x1e\xca\x58\xcc\x78\x08\xd0\x73\x50\x86\x4b\xbb\xae\x30\x1e\xa2"
+  "\x14\xae\xad\x20\x1e\xc2\x50\x65\xe3\x21\x8e\x13\x0f\x51\x1f\xcf"
+  "\x1f\xd7\xbf\x35\x54\xba\x87\xa8\xbb\xee\x7c\x6c\xff\xd6\x6c\x29"
+  "\x1e\x02\x9e\xbb\xc4\xaa\x53\x1d\xe6\xf1\xe1\x79\xe6\xa0\x55\xb1"
+  "\x2e\x75\x3a\x1f\x8c\xd5\xac\x58\xa3\x62\x7d\x8a\x75\xaa\x4b\x1a"
+  "\x15\xca\x5f\x6a\x6c\xc3\xb1\xfd\xae\xe0\x21\x56\x88\x7b\x08\xab"
+  "\x7f\x60\xc6\xf4\x59\x0f\x01\x75\x8c\xf1\x10\xf9\x6b\x6d\x3c\x44"
+  "\x57\x1b\x0f\xe1\x61\xeb\x21\xea\x3e\x96\xe7\x21\xea\x8e\xb5\x81"
+  "\x87\x28\xb9\xef\x21\xe4\x7a\x88\xba\xc2\x16\x0f\x41\xb1\xe3\xfb"
+  "\xbd\xac\x1e\xa2\x3e\xcb\xd1\x43\xd4\xef\xb1\xf1\x10\xc7\xf5\x1e"
+  "\x86\x7a\x46\x9f\x33\xfe\xc1\xa0\xe5\xfb\x87\xa6\x3b\x8e\xfe\xa1"
+  "\xbe\x46\x9e\x7f\xb8\xd3\x57\x9e\x7f\xb8\xe3\x4f\xca\x87\xdf\x4d"
+  "\xde\xac\x27\xfd\x58\xfd\x31\xce\x53\xdc\x3c\x6e\x7b\xac\x75\x4f"
+  "\x71\x67\xaf\xb0\xa7\xb8\x99\x24\xee\x29\x6e\x26\x89\x7b\x8a\x86"
+  "\xc9\x58\xfb\x61\xff\x00\xf9\x83\xf6\x6b\xe8\x67\xfb\x2e\x20\xab"
+  "\x15\x9d\x67\xef\x27\x12\xe7\x11\xff\x71\xef\x75\xde\xdd\xe3\xc2"
+  "\x3a\xef\xee\x59\xac\xa1\x4c\x8c\xce\xbb\xb3\x27\xbf\xcd\x3d\xc5"
+  "\x9d\x3d\xc2\x9e\xa2\x61\x24\xd1\x59\x77\x0a\x1d\x3d\x05\x5c\x23"
+  "\xe8\x29\x1a\x96\xb0\xd7\xec\xe1\x7b\x0a\x92\x07\xe8\x85\x2d\xe2"
+  "\x9e\xc2\x38\x88\xe8\x87\x86\x46\xa2\x1f\x08\xc6\x8e\x9e\xa2\xc1"
+  "\x76\xfc\x57\xc4\x53\x10\x4e\x31\xe5\x14\xf5\x14\xc6\xbe\x8e\x9e"
+  "\xe2\x66\x12\xf6\x14\xc2\xbc\x6a\x34\xf3\x79\xd5\xb8\x8b\xef\x29"
+  "\x8c\x0b\xed\x3d\x45\x27\xe4\xda\x71\xee\xfd\x00\x7e\xa6\xc6\x91"
+  "\xd2\x7d\x44\xe3\x12\x69\x3e\x02\xf3\x4f\xc8\x47\x34\x9e\xb0\xe7"
+  "\x1f\xdf\x47\x34\x7e\x2d\xec\x23\x1a\x6f\xf1\x7d\x04\xce\x5f\xc8"
+  "\x47\x34\xf5\xe3\xe5\xef\xe0\x23\x9a\x86\xf3\x7d\x04\x49\xc7\xf9"
+  "\x88\x26\xb6\x4d\xbe\xd9\x57\xba\x8f\x68\x3a\xe5\xdc\x47\x34\x9d"
+  "\xe5\xfb\x88\xa6\x7c\xd2\xa6\x36\xd5\x13\x1f\xd1\x54\x44\x8e\xdf"
+  "\xf4\xb7\x3d\xce\xf9\x08\x72\xdc\xd1\x47\x34\x7b\xb6\xe2\x23\x3c"
+  "\x4d\x85\x3e\xa3\x9a\xb4\x3e\x91\xcd\xbe\x63\x13\x1f\xab\x7a\xce"
+  "\xdc\xb2\x67\x40\x34\x68\x85\x4b\xa0\x1d\xe6\x22\x0a\x7f\x77\x9f"
+  "\x76\x1e\x34\xc1\x5c\x32\xdf\x1f\xeb\x82\xc3\x2b\xb0\x8e\x2b\xee"
+  "\x82\xd7\x38\x6c\xca\x0d\x0c\x35\x85\xf8\x46\x63\x7d\xd0\x58\xe8"
+  "\xa3\x31\xe6\x86\x65\x36\xe2\xb9\xfe\xf1\x88\x9a\x53\x2b\xac\xed"
+  "\x5e\xbb\x44\x5b\x80\xf3\xaa\x88\x59\x44\xd7\x9d\x8b\xfb\x81\xe1"
+  "\x31\xd6\x0c\xf8\x7b\x8c\xf2\xfa\x4a\x46\x43\x78\x46\x8f\x42\xf9"
+  "\x69\xc8\xb7\x67\x2d\x52\xf7\xf4\xf0\xe8\xfa\xc2\x45\x84\xcc\xa0"
+  "\x1f\xc6\x0d\xa2\x2d\x8f\xc5\x8c\xc2\xeb\xec\x78\x11\x0d\x71\xac"
+  "\x8b\x89\xd5\x10\x9b\xef\xa2\x90\x5d\x78\x7c\xf8\x1c\xa7\x1d\x1a"
+  "\xad\xda\xce\x46\x37\xcc\xbe\xae\x46\xbb\xd6\xf2\xe7\xfa\x37\x6f"
+  "\xe3\x74\x03\xd6\x0c\xf4\x1c\xd0\x76\x46\x32\x5f\x63\xf5\x64\x32"
+  "\xd7\x3f\xa4\x0a\x51\x05\x2f\x23\x55\x69\xf4\x15\x3c\xf6\xe3\x5f"
+  "\x5a\xb5\x0f\xad\x1a\x8f\xfa\x9b\xb0\x4e\x00\xad\x57\x5a\x95\x87"
+  "\xf0\x1a\x82\xf9\xa0\x15\x76\xdc\x45\x23\x70\x7f\x3c\x61\x2e\xd1"
+  "\x0b\xa4\x2f\x36\xed\x3b\xa3\x3b\x83\xa4\x6b\x3d\x13\xb3\x7e\x80"
+  "\xe8\xb7\xb6\x85\xa0\xeb\xb5\x3e\x1a\x33\x60\x49\xd6\x8e\x1c\x5e"
+  "\x64\x79\x2f\x32\xe7\x30\xf0\xf0\xcf\x57\xaa\x3d\xf0\x3a\xd8\x78"
+  "\x4f\x48\xcb\x41\xdf\x68\x1e\x36\xcd\x2c\x36\xcd\x04\x1b\x8c\xcb"
+  "\xcb\x89\x08\xaf\x39\xe8\x85\x31\x29\x37\x56\x22\xcb\x6b\xd6\x7d"
+  "\x21\x43\xd1\x6e\x0b\xc1\xc3\xdc\x1c\xd7\xdd\x02\xb1\xc7\x6b\x6b"
+  "\x01\x1f\x18\x0d\x97\x85\xf7\x8a\x5c\xe3\xd1\x13\x6b\x38\xe0\x77"
+  "\x8f\x82\x26\xc0\xe1\x3b\x82\x03\xbd\x56\xcd\xfc\x6b\x7a\x4d\xa7"
+  "\x81\xbc\x83\x9a\x9b\x01\x0b\xa3\x03\x16\xc3\xf0\x9e\x92\x78\xdd"
+  "\x3b\xd3\x36\xb2\xb6\x1f\x83\xc5\x6b\xba\x00\xbc\x2e\x06\xf3\xbd"
+  "\x4c\xb3\x0e\xb7\x97\xea\xdd\x57\xf1\x77\x3e\x04\x03\x33\x1b\x7b"
+  "\xbc\xbf\x24\x8e\x37\xd6\x67\xe5\xa0\xcb\x98\xef\x57\x36\x34\x6b"
+  "\x9a\xf7\xf9\x68\xf0\x5c\x9a\x1b\x1e\x16\x99\xf3\x7f\x2d\x9a\x9f"
+  "\x3e\xf6\x9a\x4e\x18\x7b\x53\x2d\x17\x7b\x7a\x97\xbc\xd8\xd3\xf9"
+  "\x3f\x7d\xec\xd5\x9d\x30\xf6\x96\xb8\x96\xd8\x53\x1e\xf2\xf4\x3f"
+  "\xe5\xe1\xef\x2c\xf6\x78\x1c\xca\x3a\x06\x65\x1d\x7f\xc2\x7d\x1c"
+  "\xe3\x55\x28\x55\x45\xcb\x7c\x4b\xf8\xdb\x76\xbe\xe5\x97\xa7\xf1"
+  "\xf7\xe7\xec\x7c\x4b\xca\xe3\xba\xd3\x71\x27\xaa\xab\x7f\xcb\xb8"
+  "\x13\xa5\x5c\xc5\xe8\x46\x4a\x39\x9b\xd1\x8d\x94\x92\x99\xd3\x90"
+  "\x7a\x19\x51\xa6\x81\xbd\x13\x0f\x27\x14\x53\xf8\xdb\xa3\xc3\x37"
+  "\x8c\x54\x56\x1d\xe8\x40\xea\x61\x1a\x8f\x03\x6d\x59\x8a\x98\xf5"
+  "\xf2\x12\x17\xa0\x87\xaf\x51\x8a\x3c\xbc\x96\xd8\xa7\x37\x8a\xa9"
+  "\x1c\x9c\x26\x28\x32\xe7\xe0\x83\x06\x0f\xdc\xb7\x1d\x4e\x30\x52"
+  "\x56\xbe\x58\xbf\x31\x84\x18\x46\x9a\xfd\xc6\x26\xde\xde\xe7\x33"
+  "\xca\x3a\x27\xd2\x74\xc8\x37\x5a\x90\x43\xf8\xdb\x45\xe0\x11\xe6"
+  "\x0c\xfe\xd6\xd0\xca\x27\xcc\xa3\x32\x63\x35\xc2\x7b\xe5\x78\x57"
+  "\x23\x35\x0d\x1c\x9a\x79\x00\xf0\xb5\xe5\x51\x8e\x08\x8f\x76\xf2"
+  "\x79\x74\x9b\xe5\x11\xf0\x89\xe3\x51\xcb\x77\x6b\x47\x8f\x4b\xe2"
+  "\x51\x2d\xcb\xa3\x6d\x76\x3c\xba\xae\x41\x5f\x5e\xba\xcc\xf2\x88"
+  "\xae\x32\x0d\xb0\xf2\x48\x31\xf7\xcc\x2c\xe0\xd1\x2c\xa9\x3c\x52"
+  "\x44\xf3\xbc\x2d\xd5\x3d\xd5\xc1\xdb\x52\x8a\x33\xf6\xde\xd6\xea"
+  "\x65\x6f\xfb\x0d\x4f\xbc\x9d\x37\x3c\xa9\xde\x8f\xf5\xb3\x94\xa2"
+  "\x46\x1e\x9f\x15\xd5\x2e\xcd\x55\xa3\x94\xe3\xed\xe7\xaa\xfd\x19"
+  "\xfb\x54\xca\xc3\x80\xb9\x26\xe8\x53\xd9\x73\x0e\x73\x8c\xa8\x2e"
+  "\x35\x2d\x73\x8c\xa8\x2e\x47\x3b\xfc\x5c\x35\xaa\x4b\x94\xa0\x5f"
+  "\xa0\xba\xcc\x65\xe6\xaa\x51\xca\xf0\x36\x9f\xab\x06\x79\x0a\xfa"
+  "\x52\xaa\x0b\x19\xff\xa7\x94\x13\x1c\xe6\xaa\xe1\x6b\x84\x7c\x29"
+  "\xd5\xb5\x3b\x7b\x4d\x38\xcf\x97\xb2\x79\x40\x7b\x32\x40\xd4\x97"
+  "\x52\x5d\x4f\x91\xf6\xa5\xeb\x36\xd2\xbe\x10\x4c\x1d\x7c\x29\xd5"
+  "\x75\xa1\xad\x2f\x15\x9c\xab\xc6\x72\x88\x29\xa7\x98\x2f\xa5\xba"
+  "\x7e\xe8\xe0\x4b\x29\x8f\x5a\xc1\xb9\x6a\x94\x6a\x23\xc7\x23\xd5"
+  "\x20\xde\x5c\x35\xaa\x6b\x63\xa7\x98\xab\x26\xce\xad\x28\xde\x5c"
+  "\x35\xaa\xdb\x59\xc9\x73\xd5\xa8\x6e\x66\x49\x5e\x94\xe1\x9c\x80"
+  "\x17\xa5\x54\xe3\xed\x39\xc7\xf3\xa2\x94\x2a\x56\xd0\x8b\x52\xaa"
+  "\x54\x9e\x17\x65\xf2\x17\xf0\xa2\x94\xea\x00\x2f\x7f\x7b\x2f\x4a"
+  "\xa9\xce\xf0\xbc\x28\x9b\xae\xc5\x8b\x52\xdd\xe3\x48\x1b\xea\x91"
+  "\x27\xd9\x8b\x52\xdd\xc7\xe3\x34\x87\xde\x21\xef\x8c\x78\x3e\x94"
+  "\xea\x3e\x99\xe7\x43\xa9\xee\x64\x3e\x1a\xd5\x3d\x85\x99\xa7\x46"
+  "\x75\x1f\x46\x8e\x7b\xe4\xda\x1e\x6f\xf1\xa1\xec\x71\x3c\x4f\x8d"
+  "\x99\x9f\xb6\xa9\x7b\x96\x34\xff\x39\xa4\x03\xfa\xcf\x50\x27\xfe"
+  "\x33\xb4\x73\xfa\x4f\xea\x81\x01\xb2\xfc\x27\xf5\x80\xe8\xfa\xdf"
+  "\xf7\x3d\x90\x13\x1d\xbe\xa9\xfb\x1e\x4e\x87\x7b\xee\x95\xa7\x5b"
+  "\x3c\xf7\xfc\xf4\xb1\xef\x84\x1e\x68\xd3\x03\xf1\x5c\xec\xbd\xfa"
+  "\xc9\x8b\xbd\x57\x80\x7c\x0f\xe4\x77\x81\xf3\x40\x7e\x17\xc4\x3d"
+  "\x90\xd7\x2d\xe7\x1e\xa8\x77\x00\xe7\x81\x7c\xc8\x9c\x5a\xca\x87"
+  "\xcc\xa9\xa5\x7c\x02\xa5\x7b\x20\xf5\xce\xfb\x1e\x48\x82\x07\xda"
+  "\xe4\x59\xcd\x79\x20\x75\xac\x3c\x0f\xa4\x8e\xe1\x7b\xa0\x3e\x6b"
+  "\x1c\x3d\x90\xfa\xac\xeb\x1e\x48\x7d\x5d\x1e\x9f\xd5\xb5\xae\x79"
+  "\x20\x9f\x89\xc2\x1e\xc8\xab\x5e\xdc\x03\x91\x73\x8e\xda\xb5\xd7"
+  "\x75\x4e\xbb\xf6\xfa\xb8\xe3\x7b\xa0\x5e\xb3\x84\x75\x6a\xaf\x58"
+  "\xe2\x81\x7c\x26\xb4\xbd\x07\xf2\x11\x9e\xef\x47\xf5\xfa\x9a\xe8"
+  "\x45\x9f\x48\x47\x0f\xe4\x23\x3c\xdf\x8f\xea\xdd\x93\xbd\x86\x3f"
+  "\xdf\x8f\xcd\x03\xda\x93\x41\xe2\x1e\xa8\xf7\x19\xd2\xbe\xf4\x26"
+  "\xeb\xba\xb0\x98\x3a\x7a\xa0\xde\x8b\x5b\xf7\x40\x84\x43\x4c\x39"
+  "\x45\x3d\x50\xef\xa3\x8e\x1e\xc8\xcb\x20\xec\x81\xfc\xb6\x70\x3c"
+  "\xf2\x1b\xcc\xf7\x40\xbd\xcd\x9d\xc3\x03\x89\x72\x6b\x16\xdf\x03"
+  "\xf9\x9e\x93\xee\x81\xfc\x3c\xa4\x79\x20\x1f\xe1\x79\x7d\x94\xdf"
+  "\x44\x7b\xce\xf1\x3d\x90\xdf\x42\x61\x0f\xe4\xb7\x86\xef\x81\x7c"
+  "\x84\xe7\xf5\x51\x7e\x87\x78\xf9\x3b\x78\x20\xbf\xb3\x7c\x0f\x44"
+  "\xd2\x71\x1e\xa8\x4f\x3c\x69\x43\xbd\x76\x4a\xf7\x40\x7d\x26\x8a"
+  "\x7b\xa0\x3e\x53\xf9\x1e\xa8\x8f\x8e\x78\x9d\x3e\x19\xc4\x03\xf5"
+  "\x19\x41\x8e\x7b\xed\xb0\x3d\xce\x79\x20\x72\x9c\xf3\x40\x7d\x72"
+  "\xa4\x79\xa0\x87\x3b\xa0\x07\xd2\x38\xf1\x40\x9a\x4e\xea\x81\xfc"
+  "\x07\xc9\xf3\x40\xfe\xba\xfb\x3a\x5c\x8e\x0e\xef\x53\xc8\xe9\xf0"
+  "\xbe\xfb\xe4\xe9\x96\xbe\x4e\xdf\x7f\x3a\xd7\xe1\x81\xb3\x38\x1d"
+  "\x1e\x38\x4b\x5c\x87\x3f\xe8\x7c\xfd\x33\xaa\x7f\x21\xa7\xc3\xfb"
+  "\x75\x21\xfd\x64\x40\x0d\xe9\x27\x03\x0e\x48\xd7\xe1\x01\x81\xf7"
+  "\x75\xb8\x14\x1d\xee\x9f\xc8\xe9\xf0\x87\xae\xcb\xd3\xe1\x0f\xd5"
+  "\xf2\x75\x78\x50\x77\x47\x1d\x1e\x30\xd9\x75\x1d\x1e\xb0\x5c\x1e"
+  "\x9f\x03\x92\x5c\xd3\xe1\x01\x17\x85\x75\xf8\x83\x29\xe2\x3a\x9c"
+  "\x9c\x73\xd4\x4f\xfd\x97\x73\xfa\xa9\xff\xe8\x8e\xaf\xc3\xfb\x55"
+  "\x09\x6b\xa5\x7e\xd7\x89\x0e\x0f\xb8\xd0\xf6\x3a\x3c\xe0\x82\xb0"
+  "\x0e\xef\x3f\x97\x68\x96\x80\x4a\x47\x1d\x0e\xd7\x08\xea\xf0\xfe"
+  "\x79\xec\x35\x17\xf8\x3a\x9c\xe4\x01\xed\xc9\x87\xe2\x3a\xfc\xe1"
+  "\x89\xa4\x7d\x79\xb8\x1f\x69\x5f\x08\xa6\x8e\x3a\xbc\xff\x9d\xd6"
+  "\x75\x38\xe1\x10\x53\x4e\x51\x1d\xfe\xf0\x48\x47\x1d\xfe\xa0\xf0"
+  "\x9a\x52\x54\xa0\x1f\xc7\x23\xcd\x51\xbe\x0e\x7f\x78\x7d\xe7\xd0"
+  "\xe1\xa2\xdc\xaa\xe2\xeb\x70\xcd\x54\xe9\x3a\x5c\xb3\x51\x9a\x0e"
+  "\xc7\x9c\x13\xd2\xe1\x9a\x8b\xf6\x9c\xe3\xeb\x70\xcd\x2d\x61\x1d"
+  "\x1e\xd8\x9d\xaf\xc3\x71\xfe\x42\x3a\x3c\xf0\x29\x5e\xfe\x0e\x3a"
+  "\x3c\x70\x32\x5f\x87\x93\x74\x9c\x0e\x0f\xac\x27\x6d\xe8\x83\xd2"
+  "\xd7\x94\xa2\x02\x2f\x8a\xeb\xf0\xc0\xcb\x7c\x1d\x1e\x58\x44\xf4"
+  "\x76\x90\x8a\xe8\xf0\xc0\xd3\xe4\xf8\x83\x1a\xdb\xe3\x9c\x0e\x27"
+  "\xc7\x39\x1d\x1e\xe4\x2f\x4d\x87\x7b\x77\x40\x1d\xae\x76\xa2\xc3"
+  "\xd5\x9d\x54\x87\x07\x7f\x28\x4f\x87\x07\x17\xc9\xd7\x82\x8f\xc5"
+  "\x71\x5a\xf0\xb1\x38\x71\x2d\xa8\x5d\xef\x5c\x0b\xea\x8a\x38\x2d"
+  "\xf8\x88\x0f\x69\xab\x07\xde\x21\x6d\xf5\xc0\xa3\xd2\xb5\xe0\xc0"
+  "\xc1\xf7\xb5\xa0\x14\x2d\x18\x14\xc2\x69\xc1\x01\x8d\xf2\xb4\xe0"
+  "\x00\x23\x5f\x0b\x86\xf8\x39\x6a\xc1\x81\xb3\x5d\xd7\x82\x03\xd7"
+  "\xc8\xd3\x82\x03\x33\x5c\xd3\x82\x03\xbf\x13\xd6\x82\xda\x4c\x71"
+  "\x2d\x48\xce\x39\xf6\xe1\xba\x35\x5c\x1f\xae\x9b\xd8\xf1\xb5\xe0"
+  "\x23\x06\xe1\xfe\xfa\x91\x46\xa2\x05\x07\xea\xdb\x5e\x0b\x0e\xd4"
+  "\x0b\x6b\x41\xdd\x62\xd2\x6f\x0e\xac\x72\xd4\x82\x70\x8d\xa0\x16"
+  "\xd4\xed\x65\xaf\xd1\xf3\xb5\x20\xc9\x03\xda\x93\x13\xe2\x5a\x70"
+  "\xd0\x74\xd2\xbe\x0c\x1a\x44\xda\x17\x82\xa9\xa3\x16\x1c\xe4\xd1"
+  "\xba\x16\x24\x1c\x62\xca\x29\xaa\x05\x07\x8d\x77\xd4\x82\xda\x75"
+  "\xc2\x5a\xf0\x31\x6e\x9d\x5a\xea\xd1\x53\x7c\x2d\x38\x68\x5b\xe7"
+  "\xd0\x82\xa2\xdc\x32\xf0\xb5\xe0\xa3\x73\xa5\x6b\xc1\x47\xf3\xa4"
+  "\x69\x41\xcc\x39\x21\x2d\xf8\xe8\x77\xf6\x9c\xe3\x6b\xc1\x47\xcd"
+  "\xc2\x5a\xf0\x31\x3f\xbe\x16\xc4\xf9\x0b\x69\xc1\xc7\x46\xf3\xf2"
+  "\x77\xd0\x82\x8f\xcd\xe6\x6b\x41\x92\x8e\xd3\x82\x21\x88\xb4\xa1"
+  "\xda\xc1\xd2\xb5\xe0\x63\xdf\x89\x6b\xc1\xc7\x6a\xf8\x5a\xf0\x31"
+  "\xf2\xcd\x19\x15\xe2\x4b\xb4\xe0\x63\x15\xe4\xb8\x36\xc4\xf6\x38"
+  "\xa7\x05\xc9\x71\x4e\x0b\x86\x68\x5b\xd3\x82\xce\xf5\xc3\x93\xc5"
+  "\x9c\x7e\x78\xb2\xd8\x56\x3f\x9c\xe5\xe9\x87\x90\x33\xce\xf5\xc3"
+  "\x50\x15\xa7\x1f\x86\x2c\x24\xf5\x7b\xc8\x44\x52\xbf\x87\x30\x6b"
+  "\xf8\xa5\x4e\x84\x7e\x1e\xf4\xc3\xa1\x6b\x45\x44\x3f\x5c\x33\x52"
+  "\x9b\x6f\xb0\xfa\xa1\x16\xa9\xb2\x12\x58\xfd\xf0\x32\xd6\x0f\x8f"
+  "\xaf\xc7\xfa\xc1\x33\x1f\xb4\x6a\x15\xab\x5d\x13\x41\xbb\x56\xc1"
+  "\xff\xa1\xee\x7c\x0a\x79\x94\x81\xbe\xcc\xc1\xd7\xe3\x7d\x1b\x20"
+  "\x2f\xe6\x5b\x4e\xe6\x3b\x4f\x7d\x17\xbc\x1f\x10\xd6\x16\x78\x7f"
+  "\x8d\x56\xf7\xd6\xa8\x62\xf7\xd6\x88\xe1\xef\xad\x81\xf7\xd4\xc0"
+  "\xfb\x6b\xe4\x2f\x45\xbe\xef\xb2\x9a\xc2\x6b\x8d\x87\x17\xde\x5f"
+  "\xc3\xab\x9e\xe8\xd3\x43\x96\x12\xa2\x4f\x97\xf9\xf7\x00\x2d\x14"
+  "\xb2\xbb\x8e\xd3\x12\x6f\x61\x1d\xb1\x4c\xa7\xa9\x5f\xa6\xeb\x7f"
+  "\xfb\xb6\x2e\xc8\x71\x5f\x8d\x23\x4a\xbc\x27\x00\xde\x8b\xd0\xc4"
+  "\xea\x53\xfa\xf7\x3a\x54\xb0\x00\xa9\x40\x17\x7b\x3c\x0e\xfa\xf4"
+  "\x91\x00\x28\xfb\x39\xa4\x36\xdf\xd6\x05\xd8\xae\xd7\x08\x65\x57"
+  "\x5b\x6e\xeb\x50\x69\xf4\x37\xcc\x77\x9d\x26\xf6\xbb\x4e\xc3\x32"
+  "\x1d\xde\x6b\x60\xd8\x3b\x4b\x6d\xf4\xa9\x9f\x55\x9f\x3e\x3e\x59"
+  "\x9e\x3e\x7d\x3c\x92\xaf\x2b\xc2\x16\x3b\xea\x8a\xc7\x8f\xba\xae"
+  "\x2b\x1e\x97\xb7\xfe\x0b\xf5\x78\xa5\x6b\xba\x62\xc8\x70\x7b\x5d"
+  "\x71\x80\xd1\x15\x21\x25\x98\x83\xc2\xba\x82\x9c\x73\xec\x0f\x42"
+  "\xbf\xe6\xfa\x83\xd0\x7d\x1d\x5f\x57\x84\x86\x0b\xb7\xfd\xa1\x93"
+  "\x89\xae\x18\x32\xac\xed\x75\xc5\x90\x61\xc2\xba\x22\xf4\x0c\x69"
+  "\x83\x87\x8c\x70\xd4\x15\x70\x8d\xa0\xae\x08\x6d\x64\xaf\x19\xc6"
+  "\xd7\x15\x24\x0f\x68\x67\xfc\xc4\x75\xc5\x50\xb2\x87\x07\x35\x74"
+  "\x0d\x69\x77\x08\xa6\x8e\xba\x62\xe8\xf4\xd6\x75\x05\xe1\x10\x53"
+  "\x4e\x51\x5d\x31\x74\xaf\xa3\xae\x08\x39\x2d\xac\x2b\x9e\x5c\xc5"
+  "\xf1\xe8\xc9\xbe\x7c\x5d\x31\xb4\xa6\x73\xe8\x0a\x51\x6e\x85\xf3"
+  "\x75\xc5\x13\x1f\x4b\xd7\x15\x4f\x5c\x97\xa6\x2b\x30\xe7\x84\x74"
+  "\xc5\x93\xc3\xed\x39\xc7\xd7\x15\x4f\x4e\x15\xd6\x15\x4f\x2e\xe6"
+  "\xeb\x0a\x9c\xbf\x90\xae\x78\x72\x27\x2f\x7f\x07\x5d\xf1\xe4\x51"
+  "\xbe\xae\x20\xe9\x38\x5d\x11\x16\xc5\x7a\xb3\xc5\xd2\x75\x45\xd8"
+  "\x70\x71\x5d\x11\x36\x9a\xaf\x2b\xc2\x7c\x89\x7e\x08\x8b\x27\xba"
+  "\x22\x4c\x47\x8e\x87\xc4\xdb\x1e\xe7\x74\x05\x39\xce\xe9\x8a\xb0"
+  "\x94\xfb\xdf\x5b\x76\xc4\x31\xa6\xa7\xfd\xe4\xf5\xe1\x4f\xfb\xfe"
+  "\xf4\xef\x7a\x3b\xe1\xf7\x96\x9b\xc2\x72\xb8\x77\xbd\xbf\xdc\x26"
+  "\x4f\xb7\xfc\x52\x74\xff\xdb\xfb\x73\x8d\x9d\xc5\xfe\xe9\x59\x5c"
+  "\xec\x87\xf7\x94\x17\xfb\xe1\x9e\x3f\x7d\xec\x3b\xe3\x1c\x87\x5f"
+  "\x56\x72\xb1\x7f\x66\xa3\xbc\xd8\x3f\x23\xba\xff\x79\xeb\xbe\x74"
+  "\x8c\xcd\x1c\x87\x31\xb3\xc4\x7d\xe9\xb3\xb3\x9d\xfb\xd2\xe7\x6c"
+  "\xe6\x38\xfc\x8a\x9d\xe3\x30\x92\x9d\xe3\x30\x92\x99\xe3\x90\x86"
+  "\x7d\xe9\x7b\x11\x19\x1f\x2c\x3d\x46\xe1\xb5\xbe\x0e\x2d\x35\x52"
+  "\x80\x89\xd2\x84\x7d\x29\xc4\x7a\x4b\x13\xf6\xa5\xa7\xd9\x71\xed"
+  "\x91\x81\x65\xd5\x36\x7b\x5a\x50\xcf\x1e\xe2\xd6\xdc\x3d\x8d\xf0"
+  "\xb9\x4f\xeb\x8e\x51\x39\x4d\x76\x63\xde\x90\xa7\x26\x81\x3f\xe6"
+  "\x8d\xc7\xba\x1b\x6d\xf6\xa6\x30\xe7\x8d\x4d\x6c\x6d\xcc\xdb\x7e"
+  "\xbc\x7b\x57\x13\xf2\xed\xbc\x63\xde\xc3\xa7\x70\x63\xde\x23\x64"
+  "\xce\x7f\x18\x61\x37\xff\xe1\xd7\x02\xf3\x1f\x46\x4a\x98\xff\x30"
+  "\x52\xe6\xfc\x87\x91\x2e\xce\x7f\x18\xe9\x30\xff\x81\x78\xd3\x67"
+  "\xa3\xd3\x44\xbd\x29\x39\xe7\xe8\x29\x9e\xb3\x99\xff\xf0\x5c\x27"
+  "\x98\xff\xf0\x2b\x91\x77\xd4\xbf\x62\xe7\x3f\x8c\xbc\x07\xf3\x1f"
+  "\x46\x8a\xcc\x7f\x78\x8e\x9d\xff\x30\x52\x60\xfe\xc3\x48\x91\xf9"
+  "\x0f\xcf\xb1\xf3\x1f\x46\xda\xcd\x7f\x18\xc9\xce\x7f\x78\xce\xc9"
+  "\xfc\x87\x51\xec\xfc\x87\x51\xec\xfc\x07\x82\xa9\xa3\x37\x7d\xce"
+  "\x85\xf9\x0f\x23\xd9\xf9\x0f\x23\x9d\xcc\x7f\x18\x25\x30\xff\xe1"
+  "\xd9\x59\xc2\xde\x74\x8c\xcd\xfc\x87\xd1\x76\xf3\x1f\x46\x75\x92"
+  "\xf9\x0f\xa2\xdc\xb2\x9b\xff\x30\x5a\xc6\xfc\x87\xd1\x12\xe7\x3f"
+  "\x8c\x14\x99\xff\x30\xfa\xa2\x3d\xe7\xf8\xde\x74\xb4\xc8\xfc\x87"
+  "\x31\x76\xf3\x1f\x46\x8a\xcc\x7f\x18\xf3\x14\x2f\x7f\x07\x6f\x3a"
+  "\xc6\x6e\xfe\xc3\x48\xbb\xf9\x0f\x63\xd8\xf9\x0f\xcf\x76\x91\xee"
+  "\x4d\xc7\x38\x99\xff\x30\xc6\x6e\xfe\xc3\x18\x76\xfe\xc3\xaf\xd9"
+  "\xf9\x0f\x63\xd8\xf9\x0f\xcf\x2a\x6d\x8f\x73\xde\x94\x1c\xe7\xbc"
+  "\xe9\xaf\x25\xce\x7f\xb8\xff\x2d\x66\xfb\x78\xd3\xb1\x32\xe7\x3f"
+  "\x8c\x75\x3a\xff\xe1\xbe\x3f\x12\xd3\xe8\xbf\x0e\xe1\x34\xfa\x6f"
+  "\x06\xcb\xd3\x2d\xbf\x09\xf9\xe9\x63\xdf\x19\xfd\xd1\x58\x23\x17"
+  "\xfb\xe7\x0f\xc8\x8b\xfd\xf3\xfb\xe5\xfb\xa3\x88\x14\xce\x1f\x45"
+  "\xa4\x88\xfb\xa3\x70\xe7\xfb\xff\x51\x13\x4e\x73\xfe\xe8\xb7\x03"
+  "\x88\x46\xf9\x6d\x77\xa2\x51\x5e\x38\x2b\xdd\x1f\xbd\x30\x9a\xef"
+  "\x8f\xc2\xcf\xdd\xf7\x47\x72\xfd\xd1\x6f\x92\x38\x7f\xf4\x42\x4f"
+  "\x79\xfe\xe8\x05\x4f\xbe\x3f\x8a\x1c\xe4\xe8\x8f\x5e\x58\xe2\xba"
+  "\x3f\x7a\x21\x4f\x1e\xd7\x5f\xc8\x75\xcd\x1f\xbd\x70\x47\xd8\x1f"
+  "\x85\x67\x88\xfb\x23\x72\xce\x51\xd7\x4e\xc8\xe3\x74\xed\x84\xb9"
+  "\x1d\xdf\x1f\x4d\x50\x0a\x6b\xd8\x09\x3d\x89\x3f\x7a\xa1\xbe\xed"
+  "\xfd\xd1\x0b\xf5\xc2\xfe\x68\x02\xd9\xff\x95\x7a\xc1\xe8\xe8\x8f"
+  "\xe0\x1a\x41\x7f\x34\xe1\x28\x7b\x4d\x3d\xdf\x1f\x91\x3c\xa0\xad"
+  "\x39\x2f\xee\x8f\x26\x2e\x26\x6d\xcf\xc4\x91\xa4\xed\x21\x98\x3a"
+  "\xfa\xa3\x89\x7e\xad\xfb\x23\xc2\x21\xa6\x9c\xa2\xfe\x68\xe2\x6c"
+  "\x47\x7f\x14\x2e\xbc\xaf\x1a\x15\xf1\x14\xc7\xa3\x49\x17\xf9\xfe"
+  "\x68\xe2\xbe\xce\xe1\x8f\x44\xb9\xa5\xe4\xfb\xa3\x49\xcb\xa5\xfb"
+  "\xa3\x49\x07\xa4\xf9\x23\xcc\x39\x21\x7f\x34\xe9\x8e\x3d\xe7\xf8"
+  "\xfe\x28\xc2\x47\xd8\x1f\x45\x0c\xe2\xfb\x23\x9c\xbf\x90\x3f\x8a"
+  "\x98\xca\xcb\xdf\xc1\x1f\x45\x2c\xe1\xfb\x23\x92\x8e\xf3\x47\x91"
+  "\xbe\x6c\x9f\x26\x7d\x5f\x35\x2a\xe2\x8e\xb8\x3f\x8a\x30\xf3\xfd"
+  "\x51\x44\x05\xf1\x41\x91\x3a\xe2\x8f\x22\xaa\xc8\xf1\x70\xad\xed"
+  "\x71\xce\x1f\x85\x6b\xf9\xfe\x28\x72\xd8\xfd\xef\x34\x3b\xa2\x3f"
+  "\x9a\x7c\x5e\x9e\x3f\x9a\x5c\x71\x5f\xa3\xcb\xd1\xe8\x91\x13\x38"
+  "\x8d\xfe\xd2\x44\x79\xba\xe5\xa5\x09\xf2\x35\xfa\x4c\x0d\xa7\xd1"
+  "\x67\x6a\xc4\x35\xfa\x94\x40\xe7\x1a\x3d\x2a\x8e\xd3\xe8\xd3\xce"
+  "\x92\x7e\x72\xda\x21\xd2\x4f\x4e\x5b\x2c\x5d\xa3\x4f\xfd\x81\xaf"
+  "\xd1\xa7\x2c\xb9\xaf\xd1\xe5\x6a\xf4\x17\xfd\x39\x8d\x3e\xf5\x43"
+  "\x79\x1a\x7d\x6a\x11\x5f\xa3\xcf\x3c\xe7\xa8\xd1\xa7\xf9\xb9\xae"
+  "\xd1\xa7\x0d\x97\xc7\xf5\x69\xc3\x5c\xd3\xe8\xd3\x76\x0a\x6b\xf4"
+  "\x29\x5a\x71\x8d\x4e\xce\x39\x6a\xab\xa8\xe1\x9c\xb6\x8a\xea\xd2"
+  "\xf1\x35\xfa\xef\xf6\x0b\xeb\xa8\xdf\x7d\x48\x34\xfa\xb4\x1d\x6d"
+  "\xaf\xd1\xa7\xed\x10\xd6\xe8\x51\x03\x88\x9e\x99\x96\xef\xa8\xd1"
+  "\xe1\x1a\x41\x8d\x1e\x35\x9d\xbd\x66\x07\x5f\xa3\x93\x3c\xa0\xad"
+  "\x59\x2e\xae\xd1\xa7\xb3\xdf\x05\x45\x7d\x47\xda\x1e\x82\xa9\xa3"
+  "\x46\x8f\xfa\xb8\x75\x8d\x4e\x38\xc4\x94\x53\x54\xa3\x4f\xf7\x70"
+  "\xd4\xe8\x53\x34\xc2\x1a\x7d\x86\xcd\x3c\xcd\x19\xab\xf8\x1a\x7d"
+  "\xfa\xf8\xce\xa1\xd1\x45\xb9\xb5\x9f\xaf\xd1\x67\xf4\x95\xae\xd1"
+  "\x67\x4c\x94\xa6\xd1\x31\xe7\x84\x34\xfa\x8c\x9d\xf6\x9c\xe3\x6b"
+  "\xf4\x19\x47\x85\x35\xfa\x8c\x73\x7c\x8d\x8e\xf3\x17\xd2\xe8\x33"
+  "\x1a\x79\xf9\x3b\x68\xf4\x99\x7e\x7c\x8d\x4e\xd2\x71\x1a\x7d\xe6"
+  "\x31\xd2\x86\xbe\x74\x56\xba\x46\x9f\xb9\x53\x5c\xa3\xcf\xdc\xcb"
+  "\xd7\xe8\x33\x93\x88\x16\x9f\x59\x4a\x34\xfa\xcc\x4c\x72\xfc\xa5"
+  "\x12\xdb\xe3\x9c\x46\x27\xc7\x39\x8d\x3e\xf3\xd2\xfd\x6f\x38\x3b"
+  "\xa2\x46\x9f\xbd\x5c\x9e\x46\x9f\x9d\x24\x5f\x27\xc6\x86\x73\x3a"
+  "\x31\x36\x5c\x5c\x27\xbe\x3c\xde\xb9\x4e\x9c\x97\xc3\xe9\xc4\xe8"
+  "\x5b\xa4\xad\x8e\xbe\x48\xda\xea\xe8\x3c\xe9\x3a\x31\xba\x27\x5f"
+  "\x27\xbe\xbc\xf3\xbe\x4e\x94\xab\x13\x67\x1a\x38\x9d\x38\xe7\x6b"
+  "\x79\x3a\x71\x4e\x25\x5f\x27\xc6\x3a\xee\xa9\x45\x45\x8f\x74\x5d"
+  "\x27\x46\xcf\x95\xa7\x13\xa3\xa3\x5d\xd3\x89\xd1\xa7\x84\x75\xe2"
+  "\xcb\x13\xc4\x75\x22\x39\xe7\xd8\xbf\xcf\x9b\xcb\xf5\xef\xf3\x06"
+  "\x77\x7c\x9d\x38\xb7\x42\xb8\x2f\x9f\xfb\x35\xd1\x89\xd1\xc5\x6d"
+  "\xaf\x13\xa3\x8b\x85\x75\xe2\x3c\x76\xfd\xb3\xe8\xd3\x8e\x3a\x11"
+  "\xae\x11\xd4\x89\xf3\xd8\xf1\xdf\xe8\x62\xbe\x4e\x24\x79\x40\x5b"
+  "\xb3\x4b\x5c\x27\xce\x1f\x4e\xda\x9e\xf9\xec\x7b\x24\x82\xa9\xa3"
+  "\x4e\x9c\xf7\x5d\xeb\x3a\x91\x70\x88\x29\xa7\xa8\x4e\x9c\x3f\xc8"
+  "\x51\x27\xbe\x1c\x2e\xac\x13\x63\x3d\x38\x1e\xc5\xec\xe5\xeb\xc4"
+  "\xf9\x4b\x3a\x87\x4e\x14\xe5\x56\x05\x5f\x27\xc6\x8c\x96\xae\x13"
+  "\x63\x96\x4b\xd3\x89\x98\x73\x42\x3a\x31\xe6\x94\x3d\xe7\xf8\x3a"
+  "\x31\xe6\xb2\xb0\x4e\x8c\xb9\xc3\xd7\x89\x38\x7f\x21\x9d\x18\x1b"
+  "\xc8\xcb\xdf\x41\x27\xc6\x8e\xe4\xeb\x44\x92\x8e\xd3\x89\xb1\x6c"
+  "\x1b\x3a\xfb\x96\x74\x9d\x18\x7b\x4a\x5c\x27\xc6\xf2\xf7\xbf\xa2"
+  "\x62\xc9\xfe\x57\x54\x6c\x3d\xd1\x89\xb1\x64\xff\x2b\x6a\xb6\xc1"
+  "\xf6\x38\xa7\x13\xc9\x71\x4e\x27\x2e\x50\xba\xf7\x7d\xe7\xe2\xe3"
+  "\x9c\xb6\x58\x7c\x5c\x5c\x5b\x2c\xd8\xe7\x5c\x5b\xbc\xa2\xe4\xb4"
+  "\xc5\xc2\x58\x52\xbf\x17\x8e\x27\xf5\x7b\x21\x33\x3f\x29\xf5\x1c"
+  "\x68\x8b\xa0\x88\x8c\xc3\x37\x8a\x18\x6d\xf1\x41\x82\x91\x02\xbd"
+  "\xa7\xb4\x60\x6d\x01\xba\x2e\x6b\x05\xd6\x16\x55\xec\xf7\x9d\x71"
+  "\x6b\xce\x25\xdb\x6a\x8b\x05\x8d\xcc\xb7\x9e\x2d\xfb\xd6\x56\x21"
+  "\x7c\x5e\xe8\xdb\xcf\x13\x09\xec\xb7\x9f\x90\xb7\xed\x37\x9f\xcc"
+  "\x77\xa0\x37\x40\x7b\xcc\x03\x3c\x6c\xb4\xc7\xfd\x6f\x3f\x71\x5f"
+  "\x1f\x37\x51\x9e\xae\x8d\x9b\xc0\xd7\x1c\x09\x0b\x1d\x35\x47\xdc"
+  "\x87\xae\x6b\x8e\xb8\x8b\xf2\x34\x47\xdc\x05\xd7\x34\xc7\xc2\xa7"
+  "\x84\x35\xc7\x82\xfd\x98\x9f\xc2\x9a\x83\x9c\x73\xec\x2b\x16\x5d"
+  "\xe4\xfa\x8a\x45\x7b\x3b\xbe\xe6\x58\x34\x56\xb8\x5f\x58\x34\x91"
+  "\x68\x8e\x85\x61\x6d\xaf\x39\x16\x86\x09\x6b\x8e\x45\x6c\xfb\xbf"
+  "\x70\x98\xa3\xe6\x80\x6b\x04\x35\xc7\x22\xf6\xfd\xdf\xc2\x30\xbe"
+  "\xe6\x20\x79\x40\x1b\xe4\x23\xae\x39\x5e\x39\x44\xda\xa4\x57\x52"
+  "\x49\x9b\x44\x30\x75\xd4\x1c\xaf\x4c\x6d\x5d\x73\x10\x0e\x31\xe5"
+  "\x14\xd5\x1c\xaf\xec\x72\xd4\x1c\x0b\x0a\x85\x35\xc7\x62\x9b\x79"
+  "\xda\x8b\xfd\xf8\x9a\xe3\x95\x1f\x3a\x87\xe6\x10\xe5\xd6\x58\xbe"
+  "\xe6\x88\x3f\x2a\x5d\x73\xc4\xd7\x48\xd3\x1c\x98\x73\x42\x9a\x63"
+  "\xf1\x53\xf6\x9c\xe3\x6b\x8e\xc5\x93\x85\x35\xc7\xe2\x85\x7c\xcd"
+  "\x81\xf3\x17\xd2\x1c\x8b\xf3\x78\xf9\x3b\x68\x8e\xc5\x1f\xf2\x35"
+  "\x07\x49\xc7\x69\x8e\x84\x29\x6c\x5f\x37\x51\xba\xe6\x48\x78\x4a"
+  "\x5c\x73\x24\x8c\xe4\x6b\x8e\x04\x35\xd1\x16\x09\x71\x44\x73\x24"
+  "\x68\xc9\xf1\x05\x13\x6c\x8f\x73\x9a\x83\x1c\xe7\x34\x47\x42\xb2"
+  "\x84\xb1\xa9\x24\x29\xdf\x7e\x1e\xba\xcb\x1f\x9b\xb2\x8e\x4b\x99"
+  "\x42\x7c\x63\x5a\xc6\xa6\xa0\xaf\x17\xdb\x47\x1d\x8f\x4d\xe1\xbe"
+  "\x9b\x1b\x9b\xba\xcc\xb4\x55\xdc\xd8\x94\x9e\x19\x9b\xc2\xe3\x52"
+  "\xe0\xd9\x5b\xc6\xa5\x2c\x2b\x1d\xbf\xfb\x3c\x64\x91\x3e\x2e\xf5"
+  "\xf2\x12\x35\xda\xcd\xf4\xdf\xc7\x52\xc8\xb8\x54\x65\xcb\xb8\x14"
+  "\xee\xb7\xcd\x0d\x8e\xe3\x52\xb8\xbf\xe6\xc6\xa5\xbe\x91\x39\x2e"
+  "\x95\xd8\x53\x5e\xff\x9d\xd8\x01\xbe\x7f\xeb\x8c\xdf\x7d\x26\x64"
+  "\x71\xef\x8e\x97\xc8\xfc\xfe\x6d\x89\xd3\xef\xdf\xee\xcf\x6b\x16"
+  "\x8b\x7d\xe2\x14\x2e\xf6\xcb\xba\xc8\x8b\xfd\x32\xe5\x4f\x1f\xfb"
+  "\xce\x38\x67\x62\x49\x05\x17\xfb\x24\x99\xeb\xbf\x25\x65\xc8\x1f"
+  "\x0b\x4f\x49\xe6\xfc\x6a\x4a\xb2\xad\x5f\x2d\x19\x6b\xeb\x57\x97"
+  "\x4f\x75\xee\x57\x57\x15\x73\x7e\x35\x39\x90\x68\xc3\xe4\x2e\x44"
+  "\x1b\xae\x64\xf6\x24\x4b\x1d\x8d\x18\x9f\x6a\xc2\x9e\x75\x91\x91"
+  "\x3a\x7c\xad\x98\x32\xad\x25\x5e\xb5\xdc\x54\x8a\xce\x19\x8c\x68"
+  "\xf3\x0a\xa4\xdc\x78\x03\x29\xff\x54\x67\xa4\xbc\xe3\x91\x0a\xfa"
+  "\x09\xd0\x52\xa5\xa0\x2d\x76\xa1\xc4\x34\xec\x63\x57\x8e\x2c\x4f"
+  "\x34\xd8\xf8\xd8\xe5\x27\x38\x0f\x0b\xe9\x12\x8d\xe8\xe4\xa2\x62"
+  "\x0a\x7b\xd5\xe6\xbc\xb1\x89\xcd\x83\x7d\xa3\x99\x35\x8b\x6c\xc7"
+  "\xcb\xe1\xde\x9a\x97\xf9\xe3\xe5\x4d\x79\x63\x93\x1a\x0f\xf9\xc6"
+  "\x30\xeb\x21\x0e\xe0\xc6\xcd\x5d\x1d\x2f\x7f\xb7\x09\xf9\x5a\xd7"
+  "\x43\xc4\xfd\x62\xe7\x1b\x2f\x5f\x36\x81\x1b\x2f\x5f\xd9\x5d\xde"
+  "\x78\xf9\x4a\x15\xdf\xbb\xa6\x0e\x70\xf4\xae\x2b\x17\xbb\xee\x5d"
+  "\x57\xca\xfc\xfe\x7f\x65\x8e\x6b\xde\x75\xe5\x2d\x7b\xef\xba\x3f"
+  "\x0d\x7b\xd7\xe5\x51\x98\xab\xc2\xde\x95\x9c\x73\xf4\x1c\xab\xb6"
+  "\x71\x9e\x63\xd5\xec\x8e\xef\x5d\x57\x21\x61\x7f\xb1\xaa\x3b\xf1"
+  "\xae\x2b\x0d\x6d\xef\x5d\x57\x1a\x84\xbd\xeb\xaa\x54\xa2\xf3\x57"
+  "\x1a\xac\x3e\x94\xf3\xae\x70\x8d\xa0\x77\x5d\xf5\xa1\xfd\x35\xc4"
+  "\xbb\xae\xac\x27\xde\x75\xd5\x39\x71\xef\xba\x9a\x5d\x2f\x6d\xf5"
+  "\x70\xd2\x3e\x11\x4c\x1d\xbd\xeb\x6a\x9f\xd6\xbd\x2b\xe1\x10\x53"
+  "\x4e\x51\xef\xba\x7a\xba\xa3\x77\x5d\x3e\x45\xd8\xbb\xa6\x0c\xe5"
+  "\x78\xf4\xda\x79\xbe\x77\x5d\xbd\xb7\x73\x78\x57\x51\x6e\x21\xbe"
+  "\x77\x7d\x6d\x89\x74\xef\xfa\xda\x3e\x69\xde\x15\x73\x4e\xc8\xbb"
+  "\xbe\x76\x8b\xe5\x4f\xbd\xb0\x77\x4d\xe9\x29\xec\x5d\x53\x06\xf0"
+  "\xbd\x2b\xce\x5f\xc8\xbb\xa6\x4c\xe6\xe5\xef\xe0\x5d\x53\x16\xf3"
+  "\xbd\x2b\x49\xc7\x79\xd7\x54\x35\x69\x43\x93\xcc\xd2\xbd\x6b\xca"
+  "\x2d\x71\xef\x9a\xd2\xc8\xf7\xae\x29\xa5\xc4\xa3\xa6\x6a\x89\x77"
+  "\x4d\xd1\x93\xe3\x49\x26\xdb\xe3\x9c\x77\x25\xc7\x39\xef\x9a\x1a"
+  "\x26\xc1\xbb\x26\xb7\x91\x77\x8d\xeb\x5c\xde\xf5\x93\x11\xed\xeb"
+  "\x5d\xd3\xce\xca\xf3\xae\x69\x25\x2e\x6a\xf8\xa4\x56\x34\x7c\xcc"
+  "\xff\x5f\x1a\x3e\x35\x9c\xd3\xf0\x19\xe3\xe4\x69\x96\x8c\xb1\x3f"
+  "\x75\xec\x3b\x5f\xdc\xd3\xd5\x5c\xdc\xd7\x9c\x90\x17\xf7\x35\xc7"
+  "\xef\xfb\x56\x39\xb1\xcf\xb0\x19\xaf\x79\x5d\xe6\xfc\xe7\xd7\x87"
+  "\xc9\xf7\xad\x9b\xa7\x70\xbe\x75\xf3\x14\x5b\xdf\xfa\x77\xde\x7b"
+  "\xd6\x75\x3d\x9d\xfb\xd6\xcc\x7c\xce\xb7\x6e\x30\x13\x5d\xb8\x81"
+  "\x9d\x6f\xbb\x81\xd1\x5b\x29\x47\x89\x6f\xbd\x8b\x7d\xeb\x55\xf0"
+  "\xad\x0b\xa2\x29\x13\xbb\x06\x3f\x9e\x97\x75\x0e\xbc\x27\xf6\xaa"
+  "\xe5\xc9\xf0\x77\x92\x01\x6d\x5e\x8a\x94\x9b\xc0\x73\x1e\x80\xfe"
+  "\xeb\xc0\x0a\x03\x95\xb9\x08\xda\xfe\xca\x43\xc8\x3b\x0e\xfc\x6c"
+  "\x1d\xf6\xb3\xa7\xc1\xab\xae\x67\xfd\xec\x86\xbe\xe5\x49\xb6\x7e"
+  "\x76\xdd\x16\xc6\xcf\x1a\xc8\x9c\xaf\xf2\x24\xf0\xb3\x70\x3f\xbc"
+  "\xa6\xbf\xad\x9f\x6d\x04\xbf\xda\x04\x7e\x35\xe7\x9a\x9d\xb7\x5d"
+  "\xe0\xe8\x6d\x1b\xfd\xc6\x26\x1b\x07\xfb\xc6\x61\x6f\x7b\x77\xdf"
+  "\xff\x8f\xde\x76\xad\x92\xf3\xb6\xeb\x7f\x90\xe7\x6d\xd7\x57\xf1"
+  "\xbd\x6d\x96\x87\xa3\xb7\xdd\x30\xde\x75\x6f\xbb\x61\xb1\xbc\x3a"
+  "\xb3\x21\xde\x35\x6f\xbb\xe1\x9c\xbd\xb7\x7d\x9f\x79\x2f\xbb\x4e"
+  "\x8d\xf9\x2c\xec\x6d\xc9\x39\x47\x4f\x92\xb9\x98\xf3\x24\x99\xc3"
+  "\x3b\xbe\xb7\x7d\xe3\x92\xb0\xff\x78\xe3\x07\xe2\x6d\x37\x94\xb6"
+  "\xbd\xb7\xdd\x50\x2a\xec\x6d\x33\xd9\xf9\xff\x1b\x4a\x1d\xbd\x2d"
+  "\x5c\x23\xe8\x6d\x33\xb7\xd8\x5f\x43\xbc\xed\x86\x0a\xe2\x6d\x33"
+  "\x0f\x88\x7b\xdb\x8d\xe3\x48\x1b\xb6\xd1\x8f\xb4\x61\x04\x53\x47"
+  "\x6f\x9b\x79\xbd\x75\x6f\x4b\x38\xc4\x94\x53\xd4\xdb\x6e\x7c\xca"
+  "\xd1\xdb\xae\xf3\x14\xf6\xb6\x9b\x7b\x72\x3c\xda\x74\x88\xef\x6d"
+  "\x37\xa6\x76\x0e\x6f\x2b\xca\xad\x4b\x7c\x6f\xbb\x69\xa2\x74\x6f"
+  "\xbb\x69\x8d\x34\x6f\x8b\x39\x27\xe4\x6d\x37\x9d\x63\xf9\x53\x21"
+  "\xec\x6d\x37\xd5\x08\x7b\xdb\xcd\x1e\x7c\x6f\x8b\xf3\x17\xf2\xb6"
+  "\x9b\x07\xf3\xf2\x77\xf0\xb6\x9b\xc7\xf3\xbd\x2d\x49\xc7\x79\xdb"
+  "\xcd\xb5\xa4\x0d\x7d\xfd\xa8\x74\x6f\xbb\xf9\x9c\xb8\xb7\xdd\x7c"
+  "\x91\xef\x6d\x37\xef\x27\x1e\x36\x0b\x11\x6f\xbb\xf9\x38\x39\xfe"
+  "\xfa\x11\xdb\xe3\x9c\xb7\x25\xc7\x39\x6f\x9b\xa5\x96\xf6\x5e\xd6"
+  "\xad\x75\x8f\x62\xda\xff\x9b\x81\xb6\x5a\xf7\xc8\xfa\x6e\xb6\xbd"
+  "\xbe\x19\xd8\x72\x40\x9e\xbf\xdd\xe2\x74\xfd\x97\xfb\x1e\x4b\x48"
+  "\xe7\x67\x69\x39\x9d\xbf\x35\x50\x9e\x66\xd9\xaa\xb9\xef\xb1\xe4"
+  "\xc4\x7e\x8b\x81\x8b\x7d\xce\x2e\x79\xb1\xcf\xc9\x97\xef\xb1\x76"
+  "\xe4\x72\x1e\x6b\x47\xae\xf8\xbb\xc1\x6d\x4b\x9c\x7b\xac\xbc\x4b"
+  "\x9c\xc7\xca\x1d\x49\xf4\x49\x6e\x20\xd1\x27\x6f\x7d\xd7\x76\xef"
+  "\x06\xdf\x9a\xce\x7f\x37\xb8\xed\xeb\xfb\xef\x06\xdb\xc2\x3f\x6d"
+  "\x8d\xe3\xfc\xd3\x5b\x03\xe4\xf9\xa7\xb7\xb4\x7c\xff\xb4\x73\xb4"
+  "\xa3\x7f\x7a\x6b\xa3\xeb\xfe\xe9\xad\x43\xf2\xea\xc3\x5b\x07\x5d"
+  "\xf3\x4f\xb9\x3d\x85\xdf\x0d\x6e\x4b\x12\x7f\x37\x48\xce\x39\xea"
+  "\xde\xbc\x43\x9c\xee\xcd\x5b\xd5\xf1\xfd\x53\x5e\x80\xb0\xc6\xcd"
+  "\x1b\x40\xfc\x53\xae\x67\xdb\xfb\xa7\x5c\x4f\x61\xff\x94\xc7\x7e"
+  "\xff\x9a\xeb\xe9\xe8\x9f\xe0\x1a\x41\xff\x94\x77\xce\xfe\x1a\xe2"
+  "\x9f\x72\xd5\xc4\x3f\xe5\xd5\x88\xfb\xa7\xed\xeb\x49\xfb\xb4\x7d"
+  "\x2a\x69\x9f\x08\xa6\x8e\xfe\x69\xfb\xe0\xd6\xfd\x13\xe1\x10\x53"
+  "\x4e\x51\xff\xb4\x7d\xb9\xa3\x7f\xda\x96\x28\xec\x9f\x76\x4c\xe4"
+  "\x78\xf4\xf6\x75\xbe\x7f\xda\x7e\xa2\x73\xf8\x27\x51\x6e\x05\xf0"
+  "\xfd\xd3\xdb\x5b\xa4\xfb\xa7\xb7\x4f\x49\xf3\x4f\x98\x73\x42\xfe"
+  "\x69\x47\x4f\x96\x3f\x6a\x61\xff\xb4\x63\x90\xb0\x7f\xda\x31\x9a"
+  "\xef\x9f\x70\xfe\x42\xfe\x69\xc7\x62\x5e\xfe\x0e\xfe\x69\xc7\x46"
+  "\xbe\x7f\x22\xe9\x38\xff\xb4\x33\x84\xed\xdf\xfa\x4a\xf7\x4f\x3b"
+  "\x7b\x8a\xfb\xa7\x9d\x7e\x7c\xff\xb4\xa3\x9a\xf8\xa4\x9d\xa3\x88"
+  "\x7f\xda\x61\x22\xc7\xb7\xf9\xdb\x1e\xe7\xfc\x13\x39\xce\xf9\xa7"
+  "\x9d\x91\xd2\xfc\x93\xeb\xeb\x22\xfd\xf4\xf3\x5a\x35\x9d\x74\x5e"
+  "\xeb\x3b\x3f\xc8\xf3\x4e\xef\x54\xdd\xd7\xf0\x72\x34\xfc\xce\x18"
+  "\x4e\xc3\xe7\xcb\xfc\xfe\x37\x3f\x5a\xbe\x86\x2f\x8c\xe2\x34\x7c"
+  "\x61\x94\xb8\x86\xdf\xf5\x94\x73\x0d\xbf\x77\x0f\xa7\xe1\xf7\x78"
+  "\x90\x3e\xb2\xe0\x07\xd2\x47\x16\xec\x6b\x3b\x0d\x5f\xd0\x8f\xaf"
+  "\xe1\x77\xed\xba\xaf\xe1\xdb\x42\xc3\xbf\x6b\xb3\xdf\xf1\xee\x1a"
+  "\x79\x1a\x7e\x77\x35\x5f\xc3\xef\xeb\xe2\xa8\xe1\x0b\x26\xba\xae"
+  "\xe1\x0b\x96\xc8\xab\x0f\x05\x89\xae\x69\xf8\x82\xf3\xc2\x1a\x7e"
+  "\xd7\x30\x71\x0d\x4f\xce\x39\x6a\xaf\xbd\x4b\x38\xed\xb5\x77\x64"
+  "\xc7\xd7\xf0\x7b\xf4\xc2\x3a\x6b\x4f\x0d\xd1\xf0\x05\x15\x6d\xaf"
+  "\xe1\x0b\x2a\x84\x35\xfc\xde\xd9\x44\xef\x14\x54\x38\x6a\x78\xb8"
+  "\x46\x50\xc3\xef\xdd\x66\x7f\x0d\xd1\xf0\x05\x17\x88\x86\xdf\x7b"
+  "\x48\x5c\xc3\xbf\x37\x9e\xb4\x4f\xef\xf5\x25\xed\x13\xc1\xd4\x51"
+  "\xc3\xef\xbd\xd5\xba\x86\x27\x1c\x62\xca\x29\xaa\xe1\xdf\x1b\xee"
+  "\xa8\xe1\x77\x85\x09\x6b\xf8\x42\x1f\x8e\x47\x7f\xf8\x90\xaf\xe1"
+  "\xdf\x5b\xd3\x39\x34\xbc\x28\xb7\xf4\x7c\x0d\xff\x87\xc9\xd2\x35"
+  "\xfc\x1f\xd6\x4b\xd3\xf0\x98\x73\x42\x1a\xfe\x0f\xe7\x59\xfe\x5c"
+  "\x10\xd6\xf0\x7f\xb8\x2e\xac\xe1\x0b\xbb\xf0\x35\x3c\xce\x5f\x48"
+  "\xc3\x17\x0e\xe5\xe5\xef\xa0\xe1\x0b\x27\xf2\x35\x3c\x49\xc7\x69"
+  "\xf8\x42\xb6\x7f\xcb\xbf\x2c\x5d\xc3\x17\x9e\x17\xd7\xf0\x85\x5f"
+  "\xf3\x35\x7c\xe1\x41\xa2\xd5\xf7\x29\x89\x86\x2f\x2c\x26\xc7\xf3"
+  "\x2f\xd9\x1e\xe7\x34\x3c\x39\xce\x69\xf8\x7d\xbe\xf7\xd7\x4d\xea"
+  "\x88\xeb\x26\xbd\x7f\x48\x9e\x8e\x7f\xff\xa0\x7c\x2d\x79\x38\x83"
+  "\xd3\x92\x87\x33\x6c\xb5\x24\x7f\x6d\x83\x3f\xae\x71\xae\x25\xff"
+  "\x5c\xc2\x69\xc9\x3f\x0d\x22\x6d\xf5\x9f\x7a\x92\xb6\xfa\x00\xf3"
+  "\x7e\x4f\xda\xba\x49\x07\xc6\xf1\xd7\x4d\xfa\xe3\xf9\xfb\xeb\x26"
+  "\xc9\xd5\x89\xfb\x74\x9c\x4e\x3c\xe0\x23\x4f\x27\x1e\x50\xf3\x75"
+  "\xe2\x07\x83\x1d\x75\xe2\x81\xe5\xae\xeb\xc4\x03\x3b\xe5\xe9\xc4"
+  "\x03\x3b\x5c\xd3\x89\x07\x1a\x85\xd7\x30\xf8\xe3\x3a\xf1\x75\x93"
+  "\xc8\x39\xc7\xfe\xfd\xcf\x3b\xb9\xfe\xfd\xcf\xb1\x1d\x5f\x27\xfe"
+  "\x59\x25\xdc\x97\xff\xd9\x87\xe8\xc4\x03\xc6\xb6\xd7\x89\x07\x8c"
+  "\xc2\x3a\xf1\xcf\xeb\x49\x9f\x7a\xc0\xe4\xb8\x86\x01\x5c\x23\xa8"
+  "\x13\xff\xfc\x31\x7b\x8d\x91\xaf\x13\x49\x1e\xd0\xd6\x5c\x14\xd7"
+  "\x89\x07\x97\x90\xb6\xe7\xe0\x68\xd2\xf6\x10\x4c\x1d\x75\xe2\xc1"
+  "\xbe\xad\xeb\x44\xc2\x21\xa6\x9c\xa2\x3a\xf1\xe0\x5c\x47\x9d\xf8"
+  "\xc7\x0c\x61\x9d\x78\xd8\x66\x9d\xd6\x43\x5f\xf3\x75\xe2\xc1\x03"
+  "\x9d\x43\x27\x8a\x72\x4b\xc5\xd7\x89\x87\x56\x49\xd7\x89\x87\x0e"
+  "\x49\xd3\x89\x98\x73\x42\x3a\xf1\x50\xa3\x3d\xe7\xf8\x3a\xf1\xb0"
+  "\x9f\xb0\x4e\x3c\x3c\x98\xaf\x13\x71\xfe\x42\x3a\xf1\xf0\x74\x5e"
+  "\xfe\x0e\x3a\xf1\xf0\x72\xbe\x4e\x24\xe9\x38\x9d\xf8\x81\x3f\xdb"
+  "\xa7\x0d\x92\xae\x13\x0f\x37\x8a\xeb\xc4\x0f\x3c\xf8\x3a\xf1\xf0"
+  "\x05\xa2\x07\x3f\x08\x21\x3a\xf1\x70\x35\x39\xfe\x47\x9d\xed\x71"
+  "\x4e\x27\x92\xe3\x9c\x4e\xfc\x60\x84\xb4\xef\x40\xda\x64\xac\xb7"
+  "\x9d\xbe\x03\x69\xab\xb1\xde\xf6\xfe\x0e\xa4\x48\xe6\xfa\xf7\x45"
+  "\xae\xae\x7f\x7f\x7f\x9e\x4c\xcb\x38\xef\x07\x91\xdc\x38\xef\x47"
+  "\xe3\xe5\xe9\x95\x8f\xc2\xe5\x6b\xf3\x4f\x6c\xf6\xef\xfd\x84\xb7"
+  "\x7f\x2f\x7f\x3e\xfc\xff\xf5\x73\xae\xcd\xff\x6a\xb3\x7f\xef\x5f"
+  "\xd8\xfd\x7b\x8f\xb2\xfb\xf7\x1e\x3d\x20\x67\x3e\xfc\xa6\x3a\xa4"
+  "\xdc\x6c\x3f\x1f\xfe\xc2\x09\x32\x1f\x7e\xa9\xfd\x7c\xf8\xa3\x81"
+  "\xfc\xf9\xf0\xff\xb7\x4b\x6c\x3e\x3c\x1e\xf7\x6d\x3e\xe4\x1b\x83"
+  "\xe7\xc2\x0b\xce\x83\x9f\xd1\xb6\xf3\xe0\x31\x37\xdf\x5d\x4d\xb4"
+  "\xfd\x3b\x9d\x52\xdb\x7f\x68\xb3\x76\xfe\x11\x99\xfb\xff\x1e\xb1"
+  "\xdb\xff\xf7\x6f\x02\xfb\xff\x1e\x95\xb0\xff\xef\x51\x99\xfb\xff"
+  "\x1e\x75\x71\xff\xdf\xa3\x0e\xfb\xff\x92\x79\xf0\xff\xa7\x11\x9f"
+  "\x07\x4f\xce\x39\x6a\xb2\xbf\xda\xac\x2b\xf5\xd7\x4e\xb0\xff\xef"
+  "\x5f\x44\xf6\x68\xfd\x0b\xbb\xff\xef\xd1\x7b\xb0\xff\xef\x51\x91"
+  "\xfd\x7f\xff\xca\xee\xff\x7b\xb4\x65\x2f\x5f\x4e\xdb\x1f\x15\xd9"
+  "\xff\xf7\xaf\x79\xf6\xd7\x10\x6d\x7f\x94\xdd\xff\xf7\xaf\x4e\xf6"
+  "\xff\x3d\xc6\xee\xff\x7b\x8c\xdd\xff\x97\x60\xea\xa8\xed\xff\xea"
+  "\xc2\xfe\xbf\x47\xd9\xfd\x7f\x8f\x3a\xd9\xff\xf7\x98\xc0\xfe\xbf"
+  "\xff\x17\x20\xac\xed\x3f\xb1\xd9\xff\xf7\x63\xbb\xfd\x7f\x8f\x75"
+  "\x92\xfd\x7f\x45\xb9\x65\xb7\xff\xef\xc7\x32\xf6\xff\xfd\x58\xe2"
+  "\xfe\xbf\x47\x45\xf6\xff\xfd\x98\xdd\xff\xf7\xa8\xc8\xfe\xbf\x1f"
+  "\x8b\xec\xff\xfb\x89\xdd\xfe\xbf\x47\x45\xf6\xff\xfd\xe4\x29\x5e"
+  "\xfe\x0e\xda\xfe\x13\xbb\xfd\x7f\x8f\xda\xed\xff\xfb\x09\xbb\xff"
+  "\xef\x47\x67\xa4\x6b\xfb\x4f\x9c\xec\xff\xfb\x89\xdd\xfe\xbf\x9f"
+  "\xb0\xfb\xff\xfe\x8d\xdd\xff\xf7\x13\x76\xff\xdf\x8f\x4e\xdb\x1e"
+  "\xe7\xb4\x3d\x39\xce\x69\xfb\xbf\x49\xd9\xff\x37\x49\xca\x18\xf0"
+  "\x4f\x3f\x8f\x43\xdd\x49\xe7\x71\x1c\x97\x39\xfe\x7b\xdc\x8d\xf1"
+  "\xdf\xd3\xf9\x9c\xc6\x3c\x9d\x2f\x3e\x97\xe0\x44\x2b\xe3\xbf\xa7"
+  "\xaa\x38\x8d\x59\xcc\x7e\xaf\x54\x3c\x88\xb4\xd3\x27\x6b\x5c\x9d"
+  "\x4b\xb0\xe9\x2e\xab\x2b\xad\x73\x09\x56\xb0\x73\x09\x40\x5b\x12"
+  "\x2d\x79\x72\x2e\x7f\x2e\xc1\x89\x1a\xb1\xb9\x04\x82\x73\x08\xec"
+  "\xf4\xa3\x55\x6b\xca\x9d\x43\xd0\xf9\xf5\xe3\xdf\x6c\xe6\x10\x9c"
+  "\x1c\x2c\x4f\x3f\x9e\x0c\xe1\xeb\xc7\x33\xe3\x1d\xf5\xe3\xc9\x6d"
+  "\xae\xeb\xc7\x93\x47\xe5\xe9\xc7\x93\x47\x5c\xd3\x8f\xc5\x7e\xc2"
+  "\x73\x08\x4e\xac\x13\x9f\x43\x40\xce\x39\xf6\xfb\xa7\x8e\x72\xfd"
+  "\xfe\xa9\x35\x1d\x5f\x3f\x9e\xd2\x0a\xf7\xf1\xa7\x06\x13\xfd\x58"
+  "\xec\xdb\xf6\xfa\xb1\xd8\x57\x58\x3f\x9e\xda\x4b\xfa\xda\x62\x5f"
+  "\x47\xfd\x08\xd7\x08\xea\xc7\x53\x17\xed\xaf\x21\xfa\xb1\xd8\x9f"
+  "\xe8\xc7\x53\xb7\xc4\xf5\xe3\x67\x5b\x48\xbb\xf4\xd9\x6c\xd2\x2e"
+  "\x11\x4c\x1d\xf5\xe3\x67\x4f\xb5\xae\x1f\x09\x87\x98\x72\x8a\xea"
+  "\xc7\xcf\x52\x1d\xf5\xe3\x09\x91\xb1\xe1\xd3\x53\x39\x1e\x7d\x7e"
+  "\x87\xaf\x1f\x3f\x3b\xd3\x39\xf4\xa3\x28\xb7\xb4\x7c\xfd\xf8\x79"
+  "\x9e\x74\xfd\xf8\xf9\x59\x69\xfa\x11\x73\x4e\x48\x3f\x9e\xf6\x63"
+  "\xf9\xe3\x2f\xac\x1f\x4f\x0f\x15\xd6\x8f\xa7\xc7\xf3\xf5\x23\xce"
+  "\x5f\x48\x3f\x9e\x5e\xce\xcb\xdf\x41\x3f\x9e\xde\xc6\xd7\x8f\x24"
+  "\x1d\xa7\x1f\xcf\x84\xb1\xfd\x9a\x8c\xb1\xe1\x33\x7e\xe2\xfa\xf1"
+  "\x4c\x3f\xbe\x7e\x3c\xcd\xae\x9d\x7f\x26\x9c\xe8\xc7\x33\x4a\x72"
+  "\xfc\x84\xce\xf6\x38\xa7\x1f\x4f\xd8\x8d\x0d\x9f\x89\x72\xa6\x1f"
+  "\xe9\x9c\x9a\xa8\x1c\xca\x52\x04\xbf\x63\x50\xce\xbe\xd0\x8f\x15"
+  "\xc3\xdf\x25\xd0\x1f\xa9\xe1\x6f\xd1\xb1\x48\x83\x4f\x4d\x94\x05"
+  "\xb4\x87\x05\xee\x53\x6e\xb8\x59\x5c\xfc\xa0\x09\x97\x9d\xec\xd9"
+  "\x02\x79\x7a\x9b\xba\x85\x5b\xe8\x38\xe8\xc3\xe1\xef\x64\x38\x06"
+  "\xe9\xbd\xa0\xdf\xd3\xac\x40\x5e\x37\xa8\x33\x46\x6b\x3a\x28\xb3"
+  "\xd7\x15\xea\xcc\x51\x9c\x47\xc3\xa6\xbf\x43\xdb\x7e\x26\x46\xb4"
+  "\xac\x90\x57\xc4\x81\xfe\x28\xd5\x44\xff\xaf\x38\xa1\x0e\x55\x51"
+  "\x7f\x9f\xe8\x5d\xdb\x2d\x1c\xda\x21\x84\xf5\x5e\xd1\x83\x06\x25"
+  "\xce\xb3\x38\xa1\x09\x9f\x0b\xc5\xe7\xcc\x50\xc6\xb4\xc5\x88\xca"
+  "\xae\xeb\xa6\x02\x5d\xd5\x25\xbd\x9e\xae\x7e\xd5\x04\x65\x4e\x36"
+  "\xa1\x93\xfd\x2b\x95\x1f\xbc\x53\xc9\xf4\x3d\x65\xf5\x66\x26\x0f"
+  "\x4d\x02\x2e\xcf\xdf\x27\xef\x86\xf4\x42\x65\x58\x7f\x18\x85\x74"
+  "\x19\x44\xeb\xa5\xf5\x77\x7f\x2f\x14\x8b\xa3\xf7\x9a\xfe\xa8\xf8"
+  "\x51\x88\x9d\x06\x51\x42\xe7\xa5\xdd\xe7\x1f\xce\xd6\xbf\x55\xbd"
+  "\xd5\x87\xae\x4f\xdf\x89\xa8\xad\x96\x6e\xaa\xcf\xa1\x4d\x2c\xd8"
+  "\x4e\x1b\x1a\x36\xfd\x23\x59\xef\xf1\xb7\x7a\x1c\xf3\xd7\xe1\xfc"
+  "\xd6\x3e\xb4\xe1\xf6\x5a\xcc\x9b\x7f\xe4\x9c\x82\xbe\xdd\x1e\x8b"
+  "\xa5\x31\x8b\xe7\x6a\x92\x16\x2e\x8e\x7d\x75\x79\x92\x66\x40\x4c"
+  "\x0f\x34\xe5\xd5\x57\x35\x8b\xe7\x26\xac\xd2\xd8\x9e\x79\x46\x13"
+  "\xb3\x70\xd9\xdc\x79\xf1\xb1\x83\x17\xcf\x4f\xec\x01\x65\x42\x36"
+  "\xe5\xf0\xc5\x65\xb1\x6c\xfa\x47\xfe\xee\x37\x11\x7a\xab\x17\x52"
+  "\xe2\x72\x35\x6c\x2a\x41\x7a\xa5\x4a\x89\xef\x97\xbd\x9d\xae\xa7"
+  "\x20\x4d\x3a\xb4\x69\x5b\xd3\xba\xe1\xb4\x9e\x05\x50\xae\xdd\x50"
+  "\x6e\x28\x23\x94\xb9\x24\xc4\x5a\x66\x2b\x27\xd2\x31\x27\xd2\xea"
+  "\x80\x83\x25\x13\xbd\x8d\xdd\x9e\xa7\xe9\x28\xfc\x7c\xf5\x50\x57"
+  "\x3c\xe0\xd8\x0f\x8c\x07\xd8\x56\x13\x05\xd7\xc6\x59\x39\x66\xc9"
+  "\x1d\x6a\xa0\xdf\xac\xd1\x80\x76\xf4\x68\xa0\xe3\x7e\x05\xdc\xc4"
+  "\xd7\x1f\x1d\x82\x50\x06\xdd\x10\xc5\xec\x3f\x40\x37\x00\x87\x09"
+  "\x4f\xe1\xdc\xd9\xcc\xdb\x14\x7a\x0e\xf2\x38\xa8\x47\x8b\xe2\x71"
+  "\x1e\x7a\x38\x86\x63\x6e\xd9\x13\x91\x38\x55\x87\x32\x1e\xc9\x40"
+  "\x19\x0d\xf8\x9a\x42\x9f\x70\xef\x24\xe4\x11\x91\x4c\x7f\x0b\xed"
+  "\x8e\x07\x1d\x18\x91\x48\xef\xf3\x09\xd7\x53\x25\x39\x96\xbc\xa1"
+  "\x06\x78\x9e\x5a\xc8\x07\x14\xe2\xdd\x75\x38\x9f\xad\xdb\x99\xd8"
+  "\xd7\xe2\x67\x87\xf8\x80\x97\xa1\x8b\xe9\xb5\x6c\x1d\xca\x79\x00"
+  "\xbc\xd9\x74\x54\xae\xbc\x8b\x22\x4c\x74\x33\xbd\xed\x81\xd0\xb2"
+  "\xfa\x7a\x68\xd3\x12\xe7\xd3\x3d\xfe\x71\xc8\xdb\xb4\x30\xb6\xa0"
+  "\x17\xd4\xc5\x6d\xd3\x11\xbd\x2d\x68\xca\xd4\x41\x48\xdd\xb0\xe9"
+  "\x6c\xa4\x35\x9e\x10\x4b\xa5\x34\x1e\x9d\x65\xd6\x74\xc1\x7c\x80"
+  "\xf2\xb0\x7c\x38\xbb\xe7\x54\x92\x23\x1f\x5a\xea\xe6\xf6\xc0\x68"
+  "\x13\x1d\xf5\x7c\x73\x6e\xe0\x0e\xda\x37\x70\x5d\xda\x0f\xa8\x2b"
+  "\x8e\x6d\x19\xe8\xfd\xec\x15\xc8\x7f\xcb\xcb\x48\x33\x67\x95\x1a"
+  "\x19\xf2\x02\x33\xbc\xd7\x64\x78\x40\x4c\x28\x68\x5f\x42\xa1\xcd"
+  "\x0c\x6d\xee\x33\xd4\x90\x12\x8b\xa8\x43\x57\x8a\x28\xac\x93\xf1"
+  "\xbc\x90\xab\xd4\x17\x73\x77\xc3\x75\xf4\xcd\x28\x84\xf1\x60\xb0"
+  "\xb8\x19\x87\x26\x2e\x84\xfe\x79\x11\x73\x3e\x6f\x17\xe4\x29\xed"
+  "\xb9\xbe\x60\xf4\xaf\x19\xb0\x1a\x02\x38\x95\x57\x99\x99\x3c\x19"
+  "\xac\xe2\x39\xac\x4e\x40\x39\x38\xbc\xbe\x08\xc0\xb8\x8a\x3c\xb3"
+  "\x9e\x3c\x73\x90\x3f\xed\x1b\xa4\x14\x7f\xe6\x20\x44\x9e\xb9\x4b"
+  "\x9d\xf3\x67\xfe\x72\xaa\xf3\x67\xfe\x72\xa3\xf4\x67\xfe\x52\x23"
+  "\xfd\x99\xbf\x54\x8b\x3f\x73\x10\x8b\x73\x10\xe0\x1c\xe4\x04\xe7"
+  "\x20\x16\xe7\x07\xae\x38\x7f\xe6\xd2\xf1\xce\x9f\xb9\x34\x55\xfa"
+  "\x33\x97\xfa\x4a\x7f\xe6\x52\xa5\x93\x67\x66\x71\x0e\x06\x9c\x83"
+  "\x9d\xe0\x1c\xcc\xe2\xec\xf3\x95\xf3\x67\x3e\x37\xd2\xf9\x33\x9f"
+  "\x5b\x22\xfd\x99\xcf\xa9\x64\x3c\xb3\x51\xfc\x99\x83\x59\x9c\x83"
+  "\x01\xe7\x60\x27\x38\x07\xb3\x38\x3f\xbd\xc9\xf9\x33\x97\x0d\x75"
+  "\xfe\xcc\x65\xb1\x32\x9e\xd9\x24\xfd\x99\xcf\xd5\x3a\x79\x66\x16"
+  "\x67\x2d\xe0\xac\x75\x82\xb3\x96\xc5\x79\xe6\x18\xe7\xcf\x5c\x3e"
+  "\xc0\xf9\x33\x97\x4f\x97\xfe\xcc\x65\x06\xe9\xcf\x5c\xa6\x17\x7b"
+  "\xe6\x26\x68\xb7\x3d\xe1\x59\x9a\xff\x1d\xf5\xbc\xd9\x37\x30\xcb"
+  "\xb3\x0a\x51\xf9\x6b\x2d\x71\xde\xd5\xa8\x3b\x3c\x5b\x1c\xbd\x3d"
+  "\xac\x18\xff\x6b\xf1\x0d\xcc\x6c\xf2\x0d\xdc\xd1\xd8\xab\x46\xf3"
+  "\xda\x6c\xd4\x15\xeb\xf1\x8d\x16\xe4\x6f\xc9\x0d\x5c\x97\xf5\x22"
+  "\xd2\xa4\x1b\x90\xba\x2c\x4d\x8f\xd2\x12\x69\x43\x19\xfa\x0e\xf5"
+  "\xac\xc6\xde\xf3\x1b\x54\x5a\x5b\x82\x12\x96\xd2\xf4\x55\xaa\x62"
+  "\x1f\x7e\x07\x0c\x3a\x39\x23\xe7\x5f\x48\x03\xf7\x08\xdd\x0d\x3f"
+  "\x9c\x8f\xf7\x04\xe8\x3f\xb7\x87\x7d\x56\x90\x86\xfc\x3f\x5d\x54"
+  "\x8d\xf0\xf1\x5d\xf0\x33\x6f\x1f\x6a\x48\x9b\x8d\xa8\xc3\x75\x95"
+  "\x14\xe9\x9b\x2b\x96\xd8\xf7\xcd\x13\xe6\x42\x2c\xe7\x31\xe7\x4e"
+  "\xe4\xbf\x28\x35\x96\x15\x23\xac\x7d\x37\x13\xcb\x4b\x66\xd2\xdf"
+  "\xdb\xf5\xdd\x9f\xc2\xfd\xb9\x58\x56\x84\xe0\x58\xd2\xb9\x81\x7b"
+  "\xca\xab\x9b\xb0\x6f\x52\x5f\x4d\x46\x94\x9e\x2a\xbf\x54\x96\x58"
+  "\x87\x44\x62\xac\xe7\x62\x1c\xe4\xe9\x59\xd5\xa5\x4e\x38\xc6\x41"
+  "\xaa\x26\xdf\x20\x7f\xc7\x18\x07\x29\x5d\x8b\xf1\x57\xdd\xdd\x8f"
+  "\xf1\xf9\x8b\xe2\x31\xfe\x2a\x50\x7a\x8c\xcf\xef\x91\x1e\xe3\xf3"
+  "\x39\x24\xc6\x41\x1a\x7e\x8c\xcf\x8f\x12\x8f\x71\x90\x0d\x8f\x83"
+  "\x80\xc7\x0f\x5c\x11\x89\x31\xf0\x38\x48\x80\xc7\x41\x2e\xf2\xf8"
+  "\x9f\x8b\xdd\x8f\xf1\x3f\x87\x8b\xc7\xf8\x9f\xeb\xa5\xc7\xf8\x9f"
+  "\x4a\xe9\x31\xfe\xaa\x9e\x8d\xb1\x1d\x8f\xbf\x2a\x74\x12\x63\x1b"
+  "\x1e\x07\x03\x8f\x7d\xbe\x12\x8e\x71\x30\xf0\x38\x58\x80\xc7\xc1"
+  "\x2e\xf2\xf8\xc2\x79\xf7\x63\x7c\x61\x97\x78\x8c\x2f\xd4\x48\x8f"
+  "\xf1\x85\x38\xe9\x31\xbe\x10\x45\x62\x1c\x6c\xc7\xe3\x0b\x2a\xf1"
+  "\x18\x07\xdb\xf0\x38\x18\x78\xfc\xf4\x26\x91\x18\x03\x8f\x83\x05"
+  "\x78\x1c\xec\x22\x8f\xff\xf5\x94\xfb\x31\xfe\x97\x87\x78\x8c\xff"
+  "\x35\x51\x7a\x8c\x2f\x96\x4a\x8f\xf1\xc5\xe3\x6c\x8c\xed\x78\x7c"
+  "\x31\xde\x49\x8c\x6d\x78\xac\x05\x1e\xcf\x1c\x23\x1c\x63\x2d\xf0"
+  "\x58\x2b\xc0\x63\xad\x8b\x3c\xfe\xf7\x4e\xf7\x63\xfc\xef\x58\xf1"
+  "\x18\xff\xfb\x43\xe9\x31\xfe\x77\xa8\xf4\x18\xff\x5b\x43\x62\xac"
+  "\xb5\xe3\xf1\xbf\x2a\xc4\x62\xdc\x0c\x1e\xb0\x27\xc4\xb8\x67\x2d"
+  "\xa2\x76\xe1\xd8\x56\x92\xd8\x9a\xfb\x84\x15\xef\xa2\x2c\x71\x38"
+  "\x26\xcc\x18\xd0\x8f\xfe\x5e\xe6\xdc\xc0\x2c\x9a\x82\x67\x4a\xc3"
+  "\xe3\xae\x95\x7d\x4d\x6b\x91\x97\x26\x0d\x8f\xff\x7e\xcd\xcc\x0f"
+  "\xd0\xa4\x6d\xb8\x0c\xf7\x53\xe0\x71\x2f\xd3\xb6\x6a\x64\xf6\x1b"
+  "\x50\x01\xe7\x26\xd3\x03\x7a\x47\x83\xdf\xdc\x43\xbf\xe2\xef\x5b"
+  "\x5e\x5b\x04\xf1\xf9\x02\x95\x55\x7e\x82\x2c\x7d\xc2\x3e\x1b\x62"
+  "\x42\x3a\xfa\x47\x9d\x6f\x69\x92\x1e\x99\xe7\xfb\x7b\x96\x27\x97"
+  "\xa0\xf2\xe4\x8f\x50\x44\x35\x7d\x97\xfe\x5e\xe7\xd9\xec\xf7\xac"
+  "\xca\xec\x17\xb6\xc7\x9c\x37\x36\xd3\xe4\xf7\x8c\xf1\xd0\x0a\x3d"
+  "\xe5\x69\x44\xba\xf8\x2a\x9a\xce\x9e\x87\x94\xd9\x57\x90\x6a\xeb"
+  "\x3c\xe4\xb9\xf5\x0a\x52\x97\x56\x55\xa2\x73\xd7\x4a\xd0\xb9\xba"
+  "\xaf\xd1\xb9\xbb\xf0\x6b\x82\x9f\x05\x7e\x19\x5f\x03\xd6\x08\x4d"
+  "\xbc\x8e\xf0\xde\x8d\x86\xc7\x2e\x21\xdf\x52\x53\x25\xc2\xdf\xbf"
+  "\xde\xa0\x2a\xaf\x7b\x46\x23\x5f\xfa\x7b\x7f\x44\xcf\xf7\xa7\xe0"
+  "\x9c\x12\x1f\x2f\x37\x19\x50\x69\x95\x11\x9f\x2f\x85\xf3\xca\xf4"
+  "\x2a\xc8\xdf\x52\x82\xf7\x66\x34\x94\x66\x9c\x85\xe7\x7b\xdb\x40"
+  "\x63\x0f\xdd\x27\x30\x3a\x07\x42\x6d\xa1\xfd\x83\x08\x0f\xbe\xe9"
+  "\xb2\xdb\x22\x15\xeb\xaf\x03\x98\x18\xbf\xe2\xdf\x0b\xe2\xfc\xa0"
+  "\xe5\x95\x28\xf5\xa4\xaf\xbf\xa5\xcb\xea\x2b\x99\xb1\x84\xb2\xfa"
+  "\x2f\x50\xf9\x3a\x0b\x8a\x58\x85\xd0\x04\x33\x42\x38\x16\xe5\xc9"
+  "\xd5\x68\x52\x22\xf2\xc6\xe3\xcf\x96\x1f\x75\xbd\xca\xab\x0c\x28"
+  "\xd5\x04\x65\xbc\x61\x6c\x29\x63\xd9\xba\x32\x04\xe7\x1e\x2c\x8b"
+  "\xd3\x23\xcf\x44\xa4\xc6\xf1\x35\xe5\x06\x66\x4e\x82\xfa\x93\x50"
+  "\x4f\xd3\x38\xb6\x38\xa6\x38\xbe\x38\x3f\x6b\xcc\xcb\x63\x0c\x28"
+  "\xdd\x88\xd4\xe5\x69\xf0\x6f\x32\x6d\x28\x47\xb7\x10\x94\x11\xd1"
+  "\x3e\x6f\x1b\x80\x17\xa7\x31\x17\xf4\x54\xa5\x1a\xf0\xef\x25\xcc"
+  "\xa9\x20\x25\xe1\x54\x97\xba\xd6\x39\x15\xe4\xc9\x71\xea\x9b\xc5"
+  "\x1c\xa7\x2e\x8d\x17\xe7\xd4\x7f\xf6\x11\x4e\x05\x69\x3a\x26\xa7"
+  "\xfe\x33\xda\x39\xa7\xfe\xa3\x11\xe7\x54\x90\x3f\x70\x4a\xcf\xe7"
+  "\xd4\xa5\xe9\xd2\x39\xf5\x9f\xc4\xf6\xe3\x54\x90\x4a\x1e\xa7\xfe"
+  "\x33\x85\xcf\xa9\x6f\x62\x9c\x70\x8a\x6d\xa7\x1e\xb8\xe2\x02\xa7"
+  "\x6c\xda\xa9\x4b\xa7\x38\x4e\xfd\x77\x97\x38\xa7\x2e\x37\xb2\x9c"
+  "\xea\xa0\xed\xd4\xe5\x3c\xe7\x9c\xba\x9c\xe4\x84\x53\xd0\x4e\x05"
+  "\xd9\xb5\x53\xff\x3d\x24\x9d\x53\x97\x4f\xb7\x23\xa7\x64\xb6\x53"
+  "\x97\xf7\xf3\x39\x75\xe9\x98\x38\xa7\x82\xd9\x76\xca\xe7\xab\xd6"
+  "\x39\x15\x6c\xd3\x4e\x7d\xeb\xc7\x71\x4a\x7f\x4b\x9c\x53\xfa\x89"
+  "\x84\x53\xc1\x1d\xb4\x9d\xfa\xb6\xc6\x39\xa7\xbe\x2d\x11\xe7\x54"
+  "\x30\xb4\x53\x41\x76\xed\xd4\x77\x1e\xd2\x39\xa5\xf7\x6f\x3f\x4e"
+  "\x05\xcb\x6c\xa7\xbe\x35\xf1\x39\xf5\xad\xa7\x13\x4e\xb1\xed\xd4"
+  "\xd3\x9b\x5c\xe0\x94\x4d\x3b\xf5\xdd\x42\x8e\x53\xdf\x8f\x13\xe7"
+  "\xd4\x95\xbd\x2c\xa7\x3a\x68\x3b\x75\x65\xa4\x73\x4e\x5d\x09\x70"
+  "\xc2\x29\x68\xa7\x82\xed\xda\xa9\xef\xa7\x4a\xe7\xd4\x95\xf8\x76"
+  "\xe4\x94\xcc\x76\xea\x4a\x24\x9f\x53\xdf\x45\x8b\x73\x4a\xcb\xb6"
+  "\x53\x33\xc7\xb4\xce\x29\xad\x4d\x3b\xf5\xfd\x09\x8e\x53\x3f\xec"
+  "\x14\xe7\x54\xd5\x1d\xc2\x29\x6d\x07\x6d\xa7\xaa\xb6\x39\xe7\x54"
+  "\x55\xa2\x38\xa7\xb4\xd0\x4e\x05\xdb\xb5\x53\x3f\x1c\x90\xce\xa9"
+  "\xaa\xe2\xf6\xe3\x94\x56\x66\x3b\x55\x55\xc8\xe7\xd4\xf7\x47\xc4"
+  "\x38\xd5\x84\x7d\x9f\x07\x70\x2a\x0e\x7c\x1f\x70\xc8\xbb\x82\x70"
+  "\xaa\x19\x38\xf5\xae\x2d\xa7\xfe\x63\xef\xfb\xae\xfa\x58\x5a\x38"
+  "\x55\xdd\xcf\x9e\x53\x16\xe0\x54\x33\xc3\xa9\xff\x3d\x65\xf5\x7d"
+  "\xe5\xb5\x7b\x00\xab\x6b\xa8\x3c\x12\xf8\xb4\x9d\xe5\xd3\x7f\x80"
+  "\x4f\xf0\x3c\x16\x78\xde\xd2\x4b\x95\x28\xc2\x40\x9e\xab\x09\x9e"
+  "\xd7\x62\xcb\xa5\xa6\x6a\x0a\x73\x08\x73\xc7\xca\xa3\x73\x09\xc0"
+  "\x9f\xa5\xe7\xd1\xb9\x15\xf0\x5b\x0d\xbf\x34\xf8\xa1\xf3\xa8\xb4"
+  "\x1a\x31\x63\xf6\x1c\x7f\x2a\x58\xfe\x5c\x3d\xef\x9c\x3f\x57\x8b"
+  "\xa4\x79\xbc\xea\xc1\xd2\xf9\xf3\x3f\xc4\xce\xa5\x53\x47\x4c\xfe"
+  "\x96\xc6\x73\x60\x09\x47\xae\xa1\x08\x13\xf2\xa6\x67\xea\x7a\x79"
+  "\x46\x21\xf5\x6b\x66\x44\x6d\x99\x87\xd4\x5b\xbe\x81\xe7\xb5\xd6"
+  "\x9d\x2b\xc8\xf3\x0b\xe3\x27\xa8\xb4\xae\x12\x95\xde\x3d\x8b\x4a"
+  "\x2d\xf0\xbb\x06\x3f\x28\x63\x44\xac\xed\xf3\x1a\xd8\xe7\xfd\xdf"
+  "\x29\xc8\x4b\x2b\xfe\xbc\xff\xdb\xc3\x3c\x6f\x0c\x3c\x6f\x13\xf7"
+  "\xbc\xe5\xc0\x45\xc0\xe5\x41\x0b\xeb\x13\x23\x0c\xa8\xfb\xab\x26"
+  "\x9a\x6e\x62\x39\x88\x71\xf9\xe2\x82\x11\x45\x24\x02\x56\xf3\x81"
+  "\x83\x55\xfb\x51\x7a\x0a\x70\xb0\xc9\x88\xdf\xeb\x1b\xca\x33\x1a"
+  "\x81\x83\x57\xab\x68\x88\x5b\x33\xe6\xe0\x7f\x30\x07\xaf\xaa\x2c"
+  "\xa2\x1c\x04\x9f\xc8\x70\x10\x7c\x62\xab\x1c\xb4\xf5\x89\xd5\x79"
+  "\x1c\x07\xaf\xed\x15\xe7\x60\xcd\xc7\x56\x9f\xf8\xd3\x73\xb0\x66"
+  "\xaa\x73\x0e\xd6\x84\x49\xf3\x84\xd7\x3e\x94\xce\xc1\x9a\x75\xed"
+  "\xc7\xc1\x6b\xe3\x9c\x73\xf0\x9a\xb6\x75\x0e\x06\xa9\xe4\x71\xb0"
+  "\x26\x8e\xcf\xc1\xea\x2c\x27\x1c\x64\xdb\x41\xf0\x95\xad\x73\xd0"
+  "\xa6\x1d\xfc\xb1\x2f\xc7\xc1\xeb\x03\xc4\x39\x58\x3b\xd2\xea\x2b"
+  "\x7f\x7a\x0e\xfe\xf8\xb5\x73\x0e\xfe\x78\x4c\x9a\x87\xbc\xfe\x94"
+  "\x74\x0e\xd6\xaa\xda\x8f\x83\xb5\x67\x9d\x73\xb0\x76\xbf\x0b\x1c"
+  "\x94\xd9\x0e\xfe\x58\xcb\xe7\xe0\x8f\x6a\x71\x0e\x06\xb3\xed\x20"
+  "\xf8\xd0\x56\x39\x68\xeb\x43\xaf\xef\xe2\x38\x78\xf3\x80\x38\x07"
+  "\x6f\x9c\xb2\xfa\xd0\x9f\x9e\x83\x37\x66\x3b\xe7\xe0\x8d\x11\xd2"
+  "\x3c\xe7\xcd\x8f\xa5\x73\xf0\x46\x56\xfb\x71\xf0\xe6\x44\xe7\x1c"
+  "\xbc\x19\xd2\x3a\x07\x83\x65\xb6\x83\x37\x12\xf9\x1c\xbc\x9e\xeb"
+  "\x84\x83\x6c\x3b\x08\xbe\xb5\x75\x0e\xda\xb4\x83\x86\x40\x8e\x83"
+  "\x75\x83\xc5\x39\x78\x6b\x9c\xd5\xb7\xfe\xf4\x1c\x34\x7c\xe7\x9c"
+  "\x83\x86\x62\x69\x1e\xb5\x6e\xa4\x74\x0e\xde\x52\xb7\x1f\x07\x6f"
+  "\x9d\x77\xce\xc1\x5b\x45\x2e\x70\x50\x66\x3b\x68\xa8\xe7\x73\xd0"
+  "\xe0\x2f\xce\x41\x2d\xdb\x0e\x82\xcf\x6d\x95\x83\xb6\x3e\xb7\x6e"
+  "\x1f\xc7\xc1\xfa\x0f\xc5\x39\x78\xfb\xac\xd5\xe7\xfe\xf4\x1c\xbc"
+  "\x1d\xeb\x9c\x83\xb7\xc7\x4a\xf3\xb4\xf5\xa7\xa4\x73\xf0\x76\x6e"
+  "\xfb\x71\xb0\x7e\xaa\x73\x0e\xd6\x87\xb5\xce\x41\xad\xcc\x76\xf0"
+  "\x76\x32\x9f\x83\x75\xf9\x62\x1c\xb4\x80\x2f\x6e\x2e\xec\x1d\x6d"
+  "\xc9\x7d\x56\xe5\xed\xa1\x41\x26\xdf\x01\x15\xe5\x49\xf5\x68\xd2"
+  "\x1d\x88\x4f\xe2\x1d\xf4\xf2\x1d\x35\x32\xe7\x3e\x63\x04\x5f\x98"
+  "\x69\xe3\x9f\x99\xb9\x65\xa6\x9c\xb7\x0d\x5b\x13\x90\x12\xfc\xf7"
+  "\x67\xf8\x58\xf9\x55\x23\xc2\xf7\x4f\xc5\xe5\xb9\xc6\x95\x07\x8f"
+  "\x13\xd0\x37\x75\x6a\xe6\x1d\x73\x93\x1e\x55\x8d\x40\x8a\xd2\x2a"
+  "\x3d\xc4\x61\x35\x83\x2f\x8e\xcb\x55\xea\x4e\x6e\xc1\x0d\xa4\x34"
+  "\x7d\xef\xff\x20\xc4\xdb\xb7\xe7\x4a\xe4\x11\x50\x45\x5b\x70\x5c"
+  "\x71\xbc\x70\x8c\x35\xab\xf1\xbb\xeb\x3b\x3f\x94\x01\xc7\x4c\xdf"
+  "\xeb\x1e\xdc\x0d\xe9\x84\xfd\xea\x9d\xeb\xd2\xb9\x71\x87\xfd\x1e"
+  "\xf6\x4e\x56\xe9\x25\x24\xf8\xee\xd8\x02\xfe\xcd\xb5\x58\x05\xa9"
+  "\x6c\x7c\xde\x3d\x88\xd5\xdd\x62\xd7\x62\xd5\xe0\xc3\x8f\x95\x90"
+  "\xaf\x6a\xe8\x2b\x3d\x56\x77\xd9\x75\x22\xef\x1e\x73\x12\x2b\x17"
+  "\x79\x15\x94\x69\xe3\x47\xee\x41\xac\x1a\x6a\x5d\x8b\x95\x71\xa4"
+  "\x5d\xac\x04\xf4\xbf\x71\x9c\xf4\x58\x19\x55\x24\x56\x0d\x55\xe2"
+  "\xb1\x0a\x76\x91\x57\xc1\x2a\x1b\xdd\x7c\x0f\x62\xd5\xe8\xef\x5a"
+  "\xac\x1a\x17\xf2\x63\x25\xa4\x53\x1b\x97\x48\x8f\x55\x63\x18\x89"
+  "\x55\xa3\xda\x49\xac\x5c\xe4\x55\x70\xa6\x8d\xbe\xbb\x07\xb1\x6a"
+  "\x1a\xeb\x5a\xac\x9a\xf2\xec\x62\x25\xa0\xa7\x9a\x76\x49\x8f\x55"
+  "\x53\x34\x89\x55\xd3\x08\xf1\x58\x69\x5d\xe4\x95\x56\x65\xa3\x43"
+  "\xee\x41\xac\x9a\x13\x5d\x8b\x55\xf3\x29\x7e\xac\x84\xfa\xfd\xe6"
+  "\xb3\xd2\x63\xd5\x9c\x45\x62\xd5\x1c\x27\x16\x2b\x73\x6e\xe0\x3a"
+  "\x6f\x88\x41\xe3\xf6\xc0\x68\xef\x64\x44\x35\x69\x21\x6e\xbe\x10"
+  "\xb7\x35\x1a\xd4\x9c\x0b\x71\x33\x98\xd0\xa4\x25\xdf\xd2\x65\xb5"
+  "\x66\xd4\x04\x31\x6b\xf4\x0d\xcc\x2c\x37\x54\xe3\x39\x47\xcf\x5e"
+  "\xa1\xcc\x07\x66\x2e\x51\x23\x1c\x37\x1c\x07\x1c\x3b\x1a\xe2\xc6"
+  "\xc4\xd1\x77\x6c\xa6\xd9\x37\x6c\xcf\xc4\xeb\xdf\xd2\xaf\xea\x69"
+  "\x1a\x3f\x2f\xad\xae\x46\xf8\xbd\x40\x44\x35\xea\xae\x79\x11\x3f"
+  "\x93\x79\x3a\x3e\x5e\x6e\xa8\x04\x7d\x50\x87\x18\x6d\xf6\xad\xce"
+  "\xd7\xfc\x3b\x9d\xa7\xb9\x3c\xea\x79\xba\x57\x8d\xc6\xd4\x67\xa8"
+  "\x21\xfd\x3a\xea\x8a\xf5\x43\xb6\x05\xf9\xa7\x2e\x46\xd4\xe1\x45"
+  "\xc5\x14\xf3\xed\xda\x52\x26\x8f\x01\x10\x17\x7f\xfa\xb6\xcd\x9c"
+  "\xee\xdb\x71\xa8\xfc\x6a\x0e\x83\x9b\xbd\x46\x60\x70\xfb\xb7\x4e"
+  "\x0d\x3a\x33\x94\xf6\x0d\xdc\x91\x53\x86\x34\x74\x33\xc4\x98\xf9"
+  "\x9e\xc8\xe2\x53\xd0\x24\x35\xc6\x26\x66\xfe\xb7\x45\xc3\xce\xdf"
+  "\x82\x38\xe1\xfb\x33\xf3\xb7\x12\x6d\xe6\x6f\x41\x99\xb9\xf9\x5b"
+  "\xa6\x23\x78\xfe\x96\xe5\x5b\xff\x07\xad\xcf\xfe\x6a\x3c\x4d\xc3"
+  "\xb3\xf7\x2a\xab\x37\x20\xfc\xfc\x65\xf5\xc5\x28\x3d\x09\xa9\xcb"
+  "\x9a\xaa\x51\x5a\x3d\x6d\x28\xcb\xa8\x41\x11\x77\xb0\x0e\xc6\x7c"
+  "\x31\xef\x25\xb8\x9a\x92\x2c\xdf\xea\x1e\xd4\x53\xe6\x1d\x65\x15"
+  "\x08\xd9\x7c\xc7\x13\x07\x9a\x59\x05\x38\xc4\x95\x67\x5c\x41\x74"
+  "\x9f\xa7\x34\xe5\xa6\x6f\x30\x4e\x71\x70\x7e\x44\x8b\xbe\xee\xf3"
+  "\x54\x10\x3e\x86\x31\xc3\xef\x9b\xf0\xfa\x00\x05\x36\xfa\x1b\xf3"
+  "\xc2\x3b\x39\x03\x95\x27\x37\xa1\x32\x13\xfe\x66\xd7\xa4\xf9\x32"
+  "\xaa\x52\x84\x47\x41\x4a\x96\x47\x7a\xef\xe4\x2e\x75\xad\xf3\x28"
+  "\x48\xc5\xf1\x88\xbe\xe5\x1e\x8f\xe8\xbd\xee\xf3\x88\x5e\x2c\x9f"
+  "\x47\x41\xfe\x3c\x1e\x29\xd0\x74\xe9\x3c\xa2\x87\x49\xe7\x91\xc5"
+  "\xe4\x1e\x8f\xe8\x1a\xc2\x23\xcb\x71\xc2\x23\x5a\xcf\xf1\x88\xf9"
+  "\x36\xea\x1e\xf1\xc8\x12\xe7\x84\x47\x6c\x7b\x14\x04\xed\xd1\x03"
+  "\x57\x5c\xe0\x11\xd7\x1e\x29\xa8\xe1\x6e\xf1\x48\xe1\x51\xe3\x36"
+  "\x8f\x14\x1e\x47\xdd\xe0\x11\xbf\x3d\x52\x50\x7b\x25\xf3\x48\xe1"
+  "\x91\x21\x99\x47\x0a\x8f\xb1\x6e\xf1\x48\x41\x31\xdf\x7e\x43\x3e"
+  "\x4a\x86\x47\x0a\x4a\xc7\xf1\x88\xf9\xde\xec\xde\xf0\x48\x81\x8a"
+  "\xc4\x79\x14\xcc\xb6\x47\x41\xd0\x1e\xf9\x7c\xd5\x3a\x8f\x82\xb9"
+  "\xf6\x48\xa1\x5c\xe3\x1e\x8f\x94\x43\xdd\xe7\x91\xc2\x2c\x9f\x47"
+  "\xc1\x76\xed\x91\xb2\x46\x3a\x8f\x14\x25\xd2\x79\xa4\xc8\x72\x8f"
+  "\x47\xca\x55\x84\x47\x8a\x09\x84\x47\xca\x44\x8e\x47\xcc\x37\x7c"
+  "\xf7\x88\x47\x94\xd1\x09\x8f\xd8\xf6\x28\x18\xda\xa3\xa7\x37\xb9"
+  "\xc0\x23\x9b\xf6\xa8\xeb\x59\xf7\x78\xd4\x75\x95\xfb\x3c\xea\x3a"
+  "\xce\x0d\x1e\xd9\xb5\x47\xdd\x86\x4a\xe7\x51\x57\xb5\x74\x1e\x75"
+  "\xb9\xe0\x1e\x8f\xba\x9e\x22\x3c\xea\x92\x4b\x78\xd4\xf5\x18\xc7"
+  "\x23\xe6\xbb\xc8\x7b\xc4\xa3\x2e\xa3\xc4\x79\xa4\x65\xdb\xa3\x60"
+  "\x68\x8f\x66\x8e\x69\x9d\x47\x5a\x9b\xf6\xa8\xbb\x8f\x7b\x3c\x52"
+  "\x9d\x72\x9f\x47\xaa\x2d\xf2\x79\xa4\xb5\x6b\x8f\xba\xaf\x92\xce"
+  "\x23\x55\x94\x74\x1e\xa9\x02\xdc\xe3\x51\xf7\xee\x84\x47\xdd\x2e"
+  "\x11\x1e\x75\x47\x1c\x8f\x98\x6f\x4d\xef\x11\x8f\xba\x65\x8a\xf1"
+  "\x08\xaf\x45\xf0\x16\x59\x17\xa2\x7e\xeb\x6a\x34\xac\x00\xff\xdb"
+  "\x84\x42\x1b\xb2\xbb\x17\x9d\x4a\x21\xeb\x01\x40\x39\x99\xf1\x5e"
+  "\xa1\xeb\x1f\x38\x00\xb8\xf8\x06\x66\x44\x5c\x26\x6b\x34\xe0\x75"
+  "\x41\x6e\xa7\xc7\xa1\x21\x78\x5d\x06\x45\x8f\x6a\xbc\x8e\x55\xcb"
+  "\xda\x01\xbe\x22\x6b\x07\xcc\x10\x5f\x3b\xa0\x69\xbb\xf5\xbb\xdb"
+  "\xfd\xdc\x77\xb7\x8a\x1e\x47\x9d\x7e\x77\xab\xe8\xb1\x6b\xd7\x0c"
+  "\xa9\x7c\xe8\xc1\x7c\xff\x75\xbb\x4f\x60\x74\x43\x76\x8f\x83\xf0"
+  "\xcc\xeb\xc8\xb3\x3f\xc0\xac\xb7\xd2\xfa\xf7\xb8\xfb\x6d\x78\xd2"
+  "\x23\x6a\xea\x2c\x94\x41\x6f\x3a\x7b\x90\xf6\x0b\xcc\xa0\xf3\x02"
+  "\x73\x24\x96\xa5\xde\x79\xbc\x83\x90\x70\xbc\x3d\xa3\xd8\x78\x93"
+  "\xef\x9c\x7d\x45\xd6\x2d\x98\x21\xbe\x6e\x81\x70\xbc\x3d\x9d\x7f"
+  "\xe7\xac\xf0\xec\x29\x3d\xde\x0f\x54\xb2\xf1\xd6\x37\x64\x7b\x06"
+  "\x70\xf1\xf6\xdc\x21\x3d\xde\x0f\x94\x90\x78\x7f\xb1\x87\xf6\x0b"
+  "\x42\x74\x5e\x90\x5a\x5a\x59\x3c\x63\x5a\x89\xb7\x08\xbf\x7b\x96"
+  "\x90\x78\xb3\x6b\x26\xf8\x8a\xac\x99\x30\x43\x7c\xcd\x04\xe1\x78"
+  "\xf7\xcc\x73\x1e\xef\x9e\xa9\xd2\xe3\xdd\x33\x9c\xc4\x3b\x08\xf8"
+  "\xdd\x33\x8b\x8b\xb7\x97\x8b\xeb\x0a\xd8\xc6\xbb\xe7\x30\x12\xef"
+  "\x2f\x73\x21\xde\xc0\xef\x20\x89\xfc\xee\x79\xc1\x79\xbc\x83\x45"
+  "\xf8\xed\x3d\x8c\x8d\x37\xcb\x6f\x91\xf5\x1a\x66\x88\xaf\xd7\x20"
+  "\x1c\x6f\xef\x2e\xce\xe3\xed\x75\x5d\x7a\xbc\xbd\x8e\xb1\xf1\x06"
+  "\x7e\x7b\x99\xb8\x78\x7b\x27\x4b\x8f\xb7\xd7\x7e\x12\xef\xd2\x4c"
+  "\xda\x2f\x18\xf8\x1d\x2c\x91\xdf\xde\x63\x5b\x89\xb7\x08\xbf\xd5"
+  "\xfb\x49\xbc\xd9\xb5\x22\x7c\x45\xd6\x8a\x98\x21\xbe\x56\x84\x70"
+  "\xbc\xd5\xcb\x9d\xc7\x5b\x3d\x5b\x7a\xbc\xd5\x3a\x12\xef\x60\xe0"
+  "\xb7\x3a\x9e\x8b\xb7\xba\x5a\x7a\xbc\xd5\xfe\x24\xde\xe7\x52\x20"
+  "\xde\xc0\xef\x60\x89\xfc\x56\x1f\x71\x1e\x6f\xad\x08\xbf\x7b\xf9"
+  "\xb3\xf1\x66\xf9\x2d\xb2\x4e\xc5\x0c\xf1\x75\x2a\x84\xe3\xed\xf3"
+  "\x83\xf3\x78\xfb\x9c\x93\x1e\x6f\x9f\x1d\x6c\xbc\x81\xdf\x3e\x97"
+  "\xb8\x78\xf7\x8a\x92\x1e\x6f\x9f\x4c\x12\xef\xb2\x44\xda\x4f\x0b"
+  "\xfc\xd6\x4a\xe4\x77\x2f\xad\x58\xbc\xbd\x21\xde\x67\x40\xc7\x80"
+  "\xee\xc8\xb4\xe4\x82\x4e\x31\xf3\xe3\x5e\x9e\x3c\x0c\x3d\x7e\x17"
+  "\xc7\xde\x57\x09\x7d\x75\x66\xbb\xad\x97\xa1\xe8\x7d\xdd\xed\x6f"
+  "\x87\x15\xbd\x3f\x16\xfd\x76\x58\xd1\x7b\xaf\xe4\x6f\x87\x15\xbd"
+  "\xe3\x39\x0d\xd4\xbb\x88\xc3\xd4\x97\x69\x3f\x24\x7d\x53\xac\xe8"
+  "\x3d\x4b\x70\x1d\x0d\x45\x6f\x4f\xfc\x4d\x31\xbd\xa9\x3c\xc6\x92"
+  "\x27\x47\x1b\xf9\xaa\x5b\xc7\x3a\x48\x65\xc9\x05\x8d\x24\x8a\xb5"
+  "\x9f\x01\xfa\xad\xf6\x5b\xb7\x43\xe1\xf7\xb5\xfb\x58\xfb\xed\x13"
+  "\xc7\xda\x6f\x8b\x74\xac\xfd\xa2\x38\xfd\xe5\x97\xcf\x61\xdd\x47"
+  "\xfa\xf7\xe3\x0a\xbf\x70\xc1\xf5\x3c\x14\xbe\x46\x82\x75\x45\x89"
+  "\x25\x4f\x8e\x2e\xf3\x33\xb9\x80\x35\xd4\xeb\x20\x27\xf5\xfa\x17"
+  "\x97\x00\xeb\xcc\x76\x5b\x3f\x44\xf1\x8b\x33\xee\x63\xfd\x8b\x6d"
+  "\xe2\x58\xff\x62\x95\x74\xac\x7f\x31\x96\xd3\x7e\xbf\xc8\xe4\xb0"
+  "\xf6\x0f\x90\x8e\xf5\x2f\xc2\x04\xd7\x15\x51\xf4\xa9\x22\x58\x7f"
+  "\x15\x02\x58\xcb\xd0\x84\xbf\xa8\x6e\x1d\xeb\x60\xa8\xd7\xc1\x4e"
+  "\xea\x75\xdf\x12\xe8\xaf\xdb\x6f\x1d\x13\x45\xdf\x0f\xdd\xc7\xba"
+  "\x6f\xaa\x38\xd6\x7d\x63\xa5\x63\xdd\x37\x94\xd3\x9d\x7d\x93\x38"
+  "\xac\x1f\x54\x49\xc7\xba\xaf\x46\x70\x7d\x13\x85\x7f\x05\xc1\xfa"
+  "\x9f\x39\x96\x3c\x39\x7a\xb4\xaf\xa8\xfe\xb7\xc1\x1a\xea\x75\xb0"
+  "\x93\x7a\xfd\xd0\x11\xc0\x3a\xb3\xdd\xd6\x53\x51\x3c\xb4\xcb\x7d"
+  "\xac\x1f\x5a\x28\x8e\xf5\x43\x93\xa5\x63\xfd\x50\x00\xa7\x79\x1f"
+  "\x8a\xe6\xb0\x7e\xa8\x5e\x3a\xd6\x0f\x79\x0a\xae\xb3\xa2\x78\xf0"
+  "\x38\xc1\xfa\x42\x3d\x60\x2d\x43\x0b\x3f\x54\xdc\x3a\xd6\x5a\xa8"
+  "\xd7\x5a\x27\xf5\xba\x1f\xf8\x7a\x6d\xfb\xad\xeb\xa2\xe8\xb7\xd1"
+  "\x7d\xac\xfb\x4d\x15\xc7\xba\xdf\x48\xe9\x58\xf7\x53\x71\x7a\xbb"
+  "\xdf\x04\x0e\xeb\x7e\x7a\xe9\x58\x07\x18\x05\xd7\x7b\x51\x04\xec"
+  "\x27\x58\xff\x2b\xca\x92\x27\x47\x87\xf7\x13\xdd\xff\xc0\x99\x0e"
+  "\x5f\xb6\x0b\xa9\xf8\x78\x3f\x9c\xd3\xbe\x5a\xfc\xe1\x55\xee\xe3"
+  "\xfd\xf0\x38\x71\xbc\x1f\x1e\x2c\x1d\xef\xfe\x46\x4e\x8b\x3f\x3c"
+  "\x82\xc3\xfb\xe1\x0a\xe9\x78\xf7\xaf\x16\xd6\xe2\xfd\x77\xb8\xa7"
+  "\xc5\x1f\xce\x97\xa3\xc5\x1d\xf1\x86\x7b\xb7\xab\x1e\x0f\x5c\xe8"
+  "\x3e\xde\x81\x4f\x89\xe3\x1d\xd8\x4f\x3a\xde\x9a\x6a\x4e\x8f\x07"
+  "\x86\x70\x78\x07\x16\x4b\xc7\x5b\x53\x29\xac\xc7\x35\x99\xee\xe9"
+  "\xf1\xc0\x2c\x39\x7a\xdc\x11\xef\xe0\xc4\xf6\xd5\xe4\xc1\xd3\xdd"
+  "\xc7\x3b\x78\x80\x38\xde\xc1\x3d\xa5\xe3\x1d\x54\xc9\x69\xf2\x60"
+  "\x9b\xf1\xef\xe0\x22\xe9\x78\x07\x95\x08\x6b\xf2\xa0\x64\xf7\x34"
+  "\x79\x70\x8a\x1c\x4d\xee\x88\xf7\x80\xe8\xf6\xd5\xe5\x03\xc6\xbb"
+  "\x8f\xf7\x00\x3f\x71\xbc\xb5\x66\xe9\x78\x6b\x4b\x38\x5d\x3e\xc0"
+  "\x93\xc3\x7b\xc0\x1e\xe9\x78\x6b\x8f\x09\xeb\x72\x6d\x9c\x7b\xba"
+  "\x7c\x40\xbc\x1c\x5d\xee\x88\xf7\x23\x91\xed\xab\xcd\x1f\x19\xee"
+  "\x3e\xde\x8f\x74\x11\xc7\x7b\xe0\x75\xe9\x78\x0f\x3c\xc6\x69\xf3"
+  "\x81\x36\xe3\xff\x8f\xe4\x48\xc7\x7b\xe0\x7e\x61\x6d\x3e\x30\xca"
+  "\x3d\x6d\xfe\xc8\x2c\x39\xda\xdc\x11\xef\x41\xa3\xda\x57\x9f\x0f"
+  "\x1a\xe4\x3e\xde\xba\x3b\xe2\x78\xeb\x2e\x4b\xc7\x5b\xb7\x9f\xd3"
+  "\xe7\xba\x5a\x0e\xef\x41\x19\xd2\xf1\xd6\xed\x10\xd6\xe7\xba\x70"
+  "\xf7\xf4\xf9\xa0\x09\xee\x8f\x93\x87\x04\x60\x6d\x2e\x75\xfd\xc7"
+  "\xf2\x24\xf6\x9b\x3b\xc5\xa3\xdc\xfa\x8f\x8a\x90\x9e\x48\x6c\x6d"
+  "\x19\xc5\x63\x0b\x3b\xf4\xfa\x8f\x8a\x47\x9d\xaf\xff\xa8\x78\x54"
+  "\xda\xfa\x8f\x8a\xc7\x26\x4b\x9e\x8f\xaf\x78\x2c\x80\xf3\x08\x8f"
+  "\xd9\xf8\xff\x10\xb2\x47\x71\x47\x5e\x17\x52\xf1\x18\x7f\x5d\x48"
+  "\xc5\xa3\xcc\xba\x90\xf4\xa6\x7f\x1f\x97\xe7\x45\x42\x74\xee\xbf"
+  "\x17\x78\xdc\x88\x7d\x88\xd4\x75\x28\x39\x6e\x87\xdc\xe1\xb8\xfd"
+  "\x78\x8d\x38\xb7\x1f\x1f\xd7\xa1\xd7\xa1\x54\x0c\x3e\xeb\x9c\xdb"
+  "\x83\xf7\x4b\x5a\x73\x44\xf1\xb8\xf4\x75\x6f\x14\x83\x8d\x9c\x1f"
+  "\x7a\xdc\xc6\xff\x0e\x19\xd6\x7e\xdc\x96\xb9\x3e\xa5\x62\xf0\x25"
+  "\x3e\xb7\x43\x6a\x09\xb7\xbf\x51\xcb\xf3\x5d\x43\x94\xee\xbf\x07"
+  "\x19\x7a\x01\x7b\x2e\xa9\xeb\x61\x72\xdc\x1e\x72\x9e\xe3\xf6\xd0"
+  "\x33\xe2\xdc\x1e\x1a\xd8\xa1\xd7\xc3\x54\x84\xee\x73\xce\xed\xd0"
+  "\x75\x92\xd6\x32\x51\x0c\xed\x2e\x9d\xdb\xa1\x17\x38\xef\x37\xd4"
+  "\x9f\xe3\xf6\x13\xbe\xed\xc8\x6d\x99\xed\x76\xe8\x31\x3e\xb7\x87"
+  "\x94\x10\x6e\x5f\x8a\x91\xe7\x31\x87\xea\xdd\x7f\xef\x13\x56\x84"
+  "\xfd\xa5\xd4\x75\x39\x39\x6e\x3f\x71\x88\xe3\x76\x98\xc3\xba\x50"
+  "\x1c\xb7\x9f\x34\x77\xe8\x75\x39\x15\x4f\xae\x71\xce\xed\x27\xa3"
+  "\x25\xad\x91\xa2\x78\xf2\x07\xe9\xdc\x7e\xb2\x88\xf3\xb9\x4f\xd6"
+  "\x73\xdc\x0e\x33\xb4\x1f\xb7\x65\xae\xd7\xa9\x78\x32\x97\xcf\xed"
+  "\x27\x0a\x09\xb7\xff\x7b\x4c\x9e\x9f\x0e\x3b\xee\xfe\x7b\xae\x5f"
+  "\x66\x61\x2f\x2d\x75\x7d\x50\x8e\xdb\x4f\x6d\xe4\xb8\xfd\xcb\x54"
+  "\x71\x6e\x3f\xfd\x75\x87\x5e\x1f\x54\xf1\xb4\xf3\xf5\x7f\x14\x4f"
+  "\x3b\x5b\xff\xc7\xf1\x5b\x61\xc5\xd3\xd2\xd7\xbd\x50\x3c\x9d\xc5"
+  "\x79\xfa\xa7\x2b\x38\x6e\xff\xb2\xb4\x1d\xb9\x2d\xb3\xdd\x7e\x3a"
+  "\x91\xcf\xed\xa7\x32\x08\xb7\xbf\xf3\x94\x37\x76\xf0\xcb\x1d\xee"
+  "\xbf\xd7\x7b\x26\x0e\x8f\x1b\x48\x5d\xa7\x94\xe3\xf6\xb0\x58\x8e"
+  "\xdb\xcf\x4c\x17\xe7\xf6\xf0\xa3\x1d\x7a\x9d\x52\xc5\xf0\xe1\xce"
+  "\xb9\x3d\xdc\x5f\xd2\x9a\x2e\x8a\xe1\xd2\xbf\x83\x57\x0c\x8f\xe3"
+  "\xc6\x2f\x86\xdb\xcc\x7f\x7f\x66\x7f\xfb\x71\x5b\xe6\xfa\xa5\x8a"
+  "\xe1\x13\xf8\xdc\x1e\x36\x8b\x70\xfb\xfb\x68\x79\xe3\x24\xcf\x24"
+  "\xb9\x3f\x4e\x32\x32\x89\x79\x87\x29\x71\xbd\x54\x8e\xdb\xcf\x8e"
+  "\x6e\x59\x9b\x48\x31\x32\xd6\x9e\xdb\x2d\x6b\x13\x29\x46\xa4\x76"
+  "\x98\xf5\x52\x15\x23\x3c\x9c\xf3\xf8\x59\xbd\xb4\x31\x91\x11\xb1"
+  "\xd2\x79\x3c\x22\x94\x1b\x13\x19\x61\x33\xff\x65\xa4\x75\x4f\xf2"
+  "\x7b\xbf\x66\x91\x62\x64\x77\xa7\x6b\x16\x29\x46\x54\xdf\xb3\x75"
+  "\x54\x15\x23\x7c\x79\x6b\x16\x29\x9e\x1d\x66\x61\xea\xc2\x0f\x47"
+  "\xe4\x8d\xab\x8c\xcc\x70\x7f\x5c\x65\x14\x79\xbf\x2b\x71\xdd\x56"
+  "\xae\x2e\xfc\x6a\x22\x57\x17\x46\x2d\x11\xaf\x0b\xcf\x6d\xec\x30"
+  "\xeb\xb6\x2a\x9e\xeb\xe9\xbc\x2e\xfc\xaa\x56\xda\x18\xca\x73\xd2"
+  "\xd7\x81\x51\x3c\x37\x82\x1b\x43\x79\x2e\x83\xab\x0b\xa3\x8a\xdb"
+  "\xaf\x2e\x8c\xf2\x73\x5e\x17\x9e\xab\xbf\x67\xeb\xb9\x2a\x9e\xd3"
+  "\xf0\xeb\xc2\xaf\xc6\x92\xba\x50\x3d\x4c\xde\x38\xcc\x28\x59\xef"
+  "\xbf\xf9\x75\xe1\xd7\x59\xcc\xbb\x6f\x89\xeb\xc7\x72\x75\x61\xf4"
+  "\x74\xae\x2e\xfc\xda\x41\xcf\x73\x75\x61\x4c\x5e\x87\x59\x3f\x56"
+  "\x31\xa6\xaf\xf3\xba\x30\xda\x28\x6d\xcc\x65\x4c\xaa\xf4\xba\x30"
+  "\xc6\xe6\xfb\xa7\x31\x36\xdf\x3f\xfd\xba\xb4\xfd\xea\xc2\xaf\x03"
+  "\x9d\xd7\x85\x5f\xa3\x7b\xb6\xae\xac\x62\x4c\x08\xbf\x2e\x8c\x8e"
+  "\x24\x75\xe1\xda\x71\x79\xe3\x36\xbf\x76\x41\xff\xb7\x36\x6e\xf3"
+  "\x9b\x1d\xcc\xbc\x00\x89\xeb\xd8\x72\x75\x61\x6c\x2c\x57\x17\x7e"
+  "\xb3\x51\xbc\x2e\x8c\xdb\xdb\x61\xd6\xb1\x55\x8c\x1b\xe0\xbc\x2e"
+  "\x8c\x53\x4a\x1b\xa3\x19\xb7\x51\x7a\x5d\x18\x37\x85\x1b\xa3\x19"
+  "\xb7\x83\xab\x0b\xbf\xa9\x6c\xbf\xba\xf0\x9b\xc1\xce\xeb\xc2\x6f"
+  "\x3c\xef\xd9\xfa\xb6\x8a\x71\xc3\xf8\x75\x61\xec\x2c\x52\x17\xae"
+  "\x8f\x92\x37\xce\xf3\x9b\x42\xf7\xc7\x79\xc6\x17\x32\x73\x26\x24"
+  "\xae\xa7\xcb\xd5\x85\xe7\x97\x70\x75\x61\x7c\x9e\x78\x5d\x08\x3f"
+  "\xd4\x61\xd6\xd3\x55\x84\x0f\x75\x5e\x17\xc2\xd5\xd2\xc6\x74\xc2"
+  "\xf3\xa4\xd7\x85\xf0\x68\x6e\x4c\x27\xbc\x90\xab\x0b\xe3\xab\xda"
+  "\xaf\x2e\x8c\x1f\xee\xbc\x2e\x8c\xf7\xbf\x67\xeb\xec\x2a\xc2\xc7"
+  "\xf2\xeb\xc2\xf3\x71\xa4\x2e\xdc\x3c\x2d\x6f\x5c\x68\x7c\x91\xfb"
+  "\xe3\x42\x13\x8a\x98\xf9\x24\x12\xd7\xf5\xe5\xea\xc2\x0b\xa9\x5c"
+  "\x5d\x98\x20\xbe\xcf\x83\xe2\xb7\x1f\x77\x98\x75\x7d\x15\xbf\x75"
+  "\xbe\xff\x91\xe2\xb7\x4e\xf6\x3f\x12\x1a\x03\xfa\xed\x5e\xe9\x75"
+  "\xe1\xb7\xf1\xdc\x18\xd0\x6f\x6d\xbe\xff\x9b\x60\x68\xbf\xba\x30"
+  "\xc1\xf9\xfe\x0f\x8a\x09\x2e\xec\xff\x20\x73\xbd\x5f\xc5\x6f\x23"
+  "\xf9\x75\xe1\x85\x24\x52\x17\xea\xc2\xe5\x8d\x23\x4d\x68\x75\xfc"
+  "\x1f\xfb\xfc\x66\x5f\xc7\x71\xa4\xd2\xaa\x61\xe8\xb1\x19\xb8\x2e"
+  "\x4c\x8a\x31\xe5\x05\x66\xe2\xf5\x85\xcd\x5a\x76\x0d\xca\x35\xec"
+  "\x1a\x2f\xf5\x26\xb2\x06\xa5\xc1\xdc\xb2\x06\x25\x59\xfb\x03\x51"
+  "\xf8\x5b\x60\xfc\x4d\xb0\x49\x4d\xd6\x9f\xa4\xf1\x9c\x28\x3c\x47"
+  "\xea\x4a\x09\xb3\xbe\x4a\x8a\x09\x9e\xfd\x6a\x2b\xeb\x4f\x46\xeb"
+  "\x51\x69\xf4\x6a\x64\xf2\x79\xdb\x40\xbe\x13\x9e\x58\xcf\xac\x3f"
+  "\x39\xc7\xff\xc1\xec\xff\x22\x5f\x6f\xbc\xfe\x64\x34\x6d\x49\xd7"
+  "\xd3\x86\x32\x23\x82\xb4\x10\xdf\xb9\xec\x1a\x94\x8a\x49\xb3\xf1"
+  "\xb3\x9b\xe6\xe8\x1e\xdc\xfd\x5f\x91\xf5\x85\x15\x93\xa4\xaf\x03"
+  "\xab\x98\xa4\xe6\xc6\x77\x26\x4d\xe1\x38\x3a\x89\xe9\x83\xf5\x8a"
+  "\x89\xb5\xa5\x51\xd0\xc6\x6c\xaa\x2f\x6d\x96\xb5\xf6\xc6\xa4\xc4"
+  "\xd6\x31\x63\xe6\x88\x38\xb4\x5f\x1c\x66\x91\xfe\xa6\xbc\x20\x66"
+  "\x9d\x63\xd7\x31\xeb\x52\x77\x6f\x30\x8b\xd8\xef\x3a\x66\x91\x3e"
+  "\x7c\xcc\x84\xc6\x21\x22\x1a\xa5\x63\x16\x71\x9a\x1b\x87\x88\x54"
+  "\x71\x98\x45\x46\x11\xcc\x22\xf6\x10\xcc\xee\x18\x9b\x65\xad\xdf"
+  "\x11\xd9\xea\xf7\xdf\xd8\x37\x35\xfb\x3a\xfa\x72\x0e\xb3\xc9\xa5"
+  "\x80\x59\x26\x5e\x6f\xd9\x75\xcc\x1e\xb8\x72\x6f\x30\x9b\x3c\xcb"
+  "\x75\xcc\x26\x9f\xb1\xc3\x4c\xc0\x2f\x4f\x96\xbe\x67\xa7\x62\x72"
+  "\x32\xe7\x97\x27\x1f\xe7\x30\x7b\xd1\x93\x60\x36\x79\x0a\xc1\xac"
+  "\x41\xdb\x2c\x6b\x0d\x90\xc9\x95\xad\x63\xc6\xbc\xd3\x77\x52\xcf"
+  "\x5e\xca\x30\xe5\x05\x33\xeb\x3e\xbb\x8e\x99\xcf\x57\xf7\x06\xb3"
+  "\x97\xd4\xae\x63\xf6\xd2\x2a\x3e\x66\x42\xbe\xee\xa5\xb9\xd2\x31"
+  "\x7b\x29\x84\xf3\x75\x2f\x25\x72\x98\xbd\x54\x4c\x30\x7b\x49\x45"
+  "\x30\x33\x46\x36\xcb\x5a\x47\xe4\xa5\x56\xc7\xbf\xb0\x0e\x6d\xf6"
+  "\x75\xf4\x39\x1c\x66\x53\xc3\x00\xb3\x4c\xbc\xfe\xb4\xeb\x98\x3d"
+  "\xbd\xe9\xde\x60\x36\xe5\xb4\xeb\x98\x4d\x1d\x6c\x87\x99\x80\xff"
+  "\x98\xea\x27\x1d\xb3\x29\x7a\xce\x7f\x4c\xd5\x72\x98\x4d\x4d\x22"
+  "\x98\x4d\x39\x4e\x30\x6b\x4c\x69\x96\xb5\x16\xc9\xd4\x51\xad\x63"
+  "\xc6\xbc\x83\x75\x52\xcf\xa6\x55\x9b\xf2\xb4\xcc\x3a\xd8\xae\x63"
+  "\x36\x73\xcc\xbd\xc1\x6c\x5a\xb2\xeb\x98\x4d\xfb\x8e\x8f\x99\x90"
+  "\x4e\x9e\x26\x7d\x1d\x6c\xc5\xb4\x5c\x4e\x27\x4f\xab\xe4\x30\xfb"
+  "\x9d\x8e\x60\x36\x2d\x91\x60\xd6\xb4\xbf\x59\xd6\x7a\x26\xd3\x44"
+  "\xd7\xff\x72\xa6\x1b\xad\xf3\xf2\x39\xdc\xa2\xf6\x74\x1c\xed\x18"
+  "\x15\xea\x3a\x6e\x51\x3b\x5b\xd7\x8e\x51\x6b\xa4\xe3\x16\x35\x81"
+  "\xd3\x8e\x51\x39\x1c\x6e\x51\x7a\x82\x5b\x94\xce\x3d\xed\x18\xd5"
+  "\xea\xf7\xaf\x42\xda\xd1\x11\xb7\x19\x51\x1d\x47\x3f\x4e\xaf\x76"
+  "\x1d\xb7\x19\x93\x5b\xd7\x8f\x33\x86\x4b\xc7\x6d\x86\x92\xd3\x8f"
+  "\x33\xc2\x39\xdc\x66\xec\x20\xb8\x4d\xd7\xbb\xa7\x1f\x67\x88\xae"
+  "\xff\xe6\x4c\x3f\x3a\xe2\x36\x4b\xdd\x71\x34\xe4\xcc\x3d\xae\xe3"
+  "\x36\xab\x7b\xeb\x1a\x72\xe6\x2d\xe9\xb8\xcd\x3c\xce\x69\xc8\x59"
+  "\x88\xc3\x6d\x56\x24\xc1\x6d\xe6\x0e\xf7\x34\xe4\xac\x00\x39\x1a"
+  "\xd2\x11\xb7\xd9\x25\x1d\x47\x47\xce\x8e\x72\x1d\xb7\xd9\xa7\x5a"
+  "\xd7\x91\xb3\xa5\xef\x59\xac\x98\x9d\xc4\xe9\xc8\xd9\xc7\x38\xdc"
+  "\x5e\x26\x7b\xb0\x28\x66\x47\xba\xa7\x23\x67\xb7\xba\xfe\x87\x90"
+  "\x8e\x74\xc4\x6d\x4e\x46\xc7\xd1\x92\x73\x24\xe8\xff\x39\xf6\xfa"
+  "\x5f\x40\x4b\xce\x91\xa1\xff\xe7\x84\x70\x5a\x72\x8e\x8d\xfe\x9f"
+  "\xc3\xea\xff\x39\x2a\xf7\xb4\xe4\x1c\x17\xf4\xbf\xa3\x96\x74\xc4"
+  "\x6d\xee\xb0\x8e\xa3\x27\xa3\x4b\x5c\xc7\x6d\xee\xd0\xd6\xf5\xe4"
+  "\x5c\xe9\xfb\x40\x29\xa2\xab\x38\x3d\x39\x57\xc7\xe1\x36\x37\x99"
+  "\xe0\x16\x5d\xec\x9e\x9e\x9c\x2b\xba\xfe\xa3\x15\x37\xb3\x6f\x60"
+  "\x26\x2d\x30\x0e\x79\x2e\x6e\x18\xbb\x36\x61\x8c\xca\xec\x17\x98"
+  "\x29\x75\x7f\x17\xeb\x9a\xd3\x67\xe3\x10\xba\xa2\x98\xbf\xd7\xbd"
+  "\x75\xa7\xe7\x4f\x76\x7f\xdd\xe9\xf9\xfd\xda\x6c\x7f\x17\xc5\xfc"
+  "\x2e\xd2\xd7\x9d\x9e\x57\xc1\x69\xd0\xf9\xbe\x1c\xd6\x31\xcc\xfc"
+  "\x04\x69\xeb\x51\xcf\xcb\x75\x6f\x3d\xea\xf9\x3b\x09\xbf\xe6\x4d"
+  "\x21\xeb\x51\xcf\xcf\x69\x97\x7d\x5f\x14\xf3\x10\x5e\x8f\x9a\xde"
+  "\xd4\x7c\x41\xde\xfa\xc8\x31\xbe\xad\xf3\x39\x48\x45\x0b\x8c\xd1"
+  "\x72\x7c\x5e\x50\x69\xf6\x0b\x92\xbc\xcf\x0c\x9f\xcf\x0b\x96\xb8"
+  "\xc7\xe7\x05\x81\xee\xf3\x39\xf6\x7a\xdb\xed\x33\x13\x7b\x51\x3a"
+  "\x9f\x63\xf7\x70\xda\x3c\xb6\x8a\xe3\xf3\xef\xfd\xa5\xf3\x39\x36"
+  "\xc6\x3d\x3e\x2f\x58\x48\xf8\x1c\xab\x25\x7c\x5e\x10\xdd\x2e\xfb"
+  "\xcf\x28\x62\x2a\x08\x9f\x2d\x01\xf2\xd6\x9f\x5e\x50\xe5\x02\x9f"
+  "\x33\x69\x81\xf1\x6b\x8e\xcf\x0b\xf7\x03\x9f\x33\xa5\xee\x77\xc3"
+  "\xe7\xf3\xc2\xd1\xee\xf1\x39\xee\x96\xfb\x7c\x8e\x3b\xd1\x76\xfb"
+  "\xdd\xc4\xed\x93\xce\xe7\xb8\x44\xce\xb3\xc4\x1d\xe1\xf8\xbc\xb0"
+  "\x5a\x3a\x9f\xe3\xc2\xdc\xe3\xf3\xc2\xe1\x84\xcf\xbf\xaf\x27\x7c"
+  "\x5e\x18\xda\x3e\xfb\xe0\xfc\x7e\x0f\xc3\xe7\x6c\x14\x23\x6f\x7d"
+  "\xef\x85\xa2\xeb\x1f\x73\x7c\x0e\x56\xd1\x02\x63\xfb\x1c\x9f\xe3"
+  "\x93\xcd\x7e\xc1\x92\xf7\xdd\xe1\xf3\x39\xde\xcd\x7d\x2e\x5e\x69"
+  "\x83\x7d\x2e\x5e\x71\x63\x9f\x0b\xfb\x7d\x77\x5e\x59\x2e\x9d\xcf"
+  "\xaf\x8c\xe2\xbc\xdc\x2b\xeb\x38\x3e\xc7\x1f\x93\xce\xe7\x57\x94"
+  "\xee\xf1\x39\x9e\xdd\xff\x62\xd1\x69\xc2\xe7\x78\xd4\x3e\xfb\xf1"
+  "\x2c\x4a\x24\x7c\xa6\x0e\xca\x5b\x3f\x3d\x7e\x9d\x0b\x7c\xce\xa4"
+  "\x05\xde\x7b\x70\x7c\x7e\x35\x1c\xf8\x9c\x29\x75\xff\x1f\x3e\x9f"
+  "\x13\xbe\x73\x8f\xcf\x09\xdb\xdc\xe7\x73\xc2\xec\xb6\xdb\xff\x27"
+  "\x61\x9c\x74\x3e\x27\xa8\x39\x8f\x9b\x60\xf3\xfe\xff\xd5\x4c\xe9"
+  "\x7c\x5e\xec\xe6\xbe\x40\x09\x5f\x13\x3e\x2f\x66\xf7\x05\x4a\xa8"
+  "\x68\x9f\x7d\x81\x16\x8f\x22\x7c\x56\xd6\xcb\x5b\x9f\xfe\xd5\x29"
+  "\xad\xf3\x59\xab\xa2\x05\xde\x09\x71\x7c\x5e\xea\x6f\xf6\xd3\x4a"
+  "\xde\x87\x88\xcf\xe7\x25\x1f\xba\xc7\xe7\x25\x73\xdd\xe7\xf3\x92"
+  "\xc1\x6d\xb7\x0f\xd1\x12\x3f\xe9\x7c\x4e\xb4\xbe\xff\x83\xf6\x79"
+  "\x89\xcd\xfb\xbf\xa5\x32\xf6\x27\x4a\x2c\x74\x8f\xcf\x4b\x0e\x10"
+  "\x3e\x27\xc6\x10\x3e\x2f\xd9\xd3\x3e\xfb\x13\x25\xaa\x09\x9f\xbb"
+  "\x8d\x90\xb7\xfe\xff\xd2\x56\xe7\x7f\x08\x8d\x6f\x58\xc7\xa5\x38"
+  "\x4e\x27\xd5\xba\x3f\xc6\x91\xb4\xde\x3d\x4e\x27\x3d\xe5\x3e\xa7"
+  "\x93\x3c\xda\x6e\x8c\x63\x99\x8c\xbd\xfe\x96\x1d\xe1\xc6\x38\x96"
+  "\x19\x39\x4e\x2f\x0f\x91\xce\xe9\x65\xc9\xee\x71\x3a\x29\x95\x70"
+  "\x7a\xd9\x30\xc2\xe9\xa4\xa4\xf6\x19\xe3\x58\x5a\xe5\xde\x18\x47"
+  "\x92\x51\xce\x18\x87\x23\xa7\x57\x16\xbb\x3f\xce\xb1\x72\xba\x7b"
+  "\x9c\x5e\xd9\xdd\x7d\x4e\xaf\xb8\xd8\x76\xe3\x1c\x2b\x4e\x48\xe7"
+  "\xf4\x8a\x4c\x6e\x9c\x63\x45\x29\xc7\x69\x3c\x44\x2b\x95\xd3\x2b"
+  "\x26\xb8\xc7\xe9\x95\x93\x09\xa7\x57\x78\x12\x4e\xaf\x0c\x6f\x9f"
+  "\x71\x8e\xe5\xc7\xdc\x1b\xe7\x58\x59\x2a\x67\x9c\xc3\x91\xd3\xab"
+  "\x73\xdd\x1f\xeb\x58\x3d\xd8\x3d\x4e\xaf\xba\xec\x3e\xa7\x57\x1d"
+  "\x68\xbb\xb1\x8e\x55\xdb\xa4\x73\x7a\xd5\x2c\x6e\xac\x63\xd5\x1e"
+  "\x8e\xd3\xab\x2f\x48\xe7\xf4\x2a\x8d\x7b\x9c\x5e\x3d\x80\x70\x3a"
+  "\x59\x4f\x38\xbd\x3a\xa0\x7d\xc6\x3a\x92\xb3\xdc\x1b\xeb\x58\xbd"
+  "\x47\xce\x58\x87\x23\xa7\x53\xe3\xdc\x1f\xef\x48\xf5\x70\x8f\xd3"
+  "\x29\x1f\xba\xcf\xe9\x94\xd4\xb6\x1b\xef\x48\x89\x95\xce\xe9\x14"
+  "\x9b\xfd\x2f\x52\x6c\xbe\xff\x4f\xdd\x2f\x9d\xd3\xaf\xd5\xbb\xc7"
+  "\xe9\x94\x46\xc2\xe9\xd7\x8e\x10\x4e\xa7\x18\xda\x67\xbc\xe3\xb5"
+  "\x68\xf7\xc6\x3b\x52\x5b\x5d\xff\x42\x68\xbc\xc3\x91\xd3\x19\x23"
+  "\xdc\x1f\xf3\x48\xbf\xe8\x1e\xa7\xd3\xd7\xbb\xcf\xe9\xf4\xc9\x6d"
+  "\x37\xe6\x91\x3e\x5c\x3a\xa7\xd3\x95\xdc\x98\x47\xba\xcd\xfc\xa7"
+  "\x8c\x14\xe9\x9c\x4e\x2b\x71\x8f\xd3\xe9\xe7\x08\xa7\xd3\x32\x09"
+  "\xa7\xd3\x4f\xb7\xcf\x98\x47\x5a\x98\x7b\x63\x1e\x19\xe1\x72\xc6"
+  "\x3c\x1c\x39\xfd\xba\xda\xfd\x71\x8f\xb5\x07\xdc\xe3\xf4\xda\xe9"
+  "\xee\x73\x7a\xed\x80\xb6\x1b\xf7\x58\xdb\x53\x3a\xa7\xd7\x54\x72"
+  "\xe3\x1e\x6b\x6d\xd6\xbf\x7f\x3d\x52\x3a\xa7\xd7\xe4\xbb\xc7\xe9"
+  "\xb5\x7b\x09\xa7\xd7\xcc\x22\x9c\x5e\xbb\xa3\x7d\xc6\x3d\xd6\xa8"
+  "\xdc\x1b\xf7\x78\xdd\x61\xfe\xdb\xb2\xd8\x84\x18\xcd\xab\x0b\x16"
+  "\x2c\x8b\x4d\xd2\x2c\x8b\x5f\x38\x3f\x76\xe4\x00\xeb\xff\x47\x86"
+  "\x26\x0f\x48\xee\x81\x62\x16\xcf\x9d\xb3\xe2\x09\xee\x64\x7c\x6c"
+  "\x02\xfc\xd3\x03\xc5\xcd\x5d\x16\xa7\x49\x5a\x95\x18\xab\xc1\xff"
+  "\x5b\x3c\x3f\x11\x92\xbc\x9a\xc4\x1d\x79\x31\x36\x7e\x6e\xf2\xc2"
+  "\x84\xdf\x6b\xe6\xc6\x2f\xfc\x7d\xc2\xe2\xd8\x84\x24\xcd\xd2\xd8"
+  "\x25\xcb\x17\x2e\x8d\xc5\x7f\x2f\xd3\x2c\x78\x75\x29\x1c\x98\x1f"
+  "\xbb\x70\x45\xac\x66\xde\xf2\x05\x0b\x62\x97\x2e\xeb\x81\x26\x2e"
+  "\x8f\x4f\x5a\x98\x18\x1f\xab\x19\x3b\x71\xf4\xe0\x29\xe3\x5e\x9a"
+  "\xf2\xdc\x73\x3d\x90\xcd\xde\xd3\x1a\x3a\x77\x6c\x06\x70\x48\x79"
+  "\x55\xb1\xb5\x6f\x99\x3f\x42\x5b\x80\x9b\x5b\x97\x22\xf5\xa6\xa5"
+  "\x48\xb9\xb1\x0e\xa9\xb6\xd4\x21\x4f\xcb\x9b\xd5\x2a\xcd\x22\x34"
+  "\x8a\xf6\x99\xad\xde\x5a\x87\x7c\x2d\xdb\xf2\xa2\xe9\x6d\x79\x1a"
+  "\x83\x4f\x9a\x1a\xa7\xa5\x7d\x52\xc3\xf1\x71\xc0\x42\x49\x6f\x7b"
+  "\xbb\xe2\x8a\x22\xbb\x12\xce\x19\xd2\x6b\x10\x45\x7b\xad\x4b\x39"
+  "\x6c\x31\x50\xa7\x70\x8f\x06\xb1\x42\x8a\xf5\xb9\xf0\xcb\x40\x8a"
+  "\x0d\xa1\xf0\x1b\x05\xbf\x2c\xf8\x1d\x81\xdf\x71\xa4\x78\x43\x07"
+  "\xbf\x78\xf8\xe5\xc3\x6f\x3f\xfc\xf0\xb1\x0a\xf8\x55\x22\x45\xe6"
+  "\x58\xf8\xc5\xc0\x2f\x09\x7e\x59\x24\x9f\x4c\xf8\x6d\xf4\x85\xdf"
+  "\x08\xf8\x4d\x41\x8a\x4d\x2a\xf8\x41\x1e\x9b\x20\xbf\x4d\x90\xf7"
+  "\xa6\x09\xf0\xc3\xc7\x13\xe1\x87\xd3\xef\x20\xe7\x36\x47\xc3\x0f"
+  "\xee\xb1\x19\xf2\xdf\x0c\x79\x67\x79\xc2\x4f\x03\xbf\x10\xf8\x85"
+  "\xc1\x2f\x0a\x7e\x90\x26\x0b\xee\xb5\x05\xce\x6d\x81\x7b\x6c\x19"
+  "\x06\xbf\x1c\xf8\xd5\x23\x45\x36\x94\x25\xbb\x92\xfd\x65\xd9\xfc"
+  "\x8d\x7f\x15\x76\xff\xb7\xff\x19\xbc\xd7\x3c\xac\x2f\x7e\xd4\x04"
+  "\xf5\x76\xfd\x2d\x7a\x2d\x52\xd0\xdb\xd2\x0c\x89\x8f\x22\x8f\x6b"
+  "\x8a\xf5\x27\xca\xd7\x21\x68\x6f\xf2\x34\xc5\xab\x9b\xf0\xf9\x13"
+  "\x38\x66\x0d\xd9\xeb\x8f\xeb\x51\xfc\x30\x5c\x3f\xa5\xf1\x73\xfd"
+  "\x71\xf6\x7a\x93\xde\xa3\x47\x34\xbe\x9e\x7e\x33\x28\x92\x4e\x8f"
+  "\x7a\x17\x7f\x87\x0b\xf9\xe7\xe2\xef\x74\xe9\x9c\xc0\x12\x5a\x1d"
+  "\x90\x84\xdb\x98\xe2\xd5\x4c\xb9\xf2\x48\x7d\x84\xf3\x50\x36\x83"
+  "\x4f\xb5\x0a\xea\x9f\x12\xff\x9f\x06\xcc\xe9\x3d\x11\x71\xa4\xdd"
+  "\xd9\xc0\xf8\x97\x26\xbf\x61\xc5\xf8\x5c\xe3\x3e\x9f\x68\xba\xb0"
+  "\xb7\xa1\x38\xa1\x09\x55\x29\xd6\x6f\x83\x67\xa3\xa0\x0d\xa4\xe8"
+  "\x81\x3e\xd1\x96\xed\xc3\x8a\x3f\x06\x1e\xe0\x74\x9f\xa4\x55\xe3"
+  "\x7f\x73\xf0\x79\x3a\x77\x78\x26\x1e\x07\x2a\x4e\x7b\x0f\xda\xe5"
+  "\xf5\x79\x4d\x7e\x11\x91\x9a\x17\xbd\xe9\x2b\x8a\x0d\x83\xa0\x6c"
+  "\x4c\x7a\x6b\x59\x9a\x7c\xaa\xd5\x38\x7f\x5a\x13\xa9\x86\x73\x4a"
+  "\x28\x9b\x1a\xca\xe1\x71\x03\xae\xa3\xa1\x8c\xc5\x2f\xe2\xfb\xbe"
+  "\x11\x08\x65\xa5\xd2\x27\x43\xde\xef\x45\xaa\x3f\x58\x6d\xa4\xf0"
+  "\x39\x4b\x4e\x35\xe6\xbb\x27\x9d\xfd\xfa\xac\x77\x7a\x21\x65\xc1"
+  "\x9b\x08\xed\x7e\x13\xa9\x1a\xb2\xdf\xf0\xd7\x2b\x55\x4a\xd2\xf6"
+  "\xad\xcf\xa5\x20\x8d\x5e\xb1\xa1\x1e\x9e\xd3\xc0\xdc\xcb\x37\x0c"
+  "\x39\xb9\x57\x6c\xcb\xbd\xb6\x87\x21\x7c\x2f\x12\xa3\x6a\x15\x1b"
+  "\x2b\x26\x0f\x4b\x61\x2f\x35\x8e\x1f\x8e\x9d\x35\x0f\xcb\x36\x6b"
+  "\x1e\x1b\xd6\xe3\xeb\xf5\x8a\x37\xa2\xe8\xf7\x7b\xa9\x2d\xdb\x9f"
+  "\x55\xc3\xfd\xc3\xf0\x79\xef\x35\xa8\x9e\x86\x7f\xf1\xfd\x59\x2c"
+  "\x20\x9f\x0c\x84\xf3\xa7\xd9\x63\xc0\x1d\x48\xff\xc6\x1e\xcb\x5a"
+  "\x0d\xf0\x26\x58\x4d\x70\x7d\xe3\xfa\xaa\x0a\xda\x02\x3f\xf3\x90"
+  "\x0a\xe4\x51\xfc\x22\xc6\x34\xd3\x53\x33\xa9\x1b\xc4\x35\xb3\x67"
+  "\x4b\x3c\x03\x23\x71\x4c\xd4\x05\xbd\x20\x2e\x1b\x94\x51\x4c\x1e"
+  "\xf0\x3c\xb6\xf1\xc1\xcf\xd0\x90\x9d\x39\xc2\x2e\x46\x6a\x38\x16"
+  "\xa9\xf7\x50\xe6\xe0\x63\x9a\x20\x86\x4b\x79\x34\x8b\x17\xe6\x33"
+  "\xc6\xce\x92\x37\x36\x03\xff\x7f\xea\x20\xa4\xf6\xae\x40\x94\x26"
+  "\x4d\x7b\x8c\x60\x3c\x3c\x13\xca\x1c\x83\xef\x05\xff\x1e\xa4\xb7"
+  "\x0f\xa8\x34\xaf\x85\x3e\xb4\x85\x57\x99\xa5\xe6\x6d\xc1\xaa\x26"
+  "\xbf\x67\x46\x35\xe6\x3d\x89\xe8\x9c\x60\x15\xfe\xae\x1c\xca\xce"
+  "\x7c\x6b\x47\xaf\x55\x21\x72\x9f\x60\xcf\xb4\x78\xda\x90\x76\x0b"
+  "\xe2\xdf\xe7\x99\x51\x9f\xac\x30\x00\x0e\x4f\x22\x8c\xf3\xc7\x77"
+  "\x8d\x14\x5e\xeb\x8f\xf6\x7a\x3d\x6d\x37\x3c\xcf\x2e\x78\x16\x78"
+  "\x4e\x84\xf3\x6d\xc8\xde\xe8\xc9\x3d\x4f\x66\x11\xc6\x1c\xee\xa1"
+  "\x21\xf7\x86\x7c\x29\xb8\x87\x4f\xb0\x06\xd2\x85\xe9\x3d\x3e\xa8"
+  "\xb0\x3e\x37\x73\x6f\x2e\x1d\x5b\x47\x36\xea\x0c\x90\xb6\x79\x05"
+  "\x5d\xb1\xf5\x1b\xc8\x7f\x2d\xa2\x9b\xee\xd2\xa5\x29\x91\xb4\x31"
+  "\x7b\x1a\x9e\xbf\x78\x09\xa5\xcf\x45\x01\x0f\xac\xa1\x0d\x11\x66"
+  "\xe4\xfd\xc0\x25\x6f\xfa\x5c\xe4\x25\x66\xcf\x83\x94\x0a\xba\xba"
+  "\x2c\xf1\x38\x4a\xf9\x01\x79\xa6\x2e\x44\xbe\xe9\x91\xf0\x2c\xa5"
+  "\xb4\xb1\x3c\xf9\x12\x2a\xab\x87\x5f\xe2\x39\x48\x77\x11\x7e\xc7"
+  "\x51\xfa\x2a\xa4\x9c\x04\xfd\x59\xda\x1d\xe4\x59\x96\x78\x07\x8e"
+  "\x5d\x47\x29\xd1\xb4\xe9\x5c\x29\x4e\x77\x06\x45\x98\x0c\xde\xa9"
+  "\xd7\x91\x72\xf7\x34\xfc\xad\xf6\x65\x54\x00\x65\x69\xf2\xc9\x8b"
+  "\x6c\xdc\xf6\x76\xe5\xed\x15\xb4\xa9\x21\x7b\x13\xd2\xa3\x67\x34"
+  "\xbc\x67\xc1\x65\x6e\x42\x98\xdf\x1e\x38\x8d\x25\x6f\xa8\x7e\x8e"
+  "\x09\xb7\x1b\x1b\xeb\x41\x4f\x20\xeb\x79\x7c\xce\xe0\x37\x54\xaf"
+  "\x57\x6c\xd2\x44\x98\xe8\x06\xc0\x99\x79\x6e\x88\x7f\x00\xfb\xfc"
+  "\x01\x8a\x44\xa4\x84\x7b\xc4\xe8\x3d\x3e\x3a\x88\xef\x01\x79\x76"
+  "\x05\x1e\x6b\x30\x37\xd8\x73\x19\x7a\x8f\xa2\x7a\x8e\x2f\x0c\xfe"
+  "\x5d\xad\x65\x81\xf3\x7b\xf4\x1e\x1f\x9a\x6c\xf8\x84\xdb\x87\x96"
+  "\xf3\x6c\x3f\x85\xdb\x1c\x9d\x05\xb7\x99\xea\x80\x70\xb3\xdf\xf0"
+  "\x1c\xa8\x0b\x7b\xe8\xdb\xfe\x9e\x34\x45\x1b\x27\x99\x68\xa3\x25"
+  "\x4f\xab\x87\xbe\xc8\xb3\xdc\x54\x8f\x48\xfa\xcd\xe3\xa0\x0e\xed"
+  "\x27\x73\x43\x37\x0f\xc6\x79\x82\x66\x09\xcd\xae\x43\xea\x88\x0a"
+  "\xda\x88\xeb\xa5\x65\xdb\x2d\x4d\xf6\x52\xe4\x4b\xe7\x0d\xcf\xb0"
+  "\xf8\x85\xe5\x34\xee\x8d\x88\xc6\x6d\x27\xed\x37\x36\x83\xce\x81"
+  "\x6b\xd9\x7c\xe0\xbe\x5d\xf4\x8a\xcd\x4a\x0b\x5c\x4f\xe7\x6a\xf5"
+  "\x2c\x0f\x98\x76\x8e\xb4\x8f\x9b\x95\xf4\x00\x38\x97\x13\x30\x01"
+  "\xce\x75\xb9\xa2\xd8\x9c\x03\xc7\x81\xbf\x01\xeb\x8a\xd3\xea\x70"
+  "\x1e\x79\x84\x43\x01\xe1\xbc\xff\x53\x38\x9e\x6f\x14\xe1\x7a\x4d"
+  "\xf4\xe5\xe6\xa3\x5c\xbd\xb5\xd6\x13\xa8\xaf\x7e\x5a\xa8\x8b\x9b"
+  "\x4b\xf4\x1e\x3d\x8f\x31\x6d\x39\x5c\x57\xcf\xb4\x35\x6f\x9c\x06"
+  "\x2d\x16\xf7\x39\x28\xb7\xcf\x4b\x11\x82\x34\xb5\x7a\x0f\xef\x52"
+  "\x2e\x96\x59\x5d\x70\x5a\xa6\x4e\x42\xdd\x24\xf7\x03\x9e\xc3\x35"
+  "\xf4\xf6\x67\x42\x71\xfb\x82\xdb\x19\xbd\x22\x0b\xe1\x36\x06\xea"
+  "\xe7\x0e\xb6\x3d\xaf\x66\xea\xe7\x9b\xd3\xc2\xa1\x5c\x19\x57\xd8"
+  "\xb2\xd8\x96\xcd\xda\x96\xd0\xdb\xa6\x95\x90\xb4\xc1\xba\x86\xec"
+  "\xac\x78\xbd\x87\xba\xd0\x96\x6b\xe4\xb9\xb2\xbe\x1b\x52\x0a\x7f"
+  "\x83\xde\xb0\xe6\x05\x75\x55\x05\x6d\xf2\x76\xcc\x41\xdc\xe6\xec"
+  "\x7c\x13\xe3\x31\xad\xa2\x71\xdb\xb4\x4a\xc8\xe7\x88\xb5\x9e\x5a"
+  "\x56\xd0\x95\x80\x2b\xb2\xdc\xa5\x2f\x6c\x05\x2c\x23\xcc\x0a\x7a"
+  "\x8e\x39\x04\x81\x1e\x35\x15\xc0\xf1\x82\x15\x58\xcf\x6d\x34\x40"
+  "\x5d\x56\x09\xa7\x55\x22\x9c\x8e\x49\xcf\xa6\x6d\xf2\x99\x56\xc1"
+  "\x94\x79\xad\xc2\x02\xe5\xf3\xb0\x96\xa9\xc9\x27\xd8\xb7\x21\x7b"
+  "\x4b\xa8\x1e\x59\xf4\xbc\xfa\xf2\xe6\x43\x71\x34\x1d\x85\x79\xa5"
+  "\xb8\xaa\xd8\x32\x15\xfe\xed\xc6\xf2\xf4\x81\xcf\x41\xaf\x8e\x9d"
+  "\x08\x75\x05\xf0\x7e\xa7\x0f\x0d\x38\x6d\x49\xd4\xa3\x97\x73\xf1"
+  "\xf5\x9b\xe0\xff\xf8\x38\x4e\x03\xc7\x33\xf5\x68\x0e\xab\xb5\xdf"
+  "\x28\xc2\xf8\xd9\xe5\x7b\x88\xe4\xcb\x94\xe5\x01\x9c\x27\xbe\x0e"
+  "\xe7\xb9\x6b\x3b\x5d\x8b\xf3\x81\x3c\x4a\xad\x79\x6f\x81\x63\xd6"
+  "\xfc\xc7\x2e\x6e\xb9\x47\x2d\xdc\xc3\xd3\xb6\xec\x3b\xb7\xd3\xf5"
+  "\xa4\x5c\xd9\x2a\x3d\x5a\x30\x0b\x9f\xdb\x08\xc7\xf0\xb5\x36\xf5"
+  "\x4d\xc1\x71\x28\x1b\x9e\x3f\xa6\xca\xb6\x7d\x07\x8c\x7a\x5a\x35"
+  "\x01\x9b\xd7\x14\x6b\x5e\xf6\xf9\xd0\x39\xbf\x2b\xb2\xa9\xaf\x9e"
+  "\x38\x5f\x48\xbf\x4e\x8f\xe6\xea\x48\xb9\x36\x84\xd5\x13\xbe\x43"
+  "\xdc\xb3\x0f\xe0\xb8\xe3\xbe\xc6\xb2\x96\xd5\x1d\x7b\x23\xe2\x58"
+  "\x6e\x14\x5a\xfb\x23\xc0\x05\xfa\x9d\xec\x12\xae\xed\xce\xce\xc7"
+  "\x78\x43\x1c\x8b\xe9\x3e\xc3\x8b\x70\xbb\xc4\xd6\xc9\x13\xb8\x0f"
+  "\xb2\x3e\x3b\xe4\xa3\xb4\x64\xbf\xfe\x17\xcc\x7b\xe8\xd3\x10\xed"
+  "\xf7\x44\x62\x43\xf6\x56\xb5\x5d\x9f\xa6\x64\xd3\xfd\x88\xd3\xbc"
+  "\xd5\x87\xae\x86\x34\x61\xd6\x34\xf8\x3c\xc4\xf8\x57\x70\x2c\x5c"
+  "\x8f\x16\xc5\xe3\x63\xd9\x90\x46\xaf\x58\x27\xfa\x0d\x4c\x5a\x20"
+  "\xa2\xca\xf3\xf5\xd8\x1f\xe2\x3a\x3e\xa2\x3c\xa0\x1e\x95\xe7\x5b"
+  "\x90\xe5\xfd\x5e\x39\xa3\xd2\xe8\x62\xd0\xdc\x67\xca\x8c\xd5\x48"
+  "\x9a\xa6\xdb\xca\xec\x5f\x44\x37\x81\x8f\x49\x79\x02\xe1\xfe\xfe"
+  "\x86\x22\xe7\x4e\xb9\xa1\x8e\x69\xef\xe0\x6f\xe6\x9b\xcb\xb7\xc0"
+  "\xf7\x60\xef\x03\xfe\x36\x2e\x87\x22\xfe\xc7\x02\x69\x77\xe3\xe3"
+  "\xd8\x1b\x81\x2f\x2b\xb0\x39\x47\xbf\xef\xa3\x26\xb1\xcb\x39\x84"
+  "\xe3\xc8\x94\xd7\xf4\x7c\x31\x2e\xb3\xa5\xd0\x47\x8d\x9f\x21\x3d"
+  "\x99\xb6\x94\x9b\x1a\x8a\xcb\xea\xcd\x48\xb3\x02\xfb\xb6\x9c\x8d"
+  "\x11\xbb\x10\x0d\xed\xa1\x44\xdf\x94\xc3\xcc\x7f\x00\x6f\x7b\xc3"
+  "\x30\xc0\x47\x9d\x6e\x46\xd4\xd6\xb4\x2e\xaa\x5f\xe7\xd3\xc5\xb7"
+  "\x07\xf6\xca\x69\xc8\xce\x39\x78\x2a\x19\x21\xe9\x7a\x37\xe7\xa0"
+  "\xf5\xd9\x77\xb3\xcf\x0e\xc7\x98\xef\xe5\x87\xec\xc8\x60\x9e\x17"
+  "\xfe\x2f\x3a\xd7\x93\x5e\xeb\x4d\x7f\x9e\x6f\x42\xcb\xf2\xe9\xa6"
+  "\x65\xbb\x10\x65\xde\x3e\x30\xfa\x83\xdd\x95\xb8\x6d\x1f\x65\x8d"
+  "\x27\x13\x3b\xf0\xf4\x89\x69\x48\x7d\x4d\xb1\x6d\x4b\x44\x4a\x06"
+  "\xb3\x0f\xd2\x49\x48\x27\xad\xac\xdb\x98\xf9\x05\x65\xe0\x95\x23"
+  "\x4c\xe9\x34\xe9\x9f\xb6\x1d\x9d\xc4\xe6\x87\xcf\x59\xf1\xdb\xcd"
+  "\x7a\x58\x19\xf7\x10\x5d\xff\xc4\xc9\xb3\xaa\x85\x9f\xf5\xcd\x55"
+  "\xf2\x9f\xf5\xcd\xb1\x8e\xcf\xfa\xe6\xde\xb6\x7d\xd6\x37\xf7\xcb"
+  "\x78\x56\x8d\xf0\xb3\xbe\x15\x2b\xff\x59\xdf\x0a\x75\x7c\xd6\xb7"
+  "\xb6\xb4\xed\xb3\xbe\x95\x2b\xe3\x59\x43\x85\x9f\x35\x77\xb2\xfc"
+  "\x67\xcd\x0d\x70\x7c\xd6\xdc\x55\x6d\xfb\xac\xb9\x19\xa2\xcf\x4a"
+  "\x79\xd3\xb8\x7d\x82\x76\xa9\x29\xad\x11\x74\xdd\xf6\x11\x9a\xd4"
+  "\xbd\x88\x2a\xad\x37\xa2\xb2\x80\x4a\xac\x99\xa9\xc7\x13\x19\xdd"
+  "\x33\x82\x7e\xb3\x5a\x53\x96\x5f\x0b\xc7\xaf\xa2\x73\xc9\x46\x34"
+  "\x6a\x29\x6e\x7f\xf3\xc6\x95\xc7\x48\x6d\x7f\xf3\xd4\x2d\xed\xaf"
+  "\xe9\x09\xb6\xcd\xdd\xbe\xa4\xac\xb6\x09\xe1\xe7\x87\xbf\x67\xb7"
+  "\xb4\xbf\x6b\x49\xbc\xed\xdb\x5f\x1c\x8f\x72\xa3\x91\xd7\xfe\x92"
+  "\x6f\xa1\xb6\x0f\xb2\x6f\x7b\xb3\xaf\x21\x24\xdc\xf6\x6e\xef\x82"
+  "\xdb\xde\xdd\x70\x5e\x62\xf9\x2b\xac\x6d\x6f\x0e\xdc\xd3\xb6\xed"
+  "\xfd\x3c\x06\xf7\xd1\xdb\x75\xf2\xda\xde\xed\x3a\xeb\x73\xef\x62"
+  "\x9f\x1b\xee\x95\xc5\x6f\x7b\xb7\x47\xbb\xc2\x5b\x7a\x7b\xe0\xa8"
+  "\x0f\xfa\x1b\xbb\x58\x0a\x7b\x47\xe2\xfe\xad\x01\x62\xf2\xd7\xdd"
+  "\x46\x25\x3c\xb3\x9e\x19\xb3\x6c\x88\xf1\xa0\x0b\x7d\x8c\x11\x49"
+  "\xf4\xb7\xf4\x80\xde\x91\x78\x3c\x12\xfb\xea\xab\x8a\xb7\xfd\x40"
+  "\xdb\x1b\x25\x96\x5b\x4f\xfa\x3f\x75\x4e\x1a\xd4\x97\x0f\x56\x18"
+  "\x29\xcb\x6b\x51\xde\x80\x83\x9a\xce\x1b\x90\x41\x6f\xe8\x1d\x70"
+  "\x3b\xef\x19\xc3\x19\xdd\x0f\x08\xa7\xa5\xd7\x28\x47\xc8\x2f\xff"
+  "\xdb\x7b\x5a\x29\xff\x45\xe9\xe5\x27\x79\xba\x56\xfe\xb7\xf7\xb8"
+  "\x54\xfe\x3e\x50\xfe\xa6\x61\x5d\xc0\x0b\x52\x27\x9b\x86\x29\xa5"
+  "\x95\x67\x47\xa8\x4b\x18\xbb\x77\x0f\x97\xdb\x3f\xba\xcf\x13\x19"
+  "\x1f\xec\x36\x50\xd0\x06\x30\x7d\x38\xae\x7b\xa4\xfd\xab\x86\x36"
+  "\xeb\x5b\x9a\xb4\x49\x06\x89\x6d\xd2\x4e\xd1\xef\x9f\x1c\xef\x3f"
+  "\x50\x7f\x0f\xee\x2f\xfe\xfc\xf6\x6d\xe2\x61\xdf\x44\xd1\x36\x71"
+  "\xfb\x00\xbd\x63\x9b\xf8\xce\x74\xe9\x6d\xe2\x3b\x5a\xc7\x36\xf1"
+  "\xdd\xf5\x5c\x9b\xf8\xee\x12\xf9\x6d\xe2\xbb\x23\x5d\x6f\x13\xdf"
+  "\xed\x2b\xaf\x4d\x7c\xa7\xca\x79\x9b\xf8\xee\x08\x79\x6d\xe2\xbb"
+  "\x23\x1c\xdb\xc4\x77\xf6\xf0\xdb\xc4\x77\x45\xdf\xf5\xd2\x39\x0f"
+  "\x84\x42\x1f\xed\x79\x4d\x91\x3f\xd6\xb4\x16\xfc\x6c\xce\xeb\xaa"
+  "\x08\x33\xdd\x40\x6f\x7b\x20\xd4\x42\x85\xe1\x76\x65\x54\x43\x43"
+  "\x9c\xca\xb2\x52\xe7\x49\xf7\x7a\xe8\x2e\xdd\xec\x8f\xc7\xef\xb4"
+  "\x50\x7e\x6f\xba\x41\xe7\x45\xaf\xd4\xf5\xca\xbf\x8b\x7c\xe1\xe7"
+  "\x9f\xcf\xf6\xc7\xf0\x77\x28\xbd\xd2\xbf\x47\xf6\x0a\x14\xe2\x5d"
+  "\x8f\x54\x50\x86\x28\xef\x35\x6a\x04\x6d\x90\x2f\xfe\x9b\x5e\x5b"
+  "\x50\x54\x70\x17\x29\xbd\x93\x01\x1b\x1f\xb8\x5f\xb2\x37\x4d\x2f"
+  "\xd3\xa1\x82\xa5\xe0\xab\x29\xe4\xbf\x9b\xa2\x8b\x4c\x0d\x3a\xca"
+  "\xec\x3b\x7c\x0f\xc1\x27\xdf\xc8\x78\xaf\xdc\xe1\xf1\x96\x3e\xc3"
+  "\xa7\x98\xd3\xe3\x14\xf4\x6b\x51\x0a\x5c\x56\x73\xee\xf0\x48\x7a"
+  "\x3b\xfc\xd2\xe3\xbc\xb0\x86\x06\xdf\x1d\x4a\x37\xf8\xf7\x00\x4f"
+  "\x1e\xb2\x7b\x05\xd2\xee\xba\x8b\x74\xf4\x6d\x1d\x05\xf8\x47\xe1"
+  "\xfd\x44\x21\x46\x51\x16\xaa\xa0\x08\xce\x29\x71\x9b\x48\xe3\xfb"
+  "\x9b\xe0\xfe\xcd\x70\xff\x26\xcc\x6d\xe4\x5f\x00\xf7\x37\xaf\xd4"
+  "\x49\xac\x2f\xf9\xcc\xfa\x67\xd6\x72\x59\x42\x02\x12\xe9\xc3\xf0"
+  "\xc3\xe5\x82\x18\x16\xe0\x98\x3c\x1e\x90\x84\xcb\xb6\xe5\x2e\x0a"
+  "\x81\x72\x6a\xa1\x0c\x3a\xb8\x2f\x5e\x8b\x25\xea\xe5\x25\x6a\xcc"
+  "\x51\x5e\xd9\xcc\xdb\xd8\xb2\xdd\x84\xb2\xdd\xe0\xca\x86\xef\x85"
+  "\xe3\x23\xf6\x9e\x33\x22\xb5\x3f\xae\x9b\xff\xf3\x4e\xee\x16\x8e"
+  "\xdf\x79\xde\x7e\x2d\x4e\x22\x57\x77\xe5\x88\xf1\x65\xeb\x61\x14"
+  "\x40\xab\x53\x87\x4d\x5a\xff\x2d\x1d\x61\x42\x68\xfd\x61\x14\x52"
+  "\x0e\xf5\xba\xcc\x78\x1d\xd1\x3e\xa9\xc3\xce\xe8\x6a\xa5\xde\xcb"
+  "\x24\x76\xaf\x4d\x6b\xe9\x0a\x8b\xef\xf0\x1c\xda\xf7\x99\xea\xad"
+  "\x6b\xe9\xe4\x66\xad\x4f\x68\x93\xb6\x17\x9a\x63\x52\x03\xaf\xe9"
+  "\x64\xcd\x52\xa4\xb9\xaa\x28\x1c\xfd\xc5\x05\xf0\xa5\x33\x90\xea"
+  "\x8a\xa2\x30\x39\xfd\x6b\xfc\x3e\x68\x77\x16\xff\x7d\xd0\xee\x22"
+  "\xa4\xd8\xa3\x41\x8a\xbd\xa1\x48\xf1\xde\x14\x04\xe9\xf8\xbf\x3f"
+  "\x24\x92\xbc\x0a\xcc\x11\x07\xfa\xa3\x34\x13\xfd\x3f\x3a\xa7\x26"
+  "\x2a\x9b\xa2\x8d\x11\x83\x3c\xf4\xc5\x2b\xf0\x7b\x92\x82\x3b\x10"
+  "\xd3\x1f\xa1\xaf\xf5\x86\xbf\x4f\x01\xa6\x28\x71\x29\xea\x7d\x4d"
+  "\x51\x50\x8c\xeb\x8d\x77\x7d\xb7\x70\x73\x7a\x14\x32\x69\x22\xa2"
+  "\x9b\x73\x87\x67\x98\x73\xb5\x7a\x8b\xfa\x75\x55\x7a\x0d\x0a\xc0"
+  "\xef\x37\xa1\x6e\x44\xcd\x31\xab\x70\x7d\x8c\x2a\x9e\xf7\x05\xba"
+  "\x9a\x84\xa8\xf4\x3b\xa8\x27\x70\xb3\xa5\x5e\x4d\xac\xf5\x36\xa6"
+  "\xd6\xd2\x16\x5c\xb7\xf0\xf8\x2a\x9c\xf3\x4a\xbb\x03\xfe\xde\x50"
+  "\x8d\xf2\x97\x22\x5f\xf3\xb2\xb8\x5e\x86\xdb\x71\xbd\xdf\xb5\x20"
+  "\x5f\xaf\x7a\xa4\xce\xaf\x03\x4e\x2d\x03\x3e\xd5\x41\x3d\x33\x90"
+  "\x7a\x86\xbf\xa7\xdf\x8d\xeb\xd8\xa6\xbf\xe7\x17\xd4\x91\x3a\xc6"
+  "\xf0\x08\xd7\xb1\x57\x81\x47\x09\xb8\xff\x00\x1e\xad\x85\x3a\x06"
+  "\xf5\x82\xce\xde\x95\x98\xbf\x96\x46\xa9\x0b\x11\x55\x70\xad\x1b"
+  "\x3e\xe7\xd1\x65\x10\xa5\xf9\x22\xd2\x88\xb8\xb1\x8e\xc2\x55\x4d"
+  "\x03\x7a\x21\xcd\x8b\xf4\xcd\x2b\x8a\x82\x5a\x38\xae\xd2\x4c\x7b"
+  "\x44\x0d\xf1\x5e\x45\xc6\xe6\x0a\x93\xf1\x78\xa7\x1e\x62\x81\xe3"
+  "\xa2\x79\x11\x3d\x72\x45\xb1\xfb\x14\x8e\xe3\xca\xfd\x48\x91\xf8"
+  "\x2b\xba\x0a\x62\x56\x42\xc6\x74\x77\x17\x33\xef\x49\xd7\x68\xd0"
+  "\x97\xcc\xfb\x29\x72\x8d\x19\xe2\x66\x52\x57\xef\x07\xbc\x8b\x8a"
+  "\x17\x35\x31\xed\x10\x8e\xe3\xd5\x78\x44\xcd\xa9\x85\x58\x99\x21"
+  "\x56\x0d\x3a\x4f\x68\x8f\x22\x71\x7b\x44\xe7\x3c\x64\x48\xd1\xd3"
+  "\x96\x88\x18\x05\x9d\xb6\x04\xa9\xca\x93\xcd\xe8\xe5\x44\x44\xa7"
+  "\x5e\x87\x78\xd5\x57\x22\x68\x97\xbc\xa0\xcd\xea\xb5\x6b\x05\xf2"
+  "\xc5\xf1\xea\x59\x0b\x5a\xe5\xcd\x74\x74\x38\xad\xa4\x8b\x19\xf8"
+  "\x8b\xdb\x27\xef\x35\x1e\xdd\xa1\x9e\x79\x65\xe1\xfa\x08\xf5\xd3"
+  "\x7b\x0d\xd3\x5e\x46\xe5\x43\x3d\x34\xad\xd4\x05\x35\xaf\xd4\x69"
+  "\xe0\xd7\xdf\xda\x86\x59\xdb\x0f\x88\x59\x25\x6e\xbf\xca\x93\xf5"
+  "\xc8\x04\xb1\xf5\xc2\x7d\xdd\x4a\x5d\x00\x13\xe3\xdf\xeb\xd0\x10"
+  "\x23\xf2\x80\x32\xa9\xa1\xbc\xa8\x60\x01\x52\x9d\x8b\xbb\x82\xcc"
+  "\x50\x37\xac\x71\x9f\xb8\x50\x83\x20\x5f\xea\x8c\xee\x22\x62\x63"
+  "\xe6\x21\xce\xbb\xf7\x26\x72\xbc\x7b\x6f\x22\x8e\x1d\xe1\xdd\x7b"
+  "\x13\x7e\x8e\xbc\xfb\x32\x8a\xe1\x9d\xa2\x79\x00\xc3\xa7\x92\x72"
+  "\xd3\x47\x10\xa3\xf7\x70\xec\x10\xe6\xcc\xd9\x3f\x61\xce\xfc\x21"
+  "\xba\xa3\x72\xa6\xb1\x41\xa7\x81\xdf\x3d\xe1\x0c\xe4\xcb\x70\x06"
+  "\xc7\xea\xcb\xa8\x26\x64\x8d\x11\x53\x57\x73\x52\x87\x69\xd2\xd1"
+  "\x73\x50\x57\x93\xbd\xd7\xf4\x47\xe7\x98\x38\x15\x26\x6b\xa6\xd1"
+  "\x96\x2b\x8a\x3f\xec\x4c\x3f\x8f\xd4\x4d\x6b\x69\xba\xdc\x74\x08"
+  "\x59\x7c\xc3\x72\x98\x77\x7e\x39\xb7\x34\xe0\x59\x55\x34\x7e\xd7"
+  "\xbe\x16\x30\x4b\xc4\x63\xf4\x69\x6a\x73\xde\xd8\x0c\xcb\xb6\xd4"
+  "\x70\xda\xe7\xed\x0a\x33\xd4\x6b\xcb\xb6\xd9\x6a\x8b\x4f\x9e\xa6"
+  "\x21\xfb\x0f\x7a\x3d\x3a\xe1\xcb\xbc\x17\xc8\x1d\x9e\x03\x6d\x03"
+  "\x6e\x7f\x99\xef\xfd\x0c\xcc\x3b\xbc\x42\x64\x7d\x87\x8c\xdb\x04"
+  "\xf6\x3d\x04\xfb\x9e\xa2\x10\x3f\x4b\x0f\xfc\x9e\x82\xb4\x29\x7f"
+  "\xb8\x65\x7d\x4f\x61\xfd\x3f\x3e\xaf\x57\xfc\xa1\x1e\x8f\xab\xda"
+  "\x5c\x97\xc8\xa6\x63\xaf\xdb\xbd\x1c\xb7\xf5\xdc\x75\xe4\xff\xd0"
+  "\xae\x24\x36\x53\x48\x25\xa8\x71\x7c\xc7\x66\x40\xfd\x01\x6f\xb4"
+  "\xef\x16\xfc\x4b\xc1\xbf\x3e\xf0\xaf\x02\xca\xce\x8c\x63\x4a\xeb"
+  "\xaf\x0a\x0f\x92\x77\x45\xcf\xfa\xb2\x6d\xe3\x21\xa6\x4e\x3e\x8a"
+  "\x7a\x5e\x63\xff\x6e\xc8\xde\xa7\xb2\xbe\x0b\x6f\x49\xcf\xe1\x53"
+  "\x88\xef\x0d\x18\x29\xc9\xfb\x79\xf2\x7f\x3c\xf7\x85\xcd\x8f\xf9"
+  "\xbf\x45\xdb\xdb\x50\x9c\x76\x05\xd5\x2a\xf6\x25\x95\x43\x1f\x6e"
+  "\xd9\xfe\xac\xef\xd6\xbb\x50\x07\x92\x5b\xda\xe4\x43\x50\x17\x55"
+  "\xc5\xab\x99\x34\x53\x19\x9d\x9b\x3b\xd4\x40\xbf\x59\xa3\xc1\x5e"
+  "\xb0\x81\x8e\xfb\x15\xfb\x2f\xd6\xb6\x0a\x32\x6e\xb2\xef\x14\x0d"
+  "\xd8\xe2\xfd\xd0\x5b\xe6\x03\xe1\x7d\xca\x33\x94\x01\xa7\x52\x48"
+  "\x5f\x69\x2d\x2f\xde\xcb\x1c\xcf\xb7\x79\x24\x03\x65\x34\x08\xec"
+  "\x65\xce\xcd\xcb\xd9\x77\xd0\x92\x37\x14\xb0\xdf\x07\xcf\xba\x7b"
+  "\x84\xed\x33\x0b\x61\xa1\x57\xbc\xef\x2f\x76\x4e\x1a\x0e\xef\x87"
+  "\x89\xe5\x33\x4e\x67\xa6\x25\xe6\x25\x3e\xfe\xa3\x55\xe7\x44\xec"
+  "\x37\x17\x5b\x9a\xa3\xbc\xcf\xa4\x5c\x97\xa8\x6d\xde\x17\x5d\xff"
+  "\xd4\x9c\x1b\x56\xd4\x3c\x50\x8d\xdf\x63\x78\x9a\x5f\x8d\x7a\xbe"
+  "\x6c\xbf\x09\x1d\x48\xa8\xa6\x70\x7b\x78\xf0\x5a\x11\x15\x31\x88"
+  "\xd5\x70\x55\x48\x8d\xc7\xbd\xb0\x96\xcb\xbe\x81\xb4\x4d\xe9\x51"
+  "\xde\x4d\xcd\x51\x68\xf3\x0d\x34\xc2\xf2\x7b\xff\x1e\x59\x0b\x90"
+  "\xb2\x11\xda\xc2\xc6\xff\xc5\x79\x7f\x79\xa9\x1a\x9d\x84\x6b\xcb"
+  "\xea\xf5\x68\x37\xa4\xa5\xff\x17\xe5\xf5\xdb\x68\xda\x58\x1a\xfd"
+  "\x11\x8a\xd0\x99\x8b\xd3\xbe\x43\x3d\xa1\x4d\x54\x97\x27\xef\x63"
+  "\xde\xed\x76\x59\x45\x69\xca\x4d\x3f\xa0\x2d\x0b\xa0\x2d\x85\xb6"
+  "\x33\x7d\x2a\xf4\x19\xc0\x89\x77\x6d\xfb\x8c\x45\xef\x70\x7d\xc6"
+  "\x4d\xe8\x33\xde\x84\x3e\x23\xdd\x1f\x95\x25\x16\x23\x68\xc3\xba"
+  "\x4d\x4a\xf4\x36\xa6\x25\x42\xdf\xb1\x0a\xfa\x8e\xe4\x1f\x10\xd3"
+  "\x6f\xd4\x56\x23\x68\xf3\xbd\x76\x25\x20\xdf\xa6\x9b\xd0\x77\xdc"
+  "\x84\xbe\x23\x8d\xf4\x1d\x3b\x6f\x40\xdf\xf1\x2a\x78\x83\x04\xe8"
+  "\x3b\x6a\x05\xfa\x8e\x1b\xc2\xbe\xc0\xda\x0e\x36\xde\xd4\x51\x3b"
+  "\xa1\xdf\x58\x7d\x11\x51\x3b\xa7\x75\x93\xc8\x99\xfd\x71\xa2\x38"
+  "\x6f\x7f\xe6\xb6\x85\x8e\x42\x38\xee\xab\x8d\xd0\x0f\x03\x2e\xe5"
+  "\x3a\x13\xf2\xbe\xd0\x2d\xbc\x11\x8e\x37\xf7\x09\x8c\xde\xff\x8d"
+  "\x81\xa2\x73\x07\x64\x34\x02\x6e\xab\x97\x23\xaa\x19\x30\x3c\xf8"
+  "\x62\x0e\x85\x7d\xa2\x25\x2f\xb0\x90\x78\xd2\x3f\xad\xc1\x63\x22"
+  "\xde\x7a\x82\x9b\x89\x8e\xf2\xa6\xe7\x47\xf5\xdc\x32\x0f\x29\xcd"
+  "\xdf\xfb\xf7\xb0\xcc\xf7\x57\xa5\x5d\x44\x6a\xc3\xfc\x38\x88\xd7"
+  "\x75\x74\xf2\xab\x1c\xaa\x60\x06\xd2\xe0\xb5\x0f\xe9\x0d\x27\x92"
+  "\x0b\x5e\x46\xc3\x0a\xfe\x8b\xc2\x76\xcf\x40\x21\xbb\xbe\xc1\x6b"
+  "\xa4\x03\x86\xd5\xb4\xf1\x5c\xdc\x27\xf8\x7d\xfb\x28\x7a\xbb\x36"
+  "\x9a\xf6\x0b\x2b\x82\xbf\x87\xe5\xcc\x00\xff\x00\xe7\x23\x74\x8d"
+  "\xc5\xe5\xc9\xe7\x50\xd6\x15\x84\xd2\x6a\x58\x8c\x5b\xf0\xbd\x8c"
+  "\x4c\x14\xb4\x1f\x58\x13\x4c\x24\xf8\xe2\xf7\x60\xd8\x73\xb4\x60"
+  "\xbc\xe0\x33\xbe\x2e\x60\x31\x3e\x57\x5b\x81\xa0\x0f\xec\xd6\xa2"
+  "\x0f\x18\x8c\x2f\x23\xab\x36\x00\x6c\xbc\x40\x0b\xf8\x36\xde\xb6"
+  "\xd3\x07\x4b\x65\xea\x03\xd6\xdf\x98\x96\xe9\xa8\x7c\x8a\x46\xe9"
+  "\xe7\x10\xb5\xc3\x22\x15\xe3\x3f\x31\xeb\x3f\xe2\xb1\x2f\x32\x0f"
+  "\xe6\x40\x17\x8c\x85\x5e\x71\x40\x39\x55\xe7\x81\x64\x62\xaf\x77"
+  "\x8e\x7d\x90\x96\x60\x7f\x30\x55\x26\xf6\x7a\xc0\xbe\x42\x1e\xf6"
+  "\x77\x24\x62\xcf\xac\x21\xf9\x33\xc5\xfe\x60\x38\x1f\xfb\x3f\x7b"
+  "\x10\xec\xff\x8c\xe4\x63\x1f\xd4\x4a\xbd\x0f\x62\xeb\xfd\xe1\x55"
+  "\xf2\xb0\x0f\x82\x7a\xff\xa9\x4e\x1e\xf6\xd7\x25\x62\xcf\xac\x43"
+  "\xf9\x33\xc5\xfe\xf0\x58\x3e\xf6\x07\xcd\x04\xfb\x83\x26\x37\xb0"
+  "\x6f\xa5\xde\x07\xb3\xf5\xbe\x68\xb9\x4c\xec\xa1\xde\x7f\x9a\x21"
+  "\x0f\xfb\xcb\x12\xb1\x67\xd6\xb2\xfc\x99\x62\x5f\x34\x8a\x8f\xfd"
+  "\xe1\x46\x82\xfd\x61\xa3\x7c\xec\x83\x5b\xa9\xf7\xc1\x6c\xbd\xff"
+  "\x68\x89\x3c\xec\x83\x71\xbd\xaf\x94\x87\xfd\x09\x89\xd8\x33\xeb"
+  "\x61\xfe\x4c\xb1\xff\x68\x04\x1f\xfb\xa2\x3b\x04\xfb\xa2\x7a\x37"
+  "\xb0\x6f\xa5\xde\x6b\xd9\x7a\x7f\x64\xb1\x4c\xec\xa1\xde\x9f\x0c"
+  "\x95\x87\x7d\xaa\x44\xec\x99\x35\x35\x7f\xa6\xd8\x1f\x19\xc6\xc7"
+  "\xfe\xa3\x5b\x04\xfb\x8f\x0c\xae\x60\xff\x9a\x2d\xf6\x97\xba\x85"
+  "\x83\xb7\x62\x74\xfe\x81\x19\x2c\xf6\xef\x03\xf6\xf0\xfc\x07\xa7"
+  "\xed\xb0\xd3\xf8\x7f\x99\xcb\xe0\x1e\x0d\xb8\x27\x03\xee\xe0\x0d"
+  "\xad\x98\x03\x46\x3d\x31\xee\x18\xf3\xb4\xcb\x48\x7d\x12\xae\xc5"
+  "\xf8\x60\x8c\x01\x47\x0d\x83\x73\xd7\x13\xc9\xb4\x87\xd2\x17\xe3"
+  "\x89\x75\x3f\xc6\xbc\x35\x6d\x8f\x39\xd1\x2a\xe6\x93\xef\x8d\xbe"
+  "\x6f\xb2\x1f\xff\x6b\x2b\xcc\xcf\x83\x87\x4b\x93\x8a\xf9\x5f\x42"
+  "\xf8\x98\x1f\xa9\xc1\x38\x00\x17\xaa\xe5\x63\x1e\xa4\x17\xc7\xdc"
+  "\xda\xc7\x1f\x9b\xea\x1e\xe6\x9f\x66\x70\x98\x07\xe9\x9d\x63\x7e"
+  "\x59\x06\xe6\x6d\xdb\xbf\x77\x2c\xcc\x8f\x69\xf8\x98\xff\xe5\x32"
+  "\xc1\xfc\x2f\x97\xc4\x30\xb7\x40\x7b\x8d\xc7\xd4\xf1\x37\x7e\xe6"
+  "\x86\xa8\xe7\x9b\x01\x57\xfc\xad\x1f\x1e\xeb\x3d\x94\x70\x8c\x6a"
+  "\x06\xdc\xb7\xae\x40\xda\xac\x15\x68\x84\x77\x35\x69\xbf\x9b\xa0"
+  "\xfd\xde\x78\x17\x29\x2d\xaf\xf8\xf7\xc8\xba\x86\x94\x4d\x10\xe3"
+  "\xa6\x57\xe2\xbc\x4b\xa3\x0d\xe8\xe4\x8d\x63\x14\x1e\xbb\xc5\xef"
+  "\xed\xe8\x1f\xa3\xbc\xc6\xc7\xd0\xc6\xd2\xaa\x37\xc9\xb8\xca\x0f"
+  "\xd6\x71\x95\x43\xbc\x71\x95\xcd\xd7\xd8\x71\x95\xe9\x04\xa3\x7c"
+  "\x5b\x7c\x5e\x7e\x4f\x64\x5c\xa5\xa4\xd5\x71\x15\x66\x3c\xe5\x06"
+  "\xf2\x6d\x7e\x35\xae\xd7\x4e\x76\x5c\xe5\x9d\x04\xf7\xc6\x55\x9a"
+  "\x5e\xd5\x51\xef\x00\x3e\xaf\x4d\x07\x7c\xbe\x91\x8a\xcf\xc7\xc5"
+  "\xae\x8e\xab\x58\xfb\x58\x6b\xbf\x8a\xeb\x1c\xee\x5b\x8d\xb9\x81"
+  "\x31\xf6\x63\x29\xb8\xbe\xdd\x50\xfc\xed\x3c\x6e\x93\xe5\x8d\xa7"
+  "\x9c\xcc\xec\x6c\xe3\x29\xb8\xce\x59\xfb\xd9\x8e\xd1\xc7\xfe\x2d"
+  "\x9f\x5f\xf7\x3e\x99\x4a\xfa\xd8\x4f\xa6\xb8\xaa\xaf\x9c\x60\x5e"
+  "\x65\x3f\x86\x42\x30\x3f\x71\x06\x8f\xb9\xc8\x1b\x47\x39\x79\xa9"
+  "\xb3\x8d\xa3\x74\x3c\xcc\x4f\xe4\xf0\x31\x3f\x3e\x9e\x60\x7e\x3c"
+  "\xdc\x7d\xcc\x83\x62\xec\xc7\x4e\x08\xe6\x27\x3f\xc6\x63\x2d\xf2"
+  "\xc6\x4f\x8a\x65\x6a\xe9\x9f\x6e\xfc\xa4\xe3\x61\x7e\x72\x1d\x1f"
+  "\xf3\x4f\x47\x12\xcc\x3f\x1d\xd1\x06\x98\x57\xd9\x8f\x99\x10\xcc"
+  "\x4f\x1d\xc2\xda\x4b\xde\xb8\x49\xf1\xba\xce\x36\x6e\xd2\xf1\x30"
+  "\x3f\x95\xcc\xc7\xbc\x78\x28\xc1\xbc\x38\xd4\x7d\xcc\x83\x63\xec"
+  "\xc7\x4a\x08\xe6\x9f\xef\xc5\x63\x2b\xf2\xc6\x4b\x8a\x3b\xdd\x78"
+  "\x49\xc7\xc3\xfc\xf3\x78\x3e\xe6\x9f\x0d\x20\x98\x7f\xa6\x6d\x03"
+  "\xcc\xab\xec\xc7\x48\x08\xe6\x67\xf2\xf0\x98\x8a\xbc\x71\x92\x53"
+  "\x21\x9d\x6d\x9c\xa4\xe3\x61\x7e\x26\x9a\x8f\xf9\xe9\xbe\x04\xf3"
+  "\xd3\xfe\xae\x7a\x66\xab\x57\xb6\xfa\x63\xc6\x2b\xfb\x82\x66\xb7"
+  "\x1b\x1b\x21\x78\xff\x63\x0d\xa3\xd9\x65\x7b\xe5\x93\x99\x9d\x65"
+  "\x7c\xc4\x8a\x35\xf6\xcb\x1d\xc3\x2b\xff\xc3\xee\xfd\xe7\xdf\xbb"
+  "\x13\xaf\xfc\x77\x95\x18\xd6\x42\x73\x11\xca\xc0\x6b\x5a\xe7\x22"
+  "\x6c\x5c\x01\x38\x02\x0f\xf0\x5c\x04\x3c\x27\x41\x68\x3e\x02\x9e"
+  "\x87\x60\x9d\x93\x60\x3b\x1f\x21\x5c\x4f\x1b\xf1\x9c\x04\xec\x93"
+  "\x4b\xa3\x37\x21\xeb\xdc\x04\x3c\x07\x21\xfd\x3b\xd4\x13\x63\x84"
+  "\xe7\x1f\x60\xbf\x7c\xaf\xe7\x20\xec\xb0\x74\x84\x39\x08\x25\xb5"
+  "\xad\x79\xe5\x89\x07\xfa\x23\xe0\x5b\xcb\x38\x55\xf3\xf6\xc0\x68"
+  "\x5c\xe7\x30\x46\xde\xb5\xa4\x1e\x1e\x9a\x56\x44\x95\x27\x1f\x43"
+  "\x1b\x57\x23\xb5\x75\xfc\x02\xd7\x41\x68\x97\xbd\x4d\x80\x67\xd6"
+  "\x22\x32\x8e\x61\xf9\x31\xaa\xa7\xe1\x95\x38\xfc\xdd\xbe\xfa\xe4"
+  "\xbf\x8a\x28\x3c\xf6\x58\xb0\x00\x85\xbd\x7b\x15\x0d\x2b\xab\xbf"
+  "\x8c\x98\x3a\x95\x17\xb8\x03\xae\xcd\x68\xce\x0b\x2b\xb2\xf8\x05"
+  "\xae\x33\xf8\x05\x66\x62\xdc\xb2\xae\x21\x84\xeb\x17\xc6\xad\x3c"
+  "\x79\x57\x0b\x5e\x0c\x56\x14\x3b\xb6\x21\x5a\xa7\xbe\x92\x8d\x59"
+  "\xfe\x0d\xc0\xec\x55\x3e\x66\xbb\xe4\x8e\x6f\x58\xe7\x73\xbf\xaa"
+  "\xa3\x76\x41\x9d\x5a\x3d\x19\x30\x7b\x51\x2a\x66\x5f\xec\x91\x81"
+  "\x99\xde\x35\xcc\x82\xb4\x2e\x60\x56\xe1\x88\x59\x90\x3f\x5c\x8b"
+  "\x08\x66\x41\x4a\x83\x5f\x90\x8a\xc3\xec\x8e\x8b\x98\xd9\x7b\xd8"
+  "\x9f\x13\x66\xa5\xa2\xeb\x9f\x8b\x63\x16\xe4\x62\x3d\x0b\x72\xa1"
+  "\x9e\x7d\xaa\x13\xc0\x0c\xea\x59\x10\x5b\xcf\x82\xa0\x9e\x05\xd9"
+  "\xd4\xb3\xeb\x2e\x62\x66\xef\x41\x7f\x4e\x98\x95\xa9\x64\x60\xe6"
+  "\x62\x3d\x0b\x76\xa1\x9e\x7d\x9a\xe1\x88\x59\x30\xd4\xb3\x60\xb6"
+  "\x9e\x05\x43\x3d\x0b\xb6\xa9\x67\x97\x5d\xc4\xcc\xde\x43\xfe\x9c"
+  "\x30\x2b\x17\xff\xfe\x5b\x14\xb3\x60\x17\xeb\x59\xb0\x2b\xf5\xac"
+  "\x52\x00\x33\xa8\x67\xc1\x6c\x3d\x0b\x86\x7a\x16\x6c\x53\xcf\x4e"
+  "\xb8\x88\x99\xbd\x07\xfc\x39\x61\x76\x3e\x51\x06\x66\x2e\xd6\x33"
+  "\xad\x0b\xf5\xec\x64\xa8\x23\x66\x5a\xa8\x67\x5a\xb6\x9e\x69\xa1"
+  "\x9e\x69\x6d\xea\x59\xaa\x8b\x98\xd9\x7b\xb8\x9f\x13\x66\xff\x14"
+  "\xdd\xff\x40\x0c\x33\x06\x2f\xd0\x8e\x82\x98\x35\xf1\x75\xa3\x09"
+  "\x74\x3c\x7e\xe7\x25\x88\xd7\x86\x13\xc9\xf4\x1a\xa5\x2f\xc6\x0a"
+  "\xeb\x41\x8c\x57\x79\xf2\x19\x24\xa4\x1b\xf1\x7b\x31\xc0\x1d\xe1"
+  "\x77\x63\xe9\x3f\x48\xd0\x8b\xf3\xc4\xb0\x6a\xfd\x7d\x58\x7e\x02"
+  "\x87\x95\xf5\x7d\x58\x9b\x62\xf5\x95\x54\xac\x2e\x54\xc8\xc3\x2a"
+  "\x48\xdf\x3a\x56\xc1\x5a\xe7\x58\x7d\x9a\xc1\x61\x75\xd9\x06\x2b"
+  "\xc7\x7e\xcc\x75\xac\xec\xfa\xaf\x9f\x15\x56\xff\x4a\x11\xc3\xca"
+  "\xe4\x1b\x56\x84\xbf\x79\x9f\x04\xde\x97\x9e\x1f\xf5\x7c\xf6\x15"
+  "\xa4\xdd\x74\x05\x8d\xc0\xdf\x37\x1f\x5a\x6d\xa4\xe0\x19\xff\xf7"
+  "\xc5\x85\x6a\xd4\xfc\xa3\x7f\x0f\xfc\xfd\x0c\xd3\x4e\xbe\xe2\xaf"
+  "\x2a\x8f\x36\x30\x6d\xe2\x16\xc0\xa8\xac\xfe\x18\xc4\xa4\x5b\x78"
+  "\x59\xfd\x47\xa8\x69\x59\x14\xfa\xf2\xd2\x35\xc0\x85\x6e\x2e\xaf"
+  "\x3d\x86\x0a\xe0\x7c\xf1\x8a\x8f\x90\xe5\x47\x5d\x8f\x39\xc9\x88"
+  "\xba\xa1\xf8\xf7\x28\xec\x9d\x87\x24\x23\xf5\x84\x5a\xda\x58\x56"
+  "\xfb\x05\x7a\x77\x1e\xd2\x9e\x49\x46\x08\xc7\x9a\xf1\xca\x8b\xb0"
+  "\x57\x3e\xc1\xc3\xe7\x1d\x1b\xaf\xcc\x7c\x2f\x9b\x08\xd8\xdc\xb2"
+  "\xc3\x06\xbc\x38\xc4\xba\xdb\xa4\x7a\xc0\xa6\xde\x8a\xcd\x75\x94"
+  "\xb6\x04\x63\xa3\xe7\xbc\x32\x8b\x4d\x3e\x6e\xf3\x12\x6d\xbc\xf2"
+  "\x0d\x1b\x6c\xd8\x6f\x55\x79\xd8\x58\xc7\x32\x56\xea\xf0\x3b\x72"
+  "\x07\xaf\x2c\x6f\x2c\xa3\x52\xf4\x5b\x11\xa6\x1e\x41\x1d\x99\x04"
+  "\xf5\x28\x25\x89\xa9\x47\x24\xfe\x7d\x02\x81\xef\x45\xc8\x5b\xdf"
+  "\x2d\x7c\x13\x60\xd0\x04\x75\x0d\xf7\x45\xe9\xf0\x9c\x18\x4b\x8c"
+  "\xdb\xa4\xfd\xcd\xcd\x2f\xd7\x23\x0a\xda\xac\x42\x8c\x9d\xf9\x47"
+  "\x7f\x55\x36\xf4\x55\xe5\xb3\xbe\x01\x7c\xea\x50\xb9\x81\xc5\x66"
+  "\xf5\x37\xe8\x86\xa2\xf2\x02\xfd\x8a\xae\xc7\xe3\xc0\x53\xe8\x7b"
+  "\xd4\x73\xf0\xb7\x2f\xd0\xe6\xbd\xbb\x00\x0d\x9b\x90\x48\x1b\x99"
+  "\xb9\x3c\x50\xc7\x70\x7f\x86\xdb\xc3\xb2\xc4\xcf\x90\x39\x2f\x70"
+  "\x5d\xb3\x5f\x58\xd1\x99\x24\x84\x70\x9b\x88\xb1\xe8\xb2\x9c\xc3"
+  "\x0e\x7f\xb7\x67\x3b\xd6\xe1\xd0\x16\x2e\xfa\x42\xb8\x7e\xcd\xd2"
+  "\x4b\x1a\xef\xc8\x67\xeb\x57\xbe\xdc\xf1\x0e\xeb\x78\x14\x60\x88"
+  "\xbf\xd5\x4b\xbf\x88\xa8\x77\x24\x63\xf8\xf5\x25\x19\x18\xea\x5b"
+  "\xc7\xb0\x81\xc5\x30\x48\xdb\x3a\x86\xdf\xec\x70\xc4\x30\x08\xd9"
+  "\x60\x58\xc1\x61\x18\xe4\x4f\x30\x0c\x52\x72\x18\x06\xa9\x5a\xc7"
+  "\xd0\xce\x4b\xff\xac\x30\xfc\x8f\xf3\xf1\x0f\x41\x0c\x83\x5c\xa8"
+  "\x87\x37\xad\x18\xba\x50\x0f\x2f\xcd\x12\xc0\xd0\xa6\x1e\x7e\xaa"
+  "\xb3\xc1\x90\xad\x87\x41\x36\xf5\x30\xc8\x85\x7a\x68\xe7\xad\x7f"
+  "\x56\x18\x5e\x8e\x91\x81\xa1\x0b\xf5\xf0\x5b\x16\xc3\x60\x17\xea"
+  "\xe1\x7f\x35\x8e\x18\x06\xdb\xd4\x43\xd0\x2e\x2d\x18\x06\xb3\xf5"
+  "\x30\xd8\xa6\x1e\x06\xbb\x50\x0f\xed\xb4\xca\xcf\x0a\xc3\x6f\x75"
+  "\xd2\x31\x0c\x76\xa1\x1e\x9e\xb4\x62\xe8\x42\x3d\xfc\xb6\x4a\x00"
+  "\x43\xdb\x7a\x58\x69\x83\x21\x5b\x0f\x83\x6d\xea\x61\xb0\x0b\xf5"
+  "\xd0\xce\x7b\xff\xac\x30\xd4\x3b\x1f\xff\x17\xc6\xd0\x85\x7a\x98"
+  "\xce\x62\xa8\x75\xa1\x1e\x7e\xb7\xdf\x11\x43\xad\x4d\x3d\x3c\x19"
+  "\xca\x61\xa8\x65\xeb\xa1\xd6\xa6\x1e\x6a\x5d\xa8\x87\x76\x5e\xfc"
+  "\x67\x85\xe1\x95\x22\x57\x30\x04\x9d\xed\xa8\x4b\xeb\x39\x0c\x6d"
+  "\xf1\xb3\xd7\xa2\x11\xa0\x51\x31\x76\xb3\x4c\x88\x72\xc4\xef\xfb"
+  "\x38\x8c\x5f\x08\x7e\x1f\x77\x87\xd3\xa4\x0c\x76\xec\xfb\x1c\x8c"
+  "\xd9\x19\x68\xf1\xb1\x3e\xb5\xea\x51\xfc\x4e\xb5\x45\x8f\xc6\xfe"
+  "\xff\xaa\x47\xab\xe2\xa5\x63\xc7\xf6\x83\xa2\xd8\xf1\xfb\xbe\x08"
+  "\xe8\x13\xc5\xb1\xfb\x41\xeb\x88\x5d\x30\xe2\xb0\x23\xfd\x1e\xc1"
+  "\xee\xd3\x0c\x6b\xff\x47\xb0\x63\xfb\x3f\xa7\xd8\xfd\x9c\xfb\xbf"
+  "\xab\xa2\xfd\x9f\x79\x2d\xa2\x76\xad\xb5\x14\xe5\x50\x96\x63\xf0"
+  "\x2b\x86\x5f\x09\x1c\xeb\x02\xc7\x98\xb1\x18\xf8\x3f\x73\xce\xd2"
+  "\x83\x59\x0b\xac\xd8\xdb\x23\x1a\xef\xdb\x81\xd3\x74\xb5\xa6\xf1"
+  "\x5e\x83\x46\x15\xb0\x79\xc0\xf1\x0c\x38\x5e\xec\xe5\x31\xaa\x2b"
+  "\xa4\x2f\xa1\xb3\xdf\x0f\x83\x63\xdd\x70\x5a\x7a\x8d\x92\xf1\xa5"
+  "\x34\x45\xe1\x3c\xec\xef\xa9\x62\xd3\x04\xd8\xde\xb7\xe7\x9a\x51"
+  "\x78\x1d\x10\x6b\x9a\xee\x16\xea\x9b\x28\x9c\xce\xe2\xa1\xd4\x58"
+  "\xd6\x22\x8d\x6d\x5a\x7a\x0c\xc2\xf9\x5a\xd3\xf6\x60\xf3\xd3\xda"
+  "\xa6\x31\xbf\x87\x90\x97\x87\x86\xc9\xd3\x2b\x91\xc2\xcf\x84\xd3"
+  "\x3e\x40\x7b\x15\x66\x31\xe9\x3d\x94\x3a\x5e\xfa\x0d\x88\x49\xcb"
+  "\xa6\xf3\xa4\xbb\x7e\x96\xc8\xa6\x63\xbe\xa7\x80\x63\x4a\xdb\xf8"
+  "\xb1\xe9\x7a\x5a\x63\x83\xd7\x1e\xb7\x7d\x56\xf3\x5a\x0a\xe7\x87"
+  "\xd3\x78\x59\xba\x9e\xca\x60\x9f\x25\xcc\xf6\x9e\x38\x1d\x5c\x37"
+  "\x94\x8d\xb3\x37\x3c\xc3\xb0\x96\xfc\x72\x6a\xa2\xac\xe9\xd2\xcd"
+  "\xa8\x6f\x01\x17\x1b\x35\xc4\xba\x04\xaf\x21\x68\x8f\x9d\x97\x87"
+  "\x87\x1e\x63\x57\x0e\x3d\x28\x4e\x4b\x7b\xbd\x9f\x02\xe9\x7d\xd8"
+  "\xe7\x18\x45\x9e\x83\x59\x6f\x85\x60\x4d\x99\x7a\xef\x66\xca\xea"
+  "\xa1\x61\xcb\xda\x0b\xd2\x8d\xb5\xe6\x6b\xa1\x98\x71\x0c\x36\xad"
+  "\x92\x49\x5b\x16\x8f\xd7\xd7\x6f\x49\xdf\x1b\xa7\x35\x67\x1f\xd9"
+  "\x61\x5e\xa3\x0c\xb7\xcf\xdf\xbc\x56\x85\xcf\xdb\xe6\xef\x4b\xd2"
+  "\xef\x2f\x82\xf4\x13\x1c\xd3\xab\xed\xd3\xfb\x91\xf4\x7f\x3a\x08"
+  "\xe9\x23\x1d\xd3\x9b\x7a\xd9\xa5\xef\x43\xd2\x1f\xdc\x0f\xe9\xa7"
+  "\x38\xa6\xd7\xd8\xa7\xff\x05\x49\xff\x97\x2c\x48\x1f\xe5\x98\x7e"
+  "\x94\x7d\x7a\x7f\x92\xfe\x70\x21\xa4\x9f\xe5\x98\x3e\xc3\x3e\x7d"
+  "\x5f\x92\xbe\x68\x0f\xa4\x8f\xb6\x4f\x5f\xc0\xa4\x45\x41\x6c\xda"
+  "\x07\x49\xda\x8f\xf2\x21\x6d\x8c\xc0\xb3\x2a\xd8\xbc\x43\xd9\xf4"
+  "\x0f\x91\xf4\x7f\xd4\x40\xfa\x38\xc7\xf4\x4a\xfb\xf4\x01\x24\xfd"
+  "\x99\x62\x48\x1f\x2f\x80\x95\x7d\xfa\x7e\x24\xfd\x27\x2a\x48\x9f"
+  "\x28\x80\x95\x7d\xfa\xfe\x24\xfd\xdf\x4c\x90\x3e\x49\x20\xf6\xf6"
+  "\xe9\x1f\x26\xe9\x4f\x18\x20\x7d\xb2\x40\xec\xf9\xe9\xb3\x4f\x56"
+  "\x41\xba\x94\xdd\x2c\x37\xed\xe2\x6e\x9f\x77\x20\xc9\xfb\x54\x25"
+  "\x5c\x93\xe1\x98\x1e\x79\x90\xf4\xe8\x09\x36\x7d\x10\x49\xff\x79"
+  "\x29\xa4\x5f\x27\x10\xfb\x60\x9c\xbe\x80\xa4\x0d\x26\x69\x8f\x65"
+  "\x40\xda\x4c\x81\xb8\xdb\xa6\xd5\x92\xb4\xff\x8c\x87\xb4\x59\x02"
+  "\x31\xb7\x4d\x3b\x80\xa4\x3d\x1b\x06\x69\x73\x04\xe2\x6d\x9b\x76"
+  "\x20\x49\xfb\x45\x35\xa4\xcd\x15\x28\x6f\x90\x4d\xda\x47\x48\xda"
+  "\x52\xcc\xab\x1d\x02\xb8\xd8\xa6\xd5\x91\xb4\x17\xfd\x21\x6d\xbe"
+  "\x00\x26\xb6\x69\x07\x91\xb4\x65\x91\x90\x76\x8f\x00\x26\xb6\x69"
+  "\x1f\xa5\xb3\x2b\x94\x6c\x3b\x5d\x68\x9f\x76\x37\xd7\xee\x3e\x66"
+  "\xf1\x3a\x7f\x8c\x6d\x2b\x99\xb5\xa4\xe9\xb5\x78\x2d\xbb\x96\xe7"
+  "\x7a\xd2\xda\x47\x58\x28\x14\x42\x67\xff\xe3\x20\x5c\x87\xf3\x3c"
+  "\xe8\xd8\xb6\x29\x9f\xdc\xcd\xf5\x11\x83\xe9\xec\x2b\x46\xf6\xfe"
+  "\x45\x8e\x69\x55\xb6\x69\x1f\xa7\xb3\x2b\xa3\xd9\xb4\x47\x1c\xd3"
+  "\xaa\x6d\xd3\x0e\xa1\xb3\xbf\xd1\xb2\x69\x8f\x09\xb4\xaf\x4f\xd8"
+  "\xa4\x0d\xa5\xb3\xff\x53\x0d\xe9\x8e\x0b\xb5\xaf\xf4\x5a\xcd\x13"
+  "\xb8\x3d\xb0\xb6\xdd\x90\x7e\x28\x89\x6f\xd5\x11\x88\x2f\xf3\xfd"
+  "\x90\x35\x2d\xe0\xf0\x84\x4d\x5f\xf9\x84\xc5\xeb\xf2\x41\x36\x66"
+  "\xa7\x1d\xcb\x90\x61\x5b\x86\x27\x49\x9e\xdf\x26\x42\x9e\x25\xf6"
+  "\x65\x60\xdb\x23\xac\x13\x70\x7c\xc3\xcc\xd9\xdf\x85\xe1\xf8\x42"
+  "\xda\x52\x9e\x46\xa0\x3c\x14\x38\x4f\x16\xdb\xa7\xe8\xec\x7f\x9d"
+  "\x66\x63\xc0\xeb\x8f\xa0\x3e\x32\xed\x21\xe0\x5b\x42\x6f\xe8\x15"
+  "\x0f\x69\x9f\x66\xd3\x5d\xb0\xef\x07\xd9\xf2\xfd\x12\xce\x55\xb6"
+  "\xf4\x81\x1e\xca\x4b\x42\x5a\x26\xf1\x51\xf4\xc0\x35\xc5\x4d\x32"
+  "\x1f\xbf\x65\xef\x2c\x83\x9e\x79\x9e\x42\x9f\xd0\x88\x7a\xda\x64"
+  "\x7b\x6c\x2b\x45\x57\x0c\xa9\x47\x4a\xbc\x06\x1f\xed\xf7\x4c\xb5"
+  "\x1e\x8e\x1b\x06\xf4\x42\x0d\xd9\x37\x73\xf4\x1e\xc7\x8b\xf0\x9a"
+  "\x4c\xf0\x77\xbe\x1e\x2d\x9c\x80\xff\xde\xba\x96\x36\xe2\x3d\x10"
+  "\xcc\x6f\xd6\x68\xca\x2d\xb5\x78\x2d\x45\x23\xe4\x61\xbc\x9a\x88"
+  "\x14\x78\xdf\x38\xbc\xae\x6b\x79\x72\x2d\xba\xaa\xb8\xf9\x1d\xfd"
+  "\x6a\xdc\x08\x28\x43\x34\xdc\x2f\xe6\x0a\xfc\x9f\xc4\x14\xb4\x6f"
+  "\x4e\xcd\x88\xe2\xa5\x78\x7d\x3a\xc3\x20\x83\xdf\xd8\x68\xfa\xf5"
+  "\x99\xd5\x89\x69\xe8\xe1\x6b\x0a\x83\xce\xba\x16\x15\xb3\xfe\xd4"
+  "\xcd\xb8\x5f\x91\xb5\xa7\x0c\x1f\x5a\x7c\x6a\x46\x38\xac\x3d\xb5"
+  "\x27\x92\xdd\x43\xc5\xc0\xe4\x0d\x65\xab\xa0\xb5\x3e\xfe\x96\xa6"
+  "\x75\x19\x78\x8f\xb7\xe2\xb4\x6b\xe8\x0a\x7b\x0e\xe7\xc9\xe6\xb5"
+  "\x06\xe7\x81\xf3\xb2\xe6\x83\xaf\x33\x04\x46\x22\xfc\xec\x10\x07"
+  "\x7f\xd7\xd7\xaf\x32\x24\xe2\xf5\xab\x24\xa4\xd7\xe1\xf4\xc2\xeb"
+  "\xf2\x82\xc6\xd9\x56\x13\xd5\x90\x7d\x0b\x6b\xd5\x38\x12\xf7\x5b"
+  "\xbe\x7a\x64\x51\xb2\x7f\x6b\xf4\x1e\x88\xc5\xe3\x56\x88\xde\xa3"
+  "\x48\xcd\xfe\x3d\xcc\xba\x5e\x98\x60\xbe\xea\x9a\x10\x88\xf7\x58"
+  "\xcb\xbb\x51\x2a\xac\xad\xc9\xba\xa5\x35\x21\x9a\xfe\x78\x3d\xe7"
+  "\x5b\xc7\xe1\x9e\x63\x49\x5c\x6e\xe5\xc1\xbf\xde\xec\xbf\x06\xf6"
+  "\x5f\x1a\xa7\x61\xb8\xe4\x3b\xc2\x9f\xce\x19\x38\x8a\xec\x0b\x73"
+  "\x8b\x59\xab\x8c\xc1\x0e\xf0\xa5\x7d\x06\x8e\x62\xf2\xcd\x1b\x1b"
+  "\x6d\x5b\x86\xd0\xa1\x4f\x3c\x19\xf6\xd4\xd3\xbf\x1c\x36\x7c\xee"
+  "\xbc\xf9\x31\xb1\x0b\x7e\x1f\xb7\x70\xd1\x2b\xf1\x8b\x13\x5e\x4d"
+  "\x5c\xb2\x74\x59\xd2\xf2\x15\x2b\x93\x57\xad\xc6\x0b\x87\xb5\x94"
+  "\xf5\xdd\xb1\x1e\xf5\x14\x02\xdc\xc6\xc0\x3d\xea\xfa\x31\xf7\x85"
+  "\x63\x04\xe3\x3a\x4f\xa5\x46\x58\xbf\x97\x83\xa2\xc6\x7b\x7b\xd4"
+  "\x2a\xea\x16\xe2\x7d\x46\x80\x63\x1e\xe5\xf9\xcf\x17\xe3\x3d\xca"
+  "\xaa\x14\x75\xb3\xca\x0c\xcf\x17\xe3\x3d\xf5\x3e\xf7\xaf\x46\xda"
+  "\x20\xbc\x8f\x59\x5d\x38\x3e\x5f\x30\x10\xa1\xd3\x70\xad\x50\x9e"
+  "\x41\x6a\xe4\xff\x56\x1f\xda\x90\xdb\x87\xae\xc5\xf9\xe7\x6e\xa7"
+  "\xab\x0d\xaf\xc5\xa1\x6c\xf8\x3f\xf0\x5c\x7d\x55\x71\xbb\xdf\xe7"
+  "\x01\xcc\xde\x44\x01\xbb\xb7\xd3\x55\xeb\xfa\xd0\x55\xaf\x6f\xa7"
+  "\x6b\x0b\xfa\xd0\x7a\x6d\x2e\xf2\x6c\xc8\xae\xab\xd0\x2b\xea\x98"
+  "\xbd\x44\xb6\xc2\x79\x8b\xd7\xad\x92\xad\x70\x6e\x88\x09\x29\x0a"
+  "\xe0\xff\x70\xac\xfe\x73\x0d\x29\xf7\x07\x75\xc6\x2e\xf0\x7c\x47"
+  "\xe8\xe6\x78\x8f\x6c\xb8\x0f\xc1\xe3\xf6\xe8\xd3\xd0\xf3\xc3\xfd"
+  "\x0c\xe5\xc6\x2b\xc0\xcd\xdb\x78\x1d\x58\x7c\x3f\xef\xf2\x1d\xb5"
+  "\x08\xe7\x77\x78\xa9\xb1\xcb\xb2\x07\x69\x13\xa4\xd5\x58\x5e\x8b"
+  "\xf7\x80\xfb\x99\x20\xef\x7a\xdb\xe7\xd1\x2d\x58\x9c\xa4\x49\x58"
+  "\x1e\x1f\x3f\xa8\x07\xd2\x31\xff\x22\xdb\xfd\xf5\x92\x20\x3f\xf4"
+  "\xd6\x76\xfa\x34\x3c\x67\x31\x3c\x6f\xc9\x39\x70\x0a\xc0\x0d\x04"
+  "\xcf\x94\x03\xf9\xe6\xc1\xf1\xe3\xf0\xf7\x71\x28\x7b\x09\xb3\x77"
+  "\x97\x52\x79\x8a\xce\xbe\x3d\x01\xca\x59\x82\xf7\x27\xc0\x6b\x29"
+  "\xde\x5e\x39\xc5\x03\x9e\x3b\x17\xd2\x95\x68\x1e\x44\x03\xae\x2a"
+  "\xea\xfb\x41\x39\x0a\xe1\x6f\x9c\xfe\x2c\xc6\x11\xd2\x9f\x66\x9e"
+  "\x4b\xa9\xfc\x10\xff\x1f\x62\x55\xbc\xab\x0f\x9d\xd5\x90\x7d\xdb"
+  "\x88\xd7\x5a\x65\xf6\x8a\x81\xff\x43\x5c\x4a\x20\x6d\xce\xed\xf4"
+  "\x29\x1e\x78\x2f\xca\x82\x96\x3c\x6f\x97\xe0\x32\xe1\x72\x60\xdf"
+  "\xfa\x25\xa8\x40\x4b\x73\x14\x1a\x6c\x44\x1e\x5f\x56\x21\x94\xbf"
+  "\x9d\xde\x03\xbf\x7c\xf8\xed\xf8\x02\xce\x9d\x85\x5f\x09\x1c\x2f"
+  "\x85\x7f\xbf\x80\x7f\xcf\x56\x31\xef\x41\xfd\x71\xb9\x97\xa5\xd0"
+  "\xd5\x43\x76\xa0\x60\x66\xaf\xcb\x34\xf4\xbb\x2b\x4a\xa5\x3f\x2e"
+  "\x3b\x5e\x57\x99\xf6\xfa\x7f\xec\xbd\x0b\x78\x94\x55\x96\x2e\xbc"
+  "\xea\x12\x08\x18\xc8\x45\xd4\x68\xd3\x6d\x61\x07\x3b\x2a\x84\x02"
+  "\xc1\x46\x1a\x24\xdc\x24\x48\x80\x28\x68\x47\x89\x40\x34\xb1\x83"
+  "\x72\x29\x93\x08\x01\x42\xaa\x28\x50\xd1\xe6\x52\xc4\x88\x51\x43"
+  "\x12\xdb\xd8\x1d\x5b\x7a\x64\xce\x30\x67\xd2\xcf\xd0\x6d\xba\x49"
+  "\x9f\xc9\x9c\x03\x29\xe6\xfc\xf8\x3f\x99\x3e\x74\x77\xc1\x89\xe9"
+  "\xc8\x04\x2c\x4d\x41\x15\xa4\x52\xfb\x7f\xd7\xde\xdf\x97\xba\x50"
+  "\x41\x3d\xe3\x99\xf3\x3c\xe7\x37\xfa\xf1\xd5\xb7\x2f\x6b\xaf\xbd"
+  "\xd6\xda\x6b\xaf\x7d\x5b\xdb\x17\xe3\xff\x15\x44\x47\x3c\xde\x63"
+  "\xe4\x3b\xf2\x31\x5d\x2e\xc0\x53\xa9\xfd\x6e\x23\xd3\xa5\x5e\xed"
+  "\x77\x27\x9e\xae\x2f\x7d\x62\xe1\x0d\xf5\x98\xfc\x79\x5f\x39\xed"
+  "\x57\x7b\xf6\x7c\xb5\x72\xaf\x24\x92\xa9\x7f\x0d\x9e\xda\xe8\xf0"
+  "\x7e\x9b\x0a\xa3\x99\x2a\x8c\x72\xb4\x77\x39\x99\x0d\xa0\x93\x01"
+  "\xf0\x0d\x47\x54\x98\xe1\x18\xde\x66\x3c\x29\x31\xe5\x33\xcc\x26"
+  "\xe6\x67\x3f\x74\x3d\xf3\xd2\x63\xf2\x15\x30\x8f\xf6\x2b\xd9\x32"
+  "\xf0\x5e\x07\x84\xe5\x43\xb6\xea\x06\xe5\xc7\x74\x79\x49\xb4\xfc"
+  "\x5c\x9e\x1e\x23\x3f\x2e\xd6\x45\x68\x2f\x4d\x0d\x4a\x5e\x8e\xf5"
+  "\x6d\x2b\xc2\xf7\xe5\x99\x80\x73\xcc\xb2\x4a\xc2\x90\x76\xce\xfe"
+  "\xf3\x44\xa3\x4a\xc8\xcc\xfa\xa5\xd7\x74\x79\x2f\xcb\x2c\x97\xad"
+  "\x95\xab\x70\x01\x7e\x08\x6b\x64\xfc\x36\x02\x2e\xbe\x19\x6e\xa3"
+  "\x9b\xbe\xd0\x71\x93\x79\x5e\x7d\x16\xf2\xa8\xe1\xcb\x30\x39\x9f"
+  "\x08\xd7\x2b\x9f\xf3\xa8\xb2\xfd\x73\x10\x6e\x85\x8e\x22\xfb\xe7"
+  "\x64\x72\x07\x3d\xc4\x32\xc9\x6f\x77\xd0\x8a\xb6\x94\x43\x21\xee"
+  "\xe7\xd2\xc9\x8a\xf6\x36\xe2\x9c\xc9\x9f\x91\x55\x49\x56\x86\xc7"
+  "\xfa\x1b\xf5\xe8\x69\xe0\xb6\xa8\x60\xdd\x4f\xd2\xef\xa2\x2f\xff"
+  "\xbf\xda\x48\x96\x53\xcf\xf8\x20\x3e\xa2\xdc\x1a\x37\x46\x40\xfb"
+  "\xb7\xaa\xba\xa2\xac\x26\xe4\x3f\xc2\x75\x67\x7a\x22\xbe\x05\x70"
+  "\x1c\x1c\xc7\x77\xab\x68\xf5\x69\xe2\x73\x19\x4c\x0f\x4e\xcf\x77"
+  "\x3e\x2a\x7f\xb2\x7d\xef\x49\xba\x21\x3f\xf3\x43\xa0\x0c\x86\x61"
+  "\x0f\x8a\xa0\x80\x3e\x7a\x77\x2b\xdf\x21\x10\xb8\x12\xcd\x1f\x7f"
+  "\x67\x24\x7f\x90\xef\x08\xf2\xb7\x71\xff\xcb\xfa\x04\x65\x26\xf3"
+  "\x5d\x68\x08\x73\x85\xf6\x01\xc6\xa6\x80\x9c\x03\x02\x9c\x4f\x81"
+  "\x8b\x8b\xe1\x00\x9f\x36\x05\x2b\x90\xc1\xbe\x26\x23\x79\xad\xc1"
+  "\x6b\x62\x9e\xcb\xf6\xbc\x55\xd6\x09\xba\x2b\xf0\xeb\x7a\x15\xd7"
+  "\x82\x34\x2d\xa2\x3f\x87\xc4\xb6\x7c\xcd\x5e\x90\x71\x47\xed\x57"
+  "\x24\x7f\xdb\xd4\x9d\x84\x81\x7f\x2d\xdb\x2e\x7a\xc2\x78\x07\x5c"
+  "\xba\x4f\x75\x0d\xef\xa3\x5c\x9e\xd8\x5c\x20\xfb\x50\x2e\x83\xf3"
+  "\x6b\xf0\xd6\x31\x3c\x9d\x56\x59\xc0\x43\xd1\xcb\xdf\x88\xf0\x26"
+  "\x96\x45\x49\x37\xe8\xd1\x3e\x3b\xcb\x62\xa0\x06\xf9\x8f\xed\xe3"
+  "\xef\xcd\xf2\x3b\x53\xea\xd8\xc1\x78\xff\x19\x8e\x77\xf7\x80\x6f"
+  "\xcf\x41\x96\x42\x44\xdf\x1f\x43\x56\x9f\x53\xd6\xed\xb0\x6f\xdb"
+  "\x7c\xc3\xf1\x20\x11\xe3\x09\x1a\xb5\xf8\xf7\x5d\x99\x09\xdd\x5f"
+  "\xc9\xb8\x42\x5f\x1f\x15\xef\xe6\x13\xe3\x0c\x7d\xa6\xe1\x77\xe5"
+  "\x57\x1a\xef\x8f\x72\x1d\x99\x9e\x59\x4a\xf7\x21\xae\xff\x61\xc6"
+  "\x3d\x5c\xef\x2b\xbb\x23\x69\x2c\xeb\x0d\x3e\x30\xbf\x98\x2f\x11"
+  "\x30\x59\xf6\x5d\x80\x75\x58\x7d\x2b\xd9\x60\x5a\xbb\x6e\x16\x27"
+  "\x38\x7d\x38\xed\xd5\xdf\x71\x5c\x15\xca\x9e\x64\xe3\x71\x0b\xfa"
+  "\xe7\xa0\xbf\x15\x70\x0f\xf3\x7d\x9e\x80\xd1\xc2\x34\x05\x2e\x37"
+  "\xb1\x3c\xe2\xfb\x84\x96\x6f\x0c\xfa\xf3\x09\x78\x66\x86\xdb\x7f"
+  "\x7f\x42\xb4\x7c\x5d\x8d\x6d\xff\xcc\x6f\x57\xc8\x9e\x43\xda\x5d"
+  "\xc6\x96\x8b\xa6\xab\xef\x68\x7d\x87\xc6\xeb\xab\x97\x8e\xa3\xbd"
+  "\x44\xc0\xa8\x8c\xe1\x75\x8b\x94\xc7\xcd\xb9\x06\xae\x33\xf2\xb6"
+  "\x68\x70\x64\x9d\xa5\x3c\x39\xa5\x0c\x9c\x10\x9b\x51\xcf\x41\x39"
+  "\xb8\xd2\xa9\xf1\xf9\x44\x0c\x4d\x74\xdd\x95\xc1\x77\x74\xb1\x4e"
+  "\x82\x7d\xfb\x80\xbf\x3f\xac\x97\x98\xf7\x21\xc9\xfb\xab\x8e\x06"
+  "\xd5\xdf\x6a\x7a\xeb\xaa\x8a\xbf\x39\x4a\x86\x19\x97\xbf\x97\xf2"
+  "\xcb\xb8\xd8\x0b\x18\x97\x16\x89\x87\xdd\x42\x17\x4d\xfd\x13\xb8"
+  "\x7c\xe4\x6d\xd1\xda\xab\x06\xeb\x0a\xcb\xcb\xb1\x9d\xd0\x55\x8c"
+  "\x13\xca\x4e\x97\xfa\xef\x41\x49\xd7\xbd\x1a\xee\xed\x01\x27\xe7"
+  "\xbd\xec\xb8\x62\x94\x79\xdb\x3d\xa6\x4b\xbe\x80\xba\xe3\x60\x24"
+  "\xf2\x37\x5b\x9e\xe2\xf4\xa2\x97\x75\xb4\xe5\x09\xf9\xfb\x63\xcb"
+  "\x63\x90\xd5\xf3\x64\x06\xbc\x44\x96\x51\x5d\x2e\x7a\x4d\xe2\x0f"
+  "\x3c\x5e\x00\xad\x0f\xc3\x46\x6a\x66\x7a\xb3\x2c\xc3\x46\x9a\xea"
+  "\xdf\xd7\xef\xd3\xe5\x16\xe5\xd4\x31\xed\x15\x7f\x82\xf7\x43\x8e"
+  "\x5b\xc2\xb2\x15\xbc\x5f\xa3\x23\xdf\x93\x98\x88\xf2\x7e\xad\xd5"
+  "\xab\x19\xe9\x61\x8b\x89\xf7\x35\xdc\x6b\xb5\xf4\x8f\xea\x7c\xd0"
+  "\xda\xea\x89\x7d\xac\x7f\x25\x0f\x82\xbd\x5a\xde\x26\xad\xac\x0b"
+  "\x7a\x5a\xb6\x11\xd5\x7d\x65\xc1\x0b\xac\x07\x27\x81\xf7\x52\xf7"
+  "\xc9\xbb\x6e\x55\x18\xb7\x1d\x55\x86\x90\x77\x23\xee\x84\xdd\x13"
+  "\x96\xa3\x60\x5b\x8c\x7e\x62\x5d\xec\xea\xd8\xa5\xee\x83\x60\x59"
+  "\x62\x9d\xca\xe3\x12\xc0\xab\xd3\xda\x8f\x86\xf3\xc0\xe4\x68\x59"
+  "\x11\x3b\x20\x2b\x13\xc3\xb0\x07\x2c\xf1\xfa\xb9\x06\xa5\x03\xeb"
+  "\x54\x9e\x81\xe7\xb5\xba\x1d\x56\x75\xd3\xbe\x99\x6e\x55\x92\x6e"
+  "\xd3\x22\xe8\x08\xba\x85\xde\xd1\xd2\xb7\xb0\x2e\x0f\xb7\xd7\x81"
+  "\x3f\xe9\x6d\xf9\x5a\x7d\x11\x3a\xc0\xed\x21\x02\xaf\x96\x18\x7d"
+  "\xd1\x12\x5f\x5f\x0c\xec\xd6\xea\xdb\x18\xd3\x36\x9a\x34\x7b\xf7"
+  "\x3d\x9d\x0f\x1d\x3e\xfd\x5e\x8e\xbe\xf7\x58\x7f\x72\xd9\x91\x7d"
+  "\x50\xbd\xa2\xab\xd6\x96\x43\xdb\xaf\xe5\x43\x28\x37\xb2\x3d\x33"
+  "\xaf\x59\x27\x30\x0c\xe6\xa9\xb4\x2b\x11\xa6\xf8\x1a\xca\x60\xdd"
+  "\x10\xa9\xa3\x91\xb6\x26\x24\xb8\xbd\x84\xf2\xa2\xdb\xe2\xc0\x31"
+  "\xad\x2d\x6a\x65\x8b\x71\xe0\x91\x35\xa2\xdc\xb6\x98\x72\x99\x37"
+  "\x6d\xd2\xef\xb2\xe2\xe9\x28\xbd\x4f\xe3\xf4\xc8\x5b\x81\x3c\x81"
+  "\x98\xfe\xd1\xc5\xf8\xa1\x2c\x9b\xd4\x59\x07\xa5\xae\xa8\xf0\x2b"
+  "\x7c\x82\x0d\x5a\x3f\x81\x30\xab\x16\xd6\xae\xf5\x25\xba\xdc\xac"
+  "\x8f\xc6\x49\xe4\xc7\xb7\x8f\x06\x6c\xba\x7d\x24\x61\x49\x5d\x24"
+  "\x0a\xb4\xfa\x71\xd8\x44\x15\x36\x90\xc1\x61\xfb\x14\x1d\x6a\x84"
+  "\xec\xaf\x82\xed\x5a\x7f\xc5\xed\xcb\x88\xef\xe9\xdc\xc6\xf8\x1b"
+  "\x30\x8e\x30\x7c\xb7\xe3\x2a\x8f\x21\x6a\x3d\xa6\xfe\xd3\xac\x0f"
+  "\x58\x5f\x58\x9e\x51\x7a\xc3\xb2\x54\xbe\x07\x58\xef\xb0\x1d\xc2"
+  "\xf1\x48\xd7\xc6\xba\xa8\xdb\x4c\xa9\x96\x87\x60\x17\xfc\x5b\x22"
+  "\xe0\x0a\x9f\xcc\x6b\xa6\xf1\xd2\x56\xf8\xb7\x1c\x93\x1e\xa6\xe7"
+  "\x83\xde\xfa\x98\xf3\x71\x7e\x5d\x7f\xb1\xee\x0a\xb2\x6e\xe2\xf2"
+  "\xcc\xb4\x56\x93\x71\x39\x6e\xd0\xed\xa2\x7e\x63\x44\x5a\xbe\xab"
+  "\xe0\x29\x99\xf6\xa8\xd4\x67\x66\x7a\x8f\xf3\x4a\xfe\x41\x57\x56"
+  "\x5d\x11\x67\x1b\x4a\xc9\x5c\xff\x05\xeb\xc5\xbe\x26\x85\xa7\x81"
+  "\x64\x3d\xcc\xf4\xcf\xb2\x1e\x4a\xa7\xba\x14\x2e\x7d\x4d\xf5\x57"
+  "\x65\xdc\x27\x5c\x17\x8e\xdb\x1f\x11\xc7\xf7\x85\x20\xbf\x41\xe2"
+  "\x15\x93\x2f\xd4\x5f\x72\x4d\xfa\x06\x75\x07\x6e\x62\xfd\x41\x4d"
+  "\xf7\x9a\x0d\x0e\x85\xa7\x61\x96\xae\x77\x41\x97\x13\xac\x7b\x65"
+  "\xdc\x33\x5a\x9a\xa5\xda\xfb\x41\xf9\x5e\xaf\xe8\x9a\x6e\xd4\xe8"
+  "\x7d\x5a\xab\xc7\x0e\x39\xce\xfe\xb7\x7c\x93\xc7\x6c\x28\xd2\x69"
+  "\x1b\xf9\x9b\xdb\x0f\xca\x4f\xe1\x6f\x29\xf7\x95\x72\x0c\x5b\xc7"
+  "\x69\x18\x27\xd9\x47\x98\xa9\x20\xd6\xa6\xee\x36\x9b\xae\x70\xbf"
+  "\x24\x6d\x55\xb3\xe9\x5f\xb5\xf9\x1f\x6a\x2d\xfd\x19\xf5\x9a\x8d"
+  "\x19\xba\x8e\x11\xfe\x1c\x62\x7f\xe5\xdd\x66\xe3\x78\x0e\x63\xff"
+  "\xf6\x91\x69\x58\x3f\x7d\x78\xd5\xa3\xc1\x34\x92\xae\x37\x58\x97"
+  "\x74\xf8\xce\x91\x16\x7e\xa4\x5e\xd3\x25\x17\xcd\xc6\xbf\x8d\xb2"
+  "\xc3\xf0\x1d\xa5\x33\xcc\xa6\x3f\xc4\xea\x0c\xd8\xcd\xbb\xfc\xd5"
+  "\xc6\x5d\x51\x76\x00\xc2\xae\xab\x3b\xcc\xc6\x7c\x6e\xa3\x7c\x5f"
+  "\x91\xd4\x4f\x3c\xa7\x65\x36\xdd\xaa\xe3\xcc\x7a\xb3\x6f\x9b\x36"
+  "\x7f\x61\x36\xfd\x3d\xdb\x6a\x31\xe5\xf9\xa2\x74\x27\x97\xa7\xc3"
+  "\x33\x13\xdf\x79\x03\x3a\x7c\xc1\xe5\xb4\x69\x7a\xbe\x31\x4a\x57"
+  "\x6a\x7d\x18\xeb\xc9\xe8\xbe\xaa\xef\xbd\xa8\xbe\xca\x6c\x7a\xe7"
+  "\x1a\x1d\x59\x6d\xb2\x7d\xe5\xbe\xca\x6c\xca\x61\xbd\xa5\xeb\xc8"
+  "\x28\x5d\x60\x36\x95\xd7\x47\xda\xb2\x66\x63\x50\xb7\x65\x07\xf5"
+  "\xa8\xd9\xb8\x87\x75\x14\xca\x6f\xd1\xca\xee\xf5\x98\x3e\xf7\xea"
+  "\x65\x23\x3e\xa3\xc3\x02\xd9\xdc\xd7\x97\x0f\x99\x3a\xa5\xd9\x80"
+  "\xb2\x6d\x5e\xe5\x7b\x3f\xcc\x86\x74\xc8\xdf\x48\x96\xb3\xd6\x0d"
+  "\x5f\x50\x57\xb8\xaf\x68\xeb\xdb\xa8\xd3\xd7\xbc\x3d\xd2\x2e\x3c"
+  "\x74\x50\xec\xf6\x57\x9b\x57\x44\xd6\x71\x2f\xc2\xf6\x6b\x73\x08"
+  "\x92\xb6\x0c\xcb\x6c\xce\x6c\x38\x18\x5d\x37\x55\x0f\x73\x01\xd7"
+  "\x83\xc7\x44\x28\x7f\x2c\xdb\x3d\x7c\x67\x19\xda\x4d\x63\x83\x2e"
+  "\xf3\xb0\x8b\xae\x38\x23\xed\xab\xbe\x20\xeb\x4a\x6d\xec\xd9\x0e"
+  "\x7b\xc7\x15\x39\x17\xb3\x64\x5e\x9e\xc5\x56\xba\x76\x43\xf9\x33"
+  "\x53\x2c\x6b\x37\xac\x2d\x5f\x5b\xb8\x6e\xed\xd6\xc2\xf2\xb5\x1b"
+  "\x37\x4c\x58\x5f\xf8\x93\xb5\x4f\x5b\x36\x17\x96\x59\xac\x15\xe3"
+  "\x2b\x46\x52\x38\xe9\x0c\x4b\x61\x59\xd9\x0b\xeb\x8b\x8b\x2c\x1b"
+  "\xd6\x3e\x3d\xb1\xb4\xb8\xac\xb8\xdc\x52\x58\xba\xf1\x85\x0d\x45"
+  "\x96\xf1\x45\x59\xe3\xad\xf7\x15\x8d\x8c\x9c\x43\xbb\x23\x85\x7a"
+  "\x43\x97\x3f\xed\xd9\x7f\x99\x12\x93\x0d\xb6\xd2\xe4\x8a\xb5\x1b"
+  "\xe4\x9c\x9d\x39\xe1\x0f\x93\x6a\xc8\xc6\x77\x8f\xf3\x5d\xb5\xa2"
+  "\xda\xdc\x89\xb7\x99\xd3\xa1\x9e\x96\x06\xbe\x7f\xfc\x66\x31\xd6"
+  "\x5f\x9d\xb0\xdb\x63\x1e\x61\x93\xf7\xc7\x22\x1c\x75\x1b\x2b\x2e"
+  "\xff\x73\x0f\x6c\x36\x1b\xef\xcd\x6e\xb8\x4c\x63\x5c\x9b\xc8\x8c"
+  "\x27\x09\x4f\x0a\xdf\x4d\x8e\x3c\xc7\x3c\xe6\x61\x9d\xd2\x7f\xbf"
+  "\x79\x58\x81\x37\x35\xc3\x22\x5c\x19\xea\x1e\x72\xf3\xb0\xc7\xf5"
+  "\x79\xe6\x65\x2f\xd2\x32\x96\xcf\x73\xe6\x61\x72\x3d\x71\x27\x64"
+  "\x99\xe7\x5e\xfb\x7e\x3b\x37\x1b\xf6\xe0\x99\xd6\xdb\x64\xdc\xe3"
+  "\x3e\x23\x25\x01\x2f\xf3\xf1\x4a\x2b\xbd\x86\xb2\xca\xd2\x85\xf0"
+  "\x57\x0f\xb3\xe8\xf3\x69\x7c\x27\x3c\xea\xd2\xa9\xea\x91\x60\x92"
+  "\xf5\x38\x28\x32\x6a\xd2\x80\x5f\x35\xe3\x33\x2c\x57\xaf\x03\xf0"
+  "\xee\xf4\x98\x13\xf8\x0e\xf5\x14\xc6\x2b\xde\x5c\x1f\xcf\x77\x01"
+  "\xcf\xd7\x43\x9b\x40\xb7\xef\xa9\x3b\x8f\xf6\xd7\xab\xf6\x87\xfa"
+  "\x9c\x68\xc0\xef\x7d\x5f\x50\xd2\x5e\xbe\x83\xdb\x79\xbb\x38\xe9"
+  "\x0b\x92\xbb\xa4\x93\x92\xb7\x08\xaf\xf8\xcf\x9f\xf6\x68\x75\x6a"
+  "\x65\xdd\xf0\x77\xcf\x76\x9a\xb9\x4e\xe8\x2b\x92\xf8\x3e\xe7\x21"
+  "\xe6\x16\xcd\xaf\xdd\x2c\x7c\xe2\xed\x08\x9b\xcb\x3c\xfc\x2e\xa6"
+  "\x09\xdb\x5b\x7d\xe8\xa7\xfc\xd5\xc3\x21\x77\xc3\x4a\x34\xdb\xd8"
+  "\x27\xfa\x0b\xc2\xb6\x94\x79\x18\xcb\x99\x6f\x08\xd8\x89\x3a\x6c"
+  "\xbe\xdb\x9b\xf3\x28\xfe\x0f\x7f\x1d\x79\xbc\x11\xf0\x6d\xb1\xf0"
+  "\x19\x26\x7e\x7b\xf5\x72\xe4\x38\xdc\x3c\x9c\x6d\x02\x2f\x64\x39"
+  "\xee\xbc\x35\xca\xcb\xa8\x3e\x28\x4e\xbb\x11\xbe\xff\x0a\x99\x91"
+  "\x16\xfd\xbd\x84\x7f\x0a\x74\x9f\xca\xf0\x77\xde\x4c\xb4\x0b\x69"
+  "\xfa\xaa\x87\x95\xf0\xfc\x2e\xe2\xd0\xfe\xfb\xae\x99\xb3\xd6\xe4"
+  "\x79\x46\x8c\x3c\x67\x57\xb3\x4d\x58\x03\xf8\x90\xa1\xfd\x97\xd0"
+  "\x0f\xe3\x3b\xab\x86\x32\xb9\x1c\xfc\x3e\xc5\xf3\x21\xfe\xea\xc4"
+  "\x6c\xbd\x3c\x01\xf9\xdf\x17\x52\x73\x30\x9a\x6c\x4d\x70\x57\xf4"
+  "\xf0\xda\x84\x38\x0e\xfd\xce\x38\xb2\x8c\x21\x4f\xb9\x2e\x53\x90"
+  "\xf5\xd3\x52\xae\xc6\x50\xa6\xa8\x1e\x1e\x68\x48\x43\x3a\xc8\x55"
+  "\x3d\xe4\x89\xe5\x0a\x69\x1b\x75\x99\x82\xac\x9d\xe2\x74\xc0\x61"
+  "\xe4\x91\xad\xd9\x66\xd6\x91\x5d\xe6\x11\x37\xb1\x8c\x89\x37\x16"
+  "\x77\x8a\x5b\x56\x76\x2a\x3e\x8d\xb8\xc9\x1d\x50\x3c\x08\xd3\x3d"
+  "\xb1\x27\x82\xee\xa7\x20\xc7\x23\x99\xce\x72\xae\x1a\xe9\x81\xdb"
+  "\x29\x69\x8b\x6f\x07\x0f\x64\x5f\x95\x78\x9a\xf3\x6b\x34\x3c\x11"
+  "\xa6\xe1\x08\x6b\x3c\x1a\xc6\xd0\x4e\xde\x19\x2d\xaa\x47\xcc\xe4"
+  "\xb6\x82\x3c\x45\xfa\x7d\xd1\xf1\x78\x89\x32\xcc\xe6\x1a\x4a\xe4"
+  "\x32\xda\xc6\xc8\xf4\x35\xf1\xca\x88\x95\xe3\xb6\x46\x22\x9e\x0b"
+  "\xe7\x7c\x19\x63\x98\xae\x23\x4e\xc4\xe5\xef\xd3\x51\xb8\xc9\x07"
+  "\xb8\x75\xbe\xa6\xdd\x9f\xed\xaf\x1e\x69\xbe\x1e\x7e\x19\x16\xd5"
+  "\x2f\xb6\xde\xc1\xf2\x3c\x72\x96\xbb\x96\x88\xc3\xb4\xef\x09\x7d"
+  "\xe8\x6b\x62\xe7\xf3\x87\x5c\x5f\x30\x8f\xdc\x1e\xb5\xbe\x60\x1e"
+  "\xb9\x6e\xa8\xf5\x85\x98\x72\x7f\xcd\xe5\x86\x1a\x56\x18\x22\xca"
+  "\x6e\x0a\xc5\x29\x5b\xcf\x9f\xd5\x18\x31\x7e\x31\xdf\x30\x82\x71"
+  "\xe8\x40\xbf\x24\xbe\xb3\xc2\x20\x00\xa7\x4d\xda\x12\x37\x24\x2a"
+  "\x7b\x85\xed\xa0\x91\x3d\x9c\x26\xb6\x1e\x83\x7f\x89\x63\x78\x3e"
+  "\x85\xae\xc8\x8f\x84\x07\x89\x6f\x7c\xa5\xef\xb5\xeb\xd1\xc6\xa8"
+  "\xc4\x24\xe2\x7c\x24\x11\xdd\x2e\xd3\x0b\xfc\xa9\x20\xed\xdb\x2b"
+  "\x3f\xcc\x83\xe9\x07\xe3\xff\x1d\x7f\x23\x14\xbe\x12\x5e\x80\x0c"
+  "\x5a\x79\x3d\x11\x29\xe6\x5f\x27\xb7\x20\x3d\x4b\xbc\x3f\x1e\xe1"
+  "\x3a\x56\x24\x10\x59\x12\x65\x62\x21\x82\x2a\x62\xf0\x5b\x44\x7e"
+  "\x73\x48\xf4\x37\xfe\x4c\x05\x11\x05\xdc\x6e\x2a\x92\x5b\xaa\xbe"
+  "\x9f\x3d\x18\x64\x6c\x4c\x89\x2c\x32\x85\x1c\x09\xf2\x47\x32\xff"
+  "\x13\x00\xbc\x4c\xc4\x5b\x32\x07\x13\xdc\xe8\xdb\x11\x91\xfc\xbf"
+  "\x29\xf4\xc7\x55\x5c\xa7\x8e\x5f\xf7\xef\x7b\x11\xbf\x6f\x57\xaf"
+  "\x71\xd3\xbf\x41\xf8\xd7\xff\xb3\x9c\x1a\xa1\xff\x0c\x8b\xc7\xb8"
+  "\xd6\x78\x49\xc3\xf4\xbf\xc3\xa2\x07\x45\x4a\x68\x38\x7e\x7c\x5d"
+  "\xf4\xf7\x0f\xf2\xa3\xbf\xef\x6a\xfe\x06\x30\x27\x89\xa4\xdd\x93"
+  "\x0a\x9e\x95\x0f\x06\x26\xc7\x34\x99\x64\x57\x4c\x13\x0a\xff\x69"
+  "\xd8\x98\x80\x4f\x30\x22\xd8\x1c\x3f\xf5\xff\x9e\xbf\xdb\x76\x68"
+  "\x0d\xe2\x76\x6f\xca\x35\x91\xb3\x63\xc2\xf8\x7b\x98\x45\x0b\x9b"
+  "\xfc\xbb\x6b\xd2\xcb\x30\x4b\xc4\xb7\x21\x1b\xff\x34\x42\xfe\x4f"
+  "\x7c\x13\xb8\x7e\xfb\xf7\xff\xc3\x3f\x03\xb7\x8f\x6f\xff\xfe\x37"
+  "\xfd\x09\xd5\x8b\x43\x13\xc9\x17\xff\x27\x06\x15\xa5\xd0\x22\x84"
+  "\x16\x20\xb4\x1f\xdf\x48\x3f\xfe\xed\xdf\xb7\x7f\xdf\xfe\x7d\xfb"
+  "\xf7\xed\xdf\xb7\x7f\xdf\xfe\xfd\x5f\xf0\x27\xd7\xa0\xa4\x6d\xa0"
+  "\xdb\x07\x61\x3b\x81\x87\x40\xcf\xd4\xc8\x30\xa3\x81\xc2\x29\x30"
+  "\xdc\x9e\x46\x86\x44\x1a\x66\xfe\xe6\xac\x3c\xcb\x20\x42\x5f\x31"
+  "\x83\x15\x0f\xaf\x97\xdf\x8b\xe7\x3b\x11\xe1\xdf\x8b\x9f\xfc\x3f"
+  "\xe0\xcf\x00\x82\x99\x30\x0e\x4c\xa0\x61\x34\x9c\x12\x69\x04\x8d"
+  "\xa4\x1b\x28\x89\x46\xd1\x68\x8c\x2f\x53\x28\x95\xd2\xe8\x46\x1a"
+  "\x43\x37\xd1\xcd\x74\x0b\xa5\xd3\xad\x74\x1b\x30\x1f\x4b\xdf\x8d"
+  "\x8f\xb3\x83\xb2\xd3\xf1\x0f\xfe\xcf\xa3\x6c\xf9\xbd\xe6\xdb\xf0"
+  "\xff\xd0\xf0\x56\x2d\xfc\x94\x16\xee\xf9\x36\xfc\x3f\x34\xdc\xf2"
+  "\x7f\xf8\x3d\xee\xff\xe8\xdb\x00\xd5\xac\xb4\xb3\x21\xae\x4e\x8c"
+  "\x0d\x35\x68\x7f\x83\xdf\xf4\x25\xf9\xaf\x81\x17\x9d\x3f\xf6\x2f"
+  "\x1b\xcf\x54\xf5\xd3\x4e\xa4\xe6\x73\x45\xe4\x5f\x70\xa8\x9c\xfa"
+  "\x5f\x95\x19\x4f\x0a\x9e\xb1\x78\x6e\xc7\x73\x0f\x9e\x69\x3a\x1c"
+  "\x95\x86\xa7\x64\x3f\x3d\x42\xf4\xc7\x7c\xa2\xff\xe1\xc2\xdb\x47"
+  "\x74\x66\x02\x9e\x56\x92\x72\xf1\xe7\x35\x44\x67\x1b\xc3\x30\x2f"
+  "\x4e\x0d\x63\xd7\x9b\xa1\x7e\x5b\xf0\x78\xf9\xcc\x02\x72\x04\xf5"
+  "\xb4\x2d\x0b\x56\xe4\x58\x26\x67\x4d\xcd\x9a\x3a\xfd\x29\xcb\xc4"
+  "\x89\x96\x29\x56\xeb\xfd\x93\x26\x4f\x99\x34\x79\xba\x65\xf2\xb4"
+  "\x19\x53\xee\x9b\x31\x6d\xba\x65\xfd\x96\xd2\xb5\x93\xad\x3f\x29"
+  "\xb6\x6c\x28\x5a\x5b\x66\x79\x66\x6d\xe9\xfa\xcd\x85\xa5\xc5\x5f"
+  "\x56\xad\xaf\xfb\xc7\xe8\x7d\x37\x44\x92\x03\xd1\xd4\xbe\x9d\xcc"
+  "\x37\xe6\x93\x39\x23\x93\xc2\x31\x99\xda\x13\xf7\x6f\xfd\x13\x8f"
+  "\xfd\x71\xfc\xca\xd1\xbf\x9f\xf3\x93\xf1\xb3\xe6\xbd\xbb\xff\x08"
+  "\x19\x27\x4c\x27\xe3\xf7\x03\x64\xbc\xb5\x97\x8c\xa3\x8b\xc8\x68"
+  "\x58\x43\xc6\x67\xd2\xc9\xf8\xe4\x31\x32\x2e\xaf\x21\xe3\x42\x2f"
+  "\x19\x67\x9c\xba\x36\xac\xbc\x5d\x85\xfd\xdc\x47\xc6\xba\x66\x32"
+  "\xba\xba\xc8\xb8\xd3\xa1\xc2\x8e\x21\xec\x3f\xb9\xbe\x69\x32\xfc"
+  "\x3b\xff\xbe\xaa\x9d\x30\xf4\x9f\x39\xa7\xf2\x1b\xc0\xe3\xdb\xbf"
+  "\x6f\xff\xbe\xfd\xfb\xf6\xef\xdb\xbf\x6f\xff\xbe\xfd\xfb\x0f\xfe"
+  "\xfb\xc2\x68\xa6\xdf\xc3\x32\xf1\x3b\x13\xd3\x3d\x86\xef\x14\xf1"
+  "\xbe\x11\xe2\xf3\x50\x94\x28\x7d\xac\x68\x4f\xe4\x9e\x93\xa4\x79"
+  "\x87\x88\xf8\x4c\xe7\x6b\x07\x85\x97\xcf\x6b\xce\x7f\x8f\xa8\x0d"
+  "\x96\x23\xef\x63\x01\x9c\x02\x0f\x3d\x9f\xab\xf6\x2c\x09\x1f\xc7"
+  "\xf3\xbe\x27\x84\x97\x23\xbc\xed\x3a\xfb\x60\xe4\x9e\x2b\x86\x39"
+  "\x7f\x9c\xc4\xa7\x29\x06\x0e\xc3\x68\xf1\x50\xe9\xcc\xeb\xc0\x48"
+  "\xd2\xf1\xf2\x19\xc9\xc0\xf0\xfa\x9c\x94\xee\x73\xb6\xde\x84\xbc"
+  "\x3e\xd4\x29\x53\xdb\x33\xd4\x2b\x9c\x64\x6a\xab\x08\xf2\xd9\x51"
+  "\x43\x37\x8d\x7c\x07\x6f\x23\xde\xfa\x79\x04\xce\x97\xc1\x30\x90"
+  "\xd7\xe0\x77\x8e\xb0\x0e\xe6\x05\x6c\x79\xf6\x9b\x46\xae\xf5\x19"
+  "\x5b\x8d\x2a\x6d\xca\x08\x2d\xad\x11\x69\x0b\xf4\xb4\x2a\xce\xb8"
+  "\x48\x8b\xbb\x01\x71\x15\xd1\x71\xe6\x6a\x2d\x2e\x09\x71\x35\x31"
+  "\xf8\x99\xdd\x57\x83\xd4\x4d\x23\x0e\x03\x17\x0b\x9f\x55\xe2\x3c"
+  "\x5a\xfa\x54\xa4\x6f\x8b\x86\x45\xa4\xc5\xa5\x21\xce\x13\x1d\xf7"
+  "\x5b\xab\x16\x77\x0b\xe2\x82\xd1\x71\x06\x3d\x5f\xba\xdf\x39\x32"
+  "\x3d\x4e\x3d\xb9\x7c\x83\x2a\x9b\xeb\x30\x72\x26\xd2\x38\x38\xcd"
+  "\x0a\x8b\x83\x98\x57\x1c\x77\xbc\x71\xb0\x7c\x4e\xb3\x46\x87\xe3"
+  "\x41\xfe\x08\x9a\x82\x96\x23\x2b\xf5\xfc\xf3\x2d\x0c\x83\x24\x0d"
+  "\x19\x8e\x87\x46\xe4\x30\x1c\xfe\xc6\xef\xb1\x5c\x6f\xed\xb7\x85"
+  "\xeb\x17\xbd\x97\x07\x43\x21\x4a\xc0\x60\x67\x18\x9e\xe1\x89\xba"
+  "\x0c\x94\xa5\x8b\x90\xfd\x56\xde\xaf\x95\xe5\x0a\x39\x05\xb9\x2b"
+  "\x02\x64\xb9\x8d\xec\xe7\xe8\x86\x74\xde\x0f\xb4\x6f\x2b\x25\xda"
+  "\x6d\x22\xc0\xe7\xeb\x3b\xbc\xbd\x64\xf7\x8a\x1e\x3e\xc3\x5e\x75"
+  "\x89\x12\xf9\xce\xa2\xaa\xe7\x29\xbd\xad\xf2\x93\xf8\x77\xda\xf2"
+  "\x9d\x40\x63\x39\x6f\x17\x75\xd4\x75\x91\xbd\x2e\x3a\xaf\xfd\xbb"
+  "\x94\x7e\x92\xcf\xc3\x3b\x29\x99\xf1\x68\xb3\x04\x29\x98\x96\xe5"
+  "\xaa\x7c\x93\xcc\xf6\x71\x64\x3c\x59\xd4\xaa\xe3\xe2\x61\x5c\x76"
+  "\x9d\xa7\xc4\x77\x9f\x81\x0c\x9d\x67\x7c\xef\x73\x7d\xb8\x35\x60"
+  "\x3c\x9e\x9e\x4b\xc7\xd3\xcf\x50\x5b\xfa\x2c\x6a\xab\x98\x4f\xfb"
+  "\xce\x53\xd2\xf1\xc0\x4c\x6a\x33\x3f\x88\x36\x36\x9f\xdc\xbd\xf8"
+  "\x6d\x19\x40\x1a\x9f\x3c\xdf\xd1\x4d\x37\x9c\xaa\x79\x96\x12\x3d"
+  "\x0a\x26\xe8\x7b\xc3\x19\xfd\xac\x02\x7f\xc7\xab\x47\xd9\xad\x94"
+  "\x0e\xfc\x7a\x80\xcb\xfd\xe7\x28\xe9\xa6\x8c\x74\xb2\x02\xe7\xe1"
+  "\xee\xda\x20\x99\x2b\x69\xc4\x10\x6d\x6b\x8c\x3c\xe7\x0c\xd9\xac"
+  "\x3f\x28\x7a\x58\x46\xfb\xb6\xe5\xa3\x9d\x26\xe5\xa2\xec\x5e\x6d"
+  "\xff\x5f\xaf\xfd\x1d\x32\xf7\x6d\xce\xe7\x7d\xcf\x5d\x88\x2b\xd1"
+  "\xe3\xf8\xfc\x36\x9f\xcb\x9e\x34\x86\xef\x86\xca\xa6\x8f\xae\xf6"
+  "\xf0\xde\xc2\x5e\xde\xef\xc9\xf0\x92\x2b\xc8\x84\xfa\x24\x00\x9f"
+  "\xfb\x1b\x10\xfe\x7d\xa4\x43\xfe\x66\x0f\x1d\x95\x72\x24\x6e\x59"
+  "\xe9\x0b\xdd\xb2\xf2\x52\xe8\x8d\x95\x7d\xe2\x8d\x95\x5f\x0c\xbc"
+  "\xb1\xf2\x73\xfb\x16\x4a\x1c\xb8\x65\xa5\xb7\xc3\x26\x79\x90\xd2"
+  "\x61\xbb\xc0\xfb\x04\x13\xd9\x17\xf7\xaa\xe7\xc1\xfb\xe0\x9f\xf8"
+  "\x0e\xa5\xf4\x50\xea\xb4\x1c\x77\xf0\x63\x5a\x55\x49\x02\xbf\xf3"
+  "\xe3\xd5\xaf\x2f\xed\xbe\x53\xaa\x0d\x25\xa2\x4e\xa3\x2c\x1e\xf3"
+  "\xc4\xdd\x5c\xae\x37\xf5\x81\x53\x78\x4e\xe3\xe9\xc4\x73\x46\xa4"
+  "\xdd\x77\x06\xb4\xb2\x8f\xde\x61\x20\x3e\x9f\x30\x29\x44\x86\xf3"
+  "\x34\x6a\x26\xf0\x4f\x19\x82\x6e\x63\x43\xd5\xdb\xd9\xaf\x41\x15"
+  "\xfb\x35\x60\xdd\xc4\x7a\x89\xf5\x14\xca\xd9\x8d\x72\xda\x65\x5b"
+  "\x3c\x28\x7c\x22\x6d\xbb\x03\xe1\x3d\xbe\x6d\x25\x06\xef\xb6\x12"
+  "\x63\x5f\xda\xf6\x9d\x48\x73\xd8\x63\xce\x22\x8d\x86\x3d\x0c\x0b"
+  "\x6d\xc2\x3b\x2a\x48\x26\xc0\xb4\xfd\xc3\xe5\x4e\xf3\xa1\x83\xe2"
+  "\x0c\xd2\x9d\x1e\x84\x05\xd8\x80\x03\xfa\x8f\xea\xd1\xc3\x40\xeb"
+  "\xae\xbd\x48\xc7\xf9\xdd\x81\x6c\xd6\xdf\x1e\xf7\xba\x1e\xde\x9f"
+  "\x3b\x52\xf4\xab\xf2\x90\x86\xcf\x6e\x7a\x47\x05\x68\x98\xdf\x49"
+  "\x79\x0c\x9b\xf3\xb1\x3f\x32\xe4\xdb\x29\xec\x25\xd0\x6f\xb4\xd4"
+  "\x2f\x4a\x0c\x7c\x56\xff\x38\xf2\xab\xb2\x47\xe7\xe9\x38\x72\x19"
+  "\xf2\xac\x3e\xe3\x09\x79\x38\xbe\x2e\x40\xa3\x6a\xc9\x84\x7c\xcb"
+  "\x19\x1e\xc3\x82\x1c\x78\x50\xd7\x9d\xc7\xd7\x79\x29\x24\xa2\x60"
+  "\x7a\x34\x78\x8d\x51\xf0\x10\x2e\x00\x8f\xe5\xaf\x0d\x79\x46\x35"
+  "\x4a\x78\x8f\xfc\x43\x88\xe1\x05\xc8\x6c\x91\xf8\x3e\xc6\x30\xa4"
+  "\xcf\x0b\xc0\x6c\xdd\x34\x97\x7a\x29\x39\xd1\x6b\x2f\x31\xc9\x7d"
+  "\x82\xc8\xff\x61\x55\x4f\x82\xe8\xcb\x37\x8d\x96\x7b\x04\xe7\x12"
+  "\xfb\xb7\xe8\xa5\xd1\x9f\x8a\xbe\x12\xd3\xa8\x5e\x32\x33\xce\x7c"
+  "\x4e\x88\xf1\x8c\xe4\xe5\x23\x0b\x1e\x9b\x45\x8f\xcd\x5f\x34\x7f"
+  "\x16\x2d\x99\x33\x6f\x16\x59\xef\x9f\x68\xbd\xf7\x87\xd3\xef\xa5"
+  "\xbc\x1f\x3f\x32\x8b\xf2\x96\xce\xa2\xe5\x78\xf2\x96\x2f\x78\x64"
+  "\xfe\x82\xe5\xb3\x28\xff\xc1\x45\xf8\x9a\x37\x6b\xb2\x75\xe1\xc4"
+  "\xbc\x79\x8b\x16\xd0\xc3\x2b\xa6\x58\xa7\x4c\xa1\x39\x0b\x72\x27"
+  "\x5b\xad\xda\x7b\xb2\x95\x93\x3c\x31\x7d\xc1\xf2\x89\x79\xa5\x1b"
+  "\xcb\x37\x4e\x5c\xba\x68\x1e\x2d\x58\x30\x2b\x2f\xba\xaf\xcd\x1c"
+  "\xb8\x3c\xc0\x34\xf6\x89\xcf\x72\xd8\x27\x03\xd5\x83\xf7\x78\x7a"
+  "\xe5\x59\x0f\x4a\xf9\xb8\x9e\x79\x26\x75\x6b\x32\xf7\x57\x66\xbf"
+  "\x33\xf9\x0c\x68\x97\xcd\xb4\x63\xbf\x08\xdd\x74\xf3\x78\xc4\xdd"
+  "\xa5\xf5\x1d\x09\x88\x0f\x46\xc7\xa7\x42\xee\x93\x27\xf1\xd9\x01"
+  "\x37\x1e\xd0\xdb\x07\x1d\x08\xba\x7a\xa9\xcf\x9e\x9f\x20\xcf\x6e"
+  "\x82\xd7\xbc\xa7\xd6\xef\x4c\x99\x1e\xd1\xd6\xbb\x78\xef\xad\x65"
+  "\x2b\x99\x2e\x52\x4a\x6a\x47\x79\x36\x9f\xaf\x21\x77\xb9\x06\xe3"
+  "\xd2\x20\x8c\x91\xda\xf9\x4f\x4f\x3d\xef\x6b\x56\x70\x1c\x11\x7a"
+  "\xc1\xc3\x70\xf6\x21\x4e\x83\xf5\x68\x07\xf4\x03\xf4\xf7\x5b\x21"
+  "\x7b\x26\x89\xb4\xac\xda\x50\x7f\xa6\xec\x13\x90\xaf\x45\x97\xe7"
+  "\x7d\xbc\x67\xd6\x86\x74\xef\xe6\x18\x78\xcf\xa9\xdc\x7f\x4a\xc9"
+  "\xec\x83\xc1\x17\xaa\x7e\xc0\x23\xcf\x46\xcb\xb0\x54\xb3\x48\xc3"
+  "\x77\xf5\x03\x67\x85\x5d\x9d\x97\x46\x58\x02\x87\x81\xd7\x26\xe9"
+  "\x6b\x64\x9b\x0c\x37\x21\x7c\x0b\xf0\xeb\x1c\xe0\xfc\x9f\xc9\xfc"
+  "\xc3\x11\xf6\x38\xd2\x9e\x0d\xa5\x3d\x70\x0e\xb2\xc3\x61\xb0\x13"
+  "\x6e\x9e\x0f\x78\xff\x93\xcf\xaa\x8b\x94\x63\x0e\xfc\xee\x6a\xdd"
+  "\xda\x2b\xfd\xbe\x7b\x10\x17\xb2\x03\x66\xff\x60\xf9\x99\x9c\x17"
+  "\x65\x99\xfd\xfd\x25\xe8\xe3\x52\x95\xbf\x37\xc6\xe7\xb3\xc1\x34"
+  "\xe9\x5c\x26\xb7\x6b\xf0\x62\x2a\xf8\x34\xc2\xef\x4c\x6d\x8a\xe1"
+  "\xd3\x31\xc0\x39\x0b\xba\x77\x02\xc6\x98\x50\x1f\xca\xc0\x37\xe0"
+  "\x1a\x35\xb8\x3a\x0c\x9f\x92\x83\xd4\xae\x18\x39\x18\x01\xd8\xb3"
+  "\xc2\xf1\x69\xe6\xe8\xf8\x9b\x2e\x20\x7e\xae\x16\x8f\xf6\x95\x96"
+  "\x11\x1d\x9f\x96\x8d\xf8\x07\x51\xbe\x0f\xed\xc7\xe4\xa1\x94\xe6"
+  "\x7a\xb6\xff\xc2\xe9\x57\xc4\xa4\xb7\x21\xfd\x43\xbc\x2f\x9e\x75"
+  "\x3b\xa7\x6f\xd0\x64\x15\xe9\x13\x91\x7e\x57\x4c\xf9\x27\x91\x7e"
+  "\x79\x04\x7e\x31\xf5\xbf\x71\x1d\xe2\xf3\x59\xb6\xf0\x2e\x42\x9a"
+  "\xe1\xdc\x66\x59\x5f\xf0\x8d\x9a\x48\x7f\x3a\xa6\x7c\x4e\xf7\x5c"
+  "\x48\xa7\x51\x1f\xd3\x28\xa5\x59\xb3\x45\xce\x28\x1c\x6e\x4c\x8c"
+  "\x29\x23\x13\x79\xca\x20\x3f\x67\x75\xd9\x88\x93\x67\x66\x4c\x9e"
+  "\x02\x29\x5b\xaa\x1c\x8d\xc7\x2a\x8f\xa6\x8b\x22\x61\x70\xdd\x60"
+  "\x1f\xdd\xe8\x88\xa9\x7b\x01\xca\xdd\xb6\x57\xb5\xf3\x1b\x20\x13"
+  "\x53\x10\xb6\x04\x30\x3f\x61\x39\x62\x59\x77\x7b\x03\xd0\x95\x39"
+  "\x49\xaa\xcf\xbf\xf1\x6c\x72\x25\xf1\xef\x89\xfc\x9b\x61\x8b\xfe"
+  "\x5c\xad\x0d\xdc\x78\x16\x6f\x0e\x97\xfe\x97\xb8\xed\x89\xfe\xc5"
+  "\x21\x05\x73\x4c\x02\xda\xa8\x11\xdf\x03\x5a\x19\x0b\xf8\x5c\x31"
+  "\xf0\x3f\x07\x3d\x4c\x7c\x36\x1a\xe1\x53\x11\x3e\x4b\x8b\x9f\xc6"
+  "\xe9\xf1\x7b\xb2\xf6\x9b\xe5\xf6\x9c\x26\xb7\x68\x07\x37\x4d\x94"
+  "\x65\xcb\xb6\xa0\xf2\x87\x94\xdc\xcf\x43\xdc\xad\x78\x2f\xc2\x3b"
+  "\x01\xef\x87\x51\xf6\x59\xf6\x05\x61\x1f\x80\xdd\xa1\xbe\x4f\xe2"
+  "\xfd\x08\xde\xbf\xc6\x7b\x39\xde\xef\x71\xbb\xf5\x6e\x2e\xa1\x18"
+  "\x99\xe9\x0d\xa9\xb6\x3a\x5c\xf1\x70\x4c\x8d\xd6\x7e\x54\xfb\xfd"
+  "\x2c\x1c\x26\x54\x98\x51\xd1\x5c\x0b\xeb\xcf\x61\xba\xe4\x01\xbe"
+  "\x8d\xcb\xd7\xda\x7d\x82\xe2\x93\x4a\x13\x52\xf9\xcc\x8a\xdf\x5a"
+  "\x98\x4a\x67\x88\x2c\x13\xef\xf9\x55\x3e\x21\xf0\xb6\x4a\x3f\x12"
+  "\x74\xd3\x54\xd0\xc4\x8c\x6f\x33\xd3\x49\xa6\x97\x70\x6f\x6c\x8c"
+  "\xe0\x37\xec\xf1\x9b\x6c\x31\xfc\x6e\x02\xbf\xf7\x4a\x7e\x83\x76"
+  "\x3a\xce\x8c\x3f\x64\x9a\xfb\xb6\x61\xba\xdc\x40\xbe\x7b\xc3\xba"
+  "\xfb\xa6\x96\x68\x38\x29\xcd\xa2\x7a\xf6\x0a\x94\xa7\xce\x0d\x02"
+  "\x9e\xa9\x92\x65\xf4\x26\xd8\xff\x27\xcf\x48\xbb\xa9\xfa\x81\x6e"
+  "\x86\xe3\xb3\x4b\xbf\x3b\x3e\x93\x8d\xdb\xd6\xcd\xa4\xc7\xcb\xb8"
+  "\xd4\x2a\xa9\xb3\x4d\xeb\x64\xdc\x58\x0f\x44\x4b\x8f\x23\x75\x9e"
+  "\xcb\x67\x2a\x97\x71\xd3\xc3\x70\xb3\x5a\x34\xb8\x26\xb6\x37\xd8"
+  "\x6e\x40\xff\xdd\x83\x34\x18\xff\x8c\xca\x1f\xd2\x97\x92\x2b\xab"
+  "\x19\x42\x63\xbc\xdb\x41\x09\xee\xe0\x69\x5a\x16\x14\x03\x13\x1d"
+  "\x34\xc2\x1d\x3c\x4c\x77\x11\xa5\xba\x83\x67\xe8\x6e\xa2\x71\xee"
+  "\x60\x0d\xfa\xe7\x26\x8e\xff\x28\x93\x0c\x06\xbc\xed\x77\x3a\x8c"
+  "\x06\x77\x70\x17\x65\x38\xcc\x78\xaf\xa3\x07\x13\x84\xdf\x1d\xcc"
+  "\x45\xba\x22\x5a\x36\x20\x3e\x9b\x9f\x20\xfe\xb2\x7a\x80\x52\x72"
+  "\x5f\x14\x76\x77\x10\xb6\x72\xf0\x04\xc2\x43\x62\xd9\xc0\x15\x3c"
+  "\x7e\x11\x72\x65\xb5\x2c\x1b\xf8\x4c\xcc\x7b\xf1\x23\x7c\xff\x45"
+  "\x08\x23\x09\x77\x70\x26\x75\xf8\x7c\x48\x67\x17\xe2\x40\x56\xf3"
+  "\xaa\x4b\x46\xea\x67\xff\x47\x07\xb2\x5a\x50\xc7\xf6\x7e\xd4\x0f"
+  "\x7d\xd0\x3f\xf5\x6f\xc3\xbb\x3a\xeb\xbf\xc8\x6f\x57\x56\xa7\x48"
+  "\xc9\x6a\xcf\xc2\xc0\x83\xeb\xe0\x0e\x76\xd1\x6a\x98\xce\xcb\xb6"
+  "\x78\x05\xe3\x3f\x7a\x07\x8f\x3b\x66\xb2\xef\x84\xe4\x65\x5b\xec"
+  "\x02\x71\x89\x22\x35\xab\xdd\x1d\xec\x25\x94\xd1\x09\x78\x1f\x4b"
+  "\x78\xae\xac\x00\xd2\x7a\x39\x5d\x24\x1c\x86\xc1\x69\x97\x0d\xb0"
+  "\x3f\xab\xac\x40\x7f\x6a\x56\x4f\x7f\xea\xa4\x44\x3c\xd3\x45\xda"
+  "\xa4\x87\x84\x73\xcc\xef\xf8\xfc\xab\x70\x4d\xca\xc7\x77\x89\x9f"
+  "\x7d\x35\x31\x2d\x07\x68\xb8\x38\x30\x29\x1f\xf2\x33\x1f\x72\x08"
+  "\x7c\x27\xed\x96\xf8\x56\x4f\x7a\xd9\x2f\xeb\x31\xe9\x25\x55\x8f"
+  "\x49\x2f\x72\x78\x1f\x64\x0a\xbf\x9b\xfb\x54\xdc\x2f\x90\x6f\x85"
+  "\xcc\xe7\x9a\xd4\x2c\x52\x26\xb5\x04\xd0\xbe\x40\x57\x07\xd3\x11"
+  "\x74\x75\x30\x2d\x01\xbf\xd9\x5d\xb1\x87\x44\xea\xa4\x16\xe0\xd3"
+  "\x8e\xfc\x7f\xec\x97\xfd\xf4\xa4\x1e\xbf\x82\xfd\x57\xc0\x29\x80"
+  "\xfc\x9a\x00\xa3\x07\xb0\x02\xfd\x4e\x0b\x2d\xdb\x22\x02\xcb\x82"
+  "\x3b\x82\xab\xb7\x90\x69\x02\x39\x0c\xec\x3b\xd7\x5d\x51\x84\x7a"
+  "\xb6\xe1\x3d\x1f\xf1\x74\x23\xca\xfa\x08\x70\x7b\xb8\x3c\x94\x13"
+  "\x00\xcc\x4b\x80\x55\xc4\x38\x5d\x61\xbf\xa4\x69\xd6\xc4\x2b\x12"
+  "\x3f\x6b\x66\xc8\x65\xcd\x09\xa5\x58\xa7\xeb\x32\xc4\xf2\xa3\xe8"
+  "\x56\x43\x4b\x7d\x22\xe8\x0e\x1e\x22\xc8\x58\x4a\x87\xef\x0c\xc7"
+  "\x63\x6c\x70\x18\x7c\x66\x99\xda\x85\x77\x13\xb1\xfc\x74\xd8\x5e"
+  "\xe0\xb4\x1f\xb1\x0c\x2d\xb5\xf9\x76\x4c\x24\x9b\x01\xdf\xf6\xd5"
+  "\xc1\x44\x5a\x65\x33\x3b\x06\x5c\xd6\xf4\x0e\x1b\xf3\xe5\x34\xf2"
+  "\x70\xbe\x75\x94\x6c\x80\x7d\x6c\x10\xc1\xe4\x0a\xaf\x79\x54\x89"
+  "\x5d\x74\xf8\x72\x91\xd6\x26\x7d\x01\xb3\x1c\x71\xfa\x25\xbd\xc2"
+  "\x33\x90\x62\x6d\xe7\xba\x89\xd1\x0e\x3a\xd9\x3b\x8d\x78\x8c\x72"
+  "\xb2\xb7\x89\xe5\x34\x24\x52\xac\xb5\x90\xd1\xfe\x25\xbd\x8e\x84"
+  "\x55\x97\xc8\x80\xb0\x81\x93\x25\x87\x11\xdf\x86\x74\x27\xa4\xdc"
+  "\x2e\xbd\x14\x4c\x0e\xa6\x58\x13\x83\x2e\x6b\xf3\xd2\x4b\xfd\xe2"
+  "\x64\x49\x0d\x3d\xd9\xeb\x00\xad\x0e\xd3\x92\x0b\x41\x53\x87\xad"
+  "\x08\x69\xfc\x08\x6f\x92\xf2\xbf\xe4\x42\x9f\x58\xfa\xbc\xf8\x6c"
+  "\xe9\xa5\xbf\x88\x25\x25\xe2\xa3\xd5\x15\x34\xfa\x86\x1d\x22\xc4"
+  "\xed\xe2\x44\xd7\x61\xba\xe1\x0c\xfb\xc6\x99\x4f\xb9\x85\x21\xb1"
+  "\xe4\xc2\x67\x62\xd5\xf3\x4c\x9b\x99\x74\xb2\x04\xed\xa7\xa2\x06"
+  "\xf4\xb6\x66\x9e\x2c\x39\x86\xf2\xe7\x03\xae\x5d\xf0\x5d\x5f\xb9"
+  "\x85\xad\xc9\x4f\x5e\x48\xa1\x13\x5d\x35\x14\x4c\xb5\x26\x0e\x1c"
+  "\xb0\x62\x2c\x65\x9d\x1e\x3a\x60\xcd\x11\xa9\xd6\xda\xe0\x01\x6b"
+  "\xf3\x40\xaa\x15\x32\x30\x39\x1d\x7c\x1a\xc1\x3c\xbf\x8a\x31\x3b"
+  "\xbe\x6f\xbe\xca\xfc\x77\x4d\xce\x14\x29\x93\x73\xa0\x1b\x85\x92"
+  "\xfd\xc9\x99\x3c\xee\x16\xa9\x93\x73\xfa\x53\x27\x4f\x47\xba\x1c"
+  "\xd5\xbe\x26\xe7\xb3\x5c\xca\xbe\xa9\x7a\xf2\x8f\xd1\x97\x98\x10"
+  "\x5f\x82\xa7\x02\xcf\x6e\x84\x75\x02\x7e\xaa\x5f\xc1\xec\x14\x0f"
+  "\xb8\x60\x67\x5e\x62\x99\xb4\x03\x56\x60\xd9\xc0\x74\x3b\xe8\x88"
+  "\xb6\x32\xb9\x33\x74\x60\x72\x8f\x48\x9b\x92\x1e\x90\xf2\x3f\xe5"
+  "\x16\x86\xdf\xbf\x2d\x93\xc7\xe4\x66\x71\x60\x4a\x26\xc2\xde\xf2"
+  "\xb3\xbc\xa6\x4c\xa9\x0d\xa5\x4c\x09\x08\xd7\x94\xe6\xc5\x2f\x0a"
+  "\xef\x80\x6b\x4a\x7b\xc8\x35\xa5\x25\x38\x0c\x36\x6c\xc5\x31\x62"
+  "\x1d\x15\xfc\xad\x10\x7c\x77\x53\x87\xad\x49\xca\x80\xbb\x02\xed"
+  "\x60\xcb\x6d\x8e\x93\xbd\x90\x07\xdb\xaf\xa4\x7e\xea\xf0\x9d\x96"
+  "\x74\x15\xa9\x53\x6a\x59\xae\x98\xc7\xab\x6c\xe4\x40\x59\xcd\xa1"
+  "\x03\x53\x5a\x06\x0e\x00\x6e\x2a\xca\x49\x9b\x36\x23\x20\xdb\xec"
+  "\x34\xc8\xec\x31\xe4\xf9\x03\x29\x39\x9f\x36\x7d\x28\x3d\xc9\xfa"
+  "\x8a\x75\xd4\xb2\x60\x80\xe5\xe6\xaf\xac\xdb\x94\xae\xa2\xd5\xba"
+  "\xae\x62\x3d\xc5\xe3\x02\xd6\x55\x21\x4d\x57\x85\x34\x5d\x25\xbf"
+  "\x53\xa0\x6f\x5c\x59\xed\xac\x93\x96\x55\x28\x5d\xb3\x6c\xc0\x2a"
+  "\x20\x1f\x49\x80\xd1\xae\xf8\x81\x34\xd5\x59\x1f\xcb\xf4\x92\x4e"
+  "\x59\x81\x10\x74\x4e\x08\x3a\x27\xa4\x74\x4e\x8e\xa6\x73\x8c\xba"
+  "\xce\x61\x1f\xa7\x68\x57\xa1\x78\x3a\x27\xa4\xe9\x9c\x01\xa1\x74"
+  "\x4e\x48\xd3\x39\x1c\x3e\xa0\xe9\x9c\x81\x38\x3a\x27\xe4\x9a\xc4"
+  "\xf5\x35\x69\xba\xc6\xc1\xba\x86\xeb\x1b\x3a\x30\xa9\x25\xa4\x74"
+  "\x4d\x27\xc6\x04\x46\xd6\x35\x03\xc8\x13\xd2\x75\x8d\x5f\xe6\x0f"
+  "\xb0\xbe\xe9\x7f\x89\xa0\x43\x2d\xc4\x7a\x46\xea\x94\xe0\xb8\x20"
+  "\xeb\x14\xd0\x6f\x76\xac\x4e\x11\xd5\x56\xf4\x95\x94\xa2\x74\x95"
+  "\x75\x7a\xf2\x0e\x11\x84\x4e\x49\x5f\x56\xe1\x23\xbe\x67\x3a\x39"
+  "\x08\xdd\x5d\x51\xee\x70\x57\x04\x09\xba\x20\x47\x74\x38\x08\x7a"
+  "\x07\x32\x3c\x00\x7d\x41\x84\xb6\x59\x8b\x36\xda\x0e\x7d\xd4\xdc"
+  "\x61\xfb\x98\xd0\xe6\x13\x97\xf4\xf6\xb9\x57\xf9\x32\x53\x96\x5c"
+  "\x10\x5e\xd0\xc7\xb3\xca\xe6\x80\x8e\xc9\xf4\x9e\xec\xfd\x0d\xe5"
+  "\x76\x89\x50\xee\x1a\x8f\x05\x6d\xad\x79\xc9\xda\xd6\x64\xbe\xc7"
+  "\x69\xe9\x25\xd1\x0a\xdd\xf8\xff\x2c\xb9\x90\x92\x5c\xd0\x45\xdf"
+  "\xcb\x2d\x14\x21\xb4\x29\xd0\x1d\x6d\x0d\x6d\x12\xed\x6c\x3a\xda"
+  "\x5d\x0e\xda\x5a\x6d\x30\xa6\xad\xa1\xdd\xdc\x8c\xdf\x16\x45\xbf"
+  "\xc9\x39\x68\x6b\x99\x21\xd9\xa7\x75\xc9\xb1\x18\xda\x43\x0e\xcf"
+  "\x55\xa1\x8d\x64\xa2\x5d\xc8\xf6\x16\x52\xf9\xf2\x43\x4c\x3f\xa3"
+  "\xd6\xde\xc0\x0b\xc4\x97\xe0\xa9\xc0\x13\xbf\xbd\xd9\x62\xda\xdb"
+  "\xf3\x5a\x7b\x4b\x55\xed\x0d\x7c\x35\x0d\x6c\x53\x6d\x8e\xcb\xe0"
+  "\x31\xdb\x60\x9b\x4b\x9b\x52\xcb\xbe\x7e\x94\xfc\xc8\x76\x87\xfe"
+  "\x65\x4a\x3b\xda\x5c\x0b\xda\x1c\xe0\x09\x2f\xeb\x4f\xc8\xe7\x9f"
+  "\xb9\xcf\x5b\x6a\x13\x7f\x5e\x3d\x70\x9b\x03\x6d\xaa\x1d\x3a\xed"
+  "\x2f\xd0\xa7\x7f\x5e\xe5\xa3\x46\xc0\xaa\x45\x5b\x6a\x46\x9b\x6a"
+  "\x41\xdb\xe2\x36\x35\x7d\x60\x1b\xc3\x9c\x36\x7d\x10\x86\xec\x33"
+  "\xa3\xdb\x94\x9a\xe9\x8e\x3f\x5f\xe8\x77\xde\x9e\xe4\xa1\x33\xf2"
+  "\xdc\x35\x7e\xa7\x7b\xe8\x4f\x87\xb5\xdf\x19\x1e\xfa\xad\x0c\xe7"
+  "\xb6\x68\xab\xa2\x9b\xce\xd3\xed\x9d\x90\x7b\xc2\xef\x24\xfc\x3e"
+  "\xb3\xec\xae\x8f\x60\x53\xbc\x0f\x9b\x42\xf8\xb9\x3d\x0a\xe7\x54"
+  "\x8c\x43\x28\x1b\xf2\x98\x28\xfc\x99\x49\x22\x6d\xce\x79\xd1\x9f"
+  "\xce\x73\x52\xc9\xf8\x1e\x0d\x1a\x64\xe0\x9d\x76\xe8\x32\x8d\xc1"
+  "\xc3\xbe\x9e\x1d\x6c\x5f\xe1\xb7\x55\x6c\x4e\x1f\xb9\x6f\x13\x4d"
+  "\x48\xf6\x29\x9f\xee\xc9\x3b\x52\x78\x6e\x66\x0c\xff\x16\xce\xdf"
+  "\x07\x1b\x2e\xeb\x7e\xdd\x51\x5e\x9c\x3b\xb1\x07\xfc\x4c\x87\xac"
+  "\x66\x1d\x17\xc6\x0d\x78\x7e\x17\x78\xf6\x3e\xba\x25\x9b\xf8\x0e"
+  "\xb3\x78\x7a\xc6\xef\xb4\x0c\xd6\x7f\x88\xf8\x09\x3a\x4d\x86\x88"
+  "\xcf\xd5\xe9\x34\xd4\xf9\x56\xee\xaf\x07\x36\x89\x5e\xf6\xc9\xc1"
+  "\xe7\x70\xed\x41\xf1\x3f\xd9\xbf\x7b\xd5\x00\x25\x2e\xab\x08\x08"
+  "\x77\xaf\x68\xe5\xbb\xd0\x1a\xd8\x4f\x48\xa5\x08\x85\x52\xe7\x9c"
+  "\x10\x07\xe6\xb4\xf7\x6d\x12\x41\x9e\xfb\x40\x19\x47\x3c\x34\xaf"
+  "\x59\xf1\xc2\x9a\x29\xc7\x80\x29\x73\xd8\xd7\x60\x2a\xc3\x3a\x89"
+  "\xfc\x03\x07\xe6\x9c\x42\x3a\x8c\x8d\xcf\xfb\x64\xba\x14\x6b\xa6"
+  "\x6d\x2b\x7d\xe7\x3c\x8d\x4b\x91\xe3\x00\xd7\x1c\x0f\xeb\x05\x84"
+  "\xa5\x20\x6c\x2c\xe0\x77\xf9\x9d\xe3\x12\x3d\xf4\xff\x06\x95\xad"
+  "\x3b\x6e\xac\x9e\xce\x43\x16\x3e\xc1\x19\x35\x77\xaa\xed\x96\x70"
+  "\x44\x9d\xf3\x32\x50\xf4\xa9\x35\x2e\x29\x3b\x7e\x74\x58\xaf\x5b"
+  "\x9b\xd9\xbf\xa6\x7d\x3b\x8d\x05\x7f\x18\xbf\x03\xf6\x0a\xd1\x2d"
+  "\x9c\xe3\x32\xdf\xdd\x1a\xc0\x18\x62\x5c\x9d\x87\xfe\xa6\x7c\x28"
+  "\x7a\x86\x2e\x8b\x2e\xc0\xc8\xd9\x8f\x71\x20\xd3\x87\xe9\x89\x76"
+  "\x13\x02\x1d\xce\xb2\x5e\x6a\xd8\xc4\x63\xe1\x71\x1e\x9d\x5e\x43"
+  "\xf3\x64\xce\x19\x35\x5e\xbc\x23\x5b\x38\x05\xb5\x7e\x8f\xd7\x1a"
+  "\xee\x98\xa3\x68\x30\x79\x7a\x1f\x74\x09\xcf\xa5\xb2\x2f\xcc\xb2"
+  "\x74\x11\xf0\x3b\xef\x98\xea\xa1\xbb\x4f\x69\x73\x36\x3e\x77\x70"
+  "\x01\xeb\x97\xb8\x7d\x97\x3c\x93\x3c\x08\xff\xfb\x6b\x3a\x40\x59"
+  "\xa5\x9f\xaa\xe6\x57\x29\xfe\x07\x18\x2e\x9f\xa9\xef\x42\x7c\x99"
+  "\x4f\xc0\x4e\xac\x9a\xce\xe3\x0c\x3e\xdf\x8b\xb0\x42\xc8\xb5\x68"
+  "\x2d\x65\x9c\xbe\x5f\xd8\xfa\xbd\xab\xd4\x8d\xf1\x20\x9f\xa1\x57"
+  "\xf3\x37\xdf\xcf\x3d\x5e\x4e\xda\x9c\xd0\x1d\x27\x3c\x34\x71\x9d"
+  "\x8e\x17\xdb\x1a\xa0\x6d\x22\xdb\x1e\x6c\x73\xf0\xfc\x7c\x59\xa5"
+  "\x08\xb0\xed\x81\xb4\x01\xbd\x0e\x5c\x3f\x55\xaf\xef\x27\x45\xd6"
+  "\x0b\x38\x78\x31\xb6\x96\x34\x28\xdb\x42\x89\xd2\x37\xdf\x00\xcf"
+  "\xef\x2f\x90\x75\xe1\x3a\xcb\xba\x48\x3d\x8b\x7e\x22\x38\x0d\x63"
+  "\x29\x19\x9e\x03\x58\xf9\x1e\xba\x47\xf9\x70\xa0\x3b\x4e\xc4\xca"
+  "\x50\xd8\x9f\xec\xa4\x80\xfd\x0a\x7d\xcf\x1e\x12\xe7\x00\xf3\x13"
+  "\xd0\xc9\xc4\xef\x10\xdb\xdb\x01\x96\xdd\x85\x6d\xdc\x2f\xbb\x2b"
+  "\x2f\xb1\x9d\xcd\x69\x6f\x44\xda\x2e\xa4\xf9\x58\x4b\xfb\xb1\x5a"
+  "\x9b\x91\xef\xe1\xfc\x46\xdf\x78\x09\x78\xf4\x7a\x65\x9f\x5f\x45"
+  "\xfa\xb7\xc0\x37\xde\x4d\xe2\xc0\xc2\xb6\xf8\xb8\x4c\x09\x70\x9f"
+  "\x36\x70\x59\xf4\xa2\x9c\x5b\x58\x8e\xec\x5b\xe8\x56\xc8\xe4\xd9"
+  "\xaa\xed\x74\x13\xcb\x98\x48\x9d\xd3\xa3\xe8\x9e\x31\x5d\x38\x61"
+  "\x83\x42\xa3\xda\x36\xd1\x77\xd0\x86\x3c\xe7\x29\x63\xc9\xea\x4a"
+  "\x0b\x70\x25\xda\x7f\x91\xd8\x4e\xf9\x0b\xd2\x77\xf1\x3d\x96\x0d"
+  "\x17\x59\x16\x33\xd6\xe9\xb2\x88\xdf\x15\xd7\xd3\x15\xa0\x6b\x85"
+  "\x9a\x57\xc8\xf8\x84\xe7\xe2\xcf\x51\xc6\x29\xae\x2f\x1e\x03\xc2"
+  "\x7e\x27\x2e\x8b\xb1\x42\xf5\x6b\x25\x1e\xca\x08\xe2\x5d\x21\x1f"
+  "\xe8\x12\xed\xbb\x04\xe9\x8e\x88\xcb\x03\x9c\x06\x65\x65\xb4\x0b"
+  "\xa7\x81\xdb\x49\x1d\xca\xf6\x79\xe8\xc1\x56\xc5\x9b\x8c\x56\x86"
+  "\x35\x04\x0e\x25\x42\x9e\x6f\xff\x02\xf5\x1d\xff\xa4\xa5\xca\x00"
+  "\x3c\xc6\x4b\xbf\x62\x0c\xab\xc1\xa8\x74\x76\x08\xb8\xd6\x3b\x43"
+  "\x25\xd0\xcf\x25\xa1\xea\x87\x76\xcb\xdf\x5a\x9c\xd0\xfa\xd2\xf8"
+  "\xf0\xab\xe6\xb3\x8f\x8e\x2e\x1a\xdf\xa2\xe0\x54\x4d\x6f\xbd\xed"
+  "\x3c\x7f\x4b\x7f\x6c\xbe\x94\xc5\xbb\xdd\xb5\xd9\xca\xef\x32\xd2"
+  "\xa8\x71\xfe\xf8\x5f\xf7\xa1\x0c\xbf\x73\x3c\xc6\xdc\x59\xcd\x6a"
+  "\x5d\x62\xf1\xee\x21\xda\x5e\x0a\xb7\x1d\x6e\x73\xaa\x4d\xff\x60"
+  "\xef\xc9\x46\xd9\xfe\xf2\x21\xf3\x15\x9a\xfe\xe5\x39\x98\xa4\x73"
+  "\xf4\x83\x3d\x27\xd3\xa5\x7c\x1b\x85\xf1\xce\xf4\x28\x9f\xad\x88"
+  "\xbb\xf6\xb9\x33\x17\x4f\x01\x9e\x12\xed\x1b\xa9\xef\xdc\x8d\xa7"
+  "\x13\xdf\x95\x92\x76\x6f\x17\x19\x3c\x88\xeb\x83\xed\xce\xdf\x1e"
+  "\xba\x73\x85\x78\x3b\xc3\xa8\xff\x6e\x78\x93\xe7\x11\xee\x04\xbf"
+  "\xc6\x27\x2a\x5e\xfc\x40\xfa\xad\x07\x6e\x4c\x77\x61\xaf\x15\x81"
+  "\xb6\x2a\x1f\xf0\xbe\xf3\x48\x5b\xad\x8f\x2c\x77\x72\xfd\xef\x3c"
+  "\xca\x75\xf2\x81\xfe\xfc\x2e\xab\x15\xde\xe3\x75\x41\xe2\x35\x2c"
+  "\xc0\x42\xfb\x7f\x79\x8f\x9a\x93\xa8\xb2\x31\x3c\x4d\x26\x84\x5e"
+  "\x7f\x45\xe7\xc5\xbb\x2d\x9b\x0c\xfc\x7d\x6b\xbd\x9c\x77\x99\xbd"
+  "\x22\x3c\x1f\xfc\x83\x54\xb4\xf3\xd9\xec\xbb\xf9\x22\xfd\xe0\x51"
+  "\x01\x5a\x1f\x2f\x91\xbe\x21\xbd\x3c\xff\x52\x2f\xe7\x35\x7e\x00"
+  "\xfd\x37\xbe\x44\xf3\x83\xe3\x95\xba\x06\x30\xf7\x21\x0e\xfd\x51"
+  "\xef\xc9\x92\x00\x0d\x70\x9d\x91\xf7\x37\x97\x03\x66\xf6\x5d\x5d"
+  "\xc5\x77\xca\x00\x0f\x01\x5e\x29\x5d\x76\x67\xcf\xf6\x0b\x22\xa0"
+  "\xd7\x99\xd7\x3a\x01\x77\x8f\x87\x5c\xb5\x43\xb6\x89\xc1\x7a\x64"
+  "\xbe\x7f\x3c\x43\xf1\x31\x04\x5a\x45\xf3\x31\xb3\x59\xf1\xf0\x07"
+  "\x67\xa2\x79\x98\xd9\x8c\x07\xb9\x32\x67\xe2\xc9\xd5\xbe\x23\x9f"
+  "\x94\x88\xdf\xe0\x6b\x66\x8d\xdf\x99\x39\x16\xed\x63\x97\xe2\x4d"
+  "\xa6\xf2\x91\xcf\x72\xf3\x39\xfa\x9e\x7e\xf6\xf7\x7d\x81\x38\x9c"
+  "\x65\x9c\xc3\x43\xb0\x6f\xf0\x6d\x45\x7c\x0a\xb7\x5f\xf6\xb3\x19"
+  "\x19\x3f\xe8\x4f\x89\x32\xa5\x8f\xac\xe4\x1d\xbb\x77\xb3\xec\x22"
+  "\xcd\xd4\xe4\xe0\x6e\xc8\x74\xe6\x1e\x9d\xae\x08\x2b\xe7\x78\x96"
+  "\x53\x84\x37\x81\x2e\x52\x57\xf8\x30\x16\x8c\x6f\x7b\x64\xb6\x0f"
+  "\xda\x68\x29\x93\x3b\x99\x97\xbd\x74\xd7\x69\xe8\x31\xe8\xef\x87"
+  "\x1c\xaa\xff\xb9\xeb\x63\xfe\x86\xfe\x3c\x8b\xdf\xa7\x4e\x42\x4f"
+  "\x5d\xad\x7e\xe0\x54\xbf\x91\x86\x5f\x35\x52\x76\xb0\xfa\xfd\x33"
+  "\xc1\xb4\xfb\xce\xb8\x7b\x8e\x52\x47\xf0\x3f\x11\xdf\xdf\x0a\x18"
+  "\xff\xcc\xfe\x5e\xed\x5b\xc4\xc0\x87\x57\x9b\xcd\xee\xe0\x67\xad"
+  "\xd2\xb7\xba\x3a\x3f\x6f\xf8\xe9\x39\x58\x01\xab\x24\x6c\x8d\x3e"
+  "\xef\xb7\xec\x7b\x46\x04\xf7\x75\xb3\x0f\x98\xf4\x91\x7b\xaf\xd2"
+  "\x84\xb7\xb6\x92\xb5\xee\x2a\x65\xd4\x5f\xa5\x4c\xf1\x57\xbe\x73"
+  "\x27\x7c\x4f\xcf\x68\x1b\x25\xd6\x6f\x85\x3d\x17\x24\xc3\xc0\x01"
+  "\xd8\x73\x41\xd8\x73\x9f\x65\xb2\xbe\x1c\xb4\xe7\xfa\xa5\xad\x3c"
+  "\x77\x85\xf4\x09\x7e\x60\xee\x8a\x51\x25\x64\x48\x5a\x43\x29\xc0"
+  "\xcf\x7e\x91\xee\x1a\x91\xd4\x05\x5b\x12\x75\xf6\x68\xf5\xc5\x7b"
+  "\x6c\x72\x09\x0d\x97\x75\x85\x0e\x17\x07\x1e\x72\x0c\xd9\x37\x1b"
+  "\x59\xa6\x7c\xdc\x96\x50\x87\xbb\xc7\xf1\x5a\xeb\xd1\xdb\x02\xe6"
+  "\xb2\x3a\x11\xe0\xf0\xf2\x71\x22\x80\xf0\x44\x2e\xfb\x08\xc2\xfd"
+  "\xce\xbb\xad\x1e\xf3\xdd\x43\xda\x80\x18\x37\x69\xba\xe6\xee\xbf"
+  "\x15\x46\x07\x64\x74\x4a\xfa\xf6\x20\xec\xf1\x8b\xdc\x8e\xef\x3e"
+  "\xb2\x6c\x9d\x08\x5a\x36\xf0\xba\xf7\xdd\x8d\xbc\x26\xcf\x6b\x71"
+  "\x7f\x03\x5b\xe7\xcb\xd6\xe1\xb9\x0f\xe1\xf1\x43\xf2\x3a\xc0\xac"
+  "\x9e\x92\x2e\x30\x6e\xff\xaa\x76\x3d\xef\x05\x79\x4d\xee\x3b\xb9"
+  "\xbb\xd7\x43\x8f\x65\x6b\x7e\x5d\x7b\x95\x3e\xbd\xe7\x84\x0f\x34"
+  "\x88\xd6\x01\xf7\x34\xb2\x7f\x92\x3e\xd7\xec\x82\xd6\xef\xb1\xee"
+  "\xbf\xe7\x4d\x65\x0b\xcd\xce\x57\x7d\xc1\x3d\x5b\xd4\x9c\xfe\x3d"
+  "\x33\x3d\x34\x43\xca\x9c\xed\x0e\x96\x89\x7b\xca\x45\xda\xec\x95"
+  "\x9c\x2e\xcb\x41\x8e\x8d\x41\x82\x2d\x30\x3b\x5f\xc8\xb6\x72\x91"
+  "\xc4\x1b\xcf\xf9\x79\x2f\x85\xef\x96\x95\x7e\xd8\x06\xb0\x6b\x67"
+  "\x17\x70\x19\x5e\xa4\x01\xdd\x47\xa8\x35\xfb\x7b\x5c\x1e\xba\x5f"
+  "\xd3\x87\xf7\x14\xa9\xb9\xe6\x7b\x8a\xfa\x90\x17\xb6\xe2\x8d\x88"
+  "\x87\xfd\xbb\x7c\x8c\xb6\xb6\x2b\xf7\xdc\x20\xac\xcd\x43\x2b\xe4"
+  "\x3c\x6b\xf9\x38\x4a\x2f\xb7\x88\x9e\x21\x6d\xbd\xa8\x7a\x4e\x5c"
+  "\x24\xf7\xc5\x18\xe9\x16\xbf\x73\x42\xa2\x0e\x17\xfd\xed\x2f\xfb"
+  "\x8c\x8f\x3e\x8a\xb0\xb1\x3a\x5c\xa4\xb9\x09\xdf\x13\x06\xd3\xa8"
+  "\x3c\x33\x23\xf2\x3c\xda\x67\xbc\xfb\x97\x08\xcb\x8b\xc9\xb3\x26"
+  "\x26\x8f\x2d\x22\x8f\x43\x2b\x67\x57\x4c\x9e\x9a\x98\x3c\x4d\x71"
+  "\x70\x6b\x89\xc9\xd3\x1e\x93\xa7\x33\x0e\x6e\xbd\x31\x79\x82\xd1"
+  "\x79\x26\x26\x45\xd0\x96\xf7\xa8\x58\x11\x66\x89\xce\x33\xd1\x1a"
+  "\x93\x27\x5b\xff\x86\xed\xb9\x46\xd9\x06\x90\x27\xf0\x14\x7c\x2d"
+  "\x40\x3c\xea\x3f\x6b\x48\x1b\x9e\x65\x13\x32\xb3\xc2\x7e\x48\xf9"
+  "\xc7\x67\xbd\xca\xf3\xe7\xac\xcf\x61\x17\xf7\xb2\x4c\xb0\xdd\xc9"
+  "\x65\x75\x53\xd6\x5e\x96\x21\xc0\x3c\x7a\x2d\x3d\x26\xb6\xc7\xe0"
+  "\xd9\x19\x83\x67\xcf\xb5\xf4\x98\x18\x8c\xce\x93\x95\x14\x9d\x27"
+  "\x6b\x6c\x44\x9e\x46\x55\x4e\x96\x35\x26\x4f\x76\x4c\x9e\xbc\x6b"
+  "\xe5\x33\xab\x28\x26\x4f\x79\x4c\x9e\x5d\x61\x1a\x66\xc9\xbb\x60"
+  "\xb8\x3d\x20\x1c\xe3\x9f\x1f\x5d\x6f\x9f\x58\x8a\x2e\xcf\xfa\x7e"
+  "\x31\x25\xd7\x93\xc6\xd5\xa8\x7d\x53\xd2\x37\x51\x17\x4d\x92\x7e"
+  "\x5a\xd9\x17\xd7\xbb\x57\x03\x09\xbc\xa6\x04\xda\xf6\x1c\xaf\x08"
+  "\xa0\xcf\x9d\x84\x3e\x6a\xda\x74\x7d\x4f\x05\xef\x43\x91\xbe\xec"
+  "\xe4\x78\x24\xcb\xa3\xda\xdf\xa4\xa9\xda\x1a\x0e\xd7\x07\xe3\x8c"
+  "\x49\x53\xff\x17\xf1\xfa\x98\xf1\x62\xdf\x4e\x80\x51\x31\x38\xd6"
+  "\x18\xc4\x95\xcb\x9c\x74\x56\xc7\xb5\x41\xed\x85\x61\x3f\x62\x5e"
+  "\xf6\xb3\x85\x3c\x87\x23\xc6\x27\x8c\xab\xef\xe8\xd6\x80\x39\x1a"
+  "\xe7\x49\x7b\x34\x9c\x3d\x4a\x47\x4d\xf2\xe8\xfa\x64\x48\xf9\x73"
+  "\x55\x65\x76\x80\xea\xbc\xee\x7f\xb2\x0e\xf6\x26\xc6\x58\x8c\xf7"
+  "\x39\xb2\x66\x4a\xfb\x77\xc3\x55\xe2\xdf\xee\xca\x19\x72\x5f\x80"
+  "\xaa\x8b\x75\x0d\xdf\xa7\xc0\xb6\x4f\x9b\xed\x0b\xea\x93\x63\x34"
+  "\xd6\x8d\xd6\xbd\xc7\x2b\xbd\xc0\xd5\x9a\xaf\xef\x9b\xf1\x90\x55"
+  "\xd9\x75\xae\x2a\x0b\xef\x59\xe0\x75\xbc\xe3\xbe\xe9\x9c\xa6\x12"
+  "\x78\x66\xeb\x34\xe0\xbb\x19\x90\x76\xea\x50\x63\xa5\x48\xba\x2a"
+  "\x1c\xa6\x5c\x51\xf2\x63\x6d\x8b\x6e\x0f\x09\x90\x53\x6b\x67\xb4"
+  "\xcc\x59\x7b\xa2\x65\xce\x1a\x88\x6e\x0f\x46\xb4\x87\xc9\x49\xd1"
+  "\x79\x26\x8f\x8d\xce\x33\x79\x42\x44\x1e\x97\x2a\x67\x72\x76\x4c"
+  "\x9e\xbc\x98\x3c\x91\xfa\x0f\x75\x9e\x6c\x1b\x1c\x77\x4a\x7d\x3f"
+  "\xd9\x11\xf1\x6d\xac\x91\xfd\xd4\xe4\x1a\x3d\x8c\xe7\xee\xd8\x46"
+  "\x65\xb9\xd1\xe0\x1d\x89\xd1\x51\x9c\xbe\x2d\x06\x87\xd3\x31\x38"
+  "\x74\xe9\xdf\xfb\xd5\xb8\xf9\xf7\xa0\xdd\x5d\x9a\x9c\xf9\x92\x77"
+  "\xd0\xc3\xc9\xc1\x47\x1e\x67\xdb\x8c\xfb\x27\xb9\x77\x6b\x3b\x6c"
+  "\xca\x4b\x94\xc2\x7b\xe6\xba\xcb\xc9\xc4\xfe\xde\x3c\x74\x6f\x81"
+  "\x48\x9d\x9b\x87\x34\xbd\xb0\xa7\x96\x75\xd3\x64\x2e\xbf\x16\x65"
+  "\x80\x76\x53\x72\xa2\x71\x98\x92\x1f\x8d\xc3\x94\x92\x88\xef\x14"
+  "\x7c\x57\x44\xd4\x3b\xc5\x94\x2e\xf7\x68\xc2\xb6\x9e\xe2\xd2\xc3"
+  "\x79\x0e\x00\x75\xec\xb1\x4b\x3b\x20\x9b\xf7\xcb\xa5\x9d\xa3\x29"
+  "\xdb\x79\xbe\x40\x83\x79\x2c\x92\xb6\x8a\x16\x53\x4e\xc5\xe0\xe1"
+  "\x89\xc1\xc3\x1b\xd6\x35\x93\x7d\xaa\x8d\xdc\x6b\xf6\xd0\x03\x56"
+  "\x0e\x03\x2d\x2c\xc9\x41\xcb\x8d\xad\x77\xb0\x9d\x7a\xef\xc3\x3e"
+  "\xd4\x57\xbc\x64\x4c\xd3\xbe\x1f\x15\x77\xb0\xdd\x3d\x37\x0f\xfa"
+  "\x99\xf7\x44\xde\x8e\xb0\x02\xc5\xd7\x7b\x51\xff\x1f\xe5\x28\xb8"
+  "\xf7\xca\x35\x58\x4e\x8b\xdf\x99\x22\xb5\x6a\xa8\xb9\x91\x94\xbe"
+  "\xb4\x2a\xab\xb6\x5f\xd3\x02\x18\x7b\xf4\xf6\x10\xaa\xae\xb2\x86"
+  "\x0e\x2c\x42\xff\x73\x6f\x23\xda\x44\xad\x1a\xd3\xe4\x54\x42\xf6"
+  "\x6b\xc1\x3f\x8c\x81\xa7\x6a\x63\x99\xaa\xf9\xbc\x67\x0e\x7a\x89"
+  "\x7d\x4a\x26\xa9\xfd\x12\xf7\x9e\x8e\x68\x57\x3e\xcb\xd6\xd9\xe2"
+  "\x1c\x4d\x7d\x93\x6d\x3b\xd6\x1b\xbc\xf7\xee\x78\xd0\x4b\x3c\xcf"
+  "\xe2\x0e\x9e\x97\x36\x39\xe2\x6b\x55\xde\xa9\x29\x11\x79\xbd\xda"
+  "\x3c\x08\xfb\x4f\x33\x4f\x0a\x92\xf9\xb8\xcf\xcb\xbe\xf3\xc7\x28"
+  "\x3b\x7e\xea\x9b\xc7\xa1\x2f\x90\x67\xbe\x9e\x87\xe7\x4c\x38\x0f"
+  "\xc6\x3c\xe6\xac\x4a\xbe\x67\xf3\x9c\x84\xad\xad\x49\xcb\xf1\x91"
+  "\xbb\xb2\x87\xdc\xbe\x4e\x9e\xd3\x34\xab\xbd\x4b\x53\x6b\x4d\x01"
+  "\x4a\xec\x3b\x50\x85\xbe\x76\x6a\xed\xc0\x81\xaa\x4c\xe0\x86\x76"
+  "\x75\xef\x31\xd6\x81\x91\xb4\x5b\xb0\x20\xef\x91\x65\x4b\x26\xfe"
+  "\xf8\x91\x45\x2b\x16\xcc\xb0\xac\x58\xbb\xbe\xb8\x68\xe2\xc6\x17"
+  "\xca\x2d\x9b\x4b\xd7\x96\xaf\xdd\xf0\x13\xe9\xee\xd3\x52\x58\xae"
+  "\xde\x99\xeb\x0a\xcb\xca\x67\xf1\xcf\x09\x16\x5b\x69\xf1\x26\xf9"
+  "\xf3\xae\x91\x14\x0d\x64\x6d\x79\x71\xa9\x65\x7c\xd1\x04\xcb\x83"
+  "\x85\x6b\xd7\xbd\x50\x5a\x1c\x17\xd6\x0c\x4b\x69\x71\x69\x71\x61"
+  "\x91\x65\x96\xc5\xca\x90\x23\xc1\x45\xf0\xd3\xaa\xeb\xa7\x32\xf4"
+  "\xe7\xb0\xa1\xe5\x5c\x09\xf7\xeb\xdd\xf4\xc3\xed\x6c\xc3\x49\xff"
+  "\x9c\x90\x43\xf4\x09\x1e\xbf\x73\x5a\xe5\xb5\xfd\xf8\x34\x57\xb4"
+  "\xfc\x4e\x6b\x8c\x96\xdf\x69\x47\xae\xed\xc7\xa7\xc5\xb4\xff\x69"
+  "\x31\xed\x7f\x5a\xd7\xb5\xfd\xf8\xb4\x40\x74\x9e\xfb\x12\xa3\xf3"
+  "\xdc\x97\x3e\xa8\x67\x80\xeb\x4e\xa9\x97\xee\x9b\x10\x93\x67\x66"
+  "\x4c\x9e\xdc\x98\xef\x82\x88\x6f\xd8\xae\xf7\xad\x8b\xb4\x0d\xf0"
+  "\x5d\xa9\xb7\xf5\xb0\x7e\xbb\xcf\xa5\xa7\xe1\xbe\xa7\x81\xef\x01"
+  "\x52\x69\x9b\x23\xd2\xf6\x68\x69\x07\xdb\x3f\xeb\x24\xde\xb3\xa8"
+  "\xec\xf3\x1f\x4e\xd4\x74\x1b\xdf\x0b\xa4\xf7\xa1\x5d\xe0\xc5\xed"
+  "\x17\xe9\xbe\x37\x1b\x54\x5a\x2f\xef\x63\x15\x6f\xac\xf4\x37\xa4"
+  "\x51\x22\xe7\x65\xff\x94\xc2\x39\xb5\x89\x7d\x27\x22\x2c\x09\x0f"
+  "\xf4\xd4\x0f\x2d\x1e\xf3\x3d\xd2\xa7\x3e\xef\x69\xf0\xd0\x0f\xa5"
+  "\x2c\x73\xbe\x5d\x72\xef\x9d\x2c\xef\x4d\xbe\xdf\x88\x7d\xbe\xb2"
+  "\xfe\xe4\x72\xd9\x6f\x2a\x97\x0d\x18\x66\x61\x9c\xfa\xa9\xe6\xff"
+  "\x32\x05\xcf\x18\xc0\x2c\xd7\x61\x02\x9e\x85\x94\x9f\x5d\xb9\x4f"
+  "\x5d\xd9\x3d\x3f\xac\xd1\xed\x0b\x1e\x2b\xc4\xd3\x1d\xf1\xf7\x24"
+  "\x53\xf2\x7e\x67\xa8\xb3\xb5\xaa\x8b\x71\x6a\x63\x3b\xd4\x9d\x1e"
+  "\xa4\x8e\xba\x20\xc6\xaf\x94\x22\xc7\x53\x15\x17\xc8\xdd\x18\x24"
+  "\x9e\x1f\x5e\x5d\x41\x8e\x06\x63\xa8\x53\x0c\xe6\xe3\x31\xda\x0f"
+  "\xe5\x9e\xff\x5d\x1c\x8e\xfc\x18\x4b\x78\x79\xef\xf2\x50\x77\x6c"
+  "\x71\xba\xd6\x3b\x78\xbc\x37\x7d\xaa\x66\xfb\xee\x6e\x00\xac\xb8"
+  "\xfb\x6a\x8d\xe4\xf6\x3b\xa7\xa3\xff\x5b\xdd\xa9\xeb\xec\xe3\xb5"
+  "\x52\xf7\x19\x11\xbe\x1b\xb4\x68\x19\xca\x4e\xd1\xf4\xbb\x8d\xf7"
+  "\x7a\x21\xed\xd1\xeb\xa5\x65\xbc\x8f\xa3\xde\x68\x8b\x6b\xde\xad"
+  "\xb2\x26\x68\xfa\x35\x11\xf9\x7a\xf5\x7c\x5f\xa5\x7e\xda\x19\x02"
+  "\x2f\xda\xaa\x4f\x8d\x15\x67\x14\xbe\x26\xf7\xea\xde\x0f\xfb\x6f"
+  "\xba\xde\x0e\x6e\xc0\x37\xf4\xdf\x74\x39\x9f\xc8\xfb\x6a\x78\x4c"
+  "\x5d\x66\x83\xcd\x96\xee\x83\x6e\xbc\x7f\x8d\x1e\x27\xe7\x89\x38"
+  "\xae\x52\x04\x8e\xa7\x77\x71\x5c\xe5\x60\x1c\xe7\x63\xbc\x2b\x82"
+  "\x1c\x5e\xa3\x87\xab\xbe\xe5\xfe\xa6\x98\xef\xa3\xfa\x37\x7e\xb7"
+  "\xe2\xf7\xe0\x3e\x7d\xe8\x5c\xde\xe3\x64\x38\x47\x33\xc6\xd5\xcb"
+  "\x76\x73\xbf\x47\x8f\x97\x73\x6a\xef\xf0\xda\x98\x8f\x42\x69\xb3"
+  "\xd7\x48\x9b\x0b\x79\xf8\xbe\x2c\x8c\x31\x0c\xa2\x5f\xee\xb7\xea"
+  "\x65\x38\xdc\x66\xe4\x9d\x35\xf8\x3e\x47\xf7\xb3\xcf\x79\x2f\xcb"
+  "\xc8\xe6\x20\x8d\xb5\x3d\xc0\xf3\xcf\x33\xa4\xdc\x72\x18\xc3\x65"
+  "\x78\xdc\x27\x32\x6c\x86\xc7\xf7\x7a\x89\xbe\x12\xe0\x3a\x83\xeb"
+  "\x5f\x33\x14\xaf\x10\xef\x88\xa0\x65\x02\xbe\x5d\xd1\x75\x9d\xd1"
+  "\x18\xf3\x7d\x44\xff\xe6\xb9\x5e\x25\x7b\x33\x9a\xb4\xb8\x13\xd7"
+  "\x2b\x8b\xc7\xbf\x48\xe3\x8d\x2e\xef\x47\x14\x0d\xff\x47\x29\x31"
+  "\xdf\x16\xfd\xbb\x46\xae\x31\xfc\xc8\xaa\x97\x21\x79\x06\x19\x6b"
+  "\xaa\xf2\x26\x5c\xcf\x9f\x2b\xf2\x14\x45\x94\x39\x0c\xdf\xe5\x61"
+  "\xfe\xfd\xc8\xa1\xc3\xc3\xef\x3d\x11\xe9\x60\x97\xfc\xa8\x4e\x4f"
+  "\xa7\xd6\x37\x7e\x74\x38\x22\x5f\xcb\x97\xd4\x35\x46\x76\x67\x25"
+  "\x28\xd9\xfd\x91\x37\x1a\x97\x99\x14\x86\x39\x33\x29\x8c\xcb\xcc"
+  "\xf4\x88\x74\x68\x9f\x33\x33\x63\x65\xb5\xac\x82\x65\x9c\xe5\x75"
+  "\xe6\xfc\x38\x71\x01\x2d\x6e\x4d\x7c\x19\x9f\x59\x11\x11\xae\x8d"
+  "\x8f\x66\xfe\x49\xb3\x13\x58\x3f\xfb\xf8\xce\x32\xcd\x6f\xba\x94"
+  "\x49\xf6\xa7\xac\xdd\xa3\x04\xb9\x9e\xd9\x12\x0b\x97\xef\xbe\x19"
+  "\x84\x11\x86\xb9\x5b\xd9\x78\x33\x7b\x22\xea\xe6\xf3\xd0\x0c\x7d"
+  "\x9d\xc8\xab\xe6\x06\x7f\xd4\x35\xd4\xb8\xc3\xef\x9c\x95\x11\x4d"
+  "\xb3\x59\x53\xc3\x34\x9b\x95\x1d\x86\x3b\x2b\x37\x22\xdd\x3f\xe1"
+  "\xbb\x20\x22\x5d\xc9\x97\xc9\xa6\x92\x95\x59\xae\x98\xb2\x1a\x23"
+  "\x60\x1c\x8e\x28\xab\x25\x22\x5d\x27\xbe\xdb\x87\xe6\xcf\xac\xae"
+  "\xa1\xf9\xf3\x00\xc5\xe7\xcf\x03\xe9\xe1\x72\x1f\xc8\xf8\xf2\x76"
+  "\xf5\x40\x4e\x04\x3e\x0d\xf8\xce\x8f\x6e\x47\x0f\x94\xc4\x7c\x0f"
+  "\xf2\x5f\x40\x77\x34\x6d\xcd\x4e\xe0\xf0\xf2\x71\x94\xa2\xda\xd9"
+  "\x03\xb5\x91\xf1\x1f\x5e\x55\xf1\x8c\xa3\x5c\x83\xe3\xf5\x4d\x95"
+  "\xae\x35\x36\x1d\xa7\x89\x88\xf7\xe8\xb8\xef\x1a\xc2\xc7\xb7\xde"
+  "\xff\xb9\x43\xdc\xff\x3d\x10\x54\xeb\x36\xd9\x35\xc2\xf9\x51\xfe"
+  "\x50\x7d\x99\xdf\x39\x7b\x3a\xc6\x0c\x5e\x45\x9f\xd9\x90\xff\xc7"
+  "\xa4\x6d\x22\x5c\xd9\x35\x90\xa7\xab\xdd\x34\xfb\x4f\x78\xf7\xe3"
+  "\xfd\xbb\xe8\xfe\x75\x76\x81\x70\x1a\x96\x37\x38\x63\xfb\xdd\xd9"
+  "\xe5\x18\x7b\x5c\x4d\x0e\x3a\xf2\xe3\xc4\xb9\x84\xd3\xf4\x48\x9c"
+  "\x70\xf6\xa1\x7f\xd5\x43\xb3\xcf\x30\xbe\x11\xe1\xad\xc2\x39\x7a"
+  "\x05\xa7\xf7\x70\x79\xc8\x33\x14\xdf\xf4\xf3\x3f\x4a\xf6\xb2\x93"
+  "\x62\xea\x71\xa5\x9b\xb2\x5f\x51\xf5\xc8\xfe\x24\xba\xec\xec\x8c"
+  "\xf8\xf5\xc8\x9e\x89\x7a\x5c\x89\x5f\x8f\x6c\xe9\xa7\x5e\x18\x51"
+  "\x97\x6b\xec\x8e\xec\x72\xd4\xe5\x8a\xa4\x7b\x74\xf8\x1e\x7d\x9c"
+  "\x6a\xbf\x82\xf1\xbf\x91\x64\xde\xe5\x95\x61\xbe\x69\xe9\x8e\x26"
+  "\xd7\x52\x5e\x9c\x32\x4f\x08\xe7\xf0\xe5\x1e\x9a\x63\xd6\xfb\x2b"
+  "\x2d\xbc\x4b\xe1\x02\x3a\x19\x99\x4e\xa8\x0f\xf2\x0d\xc5\x6f\xbd"
+  "\x7d\xaa\x75\xa6\x39\x68\xff\xb3\x7b\xf4\x3e\x1d\xfd\xb9\x57\xa7"
+  "\x23\xe2\xf2\x62\xe2\x02\x11\x71\xeb\xa2\xe2\xb6\x0f\x86\xef\xd2"
+  "\xc3\xbf\x1a\x9f\xe6\x1c\x8d\xe1\x13\xf8\x33\x77\x41\x74\xbd\xe7"
+  "\xb4\xa9\xfa\x81\x47\xd7\xd0\x7a\x8e\x07\x3c\xea\x8f\xcf\xa3\x39"
+  "\xc1\xf8\xb2\x36\x77\x8c\x84\x97\x46\x71\xe0\xcd\xe5\x33\x63\xfd"
+  "\x52\x06\x35\x3e\x5d\xcb\x9f\xb9\x2b\x74\xfe\x7c\xb5\x3a\xce\xad"
+  "\x8d\xa9\xe3\x40\x37\xcd\xbb\x49\xd5\x75\x5e\x71\x0c\xec\x23\xf1"
+  "\x65\x71\x6e\x3b\xea\x39\x10\xbf\x9e\x73\xbb\x86\x96\xc5\x79\xbc"
+  "\x1e\x32\x70\xad\x2c\xce\x4b\x57\x79\x28\x5e\x9e\xa9\xc2\x19\xaf"
+  "\x9c\x79\xb9\x6c\x17\x79\x68\xde\x2e\x5e\xa7\x8b\x08\x2f\x8a\x96"
+  "\x3f\xd4\x81\xf3\x31\xfd\x82\x6a\x1c\xc3\x7c\xe8\xb6\x90\xf1\xcb"
+  "\x64\xd2\xef\x9c\xd7\x16\x43\xab\xcf\xba\x69\xfe\x82\x3e\xa3\xf1"
+  "\x41\x45\xaf\x05\x23\x62\x70\xf2\xc4\xa7\xd7\xbc\x00\xe8\xf5\x59"
+  "\x7c\x7a\xcd\x1f\x33\x34\xbd\xe6\x33\xff\x3f\xbb\x96\x5e\xf3\x73"
+  "\x22\xe9\xc5\x77\xad\x72\xfd\xbe\x9f\x0e\xd9\xe8\x5f\x2d\x1a\x94"
+  "\x2e\x4f\x49\x86\xac\xa8\x3c\xbd\x9c\xa7\x32\x39\xa0\xe4\xc4\x72"
+  "\x1b\x25\x5e\xa4\xf9\x45\x7a\xfb\x1f\x5d\x4b\xc3\x45\xff\x4a\xde"
+  "\xab\xcd\x77\x37\xa4\xb8\x2b\x3e\x6b\xe5\x3b\x1e\x79\xbe\x31\xa6"
+  "\xdc\xd6\xf8\xba\x60\x3e\x6c\x7e\x53\x75\x9c\x70\xaf\x9a\x33\x5d"
+  "\x90\x19\xad\x23\x16\x24\x46\xf3\x08\x74\x33\x4a\x2f\xe5\x86\xaf"
+  "\xf2\x5c\x9f\x67\x0b\x2a\xae\xe5\xd9\x83\xb7\x6a\xfc\xba\x12\x8d"
+  "\xdf\x02\x57\x7c\x7e\x2d\x68\x1e\x9a\x5f\x0b\xda\x86\xe6\xd7\x02"
+  "\x0f\xf3\xcb\x43\x0f\xa6\x47\xf7\x1b\x0b\x02\xd1\xf5\x45\xb9\xc8"
+  "\x27\x8c\xc3\x6e\xe4\xef\xaf\x5a\x6f\xfd\x61\x1d\xc7\xbc\x6a\x80"
+  "\x7d\x05\xfc\xc7\x31\x8e\x5f\x17\xc6\x90\xb0\x41\x43\xd7\xd6\x21"
+  "\xef\x03\x49\xea\xc0\xb8\x92\xf7\xe7\xc9\x7b\x99\xe9\xc1\x0b\x21"
+  "\xa3\x61\x06\x7e\x1b\xbb\x29\xe7\xd7\x21\xa3\xc9\xc1\x7b\xc9\xe4"
+  "\xf9\x39\xb9\x3e\xb1\xd0\x1c\xc9\x0b\xde\x53\xc6\x73\xd1\xfb\xd4"
+  "\x3c\xe7\x5f\xba\x69\xe1\x5e\xc5\x97\x9c\x37\xa3\xe9\xb8\x30\x33"
+  "\x3e\x5f\x16\x66\x83\x2f\x7f\x89\xcf\x97\x85\x05\x43\xf3\x65\x21"
+  "\xef\x55\xf8\xcb\xb5\xed\x68\xa1\x4b\x6b\x47\x3b\x39\x8f\x65\x03"
+  "\xdb\xab\x39\xfc\x9d\x8c\xdf\x68\x23\x0b\x3f\xe5\xf8\x89\xbd\x7a"
+  "\x3b\x92\x79\x78\xfc\x2f\xcb\xd7\xd2\xb4\x6a\x30\x22\xe1\xf6\x24"
+  "\xf7\xc6\x6b\x27\x39\x72\xcf\x40\x96\x8d\x12\x41\xc3\xfc\x43\x0c"
+  "\xa3\x94\xe8\x22\xe5\x3c\xca\xe9\x38\x9c\xef\x56\x88\x48\x6f\xd5"
+  "\xd3\xc9\x79\x51\x95\x36\x93\xef\x02\xe7\x74\x31\xb0\xb5\xfa\x0f"
+  "\x97\xfd\x08\xa7\x97\x77\x8f\x47\xa7\x71\xa8\xf6\x98\xd3\x16\xdd"
+  "\x1e\x73\x6a\xa3\xe5\x73\x21\xaf\x4f\x24\x87\xa0\xe7\x20\xcb\xbd"
+  "\x03\x4e\xc3\x8c\x6f\xa6\x6d\x2e\x1a\x13\xd3\x36\x21\x03\x8b\xfe"
+  "\x5e\xc9\xc0\xa2\xd7\xa3\x71\x5d\x34\x21\xbe\x0c\x2c\x9a\x3f\xb4"
+  "\x0c\x2c\x5a\x33\xb4\x0c\x2c\xaa\x64\x19\xf0\xd0\xa2\xa3\xd1\x6d"
+  "\x73\x51\x4d\x74\xdd\x51\xae\x6c\x9b\x94\xfa\x75\xda\x26\x6c\xa1"
+  "\x1b\x87\x6a\x87\x9a\xfd\x6f\xe0\xfb\xd1\xbe\x06\xcd\xd4\x7d\x3f"
+  "\xf4\x50\x0e\xaf\x21\x41\xc7\x97\x30\x0d\xeb\xe5\x18\xed\xa1\x82"
+  "\x48\x3a\xee\x53\x63\x2d\x3b\xd2\x9e\xe5\x3d\x7b\x8a\x9e\x8b\xdf"
+  "\x8f\xae\xff\x43\x95\xf1\xe9\xf9\x50\x0d\xe8\x69\x8f\x4f\xcf\x87"
+  "\x8e\x0c\x4d\xcf\x87\x4e\xf0\x19\xed\x6b\xdb\xd4\x43\x5d\x7c\xf7"
+  "\xa5\xde\x37\x5d\xa4\xc5\xb3\xbe\x5a\xff\xb4\x78\x6c\x74\xff\xb4"
+  "\xd8\xfc\xf5\xfb\xa7\xc5\x6b\xe2\xf7\x4f\x8b\x2b\xe2\xf7\x4f\x8b"
+  "\x5d\xaa\x3d\x2c\x6e\x8f\x6e\x0f\x8b\x9b\xa3\x65\x02\xb4\xfb\xc6"
+  "\xfa\xa7\xdc\xf4\x98\x36\xb0\xbf\x9b\x72\xdf\x84\x4d\xf1\xa2\xe2"
+  "\xdb\x92\x27\xa3\x71\xcc\x9d\x1a\x9f\x6f\xb9\xb9\xe0\xdb\xfe\xf8"
+  "\x7c\xcb\x2d\x19\x9a\x6f\xb9\xbb\xc0\xb7\xfd\xd7\xf2\x2d\xb7\xee"
+  "\xeb\xdb\x14\xb9\xa7\xa2\x79\x96\xdb\xf2\xf5\x79\xb6\x64\x4c\x7c"
+  "\x9e\x2d\x99\x10\x9f\x67\x4b\xe6\x2b\x9e\x2d\xa9\x8c\xe6\xd9\x92"
+  "\x82\x68\x9e\x81\x6e\xdf\x18\xcf\x96\x9c\x88\xe1\xd9\xc6\x6e\x5a"
+  "\xba\x04\x3c\x3b\xa5\x78\xb6\x2c\x35\x06\xc7\x9e\xf8\x3c\x5b\x8a"
+  "\x01\x23\x6d\x8c\xcf\xb3\xa5\x63\x87\xe6\xd9\xd2\xe9\xe0\xd9\xc6"
+  "\x6b\x79\xb6\x34\xef\xeb\xf3\x6c\xe9\xae\x68\x9e\x2d\x5d\xf7\xf5"
+  "\x79\xb6\xb4\x3d\x3e\xcf\x96\x7a\xe2\xf3\x6c\x69\x40\xf1\x6c\x99"
+  "\x35\x9a\x67\xcb\x52\xa2\x79\x06\xba\xfd\x3b\x79\x06\xfe\xd4\xaa"
+  "\xfd\xba\xcb\x0e\xf4\xc9\x39\xed\x65\xbb\x3d\x94\x97\xa7\xd6\x04"
+  "\xf2\xa4\xec\x68\x3c\xfc\x10\x69\x2a\xaf\xed\xbb\x97\x35\x69\x61"
+  "\x3f\xbe\x96\x0f\xcb\x5a\xd1\xaf\xf6\xb6\x55\xca\x7d\x5d\x8a\x87"
+  "\x4c\x73\xa4\x53\x73\x64\xcb\x3c\x9c\x17\x3c\x16\xee\x40\x90\xb8"
+  "\x2f\x46\x7a\x1f\xc3\x61\x7f\x22\xd1\xb0\xf2\x92\xbe\x8e\x5d\x36"
+  "\xf4\x1e\xf3\xec\xda\xd6\xaa\x29\x80\xf7\xf0\x38\x25\xab\x79\xb1"
+  "\xf6\x6f\x03\xca\xba\xa4\xe4\xf4\x91\x98\x39\x93\xbc\x21\xec\xdf"
+  "\x3c\xb6\x7f\x1b\xe2\xcb\x69\xde\x75\xec\xdf\x3c\xb6\x7f\x1b\x22"
+  "\xc6\xab\x69\xab\x82\x9e\x98\xf1\xea\xc3\xe6\x64\x9f\x92\x1d\x69"
+  "\xc7\x1e\xc8\xae\xf5\x3b\x1f\x9e\x10\x83\x33\x78\xf3\xf0\xfb\x1a"
+  "\xce\xef\xc4\xe4\x9f\x1f\x1f\xe7\x87\x0b\x80\xf3\x87\xf1\x71\x7e"
+  "\xb8\x62\x68\x9c\x1f\xae\x01\xce\x1f\x5e\xdb\xb6\x1e\x3e\xac\xc9"
+  "\x41\x9c\x71\xf9\xc3\xed\xf1\xf9\xff\x70\x0c\xff\x29\xbf\xbc\x52"
+  "\x78\x65\xfe\xa8\x74\x8f\x24\x46\xa6\xe3\xbd\xfa\x9c\x96\x65\x24"
+  "\x4e\xda\xa9\xb1\x30\x87\x48\x57\x70\x8d\xec\xf1\xd9\x82\xb8\xb2"
+  "\xf7\xc8\x6e\xd5\x1e\x1f\xf1\x44\xb7\xc7\x47\x1a\xa3\xdb\x23\x68"
+  "\x1d\x9d\xaf\x35\x3a\x3e\xcf\xf5\xcd\xe9\xd8\xe5\xd6\x18\x19\xf8"
+  "\xa8\x9b\x96\xff\x4a\xc9\xc0\x8a\x84\x68\x3c\x96\xe7\xc4\x97\x81"
+  "\xe5\x6b\x50\xff\x8f\xe2\xcb\xc0\xf2\xca\xa1\x65\x60\x39\x9f\x9d"
+  "\xfa\x28\x52\x6e\x97\x57\x66\x0f\x8f\x49\x73\x2c\xbe\xce\x5b\x7e"
+  "\x3a\xfe\xbc\xce\xf2\x5e\x45\xe3\x15\x19\xd1\x34\x5e\x61\x8e\xa6"
+  "\xe1\xf2\x9c\x6f\x80\x86\x83\x7e\xbd\xfc\xce\x15\xb1\xed\xdf\x8d"
+  "\x32\xb5\xf6\xff\xe8\x85\x68\x1c\x57\x68\xe3\x9f\x78\x73\x59\x2b"
+  "\x0e\x83\x96\xee\xf8\xb4\x5c\xd1\x1e\xbf\xce\x2b\x3c\xe8\x83\xdc"
+  "\xa1\x6b\xda\xd2\x8a\x00\xc2\x97\xcb\x3b\x1b\xaf\x50\x4a\x3d\xc2"
+  "\x97\x07\x29\x51\xf6\x57\x83\xfd\xd2\xa3\x7c\xee\x40\xc8\x39\x66"
+  "\xc8\x6f\xf2\x58\xca\xe3\x3e\x88\xf1\x5a\x5d\x19\xbb\x26\xfa\xa8"
+  "\x9c\xff\xe0\x7d\x2c\x7c\xae\x26\xb9\x82\xf2\xdc\xbe\x20\xe9\xf2"
+  "\xce\xe9\x63\x60\x57\x70\xbb\xe0\xf4\x7a\x5a\x35\xd7\xe9\x88\xd1"
+  "\x4d\x8f\x36\xc6\xe7\xf1\xa3\x2d\x43\xcb\xce\xa3\xa7\x15\x9f\x1f"
+  "\x4b\x8c\xe6\xf3\xa3\xbd\x21\xe7\xe8\x15\x5c\x57\xc8\xc0\xd7\x6a"
+  "\x27\xbc\x76\x3a\xa4\xbe\xdf\xb9\xb2\xd3\x56\x45\xdf\x3b\x4f\x8f"
+  "\xd9\x64\x79\x46\x11\x48\xde\x61\xa0\x36\xa9\x03\x1e\x93\xf7\x05"
+  "\x73\x9a\xd5\x41\x32\x8a\x9d\xcf\x75\x72\x5c\x83\x53\x04\xe4\x9d"
+  "\x94\x4e\x71\x8a\xfd\xf1\x40\x16\x6e\x3c\x47\x8f\xbd\x12\x95\x1f"
+  "\x52\xe9\x56\x30\xda\xd4\xfc\xfe\x63\xad\xfa\x3c\xfc\x50\xf3\xfb"
+  "\x48\xd3\xa5\xef\xfb\x55\x6b\x61\x8f\x75\x0e\xd9\x2f\x03\x27\x3e"
+  "\x43\xce\x38\x5d\x5f\x0f\xfc\x78\xba\x2e\xbf\x6a\x6d\xee\xc7\x39"
+  "\xe1\xb3\x2d\x3f\x5e\x81\xb8\xe0\x75\xe6\x73\x23\xda\xc1\x8f\x1d"
+  "\x91\x70\x94\x6f\xbb\x1f\xd7\xe8\xe7\x53\xf0\xbb\xf1\x4b\x60\xe9"
+  "\xf8\xb4\xc7\xe0\x03\x7e\x2e\x0e\x6a\x30\xba\xbe\x04\xc6\x18\x77"
+  "\xd3\x0c\xca\x0a\x91\xe9\x3c\x3d\x31\xb9\x86\xf7\xe8\xd4\xf5\x50"
+  "\x52\x90\xcc\x6a\x6c\x97\x7f\x3f\x9f\x0d\xe1\xb1\xa1\x3b\x38\xbb"
+  "\x95\xd7\xe0\xe4\x1e\x82\xf4\xd9\xad\x27\x2b\x06\x34\xdf\x63\xf9"
+  "\x8b\x98\xa6\x27\x4b\x3e\x6b\xad\x3b\x28\x7a\x0e\x49\x9f\x53\xf9"
+  "\x51\xe3\xbf\x3d\xbc\xff\x87\xf7\x61\x54\xd1\x6c\xa4\x3f\xab\xda"
+  "\xfa\x13\x31\x36\x69\xfe\x10\xe3\xbf\x7c\x1e\xff\xcd\x8e\xdf\xce"
+  "\xf3\xaf\x33\xfe\xcb\xe7\xf1\xdf\xec\xc8\x7e\x53\xad\xf3\xe4\x77"
+  "\x45\xda\xa4\xec\x17\xca\xf2\x0c\xdb\x99\x8f\x3f\x7e\x4f\x0d\xa5"
+  "\x04\x79\x4d\x1b\x6d\xd3\xdd\xd3\xc6\xed\x35\xe5\xa4\xb7\x85\xfd"
+  "\x31\x24\xf2\x5d\xda\xaa\x2f\xe3\xf6\xfa\xb8\x9c\x2f\x4c\x0e\xaa"
+  "\xb6\x68\xaf\x10\xde\x09\x5d\x90\xa1\x8d\x25\x3a\xac\x31\xdb\x4b"
+  "\xd4\xb9\x8f\xd1\x5d\x34\xdc\xdd\x23\xfb\x45\x03\xdb\xab\xd2\x6e"
+  "\x0d\x5e\x22\x86\x7b\xbc\xf2\x24\x31\xdc\xd0\x60\x3f\x29\x61\xef"
+  "\xe2\x36\xce\x30\x19\x76\x07\xd2\x31\x5c\x4e\xa7\xd7\x43\x9d\x8d"
+  "\x79\xfc\x70\x64\xdd\xe5\xfc\x0b\xca\x46\xf8\xa7\x3c\xaf\xe2\xe6"
+  "\x7c\xf6\x95\x22\xab\x8b\xd7\xcc\x3e\x6b\x15\xf6\xe7\x44\x56\x29"
+  "\xcf\x89\x3d\x71\x3f\xe7\xfb\xf0\xcf\x9e\x84\xf2\x71\x94\xa8\xc2"
+  "\x1e\xf7\xb5\x59\x02\xe4\xa1\x27\xa6\x47\xeb\x88\x27\x62\xec\xdf"
+  "\x7c\x39\xce\xc4\x3b\x89\xf7\x27\x6a\xfb\x57\x59\x1f\x08\x77\xd0"
+  "\x2f\xe5\xe3\x7a\x7b\x2a\x78\x4d\x9a\xf7\x44\x29\xbf\x67\x4f\x38"
+  "\x62\xe6\xde\xbc\xfb\xe4\xbe\x9a\x3f\xa2\xdc\x95\xa3\x94\x8c\x14"
+  "\x8c\x8a\xe6\xe9\x13\x8d\xf6\x0b\xbc\x16\xa4\xfa\x83\x55\xc1\x58"
+  "\xfd\xf8\x44\xab\x6e\xbb\xc5\x84\x77\xea\xfd\x81\x65\x03\xc3\x5d"
+  "\x19\xd3\xcf\x3c\x21\xed\xff\x81\x6b\xfa\x85\x95\x7c\x8e\x2a\x4a"
+  "\x26\x3b\xa4\x0c\xad\xcc\x3c\xe9\x83\xdc\x94\xb2\xfc\xaf\x7c\x07"
+  "\x69\x76\xf0\x99\x43\x7c\x0f\xbf\x48\x2b\xf3\x07\x9c\x94\x78\xd2"
+  "\x2b\xcf\x54\xa5\x40\x46\xa4\xdc\x72\xbf\x31\x49\xed\x47\xf2\xc5"
+  "\x94\x51\xae\xd3\x9c\xd3\x74\x94\xfe\x91\xd4\x7e\x0a\x96\x85\x95"
+  "\x39\xbc\x37\x63\x74\x2f\x0d\x67\x58\xba\x0c\xb9\x83\x9d\xd4\x11"
+  "\x8c\x1d\xf3\xac\x3c\x16\xbf\xee\x2b\xb9\xff\xaf\xf6\x50\xc1\x84"
+  "\x68\xde\xae\x94\xfd\xbf\xbe\xae\x03\xde\x07\xa2\xf3\x15\x24\x45"
+  "\xf3\xfe\x89\x46\x8e\x1f\x72\x8f\x8f\x2b\xbb\x0e\xe3\x99\xd5\x3e"
+  "\xb9\xdf\xab\x00\xed\xff\x89\x82\xeb\xe9\x41\x91\x92\x5d\x17\x42"
+  "\x5a\x6d\x5f\x30\xf4\x56\x81\x2b\x6a\xce\xe8\x66\x39\x67\xb4\xba"
+  "\x9b\x9e\xd4\xd6\x7e\x9e\xfc\x38\x06\xbf\xc3\x43\xdb\x06\x05\xbc"
+  "\xfe\xb3\x3a\xbe\xce\x28\xe8\x8a\x6f\x1b\x14\x04\x35\xbd\xb0\x5a"
+  "\xa4\xc6\xca\xc1\x93\xe9\xe0\xb1\xcc\xa3\x8f\x61\x79\x2e\x74\xe8"
+  "\x31\xec\x93\x39\x83\x63\xd8\x52\xd6\x07\x4f\x5a\x07\xc7\xb0\xde"
+  "\x78\x63\x58\x4f\x1c\x7e\x3e\xb9\x27\x3e\x3f\x9f\x6c\x8a\x3f\x86"
+  "\x7d\xf2\x98\xea\xe7\x9f\xf4\x46\xf3\xf9\xc9\xd3\xe1\x35\xe1\x82"
+  "\xc3\xdf\x9c\x3d\xbc\x2a\xfb\x5a\x7b\x78\xd5\x6f\x14\xaf\x56\x0d"
+  "\x44\xe3\xb6\x2a\x3f\xbe\x6e\x5f\x65\x1b\xda\x1e\x5e\xb5\x67\x68"
+  "\xdd\xbe\xaa\xf9\x5a\x7b\xd8\x32\x2c\x26\xcd\x89\x41\x5b\x29\xca"
+  "\x36\x5b\xd5\xa5\xe8\xb4\x9a\xed\x39\x53\x44\xfa\x60\xb4\xbc\x03"
+  "\x67\xc0\x83\x6e\x3b\xcf\x3a\x4d\x97\x99\xa1\x68\xc2\xbe\x99\xbe"
+  "\x5f\x43\x23\xd0\x06\x3e\xf2\x3b\x57\x0f\xca\x3f\xef\xe3\xe3\x72"
+  "\x58\x47\x0e\xb9\x9f\xce\xa8\xe3\xc7\x78\xac\xde\x75\xbd\xf5\x52"
+  "\x53\x3a\xe5\xbd\x76\x0d\x3d\x56\x4b\xfb\x8f\x61\x5c\x9f\x67\xab"
+  "\x7d\x31\x6d\xcc\xa7\xf6\xe1\xae\xf9\x9d\xe2\xdb\x9a\x98\xb1\xec"
+  "\x9a\x14\x79\xa6\x6f\x48\x7d\xbb\xc6\x1a\x5f\x46\xd7\xe4\x0c\xea"
+  "\xdb\x52\x09\x77\x47\x4c\x7c\x89\xe2\xc1\x9a\xd6\x50\x6a\xe4\x5c"
+  "\xf7\x1a\x47\xb4\x4e\x5a\x53\x12\x93\x2f\x66\xfc\xb7\x86\x75\xe2"
+  "\x50\x7b\x1c\x62\xfa\x9b\x35\xde\xa1\xfb\x9b\xc2\xed\xaa\xfe\x4f"
+  "\xc5\xac\x2f\x17\xa6\x5c\xbf\xbf\x29\x1c\xa2\xfe\x85\x39\xd1\xfd"
+  "\xcd\x53\x31\x6b\xf4\x85\x25\xf1\xfb\x9b\x42\x87\xae\x67\x94\xde"
+  "\x28\xfc\xd7\xaf\xa6\x6f\x0a\x5b\xa2\xf5\x4d\x61\xe3\x97\xe9\x9b"
+  "\xe3\xd7\xe8\x9b\xc2\x60\x72\x5d\xbc\xba\x3c\x35\x26\xbe\xbe\x79"
+  "\x6a\x82\xe2\xe1\x53\xbb\xa2\xf5\xcd\x53\xf3\xa3\x79\x58\x18\xc3"
+  "\xc3\xa7\x62\xd6\xbf\x0b\x53\xfe\x57\x75\x92\xc9\x64\x32\x9a\x0c"
+  "\x46\x83\x89\xf8\xd2\x28\x03\x0d\x37\x99\x4d\x09\x78\x86\x69\xef"
+  "\xe1\x46\x93\xd1\x8c\x27\x41\x7b\x0f\x8b\xf9\x1e\xce\x79\xf1\x98"
+  "\xb5\x77\x42\xcc\xf7\xb0\x2f\x89\x1f\xae\x95\xab\x97\x6f\x8e\xf9"
+  "\x4e\xf8\x92\xf8\x61\xff\xce\xfc\x74\xcd\x77\xf4\x39\xc8\x45\x1b"
+  "\x36\x15\xae\x5b\x5b\x24\xf7\xb5\x17\x5b\x0a\x9f\x7e\xba\xb8\xac"
+  "\xcc\x52\xbe\xd1\x32\x77\xce\x23\x53\x66\x58\xd4\xf6\xf8\x75\xb3"
+  "\xc6\x17\x8d\xa4\x25\x9b\x4b\x39\x62\xc9\xf2\x45\xf9\x96\xbc\xb9"
+  "\x73\xa2\x23\x75\x30\x72\x1b\xfc\xf5\xa0\x44\xb4\xbd\xec\x57\x6e"
+  "\x26\xda\x73\xb3\xd4\x3b\x5d\x7c\xf6\x5c\x8d\x27\x4a\xfe\xe5\x44"
+  "\x13\xc6\x13\x57\xed\x82\xcf\x55\x9c\xa3\xa2\x17\xb9\x12\x13\x1b"
+  "\x1d\x64\x7b\x86\xfd\xa9\x14\xbd\x23\x7e\xeb\x25\xcb\x43\x64\x3c"
+  "\x47\xeb\xcf\xb6\x61\x14\xcd\xdf\xee\xae\x20\x59\xec\x6c\xdb\x96"
+  "\xec\x40\x9c\x41\x3c\x10\x42\x98\x4f\x3b\x9f\xff\x93\x03\x32\xec"
+  "\xb7\x0e\x3d\x5d\x72\x37\x15\x2f\x10\xbf\x15\xf2\x9b\xfd\xd6\xa8"
+  "\x74\xc5\xb7\x86\x9c\x4f\x77\xb2\x5e\xa8\xab\x26\x73\x7d\x35\xd1"
+  "\x9b\x69\x94\xf8\xe6\xcd\xec\x6b\xb6\x38\x49\xdf\x97\xfd\x0a\xbe"
+  "\x3d\xb4\xde\xc3\x65\x73\xda\x90\xb1\xc8\x28\xd3\xa7\x45\xa5\x9f"
+  "\x19\xde\xc7\x5d\x9c\x64\x44\xba\x65\x9f\x50\x72\x20\xed\xbe\x53"
+  "\xee\x4a\x07\x25\x0f\x88\xcf\xb3\x72\xc8\xd0\x81\x96\xb1\x25\x28"
+  "\x82\xad\xa5\xe7\xb9\xfc\x57\x92\xb7\x88\xcf\xdd\xb0\x1b\x97\xf4"
+  "\xda\xc5\xbe\x0b\x64\x46\x9b\x36\xb4\x96\xf2\x79\x8a\x62\x5b\xfd"
+  "\x15\x32\x83\x06\x63\xcf\xd3\x33\x8d\x95\x4b\xc4\x80\x7d\x09\x99"
+  "\xff\x6b\x05\x9f\x79\x9d\x73\x7e\xdf\x7f\x27\xf3\x07\x57\x1d\xc6"
+  "\xab\x22\x9d\x2a\xcb\x45\x8f\x60\x1f\xd4\x3e\x11\xe0\x3d\xb7\x27"
+  "\xd6\x0c\x70\x9a\x3f\xfa\xed\xe9\xd4\x51\xee\xa3\xed\x67\x44\x60"
+  "\xf7\x7f\x57\x3e\x2b\x4e\xf6\xfa\xf8\x0c\x6d\xe2\xf6\x25\x64\xea"
+  "\xce\x27\xe3\xc9\x92\x5a\x72\x17\xf8\xa8\xf2\x8c\xe8\x39\xb1\xe6"
+  "\x13\xea\x28\x39\x42\xab\x3b\xc9\x78\xa2\xeb\x4f\x24\xfd\x28\x57"
+  "\xbf\x7f\xaa\xea\x12\xa5\x6f\x5f\xcb\x61\x97\x68\xeb\x76\x1a\xb5"
+  "\xf5\x63\x1e\x0b\x75\xa2\x9c\x0b\xf4\xc4\x69\x32\x00\x9e\x71\xdb"
+  "\x9f\x28\x7d\xdb\xe3\x7c\xd6\x3c\x9b\xea\xaa\x88\xcf\xe4\x26\x5d"
+  "\xb5\x67\xa6\x5c\x15\x99\x69\x7e\x7b\xe6\x98\x0e\x1b\xd2\x77\xfd"
+  "\x86\x46\x77\xd2\x98\xdf\x9e\xef\x34\xd6\x7e\x41\x63\x2d\x4b\x99"
+  "\xff\xcf\xd4\xd5\x7d\x81\xf4\xd5\x76\x47\x08\x79\x23\xf3\x04\x53"
+  "\xed\xb5\xee\xfc\x00\x85\x00\xab\xf6\x2a\x8d\xad\xbb\x4a\xe9\xa1"
+  "\x03\x76\x07\xd3\xa2\xbf\xfa\x81\x53\xd0\x83\xc3\x3f\x7c\xaa\xc5"
+  "\xec\x3e\xd1\x4b\x27\x7d\x57\xa9\x83\xfe\x48\xee\x8a\xbf\xb6\x7e"
+  "\xf0\x54\x4b\x02\xec\x48\x43\xeb\x56\xde\xfb\xae\x64\xc6\x7e\x92"
+  "\xfd\xe7\x39\x68\x7f\x15\x25\xd9\xb6\xd2\xf0\xf3\x08\x97\x3a\xc7"
+  "\x35\xb9\xd3\x1d\xfc\x6b\xeb\x56\x79\x0e\x7c\xbd\xa7\xea\x24\x99"
+  "\x3a\x7c\xb5\x7c\xde\xd8\x38\x90\xf6\xfe\x29\xb7\xef\x14\xb9\x6d"
+  "\x7f\x69\x0d\xa5\xbc\xdf\xb2\x27\x44\x89\xbf\xba\x7c\xca\xe8\x36"
+  "\x5f\x26\x77\xbe\x8f\x3e\x42\xd9\xa2\xfa\xfd\x33\xd0\x55\xd9\x1d"
+  "\xbe\x00\xfb\xdd\xb1\x8a\xbe\xf4\x91\xfb\x4b\x69\x42\xfd\x17\x94"
+  "\x71\xe8\x0b\xca\x14\xfe\x4c\x23\x9f\xed\x66\x7f\x69\x87\xf0\x4e"
+  "\xc2\xd8\x0b\xf5\x95\x67\xbc\x45\xaa\x76\xc6\xbb\x3f\x93\x1a\xae"
+  "\x86\xcf\x78\x5f\xed\x0b\x9f\xf1\x86\x2c\xa5\xf0\x39\x6f\xb4\x8b"
+  "\x76\x96\xe7\xfd\x17\xc9\xbc\xf3\x22\x51\x96\xc3\x48\x96\xa7\xd8"
+  "\xd7\x47\xc9\x0b\xee\xa2\x0b\xf2\xf7\x39\x2a\x99\x80\x77\x12\x1e"
+  "\x8c\xdf\x4a\xc6\x71\xfd\xba\x34\xb9\x45\x98\x11\x61\x37\xe1\x6d"
+  "\xc2\x7b\x94\xbd\x4e\x78\x51\x06\xfb\x9c\x19\xc9\xf2\xab\x9d\x27"
+  "\x6f\xf6\x3b\x4b\xcc\x1e\x3a\x70\x4c\x97\x63\xa5\xcf\x8b\x53\x3e"
+  "\xea\xbe\xc0\x7e\xcd\xbd\x12\x9f\xfe\x12\x03\xfb\x38\xd7\xc2\x19"
+  "\x87\xf5\x5c\x2e\xca\xcf\xc3\x3b\x19\x0f\xda\xe5\x4f\xba\xf4\xbc"
+  "\x7d\xfd\x25\x5c\x66\x31\xc2\x85\x1e\x8e\xfa\x9a\x39\xee\xef\xba"
+  "\x2f\x18\x55\x9a\x4c\x23\x60\x06\x34\xf8\x68\xeb\x45\x47\xb9\x4d"
+  "\xf7\x19\x93\xc5\xf1\xa2\xa9\x54\x77\xb3\x38\x75\xe8\xa0\x68\x53"
+  "\x6d\xad\xa4\xd9\x43\xaf\xe9\x7e\xa0\xdb\xf6\x20\xee\xb8\x85\x88"
+  "\xe9\xd2\xb6\x86\xf7\x93\x96\xb4\x7b\xe8\x86\x8c\xc8\x3a\x08\xe7"
+  "\x53\x2d\xdc\x6f\xfe\x4d\x55\x6b\x82\x30\x3e\xdd\xd2\xe1\xe9\xa5"
+  "\x0f\xae\xf6\x24\xd8\xff\x99\x8c\xee\xe0\x39\x9a\x34\x86\xd2\x79"
+  "\x0e\xa6\xe1\xa0\xf0\xe0\xdd\x83\xa7\x17\x72\xf2\xdd\xf3\xb4\xf6"
+  "\xa6\x7b\xc6\xd0\x98\xff\x56\x41\x9a\x3e\x5a\x3b\x31\x42\x1f\xfd"
+  "\xfd\xc9\xae\x96\x08\x5d\xb4\xbe\xf8\x5a\x5d\xb4\xae\x50\xe9\x22"
+  "\x11\x54\xba\x67\xc0\xa3\x85\x2f\x89\x09\xd7\xce\xab\xac\x9b\x1c"
+  "\x13\x1e\xd0\xc2\xbf\x1b\x13\xee\x55\xe1\xcf\x3d\xa9\xeb\xba\x0e"
+  "\xc6\x63\x33\xeb\xba\xe7\xe6\xb0\xae\xeb\x28\xd2\x74\x9d\x3c\x8b"
+  "\xf9\xdc\x78\xf1\x33\x07\xb1\x1f\x9d\x6e\x7a\x76\x80\xf1\x17\xbf"
+  "\x25\x1d\xf7\x11\x08\xfb\x0d\x87\xb9\xfe\x48\x66\x3c\x52\xcf\x09"
+  "\x67\xd1\xed\xac\xe7\x58\xc7\xf1\x39\x98\xb7\x6f\x16\x9d\x6f\x1f"
+  "\x14\xa7\xeb\x0e\x8a\x13\x7e\xe7\xb3\x13\x74\x7d\xf7\x53\x84\xed"
+  "\x41\xd8\x4f\x11\xcf\x7a\x8f\x69\x72\x32\xbf\x85\xfd\x8a\x76\x09"
+  "\xd7\x9c\x9e\x64\x03\xd9\xf6\x41\xe6\xd9\xdf\xd5\x2e\xd0\xd7\x5d"
+  "\xee\x93\x67\x4e\xa4\x3f\x70\xa3\x15\x3a\xaa\x8b\xdb\xdb\xcd\x3b"
+  "\x43\x3c\x2f\xf1\x09\x55\xf9\xc4\x79\x3e\x9b\xc2\x38\xac\xde\xf2"
+  "\x10\xfb\xb7\x36\xb4\xc1\x3a\x62\x3f\x04\x7c\x76\x06\x7a\xd7\xec"
+  "\x02\x4e\xca\xbf\xef\xb3\x47\x61\xb9\x64\x2b\x5e\xaf\x97\xfe\xf3"
+  "\xcf\xd1\xda\x80\x70\x42\x17\xa2\x6e\xc9\x03\x0e\x62\x5f\x2c\x68"
+  "\xa3\x3c\xcf\x5a\xf2\x36\x1e\x97\xee\x8f\x85\xef\x52\x40\x1a\x77"
+  "\x67\x80\x18\x67\x0f\x3d\x3b\xff\x64\x65\x0b\xe7\xef\x61\xda\x08"
+  "\xa7\x5d\x87\x61\x90\xfe\x5c\x30\x86\x67\x7f\x2e\x48\xd7\xa9\xec"
+  "\x99\x07\x4e\x9d\x2c\xf0\x12\xeb\x79\x77\x0f\x60\x54\x9e\x53\x30"
+  "\x00\x4b\x40\xef\x47\xc5\x69\xf0\x47\x6d\x17\x9f\x03\xfe\x51\xe6"
+  "\x17\xfb\xe5\xe2\x7d\x49\xa0\x4b\x12\xfb\x66\x50\x76\xe7\xb3\xb3"
+  "\x1a\xfe\x48\xa4\xf9\x16\x83\xbc\x3d\x3b\x93\x7d\x77\xb1\x3f\x31"
+  "\xe9\x4b\xcc\x38\x95\xc4\xe6\xcc\xa4\x41\x7f\x62\xff\x01\xbe\xc4"
+  "\x40\xff\xf4\x7a\xa3\x38\x02\xfc\x67\xb2\x3f\x31\xe0\x5f\xc7\x72"
+  "\xa8\xd5\x29\xfb\xf5\x27\x24\xcd\x77\x71\xd8\x7e\xa7\x68\xd7\xf9"
+  "\xcf\xf5\xe5\xba\x20\xae\x44\xd9\x83\xe2\x94\x87\xd6\x65\x73\x3c"
+  "\xc2\x56\x70\xfa\x49\xd0\x63\xee\xa2\x01\xfa\xb0\x7b\xc0\xb8\x7f"
+  "\x2b\x99\x95\x4e\x5b\xff\x38\xe7\x57\x3a\x6d\x7d\x4a\x58\xa7\xad"
+  "\x4f\x50\x3a\x4d\xd1\x58\xe9\xb4\x75\x57\x94\x4e\x5b\xf7\xb9\xdc"
+  "\x3f\x04\x9d\xc6\x71\xac\xd7\x74\x9d\x76\xe8\x66\xd1\xce\xba\xc3"
+  "\xef\x5c\xe7\xd1\x75\xdb\x5e\x84\xb1\xee\x60\x1c\x95\x9e\x7a\x6e"
+  "\xba\xf8\x1f\x99\xa4\xf6\x67\xf2\xef\x12\xf6\x97\xd1\xa3\xfd\xe6"
+  "\x7e\xe4\x61\xa5\xe3\xd6\x4f\x0d\xeb\xb8\x75\x2d\xe1\xbc\xac\xe3"
+  "\xd6\x2f\x52\x3a\x4e\x85\x37\x3c\xc1\x3a\xee\xb9\xe9\x4c\x03\x0d"
+  "\xbe\x91\xd7\xcd\xb4\xf4\x4c\xc7\xec\x48\x1d\x17\xdd\xbe\xd6\xef"
+  "\xd1\x75\x1c\xeb\x36\x7c\xd7\x79\x68\xa4\xf4\x71\xce\xed\xac\x06"
+  "\x34\xd7\xdb\x1d\xf3\x80\xeb\xcc\x7e\xf2\x99\x6e\xf3\x2e\xd0\x70"
+  "\xcd\x4f\x8d\x56\xef\xf5\x9d\xfa\x99\x4c\xd0\xdf\x13\x6b\x33\xe3"
+  "\x7b\xd0\x4e\x03\xaf\x6f\x67\x1f\x8e\x6e\xc7\x39\x72\xd7\x0a\x47"
+  "\x47\xf0\x0c\x85\x76\x3e\x77\x96\xf9\x8a\xf1\xc5\x30\x7e\xb3\xde"
+  "\x39\x4f\x1b\x6e\x5d\xed\x93\xf3\xf5\x67\xf7\x1b\x11\x57\x41\x3f"
+  "\x8a\x88\x93\x67\xec\x23\xf2\x4d\x8c\x88\x7b\x98\xe3\x78\x8e\x11"
+  "\xbf\x69\xa8\x39\x85\xaf\x81\xc7\x3b\xd7\xc1\xe3\x37\xd7\xc1\xe3"
+  "\x5f\x25\x1e\xb0\xb7\x30\x3e\x4a\xbd\x48\x1b\xb4\xb3\x21\x78\xe2"
+  "\x96\xb3\x71\x84\x16\x6f\x8a\x88\x8f\x28\x6b\xe3\x5d\x71\xf2\x47"
+  "\x94\xb7\x71\xd1\x97\xc0\x5f\xfb\x25\xf0\x5f\xf9\x12\xf8\xef\xb3"
+  "\xee\xe3\x73\x7f\x03\xce\xe8\x74\x59\x41\xd9\xf6\xda\xd9\x77\x14"
+  "\xd2\xfd\x8b\xb6\xde\x72\xd6\x3e\x4e\x8e\xff\xa4\xbf\xa0\x7d\x88"
+  "\x97\x7e\x72\xa1\x97\xe7\x6f\x21\x52\x7b\xfa\xf4\x3c\xb6\x84\x58"
+  "\xdc\x46\x07\x75\xdc\x64\xfc\xf8\x58\xdc\x10\x3f\x31\x22\x7e\x41"
+  "\x98\xe7\x1b\x5b\xaf\x33\x8f\x94\xe4\xae\x25\x79\x77\xcc\x71\x0c"
+  "\x5b\xf8\xac\x4f\xcd\xe0\xda\x88\x0d\xf2\xbf\x5e\xae\xed\x68\xe7"
+  "\x8a\x7b\xa1\xd3\x6f\x67\x3f\xa0\x6c\xf3\x6a\x67\x41\x6e\x41\x3f"
+  "\x92\xc6\x7e\x62\x78\x3e\x7d\xf5\x40\x9e\xf1\x78\x25\xb7\x1d\x5b"
+  "\xa7\x9e\x77\xa8\xb9\x47\x2e\x57\x2b\x53\x9e\x93\xf2\x3b\x9f\x4f"
+  "\xd2\xf3\x30\x6c\x3e\x1b\x04\xfd\x7f\xbb\xf4\xbf\x16\xec\x65\x7d"
+  "\x7b\x0b\xec\xe3\x34\x55\xce\x1a\x52\xe5\x3c\x9f\xed\xa1\x0d\x15"
+  "\xd7\x3b\x87\x35\x74\xfd\x9e\xaf\xfc\xfa\xf5\x23\xad\x7e\xcf\xb7"
+  "\x7c\x49\xfd\xae\x57\xae\xef\xeb\x97\x9b\xa2\x95\x5b\x6a\xfd\xfa"
+  "\x74\x2d\x2d\xfa\xea\x74\xb5\x6a\x74\x2d\xad\xfd\x12\xba\xc6\x2b"
+  "\xe7\xc4\x57\x2f\xc7\xa2\x95\x53\x46\xf1\xca\x21\xf9\x37\xa4\x3f"
+  "\xa1\x44\xfd\xee\x16\xbe\xc7\x48\xdd\xd1\x50\x96\x13\x79\x47\x95"
+  "\xba\xdf\xa8\xac\x40\xbf\xa3\x2a\x7c\xce\xac\x6c\xcb\xea\x46\xb6"
+  "\x43\x44\xc8\x43\x65\x95\x3c\x17\x38\x7f\xbb\xf2\x5f\xa8\xe5\x71"
+  "\x7d\xc9\xdd\x58\x66\xf6\x0d\xcf\x65\x0b\x21\x7d\xc5\xf8\x94\x1f"
+  "\xc0\xb2\x7f\xe1\x33\x83\x6a\x4f\x91\x74\xfa\xc5\xb0\x30\x86\x2d"
+  "\x93\xfe\xdb\xd9\xb7\x7c\x9f\x5d\x4b\x7f\x1b\xf7\xa1\x7a\x9a\x72"
+  "\xd2\xd3\xc4\x9d\x93\xac\xae\xb2\x35\x55\x59\xa3\xce\x37\x2e\x28"
+  "\x2d\xdd\x58\x3a\xc3\x52\xb6\xfe\xa9\x89\x65\xe5\x85\xe5\x2f\x94"
+  "\xc9\x83\xf0\x23\x09\x01\x96\xf2\xb5\xeb\x8b\x37\xbe\x50\x9e\xb9"
+  "\xb9\x70\xad\x3a\x38\x7f\x17\x12\x46\x26\xa2\xa8\x3b\x4d\xd2\xa1"
+  "\x83\x4e\x09\xa3\xf4\x71\xd1\xcb\x75\x62\x5f\x27\xfa\xb9\xe0\xb6"
+  "\x74\x22\x1f\xc6\x47\xc0\xb1\xc9\x43\x3f\xf6\xea\x74\x64\xff\x8b"
+  "\xb0\x93\xd2\xcf\x53\xf9\xef\x98\xf7\xcb\x60\xf2\x36\x28\xbf\x15"
+  "\xd2\xf7\x80\xbb\x1c\x01\x1d\x94\xd8\xba\x89\xe7\x79\x5f\x98\x1e"
+  "\x72\x96\x67\x4a\x7f\x92\x5b\x79\xfc\xfd\xc2\x93\xba\x5d\xc2\xeb"
+  "\x56\x6a\x9d\xf9\xf6\xd9\xe7\xa8\x7c\x2f\x97\xcb\xed\xa6\x1e\xf6"
+  "\x2f\xc3\x12\xce\xf2\x6c\xb6\x81\xf1\x9d\xe8\x77\xbe\x90\xa9\xdb"
+  "\xbe\xc0\x37\x49\xa4\x56\xad\xf1\xd0\x0b\x05\xbf\x4f\xf1\x92\x76"
+  "\x96\x3c\xb1\x5e\x9d\x1b\x37\x23\xed\x8a\xc1\xb4\x4e\xf6\xad\x5c"
+  "\xb5\x86\xef\x3d\x8b\x4b\xdf\xb4\xc5\xcd\xa1\xfe\xfc\x84\xc8\x3a"
+  "\x63\xcc\x0e\xfe\x6c\x1a\x85\xba\x8f\x61\x5e\x6b\xfe\x4e\x86\x01"
+  "\xf7\x4b\xca\xbf\xf3\xe2\x66\x84\x0d\xc3\xbb\x95\x79\xca\x3e\x16"
+  "\x10\xc7\x7b\x7d\x0c\x1d\x95\x9f\xb5\x1e\x4f\x3f\x07\xb9\x7e\x81"
+  "\xe7\xae\x33\xd4\xb9\x38\xa4\x47\x19\x6e\xc7\x55\x6a\xb3\x88\x56"
+  "\x9e\x03\xf4\xd0\xa6\x8c\x36\x8b\x8f\x84\x69\xe5\x59\xce\x87\x76"
+  "\x91\x6e\xaf\x60\xdb\x07\xe1\xf2\xfc\xdf\xa6\x74\x9d\xe6\xe5\x16"
+  "\x71\x81\xd3\x0c\x35\x6f\xcd\x7d\xf0\x7e\xd9\x97\x7c\x41\xbc\xc7"
+  "\xab\x8b\x36\xcd\x8c\xd5\xf7\xe3\x8b\x66\x58\x8a\x0a\xcb\x2d\xeb"
+  "\xd6\x6e\x28\xb6\x14\xad\x2d\xb2\x6c\xd8\x58\x6e\xf9\xc9\x46\x9e"
+  "\x40\xe2\x29\xa3\x28\x99\x08\x71\xfd\x36\xe7\x27\xe8\x6b\xe4\x7d"
+  "\x9b\x4b\x86\xa1\xfe\xa0\xc9\xe6\xd7\xfb\xfc\x25\xc3\xa3\x69\xb2"
+  "\x59\xf3\xc5\xb5\x09\xe3\xbf\x17\xd6\xa9\xf3\x85\xa6\x1e\x7c\xa3"
+  "\xfe\x9b\xac\xd1\x6d\x6f\xf3\x1f\xb4\xb4\x3e\x3d\xad\x94\x8b\x3b"
+  "\xce\x0f\xc6\xed\xd7\xe4\xb1\x41\x9d\x83\x96\x7e\x75\x1a\xe4\x19"
+  "\x81\xcd\x99\x43\xe6\x61\x5f\x62\x5b\xe9\xe9\x8b\xb4\x39\x55\x38"
+  "\x37\x15\x68\x32\x94\x18\x72\x2d\x6e\xd1\xe4\x07\x32\xb1\xb9\xe4"
+  "\x5a\xf9\xd9\xdc\xc6\xf2\x23\xfc\xf9\x89\x72\x3f\x49\x30\x00\x3d"
+  "\x85\x6f\xf4\xa7\xc0\xfd\x04\xd7\xc3\xb7\x39\x3f\xd1\xfe\xa6\xec"
+  "\xaf\x3f\xe5\xb5\xd9\xe3\x01\xe9\x0b\x6a\x04\x64\x03\x3c\xda\x7c"
+  "\x4c\xe7\x91\x9e\x3e\x7e\x1b\x96\xf2\x12\x2d\x63\x92\x9e\x15\x37"
+  "\x49\x19\x83\x5d\x00\x9c\x8c\xba\x5d\xc0\x7d\x80\x87\x2a\x26\x94"
+  "\x6f\x17\xc2\xef\xac\xb0\x44\xc8\xc1\xc5\x78\x72\x00\xde\x3e\xbd"
+  "\x6e\xe3\xd3\xcf\xa1\xa1\x97\x16\x97\x3f\x5d\xc2\xbe\x33\x58\x0f"
+  "\x48\xc7\x1c\xe3\x8b\x2c\x2f\x94\x15\x3f\x3d\x92\xe2\xa5\x1a\x8c"
+  "\x8c\xe4\x7f\x4a\x08\xf2\xda\xd7\x97\x9f\xc0\x67\x38\xd4\x99\x8d"
+  "\x2d\x9f\xf4\x95\x61\xdc\x13\xc5\xf7\x2d\xff\xea\x4e\xb7\xc2\x4e"
+  "\xb4\x92\xb4\xf9\x41\x33\xb5\x0f\x61\xeb\x77\x99\x0e\x7d\x46\x03"
+  "\xfa\x83\x8a\x33\xba\x0c\xe0\x37\x64\x7b\xf3\xa9\xf0\x1e\x90\xad"
+  "\x63\xfb\x8c\x09\x67\x58\xff\xa8\xfd\x26\xe7\xa1\x07\x92\x1b\xce"
+  "\xd1\x96\x6c\xe6\x69\xbd\xec\x4f\xb6\x8c\xd5\xf3\xec\x1b\x3c\x47"
+  "\xbd\x65\x97\x2e\x27\x11\x79\x46\x71\x98\x1a\x3f\x57\x4c\x67\x9e"
+  "\x0b\xc5\x7b\xb3\x9e\x0e\x74\x15\x0d\x52\x8f\x6c\xb1\xc5\xea\x86"
+  "\xdf\xa7\xf0\x9a\xbb\xc2\x47\xca\x5f\xca\x62\x97\xf4\xcb\x02\x1b"
+  "\x0f\xb0\xb7\x6b\xfb\x5f\x4e\xc9\x3e\xbd\x02\xb0\x02\x0a\x16\xca"
+  "\x5a\xa5\x97\x25\x52\x17\xbb\x1a\xa4\x9c\x6d\x39\x15\x9e\x93\xdc"
+  "\x52\xc9\x63\x73\xd1\x97\x3f\x0c\xfc\x3c\x26\x65\x0b\xbf\xcb\x6f"
+  "\x55\x3e\xe2\x58\xde\xb8\x9e\x2c\x57\x61\x99\xda\x9a\xa2\xf3\x9b"
+  "\xeb\x8c\x7c\x6d\x16\xe9\x47\x78\x6b\xa6\x4e\xcb\xa1\x7c\xd9\xc8"
+  "\x76\x9b\x02\x5c\xfc\xaa\xed\xca\x71\xa5\xf2\x5f\xc4\xe7\x68\x4c"
+  "\xc0\xb1\xa5\x9b\xb6\xdd\xcf\x67\x03\x92\x03\x3c\x4e\x5b\xdc\xc2"
+  "\xbe\x19\xd4\x59\xf7\xad\xbb\x01\xbf\x32\x7c\xf6\x7d\x2b\xfa\xff"
+  "\x8a\x4a\xc5\xbb\xad\x4d\x11\x6d\xcf\xab\xed\x37\x18\xce\x34\x62"
+  "\x7d\xe6\xae\x58\x20\xdb\xab\x3a\x57\xbc\xf5\x94\x9e\x4f\xfa\x31"
+  "\x08\xaa\x3e\xf1\x22\x6d\xe5\x79\x1e\x2f\xe3\x07\x5a\xdb\xb8\x7c"
+  "\xae\x1f\xf7\xb9\x52\x6e\xd2\xf9\xae\x95\x6d\x49\xd1\x38\x6c\x1b"
+  "\xab\xc3\x52\xb0\xb7\x4d\xd0\xbf\xd9\xaf\x99\x87\x2a\x5b\xda\xc6"
+  "\xa2\x4d\xf9\x64\x1d\x6e\x68\x43\x97\xda\xe6\x93\xe9\x56\xe8\x34"
+  "\x44\xb8\x03\xdf\xb0\x7f\xca\x4b\xd4\x9a\x53\xd5\x1a\xa5\x8b\x2a"
+  "\x8f\xb2\xcf\x2c\xbb\x85\xfd\x1e\xce\x54\xfa\x46\xfa\xea\x91\x71"
+  "\xcf\x6b\x6d\x76\x04\x9f\x41\x92\xfb\x6e\x7c\x41\xa9\x1b\x94\x6f"
+  "\x07\xc4\xa3\x8d\xf8\xd5\x7d\x4f\x23\x34\xdc\xda\x07\xcb\x80\x4c"
+  "\xb4\xc9\x35\xce\x6d\x2d\xca\x57\xca\xf0\x53\x88\xef\xd1\xf9\xb7"
+  "\xeb\x20\xc2\x00\x13\xf9\x12\xdb\xa4\x2f\xb2\x4a\xb3\x8e\xaf\x16"
+  "\x67\x94\xf2\x20\x69\x50\x39\xd8\xfe\xfb\xd2\x64\x5a\xab\x5e\x8e"
+  "\x4c\x8b\x74\x9c\x9e\xef\xfc\x44\x5c\xee\x20\x1c\xe5\xa3\x25\x91"
+  "\xcb\x69\x6b\x94\x71\x25\x61\x5d\xb5\x4d\xae\x19\xc9\x7d\x71\xa8"
+  "\x87\x77\x5b\xc9\x08\xc9\x03\x0b\xf1\x3d\x24\x66\x86\xa7\x64\xb1"
+  "\xb2\x4e\xcf\x63\x32\x30\x1d\x2b\x0f\xeb\x65\xeb\x30\x18\xff\xeb"
+  "\xea\x3c\x55\x17\x33\xb7\x11\x4e\xcb\x70\xa5\x4c\xc8\x3b\xbe\xb6"
+  "\x4f\x93\x32\x28\xeb\xb9\x3d\x31\x92\xd7\xca\x16\xdb\x3e\x36\x42"
+  "\x1e\x80\xcf\xf6\x41\xfe\x7b\x68\x7b\x81\xea\x4b\xb6\x67\x47\xe0"
+  "\x98\x8d\xef\xbc\x30\x1f\x24\x8f\xf8\xde\xa7\xb8\xf7\x28\xca\xb6"
+  "\x82\x34\x21\x21\xf1\x64\x7e\x60\x2c\x36\x9d\xda\xa0\xf7\xb8\xad"
+  "\x80\x26\x8c\xe3\xc7\x2c\x57\x80\xdb\x1c\x2d\x9b\xdb\x5b\x22\xf0"
+  "\x35\xb0\x5e\x47\xd8\x09\x3d\x0d\xf0\x93\x7b\x59\x74\x7a\x22\xae"
+  "\x67\x90\x8f\x53\x64\xda\x80\x8e\xe7\x97\xf4\x19\x1a\xad\xaa\x26"
+  "\xab\x32\xaa\xac\x7a\x19\xf8\x3d\x13\x6d\xe0\x1a\x5b\xf5\xa9\x2d"
+  "\xe5\xc5\xca\x79\x12\x77\xf2\x85\x4f\x3f\x57\x5c\x34\xc1\x52\xf8"
+  "\x0c\xbb\x59\x2a\x5b\x57\x5c\x6c\x93\x8b\x44\xd1\x76\xe0\x18\x59"
+  "\x1e\xe8\xa0\x6c\x59\xfb\xaf\x5f\x53\xfb\x63\xb8\x5d\x70\x7b\xf7"
+  "\x72\x7b\x3f\x5e\xf9\x85\x1c\x9b\xb8\x1d\x53\xc8\x1d\x10\x0e\xb6"
+  "\xdf\xa5\xee\xe3\xfa\xa7\xfb\x54\x3f\x00\x7e\x72\x1f\x09\xdc\x3a"
+  "\xa3\xe9\x55\xd5\x13\xdd\x96\xab\x02\xf1\xf5\x44\xd5\x9b\x52\x4f"
+  "\xb8\x94\x5c\xb0\x7e\xe2\xb3\x05\x0c\xd7\xef\xb4\x4f\x88\x86\x69"
+  "\x9f\x19\xd6\x51\xf6\x1c\x5d\x47\xa9\x7e\xc2\xbe\x0e\x7d\x90\x4b"
+  "\x95\x65\x2f\x0a\xcb\x8d\xbd\x4b\xc9\x8d\xbd\xc2\x43\xd5\xa7\xf5"
+  "\xb1\x8a\xea\x3b\xaa\x72\xd8\x7e\x64\x9d\x8e\xf8\x5a\x1d\x5e\x4d"
+  "\x1a\xf7\x1b\xf6\xe6\x6b\xed\x07\xfb\x0a\xb6\x1f\x78\xdf\x23\xd3"
+  "\x02\xb8\x26\xaa\x76\x63\x3f\x1d\xa1\x7f\x52\xf0\xdd\x15\x8f\xd7"
+  "\x4f\x71\x77\x3c\x91\x97\xf3\x26\x3e\xbd\xa1\x7c\x16\xbb\xc0\x2a"
+  "\xae\xb0\x15\x3f\x5d\x5e\x5c\x14\xbb\x8e\x97\xa9\xdb\x62\xbc\x86"
+  "\x5e\x83\x76\xef\x4d\x65\x7a\x38\x50\x7f\x67\x91\x5e\x07\xa9\xa7"
+  "\x60\x3b\x6a\x3a\x2e\xa9\x9b\x9c\x93\x1b\xe4\x3e\x40\x47\x91\x2e"
+  "\x27\x9c\x6e\x5e\x85\x08\x21\x0c\xf5\xaf\xb2\x69\xe3\x25\x8c\x49"
+  "\x1d\xbb\xf5\xef\x70\x7e\xc7\x49\xd9\xf7\x1d\x94\x7b\x06\x41\xd3"
+  "\x1d\xb9\x11\xf6\x16\x7f\x67\x68\xdf\xd2\xcf\x13\xfb\x24\xeb\x25"
+  "\xc7\x59\x45\x5f\x07\xf8\xbf\x5d\xd3\x15\x4e\xb5\xef\xe6\x20\xd1"
+  "\xbb\x55\xde\x84\x06\xb9\x9e\xe0\x08\xe8\xe5\x21\xff\x99\xc8\x32"
+  "\xb9\xdf\x8a\x85\xe7\x21\x87\xf4\xe1\xbe\x53\xfa\xa8\xdb\x31\x35"
+  "\x0e\xae\x2d\x91\xe9\x90\x26\x1f\x69\xcc\x7a\x9d\x97\x57\xc8\xb0"
+  "\x75\xd7\xa9\x63\xaf\x56\x47\xd6\x9b\xb2\x7c\x96\x7f\x0d\x87\x13"
+  "\x9a\xdf\x13\x0f\xdf\x91\xc8\xf8\x4b\xff\x6b\xe9\xdc\xae\x77\xb4"
+  "\xa2\x3f\x9b\xaa\xd7\x83\xeb\x78\xb4\xca\x6b\xd6\xfd\x5e\xa9\xfc"
+  "\x3b\xde\x8b\xc1\xcd\x17\x91\xa7\xa7\xf5\x0e\x5e\x2b\xd8\xb1\x57"
+  "\x38\xed\x3c\x8e\x61\xbf\x57\x89\x35\x83\x72\xe8\xb4\x5c\x2b\x77"
+  "\x3b\xf6\xb0\xdc\x45\xca\xd2\xda\x29\x4f\x43\x92\xca\x8a\xcb\x67"
+  "\x48\xeb\x1e\x86\x1d\xbb\x55\x2b\x2c\x5f\xbb\x71\x43\xd9\x04\x4b"
+  "\x59\x51\xa1\xd6\xe8\xa3\xda\xbc\x53\x8e\xdd\x7d\x7a\x3b\x43\x59"
+  "\x7b\xc2\xba\xc5\x19\x96\x7f\xde\x03\x26\xef\x66\x76\x9e\x55\xed"
+  "\xc9\x79\x34\xa2\xed\xca\xfc\xdc\x46\x1b\xa4\xcd\xe6\x8c\xec\xff"
+  "\x79\x6c\x3c\xe2\x22\x39\xb7\x6b\x34\xf5\x29\x1a\xef\xbc\x4b\xd6"
+  "\x53\xfa\xfb\x72\xce\xe4\x7a\x4a\xff\x32\xd2\x3e\xdb\x99\xa2\xd7"
+  "\x37\x3c\x6e\xd8\x99\x29\xed\x28\xcd\x5e\xbb\xde\xb8\x3c\x6c\x9f"
+  "\xee\x6c\xd3\xe6\xdc\x3a\xf5\x31\x9e\x6e\x5f\x03\x97\x22\x65\xab"
+  "\xee\xdc\xbe\xac\x52\xf4\xaf\xae\x60\x3f\x78\xcc\x83\x9d\xef\xeb"
+  "\xb6\xa5\xdc\x1f\x78\x60\x71\x2d\xf0\x69\x8c\xd4\x13\xc2\xf4\x5c"
+  "\xa7\x66\x23\xd6\xaa\xb1\xeb\x0d\xff\x70\x0e\x65\x01\xb7\xc4\xeb"
+  "\xe0\xc6\xf5\x82\xfe\xab\x69\x62\x38\x6c\x5f\x8b\xbe\x74\xed\xbe"
+  "\xc9\x5d\x07\xa4\xbd\x0b\xd8\x5e\xf0\xd6\xef\xdc\x05\xfb\x6f\xa7"
+  "\x94\x8d\x10\x64\x94\xf7\x06\xf9\x74\x1b\x89\x76\xcd\xe2\xbe\x08"
+  "\xbf\x21\xb7\xbb\xb4\x33\x89\xbb\x5c\xde\xb2\x4c\xea\xeb\x4b\x37"
+  "\xf6\x95\xe5\x9b\x79\xbe\x80\x69\xe1\xae\x0b\x90\x92\x9f\x5d\x90"
+  "\x17\x47\x4a\x24\x3c\x0d\x16\xd3\xd4\xcc\x78\x88\xb2\x74\x23\xcb"
+  "\xb7\xbc\x9f\xb0\x2f\x13\xb6\xf0\xae\x4c\x51\x96\x69\x1c\xc2\xb7"
+  "\xd7\xf5\xea\x99\xc4\x77\x3c\xf2\xdd\x9c\xac\xaf\xd4\xfd\x01\x2f"
+  "\x5e\x78\x4d\xcd\x0d\xe8\xe5\x7e\x2e\x8c\xef\xc8\x7e\x65\x9f\xec"
+  "\x57\x04\x29\x7f\xec\x2f\x4a\x5f\xf9\xa3\x6d\xef\xc8\x7b\x55\xb5"
+  "\xf3\xdf\xde\x36\x5b\x50\xde\x95\x67\x2f\x67\x3b\x2d\xc8\xeb\x54"
+  "\xf2\x7c\xf3\xf1\xf2\x20\x2d\x0f\xb0\x4c\xbe\x98\xcd\xbe\xe8\x7d"
+  "\xd2\x5e\x78\x31\x57\xf7\x3f\xcf\xf7\x46\xf2\xbd\xa3\xa8\x97\x89"
+  "\xf9\x6e\xb1\xf3\xdd\x01\x2f\xf1\xbd\xac\xa4\xc6\xe3\xe9\xb4\x0f"
+  "\x36\xbd\xe2\xc1\x8b\xaf\xf3\x3d\xae\x6a\xac\x70\x0e\x7c\x31\xfd"
+  "\xf5\x1c\xbd\xf8\x2b\xb5\x56\xad\xeb\x89\x97\xc6\xf3\xde\x77\x8f"
+  "\x06\x03\x65\xa1\xff\xdf\xa9\x7c\x84\x72\xdf\xe9\xd7\xf9\xf9\xe2"
+  "\xeb\xd7\xce\x6f\x84\xe1\x79\xe8\xc5\x1a\xcd\x2e\x20\x35\x77\xf5"
+  "\x7b\xc0\x7a\xc9\xac\xcf\x5d\x85\x6d\x9f\x97\xd2\xf5\xb9\x2b\xe5"
+  "\xdb\x7a\xd7\x19\x2e\x7f\xa8\x39\x22\x61\x7f\x9c\xe5\x3e\x91\x6d"
+  "\xb8\x21\xed\x09\xf4\xef\x8c\xbb\x6e\x17\x2a\xfe\xbc\xf4\xb7\x6c"
+  "\x1f\xb6\x55\xaa\x71\x6d\x9f\xba\x63\x12\x36\xc0\x4b\xc7\x54\x5f"
+  "\xf6\x52\xa3\xde\x97\x21\xef\x51\x4d\x57\x68\xfd\xdc\x4b\x83\xe3"
+  "\xdf\xf8\xfb\xfe\x5f\x3a\xa3\xd3\x48\xa7\xb9\xa2\xd1\xcb\xd3\xfa"
+  "\xd2\xe6\x24\x85\x69\xfb\xb2\x5c\xbb\x88\x88\x5f\x1f\x41\x7b\xfe"
+  "\x5e\xa7\xf4\xe6\xcb\xe8\xff\x77\xd5\xa9\x3e\x45\x85\x89\xb4\xaa"
+  "\xa7\xf9\xce\x58\x45\x83\xb5\x72\x6e\xc6\x6b\xcf\x04\x6e\x2f\xe7"
+  "\x7b\x0c\x69\x79\x4a\x97\xbd\x8c\xfe\xef\xa5\x15\x5a\x3e\xc9\xff"
+  "\x48\x7c\x1f\xdd\xf0\xdc\x86\x8d\x9b\x37\xf0\x84\xda\x0b\x65\x96"
+  "\xa7\x37\x16\x15\x8f\x8c\x33\x1f\x92\xce\xf7\x45\xfb\x6a\x06\xfd"
+  "\x5a\xbd\x6a\xe3\x7d\xfa\xea\x4e\x84\x57\x9f\xb7\xdc\xc9\xf2\xf5"
+  "\xf2\xc7\x3c\x57\x20\xef\xa6\x60\x1f\xae\x6a\xde\xa0\x87\xf3\x2b"
+  "\x5a\xbf\xfa\x64\xdf\xe6\x12\xcd\xc6\x7a\xf5\x56\xa6\xa3\x36\xe6"
+  "\x10\xdd\xb4\xfb\x61\xbd\x1f\x62\xfc\xa4\x6d\xde\x9f\x29\xf5\x62"
+  "\xa8\xbf\xc4\x2c\xe9\xd5\x9f\x89\xfe\x66\xb7\xd5\x63\x48\x9d\xa0"
+  "\xea\xb5\x7b\xa6\x4e\x0f\xae\x3f\x6c\xdd\x44\xbf\x58\x0b\x19\x7d"
+  "\xd5\xa6\xc1\x62\xfd\xc9\xb0\xcd\xfa\x3e\x71\xf6\x55\xda\xba\x89"
+  "\xfd\x14\xbf\x32\x2b\x74\x80\xf5\xcd\x6e\x87\xae\x97\xb8\x2f\x0a"
+  "\x01\xce\x87\x97\xbd\x09\x68\x37\x73\x90\xf7\xe6\x73\xf4\xca\x09"
+  "\x75\x9f\xc1\xee\xc3\xd1\xf7\x19\xbc\xb2\x1b\xcf\x09\xed\xe9\x8d"
+  "\xf8\x7d\xbd\x47\xcf\xd3\x12\x11\x96\x18\x93\xa6\xd7\xef\x7c\x65"
+  "\xcc\xa0\xbd\xa2\xfc\xa5\x6a\xfe\x95\xf9\x6e\x8e\x57\x1e\x66\x9f"
+  "\xa4\x61\xd9\xd8\xfd\x82\x66\x83\xf4\x30\xed\xb8\xbf\x45\x1a\xb9"
+  "\x97\x1b\x34\x79\x9a\xe7\x68\xb9\x4e\xc2\xbf\x16\x32\xf1\xca\xba"
+  "\xb0\x1c\x28\x1a\x21\xcc\x11\xb6\x53\x5e\x59\xc1\x79\x22\xe9\x80"
+  "\x32\xe6\xa8\xb1\xe9\x2b\xcd\x7a\x9f\xcd\xfe\x58\xd5\xfd\x16\xaf"
+  "\x8c\x39\x5a\xd5\x83\x31\xff\x2b\x6d\x11\x30\xc6\x68\x73\x11\x66"
+  "\x61\x7c\xb9\xa2\x41\x8e\xd9\x5e\xe9\x0a\xcf\x09\xbc\x32\x86\xf5"
+  "\xae\x84\x91\x56\x65\x73\xfb\xe4\xbd\xcc\x06\xfd\xee\x75\xbf\xf3"
+  "\xd5\x14\xdd\x46\xd1\x61\xb5\xa9\x39\x27\xe9\x43\x13\x6d\xd0\x85"
+  "\x34\x53\x07\xe7\x63\x11\x36\x38\x06\xac\x40\x3b\x96\xb6\xf7\xab"
+  "\x2b\xc2\x63\xbd\x97\xa5\x8f\x5d\x39\x0e\x54\x70\x30\xce\x7a\x35"
+  "\x27\x76\xdc\x06\xfb\xc1\xb2\x76\xc3\x5a\x98\x0f\x3f\xb1\x6d\x9c"
+  "\x85\xa1\xc3\x4f\x6c\x6b\x67\xf1\x96\xb2\x25\xf3\x17\xc9\x37\x1a"
+  "\xc7\xac\x38\xf3\xc7\x83\x77\x2f\xf3\x9c\x11\xc6\xb9\x3c\x77\xea"
+  "\x57\x77\xaf\x0e\xd7\xde\x89\xda\x7b\x18\xfa\xbd\x56\xc8\xfd\x25"
+  "\xbe\x5b\xc7\x43\x3f\x4d\xd4\xee\xbb\xd5\xfb\x6c\xe8\xf2\x57\x2f"
+  "\xe8\xeb\x64\x72\x8f\x3d\xfb\x49\xe4\xbb\x95\x77\x3e\x77\xd6\xef"
+  "\xfc\xe9\xe0\xfc\x87\x9a\x5f\x54\xeb\x5e\x08\xcf\xd6\xc3\xf5\xf9"
+  "\x58\x84\xad\xd0\xe7\x5e\x55\xda\x9f\x16\x85\xf3\x46\xcd\x6d\x8f"
+  "\xd1\xd7\xd7\x90\x66\xb7\x4e\x33\x1d\x8e\xdd\x22\x2e\x6a\x76\x92"
+  "\x49\xda\xd5\xce\x57\x2b\xa5\x6f\x52\xb6\xc5\xe5\x3c\xf3\x4f\x8f"
+  "\xe9\xe5\xf0\x18\x81\xf1\xd6\xd6\x6e\x64\xbb\x67\x1f\xa4\xca\x87"
+  "\xe9\x4f\x07\xf9\x1f\xbd\xc6\x11\x7f\x7d\xa3\x7f\x93\x68\x0b\x5e"
+  "\x16\x2d\xfb\xfe\x88\x36\xfb\x0c\x51\x70\x93\x38\xd2\x7f\x59\x1c"
+  "\x65\x5a\xef\x7b\x8a\x68\xef\x9f\x89\x06\x4c\x2b\x3f\xbd\x0a\xba"
+  "\x2f\xbd\x14\xba\xc8\xf7\xeb\x35\x20\xdd\x52\xdf\x67\xa2\x1e\x79"
+  "\x96\xda\xc4\xc5\x7a\xa4\x5b\x72\xe1\xa2\x38\x84\xb4\x4b\x4a\x50"
+  "\xef\x4d\x22\x38\x60\x7a\xee\x53\xcb\x63\xac\x87\xf6\x54\x78\x0f"
+  "\x2c\x0c\x0a\xa7\x71\xbf\xd8\x79\xcf\xdd\x7e\xe7\x9e\x5d\x83\x77"
+  "\x7a\x01\x2e\xd3\x68\x59\x05\xff\x7e\xee\x53\xd4\xe9\xd3\xd5\xe8"
+  "\x43\xc1\x83\x4f\x91\x0e\xe3\xff\x32\xa9\x6f\xbc\xa6\xbb\xd3\xf0"
+  "\x64\xc6\xd3\xfb\xc0\xb5\x6d\x60\x93\x68\xd9\xbf\x0a\xf8\x9f\x07"
+  "\xfe\x97\xc5\x11\xd4\xe1\xe8\xbe\x6e\x22\xc6\x7f\x80\x61\x0e\x90"
+  "\x69\xf5\x16\x43\x6a\x03\xe2\x57\x57\xa4\x50\x03\xd2\xae\xf2\x51"
+  "\x6a\x3d\xd2\xac\x7a\x3e\x95\x24\xfe\xbd\xc0\x3b\x75\x61\x70\x00"
+  "\x65\x33\xfe\x7e\xe7\xde\x09\x3a\x9e\x7a\xf9\x8c\xaf\x2e\x83\xab"
+  "\x79\xbe\x2b\x6d\x4e\x2e\xe3\xad\xe6\xf0\xf7\x16\x7b\xcb\x4a\xc8"
+  "\x6b\xba\xe7\x6e\x0f\xed\x75\x70\x1b\xe2\xfa\x78\x21\x53\xda\xb9"
+  "\xb7\x4f\x75\x1a\xa8\xf1\xe4\xde\x3d\x7a\xfd\x22\xeb\x95\xb7\xb1"
+  "\x54\xce\xa3\x16\x3e\x5d\xbe\x76\x53\x21\x46\x67\x23\xc9\xc6\x41"
+  "\x72\xfc\x56\x5c\x64\xd9\xb8\xc1\xf2\x4c\xe1\xda\x75\x1b\x37\x15"
+  "\x97\x4e\x90\x43\xee\xb2\xe2\x0d\x45\x3c\xbd\x5a\x5a\x58\x6a\x1b"
+  "\x19\x63\x73\xbb\x16\x06\x79\x3f\x22\xeb\xb2\x6e\x72\xed\xd5\xe6"
+  "\x16\x03\xc2\x99\x2d\xc7\x6e\xaa\x1d\xec\x9b\x63\xd9\x9a\xcd\xf1"
+  "\x3b\x54\x5f\xe3\xda\x23\xaa\xe7\x2c\x11\x42\xde\x09\x6d\xb8\x48"
+  "\xae\x2d\xb2\x9e\x7d\x39\x3a\x1c\xb9\x47\x5f\xda\xac\x1c\xde\x9f"
+  "\x43\xe1\x3d\xe5\xae\xbd\xc2\x88\x3a\x82\x06\x9a\xdd\xda\xae\x9d"
+  "\xed\xfb\xa7\x73\xe4\x2a\x46\xbd\x79\xed\xe0\x94\xb4\x0b\xe5\x19"
+  "\x24\xd7\xa3\xb0\x7b\xdb\x85\x73\x58\x12\xd3\x65\x9f\x1a\x57\x1a"
+  "\x93\x0d\x7c\x4f\xec\x39\x3e\x0f\x69\xe5\x35\xc2\x06\x67\xc8\x1a"
+  "\xde\xd3\xb3\xb7\x96\x6d\x5c\x39\xd7\x2e\xdb\xc5\xbe\xd3\xba\xbc"
+  "\x1b\xf9\x8c\xc9\xce\xdb\x66\x28\x5d\xbd\x4f\xae\xff\x83\x6f\x33"
+  "\x14\xfe\xf2\x7e\x6a\xf4\x4f\xfb\x3f\x47\xfd\x96\x0a\x7b\x8e\xe6"
+  "\x57\x7e\xff\xe7\xa1\xb4\x63\x34\x50\x96\xae\xdd\xe9\x3e\xe7\x99"
+  "\x50\xf5\x9c\xc7\x06\xd0\xaf\x87\x60\xab\x8a\xea\x63\x3b\x07\xaa"
+  "\xe7\xe4\x85\x36\x67\x1a\x59\xbf\xdb\x2b\x40\xbf\x8d\x25\x23\xc5"
+  "\x67\x25\x37\x0c\x6c\xce\xe4\x7d\x98\xf9\x42\x20\x6f\xda\x9c\x12"
+  "\x79\x37\x6f\xf5\x9c\x27\xb4\xef\x67\xf9\x3b\x04\x5b\x0d\x61\x36"
+  "\x7c\x97\x86\x44\x44\xfa\xe8\xb4\xe5\xfc\x9d\x6c\x90\x7b\x08\xf9"
+  "\x8e\xe9\x99\x5c\x77\xbd\xce\x72\x8c\xc0\xf3\x14\x83\x75\xdb\xdf"
+  "\xab\x87\xb3\xed\xaa\xec\x48\x7a\x1a\x34\x26\xa5\xd3\x06\xd3\xfd"
+  "\x41\xa7\x81\xa4\x6d\xf5\x1c\xd8\xac\xae\x3d\xf2\x9e\xfa\x9d\xdf"
+  "\xb9\x5b\x18\xf7\x7e\xc0\x7d\xc7\xb2\x01\xb9\x96\x45\x6a\xed\xc3"
+  "\x95\xa1\xd3\x93\xf7\xca\x73\xff\x01\xbe\x65\xae\xf6\xd2\x48\xd5"
+  "\x7e\x5d\xf3\x23\xc6\x28\xbd\x42\xca\xfb\xfe\x33\xb2\x5c\x63\xe2"
+  "\x4e\xf5\xbd\xaf\x46\xf5\x77\x2e\x9b\x9e\x16\x61\x15\xca\x26\xdd"
+  "\x37\x9f\xc7\x6e\xbc\xb6\xc5\xbf\xeb\x87\x38\xc7\x59\x55\x27\x04"
+  "\xeb\x42\xd6\xcd\x96\xdb\x88\x3a\x7c\x6c\xb7\xbb\x4e\x1c\xaf\xf3"
+  "\x91\xe4\x5f\xda\x9c\x25\x7d\xa2\x84\x60\xaf\xc4\xb5\x53\x39\x4f"
+  "\x37\x1d\x48\x94\x36\x38\xe4\x39\x04\x79\x46\x9e\xa5\x2c\xaf\x55"
+  "\x97\x18\x8f\x03\x39\x6d\x95\x3d\xec\x67\x1e\x72\x78\x20\x87\x69"
+  "\xc3\x7d\xc3\x3e\xa7\x3c\xc3\x27\x75\x70\xeb\xa6\xa9\x0c\x63\xda"
+  "\xe8\x00\x99\x3b\xa0\x41\x41\xef\x80\xad\x8a\x52\xcf\x23\xbd\xb9"
+  "\x9c\x12\x79\x7c\xf4\x55\xd7\x91\x51\xde\x2e\x45\x93\x03\xbb\x74"
+  "\x1b\x08\xbf\x5d\xd1\x67\x55\x0f\x54\xc4\xae\xa5\x3d\xb5\x71\x63"
+  "\xf9\xea\xd2\x62\x7e\x65\x8e\x7f\xe1\xae\xd8\x3e\x31\x49\xdd\xeb"
+  "\x73\xa0\x99\xf9\xc7\xfd\x84\x3a\xf3\x71\xa0\x27\x62\x5c\xcb\x73"
+  "\x6b\xb3\xb9\x7f\xe3\x35\x71\xbf\xb3\xda\xfc\xbb\xca\xed\x52\x4e"
+  "\xce\x26\x92\x31\xb6\xbc\x67\x0a\xcb\x0b\xd7\xcd\x50\xcb\xb7\xd7"
+  "\x96\x53\x9d\x1e\x5d\x4e\x75\xde\x60\x39\x6a\x0c\xe2\x93\x6d\xf0"
+  "\xc0\x31\x9b\x48\x7d\x2f\x45\xe9\xb9\xea\x72\x7d\x4f\x56\x7c\xdf"
+  "\x18\x73\xda\x06\xaa\xed\xad\xcc\x2f\xfb\x76\x32\xfe\xdd\xd6\x4e"
+  "\x23\xdb\x5f\x55\xf8\xcd\x7b\x56\xe4\x3c\x9f\x76\xe7\xde\x6f\xbf"
+  "\xe8\x84\x9e\xad\x6e\x17\x07\xe6\xc0\x06\xaa\x1e\x72\x9f\x49\xe4"
+  "\xb9\x62\xb5\x46\x59\xed\x19\x2a\xad\x70\x2d\xd6\xc6\x65\xaf\x4d"
+  "\x93\x6b\x65\xb7\xd1\xcb\xe7\xe8\xb5\xc9\xe6\x74\x8c\xe3\x6e\xa3"
+  "\x5f\xe0\xb7\x1c\x2f\x70\x5c\x14\xaf\xbf\xdb\xdb\x68\x86\x74\x42"
+  "\x4a\x0d\x42\xfd\xc1\x08\x53\x7f\x26\x3c\x46\x61\x90\xbb\xf3\x4d"
+  "\xa0\xf0\xf0\x61\x66\x4a\x1e\x9d\x94\x78\xfb\xf7\xc6\xa6\xcf\x7e"
+  "\x60\xe6\x74\x7b\x55\x65\x85\x08\x05\x03\xc9\x22\xf2\x7e\xc8\xa6"
+  "\x96\x47\xef\x72\xa8\xbe\xe2\x40\x53\x4b\x3c\x5c\xf7\x3a\x85\x8d"
+  "\x6d\xeb\x50\xda\x3f\x7a\xec\x2f\x90\xf1\xc3\xab\x1e\x23\xdb\x72"
+  "\xdc\xff\xb8\x83\x7f\xc2\x98\xe0\xb5\xdf\x7d\x84\x30\xd4\xbf\x42"
+  "\xb8\xfe\xd1\xa3\xce\x5e\xd4\x18\x42\xd5\xff\xe8\x09\xc3\x37\x13"
+  "\xc3\xc7\x78\xc1\xd8\x54\xd5\x63\x74\x9b\x1f\x20\xb7\xc5\x47\x1f"
+  "\xe1\x77\x5c\x5a\xa2\x4c\x9e\x9b\x62\x18\xd0\xc3\xbb\xed\x57\xa0"
+  "\x9f\x2b\xe4\x3c\xb1\xf1\x22\xd5\xdc\x7f\x64\x88\x7c\x72\xad\x27"
+  "\x6d\xe1\xdf\xf8\x9d\x35\xe0\xff\x43\x13\x34\x7b\x08\xf6\x5a\xcd"
+  "\x2e\x5d\x27\x20\xfe\x57\x6a\xbe\xba\xa6\x56\x4f\x13\x97\x47\xaf"
+  "\xf2\x1e\x4f\xd1\xca\x7c\x15\x97\x7b\x7a\xd8\xc7\xdc\x10\x73\x02"
+  "\xf3\xd1\x3f\x7f\xc2\xed\x78\xd4\x8e\x94\x61\xa3\x77\x58\xd7\x9f"
+  "\x40\xab\x1b\xd5\x7b\x13\x8d\xf6\x3d\xc9\x38\x53\xdd\x41\xb9\xcf"
+  "\xb8\x87\xd7\xa9\x92\x0d\xd6\xb5\xc9\x3b\xac\x85\x03\xce\x99\xf7"
+  "\x72\x3f\x99\x5c\xb1\xc8\x90\x1c\x9c\x63\x08\x3a\xa7\xde\xdb\xa0"
+  "\xee\x64\xf1\xb9\x6e\x16\x9d\xc8\x73\x06\x79\x3c\x78\xba\x90\xef"
+  "\x44\x37\xbd\xfe\x38\xde\xed\xc9\x06\xd1\x90\x0c\x4e\x4e\x72\xc8"
+  "\x3b\x2a\x59\x47\x9f\x10\x69\xb0\x31\xfb\xe5\x5c\x40\x42\x78\x2e"
+  "\xe0\xf5\x4a\xf0\x6d\x58\xee\x8b\xe2\x23\xc0\x6a\x1f\xb8\x1c\x6a"
+  "\xaf\xbf\x48\xa4\xcd\x79\x9f\x46\x1b\x3d\x3d\xa1\x86\xd2\xb5\xbd"
+  "\xa2\xc6\x13\xc1\x76\xd6\xc5\x7c\xb6\xba\x0d\x65\x1e\xc3\xd3\x62"
+  "\xd9\x40\xa6\x8b\xf4\xfa\x49\xb6\x3f\xc2\x36\xec\x1b\x0b\xb4\xf1"
+  "\x48\x6b\x16\xf2\x6f\x5f\xcf\x32\xd1\x63\x0c\x02\x3e\x6c\xfe\x76"
+  "\x77\x49\xbb\xdc\x0b\xc3\x7b\xb1\x39\x0d\xca\xc8\x74\x07\xda\x29"
+  "\x24\xd2\x8d\xf8\x6e\xe1\xbd\x85\x02\x69\x3b\x2a\x3a\xa9\xc3\x16"
+  "\x80\x8e\x3d\x01\x1b\x38\x33\x03\xf8\x48\x78\x88\x3f\xfd\x21\xf8"
+  "\x6b\x81\xbd\x07\x78\xa7\x78\x6f\x0d\x9f\x51\x16\x65\x99\x77\x22"
+  "\x7f\x1b\xc6\xd0\x46\x86\x7f\x91\x0e\x7e\x2c\xfa\x32\x33\x27\xf5"
+  "\xaa\x3b\x1b\xcf\xd1\xc1\xc3\xc0\xb3\x3b\x02\xcf\x69\xc0\xdf\x0c"
+  "\xbd\xda\x0a\x98\xc7\xc4\x26\x94\xd9\x85\x32\x31\x1e\x81\xfc\x66"
+  "\x60\xbc\x6b\x66\x9c\x3b\x18\xdf\x8a\x01\xde\xff\x6a\xde\xff\x05"
+  "\x99\xd1\x16\x5a\x1b\xf0\x46\xfd\x8f\xc2\x26\x1b\xeb\x77\x1e\x6c"
+  "\xd5\xcf\xb9\xb3\x2d\x81\xef\x53\xba\x2c\xed\x45\x1a\xe0\xd8\x02"
+  "\xbc\x8e\x8d\xea\x25\x1e\xe3\x24\x40\x4e\x13\x50\xee\x70\xf0\xaa"
+  "\x05\xb4\xfb\x5b\xd0\xfa\x18\xd7\x29\x74\x39\xd4\x13\x02\xbc\xfd"
+  "\x97\x81\x53\x59\xba\x39\xa9\x8b\xef\xb4\xf6\x0b\xd0\xfb\xf4\xb2"
+  "\x0a\xbf\xe0\x7d\xb2\xa8\x33\xd3\x7b\x2f\xea\x6a\xf6\xd0\x1b\xeb"
+  "\x78\xbc\xd1\x4d\x07\xcb\xd5\x9d\x93\x07\x2b\xb4\x35\xad\xd3\x6a"
+  "\x9e\xe9\xf5\x93\x4c\x7b\xae\x57\xd2\x8e\x94\x97\xdc\x3d\x5e\x4a"
+  "\xea\xba\x09\xfd\xdb\xeb\xde\xba\x10\xdb\x28\x6f\x0c\xce\xff\x0f"
+  "\xd1\xc6\x02\x6e\xe8\x97\xd0\x65\xd1\xc3\xb6\xa7\xda\xef\xf2\xc6"
+  "\xe1\xd5\x15\xa6\x6c\xd8\x99\x46\xe0\xc9\x67\x35\x6e\x46\x3f\x3d"
+  "\x9b\xf7\x33\x01\x3f\x8c\x3b\xde\x38\x71\xbd\xbb\x5e\x41\x9f\x74"
+  "\xa4\xf1\x02\x77\x79\xa7\x1f\xdf\x85\xa9\xe6\x7a\x6a\xcd\xba\xbf"
+  "\x01\x71\x59\x54\xee\xaf\x92\xe5\x3a\x76\x6d\x92\x65\xf0\xfd\x9f"
+  "\x3d\xe5\x16\x71\xb6\xcd\xe2\x1d\xf2\x4c\x77\xc4\x3e\x1e\xaf\x76"
+  "\xa7\x98\x5c\xd3\x8c\xde\xc7\x53\xbb\x2e\x62\xdc\xc8\xeb\x9a\x0e"
+  "\x5e\xbb\x55\x7e\x61\x6a\xe5\x5e\xcc\x65\x15\xca\xff\x85\x3b\xd0"
+  "\xab\xd9\x96\xb5\xbf\x96\xf7\x0c\xb1\x5d\x23\xf7\xfe\x9c\xd7\xf6"
+  "\xeb\xd4\x3e\xcc\x65\xb4\xc5\xdc\x65\x5c\xbc\xa1\xf0\xa9\x75\xc5"
+  "\x6a\x2a\x65\xe2\xb3\xe5\x85\x3f\x89\xb6\x7f\xcd\x72\x5c\xec\xac"
+  "\x6d\x53\x73\x93\xb5\xc1\x08\x3b\xd1\x3c\x38\xb7\x64\xa4\xa3\x6a"
+  "\x7e\xe9\xcd\xb1\xf1\xe6\x97\x16\xfd\x64\xc3\xc6\x52\x59\x86\xdc"
+  "\xda\x54\xac\x4e\x3f\x8d\xa4\x47\xe7\x2f\x9a\x3f\xb1\xac\xb8\x5c"
+  "\x5e\x1e\xa2\x26\x73\x0a\x8b\x8a\x4a\xb5\x8d\x4f\x6b\x39\x17\xc7"
+  "\x3c\xb3\x59\x66\xb5\x3d\x57\xae\xb6\x4c\x95\xad\x2b\xdc\x54\xac"
+  "\x81\x88\xc4\x75\x2c\xeb\xcb\xb6\x3a\x39\x66\x1e\xa9\xd6\x69\xdf"
+  "\x3c\x1c\xb1\xae\x13\x39\x8e\xbc\x15\x71\xed\x7a\x9c\xed\x0e\x96"
+  "\x95\xb7\x26\x76\x34\x4a\x9f\x0d\xe6\xe3\x3f\x63\xfa\xbe\xc5\xeb"
+  "\xc4\x09\xdc\x67\x87\x8c\x6f\x66\xd6\x6b\x67\x99\xfc\xce\xb7\x28"
+  "\x3c\x37\x70\xe8\x98\xb6\xf7\xa1\x8b\xcb\xe3\xb2\x11\x6f\x89\xd8"
+  "\x0f\xd0\xe5\xa1\x37\x7b\x18\x06\xaf\x5b\xcb\xfb\x25\x60\x13\x69"
+  "\x67\xd9\x8d\x1d\x3f\xe3\xbe\xa5\x6e\x02\xeb\xd1\x90\x6b\x71\x8f"
+  "\x6a\x07\x6f\x17\x8a\xea\x85\x1f\x4e\xf2\xd1\x18\xa5\x07\xde\xfa"
+  "\x15\xc2\x6f\xbc\x48\x6f\xed\x46\xf8\x11\xe8\x92\x04\xb6\x47\xd4"
+  "\xfc\xf7\x5b\xbf\xd2\xe6\x0a\xb8\xce\x09\x11\x38\x34\x85\xe7\x13"
+  "\x0e\x1d\xf3\xa6\x2e\xee\xd9\xa5\xd6\xfb\xe5\xda\xa6\x5a\x5f\x7e"
+  "\x6b\xb0\xfe\xe8\xbf\x7b\xb4\xf5\xbc\x31\xdd\x48\x8f\xf1\x44\x8f"
+  "\xb6\xc6\xc6\x75\xcf\xe6\x7a\xab\x7d\x5a\x6f\x05\x23\xed\x5a\xe5"
+  "\xcf\x7f\xe1\x87\x6c\x0b\xab\x71\xc0\xdb\x77\x49\xdb\x85\xe7\x2e"
+  "\xae\x32\x0d\xdf\x9e\x85\x78\xf4\x5f\x6f\x4f\xf5\x50\x6d\x67\x24"
+  "\xcd\xca\x2b\xd0\xc1\x23\x1f\xf7\x67\xc0\x69\x38\xd2\xe4\x87\x71"
+  "\x7e\x5b\xfa\x89\xe0\xb1\x82\xb2\x2b\xde\xbe\x20\xef\x1f\xf3\xa1"
+  "\x7e\xda\x9e\x01\xa6\xb9\xba\x8f\xe0\x6d\x97\x9e\x2f\x94\xb6\xb8"
+  "\x93\xc7\x28\xfb\xd4\xfa\x17\x68\xf7\xf6\xbf\x98\x0c\x67\xe5\x1a"
+  "\xe8\xa4\x00\x35\x22\x6c\x18\xc2\xfe\xc0\xe9\x18\x0f\x39\x57\x01"
+  "\xfc\xb9\xbc\x10\xec\x60\x53\xfa\xb0\x59\x80\xe7\x81\x9e\xc9\x08"
+  "\xf3\xef\xed\xe6\xf0\xfc\xd0\x9b\xab\xd4\xfc\x50\x9d\x59\xa7\x03"
+  "\xdf\x23\xa4\xb5\x85\x04\x7d\xbd\x1c\xf1\x19\x91\xf4\x97\x7a\x4e"
+  "\xa3\xa7\x70\xbe\x59\x16\x1e\x77\xd5\xe5\x0e\xae\x15\x01\x8f\xb0"
+  "\xae\xaf\x7b\x9e\xe9\xc8\x78\xdb\xb6\xf2\x5c\xf2\xa1\x26\x59\x0f"
+  "\xb5\x1e\xf3\x7b\xf0\xe8\x75\x01\xbb\x80\xfb\x48\x1e\x03\x30\x7f"
+  "\x39\xad\xba\x63\xe8\xd0\x92\x7a\x35\xe7\x79\x10\xbf\x1f\x0e\x19"
+  "\xe3\xc9\x47\x5d\x5b\xe4\xfe\x40\x45\xe3\x43\x49\x21\x86\x09\xfa"
+  "\x31\x2c\xf4\x1b\x83\xfb\x9e\x15\xdc\xba\x01\xc0\x7c\xa3\x3b\x5c"
+  "\x1f\xaf\xa8\xd6\xe8\xc8\x7c\x94\x74\x39\x84\xf6\x5f\x2b\xe7\x6d"
+  "\xec\x8d\xe2\xc2\x46\xc0\x50\x77\x7f\x1e\x9a\x29\x98\x37\x5a\x7a"
+  "\x2f\x8f\x9d\x80\xbb\x3a\xbb\x05\x79\xc3\xf8\x83\xf1\x0c\x55\x2f"
+  "\xf6\x30\xee\xbc\x0e\x10\x1e\x0f\x1f\xe2\xbd\x1b\x9d\xde\x6d\x2a"
+  "\xcf\x7e\xb5\x4e\x01\xde\xd6\xbd\x2f\x36\x97\x90\x36\x3f\x0e\x7d"
+  "\x5c\x37\x86\x65\x9b\xe1\xf8\xe4\xb8\xe8\xd0\xee\x10\xe8\x02\x9e"
+  "\x32\x5e\x47\x75\x9e\x22\x9d\xed\x3a\x7b\xab\xc1\x93\x43\x1e\xdd"
+  "\xf7\x0b\xf7\x29\x68\xa7\x0e\x65\x03\xd6\xbf\x93\xbc\x63\xb6\x48"
+  "\x0e\xde\x7b\x2f\xdb\x34\x0d\x46\x39\x56\xd1\xf7\xbf\xdd\x0e\x3a"
+  "\x7d\xa6\xef\x05\x0e\xed\x5c\xd9\xc9\x7b\x07\xdd\x01\xb5\x77\x90"
+  "\xc3\x97\xfa\x44\xa8\xc3\x37\xc0\xfb\xf3\x3b\xfd\xce\xfa\xf9\xfa"
+  "\xf8\x85\xf5\x92\x69\x87\x01\x38\xd6\x43\xfe\x5f\x3b\xac\xe9\xa3"
+  "\xe1\xe7\xa9\x7e\x87\x06\x3f\x02\x87\x43\x41\x35\xfe\xab\x6f\x54"
+  "\xe3\xa0\xfa\x3d\xd0\x2f\xbb\xd4\x38\xa8\xbe\x56\xc7\x1b\xf1\x45"
+  "\xb1\x75\xcc\x9b\xb7\xa8\xd8\xb2\x8e\x55\xab\x75\x4a\x85\x25\x73"
+  "\x7c\xd1\x24\xb9\xd9\xd4\xf2\xe0\xbc\x19\x96\xbc\x59\xe3\x2b\x4a"
+  "\x26\x2c\x55\xaf\x79\x79\xb9\xfc\x8e\x59\x7b\xb4\x00\x7e\x20\x7a"
+  "\x9c\xd5\xa4\xe1\xd0\x90\xe2\x31\x4c\x90\xfb\x81\x45\xca\x5c\xe2"
+  "\xfb\xd5\xd1\x17\xf6\xb2\x7d\xbb\x6c\xe0\x2f\x42\x1c\xb0\xe6\x88"
+  "\xd4\xb9\x90\xd1\xa6\x16\x3c\x0e\x6f\xea\xc2\xd3\x7c\xff\x7a\xf2"
+  "\x0e\x11\x48\x0e\x0e\x57\xfa\x10\xdf\xb0\x25\x7a\x60\xaf\x30\x2f"
+  "\x69\xc1\x5d\x76\xb1\x6c\x40\xb8\x61\xb7\x80\x2e\x0d\x36\xbd\xff"
+  "\x95\x73\x47\xae\xb9\x3c\xd7\xd5\xcf\xb2\x83\x7e\x1d\xe3\x24\x94"
+  "\x69\xe2\xb9\xae\x06\xd4\xbf\xc6\xa2\x68\xd1\x00\xfd\x77\xa8\x5d"
+  "\xa3\x6f\x1e\xbe\xf9\xfe\x1b\xb5\x96\xe7\x4c\x97\x3a\x3e\xb4\xf3"
+  "\xee\x47\x60\xc3\x3b\x74\x98\x80\x95\xa4\x9d\x85\x91\xf0\xe8\x3a"
+  "\x67\xa9\x23\x9f\x50\xf5\xdc\x20\xcf\x39\xf0\xf9\xc5\xe4\x0a\x03"
+  "\xdf\x0f\x94\x3f\x38\xcf\x82\xb8\xd1\x3b\x52\x78\xee\x25\x7f\xb4"
+  "\xcf\xe0\xe0\x34\xe1\xf9\x88\x90\x67\xbf\x31\x14\x80\x1d\x90\xa2"
+  "\xee\x42\xef\xd5\xd6\x63\x1b\xd7\x0c\xce\xef\x47\xf1\xbe\x51\xca"
+  "\xc3\x17\x4e\x33\x64\xbb\xbe\xe7\x8e\x31\xca\xe6\x09\x39\x0d\xa4"
+  "\xce\xb2\x37\x3e\x2a\xdb\xa5\x26\x8f\xa0\xaf\x97\xd7\xde\x92\x83"
+  "\xc2\xcb\xfb\xd4\x43\x26\xc8\x24\x9d\x27\x77\xa5\xdf\xc1\x77\x90"
+  "\x0f\xca\xa5\x0d\x72\x69\x83\x5c\xf2\x3a\x29\xca\xf7\x9a\xee\x5e"
+  "\x83\x36\x6b\x38\x4f\x8d\x19\x8c\x3f\xd3\x06\x76\x77\x52\x08\xb4"
+  "\x92\xfb\xe1\x98\x3e\x69\xf3\x2b\xf9\x5c\x14\xd7\x35\x39\x88\x3a"
+  "\x47\xd6\xcb\x18\xf2\xec\x73\xa2\x5e\x46\xd4\xab\xe2\x82\x1c\xef"
+  "\xf3\x79\x35\xe8\x92\x9b\xc3\x77\x4c\xbc\x33\x3f\xb2\x8e\x21\xbe"
+  "\x97\x46\xd6\xe1\x9d\xe2\x78\x75\x14\x46\xae\x23\xd3\xe0\x9d\xfb"
+  "\xb5\x75\x12\x89\x27\xeb\xad\x5e\x6a\x0c\x8c\xde\xc1\xe7\xc4\xe6"
+  "\xb2\x1d\x3c\x8f\x79\x58\xef\x14\x2e\xc6\x33\x1e\xbf\x18\x9e\x82"
+  "\xf5\x33\x73\xf2\x0e\xc7\x1a\xe0\x72\x2a\x3e\xbd\xdf\xf9\xfc\xfa"
+  "\xf4\x7e\xe7\x0f\x9c\x9f\xf1\xe0\x73\x73\xc9\xec\x00\x09\xf2\x8d"
+  "\x31\xd6\xee\x78\xe5\x8e\xde\xd1\xc8\x78\xc5\x8d\x83\xec\xf7\xee"
+  "\x2f\x8d\x6e\x13\xa1\xfa\x00\x31\xfd\x1a\x10\xae\xe6\x52\x7f\x56"
+  "\x31\x38\xe7\xeb\x9a\x9b\x99\x6c\xb0\x98\xb8\x8d\x49\x5b\x16\xf5"
+  "\x8d\x07\x37\xd9\xe0\x62\x1f\x6a\xf3\xa0\xab\xe2\xc6\xa3\x1d\x58"
+  "\xc4\xce\x7b\xee\x10\xae\x39\xbd\xa3\x77\x18\x84\xd7\x74\xcf\xc8"
+  "\xd1\xbe\x60\x06\xd3\x15\xb8\x56\xa0\x8d\xef\x95\xfd\xb3\x9c\x83"
+  "\xf8\x19\xda\xff\x87\x6b\xe4\x5c\x6e\xea\x1c\x6d\xef\xe0\xbb\x49"
+  "\x1e\xfa\xcf\x9e\xf0\x1e\xa1\x77\xc7\x7a\x0c\x23\xda\x54\x5b\xfd"
+  "\xce\x5b\xe8\xd3\xf6\x84\x9c\xc9\xc2\xb2\x35\x59\x74\xd3\xbb\x7f"
+  "\x1f\x12\x99\x46\xf4\x5b\x7b\xc2\xb2\xa3\xce\xd5\xe9\xb2\x83\xfc"
+  "\x05\xf1\xe5\xe2\xdd\xed\xd7\x97\x8b\x77\x1f\xd6\xe6\xe8\xd6\xa8"
+  "\xbd\x7b\xef\x36\xe9\x63\x05\xb1\xf3\x3b\x6f\x59\xaa\x64\xf9\xd3"
+  "\x55\xd9\xa0\x49\x30\x9b\xf5\x4c\x2e\xe8\xe6\x40\xda\x53\xba\x6e"
+  "\x60\x19\x4a\x1e\xe0\x71\x0c\x49\x39\x47\x5c\x2f\x74\x8f\xba\x23"
+  "\xbb\x3a\xa7\x92\x6d\xcc\x90\xb3\xfe\x30\xfa\xaf\xb7\x79\xef\xba"
+  "\x2f\x75\xee\x3a\xbf\xb3\x29\xc5\x43\xdd\xbb\x34\xfd\x57\x04\x18"
+  "\x25\x72\x2f\x88\x3a\x0f\x9a\xc4\xed\x9c\xef\x31\xe3\xb6\x8e\xb0"
+  "\x31\xc0\x9b\xef\x34\x83\x6d\xdf\x94\xa3\xf7\xfd\x21\x67\x36\xd3"
+  "\x5b\xda\x19\x46\xb6\x63\x41\xbb\xd7\x8d\xa1\xe6\xcb\x93\xd2\x89"
+  "\xeb\x7c\x79\xe7\x6d\xcd\x2f\x67\x91\xf9\xbf\xa4\x3f\x45\xb6\x29"
+  "\x34\x66\xc7\x7d\x66\xfa\xb7\xe9\x64\x64\x3a\x78\xa8\x29\x5f\xd1"
+  "\xae\xa9\x56\xe7\x8f\x87\xde\x95\x7a\x94\xe7\xce\x97\x05\x45\x9f"
+  "\x5a\x0b\x68\x6a\xf1\xd0\x01\x6d\xcd\xab\xc1\x1c\xa7\x7f\x58\x60"
+  "\x59\x5b\x66\x29\xda\xb8\x79\xc3\xb8\x71\x23\xe3\x8c\x01\x9a\x4e"
+  "\xa8\x31\xc0\x7b\x14\x39\x06\xc0\x37\xea\x5f\xef\x89\xb5\xf9\x73"
+  "\x57\x6b\xee\x0f\x56\x5b\x29\xfc\x7b\x32\xe5\x4e\x8e\xf8\xbc\x97"
+  "\x72\xa7\xdc\xbb\xfa\x91\xe2\xc2\xa2\x2d\x11\xa1\xd3\x22\xe7\xe7"
+  "\xf6\xbf\x85\xb2\x4d\xb7\xcd\x85\xfe\x30\x2c\xdd\xc6\xfd\xce\x7b"
+  "\x97\xaa\x82\xe2\xaf\x90\xdd\xe9\xec\x73\xe8\x64\x79\x90\x4e\x42"
+  "\xbf\x89\xef\xb0\x5e\x1f\xae\xfc\x6e\x62\xfc\x0f\xd9\x4a\x46\xdd"
+  "\xbd\x18\x8b\x5d\x52\x7b\xb7\x7f\x7e\x6b\x47\x6d\x00\x7a\x62\xe1"
+  "\x19\x65\xef\xbc\x77\x1a\xe1\xa9\x78\x0f\xa8\xfd\x27\x3f\x37\x60"
+  "\x9c\x9b\x2d\x7d\x2c\x6c\x62\x1f\x0b\xef\xc9\x3e\x20\xcb\xe7\x20"
+  "\xe5\xeb\xeb\xbd\x3d\xec\x83\xdb\x43\x3f\x9f\xc9\xf6\x05\xa7\x45"
+  "\xd8\xc7\x96\x67\xc9\xca\x6f\xb6\x79\x3d\x80\x29\x0e\x2c\x3c\x23"
+  "\xde\xce\xe7\x35\xf9\x0c\xc0\xbc\x9f\xed\x36\x53\xfa\x70\xbf\xdf"
+  "\xf9\xf3\xe9\xba\x0d\xc2\xfb\x44\x87\xb2\x3f\xf4\x7e\x70\x34\xf4"
+  "\xf7\x68\x5f\xb2\x58\xcd\x3e\x4b\x0c\x94\xc1\xfd\x43\x72\x45\x9e"
+  "\x3c\x5b\xc4\xfd\x22\xeb\x84\x7a\xa9\x4b\x7f\xee\xd2\xf5\xc2\x3e"
+  "\x35\x8e\x1c\xc9\xf9\xd1\x7f\x7e\xa6\xfa\xcf\x9f\x1f\xd1\xdb\x02"
+  "\x7e\x1f\xd3\x65\x35\xea\x7c\xca\x86\xf2\xe2\xd2\xe2\x22\xcb\xf8"
+  "\xb2\x91\x14\x71\x43\x64\x49\xf1\x06\x4b\x69\xf1\xf3\x2f\x14\x97"
+  "\xc9\x01\x1a\xc7\x46\xaf\x8d\x40\x07\x85\xef\xeb\x95\x67\x64\x7e"
+  "\x31\x8e\xc7\xb0\xc9\x3b\xc6\xc9\x79\x70\xb5\x7e\xf1\x8f\x81\xd0"
+  "\xbe\x51\xd9\x6a\x1e\xf1\x3c\xe8\xda\xac\xfc\x51\xbb\x16\x9e\x60"
+  "\x3b\xae\x9b\x9a\xa7\xa9\xb5\xf6\x5f\xac\x57\xb4\x4a\xb4\xfb\x9d"
+  "\xbf\x28\x0a\xdb\x6b\xcd\x72\xff\x9f\xda\xf3\xf6\x8b\x4a\xd0\xb8"
+  "\x20\x6c\x83\x34\x7f\xc2\x7a\x50\xea\xc3\x2f\xd1\x85\x9a\xed\x8c"
+  "\x72\x9a\xef\x12\x9b\x44\xd7\xfe\xab\x24\xe7\xf1\xd8\x77\xbb\xd2"
+  "\xaf\xbf\xe8\xd4\xe9\x08\xfb\xa5\x8b\xe7\x0b\xf4\x31\xd0\xb2\xe0"
+  "\x15\x51\xb5\x85\x8c\x3c\x67\x00\x1d\xe2\xf9\x9b\x52\xaf\x51\x38"
+  "\x7f\xde\x0e\x5b\xe6\x04\xa7\xa9\xd7\xf6\x7e\x89\xd4\x85\xed\x7e"
+  "\x67\xb3\x25\x3c\x3e\x6c\xee\x92\x76\xfc\x55\x96\x9b\x5f\xb4\xad"
+  "\xe6\x3e\x42\xe9\xee\x1b\xbe\x0c\x5f\x31\x52\xcd\x95\x2b\xfd\xd6"
+  "\xbc\x46\xab\x43\x2f\xeb\x2c\x6d\xef\xa0\x51\xc9\x75\x73\x17\x64"
+  "\xee\x04\xf3\x02\x7a\x7e\xb7\x4e\x2f\xae\xaf\x1c\x77\x6e\x27\x23"
+  "\xf4\xb0\xe7\xc3\xad\x01\xa3\xba\x5b\xf1\xe7\xa7\xd5\x18\xa6\xb9"
+  "\x3d\x72\xcd\x47\x8d\xa5\x9a\xcf\x84\xfd\x1a\xfc\xe2\x9a\x33\x29"
+  "\x1b\x37\xf0\x71\x94\xe7\x56\x6f\x2e\x7c\xae\x78\xf5\x0b\xb6\x09"
+  "\x96\x17\x36\xc8\x25\x35\x39\x7c\x2f\x7f\xe1\xe9\xe7\x2c\xac\x45"
+  "\x56\xcf\xcf\xcd\x5d\x3d\xf7\xd1\xe5\x8f\x8f\xa4\xb9\x85\x08\x2b"
+  "\xdf\x68\xc9\xb5\x4e\x50\x51\x8f\x2c\x98\xf7\xd8\xea\x79\xcb\x1e"
+  "\x5d\xba\x22\xce\x9e\xd6\x24\xc8\x44\x3b\x78\x94\x70\x8e\x3e\x98"
+  "\xaa\xf6\x30\xbc\x6f\x8b\xde\xc3\xf0\x3e\xfa\xcf\xf7\x9b\xf0\xb4"
+  "\x12\x7d\x80\xd1\xcc\x07\x53\xf1\x64\x6a\x72\xd3\xef\x77\xbe\x5f"
+  "\x17\x96\x9b\x0f\xa4\x7f\x5d\x1e\xf3\xab\x39\xd3\xf7\xa1\xff\x7e"
+  "\xee\x8b\x8c\x0b\xeb\x82\x5f\xbe\x27\xf5\xa5\x26\x17\x2c\x0f\xab"
+  "\x83\x89\x52\x36\x94\xbd\xf2\xbe\x4f\x97\x0d\x79\x4e\x0e\xe1\x3c"
+  "\xd7\xc5\xf1\x90\xef\x2e\x9e\x17\x86\x2c\xb4\xf3\x7a\x26\x87\x8b"
+  "\xd4\x7f\xd4\xf6\x5f\xfe\x72\x02\xcf\x13\xb3\x3d\xab\xad\x7b\x8c"
+  "\x3e\x4f\xbf\x5c\x2b\x9c\xcd\x5e\x35\x16\x7c\x7f\x9c\x94\x9b\x9d"
+  "\xb7\xcd\x95\xeb\x47\xf2\x3c\xc2\x2f\xd7\x84\xe5\xe7\x83\xa9\xcc"
+  "\x1b\xd6\x0b\x4a\xf7\xfe\xb2\x32\x66\xfe\xc5\x84\x30\x97\xee\x07"
+  "\xbb\x7c\x1c\x19\xcd\xe3\x5c\x54\x63\x14\x0e\x0f\xfd\x32\x5b\xed"
+  "\x63\xfb\xe5\x11\xdd\x7e\xc6\x6f\xb4\xff\xff\x99\x1d\x3b\x6f\xb5"
+  "\x2f\x62\xde\xaa\xca\x26\xce\x76\xd8\xbc\x6c\x23\xb7\xba\xbd\xd2"
+  "\xff\xe2\xec\x0e\x9b\x8f\x7d\xf6\x8d\xec\xa6\x0f\x12\xec\x03\xe2"
+  "\x2a\x7e\xdf\x86\xba\xc9\x3e\x64\x92\x9a\x37\xc0\x78\xec\x83\x69"
+  "\x6a\x6c\xa2\xc2\x99\xee\x1e\x7a\xff\x30\x8f\xcd\x98\x3f\xf8\xed"
+  "\x32\xa5\x8f\x98\x11\x4f\xef\x8d\xde\x61\xd4\xfc\xdc\x7c\xf0\x0a"
+  "\x8f\x51\x99\x56\xaf\x19\x43\x25\xaf\x39\xf1\xe0\xcd\xba\x2f\x6c"
+  "\x5f\x8a\x80\xa2\xed\x07\xbb\xdb\xfe\x3f\xf2\xbe\x3f\x2e\xaa\x2a"
+  "\xef\xff\xcc\xf0\x43\x34\x74\x06\x16\x6d\x34\xca\x69\x57\x7b\x68"
+  "\xd7\x14\xcd\x5c\x77\xbf\xb6\x21\x59\x62\xab\x69\x3d\x56\xd4\x1a"
+  "\xa0\x61\x0b\xae\xe9\xa8\x88\xa8\xc8\x20\x1a\x4b\xad\xe2\x68\xe8"
+  "\x43\x89\x4a\x4f\xb4\x2f\x7a\x56\x8b\x76\x6d\x97\x8a\x6c\x5a\xb1"
+  "\xc5\x44\x86\x5a\xed\x21\x17\x6b\x22\x34\x62\xd1\x46\x41\x19\x61"
+  "\xe6\xde\xef\xfb\x73\xce\xbd\xf3\x03\x67\x54\xda\x9e\x6d\xbf\xdf"
+  "\xe7\x0f\xb8\x73\xcf\x3d\xf7\xdc\xf3\xf3\x7d\x3e\x9f\xcf\xf9\xfc"
+  "\xc8\xe9\xa0\x7d\xd3\x19\x54\xbf\x30\x5b\x6e\x56\xc7\x73\xb6\xdb"
+  "\x71\x17\x8d\x57\x77\xc1\xef\xac\xea\x58\x76\x8e\x9d\x1a\x1f\xb2"
+  "\x9e\x19\x0f\x96\x4d\xa0\x74\xac\xff\xdf\x25\x28\xfa\x93\x5d\x7d"
+  "\xdf\x05\x0e\x27\x88\xf7\xf7\x32\xf5\xfd\xbe\xfe\x53\xb9\x81\x1f"
+  "\x09\xa7\x7e\xca\x45\x58\x71\x4a\xb8\x5b\x3f\x5b\x1d\xb2\xc1\xac"
+  "\x15\x73\x52\x95\x9d\xe9\x45\x7b\xf6\x5e\x92\xb6\x81\xff\xde\xf6"
+  "\xb3\x16\x45\x0e\x80\xb5\xbd\x77\xd7\x58\xc6\x16\x77\xad\x4a\xf6"
+  "\xc8\x49\x48\xbe\x40\x3e\xd1\x50\x8f\x22\x1f\xd9\x96\x47\xc7\xcb"
+  "\xce\xf6\x3a\x49\xe7\x04\xe5\xb4\x52\x39\xb4\xae\x84\x6c\x66\x6f"
+  "\x35\xf9\xd0\x41\x79\x4b\xf8\xd9\x65\xc1\x5e\x3d\x9f\x7b\xe0\xb5"
+  "\x39\x9f\x9f\x2b\x7f\xa9\xe8\x40\x70\xda\x45\xd8\xf3\xec\xed\xf0"
+  "\xc8\x7b\xb8\x6d\xcb\xde\x0c\xd2\xeb\xec\x2e\xd8\x17\x1a\x48\xce"
+  "\x07\x7c\xc8\x98\xbf\x24\x7d\xe9\x93\x4f\x5e\x1d\x1a\x7c\x75\x2d"
+  "\x2d\x05\x52\x11\xca\x04\xff\x5b\x92\x2c\xe6\xe9\x3e\xe0\xff\xb3"
+  "\x82\xd6\x05\x0d\x83\x75\x73\x63\x3b\xdb\x67\x55\xe9\x77\xb1\x8e"
+  "\xf6\xd5\xcb\x05\xfb\xf4\xde\xb5\xb1\xaf\xf4\xf2\xb5\xb1\x6f\x6f"
+  "\xe0\xb5\xb1\xaf\x11\xfb\x6c\x33\x9e\xd7\xe3\x9b\xf5\x1c\xf3\x69"
+  "\xbc\x05\x0d\x6e\xd5\xb9\xee\xe2\x34\x78\xea\x6a\xa6\x21\xfa\x9b"
+  "\x64\xca\xb4\x1f\xb8\xc1\xd7\xba\x81\x11\xa9\x2e\xa6\xa7\xbd\x60"
+  "\xcb\x12\x92\x17\x8e\x94\x5d\x17\x65\x7b\xea\x6a\xe0\x05\xee\x8b"
+  "\xdb\xc5\x39\x6b\xca\x05\xf0\x21\xf8\xbd\xe5\x34\x61\x85\x44\xce"
+  "\xda\x99\xd8\xaf\x5f\x4d\x50\x69\x5c\xdd\x7a\x23\xf7\xe1\xcb\xf7"
+  "\x6d\xcc\x33\xda\xb7\x53\xdd\x3a\xab\xd8\xb7\x5f\xcd\xb8\xa2\x6c"
+  "\x3a\xaa\xa2\x3c\x50\x3a\xea\x58\x4b\xf5\x42\x3d\xab\x50\xaf\xfd"
+  "\x54\x9f\xe2\x27\xa9\x5d\x21\xb7\xeb\x5c\xf1\xfc\x6c\x80\xea\x99"
+  "\xd2\xc5\x6e\xa7\xfa\xa5\x2c\xbb\x9d\xed\x7e\x92\xce\x77\x85\x5e"
+  "\x8f\x32\x97\x42\x31\x67\x06\x9c\x66\xaf\xc5\x76\xf1\x98\x8a\xaf"
+  "\x62\xec\x23\x04\x5d\xaf\x9c\x9d\x50\x1e\x7a\x26\xe6\xe9\x6b\xb1"
+  "\x07\x73\xa8\xce\xaf\xc5\xaa\xf9\x7c\xeb\x76\xf7\x7c\x13\x08\xcb"
+  "\xcc\x27\x9f\x5c\xb8\x7c\x85\x1a\x1f\x3a\x6e\xe9\xe2\xf4\x3b\x15"
+  "\x7b\xd7\x25\x0b\x57\xa5\x66\xa6\x73\x7d\x7a\xa4\x8a\x9f\x7d\x68"
+  "\x8d\x31\xc4\x0b\x70\x1d\x55\x4e\x67\xfc\xe1\xd2\x6e\x85\xe6\x68"
+  "\x61\x55\x45\xe2\xfc\xb9\x6a\xaa\xd8\x07\xae\x5b\x86\x7a\x54\xa8"
+  "\xfb\x00\xc9\x23\x3a\xd9\xcd\x71\x74\x2e\x44\x36\xcc\x74\xfe\x44"
+  "\x32\x09\xe4\xa9\xb3\xb3\x57\xb3\xd4\xb9\xbd\x19\xe9\x64\x37\x61"
+  "\x5d\x42\xba\x76\xfb\x87\x4b\x5b\xa7\x36\xcb\xd1\x63\x2d\xc0\x80"
+  "\x48\xda\x1b\xe8\x3c\x44\xf8\xe3\xaf\x8a\x21\x6c\x23\xb9\x99\x75"
+  "\x09\xe9\xae\xbd\xd6\x8a\xbd\x1c\x34\xf0\xfe\x58\xf0\x45\xcd\x1b"
+  "\xd7\xb0\x08\xfa\x06\xf6\x0d\xbb\x90\xb3\x56\xc5\xbf\x97\xcb\x98"
+  "\xb2\x77\xd8\x37\x73\x99\xe2\x6b\xc2\x67\xa2\x65\xaa\x43\xc8\x1c"
+  "\xa6\x82\xb6\xa9\xc2\xfc\x1f\xcc\x44\x9d\xc7\x56\xf3\x73\x2f\x8e"
+  "\x0b\x55\xb9\xf2\xb6\x71\x49\x5c\xbf\x70\xdb\xd8\x6a\x49\xce\x08"
+  "\xa1\x7b\xe0\xf2\x20\x94\x53\x21\x9b\xe3\x98\xa2\x93\x18\x72\x9a"
+  "\xbd\x1e\x86\x6b\x28\xc6\xa3\x84\xfa\x02\xe5\xbb\x94\xf2\xb1\xa6"
+  "\xaa\xb0\xff\xdd\x60\x11\xeb\xab\xaa\x56\xfd\x16\xe6\xb6\x03\x7b"
+  "\x57\x2d\xed\x5f\xa8\xff\x31\xfc\x35\x09\xf9\x8c\x13\x7c\xd2\x48"
+  "\x8f\x7c\x46\xd0\x48\x55\x2e\x75\x4e\xd2\xb7\x95\x36\x10\x9f\x46"
+  "\xfe\xfd\x34\xca\xb7\x9c\x24\x2b\x50\xcb\x94\x51\xa6\x7c\xb1\xa3"
+  "\x1c\x7b\x4d\x04\xd6\x98\x63\xc8\x7a\xec\x29\xf4\x0d\xa2\x71\xbb"
+  "\x46\xca\xd8\x73\xdc\xa9\xee\x50\x61\x6f\xbe\x9a\x0d\xf6\xa5\x6f"
+  "\xbb\x0b\x5e\x5f\xec\xa5\xc9\x50\xc6\x45\x60\x59\x1e\xcb\x6f\x65"
+  "\xaf\x73\xff\x67\xa4\xcf\x41\xe3\xda\x83\x71\xc2\x58\x95\xe2\x3b"
+  "\x55\xa0\xcb\x07\xa3\x1f\x5e\xa1\xf1\x2a\x96\xb0\xe6\x7a\x38\xad"
+  "\xae\xa3\xd8\xe9\x2d\xec\xf5\xed\x34\x56\x54\x96\x6c\x19\x97\xe1"
+  "\xea\x4e\x9e\x4e\x7e\xa9\xa8\xaf\xd7\xe5\xca\x6d\x74\x46\x87\xb9"
+  "\x35\x9c\x68\x58\xd0\xf5\xfc\xb7\x39\x5d\x96\xf8\x58\x73\x3d\xc5"
+  "\x3f\x0c\x5f\xd7\x26\x4b\x97\x0a\x98\x5c\x07\x2c\xbd\xa4\x65\x2e"
+  "\x27\x78\x50\xd4\x5b\x6b\x3e\x43\xbe\xb3\xca\xb1\xbe\x8a\x18\xbe"
+  "\x1b\x51\xbc\x86\xe9\xc9\xd7\x98\xd9\x24\x3b\x1b\xba\xca\x58\x83"
+  "\xa9\x8c\x7d\xe0\x2a\x61\xd6\x6c\x92\x69\xfe\xc1\x7a\x24\xa7\x84"
+  "\xf4\xc2\x07\xe2\xf7\x7a\xe3\xc3\xf4\xad\xdf\x27\x1f\x39\xf6\x11"
+  "\x3b\x62\xfd\x88\x19\x1f\xe3\xf7\x19\xf5\xc9\x1f\xb0\xfa\x84\x0f"
+  "\x98\xb9\x55\x96\x88\x1e\xca\x7b\x8a\xbe\x51\x84\xb2\xca\xc9\x47"
+  "\x97\x5e\xea\x34\x0c\x42\xfb\x43\x67\xe7\x30\x7e\x0e\x68\x5d\xf2"
+  "\x16\xea\xf8\xfb\xaf\x76\x9f\x67\x11\xd6\x25\x7f\xe6\xbf\xb9\x7c"
+  "\x01\xed\xb5\xa5\x37\x71\x1d\x31\xf2\x49\x66\xcb\x69\x23\xfb\x4a"
+  "\x69\x0b\xd5\xd1\x2d\xea\x8d\xfe\x0a\x55\xdf\xdf\x93\xe7\x79\x9f"
+  "\xfb\x8a\xdd\x45\xfd\x81\x3a\x1d\x9d\x2b\xfa\xa4\xbe\x09\x7d\xfa"
+  "\xb0\xd2\x3f\xc9\xbe\xfd\xf3\xfb\x08\xea\x1f\xd2\xff\x94\xb2\x3b"
+  "\xca\x51\xb7\x04\xf4\x81\xa4\x7e\x83\xe6\x00\x9d\x57\x51\xf9\xc5"
+  "\xe7\x59\xa4\x75\x09\xe9\x87\xfe\xe1\x29\xdd\x9c\xd0\x08\xe9\xe2"
+  "\x99\xaa\x2d\x17\x58\x28\x8d\x1b\xed\xb3\x5b\xf8\x73\xde\xe7\x73"
+  "\x68\xcc\x1c\x51\x3f\x6b\xc4\x1f\xe6\xe7\xcf\x9a\x68\xee\xe1\xda"
+  "\x8c\xf1\x2a\x42\x3f\xb5\x61\xac\xca\xe9\x2a\xe6\x63\x7c\x04\xf9"
+  "\x6b\xa4\xbd\x0c\x73\xc5\x9b\xbe\x2d\x7e\x80\x0b\x6b\x47\xe2\x7c"
+  "\xda\xef\xdb\xa4\xad\x3f\x6f\x14\xba\x82\xaf\xc5\xed\x02\x5d\x5c"
+  "\xb6\x8d\xdb\xa3\x47\x82\x96\xe7\xfb\xe2\x0b\xdc\x6e\xe5\x0f\x9e"
+  "\xfd\xef\x59\x1e\xcb\xfc\x0f\x06\x2d\xd7\x09\x9b\xda\xa5\xcc\x75"
+  "\xe0\xf9\x7e\xac\xfd\x61\x0a\x5f\x5d\xc5\x6d\x5a\x08\x07\x82\xd1"
+  "\x24\xc0\xe5\x7a\xd2\xb1\x93\x6f\x48\x66\x91\x1a\xd9\x11\x99\xa6"
+  "\x93\x6d\xae\x5a\x9a\x43\x91\x7c\xee\x8b\x67\xa0\x23\x1d\x3a\x60"
+  "\x79\x23\xd2\x43\xd5\x74\xc2\x75\x09\xbc\x25\xf1\xb5\xb3\x57\xeb"
+  "\xe4\xbc\x0b\x2c\x96\xcb\x88\xd4\xf4\xd5\x0e\x5d\x83\x81\x91\xce"
+  "\xbd\x8b\xfc\x50\xd0\x3b\x48\x0f\xc1\x3e\x50\x83\xef\x5a\x91\x3f"
+  "\x46\xcd\x2f\x77\x26\x87\xda\x72\x6a\xf9\x3a\x23\xdf\x4a\xea\xbe"
+  "\x80\xf4\xb0\xd9\x39\x0e\x1d\x1f\x33\x35\x6d\x45\x32\xdf\xc7\xc8"
+  "\xe6\x1d\x74\xaa\xcc\xeb\x73\x9a\xa7\x6b\xc0\x67\xf2\x58\xe9\x3e"
+  "\x69\x5a\xf2\x2f\x40\x7e\xf1\x7c\xd2\x42\x50\x67\xe6\xb9\xc7\xb7"
+  "\xb7\x2c\xe2\xe7\xf4\x86\xd9\xab\xe9\x4c\x0c\xdf\x59\xa4\x7c\x7b"
+  "\xb5\xcc\x84\xbf\x4d\x91\x26\xf6\xcc\x37\xb2\x7c\x79\x5c\x3a\xa3"
+  "\xa0\x6f\x4b\x9d\xc9\x5a\x77\x67\x72\x08\x7d\x9f\xca\x22\xf9\x24"
+  "\x8f\xd9\xee\x6a\x63\xe4\xeb\x59\xde\x5a\x43\xf9\x42\xa9\x5c\x5e"
+  "\x9f\x1c\xf0\xff\x51\x35\xf9\x81\x75\x58\x5e\xa9\xb6\xe6\x3d\x86"
+  "\x39\xfd\xc7\x5c\xc2\x14\xb7\x3e\x11\x18\x40\x7a\x07\x6f\x5c\xa0"
+  "\x31\x75\x63\x9d\xbb\xa3\x12\x3b\xc6\xb5\x31\x4d\x1e\xd6\x8e\x38"
+  "\xab\xfb\xe3\x50\xa2\xa9\xcc\x92\x2c\xe3\x77\x04\xcd\x5d\x5d\x07"
+  "\xe9\x9e\x24\x3a\xb8\xbe\x47\xf4\xcb\x55\x36\x67\x1b\xab\xcf\x3f"
+  "\xc1\xea\x5d\xb6\xfc\x9a\xf3\x8e\x50\xa1\xf7\x11\x8a\x72\xff\x78"
+  "\x2b\x3d\x33\x63\xbd\xa4\xba\xcb\x83\xf3\x81\xe0\x2d\xd0\x77\x9f"
+  "\x89\xbd\xe0\x8f\xb9\x2a\x3f\x71\x95\x36\x1c\x23\xdf\x86\xa4\x17"
+  "\x27\x6d\xdb\x40\x31\x18\xcd\x72\x77\x1c\x1b\xb7\x86\xe4\xba\x7f"
+  "\xdc\x3b\xa4\x8b\x25\x28\xe5\x7e\xad\x94\x7b\xec\x4a\xe5\xd2\xbc"
+  "\xad\x2f\x15\xba\x16\x52\xf4\x86\x46\x37\xca\x76\x47\x6f\xd4\x63"
+  "\xaf\x31\x9b\x2f\x91\xec\xa4\x7a\x38\xbe\xd3\xd8\xe0\x6a\x64\xe4"
+  "\x23\x75\xb7\x84\xfd\xfa\x6b\x03\x53\x74\x5c\xcc\x67\xd9\x9f\xc2"
+  "\x24\x39\x4e\x0f\x3e\x87\x64\xa5\x66\xc2\x59\x92\x3d\xe7\xb9\x59"
+  "\xb8\x0d\x23\x4b\x3e\xfe\x50\xc6\xe0\x43\x24\x97\x06\x56\xb9\x65"
+  "\x83\xf6\x9d\x8b\x76\xb6\x05\xf8\xcd\x7d\xfe\x6d\xb8\xe1\x85\x21"
+  "\xeb\xd9\x5d\xb2\x56\xc7\x75\x98\xa4\xad\x2f\xb5\x61\x6c\x23\x84"
+  "\x4e\x4d\x62\xa8\x8f\x3e\x4d\x08\xbe\xf5\x0c\xe9\xd3\xc8\xfa\xa9"
+  "\x75\x65\xb4\x67\x62\xcc\xba\x0b\xfe\xb4\xdf\xce\xde\xe0\x74\xc9"
+  "\x26\x92\x03\x70\x9c\xaf\xbe\xd9\x11\x65\xa6\x18\xa2\x14\xf7\x50"
+  "\x23\x65\xbb\xaa\xb6\x9c\x03\xdd\xc3\xfb\xa3\x5a\xd3\xd0\xd1\x6d"
+  "\x95\x2d\xe6\x2a\x5a\x47\x4a\xd9\x3a\x94\xfd\xa1\xbc\xd5\x0c\x7e"
+  "\xaa\xda\x28\xc6\x86\x7e\xff\x89\x9f\x75\xb8\x7a\xc9\x0e\xe7\x4f"
+  "\x19\x65\x3d\x24\x93\xfb\x13\x70\x65\xa4\xb5\x53\x6f\xae\xfa\x77"
+  "\x43\x3e\x68\x80\xea\x89\x76\x6d\x9b\xd0\x79\x56\xfc\x17\x06\x3b"
+  "\x83\x92\x77\x1a\x06\xd9\x50\x08\x68\xdc\x98\x76\xf6\xd6\xcb\x3d"
+  "\xe0\xf3\x7b\xb1\xb7\xf6\x80\x4f\x90\x77\x26\x47\x16\x8f\x60\xf1"
+  "\x78\x36\xa2\x9d\x55\x3f\xe3\xd2\xb2\x18\xfc\xe9\x1d\x37\x64\x0c"
+  "\x44\xb9\x09\x24\xff\x3c\x7a\x9e\xce\x5d\xab\x39\xee\x6f\x79\x81"
+  "\x8d\x92\x50\x1e\xc9\x5d\xb7\x8c\x60\xa3\x48\xe6\x8a\xb4\xb8\x54"
+  "\xb7\x38\x93\x50\x79\xaa\x0d\x23\xd8\x18\xff\xef\x56\x9b\x04\x2f"
+  "\xf7\x16\xdf\xe3\x57\x39\xd8\x4d\xa6\x9f\xc9\x2d\xa7\xd9\x9b\xe9"
+  "\x72\x41\x88\x2c\xdf\x60\xd0\x0a\x9e\xe2\xcd\x59\xba\x52\x31\xef"
+  "\xb8\x0c\x1e\xf3\x8d\xce\x38\x14\xd9\xae\x86\xfb\x6d\x8c\x9e\x9e"
+  "\x4b\x76\x10\x3c\x4d\xa3\xa7\xbe\xd4\xf3\x7a\x28\x3e\xd7\xdc\x1b"
+  "\x7e\x48\xb1\xdd\xb8\xaf\xb5\xd4\xf9\x42\x2e\x4c\xfe\xd8\xd0\xc7"
+  "\xdc\x1e\x6c\xd3\x0b\x2c\xf2\x37\x2f\x30\xfd\xd1\x27\xa9\x5d\x6f"
+  "\xe6\x8a\xb5\x18\xca\xa8\xbe\x92\x85\xd6\x19\xe6\x04\xea\x4d\xdf"
+  "\xa3\xb9\xd1\xe0\xfa\xda\x6a\xce\x92\x25\xeb\x22\xf2\x05\xf0\xe6"
+  "\x3b\xd6\xe5\x7b\xd9\x6c\xf2\x5f\x47\x3e\x6c\xe6\x31\xc7\x1e\x94"
+  "\xb7\x67\x04\xd3\xa3\xac\xc3\xb6\xc5\x84\xb5\x86\xef\x5b\x97\xef"
+  "\xa7\xb2\x4f\xd2\x7e\xb4\x19\xfd\x23\xf6\xa5\xb7\x2c\x36\x67\x13"
+  "\x23\x7f\xf5\xf7\x9b\x64\x37\x95\x73\x9a\xbd\x35\x94\xb7\x77\xa7"
+  "\xc1\x98\x2a\x7c\xe6\xf1\xb6\x7a\xe4\xed\x4a\x3b\x6c\xe7\xa9\xbc"
+  "\xb7\xe2\x6c\x69\xa0\x39\x95\x36\xa9\x7d\x2d\xe6\xd7\x5b\x0b\xad"
+  "\xcb\x2b\x18\x8d\x0f\xe5\xc7\xfd\x5c\x5b\x07\xf2\x9e\xf1\x1f\x17"
+  "\xca\x83\x67\x4f\xa3\xdc\x1f\x7b\xcf\x91\xe8\x7c\xc3\x9b\xa7\x0c"
+  "\xed\x41\x5f\xd5\xed\x44\x1f\x09\xf9\xda\x9b\xe7\xa8\xae\x76\xf6"
+  "\xa6\xc3\x96\x75\x22\xb0\xfd\x11\xd6\x3e\xe6\xfd\xfa\x06\x2e\x5b"
+  "\x7a\xeb\xf3\xfb\x5d\x92\x2c\xf0\xec\xed\x12\xd0\x6e\xa0\x13\xdf"
+  "\x2e\x21\x2c\xe0\x78\x32\x96\xce\x7e\xdf\xde\xae\xd3\x88\xf1\xa5"
+  "\xb6\x10\xcd\x14\x68\x8c\x7d\xe4\xfa\x7a\xaa\xab\x3a\xc6\xb2\xfe"
+  "\x95\x6a\x89\xce\x6b\x46\xa0\xbf\x7b\x0d\x4c\xcc\x3f\xd9\x82\x72"
+  "\x9f\x16\xeb\x28\x31\x49\x39\x7b\x4b\xea\x8c\x4a\x74\xca\x6b\x0d"
+  "\x4c\xd5\xb5\xc3\xfa\xe5\x67\xd1\xf8\xa6\x81\x30\x6a\x8f\x56\xac"
+  "\x1d\xaa\xa3\xf2\xee\x34\x71\x8e\xfc\xf6\x5c\xbc\x3f\x2d\x60\x7b"
+  "\x43\x80\x3b\x05\x80\x69\xb4\x87\xdb\x05\x00\xab\xb0\x1f\x84\xdb"
+  "\xba\x7a\x98\x38\xdb\xae\x89\x02\x8d\x1f\x4e\x36\x61\x6a\xdd\xfa"
+  "\x27\x83\x7f\xbb\x59\xc8\xe0\x6b\x62\x55\x7e\x53\xd6\xa3\x8f\x0b"
+  "\x74\xdc\x77\x39\xe8\x2e\xa9\x2b\xea\x15\xab\x23\xea\x6d\xc5\x16"
+  "\xa9\x66\x9a\x1c\x25\xf0\x36\xd5\xc9\xf2\xa9\x5d\x0a\xdf\x15\x4e"
+  "\x6d\x46\x39\xe9\xea\x59\xb0\x5a\x76\xd0\x78\x00\x6a\xdb\xd0\x26"
+  "\x61\x4b\xfc\x4a\x35\x6f\x1b\xf9\xc3\x10\x6d\xe3\xf6\xb8\xfd\x6b"
+  "\x4f\x8d\x88\x11\x60\x79\xc5\x6a\x1d\x41\x65\x1c\x58\xcd\x75\xf1"
+  "\x31\x26\xc0\x87\xeb\xdb\xd9\x3b\x13\xe5\x41\xbf\x19\xd4\xbf\x32"
+  "\xdf\x61\xa2\xcc\xb7\x1d\xdb\x81\xc1\xc2\x3e\x88\x74\x58\x0e\xcc"
+  "\x97\xb7\xbe\x4d\x36\xeb\x5d\x9d\xf8\x1e\xe6\x87\x0f\x0e\xbd\xd3"
+  "\x4a\x63\x35\x76\x2f\x4b\x10\xf3\xf0\x9d\x4f\x48\x2e\x21\xe2\xb5"
+  "\xbc\x53\x84\x79\x3f\x53\xf0\x4b\xaa\x5e\xa6\x86\xeb\x65\xfa\x62"
+  "\x6c\x3f\xeb\x28\x78\x9a\xe8\x97\x2c\xf8\x9d\xc3\xf5\x74\x50\xdf"
+  "\x55\x2e\x15\xff\xde\xc9\x91\x49\x36\x9c\xa7\xc8\x08\x09\xcb\xf2"
+  "\x84\x3f\xad\xee\x82\x03\x06\x8f\x8c\x90\xec\x27\x0b\xe4\x3a\xca"
+  "\x87\xb1\xff\x9a\xf2\x08\x7f\x3f\xed\x8a\x6d\xe1\x81\xdb\x14\xbb"
+  "\xc1\x38\xd2\x47\xc2\xbb\x73\xed\xac\x65\x3f\x97\xe5\xa0\x0f\xe8"
+  "\xdb\xbc\xee\x5a\x92\x07\x1e\x30\x79\x65\xb2\xef\x70\x7b\x6e\x61"
+  "\xfb\x7b\xa0\x48\x9d\x23\x68\x6f\xb8\xf0\xd1\x5f\x73\xee\xe0\x18"
+  "\xc6\xe7\x40\xa7\x6c\x18\xf4\x83\x32\x9a\x93\x07\xaa\x7c\xfb\x69"
+  "\xb6\x4b\x32\x0b\x0c\x7a\xa7\x54\xe6\x6b\xfd\x9d\xd2\xab\xd3\x13"
+  "\xef\x86\xa9\xb4\x88\xe8\x67\x3d\xf0\xe5\xbd\x46\xde\xd7\x96\x71"
+  "\x95\xe4\x57\x73\x6d\x1e\xf9\x06\x7e\xf7\x10\xf9\x5d\x76\x59\xc6"
+  "\xd5\xb9\xcd\x06\x8a\xe9\xc2\x24\xcb\xb8\xa6\xd3\x26\xa6\x4d\x35"
+  "\x91\x1c\xda\x9c\x4f\x3c\x1e\x78\x56\xbd\x1c\x0d\xfa\x04\xeb\x7c"
+  "\x5d\x26\xd3\x3d\x9e\x81\xb2\xcd\x71\x31\xe4\x17\x99\x7c\x22\x93"
+  "\x5f\x73\xb7\x39\x2e\x1a\xbf\x87\x81\x9e\xd3\xcb\xfa\x71\xd5\x74"
+  "\x96\xed\x2e\x90\x81\xc7\xcd\xe4\x9b\x59\x6b\x73\x38\xd9\xba\x33"
+  "\x2c\x82\xfc\x2e\xbb\xb6\x9a\x4b\x1b\xba\x4e\x72\xfe\x66\x88\x89"
+  "\xc5\x80\xfe\x88\x45\x9f\x1b\xa4\x28\x33\xf8\x50\xf3\x46\xd1\xee"
+  "\xaf\x65\xd1\x6e\x51\x6f\xaa\xbf\xc0\xb8\xf1\x4d\x79\xbc\xee\xef"
+  "\x65\xba\x50\xbe\x64\x99\x74\xcc\x6d\x99\xd4\x28\xec\x57\xeb\x59"
+  "\x5e\x96\xdc\x66\xeb\xaa\x07\xcf\x75\x81\xc7\xa1\xa2\xb3\x72\x6a"
+  "\x23\xb5\x8f\xbe\x7d\xe4\xfc\x19\xee\x47\xda\x85\x7b\xf3\x62\xe5"
+  "\x9d\x0e\xbc\xd3\x51\xcf\x7a\x2c\x93\x78\xdb\x1b\xba\xc4\xbb\xa9"
+  "\xfc\x37\xbd\xef\xd3\x0f\x4a\x9b\x3d\xfd\x80\xb6\x53\xfb\xa8\xfd"
+  "\x2e\xea\x13\xf4\x81\xd2\x56\x43\xaf\xd2\x4e\x6a\xe3\x07\xd8\x75"
+  "\x5e\x40\x3b\xd1\x56\xde\xce\x5e\xb4\xb3\x2e\x83\x31\xe7\xb6\x57"
+  "\x1a\x2f\x45\x4f\x6a\x24\x1e\xd5\xfc\x21\x68\xf8\x5c\x0b\x03\x2f"
+  "\x1a\xba\x2f\xcf\xa2\x7d\x16\xb4\x49\x9e\x03\x3c\xa9\x43\x6e\x23"
+  "\x3d\x55\x9b\x09\x7f\xae\x32\x46\x34\x8e\x4a\xaf\xe3\xdb\x86\x23"
+  "\xd2\x29\x96\xd7\x26\xb7\x81\x36\x75\xda\x5c\xc8\x93\x81\xf6\x83"
+  "\x87\x3d\xad\xd4\x9f\xf2\xae\x3b\x27\xda\xa5\x5b\xcc\x62\xde\x7d"
+  "\xac\x48\x6b\x6b\x2a\x62\x6a\x5b\x52\x90\x0f\xed\x31\xa0\x2c\x1e"
+  "\x87\x46\x42\x3b\x77\xa2\x9e\x4e\x9f\x36\x1d\xed\x20\x5d\xd9\xe3"
+  "\x6c\xd0\x1c\xa6\x79\xe1\x2c\xda\x71\x96\x19\x2c\x79\xa0\xbf\x1e"
+  "\x24\x7a\xd1\xfa\xe2\x75\xc9\x6c\x94\x9d\xbd\x2b\xe2\xb5\x0a\x3f"
+  "\xaf\x43\xdb\xd9\x7b\x87\x55\x5f\xae\x12\xf9\xc2\x8e\x32\x97\xd1"
+  "\x3c\xe2\x7e\x5d\x69\xcf\xe8\xc6\x9c\xa1\x33\xed\x55\xf8\x46\x77"
+  "\xdc\x30\x5e\x9f\x02\xe1\x0b\x16\xf7\xe4\x2f\x9f\x6c\xc3\x34\x78"
+  "\xaf\x54\x46\x9f\x51\xf9\xa0\xe7\x36\xd2\x95\xfa\x30\xa0\x5e\xe9"
+  "\xab\x6c\xb2\x1c\x9d\x48\x7e\x79\xb5\x55\x79\x0e\xed\xd3\xaf\xb2"
+  "\x31\xfd\xc3\x94\xf7\x9c\xc1\xf0\x9b\x64\x99\x54\x1e\xda\x16\xdd"
+  "\xce\xfe\x7c\xd2\x7f\x8d\x19\x39\x96\x09\x1c\xfc\x73\x05\xc9\x0a"
+  "\xfb\xf7\xdd\x3f\x73\x1a\x8e\xf4\x11\xfa\xf9\x5e\xa5\x5a\x0f\xfc"
+  "\xbe\x4c\x8f\x48\xad\x7b\xff\xfb\xe1\x20\x0b\x56\xd6\xe6\x1d\x5c"
+  "\x67\xd0\x5c\xbc\x03\x78\x01\x5a\xe1\xa0\x81\xce\x1d\xb0\x77\x56"
+  "\x74\xb1\x15\xbb\x58\x84\xf9\x0c\xc9\x85\x66\xb1\x83\x65\xf1\x6c"
+  "\xf7\x79\xf2\xcf\x14\x17\xfd\xdc\x79\x8c\xa5\x82\x21\x44\x93\x92"
+  "\xcc\x55\x5e\x11\xa7\xdf\xb2\x43\xa5\xe1\x0f\x1e\xce\xbd\xc0\xb4"
+  "\x22\xf6\xf7\xc1\xba\x69\x46\xd9\x55\xa2\x95\x32\xca\xc8\xcf\x71"
+  "\x74\x05\xd1\x29\x19\xaa\xdf\x5f\x4e\xfb\xe4\x60\xcd\x75\x1a\x06"
+  "\x6d\x5e\xce\xc6\x90\x8f\x72\x9d\x43\xd0\x72\x62\xbf\x3e\x48\xba"
+  "\x9b\x7a\xc5\x17\xb0\x5e\xf1\x05\x9c\x40\x7a\xd5\xe2\x79\xed\xad"
+  "\x6e\xf0\x30\xbc\xdc\xe5\x6c\x54\xd9\x79\x16\x47\x74\x50\xea\x29"
+  "\x41\xb3\x11\x5f\x38\xab\x43\x27\xbb\xff\x1e\xc7\x76\xb5\x7b\x7d"
+  "\x98\x3b\x56\x90\xdf\x73\xd9\x10\x4c\x47\x78\xcb\x30\x7e\xf6\xce"
+  "\xfd\x52\x92\x4c\x1e\xf7\xac\x64\x1b\x0b\x3d\x48\x7a\x7c\xe5\xc2"
+  "\xde\xe8\xa0\x4b\xe8\xb4\x76\x17\xd4\x96\xaa\x3e\x9e\x83\x9e\x2d"
+  "\x5b\x04\xbf\x23\x85\x83\xff\x72\x74\x5b\x85\xbf\xbf\x5a\xbb\x6d"
+  "\xa3\xe4\xc3\xe3\xd4\xbe\x47\xcf\x28\x8d\x7c\x28\x25\xf0\xbe\x3c"
+  "\x14\x41\x7c\x8f\xc2\x33\xbe\x6b\xf4\xa4\x09\x1a\x86\xeb\x15\x1b"
+  "\xc4\x59\x19\xf6\xa6\x21\xdd\x05\x87\x46\xa9\xfb\x19\xed\xeb\x42"
+  "\x36\x7c\x68\xb2\x5d\xdb\x1e\xd4\x7f\x0e\x9d\x8d\x28\x7a\xd0\x74"
+  "\xce\x91\x80\xfc\x19\xea\xfe\xc6\xcf\x3b\x37\x8c\x48\x5c\xb1\x9a"
+  "\xc5\xfe\xfb\xf0\x08\x46\x67\x65\xc8\xdb\x26\xf6\xdd\x43\x16\xaf"
+  "\x3c\x3d\x81\xf7\x37\xd9\x03\x73\x1e\x83\xfc\xec\x09\x7f\xe5\x1d"
+  "\xaa\xbf\x3d\xb1\xff\x1e\xda\xe7\xf3\x9d\x46\xcf\x3e\x8a\x6f\x90"
+  "\x9e\x35\x95\x2f\x68\x93\x43\x1b\xb9\xcd\x18\xf2\x89\xfd\xf5\xd0"
+  "\xc6\x2b\xd0\x62\x71\xd4\xbf\x92\xc2\x4f\xda\x3a\xbe\x14\xfd\x9b"
+  "\xc3\x42\xc6\x95\x30\xc3\xbb\x79\xf6\xd0\x21\xc2\x8f\xae\xae\x85"
+  "\xbd\x7f\x33\x3d\xa7\xb9\x6e\x1d\x4b\xf2\xc0\xf7\xd7\xd9\x68\xdf"
+  "\xee\x4d\x8e\xbc\x9f\x78\x7d\x4e\x8b\xbf\xbf\xf8\x36\xbc\x87\xb4"
+  "\xe8\x03\x67\x9d\xa1\x5b\xd6\xb0\x31\xc2\x6f\xe1\xfb\x3c\x36\xb0"
+  "\xe3\xfa\x5f\x75\xff\x20\x86\x19\x7e\x50\xc2\xe2\xba\x0b\xde\x2f"
+  "\x01\x7f\x29\xf4\xdb\xe8\xfb\xdb\x6a\x8c\xe4\xab\xfd\xb5\x1e\x7b"
+  "\x98\x18\xab\xbf\x8c\xc7\x7d\x9c\xf7\xfe\xfd\xa3\xca\x59\x0a\xda"
+  "\xfe\x97\xf8\x3d\x67\x85\xbe\x38\x97\x2f\x59\x2a\xca\xbd\x67\xf5"
+  "\x7f\x19\x2f\xea\xf2\x97\xf1\x07\x81\x26\xbb\x76\xc8\xc7\x76\x0f"
+  "\x93\x1b\xbb\x0b\xfe\x12\x6a\x67\x87\xa6\x29\xf2\x98\x46\x3e\xaf"
+  "\x88\xde\x2d\x24\x1e\xec\x4b\xeb\x66\xe4\xa3\x7d\x02\xf4\x51\x82"
+  "\xa0\xe1\x2b\xaa\x25\xcc\x1f\x9f\xf6\xef\x22\x79\x63\x40\x4c\x7c"
+  "\x81\x31\xfe\xce\xd6\x97\x9c\x5c\xf7\x63\x6b\x4d\x0e\xae\x98\x6b"
+  "\x2f\x97\xe3\x1a\x89\x39\x57\x85\xab\x1e\xd7\x4a\x5c\x63\xf0\x3c"
+  "\x8d\xe6\x25\x78\x58\x03\xc5\x9b\xeb\x8c\x7a\xc9\x11\xcc\xf6\x87"
+  "\xfa\xc6\xb6\xf1\x61\x26\xf4\xdb\xea\x62\x28\xd6\xd8\xec\x5d\x8c"
+  "\xad\x70\xc9\x3d\xc6\x9b\xd8\x80\x16\xa4\x99\x77\xd1\xb9\xf3\x5f"
+  "\xda\xfc\xcf\x9d\xeb\x22\xf0\x97\x84\xbf\x32\xfc\xd5\xe3\x2f\xc6"
+  "\xfb\x77\x38\xa2\xbb\xa0\x2e\x06\xfd\x28\xfc\x41\xf4\x0b\x13\xeb"
+  "\xb8\xbd\xf8\x16\xe2\x8b\xa2\x36\x58\x45\x7b\xdf\x6e\xc4\x7d\x84"
+  "\x1c\x55\xa3\x57\xda\x6b\xc5\xbd\xde\x68\xc6\xbe\x16\x85\x3e\x19"
+  "\x81\x36\x47\xd5\xe4\x50\x7b\xa9\xbe\x9d\x51\x2f\x97\xfb\xda\x3d"
+  "\x51\x99\xd4\x7e\x47\x54\x05\x95\xc7\xe4\xb1\x53\xe3\xd5\xfe\x54"
+  "\xfa\x89\x6c\x42\xb4\x9d\x28\x43\xd0\x41\xc8\x8f\x32\xd4\xfc\x9e"
+  "\xbe\x1f\x41\x3e\xc0\x30\xa6\xc8\x07\x9e\x38\x42\xb5\xa9\xea\x2e"
+  "\x38\xcc\xde\x5b\x2c\xce\x33\xe8\xdd\x2e\x9f\x77\xc9\xcf\x47\xa0"
+  "\xf7\xf1\xcd\x08\xf1\xcd\x97\xcb\x4f\xb3\xba\xa1\xca\x77\xbb\x82"
+  "\xad\xa5\xbc\x9b\x41\xdf\x95\xd9\xc9\xfe\x87\xe8\xa1\x29\xb6\xd8"
+  "\x2e\x66\x2b\x93\xb0\xe7\x57\x34\x26\xe4\xc9\xd6\xd3\xec\xf0\x1b"
+  "\x0d\xce\xb6\x7e\xee\x87\x87\x05\x2f\xda\x93\xcf\x6c\xb9\x13\xb8"
+  "\xbe\xfa\x59\xf6\xc1\x29\x9b\x83\xdb\xd6\xd2\x6f\xee\xf3\x99\xce"
+  "\x9b\x69\x6f\x20\x1f\xf6\x2a\x8f\x2d\x21\xef\x6e\x4a\x47\x1a\xd9"
+  "\xff\xef\xf1\x79\x26\x6f\x7b\xa9\x49\xac\xa9\x0f\x76\x11\x6d\xc1"
+  "\xeb\xeb\x9a\x6e\xa5\x3a\x4b\x96\x97\x9a\xa8\x0d\x66\xf0\x7f\x14"
+  "\xe7\x8f\xd6\x84\x31\x9b\x64\x85\x1f\xac\xc6\xbc\x93\xa5\xad\x2f"
+  "\x35\xf5\xaf\x0d\x1f\x70\x3f\xec\x66\x97\x7c\xd6\x11\xf5\x52\x13"
+  "\xd1\x24\x5b\xf2\xc2\x22\xee\x2e\x93\xad\x9d\xd1\x15\x58\x97\x1f"
+  "\x94\xbd\x97\x23\xc6\xa6\x9f\xe5\x96\xa9\x6d\xdf\xad\xb4\x1d\xfd"
+  "\xc5\xcf\xa8\xc6\x95\x8a\xd8\x00\xc8\x73\x2c\xa8\xcc\x0a\xe3\x4c"
+  "\xf4\x00\xf6\x86\x4b\xa2\x2f\x8e\x8c\xf2\xec\x0d\xfd\xaa\xc7\x91"
+  "\x51\xd7\xf0\x8d\x5e\xe5\x1b\x45\xdf\xf0\x1b\x45\x57\xfa\x86\x38"
+  "\x6b\xae\x8f\xe9\x3f\xef\x78\xc4\xce\xe7\x8a\xa5\xc2\x2a\x30\xf3"
+  "\xe8\xd3\x6e\xf0\x6f\x2e\xfd\xdb\x8d\x44\xdb\x90\x5e\xa9\xcd\xee"
+  "\x62\x2e\xcb\x06\xeb\xd1\x9c\x1e\x66\xcd\xfe\x88\xb5\xb2\xfa\x59"
+  "\xf4\xce\xd1\x2c\xe2\xd9\x6a\xf4\xbd\xdb\x5e\x36\xf6\x6a\x8f\xa4"
+  "\x53\x7f\xef\xa2\x38\x0c\x3e\xf3\xac\xa1\xeb\x23\x66\x4b\x23\xf9"
+  "\x6a\x23\xc9\xb5\xf5\x72\xd4\xdb\x8d\x12\xb0\x01\x34\xba\x9b\xf7"
+  "\x07\xe8\x17\xc1\x6f\xbd\x52\xcd\xf9\x2d\x07\xf7\x4f\x3a\x18\x74"
+  "\x6f\xa4\x5c\xf0\x5c\x3a\xc9\xbe\xdd\xbd\xc9\xc6\xee\x02\x36\x87"
+  "\x62\x22\x90\xdc\x59\xd6\x4f\xb5\xcf\x76\x85\xc8\x9c\x9f\x02\xed"
+  "\x4f\xb1\x11\x6c\x5d\x76\xe6\x06\x1d\x5d\x76\x91\xc5\x94\x81\xf6"
+  "\x04\x66\xeb\x09\xd7\xf7\x28\xb1\x11\x36\x5f\xf4\xc6\x46\xd8\x4d"
+  "\xb2\x9e\x26\xfc\xbe\xc8\x42\xdd\x5b\x5f\xa9\xde\x79\x91\x8d\xda"
+  "\x95\xcd\xe2\x76\x92\x2c\xef\x2b\x41\xfb\x70\x3d\x70\x8a\x93\xb0"
+  "\x34\x8e\xce\x12\xbc\xb4\x0f\xd9\x82\x7b\x71\x2b\x94\xcb\x40\xfa"
+  "\xd5\xdf\x47\xf9\x3e\xe8\xb2\xbc\xe4\x74\xe9\x6b\x72\xd0\x77\xe5"
+  "\x76\x56\xbf\x11\xfd\x17\x50\xe6\xa5\xea\x93\x94\xf8\xc4\xb6\x78"
+  "\x6f\x94\xc0\x77\x94\x55\x17\x6c\x4e\xb8\x77\x26\xb3\x71\x1d\x2c"
+  "\x5e\xd8\x21\x0e\xc4\x9e\xd8\x30\x86\xf4\xff\xf2\x9e\x62\x06\xf7"
+  "\xce\x79\x1a\xf3\x8b\x2c\xc4\xe6\x4a\x60\xf4\x97\x77\x4e\x6e\x1b"
+  "\xb7\x98\xc5\xd3\xf9\x03\x9d\x95\x18\xd7\x52\xfe\xa3\xee\x51\xb9"
+  "\x2c\xde\xb7\xec\xa7\x56\x2f\xcf\x1c\x1f\xff\xcb\x85\xc6\x27\x33"
+  "\x97\x3f\xb5\x6a\xfe\xf2\x85\x2c\x49\xa8\x4d\x70\xd7\xcf\xab\x49"
+  "\x67\x62\x55\x66\x56\x86\xf1\x89\x95\xcb\x97\x2f\x5c\x92\x65\x9c"
+  "\x75\xf7\x9c\xcb\xfd\xff\xed\x34\x54\x70\x7f\xaf\x5c\x87\xce\x76"
+  "\x52\xfe\x8f\x1f\x5d\x2c\xce\x66\xa1\xba\xf5\xf7\xcc\xd5\xb9\x92"
+  "\x8c\x22\x3e\x12\xe6\xca\xb6\xa4\x5c\xd9\x9c\x5c\x2a\xe8\xd4\x46"
+  "\xe5\x4c\x21\x29\x5f\xd8\x56\x34\x0a\x99\x4c\x77\x52\xac\x58\x53"
+  "\xb6\xa8\x90\x2c\x46\xbf\x9f\xa2\xdf\xba\x2c\x56\x64\x1d\x41\xe7"
+  "\xe1\xb6\x28\x9e\x6f\xe7\x4c\x8d\x9a\x4f\xcd\x23\x9e\x37\xf0\xd8"
+  "\x89\xbb\xb9\x2f\xcc\x86\xc9\xe8\x9f\xe8\xee\x02\x5b\x9c\x3d\x74"
+  "\x6c\x82\x72\xbe\xde\x26\xf4\xf5\x1a\x19\xf9\xc3\x93\xff\xe3\x86"
+  "\x8b\x4a\x39\x69\xf8\xde\x75\xc8\x3b\x17\x63\xd0\xac\xe8\xf5\x8d"
+  "\x6c\x51\xea\x25\xf4\x4e\x1b\xee\x13\xfa\x1d\xb6\x1c\x1f\x7b\x6c"
+  "\x6e\x53\x4f\x7b\xa3\x42\x93\x76\x2b\xe5\x95\xa9\x98\x80\xfc\x14"
+  "\xff\xa6\xa8\xff\x58\x68\x13\xfc\x8f\x9f\x9f\x13\xa5\x9f\x76\x1a"
+  "\x7e\x0b\x7c\x88\x6d\x67\x0d\x96\xbe\xf3\xc5\x33\x82\x33\x96\x3c"
+  "\xb1\xf4\x29\xd3\xfc\xac\xcc\x05\x99\x8b\x33\xb3\x56\x73\x33\xf0"
+  "\x31\xfc\xdf\xbd\xa3\xd3\xe7\xf6\xf5\xdd\x3c\x86\x64\x2c\x8a\xcf"
+  "\xd7\x2e\xd2\x69\x10\x72\xae\xc6\xed\xae\x02\x36\xb2\x7f\xf5\x6e"
+  "\x4c\xe3\xf2\x60\xee\x7f\xa0\xb1\xc2\xae\xfd\x2a\x47\x39\xef\xe8"
+  "\x50\xfa\x9e\x3f\xef\xd4\xd7\x90\x1c\x76\x4a\x0b\x3b\x36\x8d\xce"
+  "\xb9\xd0\x7f\x55\xb4\x1f\x16\xaf\xa1\x7d\x0b\xa3\xe0\x9a\xa0\xc4"
+  "\x67\xfd\xf0\x75\xea\x03\xa2\x09\xd1\x07\x15\x2d\xec\xc3\xe1\xbc"
+  "\x0f\xbe\x36\x54\x70\xdf\x03\x5f\x1b\x7e\x4b\x73\x8b\xea\x2c\xc9"
+  "\xc9\x3b\x65\x39\xf9\x05\xe9\xeb\x8c\x9d\xf2\xd7\x19\x2f\x78\xfd"
+  "\xc6\x7d\xb8\x11\xef\xee\xc5\xbb\xcf\x50\x1c\x9a\xe2\xb3\x6c\x2f"
+  "\x9d\x7f\xd3\xbd\x2e\x4b\xcf\xdc\xfa\x8a\x4a\xaa\x8f\xad\x2d\x9e"
+  "\xd3\xdb\xad\xc8\x6f\xeb\x9a\xc0\x40\x4b\x56\x71\x9b\x46\x7e\x5e"
+  "\x07\x7a\x0f\xef\xd9\x50\x2f\x5b\x5b\x0f\xf1\xc4\x95\x12\x68\x3e"
+  "\xb4\x77\x3f\xf6\x4f\x07\x95\x4b\x6d\xe6\x76\xc5\xc3\x64\x7b\x77"
+  "\xc1\x87\xc0\x81\x06\x93\x42\x9b\x72\x7d\x0b\xea\x03\xff\xf1\xfc"
+  "\x90\xfb\x74\x40\x1f\x5f\x2f\x5b\xc6\x39\xc5\x98\x7e\xc8\x7d\x5d"
+  "\xcc\x6c\x95\xbf\xf6\xda\xb3\x7f\x78\x06\xf7\xbd\xf8\x93\x64\xcb"
+  "\x78\x83\xcf\xb9\x32\x9e\x7d\x34\x94\xd3\x6e\xc3\x64\x87\x69\x0d"
+  "\xc5\xed\xfe\xe8\x66\x31\x6f\xc6\x5f\xef\x30\x67\x84\xe0\x1d\x37"
+  "\xd9\x5f\x8a\xbe\xfc\x68\xaa\x6d\xe3\x59\x55\x4f\x03\xdf\xff\xe8"
+  "\x73\xeb\x93\x2e\xc6\xe3\x48\xb7\xba\xb8\xde\x9f\xe2\x63\x40\x23"
+  "\x15\x34\x92\x9f\x3d\x3d\x78\x3b\x3a\x8b\xe6\x3e\xd2\xbb\x0b\x3e"
+  "\xca\xf2\xd8\x89\xe9\x05\xbd\x47\x34\x17\xc5\xd8\xa2\xb9\x4f\xf4"
+  "\x1b\xd5\x89\xe6\x3e\xca\x2e\xa7\x33\x6a\xb1\x06\x3e\xda\xfb\xcd"
+  "\xd6\xc0\x47\x5c\xfe\x8b\xb2\x12\x64\xad\x59\x1e\xb7\x89\xa5\x71"
+  "\x1d\x02\x57\x17\xd9\xcd\x86\x62\xdf\x38\x26\xf0\xe4\xd8\x8d\x5c"
+  "\xcf\x24\xbb\xa3\x9c\x6c\x53\xf7\xf4\xb0\x48\xc9\x32\xb5\x89\xe8"
+  "\xec\xa3\xb9\x5c\xf7\x22\x02\xef\x55\x91\x6e\x06\xe9\xd2\x0d\xe1"
+  "\x71\xdb\x3e\x62\x7b\x2e\xb0\xd0\x56\xf6\xd7\x31\x74\x16\xe4\xed"
+  "\xeb\xbf\xae\xa7\xb3\x3f\x79\xdb\x58\x8b\x2e\x57\x5b\x44\x65\x48"
+  "\x17\xcf\x4c\x56\xdf\xa3\x18\xc1\xf4\x5e\x0b\xfb\xeb\x42\xfe\x1e"
+  "\xe5\x25\x1f\x4b\x79\xfa\x79\xa0\xb3\x9c\x94\xdf\x85\xfb\xdd\x92"
+  "\x7e\x8e\x8c\xfd\xc0\x9d\xed\xaa\xc2\xb3\xb9\x92\xe5\xe5\x72\xa4"
+  "\x25\xf3\x33\x88\x5e\x03\x9d\x4d\x62\x7e\x99\xab\x6c\xf6\x2f\xad"
+  "\xbc\x3e\x64\x4b\x9b\x85\xbd\x93\xf3\x25\x7f\x7d\x73\xf7\x57\x3c"
+  "\x9e\x1c\xc6\xf3\x98\xf0\x9d\x79\x96\x55\x8a\xfa\x1d\x9b\xd5\xb9"
+  "\x6d\x52\x63\x27\xe6\x66\x97\x36\x82\x1d\x34\x90\x2e\x79\x4d\xda"
+  "\x41\x43\x0f\xc6\xe7\x58\x0c\xb0\x4e\xa1\x89\xc5\x7b\xea\x9c\x0c"
+  "\x31\xe8\x93\xf0\x7c\xa2\xaa\x8f\xa4\xce\x47\x3b\xfb\x6b\x24\xf5"
+  "\x1b\xe6\x71\x53\xc3\x62\xd2\x2d\x93\xea\xf1\x2d\xe6\xce\x96\x9a"
+  "\xe9\x6c\x9c\xf4\xf6\x89\x9f\x99\x9d\x23\x77\x12\x7f\x46\xb6\x4e"
+  "\x74\x1e\x4e\x36\xdc\xbb\xc0\xdf\x52\xd9\x28\x77\x93\x6a\xcb\xbd"
+  "\x19\x69\x54\x36\xd9\x33\x15\x2f\xe2\x6b\x8d\x74\x38\x23\xf9\x99"
+  "\x40\xc8\xaf\xbe\xba\xbf\x4b\xee\x24\x7b\xf9\xfb\x4d\xb8\x2a\xe5"
+  "\x90\x9f\x1d\x94\xd1\xa8\x96\x21\x91\xfe\xeb\x72\xae\xe7\x66\x17"
+  "\xef\x0b\xfd\x9f\xfb\xbb\x24\x6e\x87\x42\xef\x0b\xbd\x9c\xe3\xa1"
+  "\x1e\x1d\x4a\x6e\x1b\x72\x3c\x46\xf5\xc3\x83\xdf\x46\x8f\x6d\x1b"
+  "\xfa\xaa\xd3\x52\x51\xd9\x85\x35\xde\x65\x79\x09\xbc\xfa\xf1\x29"
+  "\x40\x98\x8a\x2b\xca\x28\xc8\x7e\x7f\x25\xd3\x4a\xd1\x89\xa1\xe4"
+  "\x9b\x81\x6c\x3e\x85\xde\xf6\xf1\x5d\x8a\x9f\x86\x90\xb3\xec\xf8"
+  "\xa3\xde\xb3\x71\xb7\x22\xd7\x3d\x5e\x2b\xf8\x8a\xe3\xb5\x5c\xae"
+  "\xbb\xad\xc2\xf2\xd2\x1a\xa7\xb6\x6a\x8d\x5d\x2b\x74\x19\x8f\xe3"
+  "\xd9\xc9\x0e\xaf\x2e\xe3\xf1\x1c\x2a\x2b\x30\x1d\x38\x5d\xa1\xe9"
+  "\x3f\xe6\xf6\xb5\x5e\x3e\xfd\x63\xbe\xcf\xd1\x39\xb6\x44\x34\x5d"
+  "\xf4\x86\x46\xd2\x5b\xb2\x99\xce\x93\x7c\x37\x5c\xc8\x0c\x3e\x56"
+  "\xe2\x08\x73\x3d\xc5\xef\xb5\xfb\xdf\x47\xd3\xbd\xe8\xb3\x8f\x93"
+  "\xd4\xb3\xa2\x62\xad\x64\xd7\x69\x98\x6c\x2e\x07\xe6\x99\xba\xb8"
+  "\x7f\x00\x1b\x68\x44\x8a\x8d\x6d\x5a\x4e\xb6\x80\x1f\xaf\x23\xbf"
+  "\x01\x62\xcd\x7d\xcc\xed\x92\xa4\x82\xbb\x64\x33\xf1\x49\x0e\x8a"
+  "\xd5\x71\x9e\x21\x5f\x14\xf2\xbd\x52\x9b\xdb\x41\x7a\x5f\xf5\x14"
+  "\x27\xb2\x55\xf9\xb6\x23\x6a\x7a\xd3\x0f\x22\x59\x1a\xbe\x59\x63"
+  "\x67\xaf\x4c\xeb\x3f\x1e\x7c\x5c\x73\x25\x9a\x59\xd0\x70\x09\x2c"
+  "\x18\xdf\x4d\x72\x95\xb1\xf8\xfe\x2c\x99\xea\xff\xdf\xaf\xb8\xb4"
+  "\x4e\xd6\xab\x1d\x20\xff\x28\x3f\x87\xb9\x0a\x06\xc8\xee\x35\x18"
+  "\xaf\x4e\x03\xf8\xb2\x7a\xd6\x20\x74\x61\xe8\x3c\x5f\x97\xd7\x25"
+  "\x9f\xb7\xb9\xf6\x93\x5c\xdf\x81\xb1\x02\x1e\xfd\xf7\x8b\x36\xd7"
+  "\x3b\x8c\xf4\x93\x09\x47\x5a\xd8\x7f\x73\x7f\x4c\x63\x4d\xf9\xec"
+  "\xb6\xb3\xfc\xf9\x4c\x41\xcf\xfd\x77\xa5\x72\xcd\x21\xff\x98\xbe"
+  "\x75\xba\x77\xe5\x92\x27\xc8\xc9\xea\x6d\x33\x17\x66\x2f\x5c\x6c"
+  "\x7c\x90\x5c\xb0\xf6\xd1\x35\x8c\xf0\xc6\x15\x6b\xca\xa2\x3d\x92"
+  "\x68\x6a\x8a\x2f\xc6\x63\x8b\x15\x4c\xc4\x7a\x57\xe2\x8a\x11\x6d"
+  "\xfd\x4f\x88\x2d\xa6\xd2\xcc\x14\x57\xcc\x7b\x26\xf3\xc9\x44\xcf"
+  "\x1a\x90\xde\xed\xa6\x7b\xbe\x2f\x17\xfc\xf7\x7e\x5a\x47\x62\xdf"
+  "\x68\xda\xeb\xeb\xc3\x46\xd0\x4c\xe6\x2a\xa4\xd7\xaa\x36\x9b\x98"
+  "\x8b\x91\xb8\x3f\xe6\xb5\x11\x69\xb2\xa3\xdf\x8c\x62\xfd\xf2\xbc"
+  "\x0e\x55\x77\x41\x89\x19\xcd\x75\x2d\xa4\xc2\xeb\xf7\x0a\x79\x61"
+  "\xd3\x85\xdd\xd2\x80\x08\x71\x56\xf5\x49\xac\x6a\x83\x24\xd6\xe6"
+  "\xbb\xca\xda\xfc\x64\xe2\x95\xf4\x4b\xbc\x6b\xe3\x13\x93\x77\x5d"
+  "\x7f\xa6\xbe\x6b\xba\x9a\x6e\x8a\xc2\xb7\x0d\x6d\x67\x7f\x7b\x9a"
+  "\x64\x88\xc2\xe6\xf8\x6f\xdc\x27\xa5\xf0\x03\xf1\xb7\x19\xca\x6f"
+  "\x7c\xe3\x6f\xe3\x95\xdf\x37\xe0\xf7\x70\xe5\xf7\x08\xfc\xd6\x28"
+  "\xbf\xb1\x66\x4f\x7c\xa5\xfc\x8e\xc1\xef\x0f\x95\xdf\xd8\x13\x4e"
+  "\xbc\xa9\xfc\x1e\x86\xdf\x2f\x2a\xbf\x87\xe3\xf7\x33\xca\x6f\xac"
+  "\xc1\x13\xcb\x98\x38\xe7\x8f\x38\xcd\x4e\x3c\xde\x7f\x3e\xf2\x44"
+  "\x9c\x38\x4b\x3e\x01\x9e\xbb\x71\xb2\xd8\x53\x3c\x69\xb9\x18\x9b"
+  "\x7a\xb5\x7f\x91\x6e\xa4\xef\x20\xbd\xc4\xce\x6a\x2b\x7c\xd2\xf5"
+  "\x4a\x7e\xec\xff\xc7\x93\x7c\xd2\x43\x95\xf4\x5a\xf0\xab\x75\xde"
+  "\xf4\x4f\x9c\x4a\x7a\x33\xf2\x37\xfa\xa4\x77\x28\xe9\xc0\xcb\x03"
+  "\x4d\x3e\xe9\x76\x91\xfe\xb7\x48\x55\xaf\x46\x49\x3f\xa6\xa4\x8f"
+  "\xb2\xb3\x3f\x16\xf9\xa4\xd7\x29\xe9\xc0\xff\x4f\x12\x7c\xd2\x39"
+  "\xae\x08\x9f\xc4\x3a\xf9\x60\x2e\xad\xad\xbf\x81\xb6\xab\xc9\xf1"
+  "\xc9\x53\xa5\xbc\x9b\x63\x67\x6f\x97\xfb\xa4\x57\x28\xe9\x16\xbb"
+  "\x66\x50\x8c\x4f\x7a\x69\x30\xac\xd2\x94\xb2\xa0\x7e\x70\x89\x2f"
+  "\xe1\xfa\xc5\x9c\x56\x6e\x3e\x4a\x36\x4d\xba\x5d\x72\x8b\x31\x4f"
+  "\x96\x5b\x58\xf3\x7e\x45\x9f\x96\x7c\xc2\x74\x90\x7d\x58\x2b\x6b"
+  "\xde\xa5\xf8\x16\x70\x70\x9b\xb1\x35\x64\x33\xd6\xcc\x69\xc0\x71"
+  "\x39\xf9\xc2\x5f\xae\x1a\x7b\x81\x64\x4e\xca\x79\x3c\xf2\xcc\x20"
+  "\x19\x3c\x95\x43\x72\x69\x5b\x56\x8f\xf0\xa5\x0c\xde\x94\xd2\x48"
+  "\xf6\x42\xfd\xe1\x2b\x63\x12\xb8\xdf\x7c\x54\xea\x21\xbb\x4c\x21"
+  "\x9f\xa2\xb5\x48\xf9\x49\x87\xcc\x37\xaf\x9d\x35\x73\x9f\xd5\x21"
+  "\x86\xa8\xe7\xbb\x0b\x9a\xf7\x7a\xed\x61\x9a\x43\x95\xf4\x52\xa4"
+  "\xd7\x7a\xd3\xff\xe6\x08\x8e\xed\xc0\x3b\xfd\xd8\xa6\xde\x8b\x72"
+  "\x97\xeb\xa2\xec\x2c\xfe\x54\xe8\x92\x03\xeb\x6e\x72\x5b\xc6\xb6"
+  "\x91\xbd\x08\xc5\x64\x74\x65\xcb\x0e\xd2\x53\x44\xfa\x75\xf7\x77"
+  "\x39\x40\x63\x74\xcb\x9b\x17\x90\x4e\xea\x05\x46\xe7\xa5\xe6\x0e"
+  "\x8a\x97\xa5\x93\xc9\x0e\x79\xdd\x19\x16\x49\xf6\x24\xa4\x73\x4e"
+  "\x67\x99\xb3\x32\x1c\xec\x68\x86\x9b\xed\x46\xd9\xbb\x16\xa8\xf4"
+  "\xc5\xc9\x74\xaf\xad\xeb\x58\x3a\x5f\xbe\xc9\xcc\x63\xcf\x9e\xe4"
+  "\xbe\x7a\x75\xeb\xe9\x9c\xbf\xa6\x48\xfe\x33\xd1\xbc\x2f\xd9\x75"
+  "\xeb\x19\x68\x8e\x93\xe5\xf8\xdd\x28\xfe\xf0\x0c\xe9\xc1\xda\x24"
+  "\xd6\xf2\x49\xe1\x6f\xcd\x32\x2e\x59\xe0\xc5\xc9\x66\xf9\x3f\xc9"
+  "\x7e\xe2\xa4\x1d\x78\x53\x04\xfa\xba\x28\xd0\xfb\xeb\x76\x31\x6d"
+  "\xef\x36\xd0\x26\x67\xab\xb5\x02\x9f\x3e\xad\x97\xb4\x11\xeb\x49"
+  "\xfe\xcd\xe3\x4f\x6e\x4b\x8c\xd9\xbb\xc4\xa9\x3d\xba\xa6\x95\xad"
+  "\x1d\xce\x0c\xf3\x9c\x5a\xca\x33\x6b\x48\x16\xf9\xf4\xad\xb0\x80"
+  "\x4e\xd5\xfe\x01\xcf\x0f\x2c\xa9\xd6\xba\x38\xbd\xf2\x69\x3d\x97"
+  "\x99\x5a\xa6\xb6\xd1\x1e\x62\x6b\x72\x13\x8d\x1d\x09\x1a\xbb\x09"
+  "\xf8\x1f\xe1\x5e\x95\x11\xed\x5a\x91\x71\xdd\xae\xe5\x2c\xd2\xbd"
+  "\x22\x2e\xe6\xb9\x8b\x6c\xb2\xba\xff\xec\xca\xc6\x9e\xd2\x6d\x18"
+  "\xb4\x05\x7b\x0a\xc9\x62\x86\x68\xf4\xfc\x6c\x98\x7e\x4b\xda\xf7"
+  "\x5a\x77\x67\x5f\x39\x86\xae\x7b\x55\x1c\xf7\x97\x40\x75\x09\xd4"
+  "\xd6\x4d\x2f\xb0\x50\xb7\x62\x57\x99\x77\x8a\x0d\x03\x5d\xac\x1d"
+  "\x72\x41\xb6\xb6\x2f\x66\x5a\x8a\x3f\x9a\xb7\x90\xcb\x3b\xc3\x8e"
+  "\x66\xb8\x98\x2d\xe7\x04\xcb\x5b\x4e\x63\xf4\xd9\xcd\x44\xa7\x91"
+  "\x8e\x31\xf2\xeb\xdb\xd9\x67\xe3\x75\x4e\xec\x19\x4e\xd0\xda\x8b"
+  "\x88\xb7\xfd\xec\x1e\xe1\x9f\xe1\xb3\x22\xb2\x83\xb4\x2e\x4f\xa4"
+  "\xb4\xf9\xe6\x53\x5c\x97\xbc\x5e\xd8\x5e\x7e\x36\x85\xee\xcd\x64"
+  "\xe7\x19\x7d\xaf\xeb\xd5\x1e\x67\x98\x90\xa9\x7d\x76\xa7\xb2\x3f"
+  "\xe4\x0b\x9e\xed\xb3\xcb\x6c\xd4\x3c\xb2\x7e\xcb\x04\x3a\xb3\x1b"
+  "\x69\x2b\x23\xfa\x55\xb6\xf3\x73\x77\xb2\x79\xcf\xb9\xcb\x2a\x5f"
+  "\xb4\x28\x3e\x74\xec\x1a\x69\xeb\x04\xa7\xf0\x73\xf7\xd9\x25\x26"
+  "\x74\xe6\xb0\x47\xde\x1e\x21\xce\x1c\x6e\x37\x08\x19\xfc\xed\x71"
+  "\x1b\x46\x90\x8e\xbf\x9d\x75\x46\xdd\x3e\x19\x75\x3f\xd6\x19\xfd"
+  "\xf3\x80\xf1\xa9\xc4\x7e\x14\x1f\x67\xbc\x89\xc5\xd0\xd9\x4f\xaa"
+  "\x5b\xf8\x79\x14\x6b\xf8\x73\x94\xcd\x9f\x8d\x6c\x31\xb1\x10\xc1"
+  "\x1b\xda\x1f\x18\x57\xc6\x8c\xa8\xeb\x60\x59\x3f\xa1\x89\xeb\x22"
+  "\x5a\x26\xb4\xd9\x3a\x28\x4e\x8b\x9b\x89\x33\xba\xcf\xf5\x72\xd4"
+  "\x84\x26\x25\xff\x8b\x0d\x1d\x68\x83\x7e\x42\xa5\xcd\x79\x46\xa1"
+  "\x09\xed\x98\xfb\x13\x2a\x65\xcb\x84\x6a\x61\x2f\x6d\x3f\xa7\xe2"
+  "\xaa\x98\xa3\xf6\x53\xa2\xdf\xe2\xe3\x44\xbf\x7d\xae\x57\xf6\xab"
+  "\x91\xf4\x1b\x7b\x77\xbc\xd0\x29\xb1\x37\xab\x34\xb2\x5d\xc9\x43"
+  "\xef\xa0\xdd\x56\x81\xb5\x76\xa4\x7f\x56\x22\x9e\xdb\xcb\x29\x0d"
+  "\xed\xc3\x9e\x65\x9f\x4c\xed\x0a\x86\xad\xbc\x2f\x72\x59\x08\xea"
+  "\x5c\x47\xfa\xd7\x44\xa7\xd8\xba\xee\xb2\xda\xf8\x18\xb4\x3c\x4f"
+  "\xfa\xf6\xf4\x1d\xf2\x89\x43\xb8\x89\x32\x79\x3f\x79\xeb\xff\xf9"
+  "\x3a\xb5\x2e\xf4\x3d\x7a\x86\xb6\x56\x72\x7e\x19\x6d\xa6\x3c\x34"
+  "\xae\xa7\x4d\x24\x8b\xbb\x80\x3e\x23\xbd\xb6\x96\x4a\xea\x13\xd1"
+  "\x67\x2d\x1b\x15\x5e\x5d\x19\x87\x96\xd5\xfe\xfd\x21\xee\x25\x3d"
+  "\xb0\x61\x39\xe9\x37\xb5\x54\x2a\xfd\xa7\xc4\x18\x68\xe1\xbe\x15"
+  "\x94\x67\x83\x7d\xde\xbd\xd1\x93\x17\xf5\x26\xda\x88\x74\x05\xe8"
+  "\xec\x48\xcc\xd7\x96\xc9\x3e\xef\x4d\x4e\x3d\x47\x34\xf2\xd8\xca"
+  "\x0d\x3b\x78\xcc\xb6\xf8\xee\x82\x96\x99\xde\xfe\x16\xe5\x04\xf8"
+  "\xc6\x4d\xea\x37\x90\x27\x52\xad\x27\xc6\x47\xd9\x83\x5b\x2c\xde"
+  "\x31\xf9\xbc\x4a\x7d\x8f\xe4\x32\xb8\x9f\x47\xf1\x0f\x83\xf8\x85"
+  "\xd7\xd8\x62\x81\xc1\xae\xbb\xac\x7c\x3e\xb2\x2f\x22\x48\x77\x1c"
+  "\xfd\x5a\x27\xe6\x50\x8b\x22\x37\xfa\x22\x82\xca\xa4\xf3\x3f\x11"
+  "\x27\xe4\x0b\xac\x82\xcf\x63\xc5\xf7\xbe\x88\x11\x75\xf8\x02\xfc"
+  "\x9f\x3d\xb2\x2f\x5f\x97\x38\x3f\xdd\x38\x67\x3c\xb7\x19\xbd\x6d"
+  "\xa5\x89\xcc\x41\xd3\xbd\x37\xfe\x34\xb7\xde\xeb\x5b\xeb\x8b\x34"
+  "\x8f\x6f\x2d\xcb\x74\x97\xe8\xff\x2f\xf6\xca\x17\xe5\x12\xb2\xe7"
+  "\x90\xb3\xe5\xd2\x62\x8c\xa1\xf9\x02\xbb\x9e\xe2\xd0\xe6\x99\xe4"
+  "\x2f\xc9\xef\x9a\xac\x4f\x9c\x28\x5b\x12\x27\xe7\x5d\x60\x03\x48"
+  "\x57\x88\xf0\x87\xe4\x59\x72\x14\xd2\xb7\x26\x4e\xf6\xda\x91\x9d"
+  "\x26\x1d\x2e\x92\x89\x52\xfc\xf0\x99\x34\x1f\x48\x6f\xfc\x34\x3b"
+  "\x9d\x8c\x7c\x33\xf1\x2c\x6b\x33\x97\x11\x24\x5a\xdc\xfa\xe9\xc7"
+  "\xcc\x67\x58\x38\x8f\xf1\x95\xe3\x64\xc6\x45\x64\x6f\xd4\x3a\x18"
+  "\x65\x5a\x90\x3e\x84\xa7\x3b\x9d\xe4\x2b\xc0\x82\x67\x43\xf0\x6c"
+  "\x06\xae\x12\xca\xc8\x29\x46\xbd\xf3\xce\xb0\x9b\x50\x97\x36\x7c"
+  "\xc7\x82\x7a\x9e\x36\x3f\xc5\x86\x35\x98\xda\x88\xbf\x43\x79\x76"
+  "\xa6\xf8\xd3\xb0\xe0\xbd\x5d\x68\x57\x0e\xc9\x3a\x70\xcd\xdd\x8c"
+  "\x6b\x9e\x9b\x0d\xc9\x5b\x87\x7d\x6f\x1d\xbe\x4f\x76\x99\x28\x87"
+  "\x7c\x68\x88\xba\xa0\x6d\x24\x1b\x43\xb9\xeb\x3a\xe4\xd3\x28\xbb"
+  "\xed\x68\x07\xca\xcb\x69\xf2\x94\xa9\xd0\xd4\x58\xdf\xa7\x1f\x90"
+  "\xb7\xcd\x8c\x40\x9d\x4a\x49\x9f\x1a\x69\xc0\xe4\xd3\x33\xbd\xf4"
+  "\xf0\xe9\x59\xca\xef\x81\x9e\xbc\xe6\x64\x96\x77\x89\x19\xb8\x4e"
+  "\xc0\xaa\x10\xe0\xf1\xa9\x66\xf2\xd5\xe4\xf5\xdd\x79\xea\x38\xf2"
+  "\xe9\x51\xe6\x26\xa5\x4c\x4a\x6b\xf4\xd2\xcf\xa7\x54\x9a\x79\x90"
+  "\x27\xef\x65\x65\x9e\x5e\x4d\x65\x0a\xbf\x4a\x5f\x18\x85\x4d\xf2"
+  "\xa9\x79\x1e\x9f\x08\x17\xe5\x2a\xb2\xb9\x93\xb2\xe5\xfd\x24\x93"
+  "\x20\x59\x08\xf1\x2f\x64\x77\x97\xba\xba\x28\x9f\xcb\x23\x86\x09"
+  "\x99\xa9\xa0\x19\x4e\x95\x7a\x6c\x04\x76\xf0\x78\x04\xc2\xa6\x8e"
+  "\xec\xf4\x96\x73\x79\x4a\xf7\xec\xd5\xab\xcc\xf4\x3e\xbd\x8b\xfc"
+  "\x75\x5e\x5b\xa6\xd3\x39\x42\x76\x37\x93\x7c\x39\xe4\x38\xd4\x7a"
+  "\x15\x7c\x11\x2f\x64\xcf\xa7\xba\x3c\xf2\xb7\x6c\xb9\x96\xc6\x89"
+  "\xdb\x18\x92\x0e\xa0\x9b\x15\xa5\xba\x8a\x54\x5b\xe1\x8e\xee\x82"
+  "\xd3\x46\x1f\x5b\xe1\x0e\x5e\x87\x1e\x6e\x8f\xbf\x6a\xb6\x6b\x95"
+  "\x2c\x6c\x48\x4f\x4f\xf3\x7e\xbb\xd5\xa1\x7c\x3b\x82\x7e\x3b\x84"
+  "\x4f\x2c\xd2\x0d\x34\x0a\xbd\x8e\xd3\x26\x55\x97\x02\xeb\xad\x89"
+  "\xe6\x67\x60\xdf\xfd\xa7\x4b\xfd\xfd\xf3\x7c\x99\x41\xbe\xc3\x91"
+  "\xee\x63\xff\x7b\xfa\xaa\xf6\xbf\x66\x87\xfc\x39\xcd\x21\x13\x8f"
+  "\x43\xfb\x25\xb0\x76\xfa\x31\xe1\xff\xfe\x4b\x2e\x73\x69\x61\x5f"
+  "\xc6\xe1\x5e\x27\xce\x1d\xbe\x1c\xae\xe0\x4d\xd2\x6c\xb7\x4b\x67"
+  "\xc7\x37\xb9\xbf\x1f\xef\xbd\x9e\xfc\x17\x20\xdf\x0c\xe1\x37\xf8"
+  "\xcb\x88\x3e\xf9\xe9\x79\x7e\x9f\xfb\x84\x3e\xf7\xc6\x2e\xac\xc3"
+  "\x60\x3a\x23\x9b\x47\x70\x79\x64\xdb\x90\xf5\xcc\x64\xfe\x8a\x85"
+  "\x60\x7d\x9c\xa2\xba\x35\xb4\x71\x7b\x32\x9d\x5c\x10\xcf\x6c\x6d"
+  "\x2e\x41\x8b\x82\x06\x68\x19\x85\x3c\x5f\xb1\x61\x64\xcf\x40\xf1"
+  "\x01\x90\xbf\x5d\xc4\x04\x68\x3b\x37\x6f\xe5\x20\x26\xfd\x32\xf9"
+  "\x3a\x59\xbb\x80\xce\xc9\x23\xf6\xf5\xd8\xc9\xaf\xbe\x26\xef\x79"
+  "\x16\x4b\x6b\x0f\x6b\xb0\x55\xd6\x3e\x51\x8d\x77\x3a\x5e\xea\x69"
+  "\x0b\xb3\xb9\x4e\x30\x13\x30\xa1\x9d\xb5\xb5\x86\xe6\xb2\xd0\x2d"
+  "\xa7\x99\x1e\xf3\xcc\x75\xd0\x35\x99\xa9\xf6\xf7\x65\xd1\xc2\xae"
+  "\xbb\x0c\x73\x72\x85\x41\x76\x76\x17\xb4\x25\x80\x57\x9b\xab\xf2"
+  "\xe4\x9b\x84\xff\xad\x50\x7c\x7f\x1f\xf7\x15\x20\xf6\x3c\xf4\x6d"
+  "\xdb\x3a\x61\xcf\x18\x73\x3d\xde\xc9\xf2\xd2\xeb\x5f\x89\xb3\x08"
+  "\xcb\x74\xc5\x0e\xfa\x2b\x76\x30\x9d\xf1\x98\x46\x9d\xdc\x3f\x7a"
+  "\x5b\xb9\x47\xf7\x86\xcb\xb9\xbe\x02\x1e\x4c\x77\x0a\x5a\x7e\xba"
+  "\x33\xd5\x1d\xa1\xd0\x0c\x5f\xf1\xbd\x88\xde\xc5\x7b\x3a\x11\xbb"
+  "\xac\xad\xd9\x3b\xd7\xda\x2a\x68\x8f\x40\x9b\xc0\xe3\xb5\x19\xa8"
+  "\x5d\xd4\x27\x5d\xdc\xd7\x56\x5b\xec\xc1\x8a\x20\xb1\x2d\xf4\xe3"
+  "\x92\x5d\x5c\x66\x52\x51\x84\xf9\x74\x06\x63\xf0\x3d\xf2\x37\x64"
+  "\xc3\x77\x8e\xee\xee\x61\x47\x0d\x9d\xac\x01\xbf\x49\xc7\xde\xba"
+  "\xe8\x0b\xd6\x6a\x0c\xbc\x3f\x61\x8f\x6b\x42\x9d\xdb\xa8\x2c\xc2"
+  "\x37\xd2\x4b\xb4\xe5\x32\x7e\xd2\x64\x6b\x65\xbc\x8c\xa3\x52\x1b"
+  "\x3b\x9a\x43\x7c\x59\x4d\x51\xc3\xee\x13\xac\xc1\xf0\x57\xfe\x1d"
+  "\xa2\x21\xad\xcb\x3b\xaf\x54\x36\xfa\x63\x5c\x84\x52\x76\x07\xca"
+  "\x8e\x09\x5e\xf6\x4b\xf6\x7e\x96\xdd\x8f\x7a\xbf\xd4\xd8\x9f\xb2"
+  "\xcd\xa5\xb2\x1b\x7b\xc2\x60\xd0\xc9\x4d\xe4\xeb\x92\x6c\x29\xdd"
+  "\x17\xc9\x4f\xc8\x48\x59\xe8\x7a\xb7\x7f\x42\x78\xc3\xf5\x10\xb6"
+  "\x4e\x3d\xc6\xed\x2c\x49\x76\xac\xd8\x57\xda\x5c\xa7\x18\xc9\x92"
+  "\xbb\x0b\xda\x6b\xbd\xfc\x95\xe7\x0c\x16\xd8\xd7\xde\x26\x74\x7a"
+  "\xa7\x1e\x13\x73\xab\x9d\xeb\x34\x04\xe6\xa3\x12\x3b\x84\x6e\xf8"
+  "\xdf\x6f\x56\x65\x36\x9d\x51\x89\x1d\x4a\x59\xc6\xbe\xb2\x40\xc5"
+  "\xb9\x8b\x71\x61\x4e\x96\x71\xd5\xf2\xcc\xac\x85\xaa\x21\xf0\x20"
+  "\xf6\xe0\xc2\x27\x16\x66\x66\x2f\x4c\x37\xce\x5d\xb9\x7c\xc9\x6d"
+  "\x4b\x9f\x7c\xd2\x38\x6b\xe1\x8a\x15\xf3\x7f\xb9\x70\x10\x9b\xbb"
+  "\x7c\xfe\x92\x15\x99\x24\xaf\x33\x1a\xa7\xdd\x9e\x9a\xb1\x34\xeb"
+  "\xb6\x9f\x4d\x8b\xef\x23\xaf\x23\xbb\xe0\x66\xa2\xdb\xb1\x57\x0e"
+  "\xc3\xbe\x19\x45\xbe\x62\x74\xab\x65\xeb\x5a\xf0\x8c\x98\x83\xed"
+  "\xb4\xe7\x60\xed\x7e\x4e\xfc\x04\xf9\x8a\x25\xff\xb3\x3b\x77\xc8"
+  "\x8d\xa7\x99\xfb\x13\xd0\xa2\x4d\x48\x23\xbe\xbe\x19\x7c\xbc\x83"
+  "\xc6\x00\xe9\x6f\x20\x4f\xed\x6f\x90\xe6\x88\x9a\xee\xdc\xf2\x29"
+  "\x0b\x15\xfb\x66\xc7\x44\x59\x3b\x40\xde\x44\x7e\x5b\xbf\x30\x30"
+  "\xc5\x1f\xb4\xd6\x66\x77\x92\xae\x4a\xc4\x6c\x97\x59\x26\x4c\x15"
+  "\xeb\xab\x43\xc4\x48\x01\x1f\x22\x74\xe6\xdd\xdb\x89\xef\xd9\xc0"
+  "\x63\x69\x75\x00\xff\x3f\x6d\xf2\x62\xf5\x85\x5c\x85\xde\x24\xb9"
+  "\xf3\xaa\x16\xdc\x0b\xff\x17\x1d\x7d\xfc\x5f\x9c\x9d\xc3\xd8\xa5"
+  "\x6a\xf1\x47\xef\x5c\xaa\x15\x7f\xf4\xdb\xf7\xcf\x9d\x23\xfe\xfa"
+  "\xa6\xff\xa3\x7f\xea\xf7\xbf\xe9\xfb\x17\x27\x5e\xf9\xef\x5a\xbe"
+  "\xcf\xdb\xfd\x1d\xb6\xff\x1f\x79\xff\xe2\x94\x2b\xfd\xd1\x7c\xc3"
+  "\xdc\x6a\xfe\xcd\xa7\x2c\x02\xf3\xb3\x64\xf3\x02\xcc\xe9\x93\xcc"
+  "\x90\xeb\x92\x5b\xcd\x8f\xb3\xd8\xbc\xaf\x98\x96\xe8\xbf\xac\x1c"
+  "\xb9\x35\xef\x22\xf1\xda\x17\x07\x63\xfe\x56\x17\xb7\xb0\xc8\xcd"
+  "\x2d\x4c\xdf\x90\x25\x62\x30\xd0\x19\x0a\xd9\x13\xd9\x70\x5f\x9f"
+  "\xed\x64\x47\x1c\xe7\x48\x77\xcf\xda\x90\x06\xec\x69\x66\x8c\xe6"
+  "\x6f\x64\x1a\x8b\x29\x1b\x26\xd7\xc8\x05\xcf\xcd\x95\xb5\xcf\x4d"
+  "\x43\xda\xb1\xd7\xa4\x84\xb0\xd7\xd6\xd4\x85\x19\x17\xd0\x3e\x7f"
+  "\xf6\x82\x32\x37\xd7\x09\x7b\xb9\x0b\x9c\x07\x53\xfc\xf5\x62\x7f"
+  "\xba\x70\x49\xec\xe9\x17\x0e\x2b\x32\x2a\xfa\xcd\x65\xae\x68\x47"
+  "\xb5\x5c\xb0\xa0\x9a\xca\x7c\x55\xaa\x0e\xa3\x3d\xf3\xb5\x35\x09"
+  "\x61\xb9\xf3\x99\xb6\xc1\xde\xce\x0e\x02\x0b\xe9\xdc\x16\xeb\x6e"
+  "\x2f\xd6\x59\xd5\xae\x61\xb2\x05\xf5\xdb\x04\x7a\xae\x08\x75\xaa"
+  "\xec\x2e\xf8\x3a\x1d\xfb\xd6\x5c\x85\x96\xb3\x62\x5d\xec\xdd\x8c"
+  "\x3c\xb3\x57\xb2\x91\x9b\x91\x0f\xb4\x5d\x11\xd1\xdd\xa2\x7e\x9d"
+  "\x8f\xa3\x0f\xf6\xe3\x9b\x8d\xc6\x14\xba\x3f\xc7\x69\x0c\xfa\x36"
+  "\xda\x61\x6c\x61\x0e\xee\x0f\x87\xbe\xa1\x7e\x17\xe5\x03\xff\xda"
+  "\x23\x95\x73\x33\x8b\x28\xe7\x6b\x41\x87\x59\x12\xe7\x51\x5c\x38"
+  "\xc5\x1e\x69\xde\xe6\x35\xd8\xd7\x7b\x58\x04\xbe\x51\x82\x6f\x58"
+  "\x75\xeb\x99\xac\x23\x5b\xd6\x66\x17\x68\x75\x49\xd1\x13\x75\x1c"
+  "\x17\xef\x0a\x3a\x84\xd3\x1e\x6e\xa6\x13\x32\x07\xd0\x1f\x19\xc0"
+  "\x09\xd0\x1c\xdc\x0e\x00\xf4\x06\xa5\xe3\x1b\x25\x68\x57\x23\x78"
+  "\xc1\xfd\xd8\xbb\xab\x88\x56\x48\xb9\x70\x1f\xe3\x31\xb1\x41\x2f"
+  "\xac\xc8\x91\x9d\x22\x46\x96\xc3\xa4\xd2\x0b\x34\x3f\x88\x46\xd8"
+  "\x9c\xc2\x42\x7b\x31\xc6\x98\x23\x75\xa0\x3f\x40\x7b\x3b\xf6\x2a"
+  "\x63\x53\xc7\xe9\x02\x25\x36\xa8\xc0\x70\xc7\x9b\xd8\xdf\x23\xf1"
+  "\x0d\xd0\xbb\x6e\xd5\x97\x12\x30\xc8\x51\xa7\xee\xf5\x22\xbe\xb5"
+  "\x63\xaf\x0c\xac\x43\xbf\xed\x1f\x93\xa6\x01\x8f\xe7\xd0\x63\x2c"
+  "\xf6\x53\x5e\xf2\xf5\x80\xfc\x4e\xd0\x63\x39\xca\x98\x34\x6f\xce"
+  "\x26\x3a\xc0\x91\x4f\xf5\xc0\x3b\xf5\xe8\x6b\x1a\x0b\x25\x6e\xa0"
+  "\x7c\x4c\xd0\x30\x9d\xc3\xd5\xbe\xc7\x58\x6f\xf4\xf6\xff\xb9\x69"
+  "\xbe\xfd\x8f\xbe\xd8\x28\xc6\xe0\xfc\x21\x9f\xb1\x03\xaf\x75\xbe"
+  "\x8c\x64\xab\xf8\x5e\x8d\x90\x0b\x9d\x5b\x47\xfe\xb8\x30\x67\x6a"
+  "\xd0\x17\x35\xc8\x57\x4d\xd8\xbc\xe1\x53\x60\xee\x02\xa2\xa1\xce"
+  "\x3f\x2d\x68\xd4\xf3\xa3\x68\x0e\xe3\x9e\xf3\xd1\xad\xcc\xb1\x91"
+  "\xca\xc3\xdc\xb8\x80\x2b\x68\xd9\x73\x67\xcc\x65\x14\xb3\x32\xb1"
+  "\x92\xfc\x65\x29\x63\x8d\x79\x77\xce\xe3\xff\x88\xe6\x00\x8d\x3d"
+  "\xda\xb8\x51\xf0\xde\xe7\x9a\x49\x7e\xc6\xdf\xeb\xcd\xa0\x3a\x36"
+  "\xd3\xfa\x54\x9f\x23\xbd\x8d\xfc\x98\xfa\xf4\xcd\x46\x65\x4c\xaa"
+  "\x45\xfc\xb7\xf3\xeb\x94\xba\x25\xe3\x3e\x02\x75\xe0\x32\x95\xce"
+  "\xde\x8c\x90\x2d\xf4\x4e\x9e\xf7\x1d\x5a\x3f\x98\xcb\x3a\xbc\xb3"
+  "\x12\x57\x59\xcd\x4b\x3e\xc8\x51\x0f\xd7\x73\xdc\x9f\xd4\xf9\x98"
+  "\xce\xde\x38\x2d\xbe\xeb\xc4\x77\xb5\x34\x37\x68\x5e\xa8\x65\x6c"
+  "\x11\x7d\xb4\x17\xe3\xc7\xe7\xd7\x41\x57\x35\xfa\xfd\x3c\xe8\xff"
+  "\xbf\x59\x05\x7d\x77\xce\xa5\xd4\xcf\x2a\xe2\x12\xfc\x7d\xcc\x6e"
+  "\xe1\xfb\x85\xf2\x79\xe2\xdf\x78\xe9\xcc\x73\xdc\x4f\x14\xca\xaa"
+  "\x57\xe6\x84\xae\xbb\xa0\x33\xd2\x33\x87\xb8\x5d\xfd\xf9\x4d\x44"
+  "\x6b\x2a\xf5\xa7\xb9\xf7\xb4\xd2\x77\x63\x68\x0e\x80\x8e\x77\x8a"
+  "\x71\x76\x6c\x24\x5a\x55\xcc\xc3\xce\x39\x6a\x19\xc2\x36\xff\x5c"
+  "\xb3\x84\x32\xd4\xb9\xe2\x8b\x0d\xc8\x9b\x0b\x5c\xf0\xcc\x1b\x15"
+  "\x0b\x44\x99\x5d\x6f\x28\x74\x48\x11\xc6\x86\x7c\x5f\x5b\xb9\x6f"
+  "\x22\x3e\x2f\xbb\x8a\x0e\x76\xb9\xd8\x6f\x68\x5e\xa6\x10\x26\x74"
+  "\x9e\xea\x8c\x9e\x69\xf0\xce\xed\xce\x63\xea\xdc\xf6\x19\x57\x3e"
+  "\xb7\x37\x72\x3c\xea\x04\x1d\x3d\x4e\x3d\x3b\x6e\xa6\x75\x2e\x61"
+  "\x5d\x6f\xc9\xe6\x32\x6f\x1d\xc9\xb8\xf8\xba\x77\x76\x70\x1e\x83"
+  "\xc6\xb3\x21\xa7\x95\xfb\x1b\xdf\x20\xb1\x88\x86\xae\x53\xc4\xf3"
+  "\xb7\xd3\xfa\x57\xd7\x38\x8d\x0d\xbe\x65\x25\x9f\xf0\x1b\x81\x81"
+  "\xb4\x06\xbb\x50\x27\x8a\x83\x4e\x7e\xba\x6a\xe7\x25\xb0\x15\x18"
+  "\xdb\x83\x69\x34\x6e\x5d\x59\xaa\x6e\xff\x16\x81\x01\x91\xca\x7c"
+  "\xe1\x75\xec\xd3\xaf\x3a\xd1\xaf\x5d\x95\xfe\xeb\xfb\x7c\x12\xad"
+  "\x6f\xdf\x7e\xa5\x3e\xa5\xbe\x45\x5e\xb4\xff\xab\x2a\xb5\x5f\xbd"
+  "\x7d\x7a\xe1\x1e\x65\x3e\x2a\xd8\x7a\x21\x20\xb6\x6e\x11\xfe\xf7"
+  "\xab\x37\x50\x5b\xb0\xa7\xd0\xf7\x79\x7c\x19\x85\xf7\xa9\x75\xd0"
+  "\x9c\xba\x30\xd9\xce\xd2\x93\x54\x1c\x43\x7d\x2c\x34\x9f\x68\xac"
+  "\x54\xec\x20\xf9\x8f\xa8\xfb\x85\x74\x75\x3c\xa8\xde\xbe\x98\x80"
+  "\x3a\xbc\x4e\xf7\xde\x36\x5f\xd8\x8e\xf7\xa2\x09\xdb\xbc\xf4\xd5"
+  "\x85\x0a\xff\xb6\x5f\xd8\x44\x6d\xa7\x39\x61\xca\x26\x19\x90\xd8"
+  "\xcb\xec\xec\x6b\x83\x3f\x5e\x7d\x3d\x58\xe8\x1a\x08\x7a\x8c\xf0"
+  "\xde\x94\x22\xf2\xd3\xfe\x86\xfc\x5c\x26\xaa\xec\x87\xb9\xb4\xff"
+  "\x21\x2d\x54\xe9\x83\x66\xe4\xaf\x25\x7b\x61\xf2\x19\x73\x5d\xb3"
+  "\xe0\x05\x81\xd1\x35\x14\x87\xc0\xce\xce\xd6\x36\xa0\x54\x57\x38"
+  "\x63\x65\x0a\xbd\x49\x38\x21\xaf\x4a\xbe\x6e\x55\x1b\x1b\x68\xfa"
+  "\x99\xfc\x05\xf6\xf3\xf7\xb0\x8e\x9c\xe4\xc3\x10\x65\x1b\x4f\xb3"
+  "\x4b\x2f\xe2\xbb\x31\xca\xd5\x80\xeb\x33\xb8\x0e\xc7\x75\x19\xae"
+  "\x37\xe0\xfa\x28\xf2\x4b\x4a\xfe\x78\xdc\x4f\x45\xfa\xed\xca\x15"
+  "\x75\xbc\x58\x8d\xeb\x9c\xdf\x10\x5d\x99\xc2\xd3\x87\xd2\x3d\xae"
+  "\x61\x4a\xbb\xeb\xc5\xda\xbe\x78\x0a\xe5\xe4\x50\x3e\xda\xd7\x90"
+  "\x66\x3a\xcd\x9c\x87\xa9\x6c\xb2\xdf\xc7\xef\x75\x3e\xf4\x29\xca"
+  "\xe9\x7e\x05\xd7\x89\xb8\x3e\x85\x6b\x16\xae\xe3\xa9\x5c\xf4\x41"
+  "\xa3\x17\x2f\x1c\x1b\xd3\x73\xc4\x78\xda\x59\x27\xf1\x98\x31\x2a"
+  "\x1e\xd0\x7c\xf2\xcb\x37\x4f\xe4\x13\xfc\x6b\x77\x9a\x3a\x76\x2e"
+  "\x31\x6f\x63\x5c\x18\x3b\x94\x3f\x95\xde\xc7\xf5\x6e\xe5\x9a\xa0"
+  "\x5c\xef\x51\xae\xd3\x95\xeb\x34\xe5\x9a\x64\x67\xdd\xf1\x0a\x6d"
+  "\x82\x3e\xeb\x8e\xa7\x3e\x01\xe6\x2b\xfe\xb6\x9c\xe9\xc4\x5f\x03"
+  "\xff\xef\xe8\xa4\x98\x62\x05\xdd\x4d\xaa\x2c\x96\x64\x3f\xbd\x05"
+  "\x7f\x9f\xbe\x93\xcb\x7e\xba\x1d\x3e\x58\x58\x17\xa9\x49\x60\xa0"
+  "\x9d\xc2\xcb\xb4\xa0\x1b\x44\x39\x49\x5a\xe5\x0c\x9a\x62\x6b\x50"
+  "\xac\x34\xf2\x1d\xc7\xf9\xa8\xa8\xb7\x9d\xb4\x5e\xb9\x9c\x7a\x2b"
+  "\xf9\xc2\x99\x5e\x8f\xbf\x26\xf0\x14\x1e\xbc\x27\x7e\x49\xf1\x11"
+  "\x79\xa0\xbb\xc0\x39\xcf\xcb\xe7\x3b\x23\xc5\x79\xdd\xf5\x37\x23"
+  "\xdd\x87\xff\xef\xae\xa3\x3a\xa3\xaf\x9b\xd0\x9e\x89\x2d\xcc\x59"
+  "\x86\xeb\x84\x56\xd1\xe6\x78\xb5\xcd\xca\x58\x99\xd4\x3e\x6f\x65"
+  "\xdd\x93\x81\x87\xcb\x69\x7e\xb7\x78\x70\xb9\x9b\xcb\xa7\x95\xf9"
+  "\x83\x71\xbe\xf8\x15\x8d\xb7\x0f\x9e\xe4\x7a\x71\xda\xe9\xf4\x1f"
+  "\x17\x87\xd3\x25\xe8\x85\x26\xac\x4b\xcc\x81\x8b\xd6\x3e\xeb\x72"
+  "\x13\xad\x4b\xf1\xee\xa5\x89\xfe\x18\x7f\x61\x13\x61\xbc\x52\x47"
+  "\xcc\xdb\x8b\xe5\x34\x36\x76\x76\x29\x46\xd9\x93\x9a\xb0\x47\xde"
+  "\x81\xf4\x22\x51\x4f\x91\xae\x7c\x0b\xf3\xef\x62\x3e\xcd\x7f\x35"
+  "\x5d\x99\xdf\x54\x4e\x0e\x8d\xb5\x9a\xae\x94\x8f\x79\x7a\xd1\x44"
+  "\xeb\x47\x4d\x57\xe6\x64\x1d\xe1\x0d\xbd\xeb\xe2\x7a\x77\xe0\xbf"
+  "\x53\x6a\x51\xef\x4b\x24\x53\x2c\xa7\xf5\xbc\x61\x0d\x8b\x5c\x55"
+  "\xca\x06\x8b\xb5\xd9\x33\x54\x7d\x57\xc8\xa9\x7b\x22\x54\x8c\xda"
+  "\xc2\xf1\xac\x2b\xd7\x1f\x2b\x5d\x2f\xcb\x05\x3a\x97\x4b\x3f\xbd"
+  "\xf6\xa8\x6b\x22\xc7\x5c\xac\xfb\x32\xbc\x97\x60\x67\xcf\x31\x65"
+  "\x2f\xa9\x17\xe7\x04\x3d\x2b\x8f\x96\x0b\xec\x52\xca\xf6\xe0\x9f"
+  "\x0f\x1d\xc2\xb1\x9e\xbe\x45\x65\x61\x5f\xd1\x77\x99\x93\xaf\x13"
+  "\xf8\xdd\x53\x62\x67\xd7\x8d\x52\xb1\x95\xf6\x27\x9d\x86\x99\x8a"
+  "\x53\xc4\xfe\x24\x91\x0c\xcc\xd4\xc5\x7d\x7f\x35\x98\x3a\x18\xed"
+  "\x9b\xe4\x93\x39\x75\xf5\x20\xf2\x8d\x94\x8c\xba\x3e\x03\xfa\xac"
+  "\x42\x39\x6f\x00\x9f\xeb\xfa\x09\xf1\xb2\x4a\xbf\x62\x3d\xb9\x6e"
+  "\x54\xc6\xa5\x19\xf5\xa9\x20\x6c\xdf\x90\x2d\xe2\xd3\x90\x3c\x88"
+  "\xc7\x33\x22\x9a\xd5\x20\x3b\x85\x7f\xf9\xde\x51\x3e\x32\xae\x72"
+  "\xb1\x4e\x7a\x06\xf2\xd8\x00\x96\xe9\xb5\x42\x9e\xd8\xfb\xba\x48"
+  "\xef\x55\x7c\x55\x71\xdf\x8f\x74\x9f\x1f\x62\x18\xf6\x6b\x21\x17"
+  "\xfe\xfb\x02\x41\x8f\xf4\x66\xf9\xe8\xb1\xf0\xbe\x16\xbe\x67\x7b"
+  "\x37\x79\xd7\x45\x6f\x1a\xbd\x83\x77\x5f\x40\xba\xc7\xff\x97\xd8"
+  "\x6b\x1c\x39\x8a\xcc\xac\xee\xba\xf5\x09\x0c\xd8\x1c\xbe\xb3\x40"
+  "\x5d\xbf\xae\x50\xf1\x7d\xb1\x7e\xa9\x8d\x34\x1f\x68\x0d\xbb\xb8"
+  "\xff\xaa\xb7\x9d\xb4\x96\xf1\xbb\xde\xa5\xae\x5d\x41\xdf\xe5\xf2"
+  "\xb5\xcb\xd7\xad\x2b\xc6\xa7\x1e\xf5\xca\x5c\x6d\xee\x7c\xc2\x10"
+  "\x89\x67\x58\x93\xed\x8a\x7f\xa0\x1e\xc1\x63\x6c\x8d\x8f\x93\x2e"
+  "\xca\x4e\x92\x4d\x93\x3c\x81\x64\x36\x8a\x6e\x25\xc9\xff\xbb\xc8"
+  "\x27\x97\x05\xeb\xc1\xeb\x87\x4b\xcf\x54\x3f\x5c\x28\x2f\xdf\x2b"
+  "\x3b\xee\xb1\x2b\xed\xaa\xc5\xf7\xca\xac\x79\x7f\xa6\x7e\xfe\x50"
+  "\xac\xb1\x9e\x46\x9a\xc7\x36\xcc\x3d\xec\x3f\xa5\x14\xef\x1c\xef"
+  "\xd6\xa8\x73\x0f\x6b\x34\xfd\x34\x73\xcf\x2a\x19\x26\x97\x62\x4c"
+  "\x49\x3f\x7c\x31\xee\x7f\x82\x6b\xba\xb8\x6a\xf4\x74\x55\xe6\x7c"
+  "\x29\xde\xc5\xfa\x1f\x54\xa7\x8e\x41\x57\x54\x05\xe3\x73\x2c\x8f"
+  "\x74\xf6\xe2\xf9\xf9\x35\xcd\x31\x9a\x5f\xfc\x1c\x1b\x73\x4d\xb7"
+  "\xfe\x3e\x46\xf3\x8c\xfb\xe6\xc0\x3d\xd5\x97\xe6\x59\x77\x81\x7b"
+  "\x9a\xea\x87\xd6\xce\x5c\x6d\xe2\x0c\xc9\x9d\xac\xea\x2c\xd3\x3c"
+  "\xcc\xba\x99\x0d\x45\xf9\xc6\x5a\x63\x17\xc9\xce\x3f\xb3\xb9\xee"
+  "\x61\x94\x97\xfa\x4e\xe0\xe5\xf5\x59\x78\xc7\x67\xfc\x1d\x5c\x87"
+  "\xe5\xe0\x3c\x2e\xcf\xfc\x1e\x9e\x55\xfa\x63\x4e\xc7\x44\x4e\x57"
+  "\x62\x7f\xfe\x41\x0c\x33\x62\xde\x62\xaf\x71\xd7\xab\xf4\xf0\xb8"
+  "\x18\xd2\x21\xf8\x3b\x8f\x15\x4e\x34\x09\x7e\xd7\xd3\x3e\x1d\x44"
+  "\xee\x3c\x91\x64\x45\x84\x19\x24\x7b\x22\x39\x18\xfa\xfa\xd8\x69"
+  "\x8d\x66\xd6\x51\xf2\x93\xb3\xf4\x72\x5f\xc4\x79\x39\xf2\x05\xf2"
+  "\xdb\x64\x5c\xce\xbe\xd7\xa2\xd1\xc4\x93\xdc\xc9\x7c\x8e\x64\x3c"
+  "\xd2\x5c\x7f\x19\x8f\x54\xa1\xfc\x55\xa3\xa4\x58\x9f\xbf\xbd\xca"
+  "\x35\xee\x2a\x7f\xb5\x4a\xde\x46\xfc\x35\x2b\x7d\xb5\xbf\xbb\x40"
+  "\xaa\x56\xfb\x8a\x30\x85\x30\x96\x74\x47\x68\x9d\x6b\x5c\x8c\xfc"
+  "\xf2\x60\x9c\x50\xef\x0d\x3f\x7c\xd0\xba\x86\x78\x5a\x89\xeb\x40"
+  "\x91\x4f\xd9\xfe\xe9\x2f\x49\x7c\x3c\x85\xcf\x4f\x69\x2f\xbe\x5d"
+  "\xbb\xe5\x2c\x0b\x35\x2d\x67\x37\x92\x0c\x5d\xe7\x96\xad\xc4\x03"
+  "\xeb\x44\x7c\xf6\xc6\x76\x26\xef\xcb\x5a\xc7\xb4\x78\x3e\x12\xbf"
+  "\xcb\x54\x5a\x0a\xef\xe8\x43\x9c\x2c\x86\x68\xa8\xbb\xd7\xb1\x91"
+  "\xdd\x05\x72\x8e\x3a\x56\x44\x67\x90\x1c\xcf\x1b\x3b\x48\xe2\x7a"
+  "\x59\xe4\x5f\xdd\xce\xfb\x4d\xc1\xaa\xb3\x24\xbb\x96\xd3\x43\xba"
+  "\x98\x5e\xec\x43\x32\xe6\xff\xdf\x15\xdf\xaa\x72\x3e\xe6\xfe\x31"
+  "\x9f\x7a\x5e\xf4\xfe\x36\x4c\xa2\xf7\x75\x5d\x44\xc3\x05\xe9\x1f"
+  "\x0d\x1b\xa8\xf6\x0f\xe9\xc8\xeb\x40\xff\xf3\xf1\x76\xc9\x1d\xa8"
+  "\x5b\xbd\x69\x0d\x8b\x68\xd7\xb0\x4b\x68\x23\xd9\xa0\xd6\x71\x19"
+  "\xbf\x86\x9d\x51\xf9\x74\x5e\x6f\x0d\x7b\x53\xb7\x3e\x84\x91\x6c"
+  "\x9e\x7c\x13\x72\xfd\x42\x90\xa4\x44\xc3\xdb\x5c\x53\x98\x35\xef"
+  "\xa7\x94\xe7\x69\x65\x2f\x6b\xee\x34\x1b\xd8\x41\xc3\x14\xd6\x5d"
+  "\xc8\x36\x62\xad\xd8\xfb\xad\xc7\xa9\x61\xea\x39\x78\x3d\xd7\x7f"
+  "\xd0\xb0\x87\x68\x2f\x21\xd9\x00\xf6\x91\x5a\xda\xaf\x51\xb6\x5d"
+  "\x5d\x37\xd8\x27\x6a\xf1\xce\x5c\x81\x31\x63\x2b\xf1\x7b\x0e\xf9"
+  "\x47\xe1\xfc\x83\xc8\x1f\xc9\xcf\x0d\x0a\x35\x31\x1e\x7a\x1b\xf9"
+  "\xe8\x3d\xae\x17\xa7\x21\x5f\x43\x1a\x86\xf7\xe2\xa8\x6d\x62\x2e"
+  "\x1a\xa6\x20\xff\x34\xef\xba\x95\xf3\xf9\xba\xed\xf0\x59\x97\x85"
+  "\x9a\x74\x2f\x9f\x2a\x19\x6e\x2b\x61\xc6\x40\xeb\xd0\x34\x84\xe9"
+  "\xff\x1e\xc1\xfe\x7d\xcb\x16\xb9\xdc\xa2\x95\x12\x37\x14\xb3\x48"
+  "\xcd\x26\x74\x1b\xad\xb3\xec\xb4\xa1\x58\x8f\xa7\x74\x91\xd7\xcf"
+  "\xb9\x3b\x6b\x80\x9c\x67\x60\xda\xcd\xe7\x07\x44\xdc\xec\xbc\xbe"
+  "\x5c\x0e\xf9\xe1\x83\xb3\xb2\xe8\x3c\xd7\xc2\xbe\x5c\xcc\x42\xee"
+  "\x76\xe3\xdb\x91\xcc\x64\xd7\x84\x38\xc8\x9e\xfa\x20\x28\x2f\xfa"
+  "\x4d\x65\xe6\x96\xb1\x88\xdc\x56\xb9\x6d\xd3\x93\x61\x11\xd8\x7f"
+  "\xf5\xd8\x37\x8a\xae\x8b\xbc\xbe\xbc\x17\x65\xbc\x97\xc6\xdf\xab"
+  "\xea\x7f\xdd\x4c\xc3\x4e\x6b\xb4\xeb\xfb\x57\xb7\xb0\x78\x6f\xdd"
+  "\xc2\xe2\xbf\xe5\xba\xe9\xbd\x75\xcb\x40\xdd\x42\x6e\xec\x5f\xdd"
+  "\xc2\x4d\xde\xba\x85\x9b\xae\xb1\x6e\x7b\xfb\x5f\xb7\x9c\xeb\x51"
+  "\xb7\x37\xfb\x57\xb7\x01\x55\xde\xba\x0d\xa8\xfa\x47\xea\x96\x57"
+  "\x26\x9f\x6a\x00\x02\x93\x3c\x87\x70\xfe\xb4\x26\xf4\x9d\x75\xb1"
+  "\x5c\x37\x39\x1a\xbf\x97\x99\xcb\xe4\x2f\x38\x6d\xa3\x09\xe5\xb2"
+  "\xff\xee\xc2\xd0\x31\xe0\x4b\x45\x1c\x20\x4d\x58\x2c\xd7\xdd\x08"
+  "\x19\x51\x29\x17\xc8\xae\xb1\x5d\xa4\x07\xe7\x22\x1f\x22\x5a\x79"
+  "\x5b\x12\x7b\xed\xa2\x53\x2b\x47\x27\xe9\xf7\x9c\x0f\xc5\x6f\x87"
+  "\x16\xef\x66\xa8\x7e\x43\xd5\x77\x75\xa5\x57\xc2\xa3\xd0\x5d\x77"
+  "\x67\x30\x1d\xe1\x11\x5d\x29\x36\xe1\x96\xbc\x01\x11\x77\x9f\xc3"
+  "\xbe\x5f\x18\xba\x5f\xb5\x0b\x55\xcb\x9a\xdd\x36\x40\xd6\xe5\xb2"
+  "\x10\xb2\x4d\xe5\x3e\x06\x0d\x0e\x36\x2a\x97\x85\xcd\xce\x41\xf9"
+  "\x4e\x96\xa6\xcb\x41\xd9\xe8\x0f\x4e\xcb\x6b\x42\x2f\x85\x2c\x66"
+  "\x91\x25\x28\x9b\xae\x77\x1b\xcc\xf2\x86\xe7\x59\x28\xd9\xb0\x92"
+  "\x2d\xaa\xb0\x43\x0d\x8f\xe8\x2e\x0c\x8b\x55\xbf\x73\x95\xfe\x1b"
+  "\x22\xfa\x2f\xcc\xed\xed\xbf\xb0\xd7\xbd\xfd\x17\xb6\x52\xf4\x5f"
+  "\xd8\x62\x6f\xff\x85\xcf\xeb\x5f\xff\x85\x55\x7a\xfb\x4f\xbc\x7b"
+  "\xe5\xfe\x0b\x3b\x19\xbc\xff\xc2\xba\xbc\xfd\x27\xca\x0a\xd2\x7f"
+  "\xe1\x81\xfb\x2f\xfc\x27\xd7\xd6\x7f\xe1\xf3\xae\xb1\xff\x06\x8b"
+  "\xfe\x1b\x70\xa7\xb7\xff\xc2\xcf\x79\xfb\x2f\xfc\x0d\xd1\x7f\xe1"
+  "\x7b\xbd\xfd\x37\xa0\xac\x7f\xfd\x17\xde\xe6\xed\x3f\xf1\xee\x95"
+  "\xfb\x6f\xc0\x8d\xc1\xfb\x6f\xc0\x44\x6f\xff\x89\xb2\xfa\xd7\x7f"
+  "\x03\x56\xa3\xdf\xf4\x4a\xff\xe9\x83\xf7\xdf\x80\xb2\x6b\xec\x3f"
+  "\x9d\xe8\xbf\x88\x75\xde\xfe\x8b\x18\xef\xed\xbf\x01\x17\x44\xff"
+  "\x0d\xe8\xf0\xf6\x5f\x44\x73\xff\xfa\x2f\x22\xce\xdb\x7f\xe2\xdd"
+  "\x2b\xf7\x5f\xc4\xe3\xc1\xfb\x2f\x22\xcb\xdb\x7f\xa2\xac\x20\xfd"
+  "\x37\x20\x70\xff\x45\xbc\x79\x6d\xfd\x17\xd1\x7c\xa5\xfe\xeb\x1f"
+  "\xad\x11\x11\x54\xaf\xb8\x7f\xe5\x0c\x9c\x1c\xac\x1c\xea\x43\xd2"
+  "\xb9\x93\x0a\x07\x4e\xde\x2d\x85\x47\x08\xbb\x84\x08\xf2\xb1\x76"
+  "\x57\x8b\x66\xe0\xd3\xbb\xa5\xb0\x08\xb9\xe0\x2f\x55\x52\xc1\xe1"
+  "\x64\x79\x7d\x78\xa8\xb4\x7e\x40\x28\xd9\xcd\x07\x8d\x75\xac\x19"
+  "\x78\x2a\x64\x38\xbb\x89\x6c\xcb\x36\x80\x5e\xa3\xdf\xdd\x85\x03"
+  "\x1d\xa0\x45\x2e\xf3\xc3\x9d\x9e\xb9\x82\x07\x4e\x5c\xbe\x30\x7d"
+  "\xe5\x92\xf4\xf9\x4b\xb2\x8c\xf3\x9f\xf8\xd5\x0a\x7f\xbf\xe6\x3c"
+  "\xe6\xe0\x46\x1a\xbf\x41\x13\x3d\xbe\x4c\x40\xc7\x92\x4f\x38\xd3"
+  "\xf7\xd9\xc0\x76\xcd\xa0\x2c\xee\x6b\x3e\x3a\x29\x57\xee\x4d\x7e"
+  "\x21\xe1\x07\xf2\xbb\xdc\xd7\x5d\x6f\xc6\x0b\xb2\x25\x71\x0a\xf9"
+  "\x2f\x51\xce\x26\xa6\x9c\xd6\x44\x6e\x96\xa3\x66\x56\x93\x4e\x07"
+  "\xb7\x57\xd0\x0c\xe2\xfe\x11\xc9\xaf\x89\xac\x4f\x2c\x91\x2c\x33"
+  "\xab\xe5\xad\x33\xab\xa8\x0f\x1a\xc8\xcf\x58\x76\xc8\xc8\x16\xcd"
+  "\x90\x39\x72\x54\x62\x09\xca\x2a\x55\xca\x21\x5e\xaf\x2b\x61\x8d"
+  "\xfc\x19\x95\xa7\xd0\x82\x14\x4b\xc2\x2a\xe8\xc1\xeb\x06\xea\xd6"
+  "\x1b\x43\x28\x2f\xf9\xfb\x23\x3f\x78\x6a\xfc\x20\xaa\x37\xe5\x05"
+  "\x3d\x7e\x17\xde\xbf\x6b\x0f\xc5\x07\x52\xcb\x10\x75\xfa\x5e\xbb"
+  "\xe6\xba\x04\xde\x16\x4b\x62\x42\xe7\xda\xe4\x17\x78\x4c\x41\xde"
+  "\xaf\x43\xee\xc0\xb7\x13\xa8\x0c\xf2\xc3\x45\xef\x2a\xef\xdc\x88"
+  "\x77\x38\x9e\x92\x8f\x4f\x51\xc6\x90\x1b\xd5\x7a\x81\x86\x1e\x84"
+  "\xfb\x30\x9f\x6f\x5c\xd7\xae\x19\x7c\xc6\xe7\x79\x24\xee\x3f\x04"
+  "\x1d\x1a\xa5\x3c\x1f\x8c\xfb\x37\x88\x2e\xe5\xed\x2a\xce\x17\x7a"
+  "\xbe\x9a\xc1\xa5\x48\xd3\x2b\x79\xa2\x90\x67\x1d\xd1\xba\x4a\x19"
+  "\xd1\xb8\x9f\x4f\x3c\xa3\xf2\x3c\x06\xf7\xf7\xd0\xb9\x80\xf2\x7c"
+  "\x28\xee\x6f\xc5\xfd\xbf\x29\xcf\x41\xd7\x47\xa6\xf1\x3a\xeb\x13"
+  "\x37\x51\x9b\xd0\xf7\xa5\xd4\xef\xe8\xeb\x4d\x48\x9b\x02\x7e\xd5"
+  "\x4c\xe3\x48\xed\xb4\xae\x69\x67\x2d\x9a\xc8\x87\xc8\xd6\x4c\x8c"
+  "\xd5\xcc\x6a\xe1\x87\x46\x9b\x8c\xf4\xb9\x94\x4e\xfa\xd2\xd2\xd6"
+  "\x99\xa5\xf4\x1b\x7d\x7a\x86\xfa\x50\xf9\xd6\x48\x7c\x2b\x57\x19"
+  "\x67\xf4\x1d\xf9\x8a\x65\xf9\x7b\x94\xb1\x40\xdd\x06\xe0\xf9\x27"
+  "\xaa\xfe\xc5\x6c\x57\xaf\xb0\x99\xd1\x44\x56\x7c\x23\xdf\x08\x78"
+  "\x4f\xe0\x5e\x64\xab\x1a\x57\x0e\x69\x3c\x56\x3d\xcd\x4f\x92\xaf"
+  "\x38\xa2\x12\xe3\xb8\x2f\x10\xcc\x51\x75\xae\xd0\x3c\x91\xc3\x07"
+  "\xba\xb8\xac\xa6\x70\xb0\x37\xfe\x89\x26\x72\x9e\xe2\x8b\x9f\x09"
+  "\x3e\x61\xf0\x14\x8f\x7e\x91\xe6\x3a\x8e\x0f\x3e\xcf\x92\x7d\x9e"
+  "\xd9\xd5\x67\x5c\x07\xae\x70\x70\x96\xcf\xb3\xc6\x3e\xcf\x2c\x3e"
+  "\xcf\xac\x7d\xca\xdc\xeb\xf3\xac\xaa\xcf\x7b\x75\x3e\xcf\xca\xfa"
+  "\x3c\x6b\xf5\x79\xb6\x49\x79\x16\x82\x74\x97\xc7\x17\x9f\xe6\xba"
+  "\x5c\x25\x1d\x58\x3f\x24\xc6\x27\x7d\xb1\x92\x8e\xef\x0f\x01\xfd"
+  "\xf7\x56\x95\x92\xce\xe7\x39\xe6\xd1\x2d\xe2\x1b\x43\x92\x7c\xbe"
+  "\x31\x45\x39\x7b\x8e\x13\xe3\x37\x68\xbf\x4e\x63\x1c\x40\x73\x4a"
+  "\xb7\x3e\x9f\xe2\xba\x58\x84\xdf\x29\xb1\x0e\x79\x4c\x5f\xe2\x87"
+  "\x91\x2f\x18\x36\x06\xd4\x11\x2c\x1c\x52\xa3\xda\x66\xba\x2d\x89"
+  "\x63\x24\x4b\x45\x1d\xc5\x8a\x23\xff\x54\xe6\x0e\xf2\x51\xd2\xc5"
+  "\x6c\xac\x87\xd9\xb2\xba\xf3\x29\x5e\x5c\x83\x88\x13\x47\x36\x6d"
+  "\x1a\xb2\xd9\x20\x1f\x5b\x0d\xa6\x33\x3c\x56\xdc\xaa\x0e\x16\x6b"
+  "\xfa\x99\xdc\x7a\x5a\xa3\x33\xba\xb7\x26\x8e\x51\xfc\x0c\x3c\xcf"
+  "\x6d\xa1\x35\x3a\xb1\x3e\x88\x8f\xed\xe0\xb2\xe5\x08\xe4\xab\xe2"
+  "\x79\xe4\xe4\xe7\x45\x1b\x75\x7c\x3c\xf6\x28\xf6\x71\xdd\x85\xba"
+  "\x64\x4f\xfc\x42\x8d\x6e\xff\x85\x28\x73\x25\xd2\x16\xfb\xe9\x34"
+  "\x6a\x74\x4f\x53\x99\x54\x77\xe4\x89\xa3\xb2\x91\xc7\xe2\xd1\x69"
+  "\x44\xfa\x2a\x17\x1b\x81\x7a\x9d\x56\xcb\xc7\xf3\x2a\xbb\x66\x08"
+  "\xd7\x8f\xa6\x32\x2f\x6c\x7d\x99\xca\xad\xb5\x87\x46\x0b\x9d\xc8"
+  "\x42\x5d\xa3\x9d\xbd\x1f\x1a\x6c\xcf\xe3\x72\x48\xfd\xcc\x46\xd9"
+  "\x32\xb3\x09\xeb\xbc\x4e\xd8\xa4\xcf\x6c\x14\xfc\xbb\xfe\x46\xd2"
+  "\xb9\xa0\x18\xc8\x74\xd6\x28\xb0\x46\x3f\x9f\xaf\x57\xa4\x61\x8c"
+  "\x2a\x81\xc9\x4d\x7c\xdc\xfb\xb5\x0e\xf5\x63\x78\x19\xe7\x59\x44"
+  "\xb1\xa2\xe7\xda\x5d\xa8\xcf\xf1\x89\x23\x20\xf4\xd8\x35\xfa\x17"
+  "\x1b\x72\xf8\x79\x13\xaf\x63\xdf\x3a\x50\x7d\x51\x56\x6c\xd0\xfd"
+  "\x53\x3f\xb3\x8e\xcb\x3e\xb7\x25\x19\xb9\xfe\x98\x46\xff\x55\x88"
+  "\xe1\x86\x1d\xf8\x56\xab\x27\x7e\x02\xf2\x14\xf7\x90\x5f\xb6\x99"
+  "\x8d\x9e\x76\x2e\xa7\x6f\x44\xf1\xf3\x09\xbb\x26\xca\x08\xec\xaa"
+  "\xa3\x3a\x28\xe9\xc6\x06\x97\x93\x6c\xbf\x03\xfa\x77\xa2\x7d\x91"
+  "\xfb\x06\xda\x36\xb3\x8e\xec\x00\xc6\x39\xd5\x3a\x47\x1b\x49\xff"
+  "\x9c\xea\x2c\xfa\x36\x7a\xa8\xda\x8f\x9b\xcf\xa3\xec\xbc\x13\xac"
+  "\x55\x13\xb5\x8b\x74\x5a\xc8\x9e\x62\xcb\x1a\x45\xcf\x0a\x69\x3c"
+  "\x5f\x8f\x27\x0f\x97\xf5\x92\x8e\x2f\x61\xe8\x6e\xb2\x8b\x47\x99"
+  "\xc5\x18\x0b\xee\xf3\x42\x13\xc5\x6d\x21\x36\x2c\x67\xa2\xdd\xa4"
+  "\xc3\xa6\x89\x9e\x26\xe6\x4a\x54\xb3\x5d\x13\x3d\x47\xcc\x41\x91"
+  "\x46\x31\xb4\x49\xf7\xe0\xac\x26\xea\x1d\x8a\xe9\x89\xfe\x68\x22"
+  "\xbf\x68\x0d\x5d\x58\x27\x39\x3d\x34\x17\x9a\x28\x76\x1b\xfa\xa1"
+  "\x46\xec\x09\xd4\xe7\x51\xe5\xf4\x7d\xea\x5b\x8a\x67\x8a\x3e\xad"
+  "\xe8\x2e\x8c\xf6\xc4\xff\xa2\xd8\xa9\xc8\x33\x37\xd8\xb8\x50\x1f"
+  "\xb9\x51\x67\xf2\xef\x61\x1d\x71\x02\xf5\xfb\x9e\x46\x8a\x9e\x59"
+  "\x47\x3a\x93\xa8\xeb\xcb\x02\x2b\xc4\xd8\x89\xb5\x14\xfd\x09\xbe"
+  "\x61\xa3\xf3\x45\xd2\xc7\xe6\x71\xa0\x35\xd1\xf9\x4a\xff\xf1\x78"
+  "\x0a\x96\x6c\xd1\x0f\x22\xff\xf7\x26\x0a\x59\xcc\x0d\xc7\x51\xaf"
+  "\x46\x8f\x2c\x06\xe9\x5c\x8e\xa6\xe8\x55\xe3\x59\x87\x4f\x9d\xbb"
+  "\xb8\x3d\xdb\x79\xe2\xa3\xa3\x4b\xe8\x5b\x9b\xc9\x6f\x15\xcd\x8b"
+  "\x76\xdf\xf9\x1f\xbd\x92\xea\x49\xfa\x78\xee\xa8\x24\xa3\xbc\x35"
+  "\x69\x14\xf5\x33\xde\xd9\x8b\xb5\x10\x50\x9e\x4a\x58\x49\x31\x35"
+  "\xba\x0b\xbf\x37\xcf\x27\x06\x2a\xf6\xbe\xef\x6d\x56\xf7\x36\xda"
+  "\x97\xc9\x0f\x81\x27\x6d\x6b\x4d\x06\xd6\xbb\x49\xa1\x6b\x4c\x41"
+  "\x7d\xe8\x8d\x65\xf1\x64\x33\x4b\xba\xd9\x34\xdf\x64\x7d\x4d\x04"
+  "\xf9\xe5\x25\x1f\x83\xd6\x35\x13\x50\xdf\x98\x3b\x9f\x1b\xc6\xed"
+  "\xf4\xba\xac\x63\xcf\x93\x5e\x4e\xc7\xe9\x5c\xee\x3b\x27\x62\x76"
+  "\x8e\x4b\xde\x23\xe2\x1c\x3b\xe4\xa8\x1a\x8a\xc7\xdb\xc1\xfd\xd2"
+  "\x53\x99\xdf\xd4\xc7\xac\x26\x26\x42\xa1\x5f\x3a\x80\x95\xd7\xa3"
+  "\x3d\xfc\xbc\x00\xbf\x87\xb5\x6b\x86\x2e\x14\x71\xfb\x84\x9f\x74"
+  "\x45\xbf\x30\x5c\xd8\x99\x3b\x18\xb7\xfb\xd5\xc4\x7c\x62\xfc\x21"
+  "\x63\x1d\x9a\x98\x93\xdc\x67\xb1\x25\x31\x5f\xe9\x83\xfc\x2d\xa2"
+  "\x5e\xba\xd4\x1c\x2d\xaf\x23\xd5\xaf\x9f\x75\xab\x50\xf6\xae\xf0"
+  "\xee\xc2\x98\x36\xd5\x3e\x9d\xb7\x5f\xf1\x65\x6c\xfd\x3e\xf1\x2a"
+  "\x43\x1f\x52\xf6\xab\x8d\xca\xb7\x37\xfe\xe3\xdf\x1e\x6a\x54\xca"
+  "\xe4\x7e\xa5\x31\x17\xeb\x51\x6e\x72\x77\xe1\x50\x93\xba\x87\x2a"
+  "\x7a\xf1\x63\xc4\xde\x3e\xb4\xc8\xbb\x7f\x8a\x3e\xf4\xb3\x3d\x59"
+  "\xba\x34\xcb\x08\x22\xdd\x34\x3f\xeb\x89\x0c\xe3\xc2\xe5\xcb\x97"
+  "\x2e\x37\x92\xf3\x15\xdf\x35\xc6\xf5\x5e\x0a\x87\x96\x29\x31\xb8"
+  "\x2a\x3d\x31\xb8\x0a\x87\xb6\xfa\xc6\x46\x43\xdd\xda\xbe\x1d\x5e"
+  "\x66\xd8\x65\x71\x17\xd5\x72\x2c\x5a\x89\x64\x53\xd5\xf8\xb3\xe2"
+  "\x8f\xf6\x65\x96\xea\x64\x09\xd8\x1f\x39\xbd\xe3\xb5\xbb\x1e\x5a"
+  "\x43\x67\xdf\x2d\x9a\x61\xf3\x77\x4b\xa1\x8c\xfb\xdd\x28\x90\xb8"
+  "\x5f\xc7\x3d\x78\x1f\x7f\x56\xfc\xd5\xe1\x8f\xbf\x27\xfd\x99\xdb"
+  "\x8c\x56\xf9\x3e\xa3\xf3\x68\xb9\xa0\xa2\x95\xf2\xc8\xeb\x43\xf9"
+  "\xb9\x83\xb4\x4d\xe4\xeb\x53\x07\xad\x5c\xa8\x53\xf3\xf1\xba\x0f"
+  "\x59\xcf\x8c\x01\xf2\x85\xc8\x85\x83\x62\x95\x7c\x7c\x7e\xab\xed"
+  "\x21\xbf\xf0\xc8\xaf\xe6\x0b\x95\x0b\xbf\x57\xae\xe4\x13\xb6\x4c"
+  "\x05\xda\x40\xdf\x0d\x93\x0b\x3e\xd9\xa8\xe4\xd3\xfb\x96\xe7\x93"
+  "\x27\x5c\x2a\xe4\xf1\x76\x1b\xa5\xf5\xa1\xfc\x5c\x57\x2e\x1c\x16"
+  "\x8a\xfc\x01\xfd\x69\xf6\x6f\x9c\xae\xdf\xdb\x77\x9c\x4c\x4f\x64"
+  "\x2e\xfc\x69\xe6\x92\x6c\x8a\x52\x94\xb5\x74\x65\x16\x5d\x97\xcc"
+  "\xff\x15\xbf\x2c\x4d\x7d\xf2\x09\xf1\x23\x6b\x71\x3c\xfd\x58\x8c"
+  "\xf9\x46\xd7\xf4\x95\x26\xba\x3c\xb1\x94\x6e\x73\x32\xc6\xac\x7c"
+  "\x42\x0d\xad\xec\x3b\x0f\xe3\xba\x0b\x0d\x73\x31\x37\xa6\x09\x7a"
+  "\xc4\x90\x06\x9e\x97\x9f\x83\xe9\xd6\xdb\xd9\xa1\x38\x1e\x83\x8d"
+  "\x5d\x66\x77\xaf\x31\x3c\x45\x76\xf7\xba\xf5\xa6\x27\x74\xae\xcc"
+  "\x85\xc0\xd9\x7c\xbc\x5b\x66\x67\x9b\x94\x18\x42\x89\x16\xee\x93"
+  "\xb2\xf0\xfa\x0e\x55\xa7\x50\xb2\x24\x4e\x23\x5f\xeb\x5c\xc7\x68"
+  "\x1b\xf9\x6a\x49\x34\xe1\x7e\xd3\xee\x6d\x3c\xe6\x49\x0c\xee\x67"
+  "\xe2\xbe\x04\xf7\x06\xdc\xc7\x4a\x96\x09\x4d\x64\x67\x87\x7b\x23"
+  "\xee\x47\xa1\x7c\x4f\xfc\x77\xdf\xbe\x51\x82\x7e\xfd\x34\x20\x4f"
+  "\xec\xef\xef\x08\x6b\x6b\x78\x82\x1a\x53\x95\xc7\x4f\x2d\x1c\x3e"
+  "\x47\x3d\x0b\x14\x71\x82\xf4\xf3\xf8\xbe\xc6\xf7\xf6\xe1\x47\x43"
+  "\x0c\x37\x8e\x12\xb4\xf7\xf0\x1c\xd5\xb7\x80\xa0\xad\x87\x17\xf9"
+  "\xc4\x9e\xa5\xfb\x52\x4f\xec\x59\x41\x8b\xbe\x20\x68\xd1\xe1\x76"
+  "\xb9\x70\xb8\x37\x86\x5e\xe1\x70\xab\x6f\x9c\x30\x3b\x9e\x13\x4f"
+  "\x83\xf4\x26\xef\x3e\x38\x7c\x31\x7d\x33\x50\x9c\x5d\xf0\xe4\x39"
+  "\xa9\xab\x41\x7f\xe3\xca\x69\x71\xb7\x86\x71\x7e\x0c\xf7\x72\x41"
+  "\x02\xf9\x69\x31\xd2\x33\xa2\xfd\x02\xca\x19\x28\xce\x9d\x66\xc4"
+  "\x32\xf2\xe9\xea\x30\xa7\x6b\x7e\xb0\x9b\x69\xf8\xbd\xf0\x49\x28"
+  "\x9f\xd5\x8c\x98\x4a\x73\x4f\xf5\x57\xe6\x6b\xdb\x1d\xd0\xde\xe0"
+  "\x23\xf5\x9c\x78\xf1\x52\x9d\x6b\xfe\x42\x41\xc7\x8d\xf8\x50\x60"
+  "\x69\xd2\x34\xb1\xdf\x8f\xa8\x91\x1f\x14\xb1\x34\xec\x9a\x1b\x78"
+  "\x1c\x3b\x9d\x66\xf1\x52\x19\xef\xea\x72\xe6\x2f\xe4\x69\xc8\xb7"
+  "\x01\xb4\x96\x52\xbf\x17\x6d\xb1\x6d\x4c\xbe\xe8\x16\x36\xeb\x9a"
+  "\x11\xe5\x29\x37\xe6\xd3\x77\x22\x38\x1d\xf1\x11\x8b\xa4\x98\x6d"
+  "\x54\xb7\xdd\x3e\xfe\xd4\xb6\x20\x8d\xc7\x63\x7f\x90\x45\x92\xff"
+  "\x58\xa5\x2e\xe5\x3c\x0e\x56\xe1\x0d\x93\x55\xdf\x2f\x76\xa4\xf5"
+  "\x6d\xcf\x83\xff\xce\x57\xc8\xe8\x27\xc6\xcc\xb9\x07\xbf\xc6\x28"
+  "\xe1\x46\x7d\xe7\x4e\x6c\x67\xf4\x7d\xf9\x9d\xaf\x4e\xfd\x31\x8f"
+  "\xd7\x57\x78\x43\x11\xca\x19\xc3\xc7\x7b\xc3\x2f\xbe\x22\x6c\x51"
+  "\xe3\xd5\xdb\xa4\x2e\x7c\xf7\xa6\x85\xdc\x77\xab\x56\xd0\x8b\xdc"
+  "\x67\x5a\xe1\x0d\x33\xe5\xe8\xc4\x78\x11\xab\x73\x86\x01\xe3\xc7"
+  "\xf7\x7d\x5a\x1b\xdc\x0e\x50\x4f\x6d\xbf\xc1\x0e\x4c\xbd\x1b\x7f"
+  "\x8f\x88\xd8\x23\xbf\xf8\x4a\x2d\x97\xfc\x1b\x61\x6e\x91\x9f\x23"
+  "\x7d\x77\x61\x6c\x84\x47\x2f\x48\xb5\x2d\xd4\xc4\xde\x4a\xbe\x97"
+  "\xbc\xf4\xf9\x4d\x0f\x08\xba\x32\x76\xa2\x9d\xe9\x4a\xc4\xfa\x8e"
+  "\xc5\xfc\xdf\x37\x45\xf9\x3d\xd3\xce\x6e\xcf\xe8\x53\xc6\x76\x55"
+  "\xde\x21\xc6\x2e\xd6\x84\xb9\x78\x37\xfe\x1e\x41\xfe\x5c\x35\x56"
+  "\xf1\x06\x2d\xb7\x27\x3a\x1d\x62\x60\xf1\x48\x2f\x51\xd3\xc3\x34"
+  "\x09\xe8\x9b\xd8\x0a\x15\x4f\x3a\xa3\x93\xc6\xe0\x7e\x3f\xe8\xcd"
+  "\x31\xca\xfd\x64\xdc\xd7\xaa\xf7\xf8\xdd\xa8\xe2\x0d\xc9\x1d\x3a"
+  "\xd7\x26\x3f\x4f\xfc\xde\x13\x06\xd0\x64\x06\xe2\xaf\x62\x1d\x76"
+  "\xb6\x37\x4e\xc9\x0b\xfe\xf7\xd5\x4d\xe2\xf7\x8d\x68\x7f\x4c\xba"
+  "\xb7\xff\x43\x74\xa2\xfe\x37\x4d\x91\xa3\x2a\x28\x96\x58\x07\xf2"
+  "\x80\x4f\x1b\xce\xdf\x25\x5f\x47\x9b\x7a\xf4\x73\x6d\x1b\x41\x9f"
+  "\x3e\x49\xf3\xe2\x26\x7e\x7e\xba\x79\x8d\x7e\x0e\xd1\x77\x64\x3b"
+  "\xcf\x63\x6e\x91\xef\x42\x17\x0b\xe7\xfe\xe2\xb7\x56\x54\x73\x3f"
+  "\xe9\xab\xe2\x22\x55\xbf\x85\xb2\x65\xaa\x5d\xd6\x3e\x97\x4e\xbe"
+  "\x0c\xb9\xac\xac\x3b\x6e\x08\xf7\x5f\xa8\xf8\x2d\xdc\x95\xcd\x62"
+  "\xca\x24\xe1\xb7\x90\xdb\xd5\x5f\xc1\x77\xa1\x5c\x70\xc4\xe3\xbb"
+  "\x90\x62\xc2\xe3\x77\x9c\x7c\xd1\xe5\xc4\x75\x94\x8f\x7f\x96\xd0"
+  "\x80\x7e\x0c\xb5\xc0\x48\xad\xf0\x63\xd8\xbf\xbd\xe5\xa6\x08\x31"
+  "\x27\x6e\x4a\x52\xe3\x26\xfb\xa4\xcd\xc3\x9c\x56\x64\x27\xb1\x71"
+  "\x4a\x1a\xe8\x9f\xdf\x95\x78\xe8\x30\x60\x1b\xc9\x0c\xb1\x66\xf7"
+  "\xca\xe6\x8c\xe7\x7d\xd7\x10\x63\xb4\x45\x87\xa1\xac\x70\xfc\x0d"
+  "\xa0\xbf\x24\x0f\x4e\x5c\x94\x9b\x88\x17\xd0\x69\xb0\xaf\xe4\x84"
+  "\xc8\xb3\x5d\xae\x90\x54\x97\xe6\x18\xd1\x98\x64\x23\x3c\xdb\xed"
+  "\x22\x5b\xf5\xd0\xd9\xee\x4e\x8a\x67\x78\x8c\xec\xc4\xb6\x3c\x49"
+  "\x76\x8b\x23\x65\x8a\x75\x32\xdb\xfd\xb5\xbc\x47\xd8\x63\x36\x12"
+  "\x0f\xe0\xbe\x28\xd7\xbb\xb3\xe5\x3a\x8c\x41\x24\xf1\x17\xe4\x2f"
+  "\x6a\x88\xc6\xc9\x86\x98\x42\xde\xbd\xff\xc2\xbb\x32\xf9\x8a\xa2"
+  "\x38\x57\x52\xa1\x13\x98\x68\xd4\xa4\xba\x42\xf2\x6d\xae\x56\xee"
+  "\x6b\x7e\xb6\x7b\x80\x3c\x3b\xe7\x4e\x99\xc7\xa7\xca\x96\x6b\x81"
+  "\xa7\x21\x3c\x66\xf1\x6a\xb9\x13\xbf\x23\x66\xaf\xee\x94\x29\x9e"
+  "\x22\xca\xae\x9b\xed\x92\x7a\x66\xe7\x48\xe6\xd4\x1c\x0d\xde\xfb"
+  "\x02\xef\x7d\x81\xfa\xc4\xa3\x4c\x3d\xee\xef\x92\xf7\x3c\x49\xf6"
+  "\x4d\xf9\x9c\xc7\x41\x1b\xad\x8a\xcd\x68\x35\xea\xb7\x9f\x7c\x55"
+  "\xa7\xba\xac\xf9\x7b\x14\x1b\x50\x1e\xcb\x33\xa7\x57\x56\xbe\x33"
+  "\x79\xf6\x6a\x76\x57\xea\xea\x91\xdc\x96\x94\xec\xa4\x66\xbb\x8c"
+  "\xf8\x66\x3e\xf5\x47\x24\x8f\x9f\x4c\xb6\x52\x85\x23\x1d\x57\x8a"
+  "\xc3\x18\x90\xaf\x2e\x9e\x19\x27\x6f\xbf\x37\x54\x2e\x9e\x1d\x8a"
+  "\xeb\x46\xd9\x32\x23\x81\xf4\x4b\xe5\xe2\x07\xec\xf2\xf6\xe9\x48"
+  "\x9f\x5b\x83\xeb\x46\xb9\xf8\x91\x52\x79\x7b\x12\xee\x1f\xcb\xc2"
+  "\x15\xf7\x63\xd2\x90\x9f\xc9\xc5\xb7\x35\xe2\x9a\x2f\x17\x8f\x4b"
+  "\x40\x3e\xdc\xc7\x57\xe1\x8a\xfb\x09\x46\xe4\xc3\xfd\xed\x96\xd3"
+  "\x1a\xe3\x7e\xfc\x46\xda\xe3\x73\xc4\xb7\xd2\xe6\xf1\x6f\x15\x3f"
+  "\x91\x21\xbe\xf1\x64\x96\xf8\x46\x66\xbe\xf8\xc6\xe2\x4d\xe2\x1b"
+  "\x77\x30\xe4\x43\x1d\x27\x75\xe0\x5a\x24\x17\x4f\x6e\x42\x3e\xdc"
+  "\xff\xb4\x16\x57\xdc\x4f\xc1\xb7\x92\x70\xff\xb3\x32\x5c\x71\x9f"
+  "\x50\x84\x7c\x91\x72\x71\x62\x0e\xae\x9b\xe4\xe2\x69\x54\x3e\xee"
+  "\xef\x4d\xc6\x15\xf7\x49\x49\xc8\x87\xfb\xfb\x26\xe3\x8a\xfb\xa5"
+  "\x68\xd3\xbd\x7a\xb9\x78\xd9\x4c\x5c\x2d\x72\xf1\x0a\x7c\x6f\x3a"
+  "\xee\xb3\x50\xdf\xe9\xb8\xcf\xc6\xfb\x49\xb8\xcf\x89\xc5\x15\xf7"
+  "\xab\xa9\xad\x31\x72\xf1\x5a\xfa\x4e\x89\x5c\xbc\x8e\xda\x8c\xfb"
+  "\x3c\x27\xae\xb8\xcf\xa7\xfa\xe0\xbe\x80\xde\xc3\xfd\x46\xf4\xc1"
+  "\xbd\x06\xb9\xb8\xd0\x81\x6b\xa9\x5c\xfc\x8c\x15\xf9\x70\xbf\xc9"
+  "\x82\x2b\xee\xb7\xa0\x0f\x93\x70\xbf\x2d\x1e\x57\xdc\x6f\xa7\xf6"
+  "\xc6\xca\xc5\xff\x71\x0c\xd7\x32\xb9\xf8\x85\x4a\xe4\xc3\xfd\xae"
+  "\x5c\x5c\x71\x5f\x8e\xfe\x4b\xc2\xfd\x4b\xa3\x70\x2d\x0b\x3c\x9e"
+  "\xbf\x2d\x93\xd7\x87\xa3\xdf\x7f\xbf\x49\x5e\x3f\x00\xd7\xfd\x53"
+  "\xe4\xf5\x61\x71\x72\xf1\x9f\x3a\x90\x8e\xeb\x1b\x71\xb8\x1f\xa3"
+  "\xdc\xe3\xfa\xc7\x18\xdc\xc7\x2b\xf7\x74\x65\xb8\x9f\xa8\xdc\xe3"
+  "\x5a\x43\xf7\x93\xe5\xe2\x77\x70\x0d\xc7\xb5\x26\x1f\xf7\x53\x94"
+  "\x7b\x5c\x0f\xd4\xe3\xea\x92\x8b\xdf\xac\x46\x7a\x82\x5c\xfc\x56"
+  "\x0e\xee\x71\x7d\x7b\x32\xee\xa7\xe1\x4a\xf5\x99\xe6\x18\x7d\x47"
+  "\x15\xe9\x20\xc9\xc3\x22\xad\xd2\xb0\xfb\xf2\xcd\x17\x98\x96\x64"
+  "\xc9\x55\x79\x76\xf2\x3f\x30\xb2\x45\xf3\xfd\xad\x14\xb3\x80\xf2"
+  "\xb8\x77\xdc\xcb\xa4\x61\xf7\xe6\x23\x3d\x1c\xf9\x06\x9c\xd6\xfc"
+  "\xe0\x65\xda\x1b\x6d\xb9\x76\x1e\x2b\x4d\xf1\xad\x16\x8e\x77\xde"
+  "\x04\x2d\x30\x99\xe2\x4b\xa3\xbf\xa6\xc8\x05\x61\xe7\x71\xad\x91"
+  "\x0b\xae\x6b\x41\x7f\xe1\x3e\xea\x23\x5c\x71\x3f\xe9\x59\xf4\x17"
+  "\xee\x7f\x91\x88\x6b\x4d\x77\xe1\x0f\x0c\x76\x8d\x51\xcf\xb1\xfe"
+  "\xd5\xa9\xf1\x3a\x97\x0c\x8c\x41\xdd\x5e\xcc\xaa\xd2\xb9\xac\x18"
+  "\x83\xe4\x72\x1d\xf9\x08\x7b\x79\x52\x95\x3c\x6c\x68\x23\xaf\x77"
+  "\x01\xf8\xd7\xde\x51\x5a\xf1\xed\xeb\xe4\x16\xcd\x0f\xee\x21\x39"
+  "\xa7\x3c\xec\xb6\x60\xcf\x17\xf2\xe7\xdf\x5f\x19\x2f\x9e\xeb\x99"
+  "\xf7\xf9\x23\xf4\xfc\x69\x1d\xc9\xa6\x6f\x19\x1d\x6f\xd7\xfc\x60"
+  "\x2f\xe5\xb1\x6b\xbe\x5f\x27\x17\x84\x30\x5b\x57\x9b\xd2\xc6\x01"
+  "\x94\x6f\x1f\xbd\x17\x4c\xf6\x22\x95\xa4\xc4\x6d\x2e\x90\x1b\x89"
+  "\xcf\xc4\x7e\xa1\x35\xe6\x8d\xaa\x6e\xd1\x8c\xce\xdd\x45\xf2\x83"
+  "\x98\x15\x0e\xb2\xf9\x69\xd1\x8c\x9a\xda\xbb\x6d\x46\x96\x71\x8d"
+  "\x0e\xe5\x8d\x5e\x67\x76\xca\x5d\xd6\xbc\x44\xec\x6b\x3c\xbd\x8a"
+  "\xeb\x91\x8b\xdf\x65\x42\xf7\x87\xff\x2e\x12\xb2\xd0\xd1\xb9\xf4"
+  "\xae\x2f\x5d\xef\x2e\x3c\x55\x29\x0d\xcb\x62\xe2\xec\x6a\xd4\x3d"
+  "\xef\x48\x76\xad\x2e\x8b\x85\x19\xd7\xbc\x8b\xf2\x47\x6d\xf2\xe7"
+  "\x01\xd5\xbc\xfc\xd9\xb2\x03\xc8\xbb\x93\xcb\x6b\x46\x95\xa9\xf2"
+  "\x5d\x19\x6d\xf8\x8d\xa0\x7f\x12\x68\x0f\x13\x74\xdc\xe8\x58\xf2"
+  "\xcb\xe8\x8a\x79\x44\xef\x2a\x89\xac\x72\x97\xac\x70\xc8\x3b\xb2"
+  "\xd8\x10\x97\x86\x71\x1d\x7c\xcd\xe8\x07\xc6\x39\x49\x8e\xf6\x01"
+  "\xe5\x1d\x28\x85\x7f\xbd\x78\x6c\x0e\xd3\x5a\x97\x9f\xa0\xfb\x19"
+  "\x72\x61\x8f\xc9\xd6\xd1\xc4\xc8\xb7\x2c\xee\x93\xe4\x67\xa3\xd2"
+  "\xa5\x41\x61\x9b\x76\x13\xfd\x99\x43\xf2\x9f\x8f\xa8\x5f\x8e\xa2"
+  "\x9f\x41\xe7\x8f\x8e\x53\xeb\x42\xbe\xe5\x37\xa3\xef\x88\x36\x24"
+  "\x9b\xe9\x54\xb7\x9b\x7c\x16\x81\x7e\x1b\x9d\x2b\x64\x88\xa3\x23"
+  "\x09\xa3\x95\xef\xce\x97\xa2\x67\xa4\x35\xcc\xa3\xf3\x51\x3d\xf9"
+  "\x80\xe9\xe2\x36\x96\x2e\x8a\x07\x47\xfb\xa2\xc8\xeb\x3b\x76\x99"
+  "\x8a\x6d\x69\xe6\x92\xac\xe5\xcb\x8c\x2b\x32\xd7\x2c\xbc\x73\xf4"
+  "\xca\x31\xc6\xe5\x39\xc6\xe5\x3c\xfe\x30\x4f\x48\x1f\x63\x5c\xb1"
+  "\x78\x69\x96\x31\x6b\xb5\x69\xe1\xe5\xf1\x65\x0d\xb2\x7e\xc6\x14"
+  "\x41\xb3\xfd\x88\xfb\x15\x96\xcb\xb3\x2a\xb3\x72\x65\xc9\xf8\xfd"
+  "\x01\xa0\xc9\x6f\x89\xbd\x14\x3e\xba\x88\xec\xcd\xa5\x02\x23\x53"
+  "\x62\x24\x47\x3e\x1f\xcd\xc8\x96\x23\xa2\xbb\xf0\x96\x18\xef\x99"
+  "\xc7\x8f\xe6\x09\xf9\xc4\x2d\x71\x98\x83\xdc\x57\x57\x89\xea\x57"
+  "\x4a\x79\x26\xce\x0c\x6e\xc1\xfe\xbf\x49\xf8\xb9\x28\xcf\x8a\x10"
+  "\xb4\xde\x2d\x42\x4f\xd5\x98\x55\x29\x57\x4c\xaa\x02\xed\xa3\x21"
+  "\xb9\x0f\x8f\xc3\xca\xce\x73\x7b\x53\xac\x23\x23\xd9\x7a\xbb\x77"
+  "\xcc\x28\x97\x86\x25\x1b\xa5\xdf\xfe\xd8\x64\x7e\x91\x69\x5f\xc3"
+  "\x9a\x0f\x35\x62\x7e\x7f\x9f\x8d\x7c\x37\xaf\x4d\x8b\x3a\x3f\xf3"
+  "\x6e\x5e\x93\x56\x2e\xb9\x2f\xa7\x73\xd4\x64\x8b\x13\x34\x9d\xe8"
+  "\x7f\x27\xfb\xcb\x34\x46\x3c\x4b\x75\xd7\xd0\x34\xfc\xcd\x28\x72"
+  "\x6e\xcf\x34\x5a\xbf\x3f\x81\xdd\x73\xab\xfc\xf5\xfb\xb5\x24\x5b"
+  "\xfa\xd1\xb4\xf7\xa7\x91\x6c\x6f\xc6\x44\xa7\x7e\xc6\xe4\xae\x1d"
+  "\x8f\x94\x93\x5f\x96\x4b\x3b\x32\x4d\x3d\xc3\x66\xb2\x83\xc8\xf3"
+  "\x01\x28\xf8\x23\x46\xcc\xdf\x9b\x99\xf6\xd2\x2d\x93\xd8\x6b\x3d"
+  "\x16\x6d\x5d\xed\x14\x21\x8f\x4c\xc3\x9a\xe1\xf3\xe9\xdf\x6e\x7b"
+  "\x7f\x7f\x2d\xc3\xb7\xf1\x3c\x49\xfb\x97\xc9\x97\x3d\x9f\xf5\x7e"
+  "\x7c\x2d\xeb\x26\x5f\x9f\xe0\x9d\x0e\x9c\x28\x65\xf2\x8e\x14\xfb"
+  "\xbe\x35\x4e\xed\x3c\x3b\xd3\x1e\x6d\x2a\x65\xb9\xa7\xd8\x60\xd7"
+  "\xd7\x71\xa1\xbf\xc3\xfb\x97\xc8\xd7\xde\x11\x03\xf7\xb9\x95\x67"
+  "\xe5\x71\x45\x75\x0d\xa0\x27\xa4\xaf\xe3\xc2\x1b\xe6\x5a\x19\x9e"
+  "\x9f\x70\xfd\xdc\xc0\x8e\x66\x38\x98\x2d\xb9\x9c\x5d\xd2\x26\xb0"
+  "\x37\x1f\x2b\x67\x3b\x41\xb7\xef\x3c\xcb\x22\xc5\xd9\x6a\x5c\xb8"
+  "\xab\x37\x2e\xd4\xb5\x36\x8e\x7c\xa0\xc8\xf2\xd7\x71\x83\x88\x7e"
+  "\x74\x2d\x8d\x8b\x68\x70\x94\xb3\x71\x6d\x2c\xee\x92\x96\xe9\x2e"
+  "\xad\x8d\x1b\xd4\x60\x2a\x45\x59\x14\x0c\x99\x69\xc8\xff\x12\xf9"
+  "\x65\xa2\x7e\xba\x2e\x99\xcd\xed\xd0\xfc\x5b\xd8\xa0\x63\x6c\x28"
+  "\xf9\xff\x23\xff\x5d\xe4\x5b\x54\x8a\x49\xb1\xbb\x63\x1e\x29\xcf"
+  "\xbb\x80\x7a\x91\x4f\x92\x57\xa7\xea\x89\xa6\x4d\x01\xee\x50\x9b"
+  "\x25\x39\x6e\x50\x2a\x5d\xb7\x4d\x3d\x41\x74\xad\xd4\x6d\xa0\x78"
+  "\x39\x11\x54\x4f\xac\xd3\x88\x75\x9f\xa3\x2f\xcd\x71\xa1\xc8\x17"
+  "\x89\xf4\x21\xb6\x0e\x27\x73\xdf\x36\xd5\x38\xd6\xc4\xe3\xa2\xc6"
+  "\xec\xce\x63\x7a\x4b\x1e\x8b\x31\x4e\xe2\x73\x69\xb4\x7b\xdf\x54"
+  "\xbd\x5c\x38\xd9\x25\xaf\x0f\x8d\x15\x69\x3f\x0c\x33\xde\xcb\x98"
+  "\x71\x02\xfd\xbe\x75\x9f\xf1\xa7\x18\xc3\x98\x94\x04\x4e\x73\x73"
+  "\x5e\xec\xd6\x17\xc5\x1c\xbf\xf5\xf9\x4b\xe1\x1b\x12\xa4\xc2\x3f"
+  "\xce\x93\xd6\x87\x1a\x29\x7e\xf2\x59\xcd\xad\xeb\xe4\xe2\xc3\x53"
+  "\xe4\x92\x4c\x3e\x17\x71\xbf\xfa\x52\xf8\xc4\x0a\xa4\x95\xa3\xfc"
+  "\x84\x4b\x9a\xd0\x26\xfc\x35\x2b\xef\x9b\xa8\xdd\xee\x8a\x49\x45"
+  "\xd4\x6e\x1e\x63\x05\xed\x4a\xc5\x98\xc9\xc3\x1e\x77\x70\xbf\xe3"
+  "\xbd\xe8\x5f\x25\x06\x25\xf5\x07\xf5\x81\xd4\x1b\x37\x88\xb7\xb5"
+  "\x37\x2e\x12\xfd\x4b\xbe\x3e\x75\x79\xf3\xf1\xce\x8e\x94\x50\x3c"
+  "\x1b\x72\x29\x26\x65\x32\xc5\x3a\xb2\x99\x1c\xcc\xbd\x3d\x85\xfb"
+  "\xb2\x7a\x7e\x0d\xd6\xdc\xd0\xc7\xb1\xd7\xa7\x44\x2a\x6b\x8b\x51"
+  "\x3d\xa5\xe2\xc3\x1d\x97\x48\x6f\x1f\x75\x43\xfd\x9a\xf0\xd7\x6c"
+  "\xd7\xc4\x75\x5d\x1a\x3d\xa9\x14\xd7\x3a\xd4\xd5\x28\x17\x3e\x30"
+  "\x86\x7e\xe3\x99\x11\x75\x3e\x49\xfd\x40\xfd\xa1\xf4\xc5\x71\x6f"
+  "\x5f\xac\xcb\x40\xbe\x5a\xa9\xf0\x75\xec\x17\xb7\x56\xc8\x85\x3f"
+  "\xef\xf0\xc9\xe7\xf6\xe6\x7b\x26\x52\xe4\x7b\xbb\x4a\xe4\x7b\x38"
+  "\x1d\x7d\xfe\xbc\xe8\xef\x1f\x4e\xbd\xbc\xbf\x7f\xf8\x13\xef\xbb"
+  "\xcb\xf6\x8b\x77\x7f\x9b\x20\xde\x9d\x4a\xef\x2e\xf3\xaf\xd3\x0f"
+  "\x33\xbd\xf9\x7f\xd5\x26\xf2\x97\x3b\x44\xfe\x29\xf1\x3e\xf9\xb6"
+  "\x7a\xf3\xad\xca\x12\xf9\x7e\x57\x24\xf2\xdd\x0b\xda\xf0\x87\x47"
+  "\x03\xd4\xe5\x90\xf7\x9d\x12\xa7\x78\xe7\xfd\x0a\xf1\xce\x7c\xf4"
+  "\xcf\x0f\xdd\x7d\xea\x72\xc1\x9b\x7f\x8b\xd2\xee\xf7\x26\x8a\xfc"
+  "\xbf\xa8\xf7\xe6\xfb\xd1\x8d\x22\x1f\x3d\xaf\x47\xbe\x5b\x4b\x2f"
+  "\x85\xbf\xd0\x2c\xf2\x3d\xb9\x98\xe6\x23\xf2\xdc\x29\x15\xfe\x74"
+  "\xd3\xa5\xf0\x1f\xe7\xa0\x9c\x4d\x18\x9b\x58\xba\x62\xec\x62\x25"
+  "\xcb\x0c\x94\x19\x17\x4a\xe7\x0d\x84\xb9\xc0\xf7\x56\xe0\xae\x3b"
+  "\xf0\xf9\xe5\x8f\x72\x3d\xf2\x2d\x09\xb4\xc1\xf6\x7b\x1a\x03\xd2"
+  "\x6b\xdb\xa6\xce\x24\xbd\x03\xc2\x14\x7c\xfb\x0c\xf9\x38\x93\xcd"
+  "\x49\x8a\x4c\xe9\x47\xfc\x8c\x98\xfc\x31\x90\xdc\x51\x49\xe3\x7e"
+  "\x0b\x25\xcc\x4d\xf0\x85\xd5\xe4\x57\x8e\xe4\x8c\xd8\xa3\xea\xec"
+  "\x9a\x31\x44\x87\x84\x3d\xa7\x95\xaa\xf0\x57\x8d\x3f\xeb\x73\x24"
+  "\x7f\x2c\x60\xf7\xa8\xb2\xd9\xc0\x75\x1d\x83\xfd\x6f\x73\x93\x57"
+  "\x3e\x35\x66\x32\xe6\xaf\xa5\xff\x3a\xbb\x63\x82\xea\xbf\xf0\x78"
+  "\xc2\x44\x07\xed\xb8\xd7\x68\x91\x44\x8c\x72\xac\x45\xd0\x70\x63"
+  "\x36\x63\xcf\xcf\xe7\xbe\x4b\x4b\x92\xcb\xa5\x51\xd8\x4b\xce\xb0"
+  "\x10\x5b\x6e\x1b\xab\x92\xda\xb4\x96\x1e\x16\xda\x80\xfd\x94\xf2"
+  "\x57\x81\x76\x30\x2e\x09\x01\x1d\x31\xe6\x65\xcb\x45\xa5\xbc\xf2"
+  "\xac\x2a\xf3\x53\x22\x16\x33\xd1\x8f\xb4\x07\x01\x77\x22\x79\x7c"
+  "\xae\x25\x44\x3f\x8d\xf9\x04\xbf\x23\x28\xef\xa5\x5b\xee\x88\xbf"
+  "\xf4\x9f\x59\x55\x3d\x3b\x7e\xce\x7a\x6e\x99\xac\xef\x1d\x96\x5c"
+  "\xde\xbb\xe3\x11\xa3\xeb\x3f\xb3\x8c\xae\x5b\x26\x55\xb9\x87\xfd"
+  "\x3c\x1f\xdf\xc6\xfe\x54\xaa\x7d\x55\xaa\xd2\xbe\x9a\x67\xd5\x52"
+  "\xb9\xef\xe6\x55\x6a\x0f\xe4\x35\x6a\x0f\x48\xd5\xda\x77\xf3\x2c"
+  "\xb8\x96\x53\xac\x26\xd0\xac\xb7\xdd\x7a\x20\xaf\x0e\xfb\xe3\x6d"
+  "\x58\x93\x3f\xca\x50\xe5\xa0\x72\xa2\x8b\x35\x54\xba\xd8\xa1\xac"
+  "\x0b\xcc\x11\x35\x63\x0a\xfe\x12\x1c\x43\x53\xe2\x1c\x43\x33\x8d"
+  "\xbc\xce\xc3\x52\x79\x1b\xc9\xfe\xea\x80\x24\xea\xac\xf4\x07\x95"
+  "\xb9\x75\xb7\x44\x36\x5a\x8a\x5f\x57\xcd\xd8\x99\x97\xf9\x75\xd5"
+  "\x8a\x38\x61\x1e\xdf\xae\xff\x0c\xbf\xae\x8a\x0c\x81\xfc\xba\x82"
+  "\x77\x6d\x54\x78\x57\xab\xe2\xef\x28\x92\xf8\x55\xee\xef\x28\xc7"
+  "\xca\x7d\x16\x71\xbf\x1e\xdb\x1f\xce\x27\x3a\xb4\xbb\x70\x6c\x91"
+  "\xca\x97\x12\x6d\xe5\xde\x3a\x63\x26\xfe\x92\x90\x5e\x6e\xd7\x7c"
+  "\x14\xa1\xa6\xcb\x3b\x06\x5b\xa9\x4f\xdc\x72\xc6\xcf\xba\xc9\xb6"
+  "\x48\xce\xb8\xcb\xbd\x7d\x86\xc5\xbd\x3d\x93\x21\x6d\x0a\xfe\xee"
+  "\x74\x6f\x1f\x5c\x8b\xbf\x3a\xfc\xd5\xe3\xaf\x11\x7f\xc7\xf0\xd7"
+  "\x84\x3f\x3b\xfe\x5a\xf1\xd7\x86\xbf\x0e\xfc\x39\xf0\xd7\x25\x6d"
+  "\x1f\xdc\x4c\x7e\xea\xe4\x1d\x43\x68\x5e\x18\xd4\x72\xbd\xfd\x3d"
+  "\x2e\x0c\xed\x27\x7d\x9f\x46\x79\xc8\xe1\x64\x19\xeb\x5d\x7e\xf9"
+  "\x8e\x6a\x5e\x7f\xc2\xe5\x97\x27\x5b\x1c\x37\x67\x95\xe3\x2f\xc2"
+  "\x11\xb5\x2e\x03\x7f\x26\xfc\xe5\x38\xb6\xa7\x60\x4c\x33\x23\x30"
+  "\xae\x8d\xdd\x85\xe3\x30\xfe\x93\xe6\x0a\x59\xd3\x38\x60\xdc\xa4"
+  "\x2c\xe5\x77\xbe\x5d\x33\x81\xc7\x0a\x70\x0c\x4d\xb5\xe0\xde\x62"
+  "\xd7\x4c\xe4\xf9\x3a\x87\xa5\xcc\x51\x6c\x92\xf2\x91\x5e\x69\x0f"
+  "\xbd\xad\x48\xe4\x7b\x84\x7c\xdc\x81\x97\x1f\x57\xa3\xae\x41\xbf"
+  "\x78\x0c\x4f\x98\x52\x9f\x9a\x9f\x93\xba\x62\x71\xe6\x13\x0b\x57"
+  "\xfc\xd4\x38\x3a\xdd\x18\x97\xb9\x7c\x59\xea\xb2\x95\x0b\x57\x2e"
+  "\xe4\xe4\x23\x92\x6e\xf5\x3b\x3b\xa2\xb8\xbb\xcc\x05\x3e\x67\x48"
+  "\xab\x2c\xd3\xbe\x3d\xb3\x0b\xe3\xf3\xfd\xac\xaa\x9a\xb3\x0e\xad"
+  "\x1b\xf4\x5b\x64\x6b\x3e\xd6\x65\x72\x79\xcd\x59\xa7\x36\xb2\xd5"
+  "\xc8\x64\xac\x05\x7a\x66\x6b\x6d\x54\xe8\xb9\x8f\x58\x3d\xd1\x73"
+  "\xc8\xf3\xea\x12\xa7\xf6\x7e\x7a\xff\xb7\x93\xaa\x5e\xc3\x6f\xa4"
+  "\x19\xe9\x3d\x19\x34\x1e\xbf\x82\xc6\x13\xf7\x3f\x67\x07\xf8\xf5"
+  "\x11\xe3\x01\x9e\xef\xe7\xf9\xef\xd2\xf5\x62\xae\x5c\x8f\x72\x49"
+  "\xae\x26\xff\xf6\x8e\x78\x9e\xe7\xb7\x93\xf5\x3c\x0f\xd6\x61\x8b"
+  "\x66\xfc\x4c\xca\xc7\x79\x26\xd4\xf1\x35\xd4\xc3\xbc\x92\x85\xaa"
+  "\x6b\x9b\xf8\x22\xcf\xfa\xce\x26\x7a\x37\xfe\x0d\x5a\xdf\x54\x1f"
+  "\x19\xeb\x79\x1f\xde\x7d\x75\x89\xe0\x23\xc1\x3b\x86\x10\xcf\x48"
+  "\x18\x42\xd8\x61\xcb\x6d\xe4\xef\x57\x49\x8d\xe0\x39\x43\xe8\xdd"
+  "\x0b\xf4\xac\x0c\x34\x6a\x19\xe7\x49\xc6\xc7\xab\x7c\xc0\xa6\x61"
+  "\xc2\xdf\x51\x64\x1a\x23\xbb\xec\x91\xc8\x3b\x90\xfa\x8f\xfa\x8b"
+  "\xce\x6a\xe5\xc2\x71\x75\x65\xd1\x2c\x74\x57\x34\x8b\x70\x0d\x5d"
+  "\xe1\x14\xf2\xfa\xf1\x26\x95\xb6\xee\x8a\x59\xe1\xf4\x1d\x37\x31"
+  "\x5e\xc6\x85\x4b\xe8\xd4\x21\x9d\x1f\xef\xcd\x5f\xb1\x62\xe5\x53"
+  "\x0b\x8d\x0b\xe7\x3f\x91\x61\xe4\x8f\x8d\x2b\x57\x20\x4b\x66\xd6"
+  "\x0a\xe3\xd2\x55\x4b\x8c\x4f\xad\xc8\x24\x2e\x61\xe1\xf2\xe5\x2b"
+  "\x4d\x59\x83\x98\x78\xd3\xf8\xd4\xca\xc5\x59\x99\x26\xfc\x58\xb1"
+  "\x70\x49\xba\x91\x8f\xfa\x0a\x14\xb5\x78\xb1\x51\xf9\xc2\x8a\x8c"
+  "\xf9\xcb\x69\x22\x2c\xf9\x25\x32\xf9\xbc\xef\xcf\x43\x44\x92\x3f"
+  "\x29\xda\x77\xce\x6a\x26\x7c\x58\x1b\x8a\xbe\x2e\x59\xe1\x24\xfd"
+  "\x02\xdc\x37\x72\xbe\xb2\x70\x7c\x3e\x9d\xc5\x3c\x87\x36\x76\x8e"
+  "\x9e\x8c\xb9\x3b\x61\xa6\xda\x36\xf2\x49\xce\x7d\xf2\x91\xbf\x47"
+  "\xcd\x84\x77\xb8\xad\x1c\xd6\x03\xd7\x3f\x29\x1c\xff\x9c\xe8\x8b"
+  "\x09\xb9\xbe\xfe\x9c\xb9\x6f\x40\xcd\x84\xed\xe2\x1c\x63\x02\xf1"
+  "\xab\x4c\xf1\xa1\xae\xc1\x3b\xef\xd1\x3b\xd2\xf6\x4c\xec\x45\x13"
+  "\xf6\x7b\xf9\x93\x09\x9b\x28\x3f\xcf\x57\x38\xfe\x53\x79\x68\x0a"
+  "\xe8\x91\x09\x26\xaa\x57\x90\x3d\xc6\x78\x11\xe5\x1e\xa9\x62\xec"
+  "\x47\x31\x2c\xee\xe2\xb6\x99\x6d\xdd\xd1\x33\xe6\xf4\x14\xb0\x01"
+  "\x3d\xd8\xd7\x9c\x5a\x36\xf2\x12\xe6\xc5\xea\xf1\x2c\x64\xdd\x2c"
+  "\xa6\xad\x5a\x54\x45\x3e\x45\x59\x7d\x52\x29\xb3\xa5\xd9\x99\xcd"
+  "\xb9\x97\xd5\x5b\x5b\xd8\x51\xd7\x7f\x09\x3f\xfe\x6b\x88\xbf\x98"
+  "\x78\x07\xf9\x84\x32\xaf\x93\xdd\xaf\xbd\xe5\x08\x7b\xb5\xbd\x8a"
+  "\xfc\xef\x8f\xb4\xb9\x3e\xb3\xda\x72\x2b\x98\x2d\xc7\x66\x25\x5b"
+  "\xf9\xb3\x9a\xdb\x6f\x3e\x80\x67\x03\xeb\xf1\xde\xfd\x6c\x00\xee"
+  "\x87\xd2\x37\x8a\x76\xc8\x4d\xcf\x0c\x93\x9b\x9f\xd9\x21\xdb\x31"
+  "\xa7\xc8\x9f\x7e\xdb\xe6\x61\x72\xc7\x66\xc5\xef\x1b\xcd\x53\x53"
+  "\x36\x33\xb4\x6b\x6e\xdf\xcb\x65\x1c\xd3\xf8\xfd\x70\xdc\x73\x1d"
+  "\x0d\x5b\xce\x0e\xba\x1f\x81\xfb\x7a\x71\xbf\x9b\xee\x6f\xc0\x7d"
+  "\xb3\xb8\x7f\x9f\xee\x63\x71\xdf\x21\xee\x1b\x18\xb7\x1b\xd7\xdc"
+  "\xee\x12\xf7\x1f\xd3\x3d\xfa\x7e\x62\xa4\x35\x9b\xea\xfb\x29\xc6"
+  "\x6c\xe2\x70\xf3\x49\xf0\xa9\x39\xa7\xf9\x7a\x78\x37\x2f\x83\x64"
+  "\x30\x58\x0f\xb7\xef\xba\xae\x99\x78\xdc\x89\x53\xc2\xe3\xe9\x7a"
+  "\x7b\x82\xce\xc9\x06\x80\x66\xbc\x0e\xcf\x06\x53\xdf\x05\xa4\x61"
+  "\x5e\x9d\xfc\xd9\x6c\x97\x6c\x95\x5f\x9e\x54\x29\x6f\x7f\x14\x98"
+  "\xf9\x63\x8a\x43\x87\x7d\xee\x1e\x7b\xd5\x1a\x27\xf7\xeb\x0a\x3a"
+  "\x1d\x6b\x68\x22\xf7\x5d\xe9\x00\xdd\x1b\xc4\xcf\xa3\x5e\xde\x7e"
+  "\x9f\x11\xfc\x64\xe9\xac\x38\x17\xe9\x07\x82\xd6\xbf\x63\xf0\xa1"
+  "\x0c\xa2\x1b\x52\x9f\x93\x2a\x7e\xec\x90\xcc\xc9\x4c\x1e\x35\xa9"
+  "\x72\x56\x86\x6c\xc5\x1e\xa6\x11\xb2\x6e\x99\xbe\xff\x19\xff\xee"
+  "\xe8\x49\x95\xd2\xaa\x0c\x8a\x1f\xc4\xf1\x25\x8f\xf6\xf3\x6c\xe0"
+  "\xc9\xda\x64\x9d\x7b\x7b\xaa\xe5\x50\xc6\xa9\xfe\xc5\xe2\xd2\xdc"
+  "\x11\x19\x54\x27\x09\x75\x72\xcb\xc9\xcc\x85\xef\xb8\xd0\x56\xa2"
+  "\x1d\x5e\x95\xea\xb4\xa0\x61\x2a\xf7\x2d\x68\x0a\x93\x57\x25\xeb"
+  "\xd0\xa6\xf1\xb6\xb8\x0b\xac\xa1\x87\xd6\xca\x1d\xf5\x87\xc0\x35"
+  "\xdf\x93\xe3\xb2\xea\x1c\xdc\x1f\xad\xde\xb4\x88\xdd\x24\x0f\xbd"
+  "\xcf\xd8\xae\x99\x14\x7b\x7f\x2e\xda\x80\xb6\x1f\x68\x69\x0a\x95"
+  "\xd0\x8e\x71\xa2\xdf\xf0\xde\x24\x92\x45\x95\xaa\xfc\x4d\x3f\xeb"
+  "\xcf\xe7\x8d\xb4\x22\x99\x91\x0d\xdf\x6b\xa0\x57\xa4\xde\x64\x9d"
+  "\x84\xfd\x88\x9e\x1d\x8a\x3b\xc3\xe8\x9b\x4a\x5f\xf3\x58\x7b\xf2"
+  "\x28\xf4\x33\xbe\x4f\x7e\x70\xd5\x7e\xc5\x9e\x86\x3e\xcd\x08\x3c"
+  "\xfe\x3b\x52\xd3\x50\x3f\x8b\xbc\x7d\x70\x40\x1b\x1e\xec\xeb\x5b"
+  "\xc4\xfc\xb8\xa3\x0e\x7f\x4d\xf2\x8b\x59\x7a\xc7\xe8\x3b\xda\x78"
+  "\x7c\xc7\x1d\x0f\x5b\x54\x59\x11\xd6\x1b\xe6\xc8\xa4\x5d\x55\x79"
+  "\x6d\x81\xfd\x80\x5a\x5e\x6a\xe3\x71\xb5\xc2\x3e\x93\x75\x6e\x8a"
+  "\x17\x7b\x81\x7c\x2a\xb7\x1d\x8a\xeb\xea\xe7\x98\x4e\xb2\x07\x1b"
+  "\x53\x2a\xff\x9e\x5b\xe5\xde\xfe\x95\xf7\xe3\xf8\xa0\x73\xa4\x02"
+  "\xfd\x12\x33\xb8\xaa\x47\x9e\xa6\x11\x3c\xc8\xe4\xe3\xd4\x57\x2e"
+  "\xec\x23\x6b\x8e\x33\xad\x13\xfb\xe5\x7f\x3d\x5c\xa4\x1d\x93\x46"
+  "\xb1\xe2\x59\xfe\xe1\xc6\x5a\x36\x7b\x26\x33\x1f\xcd\x38\xcf\xd4"
+  "\x78\x59\xd8\xd7\x8c\xaf\x3c\xec\xd0\xd2\x79\x13\xc5\xc7\xe2\xfc"
+  "\xfa\x8e\xc7\xd3\x7e\xf7\x31\xf6\x4c\xd0\x11\xfb\x3e\x76\x68\x5d"
+  "\x9d\xc9\x46\xee\xd3\x19\x7c\x84\x39\x43\x96\x3c\x67\x50\xe4\xf7"
+  "\xdf\x32\xd5\x4e\xf1\x87\x8f\xcc\x69\xe4\x76\xd5\x47\x92\x6b\xd9"
+  "\x91\xe6\x52\x56\xdf\x7a\x92\x6c\x01\x5f\x3c\x92\x6c\x21\x7a\x72"
+  "\x88\x0b\x34\xe3\x4e\xd0\x8c\x58\xaf\x03\x25\xfd\x4b\x6d\xea\x39"
+  "\x14\x9d\x49\xa9\xf4\xa2\x0b\x6b\xb4\x4c\x89\x99\xe5\x2a\x9c\x54"
+  "\x5b\xa6\x9c\x49\x51\x2c\xad\x17\xb2\xd9\xa8\x17\xb4\x52\x72\xa0"
+  "\x33\xa8\x21\xcb\xb8\xdf\x15\x83\x14\xf5\x52\x9b\x1a\x53\xeb\xfe"
+  "\x65\x46\xf6\x36\xda\x7e\x28\xae\xbf\x6b\x72\x32\x3f\x93\x75\x61"
+  "\xde\xb9\x30\xe7\x5c\xe8\x4f\x8c\x81\x05\xe3\x16\x90\x17\x53\xc7"
+  "\xa0\xd7\xac\x8e\xc1\x4f\x17\xf2\x31\x00\x0f\xb7\xf6\x51\x65\x0c"
+  "\x4e\x60\x0c\x5a\x31\x06\x05\x2c\xff\x83\xb9\xf5\x6c\xf6\x1c\x8c"
+  "\x41\xc7\x79\xf2\x07\x2e\x62\x96\x65\x89\xbe\xe7\x63\x71\xc2\xa1"
+  "\x6d\xe8\x12\x63\xb0\xf7\x31\x31\x06\xaf\x3e\xe6\x00\x1d\x33\x89"
+  "\xbd\x82\x7b\xf7\xaa\x64\x23\xc5\x70\x91\x0b\xd2\x28\xbe\xb2\x18"
+  "\x8b\x5e\x8c\x45\xaf\x18\x8b\xbc\x65\x18\x8b\x63\x4d\xdc\xff\xca"
+  "\x91\xe6\x7a\x56\x9f\x56\xce\x8e\x02\x97\x30\x16\xf3\x69\x5c\x48"
+  "\xbe\xe0\x5e\x1b\x17\xfd\xfc\x1a\x16\x53\xb6\x86\x19\xd4\xf1\x90"
+  "\x7a\x31\x1e\x6b\x30\x1e\x3d\x18\x0f\xa7\x67\x3c\x62\xf8\x78\x9c"
+  "\x51\xc6\xa3\x87\x74\xd9\x30\x1e\x3d\x18\x8f\x1e\x8c\x47\x81\x18"
+  "\x0f\xc2\xf9\xfb\xbb\x74\xb2\xf4\xf7\x38\xb6\xbb\x3d\xc0\x78\xac"
+  "\x55\xc6\xe3\xc4\x37\x19\x8f\x9f\xc6\x5f\x3e\x1e\x3f\x89\xb9\xda"
+  "\x78\x78\xd7\xc4\x94\x81\x34\x1e\xbd\xe5\xca\x9a\xb8\x85\xd6\x44"
+  "\xbe\xf6\x47\xd8\x8b\xa8\x4f\x0f\x37\xd6\xf0\x35\x81\xb6\xe6\xbf"
+  "\xf2\xb0\x53\x5b\xdf\x8a\x71\x49\x97\x85\xac\x43\x19\x17\x31\x1e"
+  "\xc9\xc6\xca\x8f\x45\xff\x1b\xef\xa3\x3d\x83\xd6\x06\x8d\x0f\xc6"
+  "\x09\xeb\x27\x50\xbc\x39\xdf\xb3\x5a\x94\x29\xd1\x3a\xa1\x35\x42"
+  "\xeb\xe1\x68\xc6\x49\x1e\xbf\xfb\xc8\x9c\x3a\x46\x67\xb6\x47\x92"
+  "\x6b\x30\x56\xa5\xcc\xbd\x0a\x63\x93\x8d\x75\xa2\x61\x37\x53\xdc"
+  "\xb9\x23\xc9\x45\x44\x2f\xe8\x31\xe7\x07\xba\x31\x4e\xee\x6e\xc3"
+  "\xa0\x4d\xe0\xb1\xf6\x64\x7b\xd7\xcd\x6e\x25\xc6\xae\x1c\x3e\xa9"
+  "\x16\xe9\xa1\x2e\x8c\x11\xd6\x8e\xdf\x9a\xf1\xc4\xde\xfd\x22\x8e"
+  "\xed\x6a\x61\x11\x83\x33\xc5\x18\xb9\x7d\xd6\xcc\xac\x4c\x5a\x33"
+  "\xf9\x18\xa3\xe3\xfd\x1c\xa3\xff\xc3\xe5\x06\xe0\x3d\xd3\xe4\xa1"
+  "\x83\xab\xb0\x4f\x62\x8c\x7e\x5a\x11\x6c\x8c\xdc\x15\x77\xd4\xb9"
+  "\xf5\x33\xe8\x6c\x65\xa4\xb4\x74\xae\x46\x02\xff\xd4\x03\xbe\xf5"
+  "\x88\xc3\xc5\x72\x1f\x67\xda\x35\x27\x59\xb8\x6d\xee\x47\xcc\x66"
+  "\xaf\x66\xe4\xe3\x97\xe4\xde\xe4\xeb\xdf\xe6\xaa\x06\x5e\x65\xe6"
+  "\xd3\xfd\x2e\x7e\xef\x60\x6b\x1f\x67\x21\x3c\x1e\x65\x72\x39\xdb"
+  "\x84\xf9\xb9\xef\xb1\x72\xad\x54\x72\x5f\x8e\xac\xa7\x18\x25\xcc"
+  "\x4a\xb6\x49\xe6\xd5\x2c\xf2\x68\x46\x3d\xf9\x84\xfb\xcc\x9c\x23"
+  "\x7f\xde\xd0\x85\x32\x1d\x72\x8f\x1b\x7b\xc6\xee\x02\xb9\x9a\xfc"
+  "\xb6\x8f\xa3\x3d\x82\xfc\x55\x68\xa6\x9c\x22\x5a\x84\xe4\x7f\xd6"
+  "\xbc\x17\x40\x7b\x4d\xe1\xf6\xdf\x48\xd3\x1c\x5d\x44\xfa\x14\x09"
+  "\x8f\x52\xbd\x84\x2c\x5e\x5c\xc7\x51\xdc\xbe\x61\x99\x07\xdf\xc9"
+  "\x73\x84\x5a\xc0\x0f\x83\x46\x43\xbe\x3b\xef\xe0\x7c\xde\x8e\xc1"
+  "\x4e\xdb\x31\x27\x97\xc3\x3a\xcc\x19\xe1\x96\x35\xe4\x4f\x97\x7c"
+  "\xc0\xd3\x9e\x9d\x30\x90\x62\xea\xca\x15\xd8\xaf\x86\x3d\x6c\xa9"
+  "\x5a\xe0\xd0\x7a\xf7\xe5\x3b\xb1\xef\xdd\xd1\x76\x4f\x9c\x6c\x26"
+  "\x5f\xf9\x07\xd0\x2e\xe2\x83\xfe\xab\xc5\xc9\x31\xe5\x77\x0b\x8a"
+  "\xb4\x24\x27\x72\x02\x1f\xea\x3f\xfe\x3d\x8f\x11\x7a\x5a\xf3\xb3"
+  "\x65\x1f\x24\xbb\x18\x7d\xff\xa1\x5b\xe9\xac\xe5\xce\x8a\x4b\xda"
+  "\x3f\x77\x5d\x0a\xff\xb1\xd1\xdc\xea\x8d\x8f\xe8\x1b\x07\x91\x70"
+  "\x66\xdf\x02\x94\x49\x38\xd3\x92\xaf\x15\xd8\x92\x40\xb2\xca\x88"
+  "\xbe\xd8\x72\xb4\xe3\x0c\xcb\xc3\x3c\x3e\x9a\x51\xce\xe3\x19\x0c"
+  "\x01\xbe\x4b\x6b\x81\x27\xbd\x71\xd1\xbb\x80\x27\x84\x03\xbb\x81"
+  "\x1f\xd2\x5a\xc3\xa0\xe2\x1e\x36\x46\xc5\x11\xa2\xbd\xe8\xfa\x38"
+  "\xe6\xa8\xae\x0e\x69\x18\x27\x09\xb8\x0e\x3c\x89\xdb\xb9\x86\x8d"
+  "\xda\x89\x39\xba\x8b\x70\x04\x74\xf1\xfd\x26\xe0\xc8\x2a\xe0\x48"
+  "\x36\x8f\x53\x6b\xd8\xad\x15\xf8\xf1\x56\x4b\x91\xd6\xa2\xc6\xa9"
+  "\xe6\xfd\x7b\x57\x58\x03\xcd\x8f\xb4\x7c\x6e\x7b\xe6\xa6\xfd\x69"
+  "\x6d\x72\x48\x43\x17\xe6\xc8\x8e\x4c\x13\xa5\xf1\x75\xbb\x2a\x63"
+  "\x90\x24\xe6\x5a\x02\xf5\xc9\x9e\xb3\x2c\x9e\xc7\x72\xfc\xda\x30"
+  "\x68\xcb\x12\x36\x66\xf7\x59\x36\x6a\xf7\x12\x16\x87\xf5\xaa\xdd"
+  "\x8d\x3a\xa4\x2c\xd3\x33\x1e\x37\x20\xfc\xc7\x71\x48\x0f\x18\x37"
+  "\x00\x74\xb5\x61\x37\xad\x99\xa5\x71\x9e\x3a\xb9\x2c\xe6\x7c\x37"
+  "\xfa\x8e\xfb\x44\xd2\xdc\xf5\xb8\xd0\x81\x1e\xdf\x24\xe8\xfc\xbb"
+  "\x2c\x42\x0f\x69\x52\x33\x78\x95\x01\xed\x9a\xbb\xee\x91\xb7\xfd"
+  "\xac\xd1\xb4\x86\x69\xda\xd5\x67\xa0\x3d\x25\x8c\xd5\xd8\x7c\x96"
+  "\x2f\x45\xbd\xd2\x64\xcb\x01\xed\x44\x3e\x90\xfb\xb5\x0e\xef\xe2"
+  "\xb6\x15\x6e\x8b\x79\x23\xb5\x57\xda\x66\xde\xb4\xa7\x9d\xc5\xcb"
+  "\xbf\xc2\x78\x2c\x42\x5b\xdb\xd9\xa8\xb2\x76\xb4\x75\x95\x68\xab"
+  "\x1a\x97\x5b\x2a\xf8\xb3\x0b\xcf\xae\x18\x73\xc7\xf1\x2b\x8a\xb9"
+  "\x33\xb6\x12\x18\xf6\x3d\xf9\xfb\x8c\x1d\xed\xe0\xfe\x28\xba\x6d"
+  "\xae\x93\x8c\xbe\x4b\xb2\x23\xdb\x79\x3e\xa7\x7f\x42\x73\x59\x2a"
+  "\xcf\xd2\xa7\x36\x63\x6e\x77\x67\x90\x1c\x4d\x7f\xa0\xc5\x41\xfe"
+  "\x1f\x38\xcd\x67\xd7\xdc\x99\x41\x74\xda\xbb\x48\xa3\xb9\xef\x33"
+  "\xe7\x33\x68\xce\xd3\x73\x3e\xef\xf1\x9e\xad\xf9\x14\xa3\xf2\x7c"
+  "\xcb\xa1\xf1\x57\xcb\x3a\xad\x99\x7a\x23\x95\x45\x73\x81\x64\x3c"
+  "\xb4\xd6\xc4\xd8\x57\x93\x0e\xb8\x41\x1e\x36\x53\xb9\x77\x90\x5f"
+  "\x11\x3d\xcd\x01\x3e\x57\x80\xdf\xe4\xaf\x54\x96\x93\x43\x30\xcf"
+  "\xa8\x9e\x83\x30\xde\xf1\xea\xbc\x40\x5a\x4c\xdf\xb9\x31\x64\xbd"
+  "\x9e\x78\x9a\x18\xfa\x7d\xad\xf3\xa3\x7f\xe3\x37\x35\xa8\x8d\x82"
+  "\x34\xea\x0e\x92\xb5\x8e\x24\xdc\x74\x77\xfa\x60\x66\x87\xc0\x4c"
+  "\xc2\x24\x15\x37\x39\x36\x71\xbf\xef\xd5\x3c\xbe\x3b\xaf\x63\x3f"
+  "\x71\xf3\x68\x87\x17\x37\xef\x37\xf9\xe0\x66\x87\xdc\x23\x8d\x0e"
+  "\x84\x9b\x89\x37\xfa\xe3\x66\xe2\xcd\xfe\xb8\x79\xcf\xd3\x7d\x71"
+  "\xf3\x72\xcc\x4c\x9c\x1f\x08\x2f\xc1\xc7\x8c\x6c\xd7\xdc\x33\x31"
+  "\x38\x56\x26\x6e\xea\x3f\x56\xde\xbd\xcb\x1f\x2b\x13\x1b\xff\xff"
+  "\xc5\xca\x69\xe3\xfd\xb0\x52\x7f\x8d\x58\xd9\xce\xb1\x32\x46\xfe"
+  "\x3b\xd6\x84\x82\x1f\xbb\x17\x05\xc1\xca\x45\x57\x59\x0b\xbf\x0a"
+  "\x86\x95\xd3\x9e\xf1\xc7\xca\x69\x35\xfe\x58\x39\x6d\x99\x17\x2b"
+  "\x95\x67\xdf\x0a\x56\x4e\x2b\xfa\x6e\xb0\x72\x5a\x11\xc7\xca\xb3"
+  "\x84\x95\xf7\x2c\xbc\x3a\x56\x26\x96\x04\xc6\x4a\xa4\x73\xac\x4c"
+  "\x2c\xf1\x62\xe5\xc9\xab\x60\xe5\xbd\x33\xfa\x81\x95\x31\x1c\x2b"
+  "\xf5\x41\xb0\x72\x11\xfa\x4a\x99\x17\x7c\xee\xf5\x99\x1b\x0a\x56"
+  "\x1a\x3c\x58\x79\x0d\xf3\xa3\x7f\xe3\x77\x6f\xd2\x95\xb0\x52\xb2"
+  "\x08\xfa\x92\xb0\x52\x1e\xa6\x60\xe5\x62\x17\x5b\xf3\x09\x30\xf2"
+  "\x58\x3b\x8f\x0f\xc1\xf5\x76\xf1\x97\xfb\x28\x61\xd1\x23\xe5\xaf"
+  "\xa2\xbf\x6c\xf6\x2a\x8e\x4d\xdc\xf6\x6a\x26\x61\x55\x15\xf2\x96"
+  "\x7a\xe8\x4e\x8e\x9d\x9f\x28\xd8\x39\x4f\xc1\xce\x94\x7f\x00\x3b"
+  "\x1f\xa3\xb1\x9c\xfe\xe8\x25\xad\x8a\x9d\xdb\x80\x9d\xd3\x39\xfd"
+  "\x40\xe7\xba\x02\x3b\xef\x3b\xae\xd6\x8b\x64\x9a\xb6\xac\x17\x98"
+  "\xa8\xd7\xf9\xcb\x71\xf4\x3e\x5e\xde\x3e\xeb\xa2\x0e\xe6\xc1\xd2"
+  "\x79\x5e\x2c\x45\x59\x4f\x07\xc7\xd1\xe9\xc7\x3c\x38\x5a\x00\x1c"
+  "\xfd\xd4\x07\x47\xc1\x37\xfd\x8e\x30\x0f\x38\xda\xcd\x71\xf4\x2d"
+  "\x05\x47\x93\x4e\x7d\x30\x0f\x38\x7a\x9f\x8a\xa3\x49\x06\x67\xc1"
+  "\x9f\xbb\x9c\x85\x57\xc7\xd1\x6e\x8e\xa3\xa6\xff\x79\x1c\xad\xed"
+  "\x83\xa3\xe0\x5d\x29\x36\x77\x40\x1c\x55\xe7\x23\xc7\xd1\x7c\x2f"
+  "\x8e\xf2\x7e\x9d\xb1\xbe\x21\x0d\xfd\x9e\x66\xe2\xbc\x9b\x07\x47"
+  "\x4d\x55\x02\x47\x91\xc6\xe5\x27\x2b\x80\xa3\x98\x7f\xe6\xa3\xe4"
+  "\xd7\x8a\x25\xa0\x8e\x7a\xc2\xd7\x3d\x58\x33\xd4\x47\x1e\x3c\x5d"
+  "\x84\x35\x43\x18\xd3\x89\x35\x03\x1c\x4d\xb9\xa0\x67\x7c\xbd\x14"
+  "\x62\xbd\xb4\x07\x89\x59\xa5\xea\xdb\x06\xc5\xd3\x19\x9f\xf8\xe3"
+  "\xe9\x7d\x91\xfe\x78\x3a\xe3\x3d\x2f\x9e\x2a\xcf\x08\x4f\x31\x66"
+  "\xe8\x9f\x26\xc2\xd4\x6f\x86\xa7\x33\x9a\x3c\x78\xaa\x55\xf0\x74"
+  "\xd1\xd5\xf1\x94\x9f\x0b\x06\xc1\x53\x5f\x6c\x08\x8e\xa7\x33\x9a"
+  "\xbc\x78\x7a\xdf\x1b\x1e\x3c\x6d\x0a\x86\xa7\xd3\x9b\x03\xe3\x29"
+  "\xd2\x39\x9e\x4e\x6f\xf6\xe0\x69\x53\x00\x3c\xbd\xcf\x17\x4f\x7f"
+  "\xfe\xb2\xc0\xd3\x2a\xe1\xff\x02\x98\xda\xd0\x85\xf9\x41\x6b\x2e"
+  "\xab\x94\x63\xaa\x04\x4c\xa5\x38\x9e\x14\xe7\x86\xf4\xe5\x03\x61"
+  "\xaa\xc0\x5c\x3b\x23\x5c\xa5\xb5\x69\x9e\x05\x7e\x17\x7b\x11\xfa"
+  "\x84\xef\xbd\x6a\xff\xed\xf1\xc1\xd7\xd4\xd5\x7a\xa2\xed\xfc\xe6"
+  "\x8a\xa4\xce\x95\xce\x38\xd2\x03\xf6\x9b\x2b\xfd\x1b\xcb\x9f\x57"
+  "\x04\xc3\xd6\x60\xbc\xfb\x07\xc4\xbb\x3f\xc4\xb4\x6b\x1f\x02\xbe"
+  "\x26\x13\xef\x5e\xd9\x87\x77\xaf\xbc\x9c\x77\x3f\x7e\x65\x1c\xed"
+  "\x17\xef\xfe\x30\x8d\xe1\xcc\x17\xfd\x71\x74\xe6\xcb\xfe\x38\x3a"
+  "\xe7\x66\xaa\x97\xc0\xf1\xca\xc0\xbc\x3b\x5f\xe7\x33\xcf\x79\x78"
+  "\xf7\x26\x7f\xfc\xf4\xf2\xee\xb3\x3f\x0c\x8e\xa3\xb3\x62\xfd\xe8"
+  "\xd1\x14\x05\x47\x17\x28\x38\xba\xc0\x8b\xa3\x47\x3e\x52\xe9\xd1"
+  "\xfb\x7f\x72\xb8\xc9\x17\x47\x67\xa5\x79\x70\xb4\xf9\x72\x1c\x55"
+  "\x31\x94\xf0\x94\xca\x21\x59\xd6\x5e\xe0\xf4\x6b\x0b\x4c\x5a\x21"
+  "\xab\x4d\xa3\xbe\x8b\xe8\x2b\xab\x3d\xda\x71\x81\xe5\xcd\x23\x3c"
+  "\x2d\xe5\x78\xaa\xd3\xb0\xf9\xc0\xbe\x21\x64\x33\x50\x46\x67\xfa"
+  "\xd9\x22\x36\x11\xc9\x97\xa4\x55\x22\xa6\x9e\x2a\x67\x42\x7b\xf9"
+  "\x59\xfe\xe3\x27\x15\x4c\xa5\x18\xd8\x98\x73\x3b\x2f\x02\x53\xb3"
+  "\x03\xd0\xa6\x6b\x81\xa9\x6b\x7c\x68\x53\xac\xfd\xb7\x16\xf4\xc5"
+  "\xd4\xfb\x8f\x36\xd0\x5c\x21\x4c\xf5\xe3\xe3\x2b\xff\x05\xf8\xf8"
+  "\xd9\xa3\xfd\xb1\x74\x76\xb2\x3f\x96\xce\x1e\xec\xc5\x52\xe5\xd9"
+  "\xb7\x42\x9b\xce\x1e\xf5\xdd\xd0\xa6\xb3\x47\x79\xf9\xf8\x39\x1a"
+  "\x0f\x96\x1e\x0b\x86\xa5\xb3\x46\x05\xc6\x52\xa4\x73\x2c\x9d\x35"
+  "\xca\x83\xa5\xc7\x02\xf0\xf1\x7e\x58\x3a\xe7\x94\xc0\xd2\x4a\x41"
+  "\x9b\x36\xa9\xb4\x69\xe5\xff\x83\x7c\xfc\x9c\xd6\xfe\xf2\xf1\x1f"
+  "\x74\x08\xfc\x24\x7c\x52\x31\xd4\xcb\xc7\x57\x06\xe7\xe3\xaf\x82"
+  "\xa1\xfd\xa2\x45\x39\x86\x3e\x70\xca\x1f\x43\x1f\xf8\xca\x1f\x43"
+  "\x1f\x7a\xb4\x2f\x86\x5e\x8e\x9f\x0f\xde\x1a\x08\x3b\x05\x1f\xff"
+  "\x50\x44\x70\xdc\x7c\x70\x6e\xff\x71\xf3\xdf\x97\xf9\xe3\xe6\x83"
+  "\xa5\xff\x3b\x70\x73\x6e\x98\x1f\x6e\xea\xaf\x11\x37\xff\x29\x3c"
+  "\xfd\xdc\x3e\xf2\xcf\xb9\x7d\xe4\x9f\x73\x7d\xe4\x9f\x73\xbf\x45"
+  "\xf9\xe7\xdc\xef\x48\xfe\x39\x77\x9e\x97\x06\x7d\xe8\x27\x57\xc7"
+  "\xcd\x07\xe7\x05\xc6\x4d\xa4\x73\xdc\x7c\x70\x9e\x17\x37\xaf\x46"
+  "\x83\x3e\x7c\x63\x3f\x70\xf3\x5f\x9c\xa7\x7f\xf8\x8a\xf2\xcf\x40"
+  "\x3c\x3d\xe1\x26\xc7\xcb\xa6\x3e\x3c\xfd\x43\xbe\x3c\x7d\xa5\x97"
+  "\xa7\x4f\x12\xb8\x65\x73\x59\xfc\x79\xfa\x6f\x1d\x47\x1f\xb9\xcd"
+  "\xe9\x91\x87\x3e\x0b\x1c\x7d\x84\xc7\x5b\x77\x7a\xe4\xa1\x8f\xbd"
+  "\xa1\xd6\x4b\xf0\xf4\xdb\x98\xa8\x57\x00\x9e\x9e\xeb\x0e\x3f\xb2"
+  "\xde\xc3\xd3\x37\xf5\xe5\xe9\x1f\x5b\x18\x1c\x53\x1f\xa9\x0c\xc8"
+  "\xd3\x13\xff\xcd\x31\xd5\xc4\x31\xf5\xe2\x0e\x5f\x4c\x4d\x3e\xc4"
+  "\x31\xf5\x5e\x15\x53\x1f\xe9\x70\x62\x6d\x3a\xc3\xaf\x8e\xa9\x54"
+  "\x8e\x17\x53\x33\xfe\x39\x98\x6a\xbd\x76\x4c\xf5\xb5\x57\x7d\x0b"
+  "\x6d\xf7\x60\x2a\xef\xe3\x47\xe7\x37\xa4\x11\xa6\x66\xf4\xe1\xef"
+  "\x2b\x03\xf3\xf7\x87\x99\x96\xfa\x47\xe5\xef\x69\x0c\x38\xde\xfc"
+  "\x8f\xf2\xf7\x8f\xbe\xe9\x8f\xad\x8f\x76\xf8\x63\xeb\xa3\x2f\x7a"
+  "\xb1\x55\x79\xf6\xad\xf0\xf7\x8f\x56\x7f\x37\xfc\xfd\xa3\xd5\x5e"
+  "\x6c\x7d\x6c\xfb\xd5\xb1\xf5\x91\xaa\xc0\xd8\x8a\x74\x8e\xad\x8f"
+  "\x54\x5d\x11\x5b\xef\xf5\xc5\xd6\x5f\x3c\xad\x62\xab\x97\xbf\xc7"
+  "\xfc\xa0\xf5\x97\x65\xf9\xe6\xfc\xfd\x8c\xef\x9a\xbf\xff\xc5\xc6"
+  "\x7e\xf1\xf7\x3b\x80\xb3\xe0\xc5\xd7\x7e\x08\xfe\xfe\x01\x85\xbf"
+  "\x6f\x2e\xef\xc3\xdf\x97\x5f\xc6\xdf\xe7\x3e\xa0\x60\x2a\xd6\x14"
+  "\xc7\xd4\x05\x95\xdf\x9c\xbf\x7f\x90\xc6\x70\xde\x7a\x7f\x4c\x9d"
+  "\xf7\xb4\x3f\xa6\xa6\x0d\xa5\x7a\x09\x4c\x2f\x0f\xcc\xdf\xf3\x75"
+  "\x3e\xef\x43\x3f\xfe\x1e\xf5\xbb\x9c\xbf\x4f\x3d\xe4\x87\xa9\x29"
+  "\xbe\x98\x3a\xcf\xe5\x47\xa7\xa2\x5d\x84\xa9\xaf\x7c\x2a\x30\xf5"
+  "\xbf\x3e\xf5\xc1\xd4\xfb\xff\x4b\xc1\xd4\x94\xdb\x0e\xcf\xf5\xc5"
+  "\xd4\xc7\x13\x54\x4c\xe5\x78\x99\xe2\xd4\x9a\x93\x2f\xd7\x3b\xe1"
+  "\xfa\x3e\xa4\x0b\x84\xb2\xc9\x56\x8c\xca\xdc\xf7\x69\xc6\xd5\xf5"
+  "\x4d\x92\x03\xeb\x9b\xd8\xb2\xec\xac\xbe\xd5\xc2\xf5\x4c\xca\x48"
+  "\xcf\x64\x3d\xbb\xb9\xac\x47\xf8\x09\xe0\x3e\x0c\x83\xf8\x08\x78"
+  "\xfc\x51\x2f\xce\x92\x4e\xd6\x4e\xd2\xc9\xba\x28\x74\x80\x30\xde"
+  "\x97\xfb\x05\x50\xe9\x26\xe0\xc1\x9b\x9f\xf6\xc5\xd9\x94\xf7\x1a"
+  "\x68\xfe\xcc\xcb\xe8\xc3\xf3\x97\xff\x0b\xf0\xfc\xa9\xc3\xfd\xf1"
+  "\x35\x75\xa6\x3f\xbe\xa6\x6a\xbc\xf8\xaa\x3c\xfb\x56\x68\xd7\x54"
+  "\xc3\x77\x43\xbb\xa6\x1a\xbc\x3c\x7f\xea\x05\x0f\xbe\x36\xfa\xe0"
+  "\xeb\xa7\xbe\xf8\xfa\x78\x28\xc7\xd7\x4f\xfb\xe2\x2b\xd2\x39\xbe"
+  "\x3e\x1e\xea\xc1\xd7\xc6\x3e\x3c\xff\xa7\x7d\xf1\x35\xed\x13\x8e"
+  "\xaf\xcd\xe5\x7d\x68\xd7\xf2\xab\xf3\xfc\xcd\xff\x6a\x3c\x7f\x5a"
+  "\x53\xbf\x78\x7e\xc2\xd4\xc5\x02\x53\x09\xb3\x54\x5c\xf5\xf2\xfc"
+  "\xe5\x41\x79\xfe\xab\xe1\x6a\xbf\x68\x55\x8e\xab\xf3\x3f\xf1\xc7"
+  "\xd5\xf9\x27\xfd\x71\x75\xe1\xfc\xbe\xb8\x7a\x39\xa6\x2e\xb8\x31"
+  "\x10\x9e\x0a\x9e\x7f\xa1\x3e\x38\x96\x2e\x48\xea\x3f\x96\x3e\xb1"
+  "\xda\x1f\x4b\x17\x6c\xfa\xdf\x8b\xa5\xe9\x83\xfd\xb0\x54\x7f\x8d"
+  "\x58\xfa\x4f\x91\x03\xa4\x2f\xf4\xc7\xd2\xf4\x52\x7f\x2c\x4d\x9f"
+  "\xe5\xc5\x52\xe5\xd9\xb7\x82\xa5\xe9\xe9\xdf\x0d\x96\xa6\xa7\x7b"
+  "\x69\xd5\x85\x53\xaf\x8e\xa5\x0b\xe6\x04\xc6\x52\xa4\x73\x2c\x5d"
+  "\x30\xc7\x8b\xa5\x27\xaf\x82\xa5\x4f\x8e\xee\x07\x96\xfa\xcb\x01"
+  "\xfa\x62\xe9\x77\x2e\x07\x78\x72\x54\xbf\xe4\x00\x2a\x96\x3e\x70"
+  "\xb9\x1c\x80\xf0\x95\xcb\x01\xd0\x5f\x2a\x86\x71\x39\xc0\x34\x81"
+  "\x65\x36\x57\x91\x9f\x1c\xe0\xdb\xc7\xd6\x5f\xde\xe1\xf4\xc8\x53"
+  "\x0b\x80\xad\xbf\xe4\xb1\xa4\x9c\x1e\x79\xea\xa2\x0f\xd5\x7a\x09"
+  "\x39\xc0\xb3\x4c\xd4\x2b\x80\x1c\x20\x91\x97\xf7\x8c\x9f\x1c\xc0"
+  "\x07\x6b\x51\xd6\xfa\xe0\x38\xfb\xcb\x2a\x3f\x39\x40\x8b\x17\x67"
+  "\x2f\x92\x8e\x3a\x70\x90\xe3\xec\x30\x5f\x9c\xcd\xf8\x9c\xe3\x6c"
+  "\xa2\x8a\xb3\xbf\xec\xea\xc6\xda\xec\xee\x2f\xce\x92\x1d\xc1\xa7"
+  "\x69\xdf\x0d\xce\x56\xf7\x03\x67\x7d\x64\x03\x6f\xa2\x3f\x3c\x38"
+  "\xcb\xfb\x3d\x73\x5d\xc3\x3c\xc2\xd9\xb4\x3e\xb2\x81\xf2\xc0\xb2"
+  "\x81\x43\xdf\x85\x6c\x20\xf3\xb8\x3f\xde\x2e\x8a\xf0\xc7\xdb\xcc"
+  "\x77\xbc\x78\xab\x3c\xfb\x56\x64\x03\x99\xc7\xbe\x1b\xd9\x40\xe6"
+  "\x31\x2f\xde\x2e\x7a\xfd\xea\x78\xfb\xcb\xea\xc0\x78\x8b\x74\x8e"
+  "\xb7\xbf\xac\xbe\x22\xde\x26\xfa\xe2\xed\xaf\x5e\x54\xf1\xd6\x2b"
+  "\x1b\x28\x57\x64\x03\x45\x57\x97\x0d\x34\x07\x91\x0d\xdc\xf3\x5d"
+  "\xcb\x06\x7e\x55\xde\x1f\xd9\xc0\xa5\x1d\x42\x6f\x7f\x2d\xe9\xed"
+  "\x3f\x0e\xfc\x9d\xf3\x11\xfa\xe0\xea\x7a\xfb\xb9\xaa\xfe\x69\x5a"
+  "\xa9\x82\xb3\xa5\x01\x65\x03\x1f\xb4\x05\x97\x0d\x7c\x70\xcc\x57"
+  "\xff\x74\xf1\x2e\xff\x73\xab\xc5\x2f\xaa\xe7\x56\x1f\x7c\x4c\x38"
+  "\x6b\x7a\x85\xee\xa5\x92\x14\xc5\x67\xb9\xa9\x92\xea\x19\x48\x8f"
+  "\xff\x2d\xc9\xf7\x2c\x6b\xb1\xdb\x23\x2b\x68\x24\xbc\x2d\x65\x92"
+  "\x9c\x11\x4e\x7e\xbd\xb9\xac\xe0\x61\x9a\x7b\xa6\x47\x7d\x71\xf7"
+  "\xc0\x09\x5f\xdc\x7d\x2a\x4e\xc5\x5d\x37\x70\xf7\x9d\x96\x52\x21"
+  "\x7f\x7d\x4c\xe8\xa6\xee\x7d\xcc\x47\x37\xf5\xa3\x3f\x2b\xb8\xbb"
+  "\x64\xf4\x61\x3b\xda\x7f\x25\xfd\x29\xbc\xff\xea\x89\x6b\xd5\x41"
+  "\x2d\x0d\xa8\x3b\xa5\xe0\x53\x40\xfd\x29\xd4\x55\xbf\x4b\x59\xab"
+  "\x6e\xac\xd3\x5d\x3e\xfa\x53\x65\x6b\xb0\x9e\x15\xbb\x92\x2b\xea"
+  "\xa1\x3e\xe6\xd5\x43\x95\x4b\x52\x22\x69\x7f\x93\xb6\xa7\x34\xf6"
+  "\xc8\x19\x21\x72\x4c\x4a\x24\x7d\xbf\xb7\x17\xfb\xce\xdd\xc9\x21"
+  "\x82\xaf\x7b\xdc\x01\xec\x19\x22\xfa\x7d\x49\x9a\x1b\x7b\x8d\x1b"
+  "\x7b\x8d\x54\xf2\xb8\xc3\x45\xb4\xc9\x8e\xc7\xbb\xca\xc0\xe7\xb9"
+  "\x0a\x78\x6c\xc1\x41\xc5\xe0\xf5\xf6\x10\x9f\x77\x16\x6b\xc3\x1c"
+  "\xa7\xa5\xfa\xa8\x38\xaa\x6b\x43\x3b\xce\x5e\x99\x96\x73\x7d\xed"
+  "\xc5\x51\xeb\x7d\x1f\xe0\x9b\x4b\x1f\x6a\xa0\xb9\x9b\xec\xb5\x29"
+  "\xe0\x34\x73\x10\x5d\x59\xaa\x8b\xf0\xaf\x88\xb9\xf0\x2d\xc8\x24"
+  "\x7c\xeb\xe3\x8f\xeb\x4b\xf7\xf9\xe3\xfa\x52\xbb\x3f\xae\x2f\xdd"
+  "\xee\xc5\x75\xe5\x19\x70\x1d\xe3\xc6\xe9\x68\xec\x7d\xdf\x90\x8e"
+  "\x5e\xba\x57\xc5\x75\x49\xc1\xf5\xdd\xd7\x80\xeb\x57\xa4\xa3\x7d"
+  "\x70\x29\x38\xae\x2f\xdd\xeb\x95\x49\x98\x9e\x09\xa8\x23\x7b\xc2"
+  "\x17\xd7\x9f\x8a\xe7\xb8\x7e\xa2\x2f\xae\x23\x9d\xe3\xfa\x53\xf1"
+  "\x41\xed\x09\x4e\xf4\x3d\x4f\x5b\xf6\x14\xc7\xf5\x26\x45\x47\xb6"
+  "\xb1\x1f\xf6\x04\x4d\x02\xd3\x55\x2c\x27\x79\xd5\x77\x2b\x93\x58"
+  "\xb6\xb8\x3f\x32\x09\x8e\xe5\x1d\x02\xcb\x09\x1b\x55\x3c\xbf\x16"
+  "\x7b\x82\xab\xe1\xb9\x4a\x37\x13\x9e\x07\xa3\x9b\xfd\xf1\x7c\xf9"
+  "\x53\xfe\x78\xbe\x7c\x99\x3f\x9e\x67\x3f\xe5\x8f\xe7\xd9\x8b\xfb"
+  "\xe2\xf9\xe5\x58\xbe\xfc\xbd\x40\x38\x6e\x7a\x98\x64\x14\xd9\xb1"
+  "\xc1\x31\x7c\x79\x47\xff\x31\x7c\xc5\x57\xff\xeb\x30\x5c\xdf\x17"
+  "\xc3\xb3\x46\x11\x06\xb9\x0b\xfb\x60\xf8\x22\x05\xc3\x15\x1c\xd9"
+  "\xd3\xae\xd0\xc2\x7d\x31\xbc\x03\xed\xb8\x0a\x3f\xee\xfa\x7b\x5f"
+  "\x0c\x5f\x39\xdc\x0f\xc3\xf5\x57\xc1\xf0\x45\x42\x0e\xe2\xa7\x97"
+  "\x1b\x44\x16\x82\x76\xc4\xed\x0a\x42\x9b\xab\x7d\xe6\x5b\x1f\x7f"
+  "\x0c\x5f\xb9\xcc\x1f\xc3\x57\x56\xf8\x63\xf8\xca\x47\xbd\x18\xae"
+  "\x3c\xfb\x56\x68\xf3\x95\xa6\x6f\x9d\x36\x57\xe7\xc7\x15\x31\x7c"
+  "\xa5\xc9\x4b\x9b\x67\xcf\xba\x3a\x86\x2f\xef\x0a\x8c\xe1\x48\xe7"
+  "\x18\xbe\xbc\x2b\xa8\x9d\xc3\x65\x18\xbe\xea\xb6\x7e\x60\xb8\xbf"
+  "\x2c\x44\xc5\x70\x45\x16\xb2\xc7\x47\x16\xe2\x2e\x10\xb2\x90\x5d"
+  "\xed\x62\x6e\x0c\xd1\x88\x79\x8a\xf9\x63\xd8\xad\xbd\x32\xef\xb6"
+  "\xeb\x1b\xc9\x41\x56\x8d\xe9\x8f\x1c\x84\xe3\x37\xd9\x38\x3c\x0a"
+  "\xdc\x6e\xbc\x46\x1b\x87\x24\xd5\xc6\xc1\x12\xc4\xc6\x41\xc1\xf3"
+  "\x94\x7f\x00\xcf\xb9\x8d\x43\xce\x9d\xfe\x32\xe6\x9c\xa9\xaa\x8c"
+  "\x59\xe0\x79\xee\x03\xfe\x78\x9e\x3b\xc7\x63\xf3\x00\xcc\xb7\x99"
+  "\xb6\x5d\x66\xf3\xe0\xc1\x76\x2e\x07\xcd\x79\xd1\xfa\x70\x2b\xf3"
+  "\xe0\xfb\x3c\x2f\xbe\xa3\x2c\x8d\x1f\xb6\xb7\xf8\x62\x7b\x4e\x9d"
+  "\x1f\xb6\x7f\x5a\xea\xaf\x1f\xd1\x62\xf2\xc1\x76\xd5\xe6\x61\xf5"
+  "\xa1\xc3\xcd\x57\xc1\x76\xbc\x7f\xed\x36\x62\xdf\x2e\xb6\xab\xf6"
+  "\x0d\x01\xb1\xdd\xd7\xbe\xc1\x47\xff\x81\xb0\x9d\xc7\xc3\x18\xda"
+  "\x07\xdb\xd7\x66\x68\xdd\x07\xb1\x1e\x80\xeb\xb4\x46\xdc\x32\xb0"
+  "\x9d\xf7\xf7\x1a\xe6\x8b\xed\xbd\x05\x02\xdb\x77\xb6\xff\xe3\xd8"
+  "\xee\xa1\x87\x7d\xb1\xfd\x5e\xc2\xf6\x35\x6e\x61\x7f\x91\x7f\x6d"
+  "\xf6\x17\x7d\xf4\x33\x76\x5e\x83\xfc\xe5\x8a\x18\x1f\xa0\x5e\xfe"
+  "\x18\xbf\xf6\x21\x7f\x8c\x5f\x5b\xe4\x8f\xf1\x6b\xef\xf4\x62\xbc"
+  "\xf2\xec\x5b\xa1\xd3\xd7\xce\xfd\x6e\xe4\x2f\x6b\xe7\x7a\x31\x3e"
+  "\x77\xfc\xd5\x6d\x2f\x72\x1a\x03\xeb\x66\x20\x9d\x63\x7c\x4e\xe3"
+  "\x15\x6d\x2f\xfc\xe4\xdd\xeb\x6e\x0e\x68\x7b\xd1\xf8\xcf\xd3\xcd"
+  "\xf0\x9d\x2b\x7d\xe5\x2f\xdf\x5c\xf6\xbd\xce\xd8\x5f\xf9\x0b\xd9"
+  "\x5e\xac\x3d\xee\x63\x7b\xd1\x7c\x75\xdb\x8b\xdc\x87\xae\x51\xfe"
+  "\x72\x05\xdd\x8c\x0f\xe6\xf8\xea\xbb\xe5\xdd\xe8\x8f\xef\x79\x37"
+  "\x7b\xf0\xfd\x41\xc2\xf7\x82\x3b\xfc\xf1\xbd\x60\x22\xd5\x33\x90"
+  "\x2d\xc6\x5b\x7e\xe7\x8a\x79\xeb\xfc\x75\x35\xfa\xc8\x5f\x1e\xa4"
+  "\xb9\xb7\xfe\x94\x1f\xbe\x7f\xea\x8b\xef\x79\x95\x81\x68\x77\x92"
+  "\x7b\x73\x9d\xe2\x14\x1f\x9b\xb6\xfb\x55\xfd\x37\xf3\xeb\x87\x93"
+  "\xd1\x7e\x7b\x10\x5d\xb7\x14\xa1\xeb\xc6\x75\xdb\x48\x0e\x8e\xb2"
+  "\x5e\x4b\x31\x69\xf3\xd2\x64\x89\x74\xdd\xfa\xea\xb9\x91\xee\x1b"
+  "\xe9\xba\x1d\xcd\xb0\x04\xd5\x73\xa3\xb9\x19\x4c\xd7\x0d\xf5\x8e"
+  "\xe1\x58\xff\xb9\x82\xf5\x8a\xae\x5b\x59\xb6\x57\xd7\xcd\x0f\xeb"
+  "\x03\xe8\x0f\xbf\xf9\x69\x7e\x60\x3a\xde\xec\xc5\xfa\x1e\xa2\xe3"
+  "\xff\x4f\x1f\x59\x0c\x1f\x03\x73\xc7\x3f\x55\x16\xc3\xb1\x3e\xff"
+  "\xf3\x06\x9a\xc7\xf3\x4c\x01\x64\x31\x97\xeb\x38\xff\xf3\x64\x31"
+  "\xeb\x7f\xe2\x8f\xf1\xeb\x17\xfb\x63\xfc\xfa\x9b\xbd\x18\xaf\x3c"
+  "\xfb\x56\x30\x7e\xfd\xe4\xef\x46\x16\xb3\x7e\xb2\x57\x16\x53\x30"
+  "\x34\xa0\xfe\x9d\x9f\x8c\x3d\xaf\x2a\xb0\x8c\x3d\x4f\xd1\xbf\xcb"
+  "\xab\x0a\x6a\x13\x72\xd9\x99\x66\xc1\x25\x21\x63\xff\x06\x36\x21"
+  "\xcd\xff\x6a\xb2\x98\x02\x67\x7f\x65\x31\x5c\xb7\xf9\x38\xe9\x87"
+  "\xf4\xcf\x26\xe4\x6a\xd8\xee\xa1\xdd\xaf\x70\x86\xe9\x8f\xed\x1b"
+  "\x2e\xf9\x63\xfb\x06\xb7\x3f\xb6\x17\x85\xf9\x63\x7b\x51\x68\x5f"
+  "\x6c\xbf\x1c\xd7\x37\xce\x0a\x84\xe9\xa6\x07\x49\x16\xf3\xeb\xfd"
+  "\xc1\xf1\x7c\x63\x4e\xff\xf1\xfc\xe9\xf5\xff\xab\xf1\x5c\xdf\x17"
+  "\xcf\x9f\xae\xf9\xa7\xca\x65\x38\x9e\x17\xbe\xee\x87\xe7\xfa\xab"
+  "\xe0\xf9\x3f\x4d\x2e\xf3\xeb\x81\xfe\x78\xfe\xeb\x29\xfe\x78\x5e"
+  "\x78\xce\x8b\xe7\xca\xb3\x6f\x45\x2e\xf3\xeb\x88\xef\x46\x2e\xf3"
+  "\xeb\x08\x2f\xcd\xfe\xeb\x53\x57\xc7\xf3\x8d\xf9\x81\xf1\x1c\xe9"
+  "\x1c\xcf\x37\xe6\x07\xd5\xa7\xbe\x0c\xcf\x8b\x0e\xf5\x03\xcf\x03"
+  "\xea\xa8\xfc\x6b\xc8\x65\x8a\x6a\xfb\x2b\x97\x09\x66\xa7\x42\xf8"
+  "\xee\xd5\x4f\xf1\xb1\x53\x49\x50\xed\x54\xf2\xfd\xf5\x53\xbe\x75"
+  "\x6c\x7f\xe6\xb8\x3f\xb6\x3f\xf3\x89\x3f\xb6\x6f\xbe\xe0\x8f\xed"
+  "\x9b\xbb\xd4\x7a\x0a\xb9\x4c\xc1\x65\x76\x2b\xfe\x38\xff\xec\x4f"
+  "\xac\x0f\xb6\xb2\x40\x58\x8f\xb2\x5e\x0e\x8e\xf3\xcf\xa6\x05\xc3"
+  "\x79\xd2\x57\xf9\x5d\x4a\x46\x00\x9c\xff\x4d\xe6\xff\x0f\x38\x1f"
+  "\x4c\x0f\x85\xf3\x41\xc0\x78\xc2\x7b\x8e\xef\x0a\xd6\x13\xce\xbb"
+  "\xdf\x0e\x24\xa3\xf9\x4d\xc5\xff\x14\xce\x07\x97\xd1\x6c\x7a\xb1"
+  "\x61\x9e\x82\xf3\xd7\x62\x43\xf3\x9e\xbf\x8c\xa6\x6c\xd1\xff\xb4"
+  "\x8c\x66\xd3\x25\x7f\xbc\xdf\x3c\xc6\x1f\xef\x37\x7d\xee\xc5\x7b"
+  "\xe5\xd9\xb7\x42\xbf\x6f\x72\x7e\x37\x32\x9a\x4d\x4e\x2f\xde\x6f"
+  "\x3e\x7e\x75\xbc\x7f\x36\x23\x30\xde\x3f\xab\xf8\x66\x7b\x36\xe3"
+  "\xda\xf1\xbe\xd8\x83\xf7\x97\xdb\xcf\xe4\x7f\x73\x1d\x99\xa9\xdf"
+  "\xb5\x8c\xa6\x38\x28\xfe\x5f\xc9\x3f\xc6\x37\x97\xd1\x28\x36\x89"
+  "\x0b\x02\xfb\xc7\x38\x7c\x05\x1d\x99\xc3\xf5\xbe\x58\xbf\xe5\x3d"
+  "\x7f\x5d\xc4\x2d\x87\x54\x5d\xc4\xc3\x0d\x84\xf5\xcf\x9d\xf1\xc7"
+  "\xfa\xe7\x3a\x82\xc9\x68\xde\x94\x7c\x75\x12\x2d\x37\xfb\xcb\x68"
+  "\xca\xfd\x65\x34\xf7\xd3\xdc\x7b\x6e\x57\x70\xac\xb7\xcc\xf4\xd7"
+  "\x01\x17\x36\x8a\xaf\xa4\x28\x3a\xe0\x29\x3e\x3a\xe0\xf7\xfd\xa7"
+  "\x82\xf5\x5b\x33\xeb\x1a\x5d\xac\x3f\x7a\x88\xff\xb8\xae\x77\x51"
+  "\x40\x1d\x44\xbe\x07\x5c\x41\x0f\x31\xf5\x13\x3d\xe9\x34\xbb\x76"
+  "\x67\xfb\xe8\x21\x5e\xc1\x9f\xb1\x1f\xfe\xa7\x98\x82\xe2\xff\x25"
+  "\xd9\x8b\xff\xd2\x8f\xbd\x72\x1b\x89\xe8\x7c\x3e\x2e\x5b\x2b\xfe"
+  "\xa7\xe4\x36\x81\xe4\x24\xd6\x44\xc2\xff\x6d\xcf\x0b\x3a\x3f\xe3"
+  "\x5f\x4c\x6e\xb3\xed\x9c\x3f\xee\x3f\x37\xca\x1f\xf7\xb7\x7d\xe2"
+  "\xc5\x7d\xe5\xd9\xb7\xa2\x8b\xbe\xcd\xf1\xdd\xd0\xf9\xdb\x1c\x5e"
+  "\xb9\xcd\x73\x47\xaf\x8e\xfb\x96\xb9\x81\x71\xdf\x32\x57\xe0\xbe"
+  "\x65\xee\x15\xe5\x36\x7e\xba\x91\x25\xaf\xff\xc3\x72\x1b\x95\xce"
+  "\xff\xce\xed\x7a\x4a\xaa\xfa\x23\xb7\xf1\xd8\xa4\xff\x43\x72\x9b"
+  "\xc0\x78\xaf\xd2\xf6\x87\xaf\x70\xe6\xea\x8f\xf7\xdb\x5f\xf7\xc7"
+  "\xfb\xed\x6f\xf8\xe3\xfd\xf3\x1f\xfa\xe3\xfd\xf3\xff\x97\xbd\xaf"
+  "\x8f\x8b\xaa\xca\xff\x3f\x73\x07\x0a\x13\x64\xb0\xc1\xd0\xd5\x9a"
+  "\xfa\x62\x8d\xa9\xa5\x9b\xba\xd8\xea\xaa\xa5\x02\xe5\xe3\xa6\x2e"
+  "\x3e\xa3\x41\x41\xf9\x80\x84\x86\x0a\x88\x8f\xe1\x33\x16\x18\x1a"
+  "\x0a\x16\xb6\x50\xa2\xb8\xab\x2d\x96\xd6\xd8\x6a\xa1\xf1\x64\xab"
+  "\x1b\x16\xae\x23\x8b\x86\x2e\xda\xa8\x28\x4f\x33\x73\x7f\x9f\x73"
+  "\xcf\x1d\xee\xdc\x99\x7b\x87\xb9\x77\x10\xe1\xf5\xf3\x8f\x79\x29"
+  "\x77\xee\x3d\x73\xee\xe7\xf3\x3e\x9f\xf3\x7e\x7f\xee\xb9\x9f\x53"
+  "\x2a\x94\xb7\xe1\xc7\xfa\xed\xee\x42\x71\x3e\x6a\x1c\xce\xdb\xec"
+  "\x48\x14\x8f\xf1\xdb\xfb\x49\x8f\xf1\x1f\x8e\x7d\x10\xe3\x6d\x62"
+  "\xbc\xca\x36\xc6\x7f\x98\xd4\xaa\x1c\x9f\x89\xf1\x69\xf1\xbc\x18"
+  "\xdf\x82\xb9\x1c\x67\xde\x27\x11\xe7\xf6\x69\x36\xeb\xdf\x77\xd8"
+  "\xac\x7f\x4f\xb3\x5a\xff\xbe\xc3\xa3\xe5\x62\x7c\x5a\xcb\xaf\x7f"
+  "\x77\x2a\xc6\xa7\x59\xad\x7f\xdf\x71\xb0\xf9\x18\xbf\x3d\x40\x38"
+  "\xc6\xc3\x71\x26\xc6\x6f\x0f\x70\xc8\xed\x79\x31\x7e\x67\xea\xbd"
+  "\xc8\xe5\xdc\x9f\xf7\x8d\x76\xa6\x48\xc9\xe7\x38\xaa\x3b\x22\x9a"
+  "\xcf\x09\xb0\xe4\x73\xa2\x44\xf2\x39\x2d\x15\xf3\x3f\xda\xcb\x8f"
+  "\xf9\x1f\xe5\xf0\x63\x7e\xc6\x79\x7e\xcc\xcf\x28\xe3\xe7\x73\xa2"
+  "\xed\xf2\x39\xfc\xf8\x9f\xde\x41\x37\xce\x3a\x9f\x93\x69\x95\xcf"
+  "\xc9\x58\x2f\x1e\xff\xd3\x45\xe3\xff\x5d\x26\xfe\x87\x0a\xc4\xff"
+  "\x5d\xff\x9f\xc4\xff\x50\x17\xe2\xff\xae\xfb\x10\xff\x77\xaf\x25"
+  "\x39\x1e\x27\xeb\xa4\x1c\x91\x9e\xe3\x71\x6d\x1e\xd8\x7d\x81\x3f"
+  "\x0f\x64\xa8\xf8\xf3\xc0\xee\x93\xdc\x3c\xc0\x7e\xd7\x22\xf3\xc0"
+  "\xee\xf2\xfb\x33\x0f\xec\x2e\xe7\xe6\x81\x8c\x23\xcd\xcf\x03\xe9"
+  "\x22\xf3\x40\x3a\x3b\x0f\xa4\x4b\x98\x07\x32\x73\xc4\x73\x3c\x51"
+  "\xf2\x73\x3c\x83\xef\xf7\x7b\x50\x99\xd9\x92\x72\x3c\xdb\x67\xe7"
+  "\x15\xe2\x1a\x29\x97\x10\xb5\x7c\x8e\x25\xc7\xa3\xb3\xc9\xf1\xe8"
+  "\xec\x72\x3c\x4b\x2f\xb1\xf1\x7f\x0c\xfb\xbe\xe9\x38\x17\x6a\xa4"
+  "\x30\x7b\x49\xef\xd9\xcb\x5f\x37\xbf\x87\x89\xff\x5c\xfd\xbe\xbd"
+  "\x03\x71\xbf\xc8\xfc\xa3\x73\x50\x03\x75\xcf\x1d\x5e\x4e\x67\x8c"
+  "\x50\x8d\x94\x2c\xde\xba\x1b\xfe\xfb\xa6\x1f\x6b\x78\xf1\x7e\x1c"
+  "\x79\xdf\xf4\x33\xa1\xe7\xb4\x4d\x35\xf9\x3f\xe9\xcf\xd4\xe4\x6f"
+  "\xaa\xe5\xf7\x71\x98\x53\xb5\xa4\x67\xb1\xb5\xa4\xff\x73\x1f\x6a"
+  "\x49\x3b\x5b\x93\xff\x3f\xb6\xf5\xfb\x3e\x29\x2a\x29\xd4\xa1\x62"
+  "\x8c\x91\x19\xb6\xb5\x4f\x75\xc2\xef\xee\x53\xec\xbb\xfb\x0b\xee"
+  "\x4d\x1d\x14\xdc\x1f\x66\xce\xef\x9c\x53\x9a\x9b\x60\x60\xfa\x83"
+  "\xf7\xed\x06\x3f\x4f\x2c\x04\xac\x9a\x71\x3c\x8d\xc6\xf1\x34\x6b"
+  "\x0d\x73\xee\x25\xc0\x42\xe7\x41\xa5\x18\xc7\x5b\xcc\xc8\x33\x6a"
+  "\x09\x8e\xad\x59\xcc\xba\x2f\xa0\x11\x10\x5b\xc9\x79\xf1\x97\x68"
+  "\x93\xa9\xf3\x9f\x4a\xa1\xff\x0f\xef\x5f\x50\xea\x5e\xac\xaf\x81"
+  "\x71\x71\x8d\xd9\xc7\xb5\xc4\x58\xab\xc3\xbe\xf8\x7a\x41\xa9\x1b"
+  "\x0d\xf1\x37\xe3\x0d\xe4\x21\x6d\x9c\x66\x31\xfb\xd4\x33\xef\xae"
+  "\x77\xce\x29\xc7\x75\x40\x2c\xdc\xca\xfc\x1b\x97\xdf\xda\x05\xf6"
+  "\x31\xd3\x64\xee\x9b\x1d\x49\xe2\x06\xfc\x9e\x11\x6c\xc9\xac\xb1"
+  "\xc5\x71\x83\xd9\xc3\x0a\xe2\xc6\xee\x5b\xdc\x73\x6c\xdc\x3e\xb6"
+  "\x11\xc9\xa3\xec\xe5\xd6\xbf\xe8\xc5\x62\xeb\xc7\x5a\xe1\xd8\xfa"
+  "\xb1\x96\xc4\xd6\x8f\xb5\x4d\xb1\x55\x2f\x90\x47\xe1\xad\x63\xdf"
+  "\xcb\xae\x7f\xd1\xd9\x70\x6c\x5d\x3b\xac\x8f\xb2\x57\xd2\xfa\x17"
+  "\x26\x9e\xce\x23\xf1\x14\xc7\x2b\x4b\x4c\xe5\xf2\x28\x3a\xd1\x3c"
+  "\x4a\x73\x31\x55\xd2\x3b\xfc\x4c\x4c\xfd\xb4\x9e\x1f\x53\x3f\x35"
+  "\xf1\x63\xea\x67\xf1\xb6\x31\xd5\x3e\x9e\xfe\x75\xa8\x50\x2c\x25"
+  "\xf5\x51\x3e\xeb\x23\x1e\x47\xff\x1a\x21\x16\x47\x99\xf5\xe9\xb3"
+  "\xac\xd6\xa7\x37\xc5\xd1\xec\xa5\xfc\x38\xfa\xd7\x7d\xce\xc6\x51"
+  "\x66\x6f\x93\xff\xb4\xc2\xde\x26\xb2\xe3\x68\x94\x4d\x1c\xcd\xf1"
+  "\xe5\xe2\xa8\xed\xfe\x26\xcd\xc4\xd1\xb7\xee\x4d\x0d\x14\x5e\x1c"
+  "\x35\x1b\x98\xfe\x68\x16\x30\x7d\xdd\xc1\x8f\xa3\x39\x85\xe2\x71"
+  "\x34\x27\x92\x8b\xa3\xe4\xbc\x7b\x1b\x47\x73\xd2\x78\x71\xf4\x2d"
+  "\xab\x38\xfa\x3f\x4e\x43\xe0\x35\x16\x4d\x71\x74\xbe\x55\x1c\x7d"
+  "\xab\xb9\x38\x9a\x93\x86\x6d\x44\x38\xea\x67\x33\x9b\x8f\xa3\x7f"
+  "\x8d\x12\x8e\xa3\x70\x9c\x89\xa3\x7f\x8d\xe2\xe2\xa8\x00\x47\xe5"
+  "\xc5\xd1\xcf\x47\x48\x88\xa3\x6d\xbc\x36\xca\xe7\xc3\x25\xe5\x2a"
+  "\xb8\x77\x3a\xed\x6b\xa4\xce\xb4\x7e\x27\x28\xdf\x66\xdf\x93\x7c"
+  "\xbb\x7d\x4f\x96\x5a\xde\xf1\x0c\x62\xe3\xea\x2b\x2e\xc4\x55\xe6"
+  "\x1d\xcf\x7d\x13\xf9\x6b\x4f\xf6\x4d\xb6\xac\x3d\x21\x71\xf5\xc0"
+  "\x55\x4b\xbf\xb8\x7d\x4f\xf2\x1d\xd4\x48\xdd\xb7\x97\x57\x1b\x25"
+  "\xc8\xba\x36\xca\x81\x1d\xe2\x35\x52\xf7\x15\xf2\x6a\xa3\x9c\xce"
+  "\x6e\xda\xf7\xc4\xb6\x46\x2a\x17\x63\x73\x2f\x30\x31\xb6\xa9\x06"
+  "\x55\xae\xaa\xa9\x46\x6a\x33\xef\x05\xe1\x76\xf6\x57\x44\xdc\xfb"
+  "\x18\xab\x93\x10\x63\x79\xfb\x9e\xd8\xd6\x98\xda\xbf\xb2\xa4\x20"
+  "\x1f\x15\x87\xe6\x0b\xd4\x46\xcd\xbf\xaf\x7b\x9f\xe0\x7e\x09\xc7"
+  "\xda\x03\xee\xfc\x58\x7b\x20\x80\x39\xf7\x82\x50\xac\xdd\x7f\x8e"
+  "\x8b\xb5\xe4\xbc\xf8\x0b\x36\xb1\xb6\x5c\x24\xd6\xc2\xbc\x9a\x71"
+  "\x45\x6a\xac\x3d\xe0\xc6\xc4\xda\x55\x6c\xac\xbd\xd6\xd2\xb1\xf6"
+  "\x80\x1b\x17\x6b\x0f\x9c\x6a\x7e\x8f\xa9\x7d\x67\x85\xdf\xcb\xd9"
+  "\x77\x96\xc4\xda\x7d\x67\x1d\xee\x31\xc5\x5b\xf3\x91\x77\xc4\xb2"
+  "\xc7\x14\x97\x0f\xc8\x67\xf3\x01\xed\x79\x4f\x94\xbc\x7c\xa9\xf9"
+  "\x80\x1f\x40\xbb\xe3\xf7\x2e\x97\xe3\x3d\xa7\x66\xe0\x3d\x51\xf2"
+  "\x6c\xf2\x01\x79\xf6\xf9\x80\xa9\x8e\x63\xac\xa4\x7c\x00\xf3\xde"
+  "\xe5\xc1\xc3\xfc\x18\x7b\xf0\x08\x3f\xc6\x1e\x9e\x68\x79\xcf\x12"
+  "\xf7\x47\xbc\x66\xea\xdf\xdc\x9b\xf2\x01\xe5\xfc\xd8\xca\xe5\x03"
+  "\x0e\x2b\xc4\x63\xec\xdf\xf8\xf9\xdf\x57\xb2\x79\xef\x59\x7e\x56"
+  "\x61\x5d\x87\xda\x52\x7f\xea\xef\x63\x4f\x9d\xb5\x8e\xb1\x7f\x8b"
+  "\x69\x4f\x75\xa8\x9b\x6a\x4d\x35\xb3\x96\xdb\xbe\x0e\xf5\xdf\xaf"
+  "\x96\x14\xe4\x21\xfc\x6e\x1b\x13\x6f\x79\xb9\x81\xbc\xfb\x93\x1b"
+  "\x28\xc8\x13\xc9\x0d\x1c\x9a\xcf\x8f\xb3\x87\x32\x99\x73\xcf\x0b"
+  "\xc5\xd9\x43\x43\xb9\x38\x4b\xce\x8b\x3f\x6f\x13\x67\xcb\x5a\x92"
+  "\xd3\x1e\x9a\x77\x6f\x73\x03\x87\xe6\x71\xb9\x81\xc3\x4e\xbc\xff"
+  "\xf8\xb7\x00\xe1\x38\xfb\x37\x36\xef\xfa\x37\x2e\xef\x5a\x26\xb0"
+  "\x5f\x0a\x2f\xce\x7e\xe1\x6b\x79\xff\x91\xe1\xb4\xe5\x16\x4e\x9b"
+  "\xd7\x0e\xf7\x4b\xf9\x42\x2d\x35\x37\x80\xdf\x73\xc7\xb1\x15\xc7"
+  "\x2e\x4b\x7c\xe5\x72\x03\x79\xe2\xb9\x81\x66\xe2\xab\xf4\xbd\xfb"
+  "\xfe\xe1\xcb\x8f\xaf\xff\xe8\xca\x8f\xaf\x5f\xee\xb5\x8d\xaf\xf6"
+  "\xb1\xf5\x1f\x53\x85\xe2\x2a\xc9\x0d\x7c\x39\x49\x3c\xa6\xfe\x63"
+  "\x8d\x58\x4c\x65\x6a\xfa\x55\x70\x6b\xa4\xb9\x98\x9a\xbf\x87\x1f"
+  "\x53\xff\x51\xe0\x6c\x4c\xbd\x2f\xfb\xa5\xc8\x8e\xa9\x11\x36\x31"
+  "\xf5\xc8\x50\x2e\xa6\xda\xee\x99\xd2\x4c\x4c\xbd\x57\x79\x02\xeb"
+  "\x98\xca\xe3\xae\x47\x8e\xf3\x63\xea\x91\x1a\xf1\x98\x7a\x64\x1b"
+  "\x17\x53\xc9\x79\xf7\x36\xa6\x1e\xd1\xdd\xdb\x3c\xc1\x11\x1d\xc7"
+  "\x5d\xbf\x5c\xdb\x7c\x4c\xfd\xc7\x26\xe1\x98\xfa\x8f\x4d\x24\xa6"
+  "\xfe\x63\x93\xf3\xef\x94\x7f\x15\x29\x21\xa6\xb6\xf1\xbd\x54\xbe"
+  "\x8a\x90\x9c\x27\xc0\xf9\x56\x1c\x4b\xcb\x5d\xab\x1d\x12\x6b\xa9"
+  "\x1d\x32\x92\x8d\xb1\xa3\x5d\x8d\xb1\x47\x97\xf2\xd7\x34\x1c\x8d"
+  "\xb7\xac\x69\x20\x31\x56\xd7\x83\xbf\x3f\xaa\x7d\xad\x10\x7e\x0d"
+  "\xd5\xa3\x45\x4d\x79\x02\x1c\x73\x47\x5a\xe7\x09\xbe\x29\x12\x8f"
+  "\xb7\x47\x6b\x78\x79\x82\xef\x84\xe3\xed\x5d\x5e\xbc\xfd\xda\x87"
+  "\x89\xb7\x4d\x35\x54\x8f\x05\x58\x6a\xa8\x36\xcb\x61\x79\xf1\x36"
+  "\xb4\x75\xe2\x6d\xbe\xf3\xf1\x96\xbf\x97\x8a\x6d\xbd\xd4\xaf\x0f"
+  "\x97\x9c\x80\x78\xcb\xd4\xeb\xb0\xad\x99\xea\x5c\xbd\x8e\x7b\x55"
+  "\x33\x15\xf7\x4b\x38\xee\x7e\x33\x98\x1f\x77\xbf\x99\xc7\x9c\x2b"
+  "\x18\x77\xbf\xe9\xc0\xc5\x5d\x72\x9e\xd3\x71\x57\x56\xce\xe0\x9b"
+  "\x80\x7b\x9b\x33\xf8\x26\x80\x8b\xbb\xdf\x98\x9a\x8f\xbb\x47\x8d"
+  "\xc2\x71\xf7\xa8\x91\xc4\xdd\xa3\x46\x87\x71\x97\xb7\x86\x40\x77"
+  "\x5d\xb0\x96\x47\x79\x7b\xdf\x67\x45\x57\x2d\x27\x67\x00\x31\x98"
+  "\x8a\xc3\x35\x9c\x42\xf1\x1a\x82\xe6\x73\x06\xcd\xc5\x5b\xe9\x39"
+  "\x83\xe3\x57\xf9\xf1\xf6\xf8\x75\x7e\xbc\x3d\xb9\x03\xf7\xcb\x61"
+  "\xce\x80\x89\x01\xdf\x0e\x6e\xca\x19\xe8\xf9\x71\x96\xcb\x19\x9c"
+  "\x0c\x16\x7f\xf6\xf5\x6d\x18\x8f\xdf\x8e\xb6\xa9\x59\x3d\x8b\x8b"
+  "\xb7\xa7\x8b\x2d\x6b\xc6\xfe\x99\x7a\x6a\x82\x75\xbc\xfd\x36\xdb"
+  "\xae\x66\xf5\xa4\x16\xac\x59\x3d\xa9\x85\x6b\x56\x4f\xe6\xd7\xac"
+  "\xde\x79\x97\x5b\x47\x26\xbd\x66\xf5\x89\xfe\x4c\x0c\xc6\x18\xc2"
+  "\x75\xab\x9d\xc9\x23\xdc\xe3\xbd\x56\x78\xb1\x97\x97\x47\x38\x71"
+  "\x98\x1f\x7b\x4f\x54\x89\xc7\xde\x13\x6b\xb9\xd8\x4b\xce\xbb\xb7"
+  "\x9c\xf7\xc4\xa1\x7b\x9b\x47\x38\x71\x88\xcb\x23\x9c\x5c\x2a\x18"
+  "\x7b\x79\xcf\xc6\xbe\x9d\x27\xfc\x6c\x0c\x8e\x33\xb1\xf7\xdb\x79"
+  "\xa2\x79\x04\xbb\xf5\x5b\xdf\xcd\x24\xcf\xc6\x58\xce\xab\x97\x90"
+  "\x47\x68\x73\x6b\x0c\xbe\x9b\x21\x27\x8f\x80\xe3\x2d\x8e\x67\x96"
+  "\x98\xeb\x4c\x1e\xa1\xe5\x39\xee\xf7\x33\xf9\x31\xf7\xfb\x39\xfc"
+  "\x98\xfb\x83\xc2\x36\xe6\xda\xc7\xdb\xef\xf7\x08\xc5\x5a\x92\x47"
+  "\x38\x9d\x27\x1e\x67\xbf\x2f\x14\x8d\xb3\x36\x6b\x73\xb9\x38\x5b"
+  "\x60\xe2\xc7\xd9\x02\x95\xac\x38\xeb\xec\x1e\x2c\x6d\x2a\xce\x86"
+  "\xda\xc4\xd9\x53\x3b\xb8\x38\x6b\xbb\x0f\x4b\x33\x71\xf6\x1e\xed"
+  "\xc3\x22\xce\x71\x4f\xf7\xe0\xc7\xd9\xd3\x13\xc4\xe3\xec\xa9\xeb"
+  "\x5c\x9c\x25\xe7\xdd\xdb\x38\x7b\xba\xfb\xbd\xcd\x2d\x9c\xee\xce"
+  "\x71\xdc\xd3\x97\x9a\x8f\xb3\xdf\x9f\x15\x8e\xb3\xdf\xb3\xcf\xc5"
+  "\xbe\x3f\x2b\xca\x71\xed\xe2\xec\x0f\x27\x25\xc4\xd9\x36\xbe\x06"
+  "\xe1\x07\x49\xf5\x2f\xac\xf2\xb5\x0f\x95\xe8\x6d\xde\x97\x38\x6f"
+  "\xfd\xbe\x84\x55\x6e\x61\xa4\x25\xb7\xc0\xdf\x9f\x25\xd6\x92\xbf"
+  "\x1d\xce\xc6\xdd\x97\x5c\x8d\xbb\x85\xe7\x6a\x9b\xe2\x6e\x34\xc4"
+  "\xdd\x42\xe6\xfd\x88\xda\xa6\xb8\x5b\xba\xd9\xd2\x2f\x6e\x7f\x16"
+  "\x91\xdc\xc2\x8b\xb8\xbd\xa2\x5e\x4d\xb9\x05\x1c\x87\x87\x5b\xe7"
+  "\x16\x4a\x87\x8a\xc7\xe0\xa2\x09\xbc\xdc\xc2\xb7\xc2\x31\xb8\x86"
+  "\x17\x83\x8b\x57\x32\x31\xf8\x45\x4b\x0c\x2e\x4a\xb9\x0b\xda\xf2"
+  "\xee\x3a\x69\x31\xb8\x86\x89\xc1\x41\xf7\x27\x06\x1f\x6a\x81\x18"
+  "\xcc\xd8\xbd\xa4\x67\x89\x0e\x62\xf0\x0c\x1c\x83\x83\x9c\xcb\x37"
+  "\xb4\xd2\x1e\x2d\xb8\x5f\xc2\xb1\xb8\x24\x87\x1f\x8b\x4b\xca\x99"
+  "\x73\x05\x63\x71\xc9\x52\x2e\x16\x93\xf3\xee\x6d\xbe\xa1\x24\xfb"
+  "\xde\xe6\x1b\x4a\xb2\xb9\x58\x5c\x3a\xbf\xf9\x58\x5c\x14\x22\x1c"
+  "\x8b\xe1\x38\x13\x8b\x8b\x42\x1c\xc6\xe2\x17\xad\x63\xf1\x99\x26"
+  "\xce\xcb\xcb\x37\xe8\xdb\xfb\xde\x2d\x67\x44\xf9\xaf\xe6\x71\x94"
+  "\x58\xa1\x38\x73\xb8\x24\x1d\xa1\xdb\xab\x50\x62\x89\xf1\x45\x04"
+  "\xc7\xc0\x7e\x67\x2e\x94\xf8\x05\x20\xf3\xfb\xc1\x05\x38\x1e\x7f"
+  "\x80\x3f\xc0\x71\x93\x29\x76\x6c\x31\x36\x3e\xc3\xac\x77\xc5\xc7"
+  "\x71\xec\xcd\xb0\xfa\x5e\xe8\xb7\xe8\xe4\xe0\x20\x72\xdd\x8f\x01"
+  "\xe4\xbd\x9b\xe0\x31\x96\xbf\x31\x36\xf5\x8a\x1f\x87\xd0\xdb\x82"
+  "\x47\x1a\x7c\x82\x47\x0a\x5d\xff\x94\x0a\x79\x74\x5a\x49\xd3\xbb"
+  "\xb7\xd3\x35\xb7\x9f\x0e\xc8\xbc\xbd\x01\xa1\xe4\xed\xb4\xa1\x76"
+  "\xdd\x8f\x31\x70\x8f\xe9\x1f\xc2\x79\xb7\x3b\x1f\xcd\xbc\xbd\x6a"
+  "\x02\x82\x63\x49\x96\x63\x60\x37\x64\x5e\xa5\xa4\xcd\xf0\x1d\xbd"
+  "\xdd\x73\x53\x46\x02\xc4\xaa\x38\x84\x9e\xbb\x8b\xc7\xcc\x8f\x69"
+  "\x80\x19\xf5\x16\x68\x73\x2b\xb4\x45\x3f\xf6\xbb\x1a\xc0\xa3\x5b"
+  "\xf1\x1a\x84\xc7\x74\x12\xdc\x57\xe6\x16\x6c\x7b\xe5\xb3\x69\x34"
+  "\xe5\x86\xcc\x7b\xff\x50\x47\xfb\x86\xe6\x81\x3f\x50\x72\x34\x62"
+  "\xde\x15\xdd\x0a\xe7\xd1\xd4\x0a\xda\xdc\x73\x10\xd8\xaf\x86\x8c"
+  "\x69\xe8\xdf\xd7\xa0\x63\x69\xf8\xdd\xdd\xd1\x48\x05\x1f\x4f\x3a"
+  "\x35\x34\xaf\x76\xdd\xbf\x34\x70\x9f\x1e\xb8\x5f\x62\xf7\xb8\x75"
+  "\x27\xcc\x3b\xbf\xf3\xc3\x73\x07\xf3\xfb\xf8\xb7\x99\xdf\xa1\xcc"
+  "\x49\x26\x38\x4e\xaf\x5a\x41\x97\xc4\x1a\x91\x37\xd8\x22\x03\xfa"
+  "\x8d\xf1\x68\xfe\x34\x20\x73\x75\x37\x84\xf6\x2f\xab\xa2\x4a\xa0"
+  "\xef\xa6\x0f\x7f\x57\xa3\x4b\xf8\x3d\x82\xef\x0d\x58\xb3\x5c\x51"
+  "\x9c\xed\x31\xfe\x2a\x42\x38\x9e\xc0\xff\x7b\xd5\xc0\x3c\x36\x16"
+  "\xfe\xde\x0a\xf7\x61\xbe\xed\xe7\x86\xcf\xbd\xa2\xf8\xd7\x39\xdd"
+  "\x92\x9f\x91\x77\x14\xf2\xd8\x02\xf7\x46\xce\xfd\x57\x16\x3e\x57"
+  "\xaf\x38\xab\xc5\x7d\x80\xbf\xf3\xe1\x6f\x7c\x1d\x5e\x43\x86\xe8"
+  "\xac\x3f\xd4\x31\xd8\x4c\x09\xcd\x33\xf7\xfc\x43\x1d\x13\xfb\xe0"
+  "\x3e\xb7\xc2\x3d\xc3\x39\x9e\x70\x8e\x27\xf3\x6f\x02\x52\xa5\xc0"
+  "\x31\xdc\x0e\xfc\xeb\xa9\x5b\xd0\x80\xdb\x4e\xc1\x6d\x8b\xd8\xc1"
+  "\x8d\x56\x87\x82\x36\x71\x63\xe6\x54\x4d\x82\xe2\x4c\x85\xe2\x6c"
+  "\x81\xb7\x82\xa6\xe9\xac\x41\x89\xab\x13\x90\x67\xb2\x19\x21\x5d"
+  "\x37\xdc\xce\xd9\x3d\xd0\xbe\x1b\xb6\x45\xed\xba\xb3\x89\x7a\xc5"
+  "\xbf\xfa\x60\xfb\x82\x3f\x6b\x34\x4f\x31\xf7\x5b\x86\x7f\x07\x5f"
+  "\xc3\x9e\xcf\xd4\xbe\xc7\x7d\xd6\x24\x28\x69\xf8\xfb\xb8\x52\x71"
+  "\x09\x29\xfd\x3c\xd7\xc1\xf5\x3a\x3d\x7a\xdf\x1f\x5f\xaf\x27\xd7"
+  "\x01\x96\xce\x9e\x05\x9f\x05\xe1\x63\xf8\x6f\x91\xfe\x7a\x5a\xfc"
+  "\x56\xe4\x07\xd8\xb0\xf5\x9d\x05\x23\x80\x0b\x0b\x46\x70\x7f\x0f"
+  "\x24\xe8\x29\x66\x1e\x56\x9c\x63\x74\xdd\x16\xf0\xa1\xe9\x23\x3f"
+  "\xb7\xad\x60\x5b\x73\x23\xf6\x4b\x05\x7c\xf7\xef\xae\xd8\x2f\x5b"
+  "\x97\x81\x4f\xc8\xb9\x43\xb8\xfe\xe3\xbf\xff\xcd\xf8\xd3\x0c\xbe"
+  "\x20\xef\x6e\x9e\xbb\x8e\xef\x67\xeb\x5d\xf0\x63\x17\xba\xe6\x44"
+  "\x2c\xf4\x0b\xe3\x16\x30\xb2\x3f\xba\x8e\xc2\xeb\xfa\xf0\xf1\xaf"
+  "\x6f\xd5\x51\x5b\xaf\x21\xcc\x2b\xd1\x66\x88\xcb\xbb\x96\x80\xcd"
+  "\xa1\x4d\xda\x7f\x50\xe2\xf3\x16\x3f\x2e\x03\xdf\x2d\x01\xec\x82"
+  "\xcd\xb7\x82\xfd\x76\x43\xcc\xc3\xff\xdf\x0d\xf3\x8f\x19\xce\xd3"
+  "\x2b\xfe\xad\x85\xf6\x54\xbb\xba\xd0\x86\x8c\x2e\x74\x35\xd8\x70"
+  "\x67\xed\xba\x7f\xbb\x59\x6c\x88\xfb\xb4\x15\x8e\x6f\x86\xef\xf5"
+  "\x8a\x73\x89\x04\x43\xe7\x26\x58\xee\x59\xcc\x9e\x9b\xf6\xa3\x80"
+  "\xcd\xfb\x51\xf7\x0d\xfb\xd1\x90\xe5\x95\x30\x2e\x57\x0d\xa3\x7f"
+  "\x98\x61\x84\x39\xf1\x93\xaa\x86\x2e\xc1\x99\xf8\xd9\x93\x79\xf5"
+  "\xef\x32\xd7\xee\x47\x7d\xf0\xbb\xb1\xe3\xab\x11\xc2\x73\xf8\x78"
+  "\xf7\x8b\x74\x49\xd4\x1d\x64\xf6\xf9\xa4\xca\xb4\xfa\xd9\xce\xe3"
+  "\xee\x20\x74\x52\x5b\x83\x12\x62\x60\x2e\xbf\x55\x85\x12\x6a\x68"
+  "\x43\x71\xe2\x55\x04\xb1\x67\x08\xb1\xdd\x4f\x27\xc6\x87\x23\x84"
+  "\xdf\x19\x34\xff\x4f\x8b\xbc\x22\x90\x5b\xdc\x79\xe4\xb7\xa2\x92"
+  "\xae\x32\x6d\x9f\x92\x9c\x10\x8f\xa8\xfd\xb7\xca\x08\xf7\x54\xfc"
+  "\x94\x7a\x0c\xbf\x9f\x5a\x1b\x82\x66\x1b\xd9\xf9\x28\x25\x34\x7f"
+  "\x45\x24\xea\x8a\xef\xc7\x9b\xe1\x5e\x3f\xf5\x07\xbb\xe5\x4b\x8b"
+  "\xcf\xff\x36\x32\xfe\xdc\x1e\xa2\xd9\x3f\xb7\x0e\x78\xab\x57\xde"
+  "\x8a\x70\xba\x0a\xf3\x3a\x98\x5f\x18\x2e\x58\x52\x65\x04\x6e\x15"
+  "\x06\xf3\xb7\x1e\x7d\x53\x91\x49\x99\x53\xbd\xf2\xa4\xfd\xc6\x4f"
+  "\xa1\xcc\xbc\x8d\xe7\x52\xe8\xfb\x64\x2d\x4a\x64\xfa\x0f\x73\xa6"
+  "\x77\x0c\xe6\x53\xf4\x45\xdc\xff\xaf\xe1\x5e\xe9\x27\x63\x60\x9c"
+  "\xfe\xbb\x12\xcf\x9f\xe3\xcb\x75\xa8\xb0\xce\x84\x76\x5e\x63\x6c"
+  "\xf4\x10\xd8\xc8\x0d\xbe\xcb\x07\x3b\x79\x08\xf9\x0d\xfb\xcc\x9c"
+  "\xfc\x49\x95\x59\x49\x7c\xc3\xf8\xa5\x86\xf8\x65\xdc\x22\x04\xf3"
+  "\x28\xf8\x66\x1b\xf1\x8d\xd9\x77\x76\x26\xf6\x8d\xb4\xfb\x28\xd3"
+  "\x8a\xcd\x2f\xf8\xb7\x69\xc0\x07\xc6\x85\x59\x3d\x3b\x13\xff\x36"
+  "\xee\x03\x7e\x7e\x86\x71\x30\x7e\xed\x45\xba\x38\xaa\x0a\x95\xc0"
+  "\xfd\xd0\x3e\xd6\x7d\x30\x4a\xed\xc3\x3e\xb1\x3e\x6c\x7a\x0e\x70"
+  "\xfb\x1c\xe0\xf6\x39\xc0\xad\x9e\xe0\xf6\x74\x39\xc1\xad\x09\xfa"
+  "\x55\x0f\xdc\x7d\xf9\x64\x44\xe1\x7e\xed\xfb\x19\xd7\xe8\x83\x7e"
+  "\x56\x71\xd8\x1d\x0b\xca\xba\x09\xbf\xca\x67\x3b\x63\xfb\x14\xd7"
+  "\x94\xa1\x15\x18\xbf\x0d\x42\xf8\xfd\x79\xcd\x78\x88\x1c\xc6\x37"
+  "\x01\xbf\xbf\x6a\x91\x67\x25\x72\x8b\x9f\x0c\xf8\xad\x12\xc2\xef"
+  "\xcf\x93\x8f\xc2\x6f\xda\xe1\x37\xdc\x1a\xbf\xe7\x6f\x4a\xc7\xef"
+  "\xf9\xa3\x4d\xf8\x9d\xc6\xe2\x37\xd2\x06\xbf\x95\x56\xf8\xc5\xf7"
+  "\x2d\x19\xbf\x3f\x6b\xa4\xe1\xf7\x7c\x56\x13\x7e\x41\x97\xec\x7c"
+  "\x83\xb1\xd1\x43\x60\x23\xc0\xef\xf9\x58\xb0\x93\x20\x7e\x5b\xdf"
+  "\x7f\xe5\x23\x9d\xf7\x5f\xb9\x6f\xf3\xfe\xfb\xe5\xa0\x74\xff\xfd"
+  "\x12\x77\xef\xfd\xf7\x8b\x5e\x9a\xff\x7e\x09\x13\xf7\xdf\x2f\x01"
+  "\x6d\xc7\x7f\xff\x71\x73\xde\x7f\x17\xce\x35\xef\xbf\x0b\x8b\xa4"
+  "\xfb\xef\xc2\x90\x7b\xef\xbf\x0b\x99\xd2\xfc\x77\xc1\x5f\xdc\x7f"
+  "\xe5\x75\x62\xfe\x7b\xb9\xab\x99\x36\xe3\x75\x73\x5d\x46\x23\xcc"
+  "\x81\x08\x5f\xfb\xcf\x19\xac\x19\xe1\x6f\x37\xcb\xdf\x0c\xa7\x02"
+  "\x5d\x6d\xf3\xb7\xa7\xcd\xdf\x2a\x9b\xbf\xd5\x36\x7f\xfb\xd9\xfc"
+  "\xdd\xdd\xf2\x37\xf8\xcb\xfd\x86\xe2\x3f\x23\x40\xb3\x01\xc7\xf9"
+  "\x4f\x39\xfb\xbd\xff\x6c\x93\x06\xeb\x3e\x7f\xa1\xbe\x6f\x5d\x45"
+  "\xd7\x79\x29\x10\xdd\x48\xd1\x28\x2a\x01\xfd\xee\x9a\xe2\xe2\x84"
+  "\x86\x55\x20\x09\x95\xdd\xb4\x74\x43\x22\x02\xbf\x54\x8e\x03\xb5"
+  "\x5e\x62\x00\x9d\xb8\xc2\xef\x21\x68\xfb\x31\xb0\x9b\xa1\x38\xca"
+  "\x00\xbc\xfc\x1b\xba\x42\x71\x71\x28\xbe\xcf\xe7\xa2\x74\xc8\xac"
+  "\x7c\x56\x4b\x33\xb5\x9b\xbd\x2a\x0d\xca\x67\xbb\x81\x2e\xcd\xdc"
+  "\xbc\xca\xec\x51\x52\x7d\x16\x6d\xa1\xcc\x9a\xb8\x38\xe0\xf5\xd5"
+  "\x87\xd0\xf2\x6a\xba\x2a\xce\x48\xd7\x95\xcc\xd0\xe1\xe7\xb6\x55"
+  "\x25\xb1\x05\xa8\xd8\x70\x16\xe1\x39\x0f\x63\xb5\xc4\x70\x88\x3c"
+  "\x27\xc6\xe7\xc0\xb1\x62\xc3\x3e\x54\x04\x7f\xeb\x16\x5c\x86\xfb"
+  "\xbc\x78\xbd\xa4\x7a\x1f\x32\xa5\x78\xe9\xcd\x6a\xaf\x13\xb4\xda"
+  "\xab\xa0\xa8\x1a\xfa\x96\xe2\x55\x88\xfb\x5a\x0c\xfd\x60\xf6\xe8"
+  "\x4c\xf5\x2a\x64\xda\xad\x29\x65\x72\x08\xa6\x54\x38\xdf\x17\xce"
+  "\xf7\xf5\x2a\xc0\xfd\xc3\x7d\x13\xd4\x7b\x29\xa3\x07\x40\xdf\x5f"
+  "\x9c\xac\x75\x43\xf4\x4a\x37\x3f\x69\x78\xd3\xab\x44\x75\x64\xca"
+  "\xe8\x43\xa4\x5d\x0f\x39\xed\x8a\xae\x7f\xa2\x53\x02\xd9\xfe\xaa"
+  "\xe4\xb4\xab\x73\xd0\x2e\xdb\x5f\x8d\x8c\x76\x2f\xf9\x89\xb7\x1b"
+  "\xc4\xf6\x77\xb8\x9c\x76\xa3\x1c\xb4\xcb\xf6\x37\x51\x4e\xbb\x05"
+  "\x0e\xfc\x36\x40\x1e\x16\x2a\xba\x3b\xc2\x82\x3c\x1c\x54\x38\xb8"
+  "\xff\xc0\x01\xf2\x30\x50\x21\x9a\xff\xc6\x18\x90\xe7\xff\xff\x3a"
+  "\xf4\xbf\x3c\xdf\xff\x57\x74\xff\x47\xec\x7b\x79\x7e\xff\xaf\x28"
+  "\xfe\xb1\x36\xa6\x53\x46\x95\xd2\x5d\x62\x90\x79\xbb\x6f\xa9\xb9"
+  "\xcb\xa8\x1f\x57\x9b\x87\xa3\x97\xe3\x61\xce\x4b\x43\x3e\x2f\xef"
+  "\xba\x48\x0f\x67\x72\x4e\x95\x21\xf1\xe9\x88\x4a\xa6\xcc\x54\xee"
+  "\xb2\x32\xaa\xc4\x18\x80\xe3\x96\x29\x6b\x49\x9d\xe2\xff\xe0\xf8"
+  "\x71\x18\xb9\x35\xef\x68\x11\x69\xcb\xb7\x74\x4b\xc2\x70\x34\xde"
+  "\x84\x70\x8e\xa3\x66\xdc\xa2\x8b\xf4\x3f\x81\xc5\x8c\xbf\x09\xf1"
+  "\x35\xad\x0e\xcf\xa5\x3e\x70\xad\x11\x70\x0c\xed\xd4\xa1\x03\x66"
+  "\x83\x62\x9c\x81\x39\xd7\x00\x7a\xd4\x40\x6f\x1f\xf5\x23\x9e\x93"
+  "\xe9\x15\x5a\xb4\x06\xfe\x86\xdf\x3e\xa5\x34\x20\x6a\x37\x68\xd5"
+  "\xda\x75\x95\x27\xf4\x8a\xcb\x99\x58\xbf\x82\x4e\xae\x5e\x71\x13"
+  "\xe7\xf3\x63\xd0\x7e\xb3\x81\x5a\x0d\xba\x19\x9f\xff\x5c\x14\xa2"
+  "\xfe\x69\xc0\xb9\x81\x4a\xc3\xf1\x18\x84\x1c\xe4\x73\xdc\xcc\xea"
+  "\x59\x6a\x7c\x3d\x6e\x07\xe7\x49\xb7\x9a\xc1\xce\xea\xd0\x7c\xdc"
+  "\x6f\x3a\x25\x38\x49\xb7\x0c\xcf\x39\x97\x63\x47\xf5\xa2\x6b\xf1"
+  "\x1c\x02\x73\x47\xb7\x6b\xf0\x37\x93\x0f\x58\x45\x97\xd2\x6a\xcf"
+  "\x7c\x7a\x8b\xd7\xf0\xe2\x9a\x5b\x48\xb7\xa4\x01\x55\x28\x2e\x2f"
+  "\xc5\xbf\x7d\x5b\x3d\x4b\x55\xa3\x9e\xe5\x57\xbb\xee\x72\x8c\xa5"
+  "\xbf\xf8\xb7\x2c\xc7\x71\xfe\x83\xf4\xf1\x72\xca\xf1\x38\xf1\x3e"
+  "\xd2\xab\xbb\x75\x1e\xef\x47\x1b\xb0\x2d\x75\x09\xb7\xa0\x2f\xbf"
+  "\x76\xc0\xf6\xa6\x53\x66\xea\x6b\x56\x68\x1f\x27\xf9\xc0\x2b\xfd"
+  "\x70\x5e\x09\xe6\x86\xb3\x24\xc7\xe3\x75\x96\x59\xc3\x03\xb1\x9f"
+  "\xce\x1a\x94\x86\xb9\xd0\x0d\xc5\x65\x26\x1f\x38\x59\x4b\x49\xd4"
+  "\x53\x97\x19\xfd\xab\x7b\x1c\xdb\xe1\xca\x4d\xf8\xbd\x3f\x56\x28"
+  "\xae\x4c\x22\x39\x0e\xaf\x2a\xfc\x7b\x70\x8e\x1e\x7e\xb3\x8a\x4e"
+  "\xf1\xcc\xc3\xe7\xc1\xf7\x31\xec\xf7\x06\xab\xef\x0d\x74\xca\x2c"
+  "\x2d\xfb\x7d\x0a\xfb\x7d\x8d\xd5\xf7\x35\x51\x8f\xe3\x9c\xdf\x95"
+  "\xa3\xf8\x9e\x60\xbe\x2b\x85\xef\x2b\xf1\xf3\x04\xe6\x9e\x7c\xbd"
+  "\x4a\xd9\xf3\x2a\xab\x15\x57\xce\xdd\x06\x7c\xc1\xf7\xd5\x56\xd7"
+  "\x57\xff\x33\xb6\x1f\x7a\x79\x17\xb6\xe9\x95\x2a\xbd\x9b\xfa\x28"
+  "\xc9\x13\x5d\xae\x64\x6c\x01\xf3\xa7\x75\x7b\x7a\xc5\x95\x43\x78"
+  "\x8e\xac\x01\x1e\x09\xe7\x14\xe2\xdf\xb4\xb6\x7f\x78\x74\xf4\xc2"
+  "\x68\x4d\xcf\x30\x4d\xd8\xfc\x39\x9a\xd7\x17\x2e\x5e\x10\x33\xb4"
+  "\x67\xd8\x23\x08\x59\x61\x47\x45\xaf\xf2\xa6\xcd\x29\x53\x43\x4a"
+  "\xd2\x80\xbf\x51\x2a\x98\xcb\x1b\x50\x0a\xf8\xd5\xb8\x3d\xb2\x9f"
+  "\xa9\x4b\x84\xce\xb4\xfd\x95\x7e\x2b\xee\x20\x2a\xc1\x8f\xbe\xa4"
+  "\x5b\xf6\x12\xf8\xe0\xd7\x95\x98\x43\x94\x80\x5a\xda\x04\x58\xd5"
+  "\x2d\xfb\x16\x1f\xdb\xc1\x3c\x6f\x08\x25\xc7\xfe\x9e\x50\x40\x7d"
+  "\x93\x50\x46\x15\x86\xde\x42\xff\xf4\x33\xa0\x13\x9a\x5b\x28\x1d"
+  "\x1f\x37\x97\x32\xcf\x7d\xe0\xfc\xab\xf8\xb7\x70\xee\x0c\xff\x9f"
+  "\xe4\x01\x7f\x9d\x8f\x7f\x47\xd3\x0d\x3f\x8f\xf8\x75\x11\xfe\x3d"
+  "\xbd\xe2\xd7\x28\x65\x3a\x52\xc0\x38\xf2\xbc\xa1\xa8\xea\x6b\x4e"
+  "\x9d\x1a\xc2\x8c\xf5\x75\xbf\x6a\x8c\x94\xcf\x1b\xbb\xdf\x47\x1e"
+  "\x19\xef\x23\x94\xde\x19\xb9\xd5\xae\xab\xf2\xd3\xbb\xf5\x8e\xc3"
+  "\xf6\x82\xa6\x3d\x6f\x53\x68\x18\x1c\xeb\xa3\x47\xdb\x18\x1b\xc2"
+  "\x98\xaa\x11\x8b\x1d\xf8\x39\x5c\x5d\xd6\x40\x9d\x59\x3d\x35\x88"
+  "\x06\x5b\xd4\xf9\x0f\x34\x78\x47\x01\x5e\x60\xdc\xd0\xbe\x53\x83"
+  "\xaa\x15\xd7\xb4\xdf\xe5\x23\x94\x80\xc7\x29\xd8\xe3\xf3\xbb\x75"
+  "\xf8\xf9\x5b\xbf\x7d\x77\x0d\xf0\x77\x84\x2e\x67\x49\x1d\x75\x7a"
+  "\x64\x3e\xd2\xfc\x19\x73\xac\xaa\x3d\xaf\x86\xd1\xc6\x67\x27\x00"
+  "\x2f\xad\xfc\x1b\xfa\xa1\xbc\x00\x79\xce\x40\xca\xa6\xda\xf0\x31"
+  "\x88\x1a\xaf\x87\xbf\x17\x23\xaa\xb8\xce\xc4\x3c\x07\x48\x18\x81"
+  "\xf3\xf9\x45\x08\xe7\xf8\x69\xea\x83\xb0\xdc\x5b\x75\x10\x9f\xaa"
+  "\xdc\xf1\xbb\xe4\x66\x55\x4e\x3e\xbe\x66\x76\x0d\xfb\x6c\xec\x36"
+  "\xfb\x6c\xec\x36\xf3\x6c\xac\x12\x3f\x17\xc3\xcf\xc3\xe2\x42\x69"
+  "\xb3\xe9\x1d\x6d\xe7\xf1\xa1\x4a\x1a\xb7\x89\x9f\x95\x79\x81\xa6"
+  "\xa0\xdf\xd1\x76\xda\x11\x8d\xd4\xc5\x86\x2a\x54\x52\x55\x80\x3e"
+  "\x5a\x82\xd4\xf4\xed\x88\x0e\x85\x27\x4e\x23\xfa\xfd\xbd\x79\x07"
+  "\x12\x74\xee\x26\x9c\x4f\xb9\xed\xf7\x88\xf7\x4a\x05\x7e\x2e\xd0"
+  "\x69\x53\x34\xea\x93\x71\x0b\xf5\x9b\x7d\x39\x91\xa9\x13\x85\xf7"
+  "\xf4\x33\xde\xd6\x6a\x1a\x6f\x6b\x9f\x6a\x78\x47\xfb\xb8\xb7\x81"
+  "\x3c\x4b\x9b\x19\xa9\x42\xf8\x79\x19\xbd\xae\x2c\x2a\x03\xe7\xb4"
+  "\x6b\x0c\xc8\xe8\x93\x93\x8f\xf1\x09\xbf\xdb\x1d\x3f\x7f\x59\xb1"
+  "\x14\xa9\xcc\xff\xd5\xa2\xa2\xea\x5b\xe8\x79\xc0\x0d\x7e\xd6\xb0"
+  "\xbb\x82\x3c\x6b\x30\x6d\xfb\xa4\x0a\x3f\x6f\xa8\x7d\x47\x4b\x8d"
+  "\xbd\x0e\x73\xd7\xba\xaa\x91\x0d\x3d\x07\xea\x4e\x6a\x2f\xe0\xf9"
+  "\x61\x00\x37\xee\xaf\xde\x91\x37\xee\xaf\xd6\xe0\xeb\xf0\xf3\x37"
+  "\x1a\xf0\xbc\xef\x16\xf6\x1b\xf8\xef\x96\x81\x7a\xa5\x92\x36\x16"
+  "\x55\x7e\x06\xfe\x29\xe3\xf9\x87\xf1\x67\x74\x1d\x75\x25\x0c\xfc"
+  "\x72\x99\xf8\xaa\xb0\x06\xfc\x74\x1c\xb7\x31\x6b\x42\x2e\xf8\x1a"
+  "\xf4\x14\x55\x58\x77\x81\xa9\x73\x81\xfd\xb5\xaf\xa1\xc0\xbd\x41"
+  "\x3d\xaa\x14\x3f\xc7\xac\xf5\x1f\xa8\xaf\x4f\x99\xaa\x6d\x54\x4f"
+  "\x0d\x70\xf0\x4c\xb3\x12\xfb\x2b\x3e\x12\x79\x14\x56\x9e\x43\x8c"
+  "\xcf\x16\xb1\x3e\xc3\x6b\xdf\xde\xd5\x76\x32\xd6\x6a\x3b\xef\x00"
+  "\x5f\x15\xc7\xe8\xd1\xce\x5b\x48\x5d\x52\x55\x86\x9f\xf7\x74\x78"
+  "\x65\x22\x42\xaf\xe4\xd0\xe6\xa2\x13\x3f\x33\xfe\xdb\x0f\xfe\x33"
+  "\x82\xff\xf0\x73\xce\x26\xff\x2d\x01\xff\xdd\x05\xff\x5d\xe7\xfc"
+  "\x67\xaa\x05\xff\xd5\x82\xff\xde\x05\xff\xd5\xd8\xf9\xaf\x06\x3f"
+  "\x0b\xc5\xcf\x9c\xb0\xff\xf0\x7a\x6b\xf3\xbb\xda\xee\xcc\x33\xd0"
+  "\xd7\xb5\x28\x63\x2e\xf2\xe8\x5b\x87\x14\x2b\x8e\x23\x15\xf4\x53"
+  "\xf5\x0c\xd8\x17\xda\x03\x7c\x57\xa0\x92\x7c\x13\x5a\x3e\x15\x3d"
+  "\x8e\xfd\x69\x64\xfd\x59\x62\x3c\x8c\xee\xd6\x6a\x29\x68\x33\x60"
+  "\xc7\x5d\x34\x64\xcc\x65\x0d\x3a\x39\xa9\x08\x81\x3f\xf4\xe6\xd4"
+  "\x99\x7a\xf9\xe3\xf0\x7a\x9e\xf3\xe3\xb0\xba\xd7\x83\x71\x28\x77"
+  "\x1c\xfe\xaf\x50\x78\x1c\x5e\x8f\x97\x37\x0e\xaf\xc7\x3d\x18\x87"
+  "\x6d\x69\x1c\x5e\x8f\xb0\x1d\x87\x4d\x5c\x21\x3a\x7c\xfe\x9c\xc8"
+  "\x05\x91\x0b\xde\xd4\xcc\x5d\x1a\x13\xfe\x0e\x61\x0c\x3c\xce\xa0"
+  "\x35\x99\x87\x53\x1f\xc0\x7c\xfa\x83\x5f\x19\x3a\xd0\xad\x8c\x32"
+  "\x4f\xf7\x73\xa3\x93\x8f\x22\x73\xf2\xd1\xc4\x0f\x80\xff\xe2\xf1"
+  "\x9a\x02\xbc\xf6\x8a\xa2\x3e\xfd\x7b\x50\x56\xba\xe8\x6b\x08\xff"
+  "\x9f\x3c\x93\x8d\x8f\xc2\xef\x2d\xa6\x6d\xa7\xab\xf0\x7b\x8b\xa7"
+  "\x47\xe2\xb9\xdf\xe0\xd5\x31\x04\xe6\xf5\xe9\x7e\xa8\x7e\x7a\x08"
+  "\xb5\xe1\x67\xe4\xe1\x5d\x86\xc6\x98\xcd\x34\xad\x4b\xb8\x06\x5c"
+  "\xeb\x6e\xa5\x6e\xda\x35\xa4\x59\xe6\x01\xe7\xde\x19\xa5\x59\xb6"
+  "\x12\xff\xdb\x4b\xb3\x6c\xdd\xc5\x2b\x8a\x9a\xab\x4c\xee\xa4\x0b"
+  "\x5d\x45\x6f\x0f\xc9\x34\x7d\x1a\xa0\xc2\xcf\x2b\x33\xba\xd0\x95"
+  "\xfb\x81\xe3\xef\x6f\xa8\xa3\x56\xdf\x02\x7c\xac\x7a\x82\xc6\xcf"
+  "\x1d\xf1\x73\xcd\xd5\xd1\x60\x63\xe0\x9a\x84\x0f\xd6\x04\xe3\xf1"
+  "\xb2\x69\x3b\x5d\xf9\xf5\x95\x32\x0a\x3f\x77\xc5\x63\xa8\x46\xed"
+  "\x99\xb7\x06\xee\x05\xfa\xa9\xdf\xd9\x85\x2e\x37\xf8\x4e\x0d\x71"
+  "\xd3\x20\xaa\x76\x9d\x21\x11\x78\x49\x00\xe6\x14\x49\xf0\xdd\x06"
+  "\xf8\x8e\x3c\x03\xac\x71\xa3\x1f\xfa\x6d\x0c\x8e\x5b\x80\x5f\xc5"
+  "\x0d\x85\xa1\xa8\x1e\xee\x73\x13\xd1\x03\x55\x75\xa9\x53\x03\x8c"
+  "\x7b\x07\xea\x8d\x98\xc7\xf5\x1c\x68\x68\xf0\x9d\xaa\x35\xa6\x4e"
+  "\x0d\x9a\xdc\x8b\x79\xd6\x0d\xe7\xdf\x5a\x8f\xef\xa3\x51\xfd\x4a"
+  "\x3f\x38\xbf\xe6\xb6\x3a\xb2\xdf\xed\x94\x08\xdd\xe9\xd8\x3c\x36"
+  "\x9e\x19\xea\x5f\x49\x63\xe3\x59\x1a\x8c\x97\x10\x88\x67\x21\xf6"
+  "\xf1\x8c\xac\x0d\x30\x21\x12\xd7\x8a\x10\xb4\x55\x89\xc7\x0b\xe6"
+  "\x86\xb9\x60\x0b\x3c\x16\x30\xe6\x99\xf8\x06\xb1\xcd\x32\x2e\xf0"
+  "\x98\xc1\x31\x8c\x19\xa3\x36\x63\x04\x8f\x8b\x8e\x06\xa4\xc2\xe3"
+  "\x02\xc7\x38\x3c\x2e\xf0\x9a\x9b\x0f\xee\x92\x71\xe1\x5d\x8e\x54"
+  "\xcc\xd8\x30\x16\x30\x63\x03\xeb\x82\x42\xa3\x4d\x5c\xb3\x1a\x17"
+  "\x9b\x2d\xe3\xc2\x12\xd7\x00\xfb\x46\x3c\x2e\xde\xe5\x8f\x8b\xe9"
+  "\x17\x54\x88\x89\x79\xeb\x7e\xaa\x49\x87\x71\x81\xf3\x58\x26\x4b"
+  "\x5c\x83\x71\x81\xdf\x09\x62\xe2\xda\xdb\x6c\x5c\x33\xc0\x71\x18"
+  "\x0f\xbb\xdf\xe2\xc7\xb5\xfa\xda\xe6\xf8\xc5\xad\xc9\xf2\xe2\xda"
+  "\x2d\x46\x43\x60\x5f\x61\xbf\x61\x7f\x61\x1f\xb5\x27\xff\xe0\xb8"
+  "\x65\x52\x89\xc4\x2d\x01\xff\x00\x9e\xab\xe1\xff\x76\x3e\xa2\xd7"
+  "\xfd\x7b\x88\x75\xec\xc2\x31\x0b\xc7\x2f\x1c\xb7\x70\x0c\xc3\xe3"
+  "\x00\xc7\x2e\x26\x6e\x41\x4c\x87\xbf\xab\x8a\x22\x2a\x98\x98\xb6"
+  "\xe2\x32\x52\xad\x18\x85\x1e\xc7\x31\xac\xc4\x78\x07\xe1\x98\xc6"
+  "\xf8\xcf\x87\xf3\x1f\x8e\x61\x3b\x97\xa0\x21\x63\x23\x35\x08\xc7"
+  "\x2e\xb0\xfd\xf0\x93\xda\x73\x88\xd1\x03\xab\x1e\x1d\x96\xd1\x19"
+  "\xc6\xed\xfb\xc8\x2d\xa5\x33\xf2\xa8\x5d\x57\xe3\x6f\xaf\x05\x6a"
+  "\x02\x2c\x5a\x00\x8f\x59\x3c\x76\xf5\x0a\x03\xa3\xe1\x74\xdd\x5e"
+  "\xc4\x31\x68\x0c\xd1\x73\x53\x12\x49\xde\xbd\x61\x2c\xf3\x37\xe8"
+  "\x68\x4e\x43\xd7\xac\x25\xcf\xda\x41\x33\xfb\x06\x27\xd1\xa9\x9e"
+  "\xf9\xd8\x96\xf8\xde\x66\xf7\x02\xcc\xa5\xce\x52\x6d\xc5\xf6\x49"
+  "\x05\x3d\x9e\x3a\xcb\x8f\xc3\x57\xcd\xe1\x93\xa0\xb6\x27\xc7\x4a"
+  "\xc5\x57\x0d\xb3\xfe\x9f\xfe\x25\xe4\x51\x7a\x7a\x88\x9b\xf9\x97"
+  "\x10\x77\xc0\x82\xdf\x42\x53\x22\xba\x9b\x1c\x1f\xb1\xc2\x48\x57"
+  "\x69\x96\xa1\x67\x21\x16\xfa\x9e\x86\x19\xf6\x34\x28\xd6\x92\x09"
+  "\xf3\xc0\xaf\x71\x55\x07\xcc\x06\x37\xb8\x3f\xcf\x0c\xb0\x33\xc4"
+  "\x56\x37\xeb\xd8\x4a\xe2\xa8\xc1\x93\x59\xe7\x9d\x1c\x1f\x8b\xdb"
+  "\x1a\x5f\x80\xbc\x35\xa3\xf1\x5a\xbe\xbb\x87\x97\xc6\x23\xfc\x7e"
+  "\xaa\x3b\xfc\x7f\x65\xfd\xfb\x63\xf0\xf5\x9d\xe8\x5f\x26\x29\xa2"
+  "\x46\xc3\xfc\x32\x7d\x92\x02\xaf\x2d\xf8\x2c\x21\x8d\x32\xc3\x31"
+  "\xb2\x56\x29\x0d\xe1\xef\x37\x35\xb8\x31\x3c\xca\x0c\xe7\x14\xd7"
+  "\xa4\xa1\x4d\x4b\x3c\x10\x3e\x9f\xac\x7f\x4b\x43\xf8\xfc\xcd\xd1"
+  "\x2a\x66\x6d\x02\x73\x9d\x31\x0d\xe1\x6b\x4d\x70\x7c\xa3\xd9\x13"
+  "\x6d\x59\xa6\x46\xa7\x27\x14\x33\x6d\x9c\x9e\xf0\x1d\xc2\x6d\x00"
+  "\xe6\xe1\xff\x5f\xa3\xad\x4b\xfc\x60\x8c\xa7\xc1\xf7\xff\x46\x5b"
+  "\x6f\x74\x87\x7f\xaf\xc0\xe7\x2e\xba\xa6\xb8\xeb\x7f\x7a\x82\x19"
+  "\x79\xaf\x1c\x46\x03\x76\xe9\x12\xfc\xce\x63\x02\x7a\x08\xfa\xde"
+  "\xb7\xa4\x2c\x19\xe6\xba\x3b\x6a\xfc\x4e\x3c\xbd\x62\x7a\xb5\x99"
+  "\x9e\x7e\xdd\xbc\x62\xfa\x0d\xfc\xdb\x26\x7a\xfa\x6f\xf8\xb7\x37"
+  "\x2f\xd3\xb0\xeb\x5f\xd3\x98\xb5\x7b\x9b\xee\xfa\x23\xdc\x57\xfc"
+  "\xbb\xf8\xf7\xb6\x46\x6b\xd9\xdf\xec\xc3\xf4\x0d\xff\x26\x6e\xd3"
+  "\xfa\x37\xf1\x7e\xf3\x9a\x29\xcc\x6f\xee\x81\x7f\x7d\xc0\x1f\x7e"
+  "\xd8\x0f\xf8\xf7\xcd\x74\x88\x3b\xbd\x22\x44\xc9\x5c\x13\x5b\x25"
+  "\x74\xcd\x39\xf6\x1a\xa6\x16\x01\xbe\xa6\x81\x9c\xcf\xb4\x01\x73"
+  "\x1f\xb3\x7f\x48\xef\x10\x1d\xb2\xf7\x61\xed\x66\x32\x17\xd6\xce"
+  "\x24\x73\x21\xf1\x29\x83\x95\xe9\x21\xee\xe0\x37\x15\x9e\x37\x2b"
+  "\x14\xb5\x03\x9b\xda\xf8\x25\x44\x89\xfd\x8d\x71\x63\xc1\x12\xc6"
+  "\x91\x05\x43\x4c\x3f\xa3\x10\xb2\xc6\x0c\xfc\xdf\x83\x6d\x27\xde"
+  "\xd2\x0e\xf4\x01\x59\x70\xd4\x1b\xbe\xb7\xc7\x51\xfd\x64\x0e\x47"
+  "\x75\x77\xea\x12\x68\x1a\xe3\x48\x37\x6d\x15\x6e\xe7\x24\xd7\x9f"
+  "\x49\x0a\x8c\xb1\x76\x86\x2d\x7f\xec\xa7\xde\x71\x48\x4d\xee\xa7"
+  "\x2e\x95\xb9\x9f\x38\x9d\x1a\xf7\xd5\x72\x1f\xb8\x0f\x5b\xcc\x1a"
+  "\x64\xb9\x8f\xad\x0d\xfe\xd0\xee\x0d\xc4\x5e\x73\x0a\xb7\x6d\xb1"
+  "\x01\xf8\x0c\x59\xae\xb1\x9c\xbf\xc5\xac\x85\x7e\xf7\x61\xae\x21"
+  "\x98\xbb\x22\x80\x9f\x7a\x5f\x5b\xcc\x75\x8c\x43\x40\x64\x81\x3b"
+  "\x4d\xbb\x05\xbf\x53\xdf\x9f\xf4\xed\x1b\x53\x03\xfc\x06\xf8\x80"
+  "\x62\x8f\x07\x5b\x61\x82\x6d\xbf\x4e\xa8\xfd\xc5\xbc\xf6\x43\xa0"
+  "\xfd\x58\x68\x1f\x73\xb3\x69\x38\x0f\x56\xcf\xd4\x01\xe8\x1d\x4b"
+  "\xda\xb7\xe0\x96\x4e\x0e\x1e\x19\xb5\x0c\xaf\x1f\x6d\x08\x20\xf1"
+  "\xf4\x37\x66\x0f\x10\x66\xdd\x12\x65\xce\x34\xdb\xac\x5b\xb2\x5e"
+  "\xd7\x76\x20\xc1\xc0\xae\x59\x6a\x60\x6a\x5a\x40\x7c\xad\xc1\x1c"
+  "\x33\x17\xf8\x19\xb7\x6e\xe9\x67\xfc\xfd\x93\xba\x25\x15\x56\xeb"
+  "\x96\xea\x19\xbd\xaf\x57\x34\x8c\x01\x2d\x49\xc1\xf7\xec\xf1\xdf"
+  "\x0e\x59\x1f\xe7\xd6\x05\x92\xe3\x78\xcd\x35\x9b\x77\xad\xfe\x67"
+  "\x3e\xce\xbd\x35\x84\x59\xf2\x9d\x22\x5a\xd5\x79\x0e\x4c\xb9\xe5"
+  "\x37\x71\x60\xf8\xbf\x38\x07\x6e\xf4\x71\xc8\x81\x29\x0a\x35\x71"
+  "\x60\x0a\xcd\x61\xc6\x3d\x85\x46\x31\xe3\x9e\x42\xcc\x3e\xb8\x5b"
+  "\xa0\x3d\xe3\xc7\x31\x78\x0d\x76\x1e\xc6\xf9\x6e\xe0\xb4\x07\x96"
+  "\x14\x50\xb9\xa0\x93\x4d\xd4\x13\xf4\x6a\xb0\x1d\xae\xd7\xb6\x7a"
+  "\x19\xcc\xd3\xc6\xb3\xa8\xd8\x0d\x73\x60\xbc\xfe\x8b\x0e\x2f\x66"
+  "\x9e\xcb\x05\x27\x13\xbb\x34\xce\x07\x5f\x28\x4b\xea\xea\x10\x73"
+  "\x1e\x7c\x07\xf3\x5a\x25\xe6\xc0\x5f\x9b\x0b\xa8\xdd\x60\x53\xf8"
+  "\x00\x47\x7e\xc7\x60\xcd\x91\x6b\xd7\x35\xa6\x0b\x73\x63\x5a\x63"
+  "\x5c\x67\xcd\x8d\x1b\xaf\x62\x6e\x8c\xf3\xe4\x98\x07\x98\x09\x27"
+  "\xd6\x03\x3f\x36\x60\x9e\x8c\xb9\xb1\x99\xc7\x8d\x4d\x7b\x1d\x73"
+  "\x63\xa3\xef\x03\x6e\xec\x2a\x37\x16\xd3\xfc\xa6\x45\xf2\xb8\xb1"
+  "\x29\xea\x01\x37\xbe\x5f\xdc\xd8\x34\xc3\xc2\x8d\xcd\xab\x1e\x7d"
+  "\x36\xfd\x7d\x18\xaf\x4d\xdc\x98\x1e\x6e\xcf\x8d\xe9\x49\xf6\xdc"
+  "\xb8\x31\x8f\xe3\xc6\x8d\x13\x78\xdc\x98\x72\x8f\xb4\xe7\xc6\xf4"
+  "\x1e\x31\x6e\x0c\x71\xa9\x1a\x73\x63\x8c\x29\xcc\x93\x31\x3f\x36"
+  "\x03\x3f\x26\xf8\xa2\xcf\xc8\xe3\xc6\x74\xa9\x53\xdc\x98\x42\xfd"
+  "\x85\xb9\x71\xa3\x4a\x9c\x1b\x37\xaa\x04\xb9\x31\xa5\x38\xd3\xc4"
+  "\x69\x28\xc5\xae\x36\xcf\x8d\x29\xc5\x70\x41\xfe\x42\x29\x82\x19"
+  "\x6e\x4c\xa1\x7e\x2d\xce\x8d\xa1\x4d\x41\x6e\x4c\x29\x8e\x31\x3c"
+  "\x82\x42\x03\xec\xb8\x31\xbe\x46\x88\x1b\x53\x8a\x9b\xec\x35\xfd"
+  "\x78\xdc\x98\x6d\x03\xe6\x44\x2f\x51\x6e\x4c\x51\x39\x64\x8e\xa4"
+  "\x96\x12\x6e\x4c\x7c\x6a\xc7\x8d\x29\x6a\x62\xb3\xdc\x98\xc5\x10"
+  "\xd3\x4f\x31\x6e\x4c\x51\x3b\xec\xb9\x71\xa3\x4a\x90\x1b\x53\x6e"
+  "\x8b\x38\x1c\xb9\xf9\xf0\xb8\x31\x45\x5d\x6a\x17\xdc\x58\x1c\x5b"
+  "\xc3\x79\xdc\x98\x52\x1e\x94\xcc\x8d\x29\xe5\x65\x49\xdc\x98\xc1"
+  "\x9c\x00\x37\xa6\xdc\xfa\xdb\x62\x8e\xc7\x8d\x29\xb7\xb1\x82\xdc"
+  "\x98\x72\x0b\xe7\x71\x63\xa6\x7d\x01\x6e\x4c\xb9\x6d\xe3\xb5\x6f"
+  "\xcb\x8d\x29\xb7\x5c\x1e\x37\x66\xcf\x6b\xe2\xc6\x94\xfb\x24\x36"
+  "\xd7\x70\x44\x32\x37\xa6\xdc\x07\x3a\xe4\xc6\x94\xfb\x50\x1e\x37"
+  "\xa6\xdc\x19\xfc\xeb\x29\xf7\x08\x86\x1b\x53\xee\xfe\x2c\xc7\xce"
+  "\xb7\x3e\xce\x71\x63\x72\xdc\x8e\x1b\x6f\x70\x4f\x6c\x86\x1b\x0f"
+  "\x77\x9e\x1b\xab\x92\x0b\x9a\xb8\xb1\x2a\xd9\xc2\x8d\xf1\xfe\x41"
+  "\xe9\xc0\x37\xd3\x19\x7e\x7c\x1a\x9d\x0e\xc3\xfd\x7f\xa8\xbf\x63"
+  "\x7e\xec\xa5\xe3\xf8\xb1\xa7\x0f\x19\xfb\x1d\xef\x10\x7e\xdc\xf1"
+  "\x70\x53\x8e\x18\xb8\x31\xe6\xc8\x6c\x8e\xf8\xec\x26\xf8\x1c\x58"
+  "\x56\xc0\xf0\x63\xbc\x36\x1e\x73\x64\xcc\x8f\x31\x4f\xc6\xdc\xb7"
+  "\x68\x0d\x42\xc5\x86\x3a\xbc\xae\xa3\x54\xf7\x38\xb6\x6b\xc7\x3d"
+  "\xc0\xab\xf5\x30\xb7\x95\xc2\xb5\xfa\x03\xb7\xea\xf0\x7b\x16\xe5"
+  "\x5b\x2a\xe0\x1a\x3d\xb9\x06\xbe\x2f\xc3\xd7\xc0\x39\xe5\xc4\x17"
+  "\x8f\x98\xc8\xfc\xc9\xf2\x6b\xea\xa1\x22\x1e\xbf\x26\xe7\x9e\xb5"
+  "\xf0\xeb\x5d\xd0\x07\xf8\xb8\x61\x6e\x8d\x39\x36\x70\xeb\xc2\x5d"
+  "\xdb\xe9\x82\xdd\x5d\xe8\x13\xb5\x1b\x1e\x46\x16\x8e\xbd\x19\x8e"
+  "\x6d\x81\x63\xd0\x8f\xd2\x13\x99\x08\x1d\xbb\xa5\xc3\xdc\x41\xbf"
+  "\xeb\x0a\x72\x03\x9f\x95\xad\x86\xdf\xc7\xd7\xc3\x35\x03\x2c\xd7"
+  "\xc0\xfc\x5e\xc8\x70\x72\xea\x91\xa3\x66\xeb\x7c\x35\xf5\xf0\xca"
+  "\x26\x4e\x0e\x76\xc2\xf9\x70\xbc\x2f\x17\xc3\xcb\x7b\x0e\x34\x18"
+  "\x2d\xbc\xdc\xd7\x8a\x97\x53\x1d\x86\x5a\x78\x39\x7e\xbf\xa9\x89"
+  "\x97\xc7\xb0\xbc\x9c\x7a\x38\x57\x26\x2f\x3f\xdb\x56\x78\xb9\xa7"
+  "\x42\xe1\xe6\x19\x4a\x78\x79\xfa\x92\x96\xe1\xe5\x98\x93\x63\x1e"
+  "\x8e\x39\x39\xe6\xe8\x98\x97\x63\x8e\x6e\x66\x79\xf9\x6e\x2b\x5e"
+  "\x6e\xb6\xe2\xe5\x66\x6b\x5e\x4e\x75\xe8\x20\x8b\x97\x53\x1d\x3c"
+  "\x5a\x80\x97\xdf\x57\xff\xdc\x0f\x5e\xae\xb5\xe1\xe5\x98\x87\xc3"
+  "\xd8\xab\xc4\xfc\xbc\x44\x07\xb6\x59\x04\x1c\x1d\xf8\x79\xb3\xdc"
+  "\x9c\xf2\xa8\xb1\xe6\xe6\xbb\x3b\x5b\x71\xf3\x0d\x8f\x94\xdb\x71"
+  "\xf3\x0d\x8f\x18\xac\xb8\x79\xa1\x9e\x7a\x78\x24\x13\xf7\x61\x7c"
+  "\xeb\xe6\x36\xe0\x58\x92\xc7\xe7\xe6\x3e\x23\xec\xb8\x39\xd5\x71"
+  "\xa8\x20\x37\x27\xfa\x9b\xcf\xcd\x7d\x67\xa9\x8d\x16\x6e\x4e\x75"
+  "\x9c\x2f\x8b\x9b\x53\x1d\xe7\x35\x69\x07\xea\xa1\x38\x32\xbf\x74"
+  "\xf4\x14\xe3\xeb\xb5\x2a\x6b\xbe\xde\xf1\x12\xc7\xd7\x63\x38\xbe"
+  "\x4e\x3d\xd4\x4f\x94\xaf\xc3\x77\xcc\xda\x71\x55\x7c\x2c\x6e\x0b"
+  "\xf3\x2c\x88\x95\x95\x9a\x68\xcc\xb5\xbc\xb6\x61\xae\x05\xf1\xa9"
+  "\x12\xaf\xb9\x86\xbf\x67\x5a\x78\x3b\xa3\x2f\x31\x77\x5f\xd6\x16"
+  "\xf9\x95\xa7\x51\x98\x5f\x79\x75\xc0\x3c\x86\x79\x9f\x95\xea\xa8"
+  "\x07\x9b\x54\xb6\x2c\x7f\xef\xa8\x17\xe6\xef\x5e\xf1\x84\xeb\x74"
+  "\xac\xc4\x7e\xe1\xf3\x77\xb8\x46\x90\xbf\x7b\x1d\x64\xaf\xd1\xf3"
+  "\xf9\x3b\x69\x03\xe6\xec\x22\x71\xfe\xde\x29\x92\xcc\xe1\x9d\x06"
+  "\x93\x39\x9c\xf8\xd8\x9e\xbf\x77\xf2\xb1\xe6\xef\xd8\xff\xf6\xfc"
+  "\x9d\x60\x8a\xe9\xa7\x28\x7f\xef\x34\xd5\x8e\xbf\xc3\x6f\x62\xfe"
+  "\x6e\xb4\xc2\x55\x3a\xc6\xd5\x5c\x8c\x2b\x55\x30\xc6\x15\x9e\x27"
+  "\x35\x6f\x60\x5c\x79\x5f\xad\x33\x5b\x78\xfc\x06\xdc\x5e\x8e\x2d"
+  "\x8f\xc7\xf1\xc2\x11\xce\xa2\xa2\xd1\xe3\x18\x6b\x18\x67\x16\xbf"
+  "\xe1\xf3\x31\xde\xee\x2d\xd6\xbc\x23\x84\xb1\xe6\xbd\x98\xf1\x33"
+  "\x8b\x35\x9c\x4f\x24\xbc\x1e\xdf\x9f\xf7\x7a\x69\xbc\x9e\xb9\xe6"
+  "\x98\x34\x5e\x8f\xb1\x28\xc4\xeb\x55\x1d\x6c\xb1\xc8\xe7\xf5\xaa"
+  "\x9e\xc2\xbc\x5e\x35\x94\xcf\xeb\x71\xfb\x42\xbc\x5e\x15\xc9\x6b"
+  "\xdf\x8e\xd7\xab\xd6\xf2\x79\x3d\x39\x8f\xe3\xf5\x3e\x7d\xd8\x3c"
+  "\xc9\x39\xe9\xbc\xde\xc7\x8b\x8d\xef\x84\xd7\x57\xd8\xf2\x7a\x1f"
+  "\x5f\x3e\xaf\x57\x55\x91\xf8\xea\x33\xbc\x8e\xe1\xf5\x2a\x23\xcb"
+  "\xf7\xcf\x5a\x1f\x6f\xe2\xf5\xec\xf1\x3a\x6b\x5e\xaf\xc3\xbc\xde"
+  "\x27\xa4\x19\x5e\x3f\xc1\x79\x5e\xdf\xbd\x8c\xe3\xf5\xdd\xcb\x1c"
+  "\xf3\xfa\xce\x1d\x1c\xf3\xfa\x6e\x6a\x8e\xd7\xfb\x85\x93\x98\xe0"
+  "\x17\x4c\x62\x82\x1f\xc3\x81\x60\x5c\x71\x79\xef\x45\xcc\x1a\xeb"
+  "\x82\xfd\xb7\x0a\xa8\x03\xd1\x6c\xde\xfb\x2e\x70\xfa\x25\xc0\xcf"
+  "\x6b\x08\x3f\x87\x98\x79\x02\xf3\x7a\xcc\xbf\x09\xa7\x7f\xec\x0e"
+  "\x1c\xd3\x83\xcd\x4f\x40\x5b\xfa\x7d\xcb\x74\x14\x5e\x5b\x85\xcf"
+  "\x85\xf1\x5e\xb6\x09\xe6\x11\x38\x5e\x06\xe7\xe8\xf0\x35\x70\xec"
+  "\xac\x2e\x9a\xb9\xee\x12\xe6\xfe\x70\x9d\x0e\xbe\x2f\xb7\xb9\xae"
+  "\x14\x5f\x57\x1c\xcb\x70\xfb\x52\xe2\xbb\xc7\x46\xc0\xf1\x42\x4e"
+  "\x07\x74\x3e\xc7\xe8\x80\x1a\x56\x07\xc0\xb9\xd0\x56\x01\xa3\x03"
+  "\xe6\x82\x0e\x80\x7e\xc3\xc7\x5a\x07\x1c\x05\x1d\x90\x0f\xba\xe5"
+  "\x50\xed\x86\x47\x3d\xac\x74\x40\x3e\xe6\xfd\x58\x03\x60\xee\x0f"
+  "\xf3\xda\x21\xac\x0b\x8e\x35\xe8\xf1\x7a\xf2\xb3\xa0\x03\xca\xf0"
+  "\xf5\x56\xd7\x8e\xb4\xbe\x16\x9f\x0f\x7d\xd4\x31\x1a\x02\xf8\x1c"
+  "\xf4\xa1\x7c\x57\x05\xa3\x21\x0a\xe1\xda\x52\xa2\x21\x1e\x8d\xb5"
+  "\xd2\x10\x47\x89\x86\x78\x0c\xf1\xf2\xfa\xd4\xa3\x27\xa5\x6b\x08"
+  "\xdf\x95\x0e\x73\xfb\xd4\xa3\x37\xa5\x68\x08\xb8\xef\x02\x0b\x4f"
+  "\xb5\x5b\xc7\x87\xd7\x99\x03\x57\xc5\xbc\xd4\xe1\x7a\x30\x96\xb3"
+  "\x62\x8e\x8a\xf9\x29\xe6\xa9\x4e\x71\x54\xe8\x7f\x61\x5d\x0b\xe6"
+  "\xf6\x1f\x02\x0d\xb1\x44\x5c\x43\x58\xf4\x03\x93\xd3\x67\x35\x04"
+  "\x8c\x31\x46\x43\xa4\xaf\xb2\xd2\x10\x0f\x59\x69\x08\x85\xb5\x86"
+  "\xf0\x1d\x2b\x4f\x43\xf8\x8e\x69\x01\x0d\x51\xf0\x40\x43\xc8\xd5"
+  "\x10\xbe\x01\x4d\x1a\x82\x62\xf3\xfb\x9d\x2d\x1a\xe2\x31\x8d\xbd"
+  "\x86\x78\x6c\x80\x95\x86\x38\xaa\xa7\x1e\x4d\x62\xf8\x39\xa3\x1f"
+  "\x3a\xe7\xf3\xf5\x43\x8f\xf5\xf6\xfa\xe1\xb1\x78\x79\xfa\xe1\xb1"
+  "\x5c\x79\xfa\xe1\xb1\x7d\xa4\x7f\x15\xb8\x7f\x49\x64\x1e\x7b\x6c"
+  "\x0c\xa7\x29\x3a\x4f\xb0\x3e\xd6\xbc\xa6\xf0\x1b\x28\xac\x29\x3a"
+  "\x7b\x88\x6b\x8a\xce\x1e\xe2\x9a\xa2\xeb\x65\xcc\xfd\xb0\x7e\x80"
+  "\xf6\x81\xfb\x75\x3d\x68\xfd\x2c\x60\x53\x33\x3c\xcf\x56\x4f\x44"
+  "\xcd\x25\xfa\xe3\xde\xf3\xbc\xae\x13\x84\x79\x5e\xd7\x99\x98\x43"
+  "\x19\x19\x9e\xe7\x37\x20\xbd\xc5\x35\x85\xdf\x00\x61\x4d\xd1\xf5"
+  "\x0c\xe1\x59\x7e\x01\xf6\x9a\x02\xae\x11\xd4\x14\xdd\xdc\xd9\x6b"
+  "\x06\xf0\x35\x05\x69\x03\xf8\xc2\x93\xe2\x9a\xa2\xdb\x31\xc2\x1f"
+  "\xba\x6d\x26\xfc\x81\xf8\xd8\x5e\x53\x74\xb3\xce\xff\x8a\x68\x0a"
+  "\x82\x29\xa6\x9f\xa2\x9a\xa2\x5b\xae\xbd\xa6\xe8\xec\x81\x35\x85"
+  "\x30\xae\xba\x6f\xe3\xe3\xaa\x7b\x7f\xbe\xa6\xe8\x66\xb2\xd5\x14"
+  "\xed\x10\x6b\x13\xb8\xe7\x03\xf8\x9e\x7e\x77\x46\xba\x8e\xe8\xee"
+  "\x2e\x4d\x47\x60\xfc\x09\xe9\x88\xee\x13\x6d\xf1\xc7\xd7\x11\xdd"
+  "\xe7\x0b\xeb\x88\xee\x6b\xf9\x3a\x02\xb7\x2f\xa4\x23\xba\x1f\xe4"
+  "\xb5\x6f\xa7\x23\xba\x17\xf1\x75\x04\x39\x8f\xd3\x11\x3d\x62\xd8"
+  "\x9c\x4e\xae\x74\x1d\xd1\x63\xb2\x63\x1d\xd1\x63\x26\x5f\x47\xf4"
+  "\xe8\x47\x62\x6a\x8f\x24\xa2\x23\x7a\x8c\x64\xf5\xc8\x3e\xeb\xe3"
+  "\x9c\x8e\x20\xc7\xed\x75\x44\x8f\xcc\x66\x74\x84\xa7\x31\x6b\xa0"
+  "\xbe\xc1\x7f\xa0\xa1\x51\x1d\xa9\xea\x5d\x39\xcc\xd4\xb4\x1f\x41"
+  "\x28\x70\x85\x72\xe0\x0e\x73\x10\x85\xdf\xe9\x4f\x38\x03\x9c\x60"
+  "\x0e\x59\xef\x8f\x79\xc1\xfe\x25\x98\xc7\xe9\xdc\x71\xfd\xc4\x86"
+  "\x94\x51\xa5\xc6\x3e\x83\x11\xe6\x07\xf5\x59\x03\x75\x75\x29\x53"
+  "\xb5\xf5\x78\xad\xff\x3c\x44\xcd\xae\x16\xe6\x76\xcb\xcb\x69\x33"
+  "\x60\xde\x63\xfc\x0c\xc2\xeb\x8a\x22\x2e\x33\x38\xc6\x9c\x01\xbf"
+  "\x8f\x51\x52\x53\xc6\x70\x08\xcf\xd0\xe1\x28\x3d\x01\xa9\xbd\xaa"
+  "\x91\xca\x4b\xa1\x78\xe8\x15\x50\x71\x26\xe0\x0f\xa3\x7a\xd1\xe6"
+  "\xde\x61\xc3\x71\x0d\x9f\x4e\x84\x43\xe4\xbb\x1b\x59\x0e\xb1\xf1"
+  "\x2e\xea\xb3\x0b\xe7\x87\x8b\x38\xee\x50\x6f\xe1\x76\x56\xbc\x61"
+  "\xe6\x75\x15\xda\xb5\x8a\xbf\xd6\xbf\x71\x1b\xc7\x1b\x30\x67\xa0"
+  "\x67\x03\xb7\xab\x23\xeb\x35\x96\x4d\x24\x6b\xfd\xfb\x54\x22\x2a"
+  "\x63\x16\xf2\x28\x0c\xad\xc0\xb9\x1f\xbf\xc2\xca\xbd\x68\x69\x30"
+  "\x7a\xdc\x88\x79\x02\x70\xbd\xc2\xca\x54\x84\xeb\x13\xa6\x03\x57"
+  "\x48\xbb\x8b\x86\xe0\xf9\x78\xcc\x1c\xc2\x17\xc8\x5c\xfc\xc4\xe0"
+  "\x93\xda\x93\x48\x3a\xd7\x7b\x82\xa9\xa5\x26\xfa\xde\x6d\x16\xf0"
+  "\x7a\xff\x81\x3a\x13\xf8\x92\xd4\xa5\x9c\x35\xc1\xfc\xf1\xe2\x7e"
+  "\xfb\x01\x87\x9f\x57\x54\x29\x70\x8d\x6d\xbc\xdf\xa4\x79\xdf\x60"
+  "\xc4\xf3\x4d\x23\xeb\x9b\x46\xe2\x1b\xec\x97\x59\x51\x08\xd7\x33"
+  "\xec\x84\x7d\x52\x52\x57\x86\xcc\xcb\x2d\x7b\x4e\xf6\x43\xbb\xcd"
+  "\xc4\x1f\xa6\xc6\x88\x0e\x66\xb0\x3d\xae\xdb\x05\x78\x60\x38\xdc"
+  "\x26\xbc\x0f\xe5\x4a\x85\x17\xe6\x70\x80\xef\x47\x32\x1a\xc0\x0f"
+  "\x97\x88\x1f\xe8\x55\x2a\xe6\x5f\xe3\x72\xad\x06\xda\x7e\xaa\xb1"
+  "\x11\x7c\x51\x67\xe7\x8b\x28\xbc\x5f\x25\xae\xa9\x67\xdc\x46\xea"
+  "\x06\x32\xbe\x58\xae\xed\x8e\x6b\x6e\x30\xef\xcb\x34\x6a\x71\xbc"
+  "\x54\xed\xbe\x82\xdf\xf3\x21\x3e\x30\xb1\xb6\xc7\x7b\x57\x62\x7b"
+  "\x63\x7e\x56\x02\xbc\x8c\x79\x7f\x65\x43\x8f\x43\x8d\x7b\x07\xea"
+  "\xf0\x5a\x9a\x1b\x94\x46\xde\xfa\x5f\x4a\x73\xe8\xfe\xdb\x5e\xd3"
+  "\x0e\x6d\xff\x44\x22\x67\xfb\xa7\xfa\xcb\xb3\xfd\x53\xfd\xee\xbf"
+  "\xed\x55\xed\xd0\xf6\x1a\x23\x67\xfb\xff\x93\xc9\xff\xff\x4f\xb4"
+  "\xfe\x15\xb6\x3d\xce\x43\x59\x72\x50\x96\xfc\x13\x9e\xe3\x88\x56"
+  "\xe9\x1d\xc6\xad\xb7\xec\x1d\x66\xbd\xde\x12\x57\x0f\x6e\x5a\x6f"
+  "\x49\xf9\xaf\x74\x9c\x77\xd2\xee\xe3\xf2\x4e\xcf\x78\x11\xde\xf8"
+  "\xf4\x4d\xc2\x1b\x9f\x66\xd6\x34\xc4\x5f\x40\x94\xf1\xe9\x00\xd5"
+  "\xfe\x05\x3a\x0a\xbf\x7b\xb4\xff\x46\x1d\xb5\xe9\x16\xf0\x40\xea"
+  "\x09\x1a\xe7\x81\x36\x47\x83\xde\x80\xb9\x39\xea\x0d\xf4\xc4\x35"
+  "\xea\xe9\x5e\xb8\x4e\xd9\xd7\x37\x74\x54\x32\x3e\xe7\xa9\xc5\xfd"
+  "\xf6\x75\x33\x28\xf0\xdc\xb6\x7f\x41\x1d\x65\xc1\x8b\xe5\x1d\x43"
+  "\xb0\xa1\xc1\xe4\x1b\xa9\xba\xbd\x77\xa0\xde\xb2\x26\xd2\x98\x3b"
+  "\x18\x09\x62\x08\xbf\xbb\x08\x38\xc2\x98\xc1\xef\x1a\x5a\xf0\x84"
+  "\x71\x54\x5c\x57\x85\xf0\x3e\x3c\xde\x55\x48\x45\x03\x86\xa6\xe7"
+  "\x80\x7f\xad\x71\x94\x2c\x82\xa3\x1d\x7c\x1c\xdd\x66\x71\x04\x78"
+  "\xe2\x70\xd4\xf4\xde\xda\x4f\x35\x92\x70\x54\xcd\xe2\x68\x9b\x0d"
+  "\x8e\xae\x6b\xd0\x0f\xe5\x17\x58\x1c\x3d\x15\x6b\xec\x69\xc1\x51"
+  "\xcf\x3b\x27\x67\x00\x8e\x66\x48\xc5\x51\xcf\x1a\xbe\xb6\xed\xe3"
+  "\x63\xaf\x6d\x9f\x9e\x6a\xab\x6d\x2d\x5a\xf6\xb6\xef\x2c\xd5\xed"
+  "\xd4\x59\xea\x1a\x5f\x8b\x9e\x7d\x3a\x5e\x1e\x9e\x9f\x8e\x73\x6e"
+  "\xad\xda\xd3\x17\x6c\xd7\xaa\x7d\xce\xe8\x54\xff\x35\x18\x6b\xc2"
+  "\x3a\x95\x7c\x67\xbf\xc6\x48\x1b\xcf\xad\x31\xd2\x06\xb7\xfd\xb5"
+  "\x6a\xcf\x54\x0b\xeb\x85\x67\xee\x90\xb5\x6a\x4f\x97\xb7\xfc\x5a"
+  "\xb5\xa7\xcb\x85\x75\xa9\x96\xcd\xff\x3f\xad\xb7\x5f\xab\x06\xd7"
+  "\x08\xea\x52\xed\x2e\xf6\x9a\x72\xbe\x2e\x25\x6d\x40\x3c\x39\x22"
+  "\xae\x4b\x7b\x4d\x26\xf1\xa5\x57\x4f\x12\x5f\x88\x4f\xed\x75\xa9"
+  "\xd6\x64\xad\x4b\x85\xd7\xaa\x11\x0c\x31\xfd\x14\xd5\xa5\xbd\x46"
+  "\xd9\xeb\x52\xff\x44\xe1\xb5\x6a\xbd\x7b\x70\x38\x7a\xf6\x18\x7f"
+  "\xad\x5a\xaf\xcd\xed\x63\xad\x9a\x28\xb6\xaa\xf9\x6b\xd5\x9e\x9d"
+  "\x29\x7d\xad\xda\xb3\xdb\xa4\x69\x51\x8c\x39\x21\x2d\xfa\xec\x05"
+  "\x5b\xcc\xf1\xb5\xe8\xb3\xf5\xc2\x5a\xb4\xb7\x0f\x5f\x8b\xe2\xf6"
+  "\x85\xb4\x68\xef\xa1\xbc\xf6\xed\xb4\x68\xef\xa9\x7c\x2d\x4a\xce"
+  "\xe3\xb4\x68\x6f\x23\x89\xa1\xfe\xbd\xa4\x6b\xd1\xde\x17\xf0\x39"
+  "\xb9\x3b\xc9\x33\x23\xbe\x0e\xed\x7d\x99\xaf\x43\x7b\xb3\xeb\xd1"
+  "\xfa\xa8\xc8\x3a\xb5\xde\x85\xe4\xb8\xbf\xd6\xfa\x38\xa7\x43\xc9"
+  "\x71\xbc\x4e\x8d\xac\x4f\xeb\xa3\x91\xa6\x3f\x9f\x6f\x83\xfa\xb3"
+  "\x9f\x03\xfd\xd9\xaf\x9d\xea\xcf\xbe\x47\xe4\xe9\xcf\xbe\xa2\xfb"
+  "\x9f\x3f\xd0\x40\x8e\x78\x78\x9f\x01\x1c\x0f\x7f\x7e\xa0\x3c\xde"
+  "\xf2\xfc\x80\xfb\x6f\xfb\xf6\xa8\x81\x9e\x43\x9c\xed\xfb\x1d\x94"
+  "\x67\xfb\x7e\x79\xf2\x35\x50\x40\x04\xa7\x81\x02\x22\xc4\x35\x50"
+  "\xff\xb5\x8e\x35\xd0\xc0\x3c\x4e\x03\x0d\x60\xd7\xd4\xbe\xc0\xae"
+  "\xa9\x7d\xe1\xb0\x74\x0d\xf4\x42\xdf\x07\x1a\x48\x8a\x06\x7a\x3e"
+  "\x8e\xd3\x40\xbf\xaf\x97\xa7\x81\x7e\x5f\xc7\xd7\x40\x83\x7d\xed"
+  "\x35\xd0\x0b\x33\x9d\xd7\x40\x2f\xac\x94\x87\xe7\x17\x12\x9d\xd3"
+  "\x40\x2f\x5c\x12\xd6\x40\xfd\x93\xc4\x35\x10\xf9\xce\x9e\xbb\x0e"
+  "\x5c\xc9\x71\xd7\x81\x63\xdb\xbe\x06\x1a\x60\x10\xe6\xa9\x03\xea"
+  "\x89\x06\x7a\x41\xdf\xf2\x1a\xe8\x05\x91\xf5\x7e\x03\xe7\x13\xbe"
+  "\xf8\x42\xa5\xbd\x06\x7a\x41\x64\xbd\xdf\xc0\x3d\xec\x35\x36\xeb"
+  "\xfd\x48\x1b\x10\x4f\x8e\x89\x6b\xa0\x41\x53\x49\x7c\x19\x44\xea"
+  "\xba\xb0\x3e\xb5\xd7\x40\x83\x14\xcd\x6b\xa0\x17\xd8\xf5\x7e\x2f"
+  "\x38\x58\xef\x37\x28\xd8\x5e\x03\xf5\x5f\x23\xac\x81\x02\x9e\xe4"
+  "\x70\xf4\x87\xe3\x7c\x0d\x34\x68\x5b\xfb\xd0\x40\xa2\xd8\x32\xf0"
+  "\x35\xd0\x1f\xe6\x48\xd7\x40\x7f\x48\x95\xa6\x81\x5e\x10\x59\xd7"
+  "\xf7\x87\x4b\xb6\x98\xe3\x6b\xa0\x3f\x98\x84\x35\x50\x80\x2f\x5f"
+  "\x03\xbd\x20\xb2\xae\x2f\x60\x04\xaf\x7d\x3b\x0d\x14\x30\x93\xaf"
+  "\x81\xc8\x79\x9c\x06\x1a\x8c\x48\x0c\xed\xdf\x57\xba\x06\x0a\xb8"
+  "\x24\xae\x81\x02\xae\xf2\x35\x50\xc0\x51\xa2\x75\x06\xab\x89\x06"
+  "\x0a\x28\x25\xc7\xfb\xf7\xb1\x3e\xce\x69\x20\x72\x9c\xd3\x40\x83"
+  "\xfd\xa5\x69\xa0\x27\xda\xa0\x06\xd2\x38\xd0\x40\x9a\x76\xaa\x81"
+  "\x5e\x3c\x26\x4f\x03\xbd\x78\xf4\x01\x0f\x97\xc3\xc3\x07\x07\x70"
+  "\x3c\x7c\xc8\x60\x79\xbc\x65\x88\xc3\xe7\x9f\x8e\x79\xf8\xcb\x06"
+  "\x8e\x87\xbf\x6c\x10\xe7\xe1\x43\x1d\xd7\x3f\xa3\x46\x04\x70\x3c"
+  "\x7c\xd8\x0e\x32\x4f\x0e\x8b\x27\xf3\xe4\xb0\xa1\xd2\x79\xf8\x9f"
+  "\x0e\x3f\xe0\xe1\x52\x78\xf8\x1f\xdd\x38\x1e\xfe\xa7\x95\xf2\x78"
+  "\xf8\x9f\x12\xf9\x3c\x7c\xe4\x2e\x7b\x1e\xfe\xa7\xcb\xce\xf3\xf0"
+  "\x61\x1d\xe4\xe1\x79\x98\x87\x73\x3c\x7c\x58\xa4\x30\x0f\x1f\xaa"
+  "\x12\xe7\xe1\xe4\x3b\x7b\xfe\x34\xa2\x03\xc7\x9f\x86\x9f\x6b\xfb"
+  "\x3c\x7c\x78\xac\x30\x57\x1a\xbe\x92\xf0\xf0\x61\x11\x2d\xcf\xc3"
+  "\x87\x45\x08\xf3\xf0\xe1\x77\x08\x67\x19\x36\xcf\x9e\x87\xc3\x35"
+  "\x82\x3c\x7c\x44\x2f\xf6\x9a\x08\x3e\x0f\x27\x6d\x40\x3c\x19\x25"
+  "\xce\xc3\x47\x5c\x22\xf1\x65\xc4\x41\x12\x5f\x88\x4f\xed\x79\xf8"
+  "\x88\xf5\xcd\xf3\x70\x82\x21\xa6\x9f\xa2\x3c\x7c\xc4\x19\x7b\x1e"
+  "\x3e\x54\xb8\xa6\x14\xf5\x72\x0e\x87\xa3\x97\x83\xf9\x3c\xfc\xa5"
+  "\xae\xed\x83\x87\x8b\x62\x2b\x96\xcf\xc3\x5f\xba\x2a\x9d\x87\xbf"
+  "\xdc\x43\x1a\x0f\xc7\x98\x13\xe2\xe1\x2f\x47\xda\x62\x8e\xcf\xc3"
+  "\x5f\x5e\x2b\xcc\xc3\x5f\xde\xc5\xe7\xe1\xb8\x7d\x21\x1e\xfe\xf2"
+  "\x29\x5e\xfb\x76\x3c\xfc\xe5\xcb\x7c\x1e\x4e\xce\xe3\x78\xf8\xc8"
+  "\x24\x12\x43\x87\x48\xaf\x29\x45\x8d\x8c\x14\xe7\xe1\x23\x17\xf1"
+  "\x79\xf8\xc8\x91\x84\x6f\x8f\x4c\x27\x3c\x7c\x64\x08\x39\x3e\xe4"
+  "\x90\xf5\x71\x8e\x87\x0f\x39\xc4\xe7\xe1\x23\xf7\x49\xe3\xe1\xde"
+  "\x6d\x90\x87\xab\x1c\xf0\x70\x55\x3b\xe5\xe1\xa3\x47\xc9\xe3\xe1"
+  "\xa3\x47\xca\xe7\x82\x63\x8d\x1c\x17\x1c\x6b\x14\xe7\x82\x81\x5d"
+  "\x1d\x73\xc1\x57\x47\x72\x5c\x30\x78\x2f\x89\xd5\xc1\xeb\x49\xac"
+  "\x0e\x0e\x96\xce\x05\x83\x8e\x3f\xe0\x82\x52\xb8\xe0\x48\x1d\xc7"
+  "\x05\x83\x36\xcb\xe3\x82\x41\x9b\xf8\x5c\x70\x5c\x8e\x3d\x17\x0c"
+  "\xba\xe9\x3c\x17\x0c\xf6\x95\xc7\x05\x83\xd5\xce\x71\xc1\xe0\xc5"
+  "\xc2\x5c\x30\xb0\xbb\x38\x17\x24\xdf\xd9\xcf\xe1\xaf\xfa\x72\x73"
+  "\xf8\x2b\x97\xda\x3e\x17\x7c\x65\x8d\xf0\x7c\xfd\xca\x66\xc2\x05"
+  "\x83\x63\x5a\x9e\x0b\x06\xc7\x08\x73\xc1\x57\x15\x64\xde\x0c\x8e"
+  "\xb5\xe7\x82\x70\x8d\x20\x17\x7c\x75\x20\x7b\x4d\x0c\x9f\x0b\x92"
+  "\x36\x20\x9e\x4c\x14\xe7\x82\xaf\x5e\x27\xf1\xe5\xd5\x63\x24\xbe"
+  "\x10\x9f\xda\x73\xc1\x57\x53\x9b\xe7\x82\x04\x43\x4c\x3f\x45\xb9"
+  "\xe0\xab\x17\xec\xb9\x60\xa0\x9f\x30\x17\x1c\xcb\xd5\xa9\xa5\xc6"
+  "\x4e\xe6\x73\xc1\x31\x3d\xdb\x07\x17\x14\xc5\xd6\x1a\x3e\x17\x1c"
+  "\x73\x47\x3a\x17\x1c\xdb\x4b\x1a\x17\xc4\x98\x13\xe2\x82\x63\x17"
+  "\xdb\x62\x8e\xcf\x05\xc7\x6e\x13\xe6\x82\x63\x73\xf8\x5c\x10\xb7"
+  "\x2f\xc4\x05\xc7\x9e\xe3\xb5\x6f\xc7\x05\xc7\xde\xe4\x73\x41\x72"
+  "\x1e\xc7\x05\xc7\xa5\x90\x18\x3a\xfa\xb8\x74\x2e\x38\x6e\xb1\x38"
+  "\x17\x1c\x17\xcf\xe7\x82\xe3\xd8\x77\xce\xc6\x65\x13\x2e\x38\x2e"
+  "\x8c\x1c\x1f\xad\xb3\x3e\xce\x71\x41\x72\x9c\xe3\x82\xe3\xf2\x9b"
+  "\xe3\x82\x8e\xf9\xc3\x94\x49\x1c\x7f\x98\x32\xc9\x9a\x3f\x9c\xe2"
+  "\xf1\x87\xf1\x53\x1d\xf3\x87\xd7\xd2\x39\xfe\x30\xd1\x44\xc6\xf7"
+  "\xc4\x4b\x64\x7c\x4f\x64\x6a\xf8\xc5\x8f\x85\x79\x1e\xf8\x43\xee"
+  "\xb5\x3c\xc2\x1f\xae\xd5\x51\x1b\x6f\xb0\xfc\xa1\x1a\x79\x6c\x5a"
+  "\xc0\xf2\x87\x59\x98\x3f\x4c\xec\x8a\xf9\x83\x67\x3a\x70\xd5\x4a"
+  "\x96\xbb\x46\x01\x77\xad\x84\xbf\x61\xec\x7c\x0d\x6d\x14\x03\xbf"
+  "\x4c\xc6\xd7\xe3\x7d\x1b\xa0\x2d\xe6\x5d\x4e\xe6\x3d\x4f\xbd\x3b"
+  "\xde\x0f\x08\x73\x0b\xbc\xbf\x46\xb3\x7b\x6b\x54\xb2\x7b\x6b\x84"
+  "\xf1\xf7\xd6\xc0\x7b\x6a\xe0\xfd\x35\xd2\xa3\x91\xfa\x23\x96\x53"
+  "\x74\x5a\xa9\xe8\x84\xf7\xd7\xe8\x54\x43\xf8\x69\xae\xb9\x80\xf0"
+  "\xd3\x77\xfc\x1e\x01\x2e\xd4\x67\xf7\x2d\x8e\x4b\x7c\x80\x79\xc4"
+  "\x3b\x5a\x4d\xcd\x3b\xda\xc7\x6f\xdf\xd6\x3e\x65\xbf\xaf\xc6\xbf"
+  "\x87\xe0\x3d\x01\x4a\x62\xcb\x18\x1e\xc1\xec\xc7\xf0\xa6\x16\x65"
+  "\xbc\x81\x3c\x80\x17\x2b\x9e\x03\x7e\xfa\x4c\x77\xe8\x7b\x11\x52"
+  "\x99\x6e\x6b\xbb\x5b\xd7\x6b\x84\xbe\xab\xcc\xb7\xb5\xa8\x30\xf4"
+  "\x67\xe6\xbd\x4e\x23\xfb\x5e\xa7\xe1\x1d\x2d\xde\x6b\x20\x60\x67"
+  "\xb4\x15\x3f\xf5\xb5\xf0\xd3\x09\x97\xe5\xf1\xd3\x09\x95\x7c\x5e"
+  "\xf1\x17\x85\x3d\xaf\x98\x18\xec\x3c\xaf\x98\x28\xb3\xfe\xcb\xc4"
+  "\x79\xce\xf1\x8a\x89\x45\xb6\xbc\x22\x87\xe1\x15\xe3\x67\x60\x0c"
+  "\x0a\xf3\x0a\xf2\x9d\xfd\x7c\xf0\xda\x7c\x6e\x3e\x78\x6d\x70\xdb"
+  "\xe7\x15\x7f\x2e\x17\x8e\xfd\x7f\xbe\x4c\x78\xc5\xc4\xc2\x96\xe7"
+  "\x15\x13\x0b\x85\x79\xc5\x6b\x53\x49\x0c\x9e\x58\x6a\xcf\x2b\xe0"
+  "\x1a\x41\x5e\xf1\xda\x66\xf6\x9a\x42\x3e\xaf\x20\x6d\x40\x9c\xc9"
+  "\x11\xe7\x15\x93\xc8\x1e\x1e\xd4\x24\x5f\x12\x77\x88\x4f\xed\x79"
+  "\xc5\x6b\xd7\x9b\xe7\x15\x04\x43\x4c\x3f\x45\x79\xc5\xa4\x81\xf6"
+  "\xbc\x62\x7c\x88\x30\xaf\x98\xe2\xc5\xe1\x68\x72\x2e\x9f\x57\x4c"
+  "\x8a\x6f\x1f\xbc\x42\x14\x5b\xe5\x7c\x5e\x31\x79\xac\x74\x5e\x31"
+  "\x79\xa5\x34\x5e\x81\x31\x27\xc4\x2b\x26\x17\xd9\x62\x8e\xcf\x2b"
+  "\x26\x5f\x15\xe6\x15\x53\x14\x7c\x5e\x81\xdb\x17\xe2\x15\x53\xfa"
+  "\xf2\xda\xb7\xe3\x15\x53\x82\xf9\xbc\x82\x9c\xc7\xf1\x8a\x29\xd5"
+  "\x24\x86\x8e\x57\x48\xe7\x15\x53\x8a\xc4\x79\xc5\x94\x73\x7c\x5e"
+  "\x31\x25\x9b\xf0\x87\xbf\x20\xc2\x2b\xa6\x1c\x25\xc7\xc7\x23\xeb"
+  "\xe3\x1c\xaf\x20\xc7\x39\x5e\xf1\x17\xd5\x83\xf7\x2d\xdb\x62\x8e"
+  "\x29\x24\x47\xde\x1c\x1e\x92\x7d\xff\x9f\xf5\xb6\xc7\xf7\x2d\xff"
+  "\xe2\xcf\x3d\xeb\x9d\xd6\x53\x1e\x6f\x99\xe6\x7f\xff\x6d\xdf\x1e"
+  "\xd7\x1a\x87\x18\x38\xdb\x4f\xdf\x23\xcf\xf6\xd3\x33\xef\xbf\xed"
+  "\xdb\xe3\x1a\x87\x69\xf3\x38\xdb\xcf\xec\x21\xcf\xf6\x33\x45\xf7"
+  "\xbf\x6e\x5e\x97\x86\x59\xad\x71\x08\x33\x88\xeb\xd2\x99\x37\x1d"
+  "\xeb\xd2\xb9\x56\x6b\x1c\x42\xd9\x35\x0e\xa1\xec\x1a\x87\x50\x66"
+  "\x8d\x43\x02\xd6\xa5\x1f\xc7\x68\x0e\x44\xe7\x53\xb8\xd6\x57\x6e"
+  "\x74\x1d\x05\x3e\x71\x33\x62\x5d\x0a\xb6\xde\xdc\x80\x75\xe9\x09"
+  "\x36\xaf\x3d\xfb\x70\x71\x95\xd5\x9e\x16\xd4\xac\x11\x5c\xcd\xdd"
+  "\x13\x08\x7f\xf7\xf5\xad\x7c\x2a\xb9\xc1\x26\xe7\x0d\x6d\x6a\x16"
+  "\xf0\x73\xde\x38\xd7\x5d\x6f\xb5\x37\x85\x29\x35\x52\xd5\x5c\xce"
+  "\xdb\x36\xdf\xbd\xab\x01\xa9\xdb\x6f\xce\x7b\x7a\x15\x97\xf3\x9e"
+  "\x2d\x73\xfd\xc3\x6c\x9b\xf5\x0f\xe1\x02\xeb\x1f\x66\x4b\x58\xff"
+  "\x10\x2a\x73\xfd\x43\xa8\x93\xeb\x1f\x42\xed\xd6\x3f\x10\x6d\x3a"
+  "\xb3\x26\x41\x54\x9b\x92\xef\xec\x35\xc5\x5c\xab\xf5\x0f\x73\xda"
+  "\xc1\xfa\x87\x39\x22\xcf\xa8\xe7\xb0\xeb\x1f\x42\xef\xc1\xfa\x87"
+  "\x50\x91\xf5\x0f\x73\xd8\xf5\x0f\xa1\x02\xeb\x1f\x42\x45\xd6\x3f"
+  "\xcc\x65\xd7\x3f\x84\xda\xac\x7f\x08\x65\xd7\x3f\xcc\x75\xb0\xfe"
+  "\x61\x2e\xbb\xfe\x61\x2e\xbb\xfe\x81\xf8\xd4\x5e\x9b\xce\x75\x62"
+  "\xfd\x43\x28\xbb\xfe\x21\xd4\xc1\xfa\x87\xb9\x02\xeb\x1f\x66\x1a"
+  "\x84\xb5\x69\x98\xd5\xfa\x87\x30\x9b\xf5\x0f\xaf\xb7\x93\xf5\x0f"
+  "\xa2\xd8\xb2\x59\xff\xf0\xba\x8c\xf5\x0f\x61\x12\xd7\x3f\x84\x8a"
+  "\xac\x7f\x08\x8b\xb4\xc5\x1c\x5f\x9b\x86\x89\xac\x7f\x08\xb3\x59"
+  "\xff\x10\x2a\xb2\xfe\x21\xec\x14\xaf\x7d\x3b\x6d\x1a\x66\xb3\xfe"
+  "\x21\xd4\x66\xfd\x43\x38\xbb\xfe\x61\xe6\x0e\xe9\xda\x34\xdc\xc1"
+  "\xfa\x87\x70\x9b\xf5\x0f\xe1\xec\xfa\x87\x70\x76\xfd\x43\x38\xbb"
+  "\xfe\x61\x66\x9a\xf5\x71\x4e\x9b\x92\xe3\x9c\x36\x0d\x97\xb8\xfe"
+  "\xe1\xc1\xbb\x98\xad\xa3\x4d\xdf\x94\xb9\xfe\xe1\x4d\x87\xeb\x1f"
+  "\x1e\xe8\x23\x31\x8e\x1e\xae\xe3\x38\x7a\xc4\x71\x79\xbc\x25\x42"
+  "\x77\xff\x6d\xdf\x1e\xf5\xd1\x9b\x9b\x38\xdb\xbf\x35\x54\x9e\xed"
+  "\xdf\x1a\x22\x5f\x1f\x45\xab\x38\x7d\x14\xad\x12\xd7\x47\x6f\x37"
+  "\xb3\xff\xdf\xc2\x10\x4e\x1f\xcd\x3f\x42\x38\xca\xfc\x5d\x84\xa3"
+  "\xcc\x9f\x29\x5d\x1f\xcd\x3b\xc7\xd7\x47\x6f\xcf\x79\xa0\x8f\xe4"
+  "\xea\xa3\x48\x0f\x4e\x1f\xcd\xdb\x23\x4f\x1f\xcd\xcb\xe4\xeb\xa3"
+  "\xe8\x63\xf6\xfa\x68\xbe\xbb\xf3\xfa\x68\x7e\x2f\x79\x58\x9f\xaf"
+  "\x75\x4e\x1f\xcd\x5f\x2f\xac\x8f\xde\x56\x8b\xeb\x23\xf2\x9d\x3d"
+  "\xaf\x5d\xd8\x8b\xe3\xb5\x0b\xee\xb4\x7d\x7d\xb4\x20\x4d\x98\xc3"
+  "\x2e\xd8\x43\xf4\xd1\xfc\xa4\x96\xd7\x47\xf3\x93\x84\xf5\xd1\x42"
+  "\xb2\xff\x2b\x35\x7f\x93\xbd\x3e\x82\x6b\x04\xf5\xd1\xc2\x60\xf6"
+  "\x9a\x24\xbe\x3e\x22\x6d\x40\xac\x09\x17\xd7\x47\x51\x0a\x12\x7b"
+  "\x16\x9e\x21\xb1\x87\xf8\xd4\x5e\x1f\x2d\xcc\x69\x5e\x1f\x11\x0c"
+  "\x31\xfd\x14\xd5\x47\x0b\x6f\xda\xeb\xa3\xb7\x45\xf6\x55\x5b\x74"
+  "\x8a\xc3\xd1\xa2\x48\xbe\x3e\x8a\x1a\xdc\x3e\xf4\x91\x28\xb6\xd2"
+  "\xf8\xfa\x68\x51\x07\xe9\xfa\x68\xd1\x50\x69\xfa\x08\x63\x4e\x48"
+  "\x1f\x2d\x5a\x6f\x8b\x39\xbe\x3e\x5a\xb4\x57\x58\x1f\x2d\x3a\xc6"
+  "\xd7\x47\xb8\x7d\x21\x7d\xb4\xe8\x2a\xaf\x7d\x3b\x7d\x14\xed\xce"
+  "\xd7\x47\xe4\x3c\x4e\x1f\x45\x67\x93\x18\xfa\x96\x8c\x7d\xd5\xa2"
+  "\xd7\x8b\xeb\xa3\xe8\x6d\x7c\x7d\x14\x1d\x46\x74\x50\xf4\x51\xa2"
+  "\x8f\xa2\x63\xc9\xf1\xb7\xf2\xad\x8f\x73\xfa\xe8\xad\x7c\xbe\x3e"
+  "\x8a\x2e\x7c\xf0\x9e\x66\x5b\xd4\x47\x31\xe1\xf2\xf4\x51\x4c\xd8"
+  "\x03\x8e\x2e\x87\xa3\x47\xeb\x39\x8e\xbe\xf8\x92\x3c\xde\xb2\x58"
+  "\x2f\x9f\xa3\xc7\x1f\xe2\x38\x7a\xfc\x21\x71\x8e\xbe\xe4\xb0\x63"
+  "\x8e\xbe\xcc\xc8\x71\xf4\xa5\x33\xc9\x3c\xb9\x74\x04\x99\x27\x97"
+  "\x2a\xa4\x73\xf4\xd8\xa5\x7c\x8e\xfe\xae\xfb\x03\x8e\x2e\x97\xa3"
+  "\xc7\xec\xe3\x38\x7a\xec\x28\x79\x1c\x3d\x76\x24\x9f\xa3\x27\xcc"
+  "\xb1\xe7\xe8\xb1\x39\xce\x73\xf4\xd8\x22\x79\x58\x8f\x2d\x74\x8e"
+  "\xa3\x2f\xed\x2b\xcc\xd1\x97\xe4\x8b\x73\x74\xf2\x9d\x3d\xb7\x5a"
+  "\x56\xc4\x71\xab\x65\x3b\xda\x3e\x47\x5f\x36\x44\x98\x47\x2d\x1b"
+  "\x45\x38\xfa\xd2\x3e\x2d\xcf\xd1\x97\xf6\x11\xe6\xe8\xcb\x8e\x10"
+  "\x3e\xb3\xb4\x9f\x3d\x47\x87\x6b\x04\x39\xfa\xb2\xeb\xec\x35\x7d"
+  "\xf8\x1c\x9d\xb4\x51\x41\x2d\xef\x20\xce\xd1\x97\xb3\xef\x05\x2d"
+  "\x5f\x4c\x62\x0f\xf1\xa9\x3d\x47\x5f\x3e\xb6\x79\x8e\x4e\x30\xc4"
+  "\xf4\x53\x94\xa3\x2f\x4f\xb5\xe7\xe8\x4b\x0e\x09\x73\xf4\x78\xab"
+  "\x75\x9a\xf1\x5e\x7c\x8e\xbe\xfc\x42\xfb\xe0\xe8\xa2\xd8\x1a\xc2"
+  "\xe7\xe8\x71\xb9\xd2\x39\x7a\xdc\x25\x69\x1c\x1d\x63\x4e\x88\xa3"
+  "\xc7\xf7\xb5\xc5\x1c\x9f\xa3\xc7\x07\x0b\x73\xf4\xf8\x39\x7c\x8e"
+  "\x8e\xdb\x17\xe2\xe8\xf1\x9b\x79\xed\xdb\x71\xf4\xf8\x1c\x3e\x47"
+  "\x27\xe7\x71\x1c\x3d\x81\xe5\xc4\x4b\x66\x4a\xe7\xe8\x09\x7d\xc5"
+  "\x39\x7a\xc2\x40\x3e\x47\x4f\xf0\x20\x5c\x3c\x21\x94\x70\xf4\x84"
+  "\xee\xe4\xf8\x92\x19\xd6\xc7\x39\x8e\x4e\x8e\x73\x1c\x3d\x21\xea"
+  "\xc1\x3b\x9c\x6d\x91\xa3\x27\x76\x90\xc7\xd1\x13\x3d\xe4\xf3\xc4"
+  "\xf7\xca\x39\x9e\xf8\x5e\xb9\x38\x4f\x4c\xbc\xe0\x98\x27\xae\xf5"
+  "\xe7\x78\xe2\xea\xb5\x24\x56\xaf\x8e\x24\xb1\x7a\x75\x2f\xe9\x3c"
+  "\x71\xd5\x1e\x3e\x4f\x5c\xd9\xf7\x01\x4f\x94\xcb\x13\x13\xd6\x70"
+  "\x3c\x71\xd5\x7c\x79\x3c\x71\xd5\x3c\x3e\x4f\x4c\x12\xd8\x53\x6b"
+  "\xd5\x19\xe7\x79\xe2\xaa\x3b\xf2\x78\xe2\xaa\x1a\xe7\x78\xe2\xea"
+  "\xc9\xc2\x3c\x31\x51\x2f\xce\x13\xc9\x77\xf6\xf3\xfb\x9a\x3b\xdc"
+  "\xfc\xbe\xe6\x78\xdb\xe7\x89\x6b\xc2\x84\xe7\xf2\x35\xf3\x09\x4f"
+  "\x5c\x3d\xa9\xe5\x79\xe2\xea\x49\xc2\x3c\x71\x0d\x5b\xff\x6c\x75"
+  "\x88\x3d\x4f\x84\x6b\x04\x79\xe2\x5a\x36\xff\xbb\x7a\x12\x9f\x27"
+  "\x92\x36\x20\xd6\xf4\x17\xe7\x89\x6b\x8b\x48\xec\x59\xcb\x3e\x47"
+  "\x22\x3e\xb5\xe7\x89\x6b\x17\x37\xcf\x13\x09\x86\x98\x7e\x8a\xf2"
+  "\xc4\xb5\xc7\xec\x79\x62\x62\xb9\x30\x4f\x7c\x2f\x95\xc3\xd1\x7b"
+  "\x03\xf9\x3c\x71\x9d\x7b\xfb\xe0\x89\xa2\xd8\x0a\xe3\xf3\xc4\x75"
+  "\xe7\xa4\xf3\xc4\xf7\x3a\x48\xe3\x89\x18\x73\x42\x3c\xf1\xbd\xc9"
+  "\xb6\x98\xe3\xf3\xc4\xf7\x16\x09\xf3\xc4\xf7\xd6\xf3\x79\x22\x6e"
+  "\x5f\x88\x27\xbe\x77\x98\xd7\xbe\x1d\x4f\x7c\xef\x0c\x9f\x27\x92"
+  "\xf3\x38\x9e\x98\xc4\xee\x81\x95\xb8\x56\x3a\x4f\x4c\x9a\x2c\xce"
+  "\x13\x93\x6c\xf6\xbf\x4a\x62\xf7\xbf\x4a\x4a\x22\x3c\x31\x89\xdd"
+  "\xff\x2a\x71\x8d\xf5\x71\x8e\x27\x92\xe3\x1c\x4f\x4c\x4a\x73\xed"
+  "\xfd\xce\xe4\x09\x1c\xb7\x48\x9e\x20\xce\x2d\xd6\x0f\x76\xcc\x2d"
+  "\x36\xa7\x71\xdc\x62\x63\x3d\x19\xdf\x1b\x2f\x90\xf1\xbd\x91\x59"
+  "\x9f\x14\x5f\x04\xdc\xe2\xa9\x18\xcd\xfe\x1b\x79\x0c\xb7\x38\xb0"
+  "\xa0\x8e\x02\xbe\xe7\x66\xc6\xdc\x02\x78\xdd\xa6\x25\x98\x5b\x54"
+  "\xb2\xef\x77\x6e\xf4\x2d\x8a\xb5\xe6\x16\xeb\x37\x33\xef\x7a\x36"
+  "\xed\x5b\x5b\x89\xf0\xf7\x42\xef\x7e\x1e\x5b\xc0\xbe\xfb\x09\x6d"
+  "\x5b\xbf\xf3\xc9\xbc\x07\x7a\x03\xb8\xc7\x5c\xf0\x87\x15\xf7\x78"
+  "\xf0\xee\x27\x9e\xeb\x37\x5c\x92\xc7\x6b\x37\xe8\xf9\x9c\x23\xd9"
+  "\x64\xcf\x39\x36\x8e\x72\x9e\x73\x6c\x8c\x94\xc7\x39\x36\x46\x38"
+  "\xc7\x39\x36\x9e\x12\xe6\x1c\xeb\x87\x60\x7c\x0a\x73\x0e\xf2\x9d"
+  "\xfd\x5c\xb1\x39\x92\x9b\x2b\x36\x0f\x6c\xfb\x9c\x63\x53\x99\xf0"
+  "\xbc\xb0\xe9\x12\xe1\x1c\x1b\x0b\x5a\x9e\x73\x6c\x2c\x10\xe6\x1c"
+  "\x9b\xd9\xf8\xbf\xb1\xd0\x9e\x73\xc0\x35\x82\x9c\x63\x33\xfb\xfc"
+  "\x6f\x63\x01\x9f\x73\x90\x36\x20\x06\xed\x15\xe7\x1c\x5b\x46\x90"
+  "\x98\xb4\xc5\x87\xc4\x24\xe2\x53\x7b\xce\xb1\xf9\x6a\xf3\x9c\x83"
+  "\x60\x88\xe9\xa7\x28\xe7\xd8\xd2\xdf\x9e\x73\xac\x0f\x10\xe6\x1c"
+  "\xc9\x56\xeb\xb4\xb7\xe6\xf0\x39\xc7\x96\xa5\xed\x83\x73\x88\x62"
+  "\xab\x8c\xcf\x39\xb6\x06\x4b\xe7\x1c\x5b\xe3\xa5\x71\x0e\x8c\x39"
+  "\x21\xce\xb1\xf5\x94\x2d\xe6\xf8\x9c\x63\xeb\x65\x61\xce\xb1\xd5"
+  "\xc4\xe7\x1c\xb8\x7d\x21\xce\x91\xdc\x8b\xd7\xbe\x1d\xe7\x48\x1e"
+  "\xc5\xe7\x1c\xe4\x3c\x8e\x73\x24\x57\xb1\xba\xed\x92\x74\xce\x91"
+  "\x7c\x4a\x9c\x73\x24\x9f\xe1\x73\x8e\xe4\x2c\xc2\x2d\x92\x8d\x84"
+  "\x73\x24\xe7\xb3\x5c\x44\x6f\x7d\x9c\xe3\x1c\xe4\x38\xc7\x39\xb6"
+  "\x79\x4a\xc8\x4d\xa9\xa5\xbc\xfb\x99\x7b\x97\x9f\x9b\xb2\xe4\xa5"
+  "\x8c\x7d\x06\xbb\x35\xe5\xa6\x60\xae\x17\xdb\x47\x1d\xe7\xa6\xf0"
+  "\xdc\xcd\xe5\xa6\x2e\x30\xb1\x8a\xcb\x4d\xe9\x99\xdc\x14\xce\x4b"
+  "\x81\x66\x6f\xca\x4b\x99\xdf\xb5\x7f\xef\x33\xd7\x2c\x3d\x2f\x35"
+  "\x6b\x91\x0a\xed\x66\xe6\xef\x9f\x0f\x91\xbc\x54\x59\x53\x5e\x0a"
+  "\xcf\xdb\xa6\x5a\xfb\xbc\x14\x9e\xaf\xb9\xbc\xd4\xcf\x32\xf3\x52"
+  "\xef\xef\x91\x37\x7f\xbf\xdf\x06\xde\x7f\x6b\x8f\xef\x7d\x6e\xd3"
+  "\x70\xcf\x8e\x53\x64\xbe\xff\x96\xe2\xf0\xfd\xb7\x07\xeb\x9a\xc5"
+  "\x6c\xff\x7e\x15\x67\xfb\xd4\x1d\xf2\x6c\x9f\x9a\x76\xff\x6d\xdf"
+  "\x1e\xd7\x4c\xa4\x84\x71\xb6\xff\x50\x66\xfd\xb7\x0f\xd5\xf2\x73"
+  "\xe1\x19\x9e\x9c\x5e\xcd\xf0\xb4\xd6\xab\x05\x23\xad\xf5\xea\x87"
+  "\x57\x1d\xeb\xd5\xf4\x49\x9c\x5e\xdd\x79\x98\x70\xc3\x9d\x3b\x08"
+  "\x37\xdc\xc9\xec\x49\x16\x3f\x02\x31\x3a\xd5\x88\x35\xeb\x5b\x75"
+  "\xd4\xfe\x6b\x3a\xca\xb8\x8a\x68\xd5\x12\x63\x21\x2a\x32\xd4\xa1"
+  "\x8d\x4b\x90\xdb\xfa\x1b\xc8\xed\xb3\x5b\x75\x94\xf7\x3c\xe4\x01"
+  "\xf3\x04\x70\xa9\x42\xe0\x16\xbb\x50\x54\x02\xd6\xb1\x3b\xce\x94"
+  "\x44\x19\xac\x74\x6c\xda\x44\x4e\xc3\xc2\x79\x51\x75\xe8\x9b\xb7"
+  "\x74\x14\xd6\xaa\x8d\xa9\x91\xaa\xc6\xbe\x83\x49\xcd\x22\xeb\x7c"
+  "\x39\xfc\xb6\x66\x16\x3f\x5f\xde\x90\x1a\xa9\xae\xcf\x1d\xec\xc6"
+  "\xd4\x43\xec\xc9\xe5\xcd\x9d\xcd\x97\x7f\xd4\x80\xd4\x96\x7a\x88"
+  "\x78\x5e\x6c\x7f\xf9\xf2\x54\x3d\x97\x2f\xdf\xb1\x4b\x5e\xbe\x7c"
+  "\x47\x3a\x5f\xbb\x66\x1c\xb1\xd7\xae\x3b\x15\xce\x6b\xd7\x9d\x32"
+  "\xdf\xff\xdf\xe9\xef\x9c\x76\xdd\xb9\xd6\x56\xbb\x66\x27\x60\xed"
+  "\xfa\x61\x35\xc6\xaa\xb0\x76\x25\xdf\xd9\x6b\x8e\xf4\x9e\x9c\xe6"
+  "\xf8\xe8\x66\xdb\xd7\xae\x1f\xa5\x08\xeb\x8b\x8f\x76\x11\xed\xba"
+  "\x73\x4d\xcb\x6b\xd7\x9d\x6b\x84\xb5\x6b\xba\x0f\xe1\xf9\x3b\xd7"
+  "\x58\x74\x28\xa7\x5d\xe1\x1a\x41\xed\x9a\x3e\xca\xf6\x1a\xa2\x5d"
+  "\x77\x26\x11\xed\x9a\x3e\x47\x5c\xbb\xa6\xb3\xf5\xd2\xd2\x8b\x48"
+  "\x7c\x22\x3e\xb5\xd7\xae\xe9\x7b\x9b\xd7\xae\x04\x43\x4c\x3f\x45"
+  "\xb5\x6b\xfa\x75\x7b\xed\xfa\x61\x95\xb0\x76\xdd\x7d\x92\xc3\xd1"
+  "\xee\x70\xbe\x76\xdd\x35\xb0\x7d\x68\x57\x51\x6c\xa5\xf0\xb5\xeb"
+  "\x6e\x77\xe9\xda\x75\xf7\x60\x69\xda\x15\x63\x4e\x48\xbb\xee\x5e"
+  "\xcb\xe2\x27\x49\x58\xbb\xee\xde\x23\xac\x5d\x77\x1f\xe1\x6b\x57"
+  "\xdc\xbe\x90\x76\xdd\x7d\x99\xd7\xbe\x9d\x76\xcd\x50\xf0\xb5\x2b"
+  "\x39\x8f\xd3\xae\x19\x59\x24\x86\x7e\xb8\x4d\xba\x76\xcd\x58\x2b"
+  "\xae\x5d\x33\x36\xf3\xb5\x6b\x46\x28\xd1\xa8\x19\xf9\x44\xbb\x66"
+  "\xc4\x90\xe3\x1f\x26\x5b\x1f\xe7\xb4\x2b\x39\xce\x69\xd7\x8c\x02"
+  "\x09\xda\xd5\xaf\x85\xb4\xab\x47\xfb\xd2\xae\xe5\x31\xad\xab\x5d"
+  "\xf7\xcc\x94\xa7\x5d\xf7\xcc\x70\x92\xc3\xab\x9b\xe1\xf0\x6e\xff"
+  "\x7f\x71\xf8\x8c\x72\x8e\xc3\x7f\x7c\x5e\x1e\x67\xf9\xb8\xec\x7e"
+  "\xdb\xbe\xfd\xd9\x7d\x4f\x16\x67\xf7\xac\x89\xf2\xec\x9e\x35\xe1"
+  "\x81\x6e\x95\x63\xfb\x4f\xac\xf2\x35\x7b\x65\xae\x7f\xde\x5b\x28"
+  "\x5f\xb7\xe6\x56\x71\xba\x35\xb7\xca\x5a\xb7\x7e\xc7\x7b\xce\xfa"
+  "\xe9\x1e\xc7\xba\xf5\xf3\x7e\x9c\x6e\xcd\xd9\x46\x78\x61\x0e\xbb"
+  "\xde\x36\x87\xe1\x5b\x71\x87\x89\x6e\xbd\x8b\x75\xeb\x15\xd0\xad"
+  "\x6f\x84\x52\x46\xb6\x06\x3f\x5e\x97\x55\x04\xda\x13\x6b\xd5\x92"
+  "\x58\xf8\x7f\x8c\x01\x6d\x8c\x46\x6e\x1b\x40\x73\xe6\xc0\xfc\x95"
+  "\xb3\xc4\x40\x25\xbd\x05\xb1\xbf\x2c\x17\x79\x47\x80\x9e\xbd\x85"
+  "\xf5\xec\x09\xd0\xaa\x6b\x59\x3d\x9b\x9d\x5b\x12\x63\xad\x67\xff"
+  "\xfa\x24\xa3\x67\x0d\x64\xcd\x57\x49\x0c\xe8\x59\xf8\x3d\x5c\xd3"
+  "\xdf\x5a\xcf\xd6\x83\x5e\x6d\x00\xbd\x9a\x7c\xcd\x46\xdb\xbe\x61"
+  "\xaf\x6d\xeb\x7d\x23\xfd\xea\xfa\x0e\xf6\xc0\xda\xf6\xee\xde\xff"
+  "\x1f\xb5\x6d\x56\x1a\xa7\x6d\xb3\x97\xca\xd3\xb6\xd9\xb1\x7c\x6d"
+  "\xbb\x3f\xd5\x5e\xdb\x66\x5f\x70\x5e\xdb\xe6\x28\xe4\x8d\x19\xbc"
+  "\x1c\xd7\x19\x6d\x9b\x33\xc7\x56\xdb\x7e\xca\x3c\x97\xfd\x34\x0b"
+  "\xe3\x59\x58\xdb\x92\xef\xec\x35\xc9\xe7\x0a\x4e\x93\x7c\x56\xd4"
+  "\xf6\xb5\xed\x67\x51\xc2\xfa\xe3\xb3\xa5\x44\xdb\xe6\x84\xb6\xbc"
+  "\xb6\xcd\x09\x15\xd6\xb6\x9f\xb1\xeb\xff\x73\x42\xed\xb5\x2d\x5c"
+  "\x23\xa8\x6d\x3f\x7f\xd2\xf6\x1a\xa2\x6d\x73\xc2\x88\xb6\xfd\x7c"
+  "\xa8\xb8\xb6\xfd\xfc\x3c\x89\x61\x9f\xe7\x90\x18\x46\x7c\x6a\xaf"
+  "\x6d\x3f\x5f\xd9\xbc\xb6\x25\x18\x62\xfa\x29\xaa\x6d\x3f\x3f\x65"
+  "\xaf\x6d\x3f\xcd\x14\xd6\xb6\xb9\x7b\x38\x1c\xe5\x8e\xe0\x6b\xdb"
+  "\x7d\x3e\xed\x43\xdb\x8a\x62\x2b\x8a\xaf\x6d\xf7\x5d\x92\xae\x6d"
+  "\x73\x7d\xa5\x69\x5b\x8c\x39\x21\x6d\x9b\x3b\x87\xc5\x4f\x98\xb0"
+  "\xb6\xcd\x8d\x17\xd6\xb6\xb9\xa9\x7c\x6d\x8b\xdb\x17\xd2\xb6\xb9"
+  "\xc7\x79\xed\xdb\x69\xdb\xdc\x0b\x7c\x6d\x4b\xce\xe3\xb4\xed\x7e"
+  "\x36\x86\x7e\x1a\x2c\x5d\xdb\xee\x9f\x23\xae\x6d\xf7\x47\xf2\xb5"
+  "\xed\xfe\x21\x44\xc3\xee\x4f\x21\xda\x76\xff\x04\x72\xfc\xd3\x20"
+  "\xeb\xe3\x9c\xb6\x25\xc7\x39\x6d\xbb\x3f\x4b\xda\x73\x59\x97\xea"
+  "\x1e\xb9\xb5\xfe\x3b\x03\x2d\x55\xf7\xc8\xf2\x6c\xb6\xb5\xde\x19"
+  "\xc8\x1b\x2a\x4f\xdf\xe6\x39\xac\xff\xf2\x40\x63\x09\xf1\xfc\xfd"
+  "\xf9\x1c\xcf\x3f\x78\x58\x1e\x67\x39\x78\xe8\x81\xc6\x92\x63\xfb"
+  "\xbc\x35\x9c\xed\xff\xde\x5f\x9e\xed\xff\xde\x4f\xbe\xc6\xfa\x4a"
+  "\xcb\x69\xac\xaf\xb4\xe2\xcf\x06\x0f\xb9\x3b\xd6\x58\xf9\x51\x9c"
+  "\xc6\xfa\xe2\x0c\xe1\x27\x5f\x1c\x26\xfc\xe4\x8b\xc5\x2d\xf7\x6c"
+  "\xf0\xf0\x75\xfe\xb3\xc1\x43\xf3\x1f\x3c\x1b\x6c\x09\xfd\x74\xd0"
+  "\xc8\xe9\xa7\xc3\x47\xe4\xe9\xa7\xc3\xf9\x7c\xfd\xf4\xd5\x39\x7b"
+  "\xfd\xf4\x45\x0f\xe7\xf5\xd3\x17\x23\xe4\x8d\x87\x2f\x86\x3b\xa7"
+  "\x9f\xbe\xd8\x23\xfc\x6c\xf0\x90\x87\xf8\xb3\x41\xf2\x9d\x3d\xef"
+  "\xcd\x1f\xc1\xf1\xde\x7c\xaf\xb6\xaf\x9f\xfe\x91\x27\xcc\x71\xff"
+  "\x71\x84\xe8\xa7\x2f\x32\x5b\x5e\x3f\x7d\x91\x29\xac\x9f\xf2\xd9"
+  "\xf7\x5f\xbf\xc8\xb4\xd7\x4f\x70\x8d\xa0\x7e\xca\x9f\x63\x7b\x0d"
+  "\xd1\x4f\x5f\x64\x11\xfd\x94\x1f\x2f\xae\x9f\x8e\x74\x25\xf1\x29"
+  "\xff\x2a\x89\x4f\xc4\xa7\xf6\xfa\x29\xff\x78\xf3\xfa\x89\x60\x88"
+  "\xe9\xa7\xa8\x7e\x3a\xd2\xc1\x5e\x3f\x1d\x72\x13\xd6\x4f\x5f\x5e"
+  "\xe2\x70\xf4\xe5\x4a\xbe\x7e\x3a\x32\xb1\x7d\xe8\x27\x51\x6c\xe5"
+  "\xf1\xf5\xd3\x97\x4f\x4a\xd7\x4f\x5f\x4e\x96\xa6\x9f\x30\xe6\x84"
+  "\xf4\xd3\x97\x7b\x58\xfc\x64\x09\xeb\xa7\x2f\x8f\x09\xeb\xa7\x2f"
+  "\xcf\xf1\xf5\x13\x6e\x5f\x48\x3f\x7d\xa5\xe0\xb5\x6f\xa7\x9f\xbe"
+  "\xea\xc1\xd7\x4f\xe4\x3c\x4e\x3f\x7d\xa5\x23\x31\xf4\xef\xb9\xd2"
+  "\xf5\xd3\x57\x7b\xc4\xf5\xd3\x57\x39\x7c\xfd\xf4\x55\x1c\xd1\x49"
+  "\x5f\x9d\x25\xfa\xe9\xab\x64\x72\xfc\xef\xfb\xac\x8f\x73\xfa\x89"
+  "\x1c\xe7\xf4\xd3\x57\x95\xd2\xf4\x93\xf3\x75\x91\xee\xff\xba\x56"
+  "\x4d\x3b\x5d\xd7\x7a\x6c\xa9\x3c\xed\x74\x2c\xf6\x01\x87\x97\xc3"
+  "\xe1\xbf\xaa\xe3\x38\xfc\xd7\x32\xdf\xff\xfd\xba\x46\x3e\x87\xff"
+  "\xae\x9a\xe3\xf0\xdf\x55\x8b\x73\xf8\x6f\x4e\x39\xe6\xf0\x27\x06"
+  "\x70\x1c\xfe\xdb\x54\x32\x47\x7e\xbb\x94\xcc\x91\xdf\x0e\x6e\x39"
+  "\x0e\x7f\xfc\x20\x9f\xc3\xeb\xfa\x3f\xe0\xf0\x2d\xc1\xe1\x8f\x59"
+  "\xed\x77\x7c\x3c\x5e\x1e\x87\x3f\x1e\xc7\xe7\xf0\xdf\xef\xb0\xe7"
+  "\xf0\xc7\x2f\x39\xcf\xe1\xbf\x75\x97\x37\x1e\xbe\x75\x73\x8e\xc3"
+  "\x7f\x1b\x2e\xcc\xe1\xbf\x29\x14\xe7\xf0\xe4\x3b\x7b\xee\x75\xc2"
+  "\x9d\xe3\x5e\xff\x3c\xd3\xf6\x39\xfc\x3f\x63\x84\x79\xd6\x3f\xe3"
+  "\x09\x87\xff\x36\xac\xe5\x39\xfc\xb7\x61\xc2\x1c\xfe\x9f\x37\x09"
+  "\xdf\xf9\x36\xcc\x9e\xc3\xc3\x35\x82\x1c\xfe\x44\x4f\xdb\x6b\x08"
+  "\x87\xff\x36\x82\x70\xf8\x13\x23\xc4\x39\xfc\x89\x0b\x24\x3e\x9d"
+  "\xc8\x25\xf1\x89\xf8\xd4\x9e\xc3\x9f\x58\xdb\x3c\x87\x27\x18\x62"
+  "\xfa\x29\xca\xe1\x4f\x14\xd9\x73\xf8\x6f\x0a\x84\x39\xfc\x77\x7b"
+  "\x39\x1c\x7d\x37\x8a\xcf\xe1\x4f\xfa\xb6\x0f\x0e\x2f\x8a\xad\x18"
+  "\x3e\x87\x3f\x79\x59\x3a\x87\xff\xae\xab\x34\x0e\x8f\x31\x27\xc4"
+  "\xe1\xbf\x0b\x67\xf1\x13\x21\xcc\xe1\xbf\x5b\x29\xcc\xe1\xbf\xdb"
+  "\xc1\xe7\xf0\xb8\x7d\x21\x0e\xff\xdd\x49\x5e\xfb\x76\x1c\xfe\xbb"
+  "\x4b\x7c\x0e\x4f\xce\xe3\x38\xfc\xf7\x6b\x48\x0c\xfd\x66\x91\x74"
+  "\x0e\xff\x7d\xb8\x38\x87\xff\x7e\x3e\x9f\xc3\x7f\x3f\x9c\x70\xf5"
+  "\xef\xd3\x08\x87\xff\x7e\x12\x39\xfe\x4d\x94\xf5\x71\x8e\xc3\x93"
+  "\xe3\x1c\x87\xff\x3e\xfb\x41\xdd\xa4\xb6\x58\x37\xe9\xd4\x08\x79"
+  "\x3c\xfe\xd4\x70\xf9\x5c\xf2\x8c\x9a\xe3\x92\x67\xd4\xd6\x5c\x92"
+  "\x5f\xdb\xe0\xb4\xaf\x63\x2e\x59\x3c\x83\xe3\x92\x85\xc7\x48\xac"
+  "\x2e\xdc\x43\x62\x75\x21\xf3\x7c\x4f\x5a\xdd\xa4\x1f\xce\xf3\xeb"
+  "\x26\x9d\x0e\x7f\x50\x37\x49\x2e\x4f\xfc\xfe\x28\xc7\x13\x7f\xd8"
+  "\x2b\x8f\x27\xfe\x90\xc5\xe7\x89\x67\x8e\xdb\xf3\xc4\xc2\x0e\xce"
+  "\xf3\xc4\xc2\xbe\xf2\x78\x62\x61\x1f\xe7\x78\x62\xe1\x66\xe1\x1a"
+  "\x06\xa7\xfd\xc4\xeb\x26\x91\xef\xec\xe7\xf7\xe2\xbe\xdc\xfc\x5e"
+  "\x54\xdf\xf6\x79\x62\x51\xba\xf0\x5c\x5e\xb4\x97\xf0\xc4\xc2\x4d"
+  "\x2d\xcf\x13\x0b\x37\x09\xf3\xc4\xe2\xae\x64\x4e\x2d\x4c\xb6\xaf"
+  "\x61\x00\xd7\x08\xf2\xc4\xe2\xb1\xec\x35\x9b\xf8\x3c\x91\xb4\x01"
+  "\xb1\x26\x52\x9c\x27\x96\xb8\x93\xd8\x53\x7c\x8e\xc4\x1e\xe2\x53"
+  "\x7b\x9e\x58\x9c\xdb\x3c\x4f\x24\x18\x62\xfa\x29\xca\x13\x8b\xef"
+  "\xd8\xf3\xc4\xd3\x6a\x61\x9e\x58\x6a\x55\xa7\xb5\x74\x3e\x9f\x27"
+  "\x96\x0c\x6d\x1f\x3c\x51\x14\x5b\xe9\x7c\x9e\x58\xea\x25\x9d\x27"
+  "\x96\x8e\x90\xc6\x13\x31\xe6\x84\x78\x62\xe9\x66\x5b\xcc\xf1\x79"
+  "\x62\x69\x8e\x30\x4f\x2c\x3d\xce\xe7\x89\xb8\x7d\x21\x9e\x58\x7a"
+  "\x9d\xd7\xbe\x1d\x4f\x3c\xd3\x81\xcf\x13\xc9\x79\x1c\x4f\x3c\xb3"
+  "\x8f\xc4\xd0\x53\xc7\xa4\xf3\xc4\x33\x9b\xc5\x79\xe2\x99\x54\x3e"
+  "\x4f\x3c\x13\x41\xf8\xe0\x19\x1d\xe1\x89\x67\xe2\xc8\xf1\x53\x47"
+  "\xad\x8f\x73\x3c\x91\x1c\xe7\x78\xe2\x99\x52\x69\xef\x81\xb4\x48"
+  "\xae\xb7\x95\xde\x03\x69\xa9\x5c\x6f\x6b\xbf\x07\xf2\x2f\x99\xf5"
+  "\xef\xff\xe5\x6c\xfd\xfb\x07\xeb\x64\x9a\xf2\xbc\x67\x2a\xb9\x3c"
+  "\xef\xd9\x0b\xf2\xf8\xca\xd9\x72\xf9\xdc\xbc\xdc\x6a\xff\xde\x72"
+  "\xde\xfe\xbd\xfc\xf5\xf0\xe7\x0e\x3a\xe6\xe6\x3f\x5b\xed\xdf\x5b"
+  "\xc6\xee\xdf\x5b\xc6\xee\xdf\x5b\x36\x54\xce\x7a\xf8\x0d\xb7\x90"
+  "\xdb\x46\xdb\xf5\xf0\x67\x8f\x91\xf5\xf0\xd1\xb6\xeb\xe1\x7f\x3a"
+  "\xcc\x5f\x0f\xff\xef\xfe\x62\xeb\xe1\x71\xde\xb7\x31\x77\x30\xb3"
+  "\x16\x5e\x70\x1d\xfc\xb4\x96\x5d\x07\x8f\xb1\xf9\xd1\x32\xc2\xed"
+  "\x77\xb6\x4b\x6e\xff\x2f\xab\xda\xf9\x3f\xc9\xdc\xff\xf7\xa7\x44"
+  "\x3e\xb7\xbf\x20\xb0\xff\xef\x4f\x12\xf6\xff\x2d\x93\xb9\xff\x6f"
+  "\x99\x93\xfb\xff\x96\xd9\xed\xff\x4b\xd6\xc1\x9f\x3b\x24\xbe\x0e"
+  "\x9e\x7c\x67\xcf\xc9\x7e\xb6\xaa\x2b\x75\xbe\x1d\xec\xff\x7b\x5e"
+  "\x64\x8f\xd6\xf3\xec\xfe\xbf\x65\xf7\x60\xff\xdf\x32\x91\xfd\x7f"
+  "\xcf\xb3\xfb\xff\x96\x35\xed\xe5\xcb\x71\xfb\x32\x91\xfd\x7f\x7f"
+  "\xee\x65\x7b\x0d\xe1\xf6\x65\xec\xfe\xbf\x3f\x3b\xd8\xff\xf7\x67"
+  "\x76\xff\xdf\x9f\xd9\xfd\x7f\x89\x4f\xed\xb9\xfd\xcf\x4e\xec\xff"
+  "\x5b\xc6\xee\xff\x5b\xe6\x60\xff\xdf\x9f\x05\xf6\xff\x3d\x97\x27"
+  "\xcc\xed\xcb\xad\xf6\xff\x2d\xb7\xd9\xff\xf7\x97\x76\xb2\xff\xaf"
+  "\x28\xb6\x6c\xf6\xff\xfd\x45\xc6\xfe\xbf\xe5\x12\xf7\xff\x2d\x13"
+  "\xd9\xff\xb7\x9c\xdd\xff\xb7\x4c\x64\xff\xdf\x72\x91\xfd\x7f\xcb"
+  "\x6d\xf6\xff\x2d\x13\xd9\xff\xb7\xfc\x14\xaf\x7d\x3b\x6e\x5f\x6e"
+  "\xb3\xff\x6f\x99\xcd\xfe\xbf\x17\xd8\xfd\x7f\xcf\x4d\x95\xce\xed"
+  "\x2f\x38\xd8\xff\xf7\x82\xcd\xfe\xbf\x17\xd8\xfd\x7f\x2f\xb0\xfb"
+  "\xff\x5e\x60\xf7\xff\x3d\x17\x62\x7d\x9c\xe3\xf6\xe4\x38\xc7\xed"
+  "\x2f\x48\xd9\xff\x57\x2d\x25\x07\x7c\xff\xd7\x71\xa8\xda\xe9\x3a"
+  "\x8e\x8b\x32\xf3\xbf\x17\x5d\xc8\xff\xfe\xda\x8f\xe3\x98\xbf\xf6"
+  "\x13\x5f\x4b\xa0\x6f\x26\xff\x5b\x19\xcb\x71\xcc\x0a\xf6\x7d\xa5"
+  "\x8a\x63\x24\x4e\x57\xc4\x3b\xbb\x96\x60\xc3\x5d\x96\x57\x5a\xd6"
+  "\x12\x2c\x61\xd7\x12\x00\xb7\x24\x5c\xf2\xd2\x1d\xfe\x5a\x02\x7d"
+  "\xbc\xd8\x5a\x02\xc1\x35\x04\x36\xfc\xd1\xc2\x35\xe5\xae\x21\x68"
+  "\xff\xfc\xf1\x82\xd5\x1a\x82\x4b\xc7\xe5\xf1\xc7\x4b\x3a\x3e\x7f"
+  "\xfc\xf5\x82\x3d\x7f\xac\xe8\xe9\x3c\x7f\xac\x08\x96\xc7\x1f\x2b"
+  "\x82\x9c\xe3\x8f\x15\x39\xc2\x6b\x08\xf4\x7e\xe2\x6b\x08\xc8\x77"
+  "\xf6\xf3\x7e\x65\x30\x37\xef\x57\xfa\xb6\x7d\xfe\xf8\xdf\x7c\xe1"
+  "\x39\xfe\xbf\xc7\x09\x7f\xac\xc8\x6e\x79\xfe\x58\x91\x2d\xcc\x1f"
+  "\x2b\x07\x92\xb9\xb6\x22\xdb\x9e\x3f\xc2\x35\x82\xfc\xb1\x32\xd2"
+  "\xf6\x1a\xc2\x1f\x2b\xf6\x11\xfe\x58\xb9\x56\x9c\x3f\x5e\x7e\x92"
+  "\xc4\xa5\xca\x9b\x24\x2e\x11\x9f\xda\xf3\xc7\xca\x53\xcd\xf3\x47"
+  "\x82\x21\xa6\x9f\xa2\xfc\xf1\xb2\x8f\x3d\x7f\xd4\x8b\xe4\x86\xaf"
+  "\x5c\xe5\x70\x74\x65\x3d\x9f\x3f\x5e\x9e\xda\x3e\xf8\xa3\x28\xb6"
+  "\xf2\xf9\xfc\xf1\x4a\x2f\xe9\xfc\xf1\xca\x4c\x69\xfc\x11\x63\x4e"
+  "\x88\x3f\x5e\xc9\x61\xf1\xb3\x4f\x98\x3f\x5e\x39\x29\xcc\x1f\xaf"
+  "\x5c\xe0\xf3\x47\xdc\xbe\x10\x7f\xfc\xb5\x03\xaf\x7d\x3b\xfe\xf8"
+  "\x6b\x4f\x3e\x7f\x24\xe7\x71\xfc\xf1\xd7\x02\x12\x43\x2f\xca\xc8"
+  "\x0d\xff\x9a\x23\xce\x1f\x7f\x3d\xc8\xe7\x8f\xbf\xb2\xb5\xf3\x7f"
+  "\x2d\x27\xfc\xf1\xd7\x34\x72\xfc\xe2\x51\xeb\xe3\x1c\x7f\xbc\x68"
+  "\x93\x1b\xfe\xb5\xda\x11\x7f\xa4\x53\xbc\xea\x92\x29\x73\x1e\x7c"
+  "\xf2\xa1\x9f\x5d\x61\x1e\xd3\xc1\xff\x0b\x60\x3e\xf2\x81\xff\x97"
+  "\x8a\xf1\x15\x83\xaf\x57\x9d\x19\xb8\x87\x19\x7e\xa7\xc4\xf0\x9b"
+  "\x4e\xd7\xcd\x08\xbf\x5d\xc5\xee\xd9\xe2\x55\xe7\x6d\x7c\x38\xc8"
+  "\x4c\x47\x20\x5a\x0d\xff\x8f\x85\x63\x70\x7e\x27\x98\xf7\x34\x4b"
+  "\x50\xa7\x1b\x54\xd5\x26\xcb\x79\xd0\xe7\x4e\x15\x54\x55\x30\x6e"
+  "\xa3\x76\x43\x55\x1a\xdc\x4f\x9d\x68\x5f\xa1\xad\xf1\x39\x8f\xa3"
+  "\x78\x23\xfd\xab\x6e\xc1\x2d\x54\x49\x55\x5d\xf2\xae\x7e\x38\x08"
+  "\xe2\x10\xc2\x7c\x2f\xaf\x9b\xc1\x0d\xb7\xa9\x5b\xd0\x80\xbf\x3b"
+  "\x81\xbf\x33\x41\x1f\x13\xe6\x23\x6a\xcb\xad\x87\x3d\x80\x57\xb9"
+  "\xaf\xa8\xa1\xab\x16\x1a\xa1\xcf\xb1\x46\xf4\xcd\xe3\x65\x6e\x07"
+  "\x76\x96\x31\x73\x4f\x71\x8d\x89\x69\x43\xb3\x80\xe9\xcf\xe5\xdd"
+  "\x70\xbe\x50\x1f\xd6\xee\x47\x7d\xdc\x7b\xd1\x7a\x69\xf3\xdd\xd5"
+  "\x00\x31\x3b\x7a\xaf\x7c\x1c\xe9\x9e\x05\xdb\x69\x10\x25\xf4\xbd"
+  "\xc4\xdf\xc9\x74\xc0\x2f\x3d\x3e\xe8\x42\xd7\xac\xd8\x81\xa8\xad"
+  "\xe6\x87\x3d\xfe\x09\x31\x31\x63\x3b\x6d\xa8\xdd\x70\xcd\x53\xaf"
+  "\xf8\x4f\x1f\x6c\xf3\xd5\xf0\xfd\xd6\x2e\xb4\xe1\xf6\x2a\x8c\x9b"
+  "\x6b\xfe\xc7\x61\x6e\xb7\xf5\x45\x74\xd8\xfc\x39\x9a\x98\xc8\xf9"
+  "\xe1\x0b\x17\xc7\x68\x7a\x86\x3d\x82\x26\x2d\x5c\xa8\x99\x3f\x67"
+  "\xc1\x52\x8d\xf5\x37\x2f\x6a\xc2\x22\xdf\x99\x33\x77\x5e\x78\xdf"
+  "\xf9\xaf\x47\x3d\x02\x7d\x42\x56\xfd\x50\xe3\xbe\x98\x37\x5c\xeb"
+  "\xb7\xfb\x7d\x84\x3e\xe8\x8c\xdc\x70\xbf\xe0\xf7\x52\xf4\x6e\xbd"
+  "\xe3\xf0\xef\x6d\xd9\x4e\xd7\x50\x70\xce\x0a\x88\x69\x5b\x13\x1e"
+  "\x86\x73\xaf\x66\x66\x40\xbf\x76\x43\xbf\xa1\x8f\xb8\xcf\x3a\x4b"
+  "\x9f\x2d\x98\x58\x81\x31\x91\x70\x0b\x30\x78\xed\x92\x77\xdd\xc3"
+  "\x81\x34\x1d\x82\xef\xaf\x06\xc6\x8a\xe2\x0a\xf5\xbf\xa5\x8c\x06"
+  "\x48\xf5\xaa\x83\x6b\x8d\x16\x8c\x99\x53\xa6\x24\xd3\xdb\xbd\x74"
+  "\xc0\x1d\x15\xb5\x74\xc4\x9f\x00\x9b\x70\xfd\xff\x82\x9f\x47\x28"
+  "\x91\xae\x0d\x61\xf6\x1f\xa0\x6b\x01\xc3\x04\xa7\xf0\x5d\x75\xf7"
+  "\xdb\x14\x1a\x56\xbb\xe1\x7f\xc3\xf5\x68\xdb\x51\xdc\x86\x1e\x8e"
+  "\x61\x9b\x9b\x33\x63\x54\x93\xb5\x28\xf1\x99\x44\x94\x58\x8b\xaf"
+  "\xc9\x1a\x58\xe5\x1d\x83\x14\xe3\x63\xe9\x8b\x10\x77\x14\xf4\x93"
+  "\x31\x2a\x7a\xef\xc0\x2a\x3d\xf5\x3f\x7f\x73\xea\x94\x64\xb8\x9f"
+  "\x6a\x68\x27\x49\xaf\xf0\x1b\x82\xdb\xd9\xba\x9d\xb1\x7d\x35\xbe"
+  "\x77\xb0\x0f\x68\x19\x5a\x47\xaf\x62\xc7\x50\xf2\x73\xd9\xe6\xe4"
+  "\x15\x79\x25\x6e\x77\xd1\x78\x23\xdd\x48\x6f\x7b\x2e\xbb\xb8\xa6"
+  "\x06\x62\x5a\xd4\xeb\xf4\x23\xd7\x46\x78\x1b\x23\xc3\x33\x3a\xc3"
+  "\x58\xdc\xb6\x22\x8f\xde\x16\x94\x38\xb9\x17\x52\x41\xdb\x95\x16"
+  "\x7b\x82\x2d\xdd\xa4\xe1\xe8\x7f\x4c\x4d\x17\x8c\x07\xe8\x0f\x8b"
+  "\x87\xea\x01\xc7\x63\xec\xf1\xd0\x34\x36\xb7\x8f\x46\x46\x3a\x24"
+  "\xb0\x31\x65\x74\x00\xad\x1e\xed\x9f\x70\x19\x3d\x84\x6d\x5b\x0c"
+  "\x7c\x7f\xcb\x12\xe4\xb7\x79\x16\xd2\xcc\x5e\xaa\x42\x86\xd4\xd1"
+  "\x1a\xef\x95\x89\x0a\xb0\x09\x05\xf1\xa5\x1f\xc4\xcc\x7e\x8d\x5d"
+  "\xa6\x24\xc7\x85\x23\x2a\xb7\x22\x8f\xc2\x3c\x19\xaf\x0b\x01\x5b"
+  "\xdf\xd9\x0d\xd7\xd1\xbf\x85\x20\xec\x0f\xc6\x17\xbf\x45\xa0\xb1"
+  "\xa0\xbc\xf1\x33\x8e\x2b\xd4\xf5\x5e\xbb\xa0\x4d\x69\xf7\x55\xcd"
+  "\xf0\x5f\x13\xf8\xea\x79\xf0\x53\x49\xa5\x89\x69\x93\xf1\xd5\x3c"
+  "\xce\x57\xc7\xa0\x1f\x9c\xbf\xaa\xf3\xb0\x5f\x45\xee\x39\x91\xbd"
+  "\xe7\x7c\xb8\xe7\x2c\x07\xf7\x9c\x49\xee\xd9\xfd\x96\xe3\x7b\xbe"
+  "\x7e\xd5\xf1\x3d\xdf\xe8\x21\xfd\x9e\xaf\x1f\x92\x7e\xcf\xd7\xb3"
+  "\xc4\xef\x39\x90\xf5\x73\x20\xf8\x39\xd0\x81\x9f\x03\x59\x3f\x77"
+  "\xac\x70\x7c\xcf\x37\x2e\x38\xbe\xe7\xdf\x7c\xa4\xdf\xf3\x8d\x6c"
+  "\xe9\xf7\x7c\x23\xcd\xc1\x3d\xb3\x7e\x0e\x04\x3f\x07\x3a\xf0\x73"
+  "\x20\xeb\x67\x9f\x1f\x1d\xdf\xf3\x6f\x67\x1c\xdf\xb3\xc1\x5d\xfa"
+  "\x3d\xff\x96\x2e\xfd\x9e\x7f\xdb\x24\x7e\xcf\x41\xac\x9f\x83\xc0"
+  "\xcf\x41\x0e\xfc\x1c\xc4\xfa\x79\xd0\x06\xc7\xf7\x6c\x38\xd9\xcc"
+  "\x3d\xd7\x4b\xbf\x67\x43\xb2\xf4\x7b\x36\x24\x3a\xb8\x67\xd6\xcf"
+  "\x41\xe0\xe7\x20\x07\x7e\x0e\x62\xfd\x3c\xfd\x25\xc7\xf7\x7c\xf3"
+  "\x88\xe3\x7b\xbe\x79\x5d\xfa\x3d\xdf\x5c\x23\xfd\x9e\x6f\xc6\x88"
+  "\xdd\x73\x03\xc4\x6d\x4f\xb8\x97\xc6\x9f\x42\x02\x4d\xea\xd1\x7d"
+  "\x3c\x2b\x11\x95\xbe\xca\x1c\xe1\x5d\x85\x3a\xc0\xbd\x45\xd0\xdb"
+  "\xa7\x86\xe2\x7f\xcd\xea\xd1\xda\x06\xf5\xe8\x80\xfa\x2e\x5e\xba"
+  "\xe5\x33\xd1\x43\x98\x8f\xaf\x37\x23\x3f\x73\xca\x68\xff\x4d\x7f"
+  "\x46\x9a\x15\x06\xa4\x2a\x4e\xd0\xa3\x84\x28\xda\x50\x8c\x2e\x21"
+  "\xaf\x2a\xac\x3d\x7f\x46\x85\xd5\x05\x68\x41\x34\x4d\x5f\xa1\x6e"
+  "\x0f\xc6\xcf\x80\x81\x27\x27\x26\xff\x1b\x69\xe0\x37\xfa\xed\x86"
+  "\x0f\x6e\xc7\x7b\x0c\xcc\x9f\xdb\xa7\xce\xcd\x48\x40\x7e\x5f\xbf"
+  "\x55\x85\xf0\xf1\x5d\xf0\x31\x6d\x9f\x92\x9c\x30\x13\x51\xfb\x6f"
+  "\x95\x51\x64\x6e\xbe\xed\x6e\x3b\x37\x8f\x99\x03\xb6\x9c\xcb\x7c"
+  "\x37\x31\xfd\xcf\x52\x6d\x79\xab\xd4\x32\x77\x33\xb6\x2c\x37\x91"
+  "\xf9\xde\x66\xee\xfe\x1a\x7e\x9f\xb3\xe5\x2d\x1d\xb6\x25\x9d\x32"
+  "\x7a\x78\x49\x55\x03\xd6\x4d\xaa\x2b\xb1\x88\x82\xe3\x51\xc5\x51"
+  "\xb7\x90\x88\x8d\x13\xad\x6c\xbc\xcf\xb3\xd2\xfd\x96\x88\x8d\xb3"
+  "\xc1\xc6\xf9\x02\x36\xce\x72\xce\xc6\x35\xbb\x5c\xb7\x71\x4d\xa4"
+  "\xb8\x8d\x6b\x0e\x4b\xb7\x71\xcd\x00\xe9\x36\xae\xf1\x67\x6d\xac"
+  "\xe3\xdb\xf8\xf6\x59\x71\x1b\x07\x5a\xe1\x38\x10\x70\xdc\xb1\x42"
+  "\xd8\xc6\x81\x80\xe3\x40\x01\x1c\x07\x3a\x89\xe3\xbb\x0a\xd7\x6d"
+  "\x7c\xa7\x48\xdc\xc6\x77\xbb\x4a\xb7\xf1\x9d\x34\xe9\x36\xbe\x93"
+  "\x44\x6c\x1c\x68\x83\xe3\x3b\x01\x0e\x6c\x6c\x85\xe3\x40\xc0\xb1"
+  "\xcf\x8f\x22\x36\x06\x1c\x07\x0a\xe0\x38\xd0\x49\x1c\xd7\x86\xbb"
+  "\x6e\xe3\xda\xfe\xe2\x36\xae\x8d\x97\x6e\xe3\xbb\x46\xe9\x36\xbe"
+  "\x5b\xcd\xda\xd8\x06\xc7\x77\xd3\xc5\x6d\x1c\x64\x85\xe3\x20\xc0"
+  "\xf1\xa0\x0d\xc2\x36\x0e\x02\x1c\x07\x09\xe0\x38\xc8\x49\x1c\xd7"
+  "\x9d\x72\xdd\xc6\x75\xa9\xe2\x36\xae\xbb\x24\xdd\xc6\x75\xa1\xd2"
+  "\x6d\x5c\x37\x81\xd8\x38\xc8\x06\xc7\x75\xc8\x81\x8d\xad\x70\x1c"
+  "\x04\x38\x9e\xfe\x92\x88\x8d\x01\xc7\x41\x02\x38\x0e\x72\x12\xc7"
+  "\x0d\x7d\x5d\xb7\x71\x7d\xbd\xb8\x8d\x1b\x46\x49\xb7\x71\xfd\x09"
+  "\xe9\x36\xae\x3f\xc4\xda\xd8\x06\xc7\xf5\x61\x62\x36\x6e\x04\x0d"
+  "\xe8\x05\x36\xf6\xaa\x46\xd4\x2e\x6c\xdb\x32\x62\x5b\x53\x97\xa9"
+  "\xa1\xbb\x28\x73\x04\xb6\x09\x93\x03\xfa\x9f\x5f\x27\x53\xca\xe8"
+  "\x3e\x34\x05\xf7\x94\x80\xf3\xae\x0d\xb9\xc6\x55\xa8\x93\x26\x01"
+  "\xe7\x7f\x8d\xcc\xfa\x00\x4d\xc2\xba\x0b\xf0\x7b\x4a\x9c\xf7\x32"
+  "\xa6\x7a\x66\x9a\x7c\x5f\x89\xba\x42\x35\x5e\xa6\x7b\x06\x20\xd0"
+  "\x5e\xc3\xe9\xb7\xfd\xd4\x25\xd5\x79\x60\x9f\xd3\xa8\xb8\xec\x4b"
+  "\x64\xee\x32\x75\xee\xf3\x46\xa4\xa5\xff\xa7\x55\x17\xc6\xe8\x91"
+  "\xe9\x75\x3f\xcf\x92\xd8\x02\x54\x12\xfb\x37\x34\xbe\x8a\xbe\x4b"
+  "\xff\x57\xeb\xd9\xe8\x3b\x3b\xdb\xe4\x3b\x75\xb8\x29\x35\x52\x6b"
+  "\xf4\x9d\x9d\x96\xbb\x44\x4f\x79\xd6\x21\xed\xbc\x4a\x9a\xde\x32"
+  "\x17\xb9\x6d\xa9\x40\x1e\x5b\xe7\x22\xcf\xad\x15\x48\x55\x58\x59"
+  "\x86\x8a\xae\x15\xa0\xa2\x5b\xe7\x51\xd1\x5d\xf8\x34\xc0\xc7\x0c"
+  "\x9f\xc4\xf3\xe0\x6b\x84\xc6\x5e\x47\x78\xef\x46\x43\xef\x72\xa4"
+  "\x2e\x34\x96\x21\xfc\xfe\xeb\x0d\xaa\x71\xa5\x67\x28\x52\xd3\xff"
+  "\xf5\x43\xf4\xeb\x7e\x14\x7c\xe7\x86\x8f\x97\x18\x0d\xa8\xb0\xb2"
+  "\x0e\x7f\x1f\x0a\xdf\xbb\xad\xa8\x84\xf6\xcd\x05\x78\x6f\x46\x43"
+  "\x61\xe2\x29\x64\xdc\x76\x34\x99\xc6\x1a\xba\xcb\x68\x94\x0c\xa6"
+  "\x36\xd3\x7e\x4f\x11\x1c\x18\x77\xec\x36\x4b\xf5\x75\x63\x1e\x63"
+  "\xe3\xb7\xfd\x3a\x83\x9d\xbb\x99\xdf\x0e\x51\x8d\x3b\x7f\x91\x2e"
+  "\xae\x29\x43\x38\x97\x50\x5c\x73\x1a\x95\xac\x31\xa3\xf1\x4b\x11"
+  "\x1a\x63\x42\x08\xdb\xa2\x24\xb6\x0a\x8d\x8b\x42\xde\x38\xff\x6c"
+  "\xfe\x9f\xb6\x73\x49\xa5\x01\xc5\x1b\xa1\x8f\x37\xea\x9a\xfa\x58"
+  "\xbc\xa6\x18\xc1\x77\xdd\x8a\x23\xf4\xc8\x33\x0a\xa9\xb0\x7d\x8d"
+  "\x29\xa3\xb5\xe3\x60\xfc\x2c\xa8\xa1\x69\x6c\x5b\x6c\x53\x6c\x5f"
+  "\xdc\x9e\xc5\xe6\x25\x61\x06\xb4\xa2\x0e\xa9\x4a\x12\xe0\xdf\x58"
+  "\xda\x50\x82\x6e\x22\xe8\x63\x0a\xed\x73\x34\x19\x70\x11\x86\xb1"
+  "\xa0\xa7\x1a\xb2\xc0\xff\x9d\x45\x30\x95\x45\x30\xe5\x7e\xcb\x09"
+  "\x4c\xed\xe3\x30\x65\x52\x70\x98\x32\x5f\x10\xc7\x94\x79\x30\x8b"
+  "\x29\x5d\xdb\xc4\x94\xe9\x9c\x63\x4c\x99\x0e\x39\xc0\x54\x3e\x60"
+  "\x2a\x91\x8f\x29\xf3\x75\xe9\x98\x32\xbb\xb5\x22\xa6\xb2\xe5\x61"
+  "\xca\x54\xc5\xc7\x94\xb1\x4e\x1c\x53\x81\x6c\x9c\xea\x58\xd1\x3c"
+  "\xa6\x02\xad\xe2\x14\x3d\xb9\x09\x53\x4a\x45\x7f\x51\x4c\x29\xd1"
+  "\x66\x82\xa9\xc0\xb6\x19\xa7\x94\xa8\x97\x43\x4c\x29\x91\x87\x38"
+  "\xa6\x02\x21\x4e\x05\xf2\xe3\x94\x52\x31\x42\x32\xa6\x94\x28\xa4"
+  "\xf5\x30\x15\x28\x2f\x4e\x29\xd1\x10\x3e\xa6\xe8\x31\x0e\x30\xc5"
+  "\xc6\x29\x9f\x1f\x9d\xc0\x14\x17\xa7\x94\x8a\x1c\x0e\x53\xca\xb5"
+  "\xe2\x98\xa2\x2e\xb1\x98\x6a\x9b\x71\x4a\x49\xc5\x3b\xc6\x14\x35"
+  "\xc3\x01\xa6\x20\x4e\x05\xf2\xe3\x94\x52\x99\x2a\x1d\x53\xd4\xbe"
+  "\x56\xc4\x94\xbc\x38\xa5\xa4\x92\x79\x98\x52\x2a\x32\xc5\x31\x15"
+  "\xc4\xc6\xa9\x41\x1b\x9a\xc7\x54\x10\x17\xa7\x94\x4a\x13\x87\x29"
+  "\xf7\xf3\xe2\x98\x72\x1f\x48\x30\x15\xd4\x46\xe3\x94\xdb\x19\xc7"
+  "\x98\x72\xcb\x13\xc7\x54\x10\xc4\xa9\x20\x9b\x38\xe5\x7e\x55\x3a"
+  "\xa6\xf0\x96\x39\xad\x85\xa9\x20\x99\x71\xca\xad\x92\x8f\x29\x65"
+  "\x8d\x03\x4c\xb1\x71\x6a\xfa\x4b\x4e\x60\xca\x2a\x4e\x3d\x34\x91"
+  "\xc3\x94\x47\x5f\x71\x4c\x3d\xbc\x9e\xc5\x54\x1b\x8d\x53\x0f\xf7"
+  "\x74\x8c\xa9\x87\xdd\x1c\x60\x0a\xe2\x54\x90\x4d\x9c\xf2\x18\x2a"
+  "\x1d\x53\x0f\x4f\x6a\x45\x4c\xc9\x8c\x53\x0f\x07\xf0\x31\xf5\x50"
+  "\x90\x18\xa6\x1a\xb0\xee\x53\x00\xa6\x22\x40\xf7\x01\x86\xbc\x4b"
+  "\x09\xa6\x1a\x01\x53\x1f\x59\x63\xea\x17\x1b\xdd\xa7\xf4\xd8\x6b"
+  "\x6e\xc2\xd4\x23\x07\x6d\x31\x65\x06\x4c\x35\x32\x98\xea\x70\xca"
+  "\xa2\xfb\x4a\xaa\x33\xc1\x57\xd7\x50\xc9\x04\xc0\xd3\x76\x16\x4f"
+  "\xbf\x00\x9e\xe0\x7e\xcc\x70\xbf\x85\xe5\x65\x68\xbc\x81\xdc\x57"
+  "\x03\xdc\xaf\xd9\x1a\x4b\x0d\x55\x14\xc6\x10\xc6\x8e\x05\x47\x45"
+  "\x0b\x00\x3f\xd1\x67\x50\xd1\x12\xf8\x2c\x83\x4f\x02\x7c\xd0\x19"
+  "\x54\x58\x85\x98\x9c\x3d\x87\x9f\x52\x16\x3f\x1d\xc2\x1d\xe3\xa7"
+  "\xc3\x48\x49\x1a\x4f\xf9\xc8\x71\xe9\xf8\xe9\x90\xc2\xae\xa5\x53"
+  "\x8d\x9f\x78\x91\xc6\x6b\x60\x09\x46\xae\xa1\xf1\x46\xe4\x4d\x4f"
+  "\xd7\x76\xf6\x0c\x41\xaa\xe5\x26\x44\x6d\x9e\x8b\x54\x9b\x7f\x86"
+  "\xfb\xb5\x8c\x9d\x0a\xe4\x79\xba\xee\x4b\x54\x78\xab\x0c\x15\xde"
+  "\x3d\x85\x0a\xcd\xf0\xb9\x06\x1f\xe8\xe3\xf8\x70\xeb\xfb\x35\xb0"
+  "\xf7\xfb\xc8\x64\x68\xcb\x5f\xfc\x7e\x1f\x19\xc0\xdc\x6f\x18\xdc"
+  "\x6f\x03\x77\xbf\x25\x80\x45\xf0\x4b\x37\x33\xab\x13\xc7\x1b\x50"
+  "\x87\x85\x46\x9a\x6e\x60\x31\x88\xfd\x72\xfa\x6c\x1d\x1a\x1f\x05"
+  "\xbe\x7a\x1d\x30\x58\x99\x8d\x56\xc4\x01\x06\x1b\xea\xf0\x73\x7d"
+  "\x43\x49\x62\x3d\x60\xb0\x43\x2c\x0d\x76\x6b\xc4\x18\xfc\x05\x63"
+  "\xd0\x23\xdd\x2c\x8e\xc1\x2c\x82\x41\xd0\x89\xcd\x63\xd0\x2a\xae"
+  "\x75\xec\xc5\x61\xd0\x6b\xa0\x38\x06\x3d\xc7\x5a\x74\xe2\xfd\xc7"
+  "\x60\xc7\xab\x8e\x31\xd8\xb1\x40\x92\x26\x54\x7a\x8d\x92\x8e\x41"
+  "\x4f\xbf\xd6\xc3\xa0\xe7\x79\xc7\x18\xf4\xcc\x77\x02\x83\xd9\xf2"
+  "\x30\xd8\xd1\xc8\xc7\x60\x47\x8d\x38\x06\x03\xd9\x38\x08\xba\xb2"
+  "\x59\x0c\x5a\xe9\x4a\xa5\x57\x2e\x87\x41\xef\x23\xe2\x18\xec\x74"
+  "\xc6\xa2\x2b\xef\x3f\x06\x3b\xcd\x77\x8c\xc1\x4e\x63\xa4\x69\x48"
+  "\xef\x53\xd2\x31\xd8\x29\xbd\xf5\x30\xe8\x3d\xd3\x31\x06\xbd\x87"
+  "\x34\x8f\xc1\x40\x99\x71\xb0\x53\x22\x1f\x83\x5e\x59\x0e\x30\xc8"
+  "\xc6\x41\xd0\xa1\xcd\x63\xd0\x2a\x0e\xaa\xfa\x73\x18\xec\x3c\x54"
+  "\x1c\x83\x3e\x93\x2d\x3a\xf4\xfe\x63\x50\x75\xd3\x31\x06\x55\xa5"
+  "\xd2\x34\x67\xe7\xb1\xd2\x31\xe8\xa3\x69\x3d\x0c\xfa\x5c\x72\x8c"
+  "\x41\x1f\x9d\x13\x18\x94\x19\x07\x7d\xdc\xf8\x18\x54\x69\xc5\x31"
+  "\x18\xc4\xc6\x41\xd0\xad\xcd\x62\xd0\x5a\xb7\x76\x3e\xcc\x61\x50"
+  "\x7d\x5c\x1c\x83\x8f\x9e\xb7\xe8\xd6\xfb\x8f\xc1\x47\x17\x3b\xc6"
+  "\xe0\xa3\x93\xa4\x69\x54\xf5\x19\xe9\x18\x7c\x34\xab\xf5\x30\xa8"
+  "\x0e\x77\x8c\x41\xf5\xc8\xe6\x31\x18\x24\x33\x0e\x3e\x9a\xc4\xc7"
+  "\x60\xe7\x7d\x0e\x30\xc8\xc6\x41\xd0\xb9\xcd\x63\xd0\x2a\x0e\xfa"
+  "\x0e\xe6\x30\xf8\xd8\x28\x71\x0c\x76\x99\x69\xd1\xb9\xf7\x1f\x83"
+  "\xbe\xf5\x8e\x31\xe8\x5b\x26\x4d\xd3\x3e\x36\x59\x3a\x06\xbb\x68"
+  "\x5b\x0f\x83\x5d\xae\x3a\xc6\x60\x97\x02\x27\x30\x28\x33\x0e\x76"
+  "\xf1\xe4\x63\xd0\xb7\x9f\x18\x06\xcd\xa0\x8b\x1b\xb3\x02\x90\x39"
+  "\x65\x76\xb6\xb7\x42\x83\x8c\xea\x57\xa2\x4a\x62\x6a\xd0\xb8\x3b"
+  "\x60\x9f\xa8\x3b\x68\xd6\x1d\x15\x32\xa5\xcc\x4e\x03\x4e\xae\xb5"
+  "\xd2\xcf\xcc\xda\x32\x63\xf2\xd1\xe4\xad\x0b\x90\x1b\xe8\xef\xb9"
+  "\xf8\x58\xc9\x95\x3a\x84\x7f\x3f\x1e\xf7\xe7\x1a\xd7\x1f\x9c\x27"
+  "\xa0\x7f\xd3\xaa\x98\x67\xcc\x0d\x7a\x54\x39\x04\x29\x0b\x2b\xf5"
+  "\x60\x87\x65\x8c\x7f\xb1\x5d\xae\x28\xfd\xb4\x19\x37\x90\x9b\xf1"
+  "\xbf\x7e\xdd\xc0\xde\x6a\xaf\x77\x91\xa2\x7b\x25\x6d\xc6\x76\xc5"
+  "\xf6\xc2\x36\xd6\x2c\xa3\x69\x38\x6f\x69\x31\x60\xcc\xf8\x5f\x6d"
+  "\xb7\xdd\x70\x9e\xb0\x5e\xf5\x5b\x29\x1d\x1b\x7e\xe4\x7d\x58\xa5"
+  "\x9f\xa6\xb0\x1c\x09\x3e\x3b\x06\x5b\x65\x39\x69\xab\x6c\x2b\x9d"
+  "\x77\x0f\x6c\xd5\x75\x92\x73\xb6\xea\xba\xd7\xc6\x56\x02\xba\xaa"
+  "\x6b\xae\x74\x5b\x75\x25\x75\x22\x95\x5d\xc7\x88\xdb\x2a\xd0\x49"
+  "\x5c\x05\x6a\xad\xf4\xc8\x3d\xb0\x55\xb7\x44\xe7\x6c\xd5\xed\x0c"
+  "\xdf\x56\x42\xfc\xbf\xdb\x79\xe9\xb6\xea\x96\x4e\x6c\xd5\x2d\xd6"
+  "\x81\xad\x9c\xc4\x55\x60\xb6\x15\x6f\xbe\x07\xb6\xfa\xdd\x3e\xe7"
+  "\x6c\xf5\x3b\x93\x8d\xad\x04\x78\x6a\x77\x77\xe9\xb6\xfa\x5d\x01"
+  "\xb1\xd5\xef\xb2\xc4\x6d\x15\xe4\x24\xae\x82\xb4\x56\xfc\xee\x1e"
+  "\xd8\xaa\x7b\x99\x73\xb6\xea\xd1\x8b\x6f\x2b\x21\x3e\xd5\xa3\xbf"
+  "\x74\x5b\x75\xaf\x21\xb6\xea\x5e\xea\xc0\x56\x4e\xe2\x2a\x28\xdb"
+  "\x8a\x87\xdc\x03\x5b\x3d\xee\xe6\x9c\xad\x1e\x9f\x6c\x63\x2b\x81"
+  "\x79\xff\xf1\x99\xd2\x6d\xf5\xb8\x86\xd8\xaa\x87\x51\xcc\x56\xa6"
+  "\x94\xd1\xfe\xde\x60\x83\xfa\xed\xa3\x91\x77\x2c\xa2\x1a\xfc\xc1"
+  "\x6e\x6a\xb0\xdb\x4a\x0d\xf0\x27\xb0\x9b\xc1\x88\xc6\x2d\xba\x48"
+  "\x17\x57\x9b\x50\x03\xd8\xac\x5e\x3d\x5a\x5b\x62\xa8\xc2\x6b\x8e"
+  "\xfe\x58\xa1\xd4\x0c\x9d\xbe\x48\x85\xb0\xdd\xb0\x1d\xb0\xed\x68"
+  "\xb0\x1b\x63\x47\x75\xa4\xd6\xa4\x9e\x3a\x7c\xec\xf5\x8b\xf4\x42"
+  "\x3d\x4d\xe3\xfb\xa5\xd5\x9e\x99\xf8\xb9\xc0\xf8\x2a\xd4\x41\xf3"
+  "\x67\x7c\x4f\x4f\x5c\xc7\xc7\x4b\x0c\x65\xc0\x0f\x6e\x21\x86\x9b"
+  "\x5d\xd4\xaa\x4d\x7f\xd1\x7a\x9a\x4a\x42\x02\xe9\x2e\x5e\x3a\x63"
+  "\x97\x29\xc9\x2b\xae\xa3\x87\x30\x7f\xd8\x62\x46\x7e\xf1\xf3\x11"
+  "\xb5\xff\x2d\x1d\xc5\xbc\xbb\x16\xcd\xb4\x71\x04\xec\xe2\x47\xdf"
+  "\xb6\x5a\xd3\x7d\x3b\x02\x95\x5c\x49\x66\xfc\x66\xcb\x11\x18\xbf"
+  "\xfd\xa4\x55\x01\xcf\xec\x47\xab\x47\x07\x24\x17\x23\x0d\xdd\x08"
+  "\x36\xc6\xef\x13\x29\x35\x7b\x33\x1a\xa4\xda\xf8\x09\x66\xfd\xb7"
+  "\x59\xc3\xae\xdf\x02\x3b\xe1\xdf\x67\xd6\x6f\x45\x59\xad\xdf\x82"
+  "\x3e\x37\xad\xdf\x52\x3e\x11\x84\xd7\x6f\x99\x2f\xfa\x75\xb3\xdc"
+  "\xfb\xc2\x79\x34\x0d\xf7\xde\xb9\xb8\xc6\x80\xf0\xfd\x17\xd7\xe8"
+  "\xd0\x8a\x18\xa4\x2a\x6e\xa8\x42\x09\x35\xb4\xa1\x38\xf1\x2a\x1a"
+  "\x7f\x07\xf3\x60\x8c\x17\xcd\x40\xe2\xd7\x27\x3c\xcc\x17\xb5\xdd"
+  "\xf4\x4a\x4d\x9f\xe2\x52\x84\xac\xde\xe3\x89\x00\xce\xec\x01\x7e"
+  "\x88\x28\x49\xac\x40\xe0\x13\x5d\x89\xf1\x67\xec\xa7\x08\xf8\x7e"
+  "\x48\x13\xbf\xee\x32\xf5\x5b\x7c\x0c\xfb\x0c\x3f\x6f\xc2\xf5\x01"
+  "\x32\xac\xf8\x37\xc6\x85\x77\x6c\x22\x2a\x89\x6d\x40\xc5\x46\x04"
+  "\xfc\xea\xf1\x43\x3f\x84\x94\x89\xe1\x28\x8b\xc5\x51\xa2\x77\xac"
+  "\xfb\x2d\x27\x70\x94\xcd\xe1\xe8\xa9\xb5\xae\xe1\xe8\xa9\x81\xae"
+  "\xe3\xe8\x29\x85\x0b\x38\xca\xe7\xe3\xe8\xa9\xeb\xd2\x71\xf4\x64"
+  "\xa1\x74\x1c\x3d\x99\xec\x1a\x8e\x9e\x8a\x27\x38\x7a\x72\x02\xc1"
+  "\xd1\x53\x31\x1c\x8e\x98\x77\xa3\xee\x11\x8e\x34\x46\x71\x1c\x05"
+  "\xb2\xf1\x28\x10\xe2\x51\xc7\x8a\xe6\x71\x14\x68\x15\x8f\xfc\x8b"
+  "\x5c\xc3\x91\x7f\xbc\xeb\x38\xf2\x0f\x96\x8f\xa3\x40\x9b\x78\xd4"
+  "\x73\xa0\x74\x1c\xf9\xab\xa5\xe3\xe8\xff\xca\x5c\xc3\x91\xff\x49"
+  "\x82\xa3\xff\x4b\x23\x38\xf2\x3f\xca\xe1\x88\x79\xdf\xec\x1e\xe1"
+  "\xe8\xff\x46\x3a\xc0\x11\x1b\x8f\x02\x21\x1e\xf9\xfc\xe8\x04\x8e"
+  "\xac\xe2\xd1\x33\xbe\xae\xe1\xe8\xe9\x93\xae\xe3\xe8\xe9\x6d\x2e"
+  "\xe0\xc8\x26\x1e\x3d\x13\x2f\x1d\x47\x4f\xcf\x90\x8e\xa3\xa7\x35"
+  "\xae\xe1\xe8\x19\x2f\x82\xa3\x9e\x7a\x82\xa3\x67\xdc\x38\x1c\x31"
+  "\xef\xf0\xdd\x23\x1c\xf5\xdc\x24\x8e\xa3\x20\x36\x1e\x05\x41\x3c"
+  "\x1a\xb4\xa1\x79\x1c\x05\x59\xc5\xa3\x5e\x33\x5d\xc3\x51\x2f\x2f"
+  "\xd7\x71\xa4\x3d\x2f\x1f\x47\x41\x36\xf1\xa8\xd7\x49\xe9\x38\xd2"
+  "\x66\x49\xc7\x91\x36\xc2\x35\x1c\xf5\x9a\x4c\x70\xa4\xd5\x12\x1c"
+  "\xf5\x1a\xc3\xe1\x88\x79\x2f\xf2\x1e\xe1\xe8\x99\xb3\x0e\x70\xc4"
+  "\xc6\xa3\x20\x88\x47\xd3\x5f\x72\x02\x47\x56\xf1\xa8\xf7\x5e\xd7"
+  "\x70\xd4\x7b\xb2\xeb\x38\xea\xfd\xa4\x0b\x38\xb2\x89\x47\x7d\xbc"
+  "\xa4\xe3\xe8\xd9\x6a\xe9\x38\x7a\x36\xcf\x35\x1c\xf5\xde\x45\x70"
+  "\xf4\x6c\x14\xc1\x51\xef\x14\x0e\x47\xcc\xbb\xa6\xf7\x08\x47\xcf"
+  "\x76\x17\xc3\x11\xae\x45\xf0\x01\xa9\x0b\x51\xb3\x75\x19\x0a\xc8"
+  "\xc0\xff\x36\xa0\x7e\xb5\x5b\xfa\x8c\xc4\x3b\x52\x31\x35\x10\x94"
+  "\x7d\x98\x7c\xaf\xd0\xf5\x1d\x73\xc0\x2f\xea\xd1\x9a\xf1\x17\x48"
+  "\x8d\x06\x5c\x17\xe4\xf6\x8a\x08\xf4\x3c\xae\xcb\xa0\xec\x1b\x87"
+  "\xeb\x58\x35\xd5\x0e\x50\x8b\xd4\x0e\x98\x26\x5e\x3b\xa0\x61\xbb"
+  "\xe5\xbd\xdb\x6c\xee\xbd\x5b\x65\xdf\x60\x87\xef\xdd\x2a\xfb\xf6"
+  "\xdf\x35\x4d\x2a\x1e\xfa\x30\xef\x7f\xdd\xee\x32\x1a\xd5\x6e\xe9"
+  "\x3b\x1c\xfe\xf6\x23\xf7\xde\x97\xa9\xb7\xd2\xfc\xfb\xb8\xd9\x56"
+  "\x38\xe9\x53\x3d\x79\x06\x4a\xa4\x37\x54\x0f\xa7\x7d\x47\x6b\xe8"
+  "\xd4\xd1\xfd\xa4\xf5\xa5\x6f\x52\x33\xf6\xce\x14\xb6\xf7\x73\xd5"
+  "\xac\xbd\x13\x59\x7b\x0b\xd7\x2d\x98\x26\x5e\xb7\x40\xd8\xde\xcf"
+  "\x39\x7e\xcf\x59\xf9\xdc\x1e\xe9\xf6\x7e\x6e\x1e\x6b\xef\xc4\xda"
+  "\x2d\xcf\xe5\x71\xf6\x7e\xbe\x8f\x74\x7b\x3f\x37\x83\xd8\xfb\xfa"
+  "\x00\xb0\x77\x26\xd8\x3b\x4f\x62\x5f\xea\x1c\xdb\x3b\x50\x04\xdf"
+  "\xfd\x66\x10\x7b\xb3\x35\x13\xd4\x22\x35\x13\xa6\x89\xd7\x4c\x10"
+  "\xb6\x77\xbf\x5e\x8e\xed\xdd\xcf\x47\xba\xbd\x9f\x2f\x27\xf6\x0e"
+  "\x04\x7c\xf7\xd3\x70\xf6\xee\xe7\x64\x5d\x01\x6b\x7b\x3f\x5f\x48"
+  "\xec\x7d\x43\x4b\xfb\x06\x02\xbe\x03\x25\xe2\xbb\x5f\x44\x33\xf6"
+  "\x16\xc1\x77\xff\x42\xd6\xde\x2c\xbe\x45\xea\x35\x4c\x13\xaf\xd7"
+  "\x20\x6c\xef\xfe\x3b\x1c\xdb\xbb\xff\x4a\xe9\xf6\xee\x3f\x86\xb5"
+  "\x37\xe0\xbb\x7f\x32\x67\xef\xdf\x7b\x4a\xb7\x77\xff\x21\xc4\xde"
+  "\xbf\x75\x07\x7b\x03\xbe\x03\x25\xe2\xbb\x7f\x99\x63\x7b\x07\x89"
+  "\xe0\xfb\x85\x21\xc4\xde\x6c\xad\x08\xb5\x48\xad\x88\x69\xe2\xb5"
+  "\x22\x84\xed\xfd\x42\x07\xc7\xf6\xfe\xfd\x4d\xe9\xf6\xfe\xfd\x51"
+  "\x62\xef\x20\xc0\xf7\x0b\x88\xb3\xf7\x0b\x71\xd2\xed\xfd\xfb\x7d"
+  "\xc4\xde\x06\x15\xed\x1b\x04\xf8\x0e\x92\x88\xef\x17\x82\x9a\xb1"
+  "\xb7\x08\xbe\x07\xec\x63\xed\xcd\xe2\x5b\xa4\x4e\xc5\x34\xf1\x3a"
+  "\x15\xc2\xf6\x1e\xb0\xd4\xb1\xbd\x07\xcc\x91\x6e\xef\x01\x7d\x58"
+  "\x7b\x03\xbe\x07\x44\x71\xf6\x1e\x50\x2d\xdd\xde\x03\xba\x13\x7b"
+  "\xdf\x74\x03\x7b\x03\xbe\x83\x24\xe2\x7b\x40\xbe\x98\xbd\xbd\xc1"
+  "\xde\x27\x01\x01\x30\x0f\x6a\xcd\x29\xc0\x53\x4c\x7c\xbb\x97\xc4"
+  "\x06\xa0\xe7\xee\x62\xdb\x0f\x4a\x83\xb9\x43\xdb\x6a\xf5\x32\x94"
+  "\x83\x56\xba\xfc\xee\xb0\x72\xd0\x58\xd1\x77\x87\x95\x83\x06\x4a"
+  "\x7e\x77\x58\x39\x08\x71\x1c\x68\xd0\x48\xce\xa7\x83\x98\xf8\x21"
+  "\xe9\x9d\x62\xe5\x40\x83\x60\x1d\x0d\xe5\xc0\x4c\xfc\x4e\x31\xf8"
+  "\xba\xce\x9c\x2a\x87\x1b\x0d\xca\x72\xc2\xd7\xd9\xe0\x87\x4c\x71"
+  "\x5f\x07\xac\x01\x5f\x67\xb7\x5a\xdd\x0e\x65\xc0\x7c\xd7\x7d\x1d"
+  "\x30\x58\xdc\xd7\x01\x4f\x4a\xf7\xf5\x1f\xaa\x39\xfe\x15\xd0\x8f"
+  "\xf3\x75\x80\xf4\xf7\xc7\x95\x7f\x28\x17\xac\xe7\xa1\xfc\xc3\x26"
+  "\xe2\xeb\xdb\x33\xc0\xd7\x32\x78\x59\x40\x72\xf3\xbe\x0e\x84\x71"
+  "\x1d\xe8\x60\x5c\xbf\x18\x05\x73\xa6\xb6\xd5\xea\x87\x28\x5f\x9c"
+  "\xea\xba\xaf\x5f\xec\x29\xee\xeb\x17\xbd\xa4\xfb\x7a\x70\x19\xc7"
+  "\xfd\x5e\xec\xce\xf9\xfa\xc5\x3c\xe9\xbe\x1e\x5c\x20\x58\x57\x44"
+  "\x39\x38\x96\xf8\xba\x46\x67\x4e\x95\xc3\x09\x5f\x8c\x73\xc2\xd7"
+  "\x30\xae\x03\x1d\x8c\xeb\x21\x33\xc0\xd7\xd9\xad\x56\xc7\x44\x39"
+  "\x64\x94\xeb\xbe\x1e\xe2\x23\xee\xeb\x3f\xd6\x4b\xf7\xf5\x1f\x4f"
+  "\x70\xbc\x73\x88\x07\xe7\xeb\x21\xe9\xd2\x7d\xfd\xc7\x43\x82\xf5"
+  "\x4d\x94\x7f\x0c\x23\xbe\xbe\xeb\x0f\xbe\x96\xc1\x47\x87\x88\xf2"
+  "\x7f\xce\xd7\x41\x30\xae\x83\x1c\x8c\xeb\x3f\x05\x01\x57\xd0\xb6"
+  "\x5a\x3d\x15\xe5\x9f\xfa\xbb\xee\xeb\xa1\x26\x71\x5f\x0f\xbd\x2c"
+  "\xdd\xd7\x43\xf3\x38\xce\x3b\xb4\x86\xf3\xf5\x9f\x92\xa4\xfb\x7a"
+  "\x68\xa6\x60\x9d\x15\xe5\xd0\x09\xc4\xd7\xb5\x49\xe6\x54\x39\x5c"
+  "\xf8\x4f\x93\x9c\xf0\x35\x8c\xeb\x20\x07\xe3\x7a\x38\xe8\xfa\xa0"
+  "\xec\x56\xab\xeb\xa2\x1c\xde\xc3\x75\x5f\x0f\xbb\x2a\xee\xeb\x61"
+  "\x67\xa4\xfb\x7a\x58\x3a\xc7\xb7\x87\xe9\x39\x5f\x0f\x8f\x91\xee"
+  "\xeb\x61\x9b\x04\xeb\xbd\x28\x87\x0d\x21\xbe\xae\xab\x06\x5f\xcb"
+  "\xe0\xe1\xc3\x87\xcb\xe1\xe1\xef\xec\x42\x1e\x7c\x7f\xbf\xe4\xdf"
+  "\xba\x5c\xfc\x25\x2f\xd7\xfd\x3d\xe2\xbc\xb8\xbf\x47\x1c\x97\xee"
+  "\xef\x11\x9b\x38\x2e\x3e\xa2\x94\xf3\xf7\x4b\x61\xd2\xfd\x3d\x22"
+  "\x4e\x98\x8b\x8f\xe8\xe3\x1a\x17\x7f\xa9\x9f\x1c\x2e\x6e\xef\xef"
+  "\x91\xea\xd6\xe5\xe3\x2f\x9b\x5c\xf7\xf7\xcb\xa7\xc4\xfd\xfd\xf2"
+  "\x41\xe9\xfe\x7e\x39\x8e\xe3\xe3\x2f\xeb\x38\x7f\x8f\x9c\x24\xdd"
+  "\xdf\x2f\xcf\x13\xe6\xe3\x2f\x77\x77\x8d\x8f\x8f\xd4\xc8\xe1\xe3"
+  "\xf6\xfe\x1e\xed\xd6\xba\x9c\x7c\xd4\x75\xd7\xfd\x3d\xea\x88\xb8"
+  "\xbf\x47\xed\x91\xee\xef\x51\xf3\x38\x4e\x3e\xca\x2a\xff\x3d\x7a"
+  "\xa4\x74\x7f\x8f\x9a\x21\xcc\xc9\x47\x79\xba\xc6\xc9\x47\xab\xe4"
+  "\x70\x72\x7b\x7f\x07\xd6\xb4\x2e\x2f\x0f\xbc\xe0\xba\xbf\x03\x73"
+  "\xc4\xfd\x1d\xb8\x4d\xba\xbf\x03\x67\x70\xbc\x3c\x30\x93\xf3\x77"
+  "\x90\xf4\xfa\x99\xca\xc0\x31\xc2\xbc\x7c\xb4\xd1\x35\x5e\x1e\x84"
+  "\xe4\xf0\x72\x7b\x7f\x07\x57\xb6\x2e\x37\x0f\x2e\x72\xdd\xdf\xc1"
+  "\x3b\xc4\xfd\x1d\xbc\x52\xba\xbf\x83\xc7\x70\xdc\x3c\xd8\x2a\xff"
+  "\xff\x8a\xbf\x74\x7f\x07\x0f\x11\xe6\xe6\x41\xd5\xae\x71\xf3\x60"
+  "\x83\x1c\x6e\x6e\xef\xef\x57\xcf\xb6\x2e\x3f\x7f\xf5\x98\xeb\xfe"
+  "\x7e\x75\xbd\xb8\xbf\x5f\x5d\x24\xdd\xdf\xaf\x0e\xe1\xf8\xf9\xab"
+  "\x89\x9c\xbf\xc7\xa8\xa5\xfb\xfb\xd5\x3e\xc2\xfc\xfc\x95\x72\xd7"
+  "\xf8\xf9\xab\x7a\xd7\xf3\xe4\xe3\xf2\x30\x37\x97\x5a\xff\xb1\x24"
+  "\xc6\xf2\xce\xdd\x18\xae\xfe\xa3\x72\xdc\x1e\x24\x5a\x5b\x66\xac"
+  "\xa9\x4d\xd7\x7f\x54\x8e\x75\x5c\xff\x51\x39\x56\x5a\xfd\x47\xe5"
+  "\xd8\xcb\xd2\xd7\xe3\x8f\xcd\xe3\x34\xc2\x58\x2b\xfd\x3f\x8e\xec"
+  "\x51\xdc\x96\xeb\x42\x2a\xc7\xf2\xeb\x42\x2a\xc7\x30\x75\x21\xe9"
+  "\x0d\x0d\x13\xe4\x69\x91\x71\x47\x5d\x7f\x2e\x30\x71\x13\xd6\x21"
+  "\x52\xeb\x50\x72\xd8\x1e\xbf\x9e\xc3\xf6\xc4\x78\x71\x6c\x4f\x38"
+  "\xdf\xa6\xeb\x50\x2a\x27\xcc\x74\x8c\xed\x09\x43\xa4\xd5\x1c\x99"
+  "\x20\xa3\xee\xcd\x84\x4d\x9c\x1e\x9a\x60\xa5\x7f\x27\x16\xb6\x22"
+  "\xb6\x65\xd6\x53\x9a\x10\xc5\xc7\xf6\xf8\x44\x82\x6d\x63\x96\x3c"
+  "\xdd\x35\x31\xcd\xf5\xe7\x20\x93\x22\xb0\xe6\x92\x5a\x0f\x93\xc3"
+  "\xf6\x9f\xc3\x39\x6c\x4f\x9a\x2a\x8e\xed\xd7\x0e\xb7\xed\x7a\x98"
+  "\xaf\x0d\x76\x8c\xed\xd7\xfc\xa4\xd5\x32\x79\x6d\x97\x74\x6c\xbf"
+  "\x16\xc1\x69\xbf\xd7\xf6\x71\xd8\x9e\x94\xdd\x7a\xd8\x96\x5b\x27"
+  "\xf3\xb5\x31\x7c\x6c\xff\x79\x06\xc1\xb6\xb9\x4e\x9e\xc6\x9c\x14"
+  "\xe3\xfa\x73\x9f\xbf\x8c\xc4\xfa\x52\x6a\x5d\x4e\x0e\xdb\x93\x47"
+  "\x70\xd8\xfe\x8b\x5d\x5d\x28\x0e\xdb\x53\xb6\xb5\xed\xba\x9c\x53"
+  "\x7c\x1d\x63\x7b\x72\x8d\xb4\x1a\x29\x53\x96\x4a\xc7\xf6\x94\x91"
+  "\x9c\xce\x9d\x92\xc4\x61\xfb\x2f\x6b\x5a\x11\xdb\x32\xe3\xf6\x14"
+  "\x2d\x1f\xdb\x93\x03\x18\x6c\x6f\x51\x8c\x91\xa7\xa7\xff\x32\xc1"
+  "\xf5\xe7\x5c\xd3\x34\x58\x4b\x4b\xad\x0f\xca\x61\x3b\xa4\x07\x87"
+  "\xed\x69\x3e\xe2\xd8\x9e\x3a\xbf\x6d\xd7\x07\x0d\x69\xa6\xfe\x4f"
+  "\x88\x83\xfa\x3f\x42\xef\x0a\x4f\x95\x51\xf7\x62\xaa\x86\xd3\xf4"
+  "\x53\xc3\x38\x6c\x4f\x0b\x6d\x3d\x6c\xcb\xad\x1b\x3a\xd5\x8d\x8f"
+  "\xed\x10\x35\xc1\xb6\x32\x53\x5e\xee\x60\x5a\x1f\xd7\x9f\xeb\xcd"
+  "\x30\xe2\xbc\x81\xd4\x3a\xa5\x1c\xb6\xa7\xd5\x73\xd8\x9e\x71\x5d"
+  "\x1c\xdb\x33\x82\xdb\x76\x9d\xd2\xe9\x45\x8e\xb1\x3d\x7d\x9f\xb4"
+  "\x9a\x2e\x33\x64\xbc\x07\x3f\xdd\xc8\xe5\x2f\x66\x58\xad\x7f\x9f"
+  "\x39\xa4\x15\xb1\x2d\x33\x6e\x4f\xd7\xf3\xb1\x3d\xcd\x40\xb0\xed"
+  "\x5e\x23\x2f\x4f\x32\xd3\xc3\xf5\x3c\x49\xa8\x07\xf3\x0c\x53\x62"
+  "\xbd\x54\x0e\xdb\x33\xcf\x71\xb5\x89\x66\xd7\xdb\x62\x9b\xab\x4d"
+  "\x34\xdb\xa7\xed\xd4\x4b\x9d\x95\xea\x18\xc7\xb3\x62\xa4\xe5\x44"
+  "\x66\xd5\x4b\xc7\xf1\xac\x13\x5c\x4e\x64\xb6\xd5\xfa\x97\x50\xcb"
+  "\x9e\xe4\xad\x50\xb3\x68\xf6\x2e\xc7\x35\x8b\x66\xc7\xdd\xbb\x3a"
+  "\xaa\xb3\xb2\xf9\x35\x8b\x66\x16\x9a\x99\xb1\xe0\x11\x24\x2f\xaf"
+  "\x12\xaa\x76\x3d\xaf\xf2\x3a\x79\xbe\x2b\xb1\x6e\x2b\x37\x16\x42"
+  "\x2f\x71\x63\xe1\x75\x77\xf1\xb1\x30\xb7\x47\xdb\xa9\xdb\x3a\x67"
+  "\x8f\xe3\xb1\x30\x27\x51\x5a\x0e\x65\xae\x8c\x3a\x30\x73\x4a\xb9"
+  "\x1c\xca\x5c\x35\x37\x16\x5e\x9f\xd4\x7a\x63\x61\x6e\x8e\xe3\xb1"
+  "\x30\x37\xe9\xde\xd5\x73\x9d\x73\x88\x3f\x16\x42\xcb\xc8\x58\x78"
+  "\xa4\x50\x5e\x1e\xe6\x75\x59\xcf\xbf\xf9\x63\xe1\x0d\x0d\xf3\xec"
+  "\x5b\x62\xfd\x58\x6e\x2c\xbc\x7e\x9d\x1b\x0b\x6f\xd8\xf1\x79\x6e"
+  "\x2c\x84\xf7\x6a\x3b\xf5\x63\xc3\x72\x1d\x8f\x85\xb0\x4d\xd2\x72"
+  "\x2e\xe1\x3e\xd2\xc7\x42\x98\xd5\xfb\x4f\xe1\x56\xef\x3f\xbd\x11"
+  "\xda\x7a\x63\x21\xfc\xb0\xe3\xb1\x10\x9e\x72\xef\xea\xca\x86\xe9"
+  "\xf8\x63\xe1\xf5\x4a\x32\x16\xbc\x26\xc8\xcb\xdb\xbc\xe1\x04\xff"
+  "\x6f\x2e\x6f\x13\xd9\x87\x59\x17\x20\xb1\x8e\x2d\x37\x16\xde\xa8"
+  "\xe7\xc6\x42\x64\x0f\xf1\xb1\x10\x31\xb0\xed\xd4\xb1\x7d\xf3\x88"
+  "\xe3\xb1\xf0\x66\x9a\xb4\x1c\x4d\x44\x0f\xe9\x63\xe1\xcd\x2a\x2e"
+  "\x47\x13\xd1\x87\x1b\x0b\x91\xf3\x5a\x6f\x2c\x44\x1c\x77\x3c\x16"
+  "\x22\x32\xef\x5d\x7d\xdb\x37\x0b\xf9\x63\xe1\x0d\x03\x19\x0b\xde"
+  "\x67\xe5\xe5\x79\x22\x03\x5c\xcf\xf3\xcc\x0b\x60\xd6\x4c\x48\xac"
+  "\xa7\xcb\x8d\x85\xb7\xdc\xb9\xb1\x30\xaf\x97\xf8\x58\x78\x7b\x44"
+  "\xdb\xa9\xa7\xfb\xd6\x49\xc7\x63\xe1\xad\x2c\x69\x39\x9d\xb7\x7b"
+  "\x49\x1f\x0b\x6f\xd5\x70\x39\x9d\xb7\x03\xb8\xb1\x30\x2f\xb6\xf5"
+  "\xc6\xc2\xdb\x45\x8e\xc7\xc2\xdb\xfb\xee\x5d\x9d\xdd\xb7\xca\xf8"
+  "\x63\x21\xd2\x48\xc6\x42\xe7\x10\x79\x79\xa1\x79\x23\x5d\xcf\x0b"
+  "\x2d\x1c\xc9\xac\x27\x91\x58\xd7\x97\x1b\x0b\xf3\x7d\xb8\xb1\xb0"
+  "\xd0\xc1\x3e\x0f\x0b\xc6\xb6\x9d\xba\xbe\xf3\x9b\xd9\xff\x68\xbe"
+  "\xa3\xfd\x8f\x04\x72\x40\x0b\x06\x4a\x1f\x0b\x0b\x10\x97\x03\x5a"
+  "\x60\xf5\xfe\xdf\xc2\x35\xad\x37\x16\x16\x34\xb3\xff\xc3\x02\x27"
+  "\xf6\x7f\x90\x5b\xef\x77\x7e\x25\x7f\x2c\xcc\xf7\x20\x63\x41\x5d"
+  "\x2e\x2f\x8f\xb4\xb0\xd9\xfc\x3f\xd6\xf9\x8d\x6a\xfb\x3c\x52\x61"
+  "\x65\x00\xea\x3d\x0d\x8f\x85\xa8\x3a\x63\xea\x68\x2d\xae\x2f\x6c"
+  "\xf2\x67\x6b\x50\xae\x64\x6b\xbc\xd4\x18\x49\x0d\x4a\x83\xa9\xa9"
+  "\x06\x25\xa9\xfd\x81\x28\xfc\x2e\x30\x7e\x27\xd8\xa8\x22\xf5\x27"
+  "\x69\xbc\x26\x0a\xaf\x91\xaa\x28\x60\xea\xab\xc4\x19\xe1\xde\xaf"
+  "\x34\x53\x7f\x32\x54\x8f\x0a\x43\x97\x21\xa3\xcf\xd1\x64\xf2\x9e"
+  "\x70\x54\x12\x53\x7f\x72\xb6\x5f\xb7\x2d\xff\x41\x6a\x6f\x5c\x7f"
+  "\x32\x94\x36\xaf\xd0\xd3\x86\xe2\x3a\x04\xe7\x82\x7d\xe7\x58\x6a"
+  "\x50\x46\xdd\xc4\xf7\x6e\x9c\xad\xed\xb6\xfb\x3f\x62\xf5\x85\xa3"
+  "\x64\xd4\x81\x8d\xca\xe2\xf2\x3b\x51\x55\x1c\x46\x17\x31\x73\x30"
+  "\x7c\x9f\x58\x18\x02\x31\x66\xcb\x63\xa1\x8d\xb2\x6a\x6f\x2c\x72"
+  "\x73\xc2\x67\x78\x8d\x88\x5d\xfc\xe2\x7c\x16\xbd\x0f\x7c\x96\x8d"
+  "\xeb\x1c\x3b\xef\x33\xf7\x5b\xf7\xc6\x67\xd1\x43\x9c\xf7\x59\xf4"
+  "\x5e\x1b\x9f\x09\xe4\x21\xa2\x37\x4b\xf7\x59\x74\x08\x97\x87\x88"
+  "\x4e\xe7\x7c\x16\x5d\x4d\x7c\x16\x3d\x80\xf8\xcc\x6f\x53\xa3\xac"
+  "\xfa\x1d\xd1\xcd\xbe\xff\x8d\x75\x53\xa3\xda\x5e\x97\x73\x3e\x8b"
+  "\x09\x35\xa6\x82\x76\x07\x5d\xee\xbc\xcf\x3a\x56\xdc\x1b\x9f\xbd"
+  "\x63\x70\xde\x67\x31\x53\xf9\x3e\x13\xd2\xcb\x31\x32\xf6\xec\x8c"
+  "\xf1\xe4\xf4\x72\xcc\x04\xce\x67\x31\x99\xc4\x67\xef\x54\x11\x9f"
+  "\x75\xcd\x6f\x94\x55\x03\x24\x66\x9e\x13\x3e\xc3\xcf\xf4\x1d\x8c"
+  "\xb3\x25\x6a\xf0\x59\x36\xae\xfb\xec\xbc\xcf\x7c\x7e\xbc\x37\x3e"
+  "\x5b\x9c\xe5\xbc\xcf\x96\x78\xd9\xf8\x4c\x40\xd7\x2d\xbe\x23\xdd"
+  "\x67\x8b\x75\x9c\xae\x5b\xe2\xc6\xf9\x6c\xc9\x24\xe2\xb3\xc5\xe9"
+  "\xc4\x67\xdd\x2a\x1b\x65\xd5\x11\x59\xd2\x6c\xfe\x0b\xf3\xd0\x46"
+  "\xb5\xbd\xce\xe1\x7c\xf6\x6e\x81\x31\x15\xb4\x10\xe8\x1c\xe7\x7d"
+  "\x36\x68\xc3\xbd\xf1\xd9\xbb\x21\xce\xfb\xec\xdd\xe3\x7c\x9f\x09"
+  "\xe9\x8f\x77\x73\xa4\xfb\xec\xdd\x18\x4e\x7f\xbc\x9b\xcf\xf9\x2c"
+  "\xd6\x83\xf8\xec\xdd\x09\xc4\x67\xdd\x55\x8d\xb2\x6a\x91\xbc\x7b"
+  "\xd6\x09\x9f\xe1\x67\xb0\x0e\xc6\xd9\xd2\x38\xf0\x59\x36\xae\x83"
+  "\xed\xbc\xcf\xa6\xbf\x74\x6f\x7c\xb6\xd4\xd3\x79\x9f\x2d\x5d\x6c"
+  "\xe3\x33\x01\x9e\xbc\x54\x46\x1d\xec\xa5\x5a\x8e\x27\x2f\x9d\xc7"
+  "\xf9\x6c\xe9\x51\xe2\xb3\xa5\x6e\xc4\x67\x3d\x86\x34\xca\xaa\x67"
+  "\xb2\x54\xb4\xfe\x97\x23\xde\x68\x59\x97\xcf\xf9\x6d\xf9\x80\xb6"
+  "\xc3\x1d\x97\x9d\x70\xde\x6f\xcb\xfb\x36\xcf\x1d\x97\xfb\x4a\xf7"
+  "\xdb\x32\x3d\xc7\x1d\x97\xfb\x73\x7e\x5b\x1e\x43\xfc\xb6\xec\xa8"
+  "\x6b\xdc\x71\xf9\x70\x39\xdc\xd1\xde\x6f\x71\xd5\x6d\x87\x3f\xc6"
+  "\xc5\x39\xef\xb7\xb8\xcb\xcd\xf3\xc7\xb8\x22\xe9\x7e\x8b\x4b\xe3"
+  "\xf8\x63\x5c\x39\xe7\xb7\xf8\x3e\xc4\x6f\x71\x31\xae\xf1\xc7\x38"
+  "\xd1\xfa\x6f\x8e\xf8\xa3\xbd\xdf\x12\xb2\xda\x0e\x87\x4c\x18\xe0"
+  "\xbc\xdf\x12\x76\x35\xcf\x21\x13\xd6\x4a\xf7\x5b\xc2\x04\x8e\x43"
+  "\x26\xa4\x70\x7e\x4b\xa8\x24\x7e\x4b\xe8\xe3\x1a\x87\x4c\xc8\x93"
+  "\xc3\x21\xed\xfd\x96\x38\xa3\xed\xf0\xc8\x15\xd5\xce\xfb\x2d\x71"
+  "\x72\xf3\x3c\x32\x51\xc6\x9e\xc5\x89\x1e\x1c\x8f\x4c\x1c\xc3\xf9"
+  "\x2d\x91\xdd\x83\x65\x45\xa5\x6b\x3c\x32\xb1\xd9\xfa\x1f\x42\x3c"
+  "\xd2\xde\x6f\xab\xd4\x6d\x87\x4b\xae\x94\xc0\xff\x57\x79\x35\xcf"
+  "\x25\x57\xca\xe0\xff\x2b\x75\x1c\x97\x5c\x65\xc5\xff\x57\xb1\xfc"
+  "\x7f\x65\xba\x6b\x5c\x72\x95\x33\xfc\xdf\x8e\x4b\xda\xfb\x6d\x75"
+  "\x61\xdb\xe1\x93\xab\x67\x38\xef\xb7\xd5\x27\x9b\xe7\x93\xab\x65"
+  "\xec\x03\xb5\x3a\x96\xe3\x93\xab\x8f\x72\x7e\x5b\xe3\x49\xfc\xb6"
+  "\x7a\x92\x6b\x7c\x72\xb5\x68\xfd\x47\x8b\xdf\x4c\xea\xd1\x5a\x5a"
+  "\x20\x0f\x59\x14\x11\xc0\xd6\x26\x5c\x97\x6e\xf2\x1d\xad\x95\xba"
+  "\xbf\x8b\xa5\xe6\xf4\x29\x18\xf1\x15\xca\x75\x03\x5d\xab\x3b\xbd"
+  "\xf6\xb2\xeb\x75\xa7\xd7\x1e\x6c\xb9\xfd\x5d\xd6\xee\x90\x5e\x77"
+  "\x7a\x6d\x18\xc7\x41\xd7\x66\x73\xbe\x5e\xc7\xac\x4f\x90\x56\x8f"
+  "\x7a\xad\xd6\xb5\x7a\xd4\xeb\xfa\x12\x7c\xad\xa9\x22\xf5\xa8\xd7"
+  "\xf9\xb7\xce\xbe\x2f\x6b\x52\x70\x3d\x6a\x7a\xcb\xe3\x11\xf2\xea"
+  "\x23\xaf\xcb\x76\x02\xcf\xd9\xb4\x40\x8e\x96\xc3\xf3\xfa\x79\x80"
+  "\xe7\x6c\xa9\xfb\xcc\xf0\xf1\xbc\xde\xdd\x35\x3c\x27\x1d\x76\x1d"
+  "\xcf\x49\x2b\x5b\x6e\x9f\x99\xa4\x48\xe9\x78\x4e\x1a\xc0\x71\xf3"
+  "\xa4\x58\x0e\xcf\xeb\xf7\x49\xc7\xf3\x7b\x75\xae\xe1\x39\xc9\x44"
+  "\xf0\xfc\x5e\x3e\xc1\x73\x52\x4d\xeb\xec\x3f\xf3\x5e\x18\xc1\xb3"
+  "\x26\x4f\x5e\xfd\xe9\xf5\xb1\xcd\xe3\x39\x50\x4b\x0b\xe4\xaf\x39"
+  "\x3c\x6f\x1a\x62\xf2\x0d\xd4\x4a\xdd\xef\x86\x8f\xe7\x8d\xe7\x5c"
+  "\xc3\xf3\xc6\xb5\xae\xe3\x79\xe3\xc4\x96\xdb\xef\x66\xe3\x60\xe9"
+  "\x78\xde\xe8\xc6\x69\x96\x8d\x41\x1c\x9e\x37\xc5\x49\xc7\xf3\x86"
+  "\x02\xd7\xf0\xbc\xb1\x88\xe0\x79\x43\x12\xc1\xf3\xc6\x13\xad\xb3"
+  "\x0f\xce\x86\x01\x04\xcf\x4f\xd5\xc9\xab\xef\xbd\x49\xb4\xfe\xb1"
+  "\x15\x9e\xb3\x69\x81\xdc\x3e\x87\xe7\xad\x9e\x80\xe7\x6c\xa9\xfb"
+  "\xee\xf0\xf1\xbc\xc5\xc5\x7d\x2e\xb6\xb4\xc0\x3e\x17\x5b\x5c\xd8"
+  "\xe7\xc2\x76\xdf\x9d\x2d\x1d\xa4\xe3\x79\xf3\x59\x4e\xcb\x6d\xf1"
+  "\xe3\xf0\xbc\x75\x8c\x74\x3c\x6f\x4e\x73\x0d\xcf\x5b\xd8\xfd\x2f"
+  "\x36\x87\x10\x3c\x6f\x49\x69\x9d\xfd\x78\x36\xbb\x11\x3c\xf7\x1c"
+  "\x2e\xaf\x7e\xfa\x56\xbf\xe6\xf1\x1c\xa4\xa5\x05\x9e\x7b\x70\x78"
+  "\xde\x56\x6e\xf2\x0d\xd2\x4a\xdd\xff\x87\x8f\xe7\x6d\x8b\x5d\xc3"
+  "\xf3\xb6\x9e\xae\xe3\x39\xf9\x66\xcb\xed\xff\x93\x7c\x5e\x3a\x9e"
+  "\x93\xb3\x38\x8d\x9b\x6c\xf5\xfc\xff\xfd\xee\xd2\xf1\x9c\xec\xe2"
+  "\xbe\x40\xdb\xe6\x13\x3c\x27\xb3\xfb\x02\x6d\x0b\x6b\x9d\x7d\x81"
+  "\xb6\x9e\x25\x78\x7e\x26\x49\x5e\x7d\xfa\x6d\x55\x4e\xe0\x39\x9b"
+  "\x16\x78\x26\xc4\xe1\x39\x65\x1f\xe0\x39\x5b\xea\x3e\x44\x7c\x3c"
+  "\xa7\x8c\x72\x0d\xcf\x1f\xdc\x71\x1d\xcf\x1f\x1c\x6f\xb9\x7d\x88"
+  "\x3e\xc8\x91\x8e\xe7\x0f\x2c\xcf\xff\x20\x3e\x7f\x60\xf5\xfc\x2f"
+  "\x45\xc6\xfe\x44\x1f\x04\xb8\x86\xe7\x94\xa1\x04\xcf\xef\xd7\x11"
+  "\x3c\xa7\x0c\x68\x9d\xfd\x89\xde\xcf\x22\x78\xee\x55\x2a\xaf\xfe"
+  "\x7f\x4a\xb3\xeb\x3f\x84\xf2\x1b\x96\xbc\x14\x87\xe9\x0f\x13\x5d"
+  "\xcf\x71\x7c\xd8\xd5\x35\x4c\x6f\x3f\xe5\x3a\xa6\xb7\xa7\xb6\x5c"
+  "\x8e\x63\xbb\x8c\xbd\xfe\xb6\x07\x71\x39\x8e\xed\x9b\x38\x4c\x7f"
+  "\xa8\x93\x8e\xe9\xed\x9e\xae\x61\xfa\x43\x1f\x82\xe9\xd4\x42\x82"
+  "\xe9\x0f\x3d\x5a\x27\xc7\x91\x1a\xeb\x5a\x8e\xe3\xc3\x4d\x72\x72"
+  "\x1c\xf6\x98\xde\x39\xc9\xf5\x3c\xc7\x8e\xeb\xae\x61\x7a\xc7\x2e"
+  "\xd7\x31\xbd\x23\xb2\xe5\xf2\x1c\x3b\x26\x4a\xc7\xf4\x8e\xee\x5c"
+  "\x9e\x63\x47\x28\x87\xe9\x9d\x29\xd2\x31\x9d\xa6\x77\x0d\xd3\x3b"
+  "\x2e\x13\x4c\xa7\x65\x12\x4c\xef\x28\x6f\x9d\x3c\x47\xda\x18\xd7"
+  "\xf2\x1c\x3b\x43\xe5\xe4\x39\xec\x31\xbd\x4b\xeb\x7a\xae\x23\xfd"
+  "\xb8\x6b\x98\x4e\x5f\xe4\x3a\xa6\xd3\x87\xb6\x5c\xae\x23\xbd\xa7"
+  "\x74\x4c\x7f\x64\xe0\x72\x1d\xe9\x03\x38\x4c\xef\x8a\x90\x8e\xe9"
+  "\x8f\x0e\xb9\x86\xe9\xf4\x23\x04\xd3\x1f\xc5\x10\x4c\xa7\xe7\xb5"
+  "\x4e\xae\xe3\x23\x8d\x6b\xb9\x8e\x5d\x03\xe4\xe4\x3a\xec\x31\x9d"
+  "\x61\x74\x3d\xdf\x91\x91\xea\x1a\xa6\x33\x46\xb9\x8e\xe9\x0c\x9f"
+  "\x96\xcb\x77\xec\xae\x97\x8e\xe9\xdd\x56\xfb\x5f\x64\x58\xbd\xff"
+  "\x9f\x39\x44\x3a\xa6\x77\x27\xb9\x86\xe9\x8c\xcd\x04\xd3\xbb\x83"
+  "\x08\xa6\x33\xd6\xb4\x4e\xbe\x63\x57\x8d\x6b\xf9\x8e\xcc\x66\xeb"
+  "\x5f\x08\xe5\x3b\xec\x31\xfd\x71\xa9\xeb\x39\x8f\x8f\x23\x5d\xc3"
+  "\xf4\xc7\x5d\x5d\xc7\xf4\x9e\xcb\x2d\x97\xf3\xd8\x53\x24\x1d\xd3"
+  "\x7b\xd2\xb8\x9c\xc7\x1e\xab\xf5\x4f\x9f\xa8\xa4\x63\x7a\xcf\x0c"
+  "\xd7\x30\xfd\xf1\x1c\x82\xe9\x3d\xdd\x09\xa6\x3f\x0e\x69\x9d\x9c"
+  "\x47\x66\x81\x6b\x39\x8f\x8f\xcb\xe5\xe4\x3c\xec\x31\xbd\x37\xcb"
+  "\xf5\xbc\xc7\xde\xa1\xae\x61\x3a\xeb\xba\xeb\x98\xce\x3a\xd2\x72"
+  "\x79\x8f\xac\x3d\xd2\x31\x9d\x35\x8f\xcb\x7b\x64\x59\xd5\xbf\xdf"
+  "\x5b\x29\x1d\xd3\x59\xfd\x5c\xc3\xf4\xde\x81\x04\xd3\x9f\x18\x08"
+  "\xa6\xf7\xf6\x69\x9d\xbc\xc7\x27\xe9\xae\xe5\x3d\xf6\xda\xad\x7f"
+  "\x7b\x27\x7c\x41\x98\x66\xe1\x1b\x6f\xbc\x13\x1e\xa3\x79\x67\x5e"
+  "\xe4\xeb\xe1\x43\x7b\x5a\xfe\x1e\xda\x2f\xb6\x67\xec\x23\x28\x6c"
+  "\xfe\x9c\xd9\x4b\x7e\xcf\x7d\x39\x2f\x7c\x01\xfc\xf3\x08\x8a\x98"
+  "\xf3\x4e\x84\x26\x66\x69\x54\xb8\x06\xff\x35\xff\xf5\x28\x38\x65"
+  "\x61\x0c\x77\xe4\xcf\xe1\xf3\xe6\xc4\x46\x2e\x78\x53\x33\x67\x5e"
+  "\xe4\x9b\x0b\xe6\x87\x2f\x88\xd1\x44\x87\x2f\x5a\x1c\x19\x1d\x8e"
+  "\xff\xff\x8e\xe6\x8d\x85\xd1\x70\xe0\xf5\xf0\xc8\x25\xe1\x9a\xb9"
+  "\x8b\xdf\x78\x23\x3c\xfa\x9d\x47\xd0\xd8\xc5\xf3\x62\x22\xa3\xe6"
+  "\x85\x6b\x46\x8e\x1d\xd1\x77\xd2\xa8\xd7\x26\x0d\x1b\xf6\x08\xb2"
+  "\xda\x7b\x5a\x43\xa7\x44\x6a\x00\x43\x6e\x57\x94\x7f\x1b\x5a\xec"
+  "\x87\xd0\x66\xc0\xe6\xd6\x68\xa4\x5a\x1f\x8d\xdc\x92\x6e\x21\x8f"
+  "\xcd\xb7\x90\xa7\xe6\x2d\x34\x9c\xf6\x59\xad\xdb\x7a\x0b\xa9\xe9"
+  "\x2e\x9e\xd9\xf4\xb6\xaf\x4a\x69\x9f\xa3\x2a\x83\x4f\x16\x3e\xa6"
+  "\xa2\xb7\x7d\x52\x87\xbf\x03\x5f\xb8\xd1\xdb\x8e\xc6\x56\x28\x0f"
+  "\x1a\x0d\x3e\x7b\x33\x57\x5c\x45\x14\xdd\xe9\xaf\xaa\xfd\x66\x03"
+  "\x75\x1c\x67\xd9\xc0\x56\x48\x99\xad\x85\x8f\x1a\x3e\x27\xe0\x73"
+  "\x16\x29\x73\xba\xc3\x67\x24\x7c\xc6\xc0\x27\x1f\x29\x3f\x43\xf0"
+  "\xe9\x07\x1f\x38\xf6\x59\x08\x7c\xc2\xe0\x33\x0f\x3e\x65\xf0\xa9"
+  "\x43\xca\xcf\x3d\xe0\xa3\x21\xed\x7c\x8e\x3f\xd9\xf0\x31\x20\xe5"
+  "\x3e\x7f\xa4\xcc\x85\xe3\xb9\xd0\x4e\x2e\x9c\x97\x0b\xd7\xe4\x26"
+  "\xc1\x27\x19\x3e\x87\xe0\x03\xd7\x7f\xde\x87\x7c\xb7\x3f\x0b\x3e"
+  "\x7a\xa4\x3c\x00\xbf\x75\x00\x7e\xff\xc0\x04\xf8\xc0\xef\x1c\x88"
+  "\x82\x4f\x2c\x7c\xd2\xe1\x03\xe7\x1c\x80\xfe\xe4\xc1\x35\x79\x03"
+  "\xe0\x03\x7d\xc9\xcb\x43\xca\x83\xd0\xf7\x83\x11\xf0\x31\xb2\x9f"
+  "\x3c\xab\xff\xe3\x4f\x8d\xcd\xdf\x36\x9f\xbf\xa9\xbd\x57\x3e\xa1"
+  "\xd7\x3d\x6b\x84\x71\x9b\xbd\xd6\xb4\x0a\x29\x4d\xdb\xf6\x66\x46"
+  "\x3d\x8b\x14\xd7\x94\xd9\x13\x4b\xd6\x20\x44\xab\xbe\x2a\xd5\x2d"
+  "\x6b\xc0\xdf\x4f\xc4\x36\xab\xdd\x92\x3d\x41\x8f\x3e\x48\xc2\xe3"
+  "\x53\x1a\x3e\xb3\x27\xb0\xd7\x27\xeb\x15\x7d\x62\xf1\xf5\xf4\xfb"
+  "\x41\x71\xf4\x8a\x90\x8f\xf0\x7b\xb8\x57\xb0\x0d\xf1\xb8\x49\x0e"
+  "\x3c\x4b\xab\x5e\x9a\x87\x63\x8c\x6e\x19\xd3\xaf\x5e\x30\xde\x3a"
+  "\xc1\xf5\x5a\x1a\xfc\x68\xf0\x05\x9f\xaf\x42\x6e\xcc\xdf\xdb\xb2"
+  "\x74\x74\x66\x8c\x07\x89\x3b\xd9\x8c\x7e\xa9\xf7\x9d\x19\x8a\xbf"
+  "\xab\xdb\x3b\x08\xe2\x44\x40\xb2\x6e\x41\x03\xaa\x54\xe6\xf8\x42"
+  "\xfc\xa3\xe8\xa7\x07\x21\xf3\xf6\x99\xa1\xf9\x80\x01\x7c\xce\x91"
+  "\x84\x2a\xfc\xaf\x3f\xdc\x37\x45\xa7\xcc\xd2\xe2\x1c\x90\x2e\xe1"
+  "\x7d\x88\xc9\xd9\xbd\xea\x7d\xdf\x31\x68\x5e\xf1\xa6\x2b\xd8\x7e"
+  "\xc1\x79\x47\xa1\x1f\xcc\x75\xf5\xbe\x9e\x79\xb8\x6d\x53\x66\x4c"
+  "\x1e\x1c\x73\xa3\x01\x7b\xd0\x07\xc5\x0d\xb8\xce\x94\xea\x99\xad"
+  "\x7b\x85\xf9\xcd\x83\xd0\x4f\x6a\x45\x30\xb4\xfd\x71\x4c\xde\x81"
+  "\x65\x75\x14\x8d\xfb\xae\xf6\xcc\x06\xac\x7b\x9a\xb6\xec\x35\xec"
+  "\xe8\x8c\xdc\x76\xbd\x8f\x50\x46\x67\xe4\x51\xbb\x25\x27\x5b\xef"
+  "\xd6\x3b\x8e\xc4\xbd\x6c\x2d\x05\xe7\xe8\x95\x39\x6b\x68\xf0\x07"
+  "\xf3\x5b\x29\x21\x99\x0e\x7e\xab\xbe\xe9\xb7\xb6\x87\x64\xe2\xdf"
+  "\x62\xec\x43\x6c\x45\xfe\x6f\x69\x27\x6b\x90\xa3\x3e\xdf\xc1\x6d"
+  "\xc0\xef\x56\xd1\x9f\x0e\xca\x33\x6d\x9f\x9d\x87\xbf\xc3\xe7\x13"
+  "\xfb\x67\xe9\xbc\x57\xa2\x1a\x1a\x8e\x99\x58\x1f\x98\xb0\x0f\xa8"
+  "\x44\x88\x5f\xd9\x05\xf8\xf7\xf4\xca\xcf\x06\x98\x56\x69\x00\x37"
+  "\xc1\x43\x88\x5f\x3f\x5b\x19\x5b\x40\x9b\xe1\x63\x7a\xbe\x00\x29"
+  "\x74\xaf\x60\x9f\x7e\x96\xa9\x19\xfd\x30\xd8\xf6\xb3\x3d\xac\x6d"
+  "\xb5\xf5\x4f\xc6\x60\xbb\xa8\xc0\x16\x9e\xf4\xba\x9e\x49\x4c\x1b"
+  "\x60\x6f\x6c\xa3\x0c\xb0\x11\xd8\xc9\x03\xfb\xbf\x76\xcb\x67\xa5"
+  "\x36\x76\x52\xc1\xb1\x4a\xbd\xa2\xa7\x0e\x1f\xd3\x3c\x85\x08\x66"
+  "\xac\xee\x1b\xfb\xd7\x94\x1a\xa9\xc1\x7f\x4f\xee\x85\x54\xde\x05"
+  "\x88\xd2\x24\xf8\xe7\x13\x3f\xcf\xd2\x72\xbe\xfd\x2c\x88\xde\xfe"
+  "\x4a\x2c\x9c\xaf\xe5\x70\xf5\x79\xa8\x69\x5b\xf0\x00\x38\x4f\x5f"
+  "\x97\xfa\x97\x4c\x3a\x39\x78\x00\x7e\xaf\xbc\x42\xf9\x39\xf3\xae"
+  "\x1d\xbd\xca\x03\x91\xdf\x09\x0e\x48\x98\x47\x1b\x12\x6e\x82\x0f"
+  "\xba\xcc\xd2\x1f\x59\x62\x00\x5f\xfc\x25\x13\xfb\x3a\xff\x6e\x1d"
+  "\x85\x6b\xfd\xd1\x9d\x3e\xed\xbc\x9b\xf8\xdc\x03\xee\x13\xe1\x76"
+  "\x6b\xb7\x7c\x9e\xc9\xdd\xcf\xe7\x23\xb1\xdf\xe1\x37\xc6\xb0\x98"
+  "\xd6\x42\xbf\x14\xb4\x4f\xf0\x18\x38\xaf\x40\xaf\xf8\xd1\x83\x19"
+  "\x37\x4b\xe8\xb3\x5b\x1b\x10\xba\xbd\x84\x36\x8e\x37\x5e\x34\xc3"
+  "\x7c\x0b\x5c\xf0\xf3\x2a\x3d\x7a\x39\xdb\x62\x17\x32\x96\x9a\xda"
+  "\x61\x6a\x40\x18\x98\x76\xf6\xa9\x84\xda\x81\xdf\x2e\x9b\x6d\xd4"
+  "\x28\x1a\xee\xd2\xa5\x5b\xa7\x40\xdf\x56\x21\xba\x61\x09\x5d\x18"
+  "\x1f\x44\xd7\x6d\xf9\x11\x01\xe7\x29\x47\x10\x43\xbb\x77\x52\xd0"
+  "\x86\xf1\x4b\x91\x77\xa7\x28\x6f\xfa\x54\x41\x39\x5a\x1e\x44\x57"
+  "\x95\xc4\x9a\x50\x71\x4d\x25\x8a\x3b\x8f\x3c\x57\x14\x21\x75\x5c"
+  "\x10\x6d\x28\x0c\x2d\x47\xe4\x78\x11\x5a\x71\x09\xb9\x2d\x3f\x41"
+  "\xd7\x8d\x83\xf9\xf7\x87\x72\x7c\xbc\x12\x8e\x9b\xd0\x8a\x2a\xda"
+  "\x98\x30\x13\x79\xe2\xff\x17\x9d\xc0\xc7\x2f\x23\x18\xa7\x6e\xe3"
+  "\x63\x0d\xde\xbb\xe1\x37\xf1\xf5\x19\xd0\x17\xf3\x5d\xfa\xe8\xd6"
+  "\xbb\x08\x2d\x9f\x8a\xfc\xe2\xe6\x20\xd5\x78\xa0\x01\x25\xc6\xc3"
+  "\x68\xbc\x89\x86\xf9\xfd\xe4\xff\x6b\xef\x7b\x00\xa2\xaa\xb2\xff"
+  "\xcf\xbc\x79\xea\x64\x20\xa8\x40\x68\xa8\xa3\x82\x8e\x86\x8a\xae"
+  "\x9a\xed\x8f\x5a\x2a\x93\xa9\xb5\xa0\xfd\xba\x2e\xb5\xae\x62\x91"
+  "\x61\x99\x92\x92\x92\x7f\x00\xc9\xfa\x59\xab\x88\x84\x2c\x15\xff"
+  "\xda\xa8\x9f\xee\xcf\x3f\x58\x56\xb4\x6b\x39\x25\x6e\x58\x08\xd4"
+  "\xd2\xae\xb5\xba\x8d\x84\x46\x46\xc6\x2a\xc9\x00\xc3\xdc\xdf\x39"
+  "\xf7\xbe\xc7\xbc\x19\x06\x85\xc9\x76\xcb\x9f\x4f\x1f\xef\xbd\xfb"
+  "\xce\x3d\xf7\xdc\xfb\x39\x7f\xee\xbd\xef\xcd\xbb\xb0\x6e\x31\x18"
+  "\x62\xec\xf4\xbb\xf0\x4f\x70\x2f\x80\x22\xa4\xc5\xba\x59\xa8\x6e"
+  "\x6b\x8e\x63\x7f\xe7\x1b\x35\xcf\xdb\x4a\x9e\xe3\x40\x6d\xd6\x3a"
+  "\x70\x3f\xd8\xb6\xee\x4f\xc7\xba\x1f\xa3\x36\xc0\x72\x6a\x1c\x94"
+  "\xef\x3c\x8f\x3b\xd4\x06\xba\x05\x76\xb4\xd5\x6d\x73\xd3\x17\xa4"
+  "\x58\x38\x5f\xab\x7e\x57\x70\xd1\x72\x2e\x93\x0b\x6d\x8c\x9d\x9d"
+  "\x6b\x0a\x9c\x8b\xbc\x76\x45\xc5\xa4\xfc\x82\xa1\xfe\xe9\x50\x27"
+  "\xcc\x2d\x99\xbb\xd2\xd5\xf6\xb6\x76\xfa\x92\x5d\xc9\x88\x85\x59"
+  "\x9f\x04\x32\xde\x2f\xb6\xea\x6a\xeb\x35\xba\x4b\xfe\xa8\xaf\x4a"
+  "\xab\xd0\x94\x5b\x75\x7f\x0b\xd7\xd0\x90\xbe\x76\xd2\xe0\x7d\xd4"
+  "\xff\xda\xa9\xce\xfb\x3b\x6c\x4c\xc3\x43\x89\xab\x2a\x6f\x3d\xfa"
+  "\xd7\xa8\x8e\xc0\xf9\x11\x2c\xd0\x37\x8a\x9d\x0b\xf6\x61\x12\x62"
+  "\x63\x67\x36\xc7\xb6\xdb\xd3\x31\x76\xfa\x54\xdb\x9b\x41\xd0\xef"
+  "\x7e\x9a\x6d\xf3\x35\x8b\x77\x59\x77\x3f\x4a\x3c\xb1\x8f\x55\x83"
+  "\x71\xd8\x3f\xa6\x82\xd9\xc8\x2f\x74\x6c\x0b\xb4\x64\x2e\xc7\x58"
+  "\xbc\x6d\xbe\xd1\x11\x78\x4f\x84\xed\xc5\x64\xb2\x87\x58\x16\xb8"
+  "\x18\xe3\x39\xe6\x55\xf8\x60\xb9\x7d\xac\xfa\xdd\xe6\x0e\xcc\xcf"
+  "\x72\x6e\x4f\x17\xe9\xc2\x6f\x09\xff\xb2\xdb\xcc\xc2\xf0\x5e\xd6"
+  "\x2d\x33\xf1\x5e\x9f\x3a\xfd\xee\x5a\x4c\x07\xbc\x5e\x6b\x49\x3d"
+  "\x4b\x3c\x3e\x15\x3a\x7d\x4b\x94\xcb\xb5\x44\xed\xf9\xa7\xd9\xe4"
+  "\x7b\x8c\x77\xf0\xb2\x5a\x9d\x7e\x46\xeb\xb3\x6f\xcf\x6a\xc9\xdc"
+  "\xe3\x63\xd5\x4d\x6a\xe2\xba\x8f\xf9\x9a\xb9\xbf\x42\xbf\x35\x32"
+  "\xd9\x70\xd0\x0c\x70\xb0\x9c\xec\x68\x4f\x84\x55\x37\x45\x76\xb6"
+  "\xe5\x9e\xdb\x89\x96\xfb\x10\xf2\xa1\x92\xf0\x57\x94\x87\xe5\xce"
+  "\xaf\x21\x3f\x48\xfe\xd0\xaa\xdf\x33\x93\x7c\x21\xfa\x89\x19\x4a"
+  "\xfc\xd9\xc8\xfd\x49\xf6\xda\x06\x94\x2b\xbd\x4e\x91\x45\x2b\x9b"
+  "\xea\xfb\xd8\xd6\x75\x89\x82\xf6\xf6\x58\x2c\xbf\x14\xcb\x3f\xa6"
+  "\xd5\x17\x51\xaf\xd2\x40\xd4\xe9\xa3\x93\xca\xf1\x1a\xfb\x48\x75"
+  "\xfa\x1d\x91\x2c\xf3\x95\xf1\xe8\x5f\x0c\xa4\xa7\xe4\x23\xf3\xb2"
+  "\x41\xb6\x6d\x5d\x97\xd2\xb1\x75\x5d\x12\xf2\xb1\xa9\x7e\x85\xf2"
+  "\x91\x2d\xa0\x6f\x31\x70\x9f\xd1\x61\xd7\x73\x7b\xef\x80\xf0\x4e"
+  "\x3f\x82\x69\xad\x03\xd7\x25\x29\xe9\x32\x97\x27\x43\xef\xc0\xb2"
+  "\x75\xaa\xec\xad\x03\x6f\x8f\x6a\xc9\x2c\x8d\xb5\xea\x8c\xfe\x2e"
+  "\x7e\x26\xfb\x26\x1c\x9d\xc4\x91\xce\xe8\x51\xce\xc7\xf0\xd8\x4f"
+  "\xd1\xc1\xab\x0f\x56\x00\xcc\xbc\x0d\xcb\x40\x2c\x9f\x0b\x62\x4d"
+  "\x98\x3f\xcb\x0a\x8f\xce\xa6\xfc\x4f\xe3\x35\xa5\x13\x0d\xa6\x6f"
+  "\xb7\xc2\xf2\x48\xc1\xf7\x4f\xb3\x09\x1b\x37\xbe\x47\x04\x5f\x2e"
+  "\xcb\xd5\xc4\x93\xf2\x11\xcf\x82\x5c\xd6\x48\x7c\x90\x47\xa3\xca"
+  "\x7b\x33\xa6\xa9\xfc\x67\x3e\xa2\x96\xb1\xd7\x07\xef\x97\x6b\x65"
+  "\xcf\xcb\x65\xcd\x42\xae\xbd\x26\x2b\x3c\x15\x41\xf7\x36\x62\x1a"
+  "\xe5\x15\xf8\xef\xbd\x8d\x74\xc3\x2a\xea\xa3\x17\x3a\xb2\x77\x8e"
+  "\x15\x36\x94\x69\xe3\x0d\x62\xe0\x2b\xe2\xe1\xcb\xc5\x0a\xbf\x14"
+  "\x95\x9f\x93\x97\xe0\xc1\xb2\x52\xe3\x35\xf6\xe8\x43\xfc\x91\x1e"
+  "\xeb\x9f\xec\xa3\xd4\x7f\x46\xb3\xd0\x67\x6c\xfb\xbd\x47\xa8\xed"
+  "\x29\xf6\x11\xce\xbc\x8c\x17\x93\xa9\xbf\x6c\x40\xfc\x67\xa8\xf1"
+  "\x11\xb1\x89\x44\x1e\x8d\xce\x58\xb2\xd7\x42\x78\x23\xaf\x79\x18"
+  "\x8f\x62\xc9\x1f\x29\x65\xde\x4d\x31\x51\xad\x3f\xf2\x91\x3b\x32"
+  "\x5f\xb9\x83\xf4\x9a\xfa\x22\x2c\xf0\x37\x18\x4f\x5f\x9d\xea\x16"
+  "\x63\x65\x85\x2e\x8d\x68\x9e\x0d\x62\x0d\x48\x13\xa7\xd2\xd0\x7d"
+  "\x6c\xe7\x9b\x30\x6d\x89\x15\xb6\xee\xa7\xb4\x4c\xa4\xb1\xea\x5f"
+  "\xe9\xf6\x37\x39\xa9\x23\x41\xaa\xce\xb7\xd2\x78\x95\x6c\x38\xb2"
+  "\x3a\xa4\x19\xaa\xf3\x1d\xe0\x78\xe5\xfa\x88\xa8\x54\x66\xc1\x31"
+  "\xc0\x57\x55\xb6\x06\xe8\x5d\x1f\xf3\xd5\x7d\x5c\x1f\xdb\x70\x5c"
+  "\xb5\x76\x0a\x50\xff\xe3\x8c\x7e\xdf\x90\xea\xa6\xb3\xdc\x9f\xe1"
+  "\x39\xff\x5e\xe4\xb3\x38\x0e\xa3\xb1\x18\x8e\xb7\x13\xb3\x24\x31"
+  "\x1e\x73\x20\x6d\x21\xa5\xd3\x58\x0d\xe3\x54\x91\xe6\x1e\x7b\x65"
+  "\x5a\xa9\x68\xbb\xd7\x3e\xe2\x7e\x9d\xe4\xb5\x47\x5b\x48\x66\x47"
+  "\xc9\xb4\x52\xaa\x43\x5a\x0a\x73\x54\xdb\x5b\x2c\x14\xcb\x8c\x2b"
+  "\x69\x1c\xf9\xda\xae\x98\x02\x60\x8e\x97\xa7\xf5\x72\x1c\xf7\x1a"
+  "\x7f\xff\x13\xc7\xda\x67\x9a\xc2\xa6\x95\xa6\x75\x80\xb4\x25\xb5"
+  "\x8f\xe1\xd6\x7c\x66\x39\x37\xe6\xfa\x88\x96\xcc\xd7\x6a\xde\x45"
+  "\x8a\xde\xf7\xbf\x5f\xab\x51\xeb\x5e\xa8\xd4\x1d\xd3\xf8\x9a\x8d"
+  "\x93\xf2\xd2\x79\x7d\xad\xfa\x7d\xdd\xce\xf5\xb1\x0c\x3f\x76\x30"
+  "\xdf\x0e\x2b\xf2\x59\xdb\x8a\x02\xf4\x85\xb9\xbf\x84\x3d\x85\x47"
+  "\xc9\x77\x47\xa9\xed\xc9\xdb\xce\xde\x04\x49\xa9\xe0\x7f\x5a\xbf"
+  "\x6f\x6f\xcc\xda\x74\xbe\x2e\xd3\x01\xa4\xeb\x9d\xac\xfb\xf8\xfb"
+  "\x95\x55\x38\x76\x8f\xb1\xa7\x31\x11\x7f\xf6\x7d\x7a\x97\xc2\x8f"
+  "\xee\xa9\xf8\x15\x2a\x63\x6a\x2f\xca\xb0\x7a\x51\x57\x7f\xcf\x75"
+  "\x7d\xbd\xc0\xfb\xba\xbe\x9e\xd8\xb5\xae\xaf\x1f\xba\xb4\x75\x7d"
+  "\xbd\xd2\x8b\xba\x1a\x3d\xd7\xf5\x8d\xa7\xbd\xaf\xeb\x1b\x73\xba"
+  "\xd6\xf5\x8d\xbd\x97\xb6\xae\x6f\x74\xfb\xfe\xc7\x05\xea\x1a\xe1"
+  "\xb9\xae\x6f\x3e\xe6\x7d\x5d\xdf\x8c\xea\x5a\xd7\x37\x0b\x2e\x6d"
+  "\x5d\xdf\x2c\xe9\xb6\xae\x92\x1f\x23\xff\x84\x7e\xa9\x2d\xb5\x15"
+  "\xfb\x6d\xb9\xf1\x96\x75\x2f\x82\x54\xd9\x6c\x83\xaa\x90\xa3\x90"
+  "\xf6\x38\x48\x13\x93\xd0\xef\x65\x40\x24\xcb\xf5\xb1\x54\xe5\x37"
+  "\x62\xfa\x29\x38\x92\x62\x83\xa8\xe5\xe4\x7f\xcb\x16\x57\x27\xf4"
+  "\xd6\xff\x96\x4d\xed\xf4\xbf\xf6\x29\x8a\xcf\x7d\x6b\x5b\x55\x63"
+  "\x1b\x50\xfd\xf1\x7c\x7d\xa7\xff\xcd\x10\xed\xed\xee\x7f\xa9\x3d"
+  "\xaa\x6d\x36\x17\xff\x2b\x7e\x9b\xf5\xd6\x9d\xee\xbe\x37\xf3\x34"
+  "\x80\x67\xdf\xfb\xd6\x38\xf2\xbd\x85\x78\xbf\x97\xf2\x37\xab\xbe"
+  "\x37\x0b\xcb\xd4\xfa\xde\x83\x09\x14\xa3\xdf\x9a\xed\x9d\xef\x7d"
+  "\x6b\xb6\x5a\xef\x02\xa5\xde\x58\x56\xa9\xab\xef\x7d\x6b\x43\x4f"
+  "\xf4\x96\xe5\xde\x66\xdd\x33\xdc\xd6\xc7\x51\x72\x7d\x13\xc5\xb7"
+  "\x16\x6c\x93\x37\x0b\x6d\xf2\x29\xfd\x9f\xc5\xbb\xea\x2d\x09\x3a"
+  "\x56\x32\x3d\x2f\x26\x99\x7d\xce\xc2\xae\x6f\xa2\xf9\x51\x1a\xe7"
+  "\xe3\xfd\x1b\xd8\xcb\xd3\xf3\x7a\x27\xb7\xe0\x89\xf1\x2f\x22\x15"
+  "\xed\x65\xcf\x4a\x9b\xe4\x58\x13\xe7\x87\x38\xf8\xb3\x6d\x77\x18"
+  "\xd9\x53\xd3\xe6\x9c\xdb\xb6\x20\xeb\x90\xe9\x24\x10\x2d\x5b\x2f"
+  "\x47\x7d\x0f\xf9\xcb\x2f\x22\x7f\xab\x17\xf2\x97\xf7\x42\xfe\xf2"
+  "\x1e\xc9\x1f\x84\xf2\xb7\xcd\xe8\x83\xe3\x42\xe9\x40\xdb\x0c\xb9"
+  "\x77\xf2\xfc\xa5\xdb\xf5\xcf\x2f\x61\x19\x3d\xf6\x7f\x2c\xe8\x37"
+  "\xc6\x3d\x85\x4d\x12\xfa\x00\x1e\xc3\xc9\xf6\x84\xff\x6b\x40\x9f"
+  "\xf5\x39\x13\x3e\xa9\xa9\x97\x3e\x69\x7f\xb7\xdf\xbf\xec\x5a\xfe"
+  "\x2f\xd3\x7f\x80\xf2\xbb\xaf\xbf\xbb\x4f\xdc\x7d\x83\x7f\xf7\x3e"
+  "\xf1\x8e\xf4\xae\x3e\xf1\xed\x75\xbd\xf7\x89\x6f\x9b\xbb\xfa\xc4"
+  "\x77\x76\x38\x7d\xe2\x3b\xdb\xbc\xf7\x89\xef\x2c\xec\xb9\x4f\x7c"
+  "\xe7\x46\xef\x7c\xe2\x3b\x86\x0b\xfb\xc4\x77\xe2\xbd\xf3\x89\xef"
+  "\xc4\x77\xf5\x89\x6f\x97\xbb\xfa\xc4\x77\xba\x5d\xeb\x8c\x65\x4d"
+  "\xdc\x8e\x31\xda\xe7\xb4\xfe\x40\xa2\x3d\x03\xc0\x91\xb5\xa3\x2c"
+  "\xa6\x83\xb5\xb0\xad\x13\xb7\x3b\xa4\xa9\xe4\x57\xa2\x5a\x5a\x12"
+  "\x0d\x8e\x55\x26\x1f\x36\xe8\xe6\xd3\xac\x3d\x98\xe6\x13\x43\x51"
+  "\x7e\x3f\xd6\x62\x1a\xc0\x56\x99\x06\xe5\x9f\x87\x00\xdc\x83\xf3"
+  "\x95\x78\x8c\xe7\x11\x6c\x55\x70\xff\xcc\x95\x10\xee\xd7\x0c\x06"
+  "\x94\x21\xce\x6f\xbd\x3f\xa0\x0f\x0a\xa0\x73\x96\xf1\x9e\xbd\xe8"
+  "\x3c\xc8\x7e\x29\x88\xcd\x40\x2c\x2f\xc5\x8f\xb1\x15\x26\x28\x5a"
+  "\x0e\x06\x87\x04\xc1\x85\x12\x2b\xb5\xb7\x98\xa4\x8e\x80\xf9\x51"
+  "\x02\x1f\x4b\x08\x1f\x7b\xe5\xcc\xf7\x71\x04\xfd\xae\xb9\x23\x2d"
+  "\x51\xcf\xd6\xc4\xe9\x49\xd6\x8e\x9c\xdf\x35\xb1\x5c\xdc\xd3\x12"
+  "\x07\x50\x1f\xba\x68\x25\x96\xdd\x12\xdc\x7f\x0b\x96\x5d\xb8\x12"
+  "\x42\x0b\xce\x83\x89\x9d\x33\x49\x88\x7f\x1c\xad\x6f\x8a\x6d\x14"
+  "\xe7\x90\xde\xb3\xe3\x3d\x99\x7c\x22\xa3\xf2\xed\x58\x7e\xbb\x89"
+  "\xe6\xb2\x50\xb7\x21\xb8\x08\xcb\xef\x58\x65\xea\xa5\xbd\x1c\xe0"
+  "\xef\x7f\xab\x72\x39\xc2\x6f\xf6\x67\xbb\x71\x27\xb9\xb0\x0d\x8b"
+  "\xa8\x4d\x26\xde\x1c\x40\xb2\x6d\x3e\x0f\xe1\x28\x67\x28\xca\x60"
+  "\xc2\x72\xe9\xdb\x30\x71\xf3\x1f\xf5\x27\x1d\x75\x91\xad\x63\xab"
+  "\x22\xdb\xb7\x28\xdb\x19\xa7\x6c\x54\x16\xb5\x4f\x77\xcf\x5d\x63"
+  "\xd6\x0d\x27\xdb\xfc\xd2\x2f\xa5\x9f\x99\x9e\xc1\x9e\x5b\x93\xd8"
+  "\x4b\x5d\xb5\xec\xeb\x4e\x5f\xb6\xec\x86\x10\xe6\xff\x52\xc3\x5d"
+  "\x4f\x7e\xce\x68\xae\xf0\xc9\xdd\x10\x5e\x8d\x76\x5d\x65\xfb\x06"
+  "\xd8\xc0\x97\x1a\x0e\x99\x1a\x7b\x59\xd6\xbb\xc6\xee\xca\x7a\x26"
+  "\x83\xd5\x38\x02\xe6\x47\xb0\x80\x05\x1b\xb7\x64\xb0\x94\xf6\xd0"
+  "\x69\x35\x6d\xa1\xd3\x8b\x17\xd8\xfd\x51\xaf\x59\x8a\x71\x39\x18"
+  "\x4f\xe9\xdf\x7f\xe0\x83\x5a\x1c\x97\xde\x0b\x86\x3a\xfd\xfb\xf9"
+  "\x69\x9f\xd2\xf3\xa9\x77\x4b\x5d\x9f\x4f\xbd\x5b\x0b\xfa\x83\x33"
+  "\x41\x5f\x3e\x07\xf4\x87\x52\x00\xe9\x5c\xf7\xbf\xe6\x08\x5e\x07"
+  "\x47\xc6\xec\x18\x0e\xa9\x76\xf6\x25\xcb\xf1\xb5\x65\x4a\xcc\x16"
+  "\x33\x4e\x67\xb5\xac\xa4\xe7\x36\x07\x87\x60\x9b\x7e\x8d\xb1\xd6"
+  "\xef\x94\xfe\xbd\x93\x88\x29\x24\x2d\x87\xc1\xa7\xf5\xef\xd5\x93"
+  "\xdd\xf8\x35\xf7\x33\x77\xa4\xc5\x81\xdd\x98\x0c\xed\x39\xf3\x8d"
+  "\x1d\x39\xb7\xa7\x3b\xfc\x77\x94\xd1\x5c\x2f\x3d\x6f\x45\xdb\x88"
+  "\x5b\xd0\x61\x20\x7b\x8c\xb3\xdc\xf7\x01\x9c\x4a\x06\x29\xed\x3b"
+  "\xf0\x45\xdd\xec\xb4\xab\x3b\x1b\xfd\x6c\xeb\x1a\x99\x83\x6c\x8b"
+  "\xe6\x56\xf1\xde\x80\xd4\xef\x70\x7c\xdf\xd4\x00\xf9\xcb\x21\xa0"
+  "\x63\x45\xe2\xa0\xa6\x73\x89\x83\x5f\x70\x40\xc0\x80\x66\xf0\xcf"
+  "\x3f\x8b\x3a\xb5\x02\xf5\xe9\x2c\xda\x59\x93\xb0\x33\xfa\x7d\x7f"
+  "\x21\xd9\xd8\x33\x5f\x45\x14\x9d\x15\x36\xc6\xf5\x88\x6c\x6c\x19"
+  "\xea\xd1\x52\x8a\x1f\xa8\x47\x19\x68\x63\x68\x17\x2c\xd3\x92\x93"
+  "\x9f\xc1\x68\xee\x57\x2a\x3a\xdd\x8f\xee\xe9\xfa\x8c\x93\x8c\x1f"
+  "\xc4\xda\xc0\x39\xd7\xf1\x7e\x41\x5b\xd8\xf4\x62\xe3\xaf\xd8\xb7"
+  "\x75\xfa\x83\xfe\x98\x6e\x30\xce\x1d\xeb\x8f\xed\xad\xfc\xf6\xe8"
+  "\xfd\x7c\x9a\xcf\xb4\x62\x5b\x50\xbb\x18\x7f\x05\x63\xeb\xf4\xef"
+  "\x9e\xa4\x76\x5c\xb5\x1d\xf4\x49\x37\xb1\x7a\x6c\xb3\x46\xc6\xe7"
+  "\x5d\xde\xe5\xcf\xa2\xe9\x99\xfe\x87\xfc\x79\x99\xc8\xd3\x81\xed"
+  "\x66\x0f\xf0\x35\x23\xde\xb1\x96\x87\xda\xb8\x1f\xa2\x76\x3c\xb5"
+  "\x04\xa4\x05\x8d\xd8\x56\x1d\xd8\x56\x2d\x26\x1f\xf4\x47\xb1\xe4"
+  "\x8f\x58\xd6\xcd\xf5\x6b\xad\xcc\x11\x93\xa0\x67\xa9\x8f\x82\x81"
+  "\xe6\xb8\xe7\x27\x01\x5b\xf7\x0d\xb6\x57\xf3\x51\x40\xbf\x34\x00"
+  "\x7d\xd6\xa0\x82\x95\x10\x40\xed\xe5\xdb\x88\x7d\x95\xec\x97\x4b"
+  "\x77\xa7\x56\xf4\xe9\x40\xfd\x25\xff\xe4\xb7\x5e\x77\x15\xda\xd9"
+  "\x80\x4d\x64\x8f\x68\x9f\x7e\xeb\xb9\xbf\x8c\xcb\x47\x3b\xb4\xaf"
+  "\x32\x8d\x6a\x5f\x65\x32\xe2\x3e\x5c\xf5\x61\xaa\xff\xc0\x36\xe3"
+  "\xfe\xab\x3a\xc5\x0a\x76\x6c\xdb\x01\x14\xeb\x56\x99\x42\x78\x1b"
+  "\x3f\x68\x82\x49\x36\xd0\xa1\x4c\xfe\x28\x2f\x14\x2d\x02\xc3\x91"
+  "\xc4\x3a\xe8\x40\xdb\x50\xdb\xfd\xce\xc5\x46\x40\xbe\xd2\x21\xd3"
+  "\x27\xa0\xb4\x99\xae\x7b\xbd\x3b\xf4\xa8\x53\xef\x0e\x3d\x4a\x6d"
+  "\x27\xf4\xee\x50\xd2\xe5\xa8\x77\x1f\xc6\x71\xbd\xd3\xb7\x87\x71"
+  "\x7d\x6a\xac\xb6\xbf\x8a\x6d\x74\x68\x1e\xe9\x08\xe9\xcc\xe1\x3f"
+  "\x91\xce\xfc\x75\xc3\x8f\x55\x67\x5a\x5b\x4c\x46\xdc\x7f\x10\x9d"
+  "\x41\xbe\x5c\x67\xa8\xad\x3e\x8c\x6b\x03\xb5\x8d\xb8\xad\x66\xbd"
+  "\xd4\x60\x4c\x83\x5f\xa0\xad\xe6\xfb\xad\x1f\x0e\x47\x78\x3b\xbd"
+  "\x9f\x6f\x9c\xcb\x1c\x75\xfa\xbf\xbe\x9d\xf6\x11\xf8\xb7\x65\x30"
+  "\x56\x6d\xdf\x05\x8e\x80\x7b\x22\x68\xae\xdd\x91\x13\x68\xc1\x31"
+  "\x2b\xad\x6d\x43\x36\x2d\xfb\x25\xd1\xb3\xfe\x12\x0b\x3d\xe3\x73"
+  "\x6c\x7d\xc9\xc6\x06\xee\x4f\xa1\xe7\x0c\x8e\xad\x4f\x58\x1c\x03"
+  "\xff\x52\xd3\x92\xf9\xbe\x6c\x85\x2f\xa2\xf8\x5c\x78\xce\xfc\x08"
+  "\xf4\x0d\xe4\x7f\x27\x88\x67\x62\xf4\x4c\xf1\xfd\x50\xf5\x99\x36"
+  "\xf9\x04\xe5\x39\x83\xf2\x1c\xe2\x7d\xc2\xb0\x3f\x3d\x87\x50\x7c"
+  "\x4a\xa0\xfa\x1c\x42\xbd\xa6\xfb\x98\x2f\x98\x3f\x63\x75\xe6\xcb"
+  "\x51\xe8\x94\x7c\xef\x3e\x47\xbe\xde\x99\x4f\x5c\xa3\x5f\xc9\x69"
+  "\x97\xc0\xe0\xb1\x8f\x13\xb0\xd8\x88\xf6\x83\x63\xa3\xc3\x81\x78"
+  "\x94\x4e\xe9\x2b\xa6\xe1\x51\x8f\x47\x3e\x8f\xd9\xbb\x78\xf5\x7e"
+  "\x8d\x78\x16\xb4\x60\x9f\x22\xf7\x47\xdc\x26\xc7\x83\xef\x69\xe5"
+  "\xbc\x25\xb3\x22\x5c\x7d\x36\xdf\x49\xef\xc4\xa7\x82\xca\x46\x8c"
+  "\x64\xf1\xbe\x80\xb8\xa6\x77\x71\x14\x7e\xfc\xda\x11\x3a\x23\xcb"
+  "\x92\x5a\x07\x8d\xfa\x8a\xbc\x6a\x8c\xe1\x8e\xdc\x05\xfb\xe8\x19"
+  "\x19\xd9\x95\x5a\x2e\xda\xa2\xc1\xb2\x9a\xd3\x3c\xce\xfb\xb9\x39"
+  "\x73\xb3\x58\xae\xaf\x85\xc6\x82\x2d\x2c\xf1\x26\xe5\x78\x23\xd9"
+  "\x93\x98\x37\xa9\x38\xc9\x10\x5b\x5a\x9f\xbd\xf3\xfd\x24\x5a\x37"
+  "\x3d\x5d\x36\xbe\xbb\x56\xc4\x4a\x55\x5e\x5a\x5b\x9d\xde\xff\x19"
+  "\x9b\x0e\xe9\x2d\x1e\xd6\x56\x77\xbe\x27\x54\x51\xe3\xd8\x36\x37"
+  "\xab\x25\xf3\xb0\x11\x31\x88\xd7\xd6\xd9\x13\x16\x56\xfd\xe1\xc8"
+  "\xee\xee\xf5\x0e\x87\xc3\x71\xdd\xf1\xb9\xcd\xd4\xc1\x7a\xc9\xab"
+  "\xfb\xf9\x9f\xd0\x69\x11\x31\xdb\x3b\x2c\x8e\xf6\x38\xbf\x43\x6b"
+  "\xbf\xe9\x65\xdf\xe6\xb0\xbd\x3b\xbe\x1d\x39\xf7\xc4\xb6\x8f\x99"
+  "\x16\x81\xd8\xf8\x74\x2c\x8b\x8b\xae\xda\x6e\x87\x1d\x4b\x1b\x24"
+  "\xf2\x87\x3b\x4f\x97\x4a\x31\xe3\x94\x3e\x5c\x3d\xf8\xd3\xbc\x17"
+  "\xf5\xe5\x32\xcf\x40\x68\x5b\x5a\x9c\x5f\x5b\x7b\x1c\xfc\xfe\x0c"
+  "\x44\x3a\x1e\x0c\xee\xbf\x69\x11\xc8\xad\xe8\x0b\x5b\xbf\x4c\xf4"
+  "\xfb\xf0\x58\x03\x1c\xc0\xbc\x55\xcd\x56\x28\x44\x5a\xf6\x65\xdc"
+  "\x80\x5f\xc6\x33\x5b\x65\xfc\xab\x10\x63\xea\xb0\xa4\x9e\x00\x5f"
+  "\xf4\x89\xfe\xd5\x29\x2f\xe3\x18\xea\x1b\xe8\xf3\xb8\x64\xac\xb6"
+  "\x9f\x84\xcd\x8b\xd0\x97\xa2\xef\x4c\xfb\x35\xc6\x0c\xd4\x89\x17"
+  "\xb4\x31\xe3\xa1\xe7\x9d\x31\xe3\x5b\x8c\x19\xd9\x18\x33\xd2\x82"
+  "\xa1\x2a\xc9\x02\xe8\xc3\xfa\xdd\x95\xe4\x67\x4b\x4d\xc2\xd8\xf1"
+  "\x38\xc6\x8e\x94\x93\xc0\xe3\x46\x63\x03\xa0\xcf\x1f\x50\xb0\x14"
+  "\x02\xda\xbe\xc5\xd8\xf1\x2d\xc6\x8e\x54\x11\x3b\x9e\x3b\x83\xb1"
+  "\x63\x19\x8e\x0d\x96\x62\xec\x68\xf4\x10\x3b\xce\x78\x1e\x17\xa8"
+  "\x7e\xb0\xf5\x5b\x93\xf4\x1c\xc6\x8d\xd5\x9f\x80\xf4\xdc\xdc\x7e"
+  "\xbd\xd4\x99\x0f\xbb\xfd\xfd\x0f\xcb\x5d\xf0\xac\x83\xc5\x01\xb5"
+  "\xfb\x6a\x1b\xc6\x61\xc4\xa5\xda\x64\x07\xbf\xda\x7e\xe6\x56\x4c"
+  "\x6f\x0f\x9a\x05\xdb\x3f\x6b\x92\x58\xce\x1d\xc6\x56\xc4\x6d\xf5"
+  "\x63\x20\xb5\x23\x86\x3b\x7f\x95\x25\xd1\x38\xd1\xb1\x6d\xd6\x4c"
+  "\x31\x26\x3d\xf2\x32\xcd\x89\xf8\x59\x05\x6e\x76\x16\xe7\xc7\xee"
+  "\x8f\xf3\xdd\x7c\x1f\xc8\x1d\x5f\x04\xf7\x77\xdc\x1f\x6c\x48\xfd"
+  "\x04\xfc\x9b\xee\x4f\xc4\xf6\xfa\x06\x0e\x7c\x9c\x25\x15\xdd\x0b"
+  "\x46\xfa\x16\x23\x7b\xca\x0a\x45\xf3\x61\x46\xd1\xbf\x60\x6a\xe1"
+  "\xbd\x10\x5e\xf0\x19\x7d\xb3\x1d\x31\x6c\x60\xb6\x23\x89\x7f\x86"
+  "\xa2\xcf\x20\x8a\xe5\xde\x0e\x2c\xf0\x9e\x58\x3c\x9f\x91\x75\x2f"
+  "\x8e\x1f\xf0\x7e\x8c\xa9\xd5\x52\x9d\x72\x04\x36\xd5\x01\xa4\x7e"
+  "\xa5\x60\xdc\x89\xef\x71\xb0\x4b\xe8\x3f\xa8\x4f\x70\xa7\xc0\x97"
+  "\x9e\x83\xd1\x98\xa3\x13\xe3\x45\xef\xb9\xf6\x0b\x14\x8c\x8f\x34"
+  "\xd6\x00\xc6\xc0\x7e\x9d\xfd\x03\x8e\xf1\x71\x50\xfb\x06\x88\xcd"
+  "\x00\xec\x0b\x04\xb4\x9e\x73\xeb\x1f\x2c\xf7\xb2\x7f\xa0\x8c\x6f"
+  "\xec\x2b\x4c\x52\xbe\xc4\x20\xed\x08\x48\x79\x8e\xde\x62\x7c\x24"
+  "\x89\xfb\xdb\x92\xe9\x79\xe2\xbd\x9c\xca\x71\x84\x85\x55\x5f\x69"
+  "\xfa\xb5\x49\x07\x5e\x62\x9f\x7e\x11\xec\xcb\x05\xf6\xd5\x2f\x7a"
+  "\x89\x7d\x3a\x62\x1f\xe7\x1d\xf6\xdf\xf5\x12\x7b\xfe\x4d\xcb\xcb"
+  "\x14\xfb\xea\x25\xae\xd8\x57\x85\x09\xec\xab\x42\xbd\xc7\x3e\xfa"
+  "\x22\x76\x1f\xad\xd8\xfd\x47\x05\xde\x61\x1f\x4d\x76\x5f\xea\x1d"
+  "\xf6\xdf\xf4\x12\x7b\xfe\x5d\xcc\xcb\x14\xfb\x8f\x12\x5d\xb1\xaf"
+  "\x19\x29\xb0\xaf\x31\x7e\x0f\xec\x2f\x62\xf7\xd1\x8a\xdd\xff\xed"
+  "\x39\x2f\xb1\x47\xbb\x3f\x61\xf0\x0e\xfb\xe3\xbd\xc4\x9e\x7f\x5b"
+  "\xf3\x32\xc5\xfe\x6f\x09\xae\xd8\x7f\x3c\x4c\x60\xff\x71\x88\xf7"
+  "\xd8\x9b\x2f\x62\xf7\x66\xc5\xee\x3f\xd9\xe6\x1d\xf6\x66\xb4\xfb"
+  "\x13\xf1\xde\x61\xff\x76\x2f\xb1\xe7\xdf\xe7\xbc\x4c\xb1\xff\x24"
+  "\xde\x15\xfb\xda\x21\x02\xfb\xda\xe0\xef\x81\xfd\x45\xec\xde\xac"
+  "\xd8\xfd\x3f\xb6\x7a\x89\x3d\xd9\x7d\x99\x77\xd8\xaf\xeb\x25\xf6"
+  "\xfc\x1b\x9f\x97\x29\xf6\xff\x98\xe7\x8a\xfd\xdf\x03\x05\xf6\x7f"
+  "\x0f\xe8\x09\xf6\x6b\xb4\xd8\x1f\xeb\x67\xc6\xb1\x15\xef\xe7\xef"
+  "\xb8\x57\xc1\xfe\x15\xc4\x1e\xeb\xbf\x73\x6e\x9e\x5b\x1f\xff\xd3"
+  "\x27\x39\xee\xf1\x88\x7b\x0a\xe2\x8e\x63\x43\x15\x73\xc4\xc8\x97"
+  "\x70\x27\xcc\x53\x8f\x83\xff\x01\xcc\x4b\xf8\x10\xc6\x88\xa3\x91"
+  "\xe3\xdc\xd7\x0a\x4c\x27\x07\x13\x9e\xd4\xef\x27\xcc\x2f\xd6\xb7"
+  "\x27\x9d\xb8\x28\xe6\x77\xff\x30\xfd\xfb\x36\xf7\xf9\xbf\x4b\x85"
+  "\xf9\x47\x38\x86\x4b\xed\x2d\xe6\x9f\xc6\xba\x62\x7e\xd4\x97\x70"
+  "\xb0\xea\x8f\xfa\x78\x8f\x79\x74\x7a\xf7\x98\xab\x31\xfe\x9f\x8f"
+  "\x7f\x3f\xcc\x4f\x18\x9c\x98\x47\xa7\x5f\x18\xf3\xe3\x5e\x60\x7e"
+  "\x69\xe3\xfb\x8f\x0b\xf3\x7f\xce\x74\xc5\xfc\x33\x9d\xc0\xfc\x33"
+  "\xe8\x0e\x73\x07\xfa\x6b\x9a\x53\xa7\xdf\x1c\x76\xb4\xc4\x45\xb7"
+  "\x23\xae\xf4\xdb\x43\x9a\xeb\xdd\xb5\xb4\x4c\x6a\x47\xdc\xb7\xac"
+  "\x84\xd0\x4d\x2b\x21\xd2\xaf\x41\xf8\xef\x36\xf4\xdf\x4f\x9f\x07"
+  "\xd9\xf1\x70\x70\xff\x4d\xa7\x41\x6e\xc3\x36\x6e\x7b\x38\xd1\xaf"
+  "\x32\xbe\x09\x0e\x9c\x29\x93\x68\xee\x96\x9e\xdb\xb1\xaf\xe3\x06"
+  "\xdc\x9e\xc0\x6c\x95\xf5\xd9\x62\x5e\xe5\xa4\x3a\xaf\xb2\xcb\x65"
+  "\x5e\xe5\xf7\xa7\x95\x79\x95\x7b\x04\x46\xf9\x5a\x7c\xe6\xff\xb1"
+  "\x9b\x79\x95\x8a\x8b\xce\xab\xf0\xf9\x94\x33\x10\xd0\xbe\x2c\x71"
+  "\xd0\x73\xca\xbc\xca\xf3\x4b\xbf\xdf\xbc\x4a\xdb\x32\x93\xf4\x3c"
+  "\xe2\xb3\xe6\x1e\xc4\xe7\xb3\xde\xe2\x73\xac\xbe\xa7\xf3\x2a\x6a"
+  "\x8c\x55\xe3\x2a\xd9\x1c\xc5\x56\x5b\xce\x2c\xd9\x7d\x2e\x85\xec"
+  "\xed\x8c\xfe\x5f\xdf\x91\x4f\xf6\x6e\x3e\xa5\xce\xff\xa7\x36\x9f"
+  "\x42\x36\xa7\xc6\xd9\x1f\x47\x8c\xfd\x97\xc5\xd5\xf6\x8e\x3f\x2e"
+  "\x62\xec\xf1\x94\x9e\xf6\xaf\x2e\x80\xf9\x06\xf7\x39\x14\x81\xb9"
+  "\xf5\x2b\x9a\x73\xf1\x6e\x1e\xa5\x2e\xe1\xa7\x36\x8f\xf2\xe3\xc3"
+  "\xdc\xba\xcf\x15\xf3\xcf\x1f\x11\x98\x7f\xbe\xe4\xfb\x63\x1e\x2d"
+  "\xbb\xcf\x9d\x08\xcc\xeb\x8e\xd3\x5c\x8b\x77\xf3\x27\x75\x5e\xf6"
+  "\xa5\xff\x7b\xf3\x27\x3f\x3e\xcc\xeb\xb6\xbb\x62\x7e\x62\xa1\xc0"
+  "\xfc\x44\xfc\x25\xc0\x7c\x83\xfb\x9c\x89\xc0\xbc\xfe\x23\xea\x7b"
+  "\x79\x37\x6f\xf2\x85\xcf\x4f\x6d\xde\xe4\xc7\x87\x79\x7d\xbe\x2b"
+  "\xe6\x5f\xfc\x5a\x60\xfe\xc5\x9c\xef\x8f\xb9\x59\x76\x9f\x2b\x11"
+  "\x98\x9f\x3a\x44\x73\x2b\xde\xcd\x97\x7c\xf1\x93\x9b\x2f\xf9\xf1"
+  "\x61\x7e\x2a\xcb\x15\xf3\x93\xb7\x0b\xcc\x4f\x9a\x2f\x01\xe6\x1b"
+  "\xdc\xe7\x48\x04\xe6\x0d\x6f\xd1\x9c\x8a\x77\xf3\x24\x5f\xec\xfb"
+  "\xa9\xcd\x93\xfc\xf8\x30\x6f\xd8\xe0\x8a\xf9\x97\x37\x0a\xcc\xbf"
+  "\x8c\xec\xe9\x98\x59\x1d\x2b\xab\xe3\x63\x3e\x56\x0e\xc0\x3e\xbb"
+  "\xdb\xdc\x88\xc0\xfb\xf4\xcb\xbc\xcf\xee\xf5\x58\xb9\xce\xff\xa7"
+  "\x32\x3f\xa2\x62\x4d\xe3\xe5\x1f\xc7\x58\xf9\xb4\xdb\xf3\xcf\xaf"
+  "\x26\x88\xb1\xf2\x57\xe1\xdd\x61\xed\xe9\x5d\x84\x2a\x1c\x6b\xaa"
+  "\xef\x22\x3c\xbd\x12\x71\x44\x3d\xa0\x77\x11\xe8\x9d\x04\x4f\xef"
+  "\x23\xd0\x7b\x08\xea\x3b\x09\xda\xf7\x11\xcc\x56\x66\xa3\x77\x12"
+  "\x68\x9c\x5c\x19\xff\x0c\xa8\xef\x26\xd0\x3b\x08\x69\x27\xc0\x97"
+  "\x30\xa2\xf7\x0f\x68\xbc\xfc\x43\xbf\x83\x90\xe7\xf8\x31\xbc\x83"
+  "\xd0\xe8\x7f\xb1\xb1\xf2\x9d\x3b\x86\x03\xea\x5b\xe7\x3c\x55\x7b"
+  "\xee\x2c\x20\x9b\x23\x8c\xfc\x1a\x85\x1d\xee\x9a\x5b\x2a\x55\xa7"
+  "\x94\xc1\xd3\xab\xc1\x5f\x9d\xbf\x20\x1b\x44\xbf\xec\x67\x47\x3c"
+  "\x37\x3d\x24\xe6\x31\x1c\x5f\xc7\xf9\x36\x3d\x9c\xe8\x47\xbf\xdd"
+  "\x3f\xf0\xf7\x52\x89\xe6\x1e\x8b\x16\xc1\xd4\x17\x4e\xc1\x8c\xaa"
+  "\xe6\xe3\xc0\x6d\x6a\xdb\xac\x19\x98\xd7\xd8\xbe\xed\x9e\x58\x47"
+  "\xe0\xac\xd0\xa6\xc0\x59\x26\xc2\x6d\xd3\x69\x00\xb2\x2f\xc2\xad"
+  "\x3a\xa5\xa0\x13\x2f\x8e\x95\xa4\xcc\x6d\x74\x6b\x53\x1f\x7b\x8d"
+  "\x59\xfe\x19\xc4\x6c\x99\x2b\x66\x05\xde\xce\x6f\xa8\xef\x73\x2f"
+  "\x33\x49\x05\x68\x53\xab\xef\x46\xcc\x7e\xd5\x5b\xcc\xbe\x29\xf7"
+  "\x02\xb3\xf4\x1e\x62\x56\xde\x03\xcc\xe2\x3c\x60\x56\x86\x79\x8b"
+  "\x15\xcc\x4a\x10\xb3\xed\x4e\xcc\xbe\xeb\x21\x66\xee\x63\xd8\xcb"
+  "\x09\xb3\x6f\xbb\x5d\xff\xa5\x7b\xcc\xa2\x7b\x68\x67\xd1\x3d\xb1"
+  "\xb3\xd2\xae\x98\x45\xa3\x9d\x45\x2b\x76\x16\x8d\x76\x16\xad\xb1"
+  "\xb3\x6f\x7a\x88\x99\xfb\x18\xf4\x72\xc2\xec\xdf\xe1\x5e\x60\xd6"
+  "\x43\x3b\x8b\xee\x81\x9d\x9d\x30\x78\xc0\x0c\xed\x2c\x5a\xb1\xb3"
+  "\x68\xb4\xb3\x68\x8d\x9d\x1d\xef\x21\x66\xee\x63\xc8\xcb\x09\xb3"
+  "\xb3\xdd\xff\xfe\xbb\x5b\xcc\xcc\x3d\xb4\x33\x73\x0f\xec\xec\x44"
+  "\x7c\x57\xcc\xcc\x68\x67\x66\xc5\xce\xcc\x68\x67\x66\x8d\x9d\xbd"
+  "\xdd\x43\xcc\xdc\xc7\x80\x97\x13\x66\xcd\x39\x5e\x60\xd6\x43\x3b"
+  "\x33\xf7\xc4\xce\xca\x3c\x60\x86\x76\x66\x56\xec\xcc\x8c\x76\x66"
+  "\xd6\xd8\xd9\xba\x1e\x62\xe6\x3e\x86\xbb\x9c\x30\x3b\xdf\xed\xfa"
+  "\x4f\xdd\x61\xc6\xf1\xc2\xbe\xa3\x47\xcc\xda\x5c\xfb\x8d\x76\xec"
+  "\xc7\xd3\x33\x2f\x8f\x78\x3d\x65\x05\xb6\x5e\x0e\x26\xac\xa8\x3f"
+  "\x48\x78\x55\xa7\x1c\xf2\xd8\x6f\xa4\xe7\x62\x88\x3b\xd0\xb3\xb1"
+  "\xb4\x93\xbd\xe8\x2f\xde\xd7\x1d\x56\x17\x7f\x1e\x96\xbf\xd4\x89"
+  "\x95\xfa\x3c\xec\x92\x62\xf5\x71\x6f\xb1\x6a\x69\xf6\x0e\xab\xe8"
+  "\xf4\x8b\x63\x15\x5d\x7e\x61\xac\x4e\x18\x9c\x58\x1d\xd7\x60\xd5"
+  "\x35\x8e\xf5\x1c\x2b\xb7\xf8\x75\x59\x61\xd5\x5a\xdc\x1d\x56\xf6"
+  "\x80\x7b\x62\xe9\x37\xef\x77\xe1\xd8\x97\xdd\x1f\x17\x9d\x59\x07"
+  "\xa1\xcf\xd4\x41\x24\xfd\xbe\x79\xd7\x6a\x9b\x84\x75\xfc\xf2\x83"
+  "\xda\x06\x68\xff\x3a\xb8\x3f\xfd\x7e\x86\xfb\xc9\x87\x83\x0d\xd5"
+  "\xf1\x4d\xdc\x27\x6e\x46\x8c\xaa\x9a\xcb\xb0\x4d\xfa\x99\xab\x9a"
+  "\x5f\x85\xb6\x15\x71\xf0\xe1\xb1\xd3\x88\x0b\x6b\xaf\x6e\x2c\x83"
+  "\x22\xbc\x6f\x59\xf9\x2a\x38\xbe\x36\xf5\x5f\x90\x02\xd2\x19\x7d"
+  "\x5b\x02\x8d\x9d\x27\xa5\x80\xff\xec\x46\x66\xab\x6a\xfc\x00\x5e"
+  "\xb8\x0f\x42\x0f\x61\x4f\x96\xda\x9a\x8f\x95\x1f\xa2\xb1\xf2\xdb"
+  "\x2e\xf8\x3c\xaf\x19\x2b\xf3\xdf\xcb\x26\x21\x36\xff\x76\xc3\x06"
+  "\xc7\xe2\xd8\xd6\xfd\xee\x6a\x46\x6c\x9a\x55\x6c\xbe\x81\xd4\x47"
+  "\x09\x1b\xab\x73\xac\xac\x60\x93\x4f\x3e\x2f\x49\x33\x56\x3e\xa3"
+  "\xc1\x46\xf9\xad\xaa\x0b\x36\xea\x5c\xc6\x2a\x13\x3d\x23\xef\x32"
+  "\x56\xf6\x6e\x2e\xa3\xbd\xdb\xdf\x8a\x70\x3b\x42\x1b\xb9\x0b\xed"
+  "\x68\x6d\x32\xb7\x23\xd1\xfe\x41\xb3\x50\xdf\x4b\xc1\xcf\xda\xcf"
+  "\xfc\x0c\x62\xd0\x86\xb6\x46\xb1\x28\x0d\xeb\x49\x58\x12\x6e\x77"
+  "\x6d\x6f\x6f\x9f\xdf\x0c\x12\xfa\xac\x99\x84\x5d\xc7\xd7\xc1\x86"
+  "\x4c\x8c\x55\xd5\xf3\x3e\x43\x7c\xce\x42\x75\x93\x82\xcd\xea\xcf"
+  "\xe0\x8c\xbe\xdd\xc6\x1e\x36\xf5\x9f\x88\x7a\x8a\xb1\xc7\x7f\x01"
+  "\xfd\xf6\x05\x7d\xde\x0b\x8b\x60\xc6\xec\x24\x66\xe3\xef\xf2\xa0"
+  "\x8d\x51\x3c\x23\x7f\x58\x95\xf4\x1e\x74\x6c\x9b\x15\xda\x1e\x78"
+  "\x4f\xec\xa1\x64\x00\xf2\x89\x84\x45\x9f\xc7\x9c\xd8\xd1\xef\xf6"
+  "\xb4\x73\x1d\x5d\x7c\xe1\x43\x1f\x78\xb6\xaf\x79\xd6\x5e\xcd\x77"
+  "\xe4\x2b\xf6\x95\xef\xed\x7c\x87\x3a\x1f\x85\x18\xd2\x6f\xf5\xd2"
+  "\x3e\x01\xe9\xf9\x5e\x63\xd8\x01\x5e\x60\x98\x7e\x71\x0c\x5b\x54"
+  "\x0c\xcb\x2f\x8e\x61\xc7\x7e\x0f\x18\x16\x6b\x30\x8c\xd3\x60\x58"
+  "\xa6\x60\x58\xa2\xc1\x70\xfb\xc5\x31\x74\x1b\x4b\x5f\x56\x18\x3a"
+  "\x2e\x3c\xff\xe1\x11\xc3\xe8\x1e\xd8\xe1\xb7\x0a\x86\xd1\x3d\xb0"
+  "\x43\x96\xde\x15\xc3\x68\xad\x1d\x96\x3a\x31\x8c\x56\xec\x30\x5a"
+  "\x63\x87\xd1\x3d\xb0\x43\xb7\xb1\xf5\xe5\x84\xa1\x0c\x1b\xbd\xc0"
+  "\xb0\x07\x76\xf8\xb9\x8a\xe1\xc5\xed\x50\xd6\xcd\xf4\x80\xa1\xc6"
+  "\x0e\xb1\xef\xe2\xc4\x50\xb1\xc3\x68\x8d\x1d\x46\xf7\xc0\x0e\xdd"
+  "\xfa\x2a\x97\x15\x86\xd2\xec\xde\x63\x68\xee\x81\x1d\x1e\x50\x30"
+  "\x34\x5f\xdc\x0e\x65\xbd\xa1\x2b\x86\x66\x8d\x1d\x9e\x88\x77\x62"
+  "\x68\x56\xec\xd0\xac\xb1\x43\x73\x0f\xec\xd0\x6d\xec\x7d\x59\x61"
+  "\x28\x5f\x78\xfe\xdf\x33\x86\x3d\xb0\xc3\x34\x15\xc3\x1e\xd8\xa1"
+  "\x5c\xe9\x01\x43\xad\x1d\x96\x69\x30\x54\xec\xd0\xac\xb1\x43\x73"
+  "\x0f\xec\xd0\x6d\x2c\x7e\x59\x61\xd8\xa7\xb6\x27\x18\x62\x3f\xbb"
+  "\x6b\xbf\xb4\xd9\x89\xa1\x16\x3f\xf7\xbe\x68\x0c\xf6\x51\x09\xbb"
+  "\x79\x76\x90\xba\xe2\xd7\x77\x13\xe1\x17\x4e\xcf\xe3\xbe\x73\xf6"
+  "\x49\x39\x76\xca\xf3\x1c\xc2\xec\x50\x02\x00\xf5\x4f\xd5\xfe\x28"
+  "\x3d\x53\xed\xec\x8f\x3e\xf0\xff\x69\x7f\x54\xee\x97\xd5\x7b\xec"
+  "\x94\x38\xd8\x2d\x76\xae\xb1\x2f\x06\x63\x62\xf7\xd8\x19\xcc\x5d"
+  "\xb1\x8b\x2e\x76\x62\x27\xe2\x9e\xc0\xee\x84\x41\x8d\x7f\x02\x3b"
+  "\x25\xfe\x5d\x10\xbb\xcb\x39\xfe\x5d\xd5\x6d\xfc\xcb\x92\x1c\xa5"
+  "\xb8\x97\xe1\x6e\xc1\xbd\xa2\x43\x82\xdb\x0a\x24\x87\xf8\xf6\x82"
+  "\xd0\x67\xf7\xfb\x7d\xd9\x53\xe1\x21\x44\xc3\xd6\xcb\x01\x44\xa7"
+  "\xf2\xe8\xe8\x0f\x80\xe9\x16\x3f\x5d\x3c\xad\x35\x42\xb4\xfd\x54"
+  "\x5e\x7e\xeb\x21\x0a\xeb\x2c\xe8\x24\x48\x17\x74\x51\x7d\x89\x8e"
+  "\x65\x1e\x8e\xc3\x34\x83\xc2\x93\xaf\x6d\xd8\x21\x49\xc4\xcb\xbd"
+  "\xec\xab\x14\x1a\x63\x47\x06\x18\xb5\x65\x23\x2f\x2a\x53\xa5\xeb"
+  "\x4f\x74\x1d\x7d\x75\xe9\x1d\x3a\x39\x54\x4b\xc7\x6e\x01\x2d\xdd"
+  "\xd5\x0a\x3f\x93\x4b\x3d\x46\x01\xf8\xe9\x8c\xa2\x2e\x29\x92\x5a"
+  "\x17\x1f\xce\x73\xc0\xfb\xa5\xc8\x33\xdc\x85\x67\x5f\x00\x5f\xa4"
+  "\x27\xbe\xbe\x89\x5c\x6e\xa2\xf7\x65\x7d\x4f\xca\x9c\xbf\x4e\x8e"
+  "\x70\x48\x10\x21\xea\x05\x72\x41\xa7\xcc\x46\xc8\x72\x2d\x63\x80"
+  "\xda\x5e\x5a\x3a\xa2\x61\x52\x27\x8d\x9f\xa8\x5b\xbd\x01\xe5\x98"
+  "\xa1\x95\x43\xd0\xc1\x64\x85\xce\x1f\xeb\x15\xd9\x89\x65\x8e\xaf"
+  "\x4d\xa5\x4b\xeb\x80\x21\x88\x85\xa5\x3a\x11\x40\x69\x87\x81\x88"
+  "\x41\xa3\xd2\x16\x51\x5a\x9e\xbe\x3a\x9d\xb5\x40\x69\x2f\x47\xe6"
+  "\xe1\x62\xa4\x1d\xe4\x58\x2f\xcf\xec\xe4\x9b\x41\xdf\x94\x52\xda"
+  "\x21\xc3\x3e\x98\xf3\x6d\x40\xdb\x92\x74\x46\xa5\x1d\x06\x13\x2d"
+  "\xe6\x31\x8b\x7a\xf9\x77\xe2\xda\x21\xc9\x74\xcf\xa2\xa1\x0d\x10"
+  "\x6d\xfc\x8f\xfd\x58\xb7\xd9\x5d\xe9\x0d\xee\xf4\x81\x82\xfe\xc3"
+  "\x5a\xa4\x8f\xed\x4a\xef\xef\x4e\x1f\x24\xe8\x8f\xd4\x20\xfd\x9c"
+  "\xae\xf4\xf6\x41\x6e\xf4\xd7\x08\xfa\xea\x4a\xa4\x8f\xeb\x4a\x6f"
+  "\x74\xa7\x0f\x16\xf4\x9f\x92\x8e\xcc\xeb\x4a\x1f\xe5\x4e\x3f\x44"
+  "\xd0\x7f\x54\x81\xf4\xf1\x5d\xe9\xd3\xdd\xe9\x87\x0a\xfa\xbf\x95"
+  "\x23\x7d\x82\x3b\x7d\x11\xa7\x85\x51\x0a\xed\xb5\x82\xf6\x13\x0b"
+  "\xd2\x26\x7a\xa8\xab\x5e\xe1\x1d\xa1\xd0\x87\x08\xfa\x0f\x66\x22"
+  "\xfd\x12\x0f\x58\xb9\xd3\x0f\x13\xf4\x0d\xf5\x48\x9f\xe4\x01\x2b"
+  "\x77\xfa\xe1\x82\xfe\x78\x38\xd2\x27\x7b\xc0\xca\x9d\x7e\x84\xa0"
+  "\xff\xdc\x88\xf4\x29\x1e\xda\xde\x95\x7e\xc0\x89\x00\xa4\x5b\x5b"
+  "\x90\xa1\xda\x8f\x4b\xbb\xbb\xf3\x1e\x29\x78\x7f\x41\x36\x94\xee"
+  "\xa1\xdd\xdd\xe9\x47\x09\xfa\x7a\x3b\xd2\x6f\xe8\x4a\x0f\x3a\x41"
+  "\x0f\x53\x14\xfa\xd1\x82\xfe\x54\x13\xd2\x6f\xf4\xd0\xf6\x74\xdf"
+  "\xa2\xd8\x69\xa8\xa0\xfd\x67\x09\xd2\x6e\xf2\xd0\xee\x5a\xda\x30"
+  "\x41\x7b\x3e\x0b\x69\xb3\x3c\xb4\xb9\x96\x76\x8c\xa0\x6d\x8c\x43"
+  "\xda\x1c\x0f\xed\xad\xa5\x1d\x2b\x68\xcf\xf8\x20\x6d\x9e\x07\x79"
+  "\x47\x69\x68\x4d\x82\xf6\x5b\xd2\xab\x7c\x0f\xb8\x68\x69\xc7\x09"
+  "\x5a\x5b\x24\xd2\x16\x7b\xc0\x45\x4b\x3b\x5e\xd0\xfe\x3b\x19\x69"
+  "\x4b\x3c\x60\xa2\xa5\xbd\x8e\x0d\x38\x67\x52\x7c\xeb\x76\x77\x5a"
+  "\xd4\x01\x0b\xfa\xa1\x0a\xf4\x85\xe1\x2c\xb3\xf9\x58\x91\xf0\x6b"
+  "\x3b\x89\x4e\xa5\x61\x92\xfd\x67\x9a\x38\x30\x81\x65\x9e\xae\x51"
+  "\xfc\x5f\xa9\x3b\x3f\x26\xc9\x5a\xda\x89\x2c\xbb\xaf\x1a\xff\xf6"
+  "\x75\xa5\x35\x68\x69\x27\xb1\xcc\xf6\x0d\x0a\x6d\x59\x57\x5a\xff"
+  "\x4e\x5a\x96\xd9\x61\x46\x9a\xfd\x85\x8a\x5f\xd5\xc8\x39\x45\xc3"
+  "\x6f\x32\xcb\x64\x3e\x0a\x3f\x4b\x57\x7e\x46\x2d\xed\x14\x96\xdd"
+  "\xef\xa8\x42\x5b\xde\x95\x36\x4a\x4b\xfb\x33\x96\x0d\x6a\xfd\x2b"
+  "\xba\xd2\xa6\x6b\x69\xa7\xb2\x6c\x29\x47\xa1\xad\x74\xa7\x2d\x14"
+  "\x31\x48\x52\x70\x9a\xc6\xb2\xe5\x38\x85\xb6\xc6\x25\xc6\x4a\x3a"
+  "\x6e\x63\x85\x82\x6e\x3a\x1b\xd0\xda\xa0\xe0\x59\xeb\x12\x5b\x33"
+  "\x74\x83\x28\xa6\x14\x10\x9e\x4f\x4d\x2d\x41\xda\xeb\x15\x7e\x47"
+  "\xdd\x63\x9f\x22\xdf\x0c\xbc\x77\x4c\x8d\x4f\x18\x77\xac\x9e\xfa"
+  "\x3d\x49\xe3\xe1\xea\xd3\xf2\xa0\x5a\x11\x1b\x95\x75\xbf\xe4\x00"
+  "\xee\xe3\x1d\x25\xd3\x6a\x62\x9a\x99\x5d\x9b\xb6\x45\x62\x35\x93"
+  "\x9a\x41\xa6\xef\xf5\xb1\xc0\x05\x1b\xad\x98\xde\x14\x36\xbd\xb8"
+  "\x25\x7b\x90\xd5\xaa\xfb\x57\x03\x7d\xbf\x09\xcf\x1b\xad\xb0\xf9"
+  "\x28\x9d\x6f\xc9\xa0\xf5\x49\xa2\x74\x1d\xb9\xbe\x16\x5a\xcf\xa4"
+  "\x08\xaf\x33\x71\xe7\x6b\x87\x24\x61\x1f\xf8\x29\x88\xb2\xac\xb4"
+  "\xc3\xa9\x14\x90\xf8\x1a\x78\xf2\xe0\x1b\xd8\xb2\xc4\x48\x94\x85"
+  "\xbe\xd1\x9a\x50\x87\xd7\x5c\x16\x5a\x7b\x21\xc7\xf7\x98\x65\x79"
+  "\x1b\xd1\x6c\x6e\x0a\x5c\x0c\xec\x89\xdf\x7e\x95\x94\x0a\x23\x4e"
+  "\xcb\x83\x37\xa9\xdf\xaf\xe2\xdf\xac\xfa\x36\xf1\x26\xfe\xbd\x2a"
+  "\x39\x60\x9c\x23\xd0\xf7\x98\xfb\xf7\xaa\x44\x39\x01\x01\xe7\x68"
+  "\x4d\x9f\xe2\xe4\x62\xfe\x3d\x2c\x39\x80\xaf\x23\x84\xf2\xd6\xb0"
+  "\xd0\x69\x65\x8e\xb6\x0d\xe9\xb4\x66\x9d\x25\xf5\x34\xd4\x29\xf7"
+  "\x88\xbf\xe0\x3b\xf8\x24\xf1\x23\xbe\x2a\x4f\xca\xd7\x34\x32\xb9"
+  "\x98\xda\x03\xdb\xa6\xac\xc7\xdf\xbf\x92\x07\xd7\xf2\xef\x5f\x65"
+  "\x07\x18\xad\xba\xeb\xb2\xf8\xf7\xaf\xd4\xfa\xf4\x9c\x47\x3a\xf1"
+  "\xf0\xfc\xad\x5f\xf0\x63\xdb\x7c\x6d\xc8\x3f\x1d\xfb\xbf\x9b\x04"
+  "\x3e\x01\x9b\xac\xba\xe1\x25\xca\x79\x9e\x55\x37\xd2\xaa\x9c\x97"
+  "\x58\x75\x1f\x9b\x95\xf3\x52\xf5\x1b\x64\x9e\xbf\x89\xe6\x5b\x89"
+  "\x78\xd4\x3b\x5e\x88\x33\x50\x7f\x9d\xcb\x13\xe8\x5b\x69\x1c\x0e"
+  "\xba\x53\x72\x20\x8e\xfb\x7d\xeb\x45\x5b\x05\xfa\xe2\xd1\x4f\x39"
+  "\x36\x29\x47\x46\x34\x5c\xe7\x02\xe2\xcb\x58\xd6\x6c\x2b\xd7\x07"
+  "\x39\x30\x8c\xd2\x38\xb6\x88\x3f\x1b\x38\xdb\xca\xf9\x6e\x5b\xec"
+  "\xf2\xde\x69\xc4\xe4\x29\x3f\x9b\x3a\x6d\xfa\xf5\x33\x6e\x58\x78"
+  "\xdf\xfd\x09\x0f\x2c\x7a\x30\x71\xf1\x43\x0f\x2f\x79\x64\xe9\xb2"
+  "\xa4\x47\x97\xaf\x48\x7e\x6c\xe5\xaa\x94\xc7\x57\xd3\x43\x83\x4e"
+  "\x59\x5f\x98\xa9\x6b\x96\x00\xb1\xbc\x85\xca\xe0\xdf\xf9\xa5\x34"
+  "\x81\x7b\xe0\x06\xd9\xe8\x79\x4c\x50\x1d\x0c\x40\xeb\x85\x34\xca"
+  "\x81\x27\x68\xfd\x12\xd4\x41\x5d\x75\x7e\xb4\x85\xd6\x61\xab\x97"
+  "\x03\x6b\xab\x9a\xa2\x2d\xb4\x6e\xe0\xc1\xe0\x06\x08\x1d\x05\xba"
+  "\xd3\x72\xa0\x85\xee\x17\x8d\x01\x28\xc7\xbc\x9e\x78\x8e\xf2\x87"
+  "\xe0\x67\x83\x58\x53\x4e\x10\x6b\x24\xfe\x39\xb9\xac\xa1\x69\x4d"
+  "\x22\x64\xe2\x35\xea\xa5\xff\x29\x39\x68\xdb\x41\xec\xf9\x3b\x32"
+  "\x20\xa4\x30\x97\xd5\x6f\x08\x62\xf5\x4f\xe4\xb2\xc6\xa2\x20\x66"
+  "\x0d\xcd\x01\x9f\x96\xec\x20\xb3\x55\x0e\x2c\xe6\xb6\x85\xf7\x1d"
+  "\x83\x02\xa3\xb6\xe0\xbd\x49\x76\xd0\x17\xe1\x35\xa6\x35\x1f\x34"
+  "\x0a\xb9\xf7\x9c\xb5\xf5\x41\x7e\xe1\xac\x7d\x89\x2e\x13\xcb\x11"
+  "\x78\x04\xbd\x55\x8e\xbd\x08\x2c\xaf\xa9\xda\x56\x07\x56\x39\xa8"
+  "\x8c\xd6\x53\xc2\xf2\xfc\xaa\xf3\x1a\x81\xf8\xed\x5e\x6e\xeb\xb3"
+  "\x62\x28\xb3\x23\x6d\x9e\x63\xcd\x12\x1d\xd2\x24\x23\xef\x66\x6d"
+  "\x7d\x4c\x8b\x1e\x49\x36\x2e\x7d\x6c\xc9\x92\x71\xfd\xc1\xc4\x8f"
+  "\xa0\x5d\x43\x30\x19\xf9\xc1\xb3\xb9\xac\x1c\xeb\x69\xc1\xfa\x56"
+  "\x1c\xc1\xd1\x07\xea\x06\x60\x9d\xb2\x4e\xc9\xd7\xf8\x62\xfa\x7e"
+  "\x3c\xdf\x8f\xb2\x57\xf0\xf5\xc9\x64\xd3\x0d\x2c\x3b\xa8\x1c\xe5"
+  "\xa4\x78\x65\xa4\xef\x33\x9e\x5b\x35\x47\x87\xf5\xce\x41\xba\x0a"
+  "\xe3\x50\x08\xc3\x7c\xdb\x50\x8e\x12\x3c\x27\xfa\x9b\x09\x47\xa4"
+  "\x2f\x17\xf5\x32\xf1\xb5\xb5\xb0\xad\x2c\x05\x41\x6c\x53\x4b\xf6"
+  "\x35\x49\xf4\xfd\x56\xbe\x06\x0d\x5e\x63\xbb\x54\x20\x6d\xd6\xb9"
+  "\xb4\x39\x3a\x5a\x6f\xb3\xc8\xc9\x33\x8a\x64\x22\x39\x68\x2c\xfc"
+  "\x21\xf6\x26\x1d\xed\x71\x30\xc1\x06\xba\x0f\xeb\x01\xf2\x73\x59"
+  "\x31\xee\xf9\xb8\xe7\x7d\x80\xf7\x0e\xe3\x5e\x81\xe9\x95\x78\xfc"
+  "\x00\x8f\x87\xeb\xf9\xb3\xd5\x60\x92\x7b\xc5\x5a\xd6\x30\x29\x0f"
+  "\x46\xf3\xf5\x3c\x53\xe1\x37\x75\xf2\xd8\x2c\x92\x9d\xbe\xd5\xcc"
+  "\x06\x05\xcb\x2e\xdf\x94\x95\x87\xa4\x00\xde\xc7\xe3\x26\x71\xd4"
+  "\xee\x43\x6a\x71\x6f\x16\xe7\x43\x23\xf1\x3c\x41\x39\x8f\xc5\x7d"
+  "\xde\xc5\x77\x77\x7e\xdd\xed\x43\x2b\x7a\x4e\xdb\x93\xdd\x24\xf7"
+  "\x8c\x2e\x24\x1d\xe4\xe1\x47\x41\x1e\xe1\xef\x9a\x3e\xbc\x41\xa4"
+  "\x8d\xde\x27\xae\x47\x5b\x94\x63\x23\xc8\xa1\xd8\x4e\x61\xc8\x3f"
+  "\xcc\x24\xd2\xc2\xa6\xe2\x71\x2d\xee\x1b\x5d\xcb\x37\x61\x7e\x53"
+  "\x08\xe1\xd9\x8e\xb1\x80\xb0\xb4\xca\xd7\xd4\x12\x46\x5b\x84\x6e"
+  "\xe9\xe8\xfd\x09\x4c\xab\x41\xdd\xca\x77\xea\xcf\x90\x43\xae\xfa"
+  "\x33\xa4\xd4\x4d\x7f\xb2\xc8\x17\x61\xbe\x90\x22\xa1\x2f\xfb\xcf"
+  "\xad\x49\xc0\xeb\x21\xfb\x90\xcf\x7e\xe3\x7c\xe2\x31\x94\x8f\x9f"
+  "\xb7\x9c\xc6\x71\x70\x22\xc8\xe4\x5f\x1a\xe5\xa1\x7d\x48\x67\xa9"
+  "\x6c\xa5\x5c\x21\x0b\xca\x87\x69\xc5\x24\xdf\x32\xe4\x8b\xd7\x25"
+  "\x48\x57\x5c\x0d\x67\x55\xd9\x78\x9e\x67\x1e\x42\x7d\x54\xe4\x25"
+  "\x9e\x94\x8f\x39\xeb\x55\x43\x79\x94\xb2\xdf\xc2\x74\x1a\x5f\x43"
+  "\xda\xbf\x41\x5f\x6d\xb7\x02\xe9\x24\x1d\xab\xed\x11\x68\x4b\x66"
+  "\x70\x50\x1c\x0c\x86\x08\xb4\xb7\xab\xea\xe4\xa1\xf9\x13\xd7\x42"
+  "\x04\xf1\x23\xff\x6d\x95\x87\xc6\x17\x91\x2d\x0a\x5e\x7b\xa9\x1e"
+  "\xc4\xff\x03\x1c\xd1\xd0\xb1\x90\xe4\xc1\xfb\x9a\x72\x73\x68\xdc"
+  "\xbc\x65\xb5\xa8\x2b\x96\x55\x82\xf9\x4b\xa9\xee\xd4\x9e\x78\xbf"
+  "\x0c\xf9\xd8\xe8\x1e\xad\xd7\xa2\xd4\xa7\x84\x7e\xeb\x41\xed\x41"
+  "\xf4\xb4\xae\x25\xff\x46\xad\x7c\xcd\x30\xde\x6e\x98\x9f\xf0\x60"
+  "\x58\x06\xf1\x48\xb3\x33\x3b\x43\x7f\xf4\xd2\x6a\x1b\xf6\x3f\x42"
+  "\x1e\x75\xc5\xe7\xda\x58\x2d\x3e\x98\xaf\x14\xf3\x97\x53\x4c\x26"
+  "\x7f\x82\x65\xfa\x51\x7f\x03\xd3\xb2\x1c\xd9\xc8\x63\xa5\x8d\xcf"
+  "\x2b\x21\x9f\x85\x28\x4b\x16\xf1\x41\x79\xca\x15\x5e\xf9\xf4\xfd"
+  "\x4a\x2d\xd6\x0a\xbf\x12\xc2\x9c\xdb\xf3\x6a\x5e\x27\xf4\x5d\x21"
+  "\x93\x0b\xc5\xbd\x32\xa4\x29\x63\xed\x66\x60\x6b\xe2\xc4\x3a\x6d"
+  "\xe2\xde\xbe\xb4\x56\x8e\x6f\xb9\xf0\x6b\x21\x77\xaf\x58\xc7\x1a"
+  "\x9c\x72\x87\x18\xd4\xef\xb4\x2b\x72\xef\xa3\xf2\xd8\xaa\x79\x3c"
+  "\x86\x52\x19\x94\x5f\xf0\xbb\xb6\x9e\xf8\xa9\x6d\x35\x11\xe5\x10"
+  "\xed\x75\x6d\x30\xa6\x97\x90\x2e\xf2\x76\x43\x3f\x7a\x2e\x8d\x74"
+  "\x31\xc4\x07\xf3\xef\xcf\xa4\xeb\x55\x74\x7d\x6d\x31\xf7\xb1\x9d"
+  "\xf7\xaf\x9d\x43\xf7\x69\x5e\x62\xcb\xc3\xa8\x4b\x0e\x80\xd1\x01"
+  "\x10\xd1\x9c\xc1\xeb\xb6\xb3\x79\xcd\x4c\xdd\x41\x3b\x00\xc9\x89"
+  "\x6d\x54\x86\xb2\xee\xc3\x58\xd3\x4c\xb2\xa2\xbf\xde\xc7\x5e\x8a"
+  "\x03\x92\x19\xfd\x99\x22\xdf\xb0\x30\x05\xfb\x7d\x54\x47\x6a\xcf"
+  "\x89\xc2\xf7\xe1\xbd\xe1\x87\x49\x76\x67\xbd\x87\x81\xb6\x8d\x79"
+  "\xbd\x11\x07\xc2\x8b\x70\x71\xf2\x0c\x21\xdd\xcf\x42\x5e\x3b\xc5"
+  "\xb5\xd0\x0d\x6a\xeb\xac\x20\x56\x49\xf4\x4e\xda\xe1\xbc\x6f\x98"
+  "\x8a\x65\x4f\x4a\xa2\x39\x18\x8c\xcf\xf6\x16\x0b\xf2\xdd\x49\x6b"
+  "\x96\x22\x8f\x32\x6a\x53\xa4\xdb\x4c\xfa\x88\xd7\x95\x8a\xdc\x9b"
+  "\x30\x9e\x87\xe3\x1e\xe9\xb4\xff\xe1\xeb\x5c\xf5\x6b\x98\xbb\xfd"
+  "\x13\xde\x59\x8e\x34\x33\x28\xeb\x35\x1b\xcf\xc8\xc3\x87\x28\xb1"
+  "\x43\xc1\x7a\xf8\x23\x07\xd1\x5e\x34\x3c\x9a\xdd\xb0\x2e\xe3\xfa"
+  "\xb8\x6a\xb6\x8e\xea\x8c\x79\xcb\x04\x9f\x61\xbc\xce\x5c\x9f\x32"
+  "\xb8\x0e\x54\xb2\x55\x58\xcf\x4e\x3d\x18\x16\xab\xe0\x5c\xe9\xd6"
+  "\x26\xaa\xef\xca\xa7\x75\xbf\xc8\x27\x61\xff\xf7\xa6\x96\x76\xa7"
+  "\x5f\x22\xec\x1d\x1c\xfb\x61\xb6\x22\x11\x6f\x15\xbf\x35\x4c\xdc"
+  "\x0f\x72\xd1\x61\xaa\xd3\x04\xae\xbf\x24\x4b\xda\x3c\x92\xa5\x8c"
+  "\xcb\x91\x66\x04\xbc\x57\x42\xe5\x5b\xe5\xe1\x11\x8a\xbd\xaa\xbc"
+  "\x64\xe2\xf5\x04\xfa\x2a\x92\x09\xcb\xce\xe2\xfe\x6f\x16\xc9\x36"
+  "\xa2\x8f\x22\x7b\x85\x2d\x83\xf2\x0e\xb1\xb5\x4a\x3c\x6f\x05\x9e"
+  "\x2f\xb1\x89\x75\x13\xfa\x63\xfe\xed\xc6\xfb\x88\x7e\x74\x02\xf9"
+  "\x68\xe3\xbd\xfc\xfc\x4e\xe3\x5c\xd4\xd5\xd3\x20\x23\x3f\x03\xe9"
+  "\xa8\xaa\x17\x8d\xf2\xe8\x1b\xb1\x8f\x41\x78\xed\xc4\x3e\xd2\x76"
+  "\x6a\x6f\xd2\x65\xec\x23\x4d\x6d\xc9\x1e\xb1\x44\xd5\x5b\x2c\x27"
+  "\x9f\xda\x5e\xe0\x33\x62\x2f\xea\x71\x99\x53\xb7\x46\xec\x55\xda"
+  "\x71\x3b\xb6\xa3\x01\xcb\x9b\xac\xd4\x6b\x3b\xd2\x63\x5f\x6c\xf4"
+  "\x48\x45\xf6\x3c\x85\xfe\x88\x8a\x83\x62\xab\x95\x99\xe4\x7f\x39"
+  "\x06\xc6\x04\x25\x6f\x89\x28\xcb\xf8\x80\x4a\x4b\x7d\x44\xbe\x06"
+  "\x1a\xa6\x91\x1f\x9c\x84\xd8\x73\xdf\x47\xeb\xf9\x2a\x69\x64\x3b"
+  "\xa2\x8c\xd1\xbe\x5c\x0f\xb1\xdf\xe3\xd4\x23\x63\xa4\x9b\x7f\x22"
+  "\x5f\x9c\x55\xb5\x41\xac\x31\x41\xba\x44\x3e\x95\xc6\x2a\xc8\x2f"
+  "\x40\xb1\x1f\x45\x66\xe3\x0e\x57\x5d\x19\xd5\x8a\xba\x32\x41\xc3"
+  "\x3b\xcf\x53\x9c\x2b\x12\x3e\x30\x5f\xa9\xdb\x57\x4a\xdd\x76\x2a"
+  "\x75\xfb\x4a\xa9\xdb\x76\x2c\x03\xdb\x6d\xd4\x2e\x4d\x3b\x62\xbb"
+  "\x8d\x1a\xa2\xd0\x97\x91\x2f\x77\xda\xeb\xc8\x5f\xab\xb6\xdc\xd5"
+  "\x5f\x8c\xba\x8a\xec\xc1\x29\xd7\xc8\x08\x37\x7f\x51\xe6\xd9\x5f"
+  "\x8c\x04\xa5\xbe\xc5\x6e\xb6\x51\x22\x64\x57\x62\x0b\xe2\x50\xd5"
+  "\xac\xac\xf5\x81\x69\xe4\x3f\xa9\x6c\x6d\x0c\x2a\x14\xed\xaa\xd8"
+  "\xf2\xc8\xef\xba\xe2\x30\xb2\x5c\x6b\xcf\x84\x35\xf9\x04\xe2\x41"
+  "\x98\xf2\x7e\x25\xa6\x09\x5c\x47\xe6\x93\x6f\xd0\xfa\x68\xa4\xcd"
+  "\x71\x30\xb2\x97\x91\x15\xae\xb6\x38\x72\xaa\x62\x8b\x4a\xd9\xa3"
+  "\x9e\x43\x8c\x22\x9c\xe5\x8e\x8a\x74\x2b\x97\xb0\x29\xe7\xdf\x72"
+  "\x16\x98\x3e\xa9\xc6\x34\xa2\xc7\xbc\x29\x98\x27\xc9\x2d\x3e\x66"
+  "\x91\x7c\x56\xd9\xd8\xc0\x7d\x56\x2e\xf7\x15\x29\x2d\x5c\x9e\x51"
+  "\xc9\x45\x4a\x9c\xc0\xb4\x08\x25\x2d\x4a\x89\x25\xaa\xde\x9c\x74"
+  "\x93\xa9\xc6\x73\xff\xc8\xd8\xa0\xf6\x8f\x38\x2f\xee\x8b\x46\xd5"
+  "\x2a\xf5\xa3\xb4\x09\x22\xcd\x98\x4f\x69\x99\xa2\x1d\x72\x18\x8f"
+  "\x57\xc6\x28\x25\x5e\x91\x7d\x49\x56\x79\x44\x29\xd9\x18\x5d\x5b"
+  "\xe5\xd1\xb4\x2e\xb4\xae\x3a\xbd\x8d\xc6\x10\x79\x78\x6f\x36\xf9"
+  "\x03\xf2\x17\xc6\x45\xc2\x6f\x18\xef\xe2\xc7\xc7\xc8\xef\x50\x3f"
+  "\x84\xee\x23\x5d\x24\xf9\x22\x4c\x7f\x9a\xd6\xef\x64\x5f\x1b\x90"
+  "\xef\xe8\x25\x4a\xde\x02\xde\x57\xf8\xda\xac\x57\xd3\xd4\x7c\x68"
+  "\xeb\x77\x52\x3e\xca\xaf\xfa\x2f\xf2\x5d\x76\xf2\x4d\xa2\xbc\x13"
+  "\x8a\x8e\xf3\x71\x83\xda\x2f\x6a\x97\x34\xb4\xb4\xfe\x01\xf7\x69"
+  "\xa1\xe1\xc2\x9f\x85\x0e\xa3\xbc\x1c\x3f\xf4\x95\xa9\xad\xec\x44"
+  "\xd1\x72\x90\x0b\xcf\xf2\x3e\x56\x88\x90\x33\x34\x45\xd4\x23\xf4"
+  "\x66\x5e\x0f\xe1\x53\xb3\x84\x2c\xd7\x84\x14\xb6\xf1\x7b\xbf\xa3"
+  "\xba\xd0\xbd\x2d\x9a\x7b\xb4\x06\x09\xde\xe3\xdf\xf2\x76\xcf\xe7"
+  "\x68\x4f\xec\x42\x4f\x6b\xef\xa2\x0f\x35\x14\xe6\xaa\xbe\x37\xd4"
+  "\xa6\xc8\xf9\xba\xea\x77\xb1\x5d\x66\x92\xef\xe5\xf7\x16\x29\x34"
+  "\x77\x29\x47\xee\xdf\x43\x4f\x8a\x76\x0d\x96\x94\xf6\x9e\xad\xd4"
+  "\xa3\x95\x8f\xb3\xbf\x8e\xc3\xb6\x0d\x3d\xa6\xb6\xad\xf6\x9c\xec"
+  "\x07\xcb\xf7\xa7\x6b\xae\xf7\x6b\xf9\x18\x36\x9f\x68\x48\x26\x11"
+  "\x23\x46\xd7\xba\xf7\xa9\x4f\xc9\x63\x1f\xa5\xb8\x24\xfa\xaa\x63"
+  "\xef\x56\xe6\x87\xc0\xb2\xfc\x8f\x18\x17\xc2\xf2\x55\x1f\xc3\x5a"
+  "\xcc\x40\xdf\x40\x3f\x25\x87\xf1\x75\x26\xe8\x9b\xf9\x5a\x1a\xf2"
+  "\x4f\x7b\xda\xac\x0a\xcf\xb0\x14\xd5\x6f\x90\x2f\xa9\x6a\xae\x53"
+  "\xfa\x74\x63\x4c\x85\x8a\x2f\x39\x23\x8f\x19\xe7\xda\x0f\x1b\x33"
+  "\xce\xd5\x67\x8c\xbd\xd1\xdd\x67\x60\xbf\x79\x43\x4b\x76\x98\xdd"
+  "\xa5\x1f\x80\x69\x17\xf6\x1d\x61\x35\x64\xa3\xb4\x06\x12\xf7\x4f"
+  "\x7c\xce\x6b\xcc\x56\x55\x66\xf2\x9b\xe7\xd6\xa8\xf3\x17\x63\x27"
+  "\x50\x5f\xcd\xb5\xbc\x31\x4b\x5c\x7c\x27\x95\xa7\xf2\x93\x81\xd6"
+  "\xd1\xc1\x76\xa0\xf9\x96\x31\x91\x8a\x9f\x2f\x76\xf1\x95\x4a\x0c"
+  "\x23\x3f\xe9\x1a\xab\xae\x19\xe6\x1a\xab\xc6\x0e\xe9\xea\x23\xc7"
+  "\x34\xf4\x3c\x56\x8d\xb1\x90\xdf\x52\x7d\xa4\xab\x2f\x18\xd3\x58"
+  "\xe8\xd2\x97\x1d\x93\xac\xf6\x65\x9d\x7e\x74\x8c\x4c\x3e\x0a\xcb"
+  "\x2f\x13\x65\x8f\x4d\xc0\xb8\x9f\xa8\x96\x6d\x45\x9c\xab\x8c\xa8"
+  "\x9b\xd9\x41\x35\x78\x6e\x56\xfa\x80\xdc\x36\xdb\x68\x2d\x11\x39"
+  "\x34\x0b\xf5\xaf\x3f\xe9\x99\x65\xe9\x59\xa8\x77\xc6\x8a\xf2\x73"
+  "\xcb\x3a\xdb\xf7\x3b\x6d\xbf\xb0\x20\x97\x6d\xc4\x72\x2a\xb5\x75"
+  "\xdc\x8c\x69\x5b\x94\x39\x04\xde\xb6\x9c\xd7\xd8\xe2\xa2\x5c\xd7"
+  "\xba\x89\x7a\x8c\xad\xa5\x7a\xd0\x98\x08\xcb\xcf\xa1\x7e\x0f\xad"
+  "\x83\x86\x76\x13\x5c\xd4\xa9\xf3\x43\x96\xb4\x66\x68\xfb\x57\xd7"
+  "\x24\x93\xaf\x54\xc6\x9e\x15\xd8\xdf\x71\x99\xeb\xbb\xf3\xd6\x58"
+  "\x63\xd2\xf2\xc5\x4b\x93\x17\x4d\x31\x2e\x5e\xba\x38\x79\xf1\xc2"
+  "\x25\x8b\x57\x2f\x4c\x5e\xbc\x6c\x69\xf8\x23\x0b\x1f\x5c\x7c\xbf"
+  "\x71\xd5\xc2\x15\xc6\x88\x94\xb0\x94\xfe\xe0\x24\xfd\xb9\x71\xe1"
+  "\x8a\x15\x8f\x3d\xf2\x40\x82\x71\xe9\xe2\xfb\x27\x2c\x7f\x60\xc5"
+  "\x03\xc9\xc6\x85\xcb\x97\x3d\xb6\x34\xc1\x18\x96\x30\x31\x2c\x62"
+  "\x7a\x42\x7f\xed\x1c\xda\x28\x7f\x68\x74\x9c\x6f\x68\xd8\x72\x1e"
+  "\x0c\x7e\xba\xa4\xe5\x7e\x29\x8b\x97\x8a\x39\xbb\x71\x37\x4e\xca"
+  "\x81\x24\x5a\x5f\x9d\xd6\xbf\x65\xd9\xa6\x58\x3c\xca\x44\x87\xf5"
+  "\x34\x16\xd1\x1a\xeb\x41\x2c\xa4\x25\x7b\x1c\xda\x7e\x38\x9f\x1f"
+  "\xc6\xb6\x30\x62\xdd\x42\xd8\xf9\x8a\x06\xec\xb3\x25\xd1\xfb\xde"
+  "\x45\xe7\x21\x20\x6b\x25\xc8\xb8\xfb\xe0\xee\x4f\xeb\xaf\x63\x9e"
+  "\xa9\x56\x79\x7c\xac\x98\x13\x1d\x57\xdb\x34\xf0\x8e\xb5\x2c\xeb"
+  "\x0e\xb1\x8e\x83\x3c\xee\x23\x75\x3e\x3a\xe6\x49\x88\x21\xfd\xac"
+  "\x93\xc7\xf1\xb9\xee\x27\x50\x97\x69\x3e\xf6\xdc\x3b\xb7\x44\x61"
+  "\x7f\xf0\x98\x65\x28\xbf\xf7\x51\xb3\x04\x3e\x28\x97\x7c\x70\x6d"
+  "\x04\x3c\x8b\x65\xad\x08\x66\x0c\xcb\xc8\x53\xe7\xd3\x68\xdd\x7b"
+  "\xac\xcb\x51\xa5\x1e\x6b\x78\x3d\x72\x59\x68\xce\x20\x94\x2f\x9b"
+  "\xcb\x53\xae\xd6\x01\xe5\x3e\x8a\x32\xf1\x75\xef\x49\x2e\x4f\x73"
+  "\x7d\x34\xdf\x75\x4a\x1e\xef\xeb\x58\x89\xed\x36\x5c\xac\xa3\xb4"
+  "\xa5\x50\xd8\x1f\xd6\x6b\x66\x11\x9e\x67\x9e\x05\x9f\xcd\xb4\x6e"
+  "\x77\xc6\x08\x76\xa4\xd9\x0e\xd5\x89\x47\xc1\xef\x71\xd6\xc4\xde"
+  "\x68\x68\x10\x75\x1a\x3f\x83\x7c\xc3\x6b\x0f\x1d\x95\xa9\x4e\x18"
+  "\x2b\x7c\x8a\xce\x76\x3b\xb7\x28\x3f\x1b\xc4\x9a\xd9\x0b\xda\x3e"
+  "\xd7\xf8\x17\xa9\x4d\xa8\xbf\x75\x0e\xe3\x54\x4b\xf6\xf8\x8d\x28"
+  "\xb7\x55\xe9\x1b\x37\xb3\xf6\x79\x9a\xbe\xd4\x78\xd2\xb3\xe6\x6e"
+  "\x78\x1b\x54\xde\xb4\x1e\x38\xe5\x11\xf8\x5f\xe7\x8b\x79\x9a\x34"
+  "\xfc\x1b\xdc\xf9\x13\x4f\x3c\x6f\x52\xcb\x11\xe3\xf0\xf1\xd4\x27"
+  "\x68\x42\x5d\x6e\xea\xa6\xbc\xd0\xec\x5c\x56\x5b\x8d\xe9\x5b\x5a"
+  "\x81\xc6\x17\xb5\x45\xb9\xc4\xff\x3a\xb3\x55\x36\xed\x24\xfe\x4f"
+  "\x04\x01\x6c\x40\x9a\x73\xd9\xe3\xac\x34\xbf\x8b\xf7\xd0\xfe\x83"
+  "\x8e\xba\xcf\x59\x2b\xfa\xfc\x73\x37\x7d\x8e\xca\xa6\x3e\x61\x0e"
+  "\xf2\x47\x1d\xda\xf2\x1d\xc6\x61\xbc\x9e\x98\x03\x26\x2a\x07\xcf"
+  "\x69\x4c\x56\x81\x3c\xcb\xd4\xf2\x18\xea\x7f\xa6\x43\xcc\xc1\x28"
+  "\xba\x15\x5e\x9d\xd2\x40\xeb\x2c\xb0\x83\xe8\xdf\x49\x46\xd2\x31"
+  "\xcc\xd3\xa8\xea\x14\xea\x7a\x2d\xd7\xab\x00\x30\xb1\xec\xeb\x92"
+  "\x8a\x06\x21\x1d\xea\x55\x21\xea\x13\xe9\x55\x4b\x76\x78\xb0\xaa"
+  "\x53\xa8\x6b\x35\x44\x87\x32\xf4\x2f\x5d\x1d\x25\x93\x8f\xac\x97"
+  "\xc3\x37\x93\x8e\xb1\x3f\xfc\xf2\x28\xbb\xe6\xb7\x47\x05\x4e\xe1"
+  "\x9b\xab\x6d\x02\x03\x67\xbb\x87\xc7\x6b\xda\xbd\x06\xf5\xb8\x3f"
+  "\xb5\xb3\x98\xab\x0e\xdf\x8c\xb2\xd5\xf0\xbe\xf8\x3a\xc4\x80\xc7"
+  "\xaa\xf0\xd9\x94\x5f\x69\xc3\x4a\x67\x1b\x86\x6f\xf7\xd4\x86\x6e"
+  "\x6d\xc7\xd7\xa1\x66\xd9\xe1\xfb\xc8\x56\x30\xcf\x31\x75\x0d\x6a"
+  "\x4f\x58\x62\x19\xb2\x9c\x03\x06\x2a\xa3\x3c\x80\xe8\x27\xf8\x78"
+  "\x2a\xc3\x5d\x8f\xcb\x8b\x01\x68\x2e\x9c\xf2\x85\x06\x50\xbb\x4e"
+  "\x98\xe9\x11\xdf\xfb\x5d\x64\x13\x6b\x72\x67\x4f\x88\x7d\x56\x59"
+  "\x93\x1b\xf3\xad\xbd\x90\x7c\xa1\x46\x11\x17\x2d\xa3\x48\x9f\x27"
+  "\xbc\x5e\x9d\x07\x40\x69\xca\x75\xc9\x39\x8c\x35\xee\xf3\xf9\xdd"
+  "\x3f\x5f\x98\xf0\x9d\xeb\xf3\x85\x09\xf5\xdd\x3d\x5f\x70\x2d\x77"
+  "\xe2\x64\x2a\xd7\x51\x34\x47\xe7\x2c\x7b\x62\x88\xc3\x43\xd9\x6a"
+  "\xfe\x89\xc5\xda\xf1\xcb\xc4\xf5\x24\x43\x15\xc6\x25\x76\xed\x1c"
+  "\x1d\x43\x3e\xe5\x3c\x66\x4f\x4c\x17\xfd\x15\xea\x07\x4d\x8c\x27"
+  "\x1a\xf7\x7a\x74\x6e\x86\x80\x77\xe9\xd0\xca\x2f\xfa\xcc\x02\x7a"
+  "\xd3\x14\x86\x77\xd2\x48\x2e\xc4\xc0\x3c\x5c\xf8\x00\x8c\xe0\xf4"
+  "\x0c\x37\x91\xa4\x5c\x37\xf1\x0b\xb9\x93\xbe\xf3\xfe\xf7\xd8\xae"
+  "\x12\xf2\x72\x7e\x36\xd0\x89\x33\x63\xb0\x86\x62\xe6\x05\x72\x33"
+  "\x50\xb3\x78\xda\x68\xb6\x31\x7d\x4e\x1f\xe4\x37\x83\x13\x33\x66"
+  "\x57\xf8\xab\xd7\x4c\x7b\x4d\x29\xae\xd7\xb8\xe9\xe7\x69\x0a\x18"
+  "\xa1\x4f\xe0\xaf\x6a\x8d\x5e\xd2\x99\x24\x15\xfb\x6b\x8b\xf4\x87"
+  "\xf4\x3e\xfc\xc4\x8f\xfe\xd8\x90\x9f\x09\xef\x1b\xe3\x3a\x09\x06"
+  "\x37\xaf\xd7\x90\x7f\x28\xc4\x1f\xb9\xfd\x02\x75\xec\xed\x36\x5c"
+  "\x73\x3e\x42\x1c\x46\x26\x5e\x42\xfe\x17\xde\x8c\x35\x57\xa9\xa7"
+  "\x4e\xf5\x18\xd9\xe8\x89\xd4\xd9\xfe\xa3\x66\xab\x49\x5a\x0d\x75"
+  "\xde\x0f\xab\x70\xbd\x1e\x9b\xe7\x7a\x3d\xae\xe1\x52\x88\x6e\xa1"
+  "\x3f\x69\xd6\x81\x88\xd9\xbe\xce\x44\x3f\x37\x93\xf1\xcb\x72\x33"
+  "\x21\xe7\xa6\x48\xa3\x07\x18\x1f\xa9\x49\x96\x3d\x53\xff\x30\xdb"
+  "\xd0\xf5\x8a\x41\x8c\x68\xf2\xef\x72\xf3\x17\x6e\x69\x74\xdd\xd7"
+  "\xa8\xa4\x4d\x7e\xb7\x0b\x3d\x4f\x33\x6a\xae\x75\x51\xf8\xa7\x18"
+  "\xf5\xdf\xd6\x95\xf6\xca\x76\x65\xeb\xc1\xa6\x23\xfb\xb8\xb2\xfd"
+  "\x40\x1b\x13\x51\x1c\x3d\x11\x3f\xd0\x3f\xd6\xe9\x28\x99\x72\x83"
+  "\x29\x09\x4c\x39\xb9\x24\x71\xfc\xca\x76\x65\xbb\xb2\x5d\xd9\xae"
+  "\x6c\x57\xb6\x2b\xdb\x65\xb0\xe9\xb4\x03\x6b\x03\xee\xfd\x94\xa3"
+  "\x76\xfc\xa3\x53\x76\x6d\x9a\xf4\x7d\xf2\x31\x65\x83\xf4\x28\x8b"
+  "\xb1\x38\xde\xea\x9f\x15\x5b\x13\x51\x9a\xd4\x64\xd8\x68\xae\x30"
+  "\x6d\x4f\x6c\x08\xce\x8b\x3b\x3a\xa3\x2c\xc5\x26\x6f\x98\x59\x1e"
+  "\x5a\x92\x50\x1f\x90\x33\xa7\x76\xea\xbe\xe4\x66\x9f\x4d\xb3\x2b"
+  "\xc3\x77\x2e\x69\x0c\xc9\x9f\x77\x2c\x72\xff\x5a\xbb\x94\x71\xcb"
+  "\x7b\xa3\xfe\x78\x5f\xdd\xa0\xec\x5f\x7d\x3c\xe5\xd5\xe5\x67\xfb"
+  "\x3f\x73\xc7\x07\xe3\xff\xf4\xd0\xe9\xa1\xcf\xdf\xfb\xd9\xcf\xff"
+  "\xbc\xba\xad\xef\x53\xb3\xfe\x3a\xe6\x95\x45\xa7\x82\x72\xe7\xfe"
+  "\x7d\xfa\x1b\x2b\xcf\x0f\xc8\xbc\xab\x6a\xe2\xee\xa5\x67\x86\x17"
+  "\xce\xff\xd7\x4d\xef\xa4\x3a\x74\xeb\x6f\x7e\x77\xe4\x8b\x0b\x4f"
+  "\x0c\xdc\x7a\xf7\x47\x93\xf7\x3e\xfa\xef\xab\x9e\xbe\xfd\xf0\xb8"
+  "\x1d\x8b\xbf\x1a\xf2\xdc\x3d\x9f\xde\xf0\xd6\xe3\xad\x7d\x9e\xbc"
+  "\xed\x50\xd8\xcb\x0f\x9c\x0c\xdc\xf6\xeb\x4f\xa6\xbd\xfe\xd8\x77"
+  "\xbe\x9b\xef\x3c\x32\x61\xd7\x23\xdf\x0c\x2b\xf8\xdd\xf1\x1b\xdf"
+  "\x5e\xd7\xa1\x7f\xe2\xd6\x83\xa3\x5f\xba\xff\x8b\xc1\xcf\xfe\xcf"
+  "\xdf\x7e\xf6\xda\x8a\x73\x57\xff\xfe\x97\x1f\x5e\xf7\x7f\x1f\xfe"
+  "\xfa\xda\x17\x7e\xfb\xcf\xff\xf5\x97\x35\xed\xfd\xfe\x77\xf4\xfb"
+  "\x63\xff\xcf\x83\x5f\x5e\xf3\x87\xdf\xfc\xe3\xfa\x37\x57\xb5\xf8"
+  "\x6d\x89\xa9\x9e\xb4\x67\xd9\xb7\x23\x8a\x16\x7c\xfe\x8b\x03\x69"
+  "\xec\xfb\xb4\x1f\xc8\xa9\xff\xf3\x9f\xc6\x4d\x1c\x9e\xaa\xf0\x26"
+  "\x3f\x93\x74\x0a\xee\x22\x21\x7d\x1a\xe8\x0c\xd0\x57\xf6\x62\xa4"
+  "\xe0\x6d\x7d\xbb\xd9\x8c\xda\xfc\x3d\xd9\xe8\x9d\x1a\x7a\xff\xe4"
+  "\x67\xb8\x5f\xcb\x53\x9c\xa3\xff\xe1\x1e\x73\xfc\x27\x36\x1d\xd6"
+  "\x55\x8f\x92\xf4\x81\xbe\xd8\x3a\x06\xb8\x0a\xfa\xc3\xd5\xe0\x03"
+  "\xbe\x30\x00\xfc\xc0\x1f\x06\xc2\x20\x18\x0c\x01\x10\x08\x41\x70"
+  "\x0d\x04\xc3\x10\x18\x8a\xd2\x87\xc0\x30\xcf\x32\xa7\x43\x54\x30"
+  "\xfe\xc1\xff\xb1\x10\xc5\xaf\xe3\xaf\xa4\xff\x47\xd3\x2d\x4a\x7a"
+  "\x8d\x92\x6e\xbd\x92\xfe\x1f\x4d\x37\xfe\x97\x8f\x23\xff\xab\x47"
+  "\x1d\x76\x0d\x44\xef\xc0\xa5\x8f\xd0\xb9\xb9\xa7\xea\x94\xad\xf3"
+  "\x1a\x2e\x92\xbf\x0b\x3f\xd7\xfc\xee\x5b\x14\xee\x53\xc5\x69\x1a"
+  "\x80\x78\x9e\xc0\xb4\x9b\x3d\x57\xf7\x9e\x3c\x30\x9d\x1e\x8d\x18"
+  "\x20\x80\xff\xbd\xf8\xf6\x72\x08\xee\x26\xdc\x91\xf5\xcb\xd7\xe3"
+  "\x7e\x2b\xee\x77\xaa\xbc\x51\xa8\x74\xd0\x49\x65\xb8\x87\x80\x4e"
+  "\x3f\x07\xf7\x06\xd0\xf5\x4d\x04\x5d\x1f\x13\xe8\xfa\x39\xe7\xf3"
+  "\x75\xfe\x65\x9d\x52\xea\x06\x28\xe9\x46\x3c\x1f\x1c\xa5\x29\xac"
+  "\xb7\x71\xab\xec\xb6\x39\x66\xe3\xe4\x89\x53\x27\x4e\x9d\x71\x9f"
+  "\x71\xc2\x04\xe3\x94\x88\x88\x1b\x26\x4d\x9e\x32\x69\xf2\x0c\xe3"
+  "\xe4\x69\x3f\x9f\x32\xfd\xe7\xd3\x66\x18\x1f\x79\x7c\xf9\xe2\xc9"
+  "\x11\x0f\x3e\x60\x5c\x9a\xb0\x78\x85\x71\xd1\xe2\xe5\x8f\xac\x5a"
+  "\xb8\xfc\x81\x1e\xd4\xbc\x57\x1b\x56\x05\x86\x75\x08\x31\xb5\x08"
+  "\xe9\x60\x04\xc8\xd3\x6b\x40\xbe\x23\x1d\x9c\x77\x4c\xca\xde\x65"
+  "\x7b\xe4\xde\xb9\x9f\x85\xfd\x76\xc0\x7b\x37\x3f\x18\x76\xe3\xad"
+  "\x2f\x6d\x29\x05\xe9\xae\x4a\x90\x66\x6d\x02\x29\x32\x1d\xa4\x08"
+  "\x1b\x48\xa3\x9b\x41\xda\xb8\x13\xa4\xf4\x58\x90\x56\x9a\x40\x7a"
+  "\x68\x03\x48\xbf\x4b\xe8\x9a\xf6\x87\x79\x22\xed\xf0\x46\x90\x0e"
+  "\x44\x82\xf4\x5a\x0a\x48\xaf\x04\x88\xb4\xcf\x31\xed\x93\xd0\x4b"
+  "\xdd\x04\x97\x60\xeb\x2d\xfe\xba\xff\x07\x54\x7c\xdd\x22"
   ;
diff --git a/sys/dev/mxge/rss_ethp_z8e.h b/sys/dev/mxge/rss_ethp_z8e.h
index 5f35d4b95a0..fde34bd740b 100644
--- a/sys/dev/mxge/rss_ethp_z8e.h
+++ b/sys/dev/mxge/rss_ethp_z8e.h
@@ -28,9465 +28,9718 @@ POSSIBILITY OF SUCH DAMAGE.
 $FreeBSD$
 ***************************************************************************/
 
-static unsigned int rss_ethp_z8e_uncompressed_length = 555148 ;
-static unsigned int rss_ethp_z8e_length = 151319 ;
-static unsigned char rss_ethp_z8e[151319 + 1] = 
-  "\x78\x9c\xec\xbd\x7f\x78\x54\xd5\xb5\x37\xbe\x32\x19\x60\xa4\x91"
-  "\x99\x84\x80\x23\xa2\x0e\x1a\xda\x88\x01\xa2\x62\x45\x0b\x1a\x25"
-  "\x5a\xf0\xf2\x4b\x05\x9b\x2a\x9a\x44\x13\x0c\x1a\x21\x92\x08\x03"
-  "\x86\x4c\x18\x7e\x88\x0a\x64\x12\x53\x8d\x12\x92\xd8\x62\x8b\x2d"
-  "\x2a\x6d\x69\x6f\x6e\x2f\xd6\x58\xe2\xfb\xd0\xdb\x24\x13\xfb\xa5"
-  "\xef\x9b\xeb\x17\x6f\x07\x6e\xa4\x91\x37\xc0\x48\x06\x66\x4c\x66"
-  "\x66\xbf\x9f\xb5\xf7\x39\xc9\xcc\x30\x41\xb9\xbd\xcf\xfb\xfe\xd3"
-  "\x3c\xcf\xe4\x9c\xb3\xcf\xde\x6b\xaf\xbd\xf6\xda\x6b\xaf\xb5\xf7"
-  "\xda\xeb\x10\xfd\x1d\x7f\xc6\x29\x9d\x7f\x4f\xf1\x7f\xfc\xfd\xe3"
-  "\xef\x1f\x7f\xff\xf8\xfb\xc7\xdf\x3f\xfe\xfe\xf1\xf7\xff\xe6\xef"
-  "\xac\xc1\x48\x7f\x70\x11\xf9\x9d\x26\xab\x87\xce\x94\xbf\xfe\xaa"
-  "\x08\x22\x39\xc1\x43\x26\x2b\x5f\xb5\x1f\xd5\x20\xdd\xe0\x22\xd3"
-  "\x75\x16\x4a\x9a\xb3\x9b\xa8\x76\xbc\xe8\x7d\xf5\x35\xe1\xdd\xf4"
-  "\x9a\xe8\xcd\x7e\x9b\xa8\x35\x8d\xe8\xd5\xf1\xc2\x07\x38\xcb\x3c"
-  "\xf4\xc3\x6e\x86\xb3\x09\xcf\xfc\x7e\xf3\x78\xe1\x45\x7a\x99\x87"
-  "\x1e\x59\xc6\xe9\x1b\xc7\x03\x56\x2a\x91\xf3\x35\x11\x88\x80\x6b"
-  "\xe2\xf2\x0c\x33\x7b\x92\xc4\x67\x4f\x0c\x1c\x86\xd1\x0c\x18\x47"
-  "\x2e\x02\x23\x49\xc7\xcb\x67\xa0\x04\x86\xd7\xe7\x24\xab\xcf\xd9"
-  "\x32\x0e\x65\x7d\x68\x53\x3a\x97\xad\x42\x1e\xe1\xa4\xc4\x56\x7b"
-  "\x90\x6c\xd7\x51\xc2\x09\xba\xec\x0b\x5c\x0d\xb8\x7e\xc6\xed\xdd"
-  "\xa4\xca\xa5\x31\x0c\x94\x4d\xf0\x3b\x2f\xcb\x1c\x2c\x0b\xd8\xb6"
-  "\x0a\x32\x22\xef\x2f\x7d\x86\x16\x83\xca\x6b\xb9\x4c\xcb\x6b\x40"
-  "\xde\x65\x7a\x5e\xf5\xce\x30\x4f\x7b\xf7\x2d\xbc\xb3\x47\xbf\x33"
-  "\xd6\x68\xef\x92\xf0\xae\x36\x06\x3f\xa3\xbb\x3f\x48\xa8\x87\x71"
-  "\xb1\x79\x70\x3d\x84\x9e\xd1\x70\x63\x9c\x5a\x91\xbf\x92\xf3\x67"
-  "\xdb\x44\x70\x89\x8d\x24\x2e\x4c\x3b\xe4\x9d\x7b\xa8\x49\xe5\xc5"
-  "\xfd\x44\x2e\xaf\xdd\xdb\x70\x2f\xd3\xb5\x7a\x93\xfd\xce\xd1\x49"
-  "\xd1\x38\x11\x69\xef\x52\xf0\x2e\x3d\xfa\xdd\xef\x33\xb5\x77\x57"
-  "\xe0\x5d\x76\xf4\xbb\x04\xbd\x9c\x15\xef\xf2\xf4\x77\x91\xfd\xa4"
-  "\x38\xce\x88\xdf\x08\x13\xd1\x48\xfc\x46\x99\xf4\xbe\x2b\xb5\x8a"
-  "\xb0\xe3\x4a\x32\x8a\x9a\xb1\x4d\x61\xa7\x20\xb7\x3d\x40\xb6\x09"
-  "\xe4\x38\x4e\xa3\x3b\x01\x97\x76\xae\x27\x93\xa3\x44\x04\xdc\xf6"
-  "\x5e\xea\xf0\xf6\x92\xc3\x2b\x7a\xdc\xc1\x73\x54\x71\x8e\x4c\xee"
-  "\xe0\x29\xaa\x78\x8e\xac\xad\xe5\x9f\x53\x3c\xbe\x08\x1b\x04\x39"
-  "\x26\x72\xd9\x6e\xea\xa8\xef\x26\x47\x7d\x74\x59\xc7\xd5\x64\x6d"
-  "\xc7\x33\x68\x6e\x66\x3c\x5a\x6d\x41\x0a\xa6\x8c\x6d\x2a\x7f\x83"
-  "\x8c\x8e\x49\x64\x68\x2f\x68\xd1\x70\xf9\x56\x1d\xe3\xb2\xf9\x24"
-  "\x99\x7e\xb2\x1c\x7d\x7f\x92\xf1\xbd\xaa\xe9\xfd\xf5\x01\xc3\x21"
-  "\xeb\x7c\x3a\x64\x3d\x4a\xad\xd6\xd9\xd4\x6a\xcf\xa6\x9d\x27\x29"
-  "\xe9\x50\x60\x16\xb5\x1a\xef\xc3\xd8\xc8\x26\x77\x2f\xee\x6d\x21"
-  "\xe4\xf1\x91\x6d\x0d\xa1\x5f\xbf\xb5\xad\xf6\x69\x32\x79\x14\x4c"
-  "\xf4\xe7\xb7\x6a\x3f\x2a\x23\x62\x9a\xf1\x73\xbc\x76\x94\x5e\x49"
-  "\x56\xe0\xd7\x03\x5c\x6e\x07\x2e\xed\x69\x56\xca\x04\xce\xa3\xdc"
-  "\x75\x41\x32\x96\xd3\x65\xc3\x8c\x89\xd4\xb0\x53\x8e\xcd\xde\x86"
-  "\xd7\x44\x0f\xf3\x56\xdf\x0b\x39\x18\x5f\x49\x46\xd4\xbd\x87\xeb"
-  "\xdb\x89\x31\xea\x78\x8b\x8c\x7d\x6b\x73\x12\x1a\x5f\x13\xdd\x78"
-  "\x67\xd3\xdf\x81\xdf\xbb\xf1\xbe\x67\x7a\x2a\x59\xdc\xc1\x2c\xfa"
-  "\xb0\xbf\xc7\xc8\x30\xc6\xf8\x28\x81\xe1\x99\xed\x94\x88\xf6\x8c"
-  "\x00\x3e\x5f\x36\x22\xfd\x7a\xe4\x43\x79\xf4\xff\xcb\x7b\xb9\xbc"
-  "\xb8\xe2\x51\x5f\xf8\x8a\x47\xcf\x85\x5f\x7f\xb4\x4f\xbc\xfe\xe8"
-  "\xd9\xd0\xeb\x8f\x7e\xe9\x58\x47\xa6\xd0\x15\x8f\x7a\x3b\x4a\x64"
-  "\x1f\x58\x3a\x4a\xd0\x07\x21\x32\x6d\x38\x45\x96\xc7\x9f\x43\xdf"
-  "\x07\x3f\xa3\x0d\x2b\xc8\x1a\x4e\x9e\x90\xe3\x0e\xfe\x85\x1e\x2f"
-  "\x27\x81\xfb\xa2\x78\xed\xeb\x4b\xb9\xca\xa3\x78\xd6\xc4\x6d\xea"
-  "\xf2\x18\x53\xea\xb8\x5e\x6f\xf2\xf5\x1e\xfc\xba\xf1\xeb\xc1\xaf"
-  "\x57\xa4\x5c\xc5\x63\xca\x31\x66\x63\x02\x35\xf4\x13\x4d\x0f\x53"
-  "\x02\xba\xc8\x07\xfc\x2d\xc3\xd0\x6d\x62\xb8\x26\xb7\xe4\x3b\x95"
-  "\x54\xe1\xf7\x17\x11\xcb\x14\x96\x27\x2c\x5f\xfc\xce\xcb\xb3\x50"
-  "\x4f\x97\xe4\xfd\xd7\x84\x4f\xa4\xe4\x96\x20\xbd\xc7\xf7\x42\x51"
-  "\x82\xf7\x85\x22\x43\x5f\x4a\x6e\x29\xf2\x14\x78\x8c\x63\x2d\x1a"
-  "\x0d\x7b\x18\x16\xc6\x89\xf7\xf2\x20\x25\x02\x66\xc9\x3f\x9f\xef"
-  "\x32\xee\x7e\x4d\x1c\x45\xbe\xed\x83\xb0\x00\x1b\x70\x40\xff\xcb"
-  "\x9b\xf4\x34\xd0\xba\x7b\x07\xf2\x71\x79\x77\x20\x8b\xe5\xae\xc7"
-  "\x5d\xdc\x43\xe6\x20\x8d\x16\x03\xaa\x3e\xe4\xe9\x61\xf9\x78\x79"
-  "\x80\x46\xfa\x9d\xb4\x98\x61\x73\x39\x77\x6f\x0f\xa1\x5c\xa9\x70"
-  "\x14\x41\x2e\xd1\x42\xbf\x28\x4a\x80\x2c\xee\x3e\x84\xf2\xaa\xee"
-  "\x31\x26\x1d\x47\xae\x83\xfb\x5a\xe2\x09\x7e\x38\x54\x1c\xa0\xcb"
-  "\xeb\x28\x11\xe5\x1e\x62\x78\x0c\x0b\x7c\xe0\x41\x5b\x4b\x0f\x15"
-  "\x7b\x29\x2c\xa2\x60\x7a\x34\x78\x39\x51\xf0\x90\x2e\x00\x8f\xf9"
-  "\xaf\x15\x65\x2e\x6f\x92\xf0\x1e\xfc\xe7\x30\xc3\x0b\x90\xd1\x26"
-  "\xf1\x7d\x98\x61\xf8\x59\xa6\x01\x66\xcb\x9a\x7b\xa8\x97\xc6\xb4"
-  "\x78\x1d\x45\x89\x1d\xe5\x44\x5c\xfe\xfd\x8a\x9e\x11\xa2\x2f\x27"
-  "\x91\x79\x8e\xdf\xbb\x83\x67\x39\xcf\x5b\xa2\xaf\x28\xf1\xf2\x5e"
-  "\x32\x32\xce\x28\x6f\x67\x3c\x23\xfb\xf2\xc1\x7b\x1f\x9e\x4d\x0f"
-  "\x67\xcf\xcb\x9e\x4d\x0b\xee\x9e\x33\x9b\x32\x6f\x9f\x9a\x79\xcb"
-  "\x6d\x33\x6f\xa1\xc5\x3f\x78\x70\x36\x2d\x5e\x38\x9b\x1e\xc2\x2f"
-  "\xe7\xbe\x79\x78\x98\x33\xfb\xa6\xcc\xef\x4f\x5d\x3c\x67\xde\xbd"
-  "\xf4\xc0\x92\x9b\x33\x6f\xbe\x99\xee\xbe\x77\xfe\x4d\x99\x99\xda"
-  "\xf5\xa6\x4c\xce\xf2\xc8\xcc\x7b\x1f\x9a\xba\x78\xf5\xaa\xb2\x55"
-  "\x53\x17\xce\x9b\x13\x39\x27\xa6\x87\xce\x87\x99\xa6\x3e\x71\x66"
-  "\x2e\x85\x21\x23\x1a\xd0\xd7\xf8\xf5\xb6\x54\x1c\xc7\x58\xb7\x6c"
-  "\x68\xe0\x3e\x92\x72\x72\xcc\x51\x8c\x6f\xa3\xdf\x69\xde\x0c\x5a"
-  "\x2d\x66\x5a\x61\xee\x41\x9e\x71\xf9\x78\x77\x4c\x93\xcd\x23\xf0"
-  "\x7e\x4f\xf4\xfb\x64\x3b\xde\xff\xad\xc3\x46\xe4\xc6\x0f\xf4\xf5"
-  "\x41\xe6\x81\x8e\x5e\xea\x73\xe4\x8c\x00\x1f\x27\xa0\x8e\x6e\x8c"
-  "\xc1\x4e\x94\xf5\x44\x8c\xed\x6e\xf4\x43\xa7\x6d\x3d\x25\x9e\x26"
-  "\xf3\xbf\x74\x94\x65\x11\xf7\x87\xbb\x4c\x83\x71\x6e\x10\xc6\x68"
-  "\x09\x03\x7d\x0c\x38\x47\x14\x1c\x4b\x7a\x84\x1c\xf0\x30\x9c\x9d"
-  "\x78\xa7\xc1\x0a\x75\x40\x1e\x40\x5e\xff\x3c\xec\x48\x27\x91\x32"
-  "\x76\x6f\x78\x20\x5d\xce\x2d\x28\x97\xa7\xf3\x2f\xf2\xfb\x5a\x4b"
-  "\x90\xef\x27\x73\x13\xd0\xdf\x09\x98\x3b\xd1\x16\x73\x31\xf8\xd8"
-  "\x17\xae\xb9\xde\x2b\xfc\x39\xa4\xd2\x2c\xfb\x44\x0a\x9e\x6b\xae"
-  "\xff\x52\x38\x90\xb6\x5e\xa6\xbd\xcb\x69\xe8\xdb\x44\x1e\x83\xe2"
-  "\x05\x99\x9e\x08\x5a\x4c\x02\x7e\x5d\x21\x2e\x7f\x46\x96\x1f\x85"
-  "\xb4\x04\xe4\xfd\x32\x9c\x72\xfd\x59\xf0\x0a\xa7\x61\x3e\x1f\x57"
-  "\x09\x78\x7d\x61\x91\x43\xc2\xd2\x54\x87\x7b\x5f\xcb\xfa\x5e\x3a"
-  "\x51\x42\x06\x0f\xde\x85\x1d\x80\x39\x30\x58\x7f\x27\x97\x45\x5d"
-  "\x46\xff\x40\x11\xe6\x50\xcb\x11\xd6\x05\x42\x8c\xcf\x99\xc1\x3c"
-  "\x2d\x5c\x27\x8f\x63\xf4\x45\x2f\xfa\xe9\x32\xbf\x33\x79\x7e\x4c"
-  "\x3f\x15\x00\xce\x97\xa0\x7b\x17\x60\x1c\x0c\xf7\xa1\x0e\x3c\x03"
-  "\xae\x41\x83\xab\xc3\xf0\x29\x3e\x48\xde\x1e\xc3\x07\xf7\x02\xf6"
-  "\xb9\x88\xf7\xfb\x62\xde\xdf\x80\xf7\xfd\xda\x7b\x8c\xa7\xe4\xb6"
-  "\x98\xfa\x7b\xf0\x3e\x8c\xfa\x7d\x18\x2f\x89\xa8\x6f\x71\x03\xeb"
-  "\x69\x43\xf9\x83\xd1\xf9\x53\xac\x7d\x4e\x33\xcb\x10\x96\x85\x32"
-  "\x7f\xa3\xc6\xab\xaa\xfe\x94\x8c\x98\xfc\xe0\x61\xf3\x28\xf0\x03"
-  "\x5f\xc7\x22\xcf\x28\xc8\x22\x23\xe6\x8d\xa3\x87\xca\x59\x6f\x4b"
-  "\x59\x16\x93\xbf\x1c\xf9\x26\x30\x1d\x25\x0d\xce\x48\x1a\x2c\xd6"
-  "\xf4\x2c\x1e\x0b\x26\x94\x71\xc5\x94\xd9\x8f\x32\xd7\x85\x15\xdd"
-  "\x12\xfd\x7d\x71\xcb\xb4\xc6\x94\xe9\x96\xfd\xaf\xea\x31\x32\xbf"
-  "\xe8\x65\xa4\x6c\x19\x88\x82\xc1\x6d\x83\x3e\x36\xd6\x14\x0d\x23"
-  "\xb5\x1b\xf5\x4e\xd9\xa1\xc6\xf1\xb7\xd0\xe7\x37\x23\xed\x2f\x80"
-  "\x7b\x8e\xf9\x84\x79\xd9\xed\x0d\x40\xf6\xcd\x4d\x52\x73\xf8\xd8"
-  "\x15\xe6\x72\xe2\xfb\xa9\x7c\xcf\xb0\xc5\xc0\x7c\x8d\xc7\xc7\xae"
-  "\xc0\x95\xd3\x65\x9d\x3c\xb6\xc4\xc0\x3f\x85\x15\xcc\xb1\x3b\x30"
-  "\x06\x0d\x78\x0e\x69\x75\xb4\xe3\x39\x01\xfc\x79\x16\x72\x15\x3c"
-  "\x39\x97\xf9\x6d\x06\xd2\x3f\xd6\xde\x7f\xc0\xf9\x71\x7f\x93\x76"
-  "\xcf\x7c\x79\x56\xe3\x4b\xf0\x79\xea\x6f\x64\xdd\x92\xd7\x55\xf9"
-  "\xb0\xe2\xeb\x39\x78\xf7\x16\xae\xf3\x70\xdd\x81\xeb\x03\xb8\xae"
-  "\x70\x9c\x23\xab\x23\x04\x3d\x42\x3d\x2f\xc5\xf5\x41\x5c\xef\xc6"
-  "\xf5\x21\x5c\xa7\xf2\xb8\xf4\xae\x2d\xa2\x18\x9e\xe8\x0d\xab\xb1"
-  "\x38\x4a\xf5\x47\xea\x44\x6d\x7c\xa8\xf1\x79\x66\x28\x4d\xa8\x34"
-  "\x03\xe4\xf9\x50\xda\xc0\x5c\xa6\xcb\x62\xb4\x3d\xc0\xf5\x6b\xe3"
-  "\x7a\x84\xea\x17\x95\x27\xac\xca\x69\x7d\xa7\xa5\xa9\x7c\x09\x91"
-  "\x75\x7a\x68\x6c\x5b\x85\x4f\x08\x5c\x9b\x99\xae\x48\x3f\x08\x9a"
-  "\x40\x9f\x19\xbb\x9d\xe9\x34\xd4\xdf\x63\xd3\x23\xfa\x1b\xfa\x6c"
-  "\x6a\x20\xba\xbf\x2d\x8b\x99\x66\xdc\xdf\x3a\xbe\x8c\x3b\xe6\x14"
-  "\x9e\xa7\x46\x2a\xfc\x2d\x8b\x21\xd7\x7b\xb9\xef\x13\x4b\x78\x3c"
-  "\x8c\x9b\xe5\xa1\x3d\x52\x26\xf2\x3b\x5f\x72\xae\x97\xcb\x27\x16"
-  "\xcb\x77\x39\x90\x97\x5d\xfa\x3b\xae\x9b\xc7\x61\x62\x99\x7c\x57"
-  "\xa6\x97\x83\xcc\x3c\x2c\xcb\x62\x8e\xe3\x39\x9f\xe7\x6e\xcc\xa1"
-  "\x3d\xc8\x53\xe7\xa1\xcb\x2d\xc3\xd9\x37\xc2\x35\xb6\x79\x6a\x25"
-  "\x19\xae\xaf\xa4\x11\xee\xe0\x51\x5a\x14\x14\xa1\xa9\x44\x97\xb9"
-  "\x83\xb3\xe8\x06\xa2\x64\x77\xf0\x08\xa1\xc1\x93\xdc\xc1\x5a\xcc"
-  "\x91\x9b\xf9\xfd\x87\x53\x28\x21\x01\x57\xc7\x8d\x64\x48\x70\x07"
-  "\xf7\x20\xfd\x00\x5d\x4f\xc6\x84\xef\x8f\x10\x7e\x77\x70\x06\x9e"
-  "\xcb\xe8\xbe\x11\xe2\xaf\xb9\x21\xb2\xcc\xdf\x22\x1c\xee\x60\x01"
-  "\xdd\xb7\x25\x2c\xdc\xc1\x36\xbc\x2b\xa6\x45\xa1\xaf\xc4\xa2\x90"
-  "\x5f\x08\xcb\xd8\xc3\x8b\x42\x67\x70\xff\x57\x01\x5a\xe2\xfa\x21"
-  "\x7e\x0e\xe1\x86\xae\x2b\xaa\xc7\x36\xe7\xae\x33\xd0\x00\xe6\x15"
-  "\x91\x3c\xf6\x30\xda\xd7\x35\x20\x8a\x12\x31\x27\xfc\xaf\x81\x01"
-  "\x5c\x6b\xc6\xfe\x4f\xf9\xec\x1a\xdb\x03\x38\x5d\xd3\xa0\xf8\x33"
-  "\xfe\xee\x60\x37\xe5\x42\x76\x2c\x5a\xe7\x15\x8c\xfb\x98\x8d\x82"
-  "\x16\xad\xfb\x50\x40\x6e\x99\x17\xad\x73\x08\xbc\x33\x01\x5e\x97"
-  "\x3b\xd8\xcb\x75\xf4\x00\xde\xe7\x12\x9e\x2b\xd5\x84\xbc\x5e\xce"
-  "\x17\x09\x87\x61\x70\xde\x45\x21\x32\x8b\xea\x54\xd3\x40\xf5\xd8"
-  "\xc0\x40\x75\xaa\x15\xbf\xb9\x22\x25\xf5\x91\xb0\x33\xf5\x23\x9e"
-  "\xa3\x50\xbe\x08\xcf\xf6\xaf\xc0\x27\x92\x8e\x21\x1a\x85\xfc\x45"
-  "\xe8\xf3\x6c\xbf\xc4\x37\xb5\x4e\xe2\x5b\x93\xfa\xfa\x57\xb2\x1d"
-  "\xa9\xaf\xa9\x76\xa4\xfe\x88\xd3\x7d\xe0\x5b\xdc\x37\xfb\xd4\xbb"
-  "\x7f\x46\xb9\x25\x7e\x85\x57\xb3\xb0\xa4\x1e\x06\x0f\x26\x2e\x0a"
-  "\x89\x4a\xa6\x21\xe8\x5a\xc9\x74\x64\xbb\x05\x75\x34\x8b\xe4\xd4"
-  "\xc3\xc0\xa7\x0b\xe5\x4f\x0e\x08\x9e\x37\x53\x03\x5f\x29\xd8\x7e"
-  "\xc0\x59\xe6\x67\x98\x96\xd4\x80\x70\x8d\x33\x05\x0d\x36\xd0\x43"
-  "\x04\x16\x05\x37\x06\x73\xd7\x51\xa2\x3b\xf8\x31\xa5\x57\x56\x26"
-  "\xb8\xed\x65\x68\xe7\x76\xc0\x2c\xc0\x7b\x1a\x8b\xba\x3e\x04\xdc"
-  "\x00\xd7\x27\xaa\xc7\x99\x44\xca\x38\xe8\x0f\x54\xc0\x38\xf5\x3b"
-  "\xc9\x82\x67\x6b\xbf\xc4\x6f\xdc\xcc\xb0\x6b\x5c\x4e\xd8\x32\x6e"
-  "\xae\xce\x3f\xcc\x3b\x8a\x6e\xcc\x33\xef\x72\x9a\x45\xe7\x93\x90"
-  "\x6b\x5c\xfa\x8d\x44\x96\x85\x3e\x11\x64\x5e\x99\x4e\x25\x09\x1d"
-  "\xbe\x23\xa0\xb5\x89\x3a\x4a\x0e\xd0\x14\x62\xfb\xc9\x47\x1d\xbe"
-  "\x5a\x3c\xef\x26\xc6\xaf\xc3\xb7\x99\xda\x7b\xf7\xd0\xc2\x12\xdf"
-  "\xc6\x90\x65\xdc\xde\xf6\xde\x05\x84\xf2\x1f\x02\xc7\xf0\xe3\x25"
-  "\xc6\xca\x8e\x12\x1f\x3f\x3b\xda\x7b\xc1\x9f\x21\x11\x0a\xba\xc6"
-  "\x59\x83\x96\x71\xcd\x0b\xcf\x09\xef\x82\xde\xca\x11\x48\x1b\x30"
-  "\x27\x88\xa0\xd9\xee\x10\xed\xbd\xdb\xe9\xf1\x73\x94\xd0\x5e\x74"
-  "\x40\xf2\xe9\xe3\x25\x25\x24\xcb\x9f\x0b\x9a\x1f\xeb\xad\xa4\xc7"
-  "\x8a\x68\x0c\xf2\x9f\x61\x9e\x15\x63\x2a\xa9\xad\xbb\x98\x16\x9c"
-  "\x0a\x26\x2e\x3c\x37\x20\xda\xf2\x6a\xa9\xbd\xa8\x96\xe9\x31\x93"
-  "\xed\x8c\x05\xa7\xfa\xc4\xc2\x73\x7e\xd1\x5e\xf4\x2e\xb5\xe5\x1d"
-  "\xa0\xf9\x9f\xb7\x98\x43\xd5\xe3\xd2\xc3\xc9\xe3\xe6\x86\xab\xc7"
-  "\xe5\x84\x92\xc7\xed\x0d\x56\x03\x97\xe4\x71\xcd\xa2\x66\x7c\x3a"
-  "\xe8\x77\x99\xec\x8b\x94\xf1\xdf\xc6\xbd\x4d\xf6\xaf\x65\xfc\x4c"
-  "\xe1\x1a\x9f\x33\x50\x3d\x7e\xae\xe4\xfb\xe4\xf1\x33\xdd\x41\xe6"
-  "\xff\xf1\x39\xc8\x97\xa3\x78\x64\x7c\x91\xe2\xfd\xf1\x4f\x71\xbf"
-  "\x22\xaf\x1d\xbf\x6d\xf8\x41\xff\x18\x8f\x31\x4e\xc9\x0c\x37\xec"
-  "\x1a\x1f\x08\x5b\xc6\x63\x3c\x5c\x61\x82\x5d\x62\xe8\xf0\xed\xa1"
-  "\x10\x64\x6b\x87\x2f\x44\x0b\x9f\x0b\xa0\x6f\xd1\x07\xf6\x10\xe8"
-  "\x79\x94\x1e\x7f\x8e\x1c\x6e\xfb\x51\x12\xbf\x77\x31\x3d\xcc\x0b"
-  "\x9f\xfb\x50\x84\xab\xc7\x07\xf8\xfd\xc2\xe7\x1c\xb0\x8d\x00\x27"
-  "\xf9\x0a\x53\xb8\xe6\x8a\x74\x4d\x57\x02\x1e\x57\x7c\x87\xf1\x18"
-  "\xf0\x83\xc7\x30\x8f\xe3\xfd\x4c\xa4\xfd\x9c\xe7\x8e\x30\xf3\x9d"
-  "\xeb\x8a\xbd\xc2\x62\x35\x2d\x18\x21\xbc\xa1\xad\x24\x79\x20\x7c"
-  "\xa7\x10\x6c\x7b\xe5\xda\xa9\x49\x8e\xa9\xd0\x84\x4a\x91\x6c\x35"
-  "\x89\xea\x2b\xf6\x86\x6b\x26\xdc\x0f\x38\x89\x62\x2d\x97\x9d\x30"
-  "\x57\xf1\xcc\x67\x72\xec\x89\xea\x09\x73\xbf\xa9\x9d\xef\x77\x4e"
-  "\x28\xf7\xd0\x7b\x39\x2c\xe3\x70\xbf\xcd\x43\xef\x67\x68\xf7\xb5"
-  "\x1e\xaa\x3d\x2a\xe5\x23\xe4\x5c\x49\x05\x8d\x3b\x49\x57\xcd\x05"
-  "\x4d\x08\xf7\x49\xb8\x9f\xbf\xe8\x06\xb4\xdb\xf5\x0a\xe4\x90\xf0"
-  "\xb3\xcc\x11\xce\x19\xd0\x37\x28\x0b\xed\x35\x09\x7f\x7a\x92\x48"
-  "\x49\xab\x10\x03\x56\xb6\x25\xcd\x78\x1e\x03\xba\xa6\xe1\x9a\xb2"
-  "\xfb\x3c\xa5\xe2\x67\xdd\xed\x0c\x57\xb2\x4c\xc6\x7d\xa6\x58\x6b"
-  "\x1d\xbd\x73\x0d\x65\x98\x7d\x64\x6a\x74\x86\x73\xcc\x1b\x2d\x6c"
-  "\x53\xa5\xf2\xbd\x70\xbe\x41\x8d\xe7\xc9\xc8\x73\x4b\x38\x19\xf5"
-  "\xd9\xcd\x42\x94\xa6\x53\xe3\x6a\xe2\xbe\xb2\x36\x3a\xc5\xfe\x90"
-  "\x3f\xdd\xc0\x78\xea\xb8\x30\x6e\xc0\xf3\x6a\xe0\xb9\x6c\xe9\xba"
-  "\x2c\xfa\xd8\x4e\x71\xd7\x22\xfc\xce\xab\x06\xdb\x3f\xcc\xfb\x7a"
-  "\x9d\x26\xc3\xbc\x3f\xa8\xd3\x69\x38\x7b\x9f\xc7\x79\xe8\xbc\xf0"
-  "\x56\xad\x24\xa6\x85\xd5\x11\x14\xff\x09\x9b\xa4\xb2\x22\x44\x57"
-  "\x2f\x5a\x77\xad\x70\x7b\x45\x8b\xdb\x7e\x4a\xae\xd7\x35\x22\x4f"
-  "\x45\x50\x84\xd9\xbe\x65\xdb\xb6\x96\x6d\xd5\xea\xb4\x3c\x51\x9d"
-  "\xb6\xac\x6f\x8d\x08\x36\x48\x7b\x74\x62\xa6\x87\x6e\x2d\x51\x7d"
-  "\x33\x6e\x26\xe6\xc2\xee\x3e\x4b\xda\x32\xc0\x4e\x66\xd8\x1d\x25"
-  "\xa2\x25\x9c\x9c\x56\x80\x7c\x98\xff\x7e\xe7\x8a\x5c\xb3\xc3\xbc"
-  "\xd6\xbb\xf9\x35\x9e\xdb\x26\x62\xfe\xbb\x76\xc9\x05\x6b\x42\x72"
-  "\x75\x91\xd0\x2f\xb6\xa1\x45\xc9\x04\x8d\x7d\xf4\x3f\x0b\x7e\x59"
-  "\xf1\x5f\x0f\xcd\x8d\xe3\x9a\xfb\x60\x77\x39\x36\xd0\x44\xf4\xc3"
-  "\x55\x27\x69\xe2\x17\x0e\xbb\x38\x21\x9c\x13\x2b\x7f\xb2\x3e\x00"
-  "\x9d\x60\xa2\xcf\x43\x1b\x8b\x86\x9f\x5b\x21\x17\xcf\x8b\x9e\xaa"
-  "\x35\x83\x34\x3b\xb6\x68\x5d\x58\xf0\x3d\x8f\xb3\x46\xa4\x33\x3d"
-  "\xfc\xce\xab\x67\xe9\xb4\x18\x86\xfe\x46\xe1\x4a\x2b\x51\x3a\xe0"
-  "\xd5\xf5\xc2\x29\xa8\xe5\x1a\x5e\xc7\xbb\x7a\xb7\xd4\x83\x5c\xe3"
-  "\xe7\xf6\x41\x8e\xf0\x7a\x07\x74\x66\x5f\xa9\x55\x04\x00\xd3\xe5"
-  "\xa1\xc9\x1e\xcd\xce\xf2\xb9\x83\xf7\xb2\x4c\x99\x3b\xdc\x3a\xe9"
-  "\x10\xfc\x6b\x0e\x76\x40\x23\x62\x99\x24\x2c\x79\x33\x2a\x14\xde"
-  "\x01\x86\xdb\x52\x71\x96\xba\xf1\xbe\xd4\x27\x7a\x84\x2b\x2f\x9d"
-  "\xf5\x90\x96\x35\xfd\x9c\xf6\x01\x78\x58\xb4\xac\x66\x9c\xae\xf9"
-  "\xa0\xe5\x9a\x7e\x3a\x01\x1d\x0f\xfa\x9d\x57\xd9\x5c\xd7\xec\x3d"
-  "\x54\x46\x9a\x1d\x77\x0d\xec\xbf\xef\xec\xd5\xf1\x82\xec\x10\xa0"
-  "\x2f\xea\x67\xb9\xd7\x4b\xbc\x86\x56\x5a\x2e\x02\xc0\x75\x26\xf2"
-  "\x2e\xd1\xdb\xc0\xed\x53\xed\xba\xa6\x28\xb2\x5d\xc0\xc1\x0b\x7d"
-  "\x59\xd2\xa0\x74\x1d\x99\x6c\x8a\xd6\x26\x6e\x2f\xb7\x85\xdb\x2c"
-  "\xdb\x02\xfd\x82\xe7\x15\x77\xf0\x56\xe8\x5f\x32\x3d\x07\xb0\x0e"
-  "\x78\xe8\xdb\xd9\x4a\xb7\xba\x46\xea\x75\x71\xfb\xd1\x32\xce\xe4"
-  "\xf8\x8a\xae\x71\x84\xc5\xf1\x13\x74\x2d\xeb\xb4\x89\x7c\x95\x73"
-  "\x72\x00\xfc\x6b\x99\x32\x8b\xe7\x62\x77\xf9\x39\xc8\x6f\x99\x77"
-  "\x2c\xf2\x76\x23\xcf\x4d\x5a\xde\x9b\xd4\xfa\xae\xbc\x8e\xe2\xab"
-  "\xa8\x19\x37\x02\xbc\x3b\x97\xd7\x24\x84\x25\xd7\xab\x3f\x0b\x3c"
-  "\xe3\x8a\xbe\x9a\x32\x2b\x3e\x2e\x56\x53\x58\x8d\xc5\x5e\xd4\x73"
-  "\x05\xf3\x94\x63\x1d\x5d\x09\xbe\x3c\x56\xb1\x81\xc6\x32\x3f\x89"
-  "\xe4\xb4\x72\x45\xf7\x6b\x6b\x85\xb3\x92\xdc\x90\x9e\x25\x6b\xe8"
-  "\x2a\x8c\xbf\xb2\x93\x74\xed\x3b\xb9\xe5\x36\xe0\x4a\x54\x75\x9a"
-  "\x48\xca\x9a\xe4\x34\xbb\x3b\xf8\x39\x35\x9e\x66\x5b\xeb\xda\xc3"
-  "\x3a\x2f\xe2\xfe\xc8\xc5\xe4\x02\xe8\xba\x4d\xd9\x0a\xb6\xbb\x79"
-  "\xbd\xec\x38\xd9\x32\xb8\xbd\xf8\x25\x20\xed\x6a\x71\x5e\x2c\x13"
-  "\xac\xbf\x61\xbe\xf2\x90\x2d\x07\xd7\x6d\xf2\xe7\xa4\x3c\xed\xd9"
-  "\x8e\x7c\x49\xe2\x7c\x98\xf3\x40\x6e\xdb\xd2\x84\x33\x81\xc7\xc4"
-  "\x41\xbf\xd3\xb6\xd8\x43\x33\xb7\xa9\xbe\xb1\x4d\x64\x58\xc3\xe0"
-  "\x60\x47\xdf\x12\xf3\x26\x60\xfd\x8b\xad\x22\x81\xf1\xd8\x21\xc7"
-  "\x05\x60\x35\x1a\x94\x7c\xc6\xdc\xb8\xad\xc1\x19\x2e\x82\x2c\x2e"
-  "\x0a\xd7\x64\x34\xcb\x7b\xed\x1d\xe3\x81\xb9\x6f\x5b\x7c\xf8\x79"
-  "\x33\x5a\x26\x30\x8f\x4f\x4a\x55\x70\xf2\xd2\x5b\x26\x9c\xe4\xe7"
-  "\x71\xfc\xec\xb3\x4c\x6d\x76\xd7\x65\xa1\xfe\x93\xa8\x77\x52\xaa"
-  "\xb2\x01\x26\x8d\xeb\x43\x1d\x7e\xe7\xa4\x54\x0f\xa5\x1f\x50\x6b"
-  "\x87\x53\x9b\x87\x19\x7b\x16\x1e\x3b\xed\xf5\xa4\x8d\xe9\xeb\xfe"
-  "\x85\xd7\x31\xd0\xae\xa2\x90\x65\xfc\x36\x4d\x6e\xb0\x5d\xf5\xad"
-  "\xe3\x74\x5d\x73\x47\x91\xe4\x6f\x83\x30\x4c\x2a\x7b\x2f\xec\x35"
-  "\xf0\xfa\xae\x12\x5f\xd7\x35\x5f\xf8\x9b\xb4\x07\xbf\x03\xf8\xb5"
-  "\x68\xcf\x6d\xf8\x79\x70\x9f\x29\xe9\xd6\x57\x00\x3b\xe7\xba\x66"
-  "\xcc\xf5\xdb\xf8\xd9\x43\x93\xf6\x89\xbe\x34\x43\x58\xbb\x6f\xf8"
-  "\x92\x6d\x8c\x49\x5d\xa0\x7f\x81\xea\x07\x86\x41\x09\x18\x8b\x4c"
-  "\x73\xe1\xa8\x13\x81\xd6\x0a\x1f\xe3\x6c\x6a\xad\xf3\x91\xed\xdb"
-  "\xdc\xf6\xeb\x92\x4a\xeb\x84\xd7\x07\xda\xf3\x95\xdb\x76\xa8\x3e"
-  "\x48\xbc\xc6\xec\x77\x5e\x97\xe6\xa1\x27\x6a\xa5\xcc\x4f\xc9\x5b"
-  "\xcc\xf0\x44\xb2\xe4\x07\xa1\xb7\x5d\xc9\xb3\xa9\xcd\xdc\x8f\x78"
-  "\xfe\x21\xda\x6d\x3e\x4d\xd7\xc9\xfe\x3c\x84\xb6\xef\x86\x4c\x61"
-  "\xdb\xa9\x51\xca\xff\xeb\x20\xff\x6d\xad\xfa\x7a\xe8\x0e\xbc\x83"
-  "\xdd\xd4\xdb\x5e\x14\x20\x86\x11\x02\xec\x2a\xb9\x26\x94\xd1\xbc"
-  "\xa1\x57\x04\x3e\xac\xe8\x31\x62\x3e\x46\x7f\x4f\x6d\xe6\x3a\x1d"
-  "\xd0\x83\x5b\x56\xca\x7a\xb3\x20\xab\x7c\x71\xfb\x7f\x10\xb7\xeb"
-  "\x3f\x38\x94\x26\xe5\x62\x11\x74\x2c\x7b\x74\xbf\x5c\x7f\x50\xf5"
-  "\xc9\xf5\xa6\xe8\x3e\xb9\xfe\x20\x7e\xf3\xf1\x2b\xc0\xaf\x4c\x7b"
-  "\x8e\xfc\xcd\x8c\xb8\xdf\xec\x77\x5e\x9f\x8d\xb1\xef\x51\xb4\xe6"
-  "\x34\xe0\xca\x3c\xf0\x25\x99\xd8\xf6\xe6\x7d\x05\x4e\x67\x7e\xe5"
-  "\xf4\x30\xf4\x12\x3c\xe7\xe0\xbd\x85\xc7\x62\x55\x98\xa2\xde\xbb"
-  "\x37\x83\xa7\xd6\xf7\x33\xee\xef\xc8\xf5\x82\x8d\xdb\xb6\x31\x1f"
-  "\x22\xcf\x32\x73\x70\xdb\x36\xd4\x77\x40\xa7\x1f\xd2\xea\xf9\x7d"
-  "\x7c\xfd\xe0\xfa\xa3\x83\x7a\x14\xf4\x4b\x96\x2d\xbd\x94\xd6\x03"
-  "\xf9\x83\xbe\xca\xd8\xaf\xe6\x8d\xb4\x2f\xf8\x19\x72\xef\x18\xee"
-  "\xbb\xdb\x21\x5f\xfa\x6b\xae\xf7\x0c\x18\x68\x54\xbf\x81\xb2\x82"
-  "\x35\xaf\xf4\x06\x53\xae\xea\x75\xf7\x1c\xa0\x8e\xe0\xaf\xc8\xf6"
-  "\xb4\x84\xf1\x99\x9b\xf9\x79\x9d\x08\xbd\xdf\xbf\x17\xb6\xd6\x99"
-  "\x16\xcc\xb3\xd7\x9e\xa4\x34\xd9\xf6\x57\x8e\x63\x06\x7f\x5c\xc2"
-  "\xd6\x68\xf1\xca\xe1\x9d\xcb\x45\x70\xe7\x09\x8c\x8f\x01\xeb\xe8"
-  "\x1d\xfd\x94\xf1\xe6\x7a\xca\xac\xef\xa7\xb4\x86\x7e\x4a\x17\x7f"
-  "\x4b\x37\xd4\x43\xd7\x7a\xfc\x9c\x85\x30\xbe\x73\xc6\x94\x90\xa9"
-  "\x61\x3d\xc9\x3e\x0f\x55\x43\xe7\x0a\x42\xe7\x3a\x93\xce\x72\x6e"
-  "\x50\xe7\x1a\x18\x60\x9d\x2b\xcd\xa3\xf8\x22\xcd\x73\x79\x11\x25"
-  "\x24\xe5\x91\x05\xf8\x39\x4e\x53\xda\xd5\x49\xdd\xd0\xf7\xd0\x66"
-  "\x8f\xd6\x5e\x5c\x33\xcd\x45\x34\x4a\xb6\x15\xb2\x57\x54\x67\xec"
-  "\x1f\x76\x4e\x35\x30\xef\xf8\x78\x0f\x08\x6d\x98\x7c\x2b\xef\x63"
-  "\x1c\x98\x10\x30\x96\xd6\x83\xef\x90\x5e\x36\x49\x04\x90\x3e\x91"
-  "\xeb\xde\x8f\x74\xbf\x73\x72\xb6\xc7\x68\x3e\x38\x9c\xbc\x35\x6f"
-  "\xd4\xe7\xfd\xc9\x1f\x0b\x43\x25\xeb\xdb\xe9\x1b\x82\xc2\xeb\x3e"
-  "\xcd\x63\x70\x72\xeb\xa2\x62\x11\xb4\xad\xe4\x3d\xa5\xc9\x07\x78"
-  "\xbf\x8b\xd7\xb9\xdf\x83\x9e\xf2\x75\x7b\x5c\x2c\xfb\xa1\x8f\xcf"
-  "\x34\x17\x03\x26\xf4\x7d\xe1\x48\xa7\x68\xdd\x3b\xbe\xde\xcd\x7b"
-  "\xa3\xaf\xca\x7d\xd8\xc9\xe0\x9f\xfb\xa4\x1e\xc6\xfa\x1e\xcb\x40"
-  "\xe8\x4d\x63\x4f\xd0\xb7\x67\xb2\x5d\xef\x77\x7e\x7b\xa2\x87\xe6"
-  "\xe8\xfb\x7a\x72\x7f\x17\x69\xd0\xff\xb2\x8b\x39\xad\x6c\x12\x59"
-  "\xcb\x6c\xa2\x67\x38\xdd\x47\xee\xb9\x1a\xe8\x0a\x94\x29\xd0\xe1"
-  "\x60\xbe\xf9\x79\x9f\x61\xe9\x52\xa4\xd9\x75\x38\xc8\x33\x0e\xcf"
-  "\xdb\x06\xf3\xa8\x32\x75\x11\x65\x96\xf6\x19\xa6\xfc\x1c\x69\xfb"
-  "\x62\xca\x1c\x8c\x29\xd3\x16\x51\xa6\x52\xab\xc7\x13\x53\xc6\x1b"
-  "\x5d\xe6\x3b\x74\x21\x6e\xdf\x49\x8d\x2e\xf3\x9d\xb4\x98\x32\x33"
-  "\x2e\xc4\xed\x3b\x73\x63\xca\xe4\xc4\x94\x29\x8a\xa0\x25\xef\xad"
-  "\x66\x22\xad\x3c\xa6\xcc\xf6\x98\x32\xf5\xfa\xf3\x70\x7b\xdc\xa5"
-  "\xbb\xc9\x0a\xbe\xec\xe1\xfe\x84\xde\xde\xdb\xf7\xfa\x33\x7e\xad"
-  "\x6c\x57\x9c\x76\xf5\xc6\xd4\x17\x8c\xae\x2f\x3d\xe9\xc2\x76\xa5"
-  "\xdb\xa2\xcb\xa4\x67\xc6\x94\xc9\x8a\x28\xd3\xa4\xea\x49\x5f\x12"
-  "\x53\xa6\x20\xa6\x4c\xd9\x85\x7c\x95\xbe\x2d\xa6\x4c\x5d\x4c\x99"
-  "\xbd\x5f\x43\x0b\x9e\x8f\x95\x2f\xc2\x78\xd6\x79\xef\xc1\x5c\x7f"
-  "\x43\x32\xdb\x32\x98\x4b\xbc\x3f\xe9\x0f\x8c\xe0\x39\x85\xe7\x9f"
-  "\x43\xf6\x00\xf4\xa5\xf4\x80\x87\xa6\x95\xe8\x73\x10\xef\x63\xf2"
-  "\x78\x56\xba\x72\x7a\xd7\x70\x3a\x25\xd7\xa3\xfb\x26\x70\x5d\x87"
-  "\x26\xb2\xee\x75\x43\xf6\xa0\x6e\xab\xf6\xeb\x49\xc1\xb9\xe1\x0d"
-  "\x86\xc3\xf5\x37\xaa\xfd\xd1\x04\xd6\xad\x0f\xd9\x65\x19\x7b\x84"
-  "\x3e\xcc\xf5\xfb\x0e\xac\x0f\x18\xa3\xf1\xb8\x21\xe7\x22\x78\x24"
-  "\x41\xc7\xb1\x76\x40\xff\xe0\x7d\xa0\xf6\x7a\xe8\x32\xd0\xdf\x19"
-  "\xb7\xe3\x74\x83\x47\xea\x56\x2b\xfb\x89\xef\xdd\xe5\x77\xc8\x7d"
-  "\x22\xa5\x5b\x4e\xb1\xb6\xa2\x7e\xd6\xc1\x5b\x4b\xce\x52\x9f\xd4"
-  "\xff\x59\x07\x9b\x72\xef\xa1\x72\x2f\xf0\x9a\x62\xd1\xf7\x4d\x3d"
-  "\x34\x25\x5b\xea\x0d\xae\x3c\x0b\xef\x61\xf1\xba\xef\x21\xdf\x4c"
-  "\xce\x03\xfe\xbf\x61\xa2\xde\x5e\xd8\x80\x18\x53\x37\xf4\x5e\x8c"
-  "\x66\xaa\x0f\xa7\x14\x47\xf3\xe4\x08\xf0\xca\x94\xca\xe8\x7e\x9f"
-  "\xe2\x8a\xee\xf7\x29\x4d\xd1\x3c\x69\x00\x4f\x4e\x39\x10\x53\xa6"
-  "\x35\xa6\xcc\x91\x88\x32\x2e\xad\x9e\x9e\x98\x32\x81\xe8\x32\x37"
-  "\x9a\x22\x9e\xd1\xc6\x1b\xad\x83\x36\x8c\xdc\x93\xbf\x31\x3d\xe2"
-  "\xd9\x50\x2b\xe5\xe7\x8d\xb3\xf4\x34\xde\x47\x6b\x78\x4d\xed\x09"
-  "\x6b\xf0\x72\x62\xc6\x3b\xe7\x2f\x8e\xc6\xe1\xc6\xf2\x18\x1c\x06"
-  "\xc7\x7f\x95\xb2\xc1\xfe\x70\x82\x32\x0a\x24\x0f\x61\x8c\x60\xbe"
-  "\x5e\xc4\xcf\x80\x55\x87\xfc\xa0\xc3\x8d\x07\x63\xe0\xb5\xc5\xc0"
-  "\x3b\x1a\xf1\x6c\xc1\x73\x6f\x44\x1b\x2c\x89\x56\xe9\x17\x03\x7d"
-  "\x2c\xc3\xa8\xa7\xb3\x6d\x08\x7c\x7b\x1c\x72\x9e\xc9\x62\x5f\x87"
-  "\x94\xe3\x74\xe3\x97\x6c\x47\x2a\x98\x19\x91\xe3\x9f\x54\xbb\x32"
-  "\xb2\xa3\xf1\xc8\x58\x12\x8d\x47\x46\x41\x44\xbb\x7c\xe6\x8d\xf4"
-  "\x80\x39\xf8\xe0\x0f\x59\xc7\x61\x1f\x1a\xe9\x73\xb0\x01\x7a\xd9"
-  "\x39\xb2\xb0\xaf\xc7\x89\x32\x4a\x74\xdb\x7b\x60\x93\xa5\x1d\x1d"
-  "\x96\x9f\x52\xf2\x6c\x9a\x7f\x8a\x0d\xf0\x5b\x75\x7e\x0c\xd7\xe4"
-  "\xd9\xc2\xd5\x37\x42\x27\xcb\x80\xfc\x9b\xb2\x58\xad\xb1\x4f\xe9"
-  "\x14\x8e\x9c\x3a\xd0\x13\xf6\xcd\xd4\x8f\x35\x7b\x60\x06\xfb\x2c"
-  "\x40\xf6\xf4\x60\x7e\x4f\x52\xfb\x5b\x53\x93\x22\xf8\xda\x67\x5b"
-  "\x7f\x97\x38\x4e\x53\x3f\xe1\xf9\x9f\xc7\x28\xfb\x3e\x1c\x0a\x7a"
-  "\x89\x6d\x68\x77\xf0\xa4\xd4\xd1\xf0\xbe\x53\x2b\x3b\x37\xa2\xac"
-  "\x57\xb3\x71\x7b\xf8\xdd\xf4\x20\x19\x0f\xf9\xbc\x04\x38\xa9\x4a"
-  "\xaf\x9b\xfa\xc9\x21\x8c\x57\x94\x29\xd7\xcb\xb0\x3d\xcc\x65\xcc"
-  "\x65\x64\x9c\x56\x4e\xc6\x96\xf5\xc7\x25\x6c\xad\xef\x7b\x58\x3f"
-  "\x76\x97\xf7\x90\xdb\xd7\xc5\x6b\x53\x46\xb5\x97\x3c\xb5\x33\x31"
-  "\x40\xa6\xbe\xea\x3c\x8b\x07\xf7\xa1\xea\x3c\x2b\x70\x43\xff\x64"
-  "\x48\x39\x17\x49\xbb\x7b\xef\x5d\xfc\xe0\xa2\x05\x53\x7f\xf0\xe0"
-  "\xbc\x25\xf7\xde\x61\x5b\xb2\xe2\xd9\xc2\x82\xa9\xab\x9e\x2f\xb3"
-  "\xad\x5d\xbd\xa2\x6c\xc5\xca\xa7\x6c\x99\xf6\xc9\x76\x5b\x7e\x99"
-  "\xba\xa6\x17\xe7\x97\x96\xcd\xe6\xdb\x0c\x5b\xc9\xea\xc2\x35\xf2"
-  "\xf6\x86\xd1\x14\x0d\x64\x45\x59\xe1\x6a\xdb\xe4\x82\x0c\xdb\x7d"
-  "\xf9\x2b\x8a\x9f\x5f\x5d\x18\x17\xd6\x1d\xb6\xd5\x85\xab\x0b\xf3"
-  "\x0b\x6c\xb3\x6d\x99\x0c\x39\x12\x5c\x44\x7f\x66\xea\xf3\x18\xcf"
-  "\x5f\x55\x4e\xd1\xa9\xcd\x67\x1e\xc5\x3f\xd3\xf6\x5c\x38\x97\x4d"
-  "\x6b\x8e\xe6\xb9\x69\x87\xa3\x79\x6e\x5a\xd7\x85\x73\xd9\xb4\x98"
-  "\xf9\x6f\x5a\xcc\xfc\x37\x3d\xe9\xc2\xb9\x6c\x7a\xcc\xfc\x37\x3d"
-  "\x66\xfe\x9b\x3e\x38\xff\x81\x97\x3c\x9b\xa4\x5c\x98\x1e\x33\xff"
-  "\x4d\x8f\x99\xff\xa6\x97\xc5\x3c\x6f\x8e\x78\x1e\x8b\xe7\xda\xc8"
-  "\xf9\x11\xcf\x7b\xf4\xf1\x39\x24\x5f\xa6\x37\xeb\x79\x58\xd6\x43"
-  "\x36\x77\x6b\x79\x3b\x23\xf2\xf6\x68\x79\xbb\x07\xc7\x1f\xf8\x88"
-  "\x7d\x44\x94\xdd\x9d\x39\x8f\x65\x3a\xfb\x87\xf0\xdc\x84\xf1\x71"
-  "\xed\x69\x9a\xfe\x11\xc3\x62\x1e\x96\xeb\x87\xaf\x3f\xea\x6f\x4c"
-  "\x21\x13\x97\x69\xac\x21\xa3\x70\x4e\x3d\x8a\x2b\x21\x2d\x09\x3f"
-  "\xc8\x94\xcc\x2c\x8f\xd1\xb2\x5d\xcd\x17\x99\x2e\xa9\xef\xa3\x8c"
-  "\x06\xbf\x9a\x9f\x01\xc7\x8a\x32\xa6\x2a\x35\x17\x77\xe3\x3e\x89"
-  "\x79\x1a\xe5\x8d\xc2\x30\x6d\x12\xae\x84\x34\x0b\x7e\xa9\x80\xe7"
-  "\xd2\xe1\xf1\x3e\x58\xbc\xf1\x1f\xbb\xbe\x3c\x68\xf3\x19\xc8\x5c"
-  "\xe5\x0c\x77\xb9\xc3\xac\x57\x67\xb6\xaa\x35\x82\x34\xe8\xf1\x1f"
-  "\xe6\x34\x22\x3d\xbe\x8d\x74\x13\xf4\xbf\xcc\x66\xb5\x6e\x72\x13"
-  "\xfa\xff\xbe\x6e\xb5\xb6\x99\xc6\x7b\xa6\xfd\x27\xe8\xa6\xb7\x71"
-  "\x1d\xc0\xf5\x25\x1d\x7e\x8b\xb4\x9d\x6f\xe2\x35\x8f\x87\x18\x6e"
-  "\x4c\xfa\x2c\xc8\xb7\x7e\x73\xb0\x32\x27\xce\xbb\x1c\xe1\x4c\x7c"
-  "\x30\x4e\x7a\x09\x74\x86\x7e\x0f\xdd\xb4\x87\xf1\x8d\x48\x87\x8d"
-  "\x3d\x66\x09\xe7\xf7\x70\x7d\x28\x33\x9c\xae\xad\xfb\x83\x29\xbf"
-  "\xcb\x9b\x8e\xc4\xb4\xe3\xab\x13\x74\xf3\x03\xaa\x1d\x37\xbf\x1b"
-  "\x53\x77\x6f\xfc\x76\xdc\x6c\x44\x3b\xbe\x8a\xdf\x8e\x9b\x6d\x92"
-  "\xb6\x06\xb4\xc5\x70\xc1\xbb\x59\x68\xcb\x57\x92\xee\xd1\xe9\x4b"
-  "\x34\x5d\xc8\x07\x1b\xcc\x82\x77\xb2\xec\x43\xe5\x43\xfd\xa6\xe5"
-  "\x2b\x37\xd7\xd1\xe2\x38\x75\xd6\x0a\xe7\xa8\x87\x3c\x74\x73\x9b"
-  "\x84\x33\x94\xbe\x4f\xe1\x02\x3a\x19\x24\x9d\x7a\xb9\xdc\x70\xfd"
-  "\xad\xdb\x25\x6a\x5d\xe3\x66\xf0\xec\x4d\xfb\xf5\x35\xc9\xd2\x72"
-  "\xe1\xd5\xe9\xe8\x77\xde\x62\x8d\x79\x17\x88\x78\x37\x23\xea\xdd"
-  "\x86\xc1\xf4\xf9\x7a\xfa\x37\xeb\xa7\x5b\xca\x63\xfa\x09\xfd\x33"
-  "\xe3\xf2\xe8\x76\xdf\xb2\x5d\xb5\x0f\x7d\x74\x01\xad\x6f\xd9\x8b"
-  "\x3e\x1a\x88\xdf\x47\xb7\xb4\xc6\xe7\xb5\x5b\x8e\x4a\x78\x29\x14"
-  "\x0f\x5e\x00\x7d\x37\x20\x79\x50\xeb\xa7\x0b\xfb\x67\xc6\x44\xbd"
-  "\x7f\xbe\x59\x1b\x67\xe4\xc5\xb4\x31\x04\x18\x9f\xa9\xb6\xde\x3a"
-  "\x35\x06\xb6\x3d\x3e\x2f\xce\x70\xa1\x9d\xa1\xf8\xed\x9c\xb1\x6f"
-  "\x78\x5e\x9c\x71\x18\xed\x09\x5d\xc8\x8b\xe8\x3e\x59\x86\xe2\x95"
-  "\x09\x0a\x67\xbc\x7a\x6e\x4d\x75\x04\x59\xcf\xbd\x75\x3e\xaf\x21"
-  "\x45\xa4\x67\x44\xf3\xdf\x0c\xbb\x2c\xc7\xf4\x0b\x2a\x39\xcb\xfd"
-  "\x70\xc2\x46\x86\xaf\xe3\x49\xbf\xf3\xd6\xed\x31\xb4\x3a\x73\x82"
-  "\xbe\x7b\x79\x9f\x21\x61\x8f\xa2\xd7\x77\x3f\x89\xc1\x69\x6f\x7c"
-  "\x7a\xdd\xda\x02\x7a\x9d\x89\x4f\xaf\x5b\x8f\x0e\x4f\xaf\x5b\xb9"
-  "\xff\xcf\x5c\x48\xaf\xef\x5a\x22\xe9\x05\x5d\x57\xb6\xef\x7a\x2b"
-  "\x78\x63\x20\x57\xf0\x1a\x1c\x68\x62\x31\x83\x57\x54\x99\x5e\x2e"
-  "\x93\x6d\x0e\x28\x3e\x81\x0e\x69\x3a\x4d\xdf\xcd\xd0\xc7\xff\x98"
-  "\x3a\x1a\x25\x06\x1e\x15\x80\x97\xc0\xe5\xdc\xf6\x33\x2d\xee\x60"
-  "\x26\xb1\xfd\x11\x53\xef\xb6\xf8\xb2\xe0\xbb\x4d\xa0\x69\x4d\x9c"
-  "\xf4\x66\xe5\x13\xf2\x5d\x6f\xb4\x8c\xf8\x6e\x67\x74\x1f\x81\x6e"
-  "\x28\x47\x43\x3e\xed\x17\xfd\x5d\xbc\xcf\x6e\xcb\xba\xb0\xcf\x6e"
-  "\x3b\xa6\xfa\xeb\xb6\x8f\xa2\xf1\xbb\x2d\x27\x7e\x7f\xdd\x56\x32"
-  "\x7c\x7f\xdd\xb6\x7d\xf8\xfe\xba\x6d\x2f\xf7\x97\x87\x6e\xf3\x44"
-  "\xcf\x1b\xb7\xb5\x44\xb7\xf7\x36\xde\x47\x31\x0b\xc3\xc8\xb1\xfc"
-  "\xfc\x4d\xdb\xad\xff\x58\xc6\x71\x5f\x35\x56\x10\x78\x39\x61\x12"
-  "\xe3\x78\xa9\x30\x86\x85\x0d\x1a\xba\xd6\xc7\xdf\x1f\x65\x1b\xb7"
-  "\xa3\x8e\x78\x2f\x9c\x6c\xd7\xb0\xee\x3e\xf3\x37\x61\x03\x75\xe1"
-  "\xde\x70\x82\xee\xd8\x18\x36\x18\xca\xd9\xcf\x52\xfa\x57\xca\x35"
-  "\x84\x99\x6d\x91\x7d\xc1\xbe\x38\x6c\x9b\xee\x54\xb6\xd3\x5f\x4f"
-  "\xd0\xed\x4b\x55\xbf\xdc\x91\x1f\x4d\xc7\x99\xde\xf8\xfd\x72\xbb"
-  "\x09\xfd\xf2\xd7\xf8\xfd\x72\x7b\xda\xf0\xfd\x72\x7b\x16\xfa\xe5"
-  "\xaf\x17\x8e\xa3\xdb\x73\xb4\x71\xb4\x89\xcb\xd8\x56\xb2\x3d\x7e"
-  "\xfb\x1f\x39\x0f\xee\x31\x46\x6e\xff\x25\xbf\x9f\xda\xab\x8f\x23"
-  "\x59\x66\x3b\x60\xc9\xfa\xb5\x3c\xdb\x34\x18\x91\x70\xf7\x9b\x7b"
-  "\xe3\x8d\x93\xdb\x0f\x73\xde\x69\x25\x64\x02\x0d\x73\x76\x33\x8c"
-  "\xd5\x44\xa7\xe9\x8e\xab\x39\x1f\xa7\x4f\xf3\x45\x8e\x93\xdb\x03"
-  "\x7a\x3e\x96\x75\x2a\xef\xed\x5e\xe1\x2f\x22\xce\x17\x0d\xfb\x0e"
-  "\xad\xfd\xa3\xe4\x3c\xc2\xf9\x39\x5f\x4c\x9e\xb9\x6a\x3c\xde\xb1"
-  "\x3d\x7a\x3c\xde\x91\x17\xcd\x9f\xa0\x3f\xca\x85\x21\xe7\x70\x7f"
-  "\x00\x38\x7c\x63\xfe\xba\xf8\xd8\xbc\xe3\x68\xcc\xd8\x04\x0f\x7c"
-  "\x6f\x83\xe2\x81\xef\x3d\x16\x83\xab\x2f\x3e\x0f\x7c\x2f\x69\x78"
-  "\x1e\xf8\x5e\xfa\xf0\x3c\xf0\xbd\x6c\xe6\x01\x0f\x7d\xaf\x3c\x7a"
-  "\x6c\x7e\x6f\x59\x74\xdb\xef\xf0\xa9\xb1\x49\xc9\x97\x32\x36\xa1"
-  "\x0b\x8d\x1d\x6e\x1c\xf2\x98\x42\xdd\x09\x8d\xfd\xfa\x7e\xc6\x37"
-  "\xa2\x99\x09\xe3\x0a\xf8\xcd\xb2\xf0\x9a\x12\x64\xfc\x4c\xa6\x61"
-  "\x83\x3c\x6b\x33\x2b\x2d\x92\x8e\x3b\xd5\xb9\x17\x07\xf2\xbe\xc3"
-  "\xfb\xc3\x8a\x9e\xb3\x9f\x8b\x6e\xff\xac\xec\xf8\xf4\x9c\xb5\x0c"
-  "\xf4\x74\xc4\xa7\xe7\x2c\xfb\xf0\xf4\x9c\x55\xcb\x3e\xfb\x17\x8e"
-  "\xa9\x59\xfb\x6c\x6b\xa4\x8e\x22\xcb\x9c\xa6\xd9\x23\xbe\xd9\xfc"
-  "\x34\xab\x3b\x7a\x7e\x9a\xd5\x76\xe9\xf3\xd3\xec\xf4\xf8\xf3\xd3"
-  "\xec\xac\xf8\xf3\xd3\xec\x1c\x35\x1e\x66\xbb\xa2\xc7\xc3\xec\x92"
-  "\x68\x9e\x00\xed\xfe\xdb\xe6\xa7\xd9\x9e\x98\x31\x50\x75\x82\xee"
-  "\xcc\x87\x4e\x51\xa9\xfa\xed\xae\xc9\x31\x38\x06\xe3\xf7\xdb\x9d"
-  "\xa9\xe8\xb7\xaa\xf8\xfd\x76\x67\xe6\xf0\xfd\x76\xe7\x7c\xf4\x5b"
-  "\xd5\x85\xfd\x76\x67\xc1\xa5\xeb\x14\x77\xd6\x45\xf7\xd9\x9d\x95"
-  "\x97\xde\x67\x77\x1e\x8d\xdf\x67\x77\xfa\xe2\xf7\xd9\x5d\x49\xaa"
-  "\xcf\xee\xca\x8e\xee\xb3\xbb\xd2\xa2\xfb\x6c\x76\xf0\xef\xed\x33"
-  "\xf4\x8f\x51\xf9\x19\xdc\xf5\x36\xec\xf6\x51\x7e\xe7\x5d\xf5\x1e"
-  "\xca\xd2\xf6\x70\xb3\xd4\xdc\xa1\xfa\xf0\x7d\xe4\x71\x5d\x38\x0f"
-  "\xdc\xd5\xac\xa5\xfd\xe0\xc2\x7e\xb8\xeb\x08\x64\x74\x6f\x6b\xb9"
-  "\xdc\xd7\x52\x7d\xc8\x34\x47\xbe\x96\xf5\xbc\x37\x75\x97\x8f\xcb"
-  "\xa2\x8f\x85\x3b\x10\x24\x96\xeb\xc8\xef\x63\x38\x7c\x56\x29\x1a"
-  "\x56\x96\xed\x52\xe6\xf8\x8b\xf8\xc6\x18\x5b\x2a\x6e\x06\xbc\xbb"
-  "\x6f\x55\xbc\x9a\x15\xab\xff\x36\xe2\xdd\x65\x8a\x4f\xef\xf9\x4b"
-  "\x0c\x0e\x7b\xe2\xf3\x69\xd6\x41\xb4\xa1\x31\x3e\x9f\x66\x75\x0d"
-  "\xcf\xa7\x59\x2c\x33\x1b\x23\x6c\x9f\x94\xc7\x83\x9e\x18\xdb\xe7"
-  "\x6e\xab\xd9\xa7\x78\x47\xea\x44\xd5\x69\x46\xbf\xf3\xee\x58\xfd"
-  "\x0f\x7d\x73\xf7\x07\x1a\xce\xbf\x89\x29\x3f\x8c\xfe\x77\x37\xeb"
-  "\x7f\xef\xc7\xc7\xf9\xee\x8b\xe8\x7f\x77\xb3\xfe\xf7\xfe\x85\x63"
-  "\xeb\x6e\x4d\xff\x8b\x67\xe3\xdd\x7d\x34\x7e\xff\xdf\x1d\xd3\xff"
-  "\x94\x53\x06\x7b\x58\x96\x8f\xca\x77\xcf\xc4\xc8\x7c\xec\x63\xc4"
-  "\x79\x99\x47\xe2\xe4\x9d\x1b\x0b\x73\x98\x7c\x25\x17\xf0\x1e\xfb"
-  "\x44\xc5\xe5\xbd\x7b\xea\xd5\x78\xbc\xc7\x17\x3d\x1e\xef\x39\x10"
-  "\x3d\x1e\xef\xce\x89\x29\x77\x24\xfa\x3d\xf8\xe7\xbf\x4d\xc6\xce"
-  "\xc9\x8e\xe1\x81\x0f\x4f\xd0\x9c\x8f\x14\x0f\x64\x5f\x19\x8d\xc7"
-  "\x9c\x65\xf1\x79\x60\x4e\x19\xda\xff\x61\x7c\x1e\x98\xe3\x1a\x9e"
-  "\x07\xe6\xec\x03\x2d\x3f\x8c\xe4\xdb\x87\xca\xb3\x46\xc5\xe4\xe9"
-  "\x8c\x2f\xf3\xe6\xf4\xc4\x5f\x23\xc8\x26\x45\xe3\xec\x99\xd1\x34"
-  "\xce\xb6\x46\xd3\x10\x6d\xf9\xfb\x69\x38\x78\xd6\xd7\xef\xcc\x8e"
-  "\x1d\xff\xee\x13\x74\xaf\x36\xfe\xef\x8b\x91\x75\xd9\x7b\x14\x2e"
-  "\xf1\xd6\x45\xb2\xd9\xfe\x75\xc7\xa7\x65\xf6\xd1\x61\xda\xcc\x3e"
-  "\x6d\xee\xf0\x05\x63\xe9\xde\x24\xa4\x3f\xc4\xeb\xa1\xbc\x1e\xd2"
-  "\x80\xf4\x87\x82\x64\x92\xf3\xd5\xe0\xbc\x74\x2f\x9f\xbd\x14\x4c"
-  "\x7f\xe6\x5f\xf3\x44\x5a\xcc\x73\x10\xe3\x95\x5b\x2e\x7d\x16\xcc"
-  "\x9b\x99\xd7\xaf\x63\x5e\xbf\x57\xea\x7f\xbc\xcf\xc2\xfe\x80\x66"
-  "\x3b\x2d\x76\xfb\x82\xa4\xf3\x3b\xe7\x8f\x81\xbd\x9d\xc7\x05\xe7"
-  "\xd7\xf3\xaa\x75\xb3\xca\x18\xd9\x74\xef\x81\xf8\x7d\x7c\x6f\xdb"
-  "\xf0\xbc\x73\x6f\x8f\xea\xe7\xfb\x26\x46\xf7\xf3\x7d\xd0\xff\xc6"
-  "\x2c\xe1\xb6\x82\x07\x2e\x69\x9c\x94\xd9\x84\x77\x58\x79\xbf\xe9"
-  "\xd1\xae\x92\x0a\xba\xe6\x24\xdd\xb7\x59\xd6\x67\x10\x01\xf3\xc6"
-  "\x04\x6a\x95\x32\xe0\xbe\x7f\x97\x78\x22\x4f\x6e\x90\x0c\x62\xd3"
-  "\x33\x5d\xfc\xae\xd1\x29\x02\xc8\xd7\xc9\x7b\x02\x7c\xd6\x0f\xbc"
-  "\x30\xf6\x38\xdd\xb7\x3b\xaa\xbc\x91\xc8\xad\x60\x74\x35\xca\xf1"
-  "\x78\xdf\x11\x7d\x4d\x77\xf3\x30\xfe\x41\xc8\x13\xd0\x7d\x1f\x94"
-  "\xef\xd7\x7d\xc3\xee\x5f\x32\x4e\xec\x1f\xcf\x38\x5d\x5c\x0e\x7c"
-  "\x7f\xbe\xce\xbf\xca\x67\xf2\xfb\xcb\x86\x7c\xf2\xbe\x5f\xe4\xa1"
-  "\xef\x0f\x7b\x9e\x23\x7a\x1c\x7c\xbf\x36\x12\x8e\x3a\xef\xfe\xfd"
-  "\xbd\xba\x5f\x1d\xee\x0f\x7c\x0d\x2c\x1d\x9f\xa3\x31\xf8\xf4\x42"
-  "\x4f\x69\xd5\x60\x04\x2e\x06\x83\xfb\x5c\xf1\x2c\xf3\xc3\x5c\xcb"
-  "\xc5\xd6\xfc\x12\xad\xb4\xf8\xd5\x0b\x78\x6b\xae\xd4\x97\x18\xc6"
-  "\xc5\x71\x9c\x5b\x19\x65\x5b\xc8\xbd\x7b\xde\xdb\x9a\xb7\x40\x8d"
-  "\xfb\x79\x31\x6b\x84\x73\xeb\xa5\xdf\x94\x36\xee\x1f\x0f\xc6\x8e"
-  "\x83\xb9\x07\xf5\x39\x3a\x26\xfd\x88\x3e\xee\x61\xd7\x32\xdc\x98"
-  "\x75\xd6\xb9\x3e\x35\x16\xe6\xcd\x0f\x27\x47\xda\x6b\xf3\xa4\xfe"
-  "\xa7\xaf\x97\x7a\x90\x2f\xba\xdc\xbc\x98\xf5\xbf\xb9\xf5\x62\xf8"
-  "\x75\xfa\x24\xf4\xaf\x8f\xf7\xb6\xd4\xd9\xe1\x79\xe5\x31\xeb\x15"
-  "\xde\x9d\xf2\x9c\xe8\xa7\x80\x7b\xbf\x26\xf7\xee\xff\x32\xa6\xbe"
-  "\x7a\xc7\xa9\x8b\xb5\x7f\xde\x30\xed\x9f\x37\xd4\xfe\x95\x12\x6e"
-  "\xcc\x5a\xe2\x3c\xd9\xfe\xd0\x05\xf2\xef\xfe\x24\xc8\x2f\x9d\x6e"
-  "\xd0\xb9\xef\x2f\xd4\x75\x75\x5e\x3f\x18\x5e\x57\xbf\x7f\x68\xfd"
-  "\x4f\x95\x1b\x5a\xff\xf3\xc6\xd3\xd5\x3d\x24\xf7\x56\xa3\xeb\xde"
-  "\x66\xae\x8f\xd7\x96\xfb\x87\x59\xff\xbb\x5f\x5b\xff\xfb\x27\x4b"
-  "\xb4\x3c\xbb\xbf\x33\xba\x0f\xe7\xc5\xf4\xe1\xfd\xde\xe8\x3e\x9c"
-  "\x57\xff\x5f\x9d\xd7\x78\xe2\x4c\x4c\x4c\x34\x24\x26\x18\x12\x12"
-  "\xf1\x1a\x4d\xa4\x51\x89\xc6\xc4\x11\xf8\x8d\xd4\xae\xa3\x0c\x89"
-  "\x06\x23\x7e\x23\xb4\xeb\xc8\x98\xe7\x51\x5c\x16\x3f\xa3\x76\x1d"
-  "\x11\xf3\x3c\xf2\x6b\xde\x8f\xd2\xea\xd5\xeb\x37\xc6\x3c\x8f\xf8"
-  "\x9a\xf7\x23\xff\xce\xf2\x74\xc1\x73\xb4\x1f\xda\xbc\x95\x6b\xf2"
-  "\x8b\x57\x14\xc8\xfd\xe2\x42\x5b\xfe\x93\x4f\x16\x96\x96\xda\xca"
-  "\x56\xd9\xee\xb9\xfb\xc1\x9b\xef\xb0\xa9\x6d\xe7\xe2\xd9\x93\x0b"
-  "\x46\xd3\x82\xb5\xab\xf9\xc5\x82\x87\xe6\xe5\xd8\x16\xdf\x73\x77"
-  "\xf4\x4b\x1d\x8c\xdc\x5e\xbe\x18\x94\x88\xf1\x97\xf5\xd2\x78\xa2"
-  "\xed\xe3\xa5\xec\xe9\x6e\x6f\x22\x52\x6b\x1e\x0f\xe4\xb7\x41\x9b"
-  "\x10\xfd\x0e\xd1\x72\x1d\xef\xe9\x2f\x90\x3e\xc2\x53\x9b\x2a\xa9"
-  "\x64\x39\x9f\x37\x59\x70\x93\xf8\xbd\x97\x6c\xf7\x93\xe1\x38\x3d"
-  "\xfc\x5c\x2b\xb4\x5a\x7e\x76\x77\x07\xc9\xe6\x20\x13\xca\x27\xe3"
-  "\x5d\x82\xb8\x33\x8c\x34\x9f\xe6\xd3\xbc\x78\x92\x4c\xfb\x7d\xa5"
-  "\x9e\xcf\x7c\x82\x16\xfc\x45\xfc\x5e\xc8\x67\x71\xa7\x4b\xcb\xb7"
-  "\xe0\x9d\xb0\x73\x7e\x11\xcb\x86\xfa\x1a\x32\x36\xd4\x10\xbd\x91"
-  "\x42\xa6\x37\xc6\xf3\x19\xfa\x05\xf5\xfa\x5e\xe8\x4b\x78\xf6\xd0"
-  "\xc3\x25\x5c\x37\xe7\x0d\x1b\xe6\xd7\xc8\xfc\x29\x51\xf9\xdb\x86"
-  "\xf6\x62\x17\xd4\x1b\x90\x6f\xd1\xe7\x64\x0e\xa4\x5c\xe5\x71\x97"
-  "\x57\x92\x39\x24\xbe\x9c\x36\x97\x12\x3a\x30\xfb\xae\x0b\x8a\x60"
-  "\xcb\xea\x93\xa8\x7f\xe1\x95\xe6\x75\xe2\x4b\x37\x46\xff\x82\x5e"
-  "\x87\xd8\x79\x8a\x8c\x18\xd7\x09\x2d\xab\xd9\x4f\x61\x21\x35\x7c"
-  "\x45\x46\xd0\x60\xe2\x49\x5a\x94\x59\xbe\x40\x84\x1c\x0b\xc8\xf8"
-  "\x6f\x76\xf6\x37\x4c\xab\xd8\xf9\x67\x32\xfe\xa2\xbf\xd2\xd0\x2f"
-  "\xac\x54\x5e\x26\x7a\x04\xc7\xd6\xf0\x89\x00\xfb\xeb\xb7\xe5\x85"
-  "\x38\xcf\x4a\xbf\xc3\x4a\x1d\x65\x3e\xda\x70\x54\x04\xb6\xfd\x59"
-  "\xf9\xf9\xb7\xf7\xfa\xd8\x7f\xd1\xb4\x61\x01\x25\x9e\xc8\x21\x43"
-  "\x7b\x51\x1d\xb9\x97\xf9\xa8\xfc\xa8\xe8\x69\xcb\xfb\x9c\x3a\x8a"
-  "\xf6\x53\x6e\x17\x19\xda\xba\x3f\x23\x19\x1f\xa2\xe6\x15\x4f\xc5"
-  "\x39\xb2\x6e\x58\xc1\x69\xe7\x68\xfd\x06\xba\x7c\xfd\x5f\xc8\xec"
-  "\xee\xe9\x42\x3d\xa7\xe8\x91\x23\x94\x00\x78\x86\x17\x3e\x23\xeb"
-  "\x0b\x3f\x64\x7f\xde\x2c\xaa\xaf\x20\xab\x70\xa4\x27\xf5\x3b\xd2"
-  "\x2d\xfd\x22\x3d\xc5\xef\x48\x4f\xed\x28\x41\xfe\xee\x0f\x68\x4c"
-  "\x17\xa5\xfe\xfe\x64\x97\xa1\xee\x2c\x4d\xb4\x2d\xe4\xfe\x5f\x94"
-  "\x51\x7f\x16\xf9\x6b\xf2\xf3\xc2\x28\x1b\x59\x26\x98\x9c\x6f\x77"
-  "\xe7\x04\x28\x0c\x58\x75\xfd\x34\xb1\xbe\x9f\xac\xe1\xea\xfc\x3c"
-  "\xa6\xc5\x40\xcd\xf5\x1e\xc8\xc2\x51\xef\x3f\xd1\x6c\x74\xb7\xf5"
-  "\x52\xbb\xaf\x9f\x3a\xe8\x53\x72\xdb\xff\xd6\xf2\x8b\x27\x9a\x47"
-  "\x84\xc1\xfc\x2d\xeb\xbb\x01\x5f\xf1\x8c\xa3\x9d\xcf\x25\x56\x52"
-  "\x55\x05\x25\x95\xac\xa7\x51\x27\x91\xae\x6c\xfa\xf1\x3d\xee\xe0"
-  "\xdf\x5a\xd6\x4b\x1f\xdc\x87\x4b\x2a\xda\x29\xb1\xc3\x57\xc7\xbe"
-  "\x9e\x86\x50\xca\x2b\x1e\xb7\xaf\x93\xdc\x25\x7f\x6d\x09\x5b\x5e"
-  "\x39\xbc\x3d\x4c\xa6\x77\xcf\x77\x1a\xdc\xc6\xf3\xe4\xce\xf1\xd1"
-  "\x87\xa8\x5b\xd4\xbc\xc2\x7b\x9e\x59\x1d\xbe\x00\x9f\x4b\xca\x14"
-  "\x7d\xd6\xd1\x55\xab\x29\xa3\xe1\x2c\xa5\xed\x3e\x4b\xe9\xc2\x9f"
-  "\x6e\x60\xbf\xda\xc7\x4e\x59\x68\x37\xae\x49\xdd\x64\x42\x7b\x95"
-  "\x4f\x75\xb2\xe6\x5f\x3b\x90\x4e\x8d\xfd\x43\xfe\xb5\xfd\x7d\x43"
-  "\xfe\xb5\xe0\xa5\x26\xf6\xb1\xc5\xb8\xc8\x61\x7e\xae\x3a\x4d\xc6"
-  "\x4d\xa7\x89\xa6\x55\x1a\xc8\xf6\x04\x9f\x8f\x78\x60\x84\xbb\xe0"
-  "\x94\xbc\x3f\x4e\x8b\x0f\xe2\x9a\x84\x5f\x02\xc6\x80\x5c\xcf\xee"
-  "\xd6\xf8\x16\x69\x06\xa4\xbd\x8d\x6b\x22\xae\xbb\x1d\xf5\xc2\x2b"
-  "\x5c\x93\x67\xf4\x19\x68\x34\xf3\xaf\xf2\xe5\x9d\x3c\xc3\xef\x5c"
-  "\x0c\xfd\xa7\x30\x55\xe7\x63\x25\xd3\x17\x34\x7d\x78\xe2\x14\xc7"
-  "\x6b\xf1\x4a\x7c\x06\x8a\x12\x38\x76\x8b\x96\x0e\x1c\x16\x87\xb8"
-  "\x5e\xd4\xef\xc1\xd5\x8c\x1f\xc6\xe5\xe2\x32\xbd\x6c\xdf\x40\x11"
-  "\xd7\x79\x0e\xe9\x42\x4f\x47\x7b\x8d\xfc\xee\xd7\x27\x4e\x19\x54"
-  "\x9e\x74\x03\x60\x06\x34\xf8\x18\xeb\x0b\xb2\x79\x4c\xf7\x19\xcc"
-  "\xe2\x50\xc1\x0c\xaa\x1f\x2f\x3a\x77\xbf\x26\x5a\xd5\x58\x7b\x60"
-  "\xa6\x87\x96\xdb\x18\x47\xcc\xdb\xad\xdb\xf1\xee\x90\x8d\x88\xe9"
-  "\xd2\x9a\xc7\xfe\x63\x0f\xe4\x78\x68\xf4\xd1\xc8\x36\x08\xe7\x3f"
-  "\xcd\xe5\xb9\xf3\xbd\x8a\x96\x11\xc2\x30\x7f\x6e\x87\xa7\x97\x7e"
-  "\xd1\xdf\x33\xc2\xf1\x47\x32\xb8\x83\xc7\x69\x7a\x2a\x59\x59\xff"
-  "\x6b\x7c\x4d\x78\x70\xed\x61\x7f\x4e\xf0\xc9\xd5\x27\xe9\x81\xb7"
-  "\x6f\x4c\xa5\xd4\x3f\xd9\x49\x93\x47\x0f\x7c\x10\x21\x8f\xee\x6d"
-  "\xef\x6e\x8e\x90\x45\x4b\xcf\x5d\x28\x8b\x96\x7c\xa9\x64\x91\x08"
-  "\x2a\xd9\x13\xf2\x68\xe9\x9f\xc5\xa4\x6b\x7e\x21\x4b\x3e\x8a\x49"
-  "\x0f\x68\xe9\xef\xc6\xa4\x7b\x55\xfa\x43\xa7\x74\x59\xd7\xc1\x78"
-  "\xac\x65\x59\xf7\xd0\x27\x2c\xeb\x3a\x0a\x34\x59\x27\x7d\x0c\x1f"
-  "\xfa\x8d\xf8\x71\x25\xf1\xd9\x23\xdc\xef\x60\xfc\xc5\xef\x49\xc7"
-  "\xfd\x32\xa4\x2d\xe0\x34\xd7\xa7\x64\xc4\x4f\xca\x39\xe1\x9c\xff"
-  "\x3e\xcb\x39\x96\x71\xec\x77\xb2\x6b\xbc\xe8\xda\xf5\x9a\x38\x52"
-  "\xff\x9a\x68\xf3\x3b\x1f\x3c\xa8\xcb\xbb\x57\x90\xb6\x1d\x69\xaf"
-  "\xe0\x3d\xcb\x3d\xa6\x49\x7b\x4e\x33\xeb\x93\xdd\xe0\xe3\x72\x73"
-  "\x02\x95\xec\x04\xcf\xf3\x79\xc0\xcd\xa0\xaf\x1b\x32\x89\xcf\x72"
-  "\xc9\x38\x27\x86\x4c\xc8\xa8\x6e\x1e\x6f\xe3\x37\x61\x7c\xb9\xed"
-  "\x9f\x53\x85\x4f\x9c\xe4\x73\x71\x8c\x43\xee\xba\xfb\x39\x8e\x47"
-  "\x42\x6b\x11\x11\xfb\x80\xb3\xbf\x0a\xe4\xae\xd1\x05\x9c\x0e\x15"
-  "\x73\x5f\x3f\x04\xfb\xff\x0d\xed\x3c\xd2\xc3\x25\x1c\x17\xe8\x38"
-  "\x3d\xb8\x0d\xf6\x5d\x80\xdb\x66\x0e\x55\x12\x9f\x5f\xc1\x18\x65"
-  "\x1b\xaf\x68\x17\x7e\x2e\xfd\x0c\x0b\xc7\x76\x42\x1e\x77\x57\x80"
-  "\x18\x67\x0f\x3d\x78\xa4\xbd\xbc\x99\xcb\xdb\x99\x36\xc2\xe9\xd0"
-  "\x61\x24\xc8\x33\x30\x4e\x32\xf1\x19\x18\x0f\x3d\x54\xa4\x74\x9a"
-  "\xeb\x3d\xed\xcb\xbc\xc4\x72\xde\xdd\x03\x18\xe5\xc7\x15\x0c\xc0"
-  "\x12\x90\xfb\x51\xef\x34\xf8\x97\x6f\x10\x5f\x02\x7e\x36\xf7\x17"
-  "\x9f\x5b\xe4\xfd\x35\xd0\x25\x89\xfd\xe2\x95\xee\xf9\x60\x7b\xe3"
-  "\xa7\x44\xda\xd9\x4b\xf0\xdb\x83\x6d\x7c\xde\x88\xcf\x5b\xca\xb3"
-  "\x96\x86\x19\x24\xd6\xa6\x27\x0d\x9e\xb7\xfc\xbf\x70\xd6\x12\xf4"
-  "\xb7\x36\x18\xc4\x7e\xe0\xdf\xc6\xe7\x2d\x81\x7f\x06\xf3\xa1\xd6"
-  "\xa6\xce\x1f\x3d\x22\x69\x9e\xca\x69\xb0\x15\x0f\xeb\xfd\xcf\xed"
-  "\xe5\xb6\x1c\xa7\x07\x02\x4a\x27\x14\x9d\x1e\x5a\xd2\xc9\xef\x91"
-  "\xd6\xcd\xf9\xa7\x43\x8e\xb9\x0b\x42\xf4\xfe\x89\x90\xa1\x6a\x3d"
-  "\x19\x95\x4c\x5b\xfa\x05\x97\x57\x32\x6d\x69\xd3\x90\x4c\x5b\xfa"
-  "\x23\x25\xd3\x14\x8d\x95\x4c\x5b\xfa\x92\x92\x69\x4b\x37\xca\x7d"
-  "\x30\xc8\x34\x7e\xc7\x72\x4d\x97\x69\xbb\xc7\x8b\xc3\x2c\x3b\xfc"
-  "\xce\xa5\x25\xba\x6c\xdb\x81\x34\x96\x1d\x8c\xa3\x92\x53\x0f\x1d"
-  "\x16\xff\x7f\x3a\x29\x3f\x03\xbe\x2f\xe2\xb3\x0a\x3d\xda\x3d\xfa"
-  "\x65\xe9\x31\x25\xe3\x96\xb6\x0e\xc9\xb8\xa5\x73\x87\xca\xb2\x8c"
-  "\x5b\xfa\xef\x4a\xc6\xa9\xf4\xc6\x47\x58\xc6\x3d\x74\x98\x69\xa0"
-  "\xc1\x37\xf0\x9a\x9d\x96\x1f\x74\x7c\xa0\x33\x52\xc6\x45\x8f\xaf"
-  "\x87\x27\xea\x32\x8e\x65\x1b\x9e\x33\x20\xd3\x64\x9c\x31\x1e\x67"
-  "\xb5\xa0\xb9\x3e\xee\xb8\x0f\xb8\xcd\x1c\xff\x87\xe9\x36\xe7\x14"
-  "\x8d\xd2\xce\xfd\x68\xed\x7e\xb8\x48\xf7\x75\xf4\xd0\xd2\x92\x78"
-  "\x7a\xb3\xae\xa7\x81\x1f\xaf\x0d\x61\xbc\xb9\x2b\x31\x97\xd6\x89"
-  "\xca\x8e\xe0\x11\x7a\xbc\x8c\x0c\xe1\xc4\x67\x8e\x71\xdf\xc2\xce"
-  "\x18\xc9\x57\x96\x3d\x98\x43\xdf\xcd\xf5\xd1\x48\xd8\xe6\xc7\xaa"
-  "\x0c\x78\x67\xa7\xef\x45\xbc\xfb\x23\xd7\x13\x51\x6e\x6a\xc4\xbb"
-  "\xcf\xa5\x8e\x77\x9a\x63\x3f\x3d\xec\x1a\xce\xf6\xbf\x34\x5c\x7e"
-  "\x70\xfb\xf0\xb8\xfc\x60\xe9\xf0\xb8\xfc\x40\xea\x01\x53\x7b\x29"
-  "\x01\xb6\x59\xf2\x69\xfa\x81\x5c\x8f\x91\xb1\x2b\x36\xc5\xad\xe7"
-  "\x2d\xed\xfd\x88\x88\xf7\x91\x75\x7d\x14\xa7\x7c\x64\x7d\xc7\x2e"
-  "\x0e\x3f\x27\xe1\xe2\xf0\x73\x26\x5d\x1c\x7e\xce\xdd\x2c\x03\x41"
-  "\x3b\x73\xd8\x10\x9d\x6f\x5a\x50\x8e\xc1\xc3\x7c\xee\x0e\xf9\x56"
-  "\x68\x6b\x3e\xc7\x1c\x93\xa4\x2d\x28\xcf\x66\xed\xc4\x7b\x3e\x4b"
-  "\xce\xf2\x39\x7b\x1d\x91\xda\xa3\x1e\x2c\xb3\x3b\x16\xb7\x31\x41"
-  "\x1d\x37\xf9\xfe\x83\x58\xdc\xf0\x7e\x6a\xc4\xfb\xcf\x86\xfa\x3d"
-  "\xe7\xa2\xfe\xf5\xee\x3a\x22\x8e\xa1\x77\x08\xe6\x0b\xe6\x64\x8e"
-  "\xc7\xa5\xad\xcf\xfc\x70\x06\xe4\x7c\x65\x84\xdf\x2e\xeb\x5f\xd7"
-  "\x76\xf8\xf8\x9c\xaa\x4f\xad\xc3\x86\xe8\x0a\xcc\x27\x29\x7c\x56"
-  "\x87\xcf\xed\xe4\x86\x16\x1b\x54\x4c\x9c\x1f\x96\xe8\x65\x87\x5b"
-  "\x07\xe2\x7a\xb5\x3a\xd9\x07\xd6\x87\x32\x7b\xf4\x32\x0c\x9b\xfd"
-  "\x28\x31\x0f\x5c\x2b\xcf\xae\x06\x7b\x59\xee\x5e\x01\x3d\x39\x45"
-  "\xd5\x93\x47\x5a\x3d\xb0\x63\x7f\x90\x74\xb1\xb3\x23\xc3\xb7\xef"
-  "\x91\xd4\x4b\x6f\x1f\x69\xed\x7b\x64\xf1\xd7\xb4\xef\x62\xf5\x6e"
-  "\xbf\xf4\x7a\x2d\x7a\xbd\x87\x2f\x9d\xae\x8f\x04\xbf\x39\x5d\x33"
-  "\x35\xba\x3e\x9a\xf9\x35\x74\x8d\x53\xcf\xa3\x05\xdf\xbc\x1e\x9b"
-  "\x5e\x4f\x5d\xbc\x7a\x48\xfe\x0d\x7b\xae\xcb\xa4\xc7\xa6\xe3\xb8"
-  "\x90\x2a\x26\xd5\xa3\x9e\xc8\xd8\x99\x2a\x5e\xe4\xa3\x3e\x3d\x76"
-  "\xa6\x16\xc3\x12\x73\xcb\xb2\xe4\xdc\x26\xd6\x47\x44\xd8\x43\xcb"
-  "\x52\x39\xee\x61\xf6\x86\xc8\x18\x93\xcb\xd2\x2f\x16\xb3\x93\x63"
-  "\xe5\x08\x91\x43\x87\xea\xa4\x3f\x00\xe6\xa1\x65\xf9\x7c\x3e\x40"
-  "\xed\x67\x2e\x2b\x56\x63\x72\x59\xb1\x87\x1e\x6d\x1e\x1e\x46\xde"
-  "\xe2\x3d\x15\x99\x23\x86\xf3\xf9\x47\xf9\x7d\x1e\x7a\x4a\xae\x5f"
-  "\x86\x6a\xa6\x1e\x16\x67\xac\x5a\x2c\xae\xdc\xcb\x22\x62\x85\x61"
-  "\xee\x7e\xfc\x76\xed\x6c\x02\x68\x50\x09\x5a\x2e\xeb\xd6\x69\xa0"
-  "\xa7\x23\x2d\xa0\xd3\x00\xfa\x4a\x92\xbb\x29\xc8\x67\x87\x7c\xea"
-  "\xbc\xf7\x63\x57\x8b\xea\xbc\x2c\x05\xfb\x31\xb5\xcf\x90\x32\xf5"
-  "\xb0\xef\x05\xab\x41\x2f\x9f\x66\x73\x7c\xc5\x3c\xec\x4d\xce\xcb"
-  "\xf2\x3b\x1f\xcb\xd6\xe1\x0b\xc6\x4b\x0c\xe5\x6b\x94\x7e\x49\x8f"
-  "\xa1\xff\x1f\x9d\x25\xf9\x1a\x75\x48\xdc\x0d\x94\x18\x06\xfe\x68"
-  "\x83\xc1\x5d\xe2\x63\x3d\xb5\x37\x84\xf6\xb3\xac\x3b\xb0\xd2\x63"
-  "\xe4\x3c\x52\x77\x38\x93\x6e\x50\x71\xce\x1e\xfb\x20\x7c\x86\xe3"
-  "\x6d\x48\xbc\x92\xd0\x66\x13\xe3\xe4\xc1\xd5\xfb\x42\x3a\x2d\x3a"
-  "\x47\x1a\x2d\x1e\x7b\x3b\x8c\xf4\x70\xe9\x10\x0e\x0d\xf2\x8c\xc7"
-  "\x63\x3d\x3a\x0e\x61\xae\xdf\x6f\x35\x40\x17\xe3\x7a\x7b\xe4\x39"
-  "\x4b\xd4\x3d\x9d\xe3\x52\x71\x2c\x8b\xb5\xe9\xc4\x38\xf8\x9d\x8f"
-  "\x4f\xd4\xe9\xad\x95\xd1\xeb\x68\x0b\xcb\xba\x15\x6d\x14\x9d\x0f"
-  "\x41\x1f\x7c\x7c\xfe\x85\x74\x7e\x3c\x2f\x82\xce\x89\xcc\x57\xbc"
-  "\xc6\x82\x3e\x0a\x31\xbd\x79\x5f\xc3\xb6\x86\xf5\xaa\xc7\xab\x0f"
-  "\xf9\xa4\xdf\x49\x12\xc3\x0d\x83\xfe\x0c\x03\x70\xbf\xa5\x68\xfc"
-  "\xf8\xde\x41\x1a\xa3\x6e\x81\xbe\xd8\xa4\xce\xa4\xb0\xef\x3b\x64"
-  "\xc7\xe3\x87\x07\xeb\x61\x5c\x1d\x56\x43\x58\x58\xe5\x9a\x2a\xe3"
-  "\x5a\x66\x13\x01\xd6\x2b\xa5\x1f\x13\xda\x7a\xa0\xa2\xcb\x08\xdd"
-  "\xd2\x20\xeb\xea\x4b\x67\xfd\xde\x24\xef\x51\xd7\x30\xfc\xfd\x25"
-  "\xc7\x8e\xd3\xdb\x85\xb6\x98\x98\xb7\x80\x3b\xf4\xbf\xbc\xcb\x25"
-  "\xbf\xac\xe1\x7e\xca\xfd\x92\xd3\xf4\x7c\x78\xfe\x98\xf3\xe9\xcf"
-  "\x78\x07\xfe\xca\xdd\x82\x76\x8d\x66\x3c\xbd\x1c\x2f\x4f\xb6\x39"
-  "\x2f\x9d\x61\xf8\x9d\xb9\xae\xa8\x76\x0e\xe4\x18\x75\xbe\xe3\x3d"
-  "\xa2\x56\x5b\x40\xca\x4e\x45\xdb\xdc\x83\xfa\x98\xe4\xf2\x6a\x8c"
-  "\xe5\x76\x46\xf2\xa2\xcf\x31\xc4\x07\x65\x93\xc8\x64\xb4\x71\xbc"
-  "\xbb\xdc\xfd\x2a\xae\x6e\x6e\x30\xb6\xbf\xf8\x1d\xc7\x86\xd3\x68"
-  "\xc8\xe3\xc9\x72\x9c\x72\xbd\xdc\x36\xbc\xcb\xbe\xd8\x7c\xc9\x31"
-  "\xda\x38\xde\xde\xab\x6a\x1c\x81\x2e\xf9\x2b\x5e\x55\xe7\x7b\x7c"
-  "\x2a\x46\x5a\xde\xb3\xc2\xf0\x96\xec\x2f\xf6\xcb\x93\xf1\x30\x64"
-  "\xec\x89\x3c\xf6\x71\x13\x63\x4a\xde\x92\xb1\x12\x35\x9f\x3d\x6f"
-  "\x6b\x49\x50\xee\x07\x38\xca\xf8\x1c\x6c\x90\x6d\x32\xe9\x93\x76"
-  "\xa8\x2c\x48\x0f\x05\x98\xb6\x79\x07\xf9\xbc\xba\x4f\xd2\x22\xef"
-  "\xb0\x7e\x46\x9d\xe3\xbe\x71\x2c\xc1\xe9\x41\x4a\x64\x9d\xc2\xe6"
-  "\xe0\xd8\x02\xf9\x4d\xac\x93\x28\x9a\x82\xef\x0d\xa2\x53\xf1\x72"
-  "\x7e\x32\xc7\x66\x54\xfb\x4b\xc7\xc1\xdf\x89\x7f\x43\xde\x1b\xd4"
-  "\xba\x8c\x3e\xd6\xf2\xdf\xe2\x3d\x26\x8f\x06\xc3\xef\xcc\xc7\xfc"
-  "\xbf\xac\xf6\xc2\x71\x91\x9f\xac\xdb\x18\x7c\x2e\x4e\xed\x57\x0d"
-  "\xc1\x43\x79\xb9\x2e\x3d\x24\x9b\xfe\xc0\xb0\x2a\x2f\x1c\x33\xf9"
-  "\xb5\x3a\x2f\x97\x5c\xc7\xe7\xaa\xf3\x72\xb8\xfe\xe1\x64\xa6\x70"
-  "\xfc\x90\xfb\xc9\x74\xc2\x46\x89\x5f\x77\x5e\x62\x68\xff\x2b\x3f"
-  "\xa0\xb7\x41\xa7\x89\x6a\xc3\x13\x0f\xf4\xa5\xa4\x99\x86\xda\xfe"
-  "\xc4\x03\x92\x16\x43\xef\x5f\x8a\xa0\x0d\x3f\x6f\x53\x7c\xf7\xc4"
-  "\x5c\xf0\x87\xb6\x66\xa3\xd2\x44\x4a\xde\x1c\x8e\xd3\xa8\x70\x5c"
-  "\x41\x3a\xbf\x23\x6f\x99\x87\x4e\xa4\xab\x7d\xa8\x27\xd0\xfe\xfc"
-  "\x4e\xad\xdc\x44\xc6\x25\x6e\x3b\xa3\x70\x7c\x92\x78\x8e\x55\x71"
-  "\x0b\x9e\x4c\x60\x7c\x6d\xdf\xe6\x3e\x7e\xa2\x9d\xeb\x65\x9e\x10"
-  "\x03\x45\x23\x7c\x03\xe9\xd4\x37\x50\x84\xf1\x93\x6e\x40\x3d\x90"
-  "\x7f\x9f\x1b\xb5\x3a\x7d\x3a\xae\x8c\x1b\x74\x45\x93\x5f\xac\x88"
-  "\x4f\x5f\xae\x97\xc7\xfb\x40\xd1\x28\xfc\x4c\xf8\x8d\xfc\xa6\xf3"
-  "\x31\xf4\xda\x1e\x6f\xf5\x94\xb2\xf0\x1a\x71\x78\x51\x50\x84\x61"
-  "\x17\xf4\x54\x81\x7f\xc7\x6c\x6c\xa1\x31\xbe\xc7\x0c\xb9\xeb\x28"
-  "\x0b\xb6\x2d\x89\xf3\x62\x66\x43\x18\xd7\x35\x62\x06\xc7\xa3\xc5"
-  "\x73\xa6\xf6\x9c\xc1\xcf\x7d\x6b\xc4\x32\xbf\xf3\xc9\xbd\xfa\xde"
-  "\x9d\x8a\x3d\xf3\x64\xf3\x60\x1c\x9e\xc4\x47\xf9\x9c\x0f\x2d\xb2"
-  "\xa3\x8e\xc4\x67\x7a\xb8\xde\x5c\x9e\x3b\x50\x1f\xf2\x61\xfe\x5f"
-  "\x36\x83\xf3\x79\x13\xa7\xa4\xe0\x97\x3e\xcc\x1e\x67\x0f\xe3\xd5"
-  "\x97\x3c\xa5\x4c\xc7\x75\x8c\x2f\xcb\xf0\xcd\x70\x2b\xc8\xd6\x71"
-  "\x43\xfa\xe1\x2a\x95\x1e\xe4\x58\x64\xec\x83\x88\xf7\x05\x3a\xae"
-  "\x3a\x0e\x5c\x1f\x9f\xab\x14\x29\x69\x56\x8e\xed\xc2\xf5\x79\x5f"
-  "\x28\xe2\xbc\x2e\x1d\xdf\xaf\x3f\xfb\x13\x9f\xee\x1e\x2a\x38\xaa"
-  "\x78\xb2\xe0\xa8\x3e\x7f\xe1\xbe\x27\x7a\xbf\xb7\xa0\x33\x56\x96"
-  "\x3d\xb1\x6a\x55\x59\xee\xea\x42\xbe\xa4\x4f\x7e\xfe\x86\xd1\x91"
-  "\x36\x29\xcb\x37\x15\x1b\xa0\x90\xcf\x3e\xd1\xab\x29\xfa\xfe\x65"
-  "\xe1\xe0\xf9\x27\xcd\x4f\xfa\x2e\xd6\x55\x59\xa7\xc3\xbb\x65\x1f"
-  "\x95\x6f\x60\x30\x09\xc7\x4c\x64\x18\x4e\x76\xb2\xbc\xe8\x4b\x7e"
-  "\xd1\x22\xe9\x51\xdd\x50\x89\x72\x83\xeb\x9f\xc3\xf8\x89\xe5\x84"
-  "\x6a\xf2\x9b\x6c\x13\x64\x8c\x23\xc3\xaf\xd7\x77\x19\x78\x0e\xaf"
-  "\xc0\x3d\xdb\x4e\x52\x6f\xd0\xe2\xe6\xfc\xfe\x6c\x17\xe4\x70\x61"
-  "\x8f\xa8\x4e\xcb\x01\x4c\xcf\xb0\x38\x44\xec\xb1\xb3\x4f\x56\x37"
-  "\x2d\xa7\x61\xf7\xc3\x5d\x53\xbb\xd4\x38\x5c\xbe\xb4\xd5\x4a\x7c"
-  "\x46\xf4\xc5\xe3\xb4\xfc\x01\xa3\x15\xb2\x76\x02\xfd\x0c\xf7\xd2"
-  "\xd6\xe5\x77\x51\xfd\x75\xf5\xa9\x26\x63\xa2\x30\x08\x21\x12\x84"
-  "\xfa\x23\xa3\x76\x93\x88\x9f\x41\x24\xc8\xdd\xa2\x44\x50\x6a\xd4"
-  "\x48\x23\x99\xc7\x24\x99\xae\xbd\x66\xa2\xf5\xae\x3b\x67\xcd\x74"
-  "\x54\x94\x83\xbb\x83\x01\xb3\x88\x8c\xf3\xb4\x75\xff\xd2\x1b\x2a"
-  "\x49\xfa\x0b\x54\x6f\x8d\x1b\xcf\x61\x87\x53\xc8\x98\xc3\xe1\x94"
-  "\xdd\x5e\xc7\xf3\x64\x78\xbf\xdf\x63\xe0\xd8\xc1\x3c\x47\x73\xcc"
-  "\x32\xe0\x7a\xec\x43\xa4\xa1\xfd\x76\xe1\xda\xed\x55\xfb\x81\x4f"
-  "\x4d\x0a\xd7\xec\xf6\x0e\xc1\x37\x12\xc3\x77\xbc\x41\x86\x3d\x15"
-  "\x3d\x06\xb7\xf1\x4e\x72\xdb\x7c\xf4\x21\xee\x87\xe9\xcf\x12\xd0"
-  "\x9f\x18\x46\xa3\x33\xbc\xcd\xf1\x15\x19\xb4\xf3\x75\x86\xd3\xf4"
-  "\xd4\x0f\xf7\x0f\x53\x8e\xcf\xb3\xf6\xa5\x4c\xb9\xc3\xef\x7c\x0a"
-  "\xfd\xff\x3d\x9f\x36\x27\x40\x76\x3d\x05\xfb\xaf\x50\x3d\xa7\x4c"
-  "\xb9\xbd\x4f\xc6\xb5\x7c\xaa\x59\xcf\x13\xb7\x8f\x5e\xe6\x35\x47"
-  "\xd1\xc2\xfd\x2a\xce\x7f\xd1\xc3\xbe\xfb\xc3\xec\xf3\x8f\x72\xdb"
-  "\x6f\xe6\x7d\x96\x11\x63\x02\x94\xe4\x38\x27\x06\x60\xb7\xa7\x82"
-  "\x6d\x0d\x21\xd8\x5e\xc1\xf3\x22\xa7\xbd\xf7\x2c\x71\xac\x3f\xde"
-  "\xaf\x7d\x6f\xf9\x1f\x0c\xee\xc0\x99\x16\xf7\xe6\x30\x75\x60\x7e"
-  "\x76\xd7\x9f\x69\x69\xef\x3d\x82\xfb\x10\xb5\xd3\xa7\xd4\x6e\xff"
-  "\x5f\x95\x72\xad\xa4\x5e\x54\x32\x9d\x07\xce\x8b\x25\x6e\xe3\xff"
-  "\x24\x8e\x57\xcf\xb2\x02\x74\xb7\x9d\xa6\xa2\x8d\xbf\x07\x9c\xf7"
-  "\xff\x03\xb0\x64\x6c\xa7\xd9\xf4\x21\xee\xfd\xce\xa2\xed\xba\x1c"
-  "\x89\x1b\x47\x23\xa1\x65\x87\xd9\xfe\x98\x21\x0c\x99\xc4\x31\xb8"
-  "\x20\x8b\x66\x70\xbb\xf0\x9c\xc9\xcf\xb8\x66\xf0\xd5\xbc\xb1\x65"
-  "\xb7\x39\xf8\x18\xcb\xa8\x1c\x96\x3f\x48\x5f\xd2\x78\x5e\xca\xac"
-  "\xc5\xda\xf3\x7c\xed\x79\xae\xf6\x9c\xad\x3d\x67\x69\xcf\xb3\xf8"
-  "\x59\xc9\xb6\x15\xb6\x41\xb9\x6b\x18\xd5\x89\xe7\x4c\xbd\x2f\x80"
-  "\xcf\xe5\x66\xfb\x06\x29\x23\x35\x3c\x66\x68\x78\x65\x6a\xcf\x3a"
-  "\x3e\x57\x9b\x83\x1b\xfe\xbb\xf0\xd9\x1f\x83\x4f\x4b\x04\x3e\x64"
-  "\xb6\x67\x7d\x13\x7c\x2c\x66\x8e\xd7\xfc\x77\xe0\xc3\xb8\x70\x9a"
-  "\xdf\xf9\x74\x56\x34\x3e\x4f\x2f\xd6\xf1\x89\xcb\x6f\x6b\x44\x0f"
-  "\xcf\x0f\xa5\x57\xca\x58\x95\xa3\x58\xf6\x37\xf6\xeb\xf1\xd4\x9e"
-  "\xde\x7e\xb1\x78\x6a\x18\x0b\x56\xe4\x41\xfb\x9f\x5e\xa6\xcd\x83"
-  "\x07\x95\xbe\xf4\x74\xab\xee\x1b\x83\xb6\xee\xad\x52\x6d\xdd\xb7"
-  "\x99\x63\x8a\xad\xa3\xab\x1c\x76\xd1\x03\xfd\xff\x3f\x5b\x6d\xde"
-  "\xa8\x31\x50\x5c\x56\x5a\xfa\xec\x1d\xb6\xe2\xfc\x95\x85\xb6\xc9"
-  "\x05\xb6\xd2\xa2\x15\xcb\xcb\x0a\xa3\xf7\x8b\x2d\x5a\xbc\x7c\xe9"
-  "\x07\xcf\x3a\x29\x8f\x01\xe6\x7f\xb6\xe3\x95\xef\xe2\x33\x5b\x84"
-  "\xf3\x69\x3e\x2b\x6b\x6a\xa8\x21\x23\xef\x51\xf8\x9d\xcf\x2c\xd1"
-  "\xe7\x04\x15\x1f\x9a\x12\x0c\x16\xd6\xb9\x9e\x81\xfd\xfb\x54\x6f"
-  "\x44\x3a\xe7\xad\xd4\xd3\x18\xbe\x26\x9b\x46\x1d\xa7\x67\x26\x71"
-  "\x9d\x71\x69\x78\x5e\x34\xc1\xd6\x4d\x80\x3d\xc2\xb6\xa1\xe0\xf8"
-  "\x41\x7c\xbe\x0c\xe5\x04\xf0\xf9\x84\x65\x2f\x7f\x03\x42\xe9\xbe"
-  "\x82\x71\xfc\x1c\x65\xf6\x20\xcd\xb8\x13\x79\xa1\x4f\x73\x2c\x20"
-  "\xce\x1b\xe2\x73\xfe\x48\x37\x69\x31\x91\x90\x56\x9c\xcc\xe7\xf0"
-  "\x91\x66\x89\x48\x9b\xcc\x71\x7a\x91\x66\x53\xf0\x8a\x6f\x65\x3a"
-  "\xe3\x39\x4b\xb3\xb9\x39\xcf\x3c\xad\xde\xca\x48\x9c\x39\x8a\xfa"
-  "\xcd\xd3\x32\x6d\x4b\x1e\xfa\xee\xec\x3b\x9f\x5c\xb5\x72\xf9\x68"
-  "\x92\x64\x4f\xcf\xb4\x4f\xce\xbc\xd9\x7e\xc3\x1d\xb6\x92\xc2\xc2"
-  "\xd5\xb6\xb5\x85\x2b\xcb\x6c\xf9\x6b\xf3\xd7\x8d\xa6\xe5\xab\x56"
-  "\x3f\xc9\xa7\xc8\xb9\x5b\x4a\x73\x9f\x5c\xfe\x14\x6f\xea\xab\xdc"
-  "\xa3\xa3\xe6\xe3\x25\x2c\xdb\xb4\xb8\x0b\x87\x21\x73\x03\x22\x79"
-  "\x5a\x1d\xee\x39\x16\x91\x15\xd7\x56\xfc\x0e\xe2\xd7\x8c\xdf\x11"
-  "\xfc\x3a\x4f\xd2\xea\x54\x5c\x0f\xf8\x9d\xc5\x3e\x5d\x2f\x18\xe2"
-  "\xa1\x67\x4d\x3a\x0f\x61\x1e\x3f\xa0\xe6\xb7\x67\x67\x76\x04\xe5"
-  "\xf8\x19\xe4\xa9\xaa\xf3\x43\x3c\x25\xe3\x1d\xb2\xcf\xca\x1a\xbc"
-  "\x07\x0f\xb3\x1d\x0b\x9a\x5f\xc6\x74\x3b\x41\x25\x53\x61\xfb\xb7"
-  "\x71\x2c\x10\x5c\x5b\xc1\x2f\x6d\x2a\xfe\xc6\xb3\x07\x90\x6f\x12"
-  "\xea\x38\xa8\xd5\xa1\x9e\xc7\x8b\xc3\x6c\xe7\x1f\xd7\x9e\x95\x4d"
-  "\xbc\xea\x63\xbe\xe7\xab\xb6\x57\x64\x66\xff\x3f\x65\x5b\xe9\xef"
-  "\x56\x3e\xa6\xd5\xd1\x02\x5a\x54\x36\x38\xc5\xe0\x3e\x07\xaf\x31"
-  "\x99\x13\xee\x12\xc0\xe7\x4c\x38\xf1\x51\x19\x3b\xd7\x5d\xd9\x0f"
-  "\x19\x71\xcb\x2d\x6e\xbb\xcc\x9f\xc0\x6b\x50\x0b\x4b\x44\x98\xe3"
-  "\xa2\x86\x13\x9f\xe9\xe2\x72\xc2\x32\xad\x2e\xbc\xf3\xf2\x2c\xa5"
-  "\x0b\x70\x7c\xb4\x95\x9a\x1f\xa8\x08\x30\x6d\x4f\x52\xf1\x17\xca"
-  "\x9e\x59\x9d\xaa\xf4\xac\x95\xd9\xba\x2f\x19\xc6\x68\x3a\x9e\x97"
-  "\xe8\x32\xc0\x43\x2b\x6d\x9a\xdf\x4f\x8b\x6a\xff\xca\xed\xda\x73"
-  "\xb3\x86\x63\x02\xc7\x7a\x00\xfe\x9d\xdc\x77\xb0\x0d\x9b\x71\x7f"
-  "\x04\xf4\x69\x53\xf4\x59\x29\xd7\x18\xa0\xd7\xf0\xfb\x23\x1c\x77"
-  "\x1e\xef\x8e\xa8\x38\x0a\xcf\xb6\x72\x9b\x87\x7c\x03\xeb\xb3\x40"
-  "\xbf\x8f\x79\x4f\x0d\x63\xa9\xd9\x7d\x9e\xc7\xe7\xb3\x2d\x80\xb7"
-  "\x5f\x97\x3b\x2c\x67\x72\x43\x18\xa7\x52\x2f\x5d\x19\xd4\xe5\xcd"
-  "\x10\x1f\xac\xb2\xc4\x93\x25\xf1\xfa\x5d\xeb\x9b\x75\xc2\x59\xbc"
-  "\x04\x38\xed\x97\x7d\xc0\x71\x23\xcf\x0f\xea\xbf\x03\x4a\x46\xae"
-  "\x1a\xd4\x7f\x75\x3c\x38\xde\xad\x87\x71\xeb\x97\xfb\x9c\x9a\xdc"
-  "\x58\xb5\x5d\x97\x1b\x3a\x1c\x73\x82\x08\x9b\xed\xf8\xe7\x4a\xf3"
-  "\xf1\x1a\x2b\xcf\x97\x52\x1f\x01\x9c\x31\xe7\xd4\x19\x9f\x70\x75"
-  "\x1a\xf8\x79\x55\x36\x64\x8c\x51\xea\xa8\xce\xe2\xa7\x86\x64\xd1"
-  "\x2a\x4f\x24\x4c\x61\x49\xf3\x31\x5c\x96\x47\xac\x93\xe4\x86\x8c"
-  "\x1c\x67\xc3\xa7\xcd\x2f\x90\xc1\x25\x16\x1d\x57\xd0\xf0\xb0\x8e"
-  "\xaf\xf6\x8d\x0f\xd8\xd8\xab\x4a\x16\x85\x06\xd8\xd7\xb5\x55\xf5"
-  "\xe7\x73\x52\xde\xe0\xdd\x3e\x94\x9d\xef\xa1\x67\x9a\xb4\x31\xd4"
-  "\x86\xf2\xfb\x0e\x55\x64\x23\x4f\x49\x91\xe6\xaf\xd9\x89\xfe\x3d"
-  "\x12\xc1\xfb\x8f\x45\xd8\xcb\x47\x54\x1f\xde\x59\x79\x9c\x4a\xf6"
-  "\x46\xa4\x6b\x7d\x7b\x68\xf1\x71\x7a\xee\x31\x65\x7b\xa6\x69\xe3"
-  "\xb3\x44\xfa\x6c\xea\x38\xb2\x2c\xe0\xf3\x48\x3c\xc6\x25\xed\x65"
-  "\x1f\x97\x78\xf4\xf9\x02\xb0\x0e\x48\x9a\x8f\x17\x07\x99\x4e\x2a"
-  "\x9e\x41\xf1\x56\x45\xa7\xe7\x4c\x51\xb4\xe7\x79\x13\xf5\x30\x9d"
-  "\xc6\x6c\x14\xe1\x31\xbe\x04\x91\xbb\xce\x28\x63\x37\xf3\x18\xe7"
-  "\xbd\x09\xf0\x87\xd4\xab\x14\xdd\x9e\x9b\xab\xd3\x4d\xef\x3b\xa6"
-  "\x93\x87\x4a\x9a\x99\xb6\xd1\x6d\x1c\xd5\x79\x5c\x6f\x3b\x68\xca"
-  "\xeb\xa5\x78\x5e\xa6\x8d\x8b\xb6\x96\x09\xbc\x57\xfe\x6c\xfe\x21"
-  "\xe3\x77\xe9\x90\x7d\x06\x29\xda\x3e\x07\xfb\xef\x19\x93\x6c\x87"
-  "\x82\x75\x98\xe9\xcb\x63\x05\x78\x7a\xb5\xd8\x42\x87\x95\xbf\xc6"
-  "\xb3\xcb\xa0\xef\x7b\xe5\x58\x5e\x23\x63\x40\x70\x7c\xd1\x4e\xa6"
-  "\x11\xcb\x45\x1e\x4b\x3c\x06\x78\x3c\x29\x1a\xad\x36\x46\xd0\xa8"
-  "\x95\xe9\xa3\xd1\xe9\x40\x8c\x2c\x2f\xb4\x15\xcf\x56\xb2\xd8\x96"
-  "\x3e\xb9\x60\xba\x0c\xe4\x61\xbb\x6f\xce\x1d\xb6\xc5\xb3\x27\xdb"
-  "\x8b\x32\x16\xaa\xcb\x9c\xc5\xf3\xf9\x3a\x3a\xda\x7e\xb2\xa1\x9e"
-  "\xe2\x68\x1b\x6c\x6d\xaf\x92\x1f\xab\x37\x7b\x12\x12\xa4\x6d\x0e"
-  "\x5b\xb9\xb7\xea\x2c\x51\x88\x69\xb8\x12\x7d\xea\x4a\x73\x2d\x82"
-  "\x0c\x5e\xb4\x4e\x7c\xd5\x88\x74\x8e\x51\xcb\xbc\x08\x9e\x77\xb1"
-  "\xcd\xeb\x4d\xde\xba\x1f\xbf\x12\x6f\xf2\x94\xf9\xf7\xde\xe0\x10"
-  "\x80\xd5\xa9\xb7\x85\xed\x62\xc1\xe5\xed\x22\xc4\x74\xc9\xb5\xa3"
-  "\xbf\x51\x8e\x6d\x64\xe4\x0b\x60\x0e\xc8\x52\xb6\x61\x29\xda\x5f"
-  "\xbc\x47\x93\x5f\x8b\xf1\x9c\xea\xa1\x4c\xc9\xc7\x61\xa7\x95\xd7"
-  "\xe7\x8c\xe1\x4d\x53\x1e\x84\x0d\x50\xa2\xc3\x04\xac\x91\x5a\xec"
-  "\x39\x09\xef\x9b\xfa\x0a\x86\x6b\x26\x6f\x33\x27\xa8\x38\x77\x18"
-  "\xd7\x95\x8d\x86\x70\xce\xa0\x2f\x00\xde\x8d\xd9\x68\x61\x5f\x81"
-  "\x1c\xf0\x5b\x25\xe7\xd1\xdf\x55\x39\xc3\x9e\x2a\x43\x38\x80\xbe"
-  "\xb3\x28\x9d\xb9\x97\x65\x26\xec\xcf\xd2\x16\x7d\x2e\x93\x73\xa0"
-  "\x81\x2a\x95\x0d\x53\x2a\xf7\xf8\xce\x3a\x8d\x04\x39\xbd\xec\xba"
-  "\x54\x69\x97\x04\xc2\xce\x04\x52\xfe\x99\xa5\xbf\xd1\xe5\x2a\xef"
-  "\xb1\x98\x37\x0a\x2f\xaf\xaf\x99\x83\xc2\xcb\xfb\x2d\x72\xbe\xa0"
-  "\x93\xe4\x2e\xf7\x57\x72\x1c\x52\xa9\xf7\xa0\x5e\x35\x57\x84\xd4"
-  "\x5c\x81\xfa\x61\xcb\xe7\x61\x4e\x48\x38\x49\xa5\x9b\x19\x7f\xa6"
-  "\x0d\xaf\xe1\x86\x41\x2b\x37\xcf\x8d\x4c\x9f\x94\xef\x98\x78\x9f"
-  "\x9f\xdb\x6a\x0e\xa2\xcd\x91\xed\x32\x84\x3d\x3b\x9d\x68\x97\x01"
-  "\xed\xb2\x9f\xe2\x71\x12\x60\xff\x0b\x8c\xb1\xf1\x32\xd6\xae\xb4"
-  "\xb1\xcb\xf6\x44\xb6\x91\x65\xbe\x6a\x43\xd9\xc7\xf1\xda\x28\x0c"
-  "\xdc\x46\xa6\x41\xd9\x1b\xda\x18\x93\x78\xb2\xcc\xe8\xa5\xb2\x9c"
-  "\x31\x1b\xd9\xef\x21\xcd\x05\x3e\x9a\xc3\x7d\x88\x39\xd3\xc5\x78"
-  "\xc6\xeb\x2f\x86\xa7\x60\x3d\x5f\x60\xde\x58\x99\xe7\x77\x3e\x9f"
-  "\x19\x9f\xde\xcf\x3f\x70\x71\x7a\x3f\x3f\x99\xcb\x33\x1e\xec\x07"
-  "\x62\x0e\xc2\x40\x07\xdf\xc2\x46\xdb\x16\xaf\xde\x31\x1b\x9b\x18"
-  "\xaf\xb8\xef\x20\x77\x7a\xab\x34\xb9\x03\x3e\x14\x8b\xf0\x63\x39"
-  "\x04\xdc\xda\x74\x19\x64\x4e\xb0\x25\x4a\x99\x60\x10\x71\xdb\x65"
-  "\xde\xe8\x62\xbf\x8b\x39\xa8\x3f\xee\x7b\xd0\xd8\x06\x1a\x55\x86"
-  "\x37\xdd\x78\x9d\x39\x81\xee\xf2\x26\xde\x38\xda\x6c\x0f\xa6\x31"
-  "\x0d\x01\xd3\x8e\xb1\xfb\xef\x6c\x9b\xaa\xd8\x58\x6b\x30\xff\x6f"
-  "\x95\xeb\x79\xde\xe4\xb4\x4a\x15\x3f\x6b\x4d\x8e\x87\xb6\x1f\xd5"
-  "\xd7\x35\xf1\x5c\xe4\xa1\x4f\xb5\xf5\xaa\xab\xde\x14\x35\x53\xac"
-  "\x61\xa7\x59\xd8\xd6\x9b\xa1\x3b\xae\xe5\x38\xe4\x06\x91\x32\xc5"
-  "\x3a\xc4\x27\xca\x27\x44\xe7\x13\x94\xdf\x1b\x9f\x07\xd6\xfc\xf1"
-  "\xe2\x3c\xb0\x46\xee\x17\x33\xdd\x95\x7d\xb2\xc6\xab\xeb\x26\x62"
-  "\xd3\x55\x6f\xda\x2a\xb8\xfe\x35\x9b\x55\xdd\x4c\x93\x2c\x5e\xab"
-  "\x9f\x0f\xba\x54\xfa\x9d\x6b\x27\xea\x72\x80\xf9\xc5\x1c\xa2\x04"
-  "\x96\x45\xcc\x2b\x78\x37\x13\x72\xa6\x4e\xad\x21\x4e\xe9\x94\xdf"
-  "\x88\x72\xae\xb6\x79\x1d\x45\xbb\xd8\x87\xd3\x97\x9c\x16\x40\x9e"
-  "\x65\x1e\xfa\x6d\x9a\xcc\x63\x49\xf3\x02\x86\xaf\x36\x05\xf3\xb2"
-  "\xf2\x65\x4a\xe2\x31\xcd\x71\x6f\x78\x5c\x23\x2d\x15\x78\x73\x0c"
-  "\x1c\xd8\x38\x6b\x6b\x07\xe7\x22\x67\x16\x64\x85\x90\xf3\x21\xe6"
-  "\xa2\x89\x7d\xa0\xdd\x8f\x0c\xe1\xbd\xe7\xa7\x5b\x89\xdb\x7c\x7e"
-  "\xd3\x84\xbd\x2f\x4e\x23\xe3\xff\xb0\x3e\x41\x25\x37\x53\xea\xc6"
-  "\xef\x1a\xe9\x7f\xcf\x24\x03\xd3\xc1\x43\x6b\xf7\x28\xda\xad\xed"
-  "\xd6\xfb\xc7\x43\x6b\xe6\x73\x7f\xf0\xfa\xdb\xa2\xa0\xf8\x4a\xad"
-  "\x11\xda\x21\xff\x0a\x5a\xd4\xfb\xd5\xf6\xd8\x75\x1f\xd6\xe1\x6d"
-  "\x2b\x4a\x6d\x05\xab\xd6\xae\x9c\x34\x29\xca\x3e\x32\xca\x73\x1d"
-  "\x4e\xbb\x55\xcd\xa1\xf6\xf9\x3a\xde\xac\x8b\xe0\x19\xed\x5f\x7d"
-  "\x41\x9c\xef\xf9\xb9\x9a\xeb\x6e\x6e\x26\x0d\xdd\xdf\x44\xf3\x6f"
-  "\x8a\x78\xbc\x85\xe6\xdf\x7c\x4b\xee\x83\x85\xf9\x05\xeb\x22\x52"
-  "\x6f\x8d\x5c\x93\xab\x7a\x13\x75\x27\x4e\xb8\x07\xb2\x22\x61\xe1"
-  "\x0b\x3c\x9f\xac\xbb\xbb\x22\x28\xfe\x06\x79\x3d\x13\x63\x2c\xb7"
-  "\xbd\x2c\x48\xed\x90\x65\xe2\x2a\x96\xe1\xa3\xd4\x79\x35\xe8\x50"
-  "\xe0\x2d\x33\xda\xee\x85\x2e\x77\x8e\xd7\x64\x50\xae\xb0\xa3\x8e"
-  "\x63\xcf\x4e\x59\xa2\xf4\x8a\x75\x36\xa4\x27\xe3\x3a\x0f\xd7\x91"
-  "\xb8\x2e\xb0\xad\x84\xad\xc3\xfe\xc1\x6b\xd8\x3f\x78\x1d\xe3\x91"
-  "\x30\xcd\x57\x49\xd3\x56\xb3\x9e\x6e\xef\x62\xbd\xc3\x43\xeb\xb6"
-  "\xf1\xfe\x00\xe7\x45\x99\x49\xb6\xa7\x29\x93\xaf\x42\xee\xab\xac"
-  "\xb3\x89\xea\x29\x4b\xc4\xae\x1c\xfe\x76\x4b\x1a\xd2\xb7\x24\x26"
-  "\x1c\xa3\x44\xeb\xa8\xef\xfb\x9d\xeb\x36\x83\x27\xe5\xd8\x18\xee"
-  "\x7b\x6f\xac\x6b\xf0\x98\x1f\xd2\x45\xa0\x0b\x42\x17\xc9\xb5\xbf"
-  "\x4c\xb8\x37\x0e\xe9\x21\xeb\x3a\x07\x75\x5a\x03\x8d\xc6\xb3\x47"
-  "\xe7\x77\xdc\xf7\xea\xfc\x18\x15\x1b\x6c\x65\x59\xe1\xea\xc2\x02"
-  "\xdb\xe4\xd2\xd1\x14\x11\x19\xac\xa8\x70\xa5\x6d\x75\xe1\x73\xcf"
-  "\x17\x96\xca\xa8\x5e\xfc\x36\x6a\x3e\x4f\x15\x29\xe9\xdb\xf4\x33"
-  "\x2b\xb6\x09\x4c\xc7\xf5\x0f\x70\x3c\x29\x51\x73\x03\xeb\x1b\xbd"
-  "\xca\x96\x68\x30\x45\xdb\x12\x2f\x74\x2b\x1d\x6e\x4a\xb6\xb2\x63"
-  "\x5e\x58\xc7\xcf\xc7\x69\x7d\x70\x28\x06\xf5\xfa\x77\xf9\x3b\x08"
-  "\x1a\x7d\xba\xfc\xce\xf5\x7b\x74\xfa\x78\xa8\x5c\x3f\x47\xd0\x2b"
-  "\xe5\x04\xe6\x52\xc8\xb9\xa8\x79\x54\x7d\xcf\x6d\xfd\x3e\xde\x63"
-  "\x95\x6b\xb2\xc9\x53\xe6\x72\x5d\x0c\xf3\x04\xca\xa3\x1f\xb2\x21"
-  "\x1f\x59\x8e\x6d\xd3\xe1\xa1\xce\x5a\xae\x4f\xb3\x71\xae\x38\x49"
-  "\x2f\xc8\x3d\xeb\xb0\x6b\xca\x5c\x96\x1d\xd3\xa4\xce\x01\x38\x72"
-  "\x1f\xab\x3c\x83\xf5\x47\x19\x07\x1d\xb0\x78\x0d\x16\x32\x20\x87"
-  "\xbf\xfd\xc7\x69\x2a\xae\xd5\x3a\xe9\x27\x88\xba\xb2\xfc\xce\x17"
-  "\x0a\x86\xfc\xb2\xcb\x33\x58\xa7\x64\xb8\x1e\x7a\x21\x9d\xe1\xa9"
-  "\xb8\x5d\x2f\x00\x17\xfb\xde\x21\xdd\xe8\x85\xb6\x08\x9b\x0b\xf8"
-  "\x28\x3c\x7d\xc0\x45\xc6\x88\x54\x7e\x73\xb2\xdd\x2c\x27\x6b\xb5"
-  "\xb6\xeb\xed\x01\xbc\x2e\xf0\x5c\xad\xbe\xef\xea\xd1\xda\xcd\xf8"
-  "\x31\xee\x91\x38\x2b\x7c\xd7\xb3\x5c\xc2\x18\x2e\xb7\x44\x8c\x61"
-  "\x5e\x73\x19\x81\xb4\xb4\x21\x7f\xdc\xf5\xc5\xb1\xf2\xe1\x9e\xfc"
-  "\x27\x9f\x61\x23\x7d\x7e\x66\x86\x8d\x65\x45\xee\x83\xf7\xce\x79"
-  "\x38\x77\xce\xa2\xa5\x0b\x97\x48\xff\xfb\xc1\xf7\xd9\x2b\xe3\x67"
-  "\x88\xe6\x2b\x0b\x78\x83\xf7\x96\x46\x1c\xa7\x0a\x8f\x8a\xcf\x5c"
-  "\xbe\x37\x3a\x3e\x73\x79\x0b\x7e\x47\xf1\x83\x66\xb2\xc1\x83\x1f"
-  "\xf4\xc8\x8a\x23\x1a\xbf\xf4\x02\xdf\x23\x43\xfc\x52\x21\xd7\xbc"
-  "\xd9\x2f\x41\xad\xa5\x96\x43\xfe\xaf\x4f\x8b\x7c\x37\x64\xfb\x6d"
-  "\x48\x1a\xb4\xfd\x06\x65\xc1\x86\x99\xba\x1d\x88\xb4\xf9\xb0\x01"
-  "\x2f\x63\x1b\x50\xad\xfd\x54\x48\x1d\x2b\xd6\x56\x1b\xb2\xd3\x4c"
-  "\xa4\xdb\x80\x1c\x1b\x92\xf7\x3d\xd5\x18\xdd\x50\x16\x61\x63\xf9"
-  "\x64\xbc\xc0\xf3\xca\x26\xe4\x72\x72\xad\xcd\xb2\xdb\xc7\xeb\xcf"
-  "\xd0\x6b\xb3\x30\xc7\x63\xde\xf1\x0b\x91\xbc\xdb\xa7\xe1\x74\x80"
-  "\xd7\xa3\x59\xdf\x55\xf6\x5e\xf9\x4c\x96\xbf\x62\xd3\x84\x7b\x16"
-  "\x85\x64\x2c\x35\xc8\xde\x0d\x5d\x43\x3c\x57\xe1\xe1\xbe\x64\x1a"
-  "\x80\x0f\xba\x41\x07\xe3\x50\x9b\x2b\x68\xb0\xcd\xda\x3a\x86\xbe"
-  "\x86\xa1\xea\xaa\x38\x36\x5c\xfb\xe2\xb7\xad\x62\xf1\xd7\xb6\x8d"
-  "\xbf\x99\x83\x71\xa1\xb7\xf1\xc2\xf6\x55\xd4\xc6\xb4\x2f\xe7\xc2"
-  "\xf6\x55\x34\x0f\xee\xbb\x0c\xae\x4b\x54\x1c\xe3\x76\x32\x1f\xa0"
-  "\x9d\x87\x13\xad\xa6\x6f\x47\xdc\x67\xc4\x93\xab\x63\x36\x1a\xb4"
-  "\x33\x20\x8e\x5b\x5b\x27\x4a\x3b\x2d\xf0\xaa\x21\x5c\xf4\xaa\x13"
-  "\x3f\x5c\x59\xcf\x1e\xd2\x55\x45\x40\xe1\xe7\x98\xd1\x0a\xd9\xcb"
-  "\x6b\x2d\xc3\x9d\x6d\x03\xcd\x8e\xea\xeb\x00\xb8\xef\x62\x7b\x72"
-  "\x51\xe8\x2e\xc1\xe9\x4c\x03\xd8\x24\x5e\xf0\x55\x97\xd2\xdb\x1c"
-  "\x9b\x07\x65\xf6\xb4\x5b\xf3\x12\x37\x92\xed\x50\xfd\xcd\x9c\x5e"
-  "\x8f\xbe\x93\x6b\x83\xf2\x1b\x79\xc3\xc0\xcc\x0d\x65\xd1\x30\x70"
-  "\x8f\xea\x70\x87\x3b\x07\x19\x99\xb6\x6a\xa5\xad\x28\x7f\x65\xc1"
-  "\xaa\xe5\xcb\x33\x6c\xcf\xaf\x7c\xa2\x78\xd5\x93\xcf\xb0\xe0\x2f"
-  "\x2d\x7b\x1e\xe3\x57\x8e\xdb\xec\xf9\xf3\x73\xef\x59\xfa\xd0\x0f"
-  "\xa3\x74\x00\x93\xcb\x19\xde\x26\xbf\x91\xb5\xe9\xe9\xf5\x7e\x67"
-  "\x25\xfa\xff\x29\xbb\x9a\x6f\x2a\x31\xff\x3f\x99\xa4\x74\xad\x47"
-  "\x7b\xd4\xd9\xcf\xca\xe6\x08\xb9\x36\x06\xcf\xad\xfc\xad\x83\xa1"
-  "\x35\x90\x4a\x57\xa4\x0e\xd1\x27\xbf\x53\x57\xb9\x47\x8f\x83\x50"
-  "\x36\x89\x0c\xc6\x49\x2e\xaa\x35\x88\x4a\x0f\x55\x1e\x86\xbd\x78"
-  "\x14\xef\x5b\x3d\x54\x54\xa7\xd9\x8f\x47\x79\x8f\x95\xed\xc7\x10"
-  "\x6c\xc9\x45\xeb\x5a\xee\xca\x5d\x97\xc0\x3e\xc4\xf2\xbb\x09\xc1"
-  "\xf3\xa2\x9b\xf7\x39\x79\xcf\x88\xbf\x9b\x50\xf5\xb4\xb4\x27\x13"
-  "\x65\x1e\xdc\x57\x9d\x20\x69\x5b\xe1\xbd\xad\xf1\x84\xfc\x76\x23"
-  "\xec\x8f\x8d\x69\xba\xee\x69\xde\x68\x93\x67\x52\x77\xaa\xfe\xe8"
-  "\xe2\xbe\xe0\xfa\x72\xd7\xb5\xa8\x3a\xd0\x07\x28\x6b\x56\xeb\x3e"
-  "\x1b\x97\x5d\x74\x3d\x3b\x79\x6b\xdd\xb0\x31\xc8\x9d\x95\xa3\x5e"
-  "\x55\xf1\x8a\xd9\x0f\xce\xab\xfb\x61\xb1\x4f\x16\xe0\x1e\x88\xf5"
-  "\xe9\x52\x7e\x09\x1b\xdb\x74\x7f\x10\xdc\x77\x0d\xea\xcb\xfc\xad"
-  "\x0d\xd8\x39\xb6\x8a\x8d\x23\x4f\xd3\xc6\x37\x1a\x87\x59\x57\xd6"
-  "\xcf\xa0\x6a\x7e\x53\xa3\xfc\x4e\xe7\xc4\x41\x5f\x12\x3c\xf3\x18"
-  "\x1f\xf2\x07\x73\xce\xd4\xfd\x89\xa4\x0f\x19\xe6\x2c\xfe\x9e\xc7"
-  "\x09\x72\xfe\x50\x7e\x3f\xe4\x3a\x5e\x13\x76\xda\x5b\xa5\x2f\x9b"
-  "\xb3\x20\x12\x17\x85\x87\x73\x32\xaf\x5b\xf2\xfb\x48\x5c\xec\xf9"
-  "\xcf\xaf\x98\x6e\x5f\xbe\xc2\xf6\x64\xd1\x8a\x92\xdc\x15\x32\x6e"
-  "\xa8\x0c\x49\x5a\xb6\xae\x84\x57\xe9\x6f\x18\x1d\x33\x57\x68\x7e"
-  "\x67\x83\xfe\x35\xd2\xf7\xcc\xf9\x19\xe8\x61\x50\xbe\x67\x9b\x3a"
-  "\xd5\x7c\xe8\xec\xb9\xd0\xcf\xc2\x19\xd4\xfd\x2c\xc0\x57\x96\x5a"
-  "\x15\xaf\x5c\xf3\xcd\x60\xbe\xdb\x34\xf1\xc2\x32\x9b\x32\x07\xfd"
-  "\x8c\xd8\xdf\x65\x20\x47\x9e\x11\x90\xb1\xa5\x6b\xb8\xdf\x9c\x9b"
-  "\xdd\xf6\x7b\x79\x8f\x58\xe3\xe7\x4d\x79\x3a\x3f\xeb\x3e\x6a\x0c"
-  "\x8b\xcf\x28\x4c\x0f\x44\xfa\xa7\x6c\xfa\x18\x73\x8b\x75\xb0\x1d"
-  "\x2f\x18\x88\x71\xf7\x19\x5a\x18\x8f\x3d\xb1\x78\x00\xbf\x49\x48"
-  "\x8f\xf0\xff\xd1\xdb\xb9\x09\xfa\xdf\xe6\x0b\x74\xbc\xbb\xef\x9d"
-  "\x0f\x65\xae\xb4\xb0\x6c\x34\xcd\xc9\x2f\x2e\xe6\x71\x9d\x5f\x58"
-  "\xfc\xfc\xea\x55\xa5\xb9\x2b\x56\xae\x40\xea\xdd\xcb\x39\x9c\xab"
-  "\xcc\x72\x87\xf6\xc6\xb6\xb2\xb0\xb0\x40\x25\x69\xdd\x10\xbd\x37"
-  "\xa2\xf6\xbf\x37\x67\x79\x68\x63\x60\x48\x6f\xd9\x5c\x27\x0c\x9b"
-  "\x8e\xe2\xf7\x37\x39\xa6\xa5\x4e\xb1\xb9\x20\xda\x2e\xd8\x5c\xa6"
-  "\xf3\x83\xec\x3f\x07\xfb\x88\x5c\xff\x65\x9f\x90\x7b\x09\xe8\xb3"
-  "\x2d\x7f\xe4\xef\x9e\x7a\x68\xcb\x61\xd6\x87\x23\xe0\xec\x1b\xa4"
-  "\xe5\xa6\x47\xbb\x98\x17\x19\x1e\x7f\xef\x8d\xcf\x66\xe3\x3d\xf8"
-  "\x7f\x63\xa5\xe2\xff\xcd\x83\xfc\xdf\x67\x48\x84\x8d\xb3\xb9\x47"
-  "\xd7\x83\xa3\xc7\xcc\x16\xba\x70\x2c\xb1\xcf\xe0\x16\xab\x4e\x5b"
-  "\xbd\x9f\x15\x6f\x6d\xf9\x8d\xbe\x36\xd9\xa8\xc5\x16\xe7\x7b\x2e"
-  "\xcb\x3a\xae\x18\x73\xf9\x5d\xec\x03\x7d\x9c\xb6\x6c\x56\xfc\xb2"
-  "\x25\x2f\xc2\x97\xc7\x72\x92\xb6\x68\xf6\xec\x16\xbb\x8e\x1f\xda"
-  "\x39\x83\xd3\x18\x86\x1a\xfb\x9b\x42\x8a\x77\xb6\xd4\xeb\xb4\x65"
-  "\xbb\x11\xcf\xfb\x86\xe6\xf4\xcd\xf3\x79\xae\xd3\xce\xa6\x0f\x70"
-  "\xfb\x01\x27\x43\x87\x83\xbc\x78\x36\xb5\xea\xb4\xd2\xf3\x44\xf2"
-  "\xc4\x9c\xfc\x12\x18\x75\x2b\x96\x2f\x2f\x5c\x5d\xaa\xc7\xeb\x4d"
-  "\x5f\x55\x5c\xa0\xe2\xf3\xde\x81\xee\x5f\x8b\x11\x38\x9b\x43\xfc"
-  "\x22\x55\xdd\xc6\xd8\x00\x19\x6c\x87\x4b\x7f\x2f\xa9\xff\xbf\x7c"
-  "\x6b\x83\x66\x0b\x1c\xa7\x17\x67\xe0\x0a\x79\xb0\xf5\x9c\xd2\xcb"
-  "\x2e\x3b\xe3\x77\x6e\x2d\xd6\xf5\xb2\xbe\x91\x33\x61\x5f\x6f\x2d"
-  "\xd7\xbf\xc3\xa4\xeb\x0a\x7c\x16\xa5\x65\x25\xc7\x3e\x7f\xf9\x8d"
-  "\x70\x75\x5a\x89\x48\x19\xdb\x04\x9d\x24\x89\xf9\xfe\xf2\x5e\x8e"
-  "\x8b\xce\xf1\x62\xb6\x1e\x66\x5d\x86\x65\x09\xc7\x38\xef\xa6\xad"
-  "\x75\xfc\xed\x66\x0f\xbd\x5c\xef\x4d\x4e\x2b\xd9\xbc\x9e\x4c\xbb"
-  "\x5f\x93\xdf\xbf\xf5\xb4\x36\x31\x1d\xb7\x76\x7f\x54\xae\xbe\xa7"
-  "\xcd\xdf\x21\xde\x81\x77\xb0\x87\xf7\x6b\x6b\xc9\x9b\xb5\x75\xbc"
-  "\xcd\x7e\xe7\x8b\xd0\xff\x92\x9a\x15\x5f\x8e\xbb\xe2\x3b\x95\x64"
-  "\xe7\xef\xb3\xa9\x58\x2f\x53\xbb\x84\x6b\x9c\x15\x7a\x8c\x17\xfa"
-  "\x0f\xf4\xec\xad\xc5\xa2\x7a\x9c\x55\xc5\x89\x66\xbe\xd8\xba\x8c"
-  "\xdb\x09\x78\xdb\x79\x7d\x87\xd7\x76\x34\xb8\xec\xdb\x96\x00\x3d"
-  "\x6e\x16\xeb\x72\x78\x2e\x0a\x9f\x3f\xd5\x84\xb9\xdb\x84\xb9\xca"
-  "\xab\x7d\xf7\xa7\x98\xd7\x3c\xc7\x6c\xf4\x60\x2e\xba\x56\xe4\x06"
-  "\x2d\xbc\xd7\x70\xb9\xfe\x5d\x25\x5e\xf7\x04\x6e\x7b\x87\xf6\x10"
-  "\x4e\x49\x9a\x80\x1f\x2b\xbb\xe9\x45\xe9\xeb\xcf\xbc\xc8\xb4\xeb"
-  "\x07\xbd\xf8\xfb\xbb\xe2\xfc\xa9\xfd\xb0\x43\x2f\x3f\x41\x2f\x7e"
-  "\xce\x74\xe3\x7d\x3f\xf6\xd7\x41\x9a\x99\xe3\x47\xa3\x7f\x3e\x61"
-  "\x9a\x31\x2e\xc2\x95\x6a\x0f\xfa\x73\xbe\xcf\x67\x08\x59\x1e\x6d"
-  "\x28\x87\xee\xb7\x9c\xc7\xf2\x4b\x4b\xd9\x9e\xe3\x6f\x7e\xf0\xbd"
-  "\xa3\x40\x84\x25\xcd\xd7\x33\xcd\x5f\x5a\xba\xa1\x47\x84\xbf\x72"
-  "\x92\x38\xec\x23\xfa\xca\x40\xc1\x80\x21\x81\xf1\x36\x38\x4e\xf1"
-  "\x39\xc7\x26\x72\xdb\xb7\x11\xea\x35\xed\x5c\x4f\x16\x3e\x17\xca"
-  "\xdf\xb3\xe8\xf0\xd5\x53\x47\x49\x3d\xfd\x5b\xb0\x96\x5a\xd6\xf0"
-  "\x39\xff\x97\x82\x7f\xb2\xd7\xf2\x5e\xca\x65\xb8\xff\xc0\xf6\x30"
-  "\xd7\xb5\xad\xf6\x4f\x47\xfe\x4c\x7f\x6a\xf9\x33\xd9\x1e\x91\xcf"
-  "\x7b\xda\x72\xfe\x8d\xda\xb2\xfe\x8d\x1c\xdd\x22\xcc\x36\x41\xc5"
-  "\xb3\x5c\xc7\x36\xc0\x6a\xe2\xf3\x94\x96\x70\x9f\x75\x34\xda\x6f"
-  "\x5c\x64\x27\xea\xf0\x79\xc1\x43\xbf\x63\x1c\x27\x37\x9c\x25\x53"
-  "\xcb\xca\x3f\xc8\x7b\xa5\xab\x9f\x6a\x72\x17\x74\xb1\x9e\x14\xe4"
-  "\xf3\xa3\xbc\xf7\x04\x5d\x37\x5c\xc5\x38\x86\x14\xde\xfc\x1d\x69"
-  "\xbd\x3c\xf4\x28\xad\xfc\x36\xb9\xc6\xbb\x9b\xe9\x01\x9c\xda\x97"
-  "\x28\x9a\xb4\x75\x81\xa6\x0f\x6b\xf4\xc9\x89\xa4\xcf\xb6\x6c\xa6"
-  "\x0f\xc7\x1e\x0c\xa3\xbf\x80\x5b\x16\x68\x10\xd6\xeb\x00\xce\x26"
-  "\x6d\xdd\xce\xb4\xf3\x2c\x25\xb5\xac\xe4\x6f\x13\xbd\xf4\x8e\x79"
-  "\xb1\xd1\x14\x3e\x7f\x7a\x7f\xd5\x39\x32\x72\xbf\xf1\xfa\x7c\x95"
-  "\x7c\x2f\x69\xbe\x9d\xfb\x2c\xf2\x7b\xe6\xcc\x87\xfc\x4d\x73\xf4"
-  "\xd7\x36\xe0\x90\x86\xbe\x6a\xe2\xab\xe2\xed\x71\x56\x3e\x5f\xaf"
-  "\xe9\xf2\x43\xe9\xe0\xed\x20\x7f\x77\x50\xae\x4b\xbc\x94\x16\x06"
-  "\x6f\xb3\x3d\xdf\x50\x43\x49\x61\xe7\x16\xef\x6e\xc8\x9a\x7a\xcc"
-  "\x65\x0d\x29\x64\xe1\xb5\xac\x37\xa5\xff\xf0\xcb\xe9\xba\xec\x79"
-  "\x79\x3c\x9f\x49\x7a\x69\x89\x41\x7e\x5f\x2e\x6d\x9b\xc6\xe7\xd0"
-  "\x01\x5f\x9e\xef\xa1\x71\x7b\x94\xfc\x7d\x39\x47\x1f\x4b\xd0\x93"
-  "\xbc\x3a\xff\x63\x7c\x16\x79\x99\xdf\xa5\x1f\x82\x07\x36\xac\x59"
-  "\xb0\x6f\xe7\xd0\x37\xd5\x5e\x76\xe9\x7c\x8e\xb6\x95\xb0\x9c\xe0"
-  "\x31\x3d\x9c\x9e\x0d\x1d\xaf\x4d\xec\xca\xa1\x9d\x27\x89\x92\x36"
-  "\x0a\x6f\x52\xb7\x59\x74\xf8\xda\xe4\x79\x36\xfe\x7e\x62\x03\xd2"
-  "\xf1\x3e\x61\xa1\xcf\x6b\x86\x4e\xd8\xc9\xf4\xd7\xd3\x79\x7f\x81"
-  "\xd7\x63\x16\xfa\x84\x77\xd1\x3a\x33\x7f\xdf\x6d\xa2\x5c\x73\xd6"
-  "\xd2\x3b\xac\xbc\xef\xe0\x35\x83\x7e\xc1\x41\x58\x7d\x39\x89\x8c"
-  "\x27\xf2\xa6\x0e\xe6\xed\xcb\x31\xba\xed\xaa\xce\x88\xb4\x11\x8b"
-  "\xec\x28\xcb\xfd\xad\xa5\x29\x5d\xf2\x95\x92\x41\xfb\x88\xe3\xf4"
-  "\xf5\x61\xee\x2b\xcd\x49\x08\xf7\xe5\x18\x42\x80\x8d\xf1\x63\x91"
-  "\xdf\x99\x0b\x7a\xb5\x6f\xbd\xf4\x40\x06\x74\x91\xa8\x6e\xb0\x20"
-  "\x9f\x91\xe1\xf2\x99\x68\x8e\x93\x2f\x92\x9b\xe2\xea\x8f\xc2\xf5"
-  "\xca\xe1\x96\x8a\x47\xc0\x93\xdb\xed\x2c\x13\x42\x16\x28\x50\x4f"
-  "\xb3\x8e\xf1\xca\x97\xdc\xff\x21\x8c\xd3\x50\xf2\x64\xfb\xf4\x1e"
-  "\x4a\xe0\xef\xfd\xa9\x35\x8d\xed\xc9\x7c\x06\xdc\x11\x16\xd0\xdb"
-  "\xb6\x4b\xde\x33\xf7\xb2\x5f\xd5\xe4\x72\xe9\xcb\x94\xf2\x62\x8b"
-  "\x3b\xd0\x43\x6d\x95\x9f\x52\x5b\xd0\x5d\x79\xf0\xac\xd7\xa8\x7c"
-  "\x9a\x8c\x80\xbb\x7d\x32\xbf\x73\x80\xdf\x73\x43\x4d\x34\xdc\x9a"
-  "\x32\xdb\x7a\x98\x87\xfe\xaa\x6c\xa8\xed\x76\xdd\xc6\xfb\x9a\x36"
-  "\x74\xf2\x39\x72\x21\xac\x14\xae\x29\x6c\x01\x2e\x0e\xe1\x4f\xa7"
-  "\xe9\xeb\x79\x8d\x67\xfb\x5e\xe8\xee\x59\x1a\xdc\x33\x1a\xdc\xce"
-  "\x8b\xc1\x65\x9e\x69\xab\x93\xfb\x19\x68\x53\xe1\xfe\x10\x60\x87"
-  "\x52\x0a\xf9\x5b\x0b\x0e\xc7\x57\xbc\xd6\xb7\xf3\x6a\xd4\xb3\xbf"
-  "\x23\xd8\x49\x1c\x93\xa2\x21\x8c\x39\xee\x8c\x95\x34\xff\x2d\xc7"
-  "\x69\xda\xc1\x6b\xd5\x16\xd8\xa2\xbc\x8e\xef\x60\x39\xc9\x76\x6d"
-  "\x45\x88\x46\xba\xa1\xd5\xf0\x79\x6a\xc0\x48\xfe\x98\xf7\x4c\x20"
-  "\x6b\x42\xc2\x6a\xf8\xe0\xbc\x87\xd8\x47\x43\x9e\xaf\xde\x74\xd5"
-  "\x9b\x63\x36\xd2\x5d\xc2\x60\x96\xfe\x79\xe1\xea\x2d\x87\xd1\xb7"
-  "\x56\xe5\x2f\x96\x56\x1b\xe1\x2b\x96\x88\xba\xb6\xb0\xaf\x98\xb0"
-  "\xa4\x2d\xab\xe7\x3d\x8c\xe4\x17\x9b\xbc\xc9\x5b\x5d\x02\x7d\xe7"
-  "\x77\xee\x68\xf6\xd0\x2b\x72\xcd\x76\x3b\xfb\x57\x4b\x79\xbd\x73"
-  "\xb2\x37\x39\xbf\x4e\xa8\xb3\x57\x09\xe1\x35\xa1\xfd\x55\x5f\x92"
-  "\x51\xd1\x65\xe7\x88\x8e\x5e\x7f\x8b\x70\xe5\xd7\xf1\xd9\x19\xad"
-  "\x0e\x33\xea\xf8\x8b\xa8\xce\xaf\xf3\xd0\x4e\x4d\x66\xf0\xfd\x0e"
-  "\xb9\x9f\x18\x1c\x48\x87\x6e\xb4\xa3\xa0\xbe\x9f\xd7\x92\x77\x58"
-  "\x84\xf3\xda\x96\x3e\x4b\x7e\xdd\x43\x56\xd6\x8f\x76\xce\xf4\x18"
-  "\x3e\x9a\xa8\xad\x2f\xc9\x33\xe3\xb1\xeb\x42\x83\x7d\xb9\xcb\x3a"
-  "\xda\x0d\x20\xb0\xf7\x52\x4f\x92\xeb\x9d\x7e\x27\x19\x06\xa0\xd7"
-  "\xf5\x1b\xa0\xbf\xef\xca\x49\xda\x39\x81\x32\xf1\x6e\xc2\x49\xda"
-  "\xb9\x23\x68\xa0\x54\xfc\x2c\xde\xab\x8a\x2e\x03\xdc\x2c\x5e\x7b"
-  "\x6b\x3f\xcb\x6b\x2d\x3b\x4f\x49\xbd\xeb\x4d\x4a\x0b\x03\x1e\xef"
-  "\x17\x54\x4d\xa0\x34\x5e\xff\x42\x5a\x7a\x6e\x48\xed\x9b\xe9\xb6"
-  "\xfa\xa6\x09\x94\x11\x5d\xef\x4e\xed\x2c\xb8\x4b\xae\xa5\xaf\xf5"
-  "\xd2\x35\x25\x77\xf2\x77\x01\xab\x8a\x84\x33\x51\x88\xab\xac\x06"
-  "\xb5\x9f\x5d\xf5\x80\xb9\x4e\xf1\x9f\xdc\x27\x02\xdf\xf1\x3e\x9c"
-  "\xb6\x27\x91\x20\xcf\xca\xa7\x4c\x31\x89\x81\x74\x43\xc4\xfa\xa3"
-  "\x45\xe2\xa1\x9d\x73\x0d\x6d\x9a\x92\xc7\x30\x18\x9f\xdc\x7c\xb5"
-  "\x9f\xc1\x67\x60\x41\x63\x19\x8f\x75\xfb\x9b\x94\xf4\xca\x9b\x64"
-  "\x69\x5f\xce\xed\xaa\x52\x65\x0c\x46\x62\x7c\xc3\x2e\x1e\x6f\xe0"
-  "\x0d\xe0\xcd\xf5\xc9\x6f\xea\x06\xcf\xb4\x38\xca\x44\xb8\xe5\x69"
-  "\xd6\x2b\xab\x3e\x6a\x59\xbd\x8f\x16\xf1\x99\x61\x3e\x2f\xb4\x8c"
-  "\xbc\x8d\x80\xd7\x38\x81\x2c\x80\xd5\xee\x2e\x26\x5e\xef\xbe\xae"
-  "\x65\xf5\x01\x86\x7d\x8c\xe7\x95\x1d\xa0\x8f\x9a\x5f\x5c\xb5\xee"
-  "\x40\x17\xb5\x63\x9c\x2f\x2c\x11\x21\x86\x73\x82\x5c\x57\xca\xf6"
-  "\xee\xb2\xda\x72\xd5\x39\x65\xd9\xd6\xc1\x7d\x22\xad\x1d\xee\xb3"
-  "\x0c\xcf\x95\xe1\xce\x83\x7d\xab\xb5\x49\xa7\xb5\xe2\x2f\xd7\x8a"
-  "\x96\xd5\x7b\x88\xfb\x87\xf3\xe3\x39\xc7\xdd\x8b\xbc\xa7\xa2\xfb"
-  "\x85\xf3\xe0\xdd\x4b\x80\x7b\xdb\xd0\x5e\x27\xef\xc1\x0d\xe5\xa9"
-  "\x7f\x93\xcf\x43\xec\x6c\xdb\x05\x1a\xa9\x35\xe3\xaa\x73\x8c\x2b"
-  "\x46\x91\xcf\x5d\xf6\x69\x7c\x3f\x46\xc8\x00\xf0\xfd\xc6\x0e\xb9"
-  "\xe7\xe3\xfa\x7c\x61\x30\x2c\x94\x5c\xab\xae\x0b\x43\x1e\x78\x70"
-  "\x65\x99\x20\xe5\xca\x34\xf6\x1d\xa9\x7e\xc3\x9c\xa0\xfa\x97\xdb"
-  "\xc2\xba\x4f\xbc\x3e\x8e\xd8\x8f\xb2\x30\xae\x7a\x1f\xf3\x37\xcd"
-  "\xc2\xbc\xa7\x38\x01\xf4\x1e\xb0\x92\xe2\x3f\xe1\x02\x5c\xcd\x3f"
-  "\x3e\xed\x88\x36\x2f\x1e\xe9\x4b\x9e\xbc\x59\xbc\x60\x25\xdd\x9f"
-  "\x14\xe3\xb7\x32\x57\xf9\xe8\x5a\x59\x56\x35\x1a\xd4\xd8\x61\x1c"
-  "\xb5\xb2\x9d\x6a\x1f\xbf\x3a\x07\xe5\x3b\xe3\xb6\x37\x11\xf2\xc7"
-  "\x09\x71\x8d\xf6\xf0\xfc\x29\x20\xb3\x30\x2f\x8c\x74\xfb\xfa\xb5"
-  "\x6f\xc7\xd5\x8c\x83\xce\x3c\x92\xcf\x26\xe8\xb8\x5d\xda\xde\x51"
-  "\xb5\x47\xd9\x29\x35\x36\x7d\xed\x45\x58\x40\x63\xa7\x59\xf0\x19"
-  "\x1e\xf6\x35\xf7\x25\xbf\xd2\xe9\x4d\x6e\xd0\xbe\x2b\x54\x33\x17"
-  "\x3a\xaf\x94\xbb\xb9\x01\xaa\xe4\x76\xf1\xde\x20\x6c\xa0\x91\xdc"
-  "\x66\xc0\x29\xf2\xd0\xf2\x36\x35\xaf\x2b\xd8\xc3\xae\x7d\xe8\x6d"
-  "\x43\x9b\x64\xdb\xd0\x46\xd9\x36\xed\x9b\x2b\xa8\x4b\x9e\xdd\xbd"
-  "\xb4\xf6\xd4\x68\xfa\xfe\x2b\x9d\xfc\x5d\xc8\x13\x54\xbb\x41\xfa"
-  "\x5b\xa3\x4f\xd4\xfa\xfa\xab\x33\xc5\xe8\x57\x46\x5f\x1a\xcc\x57"
-  "\x8d\x0a\x66\x03\xfd\x88\xe3\xb3\x69\xdf\x6d\x02\xec\x42\xc8\x74"
-  "\x79\x5e\xb1\x0f\xf5\xf1\x37\xef\x86\xe4\xd0\xab\x3d\xdc\x57\xd3"
-  "\xf6\x51\x96\xe2\xc3\x57\x3f\x6b\x50\xdf\xdc\x81\x6e\xf0\xea\x76"
-  "\xf0\xbd\xfa\x66\xcd\xa0\xef\x71\x82\xf4\x3d\x8e\x94\xb1\x97\x88"
-  "\xa3\x94\x77\x22\x65\x0b\xf4\x8e\x57\xcb\x79\x3f\x9d\xf1\x5d\x1b"
-  "\xd4\xe5\xdf\xab\xe5\xfa\xde\x92\xdc\x4f\x5e\x07\x5e\xa9\x50\x67"
-  "\x17\xfd\xce\xda\x89\xba\xae\x22\xbf\xd3\xe3\x14\x87\x39\xdf\xa2"
-  "\x75\x67\xe4\x7e\x73\x95\x3c\xa7\x7b\x52\x3b\xe3\x52\x7b\x93\xb6"
-  "\x36\x91\xce\x7e\xdf\x28\x0b\xfd\xef\x80\xf4\xe3\x67\x1a\x70\xdd"
-  "\x12\x77\xf9\xad\x9c\xda\xb2\xa1\xfd\x84\x57\x17\xcb\x74\xe9\x0b"
-  "\x59\xbb\x5d\xe7\x11\xb4\x77\xa4\x8a\x97\x57\x73\xee\x50\x06\x49"
-  "\x1e\xe8\x13\xd6\xd1\xd7\xd7\x33\x4f\xd6\x1e\x88\xa4\xd3\xa2\x60"
-  "\xd8\xa1\x64\xd0\xab\xf5\x42\x8e\xf5\x57\xeb\xbf\x5e\xaf\xf8\xd1"
-  "\x65\xba\x4e\xa2\xe8\x6c\x81\x7c\x79\xfd\x88\xa4\xb5\x2b\xb5\x99"
-  "\x63\x19\xbc\x50\xc1\xf1\x58\x7e\xf4\x47\x8e\x75\x13\x74\xa5\x76"
-  "\x85\xf8\x3c\xd4\x72\xf6\x49\x49\xed\x39\x51\x42\x86\xdc\x12\xde"
-  "\x43\xc9\xcf\x63\x5b\x4d\x38\xa0\x13\xa4\x40\x4f\xc1\x38\xdf\xb0"
-  "\x82\xcc\x8f\x15\x01\xb6\x23\x3d\x95\x63\xd1\x70\x1c\x1a\x8e\x27"
-  "\x15\x72\xa4\xa7\xe0\x7e\x3c\xf4\x3a\x0b\x7f\x1b\x9e\xfd\x2d\x42"
-  "\x4e\x01\x79\x7c\x94\xe3\xe1\x18\xdc\xde\x00\x6d\x38\x45\x26\x8e"
-  "\x75\x13\xac\xce\xb7\x77\xf8\x3e\x93\x76\xca\x98\x12\xe8\xe6\x61"
-  "\x9a\x08\x9a\x5b\xc3\xc9\xf9\x79\x98\xe3\x0b\x54\xbb\xcf\x08\xd5"
-  "\x6e\x85\x37\xe3\xaf\x64\xdc\xf8\x9e\x0a\x89\xfb\xeb\xcf\x06\x01"
-  "\x3f\xec\xba\xaa\x3b\xe4\xba\xca\xa3\xce\x51\xb5\x51\x45\x99\xe8"
-  "\x71\x43\x47\x66\x9f\x3f\x3e\x53\xc6\xfe\x1c\xdc\x46\x6e\x1f\xd7"
-  "\xfd\xa7\xb3\xa7\x64\xec\x9e\x20\x9e\x1d\xc5\x5a\x99\x5e\x94\xe9"
-  "\x6d\xa3\x7e\xd7\x55\xb2\xed\x1d\x3e\x55\x36\x57\xde\x73\xf9\x08"
-  "\x3a\x68\x6d\x1e\xa4\x03\xda\xce\xed\xe3\xf6\x07\x99\x26\xa0\x81"
-  "\xd6\x56\xeb\x80\xd6\x4e\x6e\xe3\xbf\x61\xd6\x79\x13\xed\x44\x5b"
-  "\x65\x3b\x07\xd0\xce\xc3\x45\x44\x81\x9a\x57\x3c\x5f\xa5\x5c\xe5"
-  "\x61\x5b\xd3\xf1\x09\xf4\xe9\x72\x17\xc1\xa6\x34\xbe\x5b\xe1\x32"
-  "\xbc\x0c\xdd\xa4\xc2\x0b\xdb\xd2\x2b\x7a\x58\xef\x77\x97\xe0\x17"
-  "\xac\x97\xdf\xdc\x94\x7a\x32\x7f\x33\xf1\x39\xb4\x29\xfc\x39\x55"
-  "\xf4\x88\x1e\xe8\xa8\x01\x77\x10\x79\x8a\xd0\x7e\xd8\xa2\x27\x34"
-  "\xfc\x39\xef\x86\x2f\x55\xbb\xcc\xc5\x94\xfa\xe1\x23\xdb\x0c\xee"
-  "\xae\x6d\xa4\xb7\xe5\x71\xe4\x43\x7b\xac\x80\x25\xe3\xc6\x85\xd1"
-  "\xce\x5d\xc0\x33\x10\xd1\xa6\xf6\xde\x00\x60\xfe\x85\x46\x2f\xa6"
-  "\x84\x37\x4f\xa3\x1d\xa7\xc9\xea\xaa\x80\xfe\xf5\x20\xeb\x8d\xaf"
-  "\xbd\xfd\xad\x1c\x4a\xf3\xd0\x8f\xd4\xf7\x2a\x06\xbf\x6b\xfe\x7a"
-  "\xbb\x1e\x3f\x23\xcc\xf1\x87\x92\xf3\xcb\x99\x8f\x64\x2c\x0d\x9e"
-  "\x33\xfc\xe0\x19\xf6\xc5\x58\x8b\x3a\xfc\xe9\xe3\x25\x3e\x4e\x15"
-  "\x7f\x03\xcf\xfc\x1d\x95\x54\x5e\x5f\x40\x39\xbb\x00\xcd\x18\x3e"
-  "\xf4\xb9\x02\xbe\x32\x0d\xe3\x9e\x4f\x78\x8f\x66\xa2\x8e\x5a\xb6"
-  "\xa3\xf7\x57\x78\x0d\x5b\xde\xa3\x8c\x4b\x93\x29\xaf\x07\x87\x93"
-  "\xdf\xbc\xae\xcf\xf0\xd0\xb6\x94\x93\x54\x77\x2c\x7a\x8c\xd9\xa4"
-  "\x2c\x53\x72\xb0\x6e\x2f\xaf\xa5\x5f\x5a\xbd\x75\x2a\x6e\x8f\x53"
-  "\x6c\xbb\xc4\x72\xfb\x74\x3c\x70\x5f\x34\x1c\xee\x97\x4e\x87\x37"
-  "\x8c\xc3\xc1\xda\xf1\x9a\x8c\xa5\xe4\xd8\xf9\x1a\xe4\x05\x74\x85"
-  "\x43\x56\x8e\x6b\x8b\xb9\x73\x8f\x8f\x4a\x77\x93\xc9\x71\x8a\xd7"
-  "\x77\x16\xd0\xa1\xfa\x4c\x6a\x80\x7d\x2f\xfa\xd2\x53\x5e\x3d\xcb"
-  "\x7b\xea\x4a\x86\xb0\x4e\xda\xe1\x43\x99\xd2\x74\x4b\xd5\x6b\xba"
-  "\x0e\xff\x46\x7b\xf9\x39\x32\xa8\xef\x06\xbc\xd1\x96\x6d\x13\xc1"
-  "\x5a\x43\xb8\xa8\x9e\x63\xcb\xa4\x6c\xe1\x58\xbd\x45\x7a\xac\x15"
-  "\xa9\xfb\xd8\x31\xe6\xfa\xac\xa3\x77\xac\xa6\x0c\x8e\x0b\x65\xf6"
-  "\x2a\x5d\x4e\xcd\xd7\x6f\xb0\x8c\xb5\x68\xfb\xc8\x16\x15\x7f\xa5"
-  "\x2e\xbb\xf1\x2c\xea\x92\xef\xdf\x9c\x1a\x82\x2d\x23\xe1\xae\xa6"
-  "\xb4\xfa\xb3\x94\xce\x7a\x50\xee\xe7\x4a\x67\x63\xfb\x70\x41\xaf"
-  "\x59\x84\xfe\x77\x3a\xed\x3e\x39\x14\x37\xca\x5b\xca\xb1\xa6\x84"
-  "\x75\xb8\x33\xa2\x55\xe3\xa5\xcf\x88\x8c\x01\xa0\xbe\x2b\x45\x54"
-  "\x5b\x43\x46\xfe\x8e\x22\xaf\xd5\xf1\x3a\x2f\x9f\x15\x51\x73\xc8"
-  "\x9b\xf5\x7a\x5c\x9d\xf8\xb2\xfc\xc5\xa6\xe9\x52\xc7\x7a\xb1\xe9"
-  "\xd2\xfa\xed\xcd\x83\xc3\xda\x2a\x80\xc9\x7c\xf0\x5f\x83\xbb\x2b"
-  "\xf5\x22\x7a\x8d\x31\xec\x52\xb6\x59\x78\x24\x6c\x46\xaf\xbf\xa5"
-  "\x65\x0d\xcf\x6f\xbb\x5c\x7c\x96\x66\xc8\x1e\xdb\xf5\x1c\xbf\xe3"
-  "\x34\xf6\xf5\xce\x92\xfd\xbe\xab\x99\x6d\x34\xcd\xce\xfd\xd0\x36"
-  "\x98\xa6\xf4\x2d\x9e\x77\x99\x5e\x8d\x6a\xfd\x7a\x8c\xdf\xb9\xeb"
-  "\x88\x3e\xf7\xb2\x0e\xa2\xbe\x37\xb9\xab\xc7\x63\x38\x74\x81\x2f"
-  "\x4e\xec\x7a\xbe\xf4\xe9\xe2\xb8\x3e\xce\x7a\xab\x3e\x17\xcb\xef"
-  "\x09\x6c\x9a\x70\x4f\xe9\x3a\x9a\xf8\xd0\x95\xbc\xa7\x2d\xcf\x44"
-  "\xf4\x28\x1d\xa1\x3e\x6b\x68\x6f\x2c\x4b\xf2\x86\xfc\x56\x18\xdb"
-  "\x43\x06\xe8\x0b\x2a\x9e\x55\xaf\xd2\x15\xf4\xf3\xb0\xf5\x8f\x45"
-  "\xd4\x53\x39\x38\xe7\xa3\x0e\xf6\x6d\x60\xf8\x4a\x8f\xaa\x9f\xc1"
-  "\x75\xb0\x1d\xa8\x74\x81\xfa\x19\x17\xa1\x6f\x3a\xd3\x37\xac\xd9"
-  "\xbe\xee\xde\xbf\x29\xfa\xda\x29\x71\x7a\x2d\x59\x3f\xac\xf0\x18"
-  "\x31\xc7\x24\xd8\x56\x93\x19\xf5\x7f\xc2\xef\x79\x5c\xb6\x4c\xe3"
-  "\x35\xc8\xdd\x53\xdd\xac\x63\x0c\xe4\x24\x2d\xe4\xf5\x09\x69\x37"
-  "\xec\x9e\x38\x15\xe5\x90\x96\xf2\xfb\xd3\x01\x63\xd5\x7a\xca\xe0"
-  "\x6f\xf2\x21\x5d\xfa\x20\x78\xaf\x78\xc6\x7f\x7d\x2a\x59\xaf\xaf"
-  "\x65\x7f\xf7\xdd\xd9\xb0\x85\x5d\x72\xad\x8b\xeb\xaf\x69\xc8\xe4"
-  "\x58\x5e\xef\xf7\x7b\x46\xa8\xbe\xda\x7d\x0c\xcf\xe9\x11\xcf\x1b"
-  "\xf4\x3d\x04\x0f\xed\xf6\xc8\x7d\x48\xf6\xe9\x95\xfe\xae\x5b\xeb"
-  "\x86\x7c\x65\x76\x1f\xd3\x70\x39\x76\xa8\x84\x68\x37\x9f\x63\x18"
-  "\x2f\x3a\x51\x1f\xf4\x9f\x5d\x3e\x6d\x0d\xa9\x53\xf2\x15\xeb\xe6"
-  "\x5b\xd9\x5e\xfc\x5b\xcb\x0e\xe4\xe3\x39\x2d\xd7\x4e\x59\xca\xde"
-  "\xd8\xba\x3f\x0c\xfe\x19\x6a\xff\xee\x05\xbc\xc6\x19\x57\x7e\xbf"
-  "\x49\x24\xcb\x54\x6f\xe9\x92\xfe\x55\xd5\x4d\x2e\x5c\x4d\x18\x0b"
-  "\x7b\x71\x4d\x02\xcf\xf1\xd5\x82\x6b\x13\xae\xa9\xd0\x73\x4b\x98"
-  "\x2f\x61\x6f\x5b\x61\xd3\x98\xfa\x92\xb7\x74\x0e\x77\x16\x8f\x69"
-  "\xe3\xde\xfc\x30\x29\x7f\xd1\x86\xd6\x76\x2f\x74\x49\x90\xb3\x34"
-  "\x28\xfa\x6d\xd7\xf0\x99\x97\x86\x56\xc7\x6e\xf6\xf7\x68\xa8\x8b"
-  "\xf6\xf7\x68\x68\xc6\x2f\x00\x0e\x9f\x8f\x1f\xf4\xc8\x86\xd6\xa1"
-  "\x5f\x63\xb3\xdf\xd9\xd0\x0a\x3a\x06\xa5\xae\x79\x49\xe3\xb5\x41"
-  "\x7e\x23\xae\x8a\x6d\xb8\xe4\xc2\x26\xd5\xde\xdd\x1e\x3c\x9b\x44"
-  "\x72\x83\x4d\x6b\x6f\x33\x9e\x2d\x36\x07\xe6\xe0\x64\xd0\x64\x02"
-  "\xda\x9c\xdc\xe4\xe2\xf6\x32\xbe\x7d\xc9\x2f\xee\x8d\x3c\x87\xc8"
-  "\x30\xb9\xfd\xde\x64\x94\x03\x2d\xc5\xb4\x5b\xf3\x74\x7a\x6a\x74"
-  "\xe2\xfd\x2a\x43\x1f\x60\x28\x9d\x0d\xf9\x01\x43\xcf\x3f\x48\xfb"
-  "\x09\x1c\x1f\x1f\x7d\x8a\x7c\xb0\xdf\x4d\xfa\x19\x47\xbf\xb3\x71"
-  "\xff\x47\xc5\x6a\x2f\x83\xcb\xfa\x22\xca\xf2\xd9\xf8\xa8\xf2\xc9"
-  "\x11\x7d\x37\x01\x6d\x49\xce\x77\xa9\xbe\xdb\xe2\xd1\x70\x49\x55"
-  "\xb8\x6c\x85\xdd\xda\xf0\xb1\xc2\xa7\x71\xcf\x70\x63\xac\x62\x12"
-  "\x74\x54\x48\xe4\xe9\xca\x76\x9d\xe5\x9e\xe8\x23\x77\x7d\x18\x7a"
-  "\xcb\xd6\xce\xac\x0a\xd1\x72\x82\x9a\x36\x74\x04\x7a\x2e\x71\x4e"
-  "\x6f\x92\x71\xaa\x44\x7f\x25\xb9\xcb\x6f\x96\xb6\xe4\x69\x7a\xeb"
-  "\x5d\xb7\x57\xc6\x7a\xe6\x7b\xe9\xc3\xcb\xbe\x18\x3c\xbf\x71\xec"
-  "\x33\x7d\x9d\x20\x8c\xbc\x0d\x9c\x8e\x34\xb7\xcf\x2b\x63\xac\x0d"
-  "\xf9\x52\x6f\x69\x56\x63\xed\xad\x42\x79\x7e\x9b\xf1\x0d\x7e\xbf"
-  "\x85\x71\x0e\xbb\xb6\x34\x73\x1b\x1c\xb0\x61\xdd\x41\x7f\x0b\x8f"
-  "\x15\xdb\x1a\x5e\xf7\x7c\xeb\x6e\xf0\xa3\x08\x57\x6f\x69\xbe\xb4"
-  "\x36\xbc\x25\x63\x04\x3b\x82\xe2\xb4\x37\x79\x0b\xdb\x0e\x86\xaa"
-  "\x8a\x11\xa6\x39\xf5\xa2\xa5\x2f\x65\x2b\xc6\xeb\x5b\x05\x1f\xd9"
-  "\x55\x9f\x5d\x22\xdc\x02\xbd\xed\x0d\x5a\xdb\x41\x2f\xc9\xb3\xd3"
-  "\xeb\x54\x4c\x39\xe4\xa9\x1f\x7e\x2e\xdb\xba\x9f\xe7\x32\xf6\xf3"
-  "\xd4\x68\xd1\x3b\x38\x67\x5c\x1a\x1e\xc3\xc7\xc6\x1e\xaa\x63\x40"
-  "\xd5\xf1\xe3\xc5\xff\xb5\x3a\x7e\xbc\xf8\x62\x75\x40\x66\x5c\x7d"
-  "\x92\x7e\x7c\xf4\xd2\xed\xdf\x1f\x4b\xfb\x17\x72\xb5\x59\xc9\xd2"
-  "\x3d\x0b\x42\xb0\x41\x83\x96\xdd\x1e\xf9\x3d\x19\x03\x55\xba\x3d"
-  "\x41\x0a\xba\x0a\x9b\xda\xed\xfd\xd4\xb2\xe6\xcf\xd4\x4d\x3f\x91"
-  "\xf1\x5f\xdb\xcb\xd8\xee\x6c\xb0\x0d\xd4\xbc\x68\x1b\x30\xfc\x38"
-  "\x83\xe9\xbd\x9b\xe3\xf7\x45\xf0\x59\x87\xef\xcf\xe4\xce\xe3\xb5"
-  "\xe2\x4e\x5e\xa3\x87\x8c\xd8\xed\x09\x43\x66\xc0\xce\x08\x49\x7a"
-  "\x40\x07\x53\x36\xe3\x2b\x87\xa5\xcd\xe8\x95\xe7\xf2\x2e\x87\xee"
-  "\x9e\x24\x9c\xcb\x37\xf3\x3a\x7e\x68\x20\xc7\xe6\x77\xd2\x62\x8e"
-  "\xa5\xc7\x6b\xe8\xc2\x92\x56\xb6\x28\x98\x28\xa4\x4d\x08\xfb\x85"
-  "\x63\xea\xb9\x7d\x1e\x0a\xc1\x16\xa8\x3f\x4f\xa9\xf5\xd0\x9f\x21"
-  "\xcb\x2d\x2c\xef\x1b\xb5\x98\x7a\x3b\xce\x0f\xc5\xd4\x6b\xe0\xf5"
-  "\xaa\x2e\xdc\x9f\x27\x63\xa8\xfa\x95\xc3\xbb\xce\x53\xda\xee\x35"
-  "\x94\xbe\x8b\xd7\x23\xbf\x50\xfa\x1b\xeb\x1b\x32\xbe\xde\xaa\x74"
-  "\xde\x9b\x18\xd2\xdf\xd6\x72\xdc\xcf\x41\x79\x66\x94\xeb\x38\x97"
-  "\x44\xef\x3d\xf2\x1b\x01\x41\xd7\x96\xae\xa0\xa5\xc9\x05\xda\xed"
-  "\xf5\xd0\x4f\xe6\x0f\x18\xde\x8a\x1b\xd7\x41\xf7\xb5\xaa\x8d\x88"
-  "\x89\xf8\x51\x9a\x92\xfb\x80\x35\x7c\x5c\xb6\x5d\x39\x34\xbd\x97"
-  "\x32\x95\xff\xc4\x65\x98\x2b\xf7\xf8\x78\x3f\xbf\xe2\x59\xb2\x86"
-  "\x76\x2d\x4b\x70\xbc\x45\x89\xfc\xfd\x62\xfe\x55\x7c\x29\x7a\xa6"
-  "\x17\x53\x26\xef\xa5\xb0\x8f\x85\xed\x05\x99\xff\xe3\xb4\x72\xca"
-  "\x8c\x84\x3d\x57\x39\x3f\xdd\x61\x9b\xb7\xf2\xc9\x55\xcf\x96\xe4"
-  "\x97\xad\x78\x62\x45\xf1\x8a\xb2\x75\x77\xc8\x60\xc2\xf2\xdf\x7d"
-  "\x93\x0b\x96\xc8\x4d\xf0\x08\xbd\x23\x6d\x68\x4d\xf1\xed\x0d\x21"
-  "\x5e\x03\xb9\x24\x7a\xbd\x3d\x57\xdb\x57\xf4\xee\x96\xfb\x6c\x6f"
-  "\xbb\x3c\x86\x3f\xa8\xf5\x36\xe8\xa2\x3b\x54\x3c\x94\x9e\x96\xeb"
-  "\x42\x0c\x7f\xae\xe2\xe5\x86\x12\xf0\xf2\xac\xe3\xb4\x77\x19\xef"
-  "\xef\xa0\xbf\xf6\xba\xcb\x4f\x12\x74\x94\x59\xbc\x6f\xd4\xce\x6b"
-  "\x32\x52\x87\xff\xa9\x3a\xc3\x70\x5a\xc6\x06\xda\x73\x1c\xcf\xec"
-  "\xab\x1e\x16\x39\xbb\x42\xab\xac\x7b\xc2\xab\xac\x3f\x15\x22\xe7"
-  "\xcd\xf0\x99\xa2\x5d\xe2\x4c\xd1\x9b\x43\xe7\xfa\x7f\x3a\x2e\xe8"
-  "\xa4\x44\xfc\xc0\x0b\xe3\xd3\x23\xf6\x10\xf9\xdd\xed\x0c\xb3\x64"
-  "\x35\xfb\x72\xfd\x94\xfd\xa3\x61\xfb\x8f\xff\x8e\xd7\x51\x94\x38"
-  "\xbf\x1b\x3c\xaf\xea\x2d\x74\x6f\x3e\x41\x6a\xdf\xf8\xa7\x05\x2d"
-  "\x72\x9d\xfb\xa7\x21\x2e\xc7\xfb\x8c\xac\xf7\xcb\xf8\xa1\x86\xb7"
-  "\xa5\x2f\x1f\xeb\xfc\xbb\x53\xc8\xe2\x4a\xa1\x24\xbf\xf3\xa7\x83"
-  "\xfe\x5f\xc2\xa2\xe6\x56\x9e\xdf\x38\xde\x2d\x64\x8c\x9f\xe7\x4a"
-  "\xc6\x83\xf9\x12\x30\x0f\xf2\x1e\xa4\x3a\xf7\xf3\xd3\xc3\xd0\x23"
-  "\xf7\x5e\xba\x8c\xfd\xa9\x5c\x93\x17\x06\x87\x98\xbe\x9d\xf2\xe4"
-  "\xfe\xb0\xf2\x53\x34\x62\x1c\x16\xa9\xf6\xec\xbd\x55\xee\xed\xaf"
-  "\x39\xd5\x84\x71\x52\xd9\xd8\x4f\x49\x61\x57\x5a\x31\xeb\x33\xed"
-  "\xe5\x72\x5f\xdd\x84\x72\xfb\x79\xdf\x5d\x9e\x95\x93\xf1\x93\xff"
-  "\x4c\x8d\xe7\xc8\xd8\x4d\x3f\xcb\xe6\xfd\x81\x21\xda\xfe\xec\x0d"
-  "\xde\x17\x12\x35\x63\x9b\xcc\xe5\x86\x6d\x0c\x23\x7c\xfe\xf4\x4c"
-  "\xbd\x1c\xe6\xf0\x51\x5c\xee\x38\xfd\x6c\x83\x2c\xc7\x79\xe5\xb7"
-  "\xf7\x2c\xcb\x30\x6f\x75\x71\xfe\x20\x9e\x1b\xc2\x96\xc5\x02\xe3"
-  "\x2b\xb4\x26\xb4\x1f\xef\x96\x84\x5d\x2f\xee\x45\x5a\x8e\x5c\x97"
-  "\x1e\xb0\x92\x8c\xd1\x61\xc9\xaf\x73\x7b\xfe\xd6\x22\xf1\x61\x7f"
-  "\xd5\x32\xc8\x22\xa9\xff\xfd\xec\x93\x86\x2f\x64\x5c\x67\xf4\xe1"
-  "\xde\x02\x8d\x47\xf6\x2a\xfc\xf6\x16\xf6\xd5\x5c\xe5\xe9\xb3\x6c"
-  "\xdd\xeb\x33\x98\xe8\x90\x95\xfd\xe2\x1b\x4a\x0e\x59\xfb\x61\x43"
-  "\xec\xcd\xf0\x18\xc7\x5a\x94\xee\xa1\xca\xf1\xbe\x14\xf4\xd2\xde"
-  "\x44\xeb\x98\x01\xbc\x9f\xaf\xfb\x77\xf0\xf7\xaa\x79\x5f\xca\x43"
-  "\x3f\x4b\x63\xba\x81\xcf\xdb\xe4\xde\xc4\xa6\x47\x7b\xd0\x9e\x91"
-  "\xec\x83\xc7\x74\xe6\xf3\x07\x66\xdc\x8b\x35\x62\xa6\x39\x98\x65"
-  "\x68\x94\x67\x0d\xe5\x19\xf6\x19\x5a\x9c\x91\x4c\x2d\xee\x48\x06"
-  "\x3f\xab\x33\xf0\x7b\x0f\xe8\x67\xce\x39\xb6\x8a\x76\x5e\x4c\xfa"
-  "\xf5\xc9\x98\x23\x67\xd5\xde\x2e\xfb\xf5\xf1\x9a\x26\xfb\xc9\xf3"
-  "\xfe\x2b\xca\xf5\x46\xf8\xc6\x27\xe0\x39\xa8\xc7\x1a\xf1\x3b\xdf"
-  "\x31\x0d\xfa\x0b\xa1\xed\x7d\xae\xad\x4d\x3e\x4b\x43\x89\xcf\xb5"
-  "\x05\xf3\xf7\x3b\x69\x90\x45\xc5\x17\xb1\x9d\x8c\x7c\xf6\x90\xe3"
-  "\x4b\x84\x53\xd2\x6a\x39\xc6\x04\xc7\xb2\x52\xfe\xed\xef\x6c\xd1"
-  "\xce\x74\x27\x9e\xa6\x77\xee\x1e\xda\x07\x0d\x69\x6b\x77\xef\xec"
-  "\x53\x7a\xd7\x3b\xfb\xe4\xda\x5d\xcd\xd6\xca\x9f\xac\x0f\x18\xf6"
-  "\xaf\xf7\x18\x1a\xe4\xf9\xae\x77\x40\xbb\xf7\x8b\x75\x1f\x19\xe4"
-  "\xcb\x63\x58\xf1\xe7\xc9\x29\x8b\x15\xcc\x9f\xcb\x18\xa5\x43\xf6"
-  "\xcd\xcf\xd5\x77\x8f\x36\x4d\xc8\x0b\xf3\x9c\x97\x52\xb8\x5f\xfa"
-  "\x96\x94\x9c\xe5\x35\xbc\x91\xca\xd6\x52\x79\x34\xbf\xcc\xb1\x27"
-  "\xa3\x9f\x53\xf8\x59\xd1\xec\xe7\x99\xfa\x7e\xc0\x4e\x43\xd8\x63"
-  "\x4e\x20\xe1\x68\x12\x3e\x8e\x61\x06\x7d\xca\xeb\xc6\x1c\x8a\x3a"
-  "\x04\xe4\xc3\x28\x94\x29\x64\xda\xab\x31\xf4\x73\xf9\x7d\x8f\xb0"
-  "\xf3\x2e\xe1\x60\x3d\xd2\xcb\xbe\x2d\x67\x09\xf9\x92\x91\xaf\xba"
-  "\xb5\xbc\x97\x7d\x67\xf2\x38\x36\x58\xb7\x56\xb7\x37\x79\xca\xe2"
-  "\xeb\x93\x28\x0f\x75\xee\xf1\x50\x79\xf9\xa5\x8f\xed\x9f\x0f\xab"
-  "\xcb\x0e\xb5\xeb\x17\xa9\x43\x7d\xf2\x57\xad\x4f\x7e\x91\xfa\x75"
-  "\x7b\xc8\x9a\x4e\x32\xee\x24\xbd\x3b\x82\xed\x66\xdc\x5f\x7b\x92"
-  "\xf6\xc9\x3d\x4a\xe5\x8b\xbc\xef\x8f\xda\x3d\xea\xd8\xf7\x4b\xed"
-  "\xfe\x2a\xdc\xbf\xa1\xdd\x4f\xc0\xfd\x46\xed\x1e\xf4\xde\xb7\x42"
-  "\xbb\x4f\xc5\xfd\x03\xda\x3d\xc6\xe7\xbe\xdb\xb5\xfb\xf1\xb8\x9f"
-  "\xa4\xdd\x5f\x89\xfb\xcb\xb4\xbd\x37\x13\xf0\x3d\x77\xe9\x7a\xd1"
-  "\x2f\x5a\xd4\xfe\x0e\xef\xab\xbd\x9d\xa1\xc6\xf4\x60\x5a\x2a\xec"
-  "\xcb\x25\xfa\xfa\x3a\xd2\x59\x97\x36\x21\x3d\x03\xfc\x97\x19\x91"
-  "\xbe\x57\xcb\x9f\x0d\x3d\xcb\x15\x91\x5e\xaf\xa5\x2f\x43\xfe\xe6"
-  "\x88\x74\x97\x96\x5e\xe6\xa1\xda\xa3\x11\xe9\x9b\xb5\xf4\xed\xfa"
-  "\x9e\xb6\x96\x6e\xd7\xd2\xd1\xff\xdb\x37\x47\xa4\x6b\xf1\x04\xf7"
-  "\x1d\x44\x1f\x77\x47\xa4\xe7\x49\x9e\x95\x71\xe1\xcc\xe2\x50\xf9"
-  "\x0c\x8c\xf9\x7d\x1e\x0f\xd5\x94\x47\xe4\x59\xa2\x95\x0d\x78\xa8"
-  "\x7a\x4f\x44\xfa\x5c\x95\xfe\xae\xc5\x43\x9f\xee\x8d\x48\x9f\x35"
-  "\x1c\x0f\x25\xd4\x51\xdc\xf5\x55\x5e\xdf\xe2\xef\x7b\x48\xbf\x38"
-  "\xe9\x13\xf9\xde\x02\x3e\x23\x63\xde\x2d\x8e\xdb\x2a\x84\x38\x4e"
-  "\xef\xcd\xd0\x7c\xc5\x96\xb1\x7f\x10\x9f\x29\xea\xa6\xf7\xae\x96"
-  "\xe7\x4f\x38\x2e\x1a\x9f\x33\x5a\xcf\xe7\x8c\xde\x95\x71\x5e\xa7"
-  "\xdb\x2b\x55\xcc\x34\xe5\x6f\xd8\x2b\x6d\x25\x6d\x2f\x0c\x79\xf8"
-  "\xfb\xa1\xfc\x4d\xc6\x5e\x5e\x67\x71\x97\xf5\x4b\xbf\x38\xd6\x55"
-  "\x39\x8d\x6d\x06\x79\x26\x25\x42\x67\x55\xe3\xf1\xbd\x05\x61\x3e"
-  "\x0f\xec\x54\x76\x55\x95\x8a\xc5\xd7\xcb\x7e\x1c\x91\x79\x3d\xf4"
-  "\xde\x7c\xbe\x26\x5a\xcd\xc7\xfc\xce\xf7\x32\x86\xce\x55\xbc\xbb"
-  "\x59\x4b\xf7\x20\x3d\x3b\x22\xfd\x82\xd8\xbe\x43\xf2\x69\x6c\xb3"
-  "\xb0\x8c\xed\x19\x38\x2f\x7c\xc1\xf3\x22\xb0\xf3\x3f\x80\xf7\x72"
-  "\x79\xde\xe0\x9a\x90\x6b\x6c\x40\x3b\x5b\x7f\x2c\xb8\x46\x78\xa1"
-  "\xa7\x71\xac\xee\x6f\x2d\x84\x5d\xb7\xb0\xc4\x2f\x76\x3c\xc1\x7e"
-  "\x5d\xe7\x64\x9c\x19\x47\x2f\xc7\x05\x65\x3f\x1f\x1f\xef\x21\x24"
-  "\x75\x40\xf6\x34\x2c\xe7\xf7\x9f\xd1\x82\x22\xe8\x3f\x45\x21\x6a"
-  "\x00\xec\xdd\x4f\xe8\x3e\x45\xef\x75\x0f\xfa\xce\x01\x07\xae\xcf"
-  "\x21\x63\xed\xbf\x2f\xf5\x7c\xfe\x86\x90\xa8\x6e\x6a\x12\x7f\x60"
-  "\xbd\x62\x0b\x7f\x3b\xca\x06\x99\x6b\xc3\xfd\x7e\xf5\xc3\x3b\xa4"
-  "\x0f\xd7\x26\x35\x4e\xdf\x57\xdf\xf5\x74\xa5\x16\x29\x59\xf0\xfe"
-  "\x32\xf1\x63\x3e\x6f\xf1\x7e\x1e\x64\x89\x1d\x3a\x8c\x3d\x5e\xf9"
-  "\x0d\xbb\xc9\x30\x50\x83\x39\xe3\x74\xb3\x41\xc9\x9e\xfd\xf3\xc3"
-  "\x06\xd3\x46\x5e\xcf\x91\xf1\xb6\x6b\xd2\xf6\xec\x5b\x19\x30\xb4"
-  "\xaf\xef\xa6\x17\xae\x24\xeb\xb2\x00\xfb\x05\xbf\xdf\x3e\xa6\x8c"
-  "\x63\xbf\x6d\xad\x84\x3e\x60\xf8\x35\xde\xff\x7e\x65\xb3\x21\x28"
-  "\xe7\x91\xfd\xf3\xe5\x1a\x80\x2b\xad\x9c\xf7\x10\xdc\x5d\x21\xd6"
-  "\x65\x92\xa0\xcb\x14\x8b\xd2\x74\x53\x68\x6d\x51\x4a\xb0\xb4\xe8"
-  "\x5b\xbb\x57\x53\x52\xa8\x34\x3d\xf5\xd5\xf3\x34\x53\x8f\xe3\x0d"
-  "\x1b\x21\x53\xf8\xad\xa3\xab\xd6\x50\x06\xdb\x10\x63\x12\x2c\x72"
-  "\x5f\x86\xef\xc3\x86\xd7\x7b\x1a\xd6\x5c\xfc\x9b\x01\x21\xd8\x0e"
-  "\x1c\xef\x97\x71\x89\xd7\xd6\xed\x6f\xc2\x1e\xd1\xce\xe2\x55\x7c"
-  "\x4e\xe3\xa1\x7f\x18\xc6\x9c\x13\x2d\x27\x8b\xc9\xc0\xf1\xd6\x2b"
-  "\x0a\xa5\x9d\x3e\xa2\xbd\x28\x48\x6e\xfb\xa7\x54\xb1\x9a\xfb\x68"
-  "\xff\x5b\x3c\x7f\xb2\x9f\x1e\xf2\x5b\x4e\xd2\xfe\x5f\x9a\x03\x64"
-  "\xc0\x2f\xa1\xe5\x69\xd6\xb9\xf7\x7f\xcc\x7a\xbf\x87\x7e\x69\x62"
-  "\x5f\xe1\x96\xd5\xf7\x70\xda\x31\xc7\xe7\x72\x1f\x3d\x4f\x9d\xd7"
-  "\xdb\x7f\x90\x9f\x1d\x7c\x36\x30\xe5\x86\x6d\xef\xf5\x07\x46\x28"
-  "\x5b\x70\xff\x07\x9a\xec\x2f\x41\x9f\x4d\x04\xec\x61\xd7\x85\xc3"
-  "\x2e\x2b\xb7\xf3\x5a\x77\x7d\x90\x16\xfa\x84\x47\xee\x79\xf1\x99"
-  "\x68\xfb\x5d\x2d\xe2\xbc\x8b\xd4\x79\xa0\x5f\x6e\x0c\x57\x5b\x4d"
-  "\xec\x13\x80\x7b\x79\xae\x4d\xad\x29\x59\xad\x6a\x1d\xc6\x9a\xae"
-  "\xd6\x94\xac\x33\x37\x4d\x60\x7f\xd5\x5f\x56\xf6\x25\x5b\xe7\xe2"
-  "\xba\xa4\x2f\x65\xaa\x67\xf8\xb9\x66\xdc\x4c\xdb\x35\x94\xca\x6b"
-  "\x99\xec\x7b\xda\xa8\x7c\x4e\x51\xc7\xaf\x36\x8b\x6a\xf9\xee\xda"
-  "\xe3\x25\x94\xc8\xeb\x3f\xa8\xf7\x93\xe9\xf5\x64\x03\xae\x97\x0b"
-  "\xcb\x15\x3d\xd2\x0f\xc8\x75\x45\xc0\xdd\x2b\x5a\xd8\x0f\x4d\xad"
-  "\x39\xff\xca\x25\x92\xaf\xe8\x51\xf9\x7f\x35\xa9\xa3\x17\x6d\xb0"
-  "\x5c\xd1\xec\x0e\x9c\xd2\xe6\xea\x5f\x81\xf7\xaf\x68\x16\xae\x2b"
-  "\x0e\xab\x33\xb6\xbf\x7a\x4e\x97\xab\x8a\x47\x7f\x55\xa8\xe8\x36"
-  "\x6e\xa6\xa2\xdb\xaf\x5c\xda\xbc\x74\x2d\xdf\x43\x4f\xc8\x54\xfb"
-  "\xb9\xbf\x5a\xa6\xeb\x2e\x1e\x2d\x0f\x97\xc1\x7d\x96\x92\xb5\xbf"
-  "\x2a\x47\xdb\xb5\x7d\xe0\x5f\xd9\x38\x0d\xed\xc3\xdc\xf4\xcb\x66"
-  "\x6e\xd7\x70\xb2\x55\xd2\xa2\x9c\x12\x81\x33\x7f\x37\x94\x7d\x5f"
-  "\x7d\x6e\xdf\x5d\x2d\xea\x1b\x60\x07\xae\x94\x67\x10\x51\x0f\xfa"
-  "\xc7\xc0\x72\x93\x63\x1d\x30\xbc\x08\xfc\x43\x3a\x2e\x5c\x1f\xbf"
-  "\x43\x5b\x9b\xb9\x3f\x41\x2b\x8e\xc7\x40\xdc\xaf\xb0\xd7\x13\xd9"
-  "\xfe\x6e\x59\xc3\x3e\x25\x07\xd2\x99\x26\x8a\x66\x07\xe4\xbe\x4f"
-  "\xd5\x60\x3f\xfc\xfa\xab\x68\x7a\xa8\xe7\xb0\x05\xb2\x61\x35\xfb"
-  "\x16\x1c\x48\xd7\xe8\xd7\xab\xea\xff\xf5\x5f\x34\x1b\x0a\xef\x7e"
-  "\xbd\x23\xa2\xec\xd5\x83\x79\xd5\xf7\xe6\x0c\xbc\x4f\xc7\x6b\xa1"
-  "\x8a\x5f\x7f\xdd\x1c\x51\xae\x39\xf7\xcb\x2c\xe2\x78\xfc\xfc\x7d"
-  "\x30\xa6\xb9\xdf\xf9\xeb\xb6\x21\x7a\x2b\x38\x71\xea\xb8\x46\xaf"
-  "\xc3\x43\xbf\xde\xae\xe3\x89\xfb\x3c\xd5\x27\x07\x2c\x43\x7d\xf2"
-  "\xeb\x4c\xbd\x1c\xfb\x75\xa3\x8f\x8e\xf2\xd9\xaf\xb8\x72\x90\xd7"
-  "\xdc\x27\x42\x06\x07\xef\x6a\x91\xfc\x48\x07\xb6\xb1\xff\x24\xe8"
-  "\xaa\x7d\x0f\xea\x40\xb1\x9a\x0b\x0f\xc8\x33\xed\xbc\x9e\x7d\x28"
-  "\xc0\x3c\x72\xa0\x12\x70\xeb\x35\x9c\x6b\x35\x1c\x6a\x81\xc3\xf6"
-  "\x61\xcf\xcd\x0c\x9e\x5d\x3b\x70\x30\xe2\xbc\x5e\x99\xa2\xed\x6f"
-  "\xf8\xac\xec\x81\x9d\xca\x76\x68\xde\x89\xfe\x71\x9c\xa3\x09\x1c"
-  "\x53\xbf\xa2\x44\x9c\xec\x28\x81\x3d\x63\x49\x6b\x81\x6c\x68\xad"
-  "\x38\x47\xa3\x79\x0f\x9e\x65\x0b\xfb\xfa\x89\x64\xa4\x57\xa7\xb5"
-  "\x0e\x9d\x55\xfa\xad\x95\xcf\xfe\xed\xe0\x98\x49\xa7\x68\x82\xda"
-  "\x53\xff\xcd\xbd\x6c\x43\x0b\x07\xec\x66\x57\xda\x61\x3e\xbb\xd6"
-  "\x01\xad\x5c\x38\x8a\xde\x0c\x57\xa7\x1d\x06\xdc\x2e\xc7\xb3\x94"
-  "\xc2\x73\x19\xdb\xe2\x8a\x3f\x7e\x13\x00\xdc\x2e\x8e\xdb\x04\xdb"
-  "\x3b\x41\x58\x26\x4f\x0c\x5b\xa6\xcc\x67\xb8\x5c\x37\x78\xca\x70"
-  "\x9c\x7e\xf3\x23\x91\x3c\x79\x22\x7f\xdb\x8b\x6d\x6d\x77\x00\x78"
-  "\x56\x4f\x9e\x88\x77\x63\xf0\xee\x23\x5c\xc3\x1c\xc3\x89\x63\xd0"
-  "\x02\xbe\x95\xe1\x0b\xd7\xe4\x89\x0a\x77\xaf\xcc\x7b\x9c\x7e\x7b"
-  "\x25\xe7\xd1\x63\x43\x85\x1d\x39\x89\xfc\x9e\xdb\x10\x42\x39\xb7"
-  "\x1d\x78\xca\x32\x5d\xb2\x8c\x87\xdb\x87\x72\x9a\xdf\x86\x4d\xed"
-  "\xb9\xfd\xd6\xa2\xef\x1d\x79\xe8\x37\x05\x8c\x73\xfc\xf8\xa1\xbf"
-  "\x9d\x19\x1d\xcb\xe3\x9f\xf9\xac\x28\xa7\x2f\xd6\xe3\x6f\xe0\x1e"
-  "\xe3\xff\x80\x3a\x3f\x1f\x11\x4b\x67\x67\x44\x5c\x2e\x87\x57\xfc"
-  "\x27\xe3\x02\x3e\x4d\x04\xbd\xf7\x8a\xea\x29\xf3\xd5\x39\x8b\xdf"
-  "\xca\x31\x84\x36\xf1\x78\x34\xab\x73\xc1\xbf\xfd\x17\x8d\x1f\x73"
-  "\x16\x85\x82\x66\x0f\xea\xc4\xd8\xcd\x19\x7a\xfe\xed\x7e\xf0\xa7"
-  "\x05\xf9\xbe\x50\x71\xab\x7e\xbb\x37\x3a\xbf\x7c\x5f\x19\xf3\x9c"
-  "\x15\xf3\x6c\xf3\xa1\x6f\x86\xdb\x23\xdb\x31\x41\xae\x0b\x94\x8f"
-  "\xd9\x48\x25\x8e\x2f\x28\x11\x7d\xf5\x39\xe3\xd6\xd1\xd3\xcb\x6d"
-  "\x32\x0b\x67\x26\xb9\x7b\x82\x4a\x57\xc1\x1c\x71\x3c\x0d\x79\xbe"
-  "\xa0\xf1\xec\x73\xca\xb1\xc0\x91\xff\xa4\x8a\x5b\xda\x5c\xbd\xec"
-  "\xf9\xd1\x14\x7e\x2a\xe7\x5b\xc2\xf0\x4f\x73\x31\x1f\x98\xde\xed"
-  "\xf7\x8c\xe0\x75\xe9\x8a\x37\x68\x22\xc7\xbf\x00\x6f\x76\xf3\x77"
-  "\x62\xf8\xbb\xbd\x3f\xe9\xef\x19\xe1\x0e\x7e\x4a\x25\x4f\x93\xe1"
-  "\x24\x35\x6f\x36\x96\x93\xb1\xea\x04\x59\x16\x05\x45\xf0\x50\x70"
-  "\x26\xe9\xe7\x7a\xeb\x53\xd4\xf9\x48\xd8\xe5\xde\x52\xab\x08\xf8"
-  "\x9d\xff\x0c\xfd\xf7\xcd\x1c\xcd\x87\xc7\xb7\x5d\xc5\xfb\x36\xa2"
-  "\xfe\x05\x06\xed\x0c\xb3\xa2\x6d\xf3\xd5\xea\x9c\x46\xca\xb7\xfd"
-  "\xce\xe6\xd4\x21\x7d\xae\xb9\x49\xd1\x70\x4a\x89\x1a\x5f\xcd\x4d"
-  "\x87\x60\xf9\x6f\x56\x7b\x8d\xa9\xc8\x9b\x35\xb8\xd7\x28\xed\xd3"
-  "\x66\xe8\x4a\x53\x4a\x94\xae\x37\xa5\x24\x37\x64\xd2\xc6\x00\xa7"
-  "\x8f\x6d\xe6\xb2\x28\x67\xf6\x49\x5b\xb2\xb9\x7c\x88\xd7\x9a\xf9"
-  "\x7b\xe9\x09\x68\x53\x12\xfa\xb5\x99\xdb\xc5\x34\x41\x3e\x23\x9e"
-  "\x0f\x1e\xda\x33\x4c\xfc\x42\x4b\x6a\x51\xd0\x29\xf7\xcd\xec\xe0"
-  "\xa7\x53\xe8\x83\xb1\x1c\xaf\xc4\x8d\x7a\xda\x1b\xfa\xa9\xdd\xda"
-  "\x47\x1d\x05\x7c\xa6\x04\xfa\xf2\xd3\xff\x49\xdd\xb6\xf8\xf2\x0b"
-  "\x32\x10\xe3\x69\x6c\x80\x61\x41\x4e\xf4\xb0\xcf\x88\xbb\x1c\xf2"
-  "\xcc\xcb\xdf\xa7\x21\x09\xa3\x3d\xdc\x43\xed\x76\xd6\xdb\x9b\x9a"
-  "\x3a\x1a\x3e\xa5\x0e\xeb\xff\x27\xeb\x61\x1d\xa3\x65\x75\xdf\x45"
-  "\x60\xa7\x42\x4f\x4c\xb5\x6a\xb0\x7b\x01\x3b\x75\x78\xd8\x5b\x5a"
-  "\x2e\x0d\xf6\xa5\xe0\xbd\x65\xff\xa5\xc0\x86\x2c\x2b\x76\x5b\xd5"
-  "\xb9\x94\x8a\x2b\xe9\xf2\xd0\x79\x8e\x4f\x77\xad\x50\x3e\x78\xbf"
-  "\x7b\x5e\x9e\x5d\x71\x4a\x1f\xc7\x22\x79\x86\xe5\x34\x49\x3f\x2a"
-  "\x75\x6e\xe5\x73\xe2\x7d\x4d\xbf\xf3\x77\x79\x43\xba\xf7\xe0\xba"
-  "\x32\x64\xcc\xef\x36\x2b\x5f\xab\xb4\x22\xc5\x57\xbf\xbb\x9d\x61"
-  "\xc5\xc7\x63\xb2\x5d\xf9\xec\xfd\x4e\xd7\xd7\xf6\xf7\x25\x4f\xb6"
-  "\x6b\xb0\x6c\xb1\xfb\x8d\xfa\x87\xe1\x0a\xed\x65\xfa\x37\xe6\xca"
-  "\xb4\xe3\x6b\x0f\x16\x3e\x59\xb8\x62\x4d\x61\x81\x6d\xc9\xf3\xab"
-  "\x57\x4e\x5d\xb5\x7c\xb9\x6d\x41\x61\x69\x69\xfe\x53\x85\xa3\x69"
-  "\xc9\xea\xfc\x95\xa5\x2b\xca\x56\xac\x5a\x69\xb3\x65\xdf\x92\x5b"
-  "\xb4\xaa\x6c\xea\x9d\xd9\x99\x31\xe7\x9d\xf8\xac\xd3\x51\xd6\xe9"
-  "\x1c\x1b\x30\x3e\x43\x94\xcc\xb1\x27\xcc\xeb\x44\xcb\x0b\xb0\x27"
-  "\xc0\x7f\x27\x79\x5d\x1d\xe3\xf6\x18\xeb\x9a\x1c\xeb\x0a\xf3\x66"
-  "\xdb\xae\xd7\x44\xe7\x09\x6a\x3b\x07\x3d\x85\xbf\x4f\xca\x71\x9b"
-  "\x8e\xc2\xc6\xf3\xaa\xef\x20\xb5\x7d\xc2\x31\x99\x5e\x41\x9a\x37"
-  "\x79\x4a\x49\xd5\x7f\x90\x11\x73\x0f\xf4\xdc\x7f\xed\x14\x86\x51"
-  "\x62\xfb\x78\xd1\x2a\xfe\xd3\x4a\x5a\x4c\x59\x83\xdb\x13\xe0\xfd"
-  "\x37\xd3\xa2\xa0\x43\xb0\x3c\x55\x63\xeb\x5f\x3f\x51\x74\xb1\x9a"
-  "\x94\x2f\x63\xdb\x2f\x59\x27\xde\x24\xbf\x53\xf5\xaf\x18\xff\xfb"
-  "\x73\x86\xe4\x74\x6b\x50\xd3\x45\x78\x3d\x72\xed\x71\x3c\xab\x33"
-  "\xf6\x07\x93\xa2\xf7\x5c\x3f\xe8\x25\xfa\xa3\x4d\xfd\xb8\xcc\x1f"
-  "\xb3\xd4\x8f\xef\x23\x7f\x6d\xb5\xea\x17\x9b\xfe\xf7\xfe\xf4\xfa"
-  "\xff\xab\xe5\x3f\x3e\x70\xf1\xdf\x37\xa9\x5f\xb6\xfb\xff\x61\xfb"
-  "\xff\x9e\xf2\x1f\x1f\xbc\xd8\x8f\xf9\x0d\xbc\x75\xf4\x95\xff\x20"
-  "\x13\xf8\xb3\x16\xf6\xb5\xd1\xf1\x19\x59\xcb\x83\xa2\xdb\xf1\x18"
-  "\x4d\xac\xf8\x82\xf8\x3b\x41\x3d\x65\x76\xd1\x5d\x71\x9e\xf5\x9e"
-  "\x8f\x77\x80\x7f\x9b\x77\x1e\xa7\xa4\x1d\xc7\xc9\xd2\x51\xc6\xdf"
-  "\x0b\xe4\xf8\x34\x90\x33\xc0\xd4\x8d\xe7\xb6\x35\x01\xfa\x93\xf7"
-  "\xff\xb0\xf7\xf5\x71\x51\x55\xeb\xfe\x6b\x86\x11\xc9\x50\x06\x43"
-  "\x42\xa3\x1a\x0b\x3b\xa3\xa2\xd1\x3d\xd5\xcf\x3a\x7a\x0e\xbe\x75"
-  "\xad\xe3\x5b\x1d\xed\x4c\xe5\x0b\x96\x16\x7a\x7c\x19\x11\x09\x11"
-  "\x01\xd1\xb8\x76\x52\x44\x43\x2f\x16\x22\x9e\x8b\x5d\x2c\x5f\x38"
-  "\xf7\xd8\xbd\x58\x66\x63\x62\x07\x15\x18\xea\x60\x8d\x86\x39\x12"
-  "\x10\x11\xda\xf0\xa2\x0c\x30\xb3\xf7\xef\x79\xd6\xda\x7b\xf6\xec"
-  "\x61\x06\x18\xd2\xac\x7b\xcf\x1f\xf3\xd9\xb3\xd7\x5e\x7b\xed\xb5"
-  "\xd7\xb3\xd6\x77\x7d\x9f\x67\xaf\xf5\x3c\x8d\xb8\x4e\xc1\x50\x06"
-  "\x6c\xb2\xb4\x12\x63\x2d\xf2\x45\xfe\x51\x24\x28\x3b\x98\x3f\xc6"
-  "\xa7\xbe\x1c\xcb\x2b\x5f\x5e\x08\x69\x15\x87\xb9\xc8\x3e\x87\x13"
-  "\x8a\xfb\x60\x4c\xa5\x2a\x72\x7c\x9b\xd0\x37\xed\x6c\x1f\x43\x11"
-  "\xe5\xe7\x30\x4e\x2a\x98\x1f\xc4\x53\x6b\xd8\x7c\x7e\xea\x49\xc1"
-  "\x7e\x01\xff\x8b\xa8\xad\x0d\xde\xa3\x10\xe3\xaa\x61\x99\x87\xb8"
-  "\x42\x1a\x57\xed\x70\x42\x64\x9f\xc4\x05\x44\x59\x66\xae\x27\x27"
-  "\x01\x07\x31\x46\x17\x8c\xbb\x03\x30\xce\x0a\x76\x07\xf3\x19\x50"
-  "\xbf\xcd\x39\xc1\xfc\x26\xa8\x53\x7e\x6b\xea\xc7\xc0\x83\x0a\x5b"
-  "\x04\xfb\xaa\x01\xc6\xc5\x81\x2d\x90\x67\xc6\x6a\x72\xef\x16\xc8"
-  "\x97\x0e\xf9\x90\x8b\xb1\xfa\x7d\x72\x0a\xda\xe0\x08\x3c\xb3\x5c"
-  "\x33\x0f\xcf\x0d\xd4\x0e\x85\xcf\x86\xf7\xd0\x54\x11\xc3\x4c\x98"
-  "\xdb\x54\xf8\x0c\xf1\xb9\x50\x3e\xe0\xdf\xd1\x03\xd4\x26\x0e\xe9"
-  "\xac\x9c\x8f\x59\x4c\xf7\x8c\xb0\xba\xad\x8e\xb8\x77\x61\x75\x5b"
-  "\x12\x60\x4e\x6f\xa7\xbe\xda\x32\x51\x7f\x47\x8e\x41\x79\x05\xe8"
-  "\xf1\x4c\xdf\x04\x6e\x11\x0d\x38\x00\x7c\x82\xae\xbf\x04\x2e\x01"
-  "\x75\xc9\xc4\xd8\x73\x78\x1d\xf4\x80\x23\x30\x2f\x17\x20\x0f\x98"
-  "\x77\xed\x29\x82\x7b\xb7\x80\x0f\xa8\x56\xcd\xe1\xad\xcc\x47\xfe"
-  "\xc7\x0d\x22\x17\x40\x0c\xc2\xf9\x7f\x0b\xe8\xf4\x1d\x20\x43\xe8"
-  "\x03\xc5\xc0\x2d\x02\x61\x96\xd4\x0a\x6d\x5f\x4c\xe7\xfc\x38\xea"
-  "\x5b\xd4\x87\x61\xb4\xe1\x11\x78\x3f\x7f\x78\x46\xb1\x99\x94\x52"
-  "\x9c\x60\x18\x63\x98\x24\xce\xe3\xa8\x43\x99\xa1\x0c\x1e\xb0\x4c"
-  "\xb8\x06\xef\xff\x3f\x21\xe2\x33\xcd\xe4\xe3\x16\xa1\xcd\x4a\xa0"
-  "\xcd\xb0\x4c\xba\x9f\x16\x38\x97\x9e\xb5\x8d\x01\xf9\x41\x90\x70"
-  "\x6f\xb6\x58\x2e\xea\x79\x1c\xf0\x0a\x6c\x2f\x6c\x27\x78\x06\x11"
-  "\x70\xac\x82\xf1\x97\x4f\x0e\x0a\xdf\xd1\x32\x40\xd6\x1b\xa5\xf6"
-  "\x37\x98\x9d\xdb\x1f\xee\xdf\x28\xc8\xf2\x39\x27\xd9\x01\xff\xfe"
-  "\x24\x02\xed\x6e\x50\xc7\x63\xcc\x66\x70\x62\x30\xfa\xf7\x41\x1f"
-  "\xa2\xd0\xc6\xc7\x36\xa3\xbf\x4a\xc0\xe6\x0d\x5f\x13\x21\xe6\xe1"
-  "\x27\x83\x19\x3f\x3d\x51\xc8\xe2\x82\x9d\xa0\xb6\xba\x6a\xa8\x17"
-  "\x8b\x09\x76\x42\x88\x09\x76\x62\xbd\x73\x9c\x43\x29\xc6\xe1\x89"
-  "\x78\x69\x0d\xb4\x21\x8f\xe9\x63\x86\x3c\xb4\xa9\xd0\xfc\x1d\xd1"
-  "\x58\xb7\x4a\x1c\x97\xe2\xbb\x62\xbc\x43\x48\x47\x5b\x5f\x25\xca"
-  "\x4d\x4c\x47\x5f\x97\x20\x27\x7f\xa8\x53\xa0\x50\xa7\x06\x38\xf7"
-  "\x83\x67\x53\x9b\x14\xc6\x3e\xdc\x8a\xf7\x24\x49\xf7\xe0\xb8\x81"
-  "\x3e\x1c\x00\xf7\xdc\x06\x47\x5e\xcc\xcb\x62\x22\x9e\xc8\x78\xb3"
-  "\x1d\x6d\x2a\x27\xf2\xc5\x98\x88\x18\x0f\x11\x31\x63\xcb\x3c\x59"
-  "\xdb\x63\xdb\x1c\x00\x59\xd1\x7e\x77\xd2\x56\x08\xed\xfd\x09\xf0"
-  "\xff\x83\x91\xec\xbd\x4e\x64\x08\xf5\x33\x30\xdf\xe9\x1f\x14\xe7"
-  "\x6c\x17\xf7\x72\x7f\x12\xef\xf8\xce\xe7\xe0\x96\x27\x32\xb0\x4f"
-  "\x42\x59\x25\x28\x7f\xe4\x89\x90\x2f\xd7\xd1\xb7\xe8\x7e\xc5\x4f"
-  "\xd0\x8f\x92\x5e\xa8\x3f\xf6\x17\x85\xd0\x76\xc5\xce\xe3\xce\x79"
-  "\x9c\x43\x19\xd5\x30\xc6\x1d\x7d\x40\x1c\xd7\x02\xe6\x0c\x16\x38"
-  "\x45\x3c\xfa\x9a\x84\x72\x0d\xc8\xc1\xd9\xbc\x7a\xb2\xe1\x64\xa5"
-  "\x0d\x6d\xb2\x15\x70\x0e\xe3\xfb\x64\x71\xf3\xc0\x51\xd6\x8d\x14"
-  "\x37\x4e\x82\xfe\x33\x9c\xda\x8f\xb1\x5d\xc4\xf1\xba\x15\xda\x07"
-  "\xe3\x09\xd2\x31\x1b\x5f\x4d\xca\xac\x0d\x44\x58\x5f\x0c\x63\xb6"
-  "\x06\xbf\x91\xd4\x43\x1f\xf2\xc3\xf1\x0b\xf2\x3d\x80\x7e\x51\xa1"
-  "\x1d\xcb\x37\xee\xa4\xe3\xd6\x1f\xc7\x6d\x07\xee\x41\x87\xe7\x14"
-  "\x45\x45\x92\x93\xf1\x06\x3a\x8e\xd1\xb7\xc0\xdb\xd0\x76\x18\x7f"
-  "\x10\x9e\x7d\x44\x5c\x17\x89\x7d\x04\x7d\x09\xb0\x7e\xf2\xb1\x0d"
-  "\xc7\xb2\xd0\x76\x2a\xc8\x57\x29\x8e\x3d\x49\xfe\x2c\x8f\xcb\x78"
-  "\x0b\x60\xe3\xad\xc8\x5f\x6c\x6b\x1b\x1d\xc7\x27\xf2\x6d\x30\x8e"
-  "\x9d\xdb\x14\xdb\x13\xdb\x15\xf2\xc2\xfb\x1f\x9d\x29\xb6\xa9\x53"
-  "\x7b\xee\x17\x64\x5e\xce\x6c\x16\x45\x4b\x05\x7b\x86\xa3\x0d\x85"
-  "\xfe\x57\x81\x63\x6a\x03\xbe\x3b\xcc\x0d\xf8\x7c\xec\x23\x6f\x0b"
-  "\x98\x55\x64\xc1\x3e\x52\x04\xe3\x7f\xaa\x49\xc2\x8e\x13\x07\xa8"
-  "\xce\x02\x72\x62\xf2\x29\x3a\x47\xf7\xeb\xbb\xc1\x0e\xe8\x27\x99"
-  "\x12\x3e\x15\x55\x8b\xed\x20\xf6\x49\x71\xdc\xc3\x9c\xf2\x90\x1c"
-  "\x7f\x4e\x0d\x82\x32\x06\x22\xbe\x49\x1c\xea\x54\x98\x1c\xdf\x4e"
-  "\xf9\x23\xbe\x61\xbf\xd6\xc7\xa1\xcd\x86\xcd\x57\x66\x72\xfc\x88"
-  "\x1c\x93\x8e\xef\x67\xdf\x00\x19\xe7\xc2\xbe\xa5\x9f\xc7\xf2\xe3"
-  "\x1c\x06\xf9\xe9\xba\x64\x61\xce\x43\xff\x57\x98\x96\x2b\xb4\x57"
-  "\x25\xe4\x2f\xc2\xbd\x5a\xb8\xd7\xfb\xf6\x4a\xa6\xeb\x01\x4e\x1f"
-  "\x43\x3f\xb3\x90\x2f\xaa\x0c\x78\x7e\x47\x1a\xc3\x6e\x11\x2b\xf8"
-  "\x97\x74\xb7\xbf\x5a\x47\x6e\xd3\xff\x96\xff\xa6\x96\x7c\x3a\x1e"
-  "\xc6\x8c\x15\xfd\x9e\x41\xd9\x9a\x5a\x72\xfa\x36\x78\x6e\x90\x70"
-  "\x0c\xa9\x25\xc5\x8d\x70\x1c\x0c\xc7\xf3\x70\xbc\x0b\x8e\x27\x20"
-  "\x3f\x27\xe4\x8f\x80\xf3\xfd\x90\xfe\x6b\xe1\x08\x75\xfc\x74\x0c"
-  "\x1c\x67\x0a\xdc\x11\xd3\xd7\xe1\x39\x1c\x97\x09\x32\x2f\x61\x32"
-  "\xff\x14\xd7\x5c\xc5\x43\xfd\x4d\xc6\x4a\x5a\x96\x1e\xf2\x8c\xc2"
-  "\xb2\x71\x0f\x65\x2d\xf9\xfb\x65\x27\x0e\x0a\xe5\xfc\xbd\x3f\x1c"
-  "\x1f\x86\xfb\x3e\x83\x63\x2c\x1c\xf7\x09\x6d\x50\x8e\xd8\xb0\x30"
-  "\x1e\xdb\xb6\xc8\xa0\x61\x7c\x77\xa6\x38\xe6\x71\x1e\x96\xb0\xc3"
-  "\x40\x16\xce\x61\xf2\x86\xbc\xb4\x1f\x40\xde\xf1\x98\x17\x8e\x13"
-  "\x85\x63\xa4\x70\x9c\x2c\x1c\xff\x55\x38\x4e\x12\x8e\x53\xcc\xe4"
-  "\xd3\x7c\x81\x63\x40\xbb\x7c\x9a\x4f\xd7\x37\x64\x84\xe5\xb2\x67"
-  "\xfc\xbd\x18\x75\x64\xc0\x71\x9c\x07\x7d\x5a\x53\xff\x3e\x56\xb4"
-  "\xb7\xa1\x9d\xb6\x23\xf5\x83\x6f\xde\xa6\x7e\x1b\xfe\x3e\xcb\x09"
-  "\xdb\x22\xfd\x15\x91\x04\x38\xd0\xa0\x6c\x25\xcc\xff\xac\x1c\xec"
-  "\xc7\xf4\x1b\xa2\xe0\xc3\xda\x07\x7d\x45\x51\x7d\x28\x30\x07\x75"
-  "\xf2\x4a\x6a\x8b\x44\x1f\x49\x81\x23\x26\xc1\x6f\x26\xe8\x06\xb3"
-  "\x44\xfc\x46\xbd\x47\xf0\x75\x15\x0c\xcf\x32\x48\xba\xfa\xdf\xf5"
-  "\xec\x9b\xcc\x20\x18\xfb\x7f\x37\x39\xa5\x87\x63\x9d\xa1\x3d\x4d"
-  "\xf0\x3e\x0f\x57\x91\x62\x6c\xc7\x7f\xa9\x66\xef\x1c\x21\xbe\xb3"
-  "\x20\x0f\xbd\xd8\xbe\xd5\xe4\xd3\x02\xc0\xc2\x18\xec\xc3\x55\x0e"
-  "\x9c\xfd\x94\xee\x41\x12\xfa\x08\xc8\xf2\xd3\xc5\x28\x53\x69\xfc"
-  "\xc8\x30\x28\xa8\x35\xb5\x38\x4a\x8e\x29\x86\x28\xc4\x14\xec\x1b"
-  "\x80\xdf\x28\xeb\x48\x97\xf1\xe7\x8f\xe3\x8f\x8d\xbb\xe2\x6c\xf9"
-  "\xbd\xa7\xfc\x6d\x6c\xdc\x99\xa0\x9f\x41\xff\xfc\x14\xfd\xf4\xc1"
-  "\x3c\x55\x9c\x28\x8c\x69\x13\x8c\xe9\x47\x20\xdd\x8f\xd5\x95\xa5"
-  "\x0b\xcf\x82\x7e\xf6\x29\xbe\xf7\x5d\x62\xba\xf0\xbe\x50\xce\x29"
-  "\x2b\xca\x5b\x4c\x17\xca\x87\xfe\x78\x0a\xf7\x05\x87\x88\xe9\xc2"
-  "\x3b\x01\x8f\x3a\xfd\xb0\x88\x27\x9b\x69\x7f\x3b\x79\x4c\xbc\x0f"
-  "\xe5\x86\x7e\x6d\x98\xcd\xf8\xb4\x06\xc6\x6a\x2e\xce\x0f\x1b\xe6"
-  "\x11\xff\x57\xb3\x48\x7f\x36\x2e\x4f\x6b\xe4\x18\x79\xf6\x28\x9f"
-  "\x1a\x60\xe3\xd5\x23\xc6\x96\xda\x1e\x16\xf9\x6a\x36\x3c\x27\x5b"
-  "\x8c\xbf\x29\xf9\xc3\x3e\xfd\x19\xc6\x2d\x77\xaa\x8b\x41\xac\x8b"
-  "\x34\x3f\x33\x19\x60\xdd\xb0\xac\x0d\xc0\xd7\x5b\x00\x17\x18\x6e"
-  "\x9f\xb6\x88\x71\x89\xd3\x85\x79\x8b\xc6\xc6\x8d\x63\xb1\x71\x71"
-  "\x6e\xc4\x6f\xf9\x1c\xda\xb1\xe2\xed\xa4\x4c\x0f\xba\x7c\x7c\x0d"
-  "\x99\xbf\xa6\x1f\xfa\x8e\xd0\x41\x5d\x77\x43\xdd\xf2\x84\x36\x82"
-  "\x71\x73\x76\xbd\xd0\x96\x88\x57\x79\x88\xe1\x1b\x92\x58\x2c\x0b"
-  "\xb4\xdd\xe0\x78\x78\x13\xe7\xad\x10\xde\x5a\x94\x8d\x63\xe3\x8c"
-  "\x5e\xe4\xa0\x50\xbf\x5c\xc6\x01\x4f\x5e\xa4\xbe\x4c\x32\x46\x8c"
-  "\x65\xb6\xbf\xb3\x81\xec\x5d\xcf\x58\xd9\x77\xd2\x11\x42\xac\xa1"
-  "\x33\xd5\x3e\x21\x41\x31\x6c\xbd\xc5\x07\x5c\x0e\x1d\x6b\x67\x0c"
-  "\x2e\xfe\xa2\x94\x90\x56\x21\xfa\xbb\x94\xf8\x22\x6b\x13\xb8\x66"
-  "\x91\xc6\xc5\x99\x03\x58\x16\x94\xb9\xae\x35\xf5\xac\x9f\x94\x7e"
-  "\xb2\x52\xb0\x79\x45\x0e\x58\x1f\x89\xeb\x48\x06\xa1\x8f\x58\x56"
-  "\x87\xb3\xd1\xb4\x4e\xd4\xee\x31\x22\x52\x1c\xc3\xd8\xd6\x38\x6f"
-  "\xd3\x71\x0c\x63\x18\xc7\x72\xc7\xb6\x11\x93\xe0\xc7\xc6\x2e\x9b"
-  "\x9f\xad\x74\xec\xd2\x71\x7b\x36\x5e\x7a\xde\xd9\x08\x6a\xfb\x42"
-  "\x99\xae\x0d\xf1\x87\x6b\x99\x66\xf2\x81\x9f\x50\xc7\xb1\x42\x5d"
-  "\xc6\xc2\xf5\x6c\xb6\x56\xe3\xcc\x28\xc6\x85\xce\x84\x63\xff\x32"
-  "\x42\x9f\x81\x63\x16\x8b\x1b\x78\xb6\x5c\xec\x33\x30\x9e\x16\xd6"
-  "\x92\x92\x05\x99\xc1\x7c\x16\xc8\x26\x0b\xc6\xc0\x52\x38\x9f\x06"
-  "\xc7\x85\xec\xa8\x50\xe3\x51\xe8\xdb\x59\xad\xa9\x25\xfe\x62\x7c"
-  "\x57\x7c\x9f\x96\xc0\xd7\xd0\x67\x69\x62\x3a\xd4\x1d\xfb\x08\xfd"
-  "\x9e\xa8\x67\x71\x93\xb1\x7f\x60\xdf\x08\x58\xff\x14\xed\x1f\x74"
-  "\xaf\x32\xa4\xd3\x3a\x41\xff\x80\xb2\x74\xa2\xaf\x49\x78\x3f\x1b"
-  "\xb3\xeb\x97\x2c\x75\x5e\xdb\x06\x65\x6a\x8a\x34\xa0\xd7\x64\x0c"
-  "\x1a\x13\x3b\x94\x0c\x2a\xd2\x50\x9f\x72\x97\x8c\xb6\xc9\x04\xef"
-  "\xc1\xef\x32\x0c\xe7\x06\xfd\x11\xee\xcd\x97\xda\xcb\x40\xbf\x55"
-  "\x9c\x9c\x43\x6d\x89\x77\xc0\xb5\x22\x67\x3d\xc1\x4c\x3e\x2c\x47"
-  "\x5d\x01\xd7\xe0\xdc\x1f\x44\x34\xd0\x0f\x01\x87\x4a\xea\x44\x5e"
-  "\xfa\x60\x10\x7e\xdf\xfd\x10\xf7\x42\xa2\x0e\x0c\xed\xf5\x61\x34"
-  "\xe8\x82\x6e\xd7\x27\x42\xff\x78\x18\x6d\x35\x42\x1c\x88\x4a\xb4"
-  "\x43\xa1\xdf\xec\x5a\x52\xbe\xa6\x14\xfd\x08\xac\xe8\xec\x5b\x34"
-  "\x29\x9e\xbf\x86\xfe\x45\x35\x31\xe4\x8e\x2a\x52\x3e\x07\xed\x3e"
-  "\xc9\x8d\x68\x63\x29\xd5\xcb\x6d\x2c\xa5\x06\xe1\x57\x41\x48\xd9"
-  "\x18\xa7\x5f\xb1\x70\x9c\xd4\xcd\xcf\x2c\xe4\x05\x0d\xbc\xcc\x2a"
-  "\xb4\xd5\xbf\xb7\xa6\x96\x3a\xfc\x1f\x62\x9f\xc2\xb1\x8a\xdf\xf5"
-  "\xd1\x66\xa4\xb0\x11\xf4\x5b\x00\xf2\x82\x7a\x6f\x18\xf1\x8c\x21"
-  "\x01\xfb\x53\x59\x1f\xca\xfd\x95\xde\xee\xab\x2a\xa3\xdf\xc1\x98"
-  "\x8f\xbd\xd2\x62\x78\xf6\x7f\x62\x6c\x78\x7d\x0c\xb9\x1b\xed\xd7"
-  "\x01\x76\xde\x80\x3a\x2a\xf6\x8d\x3d\x34\xfe\x42\xd9\xe9\xd8\x75"
-  "\x44\x09\xd7\xef\x85\xff\x85\x22\xcf\x81\x7b\xd4\x3e\x56\x12\x84"
-  "\xfc\x66\xe2\x3a\x72\x6f\x6b\x6a\x59\xa6\x28\x2b\xe4\x00\x68\x47"
-  "\x13\x6c\x01\x50\xd7\x52\xfa\xed\x0c\x7d\x23\x9b\x69\xbb\x51\x1c"
-  "\xc5\x32\xa0\xef\x96\xa5\xf8\xb4\x10\x35\x9b\x3b\xca\x60\xfe\xfb"
-  "\x50\xe0\x7c\x65\xd9\x30\x06\x2a\x9c\xea\x79\x5e\xfa\x1f\x3c\x18"
-  "\xef\x0f\x68\x41\x7e\xe5\xa9\x7d\x8c\xc3\xc4\xf6\xc1\x75\x65\x01"
-  "\xc0\xf3\xa9\xbc\x6d\x7c\x03\xd4\xad\x44\x9f\x40\xfc\xea\x49\xf9"
-  "\xb0\x3d\x3b\xe9\x7e\x97\x62\x66\x5f\x2f\x1f\x2c\xea\xd1\xac\xde"
-  "\xc6\x9a\x80\xf5\x3e\x34\xa6\x36\xc6\xf8\xa4\x71\xb4\x7f\x08\xa1"
-  "\xdc\xdb\x68\x1b\x4b\x0c\x49\x8f\x63\x9e\x73\x22\x96\x36\x27\x87"
-  "\x90\x93\x21\x63\x61\x3c\x1b\x73\x61\xcc\x94\x78\xbf\xf6\xc9\x28"
-  "\xd8\xed\xd9\x1e\x29\x3c\xc7\xfd\x4c\xd4\xbf\x3c\xfd\x4e\x6a\x5c"
-  "\x89\x73\xc3\x46\x21\x3e\x33\xce\xb9\xad\xa9\xe5\x0e\xfe\xcf\xe2"
-  "\x52\x1b\xf5\xac\x0c\xfc\x3e\x68\x5c\x8a\xfb\xc8\xa9\x1e\xc0\xf2"
-  "\xfb\x33\x1b\x7e\xb9\xc3\xfe\x8f\xf9\xf0\x3e\xb6\x3e\xc9\x38\x69"
-  "\xbe\x5d\x01\x6d\x6c\x9c\x84\xef\xca\xfa\x66\x30\xc8\xb6\x5c\x2f"
-  "\x8d\xe3\x32\xba\x4e\xe8\x64\x83\xf3\x38\x2d\xcf\x90\xf4\xc7\xd2"
-  "\x87\x47\x65\x12\x8d\xbb\x71\xa9\x1f\x40\xd4\xdf\xfb\x91\x3f\x6c"
-  "\xdd\xca\xe7\x66\x28\xb9\x09\x1b\xd2\x89\xbf\x62\x33\x34\x23\x8e"
-  "\xbb\xb8\xa8\x41\xb5\xe4\xb3\xc0\x00\xff\x3b\x67\x4e\x8c\xed\xcb"
-  "\x27\x85\x10\xe5\x96\xa6\xbe\x7e\x43\xad\x77\xe6\xf2\x3e\x23\x9e"
-  "\x99\x16\x6b\x25\x9a\x25\x19\xe4\xdb\xa5\xc4\x67\x22\x30\xf7\xfb"
-  "\xfd\x09\xd4\xe9\x1f\xa1\xb8\xef\xec\xa4\x3f\xf2\x89\x7f\x84\x62"
-  "\x99\x89\xd9\xc4\x2f\xb1\x9a\xaf\xdb\xfc\x72\x1f\x3f\xc0\x76\xf5"
-  "\xdb\xd0\xe7\x6e\xf7\xbf\x33\xb7\x03\xca\x38\x11\x45\xef\x73\xbb"
-  "\xcf\xa5\xeb\xba\xe9\x83\xa1\x6e\x07\xbd\xab\x5b\xc5\x31\xa9\x6e"
-  "\x15\xc7\x6e\x70\xdd\xd4\x52\xdd\xa2\xa1\x6e\x9f\x3f\xe9\x5d\xdd"
-  "\xbe\x98\x23\xd5\xed\x8b\x39\x3d\xac\xdb\x01\xef\xeb\x16\x7f\x27"
-  "\xd4\xad\xc6\xbb\xba\x7d\x69\x93\xea\xf6\xa5\xed\xc7\xd4\x0d\x75"
-  "\xf3\xa4\x50\xbe\x86\xfa\x3a\x8e\x21\xfe\xb8\xb6\xab\x96\x54\x4c"
-  "\x4e\xca\xa6\xe7\x03\xe1\xbf\x42\x18\xef\x96\xe4\x16\xfe\x1b\xc6"
-  "\x63\xfe\xb1\x6c\xb4\x1e\xd7\x34\xff\x63\x21\xf4\x65\x7f\xd6\xa7"
-  "\x2b\x28\xd7\x4e\xb6\xf0\xc2\x5a\xc3\x7f\x6c\xc9\xa1\xeb\x15\x46"
-  "\x0b\x3a\xc6\x3f\xca\x9b\x07\x8e\x88\xc7\xb5\x02\x1c\x8c\x6f\x7e"
-  "\xe0\x88\x8d\x18\xd7\xed\x70\x8c\x45\xc9\xa7\xa2\x1f\x22\xf4\x95"
-  "\xa4\x22\xfc\xf6\x11\x99\x87\x63\xac\x4a\xf4\x1b\xb0\x81\xee\xc3"
-  "\xfb\x47\xb1\xb8\xc7\x44\x7c\x86\x25\x70\x74\x2e\xa4\x9b\xcd\x42"
-  "\xac\x45\x5e\x89\xdc\x64\x44\x22\x96\x0f\xe9\x56\x31\x1e\x22\xf4"
-  "\x77\x31\x26\x4b\x4b\x80\xb5\x2b\x1c\xac\x18\x25\xe2\xe0\xc4\x58"
-  "\x12\x80\xf1\xd0\xb6\x26\xf5\x45\x7d\x05\x38\xd5\x3f\x8e\x61\xbb"
-  "\xcf\x68\xe9\xcb\x07\x24\x12\x1f\xdc\x5b\x83\x6b\xb8\x8c\x21\x16"
-  "\x12\x96\x48\xfa\xcc\x88\x87\x32\xad\x24\x2a\x20\x1e\xca\x83\xb6"
-  "\x66\x5c\xbf\x82\xee\x83\xcb\x84\xf2\x70\x6d\xab\x4f\x2c\xf1\x9f"
-  "\x18\x92\xcc\x6f\xd8\x45\x54\xb8\x0f\x07\xf7\xd3\xb0\xbd\x34\xbe"
-  "\x7e\xad\xa9\x15\xf9\xe2\xfb\xf5\x40\x3e\x03\x98\x7c\xce\xd5\x48"
-  "\xf2\x39\xb7\xb7\xb3\x7c\xce\xf5\x67\xf2\x39\xa7\x92\xe4\xf3\xc5"
-  "\x14\xb9\x7c\xce\x8d\x92\xcb\xe7\x9c\xbe\x77\xf2\x39\x17\x2d\xc9"
-  "\x87\x3d\x83\xc9\xe7\x5c\x8a\x7b\xf9\x9c\xcb\x92\xe4\x73\x2e\xbc"
-  "\x67\xf2\x39\x57\xea\x59\x3e\xe7\xe6\x74\x21\x1f\x5f\xf7\xf2\xf9"
-  "\xe2\xee\x9e\xcb\xe7\x8b\x29\x5e\xc8\xa7\x3f\x93\xcf\x97\xaf\x49"
-  "\xf2\xf9\x72\x7c\x67\xf9\x7c\x71\x90\xc9\xe7\x8b\x3c\x49\x3e\x5f"
-  "\xd6\xc9\xe5\xf3\x45\xa9\x5c\x3e\x5f\xaa\x7b\x27\x9f\x2f\xfd\x24"
-  "\xf9\xb0\x67\x30\xf9\x7c\xa9\x71\x2f\x9f\x2f\xc7\x48\xf2\xf9\xa2"
-  "\xa4\x67\xf2\xf9\x72\x99\x67\xf9\x7c\x61\xf3\x5e\x3e\x5f\x7e\xe4"
-  "\x22\x1f\xb5\x67\xf9\x7c\x59\xe7\x85\x7c\x02\x98\x7c\xce\x0f\x93"
-  "\xe4\x63\xba\xdc\x59\x3e\xa6\x69\x4c\x3e\xa6\x49\x92\x7c\xce\x6f"
-  "\x92\xcb\xc7\xb4\x4c\x2e\x1f\x53\x41\xef\xe4\x63\xca\x97\xe4\xc3"
-  "\x9e\xc1\xe4\x63\x32\xb8\x97\x8f\xc9\x24\xc9\xc7\xb4\xb4\x67\xf2"
-  "\x39\xdf\xdf\xb3\x7c\x4c\xd9\x5d\xc8\xa7\xaf\x7b\xf9\x9c\x9f\xdb"
-  "\x73\xf9\x9c\xdf\xd4\x95\x7c\xbc\xe3\x7e\xe7\x29\xaf\xba\x01\xe5"
-  "\x54\x7b\x2a\x07\xdb\x0e\xd7\xa7\x71\xa9\xe7\xab\x73\x38\x5f\x1a"
-  "\x4b\x0a\xfe\x67\x6b\x12\xc8\xef\xaa\xc8\x85\x87\x72\xb8\x3e\x7e"
-  "\x7c\x6a\x4e\x14\x97\x9a\xab\xe1\xd7\xfb\xaa\xb8\xf5\x7d\x55\xb8"
-  "\x37\xd2\x5d\x59\x6c\xbd\xe4\x85\x6d\x3e\x83\xc9\x3d\xb8\xdf\x65"
-  "\x03\xf0\x67\xfc\xdf\x9a\x7a\x21\x1b\xb8\xa0\xb6\xab\x7d\x17\xb8"
-  "\x76\xe9\xe4\x46\xd4\x7b\x2f\x14\x3b\xf6\xab\xa7\xf2\xf1\xe8\xa3"
-  "\x48\x7f\x1f\xae\xb1\xbf\x60\xc9\xa4\x3e\x6f\x86\x69\x22\xef\xe3"
-  "\x2f\xa1\x2e\x52\x4b\xbe\xba\xc2\x6f\x1b\xa6\xc1\xfe\x00\xdc\xfd"
-  "\x8e\x7a\xf2\xd5\x18\xc7\x9a\x2e\x5e\xf7\x96\x60\xf3\x2b\x61\x79"
-  "\x2f\xce\xe5\xb7\x85\x95\x60\xfc\xbb\x55\x49\x18\xd7\xed\xe2\x64"
-  "\xe0\xbe\x0f\xe0\x33\xd0\xff\xca\x1e\x38\xe2\xba\x17\xb6\x76\xef"
-  "\x2b\xea\x37\x0b\x7d\xbc\xb1\x35\xfd\x17\x47\x89\xfd\x0e\x9e\xd3"
-  "\x0f\xce\x07\x09\xfc\x1e\xf3\xdf\x5e\x4f\x2a\xed\x4e\xd7\xfd\xe1"
-  "\xfc\x32\x94\x1d\x28\x5c\xef\x0f\xe7\xa7\x90\x67\xd3\xfd\xf7\xe9"
-  "\x29\xc2\x1a\xd3\xca\x7c\x48\x53\x0b\x79\x02\x21\xcf\x16\xe4\xee"
-  "\x42\x19\x03\xe1\x7c\x25\xea\xc4\xc2\xf5\x20\x38\x9f\x8d\xdf\x02"
-  "\x84\xeb\x83\xe0\x1c\xe3\x87\xfe\x8a\xed\x77\xe8\x10\xc6\x68\xa5"
-  "\xaa\x77\x7b\x36\x2b\xa9\xfe\xc7\xe2\xb4\xa3\x2e\x50\x39\x55\x5a"
-  "\xcf\xf3\x55\x83\xcb\xb5\x68\xa7\x6b\x95\xe2\x35\xb6\xe6\xac\x72"
-  "\xa3\xd3\xb5\x12\x97\x6b\xb9\x4e\xd7\x8e\xb9\x94\x79\xcc\xe9\xda"
-  "\x01\x97\xfb\x4c\x4e\xd7\xb2\x5c\xae\xb5\x38\x5d\xdb\x24\x5c\xf3"
-  "\x69\x4d\xbd\xe8\x2f\x7d\x93\xfb\x2a\x5e\x48\x57\x42\xba\x53\xfc"
-  "\x83\xaf\xa2\x85\x74\x78\xfe\xc5\xb1\x66\x92\x71\x44\x48\xa7\xb2"
-  "\x67\xe5\x5f\x9c\xe5\x54\xfe\x18\x66\xfb\xb8\x18\xed\x58\x0b\x37"
-  "\x70\x44\x39\xd7\xa1\x7b\x0b\xae\x69\xb0\x5f\x39\xf7\xed\xe5\x71"
-  "\x9a\x17\x57\xbf\xa2\x89\x59\x14\x8b\xcb\x51\x96\x2d\x8e\xd5\x2c"
-  "\x5b\xb1\x70\x91\xcc\xef\x72\x10\xfa\x2d\xc3\xb8\x3e\xe8\x53\x41"
-  "\xf0\x11\x5e\xe7\xf0\x8d\x0f\xb8\x0a\xcf\x02\xfd\xff\x77\xd4\x07"
-  "\x7b\x26\xf3\x4f\x5c\x8c\x3e\x19\x98\xff\x05\xf2\x54\x15\xb9\x78"
-  "\x5e\xf0\xbf\x60\x68\x4d\xfd\x9a\x78\xf6\xbf\x70\xa9\x92\xfa\x48"
-  "\x83\x7c\xcc\xff\xc2\x25\x33\x8c\xf3\x89\x7c\x3f\xe6\x27\x9f\xc5"
-  "\xd7\xf9\x5a\xe4\x26\x96\xf9\x6d\xd4\xcf\x58\x0a\xb3\x6d\xb8\xfa"
-  "\x7e\x1c\x46\xf0\x3e\xe1\xfb\xa7\xf3\xfd\x4b\xd9\x75\x71\x7e\x10"
-  "\x9e\x99\x31\x0c\x7d\x9e\xf4\xab\x82\x73\x6a\x8f\xa7\xd7\xbe\x66"
-  "\x7e\x5c\xb6\x0d\xc3\xfd\x3b\xc5\xf8\xde\xf2\x77\x53\xfe\xb1\x8a"
-  "\x7c\xfd\xbe\xd3\xbb\x55\x3a\xf9\x93\x12\xdf\x81\xf9\xec\xea\xfc"
-  "\xae\x74\xbf\x0e\xaf\x1e\x86\xeb\x8d\xa8\x6f\x4b\xb6\xd6\x1d\xce"
-  "\xb7\x0d\x53\x89\xf5\x71\xaa\x9f\x1f\xea\xf9\x50\xbf\xcb\xb4\x4d"
-  "\x40\xa6\x3c\xc8\x54\x78\x87\xbd\x7c\xea\xc5\x8d\x74\xed\x36\xee"
-  "\xdd\xc3\xd8\x05\x74\xae\xba\xb4\x54\xb4\x55\xe2\x1c\xc5\x7c\x61"
-  "\x5f\x92\xf8\x1f\xfa\xf9\xd9\x26\xce\x5f\x97\x9c\xf8\x1f\x7b\x26"
-  "\xa4\x1d\x70\xee\x43\x4e\xcf\x3b\x8f\xcf\x83\x7c\xb3\xd8\x7a\xf1"
-  "\x61\x74\xbc\xc3\x39\xf5\x23\x8a\xf7\x62\x1d\x3d\xc5\x82\xf2\xe4"
-  "\x87\x4d\x6a\x47\x73\x98\xd8\x8e\x99\x34\x56\x89\xf9\x61\xd1\x8e"
-  "\x47\xf7\xab\x40\x1e\x1c\x5b\x88\x4f\xbc\xfa\xdf\x72\x8b\x34\xd7"
-  "\xa0\x4e\xe6\x68\x86\xbb\x39\xf1\x0f\xfa\x93\x28\xd6\xc6\xe6\x95"
-  "\x88\xf5\x38\x76\x18\xe6\x9b\xcb\x05\xd9\xc7\xb3\xf7\x30\xef\xc2"
-  "\x74\x69\x9d\xb6\xd9\x22\xe6\x13\xf1\x99\x7d\x87\x32\x9f\xa6\xf9"
-  "\x58\xac\xca\x14\x26\xfb\x5f\xa9\xab\x88\xb9\x52\xc8\x4f\xd7\x8e"
-  "\x32\xff\x1a\x66\x2b\xbf\x6d\x74\x0a\xd4\xb9\xce\x4c\x2e\x0a\xeb"
-  "\x8c\xd9\x73\xe1\x58\x89\x75\xc1\xb6\xc2\xbd\x9f\xfc\xb6\x9c\x78"
-  "\x90\x93\xdb\x7d\x1a\xc2\x9a\xe0\x7b\xeb\x49\x15\xf5\x41\x84\xb1"
-  "\x20\xd0\x06\xcb\x30\xb9\x6a\x35\x7f\x9d\x2f\x44\x1f\x9f\x90\xc7"
-  "\x5f\xcc\xc3\x30\x9c\x5e\xa3\xeb\x91\xf5\x71\x68\x27\x12\xae\xc5"
-  "\xe1\xfe\x38\xc7\x7f\x5f\xa7\xff\x7d\xf0\x3f\x1f\xc7\x17\x6c\x4d"
-  "\xa0\x73\xac\x4a\xda\x7b\x5b\x15\x0b\xe7\xfe\x2e\xe7\x41\xb2\xf3"
-  "\x35\x24\x94\xae\xab\x6d\xe1\xab\xe9\xfa\x63\x21\x5d\x28\xfb\x36"
-  "\x5a\x9f\x38\x7e\x0c\xf4\x91\x20\xdc\x4b\x29\x8c\xc7\x20\xdc\x83"
-  "\x19\x60\x9b\x4b\xf7\x5f\x62\xac\x77\xe1\x18\x21\x1c\xc3\x59\x9c"
-  "\xc0\xaa\x70\x29\xd6\x2f\xda\x6a\xaa\xc6\x7a\x8a\x3d\x2c\xc6\x66"
-  "\x16\x63\x0f\xe3\xfe\x4d\x21\x46\xd1\x1c\xb8\x2f\xb6\xab\x38\xcf"
-  "\x70\x3d\x53\xdc\x8b\x69\xcf\x08\x2b\xe4\x32\xd2\xd0\xef\xeb\xbd"
-  "\xe8\x73\x28\xb9\x01\x7d\x36\xb4\x10\x23\x69\x27\xc6\xd8\xd6\x14"
-  "\x8c\x53\x57\xc6\xe2\xd3\x0d\x40\x79\xe0\x5e\x20\xe4\x90\x65\xfa"
-  "\x2b\x34\x46\xdd\xab\x0d\x24\x54\xff\x5b\xbe\x1a\xda\xc0\x6a\xdf"
-  "\x16\x56\x28\xf4\xa3\x5d\x30\x17\xde\x53\x4f\xbe\xa1\xd8\x4c\xe3"
-  "\xaa\x36\xd0\xef\x59\x7e\xb5\xe4\x9b\x4d\x34\x0f\xaf\xdb\xc5\xda"
-  "\xee\x1b\x3a\x3f\xec\x49\x15\xe3\x90\x7d\x13\x21\xc6\x3a\x35\x93"
-  "\x6f\x36\x5f\x0b\x5c\xb0\x09\xd2\x26\xc9\xd7\x42\x7f\x83\x31\x59"
-  "\x03\xb0\xee\x90\x87\x60\xd9\x90\x47\xc2\x7f\x48\x7f\xd5\x46\x86"
-  "\x40\xbd\x6a\xc5\xf2\xe1\xfa\x26\x33\xb9\x4c\xe7\x18\x2c\xf3\xda"
-  "\xb6\x7f\x2b\x80\xb4\x6c\xb3\x4f\xab\x10\xa3\xf0\x9b\x7c\x33\xc9"
-  "\x3e\xd2\x15\x17\x82\xb1\x50\x00\x63\x09\xda\x6b\x74\x3e\xf3\x0f"
-  "\x3c\xba\x80\xd9\x1e\xbf\xb9\x86\xeb\xb5\xb6\x5e\x27\x2a\xb4\x05"
-  "\xb2\x3e\x5b\x4d\xf7\x15\x62\x1a\x60\x76\x3e\x8c\x11\x6a\x8f\xf5"
-  "\x6e\xfe\xaf\x66\xfb\x20\x9a\x88\x5f\x7a\x8c\xe8\xdf\xb8\x7a\xa6"
-  "\x93\xaf\x75\x61\x7f\x44\xf5\x9a\xb2\x78\xfa\x1d\x9b\xd6\xd1\xb5"
-  "\x0e\x58\x5f\x68\xa7\x16\x8f\x5c\x53\x3d\x3a\x9f\x7e\x73\xd9\x3e"
-  "\x22\x8f\xad\x3d\xad\x3e\xe1\x13\x32\x78\x2d\x3c\xeb\x98\x68\x4b"
-  "\xc4\x3c\xe9\x18\x03\x14\xca\x77\xbc\x67\x0c\x7d\x46\x35\x1b\xeb"
-  "\xd5\x56\x6e\xdb\x68\xdc\x9f\xad\x12\xd2\xad\x65\x36\x2b\xee\xdd"
-  "\x76\xeb\x07\x87\xc6\x77\xc2\xb5\xde\xdb\x47\xe7\xe3\xfe\x92\x07"
-  "\xad\x62\x9d\x6b\xac\xb8\xaf\x01\xeb\xcc\xda\xb6\xe6\x8a\xd8\x8e"
-  "\x5b\x9a\xa0\xec\xa4\x0b\xa4\x9a\xd4\xac\xc6\xf5\x70\xb8\x4f\x07"
-  "\xc7\x30\x6b\x83\x9a\xd5\x34\x5f\xbb\x23\x0f\xf5\x77\x41\x63\x86"
-  "\x40\xf9\x39\x34\xbe\x10\xbc\x03\xc8\xc2\x90\x84\x7b\x76\x6b\xa8"
-  "\x6e\xb7\x21\x86\xb0\xf7\xa6\xeb\x5f\x6b\x43\x59\x5f\xa9\x39\x22"
-  "\xce\x19\x66\x21\x6d\x2b\x3e\x3b\xae\x9d\x5c\x25\x35\x3b\x30\xc6"
-  "\x2f\xb4\x47\x21\xfa\x8f\x2a\x6b\x81\x71\x12\xdf\x8e\x7d\xa1\x10"
-  "\xe3\xc8\xc1\x9c\x92\xc9\xe6\x39\x6c\xf3\x9a\x78\x7c\x3e\xb6\x2d"
-  "\xc8\xce\x02\x6d\xfa\x7a\x6b\x6a\xad\x5a\x6c\xd3\xf4\x60\xd4\x7b"
-  "\x6a\xc2\xbb\x9a\x23\xec\x50\xe7\x32\x60\x57\x86\x21\x17\xb0\x7e"
-  "\xe7\xb9\x81\xa3\xf3\x71\xad\x35\xfc\x5f\x27\x60\x3b\x95\x1d\x1b"
-  "\x4b\xb5\x7f\x85\x67\x1c\xc1\x75\x0b\x88\x95\xe8\xe3\x08\xd2\x74"
-  "\x42\xfb\x51\x3f\xf7\x19\x71\xac\x1d\x58\xfe\x6f\xfd\x99\xdd\x78"
-  "\xf0\x07\x50\x2f\xa7\xef\x3f\xdf\x52\x7f\x2b\x39\x42\x5c\x6e\xb8"
-  "\x56\xe4\x54\xe7\x16\xba\x4f\xb2\x09\x6d\x7e\xb5\x4b\xf1\x59\x5b"
-  "\xd0\xbf\x0f\xf6\x8b\x7a\xe7\xfe\x5f\x3b\x0d\xeb\x89\x6b\x79\xed"
-  "\x81\x23\xf2\x60\xde\xcd\xc7\x76\x86\x7b\x36\xc2\x58\xc8\xef\x62"
-  "\x4e\xa4\xb1\xa4\x5a\x53\xbf\x1d\x23\xce\x89\xa0\x67\xc0\xbc\x50"
-  "\xf7\x10\xd5\x3f\x81\x57\x1b\x39\xe4\x35\x75\x11\xd8\x6f\x60\xac"
-  "\xdb\x84\xf5\x7d\x30\x86\xbf\x5d\x2a\x7e\x13\xb3\xe3\x7e\x88\xab"
-  "\xf4\x3b\x6e\x8b\x18\x6f\x89\xf9\xd3\xfa\x36\x43\xda\x3f\xf1\x6d"
-  "\x76\xa7\xfd\x13\xb8\x6f\x64\x27\x8d\xf1\x73\x00\xe7\x94\xd2\x86"
-  "\x6a\x9c\x23\xe8\xfd\xb8\xa7\x22\x09\x74\x73\xb6\xf7\xa4\x1a\xed"
-  "\xf4\x34\x3e\x02\xd6\x85\xf9\xc4\xaf\xa2\xff\xa1\xdf\xaa\xf0\xc8"
-  "\xfa\x52\x1d\x71\xc4\xec\x05\x79\xe3\x37\xb8\x93\xaa\x27\x88\xe1"
-  "\x3e\x9c\xaf\xeb\x1e\xc2\xf8\xb3\x90\x27\x4c\x8c\x3d\x4b\x63\xcd"
-  "\xb2\xf7\xf1\x14\x43\xc6\x7f\xeb\x68\x12\x81\x3e\x31\x70\x1f\x16"
-  "\x6d\x03\x75\x4e\x08\xfa\x8d\x45\x1f\x78\x86\x04\x8c\xdf\x50\x77"
-  "\xf9\xcd\x60\xba\x97\xb5\xc5\x30\xba\x09\xd7\x57\x35\xd4\x26\x52"
-  "\xbf\x28\x7e\x33\xe2\x6d\x3c\xde\x47\x79\x45\x60\x0e\xc6\x57\x68"
-  "\xa0\xfe\xd3\xb1\xcc\x5e\xfb\x40\xad\x3b\x20\x70\xd4\x06\xc0\xfd"
-  "\x3b\x41\x56\xf4\xbb\x06\xfc\x0f\xae\x27\xf5\xb7\xb1\x78\x88\xcc"
-  "\x9f\xb7\xb0\xce\xda\x97\xed\x91\x87\x36\xa3\xbe\x42\xbf\x5b\xa7"
-  "\x19\x81\xb1\x43\xbf\x5b\x4f\x7d\xea\x66\x0c\xf3\x17\xe6\x4d\xf6"
-  "\xae\x80\xf5\xf3\xe3\x95\xb4\x8e\x58\x3f\xef\xea\xf6\xdd\x14\x41"
-  "\x9f\xf0\x6d\x4d\xfd\x6e\xb3\xb8\xb7\x9e\xf1\x2a\xe6\x6b\x97\xc9"
-  "\xe2\x3b\x61\x8f\xd9\x30\xb5\xf0\x6c\xf5\x0d\x78\x76\x11\x2b\x33"
-  "\xac\x9a\xf9\x1b\xae\xd3\x83\x5c\xab\x5b\x53\xeb\x83\x44\xbd\x46"
-  "\xd8\x1b\x14\xce\xf4\xad\xfa\x70\x49\xaf\xa9\xeb\xb4\xcf\x77\xc2"
-  "\x8a\x15\xb1\x9a\x85\x8b\x57\xe9\x17\xc4\xbe\x14\xad\x59\x14\x13"
-  "\xb3\x22\x46\x83\xce\x52\x9c\xc7\x0f\x8b\x6f\x52\x1f\x29\xc4\xf3"
-  "\xca\x97\xe2\x79\xd5\x6f\x72\x8e\x3b\x67\x26\xf5\x9b\x6f\x8c\x0d"
-  "\xa3\x3e\xdf\x53\x39\x19\x4a\xae\x00\x7e\x85\xf0\x33\xc0\xaf\x18"
-  "\x6d\x1a\xf3\xad\x24\x12\xe6\x7a\xca\x0f\x45\x5f\xec\x5c\x6a\x7d"
-  "\x14\xae\x1d\xaa\x22\xdf\xf7\xc9\xe1\x54\x84\xfa\x00\x49\xe5\xd0"
-  "\xdf\x34\xfa\x86\x2e\x84\x9f\x01\x7e\xc5\xf0\xa3\xf7\x71\x9f\xd0"
-  "\x7d\xd5\x05\xce\xd7\xd8\xba\x90\xf8\x08\xcc\xc3\xaf\x57\xd1\xef"
-  "\xbf\xdc\x76\x96\xcf\xa5\x0e\x4a\x3e\xf5\x9b\x63\x42\x3e\x3a\xbf"
-  "\x0e\x58\x4f\x34\x6e\xf2\xf9\xf0\xa9\x17\x0a\x84\x7c\x74\xbd\x8b"
-  "\xf8\x3e\xe8\xb7\x1c\xf2\x8b\xf9\x54\x7c\x6a\xdd\x24\x21\x1f\xc5"
-  "\x4d\x2e\x55\xe9\xee\xb9\x7d\xf8\xd4\xf7\xb4\x42\x3e\xb5\x73\x79"
-  "\x4e\x79\x7c\xb9\xd4\xf2\x03\x98\x87\x5b\xaf\x62\x7e\x13\x52\xeb"
-  "\xf3\x21\xbf\x5b\x7f\x8f\xde\xc9\xa9\xa1\x93\xff\x27\xfd\x4b\x8b"
-  "\x17\x3d\xbe\x78\x79\x1c\x46\xa0\x89\x5d\xb1\x3a\x16\x8f\xcb\x17"
-  "\xfc\x89\x1e\x56\xcc\x7f\xf9\x25\xf6\x27\x76\x69\x04\xfe\x59\x0a"
-  "\xfd\x0d\x8f\x0b\x57\xeb\xf1\xf0\xd2\x0a\x3c\x8d\x8f\x0e\x5f\xfd"
-  "\x92\x18\x8a\xda\xb9\x1f\x6a\x5b\x53\x1b\xac\xd0\x37\xea\x18\xce"
-  "\x5e\x51\x99\xc9\x05\x8a\xcb\x18\x93\xe2\x94\xd6\x46\x44\xfb\x16"
-  "\x93\x7f\xc3\x4c\xe6\x9b\xf1\x4a\x60\x0e\xd7\xd7\x2f\x60\xbd\xfe"
-  "\xa5\x00\xdb\xe2\x45\x30\x67\x54\xc0\xbd\x91\x66\xf2\xd2\x14\x86"
-  "\x8d\xc3\x42\xa9\x1f\xc2\xd4\x86\x0c\x61\xcd\xa6\x8a\xcb\x08\x2b"
-  "\x47\x5f\xe0\x70\x4e\x63\xbe\xc2\x39\xe6\x0b\x81\x73\x8c\xf5\x1a"
-  "\x04\xe7\x26\xb4\x4d\xc1\x39\xc6\x50\x0d\xe5\x32\xee\xac\xc3\xbd"
-  "\xa8\x70\xae\x81\xf3\x30\x28\x3f\x57\x1c\x17\xee\xb9\xf2\x15\x83"
-  "\x18\x87\x96\xc5\x9c\xbd\x52\xee\x88\x39\x8b\x71\x66\x92\xd4\x34"
-  "\x2e\x0d\xe3\x20\x57\x5a\x7c\x42\xee\xea\x07\x79\x5a\x1c\x71\x78"
-  "\xa8\xdd\xe3\xaa\x4a\x5c\x2f\xc3\xec\x1a\x57\x83\x9c\x62\xf7\xe2"
-  "\x79\x98\x18\xbb\x17\xed\x5e\x34\x36\x1a\x1c\xf9\x54\xf4\xf7\xc8"
-  "\xbb\x9d\x2b\x59\x4c\xbd\xab\xaf\xa3\x9f\x4f\x4b\xf2\x42\xc5\xfd"
-  "\x39\x68\x4b\x83\x73\xe6\xe3\x8d\xbf\x4a\xae\xd2\xf5\xd7\xa2\xff"
-  "\x27\x67\x9f\x03\x6e\xf7\x39\x7d\x0e\x9c\x81\xc6\x0c\x59\xba\x22"
-  "\xc0\xb6\x60\x11\xe3\x81\x57\xbf\x63\xf8\x35\xa2\x98\xf1\x85\xab"
-  "\x15\xfc\x33\x2c\xce\x82\x99\xfc\xa0\x43\x9d\x25\x40\xb1\x74\x05"
-  "\x0f\xf7\x06\xc4\x2f\x58\x44\xd3\x20\xdf\x06\xe0\x6a\x42\xfd\x8e"
-  "\x1a\x43\x71\x7f\x24\x27\xf8\x52\xb8\x5a\x38\xef\xee\x14\x7c\x8e"
-  "\x1f\xe5\x21\x9f\x13\x7f\x8c\x6d\x87\x75\xcb\x71\xf2\x4f\xb5\x15"
-  "\xd2\x70\x6d\x68\xf3\x33\xc4\x1f\xfd\x74\x0a\x75\x29\x64\xb1\x86"
-  "\x7e\x98\x29\xfa\x8a\x31\x43\x9a\xeb\xfb\x3c\xf3\x07\xda\x2b\x87"
-  "\xbd\x14\x3e\x73\x32\xfc\x0b\x17\xc2\xaa\x3a\xf7\xcd\xd0\xe6\x81"
-  "\xe1\x05\xcd\x87\x1e\x79\x85\xc5\x00\xfc\x21\x17\xca\xa1\x6b\x7d"
-  "\x39\xd4\x4b\x5a\x75\x59\x6c\x6d\xe9\x0f\xe7\xd1\x2f\x26\x97\x8a"
-  "\x7c\x12\xf7\xd7\xfe\x40\xf1\x8b\x57\x8f\x28\xd9\xb3\x0e\xfd\xc5"
-  "\x2a\xa0\x8d\x7f\xf8\x08\xaf\x09\x3e\x77\x94\xd4\x47\x8d\x9d\x84"
-  "\xd0\xfd\xa5\xc0\x51\xd0\xbf\x4c\x2d\x69\x7a\x1f\x79\x07\xda\x95"
-  "\xb8\xd4\x1f\x16\x62\xbf\x05\x19\xa3\xaf\x89\x16\x7e\x60\xd8\x31"
-  "\x3e\x70\xe4\x52\xec\xc7\xc8\x75\x8d\x6a\x6c\x33\x0b\xce\x39\x13"
-  "\xe1\xf7\x47\x16\xcf\xe2\x85\x3a\xb1\x4c\xf4\x8b\x04\x1c\x0a\x63"
-  "\xca\xab\x5b\x53\x2d\x3a\xa7\x58\x5d\xc2\x7e\x5a\xcb\x1a\xf4\xd7"
-  "\x84\x65\x33\xee\xdc\xb4\x97\x71\x10\xcb\x46\x33\x09\x18\xcb\xc6"
-  "\xa2\x05\xf8\x4f\x4a\xb8\xf0\x1f\xf8\x4f\x78\xae\x4b\x19\x35\xa2"
-  "\xcd\x94\xf5\x69\x0b\xda\x1e\x26\xc2\xef\x8f\x90\xbf\x44\x8c\xd7"
-  "\xbc\x41\x49\xf7\x3f\xd6\xfa\x84\xe0\xbe\x68\x4b\xb5\x98\xde\x47"
-  "\x11\x09\x6d\x6a\x69\x11\xc7\x7e\xf3\xc0\x11\xa0\x67\x35\xaa\x44"
-  "\x5b\x0b\xb3\xbd\x34\x06\x39\x9d\x1f\x83\xf3\x30\xf1\x1c\xfe\x47"
-  "\x88\x58\x01\xff\x41\xff\x4d\x6e\x10\xfe\x4f\x31\x93\xd4\x7c\xe1"
-  "\xff\x2c\xb3\x4f\x5b\xac\x58\x6f\x2e\xd5\x27\x80\xd5\xbd\x69\x33"
-  "\xb7\x2d\xcd\x80\x31\xb2\x21\x4f\xbc\x99\x5c\xa1\x6b\xd2\xd1\x3f"
-  "\xd2\xe6\x76\xf5\x2c\xe3\x46\xe0\xc4\x2f\x63\x5f\x6a\xa2\x63\x63"
-  "\x4b\x82\x7a\x26\xf2\x49\xf4\x03\x41\x7d\x69\xa1\xff\x38\x1b\xf1"
-  "\xa5\x7e\xc7\xb7\xa5\x15\x50\x7f\xdb\xaf\x6a\xfd\x45\xdf\x71\x80"
-  "\x33\xb8\xbf\x66\x23\xfa\x93\xa3\xf1\x05\x5a\xb5\x03\xa8\x0f\x39"
-  "\xc1\x77\xdc\xee\x38\x12\x94\xcd\x31\xdf\x71\xd4\x47\x84\x2f\xe8"
-  "\x1f\x71\xee\xfd\xc7\xf1\xa9\x7b\xcb\x45\xff\x71\xfc\x75\xbb\x15"
-  "\xfe\x87\x81\xcc\x55\x70\xd4\xd2\x73\xf4\x21\xc7\x7c\x07\xab\xdc"
-  "\xfa\x93\x53\x02\x9e\x29\x99\x3f\x39\xef\xe6\x81\x26\x1d\xeb\x13"
-  "\x4d\x59\x62\xec\x68\xa7\xb4\x03\x30\x16\x32\x59\x9a\x45\xf0\x0d"
-  "\xd3\x04\xf8\x97\x1c\x29\xac\x91\xb4\xa0\x5d\x2c\x93\xda\xbe\x7e"
-  "\xb0\xf1\x1d\xd1\xbb\xdc\x61\x49\xd3\xc0\xdc\x8c\x26\xba\x16\xb0"
-  "\x19\xb8\x6f\x33\xe5\x5b\x4c\x47\x6c\x26\xae\xe3\xf5\xc5\x97\x56"
-  "\x2c\x5c\x34\x7f\xc9\x32\xbd\xe6\x99\x59\x13\x69\x60\xb4\x70\xcd"
-  "\xe2\xd8\x45\x74\xaa\xd1\x3c\x33\x79\xc2\x8c\x19\xb3\xe6\xff\x61"
-  "\xd6\xf8\x59\xb3\xff\x30\x8e\xed\x30\x9c\x15\xb3\x06\x83\xeb\xc5"
-  "\xae\xd0\xe0\x4d\x2f\x0a\xa1\x6f\x13\x16\xc5\xac\x70\x1d\xe7\x41"
-  "\xd4\x7e\xa5\xa4\x36\xdb\x16\xfc\xcf\x6c\x64\xcd\xd9\xa2\xed\x8a"
-  "\x61\x5a\xf3\x16\x6c\x5b\x1a\xeb\x30\xb5\x39\x08\x79\x93\x10\x63"
-  "\x18\xe7\x13\x15\x8e\x55\x9c\x57\xe0\x5d\x8a\x1d\xf1\x50\x1d\xf6"
-  "\xb3\xe6\x06\x25\xde\x27\x8c\x51\x96\xd6\xa2\xe0\x87\x0c\x49\x66"
-  "\x7e\xf8\x9b\x6d\xa2\x5d\x1b\xd3\xc4\x3a\x54\x61\x9e\xd4\xe6\xc9"
-  "\x52\x4c\xce\x96\x30\x29\xee\x1c\xe9\xd4\x46\x84\x20\x4d\xe9\x03"
-  "\x1c\xc4\x17\x7e\x7d\xf1\x37\xc5\x81\xdb\x71\xbc\x09\x75\xb1\x00"
-  "\x05\xcc\xad\xf1\x3e\x2c\xe6\x4d\x5a\x05\xf5\xcf\x3e\xc3\x6e\xf3"
-  "\x99\x6f\x57\xc2\xd1\x87\x9f\x6f\x57\x51\xfd\x8f\x8f\xe3\x2b\xd0"
-  "\x17\x1a\xdc\x57\x8e\xb1\x9d\xa0\x1f\x6f\x9a\x61\x4b\xda\x34\xc3"
-  "\xce\xdb\xe6\x03\x2f\x87\xe3\xb7\xb8\xc7\x7b\x86\xfd\x5b\x9e\xc6"
-  "\xb5\x80\xbc\xe9\xcc\xff\x57\x31\xee\x47\x9d\x07\x7d\x38\xa7\x89"
-  "\xc5\xf5\x9c\xb1\xe6\x87\x4b\xf3\xd7\x98\x59\x5c\xcf\xab\x2c\x7e"
-  "\x2d\x8b\xcb\x4b\x92\xa0\x9c\xd3\xf3\xed\x3e\x9a\x19\xf6\x0e\x9e"
-  "\xed\x53\xbd\xe6\xd7\x55\xac\x4e\xc4\xce\x55\x83\x89\x12\xed\x28"
-  "\xf6\x77\x42\x0d\xe8\xeb\x2b\xd9\xc2\x5b\xd1\x37\xc9\xc7\xed\x26"
-  "\xa5\x26\x0e\xe3\x20\x5d\x1b\x55\xa6\x8f\x70\xbf\x4f\x39\x7d\x58"
-  "\x10\xbf\x63\x44\x18\x9f\xfe\x2b\x0b\x1c\xf3\xf8\x8c\x91\xd9\x88"
-  "\xe3\x7c\xfa\x88\x12\x7e\xc7\x48\x48\x1f\x95\x0f\xc7\x3c\x3e\x3d"
-  "\x62\x23\xbf\x23\x1c\xce\x7f\x1d\x05\x47\x38\xef\x33\x15\xf2\x6b"
-  "\xf8\x74\xdf\x63\x70\xcc\xe5\xd3\xfd\xc2\x21\x1f\x9c\xdf\x96\x0d"
-  "\x47\x38\xbf\xdd\x1f\xf2\xc1\xb9\x7f\x62\x2d\xb9\x66\x85\xff\x90"
-  "\xf6\xe8\x58\xf6\xac\xc7\xa6\xd0\x67\xa5\x8f\x9d\xc5\x9e\xf1\xbb"
-  "\x28\xf6\x8c\x09\x4b\xd9\x33\x26\xc7\xb3\x67\xf4\x6f\x80\x7c\x5a"
-  "\x3e\x3d\xc0\x04\xc7\x7c\x3e\x3d\xb0\x08\xf2\xc1\xf9\x1d\x05\x70"
-  "\x84\xf3\x41\xf0\xac\x70\x38\xbf\x73\x13\x1c\xe1\x7c\x70\x2c\xe4"
-  "\x0b\xe7\xd3\xef\x5a\x08\xc7\x03\x7c\xfa\xdd\x58\x3e\x9c\xdf\x3b"
-  "\x09\x8e\x70\x3e\xf4\x61\xc8\x07\xe7\xf7\x87\xc1\x11\xce\xa7\xc0"
-  "\x3b\x8d\x88\xe0\xd3\x9f\x1a\x03\xc7\x02\x3e\xfd\xf7\xf0\xbc\x91"
-  "\x70\x3e\x2d\x17\x8e\x70\x3e\x03\xee\x0f\x87\xf3\xa7\xfd\xe0\x08"
-  "\xe7\xcf\xe0\xbb\x3e\xcc\xa7\xcf\xc2\xe7\x1c\xe1\xd3\x9f\xc5\x77"
-  "\x86\xf3\x3f\x56\xc3\x11\xce\x9f\xc3\xfa\xc0\xf9\x0b\x78\x1f\x9c"
-  "\xcf\x85\x36\x18\x31\x86\x4f\x9f\x5f\x09\xc7\x42\x3e\xfd\xc5\x03"
-  "\x90\x0f\xce\x17\x25\xc2\x11\xce\xa3\xa1\x0d\xc3\xe1\xfc\x4f\xa1"
-  "\x70\x84\xf3\x65\xf8\xbe\x63\xf9\x74\xbd\x01\x8e\xc7\xf8\xf4\x55"
-  "\x99\x90\x0f\xce\xe3\xa2\xe1\x08\xe7\x6b\xa0\xfd\xc2\xe1\x3c\x51"
-  "\x0d\xc7\x63\xee\xe5\x99\xbc\x89\x5f\xef\x4b\xf8\xf4\x37\x54\xfc"
-  "\xfa\xbe\x70\xdc\x7c\x84\x5f\xdf\x07\xda\x28\x63\x21\xa4\xc3\x71"
-  "\x4b\x2e\x9c\x87\x0b\xe7\x70\x4c\xdf\x0c\xe7\x11\xc2\x39\x1c\xb7"
-  "\xc6\xc3\xf9\xc3\xc2\x39\x1c\x33\xf1\x1c\xea\xb8\x03\x8e\xbe\x70"
-  "\xcc\xb4\xc2\xf9\x58\xe1\x1c\x8e\xff\x3e\x09\x8e\x36\x3e\x7d\x7b"
-  "\x04\xa4\x47\xc2\xd1\x02\xe7\x70\x7c\xb3\x00\xce\x27\x41\xfe\x20"
-  "\x38\x9f\x64\x19\x36\xd8\x8c\x7d\x95\x1b\x68\x31\xf3\xc1\xa3\x73"
-  "\x93\xaf\x11\x25\xf6\x51\xf4\xf3\x0f\x73\xee\xbd\x55\xa4\xf5\x5c"
-  "\x41\x92\x99\x72\x01\xfb\xce\x11\x1a\x2e\x78\x44\x2e\xa4\xfb\x42"
-  "\xbe\xbe\xb5\xa4\x0d\x63\x1b\x10\x63\xa2\x99\xc6\x1c\x13\xfc\xd6"
-  "\xf9\xc2\x3d\x76\xe0\x4d\x63\x30\x7e\x3a\xb4\xd7\x1c\x3e\xb5\x4f"
-  "\x13\x1c\x2b\xf9\xd4\xdb\xab\xa0\xbd\xe0\x3c\xf0\x73\x38\xc2\xf9"
-  "\xa3\x7f\x86\xf6\x82\xf3\x17\x26\xc0\xb1\xb2\x35\xd5\x3a\xc7\x4c"
-  "\xae\x31\x3f\x62\x69\x3c\x8f\xbe\x90\x71\x2f\x25\x1d\x87\x89\x2d"
-  "\x84\x4f\x8b\x24\xfc\x50\x9d\x99\xda\x2a\x07\x8d\x35\x04\xc4\xc3"
-  "\xf9\xb0\x21\x66\x7e\x60\x1b\x5d\x6f\x8b\x31\x40\xf8\x8e\x30\x25"
-  "\xab\xc7\xed\x7c\x15\xb1\xee\x40\x5f\xf5\x7c\x70\xa0\xa7\xeb\xef"
-  "\xd3\xeb\xf7\x3d\x17\xc5\xae\xfb\x11\xe9\xfa\x0b\x78\xfd\x5c\x00"
-  "\xfa\x51\x7e\x20\x90\x5e\x37\xb6\xd4\x09\xef\xe8\x83\xd7\x1a\x31"
-  "\xaf\x99\xb4\x05\xb1\xb9\xc0\xea\xcf\xa7\xfa\x90\x66\xf5\xc8\x4d"
-  "\xad\xa9\x6d\x30\xff\x5f\x0b\x12\xec\x1f\xe5\xbc\x3a\xac\x82\xf9"
-  "\xdc\x18\xed\x36\x36\x0f\xea\xb8\x5c\xe6\x84\x29\x5b\x00\x4f\x51"
-  "\x6f\x86\x79\x55\xa9\x49\x0a\x2b\xac\x22\xed\x96\xdd\xc8\xab\x82"
-  "\x74\x1a\x86\xb3\x6d\xef\x77\x6c\x1f\x59\xa1\x49\x08\x80\xe7\xb7"
-  "\x37\x26\x5b\xf9\x6b\x86\x24\xf4\x5f\x84\xe9\xe1\x6a\xb6\x77\x88"
-  "\xe6\xb1\xb1\x35\xa5\xf4\x7f\x1d\xb3\x53\xb7\x5b\xf0\x5e\x67\x3d"
-  "\xc5\x9e\x76\x74\x13\x17\xac\x8b\x60\xdf\xe0\xdb\x8e\x7e\xc4\x99"
-  "\x95\x01\xb1\xa4\x8f\x26\xe1\x63\x2c\x9f\xc8\x74\x5a\x47\x5e\xbc"
-  "\xd6\x56\x73\x1c\xf2\xbe\x4d\xed\x4f\xed\x6a\x47\x6c\x56\x78\x87"
-  "\x37\x70\x4e\x55\x92\x48\x9c\xe7\x19\x47\x6e\xcf\x40\x9f\x97\xb6"
-  "\xa0\xdf\x44\xd8\x32\x2c\xe5\xf6\x4c\x9d\x86\xdf\xa9\x8b\x18\x60"
-  "\x53\x10\xb6\x96\xbf\xfd\xd4\x83\x56\xe4\xa4\x67\x30\xef\x3a\xce"
-  "\xf7\xa4\x69\x74\x3c\x51\x1a\x62\x2e\xe0\xf9\x47\x7c\x9a\x51\x65"
-  "\x6c\x30\x11\x43\x0c\x2d\xeb\x18\x9f\x56\x63\xe3\x7c\x2f\x8c\xcd"
-  "\x41\x6e\x1f\x8f\xb6\xb9\xcf\x31\x7d\x3c\xc8\x05\xe6\xa7\xf6\x6c"
-  "\x47\xdc\x60\x68\xcb\x2d\xd0\x76\xc8\xbb\xd1\x0f\xc6\x7c\xbb\x1d"
-  "\xfd\x94\x6d\x32\x43\x3b\x30\x79\xb5\xa7\x60\xcc\x65\xe1\xb9\xe7"
-  "\xb8\x81\x23\x0d\x65\x73\xf0\x7b\xa3\x1f\xfa\x7d\xba\x46\xf7\xce"
-  "\xdb\x30\x0e\x1b\xce\x61\x2c\xaf\xb3\xec\x16\x0b\x3e\x03\x16\x2f"
-  "\x8f\x8d\x59\xa9\x59\xb5\x38\x61\xd1\xb8\x61\xab\xc3\x35\x31\xf1"
-  "\x9a\x18\x1a\x03\x9b\x26\xc0\x94\xbf\x6a\xe9\x8a\x58\x0d\xc6\x22"
-  "\xee\x1c\x0b\x35\x84\x57\x8f\xcc\xa2\x9c\x54\x41\x98\x5d\x25\x57"
-  "\x67\x8a\x4d\xe4\x39\xcd\x7d\x7d\x81\x8b\x77\x64\xb4\x29\xdb\x71"
-  "\x9f\x90\x9a\x4b\xd5\x88\x7e\x4f\xfd\x77\x0d\x24\xb8\xbf\x0f\xf4"
-  "\xb8\x0e\x87\xfd\xc3\xac\x20\xe5\xcc\xde\xd2\x01\xef\xdf\x16\x29"
-  "\x7c\x77\x63\xbe\xe4\x84\x6b\xec\xbb\x74\xc7\x31\xd0\x3d\xe9\xf7"
-  "\x17\x78\xd6\x18\x36\xbf\x77\xd0\xef\xee\xbc\x46\x67\xe2\xf3\x86"
-  "\x98\x81\x23\x2a\xe8\x37\x40\xdb\xbd\xbc\x91\x34\x31\x9f\x9b\x3b"
-  "\xc6\x46\xa2\xff\x0e\xfb\xce\x51\x06\x2e\x78\x6c\x24\xf7\xce\x5d"
-  "\xb9\xc9\x7b\x89\xf2\x30\xe0\x82\x4a\x03\xe3\xe1\x3e\x72\xef\xc7"
-  "\x49\x75\x4a\xa8\xb3\xfd\xe3\x24\x93\x92\xcf\x1c\x9d\xd5\x1c\x16"
-  "\x5e\x6c\x15\x62\xe6\x1a\x6d\x56\xf2\xf7\x49\x04\x75\xbf\xc2\x96"
-  "\x41\x93\xea\x5a\x06\x8d\xca\xb7\xee\x98\x36\xd3\x70\xdf\xbf\x90"
-  "\xc9\xc3\xf9\x1f\x3e\x85\xb7\x6f\x50\x90\xc2\x4f\x27\xa1\x3e\x32"
-  "\x32\xc3\xaa\x1e\x99\xd9\xb2\xf3\x37\x06\xf4\xc5\xd4\xb6\x73\x5a"
-  "\x6e\x7b\x70\x84\xe6\x24\xe4\x39\x03\xfa\xd2\x59\x0d\xf4\xdf\xa1"
-  "\x44\xd9\xf6\xc0\x90\x88\xc3\xed\x19\xca\xe2\xa2\xb1\xcc\x56\x1c"
-  "\x05\x63\x86\xf6\x27\xdb\xde\x4f\x8f\x14\x11\x78\x36\x39\xdc\x3e"
-  "\x45\xf9\xf7\x31\x9d\xae\x9f\xf8\x34\xa2\x88\xb4\xa2\x1f\x55\xd0"
-  "\x47\x8f\x5f\xc8\x22\xfc\xce\x89\xe4\x60\x82\x55\x09\xe0\xa3\x2c"
-  "\x35\x65\x91\xc4\x1a\xd2\xdf\xf6\x83\x56\xf5\x1e\xdc\xdf\x86\xb1"
-  "\x56\xce\x86\x50\x3f\x7b\x49\x06\x1a\x8f\x33\xa0\x0c\xb8\x08\xf7"
-  "\x83\xd6\xb7\x6c\x96\x81\xc0\xf5\xe5\xb6\xdf\x87\x90\xd2\x68\x0b"
-  "\x31\xea\x72\x49\x9b\x32\x92\x1c\x7d\x3e\x97\xbc\x0d\xba\xcd\xdb"
-  "\x57\x89\x3f\xe5\xd5\x1d\x5a\x5f\x5b\x87\x56\x65\x5b\xab\x45\xbf"
-  "\x47\x3c\xff\x83\xb6\x1f\xf2\x6c\xdb\x0a\xad\x5f\x99\x25\x97\x3c"
-  "\x58\x47\xb4\x6d\x4a\x12\xd0\xb6\x56\xdb\xaf\x4c\x9f\x05\x65\x01"
-  "\x71\x86\x76\x45\x9f\x6b\xe8\x8b\x0d\xdb\xe9\x76\x1d\x99\xd5\x40"
-  "\x6c\x6b\xfa\x55\x90\x41\x18\xff\x05\xb9\x2b\xfa\x6d\xe5\x82\x26"
-  "\x12\x7b\xd0\x6f\x0c\x49\xd7\xa0\x5e\xe8\xab\xe8\xd0\x23\x91\xc8"
-  "\xfd\x81\xd7\x28\xf0\x9d\x39\x5e\xdb\x6f\x3e\x1e\xb7\x87\x2d\x47"
-  "\xfe\xcf\xb5\x86\x60\x7c\x1a\x3f\xac\x27\xc6\x9d\x5d\x77\x19\xda"
-  "\x32\x59\xab\x82\x7c\xfe\x90\x3e\xc0\xd8\x60\x25\xf6\x51\x8f\xcc"
-  "\x1c\xad\xa7\xf1\x44\x83\x72\x92\x88\x3a\x23\x89\x04\x69\x1e\xa5"
-  "\x7d\x69\x97\xfd\xe0\x23\x91\x7c\x5a\xff\x78\xb4\xe1\xd0\x34\xc2"
-  "\xaf\xd1\x3c\x41\x88\xe6\x5f\xe8\xff\xa1\x9a\xc7\x41\x86\x41\x13"
-  "\xa2\xa8\x6e\x42\xf5\x5c\x7e\x10\xd3\xbb\xf8\xfe\x6d\xbe\x7f\x3c"
-  "\xc0\xa5\xfd\xb9\x98\x5b\xaf\x0a\xc5\x58\xbf\x57\x09\xd7\xc8\xa7"
-  "\xef\x6d\xe0\x33\xa7\x8d\x61\xbe\xdb\xb9\x2b\x6d\xbe\xb7\xc1\x5c"
-  "\xf8\x97\x99\x50\xfe\xd8\x36\x85\xaa\x02\x7e\x26\x76\x3f\x57\x8d"
-  "\xef\x6d\xcf\x1b\x52\x88\xef\x4d\x63\x9a\xc0\x7b\xcd\x07\x99\xf1"
-  "\xc1\x13\xd4\xd4\x47\x76\x07\xb4\xaf\x10\xfb\x11\xdb\x03\xdb\x80"
-  "\xeb\xd0\xf6\xa3\xef\xda\xa1\xf5\x87\xf6\x45\xbf\xab\x01\x49\x0b"
-  "\xe0\x9e\x9d\x13\xc2\xe0\xda\x80\xb6\xa0\x09\x3a\x8c\x2d\x64\xd4"
-  "\x5b\x88\x7d\xc7\x04\x0d\xfa\xaf\xdb\x95\x00\x63\x6e\xd0\x04\x98"
-  "\xcb\x27\x84\x0b\x63\x8b\x60\x3d\xb9\xf4\xbf\x64\xb7\xe1\x3e\x3b"
-  "\xa8\x1b\xd4\xaf\x02\x7e\x26\x33\xe1\xa2\xdb\x86\x0d\x29\x86\x23"
-  "\xd6\x37\x94\x4f\x1b\x96\x85\xff\xe1\x5a\x28\xbc\xf3\xd3\xd8\x0e"
-  "\xd8\x1e\x42\x5b\x3c\x29\xb5\xc5\xd3\x15\x90\x6f\x0c\x97\xf6\xda"
-  "\x52\x33\xe1\x43\xf8\x34\x8d\xce\x29\xdf\x4a\x29\xdf\xdc\x78\x96"
-  "\x2f\x23\x94\xe5\x1b\x51\x0e\x72\xe8\x2f\xb4\xf7\xfb\x6e\xda\xfb"
-  "\xa0\x74\xef\x13\x1a\x76\x6f\xc2\x01\x76\xef\xa0\x72\x48\xaf\x71"
-  "\xa9\xd3\x45\x29\x7f\xe4\x2c\x96\x7f\xf5\x1c\x96\x5f\x9d\xed\xc8"
-  "\xa7\xc0\x79\x41\xcc\xf7\x7b\x33\xcb\x97\xdc\xc2\xf2\x0d\xb1\xc1"
-  "\xf5\xf1\x9d\xea\xa2\x20\x8f\x49\xf7\x2c\x5e\xc8\xee\x79\x5b\xcd"
-  "\xee\x79\x64\x33\x5c\x5f\x29\xab\x8b\x82\x2c\x96\xf2\xbf\x24\xbc"
-  "\xf7\x8e\x5c\x96\x3f\x62\x8c\x53\xbe\x6d\x42\x9f\x80\xeb\xb9\xe8"
-  "\xa5\xca\xbf\xcd\x77\xc5\x14\x96\xef\x71\x13\xf6\x47\xc8\xf3\x57"
-  "\x2e\x2d\x80\xb4\xf9\xde\x0e\xf8\xcd\x11\x90\x4d\x08\x1e\x41\x76"
-  "\x21\x5c\xc6\xc8\x0c\xd0\x70\xe3\xf1\x5b\x10\x62\xae\x99\x74\xe8"
-  "\x00\x77\xed\x6e\xed\x65\x69\xc4\xe2\xb0\xd7\x71\xc0\x1f\x76\x0c"
-  "\xf7\xf4\x1d\x43\x45\x7d\x6b\xef\x1c\x11\x99\xc1\xb1\xd8\xd3\xd0"
-  "\x47\x7d\xab\x14\x8a\xc1\x30\x17\xa6\xe0\x35\x2e\x73\xac\x81\x0b"
-  "\x03\x8c\xbd\x42\x7c\x8c\x89\x75\xa4\x80\xab\x53\x66\xb4\x13\x55"
-  "\x19\xd4\x10\xf3\x17\xc0\x9c\xaa\x59\x0e\xdc\x42\xa1\x78\x28\xe3"
-  "\xba\x50\x5e\xae\xce\x9c\xbc\x8c\xc5\xf6\x45\x4e\x86\xd8\x0c\xe3"
-  "\xd1\x9f\xc6\x89\x5a\x1e\x80\x79\x17\xc1\x7f\x3f\x1a\xcb\xf9\x81"
-  "\xc1\x51\x6d\x7f\xd1\x99\xdb\x77\x3e\xa8\xe9\x78\x20\x34\xb2\x2d"
-  "\x78\xac\xc1\xb6\xf3\x37\x91\xb6\xfb\x74\x33\x3b\xde\x19\x62\xb6"
-  "\x07\x3f\x98\x0b\xcf\x06\xdc\xce\x52\x1e\xe2\x32\x94\x87\x92\x0a"
-  "\x95\x58\xee\xc7\x49\xf9\xca\xe3\x49\xe5\xca\xe3\x5c\xb1\xf2\xe3"
-  "\xa4\x5c\x38\x16\x60\xcc\xa0\x7b\xa1\xec\xf7\x8f\x27\x19\x94\xad"
-  "\x69\x8a\x16\x18\x07\x95\xa2\xbd\x93\x9f\x60\x23\x65\xf9\x36\x72"
-  "\x2a\xf6\x1a\xb1\x04\x8e\xcc\x82\x5f\xb6\x65\xd0\x84\x29\x96\x41"
-  "\xd3\x66\xd2\x3a\x07\x4f\xa4\xef\x88\xfb\x54\x8f\x73\xac\xce\x42"
-  "\x7b\x40\x99\xca\xbb\x73\x38\x5c\x73\x42\xfd\x60\xfa\xd7\x2b\x94"
-  "\x26\xda\x36\x19\x6f\x14\x83\x8e\xd5\x4a\xf7\xb9\x28\x59\xbc\x2a"
-  "\xd1\xcf\xa4\x18\xef\x8a\xc6\xb8\x6a\xd5\xe2\x77\xfb\x30\x8c\x73"
-  "\xb5\xfb\x3a\x09\x82\x5f\x88\x18\xc3\x68\xb7\xe0\xdb\x3e\x3d\x4e"
-  "\xb2\x4d\x08\x36\x87\x20\x16\xaf\x68\x17\xf5\xd3\x4d\xf9\x0c\xfa"
-  "\xa4\x44\xfb\xc3\x2a\x2d\xd9\x13\x23\xd9\x1f\xec\xad\x5a\x25\xe8"
-  "\x94\xe5\x54\xa7\x84\xf9\x8b\xc6\xb8\xb3\x01\x3f\xdb\xf1\x78\x2e"
-  "\xea\x8e\xc8\xc7\x5a\xd3\x7c\x54\xa2\xee\x87\x1c\xc3\xbe\x6d\x64"
-  "\x3e\xfc\xf2\x20\x3d\xd4\xac\x78\x27\x56\x4c\xe7\xb7\x37\x9a\xd1"
-  "\xee\x6e\xe7\xa3\x7f\xdb\x8a\x7b\x2f\xf9\xe8\xdf\xd9\x77\x8c\x2a"
-  "\xb0\xef\x98\x16\x01\x69\x63\xe1\x37\xce\xbe\xad\xb1\x1a\x7e\x75"
-  "\xf0\x6b\x80\x9f\x05\x7e\x50\x5e\xa3\xd5\xbe\xad\x89\xc0\x4f\x05"
-  "\x3f\x3f\xf8\xf9\xc3\x4f\x0d\xbf\x20\x3e\xb0\xd1\x86\x3e\x1a\xf9"
-  "\xed\x4d\x1a\x90\x7b\x88\x58\xae\xd4\xbe\x3e\xeb\xe1\x7d\x23\x91"
-  "\xff\x00\x5e\xf9\xf1\x0c\xaf\x42\xf8\x7d\x83\xeb\x10\x77\xf9\x61"
-  "\xe1\xc5\x96\xa1\xba\x72\xcb\xa0\x89\xe5\x70\x1c\x63\x09\x9c\xaf"
-  "\x83\x5f\x14\xfc\xa2\x2d\x3b\x26\x44\x81\x0c\xc7\x80\x2c\x2d\xf0"
-  "\x2e\x75\x66\x45\x3f\xba\x97\x1e\xfe\x83\xfc\xfb\x59\xd9\x7f\x15"
-  "\x31\x2b\xfa\x46\xe1\x7f\x28\xa3\x00\xce\xd5\x66\x85\x1f\xcd\xd7"
-  "\x1c\x3c\x41\x2f\xec\xe3\x4c\x81\x74\xad\x59\x35\x30\x8b\xe5\xfb"
-  "\x8d\xcc\x6f\xfe\xb2\x97\xf4\xf3\x97\x2d\x88\x9f\xbf\x6a\xe9\xe2"
-  "\x97\x16\xad\x7a\x5c\x33\x6c\xa1\x46\xbb\x38\x66\xe5\xfc\x95\xab"
-  "\x17\xad\x5e\x44\xa9\x13\x24\x0d\x97\xaf\x61\xc3\xbd\x98\xb6\x43"
-  "\x8f\x44\x71\xa0\x17\x94\x55\xd7\x91\xdb\x41\x27\x58\x37\x97\x28"
-  "\x4b\x5a\x8e\x10\xfe\x3e\x9d\x99\xf3\x8d\xfc\x5d\x19\x20\xcc\xb1"
-  "\x7a\x8b\xd2\x06\x5c\x66\xaa\xc5\x00\x63\x71\xac\xa1\x7f\xf5\x7c"
-  "\xfe\x58\xbd\x55\x39\xb5\xc1\x40\x92\x2f\x03\xb7\x59\x68\x25\x1d"
-  "\x0f\x0c\x31\x1f\xab\x2f\x00\x5e\x0b\x1c\x27\xa5\x9d\x94\x58\x6d"
-  "\xd0\x67\xc7\x46\xe2\xbd\x3c\x70\x1c\xcc\x8f\x3a\x07\xfa\x8b\xed"
-  "\x78\xe0\xae\x5c\x1e\xc6\x13\xe6\x3f\x0e\xe9\xd3\xf5\x06\x32\x0d"
-  "\xca\xea\x08\xfe\x4d\x24\x0f\xe3\x89\xbf\xbe\x8e\x2f\xa9\x36\x90"
-  "\xe3\x4b\x0a\x94\x1f\xc1\xfd\x68\x8f\xe3\xdf\x19\x1c\x85\xe3\x0f"
-  "\xea\x35\x13\xef\xc1\x6b\x55\x8a\x3e\xe5\x78\x1d\xf5\x88\x0e\xa8"
-  "\xef\x61\x28\x2f\x79\x35\x51\x89\xba\x96\x6c\x5c\xc7\x05\xf0\x57"
-  "\x15\x7d\xc6\xe1\xb8\xe6\xa1\xae\xf8\x1e\x07\xe1\xde\x43\x4b\xac"
-  "\xcc\x26\x7b\x0d\xf1\xc3\x4c\x10\x3b\x10\x33\x8c\x89\x4c\xf7\x2a"
-  "\xe0\xd0\xae\xe0\x83\xf7\xae\xc1\x6b\xc0\xcf\x5b\xd0\xaf\x5b\x6b"
-  "\x5a\x9f\x23\x22\x2f\x7e\x43\xf0\xe9\x76\x7b\x25\xf4\x97\x79\xe4"
-  "\xde\xab\x0a\xd5\x1a\x6c\x53\x6c\x33\xfc\x16\xdb\xe1\xab\x1a\x83"
-  "\x7e\x23\xb2\x07\x12\xbf\x8e\x1d\x3a\xed\xdb\xe8\x7b\x23\xad\x4f"
-  "\x8b\xc8\x35\x5b\x82\x74\x5a\x67\x59\x32\x19\x6a\x16\x2d\x5f\xf0"
-  "\xe2\xd2\x45\x0b\xe9\xe7\xbb\x05\xab\x56\xad\x5e\xb6\x48\xb3\x68"
-  "\xc1\x4b\xd1\x1a\x7a\x59\xb3\x7a\x15\x64\x59\x1c\xbb\x4a\xb3\xe2"
-  "\xd5\xe5\x9a\x65\xab\x16\x23\x6b\x5e\x14\x13\xb3\x5a\x1f\xdb\x8f"
-  "\xb0\x3b\x35\xcb\x56\x2f\x8d\x5d\xac\x87\x3f\xab\x16\x2d\x5f\xa8"
-  "\xa1\x3d\x61\x15\x14\xb5\x74\xa9\x46\x78\xc2\xaa\xe8\x05\x31\xd8"
-  "\x39\x96\xbf\x02\x99\x9c\xee\x97\x73\x6a\x7f\xf4\x99\x87\x6b\xba"
-  "\xae\x2a\xfa\xce\x2e\x52\x01\x16\x65\xea\xb4\xb8\x16\x02\xce\x67"
-  "\x51\x3d\x2b\xcd\x57\x85\x36\xeb\x37\x07\x12\x55\x33\x8c\x85\xd6"
-  "\x34\xdf\x72\xf1\xdd\xa8\x0d\x1b\xfd\x52\xa2\xcf\x53\x45\xdf\xf1"
-  "\x74\x8f\x31\x8c\x09\xba\x56\x26\xcd\xf7\x4e\x6a\xdb\x4a\xeb\x4b"
-  "\x9c\xed\x66\xd4\x4e\xab\xe8\x3b\x18\xd7\xe6\xc1\xb8\x98\x85\x5c"
-  "\x41\xf0\xef\xae\x80\x7b\x26\xe3\x3d\xdc\x8e\x69\x63\xe0\xbe\x31"
-  "\x12\x5f\xef\xab\xc6\xfc\x34\x5f\x9a\xef\x8b\xfc\xa0\x09\x51\x66"
-  "\x85\x6f\x0b\xd6\xcb\xc3\xdc\xa2\xb9\x0e\xe5\x9e\x2d\x20\x64\x64"
-  "\x10\xd1\x5e\xdf\x3e\xda\xd4\x3a\x70\x64\x41\x7b\x2a\xe9\xdb\x0e"
-  "\xe3\xdb\xaa\x24\xf7\xb6\x41\xbf\x58\xf3\x10\xf1\x59\x37\x8d\x28"
-  "\x0b\xa0\xbf\xa1\xdf\xff\x92\x29\x59\xc4\x18\x05\xba\xb9\xf5\x00"
-  "\x29\x31\x54\x91\x52\xdb\xbb\x2c\x66\x40\x02\xf2\x6d\xbf\xa3\xe8"
-  "\xf7\x2e\x79\x1d\x6f\x3f\xfc\x81\xa5\xcf\x21\xe8\x8f\x9a\x18\x72"
-  "\xaf\xd1\x76\xc9\x60\x4c\xcc\x23\xc6\x78\xa3\x01\x7d\x8e\x40\xbb"
-  "\xed\x3b\x0e\xd7\x6e\x2b\x81\xfb\xa6\x93\xbe\x70\xbe\x0b\x9f\xb1"
-  "\x69\x27\x6f\x7a\x3d\x98\xaf\x7c\x7d\x27\x6f\xde\x1c\xcc\x57\x43"
-  "\x9f\xaa\xdb\x12\xcc\x37\xe0\x5a\x03\x5c\x53\x81\xfd\x54\x1f\x47"
-  "\x42\xea\x15\x7e\x11\xd4\x46\x30\x89\x9e\x0f\x86\xf3\x48\xc4\x6a"
-  "\x63\xfc\x4e\x3c\x1f\x02\xe7\x33\xd9\x79\x0e\x9e\xdf\x05\xe7\x51"
-  "\xec\xfc\x53\x3c\x0f\x85\x73\x3d\x3b\x2f\x23\xd4\x77\x86\xc2\x2f"
-  "\x85\x9d\x7f\x81\xe7\xd0\xf6\x7e\x19\x86\x38\xac\xef\xd7\x20\x33"
-  "\xbf\xdd\xc9\x17\x41\x6f\x8b\xaf\xa5\xe3\xe1\xe3\xa4\x68\xb4\x61"
-  "\xc0\x78\xf0\x1b\x8a\xfd\x1d\x70\xca\xe0\x1b\x81\xc7\xbe\x45\x01"
-  "\x56\xd2\x17\x38\xd4\xed\xf0\x3e\xdb\xb0\xed\xdc\xda\x6c\x0e\x8d"
-  "\x0a\x98\x61\xe3\x0d\xfc\xbe\x21\x26\x7e\xc7\xb8\x48\x7e\x5f\x28"
-  "\xfa\xc9\x05\xac\x18\x41\x0a\x12\xac\xd4\xb7\x31\xf0\x56\x18\x43"
-  "\x7e\x74\x5d\xb6\x05\x78\xa0\x07\x5f\xa7\xc0\x25\x47\x47\x82\x7e"
-  "\x55\x3c\x4d\x6b\xc3\x35\xd4\x8a\xab\x8a\xdb\xb6\x9d\x8a\x46\xbe"
-  "\x30\xf1\x6f\x5c\x5e\xa8\x86\x4b\xd6\x11\x3e\x6c\x88\x69\x5a\x34"
-  "\x6f\x80\xb9\x4b\xc1\xec\xe3\xfc\x25\x8c\x7f\x4e\x9f\x3b\x6c\x88"
-  "\x89\x7b\x35\x1a\x63\xbf\x50\x7c\x49\xc2\x79\x3c\x0e\xf0\x60\xad"
-  "\x2e\xc0\xbe\x63\x62\xc1\xa9\xe8\x1a\xef\xe2\x88\x28\x6e\xf3\x18"
-  "\x2b\x05\xeb\x84\xfe\x3f\x6d\xf0\x1c\x1b\xbc\x2b\x72\x86\x43\xc0"
-  "\x0d\x80\xbb\x98\x0e\xbe\x68\xea\xc3\xbf\xaa\x0b\x80\x77\x7a\xc8"
-  "\xa8\xbd\x46\xca\xda\x71\xac\xf4\x9b\x79\x2a\x9e\x90\xc9\xf1\x36"
-  "\x43\x80\x85\xfa\x64\x56\xeb\x97\x90\x7b\xf8\x41\xa3\x23\xeb\x15"
-  "\xfd\x72\xa7\x27\xc2\x3b\xc0\xbb\x1f\xaf\x32\xa9\x38\x78\x8f\x07"
-  "\x59\xbb\xe1\x7d\x1b\xa1\x6d\x8b\x45\xbe\xef\x5d\xfd\xfb\xd1\x7e"
-  "\xc3\xad\xd2\x11\xdc\x2b\x7d\x38\x09\xea\xd7\xa1\x0b\xe0\x60\x4e"
-  "\xc2\x6b\xa7\xb4\x57\x08\x3e\x93\xb5\x75\x3f\xea\x1f\x9f\x0f\x83"
-  "\x76\x86\xe7\xa3\x2f\x68\xb1\x5d\x21\xef\x46\x7b\x47\xb4\x7b\xf9"
-  "\xef\x9c\x98\x02\xf5\x33\xf0\xdb\x1a\xdd\xc7\x54\xde\xde\x78\x98"
-  "\xf5\x8f\xc1\x56\xc8\xe7\xc7\xef\xd5\x45\x42\x1f\x60\xb1\xd9\x77"
-  "\x3e\x5e\xe0\x14\x9b\x1d\xfa\xc8\xed\x43\x31\x36\xbb\x7b\x7f\x85"
-  "\xaf\x15\xd3\x98\x48\x7d\x2e\xf1\x01\x76\x8c\x57\x7a\x0d\xfd\x8a"
-  "\x17\x9f\xd2\xb6\x78\x29\xd3\xdb\x17\x7a\x92\x29\x96\x0f\xba\x76"
-  "\x87\x97\xe5\x1d\xf1\xd8\x47\xf2\xa0\x5d\xd4\x8d\xe5\xed\xfc\x24"
-  "\x05\xe3\xe4\xfd\x9f\xc6\xb6\xea\x00\x3e\x9d\x70\x8e\x28\xdb\x61"
-  "\xde\x7c\xef\xd9\x5c\x65\x38\x8c\x3b\xe0\x2b\x29\x25\xa6\x12\x32"
-  "\x63\x21\x49\x2e\x6d\x68\x42\x7f\xec\x34\xd6\x11\x1f\x3c\x3e\xe5"
-  "\xc0\xb3\x16\x25\xc6\x19\xc1\xd8\x46\x65\x2d\xa0\xbf\xee\x9c\xa0"
-  "\x3f\xfc\xac\x55\x69\x7f\x55\xa7\xc1\x78\x14\xf8\xcd\x38\xa9\x81"
-  "\xe7\xe8\x37\xab\x66\xe0\x82\xcd\xa0\xa7\x66\x84\xc5\x96\x44\x15"
-  "\xd3\x18\xac\xe8\x2b\xa9\x34\xfa\x1a\x39\xbb\xf1\x38\x29\x31\x99"
-  "\x70\xaf\xf5\xde\x92\xea\x63\x84\x6b\xd6\x0e\xb0\xaf\xd2\x0e\xcc"
-  "\x8e\x21\x41\x30\x4e\x6f\xe3\xa0\x8d\xf9\x55\x42\x6c\xcb\x26\x29"
-  "\xb6\x25\xc6\x8e\xcf\xc6\x38\x95\x57\xd4\xc4\xe6\x7b\xfb\x14\xc8"
-  "\xaf\xc2\x38\x96\xbb\x9b\x88\xf6\xed\x18\x12\xf6\x36\x5c\x93\x7d"
-  "\xaf\xfa\x93\x16\xbf\x0f\xf8\x0d\xb8\xc6\xe2\xd8\x73\x20\x27\x31"
-  "\x8e\xe5\xf4\x6b\x1a\x72\xec\x8b\x5c\x25\xf6\x3d\xef\xda\xb9\x3f"
-  "\x5d\x93\x67\x0b\x9e\x98\x62\x0b\x6c\x2c\xb7\x0d\x1b\x62\x30\x2b"
-  "\xfc\x83\x40\x5e\x6e\x75\x12\xb1\xed\x3b\x92\xc5\xb6\x1f\x70\x5e"
-  "\x6c\xfb\xb5\xcf\x81\x3e\xff\xce\x5d\xb9\xef\x5e\xc8\x92\xda\xbe"
-  "\xa2\x73\xdb\xbb\xb6\xf9\xa1\xe7\xad\x4a\x2a\x8f\xe7\x81\x03\xbd"
-  "\x33\x24\xe2\xdd\xe7\x99\x0c\x78\x2a\x83\x28\x49\x06\x1d\xd1\x18"
-  "\xe7\xdc\x21\x83\xa4\x95\xa2\x0c\x6a\x98\x0c\x2a\xa8\x0c\x16\x50"
-  "\x19\x80\x7e\x6d\x5f\xab\x1d\xf8\x56\x02\x09\xca\x4e\x20\x21\x54"
-  "\x0e\xea\xd7\x30\xde\x4c\xbf\x2d\x09\x04\xd7\x08\x47\xc0\x58\x14"
-  "\xe5\x10\x24\x93\x43\x82\x20\x87\x76\xa2\x7d\xab\x9d\x84\xbd\x95"
-  "\xca\xe4\x80\xb8\x3e\xbd\x25\x80\xe7\xbe\xd7\x92\x9c\x7a\x90\xc3"
-  "\x4a\x41\x0e\x81\x82\x1c\xd6\x82\x1c\x56\x82\x1c\xe0\xfd\x4f\x69"
-  "\xbd\xc5\xc4\x01\x79\x9d\xe5\xd0\x3f\xa3\x3b\x39\xb4\x3b\xe4\xa0"
-  "\x5e\x4d\xe5\x00\x5c\x2a\xe1\x69\xb4\x51\xdd\x95\xbb\xff\xf3\x0c"
-  "\x65\xb8\x0e\xb0\x07\xda\xb4\x64\x6a\x11\x99\x11\x45\x92\x6d\x20"
-  "\x93\x77\x3f\xb7\x2a\x4b\xaa\x41\x1e\x0b\x85\x18\x48\x4e\xf2\xa0"
-  "\xed\xbe\x73\x7c\xca\x7b\x90\x47\xf3\x2c\x8e\x93\x09\xfa\x83\x9f"
-  "\x03\x77\x74\x13\x13\xcc\xf9\x5b\x2e\x94\xc5\x61\x3c\x68\x5c\xff"
-  "\x06\xfa\xd3\x80\xb7\x40\x3f\x2a\x8d\xbe\x48\xc4\x6f\xba\x67\x2b"
-  "\x0d\x50\xb6\x76\xe0\x59\xd5\x7f\x93\x33\x25\xc5\x24\x40\x41\x86"
-  "\xbe\xcd\x91\xa0\x33\x15\x47\x90\x17\xa8\xa1\x8f\xdf\x66\x07\xf9"
-  "\xd8\x5b\x43\xfa\x6d\x06\x1d\x0a\xbf\xf5\x3a\x7f\xe3\xc5\x58\xae"
-  "\x3c\xc8\x06\xd2\x55\x36\x90\x4d\xf6\x75\xa2\xdd\x75\x9d\x84\xed"
-  "\x12\x64\xe3\x88\xf1\xfa\x8d\x96\xec\xae\x22\x7e\xfd\x17\x33\xd9"
-  "\xd8\x45\xd9\xbc\xaa\x55\x4e\x5b\xac\x21\x1f\x40\x9b\x9c\xd2\x9e"
-  "\xf3\x52\x36\x6a\xca\x1b\x40\xb7\x4c\x01\x1d\xa8\x9c\xa7\xb2\x09"
-  "\x08\xf1\x24\x1b\x7b\xde\x60\xab\x5d\x3d\x32\x13\x7d\xf0\x73\x2b"
-  "\x66\x29\x38\xd0\x97\xda\x41\x2f\x3d\x6b\xb1\x91\x44\xd0\x1b\x12"
-  "\x2e\x12\x5f\xe3\xac\xcf\x89\xd1\x5c\x48\x7d\x6a\xa3\xbd\x17\xe3"
-  "\x5a\x18\x6d\x85\xd0\xde\xd3\x0a\xf0\x7c\x37\x3d\xb7\x90\xb5\x73"
-  "\x89\x0f\x8d\x19\xa8\xcb\x25\x9b\x81\x57\x1f\x7c\x3e\x57\xc9\x65"
-  "\x8e\xce\xe2\xd5\xa0\xab\xa6\x12\x43\x99\xde\x86\x58\xe4\x5f\x1a"
-  "\x5d\x82\x3e\x2e\x2f\x25\xc7\xf3\x97\xcb\x5a\xa0\x4c\x0b\xdf\x6e"
-  "\x87\xb9\x21\x27\x95\x2f\xc4\x18\x05\x0f\xc6\x53\xce\x0d\xfd\x24"
-  "\xf0\x69\xe4\x1c\x68\xf7\x32\x24\xbd\x05\x1c\x2b\x70\x36\xbe\x1b"
-  "\xa4\x29\x4a\x97\xb4\xc0\xf5\xa0\x53\x58\x2f\x66\x83\x66\xc7\x07"
-  "\x31\xb6\x5a\xf0\xb4\xe6\x8f\x92\x2c\xaa\x0c\xd0\x77\x81\x8b\x61"
-  "\x39\x7b\x79\xa6\x0b\x86\x18\x2b\xac\xd4\xfe\x68\x49\x8e\xf6\xcd"
-  "\x48\xc0\x35\x5c\x18\xef\x00\xe7\xe6\xa0\xd5\xb8\xee\x03\xfa\x6a"
-  "\x08\x1f\xfc\x78\x41\xc1\x8b\x16\xa5\x34\xff\x06\x96\x40\x7f\x0d"
-  "\x99\xac\xe5\x93\x31\x2e\xc4\x71\x78\x2f\xd4\x7f\xde\xad\xb2\x2a"
-  "\xad\x80\x21\xef\xbd\xb8\x49\x89\xf6\x11\x2b\xf4\xbf\x92\x2f\xfe"
-  "\x8b\xc6\x71\xac\x55\x0c\xbc\x78\x46\x67\x23\xf8\xfc\xd9\xc3\x89"
-  "\x0a\xce\xd5\x6d\xca\x2c\x6b\x9b\xef\xed\x79\xc9\xd5\x52\x0c\x3b"
-  "\xe7\x58\x75\xd8\x97\x0f\xbe\x08\x65\x42\x39\x87\xaa\x52\x94\xbc"
-  "\x88\xeb\xd7\xd0\x8e\x2d\xc7\x94\xd2\x86\x2b\x24\x09\xfa\x71\x69"
-  "\x74\x2e\x8d\xdd\x31\x00\xf0\x9c\x5b\x0b\x38\xd2\x01\xfa\x3e\xe0"
-  "\x08\x8e\xff\x1c\xc0\x0d\x6e\x2d\xe8\xf9\xed\xa0\xe7\x0b\xf8\x81"
-  "\x1c\x0b\x8f\x73\xa1\x8f\x06\x14\x43\x1a\xc8\x89\xdb\x06\x7d\x14"
-  "\xf0\xe3\xed\x04\x86\xe3\xbb\x11\x3f\x80\xff\x4e\xd7\x03\x7e\xbc"
-  "\x0a\xf8\x11\x47\x63\x8c\x86\xe4\x28\x19\x6e\x7c\x50\xb5\x49\x99"
-  "\x21\xc6\x43\xa6\xed\x7b\xc7\xca\x32\xec\x1f\x51\x29\x58\x57\xa5"
-  "\x1d\xe3\x6b\xac\xd5\xf9\x94\xb5\x40\x1f\xd9\x39\x2d\x17\xd3\x28"
-  "\x7e\xbe\x1a\xdd\x8f\x63\x7d\x2d\x12\xdb\x64\xcf\x55\x12\x41\xe3"
-  "\xed\xfd\x10\xd2\x6f\xeb\x72\x12\x9e\x73\x95\x84\xe5\x2c\x27\x5a"
-  "\x18\xaf\xca\x1c\xa8\xc3\xbc\x95\x6a\x42\x63\x64\xf8\xde\x7e\x00"
-  "\xd2\xdd\xc6\xc8\x00\xfe\x1c\x92\x83\x63\x66\x85\xd6\x51\x27\x5b"
-  "\xc6\x82\x28\x3b\xb4\x1d\xf5\xff\xa6\xb8\x43\xd8\x7f\x14\x5c\xc7"
-  "\xf8\xfc\x1d\x36\xb6\xb6\xe9\xae\x06\xd0\x49\xfa\xd6\x2b\xee\xf8"
-  "\x2b\xbf\xfd\x7e\xb3\x3e\x81\x28\xea\xc5\x6b\xc0\x31\x39\x90\xd5"
-  "\xe8\x14\x92\xc2\x05\xbe\x51\x67\x8c\xbf\x82\x7e\xe8\xbd\x1c\x87"
-  "\x77\x50\x7f\x7c\xf6\x8c\x05\x0b\xe9\x7a\xa2\xed\x0b\x96\xee\xa9"
-  "\x27\x11\xfc\x9f\x40\x1e\x4b\xe0\x5d\xeb\x49\x58\x76\x3d\xbc\xeb"
-  "\xab\xec\x5d\xc5\xf8\xcf\x5c\xea\x2e\xc4\x6b\xf7\xb6\x17\x31\x96"
-  "\xe0\x9f\x30\x96\xe0\x1d\x85\x80\x61\x77\xf0\xf7\xe1\x5a\x65\xea"
-  "\xdf\xa7\xd5\x68\xbb\x48\xf0\xb9\x68\x1b\x32\x36\xd1\x3e\xbd\x0f"
-  "\xfb\x32\x97\xab\x8b\x9c\x5f\x09\x7d\xbb\x35\x1a\xed\x64\x91\xc7"
-  "\xab\x2c\xe8\x4f\x87\x72\x3b\xb3\x22\xb0\x02\xf9\xd8\xc7\x90\x86"
-  "\x7d\xdf\xa9\xcf\x57\x60\x9f\xc7\xeb\xb4\xdf\xc3\x7d\xc6\xca\x1a"
-  "\x82\xe5\x39\x97\x83\xf2\x17\xcb\xaa\x55\x0c\x7a\x1d\xcb\xc2\xbe"
-  "\x80\x36\x1d\x1c\x6b\x4c\xf6\x85\xb8\x2e\x1d\xc6\x55\x84\x86\x9d"
-  "\x5b\xd0\xbe\xa4\xc6\x3e\x40\xfb\x0a\xcc\xab\xe8\x7f\x99\xe7\x75"
-  "\x3e\xd0\xcf\xb0\x9e\xfd\x40\xde\x11\x62\xbf\x80\xb4\x20\xd7\xbe"
-  "\x31\x60\xbd\x1a\x75\x97\x20\xfc\xdf\xd3\xfe\xe1\x9d\xfc\x06\x6d"
-  "\xf2\xb8\x66\x2e\x6c\x30\xee\x51\xba\x17\x71\xd3\xde\xec\x84\x99"
-  "\x0d\x0c\x33\x11\x93\x44\xdc\xa4\xd8\x44\x63\x09\x14\xe2\x9a\xd6"
-  "\x68\x5a\x47\x2f\x71\xb3\xb4\x41\xc2\xcd\xe9\x7a\x27\xdc\x6c\xe0"
-  "\xdb\xb9\x61\xee\x70\x33\xf8\x75\x39\x6e\x06\x6f\x91\xe3\xe6\xe0"
-  "\x46\x57\xdc\xec\x8c\x99\xc1\xa5\xee\xf0\x12\xf4\x95\x7b\xeb\x15"
-  "\x83\x73\x3d\x63\x65\xb0\xd5\x7b\xac\x0c\xb9\x4d\x8e\x95\x77\x8e"
-  "\xfd\xdf\x8b\x95\x21\xbb\x65\x58\xa9\xee\x21\x56\xd6\x53\xac\x0c"
-  "\xe2\xbf\x87\x31\x21\xe0\x47\xce\x12\x0f\x58\xb9\xa4\x9b\xb1\xf0"
-  "\x27\x4f\x58\x19\x72\x4d\x8e\x95\x83\xb5\x72\xac\x0c\xb9\x28\x61"
-  "\xa5\x70\xed\x86\x60\x65\x48\xcb\xad\xc1\xca\x90\x16\x8a\x95\x57"
-  "\x11\x2b\x07\x7f\xd6\x3d\x56\xde\x49\xdc\x63\x25\xa4\x53\xac\xbc"
-  "\x93\x48\x58\x79\xb1\x1b\xac\x1c\xf2\xbe\x17\x58\x19\x44\xb1\x52"
-  "\xed\x01\x2b\x97\x40\x5b\x09\xfd\x82\xf6\x3d\x97\xbe\x21\x60\x65"
-  "\x88\x03\x2b\x7b\xd0\x3f\xbc\x93\xdf\x10\x8f\xfa\x2f\x62\x25\x97"
-  "\xc1\xf8\x25\x62\x25\x3f\x50\xc0\xca\xa5\x36\x92\x70\x1e\x30\xb2"
-  "\xa2\x9e\xc6\x4c\xa1\x6b\x81\xe1\x97\xf8\x1c\x62\xd1\x6f\x0c\x87"
-  "\xa0\xbd\x8c\xe6\x02\x8a\x4d\x74\x4d\xeb\x54\xc4\xaa\x02\xc8\x9b"
-  "\xe5\xe0\x9d\x14\x3b\xcf\x0b\xd8\x39\x47\xc0\xce\x79\x3f\x02\x3b"
-  "\x9f\x47\x59\xde\x75\xaa\x4d\x29\x62\xe7\x76\xc0\xce\xbb\x28\x7f"
-  "\xc0\xef\x99\x0c\x3b\xef\x1d\x2f\xd6\x0b\x6d\x97\xc6\xd8\xb7\x08"
-  "\xab\x57\x53\x67\x1c\x7d\x0a\xcb\x0b\x1d\x6c\x58\xd2\x40\x1c\x58"
-  "\x3a\x47\xc2\xd2\x5a\xc5\x3d\x8d\x9e\x71\x34\x34\xd2\x81\xa3\xa9"
-  "\x80\xa3\x5f\x3b\xe1\x28\xda\x0c\x10\xf3\x00\x47\x5b\x29\x8e\x7e"
-  "\x20\xe0\xe8\xdd\x4f\x9f\x99\x03\x38\xfa\x94\x88\xa3\xa1\x1b\xad"
-  "\xa9\x59\x56\x6b\x5a\xf7\x38\xda\x4a\x71\x54\x7f\xf3\x71\xb4\xc8"
-  "\x05\x47\x41\x67\xc5\xf8\xc9\x6e\x71\x54\xec\x8f\x14\x47\x53\x24"
-  "\x1c\xa5\xed\x7a\xf7\x95\xb2\x28\x68\xf7\x28\x3d\xd5\xdb\x1c\x38"
-  "\xaa\x2f\x60\x38\x0a\x69\xf4\x3b\xff\x2a\xc0\x51\xe8\x7f\xc9\xa5"
-  "\xe8\x27\x90\x44\x42\x1d\xd5\x88\xaf\x7b\x60\xcc\x60\x1b\x39\xf0"
-  "\x74\x09\x8c\x19\xc4\x98\x66\x18\x33\x80\xa3\xf3\xae\xa9\x09\x1d"
-  "\x2f\x69\x30\x5e\xea\x3d\xc4\x67\x13\xd7\xe2\x7a\xc4\xd3\x7b\x26"
-  "\xcb\xf1\xf4\x9e\x78\x39\x9e\xde\x33\x4a\xc2\x53\xe1\x1a\xe2\x29"
-  "\xc8\x0c\xda\xa7\x0e\x31\xb5\x77\x78\x7a\xcf\x24\x07\x9e\x2a\x05"
-  "\x3c\x5d\xd2\x3d\x9e\xd2\xef\x7e\x1e\xf0\xd4\x19\x1b\x3c\xe3\xe9"
-  "\x3d\x93\x24\x3c\xbd\x77\xa8\x03\x4f\x4d\x9e\xf0\x34\x74\x8a\x7b"
-  "\x3c\x85\x74\x8a\xa7\xa1\x53\x1c\x78\x6a\x72\x83\xa7\x4f\x39\xe3"
-  "\xa9\x26\x90\xe1\x69\x01\xc5\x51\xc4\xd4\xb2\x16\xe8\x1f\x38\xe6"
-  "\x62\xb3\x28\xa6\x72\x80\xa9\x80\x05\x4a\x8c\xd7\x84\x6b\xe9\xdd"
-  "\x61\x2a\xc3\x5c\x33\x41\x5c\xc5\xb1\x99\x3c\x0d\xf4\x5d\x98\x8b"
-  "\xa0\x4d\xe8\xdc\x2b\xb6\xdf\x1e\x27\x7c\x9d\xbf\x46\x8d\xdc\x4e"
-  "\xd6\x57\x38\xb1\xaf\x34\x6b\x71\xfd\xad\xac\xaf\x78\x27\x4b\x8d"
-  "\xda\x13\xb6\x7a\xd2\xdd\xcf\xa0\xee\x3e\x9b\x28\xd7\xce\x06\x7c"
-  "\xd5\xa1\xee\x9e\xef\xa2\xbb\xe7\x77\xd6\xdd\xcf\x75\x8d\xa3\x5e"
-  "\xe9\xee\xcf\xa2\x0c\x87\xf6\x97\xe3\xe8\xd0\x40\x39\x8e\x86\x6d"
-  "\xc1\x7a\x31\x1c\xcf\x77\xaf\xbb\xd3\x71\x3e\x74\xae\x43\x77\x37"
-  "\xc9\xf1\x53\xd2\xdd\xc3\xc6\x79\xc6\xd1\xa1\x9b\x64\x7c\x74\x9e"
-  "\x80\xa3\x2f\x0a\x38\xfa\xa2\x84\xa3\x67\x3f\x17\xf9\xe8\x7d\xfb"
-  "\x4e\x9b\x9c\x71\x74\x68\x89\x03\x47\x2b\x3b\xe3\xa8\x88\xa1\x34"
-  "\xde\x3c\x94\x83\x36\xac\x03\x80\xd3\x87\x5f\xd4\x53\x5b\x14\xda"
-  "\x05\xd1\x06\xeb\xb0\x41\xb5\x8a\x78\x7a\x8d\x24\xcd\x41\x3c\xcd"
-  "\xa2\x78\x1a\xa0\x20\x0b\x00\xfb\x06\x88\xf1\xe8\x77\xc7\x91\x10"
-  "\x1c\x8b\x68\x5f\xe2\x5e\x65\xf1\x23\x45\x3b\x13\xbc\x2f\xfd\x56"
-  "\x3f\xf7\xa2\x80\xa9\x18\x57\x3b\x90\xc6\xa4\xd7\xbe\x1d\xe7\x86"
-  "\x9b\xae\x05\x4c\x4d\x70\xe2\xa6\x30\xf6\x3f\x78\xd1\x15\x53\xef"
-  "\x7f\xac\x0c\xfb\x0a\x62\xaa\x4c\x8f\xcf\xff\x19\xe8\xf1\xf7\x6f"
-  "\x93\x63\xe9\xfd\x45\x72\x2c\xbd\x7f\x8d\x84\xa5\xc2\xb5\x1b\xc2"
-  "\x4d\xef\xcf\xb8\x35\xdc\xf4\xfe\x0c\x49\x8f\x0f\x5b\xe6\xc0\xd2"
-  "\x0a\x4f\x58\x3a\x34\xc3\x3d\x96\x42\x3a\xc5\xd2\xa1\x19\x0e\x2c"
-  "\xad\x70\xa3\xc7\xcb\xb0\x74\xd8\xd3\x0c\x4b\xf3\x19\x37\x35\x89"
-  "\xdc\x34\xff\x17\xa8\xc7\x0f\xeb\xb4\xff\xb1\x3b\x3d\xfe\x4c\x03"
-  "\xc3\x4f\xc4\x27\x11\x43\x25\x3d\x3e\xdf\xb3\x1e\xdf\x0d\x86\x7a"
-  "\xc5\x45\x29\x86\x3e\xf0\xb4\x1c\x43\x1f\x98\x2d\xc7\xd0\xe1\xa7"
-  "\x5c\x31\xb4\x33\x7e\x3e\xb0\xc3\x1d\x76\x32\x3d\x7e\x78\xac\x67"
-  "\xdc\x7c\xc0\xe0\x3d\x6e\xfe\xea\xa2\x1c\x37\x7f\xa5\xfa\xbf\x81"
-  "\x9b\xda\x95\x32\xdc\x54\xf7\x10\x37\x7f\x12\x9d\x5e\xeb\x62\xff"
-  "\xd4\xba\xd8\x3f\xb5\x4e\xf6\x4f\xed\x0d\xb4\x7f\x6a\x6f\x91\xfd"
-  "\x53\x5b\x2c\x71\xd0\xe1\xfb\xba\xc7\xcd\x07\x8a\xdd\xe3\x26\xa4"
-  "\x53\xdc\x7c\xa0\x58\xc2\xcd\xee\x38\xe8\x88\xd7\xbd\xc0\xcd\x9f"
-  "\xb9\x4e\x3f\xa2\x4b\xfb\xa7\x3b\x9d\x1e\x71\x93\xe2\xa5\xc9\x45"
-  "\xa7\x9f\xed\xac\xd3\xe7\x4b\x3a\xfd\x14\x86\x5b\x46\x5b\x86\x5c"
-  "\xa7\xbf\xe1\x38\x3a\x72\x97\xd5\x61\x0f\xfd\x33\xe0\xe8\xc8\xdd"
-  "\xf8\x6e\x56\x87\x3d\xf4\xc1\xa1\x62\xbd\x98\x4e\xbf\x9d\xb0\x7a"
-  "\xb9\xd1\xe9\xe9\x9a\xd9\x91\x57\x1c\x3a\xbd\xc9\x55\xa7\x1f\xfd"
-  "\x99\x67\x4c\x0d\x0f\x72\xab\xd3\xa3\xfe\x4d\x31\x55\x4f\x31\xf5"
-  "\xfa\x4e\x67\x4c\x1d\xf5\x10\xc5\xd4\x27\x44\x4c\x0d\xd7\x59\x61"
-  "\x6c\x5a\x7d\xbb\xc7\x54\x2c\x47\xc2\xd4\xe8\x9f\x06\x53\x0d\x3d"
-  "\xc7\x54\xe7\xbd\xac\x1f\xc0\xbb\x3b\x30\x95\xb6\xf1\xa8\xd2\xb2"
-  "\x28\xc4\xd4\x68\x17\xfd\x3e\xdf\xbd\x7e\x7f\x9a\x28\xb1\x7d\x44"
-  "\xfd\x1e\x65\x40\xf1\xe6\xa6\xea\xf7\xa3\x87\xc9\xb1\x75\xb4\x4e"
-  "\x8e\xad\xa3\xfb\x4b\xd8\x2a\x5c\xbb\x21\xfa\xfd\xe8\xb0\x5b\xa3"
-  "\xdf\x8f\x0e\x93\xb0\xf5\x41\x45\xf7\xd8\x1a\x1e\xea\x1e\x5b\x21"
-  "\x9d\x62\x6b\x78\x68\x97\xd8\xfa\x84\x33\xb6\x3e\xd8\x28\x62\xab"
-  "\xa4\xdf\x43\xff\xc0\xf1\x17\x9b\xd1\x7b\xfd\xfe\xc9\x5b\xad\xdf"
-  "\x3f\x68\xf1\x4a\xbf\xdf\x09\x38\x0b\xba\xf8\xda\xcf\x40\xbf\x7f"
-  "\x5a\xd0\xef\x2b\x73\x5d\xf4\xfb\xdc\x4e\xfa\x7d\xe2\xd3\x02\xa6"
-  "\xc2\x98\xa2\x98\xfa\x62\x7e\xef\xf5\xfb\x67\x50\x86\x11\x57\xe4"
-  "\x98\x1a\xd1\x28\xc7\xd4\x87\xd7\x63\xbd\x18\xa6\xe7\xba\xd7\xef"
-  "\xe9\x38\x7f\x68\x9c\x4c\xbf\x87\xfa\x75\xd6\xef\x1f\x7e\x48\x86"
-  "\xa9\xf3\x9c\x31\xf5\xa1\x68\x19\x4f\x85\xf7\x42\x4c\xdd\xff\x35"
-  "\xc3\xd4\x77\xbf\x76\xc2\xd4\xe9\xef\x0a\x98\xfa\x2f\xbb\x4e\xcf"
-  "\x72\xc6\xd4\x87\x0e\x88\x98\x4a\xf1\x72\x9e\x55\x99\xac\xf3\xbc"
-  "\xde\xe4\x00\x94\x8d\x7b\xa4\xb0\xcc\x83\x5f\x47\x77\xbf\xde\x44"
-  "\x27\x5f\x6f\xe2\x58\x6b\x12\x6b\x26\x25\xd5\x19\x74\xad\x49\x76"
-  "\x1c\x09\x0a\x58\x4f\x86\x66\xb7\x33\x3f\x02\x34\xb6\xc7\x75\xf7"
-  "\x3e\x04\xe6\x3e\x27\xe1\x2c\xfa\x11\x00\x8c\xd5\xbe\x75\x9d\xad"
-  "\xfd\x01\x79\x77\xf6\x19\x20\xf2\x26\xc0\x83\xa3\x5f\xbb\xe2\xec"
-  "\xaf\x47\x95\x61\xff\x99\x13\xed\xa2\xf3\xe7\xfe\x0c\x74\xfe\x5f"
-  "\xbf\x26\xc7\xd7\x5f\x17\xca\xf1\xf5\xd7\xcb\x24\x7c\x15\xae\xdd"
-  "\x10\xee\xfa\xeb\x8d\xb7\x86\xbb\xfe\x7a\xa3\xa4\xf3\x3f\xbc\xc0"
-  "\x81\xaf\xe5\x4e\xf8\xfa\xb5\x33\xbe\x3e\xa4\xa7\xf8\xfa\xb5\x2b"
-  "\xbe\x42\x3a\xc5\xd7\x87\xf4\x0e\x7c\x2d\x77\xd1\xf9\xbf\x76\xc5"
-  "\xd7\x47\x26\x53\x7c\x85\xbe\x20\xe7\xae\xb9\xdd\xeb\xfc\x95\x3f"
-  "\x37\x9d\xff\x91\x49\x5e\xe9\xfc\x88\xa9\x4b\x19\xa6\x22\x66\x89"
-  "\xb8\x2a\xe9\xfc\xb9\x1e\x75\xfe\xee\x70\xd5\x2b\xae\x4a\x71\xf5"
-  "\xd1\xc9\x72\x5c\x7d\xf4\x49\x39\xae\x3e\x56\xea\x8a\xab\x9d\x31"
-  "\xf5\xd1\xd7\xdd\xe1\x29\xd3\xf9\x1f\x4b\xf4\x8c\xa5\x8f\x1e\xf1"
-  "\x1e\x4b\xff\x5f\x8d\x1c\x4b\x1f\xb5\xfe\xdf\xc5\xd2\x31\x6b\x64"
-  "\x58\xaa\xee\x21\x96\xfe\x24\x76\x80\x31\x9f\xc9\xb1\xf4\x31\x95"
-  "\x1c\x4b\xc7\x1c\x95\xb0\x54\xb8\x76\x43\xb0\x74\x4c\xf9\xad\xc1"
-  "\xd2\x31\xe5\x12\x57\x7d\xec\x60\xf7\x58\xfa\xe8\x31\xf7\x58\x0a"
-  "\xe9\x14\x4b\x1f\x3d\x26\x61\xe9\xc5\x6e\xb0\xf4\xf1\x6d\x5e\x60"
-  "\xa9\xdc\x0e\xe0\x8a\xa5\xb7\xdc\x0e\xf0\xb8\xc7\xfd\x0f\x6e\xed"
-  "\x00\x22\x96\x3e\xdd\xd9\x0e\x80\xf8\x4a\xed\x00\xd0\x5e\x22\x86"
-  "\x51\x3b\xc0\x24\x86\x65\x46\xdb\x26\x99\x1d\xe0\xc6\x63\xeb\x6f"
-  "\xf6\x5a\x1d\xf6\xd4\x54\xc0\xd6\xdf\xd0\x78\xa8\x56\x87\x3d\xf5"
-  "\x77\xe3\xc4\x7a\x31\x3b\xc0\x9f\x09\xab\x97\x1b\x3b\xc0\x04\x5a"
-  "\xde\x35\x99\x1d\xc0\x09\x6b\x6b\x15\xbf\xbd\xe2\x19\x67\xc7\x86"
-  "\xca\xec\x00\x55\x12\xce\x5e\xc7\x35\xe9\x80\x83\x14\x67\x83\x9d"
-  "\x71\x76\xdc\x34\x8a\xb3\x13\x44\x9c\x1d\x1b\xd5\x0a\x63\xb3\xd5"
-  "\x5b\x9c\xc5\x35\xd2\x5f\x47\xdd\x1a\x9c\x2d\xf4\x02\x67\x9d\x6c"
-  "\x03\x47\xa1\x3d\x1c\x38\x4b\xdb\x7d\xdc\x77\x65\x73\x10\x67\xa3"
-  "\x5c\x6c\x03\xb9\xee\x6d\x03\xa7\x6e\x85\x6d\xe0\xb7\xe3\xe5\x78"
-  "\xfb\xdb\x58\x39\xde\xfe\x76\xb8\x84\xb7\xc2\xb5\x1b\x62\x1b\xf8"
-  "\x6d\xe4\xad\xb1\x0d\xfc\x36\x52\xc2\xdb\xdf\xdd\xdd\x3d\xde\x8e"
-  "\x0d\x73\x8f\xb7\x90\x4e\xf1\x76\x6c\x58\x97\x78\x3b\xc1\x19\x6f"
-  "\x23\xfb\x8b\x78\x2b\xd9\x06\x72\x05\xdb\xc0\xa6\xee\x6d\x03\x95"
-  "\x1e\x6c\x03\x93\x6f\xb5\x6d\x20\xd2\xdf\x1b\xdb\x40\xdb\x4e\xb6"
-  "\x6e\x7f\x2d\xae\xdb\x9f\x0b\xf8\x3b\xf3\x73\x68\x83\xee\xd7\xed"
-  "\x27\x8a\xeb\x4f\xa3\xb2\x04\x9c\xcd\x72\x6b\x1b\x38\x53\xe7\xd9"
-  "\x36\x70\xa6\xc2\x79\xfd\xe9\xf8\xdb\xe4\xdf\xad\xc6\xf7\x17\xbf"
-  "\x5b\x9d\xf9\x02\x71\x76\x32\x8d\xd7\xc2\x65\x4e\xb0\x50\xfc\x57"
-  "\x4c\x0e\xc2\x7a\xba\x5b\xc7\xff\x01\xe7\xfc\x2d\x6b\xfc\x62\x87"
-  "\xad\xa0\x1c\xf1\x36\x8b\x70\x7c\xb4\x2f\xfa\x1a\xa7\xb6\x82\x67"
-  "\xb1\xef\x4d\x3a\xe5\x8c\xbb\xc7\x2f\x38\xe3\xee\xf8\x4c\x11\x77"
-  "\xed\x80\xbb\x1f\x55\x65\x31\xfb\xeb\xf3\x6c\x6d\xea\x81\xe7\x9d"
-  "\xd6\xa6\x7e\xfe\x89\x80\xbb\x13\xb6\x9d\x36\xc3\xfb\x77\xb5\x7e"
-  "\x0a\xee\x3f\x74\xa1\xa7\x6b\x50\xb3\xdc\xae\x9d\x12\xf0\xc9\xed"
-  "\xfa\x29\xa8\xab\x7a\xb7\x30\x56\xed\x30\x4e\x77\x3b\xad\x9f\xca"
-  "\x4e\x80\xf1\x2c\xec\xbd\xea\x72\x1d\xea\xf3\xd2\x3a\x54\x3e\x73"
-  "\x42\x38\xce\x6f\xdc\x8e\x09\x96\x76\x3e\xda\x87\x0f\x9a\x10\x8e"
-  "\xcf\xef\xe8\x80\x79\x67\xa2\xce\x47\xd0\xeb\xd4\x80\x3d\x03\x58"
-  "\xbb\x4f\x28\xb1\xc3\x5c\x63\x87\xb9\x06\x64\xa6\xb6\x21\x37\xd9"
-  "\x39\x21\x28\x1b\xf4\x3c\x5b\x2a\x8d\xd5\xda\x2f\x1d\x74\xbd\x3d"
-  "\xa8\xe7\x5d\x85\xb1\x91\xac\x55\x62\x7d\x44\x1c\x0d\xa8\x83\xf7"
-  "\xb8\xda\x35\x97\xb3\xfd\x20\xe1\xa8\xe1\xa9\x33\xf0\xcc\x89\x27"
-  "\xca\xb0\xef\xea\xa4\x3d\x05\x94\x33\x7b\x58\x2b\x8b\x75\x61\xfe"
-  "\x17\xa1\x2f\xdc\x00\x9b\x84\x73\x7d\xe4\xb8\x3e\x69\xb0\x1c\xd7"
-  "\x27\x4d\x95\xe3\xfa\x24\x85\x84\xeb\xc2\x35\xc0\x75\x7b\x2a\xe3"
-  "\xd1\x30\xf7\xf5\x92\x47\x4f\x0a\x11\x71\x9d\x13\x70\x3d\xa7\x07"
-  "\xb8\xde\x25\x8f\x76\xc2\x25\xcf\xb8\x3e\x29\x44\xb2\x49\x4c\xba"
-  "\xe6\x76\x8d\xec\x05\x67\x5c\x1f\x9f\x4d\x71\xfd\x82\x2b\xae\x43"
-  "\x3a\xc5\xf5\xf1\xd9\x1e\xf7\x13\x5c\x70\xfd\x9e\x36\xf9\x3c\xc5"
-  "\x75\x93\xb0\x46\xb6\xdc\x8b\xfd\x04\x26\x86\xe9\x22\x96\xa3\xbd"
-  "\xea\xd6\xda\x24\x26\x9b\xbc\xb1\x49\x50\x2c\x6f\x60\x58\x8e\xd8"
-  "\x28\xe2\x79\x4f\xf6\x13\x74\x87\xe7\x22\x6f\x46\x3c\xf7\xc4\x9b"
-  "\xe5\x78\xfe\xc4\x79\x39\x9e\x3f\x71\x51\x8e\xe7\x4f\x9d\x97\xe3"
-  "\xf9\x53\x26\x57\x3c\xef\x8c\xe5\xff\x3a\xca\x1d\x8e\xeb\x9f\x45"
-  "\x1b\xc5\x53\x9b\x3c\x63\xf8\xbf\xea\xbc\xc7\xf0\x29\xb3\xff\xcf"
-  "\x61\xb8\xda\x15\xc3\xa7\x64\x20\x06\xd9\xd3\x5c\x30\x7c\x89\x80"
-  "\xe1\x02\x8e\xec\xa9\x17\xb8\xb0\x2b\x86\x37\xc0\x7b\x74\xa3\x8f"
-  "\xdb\xbe\x77\xc5\xf0\x27\x5f\x93\x61\xb8\xba\x1b\x0c\x5f\xc2\xec"
-  "\x20\xb2\x75\xb9\x1e\x6c\x21\xf0\x1e\x07\x76\x7b\xe0\xe6\x62\x9b"
-  "\x39\xd7\x47\x8e\xe1\x4f\x5e\x94\x63\xf8\x53\x6a\x39\x86\x3f\x79"
-  "\x4a\xc2\x70\xe1\xda\x0d\xe1\xe6\x4f\x56\xde\x70\x6e\x2e\xf6\x8f"
-  "\x2e\x31\xfc\xc9\x4a\x89\x9b\x3f\x75\xb4\x7b\x0c\xff\xd7\x28\xf7"
-  "\x18\x0e\xe9\x14\xc3\xff\x35\xca\xe3\x3e\x87\x4e\x18\xfe\xfb\x5d"
-  "\x5e\x60\xb8\xdc\x16\x22\x62\xb8\x60\x0b\xd9\xe3\x64\x0b\xb1\xa7"
-  "\x32\x5b\xc8\xee\x7a\xd6\x37\x06\x28\x58\x3f\x85\xfe\x13\x92\xa3"
-  "\xec\x5a\x77\xdb\xdd\x2b\x3b\xc8\xef\xb3\xbc\xb1\x83\x50\xfc\xc6"
-  "\x3d\x0e\xcf\x01\x6e\x97\xf7\x70\x8f\xc3\x14\x71\x8f\x43\x86\x87"
-  "\x3d\x0e\x02\x9e\xcf\xfb\x11\x78\x4e\xf7\x38\x4c\xdd\x2f\xb7\x31"
-  "\x4f\x3d\x28\xda\x98\x19\x9e\xcf\xfc\x48\x8e\xe7\x33\x8f\x39\xf6"
-  "\x3c\x00\xe6\x1b\xf5\xdb\x3b\xed\x79\x70\x60\x3b\xb5\x83\x4e\xeb"
-  "\x6f\x78\xb6\x9a\x38\xf0\x7d\x8e\x84\xef\x50\xd6\x32\x19\xb6\x57"
-  "\x39\x63\xfb\xb4\x87\x65\xd8\xfe\x75\x96\x7c\x7d\x44\x95\xde\x09"
-  "\xdb\xc5\x3d\x0f\xd3\x1f\x3a\x5d\xd9\x0d\xb6\xc3\xfd\x3d\xdf\x23"
-  "\x76\x63\xb1\x5d\xdc\xdf\xe0\x16\xdb\x9d\xf7\x37\x38\xad\x7f\x40"
-  "\x6c\xa7\x71\x2d\x06\xb9\x60\xfb\xda\x68\xa5\xfd\x24\x8c\x07\xc0"
-  "\x75\x1c\x23\x76\x1e\xb0\x9d\xb6\xf7\xf4\xa5\xce\xd8\xde\x91\xca"
-  "\xb0\xfd\xed\xfa\x1f\x8f\xed\x0e\x3e\xec\x8c\xed\x4f\x20\xb6\xcf"
-  "\x58\xcc\xf6\x5f\xa4\xf4\x6c\xff\x85\xcb\xfa\x8c\xb7\x7b\x60\x7f"
-  "\xe9\x12\xe3\xdd\xd4\x4b\x8e\xf1\x33\x4e\xc8\x31\x7e\x46\x8b\x1c"
-  "\xe3\x67\xec\x97\x30\x5e\xb8\x76\x43\x78\xfa\x0c\xc3\xad\xb1\xbf"
-  "\xcc\x30\x48\x18\x3f\x73\x77\xf7\x7b\x2f\xa6\x8d\x75\xbf\x36\x03"
-  "\xd2\x29\xc6\x4f\x1b\xdb\xe5\xde\x0b\x99\xbd\xfb\xe9\x2d\x6e\xf7"
-  "\x5e\x94\xff\x74\x6b\x33\x9c\xfb\x8a\xab\xfd\xa5\xf7\xb6\xef\xa7"
-  "\x3d\xc6\xca\xf1\x64\x7f\xc1\xbd\x17\x6b\xcf\x39\xed\xbd\xa8\xec"
-  "\x7e\xef\x45\xe2\xec\x1e\xda\x5f\xba\x58\x9b\x71\x66\xa6\xf3\x7a"
-  "\xb7\x67\x5e\x97\xe3\xfb\x33\x5b\x1c\xf8\xfe\x0c\xe2\xfb\xb3\x7b"
-  "\xe5\xf8\xfe\x6c\x2e\xd6\xd3\xdd\x5e\x8c\x0f\x64\xdf\x15\x9f\xf9"
-  "\x4e\xbe\x56\xc3\xc5\xfe\xf2\x0c\xf6\xbd\x67\x9f\x96\xe1\xfb\xd7"
-  "\xce\xf8\xfe\x87\x20\x77\xdc\x1d\xed\xde\x74\x4d\xf1\x3c\xa7\x3d"
-  "\x6d\xd3\xc5\xf5\x6f\xb3\xee\x3e\xad\x83\xf7\x37\x7b\x58\xeb\x36"
-  "\x8f\xad\x75\xa3\x6b\xdb\xd0\x0e\x0e\x65\x1d\x9e\xa7\x57\x26\x45"
-  "\xf1\x1c\xae\x75\x73\x5d\xe7\x86\x6b\xdf\x70\xad\x5b\x69\x74\x86"
-  "\xc7\x75\x6e\xd8\x37\x3d\xad\x75\x83\x7a\x07\x51\xac\xbf\x2c\x60"
-  "\xbd\xb0\xd6\x2d\x3b\x4e\x5a\xeb\x26\xc3\x7a\x37\xeb\x87\x8f\x7e"
-  "\x9d\xe2\x9e\xc7\x27\x4b\x58\xdf\x8e\x3c\xfe\x37\x2e\xb6\x18\x2a"
-  "\x83\x59\xba\x9f\xd4\x16\x43\xb1\x7e\xf6\xb4\x32\xec\xc7\x73\xf4"
-  "\x6e\x6c\x31\x9d\xd7\x38\xff\x74\xb6\x98\xd9\xfb\xe4\x18\x3f\xdb"
-  "\x24\xc7\xf8\xd9\x5b\x24\x8c\x17\xae\xdd\x10\x8c\x9f\x9d\x77\x6b"
-  "\x6c\x31\xb3\xf3\x24\x5b\xcc\xb3\xeb\xdd\xae\xbf\x93\xd9\xd8\xff"
-  "\x10\xea\xde\xc6\xfe\x07\x61\xfd\xdd\x1f\x42\x3d\xee\x09\xe9\xf4"
-  "\x4d\xf3\x8f\x8b\x98\x8d\xbd\x17\x7b\x42\x2a\x7f\x6e\xb6\x98\x3f"
-  "\x7a\xf4\xff\xe5\xc9\x16\x43\xd7\x36\x9f\xc3\xf5\x21\xde\xed\x09"
-  "\xe9\x0e\xdb\x1d\xdc\xbd\x8b\x6f\x98\x72\x6c\xd7\x2d\x92\x63\xbb"
-  "\x6e\xb1\x1c\xdb\xe7\xac\x94\x63\xfb\x1c\xbd\x2b\xb6\x77\xc6\x75"
-  "\xdd\x51\x77\x98\xae\x7f\x06\x6d\x31\x73\x34\x9e\xf1\x5c\x57\xed"
-  "\x3d\x9e\x3f\x77\xe5\xff\x34\x9e\xab\x5d\xf1\xfc\x79\xed\x4f\x6a"
-  "\x97\xa1\x78\xfe\xc2\xdd\x32\x3c\x57\x77\x83\xe7\x3f\x99\x5d\xe6"
-  "\x85\xd5\x72\x3c\x7f\x21\x5f\x8e\xe7\x2f\xcc\x95\xf0\x5c\xb8\x76"
-  "\x43\xec\x32\x2f\xc4\xde\x1a\xbb\xcc\x0b\xb1\x12\x67\x9f\xf3\x74"
-  "\xf7\x78\xae\x6b\x70\x8f\xe7\x90\x4e\xf1\x5c\xd7\xe0\x71\x3d\x75"
-  "\x27\x3c\x9f\xfb\x90\x17\x78\xee\x76\x8d\xca\xcf\xc3\x2e\x33\x37"
-  "\xc2\x5b\xbb\x8c\xa7\x7d\x2a\x88\xef\xd2\xfa\x14\xa7\x7d\x2a\x91"
-  "\xe2\x3e\x95\x14\xf9\xfa\x94\x1b\x8e\xed\xf3\xc6\xcb\xb1\x7d\xde"
-  "\x64\x39\xb6\xbf\xb8\x40\x8e\xed\x2f\x46\x89\xf5\x64\x76\x99\xd4"
-  "\x4e\xfb\x56\xe4\x38\x3f\x6f\x9f\xe1\x99\x6a\xe2\x0e\xeb\xa1\xac"
-  "\x40\xcf\x38\x3f\xaf\xc4\x13\xce\xe3\x7a\x95\xf7\xe6\x45\xbb\xc1"
-  "\xf9\xf9\xe7\xfe\x37\xe0\xbc\xa7\x75\x28\x54\x0f\x02\x8c\x47\xbc"
-  "\xa7\xf8\x2e\x60\x3d\xe2\xbc\xfd\x43\x77\x36\x9a\x28\xf5\xcd\xc2"
-  "\x79\xcf\x36\x9a\x05\xfd\xcb\xe6\x08\x38\xdf\x93\x3d\x34\x27\xe4"
-  "\x36\x9a\xec\x25\x37\xdb\x46\xb3\x60\x91\x1c\xef\x17\x64\xc9\xf1"
-  "\x7e\xc1\x34\x09\xef\x85\x6b\x37\x84\xbf\x2f\x58\x78\x6b\x6c\x34"
-  "\xf0\x3c\x07\xde\xbf\x38\xbe\x7b\xbc\x9f\x57\xe1\x1e\xef\xe7\x09"
-  "\xbe\xd9\xe6\x55\xf4\x1c\xef\x5f\x72\xe0\x7d\xe7\xfd\x33\x29\xbd"
-  "\x5f\x23\x33\xfe\x56\xdb\x68\x5e\xf2\x88\xff\x5d\xf9\xc7\xe8\xbd"
-  "\x8d\x46\xd8\x93\xf8\xa2\x7b\xff\x18\xa7\xbb\x58\x23\x73\xba\xc4"
-  "\x19\xeb\x17\x8e\x92\xaf\x45\x5c\xf8\x90\xb8\x16\xf1\x74\x19\x62"
-  "\x7d\xf4\x73\x72\xac\x8f\xd6\x79\xb2\xd1\x1c\xe5\x9c\xd7\x24\x2e"
-  "\xdc\x22\xb7\xd1\xe4\xca\x6d\x34\xd3\xb1\xef\x45\xdf\xe6\x19\xeb"
-  "\x17\x16\xca\xd7\x80\xb3\x3d\x8a\xfb\xe7\x09\x6b\xc0\xe7\x39\xad"
-  "\x01\x7f\xea\x2f\x02\xd6\x2f\x3a\x57\x5c\x6e\x23\xde\xac\x43\xfc"
-  "\xf1\x6b\xbd\x37\xb9\x5d\x83\x48\xe7\x80\x2e\xd6\x21\xce\x3f\xaf"
-  "\x26\x9c\x72\x17\xda\xdf\xa5\x75\x88\x80\xff\x6f\x29\x5d\xfc\x17"
-  "\xbb\x5b\x87\x38\x4f\xef\x11\xff\xdb\x78\x09\xff\xb9\xff\x27\xd9"
-  "\x6d\x38\xe4\xf9\x54\x2e\x2f\xab\x6f\x96\xdd\xc6\x9d\x9d\xc4\x30"
-  "\x01\xf1\xff\x95\x3e\x8c\xe7\x47\xff\xcc\xec\x36\xaf\xcc\x95\xe3"
-  "\xfe\x2b\x19\x72\xdc\x7f\x65\xb2\x84\xfb\xc2\xb5\x1b\xb2\x16\xfd"
-  "\x95\x39\xb7\x86\xe7\xbf\x32\x47\xb2\xdb\x44\x3f\xd6\x3d\xee\x2f"
-  "\x34\xb8\xc7\xfd\x85\x06\x86\xfb\x0b\x0d\x5d\xda\x6d\x64\x6b\x23"
-  "\x17\xdf\xfd\xa3\xed\x36\x22\xcf\xbf\xe5\xfb\x7a\x16\x87\x7a\x63"
-  "\xb7\x71\xec\x49\xff\x51\x76\x1b\xf7\x78\x2f\x72\xfb\xd3\x5d\x7c"
-  "\x73\x95\xe3\xfd\x92\xbb\xe5\x78\xbf\x64\xa8\x1c\xef\x97\x8f\x93"
-  "\xe3\xfd\xf2\xb1\xee\xec\x36\x72\xac\x5f\xb2\xd2\x1d\xce\xeb\xa7"
-  "\xa3\xdd\x66\x59\x83\x67\x8c\x5f\x92\xed\x3d\xc6\xff\xe9\xe8\x3f"
-  "\x31\xde\x05\xe3\xd5\xae\x18\xff\xa7\x96\x9f\x94\xe3\x53\x8c\x5f"
-  "\xfa\x9d\x0c\xe3\x6f\xa0\x2d\xa7\x27\xfb\x49\x3c\x73\xfb\x65\x2e"
-  "\xeb\xdf\x97\xb9\xac\x7f\x5f\xe6\xb4\xfe\x7d\x59\xec\x8d\xc3\xf8"
-  "\x65\x91\xb7\x06\xe3\x97\x39\xad\x7f\x5f\x7e\x77\xf7\x18\xbf\x24"
-  "\xcf\x3d\xc6\x43\x3a\xc5\xf8\x25\x79\x5d\x72\x7b\x19\xc6\xaf\x50"
-  "\xdc\x0c\x5b\xce\xad\xd9\x6f\xb4\x82\x78\x63\xcf\xe9\xca\xef\x88"
-  "\x47\x7b\xce\x18\xd1\x9e\xa3\xf7\x60\xcf\xb9\x51\x98\xaf\x0f\x94"
-  "\x63\xbe\x7e\x90\x1c\xf3\x63\x27\xcb\x31\x3f\x76\x92\xdc\x9e\x13"
-  "\xd3\xc9\x9e\x23\xc7\x7f\xfd\x6a\xc3\x74\x67\x7b\x4e\xae\x93\x3d"
-  "\x67\xd5\x35\xcf\xf8\xaf\xf7\x88\xff\xd7\x29\xfe\x47\xb9\xc1\xff"
-  "\x95\xff\x47\xf0\x3f\xea\x47\xe0\xff\xca\x5b\x80\xff\x31\x8d\xcc"
-  "\xc6\xd3\x43\x3f\x29\x47\xbd\xb7\xf1\xfc\xb8\x79\x60\xd5\x93\xf2"
-  "\x79\x60\x55\xa2\x7c\x1e\x58\xf5\x90\x34\x0f\x08\xd7\x6e\xc8\x3c"
-  "\xb0\x6a\xca\xad\x99\x07\x56\x4d\x91\xe6\x81\xd8\x61\xdd\xcf\x03"
-  "\x7a\x0f\xf3\x80\x5e\x98\x07\xf4\x5e\xcc\x03\xab\x07\x79\xb6\xf1"
-  "\xe8\x7b\x6f\xe3\x79\xec\x56\xef\x83\x5a\x1d\xe4\x95\x8d\x67\xe7"
-  "\x44\x73\x09\xfa\x48\xb9\x4c\x94\x6b\x17\x88\x36\x1e\x83\x8b\x8d"
-  "\xc7\xd0\xc9\xc6\xb3\xe6\xb2\x80\xff\x53\x85\xfd\xa6\xd3\x7f\x84"
-  "\x8f\x14\x8c\xa1\xac\x88\x0b\x94\xaf\x9b\x8f\xa3\xf8\x2f\xf9\xef"
-  "\x5b\xb3\x17\xeb\xc5\xe6\x1f\x43\x17\x3e\x50\xe3\x16\xc8\x6c\x3a"
-  "\x53\xdd\xf9\x48\x59\x23\x5b\x77\x23\xdf\x6f\x1a\xb7\x59\x86\xf7"
-  "\xd3\xd9\x7e\xd3\x77\xdd\x7d\xa7\x75\xf8\xe4\x7f\x75\x37\xf5\xc9"
-  "\xef\xf0\xe5\x17\x57\xde\x23\x5f\xd2\xf3\x04\x5f\xd2\x5f\xdf\x02"
-  "\x5f\xd2\x3d\xf5\xc9\xff\xb5\xab\xff\xbe\xf8\xc7\x8c\x25\x06\x52"
-  "\x86\x7d\x64\x8e\xab\xef\x53\x83\xfb\xbd\xfb\x4a\x61\xef\xfe\xf2"
-  "\x9b\xe3\x07\x05\xeb\x43\xe7\xfc\x81\x6f\x98\x0f\x26\x59\x68\x7d"
-  "\x30\x5e\x35\xd4\xf5\xa3\x12\xe8\xab\x1c\xe2\x69\x0c\xe2\x69\xbc"
-  "\x85\xe6\xbd\x0c\x7d\x61\xe0\x5d\x66\xec\xc7\xe9\x1c\xf1\xd7\xc7"
-  "\x21\xb6\xc6\xd3\x75\x5f\x40\x23\x00\x5b\x59\xbe\x75\x97\x79\xbb"
-  "\x7d\xe0\xfd\x18\x6f\xb5\xef\xa1\xe5\xe5\x7d\xca\xcc\x2d\x30\x2e"
-  "\xea\x71\x4f\xac\xc2\x68\x6b\x35\xa0\x2c\x8e\x2f\x2f\x57\xf1\x80"
-  "\xbf\x7b\x5e\x26\x7e\xde\x8d\xd3\xf8\x63\x94\xcf\xe0\xbc\x37\xf0"
-  "\x8d\x06\xf4\x03\x22\x72\x2b\xee\x07\xc9\xbe\xb5\x1b\xda\x87\xe3"
-  "\xd9\xdc\x37\x7f\x31\xc3\x0d\x1e\xe6\x6b\x68\x4b\xba\xc6\x16\x71"
-  "\x83\xc6\xae\x02\xdc\xc8\x69\x92\xbe\x63\x63\xf9\xd8\x46\xcc\x8e"
-  "\xb2\x46\x5a\xff\x62\xf6\x84\xad\x71\x99\xee\xb1\x35\x2e\x93\x61"
-  "\x6b\x5c\xa6\x03\x5b\xcd\x6e\xec\x28\xb2\x75\xec\x09\xc2\xfa\x17"
-  "\x83\x0b\xc7\x36\xfc\x02\xfd\xa3\x24\x78\xb5\xfe\x85\xe2\xe9\x52"
-  "\x86\xa7\x88\x57\x22\xa6\x4a\x76\x14\x83\x47\x3b\x4a\x77\x98\xea"
-  "\xd5\x1e\x7e\x8a\xa9\x6b\x17\xc9\x31\x75\xed\x62\x39\xa6\x26\x7d"
-  "\xe7\x8a\xa9\x9d\xf1\x74\xed\x7e\x77\x58\xca\xfc\xa3\x24\x65\x79"
-  "\xc6\xd1\xb5\x15\x9e\x70\x94\xae\x4f\x9f\xe7\xb4\x3e\xdd\x81\xa3"
-  "\x89\x35\x72\x1c\x4d\x0c\xe9\x29\x8e\xd2\xd8\x26\x5f\xff\x04\xb1"
-  "\x4d\x7a\x8d\xa3\x7a\x17\x1c\x5d\xb7\x5e\xc2\x51\xd7\xf8\x26\xdd"
-  "\xe0\xe8\x92\x9b\xe3\x03\x45\x86\xa3\x9c\x85\xd6\x47\xb3\x1c\xeb"
-  "\x9a\xd4\x47\x8e\xa3\x49\x63\x3c\xe3\xe8\xba\x73\x12\x8e\xb2\x7c"
-  "\x37\x17\x47\x93\x54\x32\x1c\x5d\xe2\x84\xa3\xdf\x4b\x3a\x04\xae"
-  "\xb1\x70\xe0\xe8\x32\x27\x1c\x5d\xd2\x1d\x8e\x26\xa9\xb0\x8d\x18"
-  "\x47\x4d\x3a\xdd\x3d\x8e\xae\xad\x74\x8f\xa3\x90\x4e\x71\x74\x6d"
-  "\xa5\x84\xa3\x6e\x38\xaa\x0c\x47\x93\x0f\x7a\x81\xa3\x3f\x73\xdf"
-  "\x28\xc9\x07\xbc\xb2\x55\x48\x7b\x3a\x3b\xfb\x48\x9d\xeb\xbc\x27"
-  "\xa8\xd0\x25\xee\x49\x61\xa7\xb8\x27\x6b\xc4\x3d\x9e\x53\x04\x5c"
-  "\x7d\xea\x47\xe0\x2a\xdd\xe3\x99\xf2\x91\x7c\xed\x49\xca\x09\x71"
-  "\xed\x09\xc3\xd5\x8d\xb3\xc5\x7a\x49\x71\x4f\x0a\xbb\xf0\x91\xba"
-  "\x3e\x50\xe6\x1b\x65\x8a\xb3\x6f\x94\x8d\x7d\x3c\xfb\x48\x5d\x3f"
-  "\x46\xe6\x1b\xe5\x4c\xbe\x23\xee\x89\xab\x8f\x54\x09\x63\x53\x9f"
-  "\xa4\x18\xeb\xf0\x41\xb5\x3e\xd1\xe1\x23\xb5\x9b\x7d\x41\x58\xce"
-  "\xa1\xaa\xe8\x9b\x8f\xb1\x06\x2f\x30\x56\x16\xf7\xc4\xd5\xc7\x54"
-  "\xea\x15\x63\x71\x21\x29\x8b\x2a\x74\xe3\x1b\xb5\xf0\x96\xc6\x3e"
-  "\xc1\x7a\xb9\xc7\xda\x0d\x2b\xe5\x58\xbb\x21\x8f\xe6\xbd\xe8\x0e"
-  "\x6b\x37\x8c\x97\xb0\x96\xe5\x5b\x77\xd1\x05\x6b\x2b\x3d\x60\x2d"
-  "\xcc\xab\x7b\x6a\xbd\xc5\xda\x0d\x34\x6e\x36\x97\x2a\x60\x6d\xfd"
-  "\x8d\xc6\xda\x0d\x7a\x09\x6b\x37\x3e\xd2\x7d\x8c\xa9\xf5\x91\xee"
-  "\xf7\xe5\xac\x8f\x64\x58\xbb\x3e\xb2\xcb\x18\x53\xb2\x35\x1f\xaf"
-  "\x0d\x13\x63\x4c\x49\xf6\x80\x42\xc1\x1e\xf0\x4b\x8e\x89\xf2\x5a"
-  "\x98\xb7\xf6\x80\xb3\xa0\xbb\xe3\xbe\xcb\xb5\x18\x73\x6a\x0e\xc6"
-  "\x44\x29\x70\xb1\x07\x14\x74\xb6\x07\x3c\xd7\x35\xc6\x7a\x65\x0f"
-  "\xa0\xfb\x2e\xd3\x86\xca\x31\x36\x6d\x98\x1c\x63\x5f\xff\x48\xdc"
-  "\x67\x89\xf5\xf1\xec\x33\x35\x6d\xa5\xc3\x1e\x50\x29\xc7\x56\xc9"
-  "\x1e\xf0\xfa\x32\xcf\x18\x9b\x26\xb7\xff\x3e\x95\x2f\xdb\x67\xf9"
-  "\x6e\x95\xb3\x1f\x6a\xd1\xff\xd4\xbf\x1d\x3d\x5d\xe1\x8c\xb1\x69"
-  "\xe6\x5f\x92\x1f\x6a\x87\xaf\xa9\x6e\xd6\x72\x77\xf6\x43\xbd\x69"
-  "\xb6\xb1\xb8\x80\xe0\xde\x36\x8a\xb7\x32\xdb\x40\xc1\xad\xb1\x0d"
-  "\x14\x17\x78\xb0\x0d\x6c\x3a\x2f\xc7\xd9\xd7\xfd\x69\xde\xf3\xee"
-  "\x70\x76\xd3\x7e\x09\x67\x59\xbe\x75\xe7\x5d\x70\xd6\x74\x23\x39"
-  "\xed\x26\xd3\xcd\xb5\x0d\x6c\x32\x49\xb6\x81\xd7\x7b\xb0\xff\x31"
-  "\x2d\xcf\x3d\xce\xa6\x09\x76\xd7\x34\xc9\xee\x6a\x72\x13\x2f\x45"
-  "\x86\xb3\x7f\x5e\x2f\xee\x7f\xa4\x9c\xb6\x52\xe4\xb4\x05\xbf\xc0"
-  "\x78\x29\x7f\x4e\xf1\xd6\x36\x80\xfb\xdc\x11\x5b\x11\xbb\x44\x7c"
-  "\x95\x6c\x03\x05\x9e\x6d\x03\xdd\xe0\xab\xf7\xb1\xfb\xde\x58\x2f"
-  "\xc7\xd7\x37\x5e\x93\xe3\xeb\xd6\x40\x57\x7c\xed\x8c\xad\x6f\x9c"
-  "\x72\x87\xab\xcc\x36\x90\x6e\xf0\x8c\xa9\x6f\x58\x3c\x61\x2a\xf5"
-  "\xe9\x57\x25\xad\x91\x96\x30\x75\x4b\x7f\x39\xa6\x6e\x7e\xb8\xa7"
-  "\x98\x7a\x4b\xe2\xa5\xf4\x1a\x53\xa3\x5d\x30\x75\xcb\x7e\x09\x53"
-  "\x5d\x63\xa6\x74\x83\xa9\x37\xcb\x4e\xe0\x8c\xa9\x32\xee\x9a\x3e"
-  "\x4a\x8e\xa9\xe9\x51\x9e\x31\x75\x8b\x5d\xc2\x54\x96\xef\xe6\x62"
-  "\x6a\x7a\xf8\xcd\xb5\x13\xa4\x87\x4b\xdc\x35\xbd\xb1\x7b\x4c\x7d"
-  "\xc3\xea\x1e\x53\xdf\xb0\x32\x4c\x7d\xc3\xda\xf3\x3d\xe5\x5b\xcf"
-  "\x79\x81\xa9\x3f\xf3\x58\x2a\x5b\x2b\xbc\xb6\x13\xa0\xbd\x15\xb1"
-  "\xb4\xf2\xc7\xf9\x0e\x89\x17\x7d\x87\x4c\x12\x30\xf6\x89\x1f\x8b"
-  "\xb1\x19\x35\xf2\x35\x0d\x19\xdf\x89\x6b\x1a\x18\xc6\x66\xbe\x2e"
-  "\x8f\x8f\xda\xd9\x57\x88\xdc\x87\xea\xb6\xc7\x1c\x76\x02\xc4\xdc"
-  "\x49\xce\x76\x82\xcc\xc7\x3c\xe3\xed\xb6\x28\x99\x9d\xe0\x53\xf7"
-  "\x78\x7b\x5d\x86\xb7\xdb\xd7\x51\xbc\x75\xf8\x50\xdd\x96\x27\xfa"
-  "\x50\xed\x96\xc3\xca\xf0\x36\xea\xa7\xc1\xdb\xc2\x9e\xe3\xad\x3c"
-  "\x96\x8a\xab\xbf\xd4\x37\x87\x1a\x8b\x00\x6f\xa9\xbf\x0e\x57\x9f"
-  "\xa9\x3d\xf3\xd7\x71\xb3\x7c\xa6\x62\xbd\xdc\xe3\xee\x9b\xfb\xe4"
-  "\xb8\xfb\xa6\x89\xe6\x75\x8b\xbb\x6f\xae\x96\x70\x97\xe5\xeb\x31"
-  "\xee\xf6\xca\x66\xf0\x66\xde\xcd\xb5\x19\xbc\x99\x27\xe1\x6e\xe6"
-  "\xe2\xee\x71\x77\x5b\xb4\x7b\xdc\xdd\x16\xcd\x70\x77\x5b\x74\x97"
-  "\xb8\x2b\x5b\x43\xb0\xe3\x39\xb7\xbe\x3c\x2a\x7f\xe9\x71\x56\x76"
-  "\xe8\x7a\x63\x33\x00\x0c\x56\x26\xa2\x0f\xa7\x28\x5c\x43\xd0\xbd"
-  "\xcd\xa0\x3b\xbc\xf5\xde\x66\xb0\x73\xb6\x1c\x6f\x77\x3e\x27\xc7"
-  "\xdb\xb7\xfa\x60\xbd\xba\xb4\x19\x50\x0c\xd8\xb9\xcf\x61\x33\x30"
-  "\xcb\x71\x56\xb2\x19\xec\x7a\xdf\xf3\xb7\xaf\x9d\xe5\x32\x7e\xfb"
-  "\x84\x8b\xcf\xea\x79\x12\xde\x9e\x29\x13\xd7\x8c\x65\x29\x4e\xcf"
-  "\x74\xc6\xdb\x7f\x0f\xea\xe4\xb3\x7a\xd6\x0d\xf4\x59\x3d\xeb\x06"
-  "\xfb\xac\x9e\x2d\xf7\x59\xfd\xd6\x75\x69\x1d\x99\xf7\x3e\xab\xb3"
-  "\x76\x53\x0c\xc6\x3e\x84\x7e\xab\x7b\x62\x47\xb8\xc9\xb1\x56\x64"
-  "\xd8\x2b\xb3\x23\xec\x1a\x2a\xc7\xde\x5d\xb3\x3c\x63\x6f\x56\xa3"
-  "\x84\xbd\x2c\xdf\xcd\xe5\xbc\xbb\x34\x37\xd7\x8e\xb0\x4b\x23\xd9"
-  "\x11\x76\xd5\xb8\xc5\x5e\xd9\xb7\xb1\x9d\x26\xf7\xdf\xc6\x20\x9d"
-  "\x62\xef\x4e\x93\x47\x3b\x42\xa7\xf5\x5b\x6f\x9d\x66\xdf\xc6\x04"
-  "\xce\x6b\xf6\xc2\x8e\xf0\xb3\x5b\x63\xf0\x56\x71\x6f\xec\x08\x88"
-  "\xb7\x88\x67\x22\xe6\xf6\xc4\x8e\x70\xe3\x39\xee\xdb\xa7\xe5\x98"
-  "\xfb\x76\xa9\x1c\x73\xf7\x2c\x73\xc5\xdc\xce\x78\x9b\xdd\xdf\x1d"
-  "\xd6\x32\x3b\xc2\x9e\x50\xcf\x38\x9b\x3d\xc6\x23\xce\xba\xac\xcd"
-  "\x95\x70\x76\xf7\x62\x39\xce\x66\x27\xf6\x0a\x67\x7b\x1a\x83\xe5"
-  "\x67\x85\xb3\x51\x2e\x38\x9b\xd3\x47\xc2\x59\xd7\x38\x2c\xdd\xe0"
-  "\xec\x4d\x8a\xc3\xe2\x99\xe3\xe6\xbc\x2e\xc7\xd9\x9c\x63\x9e\x71"
-  "\x36\xe7\x39\x09\x67\x59\xbe\x9b\x8b\xb3\x39\x9b\x6e\xae\x6d\x21"
-  "\x67\x93\xc4\x71\xf7\x4c\xeb\x1e\x67\xb3\x23\xdd\xe3\x6c\xb6\xf0"
-  "\x5d\x2c\x3b\xd2\x23\xc7\xed\x84\xb3\xb9\x0f\x79\x81\xb3\x3f\xf3"
-  "\x35\x08\xb9\x5e\xf9\xbf\x70\xb2\xd7\xfa\x1a\xcd\x2e\xfb\x25\xce"
-  "\x3b\xef\x97\x70\xb2\x2d\x4c\x12\x6d\x0b\xf2\xf8\x2c\xf1\xa2\xfd"
-  "\x36\x52\xc0\xdd\x09\x3f\x16\x77\xf7\x8e\x6f\x75\xe0\x6e\x0c\xe0"
-  "\xee\x5e\xba\x3f\xa2\xd5\x81\xbb\x79\x6d\x62\xbd\xa4\xf8\x2c\x1e"
-  "\x6c\x0b\x8f\xd3\xf2\x76\x38\x6c\x0b\x88\xc3\x91\xce\xb6\x85\xbc"
-  "\xfd\x9e\x31\x78\xef\x31\x99\x6d\xe1\x13\xf7\x18\xdc\x22\xc3\xe0"
-  "\xbf\x5c\xa1\x18\xfc\xb8\x88\xc1\x7f\x21\xd7\x41\xb7\xbc\x9e\xe6"
-  "\x1d\x06\xb7\x50\x0c\x9e\x72\x6b\x30\xf8\xc8\x0d\xc0\x60\xda\xee"
-  "\xff\xb1\xcd\x68\x00\x0c\x9e\x83\x18\x3c\xa5\x67\xf6\x86\x9f\x28"
-  "\x46\x0b\xd6\xcb\x3d\x16\xe7\x0d\x92\x63\x71\xde\x14\x9a\xd7\x2d"
-  "\x16\xff\x47\x8d\x84\xc5\x2c\xdf\xcd\xb5\x37\xe4\x05\xdd\x5c\x7b"
-  "\x43\x5e\x90\x84\xc5\x79\xe7\xbb\xc7\xe2\xbd\x45\xee\xb1\x18\xd2"
-  "\x29\x16\xef\x2d\xea\x12\x8b\x1f\x77\xc6\xe2\x7d\x0e\xce\x2b\xb3"
-  "\x37\x98\x7f\xe9\xb1\x5b\xf6\x79\xe4\xbf\x9a\x7b\x48\x4a\x95\xe2"
-  "\x9d\xa1\xc6\x6c\x42\x9a\x53\x49\x8a\xd1\xf6\x38\x81\x34\x68\xbf"
-  "\x77\x9e\x34\x86\x8c\x21\xdc\xf6\x70\x2d\xe2\xf1\x9b\xf8\x03\x8e"
-  "\x9b\xa1\x14\xc6\x16\x6d\xe3\x77\xe8\x7a\x57\x4c\x47\xec\xdd\xe3"
-  "\x74\xdd\xdd\xb3\xf8\x8c\x91\x79\xc2\x7d\x79\x6c\xdf\xcd\xc8\x7c"
-  "\xf1\x1c\xfb\xa6\x59\xf1\x4e\x3e\xbf\x6d\x64\xae\x25\x70\x64\xae"
-  "\xbb\xfb\xef\x53\x13\xbf\x01\xeb\x79\x3e\x67\x27\xdf\xd2\xfc\x40"
-  "\x78\x79\xf3\x9f\x09\xc9\xd8\xc9\x5b\x5a\xd3\xde\x31\xc3\xbd\x7e"
-  "\xff\x0e\xf9\x9a\x07\xe6\x1a\x9a\x53\x67\x12\x48\x6b\x11\xd3\xa0"
-  "\xdd\x08\x97\xea\xc3\x73\x70\x8d\xdf\x6e\x39\xb0\x27\x09\xb0\x2a"
-  "\x91\x90\xd1\xd7\x71\xcc\xfc\xa7\x0a\xfa\x4c\x50\x3a\x94\xb9\x15"
-  "\xca\xe2\xef\xbc\xab\x05\xfa\xa3\xaa\x6c\x23\xc1\x31\xbd\x09\xde"
-  "\x2b\x37\x1d\xdb\xde\x67\x44\x16\xaf\x54\x11\x6e\x5f\xa8\x96\x1f"
-  "\x34\xc9\x0c\xf2\x20\x19\x31\xc4\x0f\xdf\x63\x2b\xe4\xe3\x95\xc9"
-  "\x3c\x37\x6c\x48\x81\xd1\xd6\xc2\xc6\x34\xd4\xef\x38\xe8\xb1\x3c"
-  "\x3c\x37\x27\x86\xa8\xe1\xe7\xcf\xef\x98\x64\x6e\x4d\xfb\xcf\xcd"
-  "\x50\xaf\x58\xac\x97\xa7\x77\xdc\xfa\x16\xcc\x3b\x77\x85\xe0\xdc"
-  "\x41\x9f\x8f\xcf\xa6\xcf\x51\x72\x9b\xec\x90\xce\xa7\x26\xf3\xc6"
-  "\x78\x1b\x09\x80\xb6\xd8\x03\xf5\xc6\xfe\xc8\xbd\x13\x5e\xbe\x61"
-  "\x08\x21\x87\x12\xea\x94\x46\xa8\xbb\xfd\xdf\xef\x6a\x31\x24\xfd"
-  "\x0b\x81\xeb\x16\xd4\x59\x6a\x15\xf9\xaf\xcf\xf8\x8e\x10\xc4\x13"
-  "\xf8\xbf\xa3\x05\xe6\xb1\x69\x70\xbe\x15\xde\x83\x6b\x0e\x51\x61"
-  "\x5e\x48\x1f\x6f\x88\xbb\x40\x02\xf4\xc4\x2f\x1d\xde\x4d\xc8\xab"
-  "\xc6\xbc\x66\x45\x7e\x26\xd6\x01\xce\xc3\xe0\x1c\xef\xc3\x35\x64"
-  "\x84\xcf\x0b\xd5\xd2\xbe\x99\x39\xc9\xcc\x0d\x0b\xd5\x52\xec\x83"
-  "\xf7\xdc\x0a\xef\x0c\x79\xfc\x21\x8f\x3f\x3d\x26\x11\x75\x26\xa4"
-  "\x61\x39\x70\xf4\x37\x2c\x6f\xc7\xb2\x09\x96\xed\xa1\x1d\x54\x7c"
-  "\xd0\x24\x33\x0f\x7d\x1b\xe7\x54\x4d\x92\xe2\xb3\x2a\xc5\xfe\x87"
-  "\x03\x14\x3c\x0f\xe3\xbc\x60\x43\x12\xf1\xcf\xe0\x08\x31\x0c\xc1"
-  "\x72\xf6\xf7\x87\xf2\x55\xd8\x16\xad\x69\xf9\x0d\x66\xc5\x7f\x66"
-  "\x61\xfb\x82\x3c\x5b\x34\xf7\xe1\x3b\xec\x9f\x84\xcf\xc1\x7b\x58"
-  "\xfe\x7c\xea\xfb\x1e\xeb\xac\x49\xf2\xe1\xe1\xfa\x28\x1f\xc5\x65"
-  "\xe2\x13\xe2\xff\x7c\x6b\xda\xfe\x70\x33\x59\xa4\xc7\xfb\xcd\xec"
-  "\x3e\xe8\x4b\xfb\x23\x41\x66\x47\x30\x0d\xcf\x3d\xd4\xd7\x5f\x94"
-  "\x5b\x69\x08\xf4\x0d\x57\xd9\x89\x7d\x04\xfa\x85\xd8\x47\xb0\xbe"
-  "\x87\x93\xcc\x4a\x3a\x0f\x2b\xf6\x53\xbd\x2e\x1d\x64\x68\x7f\x3b"
-  "\x44\xb5\x15\xda\x96\xeb\x40\xb9\x54\xc1\xb5\x77\x5f\x43\xb9\x6c"
-  "\x4d\x00\x99\xb0\xbc\xf9\x52\xfd\xf1\xfc\x5d\x2a\x4f\x0e\x64\xc1"
-  "\xf6\x6e\xbe\xfb\x1c\xbe\xcf\xd6\xeb\x20\xc7\x60\xbe\xa5\x28\x1e"
-  "\xea\x85\xfd\x16\xfa\xc8\xa1\x18\xab\x12\xd7\xf5\x61\xfa\xf1\x26"
-  "\xab\x72\x6b\x3d\x41\x5e\x49\xb6\x00\x2e\xef\x8e\x83\x36\x87\x32"
-  "\xf9\xb0\x21\x05\x0f\x8a\x72\x4c\x00\xd9\xc5\x41\xdf\x85\x36\xdf"
-  "\x0a\xed\x97\x03\x98\x87\xff\x73\x60\xfe\xe1\x20\x9f\x59\xf1\x6e"
-  "\x26\x94\xa7\xde\x1d\xcc\x5b\xf6\x04\xf3\x0d\xd0\x86\xcb\x5b\xd3"
-  "\xde\xd5\x8b\x6d\x88\x75\xda\x0a\xe9\x5b\xe0\x3a\xb4\x67\x03\xeb"
-  "\x43\xfb\x8f\x89\xef\xec\xa9\x3d\x37\x1f\x22\x63\xb6\x1c\x22\xa1"
-  "\x7f\x3e\x44\xc6\x26\x2e\x84\x71\x99\xfa\x3b\xfe\x6c\x94\x0d\xe6"
-  "\xc4\xd7\x8a\xdb\x83\x47\x19\x90\x1f\x72\x1b\xee\xca\x7d\xed\x10"
-  "\x09\x3f\x38\x2f\x57\x39\x03\x4a\xc6\x39\x7c\x46\x9f\x4b\xbc\x51"
-  "\x7f\x8d\x70\x81\xaf\x15\xdb\x37\x8c\x18\x38\xfd\x1a\x21\xa7\xb4"
-  "\x2d\x24\x29\x16\xe6\xf2\xa6\x3a\x92\xd4\xc2\x5b\xca\x52\xbe\x23"
-  "\x80\x3d\x59\xac\xed\x0e\x84\xcd\x58\x44\x08\xee\x19\xe4\xbe\xd7"
-  "\x92\xfe\xd1\x44\x95\x78\x9e\x84\x24\x57\xf3\x75\xf6\x9d\x8f\x17"
-  "\x24\xad\x23\xca\x43\x4d\x26\xc6\x3d\x15\xef\x5d\xfb\x08\x9e\xc5"
-  "\xb7\xea\xc8\x7c\x9b\x30\x1f\x65\x4e\xaa\x4b\x5e\x4c\x06\xe3\xfb"
-  "\x04\x50\xee\xf5\xde\x6e\x68\xb7\x3a\xef\xf0\xf9\xbd\x68\x86\x87"
-  "\x8d\xe5\xc9\x8b\xf8\x3a\x98\x53\x94\x7c\xf2\x42\x05\xaf\xd1\x99"
-  "\xf8\x6d\x8d\xe5\x46\xd5\x75\x62\x8c\x6e\x21\x1f\xc3\xb3\xbd\x2c"
-  "\xd7\x40\xe7\x6a\x9c\x3f\xa1\xbe\xb3\xb5\x24\x85\xd6\x19\xe6\xc9"
-  "\x80\x58\xe4\x50\xfc\x25\xac\xf3\x71\x78\x3f\x7e\xa8\x0e\xfa\xf8"
-  "\x7b\x33\x71\xce\x9c\x61\x36\x90\x12\xab\x9d\xbc\x55\x4f\xdb\xc5"
-  "\x17\xda\x45\x05\xd7\xc2\xa0\x6d\xfc\xdc\xc9\x0a\xe5\xc4\x65\xbc"
-  "\x56\xcc\xf9\x30\x79\x50\x59\xb4\x30\x59\x4c\x5f\x49\x60\xee\x04"
-  "\x79\x6c\x63\xf2\xe0\x06\x4d\x34\xa0\x3c\xbc\x7b\x8f\x03\x9b\x3c"
-  "\xcd\x29\xf8\x6c\x1e\xfa\x04\xf6\x05\x2e\x68\xa2\x01\x9f\x8d\x75"
-  "\xc0\x6f\x66\x28\xfb\x19\xaf\x5d\xe2\xcb\xf4\x75\xc4\x08\xef\xc3"
-  "\x07\x3a\xd7\xc1\xe6\x65\x1d\x0e\x7a\x8c\x7f\xb6\x79\x34\xf4\xd5"
-  "\xd1\xd0\x57\x47\x93\xb1\x6b\xcd\xac\xaf\x9e\xa9\x64\x7d\xd5\x0e"
-  "\xf5\x6a\x03\xbe\xbe\x76\x36\x51\x62\xbd\x0e\x5c\x40\xbf\x7c\x50"
-  "\xcf\x3a\xa9\xbf\x4e\xbb\x02\x6d\x24\xf6\x59\x9f\x11\x03\xb1\x7d"
-  "\xca\x5a\x4c\x24\x19\xfb\x6c\xbb\xbb\x3e\x7b\xc8\x34\x63\x01\xc8"
-  "\xe6\x15\xe8\xb3\xdf\x6a\x89\x7f\x35\x51\xad\x9b\x0d\x7d\xb6\xce"
-  "\x5d\x9f\x3d\xb4\xff\x18\x3c\xb3\x53\x9f\x5d\xe4\xdc\x67\x0f\x3d"
-  "\xed\x7d\x9f\x3d\x14\xea\xe8\xb3\x8b\x3d\xf4\xd9\x85\xd0\x67\x9f"
-  "\xcf\xf2\xb2\xcf\x1e\x8a\xf5\xae\xcf\x1e\x52\xd1\x3e\x5b\x09\x7d"
-  "\x16\xf4\x8f\xb7\x5e\xa6\xed\xe2\x0b\xed\x02\x7d\xf6\xa0\x09\xda"
-  "\xc6\x6d\x9f\xfd\xe9\x65\x56\xb0\xb9\xe7\x32\x2b\x98\xdb\xbd\xcc"
-  "\x0a\xfa\x78\x2f\xb3\xc3\xe5\x37\x47\x66\x05\x5a\xef\x64\x76\xb8"
-  "\xd0\xb3\xcc\x0e\x6f\xfe\xf9\xc8\xec\xbf\x22\x7b\x2e\xb3\xff\x0a"
-  "\xec\x5e\x66\x7f\x3d\xea\xbd\xcc\xfe\xba\xf1\xe6\xc8\xec\xaf\x95"
-  "\xde\xc9\xec\xaf\x4b\x3d\xcb\xec\xaf\x91\x9e\x64\x36\x71\x30\xc7"
-  "\x73\xb8\x0e\x2e\x78\x84\x06\x39\x0d\xe3\x5f\x7f\xeb\x8f\x3a\x20"
-  "\x9c\xab\xc4\x73\xca\x91\x40\x4f\x76\x39\xf7\x77\x39\x57\xbb\x9c"
-  "\x07\xb9\x9c\x87\xb8\x9c\x87\x8a\xe7\x20\xa3\x3e\x57\x15\xff\xb5"
-  "\x0e\x74\xb0\x14\xb3\xe2\x6f\x21\xc2\xf5\xb0\xf9\x76\x0d\xea\x71"
-  "\x61\xee\xea\xbe\x35\x95\xb7\xea\x93\xc8\x5d\xf5\x8a\xbf\x31\x19"
-  "\x6c\x18\xa2\xe5\x13\x52\x08\x97\xd1\xa4\x9a\xbe\x0e\xfb\x92\x85"
-  "\xf0\x1d\x21\xbe\xd0\x4e\x77\x82\xfe\x68\xc1\x7e\xa6\x89\xf9\x98"
-  "\xaf\x52\xfc\x6d\x25\xbe\xdf\x68\xbd\x81\x70\x3e\x23\xb4\xa8\xdb"
-  "\x70\xdb\x9a\x54\x16\x9f\x11\x43\x40\xbf\x2c\x4f\x57\x72\x7e\xe9"
-  "\xa9\x9c\x66\x9d\x85\xb7\x4c\x6d\x84\x39\x0a\xe6\x29\x63\x83\x15"
-  "\xfa\x21\x6f\x31\xc4\x5c\xc1\xfa\x9e\x2f\x4d\x84\xb2\xe1\x39\xf0"
-  "\x2c\xc2\xab\x1b\xab\x8d\xb6\x72\xc2\x43\x19\x65\x2d\xc5\xa0\xcb"
-  "\x9b\x88\x50\x26\xcc\x69\x8d\xd5\x58\xa6\x5b\x7d\x2b\x73\xc4\x2c"
-  "\x78\xe6\xe3\xb3\xb5\x2a\xc2\xaf\x57\x05\x79\xd7\x3f\xfe\x66\xf3"
-  "\xa8\xc7\x65\x8e\xa8\x60\xe5\xfa\xf5\xa2\xdc\x23\xb3\x3c\x97\x3b"
-  "\x52\xa8\xaf\xba\x37\xe5\x7a\xdc\xff\x04\xe5\x0a\xf5\xd5\xf4\xa2"
-  "\xdc\xf7\x55\x9e\xcb\x0d\x17\xea\x1b\xd9\x9b\x72\xe7\x74\x51\xae"
-  "\x50\xdf\x94\xde\x94\x7b\xa4\x0b\xb9\xcd\xea\x5d\x5f\xf8\x6f\xbf"
-  "\xae\xfa\x42\xef\xfa\xc1\x7f\x77\xf1\xfe\x23\x67\xf5\xae\x0f\xfc"
-  "\x77\x41\x57\x7d\xa0\x77\xf2\xff\x9f\x2e\xe5\xdf\x3b\xd9\xff\x8f"
-  "\xc7\xf5\x1f\x28\xfb\xde\xc9\xfd\x7f\x3c\xf6\x7f\xd4\x4d\xf9\xcc"
-  "\xe1\x16\x3e\x58\x17\xc1\x6d\x6f\xb3\x70\xc1\xc3\x9b\x36\x70\x91"
-  "\x64\x22\x60\x58\x40\x16\x09\x8c\xa4\xf6\x9e\xc2\xc8\x75\xd9\x44"
-  "\x99\xa1\xe4\x94\x07\x13\x4c\x4a\xa3\x6d\x0c\x49\xb6\xf1\xf6\xbc"
-  "\x38\xab\xe2\x7e\x48\x3f\x01\x1a\x4a\xcb\x2a\x2d\xa1\xe5\x0c\x6c"
-  "\xb3\xa4\x27\x45\x92\x19\x76\x82\xf6\x85\x96\x93\x89\x80\x61\x80"
-  "\x63\xc6\x2c\x2b\xce\x73\x81\x70\x9f\x0d\xfa\x2f\x94\x61\x25\x87"
-  "\x39\x8b\x22\x32\x86\xe6\xb3\x80\x1e\x68\xe1\x77\x0e\x6f\xe2\x93"
-  "\xb5\x64\x23\xfc\x87\x67\xee\xf7\xb1\x10\x65\x0e\xe8\x87\xad\x69"
-  "\x85\x79\x66\xc5\xd1\x14\xd4\x19\x41\x37\x6d\x48\x6e\x44\x1b\xba"
-  "\x2e\x62\x03\xe8\xa9\x98\xf7\x10\x67\x51\x8e\xd6\x13\xe5\x49\x0b"
-  "\xea\xe3\x85\xe5\x27\x80\x25\x76\x61\x43\x51\x71\x41\x13\x1e\xc6"
-  "\xfb\xb1\x1c\xb4\x4d\x6e\xe5\xa0\x6d\x83\x26\xd5\x61\x7d\xf9\xcc"
-  "\x51\xf9\x86\x04\x9c\x17\x8e\xea\x26\x0f\xe7\x5b\x05\x9c\x1f\x52"
-  "\x0f\xe7\x54\x07\x4f\xe5\xcb\x79\xb5\xc5\xc4\xa7\xf7\x8f\x2c\x6b"
-  "\x69\x22\x86\xb8\x76\x52\xa5\x38\xfa\x1c\x3e\xbb\x39\x68\x42\x44"
-  "\x4b\xd0\x84\x31\xad\x69\x47\x67\x89\xf5\xc5\x67\x89\xe9\x68\x73"
-  "\x60\x75\x3c\x1a\x7b\x22\xd1\x73\x1d\x61\x2e\x19\x38\x23\x84\xb7"
-  "\x60\x1b\x1a\x92\x9a\xa0\x2e\x1f\x7c\x87\xed\xcc\x67\x4e\x20\x2d"
-  "\xc9\xda\x7b\x98\x0d\xee\x03\x35\xda\x72\x60\xee\x6f\xa1\x76\x95"
-  "\x6d\x8d\x2d\x74\xdd\x0c\xe0\x3d\xcc\xd3\xc5\xc8\x51\xae\x2a\x8e"
-  "\xd2\xf8\x81\xb3\xb5\x4a\x2f\xf5\x99\xa3\x74\xfe\x37\xdc\x83\xed"
-  "\xf0\xc1\x67\xf0\xbc\xdf\x54\x29\x3e\x78\x98\x71\x8d\x26\x3f\x7c"
-  "\x1e\xe4\x31\xc0\x9c\xe3\xc7\x67\x58\xca\x31\x1f\x5c\x9f\x25\x5c"
-  "\x57\x3b\x5d\x57\x43\x9d\xa7\x08\xd7\x05\xbf\x6a\x4d\x41\x4e\xd7"
-  "\x83\xf4\xf7\xa0\x9d\xed\x83\x6c\x7c\x27\x98\xcb\x2c\x38\xaf\xa1"
-  "\x0d\x9f\xd9\xc9\x1b\x2d\x42\x3e\x55\x83\xe2\x83\xf7\x9b\xa1\x5f"
-  "\xc1\x75\x7f\xa7\xfb\xfd\x4f\xc6\x47\x90\x89\xbb\xb1\x4d\x3f\x28"
-  "\x36\xfb\xb4\x95\x30\xdb\xcc\xd1\x22\xda\x16\xea\xc6\x3a\xe7\xf2"
-  "\xcc\x8a\x0f\x32\xa1\xcc\xba\x16\xe0\x77\x90\xe7\x00\x3e\xd3\xb9"
-  "\xfd\x17\xc5\xc4\xac\x88\xd1\x0c\x5b\xa8\x59\xb8\x6c\x81\xe6\xa5"
-  "\x15\xab\x97\xc7\x8e\x1b\xb6\xb0\x1f\x21\x4e\x7d\x47\xcd\xa7\x06"
-  "\xf0\x5c\xe6\xb8\x78\x63\x96\x8d\xf0\x4a\x35\xcc\xb7\xed\x24\x13"
-  "\xe4\x6a\x0f\x9e\x16\x65\xdf\x39\x15\xc6\xcf\xe8\x99\x86\x84\x09"
-  "\xd0\xf6\x1f\xd2\xef\xa0\x46\x0d\x21\x9b\xe1\xba\x21\xe1\x0c\xa6"
-  "\x2d\xa3\x69\x0b\x09\xa1\xf6\xa7\x04\x3f\x52\xa4\x69\xa2\x36\x2c"
-  "\xb8\xb6\x8f\xda\xeb\xae\x11\xa5\x2d\xd5\x8f\xfc\x2d\xa9\x5c\x79"
-  "\x8c\x33\x2b\xff\xc6\x99\x94\xc8\x17\x4e\x86\x14\x93\x07\xe3\xfd"
-  "\x08\x5e\xff\x38\x09\xd2\xe1\x3a\x5e\xa3\xe5\x50\x59\x7f\x78\x0d"
-  "\xf3\xa1\x4d\x0b\xff\x27\x67\xf1\x97\x4f\x86\x58\x08\xe3\xaa\x1f"
-  "\x3e\x89\x75\xd5\x0c\xc1\xef\x05\x1f\x4e\xc3\xfa\x99\x15\x1f\x4e"
-  "\xf5\xc9\x86\xfc\x71\xc4\xff\xaa\xe2\xd8\x63\xdc\x8e\x71\xf1\x88"
-  "\x05\xb6\xb4\x0f\x81\x3f\x04\x3e\x9a\xb3\x9d\xf8\x65\x6f\x87\xb1"
-  "\xb9\x9d\xa8\x5a\xd3\x8e\x85\x99\x55\xea\xcd\xd8\xb6\x50\x8c\x7f"
-  "\xb3\x92\xfc\x0e\xd2\xc6\x98\xc9\xa2\x20\x4c\x83\x31\xd8\xe2\x09"
-  "\x5b\xae\x03\xbf\xb3\x86\x0d\xb6\x70\x41\xe3\xa2\x79\x68\xb7\xd6"
-  "\xb0\x21\x9a\x00\x3d\xf4\x2d\x18\x63\xfc\xa0\x71\xd1\x0d\x8a\xe3"
-  "\x53\x3f\x85\x9e\x95\x84\x63\x7a\xe7\xe8\x99\xef\x5e\xb7\xe2\xf7"
-  "\xb1\xa8\x03\xd7\x2d\x70\x3e\xd5\x92\x0f\xe7\xa7\x0d\xf9\x44\x33"
-  "\x1d\xb9\xd3\xb1\x83\xbf\x5f\xc8\xdb\x86\x97\x00\xcf\xac\xfe\x2f"
-  "\x72\xb6\xa2\x98\xf8\xcf\x21\x3e\x0e\xdf\xed\xb1\x44\x39\xc3\x0c"
-  "\xe7\xab\x89\xb2\x0c\x74\x7a\xb4\xb5\x27\x3d\x86\xf6\xf6\x52\x82"
-  "\x36\x78\x5e\xf9\xf2\xc6\x83\x4d\x56\xc0\xb0\xba\x3e\xb8\x86\x9b"
-  "\x53\xbf\x51\x8c\xf7\xcc\x6f\x11\xbe\x5d\x35\x0b\xdf\xae\x9a\xe9"
-  "\xb7\xab\xf8\xc4\x28\xf6\xed\x0a\xbf\x59\xcd\x88\xf2\xe1\xb1\x3c"
-  "\xfc\x8e\xd5\xbf\x05\xfa\xc1\x2a\xed\x00\xfb\x2a\xed\xc0\xac\x26"
-  "\x12\x54\x66\xa9\x03\x8e\x56\x4c\xde\x8e\x23\x41\x7c\x73\xf4\x6d"
-  "\x25\x86\x33\x84\xdf\xfe\x6f\x86\xc3\x49\x86\x3e\x76\xb4\x3f\x34"
-  "\x87\xf4\x0b\x58\xaf\x40\xbb\xfd\x80\xcd\x31\x24\x7c\x4f\x13\x89"
-  "\x98\x5f\x93\x42\xfd\x38\x61\xcc\x3d\x5b\xb3\x56\xd3\xd1\xac\xbd"
-  "\xaf\xad\x59\x7b\x4f\x80\x85\x7d\xeb\x9a\x7b\x45\x4d\x70\xfd\x2c"
-  "\x9f\x76\xa0\x7c\x0f\xda\x9c\x5b\x2c\xc4\x16\xf8\x46\x31\xf6\x65"
-  "\x78\x76\x28\x7e\x1f\x49\x5e\x43\xd4\xdc\x37\x5a\x52\x1a\xdd\x44"
-  "\x1e\x04\xd9\xe3\xb7\x80\x9c\x2a\xf6\x2d\xc0\x0e\x7a\x0c\x7e\x0f"
-  "\xb8\xde\xac\x55\xf2\x41\x13\xcb\xa7\x2d\xd6\x90\xb6\x7d\x83\x2d"
-  "\xc6\xf8\x77\x49\x72\x1b\x7f\xd9\xb8\x91\x23\x68\x27\xe6\xd3\x8e"
-  "\xcd\xe4\x07\x4d\x2c\x3f\xa5\x3d\x87\xf3\x4a\x84\x84\x1d\xc7\x07"
-  "\xf7\x0e\x3b\x8e\x53\xfe\x8c\xdf\xcd\xf8\x9d\x20\xc7\x26\x94\x27"
-  "\xc8\xb5\xc9\xa2\x7c\x0a\x64\x57\x5a\xfd\x17\x90\x9b\x49\x26\x37"
-  "\x2a\x67\xc8\x57\xbb\x10\xe4\x55\xc3\x64\x58\xd2\x02\xf2\x3b\x8a"
-  "\x65\x4c\xd0\x1f\x8c\xb3\x2a\x41\x57\x52\x96\x58\x2f\xd2\x3d\x28"
-  "\x28\xc7\x03\xed\xc5\x7d\xda\x60\xbe\xc1\xef\x8f\xd7\xf3\x86\xa8"
-  "\xdb\x82\xc6\x4d\xe9\x08\x1a\xa7\xeb\xe2\x5b\x24\x93\xe7\x62\xe2"
-  "\x57\x52\x7d\x8e\xc9\x73\xa5\x20\x4f\x5c\xb3\xf6\xaa\x76\x80\xad"
-  "\x15\xe4\x79\x1d\xe4\x19\x6b\x26\x6f\xc5\x90\x20\x63\x9d\x09\xbf"
-  "\xd3\xdc\xf6\x64\x29\x21\x4f\x0d\xe7\xb9\x52\xc3\x05\x2a\xd7\x43"
-  "\x20\x57\x5b\xc6\x6b\xc5\xf8\x7d\xd2\x21\xd7\x38\x90\xeb\x75\x90"
-  "\xeb\x15\x49\xae\xf6\x56\x90\x6b\x2b\xc8\xb5\x15\xe4\x2a\x7c\xc3"
-  "\x9c\xbb\x18\xe4\x8a\xdf\xbb\xd2\x0e\xce\xc2\x6f\x98\xf8\xad\x08"
-  "\xe5\x8a\xeb\xa4\xb9\x57\xb5\xa1\xf4\xdb\xe5\x4b\x5a\xb2\xe7\x45"
-  "\xe2\x37\xca\x4a\x14\xc9\x47\x89\x1a\xea\xa9\x7e\xe0\x08\x51\x42"
-  "\x79\xd0\xef\xab\x08\xca\xd7\x78\xc4\x4e\xd6\x3e\x47\xee\xb1\x6d"
-  "\x63\x72\x36\xda\xde\x47\x5b\xed\x98\xeb\xaf\x6a\x95\xbb\xe2\xc8"
-  "\x58\x94\xf9\xd4\x1a\x0d\x39\x35\xb3\x94\xb8\xca\x9c\xdb\x81\xe3"
-  "\xff\xb8\x0a\xe5\xde\xfb\x71\xfb\x89\xaa\xe7\xe3\xd6\xb0\xe8\x9f"
-  "\xe3\xf6\x46\x8f\x5b\x83\x9f\xfb\x71\x7b\xe2\xb3\xde\x8d\xdb\x13"
-  "\xe5\xff\x1c\xb7\xbf\x84\x71\x7b\xe2\x98\xeb\xb8\x75\xf0\x96\x98"
-  "\x45\xcb\x16\x2c\x5e\xbe\x78\xf9\x2b\x9a\x17\xd7\xc4\x2e\x5a\xc5"
-  "\xd8\x8b\x8c\xbf\x68\xed\x5c\xa4\xf2\x4d\x98\xaf\xcf\x86\x98\xc8"
-  "\xe1\x21\x26\x25\xf7\x42\x88\x8a\xcf\xc8\x51\x73\x19\xb9\x59\x6f"
-  "\x02\x0f\xc7\xf1\x9d\x09\x1c\xbb\x56\x51\x16\xf1\xf7\x50\xe0\x9f"
-  "\x31\xf5\x04\xff\x33\xee\x36\x3f\x0a\xf7\x2d\x66\xed\xe4\xeb\x70"
-  "\xdf\xe2\xe9\x22\xe4\x16\x45\x6b\x6e\xd7\x81\x0e\xf1\x42\x08\x69"
-  "\x7b\x41\xa7\xfc\xf3\x05\xe2\x17\x60\x22\x53\x39\x8e\xe7\x0d\x49"
-  "\xf5\xc0\xfb\xce\xc6\x1a\x9e\xaf\x27\xc8\x75\x6a\x15\xa7\x3f\xd3"
-  "\x24\xac\xc7\xe3\xfb\x9a\x84\xb4\x4b\x70\xa4\xfb\x21\xb6\x40\x79"
-  "\xdc\x03\xa1\x91\xf8\x5d\x15\xc6\xad\x72\xf7\x4e\xbe\xfa\xf0\x72"
-  "\xb3\x72\x43\x3b\x21\x1b\x12\x88\x0a\xfd\x54\x18\xee\xc1\x7a\x14"
-  "\x9f\x9b\x61\xbb\xc4\x03\x9f\xaa\xfe\xb8\xd6\xac\xcc\x81\xeb\xe8"
-  "\x43\xb4\x45\x6d\x29\xdf\x08\x75\x87\x7a\x99\x77\xed\xe4\x2b\x2d"
-  "\x83\xc6\xc5\xab\x34\x44\xd9\x9a\x56\x54\x09\x3c\x27\x04\x39\xca"
-  "\x26\xb8\xf6\x3a\x5c\x63\xdf\xfc\x8a\x33\xec\x69\x27\x0b\x11\xd7"
-  "\xa0\x1f\x2b\xae\x2a\x4e\x0d\x47\x5f\x4d\x50\xae\x05\xeb\x82\x31"
-  "\x6d\x6d\xfb\x86\xa8\xed\xfb\x86\x68\xac\x3b\xc6\xe9\xda\x76\x8c"
-  "\x9b\x82\x98\x37\x7b\x38\xfd\xb6\x0d\xf9\x3f\xa5\xfb\xe7\xda\x32"
-  "\x47\xcf\x44\xfe\xd5\x1c\x34\x2d\xaa\x39\x73\xaa\xe5\x4c\x62\x16"
-  "\xd1\x3c\x83\x78\x77\x6a\xf6\x53\x59\xbc\x6d\xc4\x4c\xc0\xbb\xac"
-  "\x77\xc9\xd9\xa9\x80\x77\xba\xce\x78\xc7\xd6\x02\xd8\x09\xc3\xbd"
-  "\x52\x02\x3a\x50\x35\x8e\x1b\xe4\xa5\x07\xdb\x61\x5c\xc1\x98\xc0"
-  "\xbe\x4f\xf1\x0f\xb0\x4f\x1c\x1f\x38\x76\x10\xdf\xe8\x58\x75\x19"
-  "\x2b\x38\x3e\x6e\xb7\x10\x35\x8e\x0f\xc4\x3f\x1c\x1f\xb8\xc6\xe6"
-  "\x4d\x61\x7c\x04\x54\x12\xf5\x5b\x80\x7d\x46\x5b\x31\x1d\x23\x58"
-  "\xff\x12\x9b\x13\xee\xe1\xb7\x1a\xa7\xf1\xb1\x45\x1c\x1f\x22\xee"
-  "\xc1\x18\xb0\xe1\xf8\x78\x55\x7b\x5f\xfb\xab\xd2\xf8\x78\xe1\xa2"
-  "\x9a\x50\x4c\x4c\x3b\x30\x2b\x1b\xc6\x47\x99\xde\x42\xec\x22\xee"
-  "\xc1\xf8\xc0\x3d\x40\x14\xf7\xfe\x04\xb8\xd7\x00\xb8\x67\x81\x74"
-  "\x18\x17\x39\x4b\x04\xdc\x13\xc6\x43\xdb\xab\x02\xee\x5d\xd1\x90"
-  "\xf6\x61\x88\x7b\x6f\x79\xe0\x2b\x17\x5d\x70\xef\xd3\xd3\xbd\xc3"
-  "\xbd\x4f\xe9\xfa\x07\x94\x61\x3b\xc8\x13\xe5\xf8\x54\x08\x6f\x2b"
-  "\xc9\x02\xbc\x9b\xf5\x33\x93\x5b\x8c\x7b\xb9\x1d\x12\xe6\xab\xfe"
-  "\x20\xb3\xfe\x0d\x64\x00\xe2\x1b\xe2\xda\x6e\x0f\x72\x83\x7b\x1b"
-  "\xf8\x56\x77\xb2\x7b\x37\x3f\xdb\x09\xdb\x10\xd3\x10\xdf\x10\xd7"
-  "\x10\xe3\x70\x0d\x04\x8c\x91\x3a\xc4\xb7\x5f\x25\x32\x5c\x43\xbc"
-  "\x4b\xae\x61\x58\x57\x1a\x5d\x45\x92\x27\x93\x7b\x8c\x85\x76\x82"
-  "\xf1\xb5\x70\x2e\x33\xda\xae\x11\x8c\x97\x85\x18\x87\xb2\xdd\x75"
-  "\x9d\x61\x1c\xce\x6b\x88\x67\x9d\xe6\x35\x90\x2d\xc8\xe4\x08\xce"
-  "\x6b\xd4\x36\xa1\xbc\xc3\x77\x37\xea\x21\x03\x89\x2a\x73\x20\xf1"
-  "\x6b\x4d\x2b\x2e\xe8\xac\x8b\x14\x17\x89\xba\x08\x8e\x71\x1c\xeb"
-  "\x66\x45\x91\x85\xea\xb0\x43\x1e\x47\x8c\x12\xbe\x89\x3f\x9e\xcb"
-  "\xf4\xa1\xb2\xcb\xf4\x1c\x74\x7e\x49\xdf\x3f\x1d\xc8\xbe\xc5\x83"
-  "\x7e\x3f\x68\x54\x3e\xbf\xcd\x62\xc2\x36\x16\x30\xa1\x81\xdf\x31"
-  "\x81\xf6\xb5\xf9\xc3\x89\x9f\x6d\xc7\x84\x87\xed\x3b\x26\x8c\x61"
-  "\xfd\xee\xf4\xf8\x53\xf1\x84\xcc\x8e\xf7\xb6\xdf\x9d\x8e\xa4\x75"
-  "\xf8\x4a\x77\x07\xff\x82\x4e\xc5\x7d\xa5\xeb\x03\x7d\x24\x64\x85"
-  "\x3d\x85\x5c\xcf\x98\xaf\x4b\xb6\xf1\xe8\x87\x76\x04\xd4\x6b\xef"
-  "\x69\x1b\x21\xa7\x5b\x08\x31\x4e\x5d\x0a\xf2\x9e\x67\x3a\xcc\x59"
-  "\x54\xf0\x7e\xf1\xa0\x2f\xd6\x01\xf6\xaa\x9c\xb1\x97\xe1\x2c\x7e"
-  "\xd5\x27\x0a\x6b\xc6\xfc\x68\x2c\x6b\x46\x31\x09\x80\xf9\x57\x55"
-  "\xab\x38\x3b\x79\xcd\x3a\x82\xfb\x57\xfb\xc0\xff\xc0\xf6\x81\xa3"
-  "\x4d\x70\xff\x00\xfe\xab\x59\x0a\xfd\x13\xe4\x1e\xfe\x85\x59\x0a"
-  "\x5c\x7b\xb0\x9f\xcb\x55\x72\x90\xc6\xd6\x32\xe5\x12\xbc\xbe\xb9"
-  "\x5d\x45\x79\x19\x07\x79\xca\x5a\x72\xc9\xe6\x38\x3f\x82\xf9\xd9"
-  "\xfa\xb8\x5c\x82\xf9\xb7\xc4\xa8\xe9\xda\x05\x7a\x9f\x2d\x97\xe0"
-  "\xbd\x76\x48\x7f\x83\xf3\x27\xe9\x09\x41\xe4\x74\x49\x19\x2d\xe3"
-  "\x74\xc9\xa7\x04\xcb\x40\xac\x3f\x5d\x72\x9c\x6c\x8d\x0b\x01\x4c"
-  "\xc8\x85\xeb\x5f\x90\xad\x57\x43\xe1\x58\x0b\xbf\xeb\xa4\x5e\x71"
-  "\xa6\xe0\x74\x09\x47\x02\xd6\xff\x8e\x07\x2c\xe2\x8d\xb8\x27\x32"
-  "\x89\xf8\xd6\x2a\xce\x1c\xc5\xf7\x83\x36\xcc\xc5\x3d\xf3\x46\x53"
-  "\x06\xe1\x93\x5f\x68\xe0\xf8\x17\xae\x70\xc9\x2f\x5c\xc5\xe7\xdb"
-  "\xf9\x17\x7e\xc0\xe7\x6f\x49\xd0\x08\x6b\x66\x73\xe9\xfa\xbe\xcd"
-  "\xd7\xc3\x08\xd6\x17\x9f\x8d\xcf\xdc\x1a\xa3\x15\x9e\x1b\x4e\xeb"
-  "\x87\xcf\xc5\x72\x9d\x9f\x8b\x31\xe9\x35\xcf\xe2\x73\xcf\x3e\x04"
-  "\xc7\x40\x90\x49\x1e\xca\x02\x9f\xcb\xf1\xba\x3e\x7c\xb2\xce\x87"
-  "\xde\x63\xad\x73\x77\xcf\x22\xe1\x9e\x5c\xaa\xfb\xc3\x3d\x6d\x3c"
-  "\xcd\x4f\xcb\x80\xf9\x71\x3d\xa6\x8f\xd4\x19\x48\x67\x39\x96\xdc"
-  "\xcd\xe6\xcb\xb3\x57\xd8\x7c\xc9\xe4\x4a\xfb\xcb\x0b\xba\x3e\x20"
-  "\x3b\x35\xce\xad\x50\xc6\x29\x47\x19\x5f\xe9\x7c\x50\xe6\xd8\x77"
-  "\xc4\xfe\x84\x7d\x49\xec\x47\xb4\x9e\x30\x32\x9c\xfb\x0d\xfc\xf7"
-  "\x63\xe5\x94\xf4\x17\xcb\x81\x3a\x10\xb1\x2f\x8d\x84\xeb\x9d\xfb"
-  "\x52\xe9\x77\x52\x5f\x2a\x7d\xdd\x9a\xc4\xf3\xd8\x97\x0c\xcf\xa7"
-  "\x62\x39\xb3\xa5\xfa\xcc\x52\x60\x3f\xfb\x85\xf5\xaf\x02\x51\x56"
-  "\x23\x13\x49\x10\x7b\xa7\xd2\xe1\xf4\x9d\x12\x0d\x41\x58\x5f\xf1"
-  "\x5d\xb0\x1e\xe9\x9c\x86\x88\xef\xb2\xb5\x3d\x0c\xca\xbe\x4a\x84"
-  "\x7b\xe6\x62\xf9\x62\x3b\x80\xdc\x88\x78\x8f\x98\x3f\x9d\xd3\x42"
-  "\xdd\xc3\xe9\x3d\xac\xdf\xd5\xba\xe9\x43\xa5\xfb\x5d\xfb\xdd\xed"
-  "\x89\x04\x88\x30\x70\xac\xe7\x9b\xf0\x39\x4c\xfe\x89\x1f\xdb\xdb"
-  "\xbe\xd2\xa1\x6c\x95\x42\xfa\x45\xa7\x7e\x21\x94\x6f\x75\x53\x7e"
-  "\xd9\x6d\xb2\xf2\x75\x50\x7e\x3c\x94\x8f\x1c\xee\x79\xb4\xdd\x95"
-  "\x51\xff\x3f\x23\xe3\x59\xf9\x62\xdf\xe5\x33\x46\xe6\xea\x13\x70"
-  "\x9d\x69\x59\x09\xc3\xd5\x22\x1a\x2b\x84\xae\x6f\x52\x72\xb9\x9c"
-  "\xcb\xfa\x26\xe7\xf5\x6f\x87\x93\x2c\xc2\xda\xa6\xb2\x83\x98\x07"
-  "\x6d\x64\xc8\x45\x0f\xd6\x9a\x94\xd2\xfa\xa6\x0b\x78\xfd\x7d\x43"
-  "\x5c\x95\xd3\xfa\xa6\xb2\x4d\x6c\xec\x97\x99\x5b\x95\x44\x09\xe7"
-  "\xd9\x2c\xbd\x48\xe3\x9c\x2e\xad\x1f\x64\xe9\xb8\x36\x5b\xb0\x17"
-  "\x37\x9c\x2c\x44\x7b\x61\x99\x55\xb4\xd1\x7a\xd0\x81\xbd\xe0\xca"
-  "\xe7\xa3\x25\xae\x7c\x3e\xda\x33\x57\x36\xee\xeb\x9a\x2b\x7f\x51"
-  "\x20\x71\xe5\x73\x81\x6c\xec\x57\x5c\x63\x63\xbf\xe2\x7d\xda\x96"
-  "\xc1\x7c\x9d\xfd\x2f\xba\x99\x65\x2a\x42\xfb\xd0\x1e\xe0\x1e\x87"
-  "\x13\x4c\x2e\x5c\x19\xd7\x85\x55\x0c\x9a\x0e\x5c\x19\xe6\xb7\x02"
-  "\xd6\x0e\xc6\x2b\xd0\xf6\x3e\x46\xab\x95\x60\x3a\xcc\x6d\xd5\xc8"
-  "\x93\x8f\x73\x26\x65\x0e\xb4\x1f\xfc\x54\x2d\x41\x3a\x8d\x33\x8f"
-  "\x6e\x4d\x2b\x0f\x75\xcf\x9f\xff\x51\x6e\x93\xf1\xe7\xf2\xc5\x22"
-  "\x7f\xc6\xfa\x21\x67\x46\xfe\x6c\x43\x1b\xec\xb0\x21\x1a\xe4\xcf"
-  "\xb6\x1d\xce\xfc\xf9\xf3\x71\x0e\xfe\x1c\xec\xc4\x9f\xe3\x45\xfe"
-  "\x5c\xbe\xe3\x9f\xfc\xf9\x66\xf1\x67\xd1\x6e\xe0\xca\x9f\x3f\xbf"
-  "\xad\x77\xfc\xf9\x73\xbf\xff\x2d\xfc\xd9\xad\x5d\xc0\x8d\xdc\xa0"
-  "\x9f\x37\xd8\xdc\xf0\x67\x1e\xf8\xf3\x9e\x2e\xf8\x33\x8e\x0f\xe4"
-  "\xce\xc8\x95\x7f\xb5\x10\xb8\x08\x60\x03\x72\x66\x91\x43\x8b\xdc"
-  "\x19\x39\x33\x72\x6b\x67\x7b\x90\x77\xfc\xf9\xb3\x16\x89\x3f\x0f"
-  "\x6c\xcc\x96\xf1\xe7\x7f\x58\x3a\xf3\xe7\x0a\x55\x67\xfe\x5c\x1e"
-  "\x21\xf1\x67\x63\x85\x9c\x3f\x5f\x18\xdc\x99\x3f\x57\x3c\xed\x89"
-  "\x3f\x23\x67\x46\xfe\x8c\x7a\x07\x72\x67\xf8\x3f\x46\xea\x77\x15"
-  "\xeb\x7b\xc7\x9f\x2b\x52\x7a\xc6\x9f\x2b\x2e\xbb\xe7\xcf\xc6\x3c"
-  "\xcf\xfc\xd9\x98\xe7\x9e\x3f\x7f\xb1\x5e\xe2\x3c\x5f\x4c\xfb\xf9"
-  "\xf3\xe7\x73\x16\xf7\xfc\xe6\x5c\x1b\x72\x08\x68\x43\x33\xf2\xe7"
-  "\x1b\xcb\x9d\x2b\xcc\xee\xb9\xf3\x17\xcb\x18\xc7\xa8\xa8\xee\xcc"
-  "\x9d\xe1\x1e\xb7\xdc\xf9\x8b\xbd\xc2\x3d\x66\x39\x77\x66\x65\xc0"
-  "\x7c\xf9\x91\x67\xee\xfc\xe5\x73\x6c\xfe\xfc\x72\x38\x9b\x3f\x99"
-  "\x4c\x3b\x73\xe7\x2f\x15\xdd\x73\x67\xd6\x87\x68\x3d\x3d\x72\xe7"
-  "\x2f\x9f\xec\xcc\x9d\x8d\x79\xee\xb9\xf3\xf9\xa1\x52\x3f\x32\x9d"
-  "\x90\x73\xe7\x2f\xb7\xfd\x32\xb8\xb3\xc7\xbe\x65\x91\xf3\x66\xd3"
-  "\x02\xef\x79\xb3\x69\x87\x77\xbc\x19\xfb\x9c\x3b\xde\x6c\xba\xec"
-  "\xda\xe7\xe4\xbc\xd9\x64\x77\xcf\x9b\xcf\x0f\x92\xf3\x66\x2c\xdf"
-  "\x1d\x6f\x3e\x3f\x5e\x56\x7e\x27\xde\x7c\x7e\xae\x9c\x37\xb3\x7c"
-  "\x12\x6f\xbe\xa0\x12\xb8\xd9\x34\xef\x79\xf3\xf9\x9a\xae\x79\xf3"
-  "\xf9\x2b\x72\xde\x7c\xde\xc0\xf8\xf1\x85\x10\xc6\x9b\xcf\x57\xb0"
-  "\x74\xe3\x54\xe7\x74\x89\x37\xb3\xf4\xce\xbc\xf9\x42\x44\x37\xbc"
-  "\x79\x4c\xcf\x79\x73\x8d\xb6\xd8\xc1\x9b\x6b\xb4\x22\x6f\xe6\x80"
-  "\x4b\xe6\x00\x27\x80\x5f\x1d\xee\x71\xc0\x31\x07\x73\xce\xe5\xae"
-  "\xb9\x73\xd5\x42\x89\x3b\x9b\xdf\x67\x63\xdf\xbc\x8b\x8d\x7d\xf3"
-  "\x73\x0e\xee\x7c\x9f\x6e\x66\xe9\x46\x07\x77\x36\x1d\x4e\x28\x77"
-  "\xe1\xce\xd8\x76\xe6\xc9\x94\x23\x5f\xa7\x6b\x53\xcc\x38\xcf\x4f"
-  "\x4f\xbc\xc4\x6f\x86\xb9\x1d\xe6\x30\x33\x6b\xdf\x4b\xfb\xb2\x61"
-  "\xae\x94\xf8\xf5\x57\xd3\x1c\xfc\x3a\x91\xda\xa8\x4d\x94\x5f\xbf"
-  "\x5c\xae\xdc\x0d\xe5\xc3\x4f\x85\xdc\x1a\x39\x36\x70\xeb\x8a\xdd"
-  "\x3b\xf9\xf2\x9c\x9d\x7c\x49\x6b\xda\x57\x29\x22\xc7\xde\x02\x69"
-  "\xe9\x90\x56\x94\x4b\x30\xee\x37\x8d\xfd\x0d\x6d\x5f\xb9\x01\x9e"
-  "\x89\xf7\x41\xde\x03\x62\x5e\x98\xa7\x2b\x18\x17\xbf\xb4\x90\xf3"
-  "\x75\xe6\xe2\x5f\xb5\x89\x5c\x3c\x1d\xde\x17\xb9\x95\xc8\xc5\x39"
-  "\xe0\xe2\xfc\x20\x66\xcf\x96\xf3\xf1\x8b\xa5\x22\x1f\x4f\x77\xe6"
-  "\xe3\x7a\x91\x8f\x57\x0e\xeb\x25\x1f\x37\xfd\x6f\xe6\xe3\xc8\xc5"
-  "\x91\x7f\x23\x17\x47\x6e\x8e\x7c\x1c\xb9\x39\x27\xf0\xf1\x9c\x9e"
-  "\xf0\x71\xe0\x6b\xbc\xaf\xc1\x8f\xf2\x71\x85\x33\x1f\xbf\xb8\xab"
-  "\x77\x7c\xfc\x62\x96\x33\x1f\x07\x79\x9a\xbc\xe5\xe3\x28\xfb\x4e"
-  "\xdf\x5d\x71\xcd\x11\xc8\x0f\x65\xd5\xe5\x77\x3a\x41\x8e\x28\x37"
-  "\x94\x19\xca\xae\x47\x7c\x1c\xfa\x5d\x89\xf5\xd6\xf1\x71\xad\x0b"
-  "\x1f\x47\xfe\x0d\x6d\x57\x8d\xbc\xdc\x68\x80\xb6\x59\x09\xdc\x1c"
-  "\x78\x79\xef\x39\xf9\xc5\x8d\xce\x9c\x3c\x67\xa0\x33\x27\xbf\xb4"
-  "\xb1\x33\x27\xbf\x94\xe5\xc4\xc9\x2b\xcc\x8a\xaf\x68\xcc\x1a\xc3"
-  "\xcb\xc8\xb5\xbf\x7a\x58\xce\xc7\x6b\xce\x77\xe6\xe3\x97\x2e\x7b"
-  "\xe2\xe3\xb8\x86\xce\xd5\x9e\xcd\x0d\x12\xed\xd9\xe6\xc0\xde\xf1"
-  "\x71\xb3\x5a\xd2\x17\xbe\x52\xb3\x39\xe5\x52\x81\x27\x8e\xde\xaa"
-  "\x76\xe6\xe8\xe6\xd7\x24\x8e\x1e\xeb\xc4\xd1\x2f\x98\x3d\x73\xf4"
-  "\x0b\x94\x13\xf2\xea\xf9\xd1\x58\x16\x72\x2b\xb4\x85\x68\xe8\x9e"
-  "\xf9\xaa\x47\x90\x5f\xa1\x8d\x03\xde\x09\x38\x56\x95\xc2\x99\xab"
-  "\xe3\xf7\xc3\xae\xf8\x94\xfe\x65\x72\x0f\x72\x2a\xe4\x53\x22\xff"
-  "\xc5\xfc\xc8\xab\x6e\x2e\xa7\xba\x9c\xeb\x9e\x53\x5d\x3e\x48\xf9"
-  "\x32\xdd\x6b\x69\xde\x88\x73\xe3\x8d\xe5\xec\xe6\x8d\xee\x39\x7b"
-  "\xd5\x50\xc6\x6f\xcc\x9b\x50\x2e\x72\xce\x0e\xf7\xb8\xe5\xec\x55"
-  "\xb3\x85\x7b\x36\xca\x39\x3b\x2b\x03\xe6\xe9\x95\x9e\x39\xfb\x37"
-  "\xfd\xd9\xbc\x5d\x75\x91\xcd\xdb\x82\x8c\x3b\x71\xf6\xaa\xf7\x9d"
-  "\x39\x3b\xca\xbf\x33\x67\x67\x7d\x8a\xd6\xd3\x23\x67\xaf\xb2\x77"
-  "\xe6\xec\x17\xcc\xc8\xd9\xdd\xf7\xab\xea\xcb\xf2\x7e\x55\xbd\xde"
-  "\xca\x89\xdc\xfd\xcf\x50\xde\x37\xd3\x5c\xb9\xfb\x2f\xb0\xaf\xe5"
-  "\x4a\xfc\x1d\xdf\xa9\x7a\xa8\x77\xfc\x9d\xde\x33\xdb\x3b\xfe\x8e"
-  "\xfd\xcf\x1d\x7f\xaf\xde\xeb\xda\xff\xe4\xfc\xbd\xfa\x23\xf7\xfc"
-  "\xbd\xfa\x9c\x9c\xbf\x63\xf9\xee\xf8\x7b\x8d\x42\x56\x7e\x27\xfe"
-  "\x5e\x73\xb7\x9c\xbf\xb3\x7c\x12\x7f\xaf\x29\x12\xec\x21\xaf\x79"
-  "\xcf\xdf\x6b\xf6\x75\xcd\xdf\x6b\x0e\xca\xf9\x7b\x4d\x0a\xc3\xd4"
-  "\x1a\x93\x95\xf2\xf7\x9a\x4c\x96\x7e\x61\xa3\x73\xba\xc4\xdf\x59"
-  "\xba\xd5\x99\xbf\x1b\x90\xbf\xd7\x58\xba\xe1\xef\x93\x7a\xce\xdf"
-  "\x1b\xa3\x24\xfe\xde\x18\xd5\x35\x7f\xaf\xdd\xdb\x35\x7f\xbf\x9a"
-  "\x2d\xf1\xf7\x86\x2b\x0c\x07\x1a\x3e\x63\x38\xd0\xb0\xcd\x03\x7f"
-  "\x2f\x71\xcf\xdf\x1b\xd6\x39\xf1\xf7\x4a\xe4\xed\x30\xe7\x55\x22"
-  "\x3f\xc0\xf5\x23\xc0\xdb\x4d\x86\x18\x9a\x6f\x31\xf2\x7b\xe4\xf4"
-  "\x70\xdd\xbc\x19\xff\x73\xf4\x9e\x0a\x5c\xcf\x45\x79\x7c\x2d\xe5"
-  "\xfc\x15\x4c\x26\xdf\x9f\x86\x7b\xcb\x25\xce\xff\xed\x78\x17\xce"
-  "\x5f\xd2\x05\xe7\x2f\x06\xce\x5f\x04\x9c\xdf\xd0\x9a\xf6\x6d\xac"
-  "\x13\xe7\x2f\x02\xce\x6f\x70\xe1\xfc\x26\xe0\xfc\x95\x78\x1f\xde"
-  "\x03\xf9\xf3\x64\xf9\xa1\xae\x34\x7f\x13\xfd\x61\xfe\x72\xc8\x5f"
-  "\xc1\x74\x84\x6f\xcb\x9d\x74\x84\x62\xa6\x23\x7c\xbf\x89\x97\xe9"
-  "\x08\x75\x77\x7b\xaf\x23\x7c\xd7\xd8\xb5\x8e\x50\xf7\x64\x2f\x75"
-  "\x84\x92\x7f\xea\x08\xbd\xd5\x11\xbe\xfb\xa8\x77\x3a\xc2\x77\xc7"
-  "\x5c\x74\x84\x92\x7f\xea\x08\x3f\x07\x1d\xe1\xbb\x7c\x87\x8e\x90"
-  "\x3a\xb0\x71\xcf\x40\xb6\xfe\x9e\xe9\x08\xdf\xe7\x77\xd6\x11\xbe"
-  "\x3f\xe6\xa4\x23\x14\x9b\x15\xdf\x9a\x25\x1d\xe1\x5b\xad\x5c\x47"
-  "\x68\x0a\xec\xac\x23\x34\xf4\xe9\x9d\x8e\xd0\xf0\x48\xef\x74\x84"
-  "\x86\x87\x59\xfd\xf0\xfb\x64\xad\x95\xcd\x5b\xdf\x57\x48\x7a\x43"
-  "\x6d\xb9\x73\x5a\xf7\x7a\x43\xc3\x47\xee\xf5\x86\xda\x5c\xcf\x7a"
-  "\x43\x6d\xae\x67\xbd\xe1\xea\x32\x39\xbf\xbb\xfa\xd8\x2f\x43\x6f"
-  "\xb8\x62\x72\xcf\xe5\xae\xd4\x48\x7a\x43\xc3\xb1\x1b\xaf\x37\x34"
-  "\x1c\x73\xaf\x37\x5c\x7d\x8e\xf1\xaa\x06\x43\x67\xbd\x01\xee\x71"
-  "\xab\x37\x5c\xdd\x22\xdc\x73\x4c\xae\x37\xb0\x32\x80\x1f\xec\xf7"
-  "\xac\x37\xfc\x30\x99\xf1\x85\x1f\x06\x31\xbe\x20\xc8\xb8\x93\xde"
-  "\x70\xf5\x4a\xf7\x7a\x03\xeb\x53\xb4\x9e\x1e\xf5\x86\x1f\x1e\xe9"
-  "\xac\x37\xd4\xe6\x7a\xd6\x1b\x1a\x07\xcb\xfb\x95\xe5\xa8\x5c\x6f"
-  "\xf8\xe1\xb5\x5f\x8e\xde\xe0\xb1\xaf\x99\xe4\x7a\x83\xe5\x39\xef"
-  "\xf5\x06\xcb\x16\xef\xf4\x06\xec\x7f\xee\xf4\x06\xcb\x79\xd7\xfe"
-  "\x27\xd7\x1b\x2c\xd7\xdc\xeb\x0d\x8d\xfd\x89\x4c\x6f\xc0\xf2\xdd"
-  "\xe9\x0d\x8d\x8f\xc9\xca\xef\xa4\x37\x34\xce\x96\xeb\x0d\x2c\x9f"
-  "\xa4\x37\x34\xda\x18\x26\xd7\x4e\xf6\x5e\x6f\x68\xbc\xd8\xb5\xde"
-  "\xd0\x58\x23\xd7\x1b\x1a\x0b\x19\xa6\x36\xa9\x99\xde\xd0\x58\xc2"
-  "\xd2\x6b\x27\x39\xa7\x4b\x7a\x03\x4b\xef\xac\x37\x34\x69\xbb\xd1"
-  "\x1b\xfc\x6d\x79\x43\xd4\xed\x61\x43\x34\xed\x99\xd3\x22\x47\x56"
-  "\xdf\x6b\x77\xc4\x2a\x88\x82\xb9\xbe\x12\x38\xc5\x02\xa2\x44\xff"
-  "\x00\x49\x9f\x01\xc7\x5b\xc0\xf6\x08\x20\x7f\x38\x14\x87\xfc\xc1"
-  "\xd0\x07\xda\x94\x74\x04\x0d\xb7\xd8\xc2\x47\x45\x20\x87\x68\xcb"
-  "\x1b\x6c\xb1\x66\x8e\x9b\xd2\x86\xfb\x03\x96\x12\xe5\xfc\x06\xf7"
-  "\x9c\x62\x6d\x25\xcf\x41\x9f\xf7\x9b\x31\x87\xf1\x89\xd2\xe8\x1a"
-  "\xda\x8f\x91\x4b\xbc\x05\x5c\xc2\xd8\x62\xa2\xdc\xc2\x3f\x4a\x43"
-  "\xb2\x93\x48\x50\xff\x06\xa2\xee\xaf\x50\xf8\xfe\x1e\x7a\xa8\x1d"
-  "\x78\xc5\xe4\xe1\x3c\x37\xa2\x5a\x83\xfe\x7d\x06\x30\x6e\x51\xd8"
-  "\xc7\x26\x70\x8b\x37\xae\x93\xf0\xdd\x71\xc0\x29\x4a\x19\xa7\xc0"
-  "\xb8\x06\x6d\x8c\x53\xdc\xd3\xde\xaa\xbd\xcf\xb1\x3f\xc0\xb1\xef"
-  "\x43\xda\x1f\xd0\xb1\x4d\xe2\x13\xc8\x25\xf8\xf9\x5a\xf2\xa0\x95"
-  "\xad\xdb\x48\x78\x9a\xad\x99\x0d\xaf\x06\x3d\x66\x1e\xf1\x2b\x89"
-  "\xaa\xc2\x7d\xfb\x21\x25\xd5\xfb\xc8\x9a\x27\xc9\x3d\x36\xe4\x0f"
-  "\xa9\x7c\x41\x49\xf5\x0e\x82\xbe\x0b\x81\x5f\x8e\xc9\x12\x38\xc4"
-  "\xd4\x05\x1e\x38\x04\xcc\xd5\xc8\x23\xd8\x1c\xdd\x7c\xfe\x94\xf6"
-  "\x14\xf1\x9e\x1b\x36\xd3\xf8\x57\x1e\xf7\x0a\xe7\x0d\xd1\xd8\xc2"
-  "\x06\x5b\xec\x41\xd3\x22\x99\x2f\xcb\x09\x7a\xee\x2f\xcf\x45\xa1"
-  "\x8f\xc2\xf7\xaa\xea\x14\xe8\x97\x1b\x63\x54\x72\x07\x46\x45\xc8"
-  "\xf6\x74\x74\x08\x32\xeb\x60\x32\x43\x0e\x38\xb7\x81\xf0\xf3\x6d"
-  "\x4a\xf2\xff\xd9\xfb\xfa\xb8\xa8\xaa\xfc\xff\xc3\xbd\xa3\xa2\x22"
-  "\x0f\x06\x2e\xba\x64\x63\x61\x21\x8c\x86\xa5\x2d\x16\x6e\xa8\x58"
-  "\xf8\x4b\x04\x5b\xdd\xd0\x4c\xd1\x40\xb1\x50\x51\x51\xc9\x07\x9e"
-  "\x52\x53\x43\x1c\x0a\x5c\x54\x14\xec\x8b\xad\xf6\x55\xc3\xd2\x5d"
-  "\xdc\x74\x9b\x36\xdc\x45\x43\xc0\x56\x77\xb1\xd5\x6d\x72\xd1\xd0"
-  "\xd0\x46\x45\x79\x9a\x99\xfb\xfb\x9c\x7b\xee\x78\xe7\xce\xdc\x3b"
-  "\xcc\x9d\x01\x16\xfd\xfa\xc7\xbc\x60\xee\x3d\xf7\xdc\x73\x3e\x9f"
-  "\xf7\xf9\x9c\xf7\xfb\xcc\x79\x80\x7b\xee\xec\x9a\x8e\x26\x2d\xe2"
-  "\xcf\xaa\xf4\x45\xbb\x8c\x64\x3f\x48\xe3\xaa\x84\x9e\x46\xf0\x0b"
-  "\x93\x49\xa1\x03\x77\x9b\x58\xde\x97\x85\xcf\xaf\xcc\x70\xe9\x83"
-  "\x79\x1f\x60\xbf\x57\x61\x0b\xf8\xe8\x07\xe2\x23\x26\xd3\x95\xfd"
-  "\xab\x5f\x15\xa0\x84\xbc\x1f\x6f\x6d\x05\xde\xc7\x9d\x75\x69\xda"
-  "\x1b\x97\x5d\x9f\xd3\x82\xd7\xe7\xd4\x20\x7d\x0e\xd9\x6f\x10\x70"
-  "\xe1\x82\xf7\xf2\x80\x32\xf8\xb1\xeb\x72\x5a\x03\x30\x8e\x3c\x77"
-  "\x5d\xc1\x6b\x89\xbe\x63\xfd\x63\xe0\xfc\x82\xcf\xbc\x34\xf1\xb9"
-  "\xca\xbd\xe7\xc8\xda\x4c\x0b\x5f\xb4\xee\xe9\xaf\x33\xf9\x83\x59"
-  "\x7f\x2b\x14\xcf\xb7\xb9\xe1\x72\x67\xf1\x89\x64\xe0\x4e\xc9\x72"
-  "\xfd\x72\x27\xa9\x6b\xf8\xc5\xf3\x01\xf3\x4b\x83\x92\xf8\xa5\xb1"
-  "\xa7\x63\x7e\x69\x94\xdc\xff\xa0\x73\xfd\xe2\xfa\x80\xf9\xe5\x4e"
-  "\x29\xf1\x4b\xd3\x6e\xc7\xfc\xd2\x54\x64\xcb\x2f\x78\x8c\xcb\x34"
-  "\xbe\x65\x1a\xdb\xc2\xfd\x29\xab\x8b\x28\x94\x78\x6f\x3e\x27\xfc"
-  "\x6f\x3e\x9f\xb3\xa2\x0c\xaf\xc9\xdf\x84\x4e\x85\xe3\xbe\xb2\x79"
-  "\x99\xed\x31\x2d\x83\xd9\x7c\x4e\x3d\x37\xb6\xdd\x7a\x93\x70\xd4"
-  "\xd6\x43\x38\x5f\xbc\xee\x09\xaf\x9d\xfb\x74\xb9\x96\xda\x0c\x5c"
-  "\x71\x33\xf4\xe5\xd8\xf6\x64\xff\xf5\xd6\x21\x78\xbc\xea\xcb\xbb"
-  "\x5a\x4a\x0d\xb6\x67\xfb\xcb\xc7\xa7\xc5\xee\x1f\xa0\x73\xc1\x7d"
-  "\x26\xde\x0f\x96\x31\x5b\x0b\x69\xc8\x8b\x0c\xbb\x8d\xc7\x71\xb8"
-  "\x75\x4b\x2d\x3e\xa3\x23\x0c\x43\x87\x06\x8b\xe1\x89\x5d\x63\x09"
-  "\x7d\xe6\xce\x16\xe8\x0f\x1b\x90\xe7\xcc\x24\x1e\x5b\xc6\x55\x01"
-  "\x7d\x2b\x81\xa3\xef\xc4\xfb\xf2\x42\x5f\xc9\xb4\x26\xf4\x7c\x7d"
-  "\x1f\x94\x95\xc3\x14\xbc\x5b\x1a\x53\xdb\x84\x98\xba\xcd\x61\x0a"
-  "\xb0\x75\x0f\x53\x66\x6b\x24\xa7\x10\x4c\x69\xef\x61\x8a\xed\x2b"
-  "\x57\x05\xf8\x61\x5c\x99\x30\x85\xfb\x49\x82\xa9\x4b\x92\x98\xfa"
-  "\xe6\x82\x38\xa6\xf4\x83\xcd\x31\xd5\x18\x4d\x30\xd5\x72\xe7\xc4"
-  "\x0c\xc0\xd4\x0c\xb9\x98\x6a\x69\x10\x68\x6a\xca\x45\x64\x1e\x5c"
-  "\xeb\x34\x4b\x4d\x6d\xd2\xd0\xb7\x7d\xc6\x06\xdf\x06\x1d\xdd\x70"
-  "\x4f\x47\xb7\xae\x71\x4c\x47\xb7\xae\xb6\x6f\xee\x5b\xeb\xc5\x53"
-  "\x90\xf2\x14\xb4\x9f\xaa\x68\x32\xf7\x6d\x3f\xab\x8f\x9b\x53\x30"
-  "\xee\xc4\xf5\x31\xb9\x67\x3d\x67\xc9\x60\x36\xf7\xcd\x10\xd9\xfc"
-  "\x81\xf8\xdc\xb7\x4f\x52\xf3\xcd\xb4\x4a\xbe\xc8\xfc\xa4\x7c\x8b"
-  "\xf9\x49\xf9\x22\x3a\x25\x1f\xe1\x67\xcd\x75\xca\xa9\x68\xa2\x53"
-  "\x4e\x45\x63\x9d\x92\xcf\xf2\xbb\x53\xd1\x26\x9d\x92\x0f\xf7\x89"
-  "\x4e\x39\x15\x7d\x05\x3e\x58\xa7\xe8\xeb\x4f\x45\x8b\xe9\x14\xfd"
-  "\x1d\xc2\x7b\x5b\x2f\xd8\x5e\x3b\x92\x6f\xa6\x89\xf3\xcd\x34\x71"
-  "\x3e\xa7\x89\xf3\x59\x4d\x4c\xde\xab\x62\xcb\x87\xdf\x8b\xf3\x35"
-  "\x7f\x2f\xaf\x19\x0c\xdc\xfc\xb7\x56\x2d\xf6\x85\x50\x13\xc3\x33"
-  "\x29\x62\x9a\xd8\xc0\xfd\xfe\xd1\x7a\xc1\xa4\x89\x5b\x48\x7a\x36"
-  "\x0f\x88\x2f\x36\xe6\xbf\x19\xb9\xf9\x6f\x46\x6e\xfe\x1b\xf1\xab"
-  "\xb5\x26\x36\xda\x31\xff\x8d\xe0\x88\x2d\x67\x92\x94\x26\x36\x8a"
-  "\xcc\x7f\x6b\x4e\x16\x9d\xff\x46\xa1\xc1\x3c\x96\x98\x13\xc2\xf9"
-  "\x6f\x46\xc1\xfc\x37\x8c\xb3\xfb\x0c\x5f\xf5\x26\x5f\xf1\x73\xe0"
-  "\x98\x78\x71\x2d\x9c\x6f\xa6\x85\xf3\x59\x2d\x7c\x2a\xda\x34\x07"
-  "\x8e\xd9\x86\xf3\xb7\xd6\xc2\xf9\xf7\xd2\x9b\xb4\x30\x7e\x86\xe0"
-  "\x4e\x4c\x0b\x33\x97\x2d\x71\x27\xd0\xc2\xa0\xf3\x4c\x5a\xb8\xe5"
-  "\x75\x33\x2d\x4c\xa1\xfe\x42\x2d\x8c\xf3\x17\xd1\xc2\x14\x1a\x2f"
-  "\xc8\xdf\x52\x0b\x53\x68\xb6\x49\x0b\xe3\xfc\x4d\xd8\xbd\xa7\x85"
-  "\x29\x17\x6e\x0e\x5c\xf3\xa3\xb2\xb5\x30\x85\xd8\x39\x70\x07\xb6"
-  "\x93\xdf\xa8\x04\x3a\x98\x42\xc2\xf9\x6f\x14\x22\xf3\xdf\x28\x17"
-  "\x32\xff\x8d\x42\xdc\xfc\xb7\x66\x3f\xf3\xeb\xbc\x0e\x26\xd7\xf1"
-  "\xfc\x37\x76\xde\xdb\x26\x17\x99\xfa\xf7\x17\x5d\x50\xff\xfa\xda"
-  "\xd0\xbf\xbe\x0f\x96\xfe\xa5\x28\xc7\xf4\x2f\x45\x75\x11\xfd\xfb"
-  "\x80\xe9\xac\x4d\x2e\x44\xff\x52\x0a\xc7\xf4\x2f\xa5\xe8\x22\xfa"
-  "\xf7\x01\xd3\x59\x9b\x68\xa2\x7f\xa9\xee\x8e\xe9\x5f\xaa\xbb\x4d"
-  "\xfd\x6b\x5b\x67\xf5\x39\xcb\xeb\xac\x3e\x67\x25\x75\x16\xd5\xfd"
-  "\xa2\x4d\x9d\x45\xf5\xf6\xbd\xa7\xb3\xa8\x9e\xcb\x58\xde\x43\xf5"
-  "\x9c\xc6\xf2\x1e\xaa\x67\xff\x36\x75\x16\xe5\x9a\xf3\x50\x67\xb5"
-  "\xa3\xce\xda\xa4\x20\xda\x9d\x72\x7d\xc3\x21\x9d\x45\xb9\xce\x10"
-  "\xea\x2c\xf7\x0c\x2b\x9d\x45\xb9\x7e\x65\xb7\xce\xa2\x5c\x2f\x3b"
-  "\xa4\xb3\x28\xd7\x5a\xbb\x74\x16\xd5\x73\xbc\xa8\xce\xa2\xba\x6b"
-  "\x25\x75\x16\x77\xcf\x9a\x1b\xf7\xe2\xd7\x55\x53\xbd\x8e\x74\x79"
-  "\x9d\x45\xf5\x9a\x22\xca\x83\xa9\x5e\x6f\x10\x5e\xd5\x33\xbc\x43"
-  "\x74\x16\xe4\x2b\xaa\xb3\xa8\x5e\xe7\x58\x3e\x4a\xf5\x8c\xb0\xd2"
-  "\x59\xf8\x19\x31\x9d\x45\xf5\xee\xc9\x3d\x13\x2e\xd0\x59\x5c\x1e"
-  "\x10\x5f\x06\x4b\xea\x2c\xaa\xf7\x57\x24\xde\xf4\xce\x21\xf1\x86"
-  "\xf8\xd5\x4a\x67\x51\xbd\xe7\xb7\xa9\xb3\x38\x1c\xb1\xe5\x94\xd2"
-  "\x59\x54\xef\x43\x56\x3a\x8b\xea\x7e\x41\x5c\x67\xf5\xd9\xcc\x63"
-  "\xa9\xcf\x50\x81\xce\xa2\x7a\x37\xdf\x17\x3a\x4b\x1a\x5f\x53\xac"
-  "\x74\x16\xe5\x76\x5a\xb6\xce\xa2\xfa\xb8\xc8\xd2\x59\x2c\xee\x44"
-  "\x74\x16\xd5\x27\xd2\x12\x77\x42\x9d\xd5\x67\xbe\xb8\xce\xea\x93"
-  "\x21\xd0\x59\x6c\xfe\x62\x3a\xab\xcf\x01\x41\xfe\x56\x3a\xab\xcf"
-  "\x49\x81\xce\xe2\xd2\xf1\x3a\xcb\x3d\x91\xc4\xd2\xee\xf2\xe7\x2a"
-  "\x52\xee\x91\xd2\x3a\xcb\x7d\xaa\x50\x67\xb9\x07\x90\x76\xef\x9e"
-  "\x4e\x74\x96\x7b\x28\xb9\xde\x7d\xad\xf9\xf5\x7b\x3a\x8b\xbb\xce"
-  "\xeb\x2c\x77\xb5\x3c\x9d\xe5\xd1\x05\x75\x96\xa7\x0d\x9d\xe5\xf9"
-  "\x80\xe9\x2c\xcf\x31\x8e\xe9\x2c\xcf\xb0\x87\x7c\xbe\x23\xf8\xbc"
-  "\x7b\x31\xe1\x5e\x5e\xe7\x1d\xe3\xf3\x5e\x36\xf5\xaf\x6d\x3e\xdf"
-  "\xbf\x98\xe7\xf3\xfd\x8b\xa5\xf9\x7c\xdf\x03\xb6\xf9\x7c\xbf\x3a"
-  "\x9e\xcf\xfb\x90\xb9\x3d\x94\x0f\x19\xc7\xa4\xbc\xaf\xb6\xcd\xe7"
-  "\xbd\x67\x3f\xe4\xf3\xed\xc9\xe7\x3d\x37\x10\x4c\x79\x0f\x75\x8c"
-  "\xcf\x7b\xab\x84\x7c\x7e\xc0\x64\x6b\x3e\xef\x9d\x63\x3f\x9f\xf7"
-  "\x3e\xe2\x18\x9f\xf7\x3e\x6c\x1f\x9f\xf7\xf1\x11\xe7\xf3\x7d\x4b"
-  "\xa4\xf9\x3c\xb9\x67\xcd\xc1\xfa\x1d\xe5\x39\x58\xbf\x75\x5d\x9f"
-  "\xcf\xf7\xf3\x17\xe7\x5b\xfd\x86\x92\xfe\xdb\xc7\xbb\x63\xf8\xbc"
-  "\x8f\xb7\x38\x9f\xef\xb7\x87\xf0\x1e\x1f\x5f\x6b\x3e\x0f\xcf\x88"
-  "\xf2\xf9\x7e\xe7\xb9\x67\xbc\x85\x7c\x9e\xe4\x01\xf1\xe5\x8e\x34"
-  "\x9f\xff\x45\x0e\x89\x37\xbf\x98\x4d\xe2\x0d\xf1\xab\x35\x9f\xff"
-  "\xc5\xa8\xb6\xf9\x3c\xc1\x11\x5b\x4e\x49\x3e\xff\x8b\x0c\x6b\x3e"
-  "\xdf\x77\xbf\x38\x9f\xef\xff\x06\x8f\x25\x5f\x83\x90\xcf\xff\xe2"
-  "\xe4\xfd\xc1\xe7\x25\xf1\xe5\x6f\xcd\xe7\x7d\x77\xca\xe7\xf3\xbe"
-  "\x67\xe4\xf1\x79\x8c\x3b\x31\x3e\xdf\xff\x51\x4b\xdc\x09\xf9\x7c"
-  "\xff\x51\xe2\x7c\xbe\xff\x64\x21\x9f\xc7\xf9\x8b\xf1\xf9\xfe\x6b"
-  "\x04\xf9\x5b\xf1\xf9\xfe\xdb\x84\x7c\x9e\xa4\xe3\xf9\xfc\x80\x50"
-  "\x12\x4b\xfb\x4e\x95\xcf\xe7\x07\x3c\x2a\xcd\xe7\x07\x0c\x16\xf2"
-  "\xf9\xfe\x64\x9e\x36\x35\x20\x9a\xf0\xf9\x01\x6e\xe4\x7a\xdf\x29"
-  "\xe6\xd7\x79\x3e\x4f\xae\xf3\x7c\x7e\x40\xac\x3c\x3e\xdf\xa3\x0b"
-  "\xf2\x79\x57\x1b\x7c\xde\xf5\x01\xe3\xf3\x7e\x5e\x8e\xf1\x79\x3f"
-  "\x4f\xc7\x79\xe3\x13\x17\x78\xde\xf8\xc4\x05\x69\xde\xe8\x77\xd9"
-  "\x36\x6f\x1c\xa4\xe4\x79\xe3\x63\x6b\x48\x1c\x7f\x8c\x8b\xe3\x8f"
-  "\x0d\x6a\x9b\x37\x0e\xdc\xf6\x90\x37\xb6\x27\x6f\x1c\x90\x4c\x78"
-  "\xe3\xc0\x78\xc7\x78\xe3\xc0\x38\x21\x6f\xf4\xdf\x68\xcd\x1b\x07"
-  "\x9e\xb4\x9f\x37\x0e\xbc\xee\x18\x6f\x1c\x58\x6f\x1f\x6f\x7c\x2c"
-  "\x52\x9c\x37\xfa\xd5\x49\xf3\x46\x72\xcf\xba\xaf\x57\xde\xe4\xfb"
-  "\x7a\xe5\xf1\xae\xcf\x1b\x95\x33\xc4\xfb\x75\x65\x3c\xe9\x27\x1e"
-  "\x9b\xd8\x31\xbc\xf1\xb1\x89\xe2\xbc\x51\x79\x91\xf4\xaf\x8f\x45"
-  "\x5b\xf3\x46\x78\x46\x94\x37\x0e\xf2\xe2\x9e\x99\x28\xe4\x8d\x24"
-  "\x0f\x88\x2f\x43\xa5\x79\xe3\xa0\x93\x24\xde\x0c\x22\x7b\xce\x70"
-  "\x7e\xb5\xe6\x8d\x83\x16\xb7\xcd\x1b\x09\x8e\xd8\x72\x4a\xf2\xc6"
-  "\x41\x47\xad\x79\xa3\x5f\xad\x38\x6f\x7c\x22\x8f\xc7\xd2\x13\x23"
-  "\x85\xbc\xf1\x71\x97\xfb\x83\x37\x4a\xe2\x6b\x86\x35\x6f\x7c\xfc"
-  "\x9c\x7c\xde\xf8\x44\x4f\x79\xbc\x11\xe3\x4e\x8c\x37\x3e\x31\xd5"
-  "\x12\x77\x42\xde\xf8\xc4\x62\x71\xde\xf8\xc4\x46\x21\x6f\xc4\xf9"
-  "\x8b\xf1\xc6\x27\x8e\x08\xf2\xb7\xe2\x8d\x4f\x9c\x11\xf2\x46\x92"
-  "\x8e\xe7\x8d\xfe\xc9\x24\x96\xfa\x6d\x96\xcf\x1b\xfd\xa7\x4a\xf3"
-  "\x46\xff\x37\x84\xbc\xd1\x3f\x98\xb4\x7b\xff\x0d\x84\x37\xfa\x87"
-  "\x93\xeb\x7e\x59\xe6\xd7\x79\xde\x48\xae\xf3\xbc\xd1\x3f\xbf\x2d"
-  "\xde\x68\x9b\x53\xa8\x42\x79\x4e\xa1\x0a\x35\xe7\x14\x27\x05\x9c"
-  "\x62\xf0\x28\xdb\x9c\x62\xc8\x5a\x9e\x53\x3c\x75\x99\xb4\xf1\xa7"
-  "\x4e\x92\x36\xfe\x14\xeb\xb3\xd6\x8f\xfd\xc2\xd6\x9c\x46\xd4\xc1"
-  "\x1b\xa5\xd4\xfb\xcb\x91\x22\x6b\x39\x70\x0a\xe0\x77\x49\xd3\x31"
-  "\xa7\x78\xca\x25\x72\xf5\xf7\x8c\x5b\x01\xf0\xd8\x5a\x8e\xd7\x26"
-  "\x01\xaf\xad\x85\xef\xd0\x5e\x8e\x2f\x2c\xa5\x2a\x81\x7b\xaa\x81"
-  "\xfb\xb1\x6b\x9b\xd9\x75\xcf\xda\x6e\xec\xf9\x19\x37\x80\x73\xcc"
-  "\x69\xfb\xbc\x13\xd3\x59\x27\xab\x6b\x19\x23\x3e\xdb\x24\x2a\xce"
-  "\xec\xcc\x13\x7c\x7e\xa9\xae\x0e\xe1\x73\x4f\x0a\x96\x20\x6f\x7c"
-  "\xd6\x89\x47\x1d\xf2\x74\xcf\x70\x71\xc7\x67\x9e\xb8\x37\x10\xee"
-  "\x7a\xc0\x58\x4e\xb8\xeb\x52\xdf\x5e\x59\xb7\x90\x6a\xd7\x2d\x9e"
-  "\x5b\x7c\x88\x79\xc5\xd2\x00\x65\xc3\xd2\x80\x81\xb7\x6f\x03\x77"
-  "\xd5\x59\x9e\x89\xf1\xc9\x5e\x7c\xd6\x09\x3e\x7b\x52\xcf\x71\x57"
-  "\x66\x5e\x00\x2a\x9c\x8b\x5c\xf1\x58\xe7\x30\x7c\x1e\xc6\x69\xe4"
-  "\xf9\x94\x1f\xc4\xfa\xdb\x01\x7e\xe6\xfb\x5c\xe2\x71\x4f\xe3\xed"
-  "\x00\x54\x11\xfb\x1d\xbb\x6e\x56\x6f\x5a\x37\x7b\x0b\x85\xe8\x96"
-  "\x06\x50\xdb\x97\x98\x71\x57\x1f\xcc\x5d\x9f\xb7\xc1\x5d\x9f\x3c"
-  "\xed\x18\x77\x7d\xb2\x42\xc8\x33\x54\x57\xad\x79\xc6\x53\xc3\xed"
-  "\xe7\x19\x4f\x4d\x75\x8c\x67\x3c\x35\xc5\x3e\x9e\xf1\xd4\x11\x4b"
-  "\x9e\xb1\x8f\xe5\x19\x83\x43\x31\x16\xc5\x79\x06\xb9\x67\xdd\x37"
-  "\x0c\x99\xca\xf7\x0d\x43\x06\x75\x7d\x9e\x11\x50\x26\xde\x0f\x04"
-  "\x9c\x66\xf7\xb4\xa4\x9e\x3a\x2c\xbd\xa7\xa5\xa3\x1c\xe3\xa9\xc3"
-  "\xe2\x1c\x63\x08\xd9\xff\x0f\xee\x9b\xfa\x20\x9e\x63\xc0\x33\xa2"
-  "\x1c\x63\xc8\x32\xcb\x67\x08\xc7\x78\xaa\x94\x70\x8c\x21\x39\xd2"
-  "\x1c\x23\x70\x28\x89\x3f\x43\x0c\x24\xfe\x10\x9f\x5a\x73\x8c\x21"
-  "\xe7\xda\xe6\x18\x04\x43\x6c\x39\x25\x39\x46\xe0\xa3\xd6\x1c\x63"
-  "\x70\x88\x38\xc7\x08\xba\xc3\xe3\x28\x28\x4f\xc8\x31\x02\xe3\xef"
-  "\x0f\x8e\x21\x89\xad\x32\x21\xbf\x08\x1a\x29\x9f\x5f\x04\xcd\x97"
-  "\xc7\x2f\x30\xe6\xc4\xf8\x45\x10\xd7\xff\x13\xbc\x58\xf3\x8b\xa0"
-  "\x33\xe2\xfc\x22\xe8\xaa\x90\x5f\xe0\xfc\xc5\xf8\x85\xca\x47\x90"
-  "\xbf\x15\xbf\x50\x0d\x17\xf2\x0b\x92\x8e\xe7\x17\xaa\xb3\x9c\x56"
-  "\xfb\x41\x3e\xbf\x50\x1d\x91\xe6\x17\xaa\xe3\x42\x7e\xa1\x52\x13"
-  "\x1e\xa1\xaa\x23\xfc\x42\x55\xcc\xf1\x0e\xad\xf9\x75\x9e\x5f\x90"
-  "\xeb\x3c\xbf\x50\xb5\xb5\xff\xfb\xc3\xf5\xac\x5d\x6a\x5c\x6a\xd8"
-  "\x3e\xc7\xfa\xf6\x61\x7b\xbb\xc6\xef\xcc\x0f\xd8\x7a\xd6\x4d\x43"
-  "\xdd\xc8\xd8\x4e\xf0\x18\xc7\x7e\x67\x0e\xee\x22\xbf\xff\x3f\x68"
-  "\xf3\xac\x87\xe9\x88\x5f\x86\x3b\xf8\xfb\xff\xf0\x2e\x32\xff\xfd"
-  "\x41\x9b\x97\x11\xcc\xfd\x86\xfe\xac\x83\xf3\xdf\x9f\xb5\x39\xff"
-  "\xdd\xb6\x16\x7e\x61\x22\xaf\x85\x5f\x98\x28\x3d\xbe\x3e\x62\xbc"
-  "\x6d\x2d\x1c\x92\xcb\x6b\xe1\xe7\xee\x10\x2e\xfa\xdc\x79\xc2\x45"
-  "\x9f\x63\x7f\xaf\xd2\x3f\x1e\x13\x4d\xc6\xd7\x35\x22\xe3\xeb\xcf"
-  "\x79\xe1\x7d\xd2\xee\xed\x9f\x46\x8d\xc8\x30\xdf\x3f\xed\xcf\xf0"
-  "\xcc\xc3\x71\xf7\xf6\x18\x77\x7f\x86\x9b\xd3\x3f\xf2\xa2\x63\xe3"
-  "\xee\x23\x2f\x08\xf5\xf0\x0b\xcd\xd6\x7a\xf8\xb9\x31\xf6\xeb\xe1"
-  "\xe7\xe2\x1d\xd3\xc3\xcf\xc5\xd9\xa7\x87\x9f\x3b\x21\x3e\xee\x3e"
-  "\x22\x02\xe3\x51\x5c\x0f\x93\x7b\xd6\x3a\x26\x24\x9e\xd7\x31\x21"
-  "\xc3\xbb\xbe\x1e\xfe\xd5\x59\x71\xcd\xf2\xab\x8b\x44\x0f\x3f\x57"
-  "\xd6\xfe\x7a\xf8\xb9\x32\x71\x3d\x1c\x32\x99\x68\x87\xe7\xca\xad"
-  "\xc7\xdc\xe1\x19\x51\x3d\x1c\xb2\x8e\x7b\xa6\x4c\xa8\x87\x49\x1e"
-  "\x10\x73\x76\x4b\xeb\xe1\x51\xa3\x49\x0c\x1a\xd5\x87\xc4\x20\xe2"
-  "\x53\x6b\x3d\x1c\x72\xb9\x6d\x3d\x4c\x30\xc4\x96\x53\x52\x0f\x8f"
-  "\x1a\x6a\xad\x87\x47\x84\x8b\xeb\xe1\x17\xba\xf1\x38\x7a\x7e\x8f"
-  "\x50\x0f\x8f\x5a\x76\x7f\xe8\x61\x49\x6c\x9d\x15\xea\xe1\xe7\xc7"
-  "\xcb\xd7\xc3\xcf\xbf\x23\x4f\x0f\x63\xcc\x89\xe9\xe1\xe7\x4f\x58"
-  "\x62\x4e\xa8\x87\x9f\xff\x41\x5c\x0f\x3f\xdf\x2c\xd4\xc3\x38\x7f"
-  "\x31\x3d\xfc\xc2\x60\x41\xfe\x56\x7a\xf8\x85\x31\x42\x3d\x4c\xd2"
-  "\xf1\x7a\xf8\x85\x5a\x12\x43\x9f\xbd\x2e\x5f\x0f\xbf\x70\x42\x5a"
-  "\x0f\xbf\x70\x5a\xa8\x87\x5f\x28\x22\xba\xf7\x85\x26\xa2\x87\x5f"
-  "\x38\x4c\xae\x3f\x5b\x6f\x7e\x9d\xd7\xc3\xe4\x3a\xaf\x87\x43\x5d"
-  "\x1f\xae\x6f\xbd\x9f\xf4\xf0\xe8\xa3\x8e\xe9\xe1\xd1\xa5\x5d\x83"
-  "\xdf\x3f\x68\xba\x2b\xd4\x8f\x70\xae\x17\x27\x3b\xc6\xef\x5f\x8c"
-  "\xee\x1a\x7e\x79\xd0\x74\xd7\xaf\x11\xf1\x4b\xd8\x55\xc7\xfc\x12"
-  "\x56\xe7\xb8\xee\x8a\x28\xe3\x75\x57\x44\x99\xb4\xee\x1a\x73\xdc"
-  "\xb6\xee\x7a\xc9\x8d\xd7\x5d\xe1\x0b\x08\xe7\x09\x9f\x4c\x38\x4f"
-  "\xb8\x57\xdb\xba\x6b\xdc\x46\xa1\xee\x1a\xd3\xfc\x50\x77\x75\x84"
-  "\xee\x7a\x31\x9f\x60\x6d\xdc\x54\xc7\x74\xd7\xb8\x29\x42\xdd\x35"
-  "\x61\xb1\xb5\xee\x1a\x77\xd4\x7e\xdd\x35\xee\xa2\x63\xba\x6b\xdc"
-  "\x05\xfb\x74\x57\xf8\x68\x71\xdd\x35\x46\x23\xad\xbb\xc8\x3d\x6b"
-  "\xbe\x3c\xfe\x22\xcf\x97\xc7\xef\xeb\xfa\xba\x6b\xfc\x44\x71\x6e"
-  "\x3c\x7e\x2a\xd1\x5d\xe1\xa1\xed\xaf\xbb\xc2\x43\xc5\x75\xd7\xf8"
-  "\x93\x84\xa3\x86\x87\x59\xeb\x2e\x78\x46\x54\x77\x8d\x37\x70\xcf"
-  "\x84\x0a\x75\x17\xc9\x03\x62\x4e\x7f\x69\xdd\xf5\x12\x39\x5f\x8b"
-  "\x7a\x69\x1d\x89\x41\xc4\xa7\xd6\xba\xeb\xa5\x37\xda\xd6\x5d\x04"
-  "\x43\x6c\x39\x25\x75\xd7\x4b\x7b\xac\x75\xd7\x98\x63\xe2\xba\x2b"
-  "\x62\x0d\x8f\xa3\x88\x47\x85\xba\xeb\xa5\xeb\xf7\x87\xee\x92\xc4"
-  "\xd6\x44\xa1\xee\x7a\xf9\xb8\x7c\xdd\xf5\xf2\x4d\x79\xba\x0b\x63"
-  "\x4e\x4c\x77\x45\x8c\xb6\xc4\x9c\x50\x77\x45\x4c\x13\xd7\x5d\x11"
-  "\x8b\x85\xba\x0b\xe7\x2f\xa6\xbb\x22\x76\x0a\xf2\xb7\xd2\x5d\x11"
-  "\x47\x85\xba\x8b\xa4\xe3\x75\xd7\x84\x19\x5c\x5f\x17\x2f\x5f\x77"
-  "\x4d\x18\x2d\xad\xbb\x26\x8c\x17\xea\xae\x09\xbe\x44\x5f\x4d\x48"
-  "\x22\xba\x6b\x82\x8a\x5c\x1f\x13\x67\x7e\x9d\xd7\x5d\xe4\x3a\xaf"
-  "\xbb\x26\xa4\x3f\x5c\xef\x7a\x3f\xe9\xae\x57\x86\x3b\xa6\xbb\x5e"
-  "\x09\x7e\xc8\xef\x3b\x82\xdf\x4f\xc8\x25\x9c\x6b\xe2\x49\xc7\xf8"
-  "\xfd\xc4\x72\xc7\xf9\xfd\x14\xb3\xf5\xae\x53\x6c\xac\x77\x8d\xdc"
-  "\x69\x9b\xdf\x4f\xae\xe7\xf9\x7d\x74\x24\xe9\x5b\xa3\x87\x93\xbe"
-  "\x35\xea\x66\xdb\xfc\x3e\x6a\xbe\x90\xdf\x47\x9e\x7f\xc8\xef\x3b"
-  "\x82\xdf\xbf\x92\x42\xb0\x16\x35\xd2\x31\x7e\x1f\x25\x3c\xb7\x8f"
-  "\x9a\x2a\xb2\x0e\x36\x6a\x9b\xfd\xfc\x3e\xea\xb8\x63\xfc\x3e\xea"
-  "\x98\x7d\xfc\x3e\xfa\x51\x71\x7e\x1f\x59\x24\xcd\xef\xc9\x3d\x6b"
-  "\x5e\x36\xf9\x38\xcf\xcb\x26\x6f\xec\xfa\xfc\x7e\xb2\x4a\x9c\x83"
-  "\x4d\x1e\x49\xf8\x7d\xb4\x5f\xfb\xf3\xfb\x68\x3f\x71\x7e\x3f\x79"
-  "\x1f\xe1\x42\xd1\x4a\x6b\x7e\x0f\xcf\x88\xf2\xfb\xc9\xdc\xfa\x87"
-  "\x68\x3f\x21\xbf\x27\x79\x40\xcc\x69\x96\xe6\xf7\xaf\xe6\x91\x18"
-  "\xf4\x6a\x3c\x89\x41\xc4\xa7\xd6\xfc\xfe\xd5\xd1\x6d\xf3\x7b\x82"
-  "\x21\xb6\x9c\x92\xfc\xfe\xd5\x75\xd6\xfc\x3e\xb2\x40\x9c\xdf\x4f"
-  "\x31\x5b\x03\xfb\x1b\x8b\x35\xb0\xaf\x9e\xbe\x3f\xf8\xbd\x24\xb6"
-  "\x54\x42\x7e\xff\x1b\x07\xd6\xbf\xfe\x46\xe6\xfa\x57\x8c\x39\x31"
-  "\x7e\x3f\xe5\x51\x4b\xcc\x09\xf9\xfd\x14\x89\xf5\xaf\x53\x2c\xd6"
-  "\xbf\xe2\xfc\xc5\xf8\xfd\x94\x35\x82\xfc\xad\xf8\xfd\x14\x8b\xf5"
-  "\xaf\x24\x1d\xcf\xef\xa7\x72\xeb\x5f\x23\xe5\x9f\xa1\x41\x4d\xb5"
-  "\xb1\xfe\x75\xaa\xc5\xfa\xd7\x29\xdc\xfa\xd7\xa9\xdc\xfa\xd7\xa9"
-  "\xdc\xfa\xd7\xc8\x70\xf3\xeb\x3c\xbf\x27\xd7\x79\x7e\x3f\xf5\xe1"
-  "\xfa\xd7\xfb\x8a\xdf\xbf\xe6\xe0\xfa\xd7\xd7\x9c\x58\xff\x3a\xb3"
-  "\x9e\xe7\x91\x33\xeb\xa5\x79\xe4\x6b\x6d\xac\x7f\x9d\x31\x82\xe7"
-  "\x91\xd3\xb9\x18\x3e\xfd\x1d\x12\xc3\xa7\x8f\x6a\x9b\x47\x4e\x3b"
-  "\x24\xe4\x91\x31\x83\x1e\xf2\xc8\x8e\xe0\x91\x53\xb9\x75\xb1\xd3"
-  "\xd6\x38\xc6\x23\xa7\xad\x16\xf2\xc8\x59\xdb\xac\x79\xe4\x34\xab"
-  "\xf3\x9f\xa5\x79\xe4\xf4\x6e\x8e\xf1\xc8\xe9\x0a\xfb\x78\xe4\xf4"
-  "\x78\x71\x1e\xf9\x5a\x9d\x34\x8f\x24\xf7\xac\xfb\xff\x19\x66\xf3"
-  "\x2a\x5e\x3f\xd3\xf5\x79\xe4\xeb\xc9\xe2\x7d\xfd\xeb\x6b\x08\x8f"
-  "\x9c\x1e\xd7\xfe\x3c\x72\x7a\x9c\x38\x8f\x7c\xfd\x26\xe9\x73\xa7"
-  "\x27\x58\xf3\x48\x78\x46\x94\x47\xce\xe0\xe6\x3f\x4c\x8f\x13\xf2"
-  "\x48\x92\x07\xc4\x9c\x31\xd2\x3c\x72\xc6\x45\x12\x83\x66\x1c\x20"
-  "\x31\x88\xf8\xd4\x9a\x47\xce\x58\xd7\x36\x8f\x24\x18\x62\xcb\x29"
-  "\xc9\x23\x67\x9c\xb6\xe6\x91\xaf\x49\xac\x89\x9d\xb9\x87\xc7\xd1"
-  "\xcc\xf1\x42\x1e\xf9\x86\xcf\xfd\xc1\x23\x25\xb1\x95\x2c\xe4\x91"
-  "\x6f\x5c\x96\xcf\x23\x67\xf6\x97\xc7\x23\x31\xe6\xc4\x78\xe4\xcc"
-  "\x78\x4b\xcc\x09\x79\xe4\xcc\x0c\x71\x1e\x39\x73\x9b\x90\x47\xe2"
-  "\xfc\xc5\x78\xe4\xcc\x13\x82\xfc\xad\x78\xe4\xcc\x1f\x84\x3c\x92"
-  "\xa4\xe3\x79\xe4\xac\xb5\x24\x86\xbe\xe6\xc0\x7a\xd8\x59\xf1\xd2"
-  "\x3c\x72\xd6\x02\x21\x8f\x9c\x15\x46\xf8\xe2\xac\x7c\xc2\x23\x67"
-  "\x4d\x21\xd7\x5f\xcb\x32\xbf\xce\xf3\xc8\xd7\x2c\xd6\xc3\xce\xda"
-  "\xeb\xdc\x7a\xd8\x79\x71\x3c\xc7\x98\x17\x27\xbd\x1e\x36\x76\x82"
-  "\x6d\x8e\x11\xb7\x9f\xe7\x18\x6f\x92\x33\x6d\xa8\x39\xe4\x4c\x1b"
-  "\x6a\x0e\xbb\x37\x69\x2b\xb4\x71\xb2\x1e\xb6\x84\x02\x1e\xc8\xaf"
-  "\x87\x9d\x89\x39\xc6\x9c\x21\x91\x02\x8e\x11\xbb\x91\x5d\x1b\x8b"
-  "\x79\x46\x43\x13\xc2\xf7\xc4\xd7\xc9\x96\x74\xee\x3a\xd9\xbb\x0f"
-  "\xf2\x3a\xd9\xd9\x77\x1c\xe3\xb8\xb3\x2d\xce\xbf\x49\xb0\x3e\x53"
-  "\x96\x9a\x63\xff\xf9\x37\xd4\x1c\xc7\xce\xbf\xa1\xe6\xd8\x77\xfe"
-  "\x0d\x35\xc7\xea\xfc\x1b\xb2\x4e\x36\x76\x62\xab\x24\xef\x88\x8d"
-  "\xc0\x79\x5b\xf7\x17\x71\x66\xbf\x2b\xc6\x4d\xe8\xfa\xbc\xe3\x4d"
-  "\xf1\xf3\x49\xa8\x37\xef\x10\xde\x31\xe7\x42\xfb\xf3\x8e\x39\xe2"
-  "\x67\xdf\x50\x71\xf3\x49\x8c\x9e\x73\xef\x1c\x1b\x9e\x77\xcc\x11"
-  "\x3f\xfb\x86\x8a\xdb\x69\xf9\x0c\xe1\x1d\x73\xc8\xd9\x37\x54\xdc"
-  "\x51\x69\xde\x11\x3f\x95\xc4\xa5\xf8\xc1\x24\x2e\x11\x9f\x5a\xf3"
-  "\x8e\x38\x43\xdb\xbc\x83\x60\x88\x2d\xa7\x24\xef\x88\x1f\x6f\xcd"
-  "\x3b\x62\x23\xc4\x79\xc7\xbc\x47\x79\x1c\xcd\x3d\x2e\xe4\x1d\xf1"
-  "\x9b\xef\x0f\xde\x21\x89\xad\x7a\x21\xef\x98\xfb\x86\x7c\xde\x31"
-  "\x37\x47\x1e\xef\x98\x23\x7e\xee\x0d\x35\x97\x1b\xff\x9c\x23\x71"
-  "\xee\xcd\xdc\x66\x71\xde\x31\xcf\x4b\xc8\x3b\xe6\x48\x9c\x7b\x33"
-  "\x6f\xb4\x20\x7f\x2b\xde\x31\x6f\x9a\x90\x77\xcc\xb1\x38\xf7\x66"
-  "\x9e\x9e\xd3\x6e\x37\xe5\xf3\x8e\x79\x17\xa5\x79\xc7\x3c\xe1\xf9"
-  "\xaf\xd4\x3c\x72\xfe\x2b\x95\xe0\x49\x78\xc7\xbc\x0a\x8e\x8f\xe8"
-  "\xcc\xaf\xf3\xbc\x83\x5c\xe7\x79\x47\x82\x52\xc6\xf8\x55\xb8\x9c"
-  "\x75\xb2\x07\xee\x0a\xc7\xaf\x4c\x63\x57\x7a\xd5\xd0\x11\xf7\xc6"
-  "\xaf\xcc\x7f\xeb\x14\x19\xbf\xc2\x7d\x3a\x3f\x7e\x75\x91\x8d\x55"
-  "\xfc\xf8\x95\x96\x1d\xbf\xc2\x63\x57\xf8\xf7\x4e\xd3\xd8\x95\x71"
-  "\x85\xf5\x1a\xd9\x03\x46\xf9\x63\x57\xfc\x6f\x9e\x9f\xba\x92\xb1"
-  "\xab\x9a\x7b\x63\x57\xb8\x3f\x37\x34\x5a\x8f\x5d\xe1\x7e\x9c\x1f"
-  "\xbb\xfa\xae\x9d\xc7\xae\xe6\x3b\xb8\xff\xc5\xfc\x8a\xae\xf1\xdb"
-  "\xf4\x83\xb6\x46\x36\x61\x04\x19\xe7\x79\x3b\xde\xb1\xdf\xa6\xdf"
-  "\x8e\xeb\x1a\x7e\x79\xd0\xe6\x6a\xbf\xe5\x4d\xfc\x92\x68\x70\xcc"
-  "\x2f\x89\xfa\xae\xe1\x97\x07\x6d\x2e\xc7\xdb\xfb\x89\x5f\x16\xe6"
-  "\x39\xe6\x97\x85\xb9\x8e\x8f\xc1\x2f\x57\xf3\xfa\x78\xb9\x5a\x5a"
-  "\x1f\x2f\x9a\x6f\x5b\x1f\x2f\xad\xe1\xf5\xf1\x92\x51\x84\x87\x2e"
-  "\x79\x94\xf0\xd0\xc5\x17\x4d\x63\xf0\x44\x1f\x6b\x28\xdc\x97\xe0"
-  "\xb1\xf5\x2c\xe8\x3f\xde\x07\x6d\xb8\x19\xb4\xf2\xfb\x4b\x40\x2f"
-  "\x27\x21\xd7\xaa\xda\xe3\x28\x29\x15\x6b\xe6\xc5\x53\xa3\x52\xcc"
-  "\x35\xf3\xa2\xa3\x26\xbd\x1c\x05\xcf\x7e\xb9\x50\x43\x61\x5d\x6c"
-  "\xf0\x89\x0c\xd3\x1f\x18\x1a\xac\x86\x7c\x4c\xe3\xf3\xb8\xaf\x3d"
-  "\xb8\x10\xf4\xf1\x5b\xc2\x31\xfa\xd6\x03\x43\x47\xb4\xfa\x44\x86"
-  "\xe3\x71\xfa\x66\xb3\x71\x7a\x5b\x63\xf4\x62\xe3\xf3\x18\x87\x78"
-  "\x8c\xbe\xe0\xee\x83\x36\x46\xbf\x20\x9c\x60\x71\xf1\x20\xc7\xc6"
-  "\xe8\x17\x2b\x85\x5a\x79\xc5\x68\x6b\xad\xbc\x78\x9d\xfd\x5a\x79"
-  "\xf1\x3e\xc7\xb4\xf2\xe2\xbd\xf6\x69\xe5\x25\x3d\xc5\xb5\xf2\xa2"
-  "\x44\xe9\x31\x7a\x72\xcf\x5a\xe3\x2c\xdd\xc7\x6b\x9c\xa5\xcb\xba"
-  "\xbe\x56\x5e\xea\x2b\xae\x67\x96\x0e\x22\x5a\x79\x89\x6b\xfb\x6b"
-  "\xe5\x25\xae\xe2\x5a\x79\x69\x1e\xd1\x15\x4b\x5c\xad\xb5\x32\x3c"
-  "\x23\xaa\x95\x97\x9e\xb4\x7c\x86\x68\xe5\x25\x6e\x44\x2b\x2f\xbd"
-  "\x2c\xad\x95\x93\x33\x48\x8c\x4a\xe6\xd6\x93\x10\x9f\x5a\x6b\xe5"
-  "\xe4\x21\x6d\x6b\x65\x82\x21\xb6\x9c\x92\x5a\x39\x79\xb1\xb5\x56"
-  "\x5e\x94\x20\xae\x95\x97\x4f\xe0\x71\xb4\xec\xaa\x50\x2b\x27\x1f"
-  "\xbd\x3f\xb4\xb2\x24\xb6\x7c\x85\x5a\x79\xd9\x46\xf9\x5a\x79\xd9"
-  "\x71\x79\x5a\x19\x63\x4e\x4c\x2b\x2f\xe7\xce\xbf\x22\x78\xb1\xd6"
-  "\xca\xcb\x07\x8b\x6b\xe5\xe5\xa3\x85\x5a\x19\xe7\x2f\xa6\x95\x97"
-  "\xcf\x17\xe4\x6f\xa5\x95\x97\xaf\x13\x6a\x65\x92\x8e\xd7\xca\x2b"
-  "\x02\xb8\x7e\xcf\x4b\xbe\x56\x5e\xd1\x53\x5a\x2b\xaf\xf0\x12\x6a"
-  "\xe5\xe5\xb5\x44\x13\xaf\x08\x25\x5a\x79\x79\x13\xb9\xbe\xc8\xd3"
-  "\xfc\x3a\xaf\x95\xc9\x75\x5e\x2b\xaf\x98\x28\x43\x2b\x47\xb4\x93"
-  "\x56\x0e\xb9\xbf\xb4\x72\xc9\xb1\xae\xa1\x95\x53\x9a\x1d\xd3\xca"
-  "\x29\x4d\x76\x72\xff\xf0\x36\xb8\xff\x88\x87\xdc\xdf\x9c\x6f\xad"
-  "\x88\x25\x7c\x6b\x65\x8e\x63\xdc\x7f\xa5\xba\x2b\xf8\xe5\xc1\xf2"
-  "\xc9\x3b\x61\xc4\x27\xab\x07\x3b\xe6\x93\xd5\xfe\x0f\x75\x72\x47"
-  "\xf8\x65\x65\x0d\xf1\xcb\x9a\xe3\x8e\xf9\x65\xcd\x31\xc7\x75\xf2"
-  "\xba\x1a\x5e\x27\xaf\xab\x31\xd7\xc9\xe5\xe1\xe6\x3a\x39\x35\xc7"
-  "\xb6\x4e\x7e\xd7\xec\xac\x86\x0c\x8e\x83\x66\x70\xf3\x8d\x33\x58"
-  "\xbe\xd1\x8c\x75\xf2\x18\xd0\xc9\xd7\xd4\xf7\x74\x32\xd6\xc5\x91"
-  "\x4d\xdf\x33\xf8\x77\x65\xd0\xc9\x8a\x8d\x37\x90\x02\xb4\x33\xaa"
-  "\xba\x70\x04\x65\x81\x6e\xde\x74\x03\xb4\x73\x22\x68\x67\xfd\x4e"
-  "\x4e\x3b\xa7\xef\x14\x6a\xe7\xd4\x3b\x02\xed\xfc\x96\x9a\xd5\xce"
-  "\xa0\x87\x83\xf5\x79\x91\x61\x58\x3b\xeb\x41\x17\xb7\x0e\x1d\x3a"
-  "\x42\x7d\xc3\x42\x47\xbf\x05\x3a\x7a\xae\x50\x47\xb7\xe4\x45\x46"
-  "\x34\x1f\x18\x1a\x82\x75\x74\xd3\x60\xc7\x75\x74\x41\x0b\xd1\xd1"
-  "\x3b\x1e\x38\x1d\xbd\x3a\x91\x60\x35\x7d\xbe\x63\x3a\x3a\x3d\x41"
-  "\xa8\xa3\xd7\xaf\xb3\xd6\xd1\xe9\xa7\xed\xd7\xd1\xe9\x37\x1d\xd3"
-  "\xd1\xe9\x3a\xfb\x74\x74\xc6\x64\x4b\x1d\xbd\x37\x15\xeb\xe8\xd4"
-  "\xdc\x66\x49\x1d\x9d\xaa\x16\xff\xcd\x39\xd3\xec\x0c\x88\xcc\xfb"
-  "\xe0\x0c\x88\xcc\x58\x71\xad\x93\x39\x9f\xe8\xe8\x8c\xe8\xf6\xd7"
-  "\xd1\x19\xd1\xe2\x3a\x3a\x93\xfb\xfd\x2f\x23\xda\x5a\x47\xc3\x33"
-  "\xa2\x3a\xfa\x5d\x2f\xcb\x67\x88\x8e\xce\x98\x42\x74\xf4\xbb\x36"
-  "\xce\x7f\x78\x97\x3b\xff\xe1\x5d\xee\xfc\x07\xe2\x53\x6b\x1d\xfd"
-  "\xae\x1d\xe7\x3f\x10\x0c\xb1\xe5\x94\xd4\xd1\xef\x8a\x9c\xff\x90"
-  "\xaa\x16\xd7\xd1\xeb\x72\x78\x1c\xad\x1b\x2e\xd4\xd1\x6b\xef\x93"
-  "\xf3\x1f\x24\xb1\x15\x2b\xd4\xd1\x6b\xcf\xc8\xd7\xd1\xeb\xba\xc9"
-  "\xd3\xd1\x18\x73\x62\x3a\x7a\x1d\xb7\xff\x19\xc1\x8b\xb5\x8e\x5e"
-  "\xb7\x40\x5c\x47\xaf\x5b\x27\xd4\xd1\x38\x7f\x31\x1d\xbd\xee\x90"
-  "\x20\x7f\x2b\x1d\xbd\xee\xb4\x50\x47\x93\x74\xbc\x8e\x5e\x9f\xc4"
-  "\xf5\x81\xa3\xe4\xeb\xe8\xf5\x93\xa5\x75\xf4\xfa\x69\x42\x1d\xbd"
-  "\x5e\x45\xf4\xf2\xfa\xb5\x44\x47\xaf\x0f\x23\xd7\x53\x43\xcc\xaf"
-  "\xf3\x3a\x9a\x5c\xe7\x75\xf4\xfa\x5c\x79\xbf\x39\x3b\xb5\x17\xd5"
-  "\x88\xce\x5f\x33\xd1\x5e\x7b\x51\x99\x7e\x77\xfe\x6f\xaf\x99\xd8"
-  "\x30\xde\x31\x2d\xbd\x21\xfc\xa1\x66\x6b\x6f\x6d\xb0\x7e\x2f\xe1"
-  "\x5b\x1b\x1d\xdc\xff\x77\xe3\xc3\xfd\x7f\x3b\xc4\x2f\x1b\xb2\x88"
-  "\x5f\xde\x77\x70\xff\xdf\xf7\x9d\xd8\xff\xf7\xc3\x44\x5e\xb3\x7d"
-  "\x98\x28\xfd\xdb\x66\x56\x1b\xfb\xff\xaa\x0f\xf3\x9a\x6d\x8b\x0f"
-  "\xe1\x3b\xd9\xcd\x84\xef\x64\x1f\x75\xec\xb7\xcd\xec\xe1\x42\x7d"
-  "\x96\x95\xf7\xf0\xb7\xcd\x8e\xd6\x64\x9b\xb8\xfd\x81\x37\x1b\x1c"
-  "\xd3\x64\x9b\xf5\x42\x4d\x96\xdb\xdf\x5a\x93\x65\xcf\xb6\x5f\x93"
-  "\x65\xaf\x73\x4c\x93\x65\xaf\xb5\x4f\x93\x65\x5f\x16\xff\x6d\x33"
-  "\xcb\xc6\xfe\xc0\x59\x12\xfb\x03\xab\xd7\xf1\x5c\x5a\x3d\xb9\xeb"
-  "\x6b\xb2\x2d\x0d\xe2\xbc\x79\x8b\x81\x68\xb2\xec\xda\xf6\xd7\x64"
-  "\xd9\xb5\xe2\x9a\x4c\xbd\x98\xf0\xd7\xec\x5a\x6b\x4d\x06\xcf\x88"
-  "\x6a\x32\xf5\x1e\xcb\x67\x88\x26\xcb\xae\x23\x9a\x4c\xfd\x95\xb4"
-  "\x26\xcb\x79\x83\xc4\xa8\x9c\xa1\x24\x46\x65\x49\xec\x0f\x9c\xd3"
-  "\xad\x6d\x4d\x46\x30\xc4\x96\x53\x52\x93\xe5\x44\x5a\x6b\xb2\x2c"
-  "\x89\xfd\x81\x3f\x1c\xcc\xe3\xe8\x83\x13\x42\x4d\x96\x93\x77\x7f"
-  "\x68\x32\x49\x6c\x35\x08\x35\xd9\x07\xf1\xf2\x35\xd9\x07\xdb\xe4"
-  "\x69\x32\x8c\x39\x31\x4d\xf6\xc1\x65\x0e\x3f\x75\xe2\x9a\xec\x43"
-  "\x17\x71\x4d\xf6\x61\x7f\xa1\x26\xc3\xf9\x8b\x69\xb2\x0f\xc7\x0b"
-  "\xf2\xb7\xd2\x64\x1f\xce\x16\x6a\x32\x92\x8e\xd7\x64\xb9\x0a\x12"
-  "\x43\xdf\x77\x60\x7f\xe0\x0f\x2f\x4b\x6b\xb2\x0f\xaf\x0b\x35\xd9"
-  "\x87\x1a\xa2\xbd\x72\x7d\x89\x26\xfb\xf0\x2c\xb9\xfe\x7e\xbd\xf9"
-  "\x75\x5e\x93\xbd\x6f\xb1\x3f\x70\x6e\x80\x3c\x4d\x66\xff\x3e\x55"
-  "\xff\xfd\x79\xc0\x9e\x0f\xd8\x3c\xe0\xbc\x73\x8e\xe9\xb1\xbc\xb3"
-  "\x0f\xb9\x7f\x47\x70\xff\xdc\x50\xc2\xb7\x7e\xb7\xc0\x31\xee\xff"
-  "\xbb\x44\xc7\xb9\x7f\x61\x02\xcf\xfd\x0b\x13\xa4\xb9\x7f\xfe\x18"
-  "\xdb\xdc\xbf\xa0\x84\xe7\xfe\x3b\xbc\x48\xbf\xba\xfd\x0e\xe9\x57"
-  "\xb7\x1f\x71\x8c\xfb\x6f\x1f\x2a\xe4\xfe\xf9\x39\x0f\xb9\x7f\x47"
-  "\x73\xff\xad\xdc\x3e\xd5\xdb\x9a\x1d\xe3\xfe\xdb\x9a\x84\xdc\xbf"
-  "\xc8\xc7\x9a\xfb\x6f\x7f\xc3\x7e\xee\xbf\x3d\xc3\x31\xee\xbf\x3d"
-  "\xdd\x3e\xee\xbf\xfd\x07\x71\xee\x9f\x1f\x2e\xcd\xfd\xc9\x3d\x6b"
-  "\xce\x56\x90\xc1\x73\xb6\x82\xc8\xae\xcf\xfd\x77\xe8\xc4\xf9\xd9"
-  "\x8e\x66\xc2\xfd\xb7\x6b\xdb\x9f\xfb\x6f\xd7\x8a\x73\xff\x82\x05"
-  "\x84\x27\x6d\xd7\x5a\x73\x7f\x78\x46\x94\xfb\x17\xec\xb6\x7c\x86"
-  "\x70\xff\xed\xb5\x84\xfb\x17\x1c\x97\xe6\xfe\x3b\xa7\x91\x18\xb5"
-  "\x73\x08\x89\x51\xc4\xa7\xd6\xdc\x7f\xa7\x4b\xdb\xdc\x9f\x60\x88"
-  "\x2d\xa7\x24\xf7\xdf\x39\xc1\x9a\xfb\xe7\x87\x89\x73\xff\xc2\x41"
-  "\x3c\x8e\x76\x7d\x25\xe4\xfe\x3b\x73\xee\x0f\xee\x2f\x89\x2d\x9d"
-  "\x90\xfb\xef\x9a\x2d\x9f\xfb\xef\xca\x93\xc7\xfd\x31\xe6\xc4\xb8"
-  "\xff\xae\x1f\x38\xfc\xd4\x8a\x73\xff\x5d\x06\x71\xee\x5f\xe8\x23"
-  "\xe4\xfe\x38\x7f\x31\xee\x5f\x38\x46\x90\xbf\x15\xf7\x2f\x7c\x43"
-  "\xc8\xfd\x49\x3a\x9e\xfb\x17\x21\x12\x43\x7f\x77\x55\x3e\xf7\x2f"
-  "\xfc\x41\x9a\xfb\x17\x5e\x15\x72\xff\xc2\x63\x84\xe3\x17\x79\x13"
-  "\xee\x5f\x58\x4d\xae\xff\xae\xce\xfc\x3a\xcf\xfd\xc9\x75\x9e\xfb"
-  "\x17\xf9\x3f\xdc\xc3\xea\x7e\xda\xc3\x6a\xb7\x83\xfc\x7f\xb7\x4d"
-  "\xfe\x6f\x9b\x67\xee\x2b\xe1\x79\xe6\xbe\x12\x73\x9e\x29\xdc\xc3"
-  "\xea\xa3\x7d\xb6\x79\xe6\xc7\x4d\x3c\xcf\xdc\xc3\xc5\xf0\x3d\xa3"
-  "\x49\x0c\x2f\x36\x98\x78\xa6\xf4\x1e\x56\xc5\xcb\x84\x7b\x58\x7d"
-  "\x74\xf9\xe1\x1e\x56\x1d\xc1\x23\x8b\x42\x08\x8f\x2c\x1e\xe3\x18"
-  "\x8f\x2c\x0e\x13\xf2\xc8\x4f\xde\xb0\xe6\x91\xc5\x7b\xec\xe7\x91"
-  "\xc5\x27\x1d\xe3\x91\xc5\xe5\xf6\xf1\xc8\x3d\x43\xc4\xf7\xb0\xfa"
-  "\x68\xbf\x34\x8f\x24\xf7\xac\xfb\xff\x8f\x4f\xf2\xfd\xff\xc7\x79"
-  "\x5d\x9f\x47\x7e\x1c\x22\xde\xd7\x7f\x3c\x86\xf0\xc8\x3d\x01\xed"
-  "\xcf\x23\xf7\x04\x88\xf3\xc8\x8f\xb9\xf3\xaf\xf7\xa8\xac\xf7\xb0"
-  "\x82\x67\x44\x79\xe4\xc7\x57\xb9\x67\x02\x84\x3c\x92\xe4\x71\x89"
-  "\xfa\x7d\x37\x69\x1e\xf9\xfb\xdd\x24\x06\xfd\x7e\x31\x89\x41\xc4"
-  "\xa7\xd6\x3c\xf2\xf7\x13\xda\xe6\x91\x04\x43\x6c\x39\x25\x79\xe4"
-  "\xef\x73\xac\x79\xe4\x47\x7b\xc5\x79\xe4\xbe\xf9\x3c\x8e\xf6\xf5"
-  "\x14\xf2\xc8\xdf\x9f\xbf\x3f\x78\xa4\x24\xb6\x42\x84\x3c\x72\xef"
-  "\x3e\xf9\x3c\x72\xef\x45\x79\x3c\x12\x63\x4e\x8c\x47\xee\x1b\x62"
-  "\x89\x39\x21\x8f\xdc\x37\x5e\x9c\x47\xee\x7b\x43\xc8\x23\x71\xfe"
-  "\x62\x3c\x72\xdf\x46\x41\xfe\x56\x3c\x72\xdf\x1e\x21\x8f\x24\xe9"
-  "\x78\x1e\xf9\x49\x04\xd7\xd7\x4d\x96\xcf\x23\x3f\x19\x22\xcd\x23"
-  "\x3f\x19\x2e\xe4\x91\x9f\x28\x08\x5f\xfc\x64\x06\xe1\x91\x9f\xf8"
-  "\x92\xeb\x1f\x45\x9b\x5f\xe7\x79\x24\xb9\xce\xf3\xc8\x4f\x12\xe5"
-  "\xad\x8f\x69\x97\x31\xe4\x4e\x5a\x1f\xd3\x5e\x63\xc8\x5d\x65\x7d"
-  "\xcc\xfe\xfe\x8e\x71\xc8\xfd\xbe\x0f\xe7\xf4\xb4\xf7\xf8\xf1\x27"
-  "\xe9\x84\x6b\x1d\x38\xe0\xd8\xf8\xf1\x81\xfd\x8e\xf3\xfa\x23\x1a"
-  "\x9e\xd7\x1f\xd1\x48\xcf\xf7\x3f\x98\x61\x9b\xd7\x7f\xee\xca\xf3"
-  "\xfa\x43\xf3\x49\x9f\x7a\x28\x92\xf4\xa9\x87\xfa\xb4\x39\xdf\x7f"
-  "\x39\x52\x64\x71\xf3\xfd\xdf\xc7\xf3\xfd\x6b\x4e\xa0\xac\x5b\x62"
-  "\xf3\xfd\x4b\xd6\x09\xc7\x94\x0f\x5e\x16\x9b\xef\xcf\xce\xf3\xcf"
-  "\x8b\x0c\xd7\x4b\xcd\xf3\x9f\xd9\xfe\xf3\xfc\x77\x80\x3e\x30\xe9"
-  "\x81\x1d\x0f\x9c\x1e\xd8\xcf\xad\xdf\x2a\x99\xec\x98\x1e\x28\x89"
-  "\x16\xea\x81\x3f\x2c\xb0\xd6\x03\x25\x47\xec\xd7\x03\x25\xe7\x1d"
-  "\xd3\x03\x25\x35\xf6\xe9\x81\x43\xa3\xc4\xe7\xf9\x1f\x5c\x2b\x3d"
-  "\xcf\xff\x60\xba\xf8\x3c\xff\xcf\xce\xf3\x3c\xee\xb3\x3d\x5d\x5f"
-  "\x0f\x7c\x16\x21\xce\xd9\x3e\x9b\x4c\xf4\xc0\xa1\x90\xf6\xd7\x03"
-  "\x87\x42\xc4\xf5\xc0\x67\xdc\xfe\x9f\x87\x42\xac\xc7\x95\xe1\x19"
-  "\x51\x3d\xf0\x59\xb3\xe5\x33\x44\x0f\x1c\x0a\x25\x7a\xe0\x73\x1f"
-  "\x69\x3d\xf0\xf9\x21\x12\xbb\x3e\xcf\x20\xb1\x8b\xf8\xd4\x5a\x0f"
-  "\x7c\x3e\xad\x6d\x3d\x40\x30\xc4\x96\x53\x52\x0f\x7c\xbe\xdb\x5a"
-  "\x0f\x1c\x4c\x17\xd7\x03\x47\xde\xe1\x71\x74\xa4\xbf\x50\x0f\x7c"
-  "\x7e\xf5\xfe\xd0\x03\x92\xd8\x8a\x10\xea\x81\xc3\x47\xe5\xeb\x81"
-  "\xc3\xd7\xe5\xe9\x01\x8c\x39\x31\x3d\x70\x64\x14\x87\x9f\x50\x71"
-  "\x3d\x70\x64\xaa\xb8\x1e\x38\xb2\x40\xa8\x07\x70\xfe\x62\x7a\xe0"
-  "\xc8\x36\x41\xfe\x56\x7a\xe0\xc8\x11\xa1\x1e\x20\xe9\x78\x3d\xf0"
-  "\x87\x18\xae\xef\x1b\x22\x5f\x0f\xfc\x61\x94\xb4\x1e\xf8\xc3\x18"
-  "\xa1\x1e\xf8\x83\x37\xe1\xfd\x7f\x48\x24\x7a\xe0\x0f\x01\xe4\xfa"
-  "\xc1\x00\xf3\xeb\xbc\x1e\x20\xd7\x79\x3d\xf0\x87\xd5\xf2\xe6\x94"
-  "\xd8\x3f\xae\xfc\xdf\x9f\x53\xe2\xfa\x80\xcd\x29\x29\x1d\xe2\x98"
-  "\x1e\x28\x0d\x70\x9c\x7b\x6a\xfc\x78\xee\xa9\xf1\x93\x9e\xbb\x50"
-  "\x6a\xb0\xcd\x3d\x8f\xc7\xf1\xdc\xf3\x8b\x13\x24\x7e\x7f\xb1\x8f"
-  "\xc4\xef\x2f\xe6\x4b\xcd\x5d\xc0\x6b\x4c\x37\x2f\x21\xeb\x4b\xef"
-  "\xcd\x5d\x00\x2e\x44\x78\xe6\x9f\x7e\x10\xf2\xcc\xa3\x91\x62\x73"
-  "\x17\x44\xe7\x2c\x58\xac\x21\xc5\xf3\x15\x0c\xc0\x43\x9d\x9d\xb3"
-  "\xf0\xe0\xae\x21\xfd\x83\x9a\x70\xcb\x3f\x1d\x70\x8c\x5b\xfe\x69"
-  "\xbf\x90\x5b\x6a\x4e\x5a\x73\xcb\x2f\xbc\xec\xe7\x96\x5f\x8c\x74"
-  "\x8c\x5b\x7e\x31\xc2\x3e\x6e\xf9\x45\x9e\xf8\x9c\x85\xa3\x48\x7a"
-  "\xac\x99\xdc\xb3\xe6\x04\xc7\x47\xf2\x9c\xe0\xb8\x4b\xd7\xe7\x96"
-  "\xc7\x8a\xc5\xfb\xff\x63\x07\x08\xb7\xfc\x22\xb7\xfd\xb9\xe5\x17"
-  "\xb9\xe2\xdc\xf2\xf8\x20\xd2\x0f\x7f\x91\x6b\xcd\x2d\xe1\x19\x51"
-  "\x6e\x79\x7c\xaa\xe5\x33\x84\x5b\x7e\x91\x4f\xb8\xe5\xf1\xc5\xd2"
-  "\xdc\xf2\xcf\xdc\x7e\xea\xc7\x2f\x92\xd8\x44\x7c\x6a\xcd\x2d\x8f"
-  "\x1f\x69\x9b\x5b\x12\x0c\xb1\xe5\x94\xe4\x96\xc7\x0d\xd6\xdc\xb2"
-  "\x54\x2f\xce\x2d\xbf\x3c\xc7\xe3\xe8\xcb\x65\x42\x6e\xf9\xe7\xf1"
-  "\xf7\x07\xb7\x94\xc4\x56\xb1\x90\x5b\x7e\xe9\x23\x9f\x5b\x7e\x39"
-  "\x41\x1e\xb7\xc4\x98\x13\xe3\x96\x5f\x72\xfb\x7f\x11\xbc\x58\x73"
-  "\xcb\x2f\x0f\x89\x73\xcb\x2f\x4f\x0a\xb9\x25\xce\x5f\x8c\x5b\x7e"
-  "\x79\x47\x90\xbf\x15\xb7\xd4\x78\x09\xb9\x25\x49\xc7\x73\x4b\xcd"
-  "\x61\x12\x43\x4b\xf7\xc8\xe7\x96\x9a\x3c\x69\x6e\xa9\xd9\x29\xe4"
-  "\x96\x9a\x24\xc2\x21\x35\xe5\x84\x5b\x6a\xd6\x92\xeb\xa5\xc5\xe6"
-  "\xd7\x79\x6e\x49\xae\xf3\xdc\x52\x53\x63\x8b\x5b\x32\xea\x5b\xbe"
-  "\x6a\xca\x58\x02\x9f\x52\x28\x67\x7f\xe8\xdf\x34\xf0\x7f\x39\xf4"
-  "\x53\x9e\xf0\x7f\xb5\x14\x67\xd1\x79\xdd\xf2\x35\x02\xff\x30\xc2"
-  "\x7b\xaa\x74\x3f\x6b\x34\x03\xf4\xf0\xee\xaf\x62\x08\x37\xb9\xe5"
-  "\xeb\xa1\xef\x11\x61\x64\x12\xa0\x7f\x87\xff\x53\xe0\x1a\xa4\x77"
-  "\x87\xfe\x50\xb9\x1c\xb9\xdf\xa0\xbe\x4a\x31\xa5\x83\x32\xbb\x5f"
-  "\xa2\xbe\x1a\x89\xf3\x68\xdc\xf4\xd5\x5a\xa8\x4f\xad\x64\x59\x21"
-  "\xaf\xa8\x7d\x03\xd1\x1a\x3d\xf3\xa3\x66\xe1\x2d\x54\x4b\x7d\x75"
-  "\xda\xa3\xbe\x47\x04\xc4\x21\x84\xb9\x60\xc9\x00\x9d\x02\xe7\xa9"
-  "\x59\xd8\x82\xef\x95\xe0\x7b\x06\x28\x63\xea\x02\x44\x65\xdf\xea"
-  "\xe1\x0a\xdc\xaa\x5b\x5a\x03\x53\xb7\x48\x0f\x65\x86\xfe\xf5\xcb"
-  "\x81\x35\x8a\x4f\xb7\xd7\xb0\x7d\x4f\x65\x83\x81\xcd\x43\xb9\x90"
-  "\x2d\xcf\x99\x5d\x90\x5e\xac\x0c\xeb\x0e\x22\x55\xb7\x21\x8c\x56"
-  "\x5e\x7f\xf7\x17\xc9\xfd\x5f\x3c\x32\x06\x22\x4d\x20\xd8\x4e\x89"
-  "\x28\xb1\xfb\x32\xdf\x93\x65\x83\x63\xba\x7e\xd8\x8f\x69\x48\xdb"
-  "\x86\xa8\x2d\xc6\x1e\xae\x5f\x43\x4c\x2c\xdc\xca\xe8\x1a\x37\xfd"
-  "\xa5\x49\xeb\xf2\x59\x02\xb6\xf9\xbb\x70\x7f\x4b\x3f\x46\x77\x3b"
-  "\x13\xe3\xe6\x6b\x4f\xec\x25\x4b\x5f\x2c\x89\x5b\x30\x5b\x99\x3c"
-  "\x7f\x41\xfc\xa2\x65\xc9\xca\xc1\x71\xbd\xd0\x94\x45\x8b\x94\x0b"
-  "\x66\x2f\x7c\x47\x69\x7e\xe7\x79\x65\xdc\xfc\xa5\xb3\xe7\x24\xc6"
-  "\x0f\x5d\xf0\x66\x52\x2f\x28\x13\x32\x2b\x87\x37\x2e\x8b\x71\xd3"
-  "\xd7\x7e\xbb\x3e\x40\xe8\xc3\xbe\x48\x81\xcb\x05\xef\x4b\xd7\x2a"
-  "\x3c\xb3\xf0\xfb\xb2\xb7\x32\x0d\x14\xa4\x49\x83\x98\xb6\x25\xb5"
-  "\x07\xa4\xfd\x4b\x56\x21\x94\x6b\x17\x94\x1b\xca\x08\x65\xfe\x7a"
-  "\xbf\xa9\xcc\x26\x4c\xa4\x61\x4c\xa4\xde\x02\x0c\x7e\x7d\xda\xa3"
-  "\xa9\xc7\xcb\x0c\x13\x83\xeb\xd7\x00\x6d\xc5\xe5\x0a\x55\x16\xcf"
-  "\xea\x83\x9c\x5b\xbe\xf0\x6c\x9d\x09\x63\xc6\xdc\xe7\x4b\x98\x0f"
-  "\x6e\x6a\x81\x57\xba\x34\x32\x09\xbf\x06\x6c\xc2\xf3\x65\x23\x9f"
-  "\x46\x28\x9d\x69\x8c\x61\xcf\x9b\x60\x1a\x01\xc3\x04\xa7\x70\xef"
-  "\x84\xeb\x6d\x0a\xbd\xd8\xb8\xa9\x4c\xa5\x45\xf1\xde\x38\x0f\x2d"
-  "\x5c\xc3\x36\x37\x16\xc5\x84\x4d\x0d\x40\xe9\x4f\xa5\xa3\xf4\x46"
-  "\xfc\x4c\xf1\x00\x5f\x8f\x64\xe4\x12\x95\xc2\x7c\x0f\x71\xc7\x85"
-  "\x19\x14\x13\xc6\xec\x19\xe0\xab\xa5\xca\x3c\x8d\x79\xcf\x97\x40"
-  "\x7d\xea\x21\x9f\x64\x2d\xaa\xd7\xe2\x7c\xb6\x6c\x65\x6d\x5f\x8f"
-  "\xeb\x0e\xf6\x01\x9d\xc3\x00\x57\xe5\xda\x90\xfa\x91\x52\xa3\x7a"
-  "\x76\x7e\x95\xe2\x2e\x8a\xd2\x33\xad\x4c\xce\x23\xa5\x95\x0d\x0d"
-  "\x10\xd3\x92\xde\x64\x7a\x7d\x3d\xd4\x43\x3f\x3f\xbe\xb0\x2f\xb4"
-  "\xc5\x9c\xd9\xf9\x4c\x4e\xe0\xd9\xa9\x43\x90\x27\xe4\x5d\x6d\xb2"
-  "\x27\xd8\x52\x21\x0f\x47\x65\xec\xfc\x17\x8c\x07\x28\x0f\x87\x87"
-  "\x13\xca\xaf\x92\xad\xf1\x70\xaf\x6d\x6e\x0d\x54\xea\x99\x98\x97"
-  "\x5b\x73\x03\x63\x18\xef\xc0\xf0\xd4\xcb\xa8\x3b\xb6\x6d\x25\xe8"
-  "\x80\xec\xe5\xc8\x77\xf3\x4c\xa4\x9c\xf5\x8e\x27\xd2\xe5\x05\x86"
-  "\x79\x64\xa4\xbb\x80\x4d\x28\x88\x2f\xc1\x10\x33\x83\x5b\xfb\x3d"
-  "\x5f\xb2\x3a\x1e\x51\x07\x2e\x95\x50\x98\x3f\xe3\x39\x28\x60\xeb"
-  "\x1f\x76\xc1\x73\xcc\xcf\x31\x08\xfb\x83\xf5\xc5\xcf\x09\x28\x12"
-  "\x54\x0a\xfe\x6d\xe4\x0a\xf5\x57\x9f\x9d\x90\xa7\xbc\x7a\x9d\x60"
-  "\xf9\xaf\x01\x7c\xf5\x34\xf8\xa9\xaa\xd6\xc0\xe6\xc9\xfa\x2a\x91"
-  "\xf7\xd5\x71\x28\x07\xef\xaf\x13\x05\xd8\xaf\x12\x75\x2e\xe2\xea"
-  "\x5c\x03\x75\x2e\xb3\x51\x67\x0d\xa9\x73\xb7\x5b\xb6\xeb\xfc\xd7"
-  "\x73\xb6\xeb\xfc\xb7\x9e\xf2\xeb\xfc\xd7\x22\xf9\x75\xfe\xab\x5a"
-  "\xba\xce\x41\x9c\x9f\x83\xc0\xcf\x41\x36\xfc\x1c\xc4\xf9\xb9\xf7"
-  "\x25\xdb\x75\xfe\xdb\xc9\x36\xea\x6c\x90\x5f\xe7\xbf\xe5\xca\xaf"
-  "\xf3\xdf\xd6\xda\xa8\x33\xe7\xe7\x20\xf0\x73\x90\x0d\x3f\x07\x71"
-  "\x7e\xf6\xfa\xd6\x76\x9d\xcb\x8f\xdb\xae\x73\xf9\x4d\xf9\x75\x2e"
-  "\xdf\x20\xbf\xce\xe5\x29\xd2\x75\x56\x71\x7e\x56\x81\x9f\x55\x36"
-  "\xfc\xac\xe2\xfc\xfc\xdc\x26\xdb\x75\x3e\x79\xc8\x76\x9d\x4f\x5e"
-  "\x96\x5f\xe7\x93\xab\xe5\xd7\xf9\x64\xa2\x8d\x3a\x73\x7e\x56\x81"
-  "\x9f\x55\x36\xfc\xac\xe2\xfc\xfc\xfa\x58\xdb\x75\x3e\xb5\xc7\x76"
-  "\x9d\x4f\x9d\x97\x5f\xe7\x53\x49\xf2\xeb\x7c\x2a\x56\xaa\xce\x2d"
-  "\x10\xb7\xdd\xa0\x2e\xad\xff\x8c\x79\xd9\xe0\x1d\x38\xd1\xad\x16"
-  "\x51\x05\x99\xc6\x04\x8f\x3a\xd4\x13\xea\x96\xc0\x6c\x1d\x9d\x8e"
-  "\xff\x1a\xbd\x03\x23\x5a\xbc\x03\x63\x9a\xfb\xde\xd4\xae\x7a\x03"
-  "\x75\xc7\x7c\x7c\xa3\x11\xf9\x1a\x73\x03\xc3\xb3\x5e\x45\xca\x34"
-  "\x1d\xf2\xac\x4c\xd5\xa2\xd4\x24\x46\x57\x89\x7e\x40\x7d\xea\xb0"
-  "\xf6\xfc\x0e\x55\xd4\x97\xa3\x85\x4b\x18\xe6\x0a\x55\x31\x18\x8f"
-  "\x9b\x00\x4f\x4e\x57\xff\x03\x29\xe1\x1d\xc1\xbb\xe0\x83\xf3\xf1"
-  "\x98\x08\xfd\xe7\xd6\xd1\x99\x85\xa9\xc8\xf7\xcf\x6f\xd5\x21\x7c"
-  "\x7d\x27\x7c\x0c\x5b\x9f\x2f\x49\x7d\x03\x51\x07\x6f\xd5\x50\xa4"
-  "\x6f\xfe\xe6\xa6\x65\xdf\x3c\x71\x36\xd8\x72\x0e\xbe\x57\x31\xba"
-  "\xe0\x55\xb9\xb6\xfc\xe6\x98\xa9\xef\x66\x6d\x79\xc1\x40\xfa\x7b"
-  "\x8b\xbe\xfb\xcf\xf0\x7e\xde\x96\xdf\xec\xc7\xb6\x64\x72\x03\x63"
-  "\xab\xea\x5a\xb0\x6e\xf2\xbc\x92\x82\x28\xb8\x3e\xa3\x32\xe9\x16"
-  "\x92\xb0\x71\x91\x99\x8d\x2b\xdc\x6a\xbb\xdd\x92\xb0\x71\x39\xd8"
-  "\xb8\x46\xc4\xc6\x65\xf6\xd9\xf8\xf4\x46\xe7\x6d\x7c\x7a\xaa\xb4"
-  "\x8d\x4f\xef\x96\x6f\xe3\xd3\x4a\xf9\x36\x3e\xed\xc9\xd9\x58\x2b"
-  "\xb4\x71\x85\x46\xda\xc6\x41\x66\x38\x0e\x02\x1c\xf7\xbe\x24\x6e"
-  "\xe3\x20\xc0\x71\x90\x08\x8e\x83\xec\xc4\x71\xe5\x75\xe7\x6d\x5c"
-  "\x79\x54\xda\xc6\x55\xdd\xe4\xdb\xb8\x72\xad\x7c\x1b\x57\x26\x13"
-  "\x1b\x07\x59\xe0\xb8\xd2\xdf\x86\x8d\xcd\x70\x1c\x04\x38\xf6\xfa"
-  "\x56\xc2\xc6\x80\xe3\x20\x11\x1c\x07\xd9\x89\xe3\xea\xc9\xce\xdb"
-  "\xb8\xfa\x51\x69\x1b\x57\xcf\x97\x6f\xe3\xaa\x3a\xf9\x36\xae\xaa"
-  "\xe1\x6c\x6c\x81\xe3\xaa\x0d\xd2\x36\x56\x99\xe1\x58\x05\x38\x7e"
-  "\x6e\x93\xb8\x8d\x55\x80\x63\x95\x08\x8e\x55\x76\xe2\xf8\xcc\x11"
-  "\xe7\x6d\x7c\x26\x43\xda\xc6\x67\x4e\xcb\xb7\xf1\x99\x89\xf2\x6d"
-  "\x7c\x26\x94\xd8\x58\x65\x81\xe3\xea\x7a\x1b\x36\x36\xc3\xb1\x0a"
-  "\x70\xfc\xfa\x58\x09\x1b\x03\x8e\x55\x22\x38\x56\xd9\x89\xe3\xbf"
-  "\xf7\x77\xde\xc6\xdf\x5e\x96\xb6\xf1\xdf\x87\xcb\xb7\xf1\xb7\x25"
-  "\xf2\x6d\xfc\x6d\x11\x67\x63\x0b\x1c\x7f\x1b\x2d\x65\xe3\x56\xd0"
-  "\x80\x7d\xc0\xc6\x7d\xea\x11\xb5\x13\xdb\xb6\x86\xd8\xd6\xd0\x6f"
-  "\x74\xfa\x4e\xca\x98\x80\x6d\xc2\x8e\x01\xfd\xe4\xeb\x6e\xc8\x0d"
-  "\x9c\xc8\x50\x50\xa7\x54\x3c\xee\xfa\xf7\x6d\xfa\x4c\xe4\xae\x4c"
-  "\xc5\xe3\xbf\xe7\x96\xe1\x34\xca\xd4\xf5\x17\xe1\x7d\x34\x1e\xf7"
-  "\xd2\xe7\xe8\x34\x06\x9f\x61\xea\x2b\xd4\xd9\x33\xcc\x60\xbf\x60"
-  "\xd0\x5e\xb1\xcc\xdb\xbe\xde\x55\xf5\x25\x60\x9f\x53\xa8\xb2\xe6"
-  "\x4f\xc8\xd8\x6f\x74\xe6\xd3\x7a\x14\xc0\xfc\x14\xe0\x5d\x01\x0a"
-  "\xdb\xf0\xa6\xaf\x5b\x55\x4a\x39\xaa\x4a\xf9\x0c\x45\xd5\x31\x77"
-  "\x99\xff\x04\xb8\xb5\xfa\x8c\x2b\x37\xf8\x8c\x8e\x35\xe4\x45\xc6"
-  "\xe8\x7d\xc6\x95\x1e\x58\xae\xa5\xdc\x9a\x50\x40\x62\x2d\xc3\x64"
-  "\xcf\x41\x8a\xec\x4b\xc8\x75\xcb\x1c\xe4\xb6\xe5\x12\xf2\xac\xa8"
-  "\xad\x41\xa7\xaf\x95\xa3\xd3\xb7\xce\xa3\xd3\x77\xe1\xd3\x02\x1f"
-  "\x23\x7c\xd2\xcf\x83\xaf\x11\x8a\xbc\x8e\x50\x5a\x2d\xa3\x0b\xba"
-  "\x80\xbc\x2b\xf4\x35\x08\xcf\x99\xba\x41\x9d\x5d\xe0\x16\x8b\xbc"
-  "\x99\xff\xf8\x22\xe6\x4d\x5f\x0a\xee\x29\xf0\xf5\x2a\xbd\x0e\x55"
-  "\xd4\x36\xe1\xfb\x13\xe1\xbe\x22\xad\x16\xf2\x37\x96\xe3\xb3\x38"
-  "\x75\x15\xe9\x27\xa1\x7e\x45\x25\x0c\xd6\xd0\xfd\x02\x95\x6a\x30"
-  "\xb5\x91\xf1\x7d\x9c\xe0\xe0\xdc\xba\x5d\x46\xb9\xbe\x3e\x5b\xc0"
-  "\xda\xf8\x6d\xdf\xbe\x60\xe7\x01\xc6\xb7\x63\x3c\x27\x9d\xff\x9e"
-  "\xc1\xf3\xf5\xf0\x58\x42\x65\xc3\x29\x84\x7f\x6b\x8a\x7a\x07\xa1"
-  "\x89\x06\x84\xb0\x2d\xaa\x52\xea\xd0\xa4\x24\xe4\x81\xc7\x9f\x8d"
-  "\x3f\x05\xf4\xad\xaa\xd5\xa1\x35\x7a\x28\xe3\x8d\xa6\x7b\x65\xac"
-  "\x5c\x5b\x89\xe0\xde\x80\xca\x04\x2d\x72\x4b\x42\x9e\xd8\xbe\xfa"
-  "\xdc\xc0\x88\x49\xd0\x7e\x16\x36\x30\x0c\xb6\x2d\xb6\x29\xb6\x2f"
-  "\xce\xcf\x64\xf3\xaa\x38\x1d\x4a\x6b\x42\x9e\x55\xa9\xf0\x37\x85"
-  "\xd1\x55\xa1\x9b\x08\xca\x98\xce\x78\x15\x95\x00\x2e\xd6\x62\x2c"
-  "\x68\xa9\xbf\xab\xc1\xff\x7d\x25\x30\x55\x46\x30\xd5\xed\x96\x1d"
-  "\x98\xaa\xe0\x31\x75\xee\x3a\x8f\xa9\x7f\x9e\x94\xc6\xd4\x3f\x07"
-  "\x73\x98\xd2\x76\x4d\x4c\xfd\xe3\x2b\xdb\x98\xfa\x47\x91\x0d\x4c"
-  "\xd5\x00\xa6\x8a\x84\x98\xfa\xe7\x79\xf9\x98\xfa\x87\xae\x13\x31"
-  "\x55\xee\x18\xa6\xfe\x71\x56\x88\xa9\x73\xb5\xd2\x98\x0a\xe2\xe2"
-  "\x54\xef\x4b\x6d\x63\x2a\xc8\x2c\x4e\xd5\x8c\xe1\x31\xf5\xdd\xa3"
-  "\xd2\x98\x3a\xff\x0e\xc1\x54\x50\x17\x8d\x53\xe7\x7d\x6c\x63\xaa"
-  "\xa6\x41\x1a\x53\x41\x10\xa7\x82\x2c\xe2\xd4\x77\x43\xe5\x63\xea"
-  "\x7c\x78\xe7\x61\x2a\xc8\xc1\x38\x75\x3e\x40\x88\xa9\x9a\x10\x1b"
-  "\x98\xe2\xe2\x94\xd7\xb7\x76\x60\xca\x2c\x4e\x7d\x97\xc7\x63\xea"
-  "\xc2\x62\x69\x4c\xfd\xeb\x34\x87\xa9\x2e\x1a\xa7\xfe\x35\xdf\x36"
-  "\xa6\xfe\x15\x61\x03\x53\x10\xa7\x82\x2c\xe2\xd4\x85\x0c\xf9\x98"
-  "\xfa\x57\x7e\x27\x62\xca\xc1\x38\xf5\xaf\xd5\x42\x4c\x7d\x97\x25"
-  "\x8d\x29\x15\x17\xa7\x9e\xdb\xd4\x36\xa6\x54\x66\x71\xea\xc2\x55"
-  "\x1e\x53\xff\x3e\x21\x8d\xa9\x7f\x0f\x22\x98\x52\x75\xd1\x38\x75"
-  "\xf1\xb8\x6d\x4c\x5d\x2c\x90\xc6\x94\x0a\xe2\x94\xca\x22\x4e\xfd"
-  "\xfb\x9c\x7c\x4c\x5d\xac\xef\x3c\x4c\xa9\x1c\x8c\x53\x17\xab\x85"
-  "\x98\xba\xa0\xb5\x81\x29\x2e\x4e\xbd\x3e\xd6\x0e\x4c\x99\xc5\xa9"
-  "\xef\x47\xf3\x98\xfa\xa1\xbf\x34\xa6\xb4\xcb\x38\x4c\x75\xd1\x38"
-  "\xa5\xf5\xb2\x8d\xa9\xef\x75\x36\x30\x05\x71\x4a\x65\x11\xa7\x7e"
-  "\x18\x22\x1f\x53\xda\xb0\x4e\xc4\x94\x83\x71\x4a\xeb\x2f\xc4\xd4"
-  "\xf7\x23\xa4\x30\xd5\x82\x75\x9f\x0b\x60\x2a\x01\x74\x1f\x60\xc8"
-  "\xa3\x9a\x60\xaa\x15\x30\xb5\xc3\x1c\x53\xff\xb2\xd4\x7d\x3f\xe4"
-  "\x18\xef\x61\xea\x3f\x3b\x2d\x31\x65\x04\x4c\xb5\xb2\x98\xba\x74"
-  "\xc4\xa4\xfb\xaa\xea\x8b\xc0\x57\xd7\x50\x55\x34\xe0\x69\x2b\x87"
-  "\xa7\x7f\x01\x9e\xa0\x3e\x46\xa8\x6f\xc5\x85\x1a\x14\xa5\x23\xf5"
-  "\x6a\x81\xfa\x1a\xcd\xb1\xd4\x52\x47\x61\x0c\x61\xec\x98\x70\x74"
-  "\x7a\x21\xe0\x67\xc9\x19\x74\x7a\x39\x7c\x56\xc2\x27\x15\x3e\xe8"
-  "\x0c\xaa\xa8\x43\xec\x98\x3d\x8f\x9f\x6a\x0e\x3f\x97\x26\xdb\xc6"
-  "\xcf\xa5\x60\x79\x1a\xef\x3f\x07\xe4\xe3\xe7\x12\x67\xcf\x18\xcf"
-  "\xa8\xc9\xdf\x33\x78\x7e\x2c\xc1\xc8\x35\x14\xa5\x47\x1e\xcc\xeb"
-  "\x01\x7d\xdd\x62\x90\xe7\x2a\x03\xa2\x36\xcf\x41\x9e\x9b\xbf\x83"
-  "\xfa\x9a\xda\xce\x25\xe4\x76\xaa\xe9\x4f\xa8\xe2\x56\x0d\xaa\xb8"
-  "\x7b\x12\x55\x18\xe1\x73\x0d\x3e\x50\xc6\xa8\x78\xf3\xfa\xea\xb8"
-  "\xfa\xfe\x67\x0c\xe4\xe5\x2f\x5d\xdf\xff\x28\xd9\xfa\xc6\x41\x7d"
-  "\x5b\xf8\xfa\x56\x01\x16\xc1\x2f\x03\x8c\x9c\x4e\x8c\xd2\xa1\x9e"
-  "\x8b\xf4\x0c\xd3\xc2\x61\x10\xfb\xe5\xd4\xd9\x26\x14\x95\x04\xbe"
-  "\x7a\x13\x30\x58\xbb\x17\xa5\xad\x06\x0c\xb6\x34\xe1\xdf\xf5\x75"
-  "\x55\xe9\xcd\x80\xc1\x4b\x71\x0c\xd8\xad\x15\x63\xf0\x5f\x18\x83"
-  "\x3f\x6c\x30\x4a\x63\xb0\x8c\x60\x10\x74\x62\xdb\x18\x34\x8b\x6b"
-  "\xb5\x3e\x3c\x06\xaf\x0c\x92\xc6\xe0\xe5\x51\x26\x9d\xf8\xdf\xc7"
-  "\x60\xed\x39\xdb\x18\xac\x3d\x2c\x4f\x13\x5e\x19\x2e\x1f\x83\x97"
-  "\x15\x9d\x87\xc1\xcb\x27\x6c\x63\xf0\x72\xb1\x1d\x18\x2c\x77\x0c"
-  "\x83\xb5\x75\x42\x0c\xd6\xba\x49\x63\x30\x88\x8b\x83\xa0\x2b\xdb"
-  "\xc4\xa0\xb9\xae\xbc\xb2\x8d\xc7\x60\xdd\x1e\x69\x0c\xfe\x78\xdc"
-  "\xa4\x2b\xff\xfb\x18\xfc\x71\x9a\x6d\x0c\xfe\x18\x22\x4f\x43\xd6"
-  "\x1d\x91\x8f\xc1\x1f\x37\x74\x1e\x06\xeb\x26\xd8\xc6\x60\x5d\x40"
-  "\xdb\x18\x0c\x72\x30\x0e\xfe\x98\x28\xc4\xe0\x15\xb5\x0d\x0c\x72"
-  "\x71\x10\x74\x68\xdb\x18\x34\x8b\x83\x57\x1f\xe5\x31\xf8\xd3\x10"
-  "\x69\x0c\x5e\x1b\x63\xd2\xa1\xff\x7d\x0c\x5e\xbd\x68\x1b\x83\x57"
-  "\x8f\xc9\xd3\x9c\x3f\x8d\x92\x8f\xc1\x6b\x6e\x9d\x87\xc1\x6b\xa7"
-  "\x6d\x63\xf0\xda\x7e\x3b\x30\xe8\x60\x1c\xbc\xaa\x13\x62\xf0\xaa"
-  "\xb7\x34\x06\x55\x5c\x1c\x04\xdd\xda\x26\x06\xcd\x75\xeb\x4f\xbb"
-  "\x79\x0c\x5e\x3f\x20\x8d\xc1\xfa\x13\x26\xdd\xfa\xdf\xc7\x60\xfd"
-  "\x6c\xdb\x18\xac\x0f\x93\xa7\x51\xaf\x1f\x97\x8f\xc1\x7a\x75\xe7"
-  "\x61\xf0\xfa\x64\xdb\x18\xbc\x1e\xdc\x36\x06\x55\x0e\xc6\xc1\xfa"
-  "\x64\x21\x06\x7f\xca\xb7\x81\x41\x2e\x0e\x82\xce\x6d\x1b\x83\x66"
-  "\x71\xf0\xc6\x60\x1e\x83\xba\xe1\xd2\x18\xfc\x79\x82\x49\xe7\xfe"
-  "\xf7\x31\x78\xe3\xb2\x6d\x0c\xde\x28\x93\xa7\x69\x75\x63\xe4\x63"
-  "\xf0\x67\xef\xce\xc3\xe0\xcf\xe7\x6c\x63\xf0\xe7\xc3\x76\x60\xd0"
-  "\xc1\x38\x78\xa3\x49\x88\xc1\x1b\x7e\x52\x18\x34\x82\x2e\x6e\x2d"
-  "\xf6\x0b\x36\xe6\x8e\x2b\xf7\x70\x51\x22\xbd\xf7\x30\x75\x55\x72"
-  "\x03\x9a\x74\x07\xec\x93\x74\x07\xcd\xbc\xe3\x89\x0c\xb9\xe3\x4a"
-  "\x81\x93\x47\x98\xe9\x67\x76\x6e\x99\x5e\x5d\x54\xb2\x65\x21\x52"
-  "\x80\xfe\xce\xc4\xd7\xaa\xae\x34\x21\xfc\xfe\x35\xb8\x3c\xd7\xf8"
-  "\xf2\xe0\x71\x02\xe6\xe7\x00\x4f\xf6\x37\xe6\x16\x2d\xaa\x0d\x45"
-  "\x74\x45\xad\x16\xec\xb0\x92\xf5\x2f\xb6\xcb\x15\xea\xa6\x77\xe1"
-  "\x0d\xa4\xd0\xff\xc7\x77\x00\xd8\xdb\xbb\xcf\x0a\xe4\xe2\x57\xcb"
-  "\x18\xb1\x5d\xb1\xbd\xb0\x8d\x95\x2b\xf1\x6f\xd7\x37\xe3\x2b\x01"
-  "\x63\xfa\xff\x04\x0c\xd8\x05\xe9\xc4\xf5\xea\xcd\x05\xf2\xb1\x71"
-  "\x33\x98\xac\x5b\xb8\x09\x6d\x01\x89\xfe\x76\x0c\xb6\x2a\xb3\xd3"
-  "\x56\xe5\x66\x3a\xaf\x03\x6c\x75\x2b\xcc\x3e\x5b\xdd\xca\xb1\xb0"
-  "\x95\x88\xae\xba\xb5\x4d\xbe\xad\x6e\xcd\x20\xb6\xba\x15\x22\x6d"
-  "\xab\x20\x3b\x71\x15\x14\x61\xa6\x47\x3a\xc0\x56\xb7\x13\xed\xb3"
-  "\xd5\xed\xe3\x42\x5b\x89\xf1\xff\xdb\x27\xe4\xdb\xea\xf6\x06\x62"
-  "\xab\xdb\x71\x36\x6c\x65\x27\xae\x82\xca\xcd\x78\x73\x07\xd8\xaa"
-  "\x21\xdf\x3e\x5b\x35\x5c\xb5\xb0\x95\x08\x4f\x6d\xb8\x29\xdf\x56"
-  "\x0d\x87\x89\xad\x1a\xd4\xd2\xb6\x52\xd9\x89\x2b\x55\x84\x19\xbf"
-  "\xeb\x00\x5b\xdd\x29\xb3\xcf\x56\x77\x7d\x84\xb6\x12\xe3\x53\x77"
-  "\x1f\x95\x6f\xab\x3b\x5a\x62\xab\x3b\xc7\x6c\xd8\xca\x4e\x5c\xa9"
-  "\xca\xcd\x78\x48\x07\xd8\xea\xae\xce\x3e\x5b\x35\x8e\xb1\xb0\x95"
-  "\x48\xbf\xdf\x38\x41\xbe\xad\x1a\xdd\x88\xad\xee\xd6\x49\xd9\xca"
-  "\x90\x1b\x18\xee\x01\x36\x68\xde\x1a\xa8\xf4\x48\x41\x54\x8b\x3f"
-  "\xd8\xcd\x1b\xec\x96\xa1\x44\xad\xb9\x60\x37\x9d\x1e\x4d\x5a\xfc"
-  "\x3d\x53\x59\x6f\x40\x2d\x60\xb3\x66\xef\xc0\x88\x2a\x5d\x1d\x9e"
-  "\x73\xf4\xc2\x25\xaa\x79\xc8\xeb\x8b\x3d\x11\xb6\x1b\xb6\x03\xb6"
-  "\x1d\x03\x76\x63\xed\xe8\x1d\x19\x63\xf0\x1e\x1d\x1b\x79\xfd\x7b"
-  "\x66\x91\x96\x61\x70\x7d\x19\x4f\x9d\x06\xff\x2e\x10\x55\x87\x7a"
-  "\x2a\x5f\xc5\x75\x6a\x3a\x8f\xaf\x57\xe9\x6a\x80\x1f\xdc\x42\x2c"
-  "\x37\xfb\x3e\xc0\xdb\xf0\x5a\x80\x9b\xa1\x2a\xe6\x65\xa6\xef\x4d"
-  "\xad\xbe\xdf\xf3\x25\x69\xd7\x51\x77\xcc\x1f\xb2\x8d\xc8\x77\xcd"
-  "\x02\x44\x1d\x7c\x4b\x43\xb1\x6b\xd7\x96\xb0\x79\xec\x01\xbb\xf8"
-  "\x32\xb7\xcd\xe6\x74\xdf\x4e\x40\x55\x57\xd4\xac\xdf\x2c\x39\x02"
-  "\xeb\xb7\x7f\x06\x78\x02\xcf\x0c\x66\xbc\x03\x63\xd4\x95\x48\xc9"
-  "\xb4\x82\x8d\xd9\xf5\x44\xcd\x39\x85\x2d\x72\x6d\xdc\xc4\xce\xff"
-  "\x36\x2a\xb9\xf9\x5b\x60\x27\xfc\x7e\x76\xfe\x56\x92\xd9\xfc\x2d"
-  "\x28\x33\x3f\x7f\xab\x69\x04\x9e\xbf\x65\xfc\xde\x77\x80\xa9\xee"
-  "\x8b\x12\x19\x06\xea\xde\xb7\xb2\x41\x87\x70\xfd\x2b\x1b\x34\x28"
-  "\x2d\x19\x79\x56\xb6\xd4\xa1\xd4\x06\x46\x57\x99\x7e\x15\x45\xdd"
-  "\xc1\x3c\x18\xe3\xa5\x79\x10\xf1\x6b\x63\x83\xf1\xfb\x80\x01\x5a"
-  "\xaa\xd9\xb7\xb2\x1a\x21\xb3\x75\x3c\x09\xc0\x99\x5d\xc1\x0f\x09"
-  "\x55\xe9\x97\x10\xf8\x44\x5b\xa5\xff\x0e\xfb\x29\x01\xee\x87\xde"
-  "\xe3\xd7\xfd\x46\x5f\xc2\xd7\xb0\xcf\xf0\xef\x4d\x55\x49\x3a\x36"
-  "\x8d\xe9\x3e\xc6\x85\x47\x4a\x3a\xaa\x4a\x69\x41\x95\x7a\xbc\x66"
-  "\xb7\xb1\xe8\x9b\x98\x1a\x29\x1c\x95\x71\x38\x2a\xf2\x48\xe9\x76"
-  "\xcb\x0e\x1c\x95\xf3\x38\x6a\x5d\xec\x1c\x8e\x5a\x07\x39\x8f\xa3"
-  "\x96\xeb\x4e\xe0\xa8\x46\x88\xa3\xd6\xf3\xf2\x71\xd4\x52\x2a\x1f"
-  "\x47\x2d\xab\x9d\xc3\x51\xeb\x7c\x82\xa3\x96\x50\x82\xa3\xd6\x58"
-  "\x1e\x47\xec\xda\xa8\x0e\xc2\x51\x73\x9d\x34\x8e\x82\xb8\x78\x14"
-  "\x04\xf1\xa8\xf7\xa5\xb6\x71\x14\x64\x16\x8f\x0c\x47\x9d\xc3\x91"
-  "\x61\xbe\xf3\x38\x32\x8c\x74\x1c\x47\x41\x16\xf1\xc8\x38\x48\x3e"
-  "\x8e\xf0\xd2\x79\xb9\x38\xd2\x97\x39\x87\x23\xc3\x21\x82\x23\xfd"
-  "\x5a\x82\x23\xc3\x5e\x1e\x47\xec\x7a\xb3\x0e\xc2\x91\x3e\xd8\x06"
-  "\x8e\xb8\x78\x14\x04\xf1\xc8\xeb\x5b\x3b\x70\xc4\xc7\x23\x1a\xb9"
-  "\x38\x87\x23\xe6\x90\xf3\x38\x62\xd6\x38\x81\x23\x61\x3c\xa2\xd1"
-  "\x7c\xf9\x38\x62\x22\xe4\xe3\x88\x71\x73\x0e\x47\x4c\x33\xc1\x91"
-  "\xb1\x82\xe0\x08\xee\xdf\xc3\x11\xbb\x86\xaf\x83\x70\x64\x4c\x91"
-  "\xc6\x91\x8a\x8b\x47\x2a\x88\x47\xcf\x6d\x6a\x1b\x47\x2a\x3e\x1e"
-  "\xd1\xd4\x04\xa7\x70\x44\xbb\x34\x3b\x8d\x23\xda\xe5\x84\xe3\x38"
-  "\x52\x09\xe3\x11\x4d\x1d\x92\x8d\x23\xda\x45\x2d\x1b\x47\xb4\xcb"
-  "\x14\xa7\x70\x44\x53\x63\x58\x1c\xd1\x2e\xde\x2c\x8e\x68\x2a\x84"
-  "\xc7\x11\xbb\x2e\xb2\x63\x70\x44\x23\x8d\x0d\x1c\x71\xf1\x48\x05"
-  "\xf1\xe8\xf5\xb1\x76\xe0\xc8\x2c\x1e\x29\x72\x9c\xc3\x91\x62\x8c"
-  "\xf3\x38\x52\xf4\x71\x02\x47\x16\xf1\x48\xd1\x2c\x1f\x47\x74\x8d"
-  "\x7c\x1c\xd1\x05\xce\xe1\x48\xb1\x91\xe0\x88\x9e\x41\x70\xa4\x48"
-  "\xe7\x71\xc4\xae\x35\xed\x20\x1c\xd1\xae\x52\x38\xc2\x7b\x11\x7c"
-  "\x48\xf6\x85\x68\xd8\xb2\x12\x85\x14\xe2\xbf\x2d\x28\xb8\x31\xbb"
-  "\x5b\xf0\x57\xab\xc9\x7e\x00\x5a\xba\x1b\x3b\xde\x2b\xf6\x7c\xef"
-  "\x7d\xe0\x17\xef\xc0\xb0\xa8\x8b\x64\x8f\x06\xbc\x2f\xc8\xed\xb4"
-  "\x04\xf4\x34\xde\x97\x81\xee\x9e\x80\xf7\xb1\xba\xb7\x77\x80\xb7"
-  "\xc4\xde\x01\xd3\xa5\xf7\x0e\x68\xd9\x6a\x5a\x77\xbb\x97\x5f\x77"
-  "\x4b\x77\x1f\x69\x73\xdd\x2d\xdd\xfd\xd1\x9d\xd3\xe5\xe2\xa1\x1b"
-  "\xbb\xfe\xeb\x76\xbf\x40\x65\x63\x76\x77\x15\x7c\x57\x90\xba\x77"
-  "\xdf\x8b\xec\x5a\x8f\xbb\xd7\x0c\x27\xdd\x6a\xa6\xce\x40\xe9\xcc"
-  "\xa6\x13\x2a\xc6\x27\x30\x8c\xc9\x0b\x8c\x96\x57\x96\xee\xc9\x6d"
-  "\xd8\x5b\x23\x6e\xef\x1e\x35\x9c\xbd\x8b\x38\x7b\x8b\xef\x5b\x30"
-  "\x5d\x7a\xdf\x02\x71\x7b\xf7\xb0\xbd\xce\x99\xee\xb1\x59\xbe\xbd"
-  "\x7b\xc4\x70\xf6\x2e\x6a\xcc\xee\x51\xc0\xdb\xdb\xd5\x57\xbe\xbd"
-  "\x7b\x44\x10\x7b\xff\x55\x09\xf6\xd6\x80\xbd\xab\x65\x96\xa5\xd6"
-  "\xb6\xbd\x83\x24\xf0\xdd\x33\x82\xd8\x9b\xdb\x33\xc1\x5b\x62\xcf"
-  "\x84\xe9\xd2\x7b\x26\x88\xdb\xbb\xa7\x8f\x6d\x7b\xbb\x1a\xe4\xdb"
-  "\xdb\xb5\x9c\xd8\x3b\x08\xf0\xdd\xd3\x8d\xb7\x77\x4f\x3b\xf7\x15"
-  "\x30\xb7\xb7\x6b\x29\xb1\xf7\xdf\xbc\x19\x9f\x20\xc0\x77\x90\x4c"
-  "\x7c\xf7\x9c\xd2\x86\xbd\x25\xf0\xdd\xab\x94\xb3\x37\x87\x6f\x89"
-  "\xfd\x1a\xa6\x4b\xef\xd7\x20\x6e\xef\x5e\xeb\x6c\xdb\xbb\xd7\x02"
-  "\xf9\xf6\xee\x15\xc2\xd9\x1b\xf0\xdd\x6b\x35\x6f\xef\x5e\x4d\xf2"
-  "\xed\xdd\x2b\x80\xd8\xbb\xdc\x15\xec\x0d\xf8\x0e\x92\x89\xef\x5e"
-  "\x65\xb6\xed\xad\x92\xc0\xb7\x5b\x00\xb1\x37\xb7\x57\x84\xb7\xc4"
-  "\x5e\x11\xd3\xa5\xf7\x8a\x10\xb7\x77\xef\x3b\xb6\xed\xdd\xfb\xa2"
-  "\x7c\x7b\xf7\xde\x4b\xec\xad\x02\x7c\xf7\xae\xe7\xed\xed\x96\x20"
-  "\xdf\xde\xbd\xf3\x39\x7b\xeb\x19\x1f\x15\xe0\x5b\x25\x13\xdf\x6e"
-  "\x23\xda\xb0\xb7\x04\xbe\xfb\xe4\x73\xf6\xe6\xf0\x2d\xb1\x4f\xc5"
-  "\x74\xe9\x7d\x2a\xc4\xed\xdd\x27\xde\xb6\xbd\xfb\x44\xca\xb7\x77"
-  "\x1f\x5f\xce\xde\x80\xef\x3e\x33\x78\x7b\xf7\xa9\x91\x6f\xef\x3e"
-  "\xae\xc4\xde\x27\x75\x60\x6f\xc0\xb7\x4a\x26\xbe\xfb\x14\x4b\xd9"
-  "\xdb\x03\xec\x7d\x02\x78\x0c\xf4\x83\x11\xc6\x5c\xe0\x29\x06\xa1"
-  "\xdd\xab\x52\x42\xd0\xb0\xbb\xd8\xf6\x1e\x6b\xa1\xef\x88\xe8\xb4"
-  "\xfd\x32\x68\x8f\x05\x4e\xaf\x1d\xa6\x3d\x46\x49\xae\x1d\xa6\x3d"
-  "\x06\xc9\x5e\x3b\x4c\xbb\xd7\xf3\x1c\xc8\x23\x98\xf7\xa9\x07\x1b"
-  "\x3f\x64\xad\x29\xa6\xdd\x2f\x88\xee\xa3\x41\xbb\x67\xe1\x35\xc5"
-  "\xcc\xa6\x53\xb5\xc6\x3c\x47\xb8\x91\x87\xda\x0e\x5f\x97\x83\x1f"
-  "\x34\xd2\xbe\xf6\x4a\x02\x5f\x97\x77\xda\xbe\x1d\xb4\xd7\x34\xe7"
-  "\x7d\xed\x35\x58\xda\xd7\x5e\x7d\xe4\xfb\xda\xb3\x86\xe7\x5f\x5e"
-  "\x7e\xbc\xaf\xbd\xe4\xaf\x1f\xa7\x3d\xcb\x45\xf7\xf3\xa0\x3d\x53"
-  "\x88\xaf\x2b\x22\xc0\xd7\x0e\xf0\x32\xaf\xd5\x6d\xfb\x3a\x08\xda"
-  "\x75\x90\x8d\x76\xfd\xc8\x0c\xe8\x33\x23\x3a\x6d\xff\x10\xfa\x91"
-  "\xf1\xce\xfb\xfa\x11\x2f\x69\x5f\xf7\x6d\x96\xef\xeb\xbe\x65\x3c"
-  "\xf7\x7b\xc4\x95\xf7\xf5\x23\x05\xf2\x7d\xdd\xf7\xb0\xe8\xbe\x22"
-  "\x74\xdf\x38\xe2\xeb\xd3\xfb\x8d\x79\x8e\x70\xc2\x47\x12\xec\xf0"
-  "\x35\xb4\xeb\x20\x1b\xed\xda\x27\x02\x7c\x5d\xde\x69\xfb\x98\xd0"
-  "\x3e\xc3\x9d\xf7\xb5\xb7\x41\xda\xd7\xde\x97\xe5\xfb\xda\xbb\x84"
-  "\xe7\x9d\xde\x0d\xbc\xaf\x7d\x36\xc8\xf7\xb5\x77\x91\xe8\xfe\x26"
-  "\xb4\x77\x34\xf1\x75\x95\x27\xf8\xda\x01\x3e\xea\x23\xc9\xff\x79"
-  "\x5f\xab\xa0\x5d\xab\x6c\xb4\xeb\x5f\x8c\x00\xae\x10\xd1\x69\xfb"
-  "\xa9\xd0\xbf\x78\xd4\x79\x5f\xf7\xbb\x2a\xed\xeb\x7e\x67\xe4\xfb"
-  "\xba\x5f\x01\xcf\x79\xfb\x69\x79\x5f\xff\x22\x59\xbe\xaf\xfb\x65"
-  "\x89\xee\xb3\x42\xf7\x0b\x25\xbe\xae\x4e\x36\xe6\x39\xc2\x85\x7f"
-  "\x11\x66\x87\xaf\xa1\x5d\xab\x6c\xb4\xeb\xfe\xa0\xeb\x55\xe5\x9d"
-  "\xb6\xaf\x0b\xdd\xbf\xa7\xf3\xbe\xf6\x3d\x27\xed\x6b\xdf\xe3\xf2"
-  "\x7d\xed\xbb\x81\xe7\xdb\xbe\x15\xbc\xaf\xfb\xc7\xca\xf7\xb5\x6f"
-  "\x8a\xe8\x7e\x2f\xb4\x6f\x00\xf1\xf5\x99\x1a\xf0\xb5\x03\x3c\xbc"
-  "\xbf\xca\x11\x1e\xbe\x74\x27\x72\x15\xfa\xfb\x97\x9e\x9d\xcb\xc5"
-  "\x07\x34\x3b\xef\xef\x01\x27\xa4\xfd\x3d\xe0\x80\x7c\x7f\x0f\x48"
-  "\xe1\xb9\xf8\x80\x63\xbc\xbf\x7f\x19\x2d\xdf\xdf\x03\x12\xc4\xb9"
-  "\xf8\x00\x5f\xe7\xb8\xf8\x2f\xfd\x1c\xe1\xe2\xd6\xfe\x7e\x14\x75"
-  "\x2e\x1f\xf7\xbb\xea\xbc\xbf\xfd\x8e\x48\xfb\xdb\x6f\xa7\x7c\x7f"
-  "\xfb\x25\xf0\x7c\xdc\x6f\x3f\xef\xef\x47\xc3\xe4\xfb\xdb\x2f\x46"
-  "\x9c\x8f\xfb\xb9\x3a\xc7\xc7\x1f\x75\x73\x84\x8f\x5b\xfb\x7b\xa0"
-  "\xae\x73\x39\xf9\xc0\xf3\xce\xfb\x7b\xe0\x1e\x69\x7f\x0f\xdc\x2c"
-  "\xdf\xdf\x03\x63\x78\x4e\x3e\xd0\x6c\xfc\xfb\xb1\x60\xf9\xfe\x1e"
-  "\x18\x21\xce\xc9\x1f\x6d\x72\x8e\x93\x0f\xd4\x3b\xc2\xc9\xad\xfd"
-  "\xad\xd4\x76\x2e\x2f\x57\x9e\x74\xde\xdf\xca\x3c\x69\x7f\x2b\xd7"
-  "\xc8\xf7\xb7\x32\x82\xe7\xe5\xca\x2c\xde\xdf\x83\x94\xf2\xfd\xad"
-  "\x0c\x11\xe7\xe5\x8f\xd5\x39\xc7\xcb\x95\xf5\x8e\xf0\x72\x6b\x7f"
-  "\x3f\x5e\xdd\xb9\xdc\xfc\xf1\xa3\xce\xfb\xfb\xf1\x75\xd2\xfe\x7e"
-  "\x7c\x81\x7c\x7f\x3f\x1e\xc2\x73\xf3\xc7\xcd\xc6\xff\x9f\xf0\x94"
-  "\xef\xef\xc7\x03\xc4\xb9\xf9\xa0\x1a\xe7\xb8\xf9\xe3\x17\x1c\xe1"
-  "\xe6\xd6\xfe\xf6\xd7\x74\x2e\x3f\xf7\xdf\xe7\xbc\xbf\xfd\x97\x49"
-  "\xfb\xdb\xff\x0d\xf9\xfe\xf6\x0f\xe0\xf9\xb9\x7f\x22\xef\xef\xc1"
-  "\x48\xbe\xbf\xfd\x7d\xc5\xf9\xf9\x13\xe5\xce\xf1\x73\xff\x0a\xe7"
-  "\xc7\xc9\x9f\x2a\xc0\xdc\x5c\xee\xfe\x8f\x55\xc9\xdc\x9a\x3b\x7a"
-  "\x30\xbf\xff\x23\xfd\xd4\x66\x24\xb5\xb7\x0c\xfd\xe4\xd5\x2e\xbd"
-  "\xff\x23\xfd\xa4\xed\xfd\x1f\xe9\x27\xe5\xed\xff\x48\x3f\x79\x46"
-  "\xf6\x7c\x7c\xfa\xc9\x02\x5e\x23\x3c\x69\xa6\xff\x9f\x62\xdb\x75"
-  "\x97\xde\x17\x92\x7e\x52\xb8\x2f\x24\x3d\x98\xdd\x17\x92\xd9\xf4"
-  "\xf7\x50\xc7\xb4\xc8\x53\x7b\x9d\xff\x5d\x20\x30\x05\xeb\x10\xb9"
-  "\xfb\x50\xf2\xd8\x0e\x58\xc6\x63\x3b\x70\xbe\x34\xb6\x87\x9c\xe8"
-  "\xd2\xfb\x50\xd2\x43\x26\xd8\xc6\xf6\x90\x00\x59\x7b\x8e\xd0\x43"
-  "\xe4\xef\x7b\x43\x0f\x49\xe1\xf5\xd0\x10\x33\xfd\x1b\x58\xda\x89"
-  "\xd8\x76\x6c\x3f\x25\x7a\xc8\x0c\x21\xb6\x03\x12\x09\xb6\xcf\xa9"
-  "\x1d\xd3\x5d\x81\x6b\x9d\xff\x1d\x64\xe8\x14\xac\xb9\xe4\xee\x87"
-  "\xc9\x63\x3b\x68\x32\x8f\xed\xa1\xe3\xa5\xb1\xad\xda\xdd\xa5\xf7"
-  "\xc3\xa4\x55\x83\x6d\x63\x5b\xa5\x90\xb5\x97\x09\xad\xda\x28\x1f"
-  "\xdb\xaa\x29\xbc\xf6\x53\xe5\xf3\xd8\x1e\x9a\xdb\x79\xd8\x76\x70"
-  "\x9f\x4c\x5a\x15\x22\xc4\x76\x50\x04\xc1\xf6\x3f\x6b\x1d\xd3\x98"
-  "\x43\x63\x9d\xff\xdd\x27\x38\x18\xeb\x4b\xb9\xfb\x72\xf2\xd8\x1e"
-  "\x36\x94\xc7\x76\xb0\xd5\xbe\x50\x3c\xb6\x9f\x5e\xd3\xa5\xf7\xe5"
-  "\xa4\x9f\x76\xb1\x8d\xed\x61\x5a\x59\x7b\xa4\xd0\x4f\xc7\xcb\xc7"
-  "\xf6\xd3\xc1\xbc\xce\x7d\x3a\x99\xc7\x76\x70\x52\x27\x62\xdb\xc1"
-  "\xb8\xfd\xb4\xb7\x10\xdb\xc3\xfc\x09\xb6\xbf\x0b\x71\x4c\x4f\x07"
-  "\x87\x3a\xff\x3b\xd7\xb3\x6e\x58\x4b\xcb\xdd\x1f\x94\xc7\xf6\xf0"
-  "\x9e\x3c\xb6\x9f\x31\x48\x63\xfb\x99\x69\x5d\x7a\x7f\x50\x7a\xb8"
-  "\xed\xfd\x7f\xe8\xe1\x36\xf6\xff\x11\x59\x2b\x4c\x3f\x23\x7f\xdf"
-  "\x0b\xfa\x19\x37\x5e\xd3\x3f\x13\xcd\x63\xfb\xd9\x89\x9d\x87\x6d"
-  "\x07\xf7\x0d\xa5\x87\xeb\x84\xd8\x1e\x8e\x08\xb6\x2f\x64\x39\x36"
-  "\x76\xf0\xac\xaf\xf3\xbf\xeb\x8d\xac\xc3\xe3\x06\x72\xf7\x29\xe5"
-  "\xb1\xfd\xec\x65\x1e\xdb\x23\xcf\x4b\x63\x7b\xe4\xc8\x2e\xbd\x4f"
-  "\x29\x3d\xe2\xa8\x6d\x6c\x8f\xc8\x97\xb5\xa7\x0b\x3d\x52\xfe\x3a"
-  "\x78\x7a\x44\x1d\x3f\x7e\x31\xd2\x6c\xfe\xfb\x73\x01\x9d\x88\x6d"
-  "\x07\xe3\xf6\x88\x0a\x21\xb6\x9f\xbd\x40\xb0\xfd\x6f\xad\x63\xe3"
-  "\x24\x23\x1b\x9c\x1f\x27\x09\x69\x60\x7f\xc3\x94\xb9\x5f\x2a\x8f"
-  "\xed\xe7\xbe\xba\xb7\x37\x11\x1d\x72\xd9\x12\xdb\xf7\xf6\x26\xa2"
-  "\x7f\x65\xe8\x32\xfb\xa5\xd2\xbf\xca\xb0\x8d\xe3\x5f\xc5\xca\x1b"
-  "\x13\xf9\xd5\x65\xf9\x38\xfe\x55\x09\x3f\x26\xf2\x2b\xb3\xf9\x2f"
-  "\xa3\x4c\x67\x92\x77\xfc\x9e\x45\x74\xc8\x46\x9b\x7b\x16\xd1\x21"
-  "\x09\x1d\xb6\x8f\x2a\xfd\xab\x5c\xc1\x9e\x45\xf4\x73\xa5\x46\xb6"
-  "\x2d\xfc\x30\xc2\xb1\x71\x95\x51\xc8\xf9\x71\x95\x50\xf2\xfb\xae"
-  "\xcc\x7d\x5b\xf9\xb6\x30\xea\x34\xdf\x16\x5e\xb8\x29\xdd\x16\x5e"
-  "\xe8\xd9\x65\xf6\x6d\xa5\x9f\xdf\x6c\xbb\x2d\x3c\x9f\x28\x6f\x0c"
-  "\xe5\x79\xf9\xfb\xc0\xd0\xcf\x1f\xe3\xc7\x50\x5e\x40\x7c\x5b\x08"
-  "\x0d\xeb\xbc\xb6\xf0\x42\x9e\xed\xb6\xf0\x42\x72\x87\xed\xe7\x4a"
-  "\x3f\x5f\x24\x6c\x0b\xa3\xca\x48\x5b\xf8\x4f\xa9\x63\xe3\x30\xa1"
-  "\x0e\xfd\xfe\x2d\x6c\x0b\x2f\xba\xb1\xbf\x7d\xcb\xdc\x3f\x96\x6f"
-  "\x0b\xa1\xe7\xf9\xb6\xf0\x6b\x2b\x3e\xcf\xb7\x85\x5f\xfb\x74\x99"
-  "\xfd\x63\xe9\xd1\xdb\x6c\xb7\x85\xd1\x29\xf2\xc6\x5c\x46\x1b\xe4"
-  "\xb7\x85\xd1\x66\xeb\x9f\x7e\x6d\xb6\xfe\xe9\xc5\x89\x9d\xd7\x16"
-  "\x7e\xbd\xdb\x76\x5b\xf8\x75\x7a\x87\xed\x2b\x4b\x8f\xde\x2f\x6c"
-  "\x0b\xa1\xd5\xa4\x2d\x5c\x09\x75\x6c\xdc\xe6\x45\x3b\xf8\x7f\x5b"
-  "\xe3\x36\x63\x7d\xd9\x79\x01\x32\xf7\xb1\xe5\xdb\xc2\x8b\x97\xf9"
-  "\xb6\x30\xb6\xa7\x74\x5b\x18\x33\xa8\xcb\xec\x63\x4b\x87\xed\xb1"
-  "\xdd\x16\xc2\xd6\xca\x1b\xa3\x19\xd3\x53\x7e\x5b\x08\x3b\xcb\x8f"
-  "\xd1\x8c\xf1\xe5\xdb\xc2\xd8\x98\xce\x6b\x0b\x63\x0e\xd8\x6e\x0b"
-  "\x63\xb2\x3a\x6c\x7f\x5b\x3a\xac\x54\xd8\x16\x5e\xbc\x40\xda\x42"
-  "\x9d\xc6\xb1\x71\x9e\xb1\xfe\xce\x8f\xf3\x8c\xf7\x67\xe7\x4c\xc8"
-  "\xdc\x4f\x97\x6f\x0b\x63\x6f\xf2\x6d\x61\xbc\x8f\x74\x5b\x08\x1f"
-  "\xda\x65\xf6\xd3\xa5\xc7\x1d\xb2\xdd\x16\xc6\xa9\xe5\x8d\xe9\x84"
-  "\xfb\xc8\x6f\x0b\xe3\xb4\xfc\x98\x4e\xb8\x3f\xdf\x16\xc6\xc7\x75"
-  "\x5e\x5b\x08\x3f\x6a\xbb\x2d\x84\xe7\x77\xd8\x3e\xbb\xf4\xb8\x32"
-  "\x61\x5b\x18\x5b\x47\xda\xc2\x4f\xe1\x8e\x8d\x0b\x8d\x0f\x76\x7e"
-  "\x5c\x28\x22\x98\x9d\x4f\x22\x73\x5f\x5f\xbe\x2d\x8c\x37\xf0\x6d"
-  "\x21\x42\xfa\x9c\x07\xfa\xe5\x51\x5d\x66\x5f\x5f\xfa\x25\xdb\xe7"
-  "\x1f\xd1\x2f\xd9\x3a\xff\x48\x64\x0c\xe8\xe5\x41\xf2\xdb\xc2\x4b"
-  "\xf5\xfc\x18\xd0\xcb\x66\xeb\xff\x22\x92\x3a\xaf\x2d\xbc\x6c\xfb"
-  "\xfc\x07\xfa\x65\x3b\xce\x7f\x70\x70\xbf\x5f\xfa\xa5\x6a\x61\x5b"
-  "\x18\xdf\x40\xda\xc2\xf5\x72\xc7\xc6\x91\x22\xda\x1c\xff\xc7\x3a"
-  "\xbf\xd5\xdb\x7a\x1c\xa9\xa2\x36\x04\x05\x4d\xc7\x6d\x61\x42\xad"
-  "\x3e\x2f\x30\x02\xef\x2f\x6c\xf0\xe7\xf6\xa0\xcc\xe0\xf6\x78\x69"
-  "\xd0\x93\x3d\x28\x75\x86\x7b\x7b\x50\x92\xbd\x3f\x10\x85\xd7\x02"
-  "\xe3\x35\xc1\x7a\x4f\xb2\xff\x24\x83\xe7\x44\xe1\x39\x52\x97\xca"
-  "\xd9\xfd\x55\x56\xeb\xa1\xee\x57\xda\xd8\x7f\x32\x56\x8b\x2a\x62"
-  "\x57\x22\xbd\x57\x51\x09\x59\x27\x3c\x21\x99\xdd\x7f\x72\x96\xef"
-  "\x80\xec\x7f\x23\x6f\x0f\xbc\xff\x64\x2c\x63\x4c\xd3\x32\xba\xca"
-  "\x26\x04\x69\xc1\xbe\xb3\xb9\x3d\x28\xe9\x09\x17\x71\xdd\xf5\xb3"
-  "\x02\x06\xec\xfa\xb7\xc4\xfe\xc2\xf4\x04\xf9\xfb\xc0\xd2\x13\xd4"
-  "\xfc\xf8\xce\x84\xb3\x3c\x46\xff\x1f\xdb\x07\xc3\xfd\xc4\x0a\x60"
-  "\x31\xcc\x26\xdd\xc4\x56\x87\xf6\xde\x98\xa0\xb3\xc3\x67\x78\x8e"
-  "\x88\x55\xfc\xe2\x7d\xf6\x4a\x3e\xf8\xac\x1c\xef\x73\x6c\xbf\xcf"
-  "\xba\xdd\xea\x18\x9f\xbd\x12\x60\xbf\xcf\x5e\xc9\xb1\xf0\x99\xc8"
-  "\x38\xc4\x2b\xef\xc8\xf7\xd9\x2b\xe1\xfc\x38\xc4\x2b\x1b\x78\x9f"
-  "\xbd\x52\x43\x7c\xf6\x8a\x92\xf8\xec\x66\x4a\xab\x43\xfb\x77\xbc"
-  "\xd2\xe6\xfa\x6f\xac\x9b\x5a\xbd\xad\x75\x39\xef\xb3\xc8\x89\xfa"
-  "\x3c\xd0\xee\xa0\xcb\xed\xf7\x59\xef\x4b\x1d\xe3\xb3\x89\x17\xec"
-  "\xf7\x59\xe4\x78\xa1\xcf\xc4\xf4\x72\xa4\xfc\x33\x3b\xe9\x89\x4d"
-  "\xbc\x5e\x8e\x0c\xe5\x7d\x16\x99\x45\x7c\x36\xf1\x2c\xf1\xd9\xad"
-  "\xe2\x56\x87\xf6\x00\x89\x8c\xb1\xc3\x67\xf8\x37\x7d\x1b\xed\x2c"
-  "\x0a\x81\xcf\xca\xf1\xbe\xcf\xf6\xfb\xcc\xeb\xdb\x8e\xf1\xd9\x24"
-  "\xb5\xfd\x3e\x9b\xd4\x6c\xe1\x33\x11\x5d\x37\xe9\x07\xf9\x3e\x9b"
-  "\xb4\x9f\xd7\x75\x93\x74\xbc\xcf\xa2\xc2\x88\xcf\x26\x6d\x20\x3e"
-  "\xbb\x5d\xdd\xea\xd0\x3e\x22\x51\x6d\x8e\x7f\x61\x1e\xda\xea\x6d"
-  "\xad\x73\x78\x9f\x45\x1f\xd6\xe7\x81\x16\x02\x9d\x63\xbf\xcf\x9e"
-  "\xdb\xd4\x31\x3e\x8b\x0e\xb7\xdf\x67\xd1\x07\x84\x3e\x13\xd3\x1f"
-  "\xd1\x79\xf2\x7d\x16\x1d\xcb\xeb\x8f\xe8\x62\xde\x67\xd1\x0d\xc4"
-  "\x67\xd1\xa1\xc4\x67\x0d\xfa\x56\x87\xf6\x22\x89\xd6\xd8\xe1\x33"
-  "\xfc\x1b\xac\x8d\x76\xf6\x6a\x02\xf8\xac\x1c\xef\x83\x6d\xbf\xcf"
-  "\x5e\x1f\xdb\x31\x3e\x9b\xdc\x64\xbf\xcf\x5e\x9d\x6d\xe1\x33\x11"
-  "\x9e\xfc\xaa\xfc\x7d\xb0\xe9\x57\xbd\x79\x9e\xfc\x6a\x0c\xef\xb3"
-  "\x57\xf7\x12\x9f\x4d\xd6\x11\x9f\xdd\x0d\x68\x75\x68\x3f\x93\x57"
-  "\x25\xf7\xff\xb2\xc5\x1b\x4d\xf3\xf2\x79\xbf\x4d\x51\x76\x1d\xee"
-  "\xf8\x9b\x12\xfb\xfd\x36\xa5\x7f\xdb\xdc\x71\x8a\x8b\x7c\xbf\xfd"
-  "\xa6\x82\xe7\x8e\x53\x3c\x79\xbf\x4d\x89\x25\x7e\xfb\xcd\x5e\xe7"
-  "\xb8\xe3\x94\x36\xd7\xbf\x8a\x71\x47\x6b\xbf\x4d\xad\xe9\x3a\xfc"
-  "\x71\x6a\x82\xfd\x7e\x9b\x7a\xa6\x6d\xfe\x38\xf5\xa8\x7c\xbf\x4d"
-  "\x5d\xcb\xf3\xc7\xa9\xe5\xbc\xdf\x7e\xeb\x4b\xfc\x36\x35\xd6\x39"
-  "\xfe\x38\x55\x72\xff\x37\x5b\xfc\xd1\xda\x6f\xaf\xa9\xbb\x0e\x87"
-  "\x7c\x4d\x69\xbf\xdf\x5e\xdb\xd8\x36\x87\x7c\x6d\xb1\x7c\xbf\xbd"
-  "\x16\xca\x73\xc8\xd7\xd2\x79\xbf\xbd\x56\x4d\xfc\xf6\x9a\xaf\x73"
-  "\x1c\xf2\xb5\x02\x47\x38\xa4\xb5\xdf\xa6\x45\x74\x1d\x1e\x19\x53"
-  "\x63\xbf\xdf\xa6\x8d\x69\x9b\x47\x4e\x93\x7f\x66\x31\x1d\xd3\xc0"
-  "\xf3\xc8\x69\x21\xbc\xdf\xa6\x91\x33\x58\xe8\x98\x6a\xe7\x78\xe4"
-  "\xb4\x36\xf7\xff\x10\xe3\x91\xd6\x7e\x7b\x1d\x75\x1d\x2e\x39\x5d"
-  "\x06\xff\x9f\x6e\xc1\xff\xc5\xb8\xe4\x74\x07\xf8\xff\xf4\xfd\x3c"
-  "\x97\x9c\x6e\xc6\xff\x5f\xe7\xf8\xff\xf4\x0d\xce\x71\xc9\xd7\xed"
-  "\xe1\xff\x56\x5c\xd2\xda\x6f\x33\x4a\xbb\x0e\x9f\x9c\x11\x61\xbf"
-  "\xdf\x66\x1c\x6a\x9b\x4f\xce\x90\x7f\x0e\x14\x3d\x23\x8e\xe7\x93"
-  "\x33\xf6\xf2\x7e\x9b\xd1\x44\xfc\x36\x23\xcc\x39\x3e\x39\x43\x72"
-  "\xff\x47\x93\xdf\x0c\xde\x81\x11\x8c\xc8\x38\xe4\xe9\x84\x10\x6e"
-  "\x6f\xc2\x59\x1b\x0c\x3e\x81\x11\x72\xcf\x77\x31\xed\x39\x7d\x32"
-  "\x01\xa1\x4b\xf4\xac\x41\xce\xed\x3b\x3d\xf3\x8c\xf3\xfb\x4e\xcf"
-  "\xdc\xd9\x6e\xe7\xbb\xd0\x33\xd7\xc9\xdf\x77\x7a\x66\x34\xcf\x41"
-  "\x67\xe6\xf2\xbe\x9e\xc5\xce\x4f\x90\xb7\x1f\xf5\x4c\x6f\xe7\xf6"
-  "\xa3\x9e\xd5\x9f\xe0\xeb\x8d\xb3\x64\x3f\xea\x59\x9e\x9d\x72\xee"
-  "\x0b\xfd\x46\x3a\xde\x8f\x9a\xd9\xd4\x38\xc5\xb1\xfd\x91\x67\xe5"
-  "\xda\x81\xe7\x72\x46\x64\x8c\x96\xc7\xf3\x9c\x18\xc0\x73\xb9\xdc"
-  "\x73\x66\x84\x78\x9e\x7d\xd3\x39\x3c\xcf\xde\xed\x3c\x9e\x67\x2f"
-  "\x68\xb7\x73\x66\xe8\xd9\x53\xe5\xe3\x79\xb6\x92\xe7\xe6\xb3\xe3"
-  "\x78\x3c\xcf\xc9\x97\x8f\xe7\xd8\x5a\xe7\xf0\x3c\xfb\x2a\xc1\x73"
-  "\x6c\x31\xc1\xf3\x6c\x6d\xa7\x9c\x3f\x43\xc7\x46\x13\x3c\x37\x17"
-  "\x38\xb6\xff\xf4\x9c\xb8\xb6\xf1\x1c\x14\xc1\x88\x8c\x5f\xf3\x78"
-  "\x8e\x0f\x30\xf8\x04\x45\xc8\x3d\xef\x46\x88\xe7\xb8\xaf\x9c\xc3"
-  "\x73\xdc\x62\xe7\xf1\x1c\x37\xba\xdd\xce\xbb\xa1\xe3\x06\xcb\xc7"
-  "\xf3\x9b\x3a\x5e\xb3\xc4\x8d\xe0\xf1\x1c\x9f\x20\x1f\xcf\x6f\x1e"
-  "\x76\x0e\xcf\x71\x47\x09\x9e\xdf\x4c\x26\x78\x8e\x2b\xe9\x94\x73"
-  "\x70\xe8\x37\x95\x04\xcf\xad\xb5\x8e\xed\xef\x1d\x2f\xb9\xff\xb1"
-  "\x19\x9e\xcb\x19\x91\xb1\x7d\x1e\xcf\xf3\x9a\x00\xcf\xe5\x72\xcf"
-  "\xdd\x11\xe2\x79\x9e\x93\xe7\x5c\xcc\x6b\x87\x73\x2e\xe6\x39\x71"
-  "\xce\x85\xe5\xb9\x3b\x73\xef\xc8\xc7\xf3\x5c\x0d\xaf\xe5\xe6\x29"
-  "\x78\x3c\x27\x84\xc8\xc7\xf3\xdc\xb5\xce\xe1\x79\x1e\x77\xfe\xc5"
-  "\xdc\x70\x82\xe7\x79\xe9\x9d\x72\x1e\x0f\x1d\xaf\x23\x78\x36\xaa"
-  "\x1c\xdb\x3f\x3d\x41\xd1\x36\x9e\x55\x11\x8c\xc8\xef\x1e\x3c\x9e"
-  "\xdf\x2a\x37\xf8\xa8\x22\xe4\x9e\xff\x23\xc4\xf3\x5b\xb3\x9d\xc3"
-  "\xf3\x5b\x5e\xce\xe3\x79\xfe\xc5\xf6\x3b\xff\x67\xfe\x09\xf9\x78"
-  "\x9e\xaf\xe6\x35\xee\x7c\xb3\xdf\xff\xdf\x76\x95\x8f\xe7\xf9\x4e"
-  "\x9e\x0b\xf4\xd6\x34\x82\xe7\xf9\xdc\xb9\x40\x6f\x45\x77\xce\xb9"
-  "\x40\x09\xec\xb9\x40\x4c\x36\x4a\x76\x6c\x7f\xfa\xb7\xce\xda\x81"
-  "\xe7\x72\x46\xe4\x37\x21\x1e\xcf\x0b\xf2\x01\xcf\xe5\x72\xcf\x21"
-  "\x12\xe2\x79\xc1\x70\xe7\xf0\x9c\xf8\x83\xf3\x78\x4e\x3c\xd0\x7e"
-  "\xe7\x10\x25\xe6\xc9\xc7\x73\xa2\xe9\xf7\x3f\x88\xcf\x89\x66\xbf"
-  "\xff\x2d\x70\xe0\x7c\xa2\x44\x7f\xe7\xf0\xbc\x60\x08\xc1\xf3\xdb"
-  "\xb5\x04\xcf\x0b\x94\x9d\x73\x3e\xd1\xdb\x6a\x82\x67\xea\x98\x63"
-  "\xfb\xff\x2f\x68\x73\xfe\x87\xd8\xf8\x86\x69\x5c\x8a\xc7\x74\x52"
-  "\xa2\xf3\x63\x1c\x49\xdd\x9c\xc3\xf4\xa2\x23\xce\x63\x7a\x51\x46"
-  "\xfb\x8d\x71\x2c\x92\x7f\xd6\x1f\xbd\x68\x04\x3f\xc6\xb1\x28\x85"
-  "\xc7\x74\xd2\x7e\xf9\x98\x5e\xd8\xe4\x1c\xa6\x17\x19\x08\xa6\x17"
-  "\x96\x12\x4c\x2f\x6a\xe8\x9c\x31\x8e\x85\x71\xce\x8d\x71\x24\xa5"
-  "\x38\x32\xc6\x61\x8d\xe9\xa5\x61\xce\x8f\x73\x2c\x39\xef\x1c\xa6"
-  "\x97\x6c\x74\x1e\xd3\x4b\xa6\xb6\xdf\x38\xc7\x92\xd1\xf2\x31\xbd"
-  "\xc4\x95\x1f\xe7\x58\x32\x91\xc7\xf4\xd2\x74\xf9\x98\x5e\x5c\xe1"
-  "\x1c\xa6\x97\x9c\x21\x98\x5e\x9c\x45\x30\xbd\xa4\xbc\x73\xc6\x39"
-  "\x16\x87\x38\x37\xce\xb1\x74\xa2\x23\xe3\x1c\xd6\x98\x5e\xee\xed"
-  "\xfc\x58\xc7\xb2\x03\xce\x61\x7a\xd9\x1b\xce\x63\x7a\xd9\x90\xf6"
-  "\x1b\xeb\x58\xe6\x25\x1f\xd3\xc9\x17\xf8\xb1\x8e\x65\x4a\x1e\xd3"
-  "\xcb\xa7\xc8\xc7\x74\x72\x91\x73\x98\x5e\xb6\x87\x60\x3a\x39\x96"
-  "\x60\x7a\x59\x41\xe7\x8c\x75\x24\xbb\x39\x37\xd6\xb1\x5c\xe9\xc8"
-  "\x58\x87\x35\xa6\x53\xea\x9c\x1f\xef\x48\xc9\x70\x0e\xd3\x29\xc3"
-  "\x9d\xc7\xf4\x0a\x43\xfb\x8d\x77\xac\xb8\x2c\x1f\xd3\x2b\xcc\xce"
-  "\xbf\x58\x61\xb6\xfe\xff\x9d\x00\xf9\x98\x5e\x91\xec\x1c\xa6\x53"
-  "\xde\x21\x98\x5e\x31\x82\x60\x3a\x25\xa9\x73\xc6\x3b\x96\x6b\x9d"
-  "\x1b\xef\x48\x69\x73\xff\x0b\xb1\xf1\x0e\x6b\x4c\xaf\x3a\xe6\xfc"
-  "\x98\xc7\xaa\xa9\xce\x61\x7a\x55\x37\xe7\x31\xbd\xf2\x4c\xfb\x8d"
-  "\x79\xac\x3c\x2a\x1f\xd3\x2b\xd7\xf2\x63\x1e\x2b\xcd\xe6\x3f\xad"
-  "\xd2\xcb\xc7\xf4\xca\x08\xe7\x30\xbd\x2a\x92\x60\x7a\xa5\x2b\xc1"
-  "\xf4\xaa\xf0\xce\x19\xf3\x78\xe7\xb0\x73\x63\x1e\xab\xca\x1d\x19"
-  "\xf3\xb0\xc6\x74\xaa\xda\xf9\x71\x8f\xd4\x21\xce\x61\x7a\xcd\x79"
-  "\xe7\x31\xbd\x66\x4f\xfb\x8d\x7b\xac\xd9\x2c\x1f\xd3\x6b\x62\xf8"
-  "\x71\x8f\x35\x66\xfb\xdf\xa7\x56\xcb\xc7\xf4\x1a\x3f\xe7\x30\x9d"
-  "\x3a\x88\x60\x7a\xf5\x05\x82\xe9\x54\xdf\xce\x19\xf7\x58\xbd\xc1"
-  "\xb9\x71\x8f\x54\xab\xf9\x6f\x4b\xe3\x17\xc6\x29\x17\xcd\x9d\xbb"
-  "\x34\x3e\x59\xb9\x34\x71\xfe\x9b\xf1\xa3\x07\x9b\xbe\x8f\x0e\x4e"
-  "\x19\x9c\xd2\x0b\xc5\x2d\x98\x3d\x6b\xf9\x33\xfc\xcd\xc4\xf8\x85"
-  "\xf0\xa7\x17\x4a\x98\xbd\x34\x41\x99\xfc\x4e\x52\xbc\x12\x7f\x5b"
-  "\xf0\x66\x12\x24\x59\x94\xcc\x5f\x79\x35\x3e\x71\x76\xca\xfc\x85"
-  "\xf3\x94\xb3\x13\xe7\xcf\x5b\xb8\x20\x7e\x61\xb2\x72\x49\xfc\xe2"
-  "\x65\xf3\x97\xc4\xe3\xff\x97\x2a\xe7\x2e\x5a\x02\x17\xde\x8c\x9f"
-  "\xbf\x3c\x5e\x39\x67\xd9\xdc\xb9\xf1\x4b\x96\xf6\x42\x91\xcb\x12"
-  "\x93\xe7\x27\x25\xc6\x2b\xc3\x23\xc7\x0c\x9d\x32\xfe\x37\x53\x5e"
-  "\x7c\xb1\x17\x32\x3b\x7b\x5a\xc9\xe4\x46\x46\x03\x86\x14\x57\xe8"
-  "\x4d\x47\x2a\x7d\x11\xda\x0c\xd8\xdc\xb2\x04\x79\x6e\x5a\x82\x14"
-  "\x1b\x6f\x21\xd7\xcd\xb7\x90\x9b\xf1\x03\x5d\xb9\xf2\x2d\x14\xc6"
-  "\x78\xc5\x17\x6d\xb9\x85\xbc\x8d\x39\xbb\x94\x4c\xce\x4e\xad\xce"
-  "\x6b\x7d\x29\x4e\xcb\x78\xad\xab\xc1\xd7\xc1\x17\x0a\x26\xa7\x48"
-  "\x7d\x89\xde\x94\xac\xf3\x7a\x6f\x6f\xda\x55\x44\x31\xee\x69\xfa"
-  "\x83\x46\x1d\xf5\x15\x9e\x51\x0d\xb6\x42\x74\x86\x37\x7c\x10\x7c"
-  "\x4a\xe0\xa3\x41\x74\xa6\x1b\x7c\x46\xc0\x27\x14\x3e\x7b\xe1\x53"
-  "\x8f\xe8\x77\xfd\xe0\x13\x00\x1f\xb8\xf6\x6e\x34\x7c\x62\xe0\x53"
-  "\x06\x9f\x5a\xf8\x34\x20\x7a\xad\x1b\xc9\x67\x2d\xfe\xe4\xc2\xe7"
-  "\x18\x7c\xce\x22\x7a\xdd\x06\xf8\x40\x1e\xeb\x21\xbf\x75\x90\xf7"
-  "\xba\x0a\xf8\xe0\xeb\x3a\xb8\x86\xd3\xfa\x92\x7b\xeb\xb5\x88\x7e"
-  "\x0f\xde\xf1\x1e\xe4\xff\x1e\xe4\xfd\x5e\x16\x7c\x8a\xe0\xb3\x1f"
-  "\x3e\x87\xe1\x53\x03\x1f\x9c\x06\xde\xb5\x01\xee\x6d\x80\x77\x6c"
-  "\x28\x45\xf4\x46\x4f\xf8\x24\xc3\x07\xca\xb2\x29\x99\xfb\x40\x59"
-  "\x36\x45\x9b\x7d\x4f\x34\xfb\x5f\xec\x93\xe5\x91\xf1\x98\x56\x13"
-  "\xa8\x87\x76\x9b\xb1\x98\xc9\x44\x34\x93\xf3\xde\xde\xa4\x40\xe4"
-  "\x72\x8d\xce\x18\x5d\x05\x3d\x0d\xe3\xb9\x53\xab\x59\xd9\x82\xef"
-  "\x8f\xc6\x36\x6b\xcc\xce\x08\xd5\xa2\xb9\x7b\x71\xfb\x94\x87\xcf"
-  "\x8c\x50\xee\xf9\xd5\x5a\x17\x17\xb6\x7d\x33\x1f\x04\x56\x33\x69"
-  "\x31\x3b\xf0\x3a\x5c\xc8\xdf\x1b\xaf\xd3\x65\xd4\x81\x13\x19\x4f"
-  "\xff\x26\x1c\x63\x34\x2b\xd9\x72\xf9\x90\xf6\x08\xf7\xa1\x6c\x3a"
-  "\x2f\x5d\x39\xb4\x3f\x05\xfe\xce\x80\xcf\x99\xa2\x98\x10\x12\x77"
-  "\x32\x58\xfd\xd2\xe2\x33\x26\x1d\xdf\x6b\xde\x33\x20\x98\x29\x56"
-  "\x95\x6b\x16\xb6\xa0\x5a\x3a\xc3\x0b\xea\x46\x41\x0c\xa4\x98\x27"
-  "\x07\x04\x1b\xb7\x8e\x49\x3f\x0a\x38\xc0\xe9\xfe\x94\x5a\x87\xff"
-  "\x7a\xe2\xfb\x4c\xee\xd8\x08\x3c\x0e\xa4\x49\xfd\x08\xe2\x72\x86"
-  "\x4f\x8b\x4f\x8c\x52\xf9\xaa\x07\x03\xff\xef\x83\xb2\xb1\xe9\x4d"
-  "\x65\x69\xf1\xd2\x55\xe3\xfc\x19\x65\x8c\x16\xee\x29\x8c\x39\xeb"
-  "\x4b\xa1\x1c\x2e\x37\xe0\x39\x06\xca\xa8\x79\x15\xbf\x37\x73\x37"
-  "\x94\x95\x4a\x9b\x0c\x79\x7f\x14\xa3\xfd\x74\x65\x13\x85\xef\x19"
-  "\xd5\xba\x72\xc0\xbb\x1b\x93\x9d\x7a\x61\x7b\x5f\xa4\x28\xfc\x00"
-  "\xa1\x5d\x1f\x20\xd7\xc6\xec\xcc\x7c\xad\xc2\x33\x8b\xc4\xbe\x0c"
-  "\x6f\x0a\xd2\x68\xe9\xcc\x64\x06\xf0\xcb\xbe\xcb\x3b\x54\x63\xe3"
-  "\x5d\x97\xef\xbd\x6b\x6b\xa8\x06\xbf\x8b\xd8\x48\x57\x4e\xfe\x92"
-  "\x3c\x8c\xc5\x03\xb4\xd8\x7e\xd8\x76\xa6\x3c\x8c\x39\xf7\xf2\xe8"
-  "\x86\x9f\x87\x77\xd6\x30\x1f\x0f\xd0\x1a\xb7\x8e\xd3\xc2\xb3\x87"
-  "\xf1\x7d\x8f\x0c\xd4\xc0\xc0\x5f\xfc\x7e\xe2\x0b\xb0\x7d\x77\xc0"
-  "\x07\xf6\x07\x77\x8d\x81\x6b\x5a\xfa\x5d\xa5\x31\x53\x09\xb8\x09"
-  "\xca\x27\x7e\x7d\x77\xc1\x3b\xd5\x8c\x11\x3e\x86\xa7\xab\x91\x8b"
-  "\xe6\x55\xec\xd3\x77\xb3\x94\x93\x7a\x80\x5d\xdf\xdd\x7c\xcf\x9e"
-  "\x83\x62\x6a\xc0\x26\x9e\x85\x7d\xc1\x2e\x99\x2d\x7a\x36\x0f\xa8"
-  "\x8f\xb9\x7d\x70\x1d\x1a\xb3\xdf\x3d\x66\x61\x23\x4f\xb8\x56\xad"
-  "\x45\xad\x23\xf0\x35\xe5\xe3\x2c\x16\x7c\x18\xce\x5f\x18\xcf\xd8"
-  "\x77\xc6\xbc\xc8\x68\xfc\x7d\xea\x10\xe4\xe9\x51\x8d\x28\x65\xaa"
-  "\x7f\x29\xf1\xf1\xd8\x08\xa8\x6f\x2d\x7e\x17\x94\x5d\xc5\x6c\x1d"
-  "\x96\x6f\xc8\x84\x3e\xf4\x1e\xae\xd6\x4e\x34\xe4\x04\xa9\x5b\x7c"
-  "\xc6\xa1\xe6\xbc\x17\x34\x8c\x3a\x48\x8d\xd7\x95\x5f\xa2\xd7\xb2"
-  "\x6b\xed\x98\x4c\x57\x44\xde\x13\x94\x9b\x9a\xc8\xe8\x52\x6f\x82"
-  "\xfd\xfb\x8d\x43\x7f\x5a\xae\x03\x3f\xbc\xa0\xc1\x7e\x3e\x7a\xb7"
-  "\x89\xc2\x7b\xfd\x31\xee\xa9\xc6\x5d\x50\x9f\x9d\x50\x17\xa8\x27"
-  "\xc2\xf9\x36\x66\xaf\xcd\xe2\xeb\xb3\x36\x18\xfb\x1c\xde\xb1\x97"
-  "\xc3\xb4\x37\x94\xcb\x85\xf1\x0a\x82\x7a\xaf\x3d\xac\x75\xf9\x38"
-  "\xd9\x54\x6f\xf6\xdd\x7c\x3a\xae\x8d\xac\x85\xf6\x11\xb4\xb7\x75"
-  "\x39\x53\xbd\xe5\x3b\xc8\x3f\x13\x31\x2d\x77\x99\x8a\xd5\xd1\x4c"
-  "\x53\xf6\x6f\xf1\xfc\xc5\x0b\x28\x6d\x36\xf2\xeb\x9d\xc1\xe8\xa2"
-  "\x0c\xc8\xa3\xf7\x05\x0f\xe6\x74\xf4\x05\xf6\xcc\x83\xd5\xd5\x4c"
-  "\x5d\x65\xd2\x31\xb4\xfa\x32\x72\x5b\x33\x1f\x79\xa7\x45\x43\x5d"
-  "\x2a\x98\xa6\xaa\x94\x0b\xa8\xb2\x01\x3e\x49\xa7\x21\xdd\x39\xf8"
-  "\x1c\x43\x69\xef\x20\xc5\x24\xe8\xcf\x52\xef\x20\xb7\xca\xa4\x3b"
-  "\x70\xed\x3a\x5a\x1d\xcb\xe8\x4f\x57\xe0\x74\x27\x50\x94\x5e\xe7"
-  "\xb1\xe6\x3a\x52\xec\xfa\x2d\x5e\xab\x7d\x11\x15\x42\x59\x5a\xbc"
-  "\x76\x79\x36\xe7\x14\xe5\xdf\x5e\xce\xe8\x1b\xb3\xd7\xa5\x6b\xd1"
-  "\xc8\x24\x41\x5d\x70\x99\x5b\x10\x02\x5f\xb9\xe0\x34\xc6\xbc\xe7"
-  "\x8b\x66\xe9\x71\xdc\x58\x97\x0c\x7c\x02\x99\xee\xe3\x7b\x3a\x9f"
-  "\xe7\x8b\xe0\x7a\x51\x94\x9e\x69\x04\x3f\xb3\xf5\x06\xfb\x17\x73"
-  "\xf5\x2f\xa6\x93\x90\x02\xde\x51\xab\x75\xd9\x17\x8d\xdf\x01\x79"
-  "\x76\x87\xf7\x14\x61\x6c\x90\x7b\xeb\x91\xd6\xe5\xf7\xf9\x3c\x5e"
-  "\x58\xff\x77\x37\x95\x05\xee\x2b\xb5\x2e\x7b\x8b\xcc\xf0\x84\xe3"
-  "\xc3\xbd\xfb\x5c\x3f\x85\xaf\x63\x6c\xd1\x10\xaf\x2a\x0c\x3e\x63"
-  "\xa3\x19\xaf\x9b\xb1\xcc\x6d\x5f\x37\x86\x62\x9a\x26\xe9\x99\x26"
-  "\x63\xde\x50\xdc\x47\xb9\x55\xe9\x1b\x10\x49\xbf\xfe\x04\x93\x73"
-  "\x33\x81\xcc\x0d\x5d\x7f\x00\xe7\x09\x9c\x05\x65\xdf\x42\x9e\x51"
-  "\xd5\x4c\x13\x6e\x97\xc6\x9c\x66\x6d\xf6\x12\xe4\xcd\xe4\x8d\x0d"
-  "\x33\xfa\x8c\x8e\x6e\xde\x1d\x13\x8c\x63\x27\xe3\x13\x19\xcd\xa8"
-  "\xe1\x59\x2e\x1f\x78\x6f\x37\x2d\xbd\x7e\xad\x11\x9e\x67\x72\x87"
-  "\x16\x71\xe5\x61\xe3\x1c\x89\x8f\xeb\xd7\x32\x83\xe1\x9e\xda\xbf"
-  "\x1a\xee\x75\xbb\x44\xbf\xe7\x09\xd7\xe1\xfb\x60\x57\x4d\xea\x2d"
-  "\x48\xfb\x9e\x0f\xc1\x90\x7f\x85\xe0\x3b\x85\xed\xf9\x6e\x30\x6e"
-  "\xd7\x84\x5f\xbe\x37\x92\x6f\xb7\xa6\x76\x02\xed\xd5\x67\x68\x49"
-  "\x63\xf6\x7b\x11\x5a\x17\x45\x2c\x1b\xcb\xe1\xb9\x06\x36\xd6\xbc"
-  "\x1b\x0e\x5c\x2c\xe4\xeb\x68\x84\xbe\xae\x40\x08\xd2\x24\x6a\x5d"
-  "\xba\x6f\xe0\x6d\xf9\xde\x3a\x9c\x96\x6d\x93\xd0\x36\xc9\xfb\x00"
-  "\xe7\xf0\x0c\xb3\x75\xac\x0e\xc7\x17\x1c\x67\xb4\xf4\x7b\xe9\x38"
-  "\xc6\x40\xfb\x8c\xe1\xe2\x79\x29\xdb\x3e\x3f\x98\x59\x03\xe5\x4a"
-  "\xbf\xc4\x95\xc5\xbc\x6c\xa6\x58\xc2\xe4\xcc\x8a\x21\x69\x83\x70"
-  "\x19\xeb\xb5\x2e\x3d\x62\xcd\xb1\x46\xea\xb5\x61\xf6\xd3\x15\xf0"
-  "\x3f\xf0\x0d\x53\x5e\xd0\x56\x5d\x99\xec\xb4\x7e\x18\x83\x38\xe6"
-  "\x6c\xfb\x00\xfb\x63\x56\x6c\x73\xce\xac\x84\xc6\xec\x0d\x23\x4c"
-  "\xed\xd4\xb8\x9c\xc1\x1c\x03\x19\xef\x32\x67\xb7\x80\x2f\xa3\x0c"
-  "\x34\x33\xcb\xa0\x42\xc0\x47\xf5\x85\x70\xbd\x70\x39\xe6\x73\xeb"
-  "\x92\xa0\x2d\xbb\x8a\xa7\x55\x20\x9c\x8e\x4d\xcf\xa5\x6d\xf1\x9a"
-  "\x15\xcb\x96\x39\x93\x36\x42\xf9\x5c\x4c\x65\x6a\xf1\x0a\x2a\x80"
-  "\x77\x97\x68\xd1\x9d\x29\x82\xf6\xf2\xc1\x13\x3a\x86\x89\xc1\xb8"
-  "\xa2\xa1\x2e\xe7\xe0\x6f\x0f\x0e\xa7\xbd\xbf\x06\xbe\x1a\x0e\xca"
-  "\xec\x36\xf8\x7b\x7b\x3f\x46\x07\xcf\xeb\xb4\x68\x5a\x2d\x7e\x7e"
-  "\x13\x7c\xc7\xd7\x71\x9a\xc6\xec\x8d\xae\x5a\x34\xfd\x2c\xc9\xf7"
-  "\xdd\x60\xec\x3f\x61\xbe\x1b\x87\x92\x7c\xd9\xb2\xf4\xc6\x79\xe2"
-  "\xe7\x70\x9e\x3b\xb7\x32\xf5\x38\x1f\xc8\x63\xa2\x29\xef\xcd\x70"
-  "\xcd\x94\x7f\xf8\x82\x7b\xef\x48\x84\x77\xcc\x30\x2f\xfb\xb6\xad"
-  "\x4c\x03\x29\xd7\xc6\x0d\x5a\x34\x7b\x3f\xbe\xb7\x11\xae\xe1\x67"
-  "\xcd\xda\x1b\xcd\x63\x68\x23\xd4\x3f\x56\x10\xdf\xc1\x47\x7d\x4c"
-  "\x9c\x80\xcb\xeb\xac\x29\x2f\xcb\x7c\x18\x75\x6c\x98\x59\x7b\x75"
-  "\xc3\xf9\x36\x66\x6f\x52\x68\xd1\x8c\x14\xae\x5c\x87\x1b\x08\xde"
-  "\xc1\xee\x9b\x86\x60\xbb\xe3\xbe\xc6\x98\xc9\xf1\x8e\xdd\x31\x21"
-  "\x1c\x36\xfc\x4d\xfd\x11\xf8\x25\x1f\xf2\x88\xe0\x63\xf7\x26\x3f"
-  "\xec\x6f\xb8\xbe\x81\xcb\x3f\x0e\x7c\xe6\x6d\x5e\x6f\xb0\x71\x18"
-  "\xd3\x6f\x6c\x12\x8e\x59\x5c\x79\x46\xe3\xfe\xc9\x74\x1f\xde\xa1"
-  "\x30\x66\xa7\x3d\x87\xdb\x04\xf4\x77\x88\xf1\x79\x21\x18\xf2\xd9"
-  "\x6f\xd1\xdf\x29\xb8\x74\x6f\xe3\x34\x1f\xf6\x63\xea\x20\x4d\xb5"
-  "\x29\x0d\xbe\x0f\xf6\xff\x35\x5c\xab\xd5\xa2\x78\xf6\xfd\xd9\x90"
-  "\x46\x4b\xa7\x49\xae\x8f\x01\xc5\x43\x55\x15\x68\xb1\x76\xc4\xed"
-  "\x3f\xb4\xca\xaf\x01\x55\x15\x18\x91\xf1\xe3\x5f\xc6\x86\xa5\x32"
-  "\x9a\x2b\xf4\xfb\xb3\x2b\x9b\xea\x90\x3c\xbe\xf7\x3e\xbb\xfe\x8d"
-  "\x69\x01\x8d\xb3\xfa\x19\x84\xb9\xc0\x0d\x3a\x2b\xa7\x4a\x77\x8b"
-  "\x8d\x85\xf0\xff\x1a\x7c\xff\x43\xd0\x44\x58\x17\x81\xf6\x4d\x50"
-  "\x53\x44\x1b\x19\x21\xed\x2e\x7c\x1d\xeb\x26\xd0\x6c\x85\x66\xf7"
-  "\x98\x8f\xfb\x6b\x89\xed\xb2\x26\x60\x3b\xb2\xe5\xd5\xbf\xac\xc1"
-  "\x65\x36\x16\xf7\xd7\xe2\x3a\xa4\xa5\x30\xc6\x2a\x7d\xa3\xa6\xb2"
-  "\xc1\x80\x94\xcb\xb1\xa6\xcb\x1a\x1c\xb5\x13\x31\xc6\x3d\xfd\xb5"
-  "\x32\xeb\xc0\xce\xff\x03\xdd\x7b\x43\x37\xb8\xbf\x36\xcd\x80\xa8"
-  "\x2d\xa9\xdd\x5c\xc7\x15\x30\x9a\xdb\x4f\xfe\x32\xb6\x31\x3b\x2b"
-  "\xe2\xab\x14\x84\xe4\x73\xe1\xac\x08\x53\xdd\x77\x71\x75\x87\x77"
-  "\xb1\xeb\x45\x9f\xce\x4f\x67\xeb\x0b\x69\xd2\xa5\xfc\xc5\x64\x7a"
-  "\x30\x5f\x17\xe8\xd1\xd2\x02\xa6\x65\xe9\x4e\x44\x19\xb6\x3e\xad"
-  "\xfc\x74\x57\x0d\x8e\xfb\x61\x26\x7b\xb2\xb6\x03\xbd\x9f\x94\x8a"
-  "\x3c\xae\xd1\x9b\x87\x44\xad\x46\xec\x19\x49\x5f\x42\x3a\x99\x65"
-  "\x65\xc7\xff\x2a\x41\x47\x47\x19\x18\x23\xe9\xbb\x36\x4f\x9e\xc4"
-  "\xe5\x87\xef\x99\xfc\xb7\x8b\xd3\xb7\xf2\xdf\xb1\x59\x72\xfd\xbf"
-  "\x8d\xba\x7a\x8a\xd7\x35\xdb\xc7\xf1\xba\x6e\xd6\x5a\xd7\x35\x7b"
-  "\x74\xfb\xd6\x35\x3b\xdc\x81\xba\x2a\xc5\xeb\xba\xc5\xc5\xf1\xba"
-  "\x66\x57\x58\xd7\x75\xcb\x90\xf6\xad\xeb\x16\xc9\xfd\x9f\x6c\xd4"
-  "\x35\x58\xa2\xae\xd7\x1d\xaf\xeb\x96\x52\xeb\xba\xaa\x7d\xda\xb7"
-  "\xae\x6a\xc9\xf3\x4f\x19\xca\x83\xc1\xf1\x09\xe2\x52\x4b\x6a\x33"
-  "\x70\xbe\xad\xe1\xba\x35\xbb\x11\x55\xd1\xd0\x84\x2a\xfd\x6a\x30"
-  "\x9f\xa6\x86\x25\xb1\x9c\x28\x94\xf9\x40\xa7\xad\x2c\xa8\x87\xeb"
-  "\x57\xd0\xe9\x94\x26\x14\xb6\x04\xc7\x5f\xf5\x0f\x55\x71\x72\xe3"
-  "\xaf\x7a\xff\xbd\xf8\xab\x7f\x86\x8b\xb9\x1f\xf4\xa9\xac\x6f\x41"
-  "\xb8\xfe\x37\xe8\x9c\xe6\x7b\xf1\x37\x93\xd8\xdb\x32\xfe\x62\x7b"
-  "\x54\x35\x35\x09\xe2\x2f\x59\x27\x95\x73\xc2\x32\xf6\x66\x5f\x43"
-  "\x48\x3c\xf6\xe6\xec\xc6\xb1\x77\x17\xdc\x97\x57\xfe\x9c\x44\x53"
-  "\xec\x55\xc3\x3b\xcd\x63\xef\xd7\x71\xb8\x7f\xcd\x29\x73\x2c\xf6"
-  "\xe6\x94\x99\xea\xbd\x93\xab\x37\x5c\x0b\x10\xc6\xde\x1c\xc9\xb3"
-  "\x2e\xcd\x71\xcb\x6c\x0d\x44\x9f\x0e\x6c\xea\x66\x2c\xf6\x53\xe2"
-  "\xfe\xad\x11\x6c\xf2\xc7\x5d\x4d\x8a\x2b\xf4\x07\xab\xd9\xf1\xcc"
-  "\xc6\x38\x17\xa6\x78\x40\x79\x54\x32\xf3\x3d\x33\xd8\x4f\x89\xc7"
-  "\x2a\xb1\xe6\x86\xfb\x87\x80\xf7\x97\xcb\x2b\x37\xc9\x13\xfa\xbf"
-  "\xd8\x54\x68\x2f\x9f\x2e\x6f\xa2\x8c\xab\x62\x3c\xc0\x0f\x9e\x4c"
-  "\xde\xb0\x30\x66\x7d\xcf\x9a\xdb\x79\xe3\x4a\x4e\x04\x5c\x46\x38"
-  "\x2d\x93\xa1\x08\x75\xbc\xfc\x1f\x86\xda\x2e\xff\x87\x8b\xe5\x97"
-  "\x9f\xe4\x69\x5f\xf9\x3f\x0c\xb5\xab\xfc\xfd\xa0\xfc\x2d\x21\xdd"
-  "\x40\x27\x52\x5f\xb6\x84\x28\x64\x96\x47\xf2\xfc\xbb\xf6\x7b\x47"
-  "\xae\xdd\xf1\x8f\xe9\xf7\x42\xd8\xa7\xbb\x74\x14\xc4\x00\xb6\x0f"
-  "\xc7\x6d\x8f\xc4\xbf\x3a\xd0\xd3\xdf\x33\x24\x26\xe9\x64\xc6\xa4"
-  "\xdc\x12\xfb\xdf\xff\x74\x51\xfb\xbf\x3f\x4f\xba\xfe\x96\x31\xf1"
-  "\xe0\xd0\x30\xc9\x98\xb8\x75\x58\x91\x75\x4c\xcc\xbb\x23\x3f\x26"
-  "\xe6\x69\xac\x63\xe2\xef\x06\xf1\x31\xf1\x77\x7d\x1c\x8f\x89\x5b"
-  "\xcf\xdb\x1f\x13\xb7\x1e\x71\x2c\x26\x6e\x4d\xb7\x1d\x13\xb7\xd6"
-  "\x38\x16\x13\xb7\xd6\x58\xc7\xc4\xad\xa1\xc2\x98\xf8\x3b\x4f\x49"
-  "\x5f\xaa\x1f\x29\x85\x3e\xda\xed\x1a\xfd\x3b\xad\x3e\x13\xb4\xae"
-  "\xfa\xfd\x72\xe8\x67\x1b\x99\x9c\x47\x4a\x8d\xd4\x08\x1c\x57\xc2"
-  "\x1a\x1b\x13\x5c\x8d\x2b\x02\xdc\x98\xbe\xfe\xa9\x4c\xab\x2f\x1e"
-  "\xdb\xf3\x87\xf2\x7b\x30\x8d\x01\xee\xcc\x8a\x80\xbe\x05\x77\x91"
-  "\x37\x7c\x7c\x0b\xb8\xfe\x18\xfe\x0f\x66\x56\xf8\xf6\xca\x5e\x8e"
-  "\x54\x1e\x0d\xc8\x15\xca\x10\xe3\x91\xe1\x89\x20\x06\x79\xe3\xff"
-  "\x99\xcc\x6d\xa8\xf0\x2e\x52\x78\xa4\x80\x6f\xbc\xe0\x7d\x29\x1e"
-  "\x0c\xb3\x34\x00\x15\x2e\x01\xcd\x4d\x21\xdf\x5d\x14\x53\xa2\x6f"
-  "\x0c\xa0\x0c\xde\x63\x63\x89\x7f\xf2\x73\x59\xed\x95\x3b\x56\x65"
-  "\xec\x37\xd6\xdb\x90\x96\x40\x33\xab\x62\x68\x5c\x56\x43\xee\x58"
-  "\x4f\x66\x2b\x7c\xd2\x12\xdc\x31\x87\x06\x4d\x1e\xcc\x34\xfa\xf6"
-  "\x02\xbd\xae\xda\xb5\x1c\xf9\xef\xbc\x8b\x02\x98\xdb\x01\x14\xf8"
-  "\x3f\x06\x9f\x35\x0a\x36\x8a\x31\x52\xdb\x10\xdc\x53\xe0\x98\xc8"
-  "\xe0\xf7\xeb\xe1\xfd\xad\xf0\xfe\x16\x8c\x6d\xe4\x5b\x08\xef\x37"
-  "\xac\x08\x90\xd9\x5e\xf2\x63\x59\x7c\x72\xe5\x32\xaa\x46\x86\x31"
-  "\x07\xe1\x83\xcb\x05\x36\x2c\xc4\x36\x19\x36\x32\x1c\x97\x6d\xf3"
-  "\x5d\xa4\x82\x72\xfa\x43\x19\x02\xe0\xbd\x78\x9f\x96\x98\x99\x8b"
-  "\x3d\x31\x46\x05\x65\x33\xe4\x70\x65\xfb\x19\xca\x76\x83\x2f\x1b"
-  "\x7e\x17\xb6\x8f\xd4\x6f\xa0\x51\x6b\x06\xe2\xb6\xf9\xa3\x47\x4a"
-  "\x8f\x08\xfc\x7b\xe8\xed\x55\x09\x32\xb1\xba\x4d\x72\xff\x93\x2d"
-  "\x07\x91\x1f\xe3\xb9\xae\x7c\xd2\xba\xef\x99\x28\xe8\x69\xd7\x1d"
-  "\x44\xaa\x2a\x68\xd7\x95\x4d\xd7\x11\xe3\xb5\xae\xfc\x44\x40\xbd"
-  "\xdc\x77\xe5\x4b\xbd\x6b\x53\x26\x53\xdd\xea\x8f\xc7\xc8\xc6\xed"
-  "\xdd\x42\x31\x29\x2d\xfe\x03\xaa\x4f\x9d\x6d\x41\xb3\x52\xf0\x6f"
-  "\xae\x4c\x8a\x72\x3a\x72\xbd\x44\x17\x4d\x4c\x3b\x8f\x7f\x1f\xda"
-  "\xee\x27\xfc\x7d\x68\x7b\x18\xa2\x77\xd4\x22\x7a\xa7\x37\xa2\x77"
-  "\x15\x20\x48\x27\xfc\x14\x9e\x8d\xda\x37\x10\xa5\xea\x99\x1f\x19"
-  "\xf5\x2d\xdf\x6c\x8a\x69\x8a\x1a\xe2\xa2\xd5\x2c\xc7\xbf\x97\xec"
-  "\xb8\x08\xf6\xfb\x09\xfa\x55\x0f\xfc\x3f\xce\x2f\x69\x09\x7a\xe4"
-  "\x1a\xbd\xe3\x82\x47\x43\x8f\x08\xbd\xf7\xb8\x6a\x3d\x13\x83\x5a"
-  "\x95\x31\xc1\xcd\xb9\x63\xc3\x5a\xf1\x18\xde\x1c\x1c\x83\xb6\x9f"
-  "\xf3\x70\x49\x47\x0c\xf8\x9f\x61\x7c\xf1\x6f\x86\x31\x05\xf0\xc1"
-  "\xbe\x64\xfd\xd8\x37\xd0\x15\xfb\x1b\xb7\x85\x42\x72\xdd\x13\xb7"
-  "\x87\x2d\x5c\xbb\xd1\xd1\x81\xb1\x06\x0a\x21\x03\x3c\x9f\x76\x19"
-  "\xf9\xe1\x33\x66\x77\x42\xba\x59\x06\x57\xdc\x8e\x63\x34\xd3\xbf"
-  "\x45\x57\x92\x10\x95\x76\x13\xf5\x01\x4c\xb0\xed\xd1\x08\xed\x31"
-  "\xea\x82\x47\x13\xc4\x15\x63\xea\x1d\xe4\x81\xe3\x14\x3e\xaf\xa5"
-  "\xaa\x5e\x8b\x8c\x3f\x07\xb8\xef\x58\x88\xbc\xf5\x3f\x27\xf4\xd5"
-  "\xfd\x9c\xf0\xc8\x36\x23\xf2\x76\x4f\x42\x9e\x3b\x17\x02\x16\x17"
-  "\x41\xfb\xbc\x01\xed\xb3\x9e\xb4\x4f\x13\xfe\x98\x4d\x7f\xf1\xc3"
-  "\xeb\xe8\xd9\xb6\x99\xc3\xb5\xcd\x15\x01\x78\x5c\xec\x1e\xfe\xf4"
-  "\x8b\x02\xa8\x9d\x14\x83\xa0\x8c\x60\xf7\x6d\x6e\x85\xa9\x3d\x5c"
-  "\xf1\x38\x26\xf3\xa4\x1f\xfe\x8d\x03\xea\xca\xe8\x3f\x05\x5f\x74"
-  "\x1b\x42\x29\x99\xbc\x71\xd5\xa7\xa2\xeb\x10\x3f\x6e\x52\x14\xd9"
-  "\x32\x78\x40\xb5\xf2\x55\xe6\xe7\x4b\xf4\x8e\xb3\x70\xdd\x55\xf9"
-  "\xdb\xa7\x3c\xc1\x8f\xdc\x7c\x84\xa2\x89\x78\x5c\x55\x4b\xef\xc0"
-  "\x63\x38\x08\xff\x0e\xff\x0d\xfb\x1b\xd7\x4e\x37\x48\x8b\x0c\x60"
-  "\x73\xbd\xe7\xcd\x04\xa3\xf7\xd8\x24\xcd\x5b\x2d\x6c\xbc\x6a\x05"
-  "\x1f\x5c\x49\x44\xd4\xac\x7a\xb0\x8d\x01\x6c\xd3\x18\xe0\x06\x71"
-  "\x2b\x1a\xc7\x2d\x46\xed\x9f\xb2\x5a\xcb\x18\xa3\xe2\x68\x06\xec"
-  "\xe2\x5a\x95\x62\x40\x33\x93\x10\xb3\xe6\x3a\xd8\xa8\xa1\x06\x41"
-  "\xdd\xdc\x21\xb6\xf5\xdd\xb9\x1c\x79\xef\x00\xfb\xf4\xa9\x07\x4e"
-  "\xf3\xc1\x7b\x9a\x83\xa9\xe5\xdd\x0c\x80\x73\x1c\xc7\x3c\x32\x5c"
-  "\x7a\x82\xaf\xdc\xb3\x70\xbb\x85\x76\xec\x91\xc1\xc6\x55\xd6\xb7"
-  "\xfa\x15\x01\x8f\xb7\xae\x08\x50\xc2\x67\xa0\x29\xd6\x99\xe2\x0c"
-  "\x93\xbd\x2d\x19\xc7\xb9\xaa\x14\x2d\xd2\x83\x2d\xdd\x71\x9f\xb8"
-  "\x22\xc0\x8f\xb5\xe9\x3c\xb0\xe9\x5c\xe4\xfa\x74\x13\x72\x81\x72"
-  "\x79\x42\x99\xd1\xe9\x84\x4b\x38\xb6\xfa\x1a\xa0\x1d\x61\x3b\x43"
-  "\x9e\x14\x03\x58\x33\xaa\x6f\x26\x44\xce\x57\xa2\x13\x01\xe7\x10"
-  "\xde\xab\x35\xad\x99\xf9\x01\xff\xc6\x56\x95\xa2\x47\x8c\xcf\xb8"
-  "\x6a\x32\x8e\xbe\x63\xff\xa9\xe8\x26\x24\x8d\xe9\x5d\x79\x3c\xa6"
-  "\x77\xe5\xf1\x98\xde\xc5\xae\xc1\x36\xc7\x75\x73\x11\xe0\xda\xdb"
-  "\x1c\xd7\x3b\x0f\x74\x28\xae\x27\xc9\xc7\xf5\xb6\x1b\x66\xb8\x4e"
-  "\xfd\xef\xe0\xfa\x9b\x18\x16\xd7\x74\xeb\x60\x16\xaf\x25\x55\xfa"
-  "\xcf\xe0\xef\xae\x74\x13\x6e\x4f\x7e\x82\x71\x5b\x58\xd6\x55\x71"
-  "\xdb\xdc\x18\xa0\x84\x4f\xbb\xe3\x16\xf2\xb4\x1b\xb7\xdf\xc4\xb4"
-  "\x20\x93\xfd\x30\x7e\x19\xf5\xba\x72\x65\x1a\x7a\x11\xe2\xc4\x44"
-  "\x8f\x8c\x81\xe8\x34\x6b\xc3\xa2\x89\xca\xdf\x32\xc6\x4b\x74\x21"
-  "\xbb\x06\xa0\x25\x93\x61\x8c\xde\xa3\xa3\xd3\xce\x20\x4f\xa3\xba"
-  "\x59\x5b\xa5\x3f\x80\x3c\x92\xc8\x6f\x0f\x8c\x57\x91\x1a\x74\x78"
-  "\x39\xf9\x3d\x66\x5d\x8d\x21\xe7\xbd\xbd\x06\x88\x27\x86\xbc\xc8"
-  "\x68\x63\x4e\x7c\x91\xd1\x6b\xa7\x96\xc1\xf3\x0e\xbc\xd6\x97\x36"
-  "\x66\x17\x4d\x34\xfd\x1e\x2e\xca\x8d\xbc\x23\xa3\xa1\xbd\x80\xa6"
-  "\xda\x7d\x02\xfe\x52\x50\x8e\xcb\xf0\x97\x86\xbf\x47\x58\x8d\x25"
-  "\xab\x9f\x2b\x22\x63\xa0\xb9\xe3\x6a\xb9\x38\x98\xc1\xb6\xc1\x40"
-  "\xd4\xe7\x1a\xf7\x3f\x94\xe7\x82\xe9\xf7\xf5\x7b\xe9\x79\x7b\xa4"
-  "\xe0\x77\x83\x4d\x14\xe4\x37\x7f\xf2\x1d\xcf\xa7\xe1\xf2\x63\xbf"
-  "\x1b\xfd\x55\xe5\x9a\xd4\x4b\xa8\x9e\xde\x1d\x51\x05\x7d\xbf\x71"
-  "\xeb\xb8\xda\x2d\x77\x01\x8f\x29\xf7\xe2\x6f\x86\x3b\xf8\x5b\xb3"
-  "\x92\x4d\xc3\xae\x13\x32\xe6\x3e\x5f\xc2\x7c\x70\x53\x8b\x35\x64"
-  "\x23\x93\xf0\x6b\xee\xef\x68\x8c\x6d\x32\xde\xb2\x3b\x8f\x01\xfb"
-  "\xe1\x33\xd6\xef\xcd\x31\xc2\x67\x9f\xa7\x2b\xfc\xbe\x5a\x4d\xfa"
-  "\x5b\x53\x79\xf1\xf9\xe8\x78\x0e\xcf\x53\xe9\x28\xbd\x51\xe4\x7c"
-  "\x74\x7e\xae\xcf\xee\x74\x63\xde\xf3\x25\x8d\xd9\xbb\xab\x81\x03"
-  "\xd4\x98\xd7\x59\xcc\x17\x90\xbe\x5e\xea\x9e\x3c\x3f\x7c\xe4\x2a"
-  "\x95\xcf\xf8\x00\x03\x23\x33\x2f\xc9\xfd\x8f\x18\xff\xfe\xb1\x51"
-  "\x7b\x0d\x1a\x63\x6b\x8c\xc7\x89\xd5\xd7\x65\x72\xa2\x8f\xf6\x4b"
-  "\xe5\x6b\xc8\x1d\x9d\xa4\x7f\x12\xf2\x1e\x32\x10\x19\x16\xc5\xbc"
-  "\x0c\x3e\x72\xc3\x5c\x6f\xcd\x7c\x32\x2f\xac\x62\xaf\x1e\x61\xde"
-  "\xb7\x6f\x61\x39\xd5\xd2\x1a\x83\xdc\x75\xc8\x73\xd2\x1d\xc6\xb8"
-  "\xe5\x06\xf2\x67\x56\xc4\x78\x64\xdd\x40\xa1\xad\xb7\x7d\x7b\xbd"
-  "\xbf\x04\x29\x5a\x20\x26\xb7\x2c\x4d\xf0\xc0\x73\xd0\xfe\x7c\x4d"
-  "\x43\x55\xe9\x4b\x31\xcf\xf4\xc7\xfd\x00\x2e\xbb\xe1\x76\x8c\xfb"
-  "\xc6\x5b\x88\xfd\x8d\x59\x33\xe7\x23\xe8\x07\xfe\xe7\x68\xb7\x35"
-  "\x10\xfb\x20\x76\xb1\xfd\x81\x03\x7d\x41\x0b\xf4\x05\x91\x31\x4c"
-  "\x53\x65\xcd\xb7\x28\xed\x3a\xf2\x4c\x5b\x86\xfa\xe0\xfc\xab\xf4"
-  "\xc7\x49\xff\x30\x15\xfa\x07\xf8\x0e\x5a\xe2\x5e\xff\xa0\x9c\x84"
-  "\xac\xfa\x07\xac\x43\x2a\x2f\xd4\x21\xc0\x72\x8f\x49\x0d\x1e\x4d"
-  "\xa9\x0d\x8c\x11\x6b\x12\xfc\x7b\x36\xa4\x71\x37\xf5\x15\xb8\x9f"
-  "\x68\xe1\xfa\x89\x9d\x5c\x3f\xb1\xbd\x1d\xfa\x89\xed\xb8\x9f\x38"
-  "\x87\xa8\x6d\xb8\x8f\x80\xfe\xe1\x7f\xff\xad\xa3\x5a\xa1\x4f\x90"
-  "\xe7\xe7\x62\xc9\xfd\x4f\x98\xad\xe3\x3e\x37\x42\x5f\x8c\xfd\xbc"
-  "\x0a\xfc\x8b\xfd\x5c\x15\x00\xbe\xad\xe9\x11\xd1\x0c\xd7\xf5\x5b"
-  "\x03\x95\x7b\xaf\xe8\x28\x26\x77\x58\x58\x33\xe0\x61\xe5\x1d\x44"
-  "\xe9\xbd\x47\x27\x1d\xf8\xad\x9a\xc2\xba\xd5\x98\x17\x18\x47\x34"
-  "\xf2\xef\x7b\xe2\x31\x1a\x8f\x3a\xe4\x89\xc7\x4f\x0d\x4c\x8c\x87"
-  "\xf1\xa7\x98\x3e\xc6\xb7\x7d\x5d\x5b\x7f\xf2\xed\xb5\xe9\x2d\xa4"
-  "\xd0\xbd\x9d\xe0\x91\x36\x0d\x79\x7e\xf9\x0f\x35\x55\xd9\x00\x6d"
-  "\xbb\xfb\xe7\xf5\x0c\xe4\x5f\x78\x09\x85\x14\xce\x41\x23\x76\x5d"
-  "\x41\xca\x5d\x73\x91\x6a\xc7\x15\xc0\xd0\xdb\x31\xee\xad\x2c\x3e"
-  "\x9a\x35\xec\xfc\x80\xb9\x28\x8c\xe9\x37\x54\x09\x7f\x43\xd4\x73"
-  "\x41\xcf\xf4\x0b\x54\x32\x3e\xa3\x93\x8c\x90\x2e\x0b\xb4\x1b\x70"
-  "\x74\x28\xc3\x9e\x9b\x62\xb8\xd9\x21\x93\x43\x40\x04\x6a\xaa\xac"
-  "\x06\xdc\xdc\x14\xe2\x06\xeb\x56\x16\x3b\x91\x04\x3b\xf8\x37\xc0"
-  "\x42\x73\x7e\x31\xe7\x94\xc3\xf8\x29\x00\xfe\xdc\x6c\x81\x9f\x82"
-  "\x1b\xce\xe1\xa7\x15\xf0\x53\x90\x09\xf8\x39\x8d\xa8\x7c\xa3\x33"
-  "\xf8\xf9\x98\x5d\xff\x8b\xc7\xf9\xc8\x7c\xa0\x3d\xc3\xb1\x9f\xb5"
-  "\xf4\x9e\xe0\xa9\x01\x2e\xc8\x41\x5c\x15\xb5\x81\xab\x5a\x82\xab"
-  "\x7d\xb3\xe5\xe3\xea\x70\x38\xe0\xaa\xc8\x36\xae\xee\x48\xe1\xaa"
-  "\xc8\x1a\x57\x7b\x27\x74\x2e\xae\xd8\xbd\x39\xff\x0f\xe0\x6a\x9f"
-  "\x4a\x88\xab\xdf\x6f\x24\xb8\xfa\xfd\x06\xc7\x71\x15\xd4\x46\xbc"
-  "\x0a\xe2\xe2\xd5\xff\x1e\x75\x00\x57\x05\x0c\xe4\x6f\x1b\x57\xd7"
-  "\x25\x70\x15\x24\x12\xaf\x3e\xd9\xdd\xb9\xb8\x62\xf7\x0e\xfd\x3f"
-  "\x80\xab\xff\x5d\x2b\xc4\xd5\xbe\x1f\x08\xae\xf6\x69\x9d\xc0\x55"
-  "\x1b\xf1\x2a\x88\x8b\x57\x07\xbd\x1c\xc0\x55\x03\xe0\xaa\x8d\x78"
-  "\x75\x51\x0a\x57\x22\xf1\x6a\x7f\x73\xe7\xe2\x8a\xdd\xdb\xf4\xff"
-  "\x00\xae\x0e\x5c\x10\xe2\x6a\xff\x28\x82\xab\xfd\x21\x8e\xe3\x4a"
-  "\xd5\x46\xbc\x52\x71\xf1\xaa\x64\xbe\x7c\x5c\x1d\x99\xc8\x40\xfe"
-  "\xb6\x71\x75\x5c\x02\x57\x2a\x91\x78\xf5\xe9\xe4\xce\xc5\x15\xbb"
-  "\xf7\xea\xff\x01\x5c\x95\x8c\x10\xe2\xea\x60\x0e\xc1\xd5\x41\xb5"
-  "\x13\xb8\x6a\x23\x5e\xa9\xb8\x78\xf5\xd9\x57\x0e\xe0\xaa\x18\x70"
-  "\xd5\x46\xbc\x5a\x23\x85\x2b\x91\x78\x75\x68\x5f\xe7\xe2\x8a\xdd"
-  "\x1b\xf6\xff\x00\xae\x3e\xcb\x12\xe2\xaa\xe4\x2a\xc1\x55\x49\x9d"
-  "\x5d\xb8\x6a\x32\xc3\xd5\x85\x1e\x11\x2d\x69\x44\x0f\xee\x9b\xcb"
-  "\xe1\xea\xe3\xfe\xb1\xab\x96\x21\xea\xc0\xf4\x7c\x0b\x2d\x78\xa4"
-  "\x8f\x25\xa6\x00\x17\x2c\xa6\xf4\x6f\x03\xa6\xae\x11\x4c\xa5\x5e"
-  "\x04\x4c\x7d\x97\x4f\x55\xa5\x5c\xc7\x38\x61\x31\x54\x30\x17\x30"
-  "\x84\x75\xa1\x8b\xc2\x5b\x8e\x06\x7c\xff\x9a\x09\x4b\x9f\xdf\x69"
-  "\x17\x2c\x4d\x01\x2c\x9d\xb5\xc4\xd2\x09\x1e\x4b\x93\x25\x34\xe0"
-  "\x4c\x09\x2c\x69\xdb\xc6\xd2\x0e\x3c\x86\xb0\xa8\x83\xb0\x74\x86"
-  "\x1f\x43\xd8\x3f\x47\x47\xe9\x7d\xe4\x62\xe9\x70\x8d\x10\x4b\x9f"
-  "\x8f\x26\x58\xfa\x3c\xd4\x71\x2c\x05\x15\x49\x63\xc9\xc4\xa7\xfe"
-  "\x38\xcd\x39\x2c\x01\xb7\x12\x60\xa9\x6d\x1e\xc5\x63\xe9\x0f\x63"
-  "\x3a\x17\x4b\x16\x3c\xea\x81\xc5\xd2\x1f\xfd\x85\x58\x3a\xc2\xe9"
-  "\xbe\x23\x92\xba\xcf\x08\x7d\x17\xfe\xcd\x09\xaf\xb3\x35\xdc\x8e"
-  "\x79\xd9\x00\x7d\x1a\x5e\x6f\x8b\x7f\xa7\xf8\x74\x61\x35\x85\xf1"
-  "\x94\x7d\x0b\xf9\x67\x2d\x41\xa1\x1e\x4d\x04\x2b\x7a\xc0\xca\x86"
-  "\x5b\x48\xd1\xda\x0a\x38\x69\x41\x8a\x66\xb0\x77\x73\x6b\x82\x47"
-  "\x45\x6c\x1d\xfa\xf2\x46\x35\xf4\x65\xa5\x68\x17\x3c\xd3\xca\x8d"
-  "\x43\x1a\x57\xc5\xb8\x6f\x5c\x89\xc7\x21\x4f\x23\xcd\xf4\xed\xe0"
-  "\xff\x52\xa7\xfd\xdf\xfc\xae\x94\xff\x8f\x0b\x7c\x5f\x60\xe6\x77"
-  "\xe5\xff\x73\x7c\x1c\x92\xfd\x9d\x6a\x21\xf1\xbd\xc9\xef\xdb\xda"
-  "\xc1\xef\xdb\x38\xbf\x3b\xd7\x1f\x1d\x95\x9e\xff\x68\x16\x2b\xd8"
-  "\x39\x05\x4d\x24\x46\x98\xe2\x02\x8e\x11\x98\xbf\x34\x7b\x07\xfa"
-  "\x5b\xf6\x37\x38\x3e\xdc\xa0\xbf\xd8\x88\xfb\x26\x49\x1e\xc3\xc5"
-  "\x89\xb4\x77\x48\x9c\xe0\x78\x8c\xbe\x7d\xc7\x1f\xff\xb4\xb8\xe3"
-  "\xe2\xc5\xf1\xb6\xfb\x1e\x27\x78\x0c\xc6\x4d\x81\x05\x6e\x3a\x22"
-  "\x5e\x38\x86\x9b\x2f\xa6\x08\xe3\xc5\xd1\x43\x24\x5e\x1c\x2d\xb1"
-  "\xa7\xef\x69\x03\x4f\xc5\x66\x78\xaa\xe5\xf1\x74\xfc\x3c\x1e\xa3"
-  "\x94\x87\xa7\x3f\x44\xb7\xef\xb8\xe3\xb1\xaf\x3a\x17\x4f\xed\x37"
-  "\xee\xd8\xb5\xf1\x74\xbc\x58\x88\xa7\x63\x2e\x04\x4f\xc7\x90\xf3"
-  "\x78\x0a\x32\x8b\x4f\x41\x66\xf1\x49\x33\x04\x8f\x4d\xca\xc4\x53"
-  "\x71\xfb\x8e\x37\x7e\xe9\xd5\xb9\x78\x6a\xbf\xf1\xc6\xae\x8d\xa7"
-  "\x2f\x1b\x84\x78\xfa\xf3\x64\x82\xa7\x3f\x47\xb7\x03\x9e\x8a\x2d"
-  "\x39\x31\xc1\xd3\x5f\xde\xc1\xfc\x59\x26\x9e\x9a\xda\x77\x9c\xf1"
-  "\xab\xd9\x9d\x8b\xa7\xf6\x1b\x67\xec\xda\x78\xfa\x4b\xb8\x10\x4f"
-  "\x9a\xdd\x04\x4f\x9a\x22\xe7\xf1\xa4\x32\x8b\x4f\x2a\xb3\xf8\x54"
-  "\x76\x12\x8f\x45\xca\xc3\xd3\x1f\xdb\x79\x7c\xf1\xeb\x43\x9d\x8b"
-  "\xa7\xf6\x1b\x5f\xec\xda\x78\x2a\xcb\x15\xe2\xe9\x2f\x37\x09\x9e"
-  "\xfe\xa2\x6b\x07\x3c\x99\xc5\x27\x95\x59\x7c\xfa\x5b\x7f\x3c\x06"
-  "\x29\x13\x4f\x45\xed\x3b\xae\xf8\x57\x97\xce\xc5\x53\xfb\x8d\x2b"
-  "\x76\x6d\x3c\xfd\xb5\x56\x88\xa7\x13\x63\x08\x9e\x4e\x84\xd9\x3b"
-  "\x16\x64\x1a\x03\x32\xc7\x93\xb4\xb6\x3b\xf9\x86\xa5\xb6\x93\x37"
-  "\x06\x04\x3a\xcf\xe1\xf1\xc4\xf2\xf1\xf7\xeb\x78\x22\xc6\x90\x69"
-  "\x1c\xa8\xeb\x8d\x01\x9d\x0c\x10\x62\xe8\x6f\x9b\x09\x86\xfe\x96"
-  "\x25\x85\x21\xbd\xf9\x9c\xb4\x1f\xcd\xe6\xa4\x5d\x47\xd4\x81\x85"
-  "\x1a\xaa\x92\x9b\x93\x86\xe7\xa3\x55\xd6\xd6\xa1\x8d\x77\x91\xa7"
-  "\x7b\x02\xf2\x9c\xb4\x98\x31\x6e\xc1\x31\x64\x69\x8c\xc7\xfb\x57"
-  "\x50\x68\x2b\x60\x26\xfb\x1a\x37\x2f\x0d\x70\xf3\xcd\x85\x26\xf4"
-  "\xe7\x85\x78\x5e\x5a\x09\x2a\x84\x74\xfa\x5c\x32\x1e\x84\xe3\x08"
-  "\x3b\x27\x6d\x2e\x9e\x93\x76\x2a\x52\x74\x4e\x5a\xa6\xcc\x39\x69"
-  "\xc9\x80\x83\x06\xc0\xc1\x1d\x8c\x81\x23\x82\xb9\x68\x3b\x32\xcd"
-  "\xc6\x80\xe6\x48\x8c\x01\xd5\xd8\xf7\x9b\x44\xbb\xcf\x45\xfb\xd9"
-  "\x6c\x2e\x9a\x69\x0c\x68\x3a\xc4\x0e\xd9\x7e\xff\x46\x69\x6b\x0c"
-  "\xc8\x00\x31\x61\x12\x9e\x5b\xde\xc0\x8f\x17\xaf\x9e\x8f\xd7\xfe"
-  "\x06\x2a\xf5\x10\x2b\xf0\xfc\xf1\x83\x73\xca\xd9\xf1\xbe\xaa\x94"
-  "\x1a\xb4\xb1\x05\x79\x7a\xe8\xb8\xb8\xe0\x13\x18\xd7\x0a\xb1\xc1"
-  "\x00\xfd\x12\xf8\xba\x4f\xeb\x52\x88\x0d\xb7\x20\x36\x2c\x85\xd8"
-  "\x70\x07\x62\xc3\xa5\x72\x36\x36\x30\xeb\x3f\xaf\xc7\x7b\x6c\x17"
-  "\x5e\x43\x23\x76\x5e\x43\x21\x38\x06\x18\xf2\x46\x27\xb5\xfa\x04"
-  "\x86\xeb\x7c\x02\x23\xe0\x5e\x0c\xc1\x40\xb3\x26\x6b\x09\x62\x63"
-  "\x3d\xf6\xbd\x72\x2e\x8e\x07\x15\x53\x5b\x33\x11\x72\x06\x07\xad"
-  "\xe6\x63\x82\xe6\x38\x90\x88\x01\x4e\x63\xc1\x62\x1c\x78\x87\x93"
-  "\x31\x00\x63\x61\x87\x29\x06\x38\x85\x85\xd3\x92\xeb\x7f\xda\xc0"
-  "\x42\x91\x1d\x58\xa8\xb5\x0f\x0b\x87\xc3\xf1\xde\xd4\x22\x58\x28"
-  "\x03\x2c\x94\xc3\xbd\x1a\x82\x85\x3b\x22\x58\xa8\x9c\xdd\xf1\x58"
-  "\x10\x8e\xc9\x3c\xb8\x58\xa8\x0a\x71\x0c\x0b\x41\x76\xc4\x85\x20"
-  "\x3b\xe3\xc2\xe1\x02\xbc\xa7\xb3\x35\x16\x82\x20\x2e\x04\x41\x5c"
-  "\x08\xe2\xe2\xc2\x75\x11\x2c\x54\x2f\xe8\x78\x2c\x08\xc7\x53\x1e"
-  "\x5c\x2c\x9c\x91\xde\xff\xc2\x36\x16\xec\x88\x0b\x41\xf6\xc6\x85"
-  "\x06\xbc\x17\xb2\x08\x16\x20\x2e\x04\x41\x5c\x08\xe2\xe2\xc2\x45"
-  "\x11\x2c\x7c\xfb\x4e\xc7\x63\x41\x38\x16\xf2\xe0\x62\xe1\xef\xd1"
-  "\x8e\x61\x41\x65\x47\x5c\x50\xd9\x19\x17\x8e\x4c\xc4\x7b\x08\x5b"
-  "\x63\x41\x05\x71\x41\x05\x71\x41\xc5\xc5\x85\xe3\x22\x58\x38\xbb"
-  "\xae\xe3\xb1\x20\x1c\xc7\x78\x70\xb1\x70\x6e\x86\x83\x58\xb0\x23"
-  "\x2e\xa8\xec\x8c\x0b\x47\x8a\xf1\xde\xbb\x22\x58\x80\xb8\xa0\x82"
-  "\xb8\xa0\xe2\xe2\xc2\x1a\x11\x2c\xfc\x23\xa7\xe3\xb1\x20\x1c\x83"
-  "\x78\x70\xb1\xf0\xcf\x04\x9b\x58\x60\xac\xb1\x80\xc7\x10\xb0\x7e"
-  "\xc4\x7b\x5b\xb3\x58\x78\x4b\x43\xb5\x30\x18\x0b\xe5\x68\xd3\x4a"
-  "\x33\x2c\xe4\x11\x1d\x61\xc2\xc1\x66\x73\x1c\xe0\xf5\x4b\x18\x07"
-  "\xa0\x1f\xf4\xe0\x77\x66\xeb\x50\x25\x3b\x5f\x29\x2f\x30\x06\xeb"
-  "\x07\x3c\xce\x80\x35\x84\xb4\x7e\xa8\xc9\x6b\x17\x0c\x24\x02\x06"
-  "\xea\xc5\x75\x64\xbb\xeb\x87\x9f\x3b\x08\x03\xa0\x25\xb7\xa7\x3a"
-  "\x83\x81\xf3\x89\xf2\x31\x00\x1c\xc1\x2e\x0c\x10\x9e\x60\x1b\x03"
-  "\x41\x1a\x1e\x03\xc0\x17\xf2\x82\x6a\x30\x3f\x20\x18\x08\x2a\x97"
-  "\xe6\x07\xdf\x6d\xeb\x78\x0c\xb4\x33\x3f\xe8\xb2\x18\xf8\x57\x92"
-  "\xe4\x1a\x46\x1c\xcb\x21\xee\x4f\x1a\x32\x10\x31\x6f\xc7\xbc\x9c"
-  "\x7d\x0d\xf9\xbf\xff\x16\x0a\xc5\xfb\xc6\x1c\x68\x69\xa2\x52\x93"
-  "\x98\x1f\xf1\xda\x6a\x3d\xd4\x03\xef\x4f\xcc\xe2\xe3\x67\x5f\xd7"
-  "\xaa\x04\x1d\xda\x08\x58\x78\x1f\xea\x80\xf7\x81\x77\x4f\xea\x11"
-  "\x51\xd9\x70\x0a\xb5\xdc\x8e\x41\x15\xb1\xd7\x50\x54\x00\xd3\x5a"
-  "\x75\x41\x83\xd7\x30\x2a\x34\xcb\x4f\xe1\x75\xe2\xbd\x66\xa5\x20"
-  "\xea\x06\x7d\x61\x04\x1e\x53\x7a\x3a\x05\x79\x16\x5c\x23\xe3\x48"
-  "\x1b\x6f\x20\x74\x22\x05\x21\xe2\xf7\x0b\x39\xdd\xde\x69\x87\x31"
-  "\xa4\x19\xe0\xf7\x0b\x26\xbf\x9f\x10\x8e\x21\x51\x76\xac\x67\xb4"
-  "\x63\xec\xb0\x43\xd6\x33\xfe\x6c\xbd\x9e\xd1\xb1\xb1\xc3\x8b\x92"
-  "\xe7\x5f\xb3\xe3\xcc\x1c\x0f\x58\x95\xcc\xb6\x7b\xd6\xaf\xad\x10"
-  "\xfb\xab\x52\x4a\xd9\xf9\xd1\xb8\x9d\xe3\x36\x8f\xf1\x91\x06\xf5"
-  "\xc5\x18\xc1\x78\x98\xb4\xb7\xb5\x75\x66\x03\xa2\x8c\x3e\x81\x71"
-  "\x18\x13\xc6\x45\xbe\xae\x59\x50\xa7\xaa\xd8\x4b\xe0\xf7\x5b\xa8"
-  "\xaa\x96\xf3\xf9\xca\x4b\xe0\xcb\x7f\x2b\x99\x45\x01\xbd\x86\x35"
-  "\x20\xcf\xb4\xf3\xc8\x73\x16\x5e\x73\x0c\xfd\xc0\x0e\xe0\x04\x85"
-  "\x6f\xa1\x11\xd0\x1f\x84\xb5\x72\xb1\xc1\x68\x1a\x57\xc2\x7d\x04"
-  "\x60\xe2\xfd\x85\x80\x89\x64\xc0\xc4\x4c\x8c\x89\x7f\xef\xe9\xb6"
-  "\x4c\x64\x7c\x59\x06\x26\xd8\xf1\xe5\x38\xc0\x44\x2d\x8f\x89\x7b"
-  "\xe3\xca\x12\x7d\x82\x66\xba\x13\x73\x0b\x45\xe2\x81\xd3\xe3\xca"
-  "\x3f\x73\xe3\xca\x66\xf1\xc0\x31\x6c\x7c\x2f\xb9\xb6\xdb\x06\x36"
-  "\x8a\xda\xc6\x46\xa3\x09\x1b\xb5\x6d\x63\x43\x1b\x6a\x8d\x8d\xc3"
-  "\xe1\x66\xd8\xd0\x98\x61\x83\x8c\x33\xe5\x05\xd6\x58\x63\x43\xfb"
-  "\x55\xe7\x60\xc3\x62\xde\xcf\x03\x8b\x8d\x1f\x24\xf7\xb7\x95\xc6"
-  "\x46\x90\x1d\x71\xe3\x67\x0e\x1b\x41\x76\xc4\x8d\x4b\x31\x22\xd8"
-  "\x28\xe0\xb1\x11\x64\x16\x37\xb8\x71\xa7\xbc\x20\x91\xb8\x71\xe9"
-  "\x62\xe7\x60\xc3\x62\x0e\xcf\x03\x8b\x8d\xff\x94\x3a\x80\x0d\x3b"
-  "\xe2\xc6\xf7\x26\x6c\xd8\x11\x37\x6a\x93\x45\xb0\xd1\x60\x86\x0d"
-  "\xb3\xb8\xc1\x8d\x43\x61\xce\x69\x85\x8d\xda\xe6\xce\xc1\x86\xc5"
-  "\x7c\x9c\x07\x16\x1b\x97\x25\xcf\xbf\x96\xc6\x86\xca\x8e\xb8\xf1"
-  "\x25\x87\x0d\x95\x1d\x71\xe3\x8a\xda\x1a\x1b\x47\x26\xf2\xd8\x50"
-  "\x99\xc5\x0d\x6e\x5c\x2a\x4f\x25\x12\x37\x7e\xf4\xe9\x1c\x6c\x58"
-  "\xcc\xad\x79\x60\xb1\xf1\xa3\xce\x01\x6c\xd8\x11\x37\xd2\x4c\xd8"
-  "\xb0\x23\x6e\xd4\xed\x17\xc1\x46\xb1\x19\x36\xcc\xe2\x06\x37\x4e"
-  "\x95\xa7\x12\x89\x1b\x57\x87\x77\x0e\x36\x2c\xe6\xc9\x3c\xb0\xd8"
-  "\xb8\xe6\x66\x0f\x36\x56\x37\x88\xe8\x94\x5a\x82\x8d\x56\x48\x63"
-  "\x8e\x0b\x73\x6d\x02\xf5\x53\x44\x81\x66\xc1\x98\x78\x63\x35\xa2"
-  "\x58\x5c\x34\x98\xe3\xe2\x5a\x19\xc6\xc5\xd0\x04\xc0\xc5\x65\x0e"
-  "\x17\x26\x5d\xc2\xee\xbd\x42\xb4\x89\x69\xcc\xca\xa4\x4f\x36\x61"
-  "\xcd\x9a\x60\xc2\xc4\x4f\xe3\xbb\xcd\x6f\x07\x4c\x08\xe6\x3d\x98"
-  "\x61\x62\x9a\x84\x3e\xf9\xad\xe3\x98\xd8\x0e\xda\xb5\xb5\xbd\xd7"
-  "\x3e\x99\x30\x71\xde\x59\x4c\xd4\xdb\x9c\xff\x20\x8e\x09\x8e\x67"
-  "\x48\x62\x82\xe7\x16\x04\x13\xdf\xdb\xc0\x44\x7d\x8d\x35\x26\x38"
-  "\x5e\xc1\xee\x43\x40\xb8\x85\x69\x0c\xcb\xc4\x2f\x84\x98\xb8\x3e"
-  "\xad\x73\x30\x61\xc1\x2f\x1e\x58\x4c\xdc\x18\x21\x39\x86\x95\x89"
-  "\xa8\x9d\x99\xc6\x12\x35\x65\x2c\x85\x8f\x06\x3e\xe5\x70\xad\x1b"
-  "\x5c\x63\xcf\x3d\x84\xef\xec\x3d\x63\x2f\x76\xef\x61\x8d\x87\x4b"
-  "\x2c\xb6\x37\x4e\xd3\xdd\x94\xc6\x23\x03\x85\x15\x72\x79\xc0\xf5"
-  "\x74\xb8\xae\x71\x77\x09\xeb\x0e\xe9\xcb\x99\xec\x8f\xf0\x3b\x7a"
-  "\xe0\xb4\x4c\x86\xc2\x97\x9d\x93\x45\x51\x38\x0f\xcb\x77\xba\x72"
-  "\x69\xfc\xcc\xdf\xdb\x27\x23\x0c\xef\xe5\x67\x4a\xd3\xd3\x48\x55"
-  "\xef\xc7\xe9\x8c\x2e\x0a\xa5\x31\x13\x29\xcd\xd3\x32\x63\x11\xce"
-  "\xd7\x94\xb6\x17\x97\x9f\xbf\x79\x1a\xc3\x47\x08\xb9\xbb\x28\xd9"
-  "\x3c\xdd\x93\x28\x5c\x27\x9c\xb6\x37\xe3\x5e\x14\xcb\xa6\x77\x51"
-  "\x04\x08\xd2\xaf\x47\x6c\x5a\x2e\x9d\x1b\xd3\xbd\xb4\x96\x4b\xc7"
-  "\xce\x2d\x81\x6b\x0a\x73\xfb\x71\xe9\xfa\x98\x6c\x83\xf7\xef\x33"
-  "\xaf\xab\x21\x93\xc2\xf9\xe1\x34\xee\xc6\xee\x7f\x6c\xe0\xea\x32"
-  "\xc2\xfc\x9d\x38\x1d\x3c\x37\x9c\xb3\xb3\x07\xd4\x21\xe4\x5e\x7e"
-  "\xea\x5b\xbe\xa6\x74\x80\xc3\xfe\x85\xbc\x6d\x3c\xc1\xd6\x05\x78"
-  "\xcf\x72\x4b\xdf\xb9\xbb\xb8\x68\xb1\xef\xaa\xea\x11\xc2\x69\x19"
-  "\xf7\x8f\xa2\x21\xbd\x17\x57\x8f\x30\x52\x0f\x76\xcf\x44\xe2\x6b"
-  "\x4a\xff\xc8\x2e\xb6\xac\x2e\x4a\xae\xac\x7d\x21\x5d\xb8\x29\x5f"
-  "\x23\xc5\x62\x98\x4b\xab\x60\xd3\x56\x26\xe2\xb3\xbe\xee\xa5\x7f"
-  "\x04\xa7\x35\x64\x7f\x56\x6f\xc8\x50\x44\x58\xe6\x6f\xc8\x74\xc5"
-  "\xf7\xcd\xf3\xf7\x26\xe9\x8b\x2f\x40\xfa\x89\xd6\xe9\x3d\x2d\xd3"
-  "\xfb\x90\xf4\xbf\x1f\x01\xe9\xa3\xad\xd3\xeb\xfb\x5a\xa4\xef\x47"
-  "\xd2\xef\xcb\x82\xf4\x53\xac\xd3\x2b\x2d\xd3\xff\x82\xa4\x3f\x12"
-  "\x02\xe9\x63\xac\xd3\x87\x59\xa6\xf7\x25\xe9\xff\xb7\x16\xd2\xcf"
-  "\xb0\x4e\x9f\x6e\x99\xbe\x3f\x49\x7f\x30\x14\xd2\xc7\x5a\xa6\x2f"
-  "\x64\xd3\xa2\xc7\xb9\xb4\x03\x48\xda\x92\x5c\x48\x1b\x27\x52\x57"
-  "\x9a\xcb\x3b\x98\x4b\xff\x4b\x92\xfe\xa3\x06\x48\x9f\x60\x9d\x5e"
-  "\x61\x99\xde\x8f\xa4\xff\x5b\x38\xa4\x4f\x14\xf1\x95\x65\xfa\x47"
-  "\x49\xfa\xa3\x71\x90\x3e\x49\xc4\x57\x96\xe9\x07\x92\xf4\x5f\x1c"
-  "\x86\xf4\xc9\x22\xb6\xb7\x4c\xff\x18\x49\xff\x67\x05\xa4\x4f\x11"
-  "\xb1\xbd\x30\x7d\xb6\x66\x0a\xa4\x5b\xbd\x8b\xc3\xa6\x85\xdd\x2d"
-  "\xf3\x1e\x44\xf2\xfe\x4b\x31\x3c\x93\x6e\x9d\x1e\xb9\x90\xf4\xe8"
-  "\x19\x2e\xfd\xe3\x24\x7d\x19\xb6\xe5\x5a\x11\xdb\x3f\x81\xd3\x17"
-  "\x92\xb4\x4f\x90\xb4\x7f\x5c\x0b\x69\x37\x88\xd8\xdd\x3c\xad\x3f"
-  "\x49\xfb\xcf\x12\x48\x9b\x25\x62\x73\xf3\xb4\x83\x49\xda\x6f\x12"
-  "\x20\xad\x5a\xc4\xde\xe6\x69\x9f\x24\x69\x4f\x27\x43\xda\x5c\x91"
-  "\xf2\x3e\x6e\x96\xf6\x29\x92\xb6\x2a\x1d\xd2\xe6\x8b\xf8\xc5\x3c"
-  "\x6d\x00\x49\x7b\x1e\xfb\xb0\x40\xc4\x27\xe6\x69\x87\x90\xb4\x67"
-  "\x70\x5b\x2b\x12\xf1\x89\x79\xda\x40\x26\xfb\xef\xf9\x5c\x9c\x2e"
-  "\xb6\x4c\xbb\x8b\x8f\xbb\x41\x46\xf7\x73\xc5\x5c\xac\x64\xcf\x28"
-  "\x62\x20\x1d\xdf\xe7\xe8\x9f\x35\xf5\x11\x46\x0a\xa9\x98\xec\x93"
-  "\x1b\xe0\x39\x9c\xe7\x7e\xeb\xd8\xa6\x78\x76\x17\xdf\x47\x0c\x65"
-  "\xb2\xaf\x4d\xe1\xde\x5f\x62\x9d\xd6\xd5\x3c\xed\x30\x26\xfb\xe2"
-  "\x7e\x2e\xed\x61\xeb\xb4\x9e\xe6\x69\x9f\x66\xb2\xbf\x2f\xe7\xd2"
-  "\x96\x8a\xc4\xd7\x67\xcc\xd2\x06\x33\xd9\x3f\xd4\x42\xba\x63\x62"
-  "\xf1\x95\xc9\x54\x3e\x83\xe3\x81\x29\x76\x43\xfa\xe1\xc4\xbe\xf5"
-  "\x18\x0f\x1a\x9c\xde\x94\x16\xfc\xf0\x8c\x59\x5f\xf9\x8c\xd1\xbd"
-  "\x16\x71\x36\x2b\xb3\x2e\x43\xba\x79\x19\x9e\x25\x79\x5e\xf1\x83"
-  "\x3c\xcb\x2d\xcb\xc0\xc5\x23\xcc\x13\xb0\x7d\x47\x18\xb2\xeb\x42"
-  "\xb0\x7d\x21\x6d\x85\x80\x23\x50\x2e\x34\xce\x93\xf3\xed\x48\x26"
-  "\xfb\x5f\xa5\x9c\x0d\x04\xfd\x11\xb4\x47\x36\x1e\x82\x7f\xcb\x99"
-  "\xf5\x3d\x03\x20\xed\x73\x5c\xba\xb3\x96\xfd\x20\x57\xbe\x5f\xc1"
-  "\xbd\x9a\x7b\x7d\xa0\x8b\xe2\x82\x18\x97\x49\x0a\x44\xbd\xaf\xd1"
-  "\x8d\x6c\x1b\xe1\xcf\xf1\x6d\x66\x63\xa0\xb1\x78\x00\x8a\x6a\x60"
-  "\xf4\xe6\xd7\xb6\x50\x4c\xf5\xd3\x0d\x48\x81\xf7\xe9\x66\x7c\xc6"
-  "\xed\xd5\xc2\x75\xdd\xe0\x01\xd5\x8d\xd9\x8d\x05\x5a\x97\xcf\xfd"
-  "\xf1\x5e\xae\xf0\xff\x5e\x2d\x8a\x2b\xc0\xff\x6f\xc9\x64\x9a\xf0"
-  "\xfe\xc9\x86\x0f\x6e\x6a\xab\x8c\xf5\x80\x3f\xa6\x09\xf2\x68\x02"
-  "\xce\x48\xe3\x33\xac\xf1\x39\x12\x55\x29\xf5\xe8\x0a\xdd\x78\x9d"
-  "\x59\x94\x10\x0a\x65\x08\x86\xf7\xc5\x5d\x82\xef\xc4\xa6\xc0\xa9"
-  "\xd5\x37\xf5\x9a\x25\x78\x1f\xeb\xa6\x91\x3a\x9f\xc8\x60\xe6\xdd"
-  "\xd7\xeb\x92\x52\xd1\x63\xd7\xe8\x26\x96\x03\xe0\x3d\x6c\x8d\x5e"
-  "\x37\xf5\xec\xde\xb5\x3f\x27\xfc\x9a\xec\x5b\xdb\x3c\x0a\xef\x57"
-  "\x8b\xf7\xad\xbd\xb7\x67\x6d\x51\x4c\x35\xd9\x07\xb7\x69\x23\x5b"
-  "\x97\x4c\xa6\x9a\xf1\xef\x5f\x67\x6c\x59\x9b\x8e\xcf\x9b\xd6\xa4"
-  "\x5e\x43\x97\xb8\x7b\x38\x4f\x2e\x9f\x9e\x96\xf9\xe0\xe7\x74\x83"
-  "\x62\xaa\x99\x3d\xfd\xeb\x0c\x6a\xff\xb3\x46\x4f\xff\x6a\x46\x3d"
-  "\xac\xba\x2a\x51\x8b\xc8\x99\x8c\xcd\xf3\x19\xf7\x69\x55\x46\xb5"
-  "\x7f\x29\x5c\xd7\x54\x35\xb4\xb0\xd7\x21\xef\xb3\x98\xf7\xde\xf6"
-  "\x0c\xda\xc0\xa8\x83\xb2\x34\x03\xf0\xd9\xad\x4d\x5a\xfc\x3e\x7c"
-  "\x9d\xc9\x19\x56\x8d\xed\x69\xcc\x19\xa6\xa1\x7d\x91\xe2\xb6\x57"
-  "\xd0\x86\xc6\xec\xa6\x06\xd3\x79\x74\xa6\x77\xe1\x7c\xb5\x5c\x5e"
-  "\xf6\xef\xb9\xdb\xb4\x1a\xef\xb9\x2b\x23\xfd\x08\x9c\x5e\xfc\x0c"
-  "\x12\xe0\x57\x39\xb7\x7c\x1b\xb3\x9b\xd5\xc0\x93\x93\x89\xcf\x9b"
-  "\x0b\xb4\xa8\x61\x22\xf7\x3f\xf8\xbf\x91\xc3\x42\x33\x3e\xff\xf4"
-  "\x30\xf7\xbf\xc6\xb4\xc7\xb1\x68\xbe\x9e\x37\xeb\x81\xab\x29\x8c"
-  "\x3b\x62\x5c\x31\xc7\x27\x67\x34\xdc\xac\x57\x0e\xc4\x67\xd7\xb4"
-  "\x84\xc3\x3b\x15\xc4\x27\x2d\x8f\xc2\x5f\x0f\xee\xaf\x8e\xfb\xcb"
-  "\xe0\x34\x2c\x8e\xbd\xc3\xeb\xc0\xee\xe5\xc4\x17\x2d\x23\x59\x6d"
-  "\x83\x71\x03\xd8\x62\xbc\x86\x95\xb3\xf9\xe6\x45\x06\x9b\x97\x21"
-  "\x78\xf8\x33\xcf\x8e\x18\xf9\xdc\xaf\x42\x46\xcd\x9e\xf3\x66\x5c"
-  "\xfc\xdc\x79\x09\xf3\xdf\x7a\x3b\x71\xc1\xc2\x45\x49\x8b\x97\x2c"
-  "\x4d\x5e\xb6\x7c\x45\xca\x3b\x2b\x21\x9f\x7b\xe7\x5e\x33\x3b\xc2"
-  "\x5d\x1a\x28\x04\x7e\x1d\x8b\xdf\xb1\x87\x7d\x2f\x5c\x23\xf8\x6a"
-  "\xc9\x55\x28\xc5\xb5\x43\x15\xb0\x79\x7c\xc6\x61\x3d\xdd\x72\x13"
-  "\x9f\xb7\x08\xf8\x76\xa9\x2a\x78\x59\x83\xcf\x6a\xae\xa5\x5b\x6a"
-  "\x2b\x75\x2f\x6b\xf0\xd9\xe2\x5f\xfb\xd6\x21\xff\xc7\xf1\x79\xce"
-  "\x2d\xd5\xf8\x7e\xe1\x93\x08\x95\xc1\xb3\x62\x79\x3e\xee\x89\x7c"
-  "\x3f\xec\xc7\xe8\x72\xfb\x31\xf5\x38\xff\xdc\xad\x4c\x9d\x6e\x55"
-  "\x02\xca\x86\xef\xd0\xc6\x3c\xaf\xd0\xad\x7b\xbe\xf6\x63\xcf\x68"
-  "\xf5\xdb\xb5\x95\xa9\x5d\xdb\x8f\xa9\x7d\x77\x2b\x53\x5f\xd8\x8f"
-  "\xd1\xfa\xe7\x22\xb7\xc6\xec\xd6\x18\x2d\xdd\x52\xc2\xb6\x57\xb8"
-  "\x6f\x74\x6f\x89\xde\x02\xf7\x9e\xd6\x23\xba\x10\xbe\xc3\xb5\x86"
-  "\xaf\x95\xa4\xdc\x9f\xde\x6a\xea\x06\xf9\x85\x32\xad\x89\x2e\xd9"
-  "\xf0\x1e\xe2\x8f\xd6\x93\x65\xc0\x3a\xe0\x7d\xba\xaa\xa6\x4b\x48"
-  "\x4b\xb7\x96\x17\xde\x65\xdf\xe7\x51\x95\x5f\x8f\x70\x7e\x07\x97"
-  "\x34\x75\x5b\x3a\x80\xd1\x43\xda\xbd\xc6\x55\x89\x2e\x90\x66\x2d"
-  "\xe4\xdd\x60\x5e\x9f\x80\xb9\x0b\x92\x95\x0b\x97\x25\x26\x0e\xe9"
-  "\x85\x02\xd8\xbf\xc8\xfc\x9c\xf1\x64\xbc\xb7\xfa\x87\x5b\x99\x32"
-  "\xa8\xa7\x06\xea\x5b\x7e\x1a\x54\x0a\x60\x03\x41\x9d\xd4\x57\x68"
-  "\xfd\xa3\x70\xfd\x18\xfc\x7f\x0c\xca\x5e\xce\x9e\x61\xac\xe8\x33"
-  "\x81\xc9\x6e\x3d\x0b\xe5\xc4\x7b\x82\x2b\xf1\x5e\xec\xb7\x57\x4c"
-  "\x71\x81\x7a\xe7\x42\xba\x72\xe5\x00\x34\x18\x9e\xdb\x03\xe5\x28"
-  "\x86\xff\x71\xfa\xc9\xd8\x8f\x90\xbe\x8c\xad\x97\xa2\xcf\x28\xfc"
-  "\x1d\x6c\xa5\xd9\xd9\x8f\xc9\x6a\xcc\xd6\xa7\xe3\x33\x26\xd8\x33"
-  "\x33\xe1\x3b\xd8\xa5\x1c\xd2\xaa\x6f\xa7\x4d\x71\x01\xad\xeb\x52"
-  "\xc8\xe7\x19\x8d\xcb\x84\xcb\x81\xf5\xf3\x37\xc0\x40\x8d\xad\x31"
-  "\x68\x68\x13\x72\xf9\xa6\x16\xa1\x82\xad\x4c\x11\x7c\x0a\xe0\x93"
-  "\x7f\x0a\xee\x9d\x84\x4f\x39\x5c\xaf\x80\xbf\xa7\xe0\xef\x49\xf8"
-  "\x80\xfe\xf6\xc5\xe5\x5e\xba\x9a\xa9\x7b\x3a\x1f\x3d\x81\xf3\x07"
-  "\x6c\xbd\x76\x49\xe1\x56\x84\xcb\x8e\xcf\x90\x61\xdc\x0d\xde\xc2"
-  "\x73\x2f\x8c\x1b\x10\xdc\x87\xbf\x05\xec\x5f\xf3\x0f\x6d\xac\x45"
-  "\x34\xa3\x20\xff\x33\x13\xe1\x7b\x32\xf7\x7f\x2c\x7c\x12\xdb\xfc"
-  "\x58\xe6\x27\xf5\xa1\x99\x1a\xbb\xd3\xda\xf5\xe9\xe3\x6d\x5f\x3a"
-  "\x17\x35\x52\xd0\x75\x48\x01\x2d\x4f\x70\x9d\x6e\x22\xd7\x5c\xcb"
-  "\xc8\x77\xd7\x6a\xee\xaf\x1e\x29\x7a\x82\x9d\x7a\x41\xfe\xbd\x42"
-  "\xc8\xb5\x5e\xe1\xf0\x37\x0b\x3e\xf9\xc2\xf7\xf7\x81\xe7\xfb\xa8"
-  "\xb0\x3f\x5b\xa1\x8f\xc1\xbe\xd4\xd2\xfa\x5a\xec\xa3\x2d\x04\x5b"
-  "\x2e\x78\x1d\x1d\x5c\xd3\x02\xb6\x0a\xee\xe1\x87\x36\x9e\x13\xe2"
-  "\xc7\xa8\xb1\xc0\x8f\x1a\xc7\x22\x78\x4e\x55\x48\xf0\x72\xec\xf6"
-  "\xaa\x38\xf8\x6e\x2c\x83\x7c\x8e\xe1\x71\x9d\x2b\x34\xc3\xce\xc1"
-  "\xdf\x72\x0d\xa1\x3e\x09\x48\x81\xe3\x4b\x3d\xcd\xf8\x60\xcc\xe2"
-  "\x77\x73\xef\x25\x65\x81\xf2\xc1\xb5\x22\x5c\xbe\x45\x90\x2f\x7c"
-  "\x2f\x86\x74\x45\x55\xe8\x96\xa9\x6c\xec\x33\x9b\xde\x02\x3c\x72"
-  "\xe5\xc5\x79\xe2\xe7\x18\xbe\x5e\x5a\xfc\x0c\xf7\xee\x93\x70\x3d"
-  "\x18\x62\x14\x5e\x23\x47\x57\xe9\xb5\x08\x63\x12\xff\xad\xd2\x07"
-  "\x43\x5b\x8a\x40\x46\xbc\x2f\xbc\x2f\x0a\x86\xf6\xd6\xf3\x12\xcd"
-  "\xec\x1f\xb6\x1a\x05\xe3\xfc\x70\xfc\xd6\xd2\x4c\x52\x21\x6e\x8b"
-  "\x24\xaf\xaf\x70\x3d\x70\xfe\xa7\x92\x10\xfb\x9e\x5d\xb8\x3c\x70"
-  "\xdf\xec\xbd\xb9\x55\xc0\x32\xb6\xac\x24\x75\x85\x77\x15\xc3\xf3"
-  "\x25\xb8\xee\xd8\x9e\x70\xbf\xf4\x8a\x02\xb9\xe2\x7b\xf8\x1c\x49"
-  "\xae\x3e\xc5\x78\x6d\x22\xb6\x07\x4e\x5f\x05\x8a\x83\x9c\x79\xa1"
-  "\x1f\xca\xda\x0d\x9e\xc7\xfe\x60\xe0\x1d\x38\x8f\x34\x3d\xa3\x67"
-  "\x20\x1e\xfd\xcf\xca\x26\xc5\x15\x85\x4b\x86\xc0\x3f\x1f\xa0\x58"
-  "\x73\xff\xc0\x73\x25\xf0\x7c\x19\xee\xfb\x71\x3c\x81\x77\x7a\xe0"
-  "\x33\xa1\xe1\x9a\xda\x98\x0d\x79\x2c\x6f\x62\xc7\xa2\x20\x9f\xc5"
-  "\x50\x16\x35\xce\x07\xca\x53\xc6\xe5\xb5\x1f\xef\x8f\x6f\xee\x6b"
-  "\x2e\xbf\x62\xec\x73\xb6\x3d\xaf\x64\xeb\xa4\x86\xe7\xc7\xec\x22"
-  "\xf7\x4a\x21\x4d\x29\xd3\x1a\x81\x98\x55\x31\xe4\xec\x69\x72\xef"
-  "\x70\x5a\x33\xeb\xdf\x32\x12\xd7\x5c\x66\x2f\x5d\xc3\xd4\xf1\xe5"
-  "\x76\xf1\x35\x9d\x1f\xc5\x95\xfb\x30\x7e\x1f\xb3\x62\x06\xdb\x87"
-  "\xe2\x77\xe0\xe7\x49\x7e\xa8\x01\xe7\x67\xb2\xd5\x30\x28\x07\x6b"
-  "\x2f\x05\x0a\x80\xeb\xc5\x18\x8b\xac\xdd\x20\x8e\xde\x4e\x03\x2c"
-  "\x2a\x5c\xfc\xe0\xf9\x63\xd9\xf8\xfb\x0a\xfc\x1d\x95\xb0\x31\xf6"
-  "\xde\x7d\x14\x87\xef\x57\xd5\x81\xdf\xde\x06\x2c\x19\x11\x7a\xc2"
-  "\x1b\x05\x37\x64\xb2\x75\xdb\xdf\xb0\x2a\xdc\xe5\x6b\x3d\x42\xb8"
-  "\x9c\x60\xa3\x52\x28\x6b\x19\xc4\x7e\x96\x03\x40\xbc\x3e\xcc\xfc"
-  "\x4f\x0c\xc2\x65\x86\x78\xc6\x95\x8f\x1a\xc9\xf9\xfe\x30\xae\x23"
-  "\xb6\xe7\x30\x12\xfb\xe0\x1e\x7d\x1e\x97\x9d\xaf\x37\xe5\x69\x6e"
-  "\x63\xb6\xde\xe0\x07\xec\x2f\xec\x17\x3e\x4f\x17\x8c\x7d\x35\xe4"
-  "\xb5\x9f\xf4\xcf\x04\x1b\xd8\xd6\xea\x7e\x4c\x05\x4e\xcf\xa7\xa5"
-  "\x27\xe0\x7b\xa9\xf0\xee\xa7\x93\xb0\x66\x82\xfe\x59\xdf\xa8\x81"
-  "\x7c\xf7\x6b\x56\xea\x11\xe4\x51\x8a\x6d\x0a\xe9\x76\x62\x3c\xc2"
-  "\xf7\x0a\xae\xdc\x05\xd0\x9f\xab\xe0\x13\xca\xf7\x1f\xf4\x66\x21"
-  "\xbe\x28\xcb\xf6\x8f\xfd\xad\x36\xa6\x45\x20\x16\x0f\x4b\x90\xf2"
-  "\x86\x82\x1e\xc2\xf5\x1d\x9c\xaf\xe9\x35\x5f\x43\x7b\xe1\xf3\xa0"
-  "\x15\x16\xbe\x2e\x65\xf1\xb8\x62\xa2\x0b\xae\x33\x3c\x5b\x4a\xf2"
-  "\xa1\xd8\x3a\xb3\x78\xca\x64\x31\x50\xc1\xac\x80\x7a\xde\xc3\x01"
-  "\x15\xcb\xf9\xb9\xc2\xc2\x26\xa6\xd8\xb5\x1f\x9f\x47\x8c\x63\x12"
-  "\xf0\xea\x5f\x37\xb6\xf2\x71\x09\xfb\xde\xc8\xfa\x9e\x76\x2d\x24"
-  "\xfd\x2d\x89\x5b\x0a\x8a\xdc\xef\x27\xc0\x30\xae\xd3\x68\x16\xbf"
-  "\xb8\x2c\x69\x33\x70\x59\x4a\xd9\x72\xa4\x29\x11\xdc\x3b\x8c\xdf"
-  "\x0f\x79\x85\x71\xed\xd5\x94\x97\x37\xce\xeb\x5d\x88\x55\xb8\x4c"
-  "\xf0\xee\x22\x36\xfe\xbd\x84\xcb\xae\xf0\xe1\xca\x5e\xde\x94\x89"
-  "\x63\x09\xe3\xda\x4c\xb1\xcf\x96\x43\xba\xd5\x4d\xe4\x3c\xb7\x5e"
-  "\xf0\xfc\x5e\x76\x8e\xa5\xc2\x35\x19\xc7\x68\xbc\x76\x18\xfe\x7f"
-  "\x43\xf9\x5b\xc0\xea\x35\x88\xe8\x09\x08\x97\x7f\xbf\x09\x17\xf5"
-  "\x8a\xff\xcf\xde\xdb\x80\x37\x59\x65\x8b\xc2\x2b\x69\x4a\x03\x16"
-  "\x92\x96\xaa\x19\x04\x0d\x5a\x3d\x45\x0b\x84\x1f\xb5\x32\xa0\x81"
-  "\x16\x6d\xb5\xa5\x15\xaa\x56\x41\x5b\xa4\xd5\x56\xb1\x84\xb6\x40"
-  "\xc0\xd2\x84\x50\xe7\xe0\x88\x34\xad\x15\xab\x96\xb6\x8e\x38\xc3"
-  "\x0c\x38\xd6\x73\x38\xe7\x70\xef\x83\x63\x1c\x3a\xf7\x32\xe7\xb4"
-  "\x4d\xe7\x5c\xce\xb9\x3d\x7e\x78\x27\xf2\x75\x98\xca\x29\x10\x69"
-  "\xa0\xa1\x4d\xb2\xef\x5a\x7b\xbf\x6f\xf3\xd3\x04\xf5\x1e\xef\x9c"
-  "\xe7\xf9\x3e\xab\xe1\x7d\xdf\xfd\xb3\xf6\xda\x6b\xaf\xbd\xd6\xda"
-  "\x7f\x6b\xab\xf3\x68\xac\x82\xb4\x3e\x82\x36\xd2\x21\xa2\x37\xf1"
-  "\x32\xda\x48\x8b\x47\x9a\x54\xb5\x32\xdf\x62\x39\xad\x44\x7b\xd1"
-  "\x3e\xaa\xcf\x90\x8f\x8f\x8d\xf3\x16\x7e\x4b\x74\x3c\x84\x74\x54"
-  "\x63\x79\xcb\xa5\x7a\x1d\xc2\xf4\x5a\xfc\x5e\x20\xe1\xde\x22\xa5"
-  "\xff\x42\x6e\x07\xa9\xaf\x76\xef\x23\xf9\xcb\xf9\x27\xbe\x46\xca"
-  "\x7b\x50\x94\x15\xbf\x45\x4e\x4b\x36\x22\xbf\x9b\x19\xc3\x48\x0e"
-  "\xce\xc7\xb6\xe7\xb2\x6f\xc7\x28\x4f\x27\xc9\xc6\x2e\x51\x86\x7a"
-  "\x16\xe7\x43\xb4\x7b\x82\x7c\x14\x9f\x1b\x21\x9f\x48\x16\xdb\x7b"
-  "\xeb\xc5\xdd\x77\xc4\x4b\x24\x53\x69\x4c\x84\xf0\x52\xa5\xfe\x23"
-  "\xe1\x1c\xff\x5f\xc2\xed\x24\xf5\x64\xe4\x95\xb9\x21\xb0\x0f\x45"
-  "\xd3\x73\xed\x42\x06\xb6\x4a\x75\xbb\x2a\xd5\xed\x88\x54\xb7\xab"
-  "\x52\xdd\x0e\x61\x19\x48\xb7\x84\x4f\x42\xe8\x88\x74\x4b\x98\x23"
-  "\xa5\x3f\x46\xb2\x3c\xd8\x5f\x27\x95\xc9\x7d\x79\xa2\xbc\x48\xf8"
-  "\x11\xf5\x87\x20\x5e\x93\x8c\x11\xf2\xe2\x58\x74\x79\x31\x49\x2b"
-  "\xd5\xb7\x23\xa2\x6f\x1c\x14\x7d\x43\xd2\x2d\xd8\x0e\xbd\x1e\xf9"
-  "\x0e\x42\xdf\x5c\x92\x9f\x54\x76\xa8\x0e\x6a\x13\x74\x95\xfa\x72"
-  "\x42\xfc\xc4\x76\x98\x74\x2a\xb4\x3f\x53\x5b\x93\x4c\x20\x18\xd4"
-  "\xa6\xdc\xae\xc4\x30\xd1\xae\x93\x8e\x90\x6c\x08\x95\xd1\x98\xb6"
-  "\x39\xc0\xa8\xbf\x4c\xea\x0f\xef\x8b\x93\xb2\xa4\xbe\x28\x97\xfd"
-  "\x4b\x6c\x23\x43\xb0\xdc\x84\xdc\x88\x72\xa9\x6d\xba\xf8\x5d\x31"
-  "\xbc\x7d\x12\xde\x94\x75\x1a\xa5\xc7\xbc\x66\xcc\x63\x8d\xd0\x8f"
-  "\x76\xc2\xcf\xa5\x8a\xf7\x72\x99\xb5\x9f\xcb\x0a\xf3\x08\xc7\x27"
-  "\xa1\xbe\x5d\xd2\x13\x18\x66\x90\xc2\x0a\x24\x5d\x22\xf1\x4d\xc2"
-  "\xe5\x08\x9c\x5c\x51\xed\x23\x84\x2f\xdb\x47\x1c\xd6\x18\x87\x35"
-  "\x20\xd5\x8f\xc2\xe6\x8a\xb0\xf8\x23\x14\xb6\x4f\xd0\xa1\x99\x71"
-  "\x7d\x15\x5f\x20\xe9\x2b\xea\x5f\x4a\x97\x4a\xe5\xa0\x3e\x46\xdf"
-  "\x2e\x95\x3a\x83\xe0\x3b\xad\xa3\x34\x86\x68\xc1\xb8\x75\x24\x0f"
-  "\x48\x5e\xd0\xde\x60\xfe\x5c\xc5\x9f\xaf\x90\xdc\x21\x3b\x84\xe2"
-  "\x31\x5d\x2e\xc9\x22\x0c\x7f\x9b\xfc\x02\xb2\x7f\x57\x23\x5c\x75"
-  "\xad\x94\xf7\x43\x6e\x2b\xfc\x7b\x76\x9c\x1c\x26\xe7\xc3\xbe\xfe"
-  "\x34\xe5\xa3\xfc\xb2\xfc\x22\xd9\xe5\x23\xd9\x24\xca\xfb\x5a\xe2"
-  "\x71\x3e\x6e\x90\xed\xa2\x31\x65\x48\x5a\xba\x4b\x8d\xcb\xb4\xc9"
-  "\x4b\x85\x3c\x9b\x3c\x97\xf2\xf2\xf6\x43\x59\x59\x77\x95\x7d\xd9"
-  "\x5e\x05\xaa\xb6\x4b\xdc\xc6\x4a\x17\x78\x4e\xde\x23\xea\x31\xf9"
-  "\x51\x5e\x0f\x21\x53\xed\x1c\x17\x4c\xd3\x36\xca\xe3\x5e\xa2\xba"
-  "\x50\x5c\x43\x48\x1c\xdd\x8d\x88\x71\x62\xbe\x24\x22\x5f\x60\xac"
-  "\x7c\x42\xfa\xf6\x51\x3e\xee\x53\xb7\xed\x97\x65\xef\x14\xb5\x84"
-  "\xe7\xef\x64\xb9\x8b\x74\x29\x24\xd9\xcb\xe3\x9e\x93\xd2\xac\x92"
-  "\x9e\x5c\xbe\x4f\xbe\x2c\xe8\xaa\x53\x4a\xf4\x5e\x27\xea\x31\x65"
-  "\x32\x1f\x67\xff\x7b\x11\xd2\x76\xf2\x90\x4c\xdb\xd0\x77\xea\x3f"
-  "\x58\xbe\x96\xbe\x39\xdf\xd7\xf2\x31\x6c\x2b\xa5\x21\x9c\xb8\x8e"
-  "\x50\xa9\x07\x22\x6d\xea\xb3\xaa\xc4\x5d\xa4\x97\xb8\xad\xaa\x4a"
-  "\x5c\x2f\xcd\x3d\x81\xa3\xea\x67\xa8\x17\xa6\x1c\x91\x65\x0c\x1b"
-  "\xc9\x06\xba\x63\x09\x71\xf9\x90\xc2\xe8\x7e\xac\xd0\x34\x24\x9f"
-  "\x3e\x1a\x75\x49\x30\xa7\xec\x91\xe5\x06\xc9\x92\x5e\xcf\x19\xc9"
-  "\xa6\xbb\x2e\xa3\x4d\x92\x25\x17\x54\xd7\xdd\x17\x6e\x87\x5d\x77"
-  "\x5f\xb8\xcc\x48\xcc\x8b\x94\x19\x68\x37\xd7\x8f\x34\x5d\x97\x18"
-  "\x66\x07\x60\xd8\xb5\x65\xc7\x14\x17\xf5\x51\xba\x9b\x95\xcb\xa7"
-  "\x2a\x5e\xd6\x7b\x32\xce\x24\x37\x87\x5f\x96\xe6\x2f\x54\x89\xcb"
-  "\xc8\x56\x8b\x28\xaf\x36\x4c\x76\x52\x79\x32\x3c\x15\xd0\xfd\x9e"
-  "\x48\x87\x4b\x04\x33\x57\x92\xf3\x1d\x61\xb2\x52\xd2\x61\x24\x27"
-  "\xc3\x74\x15\x7e\x87\xeb\xaa\xc4\x39\x13\x65\xe4\x75\xde\x6f\xaf"
-  "\xab\xae\xeb\x23\xb9\x25\xcb\xc8\x70\x59\x70\x9d\xaf\x2d\xcc\x96"
-  "\xbd\xae\x5e\xb6\x65\x83\x72\xf4\xba\x14\x92\x51\x58\xfe\x31\x51"
-  "\x76\x62\x8d\x2b\x6e\xd4\x2c\x97\xed\xc2\x76\xee\xd5\x23\x6f\xee"
-  "\x1b\x73\xe1\x7b\x91\x64\x03\xf2\xbe\x39\x4a\x77\xf1\xa9\x26\x77"
-  "\x20\xff\x4d\x21\x3e\x73\x54\x5e\x82\x81\xa0\xae\xe8\x1a\xde\x24"
-  "\xd3\x77\x6a\x7c\xa8\x5d\x78\x60\x3f\xdb\x83\xe5\x9c\x0e\xad\xe3"
-  "\xeb\x18\xd6\x20\xcd\x21\x70\xda\x12\x2c\x55\x62\x67\xfb\xfe\xf0"
-  "\xba\x89\x7a\x24\x0e\x50\x3d\x68\x4c\x84\xe5\xd3\x98\xe9\x10\xdd"
-  "\xcf\x8c\xfd\x26\xad\x5d\xe6\x79\xb4\x8b\xae\xda\x42\xec\xab\x38"
-  "\x5f\x3d\xc9\x4a\x69\xec\x79\x12\xed\x1d\x7b\xe8\x5c\x4c\x5e\x66"
-  "\x81\xde\x54\x55\x51\x59\xf3\xdc\x42\x7d\x45\x65\x45\x4d\xc5\xfa"
-  "\x8d\x15\x3b\xd6\xd7\x54\x6c\xaa\x4c\x7f\x69\xfd\xf3\x15\x1b\xf4"
-  "\xdb\xd6\x57\xeb\x0d\xe6\xdb\xcd\x53\x20\x98\x74\x89\x7e\x7d\x75"
-  "\xf5\x96\x97\xca\x4a\xf5\x95\x15\x1b\xe6\x56\x95\x55\x97\xd5\xe8"
-  "\xd7\x57\x6d\xda\x52\x59\xaa\xbf\xbd\x74\xde\xed\x86\x7b\x4a\xa7"
-  "\x84\xce\xa1\xdd\xaa\x85\xa1\xc0\x95\xaf\x06\x1b\xae\x80\x5a\xa3"
-  "\x30\x55\x69\xcc\x15\x95\x7c\xce\x4e\x35\x2d\x6f\x7e\x33\x98\x30"
-  "\x3e\xb1\xbd\x09\x69\xdd\x34\xb5\x04\x9f\x2a\x4a\x87\xf5\xd4\xe3"
-  "\xbb\x1a\x71\x9f\x39\xd2\x34\x0d\xeb\x98\xe4\x25\x9a\x21\x2d\xf4"
-  "\x58\xb7\x99\xec\xca\xef\x07\xd1\x66\x33\xd1\x9e\x80\xf6\x2b\x90"
-  "\x62\xdf\x0a\x2a\xfc\x25\xe2\x4f\xab\x44\x78\x98\x27\xcb\xa5\xd2"
-  "\x94\xf0\x3b\xc7\x54\xd3\x06\xdc\x49\xe9\x87\x98\x3d\xfd\x90\x68"
-  "\x97\x69\x5f\xca\x73\xdc\xf9\xaf\x40\x3e\xf1\xe7\x19\xd5\x34\x3e"
-  "\x3f\xbb\x1b\x79\x99\xe6\x7d\x87\x7f\xb3\xc2\x88\xf6\xe0\x69\x9a"
-  "\xbb\xc5\xb8\x2f\x3d\x4a\x48\x44\xbc\x54\x27\x6a\x0d\xf0\x06\x96"
-  "\x55\xad\x63\x0c\xcb\x38\x24\xcf\xa7\x61\x1d\xb4\x58\x97\x7e\xa9"
-  "\x1e\xaf\xf1\x7a\xec\x67\xa9\xcd\xc9\x88\x5f\x13\xc7\xe7\x94\x5c"
-  "\x07\xc4\xbb\x1f\x71\xca\x40\x3c\xb5\x84\x57\xb4\xb9\x3e\x9a\xef"
-  "\x3a\xab\xd2\xcc\x0a\x6c\x45\xba\xdd\x2c\xee\x77\x6d\x68\x13\xfd"
-  "\x0f\xeb\x55\xd8\x8e\xef\xfb\x2e\x41\xe2\xeb\x55\x90\xc2\x6c\xb7"
-  "\xb0\x1e\x8f\x0f\x9c\xe5\xfd\xa0\xd9\xce\xdc\xec\xef\xbf\x1a\x14"
-  "\x75\xd2\x64\x93\x6c\xf8\xdb\x17\xfa\x55\x54\x27\xd4\x15\x89\xed"
-  "\x97\x62\xce\x2d\xaa\xde\xb8\x81\x79\xd8\xbb\xa1\x36\x97\xe6\x63"
-  "\xa2\x09\xd9\x5b\xc3\xa8\xa7\x46\x9a\x34\xa8\x3b\xa7\xb9\x25\xdb"
-  "\xd8\xc3\xc6\xd6\x85\xd8\x52\x1a\xe2\x33\x4f\x0c\xd8\x6a\x19\x36"
-  "\x53\xf2\x7b\x91\x75\xa2\xfd\xb5\xb3\x30\x8f\x3b\x04\xbe\x37\x12"
-  "\x3e\xc1\xc4\x77\xb7\x5c\x8e\x18\x87\x6b\xc8\x26\x70\x23\x2f\xbb"
-  "\x63\x94\x97\xda\xb4\x9f\x9d\x72\x62\x78\xc3\x55\x50\x61\xda\x53"
-  "\xed\xfb\x09\xbe\xb6\xc8\xa5\x9a\x7a\x9c\xe0\xef\xbe\x01\xa0\x1e"
-  "\xd3\x0c\x37\x4d\x73\xd3\xfc\x2e\xc6\x61\xff\x1f\x1b\x8c\x9c\xb3"
-  "\x96\xf8\x79\x49\x04\x3f\x1b\x9b\xc8\x26\x6c\x46\xf8\xc8\x43\x0d"
-  "\x97\x51\x0f\xe3\xf7\xbc\x66\x48\xa3\x72\xf0\x9d\x64\xd3\x49\x84"
-  "\x79\x52\x2e\x8f\x21\xff\xef\x0b\x88\x39\x18\x89\xb7\xd2\x9d\xe6"
-  "\x41\x5a\x17\x61\x27\x50\xbe\x13\x8e\xc4\x63\x98\xc7\x27\xf3\x14"
-  "\xf2\xfa\x29\xce\x57\x29\x90\xc6\x9a\xb4\xd6\xf6\x64\x4c\x87\x7c"
-  "\xd5\x86\xfc\x44\x7c\x35\xd2\x94\x94\x26\xf3\x14\xf2\x5a\x1f\xa5"
-  "\x43\x1c\xa6\x74\xee\x30\xaa\x48\x46\x0e\xa8\x92\x0e\x10\x8f\xb1"
-  "\xb7\x1e\xe9\x67\x37\xae\xed\x17\xed\x94\x74\xc0\xe9\x15\x6d\x10"
-  "\xa4\x7b\x92\x29\x84\xee\x7d\xc8\xc7\x53\x88\xce\x7c\xae\x1a\xd3"
-  "\x23\x6e\x7d\xdc\x16\xdf\x89\x6d\xc0\x75\x55\xd2\x3a\xca\x2f\xd1"
-  "\xb0\x3b\x48\xc3\xa4\x63\xd1\x68\x18\x41\x3b\x15\xfd\x58\x53\x52"
-  "\x17\xf5\x15\xcc\x33\xe4\x52\x69\xf7\xc6\x5a\x2b\xc0\x32\x54\xaa"
-  "\x66\x50\x53\x19\x5d\x29\x94\x3e\x79\x66\xb4\x32\x22\xf9\xb8\xab"
-  "\x03\x80\xe6\xc2\x29\x5f\x6a\x0a\xd1\x35\xb9\x30\x6a\xfb\x6e\x08"
-  "\xc3\x8d\xff\x58\x53\x72\xc9\x1b\xc9\xc8\x37\x1c\xbf\xe4\xbd\xd7"
-  "\xc2\x2f\x55\x2f\xf4\xa2\xe3\x56\xe2\xe7\xe4\xdf\x39\x5b\x00\x28"
-  "\x4c\xfa\x3e\x3a\x8c\xba\x26\x72\x3e\x3f\xe6\xfa\x82\x6a\x7a\x7c"
-  "\xd8\xfa\x82\x2a\xd9\x13\x6b\x7d\x21\xbc\xdc\xe9\xcb\xa9\xdc\x40"
-  "\x7b\xa1\x22\x58\xf6\xf4\xf4\x40\x94\xb2\xe5\xfc\xf3\x3a\x42\xc6"
-  "\x2f\xaa\xe9\x8d\x84\x43\x2f\xea\x25\x76\x53\xa1\x82\x21\x9c\x2e"
-  "\x6e\x4b\x4c\xb7\x0b\x7b\x85\xec\xa0\xe9\x26\x4a\x13\x59\x8f\xf1"
-  "\x3f\x75\x0a\x8d\x87\xe1\x2a\xff\x88\x7f\x10\xe8\x36\x72\x98\x51"
-  "\x2e\x47\x2b\xc3\x12\x03\x8b\xf2\x91\x08\x70\x13\x4f\xcf\xf0\x4f"
-  "\x04\x49\xdf\x6e\xfe\xa1\x1a\x4f\x3f\x1e\xff\x1f\xf8\x9b\x2c\xf0"
-  "\xe5\xf0\xbc\xa0\x90\xca\xdb\x13\x92\x22\xeb\x1a\xb9\x19\xc8\x59"
-  "\xa2\xfd\x6d\xc6\x9f\xb5\x10\xdb\xf2\xa6\x43\x3c\x31\x63\x3e\x09"
-  "\xbe\xfc\xcd\x42\xbf\x29\x24\xfc\x1b\xff\xe2\xd6\x85\x14\x70\x4b"
-  "\x5c\x29\xdf\xce\x75\xf3\xc9\xf1\x20\x65\x87\x36\xbc\x50\x6b\x3c"
-  "\x7f\x68\xe8\x1f\x33\xc2\x4b\xc3\xf8\x9b\x82\xe9\xe3\x3c\xbb\x42"
-  "\x12\xff\x93\x40\x7f\x56\xec\x3a\x7c\xf7\xbf\x9b\x43\xde\x6f\x11"
-  "\x8f\x99\x8e\xef\xb3\x80\x6b\xfe\xe9\xfb\x26\xcb\xaf\x41\xf6\x98"
-  "\x95\x1d\x2d\x69\x90\xfe\xb3\x64\x7a\x87\xb5\x67\x30\x7e\x76\x6a"
-  "\xf8\xf7\xad\x5d\xe1\xdf\xa9\xbe\xef\x03\x75\x07\xfd\x63\x71\x25"
-  "\x01\xdc\x16\x6c\x2f\x4d\x44\x97\xd1\xd8\x23\xba\x50\xf0\x4f\xc2"
-  "\x26\x0e\xe0\xf6\x82\x90\x60\x55\xf4\xd4\xff\x77\xfe\x66\xec\x92"
-  "\x08\x78\x8b\x5b\x3b\x21\x32\x32\x8c\xbe\x27\xe9\xa5\xb0\x05\x9f"
-  "\x4d\x48\xcf\xc3\xf4\x21\xdf\x0a\x23\xfe\xd3\x81\x19\x0b\xbf\x0f"
-  "\x5c\x7f\xf8\xfb\xff\xe1\x9f\x82\xfa\xc7\x0f\x7f\xff\x97\xfe\x98"
-  "\xd0\xe2\x28\x89\xf8\x83\xfe\x63\xe3\x82\x92\x49\x11\x4c\x0a\x60"
-  "\xd2\xcb\xf7\xa2\xc7\x7f\xf8\xfb\xe1\xef\x87\xbf\x1f\xfe\x7e\xf8"
-  "\xfb\xe1\xef\x87\xbf\xff\x0f\xfc\x29\xf8\x38\x82\x49\x7f\xf2\xbb"
-  "\x88\xa3\x21\xd0\xfa\x01\x1e\x06\xc1\x78\x1c\xfb\xde\x0d\x0a\x35"
-  "\x4c\x52\x7d\x9f\x36\x9e\x7e\x1c\xa1\x6f\x91\xd8\x80\x3f\x5a\xef"
-  "\x5f\x84\xbf\x9b\x42\xc2\x6f\x8e\x9e\xfc\x2f\xf0\xa7\x40\x62\xc5"
-  "\xe1\x18\x30\x1e\x26\x41\x02\xa8\x61\x32\x4c\x81\xeb\x20\x11\xa6"
-  "\xc2\x34\x1c\x5b\x6a\x21\x09\x92\x61\x3a\xa4\xc0\xf5\x70\x03\xdc"
-  "\x08\x3a\xf8\x11\xcc\x40\xcc\x67\xc2\xac\xe8\x38\x5b\xc1\xa8\xc3"
-  "\x7f\xf0\xff\x02\x30\xf2\xef\x92\x1f\xc2\xff\xa2\xe1\x0e\x29\xbc"
-  "\x4f\x0a\x77\xfd\x10\xfe\x17\x0d\xd7\xff\x27\x3f\x67\xff\xa7\x3e"
-  "\x15\x28\x96\x85\x64\x56\x44\x95\x87\x91\xa1\x0a\xe9\x6f\xfc\x1b"
-  "\xbe\x21\xff\x04\x78\xe1\xf9\x23\xff\x8c\xf8\x5b\x2c\x5e\x2d\x00"
-  "\x62\x2e\x97\x85\xfe\x7d\xe3\xcc\x9c\xb9\x1c\x7f\x35\xf8\xb3\xe2"
-  "\x6f\x37\xfe\x1a\xf0\xf7\xb6\x0c\x47\xa4\x51\x03\xed\x3a\x00\xe8"
-  "\x3b\x02\xf0\x87\x01\xfc\x65\x03\xfc\x33\xa6\xff\x1f\x29\x00\xff"
-  "\x5a\x08\x70\xea\x28\xc0\xff\xf4\x04\x61\x0e\xd8\x83\xd8\x9d\xb1"
-  "\x8a\x77\x3d\xfe\xfe\x4c\x67\x7b\x91\x93\x2e\x0d\xe2\xe3\xd8\xca"
-  "\xc2\x6c\xfd\x82\x79\x8b\xe7\x2d\x5e\xa4\x9f\x5b\x30\x57\xbf\xd0"
-  "\x60\xb8\x6f\xbe\xe1\xee\xf9\x0b\xef\xd1\x2f\x5c\xb4\xe4\xee\x7b"
-  "\x96\x2c\xcc\xd0\xbf\xb4\xbd\xaa\x62\x81\xe1\xf9\x32\x7d\x65\x69"
-  "\x45\xb5\xfe\xb9\x8a\xaa\x97\xb6\xad\xaf\x2a\xfb\xa6\x2a\x7d\xd7"
-  "\x3f\x42\x6d\x56\x00\x38\xf5\xc3\x29\xad\x01\xd5\x4d\x2e\x50\xa5"
-  "\x77\xc2\x78\x8c\xc2\x2e\xcd\xe2\xa7\x49\xbf\xa8\x7f\x2f\x3d\xf5"
-  "\xf8\xe7\xb7\xaf\x9d\xf6\xdb\xe5\xcf\xdf\xbe\x2c\xf3\xfd\x86\x4e"
-  "\x50\xa6\x1e\x01\xe5\xcc\x22\x50\x26\xeb\x41\x39\xa9\x00\x14\xde"
-  "\x41\x50\x16\x1f\x07\xe5\x13\x18\x96\xa7\x05\xe5\x72\x03\x28\x17"
-  "\x1d\x9b\x18\x56\x79\x5a\x84\xfd\x6c\x26\x28\xdf\x3a\x0a\xca\xd7"
-  "\x30\x4d\x9d\x4a\x84\x1d\x33\x81\xf2\x43\x4f\x2c\x1c\xfe\x93\xfe"
-  "\xbe\x8d\x9d\x70\xed\x3f\x55\x4e\xf7\xf7\x80\xc7\x0f\x7f\x3f\xfc"
-  "\xfd\xf0\xf7\xc3\xdf\x0f\x7f\x3f\xfc\xfd\xf0\xf7\x17\xfe\xbb\xa4"
-  "\x54\xc1\x6f\xd1\x52\x1a\xb1\xa9\x75\x2e\xc5\x94\x23\xb4\x6f\x04"
-  "\xe8\x3c\x14\xa8\xb9\x7f\x17\xe9\x17\xba\xe7\x24\x31\xf3\x00\x00"
-  "\x9d\xe9\x7c\x63\x3f\x73\xd3\x79\xcd\xac\x0f\x00\xba\x52\x01\x68"
-  "\x1f\x0b\xc2\x59\xe7\x82\x8d\x2a\xb1\x67\x89\x79\x28\x9e\xf6\x3d"
-  "\x61\x78\x0d\x86\xd7\x5e\x63\x1f\x0c\xdf\x73\x45\x30\xb3\x66\x73"
-  "\x7c\x0e\x46\xc0\x21\x18\xc7\x30\xcc\x73\x0d\x18\x89\x32\x5e\x1e"
-  "\x25\x28\x08\xde\xb0\x0d\x74\x1e\x9b\xe3\x7a\xcc\xeb\xc1\x3a\xa5"
-  "\x49\x7b\x86\x86\x98\x0d\xe2\xba\xcc\x3e\x3a\x3b\xaa\x38\x0b\x93"
-  "\xbf\xc2\xa7\x12\x9f\xfc\xcc\xc3\x6e\x91\x2f\x95\x60\x60\x5e\xc5"
-  "\x88\x6d\xb2\x61\x3c\x2f\xc2\xe6\xe7\xce\x61\xf2\xc7\x1e\xa5\x43"
-  "\x29\xd2\x6a\x27\x4b\x69\x95\x98\x76\x9d\x9c\x56\xc4\x29\x73\xa4"
-  "\xb8\xeb\x30\xce\x1c\x1e\xa7\x6a\x92\xe2\x12\x31\xae\x39\x02\x3f"
-  "\x95\x73\xd4\x07\x58\x0e\xe1\xa2\x77\xe1\x93\xce\x2b\x49\xb8\x11"
-  "\x4e\x5d\x98\xde\x4a\xe9\xb3\xf4\xcc\x57\x88\xd6\x2a\xc5\x11\xed"
-  "\x30\x6d\xf6\x89\x0e\x91\x16\xdf\x67\x52\x7e\xe9\x5d\x4f\xfb\xa7"
-  "\xe8\x5d\x2a\x37\x69\xc4\x36\x25\x31\x1c\x27\x00\x29\x2e\x19\xe3"
-  "\xd2\xc2\xe3\x7e\x63\x90\xe2\x6e\xc4\xb8\xac\xf0\x38\x85\x9c\x4f"
-  "\x87\x71\x25\x72\xdc\xc4\xfd\x37\x38\x3c\x81\x78\x1c\xa8\x4c\xc2"
-  "\x5f\x82\x5a\x6e\xbb\x6a\x1d\x0b\x58\x7e\x44\xfb\xac\xe6\x7b\x03"
-  "\x36\x06\x4e\xb3\x17\xf4\x33\xc0\x72\x06\xa6\xf4\xd1\x3e\x9e\x7d"
-  "\x3b\x40\x6d\x31\x31\x2f\x9d\xc9\xef\x75\x0f\x81\xc5\xcd\x06\xe9"
-  "\xdc\x7b\xdd\x65\x50\x93\xff\xa6\xba\xcd\xa0\xeb\xaa\xfd\x53\xd4"
-  "\xbd\x43\x01\xf2\x23\x3d\x93\xf2\x0e\x40\x6f\xeb\x00\x58\x5a\xc3"
-  "\xf3\x5a\x66\x81\xae\x87\xce\xd0\xdb\x40\x43\x78\x74\xe9\x7d\xe0"
-  "\x4b\x9e\xef\xad\x7d\x1b\x54\x96\xd9\xa0\xec\x29\x75\x48\xb8\x5c"
-  "\xd7\x42\xb8\xd4\x9f\x03\xf5\xfb\xcf\x61\xdb\x9f\x23\x7c\xef\xf5"
-  "\x7e\xb4\xc3\xab\x3c\xa1\xcb\x85\x13\xba\xd3\xd0\xa5\x5b\x06\x5d"
-  "\xe6\x2c\xd8\x77\x0e\x12\x4f\x78\x97\x42\x97\xea\x41\xec\x1b\x59"
-  "\xe0\x1c\xc2\x77\xbd\x1f\xd3\x78\xf8\xb9\x8c\xb3\x70\xdd\x9e\xe6"
-  "\x17\x40\xed\x12\x30\xb1\x3d\xaf\x6b\x96\xcf\x18\xd0\x77\xb4\x7a"
-  "\x54\xff\x08\x74\x88\xdf\x20\xe2\x72\x1f\xe2\xd2\x93\xaa\x03\x03"
-  "\xe2\x9c\xe0\x6c\xf1\x81\xaa\x16\x26\xc7\xe8\x13\x29\xfc\x7c\x32"
-  "\xf2\x54\xdb\x7e\x36\x48\xbc\x35\xfc\x72\x11\xf6\xaf\x44\x15\x96"
-  "\x7d\x50\xda\xb7\x37\x64\x79\x0f\x54\xc3\xdb\x8a\x68\xbf\xf2\x00"
-  "\xc6\xe9\xe5\x38\x3a\x77\x4d\xe7\xa9\xe7\xa7\x80\xd6\xe9\x33\xc2"
-  "\xa7\xa3\x83\xb4\x27\x70\x88\xf6\x69\x12\x3c\x8d\x19\xe2\xb0\x3e"
-  "\xf1\x88\xcf\xd7\xed\x18\x7e\x1b\xa6\xc3\xfc\xd8\xfe\xbf\xe0\x67"
-  "\xee\xd9\x8d\x6b\x3d\x81\x1b\xd7\x5e\x0e\xbc\xb5\x76\x98\xbd\xb5"
-  "\xf6\x92\xff\xad\xb5\x5f\x5b\xb6\x83\xda\x7f\xe3\x5a\x77\xaf\x89"
-  "\xb7\x81\xb6\xd7\x74\x9e\xf6\xf7\xa9\x77\x9e\x07\xed\x33\x9b\xb1"
-  "\xed\x7d\x5f\xc0\xce\x0a\xd0\x05\x92\xee\xe9\x74\xfa\xfe\x05\x9e"
-  "\xa9\x05\x86\xef\x8e\x68\xf5\x1b\x4e\xce\xc8\x10\x3c\xab\xa6\x3a"
-  "\xf5\xbb\x54\xf3\xf8\xbe\x40\x77\x92\x31\x03\x7f\x4b\xf1\x67\xc4"
-  "\x5f\x16\x4b\xce\xc8\x42\x5a\x59\xa6\xed\x52\x00\x9d\x2b\x98\x1f"
-  "\x00\x05\x36\x91\x07\xf1\xd7\xc6\xa0\xdb\xcc\x40\x53\x9d\xe3\xaf"
-  "\xac\x50\x47\xfe\x08\x48\xa6\x90\x3c\x21\xf9\x32\x62\x9b\x6a\x74"
-  "\xa9\xe6\x1b\x38\xef\xef\x67\x1e\x96\x5c\xe7\xc0\xf0\x41\xcf\xcb"
-  "\xe5\x0a\xf7\xcb\xe5\xca\xe1\xe4\xba\x13\x98\xa6\x14\xd3\x94\x4b"
-  "\x34\x1c\x24\x58\xd8\x4f\xdc\x53\x7d\x10\x87\x30\x4d\xff\x70\xa5"
-  "\x5f\x75\x60\x3f\x3b\x8d\xe9\xf6\x8e\xc3\x42\xd8\x08\x07\xe9\x3f"
-  "\xb5\x43\x0e\x43\x5a\x0f\xbc\x8e\xe9\x28\xbf\xd3\x6b\x24\xb9\xeb"
-  "\x72\x6e\x1c\xa4\x7d\xb5\x53\xd8\x98\x28\x0f\xd3\xd0\x99\x4b\xf7"
-  "\x54\x2f\x4c\x1a\xb1\x41\x01\xc1\xa6\x7c\xce\xa1\x41\xc0\x7c\x27"
-  "\x98\xa5\x1c\xe5\x12\xac\x1a\x61\xe5\x0a\x3a\x63\x7f\x02\xf3\x8b"
-  "\xb2\xa7\xa9\x65\x1c\xa9\x0c\x7e\xc6\x9e\xf0\x44\x7e\x38\xb1\xd1"
-  "\x0b\x53\x5b\x20\x0e\xf3\xad\x21\x78\x04\x0b\xf9\xc0\x85\x75\x3d"
-  "\x71\x62\xa3\x1b\x02\x2c\x0c\xa6\x4b\x82\x57\x14\x06\x0f\xc3\x19"
-  "\xc2\x23\xfe\xeb\xc2\x3c\x53\x3b\x38\xbc\xd5\xff\x10\x20\x78\x5e"
-  "\x50\xe9\x39\xbe\x8f\x13\x0c\xee\x23\x03\x61\x3a\xb6\xae\x80\x21"
-  "\x98\xe6\x70\x5b\xca\xe3\xf8\xfe\x3e\xcc\xff\x51\xdd\x60\x3c\x1b"
-  "\x2e\x8a\x9b\xc6\xf7\xf6\xad\x00\xf2\x89\x81\x69\xde\x63\xc3\xe5"
-  "\x71\x53\x87\x40\x45\x38\xd3\xf9\x1e\xc2\x33\xb4\x2d\x57\xaf\x7c"
-  "\x7c\x19\x3c\x9e\x95\x93\xb5\x0c\xf2\x96\x67\x2e\x03\xc3\x7d\x73"
-  "\x0d\x8b\xee\xcd\x58\x04\x05\x4f\xac\x5e\x06\x05\xab\x96\xc1\x1a"
-  "\xfc\x15\x3d\x98\x83\x1f\x99\xcb\x16\x18\x1e\x9a\x5b\x90\x99\xb3"
-  "\x12\x1e\x2d\x5c\x68\x58\xb8\x10\x96\xaf\xcc\x5d\x60\x30\x48\xcf"
-  "\x05\x06\x4a\xf2\x54\xc6\xca\x35\x73\x0b\xaa\x36\xd5\x6c\x9a\xbb"
-  "\x2a\x27\x13\x56\xae\x5c\x56\x10\xa1\x1b\xd3\xfc\x57\xfc\x44\x5b"
-  "\x0f\xbb\x98\x4d\x3e\x14\xa0\x0d\xdb\x1c\x7f\x43\xfc\x6c\x06\x68"
-  "\x5f\x69\xa3\xb6\xe2\xf2\x72\xda\x69\xec\xe7\xaa\x11\x9b\x86\xda"
-  "\xff\x10\xd1\x8c\xfc\x18\x9c\x85\xeb\x0f\x60\xdc\x97\x92\x8c\x8e"
-  "\xc7\xf8\x23\xe1\xf1\x49\x56\x8c\xff\x33\xed\xf5\x77\xe2\x0f\xe9"
-  "\xec\x41\xd9\x87\xf4\x74\xc3\xb0\xa5\x28\x9e\x9f\xb5\xc4\x36\xa6"
-  "\x3d\xb0\x98\x77\x30\xa4\x8f\x0f\xd0\x5e\x59\xfd\x0e\x88\xbb\x00"
-  "\x9a\xcf\x7a\x6b\x8c\x74\x1e\x06\x9c\x35\x12\x8c\xcb\xe3\x30\xa6"
-  "\x48\xe7\x35\xe9\x1c\xf4\x29\x01\x47\x6b\x08\x91\x07\x2e\x82\xb3"
-  "\x0f\xe3\x04\x2c\x6d\x7c\x2f\xca\x05\xd6\x64\x50\x06\x2c\x69\xc0"
-  "\x92\x0d\x10\x18\x4b\xe3\x3a\x06\xf3\x95\xcb\x7c\xbc\x8f\xf6\xb8"
-  "\x9a\x30\xdd\xfb\xd9\x0a\xda\x23\xca\xf7\x8b\x82\xa6\x06\xf9\xd9"
-  "\x13\x68\x32\x66\xf3\xb3\xcc\x3c\x4c\x7b\x94\x25\xe3\x77\x93\x31"
-  "\x87\x59\xc4\xf9\x66\x0c\xfb\x3b\x0a\xc3\x36\x8e\xe3\xbe\x41\x5e"
-  "\xe6\xe1\x71\x48\x8b\x39\x88\x5f\xbf\x9f\xf2\x5f\xe4\xf9\x13\x30"
-  "\x6c\x32\xa6\xcd\x09\x24\x1b\x1f\x46\x9e\xa1\x30\xd4\xeb\xd7\x1f"
-  "\x47\x78\x8f\xd0\xd9\x72\xa6\xfd\xc4\x8d\xef\xb9\x8e\x1d\x43\xdc"
-  "\x3f\xa0\x0b\xe3\x02\x16\x84\x39\x36\x5e\x7e\x3f\xe5\xc5\xb2\x54"
-  "\x23\x63\xe5\xa8\x4b\xb5\xa7\xc9\x26\xf0\x13\x3e\x17\xc7\xd3\x9c"
-  "\xa4\x32\xa9\x3f\x63\x5b\x0c\x61\x3b\x4d\x1e\xb1\x25\x15\x46\xb4"
-  "\xd3\x46\x84\x93\x83\x74\xef\x47\x18\x5d\x81\x61\x2c\x03\xbf\x11"
-  "\xae\x52\x82\x2b\xc3\xf0\x08\x3e\x48\x6a\x8e\xe0\x83\x5d\x08\xfb"
-  "\x72\x48\xfc\xd1\x88\xf8\x32\x8c\x1f\x95\xe2\xb1\x5f\x25\x9d\x8a"
-  "\x28\x9f\x70\x0b\x60\xf9\x1e\xec\x37\x71\x58\x5e\x51\x1b\xd9\x6b"
-  "\xe3\xe9\x93\x55\xe1\xe9\x93\xd1\x36\xd0\x90\x2c\x21\x99\xc8\xd3"
-  "\xb7\x4b\xbc\x2a\xca\x4f\x5e\x1c\x91\xde\x87\xe9\x13\xc8\x07\x07"
-  "\x3e\xa7\x63\x9a\x04\x94\x49\x2a\xd4\x1f\xa7\x4f\xd4\x92\xfd\x96"
-  "\x5c\x1a\x91\xbe\x1e\xd3\xcd\x20\x3a\x72\x1a\x5c\xe4\x34\x28\x92"
-  "\xec\x2d\xea\x0b\x6a\xcc\xd3\x12\x91\xe7\x18\xe6\xb9\x35\x20\xe8"
-  "\x16\x37\x32\x1c\x35\x4f\x77\x44\x9e\x21\xde\xfe\xa2\x1c\x15\xf1"
-  "\x8b\x9c\x87\xcb\x98\xb1\x30\x18\x54\x37\xb4\xcb\xa6\x6b\xc3\x61"
-  "\xa4\x0c\x61\xb9\x77\xbe\x2e\xfa\xf1\x75\xd8\xe6\x0b\x31\xec\x0b"
-  "\x84\x9b\x47\x7c\x42\xbc\xec\x74\x7b\x51\x06\x66\x27\x0a\x5d\x3e"
-  "\x7d\xb3\xa6\x16\xe8\x7d\x2e\xbd\x13\x6c\x36\x96\x2b\xf1\xf8\xf4"
-  "\xcd\xf8\xa4\x70\x5e\x26\xf5\x2d\x36\xf6\x48\x40\xc0\x9c\xfe\x26"
-  "\xf6\x41\x25\x7e\xfb\xa5\x32\xfe\x85\xce\xf9\x22\x7f\x3e\x8c\xf2"
-  "\x15\xe8\xac\x32\x86\x2f\xc6\xf0\x1e\x29\xfe\x77\x94\x1e\xdf\x17"
-  "\x48\xef\xc4\x97\x0f\x4b\x7c\x89\x7c\x9e\xc2\xcf\xa6\x0a\x5e\x17"
-  "\xf9\x03\x82\xaf\x33\x31\xee\x97\xf8\xcc\xc1\xe7\x9b\xf8\x7c\x14"
-  "\x9f\x9b\xc9\x37\x83\xc5\x8f\xf6\x84\xf8\x7e\x1a\x9f\xab\xf1\x99"
-  "\x83\xcf\x35\xf8\xbc\x9b\xfa\xa5\x7b\x5b\x39\x44\xf0\xc4\x50\x40"
-  "\xf4\xc5\x04\xd1\x1e\x29\xa9\x52\xff\x10\xfd\xf3\x62\x30\x8c\x89"
-  "\x30\x25\xca\xf5\x60\xd8\x58\x36\xd1\xa5\x00\xe1\x73\x5f\x22\x52"
-  "\xbf\x8e\x17\xed\x22\xd2\x04\x44\x3e\xa9\xed\xa4\x30\x91\x4e\x11"
-  "\x5a\xa6\x0b\xa6\x9f\xaa\xf3\x30\x86\x4f\x07\xf7\xeb\x00\x29\x5d"
-  "\x48\x13\xb4\x6b\xa6\x37\x13\x9d\x82\xed\x3d\xdd\x10\xd2\xde\x68"
-  "\xd7\x5e\x0f\x11\x7d\x69\x31\xb6\xf7\x52\xde\xde\x48\x3b\x19\x67"
-  "\xc2\x1f\xf5\x0b\xe9\xac\x49\xa2\x0e\xda\x22\x94\xed\x43\x41\xd9"
-  "\x7c\x7d\x76\x38\x1c\x6d\x11\xe6\x39\x2e\xe9\xb2\x71\x3e\x23\x7e"
-  "\x89\x33\x51\x1f\xba\x1e\xed\xff\xcf\xba\xf9\x19\x1f\x8c\xf3\x24"
-  "\x59\x8c\x54\x66\xdc\x46\x1e\x87\xf6\xff\x75\xfd\x72\x1c\x88\x73"
-  "\x54\x9e\xb8\x1a\x1e\xd7\x29\xe7\x43\x39\xab\xe7\x79\x51\x3f\x92"
-  "\xbd\x40\x7a\x1f\xf5\xef\x20\xa6\x39\xe5\x82\xa9\xda\x98\x3e\x8c"
-  "\xec\x06\xed\x5c\x2b\x28\x6f\xb3\x42\xbc\xd3\x77\x1a\xf2\x7d\xcc"
-  "\x3f\x17\x60\xb2\xd3\xb7\x14\xe6\x00\x24\x39\x7d\xa7\x68\x92\x7c"
-  "\xb6\xd3\xd7\x8c\xfa\xb5\x9e\xe2\x3f\xbd\x13\x14\x0a\x7c\x5a\xee"
-  "\x02\xa5\xc2\xe9\x3b\x88\xe1\x47\xe1\x36\x50\x29\x1e\x8a\x67\x23"
-  "\x4e\xdf\x62\xfc\xae\x81\x07\xe3\xd9\x1f\x8b\xfd\xa0\xcd\x7d\x85"
-  "\x59\x9c\xbe\x52\x78\xf0\x95\x00\x73\xfa\xba\x31\x6e\x23\xe4\xfb"
-  "\xaf\xb2\x7c\xff\x08\x63\x5a\x83\x3e\xdf\x7f\x11\xdf\xff\xc8\x90"
-  "\x6e\xf8\xfc\x14\x7f\x16\xe6\x44\x3b\x99\x35\x1a\xb4\xc5\xdb\x95"
-  "\xc0\xef\x38\x4a\x32\xe8\xb1\x7e\x86\x31\x56\x1e\x87\x7a\x64\xfe"
-  "\xd8\x18\x3e\x9b\x0c\xf3\xf8\xb7\xdd\x60\x44\x38\x86\x79\x38\x68"
-  "\x20\xfc\x9d\xbe\x01\x28\x46\x79\x93\xbf\xdd\xcd\x08\xf7\x69\xbb"
-  "\x18\xe4\x6f\xff\x94\xa1\xac\xd3\xe4\x6f\xb7\x30\x8c\x53\x23\x3c"
-  "\x83\xd3\x37\x44\x65\x18\x11\xde\x32\x0e\xcf\x6e\x28\xc1\xb4\x6e"
-  "\x4a\x17\x0a\x87\x60\x50\xda\x7c\x3f\xf9\x90\x32\x94\x8c\x35\x1a"
-  "\x0a\xf0\x67\xc2\x5f\x07\xe6\xfd\x9b\x80\x2d\xe5\x33\xd2\x6b\x98"
-  "\xdf\x81\xdf\x7d\x57\xb9\xff\x85\xd3\x94\x3e\x01\xd3\x93\xfd\x91"
-  "\x35\x22\xf0\x75\x73\x7c\x9b\x0c\x17\xaf\x8a\x7a\x5c\x90\xea\x71"
-  "\x9e\xc2\x3d\xc8\xeb\xac\x69\x81\xd6\xc3\xe3\x16\x68\x30\x5f\x21"
-  "\xcf\x67\x5f\xa0\x65\xda\x05\xe4\x07\x35\x2e\xdf\xcf\xac\x44\x43"
-  "\xa4\xab\x95\xe8\x48\x63\x1e\xd6\x88\xf1\x49\x0b\xf4\x63\x8d\x0b"
-  "\x0c\x98\x7f\xc5\x18\x23\x5d\xbb\xa0\xe0\x2a\x87\xbd\x20\x1f\xe1"
-  "\xac\x1b\x21\x98\xda\x05\x05\x08\xab\xc4\xa7\xd4\x23\x3d\x98\x37"
-  "\xdf\xb7\xcb\x57\xbc\x9d\x7c\xa4\xfc\x0e\xd2\xac\x56\x85\xd3\x5c"
-  "\x83\xf5\xdc\x8b\x30\x4b\x31\x1e\xa6\x63\x59\x9f\x22\xdc\x02\x2a"
-  "\x0f\xcb\x28\x41\x98\x4f\x23\xac\x52\xc2\x69\x94\xfc\x90\x26\x2f"
-  "\x30\x8d\x0a\xfc\xec\x01\xfb\x82\xce\x80\x76\x41\x87\xcc\x3f\xc4"
-  "\x3b\x82\x6e\xc4\x33\x1f\x52\x98\x56\xe6\x13\xbf\x7d\x81\xf5\x2e"
-  "\x00\xed\x2a\x0f\xf3\x11\xaf\xcc\x07\x93\xa2\xd7\x73\x0a\x69\xad"
-  "\x86\x5e\xd3\x51\xb8\x13\x68\xec\xe5\x81\x5e\x4f\x33\x7e\x1f\xe0"
-  "\xf7\x9b\xf7\x7a\xea\xa1\x67\xe8\x20\xac\x32\x79\x76\xf9\xb5\x0b"
-  "\xf1\x3d\x0f\x30\xff\xa7\x74\xc7\xd6\x33\x26\x95\xb5\xd7\xe4\xa1"
-  "\x6f\x4b\xcf\x10\xf2\xa7\x9f\xf9\x7d\xf6\x05\x26\x9f\x76\xa1\x76"
-  "\xd5\x65\xe6\xce\x1b\xb2\xc6\x63\xd8\x98\x46\xc1\x7c\x1a\xb3\x85"
-  "\xf5\x0c\xed\x85\x67\x2e\x83\xa2\xa7\xfc\x28\xe7\xd3\x67\x4c\x26"
-  "\xe0\xf9\x2f\xfb\x34\x4f\x0f\x59\xe1\xe9\x72\x98\x86\xe9\x2f\x12"
-  "\xcf\xb2\x69\x56\xe8\x1e\xd8\x08\x79\xe7\x7d\x71\xab\x2e\x8f\xb1"
-  "\xee\x92\x66\xe8\x29\x6f\x26\x7a\xd8\x69\x8c\x92\x77\x7e\x98\xad"
-  "\xba\x3c\xc2\x7a\xca\x3f\x84\xee\x92\xa3\x90\xfb\x27\x87\xc6\xdf"
-  "\xb8\xc0\x1a\x48\x5a\xd0\x11\x68\x5c\xd0\xe9\x4f\x5a\x08\xbe\x46"
-  "\xc4\x25\x69\xa1\x96\x35\x2d\xb4\x22\xfd\x26\xf3\xb6\x48\x5e\x58"
-  "\x87\xef\x7a\xde\xbe\xda\x85\x76\x66\x5f\xd8\x39\xd6\xb8\xb0\x83"
-  "\xf3\x7d\xd2\x42\xbb\xd3\x47\xfc\xbf\xb0\x13\xd3\x75\x0a\x1e\x59"
-  "\xe8\x10\xbc\xbf\xf0\x53\x6a\x57\x4c\xdb\x87\x3f\x17\xfe\xd0\x66"
-  "\x59\x64\x44\x58\x49\x04\x37\x60\x5f\x54\x10\xd0\x2e\xc2\xfe\xb0"
-  "\xa8\x04\xc7\x34\xca\x5e\xcf\x41\x20\xbf\xbc\xbd\x1e\x3f\xac\xda"
-  "\xec\xc5\xb6\xc5\x36\x30\xfb\x91\x9e\xa7\xe1\x99\xcd\x60\x71\x9a"
-  "\x4f\x03\xfb\x8d\x9d\xe8\xa1\x59\xb5\xf9\x53\x16\x68\x5c\x54\x40"
-  "\xf1\xab\x36\x5b\x70\x5c\x85\x70\x92\x16\x95\x04\x9a\x16\x59\x25"
-  "\xfb\x0a\xf1\x58\x64\x21\x3c\xc6\x46\xd2\xe8\xfc\x9b\x0a\xe3\xed"
-  "\xac\x69\xb1\x92\xf4\x4d\x80\xf8\xce\xbe\x18\xed\xa8\xc5\x25\x79"
-  "\xf1\xcc\x4d\x3e\x75\x89\x07\x02\xf7\x33\x46\xe3\xb6\x62\x33\x74"
-  "\xf0\x3e\xe5\x9f\x61\x65\x49\x8b\x4b\x58\xe3\x62\x1c\x83\xdc\xf3"
-  "\x33\x84\x13\x47\x3e\x91\x99\xfd\x9e\x0e\xc1\x33\x5f\xf0\xbe\xc7"
-  "\x1a\xef\xe9\x08\x9f\x23\x88\x3e\x3f\x30\x62\x9b\x71\xd4\x05\xbd"
-  "\x7c\x6c\x81\xef\x0e\x17\x38\x97\x4a\xef\xdd\x2e\xf8\x1b\x3e\x4f"
-  "\x44\x32\xce\x54\x07\xd7\x9f\x83\x9b\xac\x48\x0f\xc0\xf7\x44\x7c"
-  "\xaf\xcf\x9f\x83\x75\xb6\x1f\x4e\xc3\xf6\x1e\x21\x79\xc3\x6c\x8b"
-  "\xd1\x3e\x01\x23\xd6\x55\xcd\x46\xc8\x37\x74\xe6\x6a\xf2\x0d\x4d"
-  "\xbe\xa0\xf1\x7b\x1a\xd2\x34\x15\x9f\xc9\x07\xae\x40\x0a\xfe\xc8"
-  "\x1f\xac\x95\xe4\x31\xbe\x1b\xd8\x36\xdd\x94\x7d\x5b\x21\x5d\xe3"
-  "\x11\x3e\xa0\xc9\x67\x35\xda\x3d\x29\xf4\xce\x6c\x7f\x9f\xd6\x7e"
-  "\x45\xf2\x03\x9d\x84\xe5\x91\x1f\xe8\xea\x34\x68\xaf\xe2\xbe\xe9"
-  "\x74\xed\x36\xd6\xe9\x1f\x49\x53\x12\x9e\x32\x2e\x84\x1b\xe2\x39"
-  "\x0b\xf1\x6c\x7e\x6c\xbb\x91\xdf\xff\x15\x4d\x7e\x8f\xd8\x6e\x1a"
-  "\xaf\x7f\x8c\xf8\x53\x32\x4d\x62\xc4\x7b\x64\x3a\xc5\x9a\x27\xa0"
-  "\x3e\xee\xbf\xc2\x86\x1a\x2a\xc5\x79\x3b\x8b\x8f\xfd\xbf\x38\x86"
-  "\xb1\xd6\xe1\xd8\x3c\xdf\xec\x65\x4e\x37\x73\xd0\x5d\x76\x34\x0e"
-  "\x6e\xc7\x34\x75\x3e\x16\xa0\x71\x31\x8d\x89\xc9\xb7\x5b\xa0\x31"
-  "\x73\x31\x6b\xcc\x34\x0c\x6f\x65\xbe\x36\x3e\x8e\x9d\x59\xee\x82"
-  "\xfb\x4b\x44\xdb\x2c\xb0\xa3\x1e\x1c\x18\xd6\x66\x1a\x10\x76\x12"
-  "\xc1\xee\x35\x31\x47\x20\x29\x33\x03\xd3\xd9\x5d\xf0\xf9\xc1\xd0"
-  "\xb9\x3e\xd4\x69\x43\xf5\xfb\x49\xaf\xcd\x3c\xe2\x82\x5b\xf6\x4c"
-  "\x98\x4b\x12\xab\x97\xd6\xb0\x73\x17\x0a\x08\x3f\x45\x42\x27\x36"
-  "\x8c\xd1\xa3\x83\x7a\x71\xa1\x96\xfc\xdd\x59\x76\xc2\x4c\x6c\x87"
-  "\x9b\xce\xc1\xac\xd9\x16\x33\x3b\xcb\x6c\x33\x8f\xbd\xbf\xc3\x8b"
-  "\x36\xc4\xac\x74\x17\xbc\xd7\x1f\x8b\x6e\x81\x2b\x6c\x00\xeb\xd6"
-  "\xd9\x80\x76\x20\xd5\x9b\xe8\x96\x6f\x66\x01\xac\xdf\x97\xd4\xc7"
-  "\xda\xb7\x92\x2d\x3c\xcb\x24\xd3\x21\xd6\x19\x40\x66\xcf\xcc\x12"
-  "\xf6\xe2\xac\x3e\x66\x63\xe0\xb8\x99\xe6\xfe\x66\xfd\x81\xdb\x4c"
-  "\xf6\x85\x1d\xc3\x28\x3f\x68\x8e\x84\x7c\xd3\x55\xeb\x98\x17\x61"
-  "\x76\xb9\xe0\x0e\x83\x34\x26\xf3\x38\x7d\x2b\x49\x96\x74\xc4\x9a"
-  "\x5b\x0d\xc2\xbf\xd9\xdd\x3b\x93\xee\x13\x44\xb9\xa3\xb5\xd4\xd7"
-  "\x89\x76\x26\x3f\x16\x1e\x3a\xe3\x3a\x80\xf1\xd5\x1e\x36\xc8\xec"
-  "\x16\x33\xd9\x1f\x74\xde\x0e\xc3\xbe\x46\xfe\x65\x8e\x2a\xc2\xe9"
-  "\xe6\xaf\x1d\x37\x8f\xc2\x59\xb4\x07\xe9\x4c\xab\x18\x9f\xdd\x7c"
-  "\xfa\x44\x0d\x48\x63\xbe\x9b\xd7\xb9\x20\xad\x5b\xc6\x0b\x65\x06"
-  "\x43\xda\x12\x9d\xed\xa4\x5f\x69\xde\xad\xba\x96\x79\x11\x57\x3b"
-  "\xa6\xdd\x23\xd7\x81\xea\x27\xea\x75\x73\x6b\x68\xbd\x10\x07\x37"
-  "\xda\xd6\x9c\x06\xd5\xdb\x41\xcd\x7d\x65\xf9\x49\x77\xac\xe4\x75"
-  "\xa1\x3a\xf3\xba\xa0\x5d\x41\xfa\xc4\xe9\xbb\x1b\xed\x2e\x1e\xde"
-  "\x89\xb0\x70\xfc\xfb\x57\x19\xc2\xa6\xba\x39\xf6\x7d\xb0\xda\x05"
-  "\x25\x96\xab\x70\xb3\x25\xc0\xce\x9c\x85\x5b\xb6\x20\x9d\xe2\xe8"
-  "\xc9\x75\xb1\x17\x79\x57\x9b\x93\x42\x3a\xd8\x59\x7b\x19\xe5\x36"
-  "\x4f\x3b\x1d\xd3\x0e\x60\x9a\x32\x29\x6d\x99\x98\x13\xe6\xcf\x04"
-  "\x7a\xa2\x4e\x7e\x1a\xf9\xb6\x96\xe6\x31\x90\xce\x46\xf9\x9b\xe1"
-  "\x37\x3e\xb1\x9f\xe4\xa4\x44\xc7\x65\x71\x49\x40\xea\x87\x58\xce"
-  "\x8d\xc4\x47\x96\xed\xf0\x23\xe4\xc9\x2f\xeb\x76\xc2\xf5\xc4\x63"
-  "\x2c\x29\xb3\x40\xd0\xfd\x96\x93\xcc\x66\x05\x3a\x1f\x6b\xda\x0a"
-  "\x37\x61\xdf\xcb\x3e\x07\xb7\x7c\x51\x5c\xab\x47\x5c\x01\x1a\x2e"
-  "\x00\xe9\xc9\x3f\x62\xfa\x5c\xa7\xef\x4f\xe4\xd7\x1f\x79\xf1\x16"
-  "\x9f\xcc\x8b\x23\x36\xbd\xfa\x5a\x32\x01\xe9\xea\x12\xe3\x0a\xfd"
-  "\x16\x9a\x63\x3b\x03\xfa\x12\xaa\x2f\xfe\x14\x18\xf6\x28\xbb\xc2"
-  "\x66\x92\xef\x42\xa4\x75\x9f\x0b\xf4\x7b\xf1\xe9\xe2\x3f\x1b\x58"
-  "\xa5\xef\x3e\x4c\x67\x64\x57\xfc\x94\xc6\x85\x61\x28\x23\x15\xd4"
-  "\x4f\x5a\xb1\xec\x7a\x17\x2c\x37\x8b\xb6\xd1\x17\x10\xac\x18\x38"
-  "\xf4\x31\x7e\xde\xf4\x12\xd6\x57\x7f\x5e\x5f\xa7\x20\x3c\xb8\x2f"
-  "\x23\x82\xd5\xae\x14\xb2\x39\x80\xb8\xb6\xd9\x02\xe5\x28\x87\xcb"
-  "\x03\x4d\x8f\x88\x77\x29\x8e\xf0\x08\x60\xf9\xd1\xe1\x5b\xea\xb9"
-  "\xbf\x53\x98\x9d\x2d\xe0\x58\xcc\x8e\x19\xe7\xe8\x9b\xfb\xdb\xf2"
-  "\x68\x73\x5d\xce\x16\xa3\xf0\xc1\x8a\x69\x84\x9d\x3f\x3b\x67\x18"
-  "\xcb\x18\xb1\xcd\xce\x76\xc1\x9d\x6a\x31\xdf\x98\x1b\x15\x3e\x9d"
-  "\x87\xa6\xbe\xd3\xd3\x0a\x52\x9f\xbe\x2d\x9e\xe6\x3c\xb0\x5e\x0e"
-  "\xb4\x71\x5c\x92\x9c\xa5\x31\xd8\x75\x67\xe0\x36\x55\x6f\x39\xe7"
-  "\x6f\x25\x53\xce\x3e\x14\xe6\x43\x11\xe3\x26\xfe\x66\xf7\xe3\x6f"
-  "\x10\x7f\x1e\xf1\x8d\xc8\xc1\xad\x88\xc1\xad\xa5\x9c\x6e\xc3\xa5"
-  "\x38\x26\xba\x4d\x15\x48\xc2\x36\xb1\x53\x1b\xcd\x76\xb1\xe1\x54"
-  "\x25\xda\x22\xfc\xbd\x7d\x33\x8d\x2d\x6e\x4d\x44\xfa\xb7\x88\x76"
-  "\x20\x18\xa0\xc0\xbe\x48\x34\x67\x96\x16\xe6\xed\xaa\xf3\x20\xce"
-  "\xb7\x2e\xed\x6a\xf1\x80\xfe\x0e\xaa\xfb\xad\x46\xaa\x8f\x07\x69"
-  "\x4f\xcf\xea\x16\xe6\x3e\xd1\xea\x03\x9a\x97\x46\x58\x45\x2e\xb0"
-  "\x65\x89\x71\x8a\xa5\x93\xe0\x49\xfc\xc0\xe4\xba\x0b\x1a\xe7\xba"
-  "\xf4\x5b\x15\x04\xeb\x03\x9a\x93\xa0\x31\x53\x70\xae\xe7\xd6\x03"
-  "\xd8\xc7\x1f\x20\x3f\xaa\x17\xe0\x56\xee\xa7\xf0\x44\x39\xf7\xd3"
-  "\x36\x74\x80\xeb\x83\x5b\x8f\x23\xbe\x5e\xc9\x1f\xc5\x10\x9d\xb5"
-  "\x27\x78\x38\x8e\x1a\xec\x29\x77\x03\xda\x62\x2e\x7e\x16\x1f\xdb"
-  "\x67\xe7\x10\xf3\x7e\xba\xd5\xab\xe2\xe5\x57\x72\x1f\x69\x1e\xf2"
-  "\x29\xcb\xb0\xad\x70\xdc\xeb\xc5\xb2\x6a\x22\x7d\x7d\x86\xf8\x92"
-  "\x95\x70\x4e\x9d\x7c\x22\x95\xcb\x4b\x47\x00\xe9\x12\xde\x5e\xa9"
-  "\x6a\xd1\x56\xb7\x15\x86\xb7\x55\x2a\xda\x2e\xb7\xb5\xe0\xaf\x13"
-  "\x7f\x0e\xf1\x1d\xfa\xbb\xad\x3e\xe4\xbd\x6f\xc4\x76\x1b\xea\x3f"
-  "\x7d\x8a\x68\x03\x0a\x43\x1c\x89\x37\xbe\x46\xfd\x32\x46\xfe\x7d"
-  "\xcf\x03\x85\x13\x1f\x53\x78\x00\x6d\x15\xa4\xed\x41\x8c\xd7\x52"
-  "\x1f\x25\xdf\x76\xa1\xf1\xe3\x3e\x4c\xe0\xb6\xcb\x7c\xce\x61\xd7"
-  "\x9e\x3d\xc4\x9f\x98\xe7\x90\xc6\xb7\x67\xcf\x88\x2d\x15\x64\x1a"
-  "\x62\xd8\x20\xc5\x47\xb7\x19\x52\xd3\xc6\x6d\x2b\xb4\x37\xa9\x7d"
-  "\x86\xe0\xf6\xc5\x28\x97\x50\x1e\x3f\x22\xce\xe7\xc3\xed\x77\xd3"
-  "\x37\xca\xc3\x2f\xf1\xdd\xd0\x83\x72\x67\xb4\xc9\x98\x31\xa6\x84"
-  "\x84\x51\x25\x18\x7d\x4d\x87\x73\x7d\xc9\x19\x59\xce\xc1\xa3\xd0"
-  "\xeb\xfb\x1b\xd0\xbf\xc0\x61\xcc\x21\x7f\x8a\x96\xed\xcc\xff\xd1"
-  "\xe8\x21\x1c\x7b\x5d\x74\x70\xbf\xc9\x70\x3b\xaf\xfb\x6b\x67\xc4"
-  "\xdd\x21\x67\xa5\x6f\xa6\x3d\x9c\xb6\xef\x39\xe6\xdb\x77\x96\x7c"
-  "\x2c\xe8\xa6\xbc\x3e\x0a\xe9\xef\xec\x00\x43\xeb\x28\xa4\xb6\x8d"
-  "\x42\x1a\xfb\x33\xdd\xad\x11\x28\x7a\xe6\xb2\x16\xb0\xdf\x17\x4d"
-  "\x33\x81\xba\x6d\x07\xda\x61\x3e\x50\xf8\x1b\xd1\x0e\xa3\x3b\x46"
-  "\x2e\xa6\x91\xfc\x1b\xb7\xc3\xc6\xc6\xc8\x0e\xcb\xe4\x3e\xf3\x50"
-  "\x6e\x1e\x9b\x5a\x0e\x8a\xc4\x12\xd0\x22\x7e\x96\x0b\x90\x5a\x91"
-  "\x38\x80\x36\x20\xd6\xd9\x25\xd5\x17\xe9\x5b\xab\x29\x87\x04\x5e"
-  "\x57\x94\xc9\xac\xf1\x91\xfe\x98\xba\x56\x49\xbc\xe3\xa1\xfe\x41"
-  "\x75\xd8\x45\x6b\x22\x47\x67\x78\x55\xd5\xad\xcc\x4b\xe1\x35\xb3"
-  "\x89\xf7\x6e\x2f\xa7\xb2\x3b\x31\x7c\xc4\x76\xbb\xdd\xa5\x4a\x4f"
-  "\x89\x25\x87\x35\xbb\x64\x7b\xe0\x8e\x24\xa6\xb4\x22\x2f\x2e\xb2"
-  "\xee\xf4\x31\xb7\xf3\x02\xf5\xcd\x3b\xb4\xf9\x1b\x99\x4f\x5f\x49"
-  "\xeb\x53\x77\x00\xad\x9d\xd1\x9c\xf9\xaf\xd1\x76\xf9\xa6\xf5\x32"
-  "\xd2\x09\xac\x71\x91\x5d\xb3\x11\x61\xa2\xfd\xcf\x2c\x69\x51\xce"
-  "\xcb\x47\xb7\xc7\x69\xad\xf5\x0d\xbe\xae\x7b\x47\xae\x0b\x0a\xbc"
-  "\x92\xdf\xc4\x21\x21\x1f\xff\x2a\x9d\xc6\xf9\xe1\xfd\xfa\xaf\x80"
-  "\xce\xff\x0f\xdb\x8d\x5d\x8e\x9b\x49\x96\xdf\x71\x55\xd8\x36\x46"
-  "\x87\x90\xed\x77\xfc\x9b\x98\xa3\xbb\x03\xf5\xff\x3d\x89\x04\xcf"
-  "\x74\x2b\xf1\xc4\x1d\xa7\x58\xb2\xf1\x04\xa5\x9b\x67\x05\xeb\x26"
-  "\x1f\xe0\x98\xc2\xe8\x60\xbc\x5f\x5c\x00\xf6\xd6\x8b\x23\xb4\x26"
-  "\xeb\xb9\x71\xed\x08\xea\xfa\x74\x8c\xeb\xa2\x32\xdc\x98\x06\xe9"
-  "\x3e\x59\xac\xad\xdd\xe1\x76\xc1\xe2\xa5\x82\xdf\xef\xe8\x12\x73"
-  "\x47\x77\x74\x0d\x63\x5e\xb4\xfd\xa6\x8f\xd8\xfe\x4a\xeb\x82\xbc"
-  "\x6e\xc9\xfe\xe4\x6b\xda\x18\x96\xea\x82\x7c\x3e\x9f\x52\x33\x1b"
-  "\x74\x35\x7a\x36\x18\xd3\x76\x0b\xab\x67\xda\x2f\xf9\xba\xb3\x12"
-  "\x6e\x44\x18\xe5\x32\x5c\xd4\x9f\xbf\x1a\x56\x3e\xf6\x18\x86\xd5"
-  "\xca\x70\x31\xcd\xf5\xf8\xbd\x77\x3c\x8d\xc8\xd3\x1a\x92\xe7\xb1"
-  "\x61\xe5\x9d\xbf\xc2\xb0\xce\x88\x3c\x8e\x88\x3c\x7d\x21\x79\xac"
-  "\x52\x39\x03\x11\x79\x3c\xe1\x79\xd2\x54\x13\x71\x4b\xd3\x85\xe7"
-  "\x49\x4b\x8b\xc8\x93\x31\x11\xb7\xb4\xdc\x88\x3c\xeb\x22\xf2\x6c"
-  "\x0c\xa1\x2d\xad\x2f\x1b\x30\xcc\x1a\x91\xc7\x1e\x91\xa7\x43\xfe"
-  "\x46\x5b\xd2\x21\x74\x3d\xf2\x13\xb6\x29\xb6\x6b\x17\xc6\x63\xfd"
-  "\x33\xd2\xaf\xb5\x0f\x00\x79\xe6\xb8\xe5\x80\xf0\x3f\x4d\x32\x94"
-  "\xc6\x14\x24\xb7\x51\xde\xd3\x7c\x3d\xf7\x25\x47\x65\x9d\x85\x39"
-  "\xe7\x89\x87\x46\x6c\x73\x52\x26\xd2\x63\x4e\x5a\x38\x9e\x73\x32"
-  "\xc2\xf1\x9c\x93\x3d\x91\x1e\x73\xd6\x45\xe4\xd9\x18\x91\xa7\x36"
-  "\x24\x4f\x87\x54\x8e\x3d\x22\x4f\x47\x44\x9e\xce\x89\xfc\x39\xa7"
-  "\x2b\x22\xcf\xa9\x88\x3c\x03\x41\x1a\xce\xe1\x7b\x3a\xa8\x3f\x60"
-  "\x38\x7e\xdf\x73\xad\x7d\x18\x5a\x99\x9f\xe5\xfd\x18\x82\xaf\xef"
-  "\xdc\xd5\x2c\xf6\x25\x70\xdf\x1f\x03\x70\xe7\x9b\x20\xfc\x67\xb9"
-  "\xdf\x1f\xf5\xc6\x93\xce\x45\xda\x0e\x9e\x30\x7b\xd1\xc6\xbc\xb3"
-  "\xc4\x05\x86\x8d\xf2\xda\x27\xad\x17\x73\x5f\x51\x7c\x7c\x71\xa7"
-  "\x51\xf4\xbf\x3b\x9b\xa5\x39\x59\xaa\x0f\x8e\x1b\xee\x6c\xfe\x3f"
-  "\xc3\xeb\xae\xbb\x09\x2f\xf2\x9d\x82\x30\xfa\xc7\xc7\x0e\xe3\xb8"
-  "\x52\x99\x77\xc9\xbe\x2e\xdd\xed\x62\xcd\x9a\xfc\xf4\xb8\xc9\x8f"
-  "\xcd\x88\xed\xae\xc4\x90\xf1\x06\xe1\xea\x39\xba\xc3\xab\x8a\xc0"
-  "\x79\x48\xe0\x7c\x97\x51\xc8\xa8\xbb\x8c\xb2\x3c\x89\xc9\x7f\x76"
-  "\x4b\x79\x2f\xda\x7c\xb4\x4e\xd7\xd3\x8a\xf6\x23\x8e\x99\x08\xef"
-  "\x33\x70\xd7\x1e\x6e\xcf\x56\x8e\x02\xbd\x3b\x6b\x97\xf0\x75\x3c"
-  "\xa9\x2e\x0e\xf2\x57\x4e\x76\x4a\x97\xe9\x12\x0c\xf3\x31\x17\xc9"
-  "\xc6\xbb\xce\x9f\xa8\x75\x13\xae\xc7\xe4\xf5\x6d\xc4\x85\xe3\x34"
-  "\x6c\xb7\x94\xd0\x1a\x23\xcd\xcb\x9f\xf0\x64\x50\x9a\xd3\x48\xdb"
-  "\x0e\x99\x06\xe4\xfb\x1c\xd3\x36\xc7\x1a\xfb\x84\xd2\x55\xe0\x30"
-  "\xef\x49\xc1\x3f\xe9\xa9\xe1\xfd\x21\x1e\xf9\x34\x3d\x23\x9c\xe7"
-  "\xd2\xb3\xc3\x79\x2e\xbd\x28\xbc\x3f\x28\xb1\x3f\xa4\x6f\x8c\xc8"
-  "\x53\x1b\x91\x67\x6f\x48\x1e\xbb\x54\x4e\x47\x44\x9e\xce\x88\x3c"
-  "\xa1\xf2\x0f\xeb\x9c\xde\x37\x3e\x8e\xe4\xf2\x3e\xdd\x15\xf2\xad"
-  "\x6c\xe6\x7a\x2a\xdd\x23\x87\xd1\xba\x27\xda\x9d\x7c\x2d\x5f\xc0"
-  "\x9b\xab\x8d\x90\x51\x98\x7e\x6e\x6a\x38\x0e\x73\x17\x87\xe3\x30"
-  "\x37\x4b\xfe\x6e\x10\xe3\xe0\xdf\x9e\x85\xb9\xaf\x4a\x7c\xe6\xd1"
-  "\xec\x82\x47\x35\xbe\xd5\x4f\x92\x1d\x46\xfa\x89\xef\xb1\xd8\x89"
-  "\xb6\xe3\x65\xd0\xd2\xde\x96\xb3\x35\x10\x47\xfe\x94\x5c\x30\xcf"
-  "\x8e\xe3\x33\xf2\x8b\x3c\x84\xf6\x54\x3e\xc2\x28\xc4\xf2\x5b\xb0"
-  "\x0c\xa4\xdd\xdc\x43\x11\x38\x1c\x8b\xc0\xe1\x64\xc8\xb7\x16\xbf"
-  "\xfb\x43\xea\xad\x8d\xd3\xf1\x3d\x50\x68\x33\xcf\x75\xcb\xe1\x34"
-  "\xa6\xc7\x3a\x0e\x5a\xb8\x1d\x60\xa4\x7d\x2d\xc9\x67\x60\xee\x17"
-  "\x64\x07\x0b\x98\xf3\x66\x86\xd2\x56\xd0\x62\x9e\x21\x1c\x8f\x79"
-  "\xc6\x70\x3c\xe6\x15\x04\x65\xcd\xdc\x42\xd1\x47\xe6\x95\xa2\x8c"
-  "\xe6\xfe\x8b\x90\x16\x7a\x8d\x4f\x3f\xdd\x71\x2b\xd9\xa4\xf3\x5e"
-  "\xf5\x60\x7d\xd9\x4f\x94\xc9\xd2\xb7\xb8\xe3\xe3\x56\x9a\xff\xb7"
-  "\x98\x63\xf1\xe8\x70\xb2\xc5\x24\xed\x4d\xd2\x23\x6c\x87\xcc\xe3"
-  "\x81\x26\x8b\x29\xd0\xf8\xb0\x15\xc3\x50\xfe\xdd\xe5\x15\x63\x8f"
-  "\x9c\x6e\xe4\xe7\x16\x6c\x13\x1c\xa7\xce\xff\x4c\x1a\xd7\x91\x4f"
-  "\x3d\xda\x27\x41\x7e\xd8\x12\xc5\x9a\xe6\x7c\x75\x48\x5f\xf1\xe8"
-  "\x77\x3c\xc0\xce\xc0\xfc\x1e\xb2\xd7\x48\x16\xd0\xbe\x97\x13\x3e"
-  "\x37\xd0\x5c\x88\xd3\x77\x8e\xdb\xd4\x18\xdf\x2d\xe5\xcd\x0a\xc9"
-  "\xeb\x96\xe6\x2a\x06\x29\x6e\xbe\x0f\x54\x27\x3c\x6e\xf2\x37\x9d"
-  "\x22\xec\xf0\xf9\x3d\x27\x50\x06\x60\x1e\xb3\x9c\x87\xe6\x35\xa4"
-  "\xf1\x88\x6a\x5e\xad\xb8\x6f\x8f\x60\x83\xf0\xc9\x37\x88\xe3\x99"
-  "\x21\x67\xed\x20\x38\x3d\xfd\x34\xbf\xa8\x12\xfb\x07\xe6\x77\xc7"
-  "\x79\x41\x3d\xdc\x68\x41\xf9\x3a\xbf\xdb\xdf\x68\x29\x47\xdc\x50"
-  "\x97\xce\xe3\x72\x2d\x94\x76\x2b\x57\x16\xac\xce\xcf\x9b\xfb\xc4"
-  "\xea\x9c\xc2\x95\x4b\xf4\x85\x15\x2f\x95\x95\xce\xdd\xb4\xa5\x46"
-  "\xbf\xad\xaa\xa2\xa6\xa2\xf2\x79\xee\x22\x4f\xbf\xbe\x46\x3c\xd3"
-  "\x36\xae\xaf\xae\x59\x46\xaf\xe9\x7a\x53\x55\xd9\x56\xfe\x3a\x67"
-  "\x0a\x84\x03\xa9\xa8\x29\xab\xd2\xdf\x5e\x9a\xae\x7f\x70\x7d\xc5"
-  "\xc6\x2d\x55\x65\x51\x61\x2d\xd1\x57\x95\x55\x95\xad\x2f\xd5\x2f"
-  "\xd3\x1b\x08\x72\x28\xb8\x90\xf6\x34\xc8\x32\xa7\x1a\x75\x34\xda"
-  "\xc5\x83\x24\x7b\x48\x57\x9f\x85\x85\x1f\x93\x5d\xc6\x7d\xda\x21"
-  "\x6f\xa1\x9c\xc7\x71\xb6\xa1\x73\xa2\x6e\x36\x44\xe8\x3f\x43\x84"
-  "\xfe\x33\x0c\x4c\xd4\xcd\x06\x6f\x78\x9e\x05\xea\xf0\x3c\x0b\x74"
-  "\x13\x75\xf3\x82\xf4\x88\x3c\x4b\x23\xf2\xe4\x8e\xcb\x0e\xc4\x75"
-  "\x37\x97\x35\x0b\x4a\x22\xf2\x98\x22\xf2\x58\x23\xbe\x43\xed\x1f"
-  "\xb4\x47\x17\x74\x84\xea\x7b\xfc\xee\x94\xfb\x6f\x50\x66\x2d\xe8"
-  "\x92\xd3\x90\x3e\x69\xa7\xbb\x33\x44\xda\xd3\x21\x69\x07\xa5\xb4"
-  "\xee\x71\x59\xb5\x9f\x8f\x99\x07\x85\xcd\xbd\x70\xbd\x24\xaf\xe8"
-  "\x2e\x0d\x59\x2f\x0e\x60\x5b\xdc\x72\x01\x16\xf4\xb4\x8b\xb4\x6e"
-  "\x3e\x37\xfc\xd6\xda\x91\xf6\x64\x50\x53\x5e\xf2\xe9\xc6\x6c\xf3"
-  "\xb9\xef\x40\x0c\x4b\xc4\x1f\xca\x9e\x85\x85\x38\x86\x19\xa0\x32"
-  "\x68\x3d\xd2\x05\x0b\x39\x2f\x53\xbe\x7a\xbe\xff\x85\x97\xd7\x43"
-  "\x77\x82\x90\x9f\x44\x92\x89\x54\x2e\xf9\x1a\xa4\xb2\x11\x86\x8a"
-  "\x29\x0d\xb3\x24\x9f\x71\x5a\xfc\xa5\x20\xcc\x43\x32\x4c\x84\xc7"
-  "\xe5\xca\x6e\x69\x6f\xa7\xb0\x65\x16\x9e\x94\x6d\x06\xb2\xff\xa3"
-  "\xc9\x8e\xe8\xfb\x01\x41\xd3\x60\x0b\xf4\x3b\xea\x06\x08\x27\x2f"
-  "\xd9\x96\x4e\x9d\x0f\x7a\x5b\x7d\x38\x26\x05\x2d\x1f\x23\x99\xcf"
-  "\x83\xb3\xc3\xc7\xd7\x51\x8a\xcd\x60\x6d\x57\x06\xfa\xd9\x78\x3e"
-  "\x1a\x77\x2d\xe2\x6b\xca\xf5\x14\x8e\xf9\x71\x7c\xe0\xa6\x7d\x83"
-  "\xb1\xee\xa5\xa1\x74\x8e\x5b\x69\x0c\xb7\xa8\x5c\xb2\x67\xf7\xb4"
-  "\x23\xac\xa8\x7b\xda\x94\xe0\x1c\xb1\x2d\x3a\xe8\x82\xa7\xec\xb2"
-  "\x1c\x3e\xd1\xc2\x65\x9f\x12\xc3\x8f\x23\x2d\x86\x62\xd9\x1e\x92"
-  "\xcc\x26\xdf\x67\x09\x98\x76\xf0\x5a\x69\x09\xef\x13\x58\x6f\xec"
-  "\x8b\x27\xdf\xaf\x33\xc4\x4b\xf2\x15\xc7\xfd\x8b\xf5\x72\xbe\x6f"
-  "\x53\x3f\x69\xdf\xad\x1b\xfb\xaa\x47\x8c\xff\xee\x7e\xf3\x0d\xbe"
-  "\x4f\x6e\x31\x8e\x7f\x16\xed\x95\xea\x70\x1d\x7e\xa3\xfc\x5b\xc4"
-  "\xf7\xef\xd2\x9a\x38\x8d\x93\xab\x4d\x68\x87\xe9\x3c\x28\x1b\x17"
-  "\x37\xcb\x71\x7c\xde\x98\xe2\x6a\x99\xf7\x84\x6e\x80\xe2\x3a\xc7"
-  "\xe3\x28\x1f\xe1\x6d\xf6\x51\xf8\x49\x39\x5c\xd8\x01\x8b\xfb\x23"
-  "\xbe\x07\xe5\x6f\x7c\x47\xfd\xbf\x68\x9d\x04\xdf\x8d\x32\x97\xf6"
-  "\x21\x28\xce\xc0\xdd\x8f\xb5\xf1\x7e\x73\x77\x8a\x1c\xcf\xe7\xbe"
-  "\xde\xc3\xf1\xb5\xcf\x03\x81\x64\xe3\x49\x6e\x47\x61\x1e\xba\x63"
-  "\x06\xc7\x0d\x0a\x36\xc6\xf7\x44\x0c\x11\x1c\xea\x33\xfc\x9e\x07"
-  "\xfc\x46\x58\x34\x3f\xef\x26\x1e\xd9\xe6\x83\x99\xa6\xfb\x69\x8e"
-  "\xf8\x6e\xce\xb7\x14\x46\x70\x09\x9e\xc5\x27\x60\x13\x3c\xba\x0b"
-  "\x87\x0d\x97\x23\xae\x77\x53\xfd\x4f\xc6\x6a\x2b\x8c\x3f\x1a\x42"
-  "\xcb\x78\xfc\xee\x0a\xaf\xeb\xdd\xa7\x22\xbe\x07\xe4\x6f\x9a\x8f"
-  "\x15\xbc\x77\x77\xbf\x88\xbb\x07\xae\x55\x16\x8d\x69\x31\x4d\x6a"
-  "\x78\x79\xf7\x2c\x0e\x87\x7f\x4f\x56\xc4\x77\xa1\xfc\xdd\xcc\xd7"
-  "\x01\xee\x29\x95\xcb\x10\xf3\x71\xc6\x93\x07\xeb\xdc\xf1\xdf\x8e"
-  "\x7f\xee\xfd\x44\xf0\xcf\x3d\x87\x42\x70\x98\x84\xdf\xc7\x82\xed"
-  "\x79\x4f\x97\x0c\x1f\xdf\xfb\x42\xd2\x61\x1f\xb9\xc7\x15\xc9\x2f"
-  "\xd5\x66\xe2\x33\xe2\x99\x7b\x7c\x51\xe2\xbc\x22\xee\x5e\x5d\x74"
-  "\x3e\xbb\xd7\x10\x12\x2e\x8d\x3b\xee\x7d\x53\xd2\xd5\x24\x23\x3d"
-  "\x74\xd7\x8e\xe4\xef\x97\xf3\x05\xf9\x01\x95\xee\xff\x40\xde\xba"
-  "\xd7\x14\x09\x97\xee\x6c\x18\x87\x11\x84\x29\x8d\x2f\xee\xed\x08"
-  "\xd6\xed\xde\x23\x2e\xb8\xbb\x43\xe6\x5b\x31\xe7\x76\x4f\x6b\x2c"
-  "\x7b\x1e\xd3\x9f\x0e\xa7\xd9\xbd\x43\x41\x9a\xdd\xeb\x0d\xc2\xcd"
-  "\x50\x85\xa4\xfb\xef\xf8\x9d\x12\x4c\x97\xa1\xff\x26\xfe\x10\x7b"
-  "\xfd\x33\xb2\xc3\xcb\xca\x28\x0a\x81\x51\x1a\x52\x96\x29\x24\x5d"
-  "\x3f\x7e\x5b\x63\xb7\x4f\x46\x6b\xec\xf6\xc9\x38\x16\xbd\x7d\x32"
-  "\xfa\x42\xca\x3d\xfd\xcd\xbc\x7d\x1f\x84\xe0\xd3\x8e\xdf\xda\x70"
-  "\x5e\xbe\x4f\x1f\xf1\x3d\xde\xfe\x0c\xfb\xef\xc1\x1d\xc6\x78\x0a"
-  "\xaf\x99\x0d\x5a\xc1\xeb\xf7\x15\x84\xc6\x7f\x34\x2a\xe2\x09\x47"
-  "\xbe\x56\x45\xeb\x80\x22\x9d\x39\x32\x1d\xa5\x09\x89\x6f\x91\x71"
-  "\xaf\x8f\xe1\x9b\x56\xd6\x41\xce\x00\xe9\xa0\xfb\x8e\x8a\xf5\x8d"
-  "\xe5\xd8\xc7\x3f\x2d\x8a\xa5\x4f\x10\x2e\xea\xff\xfb\x0e\x09\xfa"
-  "\xdc\x87\xfc\xff\x28\x5f\x4f\x65\xf6\xe5\x74\x87\xde\xe8\x59\x58"
-  "\x42\x7b\xc2\xc6\xf0\xb9\x3d\x5c\xc7\x2d\x49\x61\x36\xc5\x9a\x76"
-  "\x5b\xa4\xee\x5b\x92\x8e\x36\xfd\xa8\xc6\x67\x2d\x8a\x12\x97\xcd"
-  "\x6c\x71\xab\xa3\x84\xd3\x5e\x85\x51\x17\x2c\x69\x26\x7c\x43\xc2"
-  "\xcd\xcc\x36\xad\x90\xd2\xbb\xa8\x3c\xcc\x13\xab\xdd\xe4\xfd\xef"
-  "\x82\xf7\x96\x74\x45\xd4\xe3\xea\x59\xf8\xf1\x72\x51\x8f\x1f\x1f"
-  "\x88\x28\xfb\x74\x8c\x7a\xd0\x38\xed\x6a\xf4\x7a\xfc\x58\xcb\x69"
-  "\xab\xc4\xba\x4c\xd0\xfd\x3f\x4e\xc7\xba\x5c\xe5\x74\x0f\x0f\xcf"
-  "\x92\xc7\x7f\x96\xab\x38\xae\x56\x02\xcf\xbb\xa6\x36\xd8\x6e\x52"
-  "\xba\x8d\x9a\x16\x28\x88\x52\x66\x3d\xb3\x25\xac\x71\xc1\x8f\x8f"
-  "\xcb\x3a\x43\x0a\x6f\x15\xb8\x20\x9d\x94\x9c\x4e\xa7\x29\x5f\xac"
-  "\xf6\x96\xfb\xa7\x58\x93\xf9\x31\xf6\xff\x25\xb2\xfc\xf0\xa0\x4e"
-  "\x75\xcb\x74\x1c\xb1\x2d\x55\x47\xc4\x79\x43\xe2\x52\xc3\xe2\x76"
-  "\x8e\x87\x2f\x95\xc3\xbf\x5d\x3b\x2d\xdd\x18\xd1\x4e\xd8\x3e\x4b"
-  "\xfd\xe1\xf5\x5e\x5a\x2b\xea\x87\x6d\x34\x81\xd6\x4b\x5b\xb0\x8d"
-  "\xc6\xa2\xb7\xd1\xd2\xa3\xd1\x79\x6d\xa9\xb0\x3d\x93\x21\x1a\xbc"
-  "\x41\x6c\xbb\x31\xce\x83\x52\x3b\x4d\x6c\x9f\x65\x89\x72\xfb\x7c"
-  "\xbb\x3a\x2e\x2b\x88\xa8\xa3\x1f\x61\xf4\x88\xba\xde\x3f\x2b\x02"
-  "\x76\x79\x74\x5e\x5c\x66\xc5\x7a\xfa\xa3\xd7\x73\x59\x6b\x6c\x5e"
-  "\x5c\x46\xf7\xe8\xf8\x27\xf2\xe2\x32\xf9\xce\xea\x68\x79\x86\x98"
-  "\x2d\x5a\x39\xf7\xab\xc8\x36\x71\xc1\xfd\x4b\x69\x9d\x2b\x24\x7c"
-  "\x66\x38\xff\x61\x1d\x28\x1f\xd1\xcf\x27\xc6\x12\xd4\x0e\x67\xf5"
-  "\xa0\xfc\x26\x9e\x1c\xb1\xdd\x5f\x1b\x41\xab\x8b\x08\xdf\x3f\xac"
-  "\x54\x3e\x28\xe8\xf5\xc0\x67\x11\x38\xb5\x44\xa7\xd7\xfd\x9d\x48"
-  "\xaf\x8b\xd1\xe9\x75\x7f\x77\x6c\x7a\xdd\x4f\xed\x7f\x71\x22\xbd"
-  "\x1e\x80\x50\x7a\xd1\x1d\x81\x54\xbf\xdb\x74\xc8\x1b\x63\xc5\xac"
-  "\x5d\xc8\x72\xad\x06\x79\x45\xe4\x19\xa2\x3c\x8b\x35\x5e\xc1\x27"
-  "\xfa\x19\xa0\xbe\x00\x0f\xcc\x94\xfb\xff\xb4\x16\x48\x60\x63\x6b"
-  "\x19\xdd\xef\x43\xf9\x9c\xe6\x8b\x0e\xba\x9b\x8c\xe6\xf1\x22\xca"
-  "\x35\x47\x97\x05\x0f\xd8\x91\xa6\x4d\x51\xc2\x0f\x89\xb9\xc8\x07"
-  "\x5c\xe1\x32\xe2\x01\x47\x78\x1b\x21\xdd\x94\xdc\xbb\xae\xe2\xdb"
-  "\xfc\xae\xdd\x66\x46\xc3\xc4\x36\x33\xfe\x41\xb4\x97\xf1\xe3\x70"
-  "\xfc\x8c\xd9\xd1\xdb\xcb\x58\x12\xbb\xbd\x8c\xb5\xb1\xdb\xcb\xd8"
-  "\x42\xed\xe5\x02\x63\x5f\xb8\xde\x30\x76\x86\xd7\x17\xcb\xc5\x7c"
-  "\x4c\x39\x69\x3a\x7d\x7f\xdb\x7a\xcb\x3f\x92\x71\xd4\x56\xed\x68"
-  "\x5f\x21\xfe\xb3\x09\xc7\xef\x0a\x23\x26\x6c\xa4\xa1\x7d\x47\x4c"
-  "\x3f\xf6\x89\xbd\x2d\x74\xdf\x3a\xbf\x33\x52\x71\x16\x96\x7f\x10"
-  "\x50\x2a\x96\xe0\xbb\xf2\x2c\x64\x6e\x0e\x28\xe3\xac\x74\x9e\x84"
-  "\x9f\x23\xe1\xf3\xfe\xcb\x8f\x87\xb6\x05\xed\x1f\xa6\x39\xde\x7d"
-  "\x62\xfe\xf0\x8f\x67\x61\xc5\x4a\xd1\x2e\x99\x8f\x86\xd3\x71\xb9"
-  "\x2b\x7a\xbb\x2c\xf7\x62\xbb\xfc\x31\x7a\xbb\xac\x48\x89\xdd\x2e"
-  "\x2b\xe8\xec\xd9\x1f\x27\xf6\xa3\x15\xd9\x52\x3f\xda\x4d\x79\xf4"
-  "\x95\x64\xaf\xae\xf8\x2f\x94\x06\xdf\xb1\x8f\xac\xe0\x77\x7b\xcc"
-  "\x1d\x92\xfb\x11\xcf\x53\x8b\xb0\x78\xf9\x52\x1a\xb3\x04\x23\x14"
-  "\x6e\x87\x66\x28\x5a\x3f\x59\xc1\xef\x64\x9e\x67\x02\x35\xd2\xb0"
-  "\xe8\x00\xc1\xa8\x02\xb8\x00\x99\x53\x29\x1d\x85\x93\x4f\xf0\x90"
-  "\xf4\x83\x72\x3a\x92\x75\x22\xed\x0a\x17\xdd\x9f\x4b\xe9\xc2\x61"
-  "\x67\x4a\xf5\x4f\xe0\x7a\x84\xd2\xf3\xfb\x7a\xc3\xd3\x64\x88\xfe"
-  "\x98\x59\x1b\xde\x1f\x33\x0b\xc2\xf9\x13\xe9\x8f\xf9\x02\x28\xe7"
-  "\xf0\xfd\xa0\xdf\xa6\x58\xf2\xfd\xf4\xcd\xcc\xee\x88\xbe\x89\x3c"
-  "\x90\xf5\x92\xe0\x81\xac\xbc\x08\x5c\x07\xa2\xf3\x40\xa6\x2f\x36"
-  "\x0f\x64\xe9\x62\xf3\x40\xd6\x62\xe2\x01\x17\x64\x6d\x0c\xef\x9b"
-  "\x59\xb9\xe1\x75\xc7\x72\x79\xdf\x84\xa4\xef\xd2\x37\xd1\x16\x9a"
-  "\x1e\xab\x1f\x4a\xf6\xbf\x82\xee\xf5\xf9\x0e\x34\x13\xf7\x54\xc0"
-  "\x4a\xa0\xb5\x19\x94\xf1\xe5\x44\xc3\x36\x3e\x46\x5b\x99\x12\x4a"
-  "\xc7\x7d\x62\xac\x65\xc1\xb4\x6f\xd3\xde\x36\x41\xcf\x07\xd7\x87"
-  "\xd7\x7f\xe5\xe2\xe8\xf4\x5c\x99\x8b\xf4\xb4\x44\xa7\xe7\xca\xf2"
-  "\xd8\xf4\x5c\x59\x4f\x67\x14\x27\xf6\xa9\x95\x74\x37\x99\x5a\xd6"
-  "\x4d\x17\x60\xe5\xe5\x6f\xa7\x9f\x56\x9e\x0a\xd7\x4f\x2b\x8f\x7f"
-  "\x77\xfd\xf4\xa0\x2e\xba\x7e\x7a\xd0\x10\x5d\x3f\x3d\x98\x2d\xfa"
-  "\xc3\x83\xd6\xf0\xfe\xf0\x60\x49\x38\x4f\x20\xed\xbe\x37\xfd\xf4"
-  "\x60\x5f\x44\x1f\x68\x38\x0b\x0f\x3d\x8a\x36\xc5\x2b\xa2\xdd\xb2"
-  "\xaf\x8f\xc0\x71\x28\x7a\xbb\x3d\xa4\xc2\x76\x6b\x88\xde\x6e\x0f"
-  "\xe9\x63\xb7\xdb\x43\x4b\xb1\xdd\x1a\x26\xb6\xdb\x43\x85\xdf\xdd"
-  "\xa6\x78\x68\x4f\x78\x9b\x3d\x64\xfa\xee\x6d\xf6\x50\x77\xf4\x36"
-  "\x7b\x68\x20\x7a\x9b\x3d\x24\x9d\xf9\xcf\x5e\x1c\xde\x66\xd9\x29"
-  "\xe1\x6d\x86\x74\xfb\xde\xda\x2c\xbb\x3e\xa2\xcd\x36\x9d\x85\x1c"
-  "\x1c\x37\x2b\xfb\x44\x9b\xe5\xfc\x3e\x1c\xc7\xec\x8e\xe8\x6d\x96"
-  "\x7d\x0c\xdb\x6c\x53\xf4\x36\xcb\x3e\x15\xbb\xcd\xb2\xdd\xd8\x66"
-  "\x9b\x26\xb6\x59\x8e\xfa\xbb\xb7\x59\xce\xd2\xf0\x36\xcb\x49\xfd"
-  "\xee\x6d\x96\x63\x8d\xde\x66\x39\x2d\xd1\xdb\x2c\xa7\x53\xb4\x59"
-  "\xce\x60\x78\x9b\xe5\x9c\x0c\x6f\x33\xa4\xdb\x7f\xb0\xcd\x98\x7d"
-  "\x85\x74\xb6\xf2\xe1\x9c\x61\x3e\xaf\xfc\xb0\xd1\x05\x8f\xa8\xc5"
-  "\xbc\xfc\xc3\x9c\x77\xa4\x36\xfc\x08\xd3\x2c\x9e\xa8\xbb\x1f\x5e"
-  "\x27\x85\x3d\x31\xb1\x1d\x1e\x36\xa3\x5e\x1d\xea\xaa\xe5\xfb\xa5"
-  "\x44\x1b\x12\xcd\x31\x9d\x98\x23\x7b\xb8\x85\xf2\x62\x1b\x33\xa7"
-  "\xd7\x07\xa4\x8b\x31\xbd\x87\xe0\xd0\x79\xfa\x08\x58\x5d\xdf\xc5"
-  "\x2e\x8b\xbd\x17\x7b\x05\x38\xea\x16\x22\xbc\x47\xfe\x4d\xf0\xea"
-  "\x23\x91\xf6\x6f\x3b\xc6\x7d\x28\xf8\x34\x2f\x62\xce\xe4\x91\x18"
-  "\xf6\xef\x23\x64\xff\xb6\x47\xe7\xd3\x47\xae\x61\xff\x3e\x42\xf6"
-  "\x6f\x7b\xc8\x78\x35\xf9\x19\x9f\x2b\x62\xbc\xfa\xc8\x71\x8d\x47"
-  "\xf0\x0e\xb7\x63\x1b\x57\x00\xe2\x3c\x10\x81\x33\xb6\x4d\xee\x7a"
-  "\x09\xe7\x27\x23\xf2\xfb\xa2\xe3\x9c\x9b\x82\x38\x7f\x14\x1d\xe7"
-  "\x5c\x43\x6c\x9c\x73\x73\x11\xe7\x8f\x26\xf6\xad\xdc\x52\x89\x0f"
-  "\xa2\x8c\xcb\x73\xad\xd1\xdb\x3f\x37\xa2\xfd\xa1\xa8\xa6\x96\xb9"
-  "\x79\xfe\xf0\x74\x8e\xd0\x74\xb4\xa7\x9d\xd2\x12\x8f\x44\x49\x3b"
-  "\x14\x09\x33\x7a\xba\xbc\x94\x09\xbc\x47\x7b\xf0\xa3\xf2\x5e\x9e"
-  "\x51\xf4\xc7\xbc\x96\xf0\xfe\x98\x57\x14\xde\x1f\x1f\x89\xa0\x49"
-  "\x9e\x39\x22\x3e\xfb\xfb\x93\xb1\x79\x83\x11\x3c\xf0\xe9\x59\x58"
-  "\x55\x26\x78\x60\xd5\x27\xe1\x78\xac\x82\xe8\x3c\xb0\x4a\x87\xf5"
-  "\xff\x34\x3a\x0f\xac\x5a\x1c\x9b\x07\x56\x15\x20\x2d\x3f\x0d\xe5"
-  "\xdb\x35\xb5\xc6\x84\x88\x34\x35\xd1\x65\xde\xaa\xbd\xd1\xe7\x75"
-  "\x56\x1d\x14\x34\x5e\x75\x3a\x9c\xc6\xab\x8e\x87\xd3\x70\x15\x7c"
-  "\x0f\x34\x1c\xf7\x47\x33\x62\xcb\x8f\xec\xff\xce\xb3\x90\x2f\xf5"
-  "\xff\x82\x0f\xc2\x71\xcc\x97\xc6\x3f\xd1\xe6\xb2\xf2\x4b\x91\x96"
-  "\xce\xe8\xb4\xcc\xb7\x46\xaf\x73\x7e\x0b\xea\x20\x67\x60\x42\x5f"
-  "\xca\xef\xc4\xf0\x35\xfc\xae\xb1\xab\xa0\x6d\xc3\xf0\x35\x3e\x50"
-  "\x73\x7d\x35\xae\x97\xf2\x4f\xd1\x1c\x39\x9f\x63\x46\xfe\xd5\xcc"
-  "\x84\x02\xd2\x41\x84\x57\x71\x6d\xe4\xba\x24\x77\x65\xc0\xcf\x9c"
-  "\xd2\xf9\x13\x8d\x19\x0a\x9c\x1e\x1f\xc8\xfc\x4e\xe9\xc3\x61\x17"
-  "\x18\xa8\x5f\x50\x7a\x39\xad\x98\xeb\xb4\x46\xc8\xa6\x82\xa2\xe8"
-  "\x6d\x5c\x60\x8a\xcd\x3b\x05\x7b\x45\x3b\x17\x38\xc2\xdb\xb9\xe0"
-  "\x60\xc0\x36\xad\x90\xea\xea\x42\x3a\x7f\x97\x36\xa6\xf5\xcb\x98"
-  "\xf2\x7e\xf7\xda\x7e\x53\x1d\xdc\x7c\x0e\x1e\x4d\xe3\xe5\x29\x19"
-  "\x8e\x89\x15\xd0\xc5\x65\xc0\xa3\x3b\x39\x9e\x98\xa6\xd8\x07\x4a"
-  "\xb6\xfb\xc5\x7e\x8a\x6b\xb7\x31\x2f\xbf\x4b\xcd\xc6\xfa\xc8\x1f"
-  "\x05\xf2\xc2\xf4\x33\xf0\xe8\xf2\xb0\xfc\x2a\x00\xa7\x80\x51\x2b"
-  "\xe6\xf7\x1f\x35\xcb\xf3\xf0\xb1\xe6\xf7\x31\x4d\xab\xbc\x9f\x56"
-  "\xac\x85\x3d\x6a\x8f\xa9\x97\x11\x27\x3a\x87\x49\x38\x5d\x5b\x0e"
-  "\x3c\xea\x96\xf9\x57\x9c\xd1\x59\x0d\xc1\x33\x20\xab\x13\x31\xee"
-  "\xe8\x35\xe6\x73\x43\xfa\xc1\xea\x8c\x50\x38\xc2\x27\xd3\xea\x5c"
-  "\xf9\x1c\x07\xbe\x17\x7d\x03\x2c\x09\x9f\xd5\xd6\x08\x7c\xec\x68"
-  "\x5b\x1e\x95\x60\xb4\x7e\x03\x8c\x14\xe7\xc1\x25\x30\x2f\x00\x71"
-  "\xe7\xa0\xf0\xab\x66\xda\x27\xd3\x3a\x08\x89\x3e\x50\x89\xb1\xdd"
-  "\xea\xaf\x7b\x74\x34\x87\x43\xe7\x73\x1f\x70\xd0\x1a\x1c\x5f\xc7"
-  "\xd7\x3d\xe0\xe8\x31\xfb\x25\xdf\x3b\x6b\x38\x4f\xf4\x94\x5f\x74"
-  "\xb4\xee\x67\x83\x07\xf8\x59\xb5\x35\x61\xe3\xbf\xbd\xb4\x07\x87"
-  "\xf6\x42\xd4\xc1\x03\x98\xfe\x6d\xd1\xd7\x0b\x23\x6c\xd2\x35\x31"
-  "\xc6\x7f\x6b\x68\xfc\xf7\x40\xf4\x7e\xbe\xe6\x1a\xe3\xbf\x35\x34"
-  "\xfe\x7b\x20\x54\x6f\x8a\x75\x9e\x35\xad\xa1\x36\x29\xf9\x45\xd1"
-  "\x3f\x47\x76\x66\x61\xd2\x5d\xcd\xa0\xf5\xd1\xba\x32\xf6\x4d\xe7"
-  "\x60\x17\xf5\x57\x6d\x8f\xfb\x18\x9d\x69\x56\xd3\x1d\xb0\x42\x97"
-  "\x51\x7f\x5d\xe3\xe2\xba\xcc\x27\xfa\xa2\xc5\xcc\xdc\xe9\x03\xc8"
-  "\x43\x9b\xca\x25\x58\x6b\xba\x77\x96\x33\xbe\x17\x62\xda\x00\x24"
-  "\x38\x07\xb9\x5e\x54\x90\xbd\xca\xed\x56\xdf\x65\x20\xb8\x27\x6a"
-  "\x7b\x80\xe0\x06\xc6\xf5\x24\xc1\x2e\x5c\x4a\x7d\x9c\x60\x12\xec"
-  "\x5e\x4c\x47\x70\x29\x9d\x5c\x0f\x71\x8e\xa4\xb0\x34\xb4\xee\x7c"
-  "\xfe\x05\xcb\xc6\xf0\xf7\x68\x5e\xc5\x49\xf9\x2c\x6b\xd9\xbc\x01"
-  "\x5a\x33\xbb\xe8\x60\x96\x17\xd9\xbc\x2a\x9a\x13\x2b\xe4\xf7\x0f"
-  "\x7f\xf4\xbf\x5c\xf1\x35\xb3\x41\x2d\x85\x1d\xe9\xd2\x7b\x91\x8f"
-  "\x0b\xdd\xe1\x32\xa2\x30\xc2\xfe\x5d\xc3\xc7\x99\x2e\x58\x4d\xbe"
-  "\x01\x40\xda\x17\x4a\xf2\x80\x39\x7d\x23\x9c\x3f\xae\xb5\xaf\x81"
-  "\xd6\xa4\x69\x5f\x92\xf0\xfb\xf3\x58\x46\xc4\xdc\x9b\x7b\x1f\xdf"
-  "\xdb\xf2\x39\x96\xfb\xd8\xef\x04\x8f\x3c\xfe\xbb\xf0\x36\x7d\xac"
-  "\xc8\x72\x9e\xd6\x82\x84\x3e\x78\xc6\x17\x29\x1f\x1f\x33\xcb\xb6"
-  "\x5b\x44\xb8\x5d\xd6\x07\xfa\x4a\x0e\x37\x42\xcf\x3c\xc6\xed\x7f"
-  "\xff\x04\xbd\xf0\xd8\x49\xac\x5f\x18\x4f\xf6\x72\x1e\x7a\xcc\xd5"
-  "\xe3\x41\xbe\xa9\x22\xfe\x7f\xfc\x49\x4c\xb3\x8b\xce\xe6\xe1\x77"
-  "\xc2\x05\x78\x5c\xeb\xb7\x81\xba\xc7\xcd\xcf\x1e\x69\x91\x47\x38"
-  "\xdf\x92\xde\x98\x2f\xf6\x04\x79\xc2\xcb\x78\x3c\x5d\xa6\x39\xa5"
-  "\xe9\xad\xfa\x1c\xc4\x9e\x06\xe2\x85\xc7\x81\xf6\x47\x4c\x1b\x82"
-  "\x04\x82\x25\xf3\x90\xd3\xd7\x0f\xbd\xbe\xc8\x31\xcf\xe3\x35\xd1"
-  "\xeb\xfe\x38\xe9\xff\x26\x17\x3c\x3e\x10\xde\xb6\x8f\x73\xfd\x2f"
-  "\xaf\xeb\xb8\x90\x06\x11\xf9\xba\xc2\xdb\xfe\xb1\x22\x8a\x8f\xb9"
-  "\xcf\xc6\xbe\x42\x85\xe3\x99\x62\x0f\xdf\x73\xf5\x04\xf6\xff\xc7"
-  "\x62\x9e\xc1\xe0\xe7\x3a\xb4\x2b\x54\x01\x4c\x2b\xed\xb7\x45\xb9"
-  "\xf5\x44\x76\xd8\x9c\xd1\x0d\x7c\xce\xa8\xf8\x2c\x3c\x21\xad\xfd"
-  "\x14\xbd\x1e\x8e\xdf\x13\xa5\xb1\x6d\x83\x27\x68\xfd\xa7\x38\xba"
-  "\xcc\x78\xa2\x35\xba\x6d\xf0\xc4\x51\x49\x2e\x14\xb3\xa4\x48\x3e"
-  "\x78\xa2\x0f\xdb\x98\xe7\x91\xc7\xb0\x34\x17\x1a\x7b\x0c\x5b\x04"
-  "\xe3\x63\xd8\x2a\x92\x07\x4f\x0c\x8e\x8f\x61\xdd\xd1\xc6\xb0\xae"
-  "\x28\xed\x59\x94\x15\xbd\x3d\x8b\xd6\x45\x1f\xc3\x16\xd5\x08\x3d"
-  "\x5f\x74\x28\xbc\x9d\x8b\xf6\x06\xd7\x84\x9f\x28\xfd\xfe\xec\xe1"
-  "\x22\xef\x44\x7b\xf8\xc9\x2d\xa2\xad\x9e\xfc\xbb\x70\xdc\x9e\xd4"
-  "\x46\x97\xed\x4f\xa6\xc5\xb6\x87\x9f\xcc\x8a\x2d\xdb\x9f\x2c\x99"
-  "\x68\x0f\xeb\x27\x45\xa4\xa9\x1f\xb7\x95\xc2\x6c\xb3\x27\x5b\x05"
-  "\x9d\x9e\x24\x7b\x2e\x2e\x24\xfd\xd1\x70\x7e\x7f\x92\xfa\x9b\x06"
-  "\x65\xdb\x39\x92\x69\x32\xcf\xc4\xa2\x09\xf9\x30\xb9\xad\x19\x26"
-  "\x63\x1f\xf8\x74\xc4\xf6\xd4\x38\xff\xd3\x5e\x3a\x2a\x87\x64\x64"
-  "\xcc\x3d\x6d\x4a\x19\x3f\xc2\xe3\xa9\xa5\xd7\x5a\x2f\x8d\xd3\x41"
-  "\xc1\x1b\x13\xe8\xf1\x14\xb7\xff\x08\xc6\xb5\xdb\xec\xa9\x23\x11"
-  "\x7d\xcc\x23\xf6\xc2\xae\xdd\x2e\xda\x6d\x6d\xc4\x58\xf6\xa9\x93"
-  "\xfc\x5c\x5c\x4c\x79\xfb\xd4\x60\x74\x1e\x5d\x3b\x4e\x2f\xe4\x7f"
-  "\x82\x7b\x5f\x44\xbc\x5e\xb4\xc1\x5a\x73\x20\x29\x74\xae\x7b\x6d"
-  "\x46\xb8\x4c\x5a\xab\x8f\xc8\x17\x31\xfe\x7b\xea\x24\xc5\x7f\x3b"
-  "\x7d\xb3\xf6\x50\x6c\x7d\xb3\xee\x6e\x51\xff\xa7\x23\xd6\x97\xd7"
-  "\x9e\xbc\xb6\xbe\x59\x1b\xa3\xfe\xeb\x20\x5c\xdf\xac\x8b\x58\xa3"
-  "\x5f\xa7\x8f\xae\x6f\xd6\x65\xc8\x72\x46\xc8\x8d\x75\x8d\xdf\x4e"
-  "\xde\xac\x33\x85\xcb\x9b\x75\x45\xdf\x24\x6f\x4e\x4c\x90\x37\xeb"
-  "\x8e\x6a\x5a\xa3\xd6\xa5\x3b\xba\xbc\x59\x37\x20\xda\xf0\xe9\xa5"
-  "\xe1\xf2\x66\x9d\x2f\xbc\x0d\xd7\x45\xb4\xe1\xd3\x11\xeb\xdf\x6b"
-  "\x4f\xfe\x9f\xca\xa4\xb8\xb8\x38\x65\x9c\x42\xa9\x88\x03\xba\xf0"
-  "\x44\x01\x09\x71\xaa\xb8\x78\xfc\x4d\x92\x9e\x09\xca\x38\xa5\x0a"
-  "\x7f\xf1\xd2\x73\x52\xc4\x77\x02\xe5\xc5\x9f\x4a\x7a\xc6\x47\x7c"
-  "\x4f\xfa\x86\xf8\x04\xa9\x5c\xb9\x7c\x55\xc4\x77\xfc\x37\xc4\x4f"
-  "\xfa\x0f\xe6\x87\x09\xdf\xe1\xe7\x0b\x73\x2a\xb7\xae\xdf\x58\x51"
-  "\xca\xf7\x96\x97\xe9\xd7\x6f\xd8\x50\x56\x5d\xad\xaf\xd9\xa4\x5f"
-  "\xb1\x7c\xf5\xc2\x25\x7a\xb1\x45\x7d\xe3\xb2\xdb\x4b\xa7\x40\xde"
-  "\xb6\x2a\x8a\xc8\x5b\x93\x53\xa4\x2f\x58\xb1\x3c\x3c\x52\x06\xc3"
-  "\xb7\xa2\x5f\x0b\x4a\xe8\x1d\xd9\xaf\xde\x00\xb0\xf7\x06\x2e\x77"
-  "\x06\x7a\x3a\x00\xc4\x78\x62\xc3\xab\xdd\x68\x75\xb0\x51\x0b\xa3"
-  "\xf3\x0a\x67\xa0\x78\x19\x55\x62\x6e\x87\x15\x4c\xcf\x91\x7f\x91"
-  "\xe2\x27\xd9\x6f\xdc\xa0\x7f\x18\x94\x67\xa0\xfc\xed\x2e\x1c\xfd"
-  "\xd3\xb7\x73\xc0\x07\x7a\x0b\xd9\xb6\x1b\xee\xc3\x38\x05\xbb\x3f"
-  "\x80\x61\x1e\xe9\x1c\xfb\xb3\x39\x3c\xec\x37\x56\x39\x9d\xe6\x2c"
-  "\x14\xfb\xd9\x6f\x18\xff\x66\xf7\xdb\xa5\x74\xc5\x7f\x08\xd8\x9e"
-  "\xb1\x93\x5c\x68\x15\xf7\x68\xc3\xdb\xc9\xa0\x7e\xfb\x06\xf2\xb5"
-  "\x58\xdc\x25\xef\x8d\x7e\x15\xbf\x5d\x50\xde\x42\x65\x53\xda\x80"
-  "\xf2\x99\xff\xca\xd3\x27\x87\xa5\xf7\x04\xf7\x52\x17\x77\xd1\x9d"
-  "\xf3\xf9\x7f\x42\x95\x9f\x9c\x91\xe1\xac\xb5\x82\xc6\xcf\xbe\x9e"
-  "\x97\x0d\x8a\xde\x7a\x80\xed\x3e\xe6\x73\x54\x9d\xc3\xf2\x4b\x96"
-  "\x6b\xb6\xb3\xaf\x9d\x68\x37\xe6\x0d\x59\xd8\xbe\xf3\xa0\xc2\x3e"
-  "\xad\x70\x54\xd1\x99\x86\x92\xb4\xb6\xab\xa0\x42\x1a\xcc\x3c\x07"
-  "\xeb\x8b\x6a\xf3\x98\xdf\x92\x07\xaa\x7f\x34\xd3\x59\xd2\xcc\xd5"
-  "\xfb\xfe\x19\x54\x87\x47\xad\xca\x51\xa6\x83\xda\x1a\x36\xc8\xc8"
-  "\x07\xab\x87\x79\x69\xdf\x6b\x77\x89\x9f\xd2\xac\x18\xb1\xe8\xa0"
-  "\xb7\xc6\x03\x3b\x4f\x33\xef\x9e\x7f\x16\xbe\x1d\x7a\x86\x3c\x74"
-  "\x36\x55\xbd\x33\x0f\xe2\xce\x16\x81\xb2\xa7\xbc\x05\x9c\xeb\x3c"
-  "\x50\x7b\x9a\x0d\x76\x97\xfc\x09\x7a\xcb\x3b\xa1\xb8\x1f\x94\xdd"
-  "\x03\x5f\x00\xf7\x23\xda\x74\xd8\x58\x77\x19\x74\x3b\x2b\x28\xec"
-  "\x32\xec\xd8\x09\x53\x77\xfc\x0b\x8d\x85\xfa\xb1\x9c\xf3\xf0\xd4"
-  "\x29\x50\x20\x3c\xe5\xcb\x5f\x80\xee\xe5\x27\xe9\xac\xb6\x11\x5a"
-  "\xeb\x40\xc7\x2c\x69\x89\xa3\x96\x34\xed\x28\x4b\x4b\x1e\xb1\xa4"
-  "\xa5\xf4\x9a\x30\xfd\xc0\x27\x30\xad\x1f\x52\x7e\x73\xae\x5f\xd9"
-  "\x72\x09\x66\xea\x57\x51\xfb\xaf\x2f\x6c\xbd\x84\xe9\x9b\xac\x8e"
-  "\x00\xe6\x0d\xcd\xe3\x4b\xb2\xf6\x3b\x8b\xbc\x10\x40\x58\x2d\xa3"
-  "\x30\xb3\x75\x14\x74\x81\x46\xab\x83\x68\x31\xd6\x64\xcc\x40\x39"
-  "\x98\xf0\xd1\xb3\xc7\x54\xce\xee\x21\xe8\xf1\x8c\x42\x2f\x7c\x0e"
-  "\x4e\xf3\x9f\x1d\x87\x9f\x3d\x16\x8f\x76\xa4\xc2\xb1\x83\xf6\x9f"
-  "\x0b\x9e\xb1\xf4\x90\x0f\x2a\x2b\x34\xd4\x41\xa2\x69\x07\x24\x9c"
-  "\xc3\x70\x2e\x73\xec\x8b\x8c\x4e\xdf\x9f\x1d\x3b\xf8\xf9\xea\xf2"
-  "\x96\xba\x1e\x88\xeb\xf5\xb4\xd0\x39\x5e\xa5\x3f\xf9\xb0\xd1\xe9"
-  "\xe9\x03\xa7\xe9\x8f\x8e\x80\xf6\x70\xda\xde\x00\xa8\x3f\xbc\xd2"
-  "\xa7\x74\xaa\xae\x80\xb3\xc8\x03\x9f\x62\xd9\xac\xe9\x70\x2e\xca"
-  "\x2a\x63\xaf\xc7\x4b\x7e\x68\x0c\x6c\x58\x37\xa5\xa1\x0a\xd2\xdb"
-  "\x2e\x41\xea\x81\x4b\x90\xc6\x46\xd2\x94\x74\x66\xfa\xe9\xf3\x5a"
-  "\x38\x80\xcf\x44\x1c\x7b\x61\x7d\xf9\xd9\x69\x96\x24\x9d\x9d\x1e"
-  "\x4b\x83\xf6\xd1\xe0\xd9\xe9\xd1\xe1\xe0\xd9\x69\xe4\xa5\x93\x74"
-  "\x7e\x1a\xfb\x85\x95\xf8\xb9\xe1\x02\xa8\x76\x5f\x00\x98\x67\x55"
-  "\x82\xfe\x59\xf2\x89\xb1\x61\xae\xb3\xf4\x3c\x7f\x3f\x03\xcf\x0e"
-  "\xe0\x33\x11\x7f\x38\x7e\x7b\x96\x9f\xf7\x1d\x90\xf8\x16\xc3\x94"
-  "\x18\xd6\x83\xcf\x38\x7c\xfe\xce\xd2\xca\xdc\xcc\x9e\x95\x88\xb6"
-  "\xc9\x14\xe2\x5f\x71\x4e\x3b\x2b\x71\xc4\xf6\xec\x71\x17\xbc\xb6"
-  "\x57\xe6\x63\x21\xcf\x8b\x4f\x7e\x7a\xf6\x3c\xf9\xf5\x75\x73\x7c"
-  "\xc6\xca\x15\xe4\xe3\x57\x0a\x27\x1c\x6e\xa7\x72\xcf\xc0\x06\x35"
-  "\x3e\x35\xf8\xc3\x7e\xf9\x6c\xab\x9c\x77\x78\xac\x1c\xcb\xdc\x30"
-  "\x0b\xc3\x99\x1c\x8e\xf5\x55\x51\xdc\xdf\x9e\x3d\xaf\x14\x69\xd2"
-  "\x94\x08\xd3\x2b\xc1\xc7\xbe\x5e\xbc\x91\xfa\xf4\xb0\x52\xc3\x4e"
-  "\x94\x2e\x86\xd6\x1b\x58\xdf\x81\xfd\xac\x4b\xf4\xb5\x0d\x25\x2e"
-  "\xd8\xcb\x7d\x2a\xa0\xce\xee\xda\x8b\x71\x27\x50\x7b\x12\x5d\xba"
-  "\x4a\x68\x3f\xe9\x06\xab\x0b\xa6\x9c\x0e\xad\x03\xb3\x3d\x6d\x22"
-  "\xbd\xf9\xeb\x3a\x47\x3c\x53\x3e\x63\xea\x75\x0d\xc1\xe1\xd1\xc1"
-  "\x78\xcb\xef\x41\xe9\xf4\x9d\x81\xf9\x29\xa0\xa3\x39\x98\xf6\xfd"
-  "\xcc\x85\xcf\x41\xfc\x0d\x21\x9f\xcc\x3a\x07\x1b\x7a\xee\x4a\x81"
-  "\x94\x7f\x32\x83\x24\x8f\x36\xfc\x29\x44\x1e\xbd\xd4\x33\x70\x2c"
-  "\x44\x16\x95\xcf\x9a\x28\x8b\x9e\xff\x91\x90\x45\xcc\x27\x64\x8f"
-  "\xdf\x25\x85\xc7\x47\x84\x4b\x67\x46\x9e\xfb\x2a\x22\xdc\x2b\x85"
-  "\xff\x4b\x44\xb8\x5b\x0a\xbf\x5e\x96\x75\xbd\x84\xc7\x36\x92\x75"
-  "\x65\x57\x49\xd6\xf5\x96\x4a\xb2\x8e\x9f\x71\x2c\xfb\x82\xfd\xcc"
-  "\x2a\xee\x77\x87\xb2\xbf\x23\xfc\xd9\x6f\x40\xc6\x7d\x32\x86\x6d"
-  "\xa1\x30\xfb\xe7\xa0\xc2\x1f\x97\x73\xcc\xf6\xcc\xff\x24\x39\x47"
-  "\x32\x8e\xce\xa2\xbc\x7b\x03\xeb\x7f\x77\x3f\x3b\xd5\xba\x9f\x75"
-  "\x8f\xd8\x4a\x07\x64\x79\xf7\x1a\x86\xed\xc5\xb0\xd7\x30\x9e\xe4"
-  "\x1e\xd1\xa4\xa7\xe8\x18\xf9\x71\x1c\x40\x3e\x2e\xd0\x28\xc0\xb4"
-  "\x0f\x79\x9e\xfc\x3f\xd5\x23\x7d\x9d\x28\x93\x68\x4f\x2e\xf7\x87"
-  "\xab\x34\xa0\x8c\x1a\xa0\xfe\x76\xc3\xee\x00\xcd\x4b\xfc\x09\xea"
-  "\x3c\xec\x1c\x9d\x0f\x21\x1c\x8a\xb7\x3f\x4c\x7e\x5e\x15\x5d\xe5"
-  "\x00\x74\xbe\x9f\xce\xaf\xa0\xdc\x55\xd9\x11\xa7\x13\x1b\xa9\xad"
-  "\xcb\x36\xba\xe0\xef\x37\x8a\xb6\x2e\xe7\xfe\xa3\xcf\x40\x69\x27"
-  "\xb3\xa1\x2c\xc4\xba\x69\xfc\x56\x20\x9f\x25\xd8\x47\x69\x9e\xb5"
-  "\xfc\x5d\xfc\xd9\x65\xbf\x25\xe4\x03\x1c\xd3\x38\xfb\xbd\x40\x38"
-  "\xbb\xa0\xd4\xd7\x53\x7b\x8c\xf2\x77\x10\x6d\x98\xcd\x22\xc3\x50"
-  "\x70\xbf\x27\x38\x86\x27\xbf\x27\x2e\x28\x13\x67\xea\x92\x8d\x19"
-  "\x3d\xeb\xdc\x40\x72\xde\x39\x88\x30\x6a\xcf\x08\x18\x08\x8b\xa1"
-  "\xdc\x0f\x8b\x93\xe0\x4f\xdd\xc9\xbe\x46\xf8\x1b\xa9\xbd\xc8\x4f"
-  "\x15\xed\x4b\x42\xba\x24\x92\xcf\x03\x61\x77\x96\x5e\x6e\xff\x1c"
-  "\x40\xf2\xb5\x85\xfc\x56\xea\x21\x5f\x56\xe4\x5f\x8b\xfb\xd6\x52"
-  "\x2e\x06\xb6\x2d\x2d\x71\xdc\xbf\xd6\x5f\xc0\xb7\x16\xd2\x5f\xd7"
-  "\xa6\x64\x9d\x88\xbf\x87\xfc\x6b\x21\xfe\x85\xc4\x87\x52\x9d\xbc"
-  "\x6f\x3e\xc5\x69\xbe\x94\xc2\x1a\x6c\xec\xa4\xdc\xfe\x54\x5f\xaa"
-  "\x0b\xc6\xe9\x85\x3d\xc8\xfa\x5c\xf0\x9c\x97\xe2\x31\x2c\x91\xd2"
-  "\xcf\x47\x39\xe6\x2c\xf5\xc3\x47\x67\xfd\xca\x86\x1d\xa0\x12\x32"
-  "\xad\x3c\x89\xf2\x0b\x99\xf6\xfc\xc9\xa0\x4c\x7b\xfe\x13\x21\xd3"
-  "\x04\x8d\x85\x4c\x7b\xfe\x63\x21\xd3\x9e\xff\x25\xdf\x3f\x84\x32"
-  "\x8d\xe2\x48\xae\xc9\x32\xed\xc0\x0d\xec\x24\xc9\x8e\x11\xdb\xf3"
-  "\x2d\xb2\x6c\x7b\x1d\xc3\x48\x76\x10\x8e\x42\x4e\x95\xb9\xd9\xff"
-  "\x93\x06\x62\x7f\x26\xbd\x97\x93\x1f\x8a\x41\xe9\x9d\xf4\xc8\x64"
-  "\x21\xe3\x9e\x1f\x0a\xca\xb8\xe7\x4d\xc1\xbc\x24\xe3\xca\x15\x42"
-  "\xc6\x89\xf0\xf6\xa7\x48\xc6\x95\xb9\x89\x06\x12\x7c\x25\xad\x9b"
-  "\x49\xe9\x91\x8e\x1b\xbc\xa1\x32\x2e\xbc\x7f\x95\x67\xc9\x32\x8e"
-  "\x64\x1b\x7e\x17\xa2\x4c\xe3\xfe\xe8\xa9\x9f\x35\x23\xcd\xe5\x7e"
-  "\x47\x6d\x40\x75\x26\x3f\xd1\x44\xb7\xcc\xf3\x90\x20\xf9\x74\x91"
-  "\xea\x5d\x6e\x97\xcf\x45\xba\xe0\xf9\x96\x48\x9b\x99\x16\x26\x42"
-  "\xce\x6e\xdd\xe2\xa7\xb9\x5d\xeb\x19\x70\xb6\x30\x6b\xaf\xef\x34"
-  "\x04\x76\xbf\xf8\x25\xb5\x2b\x8e\x2f\x26\xd1\x93\xe4\x0e\xea\xcf"
-  "\x3f\x14\x7b\xf8\x7c\xfd\x97\x0d\x4a\x8c\x33\xc3\x8f\x43\xe2\xce"
-  "\x53\x19\x21\xf9\xe6\x06\xe3\x2a\x26\x53\x1c\xcd\x31\x62\xba\x63"
-  "\xb1\xe6\x14\xbe\x3d\x1e\x15\x4f\xc6\xc6\xa3\x62\xcb\x35\xf0\x68"
-  "\xe4\x78\xa0\xbd\x85\xe3\xa3\xa4\x0b\x50\x61\xa4\x6f\xee\x5b\x34"
-  "\x7a\x39\x9f\x49\xf1\x71\x21\xf1\xa1\x65\x7d\x19\x25\x7f\x48\x79"
-  "\x2f\x28\xae\x0d\xff\x85\xd9\xd7\x86\xff\xc2\xf2\x6f\x80\xbf\x9e"
-  "\x64\x1f\x9d\xbd\xf3\xdb\xc2\xd3\xcd\xf3\xf1\xbe\x77\x92\x7c\x2c"
-  "\x61\xba\x57\xa5\xf5\x96\x2f\x2d\xb3\xf9\xf8\x8f\xfb\xdb\xd9\x87"
-  "\xf1\xdc\x5f\x27\xca\xe5\xac\xed\x00\x62\x4f\xdf\x78\x9e\x4f\x22"
-  "\x71\x9b\xe6\x93\x71\xe3\xf1\x5f\x44\xe2\x86\xf1\x73\x43\xe2\xfd"
-  "\xc1\x36\x7f\xc1\x7c\x8d\x79\xa4\x44\x27\x72\x27\xdd\xb1\x70\x02"
-  "\x87\x2d\x74\xd6\xa7\x79\x7c\x6d\xe4\x45\xe4\xff\x72\xbe\xb6\x23"
-  "\x9d\xed\xa5\xbd\x32\xb7\xf4\x7a\xc8\x27\x99\x47\x3e\x0b\x72\x23"
-  "\xea\x91\x64\xf2\xbf\x42\xf3\xe9\xc5\xfe\x02\xa5\xf0\x95\xfc\xa2"
-  "\x5d\xce\x1b\x6b\xee\x91\xca\x95\xca\xe4\xe7\xa4\x30\x4f\x97\x9c"
-  "\x87\x60\xd3\xd9\x20\x94\xff\xb7\x70\x3f\x65\xbe\x21\x92\xb7\x37"
-  "\xa2\x7d\x9c\x2c\xca\x29\x01\xa9\x1c\xec\xdb\x15\x86\x6b\x94\x73"
-  "\x8d\xfa\x6d\x5c\xfc\xdd\xeb\x07\x52\xfd\x36\x9a\xbe\xa1\x7e\xd7"
-  "\x2a\xf7\xc8\x77\x2f\x57\x2b\x97\x3b\xf8\xdd\xe9\xfa\xd2\xcc\x6f"
-  "\x4f\x57\x83\x44\xd7\x97\x0a\xbe\x81\xae\xd1\xca\xa9\xff\xf6\xe5"
-  "\xe8\xe5\x72\x8e\x45\x2b\x07\xf8\x5f\x4c\x3f\x3d\x6a\xf9\xee\x02"
-  "\xba\x37\x44\xf8\x2a\xaf\x84\xd0\xbb\x55\xc4\x7d\x22\x95\x29\xf2"
-  "\xdd\x2a\xc1\x73\x66\x95\x0b\x8a\x3b\xc8\x0e\x61\x01\x17\x54\x2e"
-  "\xa6\xb9\xc0\xac\x9d\xa1\x77\x90\x54\x66\x7f\xc3\x9d\x2e\xe4\x1b"
-  "\x27\x9b\xca\x66\x8c\xfb\x60\xf1\x08\x7f\x79\x95\xaf\x92\x9f\x06"
-  "\xb1\xa7\xa8\xf2\x98\xe8\x9b\x95\xcd\x2e\x78\x89\xfb\x59\x24\x1f"
-  "\xcc\xc3\x16\x29\xfd\x0c\xd2\xa1\xe3\x69\x8e\xc9\x69\xa2\xce\x49"
-  "\x36\x59\x3a\x0f\xd6\x19\xc2\xce\x18\xae\xac\xaa\xda\x54\xb5\x44"
-  "\x5f\xfd\xd2\xb3\x73\xab\x6b\xd6\xd7\x6c\xa9\xe6\x87\xd1\xa7\x00"
-  "\x06\xe8\x6b\x2a\x5e\x2a\xdb\xb4\xa5\x26\x6d\xdb\xfa\x0a\x71\x78"
-  "\x7d\x0e\x26\x0c\x4d\x04\x61\xbe\xfd\x75\x28\x83\xb8\x2f\x3a\xda"
-  "\x87\xcd\x7d\x60\x92\xff\x77\xe9\x6c\x6e\x97\x0e\xc0\x83\xe3\xa3"
-  "\x11\xdb\xa6\x75\x2e\x58\x7d\x48\xa6\x23\xf9\x29\x44\x3b\x49\x77"
-  "\x0e\x36\x6d\xa7\xb6\xcf\x47\x93\xb7\x5d\xf8\x83\xe0\xe7\xff\x9d"
-  "\x35\x18\xd0\x0b\x6a\xc7\x56\x9a\xe7\xdd\x84\x3c\x50\xe9\xe2\x7e"
-  "\x17\x77\xd0\xf8\xdb\x74\xbd\x6c\x97\xd0\xba\x95\x58\x67\xbe\xe5"
-  "\x81\x33\xb0\x69\x25\x95\x4b\xfd\xa6\x0d\xed\x5f\x82\xc5\x6c\x95"
-  "\x5e\xb2\x81\xf1\x5b\x8d\x38\xb8\x64\xdb\x17\xf1\x4d\x64\x49\x96"
-  "\x0e\x17\x98\x52\x7e\xab\x75\x83\x74\x9e\x5b\xdd\x26\xce\x6e\xab"
-  "\x46\x6c\xa6\xc4\xf1\xb4\x36\x4c\xdb\x68\xe9\xa0\xfb\x7a\xa2\xd2"
-  "\x37\x39\x8f\xfc\x89\xc7\x87\xd6\x19\xc7\xec\xd8\x3e\xa6\xdf\x61"
-  "\xdd\x53\xa8\xad\x25\x3f\x22\x93\x30\xec\x43\xba\xff\x80\x35\xe5"
-  "\x01\x86\x4d\xc2\xa7\x8e\xda\x94\xfc\x1c\x60\x1c\xed\xf5\x51\xf4"
-  "\xd6\x5e\x74\x9c\xd0\x9d\x41\xbe\x36\xa1\xfc\x2b\x3a\x2d\xce\xc5"
-  "\xe5\x91\x2f\xfe\x78\xa7\x75\x14\xba\xf4\xcc\x41\x73\x80\x88\xfb"
-  "\xe9\x2e\xbd\x07\x58\xdc\xda\x2f\x29\x1f\xf6\x0b\x9d\xc5\x4c\xb6"
-  "\x0f\x86\xf3\xf3\x7f\xa6\x3e\x99\xe6\x35\x7a\x76\x9e\xd2\xc4\x9a"
-  "\xb7\x26\x1d\xdc\xc0\x75\xc9\x25\xbe\xc7\x6b\x00\x4c\x9e\x48\x79"
-  "\x7f\x7b\xe9\x12\x7d\xe9\xfa\x1a\xfd\xc6\x8a\xca\x32\x7d\x69\x45"
-  "\xa9\xbe\x72\x53\x8d\xfe\xf9\x4d\x34\x81\x44\x53\x46\x61\x3c\x11"
-  "\xa0\xfa\x6d\x2b\x8a\x97\xd7\xc8\x87\xb7\x95\x4f\xc2\xfa\x23\x4d"
-  "\xaa\xf2\x86\x47\xca\x13\xc2\x69\x52\xb5\x40\xf0\xf1\x66\x1c\xff"
-  "\x99\x52\xc5\xf9\xc2\xb8\x41\xfc\xc6\xfa\x9b\x06\xc3\xfb\x5e\xd5"
-  "\x4e\x29\xed\x11\x39\x2d\xe7\x8b\x5b\xcf\x8d\xc7\x35\x48\xfc\xd8"
-  "\x2e\xce\x22\x73\x7f\x35\xed\xfc\x8c\xc0\x66\x57\xcc\x3c\xe4\xa3"
-  "\x6b\x07\x6c\xb8\x00\x9b\x7f\xcf\x6c\x9b\x53\x24\x1e\x52\x07\xec"
-  "\x79\x5a\x89\x7f\x90\x27\xaa\xf4\x13\xf9\xa7\xaa\x96\xf8\x87\x8d"
-  "\x14\xa9\xf9\x7e\x12\x9f\x17\xe5\x14\x7e\xa3\x3e\x75\xc1\xe6\x7a"
-  "\xaa\x87\x67\x5b\x91\xda\xf2\x36\xd7\xd7\x5f\xd1\xda\xec\x09\x2f"
-  "\xf7\xb1\x34\x19\x79\x03\xdb\xa8\xaa\x46\x6e\x23\x39\x7d\xf4\x3e"
-  "\xcc\xf9\x25\x9c\xc7\x04\x3d\x7b\x38\x8f\xa1\x5d\x80\x38\x29\x65"
-  "\xbb\x80\x74\x00\xe2\x36\x50\xb3\x93\x31\x2c\xa3\x3f\x84\x0f\x2e"
-  "\x44\xe3\x03\x6c\xdb\x0d\x1b\x37\x6d\x78\x11\x3b\x7a\x55\x59\xcd"
-  "\x86\x72\xf2\x5f\x41\x72\x80\x3b\xc7\xb8\xbd\x54\xbf\xa5\xba\x6c"
-  "\xc3\x14\x88\x96\x6a\x3c\x32\xb4\xfd\xb5\x01\xe4\xd7\xe1\xe1\xa2"
-  "\x78\x3a\xc3\x21\xce\x6c\xd4\x1c\x18\xae\xc6\x71\x4f\x58\xbb\xd7"
-  "\x34\x3a\x75\x06\xb4\x13\x0d\xc0\x6d\x7e\xa4\x99\xd8\x87\x50\xf3"
-  "\x2f\x44\x87\x61\xa5\x02\xf5\x41\x75\xb3\xcc\x03\xf8\x4e\xf4\xde"
-  "\x13\xdc\x03\x52\x73\x6a\x58\x19\x7f\x9a\xe4\x8f\xd8\x6f\x72\x0e"
-  "\xe5\x80\xa6\xfd\x0c\x54\x93\xec\xa7\xbb\x3a\x28\xff\x29\x39\xcf"
-  "\xbe\xf1\x73\xd4\x35\x4b\x65\x3e\x09\xc9\xf3\x3b\x0a\x13\xe3\xe7"
-  "\x2a\x37\xb5\x39\x13\x6d\xaf\x92\xd3\x21\x5d\x59\x3b\x97\x23\x35"
-  "\x69\x91\xb2\xe1\xb7\x5a\x5a\x73\x17\xf8\x70\xfe\xd3\xe6\x0e\x72"
-  "\xdf\x28\x68\xe3\x9d\x81\x9a\xbb\xa5\xfd\x2f\x7d\x5c\xa7\x9b\x11"
-  "\x96\x57\xc0\x62\xb6\xea\x1b\xe4\xb2\x58\x52\x2e\xf7\x21\x81\xf0"
-  "\xf7\x04\xe7\x24\x6b\x16\xd3\xd8\x9c\x0d\x17\x4d\x72\x41\x75\x0d"
-  "\xe7\x2d\x7c\xaf\xf9\x91\xf0\xbd\x46\xfc\x46\xf5\x24\xbe\x0a\xf2"
-  "\x54\xcd\x49\xb9\xbd\xa9\xce\x98\xaf\x56\xcf\xfd\xed\xd6\xb8\x64"
-  "\x5a\xc6\xf2\x27\xc3\xfb\xad\x16\x71\x19\x11\x7d\x97\x8f\x2b\x85"
-  "\x5f\x20\x3a\x47\x13\xc7\x92\xf2\xb4\x67\x61\xcb\xd7\x74\x36\x40"
-  "\xe3\xa5\x71\x5a\x9e\x96\xfc\x23\x08\xff\x42\x5b\x8c\xc8\xc3\x8b"
-  "\xa5\xf3\xc1\xf4\x8d\xfa\xbf\x7a\xb1\x68\xbb\x2d\xeb\x42\xfa\x9e"
-  "\x5b\xda\x6f\x90\x40\x34\x22\x79\xe6\x34\xaf\xe4\xfd\x55\x9c\x2b"
-  "\xde\xb2\x47\xce\xc7\x7d\x09\xf8\x84\x4e\xbc\x00\x5b\x0e\x91\x8e"
-  "\x20\xfc\x5c\xb0\x25\x8d\xca\xa7\xfa\x91\xce\xe5\x7c\xa3\xa3\x3b"
-  "\x09\xb6\x74\x45\xe0\x70\x4a\x86\x25\xc1\x1e\x90\xbf\xc9\x5f\x98"
-  "\x0b\xb6\x99\xba\x66\x62\x9f\xf2\xf0\x3a\x5c\xd7\x55\x83\x7d\xcb"
-  "\x43\xe9\xb6\x26\xca\x34\xc4\x70\x2b\x7e\xa3\xfd\xb3\x49\x2f\xd6"
-  "\x9c\x2c\x1d\x42\x16\x6d\xdb\x48\xbe\xa8\x2c\x7a\xf2\x27\xb8\x54"
-  "\xc8\x1b\xee\x2f\x87\xc7\xcd\x91\xfa\xec\x64\x3a\x83\xc4\xf7\xdd"
-  "\x78\x7c\x5c\x36\x08\xff\x0a\x18\x8f\x7d\x64\x44\xdc\x7b\x32\x59"
-  "\xe0\xb6\xd5\x3a\x5e\x06\xf2\x44\x17\x5f\xe3\xdc\x6a\x12\xfe\x4a"
-  "\x12\xfa\x30\xbe\x43\x6e\x3f\xf2\x01\x4d\xf5\xc6\x7c\xea\x2e\xee"
-  "\xe3\x6b\xeb\x71\x19\x5f\x29\x4e\xc9\xf9\x81\xd3\x60\xeb\x78\xff"
-  "\x1f\x4e\xe6\x69\x07\xe5\x72\x78\x5a\x4c\x47\xe9\xe9\xae\xba\x11"
-  "\xdb\x36\xd5\x38\x1c\xe1\x27\x45\x4d\xe5\x74\x75\xf0\x38\x7d\x50"
-  "\x56\x6d\xe1\x6b\x46\x7c\x5f\x1c\xd6\xc3\xfd\x32\x8e\xb3\xa9\x0d"
-  "\xf4\x10\x87\x79\x54\x04\x4f\xf0\xe2\xb6\x42\x39\x4f\x9c\x82\xe8"
-  "\xb8\xad\x54\x2e\x5b\x86\x41\xf8\x5f\x53\xe6\x89\xba\xa8\xa8\x8f"
-  "\x50\x5a\x82\xcb\x79\x82\xdf\x75\xb3\xed\x3c\xe7\x41\x5e\xcf\x6d"
-  "\x8e\xd0\xb6\x16\xb6\xd8\xb6\x53\x21\xfc\x40\xf8\x8c\xb7\xbf\x0b"
-  "\xcc\x29\x42\x97\x6c\xf3\x86\xe0\x68\x1c\xb1\x99\xd5\xc1\x76\xe0"
-  "\x6d\x44\xf7\x56\x44\xbd\x47\x8c\xf7\x15\x4c\x13\x60\x1c\x4f\x6a"
-  "\x0f\x1c\x8b\x65\x40\x57\x0b\xf9\x6d\xca\xd3\x22\x4d\x10\x47\xf3"
-  "\xeb\xc4\x57\x08\xb7\x24\x9c\x37\xcd\xa6\x10\x7c\x15\x24\xd7\x31"
-  "\xac\x5e\x4e\x83\xf8\xf1\xbd\x2c\x32\x3d\x31\xae\x63\xbc\x1d\x17"
-  "\xf2\xb4\x9d\x32\x9e\xdf\xa0\x33\x24\x5a\x99\xbf\x92\xca\x18\x94"
-  "\xcb\xc0\x77\x94\x0f\xdb\x26\xd8\xaa\xcf\x6e\xaf\x29\x13\x0e\x8c"
-  "\x48\xc9\xaf\xdf\xf0\x62\x59\x69\xba\x7e\xfd\x73\xe4\xea\xa8\x7a"
-  "\x63\x59\x99\x89\x2f\x12\x85\xdb\x81\x29\xbc\x3c\xa4\x83\xb0\x65"
-  "\x77\x6c\x7e\x43\xec\x8f\xa1\x7e\x41\xfd\x9d\xce\x15\x24\x9c\xa8"
-  "\xbd\xc4\xc7\x26\x4e\xeb\x42\x70\x7a\x99\x95\xec\x77\x2e\xfb\xa8"
-  "\xfe\x3a\x8f\xd0\x03\xd8\x9e\xa4\x23\x47\x6c\xdb\xed\xe1\xf4\xda"
-  "\xde\x11\xde\x97\xb7\x77\x46\x97\x13\xdb\x1f\xe5\x72\xc2\x2e\xf8"
-  "\x82\xe4\x13\x9d\x2d\x20\xb8\x98\x67\x20\x02\xa6\x27\x28\xa3\x76"
-  "\x80\x2c\xa3\x84\x9e\xd8\x91\x8a\x3a\xc8\x2e\xca\xda\x31\x33\xc8"
-  "\x37\x3b\x5a\x05\xdf\xec\x30\xb8\x60\xef\x46\x79\xac\x22\x74\xc7"
-  "\x76\x6e\x3f\x92\x4c\xc7\xf8\x02\x19\x5e\x73\x32\xe9\x8d\x1d\x25"
-  "\x13\xed\x87\x1d\x89\x64\x3f\xd0\xbe\x47\xa2\x05\xe2\xaa\x16\xfd"
-  "\x66\xc7\xde\x10\xf9\x83\x78\xef\x68\x8d\xd6\xd6\xcf\x92\x3a\x9e"
-  "\x4b\xcb\x79\x73\x37\x54\xd6\x2c\x23\x37\x54\x65\x66\x53\xd9\x86"
-  "\x9a\xb2\xd2\xc8\x75\xbc\x34\xd9\x16\x93\xfd\xd2\xbb\x93\x88\x1e"
-  "\x3b\xb0\xfe\x3b\x67\xca\x75\xe0\x72\x0a\x6d\x47\x49\xc6\x25\x9e"
-  "\x85\xda\xaf\xda\xf9\x3e\xc0\x97\x67\xca\x7c\x42\xe9\x32\xcd\x2c"
-  "\x80\x61\x58\xff\xed\xf2\x5d\x87\x38\x26\x7d\xd9\x28\x7f\x07\xf3"
-  "\xbf\xfc\x0a\xd7\x7d\xfb\xf9\x9e\x41\xa4\x69\xad\x2a\xc4\xde\xc2"
-  "\xef\x97\x4f\x4b\xdf\xdc\xd7\x12\xf9\x05\x1b\x82\x97\xdf\x16\xf4"
-  "\x7d\x19\xdb\xdf\x2c\xc9\x8a\x5a\xb1\xef\x66\x3f\xc0\xfb\x75\xee"
-  "\xf8\x76\xbe\x9e\xf0\x72\xa7\x5c\x1e\xe6\x3f\x1d\x5a\x26\xe9\xad"
-  "\x48\x78\x2e\x78\xb9\x9e\x9e\xbb\xb9\xef\xb7\x97\x87\xa2\xe0\x6a"
-  "\x0a\x4d\x37\x62\xab\x45\x3d\x63\x3e\x2e\xd7\x79\x8d\x99\x87\xa5"
-  "\x5e\xa3\x8e\x43\x52\x1d\x3b\x88\xb7\xa8\x7c\xe2\x7f\x09\x87\x7a"
-  "\xc9\xef\x89\x8b\xee\x0a\x23\xfc\xb9\x0f\x34\x1d\xf5\xeb\x5a\x33"
-  "\xea\xf9\x21\xb9\x1e\x54\xc7\xa3\x75\x6e\x95\xec\x7b\x4a\xe4\xaf"
-  "\x7d\x3a\x02\xb7\x23\x21\x79\x06\x1d\xb7\xd2\x5a\x41\xed\x4a\x66"
-  "\xdb\x71\x88\xf8\x90\x7c\x52\x35\x8f\xf3\x61\x6d\xff\x44\xbe\xab"
-  "\xcd\x22\xbe\x0b\xe5\xa5\x8a\x85\x1b\x90\x93\xaa\xcb\x6a\x96\x70"
-  "\xeb\x1e\x0d\x3b\x72\x6d\xb6\xbe\xa6\x62\x53\x65\x75\xba\xbe\xba"
-  "\x74\xbd\xd4\xe9\xc3\xfa\xbc\x8d\x8f\xdd\x3d\x72\x3f\x1b\xb1\xed"
-  "\xcc\x0a\xca\x96\x9d\x41\xfe\xa7\x3d\x60\xfc\x4e\xd1\x9d\x6f\x8b"
-  "\xfe\xb4\x73\x63\x48\xdf\xe5\xf9\xa9\x8f\xb6\x73\x9b\x6d\x67\xa8"
-  "\xfe\xa7\xb1\xf1\xe4\x0b\xb0\xf3\x6e\x89\xa6\x1e\x41\xe3\x9d\x5f"
-  "\xf2\x7a\x72\x9f\x5b\xb5\x1e\xaa\x27\xf7\x2f\xc3\xed\xb3\x9d\x27"
-  "\xe5\xfa\x06\xc7\x0d\x3b\x5d\xdc\x8e\x92\xec\xb5\x6b\x8d\xcb\x83"
-  "\xf6\x69\x5d\xad\x34\xe7\xd6\x2f\x8f\xf1\x64\xfb\x1a\x71\x29\x15"
-  "\xb6\x6a\xdd\xdd\xf9\xb5\x6c\xac\xd8\x4c\xbe\xe8\xa8\x0d\xea\xd6"
-  "\xcb\xb6\x25\xdf\x1f\xd8\x98\x8b\xfd\xa2\xae\x28\x54\x4e\xb0\xb8"
-  "\x17\xfb\x25\x1b\xd1\x2d\xc6\xae\xd7\xfd\xc3\x19\x2c\x0b\x71\x53"
-  "\x5f\x03\x37\xac\x57\x1d\xb6\xdb\x3e\xee\x5f\x93\xec\x6b\x36\xac"
-  "\x93\xee\x5d\xb3\x70\x9f\xec\x6d\x08\xdb\x8d\x6d\x8b\xe9\xd0\xfe"
-  "\xdb\xc9\x79\x23\x80\x3c\x4a\x7b\x83\x3c\xb2\x8d\x04\x75\x97\x49"
-  "\x17\xe1\x3b\xf2\xad\x45\x3a\x93\x68\xc9\x76\x57\xa7\xa1\xbd\xae"
-  "\x53\x0e\x57\x17\xa9\x68\xbe\x80\x68\xe1\x6c\xf5\x82\xe0\x1f\x8b"
-  "\x0e\xe5\xd4\xc9\x50\x78\x12\x2c\xa2\xa9\x8a\xf0\x60\xd5\x3a\x25"
-  "\xf1\x37\xbf\xc7\x6b\x38\x0d\xe5\x68\x9d\x8b\x55\xa7\x29\x63\xf8"
-  "\xd7\xba\x56\x3d\x13\xe9\x5e\x33\xba\xa3\x8e\xe4\x95\xf0\xb3\x6f"
-  "\xfd\xe0\x0d\x31\x37\x20\x95\x6b\xf9\x25\x53\xbe\xc7\xf5\xca\x3e"
-  "\xae\x57\x18\x88\x3b\x18\x2c\x27\xf9\x3e\x5d\xd3\x7b\xfc\x7e\x41"
-  "\xe9\xfc\xb7\xbb\xcb\xe4\xe3\x77\x93\x59\x6a\xc8\x4e\xf3\xd1\x3a"
-  "\x15\x3f\xdf\x7c\xa2\xc6\x07\x6b\xbc\xc4\x93\x16\x2f\xf9\x6d\xf7"
-  "\x70\x7b\xc1\xaa\x92\x7d\xb5\xd3\x5d\x69\x74\xff\x1e\xd6\x2b\x8e"
-  "\xda\x5d\x6f\x21\x1f\xfb\x56\xba\x5f\x0d\xc4\x78\x5c\x07\xfb\xd0"
-  "\xa6\x17\x6d\x60\xcd\xa3\xfb\x0c\xc5\x58\xe1\x0c\xb6\x4b\xdc\x9f"
-  "\x31\x6d\x99\x58\xab\x96\xe5\x84\xf5\x0b\xda\xfb\xee\x92\x60\x60"
-  "\x59\xa8\xff\xeb\xf6\x88\xb2\x10\xde\x88\xdc\x9e\xd6\xbc\x89\xf3"
-  "\x1b\x41\x78\x98\x3f\x57\xb2\x0b\x40\xcc\x5d\xfd\x96\x60\x1d\x97"
-  "\xe7\xae\x82\xb6\x8f\xb5\x4f\x9e\xbb\x12\x3e\xa3\x2d\xcd\x54\x7e"
-  "\xac\x39\x22\x66\x79\x92\xf8\x5e\x4d\x36\x5c\x4c\x7b\x02\xf5\x3b"
-  "\xe1\x2e\xdb\x85\xa2\x7d\x76\x55\x90\x7d\xd8\x55\x2b\xc6\xb5\xc3"
-  "\xe2\x2e\x36\xb4\x01\x76\xd5\x08\x5d\xb6\xab\x48\xd6\x65\x98\xf7"
-  "\xa8\x24\x2b\x24\x3d\xb7\x6b\x7c\xfc\x1b\x7d\xdf\xff\xae\x66\x99"
-  "\x46\x32\xcd\x05\x8d\x76\x9d\x1f\x4e\x5e\x51\x13\xa4\xed\x2e\xbe"
-  "\x76\x11\x8c\xb7\xdd\x1e\x42\x7b\xfa\x4e\x15\x72\x73\x17\xea\x7f"
-  "\x4b\xa1\xd0\x29\x22\x8c\x25\x5b\xde\xa7\xbb\x13\x05\x0d\x2a\xf8"
-  "\xdc\x8c\xdb\x92\x86\xb8\xd9\xb4\x2e\x85\xe2\xa0\x90\x65\x36\xd4"
-  "\x7f\xbb\x12\x45\xbe\x5d\xc7\x08\x97\x50\x7c\x1f\xab\x7c\xb1\x72"
-  "\xd3\xb6\x4a\x9a\x50\xdb\x52\xad\xdf\xb0\xa9\xb4\x6c\x4a\x94\xf9"
-  "\x10\x1d\xdd\x97\xea\x69\x1e\xf7\x6b\xf5\x4a\x1a\xed\xd3\x17\xf7"
-  "\x07\xbc\x32\x47\x7f\x07\xf1\x97\xed\x75\x9a\x2b\xe0\x77\x38\x90"
-  "\x6f\x54\x31\x6f\x30\x48\xf9\x05\xad\x5f\xb9\x7e\x78\x5b\xb9\x64"
-  "\x63\xd5\xff\x81\xe8\x28\x8d\x39\xd8\x59\xd8\x3d\x59\xd6\x43\x84"
-  "\x1f\xb7\xcd\xc7\xd2\xb8\x5c\x0c\x8c\x95\xab\x38\xbd\xc6\xd2\x50"
-  "\xdf\xd8\x06\x5d\x68\x8b\x4b\xf5\xf2\xc8\xf4\xa0\xfa\xa3\xad\xab"
-  "\x1e\x61\x15\xc8\xa3\xaf\xa4\x49\xb0\x48\x7e\x22\x6c\xdb\x71\x79"
-  "\x9f\x38\xf9\x0b\x75\x6c\x25\xff\xbf\xbb\x2f\x07\x1a\x49\xde\xec"
-  "\xce\x90\xe5\x12\xe9\xa2\x00\xc2\xf9\xe8\x8a\x3b\x1e\xfb\x0d\xf9"
-  "\x1d\xba\xe1\x0c\xd4\xd7\x8b\xfb\x00\x76\x97\x86\xdf\x07\x50\x6f"
-  "\xc4\x5f\xbd\xf4\x3b\x18\xf2\x7e\xad\x9f\x9c\xc7\x14\x0c\xdb\xed"
-  "\x88\x48\x73\x10\x71\xea\x1e\xb7\x57\x84\xcf\x52\xc9\x6f\x31\xdd"
-  "\x61\x51\x3f\x99\xfc\x82\x06\x79\x63\xf7\x5c\xc9\x06\x19\x24\xda"
-  "\x91\xbe\xc5\x34\x7c\x2f\x37\xd2\xe4\x7d\x9a\xa3\xa5\x3a\xb1\x91"
-  "\x0a\xe4\x89\xfa\xd4\x20\x1f\x08\x1a\x61\x58\x46\xd0\x4e\xa9\x4f"
-  "\xa4\x3c\xa1\x74\xc0\x32\x96\x8b\xb1\x69\x7d\x89\xac\xb3\xc9\x27"
-  "\xaa\xb8\x0b\x62\x77\xf7\xd1\xba\x41\x1c\xf3\xd7\xd7\x06\x61\xec"
-  "\xee\x96\xe6\x22\x54\x4c\x69\x33\xb4\xf3\x31\x5b\x7d\x6b\x70\x4e"
-  "\x60\x77\x37\xc9\x5d\x0e\x23\xd9\xd2\xe9\xf4\xf0\xfb\x49\x15\xf2"
-  "\xdd\xc3\x98\xf6\xa4\x6c\xa3\xc8\xb0\xba\xc4\x9c\x13\xf7\x63\x89"
-  "\x7d\xd0\x8e\x69\x86\xc6\xe7\x63\xe9\xfe\x21\x79\x0c\x68\xc6\x7e"
-  "\xcc\x6d\xef\x57\x12\x83\x63\x3d\xdb\x11\x2e\x6f\x6c\xe3\x70\x70"
-  "\x7c\xf4\x0a\x44\x8e\xdb\xd0\x7e\xd0\x57\x54\x56\xa0\xf9\xf0\xbc"
-  "\x69\xd3\x32\x1c\x3a\x3c\x6f\xaa\x58\x46\x5b\xca\xf2\xb2\x72\xf8"
-  "\x13\x3b\xc7\xb2\x28\xf3\xc7\xe3\x77\x90\xd2\x9c\x11\x8e\x73\x69"
-  "\xee\x74\x44\xdc\x51\x98\x20\x3d\xd5\xd2\x73\x12\xea\x3d\x1d\xf6"
-  "\x81\x0f\xe9\x0e\x1a\xc4\xc1\x21\xdd\x0b\x29\xeb\x6c\x94\xe5\xaf"
-  "\x7c\x20\xaf\x93\xf1\x3d\xf6\xe4\xab\x90\xee\x18\xdd\xfd\xe2\x97"
-  "\x58\xa7\xf1\xf9\x0f\x31\xbf\x28\xd6\xbd\x30\xdc\x2b\x87\xcb\xf3"
-  "\xb1\x23\xb6\x9f\x24\xca\x73\xaf\x22\xed\x4f\x66\x06\xf3\x86\xcd"
-  "\x6d\xa7\xc8\xeb\x6b\x98\xc6\x28\xd3\x4c\x86\x63\xd1\xb3\x0b\x92"
-  "\x9d\x14\xc7\xed\x6a\xdb\x2b\x8b\xb9\x7f\x50\xb2\xc5\xf9\x3c\xf3"
-  "\x4f\x6a\xe4\x72\x68\x8c\x40\x78\x4b\x6b\x37\xbc\xdf\x93\x1f\x50"
-  "\xe1\x47\xf4\x27\xe3\xed\xff\x6d\xee\x05\x1b\xdb\xca\xba\x7c\x57"
-  "\xd8\xb1\x7d\x9f\x63\x9f\x7d\x0e\xc0\xb7\x95\x75\x8e\x5d\x61\x47"
-  "\x89\xd6\xfb\x9e\x05\x78\xfd\x7f\x01\xf8\xe3\xd6\x7e\x35\x8a\x74"
-  "\x5f\x75\x39\x70\x81\xee\xc2\x6b\xc7\x74\xab\x3c\x17\x59\x1b\xe6"
-  "\x59\x65\x62\x17\xda\x30\x5d\xde\xf9\x0b\xec\x00\xa6\xcd\x2b\xc7"
-  "\x7a\x6f\x65\x3e\x7f\xdc\x8b\x5f\xe9\x1f\x27\x39\xf4\xd7\x06\x77"
-  "\x63\x4e\x2e\xb3\x29\x1b\xd8\xee\xbb\xee\x1c\xb1\xfd\xf5\xd2\xf1"
-  "\x3b\xad\x10\x2e\xd1\x28\xdf\x4c\xef\x2f\x7e\x85\x75\xfa\xaa\x18"
-  "\x75\x28\xb6\xc1\x57\x98\x0e\xc7\xff\x95\x5c\xde\xb8\xe3\xee\x4c"
-  "\xc6\x5f\x5a\x34\xb9\x8f\xb8\x76\xf9\xb7\xb2\x63\x0d\xcf\x20\xfe"
-  "\xe7\x10\xff\x2b\xac\x13\xeb\x70\x74\xdf\x59\x00\xc2\xdf\x4f\x30"
-  "\xfd\x10\x57\xbc\x5d\x91\xd4\x8e\xf1\xc5\x66\x2d\xb4\x63\xda\x67"
-  "\x3c\x90\xd4\x86\x69\x9e\xd9\x9c\x04\x1c\xff\x21\xc4\x3b\x29\x27"
-  "\xd7\x8f\x65\x13\xfe\x58\xfe\x80\x8c\xa7\x5c\x3e\xe1\x2b\xf3\x60"
-  "\x31\xcd\x77\x25\xaf\x38\x4a\x78\x8b\x39\xfc\x3d\xb3\xdc\xd5\xe5"
-  "\xe0\x8e\xbb\xeb\x4e\x17\xec\xc9\xa0\x3e\x44\xf5\x71\x23\x4f\x49"
-  "\xe7\xde\xbe\x92\x69\x20\xc6\x93\x7b\xb2\xe4\xfa\x85\xd6\xab\x60"
-  "\x53\x15\x9f\x47\x5d\xbf\xa1\xa6\x62\xeb\x7a\x1c\x9d\x4d\x01\x13"
-  "\x05\xf1\xf1\x5b\x59\xa9\x7e\x53\xa5\xfe\xb9\xf5\x15\x1b\x37\x6d"
-  "\x2d\xab\x4a\xe7\x43\xee\xea\xb2\xca\x52\x9a\x5e\xad\x5a\x5f\x65"
-  "\x9a\x12\x61\x73\xdb\x73\x72\x69\x3f\x22\xc9\xb2\xb3\xf0\xda\x2c"
-  "\x69\x6e\xd1\xcb\x6c\x46\x3e\x76\x13\xfd\x60\xcf\x57\xfa\x1d\x46"
-  "\x8a\x4f\x12\xba\xe6\xb5\x99\xbc\x5e\xc3\xd9\x72\x3e\xbe\x77\x97"
-  "\xdb\xa8\x14\x3e\x96\x0d\xc1\x3d\xe4\xaf\xcd\x62\x4a\xac\x13\xd6"
-  "\x59\xd8\xa9\x79\x7a\xe9\x2c\xdf\x7f\x3f\x03\x3f\xf5\x63\x3d\x69"
-  "\xad\xa0\x8f\xdb\x81\xfc\xcc\xd1\x4f\x69\x0e\x46\xcf\x6c\x93\x12"
-  "\x89\x0e\xfb\xc4\x38\x52\xa9\x51\x58\x15\x64\x0b\xb5\x2b\x03\x06"
-  "\x5a\x13\x6c\xb7\x05\x0c\xc1\x3d\x3c\x7b\x0a\xc8\xa6\xe5\x73\xeb"
-  "\xbc\x1f\xbc\x5a\x2b\xf3\xb7\x92\xce\x94\xec\x9e\xb1\x44\xc8\xe6"
-  "\x57\x77\x51\x7a\x6c\xa7\x25\x02\x7f\x7e\x6f\x2b\xea\xa3\x9f\xbe"
-  "\x1a\x48\xfe\xc4\xe4\xaf\xd6\x49\x77\x17\xaf\xe8\x0e\x34\xad\x38"
-  "\xee\x47\xbd\x1d\x40\x5b\x94\x35\x7d\x32\xec\x6f\x5a\xf1\xf7\x81"
-  "\x6d\x69\x4a\x92\xdf\x16\x33\xd2\x67\x53\xf9\x14\x76\xb1\xfc\x3a"
-  "\x3f\xdd\xb7\xd7\xb4\xe2\x37\x8c\x61\xde\xe4\x15\xbd\xa4\x23\xf1"
-  "\xdb\x21\x7d\xf7\xd1\x77\x00\x6d\x31\x0c\xfb\x57\xfc\xee\xe7\x77"
-  "\xfb\xc9\xe9\xc3\xd3\x7e\x4e\xdf\x1a\x05\xdf\x23\x68\x40\xdb\x77"
-  "\x29\xd5\x55\xae\x23\x1f\x03\xd0\x3c\xc4\x78\x5d\x7e\x5a\x2f\x87"
-  "\x93\x6d\x2a\xec\x44\xd8\x80\x34\x6d\x11\x32\x6b\x3c\xdd\xd3\x72"
-  "\x9d\x39\x2d\x9b\x56\x1c\x75\x51\xfb\xd1\x7d\xcc\xbb\x6f\xba\x93"
-  "\x29\xf7\x6c\x20\xdd\x90\xef\xe7\x6b\x55\x20\xd6\x36\x7e\x7a\x5c"
-  "\xa6\x1f\xed\x85\x27\xfd\x80\xed\x94\x56\xec\x86\x29\xa2\x7f\xfe"
-  "\xf4\x74\xc8\x18\x64\x88\x71\x7e\xfe\x29\x3f\x67\xc2\x94\xea\xdd"
-  "\xe2\xfb\xd5\xa5\x42\x9f\xbd\xa6\x96\xd3\x62\x18\xdf\x03\x44\x6b"
-  "\x56\xc8\xff\x43\x6d\x11\xe7\x33\x63\xc9\x1f\xc4\x57\xf2\x77\xfe"
-  "\x5a\xa1\x6c\x1b\xe0\x7b\x49\xf8\x19\xce\xd7\xb2\x23\xd7\x98\x9e"
-  "\xdd\xb4\xa9\xa6\xb8\xaa\x8c\x1e\x69\xb7\x6f\x99\x13\xa9\x2b\x12"
-  "\xc5\x3d\x32\xaf\x99\xa9\xde\x24\x3f\xc5\x59\x88\xd7\x8e\x85\x8c"
-  "\xf7\x68\xce\xe9\x01\x92\xfb\xb4\x56\x8c\x71\xa7\x3e\xab\xdd\xc9"
-  "\xed\x8d\x2f\xd5\xa0\x8c\xb5\x87\x81\xfb\xd5\x4e\xfa\xb9\x89\xf7"
-  "\xef\xc6\x4f\x5c\x23\xb6\xbd\x89\xf2\x9e\xa3\xe8\xbe\x1f\x32\xd3"
-  "\xfd\x4d\xbb\xc8\x4f\x3c\xdd\x91\xa7\xfc\xdb\x1d\xfd\x4a\xb2\x2f"
-  "\xea\xf0\x9d\xf6\x64\xf0\x79\x2c\xe9\xee\xb5\xdf\x5c\xea\x47\x39"
-  "\xb2\xb7\x84\x35\x66\xa6\x23\x5d\x8b\x62\xe2\x10\x72\x6e\x56\xac"
-  "\xc1\xed\x8d\xb9\xe7\x82\xd9\xf3\xd2\x04\xaf\xec\xed\xe1\x6b\x41"
-  "\x33\xe0\xaf\xcf\xc0\xde\xdf\xab\x74\x38\x4e\x99\x01\xbf\xc0\xf7"
-  "\x1e\xae\xf7\x75\xe1\x3a\x1a\x66\x0d\x75\xa8\xe2\x18\xf6\x09\xa6"
-  "\x60\xe2\x0f\x8d\x0c\xf1\x17\x87\x3f\x25\x53\xf0\xdd\xe7\x71\x48"
-  "\xa9\x84\x49\x2a\xd0\x4c\x4b\x54\xdf\x72\xf3\x4c\xdd\x03\xf7\x2f"
-  "\xcd\xb0\xd4\xd5\x9a\x59\xc0\xe7\xd5\xb0\xd0\x7b\x02\x7f\xae\x7d"
-  "\x6c\x8e\x55\xc8\xc2\xc6\x9f\x6b\xa3\xe1\xfa\xba\x8d\xd1\x1e\x4e"
-  "\xc0\xfe\x5a\x60\xd9\x02\xca\x8f\x46\x5d\x4a\xb2\x55\x48\xbe\xd2"
-  "\x7d\x97\x67\xe0\xf5\x27\x3f\xc5\x30\xac\xbf\x99\xd9\x3f\x29\x10"
-  "\x67\x0b\x5e\x7f\x3b\xd0\xf4\x49\x41\x10\xbe\x0a\x08\x3e\xda\xc3"
-  "\xca\x83\x75\x83\x4a\xa7\xea\x7e\x70\xea\x3d\xf0\x29\xbe\xc7\x68"
-  "\x4f\x13\xcd\xbd\x10\x0c\x94\x3b\x7b\x2c\x57\x51\x1e\x99\xf9\x3c"
-  "\xa8\xf2\x02\xbc\xfe\x87\xce\x18\xf9\xf8\x5a\x46\x72\x4e\xf2\x88"
-  "\x6d\x1f\xb6\x7f\xd6\x80\xa4\xef\xd1\x1e\xd9\x37\x53\xee\x13\x18"
-  "\x9f\x24\xe6\x63\xf7\x19\xe4\x34\x51\xdb\xe8\xa7\xb4\x87\x91\x39"
-  "\xa8\x5d\xd9\x95\xc1\x41\xf2\xa1\x16\x63\xcc\x6b\x44\xfd\x93\x47"
-  "\x36\x4c\x0f\x4a\x88\x69\xbb\xb4\xb4\x56\x8a\x72\xc5\xf0\x92\x66"
-  "\x97\xa1\x62\x9a\xe7\x7a\xd0\x98\x9f\x56\x68\x7c\x39\x8a\x03\xfb"
-  "\x59\x1f\xd9\x78\xb4\xd6\x40\xb2\x65\xea\x2e\xc3\x7a\xa6\x5c\xba"
-  "\x88\xee\xb6\x9a\x3a\xb4\x5c\x11\xb0\x2d\x5e\x44\x7e\xd1\xec\x37"
-  "\xb0\x7e\x4c\x77\x1a\xd3\xd1\x5c\xd3\x00\xa6\xed\x3e\x0b\xfb\xbe"
-  "\xc6\xe7\xc9\xa9\xbb\x58\xfb\xd4\x21\x16\x98\x67\x85\x38\x09\x5e"
-  "\x37\xbf\x5b\x7e\x8c\x8f\x75\xe3\x83\x63\xdd\x86\x14\xbf\x0d\x26"
-  "\xe5\xc7\xb3\x4f\x11\xc6\x49\x76\x25\x70\xf2\x40\x80\xfb\x87\xa2"
-  "\xf5\xa0\x53\x28\x47\x4e\xcd\x6f\xc6\xb1\x0d\xdd\x13\xb9\x1d\xdb"
-  "\xd2\xeb\x25\xbb\xc6\x81\x65\x74\xa1\x9c\x38\xbe\x73\x33\x28\xfd"
-  "\x98\x07\x75\x44\xdc\x05\x68\x78\xa9\x77\xb0\x9f\x7c\x6a\x3f\x12"
-  "\xb4\xd5\xec\x7c\x5e\xee\xf5\xfd\xcc\x41\xfb\x78\x3f\xba\xe0\xa6"
-  "\x7b\xd6\x4f\x52\x9f\xa1\x3d\x8d\x14\x8e\xdf\xc7\xe7\x35\x43\x9a"
-  "\x73\x68\x10\x7a\xd1\x4a\x63\x16\x9d\x12\xc3\x8f\xa7\xbb\xd1\x9e"
-  "\x40\xd8\xb4\x7f\x1b\xfb\x7c\xf7\xd4\x21\x88\xc7\xba\x1c\xe7\x36"
-  "\xd6\xb6\xb4\x54\xcc\xe7\x98\x8b\xb8\xa1\xce\x9f\xf9\xd1\x68\xbf"
-  "\x92\x9f\xf9\xbd\x81\xf5\x4d\xf5\x40\x2a\x97\x0d\xdc\x67\x59\xda"
-  "\x1d\x98\xb7\x0b\xed\xe8\x53\x04\x97\xe6\x16\xf0\xbb\x8f\x60\x5c"
-  "\x00\xfb\xa3\x6c\x53\x9a\x8a\xca\x40\x9b\xc0\xa1\x7f\x8e\xd6\x6c"
-  "\xec\xe9\xbd\x83\x5e\xa0\xf0\x06\xc4\x0f\x79\xde\x41\x78\x62\x5d"
-  "\x8f\x8d\xd8\xec\x4b\xe5\xb3\xda\xa4\x1f\xf1\x3b\x57\xe6\x17\x94"
-  "\xc7\xc7\xc4\x79\xd2\x86\x1c\xa2\x09\xe2\x7f\x2a\x70\x25\x30\x18"
-  "\x40\xdc\x08\x0e\xab\xd6\xa9\x10\x7f\x45\xbe\x6f\x84\x61\x1d\x4e"
-  "\xe5\x9b\x47\x18\xc1\xd5\x57\x72\xba\xdd\xce\xaa\xe9\x4e\x22\xfb"
-  "\x51\xb2\x8d\x89\xe6\x42\x9f\x37\xbc\x34\x75\x97\xf6\x27\x53\x87"
-  "\xae\x47\xb9\xdc\x50\x7f\xe0\x0a\xe9\x50\xbb\x43\x2e\x33\x46\x9f"
-  "\xf0\x3a\x51\x1e\x04\xae\xb0\x41\xb2\x85\xc4\xfe\x0b\xbb\xa7\xd8"
-  "\x1c\x67\xc4\x3a\x2a\x11\x17\x6a\xc7\x1b\x50\xaf\x3c\x40\xfb\x6b"
-  "\x10\x07\xb4\x83\x1b\x53\xae\x75\x47\x27\xd6\x55\x87\x69\x70\xfc"
-  "\x63\x17\x7e\xfa\xb7\xb2\x56\x31\xf7\xd0\x38\x7e\xfe\x9d\x5d\x61"
-  "\xb5\x0d\x75\xbc\x5c\x6b\xfd\x56\x5e\x06\xdd\xdb\x38\x58\xa3\x67"
-  "\x5f\x76\xe9\xdd\xb1\xfa\x04\xd6\xa7\xd1\x2e\x9f\x79\x27\xdc\xb1"
-  "\x3f\x5b\x85\x6c\x68\x9a\x3c\x6d\xd7\x03\x6c\x9a\x67\xd1\x22\x5a"
-  "\xfb\x6c\x57\xf2\xbd\x3e\x42\xaf\x0a\xf9\x7f\x0b\xb6\xef\x45\x6a"
-  "\x67\xb4\xed\xfa\x69\xcf\x84\xd3\xc3\xf8\x58\x81\xdf\x65\x8d\x52"
-  "\x8c\xf6\xcb\xd1\x3c\x1c\x96\xe1\x19\x1f\xbb\x86\x95\xd1\x78\x24"
-  "\x52\xf6\x16\x64\xe6\x94\xe9\x37\xd2\x1e\x18\xc3\x42\xb3\x3e\xed"
-  "\xf6\xd2\xf9\x7c\x73\x8c\xfe\xc1\xcc\x25\xfa\x02\x1c\xd8\x94\xa7"
-  "\xaf\x12\x8f\xcc\x82\x5c\x7a\x46\xcc\x95\xea\x47\x6c\x4d\x11\xfa"
-  "\xef\x2d\x9f\xd0\x91\x4d\x66\x97\x62\x66\xa2\x98\x53\xce\x2c\x45"
-  "\x3a\x0d\xb9\x93\x7e\xae\x95\xee\x60\x2b\x75\x27\x7d\xd0\xe7\x4e"
-  "\xca\x49\xa5\xbb\x54\x35\xbb\x98\x57\xe3\x4b\x60\xc4\xa3\x74\x87"
-  "\x2a\xf2\xd0\x60\xc3\x25\x3e\x26\x83\x95\x73\x2c\x2c\xdf\xcf\x9c"
-  "\xed\x97\xa8\xdd\x9a\xba\xe5\x36\xe1\xf6\x2d\xc2\xc5\x7a\x8f\x11"
-  "\x4c\x6c\x6b\x35\xc1\x25\x1b\x17\xd3\x61\xfd\x5f\x3f\x26\xf4\xf3"
-  "\x1b\xc8\x4b\x8d\x66\x89\x87\x0b\xf0\x5b\xeb\x82\x85\x7c\x5f\x51"
-  "\xc0\xa6\x23\xdf\x01\xaa\xc0\xee\x3b\x57\xb3\xc6\x0f\xfa\x64\x98"
-  "\x08\x2b\x51\xc6\x93\xe0\xc1\xb7\x3c\xfb\x15\x68\xca\x2a\x21\xbb"
-  "\x89\xce\x58\x68\xcc\x0a\xba\x47\xa0\x68\xdc\x36\xc4\x38\x94\x81"
-  "\x64\x2f\x16\x4d\xf3\x28\xac\x94\x26\x68\x53\x05\x5c\x0d\xca\x80"
-  "\x17\x75\xac\x56\xdc\x6b\x3a\x24\xcd\x19\xbf\x71\x3c\x7a\x3b\xbe"
-  "\xc1\xf7\x38\x5e\xb2\xa9\xb0\x6e\x4d\x05\xb7\xa6\x88\x7e\x10\xb0"
-  "\x29\x40\x9c\xb7\x7b\xe3\x63\xbe\x8e\x29\xf6\x8c\xdc\x82\xf4\x75"
-  "\xd3\xfc\xa0\x06\xe5\x03\xed\xa5\x0b\x10\xff\xc0\x39\x70\xd6\x8e"
-  "\x58\xe9\x3e\x51\x79\x4c\x89\xe3\xa3\x40\xaf\xc9\x8f\xf1\x2f\x72"
-  "\xdf\x42\x68\xab\x95\x60\x7f\x52\x9c\x83\x37\xac\x84\x3f\x6f\x47"
-  "\x1b\x24\x06\x90\x56\x7c\xcd\x9e\xe8\x93\xbc\xd2\x45\x7b\xb7\xa9"
-  "\xae\x1a\x1f\xd6\x39\xb4\x5e\xca\x80\x6b\x9f\x0d\xeb\xa5\xc4\x7a"
-  "\x99\xcf\x03\xef\xab\xe6\x3f\x91\x0d\x73\x43\xd0\x0f\x76\x73\x47"
-  "\x68\x1d\x03\xe4\xbf\x9e\xd7\xa1\xf9\xb3\x68\x75\x64\x4a\xaa\x23"
-  "\xd1\xa0\x59\xf6\xc9\xce\xf1\x24\xbb\x61\x08\x9a\x0b\xa7\xed\xa2"
-  "\xbd\xec\x99\xa5\xa8\x8b\x33\xa9\x0d\xdb\x6c\xcc\x4e\x78\x46\x6b"
-  "\x2f\x82\x27\x60\xbd\x59\xa2\xd9\x65\x2d\x19\xb1\xbd\x99\x1e\x9d"
-  "\xde\x6f\xe6\x5d\x9b\xde\x6f\xce\xa6\xfc\x84\x07\xed\xed\xd7\x90"
-  "\x93\x06\xe4\x6f\xd4\x93\x7b\xa2\x95\x3b\x6d\x57\x07\xe1\x15\x35"
-  "\x0e\x79\x7f\xa8\xa1\x2a\xbc\x4f\x04\xda\xe8\x9e\xef\xf3\xb4\xff"
-  "\x1d\xc4\x78\xef\xcd\x53\xc1\xbb\x96\x33\xf7\x6a\x14\xfa\x38\xb2"
-  "\x03\xb8\x7c\xc3\xfa\x46\x83\xab\x51\xd8\xc9\xcf\x4b\x26\xca\x95"
-  "\xa8\xf1\xd8\x0f\xf4\x68\x53\xdf\x8a\xf0\x90\x86\xc0\x70\x6c\x38"
-  "\x65\x9a\xc7\x97\x4a\x74\x45\x5c\xcd\xd8\xaf\x69\xfc\xab\x14\xe3"
-  "\xc1\xfd\x68\xff\xfe\xac\x8b\x8f\x37\x93\x32\x0b\xc5\xda\xc7\xfe"
-  "\x72\x17\xfc\x6a\x7c\xae\x16\xbf\xcd\x2e\xb8\xba\x54\xf4\xd5\x9b"
-  "\xde\x61\x4d\xd9\xee\x80\x4d\xc3\xf4\x3b\x34\x38\xce\x79\x2b\x09"
-  "\xc7\x1f\x4a\x96\x9c\xed\x0e\xf2\x8e\xd8\xfb\x2f\xf3\x0e\xe6\x3f"
-  "\x16\x9d\x2f\xf6\xff\xdb\xb5\xf9\x62\xff\x87\xd2\x38\xa3\x44\xec"
-  "\x2f\x78\x0b\x64\xfd\x81\xe3\x8c\x77\xf4\x75\x54\xfe\xfe\x66\x51"
-  "\x36\xd2\xc4\x67\x24\x39\x93\x8b\x74\xb3\x62\xda\x74\x59\x36\x10"
-  "\x0f\x69\xfc\xa4\xbf\x80\xf3\x39\xc6\x65\xa3\x1c\x91\xd6\xcf\x73"
-  "\xba\x51\xf6\xcd\x0c\xd8\x9a\x52\xdc\x96\xf2\x77\x69\x7f\x9d\x27"
-  "\x29\x93\xca\xda\xe8\x82\x7f\xe5\x77\x10\x33\x6d\xe6\x49\x84\xd1"
-  "\xcd\xd7\xab\xc4\x99\x95\x44\xea\xe7\x74\xdf\x09\xf5\x75\x0c\x4b"
-  "\x41\xbc\x69\x2f\x0e\xea\x9a\xb7\x0e\xca\xb6\x7e\xc0\x66\x24\x7a"
-  "\xf3\x33\xf2\x38\xde\x99\x39\x8c\xb4\x7b\x53\x19\x38\x74\x65\xbe"
-  "\x0e\xa8\xce\x57\x76\xcf\x38\xf4\xd7\xf3\x40\xf5\xdf\x74\xcf\x82"
-  "\x69\x21\xa4\xec\xba\x47\x05\xff\x9e\x01\x4a\xa2\x83\x0b\xde\x3a"
-  "\x2a\x68\xf7\x96\x47\x6e\x1f\x17\xec\x5f\x47\xed\x41\xe3\xfb\x7c"
-  "\x1f\x1b\x16\xf3\x15\x2d\xa8\xff\x5e\x93\xee\x4a\x6e\xda\x18\x45"
-  "\x27\xac\xd4\x57\x54\xeb\x4b\x37\x6d\xab\x9c\x3d\x3b\x6c\xce\x57"
-  "\xc5\xe7\xef\x6c\x2d\x69\x62\x0d\xa5\x65\x5d\xc8\xf8\x16\x75\x5b"
-  "\x0b\xd6\xbf\x29\x3b\x52\xaf\xe6\x16\x4b\x47\x34\x8b\x0d\x10\x7c"
-  "\x5f\x00\xb9\x0b\x42\x3e\x17\x41\xee\xc2\x45\xc5\xab\xcb\xd6\x97"
-  "\x6e\x0f\x09\xbd\x3b\x74\xac\xd4\xf0\x0e\x96\x1d\x37\x63\x05\xca"
-  "\x0f\xc5\xaa\x97\x49\xd7\xbc\xfd\x68\x9d\x8f\xfd\x19\x79\x37\x83"
-  "\xfc\x22\xf4\xd4\xf8\xa0\x07\xe5\x1b\xbb\x89\xe4\x7a\x82\xf0\x0d"
-  "\xe6\x07\x1a\xc3\x68\xb0\xee\x6e\xd4\xcf\x97\xc5\xfe\xb2\xb7\xb7"
-  "\xf4\xb6\xa0\xcd\x63\xcf\x49\x17\xe3\x8d\xb7\x0d\x18\x9e\x84\xcf"
-  "\x27\xc5\x1a\xd9\xdb\x4f\xa3\x9d\x62\xe4\xe7\x40\xb7\xd2\x39\xd0"
-  "\xb7\x57\x12\x8d\xe6\x79\xac\x20\xfc\x91\xb4\x0c\x92\x9f\x50\x17"
-  "\xbc\xcd\xcf\xf8\x50\x5a\xcc\xb3\x40\xff\x02\x18\xe8\x49\xeb\xcd"
-  "\x18\x67\x60\x8d\x39\xe9\xec\xdd\x22\x5a\x37\x48\xc5\xf0\x37\xe3"
-  "\x14\x5f\x42\x9c\x2e\xe1\xa1\x11\xdb\xdb\xcd\x48\xff\x41\x69\xed"
-  "\x20\xfa\x99\x03\x49\x07\x4e\x43\xd9\x3d\xcd\xa3\x61\xc5\x74\xa6"
-  "\x5a\x41\x76\xde\x10\xf6\xe3\x02\xbe\xf7\x99\x74\xa2\x90\x07\x6f"
-  "\x8f\xcf\xff\xd0\x59\x13\xfc\xf6\xc8\x3c\x3f\x62\x7b\x07\x64\x9e"
-  "\x0c\xdb\x2b\x5b\x59\x53\x56\x55\x56\xaa\xbf\xbd\x7a\x0a\x84\xdc"
-  "\x18\x55\x5e\x56\xa9\xaf\x2a\xdb\xbc\xa5\xac\x9a\xdf\xf6\x44\xb1"
-  "\x11\xf3\x34\xc9\x0f\x95\x8c\xdf\xc9\xc7\xf7\xeb\xbe\x53\x46\x76"
-  "\x3b\x6b\x7a\xc8\xc5\xef\xc3\xe0\x73\x2b\x9f\x94\x07\xf6\x4d\x35"
-  "\x8a\x31\x1f\xdd\xa5\xfc\xae\x57\xac\x5b\xe4\xcc\x14\xf3\xfd\xef"
-  "\xbe\x4e\xdf\x18\xae\x0d\xde\x31\xfd\xce\x67\x34\xbf\x22\xd1\x08"
-  "\x6d\x98\x77\x8e\xc9\x34\x72\x41\xab\x51\x9a\xcb\x1e\xe2\xb2\x02"
-  "\x75\xac\x46\xdc\xd3\x33\x2e\x2f\xe6\x07\x48\x4f\xbd\x43\x7b\x48"
-  "\xe3\xf8\x78\x39\x29\x47\x4f\x65\x11\xcc\xb3\x98\x1f\xdb\x62\x26"
-  "\xca\x49\x94\x35\x6c\x8f\x0c\x0f\xcb\x3c\x44\xe5\x91\xfc\x40\x3d"
-  "\x77\xe3\x39\x78\x97\xc3\x0a\xd8\x73\xf4\x24\x3f\xe8\xdc\x41\xa0"
-  "\x11\xe1\xf0\xf5\xb9\x56\x23\x8d\xd3\xf9\x7d\x35\x08\x8b\xc6\xc7"
-  "\x28\x07\x0c\x1f\xed\xf0\x2a\x29\x4c\xdc\x69\xf4\x0e\xcd\x6b\xa2"
-  "\xbc\xc8\xc1\x3e\xfd\xae\x39\x38\xb7\xdd\x6a\xa4\xf9\x1f\x82\xeb"
-  "\x82\x77\x97\x12\x3c\xb1\xb7\xe0\xdd\x56\x17\xb4\x1c\x0b\xda\x4e"
-  "\xef\xba\x64\xbd\x24\xf0\x11\x78\x7a\x10\x17\x7e\x47\xa1\x38\x23"
-  "\xc5\xeb\x4d\xb2\xb2\x59\xaa\xbb\x5c\x1f\x84\x37\x84\x7c\xc7\xd7"
-  "\x76\x18\x9f\x4b\x16\xf5\x26\xfc\x08\xf7\x50\x9c\x25\x7c\x75\x62"
-  "\x1e\xbe\x35\x35\x74\x9e\x4a\xdc\x01\xd3\x9a\x11\x3c\x7b\xf9\x8e"
-  "\x35\x52\x46\xac\x58\xbf\xe1\x45\xda\x24\x9b\x6b\x48\xd7\x93\xbc"
-  "\x28\x5e\xbd\x32\xf3\xf1\xe2\xcc\xfc\xc7\x56\x15\xf2\x15\xf5\xf1"
-  "\xf8\xac\xca\xe8\x09\xc2\xf9\x4a\x8b\xbc\xa1\xc3\xf6\x8a\x3f\x03"
-  "\x6d\x1e\xb1\xae\xd2\x7a\x3c\x7c\x5d\xa5\xf5\x14\xfe\xdc\x00\x07"
-  "\x12\xf1\xe7\x41\xad\x84\xc1\x6d\x83\x12\xbf\x0c\x21\xbe\x83\x41"
-  "\x7e\x69\xe3\xfb\x7c\x69\x3e\x5b\x8c\x73\x0f\xe0\x58\xe3\x9d\x8c"
-  "\xd0\xb8\xa0\x4d\x7f\x40\x3f\x6e\xd3\x8f\xcb\x83\x03\xb9\xb2\x7d"
-  "\x8f\x61\xa9\x68\xdb\x27\x90\x6d\x2f\xfc\x04\xb6\xf1\x7b\x96\x69"
-  "\xbc\x41\x63\x0b\x8d\x82\xee\x05\x12\xfd\x93\x6c\xa8\x62\xd4\x27"
-  "\x74\x0f\x3b\x8d\x33\xb8\x1d\x4f\xfb\xc6\x79\x1f\x3d\xb0\x47\xee"
-  "\xa3\x64\xcf\xf3\x7b\xe4\xae\xf0\x3b\xdb\x2f\x4a\x63\x43\x9a\xf3"
-  "\x2b\xa4\xb9\x01\xb4\x8b\x75\x34\x67\x4b\x63\x27\x96\xf4\x49\xa1"
-  "\x84\xd3\x49\x9a\x2b\x20\x7b\x98\xcf\x17\xd9\x5a\x73\xf9\x1e\xcb"
-  "\xdd\x33\x56\xf0\x39\x33\xbe\xc7\xf2\xc0\x50\x90\xe7\xda\x3c\xd4"
-  "\x96\x44\x03\xe4\x03\x2f\xdf\x6f\x35\x5e\xe7\xb6\x94\xf1\x3a\x6f"
-  "\xc5\x7a\x8e\xf2\x73\x7f\x09\xd2\x5d\xd7\xbc\x8e\xb1\xea\x17\xbd"
-  "\x6e\x6d\xa5\xdf\x58\x37\x1b\xc4\x53\xbf\x90\xeb\x38\xb1\x7e\x6d"
-  "\x87\x22\xea\xb7\x71\x62\xfd\xda\xba\xc7\xe7\xc4\x44\x1f\xc1\xb1"
-  "\x5e\xdb\x65\xaa\x27\xf1\x01\xd6\xf3\x74\x9c\x4e\x7d\x47\xc8\x7b"
-  "\x7a\x34\xd9\x3a\x6d\x97\x52\x3a\xef\xdf\x9e\x43\xeb\x3d\x04\xeb"
-  "\x0d\x65\xa0\xfc\x0d\x1b\xfe\xf0\x49\x32\x36\x68\xc3\x32\xaf\xc0"
-  "\xaf\x3d\xbb\xcb\x3c\x44\xba\xd9\x1b\x73\x9f\xc5\x56\x76\x9a\x68"
-  "\x49\x34\xc9\xf7\xbb\x1f\x20\x7f\xd5\x23\xb6\x76\xeb\xb8\x6c\x9e"
-  "\xb7\xba\x33\x6e\x17\xe8\x4f\xb4\x2e\xa4\xf0\x16\x17\xb4\x83\xb4"
-  "\x8f\xc4\x13\x99\x17\xe9\x6d\x94\xf2\x3b\xe4\xfc\x91\x7e\xe4\xf8"
-  "\x41\x87\x8d\xeb\xb7\x96\x2d\xe1\x67\x18\xd2\xa4\xab\xf7\xc2\xfb"
-  "\x55\x93\xf1\x61\x9a\x9b\xc0\x76\x4f\xa0\xb5\x69\xa1\xff\x3a\xca"
-  "\xe9\x3e\x54\x8c\xcb\x65\x7c\x9f\xfe\xc3\xfc\x8e\x4a\x6c\xa3\x87"
-  "\xf9\xde\xd5\x5a\x90\xc6\x1f\x1d\x4b\x43\xce\x37\xf0\xbd\x60\xce"
-  "\x5a\xbe\x7f\x02\xdb\xa7\xbd\x2f\xb8\x27\xac\xa3\x34\x44\x7e\x24"
-  "\x86\xe2\xb8\xa9\x52\x5f\xbe\xbe\xb2\x74\xd3\x73\xcf\xa5\xeb\xb7"
-  "\x54\xf2\x95\x01\x52\x2c\xd5\x35\x5b\x50\x3e\x70\xb9\x90\x95\x9b"
-  "\x5b\xbc\xe2\xb1\x35\x4f\x86\xd9\x19\x6a\xbb\x2d\xb0\x07\xe1\xe2"
-  "\xf8\xe7\x75\xb7\xd0\x63\x1d\x27\x5d\xf0\x8a\xb0\x79\xd1\x96\xc1"
-  "\xb6\x9f\x75\x0e\xde\x4b\x0d\x91\x97\xd3\xf0\xdb\xc0\x6c\x1d\x35"
-  "\xd4\x16\x12\x5e\xbe\x50\xfb\x04\xfb\x40\xdc\x88\xed\x3d\xad\xec"
-  "\xcf\xb6\x66\x36\x28\x55\xb3\xed\xd0\xac\x64\xd8\x46\xef\x2d\x46"
-  "\x9d\x7b\x1a\xe3\x0d\x68\x77\x96\x72\x5b\x8c\xda\x44\xd8\xe2\x0e"
-  "\x8d\xef\x01\x6e\x8b\x17\x6f\x07\x05\xd9\xe1\x72\xff\xf0\xe3\xb8"
-  "\xd6\xbf\x95\x0d\x14\xfb\x40\x4b\x7c\xde\x50\x49\xbc\x7e\x0b\xf3"
-  "\x5d\x61\xae\xe2\xed\x6a\x68\xc7\xef\x7d\xe7\x00\x7a\x3d\x3e\x78"
-  "\xe6\x32\x8e\x47\xf0\xbd\xe1\x2c\xf6\x0d\x5f\x80\x1c\xcb\xd2\x9e"
-  "\x0e\xa4\xf3\x7b\x07\x65\x5b\x57\xb3\x4b\xcf\xfd\x0d\xd2\x1c\x39"
-  "\xf1\x02\xd9\x00\xc5\x7e\x8d\x43\x8c\x7f\xdf\xeb\xbe\xe6\xbc\x45"
-  "\xd2\x07\x51\x79\x13\x71\xec\x22\xbc\x10\xcf\x4e\xc4\xeb\x28\xe1"
-  "\xb3\xef\x39\xaa\x57\xdc\x22\x8d\xcf\xc0\xcf\xd9\x11\x9e\xcf\x78"
-  "\x60\x11\xe1\xf7\xcc\xe6\x45\xd0\xf6\x1c\xe7\x0f\xbe\x06\x29\xed"
-  "\x6d\x50\x21\xef\x24\x9c\x85\x9f\x59\x3d\xfc\xfe\xa7\x9f\x15\xb9"
-  "\x40\xdd\x25\xec\x61\x31\xff\x45\x69\x28\x4e\xf0\xd8\xcf\xac\xe2"
-  "\xce\xdd\x9f\x59\xe5\x74\xa1\xb8\x65\xae\x37\xa1\x81\x59\xf1\xdc"
-  "\x73\x65\x55\xd5\xf2\x7d\x92\x69\x9b\x36\x96\x2e\x93\xce\xe6\x54"
-  "\x96\x6d\x2b\xae\x28\xe5\x7b\xff\x30\x54\xbc\x46\xd8\x22\xe9\x34"
-  "\x26\xe0\xfb\x69\xb8\x1d\xf2\xf3\x7f\x6b\x93\x6c\x92\x33\xf0\x3e"
-  "\xf9\x66\x46\xfd\xfe\x7e\xa3\xd0\x0f\x93\x2f\x8e\xd8\xde\x57\xcb"
-  "\xfa\x61\x78\x52\x06\xda\xfa\xef\xeb\xb0\xcd\xfb\x43\x65\x16\x9d"
-  "\x7f\x76\x54\xd2\x1e\x80\x5f\x2c\x0b\x34\x66\x66\xb1\xe4\xf9\x5e"
-  "\xec\x93\xe4\x97\x00\x68\x2e\x4b\xf8\x09\x7e\xbf\x94\x64\x2a\xed"
-  "\x21\xa0\x7b\x7d\x07\xe0\xfd\xc5\x68\x8b\x20\x4f\xfd\xc2\x88\x63"
-  "\xa1\xac\xfa\x1d\xa0\x3e\xb0\x9f\x0d\xd0\x1c\xa5\xd8\x5f\xfc\xbe"
-  "\xf5\x33\xec\x4f\xd2\x1a\x85\xeb\x75\x8c\x73\xc1\xfb\xc2\x67\xbe"
-  "\x3d\xb3\x48\x9a\x67\x28\xc2\x74\x87\x5c\x90\x78\x4c\xe8\x21\x83"
-  "\x9e\xcf\x57\x72\xb9\xf3\x7e\x37\x6b\x32\x74\xf2\x39\xa0\x26\x83"
-  "\x3e\xc0\xca\xe3\xe8\x1b\xed\x9c\x29\x08\x47\x4d\xf7\xb8\x4b\x7b"
-  "\x25\xe2\x90\xe6\x5e\xaa\x2f\xc2\x2d\xa1\xf3\xe1\x34\xae\x97\xe0"
-  "\x97\xd0\x98\x1d\xf5\x4a\x0a\xe9\x16\x96\x94\xb9\x94\x5d\x19\xea"
-  "\x40\xfd\x46\x76\xa6\x7b\xda\x2e\x1f\x8e\x57\x33\x8d\xdc\xde\xf4"
-  "\xdc\xc2\x50\xd7\xf9\xf9\xb9\xb4\xed\x30\x35\xdc\xce\x3c\x98\x2b"
-  "\xf3\x5f\x80\xf2\x5f\x81\x44\xc4\xd1\x3a\x00\x07\xf9\x1e\x1e\x9a"
-  "\xbb\x25\x1a\x8e\x22\xdd\x58\xb2\x01\xb0\x8c\x4e\xb4\x8d\xa7\x9e"
-  "\x85\x83\xaf\x12\xfd\xf6\x05\x90\xdf\x47\xb9\xbd\xac\xa1\x7b\x4e"
-  "\xcf\xc0\xc1\x2d\x44\x3b\x82\x85\x75\xee\xf3\x8d\x14\x3d\x44\xfe"
-  "\x2b\xa8\xee\x3b\x6b\x51\x17\x3d\x47\xf5\xff\xe0\x2a\xd9\x97\x68"
-  "\x5b\xf3\x77\x4b\x29\x0b\x70\xda\xf3\xfd\x0c\x1f\x5c\xdd\x39\xc8"
-  "\x02\x57\x6d\xc0\x4e\xa2\x56\xbf\xaa\x04\x9f\x17\xc7\x81\x34\x6f"
-  "\x6b\x39\x4f\x3e\x36\x3a\x90\xb7\xf7\x00\x96\xab\xde\xb7\x03\xb4"
-  "\xe4\x93\xc4\x62\x62\xde\x5e\x4f\x2b\xf4\x9a\x5a\xe1\x1f\x7d\xcd"
-  "\xe0\xd8\x4a\x6b\x83\x3f\xef\xf8\x27\x73\x33\xed\x1f\x9b\x8c\xef"
-  "\xeb\xf5\x8f\xf3\xb2\x32\xfe\xe9\xd4\x3f\xc3\x3f\x39\xfe\x19\xf4"
-  "\x4f\xf1\xef\xec\xee\xa2\x7f\x84\x6e\xe3\x3f\x82\x65\x80\x05\xc8"
-  "\x46\xa9\x7b\x89\xca\xd8\x83\xb0\x3a\xc8\x97\x87\x36\x30\xac\x9b"
-  "\x82\xf5\x57\xe5\x9b\xa9\xbf\xbb\x91\x97\xfe\x2b\xe1\xf8\xfb\xb6"
-  "\x4b\xa0\x76\x54\xfe\x96\xbf\x0b\xdb\x61\xa8\xc3\x59\xda\xcf\xd7"
-  "\x92\xc9\x77\x09\xdd\x0d\x8c\xba\x37\xd0\x40\x38\xfa\x05\xde\x48"
-  "\x2f\x95\x9c\xbf\xbd\x6e\x3c\x3f\xf7\x95\x7a\x80\xe8\x81\x38\xf5"
-  "\x14\x0a\x9a\x74\xf7\x23\x4d\x1f\x97\xe8\x53\x14\x4a\x9f\x83\x83"
-  "\x44\x1f\xda\x27\x12\xd8\x3a\xd4\x81\xb8\x19\x91\x06\x01\xb9\x0c"
-  "\x6a\x7f\xc4\x95\x11\xfc\x7d\x97\x20\xd1\x51\x49\xfb\x48\x7e\x9e"
-  "\xa7\x29\x50\xa9\x03\x57\xce\x77\x36\x5c\x06\x3e\x87\x4b\x7a\xa8"
-  "\x81\xc7\x13\xcc\x9f\xd3\x9a\x20\xda\x28\xc6\x0c\xfc\x2d\xc5\x9f"
-  "\x91\xf8\x10\x9f\x59\xd8\x5e\x7b\x10\x87\x93\xd8\x56\x1d\xf4\x14"
-  "\x3c\xbe\xc0\x44\x7e\x9d\x24\xdb\x22\x18\xde\xb4\x60\x93\x0f\x79"
-  "\x39\xc0\xc7\x4a\x1f\x9c\x0c\x34\xe6\xa5\x89\x3d\x05\x3f\xdb\x7b"
-  "\x00\xf5\x4a\x6b\x13\x3f\xb7\x96\xd8\x96\xcc\xef\x07\x85\x77\xf8"
-  "\xfe\xd6\x9f\x8f\xeb\xff\x9f\xf2\x7b\x47\x3f\xf0\x2a\xf9\xda\x71"
-  "\xe6\x3a\x89\xcf\xd7\x61\x1a\xb7\x0b\xae\x77\x09\x9d\xf1\x73\x9f"
-  "\xdc\xa7\x50\x5e\xbb\x65\xfe\xc7\x7e\x8a\x78\x23\xbf\xf3\xb9\x47"
-  "\x1c\x1c\xfa\x6e\x19\x9f\x7b\x14\x7c\xfe\x8b\xc5\x32\x9f\x63\xdd"
-  "\x12\x49\x5e\x50\xdf\x8e\xa5\xf7\x51\xae\x76\xd3\x7a\x3e\xbb\xa9"
-  "\x08\x12\xd1\x5e\x4a\x2c\xd1\x30\xa7\xaf\x8b\xf8\x30\x91\xf7\x1f"
-  "\x11\x87\xf6\x8e\x5b\x83\xb2\xb8\x0f\xc3\x55\x72\x38\xc9\xe5\x00"
-  "\x8e\x11\x69\x7c\x9a\xbf\x5d\xc3\xea\x2e\xc3\x4c\x3e\xd7\x23\x87"
-  "\x6f\x77\x6b\x7a\x75\x40\xfb\xfb\x7c\x74\xe6\x95\xf2\x60\x78\x1c"
-  "\xca\xf1\xe3\x58\xae\x03\xd3\xa7\xc8\xe9\xd9\x70\x91\xca\x69\xee"
-  "\xe2\x75\x20\x3f\x0e\xb2\x5c\xc7\xf0\xf8\x7c\xb3\x5b\xc3\xdb\x5d"
-  "\x0e\xab\x2e\xe2\x7a\x88\xce\xd7\xa1\x7d\xc5\x38\x3e\x67\x79\xb8"
-  "\x02\xed\x36\x7e\x37\x6a\x48\x98\x92\xce\x32\x92\x0f\x9e\x90\xb0"
-  "\x38\xc4\x19\xc6\xbf\xb1\xec\x86\x17\xb8\x1d\xa9\xcb\xdf\x8e\xf0"
-  "\xa8\x9c\x17\xa4\xb2\xb7\x33\x10\xbe\xbd\x44\x98\xd0\x79\x87\x5a"
-  "\xc6\x6d\x46\xb2\x7f\x86\x8b\x78\xd9\x81\xe1\x22\xa5\x7f\xb8\x28"
-  "\x8e\xca\x27\x58\x34\xcf\xc8\xef\x68\xf5\x0d\x02\xf9\x95\x64\x8d"
-  "\x9f\x98\x18\xed\xe7\x44\xb8\x1c\x1f\x33\x8e\xe3\x93\x3e\x89\x7e"
-  "\x86\xd1\x7e\x38\xcd\x51\xf7\x14\xf6\x8b\x5f\x12\xef\x83\x5f\x9b"
-  "\x55\xa0\x7f\x81\xd6\x80\x7e\xf9\x23\xe2\x41\x3f\xca\x0a\x7f\x52"
-  "\x56\xc1\xfc\x41\x50\xd4\x61\xff\x13\xe3\xbc\x5f\xde\x47\x3e\x90"
-  "\x2c\x01\xc6\xf0\x3d\x9d\xf8\x5f\x33\x44\xeb\x80\x59\x85\x7c\xed"
-  "\x2d\xf9\x17\x7a\xa7\x77\x10\xba\xad\x9f\x43\xb7\xcf\x69\x3d\x7e"
-  "\xc9\xad\x12\x6b\x70\x2a\x82\x9b\x47\x71\x16\xec\x73\xc5\xfe\x8e"
-  "\x98\x73\x71\x64\xff\x22\xed\xfe\x28\xe4\xfb\x2f\x3b\x64\xbb\xf7"
-  "\x1b\xea\xe0\x25\x3f\x4a\xb4\x46\x1f\x68\x7a\x85\x7c\x96\x59\xd8"
-  "\x48\x1a\xcc\xdf\x41\xe3\xde\x5f\xf6\x4d\xf3\x80\x51\x82\x7b\x51"
-  "\x82\xeb\xbd\x16\x5c\xe2\xdb\xee\x16\x3e\xf7\x8b\x75\x7a\x45\xeb"
-  "\x47\xd8\xfe\xe4\x57\x0a\x50\x8f\x58\x2c\x57\x69\x0e\xe4\xf0\x4a"
-  "\x2c\x47\xdb\xeb\xeb\x03\xf2\xc7\xd6\x16\x40\x7d\x7b\x51\x07\xd2"
-  "\x7a\xa3\xe5\x02\xfc\x6a\x4e\x80\xa5\x69\xd1\x3e\xa7\x39\x4f\x0b"
-  "\xc9\x6a\xb2\xf5\xeb\xfc\x30\xc9\x59\xe3\x02\xf2\x27\x84\x30\xee"
-  "\xfb\x1d\xcd\x2f\xa3\xbc\xf3\x33\x9d\xf2\x93\x2b\x2e\x68\x40\x1d"
-  "\xc0\xfd\x0b\xed\xbe\xe9\x9d\x69\xbb\xe0\x01\xa6\xd4\xf0\xf5\x64"
-  "\xd4\x4f\x69\xd8\xb6\x66\xb1\xbe\x99\x59\x1e\xb2\xb6\x19\x87\x65"
-  "\x7d\x48\x6b\x9b\x4c\x9b\x69\x68\xa5\xf9\xde\xa4\x5f\x80\x3b\xe9"
-  "\x03\x37\xc3\xb6\x1b\xb1\xfd\xca\xe5\x82\x43\x5c\xaf\xef\xa5\xbd"
-  "\xb4\x5c\x67\x1c\xce\x73\x27\x59\x69\xfe\x96\xee\x5a\x52\x04\xb6"
-  "\xfa\x3a\x1b\xbe\x46\xfb\x85\xd3\xe5\xf0\xdc\xde\xa1\x11\x07\xb3"
-  "\x5b\xbd\xd4\x9f\xa4\x32\x34\x58\x86\x9f\x35\x5a\xbd\x2e\x38\x2c"
-  "\xe9\x66\xfe\xae\xa3\x78\xdf\x18\xed\xfd\xfd\xd5\xde\xd6\x51\x9a"
-  "\x63\xfb\x55\x06\xda\x77\x8e\x61\xad\xd5\xbb\x46\x67\x45\xfd\x7e"
-  "\xb8\xc4\xa5\x3c\x6d\x97\xc6\xdc\xdc\x67\x52\xcc\xf5\xed\x77\x75"
-  "\x53\x9c\x08\x04\x6d\xd5\x94\x73\xf0\xe1\x1f\x46\x6d\xa0\x1c\x43"
-  "\x1d\x3d\xaa\x44\x3b\xfd\xdd\xa2\xc4\x7d\x33\xc0\x80\x71\x33\xce"
-  "\xc1\xe1\xbf\xf3\x29\x21\x05\x7f\x5a\xf7\x4d\xe5\x93\x11\xae\x91"
-  "\xe6\x23\x7a\x2e\xd1\xf8\xf3\x88\x38\x27\xfc\x0e\xa4\x06\x10\x1e"
-  "\xcd\xa3\x36\xcc\x80\x54\x9a\x13\xc0\xb0\xb4\x62\xbf\x58\x63\x90"
-  "\xc7\x2f\xbb\x67\x40\x7a\x78\xb9\x87\x25\x5f\x48\x1f\xf2\x3b\xe3"
-  "\xb6\xb9\xe1\x66\xd3\xfd\xec\x0c\xc2\x25\x1f\xb4\x8c\xdd\xa4\x53"
-  "\x8a\xb5\xb8\x23\xdb\x35\x2d\x82\xff\xf8\x9c\x3a\xf2\x1d\xad\x59"
-  "\x48\x73\xb5\x0a\xee\x2b\x2a\x39\xdb\x45\x7b\x2f\x43\xe6\x64\xb4"
-  "\x1c\x0f\xc9\xcf\x8b\x7f\xf7\x9d\x25\x04\x83\xf0\x29\x5e\x2f\xe6"
-  "\x79\xc9\x07\x0c\xd2\x95\xfb\xf1\xdd\xfb\x0e\x24\xbe\xf6\x0e\x68"
-  "\x7b\x9e\xe3\xf5\x3a\x24\xfa\xa4\x0a\x08\xdf\x80\x9d\xfa\x1b\xf2"
-  "\x06\xe2\x4d\xe5\x11\x8f\xf4\xfa\x2e\x3a\x2c\x35\x2c\xe0\x78\x81"
-  "\xce\x1f\x1e\xf9\xca\x51\x75\x04\xf2\xc9\x67\x0e\x9d\x9b\x5f\x07"
-  "\xee\x76\x84\xd7\x3e\x03\xb4\x08\xeb\xb2\x73\x23\xc9\x5c\xdd\xad"
-  "\x8e\xaa\xa3\x08\xfb\xc3\xc9\xa4\xdb\x5e\x47\xfa\x08\x1d\xf7\xe1"
-  "\x71\xa7\xb7\x1f\xc8\x47\xee\x2a\x13\xf3\x13\x1c\x4c\xb3\x9c\xd7"
-  "\xf7\x5d\x9d\xbe\x58\xf8\xe9\xe1\x75\x1d\x9f\x3f\x97\xea\xe1\xbc"
-  "\xc4\xe1\x15\x3a\x4b\xd0\x2e\x97\xea\x24\xd3\x5a\xf0\xd7\x87\x8d"
-  "\x8e\xaa\x83\x40\xed\x43\xe9\xf1\xdb\xea\x1c\xc2\xb4\xe7\xc3\xdb"
-  "\x85\xd2\x60\xdc\xc7\x08\xf7\xde\xe0\xba\x10\xad\x57\x04\xd3\xb4"
-  "\x62\x7d\x90\x56\x9e\x77\x91\x46\x62\x1e\xed\xc3\x59\x84\x2b\xb6"
-  "\xdd\x4c\x67\xcd\xe7\xd1\xf7\x3c\xa3\x0c\x40\xbe\xdf\xd5\xcb\xe7"
-  "\xc2\x7f\x3d\x75\x95\x2f\xc0\x84\x5c\xfb\xb5\x23\x80\xf2\xc0\x85"
-  "\x4f\x92\x09\x5c\xae\xcc\x23\xff\x4b\xbf\xfe\x4c\xa3\x10\xed\x4b"
-  "\x75\x21\xfb\x2b\x5a\x1b\x87\xcc\xd3\x6b\x09\x57\xb9\x8d\x99\xf6"
-  "\x70\x5a\x80\xd6\x5f\x66\x00\xdf\xc7\x2c\xf8\x8f\xd9\x11\xee\xc7"
-  "\x92\x8d\x7b\x44\xd2\xcd\x47\x86\x93\xb2\xd6\xb1\x97\x75\x20\xef"
-  "\x7f\xc0\xfe\x5b\x54\x2c\xf6\x94\xe8\x48\x56\xb5\x2b\x99\x74\xcf"
-  "\xc9\xaf\x1d\x52\xde\x43\xc2\xef\xd8\xaf\xad\x98\xff\x50\xd4\xfa"
-  "\xc6\xcd\x20\x5f\xab\x16\xf2\x49\xc4\xd7\xc9\x51\x66\xa1\x5e\x98"
-  "\xe4\xf4\x8c\xf2\x33\x2a\x67\xe1\xa3\x65\x74\x5f\x2d\xed\x43\x97"
-  "\x71\xfb\x6e\x73\xea\x1f\xa9\xc5\xdc\xda\x47\xd9\xf2\xb8\x91\x69"
-  "\x91\xc6\x36\x0d\xf7\x97\x4a\xeb\xae\x9e\xa4\xc3\x06\x77\xd2\x27"
-  "\x25\xa2\xdf\x7c\x64\x62\x49\x42\xee\x16\x7b\xc1\x4a\xf5\x92\xc6"
-  "\x4f\x93\xa8\xce\x08\xc7\x8e\x63\xda\x2c\x61\x5b\x08\xd8\x31\x7d"
-  "\x10\xcb\x75\xc3\x3a\x89\xf3\x4b\x87\xd3\x78\xdd\xe8\x0c\x2e\xaf"
-  "\x5b\xe7\x54\x3e\x97\xf5\xdd\xea\xd3\x2f\x68\x7b\xd8\xe0\x98\x41"
-  "\x30\x3e\xfe\x80\xef\x0f\xc2\x36\x11\x73\x8e\x9d\x25\x6c\xca\x6b"
-  "\x53\xbe\x1b\xcc\x4e\xb1\xaf\xd8\xfe\x49\xc9\x9b\x74\x47\x00\xdf"
-  "\x93\x4c\xe7\x46\x3e\x7e\x1d\x65\x7a\x09\xbf\x33\x19\xcb\x43\xfe"
-  "\x08\x91\x43\x1f\x6b\xa9\xad\xe6\x1d\x01\xa3\xe0\xc3\x8f\xe3\x69"
-  "\x4e\x49\xf8\x88\xef\x3c\x8a\x7c\x2f\xcd\xc9\xc9\x7b\x65\x14\x7c"
-  "\xaf\x4c\xa8\x8c\xfd\x8e\x38\x8a\x3b\x32\x93\x0f\xf6\xe1\xfb\x41"
-  "\xbe\x47\x10\xf1\xdd\xe6\x93\xe5\x5f\xe7\x41\x76\x85\x0d\xd0\x9c"
-  "\x1f\xd9\x4f\xc5\x24\xcb\xea\x84\x0f\x8f\x11\xdb\xc7\x59\xb2\xad"
-  "\x42\xb6\x35\xed\x85\xa2\x74\xd8\xf6\x17\x29\x8d\xf0\x31\x70\x4e"
-  "\x3a\xcf\xf0\xf1\x93\xd2\x59\x85\x34\xda\xa7\x84\x79\x51\xde\x9d"
-  "\xe2\xed\x4d\x34\xa0\xb2\x39\xee\x4a\x9a\xcf\xfa\xb8\x35\x38\xc7"
-  "\xda\xc9\xf7\x45\x89\xf3\x46\x1f\xff\x6f\xf6\xbe\x3f\x20\xaa\x2a"
-  "\xed\xff\xcc\x80\x4a\x8a\xce\x40\xc8\x8e\x65\x39\x95\xf6\x4e\xbb"
-  "\x58\xd8\xd2\x86\xbd\x6e\x51\xd8\xa6\xe6\xaf\x5a\x6b\xb1\x35\x41"
-  "\xd3\x16\x4d\x6d\x44\x44\x54\x04\x44\xe3\x4b\xa5\x38\x1a\xba\xa8"
-  "\x88\xf4\xbe\x6a\x56\x66\xb4\xaf\x15\x96\x3f\xc6\xc4\x56\x0d\x18"
-  "\x72\xa9\x97\x5c\xb2\x91\x90\x90\x50\x27\x19\x60\x84\x99\x7b\xbe"
-  "\xcf\x73\xce\xbd\x73\xe7\xe2\x0c\x38\xa5\xd9\x7e\xf7\xfb\x07\xdc"
-  "\xb9\xe7\x9e\x7b\xee\x39\xcf\x39\xe7\x73\x9e\xe7\x39\xcf\x79\x9e"
-  "\x3d\xd2\x18\x81\xf6\xf6\xe4\x7e\x81\x8b\x6f\x39\x1c\x41\xd8\x18"
-  "\x68\xa6\xba\xde\x77\x14\xe0\x98\x7c\xaf\xc6\x93\x4e\x13\x9c\x42"
-  "\x06\xc7\xa0\xe2\x52\xca\xe6\x7a\x71\x69\xf7\x7c\xc5\xdf\x86\x49"
-  "\x3c\x09\xa7\xb3\x16\xf0\x65\x8f\x93\xd1\xda\x34\x0c\x79\x30\xcd"
-  "\xd2\x74\xf4\x47\xf8\xb7\x1f\xd0\xd7\xa3\xd3\x34\x2c\xd2\x95\xa1"
-  "\x43\x3f\xf2\x44\x30\x0d\x8b\xa9\x37\x12\x75\xbc\x11\xf5\xca\x99"
-  "\x66\x94\x17\x41\x1e\xd5\xd2\x50\xe0\x53\x60\x9e\x2f\x9b\x45\x34"
-  "\xcf\x26\x42\xd9\x19\x86\x30\xf4\xc5\x88\x7e\x18\xd1\x97\xaa\x2b"
-  "\xc3\x10\x0a\xbf\xc3\x81\xaf\xd3\x52\xed\x30\x3d\xee\x4d\xbb\xb2"
-  "\x28\xe0\x71\x0d\xfa\x83\x54\x5b\x6c\x0e\xb2\xec\x1c\x09\x42\x5f"
-  "\x8f\xce\xb5\x99\xd5\x15\xf6\xaf\x99\xac\xd4\xcf\x48\xc2\x80\x0f"
-  "\x19\x08\x34\xd7\x09\x21\x99\x66\x58\xe3\x4b\x79\xbb\x2f\x50\xde"
-  "\x6e\x5e\x6f\xac\x3f\xc7\xb8\xdf\xc6\xa4\xb3\xba\xef\x59\xef\x84"
-  "\xf2\x05\x53\xf4\x08\x97\x29\x3a\x9a\x9f\x99\x29\x23\xe9\xc9\xb4"
-  "\xc1\x62\x2f\x03\xf9\xad\x85\xc5\xbe\xc0\xbd\x6f\x6c\x23\xb6\x0f"
-  "\xbf\xfd\xd9\xc5\x73\xcc\x77\xa5\x13\xee\x33\xe6\x88\xef\x34\xc1"
-  "\x3b\x4d\x65\xa4\xdd\x14\xcd\xda\x5e\x61\xe7\xef\xc6\xb3\xdf\xf8"
-  "\xbe\x07\x1d\xc4\x36\xbb\xe9\x00\x6d\xc7\xf6\x61\xfb\x9d\x48\x13"
-  "\xa0\x81\xd8\x56\x5d\x87\xd8\x4e\x6c\xe3\x71\x58\x75\x36\x41\x3b"
-  "\xa1\xad\xac\x9d\x1d\xd0\xce\xa3\x89\x84\x38\xd6\xbd\x1d\x73\x29"
-  "\x34\x3a\x1a\xe5\xdd\x8c\xcf\x81\x97\x4f\x33\x11\x90\x6b\x03\xdf"
-  "\x49\x37\xa9\x5f\x01\xde\x24\xdd\x06\xf2\xad\x8d\x36\x54\x40\x9b"
-  "\x2c\x46\xf8\x73\x16\x10\xe4\x71\x24\xbe\x1d\xbe\xad\xfb\x4c\x38"
-  "\x43\xd2\x1b\x68\x03\xf0\xa8\xc0\xff\x40\x9e\x44\x68\x3f\xc8\xc3"
-  "\xf5\x62\xfd\x31\xef\xb2\x1f\x78\xbb\x34\x73\x48\xd8\xc1\x67\x72"
-  "\xd4\x96\xea\x1c\x22\xb5\x65\x2a\xe4\x83\xf6\xe8\xa0\x2c\x16\x73"
-  "\x51\x80\x76\x6e\x86\x7a\x3a\x3c\xda\x54\xde\xe4\x80\x32\xbf\x20"
-  "\xbd\x27\x12\xd5\xa6\xf3\xd0\x8e\xf3\x44\x67\x4a\x07\xfe\xeb\x49"
-  "\xe4\x1b\xff\xa7\xbc\x4f\x1c\x19\x6c\x25\x7f\xe3\xf1\xba\xb8\x6f"
-  "\xb9\xfe\x8d\x64\x4f\x8b\xe4\x3f\x4e\x40\xff\x9b\x21\x99\x35\x38"
-  "\x8e\x98\x2f\x39\x5c\x33\xda\x60\xcc\xe0\x1e\xf5\x22\xf8\x46\x9b"
-  "\x21\x9c\xd5\x27\x8b\xfb\x9f\x83\x7b\x5c\xf3\xd0\x1e\x5d\x05\xef"
-  "\x55\x53\xa0\x19\x96\x0f\xfc\x5c\x29\x5e\x91\x86\x5e\x6d\x87\x76"
-  "\x93\x68\xf8\x46\x22\xca\xf2\xc5\xe9\x36\xf5\x4b\xbb\x49\x84\x7f"
-  "\x98\xf2\xfe\x60\x5f\xf8\x8d\x3a\x49\x2c\x0f\xda\x16\xda\x48\x3e"
-  "\xb8\x41\x39\xc7\xf4\x0c\xcb\x38\x0e\xbe\x5f\x89\x3a\x3f\x3f\xbf"
-  "\xcb\xfd\x56\x66\xd1\x1c\x3f\xdf\xab\x92\xea\x01\xbf\x7d\xc6\x1a"
-  "\xf1\x9f\x0e\x1f\x44\xf8\x2a\x6b\xf5\x06\x76\x36\x2e\x23\x77\x03"
-  "\xe0\x05\xf0\x0a\x18\xdb\x1d\xf9\xba\xd2\x6d\x76\xb2\x60\x0b\x09"
-  "\xca\x38\x87\x3a\xa6\x71\xe4\x70\x41\x24\x29\xbc\x88\x3e\x21\x0c"
-  "\xa1\xaf\x5d\xc4\x7d\x46\x8e\x21\xc8\x93\xa2\xee\x94\x2e\x30\x68"
-  "\xd7\x6c\x90\x78\xf8\x0f\x5a\xd2\x5a\x88\x9a\xc7\x1b\xfd\xc0\x3e"
-  "\x52\x4f\x9d\x79\x6a\x21\xb1\x00\x7d\x2b\x86\x6e\x9f\x88\xbe\x15"
-  "\x25\x5f\x83\x8c\xf7\x49\x85\x39\xd7\xac\xeb\xbd\x3a\x89\x44\xa0"
-  "\x5f\x54\x8d\x8d\xf3\x72\x7c\xbd\xfe\x70\x30\xd4\x4f\x2b\xee\xad"
-  "\x69\xb9\xff\xc1\xf7\xe7\x6c\xbd\xc8\xf4\x9d\xf8\xfc\x29\x17\xc8"
-  "\x32\xac\xdc\x24\x32\xb8\xe0\x22\x31\x20\x1f\x14\x7f\x86\xf3\x6c"
-  "\x28\x1f\x8e\x6b\xd2\x50\xd7\xf7\x06\xb2\xa5\x51\xf6\x9b\x6a\x5b"
-  "\x80\xbe\x56\xa9\xce\xd7\x79\xc0\x35\xe1\x6c\x2f\x9d\xf9\xc2\x42"
-  "\xfb\x00\xb8\x27\x79\xeb\x48\xe0\xe1\x81\x84\xa0\xde\x10\xf7\xe5"
-  "\x0e\x3b\xf9\x79\x8c\xb6\xac\x0f\x4b\x25\xbf\x92\xde\xb1\xfc\x0d"
-  "\xb4\x71\x04\x1e\xeb\x0d\x3f\xc7\xd1\x87\x75\x3e\x65\x15\x28\x13"
-  "\xc7\xc1\x8f\x2b\xb7\x64\x44\x17\x7c\x4d\xa0\x60\xe2\xb2\x99\xd0"
-  "\x13\x64\x46\x5b\x9b\x99\xfb\x43\x2a\x29\xb1\xac\x14\x3c\xe4\xb1"
-  "\x92\x8d\xf8\x0c\xd3\xd0\xc7\x44\x0c\xeb\xf7\x12\x2b\xca\x68\xa2"
-  "\x9c\x7b\x50\xef\x4e\xe3\xfc\x16\xae\xbb\x48\xaf\xad\xdc\x67\x55"
-  "\xbf\xb6\xac\x12\xa7\xb4\xf6\x22\x0f\xc2\xf5\xd1\x7b\xb5\x56\xf5"
-  "\xa9\xa3\xbe\x68\x89\x7b\x26\xcc\x7f\x16\xda\xba\xa0\x5f\xcb\xac"
-  "\xbd\x31\xd2\x5a\xcc\xce\xb9\xae\xb8\xe9\x91\x05\x8b\xc9\xc0\x3f"
-  "\x0e\x08\x22\xb8\x2f\x05\x79\x1b\x38\x8f\xb0\x37\x51\xd6\xe1\xc7"
-  "\xb0\xb1\x81\xe7\xa5\x98\x3c\x84\x7e\x88\xb8\x3f\xd7\x26\xc9\x1f"
-  "\x11\xe7\x15\xf6\xbe\xe4\xf1\x9d\x9d\xee\x35\x1f\xbe\x81\xfb\xbd"
-  "\x58\x3e\xe7\xa3\xf6\x4e\x61\x36\xf7\x90\x8f\xf3\x02\x7b\xa7\x74"
-  "\x41\x5f\x03\xd2\x57\x10\x65\x5f\x4b\xd3\x77\x9c\xbe\xa9\x24\x00"
-  "\xed\x5a\x0f\xa6\x5b\x03\xfb\x71\x3f\x83\x1a\xf8\xfe\x25\x7c\x8e"
-  "\xf3\xd2\x7c\x37\xea\x41\x3f\x7a\xca\x82\x3c\x46\x47\x5c\xf0\x78"
-  "\xd4\x4f\x30\xb9\xe1\xa3\x91\x68\x73\x0a\x69\xa1\x07\xce\x3b\x02"
-  "\xd7\x2c\x21\x11\xdc\xaf\xd3\x47\xec\x9c\x98\xed\x57\x2f\xb4\xdd"
-  "\x11\x46\x74\x77\xe4\x11\x43\x5b\xd6\x47\x73\xac\xea\xaf\x99\x0d"
-  "\x10\xfb\xfe\xba\xfd\x26\x66\x03\xdb\x6e\xed\xc1\xfb\xea\xe3\x1b"
-  "\xe0\xde\x20\xdf\x7f\xb4\x5d\xdc\xbf\x01\x9e\xec\xe3\xa0\xad\xe7"
-  "\x19\x2f\x55\xc9\x74\x62\xa6\xed\x0e\xd9\x7e\xe0\x63\xee\x87\x03"
-  "\xae\x87\x8d\x84\xa0\x3d\x69\x61\x38\xad\x84\xef\x01\xff\xb3\x77"
-  "\xa0\xa8\x43\xaa\x64\xe3\x0a\x79\xf3\x6c\x94\x17\xbf\x33\xa3\x4d"
-  "\x2a\xae\x69\xc0\xcb\xc5\x70\x79\x63\x87\x56\x80\xf1\x23\xb7\xff"
-  "\xa3\x85\xa8\x67\xf5\x8a\xdf\x9b\x08\x61\xef\xac\xdd\x1e\xcd\xec"
-  "\x4e\xd6\xee\x6f\x80\x6b\x10\xcc\x05\x7c\x16\x0c\x63\x0e\xaf\x5a"
-  "\xb8\xa2\xac\x17\x06\xcf\x2b\x71\x5c\x82\xbc\xad\xc3\x78\x3c\xcd"
-  "\x21\xdb\x23\x7d\xd9\x8e\x23\x6d\x2c\x2b\x9f\x26\xdc\xb6\xee\xe3"
-  "\x26\x8c\xc5\x32\x61\x0b\x21\x0b\x9c\xb4\x5d\x7f\x2b\xe9\x05\xed"
-  "\x6d\xca\xd8\x82\x7b\xe0\x1f\x9b\x95\x7b\xe0\x1f\x5b\x09\xd9\xa7"
-  "\x87\x3f\x48\xd9\x07\x7c\xe4\xc7\x4d\xf2\xdf\x3e\x6b\x5b\xd6\xc7"
-  "\x4d\x40\x47\xee\x6b\xca\xaf\xf9\xfa\x31\x8b\x91\xb7\x06\x65\xb8"
-  "\x90\x97\x88\xd8\xde\x18\xb8\x0f\xa2\x21\xfb\x33\xc5\xf6\xea\xe0"
-  "\x5e\xab\xcf\x80\x35\x38\x04\x68\x72\x13\xb4\x39\x64\x7f\x03\xb6"
-  "\x17\xeb\xdb\x1c\xf2\x86\xc2\x6e\x1e\xcb\xc4\xf6\xdb\x42\xe0\x3d"
-  "\xa0\x25\xbd\xfb\xc9\x62\x89\x9e\x22\x9d\xd0\xd6\x58\xdd\x0c\x65"
-  "\x70\x9e\x0d\xf2\x43\x19\x52\x7e\x37\xed\x6f\x42\x1f\x29\xd0\xa7"
-  "\x90\x0f\xe4\xf7\x20\xc9\x26\xbf\x2d\x6b\x5f\xf5\xa1\x39\x7c\x5f"
-  "\x05\xdf\xb5\x7b\xbc\x8b\xe7\xa0\x15\xef\x87\x78\xf4\xdd\x4d\xe8"
-  "\x2b\x20\xd3\xc6\xfb\x6e\x7b\x8c\x58\x97\x30\x5e\x97\xed\x36\x18"
-  "\x63\xe7\x78\x7d\xf6\x95\xf9\x9a\x63\xe9\xb7\x01\x8f\x0a\x9c\xfb"
-  "\x3d\x5c\x76\x1d\x61\x19\x68\x27\x96\x02\x01\xf8\x96\x1d\x91\x31"
-  "\xe9\xd4\x5c\x4f\xf6\x6f\xaf\x70\x34\xf8\x89\x99\xfb\x79\x8c\xb4"
-  "\xf6\x4c\x62\x49\xbb\x17\xf7\x69\xc9\x79\x72\xe0\x0b\x8b\x8d\x9d"
-  "\x51\xc2\xdf\xcc\x1e\x12\xf7\xa7\x71\x7d\x43\xdf\xbf\x92\x9e\x40"
-  "\x80\xbc\x85\x98\x0e\x69\x78\x6e\x72\xab\xc7\x33\xba\x6e\xbb\xb8"
-  "\x8f\x74\x60\x35\xf2\x47\xac\xbe\xce\xc7\xcc\x58\x67\x98\x63\x3a"
-  "\x6c\x43\x06\xda\x0e\x3b\xdb\xcc\x38\x57\xf4\x29\xa8\xf7\x3c\x30"
-  "\x0b\xc6\x23\x15\xd6\x6e\xd7\xf9\xd7\x86\x03\x51\xf8\xcd\x0c\x27"
-  "\x3d\x6f\x0b\xd9\xae\x43\xbe\x6a\x4d\x7a\x8f\xa0\xd8\x02\x6a\x6e"
-  "\x0e\xdd\x11\xd9\x96\x75\x60\xd5\xa1\x54\xde\x67\x7e\x96\xbb\x4a"
-  "\x6a\x7b\xa1\xd8\x76\xa0\x17\x1b\xb3\xf7\xe4\x73\x9f\xca\x90\xa7"
-  "\xd4\xf7\x5a\xb6\x43\x8b\x6b\x19\xac\x19\x97\x38\x2d\x0e\x86\xb9"
-  "\xd7\x0c\xbf\xea\x71\x30\xec\x0a\xbe\xd1\x21\x7e\x23\xf5\x47\x7e"
-  "\xa3\x8b\xf3\x31\x8c\x67\xbc\x05\xa4\xff\x40\xff\xe5\xdf\x83\x95"
-  "\xdc\xb6\x69\x87\x8e\x63\xe9\xa1\x85\x2e\x90\x41\x9d\xda\xfd\x31"
-  "\x2c\x0e\xb5\x9a\x64\x5a\xac\x4e\xe2\x34\xbd\x44\xca\x53\xdb\x89"
-  "\x39\xe5\x04\xa9\x23\x66\x16\xff\xa0\x3c\x19\xe5\xce\xfd\x99\x1d"
-  "\xeb\x76\x64\x76\xa8\x0f\x62\xac\x9e\xc4\x2d\xe8\xbf\xda\x63\x9c"
-  "\x55\xd8\x4f\x10\x4b\x02\xea\x8a\x2b\x51\x47\x9f\x09\x73\x2e\x46"
-  "\x00\xcc\x00\x39\xc3\xc5\xe8\x01\x3c\x18\x97\x19\xdf\x36\x30\x99"
-  "\xd1\xc6\xfc\xba\xf5\x05\xde\x3d\x98\x66\xad\x72\xa2\x1e\xdf\xd5"
-  "\x11\xa7\x6f\xcb\x22\x13\xd1\x97\x34\xea\xd0\xa9\x36\x76\xd4\x04"
-  "\x67\x00\x65\x32\x21\xc8\x2f\xe8\x53\xda\x62\xb7\x12\x17\xc8\x02"
-  "\x05\xad\x24\xac\x00\xf8\x67\xc0\x72\x86\xf7\x5b\x45\x9f\xd2\xab"
-  "\x5b\x65\x9f\xd2\x85\xa8\xaf\xaa\x86\xdf\xad\x24\xd0\xb5\xf6\x6d"
-  "\xc3\xe6\x56\x32\x78\x4b\x0a\x31\x6c\x46\x7d\xe4\x59\xce\xbf\x21"
-  "\xbf\xc1\xfc\x4b\xbf\x68\xc0\x7d\x11\x99\x7f\xc3\x33\x76\x32\x9e"
-  "\x05\x32\x3d\x8e\x5f\xf4\x3e\xc4\x6c\xb2\x9c\xa6\xed\xd1\x40\xe3"
-  "\x86\x8e\x75\x6f\x40\x9a\x39\xb9\x43\x7d\xc0\xeb\x5e\x85\x64\x7f"
-  "\x92\xe7\xe1\x13\xfc\xd0\x60\x8e\xfb\x50\x96\x4f\xdf\xc4\xae\xcd"
-  "\x71\xe4\x9e\x26\x12\xc9\xcf\xb7\xdc\x00\x6b\xe5\x27\x03\xd1\x26"
-  "\x31\x7d\x2e\xd1\xb9\x36\x4f\x51\x65\xbc\x4e\x02\x2c\xce\x18\x82"
-  "\x7f\xe9\x3f\xd0\x86\x7b\xe6\x90\x48\xdc\x4b\xc1\x7d\x1f\xfd\x52"
-  "\xcc\x7f\xe8\xdc\xe0\x34\x12\xe9\x59\xf6\xdc\xc5\x49\xb3\x86\x45"
-  "\xfe\x65\xa6\xfe\xf9\x59\x49\x73\x17\x4d\x4b\x9a\x49\x46\x71\x13"
-  "\x0e\xe6\x32\x73\x31\xda\x6f\x2c\x9a\x95\x9c\xa8\x7f\x6e\x61\x52"
-  "\xd2\xcc\x79\xc9\xfa\x71\xb1\x13\x2f\xf7\x9b\xb4\x59\xb7\x8d\xf9"
-  "\xc9\x63\xb6\x7d\x87\xcb\xe9\x5f\x7f\xd3\x9a\x9b\x42\x02\x35\xcb"
-  "\x1f\x9d\xa4\x71\x8e\xd2\xf3\xb8\x12\x87\x6d\x68\x4b\x4b\x33\xe2"
-  "\xf2\x39\xaf\x7d\xf8\x07\x2e\x9f\x8c\xae\xe4\x67\x36\x0f\x33\x3d"
-  "\x31\x6d\x1b\x35\x90\xcf\xa9\xc3\xaa\x80\x64\x82\xbf\xe7\xe2\x6f"
-  "\x4d\x32\xc9\x31\xdf\x84\xfb\xf5\x87\xf9\xbe\xca\xe6\xb1\x2a\x29"
-  "\x9f\x94\x87\x3f\xff\xc4\x8a\xcf\x0b\x99\x0f\xb1\x4f\x0c\x40\x9f"
-  "\xd0\xb6\xac\xc3\x3a\x6b\xe0\x3d\x92\x3f\xb9\x06\x6e\x7f\x77\x98"
-  "\xf9\x11\xa2\x7f\xbd\xb9\x55\x2c\x67\x22\x7c\xaf\x0f\xe4\x1d\x09"
-  "\x7d\x50\x26\xda\xe9\x0d\xaa\x15\xeb\xc5\x6d\x61\x3f\x79\x80\xdb"
-  "\x9a\x1c\x4e\xf4\x38\xaf\xc7\xce\x2a\xe2\x9a\x29\xf2\xaa\x6d\x62"
-  "\x79\xab\x24\x4c\x80\xfc\xf9\xc0\xef\xe9\xfd\xc7\xc2\xc3\xfc\x5c"
-  "\xa5\xe2\x7c\xb8\x48\xa7\xcd\xba\x1d\x80\x0f\x03\x1b\xc9\x27\x99"
-  "\x9d\xc7\x8b\xbb\x07\x47\xcf\x7b\xee\xc5\xb9\xc6\x69\xc9\xb3\xa6"
-  "\xcf\x9a\x33\x2b\x79\xf1\x03\x2c\x40\x0a\xfb\xf7\x87\x21\x33\x26"
-  "\x75\xf6\x79\x19\x81\x7a\x22\x3c\x1b\x85\xb2\x3e\xea\xe7\xd0\xc6"
-  "\x82\xeb\xeb\x4a\x5f\x66\xbe\xed\xfc\xaa\x7b\xa9\x78\x7e\xb2\x34"
-  "\x0f\xf8\x44\xd1\xce\xfa\x0d\x62\xbe\xdd\x85\xe5\xb1\x67\xcd\xda"
-  "\xfd\x95\xfa\x9b\xc8\x88\x5a\x72\x74\x04\xee\xd9\x01\xfd\x82\x70"
-  "\x3d\xcc\x5d\x82\xeb\x96\x95\x94\x3b\xef\x15\xe3\xda\x1d\xd9\x88"
-  "\x34\x40\x5e\x11\x68\xb0\xad\x96\x1c\xe1\x32\xf6\x05\xdd\x36\xb4"
-  "\x5d\x12\x2e\xe8\x76\xe0\xd8\xc2\xfa\x0a\x34\x6e\x33\xa5\x71\x9b"
-  "\x84\x0b\x89\x9b\xe9\x85\xc4\x4d\xb2\xbf\x9d\x23\xc9\xf0\xee\x2e"
-  "\x78\x77\x31\xfa\xef\xcf\x3d\x4f\x76\xa1\x3d\x00\xde\x6b\x92\xb5"
-  "\xc4\xa5\xdd\x41\xb0\x3e\x96\x86\x48\xc6\x87\xd7\x41\x7e\x8b\xfd"
-  "\x5e\x02\x3c\x66\x10\xda\x63\xf0\xbd\x47\xe0\x03\xe1\x3d\x0b\xd4"
-  "\xcb\xd2\xd0\x8e\x72\x3d\x11\x80\x17\x84\xb6\x6e\x83\xf5\x33\x12"
-  "\xcb\x45\x7b\x10\xe0\x57\x81\x3f\x3b\xb2\xca\x4a\x3e\x91\xf6\x3c"
-  "\x99\x2d\x88\xb2\x1f\x8f\xbc\x03\x74\xee\x25\xf9\xf8\xc4\xb5\x04"
-  "\x65\x06\xf9\x5c\xe4\x91\x2f\xb0\x8d\xb8\x9f\x3f\xde\x4e\x85\x42"
-  "\xf6\xec\xde\x4c\x8f\xfd\x75\xcc\xc3\xfc\x5b\xa3\x3d\x8b\x71\x09"
-  "\xc6\x39\xfd\x34\x84\x8f\x97\x7b\x33\x6c\x19\x89\x01\x62\xb9\x2e"
-  "\x2c\x17\xfd\xc8\x70\x5a\x7e\x3a\xcc\xb2\xf2\xbc\x64\x47\x02\xf5"
-  "\xf8\xf4\x0b\xb1\x8c\x26\x9c\xcb\x42\xd6\x61\x27\xda\x52\x33\xbf"
-  "\x91\xfc\x2c\x92\x0a\xe4\x53\xf4\x53\xa4\x2d\x0c\xe5\xfe\x65\xdb"
-  "\xb2\x3e\x75\x8f\x7f\xaa\xe5\xbc\x20\xf2\x63\x18\x9f\x04\xc7\x3f"
-  "\xf2\x76\x58\x3f\x1c\xff\x50\x7e\x1e\xee\xdb\xf3\x79\xf0\x69\xd1"
-  "\x8f\x9b\x07\x9f\x16\x49\xb4\xe0\xf2\xe3\xa7\x91\x54\x9d\x41\xef"
-  "\x59\x45\x12\x98\x7d\x85\x78\xde\x0e\xd6\x90\x11\x1c\x5b\x8e\xde"
-  "\xc2\x6c\x63\x52\x9a\x8a\x00\xe3\x33\xb7\xb6\x93\x60\xc1\x14\x1b"
-  "\x83\xbc\x78\x79\x1a\xb3\x4b\x09\x82\xf7\x8a\xd1\x6e\x05\xed\xf0"
-  "\xfa\xb1\xd8\x37\x27\xc8\xd6\x16\x12\x58\x47\xfe\x6e\xc0\xbd\x2d"
-  "\xb9\x1f\xfe\xbe\x0c\xf7\x34\xe9\xba\x7b\x1c\x9a\x34\x75\x0e\x96"
-  "\x21\xb4\x9e\x8b\x96\xde\xc3\x73\x71\xf8\x5e\x2d\xf9\xfb\x34\xf6"
-  "\x1e\xe6\x45\x9a\xa5\x6b\xa7\x00\xcf\x15\x8d\xf9\x9d\xc0\x8b\x15"
-  "\x0a\xda\x89\x14\xd6\x06\x57\x8a\xb3\x18\x9e\x4d\x12\x4c\x6f\x04"
-  "\x41\x5a\x1c\xdb\x53\xe9\xd0\xe1\x9e\x2b\x8c\xb5\x4c\x87\xa5\xee"
-  "\x3b\x33\xab\x0f\xda\x9f\x26\xc3\x3a\xca\x64\x97\xbf\xbf\x5f\x78"
-  "\x16\xfa\x23\x9c\xc5\x06\x81\x7e\x3e\xca\xe2\xd1\xc1\x58\xdc\xc9"
-  "\xeb\x78\xf4\xd1\xe6\x75\xd1\xd1\xcd\x30\x56\xed\xea\x20\x72\x58"
-  "\x87\xf6\xee\xfb\x2b\x0f\xeb\xda\xa1\xaf\x8e\x86\x01\xf6\x25\x72"
-  "\xde\x99\xbf\x87\x63\x34\x40\xd7\xaf\x03\x9e\x45\x4a\x76\x52\xdc"
-  "\x56\xe9\xef\x41\x48\x33\x18\xcf\x47\x2b\xe6\xa0\xbd\x9b\x50\x06"
-  "\xdf\x20\xae\x14\xa1\x06\xf7\xfb\xf1\x4c\x01\xca\x3b\x13\x52\x69"
-  "\x33\xca\x6f\x78\x0e\x0b\xf7\xf8\xf1\x8c\xe2\x16\x90\x7f\xb1\x5c"
-  "\x28\x73\xa5\x74\x8e\x70\x35\xa4\xb1\x71\x1f\xf0\xe7\xb3\xb9\xb3"
-  "\xd9\x9c\x43\xdb\xd0\x60\xb6\xbf\x11\xf0\xc2\x59\x18\xd7\xcd\x85"
-  "\xe7\xd9\xbe\x5c\x73\xa1\x58\x0e\xfa\x29\x80\x32\x8e\x4a\x65\x08"
-  "\x29\xb4\x0e\xed\xf2\x5c\xad\xd4\xca\xdf\xe7\xf6\x1b\xe3\xed\x02"
-  "\x3b\x23\x83\xef\x73\x3b\x8e\xa3\x4e\x0f\xbb\x78\xc0\x9d\x63\xc1"
-  "\x92\x1f\x03\xf8\xad\x93\xe4\x75\xa4\x51\xb3\x69\x07\xb1\xc3\x5c"
-  "\xb7\x9b\xb6\x03\x9f\x7a\x2c\x0a\xf0\x3e\xaf\x0b\x1d\x41\x20\x62"
-  "\x22\x9e\xfb\x15\x42\x63\x13\xf1\xec\x2f\xfa\xda\xe4\xb6\xed\xc7"
-  "\xd6\x8b\xe7\x80\x03\xce\x93\x63\x4f\xc8\xfb\xfd\x2e\x51\x47\x7d"
-  "\x6c\x1f\x97\x2f\x8e\xed\x63\x3a\xea\x75\xdb\xad\xff\xbd\xc4\xa1"
-  "\x2e\x5e\x62\x55\x73\xdf\xae\xc7\x8a\xad\x20\x01\x48\x76\x69\x90"
-  "\xcf\x88\x65\x79\xe7\x07\x47\x8b\xe3\xf1\x38\x93\xa3\x65\x39\xfe"
-  "\x38\xf3\x2b\x87\x7b\xf3\x02\xf2\x76\xa1\x2f\x69\xd1\x9e\xcb\x62"
-  "\xbc\x88\xba\xea\x9e\x5c\xa7\xc0\xf3\x88\xb6\x93\x37\x36\x2a\xef"
-  "\x43\xf1\x9e\xd3\xec\x78\x8c\xb4\xef\x95\xab\x16\xac\x1a\x15\xa1"
-  "\x19\x45\x80\x7d\x46\x3b\xfa\x1f\xb0\x59\x80\x57\xc4\xd8\xa2\xc6"
-  "\x24\x8c\x63\x74\x7c\x21\xfa\x34\xe7\xf3\xed\x38\x3b\x37\x27\x64"
-  "\x3d\x44\x33\x50\x5e\xb2\xa1\xaf\xf3\x8b\x04\xf2\x85\x40\xbe\xd7"
-  "\x4b\xd3\x9a\xd0\x4e\x2d\x0a\xe3\x6c\xd5\x89\xdf\xb6\x85\x8c\x36"
-  "\xdc\x11\x4c\x12\xe0\x9b\x7b\xac\xa4\xc0\xe4\x3f\x26\x1c\xdf\xd3"
-  "\x95\x3e\x96\xb7\xeb\xb3\xc1\x72\x9f\x7c\x23\xf6\xc9\x67\x83\xbb"
-  "\xb3\x95\x10\x79\xef\xfe\x8d\xa4\xbc\x3f\xea\x87\xe0\xf7\xa0\x46"
-  "\x52\xc6\xb0\x96\xdb\x21\x97\x7d\x25\xfe\x86\x6f\x94\x1d\x12\x7f"
-  "\xdf\x0c\xbf\xdf\x14\x7f\xdf\x04\xbf\xd7\x8a\xbf\x81\xde\x65\x8b"
-  "\xc5\xdf\x61\xf0\x7b\x9a\xf8\x1b\xe6\x71\xd9\x68\xf1\x77\x38\xfc"
-  "\x1e\x26\xfe\x1e\x00\xbf\x07\x88\x7b\xcc\x41\xf5\xa4\xac\x87\xff"
-  "\xfc\xff\x67\x95\x7c\xed\x2d\x83\xb1\x57\x2a\xfa\xd1\x71\xa7\x0d"
-  "\xb6\x92\x92\x34\x69\x1f\x09\xd2\x8f\xe2\x77\x20\x7d\x04\x8c\xbf"
-  "\x18\x8f\x74\xd1\x37\x7b\xd9\x24\x90\x27\x4a\x3c\xd2\x77\x89\xe9"
-  "\x73\x20\xff\x51\x8f\xf4\x22\x31\x1d\xe6\xff\xdf\x02\x3d\xd2\xf3"
-  "\xc4\xf4\x02\xc9\x76\x43\x4c\xcf\x11\xd3\xa1\xff\xdf\xdc\xe5\x91"
-  "\x9e\x26\xa6\x97\x41\x1f\xdb\x3d\xd2\x99\xcc\xcc\x7d\xed\x69\xe8"
-  "\xe1\xb4\x28\xc0\xb6\x32\x9b\x95\xbc\xbb\xcd\x23\xcf\x0c\xfe\x6e"
-  "\x39\xd0\x60\x77\x99\x47\x7a\x9c\x98\xae\xb7\x92\x4b\xab\x3c\xd2"
-  "\xc7\xfa\x1a\x43\xaa\x7c\x92\xe0\x4b\x9f\x8b\x7c\x23\xb3\x45\x65"
-  "\x7c\x64\xc5\xb3\x78\x3e\x46\xb3\x85\xd6\xea\xd3\x29\xad\x25\x15"
-  "\x23\x45\xbb\xcc\x48\xbe\x5e\xe1\x98\xaf\x18\xca\xce\x9e\xa0\xaf"
-  "\x37\x3c\x67\xb4\x04\xcf\x19\x95\xb3\x3d\xf3\x7b\x52\x33\xb9\x1f"
-  "\x38\xc9\xa7\x30\xea\x04\xc4\x3d\x5f\xc8\xf3\x15\xea\x4e\xb1\x1c"
-  "\x5c\xc3\x2d\xc9\xed\xdc\x47\x20\xc8\x0e\x98\x86\xb2\x31\x3b\x8f"
-  "\xe2\x21\x9b\xf1\xf9\x58\xf1\xac\xd0\x8e\x67\xf9\xb8\xfe\x00\xd7"
-  "\x7a\xcc\x8f\xf6\x4a\x9e\x79\xad\xa4\x82\xe9\x16\x03\x74\x9a\xd3"
-  "\x6d\x59\x15\x23\xe4\x33\x15\xe5\x79\x62\x3a\xf0\x31\x15\x93\x3c"
-  "\xd2\x2f\xe3\x35\x65\x7c\x8a\xd4\x52\x6d\x64\x4c\x47\x2b\xb5\x3b"
-  "\x5b\xa9\x23\xf7\x14\xb7\x3b\x06\x0c\xba\xd5\x65\x8a\xc4\x18\xd2"
-  "\x0d\x18\x6b\xc8\x99\x42\x6d\x68\x13\x07\xe9\x7d\xc6\xdb\x6d\x80"
-  "\xfd\x6d\x74\xf5\x74\xb4\xa1\x6c\x21\xb8\x27\x97\xd1\x84\x71\x20"
-  "\x34\x14\xcf\xae\x2e\x3b\x47\x82\x2b\x00\x7b\xd0\x3e\x19\xf7\xcb"
-  "\xc6\x25\xda\x48\x79\xa2\x8b\x14\x42\xd9\x5b\xa6\x4b\xb8\x5f\x61"
-  "\x97\xcf\x47\x46\xe2\x1e\xe6\xad\x19\x2c\xa6\x9a\x85\xf9\x4f\xc3"
-  "\x78\xed\x20\xa3\x3a\xe8\x27\xc8\x8f\x6c\xd7\x6b\x96\x13\x18\x03"
-  "\x96\x48\xf8\xad\xe5\x7f\xf0\x0c\xd2\x7d\xb5\x89\xcf\x53\xcb\x1c"
-  "\x71\xff\xca\xcc\xb1\xc0\x32\x87\xfe\x17\x9e\xb5\xb0\x18\xe1\xdd"
-  "\x6a\x5b\xc8\x76\xaf\xb1\x4e\x97\x6d\x21\xea\x8e\x75\xb0\x66\x9c"
-  "\x2f\x51\x73\xec\xa9\x9c\x22\xa8\x83\x96\xa3\xde\x92\xc5\x55\x5a"
-  "\x17\x9b\xba\x6b\x9e\x43\x5d\xbe\xa4\x8e\x2c\x1d\x40\x74\x53\x1c"
-  "\x6a\xc8\x63\xf9\xba\x5f\x32\xfa\xaa\xdb\x6e\x05\xde\x41\xfd\x3f"
-  "\xf0\xfc\xc0\xbc\x12\xb5\x93\xad\x23\x95\x53\x98\xae\xcb\x14\x3b"
-  "\x11\xf7\xca\x2c\xd5\x2e\xe4\x7b\x82\x81\xef\x89\xa1\x0b\x0c\x41"
-  "\xae\x45\x89\xa1\xce\x05\x89\x7d\xb6\x24\x91\x60\xd7\x02\x43\xd8"
-  "\x6b\xad\x24\x5a\x8a\xd7\x04\xb2\x70\x24\x6d\xd3\xf5\x5e\x93\x42"
-  "\x22\x50\x56\xee\xa7\xd2\xb2\xfd\x47\xfc\x2d\xa8\xdf\xd7\x16\xa6"
-  "\x74\x1d\x1b\xce\x05\x32\x32\xc6\xc3\xc2\xba\x78\x6b\xeb\xaa\x4d"
-  "\x20\x77\x8b\x67\xf1\xd2\xcf\x90\x70\xe3\xf3\x44\xdd\xaf\x85\x9a"
-  "\x1b\xe7\x10\x35\xc6\xd5\x4a\x9f\xc9\xf4\x51\x3d\xca\x13\x9d\xc4"
-  "\x92\x7a\x92\xa4\x27\x61\x1f\x55\xbe\x87\xeb\x27\xda\xc4\x42\x7e"
-  "\x6d\x23\xa9\x3c\xa4\x71\x10\x35\xfa\xc5\x36\xcf\x46\xb9\xa3\xf2"
-  "\x0b\x3b\xf3\xdb\xf2\xb9\x0e\xcf\xce\x99\x93\x1e\xc1\xb4\x1f\x32"
-  "\xce\x30\x7b\x91\x28\x7e\x5e\xaf\xb2\x0c\xef\x33\xf0\x6c\x60\xe8"
-  "\xa8\x84\xdd\xed\x8e\x1e\x5c\xe7\x51\x59\xce\xfb\x6c\x7b\x25\x97"
-  "\x93\x2a\x7d\xea\xf8\x04\x53\x14\xda\x5e\x0c\xb2\x14\x20\x5f\x41"
-  "\xad\x6c\x6f\x97\xc5\xb7\x7e\xc8\x4c\x5b\x4d\x84\x9f\x05\xfa\x7c"
-  "\xad\xb0\x36\x8a\xd9\xbe\xc0\x6f\x16\xcb\x86\xeb\x4e\xa3\x8c\x5c"
-  "\xdf\x18\x25\xea\x4e\xa3\x4c\x2b\x6e\x42\x1b\xf1\xcf\x4d\xcd\x21"
-  "\x51\xc0\x4b\x7d\x3e\xa3\x39\x74\x5c\xa4\xef\xb5\x66\x98\x49\x7f"
-  "\x2b\x09\x43\x9d\x7d\xbc\x8b\xfb\x33\xe2\x73\xf8\x44\x1e\x5d\xcb"
-  "\x9e\x0d\xaa\x35\x92\x00\xce\xbb\x7f\x7e\xfa\x9e\x02\xa2\x87\xba"
-  "\xf6\xa5\xda\xa8\x18\x66\xef\x66\x8a\x9a\x68\x69\x42\xff\xe3\x2e"
-  "\xc2\x79\xe3\x13\x45\x34\x24\x2a\x86\xe7\x3f\x31\xac\xa2\x09\xda"
-  "\xa0\x8d\xd2\x5a\x1c\xe7\xc4\xb5\xfa\x04\x8c\xfd\x28\xe0\x6f\xa3"
-  "\xf4\xfc\x8c\xed\x89\xe5\x12\xae\xf2\x31\x7a\x62\x21\xa7\xdb\x30"
-  "\x13\xa7\xdb\x89\x22\x71\x5d\x1a\x84\xbf\x81\x4f\x88\xe4\x76\x0b"
-  "\x27\xe6\x48\xbc\x8b\x55\xcc\x83\xef\xc0\xef\x89\x1c\x6b\x4f\x80"
-  "\xfc\xf3\xf9\x60\xf1\x79\x24\xa6\x41\xfb\x00\x97\x3f\x3f\x8a\xed"
-  "\xf2\x85\xad\x8c\x16\x69\x24\x00\xea\x1c\x89\xf6\xc2\x28\xdf\x59"
-  "\xec\x0f\x99\x2d\xac\x0f\xaa\xee\x62\xe7\x0f\xe1\x3b\x18\x2b\x00"
-  "\x71\x13\xca\x0c\xc4\xf2\xe4\xfa\xff\xa3\xaf\x54\x17\xfc\x1e\x3e"
-  "\x83\xb6\x32\xff\xcc\x40\x2b\x3c\x27\x48\xb0\x5f\xeb\x8d\xa8\x2b"
-  "\x69\x01\x9a\xa1\xed\x54\x55\x34\xd2\x84\xd3\xac\x2a\x4c\x94\x87"
-  "\xc4\x7e\xa8\xba\x41\x49\x0f\x7e\x2f\x68\x01\x1b\x92\xd0\x86\xa6"
-  "\x2a\x5a\xa4\x9f\xe8\x3b\xf7\x1f\x67\x18\xbd\xd8\xb3\x7f\x6c\xf1"
-  "\x78\xf7\x16\x77\x5e\xa8\x37\xda\x3c\xe2\x7e\x34\xea\xfc\xf9\x78"
-  "\xfd\xc7\x51\x8f\xf7\x8e\xc6\xff\x10\x43\x30\xee\xda\x8a\x0d\x2c"
-  "\x16\x09\xf0\xa9\xff\xa8\x91\xe9\xcd\xcb\xf1\xf2\x8d\x5b\xa5\x6f"
-  "\x58\xc9\x3f\x0a\xa4\x7a\xc2\x6f\x23\xef\x93\x2a\xbd\xdc\x27\xff"
-  "\x88\x91\xde\x43\xb9\x19\xfa\xa8\x09\xe3\xfa\xf8\xf0\x77\xaa\xb2"
-  "\x0c\x04\x0c\x76\x3e\x64\x66\xe3\x91\x54\xe5\xa3\x9d\x32\xd0\x35"
-  "\x92\x8f\xa1\xaa\x34\xbe\x16\x56\x31\x7d\x05\xee\xdb\x70\xff\xd7"
-  "\x55\x38\x1e\x76\x89\x75\xde\x26\xd6\x61\x1b\xd4\xa1\xc0\xe7\xb9"
-  "\x16\xf7\xb9\xb5\xaa\x32\x8f\xb3\x7a\x63\x39\x6d\xbf\xd0\xd1\x56"
-  "\x9a\x87\x67\x0b\x68\x0a\xcd\xcf\x85\xfe\xc9\x68\x21\xbf\x42\x5f"
-  "\x28\xe9\x46\xfa\x5d\x85\x11\xe4\x1e\x6d\x6c\x3e\x60\x43\x41\x7a"
-  "\x0b\xe9\x85\xb6\x26\x88\x2d\xa8\x4b\xa0\x21\x90\xbe\x36\xb6\x40"
-  "\x3e\x4f\xf4\x65\x04\x9e\xfb\x03\x79\x1c\x63\x5e\x16\x63\x5f\xa3"
-  "\xfd\x71\x3d\xf9\x12\xe6\x70\x6c\x31\x3c\x4b\x5e\xcd\x64\xb2\x58"
-  "\xbb\x4b\x3b\x7a\x70\xc6\x39\xd2\x93\xc5\xa5\x48\x75\x10\xfd\x6c"
-  "\x3c\x77\xf2\xc5\x62\x28\xd3\x0e\xe9\xfd\x58\xba\xc3\x81\x67\xc7"
-  "\xed\xf0\xac\x1f\x3c\x7b\x1f\xae\x02\x94\x91\x9a\x0b\xf5\x4e\x3f"
-  "\x47\x6e\x85\xba\x34\xc0\x77\xec\x50\xcf\xfa\x8c\xb9\x24\xbc\xc2"
-  "\xd8\x80\x3c\x35\x94\x67\x25\xa2\x7f\x05\x7b\x2d\xf9\x72\x28\xb4"
-  "\x2b\x15\x65\x4b\x3c\xab\xb7\x1a\xae\xe9\x2e\xd2\x2f\x7d\x19\xac"
-  "\x69\xcb\xe0\xfb\x90\x1f\xcb\x41\x9f\x0a\xbc\x2e\xd0\x36\xd4\x4b"
-  "\x40\xb9\xcb\x9a\x68\x3d\x94\xdd\x50\xde\x04\xe5\xa5\x56\xb3\x32"
-  "\xad\xd8\x46\x28\x57\xb4\x51\xd2\xf3\xfd\xe5\x2f\x07\x4b\xfb\xa4"
-  "\x56\xf2\xc5\x48\x6c\xa7\x77\xbf\xa5\x5f\x8e\x55\xfa\xfa\xf8\xdf"
-  "\x81\xe8\x37\x11\xd2\x67\x48\x7e\x39\xe0\xb7\x11\xca\x2a\x66\x7d"
-  "\xe4\xe1\x23\x25\xd7\xc3\x47\x4a\x86\x8d\x9e\xc6\xba\x18\x59\x0c"
-  "\xae\x2f\x41\x1e\x1a\x3d\x98\xfb\xfe\xfc\x5f\x36\x4f\xa1\xcd\x35"
-  "\x70\xaf\xe1\xba\xc3\x2f\x45\xcc\x1e\x56\x3c\xc1\xe5\xd4\x58\xe1"
-  "\x9b\x30\x7f\x8b\xe5\xfb\x2f\x4b\xf1\x6c\x22\xe4\x73\x71\x1f\x6a"
-  "\x5f\xee\x53\xe6\x67\xcf\x33\x3b\xdd\xc7\x74\xba\xd7\xdb\xa1\x3f"
-  "\x7d\xed\x07\xaf\xbe\x89\xe9\x11\x26\xf6\x5b\x4e\x8c\x19\x67\x49"
-  "\x00\xd0\xf9\x0c\xd6\xad\xa2\x81\x9d\x91\xd1\xd0\xac\x48\x62\x69"
-  "\x70\x72\x7e\x05\xd6\x89\xda\xc1\x90\xe7\x2c\x09\x47\xfb\x6a\xf4"
-  "\x8d\x0a\xf9\x1b\xb9\x3f\xd4\xea\xed\x53\x16\xf6\x26\xc2\x5f\xe2"
-  "\xfa\x50\xf5\xb3\x46\x58\x13\x82\xde\x69\xb7\xa2\x4f\x51\x55\xfa"
-  "\x46\x32\x10\xfb\x10\xfa\xb2\x0e\x63\x82\xc2\x3b\x4d\xff\xdd\xde"
-  "\xd0\xc3\xe2\x3c\x49\x8c\x30\xb6\x1a\x49\x75\x7e\x60\x1a\xc8\xfb"
-  "\xf5\x04\xf5\x89\xce\xc3\xce\x68\x22\x9d\xeb\x2d\x08\xe5\xe7\x23"
-  "\x0b\x60\xce\x2e\xd0\x51\x47\x5b\xd6\xff\x02\xff\xf3\x61\xa6\x74"
-  "\x6e\x6f\x15\xf7\x77\x1a\x08\xdf\x9f\xa6\x16\xcf\x30\x73\xda\x56"
-  "\x0f\xe3\xe7\xa3\x42\xef\x6c\xcb\xaa\x36\xc8\x3c\x5d\xf5\x1e\x51"
-  "\x0f\x3b\x8a\xcf\xb1\xea\x3d\x87\x81\x8b\x5e\xc9\xf7\xd5\xc3\x20"
-  "\xef\x24\xf7\xbe\x3a\x93\x51\xab\xf7\x40\x1f\x8e\xe2\xfc\xde\xe8"
-  "\x51\xf1\xae\x20\x71\x5d\xc1\xf4\x48\x2d\xbe\x0b\xef\x69\x78\xdc"
-  "\x86\x6a\x93\x3c\xd6\xaa\xe3\x10\x47\xa0\x4d\x20\x97\xff\x6f\x19"
-  "\xb6\x0b\x69\x02\xf9\x02\xe1\xbe\xf2\xf0\x36\x1f\x7e\x7d\xb5\x91"
-  "\x66\x67\x16\xdb\x23\xae\x86\xf1\x74\x0e\xfa\xe0\x46\xf4\x63\x62"
-  "\x81\xef\x94\x17\xb6\x93\x72\x5d\x33\xa9\x98\x81\x67\xb9\x80\x67"
-  "\x9e\xfd\x2d\xa9\xd3\x7b\xc7\x30\xc0\x41\x18\x07\x91\x13\xb1\x2c"
-  "\x9c\x27\x68\x1f\x65\x01\x49\xa3\xc2\x86\xb1\x48\x09\x2b\xa3\x5c"
-  "\x68\x20\xe5\xa9\xc8\xbb\xef\x77\x54\x14\x9e\x24\x15\xba\x7f\xb0"
-  "\xef\x20\x9f\x61\x4e\x6a\xee\xaa\xec\x04\x28\xdb\x28\x96\xdd\x04"
-  "\x65\x87\xf9\x2e\x7b\xbb\xde\xcf\xb2\xfd\xa8\xf7\x76\xad\x3f\x65"
-  "\x67\xe4\x53\x17\x60\x4b\x5f\xc0\x8f\x18\xf4\xab\x84\x67\xc3\x5c"
-  "\xad\xe8\x83\x60\x10\xe5\x36\xa7\x27\x5f\x46\x1e\x9b\xed\x25\xae"
-  "\x8d\x1d\xc1\xce\x8d\x9d\x27\xcc\x67\x8d\xc5\x79\x86\xa0\x0e\xa8"
-  "\x2d\xeb\x64\xb2\xcc\x7f\xbb\xf7\x50\x60\xcd\x39\x99\xcf\xed\x0a"
-  "\x63\x47\xf0\x71\x75\xf2\x09\x2c\xc7\x3b\x9f\x3d\x72\x22\xb7\x4f"
-  "\x3d\xf9\xb9\x24\xaf\x37\x87\x8c\x9c\x28\x96\xa5\xef\xbc\xb7\x2e"
-  "\x05\x01\x9f\x99\x9a\x2c\xc5\x13\xe7\x87\x0a\x7b\x93\x27\x67\x3e"
-  "\x37\x73\x56\xca\xcc\x19\xfa\x49\x0b\x93\xe6\x0d\x7d\xf1\xf9\xe7"
-  "\xf5\xe3\x66\x2e\x58\x30\xed\x2f\x33\x7b\x93\x49\x49\xd3\xe6\x2d"
-  "\x98\x85\xce\xe0\xf5\xfa\x91\xbf\x8d\x4f\x7c\x31\x79\xe8\x83\x23"
-  "\x23\x3b\x9d\x33\xc4\x33\x86\x35\xc8\xd7\x01\xde\x86\x03\xf6\x86"
-  "\xa0\xff\x09\xcd\x62\x6a\x5e\x0a\x32\x05\x8c\xbf\x46\xdc\x43\x82"
-  "\x79\x7b\x1a\xf9\x4d\xe0\x3f\xaa\xd0\xf7\xd8\xe6\x0d\xb4\xb2\x9e"
-  "\x9c\x7b\x18\x78\x95\x6a\xf4\x33\x06\xb2\x56\x0d\xc8\x79\x36\x1e"
-  "\xf3\xf6\xdc\x2d\x90\xa7\xf4\x55\x48\xb3\x85\x8c\x1e\xb5\xe6\x14"
-  "\x09\x84\xf5\x07\x78\xdd\x7f\xc2\xdc\xef\x45\x57\x85\xd3\x52\xfa"
-  "\xad\x8e\x88\xfe\xfe\xd4\x16\xab\x03\xf7\x9a\x83\x26\x38\x33\x28"
-  "\xe2\x29\x9f\x5b\xff\x3c\xc3\xe9\x12\x95\xc0\xed\x76\x9b\x5c\xc8"
-  "\x17\xaf\x60\x31\x04\xfe\x09\x73\xb2\x32\x51\xc6\xe9\x33\x11\x22"
-  "\x3f\x52\x0d\x74\x5f\x54\x0b\xf7\xfc\x8c\x7d\x8d\x5e\x69\x5f\x00"
-  "\x42\x14\x39\x9b\xc8\xff\xf0\x9d\xb3\xc9\xfc\x0f\x7f\x7b\xfe\xc1"
-  "\x82\xc2\xfe\x3a\xa7\xff\xd4\x3f\xe9\xfb\x3f\xba\x8c\xba\x6e\xfe"
-  "\xae\xe0\xfb\xac\xdd\xd7\xb1\xfd\x3f\xa9\x8c\xa6\xae\xfe\x70\xbc"
-  "\xc1\xd8\xaa\x79\xf5\x14\x09\x82\xf1\x99\x07\x32\x76\x60\xc6\xd7"
-  "\x44\x97\xe6\xa4\x75\x19\xcf\x92\x81\xe9\x67\x09\xc6\x84\x6d\x48"
-  "\x4e\xa5\x75\xe9\xad\x28\x8b\x9d\xd9\x0f\xe3\xb7\x24\xb7\x96\x04"
-  "\xaf\xae\x25\xda\x8a\x64\xee\x7b\x16\x75\x9f\x78\xa6\xc1\x02\xf7"
-  "\x65\x29\x0e\xf2\x99\xed\x07\xdc\xe3\x30\x57\x24\x00\xee\xd4\x10"
-  "\x82\xe3\x37\x38\x81\x84\x15\x84\xd3\x7d\x34\x6b\x15\xc8\xee\xab"
-  "\xf0\xbb\x55\xef\x0a\x31\x3d\xde\x5d\x72\xb4\x07\xc6\xcf\xad\x25"
-  "\xa7\xb6\x8b\x63\x73\x28\x3f\xb3\x73\x66\xa8\xa8\xcf\xaf\x02\xde"
-  "\x17\xd6\xa6\x33\x6f\xf2\xf5\xfc\xcc\x62\x51\x87\x81\xbf\x99\x5f"
-  "\x58\x68\x47\x09\xc6\xd0\xc6\x32\x77\x0b\x25\x2c\x86\xf6\xbb\x4b"
-  "\x62\x7a\xa4\x4d\x23\xea\x0a\x6b\x23\xdb\x0d\xc3\x7d\x17\x98\x77"
-  "\xbb\x60\x9e\x15\x6f\x09\xa7\x26\xa8\xdf\xaa\xc2\x70\x9a\x03\x75"
-  "\xda\xd9\x96\xf5\x4d\x98\x95\x7c\x15\x24\xea\x58\xcd\x30\x2f\x76"
-  "\xad\x86\x3c\x13\x16\x92\x41\xab\x21\x5f\x2e\xe4\x43\xde\x8d\xd7"
-  "\xef\xdb\xbe\x40\x83\x3d\xf0\xcd\x4a\xfd\x54\xbc\xb7\x32\x1d\x18"
-  "\x7e\x1b\xda\xa1\xaf\x25\x56\xa6\x17\xc1\x6f\x48\xdf\x85\xf2\x01"
-  "\xff\xbe\x32\x8b\xfa\x6e\x13\x2f\xe7\x1b\x51\x1e\x8a\x45\xff\x7f"
-  "\x62\x8c\xf3\x58\xf3\xea\x25\xb0\xa6\x83\x4c\x0d\xdf\xc8\x83\x6f"
-  "\x98\x35\xcb\x09\xd5\xe0\xb9\xba\x1a\x27\xf0\x7b\x82\x68\xff\x65"
-  "\x7d\x49\x7c\x97\xf1\x20\x8c\xef\x00\x59\x9f\xcb\xa4\xc0\x7b\x24"
-  "\x02\x4e\x00\xbf\xc1\x6c\x91\x81\xd7\xc0\x74\xf8\x46\x1e\xfa\xfd"
-  "\x03\x59\x61\x0f\xac\xdb\x18\xfb\x20\x68\x6a\xcb\x18\xc2\x62\x01"
-  "\x02\xaf\xb0\x20\x95\x3a\x78\x6c\x00\xab\x5e\xe2\x15\x70\x7c\x20"
-  "\x7f\xb0\x7a\x2a\x09\xec\x80\x3e\x86\x31\x72\x14\x78\x8f\x90\x46"
-  "\x62\x9d\x22\xf6\xcd\x51\xc6\x13\x88\x31\x91\x38\x86\x5b\x67\xc1"
-  "\xda\x1e\x0c\xdf\x38\x6a\x25\xe7\x98\xee\x8c\x63\x90\x35\x55\x5a"
-  "\xe7\x79\x5c\x3f\xeb\x14\x0a\x58\x07\x74\xdb\x13\x91\xa0\x02\x3e"
-  "\xf4\x1b\x33\xf4\xc5\x1e\xcc\x8b\xe7\xc6\x21\xff\x4e\x58\xf3\x23"
-  "\xc4\x3e\xa9\x59\x9d\x82\x3c\x80\x35\x12\xeb\x01\xef\x94\x01\xad"
-  "\xe1\x5b\xb5\x56\x11\xc7\xaa\x38\xff\x52\x7b\x4c\xa2\x3d\xf4\xf5"
-  "\x4a\x99\xfe\x56\xbb\x27\xfd\x81\x16\x2b\x79\x1f\xd4\x2e\xf4\xe8"
-  "\x3b\xe0\xd7\x6b\xc7\xa2\xee\x0d\xbe\xb7\x8f\xeb\x0d\x4e\x0f\x45"
-  "\x1f\x3f\x30\x66\xf6\x01\x2d\xf6\x41\xbe\x12\xc4\xe6\x15\xa7\x88"
-  "\x18\xdf\xbe\xf6\x3e\xce\x9f\x9e\xae\xe2\x31\xa0\x4f\x8b\x31\xa0"
-  "\xad\x51\x3c\xfe\xf3\xe9\xed\x3c\xfe\xf3\xe9\x2d\x9e\x31\xed\xe5"
-  "\x78\xf6\xa7\x57\x49\xf6\xfe\x38\x06\xb0\xef\xa1\x8d\x51\x5c\x36"
-  "\x3b\xbd\x0a\xf5\x2b\xec\xbd\x8e\x44\xac\x63\x0d\xce\x4f\xe9\x39"
-  "\xc6\xb8\x87\x74\xe2\x41\x9b\x28\xb1\x4f\x4a\x78\xdc\x8b\xda\xa1"
-  "\xbc\x6e\xb5\x41\x70\x1f\x04\x75\x60\xf2\x1d\xc6\xbb\x5f\x83\xef"
-  "\xa4\xcb\xef\xe0\xfc\x81\xb1\xac\x81\x77\x86\xc0\x95\x4a\x79\xb7"
-  "\xb6\x63\x9e\xd3\xbb\x5e\x6b\x47\xfd\xca\xe9\xd2\xe6\x0e\x83\x1a"
-  "\xbe\xeb\x80\xef\xaa\x71\x6c\xe0\xb8\x90\xca\x58\xc3\x69\xb4\x0b"
-  "\xfa\x8f\x8d\xaf\xc3\xce\x12\xa0\x7b\x2d\xc8\xff\xe5\x13\x39\x6f"
-  "\x77\x7a\x97\x58\x3f\x33\xf7\x6f\x7b\xb2\x06\xe3\x0d\x72\x7f\x33"
-  "\xb5\x79\xee\xbd\x42\x37\x8f\x79\x7a\x17\x8e\x3d\x28\xab\x4c\x1c"
-  "\x13\x1a\xc8\xb7\xcf\x3d\x86\xd8\x39\xe1\xda\x11\xc8\x67\x8a\xf5"
-  "\xc7\xb1\x77\x1f\xa7\x9d\xb5\x06\xc7\x00\xf0\xf0\xa3\x78\x3f\x5b"
-  "\xa3\x90\x4f\xe5\xe3\xf0\x5b\x22\x95\xc1\xcf\x1a\x9f\x5e\x25\x40"
-  "\x19\xd2\x58\xf1\xc4\x06\xc8\x1b\x01\x3c\xa9\x7b\xdc\x48\x58\xc0"
-  "\xcb\xac\x13\xe3\x5e\x6c\xaf\x86\xbe\x41\x9f\x8c\x66\xe4\xdb\xf9"
-  "\xb8\xac\x8b\x3e\x6c\x77\xb2\x18\xd8\x50\x2f\xc0\x84\x6f\xd7\x37"
-  "\x87\x8e\x1b\x25\x8f\xed\x6f\x57\x4a\x63\xdb\xa3\x5f\xd9\xd8\x5e"
-  "\xc9\xf0\xe8\x5b\x90\x7f\x7f\x33\x56\x1a\xfb\x38\xcf\x31\x16\xfd"
-  "\x9a\x14\x1e\xa7\x1e\x75\x20\x6c\xde\x3b\x9a\x98\x7c\x81\xfd\x59"
-  "\x91\x5a\xc7\xfc\x5a\x62\x9c\xfa\x0a\xfb\x19\x94\x1b\x1b\x71\xfe"
-  "\x4b\x73\x1c\xfb\x06\xbe\x65\x86\xf2\x2a\x57\x02\x06\xe2\x1c\xb4"
-  "\x43\x9d\x30\xfe\x23\xfa\xed\x28\x9d\x12\xc3\x62\xd8\x1f\x4e\xc0"
-  "\x7e\xab\x1b\x2c\xd9\x17\xaf\xe1\x18\x10\x2c\x8e\x17\x56\xc7\x4e"
-  "\x74\xd5\x70\xba\xd6\xc5\x29\xe7\xf7\x69\x07\xce\x6f\x4f\xba\x22"
-  "\x4d\x91\xb6\x90\x17\xda\xff\xd5\x0c\x89\xae\x1e\x34\x6d\x11\xc7"
-  "\xa3\x88\xad\x75\x5e\xb1\x15\xfd\x83\x42\xbd\x4a\x56\x60\x5b\x60"
-  "\x4d\xc1\xef\x33\x3f\xdb\xa2\xdc\x53\x6a\xc3\x31\x55\xd7\x60\x25"
-  "\xf1\x44\xc2\x31\x18\x2b\xcc\xe7\x12\xf6\x95\x84\x1d\xa8\x43\xe0"
-  "\x75\x3f\x13\x26\xf5\x07\xd6\xdb\x13\x13\x60\x8d\x61\x7b\x31\x72"
-  "\x9b\xcf\x3c\x0a\xef\x85\x22\xb6\xc9\xfc\xd5\x99\x49\xca\xb6\x9f"
-  "\x19\x81\x6d\xc7\x31\x61\x4c\x41\x3d\x02\x5f\xcb\xac\xe4\xd4\x51"
-  "\x25\x5e\x9d\xda\xcf\xf7\x08\x39\x3f\x86\x78\x6f\x9c\xca\xf3\xe3"
-  "\xfa\x06\xf9\xcd\x6c\xad\xe3\xeb\x21\xfa\x22\xc2\xb4\x3d\x22\x0d"
-  "\x6a\x20\x7f\x29\x9e\x59\x44\x9f\x14\x7d\x6a\xb8\x1c\x08\x18\xbd"
-  "\x0f\xd6\x0e\x33\xe4\x4b\xae\x00\x19\xc0\xd9\x93\x90\x02\x91\xdf"
-  "\x44\x9c\xa0\x8b\xe2\xfa\x2c\x6a\x20\x37\x18\x1f\xa4\xdf\xd6\x93"
-  "\xfa\xf9\x30\x8f\x1c\xb8\x97\x0f\x65\xeb\xeb\xc9\xd9\x27\xe0\xbb"
-  "\x61\xe2\x55\x07\xd7\xe1\x70\x1d\x00\xd7\xdb\xe0\x7a\x33\x5c\xf1"
-  "\xec\xa9\x20\xe6\x8f\xac\x27\x0d\x3f\x40\xfa\x6f\xc5\x2b\xd4\xb1"
-  "\x3e\x11\xae\x13\x5f\x45\xbe\x72\x2a\x4b\x3f\x82\xf7\x70\x7d\x5f"
-  "\x6c\x77\x19\x9f\xdb\xf5\xeb\xa1\x9c\x54\xcc\x87\xeb\x1a\xa4\x19"
-  "\x21\xcf\x62\x2c\x1b\xcf\x12\xc3\xef\xa1\x1e\xfc\x29\x94\xf3\xdd"
-  "\x64\xb8\x46\xc1\xf5\x16\xb8\x26\xc3\xfb\xa7\xb1\x5c\xf4\x75\x2b"
-  "\xe3\x85\x35\x6a\x46\x2a\xef\x4f\xe8\xeb\x62\x9c\xef\x12\x1e\xe0"
-  "\x78\x52\xe4\x9b\xc2\xf3\x71\xd9\xf5\x3b\xad\xd4\x77\x4e\x3e\x6e"
-  "\x4b\x9d\xd0\x77\x50\xfe\xc3\xf8\x3e\x5c\x63\xc5\x6b\x8c\x78\x7d"
-  "\x54\xbc\x3e\x26\x5e\x47\x8a\xd7\x51\x56\x52\x6f\x15\x79\x13\xa0"
-  "\x59\xbd\x15\x69\x02\x73\x37\x99\x7f\xb7\x21\x0c\x65\x6b\xc0\xff"
-  "\xfb\x9a\x31\x96\x42\xd6\x77\x39\x92\xae\x0e\x75\xbc\x1d\x59\x27"
-  "\xdb\x36\x33\xbb\x89\xef\x8a\x3c\xb0\x50\x17\xac\x8a\x21\xc0\x3b"
-  "\xf5\x2c\x50\x03\xdf\xc0\xca\xf9\xce\xa1\x16\xf7\x1f\xd1\xe7\x32"
-  "\xc6\x88\x88\x77\x06\xf1\xb3\x70\x21\xfb\x71\xaf\xa7\x86\xe9\x31"
-  "\xd1\xb7\x52\xc8\xe8\x81\xf0\x67\x00\x99\x22\x42\xc2\x7b\x94\x97"
-  "\x44\x1f\x59\xe1\x6d\x59\x0d\xc1\xb2\x8c\xff\xdd\x3e\xbe\x9f\xd3"
-  "\x1f\xf0\xa9\x61\xb0\x47\x7a\x2a\xd6\x19\x68\x5d\x0d\xed\x89\xaa"
-  "\x25\x0d\x63\xe1\x7a\x6f\x1d\x6f\x73\xa4\xd4\x66\xb1\xaf\x8c\x12"
-  "\xcd\xeb\x48\x7d\x03\xe0\x61\x12\x8e\xef\x5a\x37\x2e\xd7\xb3\x7d"
-  "\x5d\x71\xfc\x40\x3f\xd7\x6f\xc4\xfe\xf6\xc0\x93\x08\x19\xa7\x1b"
-  "\x76\x2a\xfb\xc5\xba\xd3\xc9\xf9\x85\x6a\x98\x97\x38\x06\x8c\x9d"
-  "\xe6\xe5\x08\x9c\x97\xe2\xbb\x75\x4a\x8c\x3f\x33\x02\x31\x5e\xac"
-  "\x23\x8c\xdb\x7a\x3c\xd7\x0e\xeb\x40\x43\xa9\xb8\x26\x55\xc3\x1a"
-  "\x79\x1f\xa4\x8b\x7a\x51\x9e\x2e\x7e\x0b\xc6\x5f\x3d\xfa\x03\xbc"
-  "\x59\x4a\x17\xc7\x37\x96\x63\xc0\xbe\x96\xd2\xc5\xf2\x61\x9c\xd6"
-  "\xeb\x71\xfe\x48\xe9\x7c\x4c\x7e\x9b\x8a\x78\x83\xef\x62\x7b\x90"
-  "\x67\x36\x4f\x2d\x85\x7a\x9f\xdd\x06\xfc\x45\x11\xce\xe7\x15\x4b"
-  "\x48\xf0\xa2\x7c\xd2\x97\xcf\xcd\xb3\x47\xa4\x77\xb9\xae\xf3\x6c"
-  "\x89\x84\x51\x6b\x18\x9e\xd5\x45\x28\xb1\xb2\xa9\x07\xcd\xd2\x38"
-  "\x9d\xda\xd1\x61\xe5\xce\x28\x86\xb9\x30\xef\x0b\xe0\x3d\x9b\x95"
-  "\xac\xca\x17\xd7\x92\x32\xae\x47\x6e\x1c\x52\x5e\xc4\xb1\x8b\x97"
-  "\xdd\xe8\xc6\x3f\x0f\x3e\x84\x61\x3d\x7e\x0b\xcb\x82\x75\x45\x6b"
-  "\xcf\x88\xeb\xc3\xf1\xbb\x71\xa4\x95\xf4\xae\x91\xb0\x15\xd7\x27"
-  "\x8d\x8a\x18\x73\xa7\xf2\xf5\x49\x40\xfd\x97\xd1\xce\xfc\x08\x55"
-  "\x18\x9b\x08\xae\x9b\xe8\xe7\x35\x7e\x71\x6f\xf4\xf5\x12\x57\x4f"
-  "\xbe\xc7\x78\x7b\xdb\x44\x3a\xc2\xfc\xf9\xbe\x5c\xec\x87\x1a\xf8"
-  "\xfe\x36\xc4\xf2\x15\x29\xdc\x4f\x39\xea\x7e\x98\x1f\x7c\xe4\x51"
-  "\x75\xd4\x51\x5a\x80\x73\xa4\xb1\xd4\x43\x9f\x25\xc6\xb7\x39\xbb"
-  "\x97\xc5\x54\x30\x8d\x0e\xe3\xba\xc3\xef\xa7\xf1\xf4\xef\xc5\xbd"
-  "\xd6\xd1\xa2\xdd\xf3\xf7\x91\x01\xba\xb0\x24\x1e\x77\xe6\x9f\xa1"
-  "\x9c\xff\xf8\x3e\xac\x93\x5f\x28\x35\xa4\x19\x64\x9f\x99\x67\xc5"
-  "\x7d\xee\xef\x3d\xf6\x3f\xbf\xc7\x18\xdc\x81\x50\xd6\x32\x48\x77"
-  "\xef\x7f\xf2\xb5\xc6\x6a\x10\xf5\x65\xba\x3e\xcb\x63\x08\x60\x73"
-  "\xcf\xcd\x59\xd2\xfc\xfd\x7e\x0f\xaf\x0f\x9f\xbf\xd8\x66\x1c\x0f"
-  "\x38\x87\x9d\xcc\x17\xcf\xfe\x44\x9c\xcb\xf0\x7b\xa0\x53\x9a\xbb"
-  "\x9c\xbf\x8b\x60\x73\x97\xcd\xdb\xef\x4b\x3d\xea\x91\x26\x8e\xd5"
-  "\x9a\xe6\xe7\x74\xc0\x53\x7e\x6f\xb5\x92\x93\x03\xf9\xb3\x46\x93"
-  "\x58\x8f\x30\x78\x5e\x60\x4e\xff\x04\xfb\x7e\x39\x9f\x13\x8d\x99"
-  "\x38\xee\x2c\x30\x56\x60\xbd\xc8\xe7\x31\xe6\x9b\x06\x4a\x63\x05"
-  "\xe6\xd4\x0c\x18\x53\xef\xe4\x85\xd3\x7c\xe8\x13\xb4\xc7\x9c\x03"
-  "\xf7\x38\x5f\x67\xf0\xab\x4a\x8b\x57\x71\x8c\xe6\xc3\xbb\xb0\xfe"
-  "\xf7\x96\xfa\xa4\xc6\x1e\xb2\x9d\x8f\x89\x74\xb4\x8d\x89\x64\xfb"
-  "\x91\x38\x26\x70\x3c\xb0\x7d\x49\x18\x1b\x9a\xe5\x63\x08\x8e\x0b"
-  "\x76\x9e\x1f\xee\xb1\x4e\x38\x2e\xa0\xac\x6d\x92\x8f\x4a\x2b\x69"
-  "\x1a\xc5\x69\xdf\x54\xe2\x69\x23\x08\x65\xeb\x4b\xf5\x20\xef\x98"
-  "\x86\x99\x92\x6f\x23\xfd\x31\x46\x38\xfa\xa2\xc3\x98\xeb\xf8\x0e"
-  "\xee\xe9\x70\x9c\xeb\xff\x27\x78\xd7\x2e\xd3\xcb\xca\xfc\x0a\x1c"
-  "\x9e\xc2\x74\x90\x37\xb6\x65\x9d\xd3\x2a\xb1\xe2\x9f\x75\x8c\x1f"
-  "\x84\x75\xf5\x8e\x30\xa2\x87\xf1\x07\x6b\xc4\xb9\x28\x89\x8f\xbd"
-  "\x27\x0c\xf7\x86\xff\x89\xf2\x05\xca\xb0\x95\xf0\x3b\x0d\xd7\x57"
-  "\x1f\xba\xe2\x28\xd4\xf1\xe0\x5c\x47\x9d\x11\xea\xaf\xd0\xa7\x7c"
-  "\x3d\xb1\x1d\x29\x47\x5f\x1b\x2f\x5e\xee\x97\x34\x3d\x95\xb6\xa0"
-  "\xef\x17\x7d\x12\xb9\xb1\x96\xd8\x30\x16\x70\x75\xc6\x0f\xa8\x9b"
-  "\x39\xd7\xc9\xff\xe1\xf9\x60\xf1\x4f\x0f\x7f\x2b\xe5\xbf\x0b\x61"
-  "\xe2\x6f\x53\xd7\x7f\x17\x22\x78\xde\x0b\x80\x79\x17\x46\x8a\xb4"
-  "\xfa\x6b\x5b\xd6\x79\xbd\x44\x2b\xc4\x02\xc4\x46\xb4\x09\x40\x5d"
-  "\x93\xca\x49\xd0\xb7\x07\xf4\x17\xd4\x7b\xc5\xaf\x9f\x34\x2f\x41"
-  "\x59\xf4\x3c\xb3\x69\x42\x3f\x9a\xfe\xd9\x9f\x9c\x67\x7b\x80\xdc"
-  "\x37\xdf\xf9\x30\xf8\xf6\x1b\x6b\xce\x93\x40\x63\x12\xb9\x05\xf5"
-  "\xde\x1a\x17\x35\xa3\xec\x2a\xc6\x35\xaf\x6c\x24\x17\xfa\x27\x2f"
-  "\x23\x6a\x78\x3e\x08\x7e\x4b\xf1\x35\x6b\xe0\x1d\x6d\x80\x83\x84"
-  "\x21\xef\x13\xbb\x8c\x0c\x82\xfa\x5b\xa5\xbe\x42\xfe\x00\xf5\x6f"
-  "\xa2\x0e\x01\xeb\x7a\x1b\xbe\x87\xbe\x96\xad\x8c\x6e\x22\xe6\x9c"
-  "\x47\x7d\xf3\xf9\xb2\x00\x3b\xd1\xf2\xf5\xe3\x02\xac\x7f\xff\x14"
-  "\xf9\xc1\xf3\x0d\x30\x07\xaa\x3c\xea\xf9\x95\xfc\x3b\x7c\x00\xbe"
-  "\xaf\xb1\x23\xef\xe5\x8b\x3e\x17\xe6\x4b\xf4\x41\xdb\x54\x90\xe7"
-  "\x8d\xac\xbf\x9d\xb4\x09\xea\x56\x66\x5c\x42\x82\x1a\x89\x6d\x3e"
-  "\xc6\x2c\x80\x79\x73\x94\xeb\xe5\x6d\x33\x25\xf9\x9a\xd7\xdb\x36"
-  "\x4c\xb3\x3c\x80\xa0\x3e\x3d\xde\xa5\x67\x7b\x7e\xf4\x82\x8e\xe9"
-  "\xd0\x2d\xce\x11\xc4\x9c\xfe\x00\xe6\xb9\x4d\x5c\x83\x6a\x9a\x33"
-  "\x74\xe4\xb0\x6e\x04\xcc\xe7\x0b\x4d\x56\xf5\xa9\x18\xff\xed\xa6"
-  "\x2e\x34\x71\xdc\xe0\xe7\x08\xf1\x1e\xcf\xfc\x01\x3d\xcb\xf8\x3e"
-  "\xf7\x85\xfd\xb8\x26\xa0\x8c\x0f\xeb\x41\x29\xae\xbb\x6d\x59\x36"
-  "\x37\xff\x0f\x78\x0f\xf8\x74\x41\xdc\x77\xc1\xbd\xc5\x0b\x25\xe8"
-  "\x6b\x41\xb4\x7d\xc5\xfc\xc1\x5c\xf7\x6f\x5b\xe5\xe6\x9b\x21\x1f"
-  "\xbe\xc7\x6d\x9b\x2e\x98\xe2\x5d\xa8\x13\xb8\x60\xc2\xb6\xf2\xb1"
-  "\x19\x0e\x7d\x6b\xdb\x27\xcf\xe3\xf3\x8c\x97\x38\xdc\xe4\x39\x4f"
-  "\x6d\x35\xb2\xbc\x79\x2e\x73\x68\x1e\xf1\x6a\xb3\x61\xec\x47\xb4"
-  "\xdf\x07\x91\x3f\xae\x59\x43\x8b\x4c\x6a\xe1\x91\x15\xb9\x24\x58"
-  "\xb5\x0a\xc8\x88\xf3\x2e\x25\xa1\x7f\x3d\xf9\xe1\x59\x4d\xf0\xaf"
-  "\x26\xc6\x26\xf7\xa2\xe9\x3a\xa2\x5e\x7d\xb1\x57\xd0\x6d\x8e\x5f"
-  "\x15\xd1\x80\x5f\x3f\x39\x2e\x19\xf7\xf6\x4c\xe4\xbb\x39\x24\x20"
-  "\xd6\x05\xdf\x0e\x26\x46\x2b\x69\x4e\xc4\xb3\x99\x87\x83\x91\xa7"
-  "\x68\x46\xdb\x99\x47\xd2\x0a\x48\x50\x5a\x1d\x6d\x58\xf5\x7c\x8f"
-  "\x20\x58\x47\xb5\x80\xff\x39\x7d\x82\x7f\x55\xd4\x01\x65\x1c\x4a"
-  "\x60\xef\x15\xfb\x5f\x37\x63\x38\xd4\xed\x92\x7f\x75\xb3\xef\x94"
-  "\xeb\x66\xdf\x79\x95\xeb\xa6\x95\xeb\x96\x08\x75\xbb\xb8\xde\xbf"
-  "\xba\xb5\x34\xc8\x75\x6b\x69\xb8\xc2\xba\xed\xf2\xbf\x6e\xa9\xbf"
-  "\xaa\x27\xcd\xc3\xfc\xab\x5b\x9b\x41\xae\x5b\x9b\xe1\xa7\xd4\x2d"
-  "\xbd\x80\x9e\xa9\x18\xc8\xe3\x91\x22\xee\xd7\x13\xfb\x7d\xcb\x06"
-  "\x62\xbd\x48\x28\xd4\xeb\x6c\x46\x01\xfd\x96\xf3\x2c\xcd\xef\xf0"
-  "\xb5\xae\x19\xd6\xbf\x73\x71\x7c\x1c\xdb\x99\xcc\x2b\x04\xdc\xb4"
-  "\x93\x66\x51\xe7\xdd\x76\xb4\x77\x72\xa2\x3f\x02\xf4\xdd\x3b\xf1"
-  "\xdd\x56\x87\x9a\x86\x8e\x4e\xd8\x7a\x31\x90\xbc\xdb\x6a\x03\xbe"
-  "\xa5\xd9\x2a\xf9\x17\x94\xde\xd5\xe4\x77\x85\x4f\xf6\xfe\xb1\x89"
-  "\x44\x83\xf8\x84\x57\x8c\x3d\xb3\x26\xbd\x57\x50\xec\x0f\xc8\x0f"
-  "\xd8\x23\xa4\xf3\x59\x52\x59\x13\x1a\x7a\x51\x4d\x1a\x09\xc0\x33"
-  "\x62\xcc\x6f\x99\xce\x46\x06\xa7\x91\x1e\x13\x52\xa1\x7c\x07\x49"
-  "\xd0\xa4\x42\xd9\x40\x0f\xce\x93\xdb\xe7\x07\xcc\x21\xc1\x79\x50"
-  "\x36\x5e\x63\x75\x19\x74\xc5\x46\x12\x88\x67\xc9\xf0\x4c\x18\x3f"
-  "\x0f\xd6\x33\x08\xbe\x93\x27\x7d\xa7\x1b\xfa\xf5\xe3\xf4\x6b\x59"
-  "\x28\xd3\xaf\xe5\x2e\x99\x7e\xf6\x73\x9c\x7e\xf6\x3a\x99\x7e\x2d"
-  "\x55\xfe\xd1\xaf\x45\x2f\xd3\x8f\xbf\xdb\x35\xfd\x5a\x9e\xf2\x4d"
-  "\xbf\x96\x39\x32\xfd\x78\x59\x3e\xe8\xd7\xd3\x3b\xfd\x5a\xde\xbb"
-  "\x32\xfa\xb5\x54\x5d\x21\xfd\xfa\x72\xfa\xb5\xbe\x2f\xd3\xaf\x75"
-  "\x96\x4c\xbf\xd6\xa1\x9c\x7e\xad\x83\x65\xfa\xb5\x85\xf9\x47\xbf"
-  "\xd6\x04\x99\x7e\xfc\xdd\xae\xe9\xd7\xba\xde\x37\xfd\x5a\x77\xc9"
-  "\xf4\xe3\x65\xf9\x47\xbf\xd6\x1f\x80\x6e\x5a\x91\x7e\x5a\xdf\xf4"
-  "\x6b\x0b\xbb\x42\xfa\x69\x38\xfd\xda\x5a\x64\xfa\xb5\xbd\x29\xd3"
-  "\xaf\x6d\x2e\xa7\x5f\xdb\x0c\x99\x7e\x8e\x49\xfe\xd1\xaf\xad\x48"
-  "\xa6\x1f\x7f\xb7\x6b\xfa\xb5\x7d\xe1\x9b\x7e\x6d\x4d\x32\xfd\x78"
-  "\x59\x3e\xe8\xd7\xcb\x3b\xfd\x1c\xc3\xae\x8c\x7e\x8e\x49\x5d\xd1"
-  "\xcf\x3f\xde\xc3\x91\x48\x7c\xd8\xe0\xf9\x59\x8e\x6f\xbf\x6b\x18"
-  "\xcb\xe9\x12\x51\x0b\x59\x8e\xe2\x42\xa1\x67\x10\xee\xd7\xc2\x6f"
-  "\xd4\x5d\x3d\x54\x4b\x1c\xae\x42\xa1\x47\x10\xcd\xfa\x38\x47\xc8"
-  "\xda\x3f\x8a\x2e\xef\x19\x28\x2c\xef\x15\x88\xe7\x57\xbd\x95\xc5"
-  "\x6d\xfd\x2e\x3d\x1b\x30\x80\xdc\x8a\xe7\x3a\x56\x00\xff\x86\xbf"
-  "\xdb\xb2\x2e\x25\x02\x2f\x72\x99\x9f\xfd\x19\xb3\x16\x4c\x9b\x3e"
-  "\x67\xa6\x3e\x69\xe6\x8c\x85\xf3\x66\x4c\x9b\x97\xac\x9f\xf6\xdc"
-  "\x0b\x0b\x94\xbe\x8e\x59\xec\xcd\x95\xd8\x7f\x97\x76\xb9\x7d\x0d"
-  "\x64\xd1\x54\xf4\x2f\x65\xbc\x9d\xdc\xd0\x48\x2e\x35\x31\x1f\xd1"
-  "\xa1\xa3\xcb\x68\x47\xdc\xa6\x98\x3b\xe8\x41\xe6\x37\xab\x23\x71"
-  "\x13\xc8\x59\x45\xe8\x5f\x40\xdc\x4f\x2a\xaa\x27\x1d\x2d\x34\x64"
-  "\x1c\xc6\x7c\xb5\x73\x9b\xf3\x76\xe6\x8b\x01\xfd\x0e\x50\x6d\xac"
-  "\x43\x30\x8d\x6b\xa0\x6b\xc7\x59\x91\x06\x15\xe8\xb3\x28\x25\x60"
-  "\x50\x2d\x71\x6d\xa3\x21\xb1\x0e\x28\xcb\x29\x96\xc3\x7c\x1d\xc4"
-  "\x2c\xa1\xdf\x60\x79\x22\xef\x8d\xf1\x0f\xcd\x9c\x1f\x6c\x5f\xae"
-  "\x59\xae\x0f\xc0\xbc\xe8\x3b\x0c\x7d\x6a\x49\xb1\x45\xb0\xde\x98"
-  "\x17\xf8\xf3\x87\xe0\xfd\x87\xb6\xb2\xd8\x21\x62\x19\xbc\x4e\x37"
-  "\x42\x9d\x4a\x58\x5b\x4c\xb1\xdb\x9a\x97\xc6\x6d\xc2\x72\x38\x5d"
-  "\x5d\x2f\xc3\xb7\xb7\x61\x19\xe8\xd3\x07\xdf\x15\xdf\xb9\x05\xde"
-  "\xe1\xbe\x4b\x56\xdc\xbc\x89\x97\xe1\x9a\x2f\xd5\x0b\x78\xea\xde"
-  "\x70\x3f\xd9\xe3\x1b\x7d\xe0\xfe\x61\x8f\xe7\xc1\x70\x3f\x04\xf8"
-  "\xd0\x10\xf1\x79\x5f\xb8\xc7\xd8\xb0\xc1\xac\x5d\xb9\x99\xa2\x3d"
-  "\xa7\xb3\x09\xd2\xb4\x62\x9e\x90\x46\xe2\xc4\x58\xc4\xa1\x62\x19"
-  "\xa1\x70\xff\x3e\xca\x90\xe2\xf3\x30\xb8\xdf\x88\xfa\x7d\xf1\x79"
-  "\x7f\xb8\x5f\x06\xf7\xff\x21\x3e\x07\x3e\xbf\x83\xfb\xda\xd2\xc6"
-  "\xda\xb0\x4d\x40\xfb\xa3\x2c\x96\x78\x48\xac\x0d\xd2\x8a\x40\x7e"
-  "\xcd\xc0\x7e\xc4\x76\x9a\x97\xa0\x9f\x83\x8e\x72\x3c\xeb\xc1\xfb"
-  "\x6a\x5c\x03\xf7\x13\xa1\x8e\x83\x74\xd4\xe3\x04\xf4\x63\xf1\x08"
-  "\xc6\xa1\x8c\x00\xd8\xe3\x7c\x18\x69\x28\x7e\x0b\x64\xa4\x0e\xbb"
-  "\xd8\xcf\x40\x3b\xf4\x3f\x49\x32\xb1\x5c\x7e\xce\xa1\x43\x3c\xe7"
-  "\xe0\x0c\xfe\x71\x67\x92\x9d\xc1\xac\x1d\x30\xf6\x50\x07\x62\x0b"
-  "\x89\x5d\xc5\xce\xe1\xc3\xf8\x93\xc6\x01\x8e\x01\xaa\xbe\x94\xcc"
-  "\xf5\x2b\xce\x64\xd9\x0f\x7d\x47\x95\xa8\x63\x21\x5c\x06\x70\x7a"
-  "\xd8\xff\x74\xb0\xb9\xef\xf1\x6c\x97\xc7\xb3\x38\xe9\x19\xb7\x51"
-  "\x73\x1e\xf5\x78\x36\xaa\xd3\xb3\x3a\x8f\x67\xd1\xca\x32\x5d\xc4"
-  "\xe3\x99\x41\xf9\x9e\x6b\xa0\xc7\xb3\xb0\x4e\xcf\xa2\x3d\x9e\x05"
-  "\x8a\xcf\x02\x20\x7d\xa2\xec\xb3\xab\xdd\x2e\xa6\x03\x8e\xbb\x12"
-  "\x3d\xd2\xeb\xc4\x74\xfc\x7e\xa6\x95\xbc\x53\x23\xa6\xb3\x31\x0c"
-  "\x63\xe4\x4e\xf1\x1b\x05\xf2\x37\xda\x45\x9b\xab\xd8\x55\xbc\xaf"
-  "\xda\x23\x34\x2a\x7d\x2f\x1c\x2f\x9a\xe5\x99\x18\xb7\xc2\xc4\xfd"
-  "\xd3\xf0\x39\xc6\xe2\xb4\xc1\x15\xde\x8b\xf0\x85\x7b\xde\x6d\xf8"
-  "\x04\xad\x74\xee\xc9\x65\x8a\x35\x09\xa6\x1d\xe8\x4b\x74\x10\xfa"
-  "\xb1\xc9\x68\x42\x3f\x00\x76\x62\x21\xed\xc4\x92\xdc\x96\x89\x71"
-  "\xa2\x2a\x78\x7c\xa8\x7e\xb8\xff\x86\x76\xf7\xe8\x8b\xa7\xc2\x78"
-  "\x8e\xc5\x88\x5a\xd4\x44\x06\x1a\x1f\xa4\x75\xf5\x44\x48\x76\xad"
-  "\x8d\x35\x89\x67\x79\x37\xf2\xf3\x68\x02\x6f\x0f\xca\xac\x4d\x4c"
-  "\xff\x1b\x54\x4f\x68\x20\xcb\x43\xe3\x36\xf2\x36\x52\x46\xd7\xad"
-  "\x59\x52\xcc\x1f\x61\x97\x14\x1b\xcd\x4a\x68\x50\x4b\x48\x66\x03"
-  "\xa4\x99\x95\x36\x87\xc2\x57\x58\x26\xd6\xdd\x4a\x84\x34\x2c\x1b"
-  "\xf2\xd4\xb9\x6d\x0e\x21\x7d\x91\x93\xdc\x04\xf5\xaa\x97\xca\x6f"
-  "\xcb\xa2\x81\x56\xe2\x62\x72\x24\x96\xd9\xb2\xf6\x0d\x2d\xa4\xe9"
-  "\xac\x81\x37\x1a\xb9\xcd\x22\x05\xfe\x67\x6f\x4d\x57\xe7\xbd\xa8"
-  "\x76\x3c\xc8\xe3\xe3\x83\x60\x0e\x3b\xf8\xb9\xcf\xf1\x84\xcb\xea"
-  "\x74\x3e\xda\x45\x60\xcc\x3b\x94\x9d\x39\x8e\x50\xbe\xff\x01\x69"
-  "\xd0\x47\x3b\xe9\xda\xf1\xcc\xcf\x9f\x7f\x73\x8e\x32\x9a\xac\xb9"
-  "\x48\x82\x72\x93\x24\x9f\xb9\xb4\xcc\xc3\x97\xb8\x68\x8b\x4c\x5b"
-  "\x2a\x52\xd9\x9e\x10\xab\x63\xe7\x3a\x60\x7d\xa1\x2c\xa3\xcf\xb5"
-  "\x51\x3b\x8e\xfb\x0c\x5f\x37\xda\xc8\xec\xbb\x54\xe4\xf7\x01\xba"
-  "\x01\x4b\xdb\xb2\x49\xb4\x24\x7b\x63\x9e\xdc\x76\xf4\xdf\x34\x5e"
-  "\x6e\x67\x92\x13\xf3\x26\x30\xfd\xb9\x8a\x24\x03\x2e\xa1\xaf\xf4"
-  "\x40\x31\x3d\xb9\xc2\xe9\xc0\x33\x95\x5e\x7d\xab\xb0\x38\x2a\x68"
-  "\x53\xb9\x6e\x9c\x03\x6d\xb9\xef\x71\x88\x75\x56\xa9\x92\xd1\x86"
-  "\x18\xeb\xcc\x68\xab\x52\xcd\x92\xe8\xb8\xfa\x22\x94\x9d\x7e\x92"
-  "\xd4\xa9\xc8\x0f\x68\x77\x82\x36\xf1\x6b\x96\x88\xb6\x50\x90\xc6"
-  "\xf2\xb5\xbb\xf3\x30\xbb\x7e\x3c\x0b\x88\xf8\x58\xc8\xe2\x78\x8c"
-  "\xc3\xf8\x6a\x3b\xd9\xb9\x72\x95\x6a\x38\xd3\x63\x26\x11\xde\x6e"
-  "\xb4\x33\x53\xa9\x98\x9d\x72\x5b\xb6\x2a\xd2\xaa\x52\xb1\xf3\x43"
-  "\x56\x31\x6d\x0d\x7e\x3b\xa5\x9d\x9c\x57\xa9\x42\x30\xee\x1e\xd0"
-  "\x39\x08\x7d\x12\x55\xd8\x61\x9e\xa4\xb6\xe3\x58\x08\xc2\x98\x4d"
-  "\x90\x5f\xcb\xf1\x1e\x68\xae\x22\x76\xfc\x3e\xd2\x16\xfa\xce\x06"
-  "\x34\x7d\x19\xca\x5e\x25\xd1\x14\x63\xe5\x42\x9e\x9d\xbe\xfa\x05"
-  "\x69\xe4\x82\x3a\xe3\x19\x7a\xf3\x4d\x27\xa1\x7e\xea\xa7\x84\xd0"
-  "\x71\x0e\xb4\x69\x84\xba\x5e\xe2\x58\xc1\xfb\x8e\xcd\x25\x95\x7a"
-  "\x28\x7c\x63\x0f\xee\x01\xa2\x8f\x5d\x16\x0f\x59\xa5\xaa\x12\xe9"
-  "\xc7\x7c\xb8\x9b\x52\x38\x1d\xc4\xfc\x39\x5c\xcf\x32\xe0\xa3\xb6"
-  "\x6c\xb5\xbc\xff\x03\xe9\x4c\x67\x16\xce\xcf\x7a\xc3\xb3\x18\x8f"
-  "\x3a\xdb\xd9\x99\x24\x28\x0b\xda\xda\x80\xdf\x5a\x8d\x3e\x63\x70"
-  "\x5c\x34\x7a\x8c\x7f\x95\xea\x18\xd6\x13\x6d\xe6\x5c\x21\xa3\x8d"
-  "\x74\xed\xe8\x64\xa4\x33\x94\x4d\x80\xf7\xf0\x1a\xa3\x00\xb1\x12"
-  "\x4f\xb6\xc3\xf7\x8a\x25\x1e\x08\x78\x9f\x41\x8d\x2a\xf5\x69\xde"
-  "\x56\xee\x2f\x0d\xcf\xf7\xba\xd3\xd6\xee\xaf\x86\xf9\x5e\x25\xf2"
-  "\x2c\x55\x3e\x7d\x6d\xdd\x4d\x22\xf1\x1c\xbb\x18\x5f\xd4\x4e\xb5"
-  "\xfb\x53\xd1\x7f\x27\xfa\x22\x33\x2f\xb9\x17\xea\x1b\xb0\xf6\xb5"
-  "\x70\x76\xd6\xca\x6e\xbe\xfb\x22\xea\xbd\x9a\xea\xd3\x98\x7f\x8a"
-  "\xa0\x09\xa9\x4e\xca\xce\x63\xe3\x39\xad\x90\xfd\xc8\xdb\x34\x31"
-  "\x3f\xd6\x58\xe6\x8f\xf5\x45\xa9\x0a\x98\x22\xf2\x26\x78\x76\xf7"
-  "\x57\x8d\xaa\x00\xa6\x9b\x84\xdf\xe1\x8d\xaa\xc0\xbd\x3c\x5e\x17"
-  "\xf7\xab\x2c\xda\x00\xf6\xe4\x67\x38\x6d\x84\xf9\x6c\x54\x05\x0e"
-  "\xd5\xff\x9a\x90\x26\x55\xe0\x30\xe6\xdb\xd4\x14\x5b\x27\xd2\xa0"
-  "\x6e\x0d\xaf\x97\x26\x3e\x55\xcd\xea\x88\xf5\xf3\xb3\x6e\x0e\x71"
-  "\xed\xea\xd9\x96\x1d\x38\x42\x3a\xfb\xc9\xda\x2f\xfa\x3c\x35\xdf"
-  "\x7e\x11\xeb\xf0\xa6\xb8\x5e\x35\x88\xdf\x6e\xf8\xe9\xdf\x0e\x4c"
-  "\x16\xcb\xdc\xc7\xfc\xbe\x02\x5d\xa0\xdc\x7d\x50\x8f\x52\x69\x0d"
-  "\x15\xed\xd6\x23\xd8\xda\x9e\x1d\x58\xe3\x5e\x3f\x45\x1a\x2a\x62"
-  "\x14\xbd\xf8\x62\xb2\x1e\x18\x70\xe3\xb4\xe4\xe7\x12\xf5\x33\x93"
-  "\x92\x5e\x4c\xd2\xa3\x83\x03\xcf\x39\xc6\x6c\x53\xb2\x03\x6d\x62"
-  "\xac\x99\x9d\xee\x58\x33\xd9\x3d\xa2\x3d\x63\x22\x59\x55\x3d\x7c"
-  "\xfa\x34\xf3\xaf\x8d\x3d\x7c\xc6\x4a\x36\xa9\x85\x62\xf8\x2b\x81"
-  "\x3f\x33\xfc\x1d\x45\xb9\x25\xde\x41\x62\x60\x7d\x64\xe7\x34\x25"
-  "\x9f\xd8\x42\x76\x0f\x2d\xee\x4f\xd7\xaa\x7a\xbc\x5f\x28\x04\x12"
-  "\x76\x9e\x3d\x4b\x40\x1b\x0f\xf4\xd1\x5b\x02\x7f\x66\xf8\x3b\x0a"
-  "\x7f\xdc\xe7\xcb\x27\xec\xdc\x5f\xb1\xe7\x33\xdc\x33\xa6\x59\xf9"
-  "\xe8\xeb\xb7\x92\x2e\x0f\x64\x7b\x0c\xc2\x3a\x9e\xaf\x53\x1d\xd4"
-  "\x20\xc7\x46\x8b\xf9\xd8\x7a\xda\x6f\x39\xd1\x7b\xc9\x17\x40\xb3"
-  "\x2e\xe5\x89\xf9\xd8\x7a\x27\xb5\x07\xfd\x47\x43\x7e\x29\x5f\x20"
-  "\xcd\x56\xdb\xc5\x7c\x8c\xaf\x14\xb2\xd4\xde\xbe\xdb\x83\x66\x7d"
-  "\x26\x7d\x57\xeb\x59\x9e\x47\x9e\x9e\x42\x96\xcd\x81\x79\x84\xe5"
-  "\x81\x8c\x7f\xa3\xd9\x3d\xe2\x20\xbf\x57\xd9\xcd\xbf\x7e\xea\x45"
-  "\x3a\xf7\x93\xf1\xb9\x59\x33\x1f\x98\x35\x2f\x05\xa3\x92\x24\xbf"
-  "\xb8\x30\x19\xaf\xf3\xa6\xbd\xc0\x2e\x2f\xc6\x3f\xff\x1c\xff\x91"
-  "\x3c\x27\x12\x7f\xcc\x81\xf1\x86\xd7\x19\x0b\x8d\x78\x79\xee\x45"
-  "\xbc\x4d\x4d\x8c\x58\xf8\x9c\x14\x46\xd5\x73\x1c\x1a\xda\xb2\x7b"
-  "\xc1\xfa\xd1\x83\xed\xc5\xc1\xef\x3d\x20\xcf\xb2\xb8\x37\x9a\xe5"
-  "\x56\x72\xc4\xe0\x24\x92\x0c\xcb\xfb\xbf\x17\x61\x3e\xf2\x54\xbd"
-  "\x0e\x15\x0a\xbd\x82\x34\xcb\x8d\xcf\x69\x9c\xb3\x66\x02\xce\x56"
-  "\xc2\xbb\x36\x2b\xc9\x16\xcf\xe6\xc6\xda\x99\x3f\xb8\xec\x5e\x31"
-  "\x92\xdd\x9f\x60\x8a\xdd\x89\x3e\x99\x99\x1d\xd0\x3a\xe6\x03\xa1"
-  "\x0a\xee\x6d\x70\x8f\x71\x16\xc2\xe0\xbe\x18\xee\x1d\x70\xaf\x83"
-  "\xfb\x81\x82\x29\x2a\x06\xcf\x4a\xc1\xbd\x1e\xee\x07\xb7\x65\x07"
-  "\x4d\x94\xe6\x85\x27\x6d\xc4\x20\x3f\x0f\x78\x95\x77\x95\x3e\x45"
-  "\x60\x6e\x05\xe5\x49\xb1\x14\x59\xdc\xc4\xec\x20\xf7\xfe\x1f\x8f"
-  "\x4b\xa2\x9d\xc2\xd6\x35\xb6\xb6\xdf\x70\x5b\x80\xee\xe6\xde\x8c"
-  "\xf7\xce\x0e\x2a\x93\xf6\x68\x19\x6f\x9d\x1d\x54\xe3\x11\x73\x12"
-  "\xef\x9b\xdc\x31\x27\x39\x2f\xba\x89\xf1\xa2\xaa\x1b\xa2\x68\x76"
-  "\xd0\x14\x77\x5c\xa0\xec\x1b\x14\xfb\xbf\x56\x78\x8e\x32\x0d\xa4"
-  "\x47\xc8\xeb\x60\x90\x19\xbf\xe9\x2d\xbe\x26\xc6\xf4\x8e\x5f\x0c"
-  "\xfc\x37\x5c\x45\x5e\x5c\xcf\x64\xad\x2c\xf4\xfb\x47\xbd\xfa\xa9"
-  "\x66\xf1\xa6\x54\x37\xec\x45\x7f\x8f\xb6\x8c\x19\xaa\x3b\x0a\x89"
-  "\x8a\xdd\x73\x5f\x5f\xf4\xbc\xea\x06\x76\x7e\x50\xf2\x03\xe4\x79"
-  "\x26\xd7\xeb\x19\x80\x13\x84\xf0\xf8\x15\x73\x5e\xd4\x38\xa7\xcd"
-  "\xe4\xbc\x5b\xef\x01\xe2\xfe\x6f\x1e\x5f\xe3\x7b\x07\xd2\x27\xb9"
-  "\xbf\x7d\xab\xaa\x77\x0e\xc6\xf1\xd0\xa8\xe6\xbc\x48\xe1\x5d\x4d"
-  "\xea\xb4\x99\x2c\x0d\xf2\xad\xc0\xb8\xcc\xbc\x7e\x67\x2d\x03\x1b"
-  "\x08\x6d\x75\xf1\xb3\xc6\xaa\x1b\x1a\xa6\xde\x92\x89\xdf\x09\x62"
-  "\xbc\xc3\x09\x12\x8c\x71\x99\xb0\x6e\x85\x1e\x7e\x8a\xd6\x40\x1a"
-  "\xda\x46\x35\x3f\x49\x82\xd1\x5f\x23\xaf\xcb\x0d\x0d\x2c\xfe\x4d"
-  "\x76\xef\x4c\xc9\x97\x02\xd0\xb9\xa1\x73\x7b\x9e\xfc\x23\x9b\x15"
-  "\x43\x9e\x8b\x98\xf8\x28\xfc\x8a\x10\x43\x0e\x7a\x8e\x97\x81\xcd"
-  "\xa1\x8f\x57\x37\xef\x7e\xf2\x43\x16\x37\x2b\xbb\x77\x25\x94\x93"
-  "\xcc\xfa\x78\xc5\x9f\xcf\x22\x9e\x30\x5f\x0c\x2e\xa2\x63\xe7\x9f"
-  "\x04\x3b\x8b\x4d\x56\xaf\xea\xbb\x11\x7d\x26\x32\x5f\x44\xd9\xbd"
-  "\xf3\xb0\xdf\xa1\xaf\xd8\x1a\x2f\xac\x8b\xc5\x7b\xe6\xdf\x53\x58"
-  "\x3b\x26\xd1\xa2\xc5\xb6\xf7\x31\x00\x8e\xc6\xc2\xdf\x9f\x78\x7c"
-  "\x82\x3f\x9f\x95\xca\x44\x5f\x21\x30\x9e\x2a\xe1\xaa\x6d\xcb\xee"
-  "\xe3\x1e\xff\xee\x73\x63\xaa\x3e\xf3\xd1\x9f\x09\xfa\x6b\xe0\x7c"
-  "\x6b\xdf\x97\x38\x2f\xd9\x27\xcd\x4a\x34\x23\xf9\x9c\xee\x93\x63"
-  "\x25\x45\x45\xe2\x6f\x18\xff\x77\x17\x74\x2a\xe3\x6b\x49\x5f\xc1"
-  "\xc7\x7d\x9f\x12\x18\x7f\xb1\xf0\xf7\x27\xc8\x5f\x2a\xc5\x25\x5d"
-  "\xa1\x66\x67\x7c\xea\x03\x74\x24\x12\xd2\x6b\xa4\xf4\x1e\xaa\x18"
-  "\xa0\x4d\x9f\x26\x09\x43\x9a\x43\x47\xa7\xc1\x3d\xd0\x9c\x64\x8a"
-  "\xf7\x39\x6d\xd9\xc1\xc1\xd2\x3d\xfc\xd6\x49\x18\x03\xbf\x81\xff"
-  "\xdb\xda\x20\xfe\x8e\xb4\x92\xd7\xa5\xf4\x11\xd6\xc0\xfe\x65\x52"
-  "\x3d\x85\xac\x00\x0d\xaf\x6b\x5f\xa3\xb0\x76\x87\x1e\x63\xbf\x42"
-  "\x9e\x04\x98\x2b\xdc\x77\x40\x4a\x53\xd1\xaa\x76\xed\x24\x8c\xdb"
-  "\x6e\x7e\x1e\xc7\x40\x5f\xe6\x3f\x6c\xf5\x12\x2d\x8b\x79\x8f\xe7"
-  "\x9b\x59\x1c\x1f\xf4\xff\xe5\x24\x3d\x99\xdf\xe8\xb5\x3b\xb4\xcc"
-  "\x5f\xf2\x22\x43\xb0\xe4\xfb\x0b\xe6\xdc\x28\xaa\x5e\xe5\x44\x7f"
-  "\x60\x4c\xcf\xd5\x66\xe8\xc7\x7c\x80\x89\xbe\xbf\xb6\xa4\x90\xb0"
-  "\x02\x81\xfb\xfe\x62\x67\x9f\x7b\x02\xaf\x9f\xe2\xdd\xff\x17\xcd"
-  "\x3a\xe0\x90\xfc\x7f\x61\xac\x67\xf8\x6d\xa0\xad\x4e\x4c\x63\xfe"
-  "\xf9\x45\xbf\xaf\x81\x5e\x7d\x81\xa9\x01\x03\xd5\xdc\x17\x98\x7f"
-  "\x6b\x47\xdf\x11\xbc\xff\xfb\xa6\x49\xf1\x50\x3d\xd2\x4c\x30\x7e"
-  "\xb9\x9d\x89\xaa\x8f\x51\x4c\x03\xfc\xdb\x3a\xc9\xcd\x67\x01\x76"
-  "\xa1\xbe\x0f\xe6\xa7\x9d\x66\x24\x6e\xf4\x9c\x2f\xcc\x1a\x80\xe0"
-  "\x32\xdc\x03\xd6\xd8\x9e\xf0\xd7\x0b\xff\x46\xb9\x71\xa1\x95\x56"
-  "\x8b\x71\xfb\x9c\x9a\xd4\x00\x3a\xc1\xe9\x0c\x88\x77\xaa\xaa\x58"
-  "\x6c\x42\x17\x51\x4f\x70\x39\xf1\x4c\x71\xa0\xb3\x95\x56\x4d\x70"
-  "\x35\xd3\x35\xcf\x63\x7c\x31\xf4\x65\x3a\x88\xc6\xbb\x4c\x2c\x56"
-  "\x9f\x90\x42\x2b\x91\xc7\x77\xb5\xd2\x32\x57\x0a\x3d\x0a\x7d\x10"
-  "\x8c\xf2\x03\xfa\x5a\xe9\xa7\x72\x90\x7e\xc6\x80\x83\xe3\x5b\x0e"
-  "\x52\xf4\xb3\x82\x71\x6f\x84\x6c\x07\xfa\x7d\x51\xc5\x3b\x03\x32"
-  "\x2d\xce\x3a\xe6\x73\x7a\x42\xea\x43\x74\x82\xab\x17\x05\x9c\x0c"
-  "\x60\x31\x6b\x52\x68\xe9\x84\xc5\xb4\x99\xc5\x33\x5b\x0c\x7c\xf5"
-  "\xe2\x66\x8a\xf1\xd1\xa0\xec\xa3\xf1\xa9\xb7\x63\x3c\xb4\xf6\x09"
-  "\xa9\x42\x46\x7c\xaa\x0a\xea\xf2\x2d\x9d\x90\xfa\x2d\xd4\x27\x12"
-  "\xca\xd5\xc2\xfd\x43\x74\x2b\xab\x67\x26\x93\x63\xa0\x8d\xe6\x35"
-  "\xbc\x9e\x25\x50\xc7\x3d\xe8\x0b\x36\xde\x69\xce\x64\xf1\xd7\xc4"
-  "\x18\xc9\x13\x52\x3b\x28\x7e\x0f\xbe\x15\x3d\x61\x31\x79\x28\x7e"
-  "\xf1\xa0\x4c\x26\x0f\x9e\x47\x9f\x35\x7a\xf8\x6e\x26\xd2\x23\x18"
-  "\x63\x14\xb2\x33\x4b\xd9\x1a\x43\x57\xb1\xd5\x10\x63\x16\x0c\x20"
-  "\x6a\x94\xf5\x5d\x3b\x1e\xd0\xa2\xef\x97\x0c\x1b\x75\xa0\x4e\xee"
-  "\x60\x7b\xb5\x5a\x9f\x12\x08\x78\xa9\x19\x57\x61\x8c\xf4\x7e\x66"
-  "\x2d\x37\x26\x87\xae\x7f\x2c\x99\xe6\xc6\xce\x80\xab\x9d\x9a\xc6"
-  "\xe4\xa3\x4d\x28\xcd\xfd\x43\x0c\x5d\x3f\x0a\xd2\x47\x0f\x84\xab"
-  "\x9d\xe6\x3e\xee\xa0\xeb\x41\x5e\xca\x1d\x5f\x05\x57\xb8\xd7\x9b"
-  "\x21\xbf\x91\xe6\xde\x1e\x09\x57\x1b\xcd\xbd\xa3\x08\xf2\xc1\xfd"
-  "\x10\x2d\x5c\xe1\xfe\xce\x4c\xc8\x07\xf7\xff\x61\xab\x57\x69\x75"
-  "\xf0\x1b\xd2\x9e\x28\xe6\xdf\x9a\xb4\x8f\x7d\x2b\xf7\x4f\x47\xf9"
-  "\x37\x9e\xa9\xe2\xdf\x78\xd6\xca\xbf\x91\xd0\xc4\xbf\x71\x57\x02"
-  "\xe4\x4b\xa5\xb9\xbf\x19\x0b\x57\x07\xcd\x1d\x1a\x0d\xf9\xe0\xfe"
-  "\x9e\xc1\x70\x85\xfb\x61\xf0\xad\xd1\x70\x7f\xaf\x13\xae\x70\x1f"
-  "\xd5\x00\xf9\xd2\x68\xee\xef\xaa\xe1\xea\xa4\xb9\xd1\x58\x3e\xdc"
-  "\x3f\x50\x02\x57\xb8\x1f\xb1\x13\xf2\xc1\xfd\x83\xf9\x70\x85\xfb"
-  "\xe7\xa0\x4d\x8f\x65\xd2\xdc\x99\xbb\xe0\x39\xa1\xb9\x7f\x81\xef"
-  "\x8d\x82\xfb\x59\x61\xf0\x1c\xee\x67\xc3\xfb\xa3\xe1\x7e\x4e\x1a"
-  "\x5d\x3f\x06\xee\xe7\x61\x5b\x57\xd2\xdc\x17\xe1\x3b\xa3\x02\x69"
-  "\xee\x7c\x6c\x33\xdc\x2f\x88\x83\x7c\x70\xbf\x10\xeb\x03\xf7\x29"
-  "\xf0\xde\x18\xb8\x4f\x05\x1a\x3c\x96\x43\x73\x97\x4e\x84\x7c\x40"
-  "\xeb\x74\x3d\x5c\xe1\x3e\xd3\x06\xf9\xe0\x7e\x05\xd0\x70\x34\xdc"
-  "\x67\x9b\x20\x3f\xdc\xbf\x8c\xed\x5d\x45\x73\x57\x45\x41\xbe\x60"
-  "\x9a\xbb\x26\x08\xae\x70\xbf\xb6\x06\xf2\xc1\x7d\x1e\xd0\x6f\x34"
-  "\xdc\xff\x75\x25\xe4\x0f\xf6\xde\x9f\x9b\x9c\x74\x79\x4f\xa8\xeb"
-  "\x1b\x41\x74\x79\x2f\xb8\xee\x2c\xa1\xcb\x7b\x18\x68\xee\xae\x44"
-  "\x48\x87\xeb\x9b\xdb\xe0\x3e\x42\xbc\x87\xeb\x5b\x26\xb8\x8f\x14"
-  "\xef\xe1\xfa\x76\x1a\xdc\x47\x89\xf7\x70\x2d\xc6\xfb\x68\x9a\xfb"
-  "\x1e\x5c\x7b\xc2\xb5\x18\xca\xef\x31\x42\xbc\x87\xeb\xff\xe0\xde"
-  "\x04\xd0\x72\x77\x14\xa4\xc7\xc0\xd5\x0e\xf7\x70\x7d\x77\x0f\xdc"
-  "\x8f\x84\xfc\x3a\xb8\x1f\x69\x1b\x72\x3f\x9e\x91\x27\x42\x78\xbf"
-  "\x48\x1a\xfe\xb8\x2d\xa3\x85\xa8\x71\x8c\xa2\x7f\x73\x58\x9b\x06"
-  "\xd5\xaa\x42\x5a\x8a\xd3\xad\x6a\xcc\xe3\xda\xf0\x98\x51\x08\x7f"
-  "\x0c\xf7\xb5\x7a\x42\xbe\x5e\xf5\xaa\x1b\x87\x22\x9f\x69\x49\xb3"
-  "\xb2\x58\x4b\xa2\x1f\xa3\x9e\xb5\xaa\xd0\x5b\x80\x4f\x88\xc6\x58"
-  "\xba\x40\xb7\x5d\x34\xab\xc7\x45\xa0\x57\x04\xcd\xea\x53\x0b\x57"
-  "\xb8\x0f\x39\x01\xf4\x82\xfb\xdf\xbd\x02\x57\xb8\xff\xf3\x23\x40"
-  "\xb7\x88\xb6\xec\xd0\x34\xab\x4a\xc3\xd7\xea\x6c\x4a\xd1\x07\x2c"
-  "\x9e\xab\x01\x6c\x12\x2c\x69\x76\x42\xb3\x63\x08\xbd\x2d\x25\x92"
-  "\xe9\xd3\xfa\x3f\xa3\xd5\xa4\xc2\xfd\x90\x68\xa8\xf7\xaf\x62\x98"
-  "\xcf\xb9\x2c\x90\x6d\x3b\x06\xab\x79\x3d\xfa\x50\xa8\xc7\xfb\xa8"
-  "\x03\xa5\xe1\xf7\xf8\x7a\xfe\x05\x7b\x7e\x7b\x4a\x31\x7f\x1e\x44"
-  "\xe4\xe7\x7f\xc6\xe7\x2d\x1a\xd4\x5b\xdf\x79\x37\x7b\x6e\xb1\x37"
-  "\x88\x6d\x0c\x80\x67\x37\x86\x60\x5e\xab\xea\x46\x7e\x1e\x43\x15"
-  "\x0a\xed\x09\x20\xcd\xda\x31\x2b\xdb\xb2\x6f\x1c\x09\xed\x88\x12"
-  "\x79\xea\x9d\x54\x1b\xbb\x8b\x9f\xcf\x1e\xef\xd5\xde\x04\x65\x4a"
-  "\x21\x2f\x3e\x7f\x75\x16\xad\x44\x39\x15\xd6\x23\xb5\x3e\x7d\x70"
-  "\x49\xad\xaa\xbf\x76\x0b\xea\x1f\xc2\x16\x1a\xf1\x5c\x0f\x7c\xf3"
-  "\x8b\x8e\x75\x63\xca\x30\x26\x3a\x3c\x0b\xc9\x70\xd0\x16\x73\xfa"
-  "\x23\xb0\x6e\x62\xfa\xe3\x41\xcc\x56\x9c\xe7\xb1\x33\x3b\x21\xfe"
-  "\xdb\xca\x74\xa9\x50\x16\xbe\xeb\x29\x17\xb8\xb2\xab\x9c\x42\xf8"
-  "\xc2\x4c\xb6\xaf\xa5\xba\xf1\xab\xfd\x82\x55\xad\x49\x26\x3d\xf4"
-  "\x4b\x0e\x42\xf9\x61\x7a\xa5\x0c\x29\xe5\x65\xcf\x7a\x1c\x80\xbc"
-  "\x9b\x99\xbe\x27\x2c\x52\xd2\x0f\x53\x68\xc3\xab\xe8\x77\x5a\x4d"
-  "\x62\x70\x8d\xe4\x3c\x61\x58\x31\xfa\x4b\x73\x86\xc5\x65\x3a\xf3"
-  "\xfa\xe9\x5d\x79\x0b\x8d\x74\xc3\xc2\xcc\x7e\x4e\x15\x61\x76\xf6"
-  "\xaa\xb0\x33\xf7\x38\x50\x0f\x77\x1c\xf3\x6e\x11\x7a\x7e\x33\xf6"
-  "\xee\x54\xa2\x36\x27\x9d\xc4\xfb\xaf\x69\x76\x63\xaa\xa5\xa9\x9a"
-  "\xa0\xff\x47\xb8\xaf\xa1\xaf\xa8\x8c\x42\xcf\x96\xe2\x42\xe4\x65"
-  "\x53\x51\x7f\x74\x02\xd3\xa7\x41\xbf\x80\x9c\x10\xb6\xcf\x23\x06"
-  "\x7c\xe5\x6a\xa0\x1d\xf2\x99\x78\x26\x3a\xde\xe5\x42\xbf\x35\x39"
-  "\x56\xa0\x03\xef\xaf\xb0\x22\xc4\x7f\xf1\xbb\x2d\x42\xe8\x98\x12"
-  "\xf4\x64\xa3\x71\x06\xa1\x1f\x90\x16\x76\x8e\xd2\x89\xf1\xa7\x70"
-  "\xdd\xe5\x79\x3d\xfb\x6e\x96\x78\x7e\x74\xd6\xbc\xe4\xa4\xf9\xfa"
-  "\x05\xb3\x96\xcc\xfc\xfd\x90\x85\x11\xfa\xa4\x54\x7d\x12\x8b\x57"
-  "\xca\x12\x66\x44\xe8\x17\xcc\x79\x31\x59\x9f\xbc\xd8\x38\xf3\xf2"
-  "\x78\x94\x3a\xaa\x1d\x93\xc7\x79\xb7\x9b\x98\xfe\x9f\x16\xa5\x18"
-  "\x92\xd3\xa8\xa0\xbf\xbd\x17\xf0\xf7\xfd\x8b\x2f\xf5\xec\x3f\x10"
-  "\xcf\x93\x0b\x59\x7a\x26\x8b\xa1\x0f\xbd\x8d\xa1\x04\xcf\x6b\x04"
-  "\xb5\x65\xf7\xdf\xe9\xde\x33\x51\xdd\x64\xe3\xfa\x8d\xfe\xfb\x60"
-  "\x3c\xb2\x35\x29\x4f\xf2\x2d\x24\x3e\x63\x7b\x0e\xd9\xfd\x81\xff"
-  "\xfb\x3f\xdc\x1f\x42\xd1\xc2\x1c\xce\xf3\x87\xf3\xbd\x1a\x7d\x8a"
-  "\x81\x6e\x8b\x8e\x04\xde\x4a\x85\x63\x95\xc5\xb8\x23\x17\xd9\x99"
-  "\x52\xba\x7e\xb2\x09\xcf\x72\xbb\x36\x3c\xae\x15\xc2\x27\x9b\x84"
-  "\x1d\xd1\xb6\x8c\xd7\x89\xfa\x5d\xc0\x85\x40\x3d\xcc\x87\xdb\xc9"
-  "\xa0\x83\xe9\x0d\xea\xf3\xaa\xf0\x5b\x0e\xa6\x57\xab\x69\xde\xe3"
-  "\x0d\xcd\x83\xc7\xe8\x1c\x59\x44\xc5\xe9\xef\x20\x7f\x1f\x49\x50"
-  "\xd6\x29\xb1\xf7\x9f\x1e\x6d\xef\x3f\xc6\xe1\x58\x3f\xbb\xc8\x7c"
-  "\xfb\xbd\xe4\xd1\xbb\xe8\x85\x4f\x4b\x51\x37\x75\x53\xf5\xa7\x23"
-  "\x51\x37\x38\x66\x95\x43\x3b\xc6\x64\xdf\x30\x59\x8b\xbe\x39\x2e"
-  "\x6d\x98\x6d\x6b\x0f\x1f\x67\x3c\x0c\x79\x8e\x83\x7c\xf0\x19\x8c"
-  "\x4a\xf4\x0f\x76\xe9\xce\xfb\x33\xdf\x6d\x37\xa9\x8f\x96\x8e\xe0"
-  "\xfa\xcc\x04\x98\x33\x6c\x3c\x85\x1f\xfa\x74\x4f\x29\x81\x6f\x93"
-  "\x77\xdb\x47\xa9\xff\x1e\x7d\xd9\xf3\xd3\x9f\x46\x96\x92\x36\xf4"
-  "\xc1\x07\xf2\xd7\x81\x93\xf9\x84\x6e\x48\x98\xf8\xce\x12\x87\x7a"
-  "\x8a\x95\xa8\xcb\xab\xf3\x49\xda\x19\xd2\xd7\x79\xc1\x10\xf8\x36"
-  "\xbc\x7f\x09\x63\x4c\x7c\xa6\x63\x7e\x97\xd2\xcd\x2c\x16\xa2\xa6"
-  "\x02\xf8\x15\xe1\x82\xa1\x67\xc5\x24\x33\x81\xe7\x8f\x38\x1f\xd7"
-  "\x91\xf2\x44\x1b\xb1\xc4\x15\x91\x4b\xea\x18\xb2\xf7\x99\x22\xb2"
-  "\x19\x64\x80\xcd\xe7\x49\x30\xdf\x77\x35\xf4\x74\x76\x18\x02\x9d"
-  "\x4b\x0d\xe8\x07\x83\xd2\x0b\x86\xde\xc8\x9f\x3a\x5f\x34\x04\x55"
-  "\xd8\x8a\xc8\x3d\x0d\xc4\x70\x49\x4d\x34\x97\x96\x1a\x7a\x57\x18"
-  "\xf3\xa1\x2c\x0c\x9e\x4a\x54\xe8\x83\x07\x7d\xf3\x20\x9d\xfa\xc4"
-  "\x91\x49\x4d\xaa\xf0\x8d\xbd\xab\x48\x7f\x8c\x7b\x81\x3e\x9c\xd0"
-  "\xe7\x9f\x10\x96\x30\xd1\x15\x36\x59\x9b\xde\x02\xf5\x42\xdf\x15"
-  "\xbb\x9f\x34\x21\xcf\x3c\x15\x70\x0a\xdb\x2c\x50\x43\xef\x78\xbc"
-  "\xae\x8b\x7d\x04\xf9\x66\xa1\x4d\x87\x71\x39\x82\xb0\x9e\x30\x4f"
-  "\x83\x96\x9d\x06\x5a\x66\x18\x02\x21\x5f\x30\xa4\xf7\xb3\x34\x39"
-  "\x88\x6b\xe8\x93\x45\x77\x1b\x59\x2c\xc7\xb0\xc2\x74\xa2\x35\xa5"
-  "\x93\x30\xfd\xef\xd8\x58\xda\xeb\x7a\xe7\x49\x13\xcd\x36\x14\xd1"
-  "\xe5\x81\x03\x79\xda\x80\x8d\xfa\x3f\x10\xa2\xbf\x97\xfd\x7e\x58"
-  "\xff\x00\xf4\x61\x58\x7c\x31\xe3\xe9\x99\x5c\x37\xe0\x3e\x3e\xc6"
-  "\x07\x0c\xbd\xd4\x33\xa9\x4a\xc8\xde\x6e\x13\x96\x07\xea\x31\xde"
-  "\xea\x79\xd5\x80\x10\x9a\xbb\xdf\x46\xf3\x66\xb3\xb1\x08\xf7\x7d"
-  "\x2f\xf5\x1c\x3c\x91\xe6\x1e\x98\x04\xe5\xc7\x5c\x52\x05\x56\xc3"
-  "\x5f\x8d\xf8\x7e\x20\xb6\xdb\xb5\x2d\x3a\x08\xdb\xcd\x62\x39\x40"
-  "\xbb\xe2\xa1\xcf\x68\x78\x7c\x02\xf3\x0d\xdc\x01\xf4\x15\x63\xde"
-  "\x21\x3d\x90\x06\x42\x87\xa1\x37\x6b\x6b\x87\x21\x18\xe8\x8b\xb2"
-  "\x9f\x26\x7d\x1a\xbc\xb3\x21\x3e\x19\x9e\xf5\xbb\x14\x16\xbf\x13"
-  "\x63\xaa\x58\x8c\x36\xe2\x5a\x1f\x6f\x44\x7f\x46\x1b\x97\xc0\x9c"
-  "\xeb\x1f\x0f\x6b\x7e\x7c\x9a\x38\xb7\x08\xd6\x53\xc8\x3d\x50\x74"
-  "\x09\x6d\xf3\xa1\x6e\x50\xbf\x6a\xf8\xab\xb1\xaa\x74\x39\x97\x86"
-  "\x44\xeb\xe0\x3a\x05\xea\xaa\x87\x35\xca\x8c\xbf\xe1\x99\x1e\xea"
-  "\x3c\x1f\xe9\x80\xf4\x10\x69\x31\x4b\xa6\xc5\x1c\x98\xb7\xba\x38"
-  "\x21\xbb\x28\xcf\xaa\x1a\x10\x4d\xb3\xff\x33\xd3\x23\xdf\x5a\x39"
-  "\x5f\x6a\x11\xcf\xf7\xf6\x48\x9e\xef\x51\x07\xf4\xc3\x50\x91\xde"
-  "\x5f\x78\xa1\x77\xb9\xfc\xee\xb4\x51\xfc\xdd\xf5\x55\xfc\xdd\x48"
-  "\x7c\xb7\x47\xa7\x3a\xb9\xe4\xfc\x7f\x4e\xe3\xf9\x4d\x2b\x79\xfe"
-  "\xdf\x94\xca\xf9\x6e\x1a\x22\xe7\xfb\x4b\x10\xcf\xb7\x79\x20\xcf"
-  "\xf7\xbb\xc1\xf0\x7c\xda\xe5\x75\xb9\x69\xb2\xfc\xce\xca\x55\xfc"
-  "\x9d\x0f\xa2\xf9\x3b\x13\xf7\xc0\xf3\xb5\xca\xba\xdc\xf4\xb2\x9c"
-  "\x3f\x5d\x6c\x77\xf1\x51\x9e\xff\xf1\x04\x8f\x7c\xef\xf1\x7c\xf8"
-  "\xfc\x63\xc8\x37\x20\xe2\x52\xcf\x57\x8c\x3c\xdf\xd3\x04\xc7\x23"
-  "\xe4\xf9\x5c\xc8\xfe\xb5\xe1\x52\xcf\xff\x18\x0c\xe5\xe8\xa1\x6f"
-  "\x06\xe2\x15\xfa\x6e\xa0\x60\x1a\x03\x75\xf9\x55\x3e\xee\x57\x20"
-  "\xe6\xc2\x9a\x90\x0a\xb8\xeb\xf2\xba\xff\x99\x7d\xb3\xd6\xad\x1f"
-  "\x13\x80\x7f\x58\xff\x58\x8c\x57\xfe\x6e\xdd\x23\x7b\xd0\x26\x01"
-  "\x31\xa5\x5e\x75\xf3\x72\xf4\x73\x45\x33\x46\x89\x3a\xa9\x9b\x99"
-  "\x6d\x0d\xfa\x5b\x40\xbd\xa5\x98\xc6\xf6\xb2\x05\x18\x9b\x20\x77"
-  "\x96\xa0\x6f\x31\xd4\x53\xc2\x1a\x05\xed\xbd\x39\x0f\xe3\x9f\xbf"
-  "\xa6\x16\x8a\xe1\xaf\x04\xfe\xcc\xaf\xa1\xfe\x32\x8b\x3c\x2a\xe9"
-  "\x76\x7d\xd4\x15\xd6\xbf\x1c\x93\xac\xdf\xba\xb9\x0c\xca\xf2\xdf"
-  "\xbf\xbf\xea\x66\x9f\x7e\xae\x58\xfc\x52\xe4\x95\x36\x3c\x66\x32"
-  "\x09\x3c\xce\x31\xcc\x45\xe0\xf9\x06\xde\x06\x6b\x7e\x26\x3e\x13"
-  "\xf2\x9e\xd1\x0a\x83\x61\x2d\x39\x47\x02\x2c\x69\x0d\xa4\x58\x68"
-  "\x50\x9b\xda\x49\x60\x05\xac\xa7\x98\xbf\x18\x78\x07\xfd\x3c\xe4"
-  "\xa1\x06\x0e\x37\xb5\x8a\xe5\x15\xa5\x44\x66\xcc\xe5\xf1\x63\x91"
-  "\xf7\xc4\x35\x08\x70\x27\x98\xc5\x01\x9a\x87\xfc\xce\xc0\xb9\xf0"
-  "\x3b\x88\xc5\x0b\xde\xf1\xbb\xe2\x4b\xff\x95\x12\xd9\x11\x3e\xd6"
-  "\xd8\x7e\xe7\x70\xd3\xa5\xf0\x67\xb4\xce\x0d\x71\x26\xe7\xed\x0b"
-  "\x8b\x3a\x76\x44\x47\xba\xc2\xc7\xda\xe0\xdb\xb0\x3e\xe5\xab\x77"
-  "\x0b\x26\xf5\xee\xf4\x12\x35\x96\x7b\x30\xbd\x58\x7d\x20\xbd\x52"
-  "\x7d\x40\x38\xaa\x3e\x98\xbe\x13\xae\x45\x18\x13\x06\x78\xdc\x81"
-  "\xfb\x0f\xa4\x9b\x61\x7d\x1c\x88\x6b\xa9\x53\xd2\xa3\xd2\x47\x9c"
-  "\xa4\x62\xa7\x93\x1c\x49\x6e\x21\xb6\x90\x31\x79\xf0\x97\x6f\xeb"
-  "\x1f\x0f\x7f\xb3\x59\x7c\x50\x1a\x3e\x8d\xb5\x11\xcf\x58\x1d\x10"
-  "\x78\x9d\x45\x7a\x40\x99\xb7\x0c\x29\x14\xf0\x1c\x16\xf3\xff\x16"
-  "\xdc\xa8\xba\xc5\xca\x68\x63\x7a\xdb\x00\x32\x64\x1b\xb3\xd1\x56"
-  "\xf3\x78\x44\x92\x7f\x35\x29\x9e\x11\x8b\x61\xd4\x66\xc0\x3d\xf4"
-  "\xc1\x18\xc7\x68\x4b\x2b\x09\x83\x3f\x9d\x14\xa3\x66\x8b\xe8\xbb"
-  "\x3c\x37\x45\xd6\x5d\x88\x7a\x89\x30\x1e\x8f\xe6\x03\x03\xea\x30"
-  "\x18\xdf\x86\xbe\xd8\x50\x47\xb1\xc0\x80\xbe\x4e\xdd\x3a\x0a\x57"
-  "\x9b\x41\x0d\x72\x71\xa5\x28\x17\x9b\x51\x0e\x46\xb9\x1d\x65\x61"
-  "\xe4\x75\xe2\x53\xcd\xcc\x37\x2a\xf3\xdb\xb1\xfe\x4f\x36\xe4\x43"
-  "\xdb\xb2\x6f\x1d\x28\xc9\xbc\xc8\x5b\xb9\xd6\x8e\xd9\x06\x7f\x45"
-  "\x90\x1e\x65\x55\x1d\x2a\x90\xd2\xe9\x06\x0d\xca\x14\x01\x2e\x9a"
-  "\xf8\x60\x1b\x9e\x1f\xa2\x89\x0f\xb9\xd6\x3f\x0e\xf8\x3a\x3b\x13"
-  "\xd2\x46\xc0\xdf\xef\x5d\xeb\x35\x51\xf0\x17\x0d\x7f\x23\xe0\x2f"
-  "\x06\xfe\x46\xc2\xdf\x28\xf8\x9b\x08\x7f\x93\xe0\x2f\x0e\xfe\xa6"
-  "\xc0\x5f\x02\xfc\xcd\x10\xd6\x6b\xc6\xa2\xaf\x32\x28\xdb\x08\xe3"
-  "\x40\x27\x95\x2b\xd3\xfb\xd6\x8d\xd0\xfe\x18\xe4\xfb\x68\xbf\x03"
-  "\xc1\x14\xe6\x3b\xdd\x7e\x7f\x34\xab\x3f\xe2\xf2\xf6\x31\x3a\xdb"
-  "\x6d\x29\x7a\x5b\xff\x69\x7a\xdb\x6d\x0b\x73\x6c\x21\xe9\x3b\xe1"
-  "\xaf\x18\xfe\x4a\x6c\xeb\xe3\x8b\xa1\x4f\x73\x6c\xfd\x13\x62\xda"
-  "\xb2\x07\x11\xab\xea\x4e\xc2\xf5\x59\x83\x82\xe1\xb7\x5e\xfc\x0d"
-  "\x18\x7f\x7b\x0e\xfe\x86\x32\x40\xfe\x1f\x04\xb8\x31\x98\xc7\x26"
-  "\x08\x8f\x37\x8b\x67\x91\x32\x21\x3d\xc6\x1a\x78\xb7\x8d\xe7\x8b"
-  "\xcb\xc4\xfd\x27\x48\x9b\x24\xcd\x43\x85\xdf\xf4\xe7\x8c\xf1\x73"
-  "\xa7\xa5\xc6\x2f\x98\x33\xeb\xb9\x99\x0b\x1e\xd0\x0f\x99\xa1\x37"
-  "\xcc\x4a\x9a\x1f\x3f\x7f\xe1\xcc\x85\x33\x19\x0b\x09\x49\x77\x29"
-  "\xf6\x9f\xc2\xf0\xcc\x95\x73\xf7\x93\xc5\x02\xc8\x47\x15\x75\x0d"
-  "\xa4\x0f\xc8\x46\xcb\x9e\x25\xea\x32\xfb\x1e\x02\x72\x4c\xa4\xd0"
-  "\x33\xe6\xa1\x8a\x19\x56\xb2\xaf\xd1\xa6\x76\x02\x4f\x37\xd6\x66"
-  "\x86\xb9\xfa\x8c\xb6\x6f\x5d\x3c\xdd\xd7\xe8\x50\x8f\x6d\x32\x93"
-  "\x8c\xd3\xc0\xe3\xcd\x70\x90\x8e\x3b\xa3\x23\xf7\x35\x16\x03\x7f"
-  "\x0f\xbc\x5e\x66\x3b\x29\x73\x38\x61\x4c\x4f\x36\xe1\xbb\x14\x78"
-  "\x3d\xcc\x8f\xb2\x17\xfa\x51\x84\xbc\x36\xba\x61\xac\x11\xf3\x1f"
-  "\x80\xf4\xf1\x46\x33\x19\x07\x65\x75\x84\xc7\x99\x28\xcc\x37\xda"
-  "\x9a\x46\xcb\xea\xcc\xe4\xc0\xec\x62\xf5\x7e\x78\x1f\xf5\x79\x14"
-  "\xe6\x69\x07\xcc\x4f\x0a\xf3\x12\xdf\xc1\x67\xb5\x2a\xbd\x03\x9f"
-  "\xa3\x3c\xd5\x01\xf5\x7d\x17\xca\xcb\x58\x48\x02\x25\x99\x53\x31"
-  "\xef\x53\x34\xc0\x07\xeb\x67\xe2\xbc\xa7\x50\x57\x6c\xc7\x3b\xf0"
-  "\xee\xee\xd9\x0e\xf6\x3e\xc8\xa0\x01\x28\x7b\x22\xb6\x20\xa6\x58"
-  "\xd2\xb8\x0c\x5a\x2c\xa0\x7e\x25\x00\xdf\x7d\x1d\x9f\x81\x9c\x62"
-  "\x2f\x60\xb2\x8a\xbe\x46\x92\x0f\x5e\x15\xfd\x1c\xf5\xa9\x81\xf1"
-  "\x33\x95\x0c\x3a\xaf\x1a\xf4\x3a\xd2\x14\x69\x86\x7b\xc0\x1d\x3d"
-  "\x07\x25\x6c\x46\x1f\x49\xa1\x24\xa8\x63\xfd\xc2\xd4\xcd\x68\xa7"
-  "\x94\x7d\xdb\x40\x89\xe7\xb6\x87\x2d\x4c\xf5\xec\x4b\xde\x87\xfa"
-  "\x99\xf3\x70\x37\x63\x06\xdb\x36\x9c\xb6\x60\xc1\xc2\xb9\x33\xf5"
-  "\x33\xa7\x3d\x97\xa8\x67\x8f\xf5\x0b\x17\x40\x96\x59\xc9\x0b\xf4"
-  "\x2f\x2e\x9a\xa7\x9f\xbb\x60\x16\x4a\x0f\x33\x93\x92\x16\x1a\x93"
-  "\x7b\x13\xfe\xa6\x7e\xee\xc2\x39\xc9\xb3\x8c\xf0\x63\xc1\xcc\x79"
-  "\x33\xf4\x6c\x24\x2c\x80\xa2\xe6\xcc\xd1\x8b\x5f\x58\x90\x38\x2d"
-  "\x09\x07\xc7\xbc\xbf\x40\x26\x8f\xf7\x95\xb2\x45\x30\xfa\x91\xc2"
-  "\xf5\xe8\xbc\xea\xf6\x65\xa5\x81\x30\x8f\xf3\x16\xa6\xa2\xdd\x02"
-  "\xdc\xa7\x31\x79\x33\xfb\xb6\x08\xdc\xe3\x79\x2d\x94\x04\x36\x0f"
-  "\x19\xa3\x83\xb6\x39\xa4\xb6\xb1\xd8\xf1\xe8\xaf\x0d\x7d\x01\xaa"
-  "\x6e\x9f\xc5\xce\xcd\xc1\x1c\x61\x76\x2d\xd9\xb7\x3d\xc4\xf7\x44"
-  "\x6e\x37\x78\xf8\xaf\xb7\x33\xbf\x71\xaa\xdb\x1f\xe6\xfb\x23\xb7"
-  "\xa7\x21\xcf\x24\xfa\x3d\x56\xc1\x3b\x73\xf1\x1d\x61\xfd\xec\x1c"
-  "\x78\x2f\x41\x96\x5b\x6e\x8f\xc6\xfc\x2c\x5f\xf6\x6d\xaf\xd0\xfe"
-  "\xf1\xc5\x90\x36\x10\xeb\xe5\x63\xed\xd1\xb7\x42\xb9\x9f\x15\x13"
-  "\xf2\x9b\x30\x62\x68\x5d\x37\xde\xd0\x16\x3a\x66\x67\x7b\x16\xe9"
-  "\xd5\x0e\xeb\x9d\x43\x4d\x06\x5d\x82\x71\xb1\x78\x18\x09\x58\x36"
-  "\x8e\xa8\x8b\x61\xbc\xa1\xef\xec\xb2\x51\xf9\xc4\x92\x60\x25\x16"
-  "\xc7\x2e\x52\x66\xae\x25\xe5\xce\xb7\xb8\xdf\xed\x25\x28\x77\xdc"
-  "\x71\x1a\x7d\x41\x65\x2c\xa3\xae\x77\x3f\xb2\xf5\xd8\x0d\xe3\x51"
-  "\x9f\x44\x06\x59\x9c\xdf\x98\x2d\x69\xdb\x88\x25\xd5\x62\xc6\x73"
-  "\xf2\x40\xb7\xf2\x03\xf0\xec\x86\x32\x78\x6f\x3c\xe9\x05\xf7\x87"
-  "\xf0\x1b\x39\x1b\x68\xf5\xcb\xe1\xb4\xe6\xe5\x0d\xd4\xba\x2a\x9c"
-  "\xd6\xc1\x98\x6a\x58\x1d\x4e\x9b\x56\x63\xdc\x47\xdc\x3b\x80\xfa"
-  "\x18\x53\x88\xae\x51\x75\x47\x1c\xd3\x95\x8c\x64\xf7\x03\xe0\x9e"
-  "\xad\xff\x96\xd4\x0d\x78\x7f\x13\xdc\xa7\xf2\xfb\x42\xbc\xbf\x19"
-  "\xee\x73\xf8\xfd\xa7\x78\x3f\x10\xee\xf3\xf9\x7d\x05\x61\x67\xc6"
-  "\x55\x77\xec\xe4\xf7\x5f\xe2\x3d\xd0\xfe\x8e\x12\x73\x0a\xd6\xf7"
-  "\x14\xf4\xd9\x1d\x47\x32\xbe\x06\xf9\x35\xb5\x9e\xcd\x87\x83\xe9"
-  "\x89\xa8\xcb\x81\xf9\x70\xc7\x68\x1c\xef\x56\xd5\x1d\x0d\x3d\x23"
-  "\xf1\x7a\x7b\x93\xc6\x41\x7a\x01\x2f\xd9\x07\xda\xb3\x17\x69\xe7"
-  "\x95\xb7\xd9\x3d\x26\x7e\x82\x93\x9a\xe9\xf6\x68\x03\x5d\xff\x8c"
-  "\x89\x6e\x1f\x6e\xa4\x6c\xfd\x7b\x6c\x62\xf1\x12\x07\xf3\xf9\x09"
-  "\xfc\x3b\xcc\xa1\xc1\xcc\x5f\xaa\x0d\xf8\x61\x1f\x3e\x00\xb5\x74"
-  "\xfd\xe3\x26\x90\x33\x75\xe3\x0c\x4e\xb4\x31\x04\x19\x60\xf0\xde"
-  "\x23\x89\xc8\x4f\x4c\x0b\x10\xb6\x0d\x37\x0a\x19\x71\x84\x0e\x8e"
-  "\x36\x8c\x4b\xa4\x66\x58\xdb\x54\x5c\xc7\x4e\xbf\xc1\xf8\xd7\xec"
-  "\xbb\x43\xa2\x0d\xc2\xa2\x44\x8c\xfd\xc1\xf0\x25\x1d\xd7\xf9\x14"
-  "\xc0\x83\xa5\x71\x1a\xd7\xfa\x69\xe4\x48\xe2\x19\xff\xe2\xe8\xa8"
-  "\x06\xfb\x8c\x95\x81\x75\x72\xd1\x38\xe2\x84\xef\x38\xa1\xad\xc8"
-  "\x53\xec\x06\xde\x01\x78\x1b\xc3\x3b\xd3\xab\x7b\xd0\x45\x71\x1a"
-  "\x68\xd3\x30\x8b\xa1\x85\x54\xb4\xe3\x5c\x19\x92\x7a\x04\x7a\xf1"
-  "\xd1\x54\xa7\x59\x63\x63\xbe\x4a\xb5\xc6\xd9\xe4\x56\xda\xff\x71"
-  "\x53\xa3\x6a\xc8\xd1\xf1\x69\xd0\x06\x68\xfb\x81\xda\xea\x40\x01"
-  "\xda\x71\x0f\xa7\x1b\xbe\xb7\x0b\x68\xab\x93\xe4\x1e\xff\xea\x3f"
-  "\x84\x8d\x1b\x61\x41\x1c\xc1\x73\x80\xef\xa6\x43\xfd\x3a\xe2\x34"
-  "\x02\xac\x51\xf8\xec\x88\xe1\x1c\xc1\x6f\x72\x5a\x0f\x61\xbe\x71"
-  "\xe8\x60\xa0\x33\x7c\x1f\x7d\xa4\x4a\x74\x85\xbc\xbb\x5c\x1d\x89"
-  "\xde\xfb\x7f\x43\x42\x25\xd4\x0f\xfa\x4e\xe3\xdd\xc7\xed\x86\x7e"
-  "\x94\x8f\x8f\xfb\x47\xc1\x5f\x1c\x7d\x7d\xa1\xc9\x36\xe4\xfe\x44"
-  "\x16\xb3\x6d\x43\x1c\xf1\x88\xcd\x0d\x63\xe4\xce\xd1\x18\x9b\xdb"
-  "\xbb\x0f\xaf\xed\x06\x16\x13\xa7\xc7\x37\x54\x83\xb1\xe7\xd3\x5a"
-  "\xd0\xdf\xae\xe1\x88\xc1\xee\x67\x9f\xde\xb9\xca\x57\x9f\x62\xf9"
-  "\x8f\xde\x45\x3b\xfc\x2c\xaf\xc6\xe7\x18\xd9\x06\x74\x09\xd3\xe8"
-  "\xdb\xe9\x48\x15\x97\x4d\x0c\x8b\x91\x56\x1d\x20\x57\x2c\xf9\x82"
-  "\xa8\xdb\x61\xdd\x7c\xfb\xe9\x22\x75\x04\xcc\x3b\xe0\x5f\x32\xcb"
-  "\xaa\xcb\xc8\x84\x19\x24\xa3\xbc\xe9\x22\xfa\x29\x66\xb1\x6e\x68"
-  "\xf8\xd4\xca\x5d\x4f\xdb\xd4\xe8\xab\x1f\x63\xdb\x54\xd8\x41\x8e"
-  "\xdf\x10\x6f\x7e\xf7\x69\x87\xda\xb5\x28\x4e\x8f\x7e\xda\x71\xaf"
-  "\x38\xbd\x89\x0a\x6c\xcf\xab\x19\x78\xc5\x66\x90\xd7\x4d\xb1\xa3"
-  "\xca\x12\x8e\xb2\x18\x9c\xe8\xe7\xa3\x3c\xb1\x85\x7c\xb6\xf2\x00"
-  "\x29\xab\xae\xc6\x73\x84\xaf\x97\xd5\xed\x23\x42\xb3\xa1\x9f\x6b"
-  "\x81\x21\xb4\x20\x89\x84\xc1\x3c\xbd\x41\x00\x1a\xd3\x05\x62\x6c"
-  "\xc3\x8b\x72\x6c\x43\x8c\x1d\x5e\x80\x71\x0a\xcf\x69\x89\xb3\xe7"
-  "\x9d\x46\xc8\x1f\x88\x71\x0c\xb7\x5c\x24\x86\xcd\x49\x64\xf0\x66"
-  "\x78\xa6\xd8\xf3\x7a\x01\xf8\xc9\xd9\x24\xa8\x5f\x0b\x8f\x63\x8e"
-  "\xf1\xd8\xa5\x38\x86\xe3\x5b\xf4\x64\xdf\x97\x45\x6a\x1c\x7b\xfe"
-  "\xd1\xd9\xc0\x62\x0b\x38\xc3\x13\x2a\x9d\xfd\x35\x7a\xe7\x90\x68"
-  "\xad\x55\xf5\x1f\x23\xa0\xbf\xbc\xca\x66\x12\xed\x3b\x32\x24\xda"
-  "\xff\x5a\x25\xd1\x7e\xe9\x64\xa2\xbe\xb4\x23\xda\xf6\xd6\xc9\x7c"
-  "\x99\xf6\x55\x97\xd3\xbe\x33\xcd\x77\x3f\xe3\x50\xb3\xfe\x78\x06"
-  "\x78\xa0\x1d\xf7\x67\xbe\xf5\x0c\xef\x03\xca\xfa\x20\x41\xee\x83"
-  "\x0e\xe8\x83\x0e\xb9\x0f\xd2\xe7\x4b\x7d\x70\x86\xf7\x41\x15\xeb"
-  "\x83\x69\xac\x0f\x3a\xa0\x0f\x96\x1a\x42\x37\x2d\x21\x61\x05\x4b"
-  "\x88\x8e\xf5\x83\x76\x3b\xc6\x6c\xe8\xbd\x7a\x09\xf4\x43\x3b\xf4"
-  "\x83\xc3\xdd\x0f\x61\x8a\x7e\x58\x22\xf6\x43\x3b\x31\x6c\x6a\x27"
-  "\x83\x37\x65\xf1\x7e\x40\x5c\x1f\x6f\xd7\x50\xe1\x7b\x03\x29\x6c"
-  "\x84\x7e\x98\x2f\xf6\x43\x88\xd8\x0f\x4b\xa1\x1f\xe6\x43\x3f\x40"
-  "\xfb\x8f\x18\xfc\xc5\xc4\xbb\xca\x2e\xef\x07\x43\x49\x77\xfd\xd0"
-  "\xee\xee\x87\xdf\x6c\x61\xfd\x00\xbc\xd4\x92\x27\x50\x57\x17\x6d"
-  "\x7b\xf3\x84\x49\x1d\x11\x07\xd8\x03\x34\x2d\x1b\x5b\x4a\x26\x24"
-  "\x90\x0c\x27\xf4\xc9\x5b\x27\x1c\xea\xb2\x3a\xe8\x8f\x19\x94\xeb"
-  "\x21\x3c\xfa\x83\xd1\x7d\xc3\xd4\xca\xb7\x21\x8f\xfe\x69\x9c\x27"
-  "\xf1\xe6\x77\x4e\x00\xef\xe8\x25\x26\x94\xe7\x5e\x30\x94\x25\x60"
-  "\x3c\x60\xb4\xbb\x03\xf9\xaa\xdf\x26\x90\x9f\xca\x13\xbf\x26\xd2"
-  "\x9e\xf0\x67\x35\x66\x28\xdb\x10\xfa\x59\xe0\x07\xe4\x78\xd9\x51"
-  "\x3c\x2b\x7e\xdb\x66\x81\x84\x1d\xaf\xda\x83\x7c\x81\x16\xc6\xf8"
-  "\x0d\x2e\xe8\x1f\x57\x9b\xae\xf7\x2a\x90\xb1\x70\xaf\xd8\x73\x8f"
-  "\x18\x63\x79\x52\xe8\x1b\x48\x0f\x74\x42\xdf\x14\xb4\x12\xc3\xc6"
-  "\x56\x32\x78\xa3\xd8\x37\xee\x18\x9f\xdf\x1a\xc8\x96\x5a\x12\xd4"
-  "\x77\x16\xef\x1b\x97\xd4\x37\x8b\x0c\xea\x71\xb3\xf4\xe4\x23\xa0"
-  "\xc9\x11\xc3\x17\x7e\xf6\xcd\x6f\x18\xdf\x40\xa1\x6f\x28\xf4\x0d"
-  "\x65\x7d\xf3\xeb\x18\x5f\x7d\xe3\xda\x76\xff\x28\x97\x76\x8c\x09"
-  "\x7d\x53\x0b\x2f\x4e\x52\x09\x20\x3f\xb5\x83\xdc\xfa\x99\xcd\x49"
-  "\xd2\x40\x6e\x58\xf2\x35\xe9\x69\x99\x74\x82\x58\xac\x25\x04\x7d"
-  "\xc1\xa2\xde\x1b\xfd\xbd\x5b\x9c\x25\x40\xef\x17\xd8\xfd\x16\x76"
-  "\x6f\x23\x4b\x9f\x25\x01\x2c\x66\x5c\x5c\x11\x59\x05\x7c\xf5\x3b"
-  "\xcf\x14\xa9\x85\xbc\xc7\x1b\xa8\x36\x12\xe3\x6c\x9b\xf1\xdc\x12"
-  "\x60\x51\x70\x79\x62\x19\xfa\x7d\xfb\x26\x23\x95\x9e\xae\xb0\x43"
-  "\x99\x36\xda\xee\x82\xb5\xa1\x30\x8b\x96\xa0\xef\xee\x7b\x52\x19"
-  "\xcf\x0d\xe3\x24\x62\x31\xf2\x1c\xa8\xff\x33\xa7\x6f\x02\x1e\x2b"
-  "\x62\x19\xb6\x0d\xd2\x54\xe5\xb3\xed\xf0\xfc\x9e\x73\x58\x2f\xae"
-  "\x8b\xe7\xd7\x7b\x30\xb6\x56\xf8\x0b\xb1\xfb\xd3\x6d\x81\x26\x90"
-  "\x87\x81\x17\xc3\x72\x8e\x51\x2e\x1b\x26\x5a\xaa\x1c\x4c\x0f\x6b"
-  "\xcb\x48\xec\x69\x5a\x82\xf1\x96\xd0\x0f\x38\xae\xcd\xf7\x6c\xc1"
-  "\x78\x98\x74\x1b\xac\x4b\xe1\x71\xa4\x78\xba\x4d\x2d\xaf\xbf\x11"
-  "\x76\x58\xb7\x12\x1f\x35\xd0\x0c\xf4\x97\x7e\x00\xda\x85\xf2\xcf"
-  "\x5b\xb5\x0e\xb5\x03\x30\xe4\xed\xe9\x39\x6a\xd4\x13\x39\x60\xfc"
-  "\x95\x7d\xf9\x37\x66\x33\x5d\xaf\xba\xbb\xc7\xf1\x38\x27\xc1\xef"
-  "\x3f\x75\x17\xee\xb5\x0c\x8d\xbe\xa4\xfe\x40\x7f\xa9\xe7\x9d\x65"
-  "\x19\x75\x72\x0c\x33\xcf\x58\x65\x38\x96\xdf\x99\x0e\x65\x42\x39"
-  "\xbb\x6b\x33\xd5\x54\xc2\xf5\x16\xb4\xb3\x57\x62\x4a\x79\xd3\x39"
-  "\x92\x0e\xe3\xb8\x3c\xb1\x88\xf9\xb4\xef\x07\x78\x2e\x2c\x05\x1c"
-  "\xe9\x30\x84\x6e\x01\x1c\xc1\xf9\x5f\x08\xb8\x21\x2c\xd5\xf5\xce"
-  "\x6d\x27\x11\x12\x7e\x20\x8f\x85\xd7\x67\x61\x8c\x6a\x8e\x42\x1a"
-  "\xf4\x93\xb0\x16\xc6\x28\xe0\xc7\xe6\x25\x1c\xc7\xb7\x20\x7e\x00"
-  "\xff\x3b\xde\x08\xf8\xb1\x08\xf0\x23\x85\xc5\x98\xd4\x15\xaa\x39"
-  "\x6e\x7c\x54\x9b\xa3\x36\x49\xf1\x70\x19\x7d\xef\xde\x58\x81\xe3"
-  "\x23\x21\x93\x9d\x4b\x73\xa1\xdf\xf9\xa5\x71\x01\x15\x76\x18\x23"
-  "\x1b\x66\xdb\x30\x8d\xe1\xe7\xa2\xc4\xde\x02\x1f\x6b\x31\x48\x93"
-  "\xad\xe7\x49\x24\x8b\xb7\x76\x41\xd7\x7b\xcd\x3c\x12\x51\x78\x9e"
-  "\x0c\x2e\x9c\x47\x0c\x30\x5f\xd5\x85\x50\x87\xa9\xf3\xb5\x84\xf9"
-  "\x8e\xef\x79\x67\x15\xa4\x7b\xf5\x1d\x0f\xfc\xb3\xae\x10\xe7\xcc"
-  "\x8b\x06\x77\x9d\x9c\xa6\x4c\xb3\x0b\x68\xc7\xfc\x1e\xa9\xee\xe6"
-  "\x31\xc0\xb4\xbf\x8d\xe1\xfc\xfc\x3d\x62\xbc\x8e\xe8\x91\x20\x93"
-  "\xf4\x6a\x54\xdd\xfd\x15\x5d\x17\x13\x6d\x5c\x42\x54\x8d\xd2\x33"
-  "\xe0\x31\x05\xe8\xab\xbb\x33\x49\xa6\x10\xf2\xf6\x28\x4b\x2a\xf0"
-  "\x48\x19\x89\x7e\xce\xc3\xbb\x59\x0c\x2d\x97\x29\xb3\x14\xdb\x2b"
-  "\xac\xcb\x2c\xdb\xda\x48\x22\xe9\x0b\xd0\x1f\xb3\xa1\xad\x8d\x64"
-  "\x70\x41\x23\xb4\x75\x11\x6f\xab\x14\xff\x57\xc8\xfa\xc0\x00\xcf"
-  "\xbc\xeb\x66\xa4\x58\x72\x2f\x60\x2c\xb9\x48\x2d\x60\xd8\x8d\xf4"
-  "\x76\x42\xca\x9b\x98\xef\x8a\x36\x8b\xf3\x6b\x82\xdf\x45\xdd\x91"
-  "\xe5\x22\x1b\xd3\xe5\x38\x96\x85\xa2\x85\xa6\xf8\x1a\x18\xdb\x6d"
-  "\x89\x84\xc2\xef\x03\xb5\x36\xf4\x15\xc1\x78\x3b\xab\x2a\xc2\x89"
-  "\xfc\xd8\x41\x48\xc3\xb1\xef\x31\xe6\x9d\x38\xe6\xf1\x39\x1b\xf7"
-  "\xf0\x9e\xa5\xe6\x0c\xc1\xf2\x3c\xcb\xc1\xfe\x97\xca\xaa\x57\x45"
-  "\xbe\x87\x65\xe1\x58\x40\x1d\x0f\xce\x35\xde\xf7\x25\x68\x43\xae"
-  "\xa3\xe1\xe3\x8c\xfc\xde\x86\x76\x21\x5a\x1c\x03\x6c\xac\xc0\xba"
-  "\x8a\x3e\x49\x29\x8d\x0b\x80\x71\x86\xf5\xec\x0d\xfd\x1d\x29\x8d"
-  "\x0b\x48\x0b\xeb\x3c\x36\xfa\x2d\xd7\xa2\xec\x12\x86\xbf\xaf\x74"
-  "\x7c\xf8\xd7\x7f\x91\x3e\xcf\xff\x09\x83\x81\x8f\x05\xbc\x44\xdc"
-  "\x74\x35\x7b\x60\x66\x13\xc7\x4c\xc4\x24\x09\x37\x19\x36\x31\xff"
-  "\xe0\x25\x68\x4b\x9b\xc8\xea\xe8\x27\x6e\x96\x37\xc9\xb8\x39\xde"
-  "\xe8\x81\x9b\x4d\xb4\x5d\x18\xe2\x0d\x37\x87\xbd\xa7\xc4\xcd\x61"
-  "\xef\x2b\x71\xf3\xbe\x01\x9d\x71\xf3\x72\xcc\x1c\xd6\xe2\x0d\x2f"
-  "\x41\x5e\x19\xd4\xa8\x8a\x3a\xea\x1b\x2b\xef\xd5\xfb\x8f\x95\xbf"
-  "\x1d\xa6\xc4\xca\x7b\x67\xfc\xbf\x8b\x95\xbf\x3d\xa2\xc0\x4a\xed"
-  "\x15\x62\x65\x23\xc3\xca\x30\xfa\x3d\xcc\x09\x11\x3f\x0a\x67\xfb"
-  "\xc0\xca\xd9\xdd\xcc\x85\x17\x7c\x61\x65\xd4\x2d\x4a\xac\x8c\x9a"
-  "\xa8\xc4\xca\xa8\x1e\x32\x56\x8a\xcf\xae\x0a\x56\x46\x0d\xbc\x3e"
-  "\x58\x19\x35\x90\x61\xe5\x79\xc4\xca\xa8\x4b\xdd\x63\xe5\xbd\x06"
-  "\xef\x58\x09\xe9\x0c\x2b\xef\x35\xc8\x58\xf9\x75\x37\x58\x79\xdf"
-  "\xd7\x7e\x60\x65\x18\xc3\x4a\xad\x0f\xac\x9c\x0d\xb4\x12\xc7\x05"
-  "\x1b\x7b\x9d\xc6\x86\x88\x95\x3a\x37\x56\x5e\xc1\xf8\xf0\xaf\xff"
-  "\xee\xf3\x29\xff\x22\x56\x0a\x26\xce\x5f\x22\x56\xd2\x70\x11\x2b"
-  "\xe7\x38\xc9\x92\xaf\x00\x23\xab\x1a\x59\x1c\x01\x66\x03\x0c\x7f"
-  "\x69\x93\x11\x8b\x26\x6b\x77\x03\xbd\x2c\xd6\x62\x86\x4d\xcc\x06"
-  "\x76\x2c\x62\x55\x31\xe4\xcd\x77\xf3\x9d\x0c\x3b\xbf\x12\xb1\x73"
-  "\x8a\x88\x9d\x53\x7f\x02\x76\x3e\x83\x7d\xf9\xbb\x73\x97\xd4\x12"
-  "\x76\xae\x03\xec\xfc\x1d\xe3\x1f\x70\x5f\x97\x63\xe7\x03\xb3\xa4"
-  "\x7a\xa1\xee\xd2\x92\xbc\x89\xf0\x7a\x5d\xbc\x1c\x47\xc7\x60\x79"
-  "\xf7\x3f\x6c\x9e\xdd\x44\xdc\x58\x3a\x45\xc6\x52\x28\x6b\x80\x6f"
-  "\x1c\x85\x34\x09\x47\xb3\x00\x47\x4f\x79\xe0\x28\xea\x0c\x10\xf3"
-  "\x00\x47\xdb\x18\x8e\x7e\x24\xe2\x68\xf4\xe2\xe3\x53\x00\x47\xc7"
-  "\x48\x38\x7a\xff\x2e\x47\xd6\x07\x7a\x47\x76\xf7\x38\xda\xc6\x70"
-  "\xd4\x78\xed\x71\xb4\xb4\x13\x8e\x82\xcc\x8a\xf1\x73\xbd\xe2\xa8"
-  "\x34\x1e\x19\x8e\x66\xca\x38\xca\xe8\x3a\xbc\x7f\x45\x02\xd0\x3d"
-  "\xc1\xc8\xe4\x36\x37\x8e\x1a\x8b\x39\x8e\x42\x1a\xb3\x77\x58\x00"
-  "\x38\x0a\xe3\x2f\xa3\x1c\x7d\x60\x91\x18\xa8\xa3\x16\xf1\x75\x2b"
-  "\xcc\x19\xa4\x91\x1b\x4f\x67\xc3\x9c\x41\x8c\x69\x86\x39\x03\x38"
-  "\x3a\xb5\x45\x4b\xd8\x7c\xc9\x86\xf9\xd2\xe8\x23\x6e\x91\x64\xcf"
-  "\xeb\x13\x4f\x87\xcf\x55\xe2\xe9\xf0\x22\x25\x9e\x0e\x7f\x4a\xc6"
-  "\x53\xf1\x19\xe2\x29\xf4\x19\xd0\x67\x14\x62\xea\x8f\xc3\xd3\xe1"
-  "\x73\xdc\x78\xaa\x16\xf1\x74\x76\xf7\x78\xca\xf6\x05\x7d\xe0\xa9"
-  "\x27\x36\xf8\xc6\xd3\xe1\x73\x64\x3c\x7d\x60\xb4\x1b\x4f\xab\x7d"
-  "\xe1\xe9\xfd\x46\xef\x78\x0a\xe9\x0c\x4f\xef\x37\xba\xf1\xb4\xda"
-  "\x0b\x9e\x8e\xf1\xc4\xd3\xff\x1c\xce\xf1\xb4\x98\xfb\xc6\x00\x4c"
-  "\xad\xb0\xc3\xf8\xc0\x39\x97\x9c\xcf\x30\x55\x00\x4c\x05\x2c\x50"
-  "\x63\x3c\x14\xb4\xbd\xf7\x86\xa9\x1c\x73\xad\xf8\x9d\xde\x38\x37"
-  "\x33\xc6\x81\xbc\x0b\x6b\x11\xd0\x84\xad\xbd\x12\xfd\xb6\x7a\xe0"
-  "\x6b\xfc\x62\x2d\xf2\x76\x8a\xb1\x22\x48\x63\xa5\xd9\x80\x36\xc6"
-  "\x8a\xb1\xe2\x5f\x5f\xfe\x67\xb4\x2f\x6c\xf5\x25\xbb\x1f\x47\xd9"
-  "\xfd\x29\xa2\x5e\xfa\x14\xe0\x6b\x1c\xca\xee\x3b\x3b\xc9\xee\x3b"
-  "\x2f\x97\xdd\xbf\xe8\x1a\x47\xfd\x92\xdd\x9f\xc6\x3e\x1c\x71\x9f"
-  "\x12\x47\x47\x0c\x57\xe2\xe8\x43\xef\x63\xbd\x38\x8e\xef\xf4\x2e"
-  "\xbb\xb3\x79\x3e\xe2\x25\xb7\xec\x5e\xad\xc4\x4f\x59\x76\x7f\x68"
-  "\xa6\x6f\x1c\x1d\x51\xac\xe0\x47\xa7\x8a\x38\x3a\x5d\xc4\xd1\xe9"
-  "\x32\x8e\x7e\x76\x42\xe2\x47\x7f\x5f\x7e\xac\xda\x13\x47\x47\xd8"
-  "\xdd\x38\x5a\x73\x39\x8e\x4a\x18\xca\xe2\x8d\x43\x39\xa8\xc3\xda"
-  "\x05\x38\xfd\xee\x74\x23\xd3\x45\xa1\x5e\x10\x75\xb0\x6e\x1d\x54"
-  "\x9b\x84\xa7\x2d\x24\x7d\x0a\xe2\x69\x3e\xc3\x53\x8d\x8a\x4c\x03"
-  "\xec\xeb\x27\xc5\x23\xdf\x92\x42\x74\x38\x17\x51\xbf\x24\x2c\xe2"
-  "\x71\xd5\x24\x3d\x13\xb4\x97\xed\xe5\x3f\xfb\xb5\x88\xa9\x18\x9b"
-  "\x36\x84\xc5\x24\x37\x6c\x4e\xf1\xc2\x9b\x2e\x05\x4c\x5d\xe2\xc1"
-  "\x9b\xc2\xdc\xff\x68\x7a\x67\x4c\x7d\x70\x5a\x05\x8e\x15\xc4\x54"
-  "\x85\x1c\xbf\xf3\x17\x20\xc7\x3f\xb8\x57\x89\xa5\x0f\x36\x29\xb1"
-  "\xf4\xc1\xd7\x65\x2c\x15\x9f\x5d\x15\xde\xf4\xc1\x92\xeb\xc3\x9b"
-  "\x3e\x58\x22\xcb\xf1\x0f\xad\x77\x63\x69\x95\x2f\x2c\x1d\x51\xe2"
-  "\x1d\x4b\x21\x9d\x61\xe9\x88\x12\x37\x96\x56\x79\x91\xe3\x15\x58"
-  "\x1a\xb3\x98\x63\xe9\x4e\xce\x9b\x56\x4b\xbc\xe9\xce\x7f\x41\x39"
-  "\x3e\x26\xd5\x5f\x39\xfe\x78\x13\xc7\x4f\xc4\x27\x09\x43\x65\x39"
-  "\x7e\xa7\x6f\x39\xbe\x1b\x0c\xf5\x8b\x17\x65\x18\xfa\xf0\x62\x25"
-  "\x86\x3e\xbc\x4c\x89\xa1\x23\xcf\x75\xc6\xd0\xcb\xf1\xf3\xe1\xfd"
-  "\xde\xb0\x93\xcb\xf1\x23\x0b\x7c\xe3\xe6\xc3\x0d\xfe\xe3\x66\x6c"
-  "\x0f\x25\x6e\x3e\x12\xf1\xef\x81\x9b\xb1\x1b\x15\xb8\xa9\xbd\x42"
-  "\xdc\xfc\x59\x64\xfa\xd8\x4e\xfa\xcf\x91\x9d\xf4\x9f\xb1\x1e\xfa"
-  "\xcf\x91\x57\x51\xff\x19\x7b\x9d\xf4\x9f\xb1\x36\x99\x07\x1d\x59"
-  "\xde\x3d\x6e\x3e\x6c\xf3\x8e\x9b\x90\xce\x70\xf3\x61\x9b\x8c\x9b"
-  "\xdd\xf1\xa0\x8f\xbe\xe7\x07\x6e\xfe\xc2\x65\xfa\x47\xbb\xd4\x7f"
-  "\x7a\x93\xe9\x11\x37\x19\x5e\x56\x77\x92\xe9\x9f\xf2\x94\xe9\x77"
-  "\xca\x32\xfd\x28\x8e\x5b\x16\xa7\x49\x29\xd3\x5f\x75\x1c\xfd\xc3"
-  "\x21\x87\x5b\x1f\xfa\x0a\xe0\xe8\x1f\x98\x6f\x74\x87\x5b\x1f\x3a"
-  "\x66\xb4\x54\x2f\x2e\xd3\xaf\x23\xbc\x5e\x5e\x64\x7a\x66\x3b\xfc"
-  "\x58\x7f\xb7\x4c\x5f\xdd\x59\xa6\x1f\x7d\xc9\x37\xa6\x3e\x36\xc2"
-  "\xab\x4c\x8f\xf2\x37\xc3\x54\x23\xc3\xd4\xd6\x0d\x9e\x98\x3a\x6a"
-  "\x32\xc3\xd4\x3f\x48\x98\xfa\x58\xa6\x03\xe6\xa6\xa3\x67\xf7\x98"
-  "\x8a\xe5\xc8\x98\x9a\xf8\xf3\x60\xaa\xf9\xca\x31\xd5\xf3\x3c\xec"
-  "\x47\xd0\x76\x37\xa6\x32\x1a\x8f\x6a\xa9\x48\x40\x4c\x4d\xec\x24"
-  "\xdf\xef\xf4\x2e\xdf\x1f\x23\x6a\xa4\x8f\x24\xdf\x63\x1f\x30\xbc"
-  "\xb9\xa6\xf2\xfd\xe8\x71\x4a\x6c\x1d\x9d\xa9\xc4\xd6\xd1\xf7\xc9"
-  "\xd8\x2a\x3e\xbb\x2a\xf2\xfd\xe8\xb1\xd7\x47\xbe\x1f\x3d\x56\xc6"
-  "\xd6\x31\x77\x75\x8f\xad\x8f\x8d\xf4\x8e\xad\x90\xce\xb0\xf5\xb1"
-  "\x91\x5d\x62\xeb\x1f\x3c\xb1\xf5\xf1\x01\x12\xb6\xca\xf2\x3d\x8c"
-  "\x0f\x9c\x7f\xc9\xa6\x1f\x2f\xdf\x8f\xbe\xde\xf2\xfd\xe3\x3a\xbf"
-  "\xe4\xfb\x0d\x80\xb3\x20\x8b\x2f\xfd\x1c\xe4\xfb\x27\x44\xf9\xbe"
-  "\xa6\xa8\x93\x7c\x5f\x74\x99\x7c\x9f\xf6\x84\x88\xa9\x30\xa7\x18"
-  "\xa6\x4e\xdf\xf9\xe3\xe5\xfb\x27\xb1\x0f\xc7\xf6\x57\x62\xea\xd8"
-  "\x01\x4a\x4c\x9d\xf0\x26\xd6\x8b\x63\x7a\x91\x77\xf9\x9e\xcd\xf3"
-  "\xb1\x33\x15\xf2\x3d\xd4\xef\x72\xf9\x7e\xc2\x64\x05\xa6\x4e\xf5"
-  "\xc4\xd4\xb1\x26\x05\x9f\x0a\xed\x42\x4c\x7d\xf3\x14\xc7\xd4\xb7"
-  "\x4e\x79\x60\xea\xf8\xb7\x44\x4c\x1d\x77\xe8\xd8\x24\x4f\x4c\x1d"
-  "\x5b\x25\x61\x2a\xc3\xcb\xa9\x0e\x75\x46\x9c\x6f\x7b\x93\x5d\x50"
-  "\x36\x9e\x15\xc3\x32\xdf\x39\x95\xd8\xbd\xbd\x49\x9c\xd2\xde\xc4"
-  "\x6d\x6b\x92\x6c\x25\x65\x75\x26\x66\x6b\x52\x90\x42\xc2\x34\xcb"
-  "\xc9\x6d\x05\xed\xdc\x0f\x01\xf3\x81\xd8\xea\xdd\x07\xc1\xb3\x93"
-  "\x65\x9c\x45\x3f\x04\x80\xb1\x86\x4d\xad\xdc\xf6\x07\xfa\xfb\x72"
-  "\xbf\x03\x12\xdf\x04\x78\xb0\xf7\x54\x67\x9c\x1d\xff\x54\x05\x8e"
-  "\x9f\x29\x89\x9d\x64\xfe\xa2\x5f\x80\xcc\x3f\xfe\x1d\x25\xbe\x8e"
-  "\xb7\x2a\xf1\x75\xfc\x7a\x19\x5f\xc5\x67\x57\x85\x77\x1d\xbf\xeb"
-  "\xfa\xf0\xae\xe3\x77\xc9\x32\xff\x84\x97\xdd\xf8\x5a\xe9\x81\xaf"
-  "\xa7\x3c\xf1\x75\x6c\x3e\xc3\xd7\x53\x9d\xf1\x15\xd2\x19\xbe\x8e"
-  "\xcd\x77\xe3\x6b\x65\x27\x99\xff\x54\x67\x7c\x9d\x38\x97\xe1\x6b"
-  "\x4d\x51\x27\xde\xb5\xa8\x7b\x99\xbf\xe6\x97\x26\xf3\x4f\x9c\xe3"
-  "\x97\xcc\x8f\x98\x3a\x87\x63\x2a\x62\x96\x84\xab\xb2\xcc\x5f\xe4"
-  "\x53\xe6\xef\x0e\x57\xfd\xe2\x55\x19\xae\x3e\x31\x57\x89\xab\x4f"
-  "\xcc\x57\xe2\xea\xa4\x96\xce\xb8\x7a\x39\xa6\x3e\xf1\x9e\x37\x3c"
-  "\xe5\x32\xff\xa4\x6d\xbe\xb1\xf4\x89\x1a\xff\xb1\xf4\x8f\x7d\x95"
-  "\x58\xfa\xa4\xfe\xdf\x17\x4b\xff\xf8\xba\x02\x4b\xb5\x57\x88\xa5"
-  "\x3f\x8b\x1e\xe0\x8f\x97\x94\x58\x3a\x29\x42\x89\xa5\x7f\x3c\x2d"
-  "\x63\xa9\xf8\xec\xaa\x60\xe9\x1f\x1d\xd7\x07\x4b\xff\xe8\x90\x79"
-  "\xd5\x49\x5f\x74\x8f\xa5\x4f\xd4\x79\xc7\x52\x48\x67\x58\xfa\x44"
-  "\x9d\x8c\xa5\x5f\x77\x83\xa5\x4f\xed\xf5\x03\x4b\x95\x7a\x80\xce"
-  "\x58\x7a\xdd\xf5\x00\x4f\xf9\x3c\xff\xe0\x55\x0f\x20\x61\xe9\x13"
-  "\x97\xeb\x01\x10\x5f\x99\x1e\x00\xe8\x25\x61\x18\xd3\x03\x8c\xe4"
-  "\x58\x66\x71\xe6\x28\xf4\x00\x57\x1f\x5b\x9f\x3e\xe6\x70\xeb\x53"
-  "\xb3\x00\x5b\x9f\x66\x71\xc3\x1c\x6e\x7d\xea\x33\x33\xa5\x7a\x71"
-  "\x3d\xc0\x2b\x84\xd7\xcb\x8b\x1e\xe0\x11\x2c\xef\x4f\xb7\x28\xf4"
-  "\x00\x1e\x58\x0b\x65\xf5\xf7\x8d\xb3\x7f\x1a\xa9\xd0\x03\xd4\xca"
-  "\x38\xdb\x8a\x36\xe9\x80\x83\x0c\x67\xc3\x3d\x71\x36\x6e\x21\xc3"
-  "\xd9\x47\x24\x9c\xfd\x53\x4e\x1b\xcc\xcd\x36\x7f\x71\x16\x6d\xa4"
-  "\x4f\x25\x5c\x1f\x9c\x2d\xf1\x03\x67\x3d\x74\x03\x7b\x81\x1e\x6e"
-  "\x9c\x65\x74\x9f\x1c\x52\x31\x05\x71\x36\xa1\x93\x6e\xa0\xc8\xbb"
-  "\x6e\xe0\xc8\xf5\xd0\x0d\x4c\x9e\xa5\xc4\xdb\xc9\x05\x4a\xbc\x9d"
-  "\xfc\x84\x8c\xb7\xe2\xb3\xab\xa2\x1b\x98\x9c\x78\x7d\x74\x03\x93"
-  "\x13\x65\xbc\x7d\xe6\xd1\xee\xf1\xf6\x4f\x63\xbd\xe3\x2d\xa4\x33"
-  "\xbc\xfd\xd3\xd8\x2e\xf1\xf6\x11\x4f\xbc\xfd\xf3\x7d\x12\xde\xca"
-  "\xba\x81\x22\x51\x37\x90\xd3\xbd\x6e\xa0\xc6\x87\x6e\xe0\xd1\xeb"
-  "\xad\x1b\xf8\x73\x94\x3f\xba\x81\x4b\x1b\xb8\xdd\xfe\x52\xb4\xdb"
-  "\x7f\x16\xf0\x77\xe2\x09\xa0\x41\xf7\x76\xfb\x69\x92\xfd\x69\x42"
-  "\xbe\x88\xb3\xf9\x5e\x75\x03\xc7\x1b\x7c\xeb\x06\x8e\x57\x79\xda"
-  "\x9f\x4e\x19\xa6\xdc\xb7\x9a\x72\x9f\xb4\x6f\x75\xfc\x4b\xc4\xd9"
-  "\x04\xe6\xc7\x4f\xc8\x4b\x88\xe1\xfe\x0d\x13\x46\x60\x3d\xbd\xd9"
-  "\xf1\x7f\x24\x78\xee\x65\x4d\x59\xeb\xd6\x15\x54\x22\xde\xe6\x13"
-  "\x81\x26\xf6\x44\xbf\xe0\x4c\x57\xf0\x34\x8e\xbd\xf8\x73\x9e\xb8"
-  "\x7b\xe0\xa4\x27\xee\x4e\xd9\x27\xe1\xae\x0b\x70\x77\x7f\x6d\x3e"
-  "\xd7\xbf\x3e\xc3\x6d\x53\x77\x3d\xe3\x61\x9b\x7a\xe2\x13\x11\x77"
-  "\x9f\xdd\x7b\xcc\x0a\xed\xef\xca\x7e\x0a\xde\xdf\x7d\xf2\x4a\x6d"
-  "\x50\xf3\xbd\xda\x4e\x89\xf8\xe4\xd5\x7e\x0a\xea\xaa\xdd\x22\xce"
-  "\x55\x17\xcc\xd3\x2d\x1e\xf6\x53\x05\x4b\x60\x3e\x8b\x67\xaf\xba"
-  "\xb4\x43\x7d\x46\xb6\x43\xa5\x79\xf1\x69\xb8\xbe\x09\xeb\x13\x62"
-  "\xda\x69\x62\x00\x0d\x8b\x4f\xc3\xef\x77\x74\xc0\xba\x13\x1b\x17"
-  "\x20\xca\x75\x09\x80\x3d\xfd\x38\xdd\x9f\xb5\xbb\x60\xad\x71\xc1"
-  "\x5a\x23\xe4\xc5\x27\x38\x91\x37\xd9\x10\x3f\xa3\x00\xe4\x3c\x67"
-  "\x16\x8b\x43\xd8\x3b\x17\x64\xbd\xad\x28\xe7\x9d\x87\xb9\x91\x61"
-  "\x50\x63\x7d\x24\x1c\xd5\x34\x40\x3b\xce\x77\xcd\xcb\x39\x2f\xc8"
-  "\x38\x6a\x1e\x73\x1c\xbe\x39\xf5\x6c\x05\x8e\xdd\x38\xf9\x4c\x01"
-  "\xe3\x99\x7d\xd8\xca\x62\x5d\xb8\xff\x46\x18\x0b\x57\x41\x27\xe1"
-  "\x59\x1f\x25\xae\xc7\x3f\xac\xc4\xf5\xf8\x64\x25\xae\xc7\xdf\x25"
-  "\xe3\xba\xf8\x0c\x70\x1d\xfa\x8d\xf1\xd1\xb0\xf6\xfd\x48\x3e\x3a"
-  "\x3e\x46\xc2\x75\x41\xc4\xf5\xc2\x2b\xc0\xf5\x2e\xf9\x68\x0f\x5c"
-  "\xf2\x8d\xeb\xf1\x31\xb2\x4e\x22\xe1\x16\xaf\x36\xb2\x27\x3d\x71"
-  "\x7d\x4a\x29\xc3\xf5\x93\x9d\x71\x1d\xd2\x19\xae\x4f\x29\xf5\x79"
-  "\x9e\xe0\x64\xe7\xfd\xb4\x69\x2a\x86\xeb\xd5\xa2\x8d\x6c\xa5\x1f"
-  "\xe7\x09\xaa\x39\xa6\x4b\x58\x8e\xfa\xaa\xeb\xab\x93\xc0\x30\xe0"
-  "\x57\xae\x93\x60\x58\xde\xc4\xb1\x1c\xb1\x51\xc2\xf3\x2b\x39\x4f"
-  "\xd0\x1d\x9e\x4b\x7c\x33\xe2\xb9\x2f\xbe\x59\x89\xe7\xd3\x55\x4a"
-  "\x3c\x9f\xde\x43\x89\xe7\xcf\xab\x94\x78\xfe\x3c\xe9\x8c\xe7\x97"
-  "\x63\xf9\xf4\xa7\xbc\xe1\xb8\xf1\x69\xd4\x51\xcc\x2c\xf6\x8d\xe1"
-  "\xd3\x33\xfd\xc7\xf0\xe7\x96\xfd\xdb\x61\xb8\xb6\x33\x86\x3f\x57"
-  "\x82\x18\xe4\xca\xee\x84\xe1\xb3\x45\x0c\x17\x71\x64\x6b\xa3\xc8"
-  "\x0b\x77\xc6\xf0\x26\x68\x47\x37\xf2\xb8\xf3\xfb\xce\x18\x3e\xe3"
-  "\x1d\x05\x86\x6b\xbb\xc1\xf0\xd9\x5c\x0f\xa2\xb0\xcb\xf5\xa1\x0b"
-  "\x81\x76\x54\x6d\xf1\xc1\x9b\x4b\x34\xf3\xac\x8f\x12\xc3\x67\xf6"
-  "\x50\x62\xf8\xcc\x68\x25\x86\xcf\x38\x27\x63\xb8\xf8\xec\xaa\xf0"
-  "\xe6\x33\x03\xaf\x3a\x6f\x2e\x8d\x8f\x2e\x31\x7c\x66\xa0\xcc\x9b"
-  "\xcf\x3c\xdd\x3d\x86\x4f\xcf\xf1\x8e\xe1\x90\xce\x30\x7c\x7a\x8e"
-  "\xcf\x73\x0e\x97\x61\xf8\xf3\x87\xfc\xc0\x70\xa5\x2e\x44\xc2\x70"
-  "\x51\x17\xb2\xd5\x43\x17\xe2\xca\xe2\xba\x90\x2d\x8d\x7c\x6c\xf4"
-  "\x53\xf1\x71\x0a\xe3\x47\x57\xa8\xee\x5a\x76\xdb\xf2\xa3\xf4\x20"
-  "\xcf\x9b\xfd\xd1\x83\x30\xfc\xc6\x33\x0e\x93\x01\xb7\x2b\xaf\xf0"
-  "\x8c\xc3\x28\xe9\x8c\x83\xc9\xc7\x19\x07\x11\xcf\xa7\xfe\x04\x3c"
-  "\x67\x67\x1c\xfe\xf2\xb9\x52\xc7\xfc\x97\x2f\x24\x1d\x33\xc7\xf3"
-  "\x17\xce\x28\xf1\xfc\x85\x3a\xf7\x99\x07\xc0\x7c\x8b\x71\xdd\x65"
-  "\x67\x1e\xdc\xd8\xce\xf4\xa0\x89\xf7\x99\x9f\xae\x23\x6e\x7c\x9f"
-  "\x22\xe3\x3b\x94\xb5\x5e\x81\xed\xb5\x9e\xd8\x9e\x38\x45\x81\xed"
-  "\xa7\xf2\x95\xf6\x11\xb5\x46\x0f\x6c\x97\xce\x3c\xcc\x9a\x7c\xac"
-  "\xa6\x1b\x6c\x87\xf7\xaf\xfc\x8c\xd8\xd5\xc5\x76\xe9\x7c\x83\x57"
-  "\x6c\xf7\x3c\xdf\xe0\x61\xff\x80\xd8\xce\xe2\x69\xf4\xef\x84\xed"
-  "\x4b\x13\xd5\xae\xc3\x30\x1f\x00\xd7\x71\x8e\xb8\x28\x60\x3b\xa3"
-  "\xf7\xac\x3c\x4f\x6c\xef\xc8\xe2\xd8\xbe\xb9\xf1\xa7\x63\xbb\x9b"
-  "\x1f\xf6\xc4\xf6\x3f\x20\xb6\xcf\x5e\xcb\xcf\x5f\x64\x5e\xd9\xf9"
-  "\x8b\x4e\xf6\x19\x9b\xaf\x40\xff\xd2\x25\xc6\x7b\xa9\x97\x12\xe3"
-  "\x67\x9f\x55\x62\xfc\x0b\x03\x95\x18\x3f\xfb\x73\x19\xe3\xc5\x67"
-  "\x57\x85\x4f\x9f\xdd\x70\x7d\xf4\x2f\xb3\x1b\x64\x8c\x7f\xe1\x48"
-  "\xf7\x67\x2f\x12\x67\x78\xb7\xcd\x80\x74\x86\xf1\x89\x33\xba\x3c"
-  "\x7b\xa1\xd0\x77\xcf\x79\xdf\xeb\xd9\x8b\xca\x9f\xcf\x36\xc3\x73"
-  "\xac\x74\xd6\xbf\xfc\x78\xdd\xf7\x9c\x3d\xfe\xea\x5f\xf0\xec\xc5"
-  "\xd2\x2f\x3c\xce\x5e\xd4\x74\x7f\xf6\x22\xed\xa9\x2b\xd4\xbf\x74"
-  "\x61\x9b\x71\x7c\xa2\xa7\xbd\xdb\xdc\xf7\x94\xf8\x3e\xf7\x7d\x37"
-  "\xbe\x3f\x89\xf8\x3e\xff\x98\x12\xdf\xe7\x1f\xc5\x7a\x7a\x3b\x8b"
-  "\xf1\x91\x62\x5f\x71\x5e\x88\xd2\x56\xa3\x93\xfe\xe5\x49\x1c\x7b"
-  "\xf3\x17\x2b\xf0\xfd\x94\x27\xbe\xcf\x1b\xe1\x8d\x77\x47\xbd\x37"
-  "\xb3\x29\x9e\xea\x71\xa6\x6d\xbc\x64\xff\xf6\xe2\xa3\xc7\xe2\xa0"
-  "\xfd\x56\x1f\xb6\x6e\x53\xb9\xad\x1b\xb3\x6d\x43\x3d\x38\x94\xf5"
-  "\xee\x54\xa3\x3a\x3d\x81\x0a\x68\xeb\xd6\xd9\xce\x0d\x6d\xdf\xd0"
-  "\xd6\xad\x3c\xd1\xe4\xd3\xce\x0d\xc7\xa6\x2f\x5b\x37\xa8\x77\x18"
-  "\xc3\xfa\xd3\x22\xd6\x8b\xb6\x6e\x05\x29\xb2\xad\x9b\x02\xeb\xbd"
-  "\xd8\x0f\xef\x3d\x95\xe9\x9d\x8f\xcf\x90\xb1\xbe\x1d\xf9\xf8\xff"
-  "\xec\xa4\x8b\x61\x7d\xf0\x62\xe6\xcf\xaa\x8b\x61\x58\x6f\x5c\x58"
-  "\x81\xe3\x78\x8a\xd1\x8b\x2e\xe6\x72\x1b\xe7\x9f\x4f\x17\x63\x2c"
-  "\x57\x62\xfc\x7c\xa2\xc4\x78\xe3\xfb\x32\xc6\x8b\xcf\xae\x0a\xc6"
-  "\x1b\xcb\xae\x8f\x2e\xc6\x58\x26\xeb\x62\xe6\xbf\xe9\xd5\xfe\x4e"
-  "\xa1\x63\x9f\x37\xd2\xbb\x8e\x7d\x9e\x68\x7f\x37\x6f\xa4\xcf\x33"
-  "\x21\x97\xed\x69\x26\xad\xe6\x3a\xf6\x1f\x71\x26\xa4\xe6\x97\xa6"
-  "\x8b\x49\xf2\xe9\xff\xcb\x97\x2e\x86\xd9\x36\x7f\x81\xf6\x21\xfe"
-  "\x9d\x09\xe9\x0e\xdb\xdd\xbc\x7b\x17\x7b\x98\x4a\x6c\x5f\xb0\x5a"
-  "\x89\xed\x0b\xd6\x2a\xb1\x7d\xd1\x46\x25\xb6\x2f\xca\xef\x8c\xed"
-  "\x97\xe3\xfa\x82\xd3\xde\x30\xdd\xf8\x24\xea\x62\x16\x8d\xf2\x8d"
-  "\xe7\xc9\xc1\xfe\xe3\xf9\xc2\xfe\xff\xd6\x78\xae\xed\x8c\xe7\x0b"
-  "\x27\xfe\xac\x7a\x19\x86\xe7\x29\x8f\x2a\xf0\x5c\xdb\x0d\x9e\xff"
-  "\x6c\x7a\x99\x94\x2d\x4a\x3c\x4f\xa9\x54\xe2\x79\xca\x4b\x32\x9e"
-  "\x8b\xcf\xae\x8a\x5e\x26\xa5\xe0\xfa\xe8\x65\x52\x0a\x64\x9e\x7d"
-  "\xd1\xe2\xee\xf1\x3c\x39\xcc\x3b\x9e\x43\x3a\xc3\xf3\xe4\x30\x9f"
-  "\xf6\xd4\x97\xe1\x79\xea\x64\x3f\xf0\xdc\xab\x8d\xca\x2f\x43\x2f"
-  "\x93\xea\x33\xfe\xa5\x2f\xbd\x8c\xaf\x73\x2a\x88\xef\xb2\x7d\x8a"
-  "\xc7\x39\x95\x18\xe9\x9c\x4a\xa6\xd2\x3e\xe5\xaa\x63\xfb\xe2\x59"
-  "\x4a\x6c\x5f\x3c\x57\x89\xed\xcb\x5e\x56\x62\xfb\xb2\x1c\xa9\x9e"
-  "\x5c\x2f\x93\x75\xd9\xb9\x15\x25\xce\x2f\x2e\x37\x3f\x59\x47\xbc"
-  "\x61\x3d\x94\x35\xdc\x37\xce\x2f\xb6\xfb\xc2\x79\xb4\x57\x79\x7b"
-  "\x6a\xa2\x17\x9c\x5f\xe2\xfa\x7f\x01\xe7\x7d\xd9\xa1\x30\x39\x08"
-  "\x30\x1e\xf1\x9e\xe1\xbb\x88\xf5\x88\xf3\xae\x8f\xbd\xe9\x68\x96"
-  "\x46\x5f\x2b\x9c\xf7\xad\xa3\x49\xbb\xaf\x62\x8a\x88\xf3\x57\x72"
-  "\x86\xe6\x90\x52\x47\x53\x30\xfb\x5a\xeb\x68\xd2\x56\x2b\xf1\x3e"
-  "\xcd\xac\xc4\xfb\xb4\x85\x32\xde\x8b\xcf\xae\x0a\xff\x9e\xb6\xea"
-  "\xfa\xe8\x68\xd2\x56\xc9\x78\xbf\x6c\x56\xf7\x78\xbf\xd8\xe9\x1d"
-  "\xef\x17\x8b\xbe\xd9\x16\x3b\xaf\x1c\xef\xd3\xdd\x78\x7f\xf9\xf9"
-  "\x99\xcc\x1f\x6f\x23\xf3\xf0\xf5\xd6\xd1\xa4\xfb\xc4\xff\xae\xfc"
-  "\x63\xfc\x78\x1d\x8d\x78\x26\x71\xba\x77\xff\x18\xc7\xba\xb0\x91"
-  "\x39\x56\xe6\x89\xf5\x19\x4f\x29\x6d\x11\x33\x26\x4b\xb6\x88\xc7"
-  "\x2a\x10\xeb\x57\x2c\x57\x62\xfd\x8a\x4c\x5f\x3a\x9a\xbd\x82\xa7"
-  "\x4d\x62\xc6\xfb\x4a\x1d\x4d\x91\x52\x47\x33\x1e\xc7\xde\x8a\x61"
-  "\xbe\xb1\x1e\x10\x5b\x61\x03\xce\xcf\x28\xbe\x39\x55\xb4\x01\x9f"
-  "\xea\x61\x03\x3e\xe6\xbf\x44\xac\xcf\x74\x1d\xad\x74\x12\x7f\xec"
-  "\x10\x7f\xba\xad\x77\x8e\x57\x1b\x44\xb6\x06\x74\x61\x87\x18\xff"
-  "\x95\x16\x6d\x9a\x0d\x85\x29\x1e\x76\x88\x80\xff\x9b\xd4\x9d\xfc"
-  "\x17\x7b\xb3\x43\x9c\x6a\xf4\x89\xff\x97\xa8\x8c\xff\xc2\xfd\xb2"
-  "\xde\x46\x40\x3e\x9f\xf5\xcb\xf2\xe8\x6b\xa5\xb7\xf1\xa6\x27\x31"
-  "\x3f\x82\xf8\x9f\x35\x94\xf3\xf9\x89\xbf\x30\xbd\x4d\xd6\x4b\x4a"
-  "\xdc\xcf\x2a\x51\xe2\x7e\xd6\x5c\x19\xf7\xc5\x67\x57\xc5\x16\x3d"
-  "\x6b\xe5\xf5\xe1\xf3\xb3\x56\xca\x7a\x9b\x15\xd3\xba\xc7\xfd\x8c"
-  "\x06\xef\xb8\x9f\xd1\xc0\x71\x3f\xa3\xa1\x4b\xbd\x8d\xc2\x36\x72"
-  "\xe5\xa3\x3f\x59\x6f\x23\xf1\xf9\xd7\xfd\x5c\xcf\xca\x91\xfe\xe8"
-  "\x6d\xdc\x67\xd2\x7f\x92\xde\xc6\x3b\xde\x4b\xbc\xfd\xb1\x2e\xf6"
-  "\x5c\x95\x78\xff\xd2\xa3\x4a\xbc\x7f\x69\xb4\x12\xef\x5f\x9e\xa9"
-  "\xc4\xfb\x97\x67\x78\xd3\xdb\x28\xb1\xfe\xa5\x8d\xde\x70\xde\x38"
-  "\x1e\xf5\x36\x2f\x87\xf9\xc6\xf8\x97\x4a\xfd\xc7\xf8\xec\xd3\xff"
-  "\x1f\xe3\x3b\x61\xbc\xb6\x33\xc6\xff\x9f\x81\x3f\x2b\x8f\xcf\x30"
-  "\x3e\x27\x44\x81\xf1\x57\x51\x97\x73\x25\xe7\x49\x7c\xf3\xf6\x39"
-  "\x9d\xec\xdf\x73\x3a\xd9\xbf\xe7\x78\xd8\xbf\xe7\x14\x5c\x3d\x8c"
-  "\xcf\xb9\xfa\xf6\xef\x57\x84\xf1\x39\x1e\xf6\xef\x2f\x3f\xda\x3d"
-  "\xc6\xbf\x54\xe6\x1d\xe3\x21\x9d\x61\xfc\x4b\x65\x5d\xf2\xf6\x0a"
-  "\x8c\x7f\xe5\xae\x6b\xa1\xcb\xb9\x3e\xe7\x8d\x5e\x31\xf8\xa3\xcf"
-  "\xe9\xca\xef\x88\x4f\x7d\x4e\xb4\xa4\xcf\x31\xfa\xd0\xe7\x5c\x2d"
-  "\xcc\x7f\x75\xb8\x12\xf3\x5f\xfd\xbd\x12\xf3\xd7\xcc\x55\x62\xfe"
-  "\x9a\x39\x4a\x7d\x4e\xd2\x65\xfa\x1c\x25\xfe\xbf\xba\xc5\x3c\xde"
-  "\x53\x9f\x53\xe4\xa1\xcf\x59\x73\x8b\x6f\xfc\x7f\xd5\x27\xfe\xb7"
-  "\x32\xfc\x4f\xf0\x82\xff\xab\xfe\x4d\xf0\x3f\xe1\x27\xe0\xff\xea"
-  "\xeb\x80\xff\xb9\x03\xb8\x8e\xe7\x0a\xfd\xa4\xec\xf5\x5f\xc7\xf3"
-  "\xd3\xd6\x81\xdc\xf9\xca\x75\x20\x77\x9b\x72\x1d\xc8\x9d\x2c\xaf"
-  "\x03\xe2\xb3\xab\xb2\x0e\xe4\x1a\xaf\xcf\x3a\x90\x6b\x94\xd7\x81"
-  "\x35\xe3\xba\x5f\x07\x5e\xf5\xb1\x0e\xbc\x2a\xae\x03\xaf\xfa\xb1"
-  "\x0e\x98\x7e\xef\x5b\xc7\x63\xfc\xf1\x3a\x9e\xe1\xd7\xfb\x1c\x94"
-  "\x69\x84\x5f\x3a\x9e\x0d\xd3\x22\xcb\xd0\x47\xca\x69\xa2\x5e\x3a"
-  "\x4d\xd2\xf1\x98\x3b\xe9\x78\xcc\x97\xe9\x78\x16\x9f\x16\xf1\x7f"
-  "\xac\x78\xde\x74\xfc\x4f\xf0\x91\xc2\x62\x49\xaf\x1d\xae\xb4\x9b"
-  "\x5f\xcb\xf0\x5f\xf6\xdf\x97\x77\x0c\xeb\xc5\xd7\x1f\x73\x17\x3e"
-  "\x50\xd7\xbe\xac\xd0\xe9\x8c\xf5\xe6\x23\x25\x4f\x61\x77\xa3\x3c"
-  "\x6f\xba\x76\x8f\x02\xef\xc7\xf3\xf3\xa6\x6f\x79\xdb\xa7\x75\xfb"
-  "\xe4\x5f\x77\x84\xf9\xe4\x77\xfb\xf2\x5b\xeb\xb8\x22\x5f\xd2\x53"
-  "\x45\x5f\xd2\xa7\xae\x83\x2f\xe9\x2b\xf5\xc9\x7f\xaa\xb3\xff\xbe"
-  "\xd7\xa6\x59\xca\xcc\xa4\x02\xc7\xc8\x94\xce\xbe\x4f\xcd\xde\xcf"
-  "\xee\xab\xc5\xb3\xfb\xf3\xae\x8d\x1f\x14\xac\x0f\x5b\xf3\x43\xdf"
-  "\x8e\x79\x27\xdd\xc6\xea\x83\x71\xbb\xa1\xae\x67\xca\x60\xac\x0a"
-  "\x88\xa7\x49\x88\xa7\x79\x3a\x96\xf7\x34\x8c\x85\xd0\xe8\x68\x1c"
-  "\xc7\xb9\x02\x09\x36\xa6\x20\xb6\xbe\xc6\xec\xbe\x80\x8d\x00\x6c"
-  "\xe5\xf9\x96\x9d\xa6\x2e\x57\x68\x4c\x34\xd4\xbf\xd7\xee\x79\x95"
-  "\x3d\x2a\xac\x76\x98\x17\x8d\x2c\x8e\xab\xc5\xd9\x66\xc6\xbe\x38"
-  "\x30\xaf\x32\x90\x02\xfe\x6e\x7d\x9e\x04\xf9\x37\x4f\x5f\x63\x71"
-  "\xea\xd9\xd9\xf5\xd0\xb7\xc7\xa2\x1f\x10\x89\xb7\x12\x2e\xc8\xfa"
-  "\xad\x2d\x40\x1f\x81\xf2\xb5\x2f\x7e\x16\xc7\x0d\xf8\x9e\x01\x68"
-  "\xc9\x6c\x6c\x11\x37\x58\xec\x2a\xc0\x8d\xc2\x8b\xf2\x3e\x36\x96"
-  "\x8f\x34\xe2\x7a\x94\x3c\xd9\xfe\xc5\xea\x0b\x5b\xd7\xee\xf3\x8e"
-  "\xad\x6b\xf7\x71\x6c\x5d\xbb\xcf\x8d\xad\x56\x2f\x7a\x14\x85\x1d"
-  "\xfb\x7a\xd1\xfe\xc5\xdc\x89\xc7\x36\xff\x0b\xfa\x47\x59\xef\x97"
-  "\xfd\x0b\xc3\xd3\x39\x1c\x4f\x11\xaf\x24\x4c\x95\xf5\x28\x66\x9f"
-  "\x7a\x94\xee\x30\xd5\xaf\x33\xfc\x0c\x53\x37\xac\x56\x62\xea\x86"
-  "\xb5\x4a\x4c\xdd\x14\xd2\x19\x53\x2f\xc7\xd3\x0d\x9f\x7b\xc3\x52"
-  "\xee\x1f\x65\xa3\xd9\x37\x8e\x6e\x70\xfa\xc2\x51\x66\x9f\x3e\xd5"
-  "\xc3\x3e\xdd\x8d\xa3\xf9\x7d\x95\x38\xfa\xd7\x98\x2b\xc5\x51\x16"
-  "\xdb\xe4\xd4\xcf\x10\xdb\xe4\x47\xe3\xa8\xb1\x13\x8e\xe6\xbf\x29"
-  "\xe3\x68\xe7\xf8\x26\xdd\xe0\xe8\xec\x6b\xe3\x03\x45\x81\xa3\x82"
-  "\x8d\xd5\x47\x3f\x0f\xeb\xba\x71\xa8\x12\x47\x37\x26\xf8\xc6\xd1"
-  "\x7c\x97\x8c\xa3\x3c\xdf\xb5\xc5\xd1\x8d\x11\x0a\x1c\x9d\xed\x81"
-  "\xa3\xdf\xcb\x32\x04\xda\x58\xb8\x71\x74\xae\x07\x8e\xce\xee\x0e"
-  "\x47\x37\x46\x20\x8d\x38\x8f\xba\xf1\x87\xee\x71\xf4\xaf\x81\xde"
-  "\x71\x14\xd2\x19\x8e\xfe\x35\x50\xc6\x51\x2f\x3c\xaa\x02\x47\x37"
-  "\x7d\xe1\x07\x8e\xfe\xc2\x7d\xa3\x6c\xaa\xf2\x4b\x57\x21\x9f\xe9"
-  "\xbc\xdc\x47\xea\xb3\x9e\x67\x82\x4a\x3a\xc5\x3d\x29\xb9\x2c\xee"
-  "\xc9\x62\xe9\x8c\xe7\x28\x11\x57\xc7\xfc\x04\x5c\x65\x67\x3c\x37"
-  "\x9f\x51\xda\x9e\x6c\x3e\x2b\xd9\x9e\x70\x5c\xdd\xba\x4c\xaa\x97"
-  "\x1c\xf7\xa4\xa4\x0b\x1f\xa9\x05\xc3\x15\xbe\x51\x46\x79\xfa\x46"
-  "\xd9\x3a\xd4\xb7\x8f\xd4\x82\x04\x85\x6f\x94\xe3\x3b\xdd\x71\x4f"
-  "\x3a\xfb\x48\x95\x31\x76\xcb\x7c\x86\xb1\x6e\x1f\x54\x05\xdb\xdc"
-  "\x3e\x52\xbb\x39\x17\x84\xe5\xec\xae\x4d\xbc\xf6\x18\x6b\xf6\x03"
-  "\x63\x15\x71\x4f\x3a\xfb\x98\x2a\xec\x6f\x39\x5a\x42\x2a\x12\x4a"
-  "\xbc\xf8\x46\x2d\xb9\xae\xb1\x4f\xb0\x5e\xde\xb1\xb6\x70\xa3\x12"
-  "\x6b\x0b\xcb\x58\xde\xaf\xbd\x61\x6d\xe1\x2c\x19\x6b\x79\xbe\x65"
-  "\x5f\x77\xc2\xda\x1a\x1f\x58\x0b\xeb\xea\xd6\x7a\x7f\xb1\xb6\x90"
-  "\xc5\xcd\x16\xb2\x44\xac\x6d\xbc\xda\x58\x5b\x98\x2f\x63\xed\xd6"
-  "\x67\xbb\x8f\x31\x55\x90\xe8\xfd\x5c\x4e\x41\x22\xc7\xda\x82\xc4"
-  "\x2e\x63\x4c\x29\x6c\x3e\x8a\xc6\x49\x31\xa6\x64\x7d\x40\x89\xa8"
-  "\x0f\xf8\x57\x8e\x89\x52\x34\xd6\x5f\x7d\xc0\x67\x20\xbb\xe3\xb9"
-  "\xcb\xa5\x18\x73\x6a\x0a\xc6\x44\x29\xee\xa4\x0f\x28\xbe\x5c\x1f"
-  "\x30\xb9\x6b\x8c\xf5\x4b\x1f\xc0\xce\x5d\xbe\x3e\x5a\x89\xb1\xaf"
-  "\x8f\x53\x62\xec\xb6\x33\xd2\x39\x4b\xac\x8f\x6f\x9f\xa9\xaf\x6f"
-  "\x74\xeb\x03\x6a\x94\xd8\x2a\xeb\x03\xb6\xad\xf7\x8d\xb1\xaf\x2b"
-  "\xf5\xbf\x63\x76\x2a\xce\x59\xbe\x55\xeb\xe9\x87\x5a\xf2\x3f\xf5"
-  "\x5f\xa7\x8f\x55\x79\x62\xec\x7f\x05\xfd\x2b\xf9\xa1\x76\xfb\x9a"
-  "\xea\xc6\x96\xfb\x72\x3f\xd4\xff\xbd\xcc\x72\xb4\x98\xe0\xd9\x36"
-  "\x86\xb7\x0a\xdd\x40\xf1\xf5\xd1\x0d\x1c\x2d\xf6\xa1\x1b\xd8\xa6"
-  "\x52\xe2\xec\xb6\x28\x96\xf7\x2b\x6f\x38\xfb\xdf\x9f\xcb\x38\xcb"
-  "\xf3\x2d\xfb\xaa\x13\xce\x56\x5f\x4d\x9e\x16\x55\xbb\xd7\x52\x37"
-  "\xb0\x8d\xc8\xba\x81\x6d\x57\x70\xfe\xf1\xf5\x32\xef\x38\xfb\xba"
-  "\xa8\x77\x7d\x5d\xd6\xbb\x56\x7b\x89\x97\xa2\xc0\xd9\xed\x6f\x4a"
-  "\xe7\x1f\x19\x4f\x5b\x23\xf1\xb4\xc5\xff\x82\xf1\x52\xb6\xef\xf4"
-  "\x57\x37\x80\xe7\xdc\x11\x5b\x11\xbb\x24\x7c\x95\x75\x03\xc5\xbe"
-  "\x75\x03\xdd\xe0\xab\xff\xb1\xfb\x76\xbc\xa9\xc4\xd7\x1d\xef\x28"
-  "\xf1\xf5\xad\xe1\x9d\xf1\xf5\x72\x6c\xdd\x71\xce\x1b\xae\x72\xdd"
-  "\xc0\x9b\x0d\xbe\x31\xf5\x0d\x9d\x2f\x4c\x65\x3e\xfd\x6a\x65\x1b"
-  "\x69\x19\x53\x77\xde\xa7\xc4\xd4\x37\xa6\x5c\x29\xa6\x5e\x97\x78"
-  "\x29\x3f\x1a\x53\x13\x3b\x61\xea\xce\xcf\x65\x4c\xed\x1c\x33\xa5"
-  "\x1b\x4c\xbd\x56\x7a\x02\x4f\x4c\x55\xf0\xae\x6f\x3e\xa5\xc4\xd4"
-  "\x37\x73\x7c\x63\xea\x9b\x43\x64\x4c\xe5\xf9\xae\x2d\xa6\xbe\x39"
-  "\xe9\xda\xea\x09\xde\x9c\x24\xf3\xae\x6f\x0d\xe8\x1e\x53\xdf\xd0"
-  "\x7b\xc7\xd4\x37\xf4\x1c\x53\xdf\xd0\x5f\xf9\x99\xf2\xb7\x5c\x7e"
-  "\x60\xea\x2f\x3c\x96\xca\x5b\x4e\xbf\xf5\x04\xa8\x6f\x45\x2c\xad"
-  "\xf9\x69\xbe\x43\x52\x25\xdf\x21\x23\x45\x8c\xfd\xc3\x4f\xc5\xd8"
-  "\x5d\x7d\x95\x36\x0d\xbb\x42\x24\x9b\x06\x8e\xb1\xef\xbe\xa7\x8c"
-  "\x8f\x7a\xb9\xaf\x10\xa5\x0f\xd5\x5d\xd3\xdc\x7a\x02\xc4\xdc\x91"
-  "\x9e\x7a\x82\x77\xa7\xf9\xc6\xdb\x5d\x39\x0a\x3d\xc1\xa7\xde\xf1"
-  "\xb6\x55\x81\xb7\xef\x6c\x67\x78\xeb\xf6\xa1\xba\xab\x4c\xf2\xa1"
-  "\xda\x2d\x0f\xab\xc0\xdb\x84\x9f\x07\x6f\x4b\xae\x1c\x6f\x95\xb1"
-  "\x54\x3a\xfb\x4b\xdd\x3d\xda\x52\x0a\x78\xcb\xfc\x75\x74\xf6\x99"
-  "\x7a\x65\xfe\x3a\xae\x95\xcf\x54\xac\x97\x77\xdc\xdd\x5d\xae\xc4"
-  "\xdd\x77\x09\xcb\xeb\x15\x77\x77\x6f\x91\x71\x97\xe7\xbb\x62\xdc"
-  "\xfd\x51\x3a\x83\xdd\x65\xd7\x56\x67\xb0\xbb\x4c\xc6\xdd\x77\xd7"
-  "\x76\x8f\xbb\xbb\x4c\xde\x71\x77\x97\x89\xe3\xee\x2e\x53\x97\xb8"
-  "\xab\xb0\x21\x28\x5e\xee\xd5\x97\x47\xcd\xbf\x7a\x9c\x95\xe2\xcc"
-  "\x1f\xa3\x33\x00\x0c\x56\xa7\xa1\x0f\xa7\x04\xb4\x21\xe8\x5e\x67"
-  "\xd0\x1d\xde\xfa\xaf\x33\x78\x6f\x99\x12\x6f\xdf\x5b\xae\xc4\xdb"
-  "\xf7\x87\x62\xbd\xba\xd4\x19\x30\x0c\x78\xaf\xdc\xad\x33\xb0\x2a"
-  "\x71\x56\xd6\x19\xec\xf9\xda\xf7\xde\xd7\x7b\x0e\x05\x7f\xfb\x87"
-  "\x4e\x3e\xab\xa7\xca\x78\x7b\xbc\x42\xb2\x19\xfb\x9f\xbb\x8e\x4d"
-  "\xf4\xc4\xdb\xbf\x8d\xb8\xcc\x67\xf5\xa4\xab\xe8\xb3\x7a\xd2\x55"
-  "\xf6\x59\xfd\x94\xd2\x67\xf5\xa6\x56\xd9\x8e\xcc\x7f\x9f\xd5\xff"
-  "\x73\x84\x61\x30\x8e\x21\xf4\x5b\x7d\x25\x7a\x84\x6b\x1c\x6b\x45"
-  "\x81\xbd\x0a\x3d\xc2\x9e\xd1\x4a\xec\xdd\x93\xe6\x1b\x7b\xf7\x0c"
-  "\x90\xb1\x97\xe7\xbb\xb6\x3c\xef\x9e\x51\xd7\x56\x8f\xb0\x67\x94"
-  "\xac\x47\x78\xbf\xaf\x57\xec\x55\xec\x8d\xfd\x8d\x78\xdf\x1b\x83"
-  "\x74\x86\xbd\x7f\x23\x3e\xf5\x08\x97\xd9\x6f\xbd\xff\x03\xdf\x1b"
-  "\x13\x79\x5e\xab\x1f\x7a\x84\x5f\x9c\x8d\xc1\xfb\xb6\x1f\xa3\x47"
-  "\x40\xbc\x45\x3c\x93\x30\xf7\x4a\xf4\x08\x57\x9f\xc7\xfd\xe0\x07"
-  "\x25\xe6\x7e\xd0\xa2\xc4\xdc\x8f\xd6\x77\xc6\xdc\xcb\xf1\xf6\xc3"
-  "\xfb\xbc\x61\x2d\xd7\x23\x7c\x34\xd2\x37\xce\x7e\x98\xe0\x13\x67"
-  "\x3b\xd9\xe6\xca\x38\x5b\xb2\x56\x89\xb3\x1f\x6e\xfb\x51\x38\x7b"
-  "\xa5\x31\x58\x7e\x51\x38\x9b\xd0\x09\x67\xf7\x0e\x95\x71\xb6\x73"
-  "\x1c\x96\x6e\x70\xf6\x1a\xc5\x61\xf1\xcd\xe3\xee\x7d\x4f\x89\xb3"
-  "\x7b\xeb\x7c\xe3\xec\xde\xe5\x32\xce\xf2\x7c\xd7\x16\x67\xf7\x16"
-  "\x5f\x5b\xdd\xc2\xde\x62\x99\xc7\xfd\x68\x61\xf7\x38\xfb\x61\xa2"
-  "\x77\x9c\xfd\x50\xdc\x17\xfb\x30\xd1\x27\x8f\x7b\x19\xce\x7e\x3c"
-  "\xd9\x0f\x9c\xfd\x85\xdb\x20\x7c\xec\x97\xff\x0b\x0f\x7d\x6d\x4f"
-  "\x8b\xb5\xd3\x79\x89\xaf\x3c\xcf\x4b\x78\xe8\x16\x46\x4a\xba\x05"
-  "\x65\x7c\x96\x54\x49\x7f\x1b\x23\xe2\xee\x23\x3f\x15\x77\xf7\xcd"
-  "\x6a\x73\xe3\x6e\x12\xe0\xee\x3e\x76\x3e\xa2\xcd\x8d\xbb\xe6\xdb"
-  "\xa4\x7a\xc9\xf1\x59\x7c\xe8\x16\x1e\x60\xe5\xed\x77\xeb\x16\x10"
-  "\x87\x63\x3c\x75\x0b\x07\x3f\xf7\x8d\xc1\xfb\xea\x14\xba\x85\x4f"
-  "\xbc\x63\xb0\x5d\x81\xc1\x07\xfa\x33\x0c\x7e\x40\xc2\xe0\xfd\x86"
-  "\x56\x90\x2d\x5b\xb3\xfd\xc3\x60\x3b\xc3\xe0\x51\xd7\x07\x83\xf7"
-  "\x5c\x05\x0c\x66\x74\x3f\xb0\xd7\x62\x06\x0c\x9e\x82\x18\x3c\xea"
-  "\xca\xf4\x0d\x3f\x53\x8c\x16\xac\x97\x77\x2c\x3e\xf8\x7b\x25\x16"
-  "\x1f\x34\xb2\xbc\x5e\xb1\xf8\x60\x5f\x19\x8b\x79\xbe\x6b\xab\x6f"
-  "\x38\x38\xe2\xda\xea\x1b\x0e\x8e\x90\xb1\xd8\xac\xea\x1e\x8b\xf7"
-  "\x35\x79\xc7\x62\x48\x67\x58\xbc\xaf\xa9\x4b\x2c\x7e\xc0\x13\x8b"
-  "\xcd\x6e\x9e\x57\xa1\x6f\xb0\xfe\xab\xc7\x6e\x31\xfb\xe4\x7f\xf5"
-  "\xb7\x92\xcc\x5a\xd5\xa1\xd1\x96\x02\x42\x9a\xb3\x48\xa6\xc5\xf9"
-  "\x00\x81\x34\xa0\xdf\xa1\xf9\x16\x5d\x34\x11\xd6\x3d\xae\x47\x3c"
-  "\x7e\x0d\xff\x80\xc7\x35\xa9\xc5\xb9\xc5\x68\x7c\x88\xd9\xbb\x62"
-  "\x3a\x62\xef\x56\x8f\xe7\xde\xbe\x45\x4d\x63\x8a\xc4\xf7\xca\xf8"
-  "\xb9\x9b\x31\xdb\xa4\x7b\x1c\x9b\x56\xd5\xa1\x4a\xba\x76\x4c\x81"
-  "\x2d\x64\x4c\x81\xb7\xf7\x6f\xd7\x92\xa0\x7e\xcb\x29\x2d\xdc\x40"
-  "\xed\xcd\x77\x8e\xd1\x37\xbf\x42\x88\x69\x03\xb5\xb5\x65\x7f\x02"
-  "\x6d\x3c\x14\xf9\x57\xc8\xd7\x1c\x7a\x40\xdb\x9c\x35\x91\x40\xda"
-  "\x40\x29\x0d\xe8\x46\x84\xac\x00\x2a\xc0\x33\xba\xa1\xaf\x73\x6b"
-  "\x3a\x60\x55\x1a\x21\x77\xb7\xe2\x9c\xf9\x24\x02\xc6\x4c\x58\x2e"
-  "\x94\xb9\x06\xca\xa2\xbf\xba\xd9\x0e\xe3\x31\xb0\x62\x25\xc1\x39"
-  "\x9d\x03\xed\x2a\xca\x45\xda\x07\xfc\x3a\x9f\xaa\x03\x89\xb0\x7d"
-  "\x78\x2a\xed\x3f\x3d\x12\xfa\x83\x98\x92\x48\x10\xb6\x63\x0d\xe4"
-  "\xa3\xea\x0c\x2a\x0c\x89\x06\xfc\xb7\xf3\x39\x0d\xf5\x3b\x00\x72"
-  "\x2c\x85\xef\x16\x26\x11\x2d\xfc\x05\xd3\xf5\xd3\x23\xa1\x5e\x7b"
-  "\xa0\x5e\x05\x58\x2f\x5f\x6d\x5c\xb3\x09\xd6\x9d\x9b\x75\xb8\x76"
-  "\xb0\xef\xe3\xb7\xd9\x77\xd4\x42\x8e\x0b\xd2\x69\x56\x06\xb5\xa4"
-  "\x3a\x89\x06\x68\xb1\x15\xea\x8d\xe3\x51\xd8\x31\x46\xbf\xe2\x26"
-  "\x42\x76\x2f\x69\x50\x5b\xa0\xee\xae\xbf\xde\x6c\x37\xa7\xdf\x4b"
-  "\xe0\xb9\x0d\x65\x96\x7a\xd5\xe1\xf7\x26\x9c\x25\x04\xf1\x04\x7e"
-  "\xef\xb7\xc3\x3a\x36\x0e\xee\xd7\x40\x3b\x84\x66\x5d\x20\xe6\x85"
-  "\xf4\x59\xe6\x94\x93\x44\x63\x24\x41\xb9\xd0\x36\x31\x6f\x34\xe6"
-  "\xb5\xaa\x0e\xef\xc3\x3a\xc0\xfd\x58\xb8\xc7\xf7\xd0\x86\x8c\xd0"
-  "\x6d\xc3\x53\xd9\xd8\xcc\x9b\x1e\x29\x0c\x19\x9e\xca\xb0\x0f\xda"
-  "\xb9\x06\xda\x0c\x79\x82\x21\x4f\x30\xbb\xa6\x13\x6d\x1e\xa4\x61"
-  "\x39\x70\x0d\x36\xcf\x6b\xc7\xb2\x0d\x58\xb6\x0f\x3a\x04\xd2\xb0"
-  "\xe9\x91\x14\xc6\x36\xae\xa9\xfa\x74\xd5\xe7\xb5\xaa\xd2\x29\x1a"
-  "\x15\xa5\x74\x5b\x34\x59\x91\x4e\x82\x4d\x02\x21\xe6\x9b\xb0\x9c"
-  "\xd2\xfb\xa0\xfc\x40\xa4\x45\x5b\x76\x69\x98\x55\xf5\x89\x19\xe9"
-  "\x0b\xfd\x69\xd7\xdf\x8e\x6d\x28\x9d\x83\xdf\xc1\x77\xc4\xfc\xcc"
-  "\xf7\x3d\xd6\x59\x9f\x1e\x40\xe1\xfe\xa9\x00\xd5\x69\x12\xa0\x0b"
-  "\x7e\x06\xde\x9f\x64\x25\xaf\x36\xe0\xfb\x56\xfe\x1e\x8c\xa5\x52"
-  "\xc0\x91\x43\x35\x98\x86\xf7\x3e\xea\x1b\x2c\xf5\x5b\xb9\x0e\xc6"
-  "\x46\xe7\xbe\x93\xc6\x08\x8c\x0b\x69\x8c\x60\x7d\xdf\x4d\xb7\xaa"
-  "\xd9\x3a\xac\x2a\x65\x72\x5d\x2e\xf4\xa1\x6b\xb3\x2e\x70\x0d\xd0"
-  "\x56\xe8\xc0\x7e\xa9\x85\x67\x47\xde\xc1\x7e\x59\xb3\x04\xfa\x84"
-  "\xe7\xad\x94\xeb\x8f\xf7\x47\x58\x7f\x0a\xd0\x17\xfc\xec\xe6\x91"
-  "\xe5\xd8\x9e\x35\xad\xd0\x8f\xe1\xd4\x5e\x9a\x0a\xf5\xc2\x71\x0b"
-  "\x63\x64\x77\x92\x43\x8d\x76\x7d\x98\x7e\xe0\xa2\x43\xbd\xa6\x91"
-  "\x20\x5f\x49\x56\x03\x2e\x6f\x49\x01\x9a\x43\x99\x74\x70\x34\xe3"
-  "\x23\x58\x3f\x2e\x81\xbe\x4b\x81\xb1\x0b\x34\x5f\x03\xf4\x2b\x04"
-  "\xcc\xc3\xdf\x85\xb0\xfe\x08\x90\xcf\xaa\x3a\xb2\x0f\xca\xd3\x6e"
-  "\x09\xa7\xb6\xad\xe1\xb4\x09\x68\x38\xaf\x2d\xfb\x48\xbe\x44\x43"
-  "\xac\xd3\x1a\x48\x5f\x0d\xcf\x21\x6f\x18\x1f\x43\xa5\x75\x52\x9b"
-  "\x7d\xd1\x73\xd5\x6e\x12\xbd\x7a\x37\x19\xf8\xca\x6e\x32\x22\x6d"
-  "\x06\xcc\xcb\xac\x87\xe8\x67\x09\x4e\x58\x13\xb7\x1b\xda\xc3\x1f"
-  "\xd7\x22\x7f\x28\xac\xb8\xb9\xe8\xa5\xdd\x24\xe2\x9d\xa9\x45\xea"
-  "\x09\x4d\x84\xe0\x1a\x3e\xa1\xc7\x37\xd4\x62\x6c\x21\x42\xc8\x76"
-  "\x83\x6b\xc5\xaf\x43\xc7\x03\x55\x8f\x18\xec\x24\x3d\x19\xd6\xf2"
-  "\x8b\x0d\x24\xdd\x4e\x6d\x15\x99\x67\x09\x60\x4f\x1e\xa7\xdd\xdf"
-  "\xc7\x4e\x98\x49\x08\x9e\x19\x14\xbe\x37\x90\xbe\x89\x24\x30\xed"
-  "\x2b\xa2\xcb\xa8\xa3\x0d\xae\x0d\x71\x24\x7d\x19\x51\xef\xbe\x58"
-  "\xcd\x79\x4f\xd5\xdf\x6f\xd9\x0f\xdf\xa2\x6d\x71\x24\xde\x29\xae"
-  "\x47\x79\xd3\xa3\x33\x66\x91\x01\xd8\x1e\x0d\xe3\xbd\x3e\x3d\x02"
-  "\x74\x8b\xf6\x0f\x9f\x3f\x35\xf1\xfe\xd4\xe8\x33\x66\xd2\x06\x58"
-  "\x53\xd4\x34\x63\x86\x8a\xea\x53\x0c\x74\xbd\x46\x6f\x09\x6c\x25"
-  "\x96\x44\x3b\x39\x08\xdf\xf6\xb3\x5c\xe6\xff\x9b\xad\x9f\x50\xdf"
-  "\xa7\x0c\x24\x93\xd5\x19\xd6\x49\x4d\x32\xf2\x50\xf4\x1b\xac\xf3"
-  "\x01\x68\x1f\xbd\x6d\xa1\x09\xf2\xa7\xe2\x9a\x39\xc1\x6a\x26\x65"
-  "\x0e\x17\xd9\xd4\xc8\xe8\xd2\x13\xe8\x12\x08\xcf\xc6\x02\x6d\x82"
-  "\xbc\xf5\x15\xf6\x93\x60\xda\x6e\x10\x02\x78\x7f\xb0\xbe\xb0\xf3"
-  "\xbe\x18\x3f\x9f\xc0\xda\x09\xfd\xb1\x96\xf7\x87\xd0\x7f\x9a\x16"
-  "\xfb\xc3\xbf\x76\xfc\xbd\xd8\xd7\x9a\x82\xdf\xa6\x30\x26\x70\x2c"
-  "\x08\x61\xd3\xb4\xf8\x6d\xac\x03\xee\x99\x61\xdf\x4f\x78\xe9\x1b"
-  "\x5a\x61\x6c\x20\x16\x68\x0f\x0d\xf1\xac\x83\xd3\xcf\x3a\x1c\xf5"
-  "\x19\xff\x6c\xd5\xdd\x30\x56\xef\x86\xb1\x7a\x37\x19\xb1\xd4\xca"
-  "\xc7\xea\xf1\x1a\x3e\x56\x5d\x50\xaf\x4b\xc0\xaf\x2f\x7d\x8a\xa8"
-  "\xb1\x5e\xbb\x4e\xa2\x5f\x3e\xa8\x67\x83\x3c\x5e\xc7\x9d\x03\x1a"
-  "\x49\x63\x36\xe0\xd7\xa1\x48\x9f\x0a\xfb\xff\x65\xef\xeb\xe3\xa2"
-  "\xa8\xf6\xff\xcf\xce\x42\xa2\x21\xac\xde\xc5\x56\x23\x5b\xbb\x58"
-  "\x4b\x69\x61\x5f\x4d\xec\x6a\x62\xe9\xe5\x21\x0d\x2c\x2d\x7c\x0a"
-  "\x28\xec\xa2\xf9\x80\x0a\x88\x8a\x80\xa6\x7d\xd5\x00\xc1\xc0\x8b"
-  "\x05\x88\xa5\xa5\xe5\x03\xde\xab\xa5\x5d\x2d\xbc\xe9\xef\x82\xf1"
-  "\xa0\x7d\xad\xb0\xf4\xba\x7a\xd1\xd0\xd0\x56\x45\x58\x60\x77\xe7"
-  "\xf7\x39\x73\x66\x9d\x1d\x76\x66\xd9\x99\x55\x2e\xfa\xf2\x8f\x79"
-  "\xc1\x9e\x99\x39\x73\xe6\xf3\x79\x9f\xcf\x79\xbf\xcf\x9c\x87\x1a"
-  "\x94\x86\x31\xdb\x22\x84\xd9\xa3\x28\x3c\x06\x7c\xf3\x17\xc0\xec"
-  "\xaf\x3a\xe4\x59\x8b\xdc\x96\x4e\x04\xcc\xd6\x09\x61\xb6\xfc\xf8"
-  "\x01\x78\xa6\x1d\x66\xa7\xdb\x62\xb6\x7c\x91\x74\xcc\x96\x8f\xbe"
-  "\x89\xd9\x19\x22\x98\x8d\x05\xcc\x4e\xce\x97\x88\xd9\xf2\x02\x69"
-  "\x98\x2d\x1f\xc0\x60\xf6\x14\x60\x16\xf4\xc7\x07\x6f\x31\x76\xb9"
-  "\x0f\xec\x02\x98\x2d\xc7\xb6\x11\xc4\x6c\xc7\xfb\xec\xbb\x3d\xce"
-  "\xfb\xec\xbb\x95\xed\xfb\xec\xbb\x81\xd2\x7d\x76\xd4\x78\x7b\x7c"
-  "\xf6\x5d\x84\x34\x9f\x1d\xd5\x8b\xfb\xec\xe8\x9e\xce\xe3\xb3\xca"
-  "\x38\xe7\x7d\x56\x39\xac\x7d\x9f\x55\x9c\x95\xee\xb3\x8a\xed\xb7"
-  "\xc7\x67\x95\x6e\xd2\x7c\x56\x91\x2b\xee\xb3\x8a\x38\x31\x9f\xbd"
-  "\xd0\xdb\x42\x5b\xf0\x38\xb8\x5e\xc1\xf1\x98\xd3\x10\xfe\x55\x35"
-  "\x04\x6b\x40\xf8\xed\x66\xfd\xcd\x70\x24\xd0\xc9\x6d\x7e\x7b\xb6"
-  "\xf9\xad\x6a\xf3\x5b\xdd\xe6\xb7\xa6\xcd\x6f\x5f\xeb\x6f\xf0\x91"
-  "\xfb\x15\x45\xe5\x16\xd0\x60\xe9\x7a\x45\x55\x10\x7b\xde\x2f\xca"
-  "\xac\xc5\x3a\xce\x4f\xa8\xec\x6b\x97\xd3\xc6\xee\x0a\x44\xb7\x52"
-  "\x34\x8a\x4f\x45\x0f\x5e\x52\x54\xed\x69\x59\x0e\x12\x4f\xd9\x47"
-  "\x47\xb7\xa4\x23\x4b\xae\xf7\x84\x97\x16\x01\xa6\x0c\xa0\xfb\xd2"
-  "\x34\xf7\x41\xde\x0f\x80\xdd\x0c\x55\xf1\x06\xe0\xd9\xdf\xd0\xe7"
-  "\x14\x55\x9b\xf0\x7b\x3e\x19\x5f\x8a\x2c\xca\xc7\x75\x34\xb3\x16"
-  "\xb3\xf7\x04\x83\xf2\xf1\x3e\xf4\xa6\x24\x6d\xe6\x72\x8b\x47\x75"
-  "\xfd\x09\x94\x45\x59\xb4\x29\x29\xc0\xd3\xeb\xf7\xa0\x25\xf5\x74"
-  "\x5d\x8a\x89\x36\x56\x4f\x2d\xc5\xdf\x61\xeb\xaa\x93\xcb\x50\x95"
-  "\xe1\x04\xc2\xed\x19\xc6\x67\xb5\x61\x0f\xf9\xee\x8b\xaf\x81\xb4"
-  "\x2a\xc3\x76\x54\x09\xbf\x4b\xe7\x9c\x87\xf7\xac\x1e\x5f\x5d\xbf"
-  "\x1d\x99\x73\xbd\x23\x2c\x6a\xef\xc1\xb4\xda\x3b\xb0\xb2\x1e\xca"
-  "\x96\xeb\x3d\x1c\x97\xb5\x0a\xca\xc1\xec\xb9\x99\xe7\x3d\x9c\xc9"
-  "\xb7\xe1\x18\xd3\x27\x60\xce\x83\xeb\x7d\xe0\x7a\x1f\xef\x40\x5c"
-  "\x3e\x5c\x36\x41\xfd\x96\x1b\xbc\x19\xca\xfe\xec\x44\x9d\x1b\xa2"
-  "\x97\xb9\x69\xa4\xe1\xad\x3a\x41\x54\x17\xe6\x86\xf8\x91\x7c\x3d"
-  "\xe4\xe4\x5b\xe1\x20\x5f\xb6\xbc\x2a\x19\xf9\x1e\xf3\x13\xcf\x37"
-  "\x94\x2d\xaf\x56\x4e\xbe\x29\x0e\xf2\x65\xcb\x1b\x24\x27\x5f\xd1"
-  "\xf9\x5f\x74\x6e\x18\x5b\xde\x74\x19\xf9\x1e\x1f\x20\x9e\x6f\xf0"
-  "\x66\x79\x58\x38\x2e\xde\x47\x00\x58\x90\x87\x83\xe3\x0e\xde\x3f"
-  "\x64\xb3\x3c\x0c\x7c\x2f\xba\xfe\x0f\xc6\x80\x3c\xff\x7f\xef\xd0"
-  "\xff\xf2\x7c\xff\xfd\x31\x47\xbe\x97\xe7\xf7\xff\x13\xc5\x3f\xd6"
-  "\xba\xe0\xfb\x20\xba\x57\x62\xba\x65\xfd\x03\x41\x96\x5e\xc1\xcf"
-  "\xbf\x63\x09\x42\x2f\x2c\x85\x76\x2e\x1f\xf5\x78\xa1\x10\xa1\xa5"
-  "\x05\x88\xca\xa6\x2c\xd4\x8e\xc5\x35\x54\xb5\x29\x10\xc7\x2b\xf3"
-  "\xe6\x24\xa3\xe2\x8f\x90\x7e\x28\x0e\xa1\x86\x05\x3a\x44\xf2\x78"
-  "\x20\x28\x2b\x35\x08\x85\x9b\x11\xee\xab\x68\xf8\x16\xac\x13\x7e"
-  "\x15\x62\x6a\xbe\x11\xb7\x99\x3d\xe0\x3e\x13\x60\x17\xf2\x30\xa2"
-  "\x5d\x16\x83\x22\x68\x3e\x73\x9d\x01\x34\xa5\x81\x5e\x1f\xfc\x3c"
-  "\x9d\xa6\x43\x2b\xe0\xff\x0b\x8a\x13\x0f\x29\x0d\x88\x2a\x02\xad"
-  "\xd9\xf4\xee\x09\x8d\x5e\x71\xa2\x01\xeb\x4f\xd0\xb9\xf5\x69\x57"
-  "\x71\x7f\x7c\x62\xfa\x3b\xa0\x79\xf1\xb5\x3b\x2d\x06\xea\xc9\x78"
-  "\x44\x7d\x6b\xc0\xda\xfe\xc4\xe8\x43\x10\x99\x1c\xf4\xc7\xb8\x59"
-  "\xd4\x51\x2b\xf0\xfd\x38\x1f\xdc\xcf\xb9\xd6\x02\x76\x55\xbf\x11"
-  "\x88\xcb\x0b\xf6\x35\x96\x2e\xc6\x6d\xcc\x89\x8a\x31\xfe\x74\x13"
-  "\x6e\x33\xa0\xad\xe8\x73\x09\x7e\x33\x7a\x7e\x39\x7d\x8c\x56\x7b"
-  "\xe9\xe8\xac\xee\x41\x55\x0d\xd7\x50\x69\x52\x0b\x3a\xa7\x38\x51"
-  "\x89\x9f\x7d\x5d\x1d\x95\xde\xa0\x8e\x5a\x05\x65\x28\xb3\x96\x17"
-  "\x3f\xcb\x9a\x8e\xfb\x2f\xd8\x32\xd6\x1d\x4a\x11\x2f\x23\xfd\x4e"
-  "\x9f\x9e\xe1\x1a\xda\x80\x6d\x58\x9a\x7a\x0d\xca\xf2\xe3\x34\x6c"
-  "\x67\x3a\x37\x2a\xa2\x21\x4d\xd7\x97\xf4\xe7\xfd\xb0\x02\xf7\x0b"
-  "\x41\x5b\x30\x9a\xf4\xd1\x78\x8f\x66\xc6\xe0\x40\xac\x07\x3d\xaf"
-  "\xc1\x7c\xe7\x8a\xe2\x87\xf1\xb8\xcc\x13\x75\x94\x44\x6d\xf4\x03"
-  "\xc3\xff\x4a\xfb\x62\x3b\xfc\x38\x06\x9e\xf7\xa7\x73\x8a\x1f\xb6"
-  "\xb2\xbc\x25\x12\x3f\x0f\xae\x19\x0c\xcf\x8c\xa4\x73\xbd\xb4\xf8"
-  "\x3a\x38\x5f\xc6\x9e\x8f\xb6\x39\x1f\x0d\x65\xce\x67\xcf\xd7\xb1"
-  "\xe7\x63\x6d\xce\xc7\xc6\xf7\xc5\x7d\x76\x3f\xaa\xf0\x3b\x41\xfb"
-  "\x16\x04\xe7\x27\xe0\xef\x01\xcc\x3b\xf9\x78\x07\xb1\xd7\x4d\xa8"
-  "\x57\xfc\xe8\x7f\x1d\x70\x05\xe7\xa7\xda\xdc\x3f\xf5\xdb\xe4\x00"
-  "\x84\xf1\xd9\xf4\xee\x8f\xc3\xf5\x6e\xbd\xfc\x48\x3f\xcf\x0f\x81"
-  "\x8c\x2d\xa0\xbd\xb4\xcd\x4f\xaf\xf8\xd1\x03\xb7\x89\x0d\xc0\x15"
-  "\xe1\x1a\x2d\x7e\xa6\xad\xfd\xa7\xcf\x9f\x3f\x77\xbe\xb6\x7f\xac"
-  "\x36\x76\x76\x8c\xf6\xcd\xb9\x89\x73\x12\x46\xf4\x8f\xed\x86\x90"
-  "\x0d\x76\x54\xf4\x72\x6f\xda\x92\x3b\xb9\xac\x3a\xdf\x84\x68\x4a"
-  "\x05\x6d\x77\x0b\xca\x05\xbf\x9a\x7b\xcd\x2c\x31\xaf\x9f\x09\x75"
-  "\xe7\xc5\xe2\xd2\xc5\xcf\x83\xed\x7f\x64\xf6\x8f\xa9\xd6\x22\x94"
-  "\x01\xe7\x4b\x17\x1f\xc5\x69\x67\x99\xb4\x58\x84\x98\xbe\xac\xc5"
-  "\x1e\xe8\xb0\xf6\x1a\xd3\x1f\x76\x45\xf1\x53\x6f\xa6\xef\xef\x06"
-  "\xa2\x4c\xcb\x3d\xd0\xdf\x53\x8f\x51\x07\x2c\x7a\xea\xef\x96\x1a"
-  "\x0a\x73\x8e\x6f\x35\x65\xe8\xa9\x64\x0f\x84\xcf\x7f\x93\x0a\xe9"
-  "\x70\x1e\x9f\x63\xf2\x61\x7c\xfd\xd3\x0c\x7c\x1d\xee\x1f\xc3\xff"
-  "\xa7\xe5\xd3\x67\xbf\xd5\x00\x6f\x61\x78\xef\x8f\x07\x71\x59\xb5"
-  "\x7d\xf0\xb7\x87\x1f\x0f\xe1\xf2\x81\x2d\x4a\x95\x05\x70\x7d\x12"
-  "\xf2\x84\xeb\x77\x58\xf2\x26\x97\xe1\x38\x60\x7a\xf7\xc7\x04\x7a"
-  "\x79\x8f\x67\x8a\xd6\x21\x8f\x82\x75\x50\x37\xd7\x21\xb7\xa6\x77"
-  "\x7f\xca\xd7\xbb\x0d\xa8\xc5\xb6\x85\x6c\x3c\xaf\x53\x68\x24\xa4"
-  "\x6d\xd7\xa3\xf7\x32\x70\x1a\xd4\xc1\x06\xb1\xb8\xd2\x08\x5c\xd1"
-  "\xe8\x37\x34\xc8\xa2\x9e\xbc\x8f\x06\xbb\x35\xf9\x0d\x8d\xf7\x8e"
-  "\x07\x6c\x41\x1d\xa3\x7d\x26\xef\xab\x57\x9c\x2c\xfd\x7f\xa0\xc4"
-  "\x53\x71\x9d\x5e\xff\x62\xf1\x67\x8d\x46\xa8\xdb\x33\x4b\xb6\x37"
-  "\x1a\xe0\xf7\xcc\xa0\xad\xf0\xbb\xbc\x74\x2b\xd2\xbe\x84\xf9\x57"
-  "\x4d\xbf\x17\x63\x69\x93\x7f\x05\x70\xd6\xda\xbf\xa1\xef\x4e\x94"
-  "\x21\xcf\xa9\x48\x79\x73\x1d\xf8\x04\x44\x85\xeb\xe1\x77\x22\xa2"
-  "\xaa\x8c\x66\xa6\xcf\x3f\x75\x18\xee\xbb\xaf\x44\xb8\x3f\x9f\xa6"
-  "\x32\x4c\x3b\xae\x19\x21\x86\xd5\xb9\xe3\xf1\xe0\x16\xd5\xe7\x3a"
-  "\x7c\x4f\x54\x03\xfb\x1d\xec\x3a\xfb\x1d\xec\x3a\xf3\x1d\x6c\x6c"
-  "\x4a\x34\xf9\x0e\x86\xbf\x7f\x85\x47\x2b\x69\x9c\x1f\xfe\x26\xd6"
-  "\xbd\x01\x70\xb0\x40\xe7\x65\x5e\xa0\xeb\x99\x7f\x0d\xa9\xab\x0c"
-  "\x75\xa8\xba\xbe\x0c\x7d\x98\x84\xd4\xf4\xf5\xb8\xae\x15\xa5\x47"
-  "\x11\xbd\xee\x53\xed\xae\xd4\x52\x77\x33\xee\xcb\xb8\xae\xe9\xe6"
-  "\xbd\x4c\x81\xbf\x01\x78\x65\xcc\x47\x03\x36\x5e\x43\x01\x51\xe7"
-  "\xd3\x99\x35\xa1\xf0\xfe\x7d\xa6\xeb\x3a\x6d\xeb\x75\xdd\x23\xcd"
-  "\xd7\x75\x7d\xbd\x0d\xe4\xbb\xd9\xb4\xcb\x2a\x84\xc7\xe2\xd2\xef"
-  "\xfe\xcb\xb8\x11\xf7\x5f\x37\x18\x90\xa9\xc7\xe7\x3a\x8c\x65\x78"
-  "\xb6\x2f\xfe\xd6\x92\xb6\x08\xa9\x2c\xff\xd1\xa1\xca\xb8\x6b\xe8"
-  "\x29\xf0\x3d\xfe\xae\x50\x74\x8e\x7c\x57\x30\x83\x26\xc2\xdf\x16"
-  "\x1a\xaf\xeb\x28\x5a\x1d\xa3\x1d\x37\x43\x8b\x9a\xb7\x0c\x0d\xaa"
-  "\x4e\xfe\x0c\xa5\x35\xd3\x67\xab\x57\x58\x10\xee\x73\xa6\xdf\xfd"
-  "\xe9\x30\xed\x13\xa3\x3d\xa2\xfb\x01\xb7\x29\x83\xb9\xd8\x71\x32"
-  "\x53\x5e\xec\x38\xc9\xac\xff\x81\xbf\xc1\x81\xff\x4a\xb6\x5f\xc3"
-  "\xfe\x04\xbf\x5e\x33\x50\x61\xe0\xbb\xca\xda\x8f\xc0\x6f\x35\x3c"
-  "\xbf\x31\x7e\x86\xeb\x2e\xc4\x82\xbf\xce\x13\x1f\x56\x34\x80\xff"
-  "\xf6\xe3\x3c\xa2\x4a\x77\x24\x19\x29\xd0\x5d\x54\x85\xf1\x34\x33"
-  "\x9f\x05\xfb\x71\x7b\x4b\x99\x7b\x33\xb4\x37\xf8\x5b\x66\xe3\xe6"
-  "\xa1\xd1\xcd\xea\xc9\xf9\xad\xea\xc9\x5b\x1d\x7c\xd7\x24\xfe\x9c"
-  "\x81\x3c\x2a\x6a\x7f\x20\xfe\x9c\xc7\xfa\x13\x8f\x7f\x5b\xa8\xf3"
-  "\x32\x35\x81\x3f\x1b\xc1\x9f\x09\x7a\xf4\xc1\x7c\xa4\xae\xae\xab"
-  "\xc1\xdf\x7c\xba\x86\x42\x4d\x0e\xf3\xa7\x2d\x95\xa5\x3f\x33\x7e"
-  "\xdd\x09\x7e\x35\x65\x6f\xd1\xe1\x6f\x9d\x37\xfd\x9a\x04\x7e\x6d"
-  "\x04\xbf\x5e\xe6\xfc\x6a\x6e\x02\xbf\x36\x81\x5f\x9b\xc0\xaf\xec"
-  "\xf7\xd0\x69\x33\xc0\xaf\xf8\xdb\xd9\xbb\x65\x29\xf8\x7b\x28\xfe"
-  "\xee\x84\xfd\x8a\xc7\x5c\x5b\x16\xea\x7c\x99\xef\xa0\x6f\xea\xd0"
-  "\xc6\x37\x90\xc7\x40\x23\x52\xa4\xed\x47\x2a\x28\xa7\xea\xd1\x3d"
-  "\x88\x82\xfc\x00\xf7\xe7\x10\xf6\x6f\xf5\x1e\x33\x5a\x32\x09\xf5"
-  "\x35\xe5\x10\x3f\x57\x9b\xf6\xe2\x7e\xdf\xc0\xc6\x85\x3a\x6a\x43"
-  "\x12\x1a\x8e\x7d\x3e\xf6\xbc\x16\x1d\x89\xa8\x44\x6d\x7d\x6e\xc9"
-  "\x8b\x8a\x00\x3f\x25\x63\xbf\xcb\xaf\xb7\xa7\x93\x9d\xaf\xb7\xbf"
-  "\x9c\xbc\x57\x6f\x6f\x75\xbd\xfd\x25\x45\xb8\xde\x9e\x1e\x23\xaf"
-  "\xde\x9e\x1e\x7d\xaf\xde\xde\x09\xf5\xf6\x74\x40\xdb\x7a\x7b\x93"
-  "\xb7\xcc\x9f\x3e\x3b\x66\xc6\x9c\x19\x73\xfe\xa2\x7d\x63\x51\xc2"
-  "\xf4\x05\x84\xbd\xf0\xf8\x8b\xce\x6c\x09\xa2\xde\x87\xf6\xfa\x3b"
-  "\x4d\x0d\xda\xd5\xa7\x86\xb2\x4c\xd1\xb8\xd1\xd9\x07\xe3\x2d\xd9"
-  "\x07\x0d\xef\x03\x0f\xc7\xf5\x3b\x17\x38\xf6\x05\xc5\xc5\xcd\xff"
-  "\xf2\x05\xfe\x39\xff\x12\xc2\xff\x93\xef\xbb\xa9\x25\x78\x0e\x64"
-  "\xfe\x7a\xba\x0e\xcf\x81\x2c\x3f\x8c\xb9\xc5\x99\xcb\xf7\x47\x82"
-  "\x7e\x98\xa2\x41\xcd\x53\x22\xa9\x35\x3f\x23\x0f\xef\x1a\x34\xd6"
-  "\x62\xa1\xe9\xd2\xd4\x4b\xc0\xfb\x2e\xd4\x95\x4e\xbe\x84\x30\xd7"
-  "\xb9\xa0\x38\x3f\x46\xbb\x78\x19\xfe\xeb\xaf\x5d\xfc\xee\x99\x0b"
-  "\x8a\x5a\x66\x1d\x90\x4c\xc8\xcf\xf2\xe8\xb0\x6c\xfc\x8d\x16\xea"
-  "\x2d\x55\xb8\x9e\xae\xdd\x35\x47\x4f\xbd\xd3\x82\xd0\x3b\x8b\x91"
-  "\x1b\x5e\xf3\xa2\xb4\x2f\x2e\x47\x6d\x68\xb8\xe9\x0c\x0d\x7c\xaa"
-  "\xf6\x9b\x0b\x7a\xaa\x08\xce\xe3\xf5\x48\x1b\xd4\x5e\xda\x15\x50"
-  "\x76\x28\x97\x7e\xc3\x7a\xfa\x94\xc1\x67\x72\x99\x9b\x16\x51\x4d"
-  "\xef\xea\xc1\x5e\x3f\x32\x1c\x65\x15\x9c\x5b\x0d\xe7\xc8\xf7\xc3"
-  "\x5a\x37\xf3\xbb\x67\x06\xe0\xb8\x06\x38\x56\x5c\x51\xe8\x0b\xf1"
-  "\xba\x4f\x90\xaf\x01\x97\x05\xef\x8f\x6b\xda\x32\x34\xda\xbc\x65"
-  "\x68\xbc\x31\x6f\xf2\xd6\xe6\xbc\xc9\xf9\x38\xe6\x4d\xf4\x67\xbe"
-  "\x93\xc3\xf5\xe7\x98\x75\x27\x9b\x73\x5f\x2c\xc6\xfc\xeb\xba\x7a"
-  "\x66\xc9\xf5\xdc\x99\x41\x47\x53\xf2\x91\xf6\x65\x1c\xef\xf4\xe5"
-  "\x61\xf9\xb4\xe9\xf1\x08\x88\x77\xf9\x9f\xa1\xef\xc6\x42\xbc\x8b"
-  "\xb4\x8f\x77\x64\x5c\x81\x19\x91\xb8\x57\x89\x40\x03\xd5\xe2\x7a"
-  "\x83\x79\xe9\x8e\x16\xa8\x57\x50\x27\x30\xf6\x99\xf8\x07\xb1\xcf"
-  "\x5a\x3f\x70\xdd\xc1\xf1\x8d\xa9\xab\x6d\xea\x0a\xae\x1f\xf7\x1b"
-  "\x90\x0a\xd7\x0f\x1c\xff\x70\xfd\xc0\xe3\x75\xde\x67\xeb\x87\xf7"
-  "\x29\xa4\xfa\x00\x62\x5f\xb5\xa9\x8c\xa9\x23\xb8\xfc\x15\x26\x9b"
-  "\xb8\x87\xbf\xfb\xd8\xd4\x8f\x4c\x6b\xfd\xb0\xc6\x3d\xa8\x03\x26"
-  "\x5c\x3f\x16\xea\x1e\x69\x59\xc8\xd5\x8f\x29\xa7\x55\x88\x89\x89"
-  "\xef\xfe\x2b\xa5\x00\xea\x07\xee\x33\x33\x5b\xe3\x1e\xd4\x0f\x3c"
-  "\x9f\x88\x89\x7b\x6f\x43\xdc\xab\x87\xb8\x67\x80\x74\xa8\x17\x45"
-  "\x33\xd9\xb8\xc7\xd6\x87\xe6\x85\x6c\xdc\xbb\xac\x45\x2d\xfd\x71"
-  "\xdc\xfb\x40\x84\xaf\x9c\x6e\x13\xf7\xce\x8d\x90\x17\xf7\xce\x31"
-  "\xe3\x5f\xb0\x0f\x5b\xc0\x9f\xd8\x8f\x61\x1a\xda\x54\x91\x0f\xf1"
-  "\x6e\x42\x27\xf3\xdb\x7c\x61\xbf\xed\x64\xdb\xab\xee\xe0\xb3\xee"
-  "\xf5\xc8\x0b\xc7\x37\x1c\xd7\x0a\x45\xfc\x06\xf7\xd6\xd3\x4d\x42"
-  "\xbe\x3b\x72\xac\xc0\x26\xb6\xe1\x98\x86\xe3\x1b\x8e\x6b\x38\xc6"
-  "\xe1\xf1\x14\x50\x47\xea\x70\x7c\x7b\x2c\x85\xc4\x35\x1c\xef\xd2"
-  "\xce\x93\x58\x57\x19\x77\x0e\xa5\x8d\x41\x7d\xab\xf7\x99\x11\xde"
-  "\xab\x0b\xb7\x65\xd5\xa6\x1b\x08\xef\xbd\x85\x63\x1c\xf6\xed\x86"
-  "\x46\x12\xe3\x70\xbb\x86\xe3\x99\x5d\xbb\x06\xbe\x05\x9f\xe8\x70"
-  "\xbb\xc6\xf4\x4b\x50\x7f\xb8\xaf\x10\xeb\x90\x9e\xc8\x2d\xb7\x27"
-  "\xf2\x68\x7a\xb7\xd6\xcf\x5e\x8b\xd4\x06\x5a\xb5\x08\xae\xe3\xb8"
-  "\xae\xeb\x15\xfa\x58\x46\xc3\xf6\x79\x16\xea\xbb\x9e\xec\xc1\x9c"
-  "\xfb\x9a\x81\xe8\xa1\x4b\x13\x99\xdf\xa0\xf9\x39\xbd\x5f\xbb\x92"
-  "\x7c\xd7\x07\x7d\xef\x13\x66\xa4\xf3\xbc\x74\xd8\xc6\x6c\x4c\xa8"
-  "\xa7\xf3\xa2\xd2\x31\xd6\xa2\xfc\x91\x87\x29\x2f\x6a\x85\x39\x2f"
-  "\x6a\x15\xc1\x5d\xed\xde\x23\xc9\x08\x4d\x4c\x96\x8a\xbb\x5a\x66"
-  "\xff\x5f\xfa\x97\xc8\x3f\xd0\x53\x22\xdd\x2c\xbf\x44\xba\x03\x46"
-  "\x34\x73\xcd\xe9\xa8\x31\x3b\x75\x6b\x9a\x89\xae\xd3\x2e\x46\x8f"
-  "\x43\xac\xf4\x29\x37\x21\x54\xde\x80\x50\xf5\xd8\x59\xe0\xef\x54"
-  "\xdd\x2e\x8b\xc1\x4d\xaf\x38\x53\x0f\x7a\xb1\x0e\x62\xaf\x9b\x6d"
-  "\xec\x25\x71\xf6\x4c\x3d\x33\xa6\x3c\x3b\x75\x1f\xce\x2b\xbc\x0c"
-  "\x79\x43\xfb\xeb\x76\x41\x71\x61\xff\xa2\xa5\x08\xcf\x85\x75\x87"
-  "\xff\x57\xb6\xf4\x7c\x49\x07\xf7\x7b\xd1\xbf\x4c\x50\xc4\xff\x19"
-  "\xf5\xa5\xa7\x4c\x50\xe0\x71\x0c\xdb\x2c\xc5\x94\x05\xd2\xc8\xb8"
-  "\xa8\x62\x84\xcf\x67\xb4\xb8\x31\xbc\xcc\x02\xd7\x54\x35\x14\xa3"
-  "\x8c\x24\x0f\x84\xaf\x27\x63\xed\x8a\x11\xbe\x3e\x73\xbe\x8a\x19"
-  "\x07\xc1\xdc\x67\x2a\x46\xf8\x5e\x33\xa4\xbf\x67\xf1\x44\x59\x8b"
-  "\xd5\xa8\xbc\xa2\x8a\xc9\xa3\xbc\xe2\xff\x21\x9c\x07\x8e\xf5\xe5"
-  "\x15\x5f\xa3\xb5\x49\x1a\x88\x09\xc5\x70\xfe\x47\xb4\xf6\x8a\x2f"
-  "\xfc\xbd\x00\x47\x23\xba\xa4\xb8\xe0\x57\x5e\x61\x41\xde\xcb\x46"
-  "\xd2\x10\x8b\xe8\x6a\x3c\xbf\x32\x15\xdd\x07\x65\x1f\x88\xdf\x4f"
-  "\xaf\x38\xaf\xc6\xf3\xef\xab\x6b\xb2\x11\x9d\x36\xa5\xde\x42\x4f"
-  "\xb9\x6c\x49\x9b\x72\x05\x3f\xdf\x4c\x4f\xf9\x1d\x3f\x3f\x73\xb1"
-  "\x96\x1d\x7f\x5b\xcc\x8c\x15\xcc\x68\xf4\x43\xb8\xbc\xf8\xd9\xf8"
-  "\x99\x6b\xe7\xeb\xd8\xe7\x0e\x60\xca\x87\x9f\x8b\xf3\xb5\x7d\x2e"
-  "\xde\xdf\x5e\xfb\x2a\xf3\xdc\x2d\xf0\xb7\x07\xf8\x44\x83\x7d\x81"
-  "\x9f\x6b\xa1\x23\xdd\xe9\xb4\x48\x25\x73\x8f\xb1\x4e\xe8\x9e\x93"
-  "\xec\x3d\xcc\x58\x09\x7c\x4f\x33\xcd\x5c\xcf\xe4\x01\xed\x23\x33"
-  "\x4e\xe4\x89\xc8\x52\x64\xef\xc7\x5f\x73\x48\x7b\xf9\x6b\x0c\x69"
-  "\x2f\x89\x5f\x19\xbc\x4c\x89\x74\x07\xdf\xa9\x70\xdb\x7a\x4e\xf1"
-  "\xeb\xb0\x9b\x79\xfc\x12\xa9\xc4\x3e\xc7\xd8\xb1\xe2\x09\x63\xc9"
-  "\x8a\x23\xa6\x9c\x06\x84\x6c\x71\x03\xff\x7b\xb0\xf9\x2c\xb3\xe6"
-  "\x03\x65\x40\x56\x2c\x3d\x01\xe7\xed\xb1\x74\x71\x1a\x87\xa5\x3a"
-  "\xb3\x31\x95\xa6\x31\x96\x4a\x27\x2f\xc7\xf9\x94\x73\xe5\x99\xa0"
-  "\xc0\x38\xbb\xc3\xf0\xe5\x67\xf5\xd5\x13\x29\x48\x4d\xde\xa9\x8e"
-  "\x99\x07\xfa\x44\x4a\xa9\x1a\x97\xd7\xfa\x2e\xb8\x1c\x59\x16\x2d"
-  "\xb2\xbe\xcb\xda\x16\x3f\xc8\xfb\x0a\x62\xef\x39\x8e\xf3\xb7\xda"
-  "\x01\xfc\x86\xac\xf7\x58\xaf\xcf\xb2\xe8\xa0\xec\x03\x98\x7b\x08"
-  "\xee\x2e\x08\x60\xe8\xe2\x43\x6d\x71\x77\x7f\x0a\x02\x22\x0c\x1c"
-  "\x6b\xf2\x35\x78\xce\x45\xe2\xff\x94\x6f\xcc\xcd\xbf\x44\x62\xdf"
-  "\x52\x6c\xfa\x78\x1b\x5c\xb0\xf9\x1b\x85\xf2\x5f\xca\xcb\x3f\x12"
-  "\xf2\x4f\x86\xfc\x31\x87\x9b\x8c\xfb\xee\x2e\x32\xfb\xbe\x3e\x91"
-  "\x4c\xf2\xb7\x62\x97\xce\x0e\x2b\x88\x5f\x8c\xc7\xac\x5e\x0a\x22"
-  "\x71\xf5\x4c\x1e\xbe\x8e\x19\x2b\x45\x59\x8a\x2d\x6d\xc6\x4a\xd9"
-  "\x8e\xa5\xdb\x95\x6a\x60\xc7\x49\x5d\xea\x87\xaf\xc1\x7d\x64\x98"
-  "\x8b\xee\xb8\x50\x43\x71\x63\xa5\x7e\xc6\xe7\xfd\x4b\x93\xce\xd9"
-  "\x8c\x95\xba\x68\x22\x75\xff\xd2\x84\x26\x0a\x51\x70\x5e\x45\xd2"
-  "\xcf\xe4\xda\xa6\x73\x63\x11\x49\x3a\x1e\xe7\xcd\xf6\x17\xd7\x7f"
-  "\xbb\x0f\xf7\x17\x5e\x9a\x65\xed\xa3\x15\xd1\xc0\x12\xb8\x72\xc3"
-  "\x29\x8e\x2b\x37\x9c\x12\xe7\xca\xbf\xf5\x76\xcc\x95\xaf\xf9\x71"
-  "\x5c\xd9\xb0\x92\xd4\x7d\xc3\x0c\x52\xf7\x0d\xfe\x8c\x2d\x7b\xd1"
-  "\x75\xe6\x8f\x12\x8b\xab\xdc\x10\x83\xa1\x8d\xc0\x3d\x76\x2d\xae"
-  "\x69\xc3\x95\xf1\x18\xb3\xdf\x57\xbf\x04\x5c\x99\xce\x7d\x91\xed"
-  "\x03\xfc\x2d\x06\x6c\xaf\xac\x36\x1a\x11\x4e\x87\xb6\xad\x16\xf3"
-  "\xe4\xaf\x2d\x35\x54\x11\xd8\x0f\x0e\xe0\xd1\x89\xf1\xb6\x3c\xba"
-  "\xe9\xdd\xdf\xb2\x85\xf9\xf3\xef\xa3\x4d\x3c\xfe\xfc\xdb\x69\x2b"
-  "\x7f\xc6\xe5\xc3\x9c\x19\xf3\x67\x13\xee\x83\xed\x3f\x34\x1e\xf3"
-  "\x67\x53\x9e\x2d\x7f\xbe\xbc\xfb\x26\x7f\xee\x65\xc3\x9f\x93\xad"
-  "\xfc\xb9\xbe\xeb\x3d\xfe\x7c\xbb\xf8\xb3\xb5\xdf\xa0\x2d\x7f\xbe"
-  "\xbc\x54\x1e\x7f\xbe\x9c\x72\xb7\xf0\x67\xc1\x7e\x01\x01\xbf\x01"
-  "\xce\xeb\x4d\x02\xfc\x99\x06\xfe\xbc\xd1\x01\x7f\xc6\xf5\x03\x73"
-  "\x67\xcc\x95\x1f\x8b\x05\x2e\x02\xb1\x01\x73\x66\x2b\x87\xb6\x72"
-  "\x67\xcc\x99\x31\xb7\xb6\xed\x0f\x92\xc6\x9f\x2f\xc7\x71\xfc\xb9"
-  "\xe7\xd5\x02\x1e\x7f\xfe\x3d\xd6\x9e\x3f\xff\x9e\x6c\xcf\x9f\x7f"
-  "\xdb\xcc\xf1\xe7\xdf\x42\xf8\xfc\xf9\x46\xa6\x3d\x7f\xfe\xfd\x88"
-  "\x18\x7f\xc6\x9c\x19\xf3\x67\xac\x3b\x30\x77\x86\xff\x57\x71\xb8"
-  "\xfb\xfd\x86\x3c\xfe\xfc\x7b\x83\x73\xfc\xd9\x30\x51\x98\x3f\xff"
-  "\xa6\x11\xe7\xcf\xbf\x69\x84\xf9\xf3\xd5\x1b\x1c\xe7\xb9\x7a\xa8"
-  "\xf3\xf3\xe7\xab\xb1\xc2\xfc\xe6\xea\x6c\xcc\x21\xf4\x0a\xc3\x04"
-  "\xcc\x9f\x6f\x2d\x77\x36\x4c\x10\xe6\xce\x57\xcf\x12\x8e\x61\x88"
-  "\xb4\xe7\xce\x70\x8f\x20\x77\xbe\xe6\xc3\xde\x33\x81\xcf\x9d\x49"
-  "\x1e\xd0\x5e\x0e\x12\xe7\xce\xd7\x2a\x49\xfb\x79\xad\x90\xb4\x9f"
-  "\xc4\xa7\xf6\xdc\xf9\x5a\x62\xfb\xdc\x99\x60\x88\x29\xa7\x28\x77"
-  "\xbe\x76\xd0\x9e\x3b\xff\xa6\x11\xe6\xce\x0d\x79\x1c\x8e\x1a\x86"
-  "\xf0\xb9\xf3\x75\xf7\x3b\x83\x3b\x8b\x62\x2b\x96\xcf\x9b\xaf\xff"
-  "\x20\x9d\x37\x37\x74\x95\xc6\x9b\x31\xe6\x84\x78\x73\xc3\xc4\xb6"
-  "\x98\xe3\xf3\xe6\x86\x79\xc2\xbc\xb9\x61\x35\x9f\x37\xe3\xfc\x85"
-  "\x78\x73\xc3\x5e\x5e\xfe\x76\xbc\xb9\xe1\x38\x9f\x37\x93\xeb\x38"
-  "\xde\x7c\x23\x99\xed\x8f\x38\x24\x9d\x37\xdf\x98\xe4\x98\x37\xdf"
-  "\x88\xe1\xf3\xe6\x1b\x83\x09\x3f\xbe\x91\x41\x78\xf3\x8d\x10\x96"
-  "\x7f\x97\xda\xa6\x73\xbc\x99\xa4\xdb\xf3\xe6\x1b\x9b\xdb\xe1\xcd"
-  "\x81\x4e\xf3\x66\x0a\x15\x94\x59\x79\x33\xfc\x6f\xe5\xcd\x16\xe0"
-  "\x92\x45\xc0\x09\xe0\xa8\xc3\xf3\x25\x70\x9d\xbb\xa0\x68\x9c\xe8"
-  "\x98\x3b\x9b\x6b\x38\xee\x6c\xf2\x27\x75\xdf\xd4\x9d\xd4\xfd\xd6"
-  "\xca\x9b\xdc\xf9\x91\xc4\xe2\xca\x15\x37\xb9\x73\xcd\xae\xc5\xc7"
-  "\xda\x70\x67\x6c\xbb\xd6\xfd\x0c\x47\x6e\x64\xc6\xa6\xe8\x71\x3b"
-  "\xff\x52\xca\x19\x3a\x03\xda\x76\x68\xc3\xf4\xc4\xbe\xad\xbd\x0b"
-  "\xa0\xad\xe4\xf8\x75\xe3\xa1\x9b\xfc\x3a\x85\xe9\xa3\xae\x61\xf8"
-  "\xf5\x5b\xc7\xa8\x42\xc8\x1f\x0e\x37\xcc\xad\x31\xc7\x06\x6e\x7d"
-  "\xa2\x70\x3d\x7d\xac\x68\x3d\x5d\xd1\xf4\x6e\x63\x83\x95\x63\x67"
-  "\x42\x5a\x16\xa4\x1d\x2e\x86\xeb\x1b\x99\xc3\x0d\x6c\x7f\xea\x1d"
-  "\x78\x26\xbe\xaf\xe9\xdd\x26\xad\xf5\x5a\x68\xa7\x4f\x10\x2e\xde"
-  "\x52\x63\xb9\xcf\x96\x8b\x37\xcd\xb6\x72\xf1\x2c\x78\x5f\xcc\xad"
-  "\xac\x5c\xdc\x02\x5c\x9c\xf6\x21\xfd\xd9\x7c\x3e\xde\x3c\xca\xca"
-  "\xc7\xb3\x6c\xf9\x78\xbc\x95\x8f\x37\x6d\x90\xc9\xc7\x6b\xee\x66"
-  "\x3e\x8e\xb9\x38\xe6\xdf\x98\x8b\x63\x6e\x8e\xf9\x38\xe6\xe6\x16"
-  "\x96\x8f\x17\x39\xc3\xc7\x81\xaf\xd1\xf7\xfd\x92\xc2\xf0\x71\x85"
-  "\x2d\x1f\x6f\xee\x2e\x8f\x8f\x37\x7b\xda\xf2\x71\xf0\x67\x8d\x54"
-  "\x3e\x8e\x7d\x6f\xf7\xdd\x15\x8f\x39\x02\xff\x61\x5f\x39\xfc\x4e"
-  "\xc7\xfa\x11\xfb\x0d\xfb\x0c\xfb\xce\x29\x3e\x0e\xb8\xab\x30\xfe"
-  "\xf7\xf8\xb8\xae\x0d\x1f\xc7\xfc\x1b\x6c\x57\x8b\x79\x79\x75\x29"
-  "\xd8\x66\x1e\x70\x73\xe0\xe5\xf2\x39\xb9\xd1\x68\xcb\xc9\x8b\x7a"
-  "\xda\x72\xf2\x16\xa3\x3d\x27\x6f\xf5\xb4\xe1\xe4\x27\xf4\x8a\xa6"
-  "\x00\x86\x8f\xbf\x85\xb9\x76\xe3\x56\x1e\x1f\xa7\x14\xe3\xec\xf9"
-  "\x78\xeb\x44\x31\x3e\x8e\xc7\xd0\xb5\xed\xcf\xb6\xf8\x58\xfb\xb3"
-  "\x5b\x57\xca\xe3\xe3\xad\x2b\x38\xbd\xd0\xb8\x82\xb4\x29\xad\x7e"
-  "\x62\x1c\xbd\x49\x65\xcb\xd1\x5b\x9b\x39\x8e\x9e\x60\xc3\xd1\x1b"
-  "\x27\x88\x73\xf4\x46\x86\x13\xd2\xaa\xd4\x7d\x38\x2f\xcc\xad\x70"
-  "\x5f\x88\x96\x99\x7f\x6f\xde\x86\xf9\x15\xee\xe3\x80\x77\x02\x8e"
-  "\x65\x4e\xb4\xe5\xea\xf8\xfb\xa1\x23\x3e\x15\xff\x16\xea\x8b\x39"
-  "\x15\xe6\x53\x56\xfe\x8b\xaf\xc7\xbc\xea\xf6\x72\x2a\xb3\x5a\x98"
-  "\x53\x99\xfb\x31\x7c\x99\x99\xb7\xd9\x6a\xc4\x6d\xe3\xad\xe5\xec"
-  "\xad\x46\x61\xce\x6e\xce\x23\xfc\xa6\xd5\x84\xfd\xc2\xe7\xec\x70"
-  "\x8f\x20\x67\x37\x97\xb3\xf7\x18\xf9\x9c\x9d\xe4\x01\xed\xf4\x79"
-  "\x71\xce\x6e\x59\x46\xda\x6d\xcb\x78\xd2\x6e\xb3\x3e\xb6\xe3\xec"
-  "\x16\x7f\x5b\xce\x8e\xfd\x6f\xcf\xd9\x09\xa6\x98\x72\x8a\x72\x76"
-  "\xcb\x3c\x7b\xce\xde\x38\x01\x73\x76\x41\x5c\x51\x68\x22\x1f\x57"
-  "\xf4\x0d\xa3\xc5\xca\xdd\xd7\xe0\xfc\x0e\xb5\xe5\xee\x77\x20\xd6"
-  "\xd4\x1c\x7f\xc7\xef\x44\xe7\x49\xe3\xef\xcc\x3d\xe5\xd2\xf8\x3b"
-  "\xc6\x9f\x00\x7f\xa7\x90\x4f\x5b\xfc\xf1\xf8\x3b\x85\x06\x09\xf2"
-  "\x77\x0a\x85\xf2\xf9\x3b\xce\x5f\x80\xbf\x53\x28\x91\x97\x7f\x5b"
-  "\xfe\x4e\xa1\x1c\x3e\x7f\x27\xd7\xdd\xe4\xef\x94\x22\x90\xed\x0f"
-  "\x69\x96\xcc\xdf\x29\x45\x6f\x87\xfc\x9d\x52\xf4\xe3\xf1\x77\x0a"
-  "\x31\xfd\x1d\x7a\x4a\x31\xd6\x88\xf9\x3b\xa5\xb0\xf2\x7a\xa3\x6d"
-  "\x3a\xc7\xdf\x49\xba\xd1\x96\xbf\x03\xa3\x6f\x5a\xa3\x88\x6d\x87"
-  "\xbf\x8f\x76\x9e\xbf\x7b\x9e\xe0\xf8\xbb\xe7\x09\x87\xfc\x9d\xa2"
-  "\x7c\x1c\xf2\x77\xaa\x9b\xea\x26\x7f\xa7\x3c\x62\x98\x38\x40\x79"
-  "\x8c\x61\xe2\x00\xe5\xe1\x2e\xc2\xdf\x2b\x04\xf9\x3b\xd5\xe5\xaa"
-  "\x0d\x7f\x3f\x85\x79\x3b\xb4\x79\xa7\x30\x3f\xc0\xe3\x47\x80\xb7"
-  "\xd7\x94\xce\x67\xae\x3b\x8d\xf9\x3d\xe6\xf4\x70\x5e\x9f\x81\xff"
-  "\xb7\x30\xf7\x9c\xc0\xe3\xb9\x18\x1e\x7f\x81\xe1\xfc\x27\x88\x4f"
-  "\xba\x8c\x80\x7b\x8f\xdd\xe4\xfc\x14\xb5\xb7\x0d\xe7\xaf\x70\xc0"
-  "\xf9\xcb\x80\xf3\x1f\x06\xce\x5f\xda\xb4\x86\xaa\xb3\xe1\xfc\x87"
-  "\x81\xf3\x97\xb6\xe1\xfc\x35\xc0\xf9\x4f\xe1\xfb\xf0\x3d\x4d\x6b"
-  "\x94\x1a\xde\xf5\x50\x56\xe6\xfa\x6b\xcc\x81\xaf\x3f\x06\xd7\x9f"
-  "\x60\x34\xc2\x1a\xe5\x68\x1b\x8d\x50\xc6\x68\x04\xea\x3e\x13\x6d"
-  "\xab\x11\x28\x65\x8e\x64\x8d\x40\xb9\x4f\x77\xa8\x11\x28\xe5\x41"
-  "\x99\x1a\xa1\xe2\x9e\x46\x90\xa9\x11\x28\xf7\x41\xb2\x34\x02\xe5"
-  "\x1e\xd0\x46\x23\x54\xdc\xd3\x08\x9d\x40\x23\x50\xee\xbe\x37\x35"
-  "\xc2\xf2\x9e\x57\x37\xf6\x24\xe3\xef\x19\x8d\xb0\xa6\x8b\xaf\x9d"
-  "\x46\x58\xd3\x25\xc0\x46\x23\x94\xe9\x29\xe5\x84\x9b\x1a\x81\xa2"
-  "\x0a\xf8\x1a\xa1\xfb\x4a\x3b\x8d\x40\x75\x59\x24\x4b\x23\x50\x5d"
-  "\xb6\xc9\xd2\x08\x54\x97\xad\xa4\x7c\xe7\x70\xf9\x66\x91\x76\xab"
-  "\x4b\xc8\x4d\xdd\x40\x51\xa3\x6d\xd3\xda\xd5\x0d\x94\xc7\x20\x41"
-  "\xdd\x40\x51\x6a\x51\xdd\x40\x51\x6a\x51\xdd\x40\x75\x3d\xcb\xe3"
-  "\x77\x54\xd7\x1d\x77\x84\x6e\xa0\xba\x8e\x15\xe4\x72\x54\xd7\x49"
-  "\x37\x75\x03\xe5\x11\x70\xcb\x75\x03\xe4\x29\xa8\x1b\xa8\xae\x95"
-  "\x0c\xaf\xa2\x3c\x06\xdb\xe9\x06\x7c\x8f\x90\x6e\xa0\xba\x29\xd8"
-  "\x7b\x02\x78\xba\x81\xcd\x03\xf8\xc1\x43\xa2\xba\x81\xea\xb6\x9f"
-  "\xf0\x85\x6e\xab\x09\x5f\x60\x7d\xdc\x56\x37\x50\xdd\x62\xda\xd5"
-  "\x0d\x2c\xa6\x98\x72\x8a\xe9\x06\xaa\xdb\x36\x3b\xdd\x00\xcf\x14"
-  "\xd7\x0d\x9e\x99\x7c\x5c\x79\x0e\xe4\xe9\x06\xaa\x5b\xf3\x1d\xa3"
-  "\x1b\xc4\xb1\x36\x96\xa7\x1b\xa8\xfb\x2b\x25\xeb\x06\xca\x53\x21"
-  "\x49\x37\x30\xf8\x13\xd2\x0d\x9e\xe3\xda\xe2\x8f\xaf\x1b\x3c\x67"
-  "\x08\xeb\x06\xcf\x65\xc8\x56\x37\x30\xf9\x0b\xe9\x06\xcf\x1d\xbc"
-  "\xfc\xed\x74\x83\x67\x39\x4f\x37\xb0\xd7\x71\xba\xa1\x7b\x3c\xdb"
-  "\x6f\xb3\x5f\xba\x6e\xe8\x3e\xde\xb1\x6e\xe8\x3e\x89\xaf\x1b\xba"
-  "\x0f\x20\x31\xb5\xfb\x0a\xa2\x1b\xba\x07\xb1\xfa\x63\x9f\x6d\xfa"
-  "\x4d\xdd\xc0\xa6\xdb\xeb\x86\xee\x05\xed\xe8\x06\x4f\xd3\xe6\xa1"
-  "\xd1\x2d\x7e\x43\xe3\x5b\x72\x67\x66\x3f\x51\xfb\xb0\xf9\xe6\xbe"
-  "\x07\xd1\xd0\xd6\x9f\x02\x4e\x11\x83\x28\xbc\xd6\x40\xea\x71\xe0"
-  "\x78\x31\x64\x8e\x00\xe6\x0f\x3b\x93\x30\x7f\x28\x75\x07\x9b\xa2"
-  "\x56\x75\x70\x90\x69\x40\x58\x3a\xe6\x10\xcd\x9b\x87\x06\x19\x73"
-  "\x27\xe7\x37\xe3\xf9\x01\xb3\x10\x15\x55\x2f\xcc\x29\x96\x9c\xa2"
-  "\x2d\x80\x79\x8f\xf0\xa9\x84\x4f\x54\xc6\x9d\x67\x70\x8c\xb9\xc4"
-  "\x07\xc0\x25\xaa\x1b\x6a\x18\x6e\xe1\x19\xad\x45\x05\xa9\x48\xdd"
-  "\xbd\x1e\xa9\xba\x2b\x14\xf7\xbd\x38\x09\x21\x33\xf0\x8a\x31\xfe"
-  "\xb4\xe5\xf1\x5a\x2d\x5e\x2b\xc8\x8b\x70\x8b\x7d\xee\x26\x96\x5b"
-  "\xbc\xd7\x88\x06\x14\x26\x01\xa7\xa8\x24\x9c\x02\xef\x91\xd0\x4c"
-  "\x38\x45\xdf\x96\x26\xdd\x23\x37\xe7\x07\xdc\x9c\xf7\xc1\xcd\x0f"
-  "\x68\xcd\xe1\xf8\x04\xe6\x12\x74\x94\x0e\x3d\x65\x24\xe3\x36\x16"
-  "\x8f\x27\x63\x66\x07\xd4\x82\x8e\x79\x1d\x79\x54\x44\x9f\xc3\x73"
-  "\xf7\x35\x15\xb5\x5b\xd0\xa2\x50\xd4\xd7\x84\xf9\xc3\x72\xba\xa4"
-  "\xa2\x36\x0f\xe1\x75\x10\x81\x5f\x06\xe6\xb3\x1c\x62\x6c\x8c\x08"
-  "\x87\x80\xb6\x1a\xf3\x08\xd2\x46\x7b\x8f\x3b\xa2\x3b\x82\xa4\x73"
-  "\x43\x6f\xd1\xfd\xef\x18\x5e\xb2\x79\x68\xbc\xc9\x6f\x68\x90\x59"
-  "\x3d\x33\x9b\xac\x8b\x19\x55\x6a\xf9\x28\xa9\x04\xaf\x77\xf8\xf9"
-  "\xb9\x3a\x05\x5e\xe3\x1b\xef\x77\x69\xd9\x1e\x96\xce\x9b\xd3\xd1"
-  "\xca\xfa\xac\x95\xf8\x0c\x73\xc0\x69\xf5\x88\x8e\x32\x51\x08\xce"
-  "\x79\x31\x73\x3a\x8c\x7a\xc4\xed\x7b\xa9\xc1\x6b\x52\x31\x6b\x4b"
-  "\x5a\x96\xc4\x75\xb5\x80\x5f\xe8\xe5\x14\xda\xd1\x68\x64\x78\x5f"
-  "\x06\xde\x0b\x73\x99\xa2\x3b\xe6\x7d\x80\xfd\x6e\x1b\x5b\xc0\x47"
-  "\x67\x89\x8f\xe8\xe5\x1e\xcc\x5f\xd3\x12\x9d\x16\xf2\x7e\xa4\xb5"
-  "\x15\x78\x1f\xbb\x6f\xa6\x75\x9d\x5d\x66\x7e\x4e\x0b\x9e\x9f\x53"
-  "\x83\x4c\x39\x64\xed\x42\xc0\x85\x02\xaf\x0b\x02\x65\xf0\x65\xe6"
-  "\xe5\xb4\xea\x30\x8e\x54\x45\x17\xf0\x5c\xa2\x9f\x19\xff\x98\x59"
-  "\xbf\xe0\xfd\x33\xad\x7c\xae\x6a\xeb\x0f\x64\x6e\x66\x1b\x5f\xb4"
-  "\x6e\x19\x1a\x64\xf5\x07\xbd\xa6\x7b\x09\x1e\x6f\x73\x85\x52\x9d"
-  "\x3f\x92\x00\xdc\x29\x41\xaa\x5f\x54\xb5\x9d\xc3\x2f\xaa\xbb\xcc"
-  "\x2f\xde\xb9\xc4\x2f\x3d\x97\xca\xf3\x4b\x4f\xd1\xf9\xff\x1d\xeb"
-  "\x17\x8f\xbb\xcc\x2f\x3d\x06\x10\xbf\xa8\x7d\xe4\xf9\x45\xad\x76"
-  "\xe4\x17\xdc\xc7\x65\xed\xdf\xb2\xf6\x6d\xe1\xf6\x94\xe8\xa2\x07"
-  "\xf5\x37\xc7\x73\xc2\xff\xb6\xe3\x39\x2b\x0e\xe3\x39\xf9\x6b\xd0"
-  "\xd1\xd1\xb8\xad\x54\x5f\x74\xdc\xa7\xd5\x9b\x1b\xcf\x49\x3d\x40"
-  "\xfa\xb6\xa9\x07\xa6\x13\x8e\xfa\x00\xb3\x9f\x17\x9e\xf7\x84\xe7"
-  "\xce\xed\x4a\xd2\x53\x99\xc0\x15\x33\xa1\x2d\xc7\xb6\x67\xd6\x72"
-  "\xa7\x7a\x15\xe2\xfe\xaa\x6f\x1a\xf5\x54\x36\xd8\x9e\x69\x2f\x1f"
-  "\x49\x2a\xd9\xde\xc7\xa0\xc0\x6d\x26\x5e\x5b\x96\xb6\x99\x0b\x69"
-  "\xce\x9b\x99\x7d\x1d\xf7\xe3\xb0\xf3\x96\x5a\x7c\x26\xe7\x9b\x07"
-  "\x86\xa5\x0b\xe1\x89\x99\x63\x09\x6d\x66\x61\x0b\xb4\x87\x0d\x48"
-  "\xf5\x7a\x3c\x87\x2d\xcb\x12\x5d\xcf\x2a\xe0\xe8\x85\x78\x8d\x5f"
-  "\x68\x2b\xe9\xd6\xb8\xae\x53\xb6\x41\x59\x59\x4c\xc1\xb3\xc5\x31"
-  "\xb5\x81\x8f\xa9\xeb\x2c\xa6\x00\x5b\x37\x31\x65\x33\x47\x32\x85"
-  "\x60\x4a\x7f\x13\x53\x4c\x5b\xb9\x44\xe7\x8b\x71\x65\xc5\x14\x6e"
-  "\x27\x09\xa6\xce\x89\x62\xea\xbb\x53\xc2\x98\x32\xf5\xb7\xc5\x54"
-  "\xcf\xc3\x04\x53\xbd\x66\x1c\x99\x0a\x98\x9a\x2a\x15\x53\xbd\xe2"
-  "\xf8\x9a\xda\xd7\x7e\x1c\x1c\xd5\xab\xb2\xad\xa6\xb6\x6a\xe8\xeb"
-  "\x3e\x51\xe9\xd7\x41\x47\x37\xdc\xd4\xd1\xbd\xae\xca\xd3\xd1\xbd"
-  "\x0c\x4e\x8d\x7d\xa3\x1e\x18\x7f\x14\xa2\xd3\x51\xa8\x3f\xd5\x11"
-  "\x64\xec\xdb\x76\x46\x1f\xab\xeb\x31\xee\x84\xf5\x31\x39\x67\x37"
-  "\x66\x89\xd2\x70\x63\xdf\x28\xcd\xa1\xe6\x75\xc2\x63\xdf\x3e\x4b"
-  "\xcd\xb7\xd1\x2a\xf9\x02\xe3\x93\xf2\xdb\x8c\x4f\xca\x17\xd0\x29"
-  "\xf9\x08\xdf\x6b\xab\x53\x8e\x46\x10\x9d\x72\x34\x02\xeb\x94\x7c"
-  "\x86\xdf\x1d\x8d\xb0\xea\x94\x7c\x38\x4f\x74\xca\xd1\x88\x0b\x70"
-  "\x60\x9d\xa2\x89\x3e\x1a\x21\xa4\x53\x34\x33\x08\xef\x7d\x20\xc2"
-  "\xf1\xdc\x91\x7c\x1b\x4d\x9c\x6f\xa3\x89\xf3\x59\x4d\x9c\xcf\x68"
-  "\x62\xf2\xdc\x01\x4c\xf9\xf0\x73\x71\xbe\xb6\xcf\xe5\x34\x83\x86"
-  "\x8c\x7f\xa3\x1e\x98\x80\x7d\xc1\xd7\xc4\x70\x4f\xb2\x90\x26\xee"
-  "\xed\xc3\xde\x13\x61\xd5\xc4\x2d\xe4\x7a\x26\x0f\x88\x2f\xe2\xe3"
-  "\xdf\xa8\xde\x64\xfc\x1b\xd5\x9b\x8c\x7f\x63\xfd\x6a\xaf\x89\x7b"
-  "\xb7\x3f\xfe\x8d\xc5\x11\x53\xce\x78\x31\x4d\xdc\xdb\x7e\xfc\x1b"
-  "\xa5\xae\x13\x1c\xff\x46\x3d\xb8\x81\xc3\xd2\x83\xc3\x78\xe3\xdf"
-  "\xa8\x3e\xbc\xf1\x6f\x18\x67\x77\x18\xbe\xa2\xed\xe6\x8e\x50\x7d"
-  "\x4e\x0a\x6b\xe1\x7c\x1b\x2d\x9c\xcf\x68\xe1\xa3\x11\xec\x18\x38"
-  "\xea\xc1\xee\x38\x7f\x7b\x2d\x9c\x7f\xf3\x7a\xab\x16\xc6\xf7\x10"
-  "\xdc\x09\x69\xe1\x07\x27\xb5\xc5\x1d\x5f\x0b\x3f\x98\x68\xd5\xc2"
-  "\x2d\x53\x6c\xb5\xf0\x83\x99\x7c\x2d\x8c\xf3\x17\xd2\xc2\x0f\xee"
-  "\xe7\xe5\x6f\xa7\x85\x1f\xfc\xc1\xaa\x85\x71\xfe\x56\xec\x72\x5a"
-  "\xd8\x97\x8c\x81\xa3\xd4\x39\xd2\xb5\xb0\x2f\x33\x06\x6e\xc7\x07"
-  "\xe4\x1b\x15\x5f\x07\xfb\xf2\xc7\xbf\x51\xbe\x64\xfc\x1b\xe5\x4b"
-  "\xc6\xbf\x51\xbe\x64\xfc\x1b\xa5\xce\xb6\x4d\xe7\x74\x30\x49\xc7"
-  "\xe3\xdf\x98\x71\x6f\x6b\x7c\x25\xea\xdf\x07\x3a\xa1\xfe\xd5\x38"
-  "\xd0\xbf\x9a\xbb\x4c\xff\xf6\x95\xa9\x7f\xfb\x76\x12\xfd\x7b\xb7"
-  "\xe9\x2c\x5f\x56\xff\x3e\x2c\x53\xff\x3e\xdc\x49\xf4\xef\xdd\xa6"
-  "\xb3\xfa\xb2\xfa\xb7\x9f\x4c\xfd\xdb\xcf\xa1\xfe\x75\xac\xb3\xfc"
-  "\x43\x38\x9d\xe5\x1f\x22\xae\xb3\x1e\x19\xef\x58\x67\x3d\x9a\xc1"
-  "\xe9\x2c\xbf\x8b\x84\xf7\xf8\x55\x12\xde\xe3\x97\xd9\xbe\xce\xf2"
-  "\x73\xbf\xa7\xb3\x6e\xa5\xce\xd2\xb2\xda\xfd\x8f\xc7\xe5\xe9\xac"
-  "\x3f\x1e\xe3\xeb\x2c\xff\x1b\xf6\x3a\xcb\x6f\x88\xf3\x3a\xcb\x6f"
-  "\x92\x3c\x9d\xe5\x17\xe9\x9c\xce\xf2\xdb\x2f\xac\xb3\x1e\x99\x20"
-  "\xae\xb3\xc8\x39\x7b\x6e\xfc\x28\x37\xaf\x9a\x7a\xd4\xbf\xf3\xeb"
-  "\xac\xfe\x65\xc2\x3c\xb8\xff\x71\xc2\xab\xfc\xf6\xdd\x1e\x9d\xe5"
-  "\xb7\x4f\x58\x67\x3d\x1a\x4a\xf8\xa8\xdf\x01\x7b\x9d\x05\xf7\x08"
-  "\xea\xac\x47\x97\xb2\xf7\xec\xe3\xeb\x2c\x92\x07\xc4\x97\x0d\xe2"
-  "\x3a\xeb\xb1\x21\x24\xde\x3c\xe6\x4e\xe2\x0d\xf1\xab\xbd\xce\x7a"
-  "\xf4\x74\xfb\x3a\x8b\xe0\x88\x29\xa7\xa8\xce\x7a\xac\xbf\xbd\xce"
-  "\x7a\x24\x42\x58\x67\xf9\x2b\x38\x2c\xe9\x36\xf1\x75\xd6\x63\xb3"
-  "\xef\x0c\x9d\x25\x8a\xaf\x32\x7b\x9d\xa5\x1b\x25\x5d\x67\xe9\x12"
-  "\xa5\xe9\x2c\x8c\x3b\x21\x9d\xa5\x3b\xd4\x16\x77\x7c\x9d\xa5\x3b"
-  "\x2d\xac\xb3\x74\x37\xf8\x3a\x0b\xe7\x2f\xa4\xb3\xfc\xfb\xf1\xf2"
-  "\xb7\xd3\x59\xfe\x23\xf8\x3a\x8b\x5c\xc7\xe9\x2c\x7f\x3d\x89\xa5"
-  "\xfd\x64\x8c\x55\xf4\x3f\x24\xae\xb3\xfc\xcb\xf9\x3a\xcb\xbf\x80"
-  "\xd4\x7b\xff\x06\xa2\xb3\xfc\x4b\x48\x7a\x3f\xa3\x6d\x3a\xa7\xb3"
-  "\x48\x3a\xa7\xb3\x1e\x77\x93\xa6\xb3\xbc\x3b\xa1\xce\x52\x39\xd0"
-  "\x59\xaa\xbb\x4c\x67\x3d\xb1\x57\x9e\xce\x7a\x62\xcf\x3d\x3e\x7f"
-  "\x3b\xf8\xfc\xe3\x1a\xc2\xbd\x06\x8e\x93\xc7\xe7\x07\x3a\xd4\xbf"
-  "\x8e\xf9\xfc\x10\x0d\xc7\xe7\x87\x68\xc4\xf9\xfc\x93\xfd\x1c\xf3"
-  "\xf9\xa7\xa7\x72\x7c\x3e\x80\x1d\xdb\x13\xc0\xf6\x63\x06\x4c\x6b"
-  "\x9f\xcf\x3f\xf5\xc3\x3d\x3e\x7f\x2b\xf9\xfc\x13\x26\x82\xa9\xa7"
-  "\x36\xc9\xe3\xf3\x4f\x15\xf3\xf9\xfc\x90\x23\xf6\x7c\x3e\xc0\xdd"
-  "\x79\x3e\x1f\xe0\x2f\x8f\xcf\x07\xe8\x9c\xe3\xf3\x01\xab\x85\xf9"
-  "\xfc\x93\x7e\xe2\x7c\x9e\x9c\xb3\xe7\x60\x4f\x0f\xe4\x38\xd8\xa0"
-  "\xe6\xce\xcf\xe7\x07\xe5\x0b\xf3\xad\x41\x9b\x48\xfb\x1d\xb0\xea"
-  "\xf6\xf0\xf9\x80\x55\xc2\x7c\xfe\xe9\xde\x84\xf7\x04\x64\xd8\xf3"
-  "\x79\xb8\x47\x90\xcf\x3f\xcd\x8e\xff\x0a\x58\xc5\xe7\xf3\x24\x0f"
-  "\x88\x2f\x33\xc4\xf9\xfc\xff\xb8\x93\x78\xf3\xf4\x0f\x24\xde\x10"
-  "\xbf\xda\xf3\xf9\xa7\x77\xb4\xcf\xe7\x09\x8e\x98\x72\x8a\xf2\xf9"
-  "\xa7\x6f\xd8\xf3\xf9\x27\xb5\xc2\x7c\x7e\xf0\x71\x0e\x4b\x83\xe7"
-  "\xf1\xf9\xfc\xff\x8c\xb8\x33\xf8\xbc\x28\xbe\xf2\xed\xf9\xfc\xe0"
-  "\x1e\xd2\xf9\xfc\xe0\x31\xd2\xf8\x3c\xc6\x9d\x10\x9f\x1f\x9c\xd3"
-  "\x16\x77\x7c\x3e\x3f\x78\x87\x30\x9f\x1f\x7c\x84\xcf\xe7\x71\xfe"
-  "\x42\x7c\x7e\xf0\x55\x5e\xfe\x76\x7c\x7e\x48\x77\x3e\x9f\x27\xd7"
-  "\x71\x7c\x7e\x48\x09\x89\xa5\x03\xcb\xa5\xf3\xf9\x21\x39\xe2\x7c"
-  "\x7e\xc8\x06\x3e\x9f\x1f\xc2\x8e\xd3\x1e\x72\x98\xf0\xf9\x21\xe9"
-  "\x24\x7d\x60\x99\x6d\x3a\xc7\xe7\x49\x3a\xc7\xe7\x87\x9c\x90\xc6"
-  "\xe7\xbb\x74\x42\x3e\xef\xe1\x80\xcf\x7b\xdc\x65\x7c\x7e\xe8\x4a"
-  "\x79\x7c\x7e\xe8\x0a\xf9\xbc\x71\x64\x04\xc7\x1b\x47\x46\x88\xf3"
-  "\xc6\xc0\x49\x8e\x79\xe3\xf0\x5c\x8e\x37\x3e\x7b\x95\xc4\xf1\x67"
-  "\xd9\x38\xfe\x6c\x5e\xfb\xbc\xf1\xd9\xee\xf7\x78\xe3\xad\xe4\x8d"
-  "\x43\xea\x08\x6f\x1c\x76\x52\x1e\x6f\x1c\x56\xc3\xe7\x8d\x23\xcd"
-  "\xf6\xbc\xf1\xd9\x11\xce\xf3\xc6\x67\x63\xe4\xf1\xc6\x67\xa3\x9d"
-  "\xe3\x8d\xcf\x1e\x12\xe6\x8d\x81\x53\xc5\x79\x23\x39\x67\xdf\xd6"
-  "\x0f\x9f\xce\xb5\xf5\xc3\x07\x75\x7e\xde\xf8\xa7\x63\xc2\xed\xfa"
-  "\x9f\x4e\x92\x76\xe2\xd9\xd2\xdb\xc3\x1b\x9f\x2d\x15\xe6\x8d\xc3"
-  "\xc7\x93\xf6\xf5\xd9\xc3\xf6\xbc\x11\xee\x11\xe4\x8d\xc3\x57\xb2"
-  "\xf7\x94\xf2\x79\x23\xc9\x03\xe2\xcb\x26\x71\xde\x38\x62\x04\x89"
-  "\x37\x23\xc8\x9a\x33\xac\x5f\xed\x79\xe3\xf0\xf3\xed\xf3\x46\x82"
-  "\x23\xa6\x9c\xa2\xbc\x71\xc4\x40\x7b\xde\x18\x18\x29\xcc\x1b\x47"
-  "\x76\xe5\xb0\xf4\xdc\x36\x3e\x6f\x1c\x91\x78\x67\xf0\x46\x51\x7c"
-  "\x1d\xb3\xe7\x8d\xcf\x85\x4a\xe7\x8d\xcf\x2d\x95\xc6\x1b\x31\xee"
-  "\x84\x78\xe3\x73\xe5\x6d\x71\xc7\xe7\x8d\xcf\x9d\x17\xe6\x8d\xcf"
-  "\x99\xf9\xbc\x11\xe7\x2f\xc4\x1b\x47\xfa\xf3\xf2\xb7\xe3\x8d\x23"
-  "\xc7\xf0\x79\x23\xb9\x8e\xe3\x8d\x23\xeb\x48\x2c\x0d\x54\x48\xe7"
-  "\x8d\x23\xcb\xc5\x79\xe3\xc8\xe3\x7c\xde\x38\x72\x33\xa9\xf7\x23"
-  "\x4d\x84\x37\x8e\xdc\x47\xd2\x03\x91\x6d\x3a\xc7\x1b\x49\x3a\xc7"
-  "\x1b\x83\x3c\xdb\xe3\x8d\x8e\x39\x45\x70\x09\xc7\x29\x82\x4b\x6c"
-  "\x39\x45\x39\x8f\x53\x04\xed\x70\xcc\x29\x46\x1b\x39\x4e\xf1\xc2"
-  "\x24\x52\xc7\x5f\x18\x41\xea\xf8\xf3\x8c\xcf\x5a\x3f\x19\x96\xbd"
-  "\xb4\x12\x51\x3b\xaf\xec\xa3\xde\x4b\x42\x6e\x19\x49\xc0\x29\x80"
-  "\xdf\xc5\x4f\xc6\x9c\xe2\xf9\xc4\x71\x29\x67\x68\xcf\x02\xe0\xb1"
-  "\xb5\x2c\xaf\x8d\x07\x5e\x5b\x0b\xbf\xa1\xbe\x1c\x9c\xb3\x8f\xaa"
-  "\x02\xee\x99\x0d\xdc\x8f\x99\xdb\xcc\xcc\x7b\xd6\xbb\x33\xfb\x67"
-  "\x5c\x01\xce\xf1\x46\xfb\xfb\x9d\x58\xf7\x3a\x49\xa9\xa5\x2d\x78"
-  "\x6f\x93\xf0\x58\x9b\x3d\x4f\xf0\x5e\xa8\x86\x3a\x84\xf7\x3d\x29"
-  "\x98\x8f\xd4\x78\xaf\x13\xef\x3a\xa4\xf2\x5a\xa6\xf0\xc2\x7b\x9e"
-  "\x78\x35\x10\xee\xba\xc3\x52\x46\xb8\xeb\x02\x4d\xb7\x8c\x6b\x68"
-  "\x40\xd1\x35\x8e\x5b\xbc\x8f\x79\xc5\x02\x9d\xb6\x61\x81\xae\xef"
-  "\xf5\xeb\xc0\x5d\x0d\x6d\xf7\xc4\x38\x72\x0c\xef\x75\x52\x9d\x4c"
-  "\xfa\x38\x99\xbd\x30\xfe\xa2\x43\x1b\xdf\x42\x1e\xb8\xaf\xf3\x49"
-  "\xbc\x1f\x46\x25\x52\x3d\xe6\x0b\xb1\xfe\xba\xce\xd7\x76\x9d\x4b"
-  "\xdc\xef\x69\xb9\xae\x43\x15\xd1\x3f\x33\xf3\x66\x4d\xd6\x79\xb3"
-  "\xd7\x50\xa0\x61\x81\x8e\xfa\x60\xbe\x0d\x77\xf5\xc1\xdc\xf5\x59"
-  "\x07\xdc\xf5\xf9\x51\xf2\xb8\xeb\xf3\x41\x7c\x9e\x11\x32\xcd\x9e"
-  "\x67\x3c\xbf\xc5\x79\x9e\xf1\x7c\xb9\x3c\x9e\xf1\x7c\x99\x73\x3c"
-  "\xe3\x05\xff\xb6\x3c\x63\x1b\xc3\x33\x82\x4a\x30\x16\x85\x79\x06"
-  "\x39\x67\xdf\x36\x8c\x2e\xe7\xda\x86\xd1\x79\x9d\x9f\x67\x8c\x0e"
-  "\x14\x6e\x07\x46\x8f\x62\xd6\xb4\xa4\x5e\xd0\x89\xaf\x69\x29\x97"
-  "\x63\xbc\xa0\x13\xe6\x18\xa3\xc9\xfa\x7f\x70\xde\xda\x06\x71\x1c"
-  "\x03\xee\x11\xe4\x18\xa3\x2f\xb6\xbd\x87\x70\x8c\x17\x06\x10\x8e"
-  "\x31\xc6\x5d\x9c\x63\x8c\xd9\x44\xe2\xcf\x98\x79\x24\xfe\x10\x9f"
-  "\xda\x73\x8c\x31\xa1\xed\x73\x0c\x82\x21\xa6\x9c\xa2\x1c\x63\x4c"
-  "\x8e\x3d\xc7\x08\xda\x2e\xcc\x31\x82\x67\x70\x38\x0a\xee\xca\xe7"
-  "\x18\x63\x4e\xde\x19\x1c\x43\x14\x5b\x81\x7c\x7e\xf1\xe7\x6d\xd2"
-  "\xf9\xc5\x9f\x4f\x4b\xe3\x17\x18\x73\x42\xfc\x22\x98\x6d\xff\x09"
-  "\x5e\xec\xf9\x45\xf0\x18\x61\x7e\x11\x3c\x8d\xcf\x2f\x70\xfe\x42"
-  "\xfc\x22\x78\x35\x2f\x7f\x3b\x7e\x11\xbc\x85\xcf\x2f\xc8\x75\x1c"
-  "\xbf\x08\x09\x21\x31\x34\x68\xa2\x74\x7e\x11\xe2\x2f\xce\x2f\x42"
-  "\x06\xf1\xf9\x45\x88\x1b\xe1\x11\x21\x53\x09\xbf\x08\xd1\x90\xf4"
-  "\xa0\x09\xb6\xe9\x1c\xbf\x20\xe9\x1c\xbf\x08\x69\x6f\xfd\xf7\x7b"
-  "\xf3\x59\x3b\x55\xbf\x54\xd8\x43\xf2\xda\xf6\x30\xdf\xce\xf1\x9d"
-  "\xf9\x6e\x9b\xcf\x1a\x92\x4e\xfa\x76\x5e\xdc\x2b\xef\x3b\xf3\x8b"
-  "\x9d\xe4\xfb\xff\xdd\x36\xce\x3a\x2c\x96\xf8\x65\x9c\xcc\xef\xff"
-  "\xe3\x3a\xc9\xf8\xf7\xbb\x6d\x5c\xc6\x8b\xec\x37\xf4\x97\x64\x8e"
-  "\x7f\x7f\xc9\xe1\xf8\x77\xc7\x5a\xf8\xd5\x52\x4e\x0b\xbf\x5a\x2a"
-  "\xde\xbf\x1e\xbe\xdf\xb1\x16\x9e\xe0\xc1\x69\xe1\x97\x67\x10\x2e"
-  "\xfa\xf2\x38\xc2\x45\x5f\x66\xbe\x57\x99\x1e\x49\x2c\x26\xfd\xeb"
-  "\xa5\x02\xfd\xeb\xe3\x57\xe2\x75\xd2\xb8\xf5\xd3\xc2\x6f\xd8\xae"
-  "\x9f\xf6\x35\xdc\x73\xaf\xdf\xfd\x56\xf4\xbb\x8f\x63\xc7\xf4\x8f"
-  "\x1f\x2f\xaf\xdf\x7d\x7c\x04\x5f\x0f\xbf\x36\xdb\x5e\x0f\x8f\xdf"
-  "\xeb\xbc\x1e\x1e\x7f\x52\x9e\x1e\x1e\x5f\xe3\x9c\x1e\x7e\x79\x98"
-  "\x70\xbf\x7b\xf8\x01\x8c\x47\x61\x3d\x4c\xce\xd9\xeb\x98\x57\x4e"
-  "\x72\x3a\xe6\x95\x2d\x9d\x5f\x0f\xbf\x12\x22\xac\x59\x5e\x19\x4f"
-  "\xf4\xf0\xcb\x81\xb7\x5e\x0f\xbf\x1c\x28\xac\x87\x5f\x39\x42\xb4"
-  "\xc3\xcb\xc3\xed\xfb\xdc\xe1\x1e\x41\x3d\xfc\x4a\x33\x7b\x4f\x20"
-  "\x5f\x0f\x93\x3c\x20\xe6\xf8\x88\xeb\xe1\x09\xbb\x49\x0c\x9a\xb0"
-  "\x8c\xc4\x20\xe2\x53\x7b\x3d\x3c\x61\x52\xfb\x7a\x98\x60\x88\x29"
-  "\xa7\xa8\x1e\x9e\xb0\xc9\x5e\x0f\x87\xef\x13\xd6\xc3\xaf\x2e\xe2"
-  "\x70\xf4\x6a\x6f\xbe\x1e\x9e\x70\xf1\xce\xd0\xc3\xa2\xd8\x0a\xe1"
-  "\xeb\xe1\x89\xfb\xa5\xeb\xe1\x89\x97\xa5\xe9\x61\x8c\x39\x21\x3d"
-  "\xfc\xea\xb0\xb6\x98\xe3\xeb\xe1\x57\x27\x0a\xeb\xe1\x57\x67\xf3"
-  "\xf5\x30\xce\x5f\x48\x0f\xbf\xba\x81\x97\xbf\x9d\x1e\x7e\x75\x2f"
-  "\x5f\x0f\x93\xeb\x38\x3d\xfc\x5a\x24\xdb\xd6\xc5\x48\xd7\xc3\xaf"
-  "\x0d\x13\xd7\xc3\xaf\x8d\xe2\xeb\xe1\xd7\xd4\x44\xf7\xbe\x36\x8b"
-  "\xe8\xe1\xd7\x74\x24\x3d\x3c\xda\x36\x9d\xd3\xc3\x24\x9d\xd3\xc3"
-  "\xaf\xa5\xdc\x9b\xdf\x7a\x27\xe9\xe1\x49\x03\xe5\xe9\xe1\x49\x03"
-  "\x3a\x07\xbf\xbf\xdb\x74\xd7\x6b\xd9\x84\x73\x4d\x3e\x22\x8f\xdf"
-  "\x4f\x3e\xdc\x39\xfc\x72\xb7\xe9\xae\x49\x09\xc4\x2f\x53\xa7\xc9"
-  "\xf3\xcb\xd4\xa9\xf2\x75\x57\x6c\x20\xa7\xbb\x62\x03\xc5\x75\xd7"
-  "\xb4\x41\x8e\x75\x57\x4c\x3a\xa7\xbb\xa2\xce\x12\xce\x13\x75\x84"
-  "\x70\x9e\xa8\x95\xed\xeb\xae\xd7\xcd\x7c\xdd\x35\x6d\xf6\x3d\xdd"
-  "\x75\x3b\x74\xd7\x14\x4f\x82\xb5\xd7\xcb\xe5\xe9\xae\xd7\xcb\xf8"
-  "\xba\x2b\xf6\xbc\xbd\xee\x8a\x1a\xe8\xbc\xee\x8a\x1a\x2f\x4f\x77"
-  "\x45\x45\x38\xa7\xbb\xa2\x76\x0b\xeb\xae\x69\x83\xc5\x75\x17\x39"
-  "\x67\xcf\x97\x63\xc6\x73\x7c\x39\xe6\xa1\xce\xaf\xbb\xa2\x4b\x85"
-  "\xb9\x71\x74\x39\xd1\x5d\x51\x25\xb7\x5e\x77\x45\x95\x08\xeb\xae"
-  "\x98\x11\x84\xa3\x46\xed\xb1\xd7\x5d\x70\x8f\xa0\xee\x8a\x99\xc7"
-  "\xde\x53\xc2\xd7\x5d\x24\x0f\x88\x39\x99\xe2\xba\xeb\x0d\xb2\xbf"
-  "\x16\x15\xd3\x4c\x62\x10\xf1\xa9\xbd\xee\x8a\x39\xde\xbe\xee\x22"
-  "\x18\x62\xca\x29\xaa\xbb\xde\xe8\x6d\xaf\xbb\xa6\x05\x08\xeb\xae"
-  "\x37\xaf\x72\x38\x7a\x33\x87\xaf\xbb\xde\x88\xb9\x33\x74\x97\x28"
-  "\xb6\x4a\xf9\xba\xeb\xcd\x41\xd2\x75\xd7\x9b\xd3\xa5\xe9\x2e\x8c"
-  "\x39\x21\xdd\xf5\xe6\xee\xb6\x98\xe3\xeb\xae\x37\x2b\x85\x75\xd7"
-  "\x9b\xe7\xf9\xba\x0b\xe7\x2f\xa4\xbb\x62\x7b\xf0\xf2\xb7\xd3\x5d"
-  "\xb1\x03\xf9\xba\x8b\x5c\xc7\xe9\xae\xd8\x63\x24\x86\x4e\x3d\x29"
-  "\x5d\x77\xc5\xee\x16\xd7\x5d\xb1\xfb\xf9\xba\x2b\x36\x83\xe8\xab"
-  "\xd8\x5a\xa2\xbb\x62\x8b\x49\xfa\xd4\x1a\xdb\x74\x4e\x77\x91\x74"
-  "\x4e\x77\xc5\x36\xdc\x9b\xef\x7a\x27\xe9\xae\xb7\xb6\xc8\xd3\x5d"
-  "\x6f\x6d\xbe\xc7\xef\x6f\x07\xbf\x9f\xee\x41\x38\x57\xdc\x08\x79"
-  "\xfc\x3e\x6e\xb8\x7c\x7e\x1f\x6f\x33\xdf\x35\xde\xc1\x7c\xd7\x19"
-  "\x3d\x1c\xf3\xfb\xd9\xd1\x1c\xbf\x7f\xfb\x10\x69\x5b\xdf\xde\x42"
-  "\xda\xd6\xb7\xa7\xb7\xcf\xef\x67\x9e\xe6\xf3\xfb\x19\xe3\xee\xf1"
-  "\xfb\xdb\xc1\xef\xdf\xaa\x27\x58\x9b\xb9\x4d\x1e\xbf\x9f\xd9\x66"
-  "\xdf\xbe\x78\x81\x79\xb0\x6f\x77\x77\x9e\xdf\xbf\x3d\x48\x1e\xbf"
-  "\x7f\x3b\xc0\x39\x7e\xff\x76\x8e\x30\xbf\x9f\xa1\x16\xe7\xf7\xe4"
-  "\x9c\x3d\x2f\x9b\x3d\x88\xe3\x65\xb3\xcc\x9d\x9f\xdf\xcf\x2a\x16"
-  "\xe6\x60\xb3\xb6\x11\x7e\xff\x76\xf6\xad\xe7\xf7\x6f\x67\x0b\xf3"
-  "\xfb\xd9\x0f\x11\x2e\xf4\x76\xae\x3d\xbf\x87\x7b\x04\xf9\xfd\x6c"
-  "\x76\xfe\xc3\xdb\xd9\x7c\x7e\x4f\xf2\x80\x98\x33\x5b\x9c\xdf\xcf"
-  "\xe9\x4a\x62\xd0\xec\x93\x24\x06\x11\x9f\xda\xf3\xfb\xd9\xbb\xdb"
-  "\xe7\xf7\x04\x43\x4c\x39\x45\xf9\xfd\xec\x66\x7b\x7e\x3f\x43\x25"
-  "\xcc\xef\xe7\xda\xcc\x81\x9d\xdb\x66\x0e\xec\x9c\x51\x77\x06\xbf"
-  "\x17\xc5\x56\x31\x9f\xdf\xcf\x95\x31\xff\x75\xae\xc4\xf9\xaf\x18"
-  "\x73\x42\xfc\x7e\x6e\x4e\x5b\xcc\xf1\xf9\xfd\x5c\x91\xf9\xaf\x73"
-  "\xdb\xcc\x7f\xc5\xf9\x0b\xf1\xfb\xb9\x57\x79\xf9\xdb\xf1\xfb\xf8"
-  "\x36\xf3\x5f\xc9\x75\x1c\xbf\x8f\x67\xe7\xbf\xc6\xc9\xd8\x43\x23"
-  "\xde\xc1\xfc\xd7\xf8\x36\xf3\x5f\xe3\xd9\xf9\xaf\xf1\xec\xfc\xd7"
-  "\x78\x76\xfe\x6b\xdc\x3e\xdb\x74\x8e\xdf\x93\x74\x8e\xdf\xc7\xdf"
-  "\x9b\xff\x7a\x47\xf1\xfb\xf9\x32\xe7\xbf\xce\x77\x61\xfe\xeb\xe2"
-  "\x68\x8e\x47\x2e\x8e\x16\xe7\x91\x0b\xda\x99\xff\xba\x70\x2b\xc7"
-  "\x23\x93\xd8\x18\x9e\x78\x99\xc4\xf0\xc4\x1d\xed\xf3\xc8\xc4\xfe"
-  "\x7c\x1e\xb9\x20\xef\x1e\x8f\xbc\x1d\x3c\x32\x9e\x9d\x17\x9b\x70"
-  "\x55\x1e\x8f\x4c\x30\xf0\x79\xe4\x92\xee\xf6\x3c\x32\xd1\x6e\xff"
-  "\x67\x71\x1e\x99\xb8\x48\x1e\x8f\x4c\x4c\x76\x8e\x47\x26\x9e\x14"
-  "\xe6\x91\x0b\xa6\x8a\xf3\x48\x72\xce\xbe\xfd\x5f\x68\x33\xae\x62"
-  "\xe1\x98\xce\xcf\x23\x93\xea\x84\xdb\xfa\xa4\xab\x84\x47\x26\xd6"
-  "\xdc\x7a\x1e\x99\x58\x23\xcc\x23\x17\x4e\x27\x6d\x6e\xe2\x29\x7b"
-  "\x1e\x09\xf7\x08\xf2\xc8\x85\xec\xf8\x87\xc4\x1a\x3e\x8f\x24\x79"
-  "\x40\xcc\xd9\x2b\xce\x23\x93\xc7\x93\x18\x94\xdc\x8f\xc4\x20\xe2"
-  "\x53\x7b\x1e\xb9\xb0\xb9\x7d\x1e\x49\x30\xc4\x94\x53\x94\x47\x26"
-  "\x8f\xb2\xe7\x91\x0b\x44\xe6\xc4\x2e\xee\xcd\xe1\x68\xd1\x7e\x3e"
-  "\x8f\x4c\x5e\x7d\x67\xf0\x48\x51\x6c\xd5\xf1\x79\xe4\xa2\x49\xd2"
-  "\x79\xe4\xa2\x4c\x69\x3c\x12\x63\x4e\x88\x47\x2e\x3a\xd9\x16\x73"
-  "\x7c\x1e\xb9\xe8\x86\x30\x8f\x5c\xdc\x9d\xcf\x23\x71\xfe\x42\x3c"
-  "\x72\xf1\x30\x5e\xfe\x76\x3c\x72\xf1\x44\x3e\x8f\x24\xd7\x71\x3c"
-  "\x72\xb1\x91\x6d\xeb\x64\xcc\x87\x5d\x7c\x52\x9c\x47\x2e\x3e\xcb"
-  "\xe7\x91\x8b\xf7\x10\xbe\xb8\xc4\x93\xf0\xc8\xc5\x65\x24\x7d\x01"
-  "\xb2\x4d\xe7\x78\x24\x49\xe7\x78\xe4\x12\x5f\xd7\xe6\xc3\x2e\xaf"
-  "\xe1\x38\xc6\xf2\x1a\x5b\x8e\xc1\x9f\x0f\xbb\xe4\xa0\x63\x8e\x91"
-  "\xae\xe5\x38\x46\x2a\xbb\xa7\x4d\x2a\xbb\xa7\x4d\x2a\xb3\x36\x69"
-  "\x2b\xd4\x71\x32\x1f\xb6\x84\x02\x1e\xc8\xcd\x87\x7d\x1d\x73\x8c"
-  "\xa5\x85\xe3\x78\x1c\x63\x89\x99\x99\x1b\x8b\x79\x46\x83\x11\xe1"
-  "\x73\xc2\xf3\x64\x4b\x3a\x76\x9e\x6c\xe3\xdd\x3c\x4f\x76\xe9\x0c"
-  "\x79\x1c\x77\x69\x9b\xfd\x6f\xde\x11\xd8\x53\x76\xa9\x84\xfd\x6f"
-  "\x96\xca\xdc\xff\x66\xa9\x93\xfb\xdf\xa4\xda\xed\x7f\x43\xe6\xc9"
-  "\x2e\x29\x6d\x15\xe5\x1d\x4b\x0e\xe0\xbc\xed\xdb\x8b\x34\x9b\xef"
-  "\x8a\x69\x07\x3b\x3f\xef\x48\x13\xd9\x9f\x24\x6d\x06\xe1\x1d\xa9"
-  "\x11\xb7\x9e\x77\xa4\x8a\xec\x7d\x93\x76\x9a\xc4\xe8\xd4\x9b\xfb"
-  "\xd8\x70\xbc\x23\x55\x64\xef\x9b\xf4\x1e\x6d\xef\x21\xbc\x23\x95"
-  "\xdd\xfb\x26\x7d\xa0\x38\xef\x48\x2f\x27\x71\x29\x7d\x03\x89\x4b"
-  "\xc4\xa7\xf6\xbc\x23\x7d\x5e\xfb\xbc\x23\x95\xdd\xfb\x26\xd5\xc1"
-  "\xde\x37\xe9\xfb\xed\x79\xc7\x92\x03\xc2\xbc\x63\x79\x0e\x87\xa3"
-  "\xe5\x83\xf8\xbc\x63\x99\xe2\xce\xe0\x1d\xa2\xd8\x8a\xe6\xf3\x8e"
-  "\x65\xc7\xa5\xf3\x8e\xe5\xee\xd2\x78\x47\xaa\xc8\xbe\x37\xcb\xd9"
-  "\xfe\xcf\x54\x91\x7d\x6f\x96\xcf\x16\xe6\x1d\xcb\x57\xf2\x79\x47"
-  "\xaa\xc8\xbe\x37\xcb\x77\xf3\xf2\xb7\xe3\x1d\xcb\x2b\xf9\xbc\x23"
-  "\xb5\xcd\xbe\x37\xef\xb0\x7b\xc0\x2e\x99\x2e\x9d\x77\xbc\x33\x5e"
-  "\x9c\x77\xbc\xd3\x66\xff\xd7\x77\xd8\xfd\x5f\xdf\x59\x41\x78\xc7"
-  "\x3b\xec\xfe\xaf\x4b\x62\x6d\xd3\x39\xde\x41\xd2\x39\xde\xf1\x4e"
-  "\xae\x84\xfe\xab\x5c\x29\xf3\x64\x77\x34\xf2\xfb\xaf\xac\x7d\x57"
-  "\xa6\x01\x61\x2b\x6e\xf6\x5f\xd9\x7e\xeb\x14\xe8\xbf\xc2\x6d\x3a"
-  "\xd7\x7f\x75\x9a\x89\x55\x5c\xff\x95\x9e\xe9\xbf\xc2\x7d\x57\xf8"
-  "\x7b\xa7\xb5\xef\xca\xb2\xd0\x7e\x8e\xec\x0e\x8b\xf4\xbe\x2b\xee"
-  "\x9b\xe7\xd1\x00\xd2\x77\x55\x73\xb3\xef\x0a\xb7\xe7\xe6\x26\xfb"
-  "\xbe\x2b\xdc\x8e\x73\x7d\x57\x3f\xdf\xe2\xbe\xab\x95\x32\xd7\xbf"
-  "\x58\x19\xd4\x39\xbe\x4d\xdf\x6d\x73\x64\xdf\xd9\x4a\xfa\x79\xde"
-  "\x3d\x29\xef\xdb\xf4\xbb\x35\x9d\xc3\x2f\x77\xdb\x58\xed\x95\xab"
-  "\x88\x5f\x56\xcd\x93\xe7\x97\x55\xf1\x9d\xc3\x2f\x77\xdb\x58\x8e"
-  "\xff\xd5\x12\xbf\xac\xe9\x2a\xcf\x2f\x6b\x3c\xe4\xf7\xc1\xaf\x73"
-  "\xe3\xf4\xf1\x3a\x37\x71\x7d\xbc\xe6\xb4\x63\x7d\xbc\x76\x2c\xa7"
-  "\x8f\x33\x77\x10\x1e\x9a\x99\x43\x78\x68\xe6\x78\x6b\x1f\x3c\xd1"
-  "\xc7\xa5\x14\x6e\x4b\x70\xdf\x7a\x06\xb4\x1f\xef\x81\x36\xcc\x04"
-  "\xad\xfc\xde\x7c\xd0\xcb\xf1\xc8\xa3\xba\xf6\x20\x8a\x4f\xc5\x9a"
-  "\x39\xa3\x3c\x3c\xd9\x56\x33\xbf\x37\xd0\xaa\x97\xc3\xe1\xde\x6f"
-  "\xe6\x94\x52\x58\x17\x9b\x7d\x66\x66\x9b\x76\x84\xa5\x67\x43\x3e"
-  "\xd6\xfe\x79\xdc\xd6\xee\x9c\x03\xfa\x78\x26\xbf\x8f\xbe\x75\x47"
-  "\xd8\x8a\x56\x9f\x99\xb9\xb8\x9f\xbe\xd9\xa6\x9f\xde\x51\x1f\xbd"
-  "\x50\xff\x3c\xc6\x21\xee\xa3\x2f\x68\xbc\xdb\xfa\xe8\x57\xed\x23"
-  "\x58\xcc\xc8\x93\xd7\x47\x9f\x91\xcb\xd7\xca\xeb\x76\xdb\x6b\xe5"
-  "\x8c\x66\xe7\xb5\x72\xe6\x43\xf2\xb4\x72\xa6\xaf\x73\x5a\x39\x73"
-  "\xa9\xb0\x56\x5e\xa3\x17\xef\xa3\x27\xe7\xec\x35\xce\xda\x87\x38"
-  "\x8d\x93\x75\xb1\xf3\x6b\xe5\xac\x0c\x61\x3d\x93\x95\x47\xb4\x72"
-  "\x66\xca\xad\xd7\xca\x99\x29\xc2\x5a\x79\x6d\x57\xa2\x2b\x32\x53"
-  "\xec\xb5\x32\xdc\x23\xa8\x95\xd7\x8e\x68\x7b\x0f\xd1\xca\x99\xe9"
-  "\x44\x2b\xaf\x9d\x24\xae\x95\xd7\xde\x20\x31\x6a\x2d\x3b\x9f\x84"
-  "\xf8\xd4\x5e\x2b\xaf\x2d\x6c\x5f\x2b\x13\x0c\x31\xe5\x14\xd5\xca"
-  "\x6b\xcf\xdb\x6b\xe5\x35\xa7\x84\xb5\x72\xce\x41\x0e\x47\x39\xd3"
-  "\xf8\x5a\x39\x7b\xe0\x9d\xa1\x95\x45\xb1\x95\xc1\xd7\xca\xd9\x66"
-  "\xe9\x5a\x39\x67\x90\x34\xad\x8c\x31\x27\xa4\x95\x73\xd8\xfd\xaf"
-  "\x08\x5e\xec\xb5\x72\xce\x06\x61\xad\x9c\xb3\x9b\xaf\x95\x71\xfe"
-  "\x42\x5a\x39\xe7\x34\x2f\x7f\x3b\xad\x9c\xd3\xcc\xd7\xca\xe4\x3a"
-  "\x4e\x2b\xaf\x2b\x20\x31\x74\xcd\x4a\xe9\x5a\x79\xdd\x52\x71\xad"
-  "\xbc\x6e\x25\x5f\x2b\xaf\x8b\x24\x9a\x78\x5d\x09\xd1\xca\xeb\x66"
-  "\x91\xf4\x35\x2b\x6c\xd3\x39\xad\x4c\xd2\x39\xad\xbc\xae\x54\x82"
-  "\x56\xce\xbf\x45\x5a\x79\xd5\x9d\xa5\x95\xbf\xab\xed\x1c\x5a\x39"
-  "\x77\xb6\x3c\xad\x9c\x3b\xcb\x49\xee\x9f\xdb\x0e\xf7\x5f\x71\x8f"
-  "\xfb\xdb\xf2\xad\x75\x27\x08\xdf\x5a\xef\x2e\x8f\xfb\xaf\x77\xeb"
-  "\x0c\x7e\xb9\xbb\x7c\x92\xbb\x87\xf8\xe4\xaf\x1b\xe4\xf9\xe4\xaf"
-  "\xf9\xf7\x74\xf2\xed\xf0\xcb\xfa\xb1\xc4\x2f\x1b\x06\xc9\xf3\xcb"
-  "\x86\x00\xf9\x3a\x79\xd3\x58\x4e\x27\x6f\x1a\x6b\xab\x93\xcb\x46"
-  "\xdb\xea\xe4\x0f\xdc\x1d\xeb\xe4\x22\x9b\xbd\x1a\x0a\x58\x0e\x5a"
-  "\xc0\x8e\x37\x2e\x60\xf8\x46\x33\xd6\xc9\xa3\x40\x27\x5f\xca\xbe"
-  "\xa9\x93\xb1\x2e\x1e\x67\x3c\x43\xe3\xef\xca\xa0\x93\xdd\x56\x5f"
-  "\x41\x6e\xa0\x9d\x51\xf5\xa9\xbd\x28\x03\x74\xf3\x9a\x2b\xa0\x9d"
-  "\x67\x81\x76\x36\x15\xb2\xda\xb9\xa0\x07\x5f\x3b\x7f\x30\x83\xa7"
-  "\x9d\x67\x66\x33\xda\x19\xf4\x70\xba\x29\x6f\x66\x36\xd6\xce\x26"
-  "\xd0\xc5\xad\x03\xc3\x56\x64\x5f\x69\xa3\xa3\x67\x82\x8e\x7e\x8b"
-  "\xaf\xa3\x5b\xf2\x66\xe6\x37\xef\x08\x5b\x85\x75\xb4\xb1\xbf\x7c"
-  "\x1d\x5d\xd0\x42\x74\xf4\x87\x77\x9d\x8e\xfe\xab\x9e\x60\xf5\xc3"
-  "\xd3\xf2\x74\xf4\x87\xa7\xf8\x3a\x7a\x53\xb3\xbd\x8e\x2e\x18\xe5"
-  "\xbc\x8e\x2e\x98\x2e\x4f\x47\x17\xc4\x3a\xa7\xa3\x0b\x8e\xb4\xd5"
-  "\xd1\x5b\x53\xb1\x8e\xfe\xc0\xa3\x59\x54\x47\x7f\xe0\x26\xfc\xcd"
-  "\xb9\xc8\x66\x0f\x88\xa2\x3b\x60\x0f\x88\xc2\x13\xc2\x5a\xa7\xf0"
-  "\x34\xd1\xd1\x05\x87\x6f\xbd\x8e\x2e\x38\x2c\xac\xa3\x8b\xd8\xef"
-  "\x7f\x05\x87\xed\x75\x34\xdc\x23\xa8\xa3\x8b\x56\xb6\xbd\x87\xe8"
-  "\xe8\x82\x32\xa2\xa3\x8b\x1c\xec\xff\xb0\x91\xdd\xff\x61\x23\xbb"
-  "\xff\x03\xf1\xa9\xbd\x8e\x2e\x72\x62\xff\x07\x82\x21\xa6\x9c\xa2"
-  "\x3a\x7a\xa3\xc0\xfe\x0f\x1f\xb8\x09\xeb\xe8\x4d\xee\x1c\x8e\x8a"
-  "\xb7\xf0\x75\xf4\xc6\x3b\x64\xff\x07\x51\x6c\x9d\xe0\xeb\xe8\xe2"
-  "\x31\xd2\x75\x74\xf1\x22\x69\x3a\x1a\x63\x4e\x48\x47\x17\xb3\xeb"
-  "\x9f\x11\xbc\xd8\xeb\xe8\xe2\xb3\xc2\x3a\xba\xb8\x99\xaf\xa3\x71"
-  "\xfe\x42\x3a\x7a\x53\x7f\x5e\xfe\x76\x3a\x7a\xd3\x28\xbe\x8e\x26"
-  "\xd7\x71\x3a\x7a\x53\x2d\x89\xa1\x1b\x76\x48\xd7\xd1\x9b\x8e\x88"
-  "\xeb\xe8\x4d\x95\x7c\x1d\xbd\xa9\x98\xe8\xe5\x4d\x46\xa2\xa3\x37"
-  "\xed\x21\xe9\x1b\xb6\xdb\xa6\x73\x3a\x9a\xa4\x73\x3a\xfa\x23\x0f"
-  "\x69\xdf\x9c\x5d\x5a\x8b\x6a\x45\xc7\xcf\x99\xb8\x55\x6b\x51\x59"
-  "\xbf\x3b\xff\xb7\xe7\x4c\x7c\xbc\x5f\x9e\x96\xfe\x78\xdf\x3d\xcd"
-  "\x76\xab\xb5\xc1\x47\xbe\x84\x6f\x6d\x91\xb9\xfe\xef\x96\x7b\xeb"
-  "\xff\xde\x16\xbf\x6c\x46\xc4\x2f\x9f\xc8\x5c\xff\xf7\x13\x17\xd6"
-  "\xff\xdd\xa9\xe7\x34\xdb\x4e\xbd\xf8\xb7\xcd\x4f\xdb\x59\xff\x77"
-  "\xbb\x8e\xd3\x6c\x9f\xad\x26\x7c\xe7\xb3\xd9\x84\xef\x7c\x36\x50"
-  "\xde\xb7\xcd\x6d\x5b\xf8\xfa\x6c\x6b\xd7\x7b\xdf\x36\x6f\xb7\x26"
-  "\xdb\xc2\xae\x0f\xbc\x6d\x9e\x3c\x4d\xb6\x2d\x9e\xaf\xc9\x76\x65"
-  "\xda\x6b\xb2\x6d\x3f\x38\xaf\xc9\xb6\x35\xcb\xd3\x64\xdb\x8c\xce"
-  "\x69\xb2\xcf\x26\x09\x7f\xdb\xfc\xd4\xc1\xfa\xc0\x9f\x8a\xac\x0f"
-  "\xfc\x79\x33\xc7\xa5\x3f\x3f\xd2\xf9\x35\xd9\xe7\x71\xc2\xbc\xf9"
-  "\xf3\x79\x44\x93\x7d\x16\x79\xeb\x35\xd9\x67\x91\xc2\x9a\xec\xf3"
-  "\xf3\x84\xbf\x7e\x16\x69\xaf\xc9\xe0\x1e\x41\x4d\xb6\xbd\x77\xdb"
-  "\x7b\x88\x26\xfb\x6c\x2a\xd1\x64\xdb\x87\x88\x6b\xb2\xed\xc7\x49"
-  "\x8c\xda\xbe\x89\xc4\xa8\x4f\x45\xd6\x07\xde\xbe\xa8\x7d\x4d\x46"
-  "\x30\xc4\x94\x53\x54\x93\x6d\x3f\x64\xaf\xc9\x3e\x15\x59\x1f\x78"
-  "\xe7\x06\x0e\x47\x3b\x87\xf1\x35\xd9\x8e\xae\x77\x86\x26\x13\xc5"
-  "\x56\x1c\x5f\x93\xed\x38\x29\x5d\x93\xed\xec\x2e\x4d\x93\x61\xcc"
-  "\x09\x69\xb2\x9d\x93\x58\xfc\x4c\x15\xd6\x64\x3b\x13\x85\x35\xd9"
-  "\xce\x4c\xbe\x26\xc3\xf9\x0b\x69\xb2\x9d\xfb\x79\xf9\xdb\x69\xb2"
-  "\x9d\x3f\xf0\x35\x19\xb9\x8e\xd3\x64\xbb\x92\x49\x0c\xfd\x54\xc6"
-  "\xfa\xc0\xbb\x26\x89\x6b\xb2\x5d\x31\x7c\x4d\xb6\x6b\x30\xd1\x5e"
-  "\xbb\x32\x88\x26\xdb\x15\x42\xd2\x3f\x8d\xb6\x4d\xe7\x34\x19\x49"
-  "\xe7\x34\xd9\xae\x02\x69\x9a\xcc\xf9\x75\xaa\xfe\xfb\xe3\x80\x55"
-  "\x77\xd9\x38\xe0\xdd\xa1\xf2\xf4\xd8\xee\x90\x7b\xdc\xff\x76\x70"
-  "\xff\x5d\x25\x84\x6f\xfd\xed\xac\x3c\xee\xff\x37\xbd\x7c\xee\xff"
-  "\xd5\x29\x8e\xfb\x7f\x75\x4a\x9c\xfb\xff\x7d\xaf\x63\xee\xbf\xcf"
-  "\x8f\xe3\xfe\x5f\xac\x24\xed\xea\x17\x33\x48\xbb\xfa\x85\xbf\x3c"
-  "\xee\xbf\x77\x13\x9f\xfb\xef\x71\xbf\xc7\xfd\x6f\x37\xf7\xdf\xcd"
-  "\xae\x53\xbd\x77\xb6\x3c\xee\xbf\x77\x16\x9f\xfb\xff\x63\xb5\x3d"
-  "\xf7\xdf\x7b\xdc\x79\xee\xbf\xf7\x86\x3c\xee\xbf\xb7\xc1\x39\xee"
-  "\xff\xc5\x44\x61\xee\xff\xf7\x7d\xe2\xdc\x9f\x9c\xb3\xe7\x6c\x5f"
-  "\xde\xe0\x38\xdb\x97\x87\x3a\x3f\xf7\xff\x32\x56\x98\x9f\x7d\x39"
-  "\x9b\x70\xff\x2f\x26\xdc\x7a\xee\xff\xc5\x04\x61\xee\xff\xe5\x59"
-  "\xc2\x93\xbe\x98\x60\xcf\xfd\xe1\x1e\x41\xee\xbf\xcf\xa7\xed\x3d"
-  "\x84\xfb\x7f\x11\x49\xb8\xff\xbe\x41\xe2\xdc\x7f\x5f\x25\x89\x51"
-  "\xfb\x0a\x49\x8c\x22\x3e\xb5\xe7\xfe\xfb\x12\xdb\xe7\xfe\x04\x43"
-  "\x4c\x39\x45\xb9\xff\xbe\x83\xf6\xdc\xff\xef\x7b\x84\xb9\xff\x57"
-  "\x79\x1c\x8e\xbe\x1a\xc2\xe7\xfe\xfb\xdd\xef\x0c\xee\x2f\x8a\xad"
-  "\x58\x3e\xf7\xdf\xff\x83\x74\xee\xff\x55\x57\x69\xdc\x1f\x63\x4e"
-  "\x88\xfb\x7f\x35\x91\xc5\x4f\xa4\x30\xf7\xff\x6a\x9e\x30\xf7\xff"
-  "\x6a\x35\x9f\xfb\xe3\xfc\x85\xb8\xff\x57\x7b\x79\xf9\xdb\x71\xff"
-  "\xaf\x8e\xf3\xb9\x3f\xb9\x8e\xe3\xfe\xff\x48\x20\x31\xf4\xef\xd3"
-  "\xa4\x73\xff\x7f\x4c\x14\xe7\xfe\xff\x98\xc6\xe7\xfe\xff\x08\x20"
-  "\x1c\xff\x1f\xab\x08\xf7\xff\xc7\x68\x92\xfe\xf7\xa9\xb6\xe9\x1c"
-  "\xf7\x27\xe9\x1c\xf7\xff\x47\xfe\xbd\x35\xac\xee\xa4\x35\xac\x0e"
-  "\xca\xe4\xff\x07\x1d\xf2\x7f\xc7\x3c\xf3\x88\x1f\xc7\x33\x8f\xf8"
-  "\xd9\xf2\x4c\xfe\x1a\x56\x5f\x3f\xe4\x98\x67\xfe\x73\x16\xc7\x33"
-  "\x4b\xd9\x18\x5e\xba\x9b\xc4\xf0\xd2\x79\x56\x9e\x29\xbe\x86\xd5"
-  "\x37\x17\xf9\x6b\x58\x7d\x3d\xe9\xde\x1a\x56\xb7\x83\x47\xfe\x63"
-  "\x3b\xe1\x91\xdf\xec\x95\xc7\x23\xbf\xd9\xc3\xe7\x91\x47\x8e\xdb"
-  "\xf3\xc8\xd2\xde\xce\xf3\xc8\xd2\x11\xf2\x78\x64\xe9\x70\xe7\x78"
-  "\x64\x69\xa1\xf0\x1a\x56\x5f\x6b\xc5\x79\x24\x39\x67\xdf\xfe\xff"
-  "\x73\x04\xd7\xfe\xff\xb3\x6b\xe7\xe7\x91\x87\xb6\x0b\xb7\xf5\x87"
-  "\xf6\x12\x1e\x59\x5a\x70\xeb\x79\x64\x69\x81\x30\x8f\xfc\x27\xbb"
-  "\xff\x75\x69\xb1\xfd\x1a\x56\x70\x8f\x20\x8f\xfc\xe7\x34\xf6\x9e"
-  "\x02\x3e\x8f\x24\x79\x40\xcc\x59\x24\xce\x23\xbf\xf5\x21\x31\xe8"
-  "\x9f\xe7\x49\x0c\x22\x3e\xb5\xe7\x91\xff\x3c\xd8\x3e\x8f\x24\x18"
-  "\x62\xca\x29\xca\x23\xbf\x75\xb7\xe7\x91\x5f\xfb\x0a\xf3\xc8\xc3"
-  "\xa7\x39\x1c\x1d\x5e\xca\xe7\x91\xdf\x8e\xbb\x33\x78\xa4\x28\xb6"
-  "\xb6\xf3\x79\xe4\xe1\x87\xa4\xf3\xc8\xc3\xe3\xa5\xf1\x48\x8c\x39"
-  "\x21\x1e\x79\xb8\xb0\x2d\xe6\xf8\x3c\xf2\xf0\x7e\x61\x1e\x79\xf8"
-  "\x38\x9f\x47\xe2\xfc\x85\x78\xe4\x61\x33\x2f\x7f\x3b\x1e\x79\xa4"
-  "\x37\x9f\x47\x92\xeb\x38\x1e\x79\xe4\x00\x89\xa1\x07\x8f\x48\xe7"
-  "\x91\x47\x0a\xc5\x79\xe4\x91\x2d\x7c\x1e\x79\x24\x99\xf0\xc5\x23"
-  "\xc7\x08\x8f\x3c\x92\x41\xd2\x0f\x1e\xb6\x4d\xe7\x78\x24\x49\xe7"
-  "\x78\xe4\x11\xbd\xb4\xf9\x31\xb7\xa4\x0f\xb9\x83\xe6\xc7\xdc\xaa"
-  "\x3e\xe4\xce\x32\x3f\xe6\x5f\x99\xf2\x38\xe4\xbf\x32\xee\x8d\xe9"
-  "\xb9\xd5\xfd\xc7\x47\x1a\x08\xd7\x2a\xef\x27\xaf\xff\xb8\x5c\x2b"
-  "\x9f\xd7\x1f\x1f\xcc\xf1\xfa\xe3\x83\xc5\xc7\xfb\x97\xdf\x70\xcc"
-  "\xeb\xab\x52\x38\x5e\x5f\x71\x9a\xb4\xa9\x15\x87\x48\x9b\x5a\xb1"
-  "\xac\xdd\xf1\xfe\x49\xc8\x2d\x83\x1d\xef\xff\x1e\x1e\xef\x5f\x73"
-  "\x04\x65\x5c\x13\x1a\xef\xff\x5d\x33\xbf\x4f\xf9\xe8\x24\xa1\xf1"
-  "\xfe\xcc\x38\xff\xbc\x99\xb9\x26\xb1\x71\xfe\xaf\xdf\xfa\x71\xfe"
-  "\x1f\x82\x3e\xb0\xea\x81\x0f\xef\x3a\x3d\xf0\x2f\x76\xfe\xd6\x77"
-  "\x47\xe4\xe9\x81\xef\x0e\xf3\xf5\xc0\xf1\xb3\xf6\x7a\xa0\xc2\xdf"
-  "\x79\x3d\x50\x31\x4e\x9e\x1e\xa8\x18\xeb\x9c\x1e\xa8\xd8\x21\x3c"
-  "\xce\xbf\xdc\x28\x3e\xce\xbf\xbc\x41\x78\x9c\x7f\xd5\x38\x8e\xc7"
-  "\x55\xf5\xee\xfc\x7a\xa0\xf2\x80\x30\x67\xab\x3c\x42\xf4\x40\xc5"
-  "\xf6\x5b\xaf\x07\x2a\xb6\x0b\xeb\x81\x2a\x76\xfd\xcf\x8a\xed\xf6"
-  "\xfd\xca\x70\x8f\xa0\x1e\xa8\x9a\xdd\xf6\x1e\xa2\x07\x2a\x4a\x88"
-  "\x1e\xa8\x5a\x2d\xae\x07\xaa\xfb\x93\xd8\x55\x75\x83\xc4\x2e\xe2"
-  "\x53\x7b\x3d\x50\x55\xd9\xbe\x1e\x20\x18\x62\xca\x29\xaa\x07\xaa"
-  "\x7d\xec\xf5\x40\x79\x83\xb0\x1e\x38\x76\x99\xc3\xd1\xb1\x4c\xbe"
-  "\x1e\xa8\x9e\x76\x67\xe8\x01\x51\x6c\x1d\xe0\xeb\x81\x63\x03\xa5"
-  "\xeb\x81\x63\x31\xd2\xf4\x00\xc6\x9c\x90\x1e\x38\xb6\x83\xc5\x4f"
-  "\x89\xb0\x1e\x38\x56\x2e\xac\x07\x8e\x9d\xe5\xeb\x01\x9c\xbf\x90"
-  "\x1e\x38\xde\x9d\x97\xbf\x9d\x1e\x38\xee\xcf\xd7\x03\xe4\x3a\x4e"
-  "\x0f\x1c\xaf\x20\x31\xb4\xbc\x50\xba\x1e\x38\xbe\x43\x5c\x0f\x1c"
-  "\xdf\xcb\xd7\x03\xc7\x57\x11\xde\x7f\x5c\x4f\xf4\xc0\xf1\x02\x92"
-  "\x5e\x5e\x60\x9b\xce\xe9\x01\x92\xce\xe9\x81\xe3\x06\x69\x63\x4a"
-  "\x9c\xef\x57\xfe\xef\x8f\x29\xf1\xb8\xcb\xc6\x94\xfc\x5f\xa1\x3c"
-  "\x3d\xf0\x7f\x05\xf2\xb9\xe7\x2f\xd9\x1c\xf7\xfc\x25\x5b\x7c\xec"
-  "\xc2\x89\x79\x8e\xb9\x67\x4d\x0d\xc7\x3d\x7f\x1a\x46\xe2\xf7\x4f"
-  "\x0f\x91\xf8\xfd\xe3\x69\xb1\xb1\x0b\x78\x8e\x69\xe6\x7c\x32\xbf"
-  "\xf4\xe6\xd8\x05\xe0\x42\x84\x67\xfe\x38\x91\xcf\x33\x4f\x1c\x12"
-  "\x1a\xbb\x20\x38\x66\xa1\xcd\x1c\x52\x3c\x5e\xc1\x0c\x3c\xd4\xd5"
-  "\x31\x0b\x77\xef\x1c\xd2\xef\xdd\x08\xb7\xfc\xb1\x9f\x3c\x6e\xf9"
-  "\xa3\x96\xcf\x2d\x4f\x8d\xb0\xe7\x96\x3f\xae\x74\x9e\x5b\xfe\xb8"
-  "\x4d\x1e\xb7\xfc\x71\xab\x73\xdc\xf2\xa7\xae\xc2\x63\x16\x4e\x24"
-  "\x88\xf7\x35\x93\x73\xf6\x9c\xa0\x66\x1b\xc7\x09\x6a\x12\x3b\x3f"
-  "\xb7\xac\xd1\x08\xb7\xff\x35\xfd\x08\xb7\xfc\xc9\xe3\xd6\x73\xcb"
-  "\x9f\x3c\x84\xb9\x65\x4d\x1e\x69\x87\x7f\xf2\xb0\xe7\x96\x70\x8f"
-  "\x20\xb7\xac\x29\x6f\x7b\x0f\xe1\x96\x3f\x79\x12\x6e\x59\x73\x5e"
-  "\x9c\x5b\x9e\x64\xd7\x53\x3f\x39\x9e\xc4\x26\xe2\x53\x7b\x6e\x79"
-  "\xd2\xbf\x7d\x6e\x49\x30\xc4\x94\x53\x94\x5b\x9e\x9c\x67\xcf\x2d"
-  "\x4f\xc4\x0b\x73\xcb\x5f\x42\x39\x1c\xfd\x7c\x91\xcf\x2d\x4f\xee"
-  "\xbf\x33\xb8\xa5\x28\xb6\x34\x7c\x6e\xf9\xf3\x6a\xe9\xdc\xf2\xe7"
-  "\x83\xd2\xb8\x25\xc6\x9c\x10\xb7\xfc\x85\x5d\xff\x8b\xe0\xc5\x9e"
-  "\x5b\xfe\xd2\x5f\x98\x5b\xfe\x32\x82\xcf\x2d\x71\xfe\x42\xdc\xf2"
-  "\x97\x19\xbc\xfc\xed\xb8\xe5\x2f\x2b\xf9\xdc\x92\x5c\xc7\x71\xcb"
-  "\x53\x3a\xb6\xbd\xeb\x2d\x9d\x5b\x9e\xea\x2a\xce\x2d\x4f\xf5\xe0"
-  "\x73\xcb\x5f\x6a\x09\x87\x3c\x35\x9c\x70\xcb\x5f\x8c\x24\xfd\x84"
-  "\xc6\x36\x9d\xe3\x96\x24\x9d\xe3\x96\xa7\xc6\x3a\xe2\x96\x74\xae"
-  "\x77\x5c\x36\x65\x29\x81\x63\x1f\x94\xb3\x37\xb4\x6f\xa5\xf0\x7f"
-  "\x19\xb4\x53\x3d\xe0\xff\x63\x62\x9c\xc5\xe0\xe3\x1d\x67\x01\xfe"
-  "\x61\x81\xe7\x54\x1b\x7e\x2f\x2d\xed\x63\xc2\x65\xaf\x20\xed\x8b"
-  "\x77\x9c\xb7\xa9\x4b\x88\x85\x8e\x43\xb4\x1a\xfe\x4f\x86\x34\xb8"
-  "\xde\x0b\xda\x43\x6d\x12\xf2\xba\x42\x9d\xaa\xb7\x5e\x07\x65\xf6"
-  "\x3a\x47\x9d\xda\x86\xf3\x80\xb2\x1a\xe1\x7d\x22\x45\xcb\x0a\x79"
-  "\x85\x6f\xeb\x8b\x96\x9a\xe8\x5f\x4b\xe7\x5c\x43\xb5\xd4\xe9\x51"
-  "\xde\xf5\x5d\x42\x20\x0e\x21\xcc\x05\x4b\xfa\x18\xdc\x70\x9e\xa5"
-  "\x73\x5a\xf0\x39\x3f\x7c\xce\x0c\x65\x4c\x9d\x8d\xa8\xac\x6b\x5d"
-  "\x3c\x80\x5b\xb9\xa7\x35\xd0\x75\x73\x4d\x50\x66\x68\x5f\xbf\xe9"
-  "\x5b\xe3\xb6\xeb\x83\x1a\xa6\xed\xa9\x6a\x30\x33\x79\x68\xe7\xe0"
-  "\xf2\x9c\x1e\x53\x04\xd7\x0b\x95\x61\xe5\x4e\x34\xc0\xdd\x9f\xd6"
-  "\x4b\x6b\xef\x4e\x8b\xae\xff\xe2\xbd\xac\x2f\x2a\x7d\x1c\x6c\xa7"
-  "\x45\x94\xd0\x79\x69\xcf\xf9\x37\x72\xc0\x31\x3d\xde\xef\x45\x37"
-  "\xa4\x6d\x40\xd4\x5a\x4b\x17\x8f\x6f\x21\x26\x6e\x5c\x4f\x1b\x9a"
-  "\xd6\xfc\x7b\x96\x5e\x51\x99\x8d\x6d\xfe\x0e\x9c\x5f\xdb\x8b\x36"
-  "\x5c\x5f\x8e\x71\xf3\xef\x15\x87\xa0\x6d\x6f\xeb\x8b\xf9\xb1\xb3"
-  "\x63\xb4\x09\x33\x66\x4f\x9f\x9b\x98\xa0\xed\x1f\xdb\x0d\x4d\x98"
-  "\x3b\x57\x3b\x3b\x66\xce\x22\xad\xed\x99\x67\xb5\xb1\x33\x16\xc4"
-  "\xbc\x31\x6b\xfa\xc0\xd9\x6f\xc6\x77\xc3\x85\xb2\x29\x87\x1a\x97"
-  "\xc5\xb2\xe6\xdf\xd9\x45\xeb\x10\x7a\xbf\x27\x72\xc3\xe5\x82\xe7"
-  "\x35\xe8\xdd\x06\xd4\xe2\xe7\x65\xad\xa7\x1b\x28\xb8\x26\x0d\x62"
-  "\xda\xda\xd4\x2e\xf8\x5a\xb4\x11\xca\x55\x04\xe5\x86\x32\x42\x99"
-  "\xcf\x68\xad\x65\xb6\x62\x22\x0d\x63\x22\xf5\x1a\x60\xf0\xcc\x28"
-  "\x6f\x63\x97\x60\x9a\x8e\xc4\xef\xd7\x00\x75\x45\x01\x69\x27\x19"
-  "\x7d\x90\xe7\x1d\x07\xf7\x4e\xb5\x62\xcc\x92\x1b\x89\xe8\xf5\xde"
-  "\x01\xc0\x2b\x15\x4d\x74\xdc\x73\x80\x4d\x7c\xff\xb6\xa7\x10\x4a"
-  "\xa7\x9b\x22\x99\xfd\x26\xe8\x26\xc0\x30\xc1\x29\x9c\xd3\xa7\x5c"
-  "\xa7\xd0\x48\xc8\xa3\x58\x8f\xde\xcb\xc0\x79\xe8\x21\x0d\xdb\xdc"
-  "\x52\x9c\x98\x3d\x51\x87\xd2\x1f\x4b\x47\xe9\x4d\xf8\x9e\xcd\x43"
-  "\xe3\xbc\x13\x90\x22\x3c\x99\x3e\x03\x71\x47\x41\xf7\x4b\xcc\xa6"
-  "\xb7\x0c\x8d\xd3\x53\x67\x56\x58\xf2\x22\xf1\xfb\xd4\x43\x3e\x75"
-  "\x7a\x45\x17\xe6\x3d\xd6\xae\x67\x6c\x5f\x8f\xdf\x1d\xec\x03\x3a"
-  "\x87\x2e\xa5\x97\xb3\x75\x28\x3b\x40\x65\xc9\x4e\x37\x56\xbb\x35"
-  "\xa2\x70\x13\xdd\x4a\xe7\x04\xa8\xaa\x1a\x1a\x20\xa6\xc5\xbf\x49"
-  "\x77\xfb\xf7\x26\x6f\xd3\x8c\xe9\x1b\x7b\x42\x5d\xcc\x49\x37\xd2"
-  "\x39\xa1\xc7\x26\xfa\x23\x55\xd3\x1a\xfd\x68\xab\x3d\xc1\x96\x6e"
-  "\xd2\x70\xa4\x67\xc6\xbf\x60\x3c\x40\x79\x58\x3c\xe8\x73\x0f\x25"
-  "\xd8\xe3\xe1\x66\xdd\x5c\x1f\x1c\x6f\xa2\x23\x83\x5b\x73\x83\xb7"
-  "\xd2\xea\xe0\xdc\xd4\xf3\xe8\x3e\x6c\xdb\x2a\xd0\x01\x59\x49\x48"
-  "\x93\xf9\x3a\xd2\x46\x2d\x52\x21\x43\x5e\x70\xb6\xf7\xb2\x74\x05"
-  "\xd8\x84\x82\xf8\x12\x00\x31\x33\xa0\xb5\x57\x24\x4a\x99\x8e\xa8"
-  "\x1d\xe7\x4a\x28\xcc\x9f\xf1\x18\x94\x0b\xd4\xd9\x89\x45\x70\x1f"
-  "\xfd\x7b\x24\xc2\xfe\x60\x7c\xf1\x7b\x1c\x1a\x37\x03\xda\xe7\x99"
-  "\xcc\xf9\xd5\x85\x90\xa7\xb4\xf7\x3a\xcb\xf0\x5f\x33\xf8\xea\x29"
-  "\xf0\x53\x75\xad\x99\xc9\x93\xf1\xd5\x2c\xce\x57\x07\xa1\x1c\x9c"
-  "\xbf\xce\xaa\xb0\x5f\x45\xde\xd9\x40\xde\x39\x44\x47\xab\x43\xd4"
-  "\xe2\xef\x1c\xa2\x22\xef\xec\x7e\xcd\xf1\x3b\x9f\x0b\x75\xfc\xce"
-  "\xe7\x96\x4a\x7f\xe7\x73\x6a\xe9\xef\x7c\xce\x4d\xfc\x9d\x43\x58"
-  "\x3f\x87\x80\x9f\x43\x1c\xf8\x39\x84\xf5\xf3\xfd\xe7\x1c\xbf\xf3"
-  "\x7f\x46\x38\x7e\xe7\xff\xcc\x93\xfe\xce\xff\xf1\x90\xf1\xce\x46"
-  "\x07\xef\xcc\xfa\x39\x14\xfc\x1c\xea\xc0\xcf\xa1\xac\x9f\x7b\x7c"
-  "\xef\xf8\x9d\x6b\x07\x39\x7e\xe7\xda\xe9\x32\xde\xd9\x24\xfd\x9d"
-  "\xff\x53\x2f\xfe\xce\xa1\xac\x9f\x43\xc1\xcf\xa1\x0e\xfc\x1c\xca"
-  "\xfa\xf9\x99\x35\x8e\xdf\xf9\x7c\x7f\xc7\xef\x7c\x7e\x92\xf4\x77"
-  "\xae\x35\x48\x7f\xe7\x5a\xbd\x83\x77\x66\xfd\x1c\x06\x7e\x0e\x73"
-  "\xe0\xe7\x30\xd6\xcf\x53\x9e\x77\xfc\xce\x17\x7a\x3b\x7e\xe7\x0b"
-  "\xe3\xa4\xbf\xf3\xf9\x5a\xe9\xef\x7c\xfe\x84\xd8\x3b\xb7\x40\xdc"
-  "\xf6\x84\x77\x69\xfd\x29\x32\xd8\xac\x0e\x2e\xf0\xac\x45\x54\xc1"
-  "\x72\x4b\x9c\x77\x1d\xea\x0a\xef\x16\x47\xaf\x9f\x7c\x0c\xff\xb5"
-  "\xa8\x83\xf3\x5b\xd4\xc1\x5b\x9b\x7b\x79\x07\x2c\x99\x86\xee\xc3"
-  "\x7c\x7c\xb5\x05\x69\x2c\xb9\xc1\xb9\x19\x2f\x23\x6d\x9a\x01\xa9"
-  "\xaa\x52\xf5\x28\x35\x9e\x36\x54\xa1\xb3\xa8\x7b\x1d\xd6\x9e\x3f"
-  "\xa3\x8a\xfa\x32\x34\x67\x3e\x4d\x5f\xa0\x7e\xdd\x80\xfb\x4d\x80"
-  "\x27\xa7\x67\xff\x88\xb4\xf0\x8c\x80\x22\x38\x70\x3e\xde\x63\xa1"
-  "\xfd\x5c\x3f\xf9\xfb\x8d\xa9\x48\xf3\xf5\xcc\x3a\x84\xd3\x0b\xe1"
-  "\x30\xaf\x8f\x44\xa9\xd3\x10\xb5\xf3\x5a\x0d\x45\xda\xe6\x5f\xa7"
-  "\xb7\x6d\x9b\xc7\xc6\x80\x2d\xdf\x60\xce\xed\x2e\x78\x59\xaa\x2d"
-  "\x7f\x0d\xb0\xb6\xdd\x8c\x2d\x4f\x99\x49\x7b\xdf\xa6\xed\xfe\x1a"
-  "\x9e\xcf\xd9\xf2\x57\x2d\xb6\x25\x9d\x1b\x5c\x52\x5d\xd7\x82\x75"
-  "\x93\xea\x42\x32\xa2\xf4\xd4\x85\x63\x55\xf1\xd7\x90\x88\x8d\x0d"
-  "\x9c\x8d\x43\x7c\x3d\x6b\xdd\xaf\x09\xdb\x38\x44\xd3\xa2\x0e\xd1"
-  "\xd9\xdb\x38\x44\xed\x9c\x8d\xeb\xcc\xae\xdb\xb8\xae\x5c\xdc\xc6"
-  "\x17\x7d\xa4\xdb\xb8\x2e\x57\xba\x8d\xeb\x56\x10\x1b\x87\x04\xf0"
-  "\x6d\x5c\x37\x58\xdc\xc6\x21\x36\x38\x0e\x01\x1c\xdf\x7f\x4e\xc4"
-  "\xc6\x80\xe3\x10\x01\x1c\x87\x38\x89\xe3\x4b\x31\xae\xdb\xf8\xd2"
-  "\x40\x71\x1b\x5f\x5a\x24\xdd\xc6\x17\x8d\xd2\x6d\x7c\xb1\x8e\xb5"
-  "\x71\x1b\x1c\x5f\xcc\x77\x60\x63\x1b\x1c\x87\x02\x8e\x7b\x7c\x2f"
-  "\x6c\xe3\x50\xc0\x71\xa8\x00\x8e\x43\x9d\xc4\xf1\x6f\x47\x5c\xb7"
-  "\xf1\x6f\x39\xe2\x36\xfe\xed\xb4\x74\x1b\xff\x36\x55\xba\x8d\x7f"
-  "\x1b\x4b\x6c\x1c\xda\x06\xc7\x97\x4c\xe2\x36\x0e\xb5\xc1\x71\x28"
-  "\xe0\xf8\x99\x35\x22\x36\x06\x1c\x87\x0a\xe0\x38\xd4\x49\x1c\x5f"
-  "\xf6\x77\xdd\xc6\xf5\x37\xc4\x6d\x7c\x79\x94\x74\x1b\xd7\x97\x4a"
-  "\xb7\x71\x7d\x09\x6b\xe3\x36\x38\xae\x8f\x76\x60\x63\x1b\x1c\x87"
-  "\x01\x8e\xa7\x3c\x2f\x6c\xe3\x30\xc0\x71\x98\x00\x8e\xc3\x9c\xc4"
-  "\xf1\x95\x4c\xd7\x6d\x7c\x65\x92\xb8\x8d\xaf\x6c\x91\x6e\xe3\x2b"
-  "\x7e\xd2\x6d\x7c\x45\x4d\x6c\x1c\xd6\x06\xc7\x97\x0f\x8b\xd9\xb8"
-  "\x15\x34\x60\x77\xb0\x71\xf7\x7a\x44\x15\x62\xdb\xd6\x10\xdb\x9a"
-  "\x7b\x4d\x3e\x56\x48\x59\xe2\xb0\x4d\x98\x3e\xa0\xdf\x34\x5e\xe6"
-  "\xdc\xe0\x02\x9a\x82\x77\x4a\xc5\xfd\xae\xbf\x77\x37\x2d\x47\x5e"
-  "\xda\x54\xdc\xff\x6b\xb8\x88\xaf\xd1\xa6\xbe\x7b\x1a\x9e\xa7\xc4"
-  "\xfd\x5e\xa6\x3c\x2f\x95\xd9\xe7\x45\x3d\x9c\x1b\x43\xf7\x1f\x96"
-  "\x0e\x7a\xb3\x84\x7e\x5b\xa3\xae\xae\x2f\x01\xfb\x1c\x45\x55\x35"
-  "\x5f\x21\x4b\xaf\xc9\xdf\x3f\x65\x42\x3a\xfa\x37\x9d\xba\x22\x41"
-  "\x8f\xcc\x6f\x6a\x3c\xab\x93\xcb\x50\x75\xf2\xdf\x50\x78\x1d\xdd"
-  "\x48\xff\x47\xe7\xd9\xea\x13\xa3\x31\xfb\x4c\x2e\x31\xe7\xcd\xdc"
-  "\x6a\xf2\x89\xf1\xd8\x91\xa4\xa7\x3c\x8d\x48\x37\xab\x96\xa6\xb3"
-  "\xde\x40\x6e\x59\xe7\x90\xc7\xda\x37\x90\xe7\xda\x73\x48\x55\x51"
-  "\x5b\x83\x2a\x2f\x95\xa1\xca\x6b\x27\x51\x65\x23\x1c\x2d\x70\x58"
-  "\xe0\x48\x3f\x09\xbe\x46\x68\xdc\x65\x84\xd2\x6a\x69\xc3\x13\xa7"
-  "\x90\xba\xc2\x54\x83\xf0\x98\xa9\x2b\xd4\xef\x67\x3d\xa3\x91\x9a"
-  "\xfe\x8f\x06\xd1\x6f\x6a\x28\x38\xe7\x86\xd3\xab\x4d\x06\x54\x51"
-  "\x6b\xc4\xe7\x4b\xe1\xbc\x5b\x5a\x2d\xe4\x6f\x29\xc3\x7b\x71\x1a"
-  "\x2a\xd2\xcb\x91\x29\xe7\x6b\x44\x63\x0d\xdd\x2b\x38\x3e\x1b\x4c"
-  "\x6d\xa1\x35\x8f\x10\x1c\x18\x9a\x8b\x2c\x52\x7d\x6d\x50\x31\x36"
-  "\x7e\x5b\xd3\x13\xec\xdc\xc7\xf2\x76\xa4\xea\xa5\x93\x67\x68\x3c"
-  "\x5e\x0f\xf7\x25\x54\x35\x1c\x45\xf8\x5b\x53\xf8\x22\x84\xc6\x9a"
-  "\x11\xc2\xb6\xa8\x4e\xae\x43\x2f\xc5\x23\x6f\xdc\xff\x6c\xf9\x4d"
-  "\xd7\xb3\x1a\x28\xf6\x52\x13\x94\xf1\x8a\xf1\x66\x19\xab\x56\x54"
-  "\x21\x38\xd7\xa7\x2a\x4e\x8f\x3c\xe3\x91\x0a\xdb\xd7\x94\x1b\x9c"
-  "\xff\x12\xd4\x9f\x39\x0d\x34\x8d\x6d\x8b\x6d\x8a\xed\x8b\xf3\xb3"
-  "\xda\xbc\x3a\xd6\x80\xd2\x8c\x48\x55\x9d\x0a\x7f\x93\x69\x43\x35"
-  "\xba\x8a\xf4\xd4\xef\x0d\x74\x8f\xaf\x11\xe0\xe2\x04\xc6\x02\xfc"
-  "\x76\x03\xff\xf7\x14\xc6\x54\x88\x9a\x60\xca\xfd\x5a\xfb\x98\x0a"
-  "\xf1\xe5\x30\x75\x35\x86\xc3\xd4\xf5\x11\xe2\x98\xba\xb6\x81\x60"
-  "\x2a\x24\xa0\x73\x62\xea\xda\x10\xc7\x98\xba\xa6\x16\xc7\x54\x88"
-  "\x0e\x30\x65\xe0\x63\xea\xfa\x38\xe9\x98\xba\x16\xdb\x71\x98\x0a"
-  "\xd1\xc8\xc3\xd4\xb5\x10\x3e\xa6\xae\x46\x3a\xc0\x14\x1b\xa7\xee"
-  "\x3f\xe7\x04\xa6\x6c\xe2\xd4\xf5\xbd\x1c\xa6\x6e\xe4\x88\x63\xaa"
-  "\xe1\x32\x8b\xa9\x4e\x1a\xa7\x1a\x56\x3b\xc6\x54\x43\x9c\x03\x4c"
-  "\x41\x9c\x0a\x69\x13\xa7\x6e\x6c\x92\x8e\xa9\x86\x7d\x1d\x88\x29"
-  "\x99\x71\xaa\xa1\x80\x8f\xa9\xeb\xdb\xc5\x31\x15\xca\xc6\xa9\x1e"
-  "\xdf\xb7\x8f\xa9\x50\x9b\x38\xd5\xd8\x95\xc3\x54\xd3\x79\x71\x4c"
-  "\x35\x8d\x22\x98\x0a\xed\xa4\x71\xaa\xf1\xb4\x63\x4c\x35\x1e\x10"
-  "\xc7\x54\x28\xc4\xa9\x90\x36\x71\xaa\xe9\x86\x74\x4c\x35\x79\x76"
-  "\x1c\xa6\x42\x65\xc6\xa9\x46\x03\x1f\x53\x8d\xc8\x01\xa6\xd8\x38"
-  "\xf5\xcc\x1a\x27\x30\x65\x13\xa7\x8c\xd3\x38\x4c\xb5\x0c\x13\xc7"
-  "\x54\x73\x1e\x8b\xa9\x4e\x1a\xa7\x9a\x07\x39\xc6\x54\xb3\xca\x01"
-  "\xa6\x20\x4e\x85\xb6\x89\x53\x2d\xa1\xd2\x31\xd5\x1c\xdd\x81\x98"
-  "\x92\x19\xa7\x9a\x47\xf3\x31\x65\x9c\x20\x8e\xa9\x30\x36\x4e\x4d"
-  "\x79\xbe\x7d\x4c\x85\xd9\xc4\xa9\x96\xdd\x1c\xa6\x4c\x99\xe2\x98"
-  "\x6a\xbd\x48\x30\x15\xd6\x49\xe3\x54\xeb\x4a\xc7\x98\x6a\x8d\x15"
-  "\xc7\x54\x18\xc4\xa9\xd0\x36\x71\xca\x54\x28\x1d\x53\xad\x7b\x3a"
-  "\x0e\x53\x61\x32\xe3\x54\x6b\x3e\x1f\x53\x2d\x5b\xc5\x30\xd5\x82"
-  "\x75\x9f\x02\x30\x15\x07\xba\x0f\x30\xe4\x7d\x8c\x60\xaa\x15\x30"
-  "\xf5\xa1\x2d\xa6\x7e\x69\xab\xfb\xcc\xee\x96\x9b\x98\xa2\x7b\xb4"
-  "\xc5\x94\x05\x30\xd5\xca\x60\xca\xe2\x6f\xd5\x7d\xd5\xf5\xc5\xe0"
-  "\xab\x4b\xa8\x3a\x02\xf0\xb4\x9e\xc5\xd3\x2f\x80\x27\x78\x1f\x0b"
-  "\xbc\x6f\xc5\xa9\x1a\x14\x6e\x20\xef\xd5\x02\xef\x6b\xb1\xc5\x52"
-  "\x4b\x1d\x85\x31\x84\xb1\x63\xc5\x51\xe5\x1c\xc0\xcf\xfc\xe3\xa8"
-  "\x32\x09\x8e\xc5\x70\xa4\xc2\x81\x8e\xa3\x8a\x3a\xc4\xf4\xd9\x73"
-  "\xf8\x39\xc6\xe2\xc7\x7c\xc4\x31\x7e\xcc\x9b\xa5\x69\x3c\xba\x9f"
-  "\x74\xfc\x98\xad\xeb\xff\xa8\xc2\xc7\x9f\xa1\xf1\xf8\x58\x82\x91"
-  "\x4b\x28\xdc\x84\xbc\xe9\x29\xba\x9e\x9e\x91\x48\xb5\xc4\x8c\xa8"
-  "\xcc\x37\x90\x2a\xf3\x67\x78\x5f\x6b\xdd\x39\x87\x3c\x8f\x1a\xbf"
-  "\x42\x15\xd7\x6a\x50\x45\x63\x39\xaa\xb0\xc0\x71\x09\x0e\x28\x63"
-  "\xf8\x74\xdb\xf7\x35\xb0\xef\x6b\xd9\x0b\x79\xf9\x89\xbf\xaf\x25"
-  "\x97\x79\xdf\x58\x78\xdf\x16\xee\x7d\xab\x01\x8b\xe0\x97\x3e\x16"
-  "\x56\x27\x86\x1b\x50\xd7\xb9\x26\x9a\x6e\x61\x31\x88\xfd\x72\xf4"
-  "\x84\x11\x85\xc7\x83\xaf\xde\x04\x0c\xd6\x6e\x45\x69\x29\x80\xc1"
-  "\x16\x23\xfe\xae\x6f\xa8\x4e\x6f\x06\x0c\x9a\x6b\x68\xb0\x5b\x2b"
-  "\xc6\xe0\x2f\x18\x83\x26\x93\x45\x14\x83\xa0\x13\x19\x0c\x82\x4e"
-  "\x6c\x17\x83\xb6\x3a\x91\x5e\x7d\x13\x83\x4a\x45\x9e\x28\x06\x95"
-  "\x68\x87\x55\x27\xfe\xd7\x31\xa8\x44\xa1\x0e\x31\xa8\x44\x3a\x49"
-  "\x9a\x50\xa9\xd8\x22\x19\x83\x4a\x94\xdc\x61\x18\x54\x2a\x86\x39"
-  "\xc4\xa0\x52\xa1\x69\x1f\x83\x21\x1a\x59\x18\x54\xa2\xa9\x7c\x0c"
-  "\xd2\xe9\x0e\x30\xc8\xc6\x41\xd0\x95\xed\x63\x90\x8b\x83\x4a\xaa"
-  "\x3b\x87\x41\xb7\xde\xe2\x18\x54\x0e\xb2\xea\xca\xff\x3e\x06\xa9"
-  "\x4a\xc7\x18\xa4\xb6\x4b\xd2\x90\x4a\x37\x7f\xe9\x18\xa4\x4c\x1d"
-  "\x87\x41\xe5\x41\xc7\x18\x54\x16\x38\x81\x41\x79\x71\x50\x49\xe9"
-  "\x79\x18\x54\x52\x6e\xe2\x18\x0c\x65\xe3\x20\xe8\xd0\x76\x31\x68"
-  "\xa3\x43\x95\x6e\x39\x1c\x06\xef\x2b\x14\xc7\xa0\xfb\x5e\xab\x0e"
-  "\xfd\xef\x63\xd0\x7d\xbc\x63\x0c\xba\x07\x48\xd2\x9c\xca\xfb\x76"
-  "\x48\xc7\xa0\x7b\x7a\xc7\x61\xf0\xbe\x51\x8e\x31\x78\x9f\xb6\x7d"
-  "\x0c\x86\xca\x8c\x83\xee\xb1\x7c\x0c\xba\xad\x72\x80\x41\x36\x0e"
-  "\x82\x6e\x6d\x1f\x83\x36\x71\xb0\x8b\x0f\x87\xc1\xae\xfd\xc4\x31"
-  "\xe8\x31\xcc\xaa\x5b\xff\xfb\x18\xec\xf2\x83\x63\x0c\x76\xd9\x23"
-  "\x49\xa3\x2a\xbb\x0e\x92\x8e\x41\x0f\xb7\x8e\xc3\xa0\xc7\x11\xc7"
-  "\x18\xf4\xd8\xec\x04\x06\x65\xc6\xc1\x2e\x75\x7c\x0c\x76\xf1\x14"
-  "\xc7\x60\x18\x1b\x07\x41\xe7\xb6\x8b\x41\x1b\x9d\xab\xec\xba\x81"
-  "\xc3\xe0\xfd\x5b\xc4\x31\xd8\xed\xa0\x55\xe7\xfe\xf7\x31\xd8\x6d"
-  "\x92\x63\x0c\x76\x0b\x94\xa4\x69\x95\xf7\xef\x95\x8e\xc1\x6e\xab"
-  "\x3a\x0e\x83\xf7\x87\x3a\xc6\xe0\xfd\xba\xf6\x31\x18\x26\x33\x0e"
-  "\x76\x9b\xc5\xc7\x60\xd7\x6c\x31\x0c\x5a\x40\x17\xb7\x6e\x1e\x96"
-  "\x6e\xc9\x8d\xd1\x78\x2b\xb4\xc8\xa4\x7e\x51\x5f\x9d\xd0\x80\x5e"
-  "\xba\x01\xf6\x89\xbf\x81\x5e\xbf\xa1\x42\xe6\xdc\x18\x0f\xd0\x85"
-  "\xf9\x36\xfa\x99\x19\x5b\x66\xca\xfe\x1a\xad\x9d\x83\xdc\x40\x7f"
-  "\xe3\x76\x3c\xa0\xfa\x82\x11\xe1\xe7\x2f\xc5\xe5\xb9\xc4\x95\x07"
-  "\xf7\x13\xd0\xbf\xeb\x54\xcc\x37\xe6\x16\x3d\xaa\x1d\x8e\x94\x15"
-  "\xb5\x7a\xb0\xc3\x62\xc6\xbf\xd8\x2e\x17\x94\x9e\xab\x36\x5e\x41"
-  "\x6e\xa6\xff\x68\xfa\x80\xbd\xd5\xdd\x17\x22\x85\x6f\x2d\x6d\xc1"
-  "\x76\xc5\xf6\xc2\x36\xd6\x2e\xa6\x69\xb8\xee\x64\x15\x60\xcc\xf4"
-  "\x1f\x5d\x9f\x22\xb8\x4e\x50\xaf\x2a\x3d\xcf\x4a\xc7\x86\xe7\x66"
-  "\x66\xde\x82\xd2\x33\xbd\xe2\x14\x12\xfc\x76\x6c\x01\xfd\xe6\x9c"
-  "\xad\x42\x34\x36\x3a\xef\x36\xd8\xaa\xfb\x1e\xe7\x6c\xe5\xe5\xce"
-  "\xb7\x95\x90\xae\xf2\xea\x2e\xdd\x56\xdd\x8f\x11\x5b\x75\xdf\xee"
-  "\xc0\x56\x4e\xe2\x2a\x24\xdf\x46\x8f\xdc\x06\x5b\x79\xe9\x9d\xb3"
-  "\x95\xf7\xa0\x36\xb6\x12\xe0\xff\xde\xc3\xa4\xdb\xca\xcb\x44\x6c"
-  "\xe5\x55\x23\x6e\xab\x50\x27\x71\x15\xaa\xb1\xe1\xcd\xb7\xc1\x56"
-  "\x2a\x4f\xe7\x6c\xa5\x9a\xc6\xb7\x95\x10\x4f\x55\x4d\x97\x6e\x2b"
-  "\x95\x8e\xd8\x4a\xe5\xe6\xc0\x56\x4e\xe2\x2a\x34\xdf\x86\xdf\xdd"
-  "\x06\x5b\xf5\x08\x74\xce\x56\x3d\x56\xb7\xb1\x95\x00\x9f\xea\x91"
-  "\x23\xdd\x56\x3d\x26\x10\x5b\xf5\x08\x10\xb7\x55\x98\x93\xb8\x0a"
-  "\xd3\xd8\xf0\x90\xdb\x60\xab\x9e\xb1\xce\xd9\xaa\xe7\x5e\xbe\xad"
-  "\x84\xda\xfd\x9e\x07\xa5\xdb\xaa\x67\x3a\xb1\x55\xcf\xa9\x62\xb6"
-  "\x32\xe7\x06\xe7\x7a\x83\x0d\x9a\xd7\x07\xc7\x7b\x27\x23\xaa\xc5"
-  "\x0f\xec\xa6\x06\xbb\x2d\xd3\xa2\xd6\x5c\xb0\x9b\xc1\x84\x5e\x9a"
-  "\x77\x86\xae\xaa\x37\xa3\x16\xb0\x59\xb3\x3a\x38\xbf\xda\x50\x87"
-  "\xc7\x1c\xfd\xe9\x9c\x52\x5d\x38\x65\x9e\x0a\x61\xbb\x61\x3b\x60"
-  "\xdb\xd1\x60\x37\xc6\x8e\xea\x99\x5b\xcd\xea\xc9\x25\xe3\x2e\x9f"
-  "\xa1\xe7\xea\x69\x1a\xbf\x2f\xad\xf6\x62\xbe\x0b\x84\xd7\xa1\xae"
-  "\xda\x97\xf1\x3b\xa9\xc7\xe1\xf4\x6a\x43\x0d\xf0\x83\x6b\x88\xe1"
-  "\x66\x67\x74\x6a\xf3\x6b\x3a\x4f\x73\x75\x64\x30\xdd\xcb\x3b\xc0"
-  "\xd4\x2b\x12\xa5\x5d\x46\xf7\x61\xfe\x90\x65\x41\x9a\xa5\xb3\x11"
-  "\xb5\x73\x66\x29\xc5\xcc\x5d\x9b\xcf\xe4\xd1\x1b\xec\xa2\xa1\xaf"
-  "\xdb\x8c\xe9\xbe\x1e\x87\xaa\x2f\x64\x33\x7e\x6b\xcb\x11\x18\xbf"
-  "\xfd\xa4\x53\x01\xcf\x0c\xa0\xd5\xc1\x5b\xb3\xab\x90\x96\x6e\x05"
-  "\x1b\xe3\xf9\x44\x4a\x1f\xf7\x8d\x2d\x52\x6d\xfc\x07\x66\xfc\xb7"
-  "\x45\xcb\x8e\xdf\x02\x3b\xe1\xe7\x33\xe3\xb7\xe2\x6d\xc6\x6f\x41"
-  "\x99\x6f\x8e\xdf\x52\xfe\x61\x2b\x1e\xbf\x65\x39\xa3\xe9\x63\x7d"
-  "\xf7\xb9\xb3\x68\x1a\xde\xbd\x67\x55\x83\x01\xe1\xf7\xaf\x6a\x28"
-  "\x45\x69\x09\x48\x55\xd5\x52\x87\x52\x1b\x68\x43\x55\xfa\x45\x14"
-  "\x7e\x03\xf3\x60\x8c\x17\x75\x1e\xf1\xeb\x1f\xe2\x2c\x67\x74\x7d"
-  "\xf4\x4a\x75\x46\x15\xb4\x4c\x36\xf3\x78\xe2\x80\x33\x7b\x80\x1f"
-  "\xe2\xaa\xd3\xcf\x81\x4f\xa6\x04\x54\x9b\x7e\xc6\x7e\x8a\x83\xf3"
-  "\xc3\x6f\xf2\xeb\x5e\x53\x9e\xc6\x69\xd8\x67\xf8\x7b\x53\x75\xbc"
-  "\x81\xb9\xc6\x7a\x1e\xe3\xc2\x3b\x39\x1d\x55\x27\xb7\xa0\x2a\x88"
-  "\xe6\xf0\x3c\xf5\x77\x91\x35\x22\x38\x0a\x51\xb3\x38\x32\x78\x27"
-  "\xbb\x5f\x6b\x1f\x47\x21\x1a\x0e\x47\xbd\xce\xbb\x86\xa3\x5e\x79"
-  "\xae\xe3\xa8\x57\x8c\x7c\x1c\x85\xe8\xf8\x38\x7a\x60\x9c\x74\x1c"
-  "\xf5\x1a\x20\x1d\x47\x3e\x06\xd7\x70\xd4\xeb\x34\xc1\x91\x4f\x09"
-  "\xc1\x51\xaf\x13\x1c\x8e\x98\xb9\x51\xb7\x09\x47\x3e\x53\x1d\xe0"
-  "\x88\x8d\x47\x21\x10\x8f\xee\x3f\xe7\x04\x8e\x6c\xe2\x51\xef\x81"
-  "\xae\xe1\x48\x73\xda\x75\x1c\x69\xb6\xb9\x80\xa3\x36\xf1\xa8\x77"
-  "\x9e\x74\x1c\x69\x12\xa4\xe3\x48\x13\xe8\x1a\x8e\x7a\xf7\x27\x38"
-  "\x7a\xc0\x48\x70\xd4\xdb\x97\xc3\x11\x33\xdf\xec\x36\xe1\xe8\x81"
-  "\xcd\xe2\x38\x0a\x65\xe3\x51\x08\xc4\xa3\x1e\xdf\xb7\x8f\xa3\x50"
-  "\x9b\x78\xf4\x60\xa2\x6b\x38\x7a\xb0\xbf\xeb\x38\xea\x73\x55\x3e"
-  "\x8e\x42\xdb\xc4\xa3\x07\x4f\x4b\xc7\x51\x9f\x03\xd2\x71\xd4\x27"
-  "\xdd\x35\x1c\x3d\x38\x9b\xe0\xa8\x4f\x10\xc1\xd1\x83\xb1\x1c\x8e"
-  "\x98\x39\x7c\xb7\x09\x47\xbd\xeb\x1d\xe0\x88\x8d\x47\xa1\x10\x8f"
-  "\x9e\x59\xe3\x04\x8e\x6c\xe2\xd1\x43\x07\x5d\xc3\xd1\x43\xb3\x5d"
-  "\xc7\xd1\x43\xc3\x5c\xc0\x51\x9b\x78\xd4\xb7\xbf\x74\x1c\x3d\xe4"
-  "\x26\x1d\x47\xbe\x65\xae\xe1\xe8\xa1\xbd\x04\x47\xbe\xab\x08\x8e"
-  "\x1e\xda\xce\xe1\x88\x99\x17\x79\x9b\x70\xe4\x3b\x58\x1c\x47\x61"
-  "\x6c\x3c\x0a\x85\x78\x34\xe5\xf9\xf6\x71\x14\x66\x13\x8f\xb4\xee"
-  "\xae\xe1\xe8\xe1\xbd\xae\xe3\xe8\xe1\x65\xf2\x71\x14\xd6\x26\x1e"
-  "\x69\x67\x4b\xc7\xd1\xc3\x63\xa5\xe3\xe8\x61\x95\x6b\x38\x7a\xd8"
-  "\x4c\x70\xd4\xf7\x18\xc1\xd1\xc3\x0d\x1c\x8e\x98\xb9\xa6\xb7\x09"
-  "\x47\x7d\x53\xc4\x70\x84\xd7\x22\x78\x9f\xac\x0b\xd1\xb0\x76\x31"
-  "\x0a\xdc\x88\xff\xb6\xa0\x80\xa6\x2c\xed\xe6\x43\x29\x64\x3d\x00"
-  "\xbd\x52\xcb\xf4\xf7\x0a\xdd\x7f\xff\x36\xf0\x8b\x3a\x38\x3b\xfc"
-  "\x34\x59\xa3\x01\xaf\x0b\x72\x3d\x2d\x0e\x3d\x85\xd7\x65\x50\xf6"
-  "\x3b\x85\xd7\xb1\xba\xb9\x76\x80\x5a\x64\xed\x80\xc9\xe2\x6b\x07"
-  "\xb4\xac\xb7\xce\xbb\xdd\xca\xcd\xbb\x55\xf6\xdb\xe6\x70\xde\xad"
-  "\xb2\x5f\x4e\xe1\x64\xa9\x78\xe8\xc7\xcc\xff\xba\xde\x2b\x38\xbe"
-  "\x29\xab\x5f\x31\xbc\x73\x32\x79\xf7\x47\x7c\x91\x53\xf3\x71\xb7"
-  "\xda\xe0\xa4\xdf\xd8\x89\x53\x51\x3a\xbd\x46\x5f\x4c\xfb\x04\x67"
-  "\xd3\x79\xc1\xc5\x12\xcb\x52\xe7\xd8\xde\x21\x2a\x61\x7b\xff\x71"
-  "\x2c\x6b\x6f\x32\xcf\x59\x2d\xb2\x6e\xc1\x64\xf1\x75\x0b\x84\xed"
-  "\xfd\x47\xc7\xf3\x9c\x95\x7f\x54\x48\xb7\xf7\x23\x15\xac\xbd\x0d"
-  "\x4d\x59\x7f\x54\x71\xf6\xfe\x63\x86\x74\x7b\x3f\x72\x80\xd8\xfb"
-  "\x6c\x2e\xed\x13\xa2\xa2\xf3\x42\x24\x96\xe5\x8f\x91\xed\xd8\x5b"
-  "\x04\xdf\x7e\x07\x88\xbd\xd9\x35\x13\xd4\x22\x6b\x26\x4c\x16\x5f"
-  "\x33\x41\xd8\xde\x7e\xab\x1d\xdb\xdb\x6f\x9e\x74\x7b\xfb\x0d\x27"
-  "\xf6\x0e\x01\x7c\xfb\xa5\x73\xf6\xf6\x73\x72\x5d\x01\x5b\x7b\xfb"
-  "\x0d\x20\xf6\x3e\xb7\x0a\xec\x0d\xf8\x0e\x91\x88\x6f\xbf\x32\xc7"
-  "\xf6\x0e\x15\xc1\xf7\xa3\x03\x58\x7b\xb3\xf8\x16\x59\xaf\x61\xb2"
-  "\xf8\x7a\x0d\xc2\xf6\xee\xdf\xec\xd8\xde\xfd\xcf\x4a\xb7\x77\xff"
-  "\xed\xac\xbd\x01\xdf\xfd\x0d\x9c\xbd\x1f\x9d\x25\xdd\xde\xfd\x0b"
-  "\x88\xbd\xff\x93\x42\xfb\x84\x02\xbe\x43\x25\x96\xe5\xd1\xc0\x76"
-  "\xec\x2d\x82\xef\xc7\x0a\x88\xbd\xd9\xb5\x22\xd4\x22\x6b\x45\x4c"
-  "\x16\x5f\x2b\x42\xd8\xde\x8f\xcd\x70\x6c\xef\xc7\xc6\x4b\xb7\xf7"
-  "\x63\xbe\xc4\xde\xa1\x80\xef\xc7\xa2\x39\x7b\x3f\x76\x4a\xba\xbd"
-  "\x1f\xf3\x24\xf6\xae\x8d\x07\x7b\x03\xbe\x43\x25\xe2\xfb\xb1\xad"
-  "\x8e\xed\x1d\x26\x82\x6f\x7f\x4f\xd6\xde\x2c\xbe\x45\xd6\xa9\x98"
-  "\x2c\xbe\x4e\x85\xb0\xbd\x75\x27\x1d\xdb\x5b\x77\x48\xba\xbd\x75"
-  "\x19\xac\xbd\x01\xdf\xba\x63\x9c\xbd\xfd\xc7\x4a\xb7\xb7\x2e\x85"
-  "\xd8\xfb\x7c\x2c\xed\x13\x06\xf8\x0e\x93\x58\x16\x7f\x8d\x98\xbd"
-  "\xbd\xc1\xde\x47\x80\xc7\x00\xef\xc8\xb7\xe4\x02\x4f\x31\xf3\xed"
-  "\x5e\x9d\x1c\x88\x9e\x6c\xc4\xb6\x7f\xdc\x08\x6d\x75\x7e\x87\xad"
-  "\x97\xa1\x7c\xfc\xac\xcb\x73\x87\x95\x8f\xef\x10\x9d\x3b\xac\x7c"
-  "\x3c\x4f\xf2\xdc\x61\xe5\xe3\xd1\x1c\x07\x7a\x7c\x33\xe7\xd3\x27"
-  "\x98\xf8\x21\x69\x4e\xb1\xf2\xf1\x08\xc1\x75\x34\x94\x8f\x23\x3c"
-  "\xa7\x98\x5e\x73\x21\xd2\x92\x27\x87\x1b\x3d\xe1\xd6\xbe\xaf\x43"
-  "\xf0\x7a\x0f\x2a\x71\x5f\x0f\xa8\x85\x76\x4b\xd3\x61\xeb\x76\x28"
-  "\x07\x54\xba\xee\xeb\x01\x1b\xc4\x7d\x3d\x60\x99\x74\x5f\x0f\x18"
-  "\xcb\xf1\xaf\x01\xd9\x9c\xaf\x07\x4a\x9f\x3f\xae\x1c\x30\x5c\x70"
-  "\x3d\x0f\xe5\x13\xf5\xc4\xd7\xbf\x1e\xb0\xe4\xc9\xe1\x65\x03\x0c"
-  "\x4e\xf8\x1a\xea\x75\x88\x83\x7a\xfd\xe4\x31\xf0\x75\x7e\x87\xad"
-  "\x1f\xa2\x7c\x72\xbf\xeb\xbe\x7e\x72\xa5\xb8\xaf\x9f\x9c\x2d\xdd"
-  "\xd7\x4f\x06\x72\xdc\xef\xc9\x14\xce\xd7\x4f\xa9\xa4\xfb\xfa\x49"
-  "\x9d\xe0\xba\x22\xca\x81\x35\xc4\xd7\x17\xb5\xe0\x6b\x19\x9c\xf0"
-  "\xc9\x53\xed\xfb\x3a\x14\xaf\x7f\xe1\xa0\x5e\x07\x1c\x80\xf6\x5a"
-  "\xd3\x61\xeb\x98\x28\x03\xb6\xb8\xee\xeb\x80\x79\xe2\xbe\x0e\x98"
-  "\x24\xdd\xd7\x01\x7e\x1c\xef\x0c\x88\xe3\x7c\x1d\x60\x92\xee\xeb"
-  "\x00\xb5\xe0\xfa\x26\xca\xa7\x0e\x13\x5f\x5f\x5a\x61\xc9\x93\xc3"
-  "\x47\x03\x44\xf9\xbf\x8d\xaf\xa1\x5e\x87\x3a\xa8\xd7\x4f\x6f\x05"
-  "\x5f\xe7\x77\xd8\x7a\x2a\xca\xa7\x73\x5c\xf7\xf5\xd3\xd3\xc4\x7d"
-  "\xfd\xf4\x18\xe9\xbe\x7e\x5a\xc5\x71\xde\xa7\x27\x70\xbe\x7e\xba"
-  "\x4e\xba\xaf\x9f\x46\x82\xeb\xac\x28\x07\x95\x10\x5f\xff\x56\x07"
-  "\xbe\x96\xc1\x85\x9f\xde\xd3\xbe\xaf\xc3\xf0\x9a\x2b\x0e\xea\xf5"
-  "\x60\xd0\xf5\x61\x9a\x0e\x5b\xd7\x45\x39\x78\xa9\xeb\xbe\x1e\x1c"
-  "\x2a\xee\xeb\xc1\x83\xa4\xfb\xfa\x7f\x4c\x1c\xdf\x1e\x1c\xc4\xf9"
-  "\x7a\xf0\x09\xe9\xbe\xfe\x9f\x7a\xc1\xf5\x5e\x94\xff\x53\x40\x7c"
-  "\x7d\x79\xac\x25\x4f\x0e\x0f\x1f\x5c\x2c\x87\x87\x2f\x28\x44\x1e"
-  "\x7c\x7f\x3f\xb3\xa2\x63\xb9\xf8\x33\xb3\x5d\xf7\xf7\x33\xc3\xc4"
-  "\xfd\xfd\x4c\x3f\xe9\xfe\x1e\x52\xcf\x71\xf1\x67\x02\x38\x7f\x3f"
-  "\x73\x58\xba\xbf\x87\x9c\x12\xe6\xe2\x43\x32\x5c\xe3\xe2\xcf\x64"
-  "\xcb\xe1\xe2\xf6\xfe\x0e\x4c\xe8\x58\x3e\x1e\x38\xcd\x75\x7f\x07"
-  "\xfa\x8b\xfb\x3b\xb0\x87\x74\x7f\x0f\x3d\xc5\xf1\xf1\x40\x2d\xe7"
-  "\xef\xc0\x3d\xd2\xfd\x3d\xb4\x42\x98\x8f\x0f\x4d\x71\x8d\x8f\x07"
-  "\xa6\xcb\xe1\xe3\xf6\xfe\x7e\x36\xb6\x63\x39\xf9\xb3\xe3\x5c\xf7"
-  "\xf7\xb3\xbd\xc5\xfd\xfd\xac\x42\xba\xbf\x87\x55\x70\x9c\xfc\x59"
-  "\x9b\xfe\xef\x67\x37\x4b\xf7\xf7\xb0\x03\xc2\x9c\x7c\xd8\x2c\xd7"
-  "\x38\xf9\xb3\xf1\x72\x38\xb9\xbd\xbf\x87\x4f\xe8\x58\x5e\x3e\x7c"
-  "\x84\xeb\xfe\x1e\xde\x55\xdc\xdf\x7f\xba\x2a\xdd\xdf\x7f\x3a\xc0"
-  "\xf1\xf2\xe1\x88\xf3\xf7\x70\xe9\xeb\x67\x2a\xff\xb4\x5d\x98\x97"
-  "\xff\x69\xaa\x6b\xbc\x7c\x78\xb4\x1c\x5e\x6e\xef\xef\xe7\x46\x77"
-  "\x2c\x37\x7f\x6e\xa0\xeb\xfe\x1e\xd1\x2c\xee\xef\x11\x67\xa5\xfb"
-  "\x7b\xc4\x76\x8e\x9b\x8f\xb0\xe9\xff\x7f\x6e\x85\x74\x7f\x8f\x28"
-  "\x10\xe6\xe6\x23\xc6\xba\xc6\xcd\x9f\x8b\x90\xc3\xcd\xed\xfd\x1d"
-  "\x34\xb8\x63\xf9\x79\xd0\x43\xae\xfb\x7b\xe4\x45\x71\x7f\x8f\x3c"
-  "\x2e\xdd\xdf\x23\x0b\x38\x7e\x3e\x52\xcf\xf9\x3b\x28\x41\xba\xbf"
-  "\x47\x66\x08\xf3\xf3\x91\xc3\x5d\xe3\xe7\x41\x41\xae\xf7\x93\xbf"
-  "\xa0\xc2\xdc\x5c\xea\xfa\x8f\xd5\x09\xd6\x39\x77\xa3\xb8\xf5\x1f"
-  "\x95\x2f\x28\x90\xd8\xda\x32\xca\xe7\xa7\x75\xea\xf5\x1f\x95\xa3"
-  "\x1c\xaf\xff\xa8\x1c\x25\x6d\xfd\x47\xe5\xf3\x63\xa4\x8f\xc7\x7f"
-  "\x5e\xc5\x69\x84\xe7\x6d\xf4\xff\x0b\x4c\xbd\xee\xd4\xeb\x42\x2a"
-  "\x47\xf1\xd7\x85\x54\x8e\x62\xd6\x85\xa4\xd7\x5c\x29\x91\xa7\x45"
-  "\x5e\xf0\x75\xfd\xbb\xc0\x98\x7a\xac\x43\xa4\xae\x43\xc9\x61\xfb"
-  "\x85\x8b\x1c\xb6\xc7\x9c\x16\xc7\xf6\x98\x61\x9d\x7a\x1d\x4a\xe5"
-  "\xe8\x83\x8e\xb1\x3d\xba\x40\xda\x9a\x23\x63\xa4\xaf\x7b\xa3\x1c"
-  "\x5d\xcf\xe9\xa1\x31\x36\xfa\xf7\xcf\x03\x3a\x0e\xdb\x32\xd7\xa7"
-  "\x54\x8e\x3e\xc6\xc7\xf6\x0b\x7a\x82\xed\xab\x6e\xf2\x74\xd7\x18"
-  "\xa3\xeb\xdf\x41\x42\xca\xb0\xe6\x92\xba\x1e\x26\x87\xed\x3f\x1f"
-  "\xe1\xb0\x1d\xb2\x5f\x1c\xdb\x21\x3e\x9d\x7a\x3d\x4c\x65\xf0\x06"
-  "\xc7\xd8\x0e\x4e\x96\xb6\x96\x49\xb0\x59\x3a\xb6\x83\xcb\x38\xed"
-  "\x17\xe2\xc9\x61\x3b\xd4\xa3\x03\xb1\x2d\x33\x6e\x07\x6f\xe7\x63"
-  "\xfb\xcf\x07\x08\xb6\xaf\x47\xca\xd3\x98\x21\x27\x5c\xff\xee\xf3"
-  "\xe2\x66\xac\x2f\xa5\xae\xcb\xc9\x61\x3b\x74\x13\x87\xed\x17\xed"
-  "\xd6\x85\xe2\xb0\x1d\x76\xb5\x53\xaf\xcb\xa9\x0c\x4b\x74\x8c\xed"
-  "\xb0\x09\xd2\xd6\x48\x09\x3b\x29\x1d\xdb\x61\x9b\x39\x9d\x1b\x56"
-  "\xc7\x61\xfb\xc5\xda\x8e\xc3\xb6\xcc\xf5\x3a\x95\x61\xab\xf8\xd8"
-  "\x0e\xcd\x27\xd8\xbe\xb1\x5d\x9e\x9e\x7e\xb1\xc4\xf5\xef\x5c\x2f"
-  "\xa5\x63\x2d\x2d\x75\x7d\x50\x0e\xdb\x63\x97\x72\xd8\x7e\x69\x9e"
-  "\x38\xb6\xc7\x55\x76\xea\xf5\x41\x95\xe3\xda\x59\xff\x67\x9c\xa3"
-  "\xf5\x7f\x04\xe6\x0a\x8f\x93\xb1\xee\xc5\xb8\x74\x4e\xd3\x8f\x3b"
-  "\xcc\x61\xfb\xa5\xd2\x0e\xc4\xb6\xcc\xb8\x3d\x2e\x96\x8f\xed\xb1"
-  "\x09\x04\xdb\x46\x24\xaf\xef\xe0\xa5\x0c\xd7\xbf\xeb\x8d\x9f\x8a"
-  "\xfb\x0d\xa4\xae\x53\xca\x61\x3b\x7c\x12\x87\xed\xf1\xe3\xc4\xb1"
-  "\x1d\xb1\xad\x53\xaf\x53\xaa\x8c\x18\xe8\x18\xdb\x11\x9e\xd2\xd6"
-  "\x74\x89\x90\x31\x0f\x3e\x62\x2a\xd7\x7f\x11\x61\x33\xfe\x7d\x7c"
-  "\x41\xc7\x61\x5b\xe6\xfa\xa5\xca\x88\x20\x3e\xb6\xc3\x23\x08\xb6"
-  "\x5b\x26\xc8\xeb\x27\x19\x1f\xe7\x7a\x3f\xc9\x84\x38\xe6\x1b\xa6"
-  "\xc4\xf5\x52\x39\x6c\xbf\x3c\x84\x5b\x9b\x68\xc2\xa4\xb6\xd8\xe6"
-  "\xd6\x26\x7a\x65\x5e\xa7\x59\x2f\x55\xf9\xf2\x0d\xc7\x38\x7e\xf9"
-  "\x84\xb4\x3e\x91\x57\x26\x49\xc7\xf1\x2b\x7e\x5c\x9f\xc8\x2b\x36"
-  "\xe3\x5f\x26\x58\xf7\x24\xef\x80\x35\x8b\x5e\x31\x3b\x5e\xb3\xe8"
-  "\x95\x53\xb7\x6d\x1d\x55\xe5\x2b\x1e\xfc\x35\x8b\x5e\x1e\x60\x61"
-  "\xea\x82\x69\xab\xbc\x7e\x95\x09\x09\xae\xf7\xab\xbc\x46\xbe\xef"
-  "\x4a\x5c\xb7\x95\xab\x0b\x13\x47\x71\x75\xe1\xb5\xe9\xe2\x75\xe1"
-  "\xd5\xa5\x9d\x67\xdd\xd6\x57\x15\x8e\xeb\xc2\x44\xbd\xb4\x3e\x94"
-  "\x57\x65\xac\x03\xf3\x6a\x00\xd7\x87\xf2\x6a\x02\x57\x17\x5e\xdb"
-  "\xd3\x71\x75\xe1\xb5\xae\x8e\xeb\xc2\xab\x75\xb7\x6f\x3d\xd7\x57"
-  "\xd5\xfc\xba\x30\x31\x90\xd4\x05\x7a\x80\xbc\x7e\x98\xd7\x64\x7d"
-  "\xff\xe6\xd7\x85\xc9\xe9\xcc\xb7\x6f\x89\xeb\xc7\x72\x75\x21\x72"
-  "\x1c\x57\x17\x26\xdb\xf1\x79\xae\x2e\x4c\x5a\xdd\x79\xd6\x8f\x9d"
-  "\xd4\xdd\x71\x5d\x88\xac\x97\xd6\xe7\x32\x69\x9e\xf4\xba\x30\xc9"
-  "\x66\xfe\xd3\x24\x9b\xf9\x4f\x93\x4b\x3b\xae\x2e\x4c\xf6\x71\x5c"
-  "\x17\x26\x35\xdc\xbe\x75\x65\x27\x69\xf9\x75\x21\x72\x34\x53\x17"
-  "\xb2\x14\x25\xf2\xfa\x6d\x26\x3b\xc1\xff\xdb\xeb\xb7\x99\x96\xc1"
-  "\x8c\x0b\x90\xb8\x8e\x2d\x57\x17\xa6\x4c\xe2\xea\xc2\xb4\xa5\xe2"
-  "\x75\x61\x6a\x5e\xe7\x59\xc7\x76\x6a\x6f\xc7\x75\x61\x8a\x51\x5a"
-  "\x1f\xcd\xd4\xa5\xd2\xeb\xc2\xd4\x10\xae\x8f\x66\x6a\x06\x57\x17"
-  "\xa6\x55\x74\x5c\x5d\x98\xd6\xcf\x71\x5d\x98\x86\x6e\xdf\xfa\xb6"
-  "\x53\x07\xf0\xeb\xc2\x94\x08\x52\x17\xdc\x06\xcb\xeb\xe7\x99\x96"
-  "\xef\x7a\x3f\x4f\x74\x3e\x33\x66\x42\xe2\x7a\xba\x5c\x5d\x78\x7d"
-  "\x3a\x57\x17\xa2\x57\x8b\xd7\x85\xa8\x4d\x9d\x67\x3d\xdd\xa8\xfe"
-  "\x8e\xeb\x42\x94\x9b\xb4\x3e\x9d\xa8\xd5\xd2\xeb\x42\xd4\x04\xae"
-  "\x4f\x27\x2a\x9f\xab\x0b\xd1\x35\x1d\x57\x17\xa2\x07\x3a\xae\x0b"
-  "\xd1\x9e\xb7\x6f\x9d\xdd\xa8\x40\x7e\x5d\x78\x7d\x2a\xa9\x0b\xf7"
-  "\xed\x93\xd7\x2f\x14\xbd\xd9\xf5\x7e\xa1\x37\x37\x33\xe3\x49\x24"
-  "\xae\xeb\xcb\xd5\x85\x98\x79\x5c\x5d\x78\xd3\xc1\x3e\x0f\x6f\xec"
-  "\xe8\x3c\xeb\xfa\xbe\xe1\x78\xff\x23\xe5\x1b\x0e\xf6\x3f\x12\xea"
-  "\x03\x7a\x23\x4f\x7a\x5d\x78\x23\x9a\xeb\x03\x7a\xc3\x66\xfe\xdf"
-  "\x9b\xb5\x1d\x57\x17\xde\x6c\x67\xff\x87\x37\x9d\xd8\xff\x41\xee"
-  "\x7a\xbf\x6f\x8c\xe6\xd7\x85\x98\x38\x52\x17\xba\x0e\x97\xd7\x8f"
-  "\xf4\x66\xbb\xfd\xff\x58\xe7\xb7\xaa\xed\xfb\x91\x2a\x6a\x03\xd1"
-  "\x13\x93\x71\x5d\x98\x1e\x69\xca\x0b\xce\xc7\xeb\x0b\x9b\xfd\xd8"
-  "\x35\x28\x97\xb1\x6b\xbc\x34\x98\xc8\x1a\x94\x06\xf3\xcd\x35\x28"
-  "\xc9\xda\x1f\x88\xc2\x73\x81\xf1\x9c\x60\x93\x8a\xac\x3f\x49\xe3"
-  "\x31\x51\x78\x8c\xd4\xb9\x32\x66\x7d\x95\x14\x13\xbc\xfb\x85\x76"
-  "\xd6\x9f\x8c\xd6\xa3\x8a\xe8\xc5\xc8\xd4\xe3\x6b\x76\x9e\x70\x6c"
-  "\x1d\xb3\xfe\x64\x94\xa6\x4f\xd6\xbf\x91\xda\x1b\xaf\x3f\x19\x4d"
-  "\x5b\xd2\xf4\xb4\xa1\xca\x88\xe0\x5a\xb0\x6f\x8c\x75\x0d\xca\xe9"
-  "\xe3\xf1\xbb\x9b\xa2\x74\x7d\x8a\xfe\x2d\xb6\xbe\xf0\x74\x19\xeb"
-  "\xc0\x4e\x77\xe3\xfa\x77\xa6\x87\x70\x18\x9d\xce\xb4\xc1\x7a\x65"
-  "\xac\xbe\x22\x12\x62\x4c\xd6\xfd\xa5\xad\xb2\xd6\xde\x98\x1e\xdb"
-  "\xbe\xcf\x98\x31\x22\x76\xf1\x8b\xf3\xd9\x5f\x3c\x4d\x79\x21\x1a"
-  "\xbc\xce\xb1\xf3\x3e\x73\xbf\x76\x7b\x7c\xf6\x56\x81\xf3\x3e\xfb"
-  "\x8b\x3b\xdf\x67\x42\xfd\x10\x6f\x5d\x96\xee\xb3\xb7\xf6\x71\xfd"
-  "\x10\x6f\x99\x38\x9f\xfd\x65\x2c\xf1\xd9\x5b\xb9\xc4\x67\x9e\xf5"
-  "\xad\xb2\xd6\xef\xf8\x4b\xbb\xf3\xbf\xb1\x6e\x6a\x55\xdb\xeb\x72"
-  "\xce\x67\x71\xa5\xe0\xb3\x7c\xbc\xde\xb2\xf3\x3e\xbb\xff\xdc\xed"
-  "\xf1\x59\x5c\x84\xf3\x3e\x8b\xdb\xdf\xc6\x67\x02\x7a\x39\x4e\xfa"
-  "\x9e\x9d\xca\xb8\x59\x9c\x5e\x8e\x2b\xe1\x7c\x06\x8d\x17\xe3\xb3"
-  "\xb8\x10\xe2\x33\x2f\x4d\xab\xac\x35\x40\xe2\x2a\xda\xf7\x19\xf3"
-  "\x4d\xdf\x41\x3d\x9b\x99\x60\xca\x03\x8d\x09\xfa\xd1\x79\x9f\xf5"
-  "\xf8\xfe\xf6\xf8\x6c\xa6\x9b\xf3\x3e\x9b\x39\x9b\xef\x33\x21\x5d"
-  "\x37\x73\xa2\x74\x9f\xcd\xd4\x72\xba\x6e\x66\x2c\xe7\xb3\x99\x7b"
-  "\x88\xcf\x66\x98\x88\xcf\xbc\x47\xb7\xca\x5a\x47\x64\x66\xbb\xfd"
-  "\x5f\x98\x87\xb6\xaa\xed\x75\x0e\xe7\xb3\x59\x3a\xf0\x59\x3e\x5e"
-  "\x7f\xda\x79\x9f\x3d\xb3\xe6\xf6\xf8\xec\xed\x7d\xce\xfb\x6c\x56"
-  "\xbf\x36\x3e\x13\xd0\x1f\xb3\xba\x4a\xf7\xd9\xdb\x27\x38\xfd\x31"
-  "\x4b\xc3\xf9\x6c\x56\x1c\xf1\xd9\xdb\x25\xc4\x67\xaa\xf8\x56\x59"
-  "\x6b\x91\xcc\x1a\xdc\xbe\xcf\x98\x6f\xb0\x0e\xea\xd9\xec\x53\xa6"
-  "\x3c\xe0\xec\xc0\xc7\x9d\xf7\xd9\x94\xe7\x6f\x8f\xcf\x66\xcf\x72"
-  "\xde\x67\xb3\x7f\xe0\xfb\x4c\x88\x27\xcf\x96\xb1\x0e\xf6\xec\x55"
-  "\x1c\x4f\x9e\x5d\xc1\xf9\x6c\x8e\x2f\xf1\xd9\xec\x58\xe2\xb3\x1e"
-  "\x05\xad\xb2\xd6\x33\x99\x2d\xba\xfe\x97\x23\xde\x68\x1d\x97\xcf"
-  "\xf9\x6d\x6e\x6e\xe7\xe1\x8e\x73\xfd\x9c\xf7\xdb\xdc\xcc\xf6\xb9"
-  "\xe3\xdc\x44\xe9\x7e\x9b\x1b\xc4\x71\xc7\xb9\x2b\x38\xbf\xcd\x3d"
-  "\x41\xfc\x36\xd7\xd7\x35\xee\x38\xb7\x58\x0e\x77\xb4\xf7\xdb\xbc"
-  "\xb1\x9d\x87\x3f\xc6\x9f\x72\xde\x6f\xf3\xc6\xb4\xcf\x1f\xe7\x0d"
-  "\x94\xee\xb7\x78\x23\xc7\x1f\xe7\x0d\xe7\xfc\x36\x2f\x83\xf8\x2d"
-  "\xfe\x84\x6b\xfc\x71\x9e\xe8\xfa\x6f\x8e\xf8\xa3\xbd\xdf\x16\xb8"
-  "\x75\x1e\x0e\x39\x3f\xd7\x79\xbf\xcd\x37\xb7\xcf\x21\xe7\x9f\x97"
-  "\xee\xb7\xf9\x25\x1c\x87\x9c\xdf\xc0\xf9\x6d\xc1\x68\xe2\xb7\xf9"
-  "\x19\xae\x71\xc8\x05\x2a\x39\x1c\xd2\xde\x6f\x09\x07\x3a\x0f\x8f"
-  "\x4c\x18\xeb\xbc\xdf\x12\xf6\xb6\xcf\x23\x13\xa4\xef\x59\xac\x4c"
-  "\x88\xe3\x78\x64\xc2\x76\xce\x6f\x09\xec\x1e\x2c\x09\xa3\x5d\xe3"
-  "\x91\x09\xed\xae\xff\x21\xc4\x23\xed\xfd\x96\x94\xd0\x79\xb8\x64"
-  "\x92\x04\xfe\x9f\xd4\x96\xff\x0b\x70\xc9\x24\x19\xfc\x3f\x49\xcb"
-  "\x71\xc9\x24\x1b\xfe\x9f\xc4\xf2\xff\x44\x93\x6b\x5c\x32\xc9\x09"
-  "\xfe\x6f\xcf\x25\xed\xfd\x96\x3c\xa0\xf3\xf0\xc9\x85\x07\x9c\xf7"
-  "\x5b\x72\xff\xf6\xf9\x64\xb2\x8c\x7d\xa0\x16\xd6\x70\x7c\x32\xd9"
-  "\x97\xf3\x5b\xf2\x2c\xe2\xb7\x85\x7b\x5c\xe3\x93\xc9\xa2\xeb\x3f"
-  "\x5a\xfd\x66\x56\x07\xe7\xd3\x02\xfd\x90\x95\x71\x81\xec\xda\x84"
-  "\x8b\x4d\x66\x9f\xe0\x7c\xa9\xfb\xbb\x58\xd7\x9c\x2e\x87\x88\x72"
-  "\x4e\xb9\x38\xcf\xb5\x75\xa7\x17\x8f\x71\x7d\xdd\xe9\xc5\x3d\x6e"
-  "\xdd\xfe\x2e\x8b\x9a\xa5\xaf\x3b\xbd\xe8\x30\xc7\x41\x17\x7b\x70"
-  "\xbe\x5e\xc2\x8c\x4f\x90\xb6\x1e\xf5\xa2\x55\xae\xad\x47\xbd\x38"
-  "\x93\xe0\x6b\x51\x08\x59\x8f\x7a\xf1\x8a\x8e\xd9\xf7\x25\xb9\x01"
-  "\xaf\x47\x4d\x67\xf5\x2c\x93\xb7\x3e\xf2\x12\x8f\xf6\xf1\x1c\xa2"
-  "\xa1\x05\xfa\x68\x39\x3c\x2f\xad\x30\xfb\x84\x68\xa4\xee\x33\xc3"
-  "\xc7\xf3\xd2\xe9\xae\xe1\x79\xa9\x8f\xeb\x78\x4e\x39\x7b\xeb\xf6"
-  "\x99\x49\x29\x97\x8e\xe7\x94\x5c\x8e\x9b\xa7\xd4\x70\x78\x4e\xf5"
-  "\x94\x8e\xe7\x94\x48\xd7\xf0\xbc\x74\x1a\xc1\x73\x8a\x86\xe0\x79"
-  "\xe9\x84\x8e\xd9\x7f\x66\xc9\x61\x82\x67\x1f\x95\xbc\xf5\xa7\x97"
-  "\xd6\x38\x81\xe7\x7c\x5a\xa0\xff\x9a\xc3\x73\x7a\x01\xe0\x39\x5f"
-  "\xea\x7e\x37\x7c\x3c\xa7\x0f\x71\x0d\xcf\x69\xe7\x5d\xc7\x73\xda"
-  "\xee\x5b\xb7\xdf\x4d\xda\x06\xe9\x78\x4e\x8b\xe5\x34\x4b\xda\x56"
-  "\x0e\xcf\xe9\xa7\xa4\xe3\x39\x4d\xe7\x1a\x9e\xd3\x07\x12\x3c\xa7"
-  "\xd6\x11\x3c\xa7\xfb\x75\xcc\x3e\x38\xa9\xb9\x04\xcf\x0f\x44\xca"
-  "\x5b\xdf\x3b\x5d\x74\xfd\x63\x0e\xcf\xa1\x1a\x5a\xa0\x6f\x9f\xc3"
-  "\xf3\x3b\xb3\xcc\x3e\xa1\x1a\xa9\xfb\xee\xf0\xf1\xfc\x8e\x8b\xfb"
-  "\x5c\x2c\xbf\x05\xfb\x5c\x2c\x77\x61\x9f\x8b\xb6\xfb\xee\x2c\x9f"
-  "\x21\x1d\xcf\xcb\x07\x73\x5a\x6e\x79\x32\x87\xe7\x77\xb6\x4b\xc7"
-  "\xf3\x32\xa3\x6b\x78\x5e\xce\xee\x7f\xb1\x6c\x1f\xc1\xf3\xf2\x86"
-  "\x8e\xd9\x8f\x67\x59\x2c\xc1\x73\xef\x62\x79\xeb\xa7\xbf\x93\xec"
-  "\x04\x9e\xf3\x69\x81\xef\x1e\x1c\x9e\xdf\x1d\x0e\x78\xce\x97\xba"
-  "\xff\x0f\x1f\xcf\x2b\x7f\x70\x0d\xcf\x2b\x57\xba\x8e\xe7\x95\xe3"
-  "\x6f\xdd\xfe\x3f\x2b\x87\x49\xc7\xf3\x4a\x37\x4e\xe3\xae\xb4\xf9"
-  "\xfe\xff\x6e\x8a\x74\x3c\xaf\x70\x71\x5f\xa0\x95\x95\x04\xcf\x2b"
-  "\xd8\x7d\x81\x56\x1e\xee\x98\x7d\x81\x56\x0c\x26\x78\x7e\xb0\x4e"
-  "\xde\xfa\xf4\xef\x86\xb4\x8f\xe7\x30\x0d\x2d\xf0\x4d\x88\xc3\xf3"
-  "\x6a\x4f\xb3\x4f\x98\x46\xea\x3e\x44\x7c\x3c\xaf\xda\xe2\x1a\x9e"
-  "\x57\x4d\x74\x1d\xcf\xab\xfa\xdd\xba\x7d\x88\x56\x75\x95\x8e\xe7"
-  "\xff\xb5\x7e\xff\x83\xf8\xbc\xca\xe6\xfb\xdf\x6a\x19\xfb\x13\xfd"
-  "\x6f\xbe\x6b\x78\x5e\x55\x48\xf0\xfc\xbf\x91\x04\xcf\xab\x72\x3b"
-  "\x66\x7f\xa2\xff\x75\x23\x78\xee\x1b\x20\x6f\xfd\xff\xd5\xed\x8e"
-  "\xff\x10\xea\xdf\xb0\xf6\x4b\x71\x98\x7e\x4f\xef\x7a\x1f\xc7\x7b"
-  "\x8b\x5c\xc3\xf4\x7b\xfe\xae\x63\x7a\xcd\x8d\x5b\xd7\xc7\xb1\x46"
-  "\xc6\x5e\x7f\x6b\xb6\x72\x7d\x1c\x6b\xea\x39\x4c\x67\x68\xa5\x63"
-  "\x7a\xcd\x2c\xd7\x30\xfd\xde\x3c\x82\xe9\x35\x03\x08\xa6\xdf\x8b"
-  "\xeb\x98\x3e\x8e\xd5\x35\xae\xf5\x71\xbc\x57\x2f\xa7\x8f\xc3\x1e"
-  "\xd3\x59\x7b\x5c\xef\xe7\xc8\x1a\xe7\x1a\xa6\x33\xcd\xae\x63\x3a"
-  "\xb3\xfc\xd6\xf5\x73\x64\xee\x96\x8e\xe9\xcc\x14\xae\x9f\x23\xb3"
-  "\x94\xc3\x74\x56\x83\x74\x4c\x67\x06\xb9\x86\xe9\xac\x31\x04\xd3"
-  "\x99\x88\x60\x3a\x6b\x78\xc7\xf4\x73\x64\x6c\x77\xad\x9f\x23\xab"
-  "\x54\x4e\x3f\x87\x3d\xa6\x73\x56\xb9\xde\xd7\x91\xd3\xcf\x35\x4c"
-  "\x67\x1f\x77\x1d\xd3\xd9\x85\xb7\xae\xaf\x23\x7b\xa5\x74\x4c\x67"
-  "\x47\x70\x7d\x1d\xd9\xb9\x1c\xa6\x73\xca\xa4\x63\x3a\x5b\xed\x1a"
-  "\xa6\x73\x7a\x13\x4c\xaf\x3d\x41\x30\x9d\xa3\xea\x98\xbe\x8e\xb5"
-  "\xe9\xae\xf5\x75\xe4\xe4\xca\xe9\xeb\xb0\xc7\x74\xee\x54\xd7\xfb"
-  "\x3b\xde\xbf\xe1\x1a\xa6\xdf\xdf\xe2\x3a\xa6\xdf\x9f\x77\xeb\xfa"
-  "\x3b\xde\x9f\x24\x1d\xd3\xef\xdb\xec\x7f\xf1\xbe\xcd\xfc\xff\xdc"
-  "\x02\xe9\x98\x5e\x57\xe7\x1a\xa6\xdf\xbf\x4c\x30\xbd\x6e\x2b\xc1"
-  "\xf4\xfb\xb5\x1d\xd3\xdf\xb1\x6e\x82\x6b\xfd\x1d\xb9\xed\xae\x7f"
-  "\x21\xd4\xdf\x61\x8f\xe9\xbf\x06\xb8\xde\xe7\xb1\xbe\xdc\x35\x4c"
-  "\xaf\x5f\xe4\x3a\xa6\xd7\x8f\xb9\x75\x7d\x1e\xeb\x07\x4a\xc7\x74"
-  "\x9e\x91\xeb\xf3\x58\x6f\x33\xfe\xe9\xaf\xf1\xd2\x31\x9d\x77\xc0"
-  "\x35\x4c\xaf\x3f\x44\x30\x9d\x97\x42\x30\xbd\x7e\x5f\xc7\xf4\x79"
-  "\xe4\xe9\x5c\xeb\xf3\xf8\xeb\x70\x39\x7d\x1e\xf6\x98\xfe\xc0\xcd"
-  "\xf5\x7e\x8f\x0d\x85\xae\x61\x7a\xc3\x38\xd7\x31\xbd\xa1\xf7\xad"
-  "\xeb\xf7\xd8\xa0\x90\x8e\xe9\xfc\x0a\xae\xdf\x63\x83\xcd\xfa\xf7"
-  "\x1f\x8c\x96\x8e\xe9\xfc\x6c\xd7\x30\xbd\x21\x8f\x60\x3a\x3f\x82"
-  "\x60\x7a\x43\x46\xc7\xf4\x7b\xfc\xd5\xe4\x5a\xbf\xc7\x07\x76\xe3"
-  "\xdf\x16\x4c\x9f\x13\xab\x9d\xfb\xd6\x5b\x0b\xa6\x27\x68\x17\xcc"
-  "\x9a\xf1\xe6\xf4\x11\xfd\xad\xbf\x47\x04\x24\xf7\x4f\xee\x86\x62"
-  "\x67\xc7\x44\x25\x3d\xcd\x9d\x9c\x35\x7d\x0e\xfc\xe9\x86\xe2\x62"
-  "\x16\xc4\x69\x13\x16\xc5\x4f\xd7\xe2\x5f\xb3\xdf\x8c\x87\x4b\xe6"
-  "\x26\x70\x29\x2f\x4f\x9f\x15\x93\x3c\x63\xce\x5f\xb4\x31\xb3\x66"
-  "\xfc\x65\xce\xec\xe9\x73\x12\xb4\xf3\xa7\xcf\x4b\x9c\x31\x7f\x3a"
-  "\xfe\x7f\x81\xf6\xad\xb9\xf3\x21\xe1\xcd\xe9\x33\x92\xa6\x6b\xdf"
-  "\x48\x7c\xeb\xad\xe9\xf3\x17\x74\x43\xe3\x12\x67\x25\xcc\x88\x9f"
-  "\x35\x5d\x3b\x7a\xdc\xa8\x81\x13\xc6\xbc\x32\x61\xe4\xc8\x6e\xc8"
-  "\x66\xef\x69\x2d\x9d\x3b\xb3\x18\x30\xe4\x76\x41\xf9\xc9\xfe\x2a"
-  "\x0d\x42\x99\x80\xcd\xb5\xf3\x91\x6a\xf5\x7c\xe4\xb6\xea\x1a\xf2"
-  "\xc8\xbc\x86\x3c\xb5\x33\x51\x10\xdd\x63\x25\x5a\x7b\x0d\xa9\xe9"
-  "\x5e\x5e\x1a\x3a\xe7\x20\xfc\x3e\x98\x6e\xe8\xf1\x89\x06\xd2\x54"
-  "\x74\xce\x96\x40\x7c\x0e\x7c\xe1\x06\xe7\xea\xce\x29\x3f\x49\x36"
-  "\xf4\xf8\xd4\x23\xed\x22\xa2\x68\xaf\x0f\xe3\x77\x5a\x0c\xd4\x21"
-  "\xbc\x8a\x0d\xd8\x0a\x29\x0b\x56\xc1\x91\x80\x94\x85\x7e\x70\x0c"
-  "\x86\x23\x05\x8e\xcd\x70\x6c\x47\xca\x22\x0d\x1c\xd1\x70\x64\xc3"
-  "\x01\x69\x45\xfb\xe0\x38\x0c\x47\x05\x52\x6e\x0c\x84\x23\x12\x8e"
-  "\x38\x38\xd2\x49\x3e\x1b\xe1\x28\xf6\x80\x23\x02\x8e\x15\x48\xb9"
-  "\x09\xd2\x37\x41\x3e\x1f\xc1\x75\x9b\xe0\x9e\x4d\x75\x70\x18\xe0"
-  "\xb7\x1a\x0e\x7c\x7f\x06\x39\xf7\xb1\x1b\x1c\x41\x70\xc0\xb3\x3e"
-  "\x86\xe7\x7f\x5c\x02\x07\x3c\xe7\xe3\x63\x70\xd4\xc0\x61\x42\xca"
-  "\xcd\x70\xcd\x66\x28\xcf\x66\xb8\x67\x73\x2e\x1c\x50\x96\x2d\x2a"
-  "\x38\xa0\xec\x5b\xca\x10\xbc\x23\x7b\x40\xda\x27\x13\x6c\x7e\xc7"
-  "\xdb\xfc\x2f\x74\x64\x7b\x2f\x7b\x58\x5f\xfa\xb8\x09\xea\x6d\xc1"
-  "\x79\xf3\x72\xa4\x34\xe7\x7c\xea\x11\xff\x38\x52\x5c\x52\x16\xec"
-  "\xae\x5e\x81\x10\xad\x3a\x18\x54\xba\xb8\x05\x9f\xdf\x8d\x6d\xd6"
-  "\x94\x55\x50\xa2\x47\x99\x5a\x5c\x3f\xa5\xe1\xb3\xa0\x84\xbd\xdf"
-  "\xa0\x57\xf8\x7a\xe2\xfb\xe9\x75\xa1\x15\x74\x5a\xe4\x87\x78\x1e"
-  "\xee\x05\x6c\x43\x5c\x6f\xb2\x43\xfd\x68\xd5\x0b\xc7\x70\x8c\x29"
-  "\x5d\xcc\x94\x6b\x35\xd4\x37\x2f\xb8\x7f\x15\x0d\x7e\x34\xf8\x80"
-  "\xcf\x97\x23\x37\xe6\x77\xce\x27\x1a\xba\x38\x71\x15\x89\x3b\x85"
-  "\x8c\x7e\x69\xf6\x79\xfd\x18\x3e\x67\xdc\x32\x34\x9d\xde\x1c\xa6"
-  "\x29\x9d\xd3\x82\x6a\x95\x85\x89\x10\xff\x28\xfa\xd1\xa1\xe9\x96"
-  "\xf5\xaf\x1f\xdb\x07\x18\xc0\xd7\xec\x4f\xad\xc3\x7f\x57\xc0\x7b"
-  "\x53\x74\x6e\x54\x3e\xee\x03\x2a\x4d\x5d\x07\x31\xb9\x60\x75\xb3"
-  "\x4f\x62\xbc\x36\xcc\x9b\x3e\xc7\x96\x4b\xaf\x2c\xf4\x85\x72\x30"
-  "\xf7\x35\xfb\x78\x69\x71\xde\xe6\xe2\xa4\x00\x48\x73\xa3\x01\x7b"
-  "\x50\x06\xc5\x15\xb8\xcf\x9c\xe7\xa5\x29\x0d\xc3\xcf\x2c\xea\x01"
-  "\xe5\xa4\xd2\x42\x21\xef\x8f\x92\x02\x76\x2d\x36\x52\x34\x2e\xbb"
-  "\xda\x4b\x03\x58\xf7\x34\x67\x7d\x10\xb1\xa1\x27\x72\x2b\x5c\x87"
-  "\xd0\xc6\x9e\xc8\xa3\x29\xab\xc8\x43\xef\x36\xa0\x96\xc4\xbd\x82"
-  "\x55\x14\x5c\x03\xcf\xac\xa5\xc1\x1f\xcc\xb3\x72\x27\xab\x1c\x3c"
-  "\x6b\xd2\xcd\x67\xad\x9f\xac\xc2\xcf\x62\xec\x43\x6c\x45\xfe\xb7"
-  "\xe6\xb3\x39\xd0\x51\x99\x27\xe2\x3c\xf4\xca\xa2\x10\xfa\x93\xc0"
-  "\x00\xf3\xfa\x98\x00\x7c\x0e\x5f\x4f\xec\xff\x09\xb4\x69\xa8\x81"
-  "\x86\x34\x33\xeb\x03\x33\xf6\xc1\x7d\x38\x7e\x15\xea\xf0\xf3\xe0"
-  "\xde\x5c\xf3\x72\x2d\xe0\x26\x2c\x97\xf8\xb5\xe8\x6c\x72\x19\x6d"
-  "\x81\xc3\xfc\x54\x19\x52\x94\x86\x61\x9f\x6e\x44\xda\x3f\x77\x01"
-  "\xdb\x6e\x54\x10\xdb\x82\x4d\xfb\x25\xe9\xc0\x2e\x2a\xb0\x85\x27"
-  "\xfd\xae\x8f\x2f\x93\x07\xd8\x1b\xdb\x68\x23\xd8\x08\xec\xe4\x81"
-  "\xfd\xdf\x94\xb5\x31\xa0\x8d\x9d\x54\x90\x36\x5a\xaf\xf0\x99\x80"
-  "\xd3\xb4\x8f\x20\x82\x19\x9b\xf7\xc6\xfe\x35\xe7\xcd\x2c\xc6\xbf"
-  "\x27\xfa\x23\x95\x77\x19\xa2\xb4\xa9\x7e\xfb\x88\x9f\xf1\x3c\x7f"
-  "\xab\x6f\x8b\xb6\xd2\xeb\x5f\xac\x83\xeb\x75\x1c\xae\x36\x96\x9a"
-  "\x73\xc2\x32\x9a\x7d\xa2\x23\x8c\x79\x93\x54\x74\x76\x58\x06\x9e"
-  "\x57\x0e\x65\x67\xe6\xda\xd1\xcb\x3d\x10\x79\x4e\x58\x76\xea\x2c"
-  "\xda\x90\x7a\x15\x7c\xd0\x2b\x3a\x62\x7f\x92\x01\x7c\x31\x49\x85"
-  "\x7d\xbd\xaf\xd1\x48\xe1\xb5\xfe\x68\xaf\x0f\xe6\x17\x11\x9f\x7b"
-  "\xc0\x7b\x22\x9c\x6f\x53\x56\x31\xe2\xde\x67\xe3\x66\xec\x77\x78"
-  "\xc6\x66\xf2\x6c\xc8\x97\x82\x67\xf4\x08\xdb\x0c\xd7\xe9\xf4\x8a"
-  "\x43\x05\x4c\xbd\x49\xa2\x4f\xac\x6d\x41\xe8\x7a\x12\x6d\x0a\x37"
-  "\x9d\xb1\x40\x7b\x8b\xe0\x7c\x88\x1e\x3d\x17\x6d\xb5\x0b\xa9\x4b"
-  "\x37\xf3\x61\xd6\x80\x30\x90\x7c\xe2\x85\xf2\xd1\x2b\x8b\x03\xa3"
-  "\x4c\x5a\x45\x4b\x23\x7d\x6c\xed\xab\x50\xb6\xe5\x88\x6e\x49\xa2"
-  "\x2b\x96\x86\xd0\xc6\xac\xef\x11\x70\x9e\x53\x08\x62\xa8\xaf\x97"
-  "\x82\x36\x84\x2f\x42\xde\x5e\xf1\xde\x74\x79\xd9\x29\xb4\x24\x84"
-  "\xae\xab\x4e\x36\xa3\xaa\x86\x5a\x94\x72\x12\x79\xa6\x55\x22\x75"
-  "\x4a\x08\x6d\xa8\x88\x3e\x85\x48\x7a\x25\x4a\x3b\x8b\xdc\x96\x1c"
-  "\xa6\x8d\x2f\x41\xfb\xfb\xdd\x29\x9c\x5e\x0b\xe9\x66\x94\x56\x47"
-  "\x9b\x52\xa7\x21\x4f\xfc\x7f\xe5\x61\x9c\x7e\x1e\xf3\x14\xb7\xf0"
-  "\x64\x83\x77\x11\x3c\x13\xdf\xbf\x11\xca\x62\x69\xa4\x0f\xac\x6d"
-  "\x44\x68\xc9\x24\xa4\x49\x89\x41\xc0\xc9\x10\x5d\x6d\xda\x8b\xc2"
-  "\xcd\x34\xb4\xef\x47\xd0\xd2\x19\xc8\x23\xdc\x84\xe7\x85\xff\x00"
-  "\x47\x21\xda\x08\xd7\xc2\xbb\x95\xe2\x77\x5b\x72\x1a\xf8\xce\x65"
-  "\xeb\x3d\x07\xd9\x7b\x4e\x23\x6c\xb3\xe6\x1e\x07\xe3\x8d\x39\x07"
-  "\x0d\xf0\xee\xc3\xb1\x0d\xe0\x39\xc7\x2c\xf8\xbe\x46\xa6\xdd\xc1"
-  "\x36\x50\x44\x99\xa0\xae\xe6\xbd\x66\x88\x4a\x2e\x65\xf2\xd5\x2b"
-  "\x37\x25\x6f\x9c\xcf\x94\x89\x77\x6d\xb8\x89\xbe\x6e\xf0\x79\x0d"
-  "\xf2\xda\x54\x1c\x9e\x3c\x92\x06\xfc\x29\x00\x13\xc5\x4d\x59\x9b"
-  "\xf4\x56\x7b\xeb\x6f\xc6\x92\x4d\x27\xc0\x17\xc5\xca\x78\xe4\xd6"
-  "\x94\xf5\x11\xd2\x2b\x0e\x27\xdb\x60\x17\xc7\xa3\xfb\xac\xd7\xb2"
-  "\xd7\xf8\xe9\x15\xff\x2c\xe5\xae\x61\xf0\x7a\xf3\x1a\x38\x0f\xf8"
-  "\xff\xb6\x8c\x3b\x5f\x14\x49\xdb\xe4\xc1\xb6\xab\xd6\xbc\x95\x10"
-  "\x5f\x37\x9b\x7d\xa2\x40\x0f\x7a\x95\xd0\xd7\x35\x9e\x34\x05\xbe"
-  "\x31\xd1\x46\x4b\x5e\x98\x01\xda\x4e\xcf\x6a\x53\x03\x22\xd7\x7f"
-  "\x74\x11\xea\xfa\x3e\x32\x96\xf5\xa3\xe3\x38\x4f\xe0\x58\x11\xd0"
-  "\x0e\xab\xc2\xcb\x68\x23\x8e\x0b\xe6\xbc\x07\x02\xb2\xe6\x43\x5b"
-  "\x9c\x17\x95\x6d\xf1\x99\x5c\x6c\xdc\x94\x98\x8e\x63\x3d\xed\x33"
-  "\xb3\x98\xce\x85\x7b\xd9\x7c\xe0\xb9\xee\x7a\xe5\x47\x5b\xcd\x70"
-  "\x3f\x9d\x1b\x66\x20\xe9\x24\x6e\x91\xf8\xf2\xd1\x56\xba\x3f\x9c"
-  "\xcb\x7e\x61\x2b\x9c\x73\x3f\xa7\xfc\x78\x30\xa4\x23\xf8\xad\x2f"
-  "\x4d\xbd\x06\xd7\x7e\x3c\x8c\x60\xfa\x85\xcd\xbc\xdf\x14\xb6\x67"
-  "\xd1\x76\x1c\x7b\xb4\x61\x38\xcf\x8f\x27\x71\x71\xc6\x36\x66\xbf"
-  "\x08\x75\xe4\xe3\x59\x7a\xc5\xc3\xab\x18\xec\xc3\x7d\x0d\x4c\xbc"
-  "\x82\xb8\xd5\x2f\x71\xd5\xb7\x21\x08\x7d\x7b\x18\xd7\xa3\x8f\xb3"
-  "\xf5\x8a\x7e\x25\x9c\x2d\x3f\xde\x86\xaf\x65\x62\x08\x8e\xa1\x14"
-  "\x89\x57\xf8\x1e\x7a\x7d\x74\x10\x8e\x83\x38\x1e\xea\x95\x1f\x6f"
-  "\xc6\xb1\x10\xe2\xc9\x56\xd2\xfe\x04\x7a\x30\xf1\x64\x5d\xaa\x0e"
-  "\xca\x95\x7e\x8e\x2d\x8b\x6d\xd9\xac\xb1\x8f\xce\x49\xdd\x4a\xae"
-  "\x0d\xdb\xda\x94\xb5\x59\xa5\x57\x3c\xb2\xca\x16\x2f\xe4\xbd\x36"
-  "\x27\x02\xa6\x6b\x9e\x3a\x0c\xbf\x81\x23\x41\x7e\x05\x74\xd6\x07"
-  "\x6b\x20\xbe\xe0\xf8\xa6\xc0\x31\x32\x7f\x1d\x72\x33\xe6\xa4\xee"
-  "\x33\xe7\xa4\x96\x40\x3e\x91\xd6\xb8\x82\xef\xc3\x75\x01\x62\x8b"
-  "\x07\x13\x33\xcc\x26\x25\x53\xdf\xcd\x68\xc0\xcd\x38\x02\x69\xcd"
-  "\x3d\x52\x4b\xd8\x74\x37\xa6\x3c\xcb\x95\x16\x78\xb6\xc2\x5a\xf6"
-  "\xe6\x1e\x61\xf9\x90\x6f\x89\x5e\xe1\x9d\xc0\x8b\x33\xeb\x82\x42"
-  "\x68\x3a\x12\x63\x46\x09\xe5\xfc\x01\xfe\x76\x61\x31\x78\xff\xb7"
-  "\x65\x08\x8d\x1e\x03\xcf\x00\x5f\x6e\xe8\x45\x03\xbf\xdf\x6c\xd0"
-  "\xa3\x59\x6e\xf8\xfe\xd5\xf0\x1b\xa7\xe3\x6b\x9a\xb2\xb6\x78\x40"
-  "\x7a\x03\xc9\xb7\x68\x3b\xf6\x0d\x3f\xdf\x2d\x03\x49\xbe\x4c\x59"
-  "\xee\xc7\x79\xe2\xfb\x70\x9e\x85\xeb\xe9\x7a\x9c\x0f\xe4\x31\xd6"
-  "\x9a\x77\x26\xa4\x59\xf3\x1f\x3d\xfb\xe6\x33\x66\xc1\xf9\x14\xdb"
-  "\xb2\xe7\xaf\xa7\x1b\x48\xb9\xb6\xac\xd2\xa3\xf4\x3a\x7c\x6e\x15"
-  "\xa4\xe1\x7b\x89\xff\xb7\x6c\xc1\xd8\xd0\x93\xf7\x51\x12\x8c\x6c"
-  "\xd9\xa3\x47\x69\xf1\xb6\xed\x0d\xf8\xa0\x3b\x69\x0f\x3f\xf5\x60"
-  "\xf3\xab\xb1\xe6\xc7\xe5\x45\xf2\xa0\xb3\xd3\x6c\xeb\xa3\x27\xce"
-  "\xbf\x29\xeb\x13\x78\xff\x39\x87\xd9\xf7\xcf\x6f\x20\x78\x06\xdb"
-  "\x7f\x32\x10\xdb\x1e\xb7\x7d\xd8\xcf\xcc\x33\x36\x25\xae\xc2\x7e"
-  "\x07\xff\xe7\x5b\xdb\x47\xf0\x4d\x2e\xe4\x31\x96\x6b\x4b\x3e\xd1"
-  "\x62\x7f\x43\xfa\x0a\x36\xff\x38\xf0\xdb\x60\x7e\x1c\x2a\x3a\x40"
-  "\xf7\x8a\x2a\xc5\xb1\x8a\x2d\xcf\x6e\xdc\x5e\x5a\xcf\xc3\x33\xdc"
-  "\x80\xa7\x7c\x86\x31\x8f\x79\x0a\xed\x13\x99\x0e\xf9\x94\xb4\x69"
-  "\x7f\xdd\xd8\xeb\xce\xe0\x6b\xde\xef\x45\xd7\xc1\x35\x27\xac\xd7"
-  "\xe0\xf3\xe0\x83\xe7\x20\xad\x4e\x8f\xde\xcb\xc0\x69\x59\x70\x8d"
-  "\x5e\xf9\xa1\xe8\x7c\x9d\xd4\x7e\x88\xaa\x2e\xd0\x63\x2d\x8b\xeb"
-  "\xf7\xf0\x6a\xdf\x06\x54\x5d\x60\x41\x96\x4f\x02\x4b\x82\x52\xe9"
-  "\xd2\x0b\xca\x4f\xa7\x57\x19\xeb\x90\x34\xfe\xf9\x29\xb3\xfe\x21"
-  "\xdd\x02\x9a\x2b\xe5\x69\x84\xb9\xc9\x15\xe5\xd6\xbc\x6a\xc3\x35"
-  "\x26\xd6\xc1\xff\xcb\xf0\xf9\xf7\x41\xa3\x61\x9d\x06\x5a\x3c\x2e"
-  "\x9b\x22\x5a\xcd\x02\xd7\x16\xe1\x74\xac\xe3\xa0\x0d\xdb\x68\x73"
-  "\x8e\xfe\x64\x68\x00\xb1\xdd\xd6\x71\x4c\xcc\xc7\xe5\x35\x05\x97"
-  "\xe2\x32\x5b\x36\x0f\x0d\xc0\xef\x90\x96\x4c\x5b\xaa\x4d\x4d\xa5"
-  "\xb8\x9d\xd3\x26\x61\x8d\xb9\xd5\x3f\xbc\x10\xd1\x96\x2d\x43\x03"
-  "\x24\xbe\x03\xf3\x7d\x09\x74\xf8\x15\x43\xff\xa1\x01\x69\x66\x44"
-  "\xad\x4d\x75\xf7\x78\xa1\x80\x2e\xbd\xfe\x68\x20\xd4\xf9\xad\x63"
-  "\x0f\x25\x23\x24\x9d\x9b\x6f\x1d\x6b\x7d\xf7\x22\xf6\xdd\xe1\x59"
-  "\xcc\x98\xb0\xa7\xf2\xd3\x99\xf7\x85\x6b\x56\x88\xf9\x8b\x5e\xee"
-  "\x4d\x7f\x5b\x60\x42\x0b\x0a\xe8\x96\x05\x85\x10\x27\xd7\x8f\x8d"
-  "\xdf\x55\x54\x83\xe3\x7a\x90\xd5\x9e\x8c\xed\x4c\x06\x14\x9f\x8a"
-  "\xbc\x2f\x29\xb7\x0d\x0c\x4f\x41\xcc\x9e\x4d\xdf\xc0\x75\x12\xcb"
-  "\xca\xf4\x7f\x55\x81\xae\x87\xb6\xdc\x42\xda\xa6\x6d\x13\x5f\x62"
-  "\xf3\xc3\xe7\xac\xfe\x2b\x62\xf5\xb6\xf4\x67\x6c\x9b\x2a\xe3\x5d"
-  "\x55\xc2\xef\xfa\x59\x6f\xf9\xef\xba\xad\xd6\xfe\x5d\x3f\x1b\x75"
-  "\x6b\xdf\xf5\x33\xd1\xf1\x3f\x0e\xde\x55\x2b\xfc\xae\x9f\xbb\xcb"
-  "\x7f\xd7\xcf\x8e\xd9\xbf\xeb\xe7\x03\x6f\xed\xbb\x7e\x2e\x3a\xff"
-  "\xdd\xc1\xbb\x06\x88\xbc\xeb\x55\xf9\xef\xfa\xf9\x01\xfb\x77\xdd"
-  "\xde\xfb\xd6\xbe\xeb\x76\xad\xe8\xbb\x52\xde\x34\x8e\x4f\x10\x97"
-  "\x5a\x52\x9b\x81\xd3\xad\x7f\x23\x68\xe9\x26\x44\x55\x34\x18\x51"
-  "\x95\x6f\x0d\x4a\x5b\x84\xa8\x27\xe3\x21\xee\x2d\x47\xc3\xe9\xf5"
-  "\x5e\x01\x55\x05\xf5\x90\x7e\x01\x55\x26\x1b\x51\xd0\x7c\x1c\x7f"
-  "\xb7\x9f\xaf\x8e\x95\x1a\x7f\xb7\x97\xdc\x8c\xbf\xa6\xa7\xd9\x98"
-  "\xbb\xb3\x47\x55\x7d\x0b\xc2\xef\x7f\x45\xb9\xc3\x7c\x33\xfe\x2e"
-  "\x27\xf6\x6e\x1b\x7f\xb1\x3d\xaa\x8d\x46\x5e\xfc\x25\xf3\xb6\x76"
-  "\x94\xb7\x8d\xbd\x59\x97\x10\x12\x8e\xbd\x3b\xb6\xe0\xd8\x5b\x04"
-  "\xe7\xa5\x95\x7f\x47\xbc\x35\xf6\x66\xc3\x33\x6d\x63\xef\xb7\xb1"
-  "\xb8\x7d\xdd\x51\x26\x2f\xf6\xee\x28\xb3\xbe\x77\x21\xfb\xde\x90"
-  "\x36\x80\x1f\x7b\x77\x22\x67\x70\x4b\xaf\x0f\x8e\xd8\xd5\xd7\xe8"
-  "\x6e\xd9\x3c\x2c\x1e\xb7\x6f\x4d\x60\x93\x2f\x8b\x8c\x6e\x17\x94"
-  "\x3b\x19\x5b\x5d\x6f\x8a\x55\xd0\x9b\x03\x35\xe1\x09\xf4\x19\xba"
-  "\xff\xb0\x78\xdc\x77\x8a\xfb\x00\xe0\xfc\x5e\x7a\x4b\xa0\x46\x5a"
-  "\xb9\x77\xb2\xed\xdf\x33\x25\xa9\x50\x5f\x76\x25\x19\x29\xcb\x92"
-  "\x48\x6f\xf0\x83\x8a\xce\x7b\x31\x9b\x7e\xb7\x3f\xba\x9e\x17\x83"
-  "\x8e\xe8\xce\x23\x7c\x2d\xbd\xcc\x2d\x48\x7e\xf9\x77\x05\x39\x2e"
-  "\xff\xae\x44\xe9\xe5\x27\x79\x3a\x57\xfe\x5d\x41\x4e\x95\xbf\x17"
-  "\x94\xbf\x25\xd0\x1d\x34\x23\xf5\x4d\x4b\xa0\x9b\xc4\xf2\x1c\x73"
-  "\xca\xc7\x2e\x3d\xa3\xc4\xe9\xf8\x47\xf7\x8a\xcc\xde\x55\x64\xa0"
-  "\x20\x06\x30\x6d\x38\xae\x7b\x24\xfe\xd5\x81\xd6\x3d\x43\x93\x98"
-  "\x64\x90\x18\x93\x4a\x44\xf7\x7f\xb7\x7f\xfe\x58\xc3\xad\x7f\xfe"
-  "\x6e\xf1\xf7\x6f\x1b\x13\x77\x86\x65\x8b\xc7\xc4\x17\x0d\xf6\x31"
-  "\x71\x77\xb3\xf4\x98\xb8\xfb\xb0\x7d\x4c\xfc\x7b\x7f\x2e\x26\xfe"
-  "\xbd\x87\xfc\x98\xf8\xb7\xd3\xce\xc7\xc4\xbf\xed\x97\x17\x13\xff"
-  "\xb6\xc2\x71\x4c\xfc\xdb\x29\x79\x31\xf1\x6f\xa7\xec\x63\xe2\xdf"
-  "\x82\xf8\x31\xf1\xef\x6a\x51\x5f\x66\x07\xa8\xa0\x8d\xf6\xbc\xa4"
-  "\xfc\x7b\xad\x69\x39\x42\x96\xec\xcf\x75\xd0\xce\x36\xd1\x39\x01"
-  "\x2a\x0b\x35\x18\xc7\x95\xa0\xa6\xa6\x38\x0f\xcb\x42\x9d\x27\xdd"
-  "\xf3\x85\x97\xe9\x56\x0d\xee\x6b\xf4\x83\xf2\x7b\xd3\x4d\x3a\x2f"
-  "\x7a\xa1\xae\x67\x41\x23\x52\xc3\xa1\x29\x60\xdb\x63\xf8\x3f\x80"
-  "\x5e\xa8\xe9\x96\x95\x84\x06\x78\x37\x20\x0f\x28\x43\xa4\xf7\x32"
-  "\x15\x82\x18\xa4\xc6\xff\xd3\xcb\xbf\xd0\x6d\x6c\x44\x6e\xde\xc9"
-  "\xe0\x9b\x1e\xf0\xbc\x64\x6f\x9a\x5e\xa0\x43\x1b\xe7\x23\x0f\x0b"
-  "\x85\x34\x45\x14\x5d\x62\x6a\xd2\x51\x66\x75\x54\x09\xf1\xcf\x9e"
-  "\x7c\x46\x7b\xe5\x46\xa5\x58\x7a\x45\xc5\x9a\xd3\xe2\x94\xf4\x92"
-  "\x48\x25\x2e\xab\x39\x37\x2a\x9a\x5e\x0f\x47\x5a\x9c\x17\xe6\xd0"
-  "\x1b\x93\xe0\xd9\x4d\x9a\x6e\x6b\xe1\xd9\x45\x49\xc8\xaf\xb0\x11"
-  "\xe9\xe8\xeb\x3a\x0a\xfc\x1f\x89\xf7\x3e\x05\x1b\x45\x5a\xa8\x2f"
-  "\x74\x70\xce\x0d\xc7\x44\x1a\x3f\xdf\x04\xcf\x6f\xd5\xe1\x7e\x2e"
-  "\xdc\x67\xa1\xd9\x08\xcf\x37\x2f\xd4\x49\xac\x2f\x7b\x98\xf9\x4f"
-  "\xd6\x72\x59\x06\xbc\x9c\x4d\xef\x84\x03\x97\x0b\x6c\xb8\x11\xdb"
-  "\xe4\xc9\x97\x73\x71\xd9\x32\x1b\xd1\x00\x28\xa7\x1f\x94\x41\x07"
-  "\xcf\xc5\xeb\xc6\x44\xbe\x3e\x4f\x85\x31\xca\x2b\x9b\x39\x87\x2d"
-  "\xdb\xef\x50\xb6\x2b\x5c\xd9\xf0\xb3\xb0\x7d\xc4\xbe\xc9\x86\x2f"
-  "\xed\x8b\xeb\xe6\xaf\xde\xc9\x5d\x42\xf0\xf7\xd9\xeb\x4b\xe2\x24"
-  "\x62\x75\x6f\x80\x18\x5e\xd6\xee\x44\xbe\xb4\x6a\x8b\xee\xa5\x95"
-  "\x67\x68\xdc\x8f\xb8\x72\x27\x1a\x50\x0d\xf5\xba\xca\x78\x19\xd1"
-  "\x3d\xb6\xe8\x8e\xe8\xea\xa5\x3e\xab\x40\xec\x59\x6b\x96\xd3\xc7"
-  "\x5a\xfd\x70\x1f\x58\xb4\x71\x2d\x45\x27\xb7\xf8\x05\x6a\x8f\x9e"
-  "\x68\x41\x51\xc9\xf8\x1b\x30\x9d\xac\x9d\x8c\x3c\xce\x29\x0f\x44"
-  "\xa4\x9d\xc4\xdf\xab\xbe\xd0\xf2\xbf\x57\x7d\x31\x1a\x29\xbf\xac"
-  "\x43\xca\xfd\x1a\xa4\xfc\xaa\x18\xc1\x75\xfc\xe3\x1f\x35\xe1\xdb"
-  "\xfa\xa2\x54\x13\xfd\x2b\x9d\xeb\x1d\x97\x45\xd1\xc6\x70\x7f\x85"
-  "\xbe\x34\x09\x7f\xbf\xf9\xf2\x2c\xd8\xef\x37\x68\x57\xbd\xf1\xff"
-  "\x38\xbf\xf8\xf9\xe8\x0f\x97\x94\x5f\xea\xbd\x1b\xba\x84\x98\xd4"
-  "\x31\x5a\x13\x1d\x89\x5a\xb5\x89\xe9\xcd\xb9\x51\xd9\xad\xb8\x8f"
-  "\xee\x0d\x1c\x83\xbe\x38\xe9\xad\x48\x47\x34\xf8\x9f\xa6\x35\xf8"
-  "\x1b\x66\x64\x01\x1c\xd8\x97\x8c\x1f\x7b\x86\xe8\xb1\xbf\x71\x5d"
-  "\xd8\x48\xd2\x55\xb8\x3e\xac\x65\xeb\x8d\x41\xf9\x78\xb4\x99\x42"
-  "\xc8\x0c\xf7\xa7\x9d\x47\xbe\x78\xcf\xdb\x42\xb8\x2e\xca\xec\x81"
-  "\xeb\x71\x64\xe9\xe4\xef\xd1\x85\x78\x44\xa5\x5d\x45\xdd\x01\x13"
-  "\x4c\x7d\xb4\x40\x7d\x0c\x3f\xe5\x6d\x84\xb8\x62\x49\xbd\x81\xbc"
-  "\x71\x9c\xc2\xfb\xc7\x54\xd7\xeb\x91\xe5\x77\x9d\xd7\x87\x73\x90"
-  "\xda\xf4\x7b\x5c\x4f\xc3\xef\x71\x7f\xd8\x60\x41\x6a\xaf\x78\xa4"
-  "\x2a\x9c\x03\x58\x9c\x0b\xf5\xf3\x0a\xd4\xcf\x7a\x52\x3f\xad\xf8"
-  "\xa3\xd7\x9c\xce\xc6\xf3\xfa\x99\xba\x99\xc3\xd6\xcd\x85\x80\xbf"
-  "\x24\x0e\x7f\xa6\xb9\x3a\xaa\x90\xa2\x11\x94\x11\xec\xbe\x57\xb5"
-  "\x31\xb5\x8b\x07\xee\xa7\xa4\x1f\x7d\x56\x05\x31\x1f\xde\x95\x36"
-  "\xed\x02\x5f\xb8\xfb\x53\x5a\x3a\x2f\x46\x7b\x34\xa2\x0e\x71\xfd"
-  "\x26\x07\xc6\xb7\xf4\x0f\xd4\x6a\x5f\xa6\x7f\x3f\xa7\xfc\xb2\x06"
-  "\xd2\x3d\xb4\xaf\x3e\xa6\x02\x3f\x8e\x27\xfd\x2c\x07\x22\x70\xbf"
-  "\xa9\x5e\xf9\xe5\x76\xc8\x0b\xe1\x71\x01\xdf\x31\xdf\xdc\xf6\xab"
-  "\xe0\x5a\x64\x06\x9b\x9b\xd4\x5e\xfb\x2c\xea\xa8\xd2\xd2\x99\x2d"
-  "\x4c\xbc\x6a\x05\x1f\x5c\x98\x85\xa8\xa8\x7a\xb0\x8d\x19\x6c\xd3"
-  "\xa4\xf3\x84\xb8\x15\x81\xe3\x16\x9d\xfd\xc2\xd8\x14\x3d\x6d\x09"
-  "\x8f\x55\xd2\x60\x17\x0f\xdc\x4f\xfe\x7a\x3c\xa2\x97\x5e\x06\x1b"
-  "\x35\xd4\x20\x78\x37\x2f\x88\x6d\x3d\x0b\x93\x90\xfa\x43\xb0\x4f"
-  "\xf7\x7a\xe0\x34\xeb\x3e\xd5\xee\x4c\x2d\x73\x37\x03\xce\x71\x1c"
-  "\xf3\x5e\xa6\xe8\x0a\xbe\xf2\xca\xc0\xf5\x16\xea\xb1\xf7\x32\x26"
-  "\xae\x32\xbe\x35\x2d\xd4\x3d\xd2\xba\x50\xa7\x85\xa3\xaf\x35\xd6"
-  "\x59\xe3\x0c\x9d\xb5\x37\x19\xc7\xb9\xea\x64\x3d\x32\x81\x2d\xbd"
-  "\x70\x9b\xb8\x50\xe7\xcb\xd8\xf4\x2f\x60\xd3\xb7\x90\xc7\x53\x46"
-  "\xa4\x80\x72\xa9\xa0\xcc\xa8\x32\xee\x1c\x8e\xad\x1a\x33\xd4\x23"
-  "\x6c\x67\xc8\x93\xa2\x01\x6b\x96\x5c\xaf\x7d\xe3\x66\x68\x81\x5f"
-  "\xfd\x80\xf0\xda\xb1\x69\xcd\xf4\x59\xfc\xcd\xaf\x3a\xd9\x84\x68"
-  "\x9f\x18\x2d\xcd\xf4\x75\x7d\x59\x72\x34\xc2\x88\xc4\x31\xfd\xd5"
-  "\x06\x0e\xd3\x5f\x6d\xe0\x30\xfd\x15\xb3\xfe\xa7\x2d\xae\x9b\x8b"
-  "\x01\xd7\x6a\x5b\x5c\xef\xdf\x7d\x5b\x71\xfd\x92\x74\x5c\x6f\xb8"
-  "\x62\x83\xeb\xd4\xff\x0e\xae\xbf\x8b\x64\x70\xad\x6c\xed\xcf\xe0"
-  "\x75\x4f\xb5\xe9\x6f\xc0\x7f\xbf\x5a\x61\xc5\x6d\xf9\x67\x18\xb7"
-  "\xff\x28\xeb\xac\xb8\x6d\x6e\xd2\x69\xe1\xb8\xe5\xb8\x85\x3c\x9d"
-  "\xc6\xed\x77\x91\x2d\xc8\x6a\x3f\x8c\x5f\x3a\x7b\x8b\x4e\x9b\x86"
-  "\x46\x42\x9c\x88\xf0\x5e\xd6\x17\x55\x32\x36\x3c\x10\xa1\x7d\x95"
-  "\xb6\x40\x8c\x60\xbe\x81\xb6\x2c\xa7\x69\xcb\xff\x6f\xef\x6b\x00"
-  "\xa2\xba\xce\xb4\xcf\x0c\x57\x43\x2c\x32\xa3\x01\x1c\x15\x75\x44"
-  "\x50\x8c\xa0\x68\x34\x21\xf9\x68\x3f\xda\x98\x3a\x18\x35\x76\x97"
-  "\x64\x89\x35\xad\x1a\x35\x68\x50\x09\xfe\x11\xff\x40\x42\xf2\x69"
-  "\x62\x60\x24\xe0\x62\x44\xa0\x2d\xd9\x92\xad\x69\xdd\xad\xd9\x8f"
-  "\x7e\x9f\x9a\xb1\xe2\x96\x18\x74\xb0\x31\x2d\x49\x49\x3a\x31\xc4"
-  "\x10\xe2\xcf\x44\x86\xf0\x33\xc3\x9c\x7d\xdf\x73\xce\x65\xee\x0c"
-  "\x33\xf2\x2b\x9b\x35\x5e\xbd\xdc\xb9\xe7\xbe\xf7\x3d\x7f\xcf\x79"
-  "\xce\x7b\xde\x7b\xef\x39\x41\x4b\x4a\x33\x2e\x10\xad\x33\x7f\x54"
-  "\x8c\xd9\xf1\x16\xd1\xa4\xf2\x67\x0b\x74\xc4\x89\x06\x18\x87\xb3"
-  "\xe7\xb0\xce\xfd\x6f\xc4\xa2\x8f\x19\x9f\xa3\xe0\x33\x4d\xe7\xfe"
-  "\x17\x89\x73\xc4\x89\x78\xba\xff\x44\x26\x3e\x9f\x6d\xc9\x39\xbe"
-  "\x58\x7e\x3e\xef\xd5\x36\x0a\x5a\x5b\x0a\xed\x05\xc6\x54\x27\xde"
-  "\x85\xa3\x1a\xd2\xf1\x25\x1c\xfd\xe0\xc8\x9e\x67\xf6\xae\x9f\x3b"
-  "\x9e\xcd\x9f\x2f\x2d\x9f\x2d\x78\xf0\x45\xd6\x06\xef\x25\xc3\x1b"
-  "\xc5\x6f\x48\x8f\x45\x7e\xde\xdf\x29\xef\x2a\x8f\x1d\x18\x37\x94"
-  "\x89\xc4\xdf\x41\xe0\xe7\xf8\x7e\x8f\xd0\xc7\xce\x9d\xe1\xf3\x75"
-  "\xa6\x5d\x97\xc8\x15\xbf\x13\x0b\xcc\xd0\xf7\x3b\x0f\x2c\x9f\x8d"
-  "\xcf\xdd\x10\xf7\x72\xbc\x81\x50\xdf\xa6\x6d\x4c\x86\x7d\x27\xed"
-  "\xcc\x4f\x22\xf4\x80\x26\x06\xc7\x90\x2d\x34\xf9\x07\xe2\xf8\x7d"
-  "\xc4\x36\xf7\xb7\x9c\x38\x48\xa1\xfc\x70\xcd\xf7\xce\x77\x9e\x70"
-  "\x2d\xf6\x4c\x49\x7f\x6a\x07\xef\x6f\xe5\xf4\xe2\x7a\xed\xf8\x4e"
-  "\xd1\x94\x4c\x92\xd9\xe2\x65\xbd\x76\xd7\xbb\x47\x27\xb2\x9d\x05"
-  "\x49\x60\xf7\x9e\xb8\x08\x36\x40\x9d\x32\xcf\xde\xea\x02\xe4\xad"
-  "\xbe\xae\xf5\xae\x1e\x4e\x06\xf8\xd2\xf3\x48\x64\x07\xed\xa5\x2e"
-  "\x9f\xf3\x9f\xd1\xf0\xfb\x8f\x3e\x56\xde\x61\x72\xda\x93\x34\x67"
-  "\x76\x5c\xed\xa5\x4d\x74\xd2\xe7\xfc\xd7\x1d\xf9\x4b\x4c\x8e\xc9"
-  "\xa0\x7b\xea\x78\xd2\xb1\x21\x69\x1e\xd4\x51\x00\xda\x7a\x3b\xd7"
-  "\xf0\xf7\xd4\xaa\xcb\x1d\x04\xed\xbe\x37\xd7\x57\xa9\xdb\xed\x49"
-  "\x24\xd0\x4a\xb4\x8b\x9a\xa9\x33\xf7\x1a\x09\xa7\x5b\x93\x34\xfb"
-  "\xae\x91\x38\x7b\x93\x6e\xd8\x2b\x69\x44\x6a\x07\x4e\x6e\xdf\x98"
-  "\xac\xc1\x77\xe2\x4e\x36\x9a\xd4\x66\x47\x05\xda\x99\xe1\xd8\x0f"
-  "\x60\xda\x3b\x9a\x92\x02\xf7\xde\xc0\x67\xc5\xcd\xc4\xb4\xe2\x97"
-  "\xd0\x0f\xbc\x73\x62\xc8\x4e\xe0\x3e\xe0\x2e\xd6\x1f\xf4\xa1\x2f"
-  "\x68\x87\xbe\x60\x61\x12\x6d\x3d\x5f\xfb\x67\x7c\x7e\xad\xcd\xd8"
-  "\x4c\x86\xa3\x7e\x7c\xde\xcc\xfa\x87\xc7\xa1\x7f\x80\x73\x18\x4b"
-  "\x74\xf6\x0f\xfa\x45\xa4\x4b\xff\x80\xe3\x90\xf3\x75\x0d\x04\xb0"
-  "\x7c\xd7\x22\x9b\xa6\x75\x97\x8d\x3a\x71\x4c\x62\x76\x5c\xc5\xb9"
-  "\x8b\x02\xe5\xbe\x02\xfb\x89\x76\xd1\x4f\x1c\x16\xfd\xc4\xeb\x03"
-  "\xd0\x4f\xbc\x8e\xfd\xc4\x07\x44\x7d\x10\xfb\x08\xe8\x1f\x7e\xf3"
-  "\x89\x55\x6d\x87\x3e\xa1\x77\xf5\x6c\xf2\xb9\xfe\x05\x3d\xb0\xdc"
-  "\xcf\x09\x7d\x31\xd6\xf3\x76\xa8\x5f\xac\x67\x73\x24\xd4\x6d\xed"
-  "\x5d\x86\x36\x08\x77\x1c\x98\x97\x5a\x7e\xd9\xaa\xa6\xf9\x8f\x1a"
-  "\xdb\x00\x0f\xdb\x9a\x89\xda\x11\xb4\xc4\xf4\xd6\x13\x46\x35\x8e"
-  "\x5b\x9d\x05\xf3\x8e\xf1\x31\xf2\xe9\xe1\xe8\xa3\xd1\x34\xe0\x73"
-  "\x7d\xea\xec\xa0\x49\x1a\xe7\x57\x49\xc3\x9d\xcf\xea\xfc\xed\x5f"
-  "\xe9\x86\xbd\xbc\x96\x48\xd6\x67\x93\x35\x19\x4f\x12\xed\x3b\x7f"
-  "\x31\xaa\xcf\xdb\xa0\x6d\x0f\x35\xaf\xa4\xa0\xbf\xe4\x12\x89\x2d"
-  "\x59\x41\x66\x17\x5f\x26\xfa\xe2\xd5\x24\xea\xd0\x65\xc0\xd0\xb3"
-  "\x49\x81\x76\x86\x8f\x36\x13\x7b\x37\x60\x35\x89\xa7\x21\xf3\x53"
-  "\xe1\x18\x6b\x5c\x4d\x70\xde\xc2\x54\x1a\xbc\xc4\xe4\x04\xb9\x7d"
-  "\x30\x76\x03\x1b\x1d\xd2\x70\xaa\xd9\x1b\x6e\x0e\xf5\xd2\x86\x58"
-  "\xb8\x18\x70\x53\x03\xb8\xf9\xda\x1d\x37\x38\x6e\x65\xd8\x59\xc8"
-  "\xb1\x83\xcf\x00\x4b\x94\xf6\xc5\x8a\xb3\x7d\xc6\x4f\x11\xd8\xcf"
-  "\x6d\x1e\xf8\x29\xba\xd6\x3f\xfc\xd8\x01\x3f\x45\x59\x80\x9f\x73"
-  "\x44\x5d\xe8\xec\x0f\x7e\xfe\xc8\xd7\xda\x28\x8b\x15\xef\x27\x9d"
-  "\x9a\x83\xf5\x6c\xf1\x3b\x35\xfb\xf1\x48\x15\xe9\x23\xae\xac\x37"
-  "\xc7\x95\x61\x36\xc7\xd5\x99\x55\x7d\xc0\xd5\x71\xc0\x95\xf5\xe6"
-  "\xb8\x6a\xf6\x85\x2b\x6b\x57\x5c\x55\x2e\x1c\x5c\x5c\xb1\xb9\x42"
-  "\xbf\x03\xb8\x3a\x13\xe3\x8e\xab\xd3\xaf\x72\x5c\x9d\xde\xd7\x77"
-  "\x5c\x19\xba\xe1\x2b\x83\xe0\xab\x3f\x9d\xe8\x3d\xae\x6a\x82\x28"
-  "\xe8\xbf\x39\xae\xae\xfa\xc0\x95\xc1\x0b\x5f\xfd\xe7\x1b\x83\x8b"
-  "\x2b\x36\x97\xe9\x77\x00\x57\x7f\xda\xe3\x8e\xab\x33\x9f\x73\x5c"
-  "\x9d\xa9\xef\x07\xae\xba\xe1\xab\x04\xc1\x57\x67\x83\xfb\x80\xab"
-  "\x14\xc0\x55\x37\x7c\xf5\xb1\x2f\x5c\x79\xe1\xab\xaa\x8e\xc1\xc5"
-  "\x15\x9b\x6b\xf5\x3b\x80\xab\x77\x2d\xee\xb8\xaa\xfa\x3e\xc7\x55"
-  "\x55\x5c\xdf\x71\x95\xd0\x0d\x5f\x25\x08\xbe\xaa\x5e\xd7\x07\x5c"
-  "\x55\x52\xd0\x7f\x73\x5c\x9d\xf0\x81\xab\x04\x2f\x7c\xf5\xde\xe3"
-  "\x83\x8b\x2b\x36\x17\xec\x77\x00\x57\xd5\xb1\xee\xb8\x3a\x5b\xc0"
-  "\x71\x75\x36\xbf\x1f\xb8\xea\x86\xaf\xe6\x0b\xbe\x3a\x7f\xa6\xf7"
-  "\xb8\xba\x10\x0a\xb8\xea\x86\xaf\x76\xfa\xc2\x95\x17\xbe\x3a\xf7"
-  "\xd6\xe0\xe2\x8a\xcd\x55\xfb\x1d\xc0\xd5\x79\xa3\x3b\xae\xaa\xaf"
-  "\x72\x5c\x55\x5f\xe9\x11\xae\x5a\x15\xb8\xaa\xbb\xcb\xd0\x9e\xc1"
-  "\xc7\x83\x6f\xae\x16\xb8\xfa\x97\xfb\x8f\x6e\xdf\x4c\xd4\x6f\x2d"
-  "\x29\xf4\x18\x0b\x5e\x18\xe1\x89\x29\xc0\x05\xc3\x94\xe3\x59\xc0"
-  "\x54\x23\xc7\xd4\xae\x8f\x01\x53\x1f\x15\xaa\xcd\xe9\x57\x11\x27"
-  "\x0c\x43\x45\xab\x01\x43\x38\x2e\x54\x49\xba\xde\x8c\x01\x5f\x69"
-  "\x94\xb1\x64\x6e\x1b\x10\x2c\x25\x02\x96\x2e\x7a\x62\xe9\x8c\x0b"
-  "\x4b\x3f\xf1\x31\x06\xfc\x99\x0f\x2c\x59\xba\xc7\xd2\x21\xf4\x21"
-  "\x6c\xb8\x45\x58\xba\xe0\xf2\x21\x1c\x59\x61\x55\x3b\x82\x7b\x8b"
-  "\xa5\x9a\x3a\x77\x2c\x99\x7f\xc8\xb1\x64\x8e\xef\x3b\x96\x0c\x56"
-  "\xdf\x58\x92\xed\xa9\xf7\x9f\xea\x1f\x96\xc0\xb6\x72\xc3\x52\xf7"
-  "\x76\x94\x0b\x4b\x7f\x7e\x64\x70\xb1\xe4\x61\x47\xdd\xb6\x58\x7a"
-  "\x3f\xd2\x1d\x4b\x17\xc4\xb8\xef\x82\xcf\x71\x9f\x13\xfa\x2e\x7c"
-  "\xe6\x84\xdf\xfd\x76\x34\x25\xcd\xeb\x80\x3e\x0d\xbf\xff\xc5\xe7"
-  "\x14\xbf\x5b\x5f\xa3\x46\x3c\xe5\xdc\x20\xe1\xfb\xd2\x48\x9c\xa6"
-  "\x95\x63\xc5\x01\x58\xd9\x73\x83\x48\x76\x3b\xe0\xa4\x9d\x48\x6d"
-  "\x50\xde\x6d\xf6\x64\x4d\xf5\xb2\x06\xf2\xce\xb5\x1a\xe8\xcb\x2a"
-  "\x48\x31\xdc\x63\x17\x7e\x48\xe7\xf6\xa4\xc0\xbd\xdb\xd0\x0f\x79"
-  "\x8e\x98\x96\xbc\x0e\xf5\x7f\xb1\xdf\xf5\xdf\xf6\x82\xaf\xfa\x3f"
-  "\xe1\x56\xf7\x45\x8a\x7a\x67\xdf\x16\xf4\xb1\x3f\x62\xcf\xa9\xd6"
-  "\xf3\xba\x97\xeb\xfd\xe0\x00\xd4\xfb\x41\x51\xef\xfd\xeb\x8f\x3e"
-  "\xf0\xfd\xfe\xa3\x82\x2b\xd8\x3b\x05\xad\x9c\x23\x64\x5e\x40\x8e"
-  "\x40\xfb\xa5\x2d\x68\xde\x26\xcf\xfe\x06\xf9\xe1\x9a\xdf\x5f\x5f"
-  "\xc5\xbe\xc9\xa7\x1d\x23\x78\x22\xe3\x79\xce\x13\xc2\x8e\xd9\x34"
-  "\xb0\xfe\xc7\xbf\x6c\xbe\x75\x7c\x71\xa2\xfb\xbe\xa7\x1f\x76\x0c"
-  "\xe2\xa6\xc8\x03\x37\xb7\x82\x2f\xfa\x86\x9b\xbf\x26\xb9\xf3\xc5"
-  "\x07\x6f\x73\xbe\xf8\xe0\x58\x4f\xfa\x9e\x6e\xf0\x64\x73\xe1\x89"
-  "\xfb\x1c\x39\x9e\x3e\xfc\x18\x7d\x94\xbd\xc4\x53\xd5\xc0\xfa\x1d"
-  "\x6b\xcf\x0c\x2e\x9e\x06\xce\xef\xf8\xed\xc6\xd3\x87\xe5\xee\x78"
-  "\xaa\x1d\xc2\xf1\x54\x2b\xf5\x1f\x4f\x06\x05\x3f\x19\x14\xfc\x54"
-  "\x17\x8d\xbe\xc9\xde\xe1\xe9\xcf\xa1\x03\xeb\x6f\xfc\x5b\xf0\xe0"
-  "\xe2\x69\xe0\xfc\x8d\xdf\x6e\x3c\xfd\xad\xd5\x1d\x4f\x1f\x3d\xce"
-  "\xf1\xf4\x51\xe2\x00\xe0\xc9\xe6\x69\x13\x73\x3c\x7d\xb2\x13\xed"
-  "\xe7\x5e\xe2\x29\x75\x60\xfd\x8c\x1f\xaf\x1a\x5c\x3c\x0d\x9c\x9f"
-  "\xf1\xdb\x8d\xa7\x4f\x0c\xee\x78\xaa\x7b\x83\xe3\xa9\xae\xac\xff"
-  "\x78\x4a\x50\xf0\x53\x82\x82\x9f\x2c\xe7\xd0\x17\xd9\x4b\x3c\x0d"
-  "\xb0\x7f\xf1\xef\x6f\x0f\x2e\x9e\x06\xce\xbf\xf8\xed\xc6\x93\xa5"
-  "\xd0\x1d\x4f\x9f\x34\x73\x3c\x7d\x62\x1b\x00\x3c\x29\xf8\x69\xbe"
-  "\x82\x9f\x3e\x1b\x87\x3e\xc8\xde\xe1\xe9\x7d\xdd\xc0\xfa\x15\x2f"
-  "\x0d\x19\x5c\x3c\x0d\x9c\x5f\xf1\xdb\x8d\xa7\x4b\x0d\xee\x78\xfa"
-  "\xf4\x11\x8e\xa7\x4f\xe7\xf6\xd4\x17\x24\xfb\x80\x94\x78\xf2\x3d"
-  "\xb6\xfb\x7c\xb9\xe7\xd8\xae\x77\x3e\x20\x18\xe7\xf5\xd9\x9f\x58"
-  "\x9f\xf0\x3f\xd5\x9f\x88\x18\x92\xfd\x40\xdf\x3e\x1f\xd0\xe7\x51"
-  "\xee\x18\xfa\x6c\x3f\xc7\xd0\x67\x46\x5f\x18\x72\x28\xdf\x49\xfb"
-  "\x42\xf1\x4e\xda\x55\xa2\x7e\x6b\xbd\x49\x7d\x5e\xbc\x93\x86\xef"
-  "\xa3\x9d\xaf\x6f\x20\x7b\xbf\x21\xda\xc0\x64\xa2\x5d\xf4\x1c\x75"
-  "\xe6\x22\x87\x6c\x4c\xd2\xbc\x72\x99\xc4\xd9\x01\x33\x39\x8d\xe2"
-  "\xbd\x34\xc0\xcd\x7b\x75\xad\xe4\xe4\x7a\x7c\x2f\xed\x28\x29\x01"
-  "\x39\x47\x3e\xf7\x07\x21\x8f\xb0\x77\xd2\x56\xe3\x3b\x69\x97\x7f"
-  "\xe2\xf5\x9d\xb4\xac\x5e\xbe\x93\xb6\x09\x70\x60\x03\x1c\x34\x23"
-  "\x06\xde\x76\x7b\x17\xed\x50\x96\xc2\x07\xb4\xc2\x87\x0f\xa8\xb6"
-  "\x67\xcf\x24\x06\xfc\x5d\xb4\xeb\x8a\x77\xd1\x64\x1f\xd0\x12\xe0"
-  "\x8e\x5e\xd7\xfb\x17\xe1\x37\xf3\x01\x75\x00\x27\x2c\xc2\x77\xcb"
-  "\x6d\x2e\x7f\xf1\x8e\x35\xf8\xed\xef\xbc\x54\x07\x70\x05\xbe\x3f"
-  "\xfe\xdb\x15\x55\xcc\xdf\x67\x4e\xaf\x25\x7b\xdb\x89\x56\x63\x15"
-  "\xbc\x10\x3c\xef\x98\x1d\xb8\xa1\x03\xfa\x25\xa8\xeb\xe1\xf6\x8d"
-  "\xc0\x0d\x37\x80\x1b\x36\x02\x37\x34\x03\x37\x5c\xaa\x62\xdc\x40"
-  "\x5f\x32\xaf\xc4\x39\xbf\x4b\x1a\xc9\xec\xc3\x8d\x24\x16\x39\xa0"
-  "\xa3\x60\x09\xae\x29\x9c\x6f\x0d\x9e\x57\x08\xd7\xca\x39\x06\xda"
-  "\x4c\xfb\xd2\x08\xe3\x7a\xac\x7b\xfd\x6a\xe4\x83\x86\x27\xed\x59"
-  "\x84\xf4\x07\x07\x76\xa5\x4f\x50\x89\x03\x1f\x1c\xd0\x6f\x2c\x78"
-  "\xf8\x81\x0f\xf5\x93\x03\x10\x0b\x87\x64\x0e\xe8\x17\x16\xbe\xf4"
-  "\xf9\xfd\x4f\x37\x58\xb0\x76\x8f\x05\xc3\xec\x1e\x62\xe1\x38\xce"
-  "\x95\xdd\x15\x0b\x86\x20\x6b\xb0\x41\x07\xd7\x22\x39\x16\x9a\xbd"
-  "\x60\xa1\x71\xd5\xad\xc7\x82\xbb\x4f\xe6\xf6\xc5\xc2\x57\x3e\xe7"
-  "\xff\xbc\x39\x16\x0c\x3d\xe0\x05\x43\x0f\x79\xa1\x26\x08\xe7\x98"
-  "\xf6\x82\x05\xe0\x05\x03\xf0\x82\x41\xf0\xc2\x55\x2f\x58\xb8\xf2"
-  "\xdc\xad\xc7\x82\xbb\x3f\xe5\xf6\xc5\xc2\x55\xdf\xf3\x5f\xdc\x1c"
-  "\x0b\x3d\xe0\x85\x84\x1e\xf2\x42\x4d\x0a\xce\xcd\xdc\x15\x0b\x09"
-  "\xc0\x0b\x09\xc0\x0b\x09\x82\x17\x3e\xf6\x82\x85\x6b\x3b\x6f\x3d"
-  "\x16\xdc\x7d\x21\xb7\x2f\x16\xae\x27\xf6\x0d\x0b\x09\x3d\xe0\x85"
-  "\x84\x9e\xf2\x42\x25\xce\x69\xec\x05\x0b\xc0\x0b\x09\xc0\x0b\x09"
-  "\x82\x17\x4e\x78\xc1\x82\x75\xef\xad\xc7\x82\xbb\x1f\xe3\xf6\xc5"
-  "\xc2\xd7\xcb\xfa\x88\x85\x1e\xf0\xc2\xfc\x1e\xf2\xc2\x85\x50\x9c"
-  "\x0b\xb8\x2b\x16\xe6\x03\x2f\xcc\x07\x5e\x98\x2f\x78\x61\xa7\x17"
-  "\x2c\xdc\x28\xb8\xf5\x58\x70\xf7\x41\xdc\xbe\x58\x68\x4a\xb9\x29"
-  "\x16\x68\x57\x2c\xa0\x0f\x01\xc7\x8f\x38\xd7\x36\xc3\xc2\x5a\x93"
-  "\xba\x9d\x22\x16\xaa\xc8\xcb\xdb\x14\x58\x28\xe0\xe3\x08\x19\x07"
-  "\xaf\x2a\x71\x80\xdf\x2f\x21\x0e\x60\xfc\xe0\x80\x7a\xa7\x07\xe6"
-  "\xa7\xb2\xf7\x95\x0a\xe6\x95\xe3\xf8\x01\xfd\x0c\x38\x86\xf0\x3d"
-  "\x7e\xb0\x1d\x1c\x10\x0c\xa4\x00\x06\xae\x78\x1f\x47\x0e\xf8\xf8"
-  "\xe1\xfa\x2d\xc2\x00\x8c\x25\x5f\xdf\xd5\x1f\x0c\x34\xa7\xf6\x1e"
-  "\x03\x60\x23\xf4\x08\x03\xdc\x4e\xb8\x39\x06\x12\xb4\x2e\x0c\x80"
-  "\xbd\x50\x90\x10\x89\xf6\x01\xc7\x40\x82\xce\xb7\x7d\xf0\xcd\xe1"
-  "\x5b\x8f\x81\x01\xb6\x0f\xbe\xb5\x18\x68\xd9\xe4\xf3\x1b\x46\xe4"
-  "\x72\xe0\xfd\x45\x53\xc7\x13\xfa\x6c\xd2\xbc\x9c\x46\x12\xfe\xca"
-  "\x5a\x12\x87\xf3\xc6\xbc\xd5\xde\xaa\xde\x95\x4a\xbf\xc0\x6f\xab"
-  "\x1d\x90\x0f\x9c\xbf\x9a\xe1\xe3\xba\xce\xdf\x9c\x6c\x25\x7b\x01"
-  "\x0b\xaf\x40\x1e\x70\x5e\xfa\xc0\xd4\xbb\x0c\xe7\x6d\x67\x49\x7b"
-  "\x53\x12\xa9\x5e\xd6\x48\x1e\x8b\xa4\x76\x73\x9d\x09\xbf\x61\x94"
-  "\x4c\x5b\xce\xe2\x77\xe2\xc3\x7e\x9e\x4e\xd4\xd7\xfc\x5a\x63\xd1"
-  "\xa7\x34\x23\x9d\x68\x8b\x1a\xb9\x1f\x69\xef\x35\x42\xce\xa4\x13"
-  "\xc2\xeb\xbd\xb5\x60\xc8\xf3\x03\xe0\x43\x5a\x0a\xf5\x5e\x27\xd7"
-  "\xfb\x19\x77\x1f\x92\xba\x07\xdf\x33\xf6\xc0\x77\x78\x4b\xbe\x67"
-  "\xbc\xde\xf5\x7b\xc6\xbe\xf9\x0e\xdb\x7c\xae\x7f\xc2\xfc\xcc\xc2"
-  "\x0e\xd8\xbe\x89\xb5\x7b\x56\xaf\x76\xe0\x7e\x73\x7a\x05\x7b\x3f"
-  "\x1a\xdb\x39\xb6\x79\xc4\x47\x06\xe4\x17\x31\x82\x78\x58\x54\x6e"
-  "\xb7\xff\xcc\x46\xd4\xce\xe0\x79\xc7\x10\x13\xce\x0d\x3a\xff\x7d"
-  "\x90\x27\xf3\xb2\x4b\x50\xef\x37\x88\xb9\x5e\xd4\xf9\xb6\x4b\x50"
-  "\x97\xed\xe1\x74\x43\xe4\xb0\xe9\x36\xa2\xcd\xf8\x90\x68\x7f\x8e"
-  "\xdf\x1c\x43\x3f\x70\x08\x6c\x82\x92\xb5\x64\x36\xf4\x07\x46\xbb"
-  "\xe0\x06\xa7\xec\x57\xc2\x3e\x02\x30\xf1\xca\x7a\xc0\x04\xa0\x56"
-  "\xff\x33\xc4\x44\xfb\x9b\x43\x36\x7b\xf1\x2f\xf7\x02\x13\xcc\xbf"
-  "\xbc\x12\x30\x51\xef\xc2\x44\xa7\x5f\xd9\x47\x9f\x60\x5a\xd2\x8f"
-  "\x77\x0b\xbd\xf0\x41\xbf\xfd\xca\xd7\x85\x5f\x59\xc1\x07\x7d\xc3"
-  "\x86\xdd\xf7\x9c\x98\xbe\xb1\x61\xed\x1e\x1b\x2d\x02\x1b\x86\xd9"
-  "\xdd\x63\xc3\x11\xef\x05\x1b\xc7\x5d\xd8\x30\x68\x5d\xd8\x10\x7e"
-  "\xa6\x02\x43\x64\x57\x6c\x38\xce\x0c\x0e\x36\x3c\xde\xfb\xb9\x6d"
-  "\xb1\xd1\x51\xda\x7b\x6c\x18\x7a\xc0\x1b\xd7\x65\x6c\xf4\x80\x37"
-  "\x9c\x4b\xbb\x62\xa3\x26\x48\x81\x0d\x05\x6f\x08\xbf\x53\x81\xc1"
-  "\x0b\x6f\x38\x3f\x1d\x1c\x6c\x78\xbc\xc3\x73\xdb\x62\x83\x1e\xef"
-  "\x03\x36\x7a\xc0\x1b\x7f\x17\xd8\x48\xe8\x9e\x37\x24\x92\xee\x05"
-  "\x1b\x29\x2e\x6c\x24\x28\x78\x43\xf8\xa1\xd0\xe6\xf4\xc4\x86\x44"
-  "\x3a\x06\x07\x1b\x1e\xef\xe3\xdc\xae\xd8\x90\x54\xb5\xbd\xc7\x46"
-  "\x42\x0f\x78\xe3\x1d\x19\x1b\xdd\xf3\x86\xa4\xce\xf7\x82\x8d\x4a"
-  "\x05\x36\x14\xbc\x21\xfc\x52\x05\x09\x5d\x79\x43\xf2\x1b\x3d\x38"
-  "\xd8\xf0\x78\xb7\xe6\xb6\xc5\x86\x9f\xad\x0f\xd8\xe8\x01\x6f\x64"
-  "\x08\x6c\xcc\xef\x01\x6f\x48\x47\xbb\x62\xe3\x42\xa8\x0b\x1b\xf3"
-  "\x15\xbc\x21\xfc\x54\x05\xf3\xbd\xf0\xc6\x90\x39\x83\x83\x0d\x8f"
-  "\xf7\x64\x6e\x5b\x6c\x0c\xf5\x39\x9f\xbe\x12\x1b\x3b\x6c\x5e\xc6"
-  "\x29\xf5\x1c\x1b\x76\x90\x51\xe2\x42\x39\x36\x81\xfc\x49\x8f\xc1"
-  "\x98\x05\x31\xf1\xd4\x0e\xa2\x66\xb8\xb0\x29\x71\x31\xb4\x0a\x71"
-  "\x11\x9d\x0c\xb8\xf8\x5c\xe0\x42\x1e\x97\xb0\xb9\x57\xf8\xd8\x44"
-  "\xf6\x59\xc9\xe3\x93\x97\x71\xcc\x9a\x2c\x63\xe2\xae\x84\x21\x6b"
-  "\x06\x00\x13\x6e\xef\x3d\x28\x30\xf1\xa4\x8f\xf1\xc9\x13\x7d\xc7"
-  "\xc4\xeb\x30\x76\xb5\x0f\xf4\xb7\x4f\x32\x26\x3e\xec\x2f\x26\xfc"
-  "\x6f\xfa\xfe\x83\x77\x4c\x08\x3b\xc3\x27\x26\x5c\xb6\x05\xc7\xc4"
-  "\xdf\x6f\x82\x09\xff\xba\xae\x98\x10\x76\x05\x9b\x87\x80\xdb\x16"
-  "\xb2\x0f\x4b\xb6\x2f\xdc\x31\x71\xf7\x53\x83\x83\x09\x0f\xfb\xe2"
-  "\xb6\xc5\xc4\xb0\x58\x5f\x98\x30\xaa\x9d\x47\x61\xaf\x80\xdd\x04"
-  "\x7b\x55\x87\x9a\x3c\x72\x58\xed\x64\xf3\x52\x8b\x36\xe3\x79\x7d"
-  "\x28\x7d\x69\xec\x51\x94\xa1\xbb\x25\x36\x1f\xaf\xac\xa3\x63\x18"
-  "\xc1\xf9\x10\x4d\x1a\xd5\x32\xac\x13\x94\xbd\x4b\xd6\xa5\xd9\x4d"
-  "\xe2\x21\xff\x5c\x4e\x4d\x32\xb9\x5c\xfc\x50\x94\xa3\x39\x27\x03"
-  "\x20\xcc\x5f\xe8\x64\x6b\xe4\x74\xa8\xd5\xa8\xcb\x33\xee\xbb\x85"
-  "\x8c\xbe\x23\x8b\xe8\x95\x71\x83\x2e\x8c\x53\x96\x1b\x86\x72\x1d"
-  "\x6a\x6b\x6b\x87\x4a\x0a\x57\xca\xd1\x1f\x11\xa5\xdc\xf7\x84\xbe"
-  "\x48\xb7\x7c\x84\x11\xa2\x51\xe9\x79\x5e\xd2\xd5\x72\x5e\x02\x98"
-  "\xce\xc0\xe3\x2b\x41\x67\x94\x9b\xce\xa1\x84\x0c\x07\x79\xd4\x3b"
-  "\x3c\x99\xa5\x1b\xe5\x87\xd3\xa1\x17\x93\x98\x7e\x95\x14\xe3\x54"
-  "\x93\x18\x9e\x2f\x22\x1d\xee\x4c\xb3\x9e\x18\xdd\xe3\x08\x94\xcb"
-  "\x4b\x29\x87\x32\x54\xdd\x29\xa3\x61\xe9\x18\xfa\x7e\x0a\xa4\x23"
-  "\x56\x99\x0e\x2e\x47\x66\x0a\x39\x2d\xe4\x2b\xae\xb3\x2e\xf3\x35"
-  "\xc9\xb2\x1c\xe0\x77\x34\xd4\x85\xc9\x0c\xed\x4d\x94\xc3\x08\xa8"
-  "\x83\x52\x51\x16\xf1\x4a\x9d\xc3\x55\x2a\xcb\x61\x51\x5e\xce\x9c"
-  "\x93\x89\x20\x3b\xd2\xb9\x5b\x9a\xdb\xa9\x37\x4b\x4b\xe4\x7a\xa5"
-  "\x59\x8e\x7b\x98\xde\x06\x68\x67\x6a\x95\x5e\x94\xc3\x3d\x28\x0b"
-  "\xf7\x18\x78\xbe\xb4\x9d\xf5\xda\xa1\x96\xf0\x9a\x49\x21\x1b\xc4"
-  "\xcb\xf8\xbc\x15\xf2\xb6\xa0\xab\xbc\xbf\xa7\x7c\x30\x97\x37\x59"
-  "\x40\x7e\x71\x57\x79\xad\xa7\x7c\x08\x97\x3f\x1d\x0b\xf2\x89\x5d"
-  "\xe5\x1d\x23\x3d\xe4\x47\x71\xf9\x33\x46\x90\x4f\xea\x2a\xaf\xf7"
-  "\x94\xd7\x71\xf9\x0b\x71\x20\xbf\xb4\xab\x7c\xbc\xa7\xfc\x68\x2e"
-  "\xff\xa7\x06\x90\x5f\xd6\x55\x3e\xd3\x53\x7e\x0c\x97\x3f\x1b\x0f"
-  "\xf2\x2b\x3d\xe5\x4b\x98\x2c\x09\x13\xb2\x63\xb9\x6c\x75\x21\xc8"
-  "\x26\x7b\xc9\xab\x9f\xd0\x1d\x23\xe4\x43\xb9\xfc\x49\x6c\x33\x29"
-  "\x5e\xea\xca\x53\x7e\x1c\x97\xff\xcc\x00\xf2\xa9\x5e\xea\xca\x53"
-  "\x7e\x3c\x97\xff\x20\x19\xe4\x37\x79\xa9\x2b\x4f\xf9\x09\x5c\xfe"
-  "\xaf\x15\x20\x9f\xee\xa5\xec\xdd\xe5\x03\x3f\xf2\x07\xb9\x1d\x87"
-  "\xb3\xe4\xf6\xe3\x56\xee\x9e\xba\x27\x72\xdd\x75\x49\x70\x4f\xa6"
-  "\x97\x72\xf7\x94\x0f\xe3\xf2\x9f\x94\x83\x7c\x76\x57\x79\xa2\xe2"
-  "\xf2\x64\x96\x90\x9f\xc4\xe5\x2d\x58\x96\x7b\xbc\x94\x3d\x5e\x37"
-  "\x89\x76\x1a\xce\x65\xdf\xdf\x03\xb2\xfb\xbc\x94\xbb\x52\x36\x82"
-  "\xcb\x36\x1d\x03\x59\xa3\x97\x32\x57\xca\x4e\xe6\xb2\x5f\x20\x4f"
-  "\xe4\x7b\x29\x6f\xa5\xec\x14\x2e\xfb\x65\x3a\xc8\x16\x7a\x49\x6f"
-  "\x98\x42\x36\x92\xcb\x7e\x95\x0d\xb2\x45\x5e\xea\x45\x29\x3b\x95"
-  "\xcb\x36\x63\x1d\x96\x7a\xa9\x17\xa5\xec\xbd\x5c\xf6\x2a\xb6\xb5"
-  "\x32\x2f\x75\xa2\x94\x9d\x46\x03\xaf\x17\x09\x6e\x2d\xf7\x94\x05"
-  "\x0c\x98\x80\x87\xaa\x80\x0b\xa3\x68\xce\xd7\xe5\x25\x9c\xd7\xd8"
-  "\xda\x46\xb2\x0c\x55\x3b\xee\x53\xf4\x03\xd1\x34\xe7\xf3\x7d\x82"
-  "\xff\x8e\x7a\xea\xa3\x6a\x49\x29\x3b\x9d\xe6\x0d\x4d\x12\xb2\xc7"
-  "\xba\xca\xfa\x2b\x65\x67\xd0\x9c\x36\xb9\xaf\xac\xe8\x2a\xab\xed"
-  "\x94\xa5\x39\xf6\x6a\x90\x39\x5e\x2c\x78\x55\x91\xce\x59\x0a\x7d"
-  "\x33\x69\x4e\x47\x83\xd0\x67\xea\xaa\x4f\xaf\x94\x9d\x45\xf3\xfc"
-  "\x53\x84\x6c\x65\x57\xd9\x78\xa5\xec\x7d\x34\x8f\xf5\x37\x28\x5b"
-  "\xd5\x55\x36\x53\x29\x3b\x9b\xe6\xa9\xf5\x42\xb6\xda\x53\xb6\x98"
-  "\xf7\x41\x6a\x51\x4f\x73\x68\x1e\xef\x83\x40\xb6\xc6\xad\x8f\x55"
-  "\xab\x58\x1b\x2b\xe6\x72\xf7\xd3\xc0\x96\xe3\xa2\x3e\x2f\xba\xf5"
-  "\xad\x59\xaa\x91\xd8\xa7\x1c\xc6\xfa\x7c\x29\x7c\x31\xc8\x3e\x20"
-  "\xf4\xd5\x7a\xf6\x7d\x22\x7d\xb1\x70\xad\x4e\xee\x9f\xa0\xdf\xb1"
-  "\x78\xb3\x7b\x52\xef\x25\xdf\x6b\x94\xee\x31\xf1\xbe\x51\xac\x41"
-  "\x2c\x05\xb3\x73\x67\xd9\x03\x8b\x1f\xb3\x51\x87\x32\x2c\x57\x4d"
-  "\x6b\x66\xd8\x88\x84\x73\x7a\xd3\xe0\x65\xad\x16\x08\xb7\x46\xc4"
-  "\xea\x5b\xf2\xee\xa9\xb6\xa8\xce\x2f\xc0\x79\x5f\xe1\x77\xad\x85"
-  "\xec\x31\xe2\xef\xdc\x2c\x5c\x2b\x31\x5e\xd5\x71\x40\x13\x83\x6b"
-  "\x2b\x96\xc0\x79\x0e\xec\x6c\x1d\x43\xb0\x31\xe9\x4b\x24\xde\xb4"
-  "\xc5\x41\x2e\xa7\x13\x35\x5b\x8f\x5b\x0a\x8a\xa0\x1b\x92\xe3\x20"
-  "\x2d\x99\x10\xef\xca\x4b\x70\xce\xd2\x82\xeb\xc0\xe5\x6b\x16\x98"
-  "\xd2\xda\x51\xe6\x79\x6b\xf0\xda\x4c\xfa\xc2\x4f\xbf\x4c\xdd\x45"
-  "\x26\x34\x4a\x41\x8c\x17\x71\xde\x5b\x67\xb0\x66\x01\x9b\xef\xf6"
-  "\x7a\xf2\x0f\xd8\x5c\xb7\x52\xf0\x7e\x9c\xe3\x16\xe7\xba\x95\xe7"
-  "\xb9\xe5\xf1\x04\xef\x68\xc2\xf5\x45\x4b\xb7\xe8\xd9\x3c\xba\x52"
-  "\xd0\x39\x96\xbf\x2c\x5a\x43\xc3\x1f\x88\x75\xb6\x67\x67\xe2\xfa"
-  "\xd9\xa6\x5d\x8d\xe4\x92\xb8\x86\xfa\x85\xce\x85\x9e\x3a\xf1\x3e"
-  "\xeb\xc4\x2d\x7a\x28\x97\xd8\x0e\xe3\xc3\x47\x9c\xda\x87\xcb\xa9"
-  "\x71\x91\xde\x9c\x62\x21\x2c\xaf\x52\xf0\x29\x1a\xf8\xa4\xd9\x69"
-  "\x7c\xd8\x08\xe1\x5a\xb3\xad\x9d\x85\x5f\x92\x82\x75\x68\x37\x37"
-  "\x69\xe7\x67\x53\xe3\xfc\x3d\xa6\x31\xed\xa4\x5e\x0a\x66\xb6\x1a"
-  "\x86\xd3\xfd\x8b\xf4\x58\xc6\xce\xfd\x8b\xb4\x7e\x3a\x22\x35\x8d"
-  "\x98\x9f\xdd\x92\x17\x1c\x2b\xaf\x67\x27\xc7\x85\x7a\x2d\x42\x57"
-  "\x8f\xe7\xec\x95\x82\x4c\x6c\xce\xde\xbc\xe0\x3d\x16\xd5\xd8\x70"
-  "\x36\x67\xaf\x5c\x96\x3d\xd7\x91\x82\x3a\xbc\xaf\x6b\x42\x34\xb4"
-  "\x40\x93\x0c\xfa\x1b\xc0\xf6\x4e\xe7\xd8\x08\xb6\x59\x54\xc3\xeb"
-  "\xf8\xef\x10\x62\x51\x8d\x98\x2b\x7e\x07\x58\x54\xa7\xe4\x70\x9d"
-  "\x3c\x6f\xb2\xf7\x79\x9c\x35\x80\x0f\x4d\xa2\xf3\x50\x92\x3f\x8e"
-  "\x1b\x58\x7a\x82\x35\x71\xfa\xf1\x44\x75\x59\x0a\x29\x82\x38\x13"
-  "\x79\x3d\x85\x6c\x86\xa3\x46\x1c\xad\xe2\x48\x51\x86\xe1\x3d\x68"
-  "\x45\x2c\xd4\x85\x8e\xd7\x4f\xc8\xab\x6c\xbc\x84\xb8\x02\xec\xd1"
-  "\x11\x8b\x74\x4c\x6f\xc1\xda\x4c\x65\x1a\x62\x66\xce\xba\x6f\xf6"
-  "\x9c\xfb\x1f\x88\x7d\x70\xf9\x8a\xa7\x57\xae\x5a\xfd\x4c\xf2\x9a"
-  "\xb5\xcf\xa6\xac\x5b\xbf\x21\xf5\xb9\xb4\x8d\x9b\x36\x6f\xd9\x9a"
-  "\xfe\xfc\x36\xd0\xd3\xb9\xb6\x37\x3d\x34\x57\x65\x53\x13\xa8\xeb"
-  "\x1f\x61\x1c\x6c\x9d\x27\x0c\xe3\x98\x0b\xb9\x22\xe9\xbd\x8f\x47"
-  "\xcc\x3a\x18\x03\x82\xfd\x7d\x45\x1a\x95\x80\xeb\x38\x02\xfe\x55"
-  "\xe6\xa2\x79\x26\x5c\x8f\xba\x5e\x1a\x15\x77\xde\x3a\xcf\x84\xeb"
-  "\xa7\x9f\xd6\x35\x90\xf0\x30\xa2\x6a\x94\x46\x45\xe2\xf5\x92\xc9"
-  "\x84\x54\xc2\xbd\xde\x74\x86\x69\x89\xee\xb5\x10\x6a\xcd\x0f\xa1"
-  "\x57\x50\x7f\xfe\x01\xda\x60\xdd\x9e\x4c\x72\xe0\x1c\xda\x84\xf6"
-  "\xb2\x34\xaa\xe3\x34\x8c\x3a\x9c\x59\x24\xb4\xf8\x00\xad\xcf\x0e"
-  "\xa1\xf5\x2f\x1c\xa0\x57\x4a\x42\xa8\x25\x3c\x9f\x04\xb4\xe4\x8d"
-  "\x3a\x6a\x91\x46\xf9\xb3\x76\x0d\xd7\x9d\x23\x43\xca\x73\xe1\xda"
-  "\x0c\x07\xf1\x2b\x81\x73\x08\xb3\x9d\xd6\xf3\x74\xff\xee\x46\xeb"
-  "\x10\xd0\x97\x4f\xed\x29\xaa\x1c\x88\x87\xd7\x87\x6e\x62\x25\xa0"
-  "\x0b\xe2\xb3\x9a\x5b\x2f\x11\x8b\xa4\xd3\xe3\xba\xb2\x10\x9f\xc6"
-  "\x5c\x78\x85\xa0\xbe\xdf\xa6\xb5\x0e\xd9\x38\x86\x3a\x40\x96\x38"
-  "\xb7\xa7\xa8\x20\xbe\x3a\xd0\x6d\x53\xe6\x27\x72\xf5\xba\x4d\xfa"
-  "\xf5\x9b\x53\x52\xa6\x0e\x23\x91\xec\x48\x94\x6b\xa9\x6f\xc2\xf9"
-  "\xda\x5f\x3b\x40\x2b\x21\x9f\x26\xc8\x6f\xd5\x39\x68\x4d\x80\x0d"
-  "\x02\x79\x32\x82\xde\xcd\x10\x7e\x1c\x7e\x1f\x87\xb4\x57\xb1\x75"
-  "\x9a\xa5\xa9\xbf\xa0\x79\xba\x28\x48\x27\xf6\x95\x38\x8f\x39\x69"
-  "\xda\x9a\xa8\x82\x7c\xe7\x83\x5c\x95\x7e\x0c\x89\x80\xfb\x3a\x20"
-  "\x1d\x65\xf0\x1b\xe5\xdf\xc4\x7a\x04\xf9\x4a\x9e\xaf\xa9\xfb\xf1"
-  "\x1c\xca\xca\x74\x38\x84\xee\x6b\xc9\xd3\xd5\xe2\xba\x15\x6c\x2d"
-  "\x4e\x38\x87\x72\xa9\x02\x59\x63\x53\x46\xa2\x0a\xc6\xcf\xaa\x12"
-  "\x97\xce\x72\x4c\x13\xa6\x03\xc7\xe4\xef\x81\x25\xeb\xb4\x27\x91"
-  "\xe8\x56\xa2\x7a\xaf\x9e\x90\xa2\x03\xb4\x14\xf6\x22\xd8\x0b\xcf"
-  "\xc2\xb5\x77\x61\xaf\x82\xf0\x6a\x38\x9e\x85\xe3\xbb\xb0\xc3\x98"
-  "\x5e\x87\xe9\xde\xb8\x83\x36\xcc\x28\x24\x93\x50\x3f\x60\xeb\x9f"
-  "\x2e\x49\x91\xad\x98\x76\x5c\x97\x86\x8e\x1c\x9d\xe2\xb6\x96\x86"
-  "\x34\xc6\x42\xe0\x3a\x1c\x6d\xfc\xa8\xdc\xc7\xc6\xc1\xbe\x54\xfc"
-  "\x2e\x03\x99\x6a\xf1\xbb\x02\xf6\xca\xee\x77\x4f\x7d\xbe\xf6\xd0"
-  "\x98\x9e\xcb\xf6\x64\x9f\x9a\xd2\x33\xb9\x71\x0d\x44\xd2\xc7\xc3"
-  "\x9e\xee\x1e\xae\x5f\xcc\xc3\x22\x42\xf9\x79\x44\xa4\x38\x26\xc2"
-  "\x0e\xe5\x34\x19\xf4\x4f\x36\xf2\xb0\xc9\x45\x70\xac\x87\xdd\xea"
-  "\x1e\xff\x54\xb8\x7f\x6a\x36\xd6\xa7\x1d\xfa\x20\xac\x4b\x8b\x34"
-  "\x3a\x0e\xeb\x28\x97\x63\x4b\x85\xdf\xe6\x41\x58\x2c\x60\xab\xc8"
-  "\x85\x9f\xb1\xd1\xee\xf8\x19\xab\xf3\xc0\x8f\x11\xb9\x08\xda\x4b"
-  "\x76\x09\xc7\xcb\xf1\xa6\xed\x2b\xe1\x7c\x6c\x28\xe8\x39\x8e\xbe"
-  "\x22\xd0\xc1\xec\xe0\xdc\x46\x18\x83\x27\x43\x4e\x76\x21\x77\x8c"
-  "\x5d\x87\x98\xc5\xb8\x45\xbc\x3c\x2d\x90\x3e\x08\x2b\xc5\xf4\x6d"
-  "\x00\xbd\x70\x5e\x06\x72\xa5\x66\x72\x43\x4e\x1b\xbb\xe7\xe5\xb5"
-  "\x80\x47\x91\x5e\xd4\x89\xf7\x51\x57\xbe\x62\xf1\x1e\x1e\x77\xe8"
-  "\x44\x08\xc7\xb1\x3d\x7e\x77\xe7\x67\x76\x58\x08\x62\x12\x8f\x66"
-  "\x47\x0c\xb4\x25\x03\x71\xe2\x5c\xf3\x3a\x12\x03\xed\xed\xee\x4b"
-  "\x52\xa8\x34\x7d\x07\x89\x41\x7d\xc8\xdf\x90\x8f\xaa\x12\x6c\x8b"
-  "\x5c\xd7\x68\xcc\x07\xea\x3f\x0b\xa3\x29\x3c\x16\x63\x7a\xe0\xba"
-  "\x22\xde\x7c\x1c\xb3\xe7\x6e\xe3\x79\x85\xb8\xca\xe0\xfe\xa3\x98"
-  "\x77\x2c\x4f\xb8\x5e\x01\x7a\x96\xe1\x35\x5c\x9b\x52\xe4\xa7\x0c"
-  "\xbf\x77\xc4\xf2\x40\x79\x33\x8c\x5e\xd8\x3a\x1a\x92\x8e\xcd\xd5"
-  "\x0f\xfa\x8f\x62\x7d\x50\x3b\xef\xe3\x33\x1c\xd4\x41\x81\x8f\x7e"
-  "\xb5\xad\x15\x6c\x9f\x71\x1f\xba\xd7\x4f\x68\x85\xb2\x7e\xe0\xbe"
-  "\xa3\x70\x7f\x25\xda\x03\xc8\x27\x10\xa7\x06\x6d\x1d\x08\x33\x3a"
-  "\xf3\x40\xc7\x96\x56\xe6\xdf\x02\x3d\xef\x42\x5a\x8c\xa8\x07\xd2"
-  "\x53\xc9\x75\x8d\x93\x70\xce\x7d\x65\x5d\x0b\x7d\x65\x58\xe7\xac"
-  "\x3d\x6f\x63\x79\x02\xee\x1a\x77\xb0\x98\x5f\xab\x00\x99\x0a\x6a"
-  "\x37\x10\xba\x3d\x89\xaf\x57\xcd\xaf\x1d\xcb\x68\x63\xf5\x5b\xc9"
-  "\x79\x6d\xdc\x1f\x36\xee\xa4\x0d\xae\x74\x8f\x4b\x95\xd7\xa4\x12"
-  "\xe9\x3e\x86\xf1\xd1\xad\x4b\x59\x1f\x8a\x71\xe0\xfd\x42\xdf\x02"
-  "\xd4\x27\x97\xd5\x74\x48\x07\x2f\xaf\xd0\x4c\x08\x2f\x43\x2c\xb2"
-  "\x72\x03\x1e\x6d\xca\x40\x2c\x8e\xdb\x04\xf7\x1f\xcf\xc1\xf3\xad"
-  "\xec\xdc\x9f\x71\x6c\xe7\xf5\xd0\xe3\x78\x1d\x7d\x22\xb9\xcf\x02"
-  "\x96\x9c\x84\x4c\x0a\x22\x31\xb6\x2c\x96\xb7\x23\xb6\xed\x73\x55"
-  "\xa7\x1d\x84\x60\x3a\xa1\x8c\x2a\x5a\xf2\xc6\x87\x02\xf7\x2f\xc5"
-  "\xb4\x02\x5f\x1f\xa3\xbf\x4a\x22\x98\x66\xe0\x33\x91\xbe\xf1\xaf"
-  "\x8a\xba\x3f\x86\x79\xc4\xf2\x9c\xce\xb9\x0f\xae\xe9\x67\x62\xda"
-  "\x5d\xf9\x1e\x9f\xac\x2c\x63\x96\x6f\xa8\x07\xac\x2f\xac\x17\x85"
-  "\x4e\xc4\xbe\x11\x74\x1d\xe1\xe7\x1c\x1b\x58\xd6\xc6\x10\x5a\x8d"
-  "\xf2\x2e\xd9\x09\xbf\xc0\x6b\xbb\x20\xee\x19\xa9\xe8\xff\x81\xfe"
-  "\xd9\xd1\x62\x02\xbd\x47\x4c\xdb\x1c\x04\x74\x54\x60\x99\x82\x5c"
-  "\x33\xe2\x11\xce\xab\x45\x1c\x36\xe8\xcf\xa3\x60\x8f\x73\xb5\xff"
-  "\x09\x9f\xbb\xe3\x6b\x82\x67\xfb\xc7\xfa\x36\x3a\x33\x0c\x84\xe1"
-  "\x21\x8d\xe8\xaf\x49\x13\x76\x8b\xbe\x43\xd4\xf5\x84\x0f\x4e\x43"
-  "\x7b\x51\xe8\x58\xea\x51\xd7\x15\x0c\x8f\x5b\x17\xa8\x30\xcf\x70"
-  "\x6f\x85\xd0\xc3\xf2\xcc\xf0\x94\xc5\x30\x50\x4d\xb7\x42\x3e\x3b"
-  "\x71\x30\xbe\x42\xd4\x73\xb5\x47\x99\xc8\xdc\xc5\xd6\x38\x46\x4e"
-  "\x02\xbb\xfb\x07\x2d\x76\x17\x2f\x61\xdd\x3b\x59\xdd\x4f\x58\x56"
-  "\xc2\xfb\x5b\xc1\x5b\x13\xf8\xf5\x10\x37\x0c\x63\x5a\x0a\x18\x7e"
-  "\x31\x2d\x19\x4b\x31\x2d\x15\x2c\x1d\x19\x7a\x72\x4d\xd2\x07\x60"
-  "\xfc\x70\x6f\xa1\x68\xaf\x42\xd7\xf8\x14\xd4\xf5\x02\x70\x15\xa6"
-  "\xc9\x22\x8d\x69\x65\xfc\xf7\x63\x86\x83\x75\x22\xed\x55\xad\x59"
-  "\x78\xef\xd8\x65\x6d\x6a\x76\x6f\x15\xc8\x5d\x6c\xe5\x6b\xc4\x0d"
-  "\x83\xfb\xcb\xd9\x7b\x9b\x52\x78\x35\x72\x34\x7e\x8f\x0c\xbf\xdf"
-  "\xd6\x3f\x01\x58\x6d\x24\x12\xe8\xf3\x47\x8c\xca\xb8\xb8\x22\x85"
-  "\xbf\x81\xeb\xc7\x40\x59\x1f\x01\x1b\xa9\x1c\xcb\x1b\xb1\x0c\x36"
-  "\xd2\xec\x96\x3c\xfd\x45\x19\xb7\x10\x4f\x11\x96\x3d\xaf\x9f\x89"
-  "\xa3\x01\xc7\x15\x2e\x6c\x4d\x1c\x2d\xca\xb1\x1c\xca\xd1\x1f\xe2"
-  "\x3b\x28\xf2\x55\x0e\xf2\x60\x8b\x85\xef\x15\x69\x2f\x14\xf2\x73"
-  "\xe4\x7a\x10\x6d\xb5\x3a\x07\xf9\x97\xd5\xc1\xc4\x6a\x71\x6f\x99"
-  "\x88\xeb\x9c\x2c\x8b\x36\x22\x5b\xef\x19\xc2\x90\x07\x67\x40\xdd"
-  "\x33\xee\xdb\xd6\xce\xe4\x04\x37\x56\xf2\x38\xc2\x37\x33\x1c\x82"
-  "\xdd\xe3\xc2\xd1\xc4\x32\x0f\x7e\x42\x2e\x36\x9e\xcf\xe6\xeb\xe9"
-  "\x21\x96\x90\x53\x71\x9c\x04\xfa\x76\x88\xf6\x23\xd2\x1c\x36\xc2"
-  "\x1d\x2b\xe1\xcb\x01\x2b\xd1\x2e\xdd\x61\xc4\x5b\x3f\x57\xc2\x39"
-  "\xb0\x88\xdf\x13\xf6\x13\x91\xb7\x23\x3c\x6f\xe2\x1c\xcb\x6d\x17"
-  "\x2b\xb7\x60\x45\x39\x42\xb9\x4d\xda\x2d\xe4\x2b\x90\xcb\x5d\xed"
-  "\x35\xec\x84\xdc\x96\xbb\xf2\xc5\xa4\xe7\xb0\x3d\x28\xd2\x55\xe8"
-  "\xc1\x17\x15\xde\xf9\x22\x2c\x59\xe4\xb7\xd4\xa3\x6d\x94\x09\x7b"
-  "\xf7\x45\xb9\x1e\xce\xdb\xc4\xba\x86\x10\x86\xfc\x89\x71\x2b\xfb"
-  "\xa0\x62\x5e\xae\xa2\x2d\x4f\x7a\xaa\x6b\x3d\x4c\x8a\x52\xb6\x67"
-  "\xac\x6b\xe4\x04\xd4\x81\x75\xca\xec\x4a\x08\xe3\xf5\x3a\x49\x42"
-  "\x6e\x50\x72\x34\xc8\xe6\x3b\x29\xb6\x97\x49\x31\xee\x6d\x31\xac"
-  "\x48\xb4\x45\x11\x77\xb8\x0a\xea\x28\x46\x11\x6f\x99\x47\xbc\x58"
-  "\x37\x95\x6c\xfd\x19\x96\xc7\x49\x57\xe5\x3e\x0d\xe5\xe1\xde\x74"
-  "\xb8\xa7\xd6\xa3\x7f\x34\x62\xfa\x20\xae\xc5\x8c\xb3\x0e\x30\xae"
-  "\x48\x6f\xe1\xe9\xa9\x2b\x11\xfd\x04\x84\xc5\x88\xb0\x72\xd1\x97"
-  "\xc8\xb8\x59\xe8\x9e\xa6\xf0\x58\xef\xf6\x51\xd8\x62\xd9\x3e\x62"
-  "\xba\x18\x17\x85\xc7\x89\xfc\x61\x58\x34\x0f\x0b\x93\x30\x2c\x87"
-  "\x97\x43\x3e\x65\xfd\xd5\xc4\x72\xd1\x5f\x61\xfb\x52\xc3\xb9\x0e"
-  "\xdb\x18\x9e\x83\x0e\xa6\xdf\x9c\xd9\x8e\x63\x88\x42\x8b\xa4\x3f"
-  "\x86\x7c\x80\x7c\x81\xef\x1b\xb3\xe3\x22\x76\xfc\x18\x79\x07\xed"
-  "\x10\xbc\x0e\x72\x65\xc8\x45\x10\xfe\x35\xce\x35\x48\xbf\xf2\x07"
-  "\xbd\xe1\x17\xf9\xbd\x11\x43\x98\xad\xf0\x95\xc1\x4f\x0e\x93\xef"
-  "\x03\xde\x7a\x1b\xef\xc3\xfb\x65\xfe\x42\xee\x72\x20\x37\xb1\xf8"
-  "\x22\x12\x04\xc6\xd9\xb8\x41\xb6\x8b\xec\x6a\x85\x2c\xae\xcf\xc6"
-  "\x38\x2d\x22\x9f\xf3\x59\xc4\x8b\x78\x2f\xab\x3f\xe0\xca\x5d\x6d"
-  "\xf4\xd3\x92\x34\x22\x15\xdf\x40\x5e\xd4\x65\xf3\x74\x46\x58\x78"
-  "\x3e\x22\xde\x64\xf9\xe0\x9c\x6a\xe4\x69\xd1\x65\x17\xb7\xb3\x6b"
-  "\x67\x30\x2f\x78\x2d\x57\x71\x0d\xd7\x5b\x84\x6b\x6c\x6d\x3d\xcf"
-  "\xfb\x9c\xf6\xe4\x2e\xf2\x25\xed\x6c\xdc\x87\x36\x82\xe0\xde\xc9"
-  "\xcb\x78\x3a\x27\x8f\x93\x79\x17\xca\xe5\x08\x72\x2f\xbb\xb6\x5a"
-  "\xc8\x2c\x12\x47\xc6\xef\x93\x17\xf2\x72\xd5\xa9\x45\x79\x1f\xe3"
-  "\xf9\x98\xbc\x9c\x8d\xb3\xbf\x4a\x82\xb2\x9d\x3c\x57\x2e\x5b\xe5"
-  "\x6f\x6c\x3f\x10\xbf\x16\xcf\x19\xee\x77\xb0\x31\x6c\x11\xca\x60"
-  "\x9a\x78\x1f\x11\x11\xe7\x69\x53\x5f\x96\x22\x3f\xc4\x7e\x89\xdb"
-  "\xaa\x91\x7f\x10\xbe\x29\x62\x4a\xfb\x25\xf4\x0b\x53\x24\x99\x63"
-  "\x68\x8b\x81\xe0\xba\x4d\x97\xa5\x29\x43\x30\x0c\xd7\xdc\x52\xca"
-  "\x20\x3f\xfd\xae\xdd\x22\x74\x4e\xb6\xc8\xbc\x81\x5c\x72\xde\x76"
-  "\x49\xd8\x74\x53\x8c\xc5\x82\x4b\xae\x49\x53\xf6\xbb\xdb\x61\x53"
-  "\xf6\xbb\x73\x46\xe4\x1b\x9e\x9c\x01\x76\x73\x76\x4b\xde\x94\x95"
-  "\x6e\x76\x00\x84\xdd\x9c\x3b\xa6\xc4\x62\x1b\xc5\xf5\x5e\x19\x3f"
-  "\x31\x7f\xdb\x94\x36\x39\xcd\xc8\x9b\x4d\xdb\x65\xff\x45\x64\x01"
-  "\xda\x6a\x1e\xf1\x5d\x74\xe3\x4e\x8c\x4f\xd6\x07\x39\xc7\x76\x64"
-  "\x4a\x43\x7f\xcb\x94\x32\xc1\xf3\xa5\x6e\x5c\x29\xfa\x30\xe4\x49"
-  "\xf7\xbe\x4a\xf7\xa2\x7b\x5f\x15\xb9\xbb\x2b\x47\x46\x2e\xee\x79"
-  "\x5f\x15\x19\x89\xbc\x25\x73\xa4\x3b\x17\x44\x26\x16\xbb\xd9\xb2"
-  "\x53\xea\x64\x5b\xd6\xc5\xa3\x53\x52\x90\xa3\x20\xfe\x0a\x11\x37"
-  "\xf0\x44\x48\x8d\x1c\x37\x5c\x97\xce\xeb\x01\x9b\x79\xba\x58\xc0"
-  "\xd4\x51\x61\x03\xb2\xb6\xd9\x8e\xeb\xfb\x49\x11\xad\x80\xbf\x61"
-  "\x88\x33\xd3\xfa\x1b\xa4\xde\xd5\x57\x54\x36\x6d\x90\xcb\x77\xea"
-  "\x53\x4a\xbb\xf0\xf0\x01\xba\xa7\x25\x6f\xea\x6c\x65\x1e\x5f\x85"
-  "\xb0\x5c\xe1\x43\x60\x65\xcb\x74\x4d\x45\x7b\xc5\x2d\x6f\x3c\x1f"
-  "\x53\xe3\x30\x1f\x38\x26\x82\xf8\x1d\x68\xf7\xe0\x9a\xcf\x80\xc2"
-  "\xcc\x92\x4e\xcc\x8f\xb9\xd8\x96\xa5\xb4\xaf\x74\x75\xc8\x95\x62"
-  "\xec\x59\x05\xf6\x8e\x51\xe9\x8b\x59\xf8\xf0\x62\x7d\x6a\xda\x9a"
-  "\xf5\x9b\x56\xcf\xd2\xaf\x59\xbf\x66\xd3\x9a\xe5\x29\x6b\xb6\x2d"
-  "\xdf\xb4\x66\xc3\xfa\xa8\x75\xcb\x9f\x59\xf3\xb4\x7e\xeb\xf2\x8d"
-  "\xfa\x98\xf4\x88\xf4\x61\xc4\x25\xfa\x90\x7e\xf9\xc6\x8d\x9b\xd7"
-  "\xad\x5a\xa9\x5f\xbf\xe6\xe9\xe8\xb4\x55\x1b\x57\x6d\xd2\x2f\x4f"
-  "\xdb\xb0\x79\xfd\x4a\x7d\xc4\xca\xe9\x11\x31\xf7\xaf\x1c\xa6\xf4"
-  "\xa1\x85\x69\xc9\x15\xe7\x37\x0d\x0d\xb9\xdf\x10\x7f\x8d\x2a\x35"
-  "\x4d\x93\xbe\x66\x3d\xf7\xd9\xdd\xfb\xc6\x8c\x7c\x92\x0a\xd7\x03"
-  "\x4a\xf2\xb0\xac\xa7\x56\xc0\x51\x42\x39\xc8\xa7\x1e\x7e\xfb\x43"
-  "\xda\x43\x5b\xf2\xee\x4d\xb6\x48\xd3\x17\x63\x99\x41\x59\xe8\x21"
-  "\x6f\xa1\xf4\x9b\xaa\x06\xb0\xd9\x52\xf1\x3d\x83\x92\x6f\x48\x90"
-  "\x71\x0b\x91\x60\x0f\x80\x5d\xab\xd6\xa2\xaf\xeb\x5e\xe0\x82\x69"
-  "\x15\xdc\x27\x3a\x2d\xce\x3a\xe2\xd1\x8b\xd4\xf8\xe8\x45\x5e\x2f"
-  "\xd3\x1e\x94\x7d\xe1\x8f\xbd\x48\x1e\x43\x7c\x5e\x92\xa6\xb1\x67"
-  "\xd0\x2f\x00\x96\xd1\x17\xdc\x74\xf2\x47\xf1\x60\x0f\xd6\xa1\x3f"
-  "\x17\xae\x3d\x68\x53\x93\x00\x48\x97\x74\x7a\x47\x0c\x79\x0d\xe2"
-  "\xda\xa8\xa3\xb4\x25\x6f\x1a\x91\xfd\x69\x90\x07\x2d\xe4\xa5\x56"
-  "\xe4\xe3\x33\x96\x8f\x03\x34\x3c\x7f\x24\xa4\x2f\x0f\xd3\x33\x2d"
-  "\x4a\xce\x03\xa4\xbb\xd6\x22\xdd\x6b\x84\x74\x6a\x31\x5d\xde\x7c"
-  "\x7d\xe8\xef\x82\x74\x6e\x76\x6e\x81\x72\x1b\xcf\xd7\x8c\xcd\x2d"
-  "\xe6\xed\x0f\xf2\x73\xa4\x04\x7e\xe7\xdc\x20\x01\xaf\xa6\x91\x20"
-  "\x9a\x35\x81\x9e\xb3\x39\x88\x39\xb9\x96\x68\x9e\xa7\x56\xfa\x1f"
-  "\x0d\x0d\x22\x4f\xa5\xc8\x0d\xbf\x5f\x5b\x2b\x61\x9e\xa0\xaf\x08"
-  "\x28\xb9\xe1\xd3\xb7\x28\xbd\x16\x42\x6d\xf4\x90\xd2\xe6\x8a\xba"
-  "\x1b\xcb\x04\xed\xad\x26\xe8\xa7\x20\x0f\x56\x88\xdb\x20\x6c\x63"
-  "\x1b\xb5\x2f\x55\xd8\x52\xd3\x10\x67\x36\x1f\xba\xfd\x65\xdd\x54"
-  "\xcd\xd6\x5a\x16\x3e\xdb\xa8\xcd\x70\x8f\xd5\xa5\x3f\x6a\xb1\xa7"
-  "\x7e\xd4\x09\xbf\xad\x72\x3c\x7c\x1c\x1e\x85\x36\x81\x15\xb0\x6c"
-  "\xf5\x11\x5f\x78\xde\x01\x7a\xd1\x0c\xe1\xb9\x6d\x04\x6d\x05\xe8"
-  "\x9f\x99\xfe\xa3\x50\xee\x41\xa8\xff\x85\x10\x42\xb2\x41\xa6\x29"
-  "\x6f\x9a\x01\xfd\xbb\x70\x0d\xda\xbf\x2e\xde\xd3\x67\x2d\xf0\xfc"
-  "\x90\x07\x9e\xe3\xf3\xd0\x26\xcc\x07\xfd\x80\xa1\xdc\x66\x82\xf6"
-  "\x5a\xf5\xf4\x7c\x12\x89\xf1\xc0\xef\x1a\xf4\x87\xb4\xe4\x45\xeb"
-  "\xe5\xf8\x28\xe0\x3f\xc7\xc9\x7d\x30\x02\x5b\x51\xe6\xf4\x06\x9c"
-  "\x33\x8c\x9e\x06\x7e\xc7\x34\x22\xc6\xe0\x9e\x44\x19\x53\x80\xf5"
-  "\x8b\x0c\x57\x41\x24\x92\xe6\x45\xd5\x96\x8c\x04\x39\xc0\x55\x31"
-  "\xe0\x09\x71\x05\xb2\x99\x32\xa6\x00\x6b\x35\x28\x07\x69\x18\x76"
-  "\x74\x5b\xbc\x84\x1c\x59\x2f\x45\x37\x23\xc6\xe8\x3f\x3f\x5a\x4b"
-  "\x47\xfd\xb4\x96\xd7\x53\x74\xb3\xb9\x95\xd7\x81\xab\xdc\xa3\xab"
-  "\x14\xe5\x5e\x03\x38\x1e\x86\xe5\xcc\x7d\xd5\xd1\xcd\x90\xb6\x1a"
-  "\x66\x8b\xef\x84\x3a\x60\x7d\x55\xf4\x31\xbc\x5f\x94\x61\xb5\xab"
-  "\x0c\xa7\x6b\xbd\x95\xa1\x47\xd9\x49\xb8\xd3\xbc\xe9\xa1\xd8\x56"
-  "\xe0\x9e\xb9\x16\x29\xaa\xde\xd7\xb3\x02\x88\x43\x92\xf2\x89\x3f"
-  "\xc6\x51\x19\xc4\xe4\x37\x79\x8b\xc3\x13\xc7\x95\xa5\x84\xa0\x2f"
-  "\x1c\xef\x0b\x0f\xc2\x72\x9d\x7e\xc4\x6b\xfd\x3e\xed\x96\x36\xb6"
-  "\x43\xda\x2a\x5e\x1b\x09\xb8\xe1\xe9\xab\xbf\x59\xfa\xc2\xf5\xbc"
-  "\x5f\x34\x85\x21\x9e\x67\x8c\x33\xc3\xe8\x16\xc3\xc4\x79\x40\x13"
-  "\xf4\x35\x9e\xfe\x7c\xdf\xcf\x17\x66\x3c\xe5\xfe\x7c\x61\xc6\x02"
-  "\x5f\xcf\x17\x3c\xe2\x3d\x88\xf1\x3a\x4b\x12\x55\x8a\xb8\xb3\x9d"
-  "\x5e\xe2\x96\xef\x9f\x5e\xaa\x1c\xbf\xcc\xf8\x12\xd3\x70\x1e\xfa"
-  "\x25\x3a\x36\x51\x45\x41\x4f\x25\xeb\xb3\x67\x34\x70\x7b\x05\xed"
-  "\xa0\x19\x55\x28\xe3\x99\x8f\xce\xcd\x3f\xe8\x14\x1e\xda\xd8\xc9"
-  "\x90\x1f\x13\x7c\xa3\x93\x8c\x29\x95\x2f\xab\xdd\x84\x09\xf5\x72"
-  "\x12\x40\xc8\x58\x26\x4f\x61\xe3\x41\xe2\xdc\xca\x4e\xa4\x4e\xf9"
-  "\xce\xeb\xfd\xd8\xee\xe6\xe9\x65\xfa\x5a\x89\x4a\xc4\x67\x52\x48"
-  "\xcc\xbd\xc9\xdd\x94\xc8\xb7\x78\xdb\x9e\x83\x3d\x33\x11\xec\xc6"
-  "\xb1\x16\x26\x4c\xa9\x43\xe8\x97\xcf\xa9\xf2\x1c\x43\xdc\xcf\x61"
-  "\xf3\x5b\xaa\x88\x60\x82\xdf\x4a\xf6\x9a\xd8\x78\x47\x67\x90\xba"
-  "\x54\xeb\x1e\x69\xe6\x10\x76\xd0\xe0\x9f\x74\xd0\x17\x09\xd7\x43"
-  "\x5d\x97\xfd\x6c\xbb\x15\xc2\xef\xf1\xe4\x8f\x8b\xf5\x9d\x89\x5e"
-  "\x6f\xe3\x15\xbf\x27\xf0\x43\x68\xab\x57\xc9\x5b\xb1\xe9\x6b\xee"
-  "\x96\x7f\xba\xe0\x31\x6e\x87\x37\x51\x57\xf9\x8f\xab\x93\x83\x94"
-  "\xf5\xe9\xba\x3e\x31\xc9\xfd\x7c\x92\xd6\xfd\x3c\xc2\x30\x10\x49"
-  "\x37\xe1\x9f\x0c\xcb\x08\x60\x8e\xa0\xce\x40\x8d\x47\x93\xd1\x18"
-  "\x3d\x9a\x90\x6b\x13\xa9\xf1\x83\xf4\x14\x29\x82\x25\xef\xd2\xb7"
-  "\x66\x1b\xb3\x5b\x14\xe0\x04\xab\xb6\xcb\x45\xcf\x30\x3c\x1f\xaa"
-  "\x17\x61\x33\x4f\x75\x91\x67\x61\x7a\xc5\xb9\x2a\x1e\xfe\x94\xc2"
-  "\x8d\x7b\x06\x22\xad\x77\xb6\xef\xe0\xa6\xc2\xf6\x71\x67\xbb\x45"
-  "\x1b\xe5\xbd\x38\x30\x11\x3b\xe0\x3f\xda\x49\x94\x54\x5c\xa0\x22"
-  "\x80\x8a\x1f\x03\xd2\x8f\xdf\xd9\xee\x6c\x77\xb6\x3b\xdb\x9d\xed"
-  "\xce\x76\x67\xbb\x0d\x36\x95\x72\x60\xed\x0f\xfb\x5d\xe2\xa8\x1c"
-  "\xff\xa8\xc4\xae\x0c\x53\xf7\xe7\x3e\x2a\x36\x92\x19\x6f\xd2\x97"
-  "\x2e\xb3\x68\x8d\x8b\x6b\x62\x8e\xa6\x5a\xfd\xf7\x18\xaa\x22\xcb"
-  "\x93\x1b\x74\x85\x49\xb5\xb1\x15\xe9\xad\x52\xf6\xdc\xca\xf0\xb2"
-  "\x95\xf5\x41\xf9\x89\x17\x67\x1f\xdb\x64\x0b\xd8\xb7\xa0\x3a\xea"
-  "\x48\xca\x95\xd0\xa2\xa5\x75\x71\xc7\x77\x38\xd4\x59\x3f\xfa\x63"
-  "\xd8\x2f\x57\x5c\x1a\x99\xf7\x0f\x7f\x9e\xf5\xef\x69\x37\x86\xbd"
-  "\x3c\xff\xec\xbd\xff\xba\xb6\x71\xcc\xeb\x4b\x3e\x7a\xe8\xff\x6d"
-  "\x6b\x1f\xfa\xd2\x8f\xff\x73\xf2\xbf\xac\xbe\x1c\x72\xe0\x89\xbf"
-  "\xdc\xff\x1f\x5b\xbe\x09\xcc\x59\x74\x7e\xfa\x6f\xd7\x5f\x1b\x5f"
-  "\xfc\xb3\x4f\x7e\x70\x72\x97\x53\xb5\xfb\x87\xa7\x26\xfe\x62\xf9"
-  "\xa7\x23\xf6\xff\xe4\xc2\xcc\x7f\x7b\xee\xeb\xbb\xf7\x26\xbc\x3b"
-  "\xf5\xcd\x35\x5f\x8e\x3e\xf8\xe4\x87\x0f\xfe\xe1\xf9\xb6\x21\x2f"
-  "\x3e\x72\x26\xe2\x8d\x55\x9f\x07\x17\x3c\xfe\xc1\x9c\xb7\x37\x37"
-  "\x0f\x7f\x75\xe1\xb9\xe8\xb7\xd6\x5d\x1d\x77\xf8\xa9\x8f\xbf\x7f"
-  "\x62\x67\x87\xdf\x0b\x0f\x9f\x9e\xf4\xab\xa7\x3f\xbb\xe7\xb5\x7f"
-  "\x7c\xff\xbe\xdf\x6f\x6c\xfa\xde\x2b\x8f\xbe\x37\xed\x37\xcf\x7e"
-  "\x35\xf6\xd0\x4f\xff\xf6\xbf\xfe\xff\x76\xfb\x5d\xff\x67\xde\x9f"
-  "\xa6\xfc\xfa\x99\x2f\x46\xfd\xf3\x3f\xfd\xf5\x81\xff\xbb\xb5\x45"
-  "\x93\xfb\x98\x79\xc6\xef\x36\x5c\x9f\x50\xf2\xf3\xbf\xff\xef\x77"
-  "\x32\x68\x7f\xca\x8f\x48\x19\xaf\x0d\x76\xbd\xf1\xc3\xee\xcc\xbe"
-  "\xdc\x4f\x45\xad\xf3\xd3\xcc\x39\x44\xe5\x4f\x86\x4a\x7d\x1a\x27"
-  "\xf4\x35\xbf\x3e\x36\xbd\xf2\xfe\xee\x36\xfc\x1e\x6f\x26\xec\xf7"
-  "\xc1\x3e\x96\x85\xb8\x46\xfe\xe3\xbd\xde\x31\x18\x9b\x0a\xf2\xe9"
-  "\x07\x29\x19\x42\x86\x42\xc9\xf8\x93\xbb\xc9\x30\xf2\x3d\x12\x40"
-  "\x86\x93\x40\xa2\x21\x5a\x32\x82\x8c\x24\xf7\x90\x20\x12\x4c\x42"
-  "\xc8\x28\xa2\x23\xa3\xc9\x18\x48\x7d\x28\x19\xe7\x3d\xcd\x99\x24"
-  "\x5e\x07\x7f\xe0\xff\x62\x12\xcf\xce\x97\xdd\x09\x1f\xd4\x70\x93"
-  "\x08\xaf\x11\xe1\x96\x3b\xe1\x83\x1a\xae\xff\x6f\x3e\x4e\xfc\x6f"
-  "\x3d\xaa\xc0\x2c\xe0\x96\x81\x9b\x7d\xd0\xb9\x79\x86\xaa\xc4\xd6"
-  "\x79\x4e\xba\xb9\xbf\x8b\x3e\xf7\xfb\x3d\xb7\x78\xd8\x67\xf3\x9f"
-  "\x19\x84\xf0\x67\x09\x54\xb9\x39\x7c\xdd\x29\x6f\x85\xe9\xb0\x67"
-  "\xc3\x6e\x84\x1d\xfa\xcd\xc2\x12\xd8\xdf\x94\xf5\x10\x62\x6d\x25"
-  "\xe4\x06\x70\xfb\xd7\xf9\x70\xac\x26\xa4\x69\x19\x21\xcd\x16\x42"
-  "\x6c\xa5\x84\xb4\xe8\x15\x09\x0f\x70\xa5\xa8\x43\xc4\x0a\x97\x55"
-  "\xea\x7c\x45\x64\xbd\xed\x9f\x2a\x1e\x49\x34\xe8\x67\x4e\x9f\x3d"
-  "\x7d\xf6\x7d\xfa\xe8\xc5\xd1\xfa\x59\x31\x31\x0f\xce\x88\x99\x33"
-  "\x63\xd6\xfd\xfa\x59\xf7\x3d\x34\xe7\xfe\x87\x66\xc5\xea\xd7\x3d"
-  "\x9f\xb6\x66\x66\xcc\x33\xab\xf4\xeb\x57\xae\xd9\xa8\x5f\xbd\x26"
-  "\x6d\xdd\xd6\xe5\x69\xab\xba\xcb\x76\x6f\x37\xc8\x0a\x19\xd7\xc1"
-  "\x93\xa9\xac\x0d\x15\xf4\x22\x52\x6c\x2c\x91\x1e\xad\x25\x9d\x57"
-  "\x54\x46\x91\x95\x48\xb1\x77\xd9\xd6\x2d\x79\xe2\xa3\x88\x9f\x06"
-  "\xfe\xf1\x87\xcf\x44\x7c\xff\xe1\x5f\xe5\x1e\x25\xea\x78\x3d\x51"
-  "\x3f\x50\x4d\xd4\xd1\xf9\x44\x3d\xb1\x92\xa8\x83\x96\x12\xf5\xf6"
-  "\x18\xa2\x4e\x83\xb0\xe4\x6c\xa2\x5e\x5a\x46\xd4\x8f\x45\x75\x0d"
-  "\x7b\x79\x31\x0f\x3b\x61\x24\xea\xdf\x47\x12\xf5\xaf\x41\xe6\x60"
-  "\x3a\x0f\x7b\xbf\x9e\xa8\xdf\x4d\x1e\xe8\xa2\x18\x80\xad\xb7\x38"
-  "\x50\xfd\x17\x1e\xf8\x64\x82"
+static unsigned int rss_ethp_z8e_uncompressed_length = 563036 ;
+static unsigned int rss_ethp_z8e_length = 155375 ;
+static unsigned char rss_ethp_z8e[155375 + 1] = 
+  "\x78\x9c\xec\xbd\x7f\x7c\x54\xd5\xb5\x37\xbc\x32\x19\x20\x62\x64"
+  "\x26\x31\xd2\x29\x52\x39\xfc\x50\xa3\x97\x1f\x83\x22\x05\x0b\x1a"
+  "\x04\x2c\xb6\x01\xa2\xa0\x8d\x8a\x06\x14\x68\x90\x80\x01\x02\x04"
+  "\x08\x99\x61\xc0\x2b\x2a\x3f\x26\x01\x25\x42\x20\xb1\xd2\xa7\x68"
+  "\x51\x63\x8b\x2d\x78\x51\xc7\x92\xbe\x1f\x7a\x2f\xc9\xe4\xf6\xc5"
+  "\xf7\xe5\xf6\xc5\xeb\xc8\x13\x69\xca\x13\x60\x24\x03\x19\xc9\xcc"
+  "\xd9\xcf\x77\xed\x7d\x4e\x32\x33\x4c\x50\x6e\xef\xe7\x79\xff\x29"
+  "\x9f\x4f\x98\x73\xf6\x8f\xb5\xd7\x5e\x7b\xad\xb5\xd7\xde\x7b\xed"
+  "\x75\x88\xfe\x8e\x7f\xd6\xd1\xb5\x7f\x4f\xf5\x7f\xfc\xfb\xc7\xbf"
+  "\x7f\xfc\xfb\xc7\xbf\x7f\xfc\xfb\xc7\xbf\x7f\xfc\xfb\xff\xe7\xdf"
+  "\x05\x8b\x95\xfe\xe0\x25\x6a\xf7\xa4\x39\x02\xf4\x8d\xb6\x63\x9b"
+  "\x88\x20\x39\x25\x40\x69\x0e\xfe\x35\xfe\xa8\x12\xe9\x16\x2f\xa5"
+  "\x0d\xb2\x53\xfa\xc4\xdd\x44\xdb\xfb\x8a\xd6\x6d\xaf\x89\xe0\xfa"
+  "\xd7\x44\xeb\xa4\x5f\x12\xd5\x0f\x21\xda\xd6\x57\x84\x00\x67\x56"
+  "\x80\x9e\xde\xce\x70\xd6\xe3\x9d\xf3\x37\xf4\x15\x41\xa4\x97\x04"
+  "\xa8\x20\x9d\xd3\xd7\xf5\x05\xac\x2c\x22\xcf\x6b\x22\x1c\x03\x37"
+  "\x8d\xeb\x33\xcc\x49\x03\x25\x3e\x7b\x13\xe0\x30\x8c\x83\x80\xb1"
+  "\xe1\x2a\x30\xd2\x4d\xbc\x42\x16\x4a\x61\x78\x6d\x1e\x72\x84\x3c"
+  "\xbe\x9b\x50\x37\x84\x3e\x65\x73\xdd\xad\x28\x23\x3c\x94\x5a\x5f"
+  "\x1a\x21\x6d\x10\xa5\x9c\xa6\xde\x6f\xe0\xd7\x82\xdf\x57\xb9\xbf"
+  "\xeb\x55\xbd\x21\x0c\x03\x75\x53\xda\x3d\xd7\x39\x3b\xeb\x02\xb6"
+  "\x56\x4e\x56\x94\x5d\x10\xb2\xf8\x2c\xaa\xac\xfd\x3a\xa3\xac\x05"
+  "\x65\x67\x99\x65\x55\x9e\xe5\x21\x23\xef\x7a\xe4\x95\xc6\xe7\x59"
+  "\x2b\x8d\xbc\x74\xe4\x6d\x4f\xc0\xcf\xea\xbf\x1c\xa1\xd3\x74\xdd"
+  "\x7e\xe0\xa2\x1d\xc1\xa8\x70\x1d\xa3\x7c\x06\xca\xd7\xc7\xc3\x22"
+  "\x32\xf2\x32\x91\x17\x88\xcf\xfb\xd8\x69\xe4\x7d\x0f\x79\x91\xf8"
+  "\xbc\x14\xb3\x9e\xa3\xdd\xd3\xdb\x91\xa4\x9f\xdc\x7e\x8a\x6a\x9b"
+  "\xfb\xd0\x7b\x1c\xca\xb8\xb9\xcc\x4c\xcd\x4d\x3c\x56\x9c\x77\xa4"
+  "\xb6\xb3\x7d\x2e\x33\xdb\x84\x13\x40\xfd\x18\x9a\x82\x96\xbd\xcb"
+  "\xcc\xfa\x93\x34\x86\x41\x92\x86\x0c\x27\x40\xd7\x4d\x61\x38\xfc"
+  "\x8e\xe7\xfe\xdc\x6f\xe3\x59\xe3\xfe\xc5\x8e\x39\x8c\x4f\x80\xed"
+  "\x91\x46\xd4\x13\x7f\xbd\xd2\x4c\x1e\x58\xe6\x10\xba\xeb\xfb\x64"
+  "\x15\x95\x03\x0a\x75\x8f\x20\x7f\x69\x98\xb4\x7e\xe4\x3a\x45\xd7"
+  "\x3b\x80\x1f\x6d\x59\x4d\x69\xae\x62\x11\xf6\x97\xb6\x52\x63\xb0"
+  "\x95\x5c\x41\xd1\xe2\x8f\x5c\xa4\xf2\x8b\x94\xe6\x8f\x9c\xa5\xf2"
+  "\x25\xe4\xa8\x2f\xfb\x8a\x92\xf1\x97\x6e\x11\xe4\xea\xcf\x75\x9b"
+  "\xa9\xb1\xba\x99\x5c\xd5\xf1\x75\x5d\x3f\x20\x47\x03\xde\x31\x76"
+  "\x36\xc6\xa3\x5e\x8b\x50\x24\x73\x40\x61\xd9\xeb\x64\x75\x0d\x24"
+  "\x4b\xc3\x5c\x9f\x89\x4b\x80\x71\xd9\x70\x86\xd2\xde\x9c\x0f\x1e"
+  "\x3a\xc3\xf8\xde\x5e\xf8\xde\xea\xb0\xe5\x88\x23\x97\x8e\x38\x4e"
+  "\x52\xbd\x63\x3c\xd5\x97\x4e\xa2\x2d\x67\x28\xfd\x48\x78\x1c\xd5"
+  "\x5b\x1f\x84\x8c\x4d\x22\x7f\x2b\x9e\xb5\x28\xca\x84\x48\x5b\x41"
+  "\xe0\x8f\xeb\x9b\xb6\x3f\x47\x69\x01\x05\x13\xf4\xbd\xfe\xe4\xa7"
+  "\x25\x44\x4c\x5f\x7e\x4f\xd6\x8f\x65\xdf\x27\x07\xf0\x6b\x01\x2e"
+  "\x63\x4f\x51\xfa\x4d\x43\x1c\xe4\x04\xce\xbd\xfc\x55\x11\xb2\x96"
+  "\xd1\x75\xdd\xc8\x56\x96\xee\x91\x32\xde\xba\xe7\x35\xd1\xc2\x3c"
+  "\xda\xb6\x26\x1f\x72\x9a\x9e\x8b\xb6\x5b\xb9\xbd\x2d\x90\x75\xd7"
+  "\x1b\x64\x6d\x5b\x99\x9f\x52\xf3\x9a\x68\x46\x5e\xa1\x99\x07\x7e"
+  "\x6a\x46\x7e\xcb\x88\x2c\xb2\xfb\x23\x39\xf4\xc9\xe5\x16\x2b\xc3"
+  "\xe8\x13\xa2\x14\x86\x67\x2b\xa5\x54\xf4\xa7\x07\xf0\x19\x5b\x83"
+  "\xf4\xc1\x28\x87\xfa\xfb\x02\x54\x31\x9b\xeb\x8b\xef\x3d\x19\xd2"
+  "\xbf\xf7\xe4\x45\x7d\xc7\x93\x6d\x62\xc7\x93\x17\xa2\x3b\x9e\xfc"
+  "\xda\xb5\x8a\xd2\xa2\xdf\x7b\x32\xd8\x58\x2c\xc7\xc0\xde\x58\x8c"
+  "\x31\x88\x52\xda\xda\xb3\x64\x7f\x7a\x09\xc6\x3e\xf2\x39\xad\x5d"
+  "\x40\x0e\x3d\xe3\x36\xcd\x1f\xf9\x8c\x9e\x2e\x23\x81\x67\x67\xb2"
+  "\xfe\xb5\x65\xde\xbe\x4f\xc9\x50\x1a\xfa\x74\x83\x16\xb0\xde\x22"
+  "\xdb\x0d\x66\x8c\xd8\x87\xbf\xfd\xf8\xab\xc3\xdf\x01\x91\x79\xfb"
+  "\x01\xd0\xca\xd5\x67\x5d\x0a\xed\xb9\x4c\x34\x42\xa7\x94\x33\x74"
+  "\xc3\x38\xe0\x6f\xef\x86\x6e\xfd\xf5\xca\x85\x79\xb7\xbb\xa9\xbc"
+  "\xbd\xbd\x90\x58\x37\xb1\x5e\x62\x3d\x85\x76\x36\xa2\x9d\x5a\x29"
+  "\x8b\xaf\x89\x90\xc8\x5c\x98\x87\xf4\x96\xd0\x9a\xc2\x94\xe0\x9a"
+  "\x42\x4b\x5b\xe6\xc2\x19\x28\xb3\x1f\x65\x4e\x18\x34\x6c\x61\x58"
+  "\x90\x89\xe0\x0d\x11\x4a\x05\xcc\xe2\xdf\x5f\x3a\x61\xdd\xfd\x9a"
+  "\x38\x89\x72\xc7\x3b\x61\x01\x36\xe0\x80\xfe\x37\xb4\x98\x69\xa0"
+  "\x75\xf3\x66\x94\xe3\xfa\xfe\x70\x0e\xeb\xef\x80\xbf\xa8\x85\x6c"
+  "\x11\xea\x2d\x3a\x54\x7b\x28\xd3\xc2\x7a\xf6\x86\x30\xf5\x6c\xf7"
+  "\x50\x1e\xc3\xe6\x7a\xfe\xd6\x16\x42\xbd\x19\xc2\x55\x08\xfd\x46"
+  "\xd3\xda\x45\x61\x0a\x74\x7a\xf3\x11\xd4\x57\x6d\xf7\xc9\x33\x71"
+  "\xe4\x36\x78\xac\x25\x9e\xe0\x87\x23\x45\x61\xba\xa1\x8a\x52\x51"
+  "\x6f\x06\xc3\x63\x58\xe0\x83\x00\xfa\x3a\xe3\x48\x51\x90\x74\x11"
+  "\x07\x33\x60\xc0\xab\x8d\x83\x87\x74\x01\x78\xcc\x7f\xf5\xa8\x73"
+  "\x43\xad\x84\xf7\xc8\xef\x75\x86\x17\x26\xab\x26\xf1\x7d\x8c\x61"
+  "\xb4\xb3\x8e\x01\x4c\xdf\x8a\x07\xa8\x95\x6c\x69\x41\x57\x61\x6a"
+  "\x63\x19\x11\xd7\x7f\xaf\xbc\xa5\x87\x68\xcb\x4f\x65\x9e\xe3\x7c"
+  "\x7f\xe4\x02\xca\xf4\xf9\x9b\x68\x2b\x4c\xbd\xa1\x95\xac\x8c\x33"
+  "\xea\x97\x32\x9e\xb1\x63\xf9\xc8\xe4\xc7\xc6\xd3\x63\x93\x1e\x9a"
+  "\x34\x9e\xa6\x4e\x98\x38\x9e\x9c\x63\x87\x39\xef\xfe\xe1\x98\xbb"
+  "\x29\xef\x67\x8f\x8c\xa7\xbc\x69\xe3\x69\x06\xfe\xf2\x66\x4c\x7e"
+  "\x64\xd2\xe4\x19\xe3\x29\xff\xc1\x87\xf0\x36\x71\xfc\x48\xe7\x8f"
+  "\x87\xe5\x4d\x7c\x68\x32\x3d\x3c\xf3\x2e\xe7\x5d\x77\xd1\x84\xc9"
+  "\xb9\x23\x9d\x4e\xe3\x77\xa4\x93\x8b\x3c\x31\x66\xf2\x8c\x61\x79"
+  "\x4b\x9f\x2f\x79\x7e\xd8\xb4\x87\x26\x26\xcc\xb3\xd9\xd1\x4b\x3a"
+  "\xd3\x37\x24\xce\x4f\x21\x1d\xfa\x62\x0f\xc6\x1d\x7f\xad\xbe\xf2"
+  "\x53\x90\x7b\xfb\xbf\xef\xe1\xf1\x92\x7a\xd5\xc6\x73\x95\xb5\xdd"
+  "\x63\x3b\x11\xb0\x0e\x70\x30\xdd\x30\x9f\xa1\xcc\x4d\x17\x91\x77"
+  "\x87\x31\x6f\xf4\x40\x7e\x38\x3e\x3f\xe3\x18\xf2\x47\x34\x6a\x44"
+  "\x7e\xfc\x81\xd6\x21\xe8\x3f\xd0\x34\x48\x6d\xae\xfc\x1e\xe0\xe9"
+  "\x14\xb4\xd1\x0c\x79\x6c\x6a\xf7\xd8\x47\xc5\xc8\x79\x33\xc6\xa4"
+  "\x49\x5b\x4d\xa9\xe7\xc8\x7e\x43\x63\x49\x0e\xf1\xd8\xf8\x4b\x0c"
+  "\x18\x17\x3b\x61\xf4\x96\x30\x30\xde\x80\x73\xdc\x80\x53\x16\xa3"
+  "\x13\x02\x0c\x67\x0b\xf2\x0c\x58\x0f\x37\x42\x37\x40\x77\x2f\xd5"
+  "\x5d\xd9\x24\x32\x07\x14\xeb\x1d\xd9\x72\x3e\x40\xbd\x03\x26\x2f"
+  "\xa3\x7c\xa8\xbe\x18\xe5\xde\x9c\x92\x82\xb1\x4f\xc1\x3c\x85\xbe"
+  "\xd8\x7c\xe0\xe9\x90\x5e\x39\xe2\xa0\x68\xcf\x27\x95\x96\x01\x18"
+  "\x78\xaf\x1c\x71\x48\xb8\x90\xb6\x5a\xa6\xa5\x70\x1a\xc6\x39\x95"
+  "\xe5\x51\xac\x91\xe9\xa9\x48\x5f\x0e\xfc\x4e\x44\xb9\xfe\x79\x59"
+  "\xbf\x17\xd2\x1e\x45\xd9\x43\x7a\xe6\x88\x0f\xc1\x37\x9c\x06\x1b"
+  "\xa1\x6f\x16\xe0\xfd\x8b\x2e\xf2\x49\xd8\xf7\x4f\xc1\xf3\x61\xdf"
+  "\xea\x56\x3a\x5d\x4c\x96\x00\xf2\x74\x17\x60\x76\x74\xb6\x3f\x84"
+  "\xeb\xa2\x2d\x6b\x7b\x47\x21\xe6\xb7\x8c\x6c\x9e\x0b\xa3\x8c\xcf"
+  "\xf9\xce\x32\x59\xdc\x26\xcb\x34\xc6\x62\x14\xc6\xe9\xba\x76\x4f"
+  "\x46\x6d\xc2\x38\x1d\x04\x9c\x43\xa0\xfb\x09\xc0\xb0\xeb\x6d\x85"
+  "\xdc\xaf\x43\x80\x6b\x31\xe0\x9a\x30\x42\x8a\x0f\x32\x02\x09\x7c"
+  "\xf0\x1f\x80\x3d\xbe\x2b\x3f\x93\x12\xf2\x3f\x42\xfe\x03\x46\x3e"
+  "\x64\x2b\x53\x8b\xcf\xcf\x1c\x87\xfc\x07\xd1\x7e\x08\xb2\x93\x1a"
+  "\x20\xfb\xde\x3d\x6c\xfb\x75\x95\xcf\x4b\x28\x5f\x84\xf2\x3f\xc1"
+  "\xd8\x86\x58\xaf\x73\xf9\x1a\x83\x57\x51\x3e\x0d\xe5\xdd\x09\xed"
+  "\xef\x46\xf9\x19\x31\xf8\x25\xf4\xff\xc6\x42\xe4\xe7\x33\x6f\xe1"
+  "\x77\x2e\xca\xf4\x62\x79\x65\x5d\x71\xa4\x88\x6d\xc5\xcc\xa6\x84"
+  "\xf6\x99\x96\x0b\x75\x93\x46\x6d\x4c\x23\xfb\x5e\xc3\x0e\x39\xa9"
+  "\x70\xb8\xd1\x9a\xd0\xc6\x10\xd4\x59\x06\xfe\x39\x64\xf2\x46\x92"
+  "\x3a\x63\x12\xea\xe4\x4b\xde\x52\xed\x18\x63\xac\xea\x18\x7a\x28"
+  "\x16\x06\xf7\x0d\xb6\xd1\x8d\x65\x09\x7d\xcf\x47\xbb\x6b\x36\x2b"
+  "\x39\xbf\x1e\x3c\x71\x17\xd2\x1e\x02\xcc\x8f\x98\x8f\x98\xd7\xfd"
+  "\xc1\x30\xf4\xe4\x94\x74\x35\xdf\xdf\xf8\xb9\xad\x8c\xf8\x79\x18"
+  "\x3f\x33\x6c\xd1\x91\x6b\xc8\xc0\x8d\x9f\xe3\x97\xd3\xeb\x39\x9d"
+  "\x65\x4f\x74\xfc\x54\x57\x30\xb3\x52\x20\xa3\x16\xbc\x47\x8d\x36"
+  "\x26\xe0\x3d\x05\xf8\x7f\x08\x1d\x0c\x9e\x9d\xc2\xfc\x38\x0a\xe9"
+  "\x63\x8d\xfc\x91\x5c\x1e\xcf\x23\x8d\x67\xe6\xdb\x0f\x0d\xbe\x85"
+  "\x1c\xdc\x74\x87\x6c\x5b\xca\x82\xaa\xaf\x2b\xbe\x9f\x88\xbc\x9b"
+  "\xf0\xfb\x10\x7e\x19\xaf\x87\xd1\xf6\xe7\xae\x8b\xe4\x70\x45\x61"
+  "\x73\xa8\xf7\x3f\xe1\xf7\x11\xfc\x7e\x80\xdf\x19\xf8\x7d\x83\xe5"
+  "\x36\xb8\xb2\x90\x12\x78\xa6\x55\x57\xb2\xda\x4b\x8d\x61\x96\xd7"
+  "\x90\x1f\x25\xbf\xe7\xbb\xd2\x84\x4a\xb3\x28\x9a\x1b\x69\x1d\x53"
+  "\xb8\xfd\x3c\xc0\x2f\xe2\xf6\x0d\xb9\xef\xa1\xc6\x49\x95\xd1\x55"
+  "\x3d\xab\x1a\x6f\x23\x4d\x95\x4b\x89\x6d\x13\xbf\x39\xe5\x21\x21"
+  "\xf0\x3b\x94\xe9\x1a\xa0\x9b\x9c\xa0\x89\x15\xef\xac\xfb\x2c\xb2"
+  "\xbc\x84\x7b\x63\x75\xcc\x78\xc3\x16\xbf\xa9\x28\x7e\xbc\xed\x7b"
+  "\x99\x66\x3c\xde\x26\xbe\x8c\x3b\xf8\x99\xe7\xb4\x9e\x26\xcf\x80"
+  "\xb7\x5b\xa1\x1f\x43\xa9\x65\xcc\x77\x37\xd5\x05\xe8\x6d\xaf\xb4"
+  "\x83\x2a\x47\x7c\xcc\xf9\x21\xe8\x19\xe6\x8d\xd4\x62\x96\x97\x9b"
+  "\x9a\xcc\x7c\x99\x97\xb1\xb0\x89\xe1\xa7\x16\xc9\xbc\xd6\x00\xd8"
+  "\xc5\xcc\x63\xdc\x58\x8e\x53\x4b\x38\xaf\x6f\x5a\x17\xdc\x01\x5e"
+  "\x03\x6e\x2a\xdb\x0f\x6c\x07\x60\x3e\x6e\x41\x99\xa1\x01\xba\x21"
+  "\xbf\xbb\x35\x97\xf0\x0e\x70\x0f\x23\xb2\xdc\xe9\xa6\x1e\xfe\xc8"
+  "\x71\x9a\x1e\x11\xd1\x61\x6e\xba\xce\x1f\xd9\x4f\x60\x90\x0c\x7f"
+  "\xe4\x24\xdd\x49\x34\xd0\x1f\xd9\x8e\xf9\x76\x2f\xe7\x7f\x92\x4d"
+  "\x29\x29\xf8\x75\xdd\xe6\xb6\xa4\xf8\x23\x1b\x68\x88\xdb\x8a\xdf"
+  "\x22\x7a\xb0\x87\x68\xf7\x47\x72\x51\x6e\x2e\x4d\x8f\x8a\xf3\x93"
+  "\x7a\x88\x2f\x0a\xa2\x64\xcf\x7d\x41\xb8\xfc\x11\xd8\xbe\x91\x63"
+  "\x48\xd7\xc5\xf4\xe8\x37\xf8\x6b\x17\xba\x77\x80\x77\x7a\xf4\xbc"
+  "\x98\xf8\xc2\x27\x78\xff\x42\x08\x0b\x09\x7f\x64\x1c\x35\x86\x42"
+  "\x28\xe7\x12\xa2\x62\x80\xfb\xe9\x8b\x16\xea\xc0\xdc\xa9\x57\x0c"
+  "\xf0\xa2\x8f\xb5\x1d\xe8\x1f\xe6\x95\x9a\x8e\x35\xf8\xad\x1c\xb0"
+  "\x47\xbe\x7b\x07\xd4\x09\xfb\x80\xda\xe1\x58\x48\x70\x1f\xfc\x91"
+  "\x66\x2a\x80\x29\x3c\x7d\x55\x50\x30\xfe\x7d\xd6\xf1\x3a\x62\x1c"
+  "\x41\xf7\xd9\xa6\xaf\x72\x09\xe4\xa5\x89\x8c\x01\xb5\xfe\x48\x2b"
+  "\xa1\x8d\x3a\xc0\x7b\x47\xc2\xf3\x0e\x68\x42\xd9\x20\x97\x8b\x85"
+  "\xc3\x30\xb8\xec\xf4\x28\xd9\x50\xbe\xa9\x23\x63\x80\x0f\x7f\x81"
+  "\x8e\x0c\xcd\x2e\x32\xb5\x41\xc2\x93\xf5\xa9\xc0\x3c\x27\xbc\x9a"
+  "\x13\xef\x39\xed\xb0\xdb\x25\x2d\xa3\xd4\x4b\x54\x68\x4e\xf0\xc5"
+  "\x24\xf0\x16\xf0\xd5\x66\x4b\x7c\x2b\xb5\x82\x76\xd9\x0f\xed\x69"
+  "\xd5\x0f\xed\x29\x4e\x6f\xc3\x1c\x8f\x67\x77\x9b\xca\x73\xa1\xde"
+  "\x4c\x59\xcf\xab\xb9\x85\x5d\xf3\x86\x21\x33\xa0\xab\x9b\xe9\x08"
+  "\xba\xba\x99\x96\x80\xef\xf6\x97\x6e\x22\x91\xa1\x79\x81\x4f\x2d"
+  "\xea\xff\xa6\x43\xce\xbd\x9a\xaf\x5d\xc1\xfe\x04\x70\x66\x81\x2f"
+  "\x53\x01\xc3\x07\x58\x4d\x1d\x1e\x8d\xa6\xaf\x12\xe1\xe9\x91\x75"
+  "\x91\x82\x55\x94\x3a\x94\xdc\xc0\xf7\x23\xd0\x68\x2e\xfa\x59\x8f"
+  "\xdf\x49\xc8\xa7\x1b\xd1\xd6\x27\x80\xeb\xe3\xf6\xd0\x4e\x13\x60"
+  "\x36\x00\xd6\x5c\xc6\xe9\x1b\x0f\x71\xdf\x03\xdf\x48\xfc\x06\x92"
+  "\xee\x1d\xa8\xe9\xf6\x81\x76\x93\x87\x98\x7f\x14\xdd\xb6\xd3\xb4"
+  "\x90\x88\xf8\x23\xbb\x09\x3c\x66\x6f\x0c\x9d\xe4\x7c\xd8\xfa\xfb"
+  "\x31\xce\xcc\x53\x1b\xf0\xbb\x97\x98\x7f\x1a\x8b\x97\x73\xd9\x4f"
+  "\x98\x87\xa6\x15\x87\xd6\x0d\xa3\xe2\x14\xbc\xbb\x0a\x22\x69\xf4"
+  "\x74\xb1\xd5\x1d\xf5\x6a\x58\x2b\xf0\xb8\x1c\x47\x1d\xae\x57\x44"
+  "\xb6\x14\xd8\xbb\x29\x22\x62\x2b\x0d\x5a\x6f\x28\x74\x89\xc6\x50"
+  "\x2e\xca\x16\x13\xf7\x87\xf9\x88\xcb\x4f\x6d\x15\x81\xa8\x7d\x60"
+  "\x2d\xf7\x4d\xf4\x71\x53\x43\xeb\x3d\xc4\x6b\x8e\x86\xd6\xbd\xcc"
+  "\xa7\xba\xb0\x0f\x2c\x06\x8f\x76\x4c\x6d\x75\xf7\x78\xfa\x22\xa5"
+  "\x20\x2d\xda\x50\xb8\x1f\xf9\xf5\x28\x77\x4c\xf2\xed\xb4\x8b\x11"
+  "\x5b\xc4\xae\x05\x22\xde\x81\xee\x69\x17\x3b\x44\x43\xe1\x76\x7a"
+  "\xaa\xd5\x0d\x5a\xed\xa7\xa9\x67\x23\xa9\x8d\xc5\x73\x51\xa6\x1d"
+  "\xe9\x7b\x25\xff\x4f\x3d\xdb\x26\xa6\x2d\x11\xe7\xa7\x5d\xfc\x42"
+  "\x4c\x2d\x14\x9f\x14\x94\x52\x9f\xeb\xd7\x09\x9d\xe5\xe2\x58\xf3"
+  "\x7e\xba\xfe\x64\x80\x58\x26\x72\xe7\xe8\x62\xea\xd9\xf3\xe2\xe9"
+  "\x25\x4c\x9b\x71\xd4\x50\x08\xf9\x29\xdd\x0e\x7a\x0f\xc4\xf3\x61"
+  "\xb4\x3f\x09\x70\x5d\xc2\x5f\xba\x1b\x65\x7d\xb6\xa7\xce\xda\xe9"
+  "\x58\xf3\x76\x8a\x64\x68\x81\x68\x85\x16\xd4\x33\x06\xda\xf5\x8a"
+  "\x81\x9a\xc8\x18\x58\x1c\xa9\x18\xe8\x8e\x66\x0c\x04\x0f\x0c\x0c"
+  "\x62\x9c\xae\xe3\x31\xbf\x8c\x35\x38\xde\xcf\x5d\xe6\xf1\xf7\x0e"
+  "\x82\xcd\x33\x48\x83\xbe\x13\x8a\xf7\x07\x11\xaf\xa3\x45\xc6\x20"
+  "\xad\x23\x63\x90\x5d\x54\xe2\x57\xf2\xde\x20\x27\xf3\xa5\x9c\x6f"
+  "\x2a\x07\x8d\xc0\xfc\x90\x8a\xfc\x1c\xfc\xe5\xe1\x6f\x36\xd2\xea"
+  "\x00\x3f\xa3\x5d\xc1\xac\x13\xf7\x79\x61\x3b\x5e\x64\x9e\x74\x01"
+  "\x56\xd3\xf4\xe8\x18\x17\xe8\x08\x59\x19\x54\xa7\x57\x0c\xf2\x01"
+  "\x5e\x30\x2c\xf9\x7f\xd0\x79\x86\xdf\xb1\x26\x9b\xd7\xd8\x56\x51"
+  "\x31\x18\xba\x73\xf0\xd2\x76\xe6\x57\xfb\xe0\x62\xdd\x3e\xb8\x49"
+  "\x78\x07\xbb\x7f\xfa\x82\x08\x46\xbd\x83\x6b\x75\xef\x60\x6f\xa4"
+  "\x27\xec\xd2\xd2\xc3\xc4\x3a\x2a\xf2\xb1\x00\x1d\xfe\x08\x9a\xec"
+  "\x95\x3c\xe0\x2f\x85\x1c\xac\xea\xe7\x6e\x68\x05\x3f\x14\xbf\x23"
+  "\xf5\x53\x63\xe8\xb8\xa4\xab\xc8\x18\x5c\xcc\x7c\xc5\x63\xfc\x74"
+  "\x31\xb9\xd1\x96\x5b\xaf\x18\xec\x8d\x56\x00\x6e\x06\xda\xc9\xbc"
+  "\x2d\x33\x2c\x65\xf6\x36\xf0\xec\x61\xd4\xf9\x23\x29\x3e\xbf\x2d"
+  "\xe9\x3a\x90\xf5\x24\xeb\x2b\xd6\x51\xd3\x23\x61\xe6\x9b\xbf\xb2"
+  "\x6e\x53\xba\x8a\x0a\x4c\x5d\xc5\x7a\x8a\x6d\x7d\xd6\x55\xba\xa1"
+  "\xab\x74\x43\x57\xc9\x77\x3b\xf4\x8d\x77\x40\x2d\xeb\xa4\xe9\xa5"
+  "\x4a\xd7\x4c\x8f\x3a\x05\xf8\x23\x1d\x30\x6a\xd5\x78\xa0\x4c\xe5"
+  "\x80\x77\x64\x79\x49\xa7\x01\x4d\x3a\x74\x0e\xfe\x02\xba\xd2\x39"
+  "\x9a\xa1\x73\x2c\xa6\xce\x89\x62\xfe\x82\x5c\xe9\xc9\x74\x8e\x6e"
+  "\xe8\x9c\xa8\x50\x3a\x47\x37\x74\x0e\xa7\x47\x0d\x9d\x13\x4d\xa2"
+  "\x73\x74\xaf\xc6\xfd\x4d\x35\x74\x8d\x9b\x75\x0d\xf7\x57\xaf\xd0"
+  "\xbc\xba\xd2\x35\x75\xb0\xf3\x2d\xac\x6b\xa2\xa8\xa3\x9b\xba\xa6"
+  "\x5d\xd6\x6f\x62\x7d\xd3\xf1\xcf\x04\x1d\xaa\x11\xeb\x19\xa9\x53"
+  "\x22\x03\x23\xac\x53\x40\xbf\xfb\x13\x75\x0a\xe0\x05\xf0\x6c\x57"
+  "\xba\x6a\xa0\xdd\xb6\x4e\x44\x74\xbb\x16\x9c\x5e\x1a\xc2\x58\x7f"
+  "\x8e\xb5\x2e\x74\x77\x69\x09\xf4\x5d\x84\xa2\xd0\x37\xa2\xd1\xcd"
+  "\x7a\x07\x79\x51\xe8\x0b\x22\xc8\x66\x71\x04\x72\x0e\x7d\xe4\x6e"
+  "\x2c\xfe\x8c\xa2\x90\xd7\xa9\xad\x6d\xfe\xa7\x43\xd9\xf6\xa9\x67"
+  "\x45\x10\xf4\x09\x3c\x5d\xec\x86\x8e\xc9\x0e\x36\xb4\x7e\x44\xb9"
+  "\xcd\x42\xcf\x9d\x1d\xd0\x20\x6b\xee\xa9\x0b\x7c\xb6\xa7\x97\xd8"
+  "\x21\x6b\xc2\x07\xdd\xf8\x7f\x4f\x3d\x6b\xb7\xcd\x6a\xa6\x5b\x72"
+  "\xe7\x08\x3d\x0a\x59\x43\x7f\x83\x90\x33\x8c\xcd\x40\x7b\x14\xf2"
+  "\x06\x59\x2b\x8e\x24\xc8\x9a\xc8\x1c\x78\x0e\xcf\x9a\xa2\xdf\x20"
+  "\x0d\xb2\xc6\xeb\x3e\xc1\xf3\x08\xaf\xaf\x20\x0f\x1a\xef\x3d\x41"
+  "\x46\x40\x43\x25\x6f\xba\x50\xf2\xa6\x33\xfd\x2c\x86\xbc\x61\x2c"
+  "\x90\x9f\x83\xbf\x3c\xfc\x25\x97\xb7\xe2\x04\x79\x5b\x62\xc8\x5b"
+  "\x86\x92\x37\x8c\x6b\x6a\x74\x8d\x92\x39\x6e\x83\xd7\x61\x9d\x32"
+  "\x97\x39\xb8\x58\xb0\xed\x28\xf9\x47\xca\x1d\xe6\x97\xc1\xb5\x90"
+  "\x39\x2f\x64\x0e\xf0\x44\x90\xf5\x27\xf8\xf3\x3f\x79\xce\x9b\x56"
+  "\x2c\xfe\xb3\x20\xda\xcf\x0d\x99\xaa\x85\x4e\xfb\x02\xfa\xf4\x3f"
+  "\x9f\x0e\x51\x2d\x60\x15\x43\x96\xdc\x90\x29\x2f\x64\x8b\x65\xca"
+  "\x1e\x5d\xc3\x30\x6f\xb3\x77\xc2\x90\x73\x66\xbc\x4c\xa9\x9d\xeb"
+  "\xe4\xfb\x7f\xed\x9e\x5b\xa0\x19\x7f\x77\x98\xed\x15\x3c\xb7\x04"
+  "\xe8\xf7\x5e\xe3\x39\x14\xa0\x5d\x9b\xa4\xad\x03\x59\x2c\x2e\xa7"
+  "\x9b\xce\xd0\x80\x7d\xe0\x7b\xc2\x73\x3a\x9e\xf7\x4f\xbf\xe3\x13"
+  "\xd8\x14\x3b\x4a\xd1\x76\x3b\xcb\xa3\xf0\x8c\xc2\xda\x82\x72\xc0"
+  "\x8f\x69\xa2\x3d\x3b\x5d\x64\x3a\x1f\x14\x1d\x0e\xde\x63\xb2\xe1"
+  "\xbd\x0f\x68\x30\x04\xbf\x99\xbb\x2f\x51\x16\xfe\x1c\xbb\x3d\xba"
+  "\x9b\xed\x2b\x3c\x3b\xc5\x4a\x47\xef\x2d\x2b\x68\xa8\x2d\x44\x69"
+  "\x35\x1e\x3d\xdf\xb6\xce\xce\x7b\x2d\x59\xfc\x2c\x3c\x35\x75\x35"
+  "\x97\xc8\xca\x76\xa4\x9e\x81\xf6\x4a\x6d\x42\x2c\xcb\xa6\x9a\xa5"
+  "\xd0\x13\x1e\x72\xd4\x78\x44\x5d\xb4\x9d\xe9\x30\xc0\x6d\xe2\xc2"
+  "\xb8\x01\xcf\x1f\x00\xcf\xc3\x8f\xae\xca\xa1\x3f\x96\x52\xd2\x3d"
+  "\xca\x76\xcf\x80\xce\xfe\x77\x93\x1f\x31\x69\x92\x3c\x5f\xeb\x6f"
+  "\xd2\xa9\x9b\xfd\x2c\x2b\xcf\xd7\xd1\x15\x22\xb8\xf5\x39\x62\x5a"
+  "\x38\x5c\x11\xf1\x3f\x41\x47\x77\x79\x94\x7e\x30\x7d\xd5\x00\xe1"
+  "\x6f\x15\x3e\x7f\xe9\x59\xaa\x41\x7e\x79\x99\xd0\xf5\x0c\x67\xb6"
+  "\xa8\x70\x0e\x69\x5b\x21\x22\xbb\xa5\xdd\xab\xb9\x03\x74\xaf\xa6"
+  "\xc6\x62\xa0\xdc\x33\x68\xb3\x3b\x87\x00\x56\x06\xc3\x6a\x40\xfd"
+  "\x68\x85\x73\x28\xca\xed\x0b\x50\xbd\x3c\x33\x80\x3c\x53\xf1\x6a"
+  "\xba\xf9\x0c\x69\x01\x69\xdb\x7b\x9d\xe3\x58\x2f\x20\xcd\x8e\xb4"
+  "\x56\xc0\xcf\x41\x79\xac\x8f\xeb\x02\xca\xd6\xd5\x5a\xcd\x72\x78"
+  "\xf6\xf1\x73\x1c\x0f\xc9\x53\x0d\xc2\x78\x69\x5d\x87\x21\x29\x06"
+  "\x5b\x99\xff\xec\xf8\xcb\x49\x9e\xdd\xa5\xd7\x07\xba\x61\x77\x91"
+  "\x6b\x2d\xf5\xc7\xf8\x00\xbf\x81\x73\x5c\xa5\xe2\xb4\xf0\x68\xe1"
+  "\x37\x57\x87\xb1\x2e\x18\x58\x14\xa0\x17\x9b\xbb\xb7\x9f\x61\xf7"
+  "\x5c\x12\x2d\x5b\x57\x74\xd2\xf2\xcb\xe9\xab\x74\xc1\xcf\xac\x97"
+  "\x6a\x90\xce\x74\x03\x9c\x03\x26\xcd\xba\x1f\x17\xe7\x18\xb5\x0e"
+  "\x1c\x94\x25\x3c\x82\x7c\xb7\xf0\xf9\xc1\xa0\x9b\x14\x1d\x06\xd9"
+  "\xdb\xa0\x4f\x78\x7f\xb4\x06\xf4\x5e\xe6\x10\xe1\x76\xcf\x20\xd8"
+  "\xff\x77\x7a\x8d\xbd\x98\x90\x3f\x32\x99\x75\x4c\x77\xfb\x98\x69"
+  "\x5d\xf0\x07\x8f\x6a\xec\x0f\x7d\x24\x75\x54\x51\x56\xb9\xc2\x3b"
+  "\xcc\x70\x7d\xe5\x17\xa8\x19\xf9\xcb\x42\xa2\x45\x78\x8b\xd2\x78"
+  "\xad\xe1\x5b\x71\x99\xd3\xee\x01\x6f\x0b\xdf\x52\xc6\x69\xf0\x3d"
+  "\xbe\x5b\x2e\xd3\x69\xac\xf3\xb0\xc6\x0b\xaa\x7d\x99\xc1\xda\x91"
+  "\x12\x32\xf6\x7a\x06\xd5\x06\x68\x68\xbe\x89\x17\xdb\x1b\xa0\x6f"
+  "\x1a\xdb\x1f\x6c\x77\xf0\x9e\xfb\xb2\x32\x11\x66\xfb\x03\x65\x8f"
+  "\x99\x7d\xe0\xfe\x19\xfd\x0a\xc4\xf6\x0b\x38\x04\xb1\x66\x96\x34"
+  "\x58\xb6\x8a\xd2\x34\x45\xeb\x34\xee\x2f\xf7\x85\xfb\x2c\xfb\x22"
+  "\x75\x2d\xe6\x8a\xc8\x3d\x58\x83\xc9\x74\xad\xdd\x33\x18\xeb\x9f"
+  "\x3b\x43\x8a\xa7\x06\xd5\x26\xf2\x51\xe7\x38\xda\xb5\x26\xd7\x37"
+  "\x74\x8b\x4b\x17\xa7\x00\xf3\x10\xe8\x94\xca\xbf\x3a\xdb\xdc\x61"
+  "\xe6\xdf\xd1\x69\x3c\x37\xfb\xcb\x2e\xb2\xad\xcd\x65\x6f\x44\xd9"
+  "\x66\x94\x79\xcb\x28\xfb\x96\x3a\x6f\x91\xbf\xbd\xf8\x17\xf3\x59"
+  "\x03\xf0\xf0\x05\xe5\xbc\xbf\xb0\xc9\x7c\x17\x78\xc7\x6f\xa9\xa8"
+  "\x18\x9d\x96\x1c\x97\xc1\x4d\x3c\xaf\x45\x2f\x89\x56\xb4\xf3\x3d"
+  "\xe6\x29\xd7\x2a\xfa\x3e\xf8\xf2\xcb\xf2\xb5\x74\x23\xf3\x93\xc8"
+  "\x70\x4e\x52\x74\x1f\x92\x2e\x3c\xb0\x43\xa1\x55\x8b\x57\xd0\xcd"
+  "\x90\xa3\x71\x67\x68\xc8\xc0\x82\x32\x0d\xb8\x12\x6d\x3d\x47\x24"
+  "\x75\x50\x86\x33\xc7\x1f\xf9\x8a\x6a\xce\xf1\x7e\xcb\x90\x1c\x93"
+  "\x17\xf1\x9c\x7b\x35\x7d\x01\xba\xe6\xa9\xfd\x82\x21\x87\x78\x7f"
+  "\xfd\x14\x0d\xd9\xcb\xfd\xc5\x5f\x0a\xd2\x5e\x15\x97\xc4\x2c\xa1"
+  "\xe6\x36\xc0\x1c\xd2\x84\xdf\x3c\xf9\xe7\xa1\xd9\xc6\x7b\x0e\xca"
+  "\x6d\x10\x97\x74\x2e\x93\x87\xb4\x6a\xe1\x49\x61\x99\x38\x8c\xb6"
+  "\x8f\x06\x68\xfc\x18\x35\x36\x43\xb6\x33\xac\x6e\x70\xc8\xc1\xd8"
+  "\x12\xf3\xe6\x69\xba\x75\xa4\x56\x9e\x02\x3c\x6e\xed\x21\xe5\x02"
+  "\xb0\x6a\x2c\x4a\x6f\xeb\xc0\x75\x8f\x47\x2f\x84\x8e\x2e\xd4\x2b"
+  "\xc7\x6c\x94\xcf\x46\x9e\x30\xe6\xd3\xe4\xf0\x8b\xb2\x7c\xfd\x98"
+  "\xc7\x6f\xdd\xa4\xe0\x14\xa5\xf9\xfa\x9d\xe1\xf7\xcd\xfc\x1e\xb2"
+  "\x8f\xdd\xe8\xaf\xca\x41\xfb\x67\xb8\xdd\x4d\x6a\x1f\xe0\xd6\xcd"
+  "\x6d\x68\xa3\xdd\x73\xeb\xa6\x00\x0d\x9b\xab\xce\x1a\xc6\x6e\xec"
+  "\x46\xf6\xec\x2c\x3b\x2c\x73\x4a\xa6\x6f\x9f\xda\x50\x2b\xe5\xcf"
+  "\x09\x9e\xcf\x33\xf4\x06\xef\xad\xa4\x9f\xa2\xdb\x73\x1b\x1c\x92"
+  "\xbf\x2d\xc2\x72\x6b\xeb\xbb\x7a\xd0\xc2\xe7\x41\x4a\x7d\xdd\x9e"
+  "\x7b\xe5\xdf\x6d\x50\x80\xb7\x39\xf1\x37\xce\x78\x9f\x82\xbf\x59"
+  "\xf8\xdb\x8f\xf7\x71\x92\x76\xbb\xe6\xa6\x04\x90\xd7\x06\xfb\x9d"
+  "\xdf\x03\x74\x5b\xb6\xd8\x35\xc4\x02\xfb\x44\x3e\xd7\x7c\x9f\xf7"
+  "\x12\x6e\x9b\x89\x31\x38\xa9\xc6\x82\xe1\x50\x0a\x70\x63\xba\x0b"
+  "\x57\x95\x08\xd7\x97\x87\x80\xf7\x6d\x1b\xea\xab\x42\xa4\xdd\xc6"
+  "\xfd\xbf\x6d\x23\xf7\x29\x04\xfa\xf3\xef\xb2\x2a\x11\x3c\x52\x1d"
+  "\x61\xf9\x6d\x01\x2c\xc8\xff\xcf\x27\xa9\x7d\x89\x22\x27\xc3\x33"
+  "\x78\x42\x98\xfd\x57\x3a\x6d\xec\x46\x1e\x4b\xc0\xfa\x0c\x7d\xb7"
+  "\x9d\xa3\xdb\x6f\x12\x99\x63\x36\x1e\x29\x24\xda\x0d\x3d\x82\xb9"
+  "\x46\xee\x97\x43\x2f\x31\x4c\xcc\xff\xb7\x8e\x33\xcf\x51\x36\x23"
+  "\x7f\x0b\xf2\x30\xf7\x04\x1b\x0a\xc3\xc4\xb0\xa2\xdc\x3f\xd4\xff"
+  "\x48\x0f\x5a\x31\x57\x63\xcc\xc7\x6e\x2c\x2f\x86\x9e\xe9\xd4\x5b"
+  "\xb7\x1d\x5e\x7b\x56\x84\xcd\xfe\xf1\x59\x65\xbb\xe7\x76\xf0\xff"
+  "\x82\xd9\xdd\xf2\x7f\x27\xce\xd9\x0b\x8e\x0c\x51\x63\xa6\x83\x2e"
+  "\xf1\x63\x96\x5d\xa8\xc6\xeb\xf6\xea\xf8\xf1\xca\x46\x4f\x6e\x6f"
+  "\xc6\x5f\x04\xcf\xe9\xea\x3d\xf6\xef\xf6\xa6\x98\x77\x70\x47\xf6"
+  "\x4c\xe0\x83\xf9\x7f\x48\xbe\x1a\x07\x4e\x47\x3f\x98\x47\xbe\xa6"
+  "\x34\xde\x9f\xe3\x73\x4a\x4e\x67\x7e\xe6\x74\x1d\xf6\x0c\xfa\x13"
+  "\x44\x3e\xeb\xc0\xbc\xad\x3a\xc5\xe5\xfb\x37\x80\xe7\x56\x5f\x66"
+  "\xfc\x27\xc8\x3d\xc5\x75\x1b\x37\x32\x9f\xa2\x4e\xc8\x16\xd9\x08"
+  "\xfe\xcd\xce\x35\xe9\x8a\x7a\xa3\x38\x9f\x79\x12\xe9\x73\x41\x17"
+  "\xb9\x5f\x1f\xc2\xda\x2f\xb9\xad\x91\xbd\xb1\xd3\x26\xb3\x0f\xaa"
+  "\x63\x7d\xd4\x4a\x77\x6c\x87\xce\xc2\xd8\x8e\x71\xab\xb9\xe6\x8e"
+  "\x57\xf9\x1d\xba\xf2\x4b\x3c\x7b\x1b\xa0\x93\x2e\x57\x8e\xd8\xd7"
+  "\x61\xa1\x5e\x97\x2d\x94\x13\xa9\xdc\x51\x1d\xc9\xbc\xfd\x80\xbf"
+  "\xe5\x00\x35\x46\x7e\x43\xda\x73\x12\xc6\x4b\x7e\xf4\xdc\xb5\x4a"
+  "\x44\xdf\xbb\xbc\xcf\xea\x8f\x9c\xf7\x61\x6e\x1e\x70\x86\xee\x90"
+  "\xf4\x78\xe5\x14\x66\xfd\xa7\x25\x6c\x83\x3e\x3b\x4a\xb7\xcc\x17"
+  "\x91\x2d\xa7\x45\x08\xf6\x5d\xef\xcd\x97\x69\xe8\xce\xd5\xe4\xac"
+  "\xbe\x4c\x43\xf6\x5c\xa6\x6c\xf1\xd7\x6c\x4b\x35\xec\xb6\xa7\x2f"
+  "\xda\x09\x3a\x21\xbf\x4f\x31\xa5\xed\x59\x4d\x92\x47\xa2\x15\xb0"
+  "\xdf\x22\xb0\xdf\xce\x67\xb3\x6e\xec\xb4\xdf\x3a\xa4\x6d\xec\xdc"
+  "\xaf\xf8\xc8\xb9\xff\x86\x42\x4a\x49\x9f\x4d\x76\xe0\xe7\x3a\x47"
+  "\xd9\x7f\x4a\x6f\x86\xed\x88\x3e\x07\x8c\xfe\x82\x76\x27\x6d\x85"
+  "\xd4\x4b\xf6\x15\xfa\x5a\x54\x8c\x71\x77\x3b\x0f\x5b\x98\xa7\x42"
+  "\x2c\x37\xdc\x87\x2f\xf9\xac\xf4\x40\xbf\xb0\x75\x59\xb5\x08\x73"
+  "\x7a\xc9\x40\x11\x46\xfa\x51\x6e\xbb\x0e\xe9\xed\x9e\x3b\x82\x01"
+  "\xeb\xcd\xdd\xfa\x4d\x60\x9d\x64\xe8\x95\x3b\x97\x08\x8b\x9b\x79"
+  "\x34\xb8\x36\x02\xfb\xfb\x1c\xcb\xec\x9d\xc5\xd3\x8b\x44\x44\x5b"
+  "\xcc\xe7\xd6\x77\xce\xe6\x33\x75\x3e\x4b\x7b\x17\xb6\xcd\xb7\x9d"
+  "\xa3\xf3\x7c\xc1\xeb\x05\x5b\x11\x60\x56\x0e\x0a\x0a\xac\xd3\xbf"
+  "\xab\x1d\xcf\xbe\x1c\xdb\xa4\xdf\xc8\x9d\xfb\x03\xf4\x53\x2b\xe3"
+  "\xce\x67\xa6\xac\x3b\x61\x6f\xdd\x08\xbc\x5a\x42\xa0\x03\xf2\x31"
+  "\xff\xff\xf8\x84\x71\xee\x29\xfd\x51\x90\x86\xf9\xff\xa1\xfe\x9c"
+  "\x56\x32\x90\x1c\x25\x9a\x68\xe9\xce\x66\x92\x3e\x22\x16\xfa\x5e"
+  "\xbb\xe7\x9f\xb2\x4c\x38\x98\xa7\xde\x6e\xb3\x3c\xfa\x28\xd2\xb2"
+  "\x4d\x38\x28\x73\x13\xde\xc7\x74\x96\x51\x75\xa6\xc4\xd4\x79\xb4"
+  "\xcd\x72\xe7\xdb\x48\x9b\x95\x50\xa7\x28\xa1\x4e\x59\x4c\x1d\xb7"
+  "\xd1\x8e\x37\xa1\x4e\x6d\x42\x9d\xba\x24\xb8\xd5\x27\xd4\x39\x9e"
+  "\x50\xa7\x39\x09\x6e\xe1\xf8\x3a\x43\xd3\xe2\xeb\x0c\x75\xc4\xd0"
+  "\x92\xfd\x35\x9c\x48\x1b\x9a\x50\x67\x5c\x42\x9d\x5c\xf3\xbd\x3b"
+  "\x9f\x9c\x65\xbb\xc9\x01\xde\x6c\xe1\xf1\xdc\x86\xf1\x69\xdb\xb1"
+  "\xb0\xdd\xa8\xbb\xf1\xca\x7e\x0d\xad\x4e\x68\x6f\x7f\x42\x7b\x87"
+  "\xaf\xec\xd7\xd0\xa6\x84\x3a\x81\x84\x3a\xc1\x98\x3a\xb5\xaa\x9d"
+  "\x61\xd6\xf8\x3a\xc3\xb2\xe2\xeb\x0c\x1b\x72\x25\x5f\x0d\x1b\x93"
+  "\x50\x67\x4a\x42\x9d\xfc\x6f\xa1\x05\xcf\xe3\xca\x77\xaa\x2f\xdb"
+  "\xca\x0f\xc0\x46\x18\xf6\x29\xfb\x04\x6c\x45\x1b\x6f\x5e\x0e\xf7"
+  "\xe0\xf3\x0f\x9e\xaf\x8e\x94\x86\x31\xb7\x0c\xc3\xfa\xe7\x6e\xcd"
+  "\x9c\xb3\xd8\x5f\x82\x65\x5a\xd9\xd8\xc3\x36\x76\x67\x8b\x72\x3b"
+  "\xa6\x2f\x15\xb7\x75\xa4\x3f\xcf\x53\xc3\x42\x9d\x36\xb1\xf2\x2f"
+  "\x22\x05\x67\xf8\x43\x0c\x87\xdb\xaf\x51\x7e\x18\x29\x6c\x93\x1f"
+  "\x29\xe5\x3a\xc3\xb3\x63\xec\x68\x6e\x3f\x74\x60\x75\xd8\x1a\x8f"
+  "\xc7\xf0\xb4\xab\xe0\x91\x2e\xbc\x0b\xc3\x8d\xd5\x44\x7c\xc6\xdc"
+  "\x50\x0d\x1b\x08\x76\x3f\xe3\x76\x8a\x86\x7b\xa5\x4d\xb6\xf8\x32"
+  "\xf1\xb3\xbf\xec\x5e\x79\x06\xad\x6c\xd2\xe1\x47\xeb\xd1\x3e\xdb"
+  "\xee\xf5\xc5\x17\xa8\x4d\xce\xbf\x6c\xbb\x0d\xbf\x78\xa4\x2c\xc8"
+  "\x78\xf9\x4c\xff\x8c\x00\x0d\x0f\x49\x5b\xc3\xbb\x90\xe7\xfa\x20"
+  "\x9f\x19\x1d\x09\x8d\xe1\x32\xe0\xff\x61\xc7\xcc\xfe\x62\xae\x07"
+  "\x0f\x0c\xaf\xbe\x1a\xcd\xd4\x18\x8e\xe8\x1f\xcf\x93\x3d\xc0\x2b"
+  "\x23\x9c\xf1\xe3\x3e\x22\x27\x7e\xdc\x47\xe4\xc5\xf3\xa4\x05\x3c"
+  "\x39\x62\x6e\x42\x9d\x92\x84\x3a\x1b\x62\xea\x78\x8d\x76\xaa\x12"
+  "\xea\xec\x4b\xa8\x73\x30\xe6\x1d\x7d\x1c\x71\xb4\x73\xed\x23\x7d"
+  "\x7f\x46\x9c\x88\x79\xb7\x6c\x97\xfa\x73\x44\xab\x99\xc6\x7b\x48"
+  "\x7b\x5e\x53\xbe\x27\x0a\x9e\x33\x2d\x41\xde\x51\xde\xd9\x3f\x1e"
+  "\x07\xe7\xd0\x78\x1c\x9c\x9d\xf2\xbf\x55\xad\xdd\xfe\x70\x9a\x46"
+  "\x66\x49\x1e\x82\x8c\x60\xce\x9e\xce\xef\x80\x55\x85\xf2\xa0\x83"
+  "\xb3\x28\x01\x5e\x59\x02\xbc\x4d\x31\xef\x76\xbc\x57\xc7\xf4\xc1"
+  "\x9e\xea\x90\x7e\x7c\xb0\xdf\x9c\x07\xcc\x74\x5e\x53\x02\xdf\x16"
+  "\x97\x9c\x6b\x72\xd8\xa7\x2a\xf3\x14\x39\xdf\xe0\xf5\xa7\x01\x33"
+  "\x56\xfe\xc9\xe8\x57\x28\x1e\x8f\x91\xd6\x78\x3c\x46\x66\xc5\xf4"
+  "\x2b\x64\x5b\x47\x0f\xdb\x22\x8f\x3c\xce\xb6\x0f\xfb\xc2\x49\xdf"
+  "\xa6\xb5\xb0\xd9\x2e\x92\x9d\x7d\xca\x4e\x97\x50\xaa\xbf\xb4\x05"
+  "\x6b\x39\xe7\xbe\x6e\xf9\x29\xb3\x88\x0c\xbf\x3c\xac\x23\x47\x96"
+  "\x98\xfc\xa8\x57\x16\x91\x5e\xf1\x43\xd8\x6a\x23\xa1\xff\x46\x90"
+  "\xb2\x73\x47\xd7\x0a\x57\x7e\x15\xe8\x89\x75\xd1\x5d\xcb\x8d\x75"
+  "\x44\x16\xfb\x46\x41\xf7\xb4\x60\x8e\x4f\x57\x67\xe3\x23\x0f\xc7"
+  "\xf0\x75\x48\x5b\x7d\xbf\x38\x45\x77\xad\x63\x1b\x80\x65\x94\x7d"
+  "\xac\x8e\x44\x82\xc4\x6b\x6f\x7f\xe4\x8c\xb4\xdd\x90\xef\x36\xea"
+  "\x86\x63\xea\x06\x8d\xb5\x31\xcf\xa3\xd6\x11\x11\xb2\x1e\x09\x05"
+  "\x09\x70\xb2\x94\xbd\x77\xd7\xba\x23\x90\xd7\x76\xcf\x5d\x43\xcd"
+  "\x3a\xbc\x8e\xe6\x3a\xb6\x12\xb2\x0e\x2f\x23\xab\x6f\xf5\x29\x09"
+  "\xdb\x18\xfb\x16\xd8\xd2\xad\xfe\xb2\x16\xf2\x87\x4e\xf0\x5e\x97"
+  "\x55\xf9\xa9\xdc\xe5\x4e\x0d\x53\x5a\x5b\xc5\x42\xc8\xdf\x5d\xee"
+  "\x68\xc5\xc2\x30\x70\xb3\x07\x68\xe4\x5e\xd6\x37\xb1\xb4\x9b\x3c"
+  "\x39\xef\x91\xe9\x53\x87\xfd\xec\x91\x87\x66\x4e\xbe\x57\x9b\xb9"
+  "\x60\xd1\xbc\xb9\xc3\x9e\x5f\x5e\xa2\xad\x5c\xba\xa0\x64\xc1\xe2"
+  "\x9f\x6b\xce\xd2\x5b\x4b\xb5\x39\x25\xea\x37\xbb\x68\xce\xb2\x92"
+  "\xf1\xfc\x38\x54\x2b\x5e\x3a\x6f\x85\x7c\xbc\xa3\x37\xc5\x03\x59"
+  "\x50\x32\x6f\xa9\x76\xeb\xdc\xa1\xda\x83\x73\x16\x14\x2d\x5f\x3a"
+  "\x2f\x29\xac\x7b\xb5\xa5\xf3\x96\xce\x9b\x33\x57\x1b\xaf\x39\x19"
+  "\x72\x2c\xb8\x98\xf1\x74\x9a\xf3\x18\xcf\x5f\x5b\x3d\xa2\xc9\x98"
+  "\xcf\x02\x8a\x7f\xee\x9e\x79\xe5\x5c\x76\x77\x61\x3c\xcf\xdd\x5d"
+  "\x1a\xcf\x73\x77\x6f\xbc\x72\x2e\xbb\x3b\x61\xfe\xbb\x3b\x61\xfe"
+  "\xbb\xfb\xf0\x95\x73\xd9\xdd\x09\xf3\xdf\xdd\x09\xf3\xdf\xdd\x9d"
+  "\xf3\x1f\x78\x29\xb0\x5e\xea\x85\x51\x09\xf3\xdf\xa8\x84\xf9\x6f"
+  "\xd4\x90\x84\xf7\x51\x31\xef\x37\xe2\x7d\x52\xec\xfc\x88\xf7\x99"
+  "\xa6\x7c\x76\xe9\x97\x51\x85\x66\x19\xd6\xf5\xd0\xcd\xcd\x46\x59"
+  "\x77\x4c\xd9\x16\xa3\xec\xf6\x4e\xf9\xe3\xb3\x6f\xa4\xab\xf5\xfa"
+  "\xa8\x6f\x58\xa7\xb3\x1f\x1a\xcf\x4d\x90\x8f\x01\xe7\x68\xd4\x12"
+  "\x86\xc5\x3c\xcc\x7e\x89\x62\xc7\x93\xed\x35\x99\x94\xc6\x75\x6a"
+  "\x2a\xc9\x2a\x3c\x77\x6d\xc2\x2f\x21\x2d\x1d\x7f\xd0\x29\xa3\x60"
+  "\xff\xf6\x9f\xa9\xe6\x8b\x7b\x72\xa4\xcd\x8f\x3a\x0a\xfe\x3d\x72"
+  "\x5d\x03\x38\x0e\xd4\x49\xdb\xaa\xe6\xe2\x66\x3c\xa7\x33\x4f\xa3"
+  "\xbe\x55\x58\xee\xfa\x77\xfc\x12\xd2\xec\xf8\xcb\x6a\xf7\xdc\x93"
+  "\x63\xc2\xe3\x33\xf2\x64\xf2\x9f\x68\xe7\x76\xae\x07\x2d\x64\xdb"
+  "\xea\xd1\x4f\xf8\x75\xb6\xad\xef\x29\x51\x7b\x0b\x23\x8e\x0a\xcf"
+  "\x27\xf9\x35\x48\x4f\xbe\x4e\xba\x07\xf6\xdf\x3d\x85\x6a\xbf\xe5"
+  "\x1e\x8c\xff\x4f\xb7\xab\xbd\xd3\x11\x47\xa1\x6f\x2f\x9f\xa6\xd1"
+  "\x8f\xe2\xb7\x03\xbf\x63\x4d\xf8\x3e\xb9\xde\xbe\xe7\xb8\xf0\xa4"
+  "\xcc\x60\xb8\x09\xe9\xad\xd0\x6f\x97\x6d\x11\x77\xfe\x95\x79\xa3"
+  "\xb1\x86\x49\x7d\x24\x49\xba\x06\x9b\xe1\x72\x80\x46\xcf\x64\x7c"
+  "\x63\xd2\xc7\x08\x4f\x9f\x99\x5c\x3e\xc0\xed\xa1\x4e\x77\xb6\xb6"
+  "\xe9\x77\xaa\xfc\xc4\x47\x6f\x48\xe8\xc7\x37\xa7\xe9\x87\x29\xaa"
+  "\x1f\x3f\x7c\x2a\xa1\xed\xea\xe4\xfd\x18\x7d\x00\xfd\xf8\xa6\x9b"
+  "\x7e\x34\x49\xda\x5a\xd0\x17\xcb\x15\x79\x6c\xff\x7c\x23\xe9\x1e"
+  "\x97\xfe\x43\xab\x61\x0b\x85\xb0\x0e\xb3\x23\x4f\xd6\x9d\x51\xd6"
+  "\x35\x6e\x46\xb9\xa1\xb6\x2a\xca\xbb\xb2\xcd\x1f\x4e\x12\x9e\x5e"
+  "\x33\x02\xf4\xc3\x32\x09\xa7\x2b\x7d\x96\xc2\x05\x74\xb2\x30\x9d"
+  "\xd0\x1f\xd4\xeb\x6e\xbc\xcd\x75\x89\xda\x0b\xf9\x21\xe4\x7f\xf4"
+  "\x6c\x73\x2f\x73\x59\x99\x08\x9a\x74\x44\xde\xd1\x84\xbc\x70\x4c"
+  "\x5e\x73\x5c\xde\xda\xce\xf4\x88\x99\xfe\xdd\xc6\x69\xcc\xd0\x84"
+  "\x71\xc2\xf8\x8c\xf9\x28\xbe\xdf\x63\xc6\xa9\xfe\x61\x8c\xae\xa0"
+  "\xf5\x98\x7c\x8c\x51\x47\xf2\x31\x1a\x53\x92\x9c\xd7\xc6\xc8\x7d"
+  "\x34\x91\x49\xc9\xe0\xed\xc3\xd8\x75\x48\x1e\x34\xc6\xe9\xca\xf1"
+  "\x19\x73\xcc\x1c\x9f\xef\xd6\xc7\xb1\xf6\x84\x3e\x46\x4f\xd3\xd8"
+  "\xcd\xaa\xaf\x63\x3f\x8f\x87\x3d\x36\x3b\x39\x2f\x8e\xcd\x41\x3f"
+  "\xa3\xc9\xfb\x39\x76\x56\xf7\xbc\x38\xb6\x14\xfd\x89\x5e\xc9\x8b"
+  "\x63\x95\x0f\x93\xc1\x83\x09\x79\xfb\x85\x27\x69\x3b\xf5\xae\x08"
+  "\xdb\xb9\x63\x23\xbc\xbf\x14\x93\x7e\x32\x9e\xff\xd0\x07\xae\xc7"
+  "\xf4\x8b\x28\x3d\xcb\xe3\x70\x5a\x23\xcb\xb7\xf1\x64\xbb\xe7\xde"
+  "\x71\x09\xb4\x3a\x7f\x9a\xee\xfd\xa8\xcd\x92\xb2\x57\xd1\xeb\x47"
+  "\xeb\xe2\x71\xba\x37\x3f\x39\xbd\xee\x2d\x06\xbd\xce\x27\xa7\xd7"
+  "\xbd\x9b\xba\xa7\xd7\xbd\x3c\xfe\xe7\xaf\xa4\xd7\xbd\xbe\x58\x7a"
+  "\xc1\xd6\x95\xfd\x1b\xec\x00\x6f\x74\x14\x88\x1a\xee\x6b\x94\xec"
+  "\x36\xf0\x8a\xaa\xd3\xca\x75\x42\xb6\xb0\xe2\x13\xd8\x90\x69\xe7"
+  "\xe8\xde\x93\xa6\xfc\xf7\xa9\xa2\x5e\xa2\xe3\x49\xf6\x29\x4a\xe1"
+  "\x7a\xfe\xd2\xf3\x3e\x7f\xc4\x49\xbc\xfe\x88\x6f\xf7\x47\x63\x92"
+  "\xeb\x82\x1f\xe5\x81\xa6\x95\x49\xd2\x0b\x95\x3f\xd9\x8f\x6a\xe3"
+  "\x75\xc4\x8f\xdc\xf1\x63\x04\xba\xa1\x1e\x75\xdd\xc1\xb9\xea\xdf"
+  "\xd5\xc7\xec\x47\xc1\x2b\xc7\x6c\x5c\x85\x1a\xaf\x71\x4b\xe2\xf1"
+  "\x1b\x97\x96\x7c\xbc\xc6\x69\xdd\x8f\xd7\xb8\x71\xdd\x8f\xd7\xb8"
+  "\x7c\x1e\xaf\x00\x8d\xf3\xc6\xcf\x1b\xe3\x8a\xe3\xfb\x3b\x4e\xca"
+  "\xb0\xb0\xf4\xbc\x91\xdf\xbf\x6b\xbf\xcd\x3f\xd6\x71\x3c\x56\x35"
+  "\xe5\x04\x5e\x4e\x19\xc8\x38\x5e\x2b\x8c\x6e\x61\x83\x86\xde\xd5"
+  "\xc9\xcf\x5b\x79\x8d\xdb\x58\x45\xc4\xe7\xc8\xda\x2d\x6c\xbb\x8f"
+  "\x9f\xa7\x5b\xe8\x04\x9e\x2d\xa7\xe9\xfe\x91\xba\xc5\x52\xc6\x67"
+  "\x9e\xd2\x77\x5b\xee\x21\x8c\x2f\x8b\x1d\x0b\x3e\xfb\xe4\xb5\xe9"
+  "\x16\xb5\x76\xfa\xe2\x34\xdd\xd7\x43\x8d\xcb\xfd\x19\xf1\x74\x1c"
+  "\x5f\x9b\x7c\x5c\xc6\x1f\xc4\xb8\x7c\x91\x7c\x5c\xc6\x1f\xef\x7e"
+  "\x5c\xc6\x07\x31\x2e\x5f\x5c\x29\x47\xf7\xa5\x19\x72\xb4\x9e\xeb"
+  "\x68\x8b\x79\x3d\x7e\xdf\x2a\x2e\x83\x67\xc8\xc8\x7d\x73\x38\x7f"
+  "\x58\xab\x29\x47\xb2\xce\x38\xc0\x92\xed\x1b\x65\xc6\x18\x30\x62"
+  "\xe1\xce\xb6\xb5\x26\x93\x93\xfb\x4a\xb9\xec\xf0\x62\x4a\x03\x0d"
+  "\xf3\x77\x33\x8c\xa5\x44\x80\xd1\xc0\xe5\x38\x1d\x2b\xfc\x18\x39"
+  "\xb9\x6f\x9f\x59\x8e\x75\x9d\x51\xb6\x56\xb4\x17\xf2\x4e\x40\x62"
+  "\x9b\x46\xff\x7b\xc9\x79\x84\xcb\x73\xb9\x84\x32\x61\x25\x8f\xf7"
+  "\x8f\x8b\x97\xc7\xfb\xed\xf1\xfc\x09\xfa\xa3\x9e\x0e\x3d\x87\xe7"
+  "\xb9\xc0\xe1\x3b\xf3\xd7\xd5\x65\xf3\xfe\x4d\x09\xb2\x09\x1e\xc8"
+  "\x19\xa6\x78\x20\xe7\x86\x78\x5c\xef\xdf\x9b\x9c\x07\xee\x3f\xdc"
+  "\x3d\x0f\xdc\x7f\xa2\x7b\x1e\xb8\x3f\xc4\x3c\x10\xa0\x9c\xa1\xf1"
+  "\xb2\x99\x93\x1e\xdf\x77\xb4\x2b\x65\x93\x32\xae\x45\x36\x61\x0b"
+  "\xdd\xd8\x9d\x1c\xb2\x4c\xb1\x0f\x49\xcd\x65\xf3\xac\xe3\x3b\xd1"
+  "\x2c\x0d\x72\xc5\xf8\xf9\x78\x4f\x09\x3a\x7e\x0c\xd3\x70\x8f\xbc"
+  "\x1b\x98\x73\x3c\x96\x8e\x5b\xd4\xfd\x35\xd7\x69\x9a\xf0\x38\x9f"
+  "\x2b\x2b\x7a\x3e\x30\x30\xbe\xff\x39\xa1\xe4\xf4\x9c\x90\x0e\x7a"
+  "\xba\x92\xd3\x73\x42\x76\xf7\xf4\x9c\x30\x89\xef\x06\x5d\x29\x53"
+  "\x13\x66\x69\x2b\xa4\x8d\x22\xeb\x9c\xa3\x09\x1f\x7c\xb7\xf9\x69"
+  "\xc2\xf6\xf8\xf9\x69\x42\xd9\xb5\xcf\x4f\x13\x4e\x24\x9f\x9f\x26"
+  "\x04\x93\xcf\x4f\x0f\xa4\x29\x79\x78\x20\x27\x5e\x1e\x1e\xd0\xe2"
+  "\x79\x22\x27\xf4\xdf\x37\x3f\x3d\xe0\x4d\x90\x81\xad\xa7\x69\x62"
+  "\x06\x6c\x0a\xb7\x1a\xb7\x89\x9f\x25\xe0\xb8\x3f\xf9\xb8\x3d\x50"
+  "\x8f\x71\xdb\x9a\x7c\xdc\x1e\x08\x74\x3f\x6e\x0f\x44\x30\x6e\x5b"
+  "\xaf\x1c\xb7\x89\x59\xd7\x6e\x53\x4c\x9c\x12\x3f\x66\x13\x9d\xd7"
+  "\x3e\x66\x13\x37\x25\x1f\xb3\x89\x7b\x93\x8f\xd9\xc4\xc3\x6a\xcc"
+  "\x26\x86\xe2\xc7\x6c\xe2\xf1\xf8\x31\x03\xdd\xfe\xce\x31\xc3\xf8"
+  "\x1c\x53\xfe\x09\x93\x1e\xc5\xba\xbd\x57\xbb\x67\x52\x6e\x80\x26"
+  "\x67\xa9\xb5\xf5\x64\x35\x77\xa8\x31\x7c\x0f\x65\x72\xae\x9c\x07"
+  "\x26\x15\x1a\x69\x3f\xbb\x72\x1c\x26\x6d\x80\x8e\x6e\xad\x2f\x93"
+  "\x67\x5b\x6a\x0c\x99\xe6\x28\xe7\x5b\xcd\xe7\x53\x93\xa4\xff\x3a"
+  "\xc6\x58\xf8\xc3\x11\x62\xbd\x8e\xf2\x21\x86\xc3\x77\x22\x13\x60"
+  "\x35\x5d\xcb\x1c\xdf\xbd\x4f\xcd\x88\x63\xbe\xf2\xbb\x00\x6f\xf2"
+  "\x57\x8a\x57\x27\x27\xda\xbf\x35\xc8\x3b\xa4\xf8\xf4\xc7\x2f\xc4"
+  "\xe3\x30\x79\x66\x72\x3e\x9d\x5c\x84\x3e\xd4\x24\xe7\xd3\xc9\x1b"
+  "\xbb\xe7\xd3\xc9\x18\x7f\xaa\x89\x59\xfb\x64\x3e\x1d\x09\x24\xac"
+  "\x7d\x26\x1f\xb5\x85\x14\xef\x48\x9b\xa8\x62\xc4\x31\xe0\x9c\x68"
+  "\xff\x61\x6c\x1e\x5c\x64\xe0\x3c\x2f\xbe\xfe\x83\xdd\xd8\x7f\x0f"
+  "\xb2\xfd\xf7\x5e\x72\x9c\x1f\xbc\x8a\xfd\xf7\x20\xdb\x7f\xef\x5d"
+  "\x29\x5b\x0f\x1a\xf6\x5f\xb2\x35\xde\x83\x9b\x92\x8f\xff\x83\x09"
+  "\xe3\x4f\xf9\x25\x58\x0f\xcb\xfa\xf1\xe5\x8e\xc5\x96\x63\xdf\x24"
+  "\x2e\xcb\x3c\x92\xa4\x6c\x38\x11\x66\xf2\x72\x3f\xd6\xae\xe0\x3d"
+  "\xf6\xa5\x4a\xca\x7b\x3f\xce\x55\xf2\xf8\xe3\xbd\xf1\xf2\xf8\xe3"
+  "\xb9\xf1\xf2\xf8\x60\xc2\xd8\xfd\x78\x43\x7c\x3e\xf8\xe7\xbf\x4d"
+  "\xc7\xfe\x38\x94\xc0\x03\x9f\x9c\xa6\x29\x4b\x14\x0f\x4c\xf9\x53"
+  "\x3c\x1e\x53\xd2\x93\xf3\xc0\x94\x21\xe8\xff\x27\xc9\x79\x60\x4a"
+  "\x4e\xf7\x3c\x30\x85\x7d\x7c\x3e\x89\xe5\xdb\x19\x65\x39\xbd\x12"
+  "\xca\xb8\x93\xeb\xbc\x29\x55\xc9\xf7\x08\xa6\xd4\x29\x1a\x4f\x69"
+  "\x89\xa7\xf1\x94\xa3\xf1\x34\x44\x5f\xfe\x7e\x1a\x76\xc6\x26\x68"
+  "\xf7\x3c\x94\x28\xff\xfe\xd3\xf4\x90\x21\xff\x3f\x79\x3f\x1e\xc7"
+  "\x87\x66\x2a\x5c\x92\xed\x8b\x3c\xc4\xeb\x5f\x7f\x72\x5a\x3e\xb4"
+  "\x29\x79\x9f\x1f\xda\x8b\x39\xc8\xaf\x5f\x21\x4b\x0f\x1d\x46\xfa"
+  "\x0c\xde\x0f\xe5\xfd\x90\x3d\x48\x9f\x11\xa1\x34\x39\x5f\x75\xce"
+  "\x4b\x0f\x05\xd8\x17\x85\xe9\xcf\xfc\x6b\xeb\x4f\xec\x37\x64\x67"
+  "\xbc\x0a\xca\xa4\xdf\x82\x6d\x03\xf3\xfa\x20\xe6\xf5\x9f\x48\xfb"
+  "\x8f\xcf\x59\xd8\x8f\xd0\x56\x4a\x79\xfe\x50\x84\x4c\x7e\xe7\xf2"
+  "\xf1\xb0\x7f\x32\x8e\xe5\x82\xcb\x9b\x65\xd5\xbe\x99\x3b\x81\xbf"
+  "\x7f\x32\x37\xf9\x18\xff\xa4\xac\x7b\xde\xf9\x49\x95\x1a\xe7\x9f"
+  "\x1c\x8b\x1f\xe7\x9f\xd4\xe9\x9e\x3e\x33\xb9\xaf\x01\xd0\xf9\x5a"
+  "\xc6\xb8\x44\x13\xc1\x6e\xf5\xfd\xfa\x27\x4f\x14\x97\xd3\x2d\x67"
+  "\xe8\xa7\xa3\x64\x7b\x16\x11\xb6\xad\x4b\xa1\x7a\xa9\x03\x7e\xfa"
+  "\x92\xc4\x13\x65\x0a\x22\x64\x11\xeb\x17\x9e\xe0\xbc\x1a\x8f\x08"
+  "\xa3\x5c\x13\x9f\x09\xf0\x9d\x62\xf0\xc2\x8d\xa7\xe8\xa7\x53\xe3"
+  "\xea\x5b\x89\xfc\x0a\xc6\xc6\x1a\x29\x8f\x3f\xdd\x60\xee\xe9\x6e"
+  "\xc0\x7b\xf2\x7d\xdf\x9f\xee\x33\x7d\x1f\x94\xcf\xd8\x4f\xbb\x3d"
+  "\xbf\x64\x9c\xf8\xde\x0c\xe3\x74\x75\x3d\xf0\xd3\x88\xc9\xbf\xca"
+  "\xd7\x32\x37\xbd\xcb\x97\x2f\xd7\x81\x3c\xdf\x55\xf6\x06\x63\xe4"
+  "\x20\x77\x52\x2c\x1c\x15\x9f\x23\x37\xdf\xf4\xc7\xc3\xf3\xdc\x6f"
+  "\x81\x65\xe0\x93\xbb\x29\x01\x9f\x6a\xd8\x29\x25\x06\x8c\x7d\x57"
+  "\x83\xc1\x63\xae\x78\x96\xf9\x21\xd7\x77\xb5\x3d\xbf\x54\x07\xe5"
+  "\x6d\xbb\x82\xb7\x72\xa5\xbd\xc4\x30\xae\x8e\xe3\x54\x67\xdc\xda"
+  "\x42\x9e\xdd\xf3\xd9\xd6\xd4\xa8\x92\xfb\xa9\x09\x7b\x84\x53\x73"
+  "\xa5\x3f\x95\x21\xf7\x4f\x47\x12\xe5\x60\x6a\x91\x39\x47\x27\xa4"
+  "\x6f\x30\xe5\x1e\xeb\x5a\x86\x9b\xb0\xcf\x3a\x75\xaf\x92\x85\xa9"
+  "\x11\x3d\x23\x76\xbd\x36\x55\xda\x7f\xe6\x7e\x29\xf2\xf7\x26\xd4"
+  "\x4b\xd8\xff\x9b\x9a\x2b\xba\xdf\xa7\x4f\xc7\xf8\x86\xf8\x6c\x4b"
+  "\xc5\x28\x98\x36\x34\x61\xbf\x22\xb8\x45\xde\x41\xff\x0b\xe0\x4e"
+  "\x33\xf4\xde\xf4\x37\xe2\xdb\x9b\x96\xeb\x3a\x7b\xb5\xfe\x4f\xeb"
+  "\xa6\xff\xd3\xba\xfa\xbf\x58\xc2\x4d\xd8\x4b\x9c\x26\xfb\x1f\xbd"
+  "\x42\xff\x4d\x3b\x0c\xfd\x65\xd2\x0d\x36\xf7\xf4\x9b\x4c\x5b\x9d"
+  "\xf7\x0f\xba\xb7\xd5\xa7\x75\xed\xff\xc9\x7a\xd3\xba\xf6\xff\x82"
+  "\xc9\x6c\xf5\x00\xc9\xb3\xd5\xb8\xb6\xa7\x8f\xb1\x55\x27\xeb\xcb"
+  "\xf4\x6e\xf6\xff\xa6\x1b\xfb\x7f\xd3\x7d\xf1\xfa\x6c\xba\x3b\x7e"
+  "\x0c\xa7\x25\x8c\xe1\xf4\xda\xf8\x31\x9c\x96\xfb\x5f\x9d\xd7\xf0"
+  "\x4e\xa9\xa9\xa9\x96\xd4\x14\x4b\x4a\x2a\xb2\xd1\x45\xea\x95\x6a"
+  "\x4d\xed\x81\xbf\x9e\xc6\x6f\x2f\x4b\xaa\xc5\x8a\xbf\x1e\xc6\x6f"
+  "\xcf\x84\xf7\x5e\x5c\x17\x7f\x56\xe3\xb7\x47\xc2\x7b\xcf\x6f\xc9"
+  "\xef\x65\xb4\x6b\xb6\x6f\x4d\x78\xef\xf1\x2d\xf9\x3d\xff\xce\xfa"
+  "\x74\xc5\x7b\xbc\x1f\xda\x43\x8b\x57\xcc\x29\x5a\x30\x57\x9e\x17"
+  "\xcf\xd3\xe6\x3c\xfb\xec\xbc\x65\xcb\xb4\x92\xe7\xb5\x07\x26\x3c"
+  "\x72\xd7\xbd\x9a\x3a\x76\x2e\x1a\x7f\xeb\xdc\xde\x34\x75\xe5\x52"
+  "\xce\x98\x3a\xe3\xa1\x7c\x2d\xef\x81\x09\xf1\x99\x26\x18\x79\xbc"
+  "\x7c\x35\x28\x31\xf2\x97\xf3\x52\x5f\xa2\x4d\x7d\xa5\xee\x69\x66"
+  "\x3f\x5f\xb5\xe7\xf1\x58\xc6\x31\x70\xbf\xb8\xec\x12\xbe\x41\x7c"
+  "\xa6\xff\xf0\x1f\xb9\x13\xc3\x6a\xdd\x54\x3c\x9f\xef\xaf\x3c\xfc"
+  "\xa5\xf8\x38\x48\xda\x4f\xc8\x72\x8a\x9e\x1c\x58\x3f\x05\x65\xf1"
+  "\xee\x6f\x8e\x90\xe6\xa2\xb4\xd3\xf4\xe8\xa7\xc8\x4b\x11\xf7\xe9"
+  "\x48\x0b\x19\xbe\xd0\x33\xff\x5d\xa6\x7d\xec\x36\xcb\xd9\x4e\xd3"
+  "\x23\x2f\x88\x8f\x85\x7c\xe7\x7b\x42\xaa\xdc\x23\x8f\xeb\x9e\x87"
+  "\x1d\xac\x1b\xaa\x2b\xc9\xba\xa7\x92\xe8\xf5\x4c\x4a\x7b\xbd\x2f"
+  "\xc7\xea\x78\x24\xd7\x3c\x0b\x7d\x09\xef\x01\x7a\x52\xe3\xb6\xb9"
+  "\xac\x6e\x79\xf8\x01\x59\x3e\x33\xae\x7c\x59\xd7\x59\xec\x23\xb9"
+  "\x16\x94\x9b\xfe\x15\xd9\xc2\x99\xb7\xef\xf3\x97\xb9\xc9\x16\x15"
+  "\x5f\x0f\x9f\x42\x29\x8d\xb0\x84\x57\x45\x44\xc4\xb7\xf4\x0c\xb7"
+  "\xff\x27\xdb\x2a\xf1\xb5\x1f\xda\x7a\x6a\xab\x4b\x6c\x39\x4b\x56"
+  "\xc8\x75\x8a\x6f\x29\xfb\x29\x3c\x52\xb7\xe7\x1b\xb2\x82\x06\xfd"
+  "\xcf\xd0\x8c\x40\xd9\x54\x11\x75\x4d\x25\xeb\xbf\x96\xb2\xcf\xa1"
+  "\xf3\xc1\x2d\x7f\x26\xeb\xaf\x2f\xbb\x2d\x97\x85\x83\xca\x4a\x44"
+  "\x8b\xe0\x18\x3e\x21\x11\x66\x3f\xff\x63\xb3\xa3\x5c\x66\x74\xbb"
+  "\xcb\x41\x8d\x25\x21\x5a\x7b\x52\x84\x37\xfe\x59\xdd\x0f\x68\x68"
+  "\x0d\xb1\x0f\x63\xda\xda\xa9\x94\x7a\x3a\x9f\x2c\x0d\x85\x55\xe4"
+  "\x9f\x15\xa2\xb2\x93\xa2\xe5\xd8\xec\xaf\xa8\xb1\xb0\x8e\x0a\x4e"
+  "\x90\xe5\x58\xf3\xe7\x24\xe3\xd0\x54\xee\xf0\x96\x5f\x24\xc7\xda"
+  "\x05\x9c\x76\x91\x56\xaf\xa5\x1b\x56\x7f\x46\x36\x7f\xcb\x09\xb4"
+  "\x73\x96\x9e\x38\x4e\x29\x80\x67\x59\xf3\x39\x39\xd6\x3c\xce\xbe"
+  "\xbe\x39\x54\x5d\x4e\x0e\xe1\xca\x4e\xbf\xec\xca\xb6\x5f\x16\xd9"
+  "\x99\xed\xae\xec\xac\xc6\x62\x94\x6f\xfe\x88\xfa\x9c\xa0\xac\x8f"
+  "\xcf\x9c\xb0\x54\x5d\xa0\xfe\xda\x34\x1e\xff\x19\x27\xab\x2f\xa0"
+  "\x7c\xe5\xa2\x1c\x1d\x75\x63\xeb\x44\x32\x16\xe5\xfb\xf3\xc3\xa4"
+  "\x03\x56\xd5\x65\xea\x5f\x7d\x99\x1c\x7a\xc5\xa2\x1c\xa6\x45\x47"
+  "\xe5\x88\x7d\xd0\x85\xbd\xde\x7b\xe6\xa0\xd5\x7f\xac\x95\x1a\x42"
+  "\x97\xa9\x91\xfe\x42\xfe\xd2\xbf\xfa\x7e\xfd\xcc\xc1\x1e\x3a\x98"
+  "\xdf\xb7\xba\x19\xf0\x15\xcf\xb8\x1a\xf8\xbe\xb2\x9b\xb6\x96\x53"
+  "\x7a\xf1\x6a\xea\x75\x06\xe9\x6a\x4d\x3f\xa8\xce\x1f\xf9\xab\x6f"
+  "\xb5\xf4\xc3\x7d\x52\x2b\x6f\xa0\xd4\xc6\x50\x15\xfb\x7b\x5a\xa2"
+  "\x99\x3b\xbc\xfe\x50\x13\xf9\x8b\xbf\xf0\xe9\xf6\x1d\xa5\x9b\x74"
+  "\x4a\x7b\xe7\x52\x93\xc5\x6f\xbd\x44\xfe\xfc\x10\x7d\x82\xb6\x45"
+  "\xe5\x0e\x3e\xf3\xcc\x69\x0c\x85\xf9\x9e\x93\x53\xb4\x39\x7a\x6f"
+  "\x5d\x4a\x43\xf7\x5c\xa0\x21\xbb\x2f\x50\xb6\x68\xcf\xb6\xb0\x6f"
+  "\x2d\xdf\x4f\xdd\x8d\xdf\xf4\x66\x4a\x43\x7f\x95\x1f\x76\x86\xe1"
+  "\x63\xdb\x91\x4d\x35\x97\xbb\x7c\x6c\x2f\xb7\x75\xf9\xd8\x82\x97"
+  "\xf2\xd8\xcf\xf6\x14\x3d\x92\xc6\xfc\xbc\xf5\x1c\x59\xd7\x9f\x23"
+  "\x1a\xee\xb6\x90\xf6\x0c\xdf\xab\x78\xf4\x03\xff\xdc\xb3\xf2\xf9"
+  "\x14\x3d\x5a\x84\xdf\x74\xfc\xa5\x20\x5d\xee\x67\x37\x1b\x7c\x8b"
+  "\x34\x0b\xd2\x1e\xc5\x6f\x2a\x7e\xa7\xba\xaa\x45\x50\x78\x47\xb2"
+  "\xcf\x69\x6f\xe6\x5f\xe5\xcf\x3b\x92\xda\x3d\x8f\xc2\xfe\x79\xae"
+  "\xc8\xe4\x63\xa5\xd3\x1f\xc9\xfb\xe4\xf4\x59\x8e\x0b\x15\x94\xf8"
+  "\x74\x14\xa6\x70\x8c\x28\x23\x9d\x71\x78\x87\xdb\x45\xfb\x5e\xfc"
+  "\xda\xf0\xc7\x72\x39\xc4\xac\xdb\xd6\x51\xc8\x6d\xfe\x12\xe9\xc2"
+  "\x4c\x47\x7f\xad\x9c\xf7\xdb\xd3\x67\x2d\xaa\x4c\xb6\x05\x30\xc3"
+  "\x06\x7c\xc8\xfa\xc3\x21\x96\xe9\x36\x8b\x4d\x1c\x99\x3b\x8a\xaa"
+  "\xfb\x8a\xa6\xdd\xaf\x89\x7a\x25\x6b\x8f\xa2\xed\x85\x75\x8c\x23"
+  "\xe6\xed\xfa\x4d\xc8\x3b\x82\x55\x2c\xd3\xa5\x7e\x36\xfb\x8f\x3d"
+  "\xc6\x71\xa3\x86\xc4\xf6\x41\x78\xa6\x87\x79\xee\x7c\xb7\xdc\xd7"
+  "\x43\x58\xf2\xc2\x8d\x81\x56\xfa\xf5\xe5\x96\x1e\xae\x3f\x91\xc5"
+  "\x1f\x39\x45\x23\xb2\xc8\xc1\xf6\x5f\xcd\x6b\x22\x80\xdf\x16\xf6"
+  "\xe7\x04\x9f\xfc\xe0\x0c\x3d\xf6\xe8\x3f\x65\x51\xd6\xbf\x95\x92"
+  "\xa1\x8f\x1e\x5b\xd4\xa5\x8f\x9e\xb8\xd8\xd0\x7c\x30\x46\x17\x3d"
+  "\xf1\xcb\x2b\x75\xd1\xe3\x6f\x28\x5d\x24\x22\x4a\xf7\x44\x03\x46"
+  "\xfa\xe6\x84\x74\xc3\x2f\xe4\xf1\x25\x09\xe9\x61\x23\xfd\xa9\x84"
+  "\xf4\xa0\x4a\xcf\xdf\x6d\xea\xba\x46\xc6\x63\x25\xeb\xba\xfc\x75"
+  "\xac\xeb\x1a\xe7\x1a\xba\x4e\xfa\x18\xe6\xcf\x13\xbf\x70\x13\xdf"
+  "\x59\xc2\xf3\x78\xc6\x5f\x7c\x4c\x26\xee\xd7\x9d\xa6\x9f\x45\x39"
+  "\xcd\xfb\x17\xb2\xe2\x4f\xea\x39\xe1\x79\xb8\x80\xf5\x1c\xeb\x38"
+  "\xf6\x3b\xd9\xd5\x57\x9c\xd8\xf5\x9a\x38\x5e\xfd\x9a\x38\xd6\xee"
+  "\xf9\x59\x91\xa9\xef\x5e\x41\xda\x26\xa4\xbd\x82\x7c\xd6\x7b\x4c"
+  "\x93\x86\xfc\x83\x1c\xc7\xa1\x19\x7c\x3c\xc9\x96\x42\xc5\x5b\xc0"
+  "\xf3\x7c\xbf\x70\x03\xe8\xeb\x2f\x09\xc9\xbb\xa9\x32\x9e\x92\xc5"
+  "\x09\x1d\xd5\xcc\xf2\xd6\x77\x3d\xe4\xcb\x5f\xfa\x15\x95\x87\xc4"
+  "\x19\xbe\x67\xc7\x38\x14\xac\xfa\x09\xdf\x15\x4d\xa9\x87\x75\xc1"
+  "\x7e\xe0\xec\xaf\x02\xbd\x6b\xf5\x02\x27\x15\x23\xe5\x67\x58\xff"
+  "\xd7\x18\xf7\x98\x9e\xd4\x38\xfe\xd8\x29\xfa\xd9\x18\xac\xef\xc2"
+  "\xdc\x37\x5b\xd4\x4d\x7c\xef\x05\x32\xca\x6b\xbc\xc2\x5d\xf8\xf3"
+  "\x9a\x77\x5f\x38\x16\x1d\xca\xf8\x4f\x84\x89\x71\x0e\xd0\xcf\x36"
+  "\x34\x94\x1d\xe4\xfa\xd9\x4c\x1b\xe1\x71\x99\x30\x52\xe4\xdd\x19"
+  "\x0f\xa5\xf1\xdd\x99\x00\xe5\x3b\x94\x4d\x33\x62\x5f\xc3\xac\x20"
+  "\xb1\x9e\xf7\xb7\x00\x46\xd9\x29\x05\x03\xb0\x04\xf4\x7e\x5c\x9e"
+  "\x01\xff\x86\xb5\xe2\xeb\x53\xf4\x58\x88\xc7\x8b\xef\x41\xf2\xf9"
+  "\x1a\xe8\x92\xce\xbe\xf1\xca\xf6\xfc\xd9\xda\x9a\xbf\x10\x19\x77"
+  "\x39\xc1\x6f\x3f\x2b\xe3\x7b\x4a\x7c\x7f\x53\xde\xdd\xb4\x8c\x22"
+  "\xb1\x32\x3b\xbd\xf3\xfe\xe6\xff\x81\xbb\x9b\xa0\xbf\x63\x8f\x45"
+  "\xd4\x01\xff\x32\xbe\xbf\x09\xfc\x4f\x32\x1f\x1a\x7d\x72\xbf\xfa"
+  "\x04\xd3\xfc\xb1\x7a\x4e\xc3\x5a\xf1\xa8\x39\xfe\xdc\x5f\xee\x0b"
+  "\xf2\xf6\x29\x9b\x50\x34\x05\xe8\x71\x37\xe7\x23\x6d\x3b\x97\x1f"
+  "\x01\x3d\xe6\x9f\x1b\xa5\xf7\x4e\x47\x2d\x5b\x57\x93\x55\xe9\xb4"
+  "\x27\x5e\xe7\xfa\x4a\xa7\x3d\x91\xd7\xa5\xd3\x9e\x98\xac\x74\x9a"
+  "\xa2\xb1\xd2\x69\x4f\x8c\x55\x3a\xed\x89\x91\xf2\x1c\x0c\x3a\x8d"
+  "\xf3\x58\xaf\x99\x3a\x6d\x77\x5f\x71\x94\x75\x47\xbb\xe7\x09\xcd"
+  "\xd4\x6d\x9b\x91\xc6\xba\x83\x71\x54\x7a\x2a\xbf\x54\xfc\x7f\xd9"
+  "\xa4\xfc\x0c\xf8\xb9\x90\xef\x2b\xb4\x18\xcf\x18\x97\x27\x2a\x94"
+  "\x8e\x7b\xa2\xa4\x4b\xc7\x3d\x1e\xee\xaa\xcb\x3a\xee\x89\x97\x94"
+  "\x8e\x53\xe9\x35\x4f\xb0\x8e\xcb\x2f\x65\x1a\x18\xf0\x2d\xbc\x67"
+  "\x67\x94\x67\x3a\xba\x63\x75\x5c\xbc\x7c\x3d\x71\xcc\xd4\x71\xac"
+  "\xdb\xf0\x0e\x1b\xa4\xf7\x51\x29\x6f\x28\xb7\x1d\x34\x37\xe5\x8e"
+  "\xc7\x80\xfb\xcc\x71\xc6\x98\x6e\x13\xcf\x52\x2f\xe3\xae\x90\xd1"
+  "\xef\x27\x1d\xa6\xaf\x63\x80\x9e\xd0\x92\xd9\xcd\xa6\x9d\x06\x7e"
+  "\x1c\x10\xe5\x38\x1d\x6e\xcc\xa5\x55\xc2\xdd\x18\x39\x4e\x4f\x97"
+  "\x90\x45\x4f\x5d\xf8\x25\x8f\x2d\xd6\x19\x3d\xf9\x97\x75\x0f\xe6"
+  "\xd0\xa7\x0a\x42\xd4\x13\x6b\xf3\x2f\xb7\x5a\x90\x57\x4a\x3f\x8a"
+  "\xc9\x5b\xc5\xed\xc4\xd4\x1b\x16\x93\x27\xe3\x51\x0e\x3b\xc7\x31"
+  "\xe6\x9e\xcc\xe9\x6e\xed\x7f\x8d\xb8\xfc\xad\x7b\x5c\x66\xf5\xe8"
+  "\x1e\x97\x59\xd2\x0e\x18\xd6\x4a\x29\x58\x9b\x65\x9c\xa3\x27\xe5"
+  "\x7e\x8c\x8c\x7b\xb3\x3e\x59\x3b\xb3\x1e\x36\xf2\x7b\xc4\xe4\xc7"
+  "\xb6\xb5\x24\x49\xfd\xd8\xf6\x2a\xbe\x05\xfe\xfb\xdf\x02\xff\xdf"
+  "\xbf\x05\xfe\xd7\xac\x03\x41\x3b\x9b\x6e\x89\x2f\x37\x3c\x22\x65"
+  "\xf0\x28\xdf\xd7\x3b\x43\x4f\x7d\xdf\xd8\xf3\xf9\xd2\x35\x50\xae"
+  "\x05\xe5\xbd\xad\x2d\xc8\xe7\x7b\xf9\xac\x9f\x27\x61\x04\xd5\x19"
+  "\x75\x67\x9d\xa9\x89\xb8\xf5\x89\x98\xb8\xc9\xfc\x45\x89\xb8\x21"
+  "\x7f\x58\x4c\xfe\xe6\xae\x71\x7f\xea\xaa\xfe\xf5\xfe\x2a\x92\x31"
+  "\x38\x8f\x60\xf9\x82\x39\x99\xe3\xfe\x19\xfb\x33\x4f\x35\x43\xcf"
+  "\x3b\x63\xfc\x76\x5b\xa1\xdb\x07\x70\xfc\x05\xb6\x7d\xb7\xaa\xf5"
+  "\xf0\xf7\x30\x9f\x64\xf2\x7d\x1d\xbe\xbb\x53\x10\xcd\xb3\x1c\x29"
+  "\x63\x19\x7a\x5a\x33\xeb\x76\xb7\x0f\xc4\xed\x1a\x6d\xb2\x0f\x6c"
+  "\x08\x75\x66\x9a\x75\x18\x36\xfb\x51\x62\x1e\x18\x20\xef\xbc\x46"
+  "\x5a\x59\xef\x7e\x0f\x76\x72\xa6\x6a\x67\x36\x19\xed\x6c\x44\x9d"
+  "\x6e\xef\xaa\x5f\xbd\x7f\x4f\xd7\x5f\x7b\xff\xc8\xe8\x5f\x01\x7d"
+  "\x4b\xff\xae\xd2\x6e\xc1\xb8\x6b\x6f\xd7\x6e\xb6\x5b\x7a\xed\x74"
+  "\x2d\xd8\xff\xdd\xe9\xea\x34\xe8\x5a\x10\xf8\x16\xba\x26\x69\x67"
+  "\x76\xd6\x77\x6f\x47\x33\xda\x99\x3d\x25\x59\x3b\x24\xff\x75\x7b"
+  "\xaf\x2b\xcd\x8c\x81\xc9\xf1\x60\x55\xbc\xbb\xd9\xde\xd8\x58\xbf"
+  "\x2a\x4e\xec\xec\xbd\x66\xac\x5f\x23\x16\x2d\xe6\x96\xd9\x9f\x16"
+  "\xd4\xb2\x3d\x22\xf4\x00\xcd\xae\xe7\xf8\xaa\x93\xd6\xaa\x3b\xe3"
+  "\x46\x9d\x13\x57\x8b\x31\xcc\x71\xb6\x84\xc8\xa7\x23\x55\xd2\x1f"
+  "\x00\xf3\xd0\x9c\x0c\xbe\x1f\xa0\xce\x33\xe7\xf4\x57\x32\x39\xa7"
+  "\x3f\x60\x17\x76\x0f\xa3\xc8\xb9\xb7\xdc\xd9\xa3\x3b\x9f\x7f\xd4"
+  "\x9f\x15\xa0\x45\xd2\xde\x8b\x56\x8e\xad\x12\xe7\x1d\x46\x9c\xbf"
+  "\x67\x0f\xc5\xc4\x21\xc4\xdc\xfd\xcc\xdf\x8c\xbb\x09\xa0\x81\x1b"
+  "\xb4\x9c\xb3\xdd\xa4\x81\x99\x8e\xb4\x7d\x26\x0d\x60\xaf\xa4\xfb"
+  "\x6b\x23\x7c\x77\x28\xa4\xee\x89\xcf\x69\x10\x15\x45\x9a\x82\xfd"
+  "\x8c\x3a\x67\xc8\x1c\x5b\x15\x5a\xe3\xb0\x98\xf5\x87\x68\xae\x6f"
+  "\x98\x87\x83\x19\x45\x1a\x60\x85\x4c\xf8\x82\xf1\x12\x5d\xe5\x6a"
+  "\xa4\x5f\xd2\x33\x18\xff\x02\x15\xdf\x11\x6d\x48\xdc\x2d\x94\xaa"
+  "\x03\x7f\xf4\xc1\xe2\x2f\x0e\xb1\x9d\xda\x1a\x45\xff\x59\xd7\x1d"
+  "\x58\x1c\xb0\x72\x19\x69\x3b\x9c\xcf\xb6\xa8\x18\x8a\xcf\x2c\xd2"
+  "\xcf\x73\x4c\x1c\x89\x57\x3a\xfa\x7c\x90\x71\x0a\xe0\x37\xb8\x26"
+  "\x9b\xa6\x5f\x24\x83\x16\xcf\x3c\xaa\x23\x5d\x5f\xd6\x85\xc3\x1e"
+  "\x79\xc7\xe3\x99\x2a\x13\x07\x9d\xdb\x6f\x77\x58\x60\x8b\x71\xbb"
+  "\x2d\xf2\xae\x25\xda\x1e\xc1\x31\xed\x38\x36\xc6\xca\x6c\x62\x1c"
+  "\x50\xe7\x98\x49\x6f\xa3\x8e\xd9\x46\x99\x2e\xdb\x56\xb4\x51\x74"
+  "\x3e\x02\x7b\xf0\x99\xc8\x95\x74\x7e\xd6\x1e\x43\xe7\x54\xe6\x2b"
+  "\xde\x63\x01\xfe\xef\x30\xbd\xf9\x5c\x43\x5b\xc1\x76\xd5\xb3\x13"
+  "\x8e\x84\xa4\xdf\x49\x3a\xc3\xd5\x41\x7f\x86\x01\xb8\xd7\x2b\x1a"
+  "\x3f\x9b\xdf\x49\x63\xb4\x2d\x30\x16\xeb\xd5\x9d\x14\xf6\x7d\x87"
+  "\xee\x78\xb6\xb4\xb3\x1d\xc6\xd5\xe5\xb0\xe8\xc2\xc1\xf1\x2f\x82"
+  "\x8c\x6b\x89\x26\xc2\x6c\x57\x4a\x3f\x26\xf4\xf5\x40\xf9\x09\x2b"
+  "\x6c\x4b\x8b\x6c\xab\x2d\x9b\xed\xfb\x34\xf9\x8c\xb6\xba\xe1\xef"
+  "\x43\x1c\x97\xd2\xec\x17\xfa\x92\xc6\xbc\x05\xdc\x61\xff\xcd\xfd"
+  "\x48\xf2\xcb\x0a\x1e\xa7\xb9\x6f\x70\x9a\x59\x0e\xef\xcb\xb9\x9c"
+  "\xf9\x8e\x3c\xf0\xd7\xdc\x7b\xd0\xaf\xde\x8c\x67\xd0\x25\x63\xbf"
+  "\xa0\xcf\x73\x4f\x30\x8c\x76\xcf\xdc\x9c\xb8\x7e\x76\xe4\x5b\x4d"
+  "\xbe\xe3\x33\xa2\x7a\x2d\x2c\x75\xa7\xa2\xed\xdc\x22\x53\x26\xb9"
+  "\xbe\x92\xb1\xb9\xee\x58\x5e\x0c\xb9\xba\xf8\xa0\x64\x20\xa5\x59"
+  "\x35\x8e\xa5\x39\x77\xb6\x8a\x03\x3e\x77\x7f\xe2\x78\x71\x1e\xc7"
+  "\x9d\x34\x68\xc8\xf2\x64\x3f\x45\x73\x6b\xb9\x6f\xe0\xb5\xd0\xd5"
+  "\xe6\x4b\x8e\x09\xc9\xb1\x3c\xb7\x29\x39\x02\x5d\xe6\x7f\x7f\x9b"
+  "\xba\xdf\x13\x52\xf1\x15\xe7\xfd\x40\x58\xde\x90\xe3\xc5\x7e\x79"
+  "\x32\x8e\x86\xbc\xfb\x3d\x8f\x7d\xdc\x44\x9f\xe2\x37\x64\x1c\x56"
+  "\xc3\x67\x2f\x58\x5f\x1c\x91\x71\xf8\x5c\x25\x7c\x17\x36\xc2\x6b"
+  "\x32\xe9\x93\x76\xa4\x24\x42\x33\xc2\x4c\xdb\x79\x45\x7c\xc7\x3d"
+  "\x24\x69\x31\xaf\xd4\xbc\xd7\xce\x71\x26\x39\x4e\xe9\x88\x08\xa5"
+  "\xb2\x4d\xa1\xb9\x38\x26\xc1\xfc\x3c\xb6\x49\x14\x4d\xc1\xf7\x16"
+  "\xd1\xa4\x78\x79\xde\xa7\x7c\x8f\x5d\x9d\x2f\x9d\x02\x7f\xa7\xfe"
+  "\xf5\x14\xcd\xfb\x0f\xb5\x2f\x63\xca\xda\xfc\x87\xf9\x8c\x29\x60"
+  "\xc0\x40\x5b\x98\xff\xe7\x4c\xba\x52\x2e\xe6\x7d\x6a\xae\x31\xf8"
+  "\x5e\x9c\x3a\xaf\xea\x82\x17\xa0\x79\x72\x5f\xba\x4b\x37\xfd\x01"
+  "\xb0\xe6\x3b\xaf\x94\x99\xf9\x93\x4c\x5e\x2e\x1e\xc4\x77\xab\xe7"
+  "\xa5\x71\xfb\xdd\xe9\x4c\xe1\x7a\x9c\xc7\x29\xed\xb4\x46\xa9\xdf"
+  "\x76\x5f\xa2\xeb\xfc\x6b\xfe\x3e\xb3\x0f\x26\x4d\x54\x1f\x7e\x9e"
+  "\xd2\x96\x39\xa2\xa9\xab\xef\x3f\x57\xfe\x66\x5d\xf9\x63\x63\x68"
+  "\xc3\xef\x63\x14\xdf\xcd\xc7\x9a\xe2\xd9\x7a\xc5\x8b\x2a\x4d\x64"
+  "\x16\x0d\xe6\x18\xb0\x0a\xc7\x05\x64\xf2\x7b\xbb\xe7\xe7\x43\x02"
+  "\x74\xfe\x98\x3a\x87\xfa\x39\xfa\x3f\xdf\xad\xea\xcd\x3f\xc6\xb8"
+  "\x24\xed\x67\x3c\x8e\x75\x3c\xc7\xaa\x58\x07\x3f\x7f\x9f\xf1\xd5"
+  "\x6e\xe3\x31\xfe\xf9\x5a\x6e\x57\xc6\x3d\xe8\x28\xec\x11\xea\xc8"
+  "\xa6\xb6\x8e\x42\xc8\x4f\xb6\x05\xed\x40\x5f\x9d\xdb\x67\xb4\xb9"
+  "\xd7\xc4\x95\x71\x83\xad\x98\xd6\x2e\x16\x24\xa7\x2f\xb7\x2b\xe3"
+  "\x31\x15\xf6\xc2\x5f\x1a\xfe\x7a\x7e\xd7\xf9\x18\x76\x6d\x4b\xb0"
+  "\x62\x74\x8e\xbe\x42\x1c\xe5\xf8\x5f\x58\x17\xb4\x6c\x05\xff\xf6"
+  "\x59\xe7\xa3\x3e\xa1\xa7\x2c\x05\xab\x28\x07\x6b\x5b\x12\x97\xc4"
+  "\x98\x3d\x3a\x7e\x57\x88\x51\x1c\xf7\x1a\xef\x4e\xe3\x7d\x28\xbf"
+  "\xb7\xad\x10\xb3\xda\x3d\x85\xf9\xe6\xd9\x9d\x8a\x59\x53\x58\xd8"
+  "\x19\xe7\x27\xf5\x49\xbe\xe7\xc3\x31\xa1\x74\x91\xba\xb0\x85\xdb"
+  "\x2d\xe0\xb9\x03\xed\xa1\x1c\xe6\xff\xd9\x32\x46\x4e\x30\xf5\xce"
+  "\x4c\xfc\x65\x77\x73\xc6\xd9\xc2\x78\xb5\x65\x8c\xce\x31\x71\xed"
+  "\x13\xca\xb1\x7c\x47\xdc\x42\x26\x6e\x48\x3f\xba\x55\xa5\x47\x38"
+  "\x46\x21\xfb\x20\xb6\x7b\x16\x64\x99\xb8\x9a\x38\x70\x7b\x7c\xaf"
+  "\x52\x64\x8e\x08\x70\x4c\x18\x6e\x2f\xb8\xa6\x90\xcb\xe6\x98\xf8"
+  "\x7e\x57\x5e\x2e\xaf\x16\x82\xe7\x16\x3e\x4f\xd2\xfa\x11\x35\x86"
+  "\x58\xa7\x2c\xd8\x7e\xa4\x3a\xc4\xf1\x3f\x4f\xa1\x8d\x2f\xdb\x44"
+  "\x21\xe9\x1d\x85\x49\xc7\x98\xeb\xa0\x7c\x93\xd4\x0f\x95\x23\xbe"
+  "\xd4\xc5\x14\x8e\x01\x7c\x8a\xe3\xae\xc2\xd6\x84\xdc\x2e\x88\xd4"
+  "\x97\xb5\xf0\x5d\x48\xe8\x9c\x05\x1c\x27\x34\xc0\xb6\x06\xd6\x29"
+  "\x1c\xbf\x22\x95\x75\x93\x6f\xc5\x28\x86\x11\xb5\x96\x92\xb5\xbe"
+  "\xf4\xbb\xc5\xd3\x0f\xd0\x73\xa3\x94\xec\x3c\x37\xca\x9c\x67\xf1"
+  "\x9c\x13\x7f\x2e\xfd\x5c\x76\xa2\xce\x7d\xe6\xf9\xe7\x4b\x0a\x96"
+  "\xce\xe3\x9f\xec\x5b\x97\xdf\xd1\x3b\x76\xed\xcc\x7a\x58\xc5\x31"
+  "\x78\x2e\x9f\xf7\xa9\xb6\x65\x9a\xe7\xac\xcf\x55\x99\x7b\x65\x86"
+  "\x3f\xf7\xfd\x6c\x53\xb3\xed\x89\xbc\x03\x9f\x96\xb1\xe8\x50\xca"
+  "\x97\x69\x64\x49\x6c\x6f\xfe\x9c\x92\x39\x45\xf7\xf2\x89\x4a\xef"
+  "\x64\xed\x1c\x8d\x6f\x67\x21\x75\xb6\xa3\xf4\x60\xc8\xc2\xe5\x2a"
+  "\xde\x76\x8a\x8c\xca\x26\x75\x97\x76\xe1\x10\x73\x0f\x24\xb9\x1f"
+  "\x9c\x53\x8b\x56\x2e\x72\xf3\xb8\xb8\xd6\x92\xe5\xb7\xab\x4f\x58"
+  "\xd8\x46\x29\xc7\x33\xaf\x0d\xa5\x5d\x64\xc4\x13\xfa\xf8\xc2\x09"
+  "\xcc\x33\x0b\x4b\x45\x85\x13\xeb\xaa\x85\xc5\xdd\xcd\x4f\xb1\x3e"
+  "\x04\xec\x73\xd6\x4c\x0b\xbd\xdd\x9e\xf7\x7b\xc7\xee\x53\x7a\x66"
+  "\xe1\x57\xf5\x0e\xe2\x71\x7f\xf1\x14\x2d\xfc\xd2\xea\xc0\x5c\xd2"
+  "\x8f\x7e\x85\xe7\xaf\xb8\x2e\xe7\xc5\x8d\xf3\x0f\xce\xd6\x5a\xc1"
+  "\x85\xe0\xc6\x14\xa1\xfe\x91\xd5\x78\x48\xc5\x9f\x45\xa4\xc8\xd3"
+  "\xb0\x54\x50\xb8\x57\x4f\x2b\xd9\xfa\xa4\xa7\x0d\xb8\xa5\xbf\xe3"
+  "\xfe\xfb\xc6\x8d\x71\x95\x97\x41\x7a\x23\x61\x9b\x88\x8d\x7f\x55"
+  "\x59\xfa\xe8\x1d\x6e\x92\xfe\x10\x15\x95\xa5\xc9\x70\xdd\xec\x11"
+  "\xc5\x7c\xf7\x58\xcf\x7c\xab\xd6\xb5\x9c\x2c\xef\x5d\x0e\x58\x38"
+  "\x06\x3b\xdb\x20\x1c\xa3\xff\x14\x15\x2d\xf9\x04\x69\xe8\x7f\xa9"
+  "\xf0\xbe\x55\xab\xce\x3b\x8b\xde\xd7\x2b\xdf\xaa\xed\x82\x6f\x25"
+  "\x86\xef\x7a\x9d\x2c\x7b\xcb\x5b\x2c\x7e\xeb\x7d\xe4\xd7\x42\xf4"
+  "\x09\x9e\x93\xd2\x12\x6d\x0a\x8e\xfb\x0a\x18\x35\x1e\x7d\xa3\xeb"
+  "\x1b\xb2\x18\xf7\x07\x2d\xe7\xa8\xe8\x6f\x75\xdd\xd4\xe3\xfb\xba"
+  "\x6d\x99\xa3\x7b\xb6\x7b\x16\x61\xfc\x73\xf6\x1a\x73\x1e\x74\xf3"
+  "\x22\xf0\xff\x42\x39\xdf\x21\xbf\x47\x9b\x8c\xf9\xbb\x68\x8a\x59"
+  "\x26\xe9\x18\xbd\xcc\x7b\xaa\xc2\xc7\xe3\x2a\x2e\xfd\xad\x85\xef"
+  "\x26\x74\xe3\xc7\xd0\xcb\x5f\x7a\x17\x9f\x23\xf5\xe8\x13\xa6\x74"
+  "\xd7\x45\xd1\x11\xf5\x50\x16\xd8\xdd\x12\xc5\xda\x32\x72\x49\xe4"
+  "\x37\xb4\x5e\x90\xb1\x29\x59\x7f\xbc\x3b\xff\x0f\x16\x7f\xf8\xbc"
+  "\xcf\xbf\x41\xa7\x46\xd8\x1f\xfe\xea\xf3\x3e\x15\xc3\x32\x4a\x0d"
+  "\xf4\x17\x6a\x28\xfd\x7f\xdd\x72\x2f\xa8\x5a\xb8\x99\xce\x1d\x97"
+  "\xc4\x4c\xbf\xf5\xff\x21\xfe\x86\x08\xeb\x42\xd0\x5d\x3b\x47\x8b"
+  "\x33\x3e\x06\x9c\xf7\xfe\x13\xb0\x64\xcc\xab\xf1\xf4\x09\x9e\xdb"
+  "\x3d\x8b\xfb\x9b\x7a\x32\x69\xac\x90\x14\xdf\x66\x5b\xe9\x53\x16"
+  "\x1d\x3a\x97\x63\x93\x41\xd7\x8e\xe2\x7e\xe1\xdd\xc9\xef\xf8\x1d"
+  "\xca\xbf\xb6\x75\xbe\xdd\xb6\xc8\x53\xac\x83\xf3\x59\xbf\x22\x7d"
+  "\x66\xcd\x25\xa9\x93\xf3\x8c\xf7\x5c\xe3\x7d\x8a\xf1\x3e\xc9\x78"
+  "\xcf\x31\xde\xc7\xf1\xbb\xd2\xdd\x8b\xeb\x3a\xe7\x15\x4b\xaf\x26"
+  "\xbc\xfb\xcc\xb1\x00\x3e\x37\xd8\x4a\xd7\xca\x39\xc0\xc0\x63\x94"
+  "\x81\x97\xd3\x78\x37\xf1\xf9\x81\x2d\xb2\xf6\xbf\x09\x9f\xe7\x73"
+  "\xe2\xf1\x79\x3e\x2f\x06\x1f\xb2\x95\xe6\x7c\x17\x7c\xec\x36\x8e"
+  "\x75\xff\x77\xe0\xc3\xb8\x70\x1a\xda\x6f\x4a\xc0\x27\x60\xe2\x93"
+  "\x94\xdf\x56\x88\x16\x9e\xff\x96\x7d\x5f\xc6\xe8\xed\xc5\x73\x5b"
+  "\xcd\x65\x33\xce\x5c\x71\xff\xab\xc5\x99\x83\x2c\x38\x50\x06\xfd"
+  "\x7f\xbe\xd5\x98\xe7\x0f\x2b\x7b\xb0\x78\xa6\xe9\xfb\x83\xbe\xee"
+  "\xdb\xaa\xfa\xba\x7f\x03\xc7\x5a\x5b\x45\x37\xbb\x4a\x45\x0b\xd6"
+  "\x37\xff\xb3\x5e\x0b\xc6\xc9\x40\x51\xc9\xb2\x65\x8b\xee\xd5\x8a"
+  "\xe6\x2c\x9e\xa7\xdd\x3a\x57\x5b\x56\xb8\x60\x7e\xc9\xbc\xf8\xf3"
+  "\x70\xbb\xf1\xdd\x11\xe9\xe7\xcf\x36\x37\xcb\x00\xf3\x3f\xeb\x6d"
+  "\xe5\x9b\xb9\xe4\x26\xe1\x29\x76\xb3\xae\xdf\x53\x49\x56\x3e\x83"
+  "\x01\x3e\xcd\xa6\x8e\x57\xb1\xf5\x29\x85\x75\x3c\xd2\x61\xc3\x2d"
+  "\x2a\x8b\x49\x47\xd9\x25\x76\x33\x8d\xe1\x1b\xba\xa9\xd7\x29\x2a"
+  "\x7e\x9f\xdb\x4c\x4a\xc3\x4b\x82\xef\xeb\xa7\x60\xbd\xc5\x6b\x5f"
+  "\xc1\x71\x93\xf8\xfe\x1c\xea\x09\xe0\x23\xcf\x14\xf9\xdb\x36\xca"
+  "\xb6\x17\x8c\xe3\x72\xd4\xd9\x8b\x34\xeb\x16\x94\xc5\x7a\xa1\x85"
+  "\xeb\x21\x7d\x33\xc7\x31\x40\x7a\x9a\x11\x0f\x8a\xd3\xde\xe0\x38"
+  "\x03\x48\xb3\xc7\xa4\x7d\xc0\x31\xcc\x91\xa6\x19\xf0\xfe\xc8\x74"
+  "\xc6\x7b\x8e\xb1\xa7\xc0\x65\xfe\xc3\x68\x37\x2e\x76\x10\x7f\x84"
+  "\xe2\xae\xe1\x4e\x6d\xe6\x8c\xd1\xe3\xef\x7b\xf6\xf9\xc5\xf3\x7b"
+  "\x93\x24\x7b\x36\xa6\x4b\xe7\x5d\xa5\x77\xdc\xab\x15\xcf\x9b\xb7"
+  "\x54\x5b\x39\x6f\x71\x89\x36\x67\xe5\x9c\x55\xbd\x69\xfe\xf3\x4b"
+  "\x9f\xe5\x5b\xf2\x3c\x2c\xcb\x0a\x9e\x9d\xff\x73\x76\x5a\x50\xa5"
+  "\x7b\xc7\xcd\xe3\x33\x59\xb7\x19\x71\x25\x8e\x6e\x65\x5b\x23\xe3"
+  "\xde\x62\x3c\x73\xbc\x25\x07\x7e\xeb\xf1\x77\x18\x7f\x07\xf1\x77"
+  "\x1c\x7f\x4d\x67\x68\x25\x7f\x3b\xe0\x40\xbb\x67\xe9\x06\xd3\x9e"
+  "\xe8\xe2\xa1\xa5\x55\x26\x0f\x61\xfe\x3f\xa0\xe6\xb7\xa5\x47\x1b"
+  "\x23\x52\x7e\x3a\x79\x6a\xeb\xa5\x2e\x9e\xe2\x78\x91\x8d\xec\x93"
+  "\xb3\x02\xf9\xe0\x61\x5e\xa7\x83\xe6\xd7\x31\xdd\x4e\xd3\xf2\x8f"
+  "\x6a\x5e\x13\xc7\x38\xd6\x09\x7e\xeb\xc1\x2f\xc7\x54\x7c\x91\x65"
+  "\x93\x50\x6e\x20\xda\x38\xac\xda\x30\xde\xfb\x8a\xa3\xbc\x8f\x71"
+  "\xca\x78\x57\x6b\xfe\xe5\x8f\xf2\x33\xff\x1a\x67\x61\x36\xf6\x6f"
+  "\x54\x6b\x47\x33\x6f\xd9\x59\xa3\x0d\x1f\x68\xe1\xde\xe3\x91\x36"
+  "\xb7\x5c\x63\xf1\x1e\x9a\x2d\xe5\x7e\x01\x7c\xce\xeb\xa9\x4f\x9e"
+  "\x90\xf1\x0b\xdd\x97\xa1\x23\xee\xbe\xdb\x5f\x2a\xcb\xa7\xf0\x1e"
+  "\xdb\xb4\x62\xa1\x73\x4c\x69\x3d\x75\xe1\x09\xae\x27\xec\xf7\x16"
+  "\xeb\x5b\x6e\xc8\x51\xb6\x00\xc7\x8d\x5b\x76\xd4\x80\x19\x66\xda"
+  "\x9e\xa1\xa5\xab\xd4\x7a\x6d\xa5\xf1\xbd\x81\x65\xc7\x4d\x5f\x39"
+  "\xc8\x68\x36\xde\x9b\x4d\x1d\x10\xa0\x65\x75\x86\x5f\x93\x4f\xf5"
+  "\xbf\xa4\xbf\xf1\x7e\xd0\xc0\x31\x85\x63\x59\x00\xff\x26\x1e\x3b"
+  "\xac\x7d\x0f\xe2\xf9\x38\xe8\x73\x4c\xd1\xa7\x44\xda\x80\xb0\x6b"
+  "\x38\xff\x38\x7f\xb3\x03\x79\xc7\x55\x9c\x88\x65\x33\xb9\xcf\x5d"
+  "\xbe\x8f\xd5\x39\xc0\xf5\x51\x3e\x33\x84\x2c\x1d\xf4\x5f\x62\xf9"
+  "\x5c\x96\x07\x78\x75\xa6\xde\x61\x3d\x53\x10\x85\x9c\x4a\xbb\xbb"
+  "\x64\x93\xa9\x6f\xba\xf8\xa0\xa4\x36\x99\x2e\x49\x36\xee\xc6\xd8"
+  "\x5c\x27\x3c\x4b\x9a\x81\x53\x9d\x1c\x03\x8e\xa7\x79\xa9\xd3\xbe"
+  "\xef\x50\x3a\xb2\x24\xd4\xb9\x16\x31\xf0\xe0\x38\xdd\x01\xc6\xed"
+  "\xb2\x3c\xc7\x35\xf4\xc6\xf2\xfe\xa6\xde\x30\xe1\xd8\x52\x84\x6e"
+  "\x2b\xc5\x7f\x5e\xa7\x8f\xf7\x90\x79\xbe\x94\xf6\x08\xe0\xf4\xb9"
+  "\xa8\xee\x30\xe9\x15\x4e\xcc\x49\x25\xc7\xa1\x63\xac\xd2\xe6\xf4"
+  "\x2c\x69\xef\xd2\x45\xcb\x8b\x63\x61\x0a\xbb\xd3\xc7\x70\x59\x1f"
+  "\xb1\x4d\x52\x10\xb5\x72\x1c\x11\x9f\x31\xbf\x40\x07\x2f\xaf\x35"
+  "\x71\x05\x0d\x8f\x9a\xf8\x1a\xdf\x4a\x3a\x1a\xa0\xe5\xc0\xbd\x83"
+  "\x7d\x79\xeb\xd5\x78\xae\x94\xfa\x06\x79\xfb\x51\xf7\x64\x80\x96"
+  "\x38\x0d\x19\x3a\x86\xfa\xfb\x8f\x94\x4f\x42\x99\xe5\x61\xc3\x1f"
+  "\xb5\x09\xe3\x7b\xbc\x8b\xf7\x97\x9e\x8d\xd9\x0f\x38\xae\xc6\xf0"
+  "\x3e\xf7\x29\x5a\x31\x26\x26\xdd\x18\xdb\x23\x79\x48\x3f\xab\xd6"
+  "\xd6\x4e\x23\x3e\xdb\x0a\xe5\xbb\x6b\xe0\xc8\xba\x80\xef\x5b\xb1"
+  "\x8c\x4b\xda\xcb\x31\x5e\x51\x6c\xce\x17\x80\x75\x40\xd2\xbc\xaf"
+  "\x38\xcc\x74\x52\xf1\x1a\x96\xf6\x55\x74\x5a\x51\x15\x47\x7b\x9e"
+  "\x37\xd1\x0e\xd3\xa9\xcf\x3a\xa1\xf7\x09\xa5\x88\x82\x55\x56\x19"
+  "\x73\x9c\x65\x9c\xcf\x5e\xc0\x1f\xd2\xae\x52\x74\x5b\x71\xc2\xa4"
+  "\x9b\x39\x76\x4c\xa7\x00\xad\x98\xc2\xb4\x8d\xef\x63\xaf\xa6\x53"
+  "\x66\xdf\x41\x53\xde\x0f\xc6\x7b\xab\x21\x17\xc7\x7c\xfd\xd8\x17"
+  "\x60\xe9\xd7\x47\xac\xa3\xe9\x48\xe9\x28\x52\xb4\x5d\x39\x26\x40"
+  "\xc5\x55\x31\xeb\x06\xbe\x67\xb6\x9f\x65\x05\x78\x1e\x36\x62\x27"
+  "\x1d\x55\xfe\x28\x4b\x39\x26\xed\x61\x29\xcb\x2b\x64\x8c\x0b\x8e"
+  "\xbb\xda\xc4\x34\x62\xbd\xc8\xb2\xc4\x32\xc0\xf2\xa4\x68\xb4\x72"
+  "\x7b\x0c\x8d\xea\x99\x3e\x06\x9d\x0e\x24\xe8\xf2\x79\x5a\xd1\x78"
+  "\xa5\x8b\xb5\xec\x5b\xe7\x8e\x90\x81\x4a\xb4\x07\x27\xde\xab\xe5"
+  "\x8d\xbf\xb5\xb4\x70\xe8\x34\xf5\x33\x31\x2f\x97\x7f\x7b\xc7\xaf"
+  "\xbb\x34\xb4\x13\x89\x5f\xbb\xad\xdd\xa8\xf4\x47\x69\x56\x20\xa5"
+  "\xb7\x3c\x47\xe5\xb8\xa1\x5b\x17\x13\xc7\xf8\x6d\xd9\x72\x06\x63"
+  "\x6a\x77\xce\xe2\x38\xb5\xd3\xb1\x66\x9c\x76\x51\x7c\x53\x83\xbc"
+  "\x3d\x48\xef\x53\xcc\xb1\xee\xbf\x10\x7a\x86\x73\x16\xaf\xed\x45"
+  "\xc5\x40\x2d\x98\x51\x59\x8a\xbf\x9c\x60\xc6\x68\xc7\xe4\x3b\x5c"
+  "\x02\x70\x8b\xcc\x7e\xf1\x1e\x00\xe8\x34\x6b\x7a\xa9\x88\x32\x8d"
+  "\x0a\x4a\x39\x9e\x34\x60\xa7\xf2\x1e\x40\x29\xfa\x5f\xd4\xa4\xd6"
+  "\x97\xa5\xe0\xff\xa5\xa3\x0c\x5d\x96\x87\x77\x8e\x7f\x91\x27\xc7"
+  "\xd5\xe3\x90\x71\xa8\xf5\xf5\x77\x3e\x82\xf5\x40\x8e\x09\x13\xb0"
+  "\x7a\x1a\xb1\xf6\x24\xbc\xef\xea\x17\xa9\x57\x8e\x9c\x69\x4b\x51"
+  "\x71\xfd\x20\xe3\xee\x1a\x8b\x9e\xdf\xe9\xf7\x80\xbc\x3e\xeb\xec"
+  "\xec\x17\x91\x0f\xde\x73\x73\x19\x33\x6f\xab\x47\x0f\x6c\xb5\xe8"
+  "\x61\x8c\xa3\x5d\xd9\xcf\xad\xac\x3f\xb1\xb6\x5c\xd5\xb9\xff\x2f"
+  "\xe7\x43\x0b\xb9\xd5\x7a\x66\x95\xdc\xf7\xb9\xe0\xb1\x12\x74\x76"
+  "\xeb\xa0\x2c\xb9\x46\x09\xeb\x9e\x14\x52\xbe\xa8\xab\x1e\x36\x75"
+  "\x2c\x9f\x27\xd9\xd6\x89\x20\xef\x25\xda\x22\x22\x28\x63\xa6\xf3"
+  "\xdc\x41\x67\xc8\x5f\xd6\xee\xe6\x58\xad\xd2\x06\x42\xbb\x6a\xde"
+  "\x88\xaa\x79\x03\xed\x07\x53\xef\x9c\x8d\xf9\x21\xe5\x0c\xad\xd2"
+  "\x18\x7f\xa6\x0d\xef\x57\xeb\xa0\x95\x9f\xe7\x49\xa6\x4f\xe6\x5d"
+  "\xc7\xd9\xa7\x81\xfb\x6a\x8b\xa0\xcf\xb1\xfd\xb2\xe8\x81\x2d\x1e"
+  "\xf4\xcb\x82\x7e\x95\x9e\x65\x99\x09\xb3\xaf\x09\xe4\xad\xaf\x8c"
+  "\x47\x2c\xd7\xcf\xab\x73\x62\xfb\xc8\xfa\x5f\xf5\x61\xf5\x9c\x64"
+  "\x7d\x14\x16\xee\x23\xd3\x60\xf5\x3d\x86\xbc\x49\x3c\x59\x7f\xb4"
+  "\xd2\xaa\x50\x9f\x75\xec\xe3\xe1\x9c\x05\xfd\x36\x91\xc7\x10\xf3"
+  "\xa7\x97\xf1\x4c\x36\x5e\x0c\x4f\xc1\x5a\x03\x1b\xda\x3d\x1b\xb8"
+  "\x1c\x4b\x4e\xef\xd5\x67\xaf\x4e\xef\xd5\x9f\x72\x7d\xc6\x83\x7d"
+  "\x5e\x6c\x11\x2c\xd6\xc1\xb7\x58\xaf\x6d\x4c\xd6\x6e\x9f\x75\xb5"
+  "\x8c\x57\xd2\x3c\xc1\xf2\x62\xe8\x20\xf0\xa1\x80\x9c\x08\xd6\x49"
+  "\xed\x9e\x35\x9d\xfb\x5f\xb6\x14\x2d\x55\xea\x07\x8b\xf0\x26\x83"
+  "\x61\x5b\xe7\x65\x1f\x93\x89\x68\x3f\x69\xbe\xce\xdf\x61\xf0\x3a"
+  "\xa7\xe8\xeb\xff\x69\x90\x2d\x85\xee\x0f\xa6\xfe\x53\x6f\x5b\x69"
+  "\x64\x08\xd3\x10\x30\x4b\x21\xc7\xcb\x79\x9d\xaa\xf6\x2e\xd6\xc0"
+  "\xfe\xdf\x24\xd7\xa5\xc1\x0c\xe7\x14\x15\x2b\x6c\x0d\xe6\xbf\x6d"
+  "\x9d\x7b\xb8\xed\x9e\x32\x6b\x80\x9a\xfb\x2b\xb9\xbc\x79\xa7\xa8"
+  "\xbc\xa7\x59\xf7\xd8\x84\xb6\xda\x06\x3b\xb2\x6c\xb7\x2e\x38\x2e"
+  "\xff\x3d\xcd\x5d\x7c\xa2\xfc\x5f\x4c\x3e\x41\xfd\x49\xc9\x79\xa0"
+  "\x6c\xde\xd5\x79\xa0\x4c\xee\xcd\x32\xdd\xd5\x5a\xa5\x6c\x93\x69"
+  "\xa7\x88\xf5\x37\xef\xd4\xca\x65\xfb\x9a\x6a\x9b\x69\x92\xc3\xe7"
+  "\x12\xb9\xa0\x8b\x1b\x65\x0f\x9a\x7a\x80\xf9\xc5\x16\xe5\x6f\x16"
+  "\x90\xe4\x69\xe4\xc1\xfe\x29\xce\x56\xfb\xa5\xa3\x6b\xe5\x77\xf7"
+  "\x3c\x2b\xeb\x82\xae\xc2\x5d\xec\xaf\x1a\xca\x70\xd6\xa3\x4c\x38"
+  "\x40\x9f\xc8\x98\xa4\x98\x83\x0f\x03\x86\x6f\x7b\x26\xe6\x68\xe5"
+  "\xb7\x95\xce\x32\xcd\x31\x7e\x58\xae\x91\x96\x05\xbc\x39\xde\x0f"
+  "\xd6\x3b\x6b\x9d\x9d\xf3\x92\x27\x07\xba\x42\x48\x3f\x1d\xcc\x4b"
+  "\xfd\xdb\x40\xbb\x57\x2d\xfa\xbe\x4b\x23\x1c\xc4\x7d\xbe\xb4\xbe"
+  "\xdf\xbe\x17\x87\x93\xf5\xff\x72\x3c\x43\xc5\x77\x51\xd6\xba\xd1"
+  "\x56\xfa\x5f\x63\xc8\xc2\x74\x08\xd0\xda\x1c\x45\xbb\xb5\x6e\x73"
+  "\x7c\x02\xb4\x46\xee\x8b\xf2\x5e\xe3\xf4\x88\xf8\x46\xed\x87\xae"
+  "\x85\xfe\x7b\xce\xa1\xf2\x4b\xaf\x38\xff\x67\x7b\x5e\x5b\xb0\x4c"
+  "\x9b\xfb\xfc\xca\xc5\x03\x07\xc6\xad\x95\xac\xf2\x0e\x8b\x67\xed"
+  "\x01\x35\x9f\xae\x6d\x31\xf1\x66\xbb\x04\xef\xe8\xff\xca\x2b\xf6"
+  "\x2d\x73\x0b\x0c\x37\xe5\x02\x27\x75\x3d\x8f\xa4\xdc\x91\x31\xaf"
+  "\x77\x53\xee\x5d\x77\x17\x3c\x32\x6f\xce\xdc\x55\x31\xa9\xf7\xc4"
+  "\xee\xeb\x6d\xdd\x89\xb6\x53\xfb\x3d\x00\x5d\x91\x32\x6d\x0d\xcf"
+  "\x2d\xe5\x9f\x97\x47\xc4\x5f\xa1\xaf\xc7\x40\xc6\x0a\x1a\x4a\x22"
+  "\xd4\x00\x5d\x26\x6e\x66\x1d\xde\x4b\xdd\xcd\x83\x3d\x05\xde\xb2"
+  "\xa1\xef\x41\xd8\x75\x17\x79\x7f\xe6\x34\xb9\x52\x1a\xab\x38\x26"
+  "\xef\x68\x63\xff\xbe\xfc\x30\xd2\x33\xf0\xfb\x15\x7e\x7b\xe2\xf7"
+  "\x6f\xda\x62\xac\x7b\xd8\x17\x7a\x05\xfb\x42\x97\x4b\x5f\x8f\xe1"
+  "\x21\x37\x0d\x5f\xca\x36\x7b\x79\x09\xdb\x20\x01\x72\xf1\x77\xf1"
+  "\x88\xcb\x22\xed\x23\xed\x39\x72\xf2\xaf\x90\x67\x48\xe5\x87\x45"
+  "\xc5\x68\x4d\xec\xca\xe7\x6f\x5c\x0d\x41\x9b\x03\x53\x53\xbe\xa4"
+  "\x54\x47\xaf\xf6\x76\x8f\x8b\xfd\x9f\x8e\x33\x9d\xba\xfb\x86\x26"
+  "\xd3\x39\xd1\x3e\xec\xb2\x0d\x5f\x26\x69\xdf\x1a\xf6\xdc\x1e\x39"
+  "\x2f\xb8\x4a\x62\x6c\x3a\x3e\x13\xec\xad\xec\x13\x11\x55\xf6\xa9"
+  "\x6b\xbb\x29\x07\x78\xae\x35\xf9\x34\x2e\x3e\xda\xe2\x92\x79\x4b"
+  "\xe7\xcd\xd5\x6e\x5d\xd6\x9b\x62\xa2\xa3\x15\xce\x5b\xac\x2d\x9d"
+  "\xb7\x64\xf9\xbc\x65\x32\xb2\x19\xe7\xc6\xcd\xf9\x59\x22\x73\xd4"
+  "\x4c\xf3\xde\x8e\xd6\x8f\xe9\xeb\xee\xc1\x31\xb5\x44\xe5\xa8\xe3"
+  "\x7c\xf6\xab\xd6\x1b\x6f\x1d\x8c\x5f\x6f\xac\xab\x52\x76\xde\x68"
+  "\xbb\x5a\xeb\xac\x1b\xc6\xef\xa7\xc8\x5d\xd7\x15\xbf\xdb\x3d\x07"
+  "\xb4\xb4\x28\xba\xa5\x05\xda\x3d\xee\x7c\x93\x6e\x01\x5a\x17\x30"
+  "\x6c\xa9\x56\xa9\x3f\x30\xc7\x42\xff\xc5\xcd\xaf\xea\xdb\x99\x6e"
+  "\xd6\xbf\xa9\x72\xbf\x37\x63\x74\x16\xb7\xc5\x30\xd1\x5e\x00\xe3"
+  "\x63\x87\xde\x64\xfd\xb6\xd1\x84\x87\x36\xa7\x70\x7b\xc6\x3a\xe8"
+  "\x7b\x67\x68\x9d\x26\xf5\xa3\x77\x74\x16\xeb\x14\x3e\x3b\xd5\x2b"
+  "\x00\x47\x9e\xe5\xad\x0b\xb0\x8d\x29\x63\xc8\x03\x16\xef\xd3\x42"
+  "\x37\x0c\xe1\xef\xac\x72\x9a\x8a\xed\xe5\xda\xcf\x7b\xc3\x68\x2b"
+  "\xbd\xdd\xb3\xce\xd1\xe5\x9b\xbe\x2e\xc0\x76\x27\xc3\x0d\x90\xfb"
+  "\x24\xc3\x53\xb1\xcb\xd6\x8d\x03\xef\x4c\xea\xb2\x9f\xd6\xb9\x63"
+  "\xd6\x65\x8c\x8f\xc4\x33\x04\x5c\x64\x9c\x4c\xe5\x3b\x28\xfb\xcd"
+  "\xfa\x73\xbb\xd1\x77\xb3\x3f\x80\x07\xfd\xe7\x72\x9a\x67\xcf\x01"
+  "\xa3\xdf\x8c\x1f\xe3\x1e\x8b\xb3\x81\xef\x41\xc6\x17\xf5\xea\x63"
+  "\x64\x9b\xf7\x65\x7a\x20\xed\x44\x97\x4f\xb2\x5b\x4b\xd4\x1b\xcf"
+  "\x2f\xd6\x8a\x16\x2c\x5e\x58\xb0\x72\xce\xc2\x79\x05\xcb\x8b\x87"
+  "\x6a\xcb\x17\x3f\x53\xf4\xfc\xb3\x0b\x99\x6b\x96\x95\x2c\x7f\x76"
+  "\xa1\xc6\x9a\xa5\x60\x52\x6e\x6e\xc1\x03\x8f\xce\x78\xbc\x37\x3d"
+  "\x30\x07\x69\x58\xf9\xe7\x3a\x87\xaa\xac\x47\x26\x4f\x7c\xac\x60"
+  "\xe2\xf4\x47\xa7\xcd\x94\x97\x16\x3a\xf3\x27\x2d\x4e\x5e\x20\x8e"
+  "\x0f\xed\xe0\xa5\x74\x8c\x6f\x8f\x53\xf4\xc2\x2c\x15\xef\xda\xb3"
+  "\x29\x3e\xde\xb5\x07\x6b\x59\x8f\x0f\x7f\x27\x89\x36\xd8\xf1\x87"
+  "\x75\xea\x0b\x79\x8a\xbf\xae\x7b\xa8\xdd\xe3\x39\xd8\xc5\x5f\x2f"
+  "\x48\xfb\x80\x7d\x39\xd4\xfe\xac\x07\xfa\xdf\x75\x22\x36\xaf\x6b"
+  "\x3d\xe9\x09\x76\xae\x27\x3b\x75\xca\xfa\xfe\xe6\xda\x12\x69\x0e"
+  "\xac\x2b\xaf\xe3\x75\xa5\xda\x4f\x7a\xe1\x29\xc9\x53\xdd\xca\x77"
+  "\x1a\x99\xeb\x4a\x96\x6d\x3e\x2b\x56\xeb\x8f\xf5\xf9\xb1\x32\x2e"
+  "\x63\x2c\x1a\x32\xce\xf5\xe4\xfe\x9d\xfd\xad\xbd\xbc\xa7\x0d\xfb"
+  "\x38\x1d\xb6\x02\xe6\xaf\x76\x21\x32\xde\xda\x6b\xe0\x54\xc5\x7b"
+  "\xdc\x6c\x37\x1b\xfc\xd4\xe7\x0c\xad\xff\x4c\x78\xd6\xb5\xaa\x35"
+  "\xa5\xe7\x07\xac\xd7\xc5\xfa\x7e\x0f\x4c\x8f\xca\x78\x74\xd0\xe9"
+  "\xeb\x8f\x75\xf1\xec\x0b\xb3\x98\x17\xba\xd6\xb2\xeb\xe3\xf4\x7f"
+  "\x9b\xfc\x56\xe3\xfa\x88\x79\x5f\xbf\x64\x20\x59\xac\x03\xbd\xb4"
+  "\xdd\x22\x30\x1f\xad\xdf\xcf\x6d\x30\x3d\x03\xe4\x39\x8a\xb2\xd6"
+  "\x2e\xfa\x6d\x70\x76\xd2\xcf\xd8\x67\x31\xf7\x58\x14\xde\x2f\x3c"
+  "\xd5\x1d\xad\x92\xd3\x69\x83\xfb\x5b\xe9\xe4\xa1\x1e\x2c\x93\x26"
+  "\xbd\xae\xa4\xd5\x86\xfa\x2b\x69\xf5\xc2\x4d\x31\xb4\x1a\x7f\x25"
+  "\xad\x36\x84\x63\xce\x7d\x8c\x7d\x94\x17\x9e\x62\x9a\x31\x8f\xa1"
+  "\xdf\xfb\xc1\x67\xeb\xbb\xe8\xf7\x42\xf6\x95\xf4\x7b\x61\x5c\x72"
+  "\xfa\x6d\x38\x31\x28\x1e\xce\x4b\xc9\xe6\x8d\x3e\xeb\x2c\xc6\x7d"
+  "\x9e\x17\xde\xaf\xef\x2f\xd7\xa4\xe1\x6d\x16\xbd\x70\x9b\x07\x7f"
+  "\xf8\xe5\x75\x44\x97\x2d\x2e\xc2\x06\x7d\xeb\xea\xb1\xe6\xe5\x7d"
+  "\xa5\xab\xcc\x45\x27\xcd\x3d\x0f\x3c\x9f\xe0\xb5\xf3\xf4\xe8\xfd"
+  "\x82\xd3\x99\x9e\xfc\xad\x28\xf0\xfb\x09\x65\x97\xfe\x33\x75\xee"
+  "\xb9\x0c\x9f\x60\x4f\x5d\x47\xda\x91\xea\xbb\x38\xdd\x01\x1e\x92"
+  "\xbe\x4f\xf2\x5b\xaa\xdd\xc0\x2c\x88\xe6\x50\x37\x70\x3b\xf9\xbf"
+  "\xbb\x3b\xad\x09\xfa\xa8\x70\xce\xe2\xb9\xcf\xcf\x9f\xff\xed\xaa"
+  "\x28\xd6\x7f\xcc\xeb\xd1\x37\xb6\xf3\xb7\x12\xd7\x3f\xb7\x1a\x6d"
+  "\xb2\xfd\x9f\xa6\xe6\xcd\x7f\x86\xfe\xfb\xf9\x61\x65\x4b\x3e\xd9"
+  "\xa2\xee\xf1\xbe\x38\x2a\x46\x3f\x83\x47\x5e\xcc\x11\x9e\x7f\x2e"
+  "\xeb\x1a\xe3\x17\xd3\xaf\x1c\xe3\x17\xb5\xe4\x63\xfc\xe2\x24\x7d"
+  "\x05\xdf\xab\x78\x11\xeb\x9f\xc5\xd2\xd6\xe4\x77\x3e\x2f\xc7\x9a"
+  "\xb9\x05\xeb\xe5\xd6\xe9\xab\x7c\xf7\x17\xac\x4a\x61\x7f\x70\xf9"
+  "\xed\x8c\xc8\x25\xd1\xcc\x67\xd6\x7c\x3e\xc6\xdf\xce\xe0\x6f\xe6"
+  "\xf0\x37\x54\x65\x19\x3c\x6f\x3d\x4d\x72\xed\x88\x7c\xad\xe6\xb4"
+  "\xfc\xc6\x2f\x6c\x85\x17\x6b\x4d\xdb\xda\x86\xe9\x8d\xef\x17\x6f"
+  "\x51\xe3\x71\x82\xc7\x82\xdb\x2b\x58\xe5\x53\x6d\x5c\xe2\xef\x63"
+  "\x91\x4d\xd9\x10\x2f\x9e\xb8\xea\xde\x7d\x46\xe5\xec\x6e\x63\xca"
+  "\x7b\xdc\xbd\xb6\xa9\xd8\xd3\xec\xd3\x18\x34\x7d\xea\xd8\xbf\xae"
+  "\xdd\xb3\xd1\x99\xe8\x9f\xa7\x7c\x4c\x36\x4e\x31\x7d\x7b\xf0\x3c"
+  "\xb3\x73\x3d\xc0\xdf\x5b\xc1\x3a\x4e\x2b\x5f\xd7\xf3\x1c\x6d\xbc"
+  "\xa9\xa6\x9b\x3d\x74\xf3\x3e\xb1\xe1\x03\xd7\x0b\x30\xaa\x3a\xfd"
+  "\x82\xf0\xce\xfa\xa2\xcb\xb7\x6f\xe3\x01\xd3\x37\x4c\xfa\x03\x62"
+  "\xee\xe5\x6f\xba\x9c\xa6\x8d\x9f\xc9\x6f\xc8\x0c\xe2\xfd\xef\x8d"
+  "\xa1\x7a\xe9\x97\xb8\x31\x10\x8b\x8b\x81\xc7\x1b\xbc\x47\xcb\xf9"
+  "\xb1\xb8\x94\xce\x59\xbe\x60\x44\xe9\xfc\x05\xda\xb3\x85\x0b\x8a"
+  "\x0b\x16\xc8\x18\xb0\x32\xbc\x6c\xc9\xaa\x62\x3e\x91\xb8\xa3\x77"
+  "\xc2\x1c\x66\xf8\x10\x76\xfa\x4a\x49\x3f\xc2\x97\x1e\x07\x3d\x2c"
+  "\xca\x8f\xf0\xe5\x5c\x35\xaf\xbf\x34\xf7\x4a\x9f\x99\x97\x3a\xfd"
+  "\xbf\xc0\x57\xf6\xed\x2a\xf6\xbc\xe1\x67\xc3\x7c\xf7\x52\x55\x92"
+  "\x3a\xfb\x3b\x7d\xc6\xd8\x77\xa9\x23\x5f\xde\xf7\x90\x71\xc2\x2b"
+  "\x79\xdc\x5e\x22\x7f\xe9\x64\x8e\x75\x6a\xf0\xf3\x4b\x27\x4d\x7e"
+  "\x36\xfd\x0d\x19\x16\xdf\x37\x19\x11\x8e\xf5\x35\x7a\x79\x02\xe6"
+  "\x3c\x47\x67\x3f\xd6\x58\x88\x71\x0f\x59\x7c\xc0\xe3\x65\x2d\x11"
+  "\x0f\xe0\x37\x10\xe9\x63\xba\x7c\xb9\xcc\x7e\xbe\x9c\x8b\xe7\x2b"
+  "\x6c\xd5\x09\x93\x73\x61\x94\x2e\x9b\x57\xd2\x9b\x26\xce\x29\x2a"
+  "\x62\xb9\x9e\x33\xaf\x68\xf9\xd2\xe7\x97\x15\x2c\x58\xbc\x00\xa9"
+  "\x13\xe6\x73\x68\x5e\x59\xe4\x5e\x23\x47\x5b\x3c\x6f\xde\x5c\x95"
+  "\x64\x0c\x43\xfc\x39\x90\x3a\xbb\x7f\xf9\x70\x80\x36\x96\x74\xd9"
+  "\x5f\xaf\x64\x09\xcb\xcb\xf9\xf8\x7b\x56\xca\xb4\xb4\x8d\x5e\x0e"
+  "\xc4\xaf\x7b\x5e\x0e\x9a\xfc\x20\xc7\xcf\xc5\xfe\x3e\x23\x0e\xb5"
+  "\x09\x79\x6e\x82\x31\xdb\x34\x99\xbf\x8f\x8d\x35\xd9\x24\xb6\xf7"
+  "\xbb\xe0\xbc\xd2\xa9\xff\xf9\x7e\xfd\x7a\xe5\x27\x60\xe5\x6f\x7a"
+  "\xf2\x3d\x7b\xe4\x83\xff\x5f\x8c\x28\xfe\x7f\xa5\x93\xff\xdb\x2c"
+  "\xa9\x58\xc3\xbd\x32\xd7\xb4\xe7\xe3\x65\xe6\x95\xb2\x2b\x65\x89"
+  "\xfd\x3f\x5f\xd9\x6e\xd2\xd6\x1c\x67\xc5\x5b\x9b\x46\x9a\xfb\xb0"
+  "\x35\x46\x9c\x78\x7e\xe6\xba\x6c\xab\x8b\x3e\x37\xdc\xcf\xfe\xec"
+  "\xa7\x68\x93\xc1\x2f\xaf\x9c\x8c\xf1\xcb\xb2\x9f\xa1\x57\x22\x6a"
+  "\x9c\x5e\x09\x99\xf8\x05\xe8\x15\x79\x1e\xc0\x30\x94\xec\xbf\xbc"
+  "\x4a\xf1\xce\x26\x87\x49\x5b\x5e\x17\xe3\x3d\xbb\xcb\xb6\x78\xf9"
+  "\xa8\xf4\x91\x50\x71\x06\x3a\xb8\xff\x80\xb3\xcf\x84\x83\xb2\xe8"
+  "\x7f\x5a\xbd\x49\x2b\xb3\x4c\x2c\x4f\x4c\x9c\x53\x8c\x45\xeb\x82"
+  "\xf9\xf3\xe7\x2d\x5d\x66\xc6\x5e\xce\x7e\xbe\x68\xae\x8a\xb5\x7c"
+  "\x2f\x86\x7f\x25\x24\x70\x3c\x87\x6b\x46\xaa\x7a\x4c\xb0\x21\x87"
+  "\xf2\x3e\x83\xf4\xdd\x93\xeb\x98\x8a\x91\x7b\x8c\x35\xcd\x29\xda"
+  "\x5c\xaf\x7c\x5f\x36\xbf\xa0\xec\xc5\xeb\x97\x00\xa7\x16\xd3\x5e"
+  "\xe4\xfd\xcb\x36\xd2\xc2\x7c\x8f\x88\xfd\x97\x77\xbf\x26\x9a\x79"
+  "\xbf\xb2\xdd\xb3\x39\xdd\xfc\x3e\x17\xdb\x22\x9b\xd5\xb7\xcd\x83"
+  "\xbe\xc5\x1c\xdb\xbe\xe2\x61\xbd\xc2\x39\x46\x64\x0e\x28\x84\xcd"
+  "\x93\xce\xb2\x70\x43\x2b\xc7\xbd\xe7\x78\x40\x9b\xf3\xd9\x56\x62"
+  "\xfd\xc2\x31\xec\x9b\x69\x73\x36\xd6\x37\xf6\x00\x55\xcc\x0c\x66"
+  "\x38\xc7\x6c\x58\x4d\x69\xdc\x06\x74\x53\xa0\xbe\x96\x69\xbb\xb9"
+  "\xe4\x53\xe8\x1e\x63\x7f\x37\xc0\xed\x04\x68\x73\x8e\xb1\x97\x9e"
+  "\x6b\xec\x5d\xe6\xa2\x5c\x75\x80\x6e\x30\x62\x82\x6b\x5f\xdc\xee"
+  "\xa6\x52\xfe\x6e\x9f\x8a\xe5\x33\x76\x9f\xf0\x6a\x01\xfe\x36\x1e"
+  "\xec\x2b\xac\x21\x36\xb5\x88\x0a\x2d\xa0\xe2\x80\x33\xaf\x6c\x99"
+  "\xa0\x7c\x8b\x37\x9d\x60\x1a\x00\x6e\xbe\x01\x37\x1f\x70\x31\xfe"
+  "\x37\xcf\x56\xbc\xba\x85\xcc\x36\x30\xa7\x04\x61\x8b\xa6\xb1\x3d"
+  "\x0a\xbc\x9d\xf8\x1b\xb5\x55\x9e\x4f\x07\xb0\x6e\xb1\x09\xf6\x1b"
+  "\xea\xfa\x06\xd9\x96\x31\xe6\xfc\xc2\x6d\x1b\xb8\x73\xec\x8d\x34"
+  "\xde\x3b\x33\xda\x9a\xc9\xeb\x6b\x13\x26\xde\x9d\xfa\xa5\xb3\xb5"
+  "\x80\x99\x86\xb9\x32\x68\x7c\x7b\x6a\xd4\xd6\x0b\xec\x63\x16\xc0"
+  "\x5c\x38\x40\x14\x44\xec\x7c\xae\x73\x83\xf9\x6d\xaf\x9a\x0b\x4c"
+  "\xaf\x2d\x7b\xbb\xce\x6b\x50\x1f\xf4\x87\x3c\xb8\x9b\x69\xcb\x47"
+  "\xdc\x2e\xcb\x02\x8f\xe5\x65\x8c\x0d\x7f\x27\x5e\x5c\x3a\x5b\x87"
+  "\x75\xfe\x0d\xa0\xc1\x97\x3c\x46\x7c\xc6\xca\xbe\x5f\x48\xb3\x71"
+  "\x2c\xf2\x53\xb4\xa5\x81\xc7\x87\x71\x01\x0d\x73\x22\xed\xf9\x3f"
+  "\xe6\xfb\xa8\xac\x0f\xd7\x96\xc1\x8e\x9d\xcf\xba\xc4\xfb\x30\xaf"
+  "\x8b\xf9\x1b\x32\xfc\xec\x9a\x2b\x74\x39\xbe\xab\x79\x7c\xbd\x0f"
+  "\xaf\x6d\x11\xfa\x37\x1e\x12\x47\x43\x44\xdf\x58\x28\x12\xb6\xa4"
+  "\x30\xde\x16\xd7\x59\xbe\x33\x5b\x0b\x3d\xbc\x91\xd0\x6e\xda\x96"
+  "\xd5\x64\xe7\x3b\xc6\xfc\x7d\x94\xc6\x50\x35\x35\x16\x57\xd3\xbf"
+  "\x46\xb6\x93\x6f\x05\xc7\x8c\xf0\x86\xff\xad\x74\x3b\x9f\x5b\x5d"
+  "\x87\xe7\x43\xda\x63\xdc\xd6\x56\xef\xbf\x1d\xff\x33\xfd\x9b\xef"
+  "\xcf\xa4\x3d\x21\xdf\x6b\x8f\xe5\xff\x2b\x1d\xcb\xf9\x57\x72\x35"
+  "\x0b\x9d\xd7\x4a\xe5\x8b\xb8\x8d\x8d\x80\x55\xcb\x77\x73\xed\x7a"
+  "\x9b\xa3\x37\xfa\x6f\xe5\x3d\xf9\xc6\x50\x90\x7c\x8b\x3f\x64\x1c"
+  "\x07\xee\xb9\x40\x69\xbe\xc5\x7f\x90\xcf\x6a\x0d\x73\xb6\xd6\x3f"
+  "\xf7\x04\xdb\x69\x11\xbe\x8b\xcc\xe7\x7c\xb0\xdb\xf5\xad\x8c\x63"
+  "\x54\xe1\xcd\xdf\x52\x37\xeb\xc3\x8e\x33\xea\x6f\x6d\xe6\xfa\xbb"
+  "\x99\x1e\xc0\xa9\x61\xa6\xa2\xc9\xb1\x13\xa0\xe9\x63\x06\x7d\xf2"
+  "\x63\xe9\xb3\x35\x87\xe9\xc3\x71\x2c\x75\x8c\x17\x70\xcb\x01\x0d"
+  "\x74\xb3\x0d\xe0\x9c\x66\xec\x8b\xa6\x6d\xb9\x40\xe9\xbe\xc5\xfc"
+  "\x7d\x2c\xef\x2f\x6d\x79\xd6\x34\xfd\xd2\xb9\xba\xad\x17\xc9\xca"
+  "\xe3\xc6\x67\x21\x5b\x65\xbe\xa4\xf9\x46\x1e\xb3\x60\xc6\x88\x7d"
+  "\xf8\xdb\x8f\xbf\x3a\xe6\x3b\xfc\x1e\xc0\x78\x6d\x04\x0e\x1a\xc6"
+  "\xaa\x96\x7f\x15\x2f\x6a\x01\x8e\xd5\x60\xac\x4b\xba\xd2\x21\x47"
+  "\x11\x21\xbf\x47\x0b\x99\xf1\x6a\x3a\xe4\x88\xf7\x45\xf6\x54\x52"
+  "\xba\xee\xd9\x54\xb4\x1b\xba\xae\x1a\x73\xe9\x9e\x4c\xb2\xf3\x5e"
+  "\xe1\x4e\xe9\x8b\x5e\x31\xc4\xd4\x7d\x2f\xf7\xe5\xfb\x6d\xde\x3c"
+  "\x0b\xef\xa5\x78\x9d\x79\x06\x9f\xe7\xa1\x0c\xf4\x7f\x5f\xe3\xfb"
+  "\x63\x9b\xa5\xdf\x31\xcb\x7e\x77\x36\x3a\xec\xc3\x63\x62\x57\x3e"
+  "\xf1\x99\x4a\xfa\x3a\x11\x4c\x6f\xb6\x89\xc6\xd0\x31\x79\xaf\xb1"
+  "\x31\x14\x95\x67\x2a\xc8\x4f\x99\x16\x0a\xda\x60\x4f\x36\x31\xed"
+  "\xcc\x74\x3e\x8f\xe1\xbd\xaa\x69\x21\x11\x9c\xbe\xca\xc6\xdf\x07"
+  "\xec\x2f\xf7\xe3\x8d\xf4\x46\x07\x6c\xf1\x55\x41\x1b\xfa\x1e\xe9"
+  "\x84\xd5\x96\x9f\xca\xf2\x86\xb2\x59\x9d\x65\xdb\xf2\xad\xfc\xdd"
+  "\x5b\x6e\x33\x26\xad\xc7\xf4\x52\xd4\xe5\xb1\x32\xd2\x94\x1d\x5a"
+  "\x99\xdd\xb9\x4e\xe3\x78\x8d\x6d\x98\x37\x97\xe5\xa7\xe8\x6d\xf9"
+  "\x96\x28\x60\x83\xf7\xed\xf2\x3b\x85\x91\xa0\xf1\xdd\x9f\x16\xc8"
+  "\xef\x09\x12\x15\x6f\xf9\x50\xce\xca\x70\xf9\x6e\x3c\x7f\x2f\x41"
+  "\x64\xec\x9f\x92\xdc\x8f\x6d\x47\xa9\xaf\xfc\x09\xf0\xd3\x36\x27"
+  "\xcb\x73\xd4\x3e\x72\x92\xf6\x1c\xdb\x27\x95\x6f\x31\x3d\xa3\x90"
+  "\xb1\x68\xc6\xc8\x49\x23\x5a\x28\xa5\x1c\x7c\xab\xf6\x75\x2a\xff"
+  "\xc4\xb1\x00\x5c\xba\x80\xcd\x57\x79\x98\xf9\xc6\xd6\xca\xfe\x67"
+  "\x23\xa7\x48\x9f\xaf\xcc\x6d\xc5\xfe\x70\x0b\x1d\x73\xff\x85\x8e"
+  "\x45\xfc\xee\xc3\x17\x82\x56\xe5\xfb\x65\x65\xb8\x9f\x73\x9e\x0b"
+  "\xbc\x5a\x10\xad\xa5\xee\xf6\xdb\x79\xcd\x89\x39\xec\x0b\xb5\xfe"
+  "\xda\xe6\x34\xd7\x9a\xdf\xd2\x87\x8d\x1c\x4f\x40\x08\x07\xe9\x95"
+  "\x4b\x38\x5e\xa8\x4b\xb4\x67\xd3\x88\xd5\xbc\xcf\xb5\x6d\x36\xec"
+  "\xfe\x1c\x03\xee\x79\x03\xee\xc6\xab\xc1\x65\x9e\x39\x56\x25\xcf"
+  "\x7a\xd0\xa7\x25\xde\x28\x60\x47\x33\x97\x34\x41\xc7\xbb\x5c\xdf"
+  "\xf0\x3e\xe8\xf6\x06\xb4\xe3\x6d\x8c\x34\x11\xc7\x26\xd9\xa3\x63"
+  "\x7e\x3c\xef\x20\xc3\xcf\xcd\x75\x8e\xb6\x1d\xd2\x45\xb6\x1d\x6b"
+  "\x60\xde\x63\x73\xb1\x8e\xe3\xf5\x75\x79\x94\x7a\xfa\x4b\x02\xc4"
+  "\xf7\xea\x01\xe3\xd3\x3f\xf2\x79\x12\xf4\x44\x54\x38\x2c\x1f\x5d"
+  "\x0a\x10\xfb\xb2\xc8\x7b\xf6\xeb\x6f\xde\xd9\x67\x1d\xdd\x2f\x2c"
+  "\x36\xe9\xc7\xa8\x57\x54\xec\xc3\xd8\x1e\x55\x7e\x75\xce\xd9\x31"
+  "\x3e\x75\xa9\xe7\x68\xfb\x78\xf6\xa9\x13\x76\xe7\x90\x6a\xb9\x97"
+  "\x37\x72\x52\xbb\x67\x7b\x61\x80\x2a\x4b\x99\x7f\x36\xb1\x7f\xbd"
+  "\xd4\xb1\xdb\x3f\x0b\x66\x2c\x92\xbe\x79\xfc\xcd\x61\x7d\x45\xb4"
+  "\x6e\xeb\xd7\x64\x55\xf4\xd8\xfe\x41\x63\x6b\xbb\x4f\x78\x17\x15"
+  "\xf3\xdd\x29\x03\xb6\x0d\xb0\x5f\x10\x15\x8b\x8a\x03\xb4\x5d\xc5"
+  "\x33\xf4\xca\xe7\x5a\xce\x8f\x74\x64\x63\x2e\xdb\xce\x31\x0f\xd2"
+  "\x02\xb4\xed\xa8\xf0\x0c\xf0\xb5\xd9\x17\x15\xcf\x70\xb0\x4d\xb5"
+  "\xbd\x25\x60\x39\x16\x30\xf6\xd6\x64\xcc\x80\xc4\x3d\xb1\xce\x31"
+  "\xdc\xe5\xe8\xed\x07\x10\xac\x11\xb3\xce\xd0\x8e\xc7\x2f\x7b\xc8"
+  "\xd2\x01\x5b\xf0\xb2\x05\x36\xff\xae\xfc\xf4\x2d\xfd\xc8\x89\xbc"
+  "\x7e\x67\xe8\xd5\xf1\x11\x0b\x65\xe1\xcf\x1e\xbc\xb9\xf0\x3a\xc0"
+  "\xcd\xe1\x7d\xc7\x86\x0b\xbc\x6f\xf4\xea\x6e\x69\xab\xed\xa4\x21"
+  "\x3a\xe0\xf1\x19\xca\xd6\x7e\x34\x84\xf7\xfe\x90\x96\x5d\x10\x55"
+  "\x67\x89\xe6\xfa\x7e\x7d\x3f\x1a\x1a\xdf\xee\xab\x46\x2c\x80\x1d"
+  "\xf9\xfc\xbb\x32\x48\xb7\x14\xdf\xc7\xdf\x93\x7c\xcd\x21\x3c\xa9"
+  "\x42\xdc\xec\xb0\xa8\xf3\xfe\xd7\x52\x6c\x55\x8a\xef\xe4\xd9\x19"
+  "\xf8\x8d\xcf\x26\x8d\x73\x9a\x14\x19\x2b\x21\xf3\x9e\xe3\xfc\x7d"
+  "\xde\x98\xbd\x57\xbb\xc4\xc3\xb8\xe7\x1c\x5d\x7f\xe7\x6c\x86\xc1"
+  "\xf8\x14\xcc\x51\x67\x3c\x7c\x07\x3a\x40\xaf\xca\x78\xbc\x9b\x76"
+  "\x52\xfa\x2b\x3b\xc9\xde\x30\x9f\xfb\xf5\x9a\x53\xc9\xa2\x95\x18"
+  "\x5f\xdd\xcb\x72\x06\x9e\x00\xde\xdc\x1e\xf3\x46\x63\xe4\xbc\xcf"
+  "\x55\x22\x74\xdf\x73\x6c\x8b\xbe\xb6\xc4\xb7\x74\x3f\x4d\xe7\x3b"
+  "\xe3\x7c\x5f\x6c\x16\x05\x6b\x00\xaf\xa6\x1f\xd9\x01\x6b\xad\xbf"
+  "\x88\xf8\x0c\x60\x90\x6f\xe9\x01\x86\x5d\xc1\x73\xc1\x66\xd0\x47"
+  "\xcd\x09\x3b\x26\xf9\xc3\x27\xa8\x01\xf2\x3d\xad\x58\x44\x19\x0e"
+  "\xca\xfc\x49\xf6\x77\x97\x43\x2b\x50\xf7\xd4\x65\x5f\x3b\xcf\xce"
+  "\x8c\x7e\xf8\x2f\x48\x78\x27\xfd\xb3\x61\xe3\x19\x7d\x32\x69\xad"
+  "\xf8\x6b\xc7\xf7\x7d\x4b\xf7\x12\x8f\x0f\x97\xc7\x7b\x9a\xbf\x15"
+  "\x65\xcf\xc6\x8f\x0b\x97\x41\xde\x58\xc0\xfd\x61\xd7\xf9\x2f\x9f"
+  "\x4b\x76\x95\xa9\xde\xc9\xf7\x61\x5e\x2d\xdb\x05\x1a\xa9\xfd\xf2"
+  "\xd7\x7e\xc9\xb8\x06\xe8\xb5\xbd\xfe\x92\xbf\x24\xf7\xf3\x84\xec"
+  "\x83\xef\xd7\x35\xca\x73\xb0\x1d\xaf\x4e\x8b\xe8\x42\xe9\xb3\xaa"
+  "\x29\x3a\xf4\x40\x00\xbf\xac\x0b\xa4\x3e\x19\xce\xbe\x35\x55\x0f"
+  "\xd9\x52\xd4\xf8\x72\x5f\xd8\x5e\x49\x36\xc6\x31\x67\x74\x76\xc6"
+  "\xd5\x1c\x63\xfe\xae\x9d\xce\xe7\xac\xfd\x40\xef\x0e\x07\x29\xfe"
+  "\x13\x5e\xc0\x35\xee\x47\x38\x6b\x8d\xb9\xac\xb6\x2d\x63\x64\x9e"
+  "\x58\xe3\x20\xd3\xdf\x16\xf2\x9b\x5b\xa0\x7c\x98\x1d\xac\xa3\x6a"
+  "\x2c\xc2\x88\xb7\x57\x35\xc5\xa8\x5b\xad\xfc\x1c\xaa\xd2\x50\xbf"
+  "\x3a\x69\x7f\x53\xa1\x77\x3c\x50\xd3\xe8\x0f\xdb\x91\x02\xba\x0a"
+  "\xf3\x41\x4f\x7f\xe8\xb2\xf1\x4d\xc1\xaa\x3f\xc2\xa6\xee\xc9\x77"
+  "\x53\x4c\xdc\xae\xed\x3c\xad\xca\xab\xd6\x36\x55\x4d\xe6\x7e\x8d"
+  "\xb0\x83\xc6\x1e\x9b\xe0\x3b\x5c\x7c\xd7\x20\x94\xb1\xc3\x1d\xcc"
+  "\x78\xab\x4e\xc9\x4d\x55\x18\x76\xaa\xd4\xb7\x05\x61\xfe\xa6\x7b"
+  "\x65\x29\x9f\x97\x62\xdd\xd4\x93\xfb\xdc\xee\x79\x1d\xeb\x9f\xa2"
+  "\x59\x6a\x3e\xaf\xea\xd6\xf7\x5a\xae\x99\xcc\xbe\xa1\x4f\xb2\x6f"
+  "\xe8\xa3\xec\x9b\xf1\xcd\x9d\xd3\xf4\xba\xbc\xbb\x7d\x6d\xfd\x79"
+  "\x7d\xb6\xa2\xed\x0e\x37\x7f\x4f\xf4\x34\xed\x1a\x26\xef\x1f\x60"
+  "\x4c\xd4\xd9\xc2\xeb\x2d\xa2\xf7\x2b\xbd\xaf\x11\xe6\x01\x05\xf3"
+  "\xad\xba\x57\x39\x3e\x9f\xf1\xdd\x2e\xc0\xbe\x09\xba\xbc\x8e\xd7"
+  "\x0e\x6d\x68\x8f\xbf\x7b\xd8\xa5\x87\x76\x56\xf1\x58\x0d\xdf\x4f"
+  "\x39\x8a\x0f\x77\x6e\xe6\xfd\x5b\xb5\xce\xdb\x39\x0e\x7c\xaf\xd6"
+  "\x27\x9d\xbe\xd9\x29\xd2\x37\x3b\x56\xc7\x5e\x1b\x8e\x3b\xa5\x2c"
+  "\x8b\xcc\x8a\x3c\x3c\x0f\x65\x1f\x03\xc6\x77\x65\xc4\xd4\x7f\x3b"
+  "\x87\xb2\x9f\x4f\xe7\x19\xfb\x2a\xf0\x4a\xb9\xba\xbb\x0a\x7c\x8e"
+  "\x99\x36\x8a\xfc\x4e\x93\x47\x1c\xe5\x72\xd3\x57\x9d\x97\x67\xf0"
+  "\x5b\xe5\x3d\xed\x33\xc6\x1d\xa7\x9d\x5f\x1a\xfb\x19\xd9\xec\x17"
+  "\xdf\xee\xd9\x85\xb6\x0f\x4b\x7f\x1e\xa6\x01\xb7\x2d\x71\x97\xdf"
+  "\x4a\xda\x35\xa4\xeb\x2c\x65\xa7\x3c\x9f\x50\xbe\xa2\xbb\xc6\x99"
+  "\x3c\x82\xfe\xf6\x54\xf1\x12\x5f\xff\xe5\x91\xa1\x24\x79\xa0\x4d"
+  "\x38\x7a\x0f\xae\x66\x9e\xdc\x35\x37\x96\x4e\xd3\x23\xba\x4b\xe9"
+  "\xa0\x9d\xb9\x42\xca\xfa\xce\xdc\x6f\xb7\x27\x76\x1d\x32\x6d\x11"
+  "\x45\x67\x3b\xf4\xcb\x9e\x0d\x92\xd6\x5e\xcd\xcd\xb1\x2c\xd6\x94"
+  "\x73\x3c\x9e\xea\x55\x1c\xeb\x28\xe2\xd5\x6a\xa3\x7c\x1f\x0e\xf3"
+  "\xac\xee\xd5\xea\x4e\x17\x93\xa5\xa0\x98\xcf\x8f\x16\xe5\xf0\xfa"
+  "\x4a\xb8\x60\x0b\x64\xc2\x3e\x81\x9c\xaf\x5d\x40\xb6\xa7\x0a\x01"
+  "\xdb\x95\x9d\xc5\xb1\x88\x38\x0e\x11\xc7\x13\x8b\xba\xb2\x33\xf1"
+  "\xdc\x17\xf6\x9c\x5d\xd8\x35\x2f\xfb\xa0\x44\x3d\x02\xfa\xf8\x24"
+  "\xc7\x43\xb2\xf8\x83\x61\x5a\x7b\x96\xd2\x38\xd6\x51\xa4\x62\x51"
+  "\x7e\x63\xe8\x73\xb9\xb6\xe8\x53\x0c\x7b\x5a\xa7\xfe\xa0\xb9\x43"
+  "\xcf\x58\x94\x83\x39\x7e\x92\xea\xf7\x79\xa1\xfa\xad\xf0\x66\xfc"
+  "\x95\x8e\x1b\x54\x57\x2e\x71\xdf\xf3\x83\x08\xe0\xeb\xde\xdb\xf7"
+  "\x47\xbd\xb7\xef\x53\xf7\xe8\x8e\x51\x79\x89\x68\xf1\xc3\x36\x66"
+  "\x9f\x48\xbe\x53\xc8\x3e\x2e\xdc\x47\xee\x1f\xb7\xfd\x6f\x17\xce"
+  "\xca\xd8\x4d\x11\xbc\xbb\x8a\x8c\x3a\xad\xa8\xd3\x7a\x8c\x2e\x7b"
+  "\x6f\x97\x7d\x6f\x0c\xa9\xba\x05\xf2\x99\xeb\xc7\xd0\xc1\xe8\x73"
+  "\x27\x1d\xd0\x77\xee\x1f\xf7\x3f\xc2\x34\x01\x0d\x8c\xbe\x3a\x3a"
+  "\x8c\x7e\x72\x1f\xff\x15\x9c\xba\x13\xfd\x44\x5f\x65\x3f\x3b\xd0"
+  "\xcf\xa3\x85\x44\xe1\xca\x1d\xde\x6f\x32\x6f\xdf\xc7\xeb\x43\xd7"
+  "\xbf\xc3\x8e\x2e\xf3\x12\xd6\x81\xd6\x77\xca\xbd\x96\x97\x61\x9b"
+  "\x94\x07\xb1\x1e\x0c\x8a\x16\xb6\xf7\xfd\xc5\xf8\x8b\x54\xcb\x6f"
+  "\xb1\x4a\xfb\x98\xbf\x9b\xb9\x04\x7d\xd2\xbf\xa2\xf2\x16\xd1\x02"
+  "\xdb\x34\xec\x8f\xa0\x4c\x21\xfa\x8f\xf5\xe3\x69\x03\x7f\x2e\xbb"
+  "\xf6\x6b\xd5\x2f\x5b\x11\x65\x7d\xf2\xc4\x46\x8b\xff\xc4\x46\x32"
+  "\xfb\xf2\x34\xca\xa1\x3f\x0e\xc0\x92\x71\xe3\x75\xf4\x73\x17\xf0"
+  "\x0c\xc7\xf4\xa9\xa1\x35\x0c\x98\x9f\x51\xef\x3c\x4a\xd9\x79\x0e"
+  "\xfd\x38\x47\x0e\x6f\x39\xec\xaf\x47\xd8\x5e\xdc\xfd\xe8\xf5\xf9"
+  "\x04\xbe\xaf\x56\xdf\x2b\x51\xb1\x55\x6e\x3a\x43\x7b\xd6\x9a\xf1"
+  "\x53\x74\x8e\x3f\x95\xb1\x68\x16\xf3\x91\x8c\xa5\xc2\x73\x46\x3b"
+  "\x78\x86\xfd\x53\x56\xa2\x8d\xf6\xec\xbe\x12\x1f\x8f\x8a\xbf\x82"
+  "\x77\xfe\x8e\x4e\x16\xef\x09\xa0\x5e\xbe\x00\xcd\x18\x3e\xec\xb9"
+  "\x49\xfc\xcb\x34\x4c\x7a\x7f\xe3\x5d\x1a\x83\x36\x66\xf3\xda\xb7"
+  "\xae\x3c\x68\x79\xe1\x5d\x1a\x7a\x6d\x3a\x65\xcf\xfe\xee\xf4\x37"
+  "\x9f\x05\x30\x3c\xf4\x2d\xf3\x0c\xd5\x54\xc4\xcb\x98\x26\x75\x99"
+  "\xd2\x83\x35\xf9\xbc\xff\x7e\x6d\xed\xd6\xa8\xb8\x4d\x1e\xb1\xf1"
+  "\x1a\xeb\xcd\x32\xf1\xc0\xb3\xa3\x3b\xdc\xaf\x9d\x0e\x35\x07\xba"
+  "\x83\xb5\xf9\x35\x19\x4b\xcb\xb5\xe5\x35\xf6\xf1\xdb\x51\x7a\xc4"
+  "\xc1\x71\x8d\x31\x77\xee\x0d\xd1\xb2\xdd\x94\xe6\x3a\xcb\x7b\x32"
+  "\x53\xe9\x48\xb5\x93\xf6\x60\x4d\x2e\xda\xb2\x33\xb7\x5d\x60\x7f"
+  "\x02\xa5\x43\xd8\x26\xe5\x7b\x6c\x62\x59\xb6\x7d\xeb\x6b\xa6\x0d"
+  "\x5f\xbb\xb6\xec\x22\x59\xd4\x77\x23\x6a\xcb\x26\x69\x22\xb2\xdd"
+  "\xa2\x17\x56\x73\x6c\xa1\xcc\x0a\x1f\xc7\x16\x32\x63\xed\x48\xdb"
+  "\xa7\x14\x32\xd7\xe6\xe8\xbd\x79\x29\x0d\xe5\xb8\x60\xb6\xa0\xb2"
+  "\xe5\xd4\x7c\x5d\xbb\x1f\xf8\xd9\x8d\x33\x74\xbb\x8a\xbf\xb3\x27"
+  "\x54\x73\x01\x6d\xa9\xfc\xcf\xa3\x58\xc3\x48\xb8\x4b\x69\x48\xf5"
+  "\x05\xca\x66\x3b\xa8\xe0\x2b\x65\xb3\xf1\xba\x70\x6a\xab\x4d\x44"
+  "\xff\x57\x36\xed\x3e\xd3\x15\x37\x2c\xb8\x8c\x63\x8d\x09\x47\x77"
+  "\x77\x84\xb7\xf6\x95\x7e\x34\x32\x06\x84\xfa\xae\x18\xd1\xf6\x4a"
+  "\xb2\xf2\x77\x34\x79\x2f\x8f\xf7\x86\xf9\x2e\x8d\x9a\x43\xde\xc8"
+  "\x35\xe3\x2a\x75\x7b\x36\xe7\x55\xeb\x1d\xbd\x27\xd6\x5f\xc1\x76"
+  "\x9f\x6f\x05\xcf\x19\x6f\x6c\xe7\xfb\x3b\x5d\x6b\x9c\x37\x96\x73"
+  "\x1e\xa7\xb1\x7f\x79\x8e\xa4\xe5\x1b\x87\x79\xdd\x63\xac\x19\x3f"
+  "\xd1\x3a\xd3\x94\x0d\xc3\x73\x19\xe3\x50\xa3\xf6\x91\xfb\x00\x97"
+  "\x13\xe6\x7c\xc6\xf3\xba\xfa\x86\xe7\x1b\xad\x01\x8b\xdf\x71\x15"
+  "\xfc\xec\xc6\x37\x70\x2d\x6d\x1c\x2b\xc9\xf3\x8b\xfe\xe6\xfc\x26"
+  "\xbf\xd1\xb0\xbe\xdf\x03\xcb\x56\x51\xff\x19\xdf\xe7\x33\x6f\x79"
+  "\x0f\xa3\x45\xcd\xbb\xbf\x98\xd4\x75\x46\x95\x23\xe9\x2d\xbf\xbf"
+  "\xc6\x6b\x0c\x0b\xe6\x60\x15\x23\xac\x55\xcd\xbf\xe6\x1d\xe3\x5f"
+  "\xcc\x89\x69\x67\x43\xe7\x3c\x8a\x36\xd8\x57\x82\xe1\x2b\xdb\xe4"
+  "\x17\x63\xb8\x0d\x5e\x5b\xa9\xf9\xf5\x17\x63\xae\x62\x8b\x65\x33"
+  "\x7d\x75\x63\x3d\xe9\x6f\xfd\xab\xa2\x6f\x29\xa5\x8e\xd8\x4e\x8e"
+  "\x4f\xca\x03\x56\xf6\x53\xd5\x96\x92\x0d\xed\x7f\xc6\xf9\xcc\xeb"
+  "\xbe\xe1\xbc\x17\xf7\xe6\x48\x3f\xcf\xdb\x1d\xf9\xe9\xd3\x78\xad"
+  "\x2f\x6d\xf1\x37\xb5\x61\xa8\x87\xb4\xcc\x8f\xcf\x85\xad\x5b\x57"
+  "\xd3\x50\xfe\xce\x21\xd2\xe5\xb7\xc1\x82\xdf\x5b\xd8\x3e\x38\x8b"
+  "\x1c\x83\xb7\xb3\x8f\xfd\x9b\x53\x02\x96\x06\xe5\x17\xc6\xed\x57"
+  "\xbe\x15\xe0\xf8\x68\xef\x5d\x0e\xf4\x50\x63\xf5\xe6\x57\x78\xcf"
+  "\x8e\x79\x5f\x67\xee\xe5\x07\xe8\xcd\x66\x79\x1e\xc8\x7e\xc4\x8b"
+  "\x79\xbe\xae\x9c\xdd\xe5\x7b\xf3\xe6\x57\x06\x2e\x5f\x1d\x29\x26"
+  "\xde\xab\x3e\xbe\xa7\xaf\x68\x42\x7b\x07\x03\xf4\x46\xd8\xd8\x8f"
+  "\x69\x92\x7c\xc5\xf6\xee\x3f\xf3\x1a\xec\xaf\xbe\xcd\x28\xc7\xf3"
+  "\x44\x41\x29\xe5\x28\x1b\xbe\xb2\x54\x07\xff\x74\xf5\xff\xcd\x87"
+  "\x79\xaf\x2f\xa9\x4e\x84\x89\x23\xeb\x54\x54\x1c\x94\x7e\x5c\x15"
+  "\xfb\x73\xf0\x0b\xdb\x7e\xdb\x6c\xfc\xa6\x83\xe7\x8a\xf1\x6b\xc7"
+  "\x6f\x21\x7e\xb3\x44\xc5\xdb\x1a\xf3\x25\xd6\xb0\x0e\xac\x13\xd2"
+  "\xda\x32\x2a\xea\xba\xbb\xff\xc7\xb4\xf1\x6f\x78\x8c\x94\x5f\xea"
+  "\xde\xa3\x0d\x41\xd8\x67\x58\x29\x2f\x8b\x88\xcb\xda\x2d\x7c\xcf"
+  "\x66\xef\x51\xd7\x6e\xf6\x07\xd9\x9b\xf0\xfd\xf3\xbd\x87\xf1\x07"
+  "\x49\xfb\x65\x1e\xfe\xa0\x33\xf6\x1e\xed\xfa\xfb\xe5\xe1\x76\xcf"
+  "\xde\xa3\x01\xda\x2b\x6d\xac\x6b\xd3\x89\x7b\xd5\x5d\x0a\x5e\x17"
+  "\x65\x2c\x71\xab\xfe\xbe\xe5\xc5\x7b\x9a\xc8\x78\xab\xc9\xe8\xaf"
+  "\x1b\xef\x76\xcd\x85\x79\x2d\x03\x34\xe9\x87\x3e\x67\xec\xcf\xe1"
+  "\xfe\x32\xbe\x6d\x19\xdb\x66\xc7\xde\x7d\x64\x98\xdc\xff\x60\x46"
+  "\x25\xc3\x23\x31\x7c\x82\xdd\xa4\xa7\x41\x27\x3e\x37\xb2\xb4\x01"
+  "\x86\xb2\x83\x50\x1e\x30\xcc\xf2\x9d\xb4\xef\xc7\xdf\x1c\xc0\x98"
+  "\xa2\x1c\xd6\xc4\x69\xe6\xbd\xca\x76\xcf\x2f\x0f\x7c\x5a\xa4\xce"
+  "\x0f\xb8\x6e\x28\xa6\x2e\xc7\x1b\x48\x56\x1f\x6d\xa6\xa9\x36\xb7"
+  "\xcd\x3e\x4d\x7b\xff\xa4\xda\xfd\xe5\xbe\xee\x64\xa9\x7c\x20\xec"
+  "\xbb\xea\x00\xc7\x24\x60\x7b\x68\x9c\xbf\x7f\x88\xfc\xd5\x3a\xe6"
+  "\xfc\x4a\x6f\x4e\xb9\xf0\x9d\xa6\xff\xb1\xa0\x31\xdc\x72\x8d\xf3"
+  "\xe1\xff\x90\xe7\xef\xe2\xb2\x9b\xfc\x65\x77\xc9\xef\xfb\x9e\xa3"
+  "\x5f\xbd\xee\x0f\xca\x38\xd9\xfc\xfc\x02\xe7\xb3\xef\x03\xcf\x0d"
+  "\x1c\x37\xce\x5c\x63\xeb\x28\xbb\x87\xd3\x91\xe6\x0f\x05\x65\x7c"
+  "\xba\x2e\xdf\xec\x8a\x2a\x25\x53\xbf\x7a\x58\xde\x7d\x67\x7c\x23"
+  "\x3f\xf6\x31\xce\xba\xb7\xa2\x8a\xfb\xe0\xc2\xfa\xcf\x1f\x69\xf7"
+  "\xb1\x4c\x68\x2b\x78\xaf\xf0\x57\xc3\xc0\x77\x42\xaf\xa8\xa8\xba"
+  "\xc6\x3e\xc8\xbb\x13\xae\x88\x38\x17\xcc\xa8\xa8\x62\x9b\x64\x6b"
+  "\x79\x8f\xb4\x89\xd5\xc2\xd7\x96\x59\xe9\x6d\xf7\xfc\x2a\xef\xd3"
+  "\x52\xfa\x2f\xf0\xe1\xaf\xf2\xcc\xbe\xef\x31\xfa\x8e\xb6\xe4\xfa"
+  "\x69\x44\x95\x8a\xc7\x87\x32\xdd\x7e\xe7\x99\xc7\x99\xed\x01\xf6"
+  "\x1b\x35\x68\x71\xa2\x73\x6e\xb8\x36\x3c\x4e\x7c\x87\x36\x3a\x54"
+  "\x1b\xfb\xc6\xfd\xd7\xda\xd8\x37\xee\x6a\x6d\x40\x37\xfc\xe0\x0c"
+  "\xed\x3b\x7a\xed\x6b\xc7\x7d\xdb\x25\xaf\x78\x2b\xdd\x4a\x67\xbe"
+  "\x3d\x36\x8a\xf5\x5b\xc4\xfe\x96\x57\x7e\x8b\xc7\x42\x6e\x7f\x20"
+  "\x42\x11\xef\x12\x77\x43\xe9\x65\xf2\xad\xf8\x33\x35\xd3\x5b\x72"
+  "\xdf\xa8\xa1\x84\xd7\x6c\x6f\x35\x75\x54\x56\x06\x3a\x2c\xfb\x1c"
+  "\x4c\xef\xdd\x1c\xfb\x30\x86\xcf\x1a\x43\x7f\x26\xff\x6c\xde\x5f"
+  "\x6d\xe2\x7d\xed\x26\xe8\x07\xaf\x0e\xdd\x00\x1b\x3d\x2a\xe9\x01"
+  "\xfb\x45\xad\xb7\x76\x94\xca\xf5\x56\x50\xde\xf9\xbb\x01\x76\x6f"
+  "\xba\xf0\x14\x65\xf1\xde\x77\xb4\x23\x5f\x6b\xf7\x50\x1e\xc7\x21"
+  "\xe4\x7d\x67\x61\x77\x8e\x9b\x1e\x49\x15\x72\x3d\x05\xdb\x9f\xe3"
+  "\x11\xfa\x43\x01\x8a\xc2\x8e\xae\xbe\x44\x59\xd5\xb0\x3d\xa1\xb3"
+  "\xed\xac\xd7\x6b\x8c\x78\x84\x9b\x2f\x75\xc5\x23\xdc\xc3\x7b\x3d"
+  "\x27\xf0\x7c\x89\xac\xd1\x8a\x1d\xa5\xbb\x2e\xd1\x90\xdd\x2b\x28"
+  "\x7b\x17\xef\xe5\xfd\x4d\xd9\x3e\x6c\x57\xc8\xd8\x84\xcf\x67\xf3"
+  "\x7e\x7e\x97\xed\xb3\x92\x63\xa6\x76\xea\x2d\xab\xdc\x03\xb9\x26"
+  "\x7a\xbf\x2d\xe7\xc1\x88\xb7\xe2\x60\xc4\xbe\x3f\xa7\xa3\x72\xdb"
+  "\xec\x00\xbd\x35\xa6\xc3\xf2\xab\x03\xc9\xc6\xd6\xf4\x6d\xda\x1e"
+  "\x13\x4f\xf2\xd3\x21\x4a\xbf\x03\x56\x59\x77\x3c\x11\xdd\x95\x4f"
+  "\x23\x5a\xc9\xa9\xfc\x15\xae\xc3\x9c\xf8\x76\x80\xcf\xcf\xcb\x17"
+  "\x91\x23\xba\x6b\x56\x8a\xeb\x0d\x4a\xe5\x6f\x3f\xf3\x5f\xf9\xd7"
+  "\xa2\x65\x44\x11\x39\xf9\xfc\x81\x7d\x1a\xb4\x35\xb2\xfc\xfb\x43"
+  "\xca\xc8\x19\x0b\x7b\x8a\x72\x36\xba\x57\x7b\x68\xf1\xb3\xcf\x2f"
+  "\x2a\x9e\x53\xb2\xe0\x99\x05\x45\x0b\x4a\x56\xc9\xb0\x01\x43\xe5"
+  "\x7f\x0f\xde\x3a\x77\xa6\x3c\x74\x8e\xb1\x2f\x86\x74\xed\xc7\xfd"
+  "\x7a\x41\x94\xf7\x0f\xae\x89\x5e\xbf\x1e\x65\x9c\xa3\x05\x77\xcb"
+  "\x73\xa5\x5f\x97\x05\x2c\x8d\xd2\x77\x68\xb3\x8a\x23\xd3\xa2\xfc"
+  "\x18\x54\x39\xdd\xfb\x36\xc7\xe8\x19\x77\x8a\xde\xcd\xe7\xf3\x10"
+  "\x8c\x55\xb1\xbf\xec\x0c\xc1\x0e\x19\xc7\xe7\x2c\x0d\xbc\x97\x21"
+  "\x6d\xdf\x5f\xff\x4d\xce\x61\xe7\x64\x4c\xa5\xbd\xa7\xf0\xce\x7e"
+  "\xef\xba\xc8\xdf\x15\x7d\xde\xb1\x57\x7f\xde\xf1\x3f\x84\xc8\xdf"
+  "\xa9\x9f\x2f\xdc\x25\xce\x17\xee\x14\x5e\xad\x09\x32\xd6\xff\x0c"
+  "\xfd\x3a\x1a\xf1\xd0\xf7\xf0\xd7\xab\x2b\x86\xc0\xfe\x8c\xdc\x66"
+  "\xd1\x81\x3f\x5d\x78\x07\x06\x63\xce\xd0\x38\x4f\xde\xd9\x28\x5e"
+  "\xca\xbe\x54\xfb\x27\x73\xdb\xa2\x72\xe0\xf9\xa0\xab\x30\x15\xe5"
+  "\xa3\x0a\x97\xfd\x73\xfc\x1b\x4e\x93\x3a\x37\xdd\x3f\xdb\x27\xf7"
+  "\x8c\xf7\x7f\xc3\xf5\xf8\x9c\x8d\x6d\x68\x19\x8b\xd5\xf2\x76\x2b"
+  "\xfb\xe1\xb1\xfd\xbc\x3b\x93\xec\xde\x4c\x4a\x6f\xf7\xec\xdf\xd4"
+  "\xe9\x63\x61\x57\x73\x2a\xcf\x6b\x1c\x3b\x18\x3a\xa7\x9d\xe7\x48"
+  "\xc6\x83\xf9\x14\x30\x0f\xf2\x19\x9c\xba\x57\xb4\xbf\x1e\xf6\xe3"
+  "\x98\x6b\xd7\xb9\xfb\xeb\xe5\xfc\x61\x71\x89\x11\x9b\x68\xb6\x3c"
+  "\x1f\x55\x3e\x87\x56\xc8\xa5\x53\xf5\xe7\xdd\x91\xf2\xfc\x7c\xc5"
+  "\xd9\x5a\xc8\x8d\xbb\xe6\x32\xa5\xeb\x5e\xe7\x28\xb6\x63\x1a\xca"
+  "\xe4\xb9\x72\x1a\xea\xd5\xf1\xb9\xb3\xbc\x97\x27\x63\x51\xff\x99"
+  "\x6a\x2e\x92\xb5\x99\xde\xc9\xe1\xbd\xf6\x2e\xda\xbe\xf3\x2a\x9f"
+  "\xad\x88\xca\x01\x85\xb6\x32\xcb\x46\x86\xa1\x5f\x3a\x37\xc6\xac"
+  "\x87\xb9\xbb\x17\xd7\x3b\x45\xef\xac\x92\xf5\xb8\xac\xfc\x8e\xa1"
+  "\x7d\x16\xe6\xb1\x83\x5c\x3e\x82\xf7\x3d\xba\x3d\x4f\x40\xde\xa2"
+  "\x2b\xa2\x75\xc8\x9b\xa9\x7b\xb7\xcd\x46\x5a\xbe\xdc\xe3\xc5\xba"
+  "\x5c\xc6\x3b\xb1\x2f\x2a\xf6\x07\xfe\xea\x93\xf8\xb0\x1f\x6b\x09"
+  "\x74\x93\xb4\xfb\xde\x69\xd8\xf3\x37\x19\x23\x1b\x63\xf8\xee\x6c"
+  "\x83\x6f\x0c\xfc\xde\x9d\xd3\x56\x79\xfb\xbe\x36\x7b\x65\x71\xc8"
+  "\x92\x46\x47\x1c\xec\x77\xff\xb6\x76\xc4\x71\x19\x6b\x87\x77\xb3"
+  "\x03\xd6\x5b\x0c\x9f\x5a\x55\x8f\xcf\x76\x60\x8f\xb6\xa6\x3a\xec"
+  "\x53\x90\x3f\xc5\xf4\xaf\xe0\x6f\x7f\xf3\x19\x4f\x80\xde\xd1\x98"
+  "\x6e\xe0\xfb\x03\x72\x9f\x7f\xfd\x93\x2d\xe8\x4f\x4f\xf6\x81\x63"
+  "\x3a\xf3\xfd\x06\x1b\x9e\xc5\x0a\x31\xc6\x16\xc9\xb1\xd4\xc8\x7b"
+  "\x8d\xf2\xbe\xfc\x28\x23\x66\x8b\xd3\x88\xe1\x32\x94\xdf\xd5\x7d"
+  "\xfb\x77\x3b\xef\xff\x73\x9c\x1a\xf6\x1d\x88\x1a\x7e\x75\x32\x7e"
+  "\xcb\x05\x75\x3e\xca\x7e\x75\xbc\x3f\xc8\xf7\x03\xf9\x0c\x13\xf5"
+  "\x5a\x3a\xfd\x1c\xe5\xbd\x98\x77\xc3\x66\xdc\x96\x76\xcf\x7b\xd6"
+  "\x4e\x7f\x1d\xf4\xbd\xcd\x5b\x59\x18\xb2\xbf\xad\x85\xbc\x15\x75"
+  "\xc8\xd3\xa0\x9b\xf2\xaf\xba\xa6\xe3\x78\xb4\xcb\xc9\xa2\x67\x3a"
+  "\x67\x73\x3c\x0b\x8e\x0b\xa6\xfc\xe4\xdf\x5b\x67\xdc\x1f\x4f\x3d"
+  "\x47\xef\x8d\xef\x3a\x4b\x8c\x1a\xfb\x60\xef\xed\x53\x76\xd8\x7b"
+  "\xfb\xe4\x3e\x58\x65\x65\xde\x9b\xab\xc3\x96\xba\xd5\x01\x8b\xba"
+  "\x27\xf0\x1e\x2c\xb0\xdf\x37\x99\xfe\x28\x28\xc7\xf1\x1a\x92\xc6"
+  "\x4c\x12\xde\xd1\xfd\x15\xcc\x3a\xb9\x87\xd1\xb5\xae\xa9\x53\xe7"
+  "\x64\xeb\xfb\xcd\xd6\x79\x0e\xcc\x5c\xe2\x95\xbe\x15\xc5\x17\x78"
+  "\x3f\xac\xa7\x5a\x63\xa9\x32\x86\x5f\xe4\x8d\x67\xe2\xdf\x33\xf9"
+  "\x5d\xd1\xac\x6e\xa8\xb9\xb7\xbe\xc5\xa2\x07\x6c\x29\x24\x5c\xb5"
+  "\x22\xc4\xf1\xe0\x60\x5f\x05\xfd\x98\x53\xd1\x86\x80\x7e\xe8\x85"
+  "\x3a\x73\x98\xf6\x4a\x86\xea\x3e\x93\x38\x79\xee\x17\x2e\xb6\x2b"
+  "\x83\xec\xdb\x71\x81\x50\x2e\x03\xe5\x36\xd7\x97\xb5\xb2\x7f\x4a"
+  "\x36\xc7\x59\x6b\x36\xda\x0e\x66\x8c\xee\x3f\x38\x9d\x66\xa3\x4d"
+  "\xf0\x8f\x67\xf6\xb5\xcb\x76\x5d\xed\xd5\x6c\x0c\x35\xe7\xe5\x50"
+  "\x77\xeb\x14\x5e\x87\x0e\x47\xfb\x53\x05\xe3\xff\xfe\xe6\x88\x25"
+  "\x4c\x1d\x96\x5e\xe2\x9f\xdc\xa5\x14\xf1\xf4\x12\xd1\xd5\x18\xaf"
+  "\x36\x07\xec\xd8\x63\xd4\x18\xa9\x97\xbe\x1f\x90\x59\x5b\x79\x48"
+  "\x5c\xf0\x47\x0e\x48\x5f\x58\x75\x67\xfc\xfd\x17\xfc\x91\x8f\xa8"
+  "\xb1\x38\x48\xac\x17\x4e\xd1\xfb\x32\xd6\xe9\xf0\x62\x37\x71\x4c"
+  "\x4f\xe4\x3b\xd5\xfc\xf7\xfe\x26\xe3\x77\x96\x68\xcb\x8e\x3b\x33"
+  "\x7a\x70\xf9\xe2\x67\x4b\x16\x3c\xbf\x78\x58\xee\xbc\x15\xf3\x8a"
+  "\xb4\x47\x94\x2b\x5d\xdc\xbc\x94\xd6\x15\xfb\xf8\x37\x72\xae\x60"
+  "\x1b\x84\x63\x20\xcb\xf8\xc7\x9e\x51\xd4\x19\xfb\x98\x6d\x91\xff"
+  "\x03\xf1\x8f\x4d\x1b\x83\x63\x1f\x77\xed\x61\xff\xd6\xd1\x29\x03"
+  "\xfa\x27\xed\xfc\xce\xf7\x24\x75\xcf\xfb\x55\x2c\x47\x7b\xa4\xdf"
+  "\xd9\x6f\xbc\xb1\x71\x7f\xd8\xc7\x8e\xf7\x3d\x90\xbe\xcf\xbc\x93"
+  "\x0a\x5e\xc4\x5c\xf1\x9b\x83\x5d\x77\x64\x7e\x03\xfd\xff\xbe\x55"
+  "\xc9\xaf\x2c\x7b\xdc\x3c\xeb\x35\xbe\x31\x25\xcf\xa6\x75\xcf\xc5"
+  "\x90\xda\x5f\xf9\xcd\x7f\xec\xd1\x7b\xa5\xa9\xbd\xfd\xdf\x92\x79"
+  "\xff\x4a\xc9\xe6\x27\x86\x6c\xfe\xd6\x71\xb5\xf3\xf8\x2e\xd9\xf8"
+  "\xed\xcc\x2e\xb9\xfe\xc2\xac\x3b\xf3\xdb\xce\xf2\x0d\x3b\xf7\xa6"
+  "\x33\xf4\xc1\x02\xde\x73\xc1\xf3\x00\x3c\xcb\x7b\x9f\xca\x17\xfd"
+  "\x83\x61\xc6\x33\xda\xf8\xe0\x26\xe3\xf9\xe6\x33\x74\x20\x6a\x3c"
+  "\xf7\xc3\xf3\x57\xc6\x33\x64\xf6\x40\x83\xf1\x9c\x85\xe7\x0f\x8c"
+  "\x67\xe8\xf8\x03\xbb\x8d\xe7\xbe\x78\x7e\xc1\x78\xfe\x3e\x9e\x17"
+  "\x19\xcf\x90\xc1\x03\x8f\x1a\xe7\xa2\x69\xa7\xe9\xc0\x84\x6b\xb7"
+  "\xbb\x0f\xa4\xab\xb3\xb7\x03\xb9\xd0\xf5\xc6\x5d\xb5\xce\x34\xd8"
+  "\x84\xef\xd7\x99\xf4\x45\x3a\xef\x0d\xa6\x21\x1d\xcf\x6f\xe4\x77"
+  "\xa5\xff\x36\x64\x94\xf7\x42\xcf\x0d\x8d\x49\x6f\x31\xd2\xf7\xc1"
+  "\xbe\x2f\x8b\x49\x3f\x69\xa4\xfb\x50\xfe\x40\x4c\x7a\x93\x91\x7e"
+  "\x22\x40\xbb\x36\xc5\xa4\xd7\x1b\xe9\x41\xd3\x0f\xc1\x48\x3f\xa8"
+  "\xd2\x3f\x60\x9f\x81\x71\x31\xe9\xfb\x8d\x74\xe8\xff\xdf\x0e\x89"
+  "\x49\x97\x7a\x65\xab\xbc\xb7\x65\x13\x47\xca\x58\xb6\x3e\x98\x14"
+  "\xa0\xd7\x63\x71\xde\x6e\xd4\x9d\x15\xa0\xaa\x99\x31\xe9\xc6\xfd"
+  "\xea\x0f\x4a\x02\xd4\x1c\x9b\xde\xad\xed\x9b\x52\x45\xdd\xf9\x69"
+  "\xa7\xf3\x37\x79\xa4\xff\xa3\xb4\x19\x7f\xf7\x3e\xdf\xe9\xb2\xed"
+  "\x16\xa7\xb4\x72\x21\x4e\xd1\xef\xaa\x0c\xbf\xbf\x21\xec\x87\xc5"
+  "\x77\xe3\x9a\xe9\x77\xeb\xe4\x7d\x29\x8e\x65\xc8\xf7\xe5\x56\xf3"
+  "\x7d\xb9\xdf\xc9\x38\xcf\x23\x4a\xdd\x2a\xce\xa1\xf2\x2b\x6d\x95"
+  "\x6b\x74\xe3\xfc\x12\x65\x86\xf1\x9e\x25\xc3\xe1\x7d\x3c\x7f\xc9"
+  "\x65\xe9\xeb\xc8\x6b\x24\x4e\xe3\xb5\xaa\xbc\x43\x15\xb3\x56\x52"
+  "\x7a\xff\x77\xef\xeb\x7c\xc7\xdd\xa3\xd6\xf3\x5b\x55\xfc\xcc\x56"
+  "\xf6\xb9\x89\x2d\x1b\xa0\xdf\xc9\x75\x6e\xaa\x23\xe3\xf5\x76\xcf"
+  "\xef\xbc\x5d\xf7\x7a\x3e\x68\x31\xd2\xab\x90\xbe\x2f\x26\xfd\x78"
+  "\xf7\xba\x1d\xfa\xce\x3e\xa0\xae\xe3\x92\x08\x45\x2e\x89\xf0\x96"
+  "\xff\x04\xde\xf3\xe5\x1d\x95\x5b\xa2\xde\x01\x3e\x23\x5e\xc4\x97"
+  "\x91\x15\x22\x08\x9d\xcd\xf1\xf5\xaf\x9f\x16\x0a\xd2\xb4\xe2\x76"
+  "\xb1\xf9\x19\xf6\x9f\xbb\x28\x63\x27\xb9\x5a\x39\x96\x2f\xfb\x64"
+  "\x85\xf8\xdc\x27\xbd\x11\x73\xdc\x9e\xf9\x9c\xff\x39\x4d\x2d\x84"
+  "\xed\x5d\x18\xa5\x3d\x80\xbd\xfb\x19\xd3\x1f\xf2\xf7\x53\x3a\x7d"
+  "\x14\x81\x03\xb7\xe7\x92\xdf\xc7\xf8\xbd\x8c\xcd\xc1\xdf\xfd\x12"
+  "\x15\xfb\xf3\xc4\x1f\xd8\x7e\xad\xa8\xb5\xad\x23\xf0\xd5\xef\x37"
+  "\xe0\xd9\xab\xfe\x90\x87\xf4\xee\xfa\xa4\x64\xf9\xf7\x3e\xa5\x6b"
+  "\x34\xa7\xd2\x17\xbf\xf7\x89\x5f\xf0\x1d\x9d\xdf\xf3\xfd\x97\x29"
+  "\xb0\x95\x93\xfa\x55\xad\xdd\x4d\x96\x8e\x4a\xd8\x26\xe7\x0e\x5a"
+  "\x94\x7e\x3a\x58\xa7\x5b\xd2\xd6\xf1\x7e\xa1\x8c\x91\x5f\xe9\x2c"
+  "\xde\xbf\x38\x6c\x69\x58\xdd\x4c\x6b\xbe\x4f\x8e\x59\x61\xf6\xff"
+  "\x3e\x38\xb2\x4f\x09\xc7\x6b\xac\xcc\x83\xdd\x69\xf9\x2d\xf2\x3f"
+  "\x5e\x7c\xd0\x12\x91\xf6\xca\xc1\x3a\xb9\xc7\xe4\x75\x4e\xe2\x39"
+  "\xc4\x7f\x22\xca\x36\x73\x3a\x6c\xe6\x51\xd0\xff\x69\xd1\x95\x85"
+  "\x99\x91\x65\x85\xd7\xef\x5e\x4a\xe9\xd1\x65\xd9\x59\xdb\x2e\xd1"
+  "\x18\x73\xfe\xc1\xda\xd4\x29\xda\x1d\xbd\xb7\x62\x4e\xe1\xb5\x6b"
+  "\x9f\x14\xbb\x3c\x4b\xe3\x67\xdd\xb2\xa7\x6a\xcf\x8a\xab\x7f\xe7"
+  "\x23\x8a\x35\x2b\xc7\xe8\x66\x5c\x92\xf5\x75\xd3\x4e\xac\x83\x8d"
+  "\x3b\xa5\xe5\x5f\x51\x5f\xd8\xb9\x96\x3e\x17\x85\xef\x4c\x11\x59"
+  "\xf8\x1b\x09\xe5\xf3\xe4\xfe\x50\x8f\x86\xc2\x08\xf9\x4b\xff\x42"
+  "\xe5\x4b\x79\x8c\x0e\xf5\x60\x3b\x8d\xfd\x21\x51\xde\x7e\x86\x0e"
+  "\xdd\x64\x0b\x63\xce\x08\xc3\x76\x7e\x8e\xd7\x7a\x87\xee\xe0\xf5"
+  "\x66\x80\x0e\x15\xb1\x4f\xb8\x6f\xe9\x03\x9c\x36\xd9\xf5\x95\xf4"
+  "\x7d\xc8\x56\xf7\x4e\x0f\x69\xfc\xee\xe2\x3b\xae\x99\xf7\xcc\x7c"
+  "\xf7\x72\xb8\x87\xda\x83\x38\x64\x7c\x33\xa5\x32\x47\xad\xb9\x0e"
+  "\x69\xdd\xf1\xae\xee\x1d\xdc\x24\x38\xce\x72\x75\x84\xa6\x85\x44"
+  "\x40\x9e\x53\xf2\xdd\xfe\xd2\xfb\x7d\xe2\x92\x97\xd4\x7d\xb4\x43"
+  "\x5f\xe9\x15\x83\x9b\x54\x0c\xc0\x43\x9f\x93\xf2\x31\xc2\x1c\x39"
+  "\x38\xa0\xf6\x68\x07\x07\xd5\x9e\xe5\x10\x5a\xdf\x8f\x7d\x90\x0f"
+  "\x35\xb7\x65\x0c\xe1\xdf\x83\x6d\x99\x63\xeb\xba\x9f\x8f\x06\xf2"
+  "\x5d\xa4\x2c\xde\x2b\x67\x7f\xe2\x1a\xe5\x47\x8c\x36\x3e\x6c\x11"
+  "\x15\x32\x6f\xc0\xa9\x62\x4a\xe5\xfd\x45\xa4\xdd\x33\xa2\x9a\x34"
+  "\xe0\x7a\x83\xb0\x0f\xae\x93\xbe\x5b\xde\xc1\x3e\x7f\xab\xf0\xb1"
+  "\xcf\xa0\x3a\xd3\xf8\x30\x24\x32\x06\xd7\x19\xe5\x5f\x68\x6c\x45"
+  "\x1f\xec\x83\xdd\xfe\xf0\x59\xc3\x26\xfc\x10\xbc\x3f\xd8\x2d\xbc"
+  "\x83\xbd\xea\xae\xf8\x87\x9f\x99\x7a\x55\xf1\xe8\x87\x7f\x52\x74"
+  "\x1b\x48\x8a\x6e\x1f\x86\x8c\xf9\x6a\x00\x3f\x63\xee\x76\xaa\x33"
+  "\xf8\x0f\x7d\xa6\x8d\x1c\x30\xca\x70\x1d\x3c\x1b\xb1\x70\x3e\x0c"
+  "\xa0\xef\xa5\x46\xbe\xfc\x6e\x01\xfa\x07\x5d\xff\x61\x7f\xee\x57"
+  "\x77\xba\x55\xd2\xa2\x8c\x52\x81\x73\xad\xae\xe2\x22\x87\xfc\xa1"
+  "\xfb\x7d\xea\xbb\x7d\x87\xd7\xca\x3b\xb3\x68\x07\xe3\x63\x61\xbd"
+  "\xc9\x77\x7c\x19\x5e\x17\xfe\xff\x32\xc7\xc4\x85\xdb\xe3\x3c\xf4"
+  "\xd5\xcd\xe3\x09\x5a\x79\xb9\x0c\x8f\xeb\xe9\x62\xde\xbb\xb8\x08"
+  "\x9a\xb1\x1f\xd0\xe1\x4d\x4c\x13\x45\xb3\xc3\xf2\xdb\x60\x5b\x3b"
+  "\xc7\xe1\xf0\x53\xf1\xf4\x50\xef\xba\x1d\xba\x61\x29\xfb\x83\x1c"
+  "\xde\x64\xd0\xaf\x55\xb5\x7f\x78\xac\xb1\x56\x47\xde\xbf\x7c\x1d"
+  "\x53\xf7\x07\x9d\x65\xd5\x37\x22\x2d\x7c\xb6\xca\x7b\xed\x8a\x5f"
+  "\x0f\xf7\xef\xaa\x77\xb8\x7f\xc1\xd7\x6c\x23\x0f\x70\xf3\x37\xfd"
+  "\x98\xe6\xed\x9e\xc3\xce\x2e\x7a\x2b\x38\x49\xda\xb8\xc5\x6c\x23"
+  "\x40\xff\x12\x34\xf1\xc4\xb3\x31\x07\x1f\x2e\xe9\x1a\x93\x7f\xd9"
+  "\x6e\xd6\x63\xff\x7d\xbc\xe7\xf0\x7d\xc1\xa4\x7a\x90\xcf\x74\x80"
+  "\x5d\x63\xe4\x7e\x9f\xe4\x47\x3a\xdc\xca\xbe\xae\xa0\x6b\xad\xe2"
+  "\xa1\xc3\x4d\x6a\x2e\x3c\x2c\x63\xb7\xf0\x79\xc9\x91\x30\xf3\xc8"
+  "\xe1\x66\xc0\x35\xf6\xcb\x0f\x87\x0d\x1c\xb0\xfe\x3b\x14\x4c\x5c"
+  "\xd7\x3d\x30\x67\xae\xbc\x18\x3b\x6c\x79\x71\x62\x9c\xca\xb4\xae"
+  "\x3b\x90\x1f\x8d\x8a\xb9\x43\x9a\xa3\xe8\xfd\x91\x1b\xeb\xd4\x03"
+  "\x5b\xd4\xba\xf5\xe0\x16\x8c\x99\xeb\x22\xf5\xe3\x6f\x63\x94\x17"
+  "\x8b\x33\x8d\xff\x9b\xbd\xef\x81\x8b\xaa\x4a\xfb\x3f\x33\x80\x91"
+  "\x91\x8c\x86\x36\x95\xd6\xd4\x4a\x51\x59\x51\xeb\xff\xb5\x5d\x2a"
+  "\x2d\x6b\x45\xa8\xc5\x5e\x2c\x52\x54\x28\x34\xff\x8c\x88\x88\x88"
+  "\x80\x68\x2c\xb5\x82\x83\xa1\x61\xa2\x52\x6b\xfb\x52\xeb\x1f\xda"
+  "\xb5\xf7\xc5\x5d\xff\x4c\x89\x2d\x2a\x30\x54\xd8\xa2\x8b\x3a\x22"
+  "\xba\xc4\xa2\x8d\x82\x32\xe0\xcc\x3d\xbf\xe7\x39\xe7\xde\xb9\x73"
+  "\x87\x19\x70\x4c\xb3\xfd\xed\xcb\xe7\x33\x9f\xcb\xb9\xf7\xdc\x73"
+  "\xcf\x3d\xcf\x73\xbe\xe7\x79\x9e\xfb\x9c\xe7\xd1\x83\x2e\xad\x09"
+  "\x5d\x09\x78\x81\xb9\xa1\x7a\xa3\x2f\x05\xe2\x0d\xfa\x6a\xd2\xbe"
+  "\x70\x3e\x3f\xd4\x20\xef\x53\xdb\x5b\x00\xba\x6d\x49\x2e\xe8\xb2"
+  "\x19\x67\xc9\x9d\xdc\x37\x62\xf7\x6e\xb4\xe9\xd0\x8c\xe8\xf7\x05"
+  "\x43\x68\x01\xee\x81\xac\x06\x8d\x90\x66\x24\xbc\x2f\xe4\x87\x16"
+  "\x40\xbb\x9b\x33\xe6\x90\x7e\xb8\xbe\xa1\x6d\x88\xf3\xcc\xde\x24"
+  "\x68\x77\x33\xc6\x27\x13\x68\xb4\x0a\x9e\xdf\x24\x68\x86\x6b\x73"
+  "\x05\xc2\x7c\xbf\x81\xcf\xd4\x0d\x64\xcf\xad\xf0\xfc\x26\xcc\xd1"
+  "\x87\x76\x1e\x93\xd5\x8a\x31\x14\x9a\xe0\x5a\x1f\xb8\x36\x0a\x8e"
+  "\x02\xc6\x2a\xc3\x58\xd2\xd0\xbe\x16\xdb\x87\x67\x35\xf1\xbe\xb3"
+  "\x18\x22\x4d\x50\x6f\x0e\xd6\x91\x62\xa0\x09\x19\xd1\x3e\x78\x1d"
+  "\xf7\xd4\xda\xe1\x3e\x13\xac\x18\xfc\x9e\x3a\xc7\x3d\xa2\xfc\x0c"
+  "\x73\x79\xef\x1c\xba\x7a\x54\x05\xd4\x2d\x43\x5f\x53\x2e\xcb\xee"
+  "\x4d\x10\xe7\x3a\xc8\xc7\x7b\x67\x8a\xff\x07\x38\xea\x66\x44\x93"
+  "\xf4\x0e\xa2\x65\xdf\x4b\x17\xf9\x00\xf6\xee\x5d\x03\xe3\x80\xf6"
+  "\x85\x3a\xa6\x8f\xab\x77\x3b\xf6\xe5\x6c\x64\x7b\x77\xf6\x38\xe2"
+  "\xbf\x01\x6d\xca\x57\xf1\x98\x79\x15\x02\xfe\x9f\xcc\xf6\xcc\xf5"
+  "\x46\x3d\x03\x6d\x07\x53\x17\x17\x3b\xf6\x38\x70\x1d\x7c\xaf\xce"
+  "\x29\x56\x14\xbb\x17\x75\x71\xbc\x37\xc2\x46\x2f\xae\x12\xeb\xe2"
+  "\xbd\x11\x8b\xa7\x52\xbc\x17\xee\x89\x72\xdc\xa3\xd8\x23\xb3\x97"
+  "\xf3\x3a\xbc\x03\xfe\x6f\x81\x3e\x8b\x3e\x48\x3a\xfe\xfd\x78\xef"
+  "\x4a\xe9\x9b\xad\x99\xec\xae\x47\xba\xb9\x8f\x85\xbc\x77\x87\x32"
+  "\x6e\x8f\x71\x05\xc6\x14\x82\xf3\x95\x52\x7c\x1d\xf8\x1f\x9e\xb7"
+  "\x9b\xfb\xc1\x39\xc5\xcd\xca\x73\x8a\xc1\x97\x61\xa1\xa7\x90\x1e"
+  "\x30\x7f\x7d\x40\xd2\x1b\x4c\xf3\x87\x6b\xf9\x3e\x23\xe3\x42\xec"
+  "\x67\x03\x31\x8e\x85\x72\x20\xdf\xdf\x6f\x1c\x26\xce\x53\x5d\x84"
+  "\xdd\x16\x68\x86\x67\xe2\x9e\x19\xa7\xf2\x10\x98\xb7\x1a\xa8\x17"
+  "\xcf\x63\xd4\x19\x07\xbb\xd4\xc7\xeb\x99\x2e\xe5\x30\x97\xb2\xae"
+  "\x0d\xf8\xd3\xd3\xb7\xe9\xdc\x3b\x99\x5d\x6e\x6c\x9f\x65\x44\x9f"
+  "\xf1\x1d\xf1\x01\x7e\x3d\x8d\x7d\xab\x6e\x6a\xc1\x77\x0a\xa4\x59"
+  "\xa1\xc4\xd4\x64\xe3\x32\x1c\xac\x9d\x0d\x83\xa1\xce\x77\x64\x00"
+  "\xfa\x4d\x63\x5e\x03\xa8\xdf\xcc\x63\x30\x7f\x71\x6b\xcc\xc2\xde"
+  "\x44\x78\x23\xfa\x16\xaa\x8e\xb0\xe2\xb7\xb1\xad\x9d\x66\x3f\xfc"
+  "\x4e\x94\xbe\x8e\x0c\xc4\xf8\x36\x30\x3f\x1b\x31\xe7\x15\xe6\x20"
+  "\xff\x7d\x67\x93\x9f\xc9\x76\x94\xe8\x67\x11\x75\x33\xf9\x82\xf8"
+  "\xa6\x11\xdf\x55\x67\x88\x06\xe8\x6a\xdb\x67\x1b\x49\xa4\xfd\xf9"
+  "\x45\xfd\xf8\xde\xe2\x22\xc0\xb1\x05\x5a\x6a\x6d\xcf\xfa\x1c\xe4"
+  "\xff\x0f\xfc\x25\x5d\x76\x25\xcf\x5d\xe0\x7b\x86\x7c\x7e\x40\x2d"
+  "\xc6\x22\xe0\x63\xfb\xf9\x3a\xbe\x4f\x29\xe8\x76\xb8\xc7\x49\xfe"
+  "\xfd\x62\x20\x1f\xc3\xe1\x63\x38\xc6\x7c\x31\x70\x5f\x1c\xc1\x9c"
+  "\x35\xf8\x8d\x3f\x08\xea\xee\x72\x7c\xe3\x67\xf6\xa1\x2f\x60\x4d"
+  "\x1b\x3e\x86\xcb\xc0\xc3\xc7\x4c\xb5\xfb\x8b\x38\x80\xe7\xef\xc9"
+  "\xc4\x7b\xe1\xbe\xc0\x36\x66\xcb\xf9\xdc\x2a\xf3\xda\xe7\x46\xc4"
+  "\x56\x78\xa7\x00\xf8\x7f\x28\xbe\x17\x8e\x09\xd4\xf3\x85\xf2\xc8"
+  "\x7d\x9b\x3d\xc4\x2a\xd5\xe8\x42\x6d\xcc\xd6\xb0\x7a\x3c\xf0\xd3"
+  "\x59\xa0\xc1\x6d\x18\x8f\xc8\x04\xcf\xa9\xda\xd8\x49\xaa\xb4\xad"
+  "\xa4\x1a\xfe\x47\x5f\x5e\xe3\xac\x53\xa4\x51\xe7\x1e\xd7\x61\x6d"
+  "\x28\x85\x3e\x1b\xb1\x2d\xc0\xca\x26\xf4\x7f\x32\x81\x46\x54\x6d"
+  "\xc1\x5c\x5b\x84\xb5\x51\x25\x34\x91\xaa\x14\xd4\x67\xb6\x44\x56"
+  "\x6f\x3c\x4a\xaa\xb5\xdf\xb0\xe7\xa0\xec\x65\x4c\x6c\xed\xae\xed"
+  "\x1a\x68\xdb\x2c\xb6\xdd\x02\x6d\x07\x79\x6e\x3b\xbf\xd8\xcb\xb6"
+  "\xbd\xe8\x77\xbe\xc1\x9b\xb6\x01\x2f\x87\x9a\xb4\x7c\x5f\x54\xfa"
+  "\x1d\xe4\x56\xfb\x25\x8c\x45\x79\x0f\xe5\xfe\xa4\xfb\xce\xb3\xbd"
+  "\x53\x59\xcc\x5f\x37\x94\xed\xa1\x3a\x47\x98\x4f\x20\xdf\x37\x75"
+  "\x9a\xa0\x3f\x41\x7b\xd6\xbe\x7a\x59\x27\x71\x7c\xe7\x01\x59\xb0"
+  "\x9c\xfb\x68\x1a\x42\x43\x39\x5f\xed\xfb\x0c\xdb\x72\xdf\x8f\xc7"
+  "\xc7\x72\xff\xd3\xf2\x51\x92\x9d\xa3\xb5\xef\xe3\x63\xc5\xb6\x74"
+  "\xae\xf6\x33\x29\xc9\x65\x7c\x4a\x92\x94\x2f\x33\x49\xdc\xbe\xf9"
+  "\x52\xfc\x8c\xf8\x99\xc9\xf1\x71\xba\xa8\x85\x89\x73\x1f\x99\xf7"
+  "\xfa\xeb\xba\xf0\xf8\x05\x0b\xa6\xbd\x11\xdf\x9b\x44\x25\x4e\x9b"
+  "\xbb\x60\x26\xda\xb8\x74\xba\xb1\x3f\x9f\x9a\x30\x2f\xe9\x91\x5f"
+  "\x8e\x0d\x75\xb1\x71\xe1\x5e\xbf\x7a\x94\x75\x33\x96\xc2\xfc\xb4"
+  "\x93\xbe\x18\x5b\x26\x70\x31\x35\x2e\x01\x3d\x0b\xf8\xaf\x19\xd7"
+  "\x03\x98\xb7\x27\x51\x06\xc7\xb8\x76\x80\xdf\x95\xeb\xd7\xd2\x9a"
+  "\x33\xe4\xdb\x4f\x41\x7e\xab\xdb\xc4\x63\xb4\xd5\x83\xee\x6b\xe1"
+  "\x39\xdd\xbe\x45\x5f\xd6\xf2\xdf\xc1\x39\x4b\xdf\xe1\x63\x56\x1d"
+  "\x27\xbe\xb0\xce\x80\xfc\xbf\x7f\x02\x55\xdf\x44\x57\x0e\xa0\xe5"
+  "\xf4\x94\x96\x88\x71\xa7\xd5\x26\xb3\x15\xbf\x87\xfb\x47\xd8\x32"
+  "\x28\xe2\x29\x9f\x5b\xfb\xc3\xf9\xb8\xfc\xac\x86\xfb\xe5\x7e\x3b"
+  "\x07\x75\x85\xe5\x2c\xe7\xde\x7e\x98\xff\x65\xbb\x64\x9c\xae\x4e"
+  "\x11\x65\xb4\x3a\x18\xf7\x45\x0d\x50\xe6\xb1\x2f\xf6\xe7\x28\x7d"
+  "\x1d\xfe\x06\xeb\xdf\xd7\x45\xfc\x87\xf7\x7c\xbd\x8b\xff\xf0\x7f"
+  "\xe7\xdf\xb7\x91\xfc\xe7\x7a\xfe\x87\xfe\xa4\xe7\x5f\xed\xfd\xa6"
+  "\xd0\xee\x7f\x57\xf2\x7c\xf6\xde\x37\xf0\xfd\x7f\xc8\xfd\xa6\x91"
+  "\xdd\xfd\x90\xdf\x80\xb7\xea\x7f\x77\x9c\xf8\x03\x7f\x16\xe4\x4e"
+  "\x07\x9e\x3e\x46\xb4\x69\x36\xda\x98\xf1\x1a\x19\x98\xfe\x1d\xc1"
+  "\x9c\x67\x4d\x49\x29\xb4\x31\xfd\x12\xca\x7e\xa6\x9b\x81\x7f\xcb"
+  "\xf2\x1a\x48\x40\x6e\x03\xd1\x54\x27\x61\xee\x53\x8c\x3f\x05\xad"
+  "\x81\xa4\x6b\x82\x72\x65\xb2\x95\x1c\xb2\x9c\x47\xff\x20\x63\x75"
+  "\x2c\xe0\x4e\x3d\xe6\x8d\xa5\xe5\x01\xb1\x24\xa8\x68\x00\xdd\x45"
+  "\xb3\x66\xfb\x52\xf5\x9b\x6d\x70\xae\x76\xbb\x10\xe6\xb7\x3d\xb5"
+  "\xc2\x0f\xf3\xc3\x35\x90\x8a\x5b\x45\xde\x5c\xcc\xf7\xe4\x54\x33"
+  "\x7b\x05\xcc\x93\x5a\x6e\xbf\xae\xbe\xc8\xd7\xf3\xea\xfd\xa2\x5d"
+  "\x07\xff\x67\x32\x19\xbc\x47\x19\xe6\x88\xc4\x36\xb7\x09\x65\x2c"
+  "\x47\xe4\xf6\xd4\x30\xbf\xb4\x69\x44\x5d\x6d\x6e\x26\xfb\x00\x07"
+  "\x31\xdf\x20\xcc\xbb\x2d\x30\xcf\x4a\x37\x0c\xa0\x06\xe8\xdf\xca"
+  "\x8d\x03\x68\x0e\xf4\xa9\xa4\x3d\xab\x22\x0d\xd6\x2c\xbd\xf8\x7d"
+  "\xc3\x08\xf3\x62\x4b\x2e\xd4\x89\x58\x48\xee\xc9\x85\x7a\x79\x50"
+  "\x0f\xe5\x51\xde\xbf\xca\xa7\x60\x0c\x76\xc0\x33\x6b\x74\x53\xb0"
+  "\x7c\x80\xd9\x86\xf0\xd9\xf0\x1e\xba\x06\x72\xa0\x12\xd6\x36\x5f"
+  "\x7c\x86\xf4\x5c\x68\x1f\xf0\x6f\x9f\xf4\x7d\xd5\xc0\xdb\x39\xe0"
+  "\xcf\xe7\x6b\xe8\x8e\x55\x8e\x1c\x9e\xa1\x3b\x72\x53\x61\x4d\xef"
+  "\x64\x71\x19\x51\x96\x66\x32\x06\x93\x2b\xec\x24\x90\xeb\xe1\x20"
+  "\x5b\x24\x00\x0e\x80\x3c\xc1\x7c\x89\x41\x96\x80\xbe\x14\x60\x1e"
+  "\x4d\xbc\x0e\xfa\xd1\x0e\x58\x97\x4b\x51\x0e\x98\x72\xf1\x05\x82"
+  "\xb6\x6c\x90\x07\x7c\x17\xc4\x50\x2b\xcf\xf7\x71\x20\x41\x92\x05"
+  "\x10\x83\x70\xfd\xcf\x4d\x26\xbe\x97\x81\x86\xc0\x03\x15\x20\x5b"
+  "\xf4\x6d\x26\x07\x36\x8b\x63\x5f\xc1\xd6\xfc\x64\x16\x47\xd8\x87"
+  "\x63\xf4\x81\x4f\xe1\xfd\x02\xe0\x19\x20\x3b\x7e\xcb\x72\x7c\x73"
+  "\x8c\x39\x60\x94\xd6\x71\xd4\x2d\xcd\xd0\x06\x05\x2c\x13\xaf\xc1"
+  "\xfb\x1b\x0b\xa4\x67\xc2\x35\xbd\x38\x66\x95\x30\x66\xd0\xe6\x41"
+  "\xb6\x9f\x1c\x64\xae\x31\xe2\xd8\xa4\xa1\x5c\xc1\xef\x3d\xa8\x95"
+  "\xda\x45\xfd\x57\x00\xb9\x02\xc7\x0b\xc7\x09\xda\x49\x13\x71\xac"
+  "\x96\xcb\x2f\x95\x0f\x8a\xdf\xb5\x0d\x40\xeb\x15\xf2\xf8\x1f\x8c"
+  "\x71\x1e\x7f\xb8\x7f\x05\x7f\xce\xa1\xc3\x4e\xb4\x03\x1d\xe4\xd0"
+  "\x16\xb4\x47\x42\x1f\x77\x71\x5b\xca\xc1\x35\x18\xbf\x0b\xe3\x05"
+  "\xc3\x18\xef\x5a\x89\xb1\x69\x01\x9b\x97\x1f\x27\x62\xfe\xd6\x43"
+  "\x6b\xb8\x7c\x7a\x68\x28\xcf\x71\x78\x68\x10\x96\x1b\xa1\x5f\x3c"
+  "\xbf\xe1\x21\x3f\x9e\xdf\xf0\xa0\xdd\x39\x67\xab\x9c\xaf\xf5\x60"
+  "\x9b\xec\xcf\x7f\x50\xc7\xf5\xd4\x83\x3a\xb4\x35\xb1\xfa\x97\x13"
+  "\xb0\x6f\xf5\x38\x2f\xa5\x77\xc5\xdc\xad\x70\x1e\x65\xff\x7a\xa4"
+  "\x9b\x74\x1e\xe3\xda\x02\x9d\x02\xe0\x99\xb9\x62\x9f\x12\xa0\xec"
+  "\x0f\xcf\x66\x7e\x34\x98\xc7\x75\x15\xde\x93\x2e\xdf\x83\xf3\x06"
+  "\x78\x38\x10\xee\x79\x0b\x8e\x54\xaa\xcb\xf3\xbb\x1e\x0a\x78\xb7"
+  "\x13\x6d\x4d\x87\x06\x4b\xf9\x5d\x31\xb7\x2b\x62\x46\xee\x14\xc5"
+  "\xd8\xe3\xd8\x6c\x01\x5a\x31\xbe\xdb\x67\x2b\x83\xf7\x3a\x04\xf2"
+  "\xff\x67\x62\x2c\xb9\x43\x01\x62\xff\x8c\x3c\xef\x41\xf9\xd8\x8d"
+  "\xab\xa5\x58\x06\x87\xda\x1c\xfa\x90\x43\xb6\x3c\x14\x80\x3c\x09"
+  "\x6d\x55\x22\xfd\x51\x4e\x6c\xcf\xaa\x1c\xe8\xe0\x2d\xb6\x5f\xf6"
+  "\x50\x11\xca\x97\x62\xff\x91\x5f\x96\x8a\x63\x37\xd6\x79\xde\x39"
+  "\xcf\x73\x68\x23\x16\xe6\xb8\x83\x07\xa4\x79\xcd\xf9\xa0\x6a\x8d"
+  "\x28\x53\x8c\xc7\xb8\xb2\xd0\xae\x11\x65\x70\xbe\xae\x56\x25\xec"
+  "\xab\xb7\xa1\xad\xba\x16\xca\x30\xbf\xab\xc6\xb6\xf6\x1b\x55\xb3"
+  "\x82\xe1\x46\x25\xe8\x3f\x8f\x4a\x79\x54\xeb\xa5\xf9\xba\x6a\x0a"
+  "\xea\x7e\xa1\x7c\xce\xa6\x34\x92\x6a\x6b\x0b\x11\x7d\xe5\x61\xce"
+  "\x9e\xc6\x6f\x94\xcd\xc0\x43\xfe\x38\x7f\x81\xbe\x5b\x30\x06\x32"
+  "\x8c\x63\xcd\x8a\xb5\x6c\xde\x06\xe0\xbc\xbd\x8c\x31\x18\xe0\x39"
+  "\xe5\xb1\x61\x64\x5f\x8a\x91\xcd\x63\x8c\xad\xb1\x1e\xc6\x0e\x73"
+  "\xa9\xb6\x67\x55\x85\x4a\x3e\xbe\xc8\x23\x18\x4b\x43\xe4\x93\x14"
+  "\x9c\xcb\xe2\xd8\xf9\x42\xbd\x68\x69\xee\x39\xd1\x9f\xd5\x71\x99"
+  "\x6f\x81\x7c\xbe\x55\xe5\x48\x63\x6d\x63\xf3\xf8\xd0\x60\x1b\xcc"
+  "\x63\xe7\x31\xc5\xf1\xc4\x71\x85\xba\xf0\xfe\x5f\x54\x4a\x63\x2a"
+  "\x8f\x67\x75\xb0\x48\xf3\x1a\x6e\xcb\xa9\x6a\x12\xed\x3c\x8e\x31"
+  "\x14\xf9\xaf\x16\xe7\xd4\x72\x7c\x77\x58\x1b\xf0\xf9\xc8\x23\xeb"
+  "\x45\xcc\x2a\xb7\x20\x8f\x54\xc3\xfc\x7f\x31\x47\xc6\x8e\x43\x21"
+  "\x4c\x67\x01\x3a\x71\xfa\x54\xbf\xc8\xe2\x55\xb8\xc1\x0e\x33\xa9"
+  "\xd4\xc8\xf8\x54\x1d\x2b\x8d\x83\xc4\x93\xd2\xbc\x87\x36\xb6\x2a"
+  "\xf1\xa7\x3a\x1f\xda\xe8\x87\xf8\x26\xcb\x50\xd5\xc5\x4a\x7c\xab"
+  "\xce\x41\x7c\x43\xbe\xd6\x27\xa3\x2d\xab\x5a\x8c\x7d\x5d\x11\xaa"
+  "\xc4\xa4\x8a\x60\xfe\x0d\x9e\xcb\x5c\xc8\x5b\xfa\x29\xbc\x3e\xae"
+  "\x61\x50\x9f\xe5\x29\x11\xd7\xbc\x14\x5c\xe3\xe0\x9c\x14\x0b\xbb"
+  "\x1e\xea\x97\xe3\xbe\x43\x8c\x35\x70\x4b\x3d\xd7\xf5\x00\xa7\x77"
+  "\x61\x4c\x69\x33\xf9\x5b\x7d\x35\xcc\xc2\xcb\xd9\x1c\xbb\x25\xac"
+  "\xa0\x33\xa2\x6f\x59\xd4\x44\x6e\xd6\xff\x92\x9e\x82\x35\x1b\x63"
+  "\x0b\x5a\x31\xae\x21\xb4\xad\x3b\x43\xbe\x7e\x0b\x9e\x1b\x24\x1e"
+  "\xb5\x70\x9c\x03\xc7\x3b\xe0\x38\x09\x8e\x77\xc1\xf1\x49\xa8\x2f"
+  "\x88\xf5\x43\xa1\x1c\x0c\xe7\x7f\x2e\x1e\xa1\x8f\xa6\x1d\x70\x8c"
+  "\x14\x65\x47\x38\xff\x55\x07\x96\xe1\xf8\x9d\x48\xf3\x4a\x4e\x73"
+  "\xd3\x49\x68\x27\x05\xfa\x5f\x67\xaa\x67\x6d\xe9\xa1\xce\xc7\xd8"
+  "\x36\xee\x03\x86\xff\x5f\x73\x92\x41\xa1\x9d\x9a\xb7\xe1\x38\x14"
+  "\x8e\xe1\x70\x4c\x82\xe3\xbd\xe2\x18\xd4\x20\x36\xc4\xa5\xb0\x31"
+  "\x67\x18\xc1\x9f\xc7\xe7\x3c\xae\xc3\x32\x76\x1c\x48\x8b\x8b\xe1"
+  "\xf4\x36\x93\x2a\xc6\x07\x50\xf7\x29\xac\x0b\xc7\x67\xc4\x63\x98"
+  "\x78\x1c\x27\x1e\x9f\x13\x8f\x63\xc5\xe3\x78\x33\xa9\x19\x2c\xca"
+  "\x18\x30\x2e\x35\x83\x99\x7f\x91\x21\x74\x36\x7f\xc6\x57\x63\x51"
+  "\x47\x06\x1c\x1f\x06\xed\xfb\xb4\x67\xd5\x94\x49\x76\x48\xb4\xf9"
+  "\x5c\xce\x2a\x9f\xba\x9e\x7d\x3f\xae\xa9\x71\xc2\xb6\x80\x00\x55"
+  "\x18\x01\x19\xa8\x7f\x91\x9a\x1a\xc4\x76\x42\xd4\xe2\xf7\x57\x31"
+  "\x5e\xbd\x0f\xc6\x70\x63\xfa\x50\xdf\x8f\xcb\x70\xae\x32\x1b\x2d"
+  "\xc6\x1b\xeb\x3b\x5c\x03\xbf\x81\xa0\x1b\xe8\x24\xfc\x46\xbd\x47"
+  "\x8c\x0d\xb9\xa7\x3d\xeb\xab\x31\xb2\xae\x5e\xd3\xc2\xbf\x55\xdd"
+  "\x7e\x2f\x9c\x8f\x72\x3a\x5f\x82\x7d\x86\xf1\xac\x83\xf7\x19\xda"
+  "\x40\xbe\x4a\x83\xe3\x13\x8d\xfc\x9d\x43\xa5\x77\x16\xe9\xa1\x97"
+  "\xc6\xb7\x91\xd4\x0c\x01\x2c\x4c\x44\x1e\x6e\x70\xe0\x6c\x0d\xdb"
+  "\x93\x26\xf2\x08\xd0\xd2\x84\x31\x30\x33\x9c\xe6\xa0\x33\x06\x05"
+  "\x41\x3f\xea\x95\x98\x72\xa0\x1e\x31\x05\x79\x03\xf0\x1b\x68\x6d"
+  "\xda\xe5\x32\xff\x72\x70\xfe\xf1\x79\xf7\xb5\x56\x79\x6f\x75\x8e"
+  "\x8d\xcf\xbb\x3a\xe0\x33\xe0\x4f\x53\x11\xd2\xc7\x4c\xbe\xb2\x8a"
+  "\x73\xba\x0e\xe6\xf4\x30\x38\x2f\xe6\x06\xe6\xe7\xc5\x67\x01\x9f"
+  "\x99\xf0\xbd\xef\x92\xce\x8b\xef\x8b\xed\x24\x21\xbd\xa5\xf3\x62"
+  "\xfb\xc0\x8f\xa6\xd9\x38\x4f\xa4\xf3\xe2\x3b\x81\x1c\xf5\x75\xa9"
+  "\x84\x27\x2b\x39\xbf\x8d\x94\xee\x43\xba\x61\x5c\x27\x6e\x4b\xff"
+  "\xba\x08\xe6\x6a\x31\xae\x0f\xcb\xa7\x90\x80\x45\x85\xe4\x56\x3e"
+  "\x2f\x51\xa7\x70\xc6\xc8\xc3\x4b\x69\x56\xa0\x8d\x6a\x86\xfb\x57"
+  "\xd9\x86\x4a\xf2\x6a\x51\x7b\xd6\x37\x5a\x29\x97\xb0\x1c\xfb\xfe"
+  "\x9b\xf0\xaa\x62\xc7\xf8\x42\x5f\xbe\x19\x23\xf5\xc5\x69\x7d\x66"
+  "\x34\xc0\xbe\x61\x5b\xcb\x41\x5e\x6f\x03\x5c\xe0\xb8\xfd\xcd\x6c"
+  "\x29\xc7\x7a\x9e\xb8\x6e\xb1\x3c\xdf\xc9\x3c\xcf\x37\xae\x8d\xe8"
+  "\x4b\x23\xa0\x1d\x2b\xc5\x4e\xaa\xf5\xa0\xcb\xa7\x9c\x26\x53\x17"
+  "\xf7\xc6\xd8\x25\xd1\xd0\xd7\x69\xd0\xb7\xcd\x76\xb4\xb1\xcf\x45"
+  "\x3d\xf5\x70\x7f\x7b\x32\xb5\x8a\x63\x06\xf3\xa8\xb6\x43\x1c\x5b"
+  "\xc4\xaf\xcd\x88\xe9\xcb\xd3\x79\x1e\x1b\xb4\xe5\xe0\xfc\x78\x17"
+  "\xd7\x31\x2d\xb5\x96\x17\xe1\x5c\xf9\xc6\x26\xc9\xa4\xd0\xdf\x62"
+  "\x2e\x13\x56\x4d\x66\xb1\x7d\x0c\xc3\xfd\xb9\x2d\xb0\xf6\x6d\xfe"
+  "\xee\xb5\x7a\xfe\x3d\x99\xc5\x6d\xc4\x72\x8c\x8f\x76\xc0\x6f\xb9"
+  "\xff\x53\x79\x2a\xf7\xdd\xa8\x9d\xe0\xf0\xdd\x90\x65\xc5\x24\x1e"
+  "\x77\xa9\x36\x41\x9e\x13\xb5\x23\xf1\x3e\xb8\xff\x7d\x38\x9f\x29"
+  "\x9f\xaf\x8a\x16\xed\x5d\x01\x7d\x96\x85\xa1\x0f\x57\x7f\x8c\xff"
+  "\x2c\x3e\xcf\xcc\x9e\xcf\x6c\x1e\x30\x37\xc5\xf9\x8b\xe3\x8c\x6b"
+  "\x36\x9b\xc3\x30\x7f\x71\x1e\x5f\xce\x1f\xae\x81\x1f\x9f\xb7\x7c"
+  "\x6d\x4e\x62\xf3\x96\xcd\xd9\x5a\x8b\x53\x3f\x4a\x98\xdd\x0b\xe9"
+  "\xb9\x44\x1b\xd0\x9e\x75\x38\x00\xe4\x55\x31\x4f\xc2\x37\xcc\xff"
+  "\x18\xe3\x73\xd8\x2e\x51\x0b\x7e\x43\xc6\x6f\x8a\xb8\xc7\x29\x10"
+  "\xb8\x1b\x63\x6a\x48\xdf\x84\xc3\x5b\x32\xa8\x1d\xbf\xef\x5c\xa2"
+  "\x6d\x06\x47\xfc\xf9\xc3\xd1\x72\x7c\x9c\x6f\xca\xc4\xf7\xc2\xf5"
+  "\xb3\x88\xfb\x5c\x7d\xf3\x31\x97\xa9\xbe\x29\x41\x3e\x35\x01\xef"
+  "\xc1\xb1\x90\xe7\x52\x3d\x5c\x20\xf1\x1e\xcc\xcb\xb8\x33\xe4\xdb"
+  "\xe0\x82\x01\xb4\x10\x68\x5a\x08\x73\x69\x36\x94\xfb\xc2\x31\x8e"
+  "\x1f\x55\x1a\x3c\x8a\x73\xa4\x10\xee\xad\x91\x72\x5e\xe3\xd8\xb4"
+  "\xf5\xcd\x37\x22\x9f\xe5\xc1\x38\x20\xaf\xb1\xef\xb5\x7a\x9e\x4b"
+  "\x1e\xf9\x0c\x79\x2c\x70\xd9\x0b\x8c\xcf\xd8\xfe\x7d\x38\x8f\xfd"
+  "\x45\x3e\x6b\xcf\xfa\x76\xa0\x14\x7b\xd6\x4c\x0e\x1b\xf9\x77\x93"
+  "\x6f\x43\x25\x9f\x55\xfc\x66\x93\x74\x2f\xe9\x0f\xed\xea\xca\x75"
+  "\x2c\xbe\xe3\x09\x93\x6d\x1c\xc1\xba\xf8\xbd\x8b\xe3\xe4\xed\x49"
+  "\x70\x4f\x9c\x3c\xe6\x07\x98\xdf\xc6\xbe\x18\x66\x8b\xbc\x0d\xae"
+  "\x65\x3a\xeb\x19\x66\xb2\x7f\x02\xea\x1a\xe8\x43\xf7\xb3\x20\x82"
+  "\xb9\xe9\x01\xc7\xbe\xdd\x2c\xc9\xb5\x8f\x05\xe1\x77\xf3\x72\x2b"
+  "\xf4\x0f\x75\x68\x78\xd7\xf2\x46\xd0\x25\x2b\x3c\xd8\x8c\x87\xa2"
+  "\xad\x47\xcc\x19\x53\x8f\x76\x2c\x8c\xb1\x7f\x86\x1c\x0d\xae\x2a"
+  "\x04\x7a\xce\xeb\x1a\x7b\x38\x3d\x85\x5e\xc4\xf8\xc3\xba\x44\x72"
+  "\x5b\x03\x39\x8a\xfa\x60\x5d\xc6\x79\xb4\xd1\xfc\x7d\x88\xd2\x46"
+  "\xf3\xf7\x34\xf1\x67\x80\x5f\x9b\xfc\xab\x5b\x21\x1e\x49\x0f\xbf"
+  "\x22\x5e\xb7\xae\x04\x7e\x3b\xc4\xb1\xda\xd1\x9e\xf5\x77\x87\xfd"
+  "\x17\xf9\x12\xe7\x36\xfa\x4b\xa0\xcd\x49\x65\x23\x18\xbb\x03\xe8"
+  "\x04\xfd\x5e\xfe\xd0\x4b\xc6\x54\xe4\xa3\xbf\xb3\x1c\x8e\x18\x17"
+  "\xd7\x3b\x9f\x9d\xbf\x33\x7a\xf2\x18\x95\x7f\x5f\x01\xcf\x2e\x5f"
+  "\x75\x8e\xf8\xea\x13\xc9\x20\xb4\x7f\x07\xda\xa9\x11\x75\x5c\xe4"
+  "\x89\x4d\x2c\x57\x4b\xdd\x5b\x49\x4b\x89\x1a\xae\xdf\x03\xff\x27"
+  "\x49\x72\x12\xdc\xa3\xf1\xb1\x92\x20\x94\x8f\x9e\x59\x4a\xee\x69"
+  "\xcf\xaa\x8b\x94\x68\x85\x32\x04\xda\xe1\x44\x5b\x02\xf6\x95\xf9"
+  "\x26\x62\xec\x74\x33\x1b\x37\x86\xc3\xd8\x06\xcc\xbb\xba\x31\x3e"
+  "\x6d\x44\xc3\xd7\x9e\x3a\xe0\xff\x72\x51\x66\xac\x8b\x06\xde\xaf"
+  "\x75\xea\xe7\x25\xf9\x7f\xed\x70\xbc\x3f\xb0\x0d\xe5\x33\x4f\xe3"
+  "\x53\x77\x52\x1a\x1f\xf4\x0b\x0d\x04\x3d\x81\xd1\xdb\x46\x5b\xa0"
+  "\x6f\x95\xfa\x54\xe2\xdf\x4c\x8e\x7c\xb5\x69\x2d\xdb\xa7\x56\xc1"
+  "\xed\xf3\x47\xf6\x4b\x7a\x38\xef\xf7\x91\xfc\xc0\x65\x3e\x04\xed"
+  "\xea\x18\x2f\x8c\xf9\xd4\x7d\xaf\x65\xb6\x74\x93\x6d\x0c\x31\xa6"
+  "\x8f\xc6\x3a\x92\x5c\x55\xdf\x9a\xa1\x25\xfb\xb4\x63\x60\x1e\x1f"
+  "\x89\x81\xb9\x62\xf0\xde\x77\xf1\x48\x8c\x38\xbe\x95\xfc\x9b\xff"
+  "\x91\x47\x70\x2d\x59\x21\xe6\xa6\xc7\x35\x1a\xda\x2e\x93\xe6\x0d"
+  "\xac\x1b\xe5\x70\xcf\x10\x8e\x31\xf8\x9d\xf5\x08\x8b\x2f\xc2\xf4"
+  "\x06\x5e\x3f\x80\xdb\xfc\x8f\xb4\x38\x64\x69\xa8\x87\xf7\x71\x5f"
+  "\xb0\x23\x64\xaa\x5d\x05\x63\x7a\x84\xbd\x1b\xe7\x45\xed\x98\xf6"
+  "\xac\xa3\x03\xe5\x79\x5b\xc7\xb0\x79\x5f\x8b\xf3\xbc\x3c\x3a\x46"
+  "\xd6\x37\xbf\xb5\x3c\x52\x40\xdc\xe6\xa2\xd5\xf7\x21\x9a\x7f\xf9"
+  "\x93\xdf\xac\x5a\x45\x8b\x0d\x6a\xe1\xe9\xe5\x79\x24\x40\xb5\x12"
+  "\x86\x0d\xe7\x59\x72\x6c\x7f\x98\x8f\xbb\x03\x03\x6e\x8f\x7c\x26"
+  "\xe9\x26\x9a\xae\x25\xea\xdc\x0b\x37\xf9\xdf\x6b\xbd\xbd\x98\xfa"
+  "\x3c\xf4\x52\x78\x92\x95\xe8\x66\x19\xc8\x3f\x67\x13\x9f\x67\xec"
+  "\xf0\xec\x00\xa2\x37\x93\xfa\x0a\xdc\x73\xb9\x2f\x00\xe5\x8f\xfa"
+  "\x0a\x6c\x33\xad\x88\xf8\xa7\x35\xd2\xa6\x95\xaf\xfb\xf9\xc3\x7a"
+  "\xa0\x59\x0f\x3c\x76\x4b\xc0\xed\xc5\x97\xa1\x8d\xcf\x63\xd9\x7d"
+  "\x6e\x7d\x1f\xba\xef\x9b\x7e\xc0\x19\xf2\x8f\xc9\xde\xf5\xed\x78"
+  "\x82\xdc\xb7\xe3\x09\xd7\xb8\x6f\x1a\xb9\x6f\x09\xd8\xb7\x8b\xde"
+  "\xf5\xcd\xec\x2f\xf7\xcd\xec\x7f\x85\x7d\xdb\xe2\x7d\xdf\x52\x6e"
+  "\x3f\x43\xea\xf3\xbd\xeb\xdb\xc9\x12\xb9\x6f\x27\x4b\x7e\x48\xdf"
+  "\x50\x97\x4f\x1f\x48\x4f\xb3\x18\xe7\x89\x24\x00\x7d\xe4\xce\x90"
+  "\x63\xe7\xd3\x8b\x58\xb9\x1f\xfc\xbf\x55\x9c\xdf\x96\x8c\x36\x7a"
+  "\x8a\xcb\x39\xc7\xee\x78\x54\x8f\x7e\xa5\xc7\x34\xc0\xcb\x15\x9c"
+  "\xa7\x8f\x33\xdf\xce\x0c\x0b\x15\xfd\x3a\x8f\x8d\xda\xc8\xfc\x3e"
+  "\x46\xa7\x88\xe5\xb4\xd6\x7e\xc3\xc7\xa2\xcf\x85\x00\xf3\x99\xf6"
+  "\x1b\x1e\x89\x39\x1f\xb7\x27\x5a\xd4\x34\x0b\x63\x6f\x61\xbc\x3c"
+  "\x5f\x42\x57\x0f\x8f\xdd\x9e\x68\x55\x63\xcc\x8c\xe5\x6c\xbf\xec"
+  "\xb1\x24\x69\x8f\x98\xf4\x0c\x4b\xdf\xd1\x29\x70\x7e\xa5\x94\x67"
+  "\x96\xaa\x51\x9e\x19\x3e\x1e\xdb\x87\xf3\x9b\xa5\x5c\xb0\x66\x72"
+  "\x6c\xa4\x88\x0d\x6d\x81\xd6\xee\x70\xef\xd8\x11\x09\xf7\x9e\x49"
+  "\x22\x81\x98\x2b\x71\x55\xfa\x4d\xf8\xcd\x11\xe4\x9f\x63\x09\x38"
+  "\xee\x11\x6d\x37\xd1\xc0\x34\xe2\x83\x7b\xe3\xd0\x17\xce\xa4\xb5"
+  "\x90\xc1\x69\xc4\x2f\x22\x05\xda\xb4\x92\xd8\xc0\x14\x68\x0f\xc6"
+  "\x9a\xeb\x06\xc7\x99\x8d\xaf\x00\xda\xc3\xef\xdf\x3e\x49\x24\xe0"
+  "\x19\x6d\x06\x5d\xbe\x8e\xf8\xe2\x3e\x3a\xdc\x0f\xc7\xf7\xc2\xf5"
+  "\xf2\x6f\xcf\x3a\x1e\x25\xbd\xdf\x15\xd0\xa7\x0f\xa7\xcf\x89\x7c"
+  "\x99\x3e\x27\xc2\xbb\xd2\xe7\xf8\x4e\x4e\x9f\xe3\xa5\x32\x7d\x4e"
+  "\xb4\x29\xe9\x73\xfc\x88\x92\x3e\x27\x06\x5e\x1d\x7d\x4e\x04\xc9"
+  "\xf4\x39\xd1\x26\xd3\xe7\xc4\x10\xf7\xf4\x39\x31\x56\xa6\xcf\xf1"
+  "\xba\x2b\xa3\xcf\x89\xc5\x9e\xe9\x73\xc2\xbf\x1b\xfa\xf4\x72\x4f"
+  "\x9f\x13\x07\xae\x9c\x3e\x27\xda\xbc\xa0\xcf\xad\x9c\x3e\x27\x1f"
+  "\x97\xe9\x63\x3e\xdb\x95\x3e\xe6\xc9\x9c\x3e\xe6\x48\x99\x3e\x27"
+  "\x0b\x94\xf4\x31\x2f\x56\xd2\xc7\xbc\xeb\xea\xe8\x63\xde\x21\xd3"
+  "\x87\x3f\x83\xd3\xc7\x5c\xe9\x9e\x3e\xe6\x46\x99\x3e\xe6\x94\x2b"
+  "\xa3\xcf\xc9\x3b\x3c\xd3\xc7\x5c\xe2\x3d\x7d\x4e\xce\x74\xa1\x8f"
+  "\xc6\x33\x7d\x4e\x16\x78\x41\x9f\x40\x4e\x9f\x86\xaf\x64\xfa\x34"
+  "\xe4\x76\xa5\xcf\xc9\x0e\x4e\x9f\x93\x16\x99\x3e\xa7\x86\x2a\xe9"
+  "\xd3\x70\x87\x92\x3e\x0d\x31\x57\x47\x9f\x86\x28\x99\x3e\xfc\x19"
+  "\x9c\x3e\x0d\xb3\xdd\xd3\xa7\x61\x85\x4c\x9f\x06\xed\x95\xd1\xa7"
+  "\x61\xa7\x67\xfa\x34\x8c\xef\x86\x3e\x37\xb9\xa7\xcf\xa9\x9b\xaf"
+  "\x9c\x3e\xa7\x86\x76\x47\x1f\xef\x64\xbd\x53\x2c\x86\xd6\x35\x68"
+  "\xc7\x73\x7e\x60\x18\x3b\xf4\xf3\x13\xb2\x4e\x19\x36\x0a\xbd\xfc"
+  "\xf9\x5e\x88\x53\xe3\x75\xa9\xe4\x57\x0d\xe4\xd4\xb1\x8d\x82\x9f"
+  "\x3f\xcd\xda\x1c\x27\x64\xfd\x21\x80\x2e\xeb\xe5\x2b\x2c\xbb\xc9"
+  "\x17\xf7\x36\x7b\xce\x3d\xdd\xf8\xa4\xcf\x1d\xe4\x6e\xdc\x9f\xb6"
+  "\x1c\xe4\x65\xfc\xbf\x3d\xab\x71\x3c\xc8\x82\x2b\xbb\xdb\x27\x85"
+  "\xbe\x4e\xfb\x56\xa0\x7e\xdb\x98\xe4\x88\x2b\x91\x45\x53\x30\x3e"
+  "\x97\xfe\x3e\xdc\xcf\xd0\x58\x54\xc0\xe2\x3d\x85\xb6\x84\xdd\x47"
+  "\x4f\xa0\xee\x71\x86\x9c\x5e\x47\xf3\x43\x5b\x90\x1f\x40\x56\xbf"
+  "\x0d\xea\x34\x3a\xfc\xe0\x68\xf4\xfb\xa2\x8d\xb0\x90\xd7\xfd\xe7"
+  "\xcd\x50\xb7\x10\x73\x63\x2e\x48\xc7\x9c\x8f\x67\xce\x83\xec\x7b"
+  "\x3f\x3e\x03\x63\x0f\x6d\x82\x23\xfa\xc9\x70\x1f\xc8\xd3\x6c\xef"
+  "\x2a\xc6\x35\xe4\x3e\x67\x67\x8e\x48\x7c\x07\xcf\xe9\x0d\xe5\xcf"
+  "\x45\x79\x1e\xeb\xdf\x02\xe5\x8f\x9d\xae\x07\x40\x39\x17\xda\xee"
+  "\x2b\x5e\xbf\x15\xca\xf3\x51\xce\x66\x71\x32\xf2\x32\x45\x5f\xdd"
+  "\x33\x51\x70\x4e\x23\xd6\xe9\x0b\x75\x46\xa1\xec\x2e\xb6\xd1\x0f"
+  "\xca\x83\x50\x07\x16\xaf\x07\x41\x19\xe3\x4a\xf9\x8a\xd7\xfb\x43"
+  "\x1f\x4f\x43\xf9\x01\xbe\xb7\xe4\xb2\x38\x47\x4f\x97\x5e\xdd\x9e"
+  "\xeb\xd3\x3c\x16\x97\x9a\xd9\x82\x40\x17\x38\xed\xe4\xff\x73\xba"
+  "\x50\x79\xed\x4c\x90\xd3\xb5\x1c\xe9\x1a\xf7\x51\x3b\x13\xea\x74"
+  "\x2d\xc5\xe5\xda\x04\xa7\x6b\x09\x2e\x6d\x26\x38\x5d\x8b\x76\xb9"
+  "\x6f\x85\xd3\xb5\xb1\x2e\xd7\x8a\x9d\xae\x0d\x15\xaf\xf9\xc0\xf9"
+  "\x32\xf9\x1b\xde\xe9\xc1\xe2\x79\x35\x9c\xaf\x71\x3a\x1f\x24\x9e"
+  "\xc7\xe7\x37\x99\xc9\x7b\x71\xe2\x79\x46\x7b\xde\xfe\x3f\x89\xdc"
+  "\x7e\x63\x23\xb7\x71\xfc\x33\xc8\xe1\x3b\xd7\x6f\x78\xb1\x70\x39"
+  "\xfa\x7d\xb8\x56\x89\x7c\xe5\xcc\xdb\x73\x93\x75\xd3\x17\xbe\xa1"
+  "\x4b\x8c\x4f\x42\xf7\x95\x39\x33\x93\x74\x73\xe6\xc5\xc5\x2b\xe2"
+  "\x94\x07\x61\xcc\x3e\xcc\xf3\x85\xb1\x4f\xc4\x98\xfa\x4d\x8e\x3c"
+  "\x14\x80\xab\xf0\x2c\xd0\xd7\xc6\x32\x7b\x4a\x01\x8f\xe7\x5d\x81"
+  "\xb1\x53\x78\x9c\x14\xf2\x42\x03\xf9\xe7\x5b\x62\x9c\x14\x23\xd4"
+  "\xdd\xe2\x39\x4e\xca\x77\x39\x2c\x3e\x20\xd4\xe3\x71\x52\xbe\x5b"
+  "\x09\xf3\xfc\x19\xda\x9b\xe7\x95\xe0\xf9\xb6\xfe\x29\xc9\x26\x96"
+  "\xa9\x1d\x2c\xc6\x5e\x26\xb7\x65\xb8\xc6\x3b\x0d\xad\xc4\xfb\xc4"
+  "\x6f\xe3\x95\xf2\xfd\x4d\x5a\x7e\x5d\x5a\x1f\xc4\x67\x1a\x42\x6b"
+  "\xa0\xdc\xbb\x01\xca\xcc\x7e\xcf\xae\x35\x71\x5b\x5e\x7e\x68\x2d"
+  "\xbe\x13\xbe\xb7\xf2\xdd\xd4\xff\xd5\x40\x9a\xa6\xc9\xef\xd6\x94"
+  "\xe3\x14\x4b\x4d\x7c\x87\xa6\x52\x3e\x47\xbb\xbc\x2b\xf3\x4f\xa4"
+  "\x9a\x50\xcc\xb5\x58\x83\x78\xc6\xf7\x0c\x40\x39\x3f\xb4\x46\xea"
+  "\x8f\x53\xff\xf0\x9b\x90\x2f\xf4\x2f\x97\x8d\x09\xd0\x94\x02\x4d"
+  "\xc5\x77\x08\xa7\x59\xff\x0c\x65\x3e\xf0\xb8\xd7\x16\xf3\x84\xb0"
+  "\xb5\xea\x3b\x47\xfe\x1f\x5c\xa3\xb8\x0d\xf3\x3b\x59\xfe\xc3\x18"
+  "\x57\xf9\xd2\xfa\xf5\x9d\x93\xfc\xc7\x9f\x09\xe7\xa2\x9d\x79\xc8"
+  "\xe9\x79\x6f\xe1\xf3\xa0\x1e\xe1\x7e\xf7\xa1\x2c\xe7\xbc\x99\x34"
+  "\x95\xa3\x2f\x26\xde\x8b\x7d\xf4\x94\x1b\xce\x53\x0c\x42\x79\x1c"
+  "\xbf\xab\x91\xc6\xb1\x80\xe5\x28\xfa\xce\x2c\xd9\xeb\xd8\xbe\x1f"
+  "\xa8\x53\xe0\xc8\x95\xdc\xcc\xe2\x98\x53\xc3\x27\x21\x8f\x05\x90"
+  "\x58\x3e\xb6\xcd\xfd\x11\xe3\x71\xce\x70\xac\x6f\x4e\x12\x69\x1e"
+  "\xc9\xfb\xdf\xfc\x24\x9e\x97\xfd\xdc\x9b\x0b\xa4\x7a\x12\x2e\xf3"
+  "\xef\x55\xcd\x73\x58\x3d\x9e\xbf\x36\x9a\xd3\xfc\x01\x4d\x03\x69"
+  "\xce\x14\xeb\xf3\xf8\xa8\x2c\xfe\x4d\x73\x11\xcd\x1f\x1d\xdd\x9e"
+  "\xd5\x0c\xfa\xcf\x3f\xc7\xf3\x71\xe4\xcf\x85\x63\x26\xf6\x05\xc7"
+  "\x08\xf7\x68\xd3\xfc\x4f\x42\x80\x3e\x91\xee\xf7\x6c\x32\xff\xe9"
+  "\x7b\x9a\x49\x0b\x97\x21\xd4\xd4\x8a\x36\x56\xfe\xae\x2d\x77\x38"
+  "\xf9\x18\x07\x48\x75\x38\x76\xb3\x6b\xcc\x77\x5b\x9f\x8c\xf6\x20"
+  "\xf1\x5a\x32\xee\x63\x75\xfc\xdf\xcb\xe9\x7f\x3f\xfc\x9f\x26\xd3"
+  "\xd2\x55\xa9\x6c\x6d\xf5\x95\xf7\xc8\xb7\x68\xa1\x1c\xe0\x52\x0e"
+  "\x52\x94\x17\x93\x81\xcc\xff\xb6\x8d\x36\x32\x5f\x6d\xf1\xbc\xd8"
+  "\xf6\xcd\xac\x3f\xc9\x74\x24\xf0\x86\x19\xf7\x3c\x8b\xf3\xd0\x8c"
+  "\x7b\xa5\x03\x6d\xaf\xb1\x7d\xd2\x70\x7d\xa8\x78\x0c\x15\x8f\x43"
+  "\x78\xee\xd0\x7f\x39\xe5\xff\x46\x1b\xcd\xbf\xcc\x9e\xf2\x91\x4b"
+  "\xf9\xda\xa5\x7c\xe4\xb8\xcf\x5a\xcc\x9f\x1a\xd3\x9e\xd5\xa2\xed"
+  "\x2e\xf7\x3b\x5c\x1f\x29\xed\x99\xb6\x1b\x42\x57\x08\x86\xd5\x39"
+  "\x98\xab\x12\xe3\x6c\x65\xb4\x60\xac\x95\x36\x62\x22\x9d\xc4\x94"
+  "\xd4\x9e\x89\xf9\x2a\xab\xad\x2c\x76\x31\xee\x35\x55\xa1\xdd\x1c"
+  "\x65\xc7\x6a\xfd\x59\x96\xab\x72\x51\x0b\x19\xa8\xff\x25\x6d\x84"
+  "\x31\x28\xb2\xe7\x87\xae\x10\xf9\x68\x1d\xac\x81\x77\xc3\x58\x30"
+  "\x7b\x31\xcb\xb5\xdc\xc2\xbe\x7b\xf9\x9f\x21\x67\x87\xb0\x3a\x34"
+  "\x7a\x1d\x1f\xbb\xb3\xcc\xf6\xb5\x29\x4b\xca\x47\xd8\xe2\xc8\x7f"
+  "\x6c\x26\x67\x43\x2f\xf6\x9d\x93\x00\xe7\x9a\x94\x3e\xd3\x67\x59"
+  "\x9b\xd8\x77\x33\x69\xd9\x8c\x6d\xb7\x67\x9d\x0d\x70\xcc\x59\x38"
+  "\xbf\xc8\x46\xee\x84\x7e\x9d\x91\xda\x87\xeb\x30\xff\x9b\xcb\xf0"
+  "\x3a\xb6\x79\x31\xff\x5d\x68\xf7\x6c\x98\xd9\xd7\xc7\x97\xfb\x5c"
+  "\x9f\x85\xf5\xef\xc3\xb2\xee\x64\x20\x98\x0b\x39\x30\x97\x0c\x82"
+  "\x61\x74\x26\x8f\x85\x3d\x3a\x87\xdb\x18\xcf\xae\x43\xbf\xae\x55"
+  "\x97\x88\x2f\xfa\x40\x70\x9e\x3d\xcb\xf7\xf7\xc0\x39\xc0\xea\x12"
+  "\x98\x23\x0c\x13\xbc\x5b\xf7\xcf\xb2\x18\x3f\xab\x2e\x10\xff\xbc"
+  "\x44\x29\x96\xf7\xd9\x36\xa7\xfc\x03\xe2\xfe\x92\x73\x83\xf0\x4b"
+  "\xf9\xaa\x4e\xde\x47\xd7\x3e\x60\x7f\xa1\xad\x42\x8f\x32\xa6\x66"
+  "\x34\xb3\x1b\x02\x5d\xf4\xdc\x47\xf5\x5c\xbc\x8f\xf6\xae\xb5\xed"
+  "\x59\xe7\x62\x1d\x79\x17\xa0\x4e\x1e\xfa\xde\x43\xfb\x8e\xf7\x4c"
+  "\xc4\x67\x9c\xcb\xe1\x73\xfd\x5c\x91\x90\x3f\x3a\x13\xfb\x20\x9e"
+  "\x2f\xaa\xb6\x59\x31\xc6\x82\xdb\x38\x55\x2c\x9f\x1b\xfa\x84\xaf"
+  "\x1e\x9d\x89\xfb\x73\x1e\xb3\x4a\x7d\xfe\xbe\x08\xf7\x85\x60\x9f"
+  "\xf9\xd8\x7e\x9f\x2f\x8d\x63\xee\x05\x68\x3b\xfd\x28\x69\x24\xdf"
+  "\xdf\x81\x7e\x73\xb8\xcf\x09\xe7\x30\x1f\x83\xef\x99\xce\xc7\x9e"
+  "\xcf\xea\x9c\x63\xba\x3f\xcb\xad\x03\xed\x6f\x64\xf9\xc1\xe0\x1d"
+  "\x80\x16\xc6\x74\xdc\x5b\xff\x3d\xdb\xe3\xb3\x3c\x91\xf0\xf7\x66"
+  "\x7e\xb2\xdf\x8b\xdf\x49\xbe\x8f\x96\xd6\x0a\xb3\x78\x6e\x15\x3e"
+  "\x3b\xb9\x93\x9c\x23\xdf\x8f\xc2\xbc\xdf\x30\x1e\x06\x8c\xef\x56"
+  "\xdd\x06\xf3\x24\xa5\x13\x79\xc1\x80\xf9\x24\xa1\xfe\x48\xbe\xbe"
+  "\xe1\x98\x7f\x3f\x10\x9f\x8f\x63\x0b\xb4\xb3\xc0\x98\x6e\x86\xb6"
+  "\x77\x48\x63\x9a\x37\x00\xf5\x9d\x73\x35\xdd\xad\x0d\x76\xe8\x73"
+  "\x35\x50\xce\x78\xe7\x51\xe8\x9f\x65\xa9\xd0\x6f\x74\x26\xfa\x64"
+  "\xc3\xff\xe2\xde\x34\x4e\x3b\x3e\x97\x2c\x93\xe0\x19\x26\xf4\x6f"
+  "\x40\xac\xc4\x18\x64\xf0\x4e\x36\x71\xfc\x58\x3e\x06\x43\x32\x1f"
+  "\x07\xb1\x7e\x29\xb7\x17\xdf\x75\xb8\x3d\xcb\x32\x41\xb6\x17\x5b"
+  "\xd8\xda\x8d\xfc\xb6\x91\xe9\x84\x96\x04\xa7\x3e\xb7\xb1\x7d\xa6"
+  "\x17\xd0\xd6\x67\xd1\xe0\xb3\x72\x31\xfe\x16\xf2\x45\xb3\x33\xff"
+  "\x7f\x7f\x1e\xfb\x89\x3e\xbf\xf6\xbe\xc3\xf5\xb0\xde\xe2\x1a\xa3"
+  "\x87\x7b\x42\x60\x2e\x64\x76\xb3\x16\xb2\x5c\x70\xf0\xcc\x7a\x69"
+  "\x2d\x04\xfd\x02\xd6\x85\xf3\x87\x99\xde\x09\xf2\xb4\x49\x40\x79"
+  "\xe6\x3c\xe6\x3c\x44\x7d\xa3\x42\xc4\xd8\x8a\xf6\xac\xf3\x1a\xe9"
+  "\x9b\x97\x1d\xf7\x4d\x9c\x63\xdf\x7b\xdb\xa4\x1c\x67\x3c\xde\xdd"
+  "\xf9\xa1\xf2\x3e\x8b\xf3\x61\x5d\xf6\x59\xe0\x1e\x9b\xb5\x2c\x17"
+  "\xd6\x16\x5c\x53\xaa\x5a\x1a\x71\x8d\x60\xf7\xe3\xde\x8b\x74\xd0"
+  "\xc9\xf9\x3e\x9d\x46\xb4\xcf\xb3\x9c\x21\xd8\x17\x9e\xbb\xa1\x81"
+  "\xfd\x0f\x7c\xeb\x8b\x47\xce\x4b\xe7\x37\x3b\xf2\x78\x03\xbd\xf1"
+  "\x5b\xdb\x3e\xdf\x67\x89\xf1\x3e\x5c\xaf\xcf\x1f\xc6\x9c\xd4\x50"
+  "\xa7\x42\xca\x47\xcd\xf2\x4f\xf3\xf7\xd9\xe5\x31\xae\xe1\xa3\x24"
+  "\x14\xf7\xe5\xe3\x3e\x36\x36\x06\x9a\x8f\x2b\x30\x56\x32\xc6\x7d"
+  "\x34\xa6\x62\x4e\x93\x0b\x6f\xbd\x3b\x80\xed\x05\x6e\x33\x3e\x7a"
+  "\x01\xfd\xb0\x5a\xce\xa4\xb1\x78\x46\xfe\x11\x29\x36\x8a\xf7\x31"
+  "\x79\xa2\xef\xc7\x28\xd3\xb5\xb0\x5c\x01\xd8\xe6\x55\xc7\xfd\xbd"
+  "\x10\x29\xca\xa6\x2d\x80\xfb\xb7\x37\x93\x0b\x4c\x76\x87\xff\x07"
+  "\x34\x93\xd6\xad\x3c\x2f\x2a\x8f\x5d\x2f\xfa\x63\xf7\xe2\xb1\x2c"
+  "\x60\xcc\x58\x6c\x81\xd6\x7b\x75\x0f\x61\x0e\xe1\xd6\x60\x16\x47"
+  "\xda\x10\x5a\x27\x8e\x41\xdd\x2a\xde\xaf\xc0\xa9\x29\x6a\xd6\x47"
+  "\xec\x9f\x97\x7d\x6b\x11\xf5\x88\x5e\xed\x59\xad\xa1\x52\x0c\x0c"
+  "\x2e\x4f\xf1\xf8\xd2\x9c\x16\xad\x1b\x44\xf9\x59\xf2\x2b\xad\xff"
+  "\xe1\xcf\x6e\x4d\x10\xdb\x2c\xe5\x31\xb6\x2f\x04\x41\xbb\xa5\xd0"
+  "\x8f\x32\x49\x9f\x11\xf7\x10\x0d\xe1\x7a\x56\x6b\x8d\xac\xcf\xf0"
+  "\x31\x54\xec\x6f\x9b\x37\x2f\x49\x17\x37\x73\x81\x7e\x5a\xd2\x8c"
+  "\x04\x5d\x7c\x62\xe2\xbc\x44\x1d\x06\x39\x72\x9e\x3f\x3c\x0f\x50"
+  "\x6b\xa3\x98\x33\xaf\x44\xce\x99\xd7\x36\xc4\x39\xcf\xa4\x99\xb4"
+  "\x85\x5e\x1b\xdb\x45\xdb\x04\x4f\xed\x18\xd4\x42\x29\xfc\xca\xe0"
+  "\x67\x84\x1f\xcb\x37\x30\xd5\x4a\xc2\x60\xad\x67\x98\x27\xc7\x76"
+  "\x68\xc3\x38\xa0\x61\x0d\xa4\xed\xe3\x8d\x82\x2f\x61\xb1\x7a\xb2"
+  "\x84\x52\xac\xbf\x09\xee\x87\x1f\xc6\x1b\xad\x80\x1f\xbb\x4f\xf8"
+  "\x82\xed\x4b\x2f\x75\xbe\xc6\xfd\x47\x96\x56\x62\x1d\xba\x0c\x55"
+  "\x44\xcc\x09\xce\xeb\xb9\xf4\x41\x4d\xb3\xce\xc6\x8a\xf5\x98\x2e"
+  "\xd9\x67\x19\xd1\xb9\xa9\xe7\x43\xb3\x1a\x63\xc4\x7a\xcc\xef\x58"
+  "\x7a\x1f\x8c\xd5\x0f\xf5\xa5\x7a\xbe\x34\xeb\x7c\x93\x58\x8f\xf9"
+  "\xc8\x09\x59\x6a\x77\xcf\xf5\xa3\x59\x7f\x4e\x10\xeb\x69\x9c\xdb"
+  "\x73\xaa\xd3\x4b\xc8\x3a\x8a\x31\xf1\x6b\x84\x65\xbe\x41\x5c\x76"
+  "\x6a\x9b\x00\xf5\xdd\xee\xab\xf2\x8e\x4e\x17\xdb\x5c\xe9\xa4\x9f"
+  "\x31\x33\x7e\xf4\xcc\xb9\xc9\x98\xa9\x29\x69\xde\xc2\x24\x3c\xce"
+  "\x9d\xf6\x26\x3b\xcc\x9b\xfa\xfa\x0c\xfe\x4f\xd2\xec\x50\xfc\x67"
+  "\x36\xf0\x1b\x1e\xe3\x16\xea\xf1\x30\x63\x1e\x16\x53\x12\x86\x2c"
+  "\x9c\x21\xa5\xa7\x77\xe6\xc3\x90\xf6\xac\x4b\x45\xc0\x1b\x2b\x39"
+  "\xce\x5e\x82\x75\xf1\x14\xf3\xf7\xc2\x7c\x44\xfb\x43\x6c\x44\xb2"
+  "\x6b\x29\x63\x7b\x5c\xfa\x0c\x63\x7b\x04\x2e\xd3\xcf\x08\xb4\xcd"
+  "\x8c\x87\x35\x03\xd6\xcb\x4b\x8d\x66\xf2\x86\x55\xc4\xc6\x26\x16"
+  "\x27\x34\xeb\xd2\x50\xd1\xb7\xd3\x57\x30\x84\x16\x61\xfc\x7b\x28"
+  "\xb3\xdc\xcf\x50\xae\x80\x72\x23\x94\x31\xe7\x73\x10\x94\x37\xa3"
+  "\x4d\x0a\xca\x5a\x28\x0f\x14\x0c\x3f\x2b\xc5\xbd\xbc\x50\xd6\x41"
+  "\x79\x70\x7b\x56\xfb\x58\x69\x5e\xb8\x97\x95\xdb\xe3\xa4\x7c\xd4"
+  "\x3c\xf7\x74\x7b\x92\x23\xf7\x34\xe6\x43\x4a\xd7\xc4\xb0\xf5\x97"
+  "\xc9\x20\xed\x85\x3e\xda\x41\xd8\x66\xa1\xb4\x5e\x72\x7b\x47\x7b"
+  "\x89\x14\xa7\x84\xdb\x33\xda\xcb\x9c\x72\x78\x63\xb9\x42\xca\xe1"
+  "\x8d\xf6\x2e\x96\x43\x10\x8e\x34\x0b\xe3\xb1\xd2\x12\xb7\xb6\x3c"
+  "\x96\x7b\xd2\xfa\x08\xc6\xb6\xb5\x64\xc4\xa9\x7e\xb6\x11\x6d\x68"
+  "\x50\xe6\xb1\x19\xe9\x39\xd2\xce\x62\x8d\x48\x71\xdb\x9c\x63\x36"
+  "\xb8\xdd\x0f\xf5\x35\xc8\x0c\x2c\x5f\xd4\xec\x79\x81\xb6\x69\xf1"
+  "\x5c\x0e\xb4\xe6\x72\xfc\x1a\x5e\xc0\xe5\x05\x6b\x0a\x7d\x89\xe7"
+  "\x14\x31\x13\xab\x0d\x75\x96\x40\xd5\xec\x79\x14\xee\x0d\x4c\x99"
+  "\x16\xcf\xce\x41\xbd\xe5\x20\xab\x89\xfd\x7b\xcd\x34\x10\xf7\x92"
+  "\x0a\x62\x2c\x0a\x6b\xcc\x94\x41\x99\xf8\x1c\x7f\x26\x87\x7c\x4d"
+  "\x02\x30\x07\x24\xf6\x6d\xa3\x53\x5c\xb9\x55\x70\x0e\x7d\x48\x5b"
+  "\x5f\x22\x01\x18\x47\x57\xec\x4b\x0c\xcf\xbf\x65\x6d\x93\x62\x3a"
+  "\xc1\xf3\x62\x5c\xdf\xe7\xa5\xdf\x30\xae\x0c\x9e\x31\x24\x72\x1c"
+  "\xfc\x37\x44\x4c\xa3\xec\xcc\x9b\x03\x5b\xfb\x8d\xcc\x6c\xdd\xf6"
+  "\xd4\xed\x3c\x57\x66\x07\xe8\xff\xed\x4d\xcc\x87\x05\xf5\x92\xf6"
+  "\xe8\x42\xee\x83\xda\xb1\x14\xe3\xd6\x0a\x59\x28\x4f\xe2\xfe\xe4"
+  "\x8e\xd9\xc8\xb3\x54\x33\xbc\x70\xd3\x52\x8c\x91\xac\x82\x31\xee"
+  "\x98\x86\xd7\xc4\xd8\x58\x6a\x16\x4b\xca\x4e\xb4\x6c\x2f\x2e\xc8"
+  "\x28\xb8\x07\xf5\x0c\xb1\xcd\x41\xb9\x03\xed\x49\x42\x56\x87\x3f"
+  "\xf2\x2d\xd0\x18\x63\x75\xb4\xd1\x7e\xa1\x39\xb4\xef\x88\x31\xc8"
+  "\xc7\x28\xeb\x9a\x34\x38\x66\x1d\xb5\xf0\xdc\x67\xe0\xf7\x5f\x3c"
+  "\x77\xcb\xab\x4d\x52\x9b\x18\xbf\x0c\x64\xa8\xcd\x70\xd4\x40\xbf"
+  "\x6d\x4e\x39\xed\xc4\xbd\xc7\x9d\x83\x30\xae\x1a\xb6\xcd\x65\x67"
+  "\xdb\x64\x2e\x83\x74\x86\x98\x49\xa0\x81\xcf\xc5\x4e\x90\x7f\xb2"
+  "\x4b\xc4\xff\x41\xfe\x79\x3c\xd2\xa5\x8d\xb7\x25\x5b\x29\xe7\xe9"
+  "\xce\x38\xe0\xd1\x67\xe0\xf7\x5f\x50\x5f\x2f\xe5\x6d\x5f\xae\x66"
+  "\xfb\x24\xcf\xf8\x68\x71\x5f\x79\x67\x8e\x74\xde\x4f\x15\x06\x63"
+  "\xda\x59\x28\xcd\xfd\xd6\x7e\xc3\xd3\xa0\x5c\x22\xd9\x58\xb8\xcd"
+  "\xa5\xb3\xcc\xa9\x9c\x03\xe5\x0a\xa9\x0c\xff\xd7\x4a\x58\x81\x7a"
+  "\x62\x2b\xe8\x92\xa8\x77\xce\xd0\x82\x5c\xa8\x45\x3d\xaf\x13\xe8"
+  "\x9f\x9d\xc0\xeb\x5e\x06\x19\xf4\xed\xc1\xe2\xff\x01\x66\x5f\xbf"
+  "\x91\xd2\xbb\x08\x59\x3e\x81\xfc\x7d\x6c\x63\x85\xfc\xd5\x39\x96"
+  "\xbe\xa1\xe3\xa1\x0e\xac\xff\xed\xfc\x7d\x93\xcf\x16\xaf\xec\xd4"
+  "\x44\xa1\xc7\xa3\xf1\x75\xe4\x2f\x1b\xf3\xc3\xca\x4d\xd5\x44\xa2"
+  "\x8c\x89\xb1\x35\x58\x1c\x3c\x8c\x05\x69\x23\xbd\x58\xfc\xfd\xfc"
+  "\xd5\x29\x2c\xee\xfc\xa2\x90\x00\x29\x0e\x24\x60\xcb\x18\xaa\x9e"
+  "\x1d\x84\xb1\x21\x59\x9e\x8d\xf6\x90\x3e\x2c\x1e\xa4\x18\x07\x72"
+  "\x43\x32\x09\x2a\x12\x78\x1c\x48\x16\x77\xa3\x17\xe8\x24\xc9\xee"
+  "\x63\x41\xd2\xac\xff\xde\x25\xc5\x82\xa4\x97\xec\x56\xf8\x7f\x30"
+  "\xbc\x3b\xe6\x1f\x0f\x61\x65\x39\x86\x93\xaf\xdb\xd8\x90\x6a\xc0"
+  "\x38\x35\x8f\x0d\xe9\xdd\xda\x60\xd3\x70\x3e\xb1\x45\x4a\x79\xe5"
+  "\x9d\xce\x01\xfe\x59\xc5\xdc\x58\x9d\x03\xc5\x73\x29\x66\xf2\xd6"
+  "\x2e\xd1\xbf\xd2\x82\x36\xb2\x02\x66\x07\xeb\x28\xa6\x97\x13\xd6"
+  "\xb9\xc3\x97\x0b\xfd\xb6\x84\x5d\x60\x31\x1f\x6c\x40\x7b\x3b\xc3"
+  "\x3a\xae\x37\xda\xca\x5c\xe7\xf0\xf4\x19\xf3\xe2\xe2\xa7\xce\x9a"
+  "\xa3\xd7\xbd\x14\xf5\x0c\x4b\x2a\x38\x44\x37\x33\x29\x9e\x2d\x3f"
+  "\xba\x97\xc6\x3d\x1d\x11\x11\x35\xf5\x37\x51\x4f\x45\x4d\xfa\xcd"
+  "\x93\x7c\x77\x62\x54\xe2\x62\x4c\x4c\x99\x34\x4f\x87\x37\x4d\x17"
+  "\xb3\x59\xa7\xc6\x27\xce\x73\x9d\xfb\x41\xcc\xa6\xa5\x66\xf6\xdb"
+  "\x36\xfc\x9f\xdb\xcd\xec\x51\x92\x3d\x8b\xe3\x9c\x7d\x1c\x8e\x2d"
+  "\xcb\x13\x9a\x65\xab\x44\x59\x4a\xcc\x33\x8e\x6b\x8c\x2f\xce\x5f"
+  "\x5c\x6b\xda\xb3\xec\x99\xce\xf1\xae\xc4\x7b\x37\xab\xf1\x3e\x71"
+  "\xde\x8a\xe7\x76\xd2\x3b\xef\xcc\xe0\x31\xab\xec\x3b\x24\x1b\x37"
+  "\x9e\x93\xfa\xd0\x80\x75\xb2\x6c\x76\x39\x9f\xad\xbd\x5e\xce\xd9"
+  "\xc8\xfe\x14\x63\x44\x08\x8a\x2e\x7e\x20\x97\xf4\x82\xdf\x4d\xf8"
+  "\x1b\xef\xc0\xf2\x64\x5a\x87\xfa\x59\xa0\x0a\xd6\xdb\x14\x1f\x9e"
+  "\xf3\x29\xbb\x96\xe5\x29\x88\xb0\xdb\x7c\xa6\xda\xd5\x70\xf4\xa1"
+  "\x53\xed\xbe\x4c\x27\xa4\xc9\xb4\x96\xed\xab\x4f\xa6\x35\x98\xdb"
+  "\x0c\xf8\x38\x27\xc2\x96\x9e\x13\x61\xa7\xb6\xa9\x20\xab\xc3\xf1"
+  "\x9f\xb8\x3f\x3c\xc2\xfe\x4f\xca\xf2\xbb\xe0\x3e\x7a\x1e\xbb\xaf"
+  "\x02\xfd\x25\xa7\x00\x0f\x6f\xbc\xc0\x73\xe2\x46\x2c\xfe\xfe\xc4"
+  "\xd4\xc5\x66\x9e\x13\xf7\x1c\xcf\x23\xcd\x73\x6d\x93\x74\x68\xe7"
+  "\xc0\x54\xbb\x8f\x2e\xc2\x7e\x99\xf2\x3d\xae\x82\xb1\xbb\x3c\xb7"
+  "\x88\xa7\x0b\xee\x20\x6a\xb4\xad\xd8\xff\x10\xa2\xc7\x38\x7d\x19"
+  "\x16\x6a\xc5\x78\x2f\x7b\x3b\xeb\xd4\xba\x64\xcc\x03\x26\x9c\xae"
+  "\xd6\x87\xba\xdf\xe3\x9c\x17\x5a\x47\xd7\x0c\xab\xa5\x79\x3f\xdf"
+  "\x41\xd7\x0c\x8f\xa2\x86\x11\xe8\x8f\xae\xa2\x79\xc3\x0d\x50\x86"
+  "\xf3\xa3\x66\xd3\x35\x23\xa2\x68\xde\x98\xf1\x70\x84\xf2\xaf\x06"
+  "\xd3\x35\x23\xa1\xdc\x57\x03\xf7\xd5\xd0\xbc\x7e\x99\x50\x2f\x92"
+  "\xe6\xdd\x66\x81\x23\x94\xfb\xc7\x42\x3d\x28\x0f\xa8\x81\x23\x94"
+  "\xb5\x61\x67\x08\x2d\x85\x7b\xe0\xdc\xd3\x84\x3f\x6b\x5c\x00\x7b"
+  "\x56\xde\x78\x2d\x7f\xc6\xaf\x07\xf3\x67\x4c\x0c\xe5\xcf\x78\x71"
+  "\x0c\x7f\xc6\x1d\x70\xdf\xb0\x3a\x9a\x77\x57\x11\xd4\x8b\xa6\x79"
+  "\x83\x72\xe0\x08\xe5\x7b\x92\xa0\x1e\x94\xef\xc5\x67\x41\xf9\x67"
+  "\x13\xa0\x3e\x94\x83\x47\x42\xfd\x7a\x9a\xf7\x40\x08\xd4\x8b\xa1"
+  "\x79\x0f\x62\xfb\x50\x7e\xd8\x1f\xea\x41\x79\x88\x15\x8e\x50\x7e"
+  "\xb4\x09\xea\x43\x39\x0a\xde\x69\x98\x99\xe6\x4d\xb2\x41\xbd\x58"
+  "\x9a\xf7\x5f\xf0\xbc\xe1\x50\x9e\x1c\x07\xf5\xa0\xfc\x2a\xdc\x3f"
+  "\x02\xca\x31\x95\x50\x1f\xca\x53\xe0\x5d\x87\x35\xd2\xbc\x58\x78"
+  "\xce\xf0\x38\x9a\x37\x0d\xdf\x19\xca\x33\x4a\xa0\x1e\x94\xe3\xb1"
+  "\x3f\x50\x7e\x03\xee\x1b\x09\xe5\x04\x18\x83\x61\x4d\x34\xef\xcd"
+  "\x62\xa8\x97\x40\xf3\xe6\xea\xe1\x08\xe5\xf9\x61\x50\x0f\xca\x49"
+  "\x30\x86\x23\xa0\x9c\x6c\x86\xfa\x50\x5e\x8c\xef\xdb\x42\xf3\xd2"
+  "\x56\x40\xbd\xd9\x34\x2f\x23\x1a\x8e\x50\xce\x1a\x02\xf5\xa0\xfc"
+  "\x16\x8c\xdf\x08\x28\xff\xb6\x16\xea\xcf\x76\x4f\xcf\xdf\x81\x2c"
+  "\xdc\x8b\xd0\xbc\xb5\x15\x74\xd9\x4d\x70\x2c\x4c\xa1\xcb\xfc\x42"
+  "\x68\x5e\x51\x08\x9c\x87\xe3\xba\x38\x28\x0f\x11\xcb\x70\x7c\x3f"
+  "\x12\xca\xa1\x62\x19\x8e\xeb\xc7\x40\x79\xa8\x58\x86\x63\x31\x96"
+  "\x47\xd2\xbc\x0f\xe0\xd8\x0b\x8e\xc5\xbb\xa0\x3c\x46\x2c\xc3\xf1"
+  "\xf7\xfe\x70\xb4\xd1\xbc\x0d\x6d\x70\x3e\x8c\xe6\x6d\xdc\x01\x65"
+  "\x38\x6e\x4a\x82\xf2\x58\x38\xd6\x41\x79\xac\x25\x38\xd8\x80\xbc"
+  "\x2a\xf4\xb3\x19\xe8\x80\xd1\x91\x19\x17\x89\x1a\x79\x14\xf3\x5d"
+  "\xc0\x3a\x7c\x4f\x83\x4a\x95\x5b\x9a\x6e\x66\xf2\x81\x7d\xed\xb0"
+  "\x1a\x61\xc0\xf0\x48\x38\xdf\x0b\xea\xdd\x74\x46\xa5\xde\x89\x78"
+  "\x64\x4a\x33\xb3\x9c\x7b\x62\xcc\xc9\x5e\x70\xcf\x67\x20\x4b\x8d"
+  "\x04\xfc\x57\xc3\x38\x05\xd0\x2c\xbf\x0b\x70\x5c\x49\xb3\x6e\x69"
+  "\x80\x71\x82\x72\xdf\xaf\xe1\x08\xe5\xe1\xef\xc0\x78\x41\xf9\xd5"
+  "\xa7\xe1\xb8\xb2\x3d\x5b\x1d\x64\x26\x94\xe7\x9f\xdd\xf6\x94\x26"
+  "\xd0\x46\x69\x04\x20\x2d\xfd\x20\xce\x10\x68\x33\xc2\x18\x8f\xd7"
+  "\x07\x62\xec\xc4\x8f\xee\x87\xbe\xfa\x61\x7c\x1c\xd4\xb7\x7a\xd1"
+  "\xcb\x83\xd5\xfc\xd9\xb7\xd0\x06\x95\xfa\x29\xcc\xd3\x40\x07\x0c"
+  "\xf2\x74\x7d\x1a\xbb\x7e\x5f\xbc\x86\x5f\xf7\x27\xf2\xf5\x57\xf1"
+  "\xfa\xb2\x40\x8c\x77\x7e\xff\x20\x76\xdd\xd4\xd6\x24\xbe\x97\x0f"
+  "\x5e\xdb\x80\x75\xcd\x2a\x35\xb3\xab\x99\x55\xaa\x72\x9a\xe5\x43"
+  "\x5a\x35\x23\xa2\xa1\xef\xa0\xff\x0a\x95\xa2\xac\x5f\x44\x35\xa1"
+  "\xc5\x3c\xe6\xc8\x68\xb7\x32\x30\xea\xba\x42\x41\xb8\x35\x17\x30"
+  "\x14\xf5\x67\x58\x4b\xd5\xba\xf4\xc1\x65\x0d\x2a\xdf\xa2\x0d\x28"
+  "\x5f\x05\xcd\xe0\xd8\xaa\xf2\x99\x76\x79\xf5\x88\xcd\xba\xd4\x40"
+  "\x78\xbe\xef\x86\x0c\x2b\xbd\x68\x4c\x7f\x9a\x9c\xe1\xe7\xcd\x6c"
+  "\xaf\x11\xff\xbf\x92\xf9\x90\xf2\xff\xcb\x98\xbd\x1a\xda\xc2\x7b"
+  "\x9d\xf5\x15\x7b\xf6\xbe\x04\x61\xc0\x0c\x33\xfb\x06\xaf\xf2\x89"
+  "\xdf\x2d\x98\xd5\x81\x49\xc4\x4f\x97\xba\x17\xda\xf7\xd9\xa2\xd0"
+  "\x6d\x1d\x75\xd9\xb5\xfc\x3d\x50\x77\x3d\xda\xa1\xb2\x7d\x76\x39"
+  "\x72\x19\xc3\x3b\xfc\x0e\xd7\x51\x35\xc1\xdc\xab\xbe\x4c\x56\x56"
+  "\xf9\x8e\xc1\x18\xb5\xb6\xa0\x67\xcd\x36\x83\x2d\xd3\x5e\x30\xa3"
+  "\x86\xae\x9d\x61\xee\x63\x53\x11\xe6\xeb\xaf\xf2\x9d\xff\x98\x15"
+  "\x65\xd3\x83\x58\xf7\x41\xa1\x57\x55\xd9\xa3\x29\x44\x6d\x4c\x3c"
+  "\x8a\xe5\x99\x34\xbb\xae\xc5\xd4\x52\x47\x8c\x89\xac\xad\x04\x9a"
+  "\x6d\x09\x13\x7a\x35\x8e\xdc\x88\x32\x7e\x0a\xda\xe8\xbe\xc6\x71"
+  "\x39\x0b\x74\xf1\x6d\xcf\xf6\x1d\xef\xc8\xb3\x0d\x63\x99\x0b\x63"
+  "\x87\xf2\x37\xc6\xcd\x98\x6a\xb7\x63\xbc\xb7\x1c\x33\x8c\x03\xa7"
+  "\x97\xef\x10\xcc\x51\x2e\x3e\x77\x99\xd0\x6f\x84\xa1\x3a\x06\xbf"
+  "\x37\xfa\x63\xfc\xac\x8b\x6c\xaf\xbd\x0d\x73\x0f\xc2\xba\x25\xd6"
+  "\x75\xa6\xdd\x4c\x31\xc6\xc0\xcc\xb9\x49\x89\xf3\x75\x0b\x66\xa6"
+  "\xc6\x3f\x19\xbc\x70\x88\x2e\x31\x45\x97\xc8\x72\xc6\xb3\x13\xb0"
+  "\xcc\x2f\x98\x3d\x2f\x49\x87\xb9\xbb\xbb\xe6\x0e\xd6\x52\xcd\x88"
+  "\x04\x26\x9b\xaa\x7a\xb3\x3d\xb1\xb4\x38\x2e\x27\x29\x8d\x0a\xba"
+  "\xfb\x6e\xa2\xe7\x54\x7e\x63\x3a\x7a\xf9\x62\x5e\x50\xe0\x3d\x1d"
+  "\x11\xe3\x14\x07\xac\xeb\x47\x70\x3f\xa0\x7f\x7b\xb6\xdf\x50\xc7"
+  "\xba\xaa\xea\x9d\xc6\xec\x2e\xd9\x7e\xe3\x81\x1f\x5b\xc4\xef\x6e"
+  "\x3c\x26\x9f\x78\x8d\x7d\x97\xce\xf6\x4b\x30\x93\x04\x1e\x67\xb2"
+  "\x78\x06\xff\x16\xa4\xf2\x63\xf6\x74\xaa\x8b\xcb\xa1\x9b\xef\xc7"
+  "\x7c\x68\x2a\xf6\x0d\xd0\x76\x0f\x35\x91\x0b\x3c\x46\xee\x9a\xe7"
+  "\x2c\x18\xef\xc3\xbe\x76\x94\x5e\x18\xf0\x9c\x45\xf8\xc3\x03\x91"
+  "\x19\x1f\x10\xf5\x76\xc0\x02\x5f\x1d\xcc\x87\xfb\xc8\x3d\x7b\xd3"
+  "\x9b\xd4\xd0\xe7\x8f\xf7\xa6\xd7\xa9\x69\xc1\xe8\xf1\xad\x83\x47"
+  "\xa6\x58\xc5\x1c\xd3\x26\x9b\x95\xfc\x6d\x2c\x41\x1d\xb0\xac\xad"
+  "\x7f\x64\x61\x5b\xff\x51\xd1\xd6\x35\x93\x89\xf1\xbe\x27\xc8\xb8"
+  "\x07\xe9\xf7\x5f\x96\x13\xd2\xa2\xea\x1d\xf7\xe5\x58\xd4\x4b\x46"
+  "\xc4\x5a\x35\x23\xe2\xda\xd6\x3e\xa7\xc7\x98\x56\x1d\x6b\x27\x47"
+  "\x76\x0e\xf8\x45\xcd\x3e\xa8\x73\x10\xf4\xa6\x43\x3a\xe0\xdf\x7b"
+  "\x89\xba\xe3\xfe\x60\xf3\xf6\x4e\x83\xba\xa2\x7c\x0c\xb7\x19\xc7"
+  "\xc2\x9c\x61\xfc\xd4\x2b\xfc\xcb\x1d\xe5\x04\x9e\x4d\xb6\x77\x8e"
+  "\x57\xff\x6d\x64\x97\xeb\x73\xbe\x0c\x2d\x27\xed\x18\xf7\x18\xf4"
+  "\xd2\x3d\x47\x0b\x09\x5d\x3b\xb1\x74\x6b\xaa\x55\x1d\x63\x26\xea"
+  "\xaa\xba\x42\x92\x76\x9a\xdc\x6a\xfb\x3e\xc4\xf7\x8f\x70\x7f\x07"
+  "\xc6\x29\x3d\xa4\x65\xf1\x0a\xd3\x8d\x2c\x7f\x6c\x60\x35\xc8\x1f"
+  "\xc2\xf7\x21\xbd\xaa\xa3\x8c\x04\xae\x0f\xb7\xfd\x5a\x4b\xaa\x12"
+  "\x2c\xc4\x14\x5d\x4c\x3a\xd4\x61\x64\xe7\x2b\xc5\x64\x3d\xe8\x38"
+  "\xeb\xcf\x91\x00\x26\x4b\x5f\x0e\xe9\x65\xbb\x1c\xe2\x6b\x5b\x12"
+  "\x82\xf1\xa3\x28\xfd\x3e\xa4\x37\xca\xd6\xb6\x79\x21\xfe\xd5\x96"
+  "\x62\xf2\x58\x13\x09\xe9\x50\x93\xc0\x8e\x25\x21\xbd\xab\xf5\x85"
+  "\xd0\x16\x08\xcb\x30\xae\x18\xbb\x0e\x63\xda\xe1\x38\xdd\x12\x4d"
+  "\xa2\x5a\x54\xbd\x82\x7b\xd7\x92\xfe\x18\x3b\x15\xe5\x55\x8c\xb3"
+  "\x2c\x04\x4d\x2c\xb5\x07\x3d\xa7\x4f\xbf\x08\xfd\xc2\xf8\x4e\xdb"
+  "\xc2\x2c\x28\xef\x83\x2c\xa3\xc2\x77\x16\x68\x48\xef\xa9\x78\x5c"
+  "\x1d\x3a\x1c\x65\x7e\xa1\x5d\x8b\xb9\x99\xfc\xb1\x9f\x98\x27\x79"
+  "\xe9\x49\x18\xcb\x8c\x10\x5f\xa8\x17\x00\xe7\xfb\x98\x5a\xac\xc4"
+  "\xfe\xc8\x53\xe4\x51\x3d\xcb\x7f\x1b\xb4\x31\x9d\x68\x0c\xe9\x24"
+  "\x48\x37\x9c\xf1\xd2\x38\xfb\xd6\x30\x0b\xcd\xbe\x5d\x8b\xb6\x1c"
+  "\x7e\xee\xe6\x60\xdd\xb3\x84\xe8\x9e\xc0\xff\xfd\xab\x74\xa3\x81"
+  "\x86\x41\x13\x35\x4c\x1f\x41\x7d\x57\xe5\xff\x39\xe7\x71\xff\x9d"
+  "\x1d\xbd\xa6\xc5\x08\xd9\x05\x29\xc2\x32\xdf\x81\x98\x1b\xfb\x9c"
+  "\xca\x7f\x03\xcd\xdb\x5a\x4a\x0b\xa2\x19\x2f\x42\x79\x5d\x47\xaf"
+  "\x7e\x46\x9a\xb7\x2d\x08\xda\x1f\xd3\xa1\xf2\xad\x85\x5f\x9d\x78"
+  "\xbf\x01\xdf\xdb\xbe\xf9\xfe\x04\x7c\x6f\x96\xcf\x07\xde\x6b\x2a"
+  "\xd0\x8c\x0e\x08\x37\xb2\x18\xf7\x97\x61\x7c\xc5\x7c\xa7\x38\x1e"
+  "\x38\x06\xc2\xe5\x90\xde\xec\x5d\x2f\x87\x04\xc0\xf8\x62\x9c\xe4"
+  "\xc0\xf4\x69\x70\xcf\xda\xf0\x5a\xb8\xd6\xa7\x23\x68\xa2\x3f\xe6"
+  "\xd5\x32\xe9\x2d\xc4\xbe\x26\xbc\x06\xe3\x00\xae\x4b\x85\x39\xd7"
+  "\x3f\xdc\x48\xd7\x84\xd7\x8b\x73\x8b\x60\x3f\x85\xbc\x6d\xb1\x1d"
+  "\xb8\x2f\x0f\xfa\x06\xfd\xab\x85\x5f\x9d\x59\xe5\x1f\xd4\x11\x7c"
+  "\x7f\x8a\x59\x75\x53\x13\xf4\x75\x20\xcd\x7e\x6c\x3c\xfe\x0f\xd7"
+  "\x06\x42\x9f\xed\x38\x0e\x38\x1e\xe2\x58\x5c\x94\xc7\xe2\xd5\x15"
+  "\x50\xaf\x51\xc8\x5e\x35\x10\xda\x28\xa7\xd9\x0f\xf9\xcb\xf5\x6e"
+  "\x1e\x24\xd7\x7b\x23\x84\xd7\x5b\x57\xc9\xeb\x0d\xcd\x84\xeb\x3b"
+  "\xf9\x78\xdf\x3c\xad\xeb\x78\xdf\x3c\x59\xbe\x37\xa2\x86\xdf\xbb"
+  "\x22\x86\xdf\x7b\x0f\xde\x9b\xaf\xec\xd3\xcd\x6f\xcb\xf5\x5f\xf0"
+  "\xe5\xf5\x33\x02\x78\xfd\x3b\x27\x38\xd5\xfb\x54\xae\x37\xc9\xc0"
+  "\xeb\xbd\xbd\x99\xd7\x1b\xbc\x05\xae\x9f\x75\xd3\x97\xd3\xf2\x3d"
+  "\x0b\x82\xf8\x3d\x9b\x8d\xfc\x9e\x5f\x8d\x01\x7e\x1a\xa4\xec\x4b"
+  "\xef\xfe\x72\xfd\x39\xe2\x7b\x6f\x8a\xe4\xf5\x47\x35\x39\xd5\x7b"
+  "\x92\xd7\xc3\xeb\x9f\x40\x3d\xff\xb2\x8e\x5e\x29\x56\x5e\x6f\x6c"
+  "\x0e\xf2\x23\xd4\x79\x4d\xc8\xd6\x96\x74\xf4\xea\x5f\x00\xed\x6c"
+  "\x01\xda\x68\xf1\x08\xb4\xd3\x0a\x86\x11\xb1\xf0\xff\x60\xfc\x26"
+  "\x84\x98\x6b\x56\xf9\xf9\x02\xee\xda\xdd\xda\xcd\xb2\x7b\x17\x39"
+  "\xec\x76\x02\xc8\x0f\x6b\x86\xb9\x8d\x87\xc5\xf2\x29\xa3\x0c\xb1"
+  "\x76\x98\xc5\x20\xf0\xbc\xec\xc0\xa3\x20\xff\xf4\xde\x0f\x6b\x61"
+  "\x26\x8b\x87\x5c\x30\x5e\x2f\x0c\x06\x8c\x3d\x4b\x7c\x4c\x69\x4d"
+  "\xa4\x54\x68\x52\x1b\x3a\x89\x6f\x35\xac\x33\x58\xbf\x14\xd6\x54"
+  "\xdd\x5c\x94\x2d\x7a\x1f\x33\x5c\x12\xdb\x2b\x8e\x33\x64\xcc\xe1"
+  "\xb9\xa8\x51\x0e\x43\x6c\x86\xf9\x18\xc0\x72\xa4\xcd\xbd\x09\xea"
+  "\xde\xd2\x17\xfe\xf7\xc7\xba\x80\x89\x9a\x8e\x0f\xe3\x0c\x9d\x03"
+  "\x46\xd7\x74\xfe\xe1\x01\xcb\xe5\x01\xe3\xf5\x97\xd7\x3e\x6b\xb1"
+  "\x7d\x18\x47\x6c\xf7\xdf\x6f\xb0\x0f\xf8\x45\x24\x3c\x1b\x70\xbb"
+  "\x50\xbd\x4d\x28\x55\x6f\x4b\x37\xaa\xb1\xdd\xbd\xe9\xc5\xea\x3d"
+  "\xe9\x35\xea\x3d\x42\x99\x7a\x6f\xba\x01\x8e\x25\x98\x2f\x0b\xe4"
+  "\xbd\x5b\xa6\xed\x49\xaf\x80\x75\xe3\x96\x62\x98\x07\x39\x92\xdd"
+  "\x93\x3e\x6d\x23\xd5\x25\x36\xb2\x3f\xe9\x22\xb1\xf4\x1d\x91\x00"
+  "\xbf\xd9\x96\xfe\xe1\x56\x4b\xff\xc9\x84\xf5\x79\x40\x04\x7b\x47"
+  "\xdc\xd7\xba\x47\xe0\x7d\x16\xc7\x03\xdb\x3c\xb0\x51\x40\x9f\x13"
+  "\x31\x56\xb4\x2a\x60\x45\x97\x58\xd1\x6a\x9e\xab\xcd\x11\x2f\xfa"
+  "\xc7\x88\x15\x2d\xda\x1c\x58\xac\x68\xd0\x1f\x99\x1e\x09\xeb\x17"
+  "\xcb\xef\x68\x03\xf9\x6c\xcd\xb3\x91\xa8\x2f\xa2\x3c\xd6\x9e\x1d"
+  "\x50\x2a\xe9\x7b\x28\x63\xd8\xf3\x47\xa4\xc0\x2f\x09\xce\x57\x98"
+  "\x55\xa5\x83\xa5\xf3\x74\xb5\xdd\x80\xf6\x77\x3b\x4d\xf8\x65\x3b"
+  "\xee\xd5\xa4\x09\xbf\xb2\xaf\x19\x15\x6b\x5f\x13\x6d\x86\x73\x63"
+  "\xe0\xf7\xa4\x3d\xdf\x5e\x00\xbf\x42\xf8\x15\xc1\xaf\x18\x7e\x9b"
+  "\xe1\x57\x02\xbf\x52\xf8\xed\x80\x5f\x19\xfc\x76\xc1\xcf\x08\xbf"
+  "\x72\xda\xd7\xbe\x05\x63\x5d\x42\xdb\x35\x40\x77\xad\xd4\xae\x3c"
+  "\xbe\xb7\x3e\x02\xef\x1b\x86\xf2\x8f\x90\xb7\xb5\x92\x72\xbc\xd2"
+  "\xd2\x8f\x82\x0b\x11\x77\x69\xf0\xc8\x14\xcb\xbd\x71\x99\x96\xfe"
+  "\x11\x99\x96\x7b\x67\x34\x59\xfa\xbe\x19\x0a\xbf\x91\xf0\x0b\xb3"
+  "\xac\x99\xa8\xb1\xf4\x8f\x6e\xb2\xf4\x9f\x58\xdc\x9e\x7d\x2b\xcc"
+  "\x9b\x20\x16\x17\x05\xfe\x07\xfa\x07\x19\xc4\xff\xb7\x98\x55\x1a"
+  "\x36\x1f\xa0\x8d\x58\x28\xef\x32\xab\xfa\xb1\x7a\xad\x03\x26\xea"
+  "\xc4\x7d\x9e\x99\x70\xbe\xd6\xec\x7b\x77\x2c\xaf\xf7\xac\xd9\x79"
+  "\xce\xcc\x99\xa1\x9f\x3a\x67\x5a\xca\xd4\x05\xb3\x67\xce\x88\x5f"
+  "\x30\x5a\x17\x1c\xa7\x0b\x99\x99\x38\x7f\xea\xfc\x85\xf1\x0b\xe3"
+  "\x99\xe8\x04\xa7\x1e\x54\xfa\xb0\xd9\x30\xef\x00\xe8\x01\x7d\x1a"
+  "\x29\xc5\x35\x6b\x42\x1b\xf0\xd9\x7d\x71\x86\x5d\xe7\x2c\x6a\x3b"
+  "\xc8\x2e\x01\x8d\x99\x30\xf7\xc6\xeb\x77\x9d\xb3\xaa\x03\x1a\x75"
+  "\x84\x02\xbf\xe3\x35\x53\x63\x8d\x28\xcb\x7c\x4d\x2a\x51\x96\x81"
+  "\x3a\xdb\xe6\x5a\xd5\x13\xf1\xfe\x3f\xdc\x6f\xd8\x0e\xff\xd3\xb5"
+  "\xcf\x59\xf0\x3e\x0a\xf2\x0d\x3b\x82\x7c\xc3\xcb\xa3\x6b\xf6\xb0"
+  "\xe3\xb3\x96\x3d\xac\xde\x2f\x22\xf7\xe2\xf1\xd2\x52\x5a\x09\xed"
+  "\xa2\xbd\x8d\xfe\x21\x58\xb3\x87\xdf\xc3\xeb\xc0\x5c\x6b\x50\x05"
+  "\x26\x60\x3d\xa6\x53\x40\x1f\xb7\x43\x3f\x40\xe7\xf7\x95\xe6\x2f"
+  "\xea\x10\x8e\x39\x9c\x8c\xb2\x5e\x9f\xaf\x70\x0e\x63\x7f\x28\xcc"
+  "\xd9\xad\x70\xef\xb6\xb9\x16\x6e\x87\xbd\x88\x58\x61\x26\x88\x13"
+  "\x88\x0f\xa6\xb4\x1a\x76\x7f\xa9\x50\xa3\x46\x3d\xe4\x9c\x2a\xb0"
+  "\x2f\x5e\x2b\x02\xf9\xac\x88\xc9\xe3\x81\x13\x24\x19\x78\xe5\x00"
+  "\x1e\xef\x2d\x20\x16\x78\x63\x3a\xb9\x07\x9e\x13\x8c\xe3\x87\xe3"
+  "\x85\xdf\x5f\x69\xf6\xad\x8d\x18\x6b\x61\x43\x3f\xe2\x6f\xeb\x3f"
+  "\xa3\x8e\xd9\x6b\xb2\x03\x1d\xf9\x2f\xda\x82\x66\xd4\x39\xd3\x8d"
+  "\xd3\x4b\x17\x3f\x77\xda\xf4\xd9\xf1\x71\xec\x93\xdd\xb4\x05\x0b"
+  "\x16\xce\x89\xd7\xc5\x4f\x9b\x91\xa0\x63\x97\x75\x0b\x17\x40\x95"
+  "\x99\x49\x0b\x74\xf3\x16\xcd\xd5\xcd\x59\x30\x13\x25\xe4\xf8\xc4"
+  "\xc4\x85\xfa\xa4\xde\x84\xdf\xa9\x9b\xb3\x70\x76\xd2\x4c\x3d\xfc"
+  "\xb3\x20\x7e\x6e\x9c\x8e\x51\x7d\x01\x34\x35\x7b\xb6\x4e\x7c\xc2"
+  "\x82\x84\x69\x89\xc8\x08\x73\xdf\x80\x4a\x4e\xf7\x2b\xe5\xe7\x00"
+  "\x8c\xa7\x87\x7e\x5c\xe7\x54\x9a\xb3\xe5\xbe\x30\xd6\x05\x33\xea"
+  "\xd0\xff\x01\xca\x2d\x4c\xa7\xca\x0e\x2c\x42\x3b\xf5\xbb\xf0\x8e"
+  "\xad\xc0\xf7\xed\xd9\x9a\x04\xe9\xdd\x98\xdd\x1a\x63\x79\x62\x9c"
+  "\x58\x95\xe6\x08\xdb\x6f\x0c\xfc\xcf\xfc\x63\xb2\x03\xb7\xf3\xb1"
+  "\xd0\x14\x3a\xdb\xc5\x98\x1d\x56\xa5\xf9\x14\xfd\xf0\x60\x0e\xb4"
+  "\xa0\x5c\x20\xe6\x5e\x50\xc1\x3d\xc7\xf0\x1e\x61\x4d\x74\x13\xdc"
+  "\x57\x23\xcb\xe6\x9a\x12\xac\xcf\xea\x65\x07\x76\xd2\xfe\x13\x35"
+  "\x70\x6e\x25\xf6\xcb\xc3\x3a\xa2\xbb\x04\xed\x1e\x2a\x25\xe4\xe1"
+  "\x20\x12\x72\x69\xf5\xe8\xd2\xf6\x7e\x23\x32\x3b\xb3\xc8\x4d\x9d"
+  "\x30\x97\xad\x6a\x72\x4f\x07\xf0\xc5\xe2\xc7\x89\xcf\xd2\x70\xa2"
+  "\x2e\x9d\x55\x8a\xb1\x88\x49\xe5\xf8\x42\x62\x8a\x05\xdd\xdb\xba"
+  "\x85\x54\x1a\x1b\x48\x95\xed\x13\x9e\xcf\x23\x15\x65\xeb\x7e\x2f"
+  "\x62\x4c\xbc\x8c\xa5\xd4\xbe\xfd\x2f\x16\xbf\x6d\xcd\xa5\x98\x87"
+  "\xe3\x1e\x93\xed\x84\xd1\x94\xb6\x99\x98\x52\x4c\x46\x8c\x47\x72"
+  "\x4e\xd5\xf7\xc9\x3d\x70\xed\xe6\x4a\xb8\x6f\x22\xb9\x09\xca\x8f"
+  "\xe3\x33\x72\xd6\xd2\xba\xb7\x07\xd0\xfa\xb7\xd7\x52\x33\xf0\x54"
+  "\x23\xf0\x54\x53\xee\x00\xda\x82\xfe\x05\xe8\x47\x81\x7c\xaa\x4f"
+  "\x26\xda\x66\x55\x5f\xf6\x6d\xd4\x34\x96\x95\xef\x80\x32\xf3\xf5"
+  "\x34\xa5\xac\xc5\xf2\x9d\x50\x6e\xe2\xe5\x8d\x58\xbe\x0b\xca\x56"
+  "\x5e\xfe\x12\xcb\x03\x9b\x55\xfd\xfc\x79\xb9\x9a\xb0\xb8\x1a\xaa"
+  "\x7e\x5a\x5e\xfe\x16\xcb\x30\xf6\xfd\x42\x8c\xc9\xd8\xdf\xe3\x40"
+  "\xb3\x7e\xc3\x32\x8e\x81\x8e\x96\x72\x86\xcd\x87\xbd\xe9\x09\x68"
+  "\xa3\x80\xf9\xd0\x77\xe7\x2d\xf5\xa8\xdf\xf5\x8b\xee\x15\x8a\xc7"
+  "\xbe\x31\x81\x56\x72\x13\xc8\x4b\xb7\xc0\xb5\x07\x71\xec\xdc\xda"
+  "\x64\xb6\x8d\xdc\x1b\x61\xa3\x46\xfa\xd1\xfd\x39\x74\xcd\x78\x0b"
+  "\xfd\xe8\x01\x8c\x83\x0c\x6b\xd9\xb0\xd2\xd2\x54\x2b\x8b\x07\x0d"
+  "\x32\x2a\xcc\xa1\x7e\x2c\x5e\x8c\x05\x64\x3e\x0f\xf1\x61\x35\x74"
+  "\xcd\x28\x0b\xe8\x52\x29\xe1\x21\x36\xf4\x97\x06\x39\xf7\xb6\x07"
+  "\xf7\x27\xa0\x6c\x10\x31\x43\xd8\xfc\x40\x8d\x90\x11\x4d\xe8\xe0"
+  "\xfb\x73\xc2\x13\xa8\x11\xd6\x29\x15\xb7\x7f\xd3\x13\xf0\xfc\x13"
+  "\xec\xb9\xc1\xf7\xe7\x08\x8b\x12\x30\x4f\x13\xc3\x97\x74\x5c\xb3"
+  "\x93\x01\x4f\x96\x44\x07\xda\xd7\x44\xc4\xee\x4f\x38\xed\x5d\xce"
+  "\x1f\xd5\x6d\x21\x1e\x7d\xa6\xa0\x4f\x18\x1f\xd5\x06\xcf\xb1\xc1"
+  "\xbb\xa2\x7c\xb0\x4d\xa8\x50\x83\x9c\x92\xb3\x75\x7a\x9d\x1f\x5d"
+  "\x14\x1d\x08\xef\xf4\xb8\x29\xe4\x22\xa9\xee\xc4\xb9\x72\x5b\xd3"
+  "\xfe\x14\x42\xc6\xa5\xd8\x8c\x81\x16\x16\xc7\x5a\xa3\x9f\x45\xee"
+  "\xa6\xfd\x47\x59\x9a\x55\x41\x23\x27\xa6\xc1\x3b\xc0\xbb\xef\x69"
+  "\xa8\xf3\x15\xe0\x3d\x1e\xe3\xe3\x06\xf7\x05\x0d\x84\xb1\x4d\x91"
+  "\x64\x7b\x2f\xfb\xcf\xf8\x46\x58\x10\x4d\x70\x1f\xf4\x76\x90\x49"
+  "\x84\xcb\xd1\x81\x02\xac\x3f\x78\x6d\x7f\xc8\x59\x82\xcf\x14\xc7"
+  "\x9a\xc5\x22\xa1\x83\x61\x9c\xe1\xf9\x18\x3f\x5b\x1a\x57\x58\xc3"
+  "\x06\xda\x2f\x27\xb8\xa7\xff\xda\x88\x50\xe8\x9f\x9e\xe6\xdb\xdd"
+  "\xfa\xf4\xc0\x7a\x3b\x95\xf3\x47\x70\x09\xfc\xca\xe8\x07\x33\x2c"
+  "\x96\xe0\x60\xc6\xef\xc2\xda\x67\x63\x25\x3b\x09\xcc\x37\xe0\x91"
+  "\xa0\x9d\xa5\xa0\x0f\xbb\x8f\x65\x98\x5f\xc2\xf2\x97\xf9\x9d\xa0"
+  "\x81\x76\xcc\xcb\x7b\x11\x63\xb1\x97\xec\x0f\x69\xf3\x92\xa6\x41"
+  "\x36\x4f\x34\xc5\xf6\x41\xaf\xbe\xec\x5d\x7b\xfd\x3d\xfa\x3f\xc0"
+  "\xd8\xea\xa9\xc6\x9e\xd9\x49\xc7\xaa\xb8\xfc\x3d\xe0\x3c\x8e\x95"
+  "\x0d\xd6\x91\xd4\xc3\x44\x6d\x85\xf5\xf2\x93\x97\x73\xd4\x43\x60"
+  "\x9d\xb1\xc3\xda\x7f\xa0\xa6\x9c\x44\x4c\x20\x19\x55\x09\x17\x88"
+  "\x94\x97\x8c\x0e\x78\xce\xf2\xf1\xcb\x16\x35\x7e\x87\xc2\x3c\x64"
+  "\x4c\x57\x5d\x1b\x1e\xfa\xc7\x6f\x61\xcd\x04\xb9\x61\xeb\xb7\x16"
+  "\xb5\xad\x35\x5a\xc7\x62\xc1\x83\x5e\x9e\x91\x40\x05\xc7\xb7\x29"
+  "\xcc\x17\x62\x08\x1d\x83\x79\x9e\x0f\x45\xd6\xb0\xb8\x01\x87\xa2"
+  "\xcb\xc9\xa1\xfa\x42\x52\xd9\x78\x0c\xf7\x53\x7f\x70\x28\xda\x80"
+  "\x32\x63\x1f\x1b\xc8\x85\xeb\x41\x2e\x84\xf9\x7a\xb3\xa0\xc9\x2f"
+  "\x91\xbe\x4f\x61\xde\x32\x49\x26\xb4\xc1\x1c\x2d\x12\x73\x93\xd9"
+  "\xb2\x83\xcc\x45\xe2\xb7\x2a\xcc\x59\xf6\x7e\x32\x19\xfc\xbe\x5a"
+  "\x88\x76\xf7\x5d\xaa\xcf\x7c\xe6\x73\xad\x15\xfa\xe6\x97\x48\xb9"
+  "\xcb\x26\xce\xd7\x91\xbf\xc2\xbb\xef\x0f\xf1\x76\x4e\x0e\x60\x71"
+  "\x4f\x6c\xc0\x77\x36\xe0\x39\x1b\x8c\x27\xd0\x60\x0b\xd0\xcd\xad"
+  "\x1e\x22\xd1\xe0\x72\x86\x44\x03\xed\x32\x46\x03\xd0\x5f\x96\x4c"
+  "\x16\x69\x70\x14\x68\xd0\x08\x34\xc8\x22\x99\x07\xa3\x2a\x49\x44"
+  "\x24\xd0\xa0\xe5\x02\xe6\x11\xe0\xb9\xe1\x92\xf8\xd8\x33\x5a\x1c"
+  "\xb5\xa8\xab\xdb\x38\x0d\xb6\xbc\xc2\x69\xb0\xed\x15\x0b\xc8\x31"
+  "\xc1\xe6\x8f\xa1\x6c\x5f\x14\xad\xc3\x5c\x4e\x34\x2b\x16\xf3\x58"
+  "\x73\x5a\x5c\x06\x5a\x5c\xe6\xb4\x48\x9f\x0f\xb4\xa8\xad\x63\xb1"
+  "\xad\x0e\xd5\x57\x92\xca\xd8\x62\x52\x05\xb8\x04\xb4\x98\x86\x74"
+  "\x41\xdd\xda\xbe\x24\xa4\x1f\xe8\xd2\x41\x45\xa9\x44\x2b\xd1\x03"
+  "\x74\xf7\xde\xb9\xa9\x04\xfd\x84\x43\x61\x6e\x4a\xf4\x08\x62\xf4"
+  "\x38\x2b\xd2\xa3\x13\x7d\xed\x80\x1e\x9d\x40\x8f\x4e\xa0\x47\x16"
+  "\xa7\x07\xe2\xfc\xc4\xb6\x40\x2a\xfc\x2b\x04\x63\x5f\x74\xa5\xc7"
+  "\x12\x91\x1e\x47\xaf\x86\x1e\xda\x09\x5d\xe9\x71\x7b\x68\x4f\xf4"
+  "\x90\xe7\xc4\x9d\xc1\x48\x8f\xcb\xc5\xe2\x9c\xb8\x1f\xe7\x44\xa6"
+  "\xfa\x61\x58\x8b\x70\x4c\x0f\xd4\xec\x62\x73\x02\xde\x35\xf3\xe3"
+  "\x97\xad\xea\xca\x46\xa0\x4b\x9c\x98\xaf\x4c\xa4\x0b\xa7\xc7\x73"
+  "\x96\x92\x6f\xf9\xf8\xeb\x5e\xc0\x35\x03\xe7\x06\xd2\x07\xe8\x04"
+  "\xf3\xc7\x5d\x5e\x3f\xe7\x6f\xb8\xd0\xa6\x80\xf3\x04\xe7\x08\xce"
+  "\x87\xaa\x84\x63\x2c\x4f\xfa\xa1\xc8\x0a\x82\xdf\x72\x0f\x45\xef"
+  "\x02\x5a\x15\x12\xfb\x22\xa0\x4d\x32\xee\x0d\x21\xf7\x62\x7e\xbf"
+  "\x43\xd1\x39\x28\x2f\x68\x80\xe7\x6f\xb6\x03\x9d\xec\xed\xda\xde"
+  "\x2b\x41\x8f\xc2\x6f\xbc\xce\xdf\x76\x31\x97\x31\xed\x15\x64\x86"
+  "\xf3\xbe\x36\xa0\x11\xcc\x1d\xc5\x9c\x71\xe4\x38\x3e\x15\x42\x36"
+  "\x34\x10\xff\x5b\x67\x72\x1a\xd9\x9d\xe6\x4c\xf8\x4c\x9c\x33\x99"
+  "\x40\xa3\xc3\x5e\xd2\xe8\x0e\x16\xc7\x1d\xf4\xcb\x50\xd0\x83\x32"
+  "\x61\x9d\x04\x1a\x69\x8d\x9e\x68\x64\xdf\x1c\x5c\x62\xd7\x8c\x88"
+  "\xc3\x7c\x06\xc2\xbc\x28\x95\x00\x3a\x53\x27\xe8\xa6\x87\x2c\x36"
+  "\x92\xf6\x1a\x51\xa7\x1e\x23\xbd\x4c\x51\x5f\x13\x93\xb9\x8c\xc5"
+  "\x22\x47\x9b\x2f\xe6\x08\x31\xd9\xca\x00\xaf\x26\xb3\x5c\xdf\x1b"
+  "\x58\xd9\x42\x96\xbc\x46\x7c\x58\xde\xcf\xe8\x62\xb2\x12\xf8\x73"
+  "\xeb\x2b\xc5\x6a\xa1\x60\xf4\x78\xaa\xc1\xdc\x46\xc4\x58\xad\xb7"
+  "\x61\x8c\xb7\x80\xaa\x84\x4a\x8c\x8b\x79\x22\x23\x85\x9e\xac\x6e"
+  "\x83\x36\x2d\xb4\xd3\x0e\x6b\xc6\xc6\x2c\x5a\x86\xf9\x1e\x1e\xc3"
+  "\x35\x02\xe3\xd6\xa9\xee\x52\xa1\x2c\x82\xb6\x2f\x63\xfa\xfb\x20"
+  "\x7b\xdd\xc5\x72\xa0\xc0\x39\x55\xd5\xac\x36\xb8\x7e\xf7\x42\xec"
+  "\x17\xb7\x43\xf3\xe3\x63\x18\x4f\x7c\xc0\xe4\xdf\xef\x4e\xb7\xf8"
+  "\x1a\x40\xe7\x05\x19\x0d\xdb\xe1\xf9\x46\x57\xdb\x2b\x4c\xb5\x56"
+  "\x66\x83\xb4\x64\x24\xf4\x32\xa4\xa2\x3f\x17\xe6\x8e\xc0\x35\xfb"
+  "\xee\x60\xf4\x01\xa1\x9b\x61\xbd\x1a\xf0\x6c\x6c\xe9\x74\x8b\x5a"
+  "\x5e\x97\xef\x4a\x83\xf5\xac\x62\x5c\x08\xcd\xc0\x1c\x1b\x7b\xe0"
+  "\xbd\x50\x0f\xfa\xa4\xc1\xca\x30\xe5\x8f\xd3\x73\xd4\x68\x23\xb1"
+  "\x02\x3e\x54\x7e\xfb\x27\x96\x8b\xf5\x8c\x6a\x60\xee\xc1\x68\x1b"
+  "\xc1\xe7\x4f\x7a\x10\xbf\x33\xdc\x65\xec\x50\x6f\x42\x5b\xcb\x98"
+  "\x8c\x46\x39\x0f\xa5\x73\xbe\x49\xc4\x99\xad\xd3\xa1\x4d\xc4\x99"
+  "\x86\x4c\x35\xc7\x96\x30\xb4\xd3\xf9\xbb\x62\x4b\x55\xcb\x59\x92"
+  "\x0e\x7c\x5c\x95\x50\xcc\xf2\xa0\xf4\x01\x7c\x17\x96\x00\x9e\x5c"
+  "\x06\x9d\x1f\xf0\x04\x71\x60\x23\xe0\x87\xb0\x04\x74\xfd\x4e\xd0"
+  "\xf5\x45\x1c\x41\xd9\x0b\x8f\xaf\x01\x8f\x06\x56\xc0\x39\xa0\x93"
+  "\x00\xb8\x0e\x78\x12\xb2\x3e\x95\x0c\x5e\x0f\x3c\xba\x01\x71\x04"
+  "\xe4\xe2\x89\x7a\xc0\x91\x45\x80\x23\xc9\x2c\x1f\xb0\x76\xa3\x9a"
+  "\xe3\xc7\x5f\x1a\x72\xd4\x06\x29\x1f\x38\x1b\xdf\x41\xf7\x56\x23"
+  "\x7f\xc4\x66\x62\x5f\xd5\x76\x5c\x9f\x96\x44\xfb\x54\xb7\x01\x8f"
+  "\xac\x9d\x1c\x89\xe7\xd8\xbc\x5d\x94\xd0\x5b\xe0\xbc\x16\x86\x63"
+  "\xb2\xe9\x1c\x09\x65\x39\x33\xbf\xd7\xf6\x5e\x35\x97\x0c\xd9\x78"
+  "\x8e\x0c\xde\x38\x97\x84\xc0\x7c\x55\x6f\x84\x3e\x4c\x99\xaf\x21"
+  "\x2c\xdf\x48\xaf\xfe\x63\xe1\xbc\xdb\x7c\x23\x20\x57\x6b\x37\xe2"
+  "\x9c\x99\x17\xe2\xe8\x93\xcd\x30\x27\xcc\x0e\x63\xc7\x62\xc6\xa9"
+  "\x06\x2d\xe6\x3e\xda\xf7\x95\x72\x39\x7f\xd0\x16\xee\xe7\xf4\xc0"
+  "\x0e\xd0\x55\x6e\x6a\x56\x0d\x9a\x46\x57\x3f\x56\xa2\x4f\x25\xaa"
+  "\x66\xe9\x1a\xc8\x9e\x02\xd0\xea\xd1\x4c\x92\x29\xf4\x7d\xaf\xd0"
+  "\x94\x72\x16\xe3\xf7\x7b\x39\x0f\x07\xb1\x3d\x77\x76\xc3\x9c\xb1"
+  "\xcc\xb7\x68\xf5\x9c\x09\x9b\x9a\x49\x28\x7d\x13\xe8\x31\x0b\xde"
+  "\xb5\x99\x0c\x2e\x6a\x86\x77\x5d\xc4\xdf\x55\xca\x7f\x2e\x64\x6d"
+  "\x2a\x85\x6b\xdd\xe6\xea\xb2\xbc\x89\xb9\xba\xee\xc9\x04\x0c\xbb"
+  "\x8d\xde\x87\x7e\xcb\x2c\xa6\x4f\xbb\xc9\x76\x8c\xe0\x73\xd1\x3e"
+  "\x64\xba\xc0\x78\x7a\x12\xf2\xb2\x50\x3c\xc3\x32\xb5\x1e\x78\xbb"
+  "\x3d\x81\x50\xf8\x7f\x4f\x83\x05\x63\xe8\x30\x99\xcf\xac\xba\x6b"
+  "\x05\xca\x69\x7b\xe1\x1c\xf2\xbe\x13\xcf\xaf\x40\x9e\xc7\xeb\x8c"
+  "\xef\xe1\x3e\x53\xfd\x69\x82\xed\x39\xb7\x83\xf4\x97\xda\x3a\xa3"
+  "\xba\x67\x14\xb6\x85\xbc\x80\x76\x1d\x9c\x6b\x9c\xf6\x65\xe8\xa3"
+  "\xae\xa5\x03\x7e\x51\xc3\xcb\x16\xcc\x43\xa3\x41\x1e\x60\xbc\x02"
+  "\xf8\x8d\x31\x9b\x29\x8d\xf6\x01\x3e\xc3\x7e\xf6\x06\x7a\x87\x4a"
+  "\x7c\x01\xe7\x82\x5c\x79\xa3\xcf\x32\x0d\xea\x34\x41\xf8\xff\x95"
+  "\xf2\x87\x77\xf4\xbb\x67\xa4\x47\xff\xb9\xc1\xc1\x18\x8f\xea\x1e"
+  "\xc4\x4d\x7b\xab\x13\x66\xb6\x70\xcc\x44\x4c\x92\x70\x93\x61\x13"
+  "\xcb\xc1\x50\x86\xfe\xad\x09\xac\x8f\x5e\xe2\x66\x55\x8b\x8c\x9b"
+  "\x13\xf5\x4e\xb8\xd9\x42\x3b\x85\x60\x77\xb8\xa9\x1b\xa5\xc4\x4d"
+  "\xdd\x93\x4a\xdc\xfc\xd9\x07\xae\xb8\xd9\x15\x33\x75\x4b\xdd\xe1"
+  "\x25\xe8\x31\xf7\x34\xab\x7e\x16\xe9\x19\x2b\x75\x25\xde\x63\xe5"
+  "\xbd\x3b\x95\x58\xa9\x6b\xf9\xff\x17\x2b\xef\x0b\x57\x60\xa5\xe6"
+  "\x0a\xb1\xb2\x99\x61\x65\x10\xfd\x17\xcc\x09\x11\x3f\x36\xce\xf2"
+  "\x80\x95\xb3\x7a\x98\x0b\x6f\x7a\xc2\xca\xfb\x3e\x52\x62\xe5\x7d"
+  "\x75\x4a\xac\xbc\x2f\x57\xc6\x4a\xf1\xda\x35\xc1\xca\xfb\x36\xdf"
+  "\x18\xac\xbc\x6f\x33\xc3\xca\x73\x88\x95\x3f\x5b\xd6\x33\x56\xea"
+  "\x4a\xdd\x63\x25\x9c\x67\x58\xa9\x2b\x95\xb1\xf2\x58\x0f\x58\x39"
+  "\x38\xde\x0b\xac\x0c\x62\x58\xa9\xf1\x80\x95\xb3\x60\xac\x44\xbe"
+  "\x60\xbc\xe7\xc2\x1b\x22\x56\x6a\x1d\x58\x79\x05\xfc\xe1\x1d\xfd"
+  "\x06\xc7\x75\x87\x95\x82\x81\xcb\x97\x88\x95\xb4\x9f\x88\x95\xb3"
+  "\x6d\x24\xf5\x08\x60\x64\x6d\x33\xcb\x35\xc3\xfc\x82\xe1\x97\x36"
+  "\x19\xb1\xe8\x39\xfd\x36\x18\x2f\x93\xb9\x94\x61\x13\xf3\x6f\x9d"
+  "\x80\x58\x55\x0a\x75\x0b\x1d\x72\x27\xc3\xce\x23\x22\x76\xc6\x88"
+  "\xd8\x39\xe5\x07\x60\xe7\x2b\x48\xcb\xe0\x85\x1d\x6a\x09\x3b\x57"
+  "\x03\x76\x06\x33\xf9\x01\xbf\x69\x72\xec\x0c\x39\x2f\xf5\x0b\x6d"
+  "\x9a\xa6\xa4\xf7\x09\xef\xd7\x85\xae\x38\xfa\x02\x6b\xef\x80\x71"
+  "\x56\x0b\x71\x60\x69\x8c\x8c\xa5\xd0\xd6\x07\x9e\x71\x34\xd8\xe2"
+  "\xc0\xd1\x2c\xc0\xd1\xe3\x4e\x38\x0a\x7a\xd3\x1f\x11\xf3\x00\x47"
+  "\xdb\x19\x8e\xfe\x45\xc4\xd1\x07\x54\x07\x63\x00\x47\x5f\x90\x70"
+  "\xf4\xfe\xa1\xd6\xac\x4d\x25\xd6\xec\x9e\x71\xb4\x9d\xe1\xa8\xfe"
+  "\xfa\xe3\x68\xb9\x0b\x8e\x82\xee\x8a\x39\xd0\xdd\xe2\xa8\xc4\x8f"
+  "\x0c\x47\x33\x65\x1c\x65\xe3\xfa\xc0\x86\xea\x58\x18\xf7\x58\x3d"
+  "\xd3\xdd\x1c\x38\xaa\x2f\xe5\x38\x0a\xe7\x98\xfd\x64\x01\xe0\x28"
+  "\xf0\x5f\x46\x15\xc6\x06\x24\x61\xd0\x47\x0d\xe2\xeb\x26\x98\x33"
+  "\x38\x46\x0e\x3c\x9d\x05\x73\x06\x31\xa6\x15\xe6\x0c\xe0\xe8\x94"
+  "\x8b\x1a\xc2\xe6\x4b\x36\xcc\x97\x66\x0f\xb9\xee\x24\x1f\x5c\x8f"
+  "\x78\xfa\xc0\x45\x25\x9e\x86\x84\x28\xf1\xf4\x81\x63\x32\x9e\x8a"
+  "\xd7\x10\x4f\x81\x66\x30\x3e\x85\x88\xa9\x57\x87\xa7\x0f\xb4\x39"
+  "\xf0\x54\x2d\xe2\xe9\xac\x9e\xf1\x94\x7d\xfb\xf3\x80\xa7\xce\xd8"
+  "\xe0\x19\x4f\x1f\x68\x93\xf1\x34\xe4\x2b\x07\x9e\xd6\x79\xc2\xd3"
+  "\x60\xab\x7b\x3c\x85\xf3\x0c\x4f\x83\xad\x0e\x3c\xad\x73\x83\xa7"
+  "\x2f\x38\xe3\xe9\x83\x9f\x73\x3c\x2d\x65\x38\x8a\x98\x5a\xdd\x06"
+  "\xfc\x81\x73\x2e\xa9\x90\x61\xaa\x00\x98\x8a\xf9\x7f\x31\xcf\x15"
+  "\xfa\xd5\xbb\xc3\x54\x8e\xb9\x66\x82\xb8\x8a\x73\x33\x23\x1c\xf4"
+  "\x5d\x58\x8b\x60\x4c\xd8\xda\x2b\x8d\xdf\x26\x27\x7c\x9d\xba\x58"
+  "\x83\xb2\x9d\x82\x57\x04\x89\x57\x5a\x43\xd0\xef\x56\xc1\x2b\xde"
+  "\xd1\xf2\x41\xa3\x27\x6c\xf5\xa4\xbb\x1f\x44\xdd\x7d\x12\x51\x2f"
+  "\x99\x04\xf8\x1a\x8d\xba\x7b\x89\x8b\xee\x5e\xd2\x55\x77\x3f\xdc"
+  "\x3d\x8e\x7a\xa5\xbb\xbf\x8c\x34\x7c\x68\xb7\x12\x47\x1f\xfa\x5c"
+  "\x89\xa3\x8f\x3e\x89\xfd\xe2\x38\x5e\xe2\x5e\x77\x67\xf3\xfc\xe1"
+  "\x5b\x1d\xba\x7b\x9d\x12\x3f\x65\xdd\xfd\x91\xb3\x9e\x71\xf4\xe1"
+  "\x91\x0a\x79\x74\x8a\x88\xa3\xd3\x45\x1c\x9d\x2e\xe3\xe8\xa1\xaf"
+  "\x25\x79\x74\xc8\xa4\x03\x75\xce\x38\xfa\x70\x9a\x03\x47\xeb\xbb"
+  "\xe2\xa8\x84\xa1\x88\xa7\xd8\x0e\xda\xb2\xb6\x00\x4e\x6f\x9f\xae"
+  "\x57\x73\x5b\x6d\x2c\x8e\x9d\xbf\xab\xad\xb6\xaa\xe5\x22\x49\x8f"
+  "\x41\x3c\x2d\x64\x78\x1a\xa8\x22\xd3\x00\xfb\xfa\xe0\x5e\x82\x22"
+  "\xfc\x6e\x9f\xcc\x73\xa7\xa1\x7d\x49\x58\xc4\x73\x71\x4a\x76\x26"
+  "\x78\x5f\xf6\xbd\xfe\xb5\x63\x22\xa6\x5e\x82\xf1\x00\x9e\x5b\x7f"
+  "\x09\x30\x35\xd9\x8d\x6c\xba\x04\x30\x35\xd5\x49\x36\x85\xb9\xff"
+  "\x97\xe9\xae\x98\x3a\xe4\xbb\x6a\xe4\x15\xc4\x54\x85\x1e\x5f\xf2"
+  "\x13\xd0\xe3\x1f\x79\x4a\x89\xa5\x8f\x24\x29\xb1\xf4\x91\x07\x65"
+  "\x2c\x15\xaf\x5d\x13\xd9\xf4\x91\xb0\x1b\x23\x9b\x3e\x12\x26\xeb"
+  "\xf1\x8f\x0e\x72\x60\x69\xad\x27\x2c\x7d\x38\xcc\x3d\x96\xc2\x79"
+  "\x86\xa5\x0f\x87\x39\xb0\xb4\xd6\x8d\x1e\xaf\xc0\xd2\xc7\x54\x1c"
+  "\x4b\x4b\xb8\x6c\x5a\x27\xc9\xa6\x25\xff\x86\x7a\xfc\x63\x5d\xf6"
+  "\x53\xf4\xa4\xc7\x1f\x6c\xe1\xf8\x89\xf8\x24\x61\xa8\xac\xc7\x97"
+  "\x78\xd6\xe3\x7b\xc0\x50\xaf\x64\x51\x86\xa1\xa1\x2a\x25\x86\x86"
+  "\xfa\x29\x31\xf4\xe7\x0b\x5d\x31\xb4\x2b\x7e\x86\x8e\x73\x87\x9d"
+  "\x5c\x8f\xff\xf9\x60\xcf\xb8\x19\xaa\xf7\x1e\x37\x1f\xcf\x55\xe2"
+  "\x66\xe8\x8e\xff\x0c\xdc\x7c\xe2\x5e\x05\x6e\x6a\xae\x10\x37\x7f"
+  "\x14\x9d\xfe\x09\x17\xfb\xe7\x13\x2e\xf6\xcf\x27\x9c\xec\x9f\x4f"
+  "\x5c\x43\xfb\xe7\x13\x37\xc8\xfe\xf9\x44\x8a\x2c\x83\xfe\x7c\x52"
+  "\xcf\xb8\x19\x9a\xe2\x1e\x37\xe1\x3c\xc3\xcd\xd0\x14\x19\x37\x7b"
+  "\x92\x41\x87\x8e\xf2\x02\x37\x7f\xe2\x3a\xfd\xd0\x6e\xed\x9f\xee"
+  "\x74\x7a\xc4\x4d\x86\x97\x75\x2e\x3a\xfd\x24\x67\x9d\xbe\x44\xd6"
+  "\xe9\xc7\x73\xdc\x32\xd9\x0c\x4a\x9d\xfe\x9a\xe3\xe8\xb0\xe7\xad"
+  "\x0e\x7b\xe8\x3b\x80\xa3\xc3\x58\xdc\x5a\xab\xc3\x1e\x3a\xf2\x2b"
+  "\xa9\x5f\x5c\xa7\x5f\x4d\x78\xbf\xdc\xe8\xf4\xcc\x6f\x76\xd8\x06"
+  "\x87\x4e\x5f\xe7\xaa\xd3\x8f\x5c\xe6\x19\x53\x87\x95\xbb\xd5\xe9"
+  "\x51\xff\x66\x98\xaa\x67\x98\x7a\x69\xad\x33\xa6\x0e\x3f\xc9\x30"
+  "\xf5\x59\x09\x53\x87\xfb\x5b\x61\x6e\x5a\x7b\xf5\x8c\xa9\xd8\x8e"
+  "\x8c\xa9\x09\x3f\x0e\xa6\x1a\xaf\x1c\x53\x9d\xf7\xb0\xfe\x05\xde"
+  "\xdd\x81\xa9\x6c\x8c\x47\x2c\xad\x8e\x45\x4c\x4d\x70\xd1\xef\x4b"
+  "\xdc\xeb\xf7\x07\x88\x1a\xc7\x47\xd2\xef\x91\x06\x0c\x6f\xae\xab"
+  "\x7e\x3f\xe2\xb0\x12\x5b\x47\xfa\x2b\xb1\x75\xc4\x6e\x19\x5b\xc5"
+  "\x6b\xd7\x44\xbf\x1f\x51\x7b\x63\xf4\xfb\x11\xb5\x32\xb6\x8e\xfc"
+  "\xb4\x67\x6c\x1d\x56\xe9\x1e\x5b\xe1\x3c\xc3\xd6\x61\x95\xdd\x62"
+  "\xeb\xb3\xce\xd8\x3a\xea\x03\x09\x5b\x65\xfd\x1e\xf8\x03\xe7\x5f"
+  "\x92\xe1\xea\xf5\xfb\xe7\x6f\xb4\x7e\x3f\xaa\xd8\x2b\xfd\x7e\x2d"
+  "\xe0\x2c\xe8\xe2\x4b\xbe\x02\xfd\xfe\x45\x51\xbf\xaf\x2f\x76\xd1"
+  "\xef\x8b\xbb\xe8\xf7\x69\x2f\x8a\x98\x0a\x73\x8a\x61\xea\xf4\x92"
+  "\xab\xd7\xef\x5f\x42\x1a\x8e\xde\xa0\xc4\xd4\xd1\x1f\x28\x31\xf5"
+  "\x97\x8f\x63\xbf\x38\xa6\x17\xbb\xd7\xef\xd9\x3c\x1f\x7d\x56\xa1"
+  "\xdf\x43\xff\xba\xea\xf7\x4f\x9e\x54\x60\xea\x14\x67\x4c\xfd\x85"
+  "\x56\x21\xa7\xc2\x7b\x21\xa6\x7e\x7c\x9c\x63\xea\x27\xc7\x9d\x30"
+  "\x75\xe2\x27\x22\xa6\x8e\x79\xfe\x40\x94\x33\xa6\xfe\x22\x46\xc2"
+  "\x54\x86\x97\x53\xac\xea\x8c\xe8\xae\x7e\x27\xcc\xdf\x07\x7d\x81"
+  "\xa0\x6d\xdc\x27\x85\x6d\x6e\x3d\x9e\xd0\xb3\xbf\x49\xb4\x7b\x7f"
+  "\x13\x53\x92\x99\x54\x36\x1a\x98\x9f\x49\x11\xfa\x99\x2c\x23\xf7"
+  "\x16\x75\xf2\xf8\x01\x2c\x9f\xc7\x25\xf7\xb1\x03\x5e\x9b\x2c\xe3"
+  "\x2c\xfa\x64\xad\x47\x9f\xac\x4b\xdc\x07\x08\xe8\xdd\x35\x56\x80"
+  "\x24\x37\x01\x1e\xec\x3c\xee\x8a\xb3\x63\x8e\x55\x23\xff\xc4\x24"
+  "\xb8\xe8\xfc\xc5\x3f\x01\x9d\xff\xc9\x61\x4a\x7c\x7d\x32\x41\x89"
+  "\xaf\x4f\x0e\x92\xf1\x55\xbc\x76\x4d\x64\xd7\x27\x87\xde\x18\xd9"
+  "\xf5\xc9\xa1\xb2\xce\xff\xcb\xbe\x0e\x7c\xad\x71\xc2\xd7\xe3\xce"
+  "\xf8\xfa\x0b\x1d\xc3\xd7\xe3\xae\xf8\x0a\xe7\x19\xbe\xfe\x42\xe7"
+  "\xc0\xd7\x1a\x17\x9d\xff\xb8\x2b\xbe\xfe\xf2\x22\xc3\x57\xe0\x05"
+  "\xa5\xec\x5a\xdc\xb3\xce\x5f\xff\x53\xd3\xf9\x7f\xd9\x25\xfe\x51"
+  "\xb7\x3a\x3f\x62\xea\x6c\x8e\xa9\x88\x59\x12\xae\xca\x3a\x7f\xb1"
+  "\x47\x9d\xbf\x27\x5c\xf5\x4a\x56\x65\xb8\xfa\xab\x8b\x4a\x5c\xfd"
+  "\x55\x87\x12\x57\x9f\x59\xea\x8a\xab\x5d\x31\x35\x6c\x94\x3b\x3c"
+  "\xe5\x3a\xff\x33\x43\x3c\x63\x69\x58\x9c\xf7\x58\xfa\xd4\x1a\x25"
+  "\x96\x86\x95\xfc\xe7\x62\xe9\xd3\x0f\x2a\xb0\x54\x73\x85\x58\xfa"
+  "\xa3\xd8\x01\x9e\x5e\xa6\xc4\xd2\xa7\x77\x28\xb1\xf4\xe9\x99\x32"
+  "\x96\x8a\xd7\xae\x09\x96\x3e\x9d\x79\x63\xb0\xf4\xe9\x4c\x59\x56"
+  "\x7d\xe6\xb5\x9e\xb1\x34\x6c\xb6\x7b\x2c\x85\xf3\x0c\x4b\xc3\x66"
+  "\xcb\x58\x7a\xac\x07\x2c\x1d\xfb\x94\x17\x58\xaa\xb4\x03\xb8\x62"
+  "\xe9\x0d\xb7\x03\x8c\x0d\xf3\xca\x0e\x20\x61\xe9\x8b\x5d\xed\x00"
+  "\x88\xaf\xcc\x0e\x00\xe3\x25\x61\x18\xb3\x03\x8c\xe5\x58\x66\xb2"
+  "\xe5\x28\xec\x00\xd7\x1e\x5b\xc7\xbd\x68\x75\xd8\x53\xb3\x00\x5b"
+  "\xc7\x4d\x62\xd8\xea\xb0\xa7\x8e\x3f\x2b\xf5\x8b\xdb\x01\xde\x21"
+  "\xbc\x5f\x6e\xec\x00\x4f\xb3\xf6\x3e\x52\xd8\x01\x9c\xb0\x16\xda"
+  "\xda\xe0\x19\x67\xc7\x55\x2a\xec\x00\x0d\x32\xce\x5e\x42\x1f\x75"
+  "\xc0\x41\x86\xb3\x03\x9c\x71\xf6\x59\x3b\xc3\xd9\xa7\x25\x9c\x7d"
+  "\x56\xd3\x0e\x73\xb3\xdd\x5b\x9c\xc5\x7d\x04\xc7\x63\x6f\x0c\xce"
+  "\x96\x79\x81\xb3\x4e\xb6\x81\x9d\x30\x1e\x0e\x9c\x65\xe3\xfe\xdc"
+  "\xba\xea\x18\xc4\xd9\x58\x17\xdb\x40\xb1\x7b\xdb\xc0\xfe\x1b\x61"
+  "\x1b\x78\xee\xbc\x12\x6f\xc7\x0f\x56\xe2\xed\x73\x47\x64\xbc\x15"
+  "\xaf\x5d\x13\xdb\xc0\x73\x96\x1b\x63\x1b\x78\xce\x22\xe3\xed\xf8"
+  "\xaa\x9e\xf1\x76\x5c\xad\x7b\xbc\x85\xf3\x0c\x6f\xc7\xd5\x76\x8b"
+  "\xb7\x4f\x3b\xe3\xed\xf3\xbb\x25\xbc\x95\x6d\x03\xc5\xa2\x6d\x20"
+  "\xa7\x67\xdb\x40\xbd\x07\xdb\xc0\xb8\x1b\x6d\x1b\x78\x7e\x97\x37"
+  "\xb6\x81\x8e\xb5\xdc\x6f\x7f\x09\xfa\xed\xbf\x06\xf8\x1b\xf9\x35"
+  "\x8c\x41\xcf\x7e\xfb\x69\x92\xff\x69\x6c\xa1\x88\xb3\x85\x6e\x6d"
+  "\x03\x07\x9b\x3c\xdb\x06\x0e\xd6\x3a\xfb\x9f\xbe\xb0\x53\xf9\xdd"
+  "\xea\x85\xdd\xd2\x77\xab\x83\xdf\x22\xce\x4e\x64\x79\x1b\x85\x82"
+  "\x89\xc5\x0c\xff\x55\x13\xcb\xb1\x9f\xee\xfc\xf8\xff\x22\x38\x7f"
+  "\xcb\xfa\xf5\x1d\x0e\x5b\x41\x0d\xe2\x6d\x21\x11\x68\x42\x2f\x8c"
+  "\x3b\xce\x6c\x05\x2f\x23\xef\x4d\x5c\xe8\x8c\xbb\x7b\x8e\x3a\xe3"
+  "\xee\xaf\xc7\x4a\xb8\x6b\x07\xdc\xdd\xdd\x50\xc8\xed\xaf\xaf\x70"
+  "\xdf\xd4\x2d\xaf\x38\xf9\xa6\x7e\xfd\x85\x88\xbb\x13\x9e\x3a\x60"
+  "\x86\xf7\xef\xce\x7f\x0a\xee\xdf\x76\xf4\x4a\x7d\x50\x0b\xdd\xfa"
+  "\x4e\x89\xf8\xe4\xd6\x7f\x0a\xfa\xaa\xd9\x20\xce\x55\x3b\xcc\xd3"
+  "\x0d\x4e\xfe\x53\x45\xa9\x30\x9f\xc5\x7d\x25\xdd\xfa\xa1\xbe\x22"
+  "\xfb\xa1\xd2\x82\xf0\x7a\x5c\xdf\x84\x35\x13\x8b\x3b\x69\x82\x0f"
+  "\x0d\x0a\xaf\xc7\xe7\x5f\xbe\x0c\xeb\xce\x33\xd1\x3e\x5c\xaf\x0b"
+  "\x37\x02\xf6\xf4\xe1\xe3\x3e\x21\xcd\x0e\x6b\x8d\x1d\xd6\x1a\xa1"
+  "\x20\xdc\x68\x43\xd9\x64\x6d\x78\x79\x11\xe8\x79\xb6\x2c\x96\x9f"
+  "\xb5\x77\x1e\xe8\x7a\x9b\x50\xcf\x3b\x07\x73\x23\x23\x44\x8d\xfd"
+  "\x91\x70\x34\xb0\x09\xde\xe3\x5c\xf7\xb2\x9c\xed\x7b\x19\x47\x8d"
+  "\x2f\x1c\x84\x67\x86\xcf\xaf\x46\xde\x8d\x96\xf7\x14\x30\x99\xd9"
+  "\x83\xaf\x2c\xf6\x85\xc7\x5d\x04\x5e\xb8\x06\x36\x09\xe7\xfe\x28"
+  "\x71\x3d\xfc\x80\x12\xd7\xc3\x6d\x4a\x5c\x0f\xff\x54\xc6\x75\xf1"
+  "\x1a\xe0\x3a\xd0\x8d\xc9\xd1\xb0\xf6\x5d\xa5\x1c\x1d\x5e\x21\xe1"
+  "\xba\x20\xe2\xfa\xc6\x2b\xc0\xf5\x6e\xe5\x68\x27\x5c\xf2\x8c\xeb"
+  "\xe1\x15\xb2\x4d\x62\xe2\x47\x6e\x7d\x64\x8f\x3a\xe3\xfa\xaf\x27"
+  "\x30\x5c\x3f\xea\x8a\xeb\x70\x9e\xe1\xfa\xaf\x27\x78\xdc\x4f\x70"
+  "\xd4\xf5\x7b\x5a\xc4\xdb\x0c\xd7\xeb\x44\x1f\xd9\x1a\x2f\xf6\x13"
+  "\xd4\x71\x4c\x97\xb0\x1c\xed\x55\x37\xd6\x26\x11\x91\xe3\x8d\x4d"
+  "\x82\x61\x79\x0b\xc7\x72\xc4\x46\x09\xcf\xaf\x64\x3f\x41\x4f\x78"
+  "\x2e\xc9\xcd\x88\xe7\x9e\xe4\x66\x25\x9e\x47\xbe\xad\xc4\xf3\xc8"
+  "\x5c\x25\x9e\x47\xbd\xad\xc4\xf3\xa8\x1c\x57\x3c\xef\x8a\xe5\x91"
+  "\xc7\xdc\xe1\xb8\xfe\x65\xb4\x51\x44\x8d\xf4\x8c\xe1\x2f\xfa\x7b"
+  "\x8f\xe1\x2f\xf9\xfd\xc7\x61\xb8\xc6\x15\xc3\x5f\x0a\x43\x0c\xb2"
+  "\x67\xbb\x60\xf8\x2c\x11\xc3\x45\x1c\xd9\xd4\x2c\xca\xc2\xae\x18"
+  "\xde\x02\xef\xd1\x83\x3e\x6e\xfb\x97\x2b\x86\xff\x66\x98\x02\xc3"
+  "\x35\x3d\x60\xf8\x2c\x6e\x07\x51\xf8\xe5\x7a\xb0\x85\xc0\x7b\x8c"
+  "\xdd\xe0\x41\x36\x97\xc6\xcc\xb9\x3f\x4a\x0c\xff\x4d\xae\x12\xc3"
+  "\x7f\x63\x54\x62\xf8\x6f\x16\xca\x18\x2e\x5e\xbb\x26\xb2\xf9\x6f"
+  "\x56\x5e\x73\xd9\x5c\xe2\x8f\x6e\x31\xfc\x37\x2b\x65\xd9\x3c\x6a"
+  "\x66\xcf\x18\xfe\xa2\xc6\x3d\x86\xc3\x79\x86\xe1\x2f\x6a\x3c\xee"
+  "\x73\xe8\x82\xe1\x93\x9e\xf7\x02\xc3\x95\xb6\x10\x09\xc3\x45\x5b"
+  "\xc8\x26\x27\x5b\x88\x3d\x8b\xdb\x42\x36\x34\x73\xde\xe8\xa3\xe2"
+  "\x7c\x0a\xfc\xa3\xdd\xa8\xee\x5e\x77\xdb\x70\x55\x76\x90\x49\x1e"
+  "\xf3\x3f\xba\xb3\x83\x30\xfc\xc6\x3d\x0e\x93\x01\xb7\x6b\xae\x70"
+  "\x8f\xc3\x78\x69\x8f\x83\xc1\xc3\x1e\x07\x11\xcf\xa7\xfc\x00\x3c"
+  "\x67\x7b\x1c\x5e\x9e\xac\xb4\x31\xbf\xfc\x9a\x64\x63\xe6\x78\xfe"
+  "\xca\x1c\x25\x9e\xbf\x32\xdb\xb1\xe7\x01\x30\xdf\xa4\x5f\xdd\x65"
+  "\xcf\x83\x03\xdb\x99\x1d\xf4\xe5\xdd\xc6\x97\x1b\x89\x03\xdf\x63"
+  "\x64\x7c\x87\xb6\x06\x29\xb0\xbd\xc1\x19\xdb\x5f\x6e\x54\x60\xfb"
+  "\xf1\x42\xa5\x7f\x44\x83\xde\x09\xdb\xa5\x3d\x0f\xff\x75\xf2\x40"
+  "\x7d\x0f\xd8\x0e\xf7\x5f\xf9\x1e\xb1\x6b\x8b\xed\xd2\xfe\x06\xb7"
+  "\xd8\xee\xbc\xbf\xc1\xc9\xff\x01\xb1\x9d\xe5\xb8\xe8\xef\x82\xed"
+  "\x4b\x12\xd4\xf6\x7d\x30\x1f\x00\xd7\x71\x8e\xd8\x29\x60\x3b\x1b"
+  "\xef\xe8\x81\xce\xd8\x7e\x39\x8b\x63\xfb\xfa\xe6\x1f\x8e\xed\x0e"
+  "\x79\xd8\x19\xdb\x9f\x45\x6c\x9f\x7c\x07\xdf\x7f\x91\x79\x65\xfb"
+  "\x2f\x5c\xfc\x33\xd6\x5f\x81\xfd\xa5\x5b\x8c\x77\xd3\x2f\x25\xc6"
+  "\x4f\x9e\xaf\xc4\xf8\xc9\x9b\x95\x18\x3f\x79\xb2\x8c\xf1\xe2\xb5"
+  "\x6b\x22\xa7\x4f\xd6\xdf\x18\xfb\xcb\x64\xbd\x8c\xf1\xaf\x84\xf7"
+  "\xbc\xf7\xe2\xe5\x16\xf7\xbe\x19\x70\x9e\x61\xfc\xcb\x2d\xdd\xee"
+  "\xbd\x50\xd8\xbb\x5f\x7d\xd2\xed\xde\x8b\x9a\x1f\xcf\x37\xc3\x99"
+  "\x57\x5c\xed\x2f\x57\x6f\xfb\x7e\x75\x8c\xb7\xf6\x17\xdc\x7b\xb1"
+  "\xe4\xb0\xd3\xde\x8b\xfa\x9e\xf7\x5e\xa4\x4d\xba\x42\xfb\x4b\x37"
+  "\xbe\x19\x07\x23\x9d\xfd\xdd\x62\x46\x29\xf1\x3d\xe6\x49\x07\xbe"
+  "\xbf\x84\xf8\x1e\xfb\xa2\x12\xdf\x63\x23\xb1\x9f\xee\xf6\x62\xfc"
+  "\x45\xf1\x5d\x31\x66\x9d\xd2\x57\xc3\xc5\xfe\xf2\x12\xf2\x5e\xac"
+  "\x4a\x81\xef\xc7\x9d\xf1\x3d\xa6\xdc\x9d\xec\x8e\x76\x6f\xe6\x53"
+  "\x3c\xc5\x69\x4f\xdb\x44\xc9\xff\xed\xb5\xaa\x03\xd1\xf0\xfe\x66"
+  "\x0f\xbe\x6e\x53\xb8\xaf\x1b\xf3\x6d\x43\x3b\x38\xb4\xb5\x7d\x8a"
+  "\x5e\x9d\x1e\x4b\x05\xf4\x75\x73\xf5\x73\x43\xdf\x37\xf4\x75\xab"
+  "\x4a\x30\x78\xf4\x73\x43\xde\xf4\xe4\xeb\x06\xfd\x0e\x62\x58\x7f"
+  "\x52\xc4\x7a\xd1\xd7\xad\x28\x59\xf6\x75\x53\x60\xbd\x1b\xff\xe1"
+  "\x9d\xc7\x33\xdd\xcb\xf1\x19\x32\xd6\x77\xa2\x1c\xff\x0b\x17\x5b"
+  "\x0c\xa3\xc1\x14\xff\x1f\xd5\x16\xc3\xb0\x7e\x8a\xbd\x1a\xf9\x38"
+  "\x46\xef\xc6\x16\xd3\xd5\xc7\xf9\xc7\xb3\xc5\x4c\x9d\xa4\xc4\xf8"
+  "\xa9\x39\x4a\x8c\x9f\xfa\xa4\x8c\xf1\xe2\xb5\x6b\x82\xf1\x53\xa3"
+  "\x6e\x8c\x2d\x66\x6a\x94\x6c\x8b\x89\x7d\xdc\xad\xff\x9d\xc2\xc6"
+  "\x1e\x53\xe9\xde\xc6\x1e\x23\xfa\xdf\xc5\x54\x7a\xdc\x13\xd2\xe5"
+  "\x9b\xe6\xb4\xfe\xdc\xc6\x7e\x15\x7b\x42\xea\x7f\x6a\xb6\x98\x69"
+  "\x5d\xf2\xad\xf5\x64\x8b\x61\xbe\xcd\x87\xd1\x3f\xc4\xbb\x3d\x21"
+  "\x3d\x61\xbb\x43\x76\xef\xe6\x1b\xa6\x12\xdb\xa7\xf7\x57\x62\xfb"
+  "\xf4\x3b\x94\xd8\xfe\xfa\xbd\x4a\x6c\x7f\x5d\xe7\x8a\xed\x5d\x71"
+  "\x7d\xfa\x4c\x77\x98\xae\x7f\x09\x6d\x31\xf1\x35\x9e\xf1\x7c\x7a"
+  "\x81\xf7\x78\x3e\x63\xc3\x7f\x34\x9e\x6b\x5c\xf1\x7c\x46\xdd\x8f"
+  "\x6a\x97\x61\x78\x1e\x57\xa5\xc0\x73\x4d\x0f\x78\xfe\xa3\xd9\x65"
+  "\xe2\x83\x95\x78\x1e\x1f\xad\xc4\xf3\xf8\x5b\x65\x3c\x17\xaf\x5d"
+  "\x13\xbb\x4c\xfc\xe0\x1b\x63\x97\x89\x1f\x2c\xcb\xec\xaf\xab\x7a"
+  "\xc6\xf3\xe9\x45\xee\xf1\x1c\xce\x33\x3c\x9f\x5e\xe4\xd1\x9f\xba"
+  "\x0b\x9e\xbf\x7e\xd2\x0b\x3c\x77\xeb\xa3\xf2\xd3\xb0\xcb\xbc\x6e"
+  "\xf6\xd6\x2e\xe3\x69\x9f\x0a\xe2\xbb\xec\x9f\xe2\xb4\x4f\x25\x4c"
+  "\xda\xa7\x92\xa9\xf4\x4f\xb9\xe6\xd8\xfe\xc6\x79\x25\xb6\xbf\x71"
+  "\x51\x89\xed\xb3\xfb\x2a\xb1\x7d\xb6\x46\xea\x27\xb7\xcb\x64\x75"
+  "\xd9\xb7\xa2\xc4\xf9\x84\x49\xc6\x97\x1a\x89\x3b\xac\x3f\xa3\x7a"
+  "\xf3\x73\xcf\x38\x9f\x90\xe6\x09\xe7\xd1\x5f\xe5\x8f\x53\x12\xdc"
+  "\xe0\xfc\xcc\xb7\xfe\x7f\xc0\x79\x4f\x7e\x28\x4c\x0f\x02\x8c\x47"
+  "\xbc\x67\xf8\x2e\x62\x3d\xe2\xbc\xfd\xaf\xee\x6c\x34\x33\x8d\xd7"
+  "\x0b\xe7\x3d\xdb\x68\x66\xed\xae\x8e\x11\x71\xfe\x4a\xf6\xd0\x7c"
+  "\xae\xb4\xd1\x14\xcd\xba\xde\x36\x9a\x37\xfb\x2b\xf1\xfe\xcd\xf1"
+  "\x4a\xbc\x9f\x65\x97\xf1\x5e\xbc\x76\x4d\xe4\xf7\x37\x83\x6e\x8c"
+  "\x8d\xe6\xcd\x20\x19\xef\xdf\x3c\xdf\x33\xde\x27\xac\x70\x8f\xf7"
+  "\x09\x62\x6c\xb6\x84\x15\x57\x8e\xf7\xb3\x1d\x78\xdf\x75\xff\x4c"
+  "\xe6\xd5\xfb\xc8\x3c\x75\xa3\x6d\x34\xb3\x3d\xe2\x7f\x77\xf1\x31"
+  "\xae\xde\x46\x23\xee\x49\x9c\xee\x3e\x3e\xc6\x81\x6e\x7c\x64\x0e"
+  "\x54\x3a\x63\xfd\x9c\x63\x4a\x5f\xc4\x39\x27\x25\x5f\xc4\x03\xd5"
+  "\x88\xf5\x89\x37\x2b\xb1\x3e\xd1\xdf\x93\x8d\x66\xa7\xe0\xec\x93"
+  "\x38\xf7\x49\xa5\x8d\xa6\x58\x69\xa3\x99\x88\xbc\x37\x7f\xa7\x67"
+  "\xac\x9f\x9b\xa0\xf4\x01\xe7\x7b\x14\x3f\x9e\x22\xfa\x80\x4f\x71"
+  "\xf2\x01\x7f\xe1\x43\x11\xeb\xe7\xbd\x55\x51\x63\x23\xde\xf8\x21"
+  "\xfe\x70\x5f\xef\x1c\xb7\x3e\x88\x6c\x0d\xe8\xc6\x0f\x71\xea\x11"
+  "\x0d\xfa\x34\x97\x6e\x4c\x76\xf2\x43\xec\x26\x9e\xb1\x02\xff\xa7"
+  "\xe8\x3d\xe2\x7f\x07\x95\xf1\x5f\x18\x21\xdb\x6d\x04\x94\xf3\x19"
+  "\x5d\xe6\x19\xaf\x97\xdd\xc6\x9d\x9d\xc4\xf8\x34\xe2\xbf\xfe\x33"
+  "\x2e\xe7\x27\xfc\xc4\xec\x36\xf3\x6f\x55\xe2\xfe\xfc\x30\x25\xee"
+  "\xeb\x2f\xca\xb8\x2f\x5e\xbb\x26\xbe\xe8\xf3\x03\x6e\x8c\x9c\x3f"
+  "\x3f\x40\xb6\xdb\xcc\xff\xae\x67\xdc\x9f\xab\x77\x8f\xfb\x73\xf5"
+  "\x1c\xf7\xe7\xea\xbb\xb5\xdb\x28\x7c\x23\x13\xab\x7e\xb0\xdd\x46"
+  "\x92\xf3\x6f\xf8\xbe\x9e\xc4\x4a\x6f\xec\x36\x8e\x3d\xe9\x3f\xc8"
+  "\x6e\xe3\x1e\xef\x25\xd9\xfe\x40\x37\xdf\x5c\x95\x78\xbf\xa0\x4a"
+  "\x89\xf7\x0b\xbe\x52\xe2\xfd\xa2\xb3\x4a\xbc\x5f\xd4\xe2\xce\x6e"
+  "\xa3\xc4\xfa\xa4\x7b\xdd\xe1\xbc\x7e\x22\xda\x6d\x16\x15\x79\xc6"
+  "\xf8\xa4\x09\xde\x63\xfc\xc2\x99\xff\x87\xf1\x2e\x18\xaf\x71\xc5"
+  "\xf8\x85\x9b\x7f\x54\x19\x9f\x61\x7c\xf2\x3a\x05\xc6\x5f\x43\x5b"
+  "\xce\x95\xec\x27\xf1\x2c\xdb\x27\xbb\xf8\xbf\x2f\x72\xf1\x7f\x4f"
+  "\x76\xf2\x7f\x5f\x34\xf8\xda\x61\x7c\xf2\xb5\xf7\x7f\xbf\x22\x8c"
+  "\x4f\x76\xf2\x7f\x5f\x54\xd5\x33\xc6\x27\x45\xb9\xc7\x78\x38\xcf"
+  "\x30\x3e\x29\xaa\x5b\xd9\x5e\x81\xf1\x29\x9f\x5e\x0f\x5b\xce\x8d"
+  "\xd9\x6f\x94\x52\xea\x8d\x3d\xa7\xbb\xb8\x23\x1e\xed\x39\x23\x25"
+  "\x7b\x8e\xde\x83\x3d\xe7\x5a\x61\xfe\xe2\xcf\x95\x98\xbf\x78\xbf"
+  "\x12\xf3\x97\x5e\x54\x62\xfe\xd2\x36\xa5\x3d\x27\xb1\x8b\x3d\x47"
+  "\x89\xff\xa9\xc1\xc6\x89\xce\xf6\x9c\x62\x27\x7b\xce\xd2\x8f\x3c"
+  "\xe3\x7f\xaa\x47\xfc\xbf\xc4\xf0\x3f\xd6\x0d\xfe\x2f\xf9\x0f\xc1"
+  "\xff\xd8\x1f\x80\xff\x4b\x6e\x00\xfe\xa7\x7d\xc0\x6d\x3c\x57\x18"
+  "\x27\x65\xa7\xf7\x36\x9e\x1f\xb6\x0e\xa4\x75\x28\xd7\x81\xa5\x43"
+  "\x94\xeb\x40\xda\x49\x79\x1d\x10\xaf\x5d\x93\x75\x20\xcd\x7a\x63"
+  "\xd6\x81\x34\xab\xbc\x0e\x2c\x3d\xdc\xf3\x3a\x90\xea\x61\x1d\x48"
+  "\x15\xd7\x81\x54\x2f\xd6\x81\xf4\xfd\x9e\x6d\x3c\xfa\xab\xb7\xf1"
+  "\x8c\xba\xd1\xfb\xa0\xd2\xcb\xbd\xb2\xf1\xac\x8d\x30\x54\x62\x8c"
+  "\x94\x93\x44\xbd\x64\x9a\x64\xe3\x31\xba\xd8\x78\x8c\x5d\x6c\x3c"
+  "\x8b\x4f\x8a\xf8\x3f\x41\xdc\x6f\x3a\xf1\x07\xc4\x48\x61\x79\x94"
+  "\x33\x3e\x57\xfa\xcd\x67\x30\xfc\x97\xe3\xf7\x2d\x7f\x11\xfb\xc5"
+  "\xd7\x1f\x63\x37\x31\x50\x33\xfb\x2a\x6c\x3a\x13\xdc\xc5\x48\x59"
+  "\xae\xf0\xbb\x51\xee\x37\xcd\x1c\xa3\xc0\xfb\x89\x7c\xbf\xe9\x27"
+  "\xee\xbe\xd3\x3a\x62\xf2\x2f\x0b\x67\x31\xf9\x1d\xb1\xfc\x32\x33"
+  "\xaf\x28\x96\xf4\x14\x31\x96\xf4\xf1\x1b\x10\x4b\xfa\x4a\x63\xf2"
+  "\x1f\x77\x8d\xdf\xb7\xec\x3b\x53\xa5\x91\x54\x23\x8f\xc4\xb8\xc6"
+  "\x3e\x35\xba\xdf\xbb\xaf\x16\xf7\xee\xcf\xbd\x3e\x71\x50\xb0\x3f"
+  "\x6c\xcd\xef\xf7\x9e\x61\x6b\xba\x85\xf5\x07\x73\x56\x9f\x51\x65"
+  "\xcd\xa9\x04\x5e\x15\x10\x4f\x13\x11\x4f\xb3\x8a\x59\xdd\x93\xc0"
+  "\x0b\xfd\x1e\x28\x41\x3e\xce\x13\x48\x80\x3e\x19\xb1\x35\x8b\xf9"
+  "\x7d\x81\x18\x01\xd8\xca\xeb\x2d\x3d\x49\xed\xf6\x7e\x8f\x95\x40"
+  "\xff\x6f\xda\x36\xb7\xc6\xaf\xda\xdc\x06\xf3\xa2\x19\xf7\xc4\xaa"
+  "\x4c\xb6\x76\x23\xd2\x62\xcf\xdc\x1a\x5f\x0a\xf8\xbb\xe9\x75\xe2"
+  "\xef\xdd\x3c\xcd\x9a\xcd\xe4\x19\x5c\xf7\xfa\xbd\x57\x84\x71\x40"
+  "\x24\xd9\x4a\xf8\x5e\xb6\x6f\x6d\x80\xf1\x11\x28\x5f\xfb\xa6\xce"
+  "\xe4\xb8\x01\xcf\x2b\x85\xb1\x64\x3e\xb6\x88\x1b\x2c\x87\x15\xe0"
+  "\xc6\xc6\x0b\xf2\x77\x6c\x6c\x1f\xc7\x88\xdb\x51\x96\xcb\xfe\x2f"
+  "\x66\x4f\xd8\x9a\x39\xd6\x3d\xb6\x66\x8e\xe5\xd8\x9a\x39\xd6\x81"
+  "\xad\x66\x37\x76\x14\x85\x1f\xfb\x0a\xd1\xff\xc5\xe8\x22\x63\x1b"
+  "\xff\x0d\xe3\xa3\xac\xf0\xca\xff\x85\xe1\xe9\x6c\x8e\xa7\x88\x57"
+  "\x12\xa6\xca\x76\x14\xa3\x47\x3b\x4a\x4f\x98\xea\xd5\x1e\x7e\x86"
+  "\xa9\x6f\xf5\x57\x62\xea\x5b\x77\x28\x31\x35\x67\x9d\x2b\xa6\x76"
+  "\xc5\xd3\xb7\x26\xbb\xc3\x52\x1e\x1f\x25\x67\xbc\x67\x1c\x7d\x6b"
+  "\x85\x27\x1c\x65\xfe\xe9\x53\x9c\xfc\xd3\x1d\x38\x9a\xbd\x46\x89"
+  "\xa3\x6f\x55\x5c\x29\x8e\xb2\xdc\x26\xc7\x7f\x84\xdc\x26\x57\x8d"
+  "\xa3\x7a\x17\x1c\xfd\xed\xe3\x32\x8e\xba\xe6\x37\xe9\x01\x47\x67"
+  "\x5d\x9f\x18\x28\x0a\x1c\x15\x2c\xac\x3f\xba\xb9\xac\xaf\x9f\x29"
+  "\x71\xf4\xb7\x4d\x9e\x71\xf4\xb7\x6f\xc9\x38\xca\xeb\x5d\x5f\x1c"
+  "\xfd\xed\x0e\x05\x8e\xce\x72\xc2\xd1\x7f\xc9\x3a\x04\xfa\x58\x38"
+  "\x70\x74\x8e\x13\x8e\xce\xea\x09\x47\x7f\xbb\x03\xc7\x88\xcb\xa8"
+  "\x39\x8b\x7b\xc6\xd1\xb7\x56\xba\xc7\x51\x38\xcf\x70\xf4\xad\x95"
+  "\x32\x8e\xba\x91\x51\x15\x38\xfa\xf6\x6b\x5e\xe0\xe8\x4f\x3c\x36"
+  "\xca\xdb\x31\x5e\xd9\x2a\xe4\x3d\x9d\x5d\x63\xa4\xbe\xe6\xbc\x27"
+  "\xa8\xcc\x25\xef\x49\x59\x97\xbc\x27\x8b\xa5\x3d\x9e\xe3\x45\x5c"
+  "\x7d\xe1\x07\xe0\x2a\xdb\xe3\xf9\xce\x1c\xa5\xef\xc9\x3b\xf3\x25"
+  "\xdf\x13\x8e\xab\x79\x7e\x52\xbf\xe4\xbc\x27\x65\xdd\xc4\x48\x7d"
+  "\xe7\x73\x45\x6c\x94\xf1\xce\xb1\x51\x72\x3f\xf3\x1c\x23\xf5\x9d"
+  "\x26\x45\x6c\x94\x83\x25\x8e\xbc\x27\xae\x31\x52\x65\x8c\xfd\x5d"
+  "\x07\xc3\x58\x47\x0c\xaa\xdf\x0d\x71\xc4\x48\xed\x61\x5f\x10\xb6"
+  "\xb3\xad\x21\xe1\xfa\x63\xac\xd1\x0b\x8c\x55\xe4\x3d\x71\x8d\x31"
+  "\xb5\x72\x83\xa9\xa2\x8c\x54\xc7\x96\xb9\x89\x8d\x5a\x76\x43\x73"
+  "\x9f\x60\xbf\xdc\x63\x6d\xee\xbd\x4a\xac\xcd\x8d\x62\x75\x8f\xb9"
+  "\xc3\xda\x95\xe7\x65\xac\xe5\xf5\x96\x1e\x73\xc1\xda\x7a\x0f\x58"
+  "\x0b\xeb\xea\xa6\x33\xde\x62\x6d\xae\x8e\x61\x6d\x96\x88\xb5\xcd"
+  "\xd7\x1a\x6b\x73\x75\x32\xd6\xe6\x9e\xee\x39\xc7\xd4\x3b\x16\xf7"
+  "\xfb\x72\xde\xb1\x70\xac\x7d\xc7\xd2\x6d\x8e\x29\x85\xcf\x47\xde"
+  "\x61\x29\xc7\x94\x6c\x0f\x28\x13\xed\x01\xff\xce\x39\x51\xf2\x6a"
+  "\xbd\xb5\x07\x1c\x02\xdd\x1d\xf7\x5d\x2e\xc1\x9c\x53\x31\x98\x13"
+  "\xa5\xd4\xc5\x1e\x50\xda\xd5\x1e\x30\xb9\x7b\x8c\xf5\xca\x1e\xc0"
+  "\xf6\x5d\xae\xfa\x4a\x89\xb1\xab\x0e\x2b\x31\xf6\xdd\x39\xd2\x3e"
+  "\x4b\xec\x8f\xe7\x98\xa9\x86\x7b\x1d\xf6\x80\x7a\x25\xb6\xca\xf6"
+  "\x80\x77\x07\x79\xc6\x58\x83\xd2\xfe\xfb\x42\x89\x62\x9f\xe5\x27"
+  "\x0d\xce\x71\xa8\xa5\xf8\x53\xf9\x33\x0f\xd4\x3a\x63\xac\xc1\xf0"
+  "\xef\x14\x87\xda\x11\x6b\xaa\x07\x5f\xee\xae\x71\xa8\x57\xfb\x99"
+  "\x2a\x4a\x09\xee\x6d\x63\x78\xab\xb0\x0d\x94\xde\x18\xdb\x40\x45"
+  "\xa9\x07\xdb\xc0\xea\xb7\x95\x38\xbb\x7a\x17\xab\x7b\xc4\x1d\xce"
+  "\xae\x9e\x2c\xe3\x2c\xaf\xb7\xf4\x88\x0b\xce\xd6\x5d\x4b\x99\x76"
+  "\x75\xce\xf5\xb5\x0d\xac\xce\x91\x6d\x03\xef\x5e\xc1\xfe\x47\x43"
+  "\x94\x7b\x9c\x35\x88\x76\x57\x83\x6c\x77\xad\x73\x93\x2f\x45\x81"
+  "\xb3\x05\x8f\x4b\xfb\x1f\x99\x4c\x5b\x2f\xc9\xb4\xa5\xff\x86\xf9"
+  "\x52\x0a\x42\xbd\xb5\x0d\xe0\x3e\x77\xc4\x56\xc4\x2e\x09\x5f\x65"
+  "\xdb\x40\xa9\x67\xdb\x40\x0f\xf8\xea\x7d\xee\xbe\x35\x8f\x2b\xf1"
+  "\x75\xcd\x30\x25\xbe\x16\x7e\xee\x8a\xaf\x5d\xb1\x75\xcd\x42\x77"
+  "\xb8\xca\x6d\x03\x85\x7a\xcf\x98\xba\xa6\xd8\x13\xa6\xb2\x98\x7e"
+  "\x0d\xb2\x8f\xb4\x8c\xa9\x6b\x77\x2b\x31\x75\x4d\xe3\x95\x62\xea"
+  "\x0d\xc9\x97\x72\xd5\x98\x9a\xe0\x82\xa9\xef\x4d\x96\x31\xd5\x35"
+  "\x67\x4a\x0f\x98\x7a\xbd\xec\x04\xce\x98\xaa\x90\x5d\xdf\x3b\xa6"
+  "\xc4\xd4\x42\x8d\x67\x4c\x7d\x6f\xab\x8c\xa9\xbc\xde\xf5\xc5\xd4"
+  "\xf7\xea\xaf\xaf\x9d\xe0\xbd\x7a\x59\x76\x2d\xfc\xa0\x67\x4c\x5d"
+  "\x53\xe2\x1e\x53\xd7\x94\x70\x4c\x5d\x53\x72\xe5\x7b\xca\xd7\xbd"
+  "\xe5\x05\xa6\xfe\xc4\x73\xa9\xac\x5b\xe1\xb5\x9d\x00\xed\xad\x88"
+  "\xa5\xf5\x3f\x2c\x76\x48\x8a\x14\x3b\x64\xac\x88\xb1\xcf\xfe\x50"
+  "\x8c\x7d\x7f\x8d\xd2\xa7\xe1\xfd\x75\x92\x4f\x03\xc7\xd8\x8d\xa3"
+  "\x94\xf9\x51\xbb\xc6\x0a\x51\xc6\x50\x7d\xff\x3b\x87\x9d\x00\x31"
+  "\x77\xac\xb3\x9d\x60\xc3\x77\x9e\xf1\x76\xbd\x46\x61\x27\xf8\xd2"
+  "\x3d\xde\x5e\x52\xe0\x6d\xd1\x23\x0c\x6f\x1d\x31\x54\xd7\x47\x49"
+  "\x31\x54\x7b\x94\x61\x15\x78\x1b\xfb\xe3\xe0\x6d\xd9\x95\xe3\xad"
+  "\x32\x97\x8a\x6b\xbc\xd4\xa2\xaf\x4c\xe5\x80\xb7\x2c\x5e\x87\x6b"
+  "\xcc\xd4\x2b\x8b\xd7\x71\xbd\x62\xa6\x62\xbf\xdc\xe3\xee\x86\x49"
+  "\x4a\xdc\xdd\x90\xc3\xea\xba\xc5\xdd\x0d\xc1\x32\xee\xf2\x7a\x57"
+  "\x8c\xbb\x57\x65\x33\xd8\x10\x75\x7d\x6d\x06\x1b\xa2\x64\xdc\xdd"
+  "\x78\x47\xcf\xb8\xbb\x5e\xeb\x1e\x77\xd7\x6b\x39\xee\xae\xd7\x76"
+  "\x8b\xbb\x0a\x1f\x82\x4d\x37\xbb\x8d\xe5\x51\xff\xef\x9e\x67\x65"
+  "\x93\xff\xd5\xd8\x0c\x00\x83\xd5\x69\x18\xc3\x29\x16\x7d\x08\x7a"
+  "\xb6\x19\xf4\x84\xb7\xde\xdb\x0c\x8a\xfd\x94\x78\x5b\x7c\xb3\x12"
+  "\x6f\x7f\xff\x19\xf6\xab\x5b\x9b\x01\xc3\x80\xe2\x49\x0e\x9b\x81"
+  "\x59\x89\xb3\xb2\xcd\xe0\xf7\xf1\x9e\xbf\x7d\x15\x67\x2a\xe4\xdb"
+  "\x67\x5d\x62\x56\x4f\x91\xf1\xf6\x60\xb5\xe4\x33\xf6\xc1\xa7\x07"
+  "\x22\x9d\xf1\xb6\xb8\xbc\x4b\xcc\xea\xa8\x6b\x18\xb3\x3a\xea\x1a"
+  "\xc7\xac\x9e\xa4\x8c\x59\xfd\xfe\x25\xd9\x8f\xcc\xfb\x98\xd5\x1f"
+  "\x86\x33\x0c\x46\x1e\xc2\xb8\xd5\x57\x62\x47\xb8\xce\xb9\x56\x14"
+  "\xd8\xab\xb0\x23\x7c\xf8\x95\x12\x7b\x7f\xef\xeb\x19\x7b\x3f\xfc"
+  "\x40\xc6\x5e\x5e\xef\xfa\xca\xbc\x1f\xd6\x5c\x5f\x3b\xc2\x87\x35"
+  "\xb2\x1d\xe1\xf7\x6b\xdc\x62\xaf\xe2\xdb\x58\x71\x8e\xfb\x6f\x63"
+  "\x70\x9e\x61\x6f\x71\x8e\x47\x3b\x42\x17\xff\xad\xcd\x8b\xf9\xb7"
+  "\x31\x51\xe6\x35\x7b\x61\x47\xf8\xc9\xf9\x18\x6c\x4e\xb9\x1a\x3b"
+  "\x02\xe2\x2d\xe2\x99\x84\xb9\x57\x62\x47\xb8\xf6\x32\xee\x47\x8b"
+  "\x95\x98\xfb\xd1\x52\x25\xe6\x7e\x3c\xc8\x15\x73\xbb\xe2\xed\x47"
+  "\xbb\xdd\x61\x2d\xb7\x23\x94\x54\x7a\xc6\xd9\x8f\x9a\x3c\xe2\xac"
+  "\x8b\x6f\xae\x8c\xb3\xff\x7d\x87\x12\x67\xff\x30\xe4\xaa\x70\xf6"
+  "\x4a\x73\xb0\xfc\xa4\x70\x36\xd6\x05\x67\xff\xfb\x33\x19\x67\x5d"
+  "\xf3\xb0\xf4\x80\xb3\xd7\x29\x0f\x8b\x67\x19\xb7\x64\x94\x12\x67"
+  "\x4b\x66\x7b\xc6\xd9\x92\x9b\x65\x9c\xe5\xf5\xae\x2f\xce\x96\x8c"
+  "\xbc\xbe\xb6\x85\x92\x91\xb2\x8c\x5b\x62\xef\x19\x67\x3f\xb2\xb8"
+  "\xc7\xd9\x8f\xc4\xef\x62\x1f\x59\x3c\xca\xb8\x5d\x70\xf6\xe3\x93"
+  "\x5e\xe0\xec\x4f\xdc\x07\xe1\x63\xf3\xd5\xd8\x16\x18\xbe\x9a\x5d"
+  "\xf6\x4b\x1c\x71\xde\x2f\xe1\x64\x5b\x18\x2b\xd9\x16\x94\xf9\x59"
+  "\x52\x24\xfb\x6d\x98\x88\xbb\x4f\xff\x50\xdc\xfd\xe4\x7c\xbb\x03"
+  "\x77\x13\x01\x77\x3f\x61\xfb\x23\xda\x1d\xb8\xbb\xed\x63\xa9\x5f"
+  "\x72\x7e\x16\x0f\xb6\x85\xd1\xd8\xde\x1f\xc7\x39\x6c\x0b\x88\xc3"
+  "\x61\xce\xb6\x85\x6d\x93\x3d\x63\xf0\x1f\x67\x2b\x6c\x0b\x5f\xb8"
+  "\xc7\xe0\x36\x05\x06\x6f\xd9\xc0\x30\x78\xb4\x84\xc1\x7f\x2c\xbd"
+  "\x04\xba\xe5\xa5\x6c\xef\x30\xb8\x8d\x61\xf0\xf8\x1b\x83\xc1\x3b"
+  "\xae\x01\x06\xb3\x71\xdf\xfa\x94\xc9\x08\x18\x1c\x83\x18\x3c\xfe"
+  "\xca\xec\x0d\x3f\x52\x8e\x16\xec\x97\x7b\x2c\xde\xba\x5f\x89\xc5"
+  "\x5b\xad\xac\xae\x5b\x2c\xde\xba\x46\xc6\x62\x5e\xef\xfa\xda\x1b"
+  "\xb6\x96\x5f\x5f\x7b\xc3\xd6\x72\x19\x8b\xb7\xbd\xdd\x33\x16\xff"
+  "\x31\xc9\x3d\x16\xc3\x79\x86\xc5\x7f\x4c\xea\x16\x8b\x47\x3b\x63"
+  "\xf1\x76\x87\xcc\xab\xb0\x37\x98\xff\xdd\x73\xb7\x6c\xf7\x28\xff"
+  "\xea\xee\x26\x99\x0d\xaa\xed\x5f\x99\x8a\x08\x69\xcd\x22\x99\x26"
+  "\xdb\x68\x02\xe7\x60\xfc\xb6\x77\x98\xb4\x23\x89\xb0\x7a\x84\x15"
+  "\xf1\xf8\x5d\xfc\x81\x8c\x6b\x50\x8b\x73\x8b\x8d\x71\x29\xf3\x77"
+  "\xc5\xf3\x88\xbd\x9b\x9c\xae\xbb\x7b\x16\x35\x8c\x48\x12\xef\x8b"
+  "\xe2\xfb\x6e\x46\xa4\x48\x65\xe4\x4d\xb3\xaa\x34\x9a\xe6\x8f\xd0"
+  "\x5b\xfa\x8e\xd0\xbb\xbb\xff\x3e\x0d\xf1\xef\xb3\x8c\xd2\x8d\x6b"
+  "\x69\x5b\xeb\xfd\x23\x33\x5b\xdf\x21\xc4\xb0\x96\x5a\xda\xb3\x4b"
+  "\x0d\xf0\x8e\x65\xef\x41\xbd\xd6\x7e\x5b\xf4\xad\x59\x91\x04\xce"
+  "\x6d\x96\xce\xc1\xb8\x11\x21\xcb\x87\x0a\x70\x8d\xae\xb6\xc5\x6c"
+  "\x4a\x07\xac\x4a\x23\xe4\xd1\x4b\x38\x67\x4a\x77\x00\xcf\x04\xe5"
+  "\x41\x9b\xab\xa0\x2d\x7a\xfb\x5d\x6d\xc0\x8f\xbe\xd5\x2b\x08\xce"
+  "\xe9\x1c\x78\xaf\xe2\x3c\x1c\x7b\x9f\x87\x0a\xa9\xda\x97\x08\x1f"
+  "\x3d\x50\x47\xfb\x47\x1a\x80\x1e\xc4\x90\x48\x98\x1d\x67\x15\xd4"
+  "\xa3\xea\x0c\x2a\x04\xdf\x1f\x6b\xb2\xb5\xf1\x39\x0d\xfd\xdb\x03"
+  "\x7a\x2c\x85\xe7\x6e\x4c\x24\x1a\xf8\x05\xd0\x35\x91\x86\xf6\xec"
+  "\x4f\xc7\xc0\x7b\x0e\xc6\x7e\x79\x7a\xc7\x55\xef\xc3\xba\x73\x97"
+  "\x16\xd7\x0e\xf6\x7c\x7c\x36\x7b\x8e\x5a\xc8\xb1\xc3\x79\x9a\x95"
+  "\x41\x4d\x29\x36\x12\x08\x63\xb1\x09\xfa\x8d\xfc\x28\xfc\x61\x64"
+  "\xe6\xf2\x3b\x09\xd9\x96\xda\xa4\x36\x41\xdf\xed\xef\xdd\xd5\x66"
+  "\x4c\x7f\x82\xc0\x75\x0b\xea\x2c\x67\x54\x7f\x1a\x15\xf1\x1d\x21"
+  "\x88\x27\xf0\xff\xb8\x36\x58\xc7\xc2\xa1\xbc\x0a\xde\x43\x68\xd5"
+  "\xfa\x62\xdd\x33\xaa\x4f\xcf\x1b\x93\x8f\x92\x40\x3d\xf1\xcf\x83"
+  "\x77\xe3\x75\x3f\x35\x62\x5d\xb3\xea\x4f\x63\xb1\x0f\x50\xae\x85"
+  "\x32\xde\x87\x3e\x64\x84\x6e\x7e\xa0\x8e\xf1\x66\x41\xa4\x41\x08"
+  "\x7e\xa0\x8e\x61\x1f\xbc\xe7\x2a\x78\x67\xa8\x13\x00\x75\x02\xd8"
+  "\x31\x9d\x68\x0a\xe0\x1c\xb6\x03\xc7\x00\xe3\xdc\x4e\x6c\xbb\x14"
+  "\xdb\xf6\x30\x0e\xbe\x34\x28\xd2\x40\x81\xb7\x71\x4d\xd5\xa5\xab"
+  "\xbe\x6a\x50\xfd\xa9\x31\x50\x45\x29\xdd\x7c\x7f\xec\xf2\x74\x12"
+  "\x60\x10\x08\x31\xde\x89\xed\xfc\x69\x37\xb4\xef\x8b\x63\xd1\x9e"
+  "\xfd\xa7\x22\xb3\xea\xd3\xf1\x38\xbe\x40\xcf\x36\xdd\x7d\xec\x7d"
+  "\xdb\xf0\x39\x78\x8f\x58\x9f\xc5\xbe\xc7\x3e\xeb\xd2\x7d\x28\x94"
+  "\x8f\xf9\xa8\x4e\x12\x1f\x6d\x40\x36\xdc\x5f\x6f\x26\xb3\x6a\xf1"
+  "\x7e\x33\xbf\x0f\x78\xe9\x4f\x16\xa0\x59\x1c\x9e\xc3\xb2\x87\xfe"
+  "\x06\x48\x74\xab\xd2\x02\x6f\xb8\xd2\x4e\xe2\x11\xe0\x0b\x89\x47"
+  "\xb0\xbf\xdb\xd3\xcd\x6a\xb6\x0e\xab\xfe\xcc\xf4\xba\x3c\xa0\xa1"
+  "\x7d\xbd\xd6\x77\x15\x8c\xad\x70\x19\xe9\xd2\x00\xd7\x76\x0c\x43"
+  "\xba\xac\x4a\x05\x9a\xf0\xba\xd1\x72\xff\xb1\xbc\x83\xd1\x53\x00"
+  "\x5a\xf0\xbd\x9b\x3b\x6e\xc6\xf7\x59\x75\x09\xe8\x38\x80\xb6\x95"
+  "\xc3\xec\xa7\xc8\xb7\xc0\x23\xdb\x12\xad\x6a\xf4\xeb\xc3\xf3\x7b"
+  "\x2e\x58\xd5\xab\x9a\x09\xca\x95\x24\x17\x70\x79\x43\x32\x8c\x39"
+  "\xb4\x49\x07\xdf\x1f\xfb\x98\x44\xc7\x54\xa0\x5d\x32\xf0\x2e\x8c"
+  "\xf9\x2a\x18\xbf\x8d\x80\x79\xf8\xff\x46\x58\x7f\x04\xa8\x67\x56"
+  "\xed\x18\x0b\xed\x69\x36\x0c\xa0\x96\x4d\x03\x68\x0b\x8c\xe1\xfb"
+  "\xed\xd9\x3b\x74\xd2\x18\x62\x9f\x56\xc1\xf9\x5c\xb8\x6e\x56\xfd"
+  "\xb9\x88\xf3\xd0\x9f\x67\x4b\xef\xec\x69\x3c\x57\x6e\x23\x23\x73"
+  "\xb7\x91\x81\xef\x6c\x23\x63\x96\x34\xc2\xbc\xcc\xfa\x15\x3d\x14"
+  "\x63\x83\x35\x31\xbf\xa4\x73\xc0\x28\x3d\x7e\x7b\x12\x96\xdf\x55"
+  "\xfc\xd6\x36\x32\x04\xf7\xc6\x46\xb4\x10\x82\x6b\x78\x84\xdf\x09"
+  "\x6a\xd2\x5f\x24\x42\xdf\xfc\x12\xfb\xf2\x87\xfa\x4d\x04\xa9\x6d"
+  "\x7f\x48\x1b\x49\x4f\x82\xb5\xfc\x42\x13\x49\x6f\xa3\x96\xea\xcc"
+  "\xef\x08\x60\x4f\x02\x1f\xbb\xcf\xcc\x11\xf1\x84\xe0\x9e\x41\xe1"
+  "\x5f\x21\xe4\xd6\x04\xe2\x9b\x76\x84\x68\x33\x1a\x69\x93\x7d\xed"
+  "\xb3\xb1\xe9\x4b\x89\x7a\xdb\x85\x3a\x2e\x7b\xaa\x3e\xfb\x74\x37"
+  "\xee\x4f\x6d\x8f\x26\x53\x6d\xe2\x7a\x54\x10\x59\x98\x31\x93\xdc"
+  "\x81\xef\x13\xc8\x64\xaf\xcf\xc2\x61\xdc\x0a\xbd\xc3\xe7\xcf\xb4"
+  "\x8c\x9e\x6b\x9f\xb3\x6c\x9b\x6e\x05\x79\xcb\x9e\x99\x11\x4f\x9b"
+  "\x50\xae\x83\xf5\x85\xc9\x82\xa6\x26\x1b\xc8\x56\x71\xb0\x7e\x9b"
+  "\xc9\xde\x86\x62\xb5\x90\x6f\xcf\xf4\xf2\x19\x69\x6c\xdd\xc6\xb5"
+  "\x14\xfa\x3e\x29\x84\x64\xb2\xfe\xc3\x9a\x19\x98\x84\xf2\x14\x3d"
+  "\x81\xfd\xdf\x03\xef\x4a\xef\x9d\x01\xb4\xfa\x8c\xe0\xfa\x19\x51"
+  "\x6f\x24\x95\x56\x3b\x79\xbf\x99\x8d\x51\x2f\x18\x23\x5f\xa0\x79"
+  "\x2d\x8c\x93\xbf\x3b\xba\x21\xcd\x04\x43\x7e\x89\xe0\xc3\x69\xc3"
+  "\xe8\xd2\xc6\xe9\x32\x71\x3e\x81\x75\x14\x68\x93\xcf\x69\x23\xf4"
+  "\x8f\xd0\x23\x6d\xbc\x7b\x8f\xff\x19\xeb\x69\x7d\xc1\x67\x53\xe0"
+  "\x0f\xe4\x0b\x21\x28\x42\x8f\xcf\xc6\x3e\xe0\xf7\x33\xe4\x83\x88"
+  "\xb7\x4e\xd0\x6a\x7d\x13\x31\xc1\xfb\xd0\xbe\xce\x7d\xb0\x79\xdb"
+  "\x87\x0a\x4f\x7d\x58\xf9\x28\xf0\xed\xa3\xc0\xb7\x8f\x02\xdf\x9a"
+  "\x39\xdf\x1e\xac\xe7\x7c\x6b\x87\x7e\x75\x80\xec\xbe\x64\x12\x51"
+  "\x63\xbf\xb6\x1c\xc5\x18\x7d\xd0\xcf\x26\x99\x77\xc3\xcf\xc2\x18"
+  "\x49\xfc\xeb\xf3\x50\x3f\x1c\x9f\xea\xb6\x3a\x92\x81\xfc\xdb\xe9"
+  "\x8e\x7f\xcb\x8a\x23\xa6\x01\x6d\xde\x00\xfe\xfd\x67\x08\x09\x68"
+  "\x24\xbe\x4b\x27\x01\xff\x36\xb9\xe3\xdf\xb2\xf9\xbb\xe0\x99\x5d"
+  "\xf8\x37\xde\x99\x7f\xcb\x6e\xf5\x9e\x7f\xff\xb7\xce\xc1\xbf\xaf"
+  "\x88\xfc\x3b\xd3\x85\x7f\x1b\x9d\xf8\x17\xdf\xdb\x6b\xfe\x2d\x1b"
+  "\xe3\x1d\xff\xfe\xaf\xd1\xc1\xbf\xa0\x97\xbc\xff\x3a\x1b\xa3\x5e"
+  "\x30\x46\xc0\xbf\xff\x5b\x00\xe3\xe4\x96\x7f\x7f\x7c\xfa\xfd\x25"
+  "\xf6\xca\xe9\xf7\x97\xc7\x7b\xa6\xdf\xce\x2a\xef\xe9\xb7\xb3\xf0"
+  "\xfa\xd3\x6f\xa7\xcd\x3b\xfa\xed\xcc\xf4\x4c\xbf\x9d\x51\x3f\x1d"
+  "\xfa\xed\xd2\x5d\x39\xfd\xfe\x7a\xbe\x67\xfa\xfd\x35\xd7\x7b\xfa"
+  "\xfd\x35\xfa\xfa\xd3\xef\xaf\xbb\xbc\xa3\xdf\x5f\xc3\x3c\xd3\xef"
+  "\xaf\x41\x9e\xe8\xf7\xcc\x1d\x02\x15\xd0\x6f\x6e\xc0\xb0\x1a\x94"
+  "\x81\xb8\xbc\xb6\xeb\x2c\xea\x8c\x50\xf6\x95\xca\x4c\xa6\x02\xbd"
+  "\xda\xa5\x1c\xe0\x52\xd6\xb8\x94\x83\x5c\xca\x5a\x97\xf2\x40\xa9"
+  "\x0c\xf4\xf2\x3b\xa7\xda\xf5\x1a\xe8\x6c\x99\x66\xd5\x2e\xab\x78"
+  "\x7d\xf0\x54\xbb\x0e\xf5\xbe\xc1\xee\xfa\xbe\x2a\x8b\x5a\xf5\xe9"
+  "\xe4\xae\x66\xd5\xee\x38\x46\x8f\xe5\x77\x86\xd0\xd4\x4c\x02\xf4"
+  "\xd8\x31\x71\x29\xf2\x95\x85\xd0\xcb\xda\x5e\x30\x4e\xb7\x83\xbe"
+  "\x69\x41\x9e\xd3\x25\xee\xa5\x0d\xaa\xdd\x2f\xe2\xfb\x3d\xaa\x37"
+  "\x12\xc1\xe7\xa1\x10\xd4\x85\x80\x3e\x3b\x2c\x3e\x0f\xdd\x49\x3f"
+  "\x88\xcb\xcc\x53\x0b\xfe\x79\x59\x82\x6e\xa9\x85\x5a\x26\x9c\x87"
+  "\x75\x0c\xd6\x32\x53\x8b\x15\x78\x92\x5a\x8c\x89\x67\xa1\xbf\xbb"
+  "\x77\x56\xa5\x41\xdb\xf0\x1c\x78\x56\x29\xd5\xd8\x0b\x4c\xb6\x1a"
+  "\x42\xa1\x8d\xea\xb6\x0a\xd0\xfd\xeb\x88\xd8\x66\x29\xed\x6b\x2f"
+  "\xc0\x36\xdd\xea\x67\x05\xc3\x7d\xe1\x99\xa3\x27\x85\xf8\x12\xba"
+  "\xcc\x37\xc8\x3b\xfe\xd8\x5d\xef\x51\xef\x2b\x18\xbe\x82\xb7\xeb"
+  "\x7f\x15\xed\xee\x19\xea\xb9\xdd\x11\x62\x7f\x35\x57\xd3\xee\xca"
+  "\x6e\xda\x15\xfb\xab\xbb\x9a\x76\x1b\x3d\xb7\x3b\x52\xec\x6f\xd8"
+  "\x55\xb4\xbb\xd7\x63\xfe\x0f\x68\x57\xec\x6f\xe6\xd5\xb4\x5b\xd0"
+  "\x0d\xdd\x7c\xaf\x8e\x17\xf6\x36\x75\xc7\x0b\x57\xc7\x07\xc6\x6e"
+  "\xde\x7f\x84\xef\xd5\xf1\x80\xd1\xd0\x1d\x0f\x5c\x1d\xfd\x8d\xdd"
+  "\xd2\xff\xea\x68\xff\xf9\xc8\xee\x68\x7f\x75\x74\xff\xdc\x23\xff"
+  "\xa3\x2e\x4b\x0b\x86\x15\xd3\x01\x33\xcc\xc2\x5a\xbf\x62\x61\xc0"
+  "\xb0\x0f\x97\x0b\x61\xe4\x19\xc0\xb0\xc0\x42\xd2\x37\x8c\xd9\x87"
+  "\xbe\xd0\x2d\x2d\x22\x6a\x83\x5a\x50\x6f\x4d\xad\x53\x9b\x6c\x23"
+  "\x49\x86\x8d\xda\x37\x27\x5b\x55\x3f\x83\xf3\x9f\x27\x10\xd2\xb6"
+  "\x20\x84\xf0\x76\xfc\x8a\xf3\xd2\xc3\x48\x84\x9d\xa0\x3d\xa2\x6d"
+  "\x1f\x68\x22\x11\x80\x63\xa6\x42\x2b\xae\x79\x7d\xe1\x3e\x1b\xf0"
+  "\x2f\xb4\x61\x25\xdb\x05\x8b\x2a\x2c\x91\xd5\xb3\x80\xde\x68\xa1"
+  "\x6b\x87\x7d\x48\x33\x42\xc8\x0a\xf8\x1f\x9e\xf9\xb6\x8f\x85\xa8"
+  "\x37\x82\x3e\xd9\x9e\xfd\xc5\x0a\xb3\x6a\x5f\x2c\xea\x98\xa0\xcb"
+  "\xb6\x64\x9c\x47\x9b\xfb\x0c\xf3\x72\xd0\x6b\xb1\xee\x36\xc1\xa2"
+  "\x7e\x54\x4f\xd4\xfb\x2c\xa8\xbf\x7f\x51\xfa\x79\x12\x21\xdd\xd8"
+  "\x5c\x7c\x85\xa0\xf0\x46\xbc\x1f\xdb\x41\x5b\xe6\x2a\x01\xc6\x36"
+  "\x28\xb2\x10\xfb\x4b\x0b\x46\x45\x1b\x53\x71\x5d\xd8\x37\x72\xdc"
+  "\x83\xb4\x5d\xc4\xf9\x3b\x9b\xa1\xcc\x74\xf6\x2c\x5a\x43\x35\xb6"
+  "\x1c\x9a\x77\x6b\x58\x75\xdb\x05\x62\x4c\xee\x24\x0d\xaa\x7d\xa3"
+  "\xf0\xd9\xad\x41\xe1\xe6\xb6\xa0\xf0\xa6\xf6\xec\x7d\x43\xa5\xfe"
+  "\xe2\xb3\xa4\xf3\x68\xa3\xe0\x7d\xdc\x17\xf5\x79\x9a\xe7\x3e\xc2"
+  "\x5a\xd2\x2f\x42\x4b\x2d\x38\x86\xc6\xf4\x0b\xd0\x97\xf2\x03\x38"
+  "\xce\xb4\x20\xbc\xb4\x2d\x23\xe4\x6e\x6e\xb3\xdb\x67\x41\xdb\x0f"
+  "\xac\x03\x9b\x99\x1d\x26\xdf\xbe\x99\xf9\xd9\x00\xde\x83\xce\xce"
+  "\x6c\x6d\xe7\x54\xfb\x58\xfe\xe3\x49\x21\x6a\x2f\x75\x9e\x7d\x6c"
+  "\xfd\x37\xde\x8d\xe3\x50\xfe\x29\x3c\xef\x17\x0d\xaa\xf2\x20\x6e"
+  "\xc7\xb3\x97\xe1\xf3\xa0\x4e\x31\x3c\xb3\x8c\x1a\x6c\x99\x58\x0f"
+  "\xae\x0f\x15\xaf\x1b\x9d\xae\x1b\xa1\xcf\x56\xf1\xba\x68\x07\xb4"
+  "\x97\x3b\x5d\x2f\xd7\xdf\x8d\x76\xb9\xf2\x34\x7c\x27\x58\xcb\x8a"
+  "\x71\x5d\x43\x9b\x3f\xb7\xab\xdb\x8b\xc5\x7a\x3b\x5a\x54\xe5\x6b"
+  "\x5a\x81\xaf\xe0\xfa\x2e\xa7\xfb\x77\xed\x4b\x09\x25\xcf\x6c\xc0"
+  "\x31\x2d\x2f\x31\xfb\xfa\x19\xb8\x2d\x67\x1f\x1f\x0b\x8d\xbd\xd0"
+  "\xb9\x3d\xb3\xaa\x3c\x09\xda\x2c\x6c\x03\x59\x0f\xea\xac\xc4\x67"
+  "\x3a\x8f\x7f\x7c\x62\xe2\xbc\x44\x5d\x70\x9c\x2e\x6e\xce\x34\xdd"
+  "\x8c\x79\x0b\xe7\x26\x3d\x19\x1c\xd7\x9b\x10\x27\xde\xd1\xd0\xac"
+  "\x40\x2a\x14\x3c\x1f\x62\x2a\x04\x19\x4b\xad\x81\xf5\xb6\x93\x14"
+  "\x00\x5d\xed\x03\x26\x6b\xec\x6b\xa3\x61\xfe\x8c\x26\xc6\xd4\xa7"
+  "\x61\xec\xf7\x8f\x62\x76\x7f\x1d\x21\x2b\xe1\xba\x31\xf5\x20\x9e"
+  "\x0b\x67\xe7\x40\x62\x60\xf6\xaa\x54\x7f\x52\xae\xbb\xc0\x6c\x5e"
+  "\x70\xed\x2d\x66\xdf\xbb\x48\xd4\xb6\x2c\x7f\xf2\xe7\xf4\x1a\xf5"
+  "\x2e\xc1\xac\xfe\xb3\x50\xa7\x46\x79\x61\x9f\xb6\x82\x3c\x96\xe2"
+  "\x4f\xf0\xfa\xde\x74\x38\x0f\xd7\xf1\x1a\x6b\x87\xd1\x7a\xff\x61"
+  "\xac\x87\x36\x30\xfc\x3f\xa3\x90\x9e\xdc\xa7\xb5\x10\x2e\xb7\xee"
+  "\x7f\x10\xfb\xaa\xbb\x13\xbf\x2f\xec\x7f\x04\xfb\x67\x56\xed\x1f"
+  "\xe2\x53\x04\xf5\x93\x49\xc0\x39\xd5\x97\x77\x08\x6b\x9e\x0f\x41"
+  "\x2c\xb0\x65\x97\x9b\x69\x56\xdf\xd7\x37\xae\x26\xfe\x45\xab\x61"
+  "\x6e\xae\x26\xbe\xed\xd9\x5f\xfa\x9a\x7d\x07\x46\xe1\xd8\x42\x33"
+  "\x01\xad\x6a\xf2\x2b\x38\xa7\x35\x93\x59\xb3\xf1\x1c\xcc\xc1\x36"
+  "\x4f\xd8\x72\x09\xe4\x3b\xeb\xe0\x60\xd0\xd1\x9f\xd7\x52\x18\xb7"
+  "\xf6\xc1\xc1\x35\x81\x7a\xe0\x2d\x98\x63\xb4\xff\xf3\xda\x16\x55"
+  "\xc5\x90\x2f\x81\x73\xd2\x71\x4e\xaf\x1d\x4d\x3e\xb9\x64\xc5\xef"
+  "\x69\x9a\x2d\x97\x2c\x50\x8e\x2e\x2e\x81\xf2\x01\x63\x09\xd1\x4d"
+  "\x44\xd9\xe9\xcb\xdc\x5f\xc7\x51\xdb\x83\x95\x20\x67\x36\xfe\x89"
+  "\x1c\xaa\xad\x20\x01\x31\xc4\xc7\x11\xeb\x3d\x89\xa8\x23\xcc\x50"
+  "\x5e\x48\xd4\xd5\xa0\xf7\xa3\x6d\x3e\x7d\x14\xda\xe7\xab\x08\xda"
+  "\xec\xa9\x7a\x76\xd0\xd6\x0b\x56\xc0\xb0\x26\x3f\xf4\xf9\x16\x34"
+  "\xef\xa5\xe0\x3d\x53\xdb\xc4\x6f\x5d\xad\xe2\xb7\xae\x56\xf6\xad"
+  "\x2b\x2c\x2d\x96\x7f\xeb\xc2\x6f\x5c\x11\xb1\x3e\x14\xdb\xc3\xef"
+  "\x5e\xb7\xb6\x01\x1f\x2c\x08\xe9\x63\x5f\x10\xd2\xaf\xf0\x02\x09"
+  "\xaa\xb6\x34\x81\x8c\x56\x41\xd6\x27\x93\x20\xda\x9a\x70\x73\xa5"
+  "\xf1\x20\xa1\xab\xdf\xd5\x6f\x4f\x37\xfa\xd9\xd1\x46\xd1\xaa\xed"
+  "\x1d\xb8\x4c\x85\x76\xfe\x3e\x2b\x13\xc9\x90\x4d\x17\x48\xe8\xd4"
+  "\xd3\x99\x2c\xee\x13\xe6\xe8\xb3\xb5\x86\xe8\x2e\xb7\x86\xdc\xd7"
+  "\xd1\x1a\x72\x77\xa0\x85\x7f\x1b\x7b\xed\xac\x86\xa0\xbf\x2d\xcd"
+  "\xfe\x9f\x95\x9b\xd0\x46\xdd\x66\x21\xb6\xbe\xef\xa5\x20\x2f\xc3"
+  "\xb3\x07\xe2\xf7\x94\x8c\xc5\x44\x23\x9c\x0a\x21\x55\x09\x17\xc8"
+  "\x63\x40\x7b\xfc\x76\xb0\xb1\x81\x7f\x3b\xb0\x83\x4e\x83\xdf\x0f"
+  "\x2e\xb5\x86\xa8\x69\x50\x44\x66\xf8\x4c\x1d\xe9\xf8\x28\xb8\xd8"
+  "\x94\xf2\x09\xc9\xe8\xa0\x27\x4d\x2b\x04\x82\x76\x65\x9a\xfd\x65"
+  "\x28\xed\x1f\x91\xb9\x3f\xe4\x30\xae\x2b\xa1\x32\x76\xfc\xad\xe3"
+  "\xea\xb0\xe3\x6f\x4c\x7e\xc6\xef\x6c\x74\x2d\xd0\xf1\x02\xd2\x13"
+  "\xe8\x7a\xc1\xa2\x7e\x01\x68\x57\xd5\xf8\x21\xd0\xad\x4e\x41\x37"
+  "\x46\x67\xa8\x77\x26\x0e\xe8\x75\x9a\xd3\xb0\xb2\x0d\xe8\xb7\x13"
+  "\xdb\x98\xa8\xdb\x9a\x6c\x55\x83\xde\xa4\xae\xb4\x1e\x63\x7b\x56"
+  "\x90\x8e\x5b\x3a\x2b\xfc\x3a\x60\xbd\xc1\xef\x95\x97\x36\x07\x1b"
+  "\x3b\x82\xc6\x5b\x2f\x07\x3d\xef\xdf\xcd\xb7\x4b\x4e\xcf\x99\xc4"
+  "\xbf\xb2\xf1\x30\xa7\xe7\x7c\x91\x9e\xe8\xe3\xb6\x28\xa4\x8f\xad"
+  "\x1d\xe8\x79\x09\xe8\x99\x64\x26\xef\x27\x92\x20\x53\x53\x1d\x7e"
+  "\xd7\xb9\xf9\xf9\x2a\x42\x5e\x78\x90\x0a\x55\xc6\xa3\x8c\xae\xdb"
+  "\x80\xae\x36\x43\x7e\x09\x7e\xcf\x74\xd0\x35\x19\xe8\x7a\x09\xe8"
+  "\x7a\x56\xa6\xab\xbd\x1d\xe8\xda\x0e\x74\x6d\x07\xba\x8a\xdf\x3c"
+  "\x5f\x9b\x09\x74\xc5\xef\x63\xd9\xff\xab\xc1\x6f\x9e\xf8\x6d\x09"
+  "\xe9\x8a\x7e\xd5\xc2\xa2\x90\x81\xec\x5b\xe7\x8c\x10\xb2\x69\x3a"
+  "\xf1\x7f\xc4\x4a\x54\x19\x3b\x89\x06\xfa\xa9\xb9\x7f\x07\x51\x43"
+  "\x7b\xc0\xf7\x0d\x04\xe9\x6b\xda\x61\x27\x4b\x26\x93\xbb\x6d\xf9"
+  "\x9c\xce\x26\xdb\x67\x68\xdb\x1d\x79\x69\x51\x88\x7a\x5d\x32\x19"
+  "\x83\x34\x9f\x70\x5a\x47\xf6\x47\x56\x11\x57\x9a\x0b\x6b\xc2\x4b"
+  "\x81\x4e\x8d\x48\xf7\xab\x9f\xb7\x87\x1a\xaf\x7c\xde\x1e\x1c\xf7"
+  "\x7f\xf3\xf6\x5a\xcf\xdb\x03\x4d\xee\xe7\xed\xa1\x4f\xaf\x6e\xde"
+  "\x1e\x2a\xfd\xbf\x79\xfb\xef\x30\x6f\x0f\x15\xb9\xce\x5b\x87\xdc"
+  "\x92\x18\x3f\x67\xda\xcc\xb9\x33\xe7\xbe\xa1\x9b\xbe\x38\x29\x7e"
+  "\x01\x97\x5e\x14\xf2\x4b\x88\x5d\x08\x53\xbf\x0b\xeb\xf5\x21\x6d"
+  "\x1d\xd9\x7e\x67\x9d\x5a\x78\x55\xeb\x4b\x0d\x1f\x1b\x05\xc3\x96"
+  "\xf1\xef\x82\x1c\x8e\xf3\xbb\x00\x64\xec\x33\xaa\x3a\xed\xdf\x06"
+  "\x82\xfc\x99\xd8\x4c\xf0\x7f\x2e\xbb\xbd\x39\x12\xf7\x39\x16\xae"
+  "\xa5\x6c\x9f\xe3\x81\x72\x94\x2d\xaa\x27\xdf\x12\x0d\x3a\xc4\xab"
+  "\x5a\xd2\xf1\x6a\xb4\xfa\x9d\xa3\xc4\x3f\xb0\x8e\x4c\x10\x04\x4a"
+  "\x8d\xe9\xcd\x20\xf7\x1d\x8e\x35\xbe\xd2\x4c\x50\xd6\x39\xa3\xfa"
+  "\xe6\x73\x5d\xea\x32\x3c\x7e\xa4\x4b\xcd\x3e\x01\xc7\x78\x66\x6b"
+  "\x19\x40\x9b\xe8\xda\xf1\x7a\xfb\x1f\x1e\xb0\xe0\xf7\xcd\x4d\x03"
+  "\x68\xe3\x36\xd0\x33\xb6\x75\x5a\xd5\xcb\x2f\x00\xdf\x64\xdd\x43"
+  "\xf1\x3b\x25\x8e\xc1\xf2\x44\x18\x7b\x90\x7b\xb9\x6c\xfa\xf5\x7e"
+  "\x9c\x5f\x20\x5f\x35\xee\x39\x53\xa7\xc6\xef\xb4\x38\xe7\xda\x34"
+  "\xb6\xcc\x15\xf0\x2e\xd0\x4f\xf3\xba\xb5\xb4\xde\xd2\xff\xf9\x10"
+  "\x5f\x1d\x51\xb7\x67\x57\x57\x82\x0c\x68\x45\x99\x25\x07\xae\xbd"
+  "\x0d\xd7\xf8\x37\xc3\xaf\x33\x69\xaf\xaa\x42\xc4\x39\xe0\x6b\xd5"
+  "\x39\x95\xe9\x0e\x8c\xf5\xb4\x92\xeb\x25\x4d\xd6\x35\xcf\xfb\xdb"
+  "\x3e\x0a\x36\xda\x50\xa6\x0c\x0e\xae\xe9\x58\x33\xde\x6a\x5b\xf3"
+  "\x3c\xe6\x7d\x51\xf1\xfa\x35\xcc\xa6\xd4\x51\x30\x9a\x40\xfd\xb6"
+  "\xd6\xa0\xc9\x9a\xd6\x82\xe8\xe2\x83\x29\x85\x44\xf7\x12\xe2\x9f"
+  "\x69\xdc\x0b\x85\xd4\xf6\x50\x24\xe0\x5f\xe1\x27\xe4\xd0\x04\xc0"
+  "\xbf\xe8\xae\xf8\xc7\x7d\x09\xec\x84\xe3\x60\x15\xb6\xd5\x88\xf3"
+  "\x08\xe5\xd4\xad\x30\x16\x38\x47\x70\x2e\x30\x3c\x04\x2c\x94\xe6"
+  "\x0b\xce\x25\xc4\x3b\x36\x77\x5d\xe6\x0e\xce\x97\x5b\x2c\x44\x83"
+  "\xf3\x05\xf1\x10\xe7\x0b\xfa\xe8\xbc\x2b\xce\x97\xc0\x7a\xa2\x79"
+  "\x1f\xb0\xd0\x64\xab\x60\x73\x06\xe5\xc9\x4a\x9b\x13\x0e\xe2\xf7"
+  "\x1d\xa7\xf9\x92\x2b\xcd\x17\x09\x07\x61\x4e\xd8\x70\xbe\x2c\x0a"
+  "\xb9\xaf\x73\x91\x3c\x5f\x5e\x3d\xa6\x21\x0c\x23\xb3\xff\x47\x53"
+  "\x04\xf3\xa5\x5a\x6f\x21\x76\x09\x07\x61\xbe\xe0\x1e\x22\x86\x83"
+  "\x6f\x02\x0e\xb6\x00\x0e\x5a\xe0\x3c\xcc\x93\x8d\xb3\x44\x1c\x14"
+  "\xe7\x47\xc7\x22\x11\x07\xcf\xea\x48\x67\x30\xe2\xe0\xfb\x1e\xe4"
+  "\x97\x63\x2e\x38\x58\xb3\xf3\xea\x70\xb0\xa6\x0c\xef\x43\x1a\x76"
+  "\x02\x3d\x91\x8e\x2f\x68\xa9\xad\xb2\x10\xf0\x2f\xea\x27\x46\xb7"
+  "\x44\xf7\x74\xdb\x26\xae\x5f\x6e\x71\xce\x0d\xdd\x80\xcf\x5b\x6c"
+  "\xed\x5d\x69\x47\xb3\x77\x44\x3b\x63\x1d\x62\x1c\xe2\x1d\xe2\x1c"
+  "\x62\x1e\xce\x0f\xc4\x3a\xc4\xb9\x07\x60\x0d\x80\x72\x53\x55\x42"
+  "\x03\xc3\xc0\x8c\xd3\x44\x93\x31\x8e\xdc\x6d\x2a\xb3\x83\x7e\x73"
+  "\x91\x20\x06\x3a\xaf\x6f\x88\x79\x48\xdb\x75\x97\x38\xe6\xe1\x3a"
+  "\x87\xf8\xd6\x65\x9d\x03\xda\x02\x4d\x36\xe3\x3a\xc7\x6c\x15\x59"
+  "\xb7\xfd\x6a\x53\x3f\xae\x97\x14\xf4\x23\xfe\xed\xd9\x5f\x17\x77"
+  "\xd5\x4d\xbe\xde\x21\xe9\x26\x38\xc7\x71\xae\x9b\x55\xd5\xcc\x5f"
+  "\xd1\x78\xe7\x68\xc4\x2c\xfe\x0d\xa4\xe0\xd9\x48\xae\x1f\xd5\x1d"
+  "\x60\xe5\xa0\xc8\x42\x59\xff\xff\x46\xc5\xbf\xe5\x83\xbe\xdf\x7f"
+  "\x54\x34\xcd\xb7\xe5\xe0\x18\xe3\x3b\x4f\x7d\x10\x78\x74\x4d\xb8"
+  "\x79\x15\x8e\xdb\x9a\xf0\x46\xf8\xbf\x49\xe6\xbb\x6f\x1e\xdf\x9f"
+  "\x42\xc8\xa4\x14\x6f\xf9\xee\x1b\xb6\xff\x9d\xfe\x23\xfa\x36\xfa"
+  "\x6a\xb4\xaf\xf0\x8f\x68\x3f\xe0\x11\xed\x3c\x7b\x26\xb9\x64\x78"
+  "\x33\x34\xc3\x46\x9b\x74\xa9\xe4\x21\xe8\x57\xfe\x01\x1b\x21\x07"
+  "\xda\x08\x31\x4d\x98\x0d\xf4\x9e\x55\xba\x5d\xb0\xf8\xc2\xfb\x45"
+  "\x83\xfe\xd8\x04\x58\xec\xeb\x8c\xc5\x1c\x77\xab\xd9\x37\x03\xab"
+  "\xe1\xcd\x30\x6c\x2b\xa2\x82\x04\xc2\x7a\xec\x7b\x46\x75\xf8\xf1"
+  "\xc5\x4b\x09\xee\x7f\xf5\x3b\xa3\xaa\xb5\x77\xf6\x1b\x5d\x0a\xf7"
+  "\xf7\xa1\xff\x88\x52\xe9\x9f\x25\x77\xd3\x57\xa3\x54\xe8\xbb\xf0"
+  "\xb1\x50\xac\x16\xe0\x1c\xf7\x85\x2a\x26\x78\x7d\x65\xa7\x2f\x93"
+  "\xd3\x04\xa8\x53\xdd\x56\x4c\x56\x26\xfb\x13\xac\xcf\xfd\xeb\x8a"
+  "\x09\xd6\xcf\x4d\xd4\x30\xdf\x07\x76\x9f\xad\x98\xe0\xbd\x76\x38"
+  "\xff\x3b\x21\x80\xe4\xa5\x06\x91\x03\x95\xd5\xac\x8d\x03\x95\x5f"
+  "\x12\x6c\x03\xe6\x02\xfc\xbf\x87\xac\x4a\xd6\x02\x26\x14\xc3\xf5"
+  "\x6f\xc9\xaa\x73\x03\xe1\x78\x06\x7e\x97\x48\xb3\xaa\xb6\xf8\x40"
+  "\xa5\x40\x02\x97\xfd\x8a\x02\x4f\x53\x13\xee\xa9\x4c\x27\xbd\xa0"
+  "\xef\x1f\x9b\xea\x0c\xa0\xd3\x7e\x63\xc0\x3d\xf7\x34\xe3\xd5\x16"
+  "\x81\xbe\x7a\x56\xc8\x78\xf5\x1c\x3e\xdb\x4e\x5f\xfd\x1e\x9f\x9d"
+  "\x9b\xaa\x13\xfd\x6d\x8b\x99\x6f\xe0\xca\x4b\x83\x09\xf6\x15\x9f"
+  "\x8b\xcf\x5b\x95\x18\x22\x3e\x73\x08\xeb\x1b\x3e\x13\xdb\x74\x7e"
+  "\x26\xe6\xb3\xd7\xbd\x8c\xcf\x3c\x3c\x08\x8e\x7d\x81\x1e\x05\x48"
+  "\x07\x7c\xbe\x40\xa3\xfd\x68\x46\xb4\x0f\xbb\xc7\xda\xe4\xee\x9e"
+  "\x17\xc5\x7b\x98\x2d\x12\xef\xe9\xa0\xac\x3e\x6b\x03\xd6\xca\x39"
+  "\x78\xfe\xe1\x68\x23\xe9\x4a\xc3\x6f\x6f\xe6\x6b\xe7\xe1\x23\x7c"
+  "\xed\xe4\x34\x65\xbc\xf2\x6a\xb4\x1f\xd0\x4d\x83\xeb\x2c\xb4\xf1"
+  "\xa9\xa3\x8d\x7f\x44\xfb\x20\xbd\x91\x6f\x24\x5e\x42\x3e\x92\x78"
+  "\x88\xf5\xd3\x42\x88\x33\xcf\xc0\xff\xfe\x62\x3b\x1d\x52\x3b\xd0"
+  "\x07\x22\xf1\xd1\xc3\x70\xbd\x2b\x1f\xfd\xfd\x2b\x99\x8f\xfe\x3e"
+  "\xdf\x9a\x4e\x29\xf2\x91\xf1\x95\x2c\x68\xe7\xdb\xa7\xe4\xfe\x44"
+  "\xa9\x90\xc7\xfe\xcd\x78\xab\x18\xe9\xf4\x70\x1a\x09\xe2\xef\xf3"
+  "\x77\x96\x0b\xef\xe1\x34\x63\x10\xf6\x55\x7a\x0f\xec\x43\x9e\xa0"
+  "\x23\xd2\x7b\xac\xea\x1c\x0c\xed\x9e\x23\xe2\x3d\xe3\xb0\x6d\x69"
+  "\x0c\x80\x66\x44\xba\x47\xaa\x9f\x27\x84\x40\xbf\x87\xb0\x7b\x38"
+  "\xcf\x9d\x71\xc3\x3f\x7f\xcf\x77\xe5\xb9\x5b\xd2\x08\x08\xc4\x20"
+  "\x6b\xbd\x72\x01\x9f\xb3\x95\xf7\x6d\xaf\xbd\xe3\x1f\xd1\x48\x57"
+  "\xb5\x78\x7e\xbf\x13\x4f\x88\xed\x5b\xdd\xb5\x7f\x5e\xd1\x7e\x34"
+  "\xb4\x9f\x02\xed\xa3\x2c\xf7\x0a\xda\xf0\xea\x58\xfe\x9c\x87\x53"
+  "\x78\xfb\x12\xdf\x52\xc3\x08\xbd\x3e\x15\xfd\x53\xeb\x76\x70\x3c"
+  "\xad\x66\xd8\xc9\xfc\xa2\xd4\x42\xb1\xe0\xe2\x17\xe5\xec\x37\xb7"
+  "\x3d\xdd\x22\xfa\x44\xd5\x31\xdf\x56\xb4\x95\xa1\x4c\xba\x15\xe4"
+  "\x39\xd9\x2f\xea\x28\x5e\xdf\x60\x4c\x6e\x70\xf2\x8b\xaa\x63\xf9"
+  "\xee\xcd\xaa\xba\x8a\x76\x35\x51\x43\x79\x05\x3f\x5f\x4d\x9c\xcf"
+  "\xcb\x7e\x87\xfc\x3c\xfa\x74\x8b\x76\xe3\x96\x7d\x65\x68\x37\xac"
+  "\x33\x4b\xb6\x5a\x0f\xba\xb0\x17\x32\xf3\xa9\x38\x59\x66\x3e\x15"
+  "\xe7\x59\x66\x3e\x92\xdb\xbd\xcc\x6c\xde\x22\xcb\xcc\x27\x6e\xe5"
+  "\xf3\xfe\xf8\x79\x3e\xef\x8f\xb3\xf9\x9d\x07\xed\xd9\x3e\x8c\x23"
+  "\xf4\x0f\xf7\x1b\x90\xcf\x37\x82\x0c\xbc\x3d\xb9\x42\xbd\x15\xf4"
+  "\x6e\xbb\xfa\x1e\xba\x1c\xc6\x0e\xe3\xc1\x2d\x4f\x85\xf5\xdb\x56"
+  "\x4b\xaa\x7d\x51\x66\x46\xff\xb2\xe3\x7d\xab\x5b\xac\x04\xd6\xb9"
+  "\x58\x3e\x2e\x47\xbe\x03\x5a\xf8\x98\xac\x56\xc2\xea\xc1\x35\x58"
+  "\xd7\x1a\x51\x66\xde\x23\x54\xa8\x37\xc2\x98\xc2\xcf\xb7\x2d\x68"
+  "\x46\x8d\xb3\x4c\xdd\x9e\x7d\x54\xeb\x5e\x96\x3e\x56\x69\xcb\x76"
+  "\x96\xa5\x8f\xc6\xa3\x2c\x8d\xf6\x7d\x94\x0f\x04\x2e\x43\x1b\x41"
+  "\x9e\xae\x41\xb9\x1a\x65\x69\x41\x21\x4b\xd7\x8f\xea\x5e\x96\x3e"
+  "\x9a\xff\x7f\xb2\xf4\xf5\x92\xa5\x25\x9b\x82\xab\x2c\x5d\xef\x77"
+  "\x75\xb2\x74\xbd\xef\xff\xc9\xd2\x3f\x35\x59\xfa\x1f\x16\x49\x96"
+  "\x16\xb2\x6e\x7b\x08\x6d\xfc\x1b\x1d\xb2\xf4\xb1\x96\xae\xb2\xf4"
+  "\x71\xd2\x55\x96\x3e\x3a\x44\x96\xa5\x8f\x54\x2a\x65\xe9\xc6\xfe"
+  "\x5d\x65\xe9\xe3\xe1\x9e\x64\x69\xc0\xb1\x16\x94\xa5\x91\xd7\x50"
+  "\xae\x46\x79\x1a\xfa\xde\xc4\xf9\xee\xf8\xd2\xab\x93\xa5\x8f\xa7"
+  "\x5d\x99\x2c\x7d\xfc\x98\x7b\x59\xfa\xc8\x4a\xcf\xb2\xf4\x91\x95"
+  "\xee\x65\x69\xf3\x52\x59\x06\x32\x3f\xff\xd3\x97\xa5\x4f\xb4\xb8"
+  "\x97\x77\x4e\x5c\xe4\xb2\xf4\xf1\xfa\x6b\x2f\x4b\x1f\xaf\x77\x2f"
+  "\x4b\x9b\x67\x72\xb9\xe3\xb8\xb9\xab\x2c\x0d\xf7\xb8\x95\xa5\xcd"
+  "\x1b\xc4\x7b\xea\x95\xb2\x34\x6f\x03\xd6\xd0\x9d\x9e\x65\xe9\x93"
+  "\x93\xf8\x9a\x7a\x32\x98\xaf\xa9\x9c\xa6\x5d\x65\x69\xb3\xbd\x67"
+  "\x59\x9a\xf3\x10\xeb\xa7\x47\x59\xfa\xe4\xb8\xae\xb2\xf4\x91\x95"
+  "\xee\x65\xe9\x53\x83\x64\x3e\x6a\xd8\xad\x94\xa5\x4f\xe6\xfe\x7b"
+  "\xc8\xd2\x1e\x79\xab\x45\x29\x4b\x37\xbc\xe6\xbd\x2c\xdd\x90\xef"
+  "\x9d\x2c\x8d\x3c\xe7\x4e\x96\x6e\x38\xe6\xca\x73\x4a\x59\xba\xa1"
+  "\xc3\xbd\x2c\x7d\xaa\xaf\x52\x96\xc6\xf6\xdd\xc9\xd2\xa7\x9e\x54"
+  "\xb4\xdf\x45\x96\x3e\x35\x59\x29\x4b\xf3\x7a\xb2\x2c\xdd\x28\x7e"
+  "\xbb\x3d\x32\xcc\x7b\x59\xfa\xd4\xc9\xee\x65\xe9\x53\xdf\x29\x65"
+  "\xe9\x53\xbb\xb8\xcc\xdc\x18\xc4\x65\xe9\x53\x35\xfc\xfc\x91\xa1"
+  "\xce\xe7\x65\x59\x9a\x9f\xef\x2a\x4b\x37\x0e\xe9\x41\x96\x0e\xbb"
+  "\x72\x59\xfa\xfb\xd9\x15\x0e\x59\xfa\xfb\xd9\x92\x2c\x8d\xf9\x8c"
+  "\x8a\x40\x3e\x2d\x62\xf2\xf4\x41\x72\xa0\x91\xad\x39\xc7\xba\x97"
+  "\xa7\x5b\x8a\x64\x79\xba\xf9\x2c\x9f\xfb\xcd\x5f\xf1\xb9\xdf\x9c"
+  "\xef\xb0\x41\x83\x2c\x8d\x32\xb5\x68\x83\xae\x5d\x09\xbf\xed\xa9"
+  "\x15\x4c\x9e\x46\x5f\x7d\x94\xa9\x51\x9e\x46\xb9\x1a\x65\xe5\xaa"
+  "\x15\x84\x54\x5b\xac\xe8\xbf\x52\x63\xbc\x1b\xc7\xb5\x79\x29\xc8"
+  "\xe1\x68\x17\xaa\x81\x7b\xcd\xdb\x2f\x58\x71\xdf\x47\x7d\x5e\x03"
+  "\xdc\x63\xe6\xf7\xc0\xf5\x3a\xbc\x07\xea\xd4\x73\x5a\x7c\x77\x84"
+  "\xaf\x9f\x92\x3c\x7e\x7a\xb1\x42\x1e\xe7\x75\x6b\x25\x79\x7c\x03"
+  "\xf4\x01\x7e\xbe\x28\x8b\xa3\x4c\x0e\xb2\x78\xe5\x86\xb5\xb4\x62"
+  "\xe3\x00\x5a\xde\x9e\x7d\x7a\x8b\x24\x93\xe7\xc2\xb9\x3c\x38\x07"
+  "\xfd\xa8\x29\x2f\x26\x64\xf7\x05\x23\xca\x14\xe6\x0d\x67\x88\x2f"
+  "\xd0\xac\x6e\x39\x3c\x1f\xef\x87\x7b\xcc\xd2\x3d\xb0\xbe\x57\x72"
+  "\x19\xfe\xbb\x42\x41\x61\x0f\x3f\xf3\x88\x43\x86\x87\x71\x42\x7b"
+  "\x3b\xe6\x09\x63\x72\x7c\x70\x70\x8d\x4d\x92\xe3\xfb\xff\x3f\xf6"
+  "\xbe\x3f\x2e\x8a\xe3\xfc\x7f\xd8\x03\x45\x45\x39\x0c\x18\x4c\x8d"
+  "\x9e\x09\x18\x4c\x50\xd1\x0a\x9c\xa9\x49\xb1\x51\xa3\xad\x08\x26"
+  "\xda\xa2\xc1\x88\x0a\x06\x8c\x3f\x50\xd1\x9c\x06\xf9\x61\x35\x55"
+  "\x83\x08\x06\xac\x3f\x40\x4c\xaa\xa9\x26\x6a\x48\xaa\xdf\x6a\x3e"
+  "\x9a\x60\xab\x0d\x1a\x7e\x99\x6a\x8b\xa9\x36\x17\x8b\x06\x0d\xea"
+  "\xa9\x28\x07\xdc\xdd\x7e\x9f\xd9\xd9\x73\x77\xef\x76\x8f\xdb\x3d"
+  "\xa0\x68\xfd\xe3\x5e\xe8\xee\xec\xec\xce\xf3\xbc\xe7\x99\xf7\x7b"
+  "\x76\xe6\x59\x3e\x8f\xaf\x75\xb3\xf2\x78\xbc\xdf\xea\x3e\x8f\x4f"
+  "\xb1\xf2\xf8\x2b\x53\x15\xf2\xf8\xb3\x1d\x85\xc7\x7b\xb9\xb9\xb9"
+  "\x7b\xc5\x11\x1e\x5f\xb0\xac\x75\x78\x3c\xe6\xf0\x98\xb7\x63\x0e"
+  "\x8f\x39\x3d\xe6\xf1\x98\xd3\x5b\x58\x1e\xbf\xc3\x86\xc7\x5b\x80"
+  "\xb3\xdb\xf2\x78\xcc\xed\xad\x3c\xde\x22\xe0\xf1\x3f\x94\x2b\xe3"
+  "\xf1\x3f\x94\xb5\x02\x8f\x6f\x1f\xbf\x75\x20\x1e\x1f\x64\xc3\xe3"
+  "\x31\x6f\x87\x3e\x59\x83\xf9\x7c\x65\x09\xd8\x66\x11\x70\x7a\xe0"
+  "\xf3\xca\xb9\xfc\x0f\x87\xf9\x5c\x7e\x47\x4f\x3e\x97\xbf\x7a\xd8"
+  "\x9e\xcb\x5f\x2d\xe3\x71\xf9\x32\xbd\xdb\x65\xe6\x9b\x95\xd0\xa7"
+  "\xab\x4b\x66\x61\x9e\x7e\x39\x56\xc8\xe5\x0d\x4f\xda\x73\xf9\x6b"
+  "\xbd\x45\xb9\x3c\xd1\xf7\x42\x2e\xef\x17\x59\x63\xba\xcf\xe5\xaf"
+  "\x8d\x57\xc6\xe5\xaf\x8d\xe3\xb4\xc6\xe5\x20\x32\x1e\x5d\xad\x95"
+  "\xe2\xf7\x0d\x6a\x3e\xbf\xbf\x76\x8c\xe3\xf7\x29\x3c\x7e\x5f\x73"
+  "\x41\x9a\xdf\xd7\x90\xdc\x96\xea\x37\x23\x70\x5d\x98\x97\x41\x6c"
+  "\xad\xd1\x2c\xc6\xdc\xac\x6e\x3e\xe6\x66\x10\xcf\x6a\xf0\x9a\x71"
+  "\xf8\xff\x08\x2b\xcf\x67\x74\x2a\xe6\xfa\x2b\x3a\x22\x1f\xfb\xb1"
+  "\x5a\x9c\x8f\xfd\x78\x19\xf3\x1e\xb2\x1f\xf7\xda\x51\xb0\x49\x4d"
+  "\xeb\xf2\xfd\x6b\x47\xc5\xf9\x7e\xdd\x54\xc2\x8d\xae\x95\x60\xbf"
+  "\x08\xf9\x3e\x5c\x23\xca\xf7\xeb\x36\xb0\xd7\x1c\x15\xf2\x7d\x52"
+  "\x07\x8c\xf1\x7b\xa5\xf9\xfe\xf5\x31\x64\xcc\xbf\xee\x47\xc6\x7c"
+  "\xe2\x63\x7b\xbe\x5f\x77\x9d\xcf\xf7\xb1\xff\xed\xf9\x3e\xc1\x14"
+  "\xf3\x9c\x92\x7c\xff\x7a\xa8\x3d\xdf\xaf\xb9\x80\xf9\xbe\x89\x87"
+  "\xab\x02\x8c\xab\x59\x18\x57\x37\x03\x31\xae\xf0\xb8\xaa\x99\x83"
+  "\x71\x75\xe3\xa4\xd1\x62\xe5\xfd\xeb\x71\x7d\x6b\x6c\x79\x3f\x8e"
+  "\x23\x8e\x70\x96\xbc\x18\xf5\xc5\x58\xc3\x38\xb3\xfa\x0d\x97\xc7"
+  "\x78\x6b\x5b\xac\xdd\x18\x2d\x8e\xb5\x1b\x93\x18\x3f\xb3\x58\xc3"
+  "\xf3\x95\x44\x07\xe0\xf6\xdd\x48\x90\xa7\x03\x98\x6b\xb6\xca\xd3"
+  "\x01\x18\x8b\x62\x3a\xe0\xc6\x65\x5b\x2c\x0a\x75\xc0\x4d\x37\x71"
+  "\x1d\x70\xb3\xb7\x50\x07\xe0\xfa\xc5\x74\xc0\xcd\x31\x82\xfa\xed"
+  "\x74\xc0\xcd\x99\x42\x1d\x40\xca\x71\x3a\xc0\xe0\xc9\xce\xab\x64"
+  "\xca\xd7\x01\x37\xaf\xb2\xf1\x9d\xe8\x80\x4b\xb6\x3a\xe0\xe6\x2d"
+  "\xa1\x0e\xb8\x79\x82\xc4\x57\x43\x1f\x23\xa3\x03\x6e\x56\x93\xe3"
+  "\x35\x19\xfc\xe3\x9c\x0e\x20\xc7\x8d\x7c\x1d\x50\x82\x75\x80\x61"
+  "\x78\x0b\x3a\x20\xda\x79\x1d\xd0\x5c\xc3\xe9\x80\xe6\x1a\xc7\x3a"
+  "\xc0\x70\xd9\xb1\x0e\x68\xd4\x70\x3a\xa0\x61\x11\x89\x09\x0d\x53"
+  "\x48\x4c\x68\x60\xe6\xad\xa0\x5f\x71\xf3\xea\x8b\x98\xf5\xe7\xa5"
+  "\x07\x6e\x97\x52\x9f\x2c\x66\xe7\xd5\xef\x81\x06\x58\x06\x7c\xbe"
+  "\x9e\xf0\x79\x88\x99\x27\xb0\x0e\xc0\x7c\x9d\x68\x80\x06\x37\x38"
+  "\xa6\x07\x9b\x9f\x80\xba\xf4\xfb\x56\x94\x50\x78\x6d\x18\x2e\x0b"
+  "\xfd\xbd\x3a\x0b\xc6\x11\x38\x5e\x0d\x65\x4a\xf0\x35\x70\xec\x6c"
+  "\xc9\x62\x7c\xdd\xbd\xeb\x58\x2b\xc0\x75\x25\x70\xfe\x82\xcd\x75"
+  "\x55\xf8\xba\x0a\x1d\xa3\x05\xaa\x88\xef\xee\x45\xc2\xf1\x32\x4e"
+  "\x37\xdc\xfa\x94\xd1\x0d\xf5\xac\x6e\x80\xb2\x50\x57\x29\xa3\x1b"
+  "\x66\x81\x6e\x80\xe7\x86\x1f\x5f\x37\x1c\x05\xdd\x70\x18\x74\xce"
+  "\xc1\x86\x77\x6e\xd5\xf0\x74\xc3\x61\xac\x13\xb0\x66\xc0\x5a\x01"
+  "\xc6\xb5\x83\x58\x47\x1c\x6b\xd2\x53\xe0\xe3\xb3\xa0\x1b\xaa\xf1"
+  "\xf5\xdc\xb5\xb7\x35\xfc\x6b\x71\x79\x78\xc6\x12\x46\x73\x00\xcf"
+  "\x83\x67\xb8\x50\x78\x89\xd1\x1c\x65\x70\x6d\x15\xd1\x1c\xb7\x27"
+  "\xf3\x34\xc7\x51\xa2\x39\xee\x79\x09\xdf\x1b\xdc\x7e\x5f\xbe\xe6"
+  "\xa8\x5f\xea\xf8\xdd\xc1\xed\x72\x39\x9a\x03\xda\x5d\x6a\xe5\xaf"
+  "\x76\xeb\x10\xf1\x1a\x7c\xe0\xb0\x98\xaf\x3a\x5c\xb7\xc6\x72\x59"
+  "\xcc\x5d\x31\x6f\xc5\xfc\xd5\x29\xcd\x01\xcf\x5f\x66\x6c\xc5\x77"
+  "\x07\x9d\x40\x73\x2c\x93\xd6\x1c\x7c\xbd\x81\xf5\x07\xd6\x1c\xd0"
+  "\xc7\x18\xcd\x51\xb0\xca\x46\x73\x74\x6a\x41\x73\xb8\xf1\x35\x47"
+  "\xfd\x28\x65\x9a\xa3\x3e\xa2\x15\x34\x47\xe9\x23\xcd\xd1\xda\x9a"
+  "\xa3\x3e\xf8\xbe\xe6\xa0\xd8\xf7\x07\x3d\xad\x9a\xe3\x5e\xb0\xbd"
+  "\xe6\xb8\x17\xc1\xd3\x1c\x47\xf5\x6e\xb7\x99\xf7\xa2\x44\x6f\xdc"
+  "\xca\x13\xea\x0d\x53\xbe\xbd\xde\xb8\xb7\x4e\x99\xde\xb8\x77\x44"
+  "\x99\xde\xb8\x77\x98\x3c\x1f\x7e\x57\x7a\x2b\x9e\x8c\x7b\xf7\x62"
+  "\x38\x0d\x72\x2b\x98\x7f\xac\x65\x0d\xd2\x30\x4a\x5c\x83\x18\x6a"
+  "\xa4\x35\x88\xa1\x46\x5a\x83\x18\x6f\x61\xae\x88\xf5\x06\xd4\x0f"
+  "\x5c\xd1\x78\x8c\xff\xae\x21\xab\x05\x5e\x68\xab\x3f\x92\x67\x11"
+  "\xbd\xd2\xf6\xbc\xd0\x18\x2b\xce\x0b\x8d\x49\x98\x73\x99\x18\x5e"
+  "\xd8\x10\x51\xd0\xea\x1a\xa4\x21\x42\x5c\x83\x18\xd9\xf9\xdf\x86"
+  "\xd1\xf6\x1a\x04\xae\x11\xd5\x20\x8d\x3e\xec\x35\x11\x42\x0d\x42"
+  "\xea\x00\x7e\x31\x48\x5a\x83\x34\x9e\x22\x7c\xa3\x71\x2b\xe1\x1b"
+  "\xc4\xc7\xf6\x1a\xa4\x71\x51\xcb\x1a\x84\x60\x8a\x79\x4e\x49\x0d"
+  "\xd2\x78\xff\xfd\x07\xa7\x41\x0c\x35\x58\x83\x88\xe3\xaa\xb9\x50"
+  "\x88\xab\xe6\x17\x84\x1a\xa4\xa9\x8b\xad\x06\x79\x00\xb1\x16\xcb"
+  "\xbd\x7f\x60\xda\x74\x51\xbe\xee\x68\xf6\x91\xa7\x3b\x30\xfe\xc4"
+  "\x74\x47\xf3\x74\x5b\xfc\x09\x75\x47\xf3\x72\x71\xdd\xd1\x9c\x2b"
+  "\xd4\x1d\xb8\x7e\x31\xdd\xd1\x7c\x4c\x50\xbf\x9d\xee\x68\x3e\x2f"
+  "\xd4\x1d\xa4\x1c\xa7\x3b\x4c\x19\xec\x1c\xd0\x3a\xf9\xba\xc3\x34"
+  "\xd3\xb1\xee\x30\x25\x09\x75\x87\x69\x24\x89\xa9\xa6\x3c\xa2\x3b"
+  "\x4c\xd1\xe4\xb8\x61\x2d\xff\x38\xa7\x3b\xc8\x71\x7b\xdd\x61\xda"
+  "\xd7\x82\xee\xf0\x32\xed\x0a\x2c\x69\x0a\x08\xac\x6a\xca\x8b\x31"
+  "\x3c\x57\xd3\xcf\x7c\xff\xfb\x0b\x71\xc0\x21\x2e\x00\xa7\x98\x89"
+  "\x28\x9c\xc3\x20\xed\x0c\x70\x85\x99\x64\x1f\x03\xe6\x0b\x07\x96"
+  "\x61\xde\x57\xe2\x01\x36\x45\xcd\xbe\xa1\x3b\x4d\xc1\x5a\x3d\xe6"
+  "\x0d\x8d\xbb\x02\x77\x1a\xf3\xc6\x19\x1b\xf1\x1e\x86\x79\x88\x9a"
+  "\x51\x27\xce\x05\xdf\xbe\x40\x5b\x00\xf3\x9e\x51\xb1\x84\x07\x96"
+  "\x27\x5e\x66\x70\x8c\xb9\xc4\x36\xe0\x12\x95\xf5\xd5\x0c\xb7\xf0"
+  "\x8a\xd3\xa0\x82\x34\xe4\xdb\xbd\x0e\xa9\xbb\xbb\xb9\x75\xfa\xd5"
+  "\x54\x84\xcc\xc0\x2b\xc6\x0c\xa4\x2d\xcf\xd6\x68\x70\xce\xa2\x1e"
+  "\x84\x5b\x1c\xf6\x30\xb1\xdc\xe2\xdd\x7b\x28\xb8\x10\xcf\x3f\x97"
+  "\x13\x4e\x81\xbf\xd5\xd0\x48\x38\x45\xdf\xa6\x86\xa0\xa7\xee\xef"
+  "\x61\xb8\xbf\x37\x85\xdb\xc3\xd0\x9c\xcb\xf1\x09\xcc\x25\xe8\x19"
+  "\xc0\x05\x8d\x64\xfd\xc8\x8a\x49\x64\x0f\x43\x70\x0d\xa2\x8a\x5e"
+  "\x47\x9e\x65\x71\x97\xf0\x5c\x91\x7f\x59\xcd\x6e\xb4\x7c\x3c\xea"
+  "\x6b\xc2\xfc\x01\xb8\x61\x59\x4d\x3e\xc2\xf9\x18\x0b\x80\x47\x6c"
+  "\x61\x39\xc4\x84\x99\x12\x1c\x02\xc6\x6a\xcc\x23\xc8\x18\x6d\x99"
+  "\x7e\x32\xe8\x24\x92\xcf\x0d\x2d\x92\xdf\x3f\x65\xd6\x08\xef\x02"
+  "\x7d\x10\x10\xb8\xd3\xec\x1b\x63\x20\xf9\x39\x27\x6a\x2c\x1f\x24"
+  "\xa8\x71\xde\xc5\x8f\x2f\xd5\xba\xe1\x5c\xe3\xf8\xbb\x9b\x96\x7d"
+  "\x5a\xbd\x60\xdf\x49\x33\xeb\xb3\x66\xe2\x33\xcc\x09\xa7\xd7\x21"
+  "\x7a\x86\x89\x42\x70\xae\x07\xb3\xef\xc4\xa8\x47\xdc\xf7\x37\xfd"
+  "\xd1\x0e\x0b\xc9\x71\x69\x79\x3b\xb1\x8b\x05\xfc\x42\xaf\xa2\xd0"
+  "\xfe\x7b\x46\x86\xf7\x65\xe1\x6f\x72\x66\xba\x75\xc7\xbc\x0f\xb0"
+  "\xdf\xb5\xa8\x09\x7c\xf4\x3d\xf1\x11\xbd\xca\x93\xf9\x6b\x7a\x3b"
+  "\x48\x03\x75\x3f\xd5\xdc\x0c\xbc\x8f\xfd\x7e\xa7\x35\xdf\x2f\xb3"
+  "\x87\xa8\x09\xef\x21\xaa\x46\xa6\x5c\x92\x43\x11\x70\xe1\x86\x73"
+  "\x8f\xc0\x33\xf4\x61\xf6\x0e\x35\x07\x61\x1c\xa9\x77\x5c\xc1\xfb"
+  "\x9d\xbe\x65\xfc\x63\x66\xfd\x82\xbf\xe3\x69\xe5\x73\x15\x7b\xce"
+  "\x91\xfd\xa3\x36\xbe\x68\xde\x4d\x78\x3b\xb3\x9f\xe7\x1d\x53\x09"
+  "\x5e\xf7\x73\xc3\x8d\xbe\x7b\x32\x05\xb8\x53\x8a\x5c\xbf\xd0\xf5"
+  "\x1d\xc3\x2f\xea\x87\xcc\x2f\x96\x5d\x8c\x5f\x28\xb7\x0d\x8a\xfc"
+  "\x42\xb9\x39\xde\xff\xdf\x6e\x7e\xf1\x7c\xb8\xfc\xb2\x1e\x62\x1d"
+  "\xe3\x17\x55\xa0\x32\xbf\xa8\x02\x1c\xf9\x05\xcf\x91\x59\xe7\xc7"
+  "\xac\x73\x63\x78\x3c\x65\x74\x11\xd5\xd5\x78\x7f\xad\x29\xfc\x9b"
+  "\xbf\xd6\xf4\xeb\x13\x38\x6f\xc0\x7a\x74\x7a\x34\x8c\x6b\x94\xaa"
+  "\xd1\xe1\x9c\x18\xe5\x19\x71\x7f\x4e\x8c\xea\xf4\x3e\xc3\x51\xa9"
+  "\x4e\x6b\x18\x8e\x4a\x75\x62\xd6\xad\xac\xbc\x88\x28\xd3\x80\x67"
+  "\x0c\x07\x16\x94\x50\x78\x9f\xd6\x81\x1b\x46\x2a\xeb\x36\x70\x4e"
+  "\xaa\x1f\x8d\xe7\xa8\x36\x2c\x06\x6d\x03\x3c\x20\x79\x0e\xea\x77"
+  "\x8d\xf2\x38\x86\x73\xc0\x7d\x71\xa3\x84\xca\xc1\x65\x9e\x4a\x50"
+  "\xef\x7b\xc2\xe0\x86\xc7\xd1\x03\x0b\x8c\x94\x15\x4b\xd6\xfd\x9b"
+  "\x60\xcf\xaa\x3b\xbb\x03\x4b\xf0\x5a\xd0\x26\xbf\x71\x46\xb3\x5f"
+  "\x8c\xc1\xb4\x5f\xab\x17\xc3\x17\xb3\x2f\x14\xc6\x50\xbc\x8f\xf3"
+  "\xf5\x64\x0e\x67\x96\xb7\x09\xbe\x2a\x80\xb3\xe3\xef\x1c\x79\xc3"
+  "\xd8\x49\x37\x27\x76\x79\x6d\x2f\xf8\x9e\xc5\x18\x8c\xdf\xd2\x18"
+  "\xdb\x2a\xc4\xd8\x1d\x16\x63\x80\xb5\xfb\x18\xe3\xed\xeb\x54\x13"
+  "\x8c\xe9\xef\x63\x8c\x19\x3b\xdf\x0e\xea\x83\x71\x66\xc5\x18\x1e"
+  "\x37\x09\xc6\x2e\x49\x62\xec\xeb\x0b\xe2\x18\x33\x05\xf2\x31\xe6"
+  "\x76\x96\x60\xcc\x63\xdd\x49\x18\xf5\xa6\xc4\xca\xc5\x98\xc7\x5a"
+  "\x81\xc6\xa6\xba\xed\xb6\xd3\xd8\x94\xc7\x75\x5b\x8d\x6d\xd5\xd4"
+  "\x77\xfc\x22\xf5\x77\xf2\x23\x6b\xea\xfd\x58\x5d\x4d\x75\xf2\x51"
+  "\xa4\xab\xa9\x4e\x6a\xa7\xd6\xe4\x51\x9d\x16\x9d\x4e\x45\xe8\x34"
+  "\xf4\xa7\xca\x68\xb2\x26\xef\x63\xac\x97\x29\x95\x09\xe3\x50\x54"
+  "\x2f\xb3\xe7\xec\xd6\x52\x51\x9e\x3e\xf7\xd7\x52\x51\x9d\x2f\x36"
+  "\x6e\x12\x5f\x93\xf7\x51\xda\x16\x9e\x76\xd9\x22\xa2\x5d\xb6\xd8"
+  "\xbc\xa7\xdb\x22\xa2\x5b\xb6\x20\x7c\x2d\x5f\xb7\x9c\x8e\x26\xba"
+  "\xe5\x74\x34\xd6\x2d\x5b\x18\xbe\x77\x3a\xda\xaa\x5b\xb6\xc0\x79"
+  "\xa2\x5b\x4e\x47\x5f\x81\x1f\xe8\x16\xaa\x73\xc6\xe9\x68\x11\xdd"
+  "\x42\x75\x5e\xc7\xac\xc9\xa3\x3a\x25\x4b\xaf\xc9\xdb\xc2\xd3\xc7"
+  "\x5b\x78\xfa\x78\x0b\xab\x8f\xb7\x30\xfa\x98\xdc\x33\x98\x79\x36"
+  "\x7c\x4f\x5c\x27\xff\x9e\xf7\xf5\x03\xd5\xd9\xcc\xe8\x07\xaa\x53"
+  "\x0a\xf6\x83\x40\x1f\xe3\x6b\x74\x22\xfa\x98\xf2\x1c\xca\x5e\x93"
+  "\x6c\xd5\xc7\x4d\xa4\x3c\x53\x07\xc4\x9a\x48\x49\x7d\x4c\x79\x5e"
+  "\x25\xb1\xc7\xf3\x08\x89\x3d\xc4\xa7\x76\xfa\x98\xf2\xe4\xeb\x1f"
+  "\xf1\x35\x79\x2c\x86\x98\xe7\x4c\x96\xd0\xc7\x94\xe7\x79\x3b\x7d"
+  "\x4c\xa9\x8c\xa2\x6b\xf2\xa8\xae\x9f\x72\x38\xea\x3a\x49\xb0\x26"
+  "\x8f\xea\xd2\x9f\xaf\x8b\x31\xc6\x1e\x30\x6c\x65\x08\xd6\xe4\x51"
+  "\x5d\x6e\x89\x6b\xe2\x2d\x3c\x4d\xbc\x85\xd1\xc4\xa7\xa3\xd9\x35"
+  "\x79\x54\xd7\x40\x5c\xb7\xbd\x26\xde\x72\xbf\xbc\x55\x13\xe3\x6b"
+  "\x08\xe6\x44\x34\x31\xd5\x75\x91\x2d\xe6\x04\x9a\x98\xea\xba\xc1"
+  "\xaa\x89\x9b\x5e\xe3\x69\x62\xaa\xeb\x6e\x81\x26\x66\xea\x17\xd1"
+  "\xc4\x54\xd7\x33\x82\xfa\x6d\x35\x31\xd5\xf5\xba\x55\x13\xe3\xfa"
+  "\xad\xb8\xbd\xaf\x89\xa9\x6e\x24\x07\x2f\xa5\x7a\x5f\xb6\x26\xa6"
+  "\xba\x31\xf3\x3a\xfb\xb7\x91\x77\x5d\x02\x3d\x4c\x75\x5b\x2e\xd0"
+  "\xc3\x54\xb7\x09\x8c\xee\xa5\xba\xed\x62\xd6\xe3\x51\xdd\xe2\xc8"
+  "\x71\xd5\x4e\xfe\xf1\xfb\x7a\x98\x3d\x8e\xd7\xe3\x31\xeb\xf0\xd6"
+  "\x77\x3b\x28\x4f\x07\x3f\xde\x01\x75\xb0\xbf\x03\x1d\xec\xff\x70"
+  "\xe9\x60\xaa\x7b\x82\x22\x1d\x4c\x75\x8f\xef\x18\xbc\xfe\x21\xd3"
+  "\x5b\xeb\xbb\x95\x12\xce\xd5\xc3\xac\x8c\xd7\xf7\x30\x75\x0c\xbf"
+  "\x3c\x6c\x7a\xab\xfb\x3e\xe2\x17\x75\xbe\x32\xbf\xa8\x25\xf3\x1f"
+  "\xb6\xac\xb7\xfc\x13\x39\xbd\xe5\x9f\x28\xad\xb7\x7c\x92\x1c\xeb"
+  "\x2d\xbf\x62\x4e\x6f\xf9\xfa\x10\xce\xf3\xd8\x5d\xc2\x79\x1e\x3b"
+  "\x24\x5f\x6f\x3d\x36\xe8\x91\xde\x6a\x4d\xbd\xe5\x3d\x9a\x60\xac"
+  "\x67\xa3\x32\xbd\xd5\xd3\x28\xd4\x5b\xbd\xed\xf7\x43\x51\x8f\x4d"
+  "\x77\x5e\x6f\x3d\x96\xa9\x4c\x6f\x3d\x96\xe1\x9c\xde\x7a\xec\x7b"
+  "\x71\xbd\xe5\x33\x4f\x5a\x6f\x91\x73\xf6\x3c\xd9\x2f\x93\xe3\xc9"
+  "\x7e\x91\x1d\x5f\x6f\xf9\x1a\xc4\x39\xb1\x6f\x23\xd1\x5b\x8f\xe9"
+  "\x5b\x5f\x6f\x3d\xa6\x17\xd7\x5b\x7e\xf3\x09\x37\x7d\xac\xc6\x5e"
+  "\x6f\xc1\x35\xa2\x7a\xcb\xef\x7d\xf6\x1a\xbd\x50\x6f\x91\x3a\x20"
+  "\xd6\x1c\x93\xd6\x5b\xbd\xa6\x92\xd8\xd3\x6b\x20\x89\x3d\xc4\xa7"
+  "\xf6\x7a\xab\x97\x5b\xcb\x7a\x8b\x60\x88\x79\x4e\x49\xbd\xd5\x6b"
+  "\xbc\xbd\xde\xf2\x49\x14\xd7\x5b\xfe\xfd\x39\x1c\x3d\x7e\x5c\xa8"
+  "\xb7\x7a\xe5\x3e\x18\x7a\x4b\x12\x5b\x06\xa1\xde\x7a\x7c\xa6\x7c"
+  "\xbd\xf5\x78\xbe\x3c\xbd\x85\x31\x27\xa6\xb7\x1e\xff\xde\x16\x73"
+  "\x42\xbd\xf5\xb8\x59\x5c\x6f\xf9\xfb\x09\xf5\x16\xae\x5f\x4c\x6f"
+  "\xf9\x8f\x12\xd4\x6f\xa7\xb7\xfc\xa7\x0b\xf5\x16\x29\xc7\xe9\xad"
+  "\xde\x64\x0f\x14\xe5\xe3\x23\x5f\x6f\xf9\x7f\x2f\xad\xb7\xfc\x85"
+  "\xfb\x9f\x28\x7f\xb2\xff\x89\xea\x4d\xf6\x3f\x51\xfe\x64\xff\x13"
+  "\xe5\xa3\xe6\x1f\xe7\xf4\x16\x39\xce\xe9\xad\xde\x01\xf2\xf4\x96"
+  "\x77\x07\xd4\x5b\x6a\x07\x7a\x4b\xfd\x90\xe9\xad\x27\xce\x29\xd3"
+  "\x5b\x4f\x9c\x7d\xc4\xeb\xdb\x82\xd7\xf7\xd6\x12\xce\xd5\x67\xbe"
+  "\x32\x5e\xdf\x67\x9e\x72\x5e\x1f\x10\xc1\xf1\xfa\x80\x08\x69\x5e"
+  "\xff\xe4\x28\xc7\xbc\xbe\xff\x5a\x8e\xd7\xf7\x63\xe7\x32\xfb\x95"
+  "\x93\xb1\xb5\xdf\x06\xf9\xbc\xbe\x9f\xc7\x23\x5e\xdf\x9a\xbc\xfe"
+  "\x27\x7d\x08\xc6\xfa\x9e\x51\xc6\xeb\xfb\x56\x09\x79\x7d\xc0\x75"
+  "\x7b\x5e\xdf\x2f\xd4\x79\x5e\xdf\x6f\xaa\x32\x5e\xdf\x4f\x72\xdd"
+  "\xa1\x90\xd7\xf7\x3b\x22\xce\xeb\x9f\x1c\x2d\xcd\xeb\xc9\x39\x7b"
+  "\x3e\xd6\x7f\x2a\xc7\xc7\xfa\x07\x76\x7c\x5e\xaf\x29\x15\xe7\x5e"
+  "\x9a\x33\x84\xd7\xf7\x3b\xdc\xfa\xbc\xbe\xdf\x61\x71\x5e\xdf\x9f"
+  "\xec\xff\xa0\xfa\x1d\xb5\xe7\xf5\x70\x8d\x28\xaf\xef\xbf\x9c\xbd"
+  "\xe6\xb0\x90\xd7\x93\x3a\x20\xd6\xe4\x4b\xf3\xfa\xa7\x86\x92\xd8"
+  "\xf3\x94\x1b\x89\x3d\xc4\xa7\xf6\xbc\xbe\xff\xf9\x96\x79\x3d\xc1"
+  "\x10\xf3\x9c\x92\xbc\xfe\xa9\xfe\xf6\xbc\xfe\xc9\x08\x71\x5e\xff"
+  "\x74\x23\x87\xa3\xa7\xb7\x0a\x79\xfd\x53\x49\x0f\x06\xaf\x97\xc4"
+  "\x56\xa9\x90\xd7\x3f\x3d\x42\x3e\xaf\x7f\x7a\xbe\x3c\x5e\x8f\x31"
+  "\x27\xc6\xeb\x9f\x3e\x62\x8b\x39\x21\xaf\x7f\xfa\x9c\x38\xaf\x7f"
+  "\xfa\xba\x90\xd7\xe3\xfa\xc5\x78\x7d\x40\x6f\x41\xfd\x76\xbc\x3e"
+  "\x20\x54\xc8\xeb\x49\x39\x8e\xd7\x07\x54\x93\x18\xda\xe7\xaa\x7c"
+  "\x5e\x1f\x70\x44\x9a\xd7\x07\x1c\x17\xf2\xfa\x80\x3c\xc2\xdf\x03"
+  "\xea\x08\xaf\x0f\xd8\x43\x8e\xf7\xa9\xe5\x1f\xe7\x78\x3d\x39\xce"
+  "\xf1\xfa\x00\x93\x3c\x5e\xdf\xb9\x03\xf2\x7a\x4f\x07\xbc\xde\xf3"
+  "\x21\xe3\xf5\x03\xf6\x2b\xe3\xf5\x03\xf6\x29\xe7\x8f\x83\x33\x38"
+  "\xfe\x38\x38\x43\x9a\x3f\x3e\x93\xe9\x98\x3f\x3e\x57\xca\xf1\xc7"
+  "\x67\x07\x92\x18\xfe\x6c\x77\x12\xc3\x07\x96\xcb\xe7\x8f\x03\xc7"
+  "\x3c\xe2\x8f\xad\xc9\x1f\x03\xd5\x84\x3f\x0e\xf4\x51\xc6\x1f\x07"
+  "\xaa\x85\xfc\x71\xc8\x20\x7b\xfe\x38\x70\xa9\xf3\xfc\x71\xe0\x56"
+  "\x65\xfc\x71\xe0\x16\xe7\xf8\xe3\xc0\x46\x71\xfe\xf8\xcc\x6a\x69"
+  "\xfe\x48\xce\xd9\x8f\xfb\xcf\x6d\xe5\xc6\xfd\xe7\x12\x3a\x3e\x7f"
+  "\x7c\xce\x53\x7c\x8c\x7f\xce\x87\xf0\xc7\x81\xc6\xd6\xe7\x8f\x03"
+  "\x8d\xe2\xfc\xf1\xb9\x35\x64\xac\x1d\x68\xb2\xe7\x8f\x70\x8d\x28"
+  "\x7f\x7c\x8e\x1d\xff\x07\x1a\x85\xfc\x91\xd4\x01\xb1\xe6\x9c\x34"
+  "\x7f\x0c\x26\xfb\x62\xa9\xe0\x51\x24\xf6\x10\x9f\xda\xf3\xc7\xe0"
+  "\xde\x2d\xf3\x47\x82\x21\xe6\x39\x25\xf9\x63\xf0\x4c\x7b\xfe\xf8"
+  "\x4c\x86\x38\x7f\x1c\x3c\x82\xc3\xd1\xa0\xf3\x42\xfe\x18\xbc\xf7"
+  "\xc1\xe0\x8f\x92\xd8\xf2\x14\xf2\xc7\x41\xcb\xe5\xf3\xc7\x41\xfb"
+  "\xe5\xf1\x47\x8c\x39\x31\xfe\x38\xa8\xd1\x16\x73\x42\xfe\x38\xd8"
+  "\x4f\x9c\x3f\x0e\x1e\x24\xe4\x8f\xb8\x7e\x31\xfe\x38\x78\xaa\xa0"
+  "\x7e\x3b\xfe\x38\x78\xa9\x90\x3f\x92\x72\x1c\x7f\x1c\xe2\x4f\x62"
+  "\xe8\x33\x03\xe5\xf3\xc7\xc1\x8d\xd2\xfc\x71\x88\x9b\x90\x3f\x0e"
+  "\x3e\x4b\x78\xe2\x90\x60\xc2\x1f\x07\xd7\x92\xe3\xcf\x04\xf1\x8f"
+  "\x73\xfc\x91\x1c\xe7\xf8\xe3\x90\x91\x2d\xf1\x47\xc7\xdc\x22\xcc"
+  "\xc0\x71\x8b\x30\x03\x9f\x5b\x9c\x12\x70\x8b\x21\x8e\xf3\x5f\x51"
+  "\xc3\xb5\x1c\xb7\x18\xb6\x95\xf4\xef\x61\x2b\x49\xff\x1e\xf6\x02"
+  "\xc3\x2d\x22\x81\x03\x00\xb7\xd8\x7f\xad\x98\x70\x8b\x6b\x46\xea"
+  "\xdd\x1b\x2c\xb7\xa8\x43\x9e\x59\x0b\x58\x6e\xf1\x3a\xe6\x16\x43"
+  "\x0f\x61\x6e\xe1\x55\x00\xfc\xb6\x86\xe5\xbb\xc9\xc0\x77\x6b\xe0"
+  "\xff\xd0\x77\xbe\x80\x3a\x2a\x80\x93\xe6\xe0\xeb\xf1\x77\x40\xa0"
+  "\x2e\x66\x6f\x2d\xb3\xef\x56\xef\xa1\x99\x45\xf6\xec\xe2\xef\xb8"
+  "\x48\x7d\xc3\xc5\xfa\xfd\x96\xd4\x1a\xda\x82\xbf\xd7\x12\x15\xcf"
+  "\xfb\x8e\x0b\xfe\x3e\xab\xa1\x16\xe1\x6f\xb9\x14\x2c\x46\xbe\xdb"
+  "\x31\xd7\xa8\x45\xea\x1e\x99\x6e\x3d\xf0\x77\x5c\x7a\xd4\x13\x4e"
+  "\xbb\xdf\x52\x4a\x38\xed\x12\xff\xae\xc0\x93\x82\x77\xdc\xe6\x38"
+  "\xc6\x7b\x98\x5f\x2c\x09\xd2\xd4\x2f\x09\xea\x7b\xe7\x0e\x70\x5a"
+  "\x83\xed\x77\x3e\x0e\xc6\xe0\x6f\x49\xe0\xef\x69\x9a\x58\x4e\x4b"
+  "\xbf\x11\x84\x8a\xe6\x00\xef\xa9\x43\x6e\x83\xf1\x37\x3e\xca\x91"
+  "\xfa\x99\x3e\x10\xf7\xef\x04\xf5\xe1\xe7\xe7\xc4\xf3\xa2\x96\x3b"
+  "\x41\xa8\x2c\xee\x5b\x66\x9f\xad\xc9\xba\xcf\xf6\x36\xd2\x1a\x96"
+  "\x04\x51\xdb\x16\xf3\x38\xad\x1f\xe6\xb4\xcf\x3b\xe0\xb4\x43\x33"
+  "\x95\x71\xda\xa1\x19\x42\xbe\x11\x5e\x68\xcf\x37\x86\x5e\x76\x9e"
+  "\x6f\x0c\xeb\xa2\x8c\x6f\x0c\xf3\x74\x8e\x6f\x0c\x4b\xb2\xe5\x1b"
+  "\x7b\x19\xbe\x31\x44\x8f\xb1\x29\xce\x37\xc8\x39\xfb\x71\x62\x78"
+  "\x17\x6e\x9c\xf8\xe9\xb9\x8e\xcf\x37\x7e\xaa\x13\x1f\x13\x7e\x9a"
+  "\x49\xf8\xc6\xb0\xc4\xd6\xe7\x1b\xc3\x12\xc5\xf9\xc6\x4f\xef\x92"
+  "\xd8\x3c\x6c\x9e\x3d\xdf\x80\x6b\x44\xf9\xc6\xf0\x81\xec\x35\x89"
+  "\x42\xbe\x41\xea\x80\xf8\x33\x46\x9a\x6f\x0c\xff\x9e\xc4\xa3\xe1"
+  "\x9f\x92\x78\x44\x7c\x6a\xcf\x37\x86\xaf\x6b\x99\x6f\x10\x0c\x31"
+  "\xcf\x29\xc9\x37\x86\x9f\xb1\xe7\x1b\x43\x2e\x88\xf3\x8d\xb0\xbd"
+  "\x1c\x8e\xc2\xc6\x0b\xf9\x46\x68\xef\x07\x83\x6f\x48\x62\x4b\x27"
+  "\xe4\x1b\xa1\x57\xe5\xf3\x8d\xb0\x27\xe5\xf1\x0d\x8c\x39\x31\xbe"
+  "\x11\x96\x64\x8b\x39\x21\xdf\x08\x5b\x23\xce\x37\xc2\x0a\x85\x7c"
+  "\x03\xd7\x2f\xc6\x37\xc2\x4e\x09\xea\xb7\xe3\x1b\x61\x97\x85\x7c"
+  "\x83\x94\xe3\xf8\x46\xf8\x5a\x56\xb3\xad\x91\xcf\x37\xc2\x93\xa4"
+  "\xf9\x46\xf8\x22\x21\xdf\x08\x1f\x4d\x78\x45\x78\x01\xe1\x1b\xe1"
+  "\x31\xe4\xf8\x90\xd5\xfc\xe3\x1c\xdf\x20\xc7\x39\xbe\x11\xfe\x68"
+  "\xff\xeb\x03\x35\x5f\x35\x42\xd9\xfe\x57\x6a\xc4\xa3\xfd\xaf\x6d"
+  "\xf2\x1e\x3a\x9c\xec\x7f\xa5\x9e\x57\xb6\xff\x95\x7a\xfe\xd1\xfe"
+  "\xd7\x36\xf1\xcb\x08\x76\xff\xeb\x48\x85\xfb\x5f\x47\x3e\xda\xff"
+  "\xda\x26\x7e\xf9\x19\xbb\xff\xf5\x45\x85\xfb\x5f\x5f\x74\x61\xff"
+  "\xeb\x58\x5f\x4e\x1b\x8f\xf5\x95\xd6\xc6\x2f\xb6\xb0\xff\xf5\xa5"
+  "\x58\x4e\x1b\x8f\x3a\x46\xb8\xe8\xa8\xf7\x09\x17\x1d\xc5\xcc\x4d"
+  "\xa5\x61\x6d\xfc\x41\x3c\xfa\x64\xf1\x61\x0a\xe7\x85\xc3\xdf\xc6"
+  "\xdc\xb0\x02\xb9\x9b\xb0\x36\x06\x1f\x6c\x68\xc2\xda\xf8\x04\x4a"
+  "\x9e\x8b\xb5\x71\xc4\xf9\x8a\x1a\xde\xf7\x55\xa8\x9f\x8f\xe7\xf2"
+  "\x39\x9f\x40\xf8\xdc\x17\xb7\x0f\x53\x39\x4d\x36\x73\xf2\x8b\x8d"
+  "\x94\x66\x81\x70\x4e\xde\x9c\x1f\x63\xc0\x73\xf2\x8d\xec\xb7\x52"
+  "\x98\x79\xf9\x41\x8e\xe7\xe4\x0b\x9b\x60\xec\x14\x99\x97\xc7\x73"
+  "\xf2\x30\x46\x3e\x64\x73\xf2\x23\xd9\xbd\xb1\x11\xbb\x95\xcd\xc9"
+  "\x47\xec\x12\x6a\xe4\xb1\xc7\xed\x35\xf2\xa8\x2e\xce\x6b\xe4\x51"
+  "\x83\x94\x69\xe4\x51\xc1\xce\x69\xe4\x51\x1b\xc4\x35\xf2\x8b\xa6"
+  "\x34\x49\x8d\x4c\xce\xd9\x6b\x9b\x97\x06\x71\xda\xe6\x17\x8d\x1d"
+  "\x5f\x23\xff\xa2\x40\x5c\xc7\xfc\x62\x37\xd1\xc8\xa3\xb2\x5a\x5f"
+  "\x23\x8f\xca\x12\xd7\xc8\x2f\xb1\xef\xbf\x47\xe5\xd8\x6b\x64\xb8"
+  "\x46\x54\x23\xbf\x14\xc9\x5e\x93\x25\xd4\xc8\xa4\x0e\x88\x43\x49"
+  "\xd2\x1a\x79\xb4\x07\x89\x4b\x2f\x9d\x23\x71\x89\xf8\xd4\x5e\x23"
+  "\xbf\xb4\xbf\x65\x8d\x4c\x30\xc4\x3c\xa7\xa4\x46\x7e\xe9\xae\xbd"
+  "\x46\x7e\x51\x62\x6f\xec\x98\x72\x0e\x47\x63\xe6\x0b\x35\xf2\xe8"
+  "\x17\x1e\x0c\x8d\x2c\x89\xad\x02\xa1\x46\x1e\xd3\x5d\xbe\x46\x1e"
+  "\x33\x4a\x9e\x46\xc6\x98\x13\xd3\xc8\x63\x36\xd8\x62\x4e\xa8\x91"
+  "\xc7\xec\x15\xd7\xc8\x63\x8e\x0b\x35\x32\xae\x5f\x4c\x23\x8f\xb9"
+  "\x2e\xa8\xdf\x4e\x23\x8f\xed\x22\xd4\xc8\xa4\x1c\xa7\x91\xc7\xee"
+  "\x23\x31\xf4\x45\x05\x7b\x63\xc7\x6e\x90\xd6\xc8\x63\xf3\x85\x1a"
+  "\x79\x6c\x22\xd1\xc2\x63\x4b\x88\x46\x1e\x9b\x4a\x8e\xbf\xb8\x93"
+  "\x7f\x9c\xd3\xc8\xe4\x38\xa7\x91\xc7\x56\x3d\xda\x1b\xfb\x20\x69"
+  "\xe4\x71\x0a\xe7\xbf\xc7\x65\x74\x0c\xce\xff\xb0\x69\xb1\xb1\x35"
+  "\x84\x73\xfd\xb2\xb7\x32\xce\xff\x4b\xff\x8e\xe1\x97\x87\x4d\x8b"
+  "\x8d\x63\xf7\x2c\xff\xea\x53\x65\x7e\xf9\x55\xb1\x72\x2d\xf6\xea"
+  "\x4e\x4e\x8b\xbd\xba\x53\x5a\x8b\x4d\x58\xe3\x58\x8b\x45\xd7\x72"
+  "\x5a\x2c\x6a\x3c\xe1\x3c\x51\x83\x08\xe7\x99\x78\x5d\xbe\x16\x9b"
+  "\x98\x20\xd4\x62\x13\xce\x3d\xd2\x62\x6d\xa5\xc5\x7e\x19\x47\xf0"
+  "\x37\x71\xa8\x32\x2d\x36\x31\x44\xa8\xc5\x26\x47\xda\x6b\xb1\x89"
+  "\xf9\xce\x6b\xb1\x89\xca\xf2\xff\x52\x13\x0f\x3b\xa7\xc5\xa2\x7a"
+  "\x8b\x6b\xb1\x09\x6b\xa5\xb5\x18\x39\x67\xcf\xa1\xa3\x8f\x70\x1c"
+  "\x3a\x7a\x4d\xc7\xd7\x62\xd1\x41\xe2\x7c\x39\x7a\x28\xd1\x62\x51"
+  "\xfe\xad\xaf\xc5\xa2\xfc\xc5\xb5\x58\xf4\x6e\xc2\x5b\xa3\xfa\xd8"
+  "\x6b\x31\xb8\x46\x54\x8b\x45\x9f\x67\xaf\xf1\x17\x6a\x31\x52\x07"
+  "\xc4\xa1\xbb\xd2\x5a\x6c\x52\x2e\x89\x4b\x93\x66\x92\xb8\x44\x7c"
+  "\x6a\xaf\xc5\x26\x8d\x68\x59\x8b\x11\x0c\x31\xcf\x29\xa9\xc5\x26"
+  "\x65\xda\x6b\xb1\x09\xab\xc5\xb5\xd8\xab\xbc\x7d\x1a\xaf\x34\x0a"
+  "\xb5\xd8\xa4\x53\x0f\x86\x16\x93\xc4\x56\x90\x50\x8b\xbd\xb2\x55"
+  "\xbe\x16\x7b\xa5\x5c\x9e\x16\xc3\x98\x13\xd3\x62\xaf\xf6\xb6\xc5"
+  "\x9c\x50\x8b\xbd\x1a\x2a\xae\xc5\x5e\x8d\x14\x6a\x31\x5c\xbf\x98"
+  "\x16\x7b\x75\xb9\xa0\x7e\x3b\x2d\xf6\x6a\xbe\x50\x8b\x91\x72\x9c"
+  "\x16\x9b\xac\x65\xc7\xbb\x41\xf2\xb5\xd8\xe4\xde\xd2\x5a\x6c\x72"
+  "\x7f\xa1\x16\x7b\xb5\x9e\x68\xae\xc9\x13\x88\x16\x9b\xcc\x1e\x9f"
+  "\x10\xcc\x3f\xce\x69\x31\x72\x9c\xd3\x62\x93\x63\x1f\xed\x9b\x7d"
+  "\x90\xb4\xd8\xaf\xbb\x2b\xd3\x62\xbf\xf6\x7a\xc4\xf9\xdb\x82\xf3"
+  "\x4f\x4e\x26\x9c\xeb\x37\xbb\x95\x71\xfe\xdf\xec\x52\xce\xf9\x67"
+  "\xe4\x71\x9c\x7f\x46\x9e\x34\xe7\x8f\x59\xee\x98\xf3\xc7\x5e\xe0"
+  "\x38\xff\x6b\x2f\x90\xb1\xf5\xb5\xfe\x64\x6c\x9d\xf6\xbd\x7c\xce"
+  "\x3f\x6d\xaa\x90\xf3\xc7\x9c\x7a\xc4\xf9\xdb\x8a\xf3\xff\x7a\x32"
+  "\xc1\xdf\xb4\x40\x65\x9c\x7f\x5a\x80\x90\xf3\xc7\x8d\xb2\xe7\xfc"
+  "\xd3\xec\xbe\xff\x21\xcd\xf9\xa7\xed\x57\xc6\xf9\xa7\xed\x73\x8e"
+  "\xf3\xbf\xd6\x5d\x9c\xf3\xc7\xa4\x4a\x73\x7e\x72\xce\x9e\xab\xc5"
+  "\xee\xe7\xb8\x5a\xec\xf2\x8e\xcf\xf9\x63\xfb\x88\xf3\xb2\xd8\x40"
+  "\xc2\xf9\x5f\xf3\x6a\x7d\xce\xff\x9a\x97\x38\xe7\x8f\xdd\x4a\xf8"
+  "\xd1\x6b\x6a\x7b\xce\x0f\xd7\x88\x72\xfe\xd8\x72\xf6\x1a\x2f\x21"
+  "\xe7\x27\x75\x40\x1c\xba\x2a\xcd\xf9\xa7\xaf\x21\x71\x69\x3a\xf9"
+  "\x56\x18\xeb\x53\x7b\xce\x3f\x7d\x50\xcb\x9c\x9f\x60\x88\x79\x4e"
+  "\x49\xce\x3f\x7d\xa9\x3d\xe7\x8f\xd1\x89\x73\xfe\x19\x91\x1c\x8e"
+  "\x5e\xbf\x2e\xe4\xfc\xd3\x8f\x3d\x18\x9c\x5f\x12\x5b\x7d\x84\x9c"
+  "\xff\xf5\x0d\xf2\x39\xff\xeb\xc7\xe5\x71\x7e\x8c\x39\x31\xce\x3f"
+  "\xa3\xbb\x2d\xe6\x84\x9c\x7f\xc6\x40\x71\xce\x3f\x63\x94\x90\xf3"
+  "\xe3\xfa\xc5\x38\xff\x8c\xf9\x82\xfa\xed\x38\xff\x8c\x75\x42\xce"
+  "\x4f\xca\x71\x9c\x3f\x2e\x98\x1d\xef\xfa\xcb\xe7\xfc\x71\xdd\xa5"
+  "\x39\x7f\x9c\x9f\x90\xf3\xcf\x60\xf7\xce\xc6\x45\x10\xce\x3f\xc3"
+  "\x44\x8e\xc7\x68\xf8\xc7\x39\xce\x4f\x8e\x73\x9c\x3f\x2e\xfa\xd1"
+  "\x9e\xda\x07\x89\xf3\xcf\x72\x53\xc6\xf9\x67\x21\xe5\xdc\x32\x89"
+  "\xb7\xef\x25\xc9\xc1\xbe\x97\x59\xe7\x1c\x73\xcb\x37\x78\xfb\x5e"
+  "\x12\xd8\x7d\x2f\x09\xec\xbe\x97\x84\x17\xe4\x73\xcb\xf8\x43\x42"
+  "\x6e\x39\x3b\xf0\x11\xb7\x6c\x2b\x6e\x19\x17\x4f\xb8\x65\x7c\xa6"
+  "\x32\x6e\x19\x6f\xb3\xff\x65\xae\xc8\xfe\x97\x78\x19\xfb\x5f\x12"
+  "\x14\xee\x7f\x49\x70\x72\xff\x4b\x82\xc4\xfe\x97\x59\xd5\xd2\xdc"
+  "\x92\x9c\xb3\xe7\x04\x6f\xf0\xf6\xbf\xcc\x79\x00\xf6\xbf\xcc\x91"
+  "\xd8\xa3\x30\x87\xdd\xff\x92\xd0\x06\xfb\x5f\x12\x24\xf6\xbf\xcc"
+  "\x61\xf7\xbf\x24\x88\xec\x7f\x49\x90\xd8\xff\xf2\x06\xbb\xff\x25"
+  "\xc1\x66\xff\x4b\x02\xbb\xff\xe5\x0d\x07\xfb\x5f\xde\x60\xf7\xbf"
+  "\xbc\xc1\xee\x7f\x21\x3e\xb5\xe7\x96\x6f\x38\xb1\xff\x25\x81\xdd"
+  "\xff\x92\xe0\x60\xff\xcb\x1b\x22\xfb\x5f\x66\x9d\x15\xe7\x96\x49"
+  "\xbc\xfd\x2f\x49\x36\xfb\x5f\x12\x1f\x90\xfd\x2f\x92\xd8\xb2\xd9"
+  "\xff\x92\xa8\x60\xff\x4b\x92\xcc\xfd\x2f\x09\x12\xfb\x5f\x92\x92"
+  "\x6c\x31\x27\xe4\x96\x49\x12\xfb\x5f\x92\x6c\xf6\xbf\x24\x48\xec"
+  "\x7f\x49\x3a\x25\xa8\xdf\x8e\x5b\x26\xd9\xec\x7f\x49\xb0\xd9\xff"
+  "\x32\x97\xdd\xff\x32\x6b\xa5\x7c\x6e\x39\xd7\xc1\xfe\x97\xb9\x36"
+  "\xfb\x5f\xe6\xb2\xfb\x5f\xe6\xb2\xfb\x5f\xe6\xb2\xfb\x5f\x66\xa5"
+  "\xf2\x8f\x73\xdc\x92\x1c\xe7\xb8\xe5\xdc\x16\xf7\xbf\x38\xe6\x1d"
+  "\x8b\x53\x39\xde\xb1\x38\x55\x9a\x77\xbc\x19\xe9\x98\x77\x2c\x3c"
+  "\xc1\xf1\x8e\x05\x81\xa4\x7f\x2f\xe8\x42\xfa\xf7\x7c\xe6\x3d\xcc"
+  "\xca\x72\xe0\x1d\x4f\xc5\xa3\x03\x37\x8a\x19\xde\xf1\xc9\x02\x23"
+  "\x05\x1c\xd1\xdd\x82\x79\x07\x70\xc1\xac\x65\x98\x77\xd4\xb0\xfb"
+  "\x6d\xe7\x8f\x2a\xd7\xf1\x79\xc7\x9b\xef\x33\x7b\x6f\xef\x7f\xef"
+  "\xb9\x06\xe1\xf3\x62\x7b\x71\x8f\x2d\x60\xf7\xe2\x42\xdd\xfc\x3d"
+  "\xb8\xcc\xbe\xdc\x1b\xc0\x4b\x80\xa6\x59\x78\xbc\xe4\xd1\x5e\x5c"
+  "\x47\x7b\x71\xe7\x2b\x9c\xff\x9e\xef\x25\xe4\x22\x4b\x06\xda\x73"
+  "\x91\xf9\x8b\x9c\xe7\x22\xf3\xf3\x95\x71\x91\xf9\x79\xce\x71\x91"
+  "\xf9\x77\xc5\xb9\xc8\x9b\xd1\x18\xb7\xe2\x5c\x84\x9c\xb3\x1f\x43"
+  "\x16\xe6\x73\x63\xc8\xc2\x99\x1d\x9f\x8b\x2c\x74\x17\x1f\x2f\x16"
+  "\x76\x27\x5c\x64\x7e\x7d\xeb\x73\x91\xf9\xf5\xe2\x5c\x64\x61\x26"
+  "\x89\xdb\xf3\x8d\xf6\x5c\x04\xae\x11\xe5\x22\x0b\x0f\xb1\xd7\xd4"
+  "\x0b\xb9\x08\xa9\x03\x62\xd3\x19\x69\x2e\x92\x3c\x9f\xc4\xaa\xe4"
+  "\x17\x48\xac\x22\x3e\xb5\xe7\x22\xc9\x7e\x2d\x73\x11\x82\x21\xe6"
+  "\x39\x25\xb9\x48\xf2\x74\x7b\x2e\xf2\xe6\x04\x71\x2e\xb2\x38\x94"
+  "\xc3\xd1\xa2\x73\x42\x2e\x92\xbc\xfb\xc1\xe0\x22\x92\xd8\x72\x17"
+  "\x72\x91\x45\x4b\xe5\x73\x91\x45\x7b\xe5\x71\x11\x8c\x39\x31\x2e"
+  "\xb2\xe8\xae\x2d\xe6\x84\x5c\x64\xb1\x8f\x38\x17\x59\x3c\x50\xc8"
+  "\x45\x70\xfd\x62\x5c\x64\xf1\x14\x41\xfd\x76\x5c\x64\xf1\x22\x21"
+  "\x17\x21\xe5\x38\x2e\xb2\xc4\x97\xd5\x73\x77\xe5\x73\x91\xc5\x77"
+  "\xa5\xb9\xc8\x62\xb3\x90\x8b\x2c\xae\x22\x9c\x63\x49\x10\xe1\x22"
+  "\x8b\x6b\x58\x8e\x52\xcf\x3f\xce\x71\x11\x72\x9c\xe3\x22\x4b\xb4"
+  "\x32\xe6\xb9\xea\xe5\xec\xc5\xdd\x7f\x4f\x38\xcf\x65\x9d\xe3\x32"
+  "\x05\x6b\x6b\xee\xcf\x73\xf1\xdf\x93\x8a\xcc\x73\xe1\x31\x9d\x9b"
+  "\xe7\xba\xc8\xc4\x2a\x6e\x9e\x4b\xcf\xcc\x73\xe1\x39\x2e\xfc\xae"
+  "\xd4\x3a\xc7\x65\x79\xcb\x7e\x1f\xee\x7e\x8b\xfc\x39\x2e\xee\x7d"
+  "\xe9\xe1\x2a\x32\xc7\x55\x7d\x7f\x8e\x0b\x8f\xe7\xe6\x06\xfb\x39"
+  "\x2e\x3c\x8e\x73\x73\x5c\xdf\xb6\xf2\x1c\x57\xca\x65\x65\xe3\x7a"
+  "\x4a\x4d\xc7\x78\xaf\xfd\xb0\xed\xc3\x5d\x32\x81\xcc\xfd\x2c\x5b"
+  "\xa9\xec\xbd\xf6\xb2\xd4\x8e\xe1\x97\x87\x6d\xed\xf7\xd2\x60\xe2"
+  "\x17\x9d\x9f\x32\xbf\xe8\x7c\x3b\x86\x5f\x1e\xb6\x75\x20\xcb\x4e"
+  "\x10\xbf\x2c\xdf\xaf\xcc\x2f\xcb\x5d\xc8\x7f\x99\x59\xc2\x69\xe6"
+  "\xcc\x12\xbe\x66\x2e\x1d\xcd\xd7\xcc\x2b\x5a\xc8\x7f\x99\xee\xc9"
+  "\x69\xe6\x95\x49\x84\x87\xae\x8c\x24\x3c\x74\x25\xf3\x7e\x6a\xe5"
+  "\x28\xc4\x68\x65\x13\xd6\xcd\x73\x8d\xd4\x81\x6b\x25\x94\x69\x15"
+  "\xd1\xcb\x95\xa6\x32\x54\x6e\x30\xa2\x77\x97\x21\xf7\x75\x37\x90"
+  "\xfb\x47\xb7\x8d\x94\xf7\x3c\xe4\x09\x63\x12\xd8\xac\x0c\x78\x4c"
+  "\x21\x4a\x4e\xc3\x5a\x3a\x75\x4d\x65\xb2\x81\xa7\xa5\x57\x5c\xe5"
+  "\x74\x34\x94\x4b\x36\xa2\x2f\xe7\x96\x50\x58\x2f\x37\xe7\xc7\x18"
+  "\x9a\x07\x69\xf5\x4c\x1e\x2b\xfe\x7c\x3e\xdc\x5b\xf3\xba\x70\x3e"
+  "\xbf\x29\x3f\xa6\xbe\x71\xbf\xb6\x86\xc9\xa1\x19\xc8\xcd\xe9\xcb"
+  "\xc9\x9f\xb9\xbd\x09\xf9\x5a\xe7\xf3\xb7\x3f\x74\xf3\xf9\xba\x58"
+  "\x82\xd1\xd4\x49\xca\xe6\xf3\x53\xa3\x85\x1a\x7a\xd5\x7c\x7b\x0d"
+  "\x9d\x7a\xc8\x79\x0d\x9d\x7a\x5e\x99\x86\x4e\xad\x76\x4e\x43\xaf"
+  "\x1c\x61\xab\xa1\xf7\xa4\x61\x0d\xbd\x62\x35\xc6\xb1\xb8\x86\x26"
+  "\xe7\xec\xb5\x4f\xda\x79\x4e\xfb\xa4\xed\xee\xf8\x1a\x3a\x6d\x9c"
+  "\xb8\xce\x49\x9b\x44\x34\xf4\x4a\x6d\xeb\x6b\xe8\x95\x5a\x71\x0d"
+  "\x9d\x76\x92\xe8\x8d\x95\x5a\xab\x1e\xe6\x34\x34\x5c\x23\xaa\xa1"
+  "\xd3\x1a\x6d\xaf\x21\x1a\x7a\xe5\x48\xa2\xa1\xd3\xfd\xa4\x35\x74"
+  "\xfa\xa7\x24\x76\xa5\x67\x92\xd8\x45\x7c\x6a\xaf\xa1\xd3\xa7\xb6"
+  "\xac\xa1\x09\x86\x98\xe7\x94\xd4\xd0\xe9\xef\xdb\x6b\xe8\x15\x12"
+  "\xf9\x33\x33\x97\x73\x38\xca\xec\x2d\xd4\xd0\xe9\x57\x1f\x0c\x0d"
+  "\x2d\x89\xad\x71\x42\x0d\x9d\x71\x44\xbe\x86\xce\xb8\x2e\x4f\x43"
+  "\x63\xcc\x89\x69\xe8\xcc\x11\x2c\x7e\x46\x8a\x6b\xe8\xcc\x29\xe2"
+  "\x1a\x3a\x73\xbe\x50\x43\xe3\xfa\xc5\x34\x74\xe6\x56\x41\xfd\x76"
+  "\x1a\x3a\xf3\x90\x50\x43\x93\x72\x9c\x86\x5e\x15\xc3\x8e\x7d\x0a"
+  "\xf2\x67\xae\x1a\x21\xad\xa1\x57\x8d\x12\x6a\xe8\x55\xbe\x44\x2b"
+  "\xaf\x9a\x47\x34\xf4\xaa\x20\x72\x7c\x45\x10\xff\x38\xa7\xa1\x57"
+  "\xd8\xe4\xcf\x5c\x95\x2a\x43\x43\x1b\x5b\x49\x43\xd7\x3e\x58\x1a"
+  "\xfa\xf3\x9c\x8e\xa1\xa1\x57\x0f\x54\xa6\xa1\x57\x07\x39\xa9\x09"
+  "\xea\x5b\xd0\x04\x35\x8f\x34\x01\x9f\x6f\xad\xca\x21\x7c\x6b\xcd"
+  "\x71\x65\x9a\x60\x4d\x49\x47\xf0\xcb\xc3\xe5\x93\xd5\xec\x7a\xfd"
+  "\xdf\x4d\x51\xe6\x93\xdf\x4d\x7e\xa4\x9f\xdb\xc2\x2f\xef\x78\x12"
+  "\xbf\xac\xbd\xae\xcc\x2f\x6b\xeb\x94\xeb\xe7\xdc\x00\x4e\x3f\xe7"
+  "\x06\xf0\xf5\xf3\xdf\x04\xef\x9c\xd7\x1d\x77\xac\x9f\xb3\xe7\x71"
+  "\xfa\x39\xab\x9c\x70\xd0\x2c\x76\x4d\x49\x16\x33\xa7\x0e\xea\x88"
+  "\xd1\xcf\xf7\xb0\x7e\xbe\x02\xfa\x79\x4e\x1c\x65\x62\xbf\x1d\x81"
+  "\xd7\xaf\x95\x83\x06\xc6\x9a\xb9\x52\x07\xff\x4e\x31\xa0\x77\x17"
+  "\x23\xf7\xf5\xa0\x7d\xf7\xc2\x58\xb9\x77\x99\x81\x5a\x3b\x17\xc6"
+  "\x99\xea\xfd\xc8\x3b\x11\x74\xf5\x6d\xac\xab\x4f\x80\x66\x5e\xc3"
+  "\xea\xea\x77\xaf\x56\xa6\xf0\x75\xf5\xfa\x51\x8c\xae\x36\x90\xb5"
+  "\x71\x95\x29\xa0\xab\xe1\x7e\xf8\x5b\x14\x7c\x5d\xdd\x08\xba\xb9"
+  "\x09\x74\x73\xce\x35\x1b\x8d\x3d\xc7\x5e\x63\x37\xfa\xc5\x18\x8d"
+  "\x83\xb4\xb5\x58\x63\xdf\xdb\xfd\x48\x63\xdb\x6b\xec\xdf\x15\x10"
+  "\x1c\xbf\x7b\x48\x99\xc6\x7e\xf7\xa0\x50\x63\xe7\x9e\xb1\xd7\xd8"
+  "\x59\xbd\x9d\xd7\xd8\x59\x2f\x28\xd3\xd8\x59\x23\x9d\xd3\xd8\x59"
+  "\x85\xb6\x1a\xfb\x43\xe6\x3d\xf5\xba\x13\x18\xeb\xe2\x1a\x9b\x9c"
+  "\xb3\xd7\x46\xd9\x2f\x70\xda\x28\xbb\x4b\xc7\xd7\xd8\x1b\xf6\x89"
+  "\xeb\xa0\x0d\x87\x88\xc6\xce\x2a\x68\x7d\x8d\x9d\x55\x20\xae\xb1"
+  "\xb3\xd9\xf5\x6f\x59\x05\xf6\x1a\x1b\xae\x11\xd5\xd8\xd9\xd3\x6d"
+  "\xaf\x21\x1a\x3b\x6b\x27\xd1\xd8\xd9\xcb\xa5\x35\xf6\x46\x3f\x12"
+  "\xdf\xb2\x2f\x93\xf8\x46\x7c\x6a\xaf\xb1\xb3\x8f\xb5\xac\xb1\x09"
+  "\x86\x98\xe7\x94\xd4\xd8\x1b\x3d\xec\x35\xf6\xba\x12\x71\x8d\x9d"
+  "\x73\x91\xc3\x51\xce\x4a\xa1\xc6\xde\x18\xf9\x60\x68\x6c\x49\x6c"
+  "\xed\x13\x6a\xec\x9c\x27\xe5\x6b\xec\x9c\x49\xf2\x34\x36\xc6\x9c"
+  "\x98\xc6\xce\x29\x64\xf1\xb3\x53\x5c\x63\xe7\x1c\x11\xd7\xd8\x39"
+  "\x67\x84\x1a\x1b\xd7\x2f\xa6\xb1\x73\xcc\x82\xfa\xed\x34\x76\x6e"
+  "\x6f\xa1\xc6\x26\xe5\x38\x8d\x9d\x7b\x94\xc4\xd0\x75\x49\xf2\x35"
+  "\x76\x6e\xa1\xb4\xc6\xce\xdd\x2d\xd4\xd8\xb9\x3a\xa2\xa5\x73\xab"
+  "\x88\xc6\xce\xcd\x22\xc7\xd7\x25\xf2\x8f\x73\x1a\x9b\x1c\xe7\x34"
+  "\x76\xae\x5e\xde\x7b\x6a\x97\xf2\x61\xd5\xb4\xff\x7e\x8c\xd6\xca"
+  "\x87\x65\x7d\x57\xfd\xdf\xde\x8f\xf1\x5e\xae\x32\x9d\xfd\x5e\xce"
+  "\x23\x3d\xd7\xda\xba\x21\xb7\x9e\xf0\xad\x7c\x85\xf9\x6f\xf3\x1d"
+  "\xe6\xbf\x7d\xa4\xe7\x94\xfa\xe5\xbd\x6a\xe2\x97\xcd\xc7\x94\xf9"
+  "\x65\xf3\x51\xe5\x7a\x6e\x47\x15\xa7\xe7\x76\x54\x49\xbf\x0f\xfd"
+  "\x7d\xae\x63\x3d\x57\xe0\xcf\xe9\xb9\x6d\xcb\x09\xdf\xd9\x36\x9d"
+  "\xf0\x9d\x6d\x4f\xb6\xde\xfb\xd0\xad\xf9\xc2\xf7\xa1\xbf\x6f\x7c"
+  "\xf4\x3e\xb4\x3d\xb4\x5a\xfe\x3c\x82\xd1\xad\x33\x95\x69\xb5\xad"
+  "\x71\x42\xad\x56\xb4\xd2\x5e\xab\x6d\x3d\xe9\xbc\x56\xdb\x7a\x55"
+  "\x99\x56\xdb\x5a\xeb\x9c\x56\xdb\x36\x5e\xfc\x7d\xe8\xef\xf3\xa4"
+  "\xdf\x87\x92\x73\xf6\x1c\x7b\xfb\x55\x8e\x63\x6f\x3f\xd4\xf1\xb5"
+  "\xda\xf6\x18\x71\x3e\xbd\x7d\x26\xd1\x6a\xdb\xc6\xb5\xbe\x56\xdb"
+  "\x36\x4e\x5c\xab\x6d\x3f\x47\x78\xed\xb6\x71\xf6\x5a\x0d\xae\x11"
+  "\xd5\x6a\x05\x5d\x6c\xaf\x21\x5a\x6d\xdb\x04\xa2\xd5\x0a\x02\xa5"
+  "\xb5\x5a\xc1\x71\x12\xbb\x0a\x72\x49\xec\x22\x3e\xb5\xd7\x6a\x05"
+  "\x49\x2d\x6b\x35\x82\x21\xe6\x39\x25\xb5\x5a\xc1\xa7\xf6\x5a\xed"
+  "\xf7\x39\xe2\x5a\x6d\xc7\x3a\x0e\x47\x3b\x06\x0a\xb5\x5a\x41\xe3"
+  "\x83\xa1\xd5\x24\xb1\x15\x23\xd4\x6a\x85\xa7\xe4\x6b\xb5\x42\xb3"
+  "\x3c\xad\x86\x31\x27\xa6\xd5\x76\x8c\x67\xf1\x33\x41\x5c\xab\xed"
+  "\x48\x10\xd7\x6a\x3b\x56\x0a\xb5\x1a\xae\x5f\x4c\xab\xed\xd8\x2b"
+  "\xa8\xdf\x4e\xab\xed\x38\x29\xd4\x6a\xa4\x1c\xa7\xd5\x8a\x12\xd9"
+  "\xb1\x6f\x84\x7c\xad\x56\x34\x5e\x5a\xab\x15\x4d\x12\x6a\xb5\xa2"
+  "\x00\xa2\xc9\x8a\x52\x89\x56\x2b\xd2\x92\xe3\xbf\xd7\xf2\x8f\x73"
+  "\x5a\x8d\x1c\xe7\xb4\x5a\x51\x96\x3c\xad\xe6\x7c\xbe\xac\xff\xfe"
+  "\x9a\x62\xf5\x43\xb6\xa6\xf8\xfd\x11\xca\x74\xda\xfb\xda\x47\x9a"
+  "\xa0\x2d\x34\x41\xd1\x4e\xc2\xb7\x3e\x38\xa3\x4c\x13\x7c\x50\xa5"
+  "\x5c\x13\x7c\x54\xc3\x69\x82\x8f\x6a\xa4\x35\xc1\x1f\x76\x3b\xd6"
+  "\x04\x7b\x82\x39\x4d\xf0\xe1\x06\x32\xae\x7e\xb8\x88\x8c\xab\x1f"
+  "\x0e\x6d\x3d\x4d\xb0\x7b\xaf\x50\x13\xec\xea\xfe\x48\x13\xb4\x87"
+  "\x26\x78\x3f\x83\x60\x74\xf7\x52\x65\x9a\x60\x77\x8a\x50\x13\x7c"
+  "\x9c\x6b\xaf\x09\x76\x9f\x77\x5e\x13\xec\x36\x2b\xd3\x04\xbb\x4d"
+  "\xce\x69\x82\x0f\xa7\x8b\x6b\x82\x3f\xec\x91\xd6\x04\xe4\x9c\x3d"
+  "\x97\xfb\xa3\x99\xe3\x72\x7f\x3c\xd5\xf1\x35\xc1\x1f\xe7\x89\xf3"
+  "\xb6\x3f\x2e\x25\x9a\xe0\xc3\xd8\xd6\xd7\x04\x1f\xc6\x8a\x6b\x82"
+  "\x3f\x5e\x25\xfc\xe9\xc3\x58\x7b\x4d\x00\xd7\x88\x6a\x82\x3d\x4f"
+  "\xda\x5e\x43\x34\xc1\x87\x71\x44\x13\xec\x19\x21\xad\x09\xf6\x9c"
+  "\x23\xb1\x6b\xcf\x6e\x12\xbb\x88\x4f\xed\x35\xc1\x9e\x95\x2d\x6b"
+  "\x02\x82\x21\xe6\x39\x25\x35\xc1\x9e\x93\xf6\x9a\xe0\x0f\xbb\xc4"
+  "\x35\xc1\x47\x85\x1c\x8e\x3e\x7a\x41\xa8\x09\xf6\x76\x7f\x30\x34"
+  "\x81\x24\xb6\xe6\x09\x35\xc1\xde\x8b\xf2\x35\xc1\x47\x3e\xf2\x34"
+  "\x01\xc6\x9c\x98\x26\xf8\x88\x7d\xff\x47\xf0\x62\xaf\x09\x3e\x5a"
+  "\x2e\xae\x09\x3e\xca\x15\x6a\x02\x5c\xbf\x98\x26\xf8\xe8\x98\xa0"
+  "\x7e\x3b\x4d\xf0\xd1\x79\xa1\x26\x20\xe5\x38\x4d\xf0\x71\x2a\x89"
+  "\xa1\x7f\x88\x94\xaf\x09\x3e\x9e\x2e\xad\x09\x3e\x4e\x10\x6a\x82"
+  "\x8f\x59\xee\xff\x71\x0e\xd1\x04\x1f\x4f\x20\xc7\xff\x30\x81\x7f"
+  "\x9c\xd3\x04\xe4\x38\xa7\x09\x3e\xde\xf9\x28\x9f\xd6\x83\x94\x4f"
+  "\x6b\xff\x24\x65\xba\x60\x7f\xb4\x72\xfe\x79\x28\x82\xe3\x9f\x87"
+  "\x22\xf8\xfc\x53\x98\xd7\xe2\x40\xa0\x63\xfe\xf9\xd9\x5a\x8e\x7f"
+  "\x16\x5f\x25\x31\xbc\xb8\x9c\xc4\xf0\x62\x26\x37\x9f\xbc\x7c\x5a"
+  "\xc5\x1e\xc2\x7c\x5a\x07\x96\x3e\xca\xa7\xd5\x56\xdc\xf2\xe3\x83"
+  "\x84\x5b\x7e\x72\x46\x19\xb7\xfc\xa4\x4a\xc8\x2d\x0f\x5d\xb7\xe7"
+  "\x96\xc5\xa1\xce\x73\xcb\xe2\xa9\xca\xb8\x65\x71\x8c\x73\xdc\xb2"
+  "\xf8\x88\x78\x0e\x8b\x03\x41\xd2\xf9\xb4\xc8\x39\x7b\x4e\xf0\x19"
+  "\x2f\xaf\xfe\x67\x81\x1d\x9f\x5b\x7e\x5a\x2a\x3e\xfe\x7f\x7a\x86"
+  "\x70\xcb\xe2\xc3\xad\xcf\x2d\x8b\x0f\x8b\x73\xcb\xcf\xc6\x90\x71"
+  "\xb8\xf8\xa8\x7d\x0e\x0b\xb8\x46\x94\x5b\x7e\xc6\xe6\xbf\x2f\x3e"
+  "\x2c\xe4\x96\xa4\x0e\x88\x43\xf9\xd2\xdc\xf2\x4f\x43\x49\x5c\xfa"
+  "\x93\x1b\x89\x4b\xc4\xa7\xf6\xdc\xf2\xb3\xf3\x2d\x73\x4b\x82\x21"
+  "\xe6\x39\x25\xb9\xe5\x9f\xfa\xdb\x73\xcb\x03\x01\xe2\xdc\xf2\x60"
+  "\x23\x87\xa3\x83\x5b\x85\xdc\xf2\x4f\x49\x0f\x06\xb7\x94\xc4\x56"
+  "\xa9\x90\x5b\x1e\x1c\x21\x9f\x5b\x1e\x9c\x2f\x8f\x5b\x62\xcc\x89"
+  "\x71\xcb\x83\x47\x6c\x31\x27\xe4\x96\x07\xcf\x89\x73\xcb\x83\xd7"
+  "\x85\xdc\x12\xd7\x2f\xc6\x2d\x0f\xf5\x16\xd4\x6f\xc7\x2d\x0f\x85"
+  "\x0a\xb9\x25\x29\xc7\x71\xcb\x43\xd5\x24\x86\xee\x2f\x97\xcf\x2d"
+  "\x0f\x1d\x91\xe6\x96\x87\x8e\x0b\xb9\xe5\xa1\x3c\xc2\x21\x0f\xd5"
+  "\x11\x6e\x79\x68\x0f\x39\xbe\xbf\x8c\x7f\x9c\xe3\x96\xe4\x38\xc7"
+  "\x2d\x0f\x99\xe4\xed\xbf\x69\x95\xf9\xe6\x76\xda\x7f\xd3\x5a\xf3"
+  "\xcd\x1d\x65\xff\xcd\x9f\xf7\x2a\xe3\x95\x7f\xde\xf3\x68\x5d\x50"
+  "\x6b\xcf\x35\xff\x3f\x35\xe1\x5a\x47\x5e\x50\x36\xd7\x7c\x64\xa4"
+  "\x72\xae\x7f\x7c\x1e\xc7\xf5\x8f\xcf\x93\xde\x4f\xf0\xb9\x8f\x63"
+  "\xae\xff\xc5\x41\x8e\xeb\x1f\x63\xd7\xdb\x1e\x6d\x24\x63\xea\xd1"
+  "\x23\x4a\xf6\x13\xac\xbf\x8d\xdc\xdf\xb5\xdd\x4f\x70\xf6\x18\xd9"
+  "\x4f\xb0\xd8\x76\x3f\xc1\xd1\xa1\xc2\xfd\x04\x9f\xe7\x4a\xed\x27"
+  "\xc0\x73\xcf\xcd\xfb\xb5\x35\x78\x2f\x81\xe8\x3e\x82\x69\xad\xbf"
+  "\x8f\x00\xeb\x84\xed\x80\x5b\xac\x15\x70\xbc\x79\xb8\xb4\xc2\x9f"
+  "\x0d\x04\xbf\xff\x67\x56\xa6\x15\xfe\xcf\x24\xd4\x0a\x7f\xe9\x6d"
+  "\xaf\x15\x8e\xce\x74\x5e\x2b\x1c\x5d\xa3\x4c\x2b\x1c\x5d\xed\x9c"
+  "\x56\x38\x7a\x59\x7c\x1f\xc1\xe7\xbe\xd2\xfb\x08\xc8\x39\x7b\x8e"
+  "\xf7\xc5\x1a\x8e\xe3\x7d\x31\xa9\xe3\x6b\x85\x63\xf5\xe2\x7c\xee"
+  "\x98\x99\x68\x85\xa3\x35\xad\xaf\x15\x8e\xd6\x88\x6b\x85\x2f\x16"
+  "\x11\x5e\x75\xb4\xc6\x7e\x1e\x1a\xae\x11\xd5\x0a\x5f\xec\xb6\xbd"
+  "\x86\x68\x85\xa3\xb5\x44\x2b\x7c\x71\x5c\x5a\x2b\x7c\x39\x9d\xc4"
+  "\xb5\x2f\xd9\x6f\x4c\x12\x9f\xda\x6b\x85\x2f\x3d\x5a\xd6\x0a\x04"
+  "\x43\xcc\x73\x4a\x6a\x85\x2f\x23\xed\xb5\xc2\xe7\x6a\x71\xad\x70"
+  "\x3c\x90\xc3\x51\xc9\x49\xa1\x56\xf8\x32\xff\xc1\xd0\x0a\x92\xd8"
+  "\xaa\x17\x6a\x85\x92\x04\xf9\x5a\xa1\x64\xab\x3c\xad\x80\x31\x27"
+  "\xa6\x15\x4a\x2e\xb3\xf8\xa9\x15\xd7\x0a\xc7\xdd\xc4\xb5\xc2\xf1"
+  "\xde\x42\xad\x80\xeb\x17\xd3\x0a\xc7\xc7\x08\xea\xb7\xd3\x0a\xc7"
+  "\x67\x0a\xb5\x02\x29\xc7\x69\x85\xbf\xb8\x93\x18\x7a\xe4\x88\x7c"
+  "\xad\x70\xfc\xb2\xb4\x56\x38\x7e\x5d\xa8\x15\x8e\x97\x10\x4d\xf0"
+  "\x17\x7f\xa2\x15\x8e\x9f\x25\xc7\x8f\x1c\xe6\x1f\xe7\xb4\x02\x39"
+  "\xce\x69\x85\xbf\x04\xc9\x5b\x9b\xe2\xfc\x3c\xf4\x7f\x7f\x6d\x8a"
+  "\xe7\x43\xb6\x36\xe5\xaf\xe7\x94\x69\x85\xbf\x9e\x55\xce\x4b\xbf"
+  "\xd6\x73\xbc\xf4\x6b\xbd\xf4\x1a\x88\x13\x7b\x1d\xf3\xd2\x53\x41"
+  "\x1c\x2f\xfd\x6a\x1d\x89\xdf\x5f\xcd\x27\xf1\xfb\xab\x41\xce\xae"
+  "\x81\x58\x7f\x8f\xe5\xa2\xd6\x35\x10\xcb\xd8\x35\x10\xc0\x47\x09"
+  "\xff\xfc\xdb\x6e\xe1\x1a\x88\x93\x3e\x52\x6b\x20\x44\xd7\x3e\xd8"
+  "\x70\x4e\x2b\x3f\x75\x65\xed\xc3\xc3\xcd\x39\xff\x32\x92\x70\xce"
+  "\xbf\x2d\x52\xc6\x39\xff\x96\x2c\xe4\x9c\x65\x1b\xec\x39\xe7\xdf"
+  "\xce\x39\xcf\x39\xff\xd6\xa8\x8c\x73\xfe\xcd\xe8\x1c\xe7\xfc\x6a"
+  "\xaa\xf8\xda\x87\x13\xfb\xa4\xd7\x3e\x90\x73\xf6\x5c\xa1\x94\x37"
+  "\xaf\x58\x7a\xb2\xe3\x73\xce\xd2\x44\x71\x5e\x50\xba\x88\x70\xce"
+  "\xaf\x62\x5a\x9f\x73\x7e\x15\x23\xce\x39\x4b\xd9\xf1\xff\xab\x18"
+  "\x7b\xce\x09\xd7\x88\x72\xce\x53\xbd\x6d\xaf\x21\x9c\xf3\xab\x58"
+  "\xc2\x39\x4f\x85\x4a\x73\xce\x53\x67\x48\xcc\x3a\xf5\x3e\x89\x59"
+  "\xc4\xa7\xf6\x9c\xf3\xd4\xf2\x96\x39\x27\xc1\x10\xf3\x9c\x92\x9c"
+  "\xf3\xd4\x71\x7b\xce\x79\x62\x8f\x38\xe7\xfc\x7a\x2b\x87\xa3\xaf"
+  "\x47\x08\x39\xe7\xe9\x2e\x0f\x06\xe7\x94\xc4\x56\xa2\x90\x73\x9e"
+  "\x3e\x2f\x9f\x73\x7e\xdd\x5d\x1e\xe7\xc4\x98\x13\xe3\x9c\x5f\x4f"
+  "\x65\xf1\x13\x2b\xce\x39\xbf\x5e\x2a\xce\x39\xbf\xde\x20\xe4\x9c"
+  "\xb8\x7e\x31\xce\xf9\xf5\x11\x41\xfd\x76\x9c\xf3\xeb\x73\x42\xce"
+  "\x49\xca\x71\x9c\xb3\x8c\xe5\x78\x27\x26\xc9\xe7\x9c\x65\x53\xa5"
+  "\x39\x67\xd9\x4c\x21\xe7\x2c\x1b\x4e\xb8\x65\x59\x16\xe1\x9c\x65"
+  "\xe3\xc8\xf1\x13\xd1\xfc\xe3\x1c\xe7\x24\xc7\x39\xce\x59\x56\xe0"
+  "\x88\x73\xd2\x39\xe6\xd2\x1c\xca\x52\x0c\xbf\xc3\xf0\x9c\xbd\x61"
+  "\x7c\x2b\x81\x7f\x97\xc2\x38\xa5\x86\x7f\x4b\xae\xe7\x34\xf8\x98"
+  "\x4b\x2d\xc0\x4b\x2c\x70\x9f\x4a\xc3\xcd\x92\x92\x27\x4c\x70\xef"
+  "\xf2\x3e\x84\xb3\x98\x4b\xbd\x4d\x9d\xc7\x59\xe8\x44\x18\xdf\xe1"
+  "\xdf\x3a\x38\x06\xe5\x7b\xc0\x78\xa8\x59\x86\x7a\xdc\xa0\xca\x47"
+  "\x5a\xcb\xc1\x33\xf7\xb8\x44\x95\x35\xe2\x3a\x1a\xd6\x97\x8f\x83"
+  "\xf6\xec\x91\x7c\x56\xa8\x2b\x6a\x6f\x5f\xb4\xd2\x44\xff\x50\xb2"
+  "\xe0\x36\xaa\xa1\xca\x73\xbd\xeb\x3a\x8f\x83\x38\x84\x30\x47\x2c"
+  "\x7e\xc2\xe0\x8e\xeb\x2c\x59\xd0\x84\xcf\xa5\xe0\x73\x66\x78\xc6"
+  "\xb4\xf9\x88\xca\xbe\xdd\xd9\x13\x38\x97\x47\x7a\x3d\x5d\xbb\xd0"
+  "\x04\xcf\x0c\xe3\xeb\x97\x7d\xab\xdd\x3f\xd9\x56\xcd\x8c\x3d\x15"
+  "\xf5\x66\xa6\x0e\xcd\x02\xfc\x3c\xe5\xf9\x3b\xa0\xbc\xd8\x33\xac"
+  "\x39\x80\x82\x3d\x06\xd2\x7a\x79\xe3\x5d\x79\xad\x94\x1d\xbd\x33"
+  "\xfb\xa2\x92\x67\xc1\x76\x1a\x44\x89\x9d\x97\x77\x9f\x0a\x47\xeb"
+  "\x1f\x3c\xdf\xeb\x45\xd7\xa7\x6f\x45\xd4\x46\x4b\x67\xcf\xbf\x42"
+  "\x4c\x2c\xda\x4c\x1b\x1a\xd6\x57\x1c\xd5\xbb\x1d\x1d\x87\x6d\xfe"
+  "\x5b\x38\xbf\xb1\x17\x6d\xb8\xb3\x0a\xe3\xa6\xe2\xec\x71\x18\xdb"
+  "\x6d\x7d\xb1\x38\x7e\xfe\x4c\x4d\x4a\xd2\xfc\x84\x85\x4b\x53\x34"
+  "\x81\xf1\x5d\xd1\xe4\x85\x0b\x35\xf3\x67\x2e\x58\xae\xe1\x9f\x79"
+  "\x5e\x13\x9f\xb4\x64\xe6\xac\x79\x09\x83\xe6\xcf\x4e\xee\x0a\xcf"
+  "\x84\x78\xcf\xe1\x8b\x9f\xc5\xb2\xbe\x42\xbf\x63\x13\x42\xef\xf5"
+  "\x44\xee\xf8\xb9\x1a\xd6\x57\x8e\xd6\xbb\xf7\x99\x8c\xef\x97\xbd"
+  "\x99\xae\xa7\xa0\x4c\x3a\xc4\xb4\x8d\x69\x9d\x71\xd9\xe8\x22\x78"
+  "\xae\x1d\xf0\xdc\xf0\x8c\xf0\xcc\x95\xc9\xd6\x67\xb6\x62\x22\x1d"
+  "\x63\x22\xed\x36\x60\xb0\x32\xd7\xdb\xd8\xf9\x65\x9a\x8e\xc1\xed"
+  "\xab\x87\xbe\xe2\x76\x85\xaa\x1a\xc8\xe8\x86\x5c\x73\x29\x5c\xbb"
+  "\xcf\x8a\x31\x4b\xde\xd8\x38\x7a\x93\x39\x07\x78\xa5\x5b\x03\x9d"
+  "\xf8\x22\x60\x13\x5f\xdf\x38\x04\xa1\x0c\xba\x21\x86\xf9\x36\x06"
+  "\xdd\x00\x18\x26\x38\x85\x73\x55\x65\x77\x28\xf4\x73\xa8\xc3\xa0"
+  "\x47\x73\xe7\xe1\x3a\xf4\x70\x0c\xdb\xdc\xb2\x73\xb6\x61\x4a\x10"
+  "\xca\x78\x26\x03\x65\x34\xe0\x6b\x76\x05\x96\x7a\xa7\x20\xb7\x28"
+  "\x1d\xfd\x1d\xc4\x1d\x37\xba\xff\x6c\x03\xbd\x3b\xb0\x54\x4f\x55"
+  "\x9e\xb5\xe4\x8f\x8d\x83\xf6\xd4\x35\xac\xaf\xd2\xea\xd1\xbd\xd5"
+  "\xb8\x9e\x8d\x9b\x19\xdb\xd7\xe1\xb6\x83\x7d\x40\xff\xd0\x25\xf4"
+  "\x2a\xb6\x0f\xe5\xf4\xcb\xb0\xe4\xcc\x4f\xae\x74\xbf\x87\xa2\x4c"
+  "\x74\x33\x9d\xdb\x2f\xa3\xa2\xbe\x1e\x62\x5a\xf2\x6c\xba\x6b\xc5"
+  "\x2d\x6f\x53\x52\x42\x51\x4f\xe8\x8b\xb9\xf3\x93\xe9\xdc\xb0\x5d"
+  "\x53\x06\x22\x35\xd4\x9d\x67\xb5\x27\xd8\xd2\x5d\x1e\x8e\xaa\x98"
+  "\x18\x86\xf1\x00\xcf\xc3\xe2\xa1\xaa\xe6\x78\x8a\x3d\x1e\xee\xf7"
+  "\xcd\xcd\xa1\x55\x26\x3a\xe6\xe5\xe6\xbc\x30\x4f\xda\x37\xb4\x3e"
+  "\xed\x32\xea\x84\x6d\x5b\x01\x5a\x20\x7b\x19\xf2\xdf\xf0\x3a\xd2"
+  "\xcc\x58\xae\x46\x86\xfc\x50\x83\x77\x66\x86\x1b\xd8\x84\x82\xf8"
+  "\x12\x02\x31\x33\xa4\xb9\xd7\xd8\xb8\xd4\x04\x44\xed\xbf\x54\x4c"
+  "\x61\xfe\x8c\xd7\xad\x5c\xa1\xce\xec\xde\x01\xd7\xd1\x37\x63\x10"
+  "\xf6\x07\xe3\x8b\x9b\x89\x28\x32\x09\xc6\xe7\xb9\xcc\xf9\xf3\x85"
+  "\x50\xa7\xbc\x76\x9d\x61\xf8\xaf\x19\x7c\x35\x04\xfc\x54\x59\x63"
+  "\x66\xea\x64\x7c\x35\x8f\xf3\xd5\x31\x78\x0e\xce\x5f\x67\xe2\xb0"
+  "\x5f\xc5\xdb\x1c\x16\xcd\xb6\x79\x2d\xed\x1b\x96\x22\xdd\xe6\xb0"
+  "\x64\xd2\x66\x8f\xdb\x8e\xdb\xfc\xcd\x56\xc7\x6d\xfe\xa6\x5c\x7e"
+  "\x9b\xbf\x89\x97\xdf\xe6\x6f\x26\x3b\x68\x33\xeb\xe7\x70\xf0\x73"
+  "\x98\x03\x3f\x87\xb1\x7e\xee\x76\xc9\x71\x9b\xff\xbe\xc1\x71\x9b"
+  "\xff\x7e\x5c\x7e\x9b\xff\x1e\x23\xbf\xcd\x7f\x1f\x27\xdd\xe6\x70"
+  "\xd6\xcf\xe1\xe0\xe7\x70\x07\x7e\x0e\x67\xfd\xec\xf3\x8d\xe3\x36"
+  "\x9f\xcd\x74\xdc\xe6\xb3\x87\xe4\xb7\xf9\xec\x04\xf9\x6d\x3e\x3b"
+  "\xd2\x41\x9b\x59\x3f\x6b\xc1\xcf\xe1\x0e\xfc\x1c\xce\xfa\x39\x6c"
+  "\xbd\xe3\x36\x9f\x5b\xea\xb8\xcd\xe7\xf6\xca\x6f\xf3\xb9\x08\xf9"
+  "\x6d\x3e\x17\x22\xdd\x66\x2d\xeb\x67\x2d\xf8\x59\xeb\xc0\xcf\x5a"
+  "\xd6\xcf\xaf\xfd\xc2\x71\x9b\xff\x91\xe4\xb8\xcd\xff\x28\x94\xdf"
+  "\xe6\x7f\x0c\x97\xdf\xe6\x7f\x04\x48\xb5\xb9\x09\xe2\xb6\x17\xb4"
+  "\xa5\xf9\x9f\x31\x2f\x9b\x7d\x43\x4d\x5e\x35\x88\x2a\x58\x65\x49"
+  "\xf4\xae\x45\x5d\xa0\x6d\x89\xf4\xe6\xf1\x21\xf8\xaf\xc5\x37\xd4"
+  "\xd8\xe4\x1b\xe6\xd9\xd8\xd3\x9c\xf3\xf6\x74\xd4\x09\xf3\xf1\x75"
+  "\x16\xe4\x6f\xc9\x0b\xad\xcf\x7a\x05\x69\xd2\x0d\x48\x5d\x91\xa6"
+  "\x47\x69\xc9\xb4\xa1\x02\x7d\x8f\xba\xd7\x62\xed\xf9\x2d\x2a\xab"
+  "\x2b\x45\x0b\x16\xd3\xf4\x15\xea\x9f\x57\xf1\xbc\x09\xf0\xe4\x8c"
+  "\x9c\x7f\x20\x0d\xdc\x23\x64\x07\xfc\x70\x3d\xde\x13\x60\xfc\xdc"
+  "\x3c\x7e\x58\x51\x1a\xf2\xff\x62\x6e\x2d\xc2\xc7\x0b\xe1\x67\xde"
+  "\x3c\x36\x2e\x6d\x3a\xa2\x0e\xdc\xae\xa6\xc8\xd8\xfc\xcf\x43\xb6"
+  "\x63\xf3\x84\x99\x60\xcb\x59\xf8\x5c\xb5\x5b\xc1\x2b\x72\x6d\xf9"
+  "\xcf\x0c\xeb\xd8\xcd\xd8\xf2\x82\x99\x8c\xf7\x36\x63\xf7\x17\x70"
+  "\x7f\xce\x96\xff\x4c\xc6\xb6\xa4\xf3\xc2\xd4\x95\xb5\x4d\x58\x37"
+  "\xa9\xaf\xe8\x10\x05\xc7\x35\x15\xc9\xb7\x91\xb8\x8d\xc3\xa2\x39"
+  "\x1b\x87\xa5\x7a\xd5\x78\xdc\x16\xb7\x71\x98\x0e\x6c\xbc\xd6\xde"
+  "\xc6\x61\x29\xce\xd9\xf8\x7c\xa4\xeb\x36\x3e\xdf\x5b\xda\xc6\xe7"
+  "\x13\xe4\xdb\xb8\xba\x46\xbe\x8d\xab\xcf\xb2\x36\xce\x11\xda\xb8"
+  "\x7a\xb5\x03\x1b\xf3\x70\x1c\x06\x38\xee\x76\x49\xc2\xc6\x80\xe3"
+  "\x70\x11\x1c\x87\x39\x89\xe3\x6f\x3f\x75\xdd\xc6\xdf\xae\x94\xb6"
+  "\xf1\xb7\xa7\xe4\xdb\xf8\xdb\x71\xf2\x6d\xfc\xad\x96\xd8\x38\xdc"
+  "\x06\xc7\xe7\x6b\xa5\x6d\x1c\xce\xc3\x71\x38\xe0\xd8\xe7\x1b\x71"
+  "\x1b\x87\x03\x8e\xc3\x45\x70\x1c\xee\x24\x8e\x2f\xf8\xb9\x6e\xe3"
+  "\x7f\x7d\x2f\x6d\xe3\x0b\x83\xe4\xdb\xf8\x5f\xfb\xe4\xdb\xf8\x5f"
+  "\x05\xac\x8d\x6d\x70\xfc\xaf\x09\x0e\x6c\xcc\xc3\x71\x38\xe0\x38"
+  "\x6c\xbd\x84\x8d\x01\xc7\x5a\x11\x1c\x87\x3b\x89\xe3\x8b\xcb\x5d"
+  "\xb7\xf1\xc5\x31\xd2\x36\xbe\x98\x2b\xdf\xc6\x17\xd5\xf2\x6d\x7c"
+  "\x11\x11\x1b\x6b\x6d\x70\x7c\xa1\x58\xda\xc6\x5a\x1e\x8e\xb5\x80"
+  "\xe3\xd7\x7e\x21\x6e\x63\x2d\xe0\x58\x2b\x82\x63\xad\x93\x38\xfe"
+  "\xf7\x45\xd7\x6d\xfc\xef\xbd\xd2\x36\xfe\xf7\x5d\xf9\x36\xfe\x77"
+  "\x8a\x7c\x1b\xff\x3b\x9e\xb5\xb1\x0d\x8e\xff\xed\x2b\x65\xe3\x66"
+  "\xd0\x80\xdd\xc1\xc6\xdd\xeb\x10\x55\x88\x6d\x5b\x4d\x6c\x6b\xee"
+  "\x35\x3e\xa4\x90\xb2\x24\x62\x9b\x30\x73\x40\x3f\xfa\xf7\x30\xe7"
+  "\x85\x9a\x68\x0a\xda\x94\x86\xe7\x5d\xbf\x9b\x6e\x5a\x85\x7a\x68"
+  "\xd2\xf0\xfc\xef\xf7\xcc\xfa\x58\x4d\xda\x3b\x17\xe1\x7e\x2a\x3c"
+  "\xef\x65\xca\x35\x25\x9b\xfd\x9e\x8f\xb8\x42\xe9\xf3\xe9\xc0\x67"
+  "\xf4\xa0\xbd\xd4\xf4\x9b\xfe\xbe\x95\x75\xc5\x60\x9f\xd3\xa8\xa2"
+  "\xfa\x73\x64\xe9\x35\x7e\xd8\x10\x13\x0a\xa2\x7f\x0c\xf2\x2d\x4b"
+  "\xd1\x23\xf3\x6c\x7f\xaf\x4a\x5d\x29\xaa\xd4\x7d\x86\xa2\x6a\xe9"
+  "\x7b\xf4\x7f\x82\xbc\x9a\xfd\xa2\x74\x66\xbf\xf1\x6a\x73\xfe\x54"
+  "\x4f\x93\x5f\x54\xe2\xfe\x65\x7a\xca\xcb\x88\x82\xe6\xd5\xd0\x74"
+  "\xf6\x2c\xe4\x9e\x7d\x09\x79\x6e\x9c\x85\xbc\x36\x5e\x42\xea\xb2"
+  "\x9a\x6a\x54\x7e\xad\x14\x95\xdf\x3e\x8f\xca\xef\xc1\xaf\x09\x7e"
+  "\x16\xf8\x65\x9c\x07\x5f\x23\x14\x79\x1d\xe1\xef\x8a\x1a\x9e\xbb"
+  "\x80\x7c\xcb\x4c\xd5\x08\xef\xe9\xbd\x41\xe9\x87\x7a\xc5\x21\x5f"
+  "\xfa\x3f\xfe\x88\x9e\xed\x4f\xc1\x39\x77\x7c\xbc\xd2\x64\x40\x65"
+  "\x35\x46\x7c\x5e\x0d\xe7\xdd\xd3\x6b\xa0\x7e\x4b\x29\xfe\x6e\xa8"
+  "\xa1\x2c\xe3\x14\xb4\x6f\x5f\x1c\x8d\x35\x74\xaf\xd0\xaa\x1c\x30"
+  "\xb5\x85\xf6\x7f\x8a\xe0\xe0\xfb\xf1\x3b\x2c\x72\x7d\xad\x8f\x63"
+  "\x6c\xfc\xa6\x7f\x4f\xb0\xf3\x13\x96\x37\x63\xd4\x13\xcf\x7f\x47"
+  "\xe3\x35\x7e\x78\x2e\xa1\xa2\xfe\x34\xc2\xef\x9a\xa2\x96\x23\x34"
+  "\xc1\x8c\x10\xb6\x45\xa5\xae\x16\x4d\x4c\x46\xde\x78\xfe\xd9\xf2"
+  "\x63\x50\xcf\xca\x1a\x03\x5a\x69\x82\x67\xbc\x61\xbc\xff\x8c\x15"
+  "\xab\x2b\x10\x9c\x7b\xa2\x22\x51\x8f\xbc\x92\x91\x1a\xdb\xd7\x94"
+  "\x17\x6a\x9c\x08\xfd\x67\x41\x3d\x4d\x63\xdb\x62\x9b\x62\xfb\xe2"
+  "\xfa\xac\x36\xaf\x8c\x37\xa0\x74\x23\x52\x57\xa6\xc1\x5f\x1d\x6d"
+  "\xa8\x44\xb7\x10\x3c\xe3\x68\xda\x67\x5f\x1c\xe0\x62\x38\xc6\x82"
+  "\x9e\xfa\x6e\x32\xf8\xbf\xa7\x38\xa6\xc2\x52\x08\xa6\x3c\x6e\xb7"
+  "\x8c\xa9\xb0\x54\x0e\x53\xdf\x7f\xca\x61\xea\x3f\x1b\xa4\x31\x75"
+  "\xe9\x2a\x8b\xa9\x9c\x8e\x89\xa9\x4b\x6b\x1c\x63\xea\x52\xbc\x03"
+  "\x4c\xad\xa5\x7b\x85\x45\x0b\x31\xf5\x9f\x42\xf9\x98\xba\x74\xb0"
+  "\xfd\x30\x15\xa6\x53\x86\xa9\x4b\x5b\x84\x98\xfa\x7e\x8f\x03\x4c"
+  "\xb1\x71\xaa\xdb\x25\x27\x30\xc5\x8b\x53\x35\x1e\x1c\xa6\x2e\x7f"
+  "\x2f\x8d\xa9\xcb\x2f\x10\x4c\x85\x77\xd0\x38\x55\x73\xde\x31\xa6"
+  "\x6a\x0e\x4b\x63\x2a\x1c\xe2\x54\x98\x4d\x9c\xba\x7c\x4b\x3e\xa6"
+  "\x2e\x7b\xb6\x23\xa6\x14\xc6\xa9\x9a\x3a\x21\xa6\xfe\x63\x92\xc6"
+  "\x54\x38\x1b\xa7\x7c\xbe\x69\x19\x53\xe1\xbc\x38\x75\x65\x2a\x87"
+  "\xa9\xda\x50\x69\x4c\xfd\x90\xcb\x62\xaa\x83\xc6\xa9\x1f\x06\x39"
+  "\xc6\xd4\x0f\x5e\x0e\x30\x05\x71\x2a\xdc\x26\x4e\xd5\x8e\x91\x8f"
+  "\xa9\x1f\x62\xdb\x0f\x53\xe1\x0a\xe3\xd4\x0f\x11\x42\x4c\x5d\x89"
+  "\x76\x80\x29\x36\x4e\x85\xad\x77\x02\x53\xbc\x38\x55\xbb\x9f\xc3"
+  "\xd4\xb5\x75\xd2\x98\xba\x7a\x99\x60\x4a\xdb\x41\xe3\xd4\xd5\x4c"
+  "\xc7\x98\xba\x1a\x27\x8d\x29\x2d\xc4\xa9\x70\x9b\x38\x75\x6d\xab"
+  "\x7c\x4c\x5d\x2d\x6e\x47\x4c\x29\x8c\x53\x57\xf3\x84\x98\xaa\xdd"
+  "\x25\x8d\x29\x2d\x1b\xa7\x5e\xfb\x45\xcb\x98\xd2\xf2\xe2\xd4\x8f"
+  "\x6e\x1c\xa6\xea\x2e\x4a\x63\xaa\x6e\x04\x8b\xa9\x0e\x1a\xa7\x7e"
+  "\x3c\xe7\x18\x53\x3f\x1e\x74\x80\x29\x88\x53\x5a\x9b\x38\x55\x77"
+  "\x5d\x3e\xa6\xea\xdc\xdb\x0f\x53\x5a\x85\x71\xea\xc7\x5a\x21\xa6"
+  "\xae\x19\xa5\x30\xd5\x84\x75\x9f\x1b\x60\x2a\x11\x74\x1f\x60\xc8"
+  "\xbb\x8a\x60\xaa\x19\x30\xb5\x9d\x8f\xa9\x7f\xd9\xea\xbe\xeb\x53"
+  "\x2c\xf7\x31\x75\x73\xa6\x2d\xa6\x2c\x80\xa9\x66\x06\x53\x37\x96"
+  "\x5b\x75\x5f\x65\xdd\x4e\xf0\xd5\x35\x54\x19\x0d\x78\xda\xcc\xe2"
+  "\xe9\x5f\x80\x27\x68\x8f\x05\xda\x5b\x76\xa1\x1a\x45\x19\x48\xbb"
+  "\x9a\xa0\xbd\x16\x3e\x96\x9a\x6a\x29\x8c\x21\x8c\x1d\x2b\x8e\xca"
+  "\x17\x00\x7e\x16\x9f\x41\xe5\xcb\xe0\xb7\x02\x7e\x69\xf0\x43\x67"
+  "\x50\x59\x2d\x62\xe6\xec\x39\xfc\x54\xb1\xf8\xb9\xe1\xe7\x18\x3f"
+  "\xd7\xeb\xe5\x69\xbc\x9b\x8b\xe4\xe3\xe7\xc6\x68\x76\x2d\x9d\x3a"
+  "\x6a\xd2\x77\x34\x5e\x37\x4b\x30\x72\x0d\x45\x99\x90\x37\xfd\x5a"
+  "\x50\x4f\xaf\x18\xa4\x7e\xdb\x8c\xa8\x0d\xb3\x90\x7a\xc3\xb7\xd0"
+  "\x5e\x6b\xdf\xb9\x84\xbc\x4e\x1b\x3f\x47\x65\xb7\xab\x51\xd9\xbd"
+  "\x53\xa8\xcc\x02\xbf\x6b\xf0\x83\x67\x8c\x4a\xe0\xb7\xd7\xc0\xb6"
+  "\xf7\xa6\x07\xd4\x15\x20\xdd\xde\x1b\x35\x4c\x7b\xe3\xa1\xbd\x4d"
+  "\x5c\x7b\x2b\x01\x8b\xe0\x97\x27\x2c\xac\x4e\x8c\x32\xa0\x2e\x0b"
+  "\x4d\x34\xdd\xc4\x62\x10\xfb\xe5\xf4\x59\x23\x8a\x4a\x06\x5f\xcd"
+  "\x06\x0c\xd6\xec\x41\xe9\xa9\x80\xc1\x26\x23\x7e\xaf\x6f\xa8\xcc"
+  "\x68\x04\x0c\xde\x08\xa2\xc1\x6e\xcd\x18\x83\xff\xc2\x18\xbc\x3e"
+  "\xc1\x22\x89\x41\xd0\x89\x0c\x06\x41\x27\xb6\x88\x41\xbe\x4e\xbc"
+  "\x79\x9e\xc3\xe0\xad\xcb\xd2\x18\x34\x98\xad\x3a\xf1\xbf\x8f\x41"
+  "\xc3\x56\xc7\x18\x34\xe8\xe4\x69\xc2\x5b\x77\xe5\x63\xd0\x50\xda"
+  "\x7e\x18\xbc\xb5\xce\x31\x06\x6f\x25\xb6\x8c\xc1\x30\x9d\x32\x0c"
+  "\x1a\xf6\x09\x31\x78\xb3\xca\x01\x06\xd9\x38\x08\xba\xb2\x65\x0c"
+  "\xf2\xe2\xe0\xed\xe9\x1c\x06\xeb\x93\xa4\x31\x78\x27\xd3\xaa\x2b"
+  "\xff\xfb\x18\xbc\xf3\xa4\x63\x0c\xde\x36\xc9\xd3\x90\xf5\xcb\xe5"
+  "\x63\xf0\xce\x84\xf6\xc3\x60\x7d\x77\xc7\x18\xbc\x53\xe7\x04\x06"
+  "\x15\xc6\xc1\x3b\x21\x42\x0c\xde\x9e\x2c\x8d\xc1\x70\x36\x0e\x82"
+  "\x0e\x6d\x11\x83\x7c\x1d\x5a\xff\x3d\x87\xc1\x7b\xd7\xa5\x31\x78"
+  "\xcf\xc3\xaa\x43\xff\xfb\x18\xbc\xfb\xbe\x63\x0c\xde\xcd\x90\xa7"
+  "\x39\xef\x99\xe5\x63\xf0\x6e\x55\xfb\x61\xf0\x5e\xae\x63\x0c\xde"
+  "\x4b\x6e\x19\x83\xe1\x0a\xe3\xe0\xdd\x83\x42\x0c\xd6\x57\x3b\xc0"
+  "\x20\x1b\x07\x41\xb7\xb6\x8c\x41\x5e\x1c\x6c\x48\xe0\x30\xd8\xb8"
+  "\x48\x1a\x83\xc6\x75\x56\xdd\xfa\xdf\xc7\xa0\x31\xd0\x31\x06\x8d"
+  "\xee\xf2\x34\x6a\x63\xa6\x7c\x0c\x1a\x27\xb7\x1f\x06\x1b\xfd\x1c"
+  "\x63\xd0\x58\xef\x04\x06\x15\xc6\x41\xa3\x56\x88\xc1\x86\x58\x69"
+  "\x0c\x6a\xd9\x38\x08\x3a\xb7\x45\x0c\xf2\x75\x6e\xe3\x55\x0e\x83"
+  "\xcd\x77\xa5\x31\xd8\xdc\xdd\xaa\x73\xff\xfb\x18\x6c\xda\xeb\x18"
+  "\x83\x4d\x6b\xe5\x69\x5a\x93\x87\x7c\x0c\x36\x55\xb7\x1f\x06\x9b"
+  "\xb7\x3a\xc6\x60\xb3\xae\x65\x0c\x6a\x15\xc6\xc1\xa6\xa3\x42\x0c"
+  "\x36\xea\xa5\x30\x68\x01\x5d\xdc\xbc\xeb\x19\xbd\x25\x2f\x4a\xe7"
+  "\xed\xa6\x41\x26\xdf\xe7\x23\x2a\x53\xea\xd1\xc4\xbb\x60\x9f\xe4"
+  "\xbb\xe8\xf5\xbb\x6a\x64\xce\x8b\x4a\xa4\x41\x1f\xf1\xf4\x33\xb3"
+  "\xb6\xcc\x94\xb3\x2f\x6e\xe3\x02\xe4\x0e\xfa\x7b\x18\x3e\x56\x79"
+  "\xc5\x88\xf0\xfd\x57\xe2\xe7\xb9\xc6\x3d\x0f\x9e\x27\xa0\x6f\x06"
+  "\xa9\x99\x77\xcc\x4d\x7a\x54\x33\x12\xa9\xca\x6a\xf4\x60\x87\x15"
+  "\x8c\x7f\xb1\x5d\xc0\x9f\xd5\x45\x37\x90\xbb\xe9\x3f\xfe\x4f\x80"
+  "\xbd\x7d\xbb\xbf\x85\xdc\xfa\xd4\xd0\x16\x6c\x57\x6c\x2f\x6c\x63"
+  "\xcd\x0a\xfc\xee\xda\x3c\xb0\x02\x30\x66\xfa\x4f\xd0\x13\x3b\xa0"
+  "\x9c\xb8\x5e\x35\x0f\x95\x8f\x0d\x53\x3d\xd9\xb7\x60\xaa\x2a\xbb"
+  "\x80\x44\xdf\x1d\x5b\x40\xbf\x39\x67\xab\x30\x1d\x4f\xe7\xb5\x81"
+  "\xad\x2c\xee\xce\xd9\xca\x32\xc5\xc6\x56\x22\xba\xca\x32\x5d\xbe"
+  "\xad\x2c\x1a\x62\x2b\xb3\xc9\x81\xad\x9c\xc4\x55\x98\x91\xa7\x47"
+  "\xda\xc0\x56\x74\x88\x73\xb6\xa2\x33\x85\xb6\x12\xe3\xff\xf4\x3a"
+  "\xf9\xb6\xa2\xd9\x5c\xa0\x74\x90\xb4\xad\xc2\x9d\xc4\x55\xb8\x8e"
+  "\xc7\x9b\x5b\xdf\x56\x2a\x14\xeb\x94\xad\x54\x68\xbf\x8d\xad\xec"
+  "\x79\xaa\x0a\x1d\x92\x6d\x2b\x15\x22\xdf\xc3\x53\xa1\xc9\x0e\x6c"
+  "\xe5\x24\xae\xc2\x8d\x3c\x7e\xd7\x06\xb6\x72\x5b\xeb\x9c\xad\xdc"
+  "\xce\x0b\x6d\x25\xc2\xa7\x54\x6e\xdf\xcb\xb7\x95\xdb\x2e\x62\x2b"
+  "\xb7\x0c\x69\x5b\x69\x9d\xc4\x95\x56\xc7\xe3\x21\x6d\x60\x2b\xea"
+  "\xa0\x73\xb6\x52\x79\xd8\xd8\xca\x7e\xdc\x57\xa9\xba\xcb\xb7\x15"
+  "\x55\x45\x6c\x45\xed\x93\xb2\x95\x39\x2f\xb4\xde\x1b\x6c\xd0\xb8"
+  "\x39\xb4\xca\x5b\x87\xa8\xa6\x00\xb0\x9b\x2f\xd8\x2d\x53\x83\x9a"
+  "\xf3\xc0\x6e\x06\x13\x9a\xb8\xe8\x3b\xba\xa2\xce\x8c\x9a\xc0\x66"
+  "\x8d\xbe\xa1\xc6\x4a\x43\x2d\x5e\x73\xf4\xb3\x4b\x2a\xf7\xeb\xaf"
+  "\x2d\x52\x23\x6c\x37\x6c\x07\x6c\x3b\x1a\xec\xc6\xd8\xd1\x77\xaa"
+  "\xa7\xd9\x77\xbc\x3a\xf2\xfa\x77\xf4\x42\x3d\x4d\xe3\xf6\xd2\x6a"
+  "\x53\x32\x7e\x2f\x10\x55\x8b\xba\x68\x5e\xc1\x6d\x72\x2f\xc4\xc7"
+  "\x2b\x0d\xd5\xc0\x0f\x6e\x23\x86\x9b\x7d\x17\xe4\x6b\xfe\x4d\x90"
+  "\x97\xb9\x32\xe6\x65\xba\xa7\x39\xc7\xd4\x6b\x6c\x5c\xfa\x75\xd4"
+  "\x09\xf3\x87\x6c\x0b\xf2\x5f\x39\x1f\x51\x07\xe6\x96\x50\xcc\xde"
+  "\xb5\xc5\x4c\x1d\x49\x60\x17\x7f\xfa\x0e\x6f\x4d\xf7\x9d\x44\x54"
+  "\x79\x25\x87\xf1\x9b\x2d\x47\x60\xfc\xf6\xcf\x20\x35\xf0\xcc\x10"
+  "\xda\x37\xcc\x33\xa7\x02\x69\xe8\x66\xb0\x31\xde\x4f\xa4\xf2\x98"
+  "\x52\xd4\x24\xd7\xc6\xee\xcc\xfa\x6f\x8b\x86\x5d\xbf\x05\x76\xc2"
+  "\xf7\x67\xd6\x6f\x25\xf3\xd6\x6f\xc1\x33\xdf\x5f\xbf\xa5\x52\x19"
+  "\xf1\xfa\x2d\xcb\x77\xfe\x4f\x58\xdb\xbe\x70\x1e\x4d\x43\xdb\x7b"
+  "\x56\xd4\x1b\x10\x6e\x7f\x45\x7d\x09\x4a\x4f\x41\xea\x8a\xa6\x5a"
+  "\x94\x56\x4f\x1b\x2a\x32\xae\xa2\xa8\xbb\x98\x07\x63\xbc\xb8\x5f"
+  "\x26\x7e\x55\x1d\xb6\x7c\x17\xf4\x04\x3c\xc3\x85\x0a\xf0\x34\x6f"
+  "\x1f\x4f\x22\x70\x66\x4f\xf0\x43\x62\x65\xc6\x25\x04\x3e\xc9\xa9"
+  "\x34\x7d\x8b\xfd\x94\x08\xe7\x47\xde\xe7\xd7\xbd\xc6\x6f\xc2\xc7"
+  "\xb0\xcf\xf0\xfb\x26\x9c\x3b\xa0\x88\xc7\xbf\x31\x2e\xbc\x75\x19"
+  "\xa8\x52\xd7\x84\x2a\x4c\x08\xc1\xfd\xe2\xbf\x8e\xa9\x96\xc0\x51"
+  "\x58\x0a\xc1\x51\x58\xb4\xb7\xce\xe3\x76\xcb\x38\x0a\xd3\x71\x38"
+  "\xea\x1c\xea\x1a\x8e\x3a\x5d\x76\x1d\x47\x9d\x3e\x75\x01\x47\x6b"
+  "\x85\x38\xea\x5c\x28\x1f\x47\x9d\x52\xe5\xe3\xa8\x53\x84\x6b\x38"
+  "\xea\x3c\x88\xe0\xa8\x13\x22\x38\xea\x1c\xc0\xe1\x88\xd9\x1b\xd5"
+  "\x46\x38\xf2\xd8\xe7\x00\x47\x6c\x3c\x0a\x83\x78\xd4\xed\x92\x13"
+  "\x38\xe2\xc5\xa3\x2e\x2b\x5d\xc3\x51\x97\x41\xae\xe3\xc8\xb3\x51"
+  "\x39\x8e\xc2\x6d\xe2\x51\x97\xcb\xf2\x71\xe4\x79\x42\x3e\x8e\x3c"
+  "\xd7\xba\x86\xa3\x2e\x4b\x09\x8e\x3c\xc7\x11\x1c\x75\x99\xc7\xe1"
+  "\x88\xd9\x6f\xd6\x46\x38\xea\x5c\x2f\x8d\xa3\x70\x36\x1e\x85\x43"
+  "\x3c\xf2\xf9\xa6\x65\x1c\x85\xf3\xe2\x51\xb7\x93\xae\xe1\xa8\xdb"
+  "\x52\xd7\x71\xd4\x6d\x94\x0b\x38\xb2\x89\x47\x5e\x83\xe4\xe3\xa8"
+  "\x9b\x97\x7c\x1c\x75\xad\x72\x0d\x47\xdd\x8e\x11\x1c\x75\xcd\x21"
+  "\x38\xea\x76\x90\xc3\x11\xb3\x87\xaf\x8d\x70\xd4\x75\xa4\x03\x1c"
+  "\xb1\xf1\x28\x1c\xe2\x51\xd8\x7a\x27\x70\xc4\x8b\x47\x3d\xba\xbb"
+  "\x86\xa3\xee\xc7\x5c\xc7\x51\xf7\x75\xca\x71\xa4\xb5\x89\x47\x3d"
+  "\x96\xca\xc7\x51\xf7\xc9\xf2\x71\xd4\xdd\xdf\x35\x1c\xf5\xf0\x20"
+  "\x38\xf2\xaa\x26\x38\xea\x6e\xe2\x70\xc4\xec\x8b\x6c\x23\x1c\x79"
+  "\xad\x96\xc6\x91\x96\x8d\x47\x5a\x88\x47\xaf\xfd\xa2\x65\x1c\x69"
+  "\x79\xf1\x48\x3d\xc5\x35\x1c\xa9\x3d\x5c\xc7\x91\xf7\x19\x17\x70"
+  "\x64\x13\x8f\xd4\xc7\xe4\xe3\xc8\xbb\x40\x3e\x8e\xbc\xe3\x5c\xc3"
+  "\x91\x3a\x92\xe0\xc8\x5b\x43\x70\xa4\x1e\xcd\xe1\x88\xd9\x6b\xda"
+  "\x46\x38\xea\x51\x26\x85\x23\x9c\x8b\xe0\x3d\x92\x17\xa2\x7e\xe3"
+  "\x0a\xa4\x2d\xc2\x7f\x9b\x50\x48\x43\xb6\xba\xfe\x78\x2a\xc9\x07"
+  "\x00\xcf\xc9\xcc\xf7\x8a\x5d\xdf\x6d\x2f\xf8\xc5\x37\xd4\x10\x75"
+  "\x91\xe4\x68\xc0\x79\x41\xee\xa4\x27\xa2\x21\x38\x2f\x83\xaa\x67"
+  "\x30\xce\x63\x75\x3f\x77\x80\xaf\x44\xee\x80\x69\xd2\xb9\x03\x9a"
+  "\x36\x5b\xf7\xdd\xee\xe1\xf6\xdd\xaa\x7c\x1a\x1d\xee\xbb\x55\xf9"
+  "\x7c\x5f\x38\x4d\x2e\x1e\x7c\x98\xfd\x5f\x77\x7a\x85\x56\x35\x64"
+  "\xfb\x18\xa0\xcd\xa5\xa4\xed\x3d\x99\xfc\xc1\x2d\xef\xc7\xdd\xc3"
+  "\xc3\x89\x4f\xc1\x94\x58\x94\x41\xaf\xaf\x32\xd0\x7e\xa1\x06\x3a"
+  "\x3f\x4c\x5e\xfe\x2c\x55\x4f\xc9\xef\x1f\x12\x7b\x87\x25\x8b\xdb"
+  "\xfb\xb1\x02\x62\x6f\x36\x6f\x81\xaf\x44\xde\x82\x69\xd2\x79\x0b"
+  "\xc4\xed\xfd\x98\xe3\x7d\xce\xaa\xc7\x26\xc9\xb7\xf7\x63\x7d\x88"
+  "\xbd\xc3\xa2\x1b\xb2\x1f\x8b\xe3\xec\xfd\xd8\x05\xf9\xf6\x7e\xcc"
+  "\x8b\xd8\xfb\x4c\x0d\xed\x17\x96\x0c\xf6\xce\x90\xf9\x2c\x92\xf9"
+  "\xbf\x59\x7b\x4b\xe0\xdb\xcf\x8b\xb5\x37\x8b\x6f\x89\x9c\x09\xd3"
+  "\xa4\x73\x26\x88\xdb\xdb\xf7\xbc\x63\x7b\xfb\x1e\x97\x6f\x6f\xdf"
+  "\x2c\xd6\xde\x80\x6f\xdf\x2a\xce\xde\x7e\x4e\xe6\x15\xe0\xdb\xdb"
+  "\x37\x95\xd8\xfb\x9b\x6a\xb0\x37\xe0\x3b\x5c\x26\xbe\xfd\xfc\x1d"
+  "\xdb\x3b\x5c\x02\xdf\xbd\x52\x89\xbd\xd9\x7c\x0d\xbe\x12\xf9\x1a"
+  "\xa6\x49\xe7\x6b\x10\xb7\x77\xaf\xf1\x8e\xed\xdd\x6b\xa8\x7c\x7b"
+  "\xfb\x99\x88\xbd\xc3\x01\xdf\xbd\x22\x38\x7b\xf7\x3a\x2a\xdf\xde"
+  "\x7e\x75\xc4\xde\x7f\x2f\xa3\xfd\xc2\x01\xdf\xe1\x32\xf1\xdd\x6b"
+  "\x6d\x0b\xf6\x96\xc0\xf7\xe3\x75\xac\xbd\x59\x7c\x4b\xe4\x8a\x98"
+  "\x26\x9d\x2b\x42\xdc\xde\x8f\x1f\x71\x6c\xef\xc7\xdf\x97\x6f\xef"
+  "\xc7\xe7\xb1\xf6\x06\x7c\x3f\x5e\xcc\xd9\xdb\x3f\x58\xbe\xbd\x1f"
+  "\x8f\x25\xf6\x3e\x5b\x02\xf6\x06\x7c\x6b\x65\xe2\xfb\x71\xa3\x63"
+  "\x7b\x6b\x25\xf0\xdd\x3b\x96\xd8\x9b\xcd\x53\xe1\x2b\x91\xa7\x62"
+  "\x9a\x74\x9e\x0a\x71\x7b\xf7\x1e\xe8\xd8\xde\xbd\x7d\xe4\xdb\xdb"
+  "\xff\x02\xb1\xb7\x16\xf0\xdd\x5b\xc3\xd9\xbb\x77\x81\x7c\x7b\xfb"
+  "\x97\x11\x7b\x9f\x3b\x48\xfb\x69\x01\xdf\x5a\x99\xf8\xee\x9d\x28"
+  "\x65\x6f\x6f\xb0\xf7\x49\xe0\x31\xc0\x3b\x8c\x96\x3c\xe0\x29\x66"
+  "\xa1\xdd\x2b\x75\x5a\x34\xf8\x1e\xb6\xfd\x4f\xc6\xc1\x58\x6d\x6c"
+  "\xb7\x7c\x19\xaa\x9f\x0c\x75\x79\xef\xb0\xea\x09\xb3\xe4\xde\x61"
+  "\xd5\x13\x97\x65\xef\x1d\x56\x3d\x51\xcc\x71\xa0\x27\xea\x39\x9f"
+  "\xfe\x84\x89\x1f\xb2\xf6\x14\xab\x9e\xd8\x29\x9a\x47\x43\xf5\x44"
+  "\x34\xde\x53\x4c\xaf\xff\xc7\x1e\x4b\xbe\x12\x6e\xf4\x93\xc9\x2d"
+  "\xfb\x3a\x4c\x67\xc9\x03\x8e\x24\xe9\xeb\x27\x87\xc3\xb8\xa5\x6b"
+  "\xb7\xbc\x1d\xaa\x27\x9f\x74\xdd\xd7\x7d\xae\x4a\xfb\xba\xcf\x19"
+  "\xf9\xbe\xee\x53\xc0\xf1\xaf\x3e\x7a\xce\xd7\x4f\xca\xdf\x3f\xae"
+  "\xea\x93\x25\x9a\xcf\x43\xd5\x67\x24\xf1\x75\xb5\x97\x25\x5f\x09"
+  "\x2f\x7b\x32\xc2\x09\x5f\x43\xbf\x0e\x73\xd0\xaf\xfb\x69\xc0\xd7"
+  "\xc6\x76\xcb\x1f\xa2\xea\xd7\xc5\x75\x5f\xf7\x3d\x27\xed\xeb\xbe"
+  "\xc7\xe4\xfb\xba\xef\x5a\x8e\xfb\xf5\x2d\xe3\x7c\xdd\x2f\x4e\xbe"
+  "\xaf\xfb\xea\x44\xf3\x8a\xa8\xfa\x06\x11\x5f\x9f\x4f\x06\x5f\x2b"
+  "\xe0\x84\xfd\x82\x5b\xf6\x75\x38\xf4\xeb\x70\x07\xfd\xba\xbf\x17"
+  "\x8c\xd7\xba\x76\xcb\x63\xa2\xd2\xdc\x75\xdd\xd7\x9a\xe3\xd2\xbe"
+  "\xd6\xec\x95\xef\x6b\x4d\x0a\xc7\x3b\x35\x87\x39\x5f\xf7\x9f\x20"
+  "\xdf\xd7\x9a\x78\xd1\xfc\x26\x2a\x8d\x2f\xf1\xf5\xb7\x67\x2d\xf9"
+  "\x4a\xf8\x68\x7f\x49\xfe\xcf\xf3\x35\xf4\xeb\x70\x07\xfd\xfa\x29"
+  "\x23\xf8\xda\xd8\x6e\xf9\x54\x54\x4f\x7d\xef\xba\xaf\x9f\xda\x2f"
+  "\xed\xeb\xa7\xf2\xe5\xfb\xfa\xa9\x38\x8e\xf3\x3e\xb5\x8b\xf3\xf5"
+  "\xd3\x5a\xf9\xbe\x7e\x2a\x5a\x34\xcf\x8a\xea\x29\x44\x7c\x7d\x41"
+  "\x0b\xbe\x56\xc0\x85\x9f\x76\x6f\xd9\xd7\x5a\xe8\xd7\x5a\x07\xfd"
+  "\x3a\x00\x74\xbd\x56\xd7\x6e\x79\x5d\x54\x01\xe5\xae\xfb\x3a\x60"
+  "\xab\xb4\xaf\x03\x32\xe5\xfb\x3a\x60\x02\xc7\xb7\x03\x72\x38\x5f"
+  "\x07\x06\xc8\xf7\x75\xc0\x48\xd1\x7c\x2f\xaa\xa7\xeb\x88\xaf\x2f"
+  "\x16\x58\xf2\x95\xf0\xf0\x00\x83\x12\x1e\xbe\xa4\x10\x79\x0a\xfd"
+  "\x3d\xe0\x6c\xfb\x72\xf1\x01\xc7\x5c\xf7\xf7\x80\x75\xd2\xfe\x1e"
+  "\xb0\x48\xbe\xbf\x07\x8c\xe4\xb8\xf8\x80\x0c\xce\xdf\xcf\xf8\xca"
+  "\xf7\xf7\x80\x60\x71\x2e\x1e\x78\xc1\x35\x2e\x3e\x40\xaf\x84\x8b"
+  "\xdb\xfb\x3b\xe8\x44\xfb\xf2\xf1\xa0\xfd\xae\xfb\x3b\x68\xb9\xb4"
+  "\xbf\x83\x66\xca\xf7\x77\x50\x30\xc7\xc7\x83\x92\x39\x7f\x0f\x74"
+  "\x97\xef\xef\xa0\x3e\xe2\x7c\xfc\x99\x32\xd7\xf8\x78\x90\x64\xbe"
+  "\x70\x47\x7c\xdc\xde\xdf\xcf\x1e\x6c\x5f\x4e\xfe\x6c\xa1\xeb\xfe"
+  "\x7e\x36\x49\xda\xdf\xcf\x4e\x92\xef\xef\x67\xfb\x70\x9c\xfc\x59"
+  "\xde\xfc\xf7\xb3\xf5\xf2\xfd\xfd\xac\x97\x38\x27\x1f\x78\xd4\x35"
+  "\x4e\xfe\x6c\x89\x12\x4e\x6e\xef\xef\xe0\x5d\xed\xcb\xcb\x83\x37"
+  "\xb8\xee\xef\xe0\xa9\xd2\xfe\x0e\x1e\x25\xdf\xdf\xc1\x5e\x1c\x2f"
+  "\x0f\x8e\xe6\xfc\x1d\x2c\x3f\x7f\xa6\xea\x39\x93\x38\x2f\x7f\x6e"
+  "\x9f\x6b\xbc\x3c\xb8\x58\x09\x2f\xb7\xf7\xf7\xe0\xbc\xf6\xe5\xe6"
+  "\x83\x57\xba\xee\xef\xc1\xe3\xa5\xfd\x3d\x78\xa8\x7c\x7f\x0f\x32"
+  "\x71\xdc\x7c\x30\x6f\xfe\x7f\xf0\x59\xf9\xfe\x1e\x54\x27\xce\xcd"
+  "\x07\x15\xb8\xc6\xcd\x07\xef\x54\xc2\xcd\xed\xfd\x1d\xb2\xba\x7d"
+  "\xf9\x79\xc8\x7c\xd7\xfd\x1d\x32\x42\xda\xdf\x21\xfd\xe5\xfb\x7b"
+  "\x48\x1d\xc7\xcf\x43\x42\x38\x7f\x87\x9c\x90\xef\xef\x21\x17\xc4"
+  "\xf9\xf9\x90\x2c\xd7\xf8\x79\x48\x8e\xeb\xf3\xe4\x3f\x8d\xc3\xdc"
+  "\x5c\x6e\xfe\xc7\xca\x14\x76\xcf\x9d\x6a\x28\x97\xff\x51\xf5\x53"
+  "\xe6\xdb\x2a\xa2\xb9\x65\x54\xc3\xf6\x77\xe8\xfc\x8f\xaa\x61\x8e"
+  "\xf3\x3f\xaa\x86\xc9\xcb\xff\xa8\x1a\x96\x2f\x7f\x3d\xfe\xb0\x38"
+  "\x4e\x23\x0c\xe3\xe9\xff\x9f\x32\xfd\xba\x43\xe7\x85\x54\x0d\x13"
+  "\xe6\x85\x54\x0d\x65\xf2\x42\xd2\xeb\xbf\x43\xca\xb4\xc8\x4f\xe7"
+  "\xb9\xfe\x5e\x20\x6c\x24\xd6\x21\x72\xf3\x50\x72\xd8\x1e\x3e\x82"
+  "\xc3\x76\xd8\x20\x69\x6c\x87\xae\xeb\xd0\x79\x28\x55\xa1\xdd\x1d"
+  "\x63\x7b\x78\x9d\xac\x9c\x23\xaa\x50\xf9\x79\x6f\x54\xa1\x23\x39"
+  "\x3d\x14\xca\xd3\xbf\x61\xa9\xed\x87\x6d\x85\xf9\x29\x55\xa1\x1a"
+  "\x21\xb6\x87\x87\x10\x6c\x7f\x3f\x59\x99\xee\x0a\x1b\xe7\xfa\x7b"
+  "\x90\x11\xfe\x58\x73\xc9\xcd\x87\xc9\x61\x3b\xdc\x8f\xc3\xf6\x88"
+  "\x2e\xd2\xd8\xd6\x26\x74\xe8\x7c\x98\xaa\xf0\xab\x8e\xb1\x1d\x5e"
+  "\x2a\x2b\x97\x89\x4a\x1b\x29\x1f\xdb\x5a\x7f\x4e\xfb\x69\x63\x39"
+  "\x6c\x8f\x88\x69\x47\x6c\x2b\x8c\xdb\xe1\x26\x21\xb6\xc3\xbd\x08"
+  "\xb6\xff\xb3\x47\x99\xc6\x1c\x11\xe0\xfa\x7b\x9f\x9f\xd5\x63\x7d"
+  "\x29\x37\x2f\x27\x87\xed\x11\xb7\x38\x6c\xff\xcc\x2e\x2f\x14\x87"
+  "\xed\x9f\x8d\xea\xd0\x79\x39\x55\xcf\x9f\x74\x8c\xed\xe7\x77\xc9"
+  "\xca\x91\xa2\xfa\xd9\x40\xf9\xd8\x7e\xbe\x9e\xd3\xb9\x3f\xd3\x72"
+  "\xd8\x1e\x39\xbc\xfd\xb0\xad\x30\x5f\xa7\xea\xf9\x6a\x21\xb6\x47"
+  "\xd4\x12\x6c\x5f\x36\x29\xd3\xd3\x78\x08\x73\xf5\x3d\xd7\x8b\x55"
+  "\x58\x4b\xcb\xcd\x0f\xca\x61\x7b\x64\x39\x87\xed\x17\x8f\x4b\x63"
+  "\xfb\xc5\x27\x3b\x74\x7e\x50\xd5\x0b\x8e\xf3\xff\xa8\x5e\x70\x90"
+  "\xff\x47\x6c\xaf\xf0\x8b\xf2\xf3\x5e\xa8\x5e\xa8\xe2\x34\xfd\x8b"
+  "\xbe\x1c\xb6\x7f\xae\x6e\x47\x6c\x2b\x8c\xdb\x2f\x1c\x14\x62\x7b"
+  "\xe4\x09\x82\xed\xda\x68\x65\x73\x07\x2f\x5e\x70\xfd\xbd\xde\xa8"
+  "\x7d\x78\xde\x40\x6e\x9e\x52\x0e\xdb\x3f\xdf\xcb\x61\x7b\x54\xa1"
+  "\x34\xb6\x23\x1a\x3b\x74\x9e\x52\x55\xc4\x4a\xc7\xd8\x8e\x88\x95"
+  "\x95\xd3\x45\x15\xa1\x60\x1f\x7c\xc4\x3e\x6e\xfe\x22\x82\xb7\xfe"
+  "\x7d\x54\x5d\xfb\x61\x5b\x61\xfe\x52\x55\x44\x8e\x10\xdb\x3f\xdf"
+  "\x49\xb0\x7d\x6d\x97\xb2\x79\x92\x51\x87\x5d\x9f\x27\x19\x7d\x98"
+  "\x79\x87\x29\x33\x5f\x2a\x87\xed\x5f\xac\xb9\x9f\x9b\x48\x35\x7a"
+  "\xaf\x2d\xb6\xef\xe7\x26\x52\xbd\x74\xbc\xc3\xe4\x4b\x55\xbd\x34"
+  "\xc6\x31\x8e\x5f\x0a\x90\x37\x27\xf2\xd2\x5e\xf9\x38\x7e\x29\x85"
+  "\x9b\x13\x79\x89\xb7\xfe\x65\xb4\xf5\x9b\xe4\x6d\x9f\xb3\x48\x35"
+  "\x3a\xd2\x61\xce\x22\xd5\xe8\xe0\x36\xcb\xa3\xaa\x7a\x29\x46\x90"
+  "\xb3\x48\xf5\x8b\x54\x0b\xd3\x17\xea\x8c\xca\xe6\x55\x46\x9f\x70"
+  "\x7d\x5e\xe5\x65\xf2\x7e\x57\x66\xde\x56\xae\x2f\x8c\xc9\xe5\xfa"
+  "\xc2\xcb\x87\xa4\xfb\xc2\xd8\xf2\x0e\x93\xb7\x55\x35\x76\x92\xe3"
+  "\xbe\x30\x36\x44\xde\x1c\xca\x58\x05\x79\x60\xc6\x66\x70\x73\x28"
+  "\x63\x4f\x70\x7d\x61\x9c\x7b\xfb\xf5\x85\x97\xa7\x3a\xee\x0b\x2f"
+  "\x6b\xdb\x2c\x9f\xab\x6a\x6c\xbc\xb0\x2f\x8c\x59\x4b\xfa\xc2\xcd"
+  "\x54\x65\xf3\x30\x2f\x2b\x7a\xff\x2d\xec\x0b\xbf\xac\x62\xde\x7d"
+  "\xcb\xcc\x1f\xcb\xf5\x85\x71\x85\x5c\x5f\xf8\xa5\x1d\x9f\xe7\xfa"
+  "\xc2\xf8\xf3\x1d\x26\x7f\xac\x6a\xfc\x74\xc7\x7d\x61\xfc\x48\x79"
+  "\x73\x2e\xe3\x8f\xcb\xef\x0b\xe3\x79\xfb\x9f\xc6\xf3\xf6\x3f\xfd"
+  "\x4a\xdd\x7e\x7d\xe1\x97\x09\x8e\xfb\xc2\x2f\x47\xb7\x59\x5e\x59"
+  "\xd5\xf8\x64\x61\x5f\x18\x97\x47\xfa\xc2\x6d\xa4\x6c\xde\xe6\x97"
+  "\x4e\xf0\xff\x96\xe6\x6d\x22\x2f\x30\xeb\x02\x64\xe6\xb1\xe5\xfa"
+  "\xc2\xaf\xf6\x72\x7d\x21\xb2\x5c\xba\x2f\x4c\xb8\xdc\x61\xf2\xd8"
+  "\xaa\x26\x24\x39\xee\x0b\x13\xc6\xc9\x9b\xa3\x99\x50\x2e\xbf\x2f"
+  "\x4c\xd8\xc2\xcd\xd1\x4c\xb8\xc0\xf5\x85\x89\x7d\xda\xaf\x2f\x44"
+  "\x2e\x72\xdc\x17\x22\xa3\xdb\x2c\xbf\xad\x6a\x42\xaa\xb0\x2f\xfc"
+  "\x6a\x27\xe9\x0b\xf5\xab\x95\xcd\xf3\x44\xd6\xba\x3e\xcf\x13\x5d"
+  "\xcb\xac\x99\x90\x99\x4f\x97\xeb\x0b\x13\x0f\x71\x7d\x21\xfa\xbc"
+  "\x74\x5f\x88\xba\xd5\x61\xf2\xe9\xaa\xa2\x96\x3a\xee\x0b\x51\x93"
+  "\xe5\xcd\xe9\x44\x9d\x97\xdf\x17\xa2\x76\x71\x73\x3a\x51\xb5\x5c"
+  "\x5f\x98\x14\xd4\x7e\x7d\x21\x7a\xa5\xe3\xbe\x10\x1d\xdb\x66\x79"
+  "\x76\x55\x51\x6b\x85\x7d\x61\xe2\x3e\xd2\x17\x1a\x3c\x95\xcd\x0b"
+  "\x45\xd7\xbb\x3e\x2f\xf4\x6a\x3d\xb3\x9e\x44\x66\x5e\x5f\xae\x2f"
+  "\x4c\x3a\xce\xf5\x85\x57\xa5\xbf\xf3\xa0\x7a\xc5\xdc\x61\xf2\xfa"
+  "\xaa\x5e\x71\xfc\xfd\x23\xd5\x2b\x8e\xbe\x7f\x24\x32\x07\xf4\xca"
+  "\x65\xf9\x7d\xe1\x95\x62\x6e\x0e\xe8\x15\xde\xfe\xbf\xc9\xc3\xdb"
+  "\xaf\x2f\xbc\xea\xf8\xfb\x0f\xaa\x57\x9d\xf8\xfe\x83\xc2\x7c\xbf"
+  "\xaa\x57\xf2\x84\x7d\x61\xd2\x61\xd2\x17\x1a\xb3\x94\xcd\x23\x4d"
+  "\x6e\x71\xfe\x1f\xeb\xfc\x66\x5f\xfb\x79\xa4\xb2\x1a\x2d\x7a\x6e"
+  "\x1a\xee\x0b\x53\xf6\x98\xf2\x43\x8d\x38\xbf\xb0\x39\x80\xcd\x41"
+  "\x99\xc9\xe6\x78\xa9\x37\x91\x1c\x94\x06\xf3\xfd\x1c\x94\x24\xf7"
+  "\x07\xa2\xf0\x5e\x60\xbc\x27\xd8\xa4\x26\xf9\x27\x69\xbc\x26\x0a"
+  "\xaf\x91\xba\x54\xca\xe4\x57\x49\x35\x41\xdb\xaf\xb4\x90\x7f\x32"
+  "\x4e\x8f\xca\xe2\x56\x20\x93\xcf\xbe\x38\xb2\x4f\x78\x8a\x96\xc9"
+  "\x3f\x39\xc3\xff\x89\xec\x7f\x23\x5f\x6f\x9c\x7f\x32\x8e\xb6\xa4"
+  "\xeb\x69\x43\x85\x11\x41\x59\xb0\xef\x4c\x6b\x0e\xca\x29\xef\xe3"
+  "\xb6\x9b\x66\x04\x3d\xb1\xe3\xdf\x12\xf9\x85\x55\x53\xe4\xe7\x81"
+  "\x55\x4d\x99\xcc\xcd\xef\x4c\xd9\xc2\x61\x74\x0a\x33\x06\xc3\xdf"
+  "\x90\xb2\x18\x88\x31\xeb\x4d\xea\x66\x45\xb9\x37\xa6\x1c\x6c\xd9"
+  "\x67\xcc\x1a\x11\xbb\xf8\xc5\xf9\xec\x37\xb1\xa6\xfc\x30\x1d\xce"
+  "\x73\xec\xbc\xcf\x3c\x6e\xb7\x8d\xcf\x7e\x5d\xe7\xbc\xcf\x7e\x33"
+  "\xc5\xc6\x67\x22\xf3\x10\xbf\x79\x41\xbe\xcf\x7e\xe3\xc9\xcd\x43"
+  "\xfc\x66\x02\xe7\xb3\xdf\x14\x10\x9f\xfd\xba\x86\xf8\xcc\x3c\xb2"
+  "\x59\x51\xfe\x8e\xdf\xb4\xb8\xff\x1b\xeb\xa6\x66\x5f\x7b\x5d\xce"
+  "\xf9\x6c\xaa\x1a\x7c\x66\xc4\xf9\x96\x9d\xf7\x59\xb7\x4b\x6d\xe3"
+  "\xb3\x98\x9d\xce\xfb\x6c\x6a\x17\xa1\xcf\xc4\xf4\x72\x8c\xfc\x6f"
+  "\x76\xaa\x62\x8e\x72\x7a\x79\x2a\xe2\x7c\x36\x35\x9a\xf8\x2c\x66"
+  "\x0b\xf1\x19\x8c\xc7\x8a\x72\x80\x4c\xed\xd3\xb2\xcf\x98\x77\xfa"
+  "\x0e\xfa\xd9\xb4\x13\xa6\x7c\xd0\x98\xa0\x1f\x9d\xf7\x99\xcf\x37"
+  "\x6d\xe3\xb3\x69\x93\x9d\xf7\xd9\xb4\x63\x36\x3e\x13\xd1\x75\xd3"
+  "\x76\xcb\xf7\xd9\xb4\x64\x4e\xd7\x4d\x3b\xc8\xf9\xec\x35\x77\xe2"
+  "\xb3\x69\x13\x88\xcf\xe8\xbc\x66\x45\x79\x44\xa6\xb5\x38\xff\x85"
+  "\x79\x68\xb3\xaf\xbd\xce\xe1\x7c\x16\xab\x03\x9f\x19\x71\xfe\x69"
+  "\xe7\x7d\x16\xb6\xbe\x6d\x7c\x16\xeb\xe9\xbc\xcf\x62\x17\x09\x7d"
+  "\x26\xa6\x3f\x62\xa7\xca\xf7\x59\x6c\x00\xa7\x3f\x62\x13\x39\x9f"
+  "\xc5\x1e\x26\x3e\x8b\x45\x8c\xcf\xb2\x51\x49\xb3\xa2\x5c\x24\xb1"
+  "\xab\x5b\xf6\x19\xf3\x0e\xd6\x41\x3f\x7b\x3d\xd8\x94\x0f\x9c\x1d"
+  "\xf8\xb8\xf3\x3e\x7b\xed\x17\x6d\xe3\xb3\xe9\x47\x9d\xf7\xd9\xeb"
+  "\x81\x36\x3e\x13\xe1\xc9\xaf\x2b\xc8\x83\x3d\xbd\x9a\xe3\xc9\xaf"
+  "\xf7\xe1\x7c\xf6\xfa\x3c\xe2\xb3\xe9\x07\x89\xcf\xdc\xea\x9a\x15"
+  "\xe5\x33\x79\x5d\x32\xff\x97\x23\xde\x68\x5d\x97\xcf\xf9\x6d\x46"
+  "\x4d\xc7\xe1\x8e\x33\x52\x9c\xf7\xdb\x8c\x8b\x2d\x73\xc7\x19\x27"
+  "\xe5\xfb\x6d\x46\x0e\xc7\x1d\x67\x9c\xe5\xfc\x16\x17\x40\xfc\x36"
+  "\x63\x9e\x6b\xdc\x71\x46\x8b\xfb\x5f\xc5\xb8\xa3\xbd\xdf\x66\x16"
+  "\x74\x1c\xfe\x38\x33\xd8\x79\xbf\xcd\xcc\x6f\x99\x3f\xce\x5c\x29"
+  "\xdf\x6f\x33\xc7\x71\xfc\x71\x66\x16\xe7\xb7\x99\x17\x88\xdf\x66"
+  "\x06\xb8\xc6\x1f\x67\x4a\xe6\x7f\x73\xc4\x1f\xed\xfd\x36\x7b\x72"
+  "\xc7\xe1\x90\xb3\x6a\x9c\xf7\xdb\xec\xc8\x96\x39\xe4\xec\x50\xf9"
+  "\x7e\x9b\x8d\x38\x0e\x39\x7b\x34\xe7\xb7\xd9\x79\xc4\x6f\xb3\x2e"
+  "\xb8\xc6\x21\x67\xc7\x29\xe1\x90\xf6\x7e\x4b\xf0\xea\x38\x3c\x32"
+  "\xbe\xc0\x79\xbf\x25\x78\xb4\xcc\x23\xe3\xe5\x7f\xb3\x58\x15\x7f"
+  "\x98\xe3\x91\xf1\x26\xce\x6f\x09\xe4\x1b\x2c\xaa\xf8\x3c\xd7\x78"
+  "\x64\x42\x8b\xf9\x3f\xc4\x78\xa4\xbd\xdf\xe6\x9c\xe8\x38\x5c\x72"
+  "\x8e\x0c\xfe\x3f\xc7\x86\xff\x8b\x71\xc9\x39\x0a\xf8\xff\x1c\x2b"
+  "\xff\x87\xfe\x36\x87\xc7\xff\xdf\x60\xf9\xff\x9c\x09\xae\x71\xc9"
+  "\x39\x4e\xf0\x7f\x7b\x2e\x69\xef\xb7\xc4\xd4\x8e\xc3\x27\x13\xbd"
+  "\x9c\xf7\x5b\xe2\xd2\x96\xf9\x64\xa2\xfc\xef\x40\xa9\x12\x83\x38"
+  "\x3e\x99\x38\x8f\xf3\x5b\xe2\x51\xe2\xb7\x44\x77\xd7\xf8\x64\xa2"
+  "\x64\xfe\x47\xab\xdf\xcc\xbe\xa1\x46\x5a\x64\x1e\xb2\x3c\x51\xcb"
+  "\xe6\x26\x7c\x73\x82\xd9\x2f\xd4\x28\xf7\xfb\x2e\xd6\x9c\xd3\xa7"
+  "\x12\x11\xba\xa4\x9a\x7b\xd9\xb5\xbc\xd3\x73\xf3\x5d\xcf\x3b\x3d"
+  "\x77\x66\xeb\x7d\xdf\x65\xee\x78\xf9\x79\xa7\xe7\xfa\x72\x1c\x74"
+  "\x6e\x0c\xe7\xeb\x37\x99\xf5\x09\xf2\xf2\x51\x27\x55\xbb\x96\x8f"
+  "\x7a\xee\x45\x82\xaf\xa4\x2d\x24\x1f\xf5\xdc\xb3\xed\xf3\xdd\x97"
+  "\xa4\xd1\x38\x1f\x35\x9d\xad\xf2\x57\x96\x1f\xf9\xcd\x98\x96\xf1"
+  "\x1c\xa6\xa3\x45\xe6\x68\x39\x3c\x2f\xe8\x63\xf6\x0b\xd3\xc9\xfd"
+  "\xce\x8c\x10\xcf\xf3\x0f\xb9\x86\xe7\xf9\x09\xae\xe3\x79\xfe\xd0"
+  "\xd6\xfb\xce\xcc\xfc\xde\xf2\xf1\x3c\xaf\x86\xe3\xe6\xf3\x83\x38"
+  "\x3c\x2f\x88\x95\x8f\xe7\x79\x7b\x5c\xc3\xf3\xfc\xfd\x04\xcf\xf3"
+  "\x12\x09\x9e\xe7\xef\x6a\x9f\xef\xcf\xcc\xf3\x25\x78\xf6\x88\x53"
+  "\x96\x7f\x7a\x41\x90\x13\x78\x36\xd2\x22\xf3\xd7\x1c\x9e\x93\xeb"
+  "\x00\xcf\x46\xb9\xdf\xbb\x11\xe2\x39\x79\x8d\x6b\x78\x4e\x0e\x75"
+  "\x1d\xcf\xc9\x6e\xad\xf7\xbd\x9b\x85\x57\xe5\xe3\x79\xe1\x41\x4e"
+  "\xb3\x2c\x34\x72\x78\x5e\x14\x2c\x1f\xcf\x0b\x75\xae\xe1\x39\x79"
+  "\x25\xc1\xf3\x42\x2d\xc1\x73\x72\x4a\xfb\x7c\x07\x67\x41\x0d\xc1"
+  "\x73\xe7\x3d\xca\xf2\x7b\x27\x4b\xe6\x3f\xe6\xf0\x1c\xae\xa3\x45"
+  "\xe6\xf6\x39\x3c\x2f\x39\x6a\xf6\x0b\xd7\xc9\xfd\xee\x8e\x10\xcf"
+  "\x4b\x5c\xfc\xce\xc5\x92\x56\xf8\xce\xc5\x62\x17\xbe\x73\x61\xfb"
+  "\xdd\x9d\xc5\x47\xe4\xe3\x79\xf1\x6a\x4e\xcb\x2d\x2e\xe5\xf0\xbc"
+  "\xc4\x24\x1f\xcf\x8b\xc7\xb9\x86\xe7\x25\xec\xf7\x2f\x16\x7b\x12"
+  "\x3c\x2f\x19\xdd\x3e\xdf\xe3\x59\x74\x90\xe0\xb9\x8b\x41\x59\xfe"
+  "\xf4\x25\xa5\x4e\xe0\xd9\x48\x8b\xbc\xf7\xe0\xf0\xbc\x2c\x0b\xf0"
+  "\x6c\x94\xfb\xfd\x1f\x21\x9e\x97\x05\xba\x86\xe7\xa5\xe7\x5c\xc7"
+  "\xf3\xd2\xf7\x5b\xef\xfb\x3f\x4b\xd7\xc9\xc7\xf3\xd2\xc9\x9c\xc6"
+  "\x5d\xca\x7b\xff\xbf\xac\x4c\x3e\x9e\x97\xba\xf8\x5d\xa0\x65\x4f"
+  "\x12\x3c\xa7\xb0\xdf\x05\x5a\xe6\xdb\x3e\xdf\x05\x4a\x59\x4d\xf0"
+  "\xec\xa5\x55\x96\x9f\x7e\xd9\x96\x96\xf1\xac\xd5\xd1\x22\xef\x84"
+  "\x38\x3c\x2f\x8f\x35\xfb\x69\x75\x72\xbf\x43\x24\xc4\xb3\xee\xae"
+  "\x6b\x78\xd6\xed\x76\x1d\xcf\xba\x45\xad\xf7\x1d\x22\xdd\x54\xf9"
+  "\x78\xd6\x05\x70\xda\x5f\xc7\x7b\xff\xb7\x5c\xc1\xf7\x89\xde\xaa"
+  "\x75\x0d\xcf\xba\xeb\x04\xcf\x6f\xed\x21\x78\xd6\xd5\xb4\xcf\xf7"
+  "\x89\xde\x9a\x4c\xf0\xdc\x23\x43\x59\xfe\xff\xe5\x2d\xae\xff\x10"
+  "\x9b\xdf\xb0\xce\x4b\x71\x98\x4e\x0d\x71\x7d\x8e\xe3\xed\x53\xae"
+  "\x61\xfa\xed\xe5\xae\x63\xfa\xed\x31\xad\x37\xc7\xf1\xb6\x82\x6f"
+  "\xfd\xad\x30\x72\x73\x1c\x6f\x8f\xe4\x30\x9d\x9a\x2c\x1f\xd3\x2b"
+  "\x8e\xba\x86\xe9\xb7\x8f\x13\x4c\xaf\x48\x25\x98\x7e\xfb\x70\xfb"
+  "\xcc\x71\xac\x08\x72\x6d\x8e\x23\x75\xa4\x92\x39\x0e\x7b\x4c\xa7"
+  "\xbb\xbb\x3e\xcf\x91\x56\xe8\x1a\xa6\xd3\x22\x5d\xc7\x74\x5a\xef"
+  "\xd6\x9b\xe7\x48\x73\x93\x8f\xe9\x95\x65\xdc\x3c\x47\x9a\x9a\xc3"
+  "\x74\xfa\x68\xf9\x98\x5e\x99\xe3\x1a\xa6\xd3\xf2\x09\xa6\x57\x46"
+  "\x13\x4c\xa7\x65\xb5\xcf\x3c\x47\xaa\xc9\xb5\x79\x8e\x74\xb5\x92"
+  "\x79\x0e\x7b\x4c\x67\x56\xbb\x3e\xd7\x91\xb9\xc8\x35\x4c\x67\xf6"
+  "\x77\x1d\xd3\x19\xd7\x5b\x6f\xae\x23\xe3\x9c\x7c\x4c\x67\xec\xe4"
+  "\xe6\x3a\x32\x6a\x38\x4c\xaf\xf2\x97\x8f\xe9\x8c\x78\xd7\x30\x9d"
+  "\x99\x44\x30\x9d\x11\x40\x30\x9d\x19\xd7\x3e\x73\x1d\xe9\x55\xae"
+  "\xcd\x75\x64\xd6\x28\x99\xeb\xb0\xc7\xf4\xea\x7d\xae\xcf\x77\xac"
+  "\x1e\xe3\x1a\xa6\x7f\x7b\xd7\x75\x4c\xff\xf6\x78\xeb\xcd\x77\xfc"
+  "\x76\xaf\x7c\x4c\xff\x96\xf7\xfd\x8b\xdf\xf2\xf6\xff\xaf\xae\x93"
+  "\x8f\xe9\xdf\x6a\x5d\xc3\xf4\xea\x17\x08\xa6\x57\x19\x09\xa6\x57"
+  "\x0f\x6f\x9f\xf9\x8e\x55\xbb\x5c\x9b\xef\x58\xdd\x62\xfe\x0b\xb1"
+  "\xf9\x0e\x7b\x4c\xff\x2e\xc3\xf5\x39\x8f\xdf\xf5\x76\x0d\xd3\xef"
+  "\x9c\x72\x1d\xd3\xef\xe4\xb7\xde\x9c\xc7\x3b\x2b\xe5\x63\xfa\x9d"
+  "\x71\xdc\x9c\xc7\x3b\xbc\xf5\x4f\xbf\x2b\x91\x8f\xe9\x77\xbc\x5c"
+  "\xc3\xf4\xef\x7c\x08\xa6\xd7\x94\x11\x4c\xff\xce\xb3\x7d\xe6\x3c"
+  "\xd6\xe8\x5c\x9b\xf3\xf8\x5d\x96\x92\x39\x0f\x7b\x4c\xaf\x9f\xec"
+  "\xfa\xbc\xc7\xba\xeb\xae\x61\x7a\x5d\xa1\xeb\x98\x5e\x97\xd4\x7a"
+  "\xf3\x1e\xeb\x26\xc9\xc7\xf4\xba\x3e\xdc\xbc\xc7\x3a\x5e\xfe\xfb"
+  "\xf5\x79\xf2\x31\xbd\x56\xef\x1a\xa6\xd7\x5d\x26\x98\x5e\xbb\x93"
+  "\x60\x7a\xdd\x85\xf6\x99\xf7\x58\x3b\xc1\xb5\x79\x8f\xf5\x71\xb6"
+  "\x98\x5e\x92\xb0\x20\x5e\xb3\x70\xce\x9c\x25\x09\x29\x9a\x25\xf3"
+  "\x92\x66\x27\xbc\x10\x68\xfd\xff\x0b\x21\xba\x40\x5d\x57\x14\x3f"
+  "\x7f\xe6\x8c\x65\xc3\xb8\x93\xf3\x12\x16\xc0\x9f\xae\x28\x71\xe6"
+  "\x92\x44\x4d\xca\xf2\xe4\x04\x0d\xfe\xdf\xfc\xd9\xc9\x50\x64\x61"
+  "\x0a\x77\xe4\x95\x84\x79\x33\x75\x49\x0b\xde\xd0\xcc\x9c\x97\xf4"
+  "\xc6\x82\xf9\x09\x0b\x52\x34\x8b\x13\x16\x2d\x4d\x5a\x9c\x80\xff"
+  "\xbd\x44\x33\x67\xe1\x62\x38\x30\x3b\x21\x69\x59\x82\x66\xd6\xd2"
+  "\x39\x73\x12\x16\x2f\xe9\x8a\x22\x97\xce\x4b\x49\x4a\x9e\x97\xa0"
+  "\x19\x1d\x39\x6a\xd0\xe4\x31\xaf\x4e\xfe\xf9\xcf\xbb\x22\xde\xb7"
+  "\xa7\x35\x74\xde\x54\xdc\x2f\xdc\xaf\xa8\x36\x2f\xaf\x00\xd6\xb9"
+  "\x01\xb0\xb9\x71\x31\x52\xaf\x5f\x8c\xdc\xd7\xdd\x46\x9e\x1b\x6e"
+  "\x23\x2f\xcb\x26\x93\x4e\x33\x17\x45\xd0\x3e\x8b\x32\x36\xde\x46"
+  "\xbe\x96\xdc\xbd\x55\x74\xee\xde\x1c\x83\xcf\xa6\x0c\x5c\x96\xf6"
+  "\xc9\x3d\x8c\x8f\x83\x2f\xdc\xe9\xdc\x7d\x11\x97\x54\x9b\xb5\x06"
+  "\x9f\xf7\xe2\xd2\xaf\x22\x8a\xee\xf1\x6e\xc9\x01\x8b\x81\x3a\x8e"
+  "\x59\x01\xd8\x0a\xa9\xb2\xaa\xe1\x77\x02\xa9\x36\xa4\xc0\x6f\x35"
+  "\xfc\xaa\xe0\x67\x44\xaa\x6c\x04\xbf\x79\xf0\x2b\x86\x9f\x1e\x7e"
+  "\x75\x48\xb5\x11\x8e\x6d\xf4\x85\x5f\x1f\xf8\xad\x85\xdf\x1e\xf8"
+  "\x1d\x86\x5f\x15\xa9\x67\x23\xfc\x72\x62\xe0\x97\x01\xbf\x2d\x48"
+  "\x95\x3b\x01\x7e\x50\x47\x2e\xd4\x97\x0b\x75\xe7\xe6\xc0\x0f\x1f"
+  "\x3f\x08\x3f\x5c\xfe\x02\x39\xb7\x69\x17\xfc\xe0\x1e\xef\x41\xfd"
+  "\xef\x41\xdd\xef\x45\xc3\x2f\x1e\x7e\xc9\xf0\xd3\xc1\xaf\x00\x7e"
+  "\x50\xe6\x3d\xb8\x57\x1e\x9c\xcb\x83\x7b\xe4\xa5\xc2\xef\x2c\x52"
+  "\x41\xe0\x53\xe5\xc3\xb3\x6c\xd6\x92\x5f\x3e\x3c\xcb\x66\x5f\xee"
+  "\xff\x9b\x43\x78\xff\x16\xfb\x45\x7b\x67\xf6\xd3\x97\x3c\x6b\x82"
+  "\x7e\xbb\x21\x94\x5e\x85\x54\x74\xee\x7b\x71\xc9\xcf\x22\xb7\x6b"
+  "\xaa\x0d\x6e\x95\xab\x11\xc4\x9b\xbd\x39\x25\x2b\x9a\xf0\x79\x37"
+  "\x6c\xb3\x86\xec\x0d\x48\x8f\xe6\x69\x71\xff\x94\x87\xcf\x0d\x88"
+  "\xbd\x3e\x42\xef\xd6\xb5\x18\x5f\x4f\x6f\x0a\xdb\x49\xa7\xc7\x6c"
+  "\xc7\xfb\x70\xaf\x80\x0d\xf1\x3e\x5d\x3a\x27\xcc\x9f\x56\x87\x9c"
+  "\xc0\x31\xa6\x64\x05\x7e\xae\xac\xf3\xa4\x3f\xc2\x79\x78\x36\x83"
+  "\x8f\x49\x07\xfd\xcf\x1d\xff\x9f\x06\x9f\xd3\x3b\x67\xd7\x92\xb8"
+  "\xb3\x81\xd1\x2f\x4d\x7e\x91\x21\xf8\x5c\xe3\xee\x40\x3d\xbd\x4b"
+  "\xab\x2b\x59\xd0\x84\x6a\x54\x59\xe7\xa0\x6d\x14\xc4\x40\x8a\x1e"
+  "\x10\xa8\xb7\x6c\x8e\x0c\x39\x02\x38\xc0\xe5\x3e\x4f\xab\xc5\x7f"
+  "\xcf\xe2\xf3\x74\x5e\xa4\x11\xcf\x03\x95\xa4\x7d\x00\x71\x39\xeb"
+  "\x7c\x93\xdf\xec\x2a\xcd\x2b\xde\xf4\x25\xd5\x86\xf9\xf0\x6c\x4c"
+  "\x79\xeb\xb3\x34\xf9\x98\x32\x70\xfd\xb4\x26\x3e\x07\xce\xb9\x5b"
+  "\x72\x37\x65\xc0\x73\xb8\xdd\x80\xeb\x68\x78\xc6\x92\x57\xf0\x7d"
+  "\xb3\x13\xe0\x59\xa9\xf4\x49\x50\xf7\x07\xf1\x39\x9f\xac\x30\x52"
+  "\xf8\x9c\x25\xc7\xa4\x03\xbc\x7b\xd1\xd9\xeb\x77\x6e\xeb\x89\xdc"
+  "\x8b\x36\x21\xb4\x63\x13\xf2\x6c\xc8\xce\x8e\xd5\xbb\xf7\x99\x4c"
+  "\x62\x5f\x56\x35\x05\x65\xf4\xaa\x6c\x2d\x0d\xf8\x65\xee\xe5\x3b"
+  "\x2e\xd9\xc1\xbd\xf6\xde\xbf\xd7\xe6\x71\xc9\xf8\x5e\xc4\x46\x26"
+  "\x1d\xf9\x4b\xea\xb0\xec\x1a\x90\x83\xed\x87\x6d\x67\xad\xc3\x92"
+  "\x6b\xad\x63\xc3\x29\x7c\x3d\xdc\xb3\x80\xfe\x70\x40\x8e\x65\x73"
+  "\x54\x0e\xf8\x4d\x87\xcf\x7b\x67\xa2\x7a\x1a\xfe\xe2\xfb\x13\x5f"
+  "\x80\xed\xa9\x0c\x84\xeb\xa7\xd9\x63\x34\x1c\x83\x6b\x6b\x2c\xab"
+  "\x34\x80\x9b\xf0\x44\xe2\xd7\x8d\x43\x97\x57\xd1\x16\xf8\x99\x87"
+  "\x54\x21\xb7\x92\x57\xb0\x4f\x37\x46\x6b\x26\x76\x06\xbb\x6e\x9c"
+  "\x74\xdf\x9e\xfd\xe3\xd7\x82\x4d\xd4\x45\x3d\xc1\x2e\xef\xb8\xef"
+  "\x61\xea\x80\xf6\xf0\xed\x83\xdb\xd0\x90\xbd\x31\xc3\xc6\x46\x6a"
+  "\x38\x96\xa7\x77\x73\xd7\xe3\x63\x9a\xa7\x18\x2c\x9d\xa7\x59\x7f"
+  "\x61\x3c\x63\xdf\x59\xf2\xf1\xbe\xb5\xac\xea\x29\x03\x91\xda\xbb"
+  "\x0a\x51\x9a\xb4\x80\xc3\xc4\xc7\x91\x46\x78\xe6\x3d\xf8\x5e\xf0"
+  "\xd7\x40\x6f\x7e\x7e\x9c\x79\x15\x8c\xa1\xf7\x71\x95\xa3\x36\xe7"
+  "\x86\xc7\x35\xf9\x4d\x2c\x6e\xcc\x7f\x39\x99\xce\x09\x8f\xc3\xfb"
+  "\xca\x2f\xa9\x72\x98\xbd\x76\xf4\x2a\x4f\x44\xee\x13\x1e\x9f\x36"
+  "\x8f\x36\xa4\xdd\x02\xfb\xf7\x9a\x58\xfc\xf9\x32\x03\xf8\xe1\xe5"
+  "\x64\xec\xe7\x23\xf7\x8c\x14\xce\xf5\x47\xf7\x58\xff\x97\x1d\xd0"
+  "\x9e\x42\x68\x0b\xb4\x13\xe1\x7a\x1b\xb2\x73\xa2\xb9\xf6\x6c\xac"
+  "\xc7\x3e\x87\x7b\xe8\xc8\xbd\xa1\x5e\x0a\xee\xe1\x13\xae\x83\x72"
+  "\x3a\xbd\x5b\x71\x80\xb5\xdd\xcc\xbd\xb9\x72\x6c\x1f\xc9\x99\x67"
+  "\x80\xb2\xcd\xcb\xe8\xaa\x8d\xdf\x42\xfd\xab\x10\xdd\x74\x8f\x2e"
+  "\x4b\x8d\xa6\x8d\xd9\xbf\xc6\xeb\x17\x2f\xa0\xf4\x99\xa8\x4f\xb7"
+  "\x4c\x1a\xb8\x3a\xf2\xee\x76\xc1\x9b\x2e\x8f\xbe\xc0\x7c\xf3\x20"
+  "\xb5\x8a\xae\xad\x48\x3e\x8a\x52\x2f\x23\xaf\x95\x49\xc8\x37\x3d"
+  "\x1a\xda\x52\x46\x1b\x2b\x75\x17\x50\x45\x3d\xfc\x92\xcb\xa1\xdc"
+  "\x39\xf8\x1d\x45\xe9\xcb\x91\xfb\x44\x18\xcf\xd2\xee\x22\xaf\x8a"
+  "\xe4\xbb\x70\xec\x3a\x4a\x8d\xa3\x4d\xe5\x65\xb8\xdc\x49\x14\x65"
+  "\x32\x78\xaf\xbc\x8e\xdc\x77\xfc\x1a\xef\xd5\xbe\x88\x8a\xe0\x59"
+  "\x9a\x7c\xf6\x96\x34\xe6\xee\x1b\x77\x67\x19\x6d\x6a\xc8\xce\x1d"
+  "\xad\x47\xcf\x6b\x04\x6d\xc1\xcf\xdc\x84\x10\xf8\xca\x0d\x97\xb1"
+  "\xe4\x8f\x8d\x9e\x61\xc2\x71\x23\x57\x0b\x7c\x02\x59\xcf\xe3\x73"
+  "\x06\xbf\xb1\xd1\x70\x3c\x3e\xca\x44\x37\x80\x9f\x99\x76\x83\xfd"
+  "\x53\xd8\xf6\xa7\xa8\x92\x91\x3b\xdc\x63\x8f\xde\xed\x4f\x08\xdf"
+  "\x03\xea\xec\x04\x38\x8e\xc7\xd8\x60\xcf\x9d\xd0\xbb\x7d\x3a\x8e"
+  "\xc3\x0b\xe3\xff\x4e\xd6\x67\x81\xf3\x35\x7a\xb7\xcf\xa2\x79\x78"
+  "\xc2\xf1\xe1\xfe\x79\x76\x9c\xc2\x31\x67\x9e\x05\xc7\x4c\x75\xc8"
+  "\x16\xb3\xdf\x44\xe8\x0b\x66\x35\x7d\xc7\xdf\x8b\xa6\x68\xe3\x44"
+  "\x13\x6d\xb4\xe4\x8f\x88\x86\xb1\xc8\xab\xd2\x54\xcf\x96\xdf\xb4"
+  "\x8e\xce\x35\xfb\x93\xb5\xa1\x9b\x16\xe1\x3a\x81\xb3\x14\x67\xdf"
+  "\x46\xea\xa8\x2a\xda\x88\xfb\xa5\x25\xdf\x23\x27\x7b\x31\xf2\xa5"
+  "\xf3\x23\x0d\x16\xbf\xf1\xa8\xf1\xfd\xd9\x7a\x1c\x3b\x69\xbf\xa9"
+  "\x88\xce\x81\x6b\xd9\x7a\xe0\xbe\x1e\x7a\xd5\xa6\x71\x16\xb8\x9e"
+  "\xce\x1b\x11\xcd\xe2\x80\x89\x73\x24\x3e\x6e\x1a\x47\x07\xc2\xb9"
+  "\x9c\x90\x02\x38\xe7\x71\x49\xb5\xe9\x2c\x1c\x87\x3a\x42\xce\x96"
+  "\xa4\xdd\xc6\x75\x9c\x27\x18\x0a\xd9\x22\xf8\x3f\x85\xed\x99\x5d"
+  "\x8f\xfb\x35\xe1\x97\x9b\x1a\xb9\x7e\x6b\xed\x27\xd0\x5f\xfd\x46"
+  "\x00\x76\xdf\xf3\xd2\xbb\xf5\xf0\x62\x62\x39\x5c\x57\xcf\xc4\x9a"
+  "\x8d\x9e\xc0\xc5\x6a\xff\x1a\x8d\xd0\x5f\xcb\x10\x82\x32\x21\x7a"
+  "\x37\xb5\x86\xb3\xe5\x7b\xe3\x71\x59\xa6\x4f\x42\xdf\x24\xf7\x03"
+  "\x9c\xc3\x35\xf4\xe6\x89\x38\xf7\x8a\x3b\x8e\x33\x7a\xd5\x7b\xa3"
+  "\x71\x8c\x81\x7e\xe7\x49\xe2\xf9\x80\x44\xa6\x7f\x6e\x9a\x5b\x0c"
+  "\xcf\x95\x71\x89\x7d\x16\xfe\xb3\x59\x63\x09\x9d\xfb\x66\x08\x29"
+  "\x1b\x9e\x01\xf7\x2f\x86\xfb\x1b\xf9\x58\x23\xed\xca\x0b\x1c\x52"
+  "\x06\xff\x06\xbe\x61\xad\x0b\xfa\xaa\x27\xc4\xe4\x6f\x31\x06\x71"
+  "\xcc\xd9\xba\x09\xc7\xda\x37\xb5\x8d\xb9\x6f\x46\x40\x3d\x46\x6b"
+  "\x3f\xb5\x2c\xa3\xab\xc1\xaf\xc8\x72\x8f\x3e\xbb\x11\x7c\x19\x65"
+  "\x56\xd1\x33\xcc\xc1\x08\xf8\xa8\xa9\x08\x8e\x17\x2d\xc3\x7c\x2e"
+  "\x77\x38\xf4\x65\x4f\xf1\xb2\xee\x08\x97\x63\xca\xb3\x65\x9b\x7c"
+  "\xde\xd4\x32\xcf\xbc\x4a\x65\x81\xe7\x73\xb3\x3e\x53\x93\x4f\xf8"
+  "\xbc\x86\xec\xbc\x14\x3d\xa2\xbd\x04\xfd\x65\xd3\x90\xc3\x34\x1d"
+  "\x83\x71\xa5\x82\xb6\x6c\x85\xbf\x9d\x59\x9c\x76\xfb\x2b\xf0\xd5"
+  "\xd1\x91\xd0\x57\xc0\xdf\xdb\x7a\xd1\x06\xb8\xfe\xa0\x1e\xbd\x9e"
+  "\x87\xaf\x5f\x0f\xff\xc7\xc7\x71\x19\x38\x5e\xa6\x47\x33\x56\x93"
+  "\x7a\xb3\xeb\xb1\xff\x6c\xea\xbd\x45\xea\x65\x9e\xa5\x1b\xae\x13"
+  "\x5f\x87\xeb\x2c\xdc\x4c\xd7\xe1\x7a\x1a\xb2\xf3\xd5\xd6\xba\x37"
+  "\xc0\x31\x6b\xfd\xa3\xe7\x5b\xef\x91\x1f\x02\xf7\x10\x3c\xfb\xd6"
+  "\xcd\x74\x3d\x79\xae\xfc\x09\x7a\x34\x27\x16\x9f\x5b\x07\xc7\xf0"
+  "\xb5\xbc\xfe\xa6\xe2\x30\x94\x0f\xed\x8f\xaf\xe1\xc7\x77\xf0\x51"
+  "\x77\x2b\x27\x60\xeb\xda\x62\xad\xcb\xb6\x1e\x3a\x67\x9e\x86\xd7"
+  "\x5f\xbd\x70\xbd\x50\xbe\x54\x8f\x66\x06\x91\xe7\xda\xa0\xab\x27"
+  "\x78\x07\xbb\xe7\x5f\xc7\x76\xc7\x63\x8d\x65\x15\xcb\x3b\xde\x9f"
+  "\x5d\xcb\x62\xa3\xd6\x3a\x1e\x81\x5f\x12\x1b\xb2\x37\x7b\x71\xb1"
+  "\x3b\x5f\x8f\xfd\x0d\xc7\x63\x48\xfd\x9b\x83\xf4\xc8\x52\xc6\x6f"
+  "\x37\xf4\x0d\x77\x18\x1b\x34\x38\x66\xb1\xcf\xe3\x86\xc7\x27\xeb"
+  "\x79\xb8\x87\xbb\x25\x7b\x7d\x13\xee\x13\x30\xde\x41\x9f\x1f\xab"
+  "\x87\x7a\x92\x6d\xc6\x3b\x77\x52\xee\xdd\x21\xb8\xcc\x7b\xbd\xe8"
+  "\x5a\x28\x93\x67\x2d\x83\xcf\x83\xfd\x5f\x84\x63\x7b\xf4\x68\xee"
+  "\x3c\x7c\x2c\x1b\xca\xe8\x55\xef\xda\xe9\x03\x2b\xf7\x4e\xeb\x8f"
+  "\xa8\xca\x02\x3d\xd6\x8e\xb8\xff\x8f\xac\xec\x53\x8f\x2a\x0b\x2c"
+  "\xc8\xf2\xe1\x33\xea\x88\x34\xba\xe4\x8a\xea\xf7\x81\x15\xc6\x5a"
+  "\x99\x1a\x7b\x33\xb3\xff\x8d\x6e\x02\x8d\x93\x3a\x0c\x61\x2e\x70"
+  "\x43\xb5\x65\x4a\xa5\xe1\x36\x13\x0b\xe1\xdf\xa3\xf0\xf9\xf7\x40"
+  "\x13\x61\x5d\x04\xda\x37\x31\x87\x22\xda\xc8\x02\x65\x77\xe0\xe3"
+  "\x58\x37\x81\x66\x2b\xe2\x9d\xa3\x3f\x0c\xcc\x21\xb6\xdb\xd2\x1d"
+  "\xdb\x91\x79\x5e\xd3\xcb\x25\xf8\x99\x2d\xbb\x02\x73\x70\x1b\xd2"
+  "\x75\xb4\xa5\xd2\xd4\x50\x52\x51\x6f\x46\x9a\x65\x58\xd3\xfd\xfe"
+  "\x6a\x54\x21\xa2\x21\x56\xe6\xc8\x6b\xc3\xef\x99\xf5\x7f\xa0\x7b"
+  "\x6f\x18\x02\x03\x73\xd2\xcd\x88\xda\x98\xe6\xe1\xf9\x52\x01\x5d"
+  "\x72\x67\xc0\x33\xc0\x3b\xb6\x78\x1d\xd7\x21\x24\x9f\x0b\x6f\xf1"
+  "\xb2\xb6\x7d\x07\xdb\x76\xb8\x17\xb3\x5f\x74\xc8\x96\x0c\xa6\xbd"
+  "\x50\x66\xb4\x94\xbf\xe8\x55\xde\xf4\x5f\x0b\x4c\x68\x49\x01\xdd"
+  "\xb4\xa4\x10\x51\xe6\xcd\xcf\x57\x7d\xb2\xa3\x1a\xc7\xfd\x08\xab"
+  "\x3d\x19\xdb\x81\xde\x4f\x4e\x43\xea\x6b\xaa\x2d\xd7\xa3\x52\x33"
+  "\x98\x6f\x24\x7d\x09\xe5\x64\x3e\x2b\x33\xff\x57\x01\x3a\x3a\xca"
+  "\x94\x4e\x93\xb1\x6b\xab\xdf\x44\xb6\x3e\x7c\xce\xea\xbf\x1d\xac"
+  "\xbe\x95\x7f\x8f\xad\x92\xfb\xff\x1d\xb4\x55\x2d\xde\xd6\xad\xe7"
+  "\x95\xb7\x75\xeb\x2e\xfb\xb6\x6e\x73\x6b\xdd\xb6\x6e\xf3\x54\xd0"
+  "\x56\x8d\x78\x5b\xb7\x9d\x54\xde\xd6\x6d\x39\x22\x6d\xbd\xde\xca"
+  "\x6d\x95\xcc\xff\xe4\xa0\xad\x21\xe2\x6d\xdd\xfe\xa9\xf2\xb6\x6e"
+  "\x4f\xb5\x6f\xeb\xf6\xf3\xad\xdb\xd6\xed\x7a\xc9\xb6\x52\xde\x34"
+  "\x8e\x4f\x10\x97\x9a\xd2\x1a\x81\xf3\x6d\x8e\xde\xb9\xf2\x7d\x44"
+  "\x95\xd5\x1b\x51\x45\x9f\x6a\xcc\xa7\xa9\xc1\xc9\x0c\x27\x1a\x49"
+  "\x6f\x32\xe5\x54\x14\xd4\xc1\xf1\x2b\xa8\x5c\x67\x44\x11\x8b\x71"
+  "\xfc\x2d\xd8\x5d\x19\x2f\x37\xfe\x16\x24\xdf\x8f\xbf\xa6\x61\x6c"
+  "\xcc\x2d\x3c\x53\x51\xd7\x84\x70\xfb\xe1\xdf\xc7\xee\xc7\xdf\x55"
+  "\xc4\xde\xb6\xf1\x17\xdb\xa3\xd2\x68\x14\xc4\x5f\xb2\x4f\xaa\x70"
+  "\x9d\x6d\xec\xcd\xbe\x86\x90\x78\xec\x2d\x4c\xc0\xb1\x77\x07\x9c"
+  "\x97\xf7\xfc\x85\x21\xd6\xd8\x9b\x03\xf7\xe4\xc7\xde\xbf\xc6\xe3"
+  "\xf1\xb5\x70\xad\xb2\xd8\x5b\xb8\xd6\xda\xee\x42\xb6\xdd\x60\xab"
+  "\x3a\x61\xec\x2d\x2c\x71\x06\xb7\xf4\xe6\xd0\xe2\x4f\xfa\x1a\x3d"
+  "\x2c\xbb\x9e\xa9\xc2\xe3\x5b\x03\xd8\xe4\xcf\x3b\x8c\xee\x57\x54"
+  "\x3b\x22\x98\xf9\xcc\x86\x78\x37\x7a\xd7\x00\x5d\x54\x0a\xfd\x1d"
+  "\x1d\xf8\x4c\x15\x9e\xab\xc4\x9a\x1b\xce\x2f\xa5\x77\x0f\xd0\xc9"
+  "\x7b\x6e\x52\x27\x8c\x7f\xea\x34\xe8\x2f\x9f\x2c\x33\x52\x96\xb7"
+  "\x63\xbc\xc1\x0f\x6a\x3a\x7f\x84\x81\x7e\xe7\xb1\xe4\x3b\xf9\x51"
+  "\x71\x27\x83\x2e\x23\x5c\x96\xce\x74\x1f\xa9\xfc\xf9\x8b\x90\xe3"
+  "\xe7\x2f\x0a\x95\xff\xfc\xa4\x4e\xe7\x9e\xbf\x08\x39\xf5\xfc\xbd"
+  "\xe0\xf9\x9b\xb4\x1e\xa0\x13\xa9\x2f\x9b\xb4\xee\x32\x9f\x47\xf2"
+  "\xfb\x77\xad\x78\x0f\xa7\xe3\x1f\xdd\x6b\xac\xe1\x93\x1d\x06\x0a"
+  "\x62\x00\x33\x86\xe3\xbe\x47\xe2\x5f\x2d\xc4\xac\xef\x68\x12\x93"
+  "\x0c\x32\x63\xd2\xce\x14\xe7\xef\xff\xb3\xe8\x36\xb8\xbf\x74\xfb"
+  "\x6d\x63\xe2\x01\xad\x41\x32\x26\x6e\x7e\x3e\xda\x3e\x26\xbe\x7f"
+  "\x44\x7e\x4c\x7c\x7f\xb5\x7d\x4c\xfc\xe0\x32\x17\x13\x3f\x38\xa3"
+  "\x3c\x26\x7e\x50\xe8\x7c\x4c\xfc\x60\xb9\xb2\x98\xf8\xc1\x68\xc7"
+  "\x31\xf1\x83\x02\x65\x31\xf1\x83\x02\xfb\x98\xf8\x01\x12\xc6\xc4"
+  "\x0f\xce\x4a\xfa\x32\xa7\x5f\x06\x8c\xd1\x5e\xd7\x54\x7f\xd8\x65"
+  "\x5a\x05\x5a\x37\xe7\xf7\xba\x28\x33\xdd\x40\xe7\xf6\xcb\xb0\x50"
+  "\xc3\x71\x5c\x89\x68\x68\x48\xf4\xb4\xbc\x15\xe4\x45\xf7\x0c\x19"
+  "\x4b\x37\xfb\xe3\xb9\xbd\x00\x78\x7e\x6f\xba\x21\xa8\x07\xfd\x56"
+  "\x50\xcf\x82\x7b\xc8\x17\x7e\xfe\x05\xec\x78\x0c\xff\x0e\xa1\xdf"
+  "\xf2\xef\x9a\xbd\x0c\x05\x7b\xd7\x23\x4f\x78\x86\x18\xef\x4c\x35"
+  "\x82\x18\xe4\x8b\xff\x4d\xaf\x2a\x2a\x2e\xba\x87\xdc\xbd\x75\xe0"
+  "\x1b\x1f\xb8\x9f\xce\x9b\xa6\x97\x04\xa1\xa2\xc5\xa0\xb9\x29\xe4"
+  "\xbf\x83\xa2\x8b\x4d\x0d\x41\x94\xd9\x77\xa2\x9a\xf8\x67\x57\x0c"
+  "\xa3\xbd\xf2\x22\x2f\x58\x7a\x45\x9e\x30\xa7\x27\xaa\xe8\xb7\x63"
+  "\x54\xf8\x59\xcd\x79\x91\x25\xf4\x66\xf8\xa5\x27\xf6\xc0\x1c\x1a"
+  "\x34\x79\x08\xdd\xe0\xdf\x15\xf4\x7a\xf0\x8e\x65\x28\xa0\xf0\x1e"
+  "\x0a\xa2\xef\x04\x51\xe0\xff\x18\xfc\xad\x51\xb0\x51\x8c\x85\x2a"
+  "\x2a\x86\x73\xee\x38\x26\xd2\xf8\xfe\x26\xb8\x7f\x33\xdc\xbf\x09"
+  "\x63\x1b\xf9\x17\xc1\xfd\xcd\x6f\x05\xc9\xec\x2f\xbb\x98\xf5\xbf"
+  "\xd6\xe7\xb2\x04\x47\x18\xe8\x03\xf0\xc3\xcf\x05\x36\x2c\xc2\x36"
+  "\x19\x1c\x51\x8f\x9f\x6d\xc3\x3d\x14\x0c\xcf\x19\x00\xcf\x10\x04"
+  "\xf7\xc5\x79\x5a\x62\x5e\x5f\xa4\xc6\x18\x15\x3c\x9b\x39\x97\x7d"
+  "\xb6\x9b\xf0\x6c\x37\xb8\x67\xc3\xf7\xc2\xf6\x91\x7a\x07\x1a\xb5"
+  "\xb2\x2f\xee\x9b\x3f\x78\xeb\x3a\x8f\xc3\xef\x43\xef\xbc\x9d\x28"
+  "\x13\xab\xbb\x24\xf3\x9f\x6c\x3c\x80\xfa\xd0\xea\xdc\x3d\x13\xd7"
+  "\x7c\x47\x47\x99\x10\x5a\x73\x00\x05\x57\x42\xbf\xae\x30\x5e\x47"
+  "\xb4\x4f\xee\x9e\x93\x41\x75\x32\xef\xb5\x3b\x56\xea\x5e\xeb\x57"
+  "\xd1\x55\xcd\x01\x78\x8e\x2c\x2a\x66\x23\x45\xeb\x9a\x02\x06\x64"
+  "\x9c\x3e\xdb\x84\x66\xe8\xf0\x3b\x57\x5a\xa7\x99\x86\x3c\x2f\xa9"
+  "\xf6\xa9\xd3\xcf\xe3\xf7\x43\xbb\xf5\xc2\xf7\x43\x1f\xba\x23\xd5"
+  "\x1f\xf7\x20\xd5\x9e\x6a\xa4\xfa\x28\x0e\x41\x39\xe1\xef\xe3\x2d"
+  "\x51\x7b\xfb\xa2\x34\x13\xfd\x03\x9d\x63\x2e\xcd\xa6\x68\x63\xd4"
+  "\x40\x37\x7d\xc9\x32\xfc\xbe\xe4\x8f\xef\x83\xfd\x7e\x84\x71\xd5"
+  "\x1b\xff\x1b\xd7\x97\xbc\x18\x3d\x76\x4d\xf5\xc7\x9d\xde\xf5\x9d"
+  "\xc7\x99\x7c\xa3\x32\x4c\x74\x0c\x6a\xd6\xcc\xd6\x37\xe6\x45\x1a"
+  "\x9a\xf1\x1c\xde\x2c\x1c\x83\x3e\xdc\xea\xed\x96\x81\x68\xf0\x3f"
+  "\x4d\xfb\xe3\x77\x86\x31\x05\xf0\xc3\xbe\x64\xfc\xd8\x33\xf4\x2c"
+  "\xf6\x37\xee\x0b\x45\xe4\xb8\x1a\xf7\x87\x8d\x6c\xbf\x31\xa8\x9e"
+  "\x8d\x33\x53\x08\x99\xe1\xfa\xf4\xcb\xa8\x0f\xfe\xc6\x6c\x21\x94"
+  "\x9b\x61\xf6\xc4\xfd\x38\xa6\x64\xda\x37\xe8\x4a\x32\xa2\xd2\x6f"
+  "\xa1\xee\x80\x09\xa6\x3f\x5a\xa0\x3f\x46\x5d\xf0\x36\x42\x5c\xb1"
+  "\xa4\xdd\x45\xde\x38\x4e\xe1\xef\xb5\x54\xd6\xe9\x91\xe5\x66\x50"
+  "\x8f\xed\x0b\x90\xaf\xe9\x66\x62\x4f\xc3\xcd\xc4\xc7\xb6\x5a\x90"
+  "\x6f\x8f\x64\xa4\x2e\x5c\x00\x58\x5c\x08\xfd\xf3\x06\xf4\xcf\x3a"
+  "\xd2\x3f\xad\xf8\xa3\xd7\x97\xeb\xf1\x3e\x7a\xa6\x6f\xe6\xb2\x7d"
+  "\xf3\xad\x20\x3c\x2f\x76\x1f\x7f\xa6\x85\x41\x54\x21\x45\x23\x78"
+  "\x46\xb0\xfb\xae\xaa\xa2\xb4\xce\x9e\x78\x1e\x93\x1e\x10\x84\xdf"
+  "\x71\x40\x5b\x69\xd3\x27\xe0\x0b\x8f\x81\x94\x86\xce\x8f\xca\x38"
+  "\x1d\x5d\x8b\xb8\x79\x93\x7d\x3e\x4d\x81\x03\x32\x34\xaf\xd0\x37"
+  "\x2f\xa9\xfe\xb8\x05\x8e\x7b\x6a\x7e\xfd\x8c\x1a\xfc\xc8\xae\x47"
+  "\xd8\xa7\xc6\xf3\xaa\x7a\xd5\x1f\xf1\x7c\x0f\xc2\xef\xe1\xbf\x66"
+  "\xde\x71\xed\xa9\x82\xb2\xc8\x0c\x36\x37\xa9\xcd\xfe\x16\xdf\x89"
+  "\x9a\x92\xb9\x4d\x4c\xbc\x6a\x06\x1f\x5c\x99\x87\xa8\x19\x75\x60"
+  "\x1b\x33\xd8\xa6\x21\xc8\x0b\xe2\x56\x34\x8e\x5b\x74\x4e\x48\x44"
+  "\xaa\x9e\xb6\x44\xc5\xab\x68\xb0\x8b\x67\xa5\xce\x8c\x5e\x4f\x46"
+  "\xf4\xca\xeb\x60\xa3\xfa\x6a\x04\x6d\xeb\x01\xb1\xad\x67\xe1\x32"
+  "\xe4\xbb\x1d\xec\xd3\xbd\x0e\x38\xcd\xa6\xf7\x92\x0f\xa4\x95\x7a"
+  "\x98\x01\xe7\x38\x8e\x79\x67\xba\x75\x01\x5f\xf5\xc8\xc2\xfd\x16"
+  "\xfa\xb1\x77\x26\x13\x57\x19\xdf\x9a\xde\x0a\x7a\xaa\xf9\xad\x20"
+  "\x0d\xfc\xfa\x5a\x63\x9d\x35\xce\xd0\xd9\xbb\xb5\x38\xce\x55\xea"
+  "\xf4\xc8\x04\xb6\xec\x81\xc7\xc4\xb7\x82\xfa\x30\x36\x7d\x03\x6c"
+  "\x3a\x07\x79\x0e\x31\x22\x37\x78\x2e\x35\x3c\x33\x2a\x4f\xbc\x84"
+  "\x63\xab\xbf\x19\xfa\x11\xb6\x33\xd4\x49\xd1\x80\x35\x4b\x8e\xd9"
+  "\x3f\x32\x49\x83\x4e\x06\x9d\x43\x38\x57\x6b\x7a\x23\xfd\x3d\x7e"
+  "\xc7\x56\xa9\x33\x21\xda\x2f\x2a\x83\xcc\xa3\xff\x31\xf9\x74\xb4"
+  "\x11\x49\x63\xfa\xa3\xa9\x1c\xa6\x3f\x9a\xca\x61\xfa\x23\x66\x0f"
+  "\x36\x1f\xd7\x8d\x3b\x01\xd7\xbe\x7c\x5c\xef\x5d\xd4\xa6\xb8\x9e"
+  "\x28\x1f\xd7\x5b\x6f\xf0\x70\x9d\xf6\xdf\xc1\xf5\xd7\x31\x0c\xae"
+  "\x55\xcd\x81\x0c\x5e\x53\x2a\x4d\x9f\x01\xff\xfd\x68\xb4\x15\xb7"
+  "\xa7\x3e\xc2\xb8\xfd\x78\x6d\x47\xc5\x6d\x63\x43\x90\x06\x7e\xad"
+  "\x8e\x5b\xa8\xd3\x69\xdc\x7e\x1d\xd3\x84\xac\xf6\xc3\xf8\xa5\x73"
+  "\x72\xf7\x68\xd2\xd1\xcf\x21\x4e\xa8\xbd\x33\xfb\xa2\x72\xc6\x86"
+  "\xfb\xd4\x9a\x5f\xd3\x96\x4b\xaa\x8f\x99\x3d\x00\x4d\xab\x68\xda"
+  "\xe2\x3b\x1e\xa5\x9f\x41\x6a\x4b\x9e\x47\x4e\xa5\x69\x3f\xf2\x4e"
+  "\x26\xef\x1e\x68\x9f\x7d\x11\xa0\xc3\x99\xf7\xcc\x96\xdc\xdc\xc3"
+  "\xe6\xdc\xf7\xe2\xcc\x10\x4f\xcc\xf9\x53\x91\x25\x77\x51\x86\xc5"
+  "\x67\x6f\x0e\x8d\xd7\x1d\xf8\x6c\xca\x68\xc8\xde\xa7\xb6\xbe\x0f"
+  "\x17\xe5\x46\xbe\x53\xf1\xdc\x27\x68\xaa\xfd\xeb\xe0\x2f\x05\xcf"
+  "\xb1\x17\xfe\xaa\xe0\xef\x72\x46\x63\xc9\x1a\xe7\xf6\x8d\x26\xef"
+  "\x9f\xa2\xf2\xd8\x38\x38\x86\xe9\x83\xcf\xa2\xee\xd7\xd8\x7f\xc3"
+  "\xf3\xec\xb4\xbe\x5f\xbf\x5f\x9e\xb3\xc7\x48\x7c\x6f\xb0\x89\x3b"
+  "\x79\xe7\x4f\xfe\x8f\xd7\xd3\xb0\xf5\x31\xff\xb7\x04\x68\x75\x25"
+  "\x69\x97\x50\x9d\x6a\xbf\x57\x25\x8c\xfd\x96\xcd\x51\x79\x1b\xef"
+  "\x01\x1e\x75\xf7\xe3\xef\x98\x1e\xe0\xef\x92\x15\xb8\xcc\x3e\x66"
+  "\x9f\x90\x25\x6f\x6c\x1c\xbd\xc9\x9c\x83\x35\x64\x03\x9d\xf8\x22"
+  "\xfb\xf7\x05\x8c\x6d\x32\xdf\xb2\x7f\x2a\x0d\xf6\xc3\xdf\x58\xbf"
+  "\xbf\xc6\x08\x7f\xfb\x3c\xc3\xbd\xcf\xf1\x54\x32\xde\x5a\x9f\x17"
+  "\x7f\x1f\x1d\xaf\xe1\x79\x26\x03\x65\x34\x88\x7c\x1f\x9d\x5b\xeb"
+  "\xb3\x7f\xb4\x25\x7f\x6c\x5c\x43\xf6\xfe\x3c\xe0\x00\x05\xfc\x36"
+  "\x8b\xf9\x02\xca\x17\x4b\x9d\x93\xe7\x87\xfd\x65\x52\xf5\x8c\x09"
+  "\x32\xd3\xf2\xea\x3a\x20\x99\xff\x88\x0e\x08\x54\x47\xed\x31\x97"
+  "\x58\x9a\x63\xbc\x4f\xa6\x5e\x97\xc9\x89\x0e\x24\x4b\xd5\x6b\xce"
+  "\x1b\xaf\x31\x0d\x80\xba\x07\xf6\x45\xe6\x85\x31\x2f\x83\x8f\xbc"
+  "\x30\xd7\x5b\x99\x44\xd6\x85\x95\xed\x31\x21\xcc\xfb\xf6\x2e\x28"
+  "\xa5\x9a\x9a\x63\x50\x0f\x03\x52\x4f\xac\x4f\xa7\x37\xde\x40\x01"
+  "\xf4\x5b\x31\xde\x59\x37\xd0\xc8\xe6\x3b\xfe\x5d\xdf\x5d\x8c\xdc"
+  "\x9b\x20\x26\x37\x2d\x49\xf4\xc6\x6b\xd0\xbe\xb8\x56\x42\x55\x9a"
+  "\x0e\x63\x9e\x19\x80\xc7\x01\xfc\xec\xe6\x3b\x31\x3d\xd6\xdd\x46"
+  "\xcc\x3b\xe6\x92\x59\x1f\xc0\x38\xf0\xc9\x4a\x8f\x95\x10\xfb\x20"
+  "\x76\x31\xe3\x81\x82\xb1\xa0\x09\xc6\x82\xc8\x18\xda\x58\x51\xfd"
+  "\x0d\x4a\xbf\x8e\xd4\xe9\x4b\x51\x77\x5c\x7f\xa5\xe9\x18\x19\x1f"
+  "\xa6\xc0\xf8\x00\xff\x07\x2d\x71\x7f\x7c\xd0\x4c\x44\x76\xe3\x03"
+  "\xd6\x21\x15\x17\x6a\x11\x60\xb9\xf3\xc4\x7a\x6f\x63\x5a\x3d\x6d"
+  "\xc1\x9a\x04\xbf\xcf\x86\x32\x3d\xac\x63\x05\x1e\x27\x9a\xd8\x71"
+  "\xa2\x90\x1d\x27\xb6\xb5\xc2\x38\xb1\x0d\x8f\x13\xe7\x10\xb5\x15"
+  "\x8f\x11\x30\x3e\x7c\xfc\x6f\x03\xd5\x0c\x63\x82\x3c\x3f\x17\x4b"
+  "\xe6\x3f\xa1\x37\x47\xcd\xb6\xc0\x58\x8c\xfd\xfc\x36\xf8\x17\xfb"
+  "\xb9\x32\x08\x7c\x5b\xdd\x79\x5c\x23\x1c\x37\x6d\x0e\xad\xda\x73"
+  "\xc5\x40\xc1\xf8\x64\x68\x04\x3c\xac\xb8\x8b\x28\x93\xef\x78\xcd"
+  "\xfe\x5f\xe7\x50\x58\xb7\x5a\xf2\xc3\x7c\x89\x46\xfe\xac\x1c\xcf"
+  "\xd1\x78\xd7\x22\x35\x9e\x3f\x35\xd3\x31\xde\x96\x1f\x63\xba\x5b"
+  "\xde\xf4\xf7\x6c\xfe\xd1\xbf\xeb\xfa\xb9\xc8\xdd\xf0\x66\xa2\x77"
+  "\xfa\x54\xa4\xfe\xf2\x1f\x39\x54\x45\x3d\xf4\xed\x4e\xc7\xca\x68"
+  "\xa8\xbf\xe8\x12\xd2\x16\xcd\x42\xc3\x77\x5c\x41\x9a\x1d\x73\x50"
+  "\xf0\xf6\x2b\x80\xa1\x37\x63\x7a\x34\x33\xf8\x68\x2c\x61\xd6\x07"
+  "\xcc\x41\x11\x74\x2f\x6d\x15\xfc\xd5\xe6\xcc\x01\x3d\xd3\x2b\xb4"
+  "\x8a\xf6\x1b\xaf\xb1\x40\xb9\x2c\xd0\x6e\xc0\xd1\xe1\x19\x3e\x3d"
+  "\x24\x86\x9b\xed\x32\x39\x44\x64\x34\xe0\xa6\x0a\x70\x73\x4b\x88"
+  "\x1b\xac\x5b\x19\xec\x44\x12\xec\xe0\x77\x80\x45\x7c\x7e\x31\xeb"
+  "\xb4\x62\xfc\x14\x00\x7f\x6e\xb4\xc1\x4f\xc1\x0d\xd7\xf0\xd3\x0c"
+  "\xf8\x29\x58\x05\xf8\x29\x47\xd4\x16\x8b\x2b\xf8\xf9\x8c\xd9\xff"
+  "\x8b\xe7\xf9\xc8\x7a\xa0\xe2\xbb\xd8\xcf\x80\xab\xfa\x29\x41\x6e"
+  "\x48\x19\xae\xc2\xa2\x5b\xc0\x55\x1e\xc1\xd5\xa1\x40\xf9\xb8\xfa"
+  "\x22\x80\x86\xfa\x1d\xe3\xea\xae\x04\xae\xc2\xa2\xed\x71\x75\xb0"
+  "\x7b\xfb\xe2\x8a\xc9\xcd\xf9\x3f\x80\xab\x83\x06\x21\xae\xfe\x14"
+  "\x49\x70\xf5\xa7\x09\x2e\xe0\xaa\x85\x78\x15\xce\xc6\xab\x3f\xaf"
+  "\x54\x80\xab\x54\xc0\x55\x0b\xf1\xea\xba\x14\xae\x44\xe2\xd5\xff"
+  "\x4b\x68\x5f\x5c\x31\xb9\x43\xff\x07\x70\xf5\xe7\x71\x42\x5c\x1d"
+  "\xda\x4d\x70\x75\x68\x97\x72\x5c\x85\xb7\x10\xaf\xc2\xd9\x78\x75"
+  "\xe4\x9c\x02\x5c\x9d\xa5\xa1\x7e\xc7\xb8\xba\x28\x81\xab\x70\x91"
+  "\x78\x75\xf8\x58\xfb\xe2\x8a\xc9\x6d\xfa\x3f\x80\xab\x23\x3b\x85"
+  "\xb8\xfa\xb3\x99\xe0\xea\xcf\x26\x17\x70\xd5\x42\xbc\xd2\xb2\xf1"
+  "\xea\xe8\x20\xf9\xb8\xfa\x32\x18\x70\xd5\x42\xbc\x3a\x26\x85\x2b"
+  "\x91\x78\xf5\x7f\x7e\xed\x8b\x2b\x26\xf7\xea\xff\x00\xae\xfe\xcf"
+  "\x28\xc4\xd5\xe7\x53\x08\xae\x3e\x9f\xac\x1c\x57\xda\x16\xe2\x95"
+  "\x96\x8d\x57\x5f\xac\x51\x80\xab\xd5\x34\xd4\xef\x18\x57\x2b\x25"
+  "\x70\xa5\x15\x89\x57\xc7\xe6\xb7\x2f\xae\x98\xdc\xb0\xff\x03\xb8"
+  "\xfa\x22\x5a\x88\xab\xa3\xfb\x09\xae\x8e\xee\x73\x0a\x57\x46\x1e"
+  "\xae\x2e\x74\x1e\xd7\x94\x4e\xf4\xe0\xde\x39\x2c\xae\x3e\x0c\x54"
+  "\xbf\xbd\x14\x51\xfb\xa7\x6d\xb1\xd1\x82\x25\x67\x6c\x31\x05\xb8"
+  "\x60\x30\x65\x7a\x13\x30\x75\x8d\x60\x2a\xed\x22\x60\xea\xdb\x2d"
+  "\x54\xa5\xee\x3a\xc6\x09\x83\xa1\x82\x39\x80\x21\xac\x0b\xdd\xdc"
+  "\x7d\xe5\x68\xc0\x77\xaf\x59\xb1\xf4\xe5\x91\x56\xc1\xd2\x64\xc0"
+  "\xd2\x59\x5b\x2c\x9d\xe4\xb0\x34\x49\x42\x03\xbe\x2e\x81\x25\x7d"
+  "\xcb\x58\xda\x8e\xe7\x10\x16\xb6\x11\x96\xce\x70\x73\x08\xfb\x66"
+  "\x19\x28\x93\x9f\x5c\x2c\x95\x14\x08\xb1\xf4\xa5\x1b\xc1\xd2\x97"
+  "\x48\x39\x96\xc2\xa3\xa5\xb1\x64\xe5\x53\x7f\x7d\xd2\x35\x2c\x01"
+  "\xb7\x12\x60\xa9\x65\x1e\xc5\x61\xe9\x2f\x1e\xed\x8b\x25\x1b\x1e"
+  "\xf5\xd0\x62\xe9\x2f\xb5\x42\x2c\x1d\x67\x75\xdf\x71\x49\xdd\x67"
+  "\x81\xb1\x0b\xbf\x73\xc2\xfb\x6c\xcd\x77\x62\x5e\x36\xc3\x98\x86"
+  "\xf7\xdb\xe2\xf7\x14\x9f\x2c\xa8\xa2\x30\x9e\xb2\x6f\xa3\x80\xac"
+  "\xc5\x68\xa4\xb7\x91\x60\xc5\x04\x58\x59\x7b\x1b\xb9\x37\x37\x03"
+  "\x4e\x9a\x90\x7b\x23\xd8\xbb\xb1\x39\xd1\xbb\x2c\xae\x16\x7d\x79"
+  "\xa3\x0a\xc6\xb2\xc3\x68\x07\x5c\xd3\xcc\xce\x43\x5a\xde\x8e\xe9"
+  "\xb1\x6e\x05\x9e\x87\x2c\x47\x25\xd3\xb6\x81\xff\x4f\xb8\xec\xff"
+  "\xc6\xdf\x4a\xf9\xff\x98\xc0\xf7\x05\x3c\xbf\x6b\x7e\xa9\x7c\x1e"
+  "\x92\x79\x4f\xb5\x80\xf8\xde\xea\xf7\xad\xad\xe0\xf7\xad\xac\xdf"
+  "\x5d\x1b\x8f\x4e\x48\xaf\x7f\xe4\xc5\x0a\x66\x4d\x81\x91\xc4\x08"
+  "\x6b\x5c\xc0\x31\x02\xf3\x97\x46\xdf\xd0\xb3\xb6\xe3\x0d\x8e\x0f"
+  "\x37\x54\x5f\x45\xe2\xb1\x49\x92\xc7\xb0\x71\x22\x7d\x39\x89\x13"
+  "\x2c\x8f\xb9\xd0\xba\xf3\x8f\x7f\x0b\x6d\xbb\x78\x71\xac\xe5\xb1"
+  "\xc7\x05\x1e\x83\x71\x53\x60\x83\x9b\xb6\x88\x17\xca\x70\xf3\x95"
+  "\xbf\x30\x5e\x9c\x5c\x4a\xe2\xc5\xc9\x14\x67\xc6\x1e\xc7\x78\x0a"
+  "\x9b\xcc\xc3\x53\x1e\x87\xa7\x53\x85\x78\x8e\x52\x1e\x9e\x4a\x42"
+  "\x5a\x77\xde\xb1\x74\x4d\xfb\xe2\xa9\xf5\xe6\x1d\x3b\x36\x9e\x4e"
+  "\x25\x0a\xf1\xf4\xd5\x49\x82\xa7\xaf\x4e\xb4\x02\x9e\x78\xf1\x29"
+  "\x9c\x17\x9f\xbe\xbe\x8e\xe7\x26\x65\xe2\x69\x75\xeb\xce\x37\x9e"
+  "\x3e\xd7\xbe\x78\x6a\xbd\xf9\xc6\x8e\x8d\xa7\xaf\x0f\x0b\xf1\x74"
+  "\xda\x8f\xe0\xe9\xb4\xaf\xeb\x78\x0a\x9f\x6c\xcb\x89\x09\x9e\x2a"
+  "\x5e\xc0\xfc\x59\x26\x9e\xaa\x5b\x77\x9e\xb1\x3c\xb0\x7d\xf1\xd4"
+  "\x7a\xf3\x8c\x1d\x1b\x4f\x15\x9e\x42\x3c\x95\x25\x10\x3c\x95\xc5"
+  "\xb7\x02\x9e\x78\xf1\x49\xcb\x8b\x4f\x55\x1b\xf0\x5c\xa4\x3c\x3c"
+  "\x1d\x6f\xe5\xf9\xc5\xca\xa5\xed\x8b\xa7\xd6\x9b\x5f\xec\xd8\x78"
+  "\xaa\x8a\x11\xe2\xa9\xe2\x10\xc1\x53\xc5\x41\xd7\xf1\xa4\xe5\xc5"
+  "\x27\x2d\x2f\x3e\x7d\x73\x11\xcf\x41\xca\xc4\x53\x46\xeb\xce\x2b"
+  "\x9e\x39\xd9\xbe\x78\x6a\xbd\x79\xc5\x8e\x8d\xa7\x6f\xf6\x08\xf1"
+  "\x74\xc6\x83\xe0\xe9\x8c\xbb\xb3\x73\x41\xd6\x39\x20\x3e\x9e\xa4"
+  "\xb5\xdd\xb9\xfe\xb6\xda\x4e\xde\x1c\x10\xe8\x3c\xc5\xf3\x89\x67"
+  "\xbb\x3c\xa8\xf3\x89\x18\x43\xd6\x79\xa0\x8e\x37\x07\x74\xb6\x4e"
+  "\x88\xa1\xbf\x4f\x22\x18\xfa\x7b\xb4\x14\x86\x4c\xfc\x35\x69\x3f"
+  "\xf0\xd6\xa4\x5d\x47\xd4\xfe\x05\x25\x54\x05\xbb\x26\x0d\xaf\x47"
+  "\xab\xa8\xa9\x45\xeb\xee\x21\x75\x8f\x44\xa4\x9e\x98\x9c\x4e\x6f"
+  "\xc4\x31\x64\x49\x8c\xf7\xbb\x57\xd0\xc8\x66\xc0\x4c\xf6\x35\x76"
+  "\x5d\x1a\xe0\xe6\xeb\x0b\x46\xf4\xc5\x02\xbc\x2e\xad\x18\x15\x41"
+  "\x39\x53\x1e\x99\x0f\xc2\x71\x84\x59\x93\x36\x07\xaf\x49\xfb\x87"
+  "\x8f\xe8\x9a\xb4\x55\x32\xd7\xa4\xa5\x00\x0e\xea\x01\x07\x77\x31"
+  "\x06\x0e\x09\xd6\xa2\x6d\x5f\xc5\x9b\x03\x9a\x25\x31\x07\x54\xed"
+  "\xdc\x3b\x89\x56\x5f\x8b\x76\x93\xb7\x16\xcd\x3a\x07\x34\x0d\x62"
+  "\x87\x6c\xbf\xff\x43\x32\xff\x29\x8e\x11\x66\x88\x09\x13\xf1\xda"
+  "\xf2\x7a\x6e\xbe\x38\x35\x09\xef\xfd\x0d\xad\x32\x41\xac\xc0\xeb"
+  "\xc7\x0f\xcc\x2a\x65\xe6\xfb\x2a\x75\xd5\x68\x5d\x13\x52\x7b\x1b"
+  "\xd8\xb8\xe0\x17\xe6\xdb\x0c\xb1\xc1\x0c\xe3\x12\xf8\xba\x7b\xf3"
+  "\x12\x88\x0d\xb7\x21\x36\x2c\x81\xd8\x70\x17\x62\xc3\xa5\x52\x26"
+  "\x36\xd0\xef\x1c\x2b\xc3\x39\xb6\x8b\xae\xa1\xe1\x85\xd7\x90\x16"
+  "\xc7\x00\x73\xfe\x78\x4d\xb3\x5f\x68\xbd\xc1\x2f\xd4\x48\xfb\x85"
+  "\x79\x12\x0c\x34\x96\x64\x2d\x46\x4c\xac\xc7\xbe\xd7\xcc\xc1\xf1"
+  "\xa0\xba\x77\xf3\x2a\x84\x5c\xc1\x41\x33\x7f\x4e\x90\x8f\x03\x89"
+  "\x18\xe0\x32\x16\x6c\xe6\x81\xb7\xbb\x18\x03\x30\x16\xb6\x5b\x63"
+  "\x80\x4b\x58\xa8\x96\xdc\xff\xe3\x18\x0b\x61\xd1\x4e\x60\x21\xcf"
+  "\x39\x2c\x7c\x11\x80\x73\x53\xdb\x63\x21\x2c\xc5\xe0\x17\xa6\x83"
+  "\x73\x6b\x09\x16\xee\x8a\x60\xe1\xdb\xc0\xb6\xc7\x82\x70\x4e\xe6"
+  "\xe1\xc5\xc2\xb7\x26\x85\x58\x70\x22\x2e\x84\x3b\x19\x17\xbe\x48"
+  "\xc5\x39\x9d\x45\xb0\x00\x71\x21\x0c\xe2\x42\x38\x1b\x17\xae\x8b"
+  "\x60\xe1\xc2\xd0\xb6\xc7\x82\x70\x3e\xe5\xe1\xc5\xc2\x45\xe9\xfc"
+  "\x17\x0e\xb1\x10\xee\x44\x5c\x08\x77\x36\x2e\x9c\xc5\xb9\x90\xed"
+  "\xb1\x10\x0e\x71\x21\x1c\xe2\x42\x38\x1b\x17\x2e\x8a\x60\xe1\xdf"
+  "\x2f\xb4\x3d\x16\x84\x73\x21\x0f\x2f\x16\xbe\xf3\x55\x88\x05\x27"
+  "\xe2\x82\xd6\xc9\xb8\xf0\x65\x30\xce\x21\x2c\x82\x05\x88\x0b\xe1"
+  "\x10\x17\xb4\x6c\x5c\x38\x26\x82\x05\xfd\xf8\xb6\xc7\x82\x70\x1e"
+  "\xe3\xe1\xc5\xc2\xf7\x1a\x65\x58\xd0\x3a\x11\x17\xb4\x4e\xc6\x85"
+  "\x2f\x57\xe3\xdc\xbb\xf6\x58\xd0\x42\x5c\xd0\x42\x5c\xd0\xb2\x71"
+  "\x61\xa5\x08\x16\x2e\x4d\x69\x7b\x2c\x08\xe7\x20\x1e\x5e\x2c\xfc"
+  "\x27\xd8\x21\x16\x68\x7b\x2c\xe0\x39\x04\xac\x1f\x71\x6e\x6b\x06"
+  "\x0b\x73\x4b\xa8\x26\x1a\x63\xa1\x14\xad\x5f\xc1\xc3\x42\x3e\xd1"
+  "\x11\x56\x1c\x6c\xe0\xe3\x00\xef\x5f\xc2\x38\x00\xfd\x60\x02\xbf"
+  "\xd3\x9b\xb5\x55\xcc\x7a\xa5\xfc\x30\x4f\xac\x1f\xf0\x3c\x03\xd6"
+  "\x10\xd2\xfa\xa1\x66\x6a\xab\x60\x60\x1e\x60\xa0\x4e\x5c\x47\xb6"
+  "\xba\x7e\xb8\xd9\x46\x18\x00\x2d\xb9\x2d\xcd\x15\x0c\x5c\x0e\x91"
+  "\x8f\x01\xe0\x08\x4e\x61\x80\xf0\x04\xc7\x18\x08\x4f\xe6\x30\x00"
+  "\x7c\x21\x3f\x7c\x2d\xe6\x07\x04\x03\xe1\x3a\x69\x7e\x70\x65\x7a"
+  "\xdb\x63\xa0\x95\xf9\x41\x87\xc5\xc0\x0f\xc3\x25\xf7\x30\xe2\x58"
+  "\x0e\x71\x7f\xe2\xc0\xbe\x88\x7e\x33\xe6\xe5\xec\x6b\x28\xe0\xdd"
+  "\xb9\x68\x24\xce\x1b\xb3\xbf\xc9\x48\xa5\x25\xd3\x3f\xe0\xbd\xd5"
+  "\x26\x68\x07\xce\x4f\xcc\xe0\xe3\xa6\xbf\x67\x65\xa2\x01\xad\x03"
+  "\x2c\xbc\x0b\x6d\xc0\x79\xe0\x7b\x24\x77\x1e\x57\x51\x7f\x1a\x35"
+  "\xdd\x89\x41\x65\x71\xd7\x50\x54\x10\xdd\x5c\x79\xa1\x04\xef\x61"
+  "\x74\x2f\x59\x76\x1a\xef\x13\xef\x3a\x43\x87\xa8\x1b\xaa\x1f\x8c"
+  "\x78\x4e\x69\x88\x0e\xa9\x0b\xae\x91\x79\xa4\x75\x37\x10\x3a\xa9"
+  "\x43\x88\xf8\xbd\x76\x8a\xc7\xf2\x56\x98\x43\x8a\x05\xbf\x5f\xb0"
+  "\xfa\xfd\xa4\x70\x0e\x89\x72\x62\x3f\xa3\x13\x73\x87\x6d\xb2\x9f"
+  "\xf1\xa6\xfd\x7e\x46\x65\x73\x87\x57\x25\xbf\x7f\xcd\xcc\x33\xb3"
+  "\x3c\xe0\xed\x14\xa6\xdf\x33\x7e\x6d\x86\xd8\x5f\xa9\x3b\xcc\xac"
+  "\x8f\xc6\xfd\x1c\xf7\x79\x8c\x8f\x74\x68\x2f\xc6\x08\xc6\xc3\xc4"
+  "\x3d\xcd\xcd\xaf\xd7\x23\xca\xe2\x17\xe6\x8b\x31\x61\x59\xe8\xef"
+  "\x99\x05\x6d\xaa\x8c\xbb\x04\x7e\xbf\x8d\x2a\x6b\x58\x9f\xaf\xb8"
+  "\x04\xbe\xbc\x5a\x43\x2f\x0c\xea\x3a\xb8\x1e\xe1\xbc\x20\xea\x19"
+  "\x78\xcf\x31\x8c\x03\xdb\x81\x13\x14\xcd\x45\xc3\xe9\xfc\x50\x43"
+  "\x33\x1b\x1b\x2c\xd6\x79\x25\x3c\x46\x00\x26\xde\x5d\x00\x98\x48"
+  "\x01\x4c\xbc\x8e\x31\x71\x2d\xc9\x63\xa9\xc8\xfc\xb2\x0c\x4c\x30"
+  "\xf3\xcb\xf1\x80\x89\x1a\x0e\x13\xf7\xe7\x95\x25\xc6\x84\x92\x69"
+  "\x2e\xac\x2d\x14\x89\x07\x2e\xcf\x2b\xdf\x64\xe7\x95\x79\xf1\x40"
+  "\x19\x36\x7e\x94\xce\x89\x29\x89\x8d\xb0\xe8\x96\xb1\xd1\x60\xc5"
+  "\x46\x5e\xcb\xd8\xa8\x43\xf6\xd8\xf8\x22\x80\xc3\x46\x58\x32\x87"
+  "\x0d\x76\x9e\x29\x3f\x6c\xad\x3d\x36\xea\xd6\xb4\x0f\x36\x6c\xd6"
+  "\xfd\x3c\xb4\xd8\xb8\x1e\xa7\x00\x1b\x4e\xc4\x8d\x9b\x2c\x36\xc2"
+  "\x9d\x88\x1b\x37\xfa\x88\x60\x23\x95\x87\x0d\x5e\xdc\x60\xe7\x9d"
+  "\xf2\xc3\x45\xe2\xc6\x8d\xf7\xdb\x07\x1b\x36\x6b\x78\x1e\x5a\x6c"
+  "\xdc\x4c\x95\x8f\x8d\x70\x27\xe2\xc6\x77\x56\x6c\x38\x11\x37\x0c"
+  "\x5a\x11\x6c\x9c\xe5\xb0\x11\xce\x8b\x1b\xec\x3c\x14\xe6\x9c\x76"
+  "\xd8\x30\x1c\x6b\x1f\x6c\xd8\xac\xc7\x79\x68\xb1\x71\x4b\xf2\xfb"
+  "\xd7\x0e\xb0\xe1\x44\xdc\xf8\x92\xc5\x86\xd6\x89\xb8\x71\x7b\xb2"
+  "\x3d\x36\xbe\x0c\xe6\x61\x83\x17\x37\xd8\x79\xa9\x7c\xad\x48\xdc"
+  "\xb8\x7d\xbe\x7d\xb0\x61\xb3\xb6\xe6\xa1\xc5\xc6\x9d\x83\xf2\xb1"
+  "\xa1\x75\x22\x6e\xa4\x5b\xb1\xe1\x44\xdc\xa8\x4f\x16\xc1\xc6\x6a"
+  "\x0e\x1b\x5a\x5e\xdc\x60\xe7\xa9\xf2\xb5\x22\x71\xa3\xfe\x6e\xfb"
+  "\x60\xc3\x66\x9d\xcc\x43\x8b\x8d\xbb\x55\xce\x60\x23\xb5\x5e\x44"
+  "\xa7\xd4\x10\x6c\x34\x43\x19\x3e\x2e\xf8\xda\x04\xda\xe7\x1e\x05"
+  "\x9a\x05\x63\x62\x7a\x2a\xa2\x18\x5c\xd4\xf3\x71\x71\x6f\x2d\xc6"
+  "\xc5\xa0\x44\xc0\xc5\x65\x16\x17\x56\x5d\xc2\xe4\x5e\x21\xda\xc4"
+  "\x3a\x67\x65\xd5\x27\xeb\xb1\x66\x4d\xb4\x62\xa2\xa1\x8b\x47\x52"
+  "\x2b\x60\x42\xb0\xee\x81\x87\x89\xa9\x12\xfa\xe4\xd7\xca\x31\xb1"
+  "\x0d\xb4\x6b\x73\x6b\xef\x7d\xb2\x62\xe2\xbc\xab\x98\x68\x70\xb8"
+  "\xfe\x41\x1c\x13\x2c\xcf\x90\xc4\x04\xc7\x2d\x08\x26\xbe\x73\x80"
+  "\x09\x63\x81\x3d\x26\x58\x5e\xc1\xe4\x21\x20\xdc\xc2\x3a\x87\x65"
+  "\xe5\x17\x42\x4c\x34\x3e\xd9\x3e\x98\xb0\xe1\x17\x0f\x2d\x26\x1a"
+  "\x8d\x92\x73\x58\xab\x10\x55\xb8\xca\x52\x9c\x43\x59\x0e\xc3\xaf"
+  "\x04\x7e\xa5\x70\xcc\x03\x8e\x31\xb1\x05\xfe\xcf\x9c\xb3\x74\x65"
+  "\x72\x0f\x97\x78\xbb\xc5\x61\x7b\xe3\x32\x9d\xac\x65\xbc\x33\x51"
+  "\x44\x11\x5b\x07\x1c\xcf\x80\xe3\x25\x3d\xdc\x22\x3a\x41\xf9\x52"
+  "\x3a\x7b\x7f\x19\x1c\xeb\x8c\xcb\xd2\x99\xee\x64\x9f\x0d\x45\xe1"
+  "\x3a\x6c\xef\xe9\xc9\x96\xe9\xc3\xbf\x6f\xf7\xcc\x08\x9c\xcb\xcf"
+  "\x5a\xa6\x8b\x85\xfa\x36\x06\x97\xb3\xb8\xb9\x6b\x2c\xab\x90\x86"
+  "\x5f\x96\xfe\x05\xc2\xf5\x5a\xcb\x76\x65\xeb\x0b\xe0\x97\x31\x7f"
+  "\x80\x50\x0f\x37\x0d\x53\x67\x8f\x64\x0a\xb7\x09\x97\xed\x46\xf7"
+  "\xd8\x17\xc0\x94\x77\x73\x0f\x12\x94\x7f\x07\x31\x65\xd9\x72\x5e"
+  "\x74\xa7\xbf\x9c\x60\xcb\x31\xef\x07\xe0\x98\x3b\xdf\x7e\x6c\xb9"
+  "\xee\x56\xdb\xe0\xfc\x7d\xfc\xb6\x9a\x57\x51\xb8\x3e\x5c\xa6\x87"
+  "\xa5\xd3\xf1\xb3\x6c\x5b\x86\xf3\xef\x89\xcb\xc1\x75\x43\x59\x3b"
+  "\x7b\x43\x1b\xb4\xf7\xeb\xcb\x31\x97\x5a\xcb\x01\x0e\x7b\x17\x71"
+  "\xb6\x51\xd3\xd9\x07\xe2\x70\xce\x72\x5b\xdf\xf5\x70\x73\xd3\x63"
+  "\xdf\x55\xd6\x21\x84\xcb\xd2\x3d\x0e\xf8\x42\x79\x1f\xb6\x1d\x11"
+  "\xa4\x1d\x4c\xce\x44\xe2\x6b\xca\xf4\xd8\x0e\xe6\x59\xdd\x34\xec"
+  "\xb3\xf6\x84\x72\xa3\xad\xf5\x5a\x28\x06\xc3\x6c\x59\x77\xa6\x6c"
+  "\xc5\x3c\xfc\xad\xaf\xfb\xe5\x1f\xc3\x65\xcd\xd9\x5f\x14\x9b\x33"
+  "\xdd\xc7\xd9\xd6\x6f\x5e\xe5\x89\xcf\xf3\xeb\xf7\x25\xe5\x8b\x77"
+  "\x42\xf9\x09\xf6\xe5\xd5\xb6\xe5\xfd\x48\xf9\xcf\x8c\x50\x3e\xda"
+  "\xbe\xbc\xa9\xa7\x4d\xf9\x5e\xa4\xfc\xa1\x68\x28\x3f\xd9\xbe\xbc"
+  "\xc6\xb6\xfc\xe3\xa4\x7c\x89\x09\xca\xc7\xd8\x97\x8f\xb0\x2d\xef"
+  "\x4f\xca\xff\x79\x0f\x94\x8f\xb5\x2f\x9f\x61\x5b\xbe\x37\x29\xff"
+  "\x39\x82\xf2\x71\xb6\xe5\x8b\x98\xb2\xe8\x29\xb6\xec\x13\xa4\xec"
+  "\xd1\x18\x28\x1b\x2f\xd2\x56\x15\x5b\x77\x08\x5b\xfe\x27\xa4\xfc"
+  "\x81\xc3\x50\x3e\xd1\xbe\xbc\xbb\x6d\xf9\x3e\xa4\xfc\xdf\x3d\xa1"
+  "\xfc\x3c\x11\x5f\xd9\x96\x7f\x92\x94\x3f\x19\x04\xe5\x93\x45\x7c"
+  "\x65\x5b\xbe\x2f\x29\xff\x95\x0e\xca\xa7\x88\xd8\xde\xb6\x7c\x3f"
+  "\x52\xfe\x54\x29\x94\xd7\x89\xd8\x5e\x58\x3e\xbb\xcc\x1f\xca\xa5"
+  "\xee\x60\xb1\x69\x63\x77\xdb\xba\xfb\x93\xba\x2b\x12\xe1\x9a\x0c"
+  "\xfb\xf2\xc8\x8d\x94\x47\xc3\xd8\xf2\x4f\x91\xf2\x55\xd8\x96\xab"
+  "\x45\x6c\xff\x34\x2e\x5f\x44\xca\x3e\x4d\xca\xfe\x75\x1c\x94\x5d"
+  "\x2b\x62\x77\x7e\xd9\x00\x52\xf6\x3f\x29\x50\x36\x4b\xc4\xe6\xfc"
+  "\xb2\x81\xa4\xec\x3f\x83\xa1\x6c\x8e\x88\xbd\xf9\x65\x07\x90\xb2"
+  "\xe7\xb5\x50\x36\x4f\xe4\x79\x9f\xe2\x95\x7d\x86\x94\xfd\xd7\x68"
+  "\x28\xbb\x45\xc4\x2f\xfc\xb2\x41\xa4\xec\x65\xec\xc3\x02\x11\x9f"
+  "\xf0\xcb\x0e\x24\x65\x2f\xe2\xbe\xb6\x53\xc4\x27\xfc\xb2\xcf\xd2"
+  "\xd9\xdf\xc5\xb2\x71\x7a\x97\x6d\xd9\x1d\x5c\xdc\x7d\xce\xd2\xe3"
+  "\xfb\x44\x36\x56\x92\xb5\xe1\x50\x8e\x1b\x73\x4c\x3f\xb5\x8e\x11"
+  "\x16\x0a\x05\xd3\xd9\xe7\x26\xc0\x75\xb8\xce\x7d\xf6\xb1\xcd\xfd"
+  "\xa7\x3b\xb8\x31\x62\x10\x9d\x7d\xcf\x9f\xbd\x7f\xb1\x7d\x59\x4f"
+  "\x7e\xd9\xc1\x74\xf6\xd5\x64\xb6\xec\x41\xfb\xb2\x6a\x7e\xd9\x21"
+  "\x74\xf6\x8f\x59\x6c\xd9\xc3\x22\xf1\x75\x18\xaf\x6c\x08\x9d\x7d"
+  "\x7d\x0f\x94\x3b\x2a\x16\x5f\xe9\x55\x9a\x61\x38\x1e\x58\x63\x37"
+  "\x94\x1f\x4a\xec\x6b\xc4\x78\x28\xc1\xe5\xad\x65\xc1\x0f\xc3\x78"
+  "\x63\xe5\x30\x4b\x8f\x9b\x27\x58\x9b\x9d\xb0\x7f\x86\x0c\xfe\x33"
+  "\xfc\x94\xd4\x79\x4b\x0f\x75\x96\xda\x3e\x03\x1b\x8f\x30\x4f\xc0"
+  "\xf6\x1d\x6e\xce\xbe\x63\xc2\xf6\x85\xb2\x65\x02\x8e\x40\xb9\xa9"
+  "\x70\x9d\xac\x6f\x43\xe9\xec\x1f\x52\x59\x1b\x08\xc6\x23\xe8\x8f"
+  "\x4c\x3c\x04\xff\x96\xd2\xef\xf4\xc4\x75\x87\xb1\xe5\xce\xda\x8e"
+  "\x83\xec\xf3\x85\xc3\xb9\xea\xfb\x63\xa0\x9b\xfb\x05\x31\x2e\x93"
+  "\xfc\x2c\xea\x76\xcd\x5d\xc5\xc4\xf7\xfb\xdf\xf1\x75\xf7\x60\xc6"
+  "\x69\xcb\xae\xc0\xe2\xa8\x7a\xda\xc4\x3f\xb6\x91\xa2\xab\x86\xd4"
+  "\x23\x77\x9c\xa7\x9b\xf6\x8b\x8a\xd1\xc3\x71\x43\xe0\x80\x8c\x86"
+  "\x4d\xaa\x38\xbd\xdb\x31\x77\x9c\xcb\x15\xfe\x3d\x4f\x8f\x92\x26"
+  "\xe0\x7f\x6f\x5c\x45\x1b\x71\xfe\x64\xf3\x26\x73\x4e\xa5\xa5\x0e"
+  "\xf0\x47\x1b\xa1\x0e\x23\x70\x46\x15\xfe\x86\x35\xfe\x8e\x44\xa5"
+  "\xae\x0e\x5d\x71\x57\x7d\x4a\x2f\x4c\x1c\x49\xe7\xc5\xe8\xe1\x7e"
+  "\xf1\x97\xe0\xff\xc4\xa6\xc0\xa9\x73\xcc\xfb\x4a\x16\x37\xe1\x32"
+  "\x8d\x06\xbf\x18\x3d\xfd\xdb\xd7\x6a\x93\xd3\x50\x3f\x78\x6e\x86"
+  "\xa3\xe1\x1c\xb6\x16\x1f\xf3\x3e\x26\x77\xed\xcd\xc4\x17\x99\xbc"
+  "\xb5\xee\xee\x66\x9c\xaf\x16\xe7\xad\xbd\x9f\xb3\x76\x67\x7c\x06"
+  "\x93\x07\xd7\xdd\x3d\x92\x69\xcb\x2a\xba\x8a\x0e\x08\xdc\x62\x69"
+  "\x5a\x9d\x81\xbf\x37\x5d\x92\x76\x0d\x5d\x62\xcf\xe1\x3a\xd9\x7a"
+  "\xca\x6d\xeb\xc1\xd7\x19\xfa\xc7\x67\x80\x0d\xb6\x98\x73\x42\x76"
+  "\x5a\xd4\x21\x05\x74\xce\xf3\x7b\x2a\xa1\xd5\xcc\x37\x19\xdd\x3d"
+  "\x06\xd1\x3d\xa6\x56\x5a\x72\x42\x56\xc3\xf1\x2d\x95\xf5\x4d\xcc"
+  "\x71\xa8\x7b\x0b\xe6\xbd\x77\xd4\xe1\x31\x74\x4e\x78\x6c\xc9\x13"
+  "\x4d\xa8\xc6\x9d\xf4\x61\x7c\x9c\xce\x7d\x7e\x0f\xb6\xa7\x25\xf7"
+  "\xf9\x2d\x2a\x7f\xe4\x7e\xc7\x27\x3c\xa6\x61\x93\xfb\x61\xeb\xf7"
+  "\xe8\xac\xf7\xc2\xf5\xea\xd9\xba\x9c\xce\xb9\xeb\xee\x1e\x81\x73"
+  "\xee\x3a\x5f\x5e\x65\xc4\xe5\xc5\xbf\x41\x02\xfc\x2a\xd7\x5c\xda"
+  "\xb0\xc9\x63\xb2\x5e\xd5\xa4\x25\x3e\xf7\xf8\xff\xec\xbd\x0b\x7c"
+  "\x94\x55\x96\x2f\xba\xaa\x52\x81\x02\x03\xa9\x84\x00\x25\xa2\x16"
+  "\x36\xd8\xa5\xf2\x08\x08\x36\xd2\xa0\x51\x12\x0c\x1a\x20\xca\xc3"
+  "\x28\x11\x12\x4d\x34\x68\x80\x98\x44\x28\x20\x50\xa1\x40\x1b\x6d"
+  "\x1e\x49\x8c\x18\x35\x24\xb1\x4d\xf7\xa1\x67\xe8\x91\xb9\xc3\xcc"
+  "\xc4\xfb\xa3\x35\xdd\xa4\xef\x61\x66\x20\xc5\x9c\xc1\x73\x73\xfa"
+  "\xd0\xdd\x05\x37\x66\x22\x13\xb0\x34\x05\x29\x49\xa5\xf6\xf9\xaf"
+  "\xbd\xbf\x2f\xf5\xa0\x82\x7a\xa6\xcf\x9c\xdf\xbd\xd7\xe8\xc7\x57"
+  "\xdf\x7e\xac\xbd\xf6\x5a\x6b\xaf\xbd\xf6\x6b\xed\x3c\x60\xa3\xf1"
+  "\x3f\xbe\xd8\x63\xa0\x73\xda\x6f\xbe\xff\xb4\x40\xfb\xbd\x5b\xf7"
+  "\x71\x1c\x13\xae\x65\x00\x74\x1c\x38\x16\x7c\x2f\xc7\xcc\x36\xbe"
+  "\xba\xa3\x61\xa0\xde\x76\x1b\x19\xba\x4c\xc3\xcc\x28\xf3\x98\xe2"
+  "\x49\xfc\x79\xbc\x13\xb5\xb7\x57\x7b\x0b\x4e\x23\xe5\x38\x25\xbb"
+  "\x0e\x74\x6f\xd2\x78\xf1\xb5\x1c\xdb\xb0\xdc\x40\xb6\x44\xd2\xbc"
+  "\x26\x09\xf7\xad\x1c\x4f\x38\x0e\x48\x43\xa9\x33\x67\xdd\x3b\x7b"
+  "\xce\x7d\x3f\x9a\x7b\x7f\xfe\xb3\xcf\x15\x14\x3e\xff\x42\xd1\xba"
+  "\x17\x5f\x2a\x5e\xbf\x61\x63\xc9\xcb\xa5\x65\xe5\xaf\x6c\xda\xec"
+  "\xd8\xb2\x95\xd3\x0d\xe2\xfb\x5e\xba\xc1\x67\x24\xf0\xf6\x61\x94"
+  "\x33\x6c\xbd\x2c\x1b\x61\x4a\xc6\x86\xe5\x9a\x6c\xb1\xc7\x0f\x6e"
+  "\x58\xf4\x7c\xcf\x61\x8f\x69\xd8\x47\x7c\xe7\x22\x64\xdc\xe0\xae"
+  "\x7f\xa4\x95\xef\x6b\xee\x34\x0d\x3b\xd2\xee\x7d\xa4\x95\xef\x17"
+  "\x3f\x61\xed\xa6\xc9\x77\x90\xe1\xa2\x69\x58\x1d\xc7\x37\xde\x49"
+  "\xd4\x86\xbc\xb1\x60\xde\x61\x21\xeb\x9b\xe3\x84\xb7\x76\x9c\xe8"
+  "\x61\xf8\xb5\x07\x45\xb7\x77\x5b\x11\xed\xc7\x37\xda\x99\xa5\xcb"
+  "\x34\x7c\xfd\x89\x89\xf2\x9e\xd6\x89\x0d\x07\x45\xe7\xee\x71\xa2"
+  "\x73\xd7\x41\xd1\xd3\x38\x4e\x78\x26\xd7\x52\x42\x5f\xcd\x70\x9b"
+  "\xc7\x34\xcc\x21\xdb\x2c\xe2\x83\xc9\xc3\xac\x07\x10\x37\x23\x40"
+  "\x71\x8d\xf8\x46\x98\xef\x84\x4d\xe1\xfd\xe1\x57\xfe\x78\xc0\x33"
+  "\x89\xfe\x62\xc3\x7e\x94\xa3\x78\x32\xbc\xba\x0d\x96\x07\xca\xf3"
+  "\xba\xfd\x17\xc8\x63\x1a\x5e\xd5\x78\x55\x96\x97\xe8\xae\xeb\x21"
+  "\x86\xf7\x57\xa5\xfe\xf8\xb2\x09\x22\x80\xb4\x25\xc1\x6d\xc5\x06"
+  "\xa4\xc9\x02\x6c\x5f\x78\x7d\xec\xcf\xaf\x2f\xb7\x6d\x78\xa5\xb8"
+  "\xf8\xae\x91\x64\x97\x6f\x0a\xbf\x6b\xbc\x9c\xfd\xab\xbf\x79\x50"
+  "\xb4\xa1\x9e\xad\xa8\xef\xc9\xd3\x18\xa9\x40\x3e\x08\x75\xaa\x02"
+  "\xdc\xcf\x10\x7e\x1c\xbf\x8f\x03\xf7\x93\xf2\x1e\x63\xd3\xcd\x49"
+  "\xa2\x66\x78\x3d\xf0\x3c\xc9\xf7\xb1\xb1\x3f\xf6\xde\xcd\x2b\x0c"
+  "\xa8\x77\x2d\xd2\x9d\xb4\x4d\xa0\x29\x5d\x26\xf3\x7a\xe0\xd1\x8c"
+  "\xdf\x9c\xfe\x66\xe6\x23\xd2\xb7\xa9\x7a\xdd\x2c\xef\xcf\x06\xad"
+  "\x5a\x0f\x8d\x13\x7b\xfb\x6a\xcc\x99\x7c\xcf\x84\xbc\x37\x13\xdf"
+  "\xa0\xcb\x49\xa4\xad\xea\x75\xae\x30\x60\xbc\x6b\x68\x0c\xc1\xb4"
+  "\x32\x4e\x8c\x07\x8f\xa1\xff\x09\x56\x68\xb0\x3f\x87\xa6\xf9\xc9"
+  "\xf0\x4f\x9d\x44\xf5\x07\x45\x13\x9e\x7a\x3c\x75\xff\x88\xb8\x7f"
+  "\xc0\x73\x12\xe1\xa7\xf0\xfe\x47\xbc\xff\x01\x0f\xc6\xe0\x56\xc6"
+  "\xbb\xac\x42\x74\xcf\xa8\xa3\x1f\x30\x7c\xc8\xd6\x93\x17\x4c\xd6"
+  "\x22\xc6\x9d\xef\x91\x11\xc9\xe6\x73\x11\x77\x5f\x98\x46\x66\x13"
+  "\xe2\xf1\x2e\x50\xef\xf0\x67\xe4\x11\x3c\xa7\xd4\xef\x9b\x52\xf0"
+  "\x7b\xbe\xf6\xdb\x8e\x67\xf6\x37\x3f\xd1\xf0\x86\x7a\x6e\x6a\xfa"
+  "\xf6\x69\xbf\xd5\x73\xee\xdb\xa5\x1b\x95\x43\xa6\xc4\xa3\x78\xba"
+  "\x23\xc3\x13\x5b\x55\x58\xca\x5e\xf5\x9d\x52\xa7\xbd\xdb\xc8\x34"
+  "\x16\x74\x1a\x0b\xf8\xe3\x48\x85\x8d\x4b\xc0\x7b\x05\x9e\xbc\xa8"
+  "\xf2\x19\xa6\x8f\xf9\xd9\x8f\x7e\x86\x79\xe9\x31\x99\x8f\x30\x8f"
+  "\x0e\x28\xd9\x32\xf0\x59\x3a\x84\x1d\x86\x6c\xd5\x87\xe4\x67\xe4"
+  "\xa1\x48\xf9\x19\xb9\x27\x4a\x7e\xaa\x58\x1f\xa1\x2d\xf8\x1a\x95"
+  "\xbc\x1c\xef\xdd\x56\x80\xef\x91\x7b\x01\xe7\x38\xcf\xed\x74\x99"
+  "\x6e\x92\xbc\x3d\x70\x91\x68\x14\xb0\x61\xfd\xd2\x63\x1a\xf9\x07"
+  "\x96\x59\x2e\x5b\x2b\x57\xe1\x02\xfc\x10\xd6\xc4\xf8\x6d\x04\x5c"
+  "\x7c\x37\x23\x5d\x93\x9b\xbe\xd2\x71\x93\x79\xde\x78\x11\xf2\xa8"
+  "\xe1\xcb\x30\x39\x9f\x08\xd5\xeb\x30\xe7\xd1\xca\xae\x46\x78\x2a"
+  "\x74\x14\x9f\x93\x8b\x73\x07\x3c\xc4\x32\xc9\x6f\x77\x20\x15\x6d"
+  "\x29\x93\x82\xec\x1b\xde\x4a\xa9\x68\x6f\x23\x2e\x98\x6e\x2a\x9f"
+  "\x5e\x41\xa9\x0c\x8f\x75\xb8\xc7\x74\xd3\xdc\x46\x6e\x8b\x0a\xd6"
+  "\xeb\x5c\x0f\x86\xff\x8f\x18\x05\xf1\xbb\x81\xf1\x41\x7c\x58\xb9"
+  "\xb5\x6e\x8c\xc0\x0e\x6c\x55\x75\x45\x59\xcd\xc8\x7f\x94\xeb\xce"
+  "\xf4\x44\x7c\x0b\xe0\x9c\xe1\x38\xbe\x4b\x52\xab\x4f\x33\x9f\x4f"
+  "\x64\x7a\x70\x7a\x37\x46\x1d\xf2\xde\x0b\xd3\xf0\x2b\x92\x6e\xc8"
+  "\xcf\xfc\x10\x28\x83\x61\x38\x03\x22\x20\xa0\x8f\x3e\xd8\xea\x87"
+  "\x5d\x33\x6a\x71\x24\x7f\x12\xec\xe1\xfc\x41\xbe\xa3\xc8\xdf\xc6"
+  "\xfd\x3f\xeb\x13\x94\x99\xc8\xf7\x42\x23\xac\x2a\x58\x03\x18\x9b"
+  "\xfc\x72\x3e\x0a\x70\xee\x07\x2e\x55\x0c\x07\xf8\xb4\x69\xb0\xca"
+  "\xd9\x47\x7e\x38\xaf\x35\x78\xcd\xcc\x73\xd9\x9e\xb7\xca\x3a\x41"
+  "\x77\x8d\x1a\xd1\xa0\xe2\x5a\x90\xa6\x45\xf4\x67\x92\xd8\x96\xa3"
+  "\xee\x9f\x56\x71\xc7\x9c\x5f\x4b\xfe\xb6\x29\xbd\x36\xea\xae\xb2"
+  "\xed\xa2\x3b\x0c\x6f\x8f\x7e\x87\x94\x86\xf7\x31\x2e\x4f\x6c\xce"
+  "\x95\xfd\x28\x97\xc1\xf9\x15\xbc\x04\xd6\x91\xc7\x74\x5a\x4d\x07"
+  "\x1e\x8a\x5e\x37\x79\x11\xde\xcc\xb2\x28\xe9\x06\x3d\xda\xeb\x64"
+  "\x59\x4c\xe8\x44\xfe\xe3\xfb\xf9\x7b\xb3\xfc\x76\x48\x1d\x1b\x8a"
+  "\x9f\xca\xf1\xee\x6e\xf0\xed\x25\xc8\x52\x90\xe8\x07\x29\x94\xea"
+  "\x73\xc9\xba\x1d\xf1\x6d\x4b\x37\x9c\x08\x10\x31\x9e\xa0\x51\x4b"
+  "\x5f\xcd\xa8\xbd\xe8\x6b\xa4\x4d\x03\x7d\x7d\x4c\x7c\x90\x43\x8c"
+  "\x33\xf4\x99\x86\xdf\xa8\x01\x8d\xf7\xc7\xb8\x8e\x4c\xcf\xe9\x4a"
+  "\xf7\x21\x2e\xf1\x7d\xc6\x3d\x54\xef\x51\x1d\xe1\x34\x96\xf5\x06"
+  "\x1f\x98\x5f\xcc\x97\x30\x98\x2c\xfb\x55\x80\x75\x44\x7d\x2b\xd9"
+  "\x60\x5a\x57\x8d\x13\xa7\x38\x7d\x28\x6d\xa2\xbc\x8f\x66\x07\xca"
+  "\x9e\x51\xc2\xe3\x26\xf4\xcf\x81\xbe\x56\xc0\x3d\xd2\xba\x35\x40"
+  "\x80\xd1\xc2\x34\x45\xba\x42\x96\x47\x7c\x9f\x52\xf9\x46\x17\xa0"
+  "\x3f\x9f\x8a\x67\x7e\xa8\xfd\x27\xae\x8c\x94\xaf\xd1\xd1\xed\x9f"
+  "\xf9\x5d\x15\x74\x66\x92\x94\x87\x52\xb2\x5d\x36\x8d\xfe\x52\xeb"
+  "\x3b\x34\x5e\x27\x66\x9c\x40\x7b\x09\x83\x71\x2a\x8a\xd7\x2d\x52"
+  "\x1e\x37\x67\x19\xb8\xce\xc8\xdb\xa2\xc1\x91\x75\x96\xf2\xe4\x92"
+  "\x32\x70\x4a\x6c\x46\x3d\x07\xe5\x60\xb4\x5d\xe3\xf3\xa9\x28\x9a"
+  "\xe8\xba\xab\x9c\xef\x24\x66\x9d\x04\xdb\xfa\x81\xbe\xfe\x90\x5e"
+  "\x62\xde\x07\x25\xef\x47\x9f\x69\x54\xfd\xad\xa6\xb7\x46\xab\xf8"
+  "\x71\x11\x32\x0c\x5c\x12\xe3\xa5\xfc\x32\x2e\xce\x5c\xc6\xa5\x45"
+  "\xe2\xe1\xb4\x11\xe2\x2a\xb8\x7c\x8f\x29\xd1\xac\xb5\x57\x0d\xd6"
+  "\xa8\x73\x0c\x6b\x17\x74\x15\xe3\x84\xb2\x8b\xa4\xfe\x5b\x24\x69"
+  "\xf2\x07\x0d\xf7\x93\x7e\x17\xe7\x1d\x79\xe6\x6b\xa3\xcc\x0b\xdb"
+  "\x75\x64\xba\x5f\xdd\xe9\x36\x12\xf9\x0f\xcb\x7d\x96\xa6\x94\xf9"
+  "\xac\xa3\xf9\xfc\x30\x7e\x4f\xb1\xad\x82\xac\x5e\x44\x8f\x51\x44"
+  "\x66\x96\x51\x5d\x2e\x7a\x4c\x29\x63\x79\xbc\x02\x5a\x1f\x81\x8d"
+  "\x74\x98\xe9\xcd\xb2\x0c\x1b\x69\x76\x5f\x8d\x25\x5d\x97\x5b\x94"
+  "\x53\xcf\xb4\x57\xfc\xb1\xbc\x0e\x39\x6e\x09\xc9\x96\xe5\x75\x8d"
+  "\x8e\x87\x41\x47\x33\xca\x1b\xa1\xd5\xeb\x30\xd2\xc3\x16\x1b\xf3"
+  "\xb5\x86\x7b\x9d\x96\xfe\xe7\x3a\x1f\xb4\xb6\x7a\x6a\x3f\xeb\x5f"
+  "\xc9\x83\xa4\xf9\x5a\xde\x66\x55\x56\xd2\x02\x3d\x2d\xdb\x88\xf2"
+  "\x7e\x66\x84\xb1\x1e\x9c\x01\xde\x4b\xdd\xb7\xf5\x9a\x4c\xa7\xe9"
+  "\xc6\x36\x55\xc6\x98\xcf\xa4\x1c\xc2\xee\x09\xc9\x51\x52\x4a\x94"
+  "\x7e\x62\x5d\x5c\xd5\xbe\x5b\xdd\x7f\xc7\xb2\xc4\x3a\x95\xc7\x45"
+  "\xc0\xb1\x47\x6b\x3f\x1a\xce\x49\x3b\x23\x65\x65\xcc\x3f\x43\x56"
+  "\xa6\x85\xc1\x2e\x89\xd5\xcf\x35\x2a\x1d\x58\xaf\xd5\xed\x37\x5a"
+  "\xdd\x8e\x68\x75\xfb\x8d\x56\xb7\xc3\x28\x03\x74\x1b\xf3\x6a\x18"
+  "\x1d\x41\xb7\xe4\x2f\xb5\xf4\x2d\xac\xcb\x43\xed\x35\x79\x9a\xde"
+  "\x96\xaf\xd7\x17\xc9\xe7\xb9\x3d\x84\xf0\x4a\x36\x47\xe9\x8b\x96"
+  "\xd8\xfa\x22\xa9\x43\xab\x6f\x53\x54\xdb\x68\xd6\xec\xdd\x2b\x3a"
+  "\x1f\xda\x7d\xda\x3d\x84\x08\x63\xfd\xc9\x65\x87\xf7\x41\x0d\x8a"
+  "\xae\x5a\x5b\x4e\x3e\x7d\x3d\x1f\x92\xeb\xc3\xdb\x33\xf3\x9a\x75"
+  "\x02\xc3\x60\x9e\x4a\xbb\x12\x61\x8a\xaf\xc9\xe5\xac\x1b\xc2\x75"
+  "\x34\xd2\xd6\x06\x05\xb7\x97\xe4\xa6\xc8\xb6\x98\x9c\xa0\xb5\x45"
+  "\xad\xec\x31\x2f\x83\x47\xa9\xa1\x72\xc7\xa4\x44\x95\xcb\xbc\x69"
+  "\x93\xf7\xc5\x28\x9e\x3e\xa3\xf7\x69\x9c\x1e\x79\x1d\xc8\x93\x19"
+  "\xd5\x3f\x56\x31\x7e\x1e\x53\x52\xab\xd4\x59\x07\xa5\xae\x70\xf4"
+  "\x49\x7c\xc6\x64\x35\x6a\xfd\x04\xc2\x52\xb5\x30\xab\xd6\x97\xe8"
+  "\x72\xf3\xeb\x28\x9c\x0e\xc7\xb6\x8f\x92\x5a\x75\xfb\x48\xc2\x92"
+  "\xba\x68\xcc\x11\xad\x7e\x1c\x36\x4d\x85\x25\x95\x73\xd8\x7e\x45"
+  "\x87\x5a\x21\xfb\xab\x24\xab\xd6\x5f\x71\xfb\x32\x7a\x4c\x96\x3d"
+  "\xdc\xc6\xf8\xdb\x63\x4a\xe1\xbb\x09\x0d\xee\xca\x6b\x3c\x86\xa8"
+  "\x43\xdc\x64\xd6\x07\xac\x2f\x78\x7f\xb0\x7c\x2f\x95\xef\x25\xac"
+  "\x77\xd8\x0e\xe1\x78\xa4\x4b\x61\x5d\x84\xf0\x7c\xf6\x0d\x28\xfe"
+  "\xcd\x0c\xb8\x29\xe9\x5a\xde\x57\xa4\xad\xf0\x6f\x99\x71\x7a\x98"
+  "\x9e\x0f\xed\x68\x0a\xe7\xe3\xfc\xba\xfe\x62\xdd\x15\x60\xdd\xa4"
+  "\xca\xfb\x48\x93\x71\x39\x6e\xd0\xed\xa2\x7e\x63\x58\x5a\xbe\x4f"
+  "\x4d\xea\xb4\xb1\x26\x4d\x9f\x5d\xe1\xbc\x92\x7f\xd0\x95\x3b\xbe"
+  "\x16\xe7\x1b\x4b\xc9\xd4\xf0\x15\xeb\xc5\xe1\x3e\x85\xe7\xd8\x6c"
+  "\x55\x8f\xb1\x37\xcb\x7a\x28\x9d\x5a\xa5\x70\x19\xee\x6b\xb8\x26"
+  "\xe3\xe6\x70\x5d\x38\xee\x40\x58\x1c\xdf\x8f\x88\xb8\xc7\x25\x5e"
+  "\x51\xf9\x82\xfd\x45\xd7\xa5\x6f\xbc\x26\xc7\x7d\xe6\x86\x83\xba"
+  "\xee\x1d\x7b\x46\xe1\x39\x76\x9f\xae\x77\x41\x97\x89\xac\x7b\x65"
+  "\xdc\xf3\x5a\x9a\xa5\xda\x5b\xea\xf7\xb1\xbf\x56\x74\xb5\x1a\x35"
+  "\x7a\x4f\xd6\xea\x21\xef\xfa\x14\xff\x96\x03\xda\x8e\x3d\xa6\xd3"
+  "\x36\xfc\x37\xb7\x1f\x94\x6f\xe1\x6f\x29\xf7\x15\x72\x0c\x5b\xcf"
+  "\x69\x18\x27\xd5\x47\xa4\x1c\x89\xb6\xa9\xbb\x4c\xd6\xc5\xdc\x2f"
+  "\x29\x5b\xd5\x7a\x97\x36\xff\x44\xad\xa5\x3f\x43\xbf\x30\xae\x5c"
+  "\xd7\x31\xa2\x2f\x93\xf8\x9e\xa5\x2e\xd3\xb8\x57\x38\x8c\xef\xc8"
+  "\x0a\x4f\xc3\xfa\xe9\xc3\x6b\x1e\x0d\xe6\xb8\x6c\x5d\x6f\xb0\x2e"
+  "\x69\xf7\x5d\xd0\x6c\xba\xf1\x2c\x6f\xcd\x4a\x6f\x8c\x37\x44\xda"
+  "\x61\xe3\x0d\x91\x3a\xc3\x3a\x36\x5a\x67\xc0\x6e\xde\xdd\x57\x33"
+  "\xee\x6c\x84\x1d\x80\xb0\x1b\xeb\x8e\x71\x87\xb9\x8d\xf2\xfd\xac"
+  "\x52\x3f\xc9\x39\xb5\xf1\xeb\x74\x9c\x59\x6f\xf6\x6e\xd3\xe7\x2f"
+  "\xac\xf1\x6c\xab\x45\x96\x37\x3e\x3d\x42\x77\x72\x79\x3a\x3c\x13"
+  "\xc9\x76\xd4\x5a\xca\x73\x2e\xe3\x53\x34\x3d\xdf\x14\xa1\x2b\xb5"
+  "\x3e\x8c\xf5\x64\x64\x5f\x35\xfc\x4a\x64\x5f\x35\xfe\xcb\xeb\x75"
+  "\xe4\xf8\xd6\x6f\xdf\x57\x8d\xaf\x63\xbd\xa5\xeb\xc8\x48\x5d\x30"
+  "\xbe\xad\x21\xc2\x96\x1d\x9f\xa5\xdb\xb2\x21\x3d\x3a\xee\x1c\xeb"
+  "\x28\x94\xdf\xa2\xca\xb6\xce\x47\xbf\x9f\xa6\x97\x8d\xf8\xf2\x76"
+  "\x1b\x64\xb3\x66\xf8\x61\xfc\xb6\x69\x36\xa0\x6c\x9b\xd7\xf8\x3e"
+  "\x3e\xd3\xd8\x22\xc8\xdf\x48\x96\xb3\xd6\x0d\x5f\x51\x67\xa8\xaf"
+  "\x68\xeb\xdd\x38\x48\xdf\xd3\xe1\x76\xe1\xa1\x83\x62\x0f\xca\x69"
+  "\x0e\xaf\xe3\x3e\x84\x1d\xd0\xe6\x10\x24\x6d\x25\x2c\xab\xa3\xf1"
+  "\x60\x64\xdd\x54\x3d\xac\x47\xb8\x1e\x3c\x26\x42\xf9\xc5\x6c\xf7"
+  "\xf0\x1d\xcd\xb0\xa9\xbc\x8d\x83\x32\x3f\x32\xfd\x6b\x57\xb8\x7d"
+  "\x65\xce\x62\x5d\xa9\x8d\x3d\x4f\xc2\xde\xa9\x0a\x9f\x8b\x59\xb2"
+  "\x30\xdb\x56\x52\xba\x6e\x43\xf9\xf3\xb3\x6c\xeb\x36\xac\x2b\x5f"
+  "\x97\x5f\xbc\x6e\x6b\x7e\xf9\xba\x8d\x1b\xa6\xae\xcf\x7f\x61\xdd"
+  "\x73\xb6\xcd\xf9\x65\xb6\x54\xc7\x14\xc7\x48\x0a\x25\x9d\x67\xcb"
+  "\x2f\x2b\x7b\x65\x7d\x61\x81\x6d\xc3\xba\xe7\xa6\x95\x16\x96\x15"
+  "\x96\xdb\xf2\x4b\x37\xbe\xb2\xa1\xc0\x36\xa5\x60\xfa\x94\xd4\xfb"
+  "\x0a\x46\x86\xcf\xa1\xdd\x61\xa1\x9e\xe0\xd5\xcf\xbb\x0f\x5c\x25"
+  "\x73\xa2\xa1\xa4\x34\xd1\xb1\x6e\x83\x9a\xb7\x9b\x30\x76\x46\x2d"
+  "\x95\x20\x3e\xa1\xb1\x86\x69\x7d\xb3\x1d\x6f\x13\xa7\x43\x3d\x6d"
+  "\xf8\x6d\x06\xee\x13\xfb\x6a\x6e\xee\xf0\x98\x6e\x6d\x65\x9a\x81"
+  "\x16\x36\xd4\x6d\xa2\xb8\xfa\x0f\xdd\xb0\xd9\x4a\x78\x5f\x40\xe3"
+  "\x55\x4a\xa9\xda\x44\x26\x3c\x09\x78\x2c\x46\x0b\xcf\x75\x4d\x48"
+  "\xf0\x98\x6e\xb1\xcb\x7b\xc7\x4c\x13\x8e\x78\x93\xe6\x3a\x44\xd5"
+  "\x5c\x87\xe2\xcb\x84\x5f\xea\xf3\xdc\xcb\x5e\xa5\x65\x2c\x9f\x17"
+  "\x4c\x13\xe4\xfa\xc9\x2e\xc8\x32\xcf\xfd\xf6\x7e\xfc\x70\x1a\xec"
+  "\xc1\x73\x3c\x7f\x8b\xb8\x5f\xfa\x8c\x94\x00\xbc\x4c\x27\x2a\x52"
+  "\xe9\x4d\x94\x55\x66\x15\x02\x65\x94\xe8\xf3\x69\xa8\x83\x05\x75"
+  "\xe9\xd0\xea\xb1\x5c\xd6\xe3\xa0\x98\x5c\x9b\x0c\xfc\x6a\x24\x3e"
+  "\xf5\x7a\x1d\x80\x37\xea\x33\x81\x80\xa7\x85\xf1\x8a\x35\xd7\xc7"
+  "\xf3\x5d\xc0\xf3\xb3\xe0\x26\xd0\xed\x36\x75\xc7\xeb\x81\x06\xd5"
+  "\xfe\x50\xaf\x89\x8d\xf8\xbd\xff\x2b\x4a\xd8\x57\x4a\x29\xc2\x75"
+  "\xbb\x38\xed\x0b\x90\xbb\xa8\x83\x12\xb7\x08\xaf\xf8\xbb\xcf\xbb"
+  "\x55\x9d\x6e\xb1\xb0\x6e\xf8\x9b\x17\x3b\x4c\x5c\x27\xf4\x15\x09"
+  "\x8d\x5f\x0d\x39\xb7\x68\x7a\x73\x9c\xf0\x89\xf7\xc2\x6d\xae\x5b"
+  "\xe4\x3d\x78\x6c\x6f\xf5\xa2\x9f\xea\xab\xb9\x25\x0f\x78\xb7\x68"
+  "\xb6\x31\xfa\x8c\xdc\x30\x5b\xea\x16\x96\x33\xdf\x10\xb0\xcd\x3a"
+  "\x6c\x61\x94\x77\x23\x5b\x15\xff\x6f\xf9\x0c\x79\xbc\x61\xf0\x5b"
+  "\xa3\xe1\x33\x4c\xfc\xf6\xea\xe5\xa8\x71\xf8\x2d\x6c\x13\x78\x21"
+  "\xcb\xde\x21\xca\x9b\x5c\x73\x50\x9c\x75\x23\xfc\xc0\xd7\x64\x42"
+  "\xda\xb3\x8d\x07\x19\xfe\x44\x9b\xc7\x74\xf3\x6e\x86\xbf\x6b\x1c"
+  "\xd1\x6e\xa4\xe9\xad\x99\xd0\xc2\xf3\xbb\x88\x43\xfb\x1f\x7e\xdd"
+  "\xbc\xb5\x26\xcf\xf3\xa2\xe4\x39\xad\x86\x6d\xc2\x5a\xc0\x87\x0c"
+  "\x1d\xb8\x82\x7e\x18\xdf\xd3\x6b\xc9\xce\xe5\xe0\xf7\x19\x9e\x0f"
+  "\x01\xcc\x2a\xbd\x3c\x01\xf9\xdf\x1f\x54\x73\x30\x9a\x6c\x4d\x75"
+  "\x3b\xba\x79\x6d\x44\x9c\x80\x7e\x67\x1c\x59\xc6\x90\xa7\x4d\x97"
+  "\x29\xc8\xfa\x59\x29\x57\x29\x64\x17\x35\x13\x33\x1b\x93\x91\x0e"
+  "\x72\xd5\x00\x79\x62\xb9\x42\x5a\xaf\x2e\x53\x90\xb5\x33\x9c\x0e"
+  "\x38\x8c\x3c\xba\x35\xcd\xc4\x3a\xb2\xd3\x74\x6b\x21\xcb\x98\x78"
+  "\xfb\xb1\x0e\x31\x7e\x75\x87\xe2\xd3\xad\x85\x6e\xbf\xe2\x41\x88"
+  "\xee\xb7\xce\x0d\xa3\xfb\x19\xc8\xf1\x48\xa6\xb3\x9a\xab\xbe\xb5"
+  "\x10\xb8\x9d\x91\xb6\xf8\x76\xf0\x40\xf6\x55\xb7\xf2\xfd\xd0\x56"
+  "\x8d\x86\xa7\x42\x34\xbc\xb5\x32\x16\x0d\xa3\x68\x67\xe2\x47\xd4"
+  "\xdc\xba\x97\xdb\x0a\xf2\x1c\xf3\x98\x26\xae\x18\x6a\xbd\x00\x65"
+  "\x98\x4c\xb5\x64\xe6\x32\xda\x52\x64\xfa\xce\x58\x65\x44\xcb\x71"
+  "\x5b\x13\x11\xcf\x85\x73\xbe\xc9\x29\x4c\xd7\xdb\x26\xc6\xe4\xef"
+  "\x73\x11\xb8\xc9\x47\xd4\xdc\x66\x7f\x33\x19\x72\x23\xf1\xbb\x6d"
+  "\xc5\x8d\xf0\x9b\x6c\x53\xfd\x62\xeb\x1d\x2c\xcf\xb7\xed\x73\xd7"
+  "\x11\x71\x98\xf6\x5d\xd1\x8b\xbe\x26\x7a\x3e\x7f\xe8\xf5\x85\xdb"
+  "\x4e\x47\xae\x2f\xdc\x76\x7c\xa8\xf5\x85\xc8\x72\x6f\x1f\xc1\xe5"
+  "\x06\x1b\x57\x18\xc2\xca\xf6\x05\x63\x94\xad\xe7\x9f\xde\x14\x3e"
+  "\x7e\xb9\xfd\x29\xc6\xa1\x1d\xfd\x92\xb8\x65\x85\x41\x00\x4e\x9b"
+  "\xec\xb3\x6f\xcf\x51\xf6\x0a\xdb\x41\xb7\xcf\xe5\x34\xd1\xf5\x18"
+  "\xfc\x33\xa7\xf0\xb8\x8e\xbe\x96\x1f\xf1\x8b\xc8\xc2\xef\xdb\x4e"
+  "\xea\xd1\xc6\x88\xc4\x24\x62\x7c\x24\x10\xdd\x2e\xd3\x0b\xfc\xa9"
+  "\x20\xed\xdb\x2b\x3f\x4c\x83\xe9\x07\xe3\xff\x1d\x7f\x23\x14\xbe"
+  "\x12\x9e\x9f\x0c\x5a\x79\xdd\x61\x29\xd2\x6f\x90\x5b\x90\x9e\x25"
+  "\xd6\xdf\xcb\x78\x2a\x57\xc4\x13\xd9\xcc\x32\xb1\x10\x01\x15\x31"
+  "\xf8\x2d\xc2\xbf\x39\x24\xf2\x1b\x7f\x71\xb9\x61\x05\xdc\x1e\x57"
+  "\x20\xb7\x74\xfd\x20\x6d\x30\xc8\xd8\x64\x09\x2f\xd2\x42\x95\xf1"
+  "\xf2\x47\x22\xff\xe3\x07\x3c\x3b\xe2\x6d\xf6\xc1\x04\x63\x7c\x3b"
+  "\xc3\x92\xff\x93\x42\x7f\x92\xe3\x06\x75\xfc\xae\x7f\xb7\x85\xfd"
+  "\xbe\x5d\xbd\x26\xcd\xfd\x33\xc2\xbf\xf1\x9f\xed\xcc\x08\xfd\x67"
+  "\x48\x3c\x26\xb5\xc6\x4a\x1a\xa2\xff\x1d\x36\x3d\x28\x5c\x42\x43"
+  "\xf1\x53\xea\x23\xbf\x7f\x98\x13\xf9\x7d\xd7\xe1\x3f\x03\xe6\x24"
+  "\x91\x74\x7a\x92\xc0\xb3\xf2\xc1\xc0\xc4\xa8\x26\x93\x58\x15\xd5"
+  "\x84\x42\x7f\x1a\x36\x71\xc0\x27\x10\x16\x6c\x8a\x9d\xfa\x7f\xcd"
+  "\xdf\x84\x9d\x5a\x83\xb8\xdd\x6b\xb9\x2e\xf2\xc1\xa8\x30\xfe\x1e"
+  "\x66\xd3\xc2\x66\xfe\xe6\xba\xf4\x32\xcc\x16\xf6\x6d\x48\xc3\x3f"
+  "\x4d\x90\xff\x53\x7f\x0e\x5c\xbf\xff\xfb\xff\xe1\x9f\x81\xdb\xc7"
+  "\xf7\x7f\xff\x8b\xfe\x84\xea\xc5\xa1\x89\xe4\x8b\xff\x13\x83\x8a"
+  "\x52\x68\x11\x42\x0b\x10\xda\x8f\x3f\x4b\x3f\xfe\xfd\xdf\xf7\x7f"
+  "\xdf\xff\x7d\xff\xf7\xfd\xdf\xf7\x7f\xdf\xff\xfd\x7f\xe0\xcf\x20"
+  "\xc7\x11\x42\xfb\xd3\x7f\xab\x38\x1e\x02\x3d\x5f\x2b\xc3\x8c\x06"
+  "\x0a\xa5\xc0\x70\x7b\x0e\x19\xcc\x34\xcc\xf4\xe7\xb3\xf2\x6c\x83"
+  "\x08\x7d\xcb\x0c\xec\x13\x6b\x26\x9e\x7b\xf1\xdc\x12\x16\x7e\x5b"
+  "\xec\xe4\xff\x01\x7f\x06\x10\x2c\x0e\xe3\xc0\x78\x1a\x46\xc3\xc9"
+  "\x4c\x23\x68\x24\xdd\x44\x09\x34\x8a\x46\x63\x7c\x69\xa1\x24\x4a"
+  "\xa6\x31\x94\x42\x63\x69\x1c\x8d\x27\x2b\xdd\x4c\x13\x80\xf9\x44"
+  "\xba\x35\x36\xce\x95\x94\x66\xc5\x3f\xf8\x3f\x9b\xd2\xe4\x77\xde"
+  "\xf7\xe1\xff\xa1\xe1\xad\x5a\xf8\x19\x2d\xdc\xf3\x7d\xf8\x7f\x68"
+  "\xb8\xed\x7f\xf3\x7b\xd2\xff\xd6\xb7\x01\xaa\x59\x69\x67\x43\x4c"
+  "\x9d\x18\x1d\x6a\xd0\xfe\x06\xbf\xe9\x1b\xf2\x5f\x07\x2f\x32\x7f"
+  "\xf4\x5f\x1a\x9e\xd9\xea\xa7\x93\x48\xcd\xe7\x8a\xf0\xbf\xc0\x50"
+  "\x39\xf5\xbf\x1d\x26\x3c\x16\x3c\x13\xf1\xdc\x8e\xe7\x1e\x3c\x73"
+  "\x74\x38\x2a\x0d\x4f\xc9\x7e\x7e\x94\xe8\xf7\x39\x44\xff\xbd\x0a"
+  "\x6f\x1f\xd1\xb9\xa9\x78\x5a\x49\xca\xc5\x1f\xf3\x88\xce\x37\x85"
+  "\x60\x5e\x9e\x1d\xc2\xae\x67\xb2\xfa\x6d\xc3\xe3\x3d\xce\xbf\x3c"
+  "\x14\xd0\xd3\xb6\x64\xac\xc8\xb4\xcd\x9c\x3e\x7b\xfa\xec\xb9\xcf"
+  "\xda\xa6\x65\x4f\xb3\xcd\x4a\x4d\xbd\x7f\xc6\xcc\x59\x33\x66\xce"
+  "\xb5\xcd\x9c\x33\x6f\xd6\x7d\xf3\xe6\xcc\xb5\xad\xdf\x52\xba\x6e"
+  "\x66\xea\x0b\x85\xb6\x0d\x05\xeb\xca\x6c\xcf\xaf\x2b\x5d\xbf\x39"
+  "\xbf\xb4\xf0\x9b\xea\xf5\x1d\xff\x18\xbd\x5b\x83\x24\x39\x10\x49"
+  "\xed\xdb\xc9\xf4\xc3\xc3\x64\x9a\x5b\x49\x83\x31\x86\x2a\x6d\xae"
+  "\xd4\xae\x3d\x31\xff\xd6\x3f\xbd\xea\xf7\x53\x56\x8f\xfe\xed\x43"
+  "\x2f\x4c\x59\xb0\xf0\x83\x03\x47\xc9\x38\x23\x9b\x8c\x77\xfa\xc8"
+  "\x38\xf1\x18\x19\x2d\xe7\xc8\x18\x57\x4c\xc6\x17\x5b\xc9\xf8\x6c"
+  "\x26\x19\x9f\xec\x21\xe3\x63\x7e\x32\x3e\x10\x23\x6c\x8b\x4f\x85"
+  "\xfd\xaa\x8e\x8c\x1f\x58\xc9\xf8\xb6\x89\x8c\xaf\xcf\x56\x61\x6d"
+  "\x13\xc9\xf8\xd1\xee\x3f\x33\x35\xfe\xbd\x7f\xdf\xd6\x5e\x18\xfa"
+  "\xcf\x94\xfb\xfd\x3c\xe7\xf7\x7f\xdf\xff\x7d\xff\xf7\xfd\xdf\xf7"
+  "\x7f\xdf\xff\xfd\xbf\xf0\xef\x2b\xa3\x89\x7e\x0b\x4b\xa9\xcf\x65"
+  "\xb6\x7a\x0c\xb7\xc8\xb3\xb1\xc4\xe7\xa2\xc8\x2c\x7d\xbd\x68\x4f"
+  "\xf8\xde\x93\x84\x85\x87\x88\xf8\x6c\xe7\x9b\x07\x85\x97\xcf\x6d"
+  "\xa6\xff\x9c\xa8\x0d\x16\x24\xef\x67\x01\x9c\x5c\x0f\xbd\x9c\xa5"
+  "\xf6\x2e\x09\x1f\xc7\xf3\xfe\x27\x84\x97\x23\xbc\xed\x06\xfb\x61"
+  "\xe4\xde\x2b\x86\x99\x3e\x49\xe2\xd3\x1c\x05\x87\x61\xb4\x78\xa8"
+  "\x74\xfe\x0d\x60\x24\xe8\x78\xf9\x8c\x64\x60\x78\xbd\x2e\xb2\xfa"
+  "\x5c\xad\x63\x91\xd7\x87\x3a\xd9\xb5\xbd\x43\x3d\xc2\x45\x71\x6d"
+  "\x8e\x00\x9f\x21\x35\x74\xd1\xc8\xf7\xf1\x36\xe2\xfd\x16\xa9\xbd"
+  "\x9e\x9c\x6f\x32\xc3\x40\x5e\x43\x9f\x6b\x44\xea\x60\x5e\xc0\x96"
+  "\x67\xd0\x69\xe4\x3a\x9f\xb1\xd5\xa8\xd2\x5a\x46\x68\x69\x8d\x48"
+  "\x9b\xab\xa7\x55\x71\xc6\xc5\x5a\xdc\x4d\x88\x73\x44\xc6\x99\x6a"
+  "\xb4\xb8\x04\xc4\xd5\x46\xe1\x67\x72\x5f\x0b\x50\x17\x8d\x38\x02"
+  "\x5c\x6c\x7c\x66\x89\xf3\x68\xe9\x93\x90\xbe\x2d\x12\x16\x91\x16"
+  "\x97\x8c\x38\x4f\x64\xdc\xc7\xa9\x5a\xdc\x78\xc4\x05\x22\xe3\x0c"
+  "\x7a\x3e\x6b\x9f\x6b\xa4\x35\x46\x3d\xb9\x7c\x83\x2a\x9b\xeb\x30"
+  "\x72\x3e\xd2\x54\x72\x9a\x15\xb6\x4a\x62\x5e\x71\xdc\x89\xa6\xc1"
+  "\xf2\x39\x4d\x9e\x0e\xc7\x83\xfc\x61\x34\x05\x2d\x47\x56\xe8\xf9"
+  "\xd3\x6d\x0c\x83\x24\x0d\x19\x8e\x87\x46\x64\x32\x1c\xfe\xc6\xef"
+  "\x89\x5c\x6f\xed\xb7\x8d\xeb\x17\xb9\xa7\x07\x43\x22\x8a\xc7\xa0"
+  "\x87\xcf\x59\x0f\x37\xeb\x32\x50\x66\x15\x41\xe7\xcd\xbc\x6f\xeb"
+  "\x61\x4f\xd0\x25\xc8\xed\xf0\x93\x6d\x02\x39\x2f\xd0\x4d\x56\xde"
+  "\x17\xb4\x7f\x2b\x99\x9d\x25\xc2\xcf\xe7\xfc\xdb\xbd\x3d\xe4\xf4"
+  "\x8a\x6e\x3e\x4b\xbf\xe3\x0a\x99\xd9\x27\xd4\x8e\x97\xc9\xda\x56"
+  "\xf1\x59\xcc\xbd\x48\x41\xf6\x4d\x3d\x91\xf3\x76\x52\x7b\x7d\x27"
+  "\x39\xeb\x23\xf3\x3a\x6f\x25\xeb\x69\x3e\x97\xef\xa2\x44\xc6\xa3"
+  "\xcd\x16\xa0\x40\xf2\xc3\x9e\x8a\x77\xc8\xe4\x9c\x44\xc6\xd3\x05"
+  "\xad\x3a\x2e\x1e\xc6\x65\xf7\x45\x32\x7f\xf0\x3c\x64\xe8\x22\xe3"
+  "\xfb\xa8\xe7\xc3\xad\x7e\xe3\x09\x6b\x16\x9d\xb0\x9e\xa3\x36\xeb"
+  "\x02\x6a\x73\xa4\xd3\xfe\x8b\x94\x70\xc2\x3f\x9f\xda\x4c\x8b\xd0"
+  "\xc6\xd2\xc9\xdd\x83\xdf\xb6\x01\xa4\xf1\xc9\x73\x1e\x5d\x74\xd3"
+  "\x99\xda\x17\xc9\xec\x51\x30\x41\xdf\x9b\xce\xe9\x67\x16\xf8\x3b"
+  "\x56\x3d\xca\x6e\x26\x2b\xf0\xeb\x06\x2e\xf7\x5f\xa0\x84\xb1\x93"
+  "\xad\x94\x0a\x9c\x87\xbb\xeb\x02\x64\xaa\xa0\x11\x43\xb4\xad\x14"
+  "\x79\xde\x19\xb2\xd9\x70\x50\x74\xb3\x8c\xf6\x6e\xcb\x41\x3b\x4d"
+  "\xc8\x42\xd9\x3d\xda\x3e\xc0\x1e\xe7\xfb\x64\xea\xdd\x9c\xc3\xfb"
+  "\x9f\x3b\x11\x57\xa4\xc7\xf1\x39\x6e\x3e\x9f\x3d\x23\x85\x2c\xee"
+  "\x40\x1a\x7d\x72\xad\x9b\xf7\x18\xf6\xf0\xbe\x4f\x86\x97\xe8\xa0"
+  "\x38\xd4\x27\x1e\xf8\xf0\xd9\xc5\x9e\x1f\x20\x1d\xf2\x1f\xf6\xd0"
+  "\x31\x29\x47\x62\xfc\x6a\x5f\x70\xfc\xea\x2b\xc1\xb7\x57\xf7\x8a"
+  "\xb7\x57\x7f\x35\xf0\xf6\xea\x2f\x9d\x5b\xc8\x3c\x30\x7e\xb5\xb7"
+  "\xbd\x44\xf2\xc0\xd2\x5e\x72\x89\xf7\x0b\x9a\xb7\x5f\x22\xcb\x9a"
+  "\x97\xc1\xfb\xc0\x1f\x68\xfb\x3a\xb2\x06\x93\x16\xd7\xb9\x03\x9f"
+  "\xd2\x9a\x0a\x12\xf8\x7d\x38\x56\xfd\x7a\x93\x1f\xb3\xa9\x36\x64"
+  "\x46\x9d\x46\xd9\x3c\xa6\x87\x3a\xb8\x5c\x6f\xd2\x72\x1b\x9e\xc9"
+  "\x78\xec\x78\xa6\x8a\xe4\xc7\xa6\x82\x56\xce\xd1\x3b\x0d\xc4\xe7"
+  "\x14\x66\x04\xc9\x70\x91\x46\xcd\x07\xfe\x96\x21\xe8\x36\x31\x58"
+  "\x53\xed\xfd\x61\x25\xed\x60\x1f\x07\xac\x9b\x58\x2f\xb1\x9e\x42"
+  "\x39\x7b\x3c\xa6\x87\xad\xb2\x2d\x1e\x14\x3e\x91\x5c\xcd\x67\xe6"
+  "\xbb\x7d\xdb\x8a\x0c\xde\x6d\x45\xc6\xde\xe4\xea\x5e\xa4\x39\x82"
+  "\x34\xd9\x1a\x0d\xbb\x19\x16\xda\x84\x77\x54\x80\xe2\x00\xb3\xe4"
+  "\xef\xaf\x76\x98\x0e\x1d\x14\xe7\x90\xee\xec\x20\x2c\xc0\x06\x1c"
+  "\xd0\x7f\x54\xb7\x1e\x06\x5a\x77\xee\x43\x3a\xce\xef\xf6\xa7\xb1"
+  "\xfe\xf6\xb8\x8b\xbb\x79\x9f\xee\x48\xd1\xaf\xca\x43\x1a\x3e\xc3"
+  "\xe9\x1d\xe5\xa7\x61\x7d\x2e\xca\x66\xd8\x9c\xcf\xdd\xd3\x4d\xc8"
+  "\xd7\x2b\x9c\x45\xd0\x6f\xb4\xb4\x4f\x14\x19\xf8\xcc\xfe\x09\xe4"
+  "\x57\x65\x8f\xce\xd6\x71\xe4\x32\xe4\x99\x7d\xc6\x13\xf2\x70\xa2"
+  "\xd8\x4f\xa3\xea\x28\x0e\xf9\x96\x33\x3c\x86\x05\x39\xf0\xa0\xae"
+  "\xbd\x27\x8a\xbd\x14\x14\x11\x30\x3d\x1a\xbc\xa6\x08\x78\x08\x17"
+  "\x80\xc7\xf2\xd7\x86\x3c\xa3\x9a\x24\xbc\x27\xfe\x3e\xc8\xf0\xfc"
+  "\x64\xb2\x49\x7c\x57\x31\x0c\xe9\x77\x03\x30\x5b\x37\x3d\x4c\x3d"
+  "\x94\x68\xf6\x3a\x8b\xe2\xe4\x7e\x41\xe4\xff\x70\x47\x77\xbc\xe8"
+  "\xcd\x89\x1b\x2d\xf7\x0a\x3e\x4c\xec\x67\xa3\x87\x46\x7f\x2e\x7a"
+  "\x8b\xe2\x46\xf5\x90\x89\x71\xe6\xf3\x42\x8c\x67\x38\x2f\x9f\xc8"
+  "\x58\xb5\x80\x56\xa5\x2f\x4e\x5f\x40\x4b\x1e\x5a\xb8\x80\x52\xef"
+  "\x9f\x96\x7a\xef\x8f\xe6\xde\x4b\xd9\x4f\x3e\xb1\x80\xb2\x97\x2e"
+  "\xa0\xe5\x78\xb2\x97\x67\x3c\x91\x9e\xb1\x7c\x01\xe5\x2c\x5a\x8c"
+  "\xaf\x85\x0b\x66\xa6\x3e\x32\x2d\x7b\xe1\xe2\x0c\x7a\x7c\xc5\xac"
+  "\xd4\x59\xb3\xe8\xa1\x8c\xac\x99\xa9\xa9\xda\x7b\x66\x2a\x27\x79"
+  "\x7a\x6e\xc6\xf2\x69\xd9\xa5\x1b\xcb\x37\x4e\x5b\xba\x78\x21\x65"
+  "\x64\x2c\xc8\x8e\xec\x6b\xed\x03\x57\x07\x98\xc6\x3e\xf1\x45\x26"
+  "\xfb\x66\xa0\x06\xf0\x1e\x4f\x8f\x3c\xf3\x41\x96\x4f\x1b\x98\x67"
+  "\x52\xb7\x26\x72\x7f\x65\xea\x73\x25\x9e\x03\xed\xaa\x98\x76\xec"
+  "\x1f\xa1\x8b\xc6\x4d\x41\xdc\x5d\x5a\xdf\x11\x8f\xf8\x40\x64\x7c"
+  "\xd2\x19\xc4\xcf\xe0\x33\x04\x6e\x3c\xa0\xb7\x0f\x3a\x10\x74\xf5"
+  "\x52\xaf\x33\x27\x5e\x9e\xe1\x04\xaf\x79\x6f\x6d\x9f\xcb\x32\x37"
+  "\xac\xad\x77\xf2\x1e\x5c\xdb\x56\x8a\xbb\x4c\x96\xa4\xf6\xf2\x34"
+  "\x3e\x67\x43\xee\x72\x0d\xc6\x95\x41\x18\x23\xb5\x73\xa0\x9e\x06"
+  "\xde\xdf\xac\xe0\x54\x86\xe9\x05\x0f\xc3\xd9\x8f\x38\x0d\xd6\xca"
+  "\x76\xe8\x07\xe8\xef\x8b\x41\xa7\x9d\x44\xf2\xc3\xdd\xc1\x7e\xbb"
+  "\xec\x13\x90\xaf\x45\x97\xe7\xfd\xbc\x77\xb6\x04\xe9\x3e\xc8\x34"
+  "\xf0\xde\x53\xb9\x0f\x95\x12\xd9\x17\x83\x2f\x58\xb3\x3c\x55\x9e"
+  "\x91\x96\x61\x49\x26\x91\x8c\xef\x9a\xe5\x33\x85\x53\x9d\x9b\x46"
+  "\x58\x3c\x87\x81\xd7\x71\xd2\xef\xc8\x36\x19\x1e\x87\xf0\x2d\xc0"
+  "\xaf\x63\x80\xf3\x7f\x21\xf3\x0f\x47\xd8\x53\x48\x3b\x33\x98\xbc"
+  "\x7c\x16\x64\x87\xc3\x60\x27\x8c\x4b\x07\xbc\x7b\xf9\xcc\xba\xb0"
+  "\x9c\xf1\xe2\xf7\xec\xd6\xad\x3d\xd2\xf7\xa0\x07\x71\x41\x27\x60"
+  "\xf6\x0f\x96\x6f\xe7\xbc\x28\xcb\xd4\xd7\x5f\x84\x3e\x2e\x49\xf9"
+  "\x9d\x63\x7c\xbe\x18\x4c\x63\xe5\x32\xb9\x5d\x83\x17\xb3\xc1\xa7"
+  "\x11\x7d\xae\xa4\xe6\x28\x3e\x1d\x07\x9c\x99\xa0\x7b\x07\x60\xa4"
+  "\x04\x7b\x51\x06\xbe\x01\xd7\xa8\xc1\xd5\x61\xf8\x94\x1c\x24\x75"
+  "\x46\xc9\xc1\x08\xc0\x5e\x10\x8a\x4f\x36\x45\xc6\x8f\xbd\x84\xf8"
+  "\x87\xb5\x78\xb4\xaf\xe4\xc9\x91\xf1\xc9\x69\x88\x5f\x84\xf2\x7d"
+  "\x68\x3f\x71\x1e\xb2\xf0\xf9\x1d\x6f\x58\xfa\x15\x51\xe9\x4b\x90"
+  "\xfe\x51\xde\x1f\xcf\xba\x9d\xd3\x37\x6a\xb2\x8a\xf4\x66\xa4\xdf"
+  "\x1d\x55\xfe\x69\xa4\x5f\x1e\x86\x5f\x54\xfd\xc7\x14\x23\x3e\x87"
+  "\x65\x0b\xef\x02\xa4\x19\xce\x6d\x96\xf5\xc5\x89\x62\xb6\x17\x93"
+  "\xcf\x46\x95\xcf\xe9\x5e\x0a\xea\x34\xea\x65\x1a\x59\x0e\x6b\xb6"
+  "\xc8\x39\x85\xc3\x18\x73\x54\x19\x76\xe4\x29\x83\xfc\xcc\xd4\x65"
+  "\x23\x46\x9e\xf9\x51\x79\x72\xa5\x6c\xa9\x72\x34\x1e\xab\x3c\x9a"
+  "\x2e\x0a\x87\xc1\x75\x83\x7d\x34\xa6\x32\xaa\xee\xb9\x28\x77\xdb"
+  "\x3e\xd5\xce\x6f\x82\x4c\xcc\x42\xd8\x12\xc0\x9c\xc3\x72\xc4\xb2"
+  "\xee\xf6\xfa\xa1\x2b\x33\x13\x54\x9f\x3f\xe6\x7c\x62\x05\xf1\xef"
+  "\x69\xfc\x9b\x61\x8b\xfe\x2c\xad\x0d\x8c\x39\x8f\x37\x87\x4b\x3f"
+  "\x50\xdc\xf6\x44\xff\x63\x41\x05\x33\x25\x1e\x6d\xd4\x88\xef\x01"
+  "\xad\x8c\x0c\x3e\x5f\x0c\xfc\x67\x41\x0f\x13\x9f\x91\x46\xf8\x6c"
+  "\x84\x2f\xd0\xe2\xe7\x70\x7a\xfc\x9e\xa9\xfd\x66\xb9\x9d\xa5\xc9"
+  "\x2d\xda\xc1\x58\x79\xd6\x55\xb5\x05\x95\x3f\xa8\xe4\x7e\x21\xe2"
+  "\x6e\xc6\x7b\x31\xde\xf1\x78\x3f\x8e\xb2\xcf\xb3\x4f\x08\xe7\x00"
+  "\xec\x0e\xf5\x7d\x1a\xef\x27\xf0\xfe\x08\xef\xe5\x78\xff\x9c\xdb"
+  "\xad\x77\x73\x11\x45\xc9\x4c\x4f\x50\xb5\xd5\xe1\x8a\x87\x29\xb5"
+  "\x5a\xfb\x51\xed\xf7\x8b\x50\x98\x50\x61\x46\x45\x73\x2d\xac\x3f"
+  "\x93\xe9\x92\x0d\xf8\x25\x5c\xbe\xd6\xee\xe3\x15\x9f\x54\x9a\xa0"
+  "\xca\x67\x52\xfc\xd6\xc2\x54\x3a\x43\x78\x99\x78\xa7\xef\xf0\x09"
+  "\x81\x77\xaa\xf4\x27\x41\x63\x67\x83\x26\x26\x7c\x9b\x98\x4e\x32"
+  "\xbd\x84\x3b\xa6\x29\x8c\xdf\xb0\xc7\xc7\x96\x44\xf1\xbb\x19\xfc"
+  "\xde\x27\xf9\x0d\xda\xe9\x38\x33\xfe\x90\x69\xee\xdb\x86\xe9\x72"
+  "\x03\xf9\xee\x09\xe9\xee\xb1\x2d\x91\x70\x2c\x87\x91\x07\xe3\xa4"
+  "\x31\xd2\x67\x21\xfb\xc5\x89\xab\x60\x19\x1d\x0b\xfb\xff\xb4\xf4"
+  "\x79\x84\xf8\xfb\x18\x8e\xcf\x29\xfd\xef\xf8\xe2\x4a\xb8\x6d\x8d"
+  "\x23\x3d\x5e\xc6\x25\xd5\x94\x30\x2e\x71\xc5\x32\x6e\xa2\x07\xa2"
+  "\xa5\xc7\x91\x3a\xd7\xe5\x8b\x2b\x97\x71\x73\x43\x70\x17\x9a\x35"
+  "\xb8\x71\x6c\x6f\xb0\xdd\x80\xfe\xbb\x1b\x69\x30\xfe\x19\x95\x33"
+  "\xa4\x5f\xa5\xaa\x87\xfd\x10\x1a\xe3\xdd\x95\x14\xef\x0e\x9c\xa5"
+  "\x65\x01\x31\x30\xad\x92\x46\xb8\x03\x47\xe8\x2e\xa2\x24\x77\xe0"
+  "\x1c\xdd\x4d\x34\xc9\x1d\xa8\x45\xff\xdc\xcc\xf1\x9f\xd8\xc9\x60"
+  "\xc0\xdb\x79\x67\xa5\xd1\xe0\x0e\xec\xa6\xc9\x95\x26\xbc\x8b\x69"
+  "\x51\xbc\xe8\x73\x07\xb2\x90\xae\x80\x96\x0d\x88\x2f\xd2\xe3\xc5"
+  "\x9f\xd6\x0e\x90\x25\xeb\x55\xe1\x74\x07\x60\x2b\x07\x4e\x21\x3c"
+  "\x28\x96\x0d\x7c\x8d\xa7\x4f\x04\xab\x16\x9a\x97\x0d\x7c\x21\x16"
+  "\xbe\xfa\x09\xbe\xff\x24\x84\x91\x84\x3b\x30\x9f\xda\x7d\x3e\xa4"
+  "\x73\x0a\x51\xfd\xb0\x7f\xcd\x15\x23\xf5\xb3\x1f\xa4\xea\x85\x66"
+  "\xd4\xd1\xda\x8f\xfa\x89\xe4\x85\xe3\xfb\xb7\xe1\x5d\xb3\x70\x9c"
+  "\xfc\xae\x5a\x68\x17\x96\x85\xd6\xe9\x18\x78\x70\x1d\xdc\x81\x4e"
+  "\x5a\x0b\xd3\x79\xd9\x16\xaf\x60\xfc\x47\xef\xe4\x71\xc7\x7c\xf6"
+  "\xa1\x90\xb8\x6c\x8b\x53\x20\xce\x2c\x92\x16\x5a\xdd\x81\x1e\x12"
+  "\xd5\xc8\x9b\xbc\x70\x8a\x84\x57\xb5\x30\x13\x69\xbd\x9c\x2e\x1c"
+  "\x0e\xc3\xe0\xb4\xcb\x06\xd8\xb7\xd5\xc2\xcc\xfe\xa4\x85\x73\xf1"
+  "\xe4\xe0\xd9\x83\xbc\xef\x0a\x57\xca\x6f\xf8\x1c\x2c\xf2\x1f\xc6"
+  "\x77\x4b\x1f\xfb\x6c\x62\x5a\x0e\xd0\x70\xa4\x3f\x0c\xf9\x49\x87"
+  "\x1c\x32\xbe\x1d\x12\xdf\x9a\x85\xff\x77\x9f\xaa\xc7\x7f\xd5\xea"
+  "\xf1\x29\x87\xf7\x42\xa6\xf0\xdb\xdf\xab\xe2\xfa\x90\x6f\x85\xcc"
+  "\x57\xb5\xd0\x2f\x2c\xe9\x66\x3f\xda\x17\xe8\x5a\xc9\x74\x04\x5d"
+  "\x2b\x99\x96\x80\x8f\xf1\xcf\x5e\x12\x49\xe9\xe6\xfe\xa4\x74\xab"
+  "\xa8\x49\xbf\xbb\x5f\xf6\xd3\xe9\x73\xfb\x24\xec\xf4\x1f\x01\x4e"
+  "\x2e\xe4\x37\x0e\x30\xe6\x8a\xaa\xf4\xcc\x7e\x97\x8d\x96\x6d\x11"
+  "\xfe\x65\x81\x9d\x81\xb5\x5b\x28\x6e\x2a\x55\x1a\xf8\xbe\x2b\xb7"
+  "\xa3\x00\xf5\x6c\xc3\x3b\x1d\xf1\x34\x06\x65\x7d\x02\xb8\x73\xb9"
+  "\x3c\x51\x9d\x9e\x09\x98\x19\x80\x55\xc0\x38\x7d\xcd\xfe\x51\x93"
+  "\xd3\x73\xbe\x96\xf8\xa5\x3b\x82\x55\xe9\x75\x41\x4b\xfa\x1e\x5d"
+  "\x86\x58\x7e\x14\xdd\x6a\x69\xa9\x4f\x04\xdc\x81\x43\x04\x19\xb3"
+  "\xb4\xfb\xce\x71\x3c\xc6\x06\x47\xc0\x67\x96\xa9\xdd\x78\x37\x13"
+  "\xcb\x4f\x7b\xc9\x2b\x9c\xf6\x13\x96\xa1\xa5\x25\xbe\x9d\xd3\xa8"
+  "\xc4\x80\x6f\xe7\xda\x80\x99\xd6\x94\x98\x2a\x07\xaa\xd2\x8b\xda"
+  "\x4b\x98\x2f\x67\x91\x87\xf3\x15\x53\xa2\x01\xf6\xb1\x41\x04\x12"
+  "\x1d\x5e\xd3\xa8\x22\xa7\x68\xf7\x65\x21\x6d\x89\xbc\xbf\x8b\xe5"
+  "\x88\xd3\x2f\xe9\x11\x9e\x01\x4b\x86\x95\xeb\x26\x46\x57\xd2\xe9"
+  "\x9e\x39\xc4\x63\x94\xd3\x3d\xcd\x2c\xa7\x41\xd0\xa5\x1b\x32\xda"
+  "\xbf\xa4\xa7\x32\x7e\xcd\x15\x32\x20\x6c\xe0\x74\xd1\x11\xc4\xb7"
+  "\x21\xdd\x29\x29\xb7\x4b\xaf\x04\x12\x03\x96\xf4\x9c\x40\x55\xba"
+  "\x7f\xe9\x95\x7e\x71\xba\xa8\x96\x9e\xe9\xa9\x04\xad\x8e\xd0\x92"
+  "\x4b\x81\xb8\xf6\x92\x02\xa4\xe9\x43\x78\xb3\x94\xff\x25\x97\x7a"
+  "\xc5\xd2\x97\xc5\x17\x4b\xaf\xfc\x49\x2c\x29\x12\x9f\xac\x75\xd0"
+  "\xe8\x9b\x76\x8a\x20\xb7\x8b\x53\x9d\x47\xe8\xa6\x73\xec\x23\x27"
+  "\x9d\xb2\xf2\x83\x62\xc9\xa5\x2f\xc4\x9a\x97\x99\x36\xf3\xe9\x74"
+  "\x11\xda\x8f\xa3\x96\xe9\xed\x38\x5d\x74\x1c\xe5\xa7\x03\xae\x53"
+  "\xb8\x1d\x87\x90\xb6\x35\xf1\x99\x4b\x16\x3a\xd5\x59\x4b\x81\xa4"
+  "\xf4\x9c\x81\xea\xf4\xa2\x60\x52\xfa\x9e\x60\x75\x7a\x1d\xf8\xd4"
+  "\x1d\xa8\x4e\xf7\x0f\x24\x65\x40\x06\x32\x8a\xc0\xa7\x11\xcc\xf3"
+  "\x6b\x18\xb3\xe3\xfb\xf9\x6b\xcc\xff\xaa\x0c\x87\xb0\x64\xd4\x41"
+  "\x37\x0a\x25\xfb\x19\x0e\x1e\x77\x8b\xa4\x8c\xba\xfe\xa4\x8c\x3d"
+  "\x48\x57\xa7\xda\x57\xc6\x61\x96\x4b\xd9\x37\xd5\x64\xfc\x27\xf4"
+  "\x25\x71\x88\x6f\xc1\x73\x12\x4f\x87\xa8\x59\x64\x07\xfc\x24\x29"
+  "\x53\x55\x8b\xec\xe2\x81\x2a\xd8\x99\x57\x58\x26\x9d\x22\x69\x51"
+  "\xe6\xb2\x81\xb9\x4e\xd0\x11\x6d\x65\x91\x3d\x58\xbd\x68\xae\x48"
+  "\x5e\x54\xe4\x97\xf2\xbf\xe8\x05\x86\xdf\xbf\xcd\xce\x63\x72\x13"
+  "\xe2\x1d\x08\xbb\xd8\xc7\xf2\x6a\x59\xd4\x1d\xb4\x3c\x92\x09\x78"
+  "\xfe\xc7\x5e\x15\xde\x81\xaa\x47\xac\xc1\xaa\x47\xcc\x81\x61\xb0"
+  "\x61\x1d\xc7\x89\x75\x54\xe0\x63\x01\x3a\xfc\x0e\x34\x69\x96\x32"
+  "\xe0\x76\xa0\x1d\x6c\x99\x50\x79\xba\x07\xf2\x50\xf2\x2b\xa9\x9f"
+  "\xda\x7d\x67\x25\x5d\x81\x47\x37\xcb\x15\xf3\x78\x4d\x09\x55\xa2"
+  "\x2c\x7f\xb0\xfa\x11\xf3\x40\x35\xe0\x26\xa1\x9c\xe4\xc5\x6f\xf8"
+  "\x65\x9b\x5d\x0c\x99\x3d\x4e\xec\xcf\x5a\xc9\xf9\xe2\x3d\x43\xe9"
+  "\x49\xd6\x57\xac\xa3\x96\x05\xfc\x2c\x37\xff\xca\xba\x4d\xe9\x2a"
+  "\x5a\xab\xeb\x2a\xd6\x53\x3c\x2e\x60\x5d\x15\xd4\x74\x55\x50\xd3"
+  "\x55\xf2\xdb\x02\x7d\x53\xb5\xd0\xca\x3a\x69\x99\x43\xe9\x9a\x65"
+  "\x03\xa9\x02\xf2\x91\x80\xb6\x6c\x55\xfc\x40\x9a\x9a\x85\x53\x64"
+  "\x7a\x49\xa7\x85\x99\x41\xe8\x1c\x3c\x39\x41\xa5\x73\xea\x34\x9d"
+  "\x63\xd4\x75\x0e\xfb\x5a\x45\xbb\x0a\xc6\xd2\x39\x41\x4d\xe7\x0c"
+  "\x08\xa5\x73\x34\x7c\x3e\xe5\xf0\x01\x4d\xe7\x0c\xc4\xd0\x39\x68"
+  "\xd3\x5c\xdf\x38\x4d\xd7\x54\xb2\xae\xe1\xfa\x42\xde\xcc\x41\xa5"
+  "\x6b\xec\x18\x13\x18\x59\xd7\x0c\x20\x4f\x50\xd7\x35\x7d\x52\x27"
+  "\x64\xb2\xbe\xe9\x7f\x8d\xa0\x43\x6d\xc4\x7a\x46\xea\x94\xc0\xa4"
+  "\x00\xeb\x14\xd0\xef\xc1\x68\x9d\x02\x78\x39\xf8\x6d\xd1\x74\xd5"
+  "\x9e\xc4\x9d\x22\x00\x9d\x52\xb4\xcc\xe1\x03\xaf\xff\x80\xb1\x31"
+  "\x74\xb7\xa3\xbc\xd2\xed\x08\x10\x74\x41\x9d\x68\xaf\x24\xe0\x08"
+  "\x19\x1e\x80\xbe\x20\x42\xdb\xec\x0e\xa0\x9d\xa3\x6c\x7f\x7b\xc9"
+  "\xa7\x34\x80\xf6\xba\xa4\xa7\xd7\xbd\xc6\x67\xb7\x2c\xb9\x24\xbc"
+  "\xa0\x8f\x67\x4d\x49\x25\x74\x8c\xdd\x7b\xba\xe7\xd7\x94\xd5\x29"
+  "\x82\x59\x79\x1e\x1b\xf0\xf0\x2f\x59\xd7\x9a\xc8\xbe\xc4\x97\x5e"
+  "\x11\xad\xd0\x8d\xff\xb2\xe4\x92\x25\x31\xb7\x93\x6e\xcb\xca\x17"
+  "\xc1\x01\xb4\x35\xd4\xb7\x08\xf5\x76\x00\xf7\x3d\x68\x77\x75\x68"
+  "\x6b\xdd\x81\xa8\xb6\x86\x76\xf3\x3c\x7e\xdb\x14\xfd\x32\xea\xd0"
+  "\xd6\x1c\x41\xd9\xa7\x75\xca\xb1\x18\xda\x5b\x1d\xcf\x55\xa1\xbd"
+  "\x39\x82\xd5\xaa\xbd\x05\x55\xbe\xc3\x41\xa6\x9f\x51\x6b\x6f\xe0"
+  "\x05\xe2\x5b\xf0\x9c\xc4\x13\xbb\xbd\x95\x44\xb5\xb7\x97\xb5\xf6"
+  "\x96\xa4\xda\x1b\xf8\x1a\x37\xb0\x4d\xb5\x39\x2e\x83\xc7\x6c\x83"
+  "\x6d\x2e\x79\x51\x37\xfb\xfc\x51\xf2\xc3\xed\x6e\x11\xfa\x97\x47"
+  "\xac\x68\x73\x66\xb4\x39\xc0\x13\x5e\xd6\x9f\x90\xcf\x3f\x72\x9f"
+  "\xb7\xb4\x44\xfc\x71\xed\xc0\x84\x4a\x91\xf4\x88\x15\x3a\xed\x4f"
+  "\xd0\xa7\x7f\x5c\xe3\xa3\x26\xc0\xea\x46\x79\x7e\xb4\x29\x33\xda"
+  "\x16\xb7\xa9\x3d\x03\xdb\x18\xe6\xe2\x3d\x83\x30\x64\x9f\x19\xd9"
+  "\xa6\xd4\x4c\x77\xec\xf9\xc2\x3e\xd7\xed\x09\x1e\x3a\x27\xe7\x7a"
+  "\xf0\xdb\xea\xa1\x3f\x1c\xd1\x7e\x4f\xf6\xd0\xc7\x32\x9c\xdb\x62"
+  "\xc9\x0e\x1a\x7b\x91\x6e\xef\x80\xdc\x13\x7e\x27\xe0\xf7\xb9\x65"
+  "\x77\x7d\x02\x9b\xe2\x63\x3b\xca\xee\xe3\xf6\x28\x5c\xb3\x31\x0e"
+  "\xa1\x34\xc8\xa3\x59\xf4\xb1\xff\xf9\x55\xf3\xd8\xff\x3c\xfb\x9b"
+  "\xc7\xf7\x68\xd0\x60\x32\xde\xc9\x87\xae\x52\x0a\x1e\xf6\x5b\x5b"
+  "\xc9\xf6\x15\x7e\xa7\x8a\xcd\xd6\x91\xfb\x37\xd1\xd4\x44\x9f\xf2"
+  "\x33\xcf\x7e\xf1\x13\x03\x94\xc2\xbf\x85\xeb\xb7\x81\xc6\xab\x9a"
+  "\xaf\xf9\x24\x94\xc7\xbe\xe6\xcb\xec\xd4\x58\x2a\xfd\x5f\x5a\x1b"
+  "\x5d\xe2\xe8\x40\x1f\xd3\xe1\x61\xbf\x8e\x0b\xe3\x06\x3c\x6f\x05"
+  "\x9e\x3d\x2b\xb7\xa4\xc9\x3b\x06\x63\xe9\x99\x3e\x97\x6d\xb0\xfe"
+  "\x43\xc4\x4f\xd5\x69\x32\x44\x7c\x96\x4e\xa7\xa1\xce\xb9\x72\x7f"
+  "\x3d\xb0\x49\xf4\xb0\x6f\x0e\x3e\x8f\xeb\x0c\x88\xff\x87\xfd\xcc"
+  "\xef\x18\x20\xf3\x32\x87\x5f\xb8\x7b\x44\x2b\xdf\x97\xd9\xc8\xfe"
+  "\x42\x2a\x44\x30\x98\xb4\x6a\xa2\xa8\x5e\x65\xed\xdd\x24\x02\x3c"
+  "\xf7\x81\x32\x8e\x7a\x68\xe1\x61\xc5\x8b\x74\x87\x1c\x03\x5a\x56"
+  "\x61\x2c\x41\x49\x0c\xeb\x34\xf2\x0f\x54\xaf\xb2\x21\x1d\xc6\xc6"
+  "\x17\x7d\x32\x9d\x25\xdd\x51\xb2\x95\x6e\xb9\x48\x93\x2c\x72\x1c"
+  "\x50\xb5\x2a\x95\xf5\x02\xc2\x2c\x08\x63\xf8\xb3\xfb\x5c\x93\x60"
+  "\xc3\xfe\xd7\x80\xb2\x75\x27\x4d\xd4\xd3\x79\xc8\xc6\x27\x39\x23"
+  "\xe6\x4e\xb5\xdd\x12\x95\x11\xe7\xbd\x0c\x14\x79\x7a\x8d\x4b\x4a"
+  "\x8b\x1d\x1d\xd2\xeb\xe9\x7e\xf6\xb3\xe9\xdc\x4e\x13\xc1\x1f\xc6"
+  "\xaf\xda\xe9\x10\x5d\xc2\x35\xc9\xfe\xc1\x56\x3f\xc6\x10\x93\xea"
+  "\x3d\xf4\x57\xe5\x43\xd1\x33\x78\x55\x74\x02\x46\xdd\x01\x8c\x03"
+  "\x99\x3e\x4c\x4f\xb4\x9b\x20\xe8\x70\x9e\xf5\x52\xe3\x26\x1e\x0b"
+  "\x4f\xf2\xe8\xf4\x1a\x9a\x27\xab\xa6\xaa\xf1\xe2\x1d\x69\xc2\x25"
+  "\xa8\xf5\x36\x5e\x6b\xb8\xe3\x21\x45\x83\x8c\x3d\xbd\xd0\x25\x3c"
+  "\x97\xca\x3e\x31\xcb\xac\xc2\xdf\xe7\xba\x63\xb6\x87\xee\x3e\xa3"
+  "\xcd\xd9\xf8\xdc\x81\x0c\xd6\x2f\x31\xfb\x2e\x79\x36\x79\x10\xfe"
+  "\x0f\xf2\xda\x27\xf2\x5d\xa6\xac\x9f\x6a\x8e\xed\x50\xfc\xf7\x33"
+  "\x5c\x3e\x5b\xdf\x89\xf8\x32\x9f\xe8\x16\x55\x35\x87\x79\x9c\xc1"
+  "\xe7\x7c\x11\x96\x0f\xb9\x16\xad\xa5\x8c\xd3\x0f\xf2\x5b\x6f\xbb"
+  "\x46\x5d\x18\x0f\xf2\x59\x7a\x35\x7f\xf3\x83\xac\x13\xe5\xa4\xcd"
+  "\x09\xdd\x71\xca\x43\xd3\x8a\x75\xbc\xd8\xd6\x00\x6d\xcd\x6c\x7b"
+  "\xb0\xcd\xc1\xf3\xf3\x65\x15\xc2\xcf\xb6\x07\xd2\xfa\xf5\x3a\x70"
+  "\xfd\x54\xbd\x7e\x90\x10\x5e\x2f\xe0\xe0\xc5\xd8\x5a\xd2\xa0\x6c"
+  "\x0b\x99\xa5\x8f\xbe\x01\x9e\xdf\xcf\x90\x75\xe1\x3a\xcb\xba\x48"
+  "\x3d\x8b\x7e\x22\x30\x07\x63\x29\x19\x5e\x07\x58\x39\x1e\xba\xa7"
+  "\x43\xc9\xd3\x1d\xa7\xa2\x65\x28\xe4\x5b\x36\x3d\xd3\xf9\x35\xdd"
+  "\xe6\x0c\x8a\x0b\x80\xf9\x19\xe8\x14\xc7\xef\x20\xdb\xdb\x7e\x96"
+  "\xdd\xdc\x14\xee\x97\xdd\x15\x57\xd8\xce\xe6\xb4\x63\x90\xb6\x13"
+  "\x69\x3e\xd5\xd2\x7e\xaa\xd6\x66\xe4\x7b\x38\xbf\xd1\x97\x65\x00"
+  "\x8f\x1e\xaf\xec\xf3\x6b\x4a\xf4\x6f\x81\x6f\xbc\x9b\x45\x75\x6e"
+  "\x4a\x6c\x5c\x1e\xc9\xe4\x3e\x6d\xe0\xaa\xe8\x41\x39\xe3\x59\x8e"
+  "\x9c\x5b\xe8\x66\xc8\xe4\xf9\x1d\xdb\x69\x2c\xcb\x98\x48\x5a\x35"
+  "\x57\xd1\x7d\xf2\x5c\xe1\x82\x0d\x0a\x8d\x5a\xb2\x89\x6e\x41\x1b"
+  "\x4a\xbd\x48\x93\x97\xac\xad\xb0\x01\x57\xa2\x03\x97\x89\xed\x94"
+  "\x3f\x21\xfd\x6c\x77\xe0\x33\xbe\x53\x04\xb2\x38\xb9\x58\x97\x45"
+  "\xfc\x76\xdc\x48\x57\x80\xae\x27\xd5\xbc\xc2\xe4\xcf\x78\x2e\xfe"
+  "\x02\x4d\x3e\xc3\xf5\xc5\x63\x40\xd8\x6f\xc4\x55\x31\x51\xa8\x7e"
+  "\xad\xc5\x43\x93\x03\x78\x9f\x94\x0f\x74\x89\xf6\xdd\x82\x74\x47"
+  "\xc5\xd5\x01\x4e\x73\x12\x61\x88\x33\x70\x3b\xa9\x47\xd9\x3e\x0f"
+  "\x2d\x6a\x55\xbc\x99\xdc\xca\xb0\x86\xc0\xa1\x45\xc8\x73\xee\x5f"
+  "\xa1\xbe\x53\x9e\xb1\xed\x30\x00\x8f\x29\x33\x65\xbb\x00\xac\x46"
+  "\xa3\xd2\xd9\x41\xe0\xda\xe0\x0a\x16\x41\x3f\x17\x05\x6b\xd6\x78"
+  "\xe4\x6f\x2d\x4e\x68\x7d\x69\x6c\xf8\x35\xc7\xa4\xaf\x65\x9a\xd2"
+  "\xa2\xe0\xd4\x1c\x6e\x9d\x70\x91\xbf\xa5\xaf\x25\x9f\x65\xad\xc7"
+  "\x5d\x97\xa6\xfc\x3f\x23\x8d\x1a\xe7\x4f\xf9\xa8\x17\x65\xf4\xb9"
+  "\xa6\xa0\xde\xd3\x0f\xab\x75\x89\xb5\x9e\x21\xda\x9e\x85\xdb\x0e"
+  "\xb7\x39\xd5\xa6\x7f\xb8\xef\x74\x93\x6c\x7f\x87\x21\xf3\x27\x35"
+  "\xfd\xcb\x73\x30\x09\x17\xe8\x87\x7b\x4f\x5b\xa5\x7c\x1b\x85\xf1"
+  "\x4e\x6b\x84\xef\x56\xc4\x5d\xff\xdc\x99\x85\x27\x17\x4f\x91\xf6"
+  "\x8d\xd4\x77\xee\xc1\xd3\x81\xef\x0a\x49\xbb\xf7\x0a\x0c\x1e\xc4"
+  "\xf5\xc2\x76\xe7\x6f\x0f\xdd\xb9\x42\xbc\x37\xd9\xa8\xff\x6e\x7c"
+  "\x87\xe7\x11\xee\x04\xbf\xa6\x98\x15\x2f\x7e\x28\xfd\xe7\x03\x37"
+  "\xa6\xbb\x70\xd6\x09\x7f\xdb\x0e\x1f\xf0\xbe\xf3\x68\x5b\x9d\x8f"
+  "\x6c\x77\x72\xfd\xef\x3c\xc6\x75\xf2\x81\xfe\xfc\x2e\xab\x13\xde"
+  "\x13\xf5\x01\xe2\x35\x2c\xc0\x42\xfb\xff\xc9\x5e\x35\x27\x51\xe3"
+  "\x61\x78\x9a\x4c\x08\xbd\xfe\x8a\xce\x6b\x3d\xb6\x4d\x06\xfe\xbe"
+  "\xb9\x41\xcd\xbb\x34\x87\xe6\x83\x7f\x98\x84\x76\xfe\x20\xfb\x71"
+  "\xbe\x4c\x3f\x5c\x29\x40\xeb\x13\x45\xd2\x47\xa4\x97\xe7\x5f\x1a"
+  "\xe4\xbc\xc6\x0f\xa1\xff\xa6\x14\x69\xfe\x70\xbc\x52\xd7\x00\xe6"
+  "\x7e\xc4\xa1\x3f\xea\x39\x5d\xe4\xa7\x01\xae\x33\xf2\xfe\xfa\xaa"
+  "\xdf\xc4\x7e\xac\x77\x94\x40\xef\x00\x0f\x01\x5e\x29\x5d\x76\x67"
+  "\xf7\xf6\x4b\xc2\xaf\xd7\x99\xd7\x3a\x01\x77\xaf\x87\xaa\xea\x86"
+  "\x6c\x13\x83\xf5\xb0\xff\xf2\xc4\x64\xc5\xc7\x20\x68\x15\xc9\x47"
+  "\xfb\x61\xc5\xc3\x1f\x46\xfa\xdf\x45\x38\x1e\xe4\xb2\xcf\xc7\x93"
+  "\xa5\x7d\x87\x3f\x96\xb0\xdf\xe0\xab\xbd\xb6\xcf\x65\x9f\x88\xf6"
+  "\xb1\x5b\xf1\xc6\xae\x7c\xf5\xb3\xdc\x7c\x89\xbe\xa7\x9f\xfd\x8e"
+  "\x5f\x22\x0e\x67\x19\xe7\xf0\x20\xec\x1b\x7c\xa7\x22\xde\xc2\xed"
+  "\x97\xfd\x6d\x86\xc7\x0f\xfa\x55\x22\xbb\xf4\xd1\x97\xb8\x73\xcf"
+  "\x1e\x96\x5d\xa4\x99\x9d\x18\xd8\xb3\x07\xe5\xed\xd5\xe9\x8a\xb0"
+  "\x72\x8e\x67\x39\x45\x78\x33\xe8\x22\x75\x85\x0f\x63\xc1\xd8\xb6"
+  "\x87\xfd\xe4\xa0\x8d\x66\x59\x64\x67\x5e\xf6\xd0\x5d\x67\xa1\xc7"
+  "\xa0\xbf\xd7\x28\x3f\x22\x74\xd7\xa7\xfc\x0d\xfd\x79\x1e\xbf\xcf"
+  "\x9c\x86\x9e\xba\x56\xb3\xdc\xd6\x6f\xa4\xe1\xd7\x8c\x94\x16\xa8"
+  "\xf9\x38\x2b\x90\xfc\xd8\x54\x77\xf7\x31\x6a\x0f\xfc\x1f\x64\x7b"
+  "\x51\xc2\xf8\x07\xf6\xfb\xea\xdc\x22\x06\x3e\xbc\x76\xd8\xe4\x0e"
+  "\x7c\xd1\x2a\x7d\xbc\xab\x73\xf4\x86\x9f\x5e\x50\xf7\x1c\x75\x69"
+  "\xdf\xc2\xf2\xb1\x7d\xff\xf3\x22\xb0\xbf\x8b\x7d\xc1\x58\x47\xee"
+  "\xbb\x46\x53\xdf\xdd\x4a\xa9\xf5\xd7\x68\x72\xc3\x35\xb2\x8b\x7f"
+  "\xe5\x7b\x80\x82\x39\x6b\xae\x58\x08\x7a\x22\x67\x74\x09\x99\x1b"
+  "\xb6\xc2\x9e\x0b\x90\x61\xa0\x1a\xf6\x1c\xdf\x87\xf4\x85\x9d\xf5"
+  "\xe5\xa0\x3d\xd7\x2f\x6d\xe5\x55\xd2\x37\x2b\xf4\x6c\xf3\xa8\x22"
+  "\x32\x24\xe4\x91\x05\xf8\x39\x2f\xd3\x5d\x23\x12\x3a\x61\x4b\xa2"
+  "\xce\x1e\xad\xbe\x78\x4f\x4c\x2c\xa2\xe1\xb2\xae\xd0\xe1\xa2\x7a"
+  "\x4d\xc7\x90\x7d\xb3\x91\x65\xca\xc7\x6d\x09\x75\xb8\x7b\x12\xaf"
+  "\xb5\x1e\x9b\xe0\x37\x95\xd5\x0b\x3f\x87\x97\x4f\x12\x7e\x84\x9b"
+  "\xb9\xec\xa3\x08\xef\x73\xdd\x9d\xea\x31\x3d\x10\x18\x4a\x46\x31"
+  "\x6e\xd2\x74\xcd\xdd\x7f\x2d\x8c\x95\x90\xd1\x45\x45\xdb\x03\xb0"
+  "\xc7\x2f\x73\x3b\xbe\xfb\xe8\xb2\x62\x11\xb0\x6d\xe0\x75\xef\xbb"
+  "\x9b\x78\x4d\x9e\xd7\xe2\xfe\x0a\xb6\xce\x37\xad\xc3\x73\x1f\xc2"
+  "\xe3\x87\xc4\x62\xc0\xac\x59\x54\x24\x30\x6e\xff\xb6\x76\x3d\xef"
+  "\x05\x79\x53\xee\x3b\xb9\xbb\xc7\x43\xab\xd2\x34\xff\xae\x3d\x4a"
+  "\x9f\xde\x73\xca\x07\x1a\x44\xea\x80\x7b\x9a\xd8\x4f\x49\x6f\xd5"
+  "\xf2\x23\xad\xb7\xb1\xee\xbf\xe7\x1d\x65\x0b\x2d\x3f\xac\xfa\x82"
+  "\x7b\xb6\xa8\x39\xfd\x7b\xe6\x7b\x68\x9e\x94\xb9\x92\x3b\x58\x26"
+  "\xee\x29\x17\xc9\xcb\xff\x92\xd3\x4d\xaf\xa4\xca\x8d\x01\x82\x2d"
+  "\xb0\xfc\xb0\x90\x6d\xe5\x32\x89\xb7\x5f\xea\xe3\xbd\x14\xbe\xf1"
+  "\xab\xfb\x60\x1b\x9c\x42\xdc\x11\x2e\xc3\x8b\x34\xa0\xfb\x08\xb5"
+  "\x66\x7f\x4f\x95\x87\xee\xd7\xf4\xe1\x3d\x05\x6a\xae\xf9\x9e\x82"
+  "\x5e\xe4\x85\xad\x38\x06\xf1\xb0\x7f\x97\xa7\x68\x6b\xbb\x72\x5d"
+  "\x15\x61\x6d\x1e\x5a\x21\xe7\x59\xcb\x27\x91\xb5\xdc\x26\xba\x87"
+  "\xb4\xf5\x22\xea\x39\x6d\xb1\xdc\x17\x63\xa4\xf1\x7d\xae\xa9\x66"
+  "\x1d\x2e\xfa\xdb\xbf\xe8\x35\xae\x5c\x89\xb0\x89\x3a\x5c\xa4\x19"
+  "\x8b\xef\xa9\x83\x69\x54\x9e\xf9\x61\x79\x56\xf6\x1a\xef\xfe\x0b"
+  "\x84\x65\x47\xe5\xc9\x8b\xca\x53\x12\x96\xa7\x52\x2b\x67\x77\x54"
+  "\x9e\xda\xa8\x3c\xcd\x31\x70\x6b\x89\xca\x73\x32\x2a\x4f\x47\x0c"
+  "\xdc\x7a\xa2\xf2\x04\x22\xf3\x4c\x4b\x08\xa3\x2d\xef\x51\x49\x45"
+  "\x98\x2d\x32\xcf\xb4\xd4\xa8\x3c\x69\xfa\x37\x6c\xcf\x3c\x65\x1b"
+  "\x40\x9e\xc0\x53\xf0\xf5\x08\xe2\x51\xff\x05\x43\xda\xf0\x2c\x9b"
+  "\x90\x99\x66\xe7\x21\xe5\x27\x9f\xf5\x2a\xcf\x9f\xb3\x3e\x87\x5d"
+  "\xdc\xc3\x32\xc1\x76\x27\x97\xd5\x45\xd3\xf7\xb1\x0c\x01\xe6\xb1"
+  "\xeb\xe9\x31\xed\x64\x14\x9e\x1d\x51\x78\x76\x5f\x4f\x8f\x69\x81"
+  "\xc8\x3c\xd3\x13\x22\xf3\x4c\x9f\x18\x96\xa7\x49\x95\x33\x3d\x35"
+  "\x2a\x4f\x5a\x54\x9e\xec\xeb\xe5\x73\x7a\x41\x54\x9e\xf2\xa8\x3c"
+  "\xbb\x43\x34\x9c\x2e\xef\xa4\xe1\xf6\x80\x70\x8c\x7f\x7e\x7c\xa3"
+  "\x7d\x62\x16\x5d\x9e\xf5\xfd\x62\x4a\xae\x67\x4c\xaa\x55\xfb\xa6"
+  "\xa4\x8f\xa2\x4e\x9a\x31\x87\x94\x9f\x3f\xef\x07\xd7\xfc\xf1\xbc"
+  "\xa6\x04\xda\x76\x9f\x70\xf8\xd1\xe7\xce\x40\x1f\x35\x67\xae\xbe"
+  "\xa7\x82\xf7\xa1\x48\x9f\x76\x72\x3c\x32\xdd\xa3\xda\xdf\x8c\xd9"
+  "\xda\x1a\x0e\xd7\x07\xe3\x8c\x19\xb3\xff\x27\xf1\xfa\x94\xf1\x62"
+  "\x1f\x4f\x80\xe1\x18\x1c\x6b\x0c\xe2\xca\x65\xce\x38\xaf\xe3\xda"
+  "\xa8\xf6\xc2\xb0\x3f\x31\x2f\xfb\xdb\x42\x9e\x23\x61\xe3\x13\xc6"
+  "\xd5\x77\x6c\xab\xdf\x14\x89\xf3\x8c\xbd\x1a\xce\x1e\xa5\xa3\x66"
+  "\x78\x74\x7d\x32\xa4\xfc\x55\xd5\xd4\xb5\x83\xea\xbc\xee\x7f\xba"
+  "\x1e\xf6\x26\xc6\x58\x8c\xf7\x05\x4a\xb5\x4b\xfb\x77\xc3\x35\xe2"
+  "\xdf\xee\x8a\x79\x72\x5f\x80\xaa\x4b\x6a\x1e\xdf\xab\xc0\xb6\x4f"
+  "\x5b\xc9\x57\xd4\x2b\xc7\x68\xac\x1b\x53\xf7\x9d\xa8\xf0\x02\xd7"
+  "\xd4\x1c\x7d\xdf\x8c\x87\x52\x95\x5d\x57\x55\x53\xc5\x7b\x16\x78"
+  "\x1d\xef\x84\x6f\x2e\xa7\xa9\x00\x9e\x69\x3a\x0d\xf8\x8e\x06\xa4"
+  "\x9d\x3d\xd4\x58\x29\x9c\xae\x0a\x87\x59\x5f\x2b\xf9\x49\x6d\x8b"
+  "\x6c\x0f\xf1\x90\xd3\xd4\x8e\x48\x99\x4b\xed\x8e\x94\xb9\x54\x7f"
+  "\x64\x7b\x30\xa2\x3d\xcc\x4c\x88\xcc\x33\x73\x62\x64\x9e\x99\x53"
+  "\xc3\xf2\x54\xa9\x72\x66\xa6\x45\xe5\xc9\x8e\xca\x13\xae\xff\x50"
+  "\xe7\x99\x25\x83\xe3\x4e\xa9\xef\x67\x56\x86\x7d\x1b\x6b\x65\x3f"
+  "\x35\xb3\x56\x0f\xe3\xb9\x3b\xb6\x51\x59\x6e\x34\x78\x47\xa3\x74"
+  "\x14\xa7\x6f\x8b\xc2\xe1\x6c\x14\x0e\x9d\xfa\xf7\x01\x35\x6e\xfe"
+  "\x2d\x68\x77\x97\x26\x67\xbe\xc4\x9d\xf4\x78\x62\xe0\x89\xa7\xd8"
+  "\x36\xe3\xfe\x49\xee\xdd\xda\x0e\x9b\xf2\x0a\x59\x78\xcf\x5c\x57"
+  "\x39\xc5\xb1\xdf\x37\x0f\xdd\x9b\x8b\xf1\x5c\x13\xd2\xf4\xc0\x9e"
+  "\x5a\xd6\x45\x33\xb9\xfc\x3a\x94\x01\xda\xcd\xca\x8c\xc4\x61\x56"
+  "\x4e\x24\x0e\xb3\x8a\xc2\xbe\x2d\xf8\x76\x84\xd5\xdb\x12\x67\x95"
+  "\x7b\x34\x61\x5b\xcf\xaa\xd2\xc3\x79\x0e\x00\x75\xec\x76\x4a\x3b"
+  "\x20\x8d\xf7\xcb\x25\x5f\xa0\x59\xdb\x79\xbe\x40\x83\x79\x3c\x9c"
+  "\xb6\x8a\x16\xb3\xce\x44\xe1\xe1\x89\xc2\xc3\x1b\xd2\x35\x33\x7d"
+  "\xaa\x8d\xdc\x6b\xf2\xd0\x03\xa9\x1c\x06\x5a\xd8\x12\x03\xb6\x31"
+  "\xad\x77\xb0\x9d\x7a\xef\xe3\x3e\xd4\x57\xbc\x66\x4c\xd6\xbe\x57"
+  "\x8a\x3b\xd8\xee\x5e\xd5\x04\xfd\xcc\x7b\x22\x6f\x47\x58\xae\xe2"
+  "\xeb\xbd\xa8\xff\x8f\x33\x15\xdc\x7b\xe5\x1a\x2c\xa7\xc5\x6f\xbb"
+  "\x48\xaa\x89\xb9\xcf\x8c\xe5\xb9\x37\xb9\xa6\x49\xdb\xaf\x69\x03"
+  "\x8c\xbd\x7a\x7b\x08\xd6\xd4\x34\x05\xab\x9f\xa9\x44\x58\x13\xda"
+  "\x44\x9d\x1a\xd3\xe4\x9e\x82\xec\xd7\x81\x7f\x18\x03\xcf\xd6\xc6"
+  "\x32\x35\xec\x3b\x96\xf7\x6a\xb1\x6f\xc9\x04\xb5\x5f\xe2\xde\xb3"
+  "\x61\xed\xca\x67\xdb\xfa\xa0\xb8\x40\xb3\xdf\x61\xdb\x8e\xf5\x06"
+  "\xef\xbd\x3b\x11\xf0\x12\xcf\xb3\xb8\x03\x17\xa5\x4d\x8e\xf8\x3a"
+  "\x95\x77\xb6\x25\x2c\xaf\x57\x9b\x07\xe9\xe6\xb8\x19\x01\x32\x9d"
+  "\xf0\x79\xd9\x87\x7e\x8a\xb2\xe3\x67\xbf\x73\x02\xfa\x02\x79\xd2"
+  "\xf5\x3c\x3c\x67\xc2\x79\x30\xe6\x31\x4d\xaf\x50\xf7\x88\x32\x6c"
+  "\x6d\x4d\x5a\x8e\x8f\xdc\x15\xdd\xe4\xf6\x75\xf0\x9c\xa6\x49\xed"
+  "\x5d\x9a\x5d\x17\xe7\x27\x73\x6f\x75\x0d\x78\x3f\xbb\x6e\xa0\xba"
+  "\xa6\x0e\xb8\x41\xce\xef\x3d\xce\x3a\x30\x9c\x76\x19\x19\xd9\x4f"
+  "\x2c\x5b\x32\xed\xc9\x27\x16\xaf\xc8\x98\x67\x5b\xb1\x6e\x7d\x61"
+  "\xc1\xb4\x8d\xaf\x94\xdb\x36\x97\xae\x2b\x5f\xb7\xe1\x05\xe9\xf6"
+  "\xd3\x96\x5f\xae\xde\xf6\xe2\xfc\xb2\xf2\x05\xfc\x73\xaa\xad\xa4"
+  "\xb4\x70\x93\xfc\x79\xd7\x48\x8a\x04\xb2\xae\xbc\xb0\xd4\x36\xa5"
+  "\x60\xaa\x6d\x51\xfe\xba\xe2\x57\x4a\x0b\x63\xc2\x9a\x67\x2b\x2d"
+  "\x2c\x2d\xcc\x2f\xb0\x2d\xb0\xa5\x32\xe4\x70\x70\x61\xfc\x4c\xd5"
+  "\xf5\x53\x19\xfa\x73\xd8\xd0\xdd\xac\xa7\xb8\x5f\xef\xa2\x1f\x6d"
+  "\x67\x1b\x4e\xfa\xe9\x84\x1c\xa2\x4f\xc0\x18\x7e\x4e\xc5\xf5\xfd"
+  "\xf8\x9c\xaa\x48\xf9\x9d\xd3\x14\x29\xbf\x73\x8e\x5e\xdf\x8f\xcf"
+  "\x89\x6a\xff\x73\xa2\xda\xff\x9c\xce\xeb\xfb\xf1\x39\xfe\xc8\x3c"
+  "\xf7\x99\x23\xf3\xdc\x67\x1d\xd4\x33\xc0\x75\x97\xd4\x4b\xf7\x4d"
+  "\x8d\xca\x33\x3f\x2a\x4f\x56\xd4\x77\x6e\xd8\x37\x6c\xd7\xfb\x8a"
+  "\xc3\x6d\x03\x7c\x57\xe8\x6d\x3d\xa4\xdf\xee\xab\xd2\xd3\x70\xdf"
+  "\xd3\xc8\xf7\x01\xa9\xb4\x87\xc3\xd2\x76\x6b\x69\x07\xdb\x3f\xeb"
+  "\x24\xde\xb3\xa8\xec\xf3\x1f\x4d\xd3\x74\x1b\xdf\x0f\xa4\xf7\xa1"
+  "\x9d\xe0\xc5\xed\x97\xe9\xbe\x77\x1a\x55\x5a\x2f\xef\x63\x15\x6f"
+  "\xaf\xee\x6b\x4c\x26\x33\xe7\x65\x3f\x95\xc2\x35\xbb\x99\x7d\x28"
+  "\x22\x2c\x01\x0f\xf4\xd4\x8f\x6c\x1e\xd3\x83\xd2\xb7\x3e\xef\x69"
+  "\xf0\xd0\x8f\xa4\x2c\x73\xbe\xdd\x72\xef\x9d\x2c\xef\x1d\xbe\xe7"
+  "\x88\x7d\xbf\xb2\xfe\xe4\x72\xd9\x7f\x2a\x97\x0d\x18\x26\x61\x9c"
+  "\xfd\xb9\xe6\x07\xd3\x82\x27\x05\x30\xcb\x75\x98\x80\x67\x23\xe5"
+  "\x6f\x57\xee\x53\x57\x76\xcf\x8f\x6a\x75\xfb\x82\xc7\x0a\xb1\x74"
+  "\x47\xec\x3d\xc9\x94\x78\xc0\x15\xec\x68\xdd\xd1\xc9\x38\xb5\xb1"
+  "\x1d\xea\xb6\x06\xa8\xbd\x3e\x80\xf1\x2b\x59\xe4\x78\xca\x71\x89"
+  "\xdc\x4d\x01\xe2\xf9\xe1\xb5\x0e\xaa\x6c\x34\x06\x3b\xc4\x60\x3e"
+  "\x1e\xa3\xfd\x48\xee\xf9\xdf\xcd\xe1\xc8\x8f\xb1\x84\x97\xf7\x2e"
+  "\x0f\x75\xdf\x16\xa7\x6b\xbd\x83\xc7\x7b\x73\x67\x6b\xb6\xef\x9e"
+  "\x46\xc0\x8a\xb9\xaf\xd6\x48\xee\x3e\xd7\x5c\xf4\x7f\x6b\x3b\x74"
+  "\x9d\x7d\xa2\x4e\xea\x3e\x23\xc2\xf7\x80\x16\x2d\x43\xd9\x29\x9a"
+  "\x7e\x2f\xe1\xbd\x5e\x48\x7b\xec\x46\x69\x19\xef\x13\xa8\x37\xda"
+  "\xe2\xd1\x0f\x76\xa4\xc6\x6b\xfa\xd5\x8c\x7c\x3d\x7a\xbe\x6f\x53"
+  "\x3f\xed\x0c\x81\x17\x6d\xd5\xa7\xc6\x8a\xf3\xf2\xdf\x94\x7b\x75"
+  "\xef\x87\xfd\x37\x57\x6f\x07\x37\xe1\x1b\xfa\x6f\xae\xf2\xf5\xcb"
+  "\x3e\x60\x31\x9e\x2c\x2b\x81\xcd\x66\xf5\x41\x37\xde\x9f\xa7\xc7"
+  "\xc9\x79\x22\x8e\xab\x10\xfe\x13\xd6\x4e\x8e\xab\x18\x8c\xe3\x7c"
+  "\x8c\xb7\x23\xc0\xe1\xb5\x7a\xb8\xea\x5b\xee\x6f\x8e\xfa\x3e\xa6"
+  "\x7f\xe3\x77\x2b\x7e\x0f\xee\xd3\x87\xce\xe5\x3d\x4e\x86\x0b\x34"
+  "\x6f\x52\x83\x6c\x37\xf7\x7b\xf4\x78\x39\xa7\xf6\x3e\xaf\x8d\xf9"
+  "\x28\x98\xbc\xfc\xa8\xb4\xb9\x90\x87\xef\xcd\xc2\x18\xc3\x20\xfa"
+  "\xe5\x7e\xab\x1e\x86\xc3\x6d\x46\xde\x5d\x83\xef\x0b\x74\xff\xd9"
+  "\x46\x96\x6b\xf0\x75\x73\x80\x26\x96\x3c\xc0\xf3\xcf\xf3\xa4\xdc"
+  "\x72\x18\xc3\x65\x78\xdc\x27\x32\x6c\x86\xc7\xf7\x7b\x89\xde\x22"
+  "\xe0\x3a\x8f\xeb\x5f\x3b\x14\xaf\x10\x5f\x19\x46\xcb\x78\x7c\x57"
+  "\x45\xd6\x75\x5e\x53\xd4\xf7\x51\xfd\x9b\xe7\x7a\x95\xec\xcd\x6b"
+  "\xd6\xe2\x4e\xdd\xa8\x2c\x1e\xff\x22\x8d\x37\xb2\xbc\x1f\x53\x24"
+  "\xfc\x1f\x5b\xa2\xbe\x6d\xfa\x77\xad\x5c\x63\xf8\x71\xaa\x5e\x86"
+  "\xe4\x19\x64\xac\x79\x87\x37\xfe\x46\x7e\x5d\x91\xa7\x20\xac\xcc"
+  "\x61\xf8\x2e\x0f\xf1\xef\xc7\x95\x3a\x3c\xfc\xde\x1b\x96\x0e\x76"
+  "\xc9\x8f\xeb\xf5\x74\x6a\x7d\xe3\xc7\x47\xc2\xf2\xb5\x7c\x43\x5d"
+  "\xa3\x64\x77\x41\xbc\x92\xdd\x1f\x7b\x23\x71\x99\x4f\x21\x98\xf3"
+  "\x13\x42\xb8\xcc\xb7\x86\xa5\x43\xfb\x9c\x6f\x8f\x96\xd5\x32\x07"
+  "\xcb\x38\xcb\xeb\xfc\xf4\x18\x71\x7e\x2d\x2e\x2f\xb6\x8c\xcf\x77"
+  "\x84\x85\x6b\xe3\xa3\xf9\xfa\xdd\x29\xac\x9f\x7d\x7c\x77\x99\xe6"
+  "\x3f\x5d\xca\x24\xfb\x55\xd6\xee\x53\x82\x5c\xcf\x6f\x89\x86\xcb"
+  "\x77\xe0\x0c\xc2\x08\xc1\xdc\xa3\x6c\xbc\xf9\xdd\x61\x75\xf3\x79"
+  "\x68\x9e\xbe\x4e\xe4\x55\x73\x83\x3f\xee\x1c\x6a\xdc\xd1\xe7\x5a"
+  "\x30\x39\x92\x66\x0b\x66\x87\x68\xb6\x20\x2d\x04\x77\x41\x56\x58"
+  "\xba\xff\x8c\xef\xdc\xb0\x74\x45\xdf\x24\x9b\x4a\x56\x16\x54\x45"
+  "\x95\xd5\x14\x06\xe3\x48\x58\x59\x2d\x61\xe9\x3a\xf0\x7d\x72\x68"
+  "\xfe\x2c\xe8\x1c\x9a\x3f\x0f\x50\x6c\xfe\x3c\x60\x0d\x95\xfb\xc0"
+  "\xe4\x6f\x6e\x57\x0f\x64\x86\xe1\xd3\x88\xef\x9c\xc8\x76\xf4\x40"
+  "\x51\xd4\xf7\x20\xff\x05\x74\x47\xf3\xd6\xb4\x78\x0e\x2f\x9f\x44"
+  "\x16\xd5\xce\x1e\xa8\x0b\x8f\xff\xf0\x9a\x8a\x67\x1c\xe5\x1a\x1c"
+  "\xaf\x6f\xaa\x74\xad\xd1\xe9\x38\x4d\x58\xbc\x47\xc7\x7d\xf7\x10"
+  "\xbe\xbe\xf5\xfe\xcf\x1d\xe4\xfe\xef\x81\x80\x5a\xb7\x59\xd1\x29"
+  "\x5c\x9f\xe4\x0c\xd5\x97\xf5\xb9\x1e\x9c\x8b\x31\x83\x57\xd1\xe7"
+  "\x41\xc8\xff\x2a\x69\x9b\x88\xaa\x15\x9d\x90\xa7\x6b\x5d\xf4\xe0"
+  "\x1f\xf0\xee\xc7\xfb\x37\x91\xfd\xeb\x83\xb9\xc2\x65\x58\xde\xe8"
+  "\x8a\xee\x77\x1f\x2c\xc7\xd8\xe3\x5a\x62\xa0\x32\x27\x46\x5c\x95"
+  "\x70\xc5\x3d\x11\x23\x9c\x7d\xe9\x5f\xf3\xd0\x83\xe7\x18\xdf\xb0"
+  "\xf0\x56\xe1\x1a\xbd\x82\xd3\x7b\xb8\x3c\xe4\x19\x8a\x6f\xfa\xf9"
+  "\x1f\x25\x7b\x69\x09\x51\xf5\xf8\xba\x8b\xd2\x5e\x57\xf5\x48\xfb"
+  "\x2c\xb2\xec\xb4\xc9\xb1\xeb\x91\x36\x1f\xf5\xf8\x3a\x76\x3d\xd2"
+  "\xe4\xfd\xdb\xc2\x88\xba\x5c\x67\x77\xa4\x95\xa3\x2e\x5f\x4b\xba"
+  "\x47\x86\xef\xd5\xc7\xa9\xce\xaf\x31\xfe\x37\x92\xcc\xbb\xbc\x22"
+  "\xc4\x37\x2d\xdd\xb1\xc4\x3a\xca\x8e\x51\xe6\x29\xe1\x1a\xbe\xdc"
+  "\x43\x0f\x99\xf4\xfe\x4a\x0b\xef\x54\xb8\x80\x4e\x46\xa6\x13\xea"
+  "\x83\x7c\x43\xf1\x5b\x6f\x9f\x6a\x9d\xe9\x21\xb4\xff\x07\xbb\xf5"
+  "\x3e\x1d\xfd\xb9\x57\xa7\x23\xe2\xb2\xa3\xe2\xfc\x61\x71\xc5\x11"
+  "\x71\xdb\x07\xc3\x77\xeb\xe1\xdf\x8e\x4f\x0f\x1d\x8b\xe2\x13\xf8"
+  "\xf3\x70\x46\x64\xbd\x1f\x6a\x53\xf5\x03\x8f\xae\xa3\xf5\x43\x1e"
+  "\xf0\xa8\x3f\x36\x8f\x1e\x0a\xc4\x96\xb5\x87\xe5\xbd\x30\x22\x99"
+  "\x62\xc0\x7b\x98\xcf\x8c\xf5\x4b\x19\xd4\xf8\x74\x3d\x7f\x1e\x5e"
+  "\xa1\xf3\xe7\xdb\xd5\xf1\xe1\xba\xa8\x3a\x0e\x74\xd1\xc2\xb1\xaa"
+  "\xae\x0b\x0b\xa3\x60\x1f\x8d\x2d\x8b\x0f\x9f\x44\x3d\x07\x62\xd7"
+  "\xf3\xe1\xce\xa1\x65\x71\x21\xaf\x87\x0c\x5c\x2f\x8b\x0b\xad\x2a"
+  "\x0f\xc5\xca\x33\x5b\xb8\x62\x95\xb3\x30\x8b\xed\x22\x0f\x2d\xdc"
+  "\xcd\xeb\x74\x61\xe1\x05\x91\xf2\x87\x3a\x70\x3e\xa6\x5f\x40\x8d"
+  "\x63\x98\x0f\x5d\x36\x32\x7e\x93\x4c\xf6\xb9\x16\xb6\x45\xd1\xea"
+  "\x8b\x2e\x4a\xcf\xe8\x35\x1a\x17\x29\x7a\x65\x8c\x88\xc2\xc9\x13"
+  "\x9b\x5e\x0b\xfd\xa0\xd7\x17\xb1\xe9\x95\x9e\x32\x34\xbd\xd2\x99"
+  "\xff\x5f\x5c\x4f\xaf\xf4\xcc\x70\x7a\xf1\x9d\xab\x5c\xbf\x1f\x58"
+  "\x21\x1b\xfd\x6b\x45\xa3\xd2\xe5\x96\x44\xc8\x8a\xca\xd3\xc3\x79"
+  "\x2a\x12\xfd\x4a\x4e\x6c\x13\xc8\x7c\x99\xd2\x0b\xf4\xf6\x3f\xba"
+  "\x8e\x86\x8b\xfe\xd5\xbc\x57\x9b\xef\x70\xb0\xb8\x1d\x5f\xb4\xf2"
+  "\x5d\x8f\x3c\xdf\x18\x55\x6e\x6b\x6c\x5d\x90\x0e\x9b\x3f\xae\x26"
+  "\x46\xb8\x57\xcd\x99\x66\xd8\x23\x75\x44\x86\x39\x92\x47\xa0\x9b"
+  "\x51\x7a\x2b\x37\x7c\x9b\xe7\xc6\x3c\xcb\x70\x5c\xcf\xb3\x45\x37"
+  "\x6b\xfc\xfa\x3a\x12\xbf\x8c\xaa\xd8\xfc\xca\x38\x3c\x34\xbf\x32"
+  "\xda\x86\xe6\x57\x86\x87\xf9\xe5\xa1\x45\xd6\xc8\x7e\x23\xc3\x1f"
+  "\x59\x5f\x94\x8b\x7c\xc2\x38\x6c\x0c\x7f\x7f\xdb\x7a\xeb\x0f\xeb"
+  "\x38\xe6\x55\x23\xec\x2b\xe0\x3f\x89\x71\xfc\xae\x30\x86\x84\x0d"
+  "\x1a\x56\x6d\x1d\xf2\x5e\x90\x84\x76\x8c\x2b\x79\x7f\x9e\xbc\xa3"
+  "\x99\x16\x5d\x0a\x1a\x0d\xf3\xf0\xdb\xd8\x45\x99\x1f\x05\x8d\x71"
+  "\x95\xbc\x97\x4c\x9e\x9f\x93\xeb\x13\x8f\x98\xc2\x79\xc1\x7b\xca"
+  "\x78\x2e\x7a\xbf\x9a\xe7\xfc\x53\x17\x3d\xb2\x4f\xf1\x25\xf3\x9d"
+  "\x48\x3a\x3e\x62\x8f\xcd\x97\x47\xd2\xc0\x97\x3f\xc5\xe6\xcb\x23"
+  "\xb9\x43\xf3\xe5\x11\x07\xf8\xf2\xa7\xeb\xdb\xd1\x23\x55\x5a\x3b"
+  "\xda\xc5\x79\x6c\x1b\xd8\x5e\xcd\xe4\xef\x44\xfc\x46\x1b\x79\xe4"
+  "\x73\x8e\x9f\xd6\xa3\xb7\x23\x99\x87\xc7\xff\xb2\x7c\x2d\x4d\xab"
+  "\x06\x23\x1c\x6e\x77\x62\x4f\xac\x76\x92\x29\xf7\x0c\x4c\x2f\x21"
+  "\x33\x68\x98\x73\x88\x61\x94\x12\x5d\xa6\xcc\x95\x9c\x8e\xc3\xf9"
+  "\x8e\x85\xb0\xf4\xa9\x7a\x3a\x39\x2f\xaa\xd2\xda\xf9\x4e\x72\x4e"
+  "\x17\x05\x5b\xab\xff\x70\xd9\x8f\x70\x7a\x79\x07\x7a\x64\x9a\x4a"
+  "\xd5\x1e\x33\xdb\x22\xdb\x63\x66\x5d\xa4\x7c\x3e\xc2\xeb\x13\x89"
+  "\x41\xe8\x39\xc8\x72\xcf\x80\xcb\x30\xef\xcf\xd3\x36\x17\xa7\x44"
+  "\xb5\x4d\xc8\xc0\xe2\xbf\x55\x32\xb0\xf8\xad\x48\x5c\x17\x4f\x8d"
+  "\x2d\x03\x8b\xd3\x87\x96\x81\xc5\x79\x43\xcb\xc0\xe2\x0a\x96\x01"
+  "\x0f\x2d\x3e\x16\xd9\x36\x17\xd7\x46\xd6\x1d\xe5\xca\xb6\x49\x49"
+  "\xdf\xa5\x6d\xc2\x16\x1a\x33\x54\x3b\xd4\xec\x7f\x03\xdf\x93\xf6"
+  "\x1d\x68\xa6\xee\xfd\xa1\x47\x33\x79\x0d\x09\x3a\xbe\x88\x69\xd8"
+  "\x20\xc7\x68\x8f\xe6\x86\xd3\x71\xbf\x1a\x6b\x39\x91\xf6\x3c\xef"
+  "\xd9\x53\xf4\x7c\xec\x97\x91\xf5\x7f\xb4\x22\x36\x3d\x1f\xad\x05"
+  "\x3d\x9d\xb1\xe9\xf9\xe8\xd1\xa1\xe9\xf9\xe8\x29\x3e\xa3\x7d\x7d"
+  "\x9b\x7a\xb4\x93\xef\xc0\xd4\xfb\xa6\xcb\xf4\xd8\x82\x6f\xd7\x3f"
+  "\x3d\x36\x31\xb2\x7f\x7a\xcc\xf4\xdd\xfb\xa7\xc7\xf2\x62\xf7\x4f"
+  "\x8f\x39\x62\xf7\x4f\x8f\x55\xa9\xf6\xf0\xd8\xc9\xc8\xf6\xf0\xd8"
+  "\xe1\x48\x99\x00\xed\xfe\x6c\xfd\x53\x96\x35\xaa\x0d\x1c\xe8\xa2"
+  "\xac\x77\x60\x53\xbc\xaa\xf8\xb6\xe4\x99\x48\x1c\xb3\x66\xc7\xe6"
+  "\x5b\x56\x16\xf8\x76\x20\x36\xdf\xb2\x8a\x86\xe6\x5b\xd6\x6e\xf0"
+  "\xed\xc0\xf5\x7c\xcb\xaa\xff\xee\x36\x45\xd6\x99\x48\x9e\x65\xb5"
+  "\x7c\x77\x9e\x2d\x49\x89\xcd\xb3\x25\x53\x63\xf3\x6c\x49\xba\xe2"
+  "\xd9\x92\x8a\x48\x9e\x2d\xc9\x8d\xe4\x19\xe8\xf6\x67\xe3\xd9\x92"
+  "\x53\x51\x3c\xdb\xd8\x45\x4b\x97\x80\x67\x67\x14\xcf\x96\x25\x45"
+  "\xe1\xd8\x1d\x9b\x67\x4b\x31\x60\xa4\x8d\xb1\x79\xb6\x74\xe2\xd0"
+  "\x3c\x5b\x3a\x17\x3c\xdb\x78\x3d\xcf\x96\x66\x7f\x77\x9e\x2d\xdd"
+  "\x1d\xc9\xb3\xa5\xc5\xdf\x9d\x67\x4b\x4f\xc6\xe6\xd9\x52\x4f\x6c"
+  "\x9e\x2d\xf5\x2b\x9e\x2d\x4b\x8d\xe4\xd9\x32\x4b\x24\xcf\x40\xb7"
+  "\x7f\x27\xcf\xc0\x9f\x6e\xb5\x5f\x77\x59\x75\xaf\x9c\xd3\x5e\xb6"
+  "\xc7\x43\xd9\xd9\x6a\x4d\x20\x5b\xca\x8e\xc6\xc3\x0f\x91\xa6\xe2"
+  "\xfa\xbe\x7b\x59\xb3\x16\xf6\xe4\xf5\x7c\x58\xd6\x8a\x7e\xb5\xa7"
+  "\xad\x42\xee\xeb\x52\x3c\x64\x9a\x23\x9d\x9a\x23\x5b\xe6\xe1\xbc"
+  "\xe0\xb1\x70\xfb\x03\xc4\x7d\x31\xd2\xfb\x18\x0e\xfb\x13\x89\x84"
+  "\x95\x9d\xf0\x5d\xec\xb2\xa1\xf7\x98\xaf\xc0\x98\x66\x16\xe0\x3d"
+  "\x3e\x49\xc9\x6a\x76\xb4\xfd\xdb\x88\xb2\xae\x28\x39\x7d\x22\x6a"
+  "\xce\x24\x7b\x08\xfb\x37\x9b\xed\xdf\xc6\xd8\x72\x9a\x7d\x03\xfb"
+  "\x37\x9b\xed\xdf\xc6\xb0\xf1\x6a\xf2\x9a\x80\x27\x6a\xbc\xfa\xb8"
+  "\x29\xd1\xa7\x64\x47\xda\xb1\xd5\x2b\x30\x4e\x7f\x7c\x6a\x14\xce"
+  "\xe0\xcd\xe3\xbf\xd4\x70\x7e\x3f\x2a\x7f\x7a\x6c\x9c\x1f\xcf\x05"
+  "\xce\x1f\xc6\xc6\xf9\x71\xc7\xd0\x38\x3f\x5e\x0b\x9c\x3f\xbc\xbe"
+  "\x6d\x3d\x7e\x44\x93\x83\x18\xe3\xf2\xc7\x4f\xc6\xe6\xff\xe3\x51"
+  "\xfc\xa7\x9c\xf2\x0a\xe1\x95\xf9\x23\xd2\x3d\x61\x0e\x4f\xc7\x7b"
+  "\xf5\x39\x2d\xcb\x48\x8c\xb4\xb3\xa3\x61\x0e\x91\x2e\xf7\x3a\xd9"
+  "\xe3\xb3\x05\x31\x65\xef\x89\x3d\xaa\x3d\x3e\xe1\x89\x6c\x8f\x4f"
+  "\x34\x45\xb6\x47\xd0\x3a\x32\x5f\x6b\x64\x7c\x76\xd5\x9f\x4f\xc7"
+  "\x2e\x4f\x8d\x92\x81\x4f\xba\x68\xf9\xaf\x94\x0c\xac\x88\x8f\xc4"
+  "\x63\x79\x66\x6c\x19\x58\x9e\x87\xfa\x7f\x12\x5b\x06\x96\x57\x0c"
+  "\x2d\x03\xcb\xeb\x40\xcb\x4f\xc2\xe5\x76\x79\x45\xda\xf0\xa8\x34"
+  "\xc7\x63\xeb\xbc\xe5\x67\x63\xcf\xeb\x2c\xef\x51\x34\x5e\x31\x39"
+  "\x92\xc6\x2b\x4c\x91\x34\x44\x5d\xfe\xfd\x34\x1c\xf4\xeb\xd5\xe7"
+  "\x5a\x11\xdd\xfe\xdd\x28\x53\x6b\xff\x2b\x2f\x45\xe2\xb8\x42\x1b"
+  "\xff\xc4\x9a\xcb\x5a\x71\x04\xb4\x74\xc7\xa6\xe5\x8a\x93\xb1\xeb"
+  "\xbc\xc2\x83\x3e\xc8\x1d\xbc\xae\x2d\xad\xf0\x23\x7c\xb9\xbc\xbb"
+  "\xf1\x6b\xb2\x34\x20\x7c\x79\x80\xcc\xb2\xbf\x1a\xec\x97\x56\xf2"
+  "\xb9\x03\x21\xe7\x98\x21\xbf\x89\x13\x29\x9b\xfb\x20\xc6\x6b\x6d"
+  "\x45\xf4\x9a\xe8\x4a\x39\xff\xc1\xfb\x58\xf8\x5c\x4d\xa2\x83\xb2"
+  "\xdd\xbe\x00\xe9\xf2\xce\xe9\xa3\x60\x3b\xb8\x5d\x70\x7a\x3d\xad"
+  "\x9a\xeb\xac\x8c\xd2\x4d\x2b\x9b\x62\xf3\x78\x65\xcb\xd0\xb2\xb3"
+  "\xf2\xac\xe2\xf3\x2a\x73\x24\x9f\x57\xf6\x04\x5d\xa3\x57\x70\x5d"
+  "\x21\x03\xdf\xa9\x9d\xf0\xda\xe9\x90\xfa\x7e\xd7\xea\x8e\x92\x1d"
+  "\x74\xdb\x45\x5a\x55\x22\xcb\x33\x0a\x7f\xe2\x4e\x03\xb5\x49\x1d"
+  "\xb0\xea\x77\x12\x4f\xa4\x59\x1b\x20\xa3\xd8\xf5\x52\x07\xc7\x35"
+  "\xba\x84\x5f\xde\x4d\xe9\x12\x67\xd8\x1f\x0f\x64\x61\xcc\x05\x5a"
+  "\xf5\x7a\x44\x7e\x48\xa5\x5b\xc1\x68\x53\xf3\xfb\xab\x5a\xf5\x79"
+  "\xf8\xa1\xe6\xf7\x91\xa6\x53\xdf\xf7\xab\xd6\xc2\x56\x75\x0c\xd9"
+  "\x2f\x03\x27\x3e\x43\xce\x38\xdd\x58\x0f\x3c\x39\x57\x97\x5f\xb5"
+  "\x36\xf7\x64\x66\xe8\x6c\xcb\x93\x2b\x10\x37\xe4\x1e\xe9\xc8\x76"
+  "\xf0\x64\x65\x38\x1c\xe5\xdb\xee\xc9\x5a\xfd\x7c\x0a\x7e\x37\x7d"
+  "\x03\x2c\x1d\x9f\x93\x51\xf8\x80\x9f\x8f\x05\x34\x18\x9d\xdf\x00"
+  "\x23\xc5\xdd\x3c\x8f\xa6\x07\x29\xee\x22\x3d\x3d\xb3\x96\xf7\xe8"
+  "\xd4\x77\x53\x42\x80\x4c\x6a\x6c\x97\x73\x3f\x9f\x0d\xe1\xb1\xa1"
+  "\x3b\xf0\x60\x2b\xaf\xc1\xc9\x3d\x04\xd6\x07\x5b\x4f\x3b\x06\x34"
+  "\xdf\x63\x39\x8b\x99\xa6\xa7\x8b\xbe\x68\xad\x3f\x28\xba\x0f\x49"
+  "\x9f\x53\x39\x11\xe3\xbf\xbd\xbc\xff\x87\xf7\x61\xec\xa0\x07\x91"
+  "\xfe\xbc\x6a\xeb\x4f\x47\xd9\xa4\x39\x43\x8c\xff\x72\x78\xfc\xf7"
+  "\x60\xec\x76\x9e\x73\x83\xf1\x5f\x0e\x8f\xff\x1e\x0c\xef\x37\xd5"
+  "\x3a\x4f\x4e\x67\xb8\x4d\xca\x7e\xa1\x6c\xcf\xb3\x9d\xf9\xd4\x53"
+  "\xf7\xd4\x92\x25\xc0\x6b\xda\x68\x9b\xee\xee\x36\x6e\xaf\x96\xd3"
+  "\xde\x16\xf6\xc7\x60\xe6\x3b\xb5\x55\x5f\xc6\xed\xf5\x29\x39\x5f"
+  "\x98\x18\x50\x6d\xd1\xe9\x10\xde\xa9\x9d\x90\xa1\x8d\x45\x3a\xac"
+  "\x94\xed\x45\xea\xdc\xc7\xe8\x4e\x1a\xee\xee\x96\xfd\xa2\x81\xed"
+  "\x55\x69\xb7\x06\xae\x10\xc3\x3d\x51\x71\x9a\x18\x6e\x70\xb0\x9f"
+  "\x94\xb0\x77\x73\x1b\x67\x98\x0c\xbb\x1d\xe9\x18\x2e\xa7\xd3\xeb"
+  "\xa1\xce\xc6\x3c\x75\x24\xbc\xee\x72\xfe\x05\x65\x23\xfc\x73\x9e"
+  "\x57\x71\x73\x3e\xe7\x6a\x31\xbd\x93\xd7\xcc\xbe\x68\x15\xce\x97"
+  "\xc4\xf4\x52\x9e\x13\x7b\xfa\x7e\xce\xf7\xe1\x1f\x3d\xf1\xe5\x93"
+  "\xc8\xac\xc2\x9e\xf2\xb5\xd9\xfc\xe4\xa1\xa7\xe7\x46\xea\x88\xa7"
+  "\xa3\xec\xdf\x1c\x39\xce\xc4\x3b\x81\xf7\x27\x6a\xfb\x57\x59\x1f"
+  "\x08\x77\xa0\x4f\xca\xc7\x8d\xf6\x54\xf0\x9a\x34\xef\x89\x52\x7e"
+  "\xcf\x9e\xae\x8c\x9a\x7b\xf3\xee\x97\xfb\x6a\x7e\x8f\x72\x57\x8f"
+  "\x52\x32\x92\x3b\x2a\x92\xa7\x4f\x37\x39\x2f\xf1\x5a\x90\xea\x0f"
+  "\xd6\x04\xa2\xf5\xe3\xd3\xad\xba\xed\x16\x15\xde\xa1\xf7\x07\xb6"
+  "\x0d\x0c\x77\x75\x54\x3f\xf3\xb4\xb4\xff\x07\xae\xeb\x17\x56\xf3"
+  "\x39\xaa\x08\x99\x6c\x97\x32\xb4\xda\x7e\xda\x07\xb9\x29\x65\xf9"
+  "\x5f\xfd\x3e\xd2\xec\xe4\x33\x87\xf8\x1e\x7e\x99\x56\xe7\x0c\xb8"
+  "\xc8\x7c\xda\x2b\xcf\x54\x59\x20\x23\x52\x6e\xb9\xdf\x98\xa1\xf6"
+  "\x23\xf9\xa2\xca\x28\xd7\x69\xce\x69\xda\x4b\x7f\x4f\x6a\x3f\x05"
+  "\xcb\xc2\xea\x4c\xde\x9b\x31\xba\x87\x86\x33\x2c\x5d\x86\xdc\x81"
+  "\x0e\x6a\x0f\x44\x8f\x79\x56\x1f\x8f\x5d\xf7\xd5\xdc\xff\xd7\x78"
+  "\x28\x77\x6a\x24\x6f\x57\xcb\xfe\x5f\x5f\xd7\x01\xef\xfd\x91\xf9"
+  "\x72\x13\x22\x79\xff\x74\x13\xc7\x0f\xb9\xc7\xa7\x6a\x05\xef\xe3"
+  "\x5a\xeb\x93\xfb\xbd\x72\xd1\xfe\x9f\xce\xbd\x91\x1e\x14\x96\x15"
+  "\x3d\x41\xa4\xd5\xf6\x05\x43\x6f\xe5\x56\x45\xcc\x19\x8d\x93\x73"
+  "\x46\x6b\xbb\xe8\x19\x6d\xed\xe7\x99\x4f\xa3\xf0\x3b\x32\xb4\x6d"
+  "\x90\xcb\xeb\x3f\x6b\x63\xeb\x8c\xdc\xce\xd8\xb6\x41\x6e\x40\xd3"
+  "\x0b\x6b\x45\x52\xb4\x1c\x3c\x63\x05\x8f\x65\x1e\x7d\x0c\xcb\x73"
+  "\xa1\x43\x8f\x61\x9f\xc9\x1c\x1c\xc3\x96\xb2\x3e\x78\x26\x75\x70"
+  "\x0c\xeb\x8d\x35\x86\xf5\xc4\xe0\xe7\x33\x7b\x63\xf3\xf3\x99\xe6"
+  "\xd8\x63\xd8\x67\x8e\xab\x7e\xfe\x19\x6f\x24\x9f\x9f\x39\x1b\x5a"
+  "\x13\xce\x3d\xf2\xe7\xb3\x87\xd7\xa4\x5d\x6f\x0f\xaf\xf9\xb5\xe2"
+  "\xd5\x9a\x81\x48\xdc\xd6\xe4\xc4\xd6\xed\x6b\x4a\x86\xb6\x87\xd7"
+  "\xec\x1d\x5a\xb7\xaf\x39\x7c\xbd\x3d\x6c\x1b\x16\x95\xe6\xd4\xa0"
+  "\xad\x14\x61\x9b\xad\xe9\x54\x74\x5a\xcb\xf6\x5c\x5c\x58\xfa\x40"
+  "\xa4\xbc\x03\x67\xc0\x83\x6e\xbb\xc8\x3a\x4d\x97\x99\xa1\x68\xc2"
+  "\xbe\x99\x7e\x50\x4b\x23\xd0\x06\x3e\xe9\x73\xad\x1d\x94\x7f\xde"
+  "\xc7\xc7\xe5\xb0\x8e\x1c\x72\x3f\x9d\x51\xc7\x8f\xf1\x58\xbb\xfb"
+  "\x46\xeb\xa5\x71\x56\xca\x7e\xf3\x3a\x7a\xac\x95\xf6\x1f\xc3\xb8"
+  "\x31\xcf\xd6\xfa\xa2\xda\x98\x4f\xed\xc3\xcd\xfb\x8d\xe2\x5b\x5e"
+  "\xd4\x58\x36\xcf\x22\xcf\xf4\x0d\xa9\x6f\xf3\x52\x63\xcb\x68\x5e"
+  "\xe6\xa0\xbe\x2d\x95\x70\x77\x46\xc5\x17\x29\x1e\xe4\xb5\x06\x93"
+  "\xc2\xe7\xba\xf3\x2a\x23\x75\x52\x5e\x51\x54\xbe\xa8\xf1\x5f\x1e"
+  "\xeb\xc4\xa1\xf6\x38\x44\xf5\x37\x79\xde\xa1\xfb\x9b\xfc\xed\xaa"
+  "\xfe\xcf\x46\xad\x2f\xe7\x5b\x6e\xdc\xdf\xe4\x0f\x51\xff\xfc\xcc"
+  "\xc8\xfe\xe6\xd9\xa8\x35\xfa\xfc\xa2\xd8\xfd\x4d\x7e\xa5\xae\x67"
+  "\x94\xde\xc8\xff\x6f\xdf\x4e\xdf\xe4\xb7\x44\xea\x9b\xfc\xa6\x6f"
+  "\xd2\x37\x27\xae\xd3\x37\xf9\x81\xc4\xfa\x58\x75\x79\x36\x25\xb6"
+  "\xbe\x79\x76\xaa\xe2\xe1\xb3\xbb\x23\xf5\xcd\xb3\xe9\x91\x3c\xcc"
+  "\x8f\xe2\xe1\xb3\x51\xeb\xdf\xf9\x96\xff\x59\x9d\x14\x17\x17\x67"
+  "\x8c\x33\x18\x0d\x71\xc4\x97\x47\x19\x68\x78\x9c\x29\x2e\x1e\xcf"
+  "\x30\xed\x3d\xdc\x18\x67\x34\xe1\x89\xd7\xde\xc3\xa2\xbe\x87\x73"
+  "\x5e\x3c\x26\xed\x1d\x1f\xf5\x3d\xec\x1b\xe2\x87\x6b\xe5\xea\xe5"
+  "\x9b\xa2\xbe\xe3\xbf\x21\x7e\xd8\xbf\x33\x3f\x5d\xf7\x1d\x79\x0e"
+  "\x72\xf1\x86\x4d\xf9\xc5\xeb\x0a\xe4\xbe\xf6\x42\x5b\xfe\x73\xcf"
+  "\x15\x96\x95\xd9\xca\x37\xda\x1e\x7e\xe8\x89\x59\xf3\x6c\x6a\x7b"
+  "\x7c\xf1\x82\x29\x05\x23\x69\xc9\xe6\x52\x8e\x58\xb2\x7c\x71\x8e"
+  "\x2d\xfb\xe1\x87\x22\x23\x75\x30\x72\x1b\xfc\x8d\xa0\x84\xb5\xbd"
+  "\xb4\xd7\xc7\x11\xed\x1d\x27\xf5\x4e\x27\x9f\x3d\x57\xe3\x89\xa2"
+  "\x7f\x3e\xd5\x8c\xf1\xc4\x35\xa7\xe0\x73\x15\x17\xa8\xe0\x55\xae"
+  "\xc4\xb4\xa6\x4a\x2a\x79\x9e\xfd\xa9\x14\xbc\x2f\x3e\xf6\x92\xed"
+  "\x51\x32\x5e\xa0\xf5\xe7\xdb\x30\x8a\xe6\x6f\x77\x67\x80\x6c\x4e"
+  "\xb6\x6d\x8b\x76\x22\xce\x20\x1e\x08\x22\xcc\xa7\x9d\xcf\x7f\xa1"
+  "\x5a\x86\x7d\x5c\xa9\xa7\x4b\xec\xa2\xc2\x0c\xf1\xb1\x90\xdf\xec"
+  "\xb7\x46\xa5\x2b\xbc\x39\xe8\x7a\xae\x83\xf5\x42\x7d\x0d\x99\x1a"
+  "\x6a\x88\xde\x49\x26\xf3\x3b\xe3\xd8\xd7\x6c\x61\x82\xbe\x2f\xfb"
+  "\x75\x7c\x7b\x68\xbd\x87\xcb\xe6\xb4\x41\x63\x81\x51\xa6\x4f\x8e"
+  "\x48\x3f\x3f\xb4\x8f\xbb\x30\xc1\x88\x74\xcb\x3e\xa3\x44\x7f\xf2"
+  "\x63\x36\x77\x45\x25\x25\x0e\x88\x2f\xa7\x67\x92\xa1\x1d\x2d\x63"
+  "\x4b\x40\x04\x5a\x4b\x2f\x72\xf9\xaf\x27\x6e\x11\x5f\xba\x61\x37"
+  "\x2e\xe9\x71\x8a\xfd\x97\xc8\x84\x36\x6d\x68\x2d\xe5\xf3\x14\x85"
+  "\x25\x0d\x5f\x93\x09\x34\x98\x78\x91\x9e\x6f\xaa\x58\x22\x06\x9c"
+  "\x4b\xc8\xf4\x8f\x0e\x3e\xf3\xba\x6a\xde\xfe\xff\x42\xa6\xbf\xbc"
+  "\x56\x69\xbc\x26\xac\x54\x51\x2e\xba\x05\xfb\xa0\xf6\x09\x3f\xef"
+  "\xb9\x3d\x95\x37\xc0\x69\xee\xee\x73\x5a\xa9\xbd\xdc\x47\xdb\xcf"
+  "\x09\xff\x9e\xff\xa2\x7c\x56\x9c\xee\xf1\xf1\x19\x5a\xf3\xf6\x25"
+  "\x14\xd7\x95\x43\xc6\xd3\x45\x75\xe4\xce\xf5\x51\xc5\x39\xd1\x7d"
+  "\x2a\xef\x33\x6a\x2f\x3a\x4a\x6b\x3b\xc8\x78\xaa\xf3\x0f\x24\xfd"
+  "\x28\xd7\x7c\x9c\xb6\xe3\x0a\x59\xb7\xaf\xe3\xb0\x2b\xb4\x75\x3b"
+  "\x8d\xda\xfa\x29\x8f\x85\x3a\x50\xce\x25\x7a\xfa\x2c\x19\x00\xcf"
+  "\xb8\xed\x0f\x64\xdd\xf6\x14\x9f\x35\x4f\xa3\xfa\x1d\x64\x15\x4e"
+  "\x7b\xc2\x35\xa7\xdd\x72\x4d\xd8\x93\xfb\x9c\xf6\x94\xf6\x12\xa4"
+  "\xef\xfc\x35\x8d\xee\xa0\x94\x8f\x2f\x76\x18\xeb\xbe\xa2\x89\xb6"
+  "\xa5\xcc\xff\xe7\xeb\xeb\xbf\x42\xfa\x9a\x37\xbd\x41\xe4\x0d\xcf"
+  "\x13\x48\xaa\x35\xbb\x73\xfc\x14\x04\xac\xba\x6b\x34\xb1\xfe\x1a"
+  "\x59\x83\xd5\x6f\x7a\x99\x16\xfd\x35\xcb\x6d\xd0\x83\xc3\x3f\x7c"
+  "\xb6\xc5\xe4\x3e\xd5\x43\xa7\x7d\xd7\xa8\x9d\x7e\x4f\x6e\xc7\xbf"
+  "\xb6\xfe\xe5\xb3\x2d\xf1\xb0\x23\x0d\xad\x5b\x79\xef\xbb\x92\x19"
+  "\xe7\x69\xf6\x9f\x57\x49\x07\x76\x50\x42\xc9\x56\x1a\x7e\x11\xe1"
+  "\x52\xe7\x54\x2d\xb2\xbb\x03\xff\xda\xba\x55\x9e\x03\x5f\xef\xd9"
+  "\x71\x9a\xe2\xda\x7d\x75\x7c\xde\xd8\x38\x90\xfc\x71\x9a\xdb\x77"
+  "\x86\xdc\x25\x7f\x6a\x0d\x5a\x3e\xb6\xef\x0d\x92\xf9\x57\x57\xcf"
+  "\x18\xdd\xa6\xab\xe4\xce\xf1\xd1\x27\x28\x5b\xd4\x7c\x9c\x05\x5d"
+  "\x95\xd6\xee\xf3\xb3\xdf\x9d\x54\xd1\x6b\x1d\x79\xa0\x94\xa6\x36"
+  "\x7c\x45\x93\x0f\x7d\x45\x76\xd1\x67\x37\xf2\xd9\x6e\xf6\x97\x76"
+  "\x08\xef\x04\x8c\xbd\x50\x5f\x79\xc6\x5b\x24\x69\x67\xbc\xfb\xed"
+  "\xd4\x78\x2d\x74\xc6\xfb\x5a\x6f\xe8\x8c\x37\x64\xc9\xc2\xe7\xbc"
+  "\xd1\x2e\x4e\xb2\x3c\x1f\xb8\x4c\xa6\x5d\x97\x89\xa6\x57\x1a\xc9"
+  "\xf6\x2c\xfb\xfa\x28\x7a\xc5\x5d\x70\x49\xfe\xbe\x40\x45\x53\xf1"
+  "\x4e\xc0\x83\xf1\x5b\xd1\x24\xae\x5f\xa7\x26\xb7\x08\x33\x22\x6c"
+  "\x2c\xde\x71\x78\x8f\x72\xd6\x0b\x2f\xca\x60\x9f\x33\x23\x59\x7e"
+  "\xb5\xf3\xe4\xfe\x3e\x57\x91\xc9\x43\xd5\xc7\x75\x39\x56\xfa\xbc"
+  "\xd0\xf2\x49\xd7\x25\xf6\x6b\xee\x95\xf8\xf4\x17\x19\xd8\xc7\xb9"
+  "\x16\xce\x38\xac\xe7\x72\x51\x7e\x36\xde\x89\x78\xd0\x2e\x5f\xe8"
+  "\xd4\xf3\xf6\xf6\x17\x71\x99\x85\x08\x17\x7a\x38\xea\x6b\xe2\xb8"
+  "\xbf\xe9\xba\x64\x54\x69\xec\x46\xc0\xf4\x6b\xf0\xd1\xd6\x0b\x8e"
+  "\x71\x9b\xee\x35\x26\x8a\x13\x05\xb3\xa9\x7e\x9c\x38\x73\xe8\xa0"
+  "\x68\x53\x6d\xad\xe8\xb0\x87\xde\x94\xbe\xcc\xd1\x67\xb7\xed\x45"
+  "\xdc\x09\x1b\x11\xd3\xa5\x2d\x8f\xf7\x93\x16\x9d\xf4\xd0\x4d\x93"
+  "\xc3\xeb\x20\x5c\xcf\xb6\x70\xbf\xf9\x57\x3b\x5a\xe3\x85\xf1\xb9"
+  "\x96\x76\x4f\x0f\xfd\xe5\xb5\xee\x78\xe7\x3f\x90\xd1\x1d\xb8\x40"
+  "\x33\x52\xc8\xca\x73\x30\x8d\x07\x85\x07\xef\x6e\x3c\x3d\x90\x93"
+  "\x5b\x2f\xd2\xba\xb1\xf7\xa4\x50\xca\x3f\x39\x48\xd3\x47\xeb\xa6"
+  "\x85\xe9\xa3\xbf\x3d\xdd\xd9\x12\xa6\x8b\xd6\x17\x5e\xaf\x8b\x8a"
+  "\xf3\x95\x2e\x12\x01\xa5\x7b\x06\x3c\x5a\xf8\x92\xa8\x70\xed\xbc"
+  "\x4a\xf1\xcc\xa8\x70\xbf\x16\x7e\x6b\x54\xb8\x57\x85\xbf\xf4\x8c"
+  "\xae\xeb\xda\x19\x8f\xcd\xac\xeb\x5e\x7a\x88\x75\x5d\x7b\x81\xa6"
+  "\xeb\xe4\x59\xcc\x97\xa6\x88\x9f\x55\x12\xfb\xd1\xe9\xa2\x17\x07"
+  "\x18\x7f\xf1\x31\xe9\xb8\x8f\x40\xd8\xaf\x39\xac\xea\xf7\x64\xc2"
+  "\x23\xf5\x9c\x70\x15\xdc\xce\x7a\x8e\x75\x1c\x9f\x83\x79\x6f\x9c"
+  "\xe8\x78\xef\xa0\x38\x5b\x7f\x50\x9c\xea\x73\xbd\x38\x55\xd7\x77"
+  "\x3f\x45\xd8\x5e\x84\xfd\x14\xf1\xac\xf7\x98\x26\xa7\x73\x5a\xd8"
+  "\xaf\x68\x27\x64\x6c\x6e\xa2\x81\x4a\xf6\x43\xe6\xd9\xdf\xd5\x6e"
+  "\xd0\xd7\x5d\xee\x93\x67\x4e\xa4\x3f\x70\x63\x2a\x74\x54\x27\xb7"
+  "\xb7\x71\xbb\x82\x3c\x2f\xf1\x19\xed\xf0\x89\x8b\x7c\x36\x85\x71"
+  "\x58\xbb\xe5\x51\xf6\x6f\x6d\x68\x83\x75\xc4\x7e\x08\xf8\xec\x0c"
+  "\xf4\xae\xa9\x0a\x38\x29\xff\xbe\x2f\x1e\x83\xe5\x92\xa6\x78\xbd"
+  "\x5e\xfa\xcf\xbf\x40\xeb\xfc\xc2\x05\x5d\x88\xba\x25\x0e\x54\x12"
+  "\xfb\x62\x41\x1b\xe5\x79\xd6\xa2\xf7\xf0\x54\xe9\xfe\x58\xf8\x2e"
+  "\x05\xa4\x71\x77\xf8\x89\x71\xf6\xd0\x8b\xe9\xa7\x2b\x5a\x38\x7f"
+  "\x37\xd3\x46\xb8\x9c\x3a\x0c\x83\xf4\xe7\x82\x31\x3c\xfb\x73\x41"
+  "\xba\x0e\x65\xcf\x2c\xb7\x9d\xce\xf5\x12\xeb\x79\x77\x37\x60\x54"
+  "\x5c\x50\x30\x00\x4b\x40\xef\x47\xc4\x69\xf0\x47\x6d\x17\x5f\x02"
+  "\xfe\x31\xe6\x17\xfb\xe5\xe2\x7d\x49\xa0\x4b\x02\xfb\x66\x50\x76"
+  "\xe7\x8b\x0b\x1a\x7f\x4f\xa4\xf9\x16\x83\xbc\xbd\x38\x9f\x7d\x77"
+  "\xb1\x3f\x31\xe9\x4b\xcc\x38\x9b\xc4\x66\x7b\xc2\xa0\x3f\xb1\xff"
+  "\x00\x5f\x62\xa0\xbf\xb5\xc1\x28\x8e\x02\xff\xf9\xec\x4f\x0c\xf8"
+  "\xd7\xb3\x1c\x6a\x75\x4a\x7b\xeb\x69\x49\xf3\xdd\x1c\x76\xc0\x25"
+  "\x4e\xea\xfc\xe7\xfa\x72\x5d\x10\x57\xa4\xec\x41\x71\xc6\x43\xc5"
+  "\x69\x1c\x8f\xb0\x15\x9c\x7e\x06\xf4\x98\xbb\x60\x80\x3e\xec\x1a"
+  "\x30\x1e\xd8\x4a\x26\xa5\xd3\xd6\x3f\xc5\xf9\x95\x4e\x5b\x6f\x09"
+  "\xe9\xb4\xf5\xf1\x4a\xa7\x29\x1a\x2b\x9d\x56\xfc\xb5\xd2\x69\xc5"
+  "\x5f\xca\xfd\x43\xd0\x69\x1c\xc7\x7a\x4d\xd7\x69\x87\xc6\x89\x93"
+  "\xac\x3b\xfa\x5c\xc5\x1e\x5d\xb7\xed\x43\x18\xeb\x0e\xc6\x51\xe9"
+  "\xa9\x97\xe6\x8a\xff\x6e\x27\xb5\x3f\x93\x7f\x17\xb1\xbf\x8c\x6e"
+  "\xed\x37\xf7\x23\x8f\x2b\x1d\xb7\x7e\x76\x48\xc7\x15\xb7\x84\xf2"
+  "\xb2\x8e\x5b\xbf\x58\xe9\x38\x15\xde\xf8\x34\xeb\xb8\x97\xe6\x32"
+  "\x0d\x34\xf8\x46\x5e\x37\xd3\xd2\x33\x1d\xd3\xc2\x75\x5c\x64\xfb"
+  "\x5a\xbf\x57\xd7\x71\xac\xdb\xf0\x5d\xef\xa1\x91\x27\x65\x7b\x43"
+  "\xba\x5a\xd0\x5c\x6f\x77\xcc\x03\xae\x33\xfb\xc9\x67\xba\x2d\xbc"
+  "\x44\xc3\x35\x3f\x35\x5a\xbd\xd7\x77\xe8\x67\x32\x41\x7f\x4f\xb4"
+  "\xcd\x8c\xef\x41\x3b\x0d\xbc\xbe\x9d\x7d\x38\xba\x2b\x2f\x90\xbb"
+  "\x4e\x54\xb6\x07\xce\x51\x70\xd7\x4b\xe7\x99\xaf\x18\x5f\x0c\xe3"
+  "\x37\xeb\x9d\x8b\xb4\xe1\xe6\xb5\x3e\x39\x5f\x7f\xfe\x80\x11\x71"
+  "\x0e\xfa\x71\x58\x9c\x3c\x63\x1f\x96\x6f\x5a\x58\xdc\xe3\x1c\xc7"
+  "\x73\x8c\xf8\x4d\x43\xcd\x29\x7c\x07\x3c\xde\xbf\x01\x1e\xbf\xbe"
+  "\x01\x1e\xff\x4d\xe2\x01\x7b\x0b\xe3\xa3\xa4\xcb\xb4\x41\x3b\x1b"
+  "\x82\x27\x66\x39\x1b\x47\x68\xf1\x71\x61\xf1\x61\x65\x6d\xbc\x2b"
+  "\x46\xfe\xb0\xf2\x36\x2e\xfe\x06\xf8\xeb\xbe\x01\xfe\xeb\xdf\x00"
+  "\xff\x97\xac\xfb\xf8\xdc\xdf\x80\x2b\x32\xdd\xf4\x80\x6c\x7b\x27"
+  "\xd9\x77\x14\xd2\xfd\xb3\xb6\xde\x72\xde\x39\x49\x8e\xff\xa4\xbf"
+  "\xa0\xfd\x88\x97\x7e\x72\xa1\x97\xd3\xb7\x10\xa9\x3d\x7d\x7a\x9e"
+  "\x92\xf8\x68\xdc\x46\x07\x74\xdc\x64\xfc\x94\x68\xdc\x10\x3f\x2d"
+  "\x2c\x3e\x23\xc4\xf3\x8d\xad\x37\x98\x47\x4a\x70\xd7\x91\xbc\x3b"
+  "\xe6\x04\x86\x2d\x7c\xd6\xa7\x76\x70\x6d\xa4\x04\xf2\xbf\x5e\xae"
+  "\xed\x68\xe7\x8a\x7b\xa0\xd3\x6f\x67\x3f\xa0\x6c\xf3\x6a\x67\x41"
+  "\xc6\xa3\x1f\x49\x66\x3f\x31\x3c\x9f\xbe\x76\x20\xdb\x78\xa2\x82"
+  "\xdb\x4e\x49\x87\x9e\x77\xa8\xb9\x47\x2e\x57\x2b\x53\x9e\x93\xea"
+  "\x73\xbd\x9c\xa0\xe7\x61\xd8\x7c\x36\x08\xfa\xff\x76\xe9\x7f\x2d"
+  "\xd0\xc3\xfa\x76\x3c\xec\xe3\x64\x55\x4e\x1e\xa9\x72\x5e\x4e\xf3"
+  "\xd0\x06\xc7\x8d\xce\x61\x0d\x5d\xbf\x97\x2b\xbe\x7b\xfd\x48\xab"
+  "\xdf\xcb\x2d\xdf\x50\xbf\x1b\x95\xeb\xfb\xee\xe5\x5a\xb4\x72\x4b"
+  "\x53\xbf\x3b\x5d\x4b\x0b\xbe\x3d\x5d\x53\x35\xba\x96\xd6\x7d\x03"
+  "\x5d\x63\x95\x73\xea\xdb\x97\x63\xd3\xca\x29\xa3\x58\xe5\x90\xfc"
+  "\x1b\xd2\x9f\x90\x59\xbf\xbb\x85\xef\x31\x52\x77\x34\x94\x65\x86"
+  "\xdf\x51\xa5\xee\x37\x2a\xcb\xd5\xef\xa8\x0a\x9d\x33\x2b\xdb\xb2"
+  "\xb6\x89\xed\x10\x11\xf4\x50\x59\x05\xcf\x05\xa6\x6f\x57\xfe\x0b"
+  "\xb5\x3c\x55\xdf\x70\x37\x16\xfb\xf0\x49\xe5\xb2\x85\x90\xbe\x62"
+  "\x7c\xca\x0f\x60\xd9\x3f\xf3\x99\x41\xb5\xa7\x48\x3a\xfd\x62\x58"
+  "\x18\xc3\x96\x49\xff\xed\xec\x5b\xbe\xd7\xa9\xa5\x9f\xc0\x7d\xa8"
+  "\x9e\xa6\x9c\xf4\x34\x31\xe7\x24\x6b\x6a\x3c\xcd\x3b\x52\x23\xce"
+  "\x37\x66\x94\x96\x6e\x2c\x9d\x67\x2b\x5b\xff\xec\xb4\xb2\xf2\xfc"
+  "\xf2\x57\xca\xe4\x41\xf8\x91\x84\x00\x5b\xf9\xba\xf5\x85\x1b\x5f"
+  "\x29\xb7\x6f\xce\x5f\xa7\x0e\xce\xdf\x85\x84\xe1\x89\x28\xe2\x4e"
+  "\x13\x2b\x74\xd0\x19\x61\x94\x3e\x2e\x7a\xb8\x4e\xec\xeb\x44\x3f"
+  "\x17\xdc\x66\x25\xf2\x61\x7c\x04\x1c\x9b\x3d\xf4\xa4\x57\xa7\x23"
+  "\xfb\x5f\x84\x9d\x64\xbd\x48\xe5\xbf\x61\xde\x2f\x83\xc9\xdb\xa8"
+  "\xfc\x56\x48\xdf\x03\xee\x72\x04\xb4\x93\xb9\x75\x13\xcf\xf3\xbe"
+  "\x32\x37\xe8\x2a\xb7\x4b\x7f\x92\x5b\x79\xfc\xfd\xca\x33\xba\x5d"
+  "\xc2\xeb\x56\x6a\x9d\xf9\xf6\x07\x2f\x50\xf9\x3e\x2e\x97\xdb\x4d"
+  "\x03\xec\x5f\x86\x25\x5c\xe5\x69\x6c\x03\xe3\xdb\xdc\xe7\x7a\xc5"
+  "\xae\xdb\xbe\xc0\x37\x41\x24\xd5\xc0\xae\x79\x25\xf7\xb7\x16\x2f"
+  "\x69\x67\xc9\xcd\x0d\xea\xdc\xb8\x09\x69\x57\x0c\xa6\x75\xb1\x6f"
+  "\xe5\x9a\x33\x7c\xef\x59\x4c\xfa\x26\xe7\xf1\x3d\x09\xf1\xe1\x75"
+  "\xc6\x98\x1d\xfc\xd9\x34\x0a\x75\x4f\x61\x5e\x6b\xfe\x4e\x86\x01"
+  "\xf7\x2b\xca\xbf\x73\x1e\x21\x6c\x18\xde\x56\xe6\x29\xfb\x58\x40"
+  "\x1c\xef\xf5\x31\xb4\x57\x7c\xd1\x7a\xc2\x7a\x01\x72\xfd\x0a\xcf"
+  "\x5d\x4f\x56\xe7\xe2\xf2\xf8\x0e\x92\x78\x77\xe5\x35\x6a\xb3\x89"
+  "\x56\x9e\x03\xf4\xd0\xa6\xc9\x6d\x36\x1f\x89\xb8\xd5\xe7\x39\x1f"
+  "\xda\x85\xd5\xe9\x60\xdb\x07\xe1\xf2\xfc\xdf\x26\xab\x4e\xf3\x72"
+  "\x9b\xb8\xc4\x69\x86\x9a\xb7\xe6\x3e\xf8\x80\xec\x4b\xbe\x22\xde"
+  "\xe3\xd5\x49\x9b\xe6\x47\xeb\xfb\x29\x05\xf3\x6c\x05\xf9\xe5\xb6"
+  "\xe2\x75\x1b\x0a\x6d\x05\xeb\x0a\x6c\x1b\x36\x96\xdb\x5e\xd8\xc8"
+  "\x13\x48\x3c\x65\x14\x21\x13\x41\xae\xdf\xe6\x9c\x78\x7d\x8d\xbc"
+  "\x77\x73\xd1\x30\xd4\x1f\x34\xd9\xfc\x56\x6f\x5f\xd1\xf0\x48\x9a"
+  "\x6c\xd6\x7c\x71\x6d\xc2\xf8\xef\x95\x62\x75\xbe\x30\xae\x1b\xdf"
+  "\xa8\xff\xa6\xd4\xc8\xb6\xb7\xf9\x77\x5a\x5a\x9f\x9e\x56\xca\xc5"
+  "\x1d\x17\x07\xe3\x0e\x68\xf2\xd8\xa8\xce\x41\x4b\xbf\x3a\x8d\xf2"
+  "\x8c\xc0\x66\xfb\x90\x79\xd8\x97\xd8\x56\x7a\xee\x32\x6d\x4e\x12"
+  "\xae\x4d\xb9\x9a\x0c\x99\x83\x55\x79\x16\x4d\x7e\x20\x13\x9b\x8b"
+  "\xae\x97\x9f\xcd\x6d\x2c\x3f\xa2\x2f\xc7\x2c\xf7\x93\x04\xfc\xd0"
+  "\x53\xf8\x46\x7f\x0a\xdc\x4f\x71\x3d\x7c\x9b\x73\xcc\xce\x77\x64"
+  "\x7f\xfd\x39\xaf\xcd\x9e\xf0\x4b\x5f\x50\x23\x20\x1b\xe0\xd1\xe6"
+  "\xe3\x3a\x8f\xf4\xf4\xb1\xdb\xb0\x94\x97\x48\x19\x93\xf4\x74\x8c"
+  "\x95\x32\x06\xbb\x00\x38\x19\x75\xbb\x80\xfb\x00\x0f\x39\xa6\x96"
+  "\x6f\x17\xa2\xcf\xe5\xb0\x85\xc9\xc1\xe5\x58\x72\x00\xde\x3e\x57"
+  "\xbc\xf1\xb9\x97\xd0\xd0\x4b\x0b\xcb\x9f\x2b\x62\xdf\x19\xac\x07"
+  "\xa4\x63\x8e\x29\x05\xb6\x57\xca\x0a\x9f\x1b\x49\xb1\x52\x0d\x46"
+  "\x86\xf3\xdf\x12\x84\xbc\xf6\xf6\xe6\xc4\xf3\x19\x0e\x75\x66\x63"
+  "\xcb\x67\xbd\x65\x18\xf7\x44\xf0\x7d\xcb\x7f\x73\x5b\x53\x61\x27"
+  "\xa6\x92\xb4\xf9\x41\x33\xb5\x0f\x61\xeb\xad\x4c\x87\x5e\xa3\x01"
+  "\xfd\x81\xe3\x9c\x2e\x03\xf8\x0d\xd9\xde\x7c\x26\xb4\x07\x64\xeb"
+  "\xc4\x5e\x63\xfc\x39\xd6\x3f\x6a\xbf\xc9\x45\xe8\x81\xc4\xc6\x0b"
+  "\xb4\x25\x8d\x79\xda\x20\xfb\x93\x2d\x13\xf5\x3c\xfb\x07\xcf\x51"
+  "\x6f\xd9\xad\xcb\x49\x58\x9e\x51\x1c\xa6\xc6\xcf\x8e\xb9\xcc\x73"
+  "\xa1\x78\x6f\xd2\xd3\x81\xae\xa2\x51\xea\x91\x2d\x25\xd1\xba\xe1"
+  "\xb7\x16\x5e\x73\x57\xf8\x48\xf9\xb3\xac\xed\x96\x7e\x59\x60\xe3"
+  "\x01\xf6\x76\x6d\xff\xcb\x19\xd9\xa7\x3b\x00\xcb\xaf\x60\xa1\xac"
+  "\x35\x7a\x59\x22\x69\xad\xf4\x5f\x01\xf8\x67\x42\x73\x92\x5b\x2a"
+  "\x78\x6c\x2e\x7a\x73\x86\x81\x9f\xc7\xa5\x6c\xe1\x77\xf9\xcd\xca"
+  "\x47\x1c\xcb\x1b\xd7\x93\xe5\x2a\x24\x53\x5b\x2d\x3a\xbf\xb9\xce"
+  "\xc8\xd7\x66\x93\x7e\x84\xb7\xda\x75\x5a\x0e\xe5\xcb\x46\xb6\x5b"
+  "\x0b\x70\xe9\x53\x6d\x57\x8e\x2b\x95\xff\x22\x3e\x47\x13\x27\x92"
+  "\xf2\x2c\x5d\xb4\xed\x7e\x3e\x1b\x90\xe8\xe7\x71\x5a\x9e\x85\x7d"
+  "\x33\xa8\xb3\xee\x5b\xf7\x00\x7e\x45\xe8\xec\xfb\x56\xf4\xff\x8e"
+  "\x0a\xc5\xbb\xad\xcd\x61\x6d\xcf\xab\xed\x37\x18\xce\x34\x62\x7d"
+  "\xe6\x76\x64\xc8\xf6\xaa\xce\x15\x6f\x3d\xa3\xe7\x93\x7e\x0c\x02"
+  "\xaa\x4f\xbc\x4c\x5b\x79\x9e\xc7\xcb\xf8\x81\xd6\x25\x5c\x3e\xd7"
+  "\x8f\xfb\x5c\x29\x37\x56\xbe\x6b\x65\x5b\x42\x24\x0e\xdb\x26\xea"
+  "\xb0\x14\xec\x6d\x53\xf5\x6f\xf6\x6b\xe6\xa1\x8a\x96\xb6\x89\x68"
+  "\x53\x3e\x59\x87\x9b\xda\xd0\xa5\xb6\xf9\x64\xba\x15\x3a\x0d\x11"
+  "\x5e\x89\x6f\xd8\x3f\xe5\x45\x6a\xcd\xa9\xe6\x8c\xd2\x45\x15\xc7"
+  "\xd8\x67\x96\xd3\xc6\x7e\x0f\xe7\x2b\x7d\x23\x7d\xf5\xc8\xb8\x97"
+  "\xb5\x36\x3b\x82\xcf\x20\xc9\x7d\x37\xbe\x80\xd4\x0d\xca\xb7\x03"
+  "\xe2\xd1\x46\xfa\xd4\x7d\x4f\x23\x34\xdc\x4e\x0e\x96\x01\x99\x68"
+  "\x93\x6b\x9c\xdb\x5a\x94\xaf\x94\xe1\x67\x10\xdf\xad\xf3\x6f\xf7"
+  "\x41\x84\x01\x26\xf2\x99\xdb\xa4\x2f\xb2\x0a\x93\x8e\xaf\x16\x67"
+  "\x94\xf2\x20\x69\x50\x31\xd8\xfe\x7b\x93\x65\xda\x54\xbd\x1c\x99"
+  "\x16\xe9\x38\x3d\xdf\xf9\x89\xb8\xac\x41\x38\xca\x47\x8b\x99\xcb"
+  "\x69\x6b\x92\x71\x45\x21\x5d\xb5\x4d\xae\x19\xc9\x7d\x71\xa8\x87"
+  "\x77\x5b\xd1\x08\xc9\x03\x1b\xf1\x3d\x24\x26\x86\xa7\x64\xb1\xa2"
+  "\x5e\xcf\x13\x67\x60\x3a\x56\x1c\xd1\xcb\xd6\x61\x30\xfe\x37\xd4"
+  "\x79\xaa\x2e\x26\x6e\x23\x9c\x96\xe1\x4a\x99\x90\x77\x7c\x6d\x9f"
+  "\x23\x65\x50\xd6\x73\xbb\x39\x9c\xd7\xca\x16\xdb\x3e\x31\x4c\x1e"
+  "\x80\xcf\xf6\x41\xfe\x7b\x68\x7b\xae\xea\x4b\xb6\xa7\x85\xe1\x98"
+  "\x86\xef\xec\x10\x1f\x24\x8f\xf8\xde\xa7\x98\xf7\x28\xca\xb6\x82"
+  "\x34\x41\x21\xf1\x64\x7e\x60\x2c\x36\x97\xda\xa0\xf7\xb8\xad\x80"
+  "\x26\x8c\xe3\xa7\x2c\x57\x80\x7b\x38\x52\x36\xb7\xb7\x84\xe1\x6b"
+  "\x60\xbd\x8e\xb0\x53\x7a\x1a\xe0\x27\xf7\xb2\xe8\xf4\x44\x5c\xf7"
+  "\x20\x1f\x67\xc9\xb4\x7e\x1d\xcf\x6f\xe8\x33\x34\x5a\xed\x98\xa9"
+  "\xca\xd8\x91\xaa\x97\x81\xdf\xf3\xd1\x06\xae\xb3\x55\x9f\xdd\x52"
+  "\x5e\xa8\x9c\x27\x71\x27\x9f\xff\xdc\x4b\x85\x05\x53\x6d\xf9\xcf"
+  "\xb3\x9b\xa5\xb2\xe2\xc2\xc2\x12\xb9\x48\x14\x69\x07\xa6\xc8\xf2"
+  "\x40\x07\x65\xcb\x3a\x3f\x7a\x53\xed\x8f\xe1\x76\xc1\xed\xdd\xcb"
+  "\xed\xfd\x44\xc5\x57\x72\x6c\xe2\xae\x9c\x45\x6e\xbf\xa8\x64\xfb"
+  "\x5d\xea\x3e\xae\xbf\xd5\xa7\xfa\x01\xf0\x93\xfb\x48\xe0\xd6\x11"
+  "\x49\xaf\x1d\xdd\x91\x6d\x79\x87\x3f\xb6\x9e\xd8\xf1\x8e\xd4\x13"
+  "\x55\x4a\x2e\x58\x3f\xf1\xd9\x02\x86\xdb\xe7\x72\x4e\x8d\x84\xe9"
+  "\x9c\x1f\xd2\x51\xce\x4c\x5d\x47\xa9\x7e\xc2\x59\x8c\x3e\xa8\x4a"
+  "\x95\xe5\x2c\x08\xc9\x8d\xb3\x53\xc9\x8d\xd3\xe1\xa1\x9a\xb3\xfa"
+  "\x58\x45\xf5\x1d\x3b\x32\xd9\x7e\x64\x9d\x8e\xf8\x3a\x1d\x5e\x6d"
+  "\x32\xf7\x1b\xce\xc3\xd7\xdb\x0f\xce\x15\x6c\x3f\xf0\xbe\x47\xa6"
+  "\x05\x70\x35\xab\x76\xe3\x3c\x1b\xa6\x7f\x18\xef\xce\x58\xbc\x7e"
+  "\x96\xbb\xe3\x69\xbc\x9c\x37\xed\xb9\x0d\xe5\x0b\xd8\x05\x56\xa1"
+  "\xa3\xa4\xf0\xb9\xf2\xc2\x82\xe8\x75\x3c\xbb\x6e\x8b\xf1\x1a\x7a"
+  "\x2d\xda\xbd\x37\x89\xe9\x51\x89\xfa\xbb\x0a\xf4\x3a\x48\x3d\x05"
+  "\xdb\x51\xd3\x71\x09\x5d\xe4\x9a\xd9\x28\xf7\x01\x56\x16\xe8\x72"
+  "\xc2\xe9\x16\x3a\x44\x10\x61\xa8\xff\x8e\x12\x6d\xbc\x84\x31\x69"
+  "\xe5\x1e\xfd\x3b\x94\xbf\xf2\xb4\xec\xfb\x0e\xca\x3d\x83\xa0\xe9"
+  "\xce\xac\x30\x7b\x8b\xbf\x27\x6b\xdf\xd2\xcf\x13\xfb\x24\xeb\xa1"
+  "\xca\xf3\x8a\xbe\x95\xe0\xff\x76\x4d\x57\xb8\xd4\xbe\x9b\x83\x44"
+  "\x1f\xec\xf0\xc6\x37\xca\xf5\x84\x4a\xbf\x5e\x1e\xf2\x9f\x0b\x2f"
+  "\x93\xfb\xad\x68\x78\x1e\xaa\x94\x3e\xdc\x77\x49\x1f\x75\x3b\x67"
+  "\xc7\xc0\xb5\x25\x3c\x1d\xd2\xe4\x20\x8d\x49\xaf\xf3\x72\x87\x0c"
+  "\x2b\xbe\x41\x1d\x7b\xb4\x3a\xb2\xde\x94\xe5\xb3\xfc\x6b\x38\x9c"
+  "\xd2\xfc\x9e\x78\xf8\x8e\x44\xc6\x5f\xfa\x5f\xb3\x72\xbb\xde\xd9"
+  "\x8a\xfe\x6c\xb6\x5e\x0f\xae\xe3\xb1\x1d\x5e\x93\xee\xf7\x4a\xe5"
+  "\xdf\xf9\xf3\x28\xdc\x7c\x61\x79\xba\x5b\xef\xe0\xb5\x82\x9d\xfb"
+  "\x84\xcb\xc9\xe3\x18\xf6\x7b\x65\xae\x1d\x94\x43\x97\xed\x7a\xb9"
+  "\xdb\xb9\x97\xe5\x2e\x5c\x96\xd6\xcd\x7a\x0e\x92\x54\x56\x58\x3e"
+  "\x4f\x5a\xf7\x30\xec\xd8\xad\x5a\x7e\xf9\xba\x8d\x1b\xca\xa6\xda"
+  "\xca\x0a\xf2\xb5\x46\x1f\xd1\xe6\x5d\x72\xec\xee\xd3\xdb\x19\xca"
+  "\xda\x1b\xd2\x2d\xae\x90\xfc\xf3\x1e\x30\x79\x37\xb3\xeb\xbc\x6a"
+  "\x4f\xae\x63\x61\x6d\x57\xe6\xe7\x36\xda\x28\x6d\x36\x57\x78\xff"
+  "\xcf\x63\xe3\x11\x97\xc9\xb5\x5d\xa3\xa9\x4f\xd1\x78\xd7\x5d\xb2"
+  "\x9e\xd2\xdf\x97\x6b\x3e\xd7\x53\xfa\x97\x91\xf6\xd9\x2e\x8b\x5e"
+  "\xdf\xd0\xb8\x61\x97\x5d\xda\x51\x9a\xbd\x76\xa3\x71\x79\xc8\x3e"
+  "\xdd\xd5\xa6\xcd\xb9\x75\xe8\x63\x3c\xdd\xbe\x06\x2e\x05\xca\x56"
+  "\xdd\xb5\x7d\x59\x85\xe8\x5f\xeb\x60\x3f\x78\xcc\x83\x5d\xbf\xd4"
+  "\x6d\x4b\xb9\x3f\xb0\x7a\x2d\xda\xc5\xae\xa6\x70\x3d\x21\xe2\x5e"
+  "\xea\xd0\x6c\x44\xaf\x1a\xbb\xde\xf4\xf7\x17\x50\x16\x70\x33\xdf"
+  "\x00\x37\xae\x17\xf4\x5f\x6d\x33\xc3\x61\xfb\x5a\xf4\x5a\xb5\xfb"
+  "\x26\x77\x57\x4b\x7b\x17\xb0\xbd\xe0\x6d\x9f\x6b\x37\xec\xa3\x5d"
+  "\x52\x36\x82\x90\x51\xde\x1b\xe4\xd3\x6d\x24\xda\xbd\x80\xfb\x22"
+  "\xfc\x86\xdc\xee\xd6\xce\x24\xee\xae\xf2\x96\xd9\x61\xaf\x5b\x8d"
+  "\xbd\x65\x39\x26\x9e\x2f\x60\x5a\xb8\xeb\xfd\xa4\xe4\x67\x77\x1e"
+  "\xe4\xce\x12\x0e\x4f\x83\xc5\x34\x35\x31\x1e\xa2\xcc\x6a\x64\xf9"
+  "\x96\xf7\x13\xf6\xda\x61\x0b\xef\xb6\x8b\x32\xbb\x71\x08\xdf\x5e"
+  "\x37\xaa\x67\x02\xdf\xf1\xc8\x77\x73\xb2\xbe\x52\xf7\x07\xbc\x7a"
+  "\xe9\x4d\x35\x37\xa0\x97\xfb\xa5\x30\xbe\x2f\xfb\x95\xfd\xb2\x5f"
+  "\x11\xa4\xfc\xb1\xbf\x2a\x7d\xe5\x8f\x2e\x79\x5f\xde\xab\xaa\x9d"
+  "\xff\xf6\xb6\x95\x04\xe4\x5d\x79\xce\x72\xb6\xd3\x02\xbc\x4e\x25"
+  "\xcf\x37\x9f\x28\x0f\xd0\x72\x3f\xcb\xe4\xab\x69\xec\x8b\xde\x27"
+  "\xed\x85\x57\xb3\x74\xff\xf3\x7c\x6f\x24\xdf\x3b\x8a\x7a\xc5\x31"
+  "\xdf\x6d\x4e\xbe\x3b\xe0\x35\xbe\x97\x95\xd4\x78\xdc\x4a\xfb\x61"
+  "\xd3\x2b\x1e\xbc\xfa\x16\xdf\xe3\xaa\xc6\x0a\x17\xc0\x97\xb8\x7f"
+  "\xbd\x40\xaf\xfe\x4a\xad\x55\xeb\x7a\xe2\xb5\x29\xbc\xf7\xdd\xa3"
+  "\xc1\x40\x59\xe8\xff\x77\x29\x1f\xa1\xdc\x77\xf6\xe9\xfc\x7c\xf5"
+  "\xad\xeb\xe7\x37\x42\xf0\x3c\xf4\x6a\xad\x66\x17\x90\x9a\xbb\xfa"
+  "\x2d\x60\xbd\x66\xd2\xe7\xae\x42\xb6\xcf\x6b\x56\x7d\xee\x4a\xf9"
+  "\xb6\xde\x7d\x8e\xcb\x1f\x6a\x8e\x48\x38\x9f\x62\xb9\x37\xb3\x0d"
+  "\x37\xa4\x3d\x81\xfe\x9d\x71\xd7\xed\x42\xc5\x9f\xd7\xfe\x9a\xed"
+  "\xc3\xb6\x0a\x35\xae\xed\x55\x77\x4c\xc2\x06\x78\xed\xb8\xea\xcb"
+  "\x5e\x6b\xd2\xfb\x32\xe4\x3d\xa6\xe9\x0a\xad\x9f\x7b\x6d\x70\xfc"
+  "\x1b\x7b\xdf\xff\x6b\xe7\x74\x1a\xe9\x34\x57\x34\xfa\xc9\x9c\xde"
+  "\xe4\x95\xb9\x21\xda\xfe\x44\xae\x5d\x84\xc5\xaf\x0f\xa3\x3d\x7f"
+  "\x17\x2b\xbd\xf9\x13\xf4\xff\xbb\xeb\x55\x9f\xa2\xc2\x44\x72\xcd"
+  "\xbf\xf0\x9d\xb1\x8a\x06\xeb\xe4\xdc\x8c\xd7\x69\x07\x6e\x3f\xc9"
+  "\xf1\x18\x92\xb3\x95\x2e\xfb\x09\xfa\xbf\xd7\x56\x68\xf9\x24\xff"
+  "\xc3\xf1\x5d\xb9\xe1\xa5\x0d\x1b\x37\x6f\xe0\x09\xb5\x57\xca\x6c"
+  "\xcf\x6d\x2c\x28\x1c\x19\x63\x3e\xc4\xca\xf7\x45\xfb\x6a\x07\xfd"
+  "\x5a\xbd\x51\xc2\xfb\xf4\xd5\x9d\x08\x6f\xbc\x6c\xbb\x93\xe5\xeb"
+  "\x27\x9f\xf2\x5c\x81\xbc\x9b\x82\x7d\xb8\xaa\x79\x83\x6e\xce\xaf"
+  "\x68\xfd\xc6\x33\xbd\x9b\x8b\x34\x1b\xeb\x8d\x9b\x99\x8e\xda\x98"
+  "\x43\x74\xd1\x9e\xc7\xf5\x7e\x88\xf1\x93\xb6\x79\xbf\x5d\xea\xc5"
+  "\x60\x7f\x91\x49\xd2\xab\xdf\x8e\xfe\x66\x4f\xaa\xc7\x90\x34\x55"
+  "\xd5\x6b\xcf\x7c\x9d\x1e\x5c\x7f\xd8\xba\xe6\x3e\xb1\x0e\x32\xfa"
+  "\x46\x89\x06\x8b\xf5\x27\xc3\x36\xe9\xfb\xc4\xd9\x57\x69\xeb\x26"
+  "\xf6\x53\xfc\xfa\x82\x60\x35\xeb\x9b\x3d\x95\xba\x5e\xe2\xbe\x28"
+  "\x08\x38\x1f\x5e\xf5\xc6\xa3\xdd\x3c\x84\xbc\xe3\x2e\xd0\xeb\xa7"
+  "\xd4\x7d\x06\x7b\x8e\x44\xde\x67\xf0\xfa\x1e\x3c\xa7\xb4\xa7\x27"
+  "\xec\xf7\x8d\x1e\x3d\x4f\x4b\x58\x98\x39\x2a\x4d\x4f\x9f\xeb\xf5"
+  "\x94\x41\x7b\x45\xf9\x4b\xd5\xfc\x2b\xf3\xdd\x1c\xaf\x3f\xce\x3e"
+  "\x49\x43\xb2\xb1\xe7\x15\xcd\x06\xe9\x66\xda\x71\x7f\x8b\x34\x72"
+  "\x2f\x37\x68\xf2\x2f\x3c\x47\xcb\x75\x12\x7d\xeb\x20\x13\xaf\x17"
+  "\x87\xe4\x40\xd1\x08\x61\x95\x21\x3b\xe5\xf5\x15\x9c\x27\x9c\x0e"
+  "\x28\xe3\x21\x35\x36\x7d\xfd\xb0\xde\x67\xb3\x3f\x56\x75\xbf\xc5"
+  "\xeb\x29\xc7\x76\x74\x63\xcc\xff\x7a\x5b\x18\x8c\x14\x6d\x2e\xc2"
+  "\x24\x8c\x3f\x71\x34\xca\x31\xdb\xeb\x9d\xa1\x39\x81\xd7\x53\x58"
+  "\xef\x4a\x18\xc9\x35\x1e\xb7\x4f\xde\xcb\x6c\xd0\xef\x5e\xef\x73"
+  "\xbd\x61\xd1\x6d\x14\x1d\x56\x9b\x9a\x73\x92\x3e\x34\xd1\x06\xab"
+  "\x90\x66\xf6\xe0\x7c\x2c\xc2\x06\xc7\x80\x0e\xb4\x63\x69\x7b\xbf"
+  "\xb1\x22\x34\xd6\xfb\x89\xf4\xb1\x2b\xc7\x81\x0a\x0e\xc6\x59\x6f"
+  "\x64\x46\x8f\xdb\x60\x3f\xd8\xd6\x6d\x58\x07\xf3\xe1\x85\x92\x8d"
+  "\x0b\x30\x74\x78\xa1\x64\xdd\x02\xde\x52\xb6\x24\x7d\xb1\x7c\xa3"
+  "\x71\x2c\x88\x31\x7f\x3c\x78\xf7\x32\xcf\x19\x61\x9c\xcb\x73\xa7"
+  "\x7d\xea\xee\xd5\xe1\xda\xdb\xac\xbd\x87\xa1\xdf\xb3\x42\xee\xaf"
+  "\xf0\xdd\x3a\x1e\xfa\xa9\x59\xbb\xef\x56\xef\xb3\xa1\xcb\xdf\xb8"
+  "\xa4\xaf\x93\xc9\x3d\xf6\xec\x27\x91\xef\x56\xde\xf5\xd2\xf9\x3e"
+  "\xd7\x4f\x07\xe7\x3f\xd4\xfc\xa2\x5a\xf7\x42\x78\x9a\x1e\xae\xcf"
+  "\xc7\x22\x6c\x85\x3e\xf7\xaa\xd2\xfe\xb4\x20\x94\x37\x62\x6e\x3b"
+  "\x45\x5f\x5f\x43\x9a\x3d\x3a\xcd\x74\x38\x4e\x9b\xb8\xac\xd9\x49"
+  "\x71\xd2\xae\x76\xbd\x51\x21\x7d\x93\xb2\x2d\x2e\xe7\x99\x7f\x7a"
+  "\x5c\x2f\x87\xc7\x08\x8c\xb7\xb6\x76\x23\xdb\x3d\xfb\x20\x55\x3e"
+  "\x4c\x7f\x3a\xc8\xff\xc8\x35\x8e\xd8\xeb\x1b\xfd\x9b\x44\x5b\xe0"
+  "\xaa\x68\xd9\xff\x7b\xb4\xd9\xe7\x89\x02\x9b\xc4\xd1\xfe\xab\xe2"
+  "\x18\xd3\x7a\xff\xb3\x44\xfb\xfe\x48\x34\x10\xb7\xfa\xf3\x6b\xa0"
+  "\xfb\xd2\x2b\xc1\xcb\x7c\xbf\x5e\x23\xd2\x2d\xf5\x7d\x21\x1a\x90"
+  "\x67\x69\x89\xb8\xdc\x80\x74\x4b\x2e\x5d\x16\x87\x90\x76\x49\x11"
+  "\xea\xbd\x49\x04\x06\xe2\x5e\xfa\xdc\xb6\x8a\xf5\xd0\x5e\x87\xb7"
+  "\x3a\x37\x4b\xb8\x8c\x07\xc4\xae\x7b\xee\xee\x73\xed\xdd\x3d\x78"
+  "\xa7\x17\xe0\x32\x8d\x96\x39\xf8\xf7\x4b\x9f\xa3\x4e\x9f\xaf\x45"
+  "\x1f\x0a\x1e\x7c\x8e\x74\x18\xff\x97\x49\x7d\xe3\x8d\xbb\x3b\x19"
+  "\x8f\x3d\x96\xde\x07\xae\x6d\x03\x9b\x44\xcb\x81\x35\xc0\xff\x22"
+  "\xf0\xbf\x2a\x8e\xa2\x0e\xc7\xf6\x77\x11\x31\xfe\x03\x0c\x73\x80"
+  "\xe2\xd6\x6e\x31\x24\x35\x22\x7e\xad\xc3\x42\x8d\x48\xbb\xc6\x47"
+  "\x49\x0d\x48\xb3\xe6\xe5\x24\x92\xf8\xf7\x00\xef\xa4\xdc\xac\x01"
+  "\x94\xcd\xf8\xf7\xb9\xf6\x4d\xd5\xf1\xd4\xcb\x67\x7c\x75\x19\x5c"
+  "\xcb\xf3\x5d\xc9\x2b\xeb\x19\x6f\x35\x87\xbf\xaf\xd0\x5b\x56\x44"
+  "\xde\xb8\x7b\xee\xf6\xd0\xbe\x4a\x6e\x43\x5c\x1f\x2f\x64\x4a\x3b"
+  "\xf7\xf6\xb9\x4e\x03\x35\x9e\xdc\xb7\x57\xaf\x5f\x78\xbd\xb2\x37"
+  "\x96\xca\x79\xd4\xfc\xe7\xca\xd7\x6d\xca\xc7\xe8\x6c\x24\x95\x70"
+  "\x90\x1c\xbf\x15\x16\xd8\x36\x6e\xb0\x3d\x9f\xbf\xae\x78\xe3\xa6"
+  "\xc2\xd2\xa9\x72\xc8\x5d\x56\xb8\xa1\x80\xa7\x57\x4b\xf3\x4b\x4b"
+  "\x46\x46\xd9\xdc\x55\xb9\x59\xbc\x1f\x91\x75\x59\x17\x55\xed\xd3"
+  "\xe6\x16\xfd\xc2\x95\x26\xc7\x6e\xaa\x1d\xec\x7f\xc8\xb6\x35\x8d"
+  "\xe3\x77\xaa\xbe\xa6\x6a\xaf\xa8\x59\x79\x48\x08\x79\x27\xb4\xe1"
+  "\x32\x55\x6d\x91\xf5\xec\xcd\xd4\xe1\xc8\x3d\xfa\xd2\x66\xe5\xf0"
+  "\xfe\x4c\x0a\xed\x29\xaf\xda\x27\x8c\xa8\x23\x68\xa0\xec\xd6\x3c"
+  "\x9b\x76\xb6\xef\x3f\x5f\xa0\xaa\x42\xd4\x9b\xd7\x0e\x94\x5d\x28"
+  "\xcf\x20\x55\xad\xc4\x58\xdb\x26\x5c\xc3\x12\x98\x2e\xfb\xd5\xb8"
+  "\xd2\x98\x68\xe0\x7b\x62\x2f\xf0\x79\xc8\x54\x5e\x23\x6c\x74\x05"
+  "\x53\x43\x7b\x7a\xf6\xd5\xb1\x8d\x2b\xe7\xda\x65\xbb\xd8\x7f\x56"
+  "\x97\x77\x23\x9f\x31\xd9\x35\x61\x9e\xd2\xd5\xfb\xe5\xfa\x3f\xf8"
+  "\x36\x4f\xe1\x2f\xef\xa7\x46\xff\x74\xe0\x4b\xd4\xaf\x41\x38\x33"
+  "\x35\xbf\xf2\x07\xbe\x0c\x26\x9f\x29\x19\x28\xb3\x6a\x77\xba\xaf"
+  "\xfc\xbb\x60\xcd\xca\x5f\x0c\xa0\x5f\x0f\xc2\x56\x15\x35\x67\x7a"
+  "\x07\x6a\x56\x36\x05\x37\xdb\x8d\xac\xdf\x9d\x0e\xd0\x6f\x63\xd1"
+  "\x48\xf1\x45\xd1\x4d\x03\x9b\xed\xb0\x01\x56\x1e\x16\x02\x79\x93"
+  "\x57\xb6\xc8\xbb\x79\x6b\x56\xfe\x85\xf6\xfd\x7f\xf2\x77\x10\xb6"
+  "\x1a\xc2\x5a\xf1\xfd\xdb\xa0\x08\x4b\x1f\x99\xb6\x8d\xbf\x13\x0d"
+  "\x72\x0f\x21\xdf\x31\x3d\x9f\xeb\xae\xd7\x59\x8e\x11\x78\x9e\x62"
+  "\xb0\x6e\x07\x7a\xf4\x70\xb6\x5d\x95\x1d\x49\xcf\x81\xc6\xa4\x74"
+  "\xda\x60\xba\xdf\xe9\x34\x90\xb4\xad\x59\x59\xef\x01\xff\xe4\x3d"
+  "\xf5\xbb\x6e\xb9\x5b\x18\xf7\xfd\x25\xf7\x1d\xcb\x06\xe4\x5a\x16"
+  "\xa9\xb5\x8f\xaa\xc9\x3a\x3d\x79\xaf\x3c\xf7\x1f\xe0\x9b\x7d\xad"
+  "\x97\x46\xaa\xf6\x5b\x95\x1e\x36\x46\xe9\x11\x52\xde\x0f\x9c\x93"
+  "\xe5\x1a\xcd\xbb\xd4\xf7\xfe\x5a\xd5\xdf\x55\x95\xe8\x69\x11\xe6"
+  "\x50\x36\xe9\xfe\x74\x1e\xbb\xf1\xda\x16\xff\x6e\x18\xe2\x1c\xe7"
+  "\x8e\x7a\x21\x58\x17\xb2\x6e\xb6\x4d\x20\x6a\xf7\xb1\xdd\x5e\x75"
+  "\xea\x44\xbd\x8f\x24\xff\x92\x57\x1e\xea\x15\x45\x18\x6b\x15\xc5"
+  "\xb4\x53\x39\x4f\x17\x55\x9b\xa5\x0d\x0e\x79\x0e\x42\x9e\x91\xa7"
+  "\x81\xe5\x75\xc7\x15\xc6\xa3\x3a\xb3\xad\xa2\x9b\xfd\xcc\x43\x0e"
+  "\xab\x33\x99\x36\xdc\x37\xec\x77\xc9\x33\x7c\x52\x07\xb7\x6e\x9a"
+  "\xcd\x30\xe6\x8c\xf6\x93\xa9\x1d\x1a\x14\xf4\xe6\x3d\x5b\x49\x17"
+  "\x91\xde\x54\x4e\x66\x1e\x1f\x7d\xdb\x75\x64\x94\xb7\x5b\xd1\xa4"
+  "\x7a\xb7\x6e\x03\xe1\x77\x55\xe4\x59\xd5\x6a\x47\xf4\x5a\xda\xb3"
+  "\x1b\x37\x96\xaf\x2d\x2d\xe4\x97\x7d\xca\x2b\x77\x45\xf7\x89\x09"
+  "\xea\x5e\x9f\xea\xc3\xcc\x3f\xee\x27\xd4\x99\x8f\xea\xee\xb0\x71"
+  "\x2d\xcf\xad\x3d\xc8\xfd\x1b\xaf\x89\xf7\xb9\x6a\x4c\xbf\xa9\xd8"
+  "\x2e\xe5\xe4\xbc\x99\x8c\xd1\xe5\x3d\x9f\x5f\x9e\x5f\x3c\x4f\x2d"
+  "\xdf\x5e\x5f\x4e\x8d\x35\xb2\x9c\x9a\xec\xc1\x72\xd4\x18\xc4\x27"
+  "\xdb\x60\xf5\x19\x8f\x48\xfa\xa8\x52\xe9\xb9\x9a\x72\x7d\x4f\x56"
+  "\x6c\xdf\x18\xab\x52\x06\x6a\x6a\x53\x99\x5f\xce\xed\x64\xfc\x9b"
+  "\xad\x1d\x46\xb6\xbf\x76\xe0\x37\xef\x59\x91\xf3\x7c\xda\x9d\x7b"
+  "\x1f\x7f\xd5\x01\x3d\x5b\x73\x52\x54\xaf\x82\xcd\x56\x33\xe4\x3e"
+  "\x93\xf0\x73\xc5\x6a\x8d\xb2\xc6\x33\x54\x5a\x51\x95\x67\x57\x6d"
+  "\xe5\xcd\x39\x72\xad\x6c\x02\xfd\xe4\x02\xbd\x39\xd3\x64\xc5\x38"
+  "\x6e\x02\xfd\x27\xfc\x96\xe3\x05\x8e\x8b\xe0\xf5\xad\x3d\x4d\x26"
+  "\x48\x27\xa4\xd4\x20\xd4\x1f\x8c\x30\xf5\x17\x87\xc7\x28\x0c\x72"
+  "\x77\x7e\x1c\x28\x3c\x7c\x98\x89\x12\x47\x27\x98\x6f\xbf\x6d\xa2"
+  "\xf5\xc1\x07\xe6\xcf\x75\xee\xa8\x70\x88\x60\xc0\x9f\x28\xc2\xef"
+  "\x87\xfc\xc8\xbe\xf2\xae\x4a\xd5\x57\x54\x7f\x14\xb3\xaf\xdb\xe7"
+  "\x12\x25\x6c\x5b\x43\x5f\x65\x3b\x5f\x21\xe3\x87\xd7\x3c\x46\xb6"
+  "\xe5\xb8\xff\x71\x07\xfe\x80\x31\xc1\x9b\xbf\xf9\x04\x61\xa8\xbf"
+  "\x43\x54\x9d\xc9\x56\x67\x2f\x6a\x0d\xc1\x9a\x33\xd9\x21\xf8\x26"
+  "\x62\xf8\x18\x2f\x18\x9b\x77\x74\x1b\xdd\xa6\x07\xc8\x6d\xf3\xd1"
+  "\x27\xf8\x1d\x93\x96\x28\x93\xe7\xa6\x18\x06\xf4\xf0\x1e\xe7\xd7"
+  "\xd0\xcf\x0e\x39\x4f\x6c\xbc\x4c\xb5\xf7\x1f\x1d\x22\x9f\x5c\xeb"
+  "\x49\x5e\x1d\xec\x73\xd5\x82\xff\x8f\x4e\xd5\xec\x21\xd8\x6b\xb5"
+  "\xbb\x75\x9d\x80\xf8\x01\x35\x5f\x5d\x5b\xa7\xa7\x89\xc9\xa3\x37"
+  "\x78\x8f\xa7\x68\x65\xbe\x8a\xab\xdd\xdd\xec\x63\x6e\x88\x39\x81"
+  "\x74\xf4\xcf\x73\xb8\x1d\x8f\xda\x69\x19\x36\x7a\x67\xea\xfa\x53"
+  "\x68\x75\xa3\x7a\xc6\xd2\x68\xdf\x33\x8c\x33\xd5\x1f\x94\xfb\x8c"
+  "\xbb\x79\x9d\x2a\xd1\x90\xba\x2e\x71\x67\x6a\xfe\x80\x6b\xfe\xbd"
+  "\xdc\x4f\x26\x3a\x16\x1b\x12\x03\x0f\x19\x02\xae\xd9\xf7\x36\xaa"
+  "\x3b\x59\x7c\x55\xe3\x44\x07\xf2\x9c\x43\x1e\x0f\x9e\x4e\xe4\x3b"
+  "\xd5\x45\x6f\x3d\x85\xf7\xc9\x44\x83\x68\x4c\x04\x27\x67\x54\xca"
+  "\x3b\x2a\x59\x47\x9f\x12\xc9\xb0\x31\xfb\xe5\x5c\x40\x7c\x68\x2e"
+  "\xe0\xad\x0a\xf0\x6d\x58\xd6\xab\xe2\x13\xc0\x3a\x39\x70\x35\x78"
+  "\xb2\xe1\x32\x91\x36\xe7\x7d\x16\x6d\xf4\xec\xd4\x5a\xb2\x6a\x7b"
+  "\x45\x8d\xa7\x02\x27\x59\x17\xf3\xd9\xea\x36\x94\x79\x1c\x4f\x8b"
+  "\x6d\x03\xc5\x5d\xa6\xb7\x4e\xb3\xfd\x11\xb2\x61\xdf\xce\xd0\xc6"
+  "\x23\xad\xd3\x91\x7f\xfb\x7a\x96\x89\x6e\x63\x00\xf0\x61\xf3\x9f"
+  "\x74\x17\x9d\x94\x7b\x61\x78\x2f\x36\xa7\x41\x19\x76\xb7\xff\x24"
+  "\x05\x85\xd5\x88\xef\x16\xde\x5b\x28\x90\xb6\xdd\xd1\x41\xed\x25"
+  "\x7e\xe8\xd8\x53\xb0\x81\xed\x93\x81\x8f\x84\x87\xf8\xb3\x1f\x82"
+  "\xbf\x36\xd8\x7b\x80\x77\x86\xf7\xd6\xf0\x19\x65\x51\x66\xbf\x13"
+  "\xf9\xd1\x67\x59\x8d\x0c\xff\x32\x1d\xfc\x54\xf4\xda\xed\x33\x7a"
+  "\xd4\x9d\x8d\x17\xe8\xe0\x11\xe0\x79\x5f\x18\x9e\x73\x80\xbf\x09"
+  "\x7a\xb5\x15\x30\x8f\x8b\x4d\x28\xb3\x13\x65\x62\x3c\x02\xf9\x9d"
+  "\x8c\xf1\xae\x89\x71\x6e\x67\x7c\x1d\x03\xbc\xff\xd5\x74\xe0\x2b"
+  "\x32\xa1\x2d\xb4\x36\xe2\x8d\xfa\x1f\x83\x4d\x36\xb1\xcf\x75\xb0"
+  "\x55\x3f\xe7\xce\xb6\x04\xbe\xcf\xe8\xb2\xb4\x0f\x69\x80\x63\x0b"
+  "\xf0\x3a\x3e\xaa\x87\x78\x8c\x13\x0f\x39\x8d\x47\xb9\xc3\xc1\xab"
+  "\x16\xd0\xee\xaf\x41\xeb\xe3\x5c\xa7\xe0\xd5\x60\x77\x10\xf0\x0e"
+  "\x5c\x05\x4e\x65\x56\x53\x42\x27\xdf\x69\xdd\x27\x40\xef\xb3\xcb"
+  "\x1c\x7d\x82\xf7\xc9\xa2\xce\x4c\xef\x7d\xa8\xab\xc9\x43\x6f\x17"
+  "\xf3\x78\xa3\x8b\x0e\x96\xab\x3b\x27\x0f\x3a\xb4\x35\xad\xb3\x6a"
+  "\x9e\xe9\xad\xd3\x4c\x7b\xae\x57\xc2\x4e\xcb\x6b\xee\x6e\x2f\x25"
+  "\x74\x8e\x45\xff\xf6\x96\xb7\x3e\xc8\x36\xca\xdb\x83\xf3\xff\x43"
+  "\xb4\x31\xbf\x1b\xfa\x25\x78\x55\x74\xb3\xed\xa9\xf6\xbb\xbc\x7d"
+  "\x64\xad\x23\x2e\x0d\x76\xa6\x11\x78\xf2\x59\x8d\x71\xe8\xa7\x1f"
+  "\xe4\xfd\x4c\xc0\x0f\xe3\x8e\xb7\x4f\xdd\xe8\xae\x57\xd0\xc7\x8a"
+  "\x34\x5e\xe0\x2e\xef\xf4\xe3\xbb\x30\xd5\x5c\x4f\x9d\x49\xf7\x37"
+  "\x20\xae\x8a\x8a\x03\x3b\x64\xb9\x95\xbb\x37\xc9\x32\xf8\xfe\xcf"
+  "\xee\x72\x9b\x38\xdf\x66\xf3\x0e\x79\xa6\x3b\x6c\x1f\x8f\x57\xbb"
+  "\x53\x4c\xae\x69\x46\xee\xe3\xa9\x2b\x0e\x1b\x37\xf2\xba\x66\x25"
+  "\xaf\xdd\x2a\xbf\x30\x75\x72\x2f\xe6\x32\x87\xf2\x7f\xe1\xf6\xf7"
+  "\x68\xb6\x65\xdd\x47\xf2\x9e\x21\xb6\x6b\xe4\xde\x9f\x8b\xda\x7e"
+  "\x9d\xba\xc7\xb9\x8c\xb6\xa8\xbb\x8c\x0b\x37\xe4\x3f\x5b\x5c\xa8"
+  "\xa6\x52\xa6\xbd\x58\x9e\xff\x42\xa4\xfd\x6b\x92\xe3\x62\x57\x5d"
+  "\x9b\x9a\x9b\xac\x0b\x84\xd9\x89\xa6\xc1\xb9\x25\x23\x1d\x53\xf3"
+  "\x4b\xef\x4c\x8c\x35\xbf\xb4\xf8\x85\x0d\x1b\x4b\x65\x19\x72\x6b"
+  "\x53\xa1\x3a\xfd\x34\x92\x56\xa6\x2f\x4e\x9f\x56\x56\x58\x2e\x2f"
+  "\x0f\x51\x93\x39\xf9\x05\x05\xa5\xda\xc6\xa7\x75\x9c\x8b\x63\x9e"
+  "\xdf\x2c\xb3\x96\xbc\x54\xae\xb6\x4c\x95\x15\xe7\x6f\x2a\xd4\x40"
+  "\x84\xe3\x3a\x91\xf5\x65\x5b\xbd\x1c\x33\x8f\x54\xeb\xb4\xef\x1c"
+  "\x09\x5b\xd7\x09\x1f\x47\xde\x8c\xb8\x93\x7a\x5c\xc9\x1d\x2c\x2b"
+  "\xef\x4e\x6b\x6f\x92\x3e\x1b\x4c\x27\x7e\xc6\xf4\x7d\x97\xd7\x89"
+  "\xe3\xb9\xcf\x0e\x1a\xdf\xb1\x37\x68\x67\x99\xfa\x5c\xef\x52\x68"
+  "\x6e\xe0\xd0\x71\x6d\xef\x43\x27\x97\xc7\x65\x23\xde\x16\xb6\x1f"
+  "\xa0\xd3\x43\xef\x74\x33\x0c\x5e\xb7\x96\xf7\x4b\xc0\x26\xd2\xce"
+  "\xb2\x1b\xdb\x7f\xc6\x7d\x4b\xfd\x54\xd6\xa3\xc1\xaa\xbc\x34\xd5"
+  "\x0e\xde\xcb\x17\x35\xab\xc5\x0c\x1f\xa5\x28\x3d\xf0\xee\xaf\x10"
+  "\x3e\xe6\x32\xbd\xbb\x47\xd4\xe4\x12\x74\x49\x3c\xdb\x23\x6a\xfe"
+  "\xfb\xdd\x5f\x69\x73\x05\x5c\xe7\xf8\x30\x1c\x9a\x43\xf3\x09\x87"
+  "\x8e\x7b\x93\xf2\xd2\x76\xab\xf5\x7e\xb9\xb6\xa9\xd6\x97\xdf\x1d"
+  "\xac\x3f\xfa\xef\x34\x6d\x3d\x2f\xa5\x0b\xe9\x31\x9e\x48\xd3\xd6"
+  "\xd8\xb8\xee\x69\x5c\x6f\xb5\x4f\xeb\xdd\x40\xb8\x5d\xab\xfc\xf9"
+  "\xaf\x16\x6c\x0b\xab\x71\xc0\x7b\x77\x49\xdb\x85\xe7\x2e\xae\x31"
+  "\x0d\xdf\x5b\x80\x78\xf4\x5f\xef\xcd\xf6\x50\x5d\x47\x38\xcd\xca"
+  "\x1d\xe8\xe0\x91\x8f\xfb\x33\xe0\x34\x1c\x69\x72\x42\x38\xbf\x27"
+  "\xfd\x44\xf0\x58\x41\xd9\x15\xef\x5d\x92\xf7\x8f\xf9\x50\x3f\x6d"
+  "\xcf\x00\xd3\x5c\xdd\x47\xf0\x5e\x95\x9e\x2f\x98\x9c\x97\xca\x63"
+  "\x94\xfd\x6a\xfd\x0b\xb4\x7b\xef\x9f\xe3\x0c\xe7\xe5\x1a\xe8\x0c"
+  "\x3f\x35\x21\x6c\x18\xc2\x7e\xc7\xe9\x18\x0f\x39\x57\x01\xfc\xb9"
+  "\xbc\x20\xec\xe0\x38\xeb\xb0\x05\x80\xe7\x81\x9e\x99\x1c\xe2\xdf"
+  "\x7b\x87\x43\xf3\x43\xef\xac\x51\xf3\x43\xf5\x26\x9d\x0e\x7c\x8f"
+  "\x90\xd6\x16\xe2\xf5\xf5\x72\xc4\x4f\x0e\xa7\xbf\xd4\x73\x1a\x3d"
+  "\x85\xeb\x9d\xb2\xd0\xb8\xab\x3e\x6b\x70\xad\x08\x78\x84\x74\x7d"
+  "\xfd\xcb\x4c\x47\xc6\xbb\x64\x2b\xcf\x25\x1f\x6a\x96\xf5\x50\xeb"
+  "\x31\xbf\x05\x8f\xde\x12\xb0\x0b\xb8\x8f\xe4\x31\x00\xf3\x97\xd3"
+  "\xaa\x3b\x86\x0e\x2d\x69\x50\x73\x9e\x07\xf1\xfb\xf1\xa0\x31\x96"
+  "\x7c\xd4\xb7\x85\xef\x0f\x54\x34\x3e\x94\x10\x64\x98\xa0\x1f\xc3"
+  "\x42\xbf\x31\xb8\xef\x59\xc1\xad\x1f\x00\xcc\xb7\xbb\x42\xf5\xc1"
+  "\x38\x4f\xa3\x23\xf3\x51\xd2\xe5\x10\xda\x7f\x9d\x9c\xb7\x71\x36"
+  "\x89\x4b\x1b\x01\x43\xdd\xfd\x79\x68\xbe\x60\xde\x68\xe9\xbd\x3c"
+  "\x76\x02\xee\xea\xec\x16\xe4\x0d\xe3\x0f\xc6\x33\x58\x93\x37\x97"
+  "\x71\xe7\x75\x80\xd0\x78\xf8\x10\xef\xdd\x48\xf5\x6e\x53\x79\x0e"
+  "\xa8\x75\x0a\xf0\xb6\xfe\x97\x62\x73\x11\x69\xf3\xe3\xd0\xc7\xf5"
+  "\x29\x2c\xdb\x0c\xc7\x27\xc7\x45\x87\xf6\x04\x41\x17\xf0\x94\xf1"
+  "\x3a\xa6\xf3\x14\xe9\x4a\x6e\xb0\xb7\x1a\x3c\x39\xe4\xd1\x7d\xbf"
+  "\x70\x9f\x82\x76\x5a\xa9\x6c\xc0\x86\xf7\x13\x77\x3e\x28\x12\x03"
+  "\xf7\xde\xcb\x36\x4d\xa3\x51\x8e\x55\xf4\xfd\x6f\xb7\x83\x4e\x5f"
+  "\xe8\x7b\x81\x83\xbb\x56\x77\xf0\xde\x41\xb7\x5f\xed\x1d\xe4\xf0"
+  "\xa5\x3e\x11\x6c\xf7\x0d\xf0\xfe\xfc\x8e\x3e\x57\x43\xba\x3e\x7e"
+  "\x61\xbd\x14\xb7\xd3\x00\x1c\x1b\x20\xff\x6f\x1e\xd1\xf4\xd1\xf0"
+  "\x8b\xd4\xb0\x53\x83\x1f\x86\xc3\xa1\x80\x1a\xff\x35\x34\xa9\x71"
+  "\x50\xc3\x5e\xe8\x97\xdd\x6a\x1c\xd4\x50\xa7\xe3\x8d\xf8\x82\xe8"
+  "\x3a\x66\x2f\x5c\x5c\x68\x2b\x66\xd5\x9a\x3a\xcb\x61\xb3\x4f\x29"
+  "\x98\x21\x37\x9b\xda\x16\x2d\x9c\x67\xcb\x5e\x30\xc5\x51\x34\x75"
+  "\xa9\x7a\x2d\xcc\xce\xe2\x77\xd4\xda\xa3\x0d\xf0\xfd\x91\xe3\xac"
+  "\x66\x0d\x87\x46\x8b\xc7\x30\x55\x9e\xb9\x10\x96\x55\xd9\x7c\xbf"
+  "\x3a\xfa\xc2\x1e\xb6\x6f\x97\x0d\xfc\x49\x88\xea\xf4\x3a\x91\xb4"
+  "\x2a\xdb\x9b\xf4\x91\xdd\x9b\xd4\xe2\xf5\x26\xe5\x4e\xe6\xfb\xd7"
+  "\x13\x77\x0a\x7f\x62\x60\xb8\xd2\x87\xf8\x86\x2d\xd1\x0d\x7b\x85"
+  "\x79\x49\x19\x77\x39\xc5\xb2\x01\xe1\x86\xdd\x02\xba\x34\x96\xe8"
+  "\xfd\xaf\x9c\x3b\xaa\x5a\x95\xbd\xcc\x21\xfa\x59\x76\xd0\xaf\x63"
+  "\x9c\x84\x32\xe3\x78\xae\xab\x11\xf5\xaf\xb5\x29\x5a\x34\x42\xff"
+  "\x1d\x3a\xa9\xd1\x37\x1b\xdf\x7c\xff\x8d\x5a\xcb\x73\x59\xa5\x8e"
+  "\x0f\xee\xba\xfb\x09\x51\xdd\xe2\xd5\x61\x02\x56\x82\x76\x16\x46"
+  "\xc2\xa3\x1b\x9c\xa5\x0e\x7f\x82\x35\x4f\x66\xf1\x9c\x03\x9f\x5f"
+  "\x4c\x74\x18\xf8\x7e\xa0\x9c\xc1\x79\x16\xc4\x8d\xde\x69\xe1\xb9"
+  "\x97\x9c\xd1\x3e\x43\x25\xa7\x09\xcd\x47\x04\x3d\x07\x8c\x41\x3f"
+  "\xec\x00\x8b\xba\x0b\xbd\x47\x5b\x8f\x6d\xca\x1b\x9c\xdf\x8f\xe0"
+  "\x7d\x93\x94\x87\xaf\x5c\x26\xc8\x76\x43\xf7\x1d\x29\xca\xe6\x09"
+  "\xba\x0c\xa4\xce\xb2\x37\xad\x94\xed\x52\x93\x47\xd0\xd7\xcb\x6b"
+  "\x6f\x89\x01\xe1\xe5\x7d\xea\xc1\x38\xc8\x24\x5d\x24\x77\x45\x5f"
+  "\x25\xdf\x41\x3e\x28\x97\x25\x90\xcb\x12\xc8\x25\xaf\x93\xa2\x7c"
+  "\x6f\xdc\xdd\x79\x68\xb3\x86\x8b\xd4\x34\x99\xf1\x67\xda\xc0\xee"
+  "\x4e\x08\x82\x56\x72\x3f\x1c\xd3\x27\x39\xe7\x14\x9f\x8b\xe2\xba"
+  "\x26\x06\x50\xe7\xf0\x7a\x19\x83\x9e\xfd\x2e\xd4\xcb\x88\x7a\x39"
+  "\x2e\xc9\xf1\x3e\x9f\x57\x83\x2e\x19\x17\xba\x63\xe2\xfd\xf4\xf0"
+  "\x3a\x06\xf9\x5e\x1a\x59\x87\xf7\x0b\x63\xd5\x51\x18\xb9\x8e\x4c"
+  "\x83\xf7\xef\xd7\xd6\x49\x24\x9e\xac\xb7\x7a\xa8\xc9\x3f\x7a\x27"
+  "\x9f\x13\x5b\x95\x0d\x7b\x75\x21\xf3\xb0\xc1\x25\xaa\x18\xcf\x58"
+  "\xfc\x62\x78\x0a\xd6\xcf\x4c\x89\x3b\x2b\xf3\x80\xcb\x99\xd8\xf4"
+  "\x7e\xff\xcb\x1b\xd3\xfb\xfd\xdf\x71\x7e\xc6\x83\xcf\xcd\x25\xb2"
+  "\x03\x24\xc8\x37\xc6\x58\x7b\x62\x95\x3b\x7a\x67\x13\xe3\x15\x33"
+  "\x0e\xb2\xdf\x73\xa0\x34\xb2\x4d\x04\x1b\xfc\xc4\xf4\x6b\x44\xb8"
+  "\x9a\x4b\xfd\x99\x63\x70\xce\xb7\x6a\x95\x23\xd1\x60\x8b\xe3\x36"
+  "\x26\x6d\x59\xd4\x37\x16\xdc\x44\x43\x15\xfb\x50\x5b\x08\x5d\x15"
+  "\x33\x1e\xed\xc0\x26\x76\xdd\x73\x07\xe0\xcd\x1f\xbd\xd3\x20\xbc"
+  "\x71\xf7\x8c\x1c\xed\x0b\x4c\x66\xba\x02\x57\x07\xda\xf8\x3e\xd9"
+  "\x3f\xcb\x39\x88\x9f\xa1\xfd\x7f\x98\x27\xe7\x72\x93\x56\xcd\x57"
+  "\xfb\x0a\x3e\x48\xf0\xd0\xdf\x79\x42\x7b\x84\x3e\x98\xe8\x31\x8c"
+  "\x68\x53\x6d\xf5\x96\x77\xd1\xa7\x9d\x0b\xba\x12\x85\x6d\x6b\xa2"
+  "\xe8\xa2\x0f\xfe\x36\x28\xec\x46\xf4\x5b\xe7\x42\xb2\xa3\xce\xd5"
+  "\xe9\xb2\x83\xfc\xb9\xb1\xe5\xe2\x83\xed\x37\x96\x8b\x0f\x1e\xd7"
+  "\xe6\xe8\xf2\xd4\xde\xbd\x0f\x9a\xf5\xb1\x82\xd8\x75\xcb\xbb\xb6"
+  "\x1d\xb2\xfc\xb9\xaa\x6c\xd0\x24\x90\xc6\x7a\x26\x0b\x74\xab\x44"
+  "\xda\x33\xba\x6e\x60\x19\x4a\x1c\xe0\x71\x0c\x49\x39\x47\x5c\x0f"
+  "\x74\x8f\xba\x23\xbb\x26\xf7\x14\xdb\x98\x41\x57\xc3\x11\xf4\x5f"
+  "\xef\xf1\xde\x75\x5f\xd2\xaa\xe3\x7d\xae\x66\x8b\x87\xba\x76\x6b"
+  "\xfa\xef\x18\x60\xb4\xc8\xbd\x20\xea\x3c\x68\x02\xb7\x73\xbe\xc7"
+  "\x8c\xdb\x3a\xc2\x52\x80\x37\xef\x73\x85\x6d\xdf\x9c\xa9\xf7\xfd"
+  "\x41\x57\x1a\xd3\x5b\xda\x19\x46\xb6\x63\x41\xbb\xb7\x8c\xc1\xc3"
+  "\x57\x67\x58\x89\xeb\x7c\x75\xd7\x84\xc3\x3f\x99\x4e\xa6\xff\xcb"
+  "\xfa\x2c\x95\xcc\xa2\x94\x9d\xf7\x99\xe8\xdf\xe6\x92\x91\xe9\xe0"
+  "\xa1\xe6\x1c\x45\xbb\xe6\x3a\x9d\x3f\x1e\xfa\x40\xea\x51\x9e\x3b"
+  "\x5f\x16\x10\xbd\x6a\x2d\xa0\xb9\xc5\x43\xd5\xda\x9a\x57\xa3\x29"
+  "\x46\xff\x90\x61\x5b\x57\x66\x2b\xd8\xb8\x79\xc3\xa4\x49\x23\x63"
+  "\x8c\x01\x9a\x4f\xa9\x31\xc0\xcf\x29\x7c\x0c\x80\x6f\xd4\xbf\xc1"
+  "\x13\x6d\xf3\x67\xad\xd5\xdc\x1f\xac\x4d\xa5\xd0\xef\x99\x94\x35"
+  "\x33\xec\xf3\x5e\xca\x9a\x75\xef\xda\x27\x0a\xf3\x0b\xb6\x84\x85"
+  "\xce\x09\x9f\x9f\x3b\xf0\x2e\xca\x8e\x9b\xf0\x30\xf4\x87\x61\xe9"
+  "\x36\xee\x77\x7e\x7e\x65\x47\x40\xfc\x2b\x64\x77\x2e\xfb\x1c\x3a"
+  "\x5d\x1e\xa0\xd3\xd0\x6f\xe2\x16\xd6\xeb\xc3\x95\xdf\x4d\x8c\xff"
+  "\x21\x5b\x89\xa8\xbb\x17\x63\xb1\x2b\x6a\xef\xf6\x2f\x6e\x6e\xaf"
+  "\xf3\x43\x4f\xe4\x4e\x55\xf6\xce\xcf\xcf\x22\x3c\x09\xef\x01\xb5"
+  "\xff\xe4\x17\x06\x8c\x73\xd3\xa4\x8f\x85\x4d\xec\x63\xe1\xe7\xb2"
+  "\x0f\x98\xee\xab\x24\xe5\xeb\xeb\xe7\x7b\xd9\x07\xb7\x87\x7e\x31"
+  "\x9f\xed\x0b\x4e\x8b\xb0\x4f\x6d\x2f\x52\x2a\xbf\xd9\xe6\xf5\x00"
+  "\xa6\xa8\xce\x9d\x2a\xde\xcb\xe1\x35\xf9\xc9\x80\x79\x3f\xdb\x6d"
+  "\x71\xd6\xe1\x7d\x7d\xae\x5f\xcc\xd5\x6d\x10\xde\x27\x3a\x94\xfd"
+  "\xa1\xf7\x83\xa3\xa1\xbf\x47\xfb\x12\xc5\x5a\xf6\x59\x62\xa0\xc9"
+  "\xdc\x3f\x24\x3a\xb2\xe5\xd9\x22\xee\x17\x59\x27\x34\x48\x5d\xfa"
+  "\x8b\x2a\x5d\x2f\xec\x57\xe3\xc8\x91\x9c\xff\x7f\x90\xf7\xc6\x71"
+  "\x51\x55\xe9\xff\xf8\x99\x01\x91\x8c\x9c\x81\x45\x1b\x8d\x72\x6c"
+  "\xb1\xcf\xb4\x4b\x45\xe5\xee\xba\xbd\x6c\x63\xd5\x8a\x4a\xd3\x5a"
+  "\x33\x32\x14\x30\x68\xd1\x50\x27\x44\x1c\x15\x01\xc9\xf8\xe2\xae"
+  "\xe2\x68\xe8\x97\x12\x95\x3e\x5f\xb7\xb5\xd2\xa2\xcf\xba\xbb\xd8"
+  "\x9a\x4d\x89\xad\x25\x32\xd4\x5a\x1f\x6a\xb1\x26\x42\x22\x96\x6c"
+  "\x14\x90\x11\x66\xee\xf9\xbe\x9f\x73\xee\x65\x66\x10\x34\x76\xfb"
+  "\x7e\xfa\xfc\x7e\x9f\x3f\xe0\xce\x3d\xf7\xdc\x73\xcf\x79\xce\x39"
+  "\xef\xf3\x3c\xcf\x79\xce\xf3\x60\xfd\xfc\x46\xae\x9f\x2f\x54\x69"
+  "\x73\x01\xbf\x0f\x6a\x63\x35\xe8\x7c\xca\x92\x9c\x8c\xec\x8c\x74"
+  "\xf3\x84\x65\x23\x58\x40\x84\xc8\xcc\x8c\x25\xe6\xec\x8c\x27\x97"
+  "\x67\x2c\x13\x02\x1a\x3d\x0d\xde\x1b\x01\x06\xf9\xe3\xf5\x8a\x33"
+  "\x32\xbf\x1f\x4f\x32\xac\x61\xed\x78\xa1\x07\x97\xfb\x17\xf5\x99"
+  "\x4a\xe9\x15\x09\x52\x8f\xd8\x06\xba\xee\x91\xfe\xa8\xed\xc9\x31"
+  "\xc4\xc7\xb5\xb0\x3d\x3f\x91\x7b\xed\xbf\x5f\x2c\x69\x15\x5e\xd0"
+  "\x5d\xf4\xfb\x74\x3f\xbf\xb6\x47\xd8\xff\x49\x9b\xb7\xdf\xe7\x81"
+  "\xc6\xc9\x7e\x1e\x64\xcf\x29\xc2\x41\x81\x87\x97\xc0\x42\x95\x77"
+  "\xc6\x77\xf6\x5c\xcf\x73\x79\xf3\xa6\x1e\x26\xf4\x78\xe4\xbb\x5d"
+  "\xe2\xeb\xef\x1b\x34\x3a\x82\x7f\x69\x26\x7d\x81\x26\x03\xcd\xf4"
+  "\x9e\xe7\xf9\x2b\x99\x9e\x74\x06\x3c\x2a\x39\xfe\x95\x6c\xb7\x9e"
+  "\x17\xbd\x70\x14\xbc\x4c\x0c\xe5\xd9\xa9\xda\x7e\xf1\xc8\x64\xcc"
+  "\xeb\x3d\x66\xbf\x7c\xb8\xa7\x59\xf0\xf1\x3d\x34\x6e\x7e\x5f\x93"
+  "\x42\x6b\x84\xc4\xee\xcb\x2f\x55\x5f\x3e\x42\xea\xca\x25\xbe\xed"
+  "\x49\x55\xdb\xd0\x4e\x98\xa5\xda\x0e\xea\xe5\xb8\xde\xd3\x8c\x31"
+  "\x17\x43\x7d\x01\x9c\x2f\xd1\xe8\x45\xed\x15\x72\xe7\x1a\xa6\x07"
+  "\x76\xc5\xbf\xba\xca\xa3\x97\xb1\x15\x5f\x38\x21\x65\x98\x3d\x47"
+  "\x03\xf7\x7c\xa4\x2c\xb5\xa7\xd1\xef\xd7\xe0\xf7\x17\x9c\x49\x59"
+  "\xba\x84\x8e\xa3\x3c\x91\xb2\x22\xed\x89\x8c\x94\xe5\xd6\x38\xf3"
+  "\xf2\x25\x62\x4b\x4d\x88\xef\x39\xcb\x1f\x7b\xc2\x4c\x28\x92\x32"
+  "\x6d\xfa\xf4\x94\x29\x0f\xfd\xea\x91\x11\x6c\x4a\x1a\xd2\x72\x96"
+  "\x9a\xa7\xc7\xc7\xc9\x47\x0f\xde\x39\x75\x4e\xca\xd4\x99\x0f\xdd"
+  "\x3f\x7b\x00\x9b\xd6\x08\x8c\x09\x13\xfa\x68\x58\x13\x7b\x79\xa2"
+  "\xb4\x61\x78\xd1\x1a\x6c\xc3\xf0\x22\xd6\xcf\x17\x77\xe3\xcf\xc1"
+  "\xd8\xcb\x90\x66\x5e\x9e\x88\x3f\x8b\x3a\x6e\x7a\xbb\x8b\x5e\xac"
+  "\xf0\x8f\x9b\x97\x85\x7f\x5d\x92\xf9\xa5\xce\xf4\x45\xe0\xdf\x0b"
+  "\x9d\x81\xcf\xfc\x58\xf0\xd2\xef\x04\x5e\xaa\xe3\x82\xc6\x43\x8a"
+  "\x37\x5c\x8c\x0d\xc9\xaf\xbc\xd8\xa9\x8d\x0d\x71\x4e\x0e\xe9\xa4"
+  "\xeb\xa2\xe7\x18\xdf\xb3\x49\x2f\x8c\xb1\x60\xa2\xfd\x4c\x4a\xe7"
+  "\x91\xf5\xb3\xd5\x72\xe3\x48\x4f\x4c\xfc\xac\xba\xef\x31\xb2\x8d"
+  "\xbd\xb4\x90\x17\xed\x71\x4b\x59\xf0\xc5\xf1\x62\xdc\x3c\x35\x76"
+  "\x8a\xd8\x3f\x12\xe7\x11\x5e\x4a\xf5\x8f\x9f\x97\x27\x52\xdf\x10"
+  "\x2e\x48\xec\x7d\x29\xaf\x9f\xfe\x25\x04\x69\x76\xcd\x0f\x76\xce"
+  "\x78\xa6\x0f\x1d\x6f\x67\x65\x7a\x5e\xe8\x62\x2f\x25\x48\x3b\xb6"
+  "\x97\xaa\x34\xfe\x19\xbf\x31\xff\xbf\x48\xe8\xaf\xb7\x2a\x0d\xd0"
+  "\x5b\xe5\x5b\xf9\xe7\x75\x56\x37\xf1\xc8\x0e\xa7\x5b\xf8\x5f\xbc"
+  "\xa3\xce\xda\x49\x3e\xfb\x46\xb4\xb0\x97\x87\x15\xf8\x78\x0f\x7e"
+  "\x8f\x45\xdb\xc4\x1a\x72\x93\xd4\x1b\x40\x1e\x7b\xf9\x27\x52\x36"
+  "\x91\xe9\x44\x77\x17\x7b\x71\x2f\xc9\x66\xd4\x3f\xf8\x6d\x0f\x31"
+  "\x5d\x76\xdb\x40\xb8\x37\x72\xad\x5e\xf5\x73\xf3\xf2\x7a\x92\x51"
+  "\x89\x56\xcf\xe8\x95\xcc\x67\x8a\xf0\x87\x2b\x61\x9f\x9f\xbf\xe4"
+  "\x1e\x49\xdb\x97\x4b\x6a\x6c\xed\xb4\x6e\x7a\x06\xb5\x2f\xcc\xe5"
+  "\x8d\x5a\x7f\xce\xf4\xb9\xef\xa0\xfe\xea\x2e\x7a\xd9\xa1\xf5\x65"
+  "\xc7\x8d\x19\x55\x21\x6b\x99\xf9\x70\xc5\x2d\x94\x8e\xf9\xff\x72"
+  "\x82\x6a\x3f\xd9\xd9\xff\x5d\xe0\x70\x82\x7c\x7f\x2f\xd3\xde\xef"
+  "\xef\x3f\x55\x1c\xf0\x23\xe5\xd4\x6d\x42\x85\x65\x51\xc3\xdd\x06"
+  "\x9d\xd5\xa1\x33\x98\x35\x72\x4c\x6a\xba\x33\xa3\x6c\xcf\xde\xf3"
+  "\xca\x16\xc8\xdf\x5b\x7e\x75\x8b\xaa\x07\xc0\xdc\xde\xbb\xe3\x46"
+  "\xc6\xb2\x3a\x57\x24\xf5\xe9\x49\x48\xbf\x40\x3e\xd1\x50\x8f\x92"
+  "\x00\xdd\x56\x9f\x8d\x97\x8b\xed\xf5\x90\xcd\x09\xca\x99\x48\xe5"
+  "\xd0\xbc\x92\xba\x99\xbd\xd5\xe4\x43\x07\xe5\x2d\x11\x7b\x97\x45"
+  "\x7b\xc5\x59\x2b\x92\xb5\x85\x9c\x9f\xc7\xbf\x54\x6d\x20\x04\xef"
+  "\x22\xcf\xf3\xec\x6d\xef\xd3\xf7\x88\xb3\x2d\x7b\x33\xc9\xae\xb3"
+  "\xbb\x68\x5f\xe8\x40\x7a\x3e\xe0\x43\x66\xda\x92\xf4\xa5\x8f\x3f"
+  "\x7e\x69\x68\x08\xb4\xb5\xb4\x17\x29\x25\x28\x13\xf2\x6f\x59\x92"
+  "\x1c\xa7\xfb\x80\xff\xbf\x91\xbc\x2e\x78\x18\xcc\x9b\xab\xdb\xd8"
+  "\x3e\x87\xc6\xbf\xcb\x79\xb4\xaf\x96\x17\xed\x33\xfa\xe7\xc6\xbe"
+  "\xf2\x0b\xe7\xc6\xbe\xbd\x03\xcf\x8d\x7d\xf5\x58\x67\x1b\xf1\xbc"
+  "\x16\xdf\x94\x3c\x18\xf5\xb7\xe4\xc1\x1d\x06\xef\x1d\x82\x07\x4f"
+  "\x59\xc9\x74\xc4\x7f\x93\x4e\x99\xd6\x03\x1f\xe4\x5a\x1f\x30\x22"
+  "\xc5\xcb\x8c\xb4\x16\x6c\x5a\x42\xfa\xc2\x71\xdc\x7b\x8e\xbb\x52"
+  "\x56\x02\x2f\x70\x5f\xda\x26\xf7\x59\xe7\x77\x41\x0e\xc1\xef\x4d"
+  "\x2d\x84\x15\x0a\x39\x6b\x67\x72\xbd\x7e\x25\x41\xe3\x71\x0d\x6b"
+  "\xcd\xc2\x87\xaf\x58\xb7\x31\xce\x68\xdd\x4e\xf1\x19\x1c\x72\xdd"
+  "\x7e\x25\xf3\xa2\xba\xe9\xc8\x03\xc6\x81\xd2\x51\xc7\x1a\xaa\x17"
+  "\xea\x59\x85\x7a\xed\xa7\xfa\x94\x3e\x4e\xed\x0a\xb9\xd5\xe0\x8d"
+  "\x17\x7b\x03\x54\xcf\xf9\x9d\xec\x56\xaa\xdf\xfc\x27\x6f\x65\x3b"
+  "\x1f\xa7\xfd\x5d\x69\xd7\xa3\x8e\xa5\x50\x8c\x99\xe1\x2d\xec\xd5"
+  "\x98\x4e\x11\x53\xf1\x15\xf4\x7d\xb8\xe4\xeb\xd5\xbd\x13\xca\x43"
+  "\xcf\xe4\x38\x7d\x35\xe6\xb0\x8d\xea\xfc\x6a\x8c\x96\x2f\xb0\x6e"
+  "\x53\xd3\xac\x60\x2c\x17\x3e\xfe\x78\x46\xf6\x32\x2d\x3e\xb4\x65"
+  "\x69\x56\xfa\xed\xea\x79\xd7\x25\x19\x2b\x52\x16\xa6\x0b\x7b\x7a"
+  "\xa4\xca\x9f\xfd\x78\x8d\x38\x92\x05\x84\x8d\xaa\xe0\x33\xfe\x70"
+  "\x7e\xa7\xca\x73\x34\xb1\xaa\x12\xb9\xff\x5c\xf5\x4b\xb9\x0e\x5c"
+  "\xfe\x24\xea\xb1\x5b\x5b\x07\x48\x1f\xd1\xc1\xc6\x5b\x68\x5f\x88"
+  "\xce\x30\xd3\xfe\x13\xe9\x24\x90\xe7\xa8\x8b\xbd\x92\xa3\x8d\xed"
+  "\x8d\x48\xa7\x73\x13\x8e\x25\x64\x6b\xb7\x7f\x8c\xb2\x79\x4e\x1c"
+  "\x8f\x9a\xe2\x02\x06\x44\xd0\xda\x40\xfb\x21\xd2\x1f\x7f\x55\x34"
+  "\x61\x1b\xe9\xcd\x1c\x4b\xc8\x76\xed\xd5\x66\xac\xe5\xe0\x81\xf7"
+  "\xc7\x40\x2e\x8a\x5b\xb7\x8a\x85\xd3\x37\xb0\x6e\xb8\xa4\x9e\xb5"
+  "\x2a\xfe\xad\x3c\xc6\xd4\xb5\xc3\xb5\x51\xe8\x14\x5f\x95\x3e\x13"
+  "\xed\x73\x12\x54\x9d\x43\x02\xf2\x61\xfc\x5f\xc1\x64\x9d\xa7\x86"
+  "\x8b\x7d\x2f\x81\x0b\x55\x79\x7c\xcb\xd4\x72\x61\x5f\xb8\x65\x6a"
+  "\xb8\xc2\x33\x43\xe8\x1e\xb8\x3c\x02\xe5\xec\xe6\x05\x16\xa6\xda"
+  "\x24\x86\xb4\xb0\xd7\x86\xe1\x1a\x8a\xfe\x28\x23\x5a\xa0\xfc\xe9"
+  "\x6a\xf9\xd3\x51\x3e\xd6\xbf\xab\xec\x72\x7e\x55\xd5\x68\xdf\xc2"
+  "\xd8\x26\x9d\x4c\x34\xad\x5f\xa8\x7f\x2c\xfe\x2c\x52\x3f\xe3\x81"
+  "\x9c\x34\xae\x4f\x3f\x23\x79\xa4\x2a\xaf\x36\x26\xe9\xdb\x6a\x1b"
+  "\x12\xc9\xe7\x0b\xe9\x13\xd4\x6f\x25\x92\xae\x40\x2b\x93\xa3\x4c"
+  "\x7e\xae\xbd\x12\x6b\x4d\x38\xe6\x98\x7b\xe4\x5a\xac\x29\xf4\x0d"
+  "\xe2\x71\x3b\xc7\x71\xac\x39\xbe\x14\x5f\xa8\x3c\x6f\xbe\x92\x5d"
+  "\x11\xc8\xdf\x76\x17\xbd\x96\xe5\xe7\xc9\x50\xc6\x39\x60\x59\x3e"
+  "\x2b\x6c\x66\xaf\x09\xff\x67\x64\xcf\x41\xfd\xda\x83\x7e\x42\x5f"
+  "\xb5\xe2\x3b\x55\xe0\xcb\xaf\x00\x1d\x5e\xa4\xfe\x2a\x55\x30\xe7"
+  "\x7a\x04\xaf\x6e\xa0\xd8\xe9\x4d\xec\xb5\xad\xd4\x57\x54\x16\x68"
+  "\x5c\xed\xed\x4e\xba\x9b\xfc\x52\x11\xad\xd7\xe4\xf1\x56\xda\xa3"
+  "\xc3\xd8\x1a\x43\x3c\x2c\xf8\x7a\xf1\xbb\x20\x9d\x2b\xa2\xaf\x85"
+  "\x9d\xe2\x1f\xc6\xac\x69\xe5\xca\xf9\x22\xc6\x8f\x02\x4b\xcf\xeb"
+  "\x99\xd7\x03\x19\x14\xf5\xd6\x17\x7c\x4d\xbe\xb3\x2a\x31\xbf\x4a"
+  "\x18\xbe\x1b\x5e\xba\x8a\x19\xc9\xd7\x58\x81\x95\x7b\xea\x3a\x2b"
+  "\x58\x9d\xb5\x82\xbd\xe7\x2d\x63\x8e\x5c\xd2\x69\xfe\xc1\x71\xcc"
+  "\x56\x46\x76\xe1\x97\xe1\xf7\x5a\xf3\x1c\xfa\xd6\x7f\x24\x1d\x3b"
+  "\xf1\x01\x3b\xe6\xf8\x80\x99\xe7\x8a\xfb\xcc\xda\xa4\xf7\x58\x6d"
+  "\xc2\x7b\xac\xa0\x99\x2b\xc4\x0f\xe5\x2f\xa6\x6f\x94\xa0\xac\x4a"
+  "\xf2\xd1\x65\x54\x3a\x4c\x23\xd0\xfe\xd0\x99\x36\x26\xf6\x01\x1d"
+  "\x4b\x5e\x47\x1d\xff\xe3\xab\x9d\x67\x59\xb8\x63\xc9\xdb\xe2\xb7"
+  "\xd0\x2f\xa0\xbd\xce\xf4\x06\x61\x23\x46\x3e\xc9\x9c\xb6\x56\x3a"
+  "\x5f\xa9\x6c\xa2\x3a\xfa\x64\xbd\x41\xaf\x50\xed\xfd\x5d\xf9\x7d"
+  "\xef\x0b\x5f\xb1\x3b\x88\x1e\xa8\xd3\xf1\xd9\x92\x26\xb5\x0d\xa0"
+  "\xe9\x1c\x95\x3e\x49\x81\xf4\xf9\x8f\x70\xa2\x0f\xd9\x7f\x2a\xb9"
+  "\xed\x95\xa8\x5b\x02\x68\xa0\x68\xdf\xa0\x31\x40\xfb\x55\x54\x7e"
+  "\xe9\x59\x16\xe1\x58\x42\xf6\xa1\x7f\x58\x6c\x98\x15\x1a\xae\x9c"
+  "\xfb\xba\x6a\x53\x17\x0b\xa5\x7e\xa3\x75\x76\x93\x78\x2e\x68\x3e"
+  "\x8b\xfa\xcc\x1d\xf9\x2b\x33\xfe\x30\x3e\x7f\x65\xa1\xb1\x87\x6b"
+  "\x1c\xfa\xab\x04\x74\x6a\x45\x5f\x55\xd2\x55\x8e\xc7\x69\x49\xe4"
+  "\xaf\x91\xd6\x32\x8c\x15\x7f\xfa\x96\x69\x0f\x7b\x31\x77\x14\x21"
+  "\xa7\xfd\x47\xab\xb2\x39\xd5\x22\x6d\x05\x5f\xb5\xec\x00\x5f\x5c"
+  "\xb1\x45\x9c\x47\x8f\x00\x2f\x2f\xd6\xc5\xe7\xc4\xb9\x95\x3f\xf4"
+  "\xad\x7f\xbf\x11\xb1\xcc\xff\x60\xd2\x0b\x9b\xb0\x39\xd3\xd4\xb1"
+  "\x3e\xad\xbb\x68\x3f\xe6\xfe\x68\x55\xae\xae\x12\x67\x5a\x08\x07"
+  "\x06\xe3\x49\x80\xcb\xb5\x64\x63\xc7\xaf\x4a\x62\x11\x3a\xee\x8e"
+  "\x48\x35\x70\xa7\xb7\x86\xc6\x50\x84\x18\xfb\xf2\x19\xf8\x48\xb7"
+  "\x01\x58\x5e\x8f\xf4\x50\x2d\x9d\x70\x5d\x81\x6c\x49\x72\xed\xcc"
+  "\x95\x06\x9e\xdf\xc5\x62\x84\x8e\x48\x4b\x5f\xe9\x36\xd4\x99\x18"
+  "\xd9\xdc\x7b\xc9\x0f\x05\xbd\x83\xf4\x10\xac\x03\x07\xf1\x5d\x07"
+  "\xf2\x47\x6b\xf9\x79\x47\x52\xa8\xd3\x56\x23\xe6\x19\xf9\x56\xd2"
+  "\xd6\x05\xa4\x0f\x9b\x69\x73\x1b\x44\x9f\x69\x69\xcb\x92\xc4\x3a"
+  "\x46\x67\xde\xc1\xa7\x72\x51\x9f\x16\x91\xae\x83\x9c\x29\x62\xa5"
+  "\x07\xa4\xe9\xc9\xbf\x00\xf9\xc5\x0b\x48\x0b\x41\x9d\x59\xdf\x3d"
+  "\xbe\xbd\x69\x91\xd8\xa7\x37\xcd\x5c\x49\x7b\x62\xf8\xce\x22\xf5"
+  "\xdb\x2b\x39\x93\xfe\x36\x65\x9a\x5c\x33\xff\x98\x13\x28\xe3\xd2"
+  "\x1e\x05\x7d\x5b\xe9\x48\xd2\xfb\x3a\x92\x42\xe8\xfb\x54\x16\xe9"
+  "\x27\x45\xcc\x76\x6f\x2b\x23\x5f\xcf\x7c\x73\xbd\x95\xd3\x19\x0b"
+  "\x94\x2b\xea\x63\x83\xfc\x1f\x59\x3f\xb0\x5f\x01\xfb\x21\x8b\x23"
+  "\x7f\x2e\xc6\xf4\x9f\xf2\x08\x53\x7c\xc6\x87\x27\x9b\x17\x91\xdd"
+  "\xc1\x1f\xbb\xa8\x4f\x7d\x98\xe7\xbe\xc8\x87\x27\xdf\xd4\xca\x74"
+  "\xf9\x98\x3b\x72\xaf\xee\x4f\xa3\x88\xa7\x2a\x50\x38\xc7\xef\x70"
+  "\x1a\xbb\x86\x76\xb2\x3d\x79\x38\x41\xd8\x7b\x44\xbd\x6e\x76\x7a"
+  "\x5a\x59\x6d\xe1\x27\xac\xd6\xeb\x2c\x3c\x78\xd6\x1d\x2a\xed\x3e"
+  "\x42\x51\xee\x9f\xae\xa7\x67\x05\x98\x2f\x29\xbe\xca\xc1\xe5\x40"
+  "\xc8\x16\xa0\xdd\x67\x72\x2d\xf8\x53\x9e\x26\x4f\x5c\xa2\x0d\x27"
+  "\xc8\xb7\x21\xd9\xc5\x29\x5b\xca\x67\xa1\x2e\x05\xbc\xdb\xc2\x6e"
+  "\x5a\x45\x7a\xdd\x3f\xed\x1d\xd9\xc9\x12\xd4\x72\xbf\x51\xcb\x3d"
+  "\x71\xb1\x72\x69\xdc\xd6\x96\x4b\x5b\x0b\x25\xaa\x3c\xc1\x87\xb2"
+  "\x7d\x51\xe5\x85\x58\x6b\x0a\x0a\xce\x93\xee\xa4\x7a\x0c\xbe\x93"
+  "\x50\xe7\xad\x67\xe4\x23\x75\xa7\x82\xf5\xfa\x1b\x13\x53\x6d\x5c"
+  "\x0a\x4e\xb3\x3f\x0f\x53\xb8\xc5\x08\x39\x87\x74\xa5\x05\x84\xb3"
+  "\xa4\x7b\xce\xf7\xb1\x30\x27\x7a\x96\x7c\xfc\xa1\x8c\x2b\x8e\x90"
+  "\x5e\x1a\x58\xe5\xe3\x26\xfd\x1b\xe7\x5c\x6c\x13\xf0\x5b\xf8\xfc"
+  "\x7b\xea\xaa\xe7\x46\xae\x65\x77\x70\xbd\x41\xd8\x30\x61\x7d\x49"
+  "\x42\xdf\xda\xa4\x4d\xcd\x9c\xd9\x01\xf6\x34\x21\xf8\xd6\x7a\xb2"
+  "\xa7\xe1\xc6\x39\xa6\x0a\x5a\x33\xd1\x67\xdd\x45\x7f\xde\xef\x62"
+  "\x7f\x14\x7c\xc9\x06\xd2\x03\x08\x9c\xaf\x1e\xef\x8e\x2c\x33\x53"
+  "\x19\xe4\x0b\x48\xc9\xf5\x56\x6d\x3a\x03\xbe\x47\xd0\xa3\x5a\x57"
+  "\xd7\xde\xed\xe0\xf6\x32\x33\xcd\x23\xb5\x6c\x03\xca\x7e\x9f\x6f"
+  "\x2e\x33\xbb\x58\xb5\x59\xf6\x0d\xfd\xfe\xb3\xd8\xeb\xf0\xf6\xd2"
+  "\x39\x9c\x3f\x67\x56\xf4\x90\x4e\xee\xcf\xc0\x95\x71\x8e\x0e\x63"
+  "\x99\xf9\x57\xa6\x42\xf0\x00\xd5\x13\x5d\xfa\x6f\x04\xaf\xa1\xf9"
+  "\x2f\x1c\x6c\x0f\x8a\x6f\x37\x8d\x70\xa2\x10\xf0\xb8\xd1\x6d\xec"
+  "\xf5\xdf\xf5\x40\xce\xef\xc5\xda\xda\x03\x39\x81\x6f\x4f\x8a\x28"
+  "\x1d\xcb\xe2\xf1\x6c\x6c\x1b\xab\x5e\xef\xd5\xb3\x68\xfc\x19\xdd"
+  "\x57\x65\x5e\x86\x72\x13\x48\xff\x79\xfc\x2c\xed\xbb\x56\x0b\xdc"
+  "\xdf\xf4\x1c\x8b\x55\x50\x1e\xe9\x5d\x37\x8d\x65\xb1\xa4\x73\x45"
+  "\x9a\x25\xc5\x27\xf7\x24\x34\x99\xea\xa9\xb1\x2c\x2e\xf8\xbb\xd5"
+  "\x56\x29\xcb\xbd\x2e\xd6\xf8\x15\x6e\x76\x8d\xf5\x17\xbc\xa9\x85"
+  "\x1d\x48\xe7\x45\x21\x9c\x5f\x65\xd2\x4b\x99\xe2\xc0\x0c\x43\xb9"
+  "\x1c\x77\x42\x07\x8f\xf1\x46\x7b\x1c\xaa\x6e\x57\x27\xfc\x36\x46"
+  "\x3d\x5a\x4b\xe7\x20\x44\x9a\xce\x48\xb4\x34\x8a\x7a\xa8\x3e\xd7"
+  "\x7c\x4f\xfd\x88\x62\xbb\x09\x5f\x6b\x29\x69\x52\x2f\x4c\xfe\xd8"
+  "\x40\x63\x71\x1e\x6c\xc3\x73\x2c\xe2\xb7\xcf\x31\xe3\xf1\xc7\xa9"
+  "\x5d\x07\xf2\xe4\x5c\x0c\x65\x54\x5f\xc5\x4e\xf3\x0c\x63\x02\xf5"
+  "\xa6\xef\xd1\xd8\xa8\xf3\x7e\xe3\x28\xc8\xe1\x8a\x63\x11\xf9\x02"
+  "\x38\xf0\x86\x23\x7b\x2f\x9b\x49\xfe\xeb\xc8\x87\x4d\x32\x73\xef"
+  "\x42\x79\xbb\xc6\x32\x23\xca\x7a\xd7\x99\x45\x58\x6b\xba\xd6\x91"
+  "\xbd\x9f\xca\x3e\x49\xeb\xd1\x46\xd0\x47\xae\x4b\xaf\xdb\x9d\x9e"
+  "\x06\x46\xfe\xea\xef\xb7\x72\x1f\x95\xd3\xc2\x5e\x1f\x25\xda\xbb"
+  "\xdd\x64\x4e\x91\x3e\xf3\x44\x5b\xfb\xf4\xed\x6a\x3b\x9c\x67\xa9"
+  "\xbc\xd7\x2d\xce\x54\xf0\x9c\x6a\x9b\x34\x5a\xcb\xf1\xf5\x7a\x86"
+  "\x23\x7b\x37\xa3\xfe\xa1\xfc\xb8\x9f\xed\x6c\x47\xde\xaf\x83\xfb"
+  "\x85\xf2\xe0\xd9\xd3\x28\xf7\x67\xfe\x7d\x24\xda\xdf\xf0\xe7\xa9"
+  "\x40\x7b\x40\xab\xa3\xdb\x41\x23\xa9\x5f\x3b\x70\x86\xea\xea\x62"
+  "\x07\xdc\xce\x9c\x4f\x06\x3e\x7f\x84\xb9\x8f\x71\xbf\xb6\x4e\xe8"
+  "\x96\x5e\xff\xfc\x7e\xaf\xc2\x25\x9e\xfd\xa5\x4c\x01\x0e\xb8\x70"
+  "\x25\x2c\x10\x78\x72\x23\xed\xfd\xfe\x65\xab\x41\x27\xfb\x97\xda"
+  "\x42\x3c\xd3\x40\x7d\x1c\xa0\xd7\x37\x52\x5d\xb5\x3e\xe6\xc6\x43"
+  "\x16\x85\xf6\x6b\xc6\x32\x71\xa6\x48\x8e\x3f\x6e\x47\xb9\x4f\xab"
+  "\x3c\x64\xb9\xba\x9e\x96\x77\x44\x3e\x9c\xc8\x57\x9b\x98\x66\x6b"
+  "\x87\xf9\x3b\x2d\x45\xda\x2f\x9a\x08\xa3\x76\xe9\xe5\xdc\xa1\x3a"
+  "\xaa\xef\x96\xc9\x7d\xe4\xbf\xcc\xc6\xfb\x65\x03\xb6\x37\x04\xb8"
+  "\x53\x04\x98\x46\x7b\xc4\xb9\x00\x60\x15\xd6\x83\x30\x67\x67\x0f"
+  "\x93\x7b\xdb\x07\x23\x29\x76\x3c\x9d\x09\xd3\xea\x36\x34\x1d\xfc"
+  "\x5f\x1a\xa5\x0e\xfe\x60\x8c\x26\x6f\x72\x23\x68\x5c\x64\x10\xbe"
+  "\xcb\xc1\x77\x29\x9d\x91\x87\xe2\xdd\x91\xf5\xa9\x72\xde\x1c\x9c"
+  "\xc6\x23\x25\xde\xa6\x78\x58\x21\xb5\x4b\x95\xbb\xc2\xa8\xcd\x28"
+  "\x27\x5d\xdb\x0b\xd6\xca\x1e\x34\x1e\x80\xd6\x36\xb4\x49\x9e\x25"
+  "\x3e\x64\x11\x6d\x23\x7f\x18\xb2\x6d\xe2\x3c\xee\xd0\xda\x73\x50"
+  "\xc6\x08\xb0\x1f\x8a\x77\x8c\xa5\x32\x0e\xad\x14\xb6\xf8\xe8\x13"
+  "\xe0\xc3\x95\x6d\xec\x8d\x89\x7c\xc4\x6f\x47\x0c\xad\xcc\x37\x98"
+  "\x2c\xb3\x3e\x75\x2b\x30\x58\x9e\x0f\x22\x1b\x96\x43\x69\xc0\xf2"
+  "\x54\x92\x61\x3a\xf0\x3d\x8c\x8f\x00\x1c\x7a\xa3\x99\xfa\xea\xc6"
+  "\xbd\x2c\x41\x8e\xc3\x37\x3e\x26\xbd\x84\x8c\xd7\xf2\x46\x09\xc6"
+  "\xfd\x74\x29\x2f\x69\x76\x99\x3a\x61\x97\x19\x88\xb1\x43\xac\xa3"
+  "\x94\x69\xa2\xc8\x2f\xe3\x1b\x36\x61\xa7\x83\xfa\xae\xf0\x6a\xf8"
+  "\xf7\x86\x8d\x93\x6e\x38\x5f\xd5\x11\x12\x96\xe5\x4b\x7f\x5a\xdd"
+  "\x45\x87\x4c\x7d\x3a\x42\x3a\x3f\x59\xc4\x8f\x52\x3e\xf4\xfd\x37"
+  "\x94\x47\xfa\xfb\x69\x53\xcf\x16\x1e\xba\x41\x3d\x37\x68\x21\x7b"
+  "\x24\xbc\x3b\xdb\xc5\x9a\xf6\x0b\x5d\x0e\x68\x40\xdf\x16\x75\xd7"
+  "\x93\x3e\xf0\x90\xd5\xaf\x93\x7d\x43\x9c\xe7\x96\x67\x7f\x0f\x95"
+  "\x68\x63\x04\xed\x0d\x93\x3e\xfa\x0f\x9e\x39\x1c\xc7\xc4\x18\xe8"
+  "\xe0\xa6\x11\x3f\xac\xa0\x31\x79\xa8\x2a\x90\x4e\x33\xbd\x4a\x81"
+  "\xc4\xa0\x37\xca\xb9\x98\xeb\x6f\x94\x5f\x9a\x9f\x78\x73\x98\xc6"
+  "\x8b\x48\x3a\x1b\x41\x9f\xb7\xea\x05\xad\xed\x53\x3d\xe4\x57\x73"
+  "\x75\x3e\xf9\x06\x7e\xf3\x08\xf9\x5d\xf6\xda\xa7\x99\x7c\x05\x26"
+  "\x8a\xe9\xc2\x14\xfb\x34\x4b\x8b\x95\xe9\x53\xac\xa4\x87\x7e\xc6"
+  "\x4d\x32\x1e\x64\x56\x23\x8f\x02\x7f\x82\x79\xbe\x66\x21\x33\xcc"
+  "\xcb\x44\xd9\x05\x96\x68\xf2\x8b\x4c\x3e\x91\xc9\xaf\xb9\xaf\xc0"
+  "\x12\x85\xdf\xa3\xc1\xcf\x19\xb9\x71\x5a\x38\xed\x65\xfb\x8a\x38"
+  "\xf0\xb8\x91\x7c\x33\xeb\x9d\x6e\x0f\x5b\xf3\x35\x0b\x27\xbf\xcb"
+  "\xde\xcd\x65\xe1\x75\x9d\x27\x85\x7c\x33\xd2\xca\xa2\xc1\x7f\xc4"
+  "\x80\xe6\x26\x25\xf2\x19\xc8\xa1\xcf\x74\xca\x76\x7f\xc3\x65\xbb"
+  "\x65\xbd\xa9\xfe\x12\xe3\xee\xb2\xe4\x8b\xba\xbf\xb5\xd0\x8b\xf2"
+  "\x15\xfb\x7d\xb1\x3e\xfb\x7d\x66\x79\x7e\xb5\x96\xe5\xe7\xf0\x56"
+  "\x67\x67\x2d\x64\xae\x2e\x11\x87\x8a\xf6\xca\xa9\x8d\xd4\x3e\xfa"
+  "\xf6\xb1\xb3\x5f\x0b\x3f\xd2\x5e\xdc\x17\x64\xa9\xef\xb4\xe3\x9d"
+  "\xf6\x5a\xd6\x63\xbf\x4f\xb4\xbd\xae\x53\xbe\x9b\x22\x7e\xd3\xfb"
+  "\x01\x74\x50\xdb\xdc\x47\x07\xb4\x9d\xda\x47\xed\xf7\x12\x4d\x40"
+  "\x03\xb5\xad\xa6\x5e\xb5\x9d\xd4\xc6\xf7\xb0\xea\x3c\x87\x76\xa2"
+  "\xad\xa2\x9d\xbd\x68\xe7\xd1\x4c\xc6\x3c\x5b\x0e\x25\x9c\x8f\xba"
+  "\xcf\x4c\x32\x6a\xc1\xfb\xe0\xe1\xf3\xec\x0c\xb2\x68\xe8\xbe\x7c"
+  "\xbb\xfe\x37\xe0\x4d\xf2\xdd\x90\x49\xdd\xbc\x95\xec\x54\x9d\x56"
+  "\xfc\x79\x2b\x18\xf1\x38\x1a\xbf\x8e\x6f\x9b\x8e\x29\xa7\x58\x7e"
+  "\x2b\x6f\x05\x6f\xea\x71\x7a\x91\x27\x13\xed\x87\x0c\xdb\xa2\xd6"
+  "\x9f\xf2\xae\x39\x23\xdb\x65\xc8\x62\xd1\x6f\xce\x2d\xd1\x3b\x1b"
+  "\x4a\x98\xd6\x96\xf9\xc8\x87\xf6\x98\x50\x96\x88\x43\xa3\xa0\x9d"
+  "\xdb\x51\x4f\x4f\x40\x9b\x8e\xb7\x93\xad\xec\x87\x6c\xc4\x2c\xa6"
+  "\x7b\xee\x34\xda\x71\x9a\x99\xec\xf9\xe0\xbf\x1e\x24\x7e\xd1\xf1"
+  "\xfc\xe5\x49\x2c\xd6\xc5\xde\x94\xf1\x5a\xa5\x9f\xd7\x51\x6d\xec"
+  "\xad\x77\x35\x5f\xae\x0a\xf9\xc2\x8e\x2c\x8b\xa0\x71\x24\xfc\xba"
+  "\xd2\x9a\xd1\x8d\x31\x43\x7b\xda\x2b\xf0\x8d\x6e\xcb\x68\x51\x9f"
+  "\x22\xe9\x0b\x16\xf7\xe4\xf7\x82\xce\x86\xe9\xf0\x5e\x38\x07\xcd"
+  "\xa8\x7c\xbe\xf9\x99\x4e\xba\x12\x0d\x07\xb4\x2b\x7d\x85\x4d\xc2"
+  "\x37\x66\x93\xfc\x5d\x95\xef\xd6\x3f\xfd\x0a\x8b\x1b\x1a\xa6\xbc"
+  "\xe5\x19\x0c\xbf\x49\x97\x49\xe5\xa1\x6d\x51\x6d\xec\xed\x93\xc1"
+  "\x73\xcc\x2c\xb0\x4c\xe2\xe0\xdb\xbb\x49\x57\x38\xb4\xef\xbe\x2d"
+  "\x78\x38\xb2\x47\x18\xe2\x7b\x7b\xb4\x7a\xe0\xf7\x05\x76\x44\x5a"
+  "\xdd\x87\x4e\x87\xc3\x6c\xb0\xb2\x36\x6e\x13\x36\x83\x05\xa5\xdb"
+  "\x80\x17\xe0\x15\x0e\x9b\x68\xdf\x01\x6b\xe7\xee\x4e\xb6\x6c\x07"
+  "\x0b\x2f\xf8\x9a\xf4\x42\x33\xd8\xe1\x8a\x78\xb6\xf3\x2c\xf9\x67"
+  "\xb2\x44\x3d\x73\x16\x7d\xa9\x62\x08\xf1\xa4\xa4\x73\xe5\xcb\x2c"
+  "\xc6\x4d\xdb\x34\x1e\xfe\xf0\xbb\x79\x5d\x4c\x2f\x63\x7f\x1f\x3e"
+  "\x3a\xcd\xcc\xbd\x65\x7a\x25\xb3\x82\xfc\x1c\x47\x55\x5b\xc9\xcf"
+  "\xb1\xe6\xf7\x57\xf0\x3e\x36\xcc\xb9\x0e\xd3\x88\x8d\xd9\x2c\x8e"
+  "\x7c\x94\x1b\xdc\x92\x97\x93\xeb\xf5\x61\xb2\xdd\x34\xaa\xbe\x80"
+  "\x8d\xaa\x2f\xe0\x04\xb2\xab\x96\xcf\x6b\xae\xf7\x41\x86\x11\xe5"
+  "\x66\xb3\xd8\x8a\xb3\xcc\x42\x7c\x50\xca\x29\xc9\xb3\x91\x5c\x38"
+  "\xa3\xdd\xc0\x7d\xff\xb0\xb0\x1d\x6d\x7e\x1f\xe6\xee\x65\xe4\xf7"
+  "\x9c\x9b\x06\xb3\x11\xde\x34\x5a\xec\xbd\x0b\xbf\x94\xa4\x93\xc7"
+  "\x3d\x2b\xdb\xc2\x42\x0f\x93\x1d\x5f\xa5\x3c\x6f\x74\xd8\x2b\x6d"
+  "\x5a\xbb\x8b\x6a\xca\x35\x1f\xcf\x83\xee\x2d\xdb\xa5\xbc\xa3\x84"
+  "\x41\xfe\x72\x77\x3b\xa4\xbf\xbf\x1a\x97\x73\x9d\x12\x20\xe3\xd4"
+  "\xbc\x45\xcf\x28\x8d\x7c\x28\x25\x08\x5a\x1e\x09\x27\xb9\x47\x95"
+  "\x19\xdf\x34\xf7\xa5\x49\x1e\x46\xd8\x15\x9b\xe4\x5e\x19\xd6\xa6"
+  "\x91\xdd\x45\x47\x62\xb5\xf5\x8c\xd6\x75\xa9\x1b\x3e\x32\xc9\xa5"
+  "\x3f\xb3\xf7\x22\xf5\x33\xaa\x76\xd0\xb4\xcf\x91\x80\xfc\x99\xda"
+  "\xfa\x26\xf6\x3b\x9f\x1a\x3b\x65\xd9\x4a\x16\xf3\xab\x31\xe1\x8c"
+  "\xf6\xca\x90\xb7\x55\xae\xbb\x47\xec\x7e\x7d\x7a\x82\xa0\x37\x9d"
+  "\x07\x16\x32\x06\xf9\xd9\x93\xfe\xca\xdb\x35\x7f\x7b\x72\xfd\x3d"
+  "\xb2\x2f\xe0\x3b\xf5\x7d\xeb\x28\xbe\x41\x76\xd6\x54\xbe\xe4\x4d"
+  "\x8e\xac\x13\x67\xc6\x90\x4f\xae\xaf\x47\xd6\x5d\x84\x17\xb3\x10"
+  "\x7d\x15\x55\x9e\x74\xb6\x7f\x29\xe9\x6b\x63\x21\x37\x95\x31\xd3"
+  "\x9b\xf9\xae\xd0\x91\xd2\x8f\xae\xa1\x89\xbd\x33\x9e\x9e\xd3\x58"
+  "\x77\xdc\x48\xfa\xc0\x77\xd6\x38\x69\xdd\xee\x4d\x8a\xb8\x9f\x64"
+  "\x7d\xc1\x8b\xbf\x93\x75\x03\xde\x43\x5a\xd4\xa1\xd3\x9e\xd0\x4d"
+  "\xab\x58\x9c\xf4\x5b\xf8\x8e\xb0\x6b\x72\x5f\xf9\x44\xf7\x0f\xa3"
+  "\x99\xe9\x87\x65\xcc\xd2\x5d\xf4\x4e\x19\xe4\xcb\x56\xa1\x27\xa5"
+  "\xef\x6f\xa9\xb7\x93\xaf\xf6\x57\x7b\x5c\xc3\x64\x5f\xfd\xf5\x66"
+  "\xdc\x5b\xfc\xf7\xef\x1c\x57\xf7\x52\xd0\xf6\xbf\xc6\xef\x3a\x2d"
+  "\xed\xc5\x85\x7e\xc9\x7e\xc0\xe8\xdf\xab\xff\xeb\xcd\xb2\x2e\x7f"
+  "\xbd\xf9\x30\xd0\x64\xc7\x36\x7e\x62\xe7\x68\x5e\xdf\x5d\xf4\xd7"
+  "\x50\x17\x3b\x32\x4d\xd5\xc7\xd4\x8b\x71\x45\xfc\x6e\x31\xc9\x60"
+  "\x5f\x3a\x36\x22\x1f\xad\x13\xe0\x8f\x12\x24\x0f\x7f\xc0\xa2\x60"
+  "\xfc\x04\xb4\x7f\x07\xe9\x1b\x07\xc4\xc4\xe7\x18\x13\xef\x6c\xae"
+  "\xce\x14\xb6\x1f\x9b\xeb\x5b\x71\xc5\x58\x7b\xdd\x88\x6b\x04\xc6"
+  "\x9c\x19\x57\x23\xae\x26\x5c\xa3\xf1\xbc\x9e\xc6\x25\x64\x58\x13"
+  "\xc5\x9b\xeb\x88\xac\x4e\x1d\xec\xec\x0f\xd1\xc6\xb9\x6e\x0e\x93"
+  "\xf6\x6d\x47\xa3\x29\xd6\xd8\xcc\x1d\x8c\x2d\xf3\xf2\x1e\xf3\x35"
+  "\x6c\x78\x13\xd2\x0a\x76\xd0\xbe\xf3\x5f\x5b\x83\xf7\x9d\x8f\x86"
+  "\xe3\x2f\x11\x7f\x15\xf8\xab\xc5\x5f\xb4\xff\xef\xdd\xf0\xee\xa2"
+  "\xa3\xd1\xa0\xa3\xf4\x07\x31\x24\x4c\x3c\x2a\xce\x8b\x6f\x22\xb9"
+  "\x28\xb2\x3c\x5e\x6d\x6f\x02\xee\xb1\x3e\xd5\x17\xaa\xed\x8d\xc7"
+  "\xbd\xd1\x5c\x80\x75\x2d\x12\x34\x19\x8b\x36\x47\xd6\xb7\x52\x7b"
+  "\xa9\xbe\x1d\x91\xaf\x1b\x03\xcf\x3d\x51\x99\xd4\x7e\x77\xe4\x01"
+  "\x2a\x8f\xf1\x1b\x33\xaa\x34\x7a\xaa\x74\xa2\x33\x21\xfa\x0e\x94"
+  "\x21\xf9\x20\xe4\x47\x19\x5a\xfe\x3e\xda\x8f\x25\x1f\x60\xe8\x53"
+  "\xe4\x83\x4c\x1c\xae\x9d\xa9\xea\x2e\x7a\x97\xbd\x95\x25\xf7\x33"
+  "\xe8\xdd\xce\x80\x77\xc9\xcf\xc7\x40\xef\xe3\x9b\xe1\xf2\x9b\xaf"
+  "\x43\xee\x3e\x3a\x4a\xfd\x6e\xe7\x60\x73\x29\x7f\x3c\xf8\xbb\x0a"
+  "\x17\x9d\xff\x21\x7e\x68\xb2\x33\xa6\x93\x39\x2b\x14\xac\xf9\x07"
+  "\x12\x12\xf2\xb9\xa3\x85\xbd\xfb\xc7\x3a\x4f\xeb\x10\xd7\xc3\x77"
+  "\xa5\x2c\xda\x53\xc8\x9c\x79\xb7\x08\x7b\xf5\xd3\xec\xbd\x53\x4e"
+  "\xb7\x38\x5b\x4b\xbf\x85\xcf\x67\xda\x6f\xa6\xb5\x81\x7c\xd8\x6b"
+  "\x32\xb6\x82\xbc\x3b\x29\x1d\x69\x74\xfe\x7f\x57\xc0\x33\xbe\xa5"
+  "\x3a\x51\xce\xa9\xf7\x76\x10\x6f\x21\xea\xeb\xbd\xdb\x41\x75\x56"
+  "\xec\xd5\x89\xd4\x86\x02\xc8\x7f\x14\xe7\x8f\xe6\x84\x39\x97\x74"
+  "\x85\xef\xad\xc4\xb8\xe3\xca\xe6\xea\xc4\xa1\xb5\xe1\x3d\xe1\x87"
+  "\xbd\xc0\xcb\x4f\xbb\x23\xab\x13\x89\x27\xd9\x94\x3f\x2c\x7c\x6a"
+  "\x05\x77\x74\x44\x1d\x00\x96\xbd\x57\xf1\x96\x4d\xf6\xcd\x10\xcb"
+  "\xad\xd0\xda\xbe\x53\x6d\x3b\xe8\x25\xf6\xa8\x6e\x2a\x97\xb1\x01"
+  "\x90\xe7\xc4\xa0\x3a\x2b\xf4\x33\xf1\x03\x58\x1b\xce\x4b\x5a\x1c"
+  "\x8b\xed\x5b\x1b\x86\x54\x8f\x63\xb1\xdf\xe2\x1b\xbd\xea\x37\x4a"
+  "\xfe\xc9\x6f\x94\x5c\xec\x1b\x72\xaf\xb9\x36\x7a\xe8\xb2\xe3\x31"
+  "\x97\x18\x2b\xf6\x03\xf1\x12\x33\x8f\x3f\xed\x83\xfc\xe6\x35\xd6"
+  "\x27\x10\x6f\x43\x76\xa5\x4e\x97\x97\x79\xed\xe5\xf1\xc7\x6d\x3d"
+  "\xcc\x91\xfb\x01\x6b\x66\xb5\x33\xe8\x9d\xe3\x39\x24\xb3\xd5\x17"
+  "\xf6\x6e\x39\x60\xef\xd5\x1f\x4b\x27\x7a\xef\xa0\x38\x0c\x01\xe3"
+  "\xac\xae\xf3\x03\xe6\x4c\x25\xfd\x6a\x3d\xe9\xb5\x0b\x31\xaf\x12"
+  "\x14\x60\x03\x78\x74\x9f\xa0\x07\xf8\x17\x29\x6f\x1d\x92\xf2\x96"
+  "\x5b\xf8\x27\xbd\x02\x7c\x6f\x04\x2f\x7a\x26\x9d\x74\xdf\xbe\xde"
+  "\x24\x73\x77\x11\x9b\x45\x31\x11\x48\xef\xcc\x8d\x73\xe2\x67\x7a"
+  "\x43\xb8\x90\xa7\xc0\xfb\x53\x6c\x04\x27\xb8\x61\x1f\xf8\xe8\x8a"
+  "\x73\x2c\xba\x02\xbc\x27\x30\xdb\x48\xb8\xbe\x4b\x8d\x8d\xb0\xf1"
+  "\x9c\x3f\x36\xc2\x4e\xd2\xf5\x34\xe0\xf7\x39\x16\xea\xdb\x7c\xc8"
+  "\xb2\xfd\x1c\x8b\xdd\x91\xcb\x2c\xdb\x49\x97\xf7\x95\xe4\x7d\x84"
+  "\x1d\x38\xc5\x49\x58\x6a\xa1\xbd\x04\x3f\xef\x43\x67\xc1\xfd\xb8"
+  "\x15\x2a\x74\x20\x43\xa2\xf7\x71\xb1\x0e\x7a\xed\xd5\x99\xa0\x71"
+  "\x6b\xef\x96\xd7\x8d\x2e\x56\xbb\x0e\xf4\x1b\x50\xe7\xa5\xd9\x93"
+  "\x94\x05\xc4\xb6\x78\x2b\x56\xe2\x3b\xca\x3a\x3a\xd8\x98\xf0\x6d"
+  "\x4f\x62\x37\xb5\xb3\x78\x79\x0e\xf1\x32\xac\x89\x75\x71\x64\xff"
+  "\x97\xbf\x98\x99\x7c\xdb\x93\x75\x05\xcf\xb3\x10\xa7\x37\x81\xd1"
+  "\x5f\xfe\x19\xde\x7a\x53\x16\x8b\xa7\xfd\x07\xda\x2b\x31\xaf\xa6"
+  "\xfc\xc7\x7d\xb1\x79\x2c\x3e\xb0\xec\xc5\x2b\xb3\x17\xde\x1c\xff"
+  "\xeb\x0c\xf3\xe3\x0b\xb3\x17\xaf\x48\xcb\xce\x60\x89\xd2\x6c\x42"
+  "\xb8\x7e\x5e\x49\x36\x13\x2b\x16\xe6\x64\x9a\x1f\x5b\x9e\x9d\x9d"
+  "\xb1\x24\xc7\x3c\x63\xea\xac\x0b\xfd\xff\x6d\x37\xed\x16\xfe\x5e"
+  "\x85\x0d\x9d\xf3\x24\xff\xdf\x3f\x3e\x57\x9a\xcb\x42\x0d\x6b\xef"
+  "\x9c\x6d\xf0\x26\x9a\x65\x7c\x24\x8c\x95\x2d\xc9\xb5\xbc\x20\xa9"
+  "\x5c\xf2\xa9\xf5\xea\x9e\x42\x72\xbd\x3c\x5b\x51\x2f\x75\x32\xdd"
+  "\x89\x31\x72\x4e\x39\x23\x43\x72\x18\xfd\x5e\x4c\xbf\x0d\x39\xac"
+  "\xc4\x31\x96\xf6\xc3\x9d\x91\x22\xdf\xf6\xe9\x3a\x2d\x9f\x96\x47"
+  "\x3e\xaf\x13\xb1\x13\x77\x0a\x5f\x98\x75\x93\x40\x9f\xa8\xee\x22"
+  "\xa7\xc5\x15\x3a\xc5\xae\xee\xaf\xb7\x4a\x7b\xbd\x7a\x46\xfe\xf0"
+  "\xf8\xff\xbe\xea\x9c\x5a\x4e\x2a\xbe\x77\x39\xf2\xce\x46\x1f\x34"
+  "\xaa\x76\x7d\xe3\x9a\xd4\x7a\x49\xbb\xd3\xba\x7b\xa5\x7d\x87\xd3"
+  "\x16\x70\x1e\x5b\x9c\xa9\xa7\xb5\x51\xe5\x49\xbb\xd5\xf2\x2a\x34"
+  "\x4c\x40\x7e\x8a\x7f\x53\x32\x74\x2c\x74\x4a\xf9\x27\xc8\xcf\x89"
+  "\x4a\xa7\xed\xa6\x17\x80\x0f\x31\x6d\xac\xce\xde\x7f\xbc\xf4\xf5"
+  "\xe0\x3d\x4b\x1e\x5b\xba\xd8\x9a\x96\xb3\x70\xc1\xc2\xac\x85\x39"
+  "\x2b\xc5\x31\xf0\x38\xf1\xef\xae\x09\xe9\xb3\xfb\xfb\x6e\x8e\x23"
+  "\x1d\x8b\xea\xf3\xb5\x93\x6c\x1a\xa4\x9e\xab\x7e\xab\xb7\x88\x8d"
+  "\x1b\x5a\xbd\xeb\x53\x85\x3e\x58\xf8\x1f\xa8\xdf\xed\xd2\xbb\x0f"
+  "\xaa\xfb\x1d\xed\x2a\xed\xc5\xf3\x0e\x63\x7d\xbd\x79\x2c\x9b\xdc"
+  "\xc4\x4e\x4c\xa3\x7d\x2e\xd0\xcf\x4c\xeb\x61\xe9\x2a\x5a\xb7\xd0"
+  "\x0b\xde\x5b\xd4\xf8\xac\xef\xbf\x46\x34\x20\x9e\x10\x34\xd8\xdd"
+  "\xc4\xde\x1f\x23\x68\xf0\x8d\x69\xb7\xf0\x3d\xf0\x8d\xe9\x05\x1a"
+  "\x5b\x54\x67\x85\x27\x6d\xe7\x3c\xe9\x39\xe5\x9b\xcc\xed\xfc\x9b"
+  "\xcc\xe7\xfc\x7e\xe3\xde\x5f\x87\x77\xf7\xe2\xdd\xf5\x14\x87\xa6"
+  "\xf4\x34\xdb\x4b\xfb\xdf\x74\x6f\xc8\x31\x32\x9f\xf1\x80\x89\xea"
+  "\xe3\x6c\x8d\x17\xfc\x76\x33\xf2\x3b\x3b\x6f\x61\xe0\x25\xcd\xe2"
+  "\x4c\xa3\xd8\xaf\x03\xbf\x87\xf7\x9c\xa8\x97\xb3\xb5\x87\x64\x62"
+  "\x93\x02\x9e\x0f\xed\xdd\x8f\xf5\x33\x95\xca\xa5\x36\x8b\x73\xc5"
+  "\xa3\xb9\xab\xbb\xe8\xfd\x4a\x17\xab\xb3\xaa\xbc\xa9\xb0\xb7\x20"
+  "\x1a\x04\xf7\xe7\xfb\xc2\xa7\x03\x68\x7c\x25\xb7\x4f\x4b\x94\x7d"
+  "\xfa\xbe\xf0\x75\x31\xbd\x99\x7f\xe3\x3f\xcf\xfe\xfe\xd7\xb8\xef"
+  "\xc5\x9f\xc2\xed\x77\x66\x06\xec\x2b\xe3\xd9\x07\xa3\x04\xef\x36"
+  "\x9a\xbb\xad\xab\x28\x6e\xf7\x07\xe3\xe5\xb8\xb9\xf3\xd7\xee\x82"
+  "\xcc\x10\xbc\xe3\xa3\xf3\x97\x92\x96\x1f\xfc\xd2\xb9\xee\xb4\x66"
+  "\xa7\x81\xef\x7f\xf0\xb9\xe3\x71\x2f\x13\x71\xa4\x9b\xbd\xc2\xee"
+  "\x4f\xf5\x31\xa0\x53\x8a\xea\xc9\xcf\x9e\x11\xb2\x1d\xed\x45\x0b"
+  "\x1f\xe9\xdd\x45\x1f\xe4\xf4\x9d\x13\x33\x4a\x7e\x8f\x78\x2e\x8a"
+  "\xb1\x45\x63\x9f\xf8\x37\xaa\x13\x8d\x7d\x94\x5d\x49\x7b\xd4\x72"
+  "\x0e\x7c\xb0\xf7\x9f\x9b\x03\x1f\x08\xfd\x2f\xca\x4a\xe0\xfa\x02"
+  "\x7e\xd3\x06\x96\x2a\x6c\x08\xbc\x9d\x74\x6e\x36\x14\xeb\x46\xac"
+  "\xc4\x93\x13\x57\x0b\x3b\x93\xdc\xf6\x4a\x3a\x9b\xba\xab\x87\x45"
+  "\x28\xf6\x39\x16\xe2\xb3\x8f\xe7\x09\xdb\x8b\x70\xbc\x57\x45\xb6"
+  "\x19\x64\x4b\x37\x52\xc4\x6d\xfb\x80\xed\xea\x62\xa1\xcd\xec\x6f"
+  "\x71\xb4\x17\xe4\xa7\xf5\xdf\xd6\xd2\xde\x1f\xdf\x32\xc5\x65\xc8"
+  "\xd3\x97\x50\x19\xca\xb9\xaf\x27\x69\xef\x51\x8c\x60\x7a\xaf\x89"
+  "\xfd\x2d\x43\xbc\x47\x79\xc9\xc7\x52\xbe\x31\x19\x7c\x56\x26\xe5"
+  "\xf7\xe2\x7e\xa7\x62\x9c\xc5\xb1\x1e\xf8\x72\xbd\x55\x78\x36\x5b"
+  "\xb1\xbf\x6e\x44\x5a\x92\xd8\x83\xe8\x35\xd1\xde\x24\xc6\x57\x99"
+  "\xd9\xe9\xfa\xd2\x21\xea\x43\x67\x69\x73\xb0\x76\x0a\xb9\xe4\x6f"
+  "\x07\x76\x7e\x25\xe2\xc9\xa1\x3f\x4f\x48\xdf\x99\xa7\xd9\x1e\x59"
+  "\xbf\x13\x33\x3a\xb6\xdc\x67\xee\xc0\xd8\xec\xd4\x87\xb3\xc3\x26"
+  "\xb2\x25\xaf\xaf\x3f\x6c\xea\x41\xff\x9c\x88\x06\xd6\xcd\x92\x3c"
+  "\xb1\x7c\x4f\x1b\x93\x21\x26\x63\x22\x9e\x4f\xd4\xec\x91\xb4\xf1"
+  "\xe8\x62\x7f\x8b\x20\xba\x61\x1c\x37\xd4\x65\x91\x6d\x99\x52\x8b"
+  "\x6f\x31\x5f\xae\xd2\x48\x7b\xe3\x64\xb7\x4f\xf2\xcc\x4c\x1b\xef"
+  "\x20\xf9\x8c\xce\x3a\xd1\x7e\x38\x9d\xe1\xde\x01\xf9\x96\xca\x46"
+  "\xb9\x1b\xb4\xb3\xdc\x1b\x91\x46\x65\xd3\x79\xa6\xd2\x45\x62\xae"
+  "\x91\x0d\x67\x84\xd8\x13\x08\x79\xe2\xab\xfb\x3b\x79\x07\x9d\x97"
+  "\xbf\xdf\x8a\xab\x5a\x0e\xf9\xd9\x41\x19\xf5\x5a\x19\x0a\xd9\xbf"
+  "\x66\x0b\x3b\x37\x97\x7c\x5f\xda\xff\xdc\xdf\xa9\x88\x73\x28\xf4"
+  "\xbe\xb4\xcb\xf9\x30\xb4\xcf\x86\x52\x9c\x0d\xf9\x30\x5a\xf3\xc3"
+  "\x83\xdf\xe6\xbe\xb3\x6d\xa0\x55\x87\xfd\x80\xa9\x13\x73\xbc\xd3"
+  "\x5e\x9d\x8a\x67\x93\x81\x30\xbb\x2f\xaa\xa3\xa0\xf3\xfb\xcb\x99"
+  "\x5e\x89\x9a\x33\x9b\x7c\x33\xd0\x99\x4f\x69\xb7\xfd\xe1\x0e\xd5"
+  "\x4f\x43\xc8\x69\xf6\xe1\x23\xfe\xbd\x71\x9f\xaa\xd7\xfd\xb0\x46"
+  "\xca\x15\x1f\xd6\x08\xbd\xee\x96\x03\xec\xff\xac\xf2\xe8\xab\x56"
+  "\xb9\xf4\xd2\x96\xf1\xc3\x6a\x17\x3b\xd9\xee\xb7\x65\xfc\xd0\x46"
+  "\x65\x0d\xcc\x07\x26\xab\x63\xf2\x23\x71\xbe\xd6\x2f\xa7\x7f\x24"
+  "\xd6\x39\xda\xc7\x56\x88\xa7\x8b\x2a\x4f\x20\xbb\x25\xa7\xf5\x2c"
+  "\xe9\x77\xc3\xa4\xce\xe0\x23\x35\x8e\xb0\xb0\x53\xfc\x41\x5b\xf0"
+  "\x7d\x14\xdd\x4b\x9a\x7d\x94\xa8\xed\x15\x95\xea\x15\x97\x41\xc7"
+  "\x78\x41\x25\x30\xcf\xda\x29\xfc\x03\x38\xc1\x23\x52\x6c\x6c\x6b"
+  "\x36\x9d\x05\xfc\x68\x0d\xf9\x0d\x90\x73\xee\x23\x71\x2e\x49\x29"
+  "\xba\x83\x17\x90\x9c\xe4\xa6\x58\x1d\x67\x19\xf2\x45\x22\xdf\x8b"
+  "\x35\x79\xed\x64\xf7\x15\x43\x71\x22\x9b\xd5\x6f\xbb\x23\x93\x2d"
+  "\x3f\x8c\x60\xa0\xff\x47\x07\x5d\xec\xc5\x69\x43\xc7\x83\x8f\x0e"
+  "\x5e\x8c\x67\x96\x3c\x5c\x02\x1b\x4c\xee\x26\xbd\xca\x8d\xf8\xfe"
+  "\x0c\x4e\xf5\xff\xcf\x17\xbd\x7a\x0f\xeb\xd5\x0f\xe7\x3f\x2e\xb4"
+  "\x31\x6f\xd1\x70\xee\x5b\x85\xfe\xea\x30\x41\x2e\xab\x65\x75\xd2"
+  "\x16\x86\xf6\xf3\x0d\xf9\x9d\xfc\xac\xd3\xbb\x9f\xf4\xfa\x6e\xf4"
+  "\x15\xf0\xe8\x3f\x9f\x77\x7a\xdf\x60\x64\x9f\x4c\x38\xd2\xc4\xfe"
+  "\x53\xf8\x63\xba\xd1\x5a\xc8\x6e\x38\x2d\x9e\x4f\x97\xfc\xdc\x7f"
+  "\xee\x51\xaf\x36\xf2\x8f\x19\x58\xa7\xbb\x96\x2f\x79\x8c\x9c\xac"
+  "\xde\x30\x3d\x23\x37\x23\xcb\xfc\x20\xb9\x60\xed\x67\x6b\x18\xee"
+  "\x8f\x2b\xd6\x90\x43\x6b\x24\xf1\xd4\x14\x5f\x4c\xc4\x16\x2b\x9a"
+  "\xc8\xfa\xe2\x8a\x11\x6f\xfd\x5f\x10\x5b\x4c\xe3\x99\x29\xae\x98"
+  "\x7f\x4f\xe6\xe3\x89\x7d\x73\x40\x79\xb3\x9b\xee\xc5\xba\x5c\xf4"
+  "\x9f\xfb\x69\x1e\xc9\x75\xa3\x61\x6f\xa0\x0f\x1b\xc9\x33\x95\x41"
+  "\x06\x68\xa8\xd1\xce\x6c\x62\x2c\x46\xe0\xfe\x84\xff\x8c\x48\x83"
+  "\x0b\x74\x33\xcb\xf9\x2b\xf2\xba\x35\xdb\x05\x35\x66\xb4\xb0\xb5"
+  "\x50\x8a\xaf\xdc\x2b\xf5\x85\x0d\x5d\x3b\x95\xe1\xe1\x72\xaf\xea"
+  "\xe3\x18\xed\x0c\x92\x9c\x9b\x6f\xaa\x73\xf3\xe3\x89\x17\xb3\x2f"
+  "\xf1\xcf\x8d\x8f\xad\xfe\x79\xfd\x99\xf6\xae\xf5\x52\xb6\x29\xaa"
+  "\xdc\x36\xaa\x8d\xfd\xfd\x69\xd2\x21\xca\x33\xc7\x7f\x17\x3e\x29"
+  "\xa5\x1f\x88\xbf\xdf\xa3\xfe\xc6\x37\xfe\x7e\xb3\xfa\xfb\x2a\xfc"
+  "\x1e\xa3\xfe\x1e\x8b\xdf\x3a\xf5\x37\xe6\xec\x27\x5f\xa9\xbf\xa3"
+  "\xf1\xfb\x7d\xf5\x37\xd6\x84\x4f\x0e\xa8\xbf\x47\xe3\xf7\xf3\xea"
+  "\xef\x31\xf8\xbd\x5e\xfd\x8d\x39\xf8\xc9\x93\x4c\xee\xf3\x87\xb7"
+  "\xb0\x4f\xe6\x0d\x5d\x8e\xfc\xc4\x22\xf7\x92\x3f\x81\xcc\x5d\x3f"
+  "\x49\xae\x29\x7d\x69\x79\xe8\x9b\x5a\x8d\xbe\x48\x37\xd3\x77\x90"
+  "\x5e\xe6\x62\x35\xbb\x03\xd2\x8d\x6a\x7e\xac\xff\x1f\x26\x06\xa4"
+  "\x87\xaa\xe9\x35\x90\x57\x8f\xfa\xd3\x3f\xf6\xa8\xe9\x8d\xc8\x5f"
+  "\x1f\x90\xde\xae\xa6\x03\x2f\x0f\x35\x04\xa4\xbb\x64\xfa\xdf\x23"
+  "\x34\xbb\x1a\x35\xfd\x84\x9a\x1e\xeb\x62\x7f\x2a\x09\x48\x3f\xaa"
+  "\xa6\x03\xff\x3f\x4e\x08\x48\x17\xb8\x22\x7d\x12\x1b\xf8\xe1\x3c"
+  "\x9a\x5b\x7f\x4f\x75\xb1\x83\xb6\x80\x3c\x55\xea\xbb\x36\x17\xfb"
+  "\x4b\x65\x40\xfa\x6e\x35\xdd\xee\xd2\x8d\x88\x0e\x48\x2f\x1f\x0c"
+  "\xab\x74\xe5\x2c\x75\x30\x5d\x3b\xc9\x25\xc2\xbe\x58\xf0\xca\x8d"
+  "\xc7\xe9\x4c\x93\x61\x07\x6f\x32\xe7\x73\xde\xc4\x1a\xf7\xab\xf6"
+  "\xb4\x26\xb2\x6d\xa4\xf3\x61\xcd\xac\x71\x87\xea\x5b\xc0\x2d\xce"
+  "\x8c\xad\xa2\x33\x63\x8d\x82\x07\xbc\xc9\x56\x28\xfd\xe5\x6a\xb1"
+  "\x17\x48\xe7\xa4\xee\xc7\x23\xcf\x3d\xa4\x83\xa7\x72\x48\x2f\xed"
+  "\xcc\xe9\x91\xbe\x94\x21\x9b\x52\x1a\xe9\x5e\x88\x1e\x81\x3a\x26"
+  "\x89\xfb\x8d\xc7\x95\x1e\x3a\x97\x29\xf5\x53\x34\x17\x29\x3f\xd9"
+  "\x90\x05\xe6\x75\xb1\x46\xe1\xb3\x3a\xc4\x14\xf9\x6c\x77\x51\xe3"
+  "\x5e\xff\x79\x98\xc6\x50\x35\xbd\x1c\xe9\x35\xfe\xf4\xbf\xbb\x07"
+  "\xc7\x76\xe0\x9d\x71\xaa\xa5\xf7\x1c\xef\xf4\x9e\xe3\x9e\xd2\x4f"
+  "\xa5\x2d\x39\xb0\xee\x1a\x9f\x7d\xea\x24\x3a\x2f\x42\x31\x19\xbd"
+  "\xb9\x9c\xf6\x33\x29\x76\xe5\xe5\xf7\x77\xba\xc1\x63\x74\xf3\x8d"
+  "\x0b\xc8\x26\xb5\x8b\xd1\x7e\x69\x41\x3b\xc5\xcb\x32\x70\x3a\x87"
+  "\xbc\xe6\x6b\x16\x41\xe7\x49\xc8\xe6\x9c\xf6\x32\x67\x64\xba\xd9"
+  "\xf1\x4c\x1f\xdb\x89\xb2\x77\x2c\xd0\xf8\x8b\x93\xe9\xfe\xb3\xae"
+  "\x53\x68\x7f\xf9\x9a\x02\x11\x7b\xf6\xa4\xf0\xd5\x6b\x58\x4b\xfb"
+  "\xfc\xf5\x1e\xfe\x36\xf1\xbc\xd5\xb3\x0c\x6b\x19\x78\x8e\x93\x95"
+  "\xf8\x9d\x20\xff\xf0\x0c\xe9\x83\xb5\x49\xce\xe5\x93\xd2\xdf\x9a"
+  "\x7d\xea\x1e\x89\x17\x27\x1b\xf9\xbf\xd3\xf9\x89\x93\x2e\xbc\xeb"
+  "\x71\x47\x56\x0f\x78\xae\x64\xcd\x0e\xa6\xef\xdd\x02\xde\xe4\x74"
+  "\xb5\x5e\xe2\xd3\xa7\xb5\x8a\x3e\x7c\x2d\xe9\xbf\x45\xfc\xc9\x2d"
+  "\x73\xd2\xf7\x2e\xf1\xe8\x8f\xaf\x6a\x66\xab\xc7\x30\x53\xb2\x47"
+  "\x4f\x79\x66\x8c\xcc\x21\x9f\xbe\x07\xc8\xcf\x81\xfe\x0f\x78\x7e"
+  "\x68\x49\xb5\xde\x2b\xf8\x95\x4f\x6b\x85\xce\xd4\x3e\x67\x12\xad"
+  "\x21\xce\x06\x1f\xf1\xd8\x11\xe0\xb1\xc9\xa7\x73\xb8\x6f\x45\x66"
+  "\x94\x77\x59\xe6\xe5\x3b\xb2\x59\x84\x6f\x99\x25\xfa\x99\x73\x6c"
+  "\x92\xb6\xfe\xec\xc8\xc5\x9a\xd2\x6d\x1a\xb1\x09\x6b\x0a\xe9\x62"
+  "\x46\xea\x8c\x62\x6f\x98\x7e\x2b\xfa\xb7\x9a\x77\xe6\x5e\x3c\x86"
+  "\xae\x6f\x85\x45\xf8\x4b\xa0\xba\x0c\xd4\xd6\x0d\xcf\xb1\x50\x9f"
+  "\x7a\xae\x32\xff\x14\x1b\x0d\xbe\x58\x3f\xb2\x8b\x3b\xda\xb2\x98"
+  "\x9e\xe2\x8f\xe6\x67\x08\x7d\xe7\xb0\xe3\x99\x5e\xe6\xb4\x7d\xc2"
+  "\xf2\xb3\xa9\x8f\x3e\x1b\x4f\x7c\x1a\xd9\x18\x23\xbf\xb1\x8d\x7d"
+  "\x76\xb3\xc1\x83\x35\xc3\x03\x5e\x7b\x11\xc9\xb6\x9f\xdd\x29\xfd"
+  "\x33\x7c\x56\x42\xe7\x20\x1d\xd9\x53\x28\x2d\xad\xe0\x94\xb0\xe5"
+  "\x89\x91\x67\x2f\x3f\x9b\x4c\xf7\x05\x74\xce\x33\xea\xd1\xe9\xaf"
+  "\xf4\x78\x86\x49\x9d\xda\x67\xb7\xcb\x3e\xab\x76\x4b\x99\xed\xb3"
+  "\x0b\xce\xa8\xf5\xe9\xfa\xed\x77\x27\x72\x8a\x65\x56\x41\xfc\x2b"
+  "\x77\x89\x7d\x77\x3a\xf3\x6e\xbb\xc3\xc1\xcf\xd9\x55\x1f\x3a\x2e"
+  "\x9d\xb2\xf9\xee\x44\xe9\xe7\xee\xb3\xf3\x4c\xda\xcc\x61\x8d\xbc"
+  "\x3b\x49\xee\x39\xdc\x9d\x29\x75\xf0\x77\xdb\x9e\x1a\x4b\x36\xfe"
+  "\x2e\xd6\x11\x79\x77\x09\xea\x7e\xa2\x23\x2a\x35\x71\xf0\xf5\x68"
+  "\x9a\xcd\x7c\x0d\x8b\xa6\xbd\x9f\x14\x9f\xf4\xf3\x28\xe7\xf0\xe7"
+  "\x28\x5b\x3c\x1b\xd7\x64\x65\x21\x52\x36\x74\x3d\x70\x53\x05\x33"
+  "\xa3\xae\x57\x70\xe3\xdd\x16\x61\x8b\x68\xbf\x7b\x92\xb3\x9d\xe2"
+  "\xb4\xf8\x98\xdc\xa3\xfb\xdc\xc8\x23\xef\xb6\xa8\xf9\x9f\xaf\x6b"
+  "\x47\x1b\x8c\x77\x79\x9c\x9e\xaf\x55\x9e\xd0\x85\xb1\x7f\x97\x87"
+  "\xdb\xef\x0e\x97\xe7\xa5\x5d\x67\x34\x5c\x95\x63\xd4\x75\x4a\xd2"
+  "\x6d\x9a\x4d\xd2\xed\x73\xa3\xba\x5e\x8d\xa3\xdf\x58\xbb\xe3\xa5"
+  "\x4d\x89\xab\x51\xe3\x91\x5d\x6a\x1e\x7a\x07\xed\x76\x48\xac\x75"
+  "\x21\xfd\xb3\x32\xf9\xdc\x55\x49\x69\x68\x1f\xd6\x2c\xd7\x24\x6a"
+  "\xd7\x60\xd8\x2a\x68\x91\xc7\x42\xd0\x3e\x13\xd9\x5f\x13\x9f\xe2"
+  "\xec\xbc\xc3\xe1\x14\x7d\xd0\xf4\x2c\xd9\xdb\xd3\x77\xc8\x27\x0e"
+  "\xe1\x26\xca\x14\x74\xf2\xd7\xff\xf3\x35\x5a\x5d\xe8\x7b\xf4\x8c"
+  "\xdb\xef\xf2\x08\x79\x19\x6d\xa6\x3c\xd4\xaf\x2d\x56\xd2\xc5\x75"
+  "\x81\x66\x64\xd7\xd6\xb4\x87\x68\x22\x69\xd6\xb4\x4e\x95\xd5\xd5"
+  "\x7e\x68\x5a\x19\x4c\x0f\x79\xaf\x18\x81\x0d\xd9\x64\xdf\xd4\xb4"
+  "\x47\xa5\x9f\x1a\x63\xa0\x49\xf8\x56\x50\x9f\x5d\x11\xf0\xee\xd5"
+  "\x7d\x79\x51\x6f\xe2\x8d\xc8\x56\x80\xf6\x8e\xe4\x78\x6d\x9a\x14"
+  "\xf0\xde\xa4\x94\x33\xc4\x23\x4f\xf1\x3c\xb5\x4d\xc4\x6c\x8b\xef"
+  "\x2e\x6a\x9a\xee\xa7\xb7\x2c\x67\x80\x6f\x5c\xa3\x7d\x03\x79\x22"
+  "\xb4\x7a\xa2\x7f\xd4\x35\xb8\xc9\xee\xef\x93\xcf\xab\xb4\xf7\x48"
+  "\x2f\x83\xfb\x64\x8a\x7f\x38\x88\x5f\x78\x9d\x33\x06\x18\xec\xbd"
+  "\xc3\x21\xc6\x23\xfb\x22\x9c\x6c\xc7\x31\x86\x4c\x72\x0c\x35\xa9"
+  "\x7a\xa3\x2f\xc2\xa9\x4c\xda\xff\x93\x71\x42\xbe\xc0\x2c\xf8\x3c"
+  "\x46\x7e\xef\x8b\x68\x59\x87\x2f\x20\xff\xb9\x22\xfa\xcb\x75\x53"
+  "\xd2\xd2\xcd\xb3\x6e\x16\x67\x46\x6f\x58\x6e\xa5\xe3\xa0\xe9\xfe"
+  "\x9b\x60\x9e\xdb\xe8\xf7\xad\xf5\x45\x6a\x9f\x6f\x2d\x7b\xf2\x74"
+  "\x49\xff\x2f\xf6\xf2\x73\xbc\x8c\xce\x73\xf0\x5c\x5e\x5e\x8a\x3e"
+  "\x2c\xe8\x62\x57\x52\x1c\xda\x7c\x2b\xff\x92\xfc\xae\x01\x2f\xd7"
+  "\x01\x3f\x4a\xf2\xbb\xd8\x70\xb2\x15\x22\xfc\x21\x7d\x16\x8f\x44"
+  "\xfa\xe6\x39\x25\xfe\x73\x64\x2d\x64\xc3\x95\xc7\x0b\x92\x28\x7e"
+  "\x78\x05\x8d\x07\xb2\x1b\x6f\x61\x2d\x49\xc8\x57\x81\x67\x39\x1b"
+  "\x85\x8e\x60\x8e\xcb\x67\x4c\x8e\x2d\xf8\x9a\x85\x89\x18\x5f\x36"
+  "\x0f\x33\x2f\xa2\xf3\x46\xcd\x57\xa0\x4c\x17\xd2\x47\x8a\x74\x8f"
+  "\x87\x7c\x05\xb8\xf0\x6c\x24\x9e\xdd\x83\xab\x82\x32\x6c\xa5\xa8"
+  "\x77\xfe\xd7\xec\x1a\xd4\xa5\x15\xdf\x71\xa1\x9e\x2d\x05\x8b\xd9"
+  "\xe8\x3a\x6b\x2b\xc9\x77\x28\xcf\xc5\x54\x7f\x1a\x2e\xbc\xb7\x03"
+  "\xed\xb2\x91\xae\x03\xd7\xbc\x8d\xb8\xe6\xfb\xd8\xc8\xfc\x35\x58"
+  "\xf7\xd6\xe0\xfb\x74\x2e\x13\xe5\x90\x0f\x0d\x59\x17\xb4\x8d\x74"
+  "\x63\x28\x77\x4d\x3b\x6f\x41\xd9\xad\xc7\xdb\x51\x9e\xad\xa1\xaf"
+  "\x4c\x95\xa7\xc6\xfc\x6e\x79\x80\x6f\x49\x4d\x45\x9d\xca\xc9\x9e"
+  "\x1a\x69\xc0\xe4\x96\xe9\x7e\x7e\xb8\x65\x86\xfa\xfb\xb2\xbe\xbc"
+  "\x05\x49\x2c\xff\x3c\x33\x09\x9b\x80\x15\x21\xc0\xe3\x53\x8d\xe4"
+  "\xab\xc9\xef\xbb\xf3\xd4\x87\xc8\x97\x89\x32\x37\xa8\x65\x52\x5a"
+  "\xbd\x9f\x7f\x3e\xa5\xf1\xcc\x23\xfa\xf2\x5e\x50\x66\xcb\x4a\x2a"
+  "\x53\xfa\x55\xfa\xc2\x2c\xcf\x24\x9f\x4a\xee\xf3\x89\x70\x8e\x57"
+  "\xd1\x99\x3b\x25\x97\xef\x27\x9d\x04\xe9\x42\x48\x7e\xa1\x73\x77"
+  "\x29\x2b\x4b\x0a\x85\x3e\x62\xb4\xd4\x99\x4a\x9e\xe1\x54\x79\xdf"
+  "\x19\x81\x6d\x22\x1e\x81\x3c\x53\x47\xe7\xf4\xb2\x85\x3e\xa5\x7b"
+  "\xe6\xca\x15\x05\xf4\x3e\xbd\x8b\xfc\x47\xfd\x67\x99\x5a\x6c\x52"
+  "\x77\x97\x9a\x49\xbf\xdd\x5a\xbd\x8a\xbe\x88\x97\xba\xe7\x53\x9d"
+  "\x7d\xfa\xb7\x5c\x5e\x43\xfd\x24\xce\x18\x92\x0d\xa0\x8f\x95\xa4"
+  "\x78\x4b\xb4\xb3\xc2\xed\xdd\x45\x2d\xe6\x80\xb3\xc2\xed\xa2\x0e"
+  "\x3d\xe2\x3c\xfe\x8a\x99\xde\x15\x5c\x9e\x21\x6d\x99\xe6\xff\x76"
+  "\xb3\x5b\xfd\x76\x2a\xfd\x76\x4b\x9f\x58\x64\x1b\x68\x96\x76\x1d"
+  "\x2d\x56\xcd\x96\x02\xf3\xad\x81\xc6\xe7\xc0\xbe\xfb\x5b\xca\x83"
+  "\xfd\xf3\x7c\x99\x49\xbe\xc3\x91\x1e\x70\xfe\xb7\xe5\x92\xe7\x7f"
+  "\x0b\xdc\xfc\x73\x1a\x43\x56\x11\x87\xf6\x4b\x60\x6d\x72\xac\xf4"
+  "\x7f\xff\xa5\xd0\xb9\x34\xb1\x2f\x49\x37\x62\x90\xfb\x0e\x5f\x8e"
+  "\x51\xf1\xa6\x7c\xa6\xcf\x6b\x70\xe1\x9b\xc2\xdf\x8f\xff\xde\x48"
+  "\xfe\x0b\x90\xef\x1e\xe9\x37\xf8\xcb\xf0\x7e\xf9\xe9\x79\x61\xbf"
+  "\xfb\x84\x7e\xf7\xe6\x4e\xcc\xc3\xc1\x6c\x46\x36\x8e\x15\xfa\xc8"
+  "\x49\x23\xd7\x32\x6b\xc1\x57\x2c\x04\xf3\xe3\x14\xd5\xad\xae\x55"
+  "\x9c\x27\x33\xf0\xa2\x78\xe6\x6c\xf5\x4a\x5e\x14\x3c\x40\x53\x2c"
+  "\xf2\x7c\xc5\x46\xd3\x79\x06\x8a\x0f\x80\xfc\x6d\x32\x26\x40\xeb"
+  "\x99\xe4\xe5\x23\x98\xf2\xeb\xa4\xcb\xb9\x7e\x41\x35\xed\x59\xef"
+  "\xeb\x71\x91\x5f\x7d\x5d\xfe\xb3\x2c\x86\xe6\x1e\xe6\x60\x33\xd7"
+  "\x3f\x56\x8d\x77\xda\xff\x4f\x4f\xeb\x30\xa7\xf7\x13\x66\x05\x26"
+  "\xb4\xb1\xd6\xe6\xd0\x3c\x16\xba\xa9\x85\x19\x31\xce\xbc\x87\xbd"
+  "\x93\x98\x76\xfe\xbe\x22\x4a\x9e\xeb\xae\xc0\x98\x5c\x66\xe2\x9e"
+  "\xee\xa2\xd6\x04\xc8\x6a\xb3\x35\x99\x7c\x83\xf4\xbf\x15\x8a\xef"
+  "\xef\x13\xbe\x02\xe4\x9a\x07\xda\xb6\xae\x91\xe7\x19\xa3\xaf\xc4"
+  "\x3b\x39\x7e\x7e\xfd\x2b\xa6\xee\xe1\xa8\xfb\xce\x5f\xb1\xc3\xe9"
+  "\x4c\xc4\x34\xea\x10\xfe\xd1\x5b\x2b\xfb\x6c\x6f\x84\x9e\xeb\x2b"
+  "\xe0\x41\x72\xa2\xe4\xe5\x93\x13\x53\x7c\xe1\x2a\xcf\xf0\x95\x58"
+  "\x8b\xe8\x5d\xbc\x67\x90\xb1\xcb\x5a\x1b\xfd\x63\xad\x75\x37\xad"
+  "\x11\x68\x13\x64\xbc\x56\x13\xb5\x8b\x68\xd2\x29\x7c\x6d\xb5\xc6"
+  "\x1c\xde\x3d\x48\x6c\x0b\xe3\xd4\x3d\x5e\xa1\x33\xa9\xf6\x60\x3c"
+  "\x7d\x8d\x3e\xf8\x01\xf9\x1b\x72\xe2\x3b\xc7\x77\xf6\xb0\xe3\xa6"
+  "\x0e\x56\x87\xdf\x64\x63\xef\x58\xf4\x05\x6b\x36\x0f\xbc\x3e\x29"
+  "\x90\x3b\xc0\x9b\x4f\xa2\xb2\x08\xdf\xc8\x2e\xd1\x99\xc7\xc4\x4e"
+  "\x93\xb3\x99\x89\x32\x8e\x2b\xad\xec\xb8\x8d\xe4\xb2\x7a\x4f\xdd"
+  "\xce\x4f\x58\x9d\xe9\x6f\xe2\x3b\xc4\x43\x3a\xb2\x3b\x2e\x56\x36"
+  "\xe8\x31\x35\x49\x2d\xbb\x1d\x65\x47\x0f\x5e\x76\xf5\xac\x21\x96"
+  "\x3d\x84\x7a\x57\x27\x0c\xa5\xec\x82\x72\xee\xc3\x9a\x70\x05\x70"
+  "\xdf\x42\xbe\x2e\xe9\x2c\xa5\xef\x1c\xf9\x09\x19\xc7\xa5\xad\x77"
+  "\xdb\xc7\x84\x37\xc2\x0e\x61\xf3\x9c\x58\x71\xce\x92\x74\xc7\xea"
+  "\xf9\x4a\xa7\xf7\x14\x23\x5d\x72\x77\x51\x5b\x8d\x5f\xbe\xea\xdb"
+  "\x83\x05\x7f\xdb\xd6\x2a\x6d\x7a\xe7\xc4\xca\xb1\xd5\x26\x6c\x1a"
+  "\x06\x96\xa3\x1e\x9e\x2c\x6d\xc3\xff\x31\x5e\xd3\xd9\x74\x44\x3e"
+  "\x3c\x59\x2d\xcb\xdc\x5f\x17\xa8\x3a\x77\x31\x67\xd8\x72\xcc\x2b"
+  "\xb2\x17\xe6\x64\x68\x07\x81\x47\xb0\x07\x33\x1e\xcb\x58\x98\x9b"
+  "\x91\x6e\x9e\xbd\x3c\x7b\xc9\x0d\x4b\x1f\x7f\xdc\x3c\x23\x63\xd9"
+  "\xb2\xb4\x5f\x67\x8c\x60\xb3\xb3\xd3\x96\x2c\x5b\x48\xfa\x3a\xb3"
+  "\x79\xda\xad\x29\x99\x4b\x73\x6e\xf8\xc5\xb4\xf8\x7e\xfa\x3a\x3a"
+  "\x17\xdc\x48\x7c\x3b\xd6\xca\xd1\x58\x37\x23\xc9\x57\x8c\x61\x25"
+  "\x77\xac\x86\xcc\x88\x31\xd8\x46\x6b\x0e\xe6\xee\xe7\x24\x4f\x90"
+  "\xaf\x58\xf2\x3f\xbb\x7d\x1b\xaf\x6f\x61\xbe\x8f\xc1\x8b\x36\x20"
+  "\x8d\x7c\xbd\x36\x42\x8e\x77\x53\x1f\x20\xfd\x8f\xc8\x53\xf3\x5b"
+  "\xa4\xb9\x23\x93\x13\x37\x7d\xca\x42\xe5\xba\xd9\x3e\x91\xeb\x87"
+  "\xf3\x0d\xe4\xb7\xf5\x0b\x13\x53\xfd\x41\xeb\x9d\x2e\x0f\xd9\xaa"
+  "\x84\xcf\xf4\x16\x70\xc2\x54\x39\xbf\xda\x65\x8c\x14\xc8\x21\xd2"
+  "\x66\xde\xb7\x95\xe4\x9e\xa7\x44\x2c\xad\x76\xe0\xff\xa7\x0d\x7e"
+  "\xac\xee\xca\x53\xf9\xcd\x06\xd0\x7d\x45\x13\xee\xa5\xff\x8b\xf6"
+  "\x7e\xfe\x2f\x4e\xcf\x62\xec\x7c\xb5\xfc\xa3\x77\xce\xd7\xc8\x3f"
+  "\xfa\x1d\xf8\xe7\xb3\xc9\xbf\xfe\xe9\xff\xea\x9f\xf6\xfd\x7f\xf6"
+  "\xfd\x73\x13\x2f\xfe\xf7\x6d\xbe\x2f\xda\xfd\x3d\xb6\xff\x5f\x79"
+  "\xff\xdc\xe4\x8b\xfd\xd1\x78\xc3\xd8\x6a\xfc\xed\xa7\x2c\x1c\xe3"
+  "\xb3\x6c\xe3\x02\x8c\xe9\x93\xcc\x94\xe7\xe5\xcd\x05\xf3\x58\x4c"
+  "\xfe\x57\x4c\x4f\xfc\x5f\x8e\x8d\x37\xe7\x9f\x23\x59\xfb\xdc\x15"
+  "\x18\xbf\xd5\xa5\x4d\x2c\x62\x63\x13\x33\xd6\xe5\xc8\x18\x0c\xb4"
+  "\x87\x42\xe7\x89\x9c\xb8\xaf\xcd\xf5\xb0\x63\xee\x33\x64\xbb\xe7"
+  "\xa8\x4b\x05\xf6\x34\x32\x46\xe3\x37\x22\x95\x45\x57\x8c\xe6\x07"
+  "\x79\xd1\x33\xb3\xb9\xfe\x99\x69\x48\x3b\xf1\xaa\x92\x30\xec\xd5"
+  "\x55\x47\x87\x99\x17\xd0\x3a\x7f\xba\x4b\x1d\x9b\x6b\xe4\x79\xb9"
+  "\x2e\x21\x83\xa9\xfe\x7a\xb1\x3e\x75\x9d\x97\x6b\x7a\xd7\xbb\xaa"
+  "\x8e\x8a\x7e\x0b\x9d\x2b\xda\x51\xcd\x8b\x16\x54\x53\x99\xaf\x28"
+  "\xd5\xc3\x68\xcd\x7c\x75\x55\xc2\xb0\xbc\x34\xa6\xaf\x73\xb5\xb1"
+  "\xc3\xc0\x42\xda\xb7\xc5\xbc\xdb\x8b\x79\x56\xb5\x63\x34\xb7\xa3"
+  "\x7e\x1b\xc0\xcf\x95\xa0\x4e\x7b\xba\x8b\xbe\x49\xc7\xba\x35\x5b"
+  "\xe5\xe5\x1c\x98\x17\x7b\x37\x22\xcf\xcc\xe5\x6c\xdc\x46\xe4\x03"
+  "\x6f\x57\x42\x7c\xb7\xac\x5f\xc7\x3c\xd0\x60\x3f\xbe\x59\x6f\x9e"
+  "\x4f\xf7\x67\x04\x8f\x41\xdf\x46\x3b\xcc\x4d\xcc\x2d\xfc\xe1\xd0"
+  "\x37\xb4\xef\xa2\x7c\xe0\x5f\x5b\x84\xba\x6f\x66\x97\xe5\x7c\x23"
+  "\xf9\x30\xfb\x9c\xbd\x14\x17\x4e\x3d\x8f\xb4\x77\xe3\x2a\xac\xeb"
+  "\x3d\x2c\x1c\xdf\x28\xc3\x37\x1c\x86\xb5\x8c\x1b\xe8\x2c\x6b\xa3"
+  "\x17\xbc\xba\xa2\xda\x89\xba\x3f\x54\xdf\x15\x7c\x88\xe0\x3d\x7c"
+  "\xcc\x20\x75\x0e\xe0\x3f\x32\x81\x13\xe0\x39\xc4\x39\x00\xf0\x1b"
+  "\x94\x8e\x6f\x94\xa1\x5d\xf5\x90\x05\xf7\x63\xed\xae\x22\x5e\x61"
+  "\x7e\xd7\xbd\x4c\xc4\xc4\x06\xbf\xb0\xcc\xc6\x3d\x32\x46\x96\xdb"
+  "\xaa\xf1\x0b\x34\x3e\x88\x47\xd8\x38\x9f\x85\xf6\xa2\x8f\x31\x46"
+  "\x8e\x82\xff\x00\xef\xed\xde\xab\xf6\xcd\x51\xc1\x17\xa8\xb1\x41"
+  "\x25\x86\xbb\x0f\x60\x7d\x8f\xc0\x37\xc0\xef\xfa\x34\x5f\x4a\xc0"
+  "\x20\xf7\x51\x6d\xad\x97\xf1\xad\xdd\x7b\x39\xb0\x0e\x74\xdb\x1f"
+  "\x97\xaa\x83\x8c\xe7\x36\xa2\x2f\xf6\x53\x5e\xf2\xf5\x80\xfc\x90"
+  "\x39\xbf\xb4\xa9\x7d\xd2\xb8\x31\x97\xf8\x00\x77\x21\xd5\x03\xef"
+  "\xd4\x82\xd6\xd4\x17\x6a\xdc\x40\xd0\x5e\xf0\x30\x1d\x63\x34\xda"
+  "\xa3\xaf\xd7\xf9\xe9\x7f\x66\x5a\x20\xfd\x41\x8b\x75\xb2\x0f\xce"
+  "\x1e\x09\xe8\x3b\xc8\x5a\x67\x2b\x48\xb7\x8a\xef\x1d\x94\x7a\xa1"
+  "\x33\x6b\xc8\x1f\x17\xc6\xcc\x41\xd0\xe2\x20\xf2\x55\x13\x36\x3f"
+  "\xf5\x29\x30\x77\x01\xf1\x50\x67\x9f\x96\x3c\xea\xd9\x58\x1a\xc3"
+  "\xb8\x17\x72\x74\x33\x73\xaf\xa3\xf2\x30\x36\xba\x70\x05\x2f\x7b"
+  "\xe6\xeb\x82\x0a\x8a\x59\x39\xc7\x43\xfe\xb2\xd4\xbe\x06\x6f\x76"
+  "\xa6\xcf\xff\x11\x8d\x01\xea\x7b\xb4\x71\x9d\x94\xbd\xcf\x34\x92"
+  "\xfe\x4c\xbc\xd7\x9b\x49\x75\x6c\xa4\xf9\xa9\x3d\x47\x7a\x2b\xf9"
+  "\x31\x0d\xa0\xcd\x3a\xb5\x4f\xaa\x65\xfc\xb7\xb3\x6b\xd4\xba\x25"
+  "\xe1\x3e\x1c\x75\x10\x3a\x95\x8e\xde\xcc\x90\x4d\xf4\x4e\xbe\xff"
+  "\x1d\x9a\x3f\x18\xcb\x06\xbc\xb3\x1c\x57\xae\xe5\x25\x1f\xe4\xa8"
+  "\x87\xf7\x19\xe1\x4f\xea\x6c\x74\x47\xaf\x45\x8f\xef\x7a\xf0\x5d"
+  "\x3d\x8d\x0d\x1a\x17\x5a\x19\x9b\x24\x8d\xf6\xa2\xff\xc4\xf8\x3a"
+  "\xec\xad\x06\xdd\xcf\x82\xff\xff\xbb\x43\xf2\x77\x67\xbc\x6a\xfd"
+  "\x1c\x32\x2e\xc1\x3f\xe2\x76\x4a\xdf\x2f\x94\xaf\x2f\xfe\x8d\x9f"
+  "\xcf\x3c\x23\xfc\x44\xa1\xac\x5a\x75\x4c\x18\xba\x8b\x3a\x22\xfa"
+  "\xc6\x90\x38\x57\x7f\x76\x03\xf1\x9a\x6a\xfd\x69\xec\x3d\xad\xd2"
+  "\x2e\x8e\xc6\x00\xf8\xf8\x44\xd9\xcf\xee\x75\xc4\xab\xca\x71\xd8"
+  "\x31\x4b\x2b\x43\x9e\xcd\x3f\xd3\xa8\xa0\x0c\x6d\xac\x04\x62\x03"
+  "\xf2\xe6\x01\x17\xfa\xc6\x8d\x86\x05\xb2\xcc\xce\x3f\xaa\xba\x41"
+  "\x0f\xfa\x86\x7c\x5f\x3b\x84\x6f\x22\x31\x2e\x3b\x4b\x0e\x77\x7a"
+  "\xd9\x6f\x69\x5c\xce\x27\x4c\xe8\x38\xd5\x11\x95\x6a\xf5\x8f\xed"
+  "\x8e\x13\xda\xd8\x0e\xe8\x57\x31\xb6\xd7\x09\x3c\xea\x00\x1f\x7d"
+  "\x93\xb6\x77\xdc\x48\xf3\x5c\xc1\xbc\xde\x94\x2b\x74\xde\x06\xd2"
+  "\x71\x89\x79\xef\x69\x17\x32\x06\xf5\x67\x9d\xad\x59\xf8\x1b\x7f"
+  "\x4a\x61\xe1\x75\x9d\xa7\x48\xe6\x6f\xa3\xf9\xaf\xcd\x71\xea\x1b"
+  "\x7c\xcb\x41\x3e\xe1\xd7\x01\x03\x69\x0e\x76\xa2\x4e\x14\x07\x9d"
+  "\xfc\x74\xd5\x24\x27\xb0\x65\xe8\xdb\xc3\xa9\xd4\x6f\x9d\x39\x9a"
+  "\x6d\xff\x26\x89\x01\x11\xea\x78\x11\x75\xec\x47\x57\x83\xa4\x6b"
+  "\xe7\x9e\xe0\xf9\x7d\x36\x91\xe6\x77\x20\x5d\x89\xa6\x44\x5b\xe4"
+  "\x45\xfb\xbf\xaa\xd2\xe8\xea\xa7\x69\xd7\x9d\xea\x78\x54\xb1\xb5"
+  "\x6b\x40\x6c\xdd\x24\xfd\xef\x57\x3f\x45\x6d\xc1\x9a\x42\xdf\x17"
+  "\xf1\x65\x54\xd9\xa7\xc6\x4d\x63\xaa\x6b\x92\x8b\xa5\x27\x6a\x38"
+  "\x86\xfa\xd8\x69\x3c\x51\x5f\x69\xd8\x41\xfa\x1f\x59\xf7\xae\x74"
+  "\xad\x3f\xa8\xde\x81\x98\x80\x3a\xbc\x46\xf7\xfe\x36\x77\x6d\xc5"
+  "\x7b\x51\x84\x6d\x7e\xfe\xaa\x6b\x77\x70\xdb\xbb\x36\x50\xdb\x69"
+  "\x4c\x58\x73\x49\x07\x24\xd7\x32\x17\xfb\xc6\x14\x8c\x57\xdf\x5c"
+  "\x21\x6d\x0d\x24\x3f\x46\x78\x6f\x9d\x2f\xf3\xd3\xfa\x86\xfc\x42"
+  "\x27\xaa\xae\x87\x79\xb4\xfe\x21\x2d\x54\xa5\x41\x23\xf2\xd7\xd0"
+  "\x79\x61\xf2\x19\x73\x79\xa3\x94\x05\x81\xd1\x07\x29\x0e\x81\x8b"
+  "\x9d\xae\xa9\x43\xa9\xde\x30\xc6\x2a\x54\x7e\x93\x70\x82\xaf\x48"
+  "\xba\x7c\x45\x2b\xbb\xcc\xfa\x0b\xfe\x05\xd6\xf3\xb7\x30\x8f\x3c"
+  "\xe4\xc3\x10\x65\x9b\x5b\xd8\xf9\xe7\xf1\xdd\x68\xf5\x6a\xc2\x75"
+  "\x3d\xae\x63\x70\x7d\x12\xd7\xab\x70\x7d\x04\xf9\x15\x35\x7f\x3c"
+  "\xee\x7f\x89\xf4\x5b\xd5\x2b\xea\x78\xae\x1a\xd7\x59\xbf\x25\xbe"
+  "\x72\xbe\x48\x1f\x45\xf7\xb8\x0e\x53\xdb\x5d\x2b\xe7\xf6\xb9\x53"
+  "\x28\xc7\x46\xf9\x68\x5d\x43\x9a\xb5\x85\x79\xde\xa5\xb2\xe9\xfc"
+  "\x3e\x7e\xaf\x09\xe0\x4f\x51\x4e\xf7\x8b\xb8\x4e\xc4\x75\x31\xae"
+  "\x39\xb8\xde\x4c\xe5\x82\x06\xf5\x7e\xbc\x70\xaf\x4b\xb7\xc9\xfe"
+  "\x74\xb1\x0e\x92\x31\xa3\x35\x3c\xa0\xf1\x14\x94\x2f\x59\xe6\x93"
+  "\xf2\x6b\x77\xaa\xd6\x77\x5e\x39\x6e\xa3\xbd\xe8\x3b\x94\xff\x4b"
+  "\x7a\x1f\xd7\xa9\xea\x35\x41\xbd\xde\xa9\x5e\xef\x56\xaf\xd3\xd4"
+  "\x6b\xa2\x8b\x75\xc7\xab\xbc\x09\x68\xd6\x1d\x4f\x34\xc1\xdc\x4d"
+  "\x95\xdf\xf5\xa4\x93\x7c\x0d\xfc\xff\x49\x07\xc5\x14\x2b\xea\x6e"
+  "\xd0\x74\xb1\xa4\xfb\xe9\x2d\xfa\xc7\xdd\xdb\x85\xee\xa7\xdb\x1d"
+  "\x80\x85\xa6\x08\x5d\x02\x03\xef\x14\x56\xa1\x07\xdf\x20\xcb\x49"
+  "\xd4\xab\x7b\xd0\x14\x5b\x83\x62\xa5\x91\xef\x38\x21\x47\x45\xd6"
+  "\xd3\x5e\x5e\xa3\xd0\x53\x6f\x26\x5f\x38\xc9\x31\xf8\x23\x5f\x71"
+  "\x71\x1a\xde\x93\xbc\xa4\xfa\x88\x3c\xd4\x5d\xe4\x49\xf6\xcb\xf9"
+  "\x9e\x08\xb9\x5f\x77\xe5\x78\xa4\x07\xc8\xff\xdd\x47\xa9\xce\xa0"
+  "\x75\x03\xda\x33\xb1\x89\x79\x48\x87\x79\x4b\xb3\x6c\x73\xbc\xd6"
+  "\x66\xb5\xaf\xac\x1a\xcd\x9b\x59\xf7\x24\xe0\x61\x36\x8d\xef\xa6"
+  "\x3e\x5c\xee\x16\xfa\x69\x75\xfc\xa0\x9f\xcf\x7d\x45\xfd\x1d\x80"
+  "\x27\x79\x7e\x9c\xf6\x78\x82\xfb\xc5\xed\xf1\x4a\x7e\xa1\x01\xf3"
+  "\x12\x63\xe0\x9c\xa3\xdf\xbc\xdc\x40\xf3\x52\xbe\x7b\x7e\x62\x30"
+  "\xc6\x77\x6d\x20\x8c\x57\xeb\x88\x71\x7b\xae\x92\xfa\xc6\xc5\xce"
+  "\x47\xab\x6b\x52\x03\xd6\xc8\x9f\x20\xbd\x44\xd6\x53\xa6\xab\xdf"
+  "\xc2\xf8\x3b\x47\xbe\x27\xae\xd2\xd2\xd5\xf1\x4d\xe5\xd8\xa8\xaf"
+  "\xb5\x74\xb5\x7c\x8c\xd3\x73\x56\x9a\x3f\x5a\xba\x3a\x26\x8f\x12"
+  "\xde\xd0\xbb\x5e\x61\x77\x07\xf9\x7b\x7e\x0d\xea\x7d\x9e\x74\x8a"
+  "\x95\x34\x9f\x9f\x5a\xc5\x22\x56\x94\xb3\x2b\xe4\xdc\xec\x19\xa5"
+  "\xbd\x2b\xf5\xd4\x3d\xe1\x1a\x46\x6d\x12\x78\xd6\x99\x17\x8c\x95"
+  "\xde\xdf\xf1\x22\x83\xd7\x6b\x4c\x8e\x3e\xee\x9d\x28\x30\x17\xf3"
+  "\xbe\x02\xef\x25\xb8\xd8\x33\x4c\x5d\x4b\x6a\xe5\x3e\x41\xcf\xf2"
+  "\xe3\x95\x12\xbb\xd4\xb2\xfb\xf0\x2f\x80\x0f\x11\x58\x4f\xdf\xa2"
+  "\xb2\xb0\xae\x18\x3b\x0b\x92\x2e\x97\xf8\xdd\x53\xe6\x62\x97\xc7"
+  "\x6a\xd8\x4a\xeb\x93\x41\xc7\xac\xa5\xf3\xe5\xfa\xa4\x90\x0e\xcc"
+  "\xda\x29\x7c\x7f\xd5\x59\xdb\x19\xad\x9b\xe4\x93\x39\x65\xe5\x08"
+  "\xf2\x8d\x94\x84\xba\xae\x07\x7f\xb6\x5b\xdd\x6f\x80\x9c\xeb\xfd"
+  "\x39\xc9\xb2\x2a\x5d\x31\x9f\xbc\x57\xab\xfd\xd2\x88\xfa\xec\x26"
+  "\x6c\x7f\x2a\x57\xc6\xa7\x21\x7d\x90\x88\x67\x44\x3c\xab\x89\x7b"
+  "\xa4\x7f\xf9\xde\xd8\x00\x1d\x57\xa5\x9c\x27\x3d\x97\x89\xd8\x00"
+  "\xf6\xe4\x68\xa9\x4f\xec\x7d\x4d\xa6\xf7\xaa\xbe\xaa\x92\x55\x7f"
+  "\x57\xbd\x85\x21\xa6\xd1\xff\x4b\xea\x85\xff\xb1\x40\xf2\x23\xbd"
+  "\x39\x01\x76\x2c\x82\xd6\xd2\xf7\x6c\xef\x06\xff\xbc\xe8\x4d\xa5"
+  "\x77\xf0\xee\x73\x48\xef\xf3\xff\x25\xd7\x1a\xb7\x4d\xd5\x99\x99"
+  "\x2e\x5f\x9b\xc0\x80\xcd\x61\xdb\x8b\xb4\xf9\xeb\x0d\x95\xdf\x97"
+  "\xf3\x97\xda\x48\xe3\x81\xe6\xb0\x57\xf8\xaf\xaa\xcf\xa4\xb9\x8c"
+  "\xdf\x31\x5e\x6d\xee\x4a\xfe\x2e\x4f\xcc\x5d\x31\x6f\xbd\xd1\x01"
+  "\xf5\xa8\x55\xc7\x6a\x63\xc7\x63\xa6\x08\x3c\xc3\x9c\x6c\x53\xfd"
+  "\x03\xf5\x48\x19\x63\xf3\x34\x9b\x72\x8e\x7b\x48\x37\x4d\xfa\x04"
+  "\xd2\xd9\xa8\xb6\x95\xa4\xff\xef\x24\x9f\x5c\x76\xcc\x07\xbf\x1f"
+  "\x2e\x23\xd3\xfc\x70\xa1\xbc\x42\xbf\xee\xb8\xc7\xa5\xb6\x2b\x1a"
+  "\xdf\xab\x70\xe4\xbf\x4d\x74\x7e\x5f\xce\xb1\x9e\x7a\x1a\xc7\x4e"
+  "\x8c\x3d\xac\x3f\xe5\x14\xef\x1c\xef\x1e\xd4\xc6\x1e\xe6\x68\x7a"
+  "\x0b\xf3\xcd\x28\x1b\xcd\xcb\xd1\xa7\x64\x1f\x9e\x85\xfb\x9f\xe3"
+  "\x9a\x2e\xaf\x3a\x23\x5d\xd5\x31\x5f\x8e\x77\x31\xff\x47\x1c\xd5"
+  "\xfa\xa0\x33\xb2\xda\x2a\xc6\x58\x3e\xd9\xec\xc5\x8b\xfd\x6b\x1a"
+  "\x63\x34\xbe\xc4\x3e\x36\xc6\x9a\x61\xed\xbd\x8c\xc6\x99\xf0\xcd"
+  "\x81\x7b\xaa\x2f\x8d\xb3\xee\x22\xdf\x34\xcd\x0f\xad\x8b\x79\x5b"
+  "\xe5\x1e\x92\x2f\x49\xb3\x59\xa6\x71\x98\x33\x9e\x8d\x42\xf9\xe6"
+  "\x1a\x73\x27\xe9\xce\x3f\x73\x7a\xef\x64\x94\x97\x68\x27\xf1\xf2"
+  "\xca\x1c\xbc\x13\xd0\xff\x6e\x61\xc3\x72\x38\x59\xe8\x33\x7f\x80"
+  "\x67\x7b\x82\x31\xa7\x7d\xa2\xe0\x2b\xb1\x3e\xff\x30\x9a\x99\x31"
+  "\x6e\xb1\xd6\xf8\x6a\x35\x7e\xf8\xa6\x68\xb2\x21\xf8\x87\x88\x15"
+  "\x4e\x3c\x09\x7e\xd7\xd2\x3a\x3d\x88\xde\x79\x22\xe9\x8a\x08\x33"
+  "\x48\xf7\x44\x7a\x30\xd0\xfa\x44\x8b\x4e\x37\xe3\x38\xf9\xc9\x59"
+  "\x7a\xa1\x2f\xe2\x7c\x1b\xef\x22\xbf\x4d\xe6\x6c\xf6\x83\x26\x9d"
+  "\x2e\x9e\xf4\x4e\x05\x67\x48\xc7\xa3\xcc\x0e\xd6\xf1\x28\xbb\xd5"
+  "\xbf\x6a\x94\x14\x13\xf0\xb7\x57\xbd\x5a\x2e\xf1\x57\xa3\xe6\xad"
+  "\xc7\x5f\xa3\x4a\xab\xfd\xdd\x45\x4a\xb5\x46\x2b\xc2\x14\xc2\x58"
+  "\xb2\x1d\xa1\x79\xae\xf3\x32\xf2\xcb\x83\x7e\x42\xbd\x9f\xfa\xd1"
+  "\x83\x8e\x55\x24\xd3\x2a\xc2\x06\x8a\x7c\xca\x0e\xcd\x7e\x49\x11"
+  "\xfd\x29\x7d\x7e\x2a\x7b\xf1\xed\x9a\x4d\xa7\x59\xa8\x35\x9b\x5d"
+  "\x4d\x3a\x74\x83\x8f\x3b\x48\x06\x36\xc8\xf8\xec\xf5\x6d\x8c\xef"
+  "\xcb\x59\xc3\xf4\x78\x3e\x0e\xbf\x2b\x34\x5e\x0a\xef\x18\x43\x3c"
+  "\x2c\x9a\x78\xa8\xa9\x6b\xd8\xb8\xee\x22\x6e\xd3\xfa\x8a\xf8\x0c"
+  "\xd2\xe3\xf9\x63\x07\x29\xc2\x2e\x8b\xfc\xab\xbb\x04\xdd\x54\xac"
+  "\x3a\x4d\xba\x6b\x9e\x1e\xd2\xc9\x8c\x72\x1d\xe2\x18\xff\xff\xc8"
+  "\x93\xe3\x85\x17\x62\xec\x9f\x08\xa8\xe7\x39\xff\x6f\xd3\x4f\xe9"
+  "\x7d\x43\x27\xf1\x70\x83\xd0\x47\xc7\x2e\xd3\xe8\x43\x36\xf2\x06"
+  "\xf0\xff\xa2\xbf\xbd\xbc\x1d\x75\xab\xb5\xae\x62\xe1\x6d\x3a\x76"
+  "\x1e\x6d\xa4\x33\xa8\x47\x85\x8e\x5f\xc7\xbe\xd6\xe4\x74\x51\x6f"
+  "\x1d\x3b\x60\x58\x1b\xc2\x48\x37\x4f\xbe\x09\x85\x7d\x21\x58\x52"
+  "\xe2\xe1\x9d\xde\xc9\xcc\x91\x7f\x1b\xe5\x79\x5a\x5d\xcb\x1a\x3b"
+  "\x0a\x4c\xec\xb0\x69\x32\xeb\x2e\x66\xeb\x5c\xfa\x33\xb1\x43\xb6"
+  "\xe3\xd4\x31\x6d\x1f\xbc\x56\xd8\x3f\xe8\xd8\x43\xb4\x96\x90\x6e"
+  "\x00\xeb\x48\x0d\xad\xd7\x28\xdb\xa5\xcd\x1b\xac\x13\x35\x78\x67"
+  "\xb6\xc4\x98\x29\x1e\xfc\x9e\x45\xfe\x51\x84\xfc\x20\xf3\x47\x88"
+  "\x7d\x83\x62\x5d\x74\x1f\xbf\x8d\x7c\xf4\x9e\xb0\x8b\xd3\x91\xaf"
+  "\x21\x1d\xc3\x7b\x16\x6a\x9b\x1c\x8b\xa6\xc9\xc8\x3f\xcd\x3f\x6f"
+  "\x79\xa1\x98\xb7\xed\x01\xf3\xb2\x58\x97\xee\x97\x53\x15\xd3\x0d"
+  "\x65\xcc\x3c\xd0\x3c\xb4\x8e\x64\xc6\x7f\x84\xb3\x5f\x6d\xda\xc4"
+  "\x2b\xed\x7a\x65\xca\x53\xa5\x2c\x42\xb7\x01\x64\xa3\x79\x96\x9b"
+  "\x3a\x0a\xf3\xf1\x94\x21\xe2\xca\x59\x53\x73\x86\xf3\x7c\x13\xd3"
+  "\x6f\x3c\x3b\x3c\x7c\xbc\xe7\xca\x4a\x1e\xf2\xa3\x07\x67\xe4\xd0"
+  "\x7e\xae\x9d\x7d\x99\xc5\x42\xa6\xfa\xf0\xed\x08\x66\x75\xe9\x42"
+  "\xdc\x74\x9e\xfa\x30\x38\x2f\xfa\x4d\x65\xe6\x55\xb0\xf0\xbc\x66"
+  "\xde\xba\xe1\xf1\x61\xe1\x58\x7f\x8d\x58\x37\x4a\x2e\x8f\xb8\xb2"
+  "\xb2\x17\x65\xbc\x95\x2a\xde\xab\x1a\x7a\xdd\xac\xa3\x5b\x74\xfa"
+  "\xb5\x43\xab\xdb\xb0\x78\x7f\xdd\x86\xc5\x7f\xc7\x75\x33\xfa\xeb"
+  "\x96\x89\xba\x85\x5c\x3d\xb4\xba\x85\x59\xfd\x75\x0b\xb3\x7e\xcb"
+  "\xba\xed\x1d\x7a\xdd\x6c\x57\xa2\x6e\x07\x86\x56\xb7\xe1\x55\xfe"
+  "\xba\x0d\xaf\xfa\x57\xea\x96\x5f\xc1\x4f\xd5\x01\x81\x49\x9f\x43"
+  "\x38\xdf\xa2\x0b\x7d\x63\x4d\x8c\xb0\x4d\x8e\xc2\xef\x27\x0b\x2a"
+  "\xf8\x17\x82\xb7\xd1\x85\x0a\xdd\x7f\x77\x71\x68\x1c\xe4\x52\x19"
+  "\x07\x48\x37\x2c\x46\xd8\x6e\x84\x8c\xdd\xc3\x8b\xb8\xf7\xc6\x4e"
+  "\xb2\x83\xf3\x92\x0f\x11\xf2\xcf\x3d\xeb\xd5\x73\x1e\x3d\x8f\x4a"
+  "\x4e\xdd\x75\x36\x94\xbd\x7a\xce\xad\xc7\xbb\x99\x9a\xdf\x50\xed"
+  "\x5d\x43\xf9\xc5\xf0\x28\x74\xc7\xd4\x4c\x66\x20\x3c\xa2\x2b\xc5"
+  "\x26\xdc\x94\x3f\x3c\x7c\xea\x19\xac\xfb\xc5\xa1\xfb\xb5\x73\xa1"
+  "\x5a\x59\x33\x5b\x87\x73\x43\x1e\x0b\xa1\xb3\xa9\xc2\xc7\xa0\xc9"
+  "\xcd\x62\xf3\xd8\xb0\x99\x36\x94\xef\x61\xa9\x06\x1b\xca\x06\x3d"
+  "\x04\x2f\xaf\x0b\x3d\x1f\x92\xc5\x22\xca\x50\x36\x5d\xa7\x9a\x0a"
+  "\xf8\x53\xcf\xb2\x50\x3a\xc3\x4a\x67\x51\xe5\x39\xd4\xb0\xf0\xee"
+  "\xe2\x61\x31\xda\x77\x2e\x41\xbf\x91\x92\x7e\xc3\x7c\x7e\xfa\x0d"
+  "\x7b\xcd\x4f\xbf\x61\xcb\x25\xfd\x86\x65\xf9\xe9\x17\x96\x3c\x34"
+  "\xfa\x0d\xdb\xe3\xa7\x9f\x7c\xf7\xe2\xf4\x1b\x76\x72\x70\xfa\x0d"
+  "\xeb\xf4\xd3\x4f\x96\x35\x08\xfd\xc2\x06\xa6\x5f\xd8\xcf\xbf\x1d"
+  "\xfd\xc2\x92\xbf\x25\xfd\xae\x90\xf4\x1b\x7e\xbb\x9f\x7e\x61\x67"
+  "\xfc\xf4\x0b\xfb\xa3\xa4\x5f\xd8\x5e\x3f\xfd\x86\x57\x0c\x8d\x7e"
+  "\x61\xad\x7e\xfa\xc9\x77\x2f\x4e\xbf\xe1\x57\x0f\x4e\xbf\xe1\x13"
+  "\xfd\xf4\x93\x65\x0d\x8d\x7e\xc3\x57\x82\x6e\x46\x95\x7e\xc6\xc1"
+  "\xe9\x37\xbc\xe2\x5b\xd2\xcf\x20\xe9\x17\xbe\xc6\x4f\xbf\xf0\x9b"
+  "\xfd\xf4\x1b\xde\x25\xe9\x37\xbc\xdd\x4f\xbf\xf0\xc6\xa1\xd1\x2f"
+  "\xdc\xe2\xa7\x9f\x7c\xf7\xe2\xf4\x0b\x9f\x37\x38\xfd\xc2\x73\xfc"
+  "\xf4\x93\x65\x0d\x42\xbf\xe1\x03\xd3\x2f\xfc\xc0\xb7\xa3\x5f\x78"
+  "\xe3\xc5\xe8\x37\x34\x5e\x23\x7c\x50\xbb\xe2\xa1\x95\x73\xd9\xa4"
+  "\xc1\xca\x21\x1a\x92\xcd\x9d\x52\x7c\xd9\xa4\x9d\x4a\x58\xb8\x3c"
+  "\x97\x10\x4e\xb1\xcf\xee\x68\xd2\x5d\xf6\xf4\x4e\x65\x58\x38\x2f"
+  "\xfa\x6b\x95\x52\xf4\x6e\x12\x5f\x1b\x16\xaa\xac\x1d\x1e\x4a\xe7"
+  "\xe6\x07\x8d\x75\xac\xbb\xec\x54\xc8\x18\x76\x0d\x9d\x2d\x7b\x0a"
+  "\xfc\x1a\xfd\xee\x2e\xbe\xcc\x0d\x5e\xe4\x02\x3f\xdc\xe9\x0b\x97"
+  "\x89\xc0\x89\xd9\x19\xe9\xcb\x97\xa4\xa7\x2d\xc9\x31\xa7\x3d\xf6"
+  "\xc4\xb2\x60\xbf\xe6\x22\xe6\xe0\x3a\xea\xbf\x11\x13\xfb\x7c\x99"
+  "\x80\x8f\x25\x9f\x70\xd6\x6b\xd9\x65\x6d\xba\x11\x39\xc2\xd7\x7c"
+  "\x54\x72\x2d\xef\x4d\x7a\x2e\xe1\x87\xfc\x4d\xe1\xeb\xae\x37\xf3"
+  "\x39\xc8\x53\x1b\xc8\x7f\x89\xba\x37\xb1\xa1\x45\x17\xb1\x91\x47"
+  "\xa6\x19\xc9\xa6\x43\x9c\x57\xd0\x8d\x10\xfe\x11\xc9\xaf\x09\x37"
+  "\xce\x69\x56\xec\x69\x46\xbe\x39\x4d\xd0\xa0\x8e\xfc\x8c\xe5\x86"
+  "\x8c\x6b\xd2\x8d\x9c\xc5\x23\xe7\x34\xa3\xac\x56\xb5\x9c\x56\xb2"
+  "\x81\x4c\x58\xc5\x3f\xa3\xf2\x54\x5e\x90\x62\x49\x38\x24\x3f\x78"
+  "\xf9\x65\x86\xb5\xe6\x10\xca\x4b\xfe\xfe\xc8\x0f\x9e\x16\x3f\x88"
+  "\xea\x4d\x79\xc1\x8f\xdf\x81\xf7\xef\xd8\x45\xf1\x81\xb4\x32\x64"
+  "\x9d\x7e\xd0\xa6\xbb\x3c\x41\xb4\xc5\x3e\xc7\xde\xb1\x3a\xe9\x39"
+  "\x11\x53\x50\xd0\x75\xe4\x4f\xf0\x6d\x51\x06\xf9\xe1\xa2\x77\xd5"
+  "\x77\xae\xc6\x3b\x02\x4f\xc9\xc7\xa7\x2c\x63\xe4\xd5\x5a\xbd\xc0"
+  "\x43\x8f\xc0\xfd\xb0\x80\x6f\x5c\xde\xa6\xbb\xe2\xeb\x80\xe7\x11"
+  "\xb8\x7f\x1f\x7c\x68\xa4\xfa\xfc\x0a\xdc\xff\x91\xf8\x52\xd1\xae"
+  "\xd2\x42\x69\xe7\xab\xbb\xa2\x1c\x69\x1a\xed\x22\x91\x67\x0d\xf1"
+  "\xba\x6a\x19\x51\xb8\x4f\x23\x99\x51\x7d\x1e\x8d\xfb\x3b\x69\x5f"
+  "\x40\x7d\x3e\x0a\xf7\xd7\xe3\xfe\xdf\xd4\xe7\xe0\xeb\x23\x52\x45"
+  "\x9d\x8d\x73\x1a\xa9\x4d\x8a\x3d\xd5\x4d\x74\x07\xad\x1b\x91\xb6"
+  "\x01\xf2\x6a\x01\xf5\x23\xb5\xd3\xb1\xaa\x8d\x35\xe9\x22\x1e\xa2"
+  "\xb3\x66\xb2\xaf\xd2\x8c\xd2\x0f\x8d\x3e\x09\xe9\xb3\x29\x9d\xec"
+  "\xa5\x95\xcd\xa9\x84\x43\xc0\x9e\x88\xaf\x89\x86\xea\xb7\xc6\xe1"
+  "\x5b\x79\x6a\x3f\x83\x76\xe4\x2b\x96\x15\xee\x52\xfb\x02\x75\x1b"
+  "\x8e\xe7\x1f\x6b\xf6\x17\x33\xbd\xbd\xf2\xcc\x8c\x2e\x62\xf7\x3f"
+  "\xe5\x1b\x01\xef\x49\xdc\x8b\x68\xd6\xe2\xca\x21\x4d\xc4\xaa\xa7"
+  "\xf1\x49\xfa\x15\x77\xe4\x1c\x9b\xf0\x05\x82\x31\xaa\x8d\x15\x1a"
+  "\x27\x3c\xec\x32\xaf\xd0\xd5\x14\x5f\xe1\x8f\x7f\xa2\x8b\x48\x56"
+  "\x7d\xf1\x33\x29\x27\x5c\x31\xb9\xcf\xbe\x48\x77\xb9\xc0\x87\x80"
+  "\x67\x49\x01\xcf\x5c\xda\x33\x61\x03\x57\x7c\x45\x4e\xc0\xb3\xfa"
+  "\x7e\xcf\xec\x01\xcf\x1c\xfd\xca\xdc\x1b\xf0\xac\xaa\xdf\x7b\x47"
+  "\x03\x9e\x55\xf4\x7b\xd6\x1c\xf0\x6c\x83\xfa\x2c\x04\xe9\xde\x3e"
+  "\x5f\x7c\xba\xcb\xf3\xd4\x74\x60\xfd\xc8\xe8\x80\xf4\x2c\x35\x1d"
+  "\xdf\x1f\x09\xfe\xef\xf5\x2a\x35\x5d\x8c\x73\x8c\xa3\xeb\xe4\x37"
+  "\x46\x26\x06\x7c\x63\xb2\xba\x7f\x6c\x93\xfd\x37\x62\xbf\x41\x67"
+  "\x1e\x4e\x63\xca\xb0\xb6\x90\xe2\xba\xd8\xa5\xdf\x29\x39\x0f\x45"
+  "\x4c\x5f\x92\x87\x91\x6f\x30\x6c\x1c\xd0\x46\xb0\x78\xe4\x41\xed"
+  "\x6c\xa6\xcf\x3e\x27\x4f\xb1\x1f\xa0\x18\x4a\xe3\xc8\x3f\x55\x41"
+  "\x3b\xf9\x28\xe9\x64\x4e\xd6\xc3\x9c\x39\xdd\x85\x14\x2f\xae\x4e"
+  "\xc6\x89\xa3\x33\x6d\x3a\x3a\xb3\x41\x3e\xb6\xea\xac\x5f\x8b\x58"
+  "\x71\x2b\xda\x59\x8c\xf5\x17\xbc\xb9\x45\x67\x30\xfb\x36\xcf\xc9"
+  "\x53\xfd\x0c\x3c\x2b\xce\x42\xeb\x0c\x72\x7e\x90\x1c\xdb\x2e\x74"
+  "\xcb\xe1\xc8\x57\x25\xf2\xf0\xa4\x67\x65\x1b\x0d\xa2\x3f\x76\xa9"
+  "\xe7\xe3\xba\x8b\x0d\x49\x7d\xf1\x0b\x75\x86\xfd\x5d\x91\x65\x26"
+  "\xa4\x65\x05\xd9\x34\xea\x0c\x4f\x53\x99\x54\x77\xe4\xb1\x50\xd9"
+  "\xc8\x63\xef\xb3\x69\x44\xfa\x0a\x2f\x1b\x8b\x7a\xb5\x68\xe5\xe3"
+  "\x79\x95\x4b\x37\x52\xd8\x47\x53\x99\x5d\x9b\x5f\xa7\x72\x6b\x5c"
+  "\xa1\xd7\x09\xfd\x24\x7e\xd7\xbb\xd8\x3b\xa1\x83\xad\x79\x42\x0f"
+  "\x69\x4c\xb3\x70\x7b\x5a\x3c\x30\xd6\x2c\xcf\xa4\xa7\x59\xa4\xfc"
+  "\x6e\xbc\x9a\x6c\x2e\x28\x06\x32\xed\x35\x4a\xac\x31\xa6\x89\xf9"
+  "\x8a\x34\xf4\xd1\x1e\x60\xb2\xd0\xc7\x0f\x6d\x1e\x1a\xe3\x44\x19"
+  "\x67\x59\x78\xa9\x6a\xe7\xda\x5d\x6c\xb4\x05\xc4\x11\x90\x76\xec"
+  "\x3a\xe3\xf3\x75\x36\xb1\xdf\x24\xea\xd8\xbf\x0e\x54\x5f\x94\x15"
+  "\x33\xe8\xfa\x69\x4c\x33\x0b\xdd\xe7\x96\x64\xab\xb0\x1f\xd3\x19"
+  "\xbf\x0a\x31\x5d\xb5\x0d\xdf\x6a\xee\x8b\x9f\x80\x3c\xa5\x3d\xe4"
+  "\x97\x2d\xcd\xd2\xd7\xce\x6c\xfa\x46\xa4\xd8\x9f\x70\xe9\x22\xcd"
+  "\xca\xe6\x34\x33\xd5\x41\x4d\x37\xd7\x79\x3d\x74\xf6\x7b\x40\xff"
+  "\x4e\xb4\x2e\x0a\xdf\x40\x5b\xd2\xcc\x74\x0e\xe0\x26\x8f\x56\xe7"
+  "\x28\x33\xd9\x9f\x53\x9d\x25\x6d\xa3\x46\x69\x74\xdc\x78\x16\x65"
+  "\xe7\x7f\xc2\x9a\x75\x91\x3b\xc8\xa6\x85\xce\x53\x6c\x5a\xa5\xda"
+  "\x59\x21\x4d\xe4\xeb\xe9\xcb\x23\x74\xbd\x64\xe3\x4b\x18\xba\x93"
+  "\xce\xc5\xa3\xcc\x52\xf4\x85\xf0\x79\xa1\x8b\x14\x67\x21\x9e\xca"
+  "\x66\xb2\xdd\x64\xc3\xa6\x8b\x9a\x26\xc7\x4a\x64\xa3\x4b\x17\x25"
+  "\xcf\x71\xab\x69\x14\x43\x9b\x6c\x0f\x4e\xeb\x22\xdf\xa0\x98\x9e"
+  "\xa0\x47\x3c\xf9\x45\xab\xeb\xc4\x3c\xb1\xf5\xd0\x58\x88\xa7\xd8"
+  "\x6d\xa0\xc3\x41\xb9\x26\x10\xcd\x23\x2b\xe9\xfb\x44\x5b\x8a\x67"
+  "\x0a\x9a\xee\xee\x2e\x8e\xea\x8b\xff\x45\xb1\x53\x91\x67\xf6\x60"
+  "\xfd\x42\x34\xf2\xa1\xce\xe4\xdf\xc3\x31\xf6\x13\xd4\xef\x07\x3a"
+  "\x25\x2a\xcd\x4c\x36\x93\xa8\xeb\xef\x24\x56\xc8\xbe\x93\x73\x29"
+  "\xea\x63\x7c\xc3\x49\xfb\x8b\x64\x8f\x2d\xe2\x40\xeb\xa2\x0a\x55"
+  "\xfa\x89\x78\x0a\xf6\x5c\x49\x07\x99\xff\x07\x13\xa5\x2e\xe6\xaa"
+  "\x0f\x51\xaf\xfa\x3e\x5d\x0c\xd2\x85\x1e\x4d\xb5\xab\xc6\xb3\xf6"
+  "\x80\x3a\x77\x8a\xf3\x6c\x67\x49\x8e\x8e\x2a\xa3\x6f\x6d\x24\xbf"
+  "\x55\x34\x2e\xda\x02\xc7\x7f\xd4\x72\xaa\x27\xd9\xe3\xf9\x22\x93"
+  "\xad\x7c\x73\x72\x0e\xd1\x19\xef\xec\xc5\x5c\x18\x50\x8f\x43\x58"
+  "\x49\x31\x35\xba\x8b\x7f\x90\x1c\x10\x03\x15\x6b\xdf\x0f\x36\x6a"
+  "\x6b\x1b\xad\xcb\xe4\x87\xa0\x2f\x6d\x73\x7d\x03\xe6\xbb\x43\xe5"
+  "\x6b\x1c\x83\xfa\xd0\xbb\x91\xc5\xd3\x99\x59\xb2\xcd\xa6\xf1\xc6"
+  "\x8d\xf5\x36\xf2\xcb\x4b\x3e\x06\x1d\xab\x6e\x41\x7d\xa3\x6f\x7f"
+  "\x66\xb4\x38\xa7\xd7\xe9\xb8\xf1\x2c\xd9\xe5\xb4\xb7\xe4\x09\xdf"
+  "\x39\xe1\x33\x6d\x5e\xbe\x4b\xc6\x39\x76\xf3\xc8\x7a\x5a\x73\xdb"
+  "\x85\x5f\x7a\x2a\xf3\x9f\xf5\x31\xab\x8b\x0e\x57\xf9\x97\x76\x60"
+  "\xe5\x95\x68\x8f\xd8\x2f\xc0\xef\xd1\x6d\xba\x51\x19\x32\x6e\x9f"
+  "\xf4\x93\xae\xda\x17\x86\xc9\x73\xe6\x6e\x26\xce\xfd\xea\xa2\x3f"
+  "\x36\xff\x88\xb1\x76\x5d\xf4\x49\xe1\xb3\xd8\x3e\xa7\x5e\xa5\x41"
+  "\xfd\x26\x59\x2f\x43\x8a\x4d\x2f\xea\x48\xf5\x1b\x62\xdd\x76\xab"
+  "\x6b\x57\x58\x77\x71\x74\xab\x76\x3e\x5d\xb4\x5f\xf5\x65\xec\xb8"
+  "\x96\x64\x95\x51\x0f\xa9\xeb\xd5\x09\xf5\xdb\x27\xfe\xf5\x6f\x8f"
+  "\x32\xab\x65\xee\x11\xfe\x9c\x41\x17\x94\xbb\xa7\xbb\x78\x94\x55"
+  "\x5b\x43\x55\xbb\xf8\x38\xb9\xb6\x8f\x2a\xf1\xaf\x9f\x92\x86\x41"
+  "\x67\x4f\x96\x2e\xcd\x31\x83\x49\xb7\xa6\xe5\x3c\x96\x69\xce\xc8"
+  "\xce\x5e\x9a\x6d\x26\xe7\x2b\x81\x73\x4c\xd8\xbd\x14\x8f\xaa\x50"
+  "\x63\x70\xed\xe9\x8b\xc1\x55\x3c\xaa\xcf\xfe\x85\xf6\xac\x50\xb7"
+  "\xd6\xef\x46\x96\x19\x7d\x41\xdc\x45\xad\x1c\xbb\x5e\x21\xdd\x54"
+  "\x35\xfe\x1c\xf8\x3b\x4a\xb2\x4d\x8a\x87\x25\x60\x7d\x14\xfc\x8e"
+  "\xff\xdc\xf5\xa8\x83\xb4\xf7\xdd\xa4\x1b\x9d\xb6\x53\x09\x65\xc2"
+  "\xef\x46\x91\x42\xf6\x23\xe4\x7b\xbb\x1a\x7f\x0e\xfc\x1d\xc5\x9f"
+  "\x78\x4f\x79\x5b\x9c\x19\xad\x0a\x7c\x46\xfb\xd1\xbc\x68\x77\x33"
+  "\xe5\xe1\x6b\x43\xc5\xbe\x83\xb2\x45\xe6\xeb\x57\x07\x3d\x2f\x36"
+  "\x68\xf9\x44\xdd\x47\xae\x65\xe6\x01\xf2\x85\xf0\xe2\x11\x31\x6a"
+  "\x3e\x31\xbe\xb5\xf6\x90\x5f\x78\xe4\xd7\xf2\x85\xf2\xe2\x1f\x54"
+  "\xaa\xf9\xe4\x59\xa6\x22\xfd\x40\xdf\x1d\xc6\x8b\x3e\x5e\xa7\xe6"
+  "\x33\x06\x96\x17\x90\x27\x4c\x29\x16\xf1\x76\xeb\x95\xb5\xa1\x62"
+  "\x5f\x97\x17\x8f\x0e\x45\xfe\x01\xfd\x69\x0e\xad\x9f\xae\xdc\xdb"
+  "\xbf\x9f\xac\x8f\x2d\xcc\xb8\x6d\xe1\x92\x5c\x8a\x52\x94\xb3\x74"
+  "\x79\x0e\x5d\x97\xa4\x3d\x21\x2e\x4b\x53\x1e\x7f\x4c\xfe\xc8\xc9"
+  "\x8a\xa7\x1f\x59\x18\x6f\x74\x4d\x5f\x6e\xa5\xcb\x63\x4b\xe9\xd6"
+  "\x96\x19\xb7\xfc\x31\x2d\xb4\x72\xe0\x38\xb4\x74\x17\x9b\x66\x63"
+  "\x6c\x4c\x93\xfc\x88\x29\x15\x32\xaf\xd8\xfb\x35\xac\x75\xb1\x23"
+  "\x16\x11\x83\x8d\x5d\x70\xee\x5e\x67\x5a\x4c\xe7\xee\x0d\x6b\xad"
+  "\x8f\x19\xbc\x0b\x33\x80\xb3\xf5\x78\xb7\xc2\xc5\x36\xa8\x31\x84"
+  "\xe6\xb8\x84\x4f\xca\xe2\x2b\xdb\x35\x9b\x42\xc5\x3e\xa7\x8c\x7c"
+  "\xad\x0b\x1b\xa3\x2d\xc2\x57\x8b\x03\xf7\x8d\x3b\xb7\x88\x98\x27"
+  "\xd1\xb8\xaf\xc0\x7d\x33\xee\x4d\xb8\x8f\x51\xec\x77\x5b\xe8\x9c"
+  "\x1d\xee\xcd\xb8\x8f\x45\xf9\x7d\xf1\xdf\x03\x69\xa3\x06\xfd\xba"
+  "\x6d\x40\x99\x38\xd8\xdf\x11\xe6\xd6\x98\x04\x2d\xa6\xaa\x88\x9f"
+  "\x5a\x3c\x66\x96\xb6\x17\x28\xe3\x04\x19\x93\xc5\xba\x26\xd6\xf6"
+  "\x31\xc7\x43\x4c\x57\xc7\x4a\xde\x7b\x8c\x4d\xf3\x2d\x20\x79\xeb"
+  "\x31\x25\x01\xb1\x67\xe9\xbe\xbc\x2f\xf6\xac\xe4\x45\x9f\x93\xbc"
+  "\xe8\x18\x17\x2f\x1e\xe3\x8f\xa1\x57\x3c\xc6\x11\x18\x27\xcc\x85"
+  "\xe7\x24\xd3\x20\xbd\xc1\xbf\x0e\x8e\xc9\xa2\x6f\x0e\x14\x67\x17"
+  "\x32\xb9\x2d\x65\x25\xf8\x6f\x5c\x05\x2f\xee\xd3\x31\x21\x8f\xe1"
+  "\x9e\x17\x25\x90\x9f\x16\x33\x3d\x23\xde\x6f\x40\x3d\x03\xc5\xb9"
+  "\xd3\x8d\x7d\x92\x7c\xba\xba\x0b\xd2\x75\x3f\xdc\xc9\x74\xe2\x5e"
+  "\xfa\x24\xe4\xa7\x75\x63\x7f\x49\x63\x4f\xf3\x57\x16\x78\xb6\x7b"
+  "\xc0\xf3\x06\x1f\x68\xfb\xc4\x59\x4b\x0d\xde\xb4\x0c\xc9\xc7\x8d"
+  "\x7d\x5f\xdd\x17\x2e\x93\xeb\xfd\xd8\x83\xfc\x41\x19\x4b\xc3\xa5"
+  "\xbb\x4a\xc4\xb1\x33\xe8\xb2\x96\x72\xbc\x6b\xb0\xa5\x65\x88\x34"
+  "\xe4\x7b\x0a\xbc\x96\x5a\xbf\xe7\x9d\x31\xad\x8c\x9f\xf3\xc9\x33"
+  "\xeb\xba\xb1\x95\xf3\xaf\x2e\xa4\xef\x84\x0b\x3e\xe2\x03\x16\x41"
+  "\x31\xdb\xa8\x6e\x3b\x03\xfc\xa9\x6d\x42\x9a\x88\xc7\xfe\x20\x8b"
+  "\x20\xff\xb1\x6a\x5d\x2a\x45\x1c\xac\xe2\xab\x26\x69\xbe\x5f\x5c"
+  "\x48\xeb\xdf\x9e\x07\x7f\x25\x66\xc8\x84\xc7\xe2\x66\xdd\x89\x5f"
+  "\x71\x6a\xb8\xd1\xc0\xb1\x13\xd3\x11\x35\xbf\xa1\xe3\x95\x8c\x3f"
+  "\x8b\x78\x7d\xc5\x57\x95\xa0\x9c\x38\xd1\xdf\x4f\x3d\xfa\x15\x61"
+  "\x8b\x16\xaf\xde\xa9\x74\xe2\xbb\xd7\x64\x08\xdf\xad\x7a\xc9\x2f"
+  "\x0a\x9f\x69\xc5\x57\x4d\xe7\x51\x73\x0a\x65\xac\xce\x79\x99\xe8"
+  "\x3f\xb1\xee\xd3\xdc\x10\xe7\x00\x8d\xd4\xf6\xab\x5c\xc0\xd4\xa9"
+  "\xf8\x7b\x58\xc6\x1e\x79\xf4\x2b\xad\x5c\xf2\x6f\x84\xb1\x55\x8f"
+  "\xab\xb1\xbb\x38\x26\xbc\xcf\x2e\x48\x3b\x5b\xa8\x8b\xb9\x9e\x7c"
+  "\x2f\xf9\xf9\xf3\x6b\x1e\x90\x7c\x65\xcc\x44\x17\x33\x94\xc9\xf9"
+  "\x1d\x83\xf1\xbf\x6f\xb2\xfa\x7b\xba\x8b\xdd\x9a\xd9\xaf\x8c\xad"
+  "\x9a\xbe\x43\xf6\x5d\x8c\x15\x63\x71\x2a\xfe\x1e\x46\xfe\x3c\x2d"
+  "\x56\xf1\x53\x7a\x71\x9e\xa8\x25\xc4\xc4\xe2\x91\x5e\xa6\xa5\x0f"
+  "\xd3\x25\x80\x36\x31\xbb\x35\x3c\xe9\x88\x4a\xce\xc3\xfd\x7e\xf0"
+  "\x9b\x71\xea\x7d\x09\xee\x6b\xb4\x7b\xfc\xae\xd7\xf0\x86\xf4\x0e"
+  "\x1d\xab\x93\x9e\x25\x79\xef\x31\x13\x78\x32\x13\xc9\x57\x31\x6e"
+  "\x17\xdb\x6b\x51\xf3\x42\xfe\x7d\x65\x83\xfc\x7d\x35\xda\x6f\xa9"
+  "\xf2\xd3\x3f\xc4\x20\xeb\x7f\xcd\x64\x1e\x79\x60\x12\xc5\x88\x46"
+  "\x9e\x38\xcc\x25\xf1\x2e\xf9\x3a\xda\xd0\x63\x9c\xed\x5c\x07\xfe"
+  "\xf4\x71\x1a\x17\xd7\x88\xfd\xd3\x8d\xab\x8c\xb3\x88\xbf\xa3\xb3"
+  "\xf3\x22\xe6\x16\xf9\x2e\xf4\xb2\x30\xe1\x2f\x7e\xf3\x01\x8b\xf0"
+  "\x93\xbe\xc2\x12\xa1\xf9\x2d\xc4\x9c\x8c\xe7\xfa\x67\xd2\xc9\x97"
+  "\xa1\xd0\x95\x75\x5b\x46\x0a\xff\x85\xaa\xdf\xc2\x1d\xb9\x2c\xba"
+  "\x42\x91\x7e\x0b\xc5\xb9\xfa\x8b\xf8\x2e\xe4\x45\xc7\xfa\x7c\x17"
+  "\x52\x4c\x78\xfc\xb6\xf0\x73\x5e\x0f\xae\xb1\x01\xfe\x59\x42\x07"
+  "\xf4\x63\xa8\x07\x46\xea\xa5\x1f\xc3\xa1\xad\x2d\xd7\x84\xcb\x31"
+  "\x71\x4d\xa2\x16\x37\x39\x20\x2d\x19\x63\x5a\xee\x4f\xeb\x62\x2c"
+  "\x6a\x1a\xf8\x9f\x97\xcb\xfa\xf8\x30\x60\x1b\xe9\x0c\x31\x67\xf7"
+  "\xf2\x82\xcc\x67\x03\xe7\x10\x63\xb4\x44\x0f\x43\x59\x61\xf8\x1b"
+  "\x4e\x7f\x89\x7d\x38\x71\x8e\x37\x90\x2c\x60\xd0\x61\x5d\xb1\x85"
+  "\xf0\x99\x5e\x6f\x48\x8a\x57\x77\x82\x78\x4c\x3a\x23\x3c\xd3\xe7"
+  "\xa5\xb3\xea\xa1\x33\x7d\x1d\x14\xcf\xf0\x04\x9d\x13\xdb\xf4\x38"
+  "\x9d\x5b\x1c\xc7\x29\xd6\xc9\x4c\xdf\x37\x7c\x97\x3c\x8f\x59\x4f"
+  "\x32\x80\xef\x1c\xaf\xf5\xe5\xf2\xa3\xe8\x83\x08\x92\x2f\xc8\x5f"
+  "\xd4\x48\x9d\x87\x8d\xb4\x86\xbc\x79\x7f\xd7\x9b\x9c\x7c\x45\x51"
+  "\x9c\x2b\xa5\xd8\x03\x4c\x34\xeb\x52\xbc\x21\x85\x4e\x6f\xb3\xf0"
+  "\x35\x3f\xd3\x37\x9c\xcf\xb4\xdd\xce\x45\x7c\xaa\x5c\x5e\x03\x3c"
+  "\x0d\x11\x31\x8b\x57\xf2\x0e\xfc\x0e\x9f\xb9\xb2\x83\x53\x3c\x45"
+  "\x94\x7d\x74\xa6\x57\xe9\x99\x69\x53\x0a\x52\x6c\x3a\xbc\xf7\x05"
+  "\xde\xfb\x02\xf5\x89\x47\x99\x46\xdc\xdf\xc1\x77\x3d\x4e\xe7\x9b"
+  "\x0a\x85\x8c\x83\x36\x3a\xd4\x33\xa3\xd5\xa8\xdf\x7e\xf2\x55\x9d"
+  "\xe2\x75\x14\xee\x52\xcf\x80\x8a\x58\x9e\xb6\x5e\xae\x7e\x67\xd2"
+  "\xcc\x95\xec\x8e\x94\x95\xe3\xc4\x59\x52\x3a\x27\x35\xd3\x6b\xc6"
+  "\x37\x0b\x89\x1e\x11\x22\x7e\x32\x9d\x95\x2a\x1e\xe7\xbe\x58\x1c"
+  "\x46\xb2\x01\x59\x36\x86\xe9\x49\x0f\xe0\x7b\x61\x86\x91\x7c\x57"
+  "\x15\xb8\xb9\x87\x74\x7a\x6f\xf6\x34\xe8\xcd\xb9\xa1\xc0\x4f\xf3"
+  "\xa8\x3a\x6b\xfc\xc0\xe7\xe5\x4a\x7f\x95\xc5\xb7\xce\xcd\xe1\xa5"
+  "\x73\x12\x71\xed\xe4\xf6\x79\xe5\x64\x8b\xca\x4b\x1f\x89\xe5\x5b"
+  "\x1f\x45\x7a\x32\xc3\xb5\x93\x97\xce\x6f\xe4\x5b\x21\x4b\x95\xa6"
+  "\x55\xe3\x8a\xfb\x5b\x77\x23\xbf\x95\x97\xfe\x24\x1a\x57\x37\x2f"
+  "\xfd\xe9\x3a\xe4\xc3\xfd\xcf\x3a\x71\xc5\xfd\xcf\xd3\x91\x0f\xf7"
+  "\xb7\x9d\x68\xd1\x99\x5d\xf8\x8d\xb4\xf4\x32\xf9\xad\x5f\x57\x8a"
+  "\x6f\x95\x2e\xda\x2b\xbf\xb1\xb8\x5a\x7e\xc3\x5a\x23\xbf\xb1\xac"
+  "\x5e\x7e\x63\xf2\x34\xe4\xb3\xf1\xd2\x5f\xc4\xe3\xea\xe1\xa5\x09"
+  "\x31\xc8\x87\xfb\x29\xe1\xb8\xe2\x7e\x2a\xbe\x95\x8c\xfb\x3b\xa9"
+  "\x7c\xdc\xdf\x5d\x8b\x7c\x79\xbc\xf4\x9e\x83\xb8\x7a\x79\xe9\x7d"
+  "\x54\x3e\xee\x67\x54\xe0\x8a\xfb\x99\x1b\x90\x0f\xf7\x0f\xe4\xe1"
+  "\x8a\xfb\x5c\xb4\x69\x6e\x21\x2f\xb5\xd9\xf1\x9c\xf1\xd2\x55\xf8"
+  "\xde\xa3\xb8\x5f\xed\xc1\x73\xdc\xaf\xc1\xfb\xc9\xb8\x2f\x48\xe5"
+  "\x5b\xe7\xe1\x7e\x2d\xb5\x75\x1d\x2f\x2d\xc2\x77\x1e\x0d\xe5\xa5"
+  "\xeb\xa8\xcd\xb8\x2f\x9e\x8c\x7c\xb8\xff\x5f\x54\x1f\xdc\xaf\xc7"
+  "\x7b\xf3\x70\xff\x5b\xd0\x60\x6e\x09\x2f\x2d\x9d\x88\x7c\xa0\xf5"
+  "\xe6\x50\x5c\x71\xff\xcc\x09\xe4\xc3\xfd\x36\xd0\x30\x19\xf7\xcf"
+  "\xe6\x20\x3f\xee\x2b\xa8\xbd\x1b\x78\xe9\x2e\x13\xf2\x45\xf0\xd2"
+  "\xe7\xdb\x71\xc5\xfd\x6e\x07\xf2\xe1\xfe\xf7\xa0\x5f\x32\xee\x5f"
+  "\xca\x44\xfe\x88\x81\xfb\x73\x9f\x8b\xaf\x0d\x43\x5d\x0f\xb4\xf3"
+  "\xb5\xc3\x71\xfd\x4b\x05\x5f\x3b\xcc\xc2\x4b\xdf\x9c\x8e\x74\x5c"
+  "\x0f\x96\xe0\x3e\x4e\xbd\xc7\xf5\x8d\x1c\xdc\xc7\xab\xf7\xb8\x1e"
+  "\x4a\xc5\xfd\x44\xf5\x1e\xd7\xc3\x74\x3f\x89\x97\xd6\xe0\x1a\x86"
+  "\xeb\x61\x94\x3f\x6c\xb2\x7a\x8f\xeb\x3b\x71\xb8\x82\x96\x6f\x99"
+  "\x90\x9e\x80\x6b\x03\xee\x71\x7d\xbb\x1c\xf7\xd3\x70\xf5\xe2\x7e"
+  "\x9a\x7b\xc2\xbd\xf1\x34\x56\x95\xd1\xe3\xe3\xf9\xe8\xf9\xee\x82"
+  "\x2e\xa6\xa7\x31\x4a\x31\x0d\xcc\xb9\x6c\x5c\x93\xee\xda\x37\xaa"
+  "\xf2\x5d\x7a\xca\xe3\xdb\x36\xd7\xaa\x8c\x9e\x4b\xfa\xe8\x30\xe4"
+  "\x1b\xde\xa2\xfb\x21\xad\xaf\xcc\x99\xe7\x12\x71\xd5\x54\x3f\x6c"
+  "\x61\x78\xe7\x14\xf8\x86\x49\x14\x8b\x1a\x74\xdb\xcb\x8b\x86\x9d"
+  "\x05\xbd\xe2\x78\xd1\xe5\x4d\xb8\xe2\x3e\xf2\x03\xd0\x0b\xf7\x3f"
+  "\xfd\x0d\xae\xb8\x7f\x74\x0a\xe8\x16\xd7\x5d\xfc\xc3\x69\x2e\x9d"
+  "\x59\xac\x81\xfc\x95\x8c\x2a\x83\x97\x03\x8f\xb0\x26\x3f\xbf\x3e"
+  "\xde\xe0\x75\x60\xbc\x2f\x36\x1a\xc8\x9f\xd8\xef\xee\x43\x5d\x7f"
+  "\x94\x40\x75\xa2\x18\x27\xbc\x37\x56\x2f\xbf\x7d\x39\x6f\xd2\xfd"
+  "\xf0\x49\xd2\x89\xf2\xd1\x53\x06\x7b\xbe\x59\x3c\xbf\x76\x7d\x95"
+  "\x7c\x1e\xce\xfc\xcf\x1f\xa5\xe7\xaf\x19\x48\x8f\x7d\xdd\x2f\xc5"
+  "\x73\x67\x67\xab\xda\xae\x10\x7a\x76\x9c\xf2\xba\x74\x3f\x74\x4b"
+  "\x1d\xd7\xb5\x9d\xbc\x28\x84\x75\x18\xe7\xad\xeb\x2e\x8e\x65\x2e"
+  "\xdd\x38\xaf\xca\x63\x97\x71\xe3\x9c\x72\x79\xe6\x3e\x6d\x30\x7f"
+  "\x20\xe1\x4a\x59\x76\xf9\xc6\x22\x5e\x4f\x72\x2b\xd6\x1f\xbd\x39"
+  "\x3f\xb6\xba\x49\x37\xa1\x76\x07\xe9\x23\xa2\x4b\xac\x74\x86\xa8"
+  "\x49\x17\xbb\xb9\x77\xcb\xbc\x5a\xf3\x2a\x03\xbe\x3f\xe1\x78\x81"
+  "\x87\x77\x39\xf2\xa7\x60\x9d\xa4\xf4\xf9\xe1\xc2\x2e\x5d\xe6\xe9"
+  "\x94\xb6\x44\xe2\xb7\x4b\xea\x56\x27\xd4\xd2\xbb\x81\x72\x82\xaf"
+  "\xf8\x94\x57\x19\x5d\x52\x28\xf7\xc2\x62\xb7\xbe\xa1\xb8\xf4\x86"
+  "\x1c\x36\xcc\xbc\xea\x4d\x94\x1f\xdb\x18\x2c\x53\x6a\x79\xc5\xb3"
+  "\xb7\x0e\x21\xef\x76\xa1\xff\x89\x6d\xd7\xf4\xc5\x1c\x6d\xf8\xad"
+  "\xe4\xa7\x28\x66\x69\xa8\xe4\x0b\x27\x64\x91\x9f\x47\x6f\xf4\x13"
+  "\x85\xde\xb2\xf1\x66\x5f\x59\x89\x95\x6f\x2b\x29\x1c\xe9\xd5\x31"
+  "\x61\xd3\xaf\x9b\xf0\xfc\x4d\x1e\xd2\xcb\xbd\x47\x79\x1f\x51\xc2"
+  "\xdc\xd3\x6f\xb4\x31\xbd\x23\xfb\x13\xba\x7f\x96\x17\xf7\x16\x3a"
+  "\xdb\x1b\x18\xf9\xaa\xc5\x7d\x39\xff\x4d\xd4\x09\x65\x44\x58\xed"
+  "\x4e\xe2\x67\x6d\xa4\x4f\xfa\x80\xd2\xaf\x46\xbf\x40\x6e\x98\x60"
+  "\xd3\xea\x42\xbe\xea\x37\x82\x76\xc4\x6b\xd2\x19\xec\x14\x9f\x8f"
+  "\x7c\x20\x81\x1f\x9c\x50\x2b\xfb\x6b\x42\x32\x61\xbe\xfa\xdd\xd7"
+  "\x94\xa8\x79\xd5\x75\xc9\xb4\xdf\x1a\x4e\x3e\x65\xba\xc4\x99\x4d"
+  "\x2f\xc5\x97\xa3\x75\x56\xe6\x0d\xec\xbb\x85\xea\x59\xd5\x85\x4b"
+  "\x72\xb2\x9f\x34\x2f\x5b\xb8\x2a\xe3\xf6\x09\xcb\xe3\xcc\xd9\x36"
+  "\x73\xb6\x88\x67\x2c\x12\xd2\xe3\xcc\xcb\xb2\x96\xe6\x98\x73\x56"
+  "\x5a\x33\x2e\x8c\x57\x6b\xe2\xc6\x79\x65\x92\x07\xfc\xb1\xe0\x75"
+  "\x79\xe5\x7a\x4b\x4e\x1e\x57\xcc\xd7\x0e\x07\x8f\x7f\x5d\xd6\xf9"
+  "\xb0\x09\x0d\x74\x7e\x5d\x29\x32\x33\x35\xe6\x72\xc4\xb3\x51\x8c"
+  "\xce\x86\x84\x77\x17\x5f\x97\xee\xdf\x43\xf9\xf1\x5e\xa9\xef\xb8"
+  "\xce\xe6\xd2\xc5\x0a\xbf\x1b\x65\x9a\x9f\x2a\xf5\x99\xdc\x83\xb8"
+  "\xae\x1c\xb2\x9f\xf4\x9b\x51\x59\x52\x22\x79\xc7\xeb\x84\xdf\x2d"
+  "\x6e\x5e\x6f\xe1\xbb\xef\x8b\x07\x2f\xa5\xa3\xb1\x2a\xe2\xba\xb2"
+  "\xb3\xe2\xfc\x2a\xdf\x9a\x65\xa7\xb3\xe3\xbe\x6d\xf3\x8d\xca\xe8"
+  "\x2c\xbb\xf2\xc2\x7d\xee\x82\xe7\x99\xfe\x55\x60\x41\xa8\x19\xf3"
+  "\xe1\x5a\x36\xee\xcd\xfc\x56\x3d\xea\xfc\xf1\x9b\xf9\x0d\x7a\x5e"
+  "\x36\xbf\xb5\x23\x76\x9e\xc9\x03\x1e\x51\xd2\xdf\xc3\xfe\x3a\x8d"
+  "\x91\x0c\x54\xdd\x39\x6a\xf9\xa4\xce\x51\xf3\x3c\x9e\xad\x6b\x2a"
+  "\x1d\xd7\xde\xc2\xee\xbc\x9e\x7f\xf3\x4e\x0d\xe9\xaa\x7e\x5c\xf6"
+  "\xce\x34\xd2\x15\xce\xdb\xe0\x31\xce\xb3\x77\x6e\xcb\x32\x92\x9f"
+  "\x97\xf3\xdb\xd6\xb8\x7b\x46\xa7\x5a\x0f\x23\xcf\x7b\xa0\xd2\x31"
+  "\x33\xc6\xef\x78\xa6\x3f\x7f\xdd\xbd\x85\xaf\xf6\xd8\xf5\x47\x6b"
+  "\x26\x4b\xfd\x66\x2a\xe6\x8c\x18\x4f\xff\xb6\xe6\x9d\xfd\x35\x0c"
+  "\xdf\x66\xaf\xf6\x24\xea\xff\x3a\xe9\x82\xe7\x3b\xde\x89\xaf\x61"
+  "\xdd\xe4\x3b\x14\xb2\xd8\xa1\x4f\xca\x19\xdf\xb6\x6c\xd6\xbe\x55"
+  "\x1e\x7d\xb2\x8b\xe9\x8f\x37\x94\xb3\xbc\x53\xec\x0a\xef\x37\x96"
+  "\xd0\x97\xf1\xfe\x79\xf2\xdd\x77\xcc\x24\x7c\x78\xe5\x3b\x44\x9c"
+  "\x52\x43\x1d\xf8\x13\xe5\x1b\x4b\x58\xdd\x6c\x07\xc3\xf3\x1f\x79"
+  "\xef\x33\xb1\xe3\x99\x6e\xe6\x4c\xaa\x64\xe7\xf5\x09\xec\xc0\xdc"
+  "\x4a\xb6\x1d\x72\xc0\xf6\xd3\x2c\x42\xee\xd5\x5a\xc2\xbc\xbd\x96"
+  "\x50\xef\x6a\x0b\xf9\x54\xe1\xfc\x1b\xcb\x08\xe2\x47\xbd\x4b\x2d"
+  "\xe1\x75\xee\x4a\x76\x53\x2b\xb3\x9c\xd7\x33\xc3\xf9\xd5\x96\x11"
+  "\x75\xd6\x72\x94\x45\xc1\x95\x99\x8e\xfc\x39\x91\x9f\x27\xa2\xd3"
+  "\xe5\x49\x6c\x76\xbb\xee\xdf\x1e\x1a\x71\x82\x8d\x22\x7f\x82\xe4"
+  "\x0f\x8c\x7c\x95\x2a\xd1\xcb\x66\xf9\xa2\xb3\x8c\xf9\x5d\xa8\x17"
+  "\xf9\x38\x79\x25\xc3\x4e\x3c\xf2\x7c\xe0\x14\xb5\x59\xe1\x96\x11"
+  "\x29\x74\xdd\x32\xe7\x47\xc4\x27\x2b\xdd\x26\x8a\xbf\x13\x4e\xf5"
+  "\xc4\x3c\x0d\x5f\xf3\x39\x68\x59\x60\x09\x45\xbe\x08\xa4\x8f\x74"
+  "\xb6\x7b\x98\xef\x86\x8c\xca\x1b\xad\x22\xce\x6a\xf4\xce\x7c\x66"
+  "\xb4\xe7\xb3\x68\xf3\x4f\xc5\x58\x5a\xee\xdb\x97\x61\xe7\xc5\x3f"
+  "\x9f\xc5\xd7\x86\xc6\xc8\xb4\x1f\x3d\x64\xbe\x8b\x31\xf3\x2d\xf4"
+  "\xfb\x7a\x9f\xf9\x36\xf4\x61\x74\x76\x95\xe0\xe1\x85\x6c\x77\xfd"
+  "\x19\x39\xc6\xaf\xff\xea\x7c\xd8\x53\x65\x4a\xf1\x9f\xaa\x94\xb5"
+  "\xa1\x66\x8a\xc7\x7c\x5a\x77\xfd\x71\x5e\x5a\x7f\x82\x97\xad\x11"
+  "\x63\x11\xf7\xef\x9e\x0f\x9b\x08\x1e\xe1\xfd\x49\x28\x3f\xe1\xbc"
+  "\x2e\xb4\x01\x7f\x8d\xea\xfb\x0e\x6a\xb7\x6f\xf7\x7d\xe1\xd4\x6e"
+  "\x11\xb3\x05\xed\x4a\x41\x9f\xf1\xd1\xd9\xa9\xc2\x8f\x79\x2f\xe8"
+  "\xab\xc6\xb4\x24\x7a\x10\x0d\x94\x5e\xcb\x08\xd1\xd6\x5e\x4b\x04"
+  "\xe8\x4b\xbe\x43\x0d\xf9\x69\x78\x67\x5b\x76\x0e\x9e\x8d\x3c\x1f"
+  "\x9d\xbd\x87\x62\x27\x39\xad\x6e\xe6\xdb\x9a\x6d\x25\xdf\x58\xcf"
+  "\xae\xc2\x9c\x1b\x95\x0d\x7e\x22\x3b\x4f\x9d\x5b\x8c\xea\xa9\x94"
+  "\xbe\xbf\xee\x3c\x9d\x03\x40\xdd\x50\x3f\xac\xa1\xa1\x8d\x2e\xdd"
+  "\xf5\xd3\xce\x4f\xb8\xcf\x84\xab\x09\x75\x35\xf3\xe2\x07\x0a\xe9"
+  "\x37\x9e\x99\x41\x9b\x1b\x88\x0e\x44\x0f\x49\x8b\x1f\x4d\xf0\xd3"
+  "\x62\xcd\x41\xe4\x8b\x56\x8a\x5f\x9b\x8d\x6b\x27\x2f\x9e\x9e\x10"
+  "\x90\x6f\x86\x3f\xdf\xfa\x54\x99\xef\x60\xa8\xcc\x37\xa7\x1a\xcf"
+  "\xbf\x92\xf4\xfe\xd1\xe6\x0b\xe9\xfd\xa3\xf5\xfe\x77\xb3\xc3\xe5"
+  "\xbb\x2f\x94\xc9\x77\x7f\x49\xef\xbe\xd5\xaf\x4e\x07\xfc\xf9\xb3"
+  "\x26\xcb\xfc\xcf\x4f\x93\xf9\x27\xaf\x0b\xc8\xf7\xb9\x3f\xdf\x8a"
+  "\xa3\x32\xdf\xcb\x8d\x32\xdf\x5d\xcd\x18\x1b\x57\x5f\x58\x97\x1f"
+  "\x8f\xf2\xbf\xb3\x75\xba\x7c\xe7\x1d\x8f\x7c\x27\x2d\x07\xcf\x67"
+  "\x04\xd7\xe5\xc7\x77\xfa\xf3\x6f\x52\xdb\xfd\x56\x89\xcc\x9f\x6c"
+  "\x0e\xc8\xb7\x58\xcd\x87\xe7\xb5\x94\xaf\xf5\x7c\xd8\xf6\x78\x99"
+  "\xef\x71\x07\x8d\x47\xe4\xd9\xa8\x14\xdf\xe6\x3a\x1f\xf6\xb3\x5a"
+  "\x97\xce\xd2\x88\xbe\x89\xa1\x2b\xfa\x2e\x46\xb1\xcf\xdb\x80\xdf"
+  "\xb3\x69\xff\x82\x30\xd7\xa5\xbb\x6e\x22\x70\xd7\x37\xf0\x7e\xe8"
+  "\x8f\x6b\xfb\xf4\x65\x0a\xf8\x87\xad\x73\x13\x06\xe4\xe9\xb6\x3c"
+  "\x54\x41\x76\x0c\x84\x29\x2d\xba\xb8\xdb\xc9\x67\x1a\x2f\x48\x54"
+  "\x75\x54\x71\x42\x3f\x49\xfe\x1d\x48\x8f\xa9\xa6\x89\x38\x06\x0a"
+  "\xc6\x26\xe4\xcc\x6a\xf2\x53\x47\x7a\x4b\xac\x51\xa0\x6d\xdc\x2c"
+  "\xe0\xc4\xb0\x67\xf4\x4a\x15\xfe\xaa\xf1\xe7\x78\x86\xf4\x99\x45"
+  "\xec\x4e\x4d\xd7\x3b\x70\x5d\xe3\xb0\xfe\x6d\x6c\xf0\xeb\xbb\xe2"
+  "\x40\xbb\x1f\xbb\x86\x6e\x03\x1c\x37\x68\xfc\x03\x11\x9f\x98\x78"
+  "\xa5\x6d\x73\xed\x76\x45\xc6\x3c\xc7\x5c\x04\x9f\x17\x77\x12\x6b"
+  "\x7e\xa1\xf0\x85\x5a\xb6\xd8\xa8\xc4\x62\x2d\xf9\x9a\x85\x38\xf3"
+  "\x5a\x59\x95\xd2\xaa\xb7\xf7\xb0\xd0\x3a\xac\xa7\x94\xbf\x0a\xbc"
+  "\x83\x79\x09\xf1\x50\x71\x5d\xf6\x73\x6a\x79\x95\xeb\xe3\x0b\x16"
+  "\xcb\xd8\xce\xc4\x6f\xd2\x1a\x04\xdc\x89\x10\xf1\xbe\x96\x0c\x47"
+  "\xde\x1b\xae\xc7\xef\x70\xca\x7b\xfe\xba\x7b\xaa\xce\xff\xfb\xfa"
+  "\xf8\x9e\x6d\x29\xd6\x9e\xeb\xa6\xdb\x7b\x47\x2f\x36\xf6\x6e\x7b"
+  "\xc2\xee\xfd\xf7\x92\x4a\xef\x75\xf7\xc5\xfb\x46\xa7\xb8\xf1\x6d"
+  "\xac\x4f\xe5\xfa\x57\x94\x2a\xfd\x2b\xf9\x0e\x3d\x95\xfb\x66\xfe"
+  "\x1e\xfd\xa1\xfc\x7a\xfd\x21\xa5\x5a\xff\x66\xbe\x1d\xd7\x4a\x8a"
+  "\xfd\x04\xbe\xf6\x86\x95\x87\xf2\x8f\x62\x7d\xbc\xa1\x1a\xf4\xaa"
+  "\xd6\xf4\xaa\x7c\x8a\x97\xd5\xed\xf1\xb2\x23\x39\x5d\xcc\x1d\x39"
+  "\xaf\x0c\x7f\xe5\xee\x51\xd9\xf8\x5b\x53\x29\xea\x3c\x3a\x47\xb4"
+  "\x91\xce\x73\x1d\x52\x64\x9d\x55\x7a\x50\x99\x9f\xef\x54\xe8\xcc"
+  "\x97\xea\x27\x56\x77\x63\xc5\x05\x7e\x62\xf5\x32\xee\x58\x9f\xaf"
+  "\xd8\xff\x0a\x3f\xb1\xaa\x4e\x82\xfc\xc4\x42\x16\xae\x57\x65\x61"
+  "\x87\xea\x3f\x29\x82\xe4\x5f\xe1\x3f\xc9\xe6\x10\x3e\x90\x84\x9f"
+  "\x90\xad\x8b\xdc\xc4\x87\x76\x17\xdf\xd8\xa0\xc9\xb9\xc4\x5b\xf9"
+  "\x36\xcf\xdb\x8d\xbf\x4a\xa4\xbb\x5d\xba\x0f\x92\xb5\x74\xbe\xed"
+  "\x5a\x92\x23\x42\x7c\x3c\xf3\x17\xdd\x74\x56\x89\x67\xde\xe1\xdb"
+  "\x3a\x1f\xf8\xba\xa6\x10\x69\x93\xf1\x77\xbb\x6f\xeb\xb5\x13\xf1"
+  "\x37\x09\x7f\x93\xf1\x97\x80\xbf\x69\xf8\x4b\xc4\xdf\x2c\xfc\xcd"
+  "\xc6\x5f\x12\xfe\x92\xf1\x97\x8a\xbf\x74\x65\xeb\xb5\xd3\xc9\xef"
+  "\x1d\xca\xb6\x62\x1c\x98\xb4\x72\xfd\xf4\xbe\xe9\x21\xb4\x3f\x81"
+  "\xf8\x3e\x3e\xb2\xde\xcd\x31\xdf\xf9\xef\xee\x9d\x24\xea\x4f\xb8"
+  "\xfc\xbb\x79\x26\xf7\xf8\xf5\x66\xf7\xa8\x1c\xb3\x7b\x7c\x49\x89"
+  "\x3b\x72\x73\x3d\xfe\x1a\xf0\xe7\x72\x6f\xcd\xae\x42\x9f\x96\xb8"
+  "\x47\x2d\x4b\xe8\x2e\xbe\x09\xb8\xfc\xd3\x3d\x52\x7f\x75\x13\xe6"
+  "\xe2\x4f\x8f\xaa\xbf\x4f\xb8\x74\xb7\xc6\xd3\x6f\x94\x01\x99\xff"
+  "\xa6\x66\x97\x6e\xa2\xf4\x6f\x3d\x3a\xdb\xa1\x9e\x73\x2a\x44\xba"
+  "\xd7\x15\xfa\xcb\x06\x99\xef\x89\x42\xda\x8f\xea\x2e\x8e\x37\x6a"
+  "\xf3\x30\x28\xc6\xc3\x63\xd6\x94\xc5\x69\xb6\x94\x65\x59\x0b\x1f"
+  "\xcb\x58\x76\x9b\x79\x42\xba\xd9\xb2\x30\xfb\xc9\x94\x27\x97\x67"
+  "\x2c\xcf\x10\x2c\x24\x92\xae\x0f\xda\x8f\xa2\x58\xbe\xcc\x0b\x79"
+  "\x68\x64\x33\xe7\xb4\x76\x4f\xef\x44\x1f\x5d\xbb\x3e\xfe\xe0\x69"
+  "\xb7\xde\x07\x1e\x2e\xa2\xb9\x10\x73\x73\xb1\xf1\xe0\x69\x8f\x3e"
+  "\xa2\xd9\xcc\x38\xe6\x03\x3d\x73\x36\xd7\xab\x3c\xdd\x07\xac\x96"
+  "\x78\x3a\xe4\x79\x65\x89\x47\x7f\x3f\xbd\xff\xc2\x7d\xf1\xaf\xe2"
+  "\x37\xdf\x96\x65\xa7\xf7\x38\xf8\x3c\x71\x05\x9f\x27\xef\x53\xac"
+  "\x87\xc4\xf5\x09\xfb\x21\x91\x2f\xc5\xfd\x26\x5d\xcf\xe5\xf1\x5a"
+  "\x94\x4b\xba\x3a\xfe\xc2\x3d\x55\x22\xcf\x0b\xd3\x65\x1e\xcc\xc5"
+  "\x26\xdd\xcd\x95\x94\x4f\xc8\x56\xa8\xe3\xab\xa8\x47\xc1\x72\x16"
+  "\xaa\xcd\x6f\x92\xa5\xfa\xe6\x78\x2e\xf1\xbc\x37\x5f\x46\x73\x9c"
+  "\xea\xc3\x31\xa7\xf7\xe1\xdd\x57\x96\xb8\xc5\xfb\x90\x31\x43\x48"
+  "\xb6\x24\x1c\x21\xfc\x70\xe6\xd5\x8b\xf7\xab\x94\x7a\x3d\xc9\x63"
+  "\x78\xf7\x1e\x7a\x56\x01\x3e\xb5\x42\xc8\x25\x37\xaf\xd3\x64\x81"
+  "\x0d\xa3\xa5\x0f\xa5\x88\x54\x46\x67\xbd\xc7\x9d\xd6\xc5\xcf\x23"
+  "\xfa\x11\xbd\x68\xff\x97\x17\xc7\xc7\x54\x44\xb1\xd0\x1d\x51\x2c"
+  "\xdc\x3b\xaa\xc4\x26\xf7\x00\x6e\xae\xd1\xf8\xeb\xce\xe8\x92\x20"
+  "\xbf\x85\xb2\xbf\xcc\x19\x4b\x68\x27\x23\x5d\x6c\x19\xa6\x2d\x5b"
+  "\xb6\x7c\x71\x86\x39\x23\xed\xb1\x4c\xb3\x78\x6c\x5e\xbe\x0c\x59"
+  "\x16\xe6\x2c\x33\x2f\x5d\xb1\xc4\xbc\x78\xd9\x42\x92\x14\x32\xb2"
+  "\xb3\x97\x5b\x73\x46\x30\xf9\xa6\x79\xf1\xf2\xac\x9c\x85\x56\xfc"
+  "\x58\x96\xb1\x24\xdd\x2c\x7a\x7d\x19\x8a\xca\xca\x32\xab\x5f\x58"
+  "\x96\x99\x96\x4d\x03\x61\xc9\xaf\x91\x29\xe0\xfd\x60\x39\x22\x82"
+  "\x7c\x54\xd1\xda\x73\x5a\x77\xeb\x84\x9a\x50\xd0\xba\xac\xc4\x46"
+  "\x36\x0b\xb8\x8f\x15\xb2\x65\xf1\xcd\x27\x68\x7f\xe7\x19\xb4\xb1"
+  "\x63\xc2\x3c\x53\x77\xf1\x2d\x95\x5a\xdb\xc8\xcf\xb9\xf0\xf3\x47"
+  "\x3e\x24\x75\xb7\x46\x8a\xf3\x77\x98\x0f\xc2\xa6\xa5\xf8\xe6\x2f"
+  "\x25\x2d\x6e\xa9\x0f\xf4\x11\x2d\xfc\x0d\xea\x6e\xf9\x4a\xee\x8d"
+  "\xdc\x1a\x4b\xfc\x91\xea\x97\x5d\xc7\x8b\x6f\x19\x45\xef\x28\x5b"
+  "\xd7\x94\x74\x17\xdf\x1a\xee\x97\x51\x6e\x71\x51\x7e\x91\xaf\xf8"
+  "\x96\x5b\xf8\xa8\xec\x2a\xa4\xd5\x50\xbd\x06\x59\x67\xcc\xe7\x50"
+  "\xee\xb1\x2a\xc6\x7e\x1c\xcd\x2c\xe7\xb6\xa4\xcd\xea\x8e\x9a\xb7"
+  "\xa7\xa7\x88\x0d\xef\xc1\xda\xe6\xd1\xb3\x71\xe7\x31\x2e\x56\xde"
+  "\xcc\x42\xd6\xcc\x60\xfa\xaa\x45\x55\xe4\xa7\x94\xd5\x26\x96\x33"
+  "\x67\xaa\x8b\x39\x3d\x7b\x59\xad\xa3\x89\x1d\xf7\xbe\x24\x63\x03"
+  "\xac\x22\x19\x63\xe2\x7a\xf2\x33\x55\xb0\x86\xfb\x5e\x7d\xdd\x3d"
+  "\xec\x95\xb6\x2a\xf2\xe9\x3f\xce\xe9\xfd\xcc\xe1\xcc\xdb\xcd\x9c"
+  "\x36\xa7\x83\xce\xdf\x83\x6e\xcb\x0f\xe1\xd9\x65\xb5\x78\xef\x7e"
+  "\x36\x1c\xf7\x0b\xe9\x1b\x25\xdb\x78\xc3\xfa\xd1\xbc\x71\xfd\x36"
+  "\xee\xc2\x98\x22\x1f\xfd\xad\x1b\x47\xf3\xf6\x8d\xaa\x2f\x39\x1a"
+  "\xa7\xd6\x5c\x66\x6a\xd3\x4d\x14\xfb\x71\xce\x69\xe2\x7e\x0c\xee"
+  "\xc5\xfa\xef\xb4\x6d\xa3\xfb\xb1\xb8\x37\xcb\xfb\x9d\x74\x7f\x15"
+  "\xee\xe3\xe5\xfd\x3b\x74\x1f\x83\xfb\x04\x79\x5f\xc7\xc4\x59\x74"
+  "\xdd\xc4\x59\xf2\xfe\x23\xba\x07\xed\x27\xa6\x3a\x72\xa9\xbe\x9f"
+  "\xa2\xcf\x26\x2e\x2e\x38\x09\x59\xd5\xd6\x22\xe6\xc3\x9b\xf9\x99"
+  "\xa4\xab\xc1\x7c\xb8\xf5\xcc\xe5\x8d\x24\xe7\x4e\xb4\x87\xc5\xd3"
+  "\xf5\xd6\x32\x83\x87\x0d\x07\xdf\x78\x39\x9e\xa5\x11\xed\x06\xe4"
+  "\x63\x5e\x99\x97\x32\xd3\xcb\x1d\xfc\x77\xf7\x59\xf8\xd6\xc5\x76"
+  "\xfe\xbb\xe9\x56\x2e\xd6\xba\xb9\xb3\xaa\x56\x79\x84\xaf\x58\xf0"
+  "\xea\x98\x43\x13\x45\x7c\x38\x37\x78\xdf\x41\x7c\x47\x1a\xf9\xd6"
+  "\xf9\x76\xc8\x94\xa6\x19\x16\x2f\xd9\x1c\x82\xdf\xff\x49\xda\x91"
+  "\x4c\xe2\x1d\x72\x42\x94\xdd\xd3\xad\x4a\x41\x12\xe3\xb1\xf7\x59"
+  "\x66\x64\x72\x07\xd6\x31\x9d\xd4\x9f\xf3\xcf\x28\x96\xbd\xf8\xee"
+  "\x84\xfb\x2c\xca\x8a\x4c\x8a\x49\x24\xf0\x25\x9f\xd6\xf4\x5c\xe0"
+  "\xc9\xea\x24\x83\x6f\x6b\x0e\x3b\x92\x79\x6a\x68\xf1\xbd\x74\x3f"
+  "\x49\x1d\xd4\xce\x09\x75\xf2\xf1\x24\xe6\xc5\x77\xbc\x68\x2b\xf1"
+  "\x0f\xaf\x28\x47\xf5\xe0\x63\x2c\xfb\x16\x34\x0c\xe3\x2b\x92\x0c"
+  "\x68\xd3\xcd\x4e\x4b\x17\xab\xeb\xa1\xb9\xf2\x53\xf3\x11\x1b\x63"
+  "\x77\xda\xbc\x0e\x83\x5b\xf8\xb8\x35\x5a\x17\xb1\x6b\xf8\xa8\xf9"
+  "\xf6\x36\xdd\x4f\xad\xf7\xe7\xa1\x0d\x68\xfb\xa1\xa6\x86\x50\x05"
+  "\xed\xb8\x49\xd2\x8d\xde\x9b\x0d\xda\x9a\x34\x19\x67\x68\xf5\xff"
+  "\xa9\x18\x37\xca\xb2\x24\x46\xe7\x02\x5f\x05\xcf\xa2\xf4\x26\x19"
+  "\x14\xac\x47\xf4\xec\x88\xe5\x6b\x46\xdf\x94\xb4\xfe\xa9\xf4\xb9"
+  "\x15\x0b\x3a\xe3\xfb\xe4\x5b\x57\xa3\x2b\xf2\xce\xf6\xf5\x66\x0e"
+  "\xdc\xff\xdb\x96\xd5\xa3\x7e\xe8\xbb\x6b\x07\xb4\xc3\xe1\xdb\xc6"
+  "\x73\x39\x3e\xee\x4d\xc4\x5f\x12\x7f\xbe\xc4\xee\x9e\x70\x6f\xa6"
+  "\x88\x19\xb9\xed\x89\x3e\xdd\x12\xe6\x1b\xc6\xc8\x4f\xcf\x54\xe5"
+  "\xb7\x0e\xec\x5b\xd4\x5e\x9d\x24\x62\x75\x0d\xfb\x8c\x1b\x7c\x14"
+  "\x83\xb6\x8b\xfc\x34\x27\x1d\xb1\x74\x0e\xb1\x4f\x7f\x36\x71\xb0"
+  "\x3e\xa5\xf2\xef\xbc\x9e\xf7\x0e\xb1\xbc\x41\xe3\x37\x82\xb6\x46"
+  "\x1e\x7d\xad\xb9\x87\x4f\xd3\x49\x39\xe4\xe7\xd7\x13\xad\xbc\x58"
+  "\x47\x56\x7d\xc8\xf4\x1e\xac\x97\x2f\xcd\x29\xd1\xc7\xa5\x52\xfc"
+  "\x79\x56\xf8\x6e\x7d\x0d\x9b\x39\x9d\x15\x1c\xcf\x3c\xcb\xb4\x18"
+  "\x5c\x7c\x74\x96\xfd\xc5\x39\x6e\x3d\xed\x61\x51\xcc\x2d\x21\xb3"
+  "\x6f\x7b\xb2\xfe\xe5\x8f\x3c\x24\xc7\x3a\xf6\x7d\xe4\xd6\x7b\x3b"
+  "\x92\xcc\xc2\x4f\x34\x64\x89\x82\x4c\xae\xf4\xed\x6b\x51\x2c\x01"
+  "\xfb\x9c\x78\x8a\x69\x7c\x6c\x56\xbd\x38\xab\x7d\x2c\xa9\x86\x1d"
+  "\x6b\x2c\x67\xb5\xcd\x27\xe9\x7c\xe1\xf3\xc7\x92\xec\xc4\x53\x8e"
+  "\xf4\x82\x6f\xdc\x0e\xbe\x11\xf3\xf5\x32\xc5\x58\x9d\xa4\xed\x6d"
+  "\xd1\x3e\x97\xc6\x33\x7a\x31\x47\x2b\xd4\x38\x5c\xde\xe2\x9f\x99"
+  "\x2a\xd4\x7d\x2e\x8a\xcf\xf5\x5c\x2e\x8b\x7d\x4e\xaf\x24\x0d\xb4"
+  "\xaf\x35\xf2\x49\xe1\xcb\xc5\xa4\x44\x56\x27\x69\x71\xba\xee\x7f"
+  "\xd2\xcc\xfe\x82\xb6\x1f\xb1\x0c\x75\x4e\x4e\xea\x24\x7a\x7b\x31"
+  "\xee\xbc\x18\x73\x5e\xd0\x13\x7d\xd0\x8c\x7e\x1b\x50\x1e\xd3\xfa"
+  "\xa0\xb7\x40\xeb\x83\xdb\x0e\x88\x3e\x80\x1c\xb7\xfa\x11\xb5\x0f"
+  "\x3e\x41\x1f\x34\xa3\x0f\x8a\x58\xe1\x7b\xb3\x6b\xd9\xcc\x59\xe8"
+  "\x83\xf6\xb3\xe4\x63\x5c\xc6\x41\xcb\x91\xb4\x17\x7d\xf1\x89\x5b"
+  "\x5f\xd7\x29\xfb\x60\xef\x5c\xd9\x07\xaf\xcc\x75\x83\x8f\xb9\xb7"
+  "\xf0\x45\xdc\xfb\x56\x24\x99\x29\x2e\x0c\x2f\x4a\xa5\x98\xcd\xb2"
+  "\x2f\x7a\xd1\x17\xbd\xb2\x2f\xf2\x9f\x44\x5f\x9c\x68\x10\x3e\x5d"
+  "\x8e\x35\xd6\xb2\xda\xd4\x4a\x76\x1c\xb8\x84\xbe\x48\xa3\x7e\x21"
+  "\x1d\x83\x6f\xb5\x25\xea\xd9\x55\x2c\xba\x62\x15\x33\x69\xfd\xa1"
+  "\xf4\xa2\x3f\x56\xa1\x3f\x7a\xd0\x1f\x9e\xbe\xfe\x88\x16\xfd\xf1"
+  "\xb5\xda\x1f\x3d\x64\x1f\x87\xfe\xe8\x41\x7f\xf4\xa0\x3f\x8a\x64"
+  "\x7f\x10\xce\xdf\xdf\x69\xe0\xca\x3f\x2c\x6c\x67\xdb\x00\xfd\xb1"
+  "\x5a\xed\x8f\x4f\xfe\x99\xfe\xb8\x6d\xdd\x85\xfd\xf1\xf3\xcc\x4b"
+  "\xf5\x87\x7f\x4e\x4c\x9e\x47\xfd\xd1\x5b\xa9\xce\x89\xeb\x68\x4e"
+  "\x14\xea\x7f\x8c\xb5\x88\x68\xfa\x6e\xfd\x41\x31\x27\xd0\xd6\xc2"
+  "\x17\xe7\x78\xf4\xb5\xcd\xe8\x97\x74\xf4\xcb\x2a\x7f\xbf\xc8\xfe"
+  "\xc8\xb2\xef\xf9\x48\xd2\xdf\x7c\x2f\xad\x19\x34\x37\xa8\x7f\xd0"
+  "\x4f\x98\x3f\x03\xc5\xb0\x0b\xdc\xff\x45\x99\x0a\xcd\x13\x9a\x23"
+  "\x34\x1f\x8e\x67\x9e\x14\x31\xc1\x8f\xcd\x3a\xca\x68\x1f\xf8\x58"
+  "\xd2\x41\xf4\x55\x39\xf3\xad\x40\xdf\xe4\x62\x9e\xe8\xd8\x78\x8a"
+  "\x65\x77\x2c\xa9\x84\xf8\x05\x23\xc6\xfc\x65\x3e\xf4\x93\xaf\xdb"
+  "\x34\x62\x03\xe4\xac\x5d\xb9\xfe\x79\xb3\x53\x8d\xdb\xcb\xc3\x7e"
+  "\x66\x42\x7a\xa8\x17\x7d\x84\xb9\x13\x34\x67\xfa\xe2\xf9\x7e\x61"
+  "\x61\x3b\x9a\x58\xf8\x15\x0b\x65\x1f\xf9\x02\xe6\xcc\x8c\x85\x34"
+  "\x67\x0a\xd1\x47\x1f\x0e\xb1\x8f\x26\x8b\x7d\x5f\x3e\x1a\x58\x3d"
+  "\xea\x5a\x33\xd6\x49\xf4\xd1\x6d\x9e\xc1\xfa\xc8\xb7\xfb\xde\x44"
+  "\x9f\x71\x9e\x9d\x7c\x9d\x2b\x4b\x67\xeb\x14\xc8\x50\x3d\x90\x5d"
+  "\x8f\xb9\xbd\x2c\x6f\x1e\xd3\xaf\x3a\xc9\xc2\x9c\xb3\x3f\x60\x4e"
+  "\x57\x35\x23\xbf\xc1\xa4\xfb\xa6\xf8\x01\x4e\x6f\x35\xf0\x2a\x5f"
+  "\xdc\xef\x10\xf7\x6e\xb6\x7a\x1e\x0b\x11\x31\x2e\x93\x2a\xd9\x06"
+  "\x8c\xcf\x7d\x73\x2b\xf5\x4a\xd9\xfc\x56\x6e\xa4\xb8\x27\xcc\x41"
+  "\xe7\x9d\x0a\x56\xb2\x88\xe3\x99\xb5\xe4\x67\xee\xb3\x02\x1b\xff"
+  "\xbc\xae\x13\x65\xba\x79\x8f\x0f\x6b\xc6\xce\x22\x5e\x4d\xbe\xe0"
+  "\x6f\xa2\x35\x82\x7c\x60\xe8\x6e\xff\x39\xf1\x22\xa4\x03\x74\xe4"
+  "\x3f\x07\xde\xeb\x76\xe1\xbf\x1d\x69\xba\xe3\x8b\xc8\x46\x23\x61"
+  "\x1f\xd5\x4b\xea\xe3\xe5\xf5\x26\x8a\x05\x38\x3a\x7f\xea\x1b\xf9"
+  "\xee\x50\x3b\x64\x62\xf0\x68\x54\xce\x7a\x2e\xe5\xc3\x4c\xe7\x09"
+  "\x8f\xd0\xc5\xba\x0b\x32\xc3\xec\xab\xc8\x47\x2f\xf9\x95\xa7\x35"
+  "\x3b\x61\x1e\xc5\xe9\xe5\xbb\xb1\x5e\x8d\x7e\x82\x55\x2d\x70\xeb"
+  "\xfd\xeb\xf2\xed\xfb\xb1\x9e\x65\xde\x69\xe1\x05\xe4\x7f\xff\x10"
+  "\xda\x45\x72\xd0\x4b\x4d\x1e\x81\x29\x2f\x2f\x28\xd1\x93\xae\xc8"
+  "\x03\x7c\xa8\xfd\xe8\x3f\x44\xdc\xd1\x16\xdd\x2f\x8e\xbc\x97\xe4"
+  "\x65\xf4\xfd\x87\xae\xa7\xfd\x96\xdb\x3d\xe7\xf5\x6f\x77\x9e\x0f"
+  "\xfb\x59\x4e\x41\xb3\x3f\xe6\x62\x60\x6c\x45\xc2\x99\x7d\x0b\x50"
+  "\x26\xe1\x4c\x53\xa1\x5e\x62\x4b\x02\xe9\x2b\xc3\xfb\x63\xcb\xf1"
+  "\xf6\xaf\x59\x3e\xc6\xf1\xf1\xcc\x4a\x11\x23\x61\x24\xf0\x5d\x59"
+  "\x0d\x3c\xe9\xb5\x44\xed\x00\x9e\x10\x0e\xec\x04\x7e\x28\xab\x4d"
+  "\x23\x4a\x7b\x58\x9c\x86\x23\xc4\x7b\xd1\x75\x1e\xc6\xa8\xe1\x28"
+  "\xd2\xd0\x4f\x0a\x70\x1d\x78\x62\xd9\xbe\x8a\xc5\x6e\xc7\x18\xdd"
+  "\x41\x38\x02\xbe\xf8\x7e\x2b\x70\x64\x05\x70\x24\x57\xc4\xbe\x35"
+  "\xed\xd4\x4b\xfc\x78\xbd\xa9\x44\x6f\xd7\x62\x5f\x0b\xfa\xde\xf1"
+  "\x48\x1d\x8d\x8f\xd4\x42\x71\x9e\xcd\x47\xeb\xd3\xea\xa4\x90\xba"
+  "\x4e\x8c\x91\x6d\x6b\xdc\x94\x26\xe6\xed\x8a\xcc\x11\x8a\x1c\x6b"
+  "\x09\x44\x93\x5d\xa7\x59\xbc\x88\x0f\xf9\x8d\x69\xc4\xa6\x25\x2c"
+  "\x6e\xe7\x69\x16\xbb\x73\x09\xb3\x60\xbe\xea\x77\xa2\x0e\xf3\x9f"
+  "\x34\x32\x11\x8b\x20\xec\x67\x79\x48\x1f\x30\x16\x01\xf8\x6a\xd3"
+  "\x4e\x9a\x33\x4b\x2d\x7d\x75\xf2\xda\x9f\x71\xfb\x40\x3b\xe1\x67"
+  "\x49\x77\xc7\x6b\xd2\xae\xfa\x2e\x8b\xe4\xf3\xef\x68\x96\xb6\x4d"
+  "\xf7\x51\xdc\xf4\xe1\x6d\xba\x3b\x9e\xe5\x5b\x7e\x65\xb6\xae\x62"
+  "\xba\x36\xed\x19\x78\x4f\x05\x7d\x75\x63\x21\x2b\x54\x22\x0f\x25"
+  "\x3a\x6d\xe0\x9d\xc8\xaf\xf2\x90\xe6\xe1\x1d\xc2\xb6\xd7\x67\x7f"
+  "\x86\x64\xa8\x04\x65\xcb\x33\xde\x5d\x6d\x2c\x9e\x3f\x81\xfe\x58"
+  "\x84\xb6\xb6\xb1\xd8\x8a\x36\xb4\x75\x85\x6c\xab\x16\xeb\x5b\x29"
+  "\x7a\xdb\x8b\x67\x17\x8d\xe3\xe3\x7e\x82\xe2\xf8\x4c\xf1\x00\xc3"
+  "\x7e\xc0\xaf\x65\xec\x78\xbb\xf0\x71\xd1\xed\xf4\x9e\x64\xf4\x5d"
+  "\xd2\x1f\x39\xcf\x8a\x31\xbd\x91\xc6\xb2\x52\x59\x62\x4f\x69\xc4"
+  "\xd8\xee\xce\x64\x1c\xbf\x0f\x35\xb9\xc9\xa7\x84\xe0\xf9\x5c\xba"
+  "\xdb\x0f\x12\x9f\xf6\x26\xd2\x68\xec\x07\x8c\xf9\x83\x34\xe6\xe9"
+  "\xb9\x18\xf7\x78\xcf\xd9\x78\x8a\x51\x79\x81\xe5\x50\xff\x6b\x65"
+  "\xb5\xe8\x7e\xf9\x24\x95\x45\x63\x81\xf4\x3c\x34\xd7\x64\xdf\x57"
+  "\x93\x5d\xb9\x89\x8f\x4e\xb5\xca\x7b\x37\xf9\x2a\x31\xd2\x18\x10"
+  "\x63\x05\xf8\x4d\x3e\x50\x39\x4f\x0a\xc1\x38\xa3\x7a\x8e\x40\x7f"
+  "\xc7\x6b\xe3\x02\x69\xd1\xfd\xc7\xc6\xc8\xb5\x46\x92\x69\xa2\xe9"
+  "\xf7\xb7\x1d\x1f\x43\xeb\xbf\x5f\x5a\x07\xb5\x99\x8b\xbd\x57\xc4"
+  "\x86\x20\xdc\xf4\x75\x04\x60\x66\xbb\xc4\x4c\xc2\x24\x0d\x37\x05"
+  "\x36\x09\x5f\xf2\xd5\x64\x5f\x9b\x29\xea\x38\x44\xdc\x3c\xde\xee"
+  "\xc7\xcd\xfb\xad\x01\xb8\xd9\xce\x7b\x94\x09\x03\xe1\xe6\x94\x27"
+  "\x83\x71\x73\xca\xf2\x60\xdc\xbc\xf3\xe3\xfe\xb8\x79\x21\x66\x4e"
+  "\xf9\xe3\x40\x78\x09\x39\x66\x5c\x9b\xee\xce\x92\xc1\xb1\x72\x8a"
+  "\x6b\xe8\x58\x39\xf5\x4c\x30\x56\x4e\x8d\xfd\xff\x2f\x56\x4e\x7b"
+  "\x3a\x08\x2b\x8d\xdf\x12\x2b\xdb\x04\x56\x46\xf3\x7f\x60\x4e\xa8"
+  "\xf8\xb1\x73\xd1\x20\x58\xb9\xe8\x12\x73\xe1\x89\xc1\xb0\x72\xda"
+  "\xc9\x60\xac\xbc\xd3\x18\x8c\x95\xd3\x8e\xf8\xb1\x52\x7d\xf6\x9d"
+  "\x60\xe5\xb4\xc6\xef\x07\x2b\xa7\x35\x0a\xac\x3c\x4d\x58\x79\xe7"
+  "\x81\x4b\x63\xe5\x94\xd6\x81\xb1\x12\xe9\x02\x2b\xa7\xb4\xfa\xb1"
+  "\xf2\xe4\x25\xb0\xf2\xae\x1d\x43\xc0\xca\x68\x81\x95\xc6\x41\xb0"
+  "\x72\x11\x68\xa5\x8e\x0b\x31\xf6\xfa\x8d\x0d\x15\x2b\x4d\x7d\x58"
+  "\xf9\x2d\xc6\xc7\xd0\xfa\xef\xae\x8a\x8b\x61\xa5\x62\x97\xfc\x25"
+  "\x61\x25\x1f\xad\x62\x65\x96\x97\xad\xfa\x18\x18\x79\xa2\x4d\xc4"
+  "\x9c\x10\xb6\xc0\xf8\xcb\x7b\x84\xb0\x28\xcb\xf8\x0a\xe8\xe5\x74"
+  "\x55\x09\x6c\x12\xe7\xb9\xa6\x13\x56\x55\x21\x6f\x79\x1f\xdf\x29"
+  "\xb0\xf3\x63\x15\x3b\x93\x55\xec\x9c\xff\x2f\x60\xe7\x5c\xea\xcb"
+  "\xbb\xf7\x9d\xd7\x6b\xd8\xb9\x05\xd8\x79\xb7\xe0\x1f\x68\x6f\x57"
+  "\x62\xe7\x7d\xd7\x6b\xf5\x22\x9d\xa6\x33\xe7\x39\x26\xeb\x75\xf6"
+  "\x42\x1c\xbd\x97\xca\x4b\x04\x7f\xd9\xce\xfa\xb0\x34\xd9\x8f\xa5"
+  "\x2d\xba\x7b\x3f\x1e\x1c\x47\x13\x2d\x7d\x38\x5a\x04\x1c\xfd\x34"
+  "\x00\x47\x21\x37\xbd\x4c\x98\x07\x1c\xed\x16\x38\xfa\xba\x8a\xa3"
+  "\xf7\xfc\xfc\xbd\x64\xe0\xe8\xbd\x1a\x8e\x26\x66\x79\x8a\xde\xee"
+  "\xf4\x14\x5f\x1a\x47\xbb\x05\x8e\x5a\xff\xdf\xe3\x68\x4d\x3f\x1c"
+  "\x85\xec\x4a\xf1\xbe\x07\xc4\x51\x6d\x3c\x0a\x1c\x2d\xf4\xe3\xa8"
+  "\xa0\xeb\x3d\x1f\xd6\xa5\x82\xee\xa9\x56\x21\xbb\xf5\xe1\xa8\xb5"
+  "\x4a\xe2\x28\xd2\x84\xfe\x64\x19\x70\x14\xe3\xaf\xe0\x38\xf9\xca"
+  "\x62\x09\xa8\xa3\x91\xf0\x75\x17\xe6\x0c\xd1\xa8\x0f\x4f\x17\x61"
+  "\xce\x10\xc6\x74\x60\xce\x00\x47\xe7\x77\x19\x99\x98\x2f\xc5\x98"
+  "\x2f\x6d\x83\xc4\xc1\xd2\x6c\x78\x07\xc5\xd3\x7b\x6f\x08\xc6\xd3"
+  "\x7b\x53\x83\xf1\xf4\xde\x51\x7e\x3c\x55\x9f\x11\x9e\xa2\xcf\x40"
+  "\x9f\x44\xc2\xd4\x7f\x0e\x4f\xef\x8d\xeb\xc3\x53\xbd\x8a\xa7\x8b"
+  "\x2e\x8d\xa7\x62\x6f\x70\x10\x3c\x0d\xc4\x86\xc1\xf1\xf4\xde\x38"
+  "\x3f\x9e\xde\x77\x59\x1f\x9e\x36\x0c\x86\xa7\x89\xf1\x03\xe3\x29"
+  "\xd2\x05\x9e\x26\xc6\xf7\xe1\x69\xc3\x00\x78\x7a\x6f\x20\x9e\xde"
+  "\x77\x5e\xe2\x69\x95\xf4\xa9\x01\x4c\xad\xeb\xc4\xf8\xa0\x39\x97"
+  "\x53\x2e\x30\x55\x01\xa6\x52\x6c\x50\x8a\x9d\x43\x36\xf8\x03\x61"
+  "\xaa\xc4\x5c\x17\x7d\x67\x04\xcd\xcd\x82\x19\x90\x77\xb1\x16\x81"
+  "\x26\x62\xed\xd5\xe8\xb7\x2b\x00\x5f\x53\x56\x1a\x89\xb7\x0b\x1a"
+  "\x2b\x8a\x36\x56\x3a\x2c\x64\x5b\x1c\x34\x56\x86\xd6\x97\xf7\x79"
+  "\x06\xc3\xd6\xc1\x64\xf7\xf7\x48\x76\x7f\x88\xe9\x57\x3f\x04\x7c"
+  "\x4d\x22\xd9\x7d\x4f\x3f\xd9\x7d\xcf\x85\xb2\xfb\x87\x17\xc7\xd1"
+  "\x21\xc9\xee\x73\xa8\x0f\xa7\x77\x05\xe3\xe8\xf4\xf3\xc1\x38\x3a"
+  "\x6b\x39\xd5\x4b\xe2\xf8\x9e\x81\x65\x77\x31\xcf\x67\xdc\xd9\x27"
+  "\xbb\x37\x04\xe3\xa7\x5f\x76\x9f\x35\x61\x70\x1c\x9d\x61\x0d\xe2"
+  "\x47\xe7\xab\x38\xba\x40\xc5\xd1\x05\x7e\x1c\x3d\xf6\x81\xc6\x8f"
+  "\xde\xbf\xf1\xdd\x86\x40\x1c\x9d\xb1\xbf\x0f\x47\x1b\x2f\xc4\x51"
+  "\x0d\x43\x09\x4f\xa9\x1c\xd2\x65\xed\x05\x4e\xbf\xba\xc0\xaa\x97"
+  "\xba\xda\x54\xa2\x5d\x78\x7f\x5d\xed\xf1\xf6\x2e\x96\x9f\x4c\x78"
+  "\x5a\x2e\xf0\xd4\xa0\x63\x69\xc0\xbe\x91\x74\x0e\xa1\x82\xf6\xf5"
+  "\x73\x65\xbc\x23\xd2\x2f\x29\x2b\x64\x9c\x3e\x4d\xcf\x84\xf6\x8a"
+  "\xfd\xfc\x79\x27\x55\x4c\xa5\xb8\xda\x18\x73\xdb\xcf\x01\x53\x73"
+  "\x07\xe0\x4d\x57\x03\x53\x57\x05\xf0\xa6\x98\xfb\xaf\x2f\xe8\x8f"
+  "\xa9\x33\xc7\xd7\xd1\x58\x21\x4c\x0d\x92\xe3\xf7\xfc\x37\x90\xe3"
+  "\x67\xae\x0c\xc6\xd2\x99\x7b\x83\xb1\x74\x66\x9a\x1f\x4b\xd5\x67"
+  "\xdf\x09\x6f\x3a\xd3\xf6\xfd\xf0\xa6\x33\x6d\x7e\x39\x7e\xd6\x43"
+  "\x7d\x58\x7a\x62\x30\x2c\x9d\x61\x1b\x18\x4b\x91\x2e\xb0\x74\x86"
+  "\xad\x0f\x4b\x4f\x0c\x20\xc7\x07\x61\xe9\x03\x3f\x97\x58\xba\x47"
+  "\xf2\xa6\x0d\x1a\x6f\xba\xe7\xff\x83\x72\xfc\x03\x83\xfa\xff\x19"
+  "\x4c\x8e\x7f\xaf\x5d\xe2\x27\xe1\x93\x86\xa1\x7e\x39\x7e\xcf\xe0"
+  "\x72\xfc\x25\x30\x74\x48\xbc\xa8\xc0\xd0\x07\x7f\x1e\x8c\xa1\x0f"
+  "\xde\x1e\x8c\xa1\x0f\xed\xeb\x8f\xa1\x17\xe2\xe7\x83\x6b\x06\xc2"
+  "\x4e\x29\xc7\x3f\x94\x3c\x38\x6e\x3e\xb8\x67\xe8\xb8\xf9\xab\x23"
+  "\xc1\xb8\xf9\x60\xfb\xff\x0c\xdc\x9c\xfd\x48\x10\x6e\x1a\xbf\x25"
+  "\x6e\xfe\x97\xc8\xf4\xb3\xfb\xe9\x3f\x67\xf7\xd3\x7f\xce\x0e\xd0"
+  "\x7f\xce\xfe\x0e\xf5\x9f\xb3\xbf\x27\xfd\xe7\xec\x2a\x3f\x0f\xfa"
+  "\xd0\xc6\x4b\xe3\xe6\x83\x55\x03\xe3\x26\xd2\x05\x6e\x3e\x58\xe5"
+  "\xc7\xcd\x4b\xf1\xa0\x73\x9e\x1c\x02\x6e\xfe\x37\x97\xe9\xe7\x5c"
+  "\x54\xff\x39\x90\x4c\x4f\xb8\x29\xf0\xb2\xa1\x9f\x4c\xff\x50\xa0"
+  "\x4c\xbf\xc7\x2f\xd3\x27\x4a\xdc\x72\x7a\xed\xc1\x32\xfd\x77\x8e"
+  "\xa3\x0f\xaf\xf5\xf4\xe9\x43\x7f\x03\x1c\x7d\x58\xf8\xc4\xf5\xf4"
+  "\xe9\x43\x1f\xbd\x4c\xab\x97\x94\xe9\xb7\x30\x59\xaf\x01\x64\x7a"
+  "\x61\x3f\xfc\xf0\x87\x7d\x32\x7d\x43\x7f\x99\x7e\xee\x81\xc1\x31"
+  "\xf5\x61\xef\x80\x32\x3d\xc9\xdf\x02\x53\xad\x02\x53\xcf\x6d\x0b"
+  "\xc4\xd4\x47\xc6\x08\x4c\xbd\x4b\xc3\xd4\xa4\x04\x0f\xe6\xa6\x27"
+  "\xec\xd2\x98\x4a\xe5\xf8\x31\x35\xf3\xbf\x06\x53\x1d\xdf\x1e\x53"
+  "\x03\xcf\xc0\xbe\x8e\xb6\xf7\x61\xaa\xa0\xf1\x23\x7f\xac\x4b\x25"
+  "\x4c\xcd\xec\x27\xdf\xef\x19\x58\xbe\x7f\x97\xe9\x89\x3e\x9a\x7c"
+  "\x4f\x7d\x20\xf0\xe6\xff\xa9\x7c\x3f\xf7\x8a\x60\x6c\x9d\x9b\x10"
+  "\x8c\xad\x8f\x74\xf9\xb1\x55\x7d\xf6\x9d\xc8\xf7\x73\x23\xbe\x1f"
+  "\xf9\x7e\x6e\x84\x1f\x5b\xe7\x7e\x75\x69\x6c\x4d\x0a\x1d\x18\x5b"
+  "\x91\x2e\xb0\x35\x29\xf4\xa2\xd8\x7a\x57\x20\xb6\x3e\xfa\xb1\x86"
+  "\xad\x7e\xf9\x1e\xe3\x83\xe6\x5f\x8e\xfd\x9f\x97\xef\xef\xf9\xbe"
+  "\xe5\xfb\x47\x1b\x86\x24\xdf\x6f\x03\xce\x42\x16\x5f\xfd\x3e\xe4"
+  "\xfb\x07\x54\xf9\xbe\xb1\xb2\x9f\x7c\x5f\x79\x81\x7c\x9f\xf7\x80"
+  "\x8a\xa9\x98\x53\x02\x53\x17\xec\xf9\xe7\xe5\xfb\x07\xa9\x0f\x93"
+  "\x3f\x0c\xc6\xd4\xe4\x8f\x83\x31\x35\x75\x21\xd5\x4b\x62\x7a\xe5"
+  "\xc0\xf2\xbd\x98\xe7\xf3\x26\x04\xc9\xf7\xa8\xdf\x85\xf2\x7d\xea"
+  "\x98\x20\x4c\x9d\x1f\x88\xa9\xf3\x66\x05\xf1\xa9\x68\x17\x61\xea"
+  "\x8b\x9f\x4a\x4c\x7d\xe9\xd3\x00\x4c\xbd\xff\x25\x15\x53\xe7\xaf"
+  "\x7d\x77\x76\x20\xa6\xce\x2b\xd3\x30\x55\xe0\xe5\x7c\x8f\xbe\x20"
+  "\xe9\x42\xbb\x13\x61\xef\x43\xb6\x40\x28\x9b\xce\x8b\x51\x99\xfb"
+  "\x3e\xcd\xbc\xb4\xbd\x49\xd2\xc0\xf6\x26\xce\x1c\x17\xab\x6d\xb6"
+  "\x0b\x3b\x93\x0a\xb2\x33\x59\xcb\xc6\x57\xf4\x48\xdf\x03\xc2\x2f"
+  "\xe2\x20\x7e\x07\xe6\x3d\xe2\xc7\x59\xb2\xc9\xda\x4e\x36\x59\xe7"
+  "\xa4\x0d\x10\xfa\xfb\x42\x5f\x03\x1a\xdf\x04\x3c\x38\xf0\x69\x7f"
+  "\x9c\x4d\x19\x55\x47\xe3\x27\x39\xb3\x9f\xcc\x5f\xf9\xdf\x40\xe6"
+  "\x4f\x59\x1c\x8c\xaf\x29\x95\xc1\xf8\x9a\xf2\x90\x1f\x5f\xd5\x67"
+  "\xdf\x09\xef\x9a\x92\xf5\xfd\xf0\xae\x29\x59\x7e\x99\x3f\xf5\x9e"
+  "\x3e\x7c\xad\x0f\xc0\xd7\x4f\x03\xf1\x75\x9e\xb0\xb1\x7c\xf3\xd3"
+  "\xfe\xf8\x8a\x74\x81\xaf\xf3\x92\xfa\xf0\xb5\xbe\x9f\xcc\xff\x69"
+  "\x7f\x7c\x4d\xbb\x41\xe0\x6b\x63\x65\x3f\xde\xb5\xf2\xd2\x32\x7f"
+  "\xe3\x7f\x37\x99\x3f\x2d\x6e\x48\x32\x3f\x61\x6a\x96\xc4\x54\xc2"
+  "\x2c\x0d\x57\xfd\x32\x7f\xe5\xa0\x32\xff\xa5\x70\x75\x48\xbc\xaa"
+  "\xc0\xd5\x05\x37\x04\xe3\xea\x82\x9b\x83\x71\x35\xe3\x8f\xfd\x71"
+  "\xf5\x42\x4c\x5d\xf0\xe4\x40\x78\x2a\x65\xfe\x8c\xf4\xc1\xb1\x74"
+  "\x41\xc5\xd0\xb1\xf4\xb1\xe3\xc1\x58\xba\xc0\xf5\x3f\x17\x4b\xd3"
+  "\xd3\x82\xb0\xd4\xf8\x2d\xb1\xf4\xbf\x44\x0f\x90\x7e\x20\x18\x4b"
+  "\xd3\xdb\x83\xb1\x34\xfd\x79\x3f\x96\xaa\xcf\xbe\x13\x2c\x4d\xaf"
+  "\xfe\x7e\xb0\x34\xbd\xda\xcf\xab\x66\x6c\xbd\x34\x96\x2e\xd8\x3d"
+  "\x30\x96\x22\x5d\x60\xe9\x82\xdd\x7e\x2c\x3d\x79\x09\x2c\x7d\x7c"
+  "\xe5\x10\xb0\x34\x58\x0f\xd0\x1f\x4b\xbf\x77\x3d\xc0\xe3\xb6\x21"
+  "\xe9\x01\x34\x2c\x7d\xe0\x42\x3d\x00\xe1\xab\xd0\x03\x80\x5e\x1a"
+  "\x86\x09\x3d\xc0\x34\x89\x65\x4e\x6f\x49\x90\x1e\xe0\xbb\xc7\xd6"
+  "\x5f\xaf\xf7\xf4\xe9\x53\x8b\x80\xad\xbf\x16\xbe\x40\x3d\x7d\xfa"
+  "\xd4\x27\x26\x68\xf5\x92\x7a\x80\xdf\x30\x59\xaf\x01\xf4\x00\x53"
+  "\x44\x79\x27\x83\xf4\x00\x01\x58\xdb\xa2\x5b\xf4\xe1\xe0\x38\x9b"
+  "\x19\x1a\xa4\x07\x68\xf2\xe3\xec\x39\xb2\x51\x07\x0e\x0a\x9c\x1d"
+  "\x1d\x88\xb3\x0b\x7f\x22\x70\x76\x8a\x86\xb3\x99\x89\xdd\x98\x9b"
+  "\xdd\x43\xc5\x59\x3a\x47\xf0\x69\xea\xf7\x83\xb3\xd5\x43\xc0\xd9"
+  "\x00\xdd\xc0\x01\xd0\xa3\x0f\x67\x05\xdd\x17\xbe\x5f\x97\x4c\x38"
+  "\x9b\xda\x4f\x37\x50\x39\xb0\x6e\xe0\xc8\xf7\xa1\x1b\x58\x74\x7d"
+  "\x30\xde\x2e\x4a\x0e\xc6\xdb\x45\x91\x7e\xbc\x55\x9f\x7d\x27\xba"
+  "\x81\x45\x96\xef\x47\x37\xb0\xc8\xe2\xc7\xdb\x27\x86\x5d\x1a\x6f"
+  "\x33\x23\x06\xc6\x5b\xa4\x0b\xbc\xcd\x8c\xb8\x28\xde\x4e\x09\xc4"
+  "\xdb\x27\xba\x34\xbc\xf5\xeb\x06\x2a\x55\xdd\x40\xc9\xa5\x75\x03"
+  "\x8d\x83\xe8\x06\xee\xfc\xbe\x75\x03\x4f\x74\x0e\x45\x37\x70\x7e"
+  "\x9b\xb4\xdb\x5f\x4d\x76\xfb\xf3\x80\xbf\xb3\x3e\x00\x0d\x2e\x6d"
+  "\xb7\x9f\xa7\xd9\x9f\xa6\x96\xab\x38\x5b\x3e\xa0\x6e\xe0\xbd\xd6"
+  "\xc1\x75\x03\xef\x9d\x08\xb4\x3f\xcd\x3a\x13\xbc\x6f\x95\xd5\xa5"
+  "\xed\x5b\xbd\xf7\x11\xe1\xac\xd5\x47\xf7\x4a\xd9\xb2\x04\xe9\xab"
+  "\xdb\xea\xa5\x7a\x0e\x64\xc7\xff\xba\x12\xb8\x97\xb5\xf8\x81\x3e"
+  "\x5d\x41\x3d\xe1\x6d\x39\x53\x78\x66\x18\xf9\x0a\x17\xba\x82\x39"
+  "\x34\xf6\xac\xfb\x02\x71\xf7\xd0\x27\x81\xb8\xbb\x38\x4f\xc3\x5d"
+  "\x1f\x70\xf7\x8d\xa6\x72\xa9\x7f\x9d\x2b\x6d\x53\xf7\xce\x0d\xb0"
+  "\x4d\xfd\xe0\x6d\x15\x77\x97\xac\x7c\xd7\x85\xf6\x5f\xcc\x7e\x0a"
+  "\xef\xbf\xf2\xc9\xb7\xb5\x41\x2d\x1f\xd0\x76\x4a\xc5\xa7\x01\xed"
+  "\xa7\x50\x57\xe3\x0e\x75\xae\xfa\x30\x4f\x77\x04\xd8\x4f\x55\xac"
+  "\xc2\x7c\x56\xcf\x95\x5c\xd4\x0e\x75\xae\xdf\x0e\x95\x97\x65\xe7"
+  "\xd1\xfa\xa6\x6c\x5d\x96\xd0\xc3\x33\x43\x78\x74\x76\x1e\x7d\xbf"
+  "\xb7\x17\xeb\xce\xd4\xa4\x10\x55\xae\x4b\x05\xf6\x8c\x94\x74\x5f"
+  "\xb2\xdf\x87\xb5\xc6\x87\xb5\x46\x29\xcb\x4e\xf5\x12\x6f\xb2\x2d"
+  "\x3b\xbd\x02\x72\x9e\xb7\x48\xc4\x2b\x1c\x51\x0a\x59\x6f\x17\xc9"
+  "\x79\xa7\x31\x37\x0a\x2c\x7a\xaa\x8f\x86\xa3\x86\x56\xb4\xe3\xf4"
+  "\xc5\x79\x39\xef\x37\x7e\x1c\x75\xdc\xfb\x1e\xbe\xb9\xf4\xc5\x3a"
+  "\x1a\xbb\x49\xfe\x33\x05\x82\x67\x1e\xc4\x56\x96\xea\x22\x7d\x36"
+  "\x62\x2c\x7c\x07\x3a\x89\xc0\xfa\x04\xe3\xba\x55\x17\x8c\xeb\xd6"
+  "\x89\xc1\xb8\xbe\xf4\x2b\x3f\xae\xab\xcf\x80\xeb\xe8\x37\xc1\x47"
+  "\x63\xed\xfb\x27\xf9\x68\xda\x8e\x91\xb8\xae\xa8\xb8\xbe\xf3\x5b"
+  "\xe0\xfa\x45\xf9\xe8\x00\x5c\x1a\x1c\xd7\xad\xcc\xaf\x93\xb0\x9e"
+  "\x1c\xd0\x46\xf6\x93\x40\x5c\x5f\xbc\x4e\xe0\xfa\x27\xfd\x71\x1d"
+  "\xe9\x02\xd7\x17\xaf\x1b\xf4\x3c\xc1\x27\xfd\xf7\xd3\x9e\x7c\x4b"
+  "\xe0\x7a\x83\x6a\x23\x5b\x3f\x84\xf3\x04\x0d\x12\xd3\x35\x2c\x27"
+  "\x7d\xd5\xf7\xab\x93\x78\xd2\x31\x14\x9d\x84\xc0\xf2\x76\x89\xe5"
+  "\x84\x8d\x1a\x9e\x7f\x9b\xf3\x04\x97\xc2\x73\x8d\x6f\x26\x3c\x1f"
+  "\x8c\x6f\x0e\xc6\xf3\xec\xb7\x82\xf1\x3c\xfb\x48\x30\x9e\xe7\xbe"
+  "\x15\x8c\xe7\xb9\x8e\xfe\x78\x7e\x21\x96\x2f\x1b\x35\x10\x8e\x5b"
+  "\xe7\x90\x8e\x22\xd7\x3a\x38\x86\x2f\x4b\x18\x3a\x86\xe7\xdc\xfe"
+  "\x3f\x0e\xc3\x8d\xfd\x31\x3c\xc7\x46\x18\xe4\x2b\xee\x87\xe1\x8b"
+  "\x54\x0c\x57\x71\x64\x57\x9b\xca\x0b\xf7\xc7\xf0\x76\xb4\xe3\x12"
+  "\xf2\xb8\xf7\x1f\xfd\x31\x7c\xf9\xe2\x20\x0c\x37\x5e\x02\xc3\x17"
+  "\x49\x3d\x48\x90\x5d\xee\x20\xba\x10\xb4\x23\x6f\xc7\x20\xbc\xb9"
+  "\x46\xb3\xc0\xfa\x04\x63\xf8\xf2\x23\xc1\x18\xbe\xdc\x13\x8c\xe1"
+  "\xcb\xf7\xf9\x31\x5c\x7d\xf6\x9d\xf0\xe6\xcb\x6b\xbe\x73\xde\x5c"
+  "\x1b\x1f\x17\xc5\xf0\xe5\x35\x7e\xde\x3c\xf7\xf9\x4b\x63\xf8\xb2"
+  "\xc4\x81\x31\x7c\x59\xa2\xc4\xf0\x65\x89\x83\x9e\x73\xb8\x00\xc3"
+  "\x57\xac\x1d\x02\x86\x07\xeb\x42\x34\x0c\x57\x75\x21\xbb\x02\x74"
+  "\x21\xbe\x22\xa9\x0b\xd9\xd1\x26\xc7\xc6\x48\x9d\x1c\xa7\x18\x3f"
+  "\xa6\x9d\xfa\x8b\xcb\x6e\x3b\xfe\x29\x3d\xc8\x8a\xc2\xa1\xe8\x41"
+  "\x04\x7e\xd3\x19\x87\x47\x80\xdb\xf5\xdf\xf2\x8c\x43\xa2\x76\xc6"
+  "\xc1\x3e\xc8\x19\x07\x15\xcf\xe7\xff\x0b\x78\x2e\xce\x38\xd8\x36"
+  "\x07\xeb\x98\x6d\x5b\x35\x1d\xb3\xc4\xf3\xbc\xdf\x05\xe3\x79\xde"
+  "\xee\xbe\x33\x0f\xc0\x7c\xa7\x75\xcb\x05\x67\x1e\xfa\xb0\x5d\xe8"
+  "\x41\x6d\x5d\x8e\x39\xcd\xac\x0f\xdf\x93\xfd\xf8\x8e\xb2\x1e\x0a"
+  "\xc2\xf6\xa6\x40\x6c\x5f\x19\x13\x84\xed\x9f\x96\x07\xdb\x47\x34"
+  "\x59\x03\xb0\x5d\x3b\xf3\xb0\x6a\xcc\xbb\x8d\x97\xc0\x76\xbc\xff"
+  "\xed\xcf\x88\x7d\xb7\xd8\xae\x9d\x6f\x18\x10\xdb\x03\xcf\x37\x04"
+  "\xd8\x3f\x10\xb6\x8b\x18\x1b\xa3\xfa\x61\xfb\xea\x4c\xbd\xef\x30"
+  "\xe6\x03\x70\x9d\xe6\x88\x8f\x03\xdb\x05\xbd\x57\xcd\x0e\xc4\xf6"
+  "\xde\x22\x89\xed\xdb\xdb\xfe\x75\x6c\xef\xe3\x87\x03\xb1\xfd\x2e"
+  "\xc2\xf6\xd5\x0f\xc8\xf3\x17\xff\x97\xbd\x6f\x8f\x8b\xaa\xda\xdb"
+  "\x5f\x33\x80\x61\xa1\x80\x0d\x1e\x34\xb5\xd1\x57\x3b\x83\x69\xe1"
+  "\x39\x5a\x68\xf9\x8a\xa5\xa5\x86\x8a\x1d\xed\x20\x17\xc3\x04\x0f"
+  "\x94\x28\x22\x72\x50\xb9\xe7\x05\x0d\x14\x12\x3c\x68\xa8\x58\xd8"
+  "\xd1\x12\x2f\x65\xef\xc1\x5e\xb5\xb1\xa3\xe7\x45\xe3\x66\x47\x4f"
+  "\x58\x98\xa3\xa1\xa1\xa1\x8d\x8a\xca\x65\x66\xf6\xef\xbb\xf6\xda"
+  "\xc3\x9e\x3d\xb3\xf7\xcc\xec\x3d\x80\xd8\xcf\x3f\xf8\x28\xfb\xb2"
+  "\xd8\x7b\x7d\x9f\xfd\xac\xe7\xf9\xee\xb5\xbe\x3b\xcd\xbe\xf5\x17"
+  "\x66\xf3\x33\x3e\xb0\x23\xff\x62\x95\xe3\x79\xae\x8b\xcb\xf1\x2b"
+  "\x76\x73\x39\x7e\x45\x2d\x97\xe3\x57\xe4\xb2\x1c\xcf\xec\x6b\x17"
+  "\x9d\xbe\x62\xd7\xfd\xc9\xbf\xac\xd8\xc5\x72\x7c\xd2\x2a\xdb\x6b"
+  "\x2f\x96\x0d\xe6\x9f\x9b\x01\xdb\x69\x8e\x5f\x36\xd8\xea\xda\x0b"
+  "\x4e\xbe\x3b\x79\x29\xef\xda\x8b\xea\xce\x9b\x9b\x61\x8a\x15\xf3"
+  "\xfc\x8b\xf4\xdc\x77\x72\xbc\xd8\xfc\x0b\x5e\x7b\xb1\xe2\xac\xc9"
+  "\xda\x8b\x5a\xdb\x6b\x2f\x92\x66\xd9\x99\x7f\xb1\x32\x37\xe3\x54"
+  "\xa0\xe9\x7c\xb7\x94\xc5\x5c\x7e\x4f\x59\xda\xc6\xef\xaf\x63\x7e"
+  "\xcf\x58\xcb\xe5\xf7\x8c\x4c\x7c\x9d\x7c\x6b\x31\xbe\xe4\xbc\x57"
+  "\x4c\x39\xcd\x9d\xab\x61\x96\x7f\x79\x1d\x63\x2f\x63\x34\x87\xdf"
+  "\x7f\x34\xe5\xf7\x14\x1d\x9f\x76\xc7\x79\x6f\x7a\x4e\xf1\x1c\x93"
+  "\x35\x6d\xd3\x8c\xf3\xdf\xd2\x5c\x4e\x06\xc1\xfd\x6b\x04\xe6\xba"
+  "\xcd\x21\x73\xdd\xe8\xb9\x6d\x38\x0f\x0e\x6d\xed\x9b\x13\x2b\x4f"
+  "\x09\xa7\x0c\x78\xae\x9b\xf9\x3c\x37\x3c\xf7\x0d\xcf\x75\xab\x88"
+  "\xca\x11\x9c\xe7\x86\xb1\x29\x34\xd7\x0d\xae\x5b\x41\x73\xfd\x45"
+  "\x86\xeb\x99\xb9\x6e\x85\x09\xec\x5c\x37\x0e\xd7\xf3\xcc\x1f\x3e"
+  "\xf4\x63\x1a\xbf\x8e\x4f\x65\xb9\xbe\x05\xeb\xf8\x17\xcc\x72\x31"
+  "\x74\x0c\xd2\xfc\x3b\x35\x17\x43\x73\x7d\xfa\xa8\x4a\x8c\xe3\xd0"
+  "\x58\x9e\x5c\x8c\xe5\x1c\xe7\xce\xcb\xc5\xa4\x67\x73\x39\x3e\x5d"
+  "\xcd\xe5\xf8\xf4\xa5\x2c\xc7\x33\xfb\xda\x85\xe3\xd3\xb3\xee\x4f"
+  "\x2e\x26\x3d\x8b\xcd\xc5\x64\x44\xf3\xce\xbf\xe3\xe4\xd8\x53\x9d"
+  "\xf9\x73\xec\xa9\xcc\xfc\xbb\x54\x67\xc1\x35\x21\x16\xef\x34\xdf"
+  "\x9d\x4a\x72\xec\x12\xd6\x84\xd4\x76\xb5\x5c\xcc\xbb\x01\x62\x73"
+  "\x31\xf4\xdc\xe6\xb3\x78\x7e\x88\xb8\x35\x21\xb6\xb8\xbd\x4d\xbb"
+  "\x5b\x79\x87\xc9\xe5\xf6\x95\x53\xb9\xdc\xbe\x72\x06\x97\xdb\x33"
+  "\x67\x73\xb9\x3d\x33\xc8\x9c\xdb\x2d\x79\x7d\xe5\x0e\x3e\x4e\x8f"
+  "\x7d\x1d\xe7\x62\x32\x5d\x85\xf9\x7c\x65\xb9\x78\x3e\x5f\x75\xf6"
+  "\xff\x6b\x3e\xf7\x30\xe7\xf3\xd5\x1e\x9d\x9a\x97\xa1\xf9\x7c\x8d"
+  "\x0b\x87\xcf\x3d\x6c\xf0\x79\xa7\xe5\x65\xd6\x84\x71\xf9\x7c\x4d"
+  "\x0e\x97\xcf\xd7\x4c\x64\xf9\x9c\xd9\xd7\x2e\x79\x99\x35\xa1\xf7"
+  "\x27\x2f\xb3\x26\x94\xd5\xec\x99\xa3\x6d\xf3\xf9\xca\x33\xfc\x7c"
+  "\x0e\xdb\x69\x3e\x5f\x79\x46\x70\x3e\xb5\x05\x9f\xaf\xed\x23\x82"
+  "\xcf\x79\xe7\xa8\x74\x8d\xbc\xcc\x5a\x6f\xb1\x79\x19\xa1\x75\x2a"
+  "\x98\xdf\xd9\xf9\x29\x26\xeb\x54\xfc\x8d\xeb\x54\xd2\xb8\xf3\x53"
+  "\xda\x9d\xdb\xd7\xf9\x70\xb9\x7d\xdd\x70\x2e\xb7\xaf\x9f\xcc\xe5"
+  "\xf6\xf5\x93\x8c\xd7\x49\xf2\x32\x19\x16\xeb\x56\xb8\x3c\xbf\x2e"
+  "\x5b\xfd\x7a\x1d\xe2\xe3\xfa\x2b\xb2\xec\x66\x61\x9e\x5f\x77\x50"
+  "\x88\xe7\xf1\x7c\x95\x4f\xe7\x44\xf1\xf0\xfc\x7b\x47\x7e\x0b\x3c"
+  "\x2f\x34\x0f\x85\xf6\x41\xc0\xf1\x98\xef\x69\x7e\x67\xb8\x1e\xf3"
+  "\xbc\xfe\x7f\xf9\x72\x34\xef\x35\x75\x14\xcf\x0b\xe7\x68\xb2\xee"
+  "\x54\x86\x32\x3c\x6f\xcf\x1a\x9a\x63\xdc\x1c\x4d\xe1\xdb\x1d\x9d"
+  "\xa3\xc9\x9e\xca\xe5\xfb\xec\x34\x2e\xdf\x67\x8f\x62\xf9\x9e\xd9"
+  "\xd7\x2e\xfa\x3d\x3b\xe0\xfe\xe4\x68\xb2\x03\x58\xbe\x5f\xef\x63"
+  "\x9b\xef\xd7\x1d\xe6\xe7\xfb\x75\x4c\x6d\xb6\x75\x87\xed\xe7\xfb"
+  "\x0d\x6d\x7c\x6f\xb9\x7e\x26\x4d\xfa\x1c\x99\xf1\xf7\x3b\x47\xb3"
+  "\x41\x90\xff\xad\xd5\xc7\x90\x9e\xa3\x61\xd6\x24\xbe\xc5\x5f\x1f"
+  "\xe3\xa4\x95\x39\x32\x27\xcb\x4d\xb9\x3e\xc7\x8b\x3b\x17\x31\xa7"
+  "\x8f\x71\x2e\xe2\xc9\x4a\xcc\xf5\x79\xe3\xb9\x5c\x9f\xe7\x2f\x94"
+  "\xa3\x39\x64\x30\x9d\x93\x98\xb3\x94\x9b\xa3\x29\xe2\xe6\x68\xa6"
+  "\x61\xec\x6d\xbc\x29\xcc\xf5\x39\x45\xdc\x39\xe0\x64\x8d\xe2\xee"
+  "\x39\xcc\x1c\xf0\x39\x26\x73\xc0\xa7\x7c\xc8\x70\x7d\xee\x91\xb2"
+  "\x6a\x1d\x12\x33\x0f\xd1\xf1\xb9\xde\x99\xbc\x73\x10\xe9\x31\xc0"
+  "\xca\x3c\xc4\x37\xcf\x79\xe0\x39\xcd\xba\x6d\x09\x26\xf3\x10\xad"
+  "\xd4\x33\xe6\xf0\xff\x9c\x58\x41\xfe\x6f\xa6\x58\xfe\x37\x3c\xcf"
+  "\xe6\x6d\x0c\x58\xe7\xd3\x71\xc9\x6d\xea\xa8\xbc\x0d\x5f\x9e\x44"
+  "\xfd\x12\xe6\xff\xf7\xaf\x13\x9d\x1f\xd5\xc5\xf2\x36\x1b\x27\x72"
+  "\x79\x7f\x63\x22\x97\xf7\x37\x0e\x67\x79\x9f\xd9\xd7\x2e\x73\xd1"
+  "\x37\x4e\xb8\x3f\x3a\x7f\xe3\x04\x36\x6f\x93\x37\xd0\x36\xef\xe7"
+  "\xec\xe2\xe7\xfd\x9c\x5d\x84\xf7\x73\x76\x59\xcd\xdb\x70\xe6\x46"
+  "\xe6\xbb\x38\x9c\xb7\x31\xea\xfc\xfb\xbe\xae\x27\xdf\x59\x4c\xde"
+  "\xa6\x6d\x4d\xba\x43\x79\x1b\x7e\xbe\x37\x6a\xfb\x93\x56\xde\xb9"
+  "\x72\xf9\x7e\x93\x0b\x97\xef\x37\x75\xe7\xf2\xfd\x96\x21\x5c\xbe"
+  "\xdf\x32\x98\x2f\x6f\xc3\xe5\xfa\x4d\xb3\xf9\x78\x3e\x76\x1a\xce"
+  "\xdb\x6c\x3e\x23\xcc\xf1\x9b\x56\x8a\xe7\xf8\xbf\xed\x78\xc8\xf1"
+  "\x66\x1c\xef\x61\xce\xf1\x7f\xab\xed\x54\x8d\x4f\x73\x7c\xc1\x69"
+  "\x0e\xc7\xb7\x63\x2e\xc7\x9e\xf5\x24\xc2\xda\x7e\xb3\xd9\xfc\xf7"
+  "\xcd\x66\xf3\xdf\x37\x9b\xcc\x7f\xdf\x1c\xda\x7e\x1c\xbf\xb9\xfd"
+  "\xe7\xbf\xdb\xc5\xf1\x9b\x4d\xe6\xbf\x6f\x71\xb1\xcd\xf1\x9b\xb2"
+  "\xf8\x39\x1e\xb6\xd3\x1c\xbf\x29\xcb\xaa\xb6\xe7\x70\xfc\x96\xab"
+  "\x1d\x91\xcb\xb9\x3f\xeb\x8d\xb6\xd4\x8b\xc9\xe7\x58\xab\x3b\x22"
+  "\x98\xcf\xf1\x33\xe6\x73\x62\x05\xf2\x39\xed\xc5\xf9\x1f\x34\x73"
+  "\x39\xff\x03\x3d\x97\xf3\x8b\x86\x73\x39\xbf\x68\x18\x37\x9f\x13"
+  "\x67\x91\xcf\xe1\xf2\x7f\x61\x98\x7a\x9a\x69\x3e\xa7\xc8\x24\x9f"
+  "\xb3\xfd\xbc\x30\xff\x17\x0a\xf2\xff\x5d\x9a\xff\xc3\x79\xf8\x7f"
+  "\xeb\xff\x27\xfc\x1f\xee\x00\xff\x6f\xbd\x0f\xfc\xbf\xed\x1c\xc9"
+  "\xf1\xd8\x59\x27\xe5\x90\xf8\x1c\x8f\x63\xe3\xc0\xf6\x11\xdc\x71"
+  "\x60\x7b\x04\x77\x1c\xd8\xde\x87\x1d\x07\x98\x7d\xed\x32\x0e\x6c"
+  "\xf7\xbd\x3f\xe3\xc0\x76\x5f\x76\x1c\x28\xea\x61\x7b\x1c\x28\x14"
+  "\x18\x07\x0a\x99\x71\xa0\x50\xc4\x38\x50\xa4\x17\xce\xf1\xc4\x4a"
+  "\xcf\xf1\x8c\xbe\xdf\xeb\xa0\x8a\x74\xa2\x72\x3c\x9b\xe2\x7d\xcb"
+  "\x71\x8d\x94\x8b\x48\xbe\x62\xae\x31\xc7\xa3\x36\xcb\xf1\xa8\x2d"
+  "\x72\x3c\xcb\x2e\x32\xfc\x1f\xc0\xac\x37\x9d\xe6\x40\x8d\x14\xfa"
+  "\x7b\xd2\x3b\x9a\xb9\xf3\xe6\x77\xd0\xfc\xcf\xd6\xef\xdb\xb9\x16"
+  "\x5f\x17\x19\x7f\xd4\x56\x6a\xa0\x7e\x38\x99\x93\xd3\x09\xe0\xab"
+  "\x91\xb2\x93\x33\xef\x86\xbb\xde\xf4\xc3\x78\x0e\xdf\x4f\x23\xeb"
+  "\x4d\x3f\xe1\x7b\x4f\xdb\x56\x93\xff\xa3\x55\x74\x4d\xfe\xb6\x5a"
+  "\x7e\x1f\x96\xda\x55\x4b\x7a\x0e\x53\x4b\xfa\xc7\xfb\x50\x4b\xda"
+  "\xde\x9a\xfc\x3f\x9a\xd7\xef\x2b\x1e\x58\x55\xae\x46\x95\x18\x23"
+  "\xa1\xe6\xb5\x4f\xd5\xfc\x6b\xf7\xe5\xcc\xda\xfd\x85\x1d\x53\x07"
+  "\x05\x5f\x0f\x3d\xe6\xf7\x3a\xea\x5f\x92\xa2\xa5\xaf\x07\x7f\xbb"
+  "\x1b\xae\x75\x67\x39\x60\xd5\x80\xf9\x34\x0e\xf3\x69\x71\x0d\x7d"
+  "\xec\x45\xc0\x42\xaf\xd7\x94\x18\xc7\xeb\x0d\xc8\x2d\x36\x01\x73"
+  "\x6b\x31\x3d\xef\x0b\x64\x04\x70\x2b\x39\x2e\xf9\x22\xa5\xd7\xf7"
+  "\xfa\x93\x12\xae\xff\x91\xbd\x0b\xab\x5d\x2a\x35\x8d\xf0\x5c\x5c"
+  "\xa3\xbf\xe5\x5a\xa5\xbb\xa7\xc6\xb1\x38\xba\xb0\xda\x99\x02\xfe"
+  "\xdd\x3e\x1f\xb9\x8a\x7b\x4e\x8b\x8b\x69\x3d\x83\xc7\xbd\x5e\x47"
+  "\x03\x70\x1d\x10\xa3\xb6\x32\xfc\xca\xe6\xb7\xb6\x42\xff\x18\x28"
+  "\x32\xf6\xbd\x19\x4d\x78\x03\xfe\x9e\x0e\xfa\x92\x9e\x63\x8b\x79"
+  "\x83\xfe\x86\x15\xf0\xc6\xb6\x5b\xec\x7b\x6c\xdc\x3e\xee\x23\x92"
+  "\x47\xd9\xc9\xce\x7f\xd1\x08\x71\xeb\x87\x49\xfc\xdc\xfa\x61\x12"
+  "\xe1\xd6\x0f\x93\xda\xb8\x55\xc3\x93\x47\xe1\xcc\x63\xff\x98\x99"
+  "\xff\xa2\x36\xd3\xd8\xea\x07\xb0\x3e\xca\xc7\xa2\xe6\xbf\xd0\x7c"
+  "\xba\x80\xf0\x29\xe6\x2b\x23\xa7\xb2\x79\x14\xb5\x60\x1e\xc5\x16"
+  "\xa7\x8a\x5a\xc3\x4f\x73\xea\xdf\xa7\x72\x39\xf5\xef\x33\xb8\x9c"
+  "\xfa\xc9\x69\x73\x4e\xb5\xe4\xd3\xbf\xe7\xf2\x71\x29\xa9\x8f\xf2"
+  "\x49\x9a\x30\x8f\xfe\xfd\xb0\x10\x8f\xd2\xf3\xd3\xe7\x98\xcc\x4f"
+  "\x6f\xe3\xd1\x5d\x15\x5c\x1e\xdd\x85\xec\xe5\x51\xfa\xdb\x26\x3f"
+  "\x76\xc2\xb7\x4d\x24\xf3\x68\xac\x19\x8f\xee\x8e\x66\x79\xd4\xfc"
+  "\xfb\x26\x36\x78\xf4\xed\x8e\xa9\x81\xc2\xe1\x51\x83\x96\xbe\x1e"
+  "\xe5\x42\xfa\x5a\xaf\x73\x79\xf4\x13\xa5\x30\x8f\xee\x3e\xc2\xf2"
+  "\x28\x39\xae\x63\x79\x74\x77\x03\x87\x47\xdf\x36\xe1\xd1\x5f\x58"
+  "\x0f\x81\xe7\x58\xb4\xf1\x68\x8c\x09\x8f\xbe\x6d\x8b\x47\x77\x37"
+  "\xe0\x3e\x22\x1a\xf5\x93\x03\xb6\x79\xf4\xef\xc7\xf9\x79\x14\xb6"
+  "\xd3\x3c\xfa\xf7\xe3\x2c\x8f\xf2\x68\x54\x0e\x8f\x7e\x9a\x2f\x82"
+  "\x47\xbb\x78\x6d\x94\x4f\xf3\x44\xe5\x2a\xd8\x35\x9d\x96\x35\x52"
+  "\xc3\x4c\xd7\x04\x95\x9a\x7d\xf7\xa4\xd4\xe2\xbb\x27\xcb\x8c\x6b"
+  "\x3c\x27\x31\xbc\x3a\xc5\x01\x5e\xa5\xd7\x78\xee\xd9\xc9\x9d\x7b"
+  "\xb2\x67\xb7\x71\xee\x09\xe1\xd5\xfd\x63\x8d\xd7\xc5\x7e\xf7\xa4"
+  "\xd4\x4a\x8d\xd4\x3d\xcd\x9c\xda\x28\x93\x4c\x6b\xa3\xec\xbb\x2e"
+  "\x5c\x23\xb5\x44\xc9\xa9\x8d\x72\x6a\x57\xdb\x77\x4f\xcc\x6b\xa4"
+  "\xb2\x1c\xbb\x77\x04\xcd\xb1\x6d\x35\xa8\x4a\x22\xda\x6a\xa4\xda"
+  "\x58\x17\x84\xdb\xd9\x7b\x29\xaa\xe3\x39\x56\x2d\x82\x63\x39\xdf"
+  "\x3d\x31\xaf\x31\xb5\xf7\x6c\x55\x59\x29\xaa\x0c\x2f\xe5\xa9\x8d"
+  "\x5a\x7a\x5f\xbf\x7d\x82\xaf\x8b\x9f\x6b\xf7\xcd\xe6\x72\xed\xbe"
+  "\x2c\xfa\xd8\xf3\x7c\x5c\xbb\xcf\x87\xe5\x5a\x72\x5c\xf2\x79\x33"
+  "\xae\xad\x15\xe0\x5a\x18\x57\xb7\x5f\x11\xcb\xb5\xfb\x82\x68\xae"
+  "\xcd\x60\xb8\xf6\x5a\x7b\x73\xed\xbe\x20\x96\x6b\xf7\xf7\xb7\xfd"
+  "\x8d\xa9\x12\x15\xff\xba\x9c\x12\x15\xe1\xda\x12\x95\xd5\x6f\x4c"
+  "\x71\xe6\x7c\x1c\xe8\x61\xfc\xc6\x14\x9b\x0f\x28\x65\xf2\x01\x0f"
+  "\xf2\x37\x51\x0e\xb8\x89\xcd\x07\x7c\x03\xde\x1d\xaf\xbb\x5c\x81"
+  "\xbf\x39\x15\x8a\xbf\x89\xb2\xdf\x2c\x1f\xb0\xdf\x32\x1f\x30\xdb"
+  "\x3a\xc7\x8a\xca\x07\xd0\xeb\x2e\x3f\xeb\xce\xe5\xd8\xcf\x7a\x70"
+  "\x39\xf6\x8b\x9d\xc6\x75\x96\xf8\x7a\x84\x6b\xa6\x7e\x36\xbb\x2d"
+  "\x1f\x50\xcb\xe5\x56\x36\x1f\xf0\xc5\x2c\x61\x8e\xfd\x8c\x9b\xff"
+  "\x9d\xb2\x8b\xb3\xce\xf2\x93\x4b\xa6\x75\xa8\x8d\xf5\xa7\x3e\xdf"
+  "\x71\xf2\x8c\x29\xc7\x7e\x56\xf6\x20\xd5\xa1\x6e\xab\x35\x65\x63"
+  "\x2e\xb7\x65\x1d\xea\x83\x63\xab\xca\xf6\x23\xbc\xb6\x8d\xe6\x5b"
+  "\x4e\x6e\x60\xff\xfd\xc9\x0d\x94\xed\x17\xc8\x0d\x1c\x3c\xc6\xe5"
+  "\xd9\x83\x8d\xf4\xb1\xe7\xf8\x78\xf6\x60\x2e\xcb\xb3\xe4\xb8\xe4"
+  "\x73\x66\x3c\x5b\xd3\x9e\x9a\xf6\xa0\xba\x63\x73\x03\x07\xd5\x6c"
+  "\x6e\xe0\x0b\x3b\xd6\x3f\x7e\x96\xc5\xcf\xb3\x9f\x31\x79\xd7\xcf"
+  "\xd8\xbc\x6b\x0d\xcf\xf7\x52\x38\x3c\xfb\x3f\xd1\xc6\xf5\x8f\xb4"
+  "\xa6\xad\x35\x6a\xda\xfd\x0f\xe0\xf7\x52\xfe\x27\x4a\x6c\x6e\x00"
+  "\xaf\x73\xc7\xdc\x8a\xb9\xcb\xc8\xaf\x6c\x6e\x60\xbf\x70\x6e\xc0"
+  "\x06\xbf\x8a\xff\x76\xdf\x3f\xa2\xb9\xfc\xfa\x8f\x18\x2e\xbf\x7e"
+  "\xd9\x6c\xce\xaf\x96\xdc\xfa\x8f\x12\x3e\x5e\x25\xb9\x81\x2f\x77"
+  "\x09\x73\xea\x3f\x6a\x84\x38\x95\xae\xe9\x77\x89\x9d\x23\xcd\x72"
+  "\x6a\xe9\x1d\x2e\xa7\x96\xf6\xb3\x97\x53\xef\xcb\xf7\x52\x24\x73"
+  "\x6a\x94\x19\xa7\x1e\xca\x65\x39\xd5\xfc\x9b\x29\x36\x38\xb5\xa3"
+  "\xf2\x04\xa6\x9c\xca\xd1\xae\x5f\x7a\x71\x39\xf5\xcb\x49\xc2\x9c"
+  "\x7a\xe8\x32\xcb\xa9\xe4\xb8\x8e\xe5\xd4\x2f\x15\x1d\x9b\x27\xf8"
+  "\x52\xc1\x6a\xd7\x2f\xcf\xd9\xe6\xd4\x7f\x68\xf8\x39\xf5\x1f\x1a"
+  "\xc2\xa9\xff\xd0\xd8\xbf\xa6\xfc\x7f\x8f\x88\xe0\xd4\x2e\xfe\x2d"
+  "\x95\xff\x3d\x2c\x3a\x4f\x80\xf3\xad\x98\x4b\x6b\x1d\xab\x1d\x92"
+  "\x68\xac\x1d\x32\x81\xe1\xd8\x57\x1c\xe5\xd8\xc3\x15\xdc\x39\x0d"
+  "\x87\x4f\x1b\xe7\x34\x10\x8e\x55\x2f\xe6\x7e\x1f\xd5\xb2\x56\x08"
+  "\xb7\x86\xea\x91\x81\x6d\x79\x02\xcc\xb9\x13\x4c\xf3\x04\xea\x81"
+  "\xc2\x7c\x7b\x64\x12\x27\x4f\xf0\x2f\x7e\xbe\xbd\xcb\xe1\xdb\xa3"
+  "\x91\x34\xdf\xb6\xd5\x50\x3d\x92\x65\xac\xa1\x6a\x53\xc3\x72\xf8"
+  "\x36\xbc\x73\xf8\xb6\xd4\x7e\xbe\xe5\x7e\x4b\xc5\xbc\x5e\xea\x57"
+  "\xdd\xab\x8e\x03\xdf\xd2\xf5\x3a\xcc\x6b\xa6\xda\x57\xaf\xa3\xa3"
+  "\x6a\xa6\xe2\xeb\xe2\xe7\xdd\xaf\xb2\xb9\xbc\xfb\x95\x9a\x3e\x96"
+  "\x97\x77\xbf\x0a\x63\x79\x97\x1c\x67\x37\xef\x4a\xca\x19\x7c\x95"
+  "\xd5\xb1\x39\x83\xaf\xb2\x58\xde\x55\xcf\xb0\xcd\xbb\x47\x02\xf9"
+  "\x79\xf7\x48\x20\xe1\xdd\x23\x81\x56\x79\x97\x33\x87\xe0\xd8\x78"
+  "\xde\x5a\x1e\xb5\x0f\xfa\x77\x56\x8e\xf9\x4b\xc9\x19\x00\x07\xcb"
+  "\x93\x70\x0d\xa7\x70\x3c\x87\xc0\x76\xce\xc0\x16\xdf\x8a\xcf\x19"
+  "\x7c\x3d\x96\xcb\xb7\x5f\x8f\xe7\xf2\xed\x89\xeb\xf8\xba\xac\xe6"
+  "\x0c\x68\x0e\xf8\x3a\xbb\x2d\x67\xa0\xe1\xf2\x2c\x9b\x33\x38\xb1"
+  "\x55\xf8\xdd\xd7\xd7\xa5\x1c\x7d\xfb\x8a\x59\xcd\xea\x39\x2c\xdf"
+  "\x9e\xaa\x34\xce\x19\xfb\xe7\xd5\x93\x81\xa6\x7c\xfb\xb5\xce\xa2"
+  "\x66\xf5\xcc\x76\xac\x59\x3d\xb3\x9d\x6b\x56\xcf\xe2\xd6\xac\xde"
+  "\x72\x97\x9d\x47\x26\xbe\x66\xf5\xf1\x55\x34\x07\x63\x0c\xe1\xba"
+  "\xd5\xf6\xe4\x11\x3a\xf8\x5b\x2b\x1c\xee\xe5\xe4\x11\x4e\x74\xe7"
+  "\x72\xef\x89\x17\x85\xb9\xf7\xf8\x39\x96\x7b\xc9\x71\x1d\xab\x79"
+  "\x4f\xb8\x76\x6c\x1e\xe1\x84\x2b\x9b\x47\x38\x51\xc1\xcb\xbd\x9c"
+  "\x77\x63\x5f\xab\xf9\xdf\x8d\xc1\x76\x9a\x7b\xbf\x56\x0b\xe6\x11"
+  "\x2c\xe6\x6f\xfd\xeb\x00\x79\x37\xc6\x68\x5e\x8d\x88\x3c\x42\x97"
+  "\x9b\x63\xf0\xaf\xfd\x52\xf2\x08\x98\x6f\x31\x9f\x19\x39\xd7\x9e"
+  "\x3c\x42\xfb\x6b\xdc\xff\x3b\xc0\xe5\xdc\xff\xfb\x82\xcb\xb9\xdf"
+  "\xcc\x32\xe7\x5c\x4b\xbe\xfd\xbf\x3b\x7c\x5c\x4b\xf2\x08\xdf\x38"
+  "\x0b\xf3\x6c\x99\x52\x90\x67\xcd\xe6\xe6\xb2\x3c\x7b\x72\x06\x97"
+  "\x67\xcb\x22\x24\xf1\xac\xbd\xdf\x60\xe9\x52\x3c\x1b\x6e\xc6\xb3"
+  "\x27\xaf\xb3\x3c\x6b\xfe\x1d\x16\x1b\x3c\xdb\x41\xdf\x61\x11\xd6"
+  "\xb8\xa7\x16\x73\x79\xf6\x54\xb1\x30\xcf\x9e\x1a\xcf\xf2\x2c\x39"
+  "\xae\x63\x79\xf6\x54\x6c\xc7\xe6\x16\x4e\xc5\xb2\x1a\xf7\x9b\x51"
+  "\xb6\x79\xb6\x4c\xc5\xcf\xb3\x65\xcc\x7b\xb1\x32\x95\xa0\xc6\xb5"
+  "\xe0\xd9\xf2\x3e\x22\x78\xb6\x8b\xcf\x41\x28\x17\x55\xff\xc2\x24"
+  "\x5f\xdb\xad\x4a\x63\xb6\x5e\xe2\x9c\xe9\x7a\x09\x93\xdc\xc2\x04"
+  "\x63\x6e\x81\xfb\x7d\x96\x44\x63\xfe\xd6\x9f\xe1\xdd\x97\x1c\xe5"
+  "\xdd\x0a\x9f\x7b\x6d\xbc\x1b\x07\xbc\x5b\x41\xaf\x8f\xb8\xd7\xc6"
+  "\xbb\xd5\x17\x8d\xd7\xc5\x7e\x9f\x45\x20\xb7\x30\x86\x6e\x2f\xb9"
+  "\x2d\xb7\x80\x79\xd8\xdf\x34\xb7\x50\x9d\x2b\xcc\xc1\x15\xc5\x9c"
+  "\xdc\xc2\xd7\xfc\x1c\xdc\xc8\xe1\xe0\xca\xb3\x34\x07\x8f\x31\x72"
+  "\x70\x45\xfd\x5d\xf0\x96\x77\x57\x8b\xe3\xe0\x46\x9a\x83\x27\xdd"
+  "\x1f\x0e\x3e\xd8\x0e\x1c\x4c\xf7\x7b\xd5\xb2\x2a\x35\x70\x70\x28"
+  "\xe6\xe0\x49\xf6\xe5\x1b\x3a\xe9\x1b\x2d\xf8\xba\xf8\xb9\xb8\x4a"
+  "\xcf\xe5\xe2\x6a\x5f\xfa\x58\x5e\x2e\xae\xaa\x60\xb9\x98\x1c\xd7"
+  "\xb1\xf9\x86\x2a\x5d\xc7\xe6\x1b\xa0\xa5\x36\x2e\xae\x3e\x66\x9b"
+  "\x8b\x2b\xf6\xf0\x73\x31\x6c\xa7\xb9\xb8\x62\x8f\x55\x2e\x1e\x63"
+  "\xca\xc5\xa7\xdb\x34\x2f\x27\xdf\xa0\x79\xd0\xbf\xdd\x72\x5a\x50"
+  "\xff\x2a\x07\xa0\xb4\x4b\xb2\x6f\xbb\x57\x15\x22\x74\x3b\x03\xa5"
+  "\x55\xe9\xc6\x20\xd8\x06\xfd\xf7\xed\x88\x2a\x6f\x3f\x64\x78\x7f"
+  "\x8e\x12\xf3\xf1\x46\xfc\x03\x1a\x37\x47\xce\x3c\x5b\x74\x1f\x7f"
+  "\x4b\xcf\x77\xc5\xdb\x31\xf7\x6e\x37\xd9\xcf\xf7\xb7\xa8\x9c\xb0"
+  "\x22\xe6\xbc\x2c\xb2\xee\x26\xac\xd8\xf8\x3b\xc6\xa6\x46\xf6\x6d"
+  "\x0e\x95\x1b\x56\xa8\xf5\x0c\x2b\xe4\x3b\x7f\x90\x07\x72\xed\x99"
+  "\x4e\x51\xdb\x36\x51\x8d\xb7\x9f\x0a\x53\xde\x5e\x87\x50\xce\x26"
+  "\x4a\x7b\x6f\xf5\xb7\x65\x70\x8f\xda\xbf\xc1\x71\xb7\x7b\x9d\xf6"
+  "\xb8\x9d\x11\x88\x60\x5b\xad\x71\x1b\xf4\x1b\x32\x64\x38\x51\x06"
+  "\xd8\x47\x6d\x52\xea\xb6\xa7\x00\x57\x25\x21\xf4\xcc\x5d\xfc\xcc"
+  "\x7c\xdb\x00\x98\x51\xac\x87\x36\x37\x40\x5b\xd4\xef\x9e\x68\x04"
+  "\x3c\x3a\x57\xae\x44\xf8\x99\xce\x84\xfb\x2a\x5a\x8f\xfb\xde\x69"
+  "\x68\x01\x25\x77\x46\x86\x9d\x01\x89\x94\xd7\x52\x5f\x88\x07\xca"
+  "\x89\x43\xb4\xff\xdb\x00\xc7\x51\xf2\x54\xca\x30\xe4\x35\xe0\xff"
+  "\x46\xf2\x4c\xc3\xf5\x1d\x05\x1f\x4b\xc1\xdf\xdd\x16\x87\x3c\xe0"
+  "\xc7\x8d\xca\x5f\xea\x7b\x6f\xf5\xbf\xe3\xe1\x3e\x43\xf1\x75\x09"
+  "\xdd\xe3\x86\x2d\x30\xee\x3c\xe1\x8d\xc7\x0e\xfa\xef\xe3\xbf\x4d"
+  "\xff\x1d\xb9\x21\x53\x0f\xdb\xa9\x8c\x54\xaa\x2a\x51\x87\xdc\xa1"
+  "\x2f\xb6\xc3\x75\x63\x3c\x1a\x3e\x0e\x53\xbe\xdb\x17\xa1\xbd\xcb"
+  "\xeb\xe5\x55\x70\xed\xfa\xbf\x3d\xd1\xa8\x4e\xf9\x03\x82\xfd\x5a"
+  "\xec\x59\xae\xc8\xce\x2c\x9e\x7e\x15\x21\xcc\x27\xf0\xff\xe4\x46"
+  "\x18\xc7\xa6\xc2\xef\x1b\xe0\x3e\x0c\xb7\xbd\x9d\xf1\xb1\xb0\xdd"
+  "\x47\x9d\xf0\x3d\x72\x8f\x45\xae\xeb\xe1\xde\xc8\xb1\xff\x6e\xc2"
+  "\xc7\x6a\x64\x67\x92\xf0\x35\xc0\x31\x6e\xf0\x3b\x3e\x0f\xcf\x21"
+  "\x43\x54\x71\x40\x22\x8d\xcd\xbc\xa5\xbe\x86\x21\x01\x89\x34\xf7"
+  "\xc1\x7d\x6e\x80\x7b\x86\x63\xdc\xe0\x18\x37\xfa\xdf\x14\xe4\x91"
+  "\x07\xdb\x70\x3b\xf0\xaf\x9b\x7a\x61\x0b\x6e\xbb\x1e\xb7\x2d\xd0"
+  "\x0f\xce\x94\x62\xa9\x2f\x05\xd8\xc6\x63\xaa\x32\x45\x76\xfa\x92"
+  "\xec\x6c\x3f\x77\x19\x45\x51\xc5\xaf\xa1\x77\x53\x90\x5b\x8e\x01"
+  "\x21\x75\x5f\xdc\xce\x99\x3b\xd0\xbe\x33\xee\x8b\x7b\xab\xcf\x9c"
+  "\xd1\xc8\xfe\x9d\x86\xfb\x17\xe2\xd9\xa8\x1c\x84\xef\xe1\xec\x30"
+  "\xfc\x77\xf0\x39\xcc\xf1\x74\xed\x7b\x7c\xcd\xca\x14\x27\x0a\xf6"
+  "\x7b\x39\xc9\x2e\x22\x27\x6f\xb7\xd5\xf7\x56\x9f\x55\x68\xd0\xfb"
+  "\x83\xf1\xf9\x1a\x72\x1e\x60\xe9\xac\x0a\x62\x56\x88\xb7\xe1\xdf"
+  "\x05\xae\xd7\xcd\x18\xb7\x0a\x50\x41\x16\xb1\x33\x62\x04\x70\x61"
+  "\xc4\x08\xbe\xde\x7d\x29\x1a\x39\x3d\x0e\xcb\xce\xd2\xbe\x6e\x3d"
+  "\xc4\x50\xff\x81\xb7\xf3\x06\xe8\x5b\x43\x2b\x8e\xcb\x25\xd8\xf7"
+  "\x9f\x18\x1c\x97\x0d\xcb\x21\x26\xe4\xd8\x1c\xf6\xfa\xf1\xef\xff"
+  "\xa1\xe3\x69\x80\x58\x90\xb5\x9b\xff\x19\x8f\xef\x67\xc3\x5d\x88"
+  "\x63\x6f\xaa\xf1\x78\x22\x5c\x17\xc6\x2d\x60\x64\x6f\x5c\x93\x1c"
+  "\xcf\xeb\xc3\xdb\x8f\xde\x6a\x92\x6f\xb8\x86\xb0\xae\x44\xd9\xc0"
+  "\xcb\x5b\x13\xa0\xcf\xa1\x4d\x6a\xf0\x6b\xb4\x8e\xa0\xe3\xb8\x1c"
+  "\x62\x97\x00\xd8\x85\x3e\xdf\x00\xfd\xb7\x0d\x38\x0f\xff\x7f\x1b"
+  "\x8c\x3f\x06\x38\x4e\x23\xfb\x4f\x12\xb4\xe7\xb1\xb5\x37\xa5\xdd"
+  "\xde\x9b\x6a\x80\x3e\xdc\x72\x6f\xf5\x7f\x82\x8c\x7d\x88\xaf\x69"
+  "\x03\x6c\xcf\x86\xfd\xd0\x9f\x67\x08\x86\xce\x16\x1b\xef\x59\xa8"
+  "\x3f\xb3\xf6\x22\xbf\xec\xbd\xa8\xdf\xba\xbd\xe8\xc5\x15\x75\xf0"
+  "\x5c\x66\x8c\xa3\xbe\x09\xd5\xc1\x98\x58\x1a\xd4\xd2\x7b\x8e\x07"
+  "\x7e\xf7\x64\x78\xf7\x89\xa2\x55\x7b\xd1\x30\xbc\x36\x76\x7a\x03"
+  "\x42\x78\x0c\x9f\xee\x72\x81\xaa\x8a\xbd\x83\x0c\x9e\xa5\x41\xfa"
+  "\x77\x87\xf6\x9a\x76\x07\xa1\x13\xaa\x46\x94\x12\x0f\x63\xf9\xad"
+  "\x7a\x94\xd2\x48\x69\x2b\xd3\xae\x22\xe0\x9e\x3c\xd2\x77\x35\xde"
+  "\xd3\x23\x11\xc2\x6b\x06\x0d\xbf\xa8\x50\x8f\x28\xe4\x9c\x74\x0e"
+  "\x79\xa7\xd6\x51\xf5\xfa\x4d\xef\xa0\x94\x64\x24\xdf\x7b\xab\x86"
+  "\x68\x4f\xd9\x77\x57\x8f\xe0\xf5\xa9\xf7\x82\xd0\x9b\x3a\x66\x3c"
+  "\xca\x5b\xea\x97\x1a\x8d\xfa\xe0\xfb\x71\xa7\xb5\xd7\x77\xab\xa0"
+  "\xdf\xfc\xc4\xf1\xf3\x77\x81\x74\x3c\x37\x2d\xc8\xd9\xfb\x56\x13"
+  "\xe8\xd6\x41\xca\xd4\x48\xaa\x1e\xeb\x3a\x18\x5f\x68\x2d\x58\x55"
+  "\xaf\x03\x6d\x15\x01\xa3\xa3\x06\x7d\x75\xa9\x48\x6e\xc8\x1f\xa4"
+  "\x14\xf9\x37\x0e\xd2\xe3\x36\x1e\x4b\xe1\xda\x67\xa9\x50\x1a\x7d"
+  "\xfd\x30\x66\xba\xc7\x63\x3d\x45\x5d\xc0\xd7\x7f\x14\xee\x95\x1a"
+  "\x98\x99\x03\xc7\xfb\xe1\xf1\x73\x7a\xad\x1a\x95\x37\xe9\xd1\x96"
+  "\x6b\x74\x1f\x75\x83\x3e\x72\x86\x7d\x6e\xd0\x4f\xae\x7c\x71\xc3"
+  "\x31\x33\xe4\x94\x06\x19\x9c\x48\x6c\xe8\xb8\x34\x92\xb8\x4c\x5b"
+  "\x8c\x60\x1c\x85\xd8\xe4\x92\xd8\x18\xbc\xe2\x3d\x70\x6c\xc4\xdd"
+  "\x47\x4d\x92\xd0\xf8\x82\xff\x36\x05\xf8\xc0\xb8\x30\x28\xe2\x3d"
+  "\xf0\xdf\xc6\xd7\x80\xdf\x9f\x61\x1c\x4c\x5f\x75\x81\xaa\x8c\xad"
+  "\x47\x55\x70\x3f\x94\xa7\xe9\x35\xe8\x44\x5e\x03\x4e\x33\xf2\x5f"
+  "\x43\xd6\x33\x80\xdb\x67\x00\xb7\xcf\x00\x6e\x35\x04\xb7\xa7\x6a"
+  "\x09\x6e\xf5\x70\x5d\xcd\xa0\xdd\x57\xcc\x42\x72\x7c\x5d\x7b\xbe"
+  "\xc7\x35\xfa\xe0\x3a\xeb\x59\xec\x4e\xbd\x0e\x7d\x64\xc4\xaf\xd3"
+  "\xd0\x5e\xb8\x7f\x2a\x1b\x6b\x50\x2a\xc6\x6f\x0b\x1f\x7e\xbf\xaf"
+  "\x99\x3e\x17\x62\xf3\x17\xc0\xef\xcf\x2a\xe4\x56\x87\x9c\x93\x67"
+  "\x01\x7e\xeb\xf9\xf0\xfb\xfd\xee\xc3\xf0\x37\x2d\xf0\x1b\x69\x8a"
+  "\xdf\xef\x27\x8a\xc7\xef\xf7\x1e\x6d\xf8\x0d\x66\xf0\x1b\x6d\x86"
+  "\xdf\x3a\x13\xfc\xe2\xfb\x16\x8d\xdf\xef\xe3\xc5\xe1\xf7\x5c\x53"
+  "\x1b\x7e\xc1\x97\x6c\x99\x4f\xf7\x51\x37\xe8\x23\xc0\xef\xb9\x72"
+  "\xe8\x27\x5e\xfc\x76\x7e\xfc\x6a\x0b\xec\x8f\x5f\x6d\xb4\xed\xf8"
+  "\xd5\xba\x88\x8f\xdf\x0f\xd5\x1d\x1f\xbf\xda\x91\xe2\xe2\xf7\x43"
+  "\xa9\x70\xfc\x7e\xc8\xea\x3a\xf1\xfb\x31\xc8\xfe\xf8\xfd\xe8\x63"
+  "\x3b\x7e\xe7\x4f\x88\x8f\xdf\xf9\x9c\x8e\x8f\xdf\xf9\x46\x71\xf1"
+  "\x3b\x9f\x28\x1c\xbf\xf3\x01\x42\xf1\x7b\xb9\x8f\x81\x32\xe0\x79"
+  "\x73\xbd\x83\x63\xb1\x06\x22\x7a\xed\xc2\x10\xec\x19\xe1\x77\x67"
+  "\xe3\xef\xb4\xa6\x02\x5f\x6d\xf6\xbb\x9b\xd9\xef\x1e\x66\xbf\x2b"
+  "\xcc\x7e\xf7\x36\xfb\xbd\x9f\xf1\x77\x88\x97\xcb\x0d\xd9\x8f\xf9"
+  "\xe0\xd9\xd2\x34\xb2\x0b\xbe\xcc\xfe\xc1\x6f\xea\x95\xd8\xf7\x0d"
+  "\xe6\xbb\xf6\x0d\x19\x54\x53\x0f\x19\xa2\x5a\xe5\x14\x8a\x4d\x41"
+  "\x4f\x5c\x93\x5d\x28\x6e\xc9\x00\x4b\xe8\xd4\x57\x45\xb5\xa4\x21"
+  "\x88\xcb\xcc\x69\xcb\x00\x5f\x5a\xf0\x89\xa9\xde\xdd\xa0\xed\xdf"
+  "\x41\xbf\x69\x2b\x63\xb5\xa0\xcb\xbf\xa2\x2e\xc9\x2e\xe4\xe2\xfb"
+  "\x7c\x26\x56\x8d\x0c\x4e\x43\x55\x14\x5d\xbb\x79\xd0\x4c\xad\xd3"
+  "\xd0\xbe\xd4\x8e\xb5\xca\xec\x0c\x83\x6b\x55\xc3\x19\xb4\x5e\x6e"
+  "\x50\x26\x25\x81\xae\x6f\x38\x88\x56\x34\x50\xf5\x49\x3a\xaa\xa9"
+  "\x2a\x54\x8d\xdf\xdb\xd6\x57\x25\x96\xa1\x4a\xed\x19\x84\xc7\x3c"
+  "\x8c\xd5\x2a\xed\x41\xf2\x9e\x18\x1f\x03\xdb\x2a\xb5\x7b\x50\x05"
+  "\xfc\xae\x5e\x78\x19\xee\x53\x33\xbe\xaa\x61\x0f\xd2\xe7\x0d\x0a"
+  "\x34\x28\x06\x8d\xa4\x14\x83\xfc\x2a\x1a\xe0\xda\xf2\x06\xbd\x88"
+  "\xaf\xb5\x12\xae\x83\xfe\x46\x67\xfe\xa0\x17\xe9\x76\x1b\xab\xe9"
+  "\x1c\x82\x3e\x1f\x8e\xf7\x82\xe3\xbd\x06\xf9\xe1\xeb\xc3\xd7\xc6"
+  "\xeb\xf7\xf2\x82\x8b\xe1\xda\xc7\xcc\x52\x39\x23\x2a\xdd\xd9\x5b"
+  "\x1c\xde\x34\x11\x82\x3e\x32\x2f\x64\x30\x69\xd7\x55\x4a\xbb\x82"
+  "\xf3\x9f\xa0\x5d\xe6\x7a\x3d\x24\xb4\x7b\x51\x21\xdc\x6e\x28\x73"
+  "\xbd\x4a\x29\xed\x2e\xb0\xd2\x2e\x73\xbd\xfe\x52\xda\x3d\x2e\xdc"
+  "\x6e\x18\x73\xbd\x69\x12\xda\xbd\xd4\x4f\xb8\xdd\xe0\x62\x69\x58"
+  "\xb8\x14\x6b\x0d\x0b\xd2\x70\x70\xc9\xca\xfd\x87\x14\x4b\xc3\xc0"
+  "\x4f\x82\xf9\x6f\x8c\x01\x69\xf1\xff\xc9\x6a\xfc\xa5\xc5\xfe\x27"
+  "\xb5\xb5\xd8\x4b\x8b\x7b\x9d\x20\xfe\xb1\x37\x86\xd8\xfb\x53\xbd"
+  "\x33\xd3\x0c\x9b\x86\xfa\x1b\x7a\x07\xbf\xf4\xae\xc1\x1f\xbd\x9c"
+  "\x0c\x63\x5e\x01\xf2\x7c\x79\xeb\x05\xca\x9f\xce\x39\xd5\xed\x49"
+  "\x2e\x44\xf2\x1c\xb9\x41\x5e\xb2\xbc\x46\x5e\xa5\xf3\xc3\xbc\xa5"
+  "\x2f\x4e\x68\x92\xfd\x17\x6c\x3f\x16\x85\x50\xe3\x12\x15\x22\x6d"
+  "\x0d\xf5\x5f\x9f\xe2\x8f\xa6\xeb\x11\xce\x71\x34\x4e\x5b\x7c\x81"
+  "\xfa\x27\x38\x83\xe9\x37\x81\x5f\x0b\x9a\xf0\x58\xea\x09\xe7\xea"
+  "\x00\xc7\xd0\x4e\x13\xda\x67\xd0\xca\xa6\x69\xe9\x63\xb5\xe0\x47"
+  "\xb5\xd4\xa6\xe0\x97\xf0\x98\x4c\xa5\xaa\xd0\x4a\xf8\xfd\x8a\xec"
+  "\x72\x7f\x27\x2d\x92\x6f\x03\xaf\x7a\x6f\xf5\x65\x6f\x8d\xec\x72"
+  "\x23\xf6\xaf\xe0\x93\x1b\x52\x6f\xe2\x7c\x7e\x66\xda\x5e\x83\x56"
+  "\xfe\x2e\xf8\x66\x7c\xfc\x33\xb1\x48\xfe\x4f\x2d\xce\x0d\x5c\x9e"
+  "\x70\x0c\x94\xa9\x95\x7c\x8e\xb3\x41\x11\xb7\x12\x9f\x8f\xdb\xc1"
+  "\x79\xd2\x0d\x06\xe8\x67\xc5\x52\x3f\x7c\xdd\xd0\xdf\x4d\xea\xe5"
+  "\x78\xcc\xb9\x5c\x3e\xd1\x87\xba\x87\xc7\x10\x18\x3b\xfa\x5e\x83"
+  "\xdf\xe9\x7c\x40\x06\x55\x4d\x29\x06\xaa\xa8\xf5\x3d\xfc\x2b\x1b"
+  "\x6f\x21\x75\x42\x0b\xba\x24\xbb\x5c\x81\xff\xf6\x6d\x45\x5c\x5a"
+  "\xa3\x22\x2e\x13\xae\xa1\xcc\x78\xbd\xf8\x6f\x19\xb7\xe3\xfc\x07"
+  "\x73\x8d\xf5\xc7\x92\x84\xaf\x91\x7a\xb7\x6f\xaf\xe9\xde\x94\x16"
+  "\xf7\xa5\x3a\xe5\x16\x5c\xcb\xcf\x61\xb8\xbf\xa9\xbc\xb8\xc0\xc6"
+  "\x54\xd5\x00\x92\x0f\xbc\xb2\x12\xe7\x95\x60\x6c\x98\x40\x72\x3c"
+  "\x83\x26\xd0\x73\x78\x80\xfb\xa9\xe2\xd7\xbc\xb1\x16\xba\x21\xbb"
+  "\x42\xe7\x03\x67\xa9\xe4\x22\xfd\xd4\x15\xda\xff\xaa\x07\xe0\x7e"
+  "\xf8\x79\x22\xfc\xbd\x17\x2e\xc9\xae\xec\x22\x39\x8e\x41\x41\xf8"
+  "\xef\xc1\x31\x23\xe1\x6f\x06\x51\x79\x03\x95\xf8\x38\xd8\x5f\xc6"
+  "\xec\x0f\x37\xd9\x1f\x0e\xd7\x5c\xc0\xec\xaf\x67\xf6\x47\x98\xec"
+  "\x8f\x88\x1d\x80\x73\x7e\x3f\x7b\xe0\x7b\x82\xf1\xce\x1f\xf6\xcf"
+  "\xc4\xef\x13\xe8\x7b\xf2\x1a\xe4\xcf\x1c\x37\xb3\x41\xf6\xb3\xcf"
+  "\x6d\xc0\x17\xec\x0f\x35\x39\x3f\xf4\x9f\x89\xbe\xe8\xe5\xad\xb8"
+  "\x4f\x7f\x7e\x51\xe3\xec\xe3\x4a\xf2\x44\x57\xfc\xe8\xbe\x80\xf1"
+  "\xd3\xb4\x3d\x8d\xec\x67\x57\x3c\x46\x36\x82\x8e\x84\x63\x94\xf8"
+  "\x6f\x9a\xf6\x7f\x64\x5c\xdc\xa2\x38\xe5\x90\x08\x65\x44\xcc\x5c"
+  "\xe5\xbc\x45\x4b\x17\xc6\x8f\x1d\x12\xf1\x28\x42\x26\xd8\xf1\xa0"
+  "\x32\xdc\x29\x43\x5e\x4c\x59\x55\x01\xe8\x37\xb9\x07\x8c\xe5\x2d"
+  "\x28\x0f\xe2\xaa\xef\x9d\xbc\x5f\xbf\x29\x19\x9e\xa5\x39\x45\xea"
+  "\xe5\x2f\x41\xdf\xff\x4c\xbf\x07\xa8\x52\x22\x94\x05\xfb\xd5\xcb"
+  "\x4f\xe1\x6d\x17\xe9\x6d\x30\x92\xd2\xb9\xb0\xe5\xae\xe8\xb8\xf2"
+  "\x16\x9d\x4f\xbb\x21\xab\xef\x43\xe7\x0e\xef\x20\xb9\x2e\xc3\x15"
+  "\x7d\x9e\x52\x2d\x3f\x6c\xd0\xc8\x3f\x37\xd4\xc8\xb1\x06\xf9\xa7"
+  "\x77\x19\x7a\x36\xd1\x15\xe1\xfd\x5f\xa5\xc0\x76\xd8\x8f\xf7\xd1"
+  "\xed\xd0\xb1\xae\x8f\xc6\xc7\xe1\xfc\x1a\xfe\x7f\x6a\x01\x75\xf1"
+  "\x9f\xde\xa0\x63\x68\x4d\xfc\xf3\x11\x7c\xad\xca\xbe\xf8\xdd\xc5"
+  "\xcf\xc7\xf0\xf5\x41\x5f\xa8\x9d\x0a\xe1\xf8\x04\xe4\x06\xc7\x97"
+  "\x18\xf2\x63\xca\x30\x2f\xe8\x56\xff\x1c\x4f\x65\x78\xce\xdf\xf6"
+  "\x3e\x72\x2d\x7c\x1f\x9e\xcf\xf7\x91\xf3\xbd\xd5\xf5\x05\x1a\xe7"
+  "\x71\xe5\xb8\x6f\xa1\x19\xb7\xdb\x72\x34\x0e\xb6\xed\xd1\xa0\xdc"
+  "\xc3\x78\x1b\x3c\x7f\x8d\x42\x3c\x73\x17\xb4\x63\xd3\xe0\x29\xfe"
+  "\x06\x45\x4c\x29\x05\xfd\x76\x6f\xf0\x94\x58\xf7\x58\xc0\x16\x3c"
+  "\x63\x94\x57\x4c\x69\x83\xec\x9a\xfa\x5f\xe0\x44\x52\xf0\x33\xbd"
+  "\x69\x4e\xd1\x27\x77\x9b\xe0\xd9\x4e\xde\xbf\xe7\xae\x16\x7e\x4f"
+  "\xf6\xdf\x05\xbf\x9f\x54\xef\x42\xca\x69\x58\x8f\x5d\x1d\xf8\x5a"
+  "\x04\xa5\xf3\x29\x07\x0d\x5b\xf7\x19\xfa\xe6\x4c\x19\x72\x0b\x45"
+  "\x4e\x6d\x75\xe4\xe3\x91\x7c\xba\x06\x7e\x5f\x8a\xe4\x95\x4d\x7a"
+  "\xfa\x9d\x41\xca\x68\x9c\xfb\xaf\x40\xf8\x7d\x00\x25\xdf\x18\x51"
+  "\x72\xab\x09\xb8\xac\xde\x05\xcf\x27\x37\x78\x1c\x55\xe1\x73\xde"
+  "\x6c\x64\xde\xa3\xdd\x66\xde\xa3\xdd\xa6\xdf\xa3\x8d\x4c\x0a\x27"
+  "\xef\xd1\xf0\xfb\xb3\xe9\xe1\x4e\x14\x6e\x0f\xbf\x53\xeb\xd1\x08"
+  "\x38\x58\xa2\xea\xa9\x5f\xa2\xea\x55\x70\x0b\x29\x2a\xb5\xf5\xa8"
+  "\xaa\xa1\x0c\x7d\x90\x80\x14\xd4\xed\xa8\xee\xe5\xea\x53\x88\x7a"
+  "\xff\x4b\xe5\xbe\x14\xb5\x8b\x1e\xe7\x3f\x6e\x7b\x3f\xea\x9e\x2e"
+  "\xc3\xef\x10\x7a\x66\xc5\xa1\x61\xdb\x6f\x21\xdf\x37\x2f\xa7\xd1"
+  "\x35\xa5\xf0\xf7\xff\x74\xb7\x55\xca\xd6\xdb\xaa\x41\xcd\xb7\x55"
+  "\x03\xdc\xb5\xe4\xbd\x5b\xd8\x75\x0f\x84\xe7\xf2\x52\xab\x6b\x8e"
+  "\x6f\xc7\xf9\xef\x46\x2d\xd2\x79\x1e\x55\x61\x2c\xc3\xdf\xee\x87"
+  "\xdf\xd5\xa4\x2e\x43\x1e\x86\x9f\x54\xa8\x22\xea\x16\x7a\x16\x62"
+  "\x8f\xdf\x4b\x6c\xbb\x44\xde\x4b\xe8\xc1\x2f\xe1\x77\x13\x77\x6f"
+  "\xab\xe4\x94\x22\x5e\x39\x35\x5a\x89\x9a\x77\x4e\xf1\xaf\x4a\xfc"
+  "\x04\xa5\x36\x53\x17\xab\x56\x1a\x10\xce\x59\x53\xab\xeb\x8f\x53"
+  "\x5e\xf1\xca\x13\xaa\xb3\x78\x8c\x19\xc9\x72\xc7\xb5\x6c\x69\xdc"
+  "\x71\x8d\x7e\x97\x80\xdf\xe1\x41\xfc\xf6\xef\xb9\x85\xe3\x09\x71"
+  "\xbd\xa5\x95\x4f\x81\xd8\x55\xd4\x7d\x08\x71\xab\xe1\xc4\x8d\x8e"
+  "\x33\x1c\x77\x25\x02\xe2\x75\x99\xc4\xb0\xbc\x11\xe2\x77\x08\xb7"
+  "\x11\xa7\x2e\x49\x68\x92\x83\x27\x93\x97\x37\x9d\xa7\xd7\xc3\xe0"
+  "\x38\xee\x69\x29\x73\x69\x86\x71\x07\xbf\x0b\xbd\x5b\x3c\x25\xbc"
+  "\x59\x11\x53\xd0\xaa\x88\xd9\x65\xe5\xbd\x28\x89\x67\x34\x72\x2d"
+  "\xaf\x3b\x4b\xe2\xb9\x98\x89\x27\x9e\x3f\xf7\x57\x55\x4f\xdd\x3d"
+  "\x88\xe7\x5d\x88\x67\xbc\x06\x6d\x89\x43\x8a\xaa\xfa\x1a\xfc\xce"
+  "\xa8\xfb\x64\x78\x92\xa7\xf8\x50\x86\x0a\xf5\xf7\x74\x5c\xf7\x42"
+  "\x5c\x75\x39\xa5\x41\xf8\x5d\x69\x5b\x5c\x13\x20\xae\x77\x21\xae"
+  "\xd7\xd9\xb8\xea\xef\x41\x5c\xef\x41\x5c\xef\x41\x5c\x99\xf7\xa9"
+  "\x61\xd1\x10\x57\xfc\xee\x6d\xf5\xb9\x49\xf8\x7d\x2a\x7e\x6f\x85"
+  "\xe3\x8a\xe7\x6c\x1b\xfe\xaa\xea\x47\xbf\x47\x9d\xa7\x42\xdb\xdf"
+  "\x42\xae\xc3\x9b\x90\x2c\xf5\x10\xf2\x80\xeb\xf4\x78\xea\x20\x92"
+  "\x43\x7b\x80\xfb\x4b\x08\xc7\xb7\xea\xa0\x1e\xad\x98\x8d\x06\xe8"
+  "\x72\x49\x9c\xab\x74\x5f\xe0\xbc\xb1\xdf\xdd\xbf\xaa\xe4\x9b\x13"
+  "\xd0\x8b\x38\xe6\x01\x97\x95\xe8\x44\x60\x05\x32\x8f\xb9\x21\x3f"
+  "\x2e\x10\xe2\x94\x88\xe3\x2e\xfd\xb9\xbd\x91\x68\xff\x73\xdb\x70"
+  "\xee\xe1\x73\xdb\xde\xcf\x6d\x43\x12\xff\x73\x7b\x63\xa2\xb4\xe7"
+  "\xf6\xc6\x84\x87\xcf\xed\x83\xf0\xdc\xde\xf0\x35\x7f\x6e\xdb\x74"
+  "\x4b\x5c\x64\xcc\xdc\xe8\x85\xd1\x0b\xff\xa2\x7c\x6b\x59\x7c\xe4"
+  "\x12\xa2\x5e\x38\xfa\x45\xa5\x37\xf8\xcb\x37\xc2\x78\xfd\x8d\x77"
+  "\x0d\xda\xd7\xb7\x46\x6e\x08\xf1\x76\xa6\x72\xaa\x63\x0d\x39\xd5"
+  "\xda\x8d\xa0\xc5\xf1\xf3\x9d\x07\x1a\xfb\x8a\xac\x65\xcf\xff\x81"
+  "\x73\x54\xc7\x5d\x43\xf8\xff\xe4\xfd\x70\x6e\x0d\x5e\x43\x59\xb0"
+  "\x89\xaa\xc7\x6b\x28\x4f\x1e\xc7\xda\x42\x7b\xfd\xb1\x20\xf0\x13"
+  "\x21\xde\xa8\x39\x24\x48\xbe\xee\x7b\xe4\xea\x5e\x83\x02\x0c\x06"
+  "\x8a\x52\xa7\x5c\x03\xdd\x77\xaf\x51\x1d\x7c\x0d\x61\xad\x73\x45"
+  "\x76\x77\x96\x72\x79\x3a\xfe\x77\xb4\x72\xf9\xea\x0b\x57\x64\x77"
+  "\x9a\xe9\x3c\x4e\x6f\xaa\x9e\xda\x14\xe3\xa1\xff\x38\x20\x07\xbf"
+  "\x3b\xdd\xde\x9b\xaa\xdb\x0b\x7e\x63\x6f\x4b\x93\xfc\xdd\x5b\x80"
+  "\x9b\x8c\x27\x29\xfc\x0e\x14\xf7\xc1\xbb\x71\xd0\xf7\xa0\x7b\x89"
+  "\x36\xbd\x33\x1b\x3f\x5f\xa0\xaf\xea\x8e\x5e\xa9\x91\xe3\x77\xc0"
+  "\xf8\x99\x6b\x54\x0c\x54\xae\x84\x7b\x81\xeb\xd4\x6c\xde\x44\xd5"
+  "\x6a\xbd\x62\xca\x9c\x95\x48\x7e\x6f\xf5\xcd\x70\xd0\x3d\x59\x58"
+  "\xb3\x64\xc2\xbe\xb5\xb0\x8f\xbc\x8f\xbc\xa3\xa0\xba\x69\x87\x61"
+  "\x9e\x03\x5c\xcb\x6e\xc8\x6e\x96\xe0\x3a\x52\x59\xc4\x9b\xd4\x37"
+  "\xe5\xc7\xec\xd2\xed\x9c\x12\xae\xc3\x9a\x72\xc8\x94\xd8\xe6\xfc"
+  "\x98\x02\x5d\x7e\x4c\xe9\x2c\x1f\xfa\xbd\x3b\x1c\x7f\x3b\x1d\xdf"
+  "\x47\x73\xde\x9c\x22\x38\xbe\xf1\xb6\x22\x79\xff\xed\xbc\x64\xff"
+  "\x53\x89\x05\x48\xf9\x3a\xe6\xbf\x9b\xe7\xa6\x14\x50\xba\xa1\x81"
+  "\xc0\x7f\x05\x9f\xa0\x6f\x02\x80\xff\x82\x2c\xf9\x8f\xcc\x53\xd0"
+  "\x23\xc2\x83\x15\x08\xda\xaa\xc3\xcf\x11\xd6\xa9\x25\xd0\x17\xf8"
+  "\x19\xc1\xcf\x02\xcd\x87\xc0\x85\xc6\xe7\x05\x3f\x4b\x98\xef\xe8"
+  "\x67\xd7\xec\xd9\xc1\xcf\xcb\x63\x5a\xe4\x81\x9f\x17\xcc\x87\xf8"
+  "\x79\xc1\xf3\x7f\x36\x32\xcf\x8b\x7b\x2d\xf2\xd8\x02\x5c\x58\xa5"
+  "\x2b\xa3\x9f\x19\xac\x27\xcb\x75\x26\x3c\x88\xdf\x1d\x99\x3c\x2f"
+  "\xd9\xc6\xe7\xc5\xc8\x83\xf0\x4c\xe8\xf0\xf3\xf2\x57\xd5\xa0\x96"
+  "\xbf\xb2\xcf\x4b\xc8\x79\x0f\x44\x73\xe4\xea\x9a\x49\x85\xf0\xbc"
+  "\xe0\x9c\x9a\xde\xc8\x83\xf0\xbc\xe0\xf5\x49\x34\x0f\xbe\x03\x3c"
+  "\xd8\x00\x3c\xa8\x85\xed\xf0\x9c\x6c\x7b\x9b\xe1\x41\xe6\xf9\x68"
+  "\xfe\x2b\xc3\x83\xd7\x95\xa8\x65\x08\xe6\xc1\x2d\x02\xfa\xe5\xbc"
+  "\x19\x0f\xde\x9e\x2a\x8d\x07\x6f\xd3\xf5\xcf\x70\x0c\x5b\x20\x9e"
+  "\x38\x8e\x53\xbc\x29\x5d\x79\x01\xf0\xdf\xcc\x2e\x16\xb7\x38\xfe"
+  "\xb8\xed\x65\xc6\x2f\x5e\x9e\xe3\x89\x1b\xe0\xbc\x41\x77\xcf\x32"
+  "\x76\xd4\xea\xff\xe4\x98\x72\x1d\xe6\x38\xcc\x77\x98\xe7\x30\xe7"
+  "\xe1\xe7\x03\x73\x1d\xe6\xb9\xdf\xc3\x18\x00\xbf\xd7\x57\x44\x5d"
+  "\xa2\x39\x30\xf5\x32\xf2\x48\x9d\x88\x06\x54\x95\xea\xc1\xdf\xdc"
+  "\x41\x98\x03\x4d\xc7\x37\xcc\x79\x38\xb6\x9b\xef\x12\xce\xc3\xe3"
+  "\x1c\xe6\x37\x8b\x71\x0e\x62\x0b\x31\xf1\xc3\xe3\x1c\x9d\xb7\xc8"
+  "\x78\x7c\xdc\xf6\x5e\xc4\x97\xe4\xf5\x42\xae\xf7\x56\xdf\x19\x69"
+  "\xe9\x4d\xee\x4c\x32\x7a\x13\xfc\x8c\xe3\x67\x5d\x23\xbb\x49\xbf"
+  "\xaf\x52\xf7\x1d\x03\xcf\xfb\xcd\x61\xc4\x8b\xbe\xad\x25\xfe\xa8"
+  "\x95\x7c\x5b\x4e\xb1\xd4\x8f\xf5\xff\x77\xf2\xc9\x3c\x01\xf0\xfb"
+  "\x5e\x61\x4d\x54\xfe\x40\x15\xee\x63\x7c\xcf\x6f\xfa\x00\x46\xf3"
+  "\xe3\xd2\x36\xe0\x7e\xcb\x8f\x5b\x09\xff\xcf\x64\x71\x77\xe7\xc4"
+  "\x89\x44\x84\x66\x25\x8a\xc5\xdd\x1d\x32\x07\xe2\x87\xa0\xc7\xa9"
+  "\x90\x20\x67\xc3\x0f\x41\x2e\x80\x11\xef\x45\xfa\x34\x74\x37\x27"
+  "\xb7\x3a\x55\x47\xd5\x2b\x97\xa3\xa1\xc0\x9d\x43\x4e\xea\x10\x3a"
+  "\xd9\x88\x50\x55\xc0\x02\x88\x77\x6e\xe0\x3e\x83\xd6\x59\x23\xd3"
+  "\x36\x80\x7f\xac\x07\x2e\x76\x36\xe5\x62\xc2\xbb\x5a\xba\x66\x58"
+  "\x53\x4e\xae\x06\xb7\x35\xbd\x0c\xb9\xc3\x78\xec\x7c\x45\x76\xef"
+  "\xc4\xb2\x64\x84\xd7\xd6\xba\xc0\xff\x73\x5b\x7a\xcd\x0d\x84\xf3"
+  "\x7b\x52\x3f\xcc\x94\xc5\xbe\x82\x06\x50\x21\x33\x65\x78\x5e\xc4"
+  "\x6e\x43\x91\xdc\x00\xdb\xc8\x3c\xab\x22\x84\xf7\x67\xb5\x38\xd3"
+  "\x3a\xcd\x00\xc7\x54\x36\x16\xa1\xac\x04\x57\x84\x8f\x27\x73\xf7"
+  "\x8a\x10\x3e\x3e\x3b\xce\x83\x9e\x57\x41\x9f\xa7\x2b\x42\xf8\x5c"
+  "\x3d\x6c\x7f\xcf\xe0\x86\xd6\x2f\x57\xa0\x93\xe5\x95\x74\x1b\x27"
+  "\xcb\xff\x85\x70\x1b\xf0\x2c\xc0\xff\x8f\xa2\x0d\x09\xde\xc0\x09"
+  "\x45\xb0\xff\x3f\x68\xc3\x8d\x7e\xf0\xef\x15\xf8\xb9\x8b\xae\xc9"
+  "\xee\x8d\x3c\x59\x6e\x40\xee\xe9\xe3\x28\xc0\x34\x55\x85\xd7\x6b"
+  "\xa6\xa0\x6e\x70\xed\x63\xab\x6a\x72\xc0\xd3\xde\x1d\x8c\xd7\xf3"
+  "\x53\xa9\x21\x0d\x06\x2a\xe4\xba\x21\x35\xe4\x06\xfe\xdb\x7a\x2a"
+  "\xe4\x57\xfc\xb7\xb3\x97\x2b\x99\xb9\xbc\x45\xf4\xbc\xc3\xac\xbb"
+  "\x83\x11\xbe\x56\xfc\x77\xf1\xdf\xdb\x10\xa7\x62\xfe\xe6\x30\xfa"
+  "\xda\xf0\xdf\xc4\x6d\x9a\xfe\xcd\x53\xf8\x6f\xbe\x41\xff\xcd\x03"
+  "\xf0\xaf\x27\xc4\x43\x85\xe3\x80\xff\xbe\x81\x0a\x72\xa1\x52\x83"
+  "\x9c\xe8\x73\x9a\xea\xf9\xce\xb9\xcc\x9c\x33\x98\xce\x03\xc0\x39"
+  "\xcd\x14\x7d\x3c\xdd\xc6\x25\x59\x93\x0c\x6f\x7f\x3a\x48\x8d\x2c"
+  "\x63\xd8\xb4\x95\x8c\x9d\x4d\x31\x64\xec\x24\x31\xa5\xb1\x12\x12"
+  "\xe4\x02\x71\xf3\xc0\xe3\x2c\xb4\x31\xb1\xad\x8d\x1f\x82\x9c\x70"
+  "\xbc\x31\x6e\x8c\x58\xc2\x38\x32\x62\x88\xbe\x4e\x2d\x42\xa6\x98"
+  "\x81\xff\xbb\x32\xed\x64\x1b\xdb\x81\x6b\x40\x46\x1c\x3d\x0d\xfb"
+  "\x2d\x71\xd4\x12\xc9\xe2\xa8\xc5\xa5\x29\x85\xa2\x30\x8e\xd4\xc1"
+  "\x19\xb8\x9d\xb3\xec\xf5\xcc\x94\x61\x8c\x3d\x60\xd8\x1a\x89\xe3"
+  "\xf4\x74\x12\x52\x90\xfb\x69\xde\x49\xdf\x4f\x92\x5a\x81\xaf\xd5"
+  "\x78\x1f\xf8\x1a\xd6\x1b\x94\xc8\x78\x1f\x1b\x5a\x06\x43\xbb\x37"
+  "\x10\x73\xce\x39\xdc\xb6\xb1\x0f\x20\x66\xc8\x78\x8e\xf1\xf8\xf5"
+  "\x06\x15\x5c\xf7\x30\xfa\x1c\x82\xb9\x2b\x3c\xf8\x69\x19\x62\x8e"
+  "\xb9\xc7\x92\x10\x08\x62\xd0\x5a\xc1\xb7\xe0\xef\xb4\x8c\x27\xd7"
+  "\xf6\x95\xbe\xf9\x87\x20\x1c\x57\x39\xb3\x7d\xb6\x09\x26\x98\xf6"
+  "\x9b\xf8\xda\x5f\xc5\x69\x3f\x08\xda\x4f\x84\xf6\xb1\x96\x0b\xc6"
+  "\x39\xbc\x96\x1d\x74\x3b\x89\xa4\x7d\x23\x6e\xa9\x9c\xb0\xc2\xd8"
+  "\xe5\x78\xee\x6b\xeb\x24\xc2\xa7\x5a\x9a\x3b\xe9\x39\x57\x72\x43"
+  "\x91\xc1\x6c\xce\x95\xe9\x9c\xbc\x7d\x29\x5a\x66\xbe\x55\x2b\x5d"
+  "\xdb\x0b\xe7\xca\xb0\x26\x2d\x01\x3d\xc7\xce\xb9\xfa\x1e\xef\x1f"
+  "\xa1\x4e\xb8\x64\x32\xe7\xaa\x95\xfe\xde\x8b\x46\xd6\x1a\x7a\x4f"
+  "\x8e\xe4\xf0\xbb\x37\xd9\xae\xcd\x33\xdd\xce\xce\x69\x24\xdb\xf1"
+  "\x7c\x71\x26\x67\xdc\xf0\xcf\x52\x9c\x37\x6c\x8d\x37\xe6\x6a\x05"
+  "\xbc\xb0\xfd\x9a\x59\xee\xd2\xd4\xa6\x99\xe1\xff\xc2\x9a\x59\x37"
+  "\xd0\xaa\x66\x96\x3b\xf9\xb7\x69\x66\xb9\x6c\x07\xfd\xdc\xcb\x65"
+  "\xab\xe8\xe7\x5e\x2e\xa3\x9f\xef\xf5\xd0\x9e\xee\xc3\xcc\x22\xea"
+  "\xe3\xd7\x7c\x31\xce\xb7\x81\x06\xde\x97\x50\x26\x2f\x01\xdf\xad"
+  "\x97\x3f\x49\xbd\x0b\x7d\x87\x6b\xcd\xbd\xbb\x1c\xc6\x6f\xdd\x19"
+  "\x54\xe9\x8c\x35\xf3\x25\x68\x07\xed\xac\xa4\xdf\x29\xce\x61\x72"
+  "\x83\xba\x64\x88\x85\x53\x55\x53\x13\xa2\x8f\x83\x7d\x30\xae\xd5"
+  "\x61\xcd\x7c\xd4\x50\x26\xdf\x06\x7d\x0a\x3f\xa0\xa9\x33\x63\x4d"
+  "\x35\xf5\xbd\xd5\xba\x3d\xbc\x5a\x5a\x8e\xc2\x75\xab\x4d\xb5\xb4"
+  "\x8e\xae\x73\x8d\x73\xfc\x58\x1f\x18\x88\x86\x0e\x07\x3d\x1d\x8b"
+  "\x75\x35\xd6\xd2\x06\x8e\x96\x36\x54\x58\xd7\xd2\xfa\x21\x0f\xb5"
+  "\x74\x47\x69\x69\x63\x4e\xc1\x5c\x4b\x1b\x36\x4b\xd3\xd2\x86\x82"
+  "\x87\x5a\xba\xab\x69\x69\xc3\x4a\xa3\x96\x36\x64\x3c\x3e\x14\xe7"
+  "\xf8\xb7\x19\xb5\xf4\x3a\x94\x66\xa1\xa5\xd7\xa1\x3c\x4b\x2d\xad"
+  "\x53\xb3\x5a\x5a\x17\xce\xd1\xd2\xf2\x6e\xbb\x2d\xb4\xb4\x1c\x5d"
+  "\x14\xd2\xd2\xc0\x63\x0d\x58\x4b\x63\xac\x61\x5d\x8d\xf5\x34\x5c"
+  "\x7b\x26\x8d\x3b\xb9\xcc\x53\x92\x96\x96\xcb\x3c\xec\xd2\xd2\x72"
+  "\xd9\x62\x7e\x2d\xad\x53\x0a\x6b\x69\x9d\x92\x57\x4b\xcb\x9d\x3c"
+  "\xdb\x34\x90\x5c\x7e\xbe\xcb\x6b\x69\xb9\x3c\x8d\x57\xef\xc8\xe5"
+  "\x6b\x69\x2d\x2d\x97\xc5\xb6\xbb\x96\x86\x36\x79\xb5\xb4\x5c\xae"
+  "\xa7\x75\x87\x5c\x16\x6f\xa1\xa5\xf1\x39\x7c\x5a\x5a\xee\x34\x82"
+  "\x39\x27\x96\xa3\xa5\x99\x36\x60\x0c\x9d\x2a\xa8\xa5\xe5\x4e\x57"
+  "\xc9\x98\xea\x74\x88\x68\x69\x12\x53\x0b\x2d\x2d\x77\xca\xb5\xa9"
+  "\xa5\x19\x0c\xd1\xd7\x29\xa4\xa5\xe5\x4e\xe7\x2c\xb5\xb4\x4e\xc9"
+  "\xab\xa5\xe5\x2e\x07\x58\x1c\xb9\xcc\xe0\x68\x69\xb9\xf3\xc0\x07"
+  "\x42\x4b\x0b\x63\x2b\x8d\xa3\xa5\xe5\xce\x37\x45\x6b\x69\xb9\xcb"
+  "\x10\x51\x5a\x9a\xc6\x1c\x8f\x96\x96\xbb\x2c\x36\xc7\x1c\x47\x4b"
+  "\xcb\x5d\xb2\x79\xb5\xb4\xdc\x65\x27\x47\x4b\xd3\xed\xf3\x68\x69"
+  "\xb9\xcb\x69\x4e\xfb\xe6\x5a\x5a\xee\x72\x9d\xa3\xa5\x99\xe3\xda"
+  "\xb4\xb4\xbc\x1b\x33\x9f\xb1\xf5\xa4\x68\x2d\x2d\xef\xb6\xd4\xaa"
+  "\x96\x96\x77\x4b\xe6\x68\x69\x79\x37\xfa\x7d\xbf\x46\xde\x6d\x17"
+  "\xad\xa5\xe5\xdd\x22\x18\x8d\x5d\x66\xba\x9d\xd5\xd2\x64\xbb\x85"
+  "\x96\x5e\xd7\x4d\x6d\x43\x4b\xfb\xdb\xaf\xa5\x7b\xa1\xb2\x36\x2d"
+  "\xdd\x0b\x19\xb5\x34\xfe\x56\x52\x21\xe8\xd3\x42\x5a\x4f\x9f\x42"
+  "\x27\xeb\xf0\xf5\x3f\xb2\xd8\xba\x9e\x76\xf7\x65\xf5\x74\x8f\x74"
+  "\xf2\xec\xf7\x88\x24\x7a\xba\xc7\x90\xb6\x1c\x34\x68\x69\xac\xa9"
+  "\x99\x1c\xf4\x99\x2c\xf8\xd9\xb7\xbc\x8c\xd6\xd3\x78\x1d\x00\xd6"
+  "\xd4\x58\x4f\x63\x5d\x8d\xb5\x72\xc5\x4a\x84\x2a\xb5\x4d\x78\x0e"
+  "\x4b\xb5\x7a\x00\xee\xd7\x1e\x9e\xa0\xc3\x35\x30\xb6\x55\xc3\xb9"
+  "\x9a\x7d\xb7\x9a\xf0\x9a\x92\xda\xf5\x97\xe0\x1c\x0d\x39\x07\xf6"
+  "\xd7\xe0\x73\xe0\x98\x5a\x12\x0b\xb7\x18\x32\x7e\x32\x7a\x5c\xee"
+  "\xda\x83\xa3\xc7\xc9\xb1\x67\x8c\x7a\x7c\x2b\x5c\x03\xfc\x38\x63"
+  "\x2d\x8e\x35\x39\x68\xf1\xf2\xad\x9b\xa8\xb2\x6d\xbd\xa9\xe3\xf7"
+  "\xd6\xb9\xfa\x1b\x35\x79\x36\x6c\x5b\x0f\xdb\xe0\x3a\xaa\x8f\x17"
+  "\x21\x74\xe4\x96\x1a\x6b\x0a\xcd\xd6\x2b\xc8\x19\x62\x56\xf3\x2e"
+  "\xfc\x7d\x7c\x3e\x9c\x13\x6f\x3c\x07\xc6\xf7\x72\xa2\xe1\xdd\x86"
+  "\x19\x4c\xf3\xe1\x72\xd7\x63\x6d\x1a\x1e\xfa\x09\xe7\xdb\xf1\x37"
+  "\xc8\x68\x1d\x3f\x64\x4a\xac\xce\xa8\xe3\xbd\x4c\x74\xbc\xfc\xd1"
+  "\x7c\xa3\x8e\xc7\x6b\xb9\xda\x74\x7c\x3c\xa3\xe3\xe5\xae\xd7\x25"
+  "\xea\xf8\x33\x5d\x45\xc7\xbb\xc9\x64\xce\x6e\xe1\x44\xc7\x17\x26"
+  "\xb4\x8f\x8e\xc7\x1a\x1e\xeb\x76\xac\xe1\xb1\xa6\xc7\x3a\x1e\x6b"
+  "\x7a\x03\xa3\xe3\xb7\x99\xe9\x78\x03\x68\x76\x73\x1d\x8f\xb5\xbd"
+  "\x51\xc7\x1b\x4c\x75\xbc\xfc\xd1\xb9\x92\x74\xbc\xfc\xd1\xf0\x76"
+  "\xd0\xf1\x9d\x13\xb7\x2e\xa4\xe3\x55\x66\x3a\x1e\xeb\x76\x78\x26"
+  "\xeb\xb0\x9e\xaf\x52\x43\xdf\x2c\x06\x4d\x0f\x7a\x5e\xb2\x96\x97"
+  "\x3f\x1a\x60\xaa\xe5\xb7\xf5\x32\xd5\xf2\x6e\x01\x96\x5a\xde\x2d"
+  "\xdc\x44\xcb\x97\x6b\xe4\xae\x2b\xe9\x71\x02\xf8\x40\xfd\x16\xd6"
+  "\xe9\x8f\x68\xb9\x5a\xbe\xd7\x01\x4b\x2d\xef\x56\xc2\xab\xe5\x89"
+  "\xbf\xe7\x6a\x79\xaf\xb8\x95\xba\x36\x2d\xef\x76\x5e\x9a\x96\x77"
+  "\xab\x6d\xf3\x1a\xf2\x47\x0e\x93\xf1\xc8\x2d\x49\x48\xdf\xdf\xf3"
+  "\x30\xd5\xf7\x3d\x66\xb0\xfa\x3e\x9e\xd5\xf7\xf2\x47\x62\x05\xf5"
+  "\x3d\xec\xa3\xe7\xd5\x7b\xe4\x6a\x70\x5b\x58\x97\x01\xb7\xd6\x29"
+  "\xe3\xb0\x36\x73\x97\x61\x6d\x06\x7c\x56\x87\xe7\xa3\x5f\x91\xf7"
+  "\xac\x30\xea\x7c\xda\xa7\x62\xad\xbf\xbc\x2b\xea\xb1\x9e\x0b\xf8"
+  "\xf5\x58\xcf\x65\x58\xf7\xd0\x6b\x7d\xe5\x3d\x02\xa1\x4f\xea\xda"
+  "\x57\xef\xf7\x08\xe4\xd7\xfb\x3d\xaf\x13\x6d\xd4\x63\x26\x8e\x0b"
+  "\x57\xef\xc3\x39\xbc\x7a\xdf\x7d\x20\x73\x4e\x20\x57\xef\x93\x36"
+  "\x60\x8c\x1f\x2b\xac\xf7\xdd\xcf\x91\x31\xdf\x7d\x37\x19\xf3\x49"
+  "\x8c\x2d\xf5\xbe\x7b\xba\xa9\xde\xc7\xf1\xb7\xd4\xfb\x04\x53\xf4"
+  "\x75\x0a\xea\x7d\xf7\x93\x16\x7a\x1f\xfe\x26\xd6\xfb\x3a\x13\x5c"
+  "\x15\x62\x5c\xbd\x85\x71\xe5\x79\x08\xe3\x0a\x8f\xab\xca\xf9\x18"
+  "\x57\x9e\xb3\x9b\x0c\x46\xdd\xbf\x0e\xda\xf3\xe8\x63\xae\xfb\x31"
+  "\x8f\x58\xc3\x59\x6c\x1c\x1a\x80\xb1\x86\x71\x66\x8c\x1b\x3e\x1e"
+  "\xe3\xad\x63\xb1\xe6\x51\xc3\x8f\x35\x8f\xcb\x74\x9c\x19\xac\xe1"
+  "\x7c\x25\xf1\x01\xf4\xfd\x35\x8b\xf3\x01\xf8\x1c\xcf\xe1\xe2\x7c"
+  "\x00\xc6\x22\x9f\x0f\xf0\x5c\x66\x8e\x45\xae\x0f\xf0\xcc\xe7\xf7"
+  "\x01\x9e\x25\x5c\x1f\x80\xdb\xe7\xf3\x01\x9e\xe7\x38\xed\x5b\xf8"
+  "\x00\xcf\x3b\x5c\x1f\x40\x8e\x63\x7d\x40\xaf\x42\xc2\xc5\x8f\x78"
+  "\x89\xf7\x01\xbd\x92\x19\x7e\x27\x3e\xe0\x92\xb9\x0f\xe8\xb5\x8a"
+  "\xeb\x03\x7a\x05\x11\x7e\xed\xb5\xbf\x89\xf6\x01\xbd\x16\x90\xed"
+  "\x8f\x28\x4c\xb7\xb7\xf9\x00\x66\x7b\x93\xa9\x0f\x50\x63\x1f\xd0"
+  "\xab\xcc\x86\x0f\x08\xb4\xdf\x07\x0c\x48\x64\x7d\xc0\x80\x44\xeb"
+  "\x3e\xe0\xf1\x65\xd6\x7d\xc0\x13\x07\x59\x1f\xd0\xd7\x85\x70\x42"
+  "\x9f\xab\x84\x13\xfa\xd0\x79\x2b\x78\xae\xd8\xbc\xfa\x62\x7a\xfe"
+  "\x79\xd9\xde\x5b\x65\xf2\x7d\x71\x4c\x5e\xfd\x2e\x78\x80\x04\xd0"
+  "\xf3\x8d\x44\xcf\x03\x67\x1e\xc7\x3e\x00\xeb\x75\xe2\x01\xfa\xe4"
+  "\xc3\x36\x0d\xf4\xf9\x71\x68\x4b\xb3\x67\xb9\x5a\x8e\xe7\x86\xe1"
+  "\x63\xe1\x79\xaf\xc9\x82\x71\x04\xb6\xd7\xc0\x31\x6a\x7c\x0e\x6c"
+  "\x3b\xa3\x8e\xa3\xcf\x4b\xc7\x5e\x01\xce\x53\xc3\xfe\x5a\xb3\xf3"
+  "\xaa\xf1\x79\x95\x89\xb4\x17\xa8\x26\xb1\xf3\xbe\x08\xdb\xcb\x59"
+  "\xdf\xa0\x98\x48\xfb\x86\x46\xc6\x37\xc0\xb1\xd0\x56\x19\xed\x1b"
+  "\xde\x02\xdf\x00\xd7\x0d\x3f\xa6\xbe\xe1\x30\xf8\x86\x52\xf0\x39"
+  "\x07\xef\xad\x53\x24\x9a\xf8\x86\x52\xec\x13\xb0\x67\xc0\x5e\x01"
+  "\xc6\xb5\x83\xd8\x47\x1c\x69\xd1\xe0\xb9\xf6\x67\xc0\x37\xd4\xe0"
+  "\xf3\x4d\xce\x3d\x68\x7a\x2e\x3e\x1e\xae\x51\x4d\x7b\x0e\xd0\x79"
+  "\x70\x0d\xb5\x5b\x2f\xd1\x9e\xa3\x1c\xce\xad\x26\x9e\x43\x51\x6f"
+  "\xe2\x39\x0e\x13\xcf\xe1\x5d\xc4\x79\x6f\x20\xf7\x1a\x25\xde\x73"
+  "\xfc\xae\xbb\xd5\x77\x07\x72\xaf\xb9\x62\x3c\x07\xdc\x77\x99\x51"
+  "\xbf\x5a\xcc\x43\xc4\x73\xf0\x41\xc3\x62\xbd\x6a\x75\xde\x1a\xa3"
+  "\x65\xb1\x76\xc5\xba\x15\xeb\x57\xbb\x3c\x07\x5c\x7f\x79\x53\x3b"
+  "\xbe\x3b\xe8\x06\x9e\x23\x41\xd8\x73\x98\xfa\x0d\xec\x3f\xb0\xe7"
+  "\x80\x67\x8c\xf6\x1c\x85\x19\x66\x9e\xa3\x9b\x0d\xcf\x21\x33\xf5"
+  "\x1c\xbd\xcf\x4a\xf3\x1c\xbd\xcf\xb4\x83\xe7\x28\x7b\xe8\x39\xda"
+  "\xdb\x73\xf4\x56\xb7\x79\x0e\x39\xf3\xfe\xa0\x97\xd1\x73\x78\xab"
+  "\x2d\x3d\x87\xf7\x19\x13\xcf\x71\x58\x23\x57\xd0\xef\x45\x89\xdf"
+  "\x50\xa8\xb8\x7e\xe3\x49\x1f\x4b\xbf\xd1\xa7\xbf\x34\xbf\xd1\x67"
+  "\xaa\x34\xbf\xd1\x27\x80\x5c\x1f\x7e\x57\xfa\x78\x13\x19\xf7\xbc"
+  "\x1b\x58\x0f\xf2\xb8\xda\x74\x9b\x6d\x0f\xd2\xe7\x2c\xbf\x07\x79"
+  "\x3c\x51\xd8\x83\x3c\x9e\x28\xec\x41\x9e\x58\x85\xb5\x22\xf6\x1b"
+  "\xd0\x3e\x68\xc5\x27\x66\x98\xbe\x6b\xc8\xb2\xa1\x0b\xcd\xfd\x47"
+  "\xec\x5b\xc4\xaf\x74\xbc\x2e\xec\xab\xe5\xd7\x85\x7d\xf5\x58\x73"
+  "\xe9\x68\x5d\xd8\xe7\x4c\x61\xbb\x7b\x90\x3e\x67\xf8\x3d\xc8\x13"
+  "\x4c\xfe\xb7\x4f\x8d\xa5\x07\x81\x73\x78\x3d\xc8\x13\x3b\x99\x73"
+  "\xce\x70\x3d\x08\x69\x03\xf4\xc5\x31\x61\x0f\xd2\x2f\x8c\xe8\x8d"
+  "\x7e\xc3\x89\xde\x20\x31\xb6\xf4\x20\xfd\x5c\x6c\x7b\x10\x82\x29"
+  "\xfa\x3a\x05\x3d\x48\xbf\xb6\xf7\x1f\xac\x07\x79\x3c\x11\x7b\x10"
+  "\x7e\x5c\x0d\x18\xc1\xc5\x55\xff\xd3\x5c\x0f\xd2\x6f\xab\xb9\x07"
+  "\x79\x00\xb1\xa6\x65\xdf\x3f\xe0\x7b\xea\xbf\x58\xbc\xef\xe8\xbf"
+  "\x53\x9c\xef\xc0\xf8\xe3\xf3\x1d\xfd\x6f\x9a\xe3\x8f\xeb\x3b\x06"
+  "\xf4\xe0\xf7\x1d\x03\x86\x70\x7d\x07\x6e\x9f\xcf\x77\x0c\x98\xc1"
+  "\x69\xdf\xc2\x77\x0c\x88\xe1\xfa\x0e\x72\x1c\xeb\x3b\x9e\x54\x10"
+  "\x4e\x7e\xbc\xbf\x78\xdf\x31\xe0\x8e\x75\xdf\x31\x40\xcf\xf5\x1d"
+  "\x03\xaa\x09\xa7\x3e\xa9\x22\xbe\x63\x40\x1d\xd9\xfe\x78\x3f\xd3"
+  "\xed\xac\xef\x20\xdb\x2d\x7d\xc7\x93\xfe\x36\x7c\x87\x9b\xae\x78"
+  "\x4a\x78\xcb\xe0\x29\xb1\x2d\x79\xc9\x39\x4f\xd7\x3d\xa9\x6f\xfb"
+  "\xb6\x43\x38\x68\x88\x5a\xd0\x14\x73\x91\x1c\xd7\x47\x48\x39\x0d"
+  "\x5a\x61\x2e\x59\xc7\x80\xf5\xc2\xde\x04\xac\xfb\xd4\x2e\xd0\xa7"
+  "\xa8\x55\x11\xec\xaf\x1b\x16\x96\x86\x75\x43\x73\xf1\x14\xff\xa6"
+  "\xbc\x98\x82\x66\xbc\x86\x61\x01\x92\xbf\xd9\xc0\xaf\x05\x57\xd4"
+  "\x52\x06\xc0\xbc\xeb\xf4\x50\xa2\x03\x2b\xa2\x2e\xd3\x38\xc6\x5a"
+  "\x62\x0b\x68\x89\xaa\xc6\x1a\x5a\x5b\xb8\x85\x2b\x51\x61\x0a\x52"
+  "\xf4\x68\x40\x1e\x3d\x64\xb2\x6e\xaf\xcd\x46\x48\x0f\xba\x62\xa2"
+  "\x0f\x65\x18\x5a\xa7\xc4\xf5\x90\x7a\x12\x6d\x51\xea\xa2\x63\xb4"
+  "\xc5\x7b\x77\xd1\xb0\xad\x38\xff\x5c\x41\x34\x05\xfe\x0e\x44\x33"
+  "\xd1\x14\x03\x5a\xee\xa9\x06\xb5\xad\x61\x68\x5b\x9b\xc2\xae\x61"
+  "\x68\xcd\x65\xf5\x04\xd6\x12\xd4\x9b\xa0\x05\x9b\xc8\xfc\x91\xe5"
+  "\x33\xc8\x1a\x86\x61\x75\x48\xbe\x7d\x0e\x72\x2d\x0f\xbf\x84\x73"
+  "\x45\xde\xe5\x75\x3b\xd1\xb2\xc9\x68\x80\x0e\xeb\x07\xd0\x86\xe5"
+  "\x75\xf9\x08\xd7\x7a\x2c\x04\x1d\x51\xc0\x68\x88\x80\xb9\x02\x1a"
+  "\x02\xc6\x6a\xac\x23\xc8\x18\xad\xbc\x79\x42\x75\x02\x89\xd7\x86"
+  "\x4a\x3a\x4f\x29\xb8\xb6\xb9\x18\xfc\xc1\xe0\x29\xfe\x7a\x45\x72"
+  "\x0e\xa9\xfd\x19\xa7\x36\x7c\xb8\x76\x3f\xae\xe9\xf8\xe9\xa5\x7a"
+  "\x19\xae\x63\x8e\xbf\xe9\x69\xd8\x13\x96\xc6\x59\x77\xd2\xca\xc4"
+  "\xac\x95\xc4\x0c\x6b\xc2\xb0\x06\x44\xbd\xa9\x93\x23\xd8\xd7\x93"
+  "\x5e\x77\xd2\xa4\x41\xec\xb7\x3d\xbd\x71\xdd\x2d\xba\x7e\xa6\x61"
+  "\x45\x54\x77\x03\xc4\x85\xca\x90\xa3\x92\xbb\x4d\xb4\xee\xcb\xc2"
+  "\xdf\xfb\x4c\x97\xf5\xc0\xba\x0f\xb0\xff\xe8\xf6\x16\x88\xd1\x45"
+  "\x12\x23\x2a\xc3\x95\xfe\x57\xb7\x42\xa5\x84\xb6\x07\xb5\xb6\x82"
+  "\xee\x63\xbe\x0d\x6a\xac\x25\x4c\xaf\x21\x6a\xc1\x6b\x88\x6a\x90"
+  "\x2e\x97\xd4\x67\x04\x5c\xc8\x70\x5d\x13\xb8\x86\x7e\xf4\xda\xa1"
+  "\x56\x15\xc6\x91\xc7\xb6\x2b\x78\xbd\xd3\xf7\x74\x7c\xf4\x4c\x5c"
+  "\xf0\x37\x42\x8d\x7a\xae\x72\xd7\x59\xb2\x7e\xd4\x2c\x16\xad\x3b"
+  "\x89\x6e\xa7\xd7\xf3\xac\x7b\x72\x26\x9e\xf7\x73\x43\x3e\x68\xed"
+  "\x89\x78\xd0\x4e\xf1\x62\xe3\x32\x28\xb3\x6b\xc4\xc5\xe3\x37\x16"
+  "\x97\x81\x7e\x24\x2e\x83\x07\x4a\x8b\xcb\x60\x65\xd7\x88\x8b\xeb"
+  "\x6f\x2c\x2e\x83\xaa\x49\x5c\x86\x1c\x92\x16\x97\x21\xa5\xd6\xe2"
+  "\x82\x73\x64\xc6\xfc\x98\x31\x37\x86\xc7\x53\xe2\x8b\x86\x67\xb1"
+  "\x73\x4d\x87\x67\x99\xce\x35\xfd\xe6\x38\xae\x1b\xb0\x0e\x9d\x9a"
+  "\x80\xc7\xca\xa7\xb2\xad\xe7\xc4\x86\x9e\x61\x73\x62\x3e\xa3\x88"
+  "\x46\xf5\xe9\x43\x34\xaa\x8a\x9e\xb7\x92\x7c\x1e\xc9\x75\x4f\x05"
+  "\xe4\xec\x5d\xa8\x96\xe3\x75\x5a\x7b\x6f\x34\xc9\xb3\x6e\x81\xe6"
+  "\x94\x3f\x49\xe1\x1c\x55\x76\x1c\xa2\xeb\x6c\xc6\xce\x47\x4f\x5e"
+  "\x93\xab\x66\xe0\xfa\x72\x47\x6f\xa8\xe5\x39\xf8\x98\x41\x6b\xf7"
+  "\xef\xe9\xab\x95\xe1\x71\x74\xef\xc2\x26\xb9\x11\x4b\xc6\xf5\x9b"
+  "\xd0\x9f\xb1\xb7\x77\x4e\x09\xc7\x73\x41\x5b\xbc\x62\x0a\xf4\x5e"
+  "\xc9\x39\xba\x92\xb0\x34\x3e\x7c\xd1\xeb\x42\x61\x0c\xc5\xeb\x38"
+  "\xe7\xc4\xb2\x38\x33\xac\x20\xf8\xaa\x04\xcd\x8e\xbf\xa1\xe4\x0e"
+  "\x63\x27\xd5\x1a\xd5\x3d\x64\x37\xc4\x9e\xc1\x18\x8c\xdf\xc2\x18"
+  "\xdb\xcc\xc5\xd8\x6d\x06\x63\x80\xb5\x36\x8c\x99\xac\xeb\x9c\x44"
+  "\x30\xa6\x69\xc3\x18\x3d\x76\xae\x50\xf5\xc3\x38\x33\x62\x0c\x8f"
+  "\x9b\x04\x63\x97\x04\x31\xf6\x4d\x2d\x3f\xc6\x74\x43\x4c\x31\x36"
+  "\x38\x8a\x60\x4c\xd5\xff\x44\x28\x60\x2c\x54\x2c\xc6\x54\xfd\xb8"
+  "\x1e\xfb\x99\xd1\x96\x1e\x5b\x95\x6e\xee\xb1\x8d\x9e\xfa\xb6\x57"
+  "\x5c\xda\xed\xfc\xb8\x95\x8d\x5e\x46\x5f\xad\xda\x29\xcd\x57\xab"
+  "\x8a\xed\x9b\x93\xe7\xe3\x72\x2a\x09\xa1\x53\xf0\x3c\x55\x05\x92"
+  "\x39\x79\x9f\xd2\x7e\xf9\xa9\x1c\x8c\x43\x7e\xbf\x4c\xf6\x59\xce"
+  "\xa5\x1a\xba\x93\x9d\x4b\x35\x74\x71\xf3\xfb\xfc\x73\xf2\x3e\x49"
+  "\x29\x30\xf1\x2e\x05\x3c\xde\xa5\xc0\xec\x3d\x5d\x01\x8f\x6f\x29"
+  "\x40\xf8\x5c\x53\xdf\x72\x2a\x90\xf8\x96\x53\x81\xd8\xb7\x14\xd0"
+  "\x7a\xef\x54\xa0\xd1\xb7\x14\xc0\x7e\xe2\x5b\x4e\x05\x5e\x81\x1f"
+  "\xec\x5b\x86\x2a\x4e\x05\xf2\xf9\x96\xa1\xfd\xc9\x9c\x3c\x1f\x67"
+  "\xe1\x39\x79\x05\x26\xfe\xb8\xc0\xc4\x1f\x17\x30\xfe\xb8\x80\xf6"
+  "\xc7\xe4\x6f\x0e\xa3\xaf\x0d\xff\x4d\xdc\xa6\xe9\xdf\x64\xfd\xc3"
+  "\xd0\x5c\xe2\x1f\x7c\x5c\x71\x1c\xb8\xfe\x18\xce\x49\xe4\xf3\xc7"
+  "\x43\x4f\x30\xe7\x38\x1b\xfd\x71\x0b\x39\x9e\x6e\x03\xb8\xe6\xa2"
+  "\xb0\x3f\x7e\x3a\x99\x70\xcf\xd3\x53\x09\xf7\x90\x98\x5a\xfa\xe3"
+  "\xa7\x4d\xfd\x8f\xc0\x9c\x3c\x82\x21\xfa\x3a\x63\x85\xfc\xf1\xd3"
+  "\x31\x96\xfe\xf8\xa9\x2c\xfe\x39\x79\xc3\x27\xb2\x38\x1a\x76\x99"
+  "\x3b\x27\xef\xe9\x2f\x4c\x7d\x31\xc6\xd8\x03\x86\x2d\x05\x77\x4e"
+  "\xde\xb0\x55\xfc\x9e\xb8\xc0\xc4\x13\x17\xd0\x9e\xf8\x54\xa0\x71"
+  "\x4e\xde\xb0\x43\xb8\x6d\x4b\x4f\x5c\xd0\x76\xbc\xd1\x13\xe3\x73"
+  "\x08\xe6\xf8\x3c\xf1\x70\x17\x73\xcc\x71\x3d\xf1\xf0\x81\x46\x4f"
+  "\xdc\x12\x62\xea\x89\x87\x8f\xe6\x7a\x62\xdc\x3e\x9f\x27\x1e\x1e"
+  "\xc9\x69\xdf\xc2\x13\x0f\x4f\x37\x7a\x62\xdc\xbe\x11\xb7\xac\x27"
+  "\x7e\x66\x30\xe1\xd0\xa7\x46\x89\xf7\xc4\xcf\xd0\x79\x9d\x92\x2d"
+  "\xe4\x5d\x17\xd7\x0f\x3f\xd3\x83\xeb\x87\x87\x6b\x88\xef\x7d\xc6"
+  "\x8f\xcc\xc7\x1b\xde\x48\xb6\x3f\x35\xd2\x74\x3b\xeb\x87\xc9\x76"
+  "\x3c\x1f\x8f\xcc\xc3\x7b\x66\x92\x38\x1f\xfc\xbb\x2e\xe8\x83\xbd"
+  "\xad\xf8\x60\xef\xdf\x98\x0f\x7e\xb6\x59\x9a\x0f\x7e\xb6\xa9\x6b"
+  "\xe8\xfa\xdf\x9a\xdf\x7a\x26\x94\x68\xae\x11\xb9\xd2\x74\xfd\x88"
+  "\x9c\xae\x11\x97\xdf\x9a\xdf\xf2\xf5\x27\x71\xf9\xa3\x8f\xb4\xb8"
+  "\xfc\x51\x25\xdd\x6f\x8d\xd1\xb1\x7e\x6b\x8c\x4e\xd8\x6f\xfd\x51"
+  "\x6f\xdd\x6f\xf9\x4d\x60\xfd\xd6\x73\x3b\x89\xe6\x79\x6e\x2d\xd1"
+  "\x3c\xcf\x4d\x16\xef\xb7\x46\x1d\x7b\xe8\xb7\xda\xd3\x6f\x8d\xa8"
+  "\x21\x18\x1b\x95\x2d\xcd\x6f\x8d\xca\xe2\xfa\xad\x17\x78\xd6\x43"
+  "\x8d\xba\x69\xbf\xdf\x7a\xce\x4b\x9a\xdf\x7a\x4e\x61\x9f\xdf\x7a"
+  "\x6e\x29\xbf\xdf\x1a\x89\x84\xfd\x16\xd9\x67\xa9\x93\xfd\xbc\x58"
+  "\x9d\xfc\xfc\xc5\xae\xef\xb7\x9e\x5f\xc9\xaf\x89\x9f\xcf\x26\x7e"
+  "\xeb\xb9\xf8\xf6\xf7\x5b\xcf\xc5\xf3\xfb\x2d\x3f\x19\xd1\xa6\xcf"
+  "\x25\x5a\xfa\x2d\x38\x87\xd7\x6f\xf9\x8d\x62\xce\x89\xe7\xfa\x2d"
+  "\xd2\x06\x70\xcd\x0c\x61\xbf\xe5\x77\x9d\x70\x8f\xdf\x11\xc2\x3d"
+  "\x24\xa6\x96\x7e\xcb\x2f\xdf\xb6\xdf\x22\x18\xa2\xaf\x53\xd0\x6f"
+  "\xf9\x9d\xb7\xf4\x5b\x7f\xd4\xf1\xfb\xad\x31\x5f\xb0\x38\x1a\x33"
+  "\x8b\xeb\xb7\x46\x0f\x79\x30\xfc\x96\x20\xb6\x56\x72\xfd\xd6\xe8"
+  "\x3b\xe2\xfd\xd6\x18\x1f\x71\x7e\x0b\x63\x8e\xcf\x6f\x8d\x59\x6a"
+  "\x8e\x39\xae\xdf\x1a\x93\xcb\xef\xb7\xc6\xec\xe6\xfa\x2d\xdc\x3e"
+  "\x9f\xdf\x1a\x73\x96\xd3\xbe\x85\xdf\x1a\x73\x93\xeb\xb7\xc8\x71"
+  "\xac\xdf\x7a\x81\xac\x81\x92\xff\x71\xa7\x78\xbf\xf5\xc2\x52\x61"
+  "\xbf\xf5\x82\xd9\xfa\xa7\x17\x98\xf5\x4f\x2f\x30\xeb\x9f\x5e\x20"
+  "\xeb\x9f\xe4\x7f\x2c\x36\xdd\xce\xfa\x2d\xb2\x9d\xf5\x5b\x2f\x94"
+  "\x8a\xf3\x5b\xee\x5d\xd0\x6f\x79\x58\xf1\x5b\x1e\xbf\x31\xbf\x35"
+  "\x36\x5a\x9a\xdf\x1a\x1b\xf5\x50\xd7\x77\x84\xae\x7f\xa1\x9c\x68"
+  "\xae\x71\x32\x69\xba\x7e\x1c\x92\xae\xeb\x5f\x39\xc3\xea\xfa\x57"
+  "\xce\x08\xeb\xfa\x71\x67\xad\xeb\xfa\x09\xfd\x58\x5d\xff\x12\x93"
+  "\xcb\x7c\x69\x2e\x19\x5b\x5f\x1a\x28\x5e\xd7\x8f\xdf\xfc\x50\xd7"
+  "\xb7\xa7\xae\x1f\xbb\x9f\x60\x6c\x7c\xa4\x34\x5d\x3f\x3e\x82\xab"
+  "\xeb\x5f\x4d\xb7\xd4\xf5\xe3\x4f\xda\xaf\xeb\xc7\x5f\x97\xa6\xeb"
+  "\xc7\x0b\xce\x3b\xe4\xea\xfa\x97\xa6\xf2\xeb\xfa\x71\x35\xc2\xba"
+  "\x9e\xec\xb3\xd4\x63\x2f\x5f\x67\xf5\xd8\xcb\x87\xba\xbe\xae\x7f"
+  "\x39\x94\x5f\x7b\xbd\x1c\x49\x74\xfd\x4b\x01\xed\xaf\xeb\x5f\x0a"
+  "\xe0\xd7\xf5\x2f\x33\xeb\x3f\x5e\x0a\xb4\xd4\xf5\x70\x0e\xaf\xae"
+  "\x9f\xd0\x83\x39\x27\x80\xab\xeb\x49\x1b\xc0\x35\x3e\xc2\xba\x7e"
+  "\xc2\x09\xc2\x3d\x13\xf2\x09\xf7\x90\x98\x5a\xea\xfa\x09\x31\xb6"
+  "\x75\x3d\xc1\x10\x7d\x9d\x82\xba\x7e\xc2\x17\x96\xba\x7e\xdc\x19"
+  "\x7e\x5d\xff\x4a\x36\x8b\xa3\x57\x86\x73\x75\xfd\x04\xfd\x83\xa1"
+  "\xeb\x05\xb1\x15\xca\xd5\xf5\x13\x2b\xc4\xeb\xfa\x57\x64\xe2\x74"
+  "\x3d\xc6\x1c\x9f\xae\x7f\x65\xaa\x39\xe6\xb8\xba\xfe\x95\x68\x7e"
+  "\x5d\xff\x4a\x3a\x57\xd7\xe3\xf6\xf9\x74\xfd\x2b\x25\x9c\xf6\x2d"
+  "\x74\xfd\x2b\x27\xb9\xba\x9e\x1c\xc7\xea\xfa\x57\x17\x10\x0e\x1d"
+  "\x97\x2c\x5e\xd7\xbf\x3a\x55\x58\xd7\xbf\x3a\x8b\xab\xeb\x5f\x55"
+  "\x11\xfd\xfe\x6a\x1a\xd1\xf5\xaf\xbe\x48\xb6\x8f\x4b\x32\xdd\xce"
+  "\xea\x7a\xb2\x9d\xd5\xf5\xaf\xe6\x88\xd3\xf5\x8f\x74\x41\x5d\xef"
+  "\x6a\x45\xd7\xbb\xfe\xc6\x74\xfd\xe4\xf1\xd2\x74\xfd\x64\x7f\xe9"
+  "\xfa\x71\x86\x82\xd5\x8f\x33\x14\xc2\xfa\x71\x8a\x97\x75\xfd\x38"
+  "\x2d\x94\xd5\x8f\x01\x47\x08\x87\x07\xec\x20\x1c\x1e\x30\x57\xbc"
+  "\x7e\x7c\xed\xdc\x43\xfd\xd8\x9e\xfa\xf1\xd5\x62\xa2\x1f\x5f\xdb"
+  "\x29\x4d\x3f\xbe\x56\xcc\xd5\x8f\x33\x8e\x59\xea\xc7\x80\xee\xf6"
+  "\xeb\xc7\x80\xe1\xd2\xf4\x63\xc0\x30\xfb\xf4\x63\x40\x36\xbf\x7e"
+  "\x9c\xe2\x2d\xac\x1f\xc9\x3e\xcb\x71\x7f\xda\x70\x76\xdc\x9f\xda"
+  "\xdc\xf5\xf5\xe3\xd4\x42\xfe\x31\x7e\xea\x4e\xa2\x1f\x03\xb2\xda"
+  "\x5f\x3f\x06\x64\xf1\xeb\xc7\x69\x7d\xc8\x58\x1b\x90\x63\xa9\x1f"
+  "\xe1\x1c\x5e\xfd\x38\x8d\x19\xff\x03\xb2\xb8\xfa\x91\xb4\x01\x5c"
+  "\x13\x2d\xac\x1f\xa7\x33\xeb\x62\xa7\x9d\x25\xdc\x43\x62\x6a\xa9"
+  "\x1f\xa7\x95\xd8\xd6\x8f\x04\x43\xf4\x75\x0a\xea\xc7\x69\x77\x2c"
+  "\xf5\xe3\x14\x05\xbf\x7e\x0c\xac\x60\x71\x14\x18\xc3\xd5\x8f\xd3"
+  "\xc7\x3e\x18\xfa\x51\x10\x5b\x85\x5c\xfd\x18\xd8\x43\xbc\x7e\x0c"
+  "\x1c\x2f\x4e\x3f\x62\xcc\xf1\xe9\xc7\xc0\x6c\x73\xcc\x71\xf5\x63"
+  "\xe0\x6e\x7e\xfd\x18\x78\x8c\xab\x1f\x71\xfb\x7c\xfa\x31\xf0\x3a"
+  "\xa7\x7d\x0b\xfd\x38\xa3\x3b\x57\x3f\x92\xe3\x58\xfd\x38\x63\x0f"
+  "\xe1\xd0\xc9\x47\xc4\xeb\xc7\x19\xd9\xc2\xfa\x71\x46\x3e\x57\x3f"
+  "\xce\x88\x22\x3a\x71\x86\x9a\xe8\xc7\x19\x49\x64\xfb\xe4\xc3\xa6"
+  "\xdb\x59\xfd\x48\xb6\xb3\xfa\x71\x46\xb5\x2d\xfd\x68\x5d\x5b\xcc"
+  "\x5e\xc9\x6a\x8b\xd9\x2b\x4d\xb5\xc5\x49\x8e\xb6\x78\xdd\x46\xfd"
+  "\xab\x37\xca\x59\x6d\x31\x6b\x38\x79\xbe\x67\x79\x92\xe7\x7b\xe6"
+  "\x69\x5a\x5b\x4c\x05\x0d\x00\xda\xa2\xe4\xda\x7e\xa2\x2d\xae\x35"
+  "\xc9\xdf\xbb\xc1\x68\x8b\x06\xe4\x9a\xb5\x90\xd1\x16\x73\xb0\xb6"
+  "\x98\x39\x19\x6b\x0b\xb7\x42\xd0\xb7\x75\x8c\xde\x8d\x05\xbd\x5b"
+  "\x07\xbf\xc3\xb3\x73\x14\xda\xa8\x04\x4d\x9a\x83\xcf\xc7\xdf\x01"
+  "\x81\xb6\xe8\xb5\xb5\xf4\xba\x5b\x8d\x8b\xf2\x2d\xb2\x66\x17\x7f"
+  "\xc7\x45\xe8\x1b\x2e\xc6\xef\xb7\x24\xd5\x51\x06\xfc\xbd\x96\xe9"
+  "\x11\x26\xdf\x71\xc1\xdf\x7e\xd5\xd6\x23\xfc\x2d\x97\xc2\x38\xa4"
+  "\xf8\x00\x6b\x8d\x7a\xe4\xd1\x33\x5d\xd6\x13\x7f\xc7\xa5\x67\x23"
+  "\xd1\xb4\x25\x86\x32\xa2\x69\x97\x78\x3f\x0a\x3a\x69\xd8\xb6\x5b"
+  "\xac\xc6\xd8\x88\xf5\xc5\x12\x95\xb2\x71\x89\x6a\xc0\xed\xdb\xa0"
+  "\x69\xb5\xe6\xdf\xf9\xf8\x4f\x0e\xfe\x96\x44\x55\x22\xc9\x81\xd2"
+  "\xdf\xf7\xf8\x8b\x0a\x6d\x9f\x0f\xba\xa7\x01\xc9\x9e\xc1\xdf\xf8"
+  "\xa8\x40\x1e\xbf\xef\x07\xbc\x7f\x5b\xd5\xcf\xb4\x3e\x27\xce\x8b"
+  "\x1a\x6e\xab\x50\x79\xf8\xf7\xf4\x3a\x5b\x9d\x71\x9d\xed\x2d\xe4"
+  "\xa7\x5d\xa2\x92\x6f\x89\x33\xd1\xb4\x5e\x58\xd3\x8e\xb1\xa2\x69"
+  "\x67\x7a\x49\xd3\xb4\x33\x15\x5c\xbd\x11\x3c\xc2\x52\x6f\xcc\x5c"
+  "\x66\xbf\xde\x98\xb9\x55\x9a\xde\x98\x59\x68\x9f\xde\x98\xa9\x37"
+  "\xd7\x1b\xbb\x69\xbd\xf1\x7a\x3c\xc6\x26\xbf\xde\x20\xfb\x2c\xc7"
+  "\x89\x37\xb6\xb2\xe3\xc4\x1b\xd1\x5d\x5f\x6f\xbc\xe1\xc6\x3f\x26"
+  "\xbc\xe1\x45\xf4\xc6\x4c\x5d\xfb\xeb\x8d\x99\x3a\x7e\xbd\xf1\xc6"
+  "\x5a\xc2\xcd\xb3\x90\xa5\xde\x80\x73\x78\xf5\xc6\x1b\x47\xc8\x39"
+  "\x33\x75\x5c\xbd\x41\xda\x00\xfe\x39\x27\xac\x37\xfe\xbc\x94\xf0"
+  "\xd1\x9f\x27\x12\x3e\x22\x31\xb5\xd4\x1b\x7f\xee\x6f\x5b\x6f\x10"
+  "\x0c\xd1\xd7\x29\xa8\x37\xfe\x1c\x69\xa9\x37\x5e\x8f\xe5\xd7\x1b"
+  "\xb3\xc7\xb2\x38\x0a\x3a\xcf\xd5\x1b\x7f\x2e\x79\x30\xf4\x86\x20"
+  "\xb6\xdc\xb8\x7a\x23\x28\x59\xbc\xde\x08\x3a\x20\x4e\x6f\x60\xcc"
+  "\xf1\xe9\x8d\x20\xbd\x39\xe6\xb8\x7a\x63\x76\x1f\x7e\xbd\x31\x7b"
+  "\x04\x57\x6f\xe0\xf6\xf9\xf4\xc6\xec\x30\x4e\xfb\x16\x7a\x63\xf6"
+  "\x32\xae\xde\x20\xc7\xb1\x7a\x23\xb8\x1f\xe1\xd0\xd7\xfb\x88\xd7"
+  "\x1b\xb3\xf5\xc2\x7a\x23\xd8\x85\xab\x37\x66\xd7\x10\x5d\x11\xec"
+  "\x4b\xf4\xc6\xec\x06\xb2\xfd\x75\x6f\xd3\xed\xac\xde\x20\xdb\x59"
+  "\xbd\x11\xfc\x70\xfd\xeb\x03\x95\xaf\x0a\x91\xb8\xfe\x35\xe4\xe1"
+  "\xfa\xd7\x0e\x79\x0f\x1d\xcc\xac\x7f\x0d\x93\xb8\xfe\x35\xec\xe1"
+  "\xfa\xd7\x0e\x89\x4b\x28\xb3\xfe\xf5\x4d\x89\xeb\x5f\xdf\x7c\xb8"
+  "\xfe\xb5\x43\xe2\x12\xc6\xac\x7f\x0d\x97\xb8\xfe\x35\xdc\x81\xf5"
+  "\xaf\x51\xbb\x58\x6f\x1c\xb5\x4b\xd8\x1b\xcf\xb5\xb1\xfe\x35\x52"
+  "\xcb\x7a\xe3\x88\x19\x44\x8b\x46\x8c\x22\x5a\x74\x1e\x9d\x9b\x4a"
+  "\xc1\xde\xf8\xc3\xcc\xa2\x7d\x71\xa5\x72\x5c\x17\x0e\x7f\x1b\x33"
+  "\x7b\x39\x72\xd6\x61\x6f\x0c\x31\xc8\x6e\xc1\xde\xf8\x38\x8a\x7d"
+  "\x1b\x7b\xe3\x79\x31\x95\x75\x26\xdf\x57\x91\xcf\x3d\xcf\xd6\x73"
+  "\x3e\x8e\xf0\xbe\xa3\xb7\x4a\xe5\x39\x2d\x66\x39\xf9\xb8\x26\xb9"
+  "\x72\x21\x37\x27\xaf\xcf\x4f\xce\xc1\x39\xf9\x66\xe6\x5b\x29\x74"
+  "\x5e\x7e\xb8\xf5\x9c\xfc\xd6\x16\x18\x3b\x79\xf2\xf2\x38\x27\x0f"
+  "\x63\xe4\x6f\x2c\x27\xff\x26\xb3\x36\x76\xde\x68\x69\x39\xf9\x79"
+  "\x7e\x5c\x8f\x1c\x3d\xcb\xd2\x23\xcf\xdb\x6a\xbf\x47\x9e\x77\x4c"
+  "\x9a\x47\x9e\xa7\xb6\xcf\x23\x47\x0c\xe4\xf7\xc8\x73\x73\x52\x04"
+  "\x3d\x32\xd9\x67\xe9\x6d\x22\x8f\xb1\xde\x26\x32\xbb\xeb\x7b\xe4"
+  "\x48\x5f\x7e\x1f\x13\x39\x9a\x78\xe4\x08\x65\xfb\x7b\xe4\x08\x25"
+  "\xbf\x47\x8e\x64\xde\x7f\x47\x0c\xb6\xf4\xc8\x70\x0e\xaf\x47\x8e"
+  "\xbc\xc8\x9c\xa3\xe4\x7a\x64\xd2\x06\xf0\x90\x5e\xd8\x23\xcf\xdf"
+  "\x4c\x78\x69\x7e\x34\xe1\x25\x12\x53\x4b\x8f\x3c\x7f\xbc\x6d\x8f"
+  "\x4c\x30\x44\x5f\xa7\xa0\x47\x9e\xbf\xd6\xd2\x23\xcf\x15\x58\x1b"
+  "\x1b\x35\x97\xc5\x51\x94\x8c\xeb\x91\xe7\x9f\x7e\x30\x3c\xb2\x20"
+  "\xb6\x7c\xb9\x1e\xf9\x2f\x3b\xc4\x7b\xe4\xbf\x9c\x15\xe7\x91\x31"
+  "\xe6\xf8\x3c\x72\xd4\x40\x73\xcc\x71\x3d\x72\xd4\x58\x7e\x8f\x1c"
+  "\x35\x8b\xeb\x91\x71\xfb\x7c\x1e\x39\x2a\x9d\xd3\xbe\x85\x47\x8e"
+  "\xda\xca\xf5\xc8\xe4\x38\xd6\x23\x47\xfb\x33\xe3\x9d\x84\xb5\xb1"
+  "\xd1\x03\x85\x3d\x72\xb4\x0f\xd7\x23\x47\xe9\x88\x17\x8e\x9e\x49"
+  "\x3c\x72\xb4\x07\xd9\x3e\x77\xa4\xe9\x76\xd6\x23\xcf\x35\x5b\x1b"
+  "\x1b\x1d\xf1\x70\x6d\xec\x83\xe4\x91\xdf\x91\x98\xff\x7e\x47\xd1"
+  "\x35\x34\xff\x6f\xcd\x8b\x45\x27\x12\xcd\xb5\xa0\x44\x9a\xe6\x5f"
+  "\xb0\xa7\x6b\xc4\xe5\xb7\xe6\xc5\xde\x61\xd6\x2c\x2f\x9c\x28\x2d"
+  "\x2e\x0b\x27\x48\xf7\x62\x09\x23\x59\x2f\x96\x30\x52\xd8\x8b\x2d"
+  "\xea\x63\xdd\x8b\x2d\x49\x62\xbd\xd8\xe2\xf3\x44\xf3\x2c\x3e\x46"
+  "\x34\xcf\xe2\x74\xf1\x5e\x2c\xb6\x99\xeb\xc5\x16\x45\x3f\xf4\x62"
+  "\x1d\xe5\xc5\x16\x34\x12\xfc\xc5\x9e\x90\xe6\xc5\x62\x8f\x73\xbd"
+  "\x58\xc2\x45\x4b\x2f\xb6\xd8\xc7\x7e\x2f\xb6\x58\x62\xfd\xdf\xc5"
+  "\x01\xf6\x79\xb1\xc5\x25\xfc\x5e\x6c\x51\x3f\x61\x2f\x46\xf6\x59"
+  "\x6a\xe8\x25\x53\x59\x0d\xbd\xa4\x4f\xd7\xf7\x62\x71\x87\xf9\xf5"
+  "\x72\xdc\x09\xe2\xc5\x16\xef\x69\x7f\x2f\xb6\x78\x0f\xbf\x17\x5b"
+  "\x32\x9a\xe8\xd6\xc5\xfb\x2d\xbd\x18\x9c\xc3\xeb\xc5\x96\xc4\x30"
+  "\xe7\xec\xe1\x7a\x31\xd2\x06\xf0\xd0\x5a\x61\x2f\x16\x3f\x84\xf0"
+  "\xd2\x92\x3b\x84\x97\x48\x4c\x2d\xbd\xd8\x92\x0a\xdb\x5e\x8c\x60"
+  "\x88\xbe\x4e\x41\x2f\x16\xef\x65\xe9\xc5\x16\x79\xf3\x7b\xb1\xa5"
+  "\x26\xeb\x34\x96\x66\x73\xbd\x58\x7c\xd8\x83\xe1\xc5\x04\xb1\x75"
+  "\x98\xeb\xc5\x96\x0e\x17\xef\xc5\x96\xce\x15\xe7\xc5\x30\xe6\xf8"
+  "\xbc\xd8\xd2\x12\x73\xcc\x71\xbd\xd8\xd2\x93\xfc\x5e\x6c\xe9\x45"
+  "\xae\x17\xc3\xed\xf3\x79\xb1\x84\x1e\x9c\xf6\x2d\xbc\x58\x82\x0f"
+  "\xd7\x8b\x91\xe3\x58\x2f\x96\x50\x4e\x38\x74\xe1\x31\xf1\x5e\x2c"
+  "\xa1\x44\xd8\x8b\x25\x7c\xc1\xf5\x62\x09\x99\xc4\x73\x25\x68\x88"
+  "\x17\x4b\x28\x24\xdb\x17\xaa\x4d\xb7\xb3\x5e\x8c\x6c\x67\xbd\x58"
+  "\x82\xf6\xe1\xba\xd9\x07\xc9\x8b\x25\xee\x90\xe6\xc5\x12\x8b\x1e"
+  "\x6a\xfe\x8e\xd0\xfc\x7f\x75\x26\x9a\x6b\xf9\x68\x69\x9a\x7f\xb9"
+  "\x9f\x74\xcd\x9f\xa1\x62\x35\x7f\x86\x4a\x58\xf3\xaf\xe8\x61\x5d"
+  "\xf3\xa7\xc6\xb2\x9a\x3f\xf9\x34\x19\x5b\x93\xbf\x20\x63\x6b\xf2"
+  "\x52\xf1\x9a\x3f\xe9\x3a\x57\xf3\xaf\x08\x7b\xa8\xf9\x3b\x4a\xf3"
+  "\x27\xd6\x13\xfc\x25\x1d\x92\xa6\xf9\x93\x4a\xb9\x9a\x3f\xe3\xac"
+  "\xa5\xe6\x4f\xb6\xf8\xfe\x87\xb0\xe6\x4f\x1e\x2f\x4d\xf3\x27\xfb"
+  "\xdb\xa7\xf9\x93\x77\xf0\x6b\xfe\x15\x1e\xc2\x9a\x9f\xec\xb3\xd4"
+  "\x6a\xa9\xe3\x59\xad\x96\xda\xa3\xeb\x6b\xfe\x94\xfd\xfc\xba\x2c"
+  "\xe5\x10\xd1\xfc\xc9\x45\xed\xaf\xf9\x93\x8b\xf8\x35\x7f\xea\x70"
+  "\xa2\x8f\x92\x8b\x2d\x35\x3f\x9c\xc3\xab\xf9\x53\xe7\x32\xe7\x14"
+  "\x71\x35\x3f\x69\x03\x78\x28\x59\x58\xf3\xa7\xf5\x21\xbc\x94\xca"
+  "\x7c\x2b\x8c\xc4\xd4\x52\xf3\xa7\x1e\xb3\xad\xf9\x09\x86\xe8\xeb"
+  "\x14\xd4\xfc\x69\xdd\x2d\x35\xff\x0a\x37\x7e\xcd\x9f\x7e\x91\xc5"
+  "\x51\x7a\x3a\x57\xf3\xa7\xcd\x78\x30\x34\xbf\x20\xb6\xf6\x73\x35"
+  "\x7f\xfa\x40\xf1\x9a\x3f\x7d\x96\x38\xcd\x8f\x31\xc7\xa7\xf9\xd3"
+  "\x77\x98\x63\x8e\xab\xf9\xd3\x8f\xf0\x6b\xfe\xf4\xb3\x5c\xcd\x8f"
+  "\xdb\xe7\xd3\xfc\x19\x32\x4e\xfb\x16\x9a\x3f\xa3\x3f\x57\xf3\x93"
+  "\xe3\x58\xcd\x9f\xa1\x26\x1c\xba\xfc\x0b\xf1\x9a\x3f\x63\x87\xb0"
+  "\xe6\xcf\xd8\xcd\xd5\xfc\x19\xcc\xda\xd9\x8c\x33\x44\xf3\x67\xe4"
+  "\x90\xed\xcb\x0f\x9a\x6e\x67\x35\x3f\xd9\xce\x6a\xfe\x8c\xba\x87"
+  "\x6b\x6a\x1f\x24\xcd\xbf\x32\x5f\x9a\xe6\x5f\x99\x27\x5d\x5b\x66"
+  "\x99\xac\x7b\xc9\xb2\xb2\xee\x65\x55\xb4\x75\x6d\xb9\xd6\x64\xdd"
+  "\x4b\x26\xb3\xee\x25\x93\x59\xf7\xb2\xe6\xb4\x78\x6d\xb9\x66\x32"
+  "\x57\x5b\xae\x3a\xf4\x50\x5b\x76\x94\xb6\xcc\x68\x22\xda\x72\x8d"
+  "\x97\x34\x6d\xb9\xc6\x6c\xfd\x4b\x36\xcf\xfa\x97\x35\x22\xd6\xbf"
+  "\xac\x91\xb8\xfe\x65\x8d\x9d\xeb\x5f\xd6\x08\xac\x7f\x59\xb5\x40"
+  "\x58\x5b\x92\x7d\x96\x9a\x60\xad\xc9\xfa\x97\xb5\x0f\xc0\xfa\x97"
+  "\xb5\x02\x6b\x14\xd6\x32\xeb\x5f\xd6\x74\xc0\xfa\x97\x35\x02\xeb"
+  "\x5f\xd6\x32\xeb\x5f\x32\x79\xd6\xbf\xac\x11\x58\xff\xb2\x96\x59"
+  "\xff\xb2\xc6\x6c\xfd\x4b\x26\xb3\xfe\x65\xad\x95\xf5\x2f\xeb\x98"
+  "\xf5\x2f\xeb\x98\xf5\x2f\x24\xa6\x96\xda\x72\x9d\x1d\xeb\x5f\xd6"
+  "\x30\xeb\x5f\xd6\x58\x59\xff\xb2\x8e\x67\xfd\xcb\xaa\x28\x7e\x6d"
+  "\x99\x65\xb2\xfe\xe5\x3d\xb3\xf5\x2f\xeb\x1e\x90\xf5\x2f\x82\xd8"
+  "\x32\x5b\xff\xf2\x9e\x84\xf5\x2f\xef\x89\x5c\xff\xb2\x46\x60\xfd"
+  "\xcb\x7b\x7a\x73\xcc\x71\xb5\x65\x96\xc0\xfa\x97\x2c\xb3\xf5\x2f"
+  "\x6b\x04\xd6\xbf\x64\x85\x71\xda\xb7\xd0\x96\x59\x66\xeb\x5f\x32"
+  "\xcd\xd6\xbf\x64\x33\xeb\x5f\x56\x79\x8a\xd7\x96\x59\x56\xd6\xbf"
+  "\x64\x9b\xad\x7f\xc9\x62\xd6\xbf\x64\x33\xeb\x5f\xb2\x98\xf5\x2f"
+  "\xab\x3c\x4c\xb7\xb3\xda\x92\x6c\x67\xb5\x65\xb6\xcd\xf5\x2f\xd6"
+  "\x75\x47\xbe\x07\xab\x3b\xf2\x3d\x84\x75\x47\xf6\x45\xeb\xba\xe3"
+  "\xfd\x20\x56\x77\xe4\x1c\x22\xcf\x77\xce\x56\xf2\x7c\xe7\xd0\xef"
+  "\x61\x92\x2b\x40\x77\x0c\xca\x2c\xda\x7b\x63\x3f\xad\x3b\xf6\x2d"
+  "\x6c\x92\x83\x46\x74\x36\x60\xdd\x01\x5a\x30\x2b\x01\xeb\x8e\x3a"
+  "\x66\xbd\xed\x86\xb3\x15\x89\xa6\xba\x63\xfd\x28\x7a\xed\x6d\xdb"
+  "\xf7\x9e\xeb\x10\xde\xcf\xb7\x16\xf7\xc8\x42\x66\x2d\x2e\xb4\x6d"
+  "\xba\x06\x97\x5e\x97\x7b\x03\x74\xc9\x5b\x10\x0f\x13\x5d\xf2\x70"
+  "\x2d\xae\xb5\xb5\xb8\x1b\x24\xe6\xbf\x37\x14\x71\xb5\x48\xfe\x11"
+  "\x4b\x2d\x92\xe3\x62\xbf\x16\xc9\xf1\x91\xa6\x45\x72\x54\xf6\x69"
+  "\x91\x9c\xb5\xfc\x5a\x24\xbb\x0e\xe3\x96\x5f\x8b\x90\x7d\x96\x63"
+  "\xc8\xfb\x3e\xec\x18\x92\x7b\xa7\xeb\x6b\x91\xdc\x02\xfe\xf1\x22"
+  "\x77\x07\xd1\x22\x39\x99\xed\xaf\x45\x72\x32\xf9\xb5\xc8\xfb\x5e"
+  "\x84\xb7\x73\xb2\x2c\xb5\x08\x9c\xc3\xab\x45\xde\x9f\xcc\x9c\x93"
+  "\xc9\xd5\x22\xa4\x0d\xe0\xa6\x48\x61\x2d\xb2\x51\x46\xb8\xea\xfd"
+  "\xd3\x84\xab\x48\x4c\x2d\xb5\xc8\xfb\xbb\x6d\x6b\x11\x82\x21\xfa"
+  "\x3a\x05\xb5\xc8\xfb\x37\x2d\xb5\x48\xb6\x86\x5f\x8b\xe4\x9d\x64"
+  "\x71\x94\x17\xcd\xd5\x22\x1b\x47\x3f\x18\x5a\x44\x10\x5b\x05\x5c"
+  "\x2d\x92\xd7\x5d\xbc\x16\xc9\x1b\x2b\x4e\x8b\x60\xcc\xf1\x69\x91"
+  "\xbc\xb5\xe6\x98\xe3\x6a\x91\xbc\x9d\xfc\x5a\x24\xef\x08\x57\x8b"
+  "\xe0\xf6\xf9\xb4\x48\xde\x55\x4e\xfb\x16\x5a\x24\xdf\x85\xab\x45"
+  "\xc8\x71\xac\x16\xc9\xdf\xc5\xf8\xb9\xb5\xe2\xb5\x48\xfe\x5a\x61"
+  "\x2d\x92\x9f\xcb\xd5\x22\xf9\x11\x44\x73\xe4\x1f\x26\x5a\x24\x3f"
+  "\x91\x6c\xcf\xce\x34\xdd\xce\x6a\x11\xb2\x9d\xd5\x22\xf9\xe5\x22"
+  "\xf2\x5c\x79\x62\xd6\xe2\x96\xdc\xe5\xe6\xb9\x8c\x39\x2e\xdd\xb0"
+  "\xb0\x95\x6d\x79\x2e\xd3\xf7\xa4\x3c\x79\x2e\x3c\xa6\xb3\x79\xae"
+  "\xf3\x34\x57\xb1\x79\x2e\x0d\x9d\xe7\xc2\x39\x2e\xfc\xae\xd4\x98"
+  "\xe3\x32\xfc\xd5\x72\x1d\x6e\x89\x41\x7c\x8e\x8b\x7d\x5f\xfa\x83"
+  "\x2b\xc9\x71\xd5\xb4\xe5\xb8\xf0\x78\xae\xbf\x67\x99\xe3\xc2\xe3"
+  "\x38\x9b\xe3\xfa\xbe\x9d\x73\x5c\x7f\x5b\x26\x6d\x5c\xff\x5b\x62"
+  "\xd7\x78\xaf\xfd\x5b\x5b\x87\x9b\xaf\x21\xb9\x9f\xcd\x9e\xd2\xde"
+  "\x6b\x6f\xf6\xe8\x1a\x71\xf9\xad\xcd\xfd\xfe\x9b\x9a\xc4\x65\xcb"
+  "\x6e\x69\x71\xd9\xb2\xab\x6b\xc4\xe5\xb7\x36\x0f\x64\x73\x10\x89"
+  "\x4b\xe1\x78\x69\x71\x29\xf4\x97\x9e\xab\x2f\x9e\xc9\x7a\xe6\xe2"
+  "\x99\xa6\x9e\xb9\x6c\x82\xa9\x67\xde\x6a\xa3\xfe\xe5\x8e\x42\xd6"
+  "\x33\x6f\xd7\x13\x1d\xba\xfd\x22\xd1\xa1\xdb\xe9\xf7\x53\xc9\xe3"
+  "\x11\xed\x95\x75\xd8\x37\xbf\xdd\x24\xdf\x7b\x4d\x2d\xd7\x65\x10"
+  "\xbf\x5c\xa5\x2b\x47\x15\xda\x26\xf4\x5e\x02\x72\x5e\x7b\x03\x39"
+  "\x7f\x72\xab\x49\xee\xbe\x00\xb9\xc2\x98\x04\x7d\x56\x0e\x3a\x66"
+  "\x2b\x8a\x4d\xc1\x5e\x7a\x7b\x9f\xaa\x58\xad\x89\x97\xde\x9a\xcc"
+  "\xfa\x68\x38\x2e\xb6\x09\x7d\xf5\xb6\x5a\x8e\xfd\x72\x6b\x7e\x72"
+  "\x4e\xeb\xf0\xb0\x34\xba\x8e\x95\x69\x3e\x1f\xfe\xb6\x72\x0e\x37"
+  "\x9f\xdf\x92\x9f\x9c\xd7\x5c\x12\xb6\x92\xae\xa1\x39\x84\xcd\xe9"
+  "\x8b\xa9\x9f\xf9\x41\x0b\x52\x18\xf3\xf9\x1f\xfc\xe6\xf2\xf9\x5b"
+  "\xb4\x04\xa3\xdb\x2e\x4b\xcb\xe7\x6f\xab\xe3\x7a\xe8\x9d\x32\x4b"
+  "\x0f\xbd\x7d\xb2\xfd\x1e\x7a\x7b\x8c\x34\x0f\xbd\x7d\x81\x7d\x1e"
+  "\x7a\x7b\x85\xb9\x87\xde\x95\x82\x3d\xf4\x56\x6f\x8c\x63\x7e\x0f"
+  "\x4d\xf6\x59\x7a\x9f\x1d\x31\xac\xf7\xd9\x31\xba\xeb\x7b\xe8\xa2"
+  "\x5a\x7e\x9f\x53\x74\x99\x78\xe8\xed\xe5\xed\xef\xa1\xb7\x97\xf3"
+  "\x7b\xe8\x1d\xb3\x89\xdf\xd8\x5e\x6e\xf4\xc3\xac\x87\x86\x73\x78"
+  "\x3d\xf4\x8e\x6c\xf3\x73\x88\x87\xde\x5e\x4d\x3c\xf4\x8e\xdd\xc2"
+  "\x1e\xfa\xc3\x89\x84\xbb\x3e\xf4\x22\xdc\x45\x62\x6a\xe9\xa1\x77"
+  "\x5c\xb7\xed\xa1\x09\x86\xe8\xeb\x14\xf4\xd0\x1f\x8e\xb2\xf4\xd0"
+  "\x5b\x05\xea\x67\x16\xf7\x60\x71\xf4\x51\x09\xd7\x43\x7f\x98\xfc"
+  "\x60\x78\x68\x41\x6c\xd5\x72\x3d\xf4\x47\x53\xc5\x7b\xe8\x8f\xd2"
+  "\xc5\x79\x68\x8c\x39\x3e\x0f\xfd\x51\x05\x83\x9f\x6a\x7e\x0f\xfd"
+  "\xd1\x55\x7e\x0f\x5d\x2c\xe3\x7a\x68\xdc\x3e\x9f\x87\x2e\x1e\xce"
+  "\x69\xdf\xc2\x43\x17\x4f\xe6\x7a\x68\x72\x1c\xeb\xa1\x8b\x1b\x08"
+  "\x87\x16\x4a\xa8\x9f\x59\x5c\x21\xec\xa1\x8b\xcf\x72\x3d\x74\xf1"
+  "\x2e\xe2\x95\x77\x22\xe2\xa1\x8b\x0f\x93\xed\x85\x87\x4d\xb7\xb3"
+  "\x1e\xba\xd0\xac\x7e\xe6\x4e\x0f\x11\x1e\xba\xa0\x9d\x3c\x74\xe6"
+  "\x83\xe5\xa1\x6b\xcb\xba\x86\x87\xfe\xf8\x88\x34\x0f\xfd\xf1\x61"
+  "\x3b\x3d\x41\x9e\x0d\x4f\xb0\xf2\xa1\x27\x30\xd5\x5b\x3b\x07\x13"
+  "\xbd\xb5\x6b\x96\x34\x4f\xb0\x6b\x66\x57\x88\xcb\x6f\x2b\x26\x7f"
+  "\x67\xe6\xeb\xef\xbe\x2a\x2d\x26\xbb\xeb\x1f\xfa\xe7\x8e\x88\xcb"
+  "\xae\x42\x12\x97\x4f\xd3\xa5\xc5\xe5\xd3\x34\xe9\xfe\xf9\xf3\x52"
+  "\xd6\x3f\x7f\x5e\x6a\xea\x9f\xff\xc5\x79\xe7\xbc\x67\x96\x75\xff"
+  "\x7c\x00\xb1\xfe\x79\xdf\x5c\xa2\x41\xf7\x31\x73\x4a\xf6\xd1\x39"
+  "\xf5\xa4\x2f\x88\x7f\xbe\x8b\xfd\xf3\x15\xf0\xcf\xf3\xc3\xe5\x3a"
+  "\xe6\xdb\x11\x78\xfe\x5a\x05\x78\x60\xec\x99\xab\x12\xe1\xff\xf1"
+  "\x5a\xf4\x5e\x1c\x72\x5e\x07\xde\x77\x37\x8c\x95\xbb\x13\xb4\xf2"
+  "\xcc\xb7\x61\x9c\xa9\x29\x41\xee\x51\xe0\xab\x6f\x61\x5f\x7d\x1c"
+  "\x3c\xf3\x2a\xc6\x57\xef\x4d\xae\x8a\x37\xf5\xd5\x7b\xce\xd2\xbe"
+  "\x5a\x4b\xe6\xc6\x55\xc5\x83\xaf\x86\xbf\x87\xbf\x45\x61\xea\xab"
+  "\x9b\xc1\x37\xb7\x80\x6f\xce\xb9\x66\xe6\xb1\xe7\x5b\x7a\xec\x66"
+  "\xaf\xe4\x82\xa6\xe1\x61\x99\xd8\x63\xdf\xdd\xf9\xd0\x63\x5b\x7a"
+  "\xec\x4f\x7c\x09\x8e\xf7\x4e\x96\xe6\xb1\xf7\x4e\xe2\x7a\xec\x83"
+  "\x91\x96\x1e\x7b\x6f\x89\xfd\x1e\x7b\xef\x69\x69\x1e\x7b\x6f\xb5"
+  "\x7d\x1e\x7b\xdf\x08\x73\x8f\xfd\x31\xfd\x9e\x7a\x4f\x10\xc6\x3a"
+  "\xbf\xc7\x26\xfb\x2c\xbd\xd1\xfe\xd3\xac\x37\xda\xbf\xb5\xeb\x7b"
+  "\xec\xfd\xfe\xfc\x3e\x68\xff\x64\xe2\xb1\xf7\xf9\xb6\xbf\xc7\xde"
+  "\xe7\xcb\xef\xb1\xf7\x33\xf3\xdf\xf6\xf9\x5a\x7a\x6c\x38\x87\xd7"
+  "\x63\xef\xbf\x69\x7e\x0e\xf1\xd8\xfb\x46\x12\x8f\x7d\xa0\x87\xb0"
+  "\xc7\x3e\xb0\x9b\xf0\xdb\x81\x65\x84\xdf\x48\x4c\x2d\x3d\xf6\x81"
+  "\x19\xb6\x3d\x36\xc1\x10\x7d\x9d\x82\x1e\xfb\xc0\x66\x4b\x8f\xbd"
+  "\x67\x26\xbf\xc7\xfe\x7c\x31\x8b\xa3\xcf\x3d\xb9\x1e\xfb\xc0\xc5"
+  "\x07\xc3\x63\x0b\x62\xcb\x9f\xeb\xb1\x3f\x3b\x20\xde\x63\x7f\x76"
+  "\x59\x9c\xc7\xc6\x98\xe3\xf3\xd8\x9f\x8f\x60\xf0\x33\x92\xdf\x63"
+  "\x7f\x3e\x95\xdf\x63\x7f\x1e\xc9\xf5\xd8\xb8\x7d\x3e\x8f\xfd\x79"
+  "\x2e\xa7\x7d\x0b\x8f\xfd\x79\x09\xd7\x63\x93\xe3\x58\x8f\x7d\x30"
+  "\x90\x70\xe8\xa7\x7a\xf1\x1e\xfb\xe0\x08\x61\x8f\x7d\x70\x34\xd7"
+  "\x63\x1f\x74\x23\x5e\xfa\x60\x04\xf1\xd8\x07\x95\x64\xfb\xa7\x3a"
+  "\xd3\xed\xac\xc7\x26\xdb\x59\x8f\x7d\x30\x5e\xdc\x7b\x6a\x87\xea"
+  "\x61\xad\xec\xfc\xf5\x18\xed\x55\x0f\xcb\xf8\xae\xfa\x7e\xaf\xc7"
+  "\xf8\x9f\x21\xd2\x7c\xf6\xff\x0c\x7e\xe8\xe7\xda\xdb\x37\x1c\xcc"
+  "\x24\x7a\xeb\x1f\x12\xeb\xdf\xfe\xc3\x6a\xfd\xdb\x87\x7e\x4e\x6a"
+  "\x5c\xfe\x67\x01\x89\xcb\xa1\x19\xd2\xe2\x72\x28\x50\xba\x9f\x3b"
+  "\x16\xc1\xfa\xb9\x63\x11\xc2\xef\x43\xbf\x1c\x62\xdd\xcf\x1d\xdd"
+  "\xc3\xfa\xb9\x23\x3d\x88\xde\x39\x7c\x93\xe8\x9d\xc3\x07\xda\xef"
+  "\x7d\xe8\x61\x1f\xee\xfb\xd0\x2f\xb3\x1f\xbe\x0f\xed\x0c\xaf\x56"
+  "\x8a\x08\x46\xff\xf7\x8e\x34\xaf\xf6\xbf\x8d\x5c\xaf\xf6\xb5\xa7"
+  "\xa5\x57\x3b\x3c\xdb\x7e\xaf\x76\x38\x59\x9a\x57\x3b\x9c\x64\x9f"
+  "\x57\x3b\x7c\x9e\xff\x7d\xe8\x97\x2a\xe1\xf7\xa1\x64\x9f\xa5\xc6"
+  "\x3e\x9a\xcc\x6a\xec\xa3\x93\xbb\xbe\x57\x3b\xd2\xc0\xaf\xa7\x8f"
+  "\xdc\x21\x5e\xed\x70\x6d\xfb\x7b\xb5\xc3\xb5\xfc\x5e\xed\x68\x34"
+  "\xd1\xb5\x87\x6b\x2d\xbd\x1a\x9c\xc3\xeb\xd5\x8e\x6e\x35\x3f\x87"
+  "\x78\xb5\xc3\x1a\xe2\xd5\x8e\x1e\x12\xf6\x6a\x5f\xcd\x22\xdc\xf5"
+  "\xd5\x10\xc2\x5d\x24\xa6\x96\x5e\xed\xa8\xde\xb6\x57\x23\x18\xa2"
+  "\xaf\x53\xd0\xab\x7d\x35\xd1\xd2\xab\x7d\x39\x98\xdf\xab\x1d\xeb"
+  "\xcf\xe2\x48\x7d\x84\xeb\xd5\xbe\xca\x7e\x30\xbc\x9a\x20\xb6\x1a"
+  "\xb8\x5e\x4d\x1d\x26\xde\xab\xa9\x73\xc5\x79\x35\x8c\x39\x3e\xaf"
+  "\xa6\x3e\xcf\xe0\x47\xc3\xef\xd5\xd4\xcd\xfc\x5e\xed\x98\x27\xd7"
+  "\xab\xe1\xf6\xf9\xbc\xda\xb1\xb1\x9c\xf6\x2d\xbc\xda\xb1\xd9\x5c"
+  "\xaf\x46\x8e\x63\xbd\xda\x31\x1d\xe1\xd0\x43\x15\xe2\xbd\xda\xb1"
+  "\xf3\xc2\x5e\xed\xd8\x65\xae\x57\x3b\x56\x4a\x3c\xd9\xd7\x1e\xc4"
+  "\xab\x1d\x2b\x27\xdb\x0f\x95\x9b\x6e\x67\xbd\x1a\xd9\xce\x7a\xb5"
+  "\xaf\x95\xe2\xbc\x9a\xfd\xf5\xb2\xee\xff\x9c\x62\x8f\xdf\xd8\x9c"
+  "\xe2\x7f\x56\x48\xf3\x69\xff\x2c\x7f\xe8\x09\x3a\xc2\x13\x7c\x3d"
+  "\x92\xe8\xad\x13\x91\xd2\x3c\xc1\x89\x08\xe9\x9e\xa0\x22\x91\xf5"
+  "\x04\x15\x89\xc2\x9e\xe0\x5f\xa3\xad\x7b\x82\x53\x6a\xd6\x13\x9c"
+  "\x1c\x48\xc6\xd5\x93\x2e\x64\x5c\x2d\x3b\xd1\x7e\x9e\xa0\x6c\x2c"
+  "\xd7\x13\xfc\x6b\xc7\x43\x4f\xd0\x19\x9e\xe0\xb8\x82\x60\xb4\xac"
+  "\xbb\x34\x4f\x50\xe6\xca\xf5\x04\x95\x43\x2c\x3d\x41\x59\x8c\xfd"
+  "\x9e\xa0\x2c\x57\x9a\x27\x28\xcb\xb1\xcf\x13\x94\xdd\xe4\xf7\x04"
+  "\xff\x7a\x51\xd8\x13\x90\x7d\x96\x5a\xee\x54\x2e\xab\xe5\x4e\x85"
+  "\x75\x7d\x4f\x70\x0a\xf1\xeb\xb6\x53\xdd\x89\x27\x28\xd3\xb6\xbf"
+  "\x27\x28\xd3\xf2\x7b\x82\x53\xc9\x44\x3f\x95\x69\x2d\x3d\x01\x9c"
+  "\xc3\xeb\x09\x4e\x1d\x30\x3f\x87\x78\x82\xb2\x46\xe2\x09\x4e\x55"
+  "\x08\x7b\x82\x6f\xa2\x09\x77\x7d\x33\x9a\x70\x17\x89\xa9\xa5\x27"
+  "\xf8\xc6\xd3\xb6\x27\x20\x18\xa2\xaf\x53\xd0\x13\x7c\x33\xdb\xd2"
+  "\x13\xfc\xcb\x8f\xdf\x13\x54\x8c\x60\x71\x54\x7e\x9a\xeb\x09\xbe"
+  "\xd9\xf1\x60\x78\x02\x41\x6c\x21\xae\x27\x28\x5f\x2c\xde\x13\x94"
+  "\xef\x14\xe7\x09\x30\xe6\xf8\x3c\x41\x39\xf3\xfe\x8f\xe0\xc5\xd2"
+  "\x13\x54\xf4\xe0\xf7\x04\x15\x43\xb8\x9e\x00\xb7\xcf\xe7\x09\x2a"
+  "\x66\x70\xda\xb7\xf0\x04\x15\x31\x5c\x4f\x40\x8e\x63\x3d\x41\xa5"
+  "\x07\xe1\xd0\x13\x17\xc5\x7b\x82\x8a\x9b\xc2\x9e\xa0\xa2\x99\xeb"
+  "\x09\x2a\x18\xed\x5f\x39\x98\x78\x82\x0a\x0d\xd9\x7e\x42\x63\xba"
+  "\x9d\xf5\x04\x64\x3b\xeb\x09\x2a\x47\x3e\xac\xa7\xf5\x20\xd5\xd3"
+  "\xaa\xba\x2c\xcd\x17\x54\xd5\x49\xd7\x9f\xdf\x9d\x61\xf5\xe7\x77"
+  "\x67\x4c\xf5\x27\xb7\xae\x45\xf5\x21\xeb\xfa\xf3\x6c\x3f\x56\x7f"
+  "\xfe\x3b\x99\x70\xf8\xbf\xe7\x12\x0e\xff\x37\x5d\x9b\x4f\x5c\x3d"
+  "\xad\x6f\x37\x73\xeb\x69\x9d\xee\xfe\xb0\x9e\x56\x47\x69\xcb\xca"
+  "\x49\x44\x5b\x7e\x1b\x29\x4d\x5b\x7e\x1b\xc1\xd5\x96\x35\xe9\x96"
+  "\xda\xf2\xdb\x93\xf6\x6b\xcb\x6f\xaf\x4b\xd3\x96\xdf\x36\xd8\xa7"
+  "\x2d\xff\x3d\x95\xbf\x86\x45\xf5\x61\xe1\x7a\x5a\x64\x9f\xa5\x26"
+  "\x38\x63\x52\x57\xff\xcc\xa1\xae\xaf\x2d\xcf\x84\xf2\x8f\xff\x67"
+  "\x22\x89\xb6\xfc\x77\x40\xfb\x6b\xcb\x7f\x07\xf0\x6b\xcb\x33\xe7"
+  "\xc8\x38\xfc\xef\x40\xcb\x1a\x16\x70\x0e\xaf\xb6\x3c\xcb\xd4\xbf"
+  "\xff\x77\x00\x57\x5b\x92\x36\x80\x87\x7c\x84\xb5\xe5\xd9\x13\x84"
+  "\x97\xce\xe6\x13\x5e\x22\x31\xb5\xd4\x96\x67\x63\x6c\x6b\x4b\x82"
+  "\x21\xfa\x3a\x05\xb5\xe5\xd9\x2f\x2c\xb5\x65\x75\x29\xbf\xb6\xfc"
+  "\x2e\x9b\xc5\xd1\x77\xc3\xb9\xda\xf2\xac\xfe\xc1\xd0\x96\x82\xd8"
+  "\x0a\xe5\x6a\xcb\xff\x54\x88\xd7\x96\xdf\xc9\xc4\x69\x4b\x8c\x39"
+  "\x3e\x6d\xf9\xdd\x54\x73\xcc\x71\xb5\xe5\x77\xd1\xfc\xda\xf2\xbb"
+  "\x74\xae\xb6\xc4\xed\xf3\x69\xcb\xef\x4a\x38\xed\x5b\x68\xcb\xef"
+  "\x4e\x72\xb5\x25\x39\x8e\xd5\x96\x35\x0b\x08\x87\x56\xcf\x15\xaf"
+  "\x2d\x6b\xa6\x0a\x6b\xcb\x9a\x59\x5c\x6d\x59\xa3\x22\x1a\xb2\x26"
+  "\x8d\x68\xcb\x9a\x17\xc9\xf6\xea\x70\xd3\xed\xac\xb6\x24\xdb\x59"
+  "\x6d\x59\x93\x23\x6e\xfd\x4d\xbb\xe4\x9b\x3b\x69\xfd\x4d\x7b\xe5"
+  "\x9b\xbb\xca\xfa\x9b\xef\xc7\x4a\xd3\x95\xdf\xbf\xf8\x70\x5e\x50"
+  "\x7b\xe7\x9a\x6b\x8a\x89\xd6\xfa\xe1\xb4\xb4\x5c\xf3\x0f\xd5\xd2"
+  "\xb5\x7e\x1d\x62\xb5\x3e\xb6\x0c\x42\xeb\x09\x6a\x77\x5a\xd7\xfa"
+  "\x17\x27\xb1\x5a\xff\x02\x33\xdf\xf6\x42\x36\x19\x53\x2f\x4c\x95"
+  "\xb2\x9e\x60\xdd\x2d\xe4\xfc\x9e\xf9\x7a\x82\x33\x47\xc8\x7a\x82"
+  "\x38\xf3\xf5\x04\x3f\x9e\xe0\xae\x27\x38\x3f\x44\x68\x3d\x01\xce"
+  "\x3d\xb7\x96\x84\xad\xc4\x6b\x09\x78\xd7\x11\x04\xb7\xff\x3a\x02"
+  "\xec\x13\x3e\x00\xdc\x62\xaf\x80\xf9\xe6\xb7\xe5\x15\xbe\x5f\x49"
+  "\xf0\xfb\x63\xae\x34\xaf\xf0\x63\x0e\xd7\x2b\xd4\x95\x58\x7a\x85"
+  "\x1f\xef\xd8\xef\x15\x2e\xf4\x91\xe6\x15\x2e\x78\xdb\xe7\x15\x2e"
+  "\x2c\xe3\x5f\x47\x50\xbb\x4b\x78\x1d\x01\xd9\x67\xa9\xf1\x2e\xf6"
+  "\x61\x35\x9e\xe6\x72\xd7\xf7\x0a\x9a\x4c\x7e\x3d\xa7\xc9\x25\x5e"
+  "\xe1\x42\x62\xfb\x7b\x85\x0b\x89\xfc\x5e\xe1\xa2\x0b\xd1\x55\x17"
+  "\x12\x2d\xf3\xd0\x70\x0e\xaf\x57\xb8\x38\xda\xfc\x1c\xe2\x15\x2e"
+  "\x24\x11\xaf\x70\x71\x96\xb0\x57\xb8\x78\x93\xf0\xda\x45\xe6\x1b"
+  "\x93\x24\xa6\x96\x5e\xe1\xe2\x66\xdb\x5e\x81\x60\x88\xbe\x4e\x41"
+  "\xaf\x70\xf1\xa2\xa5\x57\xa8\x2d\xe6\xf7\x0a\x3f\x1d\x62\x71\xf4"
+  "\xd3\x6c\xae\x57\xb8\xe4\xf3\x60\x78\x05\x41\x6c\x65\x72\xbd\xc2"
+  "\xa5\x66\xf1\x5e\xe1\xa7\xe1\xe2\xbc\x02\xc6\x1c\x9f\x57\xf8\x69"
+  "\x19\x83\x9f\x24\x7e\xaf\xf0\x53\x3e\xbf\x57\xf8\xa9\x84\xeb\x15"
+  "\x70\xfb\x7c\x5e\xe1\xa7\x73\x9c\xf6\x2d\xbc\xc2\x4f\x77\xb8\x5e"
+  "\x81\x1c\xc7\x7a\x85\xba\x02\xc2\xa1\xb5\x53\xc5\x7b\x85\xba\x65"
+  "\xc2\x5e\xa1\x2e\x9d\xeb\x15\xea\x66\x12\x4f\x50\xb7\x87\x78\x85"
+  "\xba\x28\xb2\xbd\x36\xc0\x74\x3b\xeb\x15\xc8\x76\xd6\x2b\xd4\x1d"
+  "\x16\x37\x37\xc5\xfe\x3c\xf4\xfd\x9f\x9b\xe2\xfa\x1b\x9b\x9b\x72"
+  "\x25\x5a\x9a\x57\xb8\x12\x25\x5d\x97\xde\x88\x67\x75\xe9\x8d\x78"
+  "\xe1\x39\x10\x3f\x8f\xb5\xae\x4b\x7f\x39\xcc\xea\xd2\x6b\xfd\x09"
+  "\x7f\x5f\x93\x11\xfe\xbe\x7a\xcc\xde\x39\x10\xeb\xee\x32\x5a\xd4"
+  "\x38\x07\x22\x81\x99\x03\x01\x7a\x94\xe8\xcf\xab\xa3\xb9\x73\x20"
+  "\x7e\xde\x29\x34\x07\x82\x77\xee\x83\x99\xe6\x34\xea\x53\x47\xe6"
+  "\x3e\xfc\xb6\x35\x67\x5d\x35\xd1\x9c\x57\x5d\xa4\x69\xce\xab\xce"
+  "\x5c\xcd\xf9\xeb\x40\x4b\xcd\x79\x35\xda\x7e\xcd\x79\x35\x5b\x9a"
+  "\xe6\xbc\x9a\x65\x9f\xe6\xbc\x7a\x9d\x7f\xee\xc3\xcf\xfe\xc2\x73"
+  "\x1f\xc8\x3e\x4b\xad\xf0\x8b\x49\x5e\xf1\x97\xd9\x5d\x5f\x73\x5e"
+  "\xd3\xf1\xeb\x82\x5f\x5c\x88\xe6\xbc\xda\xd0\xfe\x9a\xf3\x6a\x03"
+  "\xbf\xe6\xfc\x85\x19\xff\xaf\x36\x58\x6a\x4e\x38\x87\x57\x73\xfe"
+  "\x52\x62\x7e\x0e\xd1\x9c\x57\xb5\x44\x73\xfe\x72\x52\x58\x73\x36"
+  "\x44\x12\xce\x6a\x18\x45\x38\x8b\xc4\xd4\x52\x73\x36\xf4\xb0\xad"
+  "\x39\x09\x86\xe8\xeb\x14\xd4\x9c\x0d\xb3\x2c\x35\xe7\xcf\x2f\xf2"
+  "\x6b\xce\x1b\xc3\x59\x1c\x5d\xaf\xe0\x6a\xce\x86\xad\x0f\x86\xe6"
+  "\x14\xc2\xd6\x35\x1d\x57\x73\x5e\x8f\x11\xaf\x39\xaf\xef\x10\xa7"
+  "\x39\x31\xe6\xf8\x34\xe7\xf5\xeb\x0c\x7e\xb4\xfc\x9a\xf3\x46\x77"
+  "\x7e\xcd\x79\x63\x20\x57\x73\xe2\xf6\xf9\x34\xe7\x8d\xa9\x9c\xf6"
+  "\x2d\x34\xe7\x8d\x68\xae\xe6\x24\xc7\xb1\x9a\xf3\x57\x37\xc2\xa1"
+  "\x57\x2e\x8b\xd7\x9c\x37\xae\x0b\x6b\xce\x1b\x77\xb8\x9a\xf3\x46"
+  "\x19\xd1\x96\xbf\x2a\x89\xe6\xbc\x51\x4b\xb6\x5f\xa9\x33\xdd\xce"
+  "\x6a\x4e\xb2\x9d\xd5\x9c\xbf\xfa\x5a\xd3\x9c\x54\xde\xa0\xa8\x1c"
+  "\xb9\x61\x3f\xfc\x94\xc2\x75\xf6\x81\xf1\x4d\x0d\xff\x2f\x83\x71"
+  "\xca\x13\xfe\x2f\x98\x63\xd3\x7a\x0d\x8a\x32\x80\x2e\x31\xc0\xdf"
+  "\xa9\xd2\xfe\xaa\x56\xf7\xd5\xe1\xf1\x64\x3f\x19\x5f\x06\x45\xb9"
+  "\xeb\x1e\x99\x64\xa0\xa2\x10\xa5\x80\xff\x27\xc2\x36\x38\xbe\x27"
+  "\x8c\x87\xca\x04\xd4\xf3\x86\xfc\xd7\x6a\xe3\x71\x70\xcd\x3d\x2f"
+  "\xc9\x7f\xcd\xc6\x6d\xc0\xb5\xd6\xc2\xfd\xbc\x28\x78\xad\xd0\xd6"
+  "\xf4\xdd\x03\x50\xb2\x8e\xfa\x59\xbd\xf0\x16\xaa\x93\x6b\x87\xb8"
+  "\x37\x3c\x32\x09\x78\x08\x61\x8d\xb8\xbf\xaf\xd6\x19\xb7\xa9\x5e"
+  "\xd8\x82\xf7\xb9\xe2\x7d\x7a\xb8\xc6\x94\x18\x24\x5f\x7f\xeb\x11"
+  "\x57\xd0\x5c\x2e\xa9\x8d\x54\xfd\x22\x1d\x5c\x33\x8c\xaf\x5f\x0d"
+  "\xa8\x71\xde\xb7\xa5\x86\x1e\x7b\x2a\x1b\xf5\x74\x1b\xca\x85\xf8"
+  "\x7a\xb4\x3e\xdb\xe0\x78\xbe\x6b\x58\xb5\x17\x0d\x73\xf1\xa1\x34"
+  "\xe2\xc6\x3b\x6d\x92\x50\x3f\xba\xa7\x0f\x40\xea\xa1\xd0\x77\x4a"
+  "\x24\xe7\xdb\x2f\xf2\xef\x58\x9b\xff\xe0\xba\xb1\x37\xd5\x98\xba"
+  "\x19\xc9\x37\x18\x1e\x71\xfd\x27\x5c\xd1\xf6\x4d\x94\xf6\xde\xba"
+  "\x9b\x81\x1a\xd9\x8f\x69\xb8\xcf\xdf\x85\xfd\x1b\x7a\x53\xda\xdb"
+  "\x19\x18\x37\x37\xa3\x8e\xc1\xd8\x6e\x1e\x8b\xb8\x88\x98\xb9\xca"
+  "\xf8\xe8\x98\xc8\x45\x4b\xe3\x95\x43\x22\x1e\x45\x33\x17\x2d\x52"
+  "\xc6\xcc\x5d\xb8\x4c\x69\xba\x67\x8c\x32\x22\x7a\xc9\xdc\xb7\x16"
+  "\x44\x0e\x8f\x99\x17\xfb\x28\x4e\xb0\x9a\x5c\x87\x02\x5f\x8b\x61"
+  "\xdd\xcd\xf8\x6d\xef\x23\xb4\xb1\x17\x72\xc6\xd7\x05\x7f\xaf\x46"
+  "\xe3\x3c\xae\x1c\xff\xbd\xf5\x9b\xa8\x46\x39\x1c\x93\x0a\x9c\xb6"
+  "\x21\xe5\x11\x38\x56\x5b\xb7\x1d\xae\x6b\x1b\x5c\x37\x5c\x23\x5c"
+  "\xf3\x2d\x67\xe3\x35\x1b\x31\x91\x8a\x31\x91\x72\x0b\x30\x78\x6b"
+  "\x88\x7b\xd3\x23\xaf\x52\x54\x10\xbe\xbf\x46\x78\x56\x64\xb0\xed"
+  "\x08\xed\x1b\xf2\x07\x45\xc1\xb9\xfe\x46\x8c\x19\xf2\xde\x41\xd4"
+  "\xa6\x41\xbe\xa0\x2b\x65\xf7\xa8\xa8\xff\x06\x6c\xe2\xf3\xb3\x9f"
+  "\x45\x28\x8d\xba\x17\x44\x7f\x1b\x83\xba\x07\x18\x26\x38\x85\x7d"
+  "\xb7\xc3\x6f\xcb\xd1\x38\x68\x63\xa5\x06\xe5\x1e\xc6\x6d\x68\x60"
+  "\x1b\xee\x73\x43\x51\x66\xce\x2c\x15\x4a\xfb\x7d\x1a\x4a\xbb\x87"
+  "\xcf\x29\x9e\x12\xe5\x1e\x8f\x64\xd3\x13\xa9\x0b\xc0\x3b\x32\x6a"
+  "\x60\x66\x0e\xb5\x73\x4a\x94\x46\x7e\x2b\xca\x90\xff\x0e\x82\xfb"
+  "\x69\x80\x76\xca\x35\x32\x6f\xfa\x5a\x36\x6c\xa2\xfb\xbe\x01\xdf"
+  "\x3b\xf4\x0f\xf8\x1f\x4a\x4d\x65\x30\xcf\x50\xce\x4b\x4d\x86\x9c"
+  "\x3c\x65\x95\xf3\x5d\x34\x5d\x47\xb5\x52\xb9\x2f\x35\x55\x36\x36"
+  "\x02\xa7\xc5\xce\xa3\x1e\xbd\xb9\xca\x5d\x17\x1d\xb9\xbd\x17\x3c"
+  "\x8b\xb9\x79\x4a\x2a\x37\xb4\x7a\x96\x0f\xf2\xb8\xb7\xee\xb6\xca"
+  "\xd8\x9f\xd0\x97\xce\xe2\x70\x74\x7b\x18\xbe\x27\x8c\x07\xb8\x1e"
+  "\x06\x0f\xb7\x13\x8f\xc5\x5b\xe2\xa1\xed\xd9\xdc\x14\x1c\xab\xa3"
+  "\x82\x5e\x6d\xcd\x0b\xde\x45\x29\x82\xf3\x52\x2e\xa3\x6e\xb8\x6f"
+  "\x2b\xc1\x0b\xac\x4f\x40\xde\xd9\x60\x11\xde\x5c\xe6\x81\xb4\xf9"
+  "\xc1\x39\xee\xe9\x69\x32\xe8\x13\x39\xf0\x8b\x2f\x70\xa6\x6f\x6b"
+  "\xef\x77\x50\x52\x24\x92\x97\x5c\xda\x2f\xc7\xfa\x19\xcf\x5b\xb9"
+  "\x22\x6f\x1c\xbd\x0d\xce\xa3\x7e\x0d\x42\x38\x1e\x74\x2c\x7e\x8d"
+  "\x42\x53\x81\x95\xf1\xfb\x14\xd8\x1f\xb3\x15\xda\x14\x77\x5f\x8d"
+  "\xb4\xfe\xd5\x43\xac\x9e\x85\x38\x55\xd5\xe9\xe9\x36\xe9\x58\x2d"
+  "\x60\x63\x75\x04\xae\x83\x8d\xd7\xed\x46\x1c\x57\x81\x7b\xd6\x92"
+  "\x7b\x0e\x51\x51\x8a\x10\x85\xf0\x3d\x87\x78\x90\x7b\x76\xb9\x65"
+  "\xfd\x9e\xef\x0c\xb7\x7e\xcf\x77\xe6\x4a\xb8\xe7\x26\xf1\xf7\xdc"
+  "\x58\x2f\x7c\xcf\x21\x4c\x9c\x43\x20\xce\x21\x56\xe2\x1c\xc2\xc4"
+  "\xf9\xb1\x4b\xd6\xef\xf9\xee\x40\xeb\xf7\x7c\x77\x96\xf8\x7b\xbe"
+  "\xd3\x20\xfe\x9e\xef\xd4\x5a\xb9\x67\x26\xce\xa1\x10\xe7\x50\x2b"
+  "\x71\x0e\x65\xe2\xec\xf9\xad\xf5\x7b\xbe\xe7\x65\xfd\x9e\xef\x4d"
+  "\x16\x7f\xcf\x77\x35\xe2\xef\xf9\x6e\xb5\xf0\x3d\x87\x32\x71\x0e"
+  "\x85\x38\x87\x5a\x89\x73\x28\x13\xe7\xe7\xd6\x59\xbf\xe7\xa6\xee"
+  "\xd6\xef\xb9\x69\xac\xf8\x7b\xbe\x77\x46\xfc\x3d\xdf\x3b\x6e\xe5"
+  "\x9e\x99\x38\x87\x41\x9c\xc3\xac\xc4\x39\x8c\x89\x73\xc8\x4b\x36"
+  "\xee\x59\x6f\xfd\x9e\x9b\x47\x88\xbf\xe7\xa6\x32\xf1\xf7\xdc\x54"
+  "\x2a\x74\xcf\x2d\xc0\xdb\x6e\x70\x2f\xad\xdf\x05\xbd\xaa\x57\x04"
+  "\x17\xba\xd5\x21\x79\x61\x86\x21\xca\xbd\x1e\x75\x87\x7b\x8b\xa2"
+  "\x36\xc5\x54\xe3\x7f\x0d\x8a\xe0\x82\x16\x45\xf0\xae\xe6\xde\x83"
+  "\x7c\x57\x84\xa1\x6e\x58\x8f\xaf\x35\x20\x6f\x43\x5e\x70\x5e\xd6"
+  "\xeb\x48\x99\xaa\x45\x1e\x95\x29\x1a\x94\x12\x4b\x69\x2b\xd1\x45"
+  "\xd4\xa3\x1e\x7b\xcf\xef\x51\x79\x43\x19\x5a\x18\x47\x51\x57\xe4"
+  "\x2d\xc9\x38\x6f\x02\x3a\x39\x2d\xe7\x3f\x48\x09\x7f\xc3\x77\x1b"
+  "\xfc\xe0\x76\xdc\x03\x60\xfc\xdc\x14\xf3\xed\xf6\x14\xe4\x7d\xf4"
+  "\xed\x7a\x84\xb7\x6f\x85\x1f\xfd\xa6\x77\x50\x4a\x18\x92\xef\xbd"
+  "\x55\x23\x27\x63\x73\xcb\x64\xf3\xb1\x39\x60\x2e\xf4\xe5\x5b\xf4"
+  "\xbe\xfc\xc2\xd7\xc5\xf6\x65\x8b\xc2\x38\x76\xd3\x7d\x59\xab\x27"
+  "\xe3\xbd\xd9\xd8\x7d\x14\xfe\x3e\xdb\x97\x2d\xce\xb8\x2f\xa9\xbc"
+  "\xe0\xfd\x55\xf5\x2d\xd8\x37\x79\x5c\x49\x44\x72\x8d\xbc\xf9\x60"
+  "\x65\xec\x2d\x24\xd0\xc7\x5a\xb6\x8f\x43\xfa\xb9\xd5\xb9\xdc\xe2"
+  "\xef\xe3\x10\xef\x16\x45\x88\xca\xb2\x8f\x43\x14\xf6\xf5\x71\xeb"
+  "\x45\xc7\xfb\xb8\xb5\x44\xb8\x8f\x5b\x9b\xc5\xf7\x71\x6b\xa2\xf8"
+  "\x3e\x6e\x8d\x22\x7d\x1c\xe2\xcb\xed\xe3\x56\x6f\xe1\x3e\x0e\x31"
+  "\xc1\x71\x08\xe0\xf8\xb1\x4b\x02\x7d\x0c\x38\x0e\xe1\xc1\x71\x88"
+  "\x9d\x38\xd6\x4f\x74\xbc\x8f\xf5\x9e\xc2\x7d\xac\x0f\x13\xdf\xc7"
+  "\xba\x5a\xf1\x7d\xac\x2b\x67\xfa\xd8\x0c\xc7\xba\x24\x2b\x7d\x6c"
+  "\x82\xe3\x50\xc0\xb1\xe7\xb7\xfc\x7d\x1c\x0a\x38\x0e\xe5\xc1\x71"
+  "\xa8\x9d\x38\x36\xec\x76\xbc\x8f\x0d\x4b\x85\xfb\xd8\x70\x4c\x7c"
+  "\x1f\x1b\xfc\xc5\xf7\xb1\xc1\x97\xf4\x71\xa8\x19\x8e\xf5\x1a\xe1"
+  "\x3e\x0e\x35\xc1\x71\x28\xe0\xf8\xb9\x75\x02\x7d\x0c\x38\x0e\xe5"
+  "\xc1\x71\xa8\x7d\x38\x76\x42\x3d\x1c\xef\x63\xea\x9c\x60\x1f\x3b"
+  "\xa1\x21\xe2\xfb\x98\x2a\x16\xdf\xc7\x54\x1e\xd3\xc7\x66\x38\xa6"
+  "\x26\x58\xe9\x63\x13\x1c\x87\x01\x8e\x43\x5e\xe2\xef\xe3\x30\xc0"
+  "\x71\x18\x0f\x8e\xc3\xec\xc3\xb1\x93\x6c\xb1\xc3\x7d\xec\x24\x1b"
+  "\x2b\xdc\xc7\xb2\xb5\xa2\xfb\xd8\x49\xe6\x2a\xba\x8f\x9d\x50\x13"
+  "\xe9\xe3\x30\x2e\x8e\x9d\xd0\x2e\xa1\x3e\x6e\x05\x0f\xd8\x03\xfa"
+  "\xb8\x47\x03\x92\x6f\xc5\x7d\x5b\x43\xfa\x56\xdf\x3b\xa6\x7a\xab"
+  "\xdc\x10\x85\xfb\x84\xce\x01\xfd\xe2\xdd\x53\x9f\x17\x5c\x48\xc9"
+  "\xe1\x9e\x52\x5c\xf1\x3d\xdd\xd4\x65\xa0\x9e\xca\x94\x74\xf8\xbf"
+  "\x13\x3d\x3f\x56\x99\xb2\xfa\x3c\xfc\x3d\x27\x9c\xf7\xd2\xe5\x0f"
+  "\xf4\xd0\x7b\xcd\xd1\xc0\x3e\x1f\x6a\x48\x40\x1a\xf8\xcd\xfd\xd4"
+  "\x3b\xde\x8a\xaa\x86\xfd\xd0\x3f\xa7\x50\x65\xcd\x97\xc8\xd0\x3b"
+  "\xe6\xdb\x67\x75\x48\x45\xfd\xa2\x52\x94\xc7\x6b\x90\x7e\x9e\xb7"
+  "\x5b\x55\x62\x19\xaa\x4a\xfc\x0c\x4d\xaf\xa7\xee\x52\x3f\xa9\xdc"
+  "\x5a\xbd\xe2\xbd\xf5\x5e\x31\xfb\xf5\xf9\xc9\xbb\x74\x5e\xf1\xae"
+  "\x25\x09\x1a\xb9\x5b\x13\x52\x2d\xa8\xa3\xa8\xf5\x6f\x21\xe7\xf5"
+  "\x97\x90\xeb\x86\xb7\x90\xdb\x86\x4b\xc8\xa3\xbc\xae\x06\x55\x5c"
+  "\x2b\x43\x15\xb7\xce\xa1\x8a\xbb\xf0\xd3\x02\x3f\x06\xf8\x49\x3b"
+  "\x07\xb1\x46\x68\xea\x75\x84\xbf\x2b\xaa\x7d\xba\x16\x29\xca\x75"
+  "\x35\x08\xaf\xe9\xbd\xe1\x24\x3f\xe1\x16\x8e\x14\xd4\x4f\xde\x88"
+  "\x9a\xe7\x2d\x87\x7d\xce\x78\x7b\x95\x4e\x8b\xca\xeb\x9a\xf0\xfe"
+  "\x62\xd8\xef\x9c\x5a\x07\xed\x1b\xca\xf0\x77\x43\xb5\xe5\x69\x27"
+  "\x91\x2e\xf7\x34\xa2\xb0\x87\xee\x1d\x1c\x9b\x03\x5d\x6d\xa0\xbc"
+  "\x07\x11\x1c\x38\x9d\xdf\x66\x10\x1b\x6b\x39\xa9\x7f\xf3\x8e\x77"
+  "\x2f\xe8\xe7\xbe\x86\x77\x82\x3c\xa6\x9d\xbb\x40\xe1\x39\x7e\x38"
+  "\x97\x50\xd9\x78\x0a\xe1\x77\x4d\xd3\x97\x21\x14\xa0\x47\x08\xf7"
+  "\x45\x55\x62\x3d\x9a\x16\x8b\xdc\x71\xfe\xd9\xf0\x8b\xaa\x57\x55"
+  "\x9d\x16\x25\xeb\xe0\x1a\x6f\x34\xb5\x5d\x63\xe5\xca\x4a\x04\xfb"
+  "\xfa\x56\x46\x69\x90\x5b\x2c\xf2\xc0\xfd\xab\xcb\x0b\x2e\x98\x06"
+  "\xcf\xcf\xc2\x46\x8a\xc2\x7d\x8b\xfb\x14\xf7\x2f\x6e\xcf\xd8\xe7"
+  "\x55\x11\x5a\x94\xda\x84\x3c\xaa\x52\xe0\xdf\x44\x4a\x5b\x85\x6e"
+  "\x22\xb8\xc6\x1a\xca\xf3\x34\x02\x5c\x9c\xc1\x58\x00\x7c\xd6\x43"
+  "\xfc\x7b\xf1\x63\x2a\x44\x41\x30\xe5\x72\xcb\x36\xa6\x42\xfa\xb1"
+  "\x98\x72\x9e\xc8\x62\xaa\xdb\x40\x61\x4c\xb9\x24\x13\x4c\x85\xf8"
+  "\x76\x4d\x4c\xb9\xf4\xb1\x8e\x29\xe7\x26\x61\x4c\x85\xa8\x00\x53"
+  "\x5a\x2e\xa6\xba\x8d\x10\x8f\x29\x97\x49\x9d\x87\xa9\x10\x6f\x69"
+  "\x98\x72\x19\xc6\xc5\x94\xf3\x8b\x56\x30\xc5\xf0\xd4\x63\x97\xec"
+  "\xc0\x94\x09\x4f\x75\xdb\xcc\x62\xca\x75\xa9\x30\xa6\x1e\x39\xcd"
+  "\x60\xaa\x8b\xf2\xd4\x23\x31\xd6\x31\xf5\x48\x80\x15\x4c\x01\x4f"
+  "\x85\x98\xf1\x94\xeb\x2a\xf1\x98\x7a\xa4\xb0\x13\x31\x25\x91\xa7"
+  "\x1e\x49\xe3\x62\xaa\x5b\x8e\x30\xa6\x42\x19\x9e\xf2\xfc\xd6\x36"
+  "\xa6\x42\x4d\x78\xca\xf5\x3a\x8b\xa9\x47\x4f\x0a\x63\xea\xd1\x21"
+  "\x04\x53\xa1\x5d\x94\xa7\xba\x1f\xb3\x8e\xa9\xee\x45\xc2\x98\x0a"
+  "\x05\x9e\x0a\x31\xe3\xa9\x47\xcf\x89\xc7\x54\x77\x6d\xe7\x61\x2a"
+  "\x54\x22\x4f\x75\x3f\xc3\xc5\x94\x6b\x9d\x15\x4c\x31\x3c\xf5\xdc"
+  "\x3a\x3b\x30\x65\xc2\x53\x8f\x8d\x67\x31\xd5\xa3\xbf\x30\xa6\xdc"
+  "\x96\x31\x98\xea\xa2\x3c\xe5\xe6\x65\x1d\x53\x8f\x35\x5a\xc1\x14"
+  "\xf0\x54\xa8\x19\x4f\xf5\x18\x2e\x1e\x53\x6e\x13\x3a\x11\x53\x12"
+  "\x79\xca\x4d\xc5\xc5\xd4\x63\x7e\xc2\x98\x0a\x63\x78\x2a\xe4\x25"
+  "\xdb\x98\x0a\x33\xe1\xa9\x1e\xf9\x2c\xa6\xdc\x17\x0b\x63\xaa\x67"
+  "\x05\xc1\x54\x58\x17\xe5\xa9\x9e\xd1\xd6\x31\xd5\x73\x92\x30\xa6"
+  "\xc2\x80\xa7\x42\xcd\x78\xca\x3d\x5d\x3c\xa6\x7a\x16\x74\x1e\xa6"
+  "\xc2\x24\xf2\x54\xcf\x24\x2e\xa6\x7a\x64\x09\x61\xaa\x05\xfb\x3e"
+  "\x19\x60\x2a\x0a\x7c\x1f\x60\xc8\xbd\x9a\x60\xaa\x15\x30\xf5\x81"
+  "\x29\xa6\x7e\x30\xf7\x7d\xee\x57\x0d\x6d\x98\xf2\xbc\x63\x8e\x29"
+  "\x03\x60\xaa\x95\xc6\x94\x67\x0f\xa3\xef\xab\x6a\x28\x82\x58\x5d"
+  "\x43\x55\x81\x80\xa7\x4d\x0c\x9e\x7e\x00\x3c\xc1\xfd\x18\xe0\x7e"
+  "\xcb\x6b\x6b\xd0\x74\x2d\xb9\xaf\x16\xb8\x5f\x83\x29\x96\x5a\xea"
+  "\xe5\x18\x43\x18\x3b\x46\x1c\x55\x2c\x04\xfc\xc4\x9d\x46\x15\x09"
+  "\xf0\xb3\x1c\x7e\x52\xe0\x07\x9d\x46\xe5\xf5\x88\xce\xd9\xb3\xf8"
+  "\xa9\x66\xf0\xe3\xb1\xdb\x3a\x7e\x3c\x32\xc5\x79\xbc\x5e\x2e\xe2"
+  "\xf1\xe3\x51\xc3\xcc\xa5\xf3\x98\x3e\xe3\x02\x85\xe7\xcd\x12\x8c"
+  "\x5c\x43\xd3\x75\xc8\x9d\x0a\x51\xf5\x72\x0b\x42\x1e\x2b\xf4\x48"
+  "\x9e\xfd\x16\xf2\xc8\xfe\x1e\xee\xd7\xf8\xec\x5c\x42\x6e\xa7\x9a"
+  "\xbe\x44\xe5\xb7\x6a\x50\xf9\xdd\x93\xa8\xdc\x00\x3f\xd7\xe0\x07"
+  "\xae\x71\x7a\xa4\xe9\xfd\x6a\x99\xfb\xf5\xdc\x0c\x6d\x0d\x16\xbe"
+  "\x5f\xcf\x44\xfa\x7e\x23\xe0\x7e\x5b\xd8\xfb\xad\x02\x2c\x42\x5c"
+  "\xfa\x1a\x18\x9f\x38\x5d\x8b\xba\x2f\xd2\x51\x54\x0b\x83\x41\x1c"
+  "\x97\x53\x67\x9a\xd0\xf4\x58\x88\xd5\x3c\xc0\x60\xdd\x2e\x94\x9a"
+  "\x04\x18\x6c\x69\xc2\xef\xf5\xb5\x55\x69\xcd\x80\x41\x8f\xc3\x14"
+  "\xf4\x5b\x2b\xc6\xe0\x0f\x18\x83\xee\x1a\x83\x20\x06\xc1\x27\xd2"
+  "\x18\x04\x9f\x68\x13\x83\xa6\x3e\xb1\x57\x0c\x8b\x41\xc5\x32\x61"
+  "\x0c\x3e\x9e\x6b\xf4\x89\xf7\x1f\x83\x8f\x0f\xb7\x8e\xc1\xc7\xdd"
+  "\xc4\x79\x42\xc5\x5a\xf1\x18\x7c\x3c\xb4\xf3\x30\xa8\xe8\x6f\x1d"
+  "\x83\x8f\xeb\x6c\x63\x30\xc4\x5b\x1a\x06\x1f\xf7\xe7\x62\xb0\x57"
+  "\x84\x15\x0c\x32\x3c\x08\xbe\xd2\x36\x06\x4d\x78\x50\x71\x93\xc5"
+  "\x60\x6f\xbd\x30\x06\x7b\x7b\x19\x7d\xe5\xfd\xc7\xa0\xd7\x01\xeb"
+  "\x18\xf4\xca\x11\xe7\x21\x7f\xd7\x43\x3c\x06\xbd\x34\x9d\x87\xc1"
+  "\xde\x3b\xac\x63\xb0\x77\x9a\x1d\x18\x94\xc8\x83\x5e\xc7\xb9\x18"
+  "\x54\xd4\x0b\x63\x30\x94\xe1\x41\xf0\xa1\x36\x31\x68\xea\x43\x7f"
+  "\xb7\x94\xc5\x60\x9f\x74\x61\x0c\x7a\x6f\x36\xfa\xd0\xfb\x8f\x41"
+  "\xef\x51\xd6\x31\xe8\xad\x10\xe7\x39\xfb\xe4\x8a\xc7\xa0\x77\x44"
+  "\xe7\x61\xb0\xcf\x10\xeb\x18\xec\xe3\x6c\x1b\x83\xa1\x12\x79\xd0"
+  "\x7b\x12\x17\x83\xbf\x5b\x60\x05\x83\x0c\x0f\x82\x6f\xb5\x8d\x41"
+  "\x13\x1e\xec\xd3\xcc\x62\xb0\x9f\x8b\x30\x06\x9f\xe8\x6f\xf4\xad"
+  "\xf7\x1f\x83\x7d\x0f\x59\xc7\x60\xdf\x02\x71\x1e\xb5\x9f\x97\x78"
+  "\x0c\xf6\xad\xef\x3c\x0c\x3e\xb1\xdb\x3a\x06\x9f\xc8\xb4\x03\x83"
+  "\x12\x79\xb0\x6f\x39\x17\x83\x7d\xb4\xc2\x18\x0c\x63\x78\x10\x7c"
+  "\xae\x4d\x0c\x9a\xfa\xdc\x7e\xc9\x2c\x06\x07\xac\x15\xc6\x60\xff"
+  "\x1d\x46\x9f\x7b\xff\x31\xd8\x7f\xac\x75\x0c\xf6\xef\x27\xce\xd3"
+  "\x0e\xd8\x2c\x1e\x83\xfd\x17\x74\x1e\x06\x07\x0c\xb7\x8e\xc1\x01"
+  "\x6e\xb6\x31\x18\x26\x91\x07\xfb\x07\x72\x31\xd8\x2f\x5e\x08\x83"
+  "\x06\xf0\xc5\xad\xc5\x01\x69\x86\xbc\x78\x6f\x77\x99\x12\xe9\x14"
+  "\x73\x34\x55\xf1\x8d\x68\xda\x1d\xe8\x9f\xd8\x3b\x68\xce\x1d\x0f"
+  "\xa4\xcf\x8b\x77\x05\x5f\x58\x60\xe2\x9f\xe9\xb9\x65\xba\x9c\xd3"
+  "\x68\xc3\x42\xe4\x0c\xfe\x1b\x8f\xe3\xbe\x55\x57\x9a\x10\xfe\xfb"
+  "\xc9\xf8\x7a\xae\xb1\xd7\x83\xf3\x04\xd4\xaf\x2a\x0f\xfa\x1d\x73"
+  "\x8b\x06\xd5\xbd\x88\x9c\xca\xeb\x34\xd0\x0f\xcb\xe9\xf8\xe2\x7e"
+  "\xb9\xe2\xf4\xe4\x82\xed\x37\x90\xb3\xee\x27\xef\xbe\xd0\xdf\x8a"
+  "\x1e\x7f\x45\xb2\x7e\x75\x94\x01\xf7\x2b\xee\x2f\xdc\xc7\xca\xe5"
+  "\xf8\xdd\xf5\x93\x47\x2a\x01\x63\xba\x9f\x54\x7d\xb7\xc1\x71\xfc"
+  "\x7e\xf5\xc9\x13\xe2\xb1\xf1\x64\x26\xbd\x6e\xc1\xe9\xc9\x88\xf2"
+  "\x5a\xc4\xfb\xee\xd8\x00\xfe\xcd\xbe\xbe\x0a\xf1\x36\xf1\x79\x1d"
+  "\xd0\x57\xca\x02\xfb\xfa\x4a\x79\x95\xdb\x57\x7c\xbe\x4a\x79\x53"
+  "\x7c\x5f\x29\x0f\x92\xbe\x52\xe6\x58\xe9\x2b\x3b\x71\x15\x52\x60"
+  "\xe2\x47\x3a\xa0\xaf\x06\x1e\xb7\xaf\xaf\x06\x79\x99\xf5\x15\x8f"
+  "\xfe\x1f\xd4\x5f\x7c\x5f\x0d\xd4\x90\xbe\x1a\x78\x58\xb8\xaf\x42"
+  "\xed\xc4\x55\xa8\xb7\x89\x6e\xee\x80\xbe\x1a\xa4\xb5\xaf\xaf\xfe"
+  "\x6b\x3c\xb7\xaf\xf8\x74\xea\x7f\x4d\x16\xdf\x57\xff\x45\xbe\x87"
+  "\xe7\x34\xa8\xde\x4a\x5f\xd9\x89\xab\xd0\x02\x13\x7d\xd7\x01\x7d"
+  "\x35\xb8\x9f\x7d\x7d\x35\x38\xc6\xac\xaf\x78\xf4\xd4\xe0\xa5\xe2"
+  "\xfb\x6a\xb0\x1f\xe9\xab\xc1\x0a\xe1\xbe\x0a\xb3\x13\x57\x61\xde"
+  "\x26\x3a\xa4\x03\xfa\x6a\xc8\x24\xfb\xfa\x6a\xc8\x66\x6e\x5f\xf1"
+  "\x8d\xfb\x43\x76\x88\xef\xab\x21\x11\xa4\xaf\x86\xf8\x0b\xf5\x95"
+  "\x3e\x2f\x38\xcf\x1d\xfa\xa0\x79\x53\x70\xac\x7b\x22\x92\xb7\x0c"
+  "\x86\x7e\x53\x40\xbf\xa5\x2b\x51\x6b\x1e\xf4\x9b\x56\x87\xa6\x2d"
+  "\xbe\x40\x55\x36\xe8\x51\x0b\xf4\x59\xb3\x22\xb8\xa0\x4a\x5b\x8f"
+  "\xe7\x1c\xbd\x70\xc9\xe9\xf7\xe9\x21\x8b\x3d\x10\xee\x37\xdc\x0f"
+  "\xb8\xef\x28\xe8\x37\xba\x1f\x15\xc9\xbb\xf4\x8a\x98\xfd\x53\xaf"
+  "\x5f\xa0\x16\x69\x28\x0a\xdf\x2f\xa5\x18\x48\xbf\x17\x98\x5e\x8f"
+  "\xba\x2b\x5f\xc7\xf7\xf4\xfb\x11\x78\x7b\x95\xb6\x06\xf4\xc1\x2d"
+  "\x44\x6b\xb3\x0b\x2a\x85\xfe\xcf\x2a\x37\x7d\x55\xd0\xab\x54\xef"
+  "\x41\xbe\xba\xde\xef\xa0\xd4\xeb\xa8\x1b\xd6\x0f\xeb\x0d\xc8\x3b"
+  "\x39\x06\xc9\xf7\xbe\xad\x96\xd3\x6b\xd7\xe2\x70\x1b\x4f\xe9\xa1"
+  "\x5f\xbc\xa9\xdb\x26\x73\xba\x6f\x47\xa1\xaa\x2b\x39\x74\xdc\xcc"
+  "\x35\x02\x1d\xb7\xef\x54\x1e\xa0\x33\x7d\x29\x45\xf0\xae\x9c\x4a"
+  "\xa4\xa4\x5a\xa1\x8f\x53\xe8\xeb\xb9\xba\xbd\x45\x6c\x1f\x3f\x45"
+  "\xcf\xff\x36\x28\x99\xf9\x5b\xd0\x4f\xf8\xef\xd3\xf3\xb7\x62\x4d"
+  "\xe6\x6f\xc1\x35\xb3\xf3\xb7\x9e\xca\xc2\xf3\xb7\x0c\x17\xbc\xfb"
+  "\x1a\xef\x7d\xd1\x02\x8a\x82\x7b\xef\x55\xd9\xa8\x45\xf8\xfe\x2b"
+  "\x1b\xd5\x28\x35\x1e\x79\x54\xb6\xd4\xa3\x94\x46\x4a\x5b\x99\x76"
+  "\x15\x4d\xbf\x83\x75\x30\xc6\xcb\xef\x97\x91\xb8\x3e\x15\x60\xb8"
+  "\xa0\xea\xab\x71\xfa\x7d\x6c\x65\x35\x42\x26\xeb\x78\xa2\x40\x33"
+  "\xbb\x42\x1c\xa2\xaa\xd2\x2e\x41\x4c\x16\xfa\x56\xe9\xbe\xc7\x71"
+  "\x8a\x82\xfd\x2f\xb6\xe9\xeb\xde\x0b\xff\x80\xb7\xe1\x98\xe1\xf7"
+  "\x4d\xb8\x76\xc0\x76\x13\xfd\x8d\x71\xe1\x9e\x98\x86\xaa\x12\x5b"
+  "\x50\xa5\x0e\x81\xbe\x1a\xd2\xf4\x4d\x50\x8d\x00\x8e\x42\x14\x0c"
+  "\x8e\xb4\xee\x89\x2e\xb7\x6c\xe3\x28\xc4\x9b\xc5\x91\xcf\x49\xc7"
+  "\x70\xe4\xb3\xcc\x71\x1c\xf9\x4c\x94\x8e\xa3\x10\x15\x17\x47\x43"
+  "\x47\x88\xc7\x91\x8f\x87\x78\x1c\xa9\xce\x38\x86\x23\x9f\x63\x04"
+  "\x47\xaa\x3c\x82\x23\x9f\x52\x16\x47\xf4\xda\xa8\x0e\xc2\x91\xca"
+  "\xdf\x0a\x8e\x18\x3e\x0a\x01\x3e\x7a\xec\x92\x1d\x38\x32\xe1\xa3"
+  "\x61\x9e\x8e\xe1\xe8\xe9\x63\x8e\xe3\xe8\xe9\x6c\x07\x70\x64\xc6"
+  "\x47\xc3\x96\x89\xc7\xd1\xd3\x41\xe2\x71\xf4\x74\x3f\xc7\x70\x34"
+  "\xac\x3b\xc1\xd1\xd0\x5a\x82\xa3\x61\x88\xc5\x11\xbd\xde\xac\x83"
+  "\x70\x34\x34\x53\x18\x47\xa1\x0c\x1f\x85\x00\x1f\x79\x7e\x6b\x1b"
+  "\x47\xa1\x26\x7c\xf4\xcc\x6c\xc7\x70\xf4\x4c\x77\xc7\x71\x34\xfc"
+  "\xac\x74\x1c\x85\x9a\xf1\xd1\x33\xc7\xc4\xe3\x68\x78\x91\x78\x1c"
+  "\x0d\x8f\x70\x0c\x47\xcf\xcc\x20\x38\x1a\x3e\x98\xe0\xe8\x99\x49"
+  "\x2c\x8e\xe8\x35\x7c\x1d\x84\xa3\x61\xd5\x56\x70\xc4\xf0\x51\x28"
+  "\xf0\xd1\x73\xeb\xec\xc0\x91\x09\x1f\xf9\xee\x70\x0c\x47\xbe\x33"
+  "\x1c\xc7\x91\x6f\x7f\x07\x70\x64\xc6\x47\x23\xba\x8b\xc7\xd1\xb3"
+  "\xf5\xe2\x71\xf4\xec\x1e\xc7\x70\xe4\xbb\x99\xe0\xe8\xd9\x05\x04"
+  "\x47\xbe\x39\x2c\x8e\xe8\x75\x91\x1d\x84\xa3\x67\xbd\x85\x71\x14"
+  "\xc6\xf0\x51\x28\xf0\x51\xc8\x4b\xb6\x71\x14\x66\xc2\x47\x7f\xb8"
+  "\xea\x18\x8e\xfe\xb0\xd9\x71\x1c\xfd\x21\x52\x3a\x8e\xc2\xcc\xf8"
+  "\xe8\x8f\x33\xc4\xe3\xe8\x0f\xbe\xe2\x71\x34\xa2\xd1\x31\x1c\xfd"
+  "\xe1\x22\xc1\xd1\x88\x83\x04\x47\x7f\xa8\x61\x71\x44\xaf\x35\xed"
+  "\x20\x1c\x8d\x08\x17\xc2\x11\xae\x45\xb0\x91\xd4\x85\x68\xdc\xb0"
+  "\x1c\xf9\x6d\xc7\xff\xb6\x20\xdf\x7b\xeb\xff\x98\x79\x2c\x89\xd4"
+  "\x03\xd0\x38\xfd\x91\xce\xf7\xf2\x9d\xff\xd8\x6e\x88\x8b\x22\x38"
+  "\x67\xfa\x79\x52\xa3\x01\xd7\x05\xb9\x9d\x1a\x85\x9e\xc5\x75\x19"
+  "\x9c\x46\xaa\x71\x1d\xab\xb6\xda\x01\x0a\x81\xda\x01\xc1\xc2\xb5"
+  "\x03\x5a\x36\x19\xd7\xdd\xee\x62\xd7\xdd\x3a\x8d\xcc\xb6\xba\xee"
+  "\xd6\x69\xe4\xd2\xad\xc1\x62\xf1\x30\xd2\x1f\xdf\xe3\xed\xde\xc1"
+  "\xb1\xf7\xd6\x8f\x5c\x09\xf7\x1c\x4a\xee\x7d\x14\x42\x76\xad\xc7"
+  "\xdd\x65\x82\x93\x91\xbe\xb3\x42\x51\x1a\xb5\xee\xf6\x4a\xca\x2b"
+  "\x38\x87\xca\x0f\x2e\x12\x79\x2d\x82\xdf\x3f\x24\xfd\x1d\xe2\xc1"
+  "\xdf\xdf\xcf\xf9\x32\xfd\x4d\xd6\x39\x2b\x04\xea\x16\x04\x0b\xd7"
+  "\x2d\xe0\xef\xef\x51\xd6\xd7\x39\x3b\x8d\xba\x2c\xbe\xbf\x47\xed"
+  "\x67\xfa\x5b\x7b\x6f\xfd\xa8\x46\xb6\xbf\x9f\x8b\x15\xdf\xdf\xa3"
+  "\x8a\x48\x7f\x37\x26\x52\x5e\x21\x1e\x54\x7e\x88\xc8\x6b\x79\x4e"
+  "\xb0\xfe\x37\xd3\xdf\x02\xf8\x7e\xbe\x88\xf4\x37\x53\x33\x41\x21"
+  "\x50\x33\x21\x58\xb8\x66\x02\x7f\x7f\x3f\x1f\x63\xbd\xbf\x9f\x9f"
+  "\x25\xbe\xbf\x9f\x57\x92\xfe\x0e\x01\x7c\x3f\x1f\xc1\xf6\xf7\xf3"
+  "\x1a\xf1\xfd\xfd\xbc\x07\xe9\xef\x3b\x0b\xa0\xbf\x01\xdf\x21\x22"
+  "\xf1\xfd\xfc\x1e\xeb\xfd\x1d\x2a\x80\xef\xd1\x1e\x4c\x7f\x33\xf8"
+  "\x16\xa8\xd7\x10\x2c\x5c\xaf\x81\xbf\xbf\xfd\xce\x5b\xef\x6f\xbf"
+  "\x13\xe2\xfb\xdb\x2f\x87\xe9\x6f\xc0\xb7\xdf\x19\xb6\xbf\x47\x07"
+  "\x8a\xef\x6f\xbf\x34\xd2\xdf\x77\xc3\x29\xaf\x50\xc0\x77\xa8\xc8"
+  "\x6b\x19\xdd\xcf\x46\x7f\x0b\xe0\x7b\x4c\x1a\xe9\x6f\xa6\x56\x84"
+  "\x42\xa0\x56\x44\xb0\x70\xad\x08\xfe\xfe\x1e\x33\xd5\x7a\x7f\x8f"
+  "\x19\x25\xbe\xbf\xc7\x20\xd2\xdf\xa1\x80\xef\x31\x13\xd8\xfe\x1e"
+  "\xa3\x16\xdf\xdf\xa3\xb5\xa4\xbf\xef\xcd\x84\xfe\x06\x7c\x87\x8a"
+  "\xc4\xf7\x98\x2c\xeb\xfd\x1d\x26\x80\xef\x17\xb4\x4c\x7f\x33\xf8"
+  "\x16\xa8\x53\x11\x2c\x5c\xa7\x82\xbf\xbf\x5f\x38\x62\xbd\xbf\x5f"
+  "\xd8\x29\xbe\xbf\x5f\x88\x65\xfa\x1b\xf0\xfd\xc2\x41\xb6\xbf\x5f"
+  "\xf4\x15\xdf\xdf\x2f\x84\x93\xfe\x6e\x9a\x44\x79\x85\x01\xbe\xc3"
+  "\xc4\x5e\x8b\x4e\xa8\xbf\xdd\xa1\xbf\x4f\x80\x8e\x01\xdd\x51\x60"
+  "\xc8\x03\x9d\xa2\xe7\xf6\x7b\x55\xa2\x1f\x7a\xe6\x2e\xee\xfb\xb1"
+  "\xb5\x30\x56\x17\x74\x5a\xbd\x0c\xa7\xb1\x27\x1c\x5f\x3b\x3c\x36"
+  "\x57\x78\xed\xf0\xd8\x65\xe2\xd7\x0e\x8f\x9d\xc0\x6a\xa0\xb1\x99"
+  "\x6c\x4c\xff\x9b\xe6\x0f\x71\x6b\x8a\xc7\x8e\xe4\xad\xa3\xe1\xf4"
+  "\x62\x1d\x5e\x53\x4c\xad\x6b\x7e\xd1\x90\x2f\x45\x1b\x8d\xad\xb7"
+  "\x1d\xeb\x10\x5c\xef\xc1\x43\x38\xd6\xe3\xca\x60\xdc\xf2\xee\xb4"
+  "\xba\x1d\x4e\xe3\x0e\x38\x1e\xeb\x71\xc9\xc2\xb1\x1e\x17\x29\x3e"
+  "\xd6\xe3\x7c\x59\xfd\x35\x2e\x9e\x8d\xb5\xbf\x84\xf5\xe3\xe3\x94"
+  "\xbc\xf5\x3c\x9c\xfe\xbb\x9a\xc4\xba\xa5\xc8\x90\x2f\x45\x97\x8d"
+  "\x3b\x63\x47\xac\xe1\xb9\x0e\xb1\xf2\x5c\x8f\x3f\x08\xb1\x2e\xe8"
+  "\xb4\xfa\x21\x4e\xe3\xb7\x3a\x1e\xeb\xf1\xd1\xc2\xb1\x1e\x3f\x43"
+  "\x7c\xac\xc7\xf7\x63\xb5\xdf\xf8\x70\x36\xd6\xe3\x1b\xc5\xc7\x7a"
+  "\xbc\x1b\x6f\x5d\x11\x27\xff\xc3\x24\xd6\x3a\x67\x88\xb5\x04\x4d"
+  "\x38\x5e\x6d\x3b\xd6\xa1\xb8\xfe\x85\x95\xe7\xfa\xe5\x22\x18\xaf"
+  "\xbd\x3b\xad\x8e\x89\xd3\xcb\x6b\x1d\x8f\xf5\xcb\xb3\x84\x63\xfd"
+  "\xf2\x58\xf1\xb1\x7e\xd9\x95\xd5\x9d\x2f\x07\xb0\xb1\x7e\x59\x23"
+  "\x3e\xd6\x2f\x35\xf1\xd6\x37\x71\x7a\x69\x17\x89\xb5\x3e\xca\x90"
+  "\x2f\x45\x8f\xbe\x2c\xa8\xff\x4d\x62\x0d\xcf\x75\xa8\x95\xe7\x7a"
+  "\x62\x16\xc4\xba\xa0\xf3\xea\xa9\x4c\x5c\xea\x78\xac\x27\x8e\x17"
+  "\x8e\xf5\x44\x1f\xf1\xb1\x9e\xd0\xc8\x6a\xde\x89\x7e\x6c\xac\x27"
+  "\x96\x8b\x8f\xf5\x84\x3a\xde\x3a\x2b\x4e\x13\xf2\x48\xac\x0d\xe5"
+  "\x10\x6b\x09\x5a\x78\x62\x81\xed\x58\x87\xe1\x9a\x2b\x56\x9e\xeb"
+  "\x57\xc1\xd7\x87\x79\x77\x5e\x5d\x97\x57\xe7\x3a\x1e\xeb\x57\x87"
+  "\x0b\xc7\xfa\x55\x2f\xf1\xb1\x7e\x45\xc3\xea\xed\x57\x07\xb3\xb1"
+  "\x7e\xb5\x54\x7c\xac\x5f\xa9\xe6\xaf\xf7\xf2\x4a\x1a\x1d\xeb\xf5"
+  "\xc8\xd7\x90\x2f\x45\x87\xbf\xba\x52\x8a\x0e\x5f\xb2\x15\xb9\x72"
+  "\xe3\x3d\x39\xaa\x73\xb5\xf8\xe4\x19\x8e\xc7\x7b\x72\x7f\xe1\x78"
+  "\x4f\x76\x11\x1f\xef\x49\xd5\xac\x16\x9f\xac\x60\xe3\x3d\x79\x97"
+  "\xf8\x78\x4f\x52\xf3\x6b\xf1\x49\xb1\x8e\x69\xf1\xc9\xf1\x52\xb4"
+  "\xb8\x65\xbc\x5f\x0b\xea\x5c\x3d\xfe\xda\x78\xc7\xe3\xfd\x5a\x0f"
+  "\xe1\x78\x4f\xb9\x23\x3e\xde\x53\xd4\xac\x1e\x7f\xcd\x99\x8d\xf7"
+  "\x6b\x05\xe2\xe3\x3d\x65\x3f\xbf\x1e\x9f\x12\xee\x98\x1e\x7f\x2d"
+  "\x42\x8a\x1e\xb7\x8c\xf7\xd4\x49\x9d\xab\xc9\xa7\x8e\x70\x3c\xde"
+  "\x01\x7a\xe1\x78\x07\x5c\x16\x1f\xef\x80\xfd\xac\x26\x0f\x30\xc9"
+  "\x7f\x4f\xcd\x14\x1f\xef\x80\x22\x7e\x4d\x1e\x10\xe8\x98\x26\x9f"
+  "\x3a\x53\x8a\x26\xb7\x8c\xf7\x74\xbf\xce\xd5\xe5\xd3\x07\x3a\x1e"
+  "\xef\x69\xd7\x85\xe3\x3d\xed\xac\xf8\x78\x4f\x2b\x62\x75\xf9\xb4"
+  "\x3a\x36\xde\xd3\xc5\xd7\xcf\x74\x9a\x96\xc3\xaf\xcb\xa7\xf9\x3b"
+  "\xa6\xcb\xa7\x4f\x90\xa2\xcb\x2d\xe3\x3d\x43\xd5\xb9\xda\x7c\x86"
+  "\xa7\xe3\xf1\x0e\x3c\x2f\x1c\xef\xc0\x13\xe2\xe3\x1d\x98\xc3\x6a"
+  "\xf3\x40\x93\xfc\xff\x8c\x28\xf1\xf1\x0e\x4c\xe3\xd7\xe6\x81\xbe"
+  "\x8e\x69\xf3\x19\x23\xa5\x68\x73\xcb\x78\xff\xc9\xbb\x73\xf5\xf9"
+  "\x9f\x64\x8e\xc7\xfb\xf5\x0a\xe1\x78\xbf\xfe\x85\xf8\x78\xbf\x9e"
+  "\xc6\xea\xf3\xd7\x8f\xb3\xf1\xfe\x53\x90\xf8\x78\xbf\x1e\xcb\xaf"
+  "\xcf\x5f\x57\x3a\xa6\xcf\xff\x34\xd8\xf1\x3c\xf9\xac\x46\xac\xcd"
+  "\xc5\xd6\x7f\xac\x8a\x37\xae\xb9\xfb\x93\x49\xfd\xc7\x59\xf4\xb7"
+  "\x55\xf8\x6b\xcb\xcc\x1a\xdf\xb5\xeb\x3f\xce\xb4\x51\xff\x71\xa6"
+  "\xc8\xfa\x8f\xb3\x7c\xc4\xcf\xc7\x9f\xd9\xc8\x7a\x84\x59\x26\xfe"
+  "\xff\x0d\xfa\xb9\xee\xda\x75\x21\x67\x9a\xd5\x85\xfc\x13\x5d\x17"
+  "\x92\x5a\x2f\xcb\x93\xe6\x45\xde\x40\x8e\xbf\x17\x08\xaa\xc6\x3e"
+  "\x44\x6c\x1d\x4a\x16\xdb\x6f\x54\xb0\xd8\x0e\x3a\x26\x8c\xed\xa0"
+  "\xfe\x5d\xbb\x0e\xe5\x9f\x77\x58\xc7\xf6\x9f\xd3\xc4\xd5\x1c\x09"
+  "\x92\x50\xf7\xe6\xcf\xd5\xac\x1f\x0a\x32\xf1\xbf\xb3\x3d\x3a\x0f"
+  "\xdb\x52\xeb\x53\xfe\xf9\x20\x17\xdb\x6f\x1c\x27\xd8\x76\xaa\x97"
+  "\xe6\xbb\x82\x6a\x1d\x7f\x0f\x12\xb2\x07\x7b\x2e\xb1\xf5\x30\x59"
+  "\x6c\xcf\xde\xcd\x62\x3b\x64\xab\x30\xb6\x83\x9b\xbb\x76\x3d\xcc"
+  "\xe0\x64\xeb\xd8\x0e\x0e\x15\x57\xcb\x24\xf8\xa2\x78\x6c\x07\xef"
+  "\x61\xbd\x5f\xb0\x96\xc5\x76\x48\x43\x27\x62\x5b\x22\x6f\x03\x37"
+  "\x73\xb0\x3d\xbb\x88\x60\xbb\xdb\x8b\xd2\x3c\x66\x48\xa9\xe3\xef"
+  "\x7d\xe6\x64\x62\x7f\x29\xb6\x2e\x27\x8b\xed\xd0\x55\x2c\xb6\xe7"
+  "\x58\xd4\x85\x62\xb1\x1d\x76\xb6\x6b\xd7\xe5\x0c\x9b\x6d\x1d\xdb"
+  "\x61\x7e\xe2\x6a\xa4\x84\x1d\x11\x8f\xed\xb0\x4c\xd6\xe7\x86\x95"
+  "\xb3\xd8\x9e\x53\xd6\x79\xd8\x96\x5a\xaf\x33\x6c\x01\x17\xdb\xa1"
+  "\x49\x04\xdb\xae\x39\xd2\xfc\xf4\x9c\x3c\xc7\xdf\x73\xcd\x8d\xc0"
+  "\x5e\x5a\x6c\x7d\x50\x16\xdb\x6f\xce\x65\xb1\x3d\x77\x96\x30\xb6"
+  "\xc3\x0f\x74\xed\xfa\xa0\xe1\x36\xea\xff\x84\x5b\xab\xff\xc3\xb3"
+  "\x56\x38\x5c\x42\xdd\x8b\xf0\x08\xd6\xd3\x87\xef\x62\xb1\x3d\xb7"
+  "\xb8\x13\xb1\x2d\x91\xb7\xc3\x27\x71\xb1\xfd\x66\x10\xc1\xf6\xa3"
+  "\x75\xd2\x72\x07\x73\x63\x1d\x7f\xaf\x17\xe1\x8f\xf3\x06\x62\xeb"
+  "\x94\xb2\xd8\x7e\x6b\x2c\x8b\xed\x88\x11\xc2\xd8\x9e\x97\xdd\xb5"
+  "\xeb\x94\xce\xf3\xb4\x8e\xed\xb7\xb4\xe2\x6a\xba\xcc\x93\xb0\x0e"
+  "\x7e\x9e\x3f\x9b\xbf\x98\x67\x32\xff\x3d\x22\xad\xf3\xb0\x2d\xb5"
+  "\x7e\xe9\xbc\xc1\x5c\x6c\xbf\x35\x92\x60\xbb\x87\x9f\xb4\x3c\x49"
+  "\x44\x80\xe3\x79\x92\xbf\x04\xd0\xef\x30\x45\xd6\x4b\x65\xb1\x1d"
+  "\xd9\x87\xad\x4d\xf4\x97\xb1\xe6\xd8\x66\x6b\x13\xcd\x9f\xd5\x75"
+  "\xea\xa5\x46\x9e\xb3\x8e\xe3\xc8\x52\x71\x39\x91\xf9\x63\xc5\xe3"
+  "\x78\xbe\x2b\x9b\x13\x99\x6f\x32\xff\xe5\x2f\xc6\x6f\x92\x77\x42"
+  "\xcd\xa2\xf9\x17\xad\xd7\x2c\x9a\xaf\xee\xb8\x3a\xaa\x91\x0d\xdc"
+  "\x9a\x45\x91\x1e\x06\xfa\x59\x70\xcf\x92\x96\x57\xf9\x4b\x90\xe3"
+  "\x79\x95\xb7\xc9\xfb\x5d\x91\x75\x5b\xd9\x67\x21\x6a\x08\xfb\x2c"
+  "\xbc\x3d\x59\xf8\x59\x88\x9e\xdb\x75\xea\xb6\x46\x5d\xb6\xfe\x2c"
+  "\x44\x1d\x17\x97\x43\x89\x96\x50\x07\x26\x5a\xc1\xe6\x50\xa2\x83"
+  "\xd8\x67\xe1\xed\x82\xce\x7b\x16\xa2\xaf\x5b\x7f\x16\xa2\xcb\x3b"
+  "\xae\x9e\x6b\x54\x13\xf7\x59\x88\xea\x47\x9e\x85\x5e\x1e\xd2\xf2"
+  "\x30\x6f\x4b\x7a\xff\xcd\x7d\x16\x62\x22\xe8\x77\xdf\x22\xeb\xc7"
+  "\xb2\xcf\xc2\x3b\x23\xd8\x67\x21\xc6\x42\xcf\xb3\xcf\xc2\x82\x98"
+  "\xae\x53\x3f\xf6\x9d\x9b\xd6\x9f\x85\x77\xaa\xc5\xe5\x5c\x16\xcc"
+  "\x12\xff\x2c\x2c\x50\xb2\x39\x97\x05\x26\xeb\x9f\x62\x8a\x3b\xef"
+  "\x59\x58\xd0\x6c\xfd\x59\x58\x50\xd3\x71\x75\x65\x17\x38\x73\x9f"
+  "\x85\x77\x54\xe4\x59\x50\xe4\x49\xcb\xdb\xc4\xd8\xa1\xff\x6d\xe5"
+  "\x6d\x62\x63\xe9\x79\x01\x22\xeb\xd8\xb2\xcf\xc2\xc2\xb1\xec\xb3"
+  "\x10\x3b\x57\xf8\x59\x58\xb4\xac\xeb\xd4\xb1\x5d\xa8\xb7\xfe\x2c"
+  "\x2c\xac\x15\x97\xa3\x59\x34\x57\xfc\xb3\xb0\x68\x18\x9b\xa3\x59"
+  "\x14\xcb\x3e\x0b\xb1\xfb\x3b\xef\x59\x88\x75\xb1\xfe\x2c\x2c\xaa"
+  "\xeb\xb8\xfa\xb6\x8b\x3c\xb8\xcf\xc2\xc2\x91\xe4\x59\xf8\x9d\xb7"
+  "\xb4\x3c\x4f\x6c\x92\xe3\x79\x9e\x25\x49\xf4\x9c\x09\x91\xf5\x74"
+  "\xd9\x67\x61\xf1\x64\xf6\x59\x58\x12\x23\xfc\x2c\xc4\xad\xea\x3a"
+  "\xf5\x74\xe3\xba\x5b\x7f\x16\x16\xd7\x8b\xcb\xe9\xc4\xc5\x88\x7f"
+  "\x16\xe2\xfc\xd8\x9c\x4e\x5c\x12\xfb\x2c\x2c\x39\xdc\x79\xcf\xc2"
+  "\x12\x4f\xeb\xcf\x42\x9c\xb6\xe3\xea\xec\xc6\xf5\xe3\x3e\x0b\x8b"
+  "\xfd\xc9\xb3\xd0\xa7\x50\x5a\x5e\x68\x49\xa6\xe3\x79\xa1\x84\x4c"
+  "\x7a\x3e\x89\xc8\xba\xbe\xec\xb3\x10\x3f\x8b\x7d\x16\x12\xac\x7c"
+  "\xe7\x61\x69\x6e\xd7\xa9\xeb\xbb\xd4\xc6\xf7\x8f\xe2\xad\x7c\xff"
+  "\x88\x2f\x07\xb4\x74\x99\xf8\x67\x61\xe9\x04\x36\x07\xb4\xd4\x64"
+  "\xfd\x5f\x42\x59\xe7\x3d\x0b\x09\x36\xbe\xff\xb0\xd4\x8e\xef\x3f"
+  "\x48\xad\xf7\xbb\x54\xc5\x7d\x16\xe2\x03\xc8\xb3\xd0\x4f\x29\x2d"
+  "\x8f\x94\x60\x33\xff\x8f\x7d\x7e\xab\xc2\x32\x8f\x54\x5e\xe7\x87"
+  "\x9e\x0e\xc6\xcf\x42\xe2\x8b\xba\xfc\xe0\x02\x5c\x5f\x58\x3f\x98"
+  "\xa9\x41\x99\xce\xd4\x78\x69\xd4\x91\x1a\x94\x5a\x7d\x5b\x0d\x4a"
+  "\x52\xfb\x03\xc9\xf1\x5a\x60\xbc\x26\x58\xe7\x41\xea\x4f\x52\x78"
+  "\x4e\x14\x9e\x23\x75\xa9\x8c\xae\xaf\x92\xa4\x83\x7b\xbf\x62\xa3"
+  "\xfe\x64\xb8\x06\x95\x87\x2f\x47\x3a\xcf\xd3\xcc\x3a\xe1\xbf\x96"
+  "\xd3\xf5\x27\xdf\xf4\xee\xbb\xfe\x47\xa4\x70\xc7\xf5\x27\xc3\x29"
+  "\x43\xaa\x86\xd2\x56\x36\x21\x38\x16\xfa\x77\xae\xb1\x06\x65\x22"
+  "\x2e\x9c\x21\xd3\xbd\xa9\xea\xbb\xed\x47\xa1\xfa\xc2\x89\x12\xea"
+  "\xc0\xfe\xb5\x9e\xcd\xef\x24\x0e\x63\x31\x9a\x48\x8f\xc1\xb0\xff"
+  "\x78\x79\x10\x70\xcc\xfa\x01\xc5\xad\x92\x6a\x6f\x24\x4e\xb2\x1d"
+  "\x33\x7a\x8e\x88\x05\x7f\xb1\x31\x5b\xa6\xd5\xe5\x87\x78\xe3\x3a"
+  "\xc7\xf6\xc7\xcc\xe5\x56\xc7\xc4\x6c\x59\x9a\xfd\x31\x5b\x76\x95"
+  "\x1b\x33\xbe\x3c\xc4\xb2\xd3\xe2\x63\xb6\xac\x90\xcd\x43\x2c\xd3"
+  "\xb0\x31\x5b\xee\x4b\x62\xb6\x2c\x91\xc4\xec\xc9\xea\x56\x49\xf5"
+  "\x3b\x96\xd9\x5c\xff\x8d\x7d\x53\xab\xc2\xd2\x97\xb3\x31\x5b\x51"
+  "\x0c\x31\x2b\xc0\xf5\x96\xed\x8f\xd9\x63\x97\x3a\x26\x66\x2b\x46"
+  "\xda\x1f\xb3\x15\x5b\xcd\x62\xc6\xe3\x97\x57\x48\xf8\x66\xe7\x8a"
+  "\x40\xd6\x2f\xaf\xc8\x63\x63\xb6\xa2\x8e\xc4\x6c\xc5\x30\x12\x33"
+  "\xa5\xae\x55\x52\x0d\x90\x15\xfb\x6d\xc7\x8c\x7e\xa7\x6f\xe5\x39"
+  "\x4b\x0e\xd2\xe5\x83\xc7\x04\xff\x68\x7f\xcc\x3c\xbf\xed\x98\x98"
+  "\x25\xd5\xdb\x1f\xb3\xe4\x19\xdc\x98\xf1\xf9\xba\xe4\xd1\xe2\x63"
+  "\x96\xec\xcc\xfa\xba\xe4\x49\x6c\xcc\x92\x0b\x48\xcc\x92\x34\x24"
+  "\x66\x83\x54\xad\x92\xea\x88\x24\xdb\xcc\x7f\x61\x1d\xda\xaa\xb0"
+  "\xf4\x39\x6c\xcc\x52\xdd\x20\x66\x05\xb8\xfe\xb4\xfd\x31\x7b\x6e"
+  "\x5d\xc7\xc4\x2c\xa5\xd0\xfe\x98\xa5\xba\x98\xc5\x8c\xc7\x7f\xa4"
+  "\x5c\x17\x1f\xb3\x94\x52\xd6\x7f\xa4\xe8\xd8\x98\xa5\x06\x90\x98"
+  "\xa5\xe4\x91\x98\xfd\xd7\xcc\x56\x49\xb5\x48\x52\xbd\x6d\xc7\x8c"
+  "\x7e\x07\x6b\xe5\x39\x4b\x53\xeb\xf2\x41\xb3\x83\x1e\xb7\x3f\x66"
+  "\x21\x2f\x75\x4c\xcc\xd2\x02\xed\x8f\x59\xda\x21\x6e\xcc\xf8\x74"
+  "\x72\x9a\x84\x3a\xd8\x69\x0b\x58\x9d\x9c\xb6\x9f\x8d\x59\x3a\x22"
+  "\x31\x4b\x9b\x44\x62\x36\x38\xad\x55\x52\x3d\x93\x34\xc1\xfa\x5f"
+  "\xd6\x74\xa3\x71\x5e\x3e\x1b\xb7\x8c\xc4\xae\xa3\x1d\x33\x5c\xed"
+  "\x8f\x5b\xc6\x62\xdb\xda\x31\x63\xb6\xf8\xb8\x65\x0c\x66\xb5\x63"
+  "\x46\x14\x1b\xb7\x8c\x52\x12\xb7\x0c\xe4\x98\x76\xcc\xb0\xb9\xfe"
+  "\x95\x4f\x3b\x5a\xc6\x6d\xa5\x6f\xd7\xd1\x8f\xef\xaa\xed\x8f\xdb"
+  "\x4a\x1f\xdb\xfa\x71\xa5\xa7\xf8\xb8\xbd\x5b\xcb\xea\xc7\x95\x4a"
+  "\x36\x6e\x2b\x63\x49\xdc\xde\x2d\x75\x4c\x3f\xae\x14\xac\xff\x66"
+  "\x4d\x3f\x5a\xc6\x6d\x55\x7d\xd7\xd1\x90\xab\x12\xed\x8f\xdb\xaa"
+  "\x8b\xb6\x35\xe4\xaa\x93\xe2\xe3\xb6\x2a\x8f\xd5\x90\xab\x6a\xd8"
+  "\xb8\xad\x56\x91\xb8\xad\x8a\x75\x4c\x43\xae\x6a\x94\xa2\x21\x2d"
+  "\xe3\xb6\xa6\xa8\xeb\xe8\xc8\x35\xbe\xf6\xc7\x6d\xcd\x66\xdb\x3a"
+  "\x72\x8d\x84\x6f\x16\xaf\x09\x60\x75\xe4\x9a\x1c\x36\x6e\x6b\x34"
+  "\x24\x6e\x6b\x54\x8e\xe9\xc8\x35\x36\xeb\x7f\xf0\xe9\x48\xcb\xb8"
+  "\xad\x0d\xea\x3a\x5a\x32\x53\x84\xfe\x5f\x6b\xae\xff\x79\xb4\xe4"
+  "\x5a\x09\xfa\x7f\xad\x33\xab\x25\xd7\x9a\xe8\xff\xb5\x8c\xfe\xcf"
+  "\xd4\x38\xa6\x25\xd7\xda\xa1\xff\x2d\xb5\xa4\x65\xdc\xde\xf3\xe8"
+  "\x3a\x7a\x72\x5d\x91\xfd\x71\x7b\xaf\xbb\x6d\x3d\xb9\x4e\xc2\x77"
+  "\xa0\xd6\x1d\x66\xf5\xe4\x7b\x88\x8d\xdb\x7b\x81\x24\x6e\xeb\x0a"
+  "\x1c\xd3\x93\xef\x09\xd6\x7f\x34\xc6\x4d\xaf\x08\x2e\xa0\x78\xf2"
+  "\x90\x15\x51\x7e\x4c\x6d\xc2\x6c\x8d\xde\x2b\xb8\x40\xec\xf7\x5d"
+  "\x8c\x35\xa7\x4f\x46\x21\x74\xc9\x29\x7b\x99\x63\x75\xa7\xb3\x7d"
+  "\x1c\xaf\x3b\x9d\x75\xa7\xfd\xbe\xef\x92\x75\x5e\x7c\xdd\xe9\xac"
+  "\x5d\xac\x06\xcd\x6a\x60\x63\xbd\x9e\x9e\x9f\x20\xae\x1e\x75\xd6"
+  "\x02\xc7\xea\x51\x67\x2f\x26\xf8\xca\x1a\x46\xea\x51\x67\x47\x75"
+  "\xce\x77\x5f\xde\xab\xc1\xf5\xa8\xa9\xf5\x43\xf6\x48\xab\x8f\x9c"
+  "\xdd\x60\x1b\xcf\x21\xde\x14\x4f\x8e\x96\xc5\x73\xce\x7e\xbd\x57"
+  "\x88\xb7\xd8\xef\xcc\x70\xf1\x9c\x33\xd9\x31\x3c\x6f\x68\x76\x1c"
+  "\xcf\x1b\x4e\xb4\xdf\x77\x66\x36\x94\x88\xc7\xf3\x86\x44\x56\x9b"
+  "\x6f\x38\xcc\xe2\x39\x47\x2b\x1e\xcf\x1b\x5e\x74\x0c\xcf\x39\xe3"
+  "\x09\x9e\xd7\xeb\x08\x9e\x73\xfc\x3a\xe7\xfb\x33\xeb\x77\x11\x3c"
+  "\xff\xbe\x51\x5a\xfd\xe9\x9c\xc3\x76\xe0\xb9\x80\xe2\xc9\x5f\xb3"
+  "\x78\xde\x98\x06\x78\x2e\x10\xfb\xbd\x1b\x2e\x9e\x37\xf6\x71\x0c"
+  "\xcf\xef\x9f\x74\x1c\xcf\xef\xe7\xb7\xdf\xf7\x6e\xde\x4f\x16\x8f"
+  "\xe7\xf7\x27\xb1\x9e\xe5\xfd\x2c\x16\xcf\x1b\xd5\xe2\xf1\xfc\xbe"
+  "\x9b\x63\x78\xde\xe8\x49\xf0\x9c\x5b\x4e\xf0\xbc\xd1\xb5\x73\xbe"
+  "\x83\x93\x9b\x48\xf0\x3c\xf4\x45\x69\xf5\xbd\x37\x0a\xd6\x3f\x66"
+  "\xf1\x1c\xea\x4d\xf1\xe4\xf6\x59\x3c\x6f\x0a\xd4\x7b\x85\x7a\x8b"
+  "\xfd\xee\x0e\x17\xcf\xf9\x0e\x7e\xe7\x22\xbf\x1d\xbe\x73\x91\xef"
+  "\xc0\x77\x2e\xcc\xbf\xbb\x93\x3f\x55\x3c\x9e\xf3\xbd\x59\x2f\x97"
+  "\x1f\xca\xe2\x79\x53\x8e\x78\x3c\xe7\xd5\x3a\x86\xe7\x7c\xe6\xfb"
+  "\x17\x79\x85\x04\xcf\xf9\x35\x9d\xf3\x3d\x9e\xbc\x49\x04\xcf\xc3"
+  "\x56\x4a\xab\x9f\xbe\x29\xd4\x0e\x3c\x17\x50\x3c\xef\x3d\x58\x3c"
+  "\x6f\x56\x02\x9e\x0b\xc4\x7e\xff\x87\x8b\xe7\x82\x43\x8e\xe1\xb9"
+  "\x20\xda\x71\x3c\x17\x8c\x6a\xbf\xef\xff\x14\xf4\x17\x8f\xe7\xbf"
+  "\xd5\xb3\x1e\xb7\xc0\xe4\xfd\xff\xe6\x70\xf1\x78\xfe\x9b\x83\xdf"
+  "\x05\x2a\x38\x40\xf0\xfc\x37\xe6\xbb\x40\x05\xbb\x3a\xe7\xbb\x40"
+  "\x7f\xf3\x26\x78\x7e\xa6\x5c\x5a\x7d\xfa\xcd\xc3\x6c\xe3\x39\xcc"
+  "\x9b\xe2\x79\x27\xc4\xe2\xf9\x03\xad\xde\x2b\xcc\x5b\xec\x77\x88"
+  "\xb8\x78\xfe\x60\xad\x63\x78\xfe\x60\xb4\xe3\x78\xfe\xc0\xa5\xfd"
+  "\xbe\x43\xb4\xe5\xba\x78\x3c\x6f\x31\xbe\xff\x03\x7e\xde\x62\xf2"
+  "\xfe\xaf\x50\xc2\xf7\x89\xb6\x24\x39\x86\xe7\x0f\xd2\x09\x9e\xb7"
+  "\xbc\x48\xf0\xfc\x41\x62\xe7\x7c\x9f\x68\x73\x3d\xc1\xf3\x08\x85"
+  "\xb4\xfa\xff\x1f\xd8\x9c\xff\xc1\x97\xdf\x30\xe6\xa5\x58\x4c\x6f"
+  "\x3b\xee\x78\x8e\x63\x5b\x98\x63\x98\xde\xd6\xc3\x71\x4c\x6f\x3d"
+  "\xd7\x7e\x39\x8e\xad\x12\xbe\xf5\xb7\x35\x8b\xcd\x71\x6c\xad\x66"
+  "\x31\xbd\xdd\x59\x3c\xa6\xb7\x06\x3a\x86\xe9\x6d\xb3\x08\xa6\xb7"
+  "\x7a\x10\x4c\x6f\x0b\xe8\x9c\x1c\x47\xe1\x61\xc7\x72\x1c\xdb\xaa"
+  "\xa5\xe4\x38\x2c\x31\xbd\xa3\xc0\xf1\x3c\xc7\x8e\x11\x8e\x61\xba"
+  "\xe8\xa2\xe3\x98\x2e\x2a\x69\xbf\x3c\x47\x51\xbe\x78\x4c\x17\x85"
+  "\xb3\x79\x8e\xa2\x62\x16\xd3\x3b\x6a\xc4\x63\xba\x68\xb0\x63\x98"
+  "\xde\xe1\x43\x30\xbd\xbd\x8e\x60\x7a\x87\xb2\x73\xf2\x1c\xdb\x73"
+  "\x1c\xcb\x73\xec\x28\x96\x92\xe7\xb0\xc4\x74\xf1\x02\xc7\x73\x1d"
+  "\xc5\x2e\x8e\x61\xfa\xa3\x2f\x1c\xc7\xf4\x47\xe9\xed\x97\xeb\xf8"
+  "\x28\x5a\x3c\xa6\x3f\x1a\xc9\xe6\x3a\x3e\x4a\x64\x31\x5d\xbc\x47"
+  "\x3c\xa6\x3f\x6c\x72\x0c\xd3\x1f\xe9\x09\xa6\x3f\x2c\x25\x98\xfe"
+  "\xa8\xb1\x73\x72\x1d\x1f\x46\x38\x96\xeb\x28\x4e\x94\x92\xeb\xb0"
+  "\xc4\xf4\xdf\xfd\x1d\xcf\x77\x7c\x7c\xce\x31\x4c\x7f\xbc\xd6\x71"
+  "\x4c\x7f\x3c\xab\xfd\xf2\x1d\x1f\x8f\x15\x8f\xe9\x8f\x4d\xbe\x7f"
+  "\xf1\xb1\xc9\xfa\xff\xbf\xa7\x89\xc7\xf4\xce\x72\xc7\x30\xfd\xf1"
+  "\x69\x82\xe9\x9d\x59\x04\xd3\x1f\x97\x75\x4e\xbe\x63\xa7\x9f\x63"
+  "\xf9\x8e\xbf\xdb\xac\x7f\xc1\x97\xef\xb0\xc4\xf4\x27\x0a\xc7\x73"
+  "\x1e\xbb\x4b\x1c\xc3\xf4\xee\x30\xc7\x31\xbd\xdb\xa7\xfd\x72\x1e"
+  "\xbb\x3d\xc5\x63\x7a\x57\x2d\x9b\xf3\xd8\x6d\x32\xff\xe9\x93\x99"
+  "\xe2\x31\xbd\xab\xc8\x31\x4c\xef\xde\x49\x30\xbd\x2b\x9c\x60\x7a"
+  "\x77\x61\xe7\xe4\x3c\x76\xb9\x39\x96\xf3\xf8\x44\x29\x25\xe7\x61"
+  "\x89\xe9\x3d\xf5\x8e\xe7\x3d\xf6\xa4\x3b\x86\xe9\x3d\x23\x1c\xc7"
+  "\xf4\xa7\xfa\xf6\xcb\x7b\x7c\x7a\x59\x3c\xa6\x3f\xdd\xcf\xe6\x3d"
+  "\x3e\x35\xa9\x7f\x5f\xa2\x12\x8f\xe9\x4f\xe3\x1d\xc3\xf4\x9e\x65"
+  "\x04\xd3\x9f\x8e\x24\x98\xde\x13\xdb\x39\x79\x8f\x4f\x34\x8e\xe5"
+  "\x3d\xf6\x58\xcc\x7f\x5b\x12\xb9\x30\x42\xb9\x68\xfe\xfc\x25\x91"
+  "\xf1\xca\x25\x0b\xa2\xe7\x45\x8e\x1d\x62\xfc\x7d\xac\x6f\xe2\x90"
+  "\xc4\x47\x51\x44\xcc\xdc\x37\x13\xfe\xc0\xee\x5c\x10\xb9\x10\xfe"
+  "\x79\x14\x45\xcd\x5d\x12\xa5\x8c\x5f\x16\x1b\xa9\xc4\xbf\xc5\xcc"
+  "\x8b\x85\x43\x16\xc5\xb3\x5b\x5e\x8f\x5c\x30\x37\x31\x7a\xe1\x5f"
+  "\x94\x73\x17\x44\xff\x65\x61\x4c\xe4\xc2\x78\x65\x5c\xe4\xe2\xa5"
+  "\xd1\x71\x91\xf8\xff\x4b\x94\xf3\x17\xc5\xc1\x86\x79\x91\xd1\x09"
+  "\x91\xca\xb7\x96\xce\x9f\x1f\x19\xb7\xe4\x51\x34\x75\xe9\x82\xf8"
+  "\xe8\xd8\x05\x91\xca\x09\x53\xc7\x0f\x9f\x39\xf1\x4f\x33\xc7\x8d"
+  "\x7b\x14\x99\x7c\x7b\x5a\x49\xe5\x25\x17\x01\x86\x9c\xaf\x38\x1d"
+  "\xda\x5a\xe9\x8d\x50\x36\x60\x73\x43\x1c\xf2\x58\x1b\x87\x9c\x33"
+  "\x6f\x21\xd7\xec\x5b\xc8\x4d\xf9\x36\xf2\xa7\x3c\x0b\x7c\x37\xdc"
+  "\x42\x0a\xaa\xf7\x40\x6f\x2a\xb7\x1a\x7e\xaf\x4e\xd3\x7a\x1e\xc2"
+  "\xdb\x3c\xa8\xdc\xd2\x28\xbc\x0f\x62\xe1\x0c\xfb\xea\x2f\x39\x1d"
+  "\x0a\xd5\x7a\x7e\xe9\x91\x7a\x15\xc9\xa9\x9e\x7b\x67\xee\x35\x68"
+  "\xe5\xc7\xf0\x97\x4a\xa0\xaf\x90\xd3\xbe\x05\xf0\x13\x84\x9c\xfe"
+  "\x5f\x7b\xdf\x03\x10\x55\x95\xf6\x7d\xe6\xce\x55\xc9\x90\x19\x0d"
+  "\x5c\x2a\xb3\xd1\xc5\x1a\xff\x8f\x86\x85\x46\x46\x6e\x6d\xa4\xa6"
+  "\xee\xfb\x9a\x2f\x29\x98\xb6\xe6\x62\xa1\x12\xa2\xa2\x22\x20\xeb"
+  "\xf6\x69\x29\x0c\x04\xbc\xb4\x22\xd0\xae\xed\x67\xef\x5a\x62\x4b"
+  "\x86\xbb\x54\x53\xe2\x2e\x19\x3a\xd4\xda\xbe\xb4\xab\xeb\xc8\x92"
+  "\x4b\x84\x3a\xc9\x28\x03\xcc\xcc\xf9\x9e\xe7\x9c\x7b\x99\x3b\xc3"
+  "\x8c\x02\xa2\xdb\xe7\x76\xf5\x30\xf7\x9e\xfb\x9c\xe7\x3c\xe7\x3c"
+  "\xbf\xf3\x3b\x7f\xee\xbf\xb2\x00\x08\xa1\x10\x96\x40\xd8\x06\xc1"
+  "\x08\xc1\x41\xd4\x07\x1e\x85\x90\x0c\x01\xe2\x0e\x14\x41\xd8\x0b"
+  "\xa1\x8c\xa8\xdf\x19\x06\x21\x12\xc2\x6c\x08\xcb\xb8\x9e\x77\x30"
+  "\x34\x13\xf5\xef\xc2\x21\xc4\x13\x75\x39\xc4\x97\x83\x9e\x77\x41"
+  "\xae\x1c\xd2\x94\xd7\x40\x38\x01\xc1\x0e\x71\x98\x3e\x91\x9f\x7b"
+  "\xb7\x91\xa8\x0f\x86\x41\x80\xbc\x0e\x42\xfe\x07\xf3\x20\x40\x3e"
+  "\x07\xcb\x21\x54\x42\xb0\x40\x40\x19\xb0\xe7\x3d\x48\xf3\x5e\x0a"
+  "\x04\xb0\xe5\x3d\x1b\x51\x57\x80\xed\x15\xfb\x08\x94\x91\x87\x0a"
+  "\x88\x3b\x14\xe1\x3e\x3e\x34\x5f\xb1\xef\x2b\x24\x6b\xb6\xdc\x6d"
+  "\x31\x8d\x71\x40\xbb\xdd\xff\x89\x33\x93\xa8\x9d\x39\xbf\xd7\x26"
+  "\x8e\x21\xaa\x26\xf5\xfe\x7c\xf3\x56\x42\xa8\xb6\x36\xca\xb4\xb1"
+  "\x1d\xcf\xe7\x63\x9d\xb5\x66\xed\xcf\xb3\x90\x57\xb7\x61\xfb\xec"
+  "\x19\x3e\xf7\xe7\x49\xe9\x4f\x58\x54\xe3\xaa\x31\x3d\xcd\x8d\xad"
+  "\xa1\xe9\x31\xbb\xf0\x39\xdc\xb3\x58\x87\xd8\x6e\x8c\xb1\x61\x54"
+  "\xbb\xa0\x12\x39\xc6\xb4\x91\xd9\xb5\x12\xda\x5b\x10\xa4\x4f\xa0"
+  "\xe0\x47\x6b\x08\xf8\x3c\x93\x88\xec\x38\xe7\x90\x81\x96\x6e\xdb"
+  "\xc6\x79\xa7\x8c\xcd\x5f\xda\x42\x5e\xac\xc5\x73\xf6\x37\x66\x66"
+  "\xd0\x3d\x71\xa1\xa6\x55\xed\xa4\x41\x5d\xf6\x34\xf0\x9f\x40\xef"
+  "\x99\x99\xe1\x2a\x78\xb1\xb6\x02\x30\x80\x32\x87\xd2\x1a\xf1\x37"
+  "\x1e\xca\x2d\xd0\xbc\xa4\x42\x5c\x03\x32\xa5\xe5\x02\x27\xef\x5f"
+  "\xd9\x16\xb2\x2d\x51\x37\x53\x43\xeb\x25\xbb\x2c\xea\x32\x02\x76"
+  "\xb0\x74\x6d\x21\x23\x74\xa8\xdb\x59\xba\xdd\x00\x71\x22\x05\xec"
+  "\x81\x0d\xaa\xf3\x90\xce\x99\x3f\x22\xd4\x34\x93\xe5\x79\x09\xec"
+  "\x14\xd2\x9f\x00\xdd\xbf\xda\x6e\xd8\xbf\xd1\x2e\x50\xb4\x3d\x78"
+  "\x44\x28\x60\x3d\xd0\x99\xf5\x56\xf8\x6b\x43\x88\xb8\x3b\x97\x90"
+  "\x92\x21\x24\xa0\x35\xab\xac\xd9\x22\x3e\x5c\xc3\x79\x6f\x7f\x82"
+  "\x00\x32\x90\x67\x35\x05\x7f\xb0\xbc\xf2\x56\x6a\xfd\xe7\x75\xe0"
+  "\xa1\xce\xbc\x0a\x56\x6a\x31\x2f\x56\x3f\xbc\xae\xf8\xbe\xac\x67"
+  "\xcf\xac\x2b\xd8\x7c\x60\x2a\xea\xb0\xa8\x0f\x8c\xa3\xbf\x99\x65"
+  "\x70\x16\x24\x1b\xf0\x1c\xca\xf3\xfa\x3f\x64\xd0\x6c\x21\x36\x0a"
+  "\x71\x4e\xc9\x07\x4e\xf4\x81\x90\x01\xfc\x55\x16\x88\xf9\x41\xda"
+  "\x14\x67\xa6\x0e\x70\x13\x97\xc7\xfd\x7a\xe0\x48\x4a\x35\x75\x41"
+  "\x70\x4e\xac\x26\x2a\xd3\x4c\xf4\xe9\x81\x06\xdd\x8f\x07\x40\xdd"
+  "\x1e\xf8\x8a\xd7\x2d\xd4\xe9\x88\xed\x7a\xa8\x17\x2d\xd4\x45\x20"
+  "\x7d\x69\x54\x1d\xd3\x01\xf5\x8d\x75\x54\x02\x75\x04\xf5\x14\x80"
+  "\xfe\x6f\xcd\x7a\x27\xd8\xab\x9e\x30\x4e\x6f\x51\xdd\xa3\xc5\x38"
+  "\xdd\x48\xc2\x31\xa3\x28\x37\xfa\xd7\x99\xbf\xb9\x14\x8f\x9f\x1a"
+  "\x4d\xb4\x9a\x6a\x22\xe8\xd2\xc2\x2a\xb8\x9f\x93\x0a\xdd\xbe\x3d"
+  "\xb0\x83\x16\x2c\x6e\x04\x79\xbd\x1b\x57\xef\xec\x71\xe6\xc4\xed"
+  "\x68\x0b\x59\x33\xcf\x9e\x9f\xa0\xa5\xc6\xb8\x1d\xf8\x5c\x79\xbd"
+  "\xfa\x1d\xf6\xac\x1d\xcd\x0c\x20\x3c\x9f\x38\x63\x5a\x02\xb5\xa6"
+  "\x7d\x0b\x3e\x18\xba\x66\xde\xa1\x75\x56\xf0\x45\x82\x16\x7d\x5d"
+  "\x71\xd9\x2e\xe0\xbb\xfe\x68\xd0\x5b\x0b\x8a\xb9\xcf\x03\xa0\x9c"
+  "\x04\xf5\x82\xed\x0d\xee\xf2\xbc\xb3\x0d\xfd\x0e\x79\xec\xe1\x79"
+  "\x83\x5e\x01\xf2\x18\x1c\xb7\xa7\x35\xeb\x77\x81\x16\xd5\xe7\xac"
+  "\x5f\xa4\xeb\xe8\x89\xec\x76\x42\x5a\xd6\x51\xc7\x5c\xc7\x69\x17"
+  "\xf4\xb7\x04\xce\x8f\xb3\x90\x1f\xed\x95\xeb\x85\xb7\xa5\x4e\x3d"
+  "\xec\x1d\x10\x56\xae\x67\xbe\x2f\x3d\x16\xf5\xef\x86\x3d\xe3\xd0"
+  "\xa9\xda\x2f\xd3\xda\xec\x05\x60\x5b\x26\xa1\xed\xeb\x68\xcd\xe6"
+  "\x68\x6a\xcf\xfa\x9c\xc0\x98\xe7\x24\x01\x0e\x1d\x16\xa4\xa2\xd6"
+  "\xb9\x1b\x88\x26\x28\x51\x43\x3f\xa9\x3e\x49\x36\x45\xd3\x46\x73"
+  "\x8a\x93\x1c\xb7\x35\x90\xd4\x2f\x49\x60\xfa\x31\x12\x9c\x1a\x4d"
+  "\xad\x35\x4b\x4e\x12\x1e\x7f\x8c\xa4\x9f\x21\xe2\xa6\x2a\x6a\x9f"
+  "\x03\xfd\xef\xa7\x27\x31\xbe\x01\xe2\x9d\x24\xbd\x91\x3a\xd2\xe2"
+  "\x48\x20\xee\x1f\xab\xc2\xf8\xaf\x70\x9c\x22\xce\x4d\xb1\x6a\x8a"
+  "\x21\x4f\x4c\x5f\x02\xb6\xb8\x2e\xd3\xca\xec\xcb\x84\x6c\x7a\x9a"
+  "\x84\xa6\x2e\x25\x30\x26\x23\xd4\xec\x78\x97\xcc\x75\x52\xe8\xdf"
+  "\x8f\x90\xcd\x2b\x48\xc0\x5c\x07\x3e\x17\xfe\x05\x84\xdd\xa4\x04"
+  "\x64\xa1\x6c\x26\x2c\xdb\xa6\x53\x30\xde\x39\x27\xa7\x79\x5f\x4a"
+  "\x73\x8a\x60\x9d\xb5\x0d\xae\x4d\xb4\xe7\xd4\x5a\xa1\xec\x3a\xac"
+  "\x03\xc8\xa7\xd6\x85\xe9\x2e\xb3\x7e\x07\xeb\x40\xf5\x8c\x03\xda"
+  "\x6a\xfe\xf3\xd6\x67\x52\x4c\x4c\xaf\x45\x5d\x1e\x5b\x92\xc4\x6c"
+  "\xf2\x90\x9d\xeb\xa0\x2d\xd6\x90\xe7\x41\x57\xf9\xd6\xb9\x29\x0f"
+  "\x53\xc0\x9f\x0a\x30\x51\xda\x9a\x55\x5e\x25\xd7\xb7\xa5\x93\x4b"
+  "\xca\x2b\xc0\x17\xa5\xea\x44\x22\xc2\xf9\x06\x8b\xea\x8b\x08\x05"
+  "\x76\x91\x8f\xfa\xcb\xb2\x5c\xe6\xdd\x00\x8b\xea\xcf\x19\x6e\x19"
+  "\x86\xd7\x4e\x19\x38\x0f\xf8\x3f\xb1\xcd\x7d\xfe\x40\x24\x55\xe8"
+  "\x90\xfa\x55\x59\xb7\x1a\xf8\xd5\xe8\x0c\x49\x2a\x85\xf6\x5a\x46"
+  "\x5b\x42\x03\xa9\x00\xbe\x71\x50\xbb\x2b\x3f\xce\x0a\x7d\x67\xa0"
+  "\xd9\x61\x23\x5c\xfe\xdd\x63\xd0\xd6\x2b\xf8\xbd\xac\xef\xbe\x8b"
+  "\x3a\x61\x8c\x35\x0f\xfa\x61\xed\xdc\x6a\x6a\x47\x5e\x70\xe6\x8f"
+  "\x31\x64\x25\x41\x5f\x9c\x9f\x64\x74\x85\xac\x2c\xb5\xbf\xbe\x2d"
+  "\x03\xb9\x9e\x86\x6c\x2e\xa5\x79\x90\x56\xd2\x03\xf9\xf6\xb3\xa8"
+  "\xdf\xdd\xe1\x84\xf4\x34\x2f\xce\xca\xe3\x39\x6f\x71\x7e\x79\x77"
+  "\x07\x1d\x05\xe7\x8c\x0b\xf2\xe0\x5c\xbf\x7a\xf5\x41\xe4\x1d\x02"
+  "\xc7\x35\xa6\xb4\x8b\x20\x7b\xf0\x2e\x8e\xe9\x05\x46\x8f\x63\x01"
+  "\xeb\xf3\x80\x11\xb9\x47\x37\x13\x75\x1e\x7c\xc8\xcd\x33\x4a\xce"
+  "\x5e\x0c\x6d\xe4\xe0\x3c\x8b\xca\xf0\x28\xc3\x3e\xa4\xb3\x31\xbe"
+  "\x02\xde\x1a\xb1\x6d\xdb\xe1\x68\x42\x0e\x57\x61\x3b\x3a\x98\x6c"
+  "\x51\x4d\x8e\x71\xd7\xe5\xc1\x9d\x28\xcb\x38\x04\x39\x54\xe0\x7c"
+  "\x85\x69\x68\xc1\x9a\x28\xe4\x41\xe4\x43\x8b\xfa\xe0\x36\xe4\x42"
+  "\xe0\x93\xbd\xbc\xff\x99\x15\xc0\xf8\x24\x37\x67\x1e\xd8\x95\x51"
+  "\x2f\xd9\xa2\xb4\x4d\xe6\x3e\x9a\x93\x53\xcb\x65\xe3\xf6\x42\xfe"
+  "\x36\x8b\xea\x3e\x83\x12\x2f\xbc\x5c\xef\x3d\x0d\x98\xae\x9b\x58"
+  "\x05\xc7\x30\x46\x02\x7d\x19\x34\xeb\xad\x55\xc0\x2f\x01\x88\x53"
+  "\xe4\xc8\xc2\x5c\x22\xda\x73\x72\x2c\xce\x9c\x9c\xba\xd6\xac\xf7"
+  "\x22\x65\x5e\xc1\x74\xd8\x16\x80\x5b\x02\x18\x67\x38\x1d\x6a\xd6"
+  "\xde\x9d\x64\x5c\x27\x8f\x40\x5c\xdb\xe0\x9c\x3a\x29\x5e\x64\xf6"
+  "\x64\xaa\x5d\x90\xb7\x4a\xb6\xbd\x6d\x70\x5c\x21\xe8\xcd\xb3\xa8"
+  "\x74\x91\x1e\x3c\x93\xfb\x9f\x06\x4a\x63\x10\x33\x6a\xb0\xf3\x10"
+  "\xfc\x0e\x90\x30\x78\xeb\xe1\x6a\x42\x1e\x7d\x0c\xf2\x00\x5f\xbe"
+  "\x36\x94\xc2\xf8\xfe\xbd\x13\x16\xf2\xe2\x6c\x4c\xbf\x1d\x8e\x31"
+  "\x1e\x65\x20\xbe\xd9\x42\x92\x24\xbd\x07\x8c\xe8\x1b\x4f\xbd\x15"
+  "\x83\xb9\x5e\x66\xcb\xad\xa8\x13\xd3\xa1\xce\xdd\x05\xb4\x19\xf5"
+  "\xb4\x66\x55\x18\x64\xdd\x3b\x21\x4e\xd6\xff\xe8\x4a\x39\x8f\x8a"
+  "\x79\x70\xbe\x4a\x69\x7b\x61\x01\xb5\x71\xbb\x2a\x12\x2c\xe4\x25"
+  "\x56\xef\xdb\x20\x0e\xd3\x72\xff\x57\x6c\x47\x6c\x58\x78\x79\xd4"
+  "\x1c\x23\x15\x85\x16\xb2\xb5\x42\xd9\xdf\x80\x0f\x06\xf1\xfe\xf0"
+  "\xf7\x5a\x49\x5f\xa5\xac\xcf\xad\x8b\xeb\xa0\xc6\xdc\x5a\x45\x7b"
+  "\x0c\x44\xfd\x20\x0f\xe5\x4f\x0e\x94\xca\x9f\x6a\xe3\x78\x86\xba"
+  "\x3f\x34\x18\xeb\x1e\xfb\x3e\xf4\x33\xcb\xe3\xf5\x6d\xdb\xd0\xef"
+  "\xe0\xff\x54\xb9\x7f\x04\xdf\xe4\xb5\x66\x1d\x32\xb8\xfb\x92\x43"
+  "\x22\xfa\x1b\xe2\xb7\x72\xfd\x87\x66\x5b\x54\x77\x3b\x3c\x79\xe8"
+  "\x40\x29\x1d\x9a\x64\x42\xae\x92\xec\xc9\xc7\xfe\x52\x3e\x0f\x79"
+  "\x88\x30\x4e\xc9\x42\xcc\xe3\x38\x85\x86\xbc\x90\x01\x7a\xf2\xbc"
+  "\xfa\x5f\x51\x92\x3b\x8c\x32\xaf\x0e\xa5\x8d\x20\x53\x21\xcb\xe0"
+  "\x79\xf0\xc1\x74\x88\xab\xb1\x90\x9c\x4a\x8c\xcb\x02\x19\x98\xdb"
+  "\xf9\x7d\x5e\x27\x6d\x04\x11\xcc\x45\x16\x9c\xcb\x62\xfb\x8e\x34"
+  "\x0f\xb3\x11\x73\x91\x8b\xb8\x7e\x33\xab\x2c\x2a\x8d\x9a\xce\xaa"
+  "\x7f\xff\xc4\x71\x7b\x23\xe9\xd9\xf8\xf3\xf7\xec\xfd\x87\xb4\x1d"
+  "\xe6\x5c\xa9\x93\x09\x8e\x4d\xce\xab\xff\xb0\xc1\x6c\xbd\xc8\xb8"
+  "\x0e\xf6\x9f\xc3\xf3\xaf\xc2\x1c\x0d\xe7\x69\x30\x17\x8f\x37\x0a"
+  "\x7c\xae\xe6\x02\xd9\x62\x8c\xc7\x79\x1c\xf4\x61\x25\x8a\x73\xf4"
+  "\x37\x33\x0d\xbc\xee\xfe\x30\x89\x71\x3e\xda\xeb\x78\xdc\x84\x36"
+  "\xbb\xf6\xcc\x34\x60\x19\xd2\x53\xa8\xcb\xec\x68\x35\x61\x3f\xa7"
+  "\x5b\x87\x73\xcc\x3f\x0c\x9a\xbb\x9b\x50\xd7\x1b\x33\x0d\x3d\x2c"
+  "\x03\xbb\xbe\x04\xf3\xf0\xf3\xd6\x51\x33\x0d\xe9\x4e\x22\x64\xa7"
+  "\xf5\x0b\xf8\x51\x11\x35\xb5\xdc\x33\xab\xac\x35\xeb\x0f\x86\x8f"
+  "\x52\x08\xe9\xf9\xd8\xfc\x0f\x06\xb9\xec\xc5\x52\xd9\x21\x2f\x76"
+  "\x4f\xd8\xc4\xc2\x0c\x56\x5e\x90\x89\xf7\xe7\x2f\x9a\xa9\xa1\x87"
+  "\x8b\x1c\x64\x4d\x11\x6d\x5f\xb3\x1b\x78\xb2\xe0\x99\xc4\xfd\xc5"
+  "\x75\xc8\xeb\x51\x72\x7d\xb2\xba\x73\x58\x49\x62\x1a\xd1\x36\xa9"
+  "\x2b\x07\xcf\x4d\xcd\x60\xdf\x6c\xfa\x10\xe4\x7a\x68\x2b\x5b\xff"
+  "\x3a\x0e\xf3\xfa\xb9\x8e\x74\xca\xfb\xa6\xca\xa9\x73\x24\x7d\x78"
+  "\x4e\xf6\x5f\xb1\x34\xdf\xee\x79\x1e\x95\x51\xbd\x28\xab\xd6\x4f"
+  "\x59\x9d\xbd\x2f\x6b\x65\x75\xd7\xb2\xbe\x3f\xaa\x6f\xcb\xfa\xbe"
+  "\xdf\xfb\x7f\xae\x50\x56\x9d\xef\xb2\xbe\xff\x75\xef\xcb\xfa\x7e"
+  "\x79\xd7\xb2\x7e\x30\xb8\x6f\xcb\xfa\x81\xdf\xe7\xdf\xaf\x50\x56"
+  "\x83\xef\xb2\x7e\xf0\x45\xef\xcb\xfa\x41\xa9\x8f\xb2\x3a\xfb\xb6"
+  "\xac\x1f\x8a\x7e\xcb\x2a\x68\x28\xf2\x13\xf0\x52\x7b\x5a\x1b\x8c"
+  "\xe9\x0a\xd6\x46\x6d\x7e\x9d\x08\x35\x36\x3b\x39\x3e\xac\x8e\xa4"
+  "\x6f\x20\xc2\x84\x44\xe0\xbd\x4c\x12\x49\x0b\x46\x18\x8e\x17\x35"
+  "\x43\xfc\x59\x72\x2c\xc5\x4e\xa2\x92\x90\x7f\x3f\xfc\xc4\xbc\xac"
+  "\xa7\xfc\xfb\x61\x5e\x27\xff\x3a\x26\x4b\x9c\x6b\xba\x74\xbc\xb9"
+  "\x9d\x60\xf9\x61\xff\x4c\x27\xff\x66\xf2\xfa\xf6\xe6\x5f\xac\x0f"
+  "\xb3\xdd\xee\xc1\xbf\xfc\xb9\x2d\xd3\x5b\xde\xdc\x9b\xd5\x44\x88"
+  "\x6f\xee\x35\x6d\x47\xee\x2d\x86\xf3\x3d\xb3\xdf\x34\x5f\xe6\x5e"
+  "\x23\xe4\xa9\xe4\xde\xc3\xcb\xb0\x7f\x35\xed\xeb\x1d\xf7\x9a\xf6"
+  "\xc9\xe5\xde\x2d\x95\x1b\xe2\xb4\x9e\xdc\x6b\x6a\xe8\x0e\x6e\x69"
+  "\xc1\xc2\x79\xfb\x87\xdb\xfb\xb9\xf6\xcc\x4e\xc4\xfe\xad\x15\xea"
+  "\xe4\xbd\x62\xbb\x78\x56\xfd\x11\xff\x56\x41\xeb\x32\x15\xdd\x33"
+  "\x2b\x74\x6e\x32\x3d\x4d\x47\xcd\x4e\xc4\xb5\x53\x5c\x03\x80\xf3"
+  "\xaf\xd1\x37\x66\x85\xf6\xcc\x6e\xae\x93\xfe\xe6\x89\xb2\x34\x68"
+  "\x2f\xfb\xd7\xd9\x05\xd7\xa6\x18\x0d\xf8\x41\x4b\xf3\x17\x1b\xe9"
+  "\x4b\x53\xf6\xb6\xe4\x27\x93\x23\xfa\xaf\x08\xca\xd2\x2d\x62\x54"
+  "\xef\xed\xff\x38\xec\xca\xf6\x7f\xfc\x74\xcf\xed\xe7\x3a\xbb\x67"
+  "\xff\xc7\x61\xdd\xb2\x7f\x28\xd8\xdf\x1e\xd1\x0f\xe6\x8c\xc2\x87"
+  "\xed\x11\x62\x0f\xed\x29\xef\x96\x8f\xaf\x29\x8f\xc3\xdd\xe6\x3f"
+  "\x3a\xf4\x05\xe3\xfe\x62\xab\x00\x1c\xc0\xfa\x70\x6c\x7b\x9c\xff"
+  "\x1a\x81\xb3\x4e\x53\xce\x49\xd6\x1e\x72\xd2\x61\xbf\xdf\x7f\xef"
+  "\x9a\xff\x33\xd6\xbe\xcf\xbf\xca\x7f\xf9\xbd\x39\xf1\xed\x38\xa3"
+  "\x7f\x4e\x5c\x6c\xed\xca\x89\x55\xa7\x7a\xce\x89\x55\x7b\xbb\x72"
+  "\xe2\x1f\x6f\x71\x73\xe2\x91\x4b\xbd\xe7\xc4\x23\x1f\x75\x9f\x13"
+  "\x8f\xec\xee\x1d\x27\x1e\x89\xbf\x32\x27\x1e\x31\xf5\x8e\x13\x8f"
+  "\x98\xba\x72\xe2\x91\x30\x4f\x4e\x3c\x62\xf7\xeb\x4b\xe3\x0c\x3b"
+  "\xf4\xd1\x81\x4d\xea\x3f\x56\x3b\x32\x09\x71\x19\x3f\xd0\xcf\x75"
+  "\xd2\x56\x9a\x33\xc3\xee\x12\xc2\x91\x57\xa2\x5a\x5b\xe3\x03\x5c"
+  "\xeb\xf5\x81\x74\xc8\x82\x69\xb4\x23\x14\xe7\x94\x61\x60\xbf\x86"
+  "\xb6\xea\x83\xe8\x7a\xfd\x90\xa2\xcb\x24\x18\x42\x68\x91\xd4\x1f"
+  "\xc3\xbe\x81\xae\x0f\x1d\x98\xb5\x8e\x8c\xd3\xd8\x48\x00\xd8\x10"
+  "\xa3\xd9\xa2\x25\xc0\x41\xc1\xb8\x4f\x33\x3f\x76\x94\x5c\x26\xa2"
+  "\x26\x05\x7c\x33\x18\xf2\x4b\xd1\x50\xba\x46\x4f\x4a\x92\x48\x80"
+  "\x4b\x20\xa1\xc5\x02\x2d\x73\xb4\xea\x05\x67\x70\x52\x19\xf7\xcf"
+  "\x9f\x52\xd9\xdc\x2b\x2f\x29\xd5\x35\x34\x69\x99\x33\x3d\x5e\x4d"
+  "\x37\xc5\xa8\xd1\x56\x67\x5e\xd2\x12\x5a\x00\x21\x3d\x3e\x08\xc7"
+  "\xd0\x25\xeb\x20\xef\xd6\xd0\x81\xd9\x90\x77\xf1\x3a\x12\xb6\xfb"
+  "\x32\xd1\xd3\x16\xbd\x00\xfe\x8f\xc1\x6f\x9f\x42\x1d\xc5\xb8\x84"
+  "\x8f\x1d\x70\x4e\x44\x4e\xa4\x98\xbf\x03\xf2\xef\xd0\xe3\x3a\x17"
+  "\x60\x9b\x84\x96\x40\xfe\xce\xf5\xfa\x1e\xb6\x97\x3f\xb1\xe7\x9f"
+  "\x64\xbb\x5c\xe3\x9e\x33\xd2\xb7\x21\xa0\x5d\x50\x87\x25\x58\x27"
+  "\x13\x9e\xcb\x43\xdb\x76\x5e\x26\xe3\xc0\xce\x30\xb0\x41\x0f\xf9"
+  "\xe2\x7b\x63\x62\x16\xbf\xa8\x45\x8c\x7a\xd8\xe6\xcc\x91\x6c\xbb"
+  "\x00\xb6\x9d\x77\xdb\x86\x79\x61\xfd\xf8\xbb\x26\x3b\x77\xf3\x70"
+  "\x6c\x9b\xff\xd4\xa4\x0c\x88\xc6\xeb\xb3\x2d\x9b\xe2\x7b\x88\xd5"
+  "\xea\x60\x7f\x78\xc9\x7e\x9b\x0c\xa3\xda\x8a\x98\x39\xbf\x38\x4d"
+  "\x71\x1d\xf1\x17\x6f\x93\x71\x66\x68\xd7\xc7\xed\xe7\x08\x1d\x5c"
+  "\x11\x73\x44\xdf\xdc\xd3\xbc\x32\xfc\xe5\xf5\x72\x26\xad\xed\x08"
+  "\xc3\x35\xb0\x35\xf6\x6c\x81\xa6\xb4\x87\xcd\xd2\x1d\x3d\xd1\x4e"
+  "\x9e\x49\xc1\x6b\xc0\x34\x45\xb7\x90\x04\xd4\xab\xcd\xe1\xe9\x5f"
+  "\xe2\xf5\xaa\x4f\x44\xcf\xeb\x55\x9f\xe8\x89\xfa\x68\x0d\x51\x7f"
+  "\xea\x20\xea\x63\x5b\x09\xc8\x79\x86\xe3\x95\x73\xdf\x1c\x4e\xd2"
+  "\x1c\xf4\x9f\x34\x6f\x64\x7c\x96\x40\xed\x73\x47\xab\x2c\xa6\x75"
+  "\x78\xfd\xe6\xe8\x11\xa8\xbf\x6f\xa0\x5f\xd5\xe0\x3e\xea\x4b\x4c"
+  "\x22\xb7\x35\xa9\x8f\x56\x69\x6c\x03\xa2\x1d\xc1\xc9\x3a\x07\x8d"
+  "\x21\x1d\xba\x6d\x19\x6d\x79\x49\xc6\x0e\x5c\xa3\x7b\x16\x39\xe8"
+  "\x93\xf7\x35\xaa\x0c\x42\xc1\xff\x94\x86\xe2\x35\xcc\x98\x22\x08"
+  "\xe8\x4b\xe6\xc7\x21\x8b\x6a\xd0\xdf\xd8\x16\x4a\x78\xbc\x16\xdb"
+  "\x43\xb6\xd4\x6e\xac\xea\x31\x4b\x9c\x02\x21\x4e\x48\x9f\xfe\x15"
+  "\x19\x86\xdf\xbc\xdd\x0d\x72\xcf\x38\x03\xb0\x1d\xc7\x98\x16\x7e"
+  "\x4e\xce\x26\x12\x21\xfd\x5b\x32\x08\x30\xc1\xda\xa3\x0b\xda\xe3"
+  "\xdc\x93\x1a\x3b\xf0\x8a\x2b\xed\x12\xd1\x20\x4f\xe1\xf7\x63\xcc"
+  "\xcd\x16\xe2\xba\xa0\x0f\xda\xb5\x8a\x04\x3b\x2e\xc4\x0f\xb1\x5e"
+  "\x88\xbf\xed\x35\x17\x09\x0e\x4a\x24\xda\xdd\xab\x00\x8b\xab\xa1"
+  "\x7d\x9e\x87\xf6\xd9\xcc\xdb\xa7\x8c\x3f\xfa\xb2\x35\x19\x9f\xeb"
+  "\x67\x6d\x33\x47\x6a\x9b\xeb\x01\x7f\xeb\xdc\xf8\x73\xac\xd6\x0b"
+  "\xbb\x05\x4a\xc0\x46\xa8\xf7\x3f\xd9\x4a\xd2\x06\x04\xe0\x3a\x25"
+  "\xbd\xe7\x49\xfc\x66\x06\x94\x95\x3a\xf6\x83\x2f\xfa\x8d\x16\x74"
+  "\x34\x3f\x59\x77\x74\x5e\x23\x71\xaf\x9b\x98\xa7\xb4\x8f\x9a\xa5"
+  "\xd3\xfd\x07\xbd\x50\xaf\x3e\x5a\x09\xf1\x01\xba\x05\xf7\x6a\xc1"
+  "\x8f\x53\xf8\x3a\x8b\x39\x1c\xd7\x4d\x2d\xea\xa3\x46\xd0\x45\xf0"
+  "\xbe\x80\x4f\xd9\x35\xb7\x4f\x6d\x20\x4b\x9c\x50\xe7\x8e\xe0\x11"
+  "\x15\xae\xe0\x24\x93\xe9\xf9\x76\xc6\x57\x1d\xe0\x83\xb3\x09\x44"
+  "\x78\xa6\x19\xea\xc6\x09\x75\xd3\xaa\x0f\x04\xde\x9a\x87\xbc\x45"
+  "\x8d\x0b\xc2\x53\x2d\xd4\x35\x77\x99\x9a\x42\xbd\x04\xe0\x3a\xf9"
+  "\xe2\x44\x42\x37\x9f\x83\x3a\xb2\xd5\x11\x28\x5b\x10\x70\xdb\x90"
+  "\xdd\xeb\x48\xf0\x2e\xa8\x9f\x41\xcd\x30\xa6\xc9\xfd\xbd\xee\xed"
+  "\xb4\xea\x7e\x4e\xc0\x39\xf2\x98\x66\x8b\xea\x16\xf0\x55\xd0\x0e"
+  "\x6c\xb7\xd0\x8e\x35\x5b\x18\xaf\x32\xdf\x3a\xd6\xeb\x47\x76\xac"
+  "\xd7\xeb\x20\x0c\x97\xb9\x4e\xe6\x19\x9a\x55\x1d\x8b\x3c\x67\x4e"
+  "\xb1\x10\x07\xd4\x65\x10\xf6\x89\xeb\xf5\xc3\x58\x9d\xfe\x0c\xea"
+  "\x74\x39\x09\x98\x68\x27\x2a\xb0\x4b\x0b\x36\x93\x63\xf1\xf5\xc8"
+  "\xad\xa1\x4e\x68\x47\x58\xcf\xa0\x53\xa0\x80\x35\x57\xde\x88\x8a"
+  "\x27\x57\xe8\x60\x7c\xf5\x05\xc1\x77\xc7\xa6\xb7\xd1\x33\x78\xcd"
+  "\xcf\x9c\xe2\x20\x34\x24\x59\x47\xd9\x5a\xd7\xd1\xbc\xa3\xf3\xec"
+  "\xc4\x3f\xa6\x8f\x6d\x76\x63\xfa\xd8\x66\x37\xa6\x8f\xb1\xf7\x7f"
+  "\x2a\x71\xdd\x56\x0a\xb8\x0e\x56\xe2\xba\x26\xff\xba\xe2\x7a\x4e"
+  "\xcf\x71\xfd\xda\x79\x05\xae\xd3\xfe\x35\xb8\xfe\x34\x86\xe1\x5a"
+  "\xdd\x31\x8a\xe1\xb5\xd0\xec\x78\x07\xc6\xbf\xc7\xe2\x65\xdc\x7e"
+  "\xf2\x3f\x88\xdb\xe3\xfb\xbe\xab\xb8\x6d\x6b\xd5\xeb\x20\xf4\x39"
+  "\x6e\x41\x67\xb7\x71\xfb\x69\x4c\x3b\x91\xeb\x0f\xf1\x4b\x8d\x15"
+  "\x31\xba\x74\xf2\x30\xf0\x44\xb8\x66\xcb\x70\x72\x8c\xd5\xa1\x39"
+  "\x5c\xb7\x80\xba\xea\xd5\xc7\xd9\x35\xd0\xf6\x4c\x4a\x5d\xc1\x2b"
+  "\x4b\xd3\x3f\x23\x5a\x57\xde\x18\x83\xd9\xf1\x16\xd1\x24\xf2\x6b"
+  "\x0b\x74\x70\x6d\x23\xcc\xc3\xd9\x75\x58\x57\x4e\x45\x3c\xae\x31"
+  "\xe3\x75\x14\xbc\xa6\xe9\xca\x29\x34\xb8\x06\xd7\x46\xd1\x9c\xda"
+  "\x0c\xbc\x3e\xdb\x9a\x65\x0e\x97\xaf\xcf\xfb\x1c\x1b\x05\x6f\x2e"
+  "\x85\xf6\x02\x73\xaa\xda\xb7\xe0\x57\x00\x3b\x8e\xc1\xaf\x1a\x7e"
+  "\xd9\xf5\xcc\x9e\xf5\x73\xe6\x78\x7e\x7d\x29\x39\x5c\xe2\xc1\x15"
+  "\xac\x0d\x8e\x21\x83\x9a\xa4\x7d\xb0\xa7\x4a\xbe\xde\xdf\x29\xef"
+  "\xae\x8f\x25\x98\x37\xd4\x89\xc8\xef\x41\xe0\xc7\x78\x7f\x8f\xa4"
+  "\x8f\x1d\xbb\xc2\xe2\x42\x4d\x69\xf5\xa4\x59\x5d\x6b\x30\x43\xcb"
+  "\x76\x15\x24\x87\xe3\x75\x37\xc4\xbd\x9c\x6f\x10\xf8\xdb\xb4\x91"
+  "\xc9\xb0\xe7\xa4\x5d\x79\x2f\x10\x5a\x30\xd2\x80\x73\xc8\x56\x1a"
+  "\x3f\x5d\xfa\xc5\xeb\x4d\x6a\xbe\xde\x52\xbb\x99\x42\xfd\xe1\x37"
+  "\xdf\x3b\xef\x79\xc2\x6f\xb1\x67\x88\xba\x8f\x52\x89\x74\x6d\x86"
+  "\xdb\x8b\xdf\x6b\xc7\x7b\x8a\xee\xcd\x20\x19\xad\x3e\xbe\xd7\xee"
+  "\xbe\xf7\xa8\x36\xde\x95\xff\x02\x8c\x7b\x6b\x2b\x60\x0c\x60\x52"
+  "\x96\xd9\x97\x2f\x40\xfe\x84\xbf\x73\x3d\xf3\x43\xad\xd5\x9f\x9e"
+  "\xc7\xf4\x4e\xda\x33\x5d\x9f\xf9\x7d\xff\x19\x0d\x7b\xa2\x6c\xee"
+  "\x5e\xa7\xc9\xd5\x11\xa3\x39\x92\x7a\xae\x87\x63\xa2\xcf\xfc\xbe"
+  "\xff\xda\x99\xb7\xd2\xe4\xb8\x07\x74\x8f\x1e\x4e\x9c\xab\x63\x1e"
+  "\x07\x1f\x05\xe2\x58\x6f\xf3\x0a\x7e\x9f\x5a\xcd\x5e\x07\xc1\x71"
+  "\xdf\x9b\xab\xaa\x85\xf6\x8e\x18\x12\x64\x25\xda\x39\xb6\x74\x9a"
+  "\x7d\x9e\x84\xd1\xf5\x31\x9a\x1d\xe7\x49\x64\x47\x4b\xe8\xc0\x57"
+  "\x92\x88\xd8\x0e\x9c\xdc\xbe\x26\x5e\x83\xf7\xc4\x7d\xd0\x64\x12"
+  "\xcc\x8e\x0a\x1c\x67\x86\x61\x3f\x80\xb6\x3b\x5b\x62\x82\xb6\x5f"
+  "\xc4\x6b\xc5\x97\x88\xe9\xd9\x5f\x41\x3f\xf0\xf9\xeb\xfd\x36\x03"
+  "\xf7\x01\x77\xb1\xfe\xa0\x17\x7d\x41\x3b\xf4\x05\x4f\xc6\x50\xfb"
+  "\xf1\xba\xcf\xf1\xfa\xb5\x36\x7d\x2d\x19\x84\xfa\xf1\x7a\x33\xeb"
+  "\x1f\x9e\x82\xfe\x01\x8e\x61\x2e\xd1\xd9\x3f\xe8\xe6\x90\x2e\xfd"
+  "\x03\xce\x43\x8e\x9f\x6c\x24\x80\xe5\x01\x73\x6c\x1a\x7b\x9a\x8d"
+  "\xba\x70\x4e\x62\x76\x9c\xc3\x77\x17\x05\xc9\x7d\x05\xf6\x13\xed"
+  "\x52\x3f\xb1\x5b\xea\x27\x7e\xd9\x07\xfd\xc4\x2f\xb1\x9f\xf8\x82"
+  "\x08\xaf\x61\x1f\x01\xfd\xc3\x6f\xff\x6e\x15\x3a\xa0\x4f\xe8\x99"
+  "\x9f\xff\xec\xf7\xfb\x17\xb4\x20\x59\xed\x82\xbe\x18\xfd\xbc\x09"
+  "\xfc\x8b\x7e\x36\xeb\xc1\xb7\x75\x03\xa2\xdb\x20\xde\x51\xb0\x30"
+  "\x71\xef\x59\xab\x40\xf3\x16\x1b\xdb\x00\x0f\x1b\x2f\x11\xc1\x11"
+  "\xbc\xd2\xf4\xd6\x02\xa3\x80\xf3\x56\x57\xfe\xc2\x72\x3e\x47\xfe"
+  "\xe2\x5b\x5c\xa3\xd1\x34\x12\x2d\xae\x9f\x3a\x69\x8c\xc6\xf5\x4d"
+  "\xcc\x20\xd7\x0b\xa1\x01\x1d\xdf\x84\x0e\x7c\xf9\x79\x22\x5a\x5f"
+  "\x88\xd7\xa4\x3f\x4d\xb4\x1f\xfe\xc5\x28\x1c\xb7\x41\xdb\xee\x6f"
+  "\x99\x4f\x41\x7f\x49\x3d\x89\x28\x79\x96\x84\x17\x9f\x25\xba\xe2"
+  "\xe5\x64\xdc\xae\xb3\x80\xa1\x17\x62\x82\x3a\x18\x3e\xda\x4c\xec"
+  "\xde\x80\xe5\x24\x8a\x0e\x8d\x4b\x84\xdf\x08\xe3\x72\x82\xef\x2d"
+  "\x4c\xa4\x21\x2b\x4d\x2e\x90\xdb\x01\x73\x37\x18\xa3\x83\x0d\x27"
+  "\xbe\xf4\x85\x9b\x5d\x3d\x1c\x43\x3c\x39\x0f\x70\x53\x0b\xb8\xf9"
+  "\xd6\x13\x37\x38\x6f\x65\xd8\x79\x92\x63\x07\xaf\x01\x96\x28\xc7"
+  "\x17\xcf\x1e\xed\x35\x7e\x8a\x60\xfc\xdc\xe6\x85\x9f\xa2\xf3\xd7"
+  "\x86\x9f\x0e\xc0\x4f\x51\x26\xe0\xe7\x18\x11\x0a\x5d\xd7\x82\x9f"
+  "\x2f\xf8\xb7\x36\xf6\xcc\x0a\xe5\xf7\x27\x9d\xb8\x1d\xfd\x6c\x51"
+  "\x9f\x08\x7d\x4a\xaf\x22\xbd\xc4\x95\xf5\xca\xb8\x5a\x14\xce\x71"
+  "\x55\xf7\x44\x2f\x70\xb5\x0f\x70\x65\xbd\x32\xae\x2e\xf9\xc3\x95"
+  "\xb5\x2b\xae\xfe\x77\xd2\x8d\xc5\x15\x7b\x57\xe8\xbf\x01\xae\xea"
+  "\x82\x3d\x71\xf5\x97\x17\x39\xae\xfe\x92\xd8\x7b\x5c\x2d\xba\x0a"
+  "\x5f\x2d\x92\xf8\xea\xaf\xaf\xf7\x1c\x57\x67\x44\x0a\xfa\xaf\x8c"
+  "\xab\x73\x7e\x70\xb5\xc8\x07\x5f\x7d\xb9\xfd\xc6\xe2\x8a\xbd\xcb"
+  "\xf4\xdf\x00\x57\x7f\x4d\xf0\xc4\x55\xdd\x27\x1c\x57\x75\xd5\xd7"
+  "\x80\xab\xab\xf0\x55\xac\xc4\x57\x27\xdb\x7a\x81\xab\x58\xc0\xd5"
+  "\x55\xf8\xea\x94\x3f\x5c\xf9\xe0\xab\xbf\x9d\xb9\xb1\xb8\x62\xef"
+  "\x5a\xfd\x37\xc0\xd5\xc9\x2a\x4f\x5c\xfd\x6d\x04\xc7\xd5\xdf\x74"
+  "\xbd\xc7\x55\xec\x55\xf8\x2a\x56\xe2\xab\xd3\x3f\xe9\x05\xae\xca"
+  "\x29\xe8\xbf\x32\xae\xde\xf7\x83\xab\x58\x1f\x7c\xf5\xf7\xa9\x37"
+  "\x16\x57\xec\x5d\xb0\xff\x06\xb8\x3a\x3d\xcc\x13\x57\xa7\x36\x70"
+  "\x5c\x9d\x4a\xb9\x06\x5c\x5d\x85\xaf\xe2\x24\xbe\x3a\xf3\x66\xcf"
+  "\x71\x55\x1f\x08\xb8\xba\x0a\x5f\x6d\xf6\x87\x2b\x1f\x7c\x65\xc9"
+  "\xb9\xb1\xb8\x62\xef\xaa\xfd\x37\xc0\xd5\x99\x64\x4f\x5c\x9d\xfe"
+  "\x8c\xe3\xea\x74\x6d\xb7\x70\x65\x57\xe0\xea\xe4\x80\xe8\xf6\x74"
+  "\x3e\x1f\x7c\x73\xb9\x84\xab\xdf\x3c\x51\xb6\x69\x2d\x11\xde\x5a"
+  "\x58\xe8\x35\x17\xfc\xc7\x25\x6f\x4c\x01\x2e\x18\xa6\x1c\x2f\x00"
+  "\xa6\x9a\x38\xa6\xd2\x4e\x01\xa6\xfe\x5a\x28\x98\x53\xce\x21\x4e"
+  "\x18\x86\x8a\x96\x03\x86\x70\x5e\xa8\x12\x43\x7b\x32\x07\x7c\xa5"
+  "\x49\xc6\x52\xfd\xa9\x3e\xc1\xd2\x7c\xc0\xd2\x09\x6f\x2c\x1d\x71"
+  "\x63\xe9\x27\x7e\xe6\x80\x8b\xfd\x60\xc9\x72\x75\x2c\xed\xc2\x35"
+  "\x84\xd5\xd7\x09\x4b\x9f\xb9\xd7\x10\xf6\x3d\x6b\x15\x1c\x21\x3d"
+  "\xc5\xd2\x3f\x4c\x9e\x58\xaa\x1f\xc5\xb1\x54\x1f\xd6\x7b\x2c\x2d"
+  "\xb2\xfa\xc7\x92\x3c\x9e\x3a\xfb\xc8\xb5\x61\x09\xc6\x56\x1e\x58"
+  "\xba\xfa\x38\xca\x8d\xa5\xaf\x46\xdf\x58\x2c\x79\x8d\xa3\x6e\x5a"
+  "\x2c\x9d\x0d\xf4\xc4\x52\x83\x34\xef\x6b\xf0\x3b\xef\x73\x41\xdf"
+  "\x85\xd7\x9c\xf0\xb9\x5f\x67\x4b\xcc\xe3\x4e\xe8\xd3\xf0\xf9\x5f"
+  "\xbc\x4e\xb1\x7f\x55\xad\x80\x78\xca\xba\x48\xc2\x76\x24\x91\x48"
+  "\x8d\x9d\x63\xc5\x01\x58\xd9\x76\x91\x88\x1d\x1d\x80\x93\x76\x22"
+  "\xb6\x41\x7d\xb7\x75\xc4\x6b\x6a\x96\x34\x92\x0f\xcf\xd7\x42\x5f"
+  "\x56\x41\x8a\x21\x4d\x87\xb4\x0e\xe9\xda\x14\x13\xb4\x7d\x23\xae"
+  "\x43\x1e\x23\xa6\x85\xbf\x04\xff\xff\xf3\x9a\xfd\xdf\xf6\x73\x7f"
+  "\xfe\x7f\xdf\xc3\xf7\x45\x0a\xbf\xb3\x67\x0b\x7a\xd9\x1f\xb1\xeb"
+  "\x54\xab\xb8\xef\x65\xbf\xbf\xd6\x07\x7e\x7f\x4d\xf2\xfb\xb5\xf5"
+  "\x47\x8d\xfe\xef\x7f\x54\x70\x05\xbb\xa7\xc0\xce\x39\x42\xe6\x05"
+  "\xe4\x08\x1c\xbf\xb4\x05\x2f\x4c\xf6\xee\x6f\x90\x1f\xce\xab\x9b"
+  "\x5e\xc4\xbe\xc9\xef\x38\x46\xe2\x89\xf4\x0d\x9c\x27\xa4\x71\xcc"
+  "\xb2\xbe\x5d\x7f\xfc\xfa\xe9\xeb\xc7\x17\xef\x5f\xbd\xef\xb9\x86"
+  "\x71\x0c\xe2\xa6\xc8\x0b\x37\xd7\x83\x2f\x7a\x87\x9b\xa6\x48\x4f"
+  "\xbe\x68\x7c\x8d\xf3\x45\x63\x61\x77\xfa\x9e\xab\xe0\xc9\xe6\xc6"
+  "\x13\x5f\x73\xe4\x78\x6a\xfe\x08\xd7\x28\x7b\x88\xa7\x8a\xbe\x5d"
+  "\x77\xfc\xe6\xcd\x1b\x8b\xa7\xbe\x5b\x77\xfc\x6e\xe3\xa9\x79\x87"
+  "\x27\x9e\x9a\xbe\xe6\x78\x6a\x6a\xbc\x76\x3c\x2d\x52\xf0\xd3\x22"
+  "\x05\x3f\x5d\x18\x8c\x6b\x93\x3d\xc3\xd3\x3f\x02\xfb\x76\xbd\xf1"
+  "\x5c\xdb\x8d\xc5\x53\xdf\xad\x37\x7e\xb7\xf1\x74\xfe\xa4\x27\x9e"
+  "\xce\x4d\xe5\x78\x3a\x17\xd1\x07\x78\xb2\x79\x8f\x89\x39\x9e\xbe"
+  "\x5d\x8a\xe3\xe7\x1e\xe2\x69\x49\xdf\xae\x33\x5a\x9f\xb8\xb1\x78"
+  "\xea\xbb\x75\xc6\xef\x36\x9e\xbe\x1d\xe7\x89\xa7\x0b\xdb\x39\x9e"
+  "\x2e\x6c\xbb\x76\x3c\xc5\x2a\xf8\x29\x56\xc1\x4f\x2d\x07\x70\x2d"
+  "\xb2\x87\x78\xea\xe3\xf5\xc5\x8b\xaf\xdd\x58\x3c\xf5\xdd\xfa\xe2"
+  "\x77\x1b\x4f\x2d\xa9\x9e\x78\xfa\xf6\x4b\x8e\xa7\x6f\xeb\xfa\x00"
+  "\x4f\x0a\x7e\x8a\x53\xf0\xd3\x65\x15\xae\x41\xf6\x0c\x4f\x0d\x01"
+  "\x7d\xbb\xae\x68\xfb\xfa\xc6\xe2\xa9\xef\xd6\x15\xbf\xdb\x78\xba"
+  "\x54\xe3\x89\x27\xdb\x68\x8e\x27\x9b\xbe\xbb\x6b\x41\xf2\x1a\x90"
+  "\x12\x4f\xfe\xe7\x76\xf6\xc7\xbc\xe7\x76\x3d\x5b\x03\x82\x79\x5e"
+  "\xaf\xd7\x13\x5b\xc7\xff\xff\xba\x9e\x88\x18\x92\xd7\x81\xbe\x7b"
+  "\x6b\x40\x76\xad\x27\x86\x2e\xaf\xe5\x18\xba\x9c\xec\x0f\x43\x0e"
+  "\xe5\x3d\x69\xff\x54\xdc\x93\x76\x8e\x08\x6f\xad\x32\x09\xc7\xa5"
+  "\x7b\xd2\xf0\x7e\xb4\xe3\x0d\x8d\x64\xfb\x65\xa2\x0d\x8a\x27\xda"
+  "\x39\x89\xe9\x34\x1b\x39\x64\x4d\x8c\xe6\x95\xb3\x24\xb2\x03\x30"
+  "\x93\xd5\x24\xdd\x97\x06\xb8\xf9\xf4\xa4\x9d\x7c\xb0\x0a\xef\x4b"
+  "\x2b\x23\x25\x20\xe7\xc8\xe3\xeb\x41\xc8\x23\xec\x9e\xb4\xe5\x78"
+  "\x4f\x5a\xdb\x14\x9f\xf7\xa4\x65\xf6\xf0\x9e\xb4\x64\xc0\x81\x0d"
+  "\x70\x70\x09\x31\xf0\xae\xc7\xbd\x68\xbb\x32\x15\x6b\x40\xcf\xfa"
+  "\x59\x03\xaa\xeb\xde\x35\x89\x3e\xbf\x17\xed\x82\xe2\x5e\x34\x79"
+  "\x0d\x68\x21\x70\x47\x8f\xfd\xde\x1e\x70\xa5\x35\x20\x27\x70\xc2"
+  "\x1c\xbc\xb7\xdc\xe6\x5e\x2f\x4e\x5d\x81\xcf\xfe\x2e\x4c\x74\x00"
+  "\x57\xe0\xfd\xe3\x6f\x3f\x5b\xcd\xd6\xfb\xcc\x29\x75\x64\x7b\x3b"
+  "\xd1\x6a\xac\x12\x2f\x84\x2c\x2c\xef\x00\x6e\x70\x42\xbf\x04\xbe"
+  "\x1e\xd4\xb1\x06\xb8\xe1\x22\x70\xc3\x1a\xe0\x86\x4b\xc0\x0d\xf5"
+  "\xd5\x8c\x1b\xe8\x4b\x96\xf9\xf8\xce\xef\x92\x26\x12\xbe\xbb\x89"
+  "\x44\x20\x07\x38\xf3\x57\x9a\x3a\x42\x16\xe6\x59\x43\x16\x16\xc2"
+  "\xb9\xbd\x1c\x03\x6d\xa6\x1d\x49\x84\x71\x3d\xfa\x5e\xb7\x1c\xf9"
+  "\xa0\xe3\xa1\x8e\x4c\x42\xae\x05\x07\x1d\xca\x35\x41\x25\x0e\xfc"
+  "\x70\xc0\x35\x63\xc1\x6b\x1d\x78\xd7\x35\x72\x00\x62\x61\x97\xcc"
+  "\x01\xd7\x84\x05\x87\xdf\xe7\x7f\xae\x82\x05\xeb\xd5\xb1\xb0\x28"
+  "\xbc\x9b\x58\xd8\x87\xef\xca\xee\x8a\x85\x45\xc1\xd6\x90\x45\xa1"
+  "\x70\x4e\xcf\xb1\x70\xc9\x07\x16\x9c\x4f\x5c\x7f\x2c\x78\xae\xc9"
+  "\xdc\xbc\x58\x70\xe9\x7a\x87\x85\x45\xdd\xe0\x85\x45\xdd\xe4\x85"
+  "\x33\x22\xbe\x63\xda\x07\x16\x80\x17\x16\x01\x2f\x2c\x92\x78\xe1"
+  "\x9c\x0f\x2c\xd0\xa7\xae\x3f\x16\x3c\xd7\x53\x6e\x5a\x2c\x88\xc4"
+  "\xff\xfb\x2f\xae\x8c\x85\x6e\xf0\x42\x6c\x37\x79\xe1\x4c\x2c\xbe"
+  "\x9b\xb9\x2b\x16\x62\x81\x17\x62\x81\x17\x62\x25\x5e\x38\xd5\x15"
+  "\x0b\xa2\x6a\xe9\xf5\xc7\x82\xe7\x5a\xc8\xcd\x8b\x05\x21\xa2\x77"
+  "\x58\x88\xed\x06\x2f\xc4\x76\x97\x17\xca\xf1\x9d\xc6\x3e\xb0\x00"
+  "\xbc\x10\x0b\xbc\x10\x2b\xf1\xc2\xfb\x3e\xb0\xa0\x5e\x79\xfd\xb1"
+  "\xe0\xb9\x8e\x71\xf3\x62\x41\x7c\xb4\x97\x58\xe8\x06\x2f\xc4\x75"
+  "\x93\x17\xea\x03\xf1\x5d\xc0\x5d\xb1\x10\x07\xbc\x10\x07\xbc\x10"
+  "\x27\xf1\xc2\x66\x1f\x58\xe8\xb7\xe1\xfa\x63\xc1\x73\x0d\xe2\xe6"
+  "\xc5\x42\xff\x79\x57\xc4\x02\xed\x8a\x05\x5c\x43\xc0\xf9\x23\xbe"
+  "\x6b\x9b\x61\xe1\x79\x93\xd0\x4e\x11\x0b\xd5\xe4\xe5\x8d\x0a\x2c"
+  "\xe4\xf3\x79\x84\x8c\x83\x9d\x4a\x1c\xe0\xf3\x4b\x88\x03\x98\x3f"
+  "\x38\xc0\xef\xb4\x20\x2e\x91\xdd\xaf\x94\xbf\x70\x2f\xce\x1f\x70"
+  "\x9d\x01\xe7\x10\x7e\xe7\x0f\xe2\x80\xcd\x7d\x82\x81\x04\xc0\x40"
+  "\xb3\xef\x79\x64\x9f\xcf\x1f\x2e\x5c\x27\x0c\xc0\x5c\xf2\x97\x69"
+  "\xd7\x82\x81\x80\xf9\x3d\xc7\x00\x8c\x11\xba\x85\x01\x3e\x4e\xb8"
+  "\x32\x06\x62\xb5\x6e\x0c\xc0\x78\x21\x3f\x56\x8f\xe3\x03\x8e\x81"
+  "\xd8\x50\xff\xe3\x83\x5b\xb6\x5c\x7f\x0c\xf4\xf1\xf8\xe0\x3b\x8b"
+  "\x81\x81\x31\x7e\x9f\x61\x44\x2e\x07\xde\x9f\x33\x7a\x38\xa1\x2f"
+  "\xc4\x3c\x9e\xd5\x44\xc2\x5e\x79\x9e\x44\xe2\x7b\x63\xde\x6a\xb7"
+  "\x0b\x69\x89\xf4\x9f\xf8\x6c\xb5\x03\xca\x81\xef\xaf\x66\xf8\xb8"
+  "\x10\x1a\x60\x8e\xb7\x92\xed\x80\x85\x57\xa0\x0c\xf8\x5e\xfa\xa0"
+  "\xc4\x01\xd1\xc7\x6d\x47\x49\x7b\x4b\x0c\xa9\x59\xd2\x44\xe6\xea"
+  "\x69\x87\xf9\xa4\x09\x9f\x61\x14\x4d\xeb\x8e\xe2\x73\xe2\x03\x9f"
+  "\x49\x21\xc2\x79\xf1\xd6\x61\xb8\xa6\x34\x31\x85\x68\x8b\x9a\xf8"
+  "\x3a\xd2\xf6\xf3\x84\x1c\x49\x21\x84\xfb\xfd\xd6\x0d\xfd\x36\xf4"
+  "\xc1\x1a\x52\x2c\xf8\xfd\xa4\xec\xf7\x23\x9e\x6b\x48\x42\x37\x9e"
+  "\x67\xec\xc6\xda\xe1\x75\x79\x9e\xf1\x42\xd7\xe7\x19\x7b\xb5\x76"
+  "\x28\x06\xfa\xfd\xfe\x09\x5b\x67\x96\xc6\x01\x9b\x92\x59\xbb\x67"
+  "\x7e\xed\x00\xee\x37\xa7\x54\xb0\xfb\xa3\xb1\x9d\x63\x9b\x47\x7c"
+  "\xa4\x43\x79\x11\x23\x88\x87\x39\x7b\x3b\x3a\x16\xdb\x88\xe0\x0a"
+  "\x59\x58\x8e\x98\x70\xad\x0e\x0d\xd8\x01\x65\x32\x2f\xa9\x07\xbf"
+  "\x5f\x24\xe6\x06\xc9\xe7\x1b\xeb\xc1\x97\x83\x02\xe8\x6a\xfd\xc0"
+  "\x09\x36\xa2\x4d\xff\x92\x68\x9f\xc1\x67\x8e\xa1\x1f\xd8\x05\x63"
+  "\x82\x92\xe7\x49\x38\xf4\x07\xc6\x0e\x89\x1b\x5c\xf2\xba\x12\xf6"
+  "\x11\x80\x89\x57\x56\x01\x26\x92\x01\x13\x8b\x11\x13\x83\x76\xf6"
+  "\x5b\xeb\x63\x7d\xb9\x07\x98\x60\xeb\xcb\xcb\x00\x13\x0d\x6e\x4c"
+  "\x74\xae\x2b\xfb\xe9\x13\x4c\x0b\xaf\xe1\xde\x42\x1f\x7c\x70\xcd"
+  "\xeb\xca\x17\xa4\x75\x65\x05\x1f\xf4\x0e\x1b\x41\xfe\xdf\x89\xe9"
+  "\x1f\x1b\xd6\xab\x63\xa3\x55\xc2\xc6\xa2\xf0\xab\x63\x43\x13\xe6"
+  "\x03\x1b\xfb\xdc\xd8\x58\xa4\x75\x63\x43\x5a\x67\xca\x5f\xa4\xef"
+  "\x8a\x0d\xcd\x9b\x37\x06\x1b\x5e\xf7\xfd\xdc\xb4\xd8\xd0\x6e\xed"
+  "\x39\x36\x16\x75\x83\x37\x2e\xc8\xd8\xe8\x06\x6f\x0c\x8e\xea\x8a"
+  "\x8d\x33\xa2\x02\x1b\x0a\xde\x90\xd6\x9d\xf2\x17\xf9\xe0\x8d\xc1"
+  "\x47\x6e\x0c\x36\xbc\xee\xe1\xb9\x69\xb1\x31\xa4\xb4\x17\xd8\xe8"
+  "\x06\x6f\x9c\x96\xb0\x11\xdb\x0d\xde\xb8\x2d\xd6\x07\x36\x62\xdd"
+  "\xd8\x88\x55\xf0\x86\xb4\x0e\x85\x63\xce\x2e\xd8\xb8\xed\xcc\x8d"
+  "\xc1\x86\xd7\xfd\x38\x37\x2d\x36\x82\x2b\x7b\x8e\x8d\xd8\x6e\xf0"
+  "\xc6\x87\x32\x36\xba\xc1\x1b\x21\x29\x3e\xb0\x51\xae\xc0\x86\x82"
+  "\x37\xa4\x75\xa9\xfc\x58\x1f\xbc\x11\xe2\xbc\x31\xd8\xf0\xba\xb7"
+  "\xe6\xa6\xc5\xc6\xd0\xba\x5e\x60\xa3\x1b\xbc\x91\x2e\x61\x23\xae"
+  "\x1b\xbc\xf1\x83\xbc\xae\xd8\xa8\x0f\x74\x63\x23\x4e\xc1\x1b\xd2"
+  "\x3a\x55\x7e\x9c\x0f\xde\x08\xbd\xfd\xc6\x60\xc3\xeb\x3e\x99\x9b"
+  "\x16\x1b\xa1\x7e\xdf\xa7\xaf\xc4\x46\xaa\xcd\xc7\x3c\xa5\x81\x63"
+  "\xa3\x03\x64\x94\xb8\x50\xce\x4d\xa0\x7c\xe2\x5c\x98\xb3\x20\x26"
+  "\xe2\x52\x89\xc0\x70\x61\x53\xe2\xe2\xf6\x7d\x88\x8b\xf1\xf1\x80"
+  "\x8b\xaf\x24\x5c\xc8\xf3\x12\xf6\xee\x15\x3e\x37\x91\xd7\xac\xe4"
+  "\xf9\xc9\xcb\x38\x67\x8d\x97\x31\x71\xc7\xf8\x7e\x2b\xfa\x00\x13"
+  "\x1e\xf7\x3d\x28\x30\xf1\xb4\x9f\xf9\xc9\x82\xde\x63\xe2\x97\x30"
+  "\x77\xed\xe8\xeb\x67\x9f\x64\x4c\x7c\x79\xad\x98\xb8\xf3\x8a\xf7"
+  "\x3f\xf8\xc6\x84\x34\xce\xf0\x8b\x09\xf7\xd8\x82\x63\xe2\xf4\x15"
+  "\x30\x71\xa7\xa9\x2b\x26\xa4\x71\x05\x7b\x0f\x01\x1f\x5b\xc8\x6b"
+  "\x58\xf2\xf8\xc2\x13\x13\xc3\x1e\xb9\x31\x98\xf0\x1a\x5f\xdc\xb4"
+  "\x98\xb8\x6b\x98\x3f\x4c\x18\x05\x57\x19\x84\x0a\x08\x26\x08\xd5"
+  "\x4e\x81\x3c\xb6\x5b\x70\xb1\x6f\xcf\x4b\x6d\xc6\xfb\x7c\x7f\xfa"
+  "\xd2\xb8\x04\x94\xa1\x5b\x44\x76\x7f\x85\xac\xc3\x39\x90\xe0\xfb"
+  "\x10\x4d\x1a\xd5\x12\xf4\x09\xca\x0e\x90\x75\x69\xb6\x90\x28\x28"
+  "\x3f\x97\x13\x48\x06\x97\x8b\xea\x8f\x72\x34\xab\xd6\x0a\x71\x01"
+  "\x92\x4e\x66\xab\x53\x10\x50\x97\x77\xde\xb7\x48\x32\x3a\x67\x26"
+  "\xd1\x29\xf3\x06\x5d\x98\xa7\x2c\x37\x10\xe5\x9c\xfd\x55\x19\x4e"
+  "\x95\x18\xa6\x94\xa3\x33\x88\x52\xee\x56\x49\x9f\xde\xa3\x1c\x23"
+  "\x09\xd1\xa8\x74\xbc\x2c\x29\x82\x5c\x96\x40\xa6\x33\xc8\x1c\x0d"
+  "\x3a\xc7\x79\xe8\xec\x4f\xc8\x20\x90\x47\xbd\x83\xe2\x99\xdd\x28"
+  "\x3f\x88\xf6\xff\x2a\x86\xe9\x57\x89\x06\x97\x40\x0c\xbc\x5c\x44"
+  "\xdc\xdd\x69\xb3\x8e\x18\x3d\xf3\x08\x92\xeb\x4b\x29\x87\x32\x54"
+  "\xe8\x94\xd1\xf0\xb2\x35\xc4\x82\x1d\x11\x4a\x3b\xb8\x1c\x99\x24"
+  "\xc9\x69\xa1\x5c\x91\x9d\xbe\xcc\x1b\x19\x2f\xcb\x01\x7e\x6f\x07"
+  "\x5f\x98\xf0\x2d\x75\x52\x3d\x0c\xa6\x59\x9f\x6d\x95\xea\x22\x4a"
+  "\xa9\x73\x90\x4a\x65\xd9\x2d\xd5\x97\x2b\xeb\xb3\x08\x90\x1d\xe2"
+  "\xda\x22\x3e\xda\xa9\x37\x53\x4b\x64\xbf\xd2\x4c\xc7\x6d\x4c\x6f"
+  "\x23\xb4\x33\x41\xa5\x93\xea\xe1\x36\x94\x85\x34\xd1\xbc\x5c\xda"
+  "\x4e\xbf\x3a\x05\x11\xcf\x99\x14\xb2\xc1\xbc\x8e\xcf\x9c\x80\xb2"
+  "\xcd\xee\x2a\x1f\xe0\x2d\x1f\xc2\xe5\xff\x5c\x05\xf2\xf3\xba\xca"
+  "\x6b\xbd\xe5\x87\x72\xf9\xbf\x0c\x03\xf9\xf9\x5d\xe5\x1d\x43\xbc"
+  "\xe4\x7f\xc0\xe5\xeb\x92\x41\x3e\xa6\xab\xbc\xce\x5b\x3e\x94\xcb"
+  "\x37\xe8\x40\x3e\xb6\xab\x7c\x94\xb7\xfc\xed\x5c\xfe\xaf\x35\x20"
+  "\xbf\xa4\xab\x7c\x86\xb7\xfc\x1d\x5c\xfe\x54\x18\xc8\x2f\xf3\x96"
+  "\x2f\x61\xb2\x64\xa4\x24\x7b\x27\x97\x3d\x9d\x0a\xb2\xf1\x3e\xca"
+  "\xaa\x96\x74\x1b\x24\xf9\x61\x5c\xfe\xb3\x93\x20\x9f\xe0\xc3\x57"
+  "\xde\xf2\x77\x71\xf9\xcb\xe3\x40\x3e\xd1\x87\xaf\xbc\xe5\x87\x73"
+  "\xf9\xc6\xd9\x20\x9f\xec\xc3\x57\xde\xf2\x77\x73\xf9\xa6\x22\x90"
+  "\x4f\xf1\x51\xf7\x9e\xf2\x41\xcd\xcd\x20\x97\xba\x3b\x53\x6e\x3f"
+  "\x1e\xf5\xee\xad\x7b\x04\xd7\x7d\x21\x12\xd2\x64\xf8\xa8\x77\x6f"
+  "\xf9\x91\x5c\xfe\xdb\x1d\x20\xbf\xb5\xab\x3c\x51\x71\x79\x32\x59"
+  "\x92\xff\x21\x97\x6f\xc1\xba\xdc\xe6\xa3\xee\xf1\xbc\x49\x6a\xa7"
+  "\x61\x5c\xf6\x6c\x02\xc8\xee\xf0\x51\xef\x4a\xd9\x51\x4c\x76\x48"
+  "\xff\x42\x90\x35\xfa\xa8\x73\xa5\xec\x3d\x5c\x6f\xfb\x3c\x90\xcd"
+  "\xf3\x51\xdf\x4a\xd9\x7b\xb9\xac\x03\x39\xa5\xd0\x87\xbd\x23\x15"
+  "\xb2\x7a\x2e\xeb\x8a\x07\xd9\x22\x1f\x7e\x51\xca\x8e\xe6\xf6\x06"
+  "\xa0\x0f\x4b\x7d\xf8\x45\x29\x3b\x86\xcb\x12\x6c\x6b\x7b\x7c\xf8"
+  "\x44\x29\x3b\x96\x0e\x11\x32\x24\x6e\xdd\xeb\x2d\x0b\x18\x30\x01"
+  "\x0f\x55\x03\x17\x8e\xa3\xb9\xe2\x8e\x12\xce\x6b\xec\x9b\x1b\xb2"
+  "\x0c\x15\x1c\xf7\x29\xfa\x81\xf1\x34\xcb\x9e\x28\xf1\x5f\x99\xb7"
+  "\x3e\x2a\x88\x4a\xd9\x09\x34\xf7\xf6\x48\x49\xb6\xbc\xab\x6c\x80"
+  "\x52\x76\x22\xcd\x0d\xcc\x93\x64\x2b\xba\xca\x6a\x3b\x65\x69\x6e"
+  "\x50\x19\xc8\x54\x16\x4b\xbc\xaa\xb0\x73\xb2\x42\xdf\x24\x9a\xab"
+  "\xad\x91\xf4\x99\xba\xea\xd3\x29\x65\x27\xd3\xdc\x3b\xe7\x49\xb2"
+  "\x55\x5d\x65\xa3\x94\xb2\xf7\xd1\xdc\x21\x8d\x92\x6c\x75\x57\xd9"
+  "\x0c\xa5\x6c\x38\xcd\x0d\x11\x25\xd9\x1a\x6f\xd9\x62\xde\x07\x09"
+  "\x92\x9f\xa6\xd0\xdc\x1f\xe8\x24\xd9\x5a\x8f\x3e\x56\x50\xb1\x36"
+  "\x56\xcc\xe5\xee\xa7\x43\x06\x96\x4a\xfe\x3c\xe1\xd1\xb7\x66\xaa"
+  "\x86\x60\x9f\xb2\x1b\xfd\xf9\x52\xb8\x1d\x64\x1f\x90\xf4\xd5\x79"
+  "\xf7\x7d\x92\x7d\x11\x70\xee\xa4\xdc\x3f\x41\xbf\x63\xf1\x35\xee"
+  "\x49\x1c\x43\x6e\x6d\x12\xef\xd9\xc3\xfb\x46\xe9\x1b\xc4\xa2\x9e"
+  "\x1d\xbb\xf6\xcc\x9c\x37\xd7\x46\x1d\xca\xb8\x6c\x81\xd6\x4e\xb4"
+  "\x11\x11\xdf\xe9\x4d\x43\xd6\xd8\x2d\x10\x6f\x1d\x35\x4b\xd7\x9a"
+  "\x7b\x4f\x99\x45\x75\x9a\x7d\xc3\x0e\xf6\x2b\x2d\x64\x67\x1d\xee"
+  "\x67\x67\xe2\xb7\x12\xa3\x54\xce\x82\x91\x06\xfc\xb6\x62\x09\x1c"
+  "\x67\x41\x60\xdf\x31\x84\x31\x26\x7d\x89\x44\x99\xd6\x39\xc8\xd9"
+  "\x14\x22\xb0\xef\x71\x8b\xf7\xde\x42\x57\xc7\x47\x82\x2d\x19\x90"
+  "\xef\xb2\x7a\x38\x66\xb6\xe0\x77\xe0\xf2\x46\xce\x36\x25\xb5\xa3"
+  "\x4c\x9c\x35\x64\x73\x06\xfd\xf9\xa2\xaf\x13\xd3\xc8\xdd\x4d\xe2"
+  "\xbd\xac\x8f\xc1\xf7\xde\xba\x42\x46\xce\x66\xef\xbb\xbd\x10\x3f"
+  "\x9d\xbd\xeb\x56\xd4\xaf\xc5\x77\xdc\xe2\xbb\x6e\xe5\xf7\xdc\xf2"
+  "\x7c\xf4\x4b\x5a\xf0\xfb\xa2\xa5\xdb\x75\xec\x3d\xba\xe2\xbd\x07"
+  "\x58\xf9\x32\x69\x2d\x0d\x9b\x19\xe1\x6a\xdf\x9a\x81\xdf\xcf\x36"
+  "\xa5\x35\x91\x7a\xe9\x1c\xea\x97\x74\x4e\xf2\xd6\x89\xe9\xac\x23"
+  "\xb6\xeb\xa0\x5e\x22\x9c\xc6\x05\x85\x2e\xed\x82\x3c\x6a\x5c\x1a"
+  "\x6d\x4e\xb0\x10\x56\x56\x51\xff\x06\x0d\x7a\xda\xec\x32\x2e\x48"
+  "\x85\xf8\x08\xb3\xad\x9d\xc5\x83\x6e\x07\x8e\x9b\x5b\xb4\x71\x5b"
+  "\xa9\x31\x6e\x9b\xe9\x8e\x76\xd2\x20\xea\xd9\xdc\x05\xe3\x69\xce"
+  "\xd2\x68\xac\x63\x57\xce\xd2\x08\x75\x28\x11\x5b\x06\xc7\x6d\x6d"
+  "\xcd\xd5\x0f\x93\xbf\x67\x27\xe7\x85\x7a\x2d\x92\xae\x6e\xbf\xb3"
+  "\x57\xbc\x77\x0f\x7b\x67\x6f\xae\x3e\xc1\xa2\x1a\x6b\x61\xef\xec"
+  "\x95\xeb\xb2\xfb\x3a\xe6\xa1\x0e\xdf\xdf\x35\x21\x1a\x9a\x3f\x32"
+  "\x1e\xf4\xd7\xc0\xd8\x3b\x96\x63\x43\x5f\x67\x51\x0d\xdf\x23\xed"
+  "\x37\x58\x54\x23\x03\xa5\x7d\xab\x45\xf5\x79\x91\xb4\xef\x90\xdf"
+  "\x9b\xec\xfb\x3d\xce\x23\x01\x1f\x23\xe7\xbb\x76\xc5\x04\xe0\xbc"
+  "\x81\xd9\x13\x32\x32\x52\x37\x9c\xa8\xce\x8a\xa3\x33\x20\xcf\xf9"
+  "\xdc\x4f\xa3\x9f\x86\x5f\x8d\xf4\x6b\x95\x7e\x29\xca\x30\xbc\x07"
+  "\xaf\x8d\x00\x5f\x44\x71\xff\x8c\x7e\x91\xcd\x97\x10\x57\x80\x3d"
+  "\x3a\x78\x69\x14\xd3\x9b\xbf\x39\x43\x69\x03\xc8\x10\xc3\xa4\xc9"
+  "\xf7\x85\x4f\xb9\xff\x81\x88\xa9\x4b\x9f\xfd\xe9\xb2\xe7\x96\xff"
+  "\x2c\x7e\xc5\xf3\x2f\x24\xac\x5c\xb5\x3a\xf1\xc5\xa4\x35\xc9\x6b"
+  "\xd7\xad\x4f\xd9\xb0\x11\xe5\x3a\xed\xdd\xf5\xa8\xca\x26\x10\xf0"
+  "\xf7\x0c\xcc\x87\xbd\xf3\x1a\xe3\x38\xee\x46\x9f\x10\x75\xbe\xe7"
+  "\x24\xe6\x50\x98\x07\xc2\x18\xbc\x59\x1c\x33\x09\xbf\xe5\x08\x6d"
+  "\x40\x65\x2e\x7a\xdc\x84\xdf\xa4\x6e\x10\xc7\x84\x1d\xb7\x3e\x6e"
+  "\xc2\x6f\xa8\x1f\x0e\x6d\x24\x61\x23\x89\xaa\x49\x1c\xa3\xc5\xf3"
+  "\x25\xf7\x10\x82\x5f\x7b\xf1\xa5\x73\xa4\x96\x84\xbe\x3a\x94\x5a"
+  "\xf3\x86\xd2\x66\xd4\x9f\x57\x40\x1b\xad\x9b\xe2\x49\x16\x1c\x43"
+  "\xbb\xd0\x9e\x15\xc7\x7c\x75\x18\x66\x1e\xae\x4c\x32\xac\xb8\x80"
+  "\x36\x6c\x1d\x4a\x1b\x7e\x5e\x40\x9b\x4b\x86\x52\x4b\x58\x1e\x09"
+  "\x6c\xcd\x1d\x53\x68\x11\x47\x5b\x59\xdb\x86\xf3\xae\x21\xa3\x8d"
+  "\xd9\x70\x6e\xa2\x83\xa8\x4b\xe0\x18\xe2\x6c\x87\x75\xdc\xee\xfd"
+  "\x17\xed\xfd\x40\x5f\x2a\xed\x48\x50\x65\x41\x3e\xdc\x27\x63\x6f"
+  "\xa9\x82\x51\x0c\xe4\x67\x35\xdb\xeb\x89\x45\x1c\x1b\x80\xdf\x96"
+  "\x85\xfc\x34\xe6\xc2\x66\x82\xfa\xde\x4e\xb2\xf7\x5b\x73\x07\x75"
+  "\x40\xda\x46\xd7\xa6\x04\x95\x45\x1c\x53\x05\xba\x6d\xca\xf2\xe8"
+  "\x97\xaf\x4c\xd6\xad\x5a\x9b\x90\x30\x7a\x20\xd1\xb3\x5f\xa2\xfc"
+  "\x9e\x7a\x32\xbe\xb3\xfd\xd5\x02\x5a\x05\xe5\x34\x41\x79\xab\x8f"
+  "\xc1\xec\x07\xf0\x41\xa0\x4c\x46\xb0\x21\x0e\xe2\x2b\x61\xbf\x12"
+  "\x6c\xaf\x66\xdf\x6a\x16\x23\xb7\xd3\xdc\xb1\xc1\x60\x27\xf6\x97"
+  "\xf8\x2e\x73\xd2\xb2\x7e\xbe\x0a\xca\x9d\x07\x72\xd5\xba\x3b\xc8"
+  "\x28\x48\xf7\x15\xd8\xb1\x07\xf6\x51\x3e\x07\xfd\x08\xf2\x55\xbc"
+  "\x5c\x91\x1b\xf0\x18\xea\xca\xb4\x7b\x28\xdd\xd1\x9a\x3b\xd6\x84"
+  "\xdf\xae\x60\xdf\xe3\x84\x63\xa8\x97\x6a\x90\x35\xb6\xa4\xcf\x57"
+  "\xc1\x1c\x5a\x55\xe2\xd6\x69\x44\x9b\xd0\x0e\x9c\x97\x7f\x0a\xa3"
+  "\x59\x57\x47\x0c\x19\x6f\x27\xaa\x4f\x1b\x08\x29\x2a\xa0\xa5\x10"
+  "\x8a\x20\x14\x1e\x85\x73\x9f\x40\xa8\x86\xf8\x1a\xf8\x3d\x0a\xbf"
+  "\x9f\x40\x80\x79\x7d\x28\xda\xbd\x26\x95\x36\x4e\x2c\x24\x3f\x44"
+  "\xfd\x80\xad\xff\xaa\x17\x1f\xb4\xa0\xed\xf8\x6d\x1a\x3a\x64\x9c"
+  "\xe7\xf7\xdf\xc5\xf1\xd5\x04\xce\xc3\xef\x49\xfe\xab\x0c\x13\xc2"
+  "\x20\x3c\x2a\xed\xef\x00\x99\x72\x69\xbf\x14\xc2\xbe\xab\x07\x6f"
+  "\x7d\xfe\x02\x4c\xda\xbb\x2d\xdb\x9d\x10\x39\xbf\x7b\x72\x86\x5a"
+  "\x22\xde\xa7\x87\xb0\xc4\x33\xfe\xbe\x08\x1e\x17\x21\xf2\xe3\x08"
+  "\xad\xf4\x1b\x09\x01\xea\x69\x2a\xe8\x9f\x9a\xc2\xe3\xa6\x6e\x85"
+  "\xdf\x1a\x08\x75\x9e\xf9\x47\x42\xfa\xc8\x04\xf4\x67\x07\xf4\x43"
+  "\xe8\x4b\x8b\x38\x2e\x0c\x7d\x94\xcd\xb1\xa5\xc2\xe7\xf3\x20\x4e"
+  "\x07\xd8\x2a\x72\xe3\x67\x42\x88\x27\x7e\x26\x10\x2f\xfc\x18\x91"
+  "\x8f\xa0\xbd\x24\x94\x70\xbc\x54\xb6\x6c\x5a\x06\xc7\x13\x44\xd0"
+  "\x53\x89\xeb\x45\xa0\x83\xcd\x0f\xb2\x9b\x60\x1e\x1e\x4f\x44\xe4"
+  "\x97\x66\x71\xc2\x53\x88\x59\xcc\x5b\xca\x97\xdb\x02\xf6\x41\x5c"
+  "\x29\xda\xb7\x1a\xf4\xc2\xf1\x1e\x90\x2b\x35\x93\x8b\xb2\x6d\x2c"
+  "\xcd\xcb\xcf\x03\x1e\x25\x7b\x51\x27\xa6\xa3\xee\x72\xe9\x30\x0d"
+  "\xcf\x7b\xe2\x2d\x10\x8f\xf3\x7b\x7c\xf6\x4e\x6d\x76\x58\x08\x62"
+  "\x12\x7f\xcd\x0e\x03\xb4\xa5\x68\xe2\xc2\xf7\xcd\x87\x12\x03\xb4"
+  "\xb7\x5b\xea\xc5\x09\xcd\x13\x52\x89\x01\xf5\x21\x87\x43\x39\xca"
+  "\x4a\xb0\x2d\x72\x5d\x2a\x2c\x07\xea\x3f\x0a\x33\x2a\xfc\x2d\x46"
+  "\x7b\xe0\xbc\x22\xdf\x3c\x9c\xb7\x67\x6f\xe4\x65\x85\xbc\xf6\x40"
+  "\xfa\x32\x2c\x3b\xd6\x27\x9c\xaf\x00\x3d\xd1\x78\x0e\xbf\x4f\x29"
+  "\x95\x67\x0f\x3e\xf3\x88\xf5\x81\xf2\x66\x98\xc1\xb0\x6f\x69\x88"
+  "\x63\xd9\x37\xc2\x41\x7f\x19\xfa\x83\x42\x1e\xa8\x23\xdd\x41\x1d"
+  "\x14\xf8\xe8\xd7\x1b\xed\x30\xfe\x31\x7c\xe4\xe9\x9f\x89\xa5\x4a"
+  "\xff\x40\xba\x32\x48\x5f\x85\x63\x02\xe4\x13\xc8\x53\x83\xe3\x1d"
+  "\x88\x33\xba\x72\x41\xc7\x3a\x3b\x5b\xe3\x02\x3d\x07\xc0\x16\x23"
+  "\xea\x01\x7b\xaa\x24\x5d\xcd\xf8\xde\x7d\xa5\xaf\x25\x7d\x7b\xd0"
+  "\xe7\xac\x3d\x6f\x64\x65\x02\xee\x32\x6c\x29\xe6\xe7\x2a\x40\xa6"
+  "\x82\x76\x44\x13\xba\x29\x86\x7f\xb3\x9a\x9f\x2b\x4f\x6f\x63\xfe"
+  "\xad\xe2\xbc\x66\x78\x7d\xcd\x66\xda\xe8\xb6\xdb\x10\x23\x7f\x97"
+  "\x4a\xb2\xbb\x1c\xf3\xa3\xeb\x63\x59\x3f\x8a\x79\x60\x7a\x49\x5f"
+  "\x38\xea\x93\xeb\x6a\x02\xd8\xc1\xeb\x6b\x62\x3c\xc4\xef\x41\x2c"
+  "\xb2\x7a\x03\x1e\x6d\x49\x47\x2c\x1a\x62\x21\x7d\x65\x16\x1e\xaf"
+  "\xc7\xe3\x89\x56\xc6\xb1\x9d\xe7\x27\x22\xc6\x2a\x71\x5d\x24\xfb"
+  "\x05\xc0\x92\x8b\x90\x1f\x06\x13\x83\x2d\x93\x95\x6d\x9f\x6d\xd3"
+  "\xa3\xaa\xc3\x0e\x42\xd0\x4e\xa8\xa3\x8a\xd6\xdc\x49\x22\x70\x3f"
+  "\xfb\x66\x35\xf0\x75\x39\xfd\x75\x0c\x41\x9b\x81\xcf\x24\xfb\x26"
+  "\xad\x95\x7c\x5f\x8e\x65\xc4\xfa\x9c\xc0\xb9\x0f\xce\xdd\x77\x3b"
+  "\xda\xee\x2e\xf7\xa4\x79\xca\x3a\x66\xe5\x06\x3f\xa0\xbf\xd0\x2f"
+  "\x0a\x9d\x88\x7d\x23\xe8\xda\xc7\x8f\x39\x36\xb0\xae\x8d\x43\x69"
+  "\x0d\xca\xbb\x65\x27\x6f\xc7\x73\x69\x90\xf7\xc4\x44\x5c\x03\x82"
+  "\xfe\xd9\xd1\x6a\x02\xbd\xfb\x4c\x1b\x1d\x04\x74\x54\x60\x9d\x82"
+  "\xdc\x29\xc4\x23\x1c\xd7\x48\x79\x9c\x84\xfe\x7c\x1c\x84\x48\x77"
+  "\xfb\x9f\x7c\xcc\x13\x5f\x93\xbd\xdb\x3f\xfa\xdb\xe8\x4a\x8f\x26"
+  "\x0c\x0f\x49\x44\x77\x5e\x9c\xbc\x42\xea\x3b\x24\x5f\x4f\x7e\xff"
+  "\x30\xb4\x17\x85\x8e\x47\xbd\x7c\x5d\xc1\xf0\xb8\x7e\xb6\x0a\xcb"
+  "\x0c\x69\x2b\x24\x3d\xac\xcc\x0c\x4f\x99\x0c\x03\x35\x74\x3d\x94"
+  "\xb3\x13\x07\x93\x4a\x25\x3f\xd7\x78\xd5\x89\x64\xfb\x78\xfc\x06"
+  "\xf5\x74\xe4\x24\x18\x7b\x4f\x6f\xed\x70\xf3\x12\xfa\xde\xc5\x7c"
+  "\x3f\x39\xba\x84\xf7\xb7\x12\x6f\x4d\xe6\xe7\x87\x7a\x60\x18\x6d"
+  "\xd9\xcc\xf0\x8b\xb6\xa4\xc7\xa2\x2d\x15\xcc\x8e\x74\x1d\x81\x73"
+  "\x36\xcc\x1f\xd2\x66\x48\xed\x55\xd2\x35\x69\x3e\xea\xfa\x39\x70"
+  "\x15\xda\x64\x11\xc7\x5b\x18\xff\xfd\x98\xe1\xe0\x29\xc9\xf6\x6a"
+  "\x7b\x26\xa6\x9d\x10\xdd\x26\xb0\xb4\xd5\x20\x57\x69\xe7\xdf\x89"
+  "\x1b\x08\xe9\xf7\xb2\x7b\x37\xc5\x07\xca\x91\xa3\xf1\x99\x64\xd8"
+  "\xdf\xad\x5b\x00\x58\x6d\x22\x22\xe8\x0b\x40\x8c\xca\xb8\x68\x16"
+  "\x1f\xd8\x89\xdf\x90\x81\xba\xde\x07\x63\xa4\xbd\x58\xdf\x88\x65"
+  "\x18\x23\x85\xb7\xe6\xde\x57\x29\xe3\x16\xf2\x29\xc2\xba\xe7\xfe"
+  "\x09\x57\x01\x8e\x2b\xdc\xd8\x0a\x57\x49\xf5\xb8\x17\xea\x31\x00"
+  "\xf2\xdb\x22\x95\x6b\x2f\xc8\xc3\x58\xec\x81\x17\x25\xdb\x0b\x25"
+  "\xf9\xbb\x64\x3f\x48\x6d\xb5\x26\x0b\xf9\x97\xf9\x20\xbc\x5c\x4a"
+  "\xbb\x47\xca\xeb\x5d\x59\x16\xc7\x88\xec\x9b\xcf\x10\x87\x3c\x38"
+  "\x11\x7c\xcf\xb8\x6f\x63\x3b\x93\x93\xb8\xb1\x8a\xe7\xf1\x40\x1c"
+  "\xc3\x21\x8c\x7b\xdc\x38\x0a\xdf\xe1\xc5\x4f\xc8\xc5\xc6\xe3\x5b"
+  "\xf9\x37\xf5\x10\x4b\xc8\xa9\x38\x57\x02\x7d\xcb\xa4\xf6\x23\xdb"
+  "\xdc\xe6\x89\x95\x07\x9e\x00\xac\x8c\x57\xe8\x6e\xf4\xd5\xcf\x95"
+  "\x70\x0e\x2c\xe2\x69\xa6\x4c\x95\xca\xb6\x8f\x97\x4d\x3a\xc6\x7a"
+  "\x4b\xc3\x7a\xbb\xdf\xa9\xa8\x47\xa8\xb7\xfb\x57\x48\xf2\x15\xc8"
+  "\xe5\xee\xf6\x3a\xe5\x0d\xb9\x2d\x77\xe5\x8b\xfb\x9f\xc6\xf6\xe0"
+  "\xb6\x6b\x4a\x86\x17\x5f\x54\xf8\xe6\x8b\x29\xf3\xa4\xf2\x96\x7a"
+  "\xb5\x8d\x3d\xd2\x78\x77\xa5\xec\x87\xe3\x36\xe9\xdb\x86\x10\x87"
+  "\xfc\x89\x79\x2b\xfb\xa0\x62\x5e\xaf\x52\x5b\xbe\xff\xb1\xae\x7e"
+  "\xb8\x3f\x58\xd9\x9e\xd1\xd7\xc8\x09\xa8\x03\x7d\xca\xc6\x95\x10"
+  "\xc7\xfd\x3a\xa5\x19\xb9\x41\xc9\xd1\x20\x9b\xe7\xa2\xd8\x5e\xee"
+  "\x0f\xf5\x6c\x8b\x53\xb6\x4a\x6d\x51\xce\xfb\x6b\xf0\x91\x41\x91"
+  "\xef\x0e\xaf\x7c\xd1\x37\x55\xec\x1b\x34\xac\x8c\xf7\x7f\x21\xf7"
+  "\x69\x28\x0f\x69\x53\x20\x8d\xc9\xab\x7f\x34\xa2\x7d\x90\x57\x04"
+  "\xe3\xac\x02\xc6\x15\x29\xad\xdc\x9e\xaa\x12\xa9\x9f\x80\x38\x83"
+  "\x14\x67\x94\xfa\x12\x19\x37\x53\x3c\x6d\x7a\x40\xe7\x7b\x7c\x34"
+  "\x25\x42\x1e\x1f\x31\x5d\x8c\x8b\x1e\x08\x93\xca\x87\x71\xe3\x79"
+  "\x5c\x38\xce\x69\x58\x5f\x05\xf1\x79\x94\xf5\x57\xe1\x46\xa9\xbf"
+  "\xc2\xf6\x25\xc0\x31\xf6\x4b\x35\x78\x0c\x3a\x52\x50\xbf\x39\xa3"
+  "\x1d\xe7\x10\x30\x07\xba\xaf\x08\xf9\x00\xf9\x02\xef\x39\x66\xbf"
+  "\x73\xd8\xef\x11\xe4\x1d\x1c\x87\xe0\x79\x90\xdb\x81\x5c\x04\xf1"
+  "\x5f\xe2\xfb\x06\xe9\x37\x01\xa0\xf7\x81\x4a\x29\xed\x39\x36\x56"
+  "\xf8\x26\x5a\x2d\xc7\xc9\xe9\x80\xb7\x76\x63\x3a\x4c\x2f\xf3\x17"
+  "\x72\x97\x03\xb9\x89\xe5\x17\x31\x49\xc2\x38\xff\xce\xa3\x34\x2e"
+  "\xea\x10\x14\xb2\xf8\x8d\x36\xc6\x69\x11\xa9\x9c\xcf\x22\x56\x62"
+  "\x5a\xe6\x3f\xe0\xca\xb4\x36\x7a\xa6\x24\x89\x88\xc5\x17\x91\x17"
+  "\xc7\x26\x70\x3b\x23\xaa\x79\x39\x22\x72\x58\x39\x38\xa7\x1a\xb9"
+  "\x2d\x63\x13\x8a\xdb\xd9\xb9\xb7\xb0\x2c\x78\x2e\x5b\x71\x0e\xbf"
+  "\xb9\x08\xe7\x3e\x61\x76\x79\xa5\x73\x75\xc4\x77\x91\x2f\x69\x67"
+  "\xf3\xbe\x80\xe2\x02\x99\x7b\xa7\x46\x73\x3b\xa7\xf6\x93\x79\x17"
+  "\xea\x25\x0f\xb9\x97\x9d\x5b\x2e\xc9\xcc\x91\x7e\x19\xbf\x4f\x9d"
+  "\xc2\xeb\x35\x54\x90\xea\xbb\x88\x97\x63\xea\x13\x6c\x9e\xfd\x4d"
+  "\x0c\xd4\xed\xd4\x71\x72\xdd\x2a\xf7\xb1\xfd\x40\xfe\x5a\x3c\x66"
+  "\xb8\x4f\x65\x73\xd8\x22\x94\x41\x9b\x78\x1f\x11\x11\xe6\x3d\xa6"
+  "\x3e\x2b\x3e\xf8\x11\xf6\x4b\x7c\xac\xfa\xe0\xeb\xd2\xfa\x14\x31"
+  "\x25\xfd\x0a\xfa\x85\xa9\xcd\x32\xc7\xd0\xd6\x68\x82\xdf\x6e\x02"
+  "\x5b\xce\x61\x1c\x7e\x77\x4b\x29\x83\xfc\xb4\xbf\xdd\x22\xe9\x9c"
+  "\x5a\x2d\xf3\x06\x72\xc9\x71\x5b\xbd\x34\xa6\x9b\x96\x52\x2c\x71"
+  "\xc9\x79\x71\xda\x06\xcf\x71\xd8\xb4\x0d\x9e\x9c\xf1\xe0\x4e\x6f"
+  "\xce\x80\x71\xf3\xd6\xd6\xdc\x69\xb3\x3d\xc6\x01\x10\x77\x65\xee"
+  "\x98\xa6\xc3\x36\x8a\xdf\x7c\x65\xfc\xc4\xd6\xdc\xa6\x9d\x91\x6d"
+  "\x46\xde\x6c\xd9\x24\xaf\x5f\x3c\xb8\x19\xc7\x6a\x5e\xf9\x55\x7a"
+  "\x70\x27\xe6\x27\xeb\x13\x09\x7e\x37\x14\xea\x01\xd7\x5c\xa6\xed"
+  "\x90\x78\xbe\xd4\x83\x2b\xa5\x3e\x0c\x79\xd2\xb3\xaf\x1a\xbb\xd2"
+  "\xb3\xaf\x7a\x70\x45\x57\x8e\x7c\x30\xa2\xfb\x7d\xd5\x83\x38\x2f"
+  "\xe8\xe4\x48\x4f\x2e\x78\x30\xb2\xd8\x63\x2c\x3b\xad\x4a\x1e\xcb"
+  "\xba\x79\x74\xda\x7c\xe4\x28\xc8\xbf\x42\xca\xbb\xdc\x22\x8e\xae"
+  "\x90\xf3\x06\x1c\x35\x1f\xd7\x01\x36\x73\xc7\xea\x60\xbf\x50\x1a"
+  "\x03\xb2\xb6\xd9\x8e\xdf\xf8\x13\x23\x2c\x80\xbf\x81\x88\x33\xd3"
+  "\xaa\x8b\xa4\xc1\xdd\x57\x54\xb5\xac\x96\xeb\x37\xf2\x31\xe5\xb8"
+  "\x70\x77\x01\xdd\xd6\x9a\x1b\x39\x4c\x59\xc6\x9d\x10\x97\x2d\xad"
+  "\x21\xb0\xba\x65\xba\x1e\xb4\x96\x14\x78\x96\x8d\x97\x23\x32\x0c"
+  "\xcb\x81\x73\x22\xc8\xbf\x01\xc7\x3d\xf8\xdd\x67\x68\x37\xf1\x25"
+  "\x9d\x98\x1f\x5f\xd9\x96\xa9\x1c\x5f\x8d\xad\x42\xae\x94\xe6\x9e"
+  "\xd5\x30\xde\x31\x2a\xd7\x62\x9e\xfc\xd1\x3c\x5d\x62\xd2\x8a\x55"
+  "\xc9\xcb\x27\xeb\x56\xac\x5a\x91\xbc\x62\x69\xc2\x8a\x8d\x4b\x93"
+  "\x57\xac\x5e\x35\x6e\xe5\xd2\x9f\xad\xf8\xa9\x6e\xfd\xd2\x35\x3a"
+  "\x43\xca\xa8\x94\x81\xc4\x2d\x3a\x4d\xb7\x74\xcd\x9a\xb5\x2b\x9f"
+  "\x5b\xa6\x5b\xb5\xe2\xa7\xe3\x93\x9e\x5b\xf3\x5c\xb2\x6e\x69\xd2"
+  "\xea\xb5\xab\x96\xe9\x46\x2d\x9b\x30\xca\x70\xff\xb2\x81\xca\x35"
+  "\xb4\x91\x5a\xd2\xec\xba\xdc\xd8\x98\x7d\x99\x04\x68\x54\x89\x49"
+  "\x9a\x94\x15\xab\xf8\xba\xdd\x43\x3b\x27\xe6\x91\x44\x38\x1f\x58"
+  "\x92\x8b\x75\x1d\x59\x0a\xbf\x22\xca\x41\x39\x75\xb0\x1f\x00\xb6"
+  "\x0f\x6b\xcd\x7d\x68\x9e\x45\x7c\x24\x02\xeb\x0c\xea\x42\x07\x65"
+  "\x1b\x46\x2f\x57\x37\xc2\x98\x2d\x11\xef\x35\x28\xb9\x4c\x82\x8d"
+  "\xeb\x88\x08\x21\x10\x82\x56\xd0\xe2\x5a\xd7\x43\x5b\x2d\xe2\xf4"
+  "\x52\xbe\x2e\x3a\x3d\xcc\x3a\x78\xf1\x09\x6a\x5c\x7c\x82\xfb\x65"
+  "\xfa\x08\x79\x3d\x7c\xee\x2f\xc8\x5c\xc4\x67\xbd\x38\x5d\xc7\x7c"
+  "\x05\x58\xc6\xf5\xe0\x96\x0f\x66\x44\xc1\x78\xf0\x24\xae\xe9\xc2"
+  "\xb9\x11\x36\x81\x04\x82\x5d\xe2\xe1\x54\x03\x79\x15\xf2\x5a\x13"
+  "\x4a\x29\xe4\xd1\x28\xaf\xa7\x41\x19\xb4\x50\x96\x3a\xa9\x1c\x9f"
+  "\xb2\x72\x14\xd0\xb0\xbc\x21\x60\x5f\x2e\xda\x33\x3d\x58\x2e\x03"
+  "\xd8\x5d\x67\x11\x1f\x4a\x01\x3b\xb5\x68\x97\xaf\xb5\x3e\x5c\xef"
+  "\x02\x3b\xe3\x5c\xeb\xa0\xde\x86\xf3\xef\xc6\x66\x17\xf3\xf6\x07"
+  "\xe5\xc9\x2b\x81\xfd\xac\x8b\x24\x70\x67\x12\x09\xa6\x99\x77\xd3"
+  "\x63\x36\x07\x31\xc7\xd7\x11\xcd\x06\x6a\xa5\x07\x1b\x1b\xa5\x32"
+  "\x6d\x43\x6e\xf8\xdd\xf3\x75\x22\x96\x09\xfa\x8a\xc0\x92\x8b\x7e"
+  "\xd7\x16\xc5\x57\x87\x52\x1b\xdd\xa5\x1c\x73\x4d\xff\x16\xeb\x04"
+  "\xc7\x5b\x2d\xd0\x4f\x41\x19\xc0\xee\xe9\x06\x69\x6c\x6c\xa3\x1d"
+  "\xb1\x8a\xb1\xd4\x74\xc4\x99\xcd\x8f\xee\x00\x59\x37\x15\xd8\xf7"
+  "\x96\x43\xb9\xff\x1f\x8e\x83\x34\x56\xb7\xfe\x87\x23\xbc\xf5\xa3"
+  "\x4e\xd8\xb7\xca\xf9\xf0\x79\xf8\xc3\x38\x26\xb0\x02\x96\xad\x7e"
+  "\xf2\x0b\xcb\x2d\xa0\x27\xcc\x10\x9f\xdd\x46\x70\xae\x72\xa2\xa4"
+  "\x80\xe9\x87\xbe\x3f\x92\xad\xbd\xff\x7c\x28\x21\x5b\x41\xa6\x25"
+  "\x77\xba\x01\xd7\x77\xe1\x1c\xb4\xff\xb1\x7a\xef\x75\x6b\x09\xcf"
+  "\xd3\xbc\xf0\x1c\x95\x8b\x63\xc2\x3c\xd0\x0f\x18\xca\xbe\x04\xfd"
+  "\x30\x1c\x4f\xc8\x23\x7a\xcc\x07\xf6\x6b\x71\x3d\xa4\x35\x37\x2a"
+  "\x40\xce\x8f\x02\xfe\xb3\x5c\x7c\x0d\x46\xc2\xd6\x38\x73\x4a\x23"
+  "\xbe\x37\x8c\x1e\x06\x7e\x47\x1b\x11\x63\x90\x26\x52\xc6\x14\x60"
+  "\xfd\x04\xc3\x55\x30\xd1\xd3\xdc\x87\x4d\x25\x43\x40\x0e\x70\x55"
+  "\x0c\x78\x42\x5c\x81\x6c\xbc\x8c\x29\xc0\x5a\x2d\xca\x81\x0d\x03"
+  "\xcb\x36\x46\x89\xc8\x91\x0d\x62\xd4\x29\xc4\x18\xfd\xef\x59\x75"
+  "\xf4\x07\x8b\xea\xb8\x9f\xa2\x4e\x99\xed\xdc\x07\xee\x7a\x8f\x2a"
+  "\x53\xd4\x7b\x2d\xe0\x78\x20\xd6\x33\x5f\xab\x8e\x3a\x05\xb6\xd5"
+  "\xb2\xb1\xf8\x66\xf0\x01\xeb\xab\xa2\x8a\x30\xbd\x54\x87\x35\xee"
+  "\x3a\x8c\xb2\xfb\xaa\x43\xaf\xba\x13\x31\xd0\xdc\x47\x44\x6c\x2b"
+  "\xad\xb9\x8f\x8c\xb3\x88\x0f\xd7\xf8\xbb\x5e\x00\x79\x88\x62\x1e"
+  "\x09\xc0\x3c\xaa\x82\x99\x7c\xac\xaf\x3c\xbc\x71\x5c\x05\xb3\x5e"
+  "\x5c\x0b\xc7\x74\x61\xc1\x58\xaf\x8f\xe4\xf9\xf4\xef\x4f\x3d\x6c"
+  "\x63\x01\x6c\x2b\x7d\x75\x08\x91\xed\xab\xb9\x92\x7d\x61\x3a\xde"
+  "\x2f\x9a\x46\x22\x9e\x67\xf4\x33\x17\x12\x82\x71\xfc\xf8\x11\x5b"
+  "\x0b\xf4\x35\xde\xeb\xf9\xfe\xaf\x2f\xcc\x78\xcc\xf3\xfa\xc2\x8c"
+  "\x70\x7f\xd7\x17\xbc\xf2\xdd\x82\xf9\xba\x4a\xe6\xab\xdc\x79\xcf"
+  "\x48\x70\xf9\xc8\x5b\x4e\x3f\xa1\x54\x39\x7f\x99\xf1\x19\xda\x70"
+  "\x1c\xfa\x25\x7a\xe7\x7c\x15\x05\x3d\x55\xac\xcf\x9e\x51\xcb\xc7"
+  "\x2b\x38\x0e\x9a\x51\x86\x32\xde\xe5\xe8\xdc\x02\x82\x71\x8d\x8d"
+  "\xb4\xb1\x83\x7e\x3f\x26\xf8\xe6\x2a\x32\xbc\x53\x46\xf0\x10\x26"
+  "\xd4\xc7\x41\x20\x21\x77\x33\x79\x0a\x1b\x8f\x92\x8e\xad\xec\x40"
+  "\xec\x94\xef\x3c\x7f\x0d\xdb\x2d\xdc\x5e\xa6\xcf\x4e\x54\x7c\x4f"
+  "\x17\xaa\x90\x78\xf4\x0a\xa9\x29\x91\x93\xf8\xda\x70\xe6\x9f\x31"
+  "\xbf\x1f\xe8\x8b\x60\xc2\x94\x3a\x24\xfd\xf2\x31\x55\x1e\x63\x8c"
+  "\xe7\x31\x6c\xea\x58\x45\x06\x77\xab\x97\xb1\x5b\xc5\x7e\x98\xd0"
+  "\x19\x25\x94\x6a\x95\x59\x6a\x49\x46\x3f\xb6\xa3\xc1\x3f\x76\xd0"
+  "\xa7\x87\xf3\xba\x98\x4e\x81\xdb\x6c\x5b\x14\xe2\x9f\x72\xf3\x47"
+  "\xec\xbd\x42\x19\x7b\xba\x0d\x57\xec\xdf\xcd\x7f\x46\xc4\xf7\xa1"
+  "\xfe\x2b\x6f\xba\xda\x5b\xe4\x5d\x37\x3c\x46\x34\xfb\x12\x75\xd7"
+  "\xff\xc8\xd9\x72\x94\x12\xa1\xee\xf3\xa3\xaa\x3d\x8f\xef\x2d\xf4"
+  "\x3c\x1e\xdd\xd8\x17\xa6\x9b\xf0\x4f\xba\x65\x30\xf8\xac\xbc\x33"
+  "\x52\xe3\xd5\x64\x34\x46\xaf\x26\xe4\xde\x24\x6b\xd4\x84\x8c\x89"
+  "\x54\x44\x8b\xbe\xa5\xaf\xcf\x76\xc7\x16\xa9\x41\xdc\x6d\xd5\x76"
+  "\x39\xf9\xb0\x57\x1c\x1e\xf7\xd7\x49\x71\x93\x3e\xea\x22\xcf\xe2"
+  "\x74\x8a\x63\x55\x14\xfc\x29\x05\xfc\xdb\xbb\xca\x7e\xbf\x7d\xbf"
+  "\x75\x63\x53\x61\xfb\xf8\x7e\xbb\x4e\x1b\xe5\xbd\x38\x30\x11\xfb"
+  "\xc1\x7f\xb4\x93\x28\xa9\x74\x82\x4a\x11\x54\xda\xe9\x93\x7e\xfc"
+  "\xfb\xed\xfb\xed\xfb\xed\xfb\xed\xfb\xed\xfb\xed\xfb\xed\x26\xd8"
+  "\x54\xca\x89\x35\xde\x4b\x3b\x40\xfa\x55\xce\x7f\x54\x52\x50\xc6"
+  "\x09\xd7\x92\x8e\x4a\x1b\xc9\x88\x32\xe9\x4a\x97\x58\xb4\xc6\x79"
+  "\xb5\x86\xb2\x44\x6b\xc0\xb6\xe8\x6a\xfd\xde\xf8\xc6\xd0\xc2\x98"
+  "\xba\x88\x8a\x14\xbb\xb8\xf5\xd1\xaa\xb0\x3d\xcb\x1a\x82\xf3\xe6"
+  "\x9f\x08\x2f\x4f\xb6\x05\xee\x98\x5d\x33\x6e\x5f\x42\xf3\xb0\xa2"
+  "\xd8\x93\x91\x95\xa9\x0e\x21\x73\xc6\xc7\x23\x7f\xf5\x6c\xfd\x90"
+  "\xdc\xff\xf8\x7c\xf2\x3b\x49\x17\x07\xbe\x3c\xf3\xe8\x98\xff\x79"
+  "\xbe\xe9\x8e\x5f\x2e\xfc\xeb\xb4\xdf\x6f\x6c\xef\xff\xd2\x8f\xff"
+  "\x78\xcf\x6f\x96\x9f\x1d\x5a\xb0\xe0\x2f\xf7\x1f\x5c\x77\x39\x28"
+  "\x6b\xce\xf1\x09\x6f\xaf\x3a\x3f\xbc\x78\xf1\xdf\xa7\x7f\x90\xe6"
+  "\x52\x6d\x79\xe4\xa3\x11\xaf\x2f\x3d\x33\x38\xe7\x27\x9f\x4d\x3a"
+  "\xf0\xe2\xb7\xb7\x6c\x7f\xe2\x93\xd1\x6f\xae\xf8\xfa\xf6\xd7\x9e"
+  "\xfe\x72\xea\xa1\x0d\x6d\xfd\x7e\xf1\xd8\x91\x51\x6f\x3c\xf7\x55"
+  "\x48\xfe\x53\x5f\x4c\x79\x77\xed\xa5\x41\x3b\x9f\x3c\x36\xfe\xad"
+  "\x95\xe7\xee\xda\x1d\x77\xea\xa1\xf7\x37\x3b\xd5\x3f\xff\xd1\xe1"
+  "\x1f\xfe\xfa\xa7\xff\xb8\xed\xd5\xff\xfc\xf3\x7d\xbf\x5b\xd3\x72"
+  "\xeb\x2b\xb3\x3e\x1d\xfb\xdb\x17\xbe\xb9\x73\xd7\xa2\xbf\x3d\xf8"
+  "\x87\x4d\x1d\x03\xfe\xcf\xe3\x7f\xba\xf7\xff\xfe\xec\x9f\x3f\xf8"
+  "\xef\xff\xfa\xdf\x07\xde\x5b\xdf\xaa\xc9\x9e\x6b\x9e\xb8\x7f\xf5"
+  "\x85\xbb\x4b\x9e\x39\xfd\xf0\x87\xe9\xf4\x5a\xea\x8f\x88\xb9\x87"
+  "\x6f\xb4\xdf\xf8\xcf\x4b\xd5\xbd\x49\x4f\x05\x95\xe4\x77\x1e\x91"
+  "\x31\x85\xa8\x02\x48\x7f\xb1\x17\x33\x85\xde\x96\xd7\xcf\xa6\x53"
+  "\xa6\xef\xce\x86\xcf\xe5\xe1\x35\xe5\xfb\x20\xdc\xc9\x62\xdc\xb3"
+  "\xff\xe1\x3e\x53\xdc\x88\x4d\x05\x65\x55\x83\x25\xfd\x48\x7f\xa8"
+  "\x9d\x00\x72\x0b\x19\x48\x6e\x25\x81\x64\x10\x09\x22\x1a\xa2\x25"
+  "\x83\xc9\x10\x72\x1b\x09\x26\x21\x64\x28\xf9\x01\x09\x25\xb7\x93"
+  "\x3b\xc0\xfa\x61\xe4\x2e\xdf\x36\x67\x90\xa8\x50\xf8\x03\xff\xe7"
+  "\x91\x28\x76\xbc\xe4\xfb\xf8\x1b\x1a\x6f\x92\xe2\x6b\xa5\x78\xcb"
+  "\xf7\xf1\x37\x34\x5e\xf7\x2f\xfe\x1d\xf1\x2f\xfd\x55\xc1\xd0\x80"
+  "\x8f\x0e\x3c\xc6\x08\x9d\x9b\x77\xac\x4a\xda\x3a\x8f\xc9\x55\xd2"
+  "\x77\xd1\xe7\x99\xde\x7b\x8b\x82\x10\xce\x77\xd3\x09\xe1\xd7\x13"
+  "\xa8\x72\x73\x14\xa8\x3e\x16\x07\x67\xe0\xa5\x91\x00\x12\xcc\xfe"
+  "\x5e\x7d\x7b\x63\x18\x04\x3d\x04\x50\xfd\xc6\x03\x10\x7e\x04\xe1"
+  "\x49\x59\x37\x18\x95\x41\x54\x42\x05\x84\x61\x44\xa5\x9e\x0f\xa1"
+  "\x91\xa8\xfa\xc7\x13\x55\x3f\x3d\x51\x0d\x70\xaf\xe7\xab\xb4\x15"
+  "\x9d\x56\xaa\x82\xa4\x78\x1d\xec\xdf\x16\xa5\xc8\xac\xa7\xfd\x56"
+  "\xc5\x63\xf3\xa3\x75\x93\x26\x84\x4f\x08\x8f\x78\x56\x37\x7e\xde"
+  "\x78\xdd\x64\x83\x61\xea\xc4\x49\x93\x27\x4e\x8a\xd0\x4d\x9a\x32"
+  "\x6d\xf2\xfd\xd3\xa6\x44\xe8\x56\x6e\x48\x5a\x31\xc9\xf0\xb3\xe7"
+  "\x74\xab\x96\xad\x58\xa3\x5b\xbe\x22\x69\xe5\xfa\xa5\x49\xcf\x75"
+  "\xa3\xe8\x3d\xd9\xa0\x28\xe4\x2e\x27\x37\x53\xe9\x21\x15\xb9\x9b"
+  "\x88\xb3\x74\x44\x5c\x5c\x47\x3a\xcf\xa8\x8c\x52\x51\xf4\x52\xe8"
+  "\xb2\xad\x5c\xb8\xe0\xaf\xa3\x16\x05\x7d\xfc\xc8\xcf\x46\x3d\xf4"
+  "\xa3\x5f\x67\x97\x11\xe1\x27\x0d\x44\x78\x62\x1b\x11\x1e\x8e\x26"
+  "\xc2\x7d\x89\x44\xb8\x07\x54\xec\x9c\x4f\x84\xad\x27\x89\xb0\x31"
+  "\x83\x08\xab\x76\x10\x61\xa9\x8f\xb8\xa2\x6d\x3c\xae\x76\x1c\x11"
+  "\x8e\xec\x23\xc2\xa1\x42\x22\xfc\xb6\x9a\xc7\x9d\x05\xbd\x27\x43"
+  "\x7d\xe5\xff\x2f\xde\x7a\x8a\x03\xd5\xff\x03\x8a\xd2\xee\x33"
   ;

From 0f9ecfd9ccc45c6822b54c3708e0aa1864444c37 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 14 Jan 2010 21:45:39 +0000
Subject: [PATCH 1122/2592] MFC r200853:   Add bus_dma(9) and endianness
 support to ste(4).    o Sorted includes and added missing header files.    o
 Added basic endianness support. In theory ste(4) should work on      any
 architectures.    o Remove the use of contigmalloc(9), contigfree(9) and
 vtophys(9).    o Added 8 byte alignment limitation of TX/RX descriptor.    o
 Added 1 byte alignment requirement for TX/RX buffers.    o ste(4) controllers
 does not support DAC. Limit DMA address space      to be within 32bit
 address.    o Added spare DMA map to gracefully recover from DMA map failure.
    o Removed dead code for checking STE_RXSTAT_DMADONE bit. The bit      was
 already checked in each iteration of loop so it can't be true.    o Added
 second argument count to ste_rxeof(). It is used to limit      number of
 iterations done in RX handler. ATM polling is the only      consumer.    o
 Removed ste_rxeoc() which was added to address RX stuck issue      (cvs rev
 1.66). Unlike TX descriptors, ST201 supports chaining      descriptors to
 form a ring for RX descriptors. If RX descriptor      chaining is not
 supported it's possible for controller to stop      receiving incoming frames
 once controller pass the end of RX      descriptor which in turn requires
 driver post new RX      descriptors to receive more frames. For TX
 descriptors which      does not support chaning, we exactly do manual
 chaining in      driver by concatenating new descriptors to the end of
 previous      TX chain.      Maybe the workaround was borrowed from other
 drivers that does      not support RX descriptor chaining, which is not valid
 for ST201      controllers. I still have no idea how this address RX stuck   
   issue and I can't reproduce the RX stuck issue on DFE-550TX     
 controller.    o Removed hw.ste_rxsyncs sysctl as the workaround was removed.
    o TX/RX side bus_dmamap_load_mbuf_sg(9) support.    o Reimplemented
 optimized ste_encap().    o Simplified TX logic of ste_start_locked().    o
 Added comments for TFD/RFD requirements.    o Increased number of RX
 descriptors to 128 from 64. 128 gave much      better performance than 64
 under high network loads.

---
 sys/dev/ste/if_ste.c    | 743 +++++++++++++++++++++++++++-------------
 sys/dev/ste/if_stereg.h |  59 +++-
 2 files changed, 553 insertions(+), 249 deletions(-)

diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c
index 91bd968b020..0fb8929f9b2 100644
--- a/sys/dev/ste/if_ste.c
+++ b/sys/dev/ste/if_ste.c
@@ -39,14 +39,19 @@ __FBSDID("$FreeBSD$");
 
 #include 
 #include 
-#include 
-#include 
-#include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 
 #include 
+#include 
 #include 
+#include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -55,14 +60,8 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
-#include 
-
-#include               /* for vtophys */
-#include             /* for vtophys */
 #include 
 #include 
-#include 
-#include 
 
 #include 
 #include 
@@ -70,13 +69,13 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
+#include 
+
 /* "device miibus" required.  See GENERIC if you get errors here. */
 #include "miibus_if.h"
 
 #define STE_USEIOSPACE
 
-#include 
-
 MODULE_DEPEND(ste, pci, 1, 1, 1);
 MODULE_DEPEND(ste, ether, 1, 1, 1);
 MODULE_DEPEND(ste, miibus, 1, 1, 1);
@@ -96,8 +95,12 @@ static int	ste_detach(device_t);
 static int	ste_probe(device_t);
 static int	ste_shutdown(device_t);
 
+static int	ste_dma_alloc(struct ste_softc *);
+static void	ste_dma_free(struct ste_softc *);
+static void	ste_dmamap_cb(void *, bus_dma_segment_t *, int, int);
 static int 	ste_eeprom_wait(struct ste_softc *);
-static int	ste_encap(struct ste_softc *, struct ste_chain *, struct mbuf *);
+static int	ste_encap(struct ste_softc *, struct mbuf **,
+		    struct ste_chain *);
 static int	ste_ifmedia_upd(struct ifnet *);
 static void	ste_ifmedia_upd_locked(struct ifnet *);
 static void	ste_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -114,12 +117,10 @@ static int	ste_mii_writereg(struct ste_softc *, struct ste_mii_frame *);
 static int	ste_miibus_readreg(device_t, int, int);
 static void	ste_miibus_statchg(device_t);
 static int	ste_miibus_writereg(device_t, int, int, int);
-static int	ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *,
-		    struct mbuf *);
+static int	ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *);
 static int	ste_read_eeprom(struct ste_softc *, caddr_t, int, int, int);
 static void	ste_reset(struct ste_softc *);
-static void	ste_rxeoc(struct ste_softc *);
-static int	ste_rxeof(struct ste_softc *);
+static int	ste_rxeof(struct ste_softc *, int);
 static void	ste_setmulti(struct ste_softc *);
 static void	ste_start(struct ifnet *);
 static void	ste_start_locked(struct ifnet *);
@@ -168,11 +169,6 @@ static devclass_t ste_devclass;
 DRIVER_MODULE(ste, pci, ste_driver, ste_devclass, 0, 0);
 DRIVER_MODULE(miibus, ste, miibus_driver, miibus_devclass, 0, 0);
 
-SYSCTL_NODE(_hw, OID_AUTO, ste, CTLFLAG_RD, 0, "if_ste parameters");
-
-static int ste_rxsyncs;
-SYSCTL_INT(_hw_ste, OID_AUTO, rxsyncs, CTLFLAG_RW, &ste_rxsyncs, 0, "");
-
 #define STE_SETBIT4(sc, reg, x)				\
 	CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (x))
 
@@ -603,10 +599,7 @@ ste_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 
 	STE_LOCK_ASSERT(sc);
 
-	sc->rxcycles = count;
-	if (cmd == POLL_AND_CHECK_STATUS)
-		ste_rxeoc(sc);
-	rx_npkts = ste_rxeof(sc);
+	rx_npkts = ste_rxeof(sc, count);
 	ste_txeof(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		ste_start_locked(ifp);
@@ -666,10 +659,8 @@ ste_intr(void *xsc)
 		if (!(status & STE_INTRS))
 			break;
 
-		if (status & STE_ISR_RX_DMADONE) {
-			ste_rxeoc(sc);
-			ste_rxeof(sc);
-		}
+		if (status & STE_ISR_RX_DMADONE)
+			ste_rxeof(sc, -1);
 
 		if (status & STE_ISR_TX_DMADONE)
 			ste_txeof(sc);
@@ -701,62 +692,40 @@ ste_intr(void *xsc)
 	STE_UNLOCK(sc);
 }
 
-static void
-ste_rxeoc(struct ste_softc *sc)
-{
-	struct ste_chain_onefrag *cur_rx;
-
-	STE_LOCK_ASSERT(sc);
-
-	if (sc->ste_cdata.ste_rx_head->ste_ptr->ste_status == 0) {
-		cur_rx = sc->ste_cdata.ste_rx_head;
-		do {
-			cur_rx = cur_rx->ste_next;
-			/* If the ring is empty, just return. */
-			if (cur_rx == sc->ste_cdata.ste_rx_head)
-				return;
-		} while (cur_rx->ste_ptr->ste_status == 0);
-		if (sc->ste_cdata.ste_rx_head->ste_ptr->ste_status == 0) {
-			/* We've fallen behind the chip: catch it. */
-			sc->ste_cdata.ste_rx_head = cur_rx;
-			++ste_rxsyncs;
-		}
-	}
-}
-
 /*
  * A frame has been uploaded: pass the resulting mbuf chain up to
  * the higher level protocols.
  */
 static int
-ste_rxeof(struct ste_softc *sc)
+ste_rxeof(struct ste_softc *sc, int count)
 {
         struct mbuf *m;
         struct ifnet *ifp;
 	struct ste_chain_onefrag *cur_rx;
 	uint32_t rxstat;
-	int total_len = 0, count = 0, rx_npkts = 0;
-
-	STE_LOCK_ASSERT(sc);
+	int total_len, rx_npkts;
 
 	ifp = sc->ste_ifp;
 
-	while ((rxstat = sc->ste_cdata.ste_rx_head->ste_ptr->ste_status)
-	      & STE_RXSTAT_DMADONE) {
+	bus_dmamap_sync(sc->ste_cdata.ste_rx_list_tag,
+	    sc->ste_cdata.ste_rx_list_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+	cur_rx = sc->ste_cdata.ste_rx_head;
+	for (rx_npkts = 0; rx_npkts < STE_RX_LIST_CNT; rx_npkts++,
+	    cur_rx = cur_rx->ste_next) {
+		rxstat = le32toh(cur_rx->ste_ptr->ste_status);
+		if ((rxstat & STE_RXSTAT_DMADONE) == 0)
+			break;
 #ifdef DEVICE_POLLING
 		if (ifp->if_capenable & IFCAP_POLLING) {
-			if (sc->rxcycles <= 0)
+			if (count == 0)
 				break;
-			sc->rxcycles--;
+			count--;
 		}
 #endif
-		if ((STE_RX_LIST_CNT - count) < 3) {
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 			break;
-		}
-
-		cur_rx = sc->ste_cdata.ste_rx_head;
-		sc->ste_cdata.ste_rx_head = cur_rx->ste_next;
-
 		/*
 		 * If an error occurs, update stats, clear the
 		 * status word and leave the mbuf cluster in place:
@@ -769,22 +738,9 @@ ste_rxeof(struct ste_softc *sc)
 			continue;
 		}
 
-		/*
-		 * If there error bit was not set, the upload complete
-		 * bit should be set which means we have a valid packet.
-		 * If not, something truly strange has happened.
-		 */
-		if (!(rxstat & STE_RXSTAT_DMADONE)) {
-			device_printf(sc->ste_dev,
-			    "bad receive status -- packet dropped\n");
-			ifp->if_ierrors++;
-			cur_rx->ste_ptr->ste_status = 0;
-			continue;
-		}
-
 		/* No errors; receive the packet. */
 		m = cur_rx->ste_mbuf;
-		total_len = cur_rx->ste_ptr->ste_status & STE_RXSTAT_FRAMELEN;
+		total_len = STE_RX_BYTES(rxstat);
 
 		/*
 		 * Try to conjure up a new mbuf cluster. If that
@@ -793,7 +749,7 @@ ste_rxeof(struct ste_softc *sc)
 		 * result in a lost packet, but there's little else we
 		 * can do in this situation.
 		 */
-		if (ste_newbuf(sc, cur_rx, NULL) == ENOBUFS) {
+		if (ste_newbuf(sc, cur_rx) != 0) {
 			ifp->if_ierrors++;
 			cur_rx->ste_ptr->ste_status = 0;
 			continue;
@@ -806,10 +762,13 @@ ste_rxeof(struct ste_softc *sc)
 		STE_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
 		STE_LOCK(sc);
+	}
 
-		cur_rx->ste_ptr->ste_status = 0;
-		count++;
-		rx_npkts++;
+	if (rx_npkts > 0) {
+		sc->ste_cdata.ste_rx_head = cur_rx;
+		bus_dmamap_sync(sc->ste_cdata.ste_rx_list_tag,
+		    sc->ste_cdata.ste_rx_list_map,
+		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	}
 
 	return (rx_npkts);
@@ -857,27 +816,40 @@ ste_txeof(struct ste_softc *sc)
 {
 	struct ifnet *ifp;
 	struct ste_chain *cur_tx;
+	uint32_t txstat;
 	int idx;
 
-	ifp = sc->ste_ifp;
+	STE_LOCK_ASSERT(sc);
 
+	ifp = sc->ste_ifp;
 	idx = sc->ste_cdata.ste_tx_cons;
+	if (idx == sc->ste_cdata.ste_tx_prod)
+		return;
+
+	bus_dmamap_sync(sc->ste_cdata.ste_tx_list_tag,
+	    sc->ste_cdata.ste_tx_list_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
 	while (idx != sc->ste_cdata.ste_tx_prod) {
 		cur_tx = &sc->ste_cdata.ste_tx_chain[idx];
-
-		if (!(cur_tx->ste_ptr->ste_ctl & STE_TXCTL_DMADONE))
+		txstat = le32toh(cur_tx->ste_ptr->ste_ctl);
+		if ((txstat & STE_TXCTL_DMADONE) == 0)
 			break;
-
+		bus_dmamap_sync(sc->ste_cdata.ste_tx_tag, cur_tx->ste_map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(sc->ste_cdata.ste_tx_tag, cur_tx->ste_map);
+		KASSERT(cur_tx->ste_mbuf != NULL,
+		    ("%s: freeing NULL mbuf!\n", __func__));
 		m_freem(cur_tx->ste_mbuf);
 		cur_tx->ste_mbuf = NULL;
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 		ifp->if_opackets++;
-
+		sc->ste_cdata.ste_tx_cnt--;
 		STE_INC(idx, STE_TX_LIST_CNT);
 	}
 
 	sc->ste_cdata.ste_tx_cons = idx;
-	if (idx == sc->ste_cdata.ste_tx_prod)
+	if (sc->ste_cdata.ste_tx_cnt == 0)
 		sc->ste_timer = 0;
 }
 
@@ -1012,17 +984,8 @@ ste_attach(device_t dev)
 		goto fail;
 	}
 
-	/* Allocate the descriptor queues. */
-	sc->ste_ldata = contigmalloc(sizeof(struct ste_list_data), M_DEVBUF,
-	    M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
-
-	if (sc->ste_ldata == NULL) {
-		device_printf(dev, "no memory for list buffers!\n");
-		error = ENXIO;
+	if ((error = ste_dma_alloc(sc)) != 0)
 		goto fail;
-	}
-
-	bzero(sc->ste_ldata, sizeof(struct ste_list_data));
 
 	ifp = sc->ste_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
@@ -1128,44 +1091,325 @@ ste_detach(device_t dev)
 	if (ifp)
 		if_free(ifp);
 
-	if (sc->ste_ldata) {
-		contigfree(sc->ste_ldata, sizeof(struct ste_list_data),
-		    M_DEVBUF);
-	}
-
+	ste_dma_free(sc);
 	mtx_destroy(&sc->ste_mtx);
 
 	return (0);
 }
 
-static int
-ste_newbuf(struct ste_softc *sc, struct ste_chain_onefrag *c, struct mbuf *m)
-{
-	struct mbuf *m_new = NULL;
+struct ste_dmamap_arg {
+	bus_addr_t	ste_busaddr;
+};
 
-	if (m == NULL) {
-		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
-		if (m_new == NULL)
-			return (ENOBUFS);
-		MCLGET(m_new, M_DONTWAIT);
-		if (!(m_new->m_flags & M_EXT)) {
-			m_freem(m_new);
-			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;
+static void
+ste_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+	struct ste_dmamap_arg *ctx;
+
+	if (error != 0)
+		return;
+
+	KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
+
+	ctx = (struct ste_dmamap_arg *)arg;
+	ctx->ste_busaddr = segs[0].ds_addr;
+}
+
+static int
+ste_dma_alloc(struct ste_softc *sc)
+{
+	struct ste_chain *txc;
+	struct ste_chain_onefrag *rxc;
+	struct ste_dmamap_arg ctx;
+	int error, i;
+
+	/* Create parent DMA tag. */
+	error = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->ste_dev), /* parent */
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
+	    0,				/* nsegments */
+	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->ste_cdata.ste_parent_tag);
+	if (error != 0) {
+		device_printf(sc->ste_dev,
+		    "could not create parent DMA tag.\n");
+		goto fail;
 	}
 
-	m_adj(m_new, ETHER_ALIGN);
+	/* Create DMA tag for Tx descriptor list. */
+	error = bus_dma_tag_create(
+	    sc->ste_cdata.ste_parent_tag, /* parent */
+	    STE_DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    STE_TX_LIST_SZ,		/* maxsize */
+	    1,				/* nsegments */
+	    STE_TX_LIST_SZ,		/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->ste_cdata.ste_tx_list_tag);
+	if (error != 0) {
+		device_printf(sc->ste_dev,
+		    "could not create Tx list DMA tag.\n");
+		goto fail;
+	}
 
-	c->ste_mbuf = m_new;
-	c->ste_ptr->ste_status = 0;
-	c->ste_ptr->ste_frag.ste_addr = vtophys(mtod(m_new, caddr_t));
-	c->ste_ptr->ste_frag.ste_len = (1536 + ETHER_VLAN_ENCAP_LEN) | STE_FRAG_LAST;
+	/* Create DMA tag for Rx descriptor list. */
+	error = bus_dma_tag_create(
+	    sc->ste_cdata.ste_parent_tag, /* parent */
+	    STE_DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    STE_RX_LIST_SZ,		/* maxsize */
+	    1,				/* nsegments */
+	    STE_RX_LIST_SZ,		/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->ste_cdata.ste_rx_list_tag);
+	if (error != 0) {
+		device_printf(sc->ste_dev,
+		    "could not create Rx list DMA tag.\n");
+		goto fail;
+	}
 
+	/* Create DMA tag for Tx buffers. */
+	error = bus_dma_tag_create(
+	    sc->ste_cdata.ste_parent_tag, /* parent */
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    MCLBYTES * STE_MAXFRAGS,	/* maxsize */
+	    STE_MAXFRAGS,		/* nsegments */
+	    MCLBYTES,			/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->ste_cdata.ste_tx_tag);
+	if (error != 0) {
+		device_printf(sc->ste_dev, "could not create Tx DMA tag.\n");
+		goto fail;
+	}
+
+	/* Create DMA tag for Rx buffers. */
+	error = bus_dma_tag_create(
+	    sc->ste_cdata.ste_parent_tag, /* parent */
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    MCLBYTES,			/* maxsize */
+	    1,				/* nsegments */
+	    MCLBYTES,			/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->ste_cdata.ste_rx_tag);
+	if (error != 0) {
+		device_printf(sc->ste_dev, "could not create Rx DMA tag.\n");
+		goto fail;
+	}
+
+	/* Allocate DMA'able memory and load the DMA map for Tx list. */
+	error = bus_dmamem_alloc(sc->ste_cdata.ste_tx_list_tag,
+	    (void **)&sc->ste_ldata.ste_tx_list,
+	    BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_COHERENT,
+	    &sc->ste_cdata.ste_tx_list_map);
+	if (error != 0) {
+		device_printf(sc->ste_dev,
+		    "could not allocate DMA'able memory for Tx list.\n");
+		goto fail;
+	}
+	ctx.ste_busaddr = 0;
+	error = bus_dmamap_load(sc->ste_cdata.ste_tx_list_tag,
+	    sc->ste_cdata.ste_tx_list_map, sc->ste_ldata.ste_tx_list,
+	    STE_TX_LIST_SZ, ste_dmamap_cb, &ctx, 0);
+	if (error != 0 || ctx.ste_busaddr == 0) {
+		device_printf(sc->ste_dev,
+		    "could not load DMA'able memory for Tx list.\n");
+		goto fail;
+	}
+	sc->ste_ldata.ste_tx_list_paddr = ctx.ste_busaddr;
+
+	/* Allocate DMA'able memory and load the DMA map for Rx list. */
+	error = bus_dmamem_alloc(sc->ste_cdata.ste_rx_list_tag,
+	    (void **)&sc->ste_ldata.ste_rx_list,
+	    BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_COHERENT,
+	    &sc->ste_cdata.ste_rx_list_map);
+	if (error != 0) {
+		device_printf(sc->ste_dev,
+		    "could not allocate DMA'able memory for Rx list.\n");
+		goto fail;
+	}
+	ctx.ste_busaddr = 0;
+	error = bus_dmamap_load(sc->ste_cdata.ste_rx_list_tag,
+	    sc->ste_cdata.ste_rx_list_map, sc->ste_ldata.ste_rx_list,
+	    STE_RX_LIST_SZ, ste_dmamap_cb, &ctx, 0);
+	if (error != 0 || ctx.ste_busaddr == 0) {
+		device_printf(sc->ste_dev,
+		    "could not load DMA'able memory for Rx list.\n");
+		goto fail;
+	}
+	sc->ste_ldata.ste_rx_list_paddr = ctx.ste_busaddr;
+
+	/* Create DMA maps for Tx buffers. */
+	for (i = 0; i < STE_TX_LIST_CNT; i++) {
+		txc = &sc->ste_cdata.ste_tx_chain[i];
+		txc->ste_ptr = NULL;
+		txc->ste_mbuf = NULL;
+		txc->ste_next = NULL;
+		txc->ste_phys = 0;
+		txc->ste_map = NULL;
+		error = bus_dmamap_create(sc->ste_cdata.ste_tx_tag, 0,
+		    &txc->ste_map);
+		if (error != 0) {
+			device_printf(sc->ste_dev,
+			    "could not create Tx dmamap.\n");
+			goto fail;
+		}
+	}
+	/* Create DMA maps for Rx buffers. */
+	if ((error = bus_dmamap_create(sc->ste_cdata.ste_rx_tag, 0,
+	    &sc->ste_cdata.ste_rx_sparemap)) != 0) {
+		device_printf(sc->ste_dev,
+		    "could not create spare Rx dmamap.\n");
+		goto fail;
+	}
+	for (i = 0; i < STE_RX_LIST_CNT; i++) {
+		rxc = &sc->ste_cdata.ste_rx_chain[i];
+		rxc->ste_ptr = NULL;
+		rxc->ste_mbuf = NULL;
+		rxc->ste_next = NULL;
+		rxc->ste_map = NULL;
+		error = bus_dmamap_create(sc->ste_cdata.ste_rx_tag, 0,
+		    &rxc->ste_map);
+		if (error != 0) {
+			device_printf(sc->ste_dev,
+			    "could not create Rx dmamap.\n");
+			goto fail;
+		}
+	}
+
+fail:
+	return (error);
+}
+
+static void
+ste_dma_free(struct ste_softc *sc)
+{
+	struct ste_chain *txc;
+	struct ste_chain_onefrag *rxc;
+	int i;
+
+	/* Tx buffers. */
+	if (sc->ste_cdata.ste_tx_tag != NULL) {
+		for (i = 0; i < STE_TX_LIST_CNT; i++) {
+			txc = &sc->ste_cdata.ste_tx_chain[i];
+			if (txc->ste_map != NULL) {
+				bus_dmamap_destroy(sc->ste_cdata.ste_tx_tag,
+				    txc->ste_map);
+				txc->ste_map = NULL;
+			}
+		}
+		bus_dma_tag_destroy(sc->ste_cdata.ste_tx_tag);
+		sc->ste_cdata.ste_tx_tag = NULL;
+	}
+	/* Rx buffers. */
+	if (sc->ste_cdata.ste_rx_tag != NULL) {
+		for (i = 0; i < STE_RX_LIST_CNT; i++) {
+			rxc = &sc->ste_cdata.ste_rx_chain[i];
+			if (rxc->ste_map != NULL) {
+				bus_dmamap_destroy(sc->ste_cdata.ste_rx_tag,
+				    rxc->ste_map);
+				rxc->ste_map = NULL;
+			}
+		}
+		if (sc->ste_cdata.ste_rx_sparemap != NULL) {
+			bus_dmamap_destroy(sc->ste_cdata.ste_rx_tag,
+			    sc->ste_cdata.ste_rx_sparemap);
+			sc->ste_cdata.ste_rx_sparemap = NULL;
+		}
+		bus_dma_tag_destroy(sc->ste_cdata.ste_rx_tag);
+		sc->ste_cdata.ste_rx_tag = NULL;
+	}
+	/* Tx descriptor list. */
+	if (sc->ste_cdata.ste_tx_list_tag != NULL) {
+		if (sc->ste_cdata.ste_tx_list_map != NULL)
+			bus_dmamap_unload(sc->ste_cdata.ste_tx_list_tag,
+			    sc->ste_cdata.ste_tx_list_map);
+		if (sc->ste_cdata.ste_tx_list_map != NULL &&
+		    sc->ste_ldata.ste_tx_list != NULL)
+			bus_dmamem_free(sc->ste_cdata.ste_tx_list_tag,
+			    sc->ste_ldata.ste_tx_list,
+			    sc->ste_cdata.ste_tx_list_map);
+		sc->ste_ldata.ste_tx_list = NULL;
+		sc->ste_cdata.ste_tx_list_map = NULL;
+		bus_dma_tag_destroy(sc->ste_cdata.ste_tx_list_tag);
+		sc->ste_cdata.ste_tx_list_tag = NULL;
+	}
+	/* Rx descriptor list. */
+	if (sc->ste_cdata.ste_rx_list_tag != NULL) {
+		if (sc->ste_cdata.ste_rx_list_map != NULL)
+			bus_dmamap_unload(sc->ste_cdata.ste_rx_list_tag,
+			    sc->ste_cdata.ste_rx_list_map);
+		if (sc->ste_cdata.ste_rx_list_map != NULL &&
+		    sc->ste_ldata.ste_rx_list != NULL)
+			bus_dmamem_free(sc->ste_cdata.ste_rx_list_tag,
+			    sc->ste_ldata.ste_rx_list,
+			    sc->ste_cdata.ste_rx_list_map);
+		sc->ste_ldata.ste_rx_list = NULL;
+		sc->ste_cdata.ste_rx_list_map = NULL;
+		bus_dma_tag_destroy(sc->ste_cdata.ste_rx_list_tag);
+		sc->ste_cdata.ste_rx_list_tag = NULL;
+	}
+	if (sc->ste_cdata.ste_parent_tag != NULL) {
+		bus_dma_tag_destroy(sc->ste_cdata.ste_parent_tag);
+		sc->ste_cdata.ste_parent_tag = NULL;
+	}
+}
+
+static int
+ste_newbuf(struct ste_softc *sc, struct ste_chain_onefrag *rxc)
+{
+	struct mbuf *m;
+	bus_dma_segment_t segs[1];
+	bus_dmamap_t map;
+	int error, nsegs;
+
+	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+	if (m == NULL)
+		return (ENOBUFS);
+	m->m_len = m->m_pkthdr.len = MCLBYTES;
+	m_adj(m, ETHER_ALIGN);
+
+	if ((error = bus_dmamap_load_mbuf_sg(sc->ste_cdata.ste_rx_tag,
+	    sc->ste_cdata.ste_rx_sparemap, m, segs, &nsegs, 0)) != 0) {
+		m_freem(m);
+		return (error);
+	}
+	KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
+
+	if (rxc->ste_mbuf != NULL) {
+		bus_dmamap_sync(sc->ste_cdata.ste_rx_tag, rxc->ste_map,
+		    BUS_DMASYNC_POSTREAD);
+		bus_dmamap_unload(sc->ste_cdata.ste_rx_tag, rxc->ste_map);
+	}
+	map = rxc->ste_map;
+	rxc->ste_map = sc->ste_cdata.ste_rx_sparemap;
+	sc->ste_cdata.ste_rx_sparemap = map;
+	bus_dmamap_sync(sc->ste_cdata.ste_rx_tag, rxc->ste_map,
+	    BUS_DMASYNC_PREREAD);
+	rxc->ste_mbuf = m;
+	rxc->ste_ptr->ste_status = 0;
+	rxc->ste_ptr->ste_frag.ste_addr = htole32(segs[0].ds_addr);
+	rxc->ste_ptr->ste_frag.ste_len = htole32(segs[0].ds_len |
+	    STE_FRAG_LAST);
 	return (0);
 }
 
@@ -1174,30 +1418,31 @@ ste_init_rx_list(struct ste_softc *sc)
 {
 	struct ste_chain_data *cd;
 	struct ste_list_data *ld;
-	int i;
+	int error, i;
 
 	cd = &sc->ste_cdata;
-	ld = sc->ste_ldata;
-
+	ld = &sc->ste_ldata;
+	bzero(ld->ste_rx_list, STE_RX_LIST_SZ);
 	for (i = 0; i < STE_RX_LIST_CNT; i++) {
 		cd->ste_rx_chain[i].ste_ptr = &ld->ste_rx_list[i];
-		if (ste_newbuf(sc, &cd->ste_rx_chain[i], NULL) == ENOBUFS)
-			return (ENOBUFS);
+		error = ste_newbuf(sc, &cd->ste_rx_chain[i]);
+		if (error != 0)
+			return (error);
 		if (i == (STE_RX_LIST_CNT - 1)) {
-			cd->ste_rx_chain[i].ste_next =
-			    &cd->ste_rx_chain[0];
-			ld->ste_rx_list[i].ste_next =
-			    vtophys(&ld->ste_rx_list[0]);
+			cd->ste_rx_chain[i].ste_next = &cd->ste_rx_chain[0];
+			ld->ste_rx_list[i].ste_next = ld->ste_rx_list_paddr +
+			    (sizeof(struct ste_desc_onefrag) * 0);
 		} else {
-			cd->ste_rx_chain[i].ste_next =
-			    &cd->ste_rx_chain[i + 1];
-			ld->ste_rx_list[i].ste_next =
-			    vtophys(&ld->ste_rx_list[i + 1]);
+			cd->ste_rx_chain[i].ste_next = &cd->ste_rx_chain[i + 1];
+			ld->ste_rx_list[i].ste_next = ld->ste_rx_list_paddr +
+			    (sizeof(struct ste_desc_onefrag) * (i + 1));
 		}
-		ld->ste_rx_list[i].ste_status = 0;
 	}
 
 	cd->ste_rx_head = &cd->ste_rx_chain[0];
+	bus_dmamap_sync(sc->ste_cdata.ste_rx_list_tag,
+	    sc->ste_cdata.ste_rx_list_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	return (0);
 }
@@ -1210,22 +1455,32 @@ ste_init_tx_list(struct ste_softc *sc)
 	int i;
 
 	cd = &sc->ste_cdata;
-	ld = sc->ste_ldata;
+	ld = &sc->ste_ldata;
+	bzero(ld->ste_tx_list, STE_TX_LIST_SZ);
 	for (i = 0; i < STE_TX_LIST_CNT; i++) {
 		cd->ste_tx_chain[i].ste_ptr = &ld->ste_tx_list[i];
-		cd->ste_tx_chain[i].ste_ptr->ste_next = 0;
-		cd->ste_tx_chain[i].ste_ptr->ste_ctl  = 0;
-		cd->ste_tx_chain[i].ste_phys = vtophys(&ld->ste_tx_list[i]);
-		if (i == (STE_TX_LIST_CNT - 1))
-			cd->ste_tx_chain[i].ste_next =
-			    &cd->ste_tx_chain[0];
-		else
-			cd->ste_tx_chain[i].ste_next =
-			    &cd->ste_tx_chain[i + 1];
+		cd->ste_tx_chain[i].ste_mbuf = NULL;
+		if (i == (STE_TX_LIST_CNT - 1)) {
+			cd->ste_tx_chain[i].ste_next = &cd->ste_tx_chain[0];
+			cd->ste_tx_chain[i].ste_phys = htole32(STE_ADDR_LO(
+			    ld->ste_tx_list_paddr +
+			    (sizeof(struct ste_desc) * 0)));
+		} else {
+			cd->ste_tx_chain[i].ste_next = &cd->ste_tx_chain[i + 1];
+			cd->ste_tx_chain[i].ste_phys = htole32(STE_ADDR_LO(
+			    ld->ste_tx_list_paddr +
+			    (sizeof(struct ste_desc) * (i + 1))));
+		}
 	}
 
+	cd->ste_last_tx = NULL;
 	cd->ste_tx_prod = 0;
 	cd->ste_tx_cons = 0;
+	cd->ste_tx_cnt = 0;
+
+	bus_dmamap_sync(sc->ste_cdata.ste_tx_list_tag,
+	    sc->ste_cdata.ste_tx_list_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 }
 
 static void
@@ -1258,7 +1513,7 @@ ste_init_locked(struct ste_softc *sc)
 	}
 
 	/* Init RX list */
-	if (ste_init_rx_list(sc) == ENOBUFS) {
+	if (ste_init_rx_list(sc) != 0) {
 		device_printf(sc->ste_dev,
 		    "initialization failed: no memory for RX buffers\n");
 		ste_stop(sc);
@@ -1303,11 +1558,11 @@ ste_init_locked(struct ste_softc *sc)
 	STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_RXDMA_STALL);
 	ste_wait(sc);
 	CSR_WRITE_4(sc, STE_RX_DMALIST_PTR,
-	    vtophys(&sc->ste_ldata->ste_rx_list[0]));
+	    STE_ADDR_LO(sc->ste_ldata.ste_rx_list_paddr));
 	STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_RXDMA_UNSTALL);
 	STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_RXDMA_UNSTALL);
 
-	/* Set TX polling interval (defer until we TX first packet */
+	/* Set TX polling interval(defer until we TX first packet). */
 	CSR_WRITE_1(sc, STE_TX_DMAPOLL_PERIOD, 0);
 
 	/* Load address of the TX list */
@@ -1317,7 +1572,6 @@ ste_init_locked(struct ste_softc *sc)
 	STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_UNSTALL);
 	STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_UNSTALL);
 	ste_wait(sc);
-	sc->ste_tx_prev = NULL;
 
 	/* Enable receiver and transmitter */
 	CSR_WRITE_2(sc, STE_MACCTL0, 0);
@@ -1353,6 +1607,8 @@ static void
 ste_stop(struct ste_softc *sc)
 {
 	struct ifnet *ifp;
+	struct ste_chain_onefrag *cur_rx;
+	struct ste_chain *cur_tx;
 	int i;
 
 	STE_LOCK_ASSERT(sc);
@@ -1377,20 +1633,28 @@ ste_stop(struct ste_softc *sc)
 	sc->ste_link = 0;
 
 	for (i = 0; i < STE_RX_LIST_CNT; i++) {
-		if (sc->ste_cdata.ste_rx_chain[i].ste_mbuf != NULL) {
-			m_freem(sc->ste_cdata.ste_rx_chain[i].ste_mbuf);
-			sc->ste_cdata.ste_rx_chain[i].ste_mbuf = NULL;
+		cur_rx = &sc->ste_cdata.ste_rx_chain[i];
+		if (cur_rx->ste_mbuf != NULL) {
+			bus_dmamap_sync(sc->ste_cdata.ste_rx_tag,
+			    cur_rx->ste_map, BUS_DMASYNC_POSTREAD);
+			bus_dmamap_unload(sc->ste_cdata.ste_rx_tag,
+			    cur_rx->ste_map);
+			m_freem(cur_rx->ste_mbuf);
+			cur_rx->ste_mbuf = NULL;
 		}
 	}
 
 	for (i = 0; i < STE_TX_LIST_CNT; i++) {
-		if (sc->ste_cdata.ste_tx_chain[i].ste_mbuf != NULL) {
-			m_freem(sc->ste_cdata.ste_tx_chain[i].ste_mbuf);
-			sc->ste_cdata.ste_tx_chain[i].ste_mbuf = NULL;
+		cur_tx = &sc->ste_cdata.ste_tx_chain[i];
+		if (cur_tx->ste_mbuf != NULL) {
+			bus_dmamap_sync(sc->ste_cdata.ste_tx_tag,
+			    cur_tx->ste_map, BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(sc->ste_cdata.ste_tx_tag,
+			    cur_tx->ste_map);
+			m_freem(cur_tx->ste_mbuf);
+			cur_tx->ste_mbuf = NULL;
 		}
 	}
-
-	bzero(sc->ste_ldata, sizeof(struct ste_list_data));
 }
 
 static void
@@ -1505,48 +1769,60 @@ ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 }
 
 static int
-ste_encap(struct ste_softc *sc, struct ste_chain *c, struct mbuf *m_head)
+ste_encap(struct ste_softc *sc, struct mbuf **m_head, struct ste_chain *txc)
 {
+	struct ste_frag *frag;
 	struct mbuf *m;
-	struct ste_desc *d;
-	struct ste_frag *f = NULL;
-	int frag = 0;
+	struct ste_desc *desc;
+	bus_dma_segment_t txsegs[STE_MAXFRAGS];
+	int error, i, nsegs;
 
-	d = c->ste_ptr;
-	d->ste_ctl = 0;
+	STE_LOCK_ASSERT(sc);
+	M_ASSERTPKTHDR((*m_head));
 
-encap_retry:
-	for (m = m_head, frag = 0; m != NULL; m = m->m_next) {
-		if (m->m_len != 0) {
-			if (frag == STE_MAXFRAGS)
-				break;
-			f = &d->ste_frags[frag];
-			f->ste_addr = vtophys(mtod(m, vm_offset_t));
-			f->ste_len = m->m_len;
-			frag++;
+	error = bus_dmamap_load_mbuf_sg(sc->ste_cdata.ste_tx_tag,
+	    txc->ste_map, *m_head, txsegs, &nsegs, 0);
+	if (error == EFBIG) {
+		m = m_collapse(*m_head, M_DONTWAIT, STE_MAXFRAGS);
+		if (m == NULL) {
+			m_freem(*m_head);
+			*m_head = NULL;
+			return (ENOMEM);
 		}
-	}
-
-	if (m != NULL) {
-		struct mbuf *mn;
-
-		/*
-		 * We ran out of segments. We have to recopy this
-		 * mbuf chain first. Bail out if we can't get the
-		 * new buffers.
-		 */
-		mn = m_defrag(m_head, M_DONTWAIT);
-		if (mn == NULL) {
-			m_freem(m_head);
-			return ENOMEM;
+		*m_head = m;
+		error = bus_dmamap_load_mbuf_sg(sc->ste_cdata.ste_tx_tag,
+		    txc->ste_map, *m_head, txsegs, &nsegs, 0);
+		if (error != 0) {
+			m_freem(*m_head);
+			*m_head = NULL;
+			return (error);
 		}
-		m_head = mn;
-		goto encap_retry;
+	} else if (error != 0)
+		return (error);
+	if (nsegs == 0) {
+		m_freem(*m_head);
+		*m_head = NULL;
+		return (EIO);
 	}
+	bus_dmamap_sync(sc->ste_cdata.ste_tx_tag, txc->ste_map,
+	    BUS_DMASYNC_PREWRITE);
 
-	c->ste_mbuf = m_head;
-	d->ste_frags[frag - 1].ste_len |= STE_FRAG_LAST;
-	d->ste_ctl = 1;
+	desc = txc->ste_ptr;
+	for (i = 0; i < nsegs; i++) {
+		frag = &desc->ste_frags[i];
+		frag->ste_addr = htole32(STE_ADDR_LO(txsegs[i].ds_addr));
+		frag->ste_len = htole32(txsegs[i].ds_len);
+	}
+	desc->ste_frags[i - 1].ste_len |= htole32(STE_FRAG_LAST);
+	/*
+	 * Because we use Tx polling we can't chain multiple
+	 * Tx descriptors here. Otherwise we race with controller.
+	 */
+	desc->ste_next = 0;
+	desc->ste_ctl = htole32(STE_TXCTL_ALIGN_DIS | STE_TXCTL_DMAINTR);
+	txc->ste_mbuf = *m_head;
+	STE_INC(sc->ste_cdata.ste_tx_prod, STE_TX_LIST_CNT);
+	sc->ste_cdata.ste_tx_cnt++;
 
 	return (0);
 }
@@ -1568,7 +1844,7 @@ ste_start_locked(struct ifnet *ifp)
 	struct ste_softc *sc;
 	struct ste_chain *cur_tx;
 	struct mbuf *m_head = NULL;
-	int idx;
+	int enq;
 
 	sc = ifp->if_softc;
 	STE_LOCK_ASSERT(sc);
@@ -1579,62 +1855,56 @@ ste_start_locked(struct ifnet *ifp)
 	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
 		return;
 
-	idx = sc->ste_cdata.ste_tx_prod;
-
-	while (sc->ste_cdata.ste_tx_chain[idx].ste_mbuf == NULL) {
-		/*
-		 * We cannot re-use the last (free) descriptor;
-		 * the chip may not have read its ste_next yet.
-		 */
-		if (STE_NEXT(idx, STE_TX_LIST_CNT) ==
-		    sc->ste_cdata.ste_tx_cons) {
+	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd);) {
+		if (sc->ste_cdata.ste_tx_cnt == STE_TX_LIST_CNT - 1) {
+			/*
+			 * Controller may have cached copy of the last used
+			 * next ptr so we have to reserve one TFD to avoid
+			 * TFD overruns.
+			 */
 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 			break;
 		}
-
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
 		if (m_head == NULL)
 			break;
-
-		cur_tx = &sc->ste_cdata.ste_tx_chain[idx];
-
-		if (ste_encap(sc, cur_tx, m_head) != 0)
+		cur_tx = &sc->ste_cdata.ste_tx_chain[sc->ste_cdata.ste_tx_prod];
+		if (ste_encap(sc, &m_head, cur_tx) != 0) {
+			if (m_head == NULL)
+				break;
+			IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
 			break;
-
-		cur_tx->ste_ptr->ste_next = 0;
-
-		if (sc->ste_tx_prev == NULL) {
-			cur_tx->ste_ptr->ste_ctl = STE_TXCTL_DMAINTR | 1;
-			/* Load address of the TX list */
+		}
+		if (sc->ste_cdata.ste_last_tx == NULL) {
+			bus_dmamap_sync(sc->ste_cdata.ste_tx_list_tag,
+			    sc->ste_cdata.ste_tx_list_map,
+			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 			STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_STALL);
 			ste_wait(sc);
-
 			CSR_WRITE_4(sc, STE_TX_DMALIST_PTR,
-			    vtophys(&sc->ste_ldata->ste_tx_list[0]));
-
-			/* Set TX polling interval to start TX engine */
+	    		    STE_ADDR_LO(sc->ste_ldata.ste_tx_list_paddr));
 			CSR_WRITE_1(sc, STE_TX_DMAPOLL_PERIOD, 64);
-
 			STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_UNSTALL);
 			ste_wait(sc);
-		}else{
-			cur_tx->ste_ptr->ste_ctl = STE_TXCTL_DMAINTR | 1;
-			sc->ste_tx_prev->ste_ptr->ste_next
-				= cur_tx->ste_phys;
+		} else {
+			sc->ste_cdata.ste_last_tx->ste_ptr->ste_next =
+			    sc->ste_cdata.ste_last_tx->ste_phys;
+			bus_dmamap_sync(sc->ste_cdata.ste_tx_list_tag,
+			    sc->ste_cdata.ste_tx_list_map,
+			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 		}
+		sc->ste_cdata.ste_last_tx = cur_tx;
 
-		sc->ste_tx_prev = cur_tx;
-
+		enq++;
 		/*
 		 * If there's a BPF listener, bounce a copy of this frame
 		 * to him.
 	 	 */
-		BPF_MTAP(ifp, cur_tx->ste_mbuf);
-
-		STE_INC(idx, STE_TX_LIST_CNT);
-		sc->ste_timer = 5;
+		BPF_MTAP(ifp, m_head);
 	}
-	sc->ste_cdata.ste_tx_prod = idx;
+
+	if (enq > 0)
+		sc->ste_timer = STE_TX_TIMEOUT;
 }
 
 static void
@@ -1650,8 +1920,7 @@ ste_watchdog(struct ste_softc *sc)
 
 	ste_txeoc(sc);
 	ste_txeof(sc);
-	ste_rxeoc(sc);
-	ste_rxeof(sc);
+	ste_rxeof(sc, -1);
 	ste_reset(sc);
 	ste_init_locked(sc);
 
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index 8de19614302..49c52aafea0 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -412,6 +412,14 @@ struct ste_frag {
 #define STE_FRAG_LAST		0x80000000
 #define STE_FRAG_LEN		0x00001FFF
 
+/*
+ * A TFD is 16 to 512 bytes in length which means it can have up to 126
+ * fragments for a single Tx frame. Since most frames used in stack have
+ * 3-4 fragments supporting 8 fragments would be enough for normal
+ * operation. If we encounter more than 8 fragments we'll collapse them
+ * into a frame that has less than or equal to 8 fragments. Each buffer
+ * address of a fragment has no alignment limitation.
+ */
 #define STE_MAXFRAGS	8
 
 struct ste_desc {
@@ -420,6 +428,12 @@ struct ste_desc {
 	struct ste_frag		ste_frags[STE_MAXFRAGS];
 };
 
+/*
+ * A RFD has the same structure of TFD which in turn means hardware
+ * supports scatter operation in Rx buffer. Since we just allocate Rx
+ * buffer with m_getcl(9) there is no fragmentation at all so use
+ * single fragment for RFD.
+ */
 struct ste_desc_onefrag {
 	uint32_t		ste_next;
 	uint32_t		ste_status;
@@ -427,6 +441,7 @@ struct ste_desc_onefrag {
 };
 
 #define STE_TXCTL_WORDALIGN	0x00000003
+#define STE_TXCTL_ALIGN_DIS	0x00000001
 #define STE_TXCTL_FRAMEID	0x000003FC
 #define STE_TXCTL_NOCRC		0x00002000
 #define STE_TXCTL_TXINTR	0x00008000
@@ -445,6 +460,8 @@ struct ste_desc_onefrag {
 #define STE_RXSTAT_DMA_OFLOW	0x01000000
 #define STE_RXATAT_ONEBUF	0x10000000
 
+#define STE_RX_BYTES(x)		((x) & STE_RXSTAT_FRAMELEN)
+
 /*
  * register space access macros
  */
@@ -462,13 +479,22 @@ struct ste_desc_onefrag {
 #define CSR_READ_1(sc, reg)		\
 	bus_space_read_1(sc->ste_btag, sc->ste_bhandle, reg)
 
+#define	STE_DESC_ALIGN		8
+#define STE_RX_LIST_CNT		128
+#define STE_TX_LIST_CNT		128
+#define	STE_RX_LIST_SZ		\
+	(sizeof(struct ste_desc_onefrag) * STE_RX_LIST_CNT)
+#define	STE_TX_LIST_SZ		\
+	(sizeof(struct ste_desc) * STE_TX_LIST_CNT)
+#define	STE_ADDR_LO(x)		((uint64_t)(x) & 0xFFFFFFFF)
+#define	STE_ADDR_HI(x)		((uint64_t)(x) >> 32)
+
+#define	STE_TX_TIMEOUT		5
 #define STE_TIMEOUT		1000
 #define STE_MIN_FRAMELEN	60
 #define STE_PACKET_SIZE		1536
-#define ETHER_ALIGN		2
-#define STE_RX_LIST_CNT		64
-#define STE_TX_LIST_CNT		128
 #define STE_INC(x, y)		(x) = (x + 1) % y
+#define STE_DEC(x, y)		(x) = ((x) + ((y) - 1)) % (y)
 #define STE_NEXT(x, y)		(x + 1) % y
 
 struct ste_type {
@@ -478,8 +504,10 @@ struct ste_type {
 };
 
 struct ste_list_data {
-	struct ste_desc_onefrag	ste_rx_list[STE_RX_LIST_CNT];
-	struct ste_desc		ste_tx_list[STE_TX_LIST_CNT];
+	struct ste_desc_onefrag	*ste_rx_list;
+	bus_addr_t		ste_rx_list_paddr;
+	struct ste_desc		*ste_tx_list;
+	bus_addr_t		ste_tx_list_paddr;
 };
 
 struct ste_chain {
@@ -487,21 +515,32 @@ struct ste_chain {
 	struct mbuf		*ste_mbuf;
 	struct ste_chain	*ste_next;
 	uint32_t		ste_phys;
+	bus_dmamap_t		ste_map;
 };
 
 struct ste_chain_onefrag {
 	struct ste_desc_onefrag	*ste_ptr;
 	struct mbuf		*ste_mbuf;
 	struct ste_chain_onefrag	*ste_next;
+	bus_dmamap_t		ste_map;
 };
 
 struct ste_chain_data {
+	bus_dma_tag_t		ste_parent_tag;
+	bus_dma_tag_t		ste_rx_tag;
+	bus_dma_tag_t		ste_tx_tag;
+	bus_dma_tag_t		ste_rx_list_tag;
+	bus_dmamap_t		ste_rx_list_map;
+	bus_dma_tag_t		ste_tx_list_tag;
+	bus_dmamap_t		ste_tx_list_map;
+	bus_dmamap_t		ste_rx_sparemap;
 	struct ste_chain_onefrag ste_rx_chain[STE_RX_LIST_CNT];
-	struct ste_chain	 ste_tx_chain[STE_TX_LIST_CNT];
+	struct ste_chain	ste_tx_chain[STE_TX_LIST_CNT];
 	struct ste_chain_onefrag *ste_rx_head;
-
+	struct ste_chain	*ste_last_tx;
 	int			ste_tx_prod;
 	int			ste_tx_cons;
+	int			ste_tx_cnt;
 };
 
 struct ste_softc {
@@ -518,15 +557,11 @@ struct ste_softc {
 	uint8_t			ste_link;
 	int			ste_if_flags;
 	int			ste_timer;
-	struct ste_chain	*ste_tx_prev;
-	struct ste_list_data	*ste_ldata;
+	struct ste_list_data	ste_ldata;
 	struct ste_chain_data	ste_cdata;
 	struct callout		ste_stat_callout;
 	struct mtx		ste_mtx;
 	uint8_t			ste_one_phy;
-#ifdef DEVICE_POLLING
-	int			rxcycles;
-#endif
 };
 
 #define	STE_LOCK(_sc)		mtx_lock(&(_sc)->ste_mtx)

From 0d9ae5891e7b706bf81dd6393dfe3c26cfabca55 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 14 Jan 2010 22:00:33 +0000
Subject: [PATCH 1123/2592] MFC
 r200854,200856,200865,200873,200875,200877,200884

r200854:
  Add minimal dealy while ste(4) is waiting for the end of active DMA
  cycle.

r200856:
  Introduce sc_flags member variable and use it to keep track of
  link state and PHY related information.
  Remove ste_link and ste_one_phy variable of softc as it's not used
  anymore.
  While I'm here add IFF_DRV_RUNNING check in ste_start_locked().

r200865:
  Reimplement miibus_statchg method. Don't rely on link state change
  interrupt. If we want to use link state change interrupt ste(4)
  should also implement auto-negotiation complete handler as well as
  various PHY access handling. Now link state change is handled by
  mii(4) polling so it will automatically update link state UP/DOWN
  events which in turn make ste(4) usable with lagg(4).

  r199559 added a private timer to drive watchdog and the timer also
  used to drive MAC statistics update. Because the MAC statistics
  update is called whenever statistics counter reaches near-full, it
  drove watchdog timer too fast such that it caused false watchdog
  timeouts under heavy TX traffic conditions.
  Fix the regression by separating ste_stats_update() from driving
  watchdog timer and introduce a new function ste_tick() that handles
  periodic job such as driving watchdog, MAC statistics update and
  link state check etc.
  While I'm here clear armed watchdog timer in ste_stop().

r200873:
  Instead of relying on hard resetting of controller to stop
  receiving incoming traffics, try harder to gracefully stop active
  DMA cycles and then stop MACs. This is the way what datasheet
  recommends and seems to work reliably. Resetting controller while
  active DMAs are in progress is bad thing as we can't predict how
  DMAs touche allocated TX/RX buffers. This change ensures controller
  stop state before attempting to release allocated TX/RX buffers.
  Also update MAC statistics which could have been updated during the
  wait time of MAC stop.

  While I'm here remove unnecessary controller resets in various
  location. ste(4) no longer relies on hard controller reset to stop
  controller and resetting controller also clears all configured
  settings which makes it hard to implement WOL in near future.
  Now resetting a controller is performed in ste_init_locked().

r200875:
  Prefer memory space register mapping over io space. If memory space
  mapping fails fall back to old io space mapping.
  While I'm here use PCIR_BAR macro.

r200877:
  Prefer bus_write_{1,2,4}/bus_read_{1,2,4} to
  bus_space_write_{1,2,4}/bus_space_read_{1,2,4}.
  Remove unused ste_bhandle and ste_btag in softc.

r200884:
  Reimplement Tx status error handler as recommended by datasheet.
  If ste(4) encounter TX underrun or excessive collisions the TX MAC
  of controller is stalled so driver should wake it up again. TX
  underrun requires increasing TX threshold value to minimize
  further TX underruns. Previously ste(4) used to reset controller
  to recover from TX underrun, excessive collision and reclaiming
  error. However datasheet says only TX underrun requires resetting
  entire controller. So implement ste_restart_tx() that restarts TX
  MAC and do not perform full reset except TX underrun case.
  Now ste(4) uses CSR_READ_2 instead of CSR_READ_1 to read
  STE_TX_STATUS register. This way ste(4) will also read frame id
  value and we can write the same value back to STE_TX_FRAMEID
  register instead of overwriting it to 0. The datasheet was wrong
  in write back of STE_TX_STATUS so add some comments why we do so.
  Also always invoke ste_txeoc() after ste_txeof() in ste_poll as
  without reading TX status register can stall TX MAC.
---
 sys/dev/ste/if_ste.c    | 309 +++++++++++++++++++++++++---------------
 sys/dev/ste/if_stereg.h |  33 +++--
 2 files changed, 215 insertions(+), 127 deletions(-)

diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c
index 0fb8929f9b2..f25c9cf20fd 100644
--- a/sys/dev/ste/if_ste.c
+++ b/sys/dev/ste/if_ste.c
@@ -74,12 +74,13 @@ __FBSDID("$FreeBSD$");
 /* "device miibus" required.  See GENERIC if you get errors here. */
 #include "miibus_if.h"
 
-#define STE_USEIOSPACE
-
 MODULE_DEPEND(ste, pci, 1, 1, 1);
 MODULE_DEPEND(ste, ether, 1, 1, 1);
 MODULE_DEPEND(ste, miibus, 1, 1, 1);
 
+/* Define to show Tx error status. */
+#define	STE_SHOW_TXERRORS
+
 /*
  * Various supported device vendors/types and their names.
  */
@@ -120,25 +121,19 @@ static int	ste_miibus_writereg(device_t, int, int, int);
 static int	ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *);
 static int	ste_read_eeprom(struct ste_softc *, caddr_t, int, int, int);
 static void	ste_reset(struct ste_softc *);
+static void	ste_restart_tx(struct ste_softc *);
 static int	ste_rxeof(struct ste_softc *, int);
 static void	ste_setmulti(struct ste_softc *);
 static void	ste_start(struct ifnet *);
 static void	ste_start_locked(struct ifnet *);
-static void	ste_stats_update(void *);
+static void	ste_stats_update(struct ste_softc *);
 static void	ste_stop(struct ste_softc *);
+static void	ste_tick(void *);
 static void	ste_txeoc(struct ste_softc *);
 static void	ste_txeof(struct ste_softc *);
 static void	ste_wait(struct ste_softc *);
 static void	ste_watchdog(struct ste_softc *);
 
-#ifdef STE_USEIOSPACE
-#define STE_RES			SYS_RES_IOPORT
-#define STE_RID			STE_PCI_LOIO
-#else
-#define STE_RES			SYS_RES_MEMORY
-#define STE_RID			STE_PCI_LOMEM
-#endif
-
 static device_method_t ste_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		ste_probe),
@@ -369,7 +364,7 @@ ste_miibus_readreg(device_t dev, int phy, int reg)
 
 	sc = device_get_softc(dev);
 
-	if ( sc->ste_one_phy && phy != 0 )
+	if ((sc->ste_flags & STE_FLAG_ONE_PHY) != 0 && phy != 0)
 		return (0);
 
 	bzero((char *)&frame, sizeof(frame));
@@ -404,15 +399,49 @@ ste_miibus_statchg(device_t dev)
 {
 	struct ste_softc *sc;
 	struct mii_data *mii;
+	struct ifnet *ifp;
+	uint16_t cfg;
 
 	sc = device_get_softc(dev);
 
 	mii = device_get_softc(sc->ste_miibus);
+	ifp = sc->ste_ifp;
+	if (mii == NULL || ifp == NULL ||
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
 
-	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
-		STE_SETBIT2(sc, STE_MACCTL0, STE_MACCTL0_FULLDUPLEX);
-	} else {
-		STE_CLRBIT2(sc, STE_MACCTL0, STE_MACCTL0_FULLDUPLEX);
+	sc->ste_flags &= ~STE_FLAG_LINK;
+	if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+	    (IFM_ACTIVE | IFM_AVALID)) {
+		switch (IFM_SUBTYPE(mii->mii_media_active)) {
+		case IFM_10_T:
+		case IFM_100_TX:
+		case IFM_100_FX:
+		case IFM_100_T4:
+			sc->ste_flags |= STE_FLAG_LINK;
+		default:
+			break;
+		}
+	}
+
+	/* Program MACs with resolved speed/duplex/flow-control. */
+	if ((sc->ste_flags & STE_FLAG_LINK) != 0) {
+		cfg = CSR_READ_2(sc, STE_MACCTL0);
+		cfg &= ~(STE_MACCTL0_FLOWCTL_ENABLE | STE_MACCTL0_FULLDUPLEX);
+		if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
+			/*
+			 * ST201 data sheet says driver should enable receiving
+			 * MAC control frames bit of receive mode register to
+			 * receive flow-control frames but the register has no
+			 * such bits. In addition the controller has no ability
+			 * to send pause frames so it should be handled in
+			 * driver. Implementing pause timer handling in driver
+			 * layer is not trivial, so don't enable flow-control
+			 * here.
+			 */
+			cfg |= STE_MACCTL0_FULLDUPLEX;
+		}
+		CSR_WRITE_2(sc, STE_MACCTL0, cfg);
 	}
 }
 
@@ -438,7 +467,7 @@ ste_ifmedia_upd_locked(struct ifnet *ifp)
 	sc = ifp->if_softc;
 	STE_LOCK_ASSERT(sc);
 	mii = device_get_softc(sc->ste_miibus);
-	sc->ste_link = 0;
+	sc->ste_flags &= ~STE_FLAG_LINK;
 	if (mii->mii_instance) {
 		struct mii_softc	*miisc;
 		LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
@@ -471,6 +500,7 @@ ste_wait(struct ste_softc *sc)
 	for (i = 0; i < STE_TIMEOUT; i++) {
 		if (!(CSR_READ_4(sc, STE_DMACTL) & STE_DMACTL_DMA_HALTINPROG))
 			break;
+		DELAY(1);
 	}
 
 	if (i == STE_TIMEOUT)
@@ -601,6 +631,7 @@ ste_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 
 	rx_npkts = ste_rxeof(sc, count);
 	ste_txeof(sc);
+	ste_txeoc(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		ste_start_locked(ifp);
 
@@ -609,21 +640,11 @@ ste_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 
 		status = CSR_READ_2(sc, STE_ISR_ACK);
 
-		if (status & STE_ISR_TX_DONE)
-			ste_txeoc(sc);
-
-		if (status & STE_ISR_STATS_OFLOW) {
-			callout_stop(&sc->ste_stat_callout);
+		if (status & STE_ISR_STATS_OFLOW)
 			ste_stats_update(sc);
-		}
 
-		if (status & STE_ISR_LINKEVENT)
-			mii_pollstat(device_get_softc(sc->ste_miibus));
-
-		if (status & STE_ISR_HOSTERR) {
-			ste_reset(sc);
+		if (status & STE_ISR_HOSTERR)
 			ste_init_locked(sc);
-		}
 	}
 	return (rx_npkts);
 }
@@ -668,19 +689,11 @@ ste_intr(void *xsc)
 		if (status & STE_ISR_TX_DONE)
 			ste_txeoc(sc);
 
-		if (status & STE_ISR_STATS_OFLOW) {
-			callout_stop(&sc->ste_stat_callout);
+		if (status & STE_ISR_STATS_OFLOW)
 			ste_stats_update(sc);
-		}
 
-		if (status & STE_ISR_LINKEVENT)
-			mii_pollstat(device_get_softc(sc->ste_miibus));
-
-
-		if (status & STE_ISR_HOSTERR) {
-			ste_reset(sc);
+		if (status & STE_ISR_HOSTERR)
 			ste_init_locked(sc);
-		}
 	}
 
 	/* Re-enable interrupts */
@@ -777,40 +790,91 @@ ste_rxeof(struct ste_softc *sc, int count)
 static void
 ste_txeoc(struct ste_softc *sc)
 {
+	uint16_t txstat;
 	struct ifnet *ifp;
-	uint8_t txstat;
+
+	STE_LOCK_ASSERT(sc);
 
 	ifp = sc->ste_ifp;
 
-	while ((txstat = CSR_READ_1(sc, STE_TX_STATUS)) &
-	    STE_TXSTATUS_TXDONE) {
-		if (txstat & STE_TXSTATUS_UNDERRUN ||
-		    txstat & STE_TXSTATUS_EXCESSCOLLS ||
-		    txstat & STE_TXSTATUS_RECLAIMERR) {
+	/*
+	 * STE_TX_STATUS register implements a queue of up to 31
+	 * transmit status byte. Writing an arbitrary value to the
+	 * register will advance the queue to the next transmit
+	 * status byte. This means if driver does not read
+	 * STE_TX_STATUS register after completing sending more
+	 * than 31 frames the controller would be stalled so driver
+	 * should re-wake the Tx MAC. This is the most severe
+	 * limitation of ST201 based controller.
+	 */
+	for (;;) {
+		txstat = CSR_READ_2(sc, STE_TX_STATUS);
+		if ((txstat & STE_TXSTATUS_TXDONE) == 0)
+			break;
+		if ((txstat & (STE_TXSTATUS_UNDERRUN |
+		    STE_TXSTATUS_EXCESSCOLLS | STE_TXSTATUS_RECLAIMERR |
+		    STE_TXSTATUS_STATSOFLOW)) != 0) {
 			ifp->if_oerrors++;
-			device_printf(sc->ste_dev,
-			    "transmission error: %x\n", txstat);
-
-			ste_reset(sc);
-			ste_init_locked(sc);
-
-			if (txstat & STE_TXSTATUS_UNDERRUN &&
+#ifdef	STE_SHOW_TXERRORS
+			device_printf(sc->ste_dev, "TX error : 0x%b\n",
+			    txstat & 0xFF, STE_ERR_BITS);
+#endif
+			if ((txstat & STE_TXSTATUS_UNDERRUN) != 0 &&
 			    sc->ste_tx_thresh < STE_PACKET_SIZE) {
 				sc->ste_tx_thresh += STE_MIN_FRAMELEN;
+				if (sc->ste_tx_thresh > STE_PACKET_SIZE)
+					sc->ste_tx_thresh = STE_PACKET_SIZE;
 				device_printf(sc->ste_dev,
-				    "tx underrun, increasing tx"
+				    "TX underrun, increasing TX"
 				    " start threshold to %d bytes\n",
 				    sc->ste_tx_thresh);
+				/* Make sure to disable active DMA cycles. */
+				STE_SETBIT4(sc, STE_DMACTL,
+				    STE_DMACTL_TXDMA_STALL);
+				ste_wait(sc);
+				ste_init_locked(sc);
+				break;
 			}
-			CSR_WRITE_2(sc, STE_TX_STARTTHRESH, sc->ste_tx_thresh);
-			CSR_WRITE_2(sc, STE_TX_RECLAIM_THRESH,
-			    (STE_PACKET_SIZE >> 4));
+			/* Restart Tx. */
+			ste_restart_tx(sc);
 		}
-		ste_init_locked(sc);
+		/*
+		 * Advance to next status and ACK TxComplete
+		 * interrupt. ST201 data sheet was wrong here, to
+		 * get next Tx status, we have to write both
+		 * STE_TX_STATUS and STE_TX_FRAMEID register.
+		 * Otherwise controller returns the same status
+		 * as well as not acknowledge Tx completion
+		 * interrupt.
+		 */
 		CSR_WRITE_2(sc, STE_TX_STATUS, txstat);
 	}
 }
 
+static void
+ste_tick(void *arg)
+{
+	struct ste_softc *sc;
+	struct mii_data *mii;
+
+	sc = (struct ste_softc *)arg;
+
+	STE_LOCK_ASSERT(sc);
+
+	mii = device_get_softc(sc->ste_miibus);
+	mii_tick(mii);
+	/*
+	 * ukphy(4) does not seem to generate CB that reports
+	 * resolved link state so if we know we lost a link,
+	 * explicitly check the link state.
+	 */
+	if ((sc->ste_flags & STE_FLAG_LINK) == 0)
+		ste_miibus_statchg(sc->ste_dev);
+	ste_stats_update(sc);
+	ste_watchdog(sc);
+	callout_reset(&sc->ste_callout, hz, ste_tick, sc);
+}
+
 static void
 ste_txeof(struct ste_softc *sc)
 {
@@ -854,43 +918,18 @@ ste_txeof(struct ste_softc *sc)
 }
 
 static void
-ste_stats_update(void *xsc)
+ste_stats_update(struct ste_softc *sc)
 {
-	struct ste_softc *sc;
 	struct ifnet *ifp;
-	struct mii_data *mii;
 
-	sc = xsc;
 	STE_LOCK_ASSERT(sc);
 
 	ifp = sc->ste_ifp;
-	mii = device_get_softc(sc->ste_miibus);
-
 	ifp->if_collisions += CSR_READ_1(sc, STE_LATE_COLLS)
 	    + CSR_READ_1(sc, STE_MULTI_COLLS)
 	    + CSR_READ_1(sc, STE_SINGLE_COLLS);
-
-	if (!sc->ste_link) {
-		mii_pollstat(mii);
-		if (mii->mii_media_status & IFM_ACTIVE &&
-		    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
-			sc->ste_link++;
-			/*
-			* we don't get a call-back on re-init so do it
-			* otherwise we get stuck in the wrong link state
-			*/
-			ste_miibus_statchg(sc->ste_dev);
-			if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-				ste_start_locked(ifp);
-		}
-	}
-
-	if (sc->ste_timer > 0 && --sc->ste_timer == 0)
-		ste_watchdog(sc);
-	callout_reset(&sc->ste_stat_callout, hz, ste_stats_update, sc);
 }
 
-
 /*
  * Probe for a Sundance ST201 chip. Check the PCI vendor and device
  * IDs against our list and return a device name if we find a match.
@@ -937,7 +976,7 @@ ste_attach(device_t dev)
 	if (pci_get_vendor(dev) == DL_VENDORID &&
 	    pci_get_device(dev) == DL_DEVICEID_DL10050 &&
 	    pci_get_revid(dev) == 0x12 )
-		sc->ste_one_phy = 1;
+		sc->ste_flags |= STE_FLAG_ONE_PHY;
 
 	mtx_init(&sc->ste_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
 	    MTX_DEF);
@@ -946,18 +985,23 @@ ste_attach(device_t dev)
 	 */
 	pci_enable_busmaster(dev);
 
-	rid = STE_RID;
-	sc->ste_res = bus_alloc_resource_any(dev, STE_RES, &rid, RF_ACTIVE);
-
+	/* Prefer memory space register mapping over IO space. */
+	sc->ste_res_id = PCIR_BAR(1);
+	sc->ste_res_type = SYS_RES_MEMORY;
+	sc->ste_res = bus_alloc_resource_any(dev, sc->ste_res_type,
+	    &sc->ste_res_id, RF_ACTIVE);
+	if (sc->ste_res == NULL) {
+		sc->ste_res_id = PCIR_BAR(0);
+		sc->ste_res_type = SYS_RES_IOPORT;
+		sc->ste_res = bus_alloc_resource_any(dev, sc->ste_res_type,
+		    &sc->ste_res_id, RF_ACTIVE);
+	}
 	if (sc->ste_res == NULL) {
 		device_printf(dev, "couldn't map ports/memory\n");
 		error = ENXIO;
 		goto fail;
 	}
 
-	sc->ste_btag = rman_get_bustag(sc->ste_res);
-	sc->ste_bhandle = rman_get_bushandle(sc->ste_res);
-
 	/* Allocate interrupt */
 	rid = 0;
 	sc->ste_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
@@ -969,7 +1013,7 @@ ste_attach(device_t dev)
 		goto fail;
 	}
 
-	callout_init_mtx(&sc->ste_stat_callout, &sc->ste_mtx, 0);
+	callout_init_mtx(&sc->ste_callout, &sc->ste_mtx, 0);
 
 	/* Reset the adapter. */
 	ste_reset(sc);
@@ -1075,7 +1119,7 @@ ste_detach(device_t dev)
 		STE_LOCK(sc);
 		ste_stop(sc);
 		STE_UNLOCK(sc);
-		callout_drain(&sc->ste_stat_callout);
+		callout_drain(&sc->ste_callout);
 	}
 	if (sc->ste_miibus)
 		device_delete_child(dev, sc->ste_miibus);
@@ -1086,7 +1130,8 @@ ste_detach(device_t dev)
 	if (sc->ste_irq)
 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
 	if (sc->ste_res)
-		bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
+		bus_release_resource(dev, sc->ste_res_type, sc->ste_res_id,
+		    sc->ste_res);
 
 	if (ifp)
 		if_free(ifp);
@@ -1504,6 +1549,8 @@ ste_init_locked(struct ste_softc *sc)
 	ifp = sc->ste_ifp;
 
 	ste_stop(sc);
+	/* Reset the chip to a known state. */
+	ste_reset(sc);
 
 	/* Init our MAC address */
 	for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
@@ -1600,7 +1647,7 @@ ste_init_locked(struct ste_softc *sc)
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
-	callout_reset(&sc->ste_stat_callout, hz, ste_stats_update, sc);
+	callout_reset(&sc->ste_callout, hz, ste_tick, sc);
 }
 
 static void
@@ -1609,28 +1656,44 @@ ste_stop(struct ste_softc *sc)
 	struct ifnet *ifp;
 	struct ste_chain_onefrag *cur_rx;
 	struct ste_chain *cur_tx;
+	uint32_t val;
 	int i;
 
 	STE_LOCK_ASSERT(sc);
 	ifp = sc->ste_ifp;
 
-	callout_stop(&sc->ste_stat_callout);
+	callout_stop(&sc->ste_callout);
+	sc->ste_timer = 0;
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING|IFF_DRV_OACTIVE);
 
 	CSR_WRITE_2(sc, STE_IMR, 0);
-	STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_TX_DISABLE);
-	STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_RX_DISABLE);
-	STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_STATS_DISABLE);
-	STE_SETBIT2(sc, STE_DMACTL, STE_DMACTL_TXDMA_STALL);
-	STE_SETBIT2(sc, STE_DMACTL, STE_DMACTL_RXDMA_STALL);
+	/* Stop pending DMA. */
+	val = CSR_READ_4(sc, STE_DMACTL);
+	val |= STE_DMACTL_TXDMA_STALL | STE_DMACTL_RXDMA_STALL;
+	CSR_WRITE_4(sc, STE_DMACTL, val);
 	ste_wait(sc);
-	/*
-	 * Try really hard to stop the RX engine or under heavy RX
-	 * data chip will write into de-allocated memory.
-	 */
-	ste_reset(sc);
-
-	sc->ste_link = 0;
+	/* Disable auto-polling. */
+	CSR_WRITE_1(sc, STE_RX_DMAPOLL_PERIOD, 0);
+	CSR_WRITE_1(sc, STE_TX_DMAPOLL_PERIOD, 0);
+	/* Nullify DMA address to stop any further DMA. */
+	CSR_WRITE_4(sc, STE_RX_DMALIST_PTR, 0);
+	CSR_WRITE_4(sc, STE_TX_DMALIST_PTR, 0);
+	/* Stop TX/RX MAC. */
+	val = CSR_READ_2(sc, STE_MACCTL1);
+	val |= STE_MACCTL1_TX_DISABLE | STE_MACCTL1_RX_DISABLE |
+	    STE_MACCTL1_STATS_DISABLE;
+	CSR_WRITE_2(sc, STE_MACCTL1, val);
+	for (i = 0; i < STE_TIMEOUT; i++) {
+		DELAY(10);
+		if ((CSR_READ_2(sc, STE_MACCTL1) & (STE_MACCTL1_TX_DISABLE |
+		    STE_MACCTL1_RX_DISABLE | STE_MACCTL1_STATS_DISABLE)) == 0)
+			break;
+	}
+	if (i == STE_TIMEOUT)
+		device_printf(sc->ste_dev, "Stopping MAC timed out\n");
+	/* Acknowledge any pending interrupts. */
+	CSR_READ_2(sc, STE_ISR_ACK);
+	ste_stats_update(sc);
 
 	for (i = 0; i < STE_RX_LIST_CNT; i++) {
 		cur_rx = &sc->ste_cdata.ste_rx_chain[i];
@@ -1680,6 +1743,26 @@ ste_reset(struct ste_softc *sc)
 		device_printf(sc->ste_dev, "global reset never completed\n");
 }
 
+static void
+ste_restart_tx(struct ste_softc *sc)
+{
+	uint16_t mac;
+	int i;
+
+	for (i = 0; i < STE_TIMEOUT; i++) {
+		mac = CSR_READ_2(sc, STE_MACCTL1);
+		mac |= STE_MACCTL1_TX_ENABLE;
+		CSR_WRITE_2(sc, STE_MACCTL1, mac);
+		mac = CSR_READ_2(sc, STE_MACCTL1);
+		if ((mac & STE_MACCTL1_TX_ENABLED) != 0)
+			break;
+		DELAY(10);
+	}
+
+	if (i == STE_TIMEOUT)
+		device_printf(sc->ste_dev, "starting Tx failed");
+}
+
 static int
 ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 {
@@ -1849,10 +1932,8 @@ ste_start_locked(struct ifnet *ifp)
 	sc = ifp->if_softc;
 	STE_LOCK_ASSERT(sc);
 
-	if (!sc->ste_link)
-		return;
-
-	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
+	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+	    IFF_DRV_RUNNING || (sc->ste_flags & STE_FLAG_LINK) == 0)
 		return;
 
 	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd);) {
@@ -1915,13 +1996,15 @@ ste_watchdog(struct ste_softc *sc)
 	ifp = sc->ste_ifp;
 	STE_LOCK_ASSERT(sc);
 
+	if (sc->ste_timer == 0 || --sc->ste_timer)
+		return;
+
 	ifp->if_oerrors++;
 	if_printf(ifp, "watchdog timeout\n");
 
-	ste_txeoc(sc);
 	ste_txeof(sc);
+	ste_txeoc(sc);
 	ste_rxeof(sc, -1);
-	ste_reset(sc);
 	ste_init_locked(sc);
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index 49c52aafea0..4ec1920f4cf 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -253,6 +253,11 @@
 #define STE_TXSTATUS_TXINTR_REQ		0x40
 #define STE_TXSTATUS_TXDONE		0x80
 
+#define	STE_ERR_BITS			"\20"				\
+					"\2RECLAIM\3STSOFLOW"		\
+					"\4EXCESSCOLLS\5UNDERRUN"	\
+					"\6INTREQ\7DONE"
+
 #define STE_ISRACK_INTLATCH		0x0001
 #define STE_ISRACK_HOSTERR		0x0002
 #define STE_ISRACK_TX_DONE		0x0004
@@ -276,10 +281,9 @@
 #define STE_IMR_TX_DMADONE		0x0200
 #define STE_IMR_RX_DMADONE		0x0400
 
-#define STE_INTRS					\
+#define STE_INTRS				\
 	(STE_IMR_RX_DMADONE|STE_IMR_TX_DMADONE|	\
-	STE_IMR_TX_DONE|STE_IMR_HOSTERR| \
-        STE_IMR_LINKEVENT)
+	STE_IMR_TX_DONE|STE_IMR_HOSTERR)
 
 #define STE_ISR_INTLATCH		0x0001
 #define STE_ISR_HOSTERR			0x0002
@@ -466,18 +470,18 @@ struct ste_desc_onefrag {
  * register space access macros
  */
 #define CSR_WRITE_4(sc, reg, val)	\
-	bus_space_write_4(sc->ste_btag, sc->ste_bhandle, reg, val)
+	bus_write_4((sc)->ste_res, reg, val)
 #define CSR_WRITE_2(sc, reg, val)	\
-	bus_space_write_2(sc->ste_btag, sc->ste_bhandle, reg, val)
+	bus_write_2((sc)->ste_res, reg, val)
 #define CSR_WRITE_1(sc, reg, val)	\
-	bus_space_write_1(sc->ste_btag, sc->ste_bhandle, reg, val)
+	bus_write_1((sc)->ste_res, reg, val)
 
 #define CSR_READ_4(sc, reg)		\
-	bus_space_read_4(sc->ste_btag, sc->ste_bhandle, reg)
+	bus_read_4((sc)->ste_res, reg)
 #define CSR_READ_2(sc, reg)		\
-	bus_space_read_2(sc->ste_btag, sc->ste_bhandle, reg)
+	bus_read_2((sc)->ste_res, reg)
 #define CSR_READ_1(sc, reg)		\
-	bus_space_read_1(sc->ste_btag, sc->ste_bhandle, reg)
+	bus_read_1((sc)->ste_res, reg)
 
 #define	STE_DESC_ALIGN		8
 #define STE_RX_LIST_CNT		128
@@ -545,23 +549,24 @@ struct ste_chain_data {
 
 struct ste_softc {
 	struct ifnet		*ste_ifp;
-	bus_space_tag_t		ste_btag;
-	bus_space_handle_t	ste_bhandle;
 	struct resource		*ste_res;
+	int			ste_res_id;
+	int			ste_res_type;
 	struct resource		*ste_irq;
 	void			*ste_intrhand;
 	struct ste_type		*ste_info;
 	device_t		ste_miibus;
 	device_t		ste_dev;
 	int			ste_tx_thresh;
-	uint8_t			ste_link;
+	int			ste_flags;
+#define	STE_FLAG_ONE_PHY	0x0001
+#define	STE_FLAG_LINK		0x8000
 	int			ste_if_flags;
 	int			ste_timer;
 	struct ste_list_data	ste_ldata;
 	struct ste_chain_data	ste_cdata;
-	struct callout		ste_stat_callout;
+	struct callout		ste_callout;
 	struct mtx		ste_mtx;
-	uint8_t			ste_one_phy;
 };
 
 #define	STE_LOCK(_sc)		mtx_lock(&(_sc)->ste_mtx)

From 812b4b875dd5135500c12ebf7e579a4994e3fdb5 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 14 Jan 2010 22:15:51 +0000
Subject: [PATCH 1124/2592] MFC r200904-200908,200910-200913

r200904:
  Don't reinitialize controller if driver is already running. This
  reduces number of link state UP/DOWN changes.

r200905:
  Reimplement controller reset. Datasheet says full reset takes about
  1ms. Since we switched to memory register mapping make sure to
  flush PCI posted write by reading the register again.
  While I'm here add additional delays in loop while driver waits the
  completion of the reset.

r200906:
  Overhaul RX filter programming.
   o Let RX filter handler program promiscuous/multicast filter as
     well as broadcasting.
   o Remove unnecessary register access.
   o Simplify ioctl handler and have set_rxfilter to handle
     IFF_PROMISC and IFF_ALLMULTI change instead of directly
     programming the controller.
   o Removed unnecessary error variable reinitialization in ioctl
     handler.
   o Add IFF_DRV_RUNNING check before programming multicast filter.
   o Configure maximum allowed frame length before enabling MAC.
     Datasheet didn't say the exact ordering of programming sequence
     but it looks more natural to set maximum allowed frame length
     first prior to enabling controller.

r200907:
  Don't report link status if driver is not running.

r200908:
  Report the correct result of mii_mediachg(). Previously it always
  used to return success without respect to the result.
  While I'm here use mii_mediachg() in ste_init_locked which allows
  driver to use currently configured media. ste_ifmedia_upd() is
  supposed to be called whenever user changes current media settings.

r200910:
  Implement hardware MAC statistics counter support. The counters
  could be accessed with dev.ste.0.stats sysctl node.

r200911:
  Remove unused duplicated register definition. It seems the
  definition was made to access STE_ASICCTL register as 16bits but
  ste(4) always access the register as 32bits so it was never used
  before.

r200912:
  Correct STE_COUNTDOWN register offset. The datasheet was wrong.

r200913:
  We don't need to generate DMA complete interrupt for every
  transmitted frames. So request interrupt for every 16th frames. Due
  to the limitation of hardware we can't suppress the interrupt as
  driver should have to check TX status register. The TX status
  register can store up to 31 TX status so driver can't send more
  than 31 frames without reading TX status register.
  With this change controller would not generate TX completion
  interrupt for every frame, so reclaim transmitted frames in
  ste_tick().
---
 sys/dev/ste/if_ste.c    | 316 ++++++++++++++++++++++++++++------------
 sys/dev/ste/if_stereg.h |  78 +++++-----
 2 files changed, 266 insertions(+), 128 deletions(-)

diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c
index f25c9cf20fd..8c8b121ff1d 100644
--- a/sys/dev/ste/if_ste.c
+++ b/sys/dev/ste/if_ste.c
@@ -103,7 +103,6 @@ static int 	ste_eeprom_wait(struct ste_softc *);
 static int	ste_encap(struct ste_softc *, struct mbuf **,
 		    struct ste_chain *);
 static int	ste_ifmedia_upd(struct ifnet *);
-static void	ste_ifmedia_upd_locked(struct ifnet *);
 static void	ste_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 static void	ste_init(void *);
 static void	ste_init_locked(struct ste_softc *);
@@ -123,11 +122,13 @@ static int	ste_read_eeprom(struct ste_softc *, caddr_t, int, int, int);
 static void	ste_reset(struct ste_softc *);
 static void	ste_restart_tx(struct ste_softc *);
 static int	ste_rxeof(struct ste_softc *, int);
-static void	ste_setmulti(struct ste_softc *);
+static void	ste_rxfilter(struct ste_softc *);
 static void	ste_start(struct ifnet *);
 static void	ste_start_locked(struct ifnet *);
+static void	ste_stats_clear(struct ste_softc *);
 static void	ste_stats_update(struct ste_softc *);
 static void	ste_stop(struct ste_softc *);
+static void	ste_sysctl_node(struct ste_softc *);
 static void	ste_tick(void *);
 static void	ste_txeoc(struct ste_softc *);
 static void	ste_txeof(struct ste_softc *);
@@ -449,31 +450,21 @@ static int
 ste_ifmedia_upd(struct ifnet *ifp)
 {
 	struct ste_softc *sc;
+	struct mii_data	*mii;
+	struct mii_softc *miisc;
+	int error;
 
 	sc = ifp->if_softc;
 	STE_LOCK(sc);
-	ste_ifmedia_upd_locked(ifp);
-	STE_UNLOCK(sc);
-
-	return (0);
-}
-
-static void
-ste_ifmedia_upd_locked(struct ifnet *ifp)
-{
-	struct ste_softc *sc;
-	struct mii_data *mii;
-
-	sc = ifp->if_softc;
-	STE_LOCK_ASSERT(sc);
 	mii = device_get_softc(sc->ste_miibus);
-	sc->ste_flags &= ~STE_FLAG_LINK;
 	if (mii->mii_instance) {
-		struct mii_softc	*miisc;
 		LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
 			mii_phy_reset(miisc);
 	}
-	mii_mediachg(mii);
+	error = mii_mediachg(mii);
+	STE_UNLOCK(sc);
+
+	return (error);
 }
 
 static void
@@ -486,6 +477,10 @@ ste_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 	mii = device_get_softc(sc->ste_miibus);
 
 	STE_LOCK(sc);
+	if ((ifp->if_flags & IFF_UP) == 0) {
+		STE_UNLOCK(sc);
+		return;
+	}
 	mii_pollstat(mii);
 	ifmr->ifm_active = mii->mii_media_active;
 	ifmr->ifm_status = mii->mii_media_status;
@@ -563,27 +558,33 @@ ste_read_eeprom(struct ste_softc *sc, caddr_t dest, int off, int cnt, int swap)
 }
 
 static void
-ste_setmulti(struct ste_softc *sc)
+ste_rxfilter(struct ste_softc *sc)
 {
 	struct ifnet *ifp;
 	struct ifmultiaddr *ifma;
 	uint32_t hashes[2] = { 0, 0 };
+	uint8_t rxcfg;
 	int h;
 
+	STE_LOCK_ASSERT(sc);
+
 	ifp = sc->ste_ifp;
-	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
-		STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_ALLMULTI);
-		STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_MULTIHASH);
-		return;
+	rxcfg = CSR_READ_1(sc, STE_RX_MODE);
+	rxcfg |= STE_RXMODE_UNICAST;
+	rxcfg &= ~(STE_RXMODE_ALLMULTI | STE_RXMODE_MULTIHASH |
+	    STE_RXMODE_BROADCAST | STE_RXMODE_PROMISC);
+	if (ifp->if_flags & IFF_BROADCAST)
+		rxcfg |= STE_RXMODE_BROADCAST;
+	if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
+		if ((ifp->if_flags & IFF_ALLMULTI) != 0)
+			rxcfg |= STE_RXMODE_ALLMULTI;
+		if ((ifp->if_flags & IFF_PROMISC) != 0)
+			rxcfg |= STE_RXMODE_PROMISC;
+		goto chipit;
 	}
 
-	/* first, zot all the existing hash bits */
-	CSR_WRITE_2(sc, STE_MAR0, 0);
-	CSR_WRITE_2(sc, STE_MAR1, 0);
-	CSR_WRITE_2(sc, STE_MAR2, 0);
-	CSR_WRITE_2(sc, STE_MAR3, 0);
-
-	/* now program new ones */
+	rxcfg |= STE_RXMODE_MULTIHASH;
+	/* Now program new ones. */
 	if_maddr_rlock(ifp);
 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
 		if (ifma->ifma_addr->sa_family != AF_LINK)
@@ -597,12 +598,13 @@ ste_setmulti(struct ste_softc *sc)
 	}
 	if_maddr_runlock(ifp);
 
+chipit:
 	CSR_WRITE_2(sc, STE_MAR0, hashes[0] & 0xFFFF);
 	CSR_WRITE_2(sc, STE_MAR1, (hashes[0] >> 16) & 0xFFFF);
 	CSR_WRITE_2(sc, STE_MAR2, hashes[1] & 0xFFFF);
 	CSR_WRITE_2(sc, STE_MAR3, (hashes[1] >> 16) & 0xFFFF);
-	STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_ALLMULTI);
-	STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_MULTIHASH);
+	CSR_WRITE_1(sc, STE_RX_MODE, rxcfg);
+	CSR_READ_1(sc, STE_RX_MODE);
 }
 
 #ifdef DEVICE_POLLING
@@ -643,8 +645,10 @@ ste_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 		if (status & STE_ISR_STATS_OFLOW)
 			ste_stats_update(sc);
 
-		if (status & STE_ISR_HOSTERR)
+		if (status & STE_ISR_HOSTERR) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			ste_init_locked(sc);
+		}
 	}
 	return (rx_npkts);
 }
@@ -692,8 +696,10 @@ ste_intr(void *xsc)
 		if (status & STE_ISR_STATS_OFLOW)
 			ste_stats_update(sc);
 
-		if (status & STE_ISR_HOSTERR)
+		if (status & STE_ISR_HOSTERR) {
 			ste_init_locked(sc);
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+		}
 	}
 
 	/* Re-enable interrupts */
@@ -832,6 +838,7 @@ ste_txeoc(struct ste_softc *sc)
 				STE_SETBIT4(sc, STE_DMACTL,
 				    STE_DMACTL_TXDMA_STALL);
 				ste_wait(sc);
+				ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 				ste_init_locked(sc);
 				break;
 			}
@@ -870,6 +877,13 @@ ste_tick(void *arg)
 	 */
 	if ((sc->ste_flags & STE_FLAG_LINK) == 0)
 		ste_miibus_statchg(sc->ste_dev);
+	/*
+	 * Because we are not generating Tx completion
+	 * interrupt for every frame, reclaim transmitted
+	 * buffers here.
+	 */
+	ste_txeof(sc);
+	ste_txeoc(sc);
 	ste_stats_update(sc);
 	ste_watchdog(sc);
 	callout_reset(&sc->ste_callout, hz, ste_tick, sc);
@@ -917,17 +931,75 @@ ste_txeof(struct ste_softc *sc)
 		sc->ste_timer = 0;
 }
 
+static void
+ste_stats_clear(struct ste_softc *sc)
+{
+
+	STE_LOCK_ASSERT(sc);
+
+	/* Rx stats. */
+	CSR_READ_2(sc, STE_STAT_RX_OCTETS_LO);
+	CSR_READ_2(sc, STE_STAT_RX_OCTETS_HI);
+	CSR_READ_2(sc, STE_STAT_RX_FRAMES);
+	CSR_READ_1(sc, STE_STAT_RX_BCAST);
+	CSR_READ_1(sc, STE_STAT_RX_MCAST);
+	CSR_READ_1(sc, STE_STAT_RX_LOST);
+	/* Tx stats. */
+	CSR_READ_2(sc, STE_STAT_TX_OCTETS_LO);
+	CSR_READ_2(sc, STE_STAT_TX_OCTETS_HI);
+	CSR_READ_2(sc, STE_STAT_TX_FRAMES);
+	CSR_READ_1(sc, STE_STAT_TX_BCAST);
+	CSR_READ_1(sc, STE_STAT_TX_MCAST);
+	CSR_READ_1(sc, STE_STAT_CARRIER_ERR);
+	CSR_READ_1(sc, STE_STAT_SINGLE_COLLS);
+	CSR_READ_1(sc, STE_STAT_MULTI_COLLS);
+	CSR_READ_1(sc, STE_STAT_LATE_COLLS);
+	CSR_READ_1(sc, STE_STAT_TX_DEFER);
+	CSR_READ_1(sc, STE_STAT_TX_EXDEFER);
+	CSR_READ_1(sc, STE_STAT_TX_ABORT);
+}
+
 static void
 ste_stats_update(struct ste_softc *sc)
 {
 	struct ifnet *ifp;
+	struct ste_hw_stats *stats;
+	uint32_t val;
 
 	STE_LOCK_ASSERT(sc);
 
 	ifp = sc->ste_ifp;
-	ifp->if_collisions += CSR_READ_1(sc, STE_LATE_COLLS)
-	    + CSR_READ_1(sc, STE_MULTI_COLLS)
-	    + CSR_READ_1(sc, STE_SINGLE_COLLS);
+	stats = &sc->ste_stats;
+	/* Rx stats. */
+	val = (uint32_t)CSR_READ_2(sc, STE_STAT_RX_OCTETS_LO) |
+	    ((uint32_t)CSR_READ_2(sc, STE_STAT_RX_OCTETS_HI)) << 16;
+	val &= 0x000FFFFF;
+	stats->rx_bytes += val;
+	stats->rx_frames += CSR_READ_2(sc, STE_STAT_RX_FRAMES);
+	stats->rx_bcast_frames += CSR_READ_1(sc, STE_STAT_RX_BCAST);
+	stats->rx_mcast_frames += CSR_READ_1(sc, STE_STAT_RX_MCAST);
+	stats->rx_lost_frames += CSR_READ_1(sc, STE_STAT_RX_LOST);
+	/* Tx stats. */
+	val = (uint32_t)CSR_READ_2(sc, STE_STAT_TX_OCTETS_LO) |
+	    ((uint32_t)CSR_READ_2(sc, STE_STAT_TX_OCTETS_HI)) << 16;
+	val &= 0x000FFFFF;
+	stats->tx_bytes += val;
+	stats->tx_frames += CSR_READ_2(sc, STE_STAT_TX_FRAMES);
+	stats->tx_bcast_frames += CSR_READ_1(sc, STE_STAT_TX_BCAST);
+	stats->tx_mcast_frames += CSR_READ_1(sc, STE_STAT_TX_MCAST);
+	stats->tx_carrsense_errs += CSR_READ_1(sc, STE_STAT_CARRIER_ERR);
+	val = CSR_READ_1(sc, STE_STAT_SINGLE_COLLS);
+	stats->tx_single_colls += val;
+	ifp->if_collisions += val;
+	val = CSR_READ_1(sc, STE_STAT_MULTI_COLLS);
+	stats->tx_multi_colls += val;
+	ifp->if_collisions += val;
+	val += CSR_READ_1(sc, STE_STAT_LATE_COLLS);
+	stats->tx_late_colls += val;
+	ifp->if_collisions += val;
+	stats->tx_frames_defered += CSR_READ_1(sc, STE_STAT_TX_DEFER);
+	stats->tx_excess_defers += CSR_READ_1(sc, STE_STAT_TX_EXDEFER);
+	stats->tx_abort += CSR_READ_1(sc, STE_STAT_TX_ABORT);
 }
 
 /*
@@ -1027,6 +1099,7 @@ ste_attach(device_t dev)
 		error = ENXIO;;
 		goto fail;
 	}
+	ste_sysctl_node(sc);
 
 	if ((error = ste_dma_alloc(sc)) != 0)
 		goto fail;
@@ -1543,10 +1616,15 @@ static void
 ste_init_locked(struct ste_softc *sc)
 {
 	struct ifnet *ifp;
+	struct mii_data *mii;
 	int i;
 
 	STE_LOCK_ASSERT(sc);
 	ifp = sc->ste_ifp;
+	mii = device_get_softc(sc->ste_miibus);
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		return;
 
 	ste_stop(sc);
 	/* Reset the chip to a known state. */
@@ -1582,24 +1660,11 @@ ste_init_locked(struct ste_softc *sc)
 	/* Set the TX reclaim threshold. */
 	CSR_WRITE_1(sc, STE_TX_RECLAIM_THRESH, (STE_PACKET_SIZE >> 4));
 
+	/* Accept VLAN length packets */
+	CSR_WRITE_2(sc, STE_MAX_FRAMELEN, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
+
 	/* Set up the RX filter. */
-	CSR_WRITE_1(sc, STE_RX_MODE, STE_RXMODE_UNICAST);
-
-	/* If we want promiscuous mode, set the allframes bit. */
-	if (ifp->if_flags & IFF_PROMISC) {
-		STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_PROMISC);
-	} else {
-		STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_PROMISC);
-	}
-
-	/* Set capture broadcast bit to accept broadcast frames. */
-	if (ifp->if_flags & IFF_BROADCAST) {
-		STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_BROADCAST);
-	} else {
-		STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_BROADCAST);
-	}
-
-	ste_setmulti(sc);
+	ste_rxfilter(sc);
 
 	/* Load the address of the RX list. */
 	STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_RXDMA_STALL);
@@ -1628,6 +1693,8 @@ ste_init_locked(struct ste_softc *sc)
 
 	/* Enable stats counters. */
 	STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_STATS_ENABLE);
+	/* Clear stats counters. */
+	ste_stats_clear(sc);
 
 	CSR_WRITE_2(sc, STE_ISR, 0xFFFF);
 #ifdef DEVICE_POLLING
@@ -1639,10 +1706,9 @@ ste_init_locked(struct ste_softc *sc)
 	/* Enable interrupts. */
 	CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
 
-	/* Accept VLAN length packets */
-	CSR_WRITE_2(sc, STE_MAX_FRAMELEN, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
-
-	ste_ifmedia_upd_locked(ifp);
+	sc->ste_flags &= ~STE_FLAG_LINK;
+	/* Switch to the current media. */
+	mii_mediachg(mii);
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
@@ -1723,20 +1789,27 @@ ste_stop(struct ste_softc *sc)
 static void
 ste_reset(struct ste_softc *sc)
 {
+	uint32_t ctl;
 	int i;
 
-	STE_SETBIT4(sc, STE_ASICCTL,
-	    STE_ASICCTL_GLOBAL_RESET|STE_ASICCTL_RX_RESET|
-	    STE_ASICCTL_TX_RESET|STE_ASICCTL_DMA_RESET|
-	    STE_ASICCTL_FIFO_RESET|STE_ASICCTL_NETWORK_RESET|
-	    STE_ASICCTL_AUTOINIT_RESET|STE_ASICCTL_HOST_RESET|
-	    STE_ASICCTL_EXTRESET_RESET);
-
-	DELAY(100000);
+	ctl = CSR_READ_4(sc, STE_ASICCTL);
+	ctl |= STE_ASICCTL_GLOBAL_RESET | STE_ASICCTL_RX_RESET |
+	    STE_ASICCTL_TX_RESET | STE_ASICCTL_DMA_RESET |
+	    STE_ASICCTL_FIFO_RESET | STE_ASICCTL_NETWORK_RESET |
+	    STE_ASICCTL_AUTOINIT_RESET |STE_ASICCTL_HOST_RESET |
+	    STE_ASICCTL_EXTRESET_RESET;
+	CSR_WRITE_4(sc, STE_ASICCTL, ctl);
+	CSR_READ_4(sc, STE_ASICCTL);
+	/*
+	 * Due to the need of accessing EEPROM controller can take
+	 * up to 1ms to complete the global reset.
+	 */
+	DELAY(1000);
 
 	for (i = 0; i < STE_TIMEOUT; i++) {
 		if (!(CSR_READ_4(sc, STE_ASICCTL) & STE_ASICCTL_RESET_BUSY))
 			break;
+		DELAY(10);
 	}
 
 	if (i == STE_TIMEOUT)
@@ -1777,39 +1850,24 @@ ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 	switch (command) {
 	case SIOCSIFFLAGS:
 		STE_LOCK(sc);
-		if (ifp->if_flags & IFF_UP) {
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
-			    ifp->if_flags & IFF_PROMISC &&
-			    !(sc->ste_if_flags & IFF_PROMISC)) {
-				STE_SETBIT1(sc, STE_RX_MODE,
-				    STE_RXMODE_PROMISC);
-			} else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
-			    !(ifp->if_flags & IFF_PROMISC) &&
-			    sc->ste_if_flags & IFF_PROMISC) {
-				STE_CLRBIT1(sc, STE_RX_MODE,
-				    STE_RXMODE_PROMISC);
-			}
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
-			    (ifp->if_flags ^ sc->ste_if_flags) & IFF_ALLMULTI)
-				ste_setmulti(sc);
-			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-				sc->ste_tx_thresh = STE_TXSTART_THRESH;
+		if ((ifp->if_flags & IFF_UP) != 0) {
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
+			    ((ifp->if_flags ^ sc->ste_if_flags) &
+			     (IFF_PROMISC | IFF_ALLMULTI)) != 0)
+				ste_rxfilter(sc);
+			else
 				ste_init_locked(sc);
-			}
-		} else {
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-				ste_stop(sc);
-		}
+		} else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+			ste_stop(sc);
 		sc->ste_if_flags = ifp->if_flags;
 		STE_UNLOCK(sc);
-		error = 0;
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		STE_LOCK(sc);
-		ste_setmulti(sc);
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+			ste_rxfilter(sc);
 		STE_UNLOCK(sc);
-		error = 0;
 		break;
 	case SIOCGIFMEDIA:
 	case SIOCSIFMEDIA:
@@ -1902,7 +1960,11 @@ ste_encap(struct ste_softc *sc, struct mbuf **m_head, struct ste_chain *txc)
 	 * Tx descriptors here. Otherwise we race with controller.
 	 */
 	desc->ste_next = 0;
-	desc->ste_ctl = htole32(STE_TXCTL_ALIGN_DIS | STE_TXCTL_DMAINTR);
+	if ((sc->ste_cdata.ste_tx_prod % STE_TX_INTR_FRAMES) == 0)
+		desc->ste_ctl = htole32(STE_TXCTL_ALIGN_DIS |
+		    STE_TXCTL_DMAINTR);
+	else
+		desc->ste_ctl = htole32(STE_TXCTL_ALIGN_DIS);
 	txc->ste_mbuf = *m_head;
 	STE_INC(sc->ste_cdata.ste_tx_prod, STE_TX_LIST_CNT);
 	sc->ste_cdata.ste_tx_cnt++;
@@ -2005,6 +2067,7 @@ ste_watchdog(struct ste_softc *sc)
 	ste_txeof(sc);
 	ste_txeoc(sc);
 	ste_rxeof(sc, -1);
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	ste_init_locked(sc);
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
@@ -2024,3 +2087,70 @@ ste_shutdown(device_t dev)
 
 	return (0);
 }
+
+#define	STE_SYSCTL_STAT_ADD32(c, h, n, p, d)	\
+	    SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
+#define	STE_SYSCTL_STAT_ADD64(c, h, n, p, d)	\
+	    SYSCTL_ADD_QUAD(c, h, OID_AUTO, n, CTLFLAG_RD, p, d)
+
+static void
+ste_sysctl_node(struct ste_softc *sc)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid_list *child, *parent;
+	struct sysctl_oid *tree;
+	struct ste_hw_stats *stats;
+
+	stats = &sc->ste_stats;
+	ctx = device_get_sysctl_ctx(sc->ste_dev);
+	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->ste_dev));
+
+	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
+	    NULL, "STE statistics");
+	parent = SYSCTL_CHILDREN(tree);
+
+	/* Rx statistics. */
+	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "rx", CTLFLAG_RD,
+	    NULL, "Rx MAC statistics");
+	child = SYSCTL_CHILDREN(tree);
+	STE_SYSCTL_STAT_ADD64(ctx, child, "good_octets",
+	    &stats->rx_bytes, "Good octets");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
+	    &stats->rx_frames, "Good frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_bcast_frames",
+	    &stats->rx_bcast_frames, "Good broadcast frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_mcast_frames",
+	    &stats->rx_mcast_frames, "Good multicast frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "lost_frames",
+	    &stats->rx_lost_frames, "Lost frames");
+
+	/* Tx statistics. */
+	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
+	    NULL, "Tx MAC statistics");
+	child = SYSCTL_CHILDREN(tree);
+	STE_SYSCTL_STAT_ADD64(ctx, child, "good_octets",
+	    &stats->tx_bytes, "Good octets");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
+	    &stats->tx_frames, "Good frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_bcast_frames",
+	    &stats->tx_bcast_frames, "Good broadcast frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_mcast_frames",
+	    &stats->tx_mcast_frames, "Good multicast frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "carrier_errs",
+	    &stats->tx_carrsense_errs, "Carrier sense errors");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "single_colls",
+	    &stats->tx_single_colls, "Single collisions");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "multi_colls",
+	    &stats->tx_multi_colls, "Multiple collisions");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "late_colls",
+	    &stats->tx_late_colls, "Late collisions");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "defers",
+	    &stats->tx_frames_defered, "Frames with deferrals");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "excess_defers",
+	    &stats->tx_excess_defers, "Frames with excessive derferrals");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "abort",
+	    &stats->tx_abort, "Aborted frames due to Excessive collisions");
+}
+
+#undef STE_SYSCTL_STAT_ADD32
+#undef STE_SYSCTL_STAT_ADD64
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index 4ec1920f4cf..db0d2e7f92d 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -63,6 +63,7 @@
 #define STE_RX_DMABURST_THRESH	0x14
 #define STE_RX_DMAURG_THRESH	0x15
 #define STE_RX_DMAPOLL_PERIOD	0x16
+#define	STE_COUNTDOWN		0x18
 #define STE_DEBUGCTL		0x1A
 #define STE_ASICCTL		0x30
 #define STE_EEPROM_DATA		0x34
@@ -75,7 +76,6 @@
 #define STE_WAKE_EVENT		0x45
 #define STE_TX_STATUS		0x46
 #define STE_TX_FRAMEID		0x47
-#define STE_COUNTDOWN		0x48
 #define STE_ISR_ACK		0x4A
 #define STE_IMR			0x4C
 #define STE_ISR			0x4E
@@ -92,11 +92,25 @@
 #define STE_MAR1		0x62
 #define STE_MAR2		0x64
 #define STE_MAR3		0x66
-#define STE_STATS		0x68
 
-#define STE_LATE_COLLS  0x75
-#define STE_MULTI_COLLS	0x76
-#define STE_SINGLE_COLLS 0x77
+#define	STE_STAT_RX_OCTETS_LO	0x68
+#define	STE_STAT_RX_OCTETS_HI	0x6A
+#define	STE_STAT_TX_OCTETS_LO	0x6C
+#define	STE_STAT_TX_OCTETS_HI	0x6E
+#define	STE_STAT_TX_FRAMES	0x70
+#define	STE_STAT_RX_FRAMES	0x72
+#define	STE_STAT_CARRIER_ERR	0x74
+#define	STE_STAT_LATE_COLLS	0x75
+#define	STE_STAT_MULTI_COLLS	0x76
+#define	STE_STAT_SINGLE_COLLS	0x77
+#define	STE_STAT_TX_DEFER	0x78
+#define	STE_STAT_RX_LOST	0x79
+#define	STE_STAT_TX_EXDEFER	0x7A
+#define	STE_STAT_TX_ABORT	0x7B
+#define	STE_STAT_TX_BCAST	0x7C
+#define	STE_STAT_RX_BCAST	0x7D
+#define	STE_STAT_TX_MCAST	0x7E
+#define	STE_STAT_RX_MCAST	0x7F
 
 #define STE_DMACTL_RXDMA_STOPPED	0x00000001
 #define STE_DMACTL_TXDMA_CMPREQ		0x00000002
@@ -199,18 +213,6 @@
 #define STE_ASICCTL_SOFTINTR		0x02000000
 #define STE_ASICCTL_RESET_BUSY		0x04000000
 
-#define STE_ASICCTL1_GLOBAL_RESET	0x0001
-#define STE_ASICCTL1_RX_RESET		0x0002
-#define STE_ASICCTL1_TX_RESET		0x0004
-#define STE_ASICCTL1_DMA_RESET		0x0008
-#define STE_ASICCTL1_FIFO_RESET		0x0010
-#define STE_ASICCTL1_NETWORK_RESET	0x0020
-#define STE_ASICCTL1_HOST_RESET		0x0040
-#define STE_ASICCTL1_AUTOINIT_RESET	0x0080
-#define STE_ASICCTL1_EXTRESET_RESET	0x0100
-#define STE_ASICCTL1_SOFTINTR		0x0200
-#define STE_ASICCTL1_RESET_BUSY		0x0400
-
 #define STE_EECTL_ADDR			0x00FF
 #define STE_EECTL_OPCODE		0x0300
 #define STE_EECTL_BUSY			0x1000
@@ -388,24 +390,23 @@
 #define STE_PME_EN			0x0010
 #define STE_PME_STATUS			0x8000
 
-
-struct ste_stats {
-	uint32_t		ste_rx_bytes;
-	uint32_t		ste_tx_bytes;
-	uint16_t		ste_tx_frames;
-	uint16_t		ste_rx_frames;
-	uint8_t			ste_carrsense_errs;
-	uint8_t			ste_late_colls;
-	uint8_t			ste_multi_colls;
-	uint8_t			ste_single_colls;
-	uint8_t			ste_tx_frames_defered;
-	uint8_t			ste_rx_lost_frames;
-	uint8_t			ste_tx_excess_defers;
-	uint8_t			ste_tx_abort_excess_colls;
-	uint8_t			ste_tx_bcast_frames;
-	uint8_t			ste_rx_bcast_frames;
-	uint8_t			ste_tx_mcast_frames;
-	uint8_t			ste_rx_mcast_frames;
+struct ste_hw_stats {
+	uint64_t		rx_bytes;
+	uint32_t		rx_frames;
+	uint32_t		rx_bcast_frames;
+	uint32_t		rx_mcast_frames;
+	uint32_t		rx_lost_frames;
+	uint64_t		tx_bytes;
+	uint32_t		tx_frames;
+	uint32_t		tx_bcast_frames;
+	uint32_t		tx_mcast_frames;
+	uint32_t		tx_carrsense_errs;
+	uint32_t		tx_single_colls;
+	uint32_t		tx_multi_colls;
+	uint32_t		tx_late_colls;
+	uint32_t		tx_frames_defered;
+	uint32_t		tx_excess_defers;
+	uint32_t		tx_abort;
 };
 
 struct ste_frag {
@@ -493,6 +494,12 @@ struct ste_desc_onefrag {
 #define	STE_ADDR_LO(x)		((uint64_t)(x) & 0xFFFFFFFF)
 #define	STE_ADDR_HI(x)		((uint64_t)(x) >> 32)
 
+/*
+ * Since Tx status can hold up to 31 status bytes we should
+ * check Tx status before controller fills it up. Otherwise
+ * Tx MAC stalls.
+ */
+#define	STE_TX_INTR_FRAMES	16
 #define	STE_TX_TIMEOUT		5
 #define STE_TIMEOUT		1000
 #define STE_MIN_FRAMELEN	60
@@ -566,6 +573,7 @@ struct ste_softc {
 	struct ste_list_data	ste_ldata;
 	struct ste_chain_data	ste_cdata;
 	struct callout		ste_callout;
+	struct ste_hw_stats	ste_stats;
 	struct mtx		ste_mtx;
 };
 

From 6b15d2af78987c6e8f4371ae294c4a56ae85aa13 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 14 Jan 2010 22:26:52 +0000
Subject: [PATCH 1125/2592] MFC r200950,200955,200965-200966,201767-201768

r200950:
  Implement RX interrupt moderation using one-shot timer interrupt.
  Unlike TX interrupt, ST201 does not provide any mechanism to
  suppress RX interrupts. ste(4) can generate more than 70k RX
  interrupts under heavy RX traffics such that these excessive
  interrupts make system useless to process other useful things.
  Maybe this was the major reason why polling support code was
  introduced to ste(4).
  The STE_COUNTDOWN register provides a programmable counter that
  will generate an interrupt upon its expiration. We program
  STE_DMACTL register to use 3.2us clock rate to drive the counter
  register. Whenever ste(4) serves RX interrupt, the driver rearm
  the timer to expire after STE_IM_RX_TIMER_DEFAULT time and disables
  further generation of RX interrupts. This trick seems to work well
  and ste(4) generates less than 8k RX interrupts even under 64 bytes
  UDP torture test. Combined with TX interrupts, the total number of
  interrupts are less than 10k which looks reasonable on heavily
  loaded controller.

  The default RX interrupt moderation time is 150us. Users can change
  the value at any time with dev.ste.%d.int_rx_mod sysctl node.
  Setting it 0 effectively disables the RX interrupt moderation
  feature. Now we have both TX/RX interrupt moderation code so remove
  loop of interrupt handler which resulted in sub-optimal performance
  as well as more register accesses.

r200955:
  Add suspend/resume support as well as basic WOL.
  While I'm here simplify SIOCSIFCAP handler.

r200965:
  Update if_iqdrops in case of RX buffer allocation failure.

r200966:
  ether_ifattach sets if_mtu, remove unnecessary code.

r201767:
  Fix EEPROM access code to return data in host byte order.
  EEPROM on ST201 always returns 16bits data with little endian
  format so conversion to host order is required.
  This change fixes inversed ethernet address on sparc64.

r201768:
  Make sure to store dma address of RX buffer in little endian form.
  This fixes the last bug which keeps ste(4) from working on sparc64.
---
 sys/dev/ste/if_ste.c    | 264 +++++++++++++++++++++++++++++-----------
 sys/dev/ste/if_stereg.h |  12 +-
 2 files changed, 201 insertions(+), 75 deletions(-)

diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c
index 8c8b121ff1d..3fd43187c7c 100644
--- a/sys/dev/ste/if_ste.c
+++ b/sys/dev/ste/if_ste.c
@@ -94,7 +94,9 @@ static struct ste_type ste_devs[] = {
 static int	ste_attach(device_t);
 static int	ste_detach(device_t);
 static int	ste_probe(device_t);
+static int	ste_resume(device_t);
 static int	ste_shutdown(device_t);
+static int	ste_suspend(device_t);
 
 static int	ste_dma_alloc(struct ste_softc *);
 static void	ste_dma_free(struct ste_softc *);
@@ -118,11 +120,12 @@ static int	ste_miibus_readreg(device_t, int, int);
 static void	ste_miibus_statchg(device_t);
 static int	ste_miibus_writereg(device_t, int, int, int);
 static int	ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *);
-static int	ste_read_eeprom(struct ste_softc *, caddr_t, int, int, int);
+static int	ste_read_eeprom(struct ste_softc *, uint16_t *, int, int);
 static void	ste_reset(struct ste_softc *);
 static void	ste_restart_tx(struct ste_softc *);
 static int	ste_rxeof(struct ste_softc *, int);
 static void	ste_rxfilter(struct ste_softc *);
+static void	ste_setwol(struct ste_softc *);
 static void	ste_start(struct ifnet *);
 static void	ste_start_locked(struct ifnet *);
 static void	ste_stats_clear(struct ste_softc *);
@@ -141,6 +144,8 @@ static device_method_t ste_methods[] = {
 	DEVMETHOD(device_attach,	ste_attach),
 	DEVMETHOD(device_detach,	ste_detach),
 	DEVMETHOD(device_shutdown,	ste_shutdown),
+	DEVMETHOD(device_suspend,	ste_suspend),
+	DEVMETHOD(device_resume,	ste_resume),
 
 	/* bus interface */
 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
@@ -533,9 +538,8 @@ ste_eeprom_wait(struct ste_softc *sc)
  * data is stored in the EEPROM in network byte order.
  */
 static int
-ste_read_eeprom(struct ste_softc *sc, caddr_t dest, int off, int cnt, int swap)
+ste_read_eeprom(struct ste_softc *sc, uint16_t *dest, int off, int cnt)
 {
-	uint16_t word, *ptr;
 	int err = 0, i;
 
 	if (ste_eeprom_wait(sc))
@@ -546,12 +550,8 @@ ste_read_eeprom(struct ste_softc *sc, caddr_t dest, int off, int cnt, int swap)
 		err = ste_eeprom_wait(sc);
 		if (err)
 			break;
-		word = CSR_READ_2(sc, STE_EEPROM_DATA);
-		ptr = (uint16_t *)(dest + (i * 2));
-		if (swap)
-			*ptr = ntohs(word);
-		else
-			*ptr = word;
+		*dest = le16toh(CSR_READ_2(sc, STE_EEPROM_DATA));
+		dest++;
 	}
 
 	return (err ? 1 : 0);
@@ -659,7 +659,7 @@ ste_intr(void *xsc)
 {
 	struct ste_softc *sc;
 	struct ifnet *ifp;
-	uint16_t status;
+	uint16_t intrs, status;
 
 	sc = xsc;
 	STE_LOCK(sc);
@@ -671,43 +671,67 @@ ste_intr(void *xsc)
 		return;
 	}
 #endif
-
-	/* See if this is really our interrupt. */
-	if (!(CSR_READ_2(sc, STE_ISR) & STE_ISR_INTLATCH)) {
+	/* Reading STE_ISR_ACK clears STE_IMR register. */
+	status = CSR_READ_2(sc, STE_ISR_ACK);
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 		STE_UNLOCK(sc);
 		return;
 	}
 
-	for (;;) {
-		status = CSR_READ_2(sc, STE_ISR_ACK);
+	intrs = STE_INTRS;
+	if (status == 0xFFFF || (status & intrs) == 0)
+		goto done;
 
-		if (!(status & STE_INTRS))
-			break;
-
-		if (status & STE_ISR_RX_DMADONE)
-			ste_rxeof(sc, -1);
-
-		if (status & STE_ISR_TX_DMADONE)
-			ste_txeof(sc);
-
-		if (status & STE_ISR_TX_DONE)
-			ste_txeoc(sc);
-
-		if (status & STE_ISR_STATS_OFLOW)
-			ste_stats_update(sc);
-
-		if (status & STE_ISR_HOSTERR) {
-			ste_init_locked(sc);
-			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-		}
+	if (sc->ste_int_rx_act > 0) {
+		status &= ~STE_ISR_RX_DMADONE;
+		intrs &= ~STE_IMR_RX_DMADONE;
 	}
 
-	/* Re-enable interrupts */
-	CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
-
-	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		ste_start_locked(ifp);
-
+	if ((status & (STE_ISR_SOFTINTR | STE_ISR_RX_DMADONE)) != 0) {
+		ste_rxeof(sc, -1);
+		/*
+		 * The controller has no ability to Rx interrupt
+		 * moderation feature. Receiving 64 bytes frames
+		 * from wire generates too many interrupts which in
+		 * turn make system useless to process other useful
+		 * things. Fortunately ST201 supports single shot
+		 * timer so use the timer to implement Rx interrupt
+		 * moderation in driver. This adds more register
+		 * access but it greatly reduces number of Rx
+		 * interrupts under high network load.
+		 */
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
+		    (sc->ste_int_rx_mod != 0)) {
+			if ((status & STE_ISR_RX_DMADONE) != 0) {
+				CSR_WRITE_2(sc, STE_COUNTDOWN,
+				    STE_TIMER_USECS(sc->ste_int_rx_mod));
+				intrs &= ~STE_IMR_RX_DMADONE;
+				sc->ste_int_rx_act = 1;
+			} else {
+				intrs |= STE_IMR_RX_DMADONE;
+				sc->ste_int_rx_act = 0;
+			}
+		}
+	}
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+		if ((status & STE_ISR_TX_DMADONE) != 0)
+			ste_txeof(sc);
+		if ((status & STE_ISR_TX_DONE) != 0)
+			ste_txeoc(sc);
+		if ((status & STE_ISR_STATS_OFLOW) != 0)
+			ste_stats_update(sc);
+		if ((status & STE_ISR_HOSTERR) != 0) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+			ste_init_locked(sc);
+			STE_UNLOCK(sc);
+			return;
+		}
+		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+			ste_start_locked(ifp);
+done:
+		/* Re-enable interrupts */
+		CSR_WRITE_2(sc, STE_IMR, intrs);
+	}
 	STE_UNLOCK(sc);
 }
 
@@ -769,7 +793,7 @@ ste_rxeof(struct ste_softc *sc, int count)
 		 * can do in this situation.
 		 */
 		if (ste_newbuf(sc, cur_rx) != 0) {
-			ifp->if_ierrors++;
+			ifp->if_iqdrops++;
 			cur_rx->ste_ptr->ste_status = 0;
 			continue;
 		}
@@ -1034,8 +1058,8 @@ ste_attach(device_t dev)
 {
 	struct ste_softc *sc;
 	struct ifnet *ifp;
-	u_char eaddr[6];
-	int error = 0, rid;
+	uint16_t eaddr[ETHER_ADDR_LEN / 2];
+	int error = 0, pmc, rid;
 
 	sc = device_get_softc(dev);
 	sc->ste_dev = dev;
@@ -1093,8 +1117,7 @@ ste_attach(device_t dev)
 	/*
 	 * Get station address from the EEPROM.
 	 */
-	if (ste_read_eeprom(sc, eaddr,
-	    STE_EEADDR_NODE0, 3, 0)) {
+	if (ste_read_eeprom(sc, eaddr, STE_EEADDR_NODE0, ETHER_ADDR_LEN / 2)) {
 		device_printf(dev, "failed to read station address\n");
 		error = ENXIO;;
 		goto fail;
@@ -1121,7 +1144,6 @@ ste_attach(device_t dev)
 
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-	ifp->if_mtu = ETHERMTU;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = ste_ioctl;
 	ifp->if_start = ste_start;
@@ -1135,13 +1157,15 @@ ste_attach(device_t dev)
 	/*
 	 * Call MI attach routine.
 	 */
-	ether_ifattach(ifp, eaddr);
+	ether_ifattach(ifp, (uint8_t *)eaddr);
 
 	/*
 	 * Tell the upper layer(s) we support long frames.
 	 */
 	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
 	ifp->if_capabilities |= IFCAP_VLAN_MTU;
+	if (pci_find_extcap(dev, PCIY_PMG, &pmc) == 0)
+		ifp->if_capabilities |= IFCAP_WOL_MAGIC;
 	ifp->if_capenable = ifp->if_capabilities;
 #ifdef DEVICE_POLLING
 	ifp->if_capabilities |= IFCAP_POLLING;
@@ -1538,6 +1562,7 @@ ste_init_rx_list(struct ste_softc *sc)
 	struct ste_list_data *ld;
 	int error, i;
 
+	sc->ste_int_rx_act = 0;
 	cd = &sc->ste_cdata;
 	ld = &sc->ste_ldata;
 	bzero(ld->ste_rx_list, STE_RX_LIST_SZ);
@@ -1548,12 +1573,14 @@ ste_init_rx_list(struct ste_softc *sc)
 			return (error);
 		if (i == (STE_RX_LIST_CNT - 1)) {
 			cd->ste_rx_chain[i].ste_next = &cd->ste_rx_chain[0];
-			ld->ste_rx_list[i].ste_next = ld->ste_rx_list_paddr +
-			    (sizeof(struct ste_desc_onefrag) * 0);
+			ld->ste_rx_list[i].ste_next =
+			    htole32(ld->ste_rx_list_paddr +
+			    (sizeof(struct ste_desc_onefrag) * 0));
 		} else {
 			cd->ste_rx_chain[i].ste_next = &cd->ste_rx_chain[i + 1];
-			ld->ste_rx_list[i].ste_next = ld->ste_rx_list_paddr +
-			    (sizeof(struct ste_desc_onefrag) * (i + 1));
+			ld->ste_rx_list[i].ste_next =
+			    htole32(ld->ste_rx_list_paddr +
+			    (sizeof(struct ste_desc_onefrag) * (i + 1)));
 		}
 	}
 
@@ -1617,6 +1644,7 @@ ste_init_locked(struct ste_softc *sc)
 {
 	struct ifnet *ifp;
 	struct mii_data *mii;
+	uint8_t val;
 	int i;
 
 	STE_LOCK_ASSERT(sc);
@@ -1651,6 +1679,12 @@ ste_init_locked(struct ste_softc *sc)
 	/* Init TX descriptors */
 	ste_init_tx_list(sc);
 
+	/* Clear and disable WOL. */
+	val = CSR_READ_1(sc, STE_WAKE_EVENT);
+	val &= ~(STE_WAKEEVENT_WAKEPKT_ENB | STE_WAKEEVENT_MAGICPKT_ENB |
+	    STE_WAKEEVENT_LINKEVT_ENB | STE_WAKEEVENT_WAKEONLAN_ENB);
+	CSR_WRITE_1(sc, STE_WAKE_EVENT, val);
+
 	/* Set the TX freethresh value */
 	CSR_WRITE_1(sc, STE_TX_DMABURST_THRESH, STE_PACKET_SIZE >> 8);
 
@@ -1684,6 +1718,9 @@ ste_init_locked(struct ste_softc *sc)
 	STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_UNSTALL);
 	STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_TXDMA_UNSTALL);
 	ste_wait(sc);
+	/* Select 3.2us timer. */
+	STE_CLRBIT4(sc, STE_DMACTL, STE_DMACTL_COUNTDOWN_SPEED |
+	    STE_DMACTL_COUNTDOWN_MODE);
 
 	/* Enable receiver and transmitter */
 	CSR_WRITE_2(sc, STE_MACCTL0, 0);
@@ -1696,6 +1733,7 @@ ste_init_locked(struct ste_softc *sc)
 	/* Clear stats counters. */
 	ste_stats_clear(sc);
 
+	CSR_WRITE_2(sc, STE_COUNTDOWN, 0);
 	CSR_WRITE_2(sc, STE_ISR, 0xFFFF);
 #ifdef DEVICE_POLLING
 	/* Disable interrupts if we are polling. */
@@ -1733,6 +1771,7 @@ ste_stop(struct ste_softc *sc)
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING|IFF_DRV_OACTIVE);
 
 	CSR_WRITE_2(sc, STE_IMR, 0);
+	CSR_WRITE_2(sc, STE_COUNTDOWN, 0);
 	/* Stop pending DMA. */
 	val = CSR_READ_4(sc, STE_DMACTL);
 	val |= STE_DMACTL_TXDMA_STALL | STE_DMACTL_RXDMA_STALL;
@@ -1842,7 +1881,7 @@ ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 	struct ste_softc *sc;
 	struct ifreq *ifr;
 	struct mii_data *mii;
-	int error = 0;
+	int error = 0, mask;
 
 	sc = ifp->if_softc;
 	ifr = (struct ifreq *)data;
@@ -1875,31 +1914,31 @@ ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 		break;
 	case SIOCSIFCAP:
+		STE_LOCK(sc);
+		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 #ifdef DEVICE_POLLING
-		if (ifr->ifr_reqcap & IFCAP_POLLING &&
-		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(ste_poll, ifp);
-			if (error)
-				return (error);
-			STE_LOCK(sc);
-			/* Disable interrupts */
-			CSR_WRITE_2(sc, STE_IMR, 0);
-			ifp->if_capenable |= IFCAP_POLLING;
-			STE_UNLOCK(sc);
-			return (error);
-
-		}
-		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
-		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
-			/* Enable interrupts. */
-			STE_LOCK(sc);
-			CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
-			ifp->if_capenable &= ~IFCAP_POLLING;
-			STE_UNLOCK(sc);
-			return (error);
+		if ((mask & IFCAP_POLLING) != 0 &&
+		    (IFCAP_POLLING & ifp->if_capabilities) != 0) {
+			ifp->if_capenable ^= IFCAP_POLLING;
+			if ((IFCAP_POLLING & ifp->if_capenable) != 0) {
+				error = ether_poll_register(ste_poll, ifp);
+				if (error != 0) {
+					STE_UNLOCK(sc);
+					break;
+				}
+				/* Disable interrupts. */
+				CSR_WRITE_2(sc, STE_IMR, 0);
+			} else {
+				error = ether_poll_deregister(ifp);
+				/* Enable interrupts. */
+				CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
+			}
 		}
 #endif /* DEVICE_POLLING */
+		if ((mask & IFCAP_WOL_MAGIC) != 0 &&
+		    (ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0)
+			ifp->if_capenable ^= IFCAP_WOL_MAGIC;
+		STE_UNLOCK(sc);
 		break;
 	default:
 		error = ether_ioctl(ifp, command, data);
@@ -2076,6 +2115,13 @@ ste_watchdog(struct ste_softc *sc)
 
 static int
 ste_shutdown(device_t dev)
+{
+
+	return (ste_suspend(dev));
+}
+
+static int
+ste_suspend(device_t dev)
 {
 	struct ste_softc *sc;
 
@@ -2083,6 +2129,37 @@ ste_shutdown(device_t dev)
 
 	STE_LOCK(sc);
 	ste_stop(sc);
+	ste_setwol(sc);
+	STE_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+ste_resume(device_t dev)
+{
+	struct ste_softc *sc;
+	struct ifnet *ifp;
+	int pmc;
+	uint16_t pmstat;
+
+	sc = device_get_softc(dev);
+	STE_LOCK(sc);
+	if (pci_find_extcap(sc->ste_dev, PCIY_PMG, &pmc) == 0) {
+		/* Disable PME and clear PME status. */
+		pmstat = pci_read_config(sc->ste_dev,
+		    pmc + PCIR_POWER_STATUS, 2);
+		if ((pmstat & PCIM_PSTAT_PMEENABLE) != 0) {
+			pmstat &= ~PCIM_PSTAT_PMEENABLE;
+			pci_write_config(sc->ste_dev,
+			    pmc + PCIR_POWER_STATUS, pmstat, 2);
+		}
+	}
+	ifp = sc->ste_ifp;
+	if ((ifp->if_flags & IFF_UP) != 0) {
+		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+		ste_init_locked(sc);
+	}
 	STE_UNLOCK(sc);
 
 	return (0);
@@ -2105,6 +2182,13 @@ ste_sysctl_node(struct ste_softc *sc)
 	ctx = device_get_sysctl_ctx(sc->ste_dev);
 	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->ste_dev));
 
+	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "int_rx_mod",
+	    CTLFLAG_RW, &sc->ste_int_rx_mod, 0, "ste RX interrupt moderation");
+	/* Pull in device tunables. */
+	sc->ste_int_rx_mod = STE_IM_RX_TIMER_DEFAULT;
+	resource_int_value(device_get_name(sc->ste_dev),
+	    device_get_unit(sc->ste_dev), "int_rx_mod", &sc->ste_int_rx_mod);
+
 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
 	    NULL, "STE statistics");
 	parent = SYSCTL_CHILDREN(tree);
@@ -2154,3 +2238,35 @@ ste_sysctl_node(struct ste_softc *sc)
 
 #undef STE_SYSCTL_STAT_ADD32
 #undef STE_SYSCTL_STAT_ADD64
+
+static void
+ste_setwol(struct ste_softc *sc)
+{
+	struct ifnet *ifp;
+	uint16_t pmstat;
+	uint8_t val;
+	int pmc;
+
+	STE_LOCK_ASSERT(sc);
+
+	if (pci_find_extcap(sc->ste_dev, PCIY_PMG, &pmc) != 0) {
+		/* Disable WOL. */
+		CSR_READ_1(sc, STE_WAKE_EVENT);
+		CSR_WRITE_1(sc, STE_WAKE_EVENT, 0);
+		return;
+	}
+
+	ifp = sc->ste_ifp;
+	val = CSR_READ_1(sc, STE_WAKE_EVENT);
+	val &= ~(STE_WAKEEVENT_WAKEPKT_ENB | STE_WAKEEVENT_MAGICPKT_ENB |
+	    STE_WAKEEVENT_LINKEVT_ENB | STE_WAKEEVENT_WAKEONLAN_ENB);
+	if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0)
+		val |= STE_WAKEEVENT_MAGICPKT_ENB | STE_WAKEEVENT_WAKEONLAN_ENB;
+	CSR_WRITE_1(sc, STE_WAKE_EVENT, val);
+	/* Request PME. */
+	pmstat = pci_read_config(sc->ste_dev, pmc + PCIR_POWER_STATUS, 2);
+	pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
+	if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0)
+		pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
+	pci_write_config(sc->ste_dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
+}
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index db0d2e7f92d..840e0bfada5 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -285,7 +285,8 @@
 
 #define STE_INTRS				\
 	(STE_IMR_RX_DMADONE|STE_IMR_TX_DMADONE|	\
-	STE_IMR_TX_DONE|STE_IMR_HOSTERR)
+	STE_IMR_TX_DONE|STE_IMR_SOFTINTR|	\
+	STE_IMR_HOSTERR)
 
 #define STE_ISR_INTLATCH		0x0001
 #define STE_ISR_HOSTERR			0x0002
@@ -349,6 +350,13 @@
 #define STE_PHYCTL_SPEEDSTAT		0x40
 #define STE_PHYCTL_LINKSTAT		0x80
 
+#define	STE_TIMER_TICKS			32
+#define	STE_TIMER_USECS(x)		((x * 10) / STE_TIMER_TICKS)
+
+#define	STE_IM_RX_TIMER_MIN		0
+#define	STE_IM_RX_TIMER_MAX		209712
+#define	STE_IM_RX_TIMER_DEFAULT		150
+
 /*
  * EEPROM offsets.
  */
@@ -570,6 +578,8 @@ struct ste_softc {
 #define	STE_FLAG_LINK		0x8000
 	int			ste_if_flags;
 	int			ste_timer;
+	int			ste_int_rx_act;
+	int			ste_int_rx_mod;
 	struct ste_list_data	ste_ldata;
 	struct ste_chain_data	ste_cdata;
 	struct callout		ste_callout;

From 33e6efefc15462b052615265240bab4310425fc1 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 14 Jan 2010 22:33:46 +0000
Subject: [PATCH 1126/2592] MFC r200958:   Document newly added loader
 tunable/sysctl variable   dev.ste.%d.int_rx_mod.   While I'm here add .Xr
 vlan as ste(4) supports long frames.

---
 share/man/man4/ste.4 | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/share/man/man4/ste.4 b/share/man/man4/ste.4
index 1e652df8df6..b5ea1abe777 100644
--- a/share/man/man4/ste.4
+++ b/share/man/man4/ste.4
@@ -30,7 +30,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 16, 2005
+.Dd December 24, 2009
 .Dt STE 4
 .Os
 .Sh NAME
@@ -126,6 +126,23 @@ D-Link DFE-550TX
 .It
 D-Link DFE-580TX
 .El
+.Sh SYSCTL VARIABLES
+The following variables are available as both
+.Xr sysctl 8
+variables and
+.Xr loader 8
+tunables:
+.Bl -tag -width "xxxxxx"
+.It Va dev.ste.%d.int_rx_mod
+Maximum number of time to delay RX interrupts.
+The valid range is 0 to 209712 in units of 1us, the default is
+150 (150us).
+The value 0 effectively disables the RX interrupt moderation.
+The resolution of of timer is about 3.2us so finer tuning than
+3.2us wouldn't be available.
+The interface does not need to be brought down and up again before
+a change takes effect.
+.El
 .Sh DIAGNOSTICS
 .Bl -diag
 .It "ste%d: couldn't map ports/memory"
@@ -171,6 +188,7 @@ the card should be configured correctly.
 .Xr netintro 4 ,
 .Xr ng_ether 4 ,
 .Xr polling 4 ,
+.Xr vlan 4 ,
 .Xr ifconfig 8
 .Rs
 .%T Sundance ST201 data sheet

From 073ffa6670c93bc4a7fed074bc0597d586847345 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 14 Jan 2010 22:36:06 +0000
Subject: [PATCH 1127/2592] MFC r201769:   Enable ste(4). ste(4) should work on
 all architectures.

---
 sys/sparc64/conf/GENERIC | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index 1b4a74c18cc..676493fc93c 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -181,7 +181,7 @@ device		rl		# RealTek 8129/8139
 device		sf		# Adaptec AIC-6915 (``Starfire'')
 #device		sis		# Silicon Integrated Systems SiS 900/SiS 7016
 device		sk		# SysKonnect SK-984x & SK-982x gigabit Ethernet
-#device		ste		# Sundance ST201 (D-Link DFE-550TX)
+device		ste		# Sundance ST201 (D-Link DFE-550TX)
 device		stge		# Sundance/Tamarack TC9021 gigabit Ethernet
 #device		tl		# Texas Instruments ThunderLAN
 #device		tx		# SMC EtherPower II (83c170 ``EPIC'')

From ede27ce6d06abbc2aa242a9b42ce0f3aac007e48 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Fri, 15 Jan 2010 02:18:07 +0000
Subject: [PATCH 1128/2592] MFC r201601: Remove more duplicates Minor
 reformatting on a few

---
 games/fortune/datfiles/fortunes | 233 ++------------------------------
 1 file changed, 14 insertions(+), 219 deletions(-)

diff --git a/games/fortune/datfiles/fortunes b/games/fortune/datfiles/fortunes
index 7458fdaac66..06ec724f958 100644
--- a/games/fortune/datfiles/fortunes
+++ b/games/fortune/datfiles/fortunes
@@ -1695,14 +1695,6 @@ the Cat.
 	"I don't care much where--" said Alice.
 	"Then it doesn't matter which way you go," said the Cat.
 		-- Lewis Carroll
-%
-	COMMENT
-
-Oh, life is a glorious cycle of song,
-A medley of extemporanea;
-And love is thing that can never go wrong;
-And I am Marie of Roumania.
-		-- Dorothy Parker
 %
 	Concerning the war in Vietnam, Senator George Aiken of Vermont noted
 in January, 1966, "I'm not very keen for doves or hawks.  I think we need more
@@ -1922,22 +1914,6 @@ Christmas tree.  The piano is missing.
 	You want to keep your party somewhere around level 3, unless
 you rent your home and own Firearms, in which case you can go to level
 4.  The best way to get to level 3 is egg-nog.
-%
-	FIGHTING WORDS
-
-Say my love is easy had,
-	Say I'm bitten raw with pride,
-Say I am too often sad --
-	Still behold me at your side.
-
-Say I'm neither brave nor young,
-	Say I woo and coddle care,
-Say the devil touched my tongue --
-	Still you have my heart to wear.
-
-But say my verses do not scan,
-	And I get me another man!
-		-- Dorothy Parker
 %
 	"For I perceive that behind this seemingly unrelated sequence
 of events, there lurks a singular, sinister attitude of mind."
@@ -2209,20 +2185,6 @@ full of money before."
 	"Ran over a bottle."
 	"Didn't you see it?"
 	"Damn kid had it under his coat."
-%
-	Hug O' War
-
-I will not play at tug o' war.
-I'd rather play at hug o' war,
-Where everyone hugs
-Instead of tugs,
-Where everyone giggles
-And rolls on the rug,
-Where everyone kisses,
-And everyone grins,
-And everyone cuddles,
-And everyone wins.
-		-- Shel Silverstein
 %
 	Human thinking can skip over a great deal, leap over small
 misunderstandings, can contain ifs and buts in untroubled corners of
@@ -2676,33 +2638,6 @@ right any day."
 	"Pity," said Arthur with sympathy.  "It sounded like quite a good
 life-style otherwise."
 		-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
-%
-	Insofar as I may be heard by anything, which may or may not care
-what I say, I ask, if it matters, that you be forgiven for anything you
-may have done or failed to do which requires forgiveness.  Conversely, if
-not forgiveness but something else may be required to insure any possible
-benefit for which you may be eligible after the destruction of your body,
-I ask this, whatever it may be, be granted or withheld, as the case may be,
-in such a manner as to insure your receiving said benefit.  I ask this in my
-capacity as your elected intermediary between yourself and that which may
-not be yourself, but which may have an interest in the matter of your
-receiving as much as it is possible for you to receive of this thing, and
-which may in some way be influenced by this ceremony.
-	Amen.
-		-- Roger Zelazny, "Creatures of Light and Darkness", 1969
-%
-	INVENTORY
-Four be the things I am wiser to know:
-Idleness, sorrow, a friend, and a foe.
-
-Four be the things I'd been better without:
-Love, curiosity, freckles, and doubt.
-
-Three be the things I shall never attain:
-Envy, content, and sufficient champagne.
-
-Three be the things I shall have till I die:
-Laughter and hope and a sock in the eye.
 %
 	"Is there any point to which you would wish to draw my attention?"
 	"To the curious incident of the dog in the night-time."
@@ -3982,28 +3917,6 @@ The center is very pleased with progress to date.  They say they have
 almost succeeded in getting a VAX to think. However, sources inside the
 organization say that each time the machine fails to think it ceases to
 exist.
-%
-	THE LESSER-KNOWN PROGRAMMING LANGUAGES #5: VALGOL
-From its modest beginnings in Southern California's San Fernando Valley,
-VALGOL is enjoying a dramatic surge of popularity across the industry.
-
-Here is a sample program:
-	LIKE, Y*KNOW(I MEAN)START
-	IF PIZZA = LIKE BITCHEN AND GUY = LIKE TUBULAR AND
-	   VALLEY GIRL = LIKE GRODY**MAX(FERSURE)**2 THEN
-		FOR I = LIKE 1 TO OH*MAYBE 100
-			DO*WAH - (DITTY**2)
-			BARF(I)=TOTALLY GROSS(OUT)
-		SURE
-	LIKE BAG THIS PROGRAM
-	REALLY
-	LIKE TOTALLY (Y*KNOW)
-	IM*SURE
-	GOTO THE MALL
-
-When the user makes a syntax error, the interpreter displays the message:
-
-	GAG ME WITH A SPOON!!
 %
 	THE LESSER-KNOWN PROGRAMMING LANGUAGES #8: LAIDBACK
 
@@ -5335,9 +5248,6 @@ that he didn't force you down on the asking price.
 -- A plethora of individuals wither expertise in culinary techniques vitiated
 	the potable concoction produced by steeping certain coupestibles.
 -- Eleemosynary deeds have their initial incidence intramurally.
--- Male cadavers are incapable of yielding testimony.
--- Individuals who make their abode in vitreous edifices would be well
-	advised to refrain from catapulting projectiles.
 %
 =============== ALL FRESHMEN PLEASE NOTE ===============
 
@@ -11076,9 +10986,6 @@ Armstrong's Collection Law:
 	If the check is truly in the mail,
 	it is surely made out to someone else.
 %
-Arnold's Addendum:
-	Anything not fitting into these categories causes cancer in rats.
-%
 Arnold's Laws of Documentation:
 	1.) If it should exist, it doesn't.
 	2.) If it does exist, it's out of date.
@@ -12654,7 +12561,7 @@ Boren's Laws:
 	(2) When in trouble, delegate.
 	(3) When in doubt, mumble.
 %
-boss, n:
+Boss, n:
 	According to the Oxford English Dictionary, in the Middle Ages the
 	words "boss" and "botch" were largely synonymous, except that boss,
 	in addition to meaning "a supervisor of workers" also meant "an
@@ -12935,7 +12842,7 @@ wrote the program.
 Fortunately, the second-to-last bug has just been fixed.
 		-- Ray Simard
 %
-bug, n:
+Bug, n:
 	An elusive creature living in a program that makes it incorrect.
 	The activity of "debugging", or removing bugs from a program, ends
 	when people get tired of doing it, not when the bugs are removed.
@@ -13524,14 +13431,14 @@ only robust persons doing this thing is that it has killed all the
 others who have tried it.
 		-- Ambrose Bierce, "The Devil's Dictionary"
 %
-
-Certain passages in several laws have always defied interpretation and the
-most inexplicable must be a matter of opinion.  A judge of the Court of
-Session of Scotland has sent the editors of this book his candidate which
-reads, "In the Nuts (unground), (other than ground nuts) Order, the expression
-nuts shall have reference to such nuts, other than ground nuts, as would
-but for this amending Order not qualify as nuts (unground) (other than ground
-nuts) by reason of their being nuts (unground)."
+Certain passages in several laws have always defied interpretation and
+the most inexplicable must be a matter of opinion.  A judge of the Court
+of Session of Scotland has sent the editors of this book his candidate
+which reads, "In the Nuts (unground), (other than ground nuts) Order,
+the expression nuts shall have reference to such nuts, other than ground
+nuts, as would but for this amending Order not qualify as nuts
+(unground) (other than ground nuts) by reason of their being nuts
+(unground)."
 		-- Guinness Book of World Records, 1973
 %
 Certainly the game is rigged.
@@ -15057,17 +14964,6 @@ letter, or even 25 cents on a stamp!
 so post it as many places as you can.
 		-- Emily Postnews Answers Your Questions on Netiquette
 %
-Dear Sir,
-	I am firmly opposed to the spread of microchips either to the home or
-to the office.  We have more than enough of them foisted upon us in public
-places.  They are a disgusting Americanism, and can only result in the farmers
-being forced to grow smaller potatoes, which in turn will cause massive un-
-employment in the already severely depressed agricultural industry.
-	Yours faithfully,
-	Capt. Quinton D'Arcy, J.P.
-	Sevenoaks
-		-- Letters To The Editor, The Times of London
-%
 Death before dishonor.
 But neither before breakfast.
 %
@@ -17837,9 +17733,6 @@ Finagle's Eleventh Law:
 	No matter what occurs, someone believes
 	it happened according to his pet theory.
 %
-Finagle's First Law:
-	If an experiment works, something has gone wrong.
-%
 Finagle's First Law:
 	To study a subject best, understand it thoroughly before you start.
 
@@ -18173,9 +18066,6 @@ For children with short attention spans: boomerangs that don't come back.
 For courage mounteth with occasion.
 		-- William Shakespeare, "King John"
 %
-For every action, there is an equal and opposite criticism.
-		-- Harrison
-%
 For every bloke who makes his mark,
 there's half a dozen waiting to rub it out.
 		-- Andy Capp
@@ -19520,17 +19410,6 @@ Your butt is on the menu
 And the check is in the mail.
 		-- The Piranha Club Anthem, to the tune of "De Camptown Races"
 %
-From the "Guinness Book of World Records", 1973:
-
-Certain passages in several laws have always defied interpretation and
-the most inexplicable must be a matter of opinion.  A judge of the
-Court of Session of Scotland has sent the editors of this book his
-candidate which reads, "In the Nuts (unground), (other than ground
-nuts) Order, the expression nuts shall have reference to such nuts,
-other than ground nuts, as would but for this amending Order not
-qualify as nuts (unground)(other than ground nuts) by reason of their
-being nuts (unground)."
-%
 From the moment I picked your book up until I put it down I was
 convulsed with laughter.  Some day I intend reading it.
 		-- Groucho Marx, from "The Book of Insults"
@@ -24035,21 +23914,6 @@ I may not be totally perfect, but parts of me are excellent.
 I met a wonderful new man.  He's fictional, but you can't have everything.
 		-- Cecelia, "The Purple Rose of Cairo"
 %
-I met him in a swamp down in Dagobah
-Where it bubbles all the time like a giant cabinet soda
-	S-O-D-A soda
-I saw the little runt sitting there on a log
-I asked him his name and in a raspy voice he said Yoda
-	Y-O-D-A Yoda, Yo-Yo-Yo-Yo Yoda
-
-Well I've been around but I ain't never seen
-A guy who looks like a Muppet but he's wrinkled and green
-	Oh my Yoda, Yo-Yo-Yo-Yo Yoda
-Well I'm not dumb but I can't understand
-How he can raise me in the air just by raising his hand
-	Oh my Yoda, Yo-Yo-Yo-Yo Yoda, Yo-Yo-Yo-Yo Yoda
-		-- The STAR WARS Song, to "Lola", by the Kinks
-%
 I met my latest girl friend in a department store.  She was looking at
 clothes, and I was putting Slinkys on the escalators.
 		-- Steven Wright
@@ -24524,10 +24388,6 @@ are worth considering, to wit:
 	"When paying tolls, remember that it is necessary to release the
 	quarter a full 3 seconds before passing the basket if you are
 	traveling more than 60 MPH."
-
-[110.13]:
-	"When traveling on a one-way street, stay to the right, so as not
-	to interfere with oncoming traffic."
 %
 I suppose some of the variation between Boston drivers and the rest of the
 country is due to the progressive Massachusetts Driver Education Manual which
@@ -24620,12 +24480,6 @@ But only Schlitz can make a beer.
 I think that I shall never see
 A billboard lovely as a tree.
 Indeed, unless the billboards fall
-I'll never see a tree at all.
-		-- Nash
-%
-I think that I shall never see
-A billboard lovely as a tree.
-Perhaps, unless the billboards fall
 I'll never see a tree at all.
 		-- Ogden Nash
 %
@@ -25892,21 +25746,6 @@ this is the case, then programmers stand on one another's toes, and
 software engineers dig each other's graves.
 		-- Unknown
 %
-If I have seen farther than others, it is because I was standing on the
-shoulders of giants.
-		-- Isaac Newton
-
-In the sciences, we are now uniquely privileged to sit side by side
-with the giants on whose shoulders we stand.
-		-- Gerald Holton
-
-If I have not seen as far as others, it is because giants were standing
-on my shoulders.
-		-- Hal Abelson
-
-In computer science, we stand on each other's feet.
-		-- Brian K. Reid
-%
 If I have to lay an egg for my country, I'll do it.
 		-- Bob Hope
 %
@@ -37634,7 +37473,7 @@ Pardo's First Postulate:
 fattening.
 
 Arnold's Addendum:
-	Everything else causes cancer in rats.
+	Anything not fitting into these categories causes cancer in rats.
 %
 Parents often talk about the younger generation as if they
 didn't have much of anything to do with it.
@@ -39431,10 +39270,6 @@ A:	A dope ring.
 
 Q:	Why do blondes put their hair in ponytails?
 A:	To cover up the valve stem.
-
-Q:	Why did the blonde get so excited after she finished her jigsaw
-	puzzle in only 6 months?
-A:	Because on the box it said "From 2-4 years".
 %
 Q:	What do you call a blind pre-historic animal?
 A:	Diyathinkhesaurus.
@@ -41467,25 +41302,6 @@ Spock:	Affirmative.
 Kirk:	Mr. Sulu, go to pass two.
 Sulu:	Aye aye, sir, going to pass two.
 %
-Scratch the disks, dump the core,	Shut it down, pull the plug
-Roll the tapes across the floor,	Give the core an extra tug
-And the system is going to crash.	And the system is going to crash.
-Teletypes smashed to bits.		Mem'ry cards, one and all,
-Give the scopes some nasty hits		Toss out halfway down the hall
-And the system is going to crash.	And the system is going to crash.
-And we've also found			Just flip one switch
-When you turn the power down,		And the lights will cease to twitch
-You turn the disk readers into trash.	And the tape drives will crumble
-Oh, it's so much fun,				in a flash.
-Now the CPU won't run			 When the CPU
-And the system is going to crash.	Can print nothing out but "foo,"
-					The system is going to crash.
-		-- To The Caissons Go Rolling Along
-%
-Scratch the disks!
-Drop the core!
-Roll the tapes across the floor!
-%
 Screw up your courage!  You've screwed up everything else.
 %
 Scribline, n.:
@@ -46662,7 +46478,8 @@ often turn to a related (but infinitely faster) language, COCAINE.
 %
 THE LESSER-KNOWN PROGRAMMING LANGUAGES #14 -- VALGOL
 
-	VALGOL is enjoying a dramatic surge of popularity across the
+	From its modest beginnings in Southern California's San Fernando
+Valley VALGOL is enjoying a dramatic surge of popularity across the
 industry.  VALGOL commands include REALLY, LIKE, WELL, and Y*KNOW.
 Variables are assigned with the =LIKE and =TOTALLY operators.  Other
 operators include the "California booleans", AX and NOWAY.  Loops are
@@ -48369,9 +48186,6 @@ and peculiar sort of voluntary thinking.
 The solution of this problem is trivial
 and is left as an exercise for the reader.
 %
-The solution to a problem changes the nature of the problem.
-		-- Peer
-%
 The somewhat old and crusty vicar was taking a well-earned retirement from
 his rather old and crusty parish.  As is usual in these cases, a locum was
 sent to cover the transition period.  This particular man was young and
@@ -52040,7 +51854,7 @@ yourself and that which may have an interest in the matter of your receiving
 as much as it is possible for you to receive of this thing, and which may
 in some way be influenced by this ceremony.
 	Amen.
-		-- Roger Zelazny, "Creatures of Light and Darkness"
+		-- Roger Zelazny, "Creatures of Light and Darkness", 1969
 %
 To understand a program you must become both the machine and the program.
 %
@@ -56789,22 +56603,6 @@ I'd LOVE to, but...
 	-- I'm teaching my ferret to yodel.
 	-- My crayons all melted together.
 %
-Why I Can't Go Out With You:
-
-I'd LOVE to, but ...
-	-- I have to floss my cat.
-	-- I've dedicated my life to linguini.
-	-- I need to spend more time with my blender.
-	-- it wouldn't be fair to the other Beautiful People.
-	-- it's my night to pet the dog/ferret/goldfish.
-	-- I'm going downtown to try on some gloves.
-	-- I have to check the freshness dates on my dairy products.
-	-- I'm going down to the bakery to watch the buns rise.
-	-- I have an appointment with a cuticle specialist.
-	-- I have some really hard words to look up.
-	-- I've got a Friends of the Lowly Rutabaga meeting.
-	-- I promised to help a friend fold road maps.
-%
 Why is it called a funny bone when it hurts so much?
 %
 Why is it taking so long for her to bring out all the good in you?
@@ -57859,9 +57657,6 @@ a private eye.
 Yeah, there are more important things in life than money,
 but they won't go out with you if you don't have any.
 %
-YEAR:
-	A period of three hundred and sixty-five disappointments.
-%
 Year  Name				James Bond	Book
 ----  --------------------------------	--------------	----
 50's  James Bond TV Series		Barry Nelson

From 209597ee907012c4fa4c06533bfc58ffb88262ac Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Fri, 15 Jan 2010 02:55:19 +0000
Subject: [PATCH 1129/2592] MFC r201626: - Move potentially offensive quotes I
 committed recently to fortunes-o. - Reference date. - Be more clear on
 context.

MFC r201764:
For the now-infamous Rumsfeld quote:

Change "there're" to "there are" which is consistent with the vast
majority of on line references.

Remove a spurious trailing "

Update the citation text with a suggestion from des.
---
 games/fortune/datfiles/fortunes-o.real | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/games/fortune/datfiles/fortunes-o.real b/games/fortune/datfiles/fortunes-o.real
index dbfafcae703..5c893637cc4 100644
--- a/games/fortune/datfiles/fortunes-o.real
+++ b/games/fortune/datfiles/fortunes-o.real
@@ -662,6 +662,13 @@ posh hotel.
 	"Anything for your wife, sir?" the bellhop asked.
 	"Why, yes, young man," said the gentleman.  "Would you bring me
 a postcard?"
+%
+	As we know, there are known knowns.  There are things we know we
+know.  We also know there are known unknowns.  That is to say, we know
+there are some things we do not know.  But there are also unknown
+unknowns; the ones we don't know we don't know.
+		-- United States Secretary of Defense Donald Rumsfeld
+		   12 February 2002, Regarding the US invasion of Iraq
 %
 	"Are pirates an ethnic group?  Or are they just people who burn
 illegal cds?"
@@ -12873,6 +12880,14 @@ Contraception", has been withdrawn after the Pope advised them to
 pull it out at the last minute.
 		-- Not the Nine O'Clock News
 %
+The investment community feels very putupon.  They feel there is no
+reason why they shouldn't earn $1 million to $200 million a year,
+and they don't want to be held responsible for the global financial
+meltdown.
+		-- Daniel Fass, Chairman of United States President
+		   Barack Obama's financial-industry fundraising party
+		   20 October 2009
+%
 The king arranged a regal marriage for his daughter -- a bond that would unite
 two great kingdoms.  Yet, because the young couple seemed so formal to each
 other, he posted a spy outside the royal wedding chamber and demanded a full

From 06ee3ef09d49abde9db9a6ff9c6c6e6c03def192 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Fri, 15 Jan 2010 03:03:02 +0000
Subject: [PATCH 1130/2592] MFC r201367, r201370: Virtualize the location of
 "the configuration directory" instead of hard-coding it to be /etc/namedb

---
 etc/rc.d/named | 41 +++++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/etc/rc.d/named b/etc/rc.d/named
index 6e03a2c857d..346b6fc9dd4 100755
--- a/etc/rc.d/named
+++ b/etc/rc.d/named
@@ -43,19 +43,19 @@ chroot_autoupdate()
 		warn "chroot directory structure not updated"
 	fi
 
-	# Create /etc/namedb symlink
+	# Create (or update) the configuration directory symlink
 	#
-	if [ ! -L /etc/namedb ]; then
-		if [ -d /etc/namedb ]; then
-			warn "named chroot: /etc/namedb is a directory!"
-		elif [ -e /etc/namedb ]; then
-			warn "named chroot: /etc/namedb exists!"
+	if [ ! -L "${named_conf%/*}" ]; then
+		if [ -d "${named_conf%/*}" ]; then
+			warn "named chroot: ${named_conf%/*} is a directory!"
+		elif [ -e "${named_conf%/*}" ]; then
+			warn "named chroot: ${named_conf%/*} exists!"
 		else
-			ln -s ${named_chrootdir}/etc/namedb /etc/namedb
+			ln -s ${named_confdir} ${named_conf%/*}
 		fi
 	else
 		# Make sure it points to the right place.
-		ln -shf ${named_chrootdir}/etc/namedb /etc/namedb
+		ln -shf ${named_confdir} ${named_conf%/*}
 	fi
 
 	# Mount a devfs in the chroot directory if needed
@@ -179,12 +179,12 @@ named_prestart()
 	# Create an rndc.key file for the user if none exists
 	#
 	confgen_command="${command%/named}/rndc-confgen -a -b256 -u $named_uid \
-	    -c ${named_chrootdir}/etc/namedb/rndc.key"
-	if [ -s "${named_chrootdir}/etc/namedb/rndc.conf" ]; then
+	    -c ${named_confdir}/rndc.key"
+	if [ -s "${named_confdir}/rndc.conf" ]; then
 		unset confgen_command
 	fi
-	if [ -s "${named_chrootdir}/etc/namedb/rndc.key" ]; then
-		case `stat -f%Su ${named_chrootdir}/etc/namedb/rndc.key` in
+	if [ -s "${named_confdir}/rndc.key" ]; then
+		case `stat -f%Su ${named_confdir}/rndc.key` in
 		root|$named_uid) ;;
 		*) $confgen_command ;;
 		esac
@@ -198,8 +198,8 @@ named_prestart()
 			warn "named_auto_forward enabled, but no /etc/resolv.conf"
 
 			# Empty the file in case it is included in named.conf
-			[ -s "${named_chrootdir}/etc/namedb/auto_forward.conf" ] &&
-			    create_file ${named_chrootdir}/etc/namedb/auto_forward.conf
+			[ -s "${named_confdir}/auto_forward.conf" ] &&
+			    create_file ${named_confdir}/auto_forward.conf
 
 			${command%/named}/named-checkconf $named_conf ||
 			    err 3 'named-checkconf for $named_conf failed'
@@ -248,19 +248,19 @@ named_prestart()
 			mv /var/run/naf-resolv.conf /etc/resolv.conf
 		fi
 
-		if cmp -s ${named_chrootdir}/etc/namedb/auto_forward.conf \
+		if cmp -s ${named_confdir}/auto_forward.conf \
 		    /var/run/auto_forward.conf; then
 			unlink /var/run/auto_forward.conf
 		else
-			[ -e "${named_chrootdir}/etc/namedb/auto_forward.conf" ] &&
-			    unlink ${named_chrootdir}/etc/namedb/auto_forward.conf
+			[ -e "${named_confdir}/auto_forward.conf" ] &&
+			    unlink ${named_confdir}/auto_forward.conf
 			mv /var/run/auto_forward.conf \
-			    ${named_chrootdir}/etc/namedb/auto_forward.conf
+			    ${named_confdir}/auto_forward.conf
 		fi
 	else
 		# Empty the file in case it is included in named.conf
-		[ -s "${named_chrootdir}/etc/namedb/auto_forward.conf" ] &&
-		    create_file ${named_chrootdir}/etc/namedb/auto_forward.conf
+		[ -s "${named_confdir}/auto_forward.conf" ] &&
+		    create_file ${named_confdir}/auto_forward.conf
 	fi
 
 	${command%/named}/named-checkconf $named_conf ||
@@ -274,5 +274,6 @@ load_rc_config $name
 required_dirs="$named_chrootdir"	# if it is set, it must exist
 required_files="${named_conf:=/etc/namedb/named.conf}"
 pidfile="${named_pidfile:-/var/run/named/pid}"
+named_confdir="${named_chrootdir}${named_conf%/*}"
 
 run_rc_command "$1"

From bda5bb9d4d6ce9f64fd0ec39fe6d49c8c4c08ec9 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Fri, 15 Jan 2010 03:04:43 +0000
Subject: [PATCH 1131/2592] MFC r201368: Update named_flags comment regarding
 not using it for -u and -c

---
 etc/defaults/rc.conf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index dd5c0b35bed..6e7c37d8c68 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -252,7 +252,7 @@ inetd_flags="-wW -C 60"		# Optional flags to inetd
 named_enable="NO"		# Run named, the DNS server (or NO).
 named_program="/usr/sbin/named" # Path to named, if you want a different one.
 named_conf="/etc/namedb/named.conf" 	# Path to the configuration file
-#named_flags="-c /etc/namedb/named.conf" # Uncomment for named not in /usr/sbin
+#named_flags=""			# Use this for flags OTHER than -u and -c
 named_pidfile="/var/run/named/pid" # Must set this in named.conf as well
 named_uid="bind" 		# User to run named as
 named_chrootdir="/var/named"	# Chroot directory (or "" not to auto-chroot it)

From ad9bb0898d7d8f037e2642af4a1ab960440f7f48 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Fri, 15 Jan 2010 03:28:46 +0000
Subject: [PATCH 1132/2592] MFC r200416: Simplify handling of MTREEFILE
 relative to DESTDIR

Make the message about a missing MTREEFILE combined with -U
more informative

MFC r200425:
Over time things that used to be files/directories/links can change
to something else. So add code to detect when things don't match and
give the user choices about how to fix it.

If we're using -P and something in the above check needs to be moved
we need to have the directory there for it, so create it at the
beginning and delete empty versions of it at the end.

The case where something used to be a file or link and now is supposed
to be a directory (e.g., /etc/security) is especially dangerous, so
make failure to install a necessary directory in $DESTDIR a fatal error.

MFC r200700:
In the places where find is used that the user may see the results,
first pipe it to sort so that order of processing will be deterministic
and like things will be grouped together.

MFC r200701:
Fix an indentation issue, no functional changes

MFC r200708:
Fix a problem with how mergemaster handles the hard links for /.cshrc
and /.profile. The problem is that install(1) will unlink the old file
before it installs the new one, which means that in the best case we
have to compare the changes for the old file twice.

So, change the logic to first test to see if the link exists, then
install the file. Then if the link was there and we're using -i, just
create the link in /root and be done with it. Otherwise display the
message to the user and give them the option.

Because we are now sorting things before doing the comparison we can
know conclusively that the files in / should be the sources, and the
files in /root will be the targets, so adjust the paths accordingly.

While I'm here, split a too-long error message into two lines and
just return at the end of handling these files instead of setting
the variable that says "do nothing" and then returning at the end
of the function anyway.

MFC r201291:
Add some patches contributed by jhb:
1. Don't prompt the user for "-U but no db" error if we're using -a
2. Add an option to delete stale rc.d files automatically if the user
has DELETE_STALE_RC_FILES in their rc file. Lack of command line option
for this is not an oversight.
3. Add []'s around the terminal $ for the $FreeBSD$ test for -F

For one bug raised by jhb I did a more thorough solution:
There were a lot of things that "snuck in" between the end of the test
for -r and the start of the comparison. One of them is the creation of
the mtree db, as pointed out by jhb. Fix this problem more thoroughly
by moving the end of the test down to where it should/used to be, right
before the comparison. As a result, indent the interloping code to match.

MFC r201292:
Document the DELETE_STALE_RC_FILES option introduced in r201291. This is
an "rc file only" option by design.

While I'm here, update the comments in the example rc file to indicate
which command line options they relate to, and correct the defaults
for a couple of options.

MFC r201293:
It's not necessary to include both Op and Fl for command line options
included in the text, so use only the latter.

Clarify that using -U doesn't make sense in combination with -a

MFC r201323:
If we are using -p it does not make any sense to even create the
MTREENEW file since it will never be used.

MFC r201765:
Update copyright date

Update delete_temproot() to include the error message if it fails,
and clean up the places where it's called.

If there are no files left in temproot when the comparison is done
delete it without prompting. This should make "automated" runs of
mergemaster without -a a little easier.

Document the new behavior in the man page.
---
 usr.sbin/mergemaster/mergemaster.8  |  65 ++++---
 usr.sbin/mergemaster/mergemaster.sh | 252 ++++++++++++++++++----------
 2 files changed, 202 insertions(+), 115 deletions(-)

diff --git a/usr.sbin/mergemaster/mergemaster.8 b/usr.sbin/mergemaster/mergemaster.8
index 2bff4be2e4a..c9217b3f4ca 100644
--- a/usr.sbin/mergemaster/mergemaster.8
+++ b/usr.sbin/mergemaster/mergemaster.8
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1998-2009 Douglas Barton
+.\" Copyright (c) 1998-2010 Douglas Barton
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 18, 2009
+.Dd January 7, 2010
 .Dt MERGEMASTER 8
 .Os
 .Sh NAME
@@ -61,10 +61,10 @@ down, populating that environment with the various
 files.
 You can specify a different source directory
 with the
-.Op Fl m
+.Fl m
 command line option, or specify the destination
 directory with the
-.Op Fl D
+.Fl D
 option.
 It then compares each file in that environment
 to its installed counterpart.
@@ -91,10 +91,10 @@ compares the files themselves.
 You can
 also specify that the script ignore the Id strings and
 compare every file with the
-.Op Fl s
+.Fl s
 option.
 Using the
-.Op Fl F
+.Fl F
 option
 .Nm
 will install the new file for you if they differ only by
@@ -126,7 +126,7 @@ installing an updated version of this file you should
 probably run
 .Xr pwd_mkdb 8
 with the
-.Op Fl p
+.Fl p
 option to rebuild your password databases
 and recreate
 .Pa /etc/passwd .
@@ -165,6 +165,14 @@ which will be read before
 Options specified on the command line are updated last,
 and therefore can override both files.
 .Pp
+When the comparison is done if there are any files remaining
+in the temproot directory they will be listed, and if the
+.Fl a
+option is not in use the user will be given the option of 
+deleting the temproot directory.
+If there are no files remaining in the temproot directory
+it will be deleted.
+.Pp
 The options are as follows:
 .Bl -tag -width Fl
 .It Fl s
@@ -198,11 +206,13 @@ If the
 directory exists, it creates a new one in a previously
 non-existent directory.
 This option unsets the verbose flag,
-but is compatible with all other options.
+but other than
+.Fl U
+it is compatible with all other options.
 Setting
-.Op Fl a
+.Fl a
 makes
-.Op Fl w
+.Fl w
 superfluous.
 .It Fl h
 Display usage and help information.
@@ -253,7 +263,7 @@ instead of the default
 Add the date and time to the name of the temporary
 root directory.
 If
-.Op Fl t
+.Fl t
 is specified, this option must
 follow it if you want the date added too.
 .It Fl u Ar N
@@ -320,44 +330,44 @@ with all values commented out:
 # These are options for mergemaster, with their default values listed
 # The following options have command line overrides
 #
-# The target architecture (unset by default)
+# The target architecture (-A, unset by default)
 #ARCHSTRING='TARGET_ARCH='
 #
-# Sourcedir is the directory to do the 'make' in (where the new files are)
+# Sourcedir is the directory to do the 'make' in (-m)
 #SOURCEDIR='/usr/src'
 #
-# Directory to install the temporary root environment into
+# Directory to install the temporary root environment into (-t)
 #TEMPROOT='/var/tmp/temproot'
 #
-# Specify the destination directory for the installed files
+# Specify the destination directory for the installed files (-D)
 #DESTDIR=
 #
-# Strict comparison skips the VCS Id test and compares every file
+# Strict comparison skips the VCS Id test and compares every file (-s)
 #STRICT=no
 #
-# Type of diff, such as unified, context, etc.
+# Type of diff, such as unified, context, etc. (-c)
 #DIFF_FLAG='-u'
 #
-# Install the new file if it differs only by VCS Id ($FreeBSD)
+# Install the new file if it differs only by VCS Id ($FreeBSD, -F)
 #FREEBSD_ID=
 #
-# Verbose mode includes more details and additional checks
+# Verbose mode includes more details and additional checks (-v)
 #VERBOSE=
 #
-# Automatically install files that do not exist on the system already
+# Automatically install files that do not exist on the system already (-i)
 #AUTO_INSTALL=
 #
-# Automatically upgrade files that have not been user modified
+# Automatically upgrade files that have not been user modified (-U)
 #AUTO_UPGRADE=
 #
-# Compare /etc/rc.conf[.local] to /etc/defaults/rc.conf
-#COMP_CONFS=yes
+# Compare /etc/rc.conf[.local] to /etc/defaults/rc.conf (-C)
+#COMP_CONFS=
 #
-# Preserve files that you replace
-#PRESERVE_FILES=yes
+# Preserve files that you replace (-P)
+#PRESERVE_FILES=
 #PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S`
 #
-# The umask for mergemaster to compare the default file's modes to
+# The umask for mergemaster to compare the default file's modes to (-u)
 #NEW_UMASK=022
 #
 # The following options have no command line overrides
@@ -377,6 +387,9 @@ with all values commented out:
 # If you set 'yes' above, make sure to include the PATH to your pager
 #PATH=/bin:/usr/bin:/usr/sbin
 #
+# Delete stale files in /etc/rc.d without prompting
+#DELETE_STALE_RC_FILES=
+#
 # Specify the path to scripts to run before the comparison starts,
 # and/or after the script has finished its work
 #MM_PRE_COMPARE_SCRIPT=
diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh
index 4d2ffc09056..1b0753b8925 100755
--- a/usr.sbin/mergemaster/mergemaster.sh
+++ b/usr.sbin/mergemaster/mergemaster.sh
@@ -5,7 +5,7 @@
 # Compare files created by /usr/src/etc/Makefile (or the directory
 # the user specifies) with the currently installed copies.
 
-# Copyright 1998-2009 Douglas Barton
+# Copyright 1998-2010 Douglas Barton
 # DougB@FreeBSD.org
 
 # $FreeBSD$
@@ -263,7 +263,7 @@ fi
 
 # Assign the location of the mtree database
 #
-MTREEDB=${MTREEDB:-/var/db}
+MTREEDB=${MTREEDB:-${DESTDIR}/var/db}
 MTREEFILE="${MTREEDB}/mergemaster.mtree"
 
 # Check the command line options
@@ -345,18 +345,24 @@ done
 # Don't force the user to set this in the mergemaster rc file
 if [ -n "${PRESERVE_FILES}" -a -z "${PRESERVE_FILES_DIR}" ]; then
   PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S`
+  mkdir -p ${PRESERVE_FILES_DIR}
 fi
 
 # Check for the mtree database in DESTDIR
 case "${AUTO_UPGRADE}" in
 '') ;;	# If the option is not set no need to run the test or warn the user
 *)
-  if [ ! -s "${DESTDIR}${MTREEFILE}" ]; then
+  if [ ! -s "${MTREEFILE}" ]; then
     echo ''
-    echo "*** Unable to find mtree database. Skipping auto-upgrade on this run."
+    echo "*** Unable to find mtree database (${MTREEFILE})."
+    echo "    Skipping auto-upgrade on this run."
     echo "    It will be created for the next run when this one is complete."
     echo ''
-    press_to_continue
+    case "${AUTO_RUN}" in
+    '')
+      press_to_continue
+      ;;
+    esac
     unset AUTO_UPGRADE
   fi
   ;;
@@ -463,9 +469,9 @@ MM_MAKE="make ${ARCHSTRING} -m ${SOURCEDIR}/share/mk"
 # Check DESTDIR against the mergemaster mtree database to see what
 # files the user changed from the reference files.
 #
-if [ -n "${AUTO_UPGRADE}" -a -s "${DESTDIR}${MTREEFILE}" ]; then
+if [ -n "${AUTO_UPGRADE}" -a -s "${MTREEFILE}" ]; then
 	CHANGED=:
-	for file in `mtree -eqL -f ${DESTDIR}${MTREEFILE} -p ${DESTDIR}/ \
+	for file in `mtree -eqL -f ${MTREEFILE} -p ${DESTDIR}/ \
 		2>/dev/null | awk '($2 == "changed") {print $1}'`; do
 		if [ -f "${DESTDIR}/$file" ]; then
 			CHANGED="${CHANGED}${DESTDIR}/${file}:"
@@ -505,7 +511,7 @@ CVS_ID_TAG=FreeBSD
 delete_temproot () {
   rm -rf "${TEMPROOT}" 2>/dev/null
   chflags -R 0 "${TEMPROOT}" 2>/dev/null
-  rm -rf "${TEMPROOT}" || exit 1
+  rm -rf "${TEMPROOT}" || { echo "*** Unable to delete ${TEMPROOT}";  exit 1; }
 }
 
 case "${RERUN}" in
@@ -536,7 +542,7 @@ case "${RERUN}" in
           echo ''
           echo "   *** Deleting the old ${TEMPROOT}"
           echo ''
-          delete_temproot || exit 1
+          delete_temproot
           unset TEST_TEMP_ROOT
           ;;
         [tT])
@@ -663,33 +669,34 @@ case "${RERUN}" in
   for file in ${IGNORE_FILES}; do
     test -e ${TEMPROOT}/${file} && unlink ${TEMPROOT}/${file}
   done
+
+  # We really don't want to have to deal with files like login.conf.db, pwd.db,
+  # or spwd.db.  Instead, we want to compare the text versions, and run *_mkdb.
+  # Prompt the user to do so below, as needed.
+  #
+  rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd
+
+  # We only need to compare things like freebsd.cf once
+  find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null
+
+  # Delete stuff we do not need to keep the mtree database small,
+  # and to make the actual comparison faster.
+  find ${TEMPROOT}/usr -type l -delete 2>/dev/null
+  find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null
+  find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null
+
+  # Build the mtree database in a temporary location.
+  case "${PRE_WORLD}" in
+  '') MTREENEW=`mktemp -t mergemaster.mtree`
+      mtree -ci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null
+      ;;
+  *) # We don't want to mess with the mtree database on a pre-world run or
+     # when re-scanning a previously-built tree.
+     ;;
+  esac
   ;; # End of the "RERUN" test
 esac
 
-# We really don't want to have to deal with files like login.conf.db, pwd.db,
-# or spwd.db.  Instead, we want to compare the text versions, and run *_mkdb.
-# Prompt the user to do so below, as needed.
-#
-rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd
-
-# We only need to compare things like freebsd.cf once
-find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null
-
-# Delete stuff we do not need to keep the mtree database small,
-# and to make the actual comparison faster.
-find ${TEMPROOT}/usr -type l -delete 2>/dev/null
-find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null
-find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null
-
-# Build the mtree database in a temporary location.
-MTREENEW=`mktemp -t mergemaster.mtree`
-case "${PRE_WORLD}" in
-'') mtree -ci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null
-    ;;
-*) # We don't want to mess with the mtree database on a pre-world run.
-   ;;
-esac
-
 # Get ready to start comparing files
 
 # Check umask if not specified on the command line,
@@ -818,7 +825,8 @@ mm_install () {
 
   if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then
     DIR_MODE=`find_mode "${TEMPROOT}/${INSTALL_DIR}"`
-    install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}"
+    install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}" ||
+      install_error $1 ${DESTDIR}${INSTALL_DIR}
   fi
 
   FILE_MODE=`find_mode "${1}"`
@@ -837,32 +845,39 @@ mm_install () {
       DONT_INSTALL=yes
       ;;
     /.cshrc | /.profile)
-    case "${AUTO_INSTALL}" in
-    '')
-      case "${LINK_EXPLAINED}" in
-      '')
-        echo "   *** Historically BSD derived systems have had a"
-        echo "       hard link from /.cshrc and /.profile to"
-        echo "       their namesakes in /root.  Please indicate"
-        echo "       your preference below for bringing your"
-        echo "       installed files up to date."
-        echo ''
-        LINK_EXPLAINED=yes
-        ;;
-      esac
+      local st_nlink
 
-      echo "   Use 'd' to delete the temporary ${COMPFILE}"
-      echo "   Use 'l' to delete the existing ${DESTDIR}${COMPFILE#.} and create the link"
-      echo ''
-      echo "   Default is to leave the temporary file to deal with by hand"
-      echo ''
-      echo -n "  How should I handle ${COMPFILE}? [Leave it to install later] "
-      read HANDLE_LINK
-      ;;
-    *)  # Part of AUTO_INSTALL
-      HANDLE_LINK=l
-      ;;
-    esac
+      # install will unlink the file before it installs the new one,
+      # so we have to restore/create the link afterwards.
+      #
+      st_nlink=0		# In case the file does not yet exist
+      eval $(stat -s ${DESTDIR}${COMPFILE#.} 2>/dev/null)
+
+      do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
+
+      if [ -n "${AUTO_INSTALL}" -a $st_nlink -gt 1 ]; then
+        HANDLE_LINK=l
+      else
+        case "${LINK_EXPLAINED}" in
+        '')
+          echo "   *** Historically BSD derived systems have had a"
+          echo "       hard link from /.cshrc and /.profile to"
+          echo "       their namesakes in /root.  Please indicate"
+          echo "       your preference below for bringing your"
+          echo "       installed files up to date."
+          echo ''
+          LINK_EXPLAINED=yes
+          ;;
+        esac
+
+        echo "   Use 'd' to delete the temporary ${COMPFILE}"
+        echo "   Use 'l' to delete the existing ${DESTDIR}/root/${COMPFILE##*/} and create the link"
+        echo ''
+        echo "   Default is to leave the temporary file to deal with by hand"
+        echo ''
+        echo -n "  How should I handle ${COMPFILE}? [Leave it to install later] "
+        read HANDLE_LINK
+      fi
 
       case "${HANDLE_LINK}" in
       [dD]*)
@@ -872,19 +887,19 @@ mm_install () {
         ;;
       [lL]*)
         echo ''
-        rm -f "${DESTDIR}${COMPFILE#.}"
-        if ln "${DESTDIR}/root/${COMPFILE##*/}" "${DESTDIR}${COMPFILE#.}"; then
+        unlink ${DESTDIR}/root/${COMPFILE##*/}
+        if ln ${DESTDIR}${COMPFILE#.} ${DESTDIR}/root/${COMPFILE##*/}; then
           echo "   *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully"
-          rm "${COMPFILE}"
         else
-          echo "   *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand"
+          echo "   *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}"
+          echo "   *** ${COMPFILE} will remain for your consideration"
         fi
         ;;
       *)
         echo "   *** ${COMPFILE} will remain for your consideration"
         ;;
       esac
-      DONT_INSTALL=yes
+      return
       ;;
     esac
 
@@ -955,6 +970,12 @@ if [ -z "${PRE_WORLD}" -a -z "${RERUN}" ]; then
       esac
       sleep 2
       ;;
+    *)
+      if [ -n "${DELETE_STALE_RC_FILES}" ]; then
+        echo '      *** Deleting ... '
+        rm ${STALE_RC_FILES}
+        echo '                       done.'
+      fi
     esac
     ;;
   esac
@@ -967,7 +988,58 @@ if [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then
   . "${MM_PRE_COMPARE_SCRIPT}"
 fi
 
-for COMPFILE in `find . -type f`; do
+# Things that were files/directories/links in one version can sometimes
+# change to something else in a newer version.  So we need to explicitly
+# test for this, and warn the user if what we find does not match.
+#
+for COMPFILE in `find . | sort` ; do
+  if [ -e "${DESTDIR}${COMPFILE#.}" ]; then
+    INSTALLED_TYPE=`stat -f '%HT' ${DESTDIR}${COMPFILE#.}`
+  else
+    continue
+  fi
+  TEMPROOT_TYPE=`stat -f '%HT' $COMPFILE`
+
+  if [ ! "$TEMPROOT_TYPE" = "$INSTALLED_TYPE" ]; then
+    [ "$COMPFILE" = '.' ] && continue
+    TEMPROOT_TYPE=`echo $TEMPROOT_TYPE | tr [:upper:] [:lower:]`
+    INSTALLED_TYPE=`echo $INSTALLED_TYPE | tr [:upper:] [:lower:]`
+
+    echo "*** The installed file ${DESTDIR}${COMPFILE#.} has the type \"$INSTALLED_TYPE\""
+    echo "    but the new version has the type \"$TEMPROOT_TYPE\""
+    echo ''
+    echo "    How would you like to handle this?"
+    echo ''
+    echo "    Use 'r' to remove ${DESTDIR}${COMPFILE#.}"
+    case "$TEMPROOT_TYPE" in
+    'symbolic link')
+	TARGET=`readlink $COMPFILE`
+	echo "    and create a link to $TARGET in its place" ;;
+    *)	echo "    You will be able to install it as a \"$TEMPROOT_TYPE\"" ;;
+    esac
+    echo ''
+    echo "    Use 'i' to ignore this"
+    echo ''
+    echo -n "    How to proceed? [i] "
+    read ANSWER
+    case "$ANSWER" in
+    [rR])	case "${PRESERVE_FILES}" in
+		[Yy][Ee][Ss])
+		mv ${DESTDIR}${COMPFILE#.} ${PRESERVE_FILES_DIR}/ || exit 1 ;;
+		*) rm -rf ${DESTDIR}${COMPFILE#.} ;;
+		esac
+		case "$TEMPROOT_TYPE" in
+		'symbolic link') ln -sf $TARGET ${DESTDIR}${COMPFILE#.} ;;
+		esac ;;
+    *)	echo ''
+        echo "*** See the man page about adding ${COMPFILE#.} to the list of IGNORE_FILES"
+        press_to_continue ;;
+    esac
+    echo ''
+  fi
+done
+
+for COMPFILE in `find . -type f | sort`; do
 
   # First, check to see if the file exists in DESTDIR.  If not, the
   # diff_loop function knows how to handle it.
@@ -1032,7 +1104,7 @@ for COMPFILE in `find . -type f`; do
       # If the user chose the -F option, test for that before proceeding
       #
       if [ -n "$FREEBSD_ID" ]; then
-        if diff -q -I'[$]FreeBSD:.*$' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \
+        if diff -q -I'[$]FreeBSD.*[$]' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \
             /dev/null 2>&1; then
           if mm_install "${COMPFILE}"; then
             echo "*** Updated revision control Id for ${DESTDIR}${COMPFILE#.}"
@@ -1061,8 +1133,8 @@ echo "*** Comparison complete"
 
 if [ -s "${MTREENEW}" ]; then
   echo "*** Saving mtree database for future upgrades"
-  test -e "${DESTDIR}${MTREEFILE}" && unlink ${DESTDIR}${MTREEFILE}
-  mv ${MTREENEW} ${DESTDIR}${MTREEFILE}
+  test -e "${MTREEFILE}" && unlink ${MTREEFILE}
+  mv ${MTREENEW} ${MTREEFILE}
 fi
 
 echo ''
@@ -1070,30 +1142,28 @@ echo ''
 TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null`
 if [ -n "${TEST_FOR_FILES}" ]; then
   echo "*** Files that remain for you to merge by hand:"
-  find "${TEMPROOT}" -type f -size +0
+  find "${TEMPROOT}" -type f -size +0 | sort
   echo ''
-fi
 
-case "${AUTO_RUN}" in
-'')
-  echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] "
-  read DEL_TEMPROOT
-
-  case "${DEL_TEMPROOT}" in
-  [yY]*)
-    if delete_temproot; then
-      echo " *** ${TEMPROOT} has been deleted"
-    else
-      echo " *** Unable to delete ${TEMPROOT}"
-    fi
-    ;;
-  *)
-    echo " *** ${TEMPROOT} will remain"
+  case "${AUTO_RUN}" in
+  '')
+    echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] "
+    read DEL_TEMPROOT
+    case "${DEL_TEMPROOT}" in
+    [yY]*)
+      delete_temproot
+      ;;
+    *)
+      echo " *** ${TEMPROOT} will remain"
+      ;;
+    esac
     ;;
+  *) ;;
   esac
-  ;;
-*) ;;
-esac
+else
+  echo "*** ${TEMPROOT} is empty, deleting"
+  delete_temproot
+fi
 
 case "${AUTO_INSTALLED_FILES}" in
 '') ;;
@@ -1268,5 +1338,9 @@ case "${PRE_WORLD}" in
   ;;
 esac
 
-exit 0
+if [ -n "${PRESERVE_FILES}" ]; then
+  find -d $PRESERVE_FILES_DIR -type d -empty -delete 2>/dev/null
+  rmdir $PRESERVE_FILES_DIR 2>/dev/null
+fi
 
+exit 0

From cf8398526359cf892db26ecb2bf7074aa2222b27 Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Fri, 15 Jan 2010 11:26:20 +0000
Subject: [PATCH 1133/2592] MFC: revision 201339 and 201340

  - Add setting machine type support to the loader.
  - Don't use 15M-16M area on pc98.  It's reserved for some devices.
---
 sys/boot/common/module.c         | 19 ++++++++
 sys/boot/pc98/Makefile.inc       |  2 +-
 sys/boot/pc98/libpc98/Makefile   |  2 +-
 sys/boot/pc98/libpc98/libpc98.h  | 29 ++++++++++++
 sys/boot/pc98/libpc98/pc98_sys.c | 78 ++++++++++++++++++++++++++++++++
 sys/boot/pc98/loader/main.c      |  4 ++
 6 files changed, 132 insertions(+), 2 deletions(-)
 create mode 100644 sys/boot/pc98/libpc98/libpc98.h
 create mode 100644 sys/boot/pc98/libpc98/pc98_sys.c

diff --git a/sys/boot/common/module.c b/sys/boot/common/module.c
index 098e39ad938..18ba1b550e2 100644
--- a/sys/boot/common/module.c
+++ b/sys/boot/common/module.c
@@ -351,6 +351,9 @@ file_loadraw(char *type, char *name)
     char			*cp;
     int				fd, got;
     vm_offset_t			laddr;
+#ifdef PC98
+    struct stat			st;
+#endif
 
     /* We can't load first */
     if ((file_findfile(NULL, NULL)) == NULL) {
@@ -372,6 +375,14 @@ file_loadraw(char *type, char *name)
 	return(CMD_ERROR);
     }
 
+#ifdef PC98
+    /* We cannot use 15M-16M area on pc98. */
+    if (loadaddr < 0x1000000 &&
+	fstat(fd, &st) == 0 &&
+	(st.st_size == -1 || loadaddr + st.st_size > 0xf00000))
+	loadaddr = 0x1000000;
+#endif
+
     laddr = loadaddr;
     for (;;) {
 	/* read in 4k chunks; size is not really important */
@@ -477,6 +488,14 @@ mod_loadkld(const char *kldname, int argc, char *argv[])
 	;
 
     do {
+#ifdef PC98
+	/* We cannot use 15M-16M area on pc98. */
+	struct stat st;
+	if (loadaddr < 0x1000000 &&
+	    stat(filename, &st) == 0 &&
+	    (st.st_size == -1 || loadaddr + st.st_size > 0xf00000))
+	    loadaddr = 0x1000000;
+#endif
 	err = file_load(filename, loadaddr, &fp);
 	if (err)
 	    break;
diff --git a/sys/boot/pc98/Makefile.inc b/sys/boot/pc98/Makefile.inc
index 54d4431e936..641fbca88e6 100644
--- a/sys/boot/pc98/Makefile.inc
+++ b/sys/boot/pc98/Makefile.inc
@@ -7,7 +7,7 @@ BINDIR?=	/boot
 LOADER_ADDRESS?=0x200000
 CFLAGS+=	-ffreestanding -mpreferred-stack-boundary=2 \
 		-mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
-		-Os
+		-Os -DPC98
 LDFLAGS+=	-nostdlib
 
 # BTX components
diff --git a/sys/boot/pc98/libpc98/Makefile b/sys/boot/pc98/libpc98/Makefile
index 1a28b6b9a25..6c6ce892fdd 100644
--- a/sys/boot/pc98/libpc98/Makefile
+++ b/sys/boot/pc98/libpc98/Makefile
@@ -8,7 +8,7 @@ INTERNALLIB=
 SRCS=	bioscd.c biosdisk.c biosmem.c biospnp.c \
 	biospci.c biossmap.c bootinfo.c bootinfo32.c \
 	comconsole.c devicename.c elf32_freebsd.c \
-	i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \
+	i386_copy.c i386_module.c nullconsole.c pc98_sys.c pxe.c pxetramp.s \
 	time.c vidconsole.c
 
 # Enable PXE TFTP or NFS support, not both.
diff --git a/sys/boot/pc98/libpc98/libpc98.h b/sys/boot/pc98/libpc98/libpc98.h
new file mode 100644
index 00000000000..78b07a10ffa
--- /dev/null
+++ b/sys/boot/pc98/libpc98/libpc98.h
@@ -0,0 +1,29 @@
+/*-
+ * Copyright (c) 2009 TAKAHASHI Yoshihiro 
+ * 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$
+ */
+
+void set_machine_type(void);
diff --git a/sys/boot/pc98/libpc98/pc98_sys.c b/sys/boot/pc98/libpc98/pc98_sys.c
new file mode 100644
index 00000000000..7f66d02c630
--- /dev/null
+++ b/sys/boot/pc98/libpc98/pc98_sys.c
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 2009 TAKAHASHI Yoshihiro 
+ * 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 
+#define _KERNEL
+#include 
+
+/*
+ * Set machine type to PC98_SYSTEM_PARAMETER.
+ */
+void
+set_machine_type(void)
+{
+	int i;
+	u_long ret, data;
+
+	/* PC98_SYSTEM_PARAMETER (0x501) */
+	ret = ((*(u_char *)PTOV(0xA1501)) & 0x08) >> 3;
+
+	/* Wait V-SYNC */
+	while (inb(0x60) & 0x20) {}
+	while (!(inb(0x60) & 0x20)) {}
+
+	/* ANK 'A' font */
+	outb(0xa1, 0x00);
+	outb(0xa3, 0x41);
+
+	/* M_NORMAL, use CG window (all NEC OK)  */
+	for (i = data = 0; i < 4; i++)
+		data += *((u_long *)PTOV(0xA4000) + i);	/* 0xa4000 */
+	if (data == 0x6efc58fc)		/* DA data */
+		ret |= M_NEC_PC98;
+	else
+		ret |= M_EPSON_PC98;
+	ret |= (inb(0x42) & 0x20) ? M_8M : 0;
+
+	/* PC98_SYSTEM_PARAMETER(0x400) */
+	if ((*(u_char *)PTOV(0xA1400)) & 0x80)
+		ret |= M_NOTE;
+	if (ret & M_NEC_PC98) {
+		/* PC98_SYSTEM_PARAMETER(0x458) */
+		if ((*(u_char *)PTOV(0xA1458)) & 0x80)
+			ret |= M_H98;
+		else
+			ret |= M_NOT_H98;
+	} else
+		ret |= M_NOT_H98;
+
+	(*(u_long *)PTOV(0xA1620)) = ret;
+}
diff --git a/sys/boot/pc98/loader/main.c b/sys/boot/pc98/loader/main.c
index e10b1e7217e..da14d0bcf8f 100644
--- a/sys/boot/pc98/loader/main.c
+++ b/sys/boot/pc98/loader/main.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 
 #include "bootstrap.h"
 #include "libi386/libi386.h"
+#include "libpc98/libpc98.h"
 #include "btxv86.h"
 
 #define	KARGS_FLAGS_CD		0x1
@@ -81,6 +82,9 @@ main(void)
 {
     int			i;
 
+    /* Set machine type to PC98_SYSTEM_PARAMETER. */
+    set_machine_type();
+
     /* Pick up arguments */
     kargs = (void *)__args;
     initial_howto = kargs->howto;

From 2eea36f8d917419c8401e3f767f44854a7b927ff Mon Sep 17 00:00:00 2001
From: Dmitry Morozovsky 
Date: Fri, 15 Jan 2010 12:02:22 +0000
Subject: [PATCH 1134/2592] MFH r201051:

  To remove a server, one should use double backslash, and half of them
  are eaten by shell.  Fix this.
---
 usr.sbin/ypserv/ypinit.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/usr.sbin/ypserv/ypinit.sh b/usr.sbin/ypserv/ypinit.sh
index 1be7e0e3e18..374308e2084 100644
--- a/usr.sbin/ypserv/ypinit.sh
+++ b/usr.sbin/ypserv/ypinit.sh
@@ -298,7 +298,7 @@ do
 		echo "Update the list of hosts running YP servers in domain ${DOMAIN}."
 		echo "Master for this domain is ${MASTER_NAME}."
 		echo ""
-		echo "First verify old servers, type \\ to remove a server."
+		echo "First verify old servers, type \\\\ to remove a server."
 		echo "Then add new servers, one per line. When done type a ."
 		echo ""
 		echo "	master server   :  ${HOST}"

From 854f8af8194bbd15fe1b3976ff20a37ee4290bf4 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 12:07:30 +0000
Subject: [PATCH 1135/2592] MFC: r200944

Revert r183628 as with the current ata(4) ATAPI DMA with AcerLabs
M5229 appears to be once again fixed. If this happens to return
we probably should disable ATAPI DMA in ataacerlabs(4) instead
just like the Linux libATA does.
---
 sys/boot/sparc64/loader/main.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c
index 3a899a862e0..a9f641ea129 100644
--- a/sys/boot/sparc64/loader/main.c
+++ b/sys/boot/sparc64/loader/main.c
@@ -261,7 +261,6 @@ static int
 sparc64_autoload(void)
 {
 
-	setenv("hw.ata.atapi_dma", "0", 0);
 	return (0);
 }
 

From b304370214b25fcb9958e6db994eee7caef454e8 Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Fri, 15 Jan 2010 12:27:46 +0000
Subject: [PATCH 1136/2592] MFC: revision 201342

  Reimplement the boot2 for pc98 completely.
  It's based on the newest i386's one and has the advantage of:

   - ELF binary support.
   - UFS2 filesystem support.
   - Many FreeBSD slices support on a disk.
---
 sys/boot/pc98/boot2/Makefile         | 165 +++---
 sys/boot/pc98/boot2/asm.S            | 258 --------
 sys/boot/pc98/boot2/asm.h            | 144 -----
 sys/boot/pc98/boot2/bios.S           | 502 ----------------
 sys/boot/pc98/boot2/boot.c           | 405 -------------
 sys/boot/pc98/boot2/boot.h           | 108 ----
 sys/boot/pc98/boot2/boot1.S          | 395 +++++++++++++
 sys/boot/pc98/boot2/boot2.S          | 182 ------
 sys/boot/pc98/boot2/boot2.c          | 842 +++++++++++++++++++++++++++
 sys/boot/pc98/boot2/dinode.h         | 126 ----
 sys/boot/pc98/boot2/disk.c           | 175 ------
 sys/boot/pc98/boot2/fs.h             | 551 ------------------
 sys/boot/pc98/boot2/inode.h          | 161 -----
 sys/boot/pc98/boot2/io.c             | 396 -------------
 sys/boot/pc98/boot2/probe_keyboard.c |  42 --
 sys/boot/pc98/boot2/quota.h          | 201 -------
 sys/boot/pc98/boot2/serial.S         |  57 --
 sys/boot/pc98/boot2/serial_16550.S   | 181 ------
 sys/boot/pc98/boot2/serial_8251.S    | 198 -------
 sys/boot/pc98/boot2/start.S          | 475 ---------------
 sys/boot/pc98/boot2/sys.c            | 321 ----------
 sys/boot/pc98/boot2/table.c          | 146 -----
 22 files changed, 1315 insertions(+), 4716 deletions(-)
 delete mode 100644 sys/boot/pc98/boot2/asm.S
 delete mode 100644 sys/boot/pc98/boot2/asm.h
 delete mode 100644 sys/boot/pc98/boot2/bios.S
 delete mode 100644 sys/boot/pc98/boot2/boot.c
 delete mode 100644 sys/boot/pc98/boot2/boot.h
 create mode 100644 sys/boot/pc98/boot2/boot1.S
 delete mode 100644 sys/boot/pc98/boot2/boot2.S
 create mode 100644 sys/boot/pc98/boot2/boot2.c
 delete mode 100644 sys/boot/pc98/boot2/dinode.h
 delete mode 100644 sys/boot/pc98/boot2/disk.c
 delete mode 100644 sys/boot/pc98/boot2/fs.h
 delete mode 100644 sys/boot/pc98/boot2/inode.h
 delete mode 100644 sys/boot/pc98/boot2/io.c
 delete mode 100644 sys/boot/pc98/boot2/probe_keyboard.c
 delete mode 100644 sys/boot/pc98/boot2/quota.h
 delete mode 100644 sys/boot/pc98/boot2/serial.S
 delete mode 100644 sys/boot/pc98/boot2/serial_16550.S
 delete mode 100644 sys/boot/pc98/boot2/serial_8251.S
 delete mode 100644 sys/boot/pc98/boot2/start.S
 delete mode 100644 sys/boot/pc98/boot2/sys.c
 delete mode 100644 sys/boot/pc98/boot2/table.c

diff --git a/sys/boot/pc98/boot2/Makefile b/sys/boot/pc98/boot2/Makefile
index f5da55d31ed..63f364c2261 100644
--- a/sys/boot/pc98/boot2/Makefile
+++ b/sys/boot/pc98/boot2/Makefile
@@ -1,113 +1,104 @@
 # $FreeBSD$
-#
 
-PROG=	boot
-# Order is very important on the SRCS line for this prog
-SRCS=	start.S table.c boot2.S boot.c asm.S bios.S serial.S
-SRCS+=	probe_keyboard.c io.c disk.c sys.c
+FILES=		boot boot1 boot2
 
-BINMODE=	444
-CFLAGS=		-Os -mrtd \
-		-fno-guess-branch-probability \
-		-fno-unit-at-a-time \
-		-D_KERNEL -DBOOTWAIT=${BOOTWAIT} -DTIMEOUT=${TIMEOUT}
-CFLAGS+=	-DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK}
-CFLAGS+=	-I${.CURDIR}/../../.. -I.
+NM?=		nm
 
-# By default, if a serial port is going to be used as console, use COM1
-# (aka /dev/ttyd0).
-#BOOT_COMCONSOLE_PORT?=0x30
-BOOT_COMCONSOLE_PORT?=0x238
-BOOT_COMCONSOLE_CLK?=16
-BOOT_COMCONSOLE_MODE=0x0c
-CFLAGS+=	-DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \
-		-DCOMCONSOLE_CLK=${BOOT_COMCONSOLE_CLK} \
-		-DCOMCONSOLE_MODE=${BOOT_COMCONSOLE_MODE}
+BOOT_COMCONSOLE_PORT?= 0x238
+BOOT_COMCONSOLE_SPEED?= 9600
+B2SIOFMT?=	0x3
 
-# feature not implemented
-BOOT_COMCONSOLE_SPEED?=9600
-CFLAGS+=	-DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
+REL1=	0x700
+ORG1=	0
+ORG2=	0x2000
 
-# Enable code to take the default boot string from a fixed location on the
-# disk.  See nextboot(8) and README.386BSD for more info.
-#CFLAGS+=	-DNAMEBLOCK
-#CFLAGS+=	-DNAMEBLOCK_WRITEBACK
+# Decide level of UFS support.
+BOOT2_UFS?=	UFS1_AND_UFS2
+#BOOT2_UFS?=	UFS2_ONLY
+#BOOT2_UFS?=	UFS1_ONLY
 
-# Bias the conversion from the BIOS drive number to the FreeBSD unit number
-# for hard disks.  This may be useful for people booting in a mixed IDE/SCSI
-# environment (set BOOT_HD_BIAS to the number of IDE drives).
-#CFLAGS+=	-DBOOT_HD_BIAS=1
-#
-# Details: this only applies if BOOT_HD_BIAS > 0.  If the BIOS drive number
-# for the boot drive is >= BOOT_HD_BIAS, then the boot drive is assumed to
-# be SCSI and have unit number (BIOS_drive_number - BOOT_HD_BIAS).  E.g.,
-# BOOT_HD_BIAS=1 makes BIOS drive 1 correspond to 1:da(0,a) instead of
-# 1:wd(1,a).  If `da' is given explicitly, then the drive is assumed to be
-# SCSI and have BIOS drive number (da_unit_number + BOOT_HD_BIAS).  E.g.,
-# BOOT_HD_BIAS=1 makes da(0,a) correspond to 1:da(0,a) instead of 0:da(0,a).
+CFLAGS=	-Os \
+	-fno-guess-branch-probability \
+	-fomit-frame-pointer \
+	-fno-unit-at-a-time \
+	-mno-align-long-strings \
+	-mrtd \
+	-mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
+	-D${BOOT2_UFS} \
+	-DFLAGS=${BOOT_BOOT1_FLAGS} \
+	-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
+	-DSIOFMT=${B2SIOFMT} \
+	-DSIOSPD=${BOOT_COMCONSOLE_SPEED} \
+	-I${.CURDIR}/../../.. \
+	-I${.CURDIR}/../../i386/boot2 \
+	-I${.CURDIR}/../../common \
+	-I${.CURDIR}/../btx/lib -I. \
+	-Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
+	-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
+	-Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \
+	-Winline --param max-inline-insns-single=100
 
-CLEANFILES+=	boot.nohdr boot.strip boot.ldr boot1 boot2 sizetest
-LDFLAGS+=	-N -Ttext 0 -e start
-NO_SHARED=	YES
-NO_MAN=
-STRIP=
+# Set machine type to PC98_SYSTEM_PARAMETER
+#CFLAGS+=	-DSET_MACHINE_TYPE
 
-# tunable timeout parameter, waiting for keypress, calibrated in ms
-BOOTWAIT?=	5000
-# tunable timeout during string input, calibrated in ms
-#TIMEOUT?=	30000
+# Initialize the bi_bios_geom using the BIOS geometry
+#CFLAGS+=	-DGET_BIOSGEOM
 
-# Location that boot2 is loaded at
-BOOTSEG=	0x1000
+LDFLAGS=-static -N --gc-sections
 
-# Offset in BOOTSEG for the top of the stack, keep this 16 byte aligned
-BOOTSTACK=	0xFFF0
+# Pick up ../Makefile.inc early.
+.include 
 
-boot.nohdr:	boot
-	objcopy -S -O binary boot boot.nohdr
-	ls -l boot.nohdr
+.PATH:	${.CURDIR}/../../i386/boot2
 
-boot.ldr:	boot.nohdr
-	dd if=boot.nohdr of=boot.ldr bs=8192 count=1 conv=sync
+CLEANFILES=	boot
 
-boot1:		boot.nohdr
-	dd if=boot.nohdr of=boot1 bs=512 count=1
+boot: boot1 boot2
+	cat boot1 boot2 > boot
 
-boot2:		boot.nohdr
-	dd if=boot.nohdr of=boot2 bs=512 skip=1
-	@dd if=boot2 skip=14 of=sizetest 2> /dev/null
-	@if [ -s sizetest ] ; then \
-		echo "boot2 is too big" >&2 ; \
-		rm boot2 ; \
-		exit 2 ; \
-	fi
+CLEANFILES+=	boot1 boot1.out boot1.o
 
-all:		boot.ldr boot1 boot2
+boot1: boot1.out
+	objcopy -S -O binary boot1.out ${.TARGET}
 
-install:
-	${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
-		boot.ldr ${DESTDIR}${BINDIR}/boot
-	${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
-		boot1 boot2 ${DESTDIR}${BINDIR}
+boot1.out: boot1.o
+	${LD} ${LDFLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} boot1.o
 
-# If it's not there, don't consider it a target
-.if exists(${.CURDIR}/../../../pc98/include)
-beforedepend ${OBJS}: machine
+CLEANFILES+=	boot2 boot2.ld boot2.ldr boot2.bin boot2.out boot2.o \
+		boot2.s boot2.s.tmp boot2.h sio.o
 
-machine:
-	ln -sf ${.CURDIR}/../../../pc98/include machine
+boot2: boot2.ld
+	@set -- `ls -l boot2.ld`; x=$$((7680-$$5)); \
+	    echo "$$x bytes available"; test $$x -ge 0
+	dd if=boot2.ld of=${.TARGET} obs=7680 conv=osync
 
-.endif
+boot2.ld: boot2.ldr boot2.bin ${BTXKERN}
+	btxld -v -E ${ORG2} -f bin -b ${BTXKERN} -l boot2.ldr \
+	    -o ${.TARGET} -P 1 boot2.bin
 
-.if exists(${.CURDIR}/../../../i386/include) 
-beforedepend ${OBJS}: i386
+boot2.ldr:
+	dd if=/dev/zero of=${.TARGET} bs=276 count=1
 
-i386:
-	ln -sf ${.CURDIR}/../../../i386/include i386
+boot2.bin: boot2.out
+	objcopy -S -O binary boot2.out ${.TARGET}
 
-.endif
+boot2.out: ${BTXCRT} boot2.o sio.o
+	${LD} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC}
 
-CLEANFILES+=	machine i386
+boot2.o: boot2.s
+
+SRCS=	boot2.c boot2.h
+
+boot2.s: boot2.c boot2.h ${.CURDIR}/../../common/ufsread.c
+	${CC} ${CFLAGS} -S -o boot2.s.tmp ${.CURDIR}/boot2.c
+	sed -e '/align/d' -e '/nop/d' < boot2.s.tmp > boot2.s
+	rm -f boot2.s.tmp
+
+boot2.h: boot1.out
+	${NM} -t d ${.ALLSRC} | awk '/([0-9])+ T (read|putc)/ \
+	    { x = $$1 - ORG1; \
+	    printf("#define %sORG %#x\n", toupper($$3), REL1 + x) }' \
+	    ORG1=`printf "%d" ${ORG1}` \
+	    REL1=`printf "%d" ${REL1}` > ${.TARGET}
 
-CWARNFLAGS!=	${MAKE} -f bsd.own.mk -f ${.CURDIR}/../../../conf/kern.mk -V CWARNFLAGS
 .include 
diff --git a/sys/boot/pc98/boot2/asm.S b/sys/boot/pc98/boot2/asm.S
deleted file mode 100644
index de51618f162..00000000000
--- a/sys/boot/pc98/boot2/asm.S
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:34:13  rpd
- * $FreeBSD$
- */
-
-
-/*
-  Copyright 1988, 1989, 1990, 1991, 1992 
-   by Intel Corporation, Santa Clara, California.
-
-                All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-	.file "asm.s"
-
-#include "asm.h"
-
-
-CR0_PE_ON	=	0x1
-CR0_PE_OFF	=	0xfffffffe
-	.code16
-	.text
-
-/*
- *
- * real_to_prot()
- * 	transfer from real mode to protected mode.
- */
-
-ENTRY(real_to_prot)
-	/* guarantee that interrupt is disabled when in prot mode */
-	cli
-
-	/* load the gdtr */
-	.code32
-	addr32
-	data32
-	lgdt	EXT(Gdtr)
-	.code16
-
-	/* set the PE bit of CR0 */
-	mov	%cr0, %eax
-
-	or	$CR0_PE_ON, %eax
-	mov	%eax, %cr0 
-
-	/*
-	 * make intrasegment jump to flush the processor pipeline and
-	 * reload CS register
-	 */
-	.code32
-	data32
-	ljmp	$0x18, $xprot
-	.code16
-xprot:
-
-	/*
-	 * we are in USE32 mode now
-	 * set up the protected mode segment registers : DS, SS, ES, FS
-	 */
-	data32
-	movw	$0x20, %ax	/* data segment */
-	mov	%ax, %ds	/* gas would waste a prefix byte for movw */
-	mov	%ax, %ss
-	mov	%ax, %es
-	data32
-	movw	$0x10, %ax	/* flat segment */
-	mov	%ax, %fs
-
-#ifdef BDE_DEBUGGER
-	/* load idtr so we can debug */
-	lidt	EXT(Idtr_prot)
-#endif
-
-	ret
-
-/*
- *
- * prot_to_real()
- * 	transfer from protected mode to real mode
- * 
- */
-
-ENTRY(prot_to_real)
-
-	/* Prepare %ax while we're still in a mode that gas understands. */
-	data32
-	movw	$0x30, %ax
-
-	/* Change to use16 mode. */
-	.code32
-	ljmp	$0x28, $x16
-	.code16
-x16:
-
-	mov	%ax, %ds
-	mov	%ax, %ss
-	mov	%ax, %es
-	mov	%ax, %fs
-
-	/* clear the PE bit of CR0 */
-	mov	%cr0, %eax
-	and 	$CR0_PE_OFF, %eax
-	mov	%eax, %cr0
-
-	/*
-	 * make intersegment jmp to flush the processor pipeline
-	 * and reload CS register
-	 */
-	.code32
-	data32
-	ljmp	$BOOTSEG, $xreal
-	.code16
-xreal:
-
-	/*
-	 * we are in real mode now
-	 * set up the real mode segment registers : DS, SS, ES, FS
-	 */
-	mov	%cs, %ax
-	mov	%ax, %ds
-	mov	%ax, %ss
-	mov	%ax, %es
-	mov	%ax, %fs
-
-#ifdef BDE_DEBUGGER
-	/* load idtr so we can debug */
-	addr32
-	data32
-	lidt	EXT(Idtr_real)
-#endif
-
-	data32
-	ret
-
-/*
- * startprog(phyaddr)
- *	start the program on protected mode where phyaddr is the entry point
- *
- * XXX This whole mess should go away and we should run the boot code in
- * flat 32 bit mode with it linked -T BOOTSEG.  See the netboot code for
- * how this is done.
- */
-
-ENTRY(startprog)
-	.code32
-	push	%ebp
-	mov	%esp, %ebp
-	movl	%esp, %eax		/* Use eax as the old stack pointer */
-
-	/* convert the current stack to a 32 bit flat model */
-	movw	$0x10, %bx
-	data32
-	mov	%bx, %ss
-	addl	$(BOOTSEG<<4),%esp
-	
-	/* copy the arguments from the old stack to the new stack */
-	pushl	0x14(%eax)		/* &bootinfo */
-	pushl	$0			/* was &nfsdiskless */
-	pushl	$0			/* was esym */
-	pushl	$0			/* was cyloffset */
-	pushl	0x10(%eax)		/* bootdev */
-	pushl	0x0C(%eax)		/* howto */
-	movl	$(ourreturn),%ebx
-	addl	$(BOOTSEG<<4),%ebx	/* Fix it up for flat segments */
-	pushl	%ebx			/* our return address */
-	
-	/* push on our entry address */
-	pushl	$0x08			/* segment selector */
-	pushl	0x08(%eax)		/* kernel entry address */
-
-	/* convert over the other data segs */
-	movw	$0x10, %bx
-	data32
-	mov	%bx, %ds
-	data32
-	mov	%bx, %es
-
-	/* convert the PC (and code seg) */
-	lret
-ourreturn:
-	/* For now there is not much we can do, just lock in a loop */
-	jmp	ourreturn
-
-/*
- * pcpy(src, dst, cnt)
- *	where src is a virtual address and dst is a physical address
- */
-
-ENTRY(pcpy)
-	.code32
-	push	%ebp
-	mov	%esp, %ebp
-	push	%es
-	push	%esi
-	push	%edi
-	push	%ecx
-
-	cld
-
-	/* set %es to point at the flat segment */
-	movw	$0x10, %ax
-	mov	%ax, %es
-
-	mov	0x8(%ebp), %esi		/* source */
-	mov	0xc(%ebp), %edi		/* destination */
-	mov	0x10(%ebp), %ecx	/* count */
-
-	rep
-	movsb
-
-	pop	%ecx
-	pop	%edi
-	pop	%esi
-	pop	%es
-	pop	%ebp
-
-	ret
diff --git a/sys/boot/pc98/boot2/asm.h b/sys/boot/pc98/boot2/asm.h
deleted file mode 100644
index 914014dea7b..00000000000
--- a/sys/boot/pc98/boot2/asm.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.7  92/02/29  15:33:41  rpd
- * $FreeBSD$
- */
-
-#define S_ARG0	 4(%esp)
-#define S_ARG1	 8(%esp)
-#define S_ARG2	12(%esp)
-#define S_ARG3	16(%esp)
-
-#define FRAME	pushl %ebp; movl %esp, %ebp
-#define EMARF	leave
-
-#define B_ARG0	 8(%ebp)
-#define B_ARG1	12(%ebp)
-#define B_ARG2	16(%ebp)
-#define B_ARG3	20(%ebp)
-
-#ifdef	wheeze
-
-#define ALIGN 4
-#define EXT(x) x
-#define LEXT(x) x:
-#define LCL(x) ./**/x
-
-#define LB(x,n) ./**/x
-#define LBb(x,n) ./**/x
-#define LBf(x,n) ./**/x
-
-#define	SVC lcall $7,$0
-
-#define String .string
-#define Value  .value
-#define Times(a,b) [a\*b]
-#define Divide(a,b) [a\\b]
-
-#define INB	inb	(%dx)
-#define OUTB	outb	(%dx)
-#define INL	inl	(%dx)
-#define OUTL	outl	(%dx)
-
-#else	/* wheeze */
-
-#define ALIGN
-#define	LCL(x)	x
-
-#define LB(x,n) n
-#ifdef	__STDC__
-#define EXT(x) x
-#define LEXT(x) .type EXT(x),@function; EXT(x):
-#define LBb(x,n) n ## b
-#define LBf(x,n) n ## f
-#else	/* __STDC__ */
-#define EXT(x) _/**/x
-#define LEXT(x) .type EXT(x),@function; EXT(x)/**/:
-#define LBb(x,n) n/**/b
-#define LBf(x,n) n/**/f
-#endif	/* __STDC__ */
-#define SVC .byte 0x9a; .long 0; .word 0x7
-
-#define String	.ascii
-#define Value	.word
-#define Times(a,b) (a*b)
-#define Divide(a,b) (a/b)
-
-#define INB	inb	%dx, %al
-#define OUTB	outb	%al, %dx
-#define INL	inl	%dx, %eax
-#define OUTL	outl	%eax, %dx
-
-#endif	/* wheeze */
-
-#define addr32	.byte 0x67
-#define data32	.byte 0x66
-
-#ifdef GPROF
-#ifdef	__STDC__
-
-#define MCOUNT		.data; LB(x, 9); .long 0; .text; lea LBb(x, 9),%edx; call mcount
-#define	ENTRY(x)	.globl EXT(x); .align ALIGN; LEXT(x) ; \
-			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
-#define	ENTRY2(x,y)	.globl EXT(x); .globl EXT(y); \
-			.align ALIGN; LEXT(x) LEXT(y) ; \
-			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
-#define	ASENTRY(x) 	.globl x; .align ALIGN; x ## : ; \
-  			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
-
-#else	/* __STDC__ */
-
-#define MCOUNT		.data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount
-#define	ENTRY(x)	.globl EXT(x); .align ALIGN; LEXT(x) ; \
-			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
-#define	ENTRY2(x,y)	.globl EXT(x); .globl EXT(y); \
-			.align ALIGN; LEXT(x) LEXT(y)
-#define	ASENTRY(x) 	.globl x; .align ALIGN; x: ; \
-  			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
-
-#endif	/* __STDC__ */
-#else	/* GPROF */
-#ifdef	__STDC__
-
-#define MCOUNT
-#define	ENTRY(x)	.globl EXT(x); .align ALIGN; LEXT(x)
-#define	ENTRY2(x,y)	.globl EXT(x); .globl EXT(y); \
-			.align ALIGN; LEXT(x) LEXT(y)
-#define	ASENTRY(x)	.globl x; .align ALIGN; x ## :
-
-#else	/* __STDC__ */
-
-#define MCOUNT
-#define	ENTRY(x)	.globl EXT(x); .align ALIGN; LEXT(x)
-#define	ENTRY2(x,y)	.globl EXT(x); .globl EXT(y); \
-			.align ALIGN; LEXT(x) LEXT(y)
-#define	ASENTRY(x)	.globl x; .align ALIGN; x:
-
-#endif	/* __STDC__ */
-#endif	/* GPROF */
-
-#define	Entry(x)	.globl EXT(x); .align ALIGN; LEXT(x)
-#define	DATA(x)		.globl EXT(x); .align ALIGN; LEXT(x)
diff --git a/sys/boot/pc98/boot2/bios.S b/sys/boot/pc98/boot2/bios.S
deleted file mode 100644
index 8a884d6342d..00000000000
--- a/sys/boot/pc98/boot2/bios.S
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:34:26  rpd
- * $FreeBSD$
- */
-
-/*
-  Copyright 1988, 1989, 1990, 1991, 1992 
-   by Intel Corporation, Santa Clara, California.
-
-                All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-/*
- * Ported to PC-9801 by Yoshio Kimura
- */
-
-/*
- * Extensions for El Torito CD-ROM booting:
- *
- * Copyright © 1997 Pluto Technologies International, Inc.  Boulder CO
- * Copyright © 1997 interface business GmbH, Dresden.
- *      All rights reserved.
- *
- * This code has been written by Jörg Wunsch, Dresden.
- * Direct comments to .
- *
- * 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(S) ``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(S) 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.
- *
- */
-
-	.file	"bios.s"
-
-#include "asm.h"
-	.text
-
-#ifndef CDBOOT
-
-/*
- *  PC-9801/PC-9821 SCSI MO booting
- *    2002/06/05-07/03 Kawanobe Koh 
- *
- */
-scsi_hd:
-	.code16
-	push	%cx
-	push	%ds
-	mov	%bl, %cl		/* UA */
-	and	$0x0F, %cl
-	xor	%ax, %ax
-	mov	%ax, %ds
-	mov	(0x0482), %al		/* SCSI HD equipment bits */
-	shr	%cl, %al
-	pop	%ds
-	pop	%cx
-	test	$1, %al
-	ret
-
-/*
- * biosread(dev, cyl, head, sec, nsec, offset)
- *	Read "nsec" sectors from disk to offset "offset" in boot segment
- * BIOS call "INT 0x1B Function 0xn6" to read sectors from disk into memory
- *	Call with	%ah = 0xd6(for floppy disk) or 0x06(for hard disk)
- *			%al = DA/UA
- *			%bx = data length
- *			%ch = sector size(for floppy) or cylinder(for hard)
- *			%cl = cylinder
- *			%dh = head
- *			%dl = sector
- *			%es:%bp = segment:offset of buffer
- *	Return:		
- *			%al = 0x0 on success; err code on failure
- */
-
-ENTRY(biosread)
-	.code32
-	push	%ebp
-	mov	%esp, %ebp
-
-	push	%ebx
-	push	%esi
-	push	%edi
-
-	mov	0x08(%ebp), %bl		/* (byte) DA/UA */
-	mov	0x0C(%ebp), %ecx	/* (word) cylinder */
-	mov	0x10(%ebp), %dh		/* (byte) head */
-	mov	0x14(%ebp), %dl		/* (byte) sector */
-	mov	0x18(%ebp), %esi	/* (byte) number of sectors */
-	mov	0x1C(%ebp), %edi	/* (word) destination offset */
-
-	/* prot_to_real will set %es to BOOTSEG */
-	call	EXT(prot_to_real)	/* enter real mode */
-	.code16
-	mov	$0x06, %bh		/* read data function */
-	mov	%bl, %al		/* DA */
-	and	$0xF0, %al
-	cmp	$0x30, %al		/* 1440KB FD */
-	jz	read_floppy
-	cmp	$0x90, %al		/* 1200KB FD */
-	jz	read_floppy
-	cmp	$0xA0, %al		/* SCSI HD or MO */
-	jnz	read_next
-	call	scsi_hd
-	jnz	read_next
-read_linear:
-	mov	%dh, %al		/* change to linear sector */
-	shl	$5, %al			/* multiply by 32 sector per track */
-	add	%dl, %al
-	xor	%dh, %dh		/* higher 16 bits into %dx */
-	mov	%ch, %dl
-	mov	%cl, %ch		/* lower 16 bits into %cx */
-	mov	%al, %cl
-	and	$0x7F, %bl		/* linear access DA/UA */
-	jmp	read_next
-read_floppy:
-	inc	%dx			/* sector address begins from one */
-	mov	$0x02, %ch		/* 512 bytes sector */
-	mov	$0xD6, %bh		/* MT MFM retry seek */
-read_next:
-	mov	%si, %ax		/* number of sectors */
-	shl	$9, %ax			/* multiply by 512 bytes */
-	xchg	%bx, %ax
-	mov	%di, %bp		/* destination offset */
-	int	$0x1B			/* disk bios call */
-	jc	read_end
-	xor	%ax, %ax
-read_end:
-	mov	%ax, %bx		/* save return value */
-
-	.code32
-	data32
-	call	EXT(real_to_prot)	/* back to protected mode */
-
-	xor	%eax, %eax
-	mov	%bh, %al		/* return value in %eax */
-
-	pop	%edi
-	pop	%esi
-	pop	%ebx
-	pop	%ebp
-
-	ret
-
-#else /* CDBOOT */
-
-
-/*
- * int
- * getbootspec(struct specpacket *offset)
- *
- * Read CD-ROM boot specification packet to "offset".
- */
-ENTRY(getbootspec)
-	push	%ebp
-	mov	%esp, %ebp
-
-	push	%esi
-	push	%ebx
-
-	movw	0x8(%ebp), %si
-	mov	$0x7f, %edx
-
-	/* prot_to_real will set %es to BOOTSEG */
-	call	EXT(prot_to_real)	/* enter real mode */
-	movw	$0x4b01, %ax		/* (do not) terminate disk emulation */
-	movb	$0x7f, %dl		/* any drive */
-
-	sti
-	int	$0x13
-	cli
-
-	/* save return value (actually movw %ax, %bx) */
-	mov	%eax, %ebx
-
-	data32
-	call	EXT(real_to_prot)	/* back to protected mode */
-
-	xor	%eax, %eax
-	movb	%bh, %al		/* return value in %ax */
-
-	pop	%ebx
-	pop	%esi
-	pop	%ebp
-
-	ret
-
-
-/*
- * int
- * biosreadlba(struct daddrpacket *daddr)
- *	Read sectors using the BIOS "read extended" function
- * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
- *	Call with	%ah = 0x42
- *			%dl = drive (0x0 for floppy disk, or emulated CD)
- *			%ds:%si = ptr to disk address packet
- *	Return:
- *			%ah = 0x0 on success; err code on failure
- */
-
-ENTRY(biosreadlba)
-	push	%ebp
-	mov	%esp, %ebp
-
-	push	%ebx
-	push	%esi
-
-	movw	8(%ebp), %si
-	movl	$0, %edx		/* emulated CD is always drive 0 */
-
-	/* prot_to_real will set %es to BOOTSEG */
-	call	EXT(prot_to_real)	/* enter real mode */
-	movw	$0x4200, %ax		/* subfunction */
-	movb	$0, %dl
-
-	sti
-	int	$0x13
-	cli
-
-	/* save return value (actually movw %ax, %bx) */
-	mov	%eax, %ebx
-
-	data32
-	call	EXT(real_to_prot)	/* back to protected mode */
-
-	xor	%eax, %eax
-	movb	%bh, %al		/* return value in %ax */
-
-	pop	%esi
-	pop	%ebx
-	pop	%ebp
-
-	ret
-
-#endif /* !CDBOOT */
-
-/*
- * getc()
- * BIOS call "INT 18H Function 00H" to read character from keyboard
- *	Call with	%ah = 0x0
- *	Return:		%ah = keyboard scan code
- *			%al = ASCII character
- */
-
-ENTRY(getc)
-	.code32
-	push	%ebp
-	mov	%esp, %ebp
-	push	%ebx			/* save %ebx */
-	push    %esi
-	push    %edi
-
-	call	EXT(prot_to_real)
-	.code16
-
-	movb	$0x0, %ah
-	int	$0x18
-
-	movb	%al, %bl		/* real_to_prot uses %eax */
-
-	.code32
-	data32
-	call	EXT(real_to_prot)
-
-	xor	%eax, %eax
-	movb	%bl, %al
-
-	pop	%edi
-	pop	%esi
-	pop	%ebx
-	pop	%ebp
-	ret
-/*
- * ischar()
- *	if there is a character pending, return it; otherwise return 0
- * BIOS call "INT 18H Function 01H" to check whether a character is pending
- *	Call with	%ah = 0x1
- *	Return:
- *		If key waiting to be input:
- *			%ah = keyboard scan code
- *			%al = ASCII character
- *			%bh = 1
- *		else
- *			%bh = 0
- */
-ENTRY(ischar)
-	.code32
-	push	%ebp
-	mov	%esp, %ebp
-	push	%ebx
-	push    %esi
-	push    %edi
-
-	call	EXT(prot_to_real)	/* enter real mode */
-
-	xor	%ebx, %ebx
-	.code16
-	movb	$0x1, %ah
-	int	$0x18
-	andb	%bh, %bh
-	data32
-	jz	nochar
-	movb	%al, %bl
-
-nochar:
-	.code32
-	data32
-	call	EXT(real_to_prot)
-
-	xor	%eax, %eax
-	movb	%bl, %al
-
-	pop	%edi
-	pop	%esi
-	pop	%ebx
-	pop	%ebp
-	ret
-
-/*
- *
- * get_diskinfo():  return a word that represents the
- *	max number of sectors and heads and drives for this device
- *
- */
-
-ENTRY(get_diskinfo)
-	.code32
-	push	%ebp
-	mov	%esp, %ebp
-	push	%ebx
-
-	mov	0x08(%ebp), %bl		/* (byte) DA/UA */
-
-	call	EXT(prot_to_real)	/* enter real mode */
-	.code16
-	mov	%bl, %al		/* DA */
-	and	$0xf0, %al
-	mov	$18, %dl		/* 1440KB FD sectors per track */
-	cmp	$0x30, %al
-	jz	floppy
-	mov	$15, %dl		/* 1200KB FD sectors per track */
-	cmp	$0x90, %al
-	jz	floppy
-	cmp	$0xA0, %al		/* SCSI HD or MO */
-	jnz	sense
-	call	scsi_hd
-	jnz	sense
-
-	push	%ds			/* SCSI MO or CD ? */
-	xor	%ax, %ax
-	mov	%ax, %ds
-	and	$0x0F, %bx		/* UA */
-	shl	$2, %bx			/* parameter offset */
-	add	$0x0460, %bx
-	mov	(%bx), %al		/* SCSI equipment parameter[0] */
-	and	$0x1F, %al		/* peripheral device type */
-	cmp	$7, %al			/* SCSI MO */
-	jnz	good
-	add	$3, %bx
-	mov	(%bx), %al		/* SCSI equipment parameter[3] */
-	test	$0x30, %al		/* sector length from 256 to 2048 */
-	jnz	good
-	or	$0x10, %al		/* forced set 512 bytes sector */
-	mov	%al, (%bx)
-	mov	$0xA100, %dx		/* refered by C language */
-	mov	%dx, %ds
-	mov	%al, (%bx)
-good:
-	pop	%ds
-
-	mov	$0xFFFE, %cx		/* virtual 65535 cylinders setting */
-	mov	$0x0820, %dx		/* standard 8 heads and 32 sectors */
-	jmp	ok
-sense:
-	mov	$0x84, %ah		/* ask for disk info */
-	mov	%bl, %al
-	int	$0x1b
-	jnc	ok			/* use %cx and %dx after */
-	/*
-	 * Urk.  Call failed.  It is not supported for floppies by old BIOS's.
-	 * Guess it's a 15-sector floppy.
-	 */
-floppy:
-	mov	$79, %cx		/* 80 cylinders 1200K and 1440K FD */
-	mov	$2, %dh			/* 2 heads as double side */
-ok:
-	.code32
-	data32
-	call	EXT(real_to_prot)	/* back to protected mode */
-
-	/* 
-	 * form a longword representing all this gunk:
-	 *	16 bit cylinder
-	 *	 8 bit head
-	 *	 8 bit sector
-	 */
-	mov	%ecx, %eax
-	sal	$16, %eax		/* max cylinder number from zero */
-	mov	%dx, %ax		/* number of heads and sectors */
-
-	pop	%ebx
-	pop	%ebp
-	ret
-
-/*
- *
- * memsize(i) :  return the memory size in KB. i == 0 for conventional memory,
- *		i == 1 for extended memory
- *		Both have the return value in AX.
- *
- */
-
-ENTRY(memsize)
-	.code32
-	push	%ebp
-	mov	%esp, %ebp
-	push	%ebx
-	push    %esi
-	push    %edi
-
-	mov	8(%ebp), %ebx
-
-	xor	%eax, %eax
-	cmpb	$0x01, %bl
-	jnz	memcnv
-memext:
-	movb	0xA1401 - BOOTSEG * 0x10, %al
-	shll	$7, %eax
-	xorl	%ebx, %ebx
-	movw	0xA1594 - BOOTSEG * 0x10, %bx
-	shll	$10, %ebx
-	addl	%ebx, %eax
-	jmp	xdone
-
-memcnv:
-	movb	0xA1501 - BOOTSEG * 0x10, %al
-	andb	$0x07, %al
-	incl	%eax
-	shll	$7, %eax
-
-xdone:
-	pop	%edi
-	pop	%esi
-	pop	%ebx
-	pop	%ebp
-	ret
diff --git a/sys/boot/pc98/boot2/boot.c b/sys/boot/pc98/boot2/boot.c
deleted file mode 100644
index 4bdfbef7b14..00000000000
--- a/sys/boot/pc98/boot2/boot.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, [92/04/03  16:51:14  rvb]
- */
-/*
-  Copyright 1988, 1989, 1990, 1991, 1992
-   by Intel Corporation, Santa Clara, California.
-
-                All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN 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 "boot.h"
-#include 
-#include 
-#include 
-
-#define	ouraddr	(BOOTSEG << 4)		/* XXX */
-
-#define	BOOT_CONFIG_SIZE	512
-#define	BOOT_HELP_SIZE		2048
-#define	KERNEL_CONFIG_SIZE	512
-#define	NAMEBUF_LEN		1024	/* oversized to defend against gets() */
-
-static char boot_config[BOOT_CONFIG_SIZE];
-static char boot_help[BOOT_HELP_SIZE];
-char *name;
-static char kernel_config[KERNEL_CONFIG_SIZE];
-static char kernel_config_namebuf[NAMEBUF_LEN + sizeof "config"];
-static char linebuf[NAMEBUF_LEN];
-static char namebuf[NAMEBUF_LEN];
-struct bootinfo bootinfo;
-int loadflags;
-
-static void getbootdev(char *ptr, int *howto);
-static void loadprog(void);
-static void readfile(char *path, char *buf, size_t nbytes);
-
-/* NORETURN */
-void
-boot(int drive)
-{
-	int i, ret;
-	unsigned char disk_equips;
-
-	/* Pick up the story from the Bios on geometry of disks */
-
-	for(ret = 0; ret < 2; ret ++) {
-		if (*(unsigned char*)V(0xA155d) & (1 << ret)) {
-			bootinfo.bi_bios_geom[ret] = get_diskinfo(ret + 0x80);
-		}
-	}
-
-	bootinfo.bi_basemem = memsize(0);
-	bootinfo.bi_extmem = memsize(1);
-	bootinfo.bi_memsizes_valid = 1;
-
-	gateA20();
-
-	/* set machine type to PC98_SYSTEM_PARAMETER */
-	machine_check();
-
-	/*
-	 * The default boot device is the first partition in the
-	 * compatibility slice on the boot drive.
-	 */
-	dosdev = drive;
-	maj = (drive&0x70) >> 3;		/* a good first bet */
-	if (maj == 4) {	/* da */
-		disk_equips = *(unsigned char *)V(0xA1482);
-		unit = 0;
-		for (i=0; i<(drive&0x0f); i++) {
-			int media = ((unsigned *)V(0xA1460))[i] & 0x1F;
-
-			if ((disk_equips >> i) & 1)	/* HD */
-				unit++;
-			else if (media == 7)		/* MO */
-				unit++;
-		}
-	} else {
-		unit = drive & 0x0f;
-	}
-	readfile("boot.config", boot_config, BOOT_CONFIG_SIZE);
-		name = "/boot/loader";
-	if (boot_config[0] != '\0') {
-		getbootdev(boot_config, &loadflags);
-		printf("boot.config: %s", boot_config);
-		if (openrd() != 0)
-			name = "kernel";
-	}
-loadstart:
-	/* print this all each time.. (saves space to do so) */
-	/* If we have looped, use the previous entries as defaults */
-	printf("\r \n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory, %s%s console\n"
-	       "Boot default: %d:%s(%d,%c)%s\n"
-	       "%s\n"
-	       "boot: ",
-	       ouraddr, bootinfo.bi_basemem, bootinfo.bi_extmem,
-	       (loadflags & RB_SERIAL) ? "serial" : "internal",
-	       (loadflags & RB_DUAL) ? "/dual" : "",
-	       dosdev & 0x0f, devs[maj], unit, 'a' + part,
-	       name ? name : "*specify_a_kernel_name*",
-	       boot_help);
-
-	/*
-	 * Ignore flags from previous attempted boot, if any.
-	 * XXX this is now too strict.  Settings given in boot.config should
-	 * not be changed.
-	 */
-	loadflags &= (RB_DUAL | RB_SERIAL);
-
-	/*
-	 * Be paranoid and make doubly sure that the input buffer is empty.
-	 */
-	if (loadflags & (RB_DUAL | RB_SERIAL))
-		init_serial();
-
-	if (!gets(linebuf))
-		putchar('\n');
-	else
-		getbootdev(linebuf, &loadflags);
-	if (name == NULL)
-		goto loadstart;
-	ret = openrd();
-	if (ret != 0) {
-		if (ret > 0)
-			printf("Can't find %s\n", name);
-		goto loadstart;
-	}
-/*	if (inode.i_mode&IEXEC)
-		loadflags |= RB_KDB;
-*/
-	loadprog();
-	goto loadstart;
-}
-
-static void
-loadprog(void)
-{
-	struct exec head;
-	int startaddr;
-	int addr;	/* physical address.. not directly useable */
-	int bootdev;
-	int i;
-	unsigned pad;
-	char *s, *t;
-
-	read((void *)&head, sizeof(head));
-	if ( N_BADMAG(head)) {
-		printf("Invalid format!\n");
-		return;
-	}
-
-	poff = N_TXTOFF(head);
-	/*if(poff==0)
-		poff = 32;*/
-
-	/*
-	 * We assume that the entry address is the same as the lowest text
-	 * address and that the kernel startup code handles relocation by
-	 * this address rounded down to a multiple of 16M.
-	 */
-	startaddr = head.a_entry & 0x00FFFFFF;
-	addr =  startaddr;
-	printf("Booting %d:%s(%d,%c)%s @ 0x%x\n"
-			, dosdev & 0x0f
-			, devs[maj]
-			, unit
-			, 'a'+part
-			, name
-			, addr);
-	if(addr < 0x00100000)
-	{
-		/*
-		 * Bail out, instead of risking to damage the BIOS
-		 * variables, the loader, or the adapter memory area.
-		 * We don't support loading below 1 MB any more.
-		 */
-		printf("Start address too low\n");
-		return;
-	}
-	printf("text=0x%x ", head.a_text);
-	/********************************************************/
-	/* LOAD THE TEXT SEGMENT				*/
-	/********************************************************/
-	xread((void *)addr, head.a_text);
-	addr += head.a_text;
-
-	/********************************************************/
-	/* Load the Initialised data after the text		*/
-	/********************************************************/
-	while (addr & PAGE_MASK)
-                *(char *)addr++ = 0;
-
-	printf("data=0x%x ", head.a_data);
-	xread((void *)addr, head.a_data);
-	addr += head.a_data;
-
-	/********************************************************/
-	/* Skip over the uninitialised data			*/
-	/* (but clear it)					*/
-	/********************************************************/
-	printf("bss=0x%x ", head.a_bss);
-
-/*
- * XXX however, we should be checking that we don't load ... into
- * nonexistent memory.  A full symbol table is unlikely to fit on 4MB
- * machines.
- */
-	/* kzip & kernel will zero their own bss */
-	addr += head.a_bss;
-
-	/* Pad to a page boundary. */
-	pad = (unsigned)addr & PAGE_MASK;
-	if (pad != 0) {
-		pad = PAGE_SIZE - pad;
-		addr += pad;
-	}
-	bootinfo.bi_symtab = addr;
-
-	/********************************************************/
-	/* Copy the symbol table size				*/
-	/********************************************************/
-	pcpy(&head.a_syms, (void *)addr, sizeof(head.a_syms));
-	addr += sizeof(head.a_syms);
-
-	/********************************************************/
-	/* Load the symbol table				*/
-	/********************************************************/
-	printf("symbols=[+0x%x+0x%x+0x%x", pad, sizeof(head.a_syms),
-	       head.a_syms);
-	xread((void *)addr, head.a_syms);
-	addr += head.a_syms;
-
-	/********************************************************/
-	/* Load the string table size				*/
-	/********************************************************/
-	read((void *)&i, sizeof(int));
-	pcpy(&i, (void *)addr, sizeof(int));
-	i -= sizeof(int);
-	addr += sizeof(int);
-
-	/********************************************************/
-	/* Load the string table				*/
-	/********************************************************/
-       printf("+0x%x+0x%x]\n", sizeof(int), i);
-	xread((void *)addr, i);
-	addr += i;
-
-	bootinfo.bi_esymtab = addr;
-
-	/*
-	 * For backwards compatibility, use the previously-unused adaptor
-	 * and controller bitfields to hold the slice number.
-	 */
-	bootdev = MAKEBOOTDEV(maj, slice, unit, part);
-
-	bootinfo.bi_version = BOOTINFO_VERSION;
-	bootinfo.bi_kernelname = (u_int32_t)(name + ouraddr);
-	bootinfo.bi_nfs_diskless = 0;
-	bootinfo.bi_size = sizeof(bootinfo);
-	bootinfo.bi_bios_dev = dosdev;
-
-	/*
-	 * Load the kernel config file (if any).  Its name is given by
-	 * appending ".config" to the kernel name.  Build the name inline
-	 * because no str*() functions are available.  The file has to be
-	 * copied to &disklabel for userconfig.  It can't be loaded there
-	 * directly because the label is used late in readfile() in some
-	 * unusual cases.
-	 */
-	s = name;
-	t = kernel_config_namebuf;
-	do
-		;
-	while ((*t++ = *s++) != '\0');
-	s = ".config";
-	--t;
-	do
-		;
-	while ((*t++ = *s++) != '\0');
-	readfile(kernel_config_namebuf, kernel_config, KERNEL_CONFIG_SIZE);
-	pcpy(kernel_config, (char *)&disklabel + ouraddr, KERNEL_CONFIG_SIZE);
-
-	printf("total=0x%x entry point=0x%x\n", addr, startaddr);
-	startprog(startaddr, loadflags | RB_BOOTINFO, bootdev,
-		  (unsigned)&bootinfo + ouraddr);
-}
-
-static void
-readfile(char *path, char *buf, size_t nbytes)
-{
-	int openstatus;
-
-	buf[0] = '\0';
-	name = path;
-	openstatus = openrd();
-	if (openstatus == 0) {
-		/* XXX no way to determine file size. */
-		read(buf, nbytes);
-	}
-	buf[nbytes - 1] = '\0';
-}
-
-static void
-getbootdev(char *ptr, int *howto)
-{
-	char c;
-	int f;
-	char *p;
-
-	/* Copy the flags to save some bytes. */
-	f = *howto;
-
-	c = *ptr;
-	for (;;) {
-nextarg:
-		while (c == ' ' || c == '\n')
-			c = *++ptr;
-		if (c == '-')
-			while ((c = *++ptr) != '\0') {
-				if (c == ' ' || c == '\n')
-					goto nextarg;
-				if (c == 'a')
-					f |= RB_ASKNAME;
-				if (c == 'C')
-					f |= RB_CDROM;
-				if (c == 'D')
-					f ^= RB_DUAL;
-				if (c == 'd')
-					f |= RB_KDB;
-				if (c == 'g')
-					f |= RB_GDB;
-				if (c == 'h')
-					f ^= RB_SERIAL;
-				if (c == 'P')
-					f |= RB_PROBEKBD;
-				if (c == 'r')
-					f |= RB_DFLTROOT;
-				if (c == 's')
-					f |= RB_SINGLE;
-				if (c == 'v')
-					f |= RB_VERBOSE;
-			}
-		if (c == '\0')
-			break;
-		p = name = namebuf;
-		while (c != '\0' && c != ' ' && c != '\n') {
-			*p++ = c;
-			c = *++ptr;
-		}
-		*p = '\0';
-	}
-	if (f & RB_PROBEKBD) {
-		if (probe_keyboard()) {
-			f |= RB_DUAL | RB_SERIAL;
-			printf("No keyboard found\n");
-		} else
-			printf("Keyboard found\n");
-	}
-	if (f & (RB_DUAL | RB_SERIAL))
-		init_serial();
-	*howto = f;
-}
diff --git a/sys/boot/pc98/boot2/boot.h b/sys/boot/pc98/boot2/boot.h
deleted file mode 100644
index e39fee53d1e..00000000000
--- a/sys/boot/pc98/boot2/boot.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:35:03  rpd
- * $FreeBSD$
- */
-
-#include 
-#include 
-
-typedef	int32_t	ufs_daddr_t;
-
-#define	MAXFRAG	8
-
-#include "quota.h"
-#include "inode.h"
-#include "fs.h"
-
-#define	RB_DUAL		0x40000		/* XXX */
-#define	RB_PROBEKBD	0x80000		/* XXX */
-
-extern char *devs[];
-extern char *name;
-extern struct fs *fs;
-extern struct inode inode;
-extern int dosdev, unit, slice, part, maj, boff, poff;
-extern unsigned tw_chars;
-extern int loadflags;
-extern struct disklabel disklabel;
-
-/* asm.S */
-#if ASM_ONLY
-void real_to_prot(void);
-void prot_to_real(void);
-#endif
-void startprog(unsigned int physaddr, int howto, int bootdev,
-	       /* XXX struct bootinfo * */ unsigned int bootinfo);
-void pcpy(const void *src, void *dst, size_t count);
-
-/* bios.S */
-int biosread(int dev, int cyl, int head, int sec, int nsec, void *offset);
-void putc(int c);
-int getc(void);
-int ischar(void);
-int get_diskinfo(int drive);
-int memsize(int extended);
-
-/* boot.c */
-void boot(int drive);
-
-/* boot2.S */
-void boot2(void);
-
-/* disk.c */
-int devopen(void);
-void devread(char *iodest, int sector, int cnt);
-
-/* io.c */
-void gateA20(void);
-void printf(const char *format, ...);
-void putchar(int c);
-void delay1ms(void);
-int gets(char *buf);
-int strcmp(const char *s1, const char *s2);
-#ifdef CDBOOT
-int strcasecmp(const char *s1, const char *s2);
-#endif /* !CDBOOT */
-void memcpy(const void *from, void *to, size_t len);
-void twiddle(void);
-void machine_check(void);
-
-/* probe_keyboard.c */
-int probe_keyboard(void);
-
-/* serial.S */
-void serial_putc(int ch);
-int serial_getc(void);
-int serial_ischar(void);
-void init_serial(void);
-
-/* sys.c */
-void xread(char *addr, int size);
-void read(char *buffer, int count);
-int openrd(void);
-
-#define V(ra)	(ra - BOOTSEG * 0x10)
diff --git a/sys/boot/pc98/boot2/boot1.S b/sys/boot/pc98/boot2/boot1.S
new file mode 100644
index 00000000000..e4f48eb1a26
--- /dev/null
+++ b/sys/boot/pc98/boot2/boot1.S
@@ -0,0 +1,395 @@
+/*-
+ * Copyright (c) 2008-2009 TAKAHASHI Yoshihiro
+ * 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$
+ */
+
+/* Memory Locations */
+		.set STACK_OFF,0x6000		# Stack offset
+		.set LOAD_SIZE,8192		# Load size
+		.set DAUA,0x0584		# DA/UA
+		.set MEM_REL,0x700		# Relocation address
+		.set MEM_ARG,0x900		# Arguments
+		.set MEM_BUF,0x8cec		# Load area
+		.set MEM_BTX,0x9000		# BTX start
+		.set MEM_JMP,0x9010		# BTX entry point
+		.set MEM_USR,0xa000		# Client start
+
+/* PC98 machine type from sys/pc98/pc98/pc98_machdep.h */
+		.set MEM_SYS,		0xa100	# System common area segment
+		.set PC98_MACHINE_TYPE,	0x0620	# PC98 machine type
+		.set EPSON_ID,		0x0624	# EPSON machine id
+
+		.set M_NEC_PC98,	0x0001
+		.set M_EPSON_PC98,	0x0002
+		.set M_NOT_H98,		0x0010
+		.set M_H98,		0x0020
+		.set M_NOTE,		0x0040
+		.set M_NORMAL,		0x1000
+		.set M_8M,		0x8000
+
+/* Partition Constants */
+		.set PRT_OFF,0x1be		# Partition offset
+
+/* Misc. Constants */
+		.set SIZ_PAG,0x1000		# Page size
+		.set SIZ_SEC,0x200		# Sector size
+
+		.set NSECT,0x10
+
+		.globl start
+		.globl read
+		.globl putc
+		.code16
+
+start:		jmp main
+
+boot_cyl:	.org 4
+		.ascii "IPL1   "
+
+main:		cld
+
+		/* Setup the stack */
+		xor %si,%si
+		mov %si,%ss
+		mov $STACK_OFF,%sp
+
+		push %cx
+
+		/* Relocate ourself to MEM_REL */
+		push %cs
+		pop %ds
+		mov %si,%es
+		mov $MEM_REL,%di
+		mov $SIZ_SEC,%cx
+		rep
+		movsb
+
+		/* Transfer PC-9801 system common area */
+		xor %ax,%ax
+		mov %ax,%si
+		mov %ax,%ds
+		mov %ax,%di
+		mov $MEM_SYS,%ax
+		mov %ax,%es
+		mov $0x0600,%cx
+		rep
+		movsb
+
+		/* Transfer EPSON machine type */
+		mov $0xfd00,%ax
+		mov %ax,%ds
+		mov (0x804),%eax
+		and $0x00ffffff,%eax
+		mov %eax,%es:(EPSON_ID)
+
+		/* Set machine type to PC98_SYSTEM_PARAMETER */
+#ifdef SET_MACHINE_TYPE
+		call set_machine_type
+#else
+		mov $M_NEC_PC98+M_NOT_H98,%eax
+		mov %eax,%es:(PC98_MACHINE_TYPE)
+#endif
+
+		/* Setup graphic screen */
+		mov $0x42,%ah		/* 640x400 */
+		mov $0xc0,%ch
+		int $0x18
+		mov $0x40,%ah		/* graph on */
+		int $0x18
+
+		/* Setup text screen */
+		mov $0x0a00,%ax		/* 80x25 */
+		int $0x18
+		mov $0x0c,%ah		/* text on */
+		int $0x18
+		mov $0x13,%ah		/* cursor home */
+		xor %dx,%dx
+		int $0x18
+		mov $0x11,%ah		/* cursor on */
+		int $0x18
+
+		/* Setup keyboard */
+		mov $0x03,%ah
+		int $0x18
+
+		pop %cx
+
+		/* bootstrap passes */
+		xor %edi,%edi
+		mov %di,%ds
+		mov %di,%es
+		mov %cs,%bx
+		cmp $0x1fe0,%bx
+		jz boot_fd
+		cmp $0x1fc0,%bx
+		jnz boot_hd
+		xor %cx,%cx
+		mov (DAUA),%al
+		and $0xf0,%al
+		cmp $0x30,%al
+		jz boot_fd
+		cmp $0x90,%al
+		jnz boot_hd
+boot_fd:	xor %cx,%cx
+		jmp boot_load
+boot_hd:	test %cx,%cx
+		jnz boot_load
+		mov %cs:(boot_cyl),%cx
+boot_load:	mov %cx,MEM_ARG		/* Save cylinder number */
+		mov %cx,%di
+		xor %dx,%dx
+		mov $LOAD_SIZE,%bx
+		mov $MEM_BUF,%bp
+		push %cs
+		callw read
+		jc error
+
+		/* Transfer boot2.bin */
+		mov $MEM_BTX,%bx
+		mov 0xa(%bx),%si	/* BTX size */
+		add %bx,%si		/* start of boot2.bin */
+		mov $MEM_USR+SIZ_PAG*2,%di
+		mov $MEM_BTX+(NSECT-1)*SIZ_SEC,%cx
+		sub %si,%cx
+		rep
+		movsb
+
+		/* Enable A20 */
+		xor %ax,%ax
+		outb %al,$0xf2
+		mov $0x02,%al
+		outb %al,$0xf6
+
+		/* Start BTX */
+		ljmp $0x0000,$MEM_JMP
+
+/*
+ * Reads sectors from the disk.
+ * Call with:
+ *
+ * %bx		- bytes to read
+ * %cx		- cylinder
+ * %dh		- head
+ * %dl		- sector
+ * %edi		- lba
+ * %es:(%bp)	- buffer to read data into
+ */
+read:		xor %ax,%ax
+		mov %ax,%ds
+		mov $0x06,%ah
+		mov (DAUA),%al
+		mov %ax,%si
+		and $0xf0,%al
+		cmp $0x30,%al		/* 1.44MB FDD */
+		jz read_fd
+		cmp $0x90,%al		/* 1MB FDD */
+		jz read_fd
+		cmp $0xa0,%al		/* Is SCSI device? */
+		jnz read_load
+		push %cx
+		mov %si,%cx
+		and $0x0f,%cl
+		inc %cl
+		mov (0x482),%ah
+		shr %cl,%ah		/* Is SCSI HDD? */
+		pop %cx
+		jc read_load
+		and $0xff7f,%si		/* SCSI MO */
+		mov %di,%cx
+		shr $16,%di
+		mov %di,%dx
+		jmp read_load
+read_fd:	or $0xd000,%si
+		or $0x0200,%cx
+		inc %dx
+read_load:	mov %si,%ax
+		int $0x1b
+		lret
+
+/*
+ * Print out the error message, wait for a keypress, and then reboot
+ * the machine.
+ */
+error:		push %cs
+		pop %ds
+		mov $msg_eread,%si
+		call putstr
+		xor %ax,%ax		/* Get keypress */
+		int $0x18
+		xor %ax,%ax		/* CPU reset */
+		outb %al,$0xf0
+halt:		hlt
+		jmp halt		/* Spin */
+
+/*
+ * Display a null-terminated string.
+ */
+putstr.0:	push %cs
+		callw putc
+putstr:		lodsb
+		test %al,%al
+		jne putstr.0
+		ret
+
+/*
+ * Display a single char.
+ */
+putc:		pusha
+		xor %dx,%dx
+		mov %dx,%ds
+		mov MEM_REL+cursor-start,%di
+		mov $0xa000,%bx
+		mov %bx,%es
+		mov $(80*2),%cx
+
+		cmp $0x08,%al
+		je putc.bs
+		cmp $0x0d,%al
+		je putc.cr
+		cmp $0x0a,%al
+		je putc.lf
+		cmp $0x5c,%al			/* \ */
+		jne 1f
+		mov $0xfc,%al
+1:		movb $0xe1,%es:0x2000(%di)
+		stosw
+		jmp putc.scr
+putc.bs:	test %di,%di
+		jz putc.move
+		dec %di
+		dec %di
+		movb $0xe1,%es:0x2000(%di)
+		movw $0x20,%es:(%di)
+		jmp putc.move
+putc.cr:	mov %di,%ax
+		div %cx
+		sub %dx,%di
+		jmp putc.move
+putc.lf:	add %cx,%di
+putc.scr:	cmp $(80*2*25),%di		/* Scroll screen */
+		jb putc.move
+		push %ds
+		mov %bx,%ds
+		mov $(80*2),%si
+		xor %di,%di
+		mov $(80*24/2),%cx
+		rep
+		movsl
+		xor %ax,%ax
+		mov $0x20,%al
+		mov $80,%cl
+		rep
+		stosw
+		pop %ds
+		mov $(80*24*2),%di
+putc.move:	mov %di,MEM_REL+cursor-start	/* Move cursor */
+		mov $0x13,%ah
+		mov %di,%dx
+		int $0x18
+		popa
+		lret
+
+cursor:		.word 0
+
+#ifdef SET_MACHINE_TYPE
+/*
+ * Set machine type to PC98_SYSTEM_PARAMETER.
+ */
+set_machine_type:
+		xor %edx,%edx
+		mov %dx,%ds
+//		mov $MEM_SYS,%ax
+//		mov %ax,%es
+
+		/* Wait V-SYNC */
+vsync.1:	inb $0x60,%al
+		test $0x20,%al
+		jnz vsync.1
+vsync.2:	inb $0x60,%al
+		test $0x20,%al
+		jz vsync.2
+
+		/* ANK 'A' font */
+		xor %al,%al
+		outb %al,$0xa1
+		mov $0x41,%al
+		outb %al,$0xa3
+
+		/* Get 'A' font from CG window */
+		push %ds
+		mov $0xa400,%ax
+		mov %ax,%ds
+		xor %eax,%eax
+		xor %bx,%bx
+		mov $4,%cx
+font.1:		add (%bx),%eax
+		add $4,%bx
+		loop font.1
+		pop %ds
+		cmp $0x6efc58fc,%eax
+		jnz m_epson
+
+m_pc98:		or $M_NEC_PC98,%edx
+		mov $0x0458,%bx
+		mov (%bx),%al
+		test $0x80,%al
+		jz m_not_h98
+		or $M_H98,%edx
+		jmp 1f
+m_epson:	or $M_EPSON_PC98,%edx
+m_not_h98:	or $M_NOT_H98,%edx
+
+1:		inb $0x42,%al
+		test $0x20,%al
+		jz 1f
+		or $M_8M,%edx
+
+1:		mov $0x0400,%bx
+		mov (%bx),%al
+		test $0x80,%al
+		jz 1f
+		or $M_NOTE,%edx
+
+1:		mov $PC98_MACHINE_TYPE,%bx
+		mov %edx,%es:(%bx)
+		ret
+#endif
+
+/* Messages */
+
+msg_eread:	.asciz "Error\r\n"
+
+		.org PRT_OFF,0x90
+
+/* Partition table */
+
+		.fill 0x30,0x1,0x0
+		.byte 0x80, 0x00, 0x01, 0x00
+		.byte 0xa5, 0xff, 0xff, 0xff
+		.byte 0x00, 0x00, 0x00, 0x00
+		.byte 0x50, 0xc3, 0x00, 0x00
+
+		.word 0xaa55			# Magic number
diff --git a/sys/boot/pc98/boot2/boot2.S b/sys/boot/pc98/boot2/boot2.S
deleted file mode 100644
index be85030b089..00000000000
--- a/sys/boot/pc98/boot2/boot2.S
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:35:26  rpd
- *	boot2.S,v 1.6 1995/01/25 21:37:40 bde Exp
- * $FreeBSD$
- */
-/*
- * Ported to PC-9801 by Yoshio Kimura
- */
-
-#include	"asm.h"
-
-/* Conventional GDT indexes. */
-#define BOOT_CS_INDEX		3
-#define BOOT_CS16_INDEX		5
-#define BOOT_DS_INDEX		4
-
-#ifdef BDE_DEBUGGER
-#define DB_CS_INDEX		14
-#define DB_CS16_INDEX		15
-#define DB_DS_INDEX		16
-#define GDT_INDEX		17
-#endif
-
-/* Vector numbers. */
-#define BREAKPOINT_VECTOR	3
-#define DEBUG_VECTOR		1
-
-/*
- * boot2() -- second stage boot
- * SP points to default string if found
- */
-	.code16
-ENTRY(boot2)
-	subl	%eax, %eax
-	mov	%cs, %ax
-	mov	%ax, %ds
-	mov	%ax, %es
-	shll	$4, %eax
-
-	/* fix up GDT entries for bootstrap */
-#define FIXUP(gdt_index) \
-	.code32; \
-	addr32; \
-	movl	%eax, EXT(Gdt)+(8*gdt_index)+2;	/* actually movw %ax */ \
-	addr32; \
-	movb	%bl, EXT(Gdt)+(8*gdt_index)+4; \
-	.code16
-
-	shld	$16, %eax, %ebx
-	FIXUP(BOOT_CS_INDEX)
-	FIXUP(BOOT_CS16_INDEX)
-	FIXUP(BOOT_DS_INDEX)
-
-	/* fix up GDT pointer */
-	movl	%eax, %ecx
-	addl	$ EXT(Gdt), %eax
-	.code32
-	addr32
-	data32
-	movl	%eax, EXT(Gdtr)+2
-	.code16
-
-#ifdef BDE_DEBUGGER
-	/* fix up GDT entry for GDT */
-	data32
-	shld	$16, %eax, %ebx
-	FIXUP(GDT_INDEX)
-
-	/* fix up IDT pointer */
-	data32
-	addl	$ EXT(Idt), %ecx
-	addr32
-	data32
-	movl	%ecx, EXT(Idtr_prot)+2
-
-	/* %es = vector table segment for a while */
-	push	%es
-	data32
-	subl	%eax, %eax
-	mov	%ax, %es
-
-	/* fix up GDT entries for bdb */
-	data32
-	movl	$4*DEBUG_VECTOR, %esi
-	addr32
-	movl	%es: 2(%esi), %eax	/* actually movw to %ax */
-	data32
-	shll	$4, %eax
-	data32
-	shld	$16, %eax, %ebx
-	FIXUP(DB_CS_INDEX)
-	FIXUP(DB_CS16_INDEX)
-	FIXUP(DB_DS_INDEX)
-
-	/* Fetch entry points of bdb's protected mode trap handlers.  These
-	 * are stored at 2 before the corresponding entry points for real mode.
-	 */
-	data32
-	subl	%ebx, %ebx
-	addr32
-	movl	%es: (%esi), %ebx	/* actually movw to %bx */
-	data32
-	subl	%ecx, %ecx
-	addr32
-	movl	%es: 4*(BREAKPOINT_VECTOR-DEBUG_VECTOR)(%esi), %ecx
-					/* actually movw to %cx */
-
-	/* %es = bdb segment for a while */
-	data32
-	shrl	$4, %eax
-	mov	%ax, %es
-
-	/* fix up IDT entries for bdb */
-	data32
-	subl	$2, %ebx		/* calculate EA to check it */
-	jb	1f			/* give up if it would trap */
-	addr32
-	movl	%es: (%ebx), %eax	/* actually movw to %ax */
-	addr32
-	movl	%eax, EXT(Idt)+8*DEBUG_VECTOR	/* actually movw %ax */
-1:
-	data32
-	subl	$2, %ecx
-	jb	1f
-	addr32
-	movl	%es: (%ecx), %eax	/* actually movw to %ax */
-	addr32
-	movl	%eax, EXT(Idt)+8*BREAKPOINT_VECTOR	/* actually movw %ax */
-1:
-
-	/* finished with groping in real mode segments */
-	pop	%es
-#endif /* BDE_DEBUGGER */
-
-	/* change to protected mode */
-	.code32
-	data32
-	call	EXT(real_to_prot)
-
-	/* clear the bss */
-	movl	$ EXT(edata), %edi	/* no EXT(_edata) - krufty ld */
-	movl	$ EXT(end), %ecx	/* or EXT(_end) */
-	subl	%edi, %ecx
-	subb	%al, %al
-	rep
-	stosb
-
-#ifdef NAMEBLOCK
-	movl	%esp, EXT(dflt_name)
-#endif
-
-	movb	0xA1584 - BOOTSEG * 0x10, %dl
-	movzbl	%dl, %edx	/* discard head (%dh) and random high bits */
-	pushl	%edx
-	call	EXT(boot)
-oops:
-	hlt
-	jmp	oops
diff --git a/sys/boot/pc98/boot2/boot2.c b/sys/boot/pc98/boot2/boot2.c
new file mode 100644
index 00000000000..8c833ba02d8
--- /dev/null
+++ b/sys/boot/pc98/boot2/boot2.c
@@ -0,0 +1,842 @@
+/*-
+ * Copyright (c) 2008-2009 TAKAHASHI Yoshihiro
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+#include 
+
+#include "boot2.h"
+#include "lib.h"
+
+#define IO_KEYBOARD	1
+#define IO_SERIAL	2
+
+#define SECOND		1	/* Circa that many ticks in a second. */
+
+#define RBX_ASKNAME	0x0	/* -a */
+#define RBX_SINGLE	0x1	/* -s */
+/* 0x2 is reserved for log2(RB_NOSYNC). */
+/* 0x3 is reserved for log2(RB_HALT). */
+/* 0x4 is reserved for log2(RB_INITNAME). */
+#define RBX_DFLTROOT	0x5	/* -r */
+#define RBX_KDB 	0x6	/* -d */
+/* 0x7 is reserved for log2(RB_RDONLY). */
+/* 0x8 is reserved for log2(RB_DUMP). */
+/* 0x9 is reserved for log2(RB_MINIROOT). */
+#define RBX_CONFIG	0xa	/* -c */
+#define RBX_VERBOSE	0xb	/* -v */
+#define RBX_SERIAL	0xc	/* -h */
+#define RBX_CDROM	0xd	/* -C */
+/* 0xe is reserved for log2(RB_POWEROFF). */
+#define RBX_GDB 	0xf	/* -g */
+#define RBX_MUTE	0x10	/* -m */
+/* 0x11 is reserved for log2(RB_SELFTEST). */
+/* 0x12 is reserved for boot programs. */
+/* 0x13 is reserved for boot programs. */
+#define RBX_PAUSE	0x14	/* -p */
+#define RBX_QUIET	0x15	/* -q */
+#define RBX_NOINTR	0x1c	/* -n */
+/* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
+#define RBX_DUAL	0x1d	/* -D */
+/* 0x1f is reserved for log2(RB_BOOTINFO). */
+
+/* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */
+#define RBX_MASK	(OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
+			OPT_SET(RBX_DFLTROOT) | OPT_SET(RBX_KDB ) | \
+			OPT_SET(RBX_CONFIG) | OPT_SET(RBX_VERBOSE) | \
+			OPT_SET(RBX_SERIAL) | OPT_SET(RBX_CDROM) | \
+			OPT_SET(RBX_GDB ) | OPT_SET(RBX_MUTE) | \
+			OPT_SET(RBX_PAUSE) | OPT_SET(RBX_DUAL))
+
+#define PATH_CONFIG	"/boot.config"
+#define PATH_BOOT3	"/boot/loader"
+#define PATH_KERNEL	"/boot/kernel/kernel"
+
+#define ARGS		0x900
+#define NOPT		14
+#define NDEV		3
+#define V86_CY(x)	((x) & PSL_C)
+#define V86_ZR(x)	((x) & PSL_Z)
+
+#define DRV_DISK	0xf0
+#define DRV_UNIT	0x0f
+
+#define TYPE_AD		0
+#define TYPE_DA		1
+#define TYPE_FD		2
+
+#define OPT_SET(opt)	(1 << (opt))
+#define OPT_CHECK(opt)	((opts) & OPT_SET(opt))
+
+extern uint32_t _end;
+
+static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
+static const unsigned char flags[NOPT] = {
+    RBX_DUAL,
+    RBX_SERIAL,
+    RBX_ASKNAME,
+    RBX_CDROM,
+    RBX_CONFIG,
+    RBX_KDB,
+    RBX_GDB,
+    RBX_MUTE,
+    RBX_NOINTR,
+    RBX_PAUSE,
+    RBX_QUIET,
+    RBX_DFLTROOT,
+    RBX_SINGLE,
+    RBX_VERBOSE
+};
+
+static const char *const dev_nm[NDEV] = {"ad", "da", "fd"};
+static const unsigned char dev_maj[NDEV] = {30, 4, 2};
+static const unsigned char dev_daua[NDEV] = {0x80, 0xa0, 0x90};
+
+static struct dsk {
+    unsigned daua;
+    unsigned type;
+    unsigned disk;
+    unsigned unit;
+    unsigned head;
+    unsigned sec;
+    unsigned slice;
+    unsigned part;
+    unsigned start;
+} dsk;
+static char cmd[512], cmddup[512];
+static char kname[1024];
+static uint32_t opts;
+static int comspeed = SIOSPD;
+static struct bootinfo bootinfo;
+static uint8_t ioctrl = IO_KEYBOARD;
+
+void exit(int);
+static void load(void);
+static int parse(void);
+static int xfsread(ino_t, void *, size_t);
+static int dskread(void *, unsigned, unsigned);
+static void printf(const char *,...);
+static void putchar(int);
+static uint32_t memsize(void);
+static int drvread(void *, unsigned);
+static int keyhit(unsigned);
+static int xputc(int);
+static int xgetc(int);
+static int getc(int);
+
+static void memcpy(void *, const void *, int);
+static void
+memcpy(void *dst, const void *src, int len)
+{
+    const char *s = src;
+    char *d = dst;
+
+    while (len--)
+        *d++ = *s++;
+}
+
+static inline int
+strcmp(const char *s1, const char *s2)
+{
+    for (; *s1 == *s2 && *s1; s1++, s2++);
+    return (unsigned char)*s1 - (unsigned char)*s2;
+}
+
+#define	UFS_SMALL_CGBASE
+#include "ufsread.c"
+
+static inline int
+xfsread(ino_t inode, void *buf, size_t nbyte)
+{
+    if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
+	printf("Invalid %s\n", "format");
+	return -1;
+    }
+    return 0;
+}
+
+static inline uint32_t
+memsize(void)
+{
+    u_char *p = (u_char *)PTOV(0);
+
+    return *(p + 0x401) * 128 * 1024 + *(u_int16_t *)(p + 0x594) * 1024 * 1024;
+}
+
+static inline void
+getstr(void)
+{
+    char *s;
+    int c;
+
+    s = cmd;
+    for (;;) {
+	switch (c = xgetc(0)) {
+	case 0:
+	    break;
+	case '\177':
+	case '\b':
+	    if (s > cmd) {
+		s--;
+		printf("\b \b");
+	    }
+	    break;
+	case '\n':
+	case '\r':
+	    *s = 0;
+	    return;
+	default:
+	    if (s - cmd < sizeof(cmd) - 1)
+		*s++ = c;
+	    putchar(c);
+	}
+    }
+}
+
+static inline void
+putc(int c)
+{
+
+    v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
+    v86.addr = PUTCORG;		/* call to putc in boot1 */
+    v86.eax = c;
+    v86int();
+    v86.ctl = V86_FLAGS;
+}
+
+static inline int
+is_scsi_hd(void)
+{
+
+    if ((*(u_char *)PTOV(0x482) >> dsk.unit) & 0x01)
+	return 1;
+
+    return 0;
+}
+
+static inline void
+fix_sector_size(void)
+{
+    u_char *p;
+
+    p = (u_char *)PTOV(0x460 + dsk.unit * 4);	/* SCSI equipment parameter */
+
+    if ((p[0] & 0x1f) == 7) {		/* SCSI MO */
+	if (!(p[3] & 0x30)) {		/* 256B / sector */
+	    p[3] |= 0x10;		/* forced set 512B / sector */
+	    p[3 + 0xa1000] |= 0x10;
+	}
+    }
+}
+
+static inline uint32_t
+get_diskinfo(void)
+{
+
+    if (dsk.disk == 0x30) {				/* 1440KB FD */
+	/* 80 cylinders, 2 heads, 18 sectors */
+	return (80 << 16) | (2 << 8) | 18;
+    } else if (dsk.disk == 0x90) {			/* 1200KB FD */
+	/* 80 cylinders, 2 heads, 15 sectors */
+	return (80 << 16) | (2 << 8) | 15;
+    } else if (dsk.disk == 0x80 || is_scsi_hd()) {	/* IDE or SCSI HDD */
+	v86.addr = 0x1b;
+	v86.eax = 0x8400 | dsk.daua;
+	v86int();
+	return (v86.ecx << 16) | v86.edx;
+    }
+
+    /* SCSI MO or CD */
+    fix_sector_size();	/* SCSI MO */
+
+    /* other SCSI devices */
+    return (65535 << 16) | (8 << 8) | 32;
+}
+
+static void
+set_dsk(void)
+{
+    uint32_t di;
+
+    di = get_diskinfo();
+
+    dsk.head = (di >> 8) & 0xff;
+    dsk.sec = di & 0xff;
+    dsk.start = 0;
+}
+
+#ifdef GET_BIOSGEOM
+static uint32_t
+bd_getbigeom(int bunit)
+{
+    int hds = 0;
+    int unit = 0x80;		/* IDE HDD */
+    u_int addr = 0x55d;
+
+    while (unit < 0xa7) {
+	if (*(u_char *)PTOV(addr) & (1 << (unit & 0x0f)))
+	    if (hds++ == bunit)
+		break;
+
+	if (unit >= 0xA0) {
+	    int media = ((unsigned *)PTOV(0x460))[unit & 0x0F] & 0x1F;
+
+	    if (media == 7 && hds++ == bunit)	/* SCSI MO */
+		return(0xFFFE0820); /* C:65535 H:8 S:32 */
+	}
+	if (++unit == 0x84) {
+	    unit = 0xA0;	/* SCSI HDD */
+	    addr = 0x482;
+	}
+    }
+    if (unit == 0xa7)
+	return 0x4F020F;	/* 1200KB FD C:80 H:2 S:15 */
+    v86.addr = 0x1b;
+    v86.eax = 0x8400 | unit;
+    v86int();
+    if (v86.efl & 0x1)
+	return 0x4F020F;	/* 1200KB FD C:80 H:2 S:15 */
+    return ((v86.ecx & 0xffff) << 16) | (v86.edx & 0xffff);
+}
+#endif
+
+static int
+check_slice(void)
+{
+    struct pc98_partition *dp;
+    char *sec;
+    unsigned i, cyl;
+
+    sec = dmadat->secbuf;
+    cyl = *(uint16_t *)PTOV(ARGS);
+    set_dsk();
+
+    if (dsk.type == TYPE_FD)
+	return (WHOLE_DISK_SLICE);
+    if (drvread(sec, DOSBBSECTOR + 1))
+	return (WHOLE_DISK_SLICE);	/* Read error */
+    dp = (void *)(sec + DOSPARTOFF);
+    for (i = 0; i < NDOSPART; i++) {
+	if (dp[i].dp_mid == DOSMID_386BSD) {
+	    if (dp[i].dp_scyl <= cyl && cyl <= dp[i].dp_ecyl)
+		return (BASE_SLICE + i);
+	}
+    }
+
+    return (WHOLE_DISK_SLICE);
+}
+
+int
+main(void)
+{
+#ifdef GET_BIOSGEOM
+    int i;
+#endif
+    int autoboot;
+    ino_t ino;
+
+    dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
+    v86.ctl = V86_FLAGS;
+    v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
+    dsk.daua = *(uint8_t *)PTOV(0x584);
+    dsk.disk = dsk.daua & DRV_DISK;
+    dsk.unit = dsk.daua & DRV_UNIT;
+    if (dsk.disk == 0x80)
+        dsk.type = TYPE_AD;
+    else if (dsk.disk == 0xa0)
+        dsk.type = TYPE_DA;
+    else /* if (dsk.disk == 0x30 || dsk.disk == 0x90) */
+        dsk.type = TYPE_FD;
+    dsk.slice = check_slice();
+#ifdef GET_BIOSGEOM
+    for (i = 0; i < N_BIOS_GEOM; i++)
+	bootinfo.bi_bios_geom[i] = bd_getbigeom(i);
+#endif
+    bootinfo.bi_version = BOOTINFO_VERSION;
+    bootinfo.bi_size = sizeof(bootinfo);
+    bootinfo.bi_basemem = 0;	/* XXX will be filled by loader or kernel */
+    bootinfo.bi_extmem = memsize();
+    bootinfo.bi_memsizes_valid++;
+
+    /* Process configuration file */
+
+    autoboot = 1;
+
+    if ((ino = lookup(PATH_CONFIG)))
+	fsread(ino, cmd, sizeof(cmd));
+
+    if (*cmd) {
+	memcpy(cmddup, cmd, sizeof(cmd));
+	if (parse())
+	    autoboot = 0;
+	if (!OPT_CHECK(RBX_QUIET))
+	    printf("%s: %s", PATH_CONFIG, cmddup);
+	/* Do not process this command twice */
+	*cmd = 0;
+    }
+
+    /*
+     * Try to exec stage 3 boot loader. If interrupted by a keypress,
+     * or in case of failure, try to load a kernel directly instead.
+     */
+
+    if (autoboot && !*kname) {
+	memcpy(kname, PATH_BOOT3, sizeof(PATH_BOOT3));
+	if (!keyhit(3*SECOND)) {
+	    load();
+	    memcpy(kname, PATH_KERNEL, sizeof(PATH_KERNEL));
+	}
+    }
+
+    /* Present the user with the boot2 prompt. */
+
+    for (;;) {
+	if (!autoboot || !OPT_CHECK(RBX_QUIET))
+	    printf("\nFreeBSD/pc98 boot\n"
+		   "Default: %u:%s(%u,%c)%s\n"
+		   "boot: ",
+		   dsk.unit, dev_nm[dsk.type], dsk.unit,
+		   'a' + dsk.part, kname);
+	if (ioctrl & IO_SERIAL)
+	    sio_flush();
+	if (!autoboot || keyhit(5*SECOND))
+	    getstr();
+	else if (!autoboot || !OPT_CHECK(RBX_QUIET))
+	    putchar('\n');
+	autoboot = 0;
+	if (parse())
+	    putchar('\a');
+	else
+	    load();
+    }
+}
+
+/* XXX - Needed for btxld to link the boot2 binary; do not remove. */
+void
+exit(int x)
+{
+}
+
+static void
+load(void)
+{
+    union {
+	struct exec ex;
+	Elf32_Ehdr eh;
+    } hdr;
+    static Elf32_Phdr ep[2];
+    static Elf32_Shdr es[2];
+    caddr_t p;
+    ino_t ino;
+    uint32_t addr, x;
+    int fmt, i, j;
+
+    if (!(ino = lookup(kname))) {
+	if (!ls)
+	    printf("No %s\n", kname);
+	return;
+    }
+    if (xfsread(ino, &hdr, sizeof(hdr)))
+	return;
+    if (N_GETMAGIC(hdr.ex) == ZMAGIC)
+	fmt = 0;
+    else if (IS_ELF(hdr.eh))
+	fmt = 1;
+    else {
+	printf("Invalid %s\n", "format");
+	return;
+    }
+    if (fmt == 0) {
+	addr = hdr.ex.a_entry & 0xffffff;
+	p = PTOV(addr);
+	fs_off = PAGE_SIZE;
+	if (xfsread(ino, p, hdr.ex.a_text))
+	    return;
+	p += roundup2(hdr.ex.a_text, PAGE_SIZE);
+	if (xfsread(ino, p, hdr.ex.a_data))
+	    return;
+	p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE);
+	bootinfo.bi_symtab = VTOP(p);
+	memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms));
+	p += sizeof(hdr.ex.a_syms);
+	if (hdr.ex.a_syms) {
+	    if (xfsread(ino, p, hdr.ex.a_syms))
+		return;
+	    p += hdr.ex.a_syms;
+	    if (xfsread(ino, p, sizeof(int)))
+		return;
+	    x = *(uint32_t *)p;
+	    p += sizeof(int);
+	    x -= sizeof(int);
+	    if (xfsread(ino, p, x))
+		return;
+	    p += x;
+	}
+    } else {
+	fs_off = hdr.eh.e_phoff;
+	for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) {
+	    if (xfsread(ino, ep + j, sizeof(ep[0])))
+		return;
+	    if (ep[j].p_type == PT_LOAD)
+		j++;
+	}
+	for (i = 0; i < 2; i++) {
+	    p = PTOV(ep[i].p_paddr & 0xffffff);
+	    fs_off = ep[i].p_offset;
+	    if (xfsread(ino, p, ep[i].p_filesz))
+		return;
+	}
+	p += roundup2(ep[1].p_memsz, PAGE_SIZE);
+	bootinfo.bi_symtab = VTOP(p);
+	if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
+	    fs_off = hdr.eh.e_shoff + sizeof(es[0]) *
+		(hdr.eh.e_shstrndx + 1);
+	    if (xfsread(ino, &es, sizeof(es)))
+		return;
+	    for (i = 0; i < 2; i++) {
+		memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size));
+		p += sizeof(es[i].sh_size);
+		fs_off = es[i].sh_offset;
+		if (xfsread(ino, p, es[i].sh_size))
+		    return;
+		p += es[i].sh_size;
+	    }
+	}
+	addr = hdr.eh.e_entry & 0xffffff;
+    }
+    bootinfo.bi_esymtab = VTOP(p);
+    bootinfo.bi_kernelname = VTOP(kname);
+    bootinfo.bi_bios_dev = dsk.daua;
+    __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
+	   MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part),
+	   0, 0, 0, VTOP(&bootinfo));
+}
+
+static int
+parse()
+{
+    char *arg = cmd;
+    char *ep, *p, *q;
+    const char *cp;
+    unsigned int drv;
+    int c, i, j;
+
+    while ((c = *arg++)) {
+	if (c == ' ' || c == '\t' || c == '\n')
+	    continue;
+	for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
+	ep = p;
+	if (*p)
+	    *p++ = 0;
+	if (c == '-') {
+	    while ((c = *arg++)) {
+		if (c == 'P') {
+		    if (*(uint8_t *)PTOV(0x481) & 0x48) {
+			cp = "yes";
+		    } else {
+			opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL);
+			cp = "no";
+		    }
+		    printf("Keyboard: %s\n", cp);
+		    continue;
+		} else if (c == 'S') {
+		    j = 0;
+		    while ((unsigned int)(i = *arg++ - '0') <= 9)
+			j = j * 10 + i;
+		    if (j > 0 && i == -'0') {
+			comspeed = j;
+			break;
+		    }
+		    /* Fall through to error below ('S' not in optstr[]). */
+		}
+		for (i = 0; c != optstr[i]; i++)
+		    if (i == NOPT - 1)
+			return -1;
+		opts ^= OPT_SET(flags[i]);
+	    }
+	    ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) :
+		     OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD;
+	    if (ioctrl & IO_SERIAL)
+	        sio_init(115200 / comspeed);
+	} else {
+	    for (q = arg--; *q && *q != '('; q++);
+	    if (*q) {
+		drv = -1;
+		if (arg[1] == ':') {
+		    drv = *arg - '0';
+		    if (drv > 9)
+			return (-1);
+		    arg += 2;
+		}
+		if (q - arg != 2)
+		    return -1;
+		for (i = 0; arg[0] != dev_nm[i][0] ||
+			    arg[1] != dev_nm[i][1]; i++)
+		    if (i == NDEV - 1)
+			return -1;
+		dsk.type = i;
+		arg += 3;
+		dsk.unit = *arg - '0';
+		if (arg[1] != ',' || dsk.unit > 9)
+		    return -1;
+		arg += 2;
+		dsk.slice = WHOLE_DISK_SLICE;
+		if (arg[1] == ',') {
+		    dsk.slice = *arg - '0' + 1;
+		    if (dsk.slice > NDOSPART + 1)
+			return -1;
+		    arg += 2;
+		}
+		if (arg[1] != ')')
+		    return -1;
+		dsk.part = *arg - 'a';
+		if (dsk.part > 7)
+		    return (-1);
+		arg += 2;
+		if (drv == -1)
+		    drv = dsk.unit;
+		dsk.disk = dev_daua[dsk.type];
+		dsk.daua = dsk.disk | dsk.unit;
+		dsk_meta = 0;
+	    }
+	    if ((i = ep - arg)) {
+		if ((size_t)i >= sizeof(kname))
+		    return -1;
+		memcpy(kname, arg, i + 1);
+	    }
+	}
+	arg = p;
+    }
+    return 0;
+}
+
+static int
+dskread(void *buf, unsigned lba, unsigned nblk)
+{
+    struct pc98_partition *dp;
+    struct disklabel *d;
+    char *sec;
+    unsigned sl, i;
+    u_char *p;
+
+    if (!dsk_meta) {
+	sec = dmadat->secbuf;
+	set_dsk();
+	if (dsk.type == TYPE_FD)
+	    goto unsliced;
+	if (drvread(sec, DOSBBSECTOR + 1))
+	    return -1;
+	dp = (void *)(sec + DOSPARTOFF);
+	sl = dsk.slice;
+	if (sl < BASE_SLICE) {
+	    for (i = 0; i < NDOSPART; i++)
+		if (dp[i].dp_mid == DOSMID_386BSD) {
+		    sl = BASE_SLICE + i;
+		    break;
+		}
+	    dsk.slice = sl;
+	}
+	if (sl != WHOLE_DISK_SLICE) {
+	    dp += sl - BASE_SLICE;
+	    if (dp->dp_mid != DOSMID_386BSD) {
+		printf("Invalid %s\n", "slice");
+		return -1;
+	    }
+	    dsk.start = dp->dp_scyl * dsk.head * dsk.sec +
+		dp->dp_shd * dsk.sec + dp->dp_ssect;
+	}
+	if (drvread(sec, dsk.start + LABELSECTOR))
+		return -1;
+	d = (void *)(sec + LABELOFFSET);
+	if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) {
+	    if (dsk.part != RAW_PART) {
+		printf("Invalid %s\n", "label");
+		return -1;
+	    }
+	} else {
+	    if (dsk.part >= d->d_npartitions ||
+		!d->d_partitions[dsk.part].p_size) {
+		printf("Invalid %s\n", "partition");
+		return -1;
+	    }
+	    dsk.start += d->d_partitions[dsk.part].p_offset;
+	    dsk.start -= d->d_partitions[RAW_PART].p_offset;
+	}
+    unsliced: ;
+    }
+    for (p = buf; nblk; p += 512, lba++, nblk--) {
+	if ((i = drvread(p, dsk.start + lba)))
+	    return i;
+    }
+    return 0;
+}
+
+static void
+printf(const char *fmt,...)
+{
+    va_list ap;
+    char buf[10];
+    char *s;
+    unsigned u;
+    int c;
+
+    va_start(ap, fmt);
+    while ((c = *fmt++)) {
+	if (c == '%') {
+	    c = *fmt++;
+	    switch (c) {
+	    case 'c':
+		putchar(va_arg(ap, int));
+		continue;
+	    case 's':
+		for (s = va_arg(ap, char *); *s; s++)
+		    putchar(*s);
+		continue;
+	    case 'u':
+		u = va_arg(ap, unsigned);
+		s = buf;
+		do
+		    *s++ = '0' + u % 10U;
+		while (u /= 10U);
+		while (--s >= buf)
+		    putchar(*s);
+		continue;
+	    }
+	}
+	putchar(c);
+    }
+    va_end(ap);
+    return;
+}
+
+static void
+putchar(int c)
+{
+    if (c == '\n')
+	xputc('\r');
+    xputc(c);
+}
+
+static int
+drvread(void *buf, unsigned lba)
+{
+    static unsigned c = 0x2d5c7c2f;
+    unsigned bpc, x, cyl, head, sec;
+
+    bpc = dsk.sec * dsk.head;
+    cyl = lba / bpc;
+    x = lba % bpc;
+    head = x / dsk.sec;
+    sec = x % dsk.sec;
+
+    if (!OPT_CHECK(RBX_QUIET))
+	printf("%c\b", c = c << 8 | c >> 24);
+    v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
+    v86.addr = READORG;		/* call to read in boot1 */
+    v86.ecx = cyl;
+    v86.edx = (head << 8) | sec;
+    v86.edi = lba;
+    v86.ebx = 512;
+    v86.es = VTOPSEG(buf);
+    v86.ebp = VTOPOFF(buf);
+    v86int();
+    v86.ctl = V86_FLAGS;
+    if (V86_CY(v86.efl)) {
+	printf("error %u c/h/s %u/%u/%u lba %u\n", v86.eax >> 8 & 0xff,
+	       cyl, head, sec, lba);
+	return -1;
+    }
+    return 0;
+}
+
+static inline void
+delay(void)
+{
+    int i;
+
+    i = 800;
+    do {
+	outb(0x5f, 0);	/* about 600ns */
+    } while (--i >= 0);
+}
+
+static int
+keyhit(unsigned sec)
+{
+    unsigned i;
+
+    if (OPT_CHECK(RBX_NOINTR))
+	return 0;
+    for (i = 0; i < sec * 1000; i++) {
+	if (xgetc(1))
+	    return 1;
+	delay();
+    }
+    return 0;
+}
+
+static int
+xputc(int c)
+{
+    if (ioctrl & IO_KEYBOARD)
+	putc(c);
+    if (ioctrl & IO_SERIAL)
+	sio_putc(c);
+    return c;
+}
+
+static int
+xgetc(int fn)
+{
+    if (OPT_CHECK(RBX_NOINTR))
+	return 0;
+    for (;;) {
+	if (ioctrl & IO_KEYBOARD && getc(1))
+	    return fn ? 1 : getc(0);
+	if (ioctrl & IO_SERIAL && sio_ischar())
+	    return fn ? 1 : sio_getc();
+	if (fn)
+	    return 0;
+    }
+}
+
+static int
+getc(int fn)
+{
+    v86.addr = 0x18;
+    v86.eax = fn << 8;
+    v86int();
+    if (fn)
+	return (v86.ebx >> 8) & 0x01;
+    else
+	return v86.eax & 0xff;
+}
diff --git a/sys/boot/pc98/boot2/dinode.h b/sys/boot/pc98/boot2/dinode.h
deleted file mode 100644
index 2a78f344d40..00000000000
--- a/sys/boot/pc98/boot2/dinode.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 1982, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- *	@(#)dinode.h	8.3 (Berkeley) 1/21/94
- * %FreeBSD: src/sys/ufs/ufs/dinode.h,v 1.7 1999/08/28 00:52:27 peter Exp %
- * $FreeBSD$
- */
-
-#ifndef _UFS_UFS_DINODE_H_
-#define _UFS_UFS_DINODE_H_
-
-/*
- * The root inode is the root of the file system.  Inode 0 can't be used for
- * normal purposes and historically bad blocks were linked to inode 1, thus
- * the root inode is 2.  (Inode 1 is no longer used for this purpose, however
- * numerous dump tapes make this assumption, so we are stuck with it).
- */
-#define	ROOTINO	((ino_t)2)
-
-/*
- * The Whiteout inode# is a dummy non-zero inode number which will
- * never be allocated to a real file.  It is used as a place holder
- * in the directory entry which has been tagged as a DT_W entry.
- * See the comments about ROOTINO above.
- */
-#define	WINO	((ino_t)1)
-
-/*
- * A dinode contains all the meta-data associated with a UFS file.
- * This structure defines the on-disk format of a dinode. Since
- * this structure describes an on-disk structure, all its fields
- * are defined by types with precise widths.
- */
-
-/* typedef int32_t ufs_daddr_t; */
-#define	NDADDR	12			/* Direct addresses in inode. */
-#define	NIADDR	3			/* Indirect addresses in inode. */
-
-struct dinode {
-	u_int16_t	di_mode;	/*   0: IFMT, permissions; see below. */
-	int16_t		di_nlink;	/*   2: File link count. */
-	union {
-		u_int16_t oldids[2];	/*   4: Ffs: old user and group ids. */
-		int32_t	  inumber;	/*   4: Lfs: inode number. */
-	} di_u;
-	u_int64_t	di_size;	/*   8: File byte count. */
-	int32_t		di_atime;	/*  16: Last access time. */
-	int32_t		di_atimensec;	/*  20: Last access time. */
-	int32_t		di_mtime;	/*  24: Last modified time. */
-	int32_t		di_mtimensec;	/*  28: Last modified time. */
-	int32_t		di_ctime;	/*  32: Last inode change time. */
-	int32_t		di_ctimensec;	/*  36: Last inode change time. */
-	ufs_daddr_t	di_db[NDADDR];	/*  40: Direct disk blocks. */
-	ufs_daddr_t	di_ib[NIADDR];	/*  88: Indirect disk blocks. */
-	u_int32_t	di_flags;	/* 100: Status flags (chflags). */
-	int32_t		di_blocks;	/* 104: Blocks actually held. */
-	int32_t		di_gen;		/* 108: Generation number. */
-	u_int32_t	di_uid;		/* 112: File owner. */
-	u_int32_t	di_gid;		/* 116: File group. */
-	int32_t		di_spare[2];	/* 120: Reserved; currently unused */
-};
-
-/*
- * The di_db fields may be overlaid with other information for
- * file types that do not have associated disk storage. Block
- * and character devices overlay the first data block with their
- * dev_t value. Short symbolic links place their path in the
- * di_db area.
- */
-#define	di_inumber	di_u.inumber
-#define	di_ogid		di_u.oldids[1]
-#define	di_ouid		di_u.oldids[0]
-#define	di_rdev		di_db[0]
-#define	di_shortlink	di_db
-#define	MAXSYMLINKLEN	((NDADDR + NIADDR) * sizeof(ufs_daddr_t))
-
-/* File permissions. */
-#define	IEXEC		0000100		/* Executable. */
-#define	IWRITE		0000200		/* Writeable. */
-#define	IREAD		0000400		/* Readable. */
-#define	ISVTX		0001000		/* Sticky bit. */
-#define	ISGID		0002000		/* Set-gid. */
-#define	ISUID		0004000		/* Set-uid. */
-
-/* File types. */
-#define	IFMT		0170000		/* Mask of file type. */
-#define	IFIFO		0010000		/* Named pipe (fifo). */
-#define	IFCHR		0020000		/* Character device. */
-#define	IFDIR		0040000		/* Directory file. */
-#define	IFBLK		0060000		/* Block device. */
-#define	IFREG		0100000		/* Regular file. */
-#define	IFLNK		0120000		/* Symbolic link. */
-#define	IFSOCK		0140000		/* UNIX domain socket. */
-#define	IFWHT		0160000		/* Whiteout. */
-
-#endif
diff --git a/sys/boot/pc98/boot2/disk.c b/sys/boot/pc98/boot2/disk.c
deleted file mode 100644
index f9706cad3e0..00000000000
--- a/sys/boot/pc98/boot2/disk.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
- */
-/*
- * Ported to PC-9801 by Yoshio Kimura
- */
-
-/*
- * 93/10/08  bde
- *	If there is no 386BSD partition, initialize the label sector with
- *	LABELSECTOR instead of with garbage.
- *
- * 93/08/22  bde
- *	Fixed reading of bad sector table.  It is at the end of the 'c'
- *	partition, which is not always at the end of the disk.
- */
-
-#include 
-__FBSDID("$FreeBSD$");
-
-#include "boot.h"
-#include 
-#include 
-#include 
-
-#define	BIOS_DEV_FLOPPY	0x0
-#define	BIOS_DEV_WIN	0x80
-
-#define BPS		512
-#define	SPT(di)		((di)&0xff)
-#define	HEADS(di)	(((di)>>8)&0xff)
-
-
-static int spt, spc;
-
-struct fs *fs;
-struct inode inode;
-int dosdev, unit, slice, part, maj, boff;
-
-/*#define EMBEDDED_DISKLABEL 1*/
-
-/* Read ahead buffer large enough for one track on a 1440K floppy.  For
- * reading from floppies, the bootstrap has to be loaded on a 64K boundary
- * to ensure that this buffer doesn't cross a 64K DMA boundary.
- */
-#define RA_SECTORS	18
-static char ra_buf[RA_SECTORS * BPS];
-static int ra_dev;
-static int ra_end;
-static int ra_first;
-
-static char *Bread(int dosdev, int sector);
-
-int
-devopen(void)
-{
-	struct pc98_partition *dptr;
-	struct disklabel *dl;
-	char *p;
-	int i, sector = 0, di, dosdev_copy;
-
-	dosdev_copy = dosdev;
-	di = get_diskinfo(dosdev_copy);
-	spc = (spt = SPT(di)) * HEADS(di);
-
-#ifndef RAWBOOT
-	if ((dosdev_copy & 0xf0) == 0x90)
-	{
-		boff = 0;
-		part = (spt == 15 ? 0 : 1);
-	}
-	else
-	{
-#ifdef	EMBEDDED_DISKLABEL
-		dl = &disklabel;
-#else	/* EMBEDDED_DISKLABEL */
-		p = Bread(dosdev_copy, 1);
-		dptr = (struct pc98_partition *)p;
-		slice = WHOLE_DISK_SLICE;
-		for (i = 0; i < NDOSPART; i++, dptr++)
-			if (dptr->dp_mid == DOSMID_386BSD) {
-				slice = BASE_SLICE + i;
-				sector = dptr->dp_scyl * spc;
-				break;
-			}
-		p = Bread(dosdev, sector + LABELSECTOR);
-		dl=((struct disklabel *)p);
-		disklabel = *dl;	/* structure copy (maybe useful later)*/
-#endif /* EMBEDDED_DISKLABEL */
-		if (dl->d_magic != DISKMAGIC) {
-			printf("bad disklabel\n");
-			return 1;
-		}
-		/* This little trick is for OnTrack DiskManager disks */
-		boff = dl->d_partitions[part].p_offset -
-			dl->d_partitions[2].p_offset + sector;
-	}
-#endif /* RAWBOOT */
-	return 0;
-}
-
-
-/*
- * Be aware that cnt is rounded up to N*BPS
- */
-void
-devread(char *iodest, int sector, int cnt)
-{
-	int offset;
-	char *p;
-	int dosdev_copy;
-
-	for (offset = 0; offset < cnt; offset += BPS)
-	{
-		dosdev_copy = dosdev;
-		p = Bread(dosdev_copy, sector++);
-		memcpy(p, iodest+offset, BPS);
-	}
-}
-
-
-static char *
-Bread(int dosdev, int sector)
-{
-	if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)
-	{
-		int cyl, head, sec, nsec;
-
-		cyl = sector/spc;
-		head = (sector % spc) / spt;
-		sec = sector % spt;
-		nsec = spt - sec;
-		if (nsec > RA_SECTORS)
-			nsec = RA_SECTORS;
-		twiddle();
-		if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
-		{
-		    nsec = 1;
-		    twiddle();
-		    while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0) {
-			printf("Error: D:0x%x C:%d H:%d S:%d\n",
-			       dosdev, cyl, head, sec);
-			twiddle();
-		    }
-		}
-		ra_dev = dosdev;
-		ra_first = sector;
-		ra_end = sector + nsec;
-	}
-	return (ra_buf + (sector - ra_first) * BPS);
-}
diff --git a/sys/boot/pc98/boot2/fs.h b/sys/boot/pc98/boot2/fs.h
deleted file mode 100644
index 8ac77da6d09..00000000000
--- a/sys/boot/pc98/boot2/fs.h
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- *	The Regents of the University of California.  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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- *	@(#)fs.h	8.13 (Berkeley) 3/21/95
- * %FreeBSD: src/sys/ufs/ffs/fs.h,v 1.14.2.3 2001/09/21 19:15:22 dillon Exp %
- * $FreeBSD$
- */
-
-#ifndef _UFS_FFS_FS_H_
-#define _UFS_FFS_FS_H_
-
-/*
- * Each disk drive contains some number of file systems.
- * A file system consists of a number of cylinder groups.
- * Each cylinder group has inodes and data.
- *
- * A file system is described by its super-block, which in turn
- * describes the cylinder groups.  The super-block is critical
- * data and is replicated in each cylinder group to protect against
- * catastrophic loss.  This is done at `newfs' time and the critical
- * super-block data does not change, so the copies need not be
- * referenced further unless disaster strikes.
- *
- * For file system fs, the offsets of the various blocks of interest
- * are given in the super block as:
- *	[fs->fs_sblkno]		Super-block
- *	[fs->fs_cblkno]		Cylinder group block
- *	[fs->fs_iblkno]		Inode blocks
- *	[fs->fs_dblkno]		Data blocks
- * The beginning of cylinder group cg in fs, is given by
- * the ``cgbase(fs, cg)'' macro.
- *
- * The first boot and super blocks are given in absolute disk addresses.
- * The byte-offset forms are preferred, as they don't imply a sector size.
- */
-#define BBSIZE		8192
-#define SBSIZE		8192
-#define	BBOFF		((off_t)(0))
-#define	SBOFF		((off_t)(BBOFF + BBSIZE))
-#define	BBLOCK		((ufs_daddr_t)(0))
-#define	SBLOCK		((ufs_daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
-
-/*
- * Addresses stored in inodes are capable of addressing fragments
- * of `blocks'. File system blocks of at most size MAXBSIZE can
- * be optionally broken into 2, 4, or 8 pieces, each of which is
- * addressable; these pieces may be DEV_BSIZE, or some multiple of
- * a DEV_BSIZE unit.
- *
- * Large files consist of exclusively large data blocks.  To avoid
- * undue wasted disk space, the last data block of a small file may be
- * allocated as only as many fragments of a large block as are
- * necessary.  The file system format retains only a single pointer
- * to such a fragment, which is a piece of a single large block that
- * has been divided.  The size of such a fragment is determinable from
- * information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
- *
- * The file system records space availability at the fragment level;
- * to determine block availability, aligned fragments are examined.
- */
-
-/*
- * MINBSIZE is the smallest allowable block size.
- * In order to insure that it is possible to create files of size
- * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
- * MINBSIZE must be big enough to hold a cylinder group block,
- * thus changes to (struct cg) must keep its size within MINBSIZE.
- * Note that super blocks are always of size SBSIZE,
- * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
- */
-#define MINBSIZE	4096
-
-/*
- * The path name on which the file system is mounted is maintained
- * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
- * the super block for this name.
- */
-#define MAXMNTLEN	512
-
-/*
- * There is a 128-byte region in the superblock reserved for in-core
- * pointers to summary information. Originally this included an array
- * of pointers to blocks of struct csum; now there are just three
- * pointers and the remaining space is padded with fs_ocsp[].
- *
- * NOCSPTRS determines the size of this padding. One pointer (fs_csp)
- * is taken away to point to a contiguous array of struct csum for
- * all cylinder groups; a second (fs_maxcluster) points to an array
- * of cluster sizes that is computed as cylinder groups are inspected,
- * and the third points to an array that tracks the creation of new
- * directories.
- */
-#define	NOCSPTRS	((128 / sizeof(void *)) - 3)
-
-/*
- * A summary of contiguous blocks of various sizes is maintained
- * in each cylinder group. Normally this is set by the initial
- * value of fs_maxcontig. To conserve space, a maximum summary size
- * is set by FS_MAXCONTIG.
- */
-#define FS_MAXCONTIG	16
-
-/*
- * MINFREE gives the minimum acceptable percentage of file system
- * blocks which may be free. If the freelist drops below this level
- * only the superuser may continue to allocate blocks. This may
- * be set to 0 if no reserve of free blocks is deemed necessary,
- * however throughput drops by fifty percent if the file system
- * is run at between 95% and 100% full; thus the minimum default
- * value of fs_minfree is 5%. However, to get good clustering
- * performance, 10% is a better choice. hence we use 10% as our
- * default value. With 10% free space, fragmentation is not a
- * problem, so we choose to optimize for time.
- */
-#define MINFREE		8
-#define DEFAULTOPT	FS_OPTTIME
-
-/*
- * Grigoriy Orlov  has done some extensive work to fine
- * tune the layout preferences for directories within a filesystem.
- * His algorithm can be tuned by adjusting the following parameters
- * which tell the system the average file size and the average number
- * of files per directory. These defaults are well selected for typical
- * filesystems, but may need to be tuned for odd cases like filesystems
- * being used for sqiud caches or news spools.
- */
-#define AVFILESIZ      16384   /* expected average file size */
-#define AFPDIR         64      /* expected number of files per directory */
-
-/*
- * The maximum number of snapshot nodes that can be associated
- * with each filesystem. This limit affects only the number of
- * snapshot files that can be recorded within the superblock so
- * that they can be found when the filesystem is mounted. However,
- * maintaining too many will slow the filesystem performance, so
- * having this limit is a good idea.
- *
- * VALUE NOT IMPLEMENTED IN 4.x YET, RESERVED FROM -CURRENT SO SUPERBLOCKS
- * REMAIN COMPATIBLE.
- */
-#define FSMAXSNAP 20
-
-/*
- * Per cylinder group information; summarized in blocks allocated
- * from first cylinder group data blocks.  These blocks have to be
- * read in from fs_csaddr (size fs_cssize) in addition to the
- * super block.
- */
-struct csum {
-	int32_t	cs_ndir;		/* number of directories */
-	int32_t	cs_nbfree;		/* number of free blocks */
-	int32_t	cs_nifree;		/* number of free inodes */
-	int32_t	cs_nffree;		/* number of free frags */
-};
-
-/*
- * Super block for an FFS file system.
- */
-struct fs {
-	int32_t	 fs_firstfield;		/* historic file system linked list, */
-	int32_t	 fs_unused_1;		/*     used for incore super blocks */
-	ufs_daddr_t fs_sblkno;		/* addr of super-block in filesys */
-	ufs_daddr_t fs_cblkno;		/* offset of cyl-block in filesys */
-	ufs_daddr_t fs_iblkno;		/* offset of inode-blocks in filesys */
-	ufs_daddr_t fs_dblkno;		/* offset of first data after cg */
-	int32_t	 fs_cgoffset;		/* cylinder group offset in cylinder */
-	int32_t	 fs_cgmask;		/* used to calc mod fs_ntrak */
-	time_t 	 fs_time;		/* last time written */
-	int32_t	 fs_size;		/* number of blocks in fs */
-	int32_t	 fs_dsize;		/* number of data blocks in fs */
-	int32_t	 fs_ncg;		/* number of cylinder groups */
-	int32_t	 fs_bsize;		/* size of basic blocks in fs */
-	int32_t	 fs_fsize;		/* size of frag blocks in fs */
-	int32_t	 fs_frag;		/* number of frags in a block in fs */
-/* these are configuration parameters */
-	int32_t	 fs_minfree;		/* minimum percentage of free blocks */
-	int32_t	 fs_rotdelay;		/* num of ms for optimal next block */
-	int32_t	 fs_rps;		/* disk revolutions per second */
-/* these fields can be computed from the others */
-	int32_t	 fs_bmask;		/* ``blkoff'' calc of blk offsets */
-	int32_t	 fs_fmask;		/* ``fragoff'' calc of frag offsets */
-	int32_t	 fs_bshift;		/* ``lblkno'' calc of logical blkno */
-	int32_t	 fs_fshift;		/* ``numfrags'' calc number of frags */
-/* these are configuration parameters */
-	int32_t	 fs_maxcontig;		/* max number of contiguous blks */
-	int32_t	 fs_maxbpg;		/* max number of blks per cyl group */
-/* these fields can be computed from the others */
-	int32_t	 fs_fragshift;		/* block to frag shift */
-	int32_t	 fs_fsbtodb;		/* fsbtodb and dbtofsb shift constant */
-	int32_t	 fs_sbsize;		/* actual size of super block */
-	int32_t	 fs_csmask;		/* csum block offset (now unused) */
-	int32_t	 fs_csshift;		/* csum block number (now unused) */
-	int32_t	 fs_nindir;		/* value of NINDIR */
-	int32_t	 fs_inopb;		/* value of INOPB */
-	int32_t	 fs_nspf;		/* value of NSPF */
-/* yet another configuration parameter */
-	int32_t	 fs_optim;		/* optimization preference, see below */
-/* these fields are derived from the hardware */
-	int32_t	 fs_npsect;		/* # sectors/track including spares */
-	int32_t	 fs_interleave;		/* hardware sector interleave */
-	int32_t	 fs_trackskew;		/* sector 0 skew, per track */
-/* fs_id takes the space of the unused fs_headswitch and fs_trkseek fields */
-	int32_t	 fs_id[2];		/* unique filesystem id */
-/* sizes determined by number of cylinder groups and their sizes */
-	ufs_daddr_t fs_csaddr;		/* blk addr of cyl grp summary area */
-	int32_t	 fs_cssize;		/* size of cyl grp summary area */
-	int32_t	 fs_cgsize;		/* cylinder group size */
-/* these fields are derived from the hardware */
-	int32_t	 fs_ntrak;		/* tracks per cylinder */
-	int32_t	 fs_nsect;		/* sectors per track */
-	int32_t  fs_spc;			/* sectors per cylinder */
-/* this comes from the disk driver partitioning */
-	int32_t	 fs_ncyl;		/* cylinders in file system */
-/* these fields can be computed from the others */
-	int32_t	 fs_cpg;			/* cylinders per group */
-	int32_t	 fs_ipg;			/* inodes per group */
-	int32_t	 fs_fpg;			/* blocks per group * fs_frag */
-/* this data must be re-computed after crashes */
-	struct	csum fs_cstotal;	/* cylinder summary information */
-/* these fields are cleared at mount time */
-	int8_t   fs_fmod;		/* super block modified flag */
-	int8_t   fs_clean;		/* file system is clean flag */
-	int8_t 	 fs_ronly;		/* mounted read-only flag */
-	int8_t   fs_flags;		/* see FS_ flags below */
-	u_char	 fs_fsmnt[MAXMNTLEN];	/* name mounted on */
-/* these fields retain the current block allocation info */
-	int32_t	 fs_cgrotor;		/* last cg searched */
-	void 	*fs_ocsp[NOCSPTRS];	/* padding; was list of fs_cs buffers */
-	u_int8_t *fs_contigdirs;	/* # of contiguously allocated dirs */
-	struct csum *fs_csp;		/* cg summary info buffer for fs_cs */
-	int32_t	*fs_maxcluster;		/* max cluster in each cyl group */
-	int32_t	 fs_cpc;		/* cyl per cycle in postbl */
-	int16_t	 fs_opostbl[16][8];	/* old rotation block list head */
-	int32_t  fs_snapinum[FSMAXSNAP];/* RESERVED FROM 5.x */
-	int32_t	 fs_avgfilesize;	/* expected average file size */
-	int32_t  fs_avgfpdir;		/* expected # of files per directory */
-	int32_t	 fs_sparecon[26];	/* reserved for future constants */
-	int32_t  fs_pendingblocks;      /* RESERVED FROM 5.x */
-	int32_t  fs_pendinginodes;      /* RESERVED FROM 5.x */
-	int32_t	 fs_contigsumsize;	/* size of cluster summary array */ 
-	int32_t	 fs_maxsymlinklen;	/* max length of an internal symlink */
-	int32_t	 fs_inodefmt;		/* format of on-disk inodes */
-	u_int64_t fs_maxfilesize;	/* maximum representable file size */
-	int64_t	 fs_qbmask;		/* ~fs_bmask for use with 64-bit size */
-	int64_t	 fs_qfmask;		/* ~fs_fmask for use with 64-bit size */
-	int32_t	 fs_state;		/* validate fs_clean field */
-	int32_t	 fs_postblformat;	/* format of positional layout tables */
-	int32_t	 fs_nrpos;		/* number of rotational positions */
-	int32_t	 fs_postbloff;		/* (u_int16) rotation block list head */
-	int32_t	 fs_rotbloff;		/* (u_int8) blocks for each rotation */
-	int32_t	 fs_magic;		/* magic number */
-	u_int8_t fs_space[1];		/* list of blocks for each rotation */
-/* actually longer */
-};
-
-/*
- * Filesystem identification
- */
-#define	FS_MAGIC	0x011954	/* the fast filesystem magic number */
-#define	FS_OKAY		0x7c269d38	/* superblock checksum */
-#define FS_42INODEFMT	-1		/* 4.2BSD inode format */
-#define FS_44INODEFMT	2		/* 4.4BSD inode format */
-
-/*
- * Preference for optimization.
- */
-#define FS_OPTTIME	0	/* minimize allocation time */
-#define FS_OPTSPACE	1	/* minimize disk fragmentation */
-
-/*
- * Filesystem flags.
- */
-#define FS_UNCLEAN    0x01    /* filesystem not clean at mount */
-#define FS_DOSOFTDEP  0x02    /* filesystem using soft dependencies */
-
-/*
- * Rotational layout table format types
- */
-#define FS_42POSTBLFMT		-1	/* 4.2BSD rotational table format */
-#define FS_DYNAMICPOSTBLFMT	1	/* dynamic rotational table format */
-/*
- * Macros for access to superblock array structures
- */
-#define fs_postbl(fs, cylno) \
-    (((fs)->fs_postblformat == FS_42POSTBLFMT) \
-    ? ((fs)->fs_opostbl[cylno]) \
-    : ((int16_t *)((u_int8_t *)(fs) + \
-	(fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))
-#define fs_rotbl(fs) \
-    (((fs)->fs_postblformat == FS_42POSTBLFMT) \
-    ? ((fs)->fs_space) \
-    : ((u_int8_t *)((u_int8_t *)(fs) + (fs)->fs_rotbloff)))
-
-/*
- * The size of a cylinder group is calculated by CGSIZE. The maximum size
- * is limited by the fact that cylinder groups are at most one block.
- * Its size is derived from the size of the maps maintained in the
- * cylinder group and the (struct cg) size.
- */
-#define CGSIZE(fs) \
-    /* base cg */	(sizeof(struct cg) + sizeof(int32_t) + \
-    /* blktot size */	(fs)->fs_cpg * sizeof(int32_t) + \
-    /* blks size */	(fs)->fs_cpg * (fs)->fs_nrpos * sizeof(int16_t) + \
-    /* inode map */	howmany((fs)->fs_ipg, NBBY) + \
-    /* block map */	howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY) +\
-    /* if present */	((fs)->fs_contigsumsize <= 0 ? 0 : \
-    /* cluster sum */	(fs)->fs_contigsumsize * sizeof(int32_t) + \
-    /* cluster map */	howmany((fs)->fs_cpg * (fs)->fs_spc / NSPB(fs), NBBY)))
-
-/*
- * Convert cylinder group to base address of its global summary info.
- */
-#define fs_cs(fs, indx) fs_csp[indx]
-
-/*
- * Cylinder group block for a file system.
- */
-#define	CG_MAGIC	0x090255
-struct cg {
-	int32_t	 cg_firstfield;		/* historic cyl groups linked list */
-	int32_t	 cg_magic;		/* magic number */
-	time_t	 cg_time;		/* time last written */
-	int32_t	 cg_cgx;		/* we are the cgx'th cylinder group */
-	int16_t	 cg_ncyl;		/* number of cyl's this cg */
-	int16_t	 cg_niblk;		/* number of inode blocks this cg */
-	int32_t	 cg_ndblk;		/* number of data blocks this cg */
-	struct	csum cg_cs;		/* cylinder summary information */
-	int32_t	 cg_rotor;		/* position of last used block */
-	int32_t	 cg_frotor;		/* position of last used frag */
-	int32_t	 cg_irotor;		/* position of last used inode */
-	int32_t	 cg_frsum[MAXFRAG];	/* counts of available frags */
-	int32_t	 cg_btotoff;		/* (int32) block totals per cylinder */
-	int32_t	 cg_boff;		/* (u_int16) free block positions */
-	int32_t	 cg_iusedoff;		/* (u_int8) used inode map */
-	int32_t	 cg_freeoff;		/* (u_int8) free block map */
-	int32_t	 cg_nextfreeoff;	/* (u_int8) next available space */
-	int32_t	 cg_clustersumoff;	/* (u_int32) counts of avail clusters */
-	int32_t	 cg_clusteroff;		/* (u_int8) free cluster map */
-	int32_t	 cg_nclusterblks;	/* number of clusters this cg */
-	int32_t	 cg_sparecon[13];	/* reserved for future use */
-	u_int8_t cg_space[1];		/* space for cylinder group maps */
-/* actually longer */
-};
-
-/*
- * Macros for access to cylinder group array structures
- */
-#define cg_blktot(cgp) \
-    (((cgp)->cg_magic != CG_MAGIC) \
-    ? (((struct ocg *)(cgp))->cg_btot) \
-    : ((int32_t *)((u_int8_t *)(cgp) + (cgp)->cg_btotoff)))
-#define cg_blks(fs, cgp, cylno) \
-    (((cgp)->cg_magic != CG_MAGIC) \
-    ? (((struct ocg *)(cgp))->cg_b[cylno]) \
-    : ((int16_t *)((u_int8_t *)(cgp) + \
-	(cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))
-#define cg_inosused(cgp) \
-    (((cgp)->cg_magic != CG_MAGIC) \
-    ? (((struct ocg *)(cgp))->cg_iused) \
-    : ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_iusedoff)))
-#define cg_blksfree(cgp) \
-    (((cgp)->cg_magic != CG_MAGIC) \
-    ? (((struct ocg *)(cgp))->cg_free) \
-    : ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_freeoff)))
-#define cg_chkmagic(cgp) \
-    ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
-#define cg_clustersfree(cgp) \
-    ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_clusteroff))
-#define cg_clustersum(cgp) \
-    ((int32_t *)((u_int8_t *)(cgp) + (cgp)->cg_clustersumoff))
-
-/*
- * The following structure is defined
- * for compatibility with old file systems.
- */
-struct ocg {
-	int32_t	 cg_firstfield;		/* historic linked list of cyl groups */
-	int32_t	 cg_unused_1;		/*     used for incore cyl groups */
-	time_t	 cg_time;		/* time last written */
-	int32_t	 cg_cgx;		/* we are the cgx'th cylinder group */
-	int16_t	 cg_ncyl;		/* number of cyl's this cg */
-	int16_t	 cg_niblk;		/* number of inode blocks this cg */
-	int32_t	 cg_ndblk;		/* number of data blocks this cg */
-	struct	csum cg_cs;		/* cylinder summary information */
-	int32_t	 cg_rotor;		/* position of last used block */
-	int32_t	 cg_frotor;		/* position of last used frag */
-	int32_t	 cg_irotor;		/* position of last used inode */
-	int32_t	 cg_frsum[8];		/* counts of available frags */
-	int32_t	 cg_btot[32];		/* block totals per cylinder */
-	int16_t	 cg_b[32][8];		/* positions of free blocks */
-	u_int8_t cg_iused[256];		/* used inode map */
-	int32_t	 cg_magic;		/* magic number */
-	u_int8_t cg_free[1];		/* free block map */
-/* actually longer */
-};
-
-/*
- * Turn file system block numbers into disk block addresses.
- * This maps file system blocks to device size blocks.
- */
-#define fsbtodb(fs, b)	((b) << (fs)->fs_fsbtodb)
-#define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtodb)
-
-/*
- * Cylinder group macros to locate things in cylinder groups.
- * They calc file system addresses of cylinder group data structures.
- */
-#define	cgbase(fs, c)	((ufs_daddr_t)((fs)->fs_fpg * (c)))
-#define	cgdmin(fs, c)	(cgstart(fs, c) + (fs)->fs_dblkno)	/* 1st data */
-#define	cgimin(fs, c)	(cgstart(fs, c) + (fs)->fs_iblkno)	/* inode blk */
-#define	cgsblock(fs, c)	(cgstart(fs, c) + (fs)->fs_sblkno)	/* super blk */
-#define	cgtod(fs, c)	(cgstart(fs, c) + (fs)->fs_cblkno)	/* cg block */
-#define cgstart(fs, c)							\
-	(cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
-
-/*
- * Macros for handling inode numbers:
- *     inode number to file system block offset.
- *     inode number to cylinder group number.
- *     inode number to file system block address.
- */
-#define	ino_to_cg(fs, x)	((x) / (fs)->fs_ipg)
-#define	ino_to_fsba(fs, x)						\
-	((ufs_daddr_t)(cgimin(fs, ino_to_cg(fs, x)) +			\
-	    (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
-#define	ino_to_fsbo(fs, x)	((x) % INOPB(fs))
-
-/*
- * Give cylinder group number for a file system block.
- * Give cylinder group block number for a file system block.
- */
-#define	dtog(fs, d)	((d) / (fs)->fs_fpg)
-#define	dtogd(fs, d)	((d) % (fs)->fs_fpg)
-
-/*
- * Extract the bits for a block from a map.
- * Compute the cylinder and rotational position of a cyl block addr.
- */
-#define blkmap(fs, map, loc) \
-    (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
-#define cbtocylno(fs, bno) \
-    ((bno) * NSPF(fs) / (fs)->fs_spc)
-#define cbtorpos(fs, bno) \
-    (((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \
-     (bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \
-     (fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect)
-
-/*
- * The following macros optimize certain frequently calculated
- * quantities by using shifts and masks in place of divisions
- * modulos and multiplications.
- */
-#define blkoff(fs, loc)		/* calculates (loc % fs->fs_bsize) */ \
-	((loc) & (fs)->fs_qbmask)
-#define fragoff(fs, loc)	/* calculates (loc % fs->fs_fsize) */ \
-	((loc) & (fs)->fs_qfmask)
-#define lblktosize(fs, blk)	/* calculates ((off_t)blk * fs->fs_bsize) */ \
-	((off_t)(blk) << (fs)->fs_bshift)
-/* Use this only when `blk' is known to be small, e.g., < NDADDR. */
-#define smalllblktosize(fs, blk)    /* calculates (blk * fs->fs_bsize) */ \
-	((blk) << (fs)->fs_bshift)
-#define lblkno(fs, loc)		/* calculates (loc / fs->fs_bsize) */ \
-	((loc) >> (fs)->fs_bshift)
-#define numfrags(fs, loc)	/* calculates (loc / fs->fs_fsize) */ \
-	((loc) >> (fs)->fs_fshift)
-#define blkroundup(fs, size)	/* calculates roundup(size, fs->fs_bsize) */ \
-	(((size) + (fs)->fs_qbmask) & (fs)->fs_bmask)
-#define fragroundup(fs, size)	/* calculates roundup(size, fs->fs_fsize) */ \
-	(((size) + (fs)->fs_qfmask) & (fs)->fs_fmask)
-#define fragstoblks(fs, frags)	/* calculates (frags / fs->fs_frag) */ \
-	((frags) >> (fs)->fs_fragshift)
-#define blkstofrags(fs, blks)	/* calculates (blks * fs->fs_frag) */ \
-	((blks) << (fs)->fs_fragshift)
-#define fragnum(fs, fsb)	/* calculates (fsb % fs->fs_frag) */ \
-	((fsb) & ((fs)->fs_frag - 1))
-#define blknum(fs, fsb)		/* calculates rounddown(fsb, fs->fs_frag) */ \
-	((fsb) &~ ((fs)->fs_frag - 1))
-
-/*
- * Determine the number of available frags given a
- * percentage to hold in reserve.
- */
-#define freespace(fs, percentreserved) \
-	(blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
-	(fs)->fs_cstotal.cs_nffree - \
-	((off_t)((fs)->fs_dsize) * (percentreserved) / 100))
-
-/*
- * Determining the size of a file block in the file system.
- */
-#define blksize(fs, ip, lbn) \
-	(((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \
-	    ? (fs)->fs_bsize \
-	    : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
-#define dblksize(fs, dip, lbn) \
-	(((lbn) >= NDADDR || (dip)->di_size >= smalllblktosize(fs, (lbn) + 1)) \
-	    ? (fs)->fs_bsize \
-	    : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
-#define sblksize(fs, size, lbn) \
-	(((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
-	  ? (fs)->fs_bsize \
-	  : (fragroundup(fs, blkoff(fs, (size)))))
-
-
-/*
- * Number of disk sectors per block/fragment; assumes DEV_BSIZE byte
- * sector size.
- */
-#define	NSPB(fs)	((fs)->fs_nspf << (fs)->fs_fragshift)
-#define	NSPF(fs)	((fs)->fs_nspf)
-
-/*
- * Number of inodes in a secondary storage block/fragment.
- */
-#define	INOPB(fs)	((fs)->fs_inopb)
-#define	INOPF(fs)	((fs)->fs_inopb >> (fs)->fs_fragshift)
-
-/*
- * Number of indirects in a file system block.
- */
-#define	NINDIR(fs)	((fs)->fs_nindir)
-
-extern int inside[], around[];
-extern u_char *fragtbl[];
-
-#endif
diff --git a/sys/boot/pc98/boot2/inode.h b/sys/boot/pc98/boot2/inode.h
deleted file mode 100644
index add9bb9f9ab..00000000000
--- a/sys/boot/pc98/boot2/inode.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 1982, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- *	@(#)inode.h	8.9 (Berkeley) 5/14/95
- * %FreeBSD: src/sys/ufs/ufs/inode.h,v 1.28.2.2 2001/09/29 12:52:52 iedowse Exp %
- * $FreeBSD$
- */
-
-#ifndef _UFS_UFS_INODE_H_
-#define	_UFS_UFS_INODE_H_
-
-#include 
-#include 
-#include 
-#include "dinode.h"
-
-/*
- * The size of a logical block number.
- */
-typedef long ufs_lbn_t;
-
-/*
- * This must agree with the definition in .
- */
-#define	doff_t		int32_t
-
-/*
- * The inode is used to describe each active (or recently active) file in the
- * UFS filesystem. It is composed of two types of information. The first part
- * is the information that is needed only while the file is active (such as
- * the identity of the file and linkage to speed its lookup). The second part
- * is the permanent meta-data associated with the file which is read in
- * from the permanent dinode from long term storage when the file becomes
- * active, and is put back when the file is no longer being used.
- */
-struct inode {
-	struct	 lock i_lock;	/* Inode lock. >Keep this first< */
-	LIST_ENTRY(inode) i_hash;/* Hash chain. */
-	struct	vnode  *i_vnode;/* Vnode associated with this inode. */
-	struct	vnode  *i_devvp;/* Vnode for block I/O. */
-	u_int32_t i_flag;	/* flags, see below */
-	dev_t	  i_dev;	/* Device associated with the inode. */
-	ino_t	  i_number;	/* The identity of the inode. */
-	int	  i_effnlink;	/* i_nlink when I/O completes */
-
-	union {			/* Associated filesystem. */
-		struct	fs *fs;		/* FFS */
-		struct	ext2_sb_info *e2fs;	/* EXT2FS */
-	} inode_u;
-#define	i_fs	inode_u.fs
-#define	i_e2fs	inode_u.e2fs
-	struct	 dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
-	u_quad_t i_modrev;	/* Revision level for NFS lease. */
-	struct	 lockf *i_lockf;/* Head of byte-level lock list. */
-	/*
-	 * Side effects; used during directory lookup.
-	 */
-	int32_t	  i_count;	/* Size of free slot in directory. */
-	doff_t	  i_endoff;	/* End of useful stuff in directory. */
-	doff_t	  i_diroff;	/* Offset in dir, where we found last entry. */
-	doff_t	  i_offset;	/* Offset of free space in directory. */
-	ino_t	  i_ino;	/* Inode number of found directory. */
-	u_int32_t i_reclen;	/* Size of found directory entry. */
-	u_int32_t i_spare[3];	/* XXX actually non-spare (for ext2fs). */
-
-	struct dirhash *i_dirhash; /* Hashing for large directories */
-	/*
-	 * The on-disk dinode itself.
-	 */
-	struct	dinode i_din;	/* 128 bytes of the on-disk dinode. */
-};
-
-#define	i_atime		i_din.di_atime
-#define	i_atimensec	i_din.di_atimensec
-#define	i_blocks	i_din.di_blocks
-#define	i_ctime		i_din.di_ctime
-#define	i_ctimensec	i_din.di_ctimensec
-#define	i_db		i_din.di_db
-#define	i_flags		i_din.di_flags
-#define	i_gen		i_din.di_gen
-#define	i_gid		i_din.di_gid
-#define	i_ib		i_din.di_ib
-#define	i_mode		i_din.di_mode
-#define	i_mtime		i_din.di_mtime
-#define	i_mtimensec	i_din.di_mtimensec
-#define	i_nlink		i_din.di_nlink
-#define	i_rdev		i_din.di_rdev
-#define	i_shortlink	i_din.di_shortlink
-#define	i_size		i_din.di_size
-#define	i_uid		i_din.di_uid
-
-/* These flags are kept in i_flag. */
-#define	IN_ACCESS	0x0001		/* Access time update request. */
-#define	IN_CHANGE	0x0002		/* Inode change time update request. */
-#define	IN_UPDATE	0x0004		/* Modification time update request. */
-#define	IN_MODIFIED	0x0008		/* Inode has been modified. */
-#define	IN_RENAME	0x0010		/* Inode is being renamed. */
-#define	IN_SHLOCK	0x0020		/* File has shared lock. */
-#define	IN_EXLOCK	0x0040		/* File has exclusive lock. */
-#define	IN_HASHED	0x0080		/* Inode is on hash list */
-#define	IN_LAZYMOD	0x0100		/* Modified, but don't write yet. */
-
-#ifdef _KERNEL
-/*
- * Structure used to pass around logical block paths generated by
- * ufs_getlbns and used by truncate and bmap code.
- */
-struct indir {
-	ufs_daddr_t in_lbn;		/* Logical block number. */
-	int	in_off;			/* Offset in buffer. */
-	int	in_exists;		/* Flag if the block exists. */
-};
-
-/* Convert between inode pointers and vnode pointers. */
-#define VTOI(vp)	((struct inode *)(vp)->v_data)
-#define ITOV(ip)	((ip)->i_vnode)
-
-/* Determine if soft dependencies are being done */
-#define DOINGSOFTDEP(vp)	((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
-#define DOINGASYNC(vp)		((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC)
-
-/* This overlays the fid structure (see mount.h). */
-struct ufid {
-	u_int16_t ufid_len;	/* Length of structure. */
-	u_int16_t ufid_pad;	/* Force 32-bit alignment. */
-	ino_t	  ufid_ino;	/* File number (ino). */
-	int32_t	  ufid_gen;	/* Generation number. */
-};
-#endif /* _KERNEL */
-
-#endif /* !_UFS_UFS_INODE_H_ */
diff --git a/sys/boot/pc98/boot2/io.c b/sys/boot/pc98/boot2/io.c
deleted file mode 100644
index a6b9bdce697..00000000000
--- a/sys/boot/pc98/boot2/io.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:35:57  rpd
- */
-
-#include 
-__FBSDID("$FreeBSD$");
-
-#include "boot.h"
-#include 
-#include 
-#include 
-
-static int getchar(int in_buf);
-
-/*
- * Gate A20 for high memory
- */
-void
-gateA20(void)
-{
-	outb(0xf2, 0x00);
-	outb(0xf6, 0x02);
-}
-
-/* printf - only handles %d as decimal, %c as char, %s as string */
-
-void
-printf(const char *format, ...)
-{
-	int *dataptr = (void *)&format;
-	char c;
-
-	dataptr++;
-	while ((c = *format++))
-		if (c != '%')
-			putchar(c);
-		else
-			switch (c = *format++) {
-			      case 'd': {
-				      int num = *dataptr++;
-				      char buf[10], *ptr = buf;
-				      if (num<0) {
-					      num = -num;
-					      putchar('-');
-				      }
-				      do
-					      *ptr++ = '0'+num%10;
-				      while (num /= 10);
-				      do
-					      putchar(*--ptr);
-				      while (ptr != buf);
-				      break;
-			      }
-			      case 'x': {
-				      unsigned int num = *dataptr++, dig;
-				      char buf[8], *ptr = buf;
-				      do
-					      *ptr++ = (dig=(num&0xf)) > 9?
-							'a' + dig - 10 :
-							'0' + dig;
-				      while (num >>= 4);
-				      do
-					      putchar(*--ptr);
-				      while (ptr != buf);
-				      break;
-			      }
-			      case 'c': putchar((*dataptr++)&0xff); break;
-			      case 's': {
-				      char *ptr = (char *)*dataptr++;
-				      while ((c = *ptr++))
-					      putchar(c);
-				      break;
-			      }
-			}
-}
-
-void
-putchar(int c)
-{
-	if (c == '\n')
-		putchar('\r');
-	if (loadflags & RB_DUAL) {
-		putc(c);
-		serial_putc(c);
-	} else if (loadflags & RB_SERIAL)
-		serial_putc(c);
-	else
-		putc(c);
-}
-
-static int
-getchar(int in_buf)
-{
-	int c;
-
-loop:
-	if (loadflags & RB_DUAL) {
-		if (ischar())
-			c = getc();
-		else if (serial_ischar())
-			c = serial_getc();
-		else
-			goto loop;
-	} else if (loadflags & RB_SERIAL)
-		c = serial_getc();
-	else
-		c = getc();
-	if (c == '\r')
-		c = '\n';
-	if (c == '\b') {
-		if (in_buf != 0) {
-			putchar('\b');
-			putchar(' ');
-		} else {
-			goto loop;
-		}
-	}
-	putchar(c);
-	return(c);
-}
-
-/*
- * This routine uses an inb to an unused port, the time to execute that
- * inb is approximately 1.25uS.  This value is pretty constant across
- * all CPU's and all buses, with the exception of some PCI implentations
- * that do not forward this I/O address to the ISA bus as they know it
- * is not a valid ISA bus address, those machines execute this inb in
- * 60 nS :-(.
- *
- * XXX this should be converted to use bios_tick.
- */
-void
-delay1ms(void)
-{
-	int i = 800;
-
-	while (--i >= 0)
-	    (void)outb(0x5f,0);		/* about 600ns */
-}
-
-static __inline int
-isch(void)
-{
-	int isc;
-
-	/*
-	 * Checking the keyboard has the side effect of enabling clock
-	 * interrupts so that bios_tick works.  Check the keyboard to
-	 * get this side effect even if we only want the serial status.
-	 */
-	isc = ischar();
-
-	if (loadflags & RB_DUAL) {
-		if (isc != 0)
-			return (isc);
-	} else if (!(loadflags & RB_SERIAL))
-		return (isc);
-	return (serial_ischar());
-}
-
-static __inline unsigned
-pword(unsigned physaddr)
-{
-	static int counter = 0;
-	int i;
-
-	for (i = 0; i < 512; i++)
-		(void)outb(0x5f, 0);
-
-	return (counter++);
-}
-
-int
-gets(char *buf)
-{
-#define bios_tick		pword(0x46c)
-#define BIOS_TICK_MS		1
-	unsigned initial_bios_tick;
-	char *ptr=buf;
-
-#if BOOTWAIT
-	for (initial_bios_tick = bios_tick;
-	     bios_tick - initial_bios_tick < BOOTWAIT / BIOS_TICK_MS;)
-#endif
-		if (isch())
-			for (;;) {
-				switch(*ptr = getchar(ptr - buf) & 0xff) {
-				      case '\n':
-				      case '\r':
-					*ptr = '\0';
-					return 1;
-				      case '\b':
-					if (ptr > buf) ptr--;
-					continue;
-				      default:
-					ptr++;
-				}
-#if TIMEOUT + 0
-#if !BOOTWAIT
-#error "TIMEOUT without BOOTWAIT"
-#endif
-				for (initial_bios_tick = bios_tick;;) {
-					if (isch())
-						break;
-					if (bios_tick - initial_bios_tick >=
-					    TIMEOUT / BIOS_TICK_MS)
-					return 0;
-				}
-#endif
-			}
-	return 0;
-}
-
-int
-strcmp(const char *s1, const char *s2)
-{
-	while (*s1 == *s2) {
-		if (!*s1++)
-			return 0;
-		s2++;
-	}
-	return 1;
-}
-
-#ifdef CDBOOT
-int
-strcasecmp(const char *s1, const char *s2)
-{
-	/*
-	 * We only consider ASCII chars and don't anticipate
-	 * control characters (they are invalid in filenames
-	 * anyway).
-	 */
-	while ((*s1 & 0x5f) == (*s2 & 0x5f)) {
-		if (!*s1++)
-			return 0;
-		s2++;
-	}
-	return 1;
-}
-#endif /* !CDBOOT */
-
-void
-memcpy(const void *from, void *to, size_t len)
-{
-	const char *fp = (const char *)from;
-	char *tp = (char *)to;
-
-	while (len-- > 0)
-		*tp++ = *fp++;
-}
-
-/* To quote Ken: "You are not expected to understand this." :) */
-
-void
-twiddle(void)
-{
-	putchar((char)tw_chars);
-	tw_chars = (tw_chars >> 8) | ((tw_chars & (unsigned long)0xFF) << 24);
-	putchar('\b');
-}
-
-static unsigned short *Crtat = (unsigned short *)0;
-static int row;
-static int col;
-
-void putc(int c)
-{
-	static unsigned short *crtat;
-	unsigned char sys_type;
-	unsigned short *cp;
-	int i, pos;
-
-	if (Crtat == 0) {
-		sys_type = *(unsigned char *)V(0xA1501);
-		if (sys_type & 0x08) {
-			Crtat = (unsigned short *)V(0xE0000);
-			crtat = Crtat;
-			row = 31;
-			col = 80;
-		} else {
-			Crtat = (unsigned short *)V(0xA0000);
-			crtat = Crtat;
-			row = 25;
-			col = 80;
-		}
-	}
-
-	switch(c) {
-	case '\t':
-		do {
-			putc(' ');
-		} while ((int)crtat % 16);
-		break;
-	case '\b':
-		crtat--;
-		break;
-	case '\r':
-		crtat -= (crtat - Crtat) % col;
-		break;
-	case '\n':
-		crtat += col;
-		break;
-	default:
-		*crtat = (c == 0x5c ? 0xfc : c);
-		*(crtat++ + 0x1000) = 0xe1;
-		break;
-	}
-
-	if (crtat >= Crtat + col * row) {
-		cp = Crtat;
-		for (i = 1; i < row; i++) {
-			memcpy((void *)(cp+col), (void *)cp, col*2);
-			cp += col;
-		}
-		for (i = 0; i < col; i++) {
-			*cp++ = ' ';
-		}
-		crtat -= col;
-	}
-	pos = crtat - Crtat;
-	while((inb(0x60) & 0x04) == 0) {}
-	outb(0x62, 0x49);
-	outb(0x60, pos & 0xff);
-	outb(0x60, pos >> 8);
-}
-
-void machine_check(void)
-{
-	int	ret;
-	int	i;
-	int	data = 0;
-	
-	/* PC98_SYSTEM_PARAMETER(0x501) */
-	ret = ((*(unsigned char*)V(0xA1501)) & 0x08) >> 3;
-
-	/* Wait V-SYNC */
-	while (inb(0x60) & 0x20) {}
-	while (!(inb(0x60) & 0x20)) {}
-
-	/* ANK 'A' font */
-	outb(0xa1, 0x00);
-	outb(0xa3, 0x41);
-
-	/* M_NORMAL, use CG window (all NEC OK)  */
-	/* sum */
-	for (i = 0; i < 4; i++) {
-		data += *((unsigned long*)V(0xA4000) + i);/* 0xa4000 */
-	}
-	if (data == 0x6efc58fc) { /* DA data */
-		ret |= M_NEC_PC98;
-	} else {
-		ret |= M_EPSON_PC98;
-	}
-	ret |= (inb(0x42) & 0x20) ? M_8M : 0;
-
-	/* PC98_SYSTEM_PARAMETER(0x400) */
-	if ((*(unsigned char*)V(0xA1400)) & 0x80) {
-		ret |= M_NOTE;
-	}
-	if (ret & M_NEC_PC98) {
-		/* PC98_SYSTEM_PARAMETER(0x458) */
-		if ((*(unsigned char*)V(0xA1458)) & 0x80) {
-			ret |= M_H98;
-		} else {
-			ret |= M_NOT_H98;
-		}
-	} else
-		ret |= M_NOT_H98;
-
-	(*(unsigned long *)V(0xA1620)) = ret;
-}
diff --git a/sys/boot/pc98/boot2/probe_keyboard.c b/sys/boot/pc98/boot2/probe_keyboard.c
deleted file mode 100644
index f10329683a8..00000000000
--- a/sys/boot/pc98/boot2/probe_keyboard.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) KATO Takenori, 1994-1995. 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 as
- *    the first lines of this file unmodified.
- * 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. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- * 
- * 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 "boot.h"
-
-int probe_keyboard(void)
-{
-	/*
-	 * New type (RA and later) keyboard only!
-	 */
-	if (*(unsigned char*)V(0xA1481) & 0x48)
-		return 0;
-	return 1;	/* keyboard not found */
-}
-
diff --git a/sys/boot/pc98/boot2/quota.h b/sys/boot/pc98/boot2/quota.h
deleted file mode 100644
index 324131acf56..00000000000
--- a/sys/boot/pc98/boot2/quota.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Robert Elz at The University of Melbourne.
- *
- * 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- *	@(#)quota.h	8.3 (Berkeley) 8/19/94
- * %FreeBSD: src/sys/ufs/ufs/quota.h,v 1.15 1999/12/29 04:55:05 peter Exp %
- * $FreeBSD$
- */
-
-#ifndef _UFS_UFS_QUOTA_H_
-#define	_UFS_UFS_QUOTA_H_
-
-/*
- * Definitions for disk quotas imposed on the average user
- * (big brother finally hits UNIX).
- *
- * The following constants define the amount of time given a user before the
- * soft limits are treated as hard limits (usually resulting in an allocation
- * failure). The timer is started when the user crosses their soft limit, it
- * is reset when they go below their soft limit.
- */
-#define	MAX_IQ_TIME	(7*24*60*60)	/* seconds in 1 week */
-#define	MAX_DQ_TIME	(7*24*60*60)	/* seconds in 1 week */
-
-/*
- * The following constants define the usage of the quota file array in the
- * ufsmount structure and dquot array in the inode structure.  The semantics
- * of the elements of these arrays are defined in the routine getinoquota;
- * the remainder of the quota code treats them generically and need not be
- * inspected when changing the size of the array.
- */
-#define	MAXQUOTAS	2
-#define	USRQUOTA	0	/* element used for user quotas */
-#define	GRPQUOTA	1	/* element used for group quotas */
-
-/*
- * Definitions for the default names of the quotas files.
- */
-#define INITQFNAMES { \
-	"user",		/* USRQUOTA */ \
-	"group",	/* GRPQUOTA */ \
-	"undefined", \
-}
-#define	QUOTAFILENAME	"quota"
-#define	QUOTAGROUP	"operator"
-
-/*
- * Command definitions for the 'quotactl' system call.  The commands are
- * broken into a main command defined below and a subcommand that is used
- * to convey the type of quota that is being manipulated (see above).
- */
-#define SUBCMDMASK	0x00ff
-#define SUBCMDSHIFT	8
-#define	QCMD(cmd, type)	(((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
-
-#define	Q_QUOTAON	0x0100	/* enable quotas */
-#define	Q_QUOTAOFF	0x0200	/* disable quotas */
-#define	Q_GETQUOTA	0x0300	/* get limits and usage */
-#define	Q_SETQUOTA	0x0400	/* set limits and usage */
-#define	Q_SETUSE	0x0500	/* set usage */
-#define	Q_SYNC		0x0600	/* sync disk copy of a filesystems quotas */
-
-/*
- * The following structure defines the format of the disk quota file
- * (as it appears on disk) - the file is an array of these structures
- * indexed by user or group number.  The setquota system call establishes
- * the vnode for each quota file (a pointer is retained in the ufsmount
- * structure).
- */
-struct dqblk {
-	u_int32_t dqb_bhardlimit;	/* absolute limit on disk blks alloc */
-	u_int32_t dqb_bsoftlimit;	/* preferred limit on disk blks */
-	u_int32_t dqb_curblocks;	/* current block count */
-	u_int32_t dqb_ihardlimit;	/* maximum # allocated inodes + 1 */
-	u_int32_t dqb_isoftlimit;	/* preferred inode limit */
-	u_int32_t dqb_curinodes;	/* current # allocated inodes */
-	time_t	  dqb_btime;		/* time limit for excessive disk use */
-	time_t	  dqb_itime;		/* time limit for excessive files */
-};
-
-#ifdef _KERNEL
-
-#include 
-
-/*
- * The following structure records disk usage for a user or group on a
- * filesystem. There is one allocated for each quota that exists on any
- * filesystem for the current user or group. A cache is kept of recently
- * used entries.
- */
-struct dquot {
-	LIST_ENTRY(dquot) dq_hash;	/* hash list */
-	TAILQ_ENTRY(dquot) dq_freelist;	/* free list */
-	u_int16_t dq_flags;		/* flags, see below */
-	u_int16_t dq_cnt;		/* count of active references */
-	u_int16_t dq_spare;		/* unused spare padding */
-	u_int16_t dq_type;		/* quota type of this dquot */
-	u_int32_t dq_id;		/* identifier this applies to */
-	struct	ufsmount *dq_ump;	/* filesystem that this is taken from */
-	struct	dqblk dq_dqb;		/* actual usage & quotas */
-};
-/*
- * Flag values.
- */
-#define	DQ_LOCK		0x01		/* this quota locked (no MODS) */
-#define	DQ_WANT		0x02		/* wakeup on unlock */
-#define	DQ_MOD		0x04		/* this quota modified since read */
-#define	DQ_FAKE		0x08		/* no limits here, just usage */
-#define	DQ_BLKS		0x10		/* has been warned about blk limit */
-#define	DQ_INODS	0x20		/* has been warned about inode limit */
-/*
- * Shorthand notation.
- */
-#define	dq_bhardlimit	dq_dqb.dqb_bhardlimit
-#define	dq_bsoftlimit	dq_dqb.dqb_bsoftlimit
-#define	dq_curblocks	dq_dqb.dqb_curblocks
-#define	dq_ihardlimit	dq_dqb.dqb_ihardlimit
-#define	dq_isoftlimit	dq_dqb.dqb_isoftlimit
-#define	dq_curinodes	dq_dqb.dqb_curinodes
-#define	dq_btime	dq_dqb.dqb_btime
-#define	dq_itime	dq_dqb.dqb_itime
-
-/*
- * If the system has never checked for a quota for this file, then it is
- * set to NODQUOT.  Once a write attempt is made the inode pointer is set
- * to reference a dquot structure.
- */
-#define	NODQUOT		NULL
-
-/*
- * Flags to chkdq() and chkiq()
- */
-#define	FORCE	0x01	/* force usage changes independent of limits */
-#define	CHOWN	0x02	/* (advisory) change initiated by chown */
-
-/*
- * Macros to avoid subroutine calls to trivial functions.
- */
-#ifdef DIAGNOSTIC
-#define	DQREF(dq)	dqref(dq)
-#else
-#define	DQREF(dq)	(dq)->dq_cnt++
-#endif
-
-struct inode;
-struct mount;
-struct proc;
-struct ucred;
-struct vnode;
-
-int	chkdq __P((struct inode *, long, struct ucred *, int));
-int	chkiq __P((struct inode *, long, struct ucred *, int));
-void	dqinit __P((void));
-void	dqrele __P((struct vnode *, struct dquot *));
-int	getinoquota __P((struct inode *));
-int	getquota __P((struct mount *, u_long, int, caddr_t));
-int	qsync __P((struct mount *mp));
-int	quotaoff __P((struct proc *, struct mount *, int));
-int	quotaon __P((struct proc *, struct mount *, int, caddr_t));
-int	setquota __P((struct mount *, u_long, int, caddr_t));
-int	setuse __P((struct mount *, u_long, int, caddr_t));
-int	ufs_quotactl __P((struct mount *, int, uid_t, caddr_t, struct proc *));
-
-#else /* !_KERNEL */
-
-#include 
-
-__BEGIN_DECLS
-int	quotactl __P((const char *, int, int, void *));
-__END_DECLS
-
-#endif /* _KERNEL */
-
-#endif /* !_UFS_UFS_QUOTA_H_ */
diff --git a/sys/boot/pc98/boot2/serial.S b/sys/boot/pc98/boot2/serial.S
deleted file mode 100644
index ea7b98aac4e..00000000000
--- a/sys/boot/pc98/boot2/serial.S
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:34:26  rpd
- * $FreeBSD$
- */
-
-/*
-  Copyright 1988, 1989, 1990, 1991, 1992 
-   by Intel Corporation, Santa Clara, California.
-
-                All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-#if COMCONSOLE == 0x238
-#include "serial_16550.S"
-#else
-#include "serial_8251.S"
-#endif
diff --git a/sys/boot/pc98/boot2/serial_16550.S b/sys/boot/pc98/boot2/serial_16550.S
deleted file mode 100644
index 114a369c8c9..00000000000
--- a/sys/boot/pc98/boot2/serial_16550.S
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:34:26  rpd
- * $FreeBSD$
- */
-
-/*
-  Copyright 1988, 1989, 1990, 1991, 1992 
-   by Intel Corporation, Santa Clara, California.
-
-                All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/*
- * Serial bootblock interface routines
- * Copyright (c) 1994, J"org Wunsch
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- */ 
-
-	.file	"serial.S"
-
-#include 
-#include "asm.h"
-
-	.text
-
-/*
- * The serial port interface routines implement a simple polled i/o
- * interface to a standard serial port.  Due to the space restrictions
- * for the boot blocks, no BIOS support is used (since BIOS requires
- * expensive real/protected mode switches), instead the rudimentary
- * BIOS support is duplicated here.
- *
- * The base address and speed for the i/o port are passed from the
- * Makefile in the COMCONSOLE and COMSPEED preprocessor macros.  The
- * line control parameters are currently hard-coded to 8 bits, no
- * parity, 1 stop bit (8N1).  This can be changed in init_serial().
- */
-
-/*
- * void serial_putc(int ch);
- *	Write character `ch' to port COMCONSOLE.
- */
-ENTRY(serial_putc)
-	movl	$10000, %ecx	# timeout
-	movl	$COMCONSOLE + 5, %edx	# line status reg
-1:
-	decl	%ecx
-	je	2f
-	inb	%dx, %al
-	testb	$0x20, %al
-	je	1b		# TX buffer not empty
-
-	movb	4(%esp), %al
-
-	subl	$5, %edx	# TX output reg
-	outb	%al, %dx	# send this one
-
-2:
-	ret
-
-/*
- * int serial_getc(void);
- *	Read a character from port COMCONSOLE.
- */
-ENTRY(serial_getc)
-	mov	$COMCONSOLE + 5, %edx	# line status reg
-1:
-	inb	%dx, %al
-	testb	$0x01, %al
-	je	1b		# no rx char available
-
-	xorl	%eax, %eax
-	subl	$5, %edx	# rx buffer reg
-	inb	%dx, %al	# fetch (first) character
-
-	andb	$0x7F, %al	# remove any parity bits we get
-	cmpb	$0x7F, %al	# make DEL...
-	jne	2f
-	movb	$0x08, %al	# look like BS
-2:
-	ret
-
-/*
- * int serial_ischar(void);
- *       If there is a character in the input buffer of port COMCONSOLE,
- *       return nonzero; otherwise return 0.
- */
-ENTRY(serial_ischar)
-	xorl	%eax, %eax
-	movl	$COMCONSOLE + 5, %edx	# line status reg
-	inb	%dx, %al
-	andb	$0x01, %al		# rx char available?
-	ret
-
-/*
- * void init_serial(void);
- * 	Initialize port COMCONSOLE to speed COMSPEED, line settings 8N1.
- */
-ENTRY(init_serial)
-	movl	$COMCONSOLE + 3, %edx	# line control reg
-	movb	$0x80, %al
-	outb	%al, %dx	# enable DLAB
-
-	subl	$3, %edx	# divisor latch, low byte
-	movb	(1843200 / (16*(COMSPEED))) & 0xff, %al
-	outb	%al, %dx
-	incl	%edx		# divisor latch, high byte
-	movb	(1843200 / (16*(COMSPEED))) >> 8, %al
-	outb	%al, %dx
-
-	incl	%edx		# fifo control register (if any)
-	xorl	%eax,%eax
-	outb	%al, %dx	# disable fifo to reduce worst-case busy-wait
-
-	incl	%edx		# line control reg
-	movb	$0x03, %al
-	outb	%al, %dx	# 8N1
-
-	incl	%edx		# modem control reg
-	outb	%al, %dx	# enable DTR/RTS
-
-	/* Flush the input buffer. */
-	incl	%edx		# line status reg
-1:
-	subl	$5, %edx	# rx buffer reg
-	inb	%dx, %al	# throw away (unconditionally the first time)
-	addl	$5, %edx	# line status reg
-	inb	%dx, %al
-	testb	$0x01, %al
-	jne	1b		# more
-
-	ret
diff --git a/sys/boot/pc98/boot2/serial_8251.S b/sys/boot/pc98/boot2/serial_8251.S
deleted file mode 100644
index 217dbdb1769..00000000000
--- a/sys/boot/pc98/boot2/serial_8251.S
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:34:26  rpd
- * $FreeBSD$
- */
-
-/*
-  Copyright 1988, 1989, 1990, 1991, 1992 
-   by Intel Corporation, Santa Clara, California.
-
-                All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/*
- * Serial bootblock interface routines
- * Copyright (c) 1994, J"org Wunsch
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- */ 
-
-/*
- * modified for PC-98 by KATO T. of Nagoya University
- */
-
-	.file	"serial.S"
-
-#include 
-#include "asm.h"
-
-	.text
-
-/*
- * The serial port interface routines implement a simple polled i/o
- * interface to a standard serial port.  Due to the space restrictions
- * for the boot blocks, no BIOS support is used (since BIOS requires
- * expensive real/protected mode switches), instead the rudimentary
- * BIOS support is duplicated here.
- *
- * The base address for the i/o port is passed from the Makefile in
- * the COMCONSOLE preprocessor macro.  Console parameters are currently
- * hard-coded to 9600 Bd, 8 bit.  This can be changed in the
- * init_serial() function.
- */
-
-/*
- * void serial_putc(char ch)
- *	send ch to serial port
- *
- */
-
-ENTRY(serial_putc)
-	mov	$COMCONSOLE + 2, %edx	# line status reg
-1:	inb	%dx, %al
-	testb	$0x01, %al
-	jz	1b		# TX buffer not empty
-
-	movb	0x4(%esp), %al
-
-	sub	$2, %edx	# TX output reg
-	outb	%al, %dx	# send this one
-
-	ret
-
-/*
- * int serial_getc(void)
- *	read a character from serial port
- */
-
-ENTRY(serial_getc)
-	mov	$COMCONSOLE + 2, %edx	# line status reg
-1:
-	inb	%dx, %al
-	testb	$0x02, %al
-	jz	1b		# no RX char available
-
-	xorb	%eax, %eax
-	subb	$2, %edx	# RX buffer reg
-	inb	%dx, %al	# fetch (first) character
-
-	cmp	$0x7F, %eax	# make DEL...
-	jne	2f
-	movb	$0x08, %eax	# look like BS
-2:
-	ret
-
-/*
- * int serial_ischar(void)
- *       if there is a character pending, return true; otherwise return 0
- */
-ENTRY(serial_ischar)
-	xorl	%eax, %eax
-	movl	$COMCONSOLE + 2, %edx	# line status reg
-	inb	%dx, %al
-	andb	$0x02, %al		# RX char available?
-
-	ret
-
-/*
- * void init_serial(void)
- * 	initialize the serial console port to 9600 Bd, 8 bpc
- */
-ENTRY(init_serial)
-	/* set 8253 */
-	movb	0xb6, %al
-	outb	%al, $0x77
-	movl	$COMCONSOLE_CLK, %eax
-	outb	%al, $0x75
-	inb	$0x5f, %al
-	movb	%ah, %al
-	outb	%al, $0x75
-
-	/* inhibit com int */
-	inb	$0x35, %al
-	andb	$0xf8, %al
-	movb	%al, %ah
-	inb	$0x5f, %al
-	movb	%ah, %al
-	outb	%al, $0x35
-
-	inb	$0x02, %al
-	orb	$0x10, %al
-	outb	%al, $0x02
-	
-	/* dummy command */
-	xorb	%al,%al
-	movl	$COMCONSOLE + 2, %edx
-	outb	%al, %dx
-	inb	$0x5f, %al
-	xorb	%al,%al
-	outb	%al, %dx
-	inb	$0x5f, %al
-	xorb	%al,%al
-	outb	%al, %dx
-	inb	$0x5f, %al
-
-	/* RESET 8251 */
-	movb	$0x40, %al
-	outb	%al, %dx
-
-	movb	$COMCONSOLE_MODE , %al
-	andb	$0xfc, %al
-	orb	$0x02, %al	/* factor = 1/16 */
-	outb	%al, %dx
-	inb	$0x5f, %al
-
-	/* start RS-232C */
-	movb	$0x37, %al
-	outb	%al, %dx
-
-	ret
-
diff --git a/sys/boot/pc98/boot2/start.S b/sys/boot/pc98/boot2/start.S
deleted file mode 100644
index 2a9bcbb7a1b..00000000000
--- a/sys/boot/pc98/boot2/start.S
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:36:29  rpd
- * $FreeBSD$
- */
-
-/*
-  Copyright 1988, 1989, 1990, 1991, 1992 
-   by Intel Corporation, Santa Clara, California.
-
-                All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-/*
- * Ported to PC-9801 by Yoshio Kimura
- */
-
-#include	"asm.h"
-
-	.file	"start.S"
-
-SIGNATURE=	0xaa55
-LOADSZ=		8192	/* size of unix boot */
-
-NAMEBLOCKMAGIC=	0xfadefeed /* value of magicnumebr for block2 	*/
-
-/*
- * This DEBUGMSG(msg) macro may be useful for debugging.  Its use is
- * restricted to this file since it only works in real mode.
- */
-#define DEBUGMSG(msg)		\
-	data32			; \
-	mov	$msg, %esi	; \
-	data32			; \
-	call	message
-
-	.code16
-	.text	
-	.globl	start
-
-start:
-	jmp	main
-boot_cyl:
-	.word	0
-	String	"IPL1   "
-
-main:
-	/* set up %ds */
-	xor	%ax, %ax
-	mov	%ax, %ds
-
-	/* set up %ss and %esp */
-	mov	$BOOTSEG, %eax
-	mov	%ax, %ss
-	/*
-	 * make a little room on the stack for
-	 * us to save the default bootstring we might find..
-	 * effectively, we push the bootstring.
-	 */
-	mov	$BOOTSTACK-64, %esp
-
-	/* set up %es, (where we will load boot2 to) */
-	mov	%ax, %es
-
-	push	%es
-	push	%ecx
-	push	%dx
-
-	mov	$0xa000, %eax
-	mov	%ax, %es
-
-	/* set up graphic screen */
-	movb	$0x42, %ah
-	movb	$0xc0, %ch
-	int	$0x18
-	movb	$0x40, %ah
-	int	$0x18
-
-	mov	$0x0a00, %eax		/* 80 x 25 mode  */
-
-	int	$0x18
-	movb	$0x0c, %ah		/* text on */
-	int	$0x18
-
-	/* cursor home and on */
-	xor	%dx, %dx
-	movb	$0x13, %ah
-	int	$0x18
-	movb	$0x11, %ah
-	int	$0x18
-
-	/* keyboad reset */
-	movb	$0x03, %ah
-	int	$0x18
-
-	/* transfer PC-9801 system common area to 0xa1000 */
-	mov	$0x0000, %esi
-	mov	$0x1000, %edi
-	mov	$0x0630, %ecx
-	cld
-	rep
-	movsb
-
-	/* transfer EPSON machine type to 0xa1200 */
-	push	%ds
-	mov	$0xfd00, %eax
-	mov	%ax, %ds
-	mov	0x804, %eax
-	and	$0x00ffffff, %eax
-	mov	%eax, %es: (0x1624)
-
-	pop	%ds
-	pop	%dx
-	pop	%ecx
-	pop	%es
-
-	/* bootstrap passes */
-	mov	%cs, %bx
-	cmp	$0x1fe0, %bx
-	jz	fd
-	cmp	$0x1fc0, %bx
-	jnz	hd
-	xor	%cx, %cx
-	movb	0x584, %al
-	andb	$0xf0, %al
-	cmpb	$0x30, %al
-	jz	fd
-	cmpb	$0x90, %al
-	jnz	hd
-fd:
-	mov	$0x0200, %cx
-	mov	$0x0001, %dx
-	movb	$0xd6, %ah
-	jmp	load
-hd:
-	and	%cx, %cx
-	jnz	1f
-	.code32
-	addr32
-	mov	%cs: (boot_cyl), %ecx	/* actualy %cx in real mode */
-	.code16
-1:
-	xor	%dx, %dx
-	movb	$0x06, %ah	
-
-/*
- * BIOS call "INT 0x1B Function 0xn6" to read sectors from disk into memory
- *	Call with	%ah = 0xd6(for floppy disk) or 0x06(for hard disk)
- *			%al = DA/UA
- *			%bx = data length
- *			%ch = sector size(for floppy) or cylinder(for hard)
- *			%cl = cylinder
- *			%dh = head
- *			%dl = sector
- *			%es:%bp = segment:offset of buffer
- *	Return:
- *			%ah = 0x0 on success; err code on failure
- */
-
-load:
-#ifdef NAMEBLOCK
-/*
- * Load the second sector and see if it is a boot instruction block.
- * If it is then scan the contents for the first valid string and copy it to 
- * the location of the default boot string.. then zero it out.
- * Finally write the block back to disk with the zero'd out entry..
- * I hate writing at this stage but we need this to be persistant.
- * If the boot fails, then the next boot will get the next string.
- * /etc/rc will regenerate a complete block2 iff the boot succeeds.
- *
- * Format of block 2 is:
- * [NAMEBLOCKMAGIC] <--0xdeafc0de
- * [nulls]
- * [bootstring]NULL  <---e.g. 0:wd(0,a)/kernel.experimental
- * [bootstring]NULL  <---e.g. 0:wd(0,a)/kernel.old
- * ....
- * [bootstring]NULL  <---e.g. 0:wd(0,f)/kernel
- * FF FF FF
- */
-where:
-	/*
-	 * save things we might smash
-	 * (that are not smashed immedatly after us anyway.)
-	 */
-	data32
-	push	%ecx	/* preserve 'cyl,sector ' */
-	data32
-	push	%edx
-/* 
- * Load the second sector
- * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
- *	Call with	%ah = 0x2
- *			%al = number of sectors
- *			%ch = cylinder
- *			%cl = sector
- *			%dh = head
- *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
- *			%es:%bx = segment:offset of buffer
- *	Return:
- *			%al = 0x0 on success; err code on failure
- */
-	data32
-	movl	$0x0201, %eax	/function 2 (read) 1 sector */
-	xor	%ebx, %ebx	/* %bx = 0 */ /* buffer address (ES:0) */
-	data32
-	movl	$0x0002, %ecx	/* sector 2, cylinder 0 */
-	data32
-	andl	$0x00ff, %edx	/* head 0, drive N */
-	int	$0x13
-	data32
-	jb	read_error
-	/*
-	 * confirm that it is one for us
-	 */
-	data32
-	xorl	%ebx, %ebx	/* magic number at start of buffer */
-	data32
-	addr32
-	movl	%es:(%ebx), %eax
-	data32
-	cmpl	$NAMEBLOCKMAGIC, %eax
-	data32
-	jne	notours		/* not ours so return to caller */
-	/*
-	 * scan for a bootstring
-	 * Skip the magic number, and scan till we find a non-null,
-	 * or a -1
-	 */
-	incl	%ebx	/* quicker and smaller */
-	incl	%ebx
-	incl	%ebx
-scan:
-	incl	%ebx
-	addr32
-	movb	%es:(%ebx), %al	/* load the next byte */
-	testb	%al, %al	/* and if it is null */
-	data32			/* keep scanning (past deleted entries) */
-	jz scan
-	incb	%al		/* now look for -1 */
-	data32
-	jz	notours		/* if we reach the 0xFF then we have finished */
-
-	/*
-	 * save our settings.. we need them twice..
-	 */
-	data32
-	push	%ebx
-	/*
-	 * copy it to the default string location
-	 * which is just above the stack for 64 bytes.
-	 */
-	data32
-	movl	$BOOTSTACK-64, %ecx	/* 64 bytes at the top of the stack */
-nxtbyte:
-	addr32
-	movb	%es:(%ebx), %al	/* get the next byte in */
-	addr32
-	movb	%al, %es:(%ecx)	/* and transfer it to the name buffer */
-	incl	%ebx		/* get on with the next byte */
-	incl	%ecx		/* get on with the next byte */
-	testb	%al, %al	/* if it was 0 then quit this */
-	data32
-	jnz nxtbyte		/* and looop if more to do */ 
-	
-	/*
-	 * restore the saved settings and
-	 * zero it out so next time we don't try it again
-	 */
-	data32
-	pop	%ebx		/* get back our starting location */
-#ifdef	NAMEBLOCK_WRITEBACK
-nxtbyte2:
-	addr32
-	movb	%es:(%ebx), %al	/* get the byte */
-	addr32
-	movb	$0,  %es:(%ebx)	/* zero it out */
-	data32
-	incl	%ebx		/* point to the next byte */
-	testb	%al, %al	/* check if we have finished.. */
-	data32
-	jne nxtbyte2
-/* 
- * Write the second sector back
- * Load the second sector
- * BIOS call "INT 0x13 Function 0x3" to write sectors from memory to disk
- *	Call with	%ah = 0x3
- *			%al = number of sectors
- *			%ch = cylinder
- *			%cl = sector
- *			%dh = head
- *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
- *			%es:%bx = segment:offset of buffer
- *	Return:
- *			%al = 0x0 on success; err code on failure
- */
-	data32
-	movl	$0x0301, %eax	/* write 1 sector */
-	xor	%ebx, %ebx	/* buffer is at offset 0 */ 
-	data32
-	movl	$0x0002, %ecx	/* block 2 */
-	data32
-	andl	$0xff, %edx	/* head 0 */
-	int	$0x13
-	data32
-	jnb	notours
-	data32
-	mov	$eread, %esi
-	jmp	err_stop
-#endif	/* NAMEBLOCK_WRITEBACK */
-	/*
-	 * return to the main-line
-	 */
-notours:
-	data32
-	pop	%edx
-	data32
-	pop	%ecx
-#endif
-	mov	$LOADSZ, %ebx
-	movb	0x584, %al
-	xor	%bp, %bp	/* %bp = 0, put it at 0 in the BOOTSEG */
-	int	$0x1b
-	jc	read_error
-
-	/*
-	 * ljmp to the second stage boot loader (boot2).
-	 * After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
-	 * as an internal buffer "intbuf".
-	 */
-
-	.code32
-	data32
-	ljmp	$BOOTSEG, $ EXT(boot2)
-	.code16
-
-/*
- * read_error
- */
-read_error:
-	mov	$eread, %esi
-err_stop:
-	call	message
-	jmp	stop
-
-/*
- * message: write the error message in %ds:%esi to console
- */
-message:
-
-	push	%eax
-	push	%ebx
-	push	%ds
-	push	%es
-	mov	$0xe000, %dx
-	mov	0x501, %al
-	testb	$0x08, %al
-	jnz	1f
-	mov	$0xa000, %dx
-1:
-	mov	%dx, %es
-	mov	%cs, %ax
-	mov	%ax, %ds
-	mov	vram, %di
-	mov	$0x00e1, %bx
-	mov	$160, %cx
-	cld
-
-nextb:
-	lodsb			/* load a byte into %al */
-	cmpb	$0x0, %al
-	je	done
-	cmpb	$0x0d, %al
-	je	cr_code
-	cmpb	$0x0a, %al
-	je	lf_code
-	movb	%bl, %es:0x2000(%di)
-	stosb
-	inc	%di
-	jmp	move_cursor
-lf_code:
-	add	%cx, %di
-	jmp	move_cursor
-cr_code:
-	xor	%dx, %dx
-	mov	%di, %ax
-	div	%cx
-	sub	%dx, %di
-move_cursor:
-	mov	%di, %dx
-	movb	$0x13, %ah
-	int	$0x18
-	jmp	nextb
-done:
-	mov	%di, vram
-	pop	%es
-	pop	%ds
-	pop	%ebx
-	pop	%eax
-	ret
-
-stop:	hlt
-	jmp	stop		/* halt doesnt actually halt forever */
-
-vram:
-	.word	0
-
-/* error messages */
-
-
-#ifdef	DEBUG
-one:	String		"1-\0"
-two:	String		"2-\0"
-three:	String		"3-\0"
-four:	String		"4-\0"
-#endif	/* DEBUG */
-#ifdef 	NAMEBLOCK_WRITEBACK
-ewrite:	String		"Write error\r\n\0"
-#endif	/* NAMEBLOCK_WRITEBACK */
-eread:	String		"Read error\r\n\0"
-enoboot: String		"No bootable partition\r\n\0"
-endofcode:
-
-	. = EXT(start) + 0x1be
-
-/* Partition table */
-
-	.fill 0x30,0x1,0x0
-	.byte 0x80, 0x00, 0x01, 0x00
-	.byte 0xa5, 0xff, 0xff, 0xff
-	.byte 0x00, 0x00, 0x00, 0x00
-	.byte 0x50, 0xc3, 0x00, 0x00
-
-/* the last 2 bytes in the sector 0 contain the signature */
-	.value	SIGNATURE
-
-ENTRY(disklabel)
-	. = EXT(start) + 0x400	
diff --git a/sys/boot/pc98/boot2/sys.c b/sys/boot/pc98/boot2/sys.c
deleted file mode 100644
index c8d4304bd31..00000000000
--- a/sys/boot/pc98/boot2/sys.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:36:34  rpd
- */
-
-#include 
-__FBSDID("$FreeBSD$");
-
-/*
- * Ported to PC-9801 by Yoshio Kimura
- */
-
-#include "boot.h"
-#include 
-
-#if 0
-/* #define BUFSIZE 4096 */
-#define BUFSIZE MAXBSIZE
-static char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
-#endif
-
-static char biosdrivedigit;
-
-#define BUFSIZE 8192
-#define MAPBUFSIZE BUFSIZE
-static char buf[BUFSIZE], fsbuf[BUFSIZE], iobuf[BUFSIZE];
-
-static char mapbuf[MAPBUFSIZE];
-static int mapblock;
-
-int poff;
-
-#ifdef RAWBOOT
-#define STARTBYTE	8192	/* Where on the media the kernel starts */
-#endif
-
-static int block_map(int file_block);
-static int find(char *path);
-
-void
-xread(char *addr, int size)
-{
-	int count = BUFSIZE;
-	while (size > 0) {
-		if (BUFSIZE > size)
-			count = size;
-		read(buf, count);
-		pcpy(buf, addr, count);
-		size -= count;
-		addr += count;
-	}
-}
-
-#ifndef RAWBOOT
-void
-read(char *buffer, int count)
-{
-	int logno, off, size;
-	int cnt2, bnum2;
-	struct fs *fs_copy;
-
-	while (count > 0 && poff < inode.i_size) {
-		fs_copy = fs;
-		off = blkoff(fs_copy, poff);
-		logno = lblkno(fs_copy, poff);
-		cnt2 = size = blksize(fs_copy, &inode, logno);
-		bnum2 = fsbtodb(fs_copy, block_map(logno)) + boff;
-		if (	(!off)  && (size <= count)) {
-			devread(buffer, bnum2, cnt2);
-		} else {
-			size -= off;
-			if (size > count)
-				size = count;
-			devread(iobuf, bnum2, cnt2);
-			memcpy(iobuf+off, buffer, size);
-		}
-		buffer += size;
-		count -= size;
-		poff += size;
-	}
-}
-#else
-void
-read(char *buffer, int count)
-{
-	int cnt, bnum, off, size;
-
-	off = STARTBYTE + poff;
-	poff += count;
-
-	/* Read any unaligned bit at the front */
-	cnt = off & 511;
-	if (cnt) {
-		size = 512-cnt;
-		if (count < size)
-			size = count;
-		devread(iobuf, off >> 9, 512);
-		memcpy(iobuf+cnt, buffer, size);
-		count -= size;
-		off += size;
-		buffer += size;
-	}
-	size = count & (~511);
-	if (size && (off & (~511))) {
-		devread(buffer, off >> 9, size);
-		off += size;
-		count -= size;
-		buffer += size;
-	}
-	if (count) {
-		devread(iobuf, off >> 9, 512);
-		memcpy(iobuf, buffer, count);
-	}
-}
-#endif
-
-static int
-find(char *path)
-{
-	char *rest, ch;
-	int block, off, loc, ino = ROOTINO;
-	struct direct *dp;
-	char list_only;
-
-	list_only = (path[0] == '?' && path[1] == '\0');
-loop:
-	devread(iobuf, fsbtodb(fs, ino_to_fsba(fs, ino)) + boff, fs->fs_bsize);
-	memcpy((void *)&((struct dinode *)iobuf)[ino % fs->fs_inopb],
-	      (void *)&inode.i_din,
-	      sizeof (struct dinode));
-	if (!*path)
-		return 1;
-	while (*path == '/')
-		path++;
-	if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
-		return 0;
-	for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
-	*rest = 0;
-	loc = 0;
-	do {
-		if (loc >= inode.i_size) {
-			if (list_only) {
-				putchar('\n');
-				return -1;
-			} else {
-				return 0;
-			}
-		}
-		if (!(off = blkoff(fs, loc))) {
-			block = lblkno(fs, loc);
-			devread(iobuf, fsbtodb(fs, block_map(block)) + boff,
-				blksize(fs, &inode, block));
-		}
-		dp = (struct direct *)(iobuf + off);
-		loc += dp->d_reclen;
-		if (dp->d_ino && list_only)
-			printf("%s ", dp->d_name);
-	} while (!dp->d_ino || strcmp(path, dp->d_name));
-	ino = dp->d_ino;
-	*(path = rest) = ch;
-	goto loop;
-}
-
-
-static int
-block_map(int file_block)
-{
-	int bnum;
-	if (file_block < NDADDR)
-		return(inode.i_db[file_block]);
-	if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
-		devread(mapbuf, bnum, fs->fs_bsize);
-		mapblock = bnum;
-	}
-	return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
-}
-
-
-int
-openrd(void)
-{
-	char **devp, *name0 = name, *cp = name0;
-	int biosdrive, dosdev_copy, ret;
-
-	/*******************************************************\
-	* If bracket given look for preceding device name	*
-	\*******************************************************/
-	while (*cp && *cp!='(')
-		cp++;
-	if (!*cp)
-	{
-		cp = name0;
-	}
-	else
-	{
-		/*
-		 * Look for a BIOS drive number (a leading digit followed
-		 * by a colon).
-		 */
-		biosdrivedigit = '\0';
-		if (*(name0 + 1) == ':' && *name0 >= '0' && *name0 <= '9') {
-			biosdrivedigit = *name0;
-			name0 += 2;
-		}
-
-		if (cp++ != name0)
-		{
-			for (devp = devs; *devp; devp++)
-				if (name0[0] == (*devp)[0] &&
-				    name0[1] == (*devp)[1])
-					break;
-			if (!*devp)
-			{
-				printf("Unknown device\n");
-				return 1;
-			}
-			maj = devp-devs;
-		}
-		/*******************************************************\
-		* Look inside brackets for unit number, and partition	*
-		\*******************************************************/
-		/*
-		 * Allow any valid digit as the unit number, as the BIOS
-		 * will complain if the unit number is out of range.
-		 * Restricting the range here prevents the possibilty of using
-		 * BIOSes that support more than 2 units.
-		 * XXX Bad values may cause strange errors, need to check if
-		 * what happens when a value out of range is supplied.
-		 */
-		if (*cp >= '0' && *cp <= '9')
-			unit = *cp++ - '0';
-		if (!*cp || (*cp == ',' && !*++cp))
-			return 1;
-		if (*cp >= 'a' && *cp <= 'p')
-			part = *cp++ - 'a';
-		while (*cp && *cp++!=')') ;
-		if (!*cp)
-			return 1;
-	}
-	biosdrive = biosdrivedigit - '0';
-	if (biosdrivedigit == '\0') {
-		biosdrive = dosdev & 0x0f;
-#if BOOT_HD_BIAS > 0
-		/* XXX */
-		if (maj == 4)
-			biosdrive += BOOT_HD_BIAS;
-#endif
-	}
-	switch(maj)
-	{
-	case 4:	/* da */
-		dosdev_copy = biosdrive | 0xA0; /* SCSI HD or MO */
-		break;
-	case 0:	/* wd */
-	case 2:	/* 1200KB fd */
-		dosdev_copy = (maj << 3) | unit | 0x80;
-		break;
-	case 6:	/* 1440KB fd */
-		dosdev_copy = (maj << 3) | unit;
-		break;
-	default:
-		printf("Unknown device\n");
-		return 1;
-	}
-	dosdev = dosdev_copy;
-#if 0
-	/* XXX this is useful, but misplaced. */
-	printf("dosdev= %x, biosdrive = %d, unit = %d, maj = %d\n",
-		dosdev_copy, biosdrive, unit, maj);
-#endif
-
-	/***********************************************\
-	* Now we know the disk unit and part,		*
-	* Load disk info, (open the device)		*
-	\***********************************************/
-	if (devopen())
-		return 1;
-
-#ifndef RAWBOOT
-	/***********************************************\
-	* Load Filesystem info (mount the device)	*
-	\***********************************************/
-	devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE);
-	/***********************************************\
-	* Find the actual FILE on the mounted device	*
-	\***********************************************/
-	ret = find(cp);
-	name = cp;
-	if (ret == 0)
-		return 1;
-	if (ret < 0) {
-		name = NULL;
-		return -1;
-	}
-	poff = 0;
-#endif /* RAWBOOT */
-	return 0;
-}
diff --git a/sys/boot/pc98/boot2/table.c b/sys/boot/pc98/boot2/table.c
deleted file mode 100644
index e8e6dea521b..00000000000
--- a/sys/boot/pc98/boot2/table.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- *	from: Mach, Revision 2.2  92/04/04  11:36:43  rpd
- */
-/*
-  Copyright 1988, 1989, 1990, 1991, 1992
-   by Intel Corporation, Santa Clara, California.
-
-                All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN 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 "boot.h"
-
-/*  Segment Descriptor
- *
- * 31          24         19   16                 7           0
- * ------------------------------------------------------------
- * |             | |B| |A|       | |   |1|0|E|W|A|            |
- * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |
- * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
- * ------------------------------------------------------------
- * |                             |                            |
- * |        BASE 15..0           |       LIMIT 15..0          |
- * |                             |                            |
- * ------------------------------------------------------------
- */
-
-struct seg_desc {
-	unsigned short	limit_15_0;
-	unsigned short	base_15_0;
-	unsigned char	base_23_16;
-	unsigned char	p_dpl_type;
-	unsigned char	g_b_a_limit;
-	unsigned char	base_31_24;
-	};
-
-#define RUN	0		/* not really 0, but filled in at boot time */
-
-struct seg_desc	Gdt[] = {
-	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0},		/* 0x0 : null */
-	{0xFFFF, 0x0, 0x0, 0x9F, 0xCF, 0x0},	/* 0x08 : kernel code */
-			/* 0x9E? */
-	{0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0},	/* 0x10 : kernel data */
-			/* 0x92? */
-	{0xFFFF, RUN, RUN, 0x9E, 0x40, 0x0},	/* 0x18 : boot code */
-	/*
-	 * The limit of boot data should be more than or equal to 0x9FFFF
-	 * for saving BIOS parameter and EPSON machine ID into 2'nd T-VRAM,
-	 * because base address is normally 0x10000.
-	 */
-	{0xFFFF, RUN, RUN, 0x92, 0x4F, 0x0},	/* 0x20 : boot data */
-	{0xFFFF, RUN, RUN, 0x9E, 0x0, 0x0},	/* 0x28 : boot code, 16 bits */
-	{0xFFFF, 0x0, 0x0, 0x92, 0x0, 0x0},	/* 0x30 : boot data, 16 bits */
-#ifdef BDE_DEBUGGER
-	/* More for bdb. */
-	{},					/* BIOS_TMP_INDEX = 7 : null */
-	{},					/* TSS_INDEX = 8 : null */
-	{0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0},	/* DS_286_INDEX = 9 */
-	{0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0},	/* ES_286_INDEX = 10 */
-	{},					/* Unused = 11 : null */
-	{0x7FFF, 0x8000, 0xB, 0xB2, 0x40, 0x0},	/* COLOR_INDEX = 12 */
-	{0x7FFF, 0x0, 0xB, 0xB2, 0x40, 0x0},	/* MONO_INDEX = 13 */
-	{0xFFFF, RUN, RUN, 0x9A, 0x40, 0x0},	/* DB_CS_INDEX = 14 */
-	{0xFFFF, RUN, RUN, 0x9A, 0x0, 0x0},	/* DB_CS16_INDEX = 15 */
-	{0xFFFF, RUN, RUN, 0x92, 0x40, 0x0},	/* DB_DS_INDEX = 16 */
-	{8*18-1, RUN, RUN, 0x92, 0x40, 0x0},	/* GDT_INDEX = 17 */
-#endif /* BDE_DEBUGGER */
-};
-
-#ifdef BDE_DEBUGGER
-struct idt_desc {
-	unsigned short	entry_15_0;
-	unsigned short	selector;
-	unsigned char	padding;
-	unsigned char	p_dpl_type;
-	unsigned short	entry_31_16;
-};
-
-struct idt_desc	Idt[] = {
-	{},					/* Null (int 0) */
-	{RUN, 0x70, 0, 0x8E, 0},		/* DEBUG_VECTOR = 1 */
-	{},					/* Null (int 2) */
-	{RUN, 0x70, 0, 0xEE, 0},		/* BREAKPOINT_VECTOR = 3 */
-};
-#endif /* BDE_DEBUGGER */
-
-struct pseudo_desc {
-	unsigned short	limit;
-	unsigned short	base_low;
-	unsigned short	base_high;
-	};
-
-struct pseudo_desc Gdtr = { sizeof Gdt - 1, RUN, RUN };
-#ifdef BDE_DEBUGGER
-struct pseudo_desc Idtr_prot = { sizeof Idt - 1, RUN, RUN };
-struct pseudo_desc Idtr_real = { 0x400 - 1, 0x0, 0x0 };
-#endif
-
-/*
- * All initialized data is defined in one file to reduce space wastage from
- * fragmentation.
- */
-char *devs[] = { "wd", "dk", "fd", "wt", "da", "dk", "fd", 0 };
-unsigned tw_chars = 0x5C2D2F7C;	/* "\-/|" */

From f96c46c6ab61dce0b0dae450e2fb0e85f76727ba Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Fri, 15 Jan 2010 14:20:01 +0000
Subject: [PATCH 1137/2592] Update to a 26-Nov-2009 release.

---
 contrib/one-true-awk/FIXES     | 17 ++++++++
 contrib/one-true-awk/b.c       | 27 +++++++++++--
 contrib/one-true-awk/lib.c     |  1 +
 contrib/one-true-awk/mac.code  | 73 ----------------------------------
 contrib/one-true-awk/main.c    | 35 +++++++++++-----
 contrib/one-true-awk/makefile  |  1 -
 contrib/one-true-awk/maketab.c |  2 +-
 contrib/one-true-awk/proctab.c |  2 +-
 contrib/one-true-awk/proto.h   |  2 +-
 contrib/one-true-awk/run.c     |  9 +++--
 usr.bin/awk/Makefile           |  8 +---
 usr.bin/awk/b.c.diff           | 53 ------------------------
 usr.bin/awk/main.c.diff        | 69 --------------------------------
 usr.bin/awk/run.c.diff         | 18 ---------
 14 files changed, 77 insertions(+), 240 deletions(-)
 delete mode 100644 contrib/one-true-awk/mac.code
 delete mode 100644 usr.bin/awk/b.c.diff
 delete mode 100644 usr.bin/awk/main.c.diff
 delete mode 100644 usr.bin/awk/run.c.diff

diff --git a/contrib/one-true-awk/FIXES b/contrib/one-true-awk/FIXES
index 2f39d4827c1..bda79768606 100644
--- a/contrib/one-true-awk/FIXES
+++ b/contrib/one-true-awk/FIXES
@@ -25,6 +25,23 @@ THIS SOFTWARE.
 This file lists all bug fixes, changes, etc., made since the AWK book
 was sent to the printers in August, 1987.
 
+Nov 26, 2009:
+	fixed a long-standing issue with when FS takes effect.  a
+	change to FS is now noticed immediately for subsequent splits.
+
+	changed the name getline() to awkgetline() to avoid yet another
+	name conflict somewhere.
+
+Feb 11, 2009:
+	temporarily for now defined HAS_ISBLANK, since that seems to
+	be the best way through the thicket.  isblank arrived in C99,
+	but seems to be arriving at different systems at different
+	times.
+
+Oct 8, 2008:
+	fixed typo in b.c that set tmpvec wrongly.  no one had ever
+	run into the problem, apparently.  thanks to alistair crooks.
+
 Oct 23, 2007:
 	minor fix in lib.c: increase inputFS to 100, change malloc
 	for fields to n+1.  
diff --git a/contrib/one-true-awk/b.c b/contrib/one-true-awk/b.c
index 0d91f23f548..baefe6f71e2 100644
--- a/contrib/one-true-awk/b.c
+++ b/contrib/one-true-awk/b.c
@@ -24,6 +24,9 @@ THIS SOFTWARE.
 
 /* lasciate ogne speranza, voi ch'intrate. */
 
+#include 
+__FBSDID("$FreeBSD$");
+
 #define	DEBUG
 
 #include 
@@ -285,9 +288,21 @@ int quoted(char **pp)	/* pick up next thing after a \\ */
 	return c;
 }
 
+static int collate_range_cmp(int a, int b)
+{
+	static char s[2][2];
+
+	if ((uschar)a == (uschar)b)
+		return 0;
+	s[0][0] = a;
+	s[1][0] = b;
+	return (strcoll(s[0], s[1]));
+}
+
 char *cclenter(const char *argp)	/* add a character class */
 {
 	int i, c, c2;
+	int j;
 	uschar *p = (uschar *) argp;
 	uschar *op, *bp;
 	static uschar *buf = 0;
@@ -306,15 +321,18 @@ char *cclenter(const char *argp)	/* add a character class */
 				c2 = *p++;
 				if (c2 == '\\')
 					c2 = quoted((char **) &p);
-				if (c > c2) {	/* empty; ignore */
+				if (collate_range_cmp(c, c2) > 0) {
 					bp--;
 					i--;
 					continue;
 				}
-				while (c < c2) {
+				for (j = 0; j < NCHARS; j++) {
+					if ((collate_range_cmp(c, j) > 0) ||
+					    collate_range_cmp(j, c2) > 0)
+						continue;
 					if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1"))
 						FATAL("out of space for character class [%.10s...] 2", p);
-					*bp++ = ++c;
+					*bp++ = j;
 					i++;
 				}
 				continue;
@@ -731,6 +749,7 @@ Node *unary(Node *np)
  * to nelson beebe for the suggestion; let's see if it works everywhere.
  */
 
+/* #define HAS_ISBLANK */
 #ifndef HAS_ISBLANK
 
 int (isblank)(int c)
@@ -876,7 +895,7 @@ int cgoto(fa *f, int s, int c)
 					if (q[j] >= maxsetvec) {
 						maxsetvec *= 4;
 						setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
-						tmpset = (int *) realloc(setvec, maxsetvec * sizeof(int));
+						tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
 						if (setvec == 0 || tmpset == 0)
 							overflo("cgoto overflow");
 					}
diff --git a/contrib/one-true-awk/lib.c b/contrib/one-true-awk/lib.c
index c9cc5d563b1..017b37670d0 100644
--- a/contrib/one-true-awk/lib.c
+++ b/contrib/one-true-awk/lib.c
@@ -274,6 +274,7 @@ void fldbld(void)	/* create fields from current record */
 	}
 	fr = fields;
 	i = 0;	/* number of fields accumulated here */
+	strcpy(inputFS, *FS);
 	if (strlen(inputFS) > 1) {	/* it's a regular expression */
 		i = refldbld(r, inputFS);
 	} else if ((sep = *inputFS) == ' ') {	/* default whitespace */
diff --git a/contrib/one-true-awk/mac.code b/contrib/one-true-awk/mac.code
deleted file mode 100644
index af47b17fb08..00000000000
--- a/contrib/one-true-awk/mac.code
+++ /dev/null
@@ -1,73 +0,0 @@
-Note added June, 2002:  
-
-With the advent of OS X, life is simpler:  if you have the developer
-tools installed, the standard awk makefile and gcc works fine, and
-you can ignore the rest of this file, which is now hereby deprecated.
-
-
-
-
-This file contains a make shell script and a version of the file
-missing95.c for the Mac, courtesy of Dan Allen.
-
-make shell script:
-
-# MPW Shell script to build Awk using Apple's MRC compiler.
-# 22 Jan 1999 - Created by Dan Allen.
-# 25 Mar 1999 - Updated for newer Awk.
-#
-# Porting notes for the Mac:
-# 
-# 1.  main in main.c needs to have its prototype changed to:
-# 
-#     int main(int argc, char *argv[], char *environ[])
-#
-# 2.  popen and pclose in missing95.c need to have as their body the
-#     older style
-#
-#				return NULL;
-#
-#     as parallel pipes are not supported by MPW.
-#
-# 3.  To make your Mac more responsive while long awk scripts run,
-#     you may want to add some SpinCursor calls to support cooperative multitasking.
-#
-# All of these minor changes can be put under "#ifdef powerc" for portability's sake.
-#
-#
-
-If {1} == "clean"
-	Delete -i awk maketab maketab.c.o ytab.c.o b.c.o main.c.o parse.c.o proctab.c proctab.c.o tran.c.o lib.c.o run.c.o lex.c.o missing95.c.o
-Else
-	MRC ytab.c -w off -opt speed
-	MRC b.c -w off -opt speed
-	MRC main.c -w off -opt speed
-	MRC parse.c -w off -opt speed
-	MRC maketab.c -w off -opt speed
-	PPCLink -o maketab maketab.c.o "{PPCLibraries}InterfaceLib" "{PPCLibraries}MathLib" "{PPCLibraries}StdCLib" "{PPCLibraries}StdCRuntime.o" "{PPCLibraries}PPCCRuntime.o" "{PPCLibraries}PPCToolLibs.o" -t MPST -c 'MPS '
-	maketab > proctab.c
-	MRC proctab.c -w off -opt speed
-	MRC tran.c -w off -opt speed
-	MRC lib.c -w off -opt speed
-	MRC run.c -w off -opt speed
-	MRC lex.c -w off -opt speed
-	MRC missing95.c -w off -opt speed
-	PPCLink -o awk ytab.c.o b.c.o main.c.o parse.c.o proctab.c.o tran.c.o lib.c.o run.c.o lex.c.o missing95.c.o "{PPCLibraries}InterfaceLib" "{PPCLibraries}MathLib" "{PPCLibraries}StdCLib" "{PPCLibraries}StdCRuntime.o" "{PPCLibraries}PPCCRuntime.o" "{PPCLibraries}PPCToolLibs.o" -d
-	SetFile awk -d . -m . -t MPST -c 'MPS '
-End
-
-
-missing95.c for the Mac:
-
-/* popen and pclose are not available on the Mac. */
-
-#include 
-
-FILE *popen(char *s, char *m) {
-	return NULL;
-}
-
-int pclose(FILE *f) {
-	return NULL;
-}
-
diff --git a/contrib/one-true-awk/main.c b/contrib/one-true-awk/main.c
index e1ed1773e09..d78a8511e79 100644
--- a/contrib/one-true-awk/main.c
+++ b/contrib/one-true-awk/main.c
@@ -22,7 +22,10 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 THIS SOFTWARE.
 ****************************************************************/
 
-const char	*version = "version 20070501";
+#include 
+__FBSDID("$FreeBSD$");
+
+const char	*version = "version 20091126 (FreeBSD)";
 
 #define DEBUG
 #include 
@@ -58,6 +61,7 @@ int main(int argc, char *argv[])
 	const char *fs = NULL;
 
 	setlocale(LC_CTYPE, "");
+	setlocale(LC_COLLATE, "");
 	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
 	cmdname = argv[0];
 	if (argc == 1) {
@@ -86,13 +90,18 @@ int main(int argc, char *argv[])
 				safe = 1;
 			break;
 		case 'f':	/* next argument is program filename */
-			argc--;
-			argv++;
-			if (argc <= 1)
-				FATAL("no program filename");
-			if (npfile >= MAX_PFILE - 1)
-				FATAL("too many -f options"); 
-			pfile[npfile++] = argv[1];
+			if (argv[1][2] != 0) {	/* arg is -fsomething */
+				if (npfile >= MAX_PFILE - 1)
+					FATAL("too many -f options"); 
+				pfile[npfile++] = &argv[1][2];
+			} else {		/* arg is -f something */
+				argc--; argv++;
+				if (argc <= 1)
+					FATAL("no program filename");
+				if (npfile >= MAX_PFILE - 1)
+					FATAL("too many -f options"); 
+				pfile[npfile++] = argv[1];
+			}
 			break;
 		case 'F':	/* set field separator */
 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
@@ -111,8 +120,14 @@ int main(int argc, char *argv[])
 				WARNING("field separator FS is empty");
 			break;
 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
-			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
-				setclvar(argv[1]);
+			if (argv[1][2] != 0) {	/* arg is -vsomething */
+				if (argv[1][2] != 0)
+					setclvar(&argv[1][2]);
+			} else {		/* arg is -v something */
+				argc--; argv++;
+				if (argc > 1 && isclvar(argv[1]))
+					setclvar(argv[1]);
+			}
 			break;
 		case 'd':
 			dbg = atoi(&argv[1][2]);
diff --git a/contrib/one-true-awk/makefile b/contrib/one-true-awk/makefile
index a761a594d89..9d3985be2d4 100644
--- a/contrib/one-true-awk/makefile
+++ b/contrib/one-true-awk/makefile
@@ -31,7 +31,6 @@ CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov
 CC = gcc -Wall -g
 CC = cc
 CC = gcc -O4
-CC = gcc -Wall -g
 
 
 YACC = bison -y
diff --git a/contrib/one-true-awk/maketab.c b/contrib/one-true-awk/maketab.c
index 1f78a9eb922..31acd7522da 100644
--- a/contrib/one-true-awk/maketab.c
+++ b/contrib/one-true-awk/maketab.c
@@ -102,7 +102,7 @@ struct xx
 	{ CALL, "call", "call" },
 	{ ARG, "arg", "arg" },
 	{ VARNF, "getnf", "NF" },
-	{ GETLINE, "getline", "getline" },
+	{ GETLINE, "awkgetline", "getline" },
 	{ 0, "", "" },
 };
 
diff --git a/contrib/one-true-awk/proctab.c b/contrib/one-true-awk/proctab.c
index 401dec635d9..e4eddfda92d 100644
--- a/contrib/one-true-awk/proctab.c
+++ b/contrib/one-true-awk/proctab.c
@@ -180,7 +180,7 @@ Cell *(*proctab[93])(Node **, int) = {
 	nullproc,	/* NUMBER */
 	nullproc,	/* STRING */
 	nullproc,	/* REGEXPR */
-	getline,	/* GETLINE */
+	awkgetline,	/* GETLINE */
 	substr,	/* SUBSTR */
 	split,	/* SPLIT */
 	jump,	/* RETURN */
diff --git a/contrib/one-true-awk/proto.h b/contrib/one-true-awk/proto.h
index adda07108c8..0a68b3a813f 100644
--- a/contrib/one-true-awk/proto.h
+++ b/contrib/one-true-awk/proto.h
@@ -149,7 +149,7 @@ extern	Cell	*call(Node **, int);
 extern	Cell	*copycell(Cell *);
 extern	Cell	*arg(Node **, int);
 extern	Cell	*jump(Node **, int);
-extern	Cell	*getline(Node **, int);
+extern	Cell	*awkgetline(Node **, int);
 extern	Cell	*getnf(Node **, int);
 extern	Cell	*array(Node **, int);
 extern	Cell	*awkdelete(Node **, int);
diff --git a/contrib/one-true-awk/run.c b/contrib/one-true-awk/run.c
index a9e269cc715..20c08b10525 100644
--- a/contrib/one-true-awk/run.c
+++ b/contrib/one-true-awk/run.c
@@ -22,6 +22,9 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 THIS SOFTWARE.
 ****************************************************************/
 
+#include 
+__FBSDID("$FreeBSD$");
+
 #define DEBUG
 #include 
 #include 
@@ -388,7 +391,7 @@ Cell *jump(Node **a, int n)	/* break, continue, next, nextfile, return */
 	return 0;	/* not reached */
 }
 
-Cell *getline(Node **a, int n)	/* get next line from specific input */
+Cell *awkgetline(Node **a, int n)	/* get next line from specific input */
 {		/* a[0] is variable, a[1] is operator, a[2] is filename */
 	Cell *r, *x;
 	extern Cell **fldtab;
@@ -653,7 +656,7 @@ Cell *relop(Node **a, int n)	/* a[0 < a[1], etc. */
 		j = x->fval - y->fval;
 		i = j<0? -1: (j>0? 1: 0);
 	} else {
-		i = strcmp(getsval(x), getsval(y));
+		i = strcoll(getsval(x), getsval(y));
 	}
 	tempfree(x);
 	tempfree(y);
@@ -1159,11 +1162,11 @@ Cell *cat(Node **a, int q)	/* a[0] cat a[1] */
 			x->sval, y->sval);
 	strcpy(s, x->sval);
 	strcpy(s+n1, y->sval);
+	tempfree(x);
 	tempfree(y);
 	z = gettemp();
 	z->sval = s;
 	z->tval = STR;
-	tempfree(x);
 	return(z);
 }
 
diff --git a/usr.bin/awk/Makefile b/usr.bin/awk/Makefile
index 7ec2e575c60..65386365b18 100644
--- a/usr.bin/awk/Makefile
+++ b/usr.bin/awk/Makefile
@@ -8,6 +8,8 @@ SRCS=	awkgram.y b.c lex.c lib.c main.c parse.c proctab.c run.c tran.c ytab.h
 
 CFLAGS+= -DHAS_ISBLANK -I. -I${AWKSRC} -DFOPEN_MAX=64
 
+WARNS?=	1
+
 DPADD=	${LIBM}
 LDADD=	-lm
 
@@ -25,10 +27,4 @@ proctab.c: maketab
 build-tools: maketab
 maketab: ytab.h ${AWKSRC}/maketab.c
 
-.for f in b.c main.c run.c
-${f}: ${AWKSRC}/${f} ${.CURDIR}/${f}.diff
-	patch -s -b .orig -o ${.TARGET} < ${.CURDIR}/${f}.diff ${AWKSRC}/${f}
-CLEANFILES+= ${f}
-.endfor
-
 .include 
diff --git a/usr.bin/awk/b.c.diff b/usr.bin/awk/b.c.diff
deleted file mode 100644
index 525fcbc37dc..00000000000
--- a/usr.bin/awk/b.c.diff
+++ /dev/null
@@ -1,53 +0,0 @@
-$FreeBSD$
-
-Index: b.c
-===================================================================
-RCS file: /home/ncvs/src/contrib/one-true-awk/b.c,v
-retrieving revision 1.1.1.8
-diff -u -p -r1.1.1.8 b.c
---- b.c	16 May 2005 19:11:31 -0000	1.1.1.8
-+++ b.c	16 May 2005 19:12:40 -0000
-@@ -282,9 +282,21 @@ int quoted(char **pp)	/* pick up next th
- 	return c;
- }
- 
-+static int collate_range_cmp(int a, int b)
-+{
-+	static char s[2][2];
-+
-+	if ((uschar)a == (uschar)b)
-+		return 0;
-+	s[0][0] = a;
-+	s[1][0] = b;
-+	return (strcoll(s[0], s[1]));
-+}
-+
- char *cclenter(const char *argp)	/* add a character class */
- {
- 	int i, c, c2;
-+	int j;
- 	uschar *p = (uschar *) argp;
- 	uschar *op, *bp;
- 	static uschar *buf = 0;
-@@ -303,15 +315,18 @@ char *cclenter(const char *argp)	/* add 
- 				c2 = *p++;
- 				if (c2 == '\\')
-					c2 = quoted((char **) &p);
--				if (c > c2) {	/* empty; ignore */
-+				if (collate_range_cmp(c, c2) > 0) {
- 					bp--;
- 					i--;
- 					continue;
- 				}
--				while (c < c2) {
-+				for (j = 0; j < NCHARS; j++) {
-+					if ((collate_range_cmp(c, j) > 0) ||
-+					    collate_range_cmp(j, c2) > 0)
-+						continue;
-					if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1"))
-						FATAL("out of space for character class [%.10s...] 2", p);
--					*bp++ = ++c;
-+					*bp++ = j;
- 					i++;
- 				}
- 				continue;
diff --git a/usr.bin/awk/main.c.diff b/usr.bin/awk/main.c.diff
deleted file mode 100644
index 252cd5ac242..00000000000
--- a/usr.bin/awk/main.c.diff
+++ /dev/null
@@ -1,69 +0,0 @@
-$FreeBSD$
-
-Index: main.c
-===================================================================
-RCS file: /home/ncvs/src/contrib/one-true-awk/main.c,v
-retrieving revision 1.1.1.10
-diff -u -p -r1.1.1.10 main.c
---- main.c	16 May 2005 19:11:31 -0000	1.1.1.10
-+++ main.c	15 Sep 2006 13:21:30 -0000
-@@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE
- THIS SOFTWARE.
- ****************************************************************/
- 
--const char	*version = "version 20070501";
-+const char	*version = "version 20070501 (FreeBSD)";
- 
- #define DEBUG
- #include 
-@@ -58,6 +58,7 @@ int main(int argc, char *argv[])
- 	const char *fs = NULL;
- 
- 	setlocale(LC_CTYPE, "");
-+	setlocale(LC_COLLATE, "");
- 	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
- 	cmdname = argv[0];
- 	if (argc == 1) {
-@@ -79,13 +80,18 @@ int main(int argc, char *argv[])
- 				safe = 1;
- 			break;
- 		case 'f':	/* next argument is program filename */
--			argc--;
--			argv++;
--			if (argc <= 1)
--				FATAL("no program filename");
--			if (npfile >= MAX_PFILE - 1)
--				FATAL("too many -f options"); 
--			pfile[npfile++] = argv[1];
-+			if (argv[1][2] != 0) {	/* arg is -fsomething */
-+				if (npfile >= MAX_PFILE - 1)
-+					FATAL("too many -f options"); 
-+				pfile[npfile++] = &argv[1][2];
-+			} else {		/* arg is -f something */
-+				argc--; argv++;
-+				if (argc <= 1)
-+					FATAL("no program filename");
-+				if (npfile >= MAX_PFILE - 1)
-+					FATAL("too many -f options"); 
-+				pfile[npfile++] = argv[1];
-+			}
- 			break;
- 		case 'F':	/* set field separator */
- 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
-@@ -104,8 +110,14 @@ int main(int argc, char *argv[])
- 				WARNING("field separator FS is empty");
- 			break;
- 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
--			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
--				setclvar(argv[1]);
-+			if (argv[1][2] != 0) {	/* arg is -vsomething */
-+				if (argv[1][2] != 0)
-+					setclvar(&argv[1][2]);
-+			} else {		/* arg is -v something */
-+				argc--; argv++;
-+				if (argc > 1 && isclvar(argv[1]))
-+					setclvar(argv[1]);
-+			}
- 			break;
- 		case 'm':	/* more memory: -mr=record, -mf=fields */
- 				/* no longer supported */
diff --git a/usr.bin/awk/run.c.diff b/usr.bin/awk/run.c.diff
deleted file mode 100644
index d4912507ee5..00000000000
--- a/usr.bin/awk/run.c.diff
+++ /dev/null
@@ -1,18 +0,0 @@
-$FreeBSD$
-
-Index: run.c
-===================================================================
-RCS file: /home/ncvs/src/contrib/one-true-awk/run.c,v
-retrieving revision 1.1.1.8
-diff -u -p -r1.1.1.8 run.c
---- run.c	16 May 2005 19:11:35 -0000	1.1.1.8
-+++ run.c	16 May 2005 19:12:47 -0000
-@@ -651,7 +651,7 @@ Cell *relop(Node **a, int n)	/* a[0 < a[
- 		j = x->fval - y->fval;
- 		i = j<0? -1: (j>0? 1: 0);
- 	} else {
--		i = strcmp(getsval(x), getsval(y));
-+		i = strcoll(getsval(x), getsval(y));
- 	}
- 	tempfree(x);
- 	tempfree(y);

From 158c24fd61ca9957cd5a4ba5e67e5c71b022cfc9 Mon Sep 17 00:00:00 2001
From: Antoine Brodin 
Date: Fri, 15 Jan 2010 14:24:32 +0000
Subject: [PATCH 1138/2592] MFC r200440 to stable/8:   Install firmware(9)
 examples.

---
 etc/mtree/BSD.usr.dist  | 6 ++++++
 share/examples/Makefile | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist
index 054ba9ceb22..44a9aad5ab6 100644
--- a/etc/mtree/BSD.usr.dist
+++ b/etc/mtree/BSD.usr.dist
@@ -230,6 +230,12 @@
                 ..
                 dyn_sysctl
                 ..
+                firmware
+                    fwconsumer
+                    ..
+                    fwimage
+                    ..
+                ..
                 syscall
                     module
                     ..
diff --git a/share/examples/Makefile b/share/examples/Makefile
index b5e2ab3ac0a..3d28511ff2f 100644
--- a/share/examples/Makefile
+++ b/share/examples/Makefile
@@ -88,6 +88,12 @@ XFILES=	BSD_daemon/FreeBSD.pfa \
 	kld/dyn_sysctl/Makefile \
 	kld/dyn_sysctl/README \
 	kld/dyn_sysctl/dyn_sysctl.c \
+	kld/firmware/Makefile \
+	kld/firmware/README \
+	kld/firmware/fwconsumer/Makefile \
+	kld/firmware/fwconsumer/fw_consumer.c \
+	kld/firmware/fwimage/Makefile \
+	kld/firmware/fwimage/firmware.img \
 	kld/syscall/Makefile \
 	kld/syscall/module/Makefile \
 	kld/syscall/module/syscall.c \

From e6af3b7bb837cf418226de51649d5158ec656131 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 15:27:17 +0000
Subject: [PATCH 1139/2592] MFC: r200945

- Consistently wrap debugging in NETIF_DEBUG. This basically merges
  NetBSD rev 1.19.
- Make the functions match their prototypes regarding static.
---
 sys/boot/common/dev_net.c | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/sys/boot/common/dev_net.c b/sys/boot/common/dev_net.c
index 5dc1dc33fe4..0101ce1f825 100644
--- a/sys/boot/common/dev_net.c
+++ b/sys/boot/common/dev_net.c
@@ -76,7 +76,9 @@ __FBSDID("$FreeBSD$");
 #include "dev_net.h"
 #include "bootstrap.h"
 
+#ifdef	NETIF_DEBUG
 int debug = 0;
+#endif
 
 static int netdev_sock = -1;
 static int netdev_opens;
@@ -100,7 +102,7 @@ struct devsw netdev = {
 	net_print
 };
 
-int
+static int
 net_init(void)
 {
 
@@ -112,7 +114,7 @@ net_init(void)
  * This opens the low-level device and sets f->f_devdata.
  * This is declared with variable arguments...
  */
-int
+static int
 net_open(struct open_file *f, ...)
 {
 	va_list args;
@@ -132,8 +134,10 @@ net_open(struct open_file *f, ...)
 				printf("net_open: netif_open() failed\n");
 				return (ENXIO);
 			}
+#ifdef	NETIF_DEBUG
 			if (debug)
-			printf("net_open: netif_open() succeeded\n");
+				printf("net_open: netif_open() succeeded\n");
+#endif
 		}
 		if (rootip.s_addr == 0) {
 			/* Get root IP address, and path, etc. */
@@ -154,7 +158,7 @@ net_open(struct open_file *f, ...)
 	return (error);
 }
 
-int
+static int
 net_close(struct open_file *f)
 {
 #ifdef	NETIF_DEBUG
@@ -173,15 +177,17 @@ net_close(struct open_file *f)
 		return(0);
 	rootip.s_addr = 0;
 	if (netdev_sock >= 0) {
+#ifdef	NETIF_DEBUG
 		if (debug)
 			printf("net_close: calling netif_close()\n");
+#endif
 		netif_close(netdev_sock);
 		netdev_sock = -1;
 	}
 	return (0);
 }
 
-int
+static int
 net_strategy()
 {
 
@@ -227,8 +233,10 @@ net_getparams(int sock)
 		bootp(sock, BOOTP_NONE);
 	if (myip.s_addr != 0)
 		goto exit;
+#ifdef	NETIF_DEBUG
 	if (debug)
 		printf("net_open: BOOTP failed, trying RARP/RPC...\n");
+#endif
 #endif
 
 	/*
@@ -246,8 +254,10 @@ net_getparams(int sock)
 		printf("net_open: bootparam/whoami RPC failed\n");
 		return (EIO);
 	}
+#ifdef	NETIF_DEBUG
 	if (debug)
 		printf("net_open: client name: %s\n", hostname);
+#endif
 
 	/*
 	 * Ignore the gateway from whoami (unreliable).
@@ -261,11 +271,15 @@ net_getparams(int sock)
 	}
 	if (smask) {
 		netmask = smask;
+#ifdef	NETIF_DEBUG
 		if (debug)
-		printf("net_open: subnet mask: %s\n", intoa(netmask));
+			printf("net_open: subnet mask: %s\n", intoa(netmask));
+#endif
 	}
+#ifdef	NETIF_DEBUG
 	if (gateip.s_addr && debug)
 		printf("net_open: net gateway: %s\n", inet_ntoa(gateip));
+#endif
 
 	/* Get the root server and pathname. */
 	if (bp_getfile(sock, "root", &rootip, rootpath)) {
@@ -288,10 +302,12 @@ exit:
 		bcopy(&rootpath[i], &temp[0], strlen(&rootpath[i])+1);
 		bcopy(&temp[0], &rootpath[0], strlen(&rootpath[i])+1);
 	}
+#ifdef	NETIF_DEBUG
 	if (debug) {
 		printf("net_open: server addr: %s\n", inet_ntoa(rootip));
 		printf("net_open: server path: %s\n", rootpath);
 	}
+#endif
 
 	d = socktodesc(sock);
 	sprintf(temp, "%6D", d->myea, ":");

From 95915f9fa666945b5606032c15a6efcc22899ad4 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 15:28:57 +0000
Subject: [PATCH 1140/2592] MFC: r200946

Execute the cleanup handlers before jumping to the kernel just
like the other architectures do.
---
 sys/boot/sparc64/loader/main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c
index a9f641ea129..604e792445d 100644
--- a/sys/boot/sparc64/loader/main.c
+++ b/sys/boot/sparc64/loader/main.c
@@ -386,6 +386,8 @@ __elfN(exec)(struct preloaded_file *fp)
 	pmap_print_tlb_sun4u();
 #endif
 
+	dev_cleanup();
+
 	entry = e->e_entry;
 
 	OF_release((void *)heapva, HEAPSZ);

From 9d65a8f8343f0704340b8dddedc8b6a486280e49 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 15:36:12 +0000
Subject: [PATCH 1141/2592] MFC: r200947

Add missing locking in intr_bind().
---
 sys/sparc64/sparc64/intr_machdep.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/sys/sparc64/sparc64/intr_machdep.c b/sys/sparc64/sparc64/intr_machdep.c
index d0174b93198..f47ad0eed1a 100644
--- a/sys/sparc64/sparc64/intr_machdep.c
+++ b/sys/sparc64/sparc64/intr_machdep.c
@@ -450,13 +450,19 @@ int
 intr_bind(int vec, u_char cpu)
 {
 	struct intr_vector *iv;
+	int error;
 
 	if (vec < 0 || vec >= IV_MAX)
 		return (EINVAL);
+	sx_xlock(&intr_table_lock);
 	iv = &intr_vectors[vec];
-	if (iv == NULL)
+	if (iv == NULL) {
+		sx_xunlock(&intr_table_lock);
 		return (EINVAL);
-	return (intr_event_bind(iv->iv_event, cpu));
+	}
+	error = intr_event_bind(iv->iv_event, cpu);
+	sx_xunlock(&intr_table_lock);
+	return (error);
 }
 
 /*

From 435ada6626ec9b3ca867126c063f99c101428f84 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 15:38:49 +0000
Subject: [PATCH 1142/2592] - Hook up the default implementations of the
 MSI/MSI-X pcib_if methods   so requests may bubble up to a host-PCI bridge
 driver. - Distinguish between PCI and PCIe bridges in the device description 
  so it's a bit easier to follow what hangs off of what in the dmesg.  
 Unfortunately we can't also tell PCI and PCI-X apart based on the  
 information provided in the OFW device tree. - Add quirk handling for the ALi
 M5249 found in Fire-based machines   which are used as a PCIe-PCIe bridge
 there. These are obviously   subtractive decoding as as they have a PCI-ISA
 bridge on their   secondary side (and likewise don't include the ISA I/O
 range in   their bridge decode) but don't indicate this via the class code.  
 Given that this quirk isn't likely to apply to all ALi M5249 and   I have no
 datasheet for these chips so I could implement a check   using the chip
 specific bits enabling subtractive decoding this   quirk handling is added to
 the MD code rather than the MI one.

---
 sys/sparc64/pci/ofw_pcib.c | 41 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/sys/sparc64/pci/ofw_pcib.c b/sys/sparc64/pci/ofw_pcib.c
index 1988561ab84..c18d7c0e349 100644
--- a/sys/sparc64/pci/ofw_pcib.c
+++ b/sys/sparc64/pci/ofw_pcib.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2000 Michael Smith 
  * Copyright (c) 2000 BSDi
  * Copyright (c) 2001 - 2003 Thomas Moestl 
+ * Copyright (c) 2009 by Marius Strobl 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,8 +38,9 @@ __FBSDID("$FreeBSD$");
 #include "opt_ofw_pci.h"
 
 #include 
-#include 
 #include 
+#include 
+#include 
 #include 
 
 #include 
@@ -82,6 +84,11 @@ static device_method_t ofw_pcib_methods[] = {
 	DEVMETHOD(pcib_read_config,	pcib_read_config),
 	DEVMETHOD(pcib_write_config,	pcib_write_config),
 	DEVMETHOD(pcib_route_interrupt,	ofw_pcib_gen_route_interrupt),
+	DEVMETHOD(pcib_alloc_msi,	pcib_alloc_msi),
+	DEVMETHOD(pcib_release_msi,	pcib_release_msi),
+	DEVMETHOD(pcib_alloc_msix,	pcib_alloc_msix),
+	DEVMETHOD(pcib_release_msix,	pcib_release_msix),
+	DEVMETHOD(pcib_map_msi,		pcib_map_msi),
 
 	/* ofw_bus interface */
 	DEVMETHOD(ofw_bus_get_node,	ofw_pcib_gen_get_node),
@@ -100,19 +107,49 @@ MODULE_DEPEND(ofw_pcib, pci, 1, 1, 1);
 static int
 ofw_pcib_probe(device_t dev)
 {
+	char desc[sizeof("OFW PCIe-PCIe bridge")];
+	const char *dtype, *pbdtype;
+
+#define	ISDTYPE(dtype, type)						\
+	(((dtype) != NULL) && strcmp((dtype), (type)) == 0)
 
 	if ((pci_get_class(dev) == PCIC_BRIDGE) &&
 	    (pci_get_subclass(dev) == PCIS_BRIDGE_PCI) &&
 	    ofw_bus_get_node(dev) != 0) {
-		device_set_desc(dev, "OFW PCI-PCI bridge");
+		dtype = ofw_bus_get_type(dev);
+		pbdtype = ofw_bus_get_type(device_get_parent(
+		    device_get_parent(dev)));
+		snprintf(desc, sizeof(desc), "OFW PCI%s-PCI%s bridge",
+		    ISDTYPE(pbdtype, OFW_TYPE_PCIE) ? "e" : "",
+		    ISDTYPE(dtype, OFW_TYPE_PCIE) ? "e" : "");
+		device_set_desc_copy(dev, desc);
 		return (0);
 	}
+
+#undef ISDTYPE
+
 	return (ENXIO);
 }
 
 static int
 ofw_pcib_attach(device_t dev)
 {
+	struct ofw_pcib_gen_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	/* Quirk handling */
+	switch (pci_get_devid(dev)) {
+	/*
+	 * The ALi M5249 found in Fire-based machines by definition must me
+	 * subtractive as they have a ISA bridge on their secondary side but
+	 * don't indicate this in the class code although the ISA I/O range
+	 * isn't included in their bridge decode.
+	 */
+	case 0x524910b9:
+		sc->ops_pcib_sc.flags |= PCIB_SUBTRACTIVE;
+		break;
+	}
 
 	ofw_pcib_gen_setup(dev);
 	pcib_attach_common(dev);

From 3425abf549597bdaa2d94d3f8f1d24391a5b1f3a Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 15:40:44 +0000
Subject: [PATCH 1143/2592] MFC: r201003

Style changes
---
 sys/dev/mk48txx/mk48txx.c    |  20 +++---
 sys/dev/mk48txx/mk48txxreg.h | 120 +++++++++++++++++------------------
 sys/dev/mk48txx/mk48txxvar.h |  16 ++---
 3 files changed, 78 insertions(+), 78 deletions(-)

diff --git a/sys/dev/mk48txx/mk48txx.c b/sys/dev/mk48txx/mk48txx.c
index 71ab8f518df..6f8b5409362 100644
--- a/sys/dev/mk48txx/mk48txx.c
+++ b/sys/dev/mk48txx/mk48txx.c
@@ -40,7 +40,7 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * Mostek MK48T02, MK48T08, MK48T18, MK48T59 time-of-day chip subroutines.
+ * Mostek MK48T02, MK48T08, MK48T18, MK48T59 time-of-day chip subroutines
  */
 
 #include 
@@ -59,17 +59,17 @@ __FBSDID("$FreeBSD$");
 
 #include "clock_if.h"
 
-static uint8_t	mk48txx_def_nvrd(device_t, int);
-static void	mk48txx_def_nvwr(device_t, int, uint8_t);
-static void	mk48txx_watchdog(void *, u_int, int *);
+static uint8_t	mk48txx_def_nvrd(device_t dev, int off);
+static void	mk48txx_def_nvwr(device_t dev, int off, uint8_t v);
+static void	mk48txx_watchdog(void *arg, u_int cmd, int *error);
 
-struct {
+static const struct {
 	const char *name;
 	bus_size_t nvramsz;
 	bus_size_t clkoff;
-	int flags;
-#define MK48TXX_EXT_REGISTERS	1	/* Has extended register set */
-} mk48txx_models[] = {
+	u_int flags;
+#define	MK48TXX_EXT_REGISTERS	1	/* Has extended register set. */
+} const mk48txx_models[] = {
 	{ "mk48t02", MK48T02_CLKSZ, MK48T02_CLKOFF, 0 },
 	{ "mk48t08", MK48T08_CLKSZ, MK48T08_CLKOFF, 0 },
 	{ "mk48t18", MK48T18_CLKSZ, MK48T18_CLKOFF, 0 },
@@ -112,7 +112,7 @@ mk48txx_attach(device_t dev)
 
 	if (mk48txx_models[i].flags & MK48TXX_EXT_REGISTERS) {
 		mtx_lock(&sc->sc_mtx);
-	    	if ((*sc->sc_nvrd)(dev, sc->sc_clkoffset + MK48TXX_FLAGS) &
+		if ((*sc->sc_nvrd)(dev, sc->sc_clkoffset + MK48TXX_FLAGS) &
 		    MK48TXX_FLAGS_BL) {
 			mtx_unlock(&sc->sc_mtx);
 			device_printf(dev, "%s: battery low\n", __func__);
@@ -140,7 +140,7 @@ mk48txx_attach(device_t dev)
 		}
 	}
 
-	clock_register(dev, 1000000);	/* 1 second resolution. */
+	clock_register(dev, 1000000);	/* 1 second resolution */
 
 	if ((sc->sc_flag & MK48TXX_WDOG_REGISTER) &&
 	    (mk48txx_models[i].flags & MK48TXX_EXT_REGISTERS)) {
diff --git a/sys/dev/mk48txx/mk48txxreg.h b/sys/dev/mk48txx/mk48txxreg.h
index 25b9cb39208..274ffbf65f0 100644
--- a/sys/dev/mk48txx/mk48txxreg.h
+++ b/sys/dev/mk48txx/mk48txxreg.h
@@ -59,23 +59,23 @@
  * The first bank of eight registers at offset (nvramsz - 16) is
  * available only on recenter (which?) MK48Txx models.
  */
-#define MK48TXX_FLAGS	0	/* flags register */
-#define MK48TXX_UNUSED	1	/* unused */
-#define MK48TXX_ASEC	2	/* alarm seconds (0..59; BCD) */
-#define MK48TXX_AMIN	3	/* alarm minutes (0..59; BCD) */
-#define MK48TXX_AHOUR	4	/* alarm hours (0..23; BCD) */
-#define MK48TXX_ADAY	5	/* alarm day in month (1..31; BCD) */
-#define MK48TXX_INTR	6	/* interrupts register */
-#define MK48TXX_WDOG	7	/* watchdog register */
+#define	MK48TXX_FLAGS	0	/* flags register */
+#define	MK48TXX_UNUSED	1	/* unused */
+#define	MK48TXX_ASEC	2	/* alarm seconds (0..59; BCD) */
+#define	MK48TXX_AMIN	3	/* alarm minutes (0..59; BCD) */
+#define	MK48TXX_AHOUR	4	/* alarm hours (0..23; BCD) */
+#define	MK48TXX_ADAY	5	/* alarm day in month (1..31; BCD) */
+#define	MK48TXX_INTR	6	/* interrupts register */
+#define	MK48TXX_WDOG	7	/* watchdog register */
 
-#define MK48TXX_ICSR	8	/* control register */
-#define MK48TXX_ISEC	9	/* seconds (0..59; BCD) */
-#define MK48TXX_IMIN	10	/* minutes (0..59; BCD) */
-#define MK48TXX_IHOUR	11	/* hours (0..23; BCD) */
-#define MK48TXX_IWDAY	12	/* weekday (1..7) */
-#define MK48TXX_IDAY	13	/* day in month (1..31; BCD) */
-#define MK48TXX_IMON	14	/* month (1..12; BCD) */
-#define MK48TXX_IYEAR	15	/* year (0..99; BCD) */
+#define	MK48TXX_ICSR	8	/* control register */
+#define	MK48TXX_ISEC	9	/* seconds (0..59; BCD) */
+#define	MK48TXX_IMIN	10	/* minutes (0..59; BCD) */
+#define	MK48TXX_IHOUR	11	/* hours (0..23; BCD) */
+#define	MK48TXX_IWDAY	12	/* weekday (1..7) */
+#define	MK48TXX_IDAY	13	/* day in month (1..31; BCD) */
+#define	MK48TXX_IMON	14	/* month (1..12; BCD) */
+#define	MK48TXX_IYEAR	15	/* year (0..99; BCD) */
 
 /*
  * Note that some of the bits below that are not in the first eight
@@ -84,80 +84,80 @@
  */
 
 /* Bits in the flags register (extended only) */
-#define MK48TXX_FLAGS_BL	0x10	/* battery low (read only) */
-#define MK48TXX_FLAGS_AF	0x40	/* alarm flag (read only) */
-#define MK48TXX_FLAGS_WDF	0x80	/* watchdog flag (read only) */
+#define	MK48TXX_FLAGS_BL	0x10	/* battery low (read only) */
+#define	MK48TXX_FLAGS_AF	0x40	/* alarm flag (read only) */
+#define	MK48TXX_FLAGS_WDF	0x80	/* watchdog flag (read only) */
 
 /* Bits in the alarm seconds register (extended only) */
-#define MK48TXX_ASEC_MASK	0x7f	/* mask for alarm seconds */
-#define MK48TXX_ASEC_RPT1	0x80	/* alarm repeat mode bit 1 */
+#define	MK48TXX_ASEC_MASK	0x7f	/* mask for alarm seconds */
+#define	MK48TXX_ASEC_RPT1	0x80	/* alarm repeat mode bit 1 */
 
 /* Bits in the alarm minutes register (extended only) */
-#define MK48TXX_AMIN_MASK	0x7f	/* mask for alarm minutes */
-#define MK48TXX_AMIN_RPT2	0x80	/* alarm repeat mode bit 2 */
+#define	MK48TXX_AMIN_MASK	0x7f	/* mask for alarm minutes */
+#define	MK48TXX_AMIN_RPT2	0x80	/* alarm repeat mode bit 2 */
 
 /* Bits in the alarm hours register (extended only) */
-#define MK48TXX_AHOUR_MASK	0x3f	/* mask for alarm hours */
-#define MK48TXX_AHOUR_RPT3	0x80	/* alarm repeat mode bit 3 */
+#define	MK48TXX_AHOUR_MASK	0x3f	/* mask for alarm hours */
+#define	MK48TXX_AHOUR_RPT3	0x80	/* alarm repeat mode bit 3 */
 
 /* Bits in the alarm day in month register (extended only) */
-#define MK48TXX_ADAY_MASK	0x3f	/* mask for alarm day in month */
-#define MK48TXX_ADAY_RPT4	0x80	/* alarm repeat mode bit 4 */
+#define	MK48TXX_ADAY_MASK	0x3f	/* mask for alarm day in month */
+#define	MK48TXX_ADAY_RPT4	0x80	/* alarm repeat mode bit 4 */
 
 /* Bits in the interrupts register (extended only) */
-#define MK48TXX_INTR_ABE	0x20	/* alarm in battery back-up mode */
-#define MK48TXX_INTR_AFE	0x80	/* alarm flag enable */
+#define	MK48TXX_INTR_ABE	0x20	/* alarm in battery back-up mode */
+#define	MK48TXX_INTR_AFE	0x80	/* alarm flag enable */
 
 /* Bits in the watchdog register (extended only) */
-#define MK48TXX_WDOG_RB_1_16	0x00	/* watchdog resolution 1/16 second */
-#define MK48TXX_WDOG_RB_1_4	0x01	/* watchdog resolution 1/4 second */
-#define MK48TXX_WDOG_RB_1	0x02	/* watchdog resolution 1 second */
-#define MK48TXX_WDOG_RB_4	0x03	/* watchdog resolution 4 seconds */
-#define MK48TXX_WDOG_BMB_MASK	0x7c	/* mask for watchdog multiplier */
-#define MK48TXX_WDOG_BMB_SHIFT	2	/* shift for watchdog multiplier */
-#define MK48TXX_WDOG_WDS	0x80	/* watchdog steering bit */
+#define	MK48TXX_WDOG_RB_1_16	0x00	/* watchdog resolution 1/16 second */
+#define	MK48TXX_WDOG_RB_1_4	0x01	/* watchdog resolution 1/4 second */
+#define	MK48TXX_WDOG_RB_1	0x02	/* watchdog resolution 1 second */
+#define	MK48TXX_WDOG_RB_4	0x03	/* watchdog resolution 4 seconds */
+#define	MK48TXX_WDOG_BMB_MASK	0x7c	/* mask for watchdog multiplier */
+#define	MK48TXX_WDOG_BMB_SHIFT	2	/* shift for watchdog multiplier */
+#define	MK48TXX_WDOG_WDS	0x80	/* watchdog steering bit */
 
 /* Bits in the control register */
-#define MK48TXX_CSR_CALIB_MASK	0x1f	/* mask for calibration step width */
-#define MK48TXX_CSR_SIGN	0x20	/* sign of above calibration witdh */
-#define MK48TXX_CSR_READ	0x40	/* want to read (freeze clock) */
-#define MK48TXX_CSR_WRITE	0x80	/* want to write */
+#define	MK48TXX_CSR_CALIB_MASK	0x1f	/* mask for calibration step width */
+#define	MK48TXX_CSR_SIGN	0x20	/* sign of above calibration witdh */
+#define	MK48TXX_CSR_READ	0x40	/* want to read (freeze clock) */
+#define	MK48TXX_CSR_WRITE	0x80	/* want to write */
 
 /* Bits in the seconds register */
-#define MK48TXX_SEC_MASK	0x7f	/* mask for seconds */
-#define MK48TXX_SEC_ST		0x80	/* stop oscillator */
+#define	MK48TXX_SEC_MASK	0x7f	/* mask for seconds */
+#define	MK48TXX_SEC_ST		0x80	/* stop oscillator */
 
 /* Bits in the minutes register */
-#define MK48TXX_MIN_MASK	0x7f	/* mask for minutes */
+#define	MK48TXX_MIN_MASK	0x7f	/* mask for minutes */
 
 /* Bits in the hours register */
-#define MK48TXX_HOUR_MASK	0x3f	/* mask for hours */
+#define	MK48TXX_HOUR_MASK	0x3f	/* mask for hours */
 
 /* Bits in the century/weekday register */
-#define MK48TXX_WDAY_MASK	0x07	/* mask for weekday */
-#define MK48TXX_WDAY_CB		0x10	/* century bit (extended only) */
-#define MK48TXX_WDAY_CB_SHIFT	4	/* shift for century bit */
-#define MK48TXX_WDAY_CEB	0x20	/* century enable bit (extended only) */
-#define MK48TXX_WDAY_FT		0x40	/* frequency test */
+#define	MK48TXX_WDAY_MASK	0x07	/* mask for weekday */
+#define	MK48TXX_WDAY_CB		0x10	/* century bit (extended only) */
+#define	MK48TXX_WDAY_CB_SHIFT	4	/* shift for century bit */
+#define	MK48TXX_WDAY_CEB	0x20	/* century enable bit (extended only) */
+#define	MK48TXX_WDAY_FT		0x40	/* frequency test */
 
 /* Bits in the day in month register */
-#define MK48TXX_DAY_MASK	0x3f	/* mask for day in month */
+#define	MK48TXX_DAY_MASK	0x3f	/* mask for day in month */
 
 /* Bits in the month register */
-#define MK48TXX_MON_MASK	0x1f	/* mask for month */
+#define	MK48TXX_MON_MASK	0x1f	/* mask for month */
 
 /* Bits in the year register */
-#define MK48TXX_YEAR_MASK	0xff	/* mask for year */
+#define	MK48TXX_YEAR_MASK	0xff	/* mask for year */
 
 /* Model specific NVRAM sizes and clock offsets */
-#define MK48T02_CLKSZ		2048
-#define MK48T02_CLKOFF		0x7f0
+#define	MK48T02_CLKSZ		2048
+#define	MK48T02_CLKOFF		0x7f0
 
-#define MK48T08_CLKSZ		8192
-#define MK48T08_CLKOFF		0x1ff0
+#define	MK48T08_CLKSZ		8192
+#define	MK48T08_CLKOFF		0x1ff0
 
-#define MK48T18_CLKSZ		8192
-#define MK48T18_CLKOFF		0x1ff0
+#define	MK48T18_CLKSZ		8192
+#define	MK48T18_CLKOFF		0x1ff0
 
-#define MK48T59_CLKSZ		8192
-#define MK48T59_CLKOFF		0x1ff0
+#define	MK48T59_CLKSZ		8192
+#define	MK48T59_CLKOFF		0x1ff0
diff --git a/sys/dev/mk48txx/mk48txxvar.h b/sys/dev/mk48txx/mk48txxvar.h
index f7c3d319506..b72e29dd902 100644
--- a/sys/dev/mk48txx/mk48txxvar.h
+++ b/sys/dev/mk48txx/mk48txxvar.h
@@ -38,8 +38,8 @@
  * $FreeBSD$
  */
 
-typedef uint8_t (*mk48txx_nvrd_t)(device_t, int);
-typedef void (*mk48txx_nvwr_t)(device_t, int, uint8_t);
+typedef uint8_t (*mk48txx_nvrd_t)(device_t dev, int off);
+typedef void (*mk48txx_nvwr_t)(device_t dev, int off, uint8_t v);
 
 struct mk48txx_softc {
 	bus_space_tag_t		sc_bst;	/* bus space tag */
@@ -53,17 +53,17 @@ struct mk48txx_softc {
 	bus_size_t	sc_clkoffset;	/* Offset in NVRAM to clock bits */
 	u_int		sc_year0;	/* year counter offset */
 	u_int		sc_flag;	/* MD flags */
-#define MK48TXX_NO_CENT_ADJUST	0x0001	/* don't manually adjust century */
-#define MK48TXX_WDOG_REGISTER	0x0002	/* register watchdog */
-#define MK48TXX_WDOG_ENABLE_WDS	0x0004	/* enable watchdog steering bit */
+#define	MK48TXX_NO_CENT_ADJUST	0x0001	/* don't manually adjust century */
+#define	MK48TXX_WDOG_REGISTER	0x0002	/* register watchdog */
+#define	MK48TXX_WDOG_ENABLE_WDS	0x0004	/* enable watchdog steering bit */
 
 	mk48txx_nvrd_t	sc_nvrd;	/* NVRAM/RTC read function */
 	mk48txx_nvwr_t	sc_nvwr;	/* NVRAM/RTC write function */
 };
 
 /* Chip attach function */
-int mk48txx_attach(device_t);
+int mk48txx_attach(device_t dev);
 
 /* Methods for the clock interface */
-int mk48txx_gettime(device_t, struct timespec *);
-int mk48txx_settime(device_t, struct timespec *);
+int mk48txx_gettime(device_t dev, struct timespec *ts);
+int mk48txx_settime(device_t dev, struct timespec *ts);

From 1051ec0b8a6e797562ea0f826a06083534f8eaca Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 15:42:14 +0000
Subject: [PATCH 1144/2592] MFC: r201004

Remove clause 3 and 4 from TNF licenses.

Obtained from:	NetBSD
---
 sys/dev/mk48txx/mk48txx.c    | 9 +--------
 sys/dev/mk48txx/mk48txxreg.h | 9 +--------
 sys/dev/mk48txx/mk48txxvar.h | 9 +--------
 3 files changed, 3 insertions(+), 24 deletions(-)

diff --git a/sys/dev/mk48txx/mk48txx.c b/sys/dev/mk48txx/mk48txx.c
index 6f8b5409362..ec8a1e9b175 100644
--- a/sys/dev/mk48txx/mk48txx.c
+++ b/sys/dev/mk48txx/mk48txx.c
@@ -13,13 +13,6 @@
  * 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
@@ -33,7 +26,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- *	from: NetBSD: mk48txx.c,v 1.15 2004/07/05 09:24:31 pk Exp
+ *	$NetBSD: mk48txx.c,v 1.25 2008/04/28 20:23:50 martin Exp $
  */
 
 #include 
diff --git a/sys/dev/mk48txx/mk48txxreg.h b/sys/dev/mk48txx/mk48txxreg.h
index 274ffbf65f0..bae6ae5f51b 100644
--- a/sys/dev/mk48txx/mk48txxreg.h
+++ b/sys/dev/mk48txx/mk48txxreg.h
@@ -13,13 +13,6 @@
  * 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
@@ -33,7 +26,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- *	from: NetBSD: mk48txxreg.h,v 1.7 2003/11/01 22:41:42 tsutsui Exp
+ *	$NetBSD: mk48txxreg.h,v 1.10 2008/04/28 20:23:50 martin Exp $
  *
  * $FreeBSD$
  */
diff --git a/sys/dev/mk48txx/mk48txxvar.h b/sys/dev/mk48txx/mk48txxvar.h
index b72e29dd902..5bb92da2a63 100644
--- a/sys/dev/mk48txx/mk48txxvar.h
+++ b/sys/dev/mk48txx/mk48txxvar.h
@@ -13,13 +13,6 @@
  * 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
@@ -33,7 +26,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- *	from: NetBSD: mk48txxvar.h,v 1.1 2003/11/01 22:41:42 tsutsui Exp
+ *	$NetBSD: mk48txxvar.h,v 1.6 2008/04/28 20:23:50 martin Exp $
  *
  * $FreeBSD$
  */

From 2a2cbae7cb6b976e14dce0bcf94dcb44e0839eb1 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 15:47:31 +0000
Subject: [PATCH 1145/2592] MFC: r201005, r201371

- Take advantage of bus_{read,write}_*(9).
- Set dow = -1 in mk48txx_gettime() because some drivers (for example
  the NetBSD and OpenBSD mk48txx(4)) don't set it correctly.
---
 sys/dev/mk48txx/mk48txx.c    | 13 +++++++++++--
 sys/dev/mk48txx/mk48txxvar.h |  3 +--
 sys/sparc64/sparc64/eeprom.c | 12 +++++-------
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/sys/dev/mk48txx/mk48txx.c b/sys/dev/mk48txx/mk48txx.c
index ec8a1e9b175..9742e82748c 100644
--- a/sys/dev/mk48txx/mk48txx.c
+++ b/sys/dev/mk48txx/mk48txx.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -175,8 +176,16 @@ mk48txx_gettime(device_t dev, struct timespec *ts)
 	ct.min = FROMBCD(FROMREG(MK48TXX_IMIN, MK48TXX_MIN_MASK));
 	ct.hour = FROMBCD(FROMREG(MK48TXX_IHOUR, MK48TXX_HOUR_MASK));
 	ct.day = FROMBCD(FROMREG(MK48TXX_IDAY, MK48TXX_DAY_MASK));
+#if 0
 	/* Map dow from 1 - 7 to 0 - 6; FROMBCD() isn't necessary here. */
 	ct.dow = FROMREG(MK48TXX_IWDAY, MK48TXX_WDAY_MASK) - 1;
+#else
+	/*
+	 * Set dow = -1 because some drivers (for example the NetBSD and
+	 * OpenBSD mk48txx(4)) don't set it correctly.
+	 */
+	ct.dow = -1;
+#endif
 	ct.mon = FROMBCD(FROMREG(MK48TXX_IMON, MK48TXX_MON_MASK));
 	year = FROMBCD(FROMREG(MK48TXX_IYEAR, MK48TXX_YEAR_MASK));
 	year += sc->sc_year0;
@@ -266,7 +275,7 @@ mk48txx_def_nvrd(device_t dev, int off)
 	struct mk48txx_softc *sc;
 
 	sc = device_get_softc(dev);
-	return (bus_space_read_1(sc->sc_bst, sc->sc_bsh, off));
+	return (bus_read_1(sc->sc_res, off));
 }
 
 static void
@@ -275,7 +284,7 @@ mk48txx_def_nvwr(device_t dev, int off, uint8_t v)
 	struct mk48txx_softc *sc;
 
 	sc = device_get_softc(dev);
-	bus_space_write_1(sc->sc_bst, sc->sc_bsh, off, v);
+	bus_write_1(sc->sc_res, off, v);
 }
 
 static void
diff --git a/sys/dev/mk48txx/mk48txxvar.h b/sys/dev/mk48txx/mk48txxvar.h
index 5bb92da2a63..9706d8dbc94 100644
--- a/sys/dev/mk48txx/mk48txxvar.h
+++ b/sys/dev/mk48txx/mk48txxvar.h
@@ -35,8 +35,7 @@ typedef uint8_t (*mk48txx_nvrd_t)(device_t dev, int off);
 typedef void (*mk48txx_nvwr_t)(device_t dev, int off, uint8_t v);
 
 struct mk48txx_softc {
-	bus_space_tag_t		sc_bst;	/* bus space tag */
-	bus_space_handle_t	sc_bsh;	/* bus space handle */
+	struct resource		*sc_res;/* bus resource */
 
 	struct mtx		sc_mtx;	/* hardware mutex */
 	eventhandler_tag	sc_wet;	/* watchdog event handler tag */
diff --git a/sys/sparc64/sparc64/eeprom.c b/sys/sparc64/sparc64/eeprom.c
index 223b96c93c5..da9909a5d30 100644
--- a/sys/sparc64/sparc64/eeprom.c
+++ b/sys/sparc64/sparc64/eeprom.c
@@ -107,7 +107,7 @@ DRIVER_MODULE(eeprom, sbus, eeprom_driver, eeprom_devclass, 0, 0);
 static int
 eeprom_probe(device_t dev)
 {
- 
+
 	if (strcmp("eeprom", ofw_bus_get_name(dev)) == 0) {
 		device_set_desc(dev, "EEPROM/clock");
 		return (0);
@@ -119,7 +119,6 @@ static int
 eeprom_attach(device_t dev)
 {
 	struct mk48txx_softc *sc;
-	struct resource *res;
 	struct timespec ts;
 	int error, rid;
 
@@ -128,14 +127,13 @@ eeprom_attach(device_t dev)
 	mtx_init(&sc->sc_mtx, "eeprom_mtx", NULL, MTX_DEF);
 
 	rid = 0;
-	res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
-	if (res == NULL) {
+	sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_res == NULL) {
 		device_printf(dev, "cannot allocate resources\n");
 		error = ENXIO;
 		goto fail_mtx;
 	}
-	sc->sc_bst = rman_get_bustag(res);
-	sc->sc_bsh = rman_get_bushandle(res);
 
 	if ((sc->sc_model = ofw_bus_get_model(dev)) == NULL) {
 		device_printf(dev, "cannot determine model\n");
@@ -180,7 +178,7 @@ eeprom_attach(device_t dev)
 	return (0);
 
  fail_res:
-	bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
+	bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->sc_res);
  fail_mtx:
 	mtx_destroy(&sc->sc_mtx);
 

From f0152768f7a883b0cf6713d6e09258aba32da363 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 16:21:32 +0000
Subject: [PATCH 1146/2592] MFC: r201007

Add a man page for mk48txx(4).

Requested by:	n_hibma
Obtained from:	NetBSD (original version)
---
 share/man/man4/Makefile  |   1 +
 share/man/man4/mk48txx.4 | 230 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 231 insertions(+)
 create mode 100644 share/man/man4/mk48txx.4

diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 50b707c3284..76006acf6c0 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -198,6 +198,7 @@ MAN=	aac.4 \
 	meteor.4 \
 	mfi.4 \
 	miibus.4 \
+	mk48txx.4 \
 	mld.4 \
 	mlx.4 \
 	mly.4 \
diff --git a/share/man/man4/mk48txx.4 b/share/man/man4/mk48txx.4
new file mode 100644
index 00000000000..5706924bfcf
--- /dev/null
+++ b/share/man/man4/mk48txx.4
@@ -0,0 +1,230 @@
+.\"	$NetBSD: mk48txx.4,v 1.16 2009/04/10 17:14:07 joerg Exp $
+.\"
+.\" Copyright (c) 2000, 2002 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Paul Kranenburg.
+.\"
+.\" 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 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 25, 2009
+.Dt MK48TXX 4
+.Os
+.Sh NAME
+.Nm mk48txx
+.Nd
+.Tn Mostek
+time-of-day clock driver
+.Sh SYNOPSIS
+.In sys/eventhandler.h
+.In sys/lock.h
+.In sys/mutex.h
+.In dev/mk48txx/mk48txxvar.h
+.Pp
+To compile this driver into the kernel,
+place the following line in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device mk48txx"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver is a back-end for several models of
+.Tn Mostek
+time-of-day clock chips.
+It provides access methods to retrieve and set date and time for use with the
+.Dq Li clock
+KOBJ interface.
+.Pp
+To tie an instance of this device to the system, use the
+.Fn mk48txx_attach
+function and the mk48txx_softc structure defined as follows:
+.Pp
+.Ft "int"
+.Fn mk48txx_attach "device_t dev"
+.Pp
+.Bd -literal
+typedef uint8_t (*mk48txx_nvrd_t)(device_t dev, int off);
+typedef void (*mk48txx_nvwr_t)(device_t dev, int off, uint8_t v);
+.Ed
+.Bd -literal
+struct mk48txx_softc {
+	struct resource	sc_res;
+	struct mtx	sc_mtx;
+	eventhandler_tag	sc_wet;
+	const char	*sc_model;
+	bus_size_t	sc_nvramsz;
+	bus_size_t	sc_clkoffset;
+	u_int		sc_year0;
+	u_int		sc_flag;
+	mk48txx_nvrd_t	sc_nvrd;
+	mk48txx_nvwr_t	sc_nvwr;
+};
+.Ed
+.Pp
+.Bl -tag -width indent
+.It Fa sc_res
+The bus resource used for accessing the chip's non-volatile memory
+.Pq including the clock registers ,
+which must be supplied by the front-end when using the default access methods
+.Pq see below .
+Otherwise this member is optional.
+.It Fa sc_mtx
+The hardware mutex used when accessing the chip's non-volatile memory
+.Pq including the clock registers ,
+which must be initialized with
+.Dv MTX_DEF
+by the front-end.
+.It Fa sc_wet
+The event handler tag for the watchdog functionality,
+which is registered by the
+.Fn mk48txx_attach
+function if supported by the chip and specified as part of the
+machine-dependent features
+.Pq see below .
+.It Fa sc_model
+The chip model which this instance should serve.
+This member must be set to one of
+.Dq mk48t02 ,
+.Dq mk48t08 ,
+.Dq mk48t18 ,
+or
+.Dq mk48t59
+by the front-end.
+.It Fa sc_nvramsz
+The size of the non-volatile RAM in the
+.Tn Mostek
+chip,
+which is set by the
+.Fn mk48txx_attach
+function.
+.It Fa sc_clkoffset
+The offset into the control registers of the
+.Tn Mostek
+chip,
+which is set by the the
+.Fn mk48txx_attach
+function.
+.It Fa sc_year0
+The year offset to be used with the
+.Sq year
+counter of the clock,
+which must be set by the front-end.
+This value is generally dependent on the system configuration in which
+the clock device is mounted.
+For instance, on
+.Tn Sun Microsystems
+machines the convention is to have clock's two-digit year represent
+the year since 1968.
+.It Fa sc_flag
+This flag is used to specify machine-dependent features.
+The following flags are supported:
+.Bl -tag -width ".Dv MK48TXX_WDOG_ENABLE_WDS"
+.It Dv MK48TXX_NO_CENT_ADJUST
+If the resulting date retrieved with the
+.Dq Li clock_gettime() method
+would be earlier than January 1, 1970,
+the driver will assume that the chip's year counter actually represents a
+year in the 21st century.
+This behavior can be overridden by setting this flag,
+which causes the
+.Nm
+driver to respect the clock's century bit instead.
+.It Dv MK48TXX_WDOG_REGISTER
+When this flag is set,
+the
+.Nm
+driver will register as a watchdog via the interface defined in
+.Xr 9 watchdog
+if supported by the specific chip model.
+.It Dv MK48TXX_WDOG_ENABLE_WDS
+When this flag is set,
+the
+.Nm
+driver will set the watchdog steering
+.Pq WDS
+bit when enabling the watchdog functionality of the chip.
+enabled
+.Pq see the chip documentation for further information regarding the WDS bit .
+.El
+.It Fa sc_nvread
+.It Fa sc_nvwrite
+These members specify the access methods for reading respectively writing
+clock device registers.
+The default,
+when
+.Dv NULL
+is passed as an access method,
+is to access the chip memory
+.Pq and clock registers
+as if they were direct-mapped using the specified bus resource.
+.Pp
+Otherwise, the driver will call the respective function supplied by the
+front-end to perform the access,
+passing it the offset
+.Va off
+of the chip memory
+.Pq or clock register
+location to be read from or written to, respectively.
+.El
+.Sh HARDWARE
+The following models are supported:
+.Pp
+.Bl -tag -width indent -offset indent -compact
+.It Tn Mostek MK48T02
+.It Tn Mostek MK48T08
+.It Tn Mostek MK48T18
+.It Tn Mostek MK48T59
+.El
+.Sh SEE ALSO
+.Xr intro 4 ,
+.Xr watchdog 9
+.Sh HISTORY
+The
+.Nm mk48txx
+driver appeared in
+.Nx 1.5 .
+The first
+.Fx
+version to include it was
+.Fx 5.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written for
+.Nx
+by
+.An Paul Kranenburg
+.Aq pk@NetBSD.org .
+It was ported to
+.Fx
+by
+.An Thomas Moestl
+.Aq tmm@FreeBSD.org
+and later on improved by
+.An Marius Strobl
+.Aq marius@FreeBSD.org .

From ca3405fdef86afaa09a17562ac91e4ab519df6c5 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 16:25:17 +0000
Subject: [PATCH 1147/2592] MFC: r201007

Correct my e-mail address.
---
 share/man/man4/gem.4 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/share/man/man4/gem.4 b/share/man/man4/gem.4
index 1a6ea4bec0f..314d95f81d0 100644
--- a/share/man/man4/gem.4
+++ b/share/man/man4/gem.4
@@ -33,7 +33,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 14, 2009
+.Dd December 25, 2009
 .Dt GEM 4
 .Os
 .Sh NAME
@@ -150,7 +150,7 @@ by
 .Aq tmm@FreeBSD.org
 and later on improved by
 .An Marius Strobl
-.Aq marus@FreeBSD.org .
+.Aq marius@FreeBSD.org .
 The man page was written by
 .An Thomas Klausner
 .Aq wiz@NetBSD.org .

From b70d4939108af6b2ff3b353fc421c0fa3d275b42 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 16:27:57 +0000
Subject: [PATCH 1148/2592] MFC: r201008

Style changes

Obtained from:	NetBSD (mc146818reg.h)
---
 sys/dev/mc146818/mc146818.c    |  9 +++++++--
 sys/dev/mc146818/mc146818reg.h | 22 +++++++++++-----------
 sys/dev/mc146818/mc146818var.h | 25 +++++++++++++------------
 sys/sparc64/sparc64/rtc.c      |  6 +++---
 4 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/sys/dev/mc146818/mc146818.c b/sys/dev/mc146818/mc146818.c
index ea59d2c3c54..53fe5daf6a8 100644
--- a/sys/dev/mc146818/mc146818.c
+++ b/sys/dev/mc146818/mc146818.c
@@ -94,7 +94,7 @@ mc146818_attach(device_t dev)
 	(*sc->sc_mcwrite)(dev, MC_REGB, sc->sc_regb);
 	mtx_unlock_spin(&sc->sc_mtx);
 
-	clock_register(dev, 1000000);	/* 1 second resolution. */
+	clock_register(dev, 1000000);	/* 1 second resolution */
 
 	return (0);
 }
@@ -116,7 +116,7 @@ mc146818_gettime(device_t dev, struct timespec *ts)
 
 	/*
 	 * If MC_REGA_UIP is 0 we have at least 244us before the next
-	 * update. If it's 1 an update is imminent.
+	 * update.  If it's 1 an update is imminent.
 	 */
 	for (;;) {
 		mtx_lock_spin(&sc->sc_mtx);
@@ -260,6 +260,9 @@ mc146818_def_write(device_t dev, u_int reg, u_int val)
 	bus_space_write_1(sc->sc_bst, sc->sc_bsh, MC_DATA, val);
 }
 
+#undef MC_ADDR
+#undef MC_DATA
+
 /*
  * Looks like it's common even across platforms to store the century at
  * 0x32 in the NVRAM of the mc146818.
@@ -283,3 +286,5 @@ mc146818_def_setcent(device_t dev, u_int cent)
 	sc = device_get_softc(dev);
 	(*sc->sc_mcwrite)(dev, MC_CENT, cent);
 }
+
+#undef MC_CENT
diff --git a/sys/dev/mc146818/mc146818reg.h b/sys/dev/mc146818/mc146818reg.h
index 7e17aa248d3..811187e4b7d 100644
--- a/sys/dev/mc146818/mc146818reg.h
+++ b/sys/dev/mc146818/mc146818reg.h
@@ -1,17 +1,17 @@
 /*-
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
- * 
+ *
  * Permission to use, copy, modify and distribute this software and
  * its documentation is hereby granted, provided that both the copyright
  * notice and this permission notice appear in all copies of the
  * software, derivative works or modified versions, and any portions
  * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
+ *
  * Carnegie Mellon requests users of this software to return to
  *
  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
@@ -22,7 +22,7 @@
  * any improvements or extensions that they make and grant Carnegie the
  * rights to redistribute these changes.
  *
- *	from: NetBSD: mc146818reg.h,v 1.5 2003/11/02 11:07:45 wiz Exp
+ *	$NetBSD: mc146818reg.h,v 1.9 2006/03/08 23:46:25 lukem Exp $
  *
  * $FreeBSD$
  */
@@ -122,8 +122,8 @@
  * Periodic Interrupt Rate Select constants (Control register A)
  */
 #define	MC_RATE_NONE	0x0	/* No periodic interrupt */
-#define	MC_RATE_1	0x1     /* 256 Hz if MC_BASE_32_KHz, else 32768 Hz */
-#define	MC_RATE_2	0x2     /* 128 Hz if MC_BASE_32_KHz, else 16384 Hz */
+#define	MC_RATE_1	0x1	/* 256 Hz if MC_BASE_32_KHz, else 32768 Hz */
+#define	MC_RATE_2	0x2	/* 128 Hz if MC_BASE_32_KHz, else 16384 Hz */
 #define	MC_RATE_8192_Hz	0x3	/* 122.070 us period */
 #define	MC_RATE_4096_Hz	0x4	/* 244.141 us period */
 #define	MC_RATE_2048_Hz	0x5	/* 488.281 us period */
@@ -141,8 +141,8 @@
 /*
  * Time base (divisor select) constants (Control register A)
  */
-#define	MC_BASE_4_MHz	0x00		/* 4MHz crystal */
-#define	MC_BASE_1_MHz	MC_REGA_DV0	/* 1MHz crystal */
-#define	MC_BASE_32_KHz	MC_REGA_DV1	/* 32KHz crystal */
+#define	MC_BASE_4_MHz	0x00		/* 4 MHz crystal */
+#define	MC_BASE_1_MHz	MC_REGA_DV0	/* 1 MHz crystal */
+#define	MC_BASE_32_KHz	MC_REGA_DV1	/* 32 KHz crystal */
 #define	MC_BASE_NONE	(MC_REGA_DV2 | MC_REGA_DV1) /* actually also resets */
 #define	MC_BASE_RESET	(MC_REGA_DV2 | MC_REGA_DV1 | MC_REGA_DV0)
diff --git a/sys/dev/mc146818/mc146818var.h b/sys/dev/mc146818/mc146818var.h
index cce95086edf..d54f53ee54b 100644
--- a/sys/dev/mc146818/mc146818var.h
+++ b/sys/dev/mc146818/mc146818var.h
@@ -38,29 +38,30 @@ struct mc146818_softc {
 	u_char sc_regb;				/* register B */
 
 	u_int sc_year0;				/* year counter offset */
+
 	u_int sc_flag;				/* MD flags */
-#define MC146818_NO_CENT_ADJUST	0x0001		/* don't adjust century */
-#define MC146818_BCD		0x0002		/* use BCD mode */
-#define MC146818_12HR		0x0004		/* use AM/PM mode */
+#define	MC146818_NO_CENT_ADJUST	0x0001		/* don't adjust century */
+#define	MC146818_BCD		0x0002		/* use BCD mode */
+#define	MC146818_12HR		0x0004		/* use AM/PM mode */
 
 	/* MD chip register read/write functions */
-	u_int (*sc_mcread)(device_t, u_int);
-	void (*sc_mcwrite)(device_t, u_int, u_int);
+	u_int (*sc_mcread)(device_t dev, u_int reg);
+	void (*sc_mcwrite)(device_t dev, u_int reg, u_int val);
 	/* MD century get/set functions */
-	u_int (*sc_getcent)(device_t);
-	void (*sc_setcent)(device_t, u_int);
+	u_int (*sc_getcent)(device_t dev);
+	void (*sc_setcent)(device_t dev, u_int cent);
 };
 
 /* Default read/write functions */
-u_int mc146818_def_read(device_t, u_int);
-void mc146818_def_write(device_t, u_int, u_int);
+u_int mc146818_def_read(device_t dev, u_int reg);
+void mc146818_def_write(device_t dev, u_int reg, u_int val);
 
 /* Chip attach function */
 int mc146818_attach(device_t);
 
 /* Methods for the clock interface */
 #ifdef notyet
-int mc146818_getsecs(device_t, int *);
+int mc146818_getsecs(device_t dev, int *secp);
 #endif
-int mc146818_gettime(device_t, struct timespec *);
-int mc146818_settime(device_t, struct timespec *);
+int mc146818_gettime(device_t dev, struct timespec *ts);
+int mc146818_settime(device_t dev, struct timespec *ts);
diff --git a/sys/sparc64/sparc64/rtc.c b/sys/sparc64/sparc64/rtc.c
index 7d9e1295e83..d9b0da95d4b 100644
--- a/sys/sparc64/sparc64/rtc.c
+++ b/sys/sparc64/sparc64/rtc.c
@@ -111,7 +111,7 @@ static device_method_t rtc_isa_methods[] = {
 	DEVMETHOD(clock_gettime,	mc146818_gettime),
 	DEVMETHOD(clock_settime,	mc146818_settime),
 
-	{ 0, 0 }
+	KOBJMETHOD_END
 };
 
 static driver_t rtc_isa_driver = {
@@ -123,8 +123,8 @@ static driver_t rtc_isa_driver = {
 DRIVER_MODULE(rtc, isa, rtc_isa_driver, rtc_devclass, 0, 0);
 #endif
 
-static u_int pc87317_getcent(device_t);
-static void pc87317_setcent(device_t, u_int);
+static u_int pc87317_getcent(device_t dev);
+static void pc87317_setcent(device_t dev, u_int cent);
 
 static int
 rtc_ebus_probe(device_t dev)

From 5896e2fa2746a3dff57f2ad9ccb8cc6da44cd69a Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 16:29:40 +0000
Subject: [PATCH 1149/2592] MFC: r201009

Remove clause 3 from Izumi Tsutsui's licenses.

Obtained from:	NetBSD
---
 sys/dev/mc146818/mc146818.c    | 4 +---
 sys/dev/mc146818/mc146818var.h | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/sys/dev/mc146818/mc146818.c b/sys/dev/mc146818/mc146818.c
index 53fe5daf6a8..108ee5ae41b 100644
--- a/sys/dev/mc146818/mc146818.c
+++ b/sys/dev/mc146818/mc146818.c
@@ -9,8 +9,6 @@
  * 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. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -23,7 +21,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *	from: NetBSD: mc146818.c,v 1.4 2003/11/24 06:20:40 tsutsui Exp
+ *	$NetBSD: mc146818.c,v 1.16 2008/05/14 13:29:28 tsutsui Exp $
  */
 
 #include 
diff --git a/sys/dev/mc146818/mc146818var.h b/sys/dev/mc146818/mc146818var.h
index d54f53ee54b..722b4fe1e77 100644
--- a/sys/dev/mc146818/mc146818var.h
+++ b/sys/dev/mc146818/mc146818var.h
@@ -9,8 +9,6 @@
  * 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. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -23,7 +21,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *	from: NetBSD: mc146818var.h,v 1.3 2003/11/24 06:20:40 tsutsui Exp
+ *	$NetBSD: mc146818var.h,v 1.7 2008/05/14 13:29:29 tsutsui Exp $
  *
  * $FreeBSD$
  */

From 98fb63cac16ce5e0793e074373198f33792e9c44 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 16:42:39 +0000
Subject: [PATCH 1150/2592] MFC: r201199

- Prefer i and j over i and n for temporary integer variables.
- Wrap/shorten too long lines.
- Remove a redundant variable and an unnecessary cast in schizo(4).
---
 sys/sparc64/pci/psycho.c | 104 +++++++++++++++++---------------
 sys/sparc64/pci/schizo.c | 127 ++++++++++++++++++++-------------------
 2 files changed, 120 insertions(+), 111 deletions(-)

diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index 8034612fd4c..0aabb224ab3 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -181,9 +181,9 @@ struct psycho_dma_sync {
 	void			*pds_arg;	/* argument for the handler */
 	void			*pds_cookie;	/* parent bus int. cookie */
 	device_t		pds_ppb;	/* farest PCI-PCI bridge */
-	uint8_t			pds_bus;	/* bus of farest PCI device */
-	uint8_t			pds_slot;	/* slot of farest PCI device */
-	uint8_t			pds_func;	/* func. of farest PCI device */
+	uint8_t			pds_bus;	/* bus of farest PCI dev. */
+	uint8_t			pds_slot;	/* slot of farest PCI dev. */
+	uint8_t			pds_func;	/* func. of farest PCI dev. */
 };
 
 #define	PSYCHO_READ8(sc, off) \
@@ -205,8 +205,8 @@ struct psycho_dma_sync {
  * "Hummingbird" is the UltraSPARC IIe onboard UPA to PCI bridge. It's
  * basically the same as Sabre but without an APB underneath it.
  *
- * "Psycho" and "Psycho+" are dual UPA to PCI bridges.  They sit on the UPA bus
- * and manage two PCI buses.  "Psycho" has two 64-bit 33MHz buses, while
+ * "Psycho" and "Psycho+" are dual UPA to PCI bridges.  They sit on the UPA
+ * bus and manage two PCI buses.  "Psycho" has two 64-bit 33MHz buses, while
  * "Psycho+" controls both a 64-bit 33Mhz and a 64-bit 66Mhz PCI bus.  You
  * will usually find a "Psycho+" since I don't think the original "Psycho"
  * ever shipped, and if it did it would be in the U30.
@@ -263,7 +263,8 @@ psycho_get_desc(device_t dev)
 
 	rv = psycho_find_desc(psycho_models, ofw_bus_get_model(dev));
 	if (rv == NULL)
-		rv = psycho_find_desc(psycho_compats, ofw_bus_get_compat(dev));
+		rv = psycho_find_desc(psycho_compats,
+		    ofw_bus_get_compat(dev));
 	return (rv);
 }
 
@@ -295,7 +296,7 @@ psycho_attach(device_t dev)
 	uint32_t dvmabase, prop, prop_array[2];
 	int32_t rev;
 	u_int rerun, ver;
-	int i, n;
+	int i, j;
 
 	node = ofw_bus_get_node(dev);
 	sc = device_get_softc(dev);
@@ -461,12 +462,12 @@ psycho_attach(device_t dev)
 	    rman_manage_region(&sc->sc_pci_mem_rman, 0, PSYCHO_MEM_SIZE) != 0)
 		panic("%s: failed to set up memory rman", __func__);
 
-	n = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
+	i = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
 	/*
 	 * Make sure that the expected ranges are present.  The
 	 * OFW_PCI_CS_MEM64 one is not currently used though.
 	 */
-	if (n != PSYCHO_NRANGE)
+	if (i != PSYCHO_NRANGE)
 		panic("%s: unsupported number of ranges", __func__);
 	/*
 	 * Find the addresses of the various bus spaces.
@@ -474,11 +475,12 @@ psycho_attach(device_t dev)
 	 * The physical start addresses of the ranges are the configuration,
 	 * memory and I/O handles.
 	 */
-	for (n = 0; n < PSYCHO_NRANGE; n++) {
-		i = OFW_PCI_RANGE_CS(&range[n]);
-		if (sc->sc_pci_bh[i] != 0)
-			panic("%s: duplicate range for space %d", __func__, i);
-		sc->sc_pci_bh[i] = OFW_PCI_RANGE_PHYS(&range[n]);
+	for (i = 0; i < PSYCHO_NRANGE; i++) {
+		j = OFW_PCI_RANGE_CS(&range[i]);
+		if (sc->sc_pci_bh[j] != 0)
+			panic("%s: duplicate range for space %d",
+			    __func__, j);
+		sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]);
 	}
 	free(range, M_OFWPROP);
 
@@ -496,8 +498,8 @@ psycho_attach(device_t dev)
 		 * vectors.  We do this early in order to be able to catch
 		 * stray interrupts.
 		 */
-		for (n = 0; n <= PSYCHO_MAX_INO; n++) {
-			if (psycho_find_intrmap(sc, n, &intrmap, &intrclr,
+		for (i = 0; i <= PSYCHO_MAX_INO; i++) {
+			if (psycho_find_intrmap(sc, i, &intrmap, &intrclr,
 			    NULL) == 0)
 				continue;
 			pica = malloc(sizeof(*pica), M_DEVBUF, M_NOWAIT);
@@ -515,21 +517,21 @@ psycho_attach(device_t dev)
 			 */
 			device_printf(dev,
 			    "intr map (INO %d, %s) %#lx: %#lx, clr: %#lx\n",
-			    n, intrmap <= PSR_PCIB3_INT_MAP ? "PCI" : "OBIO",
-			    (u_long)intrmap, (u_long)PSYCHO_READ8(sc, intrmap),
-			    (u_long)intrclr);
-			PSYCHO_WRITE8(sc, intrmap, INTMAP_VEC(sc->sc_ign, n));
+			    i, intrmap <= PSR_PCIB3_INT_MAP ? "PCI" : "OBIO",
+			    (u_long)intrmap, (u_long)PSYCHO_READ8(sc,
+			    intrmap), (u_long)intrclr);
+			PSYCHO_WRITE8(sc, intrmap, INTMAP_VEC(sc->sc_ign, i));
 			PSYCHO_WRITE8(sc, intrclr, 0);
 			PSYCHO_WRITE8(sc, intrmap,
-			    INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, n),
+			    INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, i),
 			    PCPU_GET(mid)));
 #endif
-			i = intr_controller_register(INTMAP_VEC(sc->sc_ign, n),
-			    &psycho_ic, pica);
-			if (i != 0)
+			j = intr_controller_register(INTMAP_VEC(sc->sc_ign,
+			    i), &psycho_ic, pica);
+			if (j != 0)
 				device_printf(dev, "could not register "
 				    "interrupt controller for INO %d (%d)\n",
-				    n, i);
+				    i, j);
 		}
 
 		if (sc->sc_mode == PSYCHO_MODE_PSYCHO)
@@ -583,12 +585,12 @@ psycho_attach(device_t dev)
 	sc->sc_pci_dmat->dt_cookie = sc->sc_is;
 	sc->sc_pci_dmat->dt_mt = &iommu_dma_methods;
 
-	n = OF_getprop(node, "bus-range", (void *)prop_array,
+	i = OF_getprop(node, "bus-range", (void *)prop_array,
 	    sizeof(prop_array));
-	if (n == -1)
+	if (i == -1)
 		panic("%s: could not get bus-range", __func__);
-	if (n != sizeof(prop_array))
-		panic("%s: broken bus-range (%d)", __func__, n);
+	if (i != sizeof(prop_array))
+		panic("%s: broken bus-range (%d)", __func__, i);
 	if (bootverbose)
 		device_printf(dev, "bus range %u to %u; PCI bus %d\n",
 		    prop_array[0], prop_array[1], prop_array[0]);
@@ -657,15 +659,15 @@ psycho_attach(device_t dev)
 	PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
 	    PCIR_LATTIMER, OFW_PCI_LATENCY, 1);
 
-	for (n = PCIR_VENDOR; n < PCIR_STATUS; n += sizeof(uint16_t))
-		le16enc(&sc->sc_pci_hpbcfg[n], bus_space_read_2(
+	for (i = PCIR_VENDOR; i < PCIR_STATUS; i += sizeof(uint16_t))
+		le16enc(&sc->sc_pci_hpbcfg[i], bus_space_read_2(
 		    sc->sc_pci_cfgt, sc->sc_pci_bh[OFW_PCI_CS_CONFIG],
 		    PSYCHO_CONF_OFF(sc->sc_pci_secbus, PCS_DEVICE,
-		    PCS_FUNC, n)));
-	for (n = PCIR_REVID; n <= PCIR_BIST; n += sizeof(uint8_t))
-		sc->sc_pci_hpbcfg[n] = bus_space_read_1(sc->sc_pci_cfgt,
+		    PCS_FUNC, i)));
+	for (i = PCIR_REVID; i <= PCIR_BIST; i += sizeof(uint8_t))
+		sc->sc_pci_hpbcfg[i] = bus_space_read_1(sc->sc_pci_cfgt,
 		    sc->sc_pci_bh[OFW_PCI_CS_CONFIG], PSYCHO_CONF_OFF(
-		    sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, n));
+		    sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, i));
 
 	ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t));
 	/*
@@ -694,8 +696,8 @@ psycho_set_intr(struct psycho_softc *sc, u_int index, bus_addr_t intrmap,
 	int rid;
 
 	rid = index;
-	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
-	    &rid, RF_ACTIVE);
+	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev,
+	    SYS_RES_IRQ, &rid, RF_ACTIVE);
 	if (sc->sc_irq_res[index] == NULL && intrmap >= PSR_POWER_INT_MAP) {
 		/*
 		 * These interrupts aren't mandatory and not available
@@ -704,7 +706,8 @@ psycho_set_intr(struct psycho_softc *sc, u_int index, bus_addr_t intrmap,
 		return;
 	}
 	if (sc->sc_irq_res[index] == NULL ||
-	    INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) != sc->sc_ign ||
+	    INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) !=
+	    sc->sc_ign ||
 	    INTVEC(PSYCHO_READ8(sc, intrmap)) != vec ||
 	    intr_vectors[vec].iv_ic != &psycho_ic ||
 	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
@@ -714,8 +717,8 @@ psycho_set_intr(struct psycho_softc *sc, u_int index, bus_addr_t intrmap,
 }
 
 static int
-psycho_find_intrmap(struct psycho_softc *sc, u_int ino, bus_addr_t *intrmapptr,
-    bus_addr_t *intrclrptr, bus_addr_t *intrdiagptr)
+psycho_find_intrmap(struct psycho_softc *sc, u_int ino,
+    bus_addr_t *intrmapptr, bus_addr_t *intrclrptr, bus_addr_t *intrdiagptr)
 {
 	bus_addr_t intrclr, intrmap;
 	uint64_t diag;
@@ -875,7 +878,7 @@ psycho_wakeup(void *arg)
 {
 	struct psycho_softc *sc = arg;
 
-	/* Gee, we don't really have a framework to deal with this properly. */
+	/* We don't really have a framework to deal with this properly. */
 	device_printf(sc->sc_dev, "power management wakeup\n");
 	return (FILTER_HANDLED);
 }
@@ -992,8 +995,8 @@ psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
 }
 
 static void
-psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
-    uint32_t val, int width)
+psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, uint32_t val, int width)
 {
 	struct psycho_softc *sc;
 	bus_space_handle_t bh;
@@ -1029,8 +1032,9 @@ psycho_route_interrupt(device_t bridge, device_t dev, int pin)
 
 	sc = device_get_softc(bridge);
 	pintr = pin;
-	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, ®,
-	    sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf))
+	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
+	    ®, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
+	    maskbuf))
 		return (mintr);
 	/*
 	 * If this is outside of the range for an intpin, it's likely a full
@@ -1052,7 +1056,8 @@ psycho_route_interrupt(device_t bridge, device_t dev, int pin)
 	intrmap = PSR_PCIA0_INT_MAP +
 	    8 * (pci_get_slot(dev) - 1 + 3 * sc->sc_half);
 	mintr = INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1;
-	device_printf(bridge, "guessing interrupt %d for device %d.%d pin %d\n",
+	device_printf(bridge,
+	    "guessing interrupt %d for device %d.%d pin %d\n",
 	    (int)mintr, pci_get_slot(dev), pci_get_function(dev), pin);
 	return (mintr);
 }
@@ -1271,8 +1276,8 @@ psycho_alloc_resource(device_t bus, device_t child, int type, int *rid,
 		if (start != end)
 			panic("%s: XXX: interrupt range", __func__);
 		start = end = INTMAP_VEC(sc->sc_ign, end);
-		return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type,
-		    rid, start, end, count, flags));
+		return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
+		    type, rid, start, end, count, flags));
 	}
 	switch (type) {
 	case SYS_RES_MEMORY:
@@ -1387,7 +1392,8 @@ psycho_alloc_bus_tag(struct psycho_softc *sc, int type)
 {
 	bus_space_tag_t bt;
 
-	bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF, M_NOWAIT | M_ZERO);
+	bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
 	if (bt == NULL)
 		panic("%s: out of memory", __func__);
 
diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index c1e6e1b4c8f..75769f29926 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -180,9 +180,9 @@ struct schizo_dma_sync {
 	void			*sds_cookie;
 	uint64_t		sds_syncval;
 	device_t		sds_ppb;	/* farest PCI-PCI bridge */
-	uint8_t			sds_bus;	/* bus of farest PCI device */
-	uint8_t			sds_slot;	/* slot of farest PCI device */
-	uint8_t			sds_func;	/* func. of farest PCI device */
+	uint8_t			sds_bus;	/* bus of farest PCI dev. */
+	uint8_t			sds_slot;	/* slot of farest PCI dev. */
+	uint8_t			sds_func;	/* func. of farest PCI dev. */
 };
 
 #define	SCHIZO_PERF_CNT_QLTY	100
@@ -260,7 +260,7 @@ schizo_attach(device_t dev)
 	uint64_t ino_bitmap, reg;
 	phandle_t node;
 	uint32_t prop, prop_array[2];
-	int i, mode, n, nrange, rid, tsbsize;
+	int i, j, mode, rid, tsbsize;
 
 	sc = device_get_softc(dev);
 	node = ofw_bus_get_node(dev);
@@ -289,18 +289,18 @@ schizo_attach(device_t dev)
 	 */
 	sc->sc_half = (bus_get_resource_start(dev, SYS_RES_MEMORY, STX_PCI) >>
 	    20) & 1;
-	for (n = 0; n < (mode == SCHIZO_MODE_SCZ ? SCZ_NREG : TOM_NREG);
-	    n++) {
-		rid = n;
-		sc->sc_mem_res[n] = bus_alloc_resource_any(dev,
+	for (i = 0; i < (mode == SCHIZO_MODE_SCZ ? SCZ_NREG : TOM_NREG);
+	    i++) {
+		rid = i;
+		sc->sc_mem_res[i] = bus_alloc_resource_any(dev,
 		    SYS_RES_MEMORY, &rid,
 		    (((mode == SCHIZO_MODE_SCZ && ((sc->sc_half == 1 &&
-		    n == STX_PCI) || n == STX_CTRL)) ||
+		    i == STX_PCI) || i == STX_CTRL)) ||
 		    (mode == SCHIZO_MODE_TOM && sc->sc_half == 0 &&
-		    n == STX_CTRL)) ? RF_SHAREABLE : 0) | RF_ACTIVE);
-		if (sc->sc_mem_res[n] == NULL)
+		    i == STX_CTRL)) ? RF_SHAREABLE : 0) | RF_ACTIVE);
+		if (sc->sc_mem_res[i] == NULL)
 			panic("%s: could not allocate register bank %d",
-			    __func__, n);
+			    __func__, i);
 	}
 
 	/*
@@ -333,7 +333,8 @@ schizo_attach(device_t dev)
 
 	if (OF_getprop(node, "portid", &sc->sc_ign, sizeof(sc->sc_ign)) == -1)
 		panic("%s: could not determine IGN", __func__);
-	if (OF_getprop(node, "version#", &sc->sc_ver, sizeof(sc->sc_ver)) == -1)
+	if (OF_getprop(node, "version#", &sc->sc_ver, sizeof(sc->sc_ver)) ==
+	    -1)
 		panic("%s: could not determine version", __func__);
 	if (OF_getprop(node, "clock-frequency", &prop, sizeof(prop)) == -1)
 		prop = 33000000;
@@ -397,21 +398,21 @@ schizo_attach(device_t dev)
 	 * This is complicated by the fact that a pair of Schizo PBMs
 	 * shares one IGN.
 	 */
-	n = OF_getprop(node, "ino-bitmap", (void *)prop_array,
+	i = OF_getprop(node, "ino-bitmap", (void *)prop_array,
 	    sizeof(prop_array));
-	if (n == -1)
+	if (i == -1)
 		panic("%s: could not get ino-bitmap", __func__);
 	ino_bitmap = ((uint64_t)prop_array[1] << 32) | prop_array[0];
-	for (n = 0; n <= STX_MAX_INO; n++) {
-		if ((ino_bitmap & (1ULL << n)) == 0)
+	for (i = 0; i <= STX_MAX_INO; i++) {
+		if ((ino_bitmap & (1ULL << i)) == 0)
 			continue;
-		if (n == STX_FB0_INO || n == STX_FB1_INO)
+		if (i == STX_FB0_INO || i == STX_FB1_INO)
 			/* Leave for upa(4). */
 			continue;
-		i = schizo_intr_register(sc, n);
-		if (i != 0)
+		j = schizo_intr_register(sc, i);
+		if (j != 0)
 			device_printf(dev, "could not register interrupt "
-			    "controller for INO %d (%d)\n", n, i);
+			    "controller for INO %d (%d)\n", i, j);
 	}
 
 	/*
@@ -464,9 +465,9 @@ schizo_attach(device_t dev)
 		tsbsize = (x);						\
 		break;							\
 
-	n = OF_getprop(node, "virtual-dma", (void *)prop_array,
+	i = OF_getprop(node, "virtual-dma", (void *)prop_array,
 	    sizeof(prop_array));
-	if (n == -1 || n != sizeof(prop_array))
+	if (i == -1 || i != sizeof(prop_array))
 		schizo_iommu_init(sc, 7, -1);
 	else {
 		switch (prop_array[1]) {
@@ -500,13 +501,12 @@ schizo_attach(device_t dev)
 	    rman_manage_region(&sc->sc_pci_mem_rman, 0, STX_MEM_SIZE) != 0)
 		panic("%s: failed to set up memory rman", __func__);
 
-	nrange = OF_getprop_alloc(node, "ranges", sizeof(*range),
-	    (void **)&range);
+	i = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
 	/*
 	 * Make sure that the expected ranges are present.  The
 	 * OFW_PCI_CS_MEM64 one is not currently used though.
 	 */
-	if (nrange != STX_NRANGE)
+	if (i != STX_NRANGE)
 		panic("%s: unsupported number of ranges", __func__);
 	/*
 	 * Find the addresses of the various bus spaces.
@@ -514,11 +514,12 @@ schizo_attach(device_t dev)
 	 * The physical start addresses of the ranges are the configuration,
 	 * memory and I/O handles.
 	 */
-	for (n = 0; n < STX_NRANGE; n++) {
-		i = OFW_PCI_RANGE_CS(&range[n]);
-		if (sc->sc_pci_bh[i] != 0)
-			panic("%s: duplicate range for space %d", __func__, i);
-		sc->sc_pci_bh[i] = OFW_PCI_RANGE_PHYS(&range[n]);
+	for (i = 0; i < STX_NRANGE; i++) {
+		j = OFW_PCI_RANGE_CS(&range[i]);
+		if (sc->sc_pci_bh[j] != 0)
+			panic("%s: duplicate range for space %d",
+			    __func__, j);
+		sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]);
 	}
 	free(range, M_OFWPROP);
 
@@ -541,12 +542,12 @@ schizo_attach(device_t dev)
 	 * Get the bus range from the firmware.
 	 * NB: Tomatillos don't support PCI bus reenumeration.
 	 */
-	n = OF_getprop(node, "bus-range", (void *)prop_array,
+	i = OF_getprop(node, "bus-range", (void *)prop_array,
 	    sizeof(prop_array));
-	if (n == -1)
+	if (i == -1)
 		panic("%s: could not get bus-range", __func__);
-	if (n != sizeof(prop_array))
-		panic("%s: broken bus-range (%d)", __func__, n);
+	if (i != sizeof(prop_array))
+		panic("%s: broken bus-range (%d)", __func__, i);
 	if (bootverbose)
 		device_printf(dev, "bus range %u to %u; PCI bus %d\n",
 		    prop_array[0], prop_array[1], prop_array[0]);
@@ -634,7 +635,8 @@ schizo_attach(device_t dev)
 	 * a block store after a write to TOMXMS_PCI_DMA_SYNC_PEND though.
 	 */
 	if ((sc->sc_mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 5) ||
-	    sc->sc_mode == SCHIZO_MODE_TOM || sc->sc_mode == SCHIZO_MODE_XMS) {
+	    sc->sc_mode == SCHIZO_MODE_TOM ||
+	    sc->sc_mode == SCHIZO_MODE_XMS) {
 		sc->sc_flags |= SCHIZO_FLAGS_CDMA;
 		if (sc->sc_mode == SCHIZO_MODE_SCZ) {
 			sc->sc_cdma_state = SCHIZO_CDMA_STATE_DONE;
@@ -643,26 +645,26 @@ schizo_attach(device_t dev)
 			 * at RID 4 but most don't.  With the latter we add
 			 * it ourselves at the spare RID 5.
 			 */
-			n = INTINO(bus_get_resource_start(dev, SYS_RES_IRQ,
+			i = INTINO(bus_get_resource_start(dev, SYS_RES_IRQ,
 			    4));
-			if (n == STX_CDMA_A_INO || n == STX_CDMA_B_INO) {
-				(void)schizo_get_intrmap(sc, n, NULL,
+			if (i == STX_CDMA_A_INO || i == STX_CDMA_B_INO) {
+				(void)schizo_get_intrmap(sc, i, NULL,
 				   &sc->sc_cdma_clr);
-				schizo_set_intr(sc, 4, n, schizo_cdma);
+				schizo_set_intr(sc, 4, i, schizo_cdma);
 			} else {
-				n = STX_CDMA_A_INO + sc->sc_half;
+				i = STX_CDMA_A_INO + sc->sc_half;
 				if (bus_set_resource(dev, SYS_RES_IRQ, 5,
-				    INTMAP_VEC(sc->sc_ign, n), 1) != 0)
+				    INTMAP_VEC(sc->sc_ign, i), 1) != 0)
 					panic("%s: failed to add CDMA "
 					    "interrupt", __func__);
-				i = schizo_intr_register(sc, n);
-				if (i != 0)
+				j = schizo_intr_register(sc, i);
+				if (j != 0)
 					panic("%s: could not register "
 					    "interrupt controller for CDMA "
-					    "(%d)", __func__, i);
-				(void)schizo_get_intrmap(sc, n, NULL,
+					    "(%d)", __func__, j);
+				(void)schizo_get_intrmap(sc, i, NULL,
 				   &sc->sc_cdma_clr);
-				schizo_set_intr(sc, 5, n, schizo_cdma);
+				schizo_set_intr(sc, 5, i, schizo_cdma);
 			}
 		}
 		if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4)
@@ -690,11 +692,11 @@ schizo_set_intr(struct schizo_softc *sc, u_int index, u_int ino,
 	int rid;
 
 	rid = index;
-	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
-	    &rid, RF_ACTIVE);
+	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev,
+	    SYS_RES_IRQ, &rid, RF_ACTIVE);
 	if (sc->sc_irq_res[index] == NULL ||
-	    INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) != sc->sc_ign ||
-	    INTINO(vec) != ino ||
+	    INTINO(vec = rman_get_start(sc->sc_irq_res[index])) != ino ||
+	    INTIGN(vec) != sc->sc_ign ||
 	    intr_vectors[vec].iv_ic != &schizo_ic ||
 	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
 	    INTR_TYPE_MISC | INTR_FAST, handler, NULL, sc,
@@ -730,8 +732,8 @@ schizo_intr_register(struct schizo_softc *sc, u_int ino)
 }
 
 static int
-schizo_get_intrmap(struct schizo_softc *sc, u_int ino, bus_addr_t *intrmapptr,
-    bus_addr_t *intrclrptr)
+schizo_get_intrmap(struct schizo_softc *sc, u_int ino,
+    bus_addr_t *intrmapptr, bus_addr_t *intrclrptr)
 {
 	bus_addr_t intrclr, intrmap;
 	uint64_t mr;
@@ -965,8 +967,8 @@ schizo_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
 }
 
 static void
-schizo_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
-    uint32_t val, int width)
+schizo_write_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, uint32_t val, int width)
 {
 	struct schizo_softc *sc;
 	bus_space_handle_t bh;
@@ -1001,8 +1003,9 @@ schizo_route_interrupt(device_t bridge, device_t dev, int pin)
 
 	sc = device_get_softc(bridge);
 	pintr = pin;
-	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, ®,
-	    sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf))
+	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
+	    ®, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
+	    maskbuf))
 		return (mintr);
 
 	device_printf(bridge, "could not route pin %d for device %d.%d\n",
@@ -1037,8 +1040,8 @@ schizo_dma_sync_stub(void *arg)
 
 	(void)PCIB_READ_CONFIG(sds->sds_ppb, sds->sds_bus, sds->sds_slot,
 	    sds->sds_func, PCIR_VENDOR, 2);
-	for (; atomic_cmpset_acq_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_DONE,
-	    SCHIZO_CDMA_STATE_PENDING) == 0;)
+	for (; atomic_cmpset_acq_32(&sc->sc_cdma_state,
+	    SCHIZO_CDMA_STATE_DONE, SCHIZO_CDMA_STATE_PENDING) == 0;)
 		;
 	SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, 1);
 	microuptime(&cur);
@@ -1295,8 +1298,8 @@ schizo_alloc_resource(device_t bus, device_t child, int type, int *rid,
 		if (start != end)
 			panic("%s: XXX: interrupt range", __func__);
 		start = end = INTMAP_VEC(sc->sc_ign, end);
-		return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type,
-		    rid, start, end, count, flags));
+		return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
+		    type, rid, start, end, count, flags));
 	}
 	switch (type) {
 	case SYS_RES_MEMORY:
@@ -1411,7 +1414,7 @@ schizo_alloc_bus_tag(struct schizo_softc *sc, int type)
 {
 	bus_space_tag_t bt;
 
-	bt = (bus_space_tag_t)malloc(sizeof(struct bus_space_tag), M_DEVBUF,
+	bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF,
 	    M_NOWAIT | M_ZERO);
 	if (bt == NULL)
 		panic("%s: out of memory", __func__);

From bfb0b715cedd316859cb02ee8bd36165db4ae305 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 16:46:03 +0000
Subject: [PATCH 1151/2592] MFC: r201395

- Preserve the PROM IOMMU in order to allow OFW drivers to continue to
  work.
- Sanity check the parameters passed to the implementations of the
  pcib_{read,write}_config() methods. Using illegal values can cause
  no real harm but it doesn't hurt to avoid unnecessary data error
  traps requiring to flush and re-enable the level 1 caches.
---
 sys/sparc64/pci/psycho.c    | 14 ++++++++++++--
 sys/sparc64/pci/psychovar.h |  1 +
 sys/sparc64/pci/schizo.c    | 13 +++++++++++--
 sys/sparc64/pci/schizovar.h |  1 +
 4 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index 0aabb224ab3..0eadc4b557f 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -554,6 +554,7 @@ psycho_attach(device_t dev)
 		    M_NOWAIT | M_ZERO);
 		if (sc->sc_is == NULL)
 			panic("%s: malloc iommu_state failed", __func__);
+		sc->sc_is->is_flags = IOMMU_PRESERVE_PROM;
 		if (sc->sc_mode == PSYCHO_MODE_SABRE)
 			sc->sc_is->is_pmaxaddr =
 			    IOMMU_MAXADDR(SABRE_IOMMU_BITS);
@@ -591,10 +592,11 @@ psycho_attach(device_t dev)
 		panic("%s: could not get bus-range", __func__);
 	if (i != sizeof(prop_array))
 		panic("%s: broken bus-range (%d)", __func__, i);
+	sc->sc_pci_secbus = prop_array[0];
+	sc->sc_pci_subbus = prop_array[1];
 	if (bootverbose)
 		device_printf(dev, "bus range %u to %u; PCI bus %d\n",
-		    prop_array[0], prop_array[1], prop_array[0]);
-	sc->sc_pci_secbus = prop_array[0];
+		    sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus);
 
 	/* Clear any pending PCI error bits. */
 	PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
@@ -923,6 +925,10 @@ psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
 	int i;
 
 	sc = device_get_softc(dev);
+	if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+	    slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
+		return (-1);
+
 	bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
 
 	/*
@@ -1003,6 +1009,10 @@ psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func,
 	u_long offset = 0;
 
 	sc = device_get_softc(dev);
+	if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+	    slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
+		return;
+
 	offset = PSYCHO_CONF_OFF(bus, slot, func, reg);
 	bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
 	switch (width) {
diff --git a/sys/sparc64/pci/psychovar.h b/sys/sparc64/pci/psychovar.h
index 04d81adf731..e7c6980bba5 100644
--- a/sys/sparc64/pci/psychovar.h
+++ b/sys/sparc64/pci/psychovar.h
@@ -75,6 +75,7 @@ struct psycho_softc {
 	struct rman			sc_pci_io_rman;
 
 	uint8_t				sc_pci_secbus;
+	uint8_t				sc_pci_subbus;
 
 	uint8_t				sc_pci_hpbcfg[16];
 
diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index 75769f29926..4703571f131 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -454,6 +454,7 @@ schizo_attach(device_t dev)
 	 * buffer, in Schizo version < 5 (i.e. revision < 2.3) it's
 	 * affected by several errata and basically unusable though.
 	 */
+	sc->sc_is.is_flags = IOMMU_PRESERVE_PROM;
 	sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS);
 	sc->sc_is.is_sb[0] = sc->sc_is.is_sb[1] = 0;
 	if (OF_getproplen(node, "no-streaming-cache") < 0 &&
@@ -548,10 +549,11 @@ schizo_attach(device_t dev)
 		panic("%s: could not get bus-range", __func__);
 	if (i != sizeof(prop_array))
 		panic("%s: broken bus-range (%d)", __func__, i);
+	sc->sc_pci_secbus = prop_array[0];
+	sc->sc_pci_subbus = prop_array[1];
 	if (bootverbose)
 		device_printf(dev, "bus range %u to %u; PCI bus %d\n",
-		    prop_array[0], prop_array[1], prop_array[0]);
-	sc->sc_pci_secbus = prop_array[0];
+		    sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus);
 
 	/* Clear any pending PCI error bits. */
 	PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC,
@@ -927,6 +929,9 @@ schizo_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
 	uint8_t byte;
 
 	sc = device_get_softc(dev);
+	if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+	    slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
+		return (-1);
 
 	/*
 	 * The Schizo bridges contain a dupe of their header at 0x80.
@@ -975,6 +980,10 @@ schizo_write_config(device_t dev, u_int bus, u_int slot, u_int func,
 	u_long offset = 0;
 
 	sc = device_get_softc(dev);
+	if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+	    slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
+		return;
+
 	offset = STX_CONF_OFF(bus, slot, func, reg);
 	bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
 	switch (width) {
diff --git a/sys/sparc64/pci/schizovar.h b/sys/sparc64/pci/schizovar.h
index 6b2bca9c601..144ace7c065 100644
--- a/sys/sparc64/pci/schizovar.h
+++ b/sys/sparc64/pci/schizovar.h
@@ -71,6 +71,7 @@ struct schizo_softc {
 	bus_dma_tag_t			sc_pci_dmat;
 
 	uint8_t				sc_pci_secbus;
+	uint8_t				sc_pci_subbus;
 
 	struct ofw_bus_iinfo		sc_pci_iinfo;
 

From 39759286dfd5bbefbe5090ac616a19b292213cd6 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 16:54:59 +0000
Subject: [PATCH 1152/2592] MFC: r201396, r201410

- Demapping unused kernel TLB slots has proven to work reliably so move
  the associated debugging under bootverbose.
- Remove freebsd4_sigreturn(); given that FreeBSD 4 didn't supported
  sparc64 this only ever served as a transition aid prior to FreeBSD
  5.0 and is unused by default since COMPAT_FREEBSD4 was removed from
  GENERIC in r143072 nearly 5 years ago.
---
 sys/sparc64/conf/NOTES        |  1 +
 sys/sparc64/sparc64/machdep.c | 14 +++-----------
 2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/sys/sparc64/conf/NOTES b/sys/sparc64/conf/NOTES
index 211165a1fe8..e189286bd90 100644
--- a/sys/sparc64/conf/NOTES
+++ b/sys/sparc64/conf/NOTES
@@ -129,6 +129,7 @@ nodevice	ex
 # Options we don't want to deal with
 
 nooption	FDC_DEBUG
+nooption	COMPAT_FREEBSD4
 nooption	SC_RENDER_DEBUG
 nooption	SC_DEBUG_LEVEL
 nooption	PPC_DEBUG
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 244928a81e3..06f6ebca8eb 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -383,8 +383,9 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
 	 */
 	for (va = KERNBASE + (kernel_tlb_slots - 1) * PAGE_SIZE_4M;
 	    va >= roundup2(end, PAGE_SIZE_4M); va -= PAGE_SIZE_4M) {
-		printf("demapping unused kernel TLB slot (va %#lx - %#lx)\n",
-		    va, va + PAGE_SIZE_4M - 1);
+		if (bootverbose)
+			printf("demapping unused kernel TLB slot "
+			    "(va %#lx - %#lx)\n", va, va + PAGE_SIZE_4M - 1);
 		stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE,
 		    ASI_DMMU_DEMAP, 0);
 		stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE,
@@ -660,15 +661,6 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
 	return (EJUSTRETURN);
 }
 
-#ifdef COMPAT_FREEBSD4
-int
-freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
-{
-
-	return sigreturn(td, (struct sigreturn_args *)uap);
-}
-#endif
-
 /*
  * Construct a PCB from a trapframe. This is called from kdb_trap() where
  * we want to start a backtrace from the function that caused us to enter

From 1a6cae7f37c634fdcd4264ec03b4fdac05b11bf5 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 16:57:49 +0000
Subject: [PATCH 1153/2592] MFC: r201901

Remove clause 3 and 4 from TNF licenses (this was the only 4-clause TNF
license FreeBSD had in sys/boot).

Obtained from:	NetBSD
---
 sys/boot/common/dev_net.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/sys/boot/common/dev_net.c b/sys/boot/common/dev_net.c
index 0101ce1f825..2fcd45a8908 100644
--- a/sys/boot/common/dev_net.c
+++ b/sys/boot/common/dev_net.c
@@ -1,6 +1,4 @@
-/*
- * $NetBSD: dev_net.c,v 1.12 1997/12/10 20:38:37 gwr Exp $
- */
+/*	$NetBSD: dev_net.c,v 1.23 2008/04/28 20:24:06 martin Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -17,13 +15,6 @@
  * 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

From 455564ab5cbeb45bf04d8b6f1852de1c956bba9e Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 19:06:33 +0000
Subject: [PATCH 1154/2592] MFC: r201932

- Add code allowing a network device to only be open and closed once
  by keeping it opened after the first open and closing it via the
  cleanup handler when NETIF_OPEN_CLOSE_ONCE is defined in order to
  avoid the open-close-dance on every file access which with firmware
  that for example performs an auto-negotiation on every open causes
  netbooting to take horribly long. Basically the behavior with this
  knob enabled resembles the one employed between r60506 and r177108
  (and for sparc64 also again since r182919) with the addition that
  the network device now is closed eventually before entering the
  kernel and before rebooting. Actually I think this should be the
  desired MI behavior, however the U-Boot loader actually requires
  net_close() to be called after every transaction in order for some
  local shutdown operations to be performed (and which I think thus
  will break on concurrent opens, i.e. when netdev_opens is > 1, like
  the loader does at least for disks when LOADER_GZIP_SUPPORT is
  enabled).
- Use NETIF_OPEN_CLOSE_ONCE to replace the hack, which artificially
  increased netdev_opens for sparc64 in order to keep the network
  device opened forever, as at least some firmware versions require
  the network device to be closed eventually before entering the
  kernel or otherwise will DMA received packets to stale memory.
  The powerpc OFW loader probably wants NETIF_OPEN_CLOSE_ONCE to be
  set as well for the same reasons.
---
 sys/boot/common/dev_net.c        | 42 +++++++++++++++++++++++++-------
 sys/boot/sparc64/loader/Makefile |  6 ++++-
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/sys/boot/common/dev_net.c b/sys/boot/common/dev_net.c
index 2fcd45a8908..147a809325a 100644
--- a/sys/boot/common/dev_net.c
+++ b/sys/boot/common/dev_net.c
@@ -71,12 +71,14 @@ __FBSDID("$FreeBSD$");
 int debug = 0;
 #endif
 
+static char *netdev_name;
 static int netdev_sock = -1;
 static int netdev_opens;
 
 static int	net_init(void);
 static int	net_open(struct open_file *, ...);
 static int	net_close(struct open_file *);
+static void	net_cleanup(void);
 static int	net_strategy();
 static void	net_print(int);
 
@@ -90,7 +92,8 @@ struct devsw netdev = {
 	net_open,
 	net_close,
 	noioctl,
-	net_print
+	net_print,
+	net_cleanup
 };
 
 static int
@@ -116,6 +119,12 @@ net_open(struct open_file *f, ...)
 	devname = va_arg(args, char*);
 	va_end(args);
 
+#ifdef	NETIF_OPEN_CLOSE_ONCE
+	/* Before opening another interface, close the previous one first. */
+	if (netdev_sock >= 0 && strcmp(devname, netdev_name) != 0)
+		net_cleanup();
+#endif
+
 	/* On first open, do netif open, mount, etc. */
 	if (netdev_opens == 0) {
 		/* Find network interface. */
@@ -125,6 +134,7 @@ net_open(struct open_file *f, ...)
 				printf("net_open: netif_open() failed\n");
 				return (ENXIO);
 			}
+			netdev_name = strdup(devname);
 #ifdef	NETIF_DEBUG
 			if (debug)
 				printf("net_open: netif_open() succeeded\n");
@@ -135,14 +145,12 @@ net_open(struct open_file *f, ...)
 			error = net_getparams(netdev_sock);
 			if (error) {
 				/* getparams makes its own noise */
+				free(netdev_name);
 				netif_close(netdev_sock);
 				netdev_sock = -1;
 				return (error);
 			}
 		}
-#if defined(__sparc64__)
-		netdev_opens++;
-#endif
 	}
 	netdev_opens++;
 	f->f_devdata = &netdev_sock;
@@ -152,30 +160,46 @@ net_open(struct open_file *f, ...)
 static int
 net_close(struct open_file *f)
 {
+
 #ifdef	NETIF_DEBUG
 	if (debug)
 		printf("net_close: opens=%d\n", netdev_opens);
 #endif
 
-	/* On last close, do netif close, etc. */
 	f->f_devdata = NULL;
+
+#ifndef	NETIF_OPEN_CLOSE_ONCE
 	/* Extra close call? */
 	if (netdev_opens <= 0)
 		return (0);
 	netdev_opens--;
 	/* Not last close? */
 	if (netdev_opens > 0)
-		return(0);
-	rootip.s_addr = 0;
+		return (0);
+	/* On last close, do netif close, etc. */
+#ifdef	NETIF_DEBUG
+	if (debug)
+		printf("net_close: calling net_cleanup()\n");
+#endif
+	net_cleanup();
+#endif
+	return (0);
+}
+
+static void
+net_cleanup(void)
+{
+
 	if (netdev_sock >= 0) {
 #ifdef	NETIF_DEBUG
 		if (debug)
-			printf("net_close: calling netif_close()\n");
+			printf("net_cleanup: calling netif_close()\n");
 #endif
+		rootip.s_addr = 0;
+		free(netdev_name);
 		netif_close(netdev_sock);
 		netdev_sock = -1;
 	}
-	return (0);
 }
 
 static int
diff --git a/sys/boot/sparc64/loader/Makefile b/sys/boot/sparc64/loader/Makefile
index 0d7161c715e..46c6baaee3a 100644
--- a/sys/boot/sparc64/loader/Makefile
+++ b/sys/boot/sparc64/loader/Makefile
@@ -51,11 +51,15 @@ CFLAGS+=	-DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/sparc64
 LIBFICL=	${.OBJDIR}/../../ficl/libficl.a
 .endif
 
-# Always add MI sources 
+# Always add MI sources
 .PATH:		${.CURDIR}/../../common
 .include	"${.CURDIR}/../../common/Makefile.inc"
 CFLAGS+=	-I${.CURDIR}/../../common
 CFLAGS+=	-I.
+# Avoid the open-close-dance for every file access as some firmwares perform
+# an auto-negotiation on every open of the network interface and thus causes
+# netbooting to take horribly long.
+CFLAGS+=	-DNETIF_OPEN_CLOSE_ONCE
 
 CLEANFILES+=	vers.c loader.help
 

From 8e52edcf3b0d8b35f82cc7d4367c1a54b210e46c Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 19:12:33 +0000
Subject: [PATCH 1155/2592] MFC: r202006

Add epic(4), a driver for the front panel LEDs in Sun Fire V215/V245.
It's named after the driver doing the same job in OpenSolaris.
---
 sys/conf/files.sparc64    |   1 +
 sys/modules/Makefile      |   2 +
 sys/modules/epic/Makefile |   8 ++
 sys/sparc64/conf/GENERIC  |   1 +
 sys/sparc64/ebus/epic.c   | 216 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 228 insertions(+)
 create mode 100644 sys/modules/epic/Makefile
 create mode 100644 sys/sparc64/ebus/epic.c

diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64
index 53077bbf237..8ccfd82a700 100644
--- a/sys/conf/files.sparc64
+++ b/sys/conf/files.sparc64
@@ -68,6 +68,7 @@ libkern/flsl.c			standard
 libkern/memmove.c		standard
 sparc64/central/central.c	optional	central
 sparc64/ebus/ebus.c		optional	ebus
+sparc64/ebus/epic.c		optional	epic ebus
 sparc64/fhc/clkbrd.c		optional	fhc
 sparc64/fhc/fhc.c		optional	fhc
 sparc64/isa/isa.c		optional	isa
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 841941b5055..3432da12854 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -80,6 +80,7 @@ SUBDIR=	${_3dfx} \
 	${_em} \
 	en \
 	${_ep} \
+	${_epic} \
 	${_et} \
 	${_ex} \
 	${_exca} \
@@ -593,6 +594,7 @@ _sound=		sound
 .if ${MACHINE_ARCH} == "sparc64"
 _auxio=		auxio
 _em=		em
+_epic=		epic
 _i2c=		i2c
 _igb=		igb
 .if ${MK_CDDL} != "no" || defined(ALL_MODULES)
diff --git a/sys/modules/epic/Makefile b/sys/modules/epic/Makefile
new file mode 100644
index 00000000000..8c2212b5e42
--- /dev/null
+++ b/sys/modules/epic/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../sparc64/ebus
+
+KMOD=	epic
+SRCS=	device_if.h epic.c bus_if.h ofw_bus_if.h
+
+.include 
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index 676493fc93c..a9c026c4f3d 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -141,6 +141,7 @@ device		eeprom		# eeprom (really a front-end for the MK48Txx)
 device		mk48txx		# Mostek MK48Txx clocks
 device		rtc		# rtc (really a front-end for the MC146818)
 device		mc146818	# Motorola MC146818 and compatible clocks
+device		epic		# Sun Fire V215/V245 LEDs
 
 # Serial (COM) ports
 device		puc		# Multi-channel uarts
diff --git a/sys/sparc64/ebus/epic.c b/sys/sparc64/ebus/epic.c
new file mode 100644
index 00000000000..8c20e940228
--- /dev/null
+++ b/sys/sparc64/ebus/epic.c
@@ -0,0 +1,216 @@
+/*-
+ * Copyright (c) 2009 Marius Strobl 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+
+#define	EPIC_DELAY			10000
+
+#define	EPIC_NREG			1
+#define	EPIC_FW_LED			0
+
+#define	EPIC_FW_LED_DATA		0x40
+#define	EPIC_FW_LED_ADDR		0x41
+#define	EPIC_FW_LED_WRITE_MASK		0x80
+
+#define	EPIC_FW_VERSION			0x05
+#define	EPIC_LED_STATE0			0x06
+
+#define	EPIC_LED_ALERT_MASK		0x0c
+#define	EPIC_LED_ALERT_OFF		0x00
+#define	EPIC_LED_ALERT_ON		0x04
+
+#define	EPIC_LED_POWER_MASK		0x30
+#define	EPIC_LED_POWER_OFF		0x00
+#define	EPIC_LED_POWER_ON		0x10
+#define	EPIC_LED_POWER_SB_BLINK		0x20
+#define	EPIC_LED_POWER_FAST_BLINK	0x30
+
+static struct resource_spec epic_res_spec[] = {
+	{ SYS_RES_MEMORY, EPIC_FW_LED, RF_ACTIVE },
+	{ -1, 0 }
+};
+
+struct epic_softc {
+	struct mtx		sc_mtx;
+	struct resource		*sc_res[EPIC_NREG];
+	struct cdev		*sc_led_dev_alert;
+	struct cdev		*sc_led_dev_power;
+};
+
+#define	EPIC_FW_LED_READ(sc, off) ({					\
+	uint8_t	__val;							\
+	bus_write_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_ADDR, (off));\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_ADDR, 1,	\
+	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);		\
+	DELAY(EPIC_DELAY);						\
+	__val = bus_read_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_DATA);\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_DATA, 1,	\
+	    BUS_SPACE_BARRIER_READ);					\
+	DELAY(EPIC_DELAY);						\
+	__val;								\
+})
+
+#define	EPIC_FW_LED_WRITE(sc, off, mask, val) do {			\
+	bus_write_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_ADDR, (off));\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_ADDR, 1,	\
+	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);		\
+	DELAY(EPIC_DELAY);						\
+	bus_write_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_WRITE_MASK,	\
+	    (mask));							\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_WRITE_MASK,	\
+	    1, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);	\
+	DELAY(EPIC_DELAY);						\
+	bus_write_1((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_DATA, (val));\
+	bus_barrier((sc)->sc_res[EPIC_FW_LED], EPIC_FW_LED_DATA, 1,	\
+	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);		\
+	DELAY(EPIC_DELAY);						\
+} while (0)
+
+#define	EPIC_LOCK_INIT(sc)						\
+	mtx_init(&(sc)->sc_mtx, "epic mtx", NULL, MTX_DEF)
+#define	EPIC_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
+#define	EPIC_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
+#define	EPIC_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
+
+static device_probe_t epic_probe;
+static device_attach_t epic_attach;
+static device_detach_t epic_detach;
+
+static void epic_led_alert(void *arg, int onoff);
+static void epic_led_power(void *arg, int onoff);
+
+static device_method_t epic_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		epic_probe),
+	DEVMETHOD(device_attach,	epic_attach),
+	DEVMETHOD(device_detach,	epic_detach),
+
+	KOBJMETHOD_END
+};
+
+static devclass_t epic_devclass;
+
+DEFINE_CLASS_0(epic, epic_driver, epic_methods,
+    sizeof(struct epic_softc));
+DRIVER_MODULE(epic, ebus, epic_driver, epic_devclass, 0, 0);
+
+static int
+epic_probe(device_t dev)
+{
+	const char* compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat != NULL && strcmp(ofw_bus_get_name(dev),
+	    "env-monitor") == 0 && strcmp(compat, "epic") == 0) {
+		device_set_desc(dev, "Sun Fire V215/V245 LEDs");
+		return (BUS_PROBE_DEFAULT);
+	}
+	return (ENXIO);
+}
+
+static int
+epic_attach(device_t dev)
+{
+	struct epic_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (bus_alloc_resources(dev, epic_res_spec, sc->sc_res)) {
+		device_printf(dev, "failed to allocate resources\n");
+		bus_release_resources(dev, epic_res_spec, sc->sc_res);
+		return (ENXIO);
+	}
+
+	EPIC_LOCK_INIT(sc);
+
+	if (bootverbose)
+		device_printf(dev, "version 0x%x\n",
+		    EPIC_FW_LED_READ(sc, EPIC_FW_VERSION));
+
+	sc->sc_led_dev_alert = led_create(epic_led_alert, sc, "alert");
+	sc->sc_led_dev_power = led_create(epic_led_power, sc, "power");
+
+	return (0);
+}
+
+static int
+epic_detach(device_t dev)
+{
+	struct epic_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	led_destroy(sc->sc_led_dev_alert);
+	led_destroy(sc->sc_led_dev_power);
+
+	bus_release_resources(dev, epic_res_spec, sc->sc_res);
+
+	EPIC_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static void
+epic_led_alert(void *arg, int onoff)
+{
+	struct epic_softc *sc;
+
+	sc = (struct epic_softc *)arg;
+
+	EPIC_LOCK(sc);
+	EPIC_FW_LED_WRITE(sc, EPIC_LED_STATE0, EPIC_LED_ALERT_MASK,
+	    onoff ? EPIC_LED_ALERT_ON : EPIC_LED_ALERT_OFF);
+	EPIC_UNLOCK(sc);
+}
+
+static void
+epic_led_power(void *arg, int onoff)
+{
+	struct epic_softc *sc;
+
+	sc = (struct epic_softc *)arg;
+
+	EPIC_LOCK(sc);
+	EPIC_FW_LED_WRITE(sc, EPIC_LED_STATE0, EPIC_LED_POWER_MASK,
+	    onoff ? EPIC_LED_POWER_ON : EPIC_LED_POWER_OFF);
+	EPIC_UNLOCK(sc);
+}

From 82dd0f696c02e250e27e96b5a9a5ccd44826f2b1 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 15 Jan 2010 19:42:09 +0000
Subject: [PATCH 1156/2592] MFC: r201836

Remove unnecessary quoting and markup, add missing punctuation.
---
 lib/libc/stdio/getc.3 | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lib/libc/stdio/getc.3 b/lib/libc/stdio/getc.3
index c8b938664f2..d0f3c15f072 100644
--- a/lib/libc/stdio/getc.3
+++ b/lib/libc/stdio/getc.3
@@ -56,7 +56,7 @@
 .Ft int
 .Fn getchar void
 .Ft int
-.Fn getchar_unlocked "void"
+.Fn getchar_unlocked void
 .Ft int
 .Fn getw "FILE *stream"
 .Sh DESCRIPTION
@@ -141,7 +141,7 @@ until the condition is cleared with
 .Sh STANDARDS
 The
 .Fn fgetc ,
-.Fn getc
+.Fn getc ,
 and
 .Fn getchar
 functions
@@ -167,4 +167,3 @@ The size and byte order of an
 varies from one machine to another, and
 .Fn getw
 is not recommended for portable applications.
-.Pp

From c8dedae27a3c9c4309b3854488871d5f6ed7469b Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 15 Jan 2010 19:53:36 +0000
Subject: [PATCH 1157/2592] MFC: r202159

Remove useless .TE groff macro.
---
 lib/libelf/elf.3 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/libelf/elf.3 b/lib/libelf/elf.3
index 0727ba825e0..854e1af1a2f 100644
--- a/lib/libelf/elf.3
+++ b/lib/libelf/elf.3
@@ -379,7 +379,6 @@ See
 .It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records.
 .It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags.
 .El
-.TE
 .Ss Functional Grouping
 This section contains a brief overview of the available functionality
 in the ELF library.

From 72021af0655b1c23c8a5f4547bfe391c205e5230 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Fri, 15 Jan 2010 21:45:46 +0000
Subject: [PATCH 1158/2592] MFC: r201052, r201200, r202003, r202010, r202023

Add a driver for the `Fire' JBus to PCIe bridges found in at least
the Sun Fire V215/V245 and Sun Ultra 25/45 machines. This driver also
already includes all the code to support the `Oberon' Uranus to PCIe
bridges found in the Fujitsu-Siemens based Mx000 machines but due to
lack of access to such a system for testing, probing of these bridges
is currently disabled.
Unfortunately, the event queue mechanism of these bridges for MSIs/
MSI-Xs matches our current MD and MI interrupt frameworks like square
pegs fit into round holes so for now we are generous and use one event
queue per MSI, which limits us to 35 MSIs/MSI-Xs per Host-PCIe-bridge
(we use one event queue for the PCIe error messages). This seems
tolerable as long as most devices just use one MSI/MSI-X anyway.
Adding knowledge about MSIs/MSI-Xs to the MD interrupt code should
allow us to decouple the 1:1 mapping at the cost of no longer being
able to bind MSIs/MSI-Xs to specific CPUs as we currently have no
reliable way to quiesce a device during the transition of its MSIs/
MSI-Xs to another event queue. This would still require the problem
of interrupt storms generated by devices which have no one-shot
behavior or can't/don't mask interrupts while the filter/handler is
executed (like the older PCIe NICs supported by bge(4)) to be solved
though.
---
 sys/conf/files.sparc64    |    1 +
 sys/conf/options.sparc64  |    2 +
 sys/sparc64/pci/fire.c    | 2172 +++++++++++++++++++++++++++++++++++++
 sys/sparc64/pci/firereg.h | 1004 +++++++++++++++++
 sys/sparc64/pci/firevar.h |   98 ++
 5 files changed, 3277 insertions(+)
 create mode 100644 sys/sparc64/pci/fire.c
 create mode 100644 sys/sparc64/pci/firereg.h
 create mode 100644 sys/sparc64/pci/firevar.h

diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64
index 8ccfd82a700..e5d5f7181f0 100644
--- a/sys/conf/files.sparc64
+++ b/sys/conf/files.sparc64
@@ -75,6 +75,7 @@ sparc64/isa/isa.c		optional	isa
 sparc64/isa/isa_dma.c		optional	isa
 sparc64/isa/ofw_isa.c		optional	ebus | isa
 sparc64/pci/apb.c		optional	pci
+sparc64/pci/fire.c		optional	pci
 sparc64/pci/ofw_pcib.c		optional	pci
 sparc64/pci/ofw_pcib_subr.c	optional	pci
 sparc64/pci/ofw_pcibus.c	optional	pci
diff --git a/sys/conf/options.sparc64 b/sys/conf/options.sparc64
index ba5ab9fc85b..bc6af5a18a5 100644
--- a/sys/conf/options.sparc64
+++ b/sys/conf/options.sparc64
@@ -8,6 +8,8 @@ SUN4U			opt_global.h
 
 ATKBD_DFLT_KEYMAP	opt_atkbd.h
 
+FIRE_DEBUG		opt_fire.h
+
 # Debug IOMMU inserts/removes using diagnostic accesses.  This is very loud.
 IOMMU_DIAG		opt_iommu.h
 
diff --git a/sys/sparc64/pci/fire.c b/sys/sparc64/pci/fire.c
new file mode 100644
index 00000000000..f8a18c1fe18
--- /dev/null
+++ b/sys/sparc64/pci/fire.c
@@ -0,0 +1,2172 @@
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * Copyright (c) 2001 - 2003 by Thomas Moestl 
+ * Copyright (c) 2009 by Marius Strobl 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp
+ *	from: FreeBSD: psycho.c 183152 2008-09-18 19:45:22Z marius
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+
+/*
+ * Driver for `Fire' JBus to PCI Express and `Oberon' Uranus to PCI Express
+ * bridges
+ */
+
+#include "opt_fire.h"
+#include "opt_ofw_pci.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "pcib_if.h"
+
+struct fire_msiqarg;
+
+static bus_space_tag_t fire_alloc_bus_tag(struct fire_softc *sc, int type);
+static const struct fire_desc *fire_get_desc(device_t dev);
+static void fire_dmamap_sync(bus_dma_tag_t dt __unused, bus_dmamap_t map,
+    bus_dmasync_op_t op);
+static int fire_get_intrmap(struct fire_softc *sc, u_int ino,
+    bus_addr_t *intrmapptr, bus_addr_t *intrclrptr);
+static void fire_intr_assign(void *arg);
+static void fire_intr_clear(void *arg);
+static void fire_intr_disable(void *arg);
+static void fire_intr_enable(void *arg);
+static int fire_intr_register(struct fire_softc *sc, u_int ino);
+static inline void fire_msiq_common(struct intr_vector *iv,
+    struct fire_msiqarg *fmqa);
+static void fire_msiq_filter(void *cookie);
+static void fire_msiq_handler(void *cookie);
+static void fire_set_intr(struct fire_softc *sc, u_int index, u_int ino,
+    driver_filter_t handler, void *arg);
+static timecounter_get_t fire_get_timecount;
+
+/* Interrupt handlers */
+static driver_filter_t fire_dmc_pec;
+static driver_filter_t fire_pcie;
+static driver_filter_t fire_xcb;
+
+/*
+ * Methods
+ */
+static bus_activate_resource_t fire_activate_resource;
+static pcib_alloc_msi_t fire_alloc_msi;
+static pcib_alloc_msix_t fire_alloc_msix;
+static bus_alloc_resource_t fire_alloc_resource;
+static device_attach_t fire_attach;
+static bus_deactivate_resource_t fire_deactivate_resource;
+static bus_get_dma_tag_t fire_get_dma_tag;
+static ofw_bus_get_node_t fire_get_node;
+static pcib_map_msi_t fire_map_msi;
+static pcib_maxslots_t fire_maxslots;
+static device_probe_t fire_probe;
+static pcib_read_config_t fire_read_config;
+static bus_read_ivar_t fire_read_ivar;
+static pcib_release_msi_t fire_release_msi;
+static pcib_release_msix_t fire_release_msix;
+static bus_release_resource_t fire_release_resource;
+static pcib_route_interrupt_t fire_route_interrupt;
+static bus_setup_intr_t fire_setup_intr;
+static bus_teardown_intr_t fire_teardown_intr;
+static pcib_write_config_t fire_write_config;
+
+static device_method_t fire_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		fire_probe),
+	DEVMETHOD(device_attach,	fire_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	bus_generic_print_child),
+	DEVMETHOD(bus_read_ivar,	fire_read_ivar),
+	DEVMETHOD(bus_setup_intr,	fire_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	fire_teardown_intr),
+	DEVMETHOD(bus_alloc_resource,	fire_alloc_resource),
+	DEVMETHOD(bus_activate_resource,	fire_activate_resource),
+	DEVMETHOD(bus_deactivate_resource,	fire_deactivate_resource),
+	DEVMETHOD(bus_release_resource,	fire_release_resource),
+	DEVMETHOD(bus_get_dma_tag,	fire_get_dma_tag),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,	fire_maxslots),
+	DEVMETHOD(pcib_read_config,	fire_read_config),
+	DEVMETHOD(pcib_write_config,	fire_write_config),
+	DEVMETHOD(pcib_route_interrupt,	fire_route_interrupt),
+	DEVMETHOD(pcib_alloc_msi,	fire_alloc_msi),
+	DEVMETHOD(pcib_release_msi,	fire_release_msi),
+	DEVMETHOD(pcib_alloc_msix,	fire_alloc_msix),
+	DEVMETHOD(pcib_release_msix,	fire_release_msix),
+	DEVMETHOD(pcib_map_msi,		fire_map_msi),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node,	fire_get_node),
+
+	KOBJMETHOD_END
+};
+
+static devclass_t fire_devclass;
+
+DEFINE_CLASS_0(pcib, fire_driver, fire_methods, sizeof(struct fire_softc));
+EARLY_DRIVER_MODULE(fire, nexus, fire_driver, fire_devclass, 0, 0,
+    BUS_PASS_BUS);
+MODULE_DEPEND(fire, nexus, 1, 1, 1);
+
+static const struct intr_controller fire_ic = {
+	fire_intr_enable,
+	fire_intr_disable,
+	fire_intr_assign,
+	fire_intr_clear
+};
+
+struct fire_icarg {
+	struct fire_softc	*fica_sc;
+	bus_addr_t		fica_map;
+	bus_addr_t		fica_clr;
+};
+
+static const struct intr_controller fire_msiqc_filter = {
+	fire_intr_enable,
+	fire_intr_disable,
+	fire_intr_assign,
+	NULL
+};
+
+struct fire_msiqarg {
+	struct fire_icarg	fmqa_fica;
+	struct mtx		fmqa_mtx;
+	struct fo_msiq_record	*fmqa_base;
+	uint64_t		fmqa_head;
+	uint64_t		fmqa_tail;
+	uint32_t		fmqa_msiq;
+	uint32_t		fmqa_msi;
+};
+
+#define	FIRE_PERF_CNT_QLTY	100
+
+#define	FIRE_SPC_BARRIER(spc, sc, offs, len, flags)			\
+	bus_barrier((sc)->sc_mem_res[(spc)], (offs), (len), (flags))
+#define	FIRE_SPC_READ_8(spc, sc, offs)					\
+	bus_read_8((sc)->sc_mem_res[(spc)], (offs))
+#define	FIRE_SPC_WRITE_8(spc, sc, offs, v)				\
+	bus_write_8((sc)->sc_mem_res[(spc)], (offs), (v))
+
+#ifndef FIRE_DEBUG
+#define	FIRE_SPC_SET(spc, sc, offs, reg, v)				\
+	FIRE_SPC_WRITE_8((spc), (sc), (offs), (v))
+#else
+#define	FIRE_SPC_SET(spc, sc, offs, reg, v) do {			\
+	device_printf((sc)->sc_dev, reg " 0x%016llx -> 0x%016llx\n",	\
+	    (unsigned long long)FIRE_SPC_READ_8((spc), (sc), (offs)),	\
+	    (unsigned long long)(v));					\
+	FIRE_SPC_WRITE_8((spc), (sc), (offs), (v));			\
+	} while (0)
+#endif
+
+#define	FIRE_PCI_BARRIER(sc, offs, len, flags)				\
+	FIRE_SPC_BARRIER(FIRE_PCI, (sc), (offs), len, flags)
+#define	FIRE_PCI_READ_8(sc, offs)					\
+	FIRE_SPC_READ_8(FIRE_PCI, (sc), (offs))
+#define	FIRE_PCI_WRITE_8(sc, offs, v)					\
+	FIRE_SPC_WRITE_8(FIRE_PCI, (sc), (offs), (v))
+#define	FIRE_CTRL_BARRIER(sc, offs, len, flags)				\
+	FIRE_SPC_BARRIER(FIRE_CTRL, (sc), (offs), len, flags)
+#define	FIRE_CTRL_READ_8(sc, offs)					\
+	FIRE_SPC_READ_8(FIRE_CTRL, (sc), (offs))
+#define	FIRE_CTRL_WRITE_8(sc, offs, v)					\
+	FIRE_SPC_WRITE_8(FIRE_CTRL, (sc), (offs), (v))
+
+#define	FIRE_PCI_SET(sc, offs, v)					\
+	FIRE_SPC_SET(FIRE_PCI, (sc), (offs), # offs, (v))
+#define	FIRE_CTRL_SET(sc, offs, v)					\
+	FIRE_SPC_SET(FIRE_CTRL, (sc), (offs), # offs, (v))
+
+struct fire_desc {
+	const char	*fd_string;
+	int		fd_mode;
+	const char	*fd_name;
+};
+
+static const struct fire_desc const fire_compats[] = {
+	{ "pciex108e,80f0",	FIRE_MODE_FIRE,		"Fire" },
+#if 0
+	{ "pciex108e,80f8",	FIRE_MODE_OBERON,	"Oberon" },
+#endif
+	{ NULL,			0,			NULL }
+};
+
+static const struct fire_desc *
+fire_get_desc(device_t dev)
+{
+	const struct fire_desc *desc;
+	const char *compat;
+
+	compat = ofw_bus_get_compat(dev);
+	if (compat == NULL)
+		return (NULL);
+	for (desc = fire_compats; desc->fd_string != NULL; desc++)
+		if (strcmp(desc->fd_string, compat) == 0)
+			return (desc);
+	return (NULL);
+}
+
+static int
+fire_probe(device_t dev)
+{
+	const char *dtype;
+
+	dtype = ofw_bus_get_type(dev);
+	if (dtype != NULL && strcmp(dtype, OFW_TYPE_PCIE) == 0 &&
+	    fire_get_desc(dev) != NULL) {
+		device_set_desc(dev, "Sun Host-PCIe bridge");
+		return (BUS_PROBE_GENERIC);
+	}
+	return (ENXIO);
+}
+
+static int
+fire_attach(device_t dev)
+{
+	struct fire_softc *sc;
+	const struct fire_desc *desc;
+	struct ofw_pci_msi_ranges msi_ranges;
+	struct ofw_pci_msi_addr_ranges msi_addr_ranges;
+	struct ofw_pci_msi_eq_to_devino msi_eq_to_devino;
+	struct fire_msiqarg *fmqa;
+	struct timecounter *tc;
+	struct ofw_pci_ranges *range;
+	uint64_t ino_bitmap, val;
+	phandle_t node;
+	uint32_t prop, prop_array[2];
+	int i, j, mode;
+	u_int lw;
+	uint16_t mps;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+	desc = fire_get_desc(dev);
+	mode = desc->fd_mode;
+
+	sc->sc_dev = dev;
+	sc->sc_node = node;
+	sc->sc_mode = mode;
+	sc->sc_flags = 0;
+
+	mtx_init(&sc->sc_msi_mtx, "msi_mtx", NULL, MTX_DEF);
+	mtx_init(&sc->sc_pcib_mtx, "pcib_mtx", NULL, MTX_SPIN);
+
+	/*
+	 * Fire and Oberon have two register banks:
+	 * (0) per-PBM PCI Express configuration and status registers
+	 * (1) (shared) Fire/Oberon controller configuration and status
+	 *     registers
+	 */
+	for (i = 0; i < FIRE_NREG; i++) {
+		j = i;
+		sc->sc_mem_res[i] = bus_alloc_resource_any(dev,
+		    SYS_RES_MEMORY, &j, RF_ACTIVE);
+		if (sc->sc_mem_res[i] == NULL)
+			panic("%s: could not allocate register bank %d",
+			    __func__, i);
+	}
+
+	if (OF_getprop(node, "portid", &sc->sc_ign, sizeof(sc->sc_ign)) == -1)
+		panic("%s: could not determine IGN", __func__);
+	if (OF_getprop(node, "module-revision#", &prop, sizeof(prop)) == -1)
+		panic("%s: could not determine revision", __func__);
+
+	device_printf(dev, "%s, module-revision %d, IGN %#x\n",
+	    desc->fd_name, prop, sc->sc_ign);
+
+	/*
+	 * Hunt through all the interrupt mapping regs and register
+	 * the interrupt controller for our interrupt vectors.  We do
+	 * this early in order to be able to catch stray interrupts.
+	 */
+	i = OF_getprop(node, "ino-bitmap", (void *)prop_array,
+	    sizeof(prop_array));
+	if (i == -1)
+		panic("%s: could not get ino-bitmap", __func__);
+	ino_bitmap = ((uint64_t)prop_array[1] << 32) | prop_array[0];
+	for (i = 0; i <= FO_MAX_INO; i++) {
+		if ((ino_bitmap & (1ULL << i)) == 0)
+			continue;
+		j = fire_intr_register(sc, i);
+		if (j != 0)
+			device_printf(dev, "could not register interrupt "
+			    "controller for INO %d (%d)\n", i, j);
+	}
+
+	/* JBC/UBC module initialization */
+	FIRE_CTRL_SET(sc, FO_XBC_ERR_LOG_EN, ~0ULL);
+	FIRE_CTRL_SET(sc, FO_XBC_ERR_STAT_CLR, ~0ULL);
+	/* not enabled by OpenSolaris */
+	FIRE_CTRL_SET(sc, FO_XBC_INT_EN, ~0ULL);
+	if (sc->sc_mode == FIRE_MODE_FIRE) {
+		FIRE_CTRL_SET(sc, FIRE_JBUS_PAR_CTRL,
+		    FIRE_JBUS_PAR_CTRL_P_EN);
+		FIRE_CTRL_SET(sc, FIRE_JBC_FATAL_RST_EN,
+		    ((1ULL << FIRE_JBC_FATAL_RST_EN_SPARE_P_INT_SHFT) &
+		    FIRE_JBC_FATAL_RST_EN_SPARE_P_INT_MASK) |
+		    FIRE_JBC_FATAL_RST_EN_MB_PEA_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_CPE_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_APE_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_PIO_CPE_INT |
+		    FIRE_JBC_FATAL_RST_EN_JTCEEW_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_JTCEEI_P_INT |
+		    FIRE_JBC_FATAL_RST_EN_JTCEER_P_INT);
+		FIRE_CTRL_SET(sc, FIRE_JBC_CORE_BLOCK_INT_EN, ~0ULL);
+	}
+
+	/* TLU initialization */
+	FIRE_PCI_SET(sc, FO_PCI_TLU_OEVENT_STAT_CLR,
+	    FO_PCI_TLU_OEVENT_S_MASK | FO_PCI_TLU_OEVENT_P_MASK);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_TLU_OEVENT_INT_EN,
+	    FO_PCI_TLU_OEVENT_S_MASK | FO_PCI_TLU_OEVENT_P_MASK);
+	FIRE_PCI_SET(sc, FO_PCI_TLU_UERR_STAT_CLR,
+	    FO_PCI_TLU_UERR_INT_S_MASK | FO_PCI_TLU_UERR_INT_P_MASK);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_TLU_UERR_INT_EN,
+	    FO_PCI_TLU_UERR_INT_S_MASK | FO_PCI_TLU_UERR_INT_P_MASK);
+	FIRE_PCI_SET(sc, FO_PCI_TLU_CERR_STAT_CLR,
+	    FO_PCI_TLU_CERR_INT_S_MASK | FO_PCI_TLU_CERR_INT_P_MASK);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_TLU_CERR_INT_EN,
+	    FO_PCI_TLU_CERR_INT_S_MASK | FO_PCI_TLU_CERR_INT_P_MASK);
+	val = FIRE_PCI_READ_8(sc, FO_PCI_TLU_CTRL) |
+	    ((FO_PCI_TLU_CTRL_L0S_TIM_DFLT << FO_PCI_TLU_CTRL_L0S_TIM_SHFT) &
+	    FO_PCI_TLU_CTRL_L0S_TIM_MASK) |
+	    ((FO_PCI_TLU_CTRL_CFG_DFLT << FO_PCI_TLU_CTRL_CFG_SHFT) &
+	    FO_PCI_TLU_CTRL_CFG_MASK);
+	if (sc->sc_mode == FIRE_MODE_OBERON)
+		val &= ~FO_PCI_TLU_CTRL_NWPR_EN;
+	val |= FO_PCI_TLU_CTRL_CFG_REMAIN_DETECT_QUIET;
+	FIRE_PCI_SET(sc, FO_PCI_TLU_CTRL, val);
+	FIRE_PCI_SET(sc, FO_PCI_TLU_DEV_CTRL, 0);
+	FIRE_PCI_SET(sc, FO_PCI_TLU_LNK_CTRL, FO_PCI_TLU_LNK_CTRL_CLK);
+
+	/* DLU/LPU initialization */
+	if (sc->sc_mode == FIRE_MODE_OBERON)
+		FIRE_PCI_SET(sc, FO_PCI_LPU_INT_MASK, 0);
+	else
+		FIRE_PCI_SET(sc, FO_PCI_LPU_RST, 0);
+	FIRE_PCI_SET(sc, FO_PCI_LPU_LNK_LYR_CFG,
+	    FO_PCI_LPU_LNK_LYR_CFG_VC0_EN);
+	FIRE_PCI_SET(sc, FO_PCI_LPU_FLW_CTRL_UPDT_CTRL,
+	    FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_NP_EN |
+	    FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_P_EN);
+	if (sc->sc_mode == FIRE_MODE_OBERON)
+		FIRE_PCI_SET(sc, FO_PCI_LPU_TXLNK_RPLY_TMR_THRS,
+		    (OBERON_PCI_LPU_TXLNK_RPLY_TMR_THRS_DFLT <<
+		    FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_SHFT) &
+		    FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_MASK);
+	else {
+		switch ((FIRE_PCI_READ_8(sc, FO_PCI_TLU_LNK_STAT) &
+		    FO_PCI_TLU_LNK_STAT_WDTH_MASK) >>
+		    FO_PCI_TLU_LNK_STAT_WDTH_SHFT) {
+		case 1:
+			lw = 0;
+			break;
+		case 4:
+			lw = 1;
+			break;
+		case 8:
+			lw = 2;
+			break;
+		case 16:
+			lw = 3;
+			break;
+		default:
+			lw = 0;
+		}
+		mps = (FIRE_PCI_READ_8(sc, FO_PCI_TLU_CTRL) &
+		    FO_PCI_TLU_CTRL_CFG_MASK) >> FO_PCI_TLU_CTRL_CFG_SHFT;
+		i = sizeof(fire_freq_nak_tmr_thrs) /
+		    sizeof(*fire_freq_nak_tmr_thrs);
+		if (mps >= i);
+			mps = i - 1;
+		FIRE_PCI_SET(sc, FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS,
+		    (fire_freq_nak_tmr_thrs[mps][lw] <<
+		    FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS_SHFT) &
+		    FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS_MASK);
+		FIRE_PCI_SET(sc, FO_PCI_LPU_TXLNK_RPLY_TMR_THRS,
+		    (fire_rply_tmr_thrs[mps][lw] <<
+		    FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_SHFT) &
+		    FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_MASK);
+		FIRE_PCI_SET(sc, FO_PCI_LPU_TXLNK_RTR_FIFO_PTR,
+		    ((FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_DFLT <<
+		    FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_SHFT) &
+		    FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_MASK) |
+		    ((FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_DFLT <<
+		    FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_SHFT) &
+		    FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_MASK));
+		FIRE_PCI_SET(sc, FO_PCI_LPU_LTSSM_CFG2,
+		    (FO_PCI_LPU_LTSSM_CFG2_12_TO_DFLT <<
+		    FO_PCI_LPU_LTSSM_CFG2_12_TO_SHFT) &
+		    FO_PCI_LPU_LTSSM_CFG2_12_TO_MASK);
+		FIRE_PCI_SET(sc, FO_PCI_LPU_LTSSM_CFG3,
+		    (FO_PCI_LPU_LTSSM_CFG3_2_TO_DFLT <<
+		    FO_PCI_LPU_LTSSM_CFG3_2_TO_SHFT) &
+		    FO_PCI_LPU_LTSSM_CFG3_2_TO_MASK);
+		FIRE_PCI_SET(sc, FO_PCI_LPU_LTSSM_CFG4,
+		    ((FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_DFLT <<
+		    FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_SHFT) &
+		    FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_MASK) |
+		    ((FO_PCI_LPU_LTSSM_CFG4_N_FTS_DFLT <<
+		    FO_PCI_LPU_LTSSM_CFG4_N_FTS_SHFT) &
+		    FO_PCI_LPU_LTSSM_CFG4_N_FTS_MASK));
+		FIRE_PCI_SET(sc, FO_PCI_LPU_LTSSM_CFG5, 0);
+	}
+
+	/* ILU initialization */
+	FIRE_PCI_SET(sc, FO_PCI_ILU_ERR_STAT_CLR, ~0ULL);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_ILU_INT_EN, ~0ULL);
+
+	/* IMU initialization */
+	FIRE_PCI_SET(sc, FO_PCI_IMU_ERR_STAT_CLR, ~0ULL);
+	FIRE_PCI_SET(sc, FO_PCI_IMU_INT_EN,
+	    FIRE_PCI_READ_8(sc, FO_PCI_IMU_INT_EN) &
+	    ~(FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_S |
+	    FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_S |
+	    FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_S |
+	    FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_P |
+	    FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_P |
+	    FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_P));
+
+	/* MMU initialization */
+	FIRE_PCI_SET(sc, FO_PCI_MMU_ERR_STAT_CLR,
+	    FO_PCI_MMU_ERR_INT_S_MASK | FO_PCI_MMU_ERR_INT_P_MASK);
+	/* not enabled by OpenSolaris */
+	FIRE_PCI_SET(sc, FO_PCI_MMU_INT_EN,
+	    FO_PCI_MMU_ERR_INT_S_MASK | FO_PCI_MMU_ERR_INT_P_MASK);
+
+	/* DMC initialization */
+	FIRE_PCI_SET(sc, FO_PCI_DMC_CORE_BLOCK_INT_EN, ~0ULL);
+	FIRE_PCI_SET(sc, FO_PCI_DMC_DBG_SEL_PORTA, 0);
+	FIRE_PCI_SET(sc, FO_PCI_DMC_DBG_SEL_PORTB, 0);
+
+	/* PEC initialization */
+	FIRE_PCI_SET(sc, FO_PCI_PEC_CORE_BLOCK_INT_EN, ~0ULL);
+
+	/* Establish handlers for interesting interrupts. */
+	if ((ino_bitmap & (1ULL << FO_DMC_PEC_INO)) != 0)
+		fire_set_intr(sc, 1, FO_DMC_PEC_INO, fire_dmc_pec, sc);
+	if ((ino_bitmap & (1ULL << FO_XCB_INO)) != 0)
+		fire_set_intr(sc, 0, FO_XCB_INO, fire_xcb, sc);
+
+	/* MSI/MSI-X support */
+	if (OF_getprop(node, "#msi", &sc->sc_msi_count,
+	    sizeof(sc->sc_msi_count)) == -1)
+		panic("%s: could not determine MSI count", __func__);
+	if (OF_getprop(node, "msi-ranges", &msi_ranges,
+	    sizeof(msi_ranges)) == -1)
+		sc->sc_msi_first = 0;
+	else
+		sc->sc_msi_first = msi_ranges.first;
+	if (OF_getprop(node, "msi-data-mask", &sc->sc_msi_data_mask,
+	    sizeof(sc->sc_msi_data_mask)) == -1)
+		panic("%s: could not determine MSI data mask", __func__);
+	if (OF_getprop(node, "msix-data-width", &sc->sc_msix_data_width,
+	    sizeof(sc->sc_msix_data_width)) > 0)
+		sc->sc_flags |= FIRE_MSIX;
+	if (OF_getprop(node, "msi-address-ranges", &msi_addr_ranges,
+	    sizeof(msi_addr_ranges)) == -1)
+		panic("%s: could not determine MSI address ranges", __func__);
+	sc->sc_msi_addr32 = OFW_PCI_MSI_ADDR_RANGE_32(&msi_addr_ranges);
+	sc->sc_msi_addr64 = OFW_PCI_MSI_ADDR_RANGE_64(&msi_addr_ranges);
+	if (OF_getprop(node, "#msi-eqs", &sc->sc_msiq_count,
+	    sizeof(sc->sc_msiq_count)) == -1)
+		panic("%s: could not determine MSI event queue count",
+		    __func__);
+	if (OF_getprop(node, "msi-eq-size", &sc->sc_msiq_size,
+	    sizeof(sc->sc_msiq_size)) == -1)
+		panic("%s: could not determine MSI event queue size",
+		    __func__);
+	if (OF_getprop(node, "msi-eq-to-devino", &msi_eq_to_devino,
+	    sizeof(msi_eq_to_devino)) == -1 &&
+	    OF_getprop(node, "msi-eq-devino", &msi_eq_to_devino,
+	    sizeof(msi_eq_to_devino)) == -1) {
+		sc->sc_msiq_first = 0;
+		sc->sc_msiq_ino_first = FO_EQ_FIRST_INO;
+	} else {
+		sc->sc_msiq_first = msi_eq_to_devino.eq_first;
+		sc->sc_msiq_ino_first = msi_eq_to_devino.devino_first;
+	}
+	if (sc->sc_msiq_ino_first < FO_EQ_FIRST_INO ||
+	    sc->sc_msiq_ino_first + sc->sc_msiq_count - 1 > FO_EQ_LAST_INO)
+		panic("%s: event queues exceed INO range", __func__);
+	sc->sc_msi_bitmap = malloc(roundup2(sc->sc_msi_count, NBBY) / NBBY,
+	    M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (sc->sc_msi_bitmap == NULL)
+		panic("%s: could not malloc MSI bitmap", __func__);
+	sc->sc_msi_msiq_table = malloc(sc->sc_msi_count *
+	    sizeof(*sc->sc_msi_msiq_table), M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (sc->sc_msi_msiq_table == NULL)
+		panic("%s: could not malloc MSI-MSI event queue table",
+		    __func__);
+	sc->sc_msiq_bitmap = malloc(roundup2(sc->sc_msiq_count, NBBY) / NBBY,
+	    M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (sc->sc_msiq_bitmap == NULL)
+		panic("%s: could not malloc MSI event queue bitmap", __func__);
+	j = FO_EQ_RECORD_SIZE * FO_EQ_NRECORDS * sc->sc_msiq_count;
+	sc->sc_msiq = contigmalloc(j, M_DEVBUF, M_NOWAIT, 0, ~0UL,
+	    FO_EQ_ALIGNMENT, 0);
+	if (sc->sc_msiq == NULL)
+		panic("%s: could not contigmalloc MSI event queue", __func__);
+	memset(sc->sc_msiq, 0, j);
+	FIRE_PCI_SET(sc, FO_PCI_EQ_BASE_ADDR, FO_PCI_EQ_BASE_ADDR_BYPASS |
+	    (pmap_kextract((vm_offset_t)sc->sc_msiq) &
+	    FO_PCI_EQ_BASE_ADDR_MASK));
+	for (i = 0; i < sc->sc_msi_count; i++) {
+		j = (i + sc->sc_msi_first) << 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_MAP_BASE + j,
+		    FIRE_PCI_READ_8(sc, FO_PCI_MSI_MAP_BASE + j) &
+		    ~FO_PCI_MSI_MAP_V);
+	}
+	for (i = 0; i < sc->sc_msiq_count; i++) {
+		j = i + sc->sc_msiq_ino_first;
+		if ((ino_bitmap & (1ULL << j)) == 0) {
+			mtx_lock(&sc->sc_msi_mtx);
+			setbit(sc->sc_msiq_bitmap, i);
+			mtx_unlock(&sc->sc_msi_mtx);
+		}
+		fmqa = intr_vectors[INTMAP_VEC(sc->sc_ign, j)].iv_icarg;
+		mtx_init(&fmqa->fmqa_mtx, "msiq_mtx", NULL, MTX_SPIN);
+		fmqa->fmqa_base =
+		    (struct fo_msiq_record *)((caddr_t)sc->sc_msiq +
+		    (FO_EQ_RECORD_SIZE * FO_EQ_NRECORDS * i));
+		j = i + sc->sc_msiq_first;
+		fmqa->fmqa_msiq = j;
+		j <<= 3;
+		fmqa->fmqa_head = FO_PCI_EQ_HD_BASE + j;
+		fmqa->fmqa_tail = FO_PCI_EQ_TL_BASE + j;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + j,
+		    FO_PCI_EQ_CTRL_CLR_COVERR | FO_PCI_EQ_CTRL_CLR_E2I |
+		    FO_PCI_EQ_CTRL_CLR_DIS);
+		FIRE_PCI_WRITE_8(sc, fmqa->fmqa_tail,
+		    (0 << FO_PCI_EQ_TL_SHFT) & FO_PCI_EQ_TL_MASK);
+		FIRE_PCI_WRITE_8(sc, fmqa->fmqa_head,
+		    (0 << FO_PCI_EQ_HD_SHFT) & FO_PCI_EQ_HD_MASK);
+	}
+	FIRE_PCI_SET(sc, FO_PCI_MSI_32_BIT_ADDR, sc->sc_msi_addr32 &
+	    FO_PCI_MSI_32_BIT_ADDR_MASK);
+	FIRE_PCI_SET(sc, FO_PCI_MSI_64_BIT_ADDR, sc->sc_msi_addr64 &
+	    FO_PCI_MSI_64_BIT_ADDR_MASK);
+
+	/*
+	 * Establish a handler for interesting PCIe messages and disable
+	 * unintersting ones.
+	 */
+	mtx_lock(&sc->sc_msi_mtx);
+	for (i = 0; i < sc->sc_msiq_count; i++) {
+		if (isclr(sc->sc_msiq_bitmap, i) != 0) {
+			j = i;
+			break;
+		}
+	}
+	if (i == sc->sc_msiq_count) {
+		mtx_unlock(&sc->sc_msi_mtx);
+		panic("%s: no spare event queue for PCIe messages", __func__);
+	}
+	setbit(sc->sc_msiq_bitmap, j);
+	mtx_unlock(&sc->sc_msi_mtx);
+	i = INTMAP_VEC(sc->sc_ign, j + sc->sc_msiq_ino_first);
+	if (bus_set_resource(dev, SYS_RES_IRQ, 2, i, 1) != 0)
+		panic("%s: failed to add interrupt for PCIe messages",
+		    __func__);
+	fire_set_intr(sc, 2, INTINO(i), fire_pcie, intr_vectors[i].iv_icarg);
+	j += sc->sc_msiq_first;
+	/*
+	 * "Please note that setting the EQNUM field to a value larger than
+	 * 35 will yield unpredictable results."
+	 */
+	if (j > 35)
+		panic("%s: invalid queue for PCIe messages (%d)",
+		    __func__, j);
+	FIRE_PCI_SET(sc, FO_PCI_ERR_COR, FO_PCI_ERR_PME_V |
+	    ((j << FO_PCI_ERR_PME_EQNUM_SHFT) & FO_PCI_ERR_PME_EQNUM_MASK));
+	FIRE_PCI_SET(sc, FO_PCI_ERR_NONFATAL, FO_PCI_ERR_PME_V |
+	    ((j << FO_PCI_ERR_PME_EQNUM_SHFT) & FO_PCI_ERR_PME_EQNUM_MASK));
+	FIRE_PCI_SET(sc, FO_PCI_ERR_FATAL, FO_PCI_ERR_PME_V |
+	    ((j << FO_PCI_ERR_PME_EQNUM_SHFT) & FO_PCI_ERR_PME_EQNUM_MASK));
+	FIRE_PCI_SET(sc, FO_PCI_PM_PME, 0);
+	FIRE_PCI_SET(sc, FO_PCI_PME_TO_ACK, 0);
+	FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_SET_BASE + (j << 3),
+	    FO_PCI_EQ_CTRL_SET_EN);
+
+#define	TC_COUNTER_MAX_MASK	0xffffffff
+
+	/*
+	 * Setup JBC/UBC performance counter 0 in bus cycle counting
+	 * mode as timecounter.  Unfortunately, at least with Fire all
+	 * JBus-driven performance counters just don't advance in bus
+	 * cycle counting mode.
+	 */
+	if (device_get_unit(dev) == 0) {
+		FIRE_CTRL_SET(sc, FO_XBC_PRF_CNT0, 0);
+		FIRE_CTRL_SET(sc, FO_XBC_PRF_CNT1, 0);
+		FIRE_CTRL_SET(sc, FO_XBC_PRF_CNT_SEL,
+		    (FO_XBC_PRF_CNT_NONE << FO_XBC_PRF_CNT_CNT1_SHFT) |
+		    (FO_XBC_PRF_CNT_XB_CLK << FO_XBC_PRF_CNT_CNT0_SHFT));
+#ifdef FIRE_DEBUG
+		device_printf(dev, "FO_XBC_PRF_CNT0 0x%016llx\n",
+		    (long long unsigned)FIRE_CTRL_READ_8(sc,
+		    FO_XBC_PRF_CNT0));
+		device_printf(dev, "FO_XBC_PRF_CNT0 0x%016llx\n",
+		    (long long unsigned)FIRE_CTRL_READ_8(sc,
+		    FO_XBC_PRF_CNT0));
+#endif
+		tc = malloc(sizeof(*tc), M_DEVBUF, M_NOWAIT | M_ZERO);
+		if (tc == NULL)
+			panic("%s: could not malloc timecounter", __func__);
+		tc->tc_get_timecount = fire_get_timecount;
+		tc->tc_poll_pps = NULL;
+		tc->tc_counter_mask = TC_COUNTER_MAX_MASK;
+		if (OF_getprop(OF_peer(0), "clock-frequency", &prop,
+		    sizeof(prop)) == -1)
+			panic("%s: could not determine clock frequency",
+			    __func__);
+		tc->tc_frequency = prop;
+		tc->tc_name = strdup(device_get_nameunit(dev), M_DEVBUF);
+		tc->tc_quality = -FIRE_PERF_CNT_QLTY;
+		tc->tc_priv = sc;
+		tc_init(tc);
+	}
+
+	/*
+	 * Set up the IOMMU.  Both Fire and Oberon have one per PBM, but
+	 * neither has a streaming buffer.
+	 */
+	memcpy(&sc->sc_dma_methods, &iommu_dma_methods,
+	    sizeof(sc->sc_dma_methods));
+	sc->sc_is.is_flags = IOMMU_FIRE | IOMMU_PRESERVE_PROM;
+	if (sc->sc_mode == FIRE_MODE_OBERON) {
+		sc->sc_is.is_flags |= IOMMU_FLUSH_CACHE;
+		sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(OBERON_IOMMU_BITS);
+	} else {
+		sc->sc_dma_methods.dm_dmamap_sync = fire_dmamap_sync;
+		sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(FIRE_IOMMU_BITS);
+	}
+	sc->sc_is.is_sb[0] = sc->sc_is.is_sb[1] = 0;
+	/* Punch in our copies. */
+	sc->sc_is.is_bustag = rman_get_bustag(sc->sc_mem_res[FIRE_PCI]);
+	sc->sc_is.is_bushandle = rman_get_bushandle(sc->sc_mem_res[FIRE_PCI]);
+	sc->sc_is.is_iommu = FO_PCI_MMU;
+	val = FIRE_PCI_READ_8(sc, FO_PCI_MMU + IMR_CTL);
+	iommu_init(device_get_nameunit(sc->sc_dev), &sc->sc_is, 7, -1, 0);
+#ifdef FIRE_DEBUG
+	device_printf(dev, "FO_PCI_MMU + IMR_CTL 0x%016llx -> 0x%016llx\n",
+	    (long long unsigned)val, (long long unsigned)sc->sc_is.is_cr);
+#endif
+
+	/* Initialize memory and I/O rmans. */
+	sc->sc_pci_io_rman.rm_type = RMAN_ARRAY;
+	sc->sc_pci_io_rman.rm_descr = "Fire PCI I/O Ports";
+	if (rman_init(&sc->sc_pci_io_rman) != 0 ||
+	    rman_manage_region(&sc->sc_pci_io_rman, 0, FO_IO_SIZE) != 0)
+		panic("%s: failed to set up I/O rman", __func__);
+	sc->sc_pci_mem_rman.rm_type = RMAN_ARRAY;
+	sc->sc_pci_mem_rman.rm_descr = "Fire PCI Memory";
+	if (rman_init(&sc->sc_pci_mem_rman) != 0 ||
+	    rman_manage_region(&sc->sc_pci_mem_rman, 0, FO_MEM_SIZE) != 0)
+		panic("%s: failed to set up memory rman", __func__);
+
+	i = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
+	/*
+	 * Make sure that the expected ranges are present.  The
+	 * OFW_PCI_CS_MEM64 one is not currently used though.
+	 */
+	if (i != FIRE_NRANGE)
+		panic("%s: unsupported number of ranges", __func__);
+	/*
+	 * Find the addresses of the various bus spaces.
+	 * There should not be multiple ones of one kind.
+	 * The physical start addresses of the ranges are the configuration,
+	 * memory and I/O handles.
+	 */
+	for (i = 0; i < FIRE_NRANGE; i++) {
+		j = OFW_PCI_RANGE_CS(&range[i]);
+		if (sc->sc_pci_bh[j] != 0)
+			panic("%s: duplicate range for space %d",
+			    __func__, j);
+		sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]);
+	}
+	free(range, M_OFWPROP);
+
+	/* Allocate our tags. */
+	sc->sc_pci_memt = fire_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE);
+	sc->sc_pci_iot = fire_alloc_bus_tag(sc, PCI_IO_BUS_SPACE);
+	sc->sc_pci_cfgt = fire_alloc_bus_tag(sc, PCI_CONFIG_BUS_SPACE);
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
+	    sc->sc_is.is_pmaxaddr, ~0, NULL, NULL, sc->sc_is.is_pmaxaddr,
+	    0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0)
+		panic("%s: bus_dma_tag_create failed", __func__);
+	/* Customize the tag. */
+	sc->sc_pci_dmat->dt_cookie = &sc->sc_is;
+	sc->sc_pci_dmat->dt_mt = &sc->sc_dma_methods;
+
+	/*
+	 * Get the bus range from the firmware.
+	 * NB: Neither Fire nor Oberon support PCI bus reenumeration.
+	 */
+	i = OF_getprop(node, "bus-range", (void *)prop_array,
+	    sizeof(prop_array));
+	if (i == -1)
+		panic("%s: could not get bus-range", __func__);
+	if (i != sizeof(prop_array))
+		panic("%s: broken bus-range (%d)", __func__, i);
+	sc->sc_pci_secbus = prop_array[0];
+	sc->sc_pci_subbus = prop_array[1];
+	if (bootverbose != 0)
+		device_printf(dev, "bus range %u to %u; PCI bus %d\n",
+		    sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus);
+
+	ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t));
+
+#define	FIRE_SYSCTL_ADD_UINT(name, arg, desc)				\
+	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),			\
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,	\
+	    (name), CTLFLAG_RD, (arg), 0, (desc))
+
+	FIRE_SYSCTL_ADD_UINT("ilu_err", &sc->sc_stats_ilu_err,
+	    "ILU unknown errors");
+	FIRE_SYSCTL_ADD_UINT("jbc_ce_async", &sc->sc_stats_jbc_ce_async,
+	    "JBC correctable errors");
+	FIRE_SYSCTL_ADD_UINT("jbc_unsol_int", &sc->sc_stats_jbc_unsol_int,
+	    "JBC unsolicited interrupt ACK/NACK errors");
+	FIRE_SYSCTL_ADD_UINT("jbc_unsol_rd", &sc->sc_stats_jbc_unsol_rd,
+	    "JBC unsolicited read response errors");
+	FIRE_SYSCTL_ADD_UINT("mmu_err", &sc->sc_stats_mmu_err, "MMU errors");
+	FIRE_SYSCTL_ADD_UINT("tlu_ce", &sc->sc_stats_tlu_ce,
+	    "DLU/TLU correctable errors");
+	FIRE_SYSCTL_ADD_UINT("tlu_oe_non_fatal",
+	    &sc->sc_stats_tlu_oe_non_fatal,
+	    "DLU/TLU other event non-fatal errors summary"),
+	FIRE_SYSCTL_ADD_UINT("tlu_oe_rx_err", &sc->sc_stats_tlu_oe_rx_err,
+	    "DLU/TLU receive other event errors"),
+	FIRE_SYSCTL_ADD_UINT("tlu_oe_tx_err", &sc->sc_stats_tlu_oe_tx_err,
+	    "DLU/TLU transmit other event errors"),
+	FIRE_SYSCTL_ADD_UINT("ubc_dmardue", &sc->sc_stats_ubc_dmardue,
+	    "UBC DMARDUE erros");
+
+#undef FIRE_SYSCTL_ADD_UINT
+
+	device_add_child(dev, "pci", -1);
+	return (bus_generic_attach(dev));
+}
+
+static void
+fire_set_intr(struct fire_softc *sc, u_int index, u_int ino,
+    driver_filter_t handler, void *arg)
+{
+	u_long vec;
+	int rid;
+
+	rid = index;
+	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev,
+	    SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->sc_irq_res[index] == NULL ||
+	    INTINO(vec = rman_get_start(sc->sc_irq_res[index])) != ino ||
+	    INTIGN(vec) != sc->sc_ign ||
+	    intr_vectors[vec].iv_ic != &fire_ic ||
+	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
+	    INTR_TYPE_MISC | INTR_FAST, handler, NULL, arg,
+	    &sc->sc_ihand[index]) != 0)
+		panic("%s: failed to set up interrupt %d", __func__, index);
+}
+
+static int
+fire_intr_register(struct fire_softc *sc, u_int ino)
+{
+	struct fire_icarg *fica;
+	bus_addr_t intrclr, intrmap;
+	int error;
+
+	if (fire_get_intrmap(sc, ino, &intrmap, &intrclr) == 0)
+		return (ENXIO);
+	fica = malloc((ino >= FO_EQ_FIRST_INO && ino <= FO_EQ_LAST_INO) ?
+	    sizeof(struct fire_msiqarg) : sizeof(struct fire_icarg), M_DEVBUF,
+	    M_NOWAIT);
+	if (fica == NULL)
+		return (ENOMEM);
+	fica->fica_sc = sc;
+	fica->fica_map = intrmap;
+	fica->fica_clr = intrclr;
+	error = (intr_controller_register(INTMAP_VEC(sc->sc_ign, ino),
+	    &fire_ic, fica));
+	if (error != 0)
+		free(fica, M_DEVBUF);
+	return (error);
+}
+
+static int
+fire_get_intrmap(struct fire_softc *sc, u_int ino, bus_addr_t *intrmapptr,
+    bus_addr_t *intrclrptr)
+{
+
+	if (ino > FO_MAX_INO) {
+		device_printf(sc->sc_dev, "out of range INO %d requested\n",
+		    ino);
+		return (0);
+	}
+
+	ino <<= 3;
+	if (intrmapptr != NULL)
+		*intrmapptr = FO_PCI_INT_MAP_BASE + ino;
+	if (intrclrptr != NULL)
+		*intrclrptr = FO_PCI_INT_CLR_BASE + ino;
+	return (1);
+}
+
+/*
+ * Interrupt handlers
+ */
+static int
+fire_dmc_pec(void *arg)
+{
+	struct fire_softc *sc;
+	device_t dev;
+	uint64_t cestat, dmcstat, ilustat, imustat, mcstat, mmustat, mmutfar;
+	uint64_t mmutfsr, oestat, pecstat, uestat, val;
+	u_int fatal, oenfatal;
+
+	fatal = 0;
+	sc = arg;
+	dev = sc->sc_dev;
+	mtx_lock_spin(&sc->sc_pcib_mtx);
+	mcstat = FIRE_PCI_READ_8(sc, FO_PCI_MULTI_CORE_ERR_STAT);
+	if ((mcstat & FO_PCI_MULTI_CORE_ERR_STAT_DMC) != 0) {
+		dmcstat = FIRE_PCI_READ_8(sc, FO_PCI_DMC_CORE_BLOCK_ERR_STAT);
+		if ((dmcstat & FO_PCI_DMC_CORE_BLOCK_INT_EN_IMU) != 0) {
+			imustat = FIRE_PCI_READ_8(sc, FO_PCI_IMU_INT_STAT);
+			device_printf(dev, "IMU error %#llx\n",
+			    (unsigned long long)imustat);
+			if ((imustat &
+			    FO_PCI_IMU_ERR_INT_EQ_NOT_EN_P) != 0) {
+				fatal = 1;
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_IMU_SCS_ERR_LOG);
+				device_printf(dev, "SCS error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((imustat & FO_PCI_IMU_ERR_INT_EQ_OVER_P) != 0) {
+				fatal = 1;
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_IMU_EQS_ERR_LOG);
+				device_printf(dev, "EQS error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((imustat & (FO_PCI_IMU_ERR_INT_MSI_MAL_ERR_P |
+			    FO_PCI_IMU_ERR_INT_MSI_PAR_ERR_P |
+			    FO_PCI_IMU_ERR_INT_PMEACK_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_PMPME_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_P |
+			    FO_PCI_IMU_ERR_INT_MSI_NOT_EN_P)) != 0) {
+				fatal = 1;
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_IMU_RDS_ERR_LOG);
+				device_printf(dev, "RDS error log %#llx\n",
+				    (unsigned long long)val);
+			}
+		}
+		if ((dmcstat & FO_PCI_DMC_CORE_BLOCK_INT_EN_MMU) != 0) {
+			fatal = 1;
+			mmustat = FIRE_PCI_READ_8(sc, FO_PCI_MMU_INT_STAT);
+			mmutfar = FIRE_PCI_READ_8(sc,
+			    FO_PCI_MMU_TRANS_FAULT_ADDR);
+			mmutfsr = FIRE_PCI_READ_8(sc,
+			    FO_PCI_MMU_TRANS_FAULT_STAT);
+			if ((mmustat & (FO_PCI_MMU_ERR_INT_TBW_DPE_P |
+			    FO_PCI_MMU_ERR_INT_TBW_ERR_P |
+			    FO_PCI_MMU_ERR_INT_TBW_UDE_P |
+			    FO_PCI_MMU_ERR_INT_TBW_DME_P |
+			    FO_PCI_MMU_ERR_INT_TTC_CAE_P |
+			    FIRE_PCI_MMU_ERR_INT_TTC_DPE_P |
+			    OBERON_PCI_MMU_ERR_INT_TTC_DUE_P |
+			    FO_PCI_MMU_ERR_INT_TRN_ERR_P)) != 0)
+				fatal = 1;
+			else {
+				sc->sc_stats_mmu_err++;
+				FIRE_PCI_WRITE_8(sc, FO_PCI_MMU_ERR_STAT_CLR,
+				    mmustat);
+			}
+			device_printf(dev,
+			    "MMU error %#llx: TFAR %#llx TFSR %#llx\n",
+			    (unsigned long long)mmustat,
+			    (unsigned long long)mmutfar,
+			    (unsigned long long)mmutfsr);
+		}
+	}
+	if ((mcstat & FO_PCI_MULTI_CORE_ERR_STAT_PEC) != 0) {
+		pecstat = FIRE_PCI_READ_8(sc, FO_PCI_PEC_CORE_BLOCK_INT_STAT);
+		if ((pecstat & FO_PCI_PEC_CORE_BLOCK_INT_STAT_UERR) != 0) {
+			fatal = 1;
+			uestat = FIRE_PCI_READ_8(sc,
+			    FO_PCI_TLU_UERR_INT_STAT);
+			device_printf(dev,
+			    "DLU/TLU uncorrectable error %#llx\n",
+			    (unsigned long long)uestat);
+			if ((uestat & (FO_PCI_TLU_UERR_INT_UR_P |
+			    OBERON_PCI_TLU_UERR_INT_POIS_P |
+			    FO_PCI_TLU_UERR_INT_MFP_P |
+			    FO_PCI_TLU_UERR_INT_ROF_P |
+			    FO_PCI_TLU_UERR_INT_UC_P |
+			    FIRE_PCI_TLU_UERR_INT_PP_P |
+			    OBERON_PCI_TLU_UERR_INT_POIS_P)) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_RX_UERR_HDR1_LOG);
+				device_printf(dev,
+				    "receive header log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_RX_UERR_HDR2_LOG);
+				device_printf(dev,
+				    "receive header log 2 %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((uestat & FO_PCI_TLU_UERR_INT_CTO_P) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_TX_UERR_HDR1_LOG);
+				device_printf(dev,
+				    "transmit header log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_TX_UERR_HDR2_LOG);
+				device_printf(dev,
+				    "transmit header log 2 %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((uestat & FO_PCI_TLU_UERR_INT_DLP_P) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_LPU_LNK_LYR_INT_STAT);
+				device_printf(dev,
+				    "link layer interrupt and status %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((uestat & FO_PCI_TLU_UERR_INT_TE_P) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_LPU_PHY_LYR_INT_STAT);
+				device_printf(dev,
+				    "phy layer interrupt and status %#llx\n",
+				    (unsigned long long)val);
+			}
+		}
+		if ((pecstat & FO_PCI_PEC_CORE_BLOCK_INT_STAT_CERR) != 0) {
+			sc->sc_stats_tlu_ce++;
+			cestat = FIRE_PCI_READ_8(sc,
+			    FO_PCI_TLU_CERR_INT_STAT);
+			device_printf(dev,
+			    "DLU/TLU correctable error %#llx\n",
+			    (unsigned long long)cestat);
+			val = FIRE_PCI_READ_8(sc,
+			    FO_PCI_LPU_LNK_LYR_INT_STAT);
+			device_printf(dev,
+			    "link layer interrupt and status %#llx\n",
+			    (unsigned long long)val);
+			if ((cestat & FO_PCI_TLU_CERR_INT_RE_P) != 0) {
+				FIRE_PCI_WRITE_8(sc,
+				    FO_PCI_LPU_LNK_LYR_INT_STAT, val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_LPU_PHY_LYR_INT_STAT);
+				device_printf(dev,
+				    "phy layer interrupt and status %#llx\n",
+				    (unsigned long long)val);
+			}
+			FIRE_PCI_WRITE_8(sc, FO_PCI_TLU_CERR_STAT_CLR,
+			    cestat);
+		}
+		if ((pecstat & FO_PCI_PEC_CORE_BLOCK_INT_STAT_OEVENT) != 0) {
+			oenfatal = 0;
+			oestat = FIRE_PCI_READ_8(sc,
+			    FO_PCI_TLU_OEVENT_INT_STAT);
+			device_printf(dev, "DLU/TLU other event %#llx\n",
+			    (unsigned long long)oestat);
+			if ((oestat & (FO_PCI_TLU_OEVENT_MFC_P |
+			    FO_PCI_TLU_OEVENT_MRC_P |
+			    FO_PCI_TLU_OEVENT_WUC_P |
+			    FO_PCI_TLU_OEVENT_RUC_P |
+			    FO_PCI_TLU_OEVENT_CRS_P)) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_RX_OEVENT_HDR1_LOG);
+				device_printf(dev,
+				    "receive header log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_RX_OEVENT_HDR2_LOG);
+				device_printf(dev,
+				    "receive header log 2 %#llx\n",
+				    (unsigned long long)val);
+				if ((oestat & (FO_PCI_TLU_OEVENT_MFC_P |
+				    FO_PCI_TLU_OEVENT_MRC_P |
+				    FO_PCI_TLU_OEVENT_WUC_P |
+				    FO_PCI_TLU_OEVENT_RUC_P)) != 0)
+					fatal = 1;
+				else {
+					sc->sc_stats_tlu_oe_rx_err++;
+					oenfatal = 1;
+				}
+			}
+			if ((oestat & (FO_PCI_TLU_OEVENT_MFC_P |
+			    FO_PCI_TLU_OEVENT_CTO_P |
+			    FO_PCI_TLU_OEVENT_WUC_P |
+			    FO_PCI_TLU_OEVENT_RUC_P)) != 0) {
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_TX_OEVENT_HDR1_LOG);
+				device_printf(dev,
+				    "transmit header log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_TLU_TX_OEVENT_HDR2_LOG);
+				device_printf(dev,
+				    "transmit header log 2 %#llx\n",
+				    (unsigned long long)val);
+				if ((oestat & (FO_PCI_TLU_OEVENT_MFC_P |
+				    FO_PCI_TLU_OEVENT_CTO_P |
+				    FO_PCI_TLU_OEVENT_WUC_P |
+				    FO_PCI_TLU_OEVENT_RUC_P)) != 0)
+					fatal = 1;
+				else {
+					sc->sc_stats_tlu_oe_tx_err++;
+					oenfatal = 1;
+				}
+			}
+			if ((oestat & (FO_PCI_TLU_OEVENT_ERO_P |
+			    FO_PCI_TLU_OEVENT_EMP_P |
+			    FO_PCI_TLU_OEVENT_EPE_P |
+			    FIRE_PCI_TLU_OEVENT_ERP_P |
+			    OBERON_PCI_TLU_OEVENT_ERBU_P |
+			    FIRE_PCI_TLU_OEVENT_EIP_P |
+			    OBERON_PCI_TLU_OEVENT_EIUE_P)) != 0) {
+				fatal = 1;
+				val = FIRE_PCI_READ_8(sc,
+				    FO_PCI_LPU_LNK_LYR_INT_STAT);
+				device_printf(dev,
+				    "link layer interrupt and status %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((oestat & (FO_PCI_TLU_OEVENT_IIP_P |
+			    FO_PCI_TLU_OEVENT_EDP_P |
+			    FIRE_PCI_TLU_OEVENT_EHP_P |
+			    OBERON_PCI_TLU_OEVENT_TLUEITMO_S |
+			    FO_PCI_TLU_OEVENT_ERU_P)) != 0)
+				fatal = 1;
+			if ((oestat & (FO_PCI_TLU_OEVENT_NFP_P |
+			    FO_PCI_TLU_OEVENT_LWC_P |
+			    FO_PCI_TLU_OEVENT_LIN_P |
+			    FO_PCI_TLU_OEVENT_LRS_P |
+			    FO_PCI_TLU_OEVENT_LDN_P |
+			    FO_PCI_TLU_OEVENT_LUP_P)) != 0)
+				oenfatal = 1;
+			if (oenfatal != 0) {
+				sc->sc_stats_tlu_oe_non_fatal++;
+				FIRE_PCI_WRITE_8(sc,
+				    FO_PCI_TLU_OEVENT_STAT_CLR, oestat);
+				if ((oestat & FO_PCI_TLU_OEVENT_LIN_P) != 0)
+					FIRE_PCI_WRITE_8(sc,
+					    FO_PCI_LPU_LNK_LYR_INT_STAT,
+					    FIRE_PCI_READ_8(sc,
+					    FO_PCI_LPU_LNK_LYR_INT_STAT));
+			}
+		}
+		if ((pecstat & FO_PCI_PEC_CORE_BLOCK_INT_STAT_ILU) != 0) {
+			ilustat = FIRE_PCI_READ_8(sc, FO_PCI_ILU_INT_STAT);
+			device_printf(dev, "ILU error %#llx\n",
+			    (unsigned long long)ilustat);
+			if ((ilustat & (FIRE_PCI_ILU_ERR_INT_IHB_PE_P |
+			    FIRE_PCI_ILU_ERR_INT_IHB_PE_P)) != 0)
+			    fatal = 1;
+			else {
+				sc->sc_stats_ilu_err++;
+				FIRE_PCI_WRITE_8(sc, FO_PCI_ILU_INT_STAT,
+				    ilustat);
+			}
+		}
+	}
+	mtx_unlock_spin(&sc->sc_pcib_mtx);
+	if (fatal != 0)
+		panic("%s: fatal DMC/PEC error",
+		    device_get_nameunit(sc->sc_dev));
+	return (FILTER_HANDLED);
+}
+
+static int
+fire_xcb(void *arg)
+{
+	struct fire_softc *sc;
+	device_t dev;
+	uint64_t errstat, intstat, val;
+	u_int fatal;
+
+	fatal = 0;
+	sc = arg;
+	dev = sc->sc_dev;
+	mtx_lock_spin(&sc->sc_pcib_mtx);
+	if (sc->sc_mode == FIRE_MODE_OBERON) {
+		intstat = FIRE_CTRL_READ_8(sc, FO_XBC_INT_STAT);
+		device_printf(dev, "UBC error: interrupt status %#llx\n",
+		    (unsigned long long)intstat);
+		if ((intstat & ~(OBERON_UBC_ERR_INT_DMARDUEB_P |
+		    OBERON_UBC_ERR_INT_DMARDUEA_P)) != 0)
+			fatal = 1;
+		else
+			sc->sc_stats_ubc_dmardue++;
+		if (fatal != 0) {
+			mtx_unlock_spin(&sc->sc_pcib_mtx);
+			panic("%s: fatal UBC core block error",
+			    device_get_nameunit(sc->sc_dev));
+		} else {
+			FIRE_CTRL_SET(sc, FO_XBC_ERR_STAT_CLR, ~0ULL);
+			mtx_unlock_spin(&sc->sc_pcib_mtx);
+		}
+	} else {
+		errstat = FIRE_CTRL_READ_8(sc, FIRE_JBC_CORE_BLOCK_ERR_STAT);
+		if ((errstat & (FIRE_JBC_CORE_BLOCK_ERR_STAT_MERGE |
+		    FIRE_JBC_CORE_BLOCK_ERR_STAT_JBCINT |
+		    FIRE_JBC_CORE_BLOCK_ERR_STAT_DMCINT)) != 0) {
+			intstat = FIRE_CTRL_READ_8(sc, FO_XBC_INT_STAT);
+			device_printf(dev, "JBC interrupt status %#llx\n",
+			    (unsigned long long)intstat);
+			if ((intstat & FIRE_JBC_ERR_INT_EBUS_TO_P) != 0) {
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBC_CSR_ERR_LOG);
+				device_printf(dev, "CSR error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_UNSOL_RD_P |
+			    FIRE_JBC_ERR_INT_UNSOL_INT_P)) != 0) {
+				if ((intstat &
+				    FIRE_JBC_ERR_INT_UNSOL_RD_P) != 0)
+					sc->sc_stats_jbc_unsol_rd++;
+				if ((intstat &
+				    FIRE_JBC_ERR_INT_UNSOL_INT_P) != 0)
+					sc->sc_stats_jbc_unsol_int++;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_DMCINT_IDC_ERR_LOG);
+				device_printf(dev,
+				    "DMCINT IDC error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_MB_PER_P |
+			    FIRE_JBC_ERR_INT_MB_PEW_P)) != 0) {
+				fatal = 1;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_MERGE_TRANS_ERR_LOG);
+				device_printf(dev,
+				    "merge transaction error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((intstat & FIRE_JBC_ERR_INT_IJP_P) != 0) {
+				fatal = 1;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBCINT_OTRANS_ERR_LOG);
+				device_printf(dev,
+				    "JBCINT out transaction error log "
+				    "%#llx\n", (unsigned long long)val);
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBCINT_OTRANS_ERR_LOG2);
+				device_printf(dev,
+				    "JBCINT out transaction error log 2 "
+				    "%#llx\n", (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_UE_ASYN_P |
+			    FIRE_JBC_ERR_INT_CE_ASYN_P |
+			    FIRE_JBC_ERR_INT_JTE_P | FIRE_JBC_ERR_INT_JBE_P |
+			    FIRE_JBC_ERR_INT_JUE_P |
+			    FIRE_JBC_ERR_INT_ICISE_P |
+			    FIRE_JBC_ERR_INT_WR_DPE_P |
+			    FIRE_JBC_ERR_INT_RD_DPE_P |
+			    FIRE_JBC_ERR_INT_ILL_BMW_P |
+			    FIRE_JBC_ERR_INT_ILL_BMR_P |
+			    FIRE_JBC_ERR_INT_BJC_P)) != 0) {
+				if ((intstat & (FIRE_JBC_ERR_INT_UE_ASYN_P |
+				    FIRE_JBC_ERR_INT_JTE_P |
+				    FIRE_JBC_ERR_INT_JBE_P |
+				    FIRE_JBC_ERR_INT_JUE_P |
+				    FIRE_JBC_ERR_INT_ICISE_P |
+				    FIRE_JBC_ERR_INT_WR_DPE_P |
+				    FIRE_JBC_ERR_INT_RD_DPE_P |
+				    FIRE_JBC_ERR_INT_ILL_BMW_P |
+				    FIRE_JBC_ERR_INT_ILL_BMR_P |
+				    FIRE_JBC_ERR_INT_BJC_P)) != 0)
+					fatal = 1;
+				else
+					sc->sc_stats_jbc_ce_async++;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBCINT_ITRANS_ERR_LOG);
+				device_printf(dev,
+				    "JBCINT in transaction error log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBCINT_ITRANS_ERR_LOG2);
+				device_printf(dev,
+				    "JBCINT in transaction error log 2 "
+				    "%#llx\n", (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_PIO_UNMAP_RD_P |
+			    FIRE_JBC_ERR_INT_ILL_ACC_RD_P |
+			    FIRE_JBC_ERR_INT_PIO_UNMAP_P |
+			    FIRE_JBC_ERR_INT_PIO_DPE_P |
+			    FIRE_JBC_ERR_INT_PIO_CPE_P |
+			    FIRE_JBC_ERR_INT_ILL_ACC_P)) != 0) {
+				fatal = 1;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_JBC_CSR_ERR_LOG);
+				device_printf(dev,
+				    "DMCINT ODCD error log %#llx\n",
+				    (unsigned long long)val);
+			}
+			if ((intstat & (FIRE_JBC_ERR_INT_MB_PEA_P |
+			    FIRE_JBC_ERR_INT_CPE_P | FIRE_JBC_ERR_INT_APE_P |
+			    FIRE_JBC_ERR_INT_PIO_CPE_P |
+			    FIRE_JBC_ERR_INT_JTCEEW_P |
+			    FIRE_JBC_ERR_INT_JTCEEI_P |
+			    FIRE_JBC_ERR_INT_JTCEER_P)) != 0) {
+				fatal = 1;
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_FATAL_ERR_LOG);
+				device_printf(dev, "fatal error log %#llx\n",
+				    (unsigned long long)val);
+				val = FIRE_CTRL_READ_8(sc,
+				    FIRE_FATAL_ERR_LOG2);
+				device_printf(dev, "fatal error log 2 "
+				    "%#llx\n", (unsigned long long)val);
+			}
+			if (fatal != 0) {
+				mtx_unlock_spin(&sc->sc_pcib_mtx);
+				panic("%s: fatal JBC core block error",
+				    device_get_nameunit(sc->sc_dev));
+			} else {
+				FIRE_CTRL_SET(sc, FO_XBC_ERR_STAT_CLR, ~0ULL);
+				mtx_unlock_spin(&sc->sc_pcib_mtx);
+			}
+		} else {
+			mtx_unlock_spin(&sc->sc_pcib_mtx);
+			panic("%s: unknown JCB core block error status %#llx",
+			    device_get_nameunit(sc->sc_dev),
+			    (unsigned long long)errstat);
+		}
+	}
+	return (FILTER_HANDLED);
+}
+
+static int
+fire_pcie(void *arg)
+{
+	struct fire_msiqarg *fmqa;
+	struct fire_softc *sc;
+	struct fo_msiq_record *qrec;
+	device_t dev;
+	uint64_t word0;
+	u_int head, msg, msiq;
+
+	fmqa = arg;
+	sc = fmqa->fmqa_fica.fica_sc;
+	dev = sc->sc_dev;
+	msiq = fmqa->fmqa_msiq;
+	mtx_lock_spin(&fmqa->fmqa_mtx);
+	head = (FIRE_PCI_READ_8(sc, fmqa->fmqa_head) & FO_PCI_EQ_HD_MASK) >>
+	    FO_PCI_EQ_HD_SHFT;
+	qrec = &fmqa->fmqa_base[head];
+	word0 = qrec->fomqr_word0;
+	for (;;) {
+		KASSERT((word0 & FO_MQR_WORD0_FMT_TYPE_MSG) != 0,
+		    ("%s: received non-PCIe message in event queue %d "
+		    "(word0 %#llx)", device_get_nameunit(dev), msiq,
+		    (unsigned long long)word0));
+		msg = (word0 & FO_MQR_WORD0_DATA0_MASK) >>
+		    FO_MQR_WORD0_DATA0_SHFT;
+
+#define	PCIE_MSG_CODE_ERR_COR		0x30
+#define	PCIE_MSG_CODE_ERR_NONFATAL	0x31
+#define	PCIE_MSG_CODE_ERR_FATAL		0x33
+
+		if (msg == PCIE_MSG_CODE_ERR_COR)
+			device_printf(dev, "correctable PCIe error\n");
+		else if (msg == PCIE_MSG_CODE_ERR_NONFATAL ||
+		    msg == PCIE_MSG_CODE_ERR_FATAL)
+			panic("%s: %sfatal PCIe error",
+			    device_get_nameunit(dev),
+			    msg == PCIE_MSG_CODE_ERR_NONFATAL ? "non-" : "");
+		else
+			panic("%s: received unknown PCIe message %#x",
+			    device_get_nameunit(dev), msg);
+		qrec->fomqr_word0 &= ~FO_MQR_WORD0_FMT_TYPE_MASK;
+		head = (head + 1) % sc->sc_msiq_size;
+		qrec = &fmqa->fmqa_base[head];
+		word0 = qrec->fomqr_word0;
+		if (__predict_true((word0 & FO_MQR_WORD0_FMT_TYPE_MASK) == 0))
+			break;
+	}
+	FIRE_PCI_WRITE_8(sc, fmqa->fmqa_head, (head & FO_PCI_EQ_HD_MASK) <<
+	    FO_PCI_EQ_HD_SHFT);
+	if ((FIRE_PCI_READ_8(sc, fmqa->fmqa_tail) &
+	    FO_PCI_EQ_TL_OVERR) != 0) {
+		device_printf(dev, "event queue %d overflow\n", msiq);
+		msiq <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq,
+		    FIRE_PCI_READ_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq) |
+		    FO_PCI_EQ_CTRL_CLR_COVERR);
+	}
+	mtx_unlock_spin(&fmqa->fmqa_mtx);
+	return (FILTER_HANDLED);
+}
+
+static int
+fire_maxslots(device_t dev)
+{
+
+	return (1);
+}
+
+static uint32_t
+fire_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
+    int width)
+{
+	struct fire_softc *sc;
+	bus_space_handle_t bh;
+	u_long offset = 0;
+	uint32_t r, wrd;
+	int i;
+	uint16_t shrt;
+	uint8_t byte;
+
+	sc = device_get_softc(dev);
+	if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+	    slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCIE_REGMAX)
+		return (-1);
+
+	offset = FO_CONF_OFF(bus, slot, func, reg);
+	bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
+	switch (width) {
+	case 1:
+		i = bus_space_peek_1(sc->sc_pci_cfgt, bh, offset, &byte);
+		r = byte;
+		break;
+	case 2:
+		i = bus_space_peek_2(sc->sc_pci_cfgt, bh, offset, &shrt);
+		r = shrt;
+		break;
+	case 4:
+		i = bus_space_peek_4(sc->sc_pci_cfgt, bh, offset, &wrd);
+		r = wrd;
+		break;
+	default:
+		panic("%s: bad width", __func__);
+		/* NOTREACHED */
+	}
+
+	if (i) {
+#ifdef FIRE_DEBUG
+		printf("%s: read data error reading: %d.%d.%d: 0x%x\n",
+		    __func__, bus, slot, func, reg);
+#endif
+		r = -1;
+	}
+	return (r);
+}
+
+static void
+fire_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
+    uint32_t val, int width)
+{
+	struct fire_softc *sc;
+	bus_space_handle_t bh;
+	u_long offset = 0;
+
+	sc = device_get_softc(dev);
+	if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+	    slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCIE_REGMAX)
+		return;
+
+	offset = FO_CONF_OFF(bus, slot, func, reg);
+	bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
+	switch (width) {
+	case 1:
+		bus_space_write_1(sc->sc_pci_cfgt, bh, offset, val);
+		break;
+	case 2:
+		bus_space_write_2(sc->sc_pci_cfgt, bh, offset, val);
+		break;
+	case 4:
+		bus_space_write_4(sc->sc_pci_cfgt, bh, offset, val);
+		break;
+	default:
+		panic("%s: bad width", __func__);
+		/* NOTREACHED */
+	}
+}
+
+static int
+fire_route_interrupt(device_t bridge, device_t dev, int pin)
+{
+	struct fire_softc *sc;
+	struct ofw_pci_register reg;
+	ofw_pci_intr_t pintr, mintr;
+	uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
+
+	sc = device_get_softc(bridge);
+	pintr = pin;
+	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
+	    ®, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
+	    maskbuf) != 0)
+		return (mintr);
+
+	device_printf(bridge, "could not route pin %d for device %d.%d\n",
+	    pin, pci_get_slot(dev), pci_get_function(dev));
+	return (PCI_INVALID_IRQ);
+}
+
+static int
+fire_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct fire_softc *sc;
+
+	sc = device_get_softc(dev);
+	switch (which) {
+	case PCIB_IVAR_DOMAIN:
+		*result = device_get_unit(dev);
+		return (0);
+	case PCIB_IVAR_BUS:
+		*result = sc->sc_pci_secbus;
+		return (0);
+	}
+	return (ENOENT);
+}
+
+#define	VIS_BLOCKSIZE	64
+
+static void
+fire_dmamap_sync(bus_dma_tag_t dt __unused, bus_dmamap_t map,
+    bus_dmasync_op_t op)
+{
+	static u_char buf[VIS_BLOCKSIZE] __aligned(VIS_BLOCKSIZE);
+	register_t reg, s;
+
+	if ((map->dm_flags & DMF_LOADED) == 0 ||
+	    (op & ~BUS_DMASYNC_POSTWRITE) == 0)
+		return;
+
+	s = intr_disable();
+	reg = rd(fprs);
+	wr(fprs, reg | FPRS_FEF, 0);
+	__asm __volatile("stda %%f0, [%0] %1"
+	    : : "r" (buf), "n" (ASI_BLK_COMMIT_S));
+	membar(Sync);
+	wr(fprs, reg, 0);
+	intr_restore(s);
+}
+
+static void
+fire_intr_enable(void *arg)
+{
+	struct intr_vector *iv;
+	struct fire_icarg *fica;
+	struct fire_softc *sc;
+	struct pcpu *pc;
+	uint64_t mr;
+	u_int ctrl, i;
+
+	iv = arg;
+	fica = iv->iv_icarg;
+	sc = fica->fica_sc;
+	mr = FO_PCI_IMAP_V;
+	if (sc->sc_mode == FIRE_MODE_OBERON)
+		mr |= (iv->iv_mid << OBERON_PCI_IMAP_T_DESTID_SHFT) &
+		    OBERON_PCI_IMAP_T_DESTID_MASK;
+	else
+		mr |= (iv->iv_mid << FIRE_PCI_IMAP_T_JPID_SHFT) &
+		    FIRE_PCI_IMAP_T_JPID_MASK;
+	/*
+	 * Given that all mondos for the same target are required to use the
+	 * same interrupt controller we just use the CPU ID for indexing the
+	 * latter.
+	 */
+	ctrl = 0;
+	for (i = 0; i < mp_ncpus; ++i) {
+		pc = pcpu_find(i);
+		if (pc == NULL || iv->iv_mid != pc->pc_mid)
+			continue;
+		ctrl = pc->pc_cpuid % 4;
+		break;
+	}
+	mr |= (1ULL << ctrl) << FO_PCI_IMAP_INT_CTRL_NUM_SHFT &
+	    FO_PCI_IMAP_INT_CTRL_NUM_MASK;
+	FIRE_PCI_WRITE_8(sc, fica->fica_map, mr);
+}
+
+static void
+fire_intr_disable(void *arg)
+{
+	struct intr_vector *iv;
+	struct fire_icarg *fica;
+	struct fire_softc *sc;
+
+	iv = arg;
+	fica = iv->iv_icarg;
+	sc = fica->fica_sc;
+	FIRE_PCI_WRITE_8(sc, fica->fica_map,
+	    FIRE_PCI_READ_8(sc, fica->fica_map) & ~FO_PCI_IMAP_V);
+}
+
+static void
+fire_intr_assign(void *arg)
+{
+	struct intr_vector *iv;
+	struct fire_icarg *fica;
+	struct fire_softc *sc;
+	uint64_t mr;
+
+	iv = arg;
+	fica = iv->iv_icarg;
+	sc = fica->fica_sc;
+	mr = FIRE_PCI_READ_8(sc, fica->fica_map);
+	if ((mr & FO_PCI_IMAP_V) != 0) {
+		FIRE_PCI_WRITE_8(sc, fica->fica_map, mr & ~FO_PCI_IMAP_V);
+		FIRE_PCI_BARRIER(sc, fica->fica_map, 8,
+		    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
+	}
+	while (FIRE_PCI_READ_8(sc, fica->fica_clr) != INTCLR_IDLE)
+		;
+	if ((mr & FO_PCI_IMAP_V) != 0)
+		fire_intr_enable(arg);
+}
+
+static void
+fire_intr_clear(void *arg)
+{
+	struct intr_vector *iv;
+	struct fire_icarg *fica;
+
+	iv = arg;
+	fica = iv->iv_icarg;
+	FIRE_PCI_WRITE_8(fica->fica_sc, fica->fica_clr, INTCLR_IDLE);
+}
+
+/*
+ * Given that the event queue implementation matches our current MD and MI
+ * interrupt frameworks like square pegs fit into round holes we are generous
+ * and use one event queue per MSI for now, which limits us to 35 MSIs/MSI-Xs
+ * per Host-PCIe-bridge (we use one event queue for the PCIe error messages).
+ * This seems tolerable as long as most devices just use one MSI/MSI-X anyway.
+ * Adding knowledge about MSIs/MSI-Xs to the MD interrupt code should allow us
+ * to decouple the 1:1 mapping at the cost of no longer being able to bind
+ * MSIs/MSI-Xs to specific CPUs as we currently have no reliable way to
+ * quiesce a device while we move its MSIs/MSI-Xs to another event queue.
+ */
+
+static int
+fire_alloc_msi(device_t dev, device_t child, int count, int maxcount __unused,
+    int *irqs)
+{
+	struct fire_softc *sc;
+	u_int i, j, msiqrun;
+
+	if (powerof2(count) == 0 || count > 32)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+	mtx_lock(&sc->sc_msi_mtx);
+	msiqrun = 0;
+	for (i = 0; i < sc->sc_msiq_count; i++) {
+		for (j = i; j < i + count; j++) {
+			if (isclr(sc->sc_msiq_bitmap, j) == 0)
+				break;
+		}
+		if (j == i + count) {
+			msiqrun = i;
+			break;
+		}
+	}
+	if (i == sc->sc_msiq_count) {
+		mtx_unlock(&sc->sc_msi_mtx);
+		return (ENXIO);
+	}
+	for (i = 0; i + count < sc->sc_msi_count; i += count) {
+		for (j = i; j < i + count; j++)
+			if (isclr(sc->sc_msi_bitmap, j) == 0)
+				break;
+		if (j == i + count) {
+			for (j = 0; j < count; j++) {
+				setbit(sc->sc_msiq_bitmap, msiqrun + j);
+				setbit(sc->sc_msi_bitmap, i + j);
+				sc->sc_msi_msiq_table[i + j] = msiqrun + j;
+				irqs[j] = sc->sc_msi_first + i + j;
+			}
+			mtx_unlock(&sc->sc_msi_mtx);
+			return (0);
+		}
+	}
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (ENXIO);
+}
+
+static int
+fire_release_msi(device_t dev, device_t child, int count, int *irqs)
+{
+	struct fire_softc *sc;
+	u_int i;
+
+	sc = device_get_softc(dev);
+	mtx_lock(&sc->sc_msi_mtx);
+	for (i = 0; i < count; i++) {
+		clrbit(sc->sc_msiq_bitmap,
+		    sc->sc_msi_msiq_table[irqs[i] - sc->sc_msi_first]);
+		clrbit(sc->sc_msi_bitmap, irqs[i] - sc->sc_msi_first);
+	}
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (0);
+}
+
+static int
+fire_alloc_msix(device_t dev, device_t child, int *irq)
+{
+	struct fire_softc *sc;
+	u_int i, msiq;
+
+	sc = device_get_softc(dev);
+	if ((sc->sc_flags & FIRE_MSIX) == 0)
+		return (ENXIO);
+	mtx_lock(&sc->sc_msi_mtx);
+	msiq = 0;
+	for (i = 0; i < sc->sc_msiq_count; i++) {
+		if (isclr(sc->sc_msiq_bitmap, i) != 0) {
+			msiq = i;
+			break;
+		}
+	}
+	if (i == sc->sc_msiq_count) {
+		mtx_unlock(&sc->sc_msi_mtx);
+		return (ENXIO);
+	}
+	for (i = sc->sc_msi_count - 1; i >= 0; i--) {
+		if (isclr(sc->sc_msi_bitmap, i) != 0) {
+			setbit(sc->sc_msiq_bitmap, msiq);
+			setbit(sc->sc_msi_bitmap, i);
+			sc->sc_msi_msiq_table[i] = msiq;
+			*irq = sc->sc_msi_first + i;
+			mtx_unlock(&sc->sc_msi_mtx);
+			return (0);
+		}
+	}
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (ENXIO);
+}
+
+static int
+fire_release_msix(device_t dev, device_t child, int irq)
+{
+	struct fire_softc *sc;
+
+	sc = device_get_softc(dev);
+	if ((sc->sc_flags & FIRE_MSIX) == 0)
+		return (ENXIO);
+	mtx_lock(&sc->sc_msi_mtx);
+	clrbit(sc->sc_msiq_bitmap,
+	    sc->sc_msi_msiq_table[irq - sc->sc_msi_first]);
+	clrbit(sc->sc_msi_bitmap, irq - sc->sc_msi_first);
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (0);
+}
+
+static int
+fire_map_msi(device_t dev, device_t child, int irq, uint64_t *addr,
+    uint32_t *data)
+{
+	struct fire_softc *sc;
+	struct pci_devinfo *dinfo;
+
+	sc = device_get_softc(dev);
+	dinfo = device_get_ivars(child);
+	if (dinfo->cfg.msi.msi_alloc > 0) {
+		if ((irq & ~sc->sc_msi_data_mask) != 0) {
+			device_printf(dev, "invalid MSI 0x%x\n", irq);
+			return (EINVAL);
+		}
+	} else {
+		if ((sc->sc_flags & FIRE_MSIX) == 0)
+			return (ENXIO);
+		if (fls(irq) > sc->sc_msix_data_width) {
+			device_printf(dev, "invalid MSI-X 0x%x\n", irq);
+			return (EINVAL);
+		}
+	}
+	if (dinfo->cfg.msi.msi_alloc > 0 &&
+	    (dinfo->cfg.msi.msi_ctrl & PCIM_MSICTRL_64BIT) == 0)
+		*addr = sc->sc_msi_addr32;
+	else
+		*addr = sc->sc_msi_addr64;
+	*data = irq;
+	return (0);
+}
+
+static void
+fire_msiq_handler(void *cookie)
+{
+	struct intr_vector *iv;
+	struct fire_msiqarg *fmqa;
+
+	iv = cookie;
+	fmqa = iv->iv_icarg;
+	/*
+	 * Note that since fire_intr_clear() will clear the event queue
+	 * interrupt after the handler associated with the MSI [sic] has
+	 * been executed we have to protect the access to the event queue as
+	 * otherwise nested event queue interrupts cause corruption of the
+	 * event queue on MP machines.  Obviously especially when abandoning
+	 * the 1:1 mapping it would be better to not clear the event queue
+	 * interrupt after each handler invocation but only once when the
+	 * outstanding MSIs have been processed but unfortunately that
+	 * doesn't work well and leads to interrupt storms with controllers/
+	 * drivers which don't mask interrupts while the handler is executed.
+	 * Maybe delaying clearing the MSI until after the handler has been
+	 * executed could be used to work around this but that's not the
+	 * intended usage and might in turn cause lost MSIs.
+	 */
+	mtx_lock_spin(&fmqa->fmqa_mtx);
+	fire_msiq_common(iv, fmqa);
+	mtx_unlock_spin(&fmqa->fmqa_mtx);
+}
+
+static void
+fire_msiq_filter(void *cookie)
+{
+	struct intr_vector *iv;
+	struct fire_msiqarg *fmqa;
+
+	iv = cookie;
+	fmqa = iv->iv_icarg;
+	/*
+	 * For filters we don't use fire_intr_clear() since it would clear
+	 * the event queue interrupt while we're still processing the event
+	 * queue as filters and associated post-filter handler are executed
+	 * directly, which in turn would lead to lost MSIs.  So we clear the
+	 * event queue interrupt only once after processing the event queue.
+	 * Given that this still guarantees the filters to not be executed
+	 * concurrently and no other CPU can clear the event queue interrupt
+	 * while the event queue is still processed, we don't even need to
+	 * interlock the access to the event queue in this case.
+	 */
+	critical_enter();
+	fire_msiq_common(iv, fmqa);
+	FIRE_PCI_WRITE_8(fmqa->fmqa_fica.fica_sc, fmqa->fmqa_fica.fica_clr,
+	    INTCLR_IDLE);
+	critical_exit();
+}
+
+static inline void
+fire_msiq_common(struct intr_vector *iv, struct fire_msiqarg *fmqa)
+{
+	struct fire_softc *sc;
+	struct fo_msiq_record *qrec;
+	device_t dev;
+	uint64_t word0;
+	u_int head, msi, msiq;
+
+	sc = fmqa->fmqa_fica.fica_sc;
+	dev = sc->sc_dev;
+	msiq = fmqa->fmqa_msiq;
+	head = (FIRE_PCI_READ_8(sc, fmqa->fmqa_head) & FO_PCI_EQ_HD_MASK) >>
+	    FO_PCI_EQ_HD_SHFT;
+	qrec = &fmqa->fmqa_base[head];
+	word0 = qrec->fomqr_word0;
+	for (;;) {
+		KASSERT((word0 & FO_MQR_WORD0_FMT_TYPE_MSI64) != 0 ||
+		    (word0 & FO_MQR_WORD0_FMT_TYPE_MSI32) != 0,
+		    ("%s: received non-MSI/MSI-X message in event queue %d "
+		    "(word0 %#llx)", device_get_nameunit(dev), msiq,
+		    (unsigned long long)word0));
+		if (__predict_false((word0 & FO_MQR_WORD0_FMT_TYPE_MASK) == 0))
+			break;
+		msi = (word0 & FO_MQR_WORD0_DATA0_MASK) >>
+		    FO_MQR_WORD0_DATA0_SHFT;
+		/*
+		 * Sanity check the MSI/MSI-X as long as we use a 1:1 mapping.
+		 */
+		KASSERT(msi == fmqa->fmqa_msi,
+		    ("%s: received non-matching MSI/MSI-X in event queue %d "
+		    "(%d versus %d)", device_get_nameunit(dev), msiq, msi,
+		    fmqa->fmqa_msi));
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_CLR_BASE + (msi << 3),
+		    FO_PCI_MSI_CLR_EQWR_N);
+		if (__predict_false(intr_event_handle(iv->iv_event,
+		    NULL) != 0))
+			printf("stray MSI/MSI-X in event queue %d\n", msiq);
+		qrec->fomqr_word0 &= ~FO_MQR_WORD0_FMT_TYPE_MASK;
+		head = (head + 1) % sc->sc_msiq_size;
+		qrec = &fmqa->fmqa_base[head];
+		word0 = qrec->fomqr_word0;
+	}
+	FIRE_PCI_WRITE_8(sc, fmqa->fmqa_head, (head & FO_PCI_EQ_HD_MASK) <<
+	    FO_PCI_EQ_HD_SHFT);
+	if (__predict_false((FIRE_PCI_READ_8(sc, fmqa->fmqa_tail) &
+	    FO_PCI_EQ_TL_OVERR) != 0)) {
+		device_printf(dev, "event queue %d overflow\n", msiq);
+		msiq <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq,
+		    FIRE_PCI_READ_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq) |
+		    FO_PCI_EQ_CTRL_CLR_COVERR);
+	}
+}
+
+static int
+fire_setup_intr(device_t dev, device_t child, struct resource *ires,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+	struct fire_softc *sc;
+	struct fire_msiqarg *fmqa;
+	u_long vec;
+	int error;
+	u_int msi, msiq;
+
+	sc = device_get_softc(dev);
+	/*
+	 * XXX this assumes that a device only has one INTx, while in fact
+	 * Cassini+ and Saturn can use all four the firmware has assigned
+	 * to them, but so does pci(4).
+	 */
+	if (rman_get_rid(ires) != 0) {
+		msi = rman_get_start(ires);
+		msiq = sc->sc_msi_msiq_table[msi - sc->sc_msi_first];
+		vec = INTMAP_VEC(sc->sc_ign, sc->sc_msiq_ino_first + msiq);
+		msiq += sc->sc_msiq_first;
+		if (intr_vectors[vec].iv_ic != &fire_ic) {
+			device_printf(dev,
+			    "invalid interrupt controller for vector 0x%lx\n",
+			    vec);
+			return (EINVAL);
+		}
+		/*
+		 * The MD interrupt code needs the vector rather than the MSI.
+		 */
+		rman_set_start(ires, vec);
+		rman_set_end(ires, vec);
+		error = bus_generic_setup_intr(dev, child, ires, flags, filt,
+		    intr, arg, cookiep);
+		rman_set_start(ires, msi);
+		rman_set_end(ires, msi);
+		if (error != 0)
+			return (error);
+		fmqa = intr_vectors[vec].iv_icarg;
+		/*
+		 * XXX inject our event queue handler.
+		 */
+		if (filt != NULL) {
+			intr_vectors[vec].iv_func = fire_msiq_filter;
+			intr_vectors[vec].iv_ic = &fire_msiqc_filter;
+			/*
+			 * Ensure the event queue interrupt is cleared, it
+			 * might have triggered before.  Given we supply NULL
+			 * as ic_clear, inthand_add() won't do this for us.
+			 */
+			FIRE_PCI_WRITE_8(sc, fmqa->fmqa_fica.fica_clr,
+			    INTCLR_IDLE);
+		} else
+			intr_vectors[vec].iv_func = fire_msiq_handler;
+		/* Record the MSI/MSI-X as long as we we use a 1:1 mapping. */
+		fmqa->fmqa_msi = msi;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_SET_BASE + (msiq << 3),
+		    FO_PCI_EQ_CTRL_SET_EN);
+		msi <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_MAP_BASE + msi,
+		    (FIRE_PCI_READ_8(sc, FO_PCI_MSI_MAP_BASE + msi) &
+		    ~FO_PCI_MSI_MAP_EQNUM_MASK) |
+		    ((msiq << FO_PCI_MSI_MAP_EQNUM_SHFT) &
+		    FO_PCI_MSI_MAP_EQNUM_MASK));
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_CLR_BASE + msi,
+		    FO_PCI_MSI_CLR_EQWR_N);
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_MAP_BASE + msi,
+		    FIRE_PCI_READ_8(sc, FO_PCI_MSI_MAP_BASE + msi) |
+		    FO_PCI_MSI_MAP_V);
+		return (error);
+	}
+
+	/*
+	 * Make sure the vector is fully specified and we registered
+	 * our interrupt controller for it.
+	 */
+	vec = rman_get_start(ires);
+	if (INTIGN(vec) != sc->sc_ign) {
+		device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+	if (intr_vectors[vec].iv_ic != &fire_ic) {
+		device_printf(dev,
+		    "invalid interrupt controller for vector 0x%lx\n", vec);
+		return (EINVAL);
+	}
+	return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
+	    arg, cookiep));
+}
+
+static int
+fire_teardown_intr(device_t dev, device_t child, struct resource *ires,
+    void *cookie)
+{
+	struct fire_softc *sc;
+	u_long vec;
+	int error;
+	u_int msi, msiq;
+
+	sc = device_get_softc(dev);
+	if (rman_get_rid(ires) != 0) {
+		msi = rman_get_start(ires);
+		msiq = sc->sc_msi_msiq_table[msi - sc->sc_msi_first];
+		vec = INTMAP_VEC(sc->sc_ign, msiq + sc->sc_msiq_ino_first);
+		msiq += sc->sc_msiq_first;
+		msi <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_MSI_MAP_BASE + msi,
+		    FIRE_PCI_READ_8(sc, FO_PCI_MSI_MAP_BASE + msi) &
+		    ~FO_PCI_MSI_MAP_V);
+		msiq <<= 3;
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_CTRL_CLR_BASE + msiq,
+		    FO_PCI_EQ_CTRL_CLR_COVERR | FO_PCI_EQ_CTRL_CLR_E2I |
+		    FO_PCI_EQ_CTRL_CLR_DIS);
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_TL_BASE + msiq,
+		    (0 << FO_PCI_EQ_TL_SHFT) & FO_PCI_EQ_TL_MASK);
+		FIRE_PCI_WRITE_8(sc, FO_PCI_EQ_HD_BASE + msiq,
+		    (0 << FO_PCI_EQ_HD_SHFT) & FO_PCI_EQ_HD_MASK);
+		intr_vectors[vec].iv_ic = &fire_ic;
+		/*
+		 * The MD interrupt code needs the vector rather than the MSI.
+		 */
+		rman_set_start(ires, vec);
+		rman_set_end(ires, vec);
+		error = bus_generic_teardown_intr(dev, child, ires, cookie);
+		msi >>= 3;
+		rman_set_start(ires, msi);
+		rman_set_end(ires, msi);
+		return (error);
+	}
+	return (bus_generic_teardown_intr(dev, child, ires, cookie));
+}
+
+static struct resource *
+fire_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct fire_softc *sc;
+	struct resource *rv;
+	struct rman *rm;
+	bus_space_tag_t bt;
+	bus_space_handle_t bh;
+	int needactivate = flags & RF_ACTIVE;
+
+	flags &= ~RF_ACTIVE;
+
+	sc = device_get_softc(bus);
+	if (type == SYS_RES_IRQ) {
+		/*
+		 * XXX: Don't accept blank ranges for now, only single
+		 * interrupts.  The other case should not happen with
+		 * the MI PCI code...
+		 * XXX: This may return a resource that is out of the
+		 * range that was specified.  Is this correct...?
+		 */
+		if (start != end)
+			panic("%s: XXX: interrupt range", __func__);
+		if (*rid == 0)
+			start = end = INTMAP_VEC(sc->sc_ign, end);
+		return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
+		    type, rid, start, end, count, flags));
+	}
+	switch (type) {
+	case SYS_RES_MEMORY:
+		rm = &sc->sc_pci_mem_rman;
+		bt = sc->sc_pci_memt;
+		bh = sc->sc_pci_bh[OFW_PCI_CS_MEM32];
+		break;
+	case SYS_RES_IOPORT:
+		rm = &sc->sc_pci_io_rman;
+		bt = sc->sc_pci_iot;
+		bh = sc->sc_pci_bh[OFW_PCI_CS_IO];
+		break;
+	default:
+		return (NULL);
+		/* NOTREACHED */
+	}
+
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (rv == NULL)
+		return (NULL);
+	rman_set_rid(rv, *rid);
+	bh += rman_get_start(rv);
+	rman_set_bustag(rv, bt);
+	rman_set_bushandle(rv, bh);
+
+	if (needactivate) {
+		if (bus_activate_resource(child, type, *rid, rv)) {
+			rman_release_resource(rv);
+			return (NULL);
+		}
+	}
+	return (rv);
+}
+
+static int
+fire_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	void *p;
+	int error;
+
+	if (type == SYS_RES_IRQ)
+		return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child,
+		    type, rid, r));
+	if (type == SYS_RES_MEMORY) {
+		/*
+		 * Need to memory-map the device space, as some drivers
+		 * depend on the virtual address being set and usable.
+		 */
+		error = sparc64_bus_mem_map(rman_get_bustag(r),
+		    rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);
+		if (error != 0)
+			return (error);
+		rman_set_virtual(r, p);
+	}
+	return (rman_activate_resource(r));
+}
+
+static int
+fire_deactivate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+	if (type == SYS_RES_IRQ)
+		return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child,
+		    type, rid, r));
+	if (type == SYS_RES_MEMORY) {
+		sparc64_bus_mem_unmap(rman_get_virtual(r), rman_get_size(r));
+		rman_set_virtual(r, NULL);
+	}
+	return (rman_deactivate_resource(r));
+}
+
+static int
+fire_release_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	int error;
+
+	if (type == SYS_RES_IRQ)
+		return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
+		    type, rid, r));
+	if (rman_get_flags(r) & RF_ACTIVE) {
+		error = bus_deactivate_resource(child, type, rid, r);
+		if (error)
+			return (error);
+	}
+	return (rman_release_resource(r));
+}
+
+static bus_dma_tag_t
+fire_get_dma_tag(device_t bus, device_t child)
+{
+	struct fire_softc *sc;
+
+	sc = device_get_softc(bus);
+	return (sc->sc_pci_dmat);
+}
+
+static phandle_t
+fire_get_node(device_t bus, device_t dev)
+{
+	struct fire_softc *sc;
+
+	sc = device_get_softc(bus);
+	/* We only have one child, the PCI bus, which needs our own node. */
+	return (sc->sc_node);
+}
+
+static bus_space_tag_t
+fire_alloc_bus_tag(struct fire_softc *sc, int type)
+{
+	bus_space_tag_t bt;
+
+	bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
+	if (bt == NULL)
+		panic("%s: out of memory", __func__);
+
+	bt->bst_cookie = sc;
+	bt->bst_parent = rman_get_bustag(sc->sc_mem_res[FIRE_PCI]);
+	bt->bst_type = type;
+	return (bt);
+}
+
+static u_int
+fire_get_timecount(struct timecounter *tc)
+{
+	struct fire_softc *sc;
+
+	sc = tc->tc_priv;
+	return (FIRE_CTRL_READ_8(sc, FO_XBC_PRF_CNT0) & TC_COUNTER_MAX_MASK);
+}
diff --git a/sys/sparc64/pci/firereg.h b/sys/sparc64/pci/firereg.h
new file mode 100644
index 00000000000..1471b09de99
--- /dev/null
+++ b/sys/sparc64/pci/firereg.h
@@ -0,0 +1,1004 @@
+/*-
+ * Copyright (c) 2009 Marius Strobl 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SPARC64_PCI_FIREREG_H_
+#define	_SPARC64_PCI_FIREREG_H_
+
+#define	FIRE_NINTR				3	/* 2 OFW + 1 MSIq */
+#define	FIRE_NRANGE				4
+#define	FIRE_NREG				2
+
+#define	FIRE_PCI				0
+#define	FIRE_CTRL				1
+
+/* PCI configuration and status registers */
+#define	FO_PCI_INT_MAP_BASE			0x01000
+#define	FO_PCI_INT_CLR_BASE			0x01400
+#define	FO_PCI_EQ_BASE_ADDR			0x10000
+#define	FO_PCI_EQ_CTRL_SET_BASE			0x11000
+#define	FO_PCI_EQ_CTRL_CLR_BASE			0x11200
+#define	FO_PCI_EQ_TL_BASE			0x11600
+#define	FO_PCI_EQ_HD_BASE			0x11800
+#define	FO_PCI_MSI_MAP_BASE			0x20000
+#define	FO_PCI_MSI_CLR_BASE			0x28000
+#define	FO_PCI_ERR_COR				0x30000
+#define	FO_PCI_ERR_NONFATAL			0x30008
+#define	FO_PCI_ERR_FATAL			0x30010
+#define	FO_PCI_PM_PME				0x30018
+#define	FO_PCI_PME_TO_ACK			0x30020
+#define	FO_PCI_IMU_INT_EN			0x31008
+#define	FO_PCI_IMU_INT_STAT			0x31010
+#define	FO_PCI_IMU_ERR_STAT_CLR			0x31018
+#define	FO_PCI_IMU_RDS_ERR_LOG			0x31028
+#define	FO_PCI_IMU_SCS_ERR_LOG			0x31030
+#define	FO_PCI_IMU_EQS_ERR_LOG			0x31038
+#define	FO_PCI_DMC_CORE_BLOCK_INT_EN		0x31800
+#define	FO_PCI_DMC_CORE_BLOCK_ERR_STAT		0x31808
+#define	FO_PCI_MULTI_CORE_ERR_STAT		0x31810
+#define	FO_PCI_MSI_32_BIT_ADDR			0x34000
+#define	FO_PCI_MSI_64_BIT_ADDR			0x34008
+#define	FO_PCI_MMU				0x40000
+#define	FO_PCI_MMU_INT_EN			0x41008
+#define	FO_PCI_MMU_INT_STAT			0x41010
+#define	FO_PCI_MMU_ERR_STAT_CLR			0x41018
+#define	FO_PCI_MMU_TRANS_FAULT_ADDR		0x41028
+#define	FO_PCI_MMU_TRANS_FAULT_STAT		0x41030
+#define	FO_PCI_ILU_INT_EN			0x51008
+#define	FO_PCI_ILU_INT_STAT			0x51010
+#define	FO_PCI_ILU_ERR_STAT_CLR			0x51018
+#define	FO_PCI_DMC_DBG_SEL_PORTA		0x53000
+#define	FO_PCI_DMC_DBG_SEL_PORTB		0x53008
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN		0x51800
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT		0x51808
+#define	FO_PCI_TLU_CTRL				0x80000
+#define	FO_PCI_TLU_OEVENT_INT_EN		0x81008
+#define	FO_PCI_TLU_OEVENT_INT_STAT		0x81010
+#define	FO_PCI_TLU_OEVENT_STAT_CLR		0x81018
+#define	FO_PCI_TLU_RX_OEVENT_HDR1_LOG		0x81028
+#define	FO_PCI_TLU_RX_OEVENT_HDR2_LOG		0x81030
+#define	FO_PCI_TLU_TX_OEVENT_HDR1_LOG		0x81038
+#define	FO_PCI_TLU_TX_OEVENT_HDR2_LOG		0x81040
+#define	FO_PCI_TLU_DEV_CTRL			0x90008
+#define	FO_PCI_TLU_LNK_CTRL			0x90020
+#define	FO_PCI_TLU_LNK_STAT			0x90028
+#define	FO_PCI_TLU_UERR_INT_EN			0x91008
+#define	FO_PCI_TLU_UERR_INT_STAT		0x91010
+#define	FO_PCI_TLU_UERR_STAT_CLR		0x91018
+#define	FO_PCI_TLU_RX_UERR_HDR1_LOG		0x91028
+#define	FO_PCI_TLU_RX_UERR_HDR2_LOG		0x91030
+#define	FO_PCI_TLU_TX_UERR_HDR1_LOG		0x91038
+#define	FO_PCI_TLU_TX_UERR_HDR2_LOG		0x91040
+#define	FO_PCI_TLU_CERR_INT_EN			0xa1008
+#define	FO_PCI_TLU_CERR_INT_STAT		0xa1010
+#define	FO_PCI_TLU_CERR_STAT_CLR		0xa1018
+#define	FO_PCI_LPU_RST				0xe2008
+#define	FO_PCI_LPU_INT_STAT			0xe2040
+#define	FO_PCI_LPU_INT_MASK			0xe0248
+#define	FO_PCI_LPU_LNK_LYR_CFG			0xe2200
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT		0xe2210
+#define	FO_PCI_LPU_FLW_CTRL_UPDT_CTRL		0xe2240
+#define	FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS	0xe2400
+#define	FO_PCI_LPU_TXLNK_RPLY_TMR_THRS		0xe2410
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR		0xe2430
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT		0xe2610
+#define	FO_PCI_LPU_LTSSM_CFG2			0xe2788
+#define	FO_PCI_LPU_LTSSM_CFG3			0xe2790
+#define	FO_PCI_LPU_LTSSM_CFG4			0xe2798
+#define	FO_PCI_LPU_LTSSM_CFG5			0xe27a0
+
+/* PCI interrupt mapping registers */
+#define	FO_PCI_IMAP_MDO_MODE			0x8000000000000000ULL
+#define	FO_PCI_IMAP_V				0x0000000080000000ULL
+#define	FIRE_PCI_IMAP_T_JPID_MASK		0x000000007c000000ULL
+#define	FIRE_PCI_IMAP_T_JPID_SHFT		26
+#define	OBERON_PCI_IMAP_T_DESTID_MASK		0x000000007fe00000ULL
+#define	OBERON_PCI_IMAP_T_DESTID_SHFT		21
+#define	FO_PCI_IMAP_INT_CTRL_NUM_MASK		0x00000000000003c0ULL
+#define	FO_PCI_IMAP_INT_CTRL_NUM_SHFT		6
+
+/* PCI interrupt clear registers - use INTCLR_* from  */
+
+/* PCI event queue base address register */
+#define	FO_PCI_EQ_BASE_ADDR_BYPASS		0xfffc000000000000ULL
+#define	FO_PCI_EQ_BASE_ADDR_MASK		0xfffffffffff80000ULL
+#define	FO_PCI_EQ_BASE_ADDR_SHFT		19
+
+/* PCI event queue control set registers */
+#define	FO_PCI_EQ_CTRL_SET_ENOVERR		0x0200000000000000ULL
+#define	FO_PCI_EQ_CTRL_SET_EN			0x0000100000000000ULL
+
+/* PCI event queue control clear registers */
+#define	FO_PCI_EQ_CTRL_CLR_COVERR		0x0200000000000000ULL
+#define	FO_PCI_EQ_CTRL_CLR_E2I			0x0000800000000000ULL
+#define	FO_PCI_EQ_CTRL_CLR_DIS			0x0000100000000000ULL
+
+/* PCI event queue tail registers */
+#define	FO_PCI_EQ_TL_OVERR			0x0200000000000000ULL
+#define	FO_PCI_EQ_TL_MASK			0x000000000000007fULL
+#define	FO_PCI_EQ_TL_SHFT			0
+
+/* PCI event queue head registers */
+#define	FO_PCI_EQ_HD_MASK			0x000000000000007fULL
+#define	FO_PCI_EQ_HD_SHFT			0
+
+/* PCI MSI mapping registers */
+#define	FO_PCI_MSI_MAP_V			0x8000000000000000ULL
+#define	FO_PCI_MSI_MAP_EQWR_N			0x4000000000000000ULL
+#define	FO_PCI_MSI_MAP_EQNUM_MASK		0x000000000000003fULL
+#define	FO_PCI_MSI_MAP_EQNUM_SHFT		0
+
+/* PCI MSI clear registers */
+#define	FO_PCI_MSI_CLR_EQWR_N			0x4000000000000000ULL
+
+/*
+ * PCI IMU interrupt enable, interrupt status and error status clear
+ * registers
+ */
+#define	FO_PCI_IMU_ERR_INT_SPARE_S_MASK		0x00007c0000000000ULL
+#define	FO_PCI_IMU_ERR_INT_SPARE_S_SHFT		42
+#define	FO_PCI_IMU_ERR_INT_EQ_OVER_S		0x0000020000000000ULL
+#define	FO_PCI_IMU_ERR_INT_EQ_NOT_EN_S		0x0000010000000000ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_MAL_ERR_S	0x0000008000000000ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_PAR_ERR_S	0x0000004000000000ULL
+#define	FO_PCI_IMU_ERR_INT_PMEACK_MES_NOT_EN_S	0x0000002000000000ULL
+#define	FO_PCI_IMU_ERR_INT_PMPME_MES_NOT_EN_S	0x0000001000000000ULL
+#define	FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_S	0x0000000800000000ULL
+#define	FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_S	0x0000000400000000ULL
+#define	FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_S	0x0000000200000000ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_NOT_EN_S		0x0000000100000000ULL
+#define	FO_PCI_IMU_ERR_INT_SPARE_P_MASK		0x0000000000007c00ULL
+#define	FO_PCI_IMU_ERR_INT_SPARE_P_SHFT		10
+#define	FO_PCI_IMU_ERR_INT_EQ_OVER_P		0x0000000000000200ULL
+#define	FO_PCI_IMU_ERR_INT_EQ_NOT_EN_P		0x0000000000000100ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_MAL_ERR_P	0x0000000000000080ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_PAR_ERR_P	0x0000000000000040ULL
+#define	FO_PCI_IMU_ERR_INT_PMEACK_MES_NOT_EN_P	0x0000000000000020ULL
+#define	FO_PCI_IMU_ERR_INT_PMPME_MES_NOT_EN_P	0x0000000000000010ULL
+#define	FO_PCI_IMU_ERR_INT_FATAL_MES_NOT_EN_P	0x0000000000000008ULL
+#define	FO_PCI_IMU_ERR_INT_NFATAL_MES_NOT_EN_P	0x0000000000000004ULL
+#define	FO_PCI_IMU_ERR_INT_COR_MES_NOT_EN_P	0x0000000000000002ULL
+#define	FO_PCI_IMU_ERR_INT_MSI_NOT_EN_P		0x0000000000000001ULL
+
+/* PCI IMU RDS error log register */
+#define	FO_PCI_IMU_RDS_ERR_LOG_TYPE_MASK	0xfc00000000000000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_TYPE_SHFT	58
+#define	FO_PCI_IMU_RDS_ERR_LOG_LENGTH_MASK	0x03ff000000000000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_LENGTH_SHFT	48
+#define	FO_PCI_IMU_RDS_ERR_LOG_REQ_ID_MASK	0x0000ffff00000000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_REQ_ID_SHFT	32
+#define	FO_PCI_IMU_RDS_ERR_LOG_TLP_TAG_MASK	0x00000000ff000000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_TLP_TAG_SHFT	24
+#define	FO_PCI_IMU_RDS_ERR_LOG_BE_MCODE_MASK	0x0000000000ff0000ULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_BE_MCODE_SHFT	16
+#define	FO_PCI_IMU_RDS_ERR_LOG_MSI_DATA_MASK	0x000000000000ffffULL
+#define	FO_PCI_IMU_RDS_ERR_LOG_MSI_DATA_SHFT	0
+
+/* PCI IMU SCS error log register */
+#define	FO_PCI_IMU_SCS_ERR_LOG_TYPE_MASK	0xfc00000000000000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_TYPE_SHFT	58
+#define	FO_PCI_IMU_SCS_ERR_LOG_LENGTH_MASK	0x03ff000000000000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_LENGTH_SHFT	48
+#define	FO_PCI_IMU_SCS_ERR_LOG_REQ_ID_MASK	0x0000ffff00000000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_REQ_ID_SHFT	32
+#define	FO_PCI_IMU_SCS_ERR_LOG_TLP_TAG_MASK	0x00000000ff000000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_TLP_TAG_SHFT	24
+#define	FO_PCI_IMU_SCS_ERR_LOG_BE_MODE_MASK	0x0000000000ff0000ULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_BE_MCODE_SHFT	16
+#define	FO_PCI_IMU_SCS_ERR_LOG_EQ_NUM_MASK	0x000000000000003fULL
+#define	FO_PCI_IMU_SCS_ERR_LOG_EQ_NUM_SHFT	0
+
+/* PCI IMU EQS error log register */
+#define	FO_PCI_IMU_EQS_ERR_LOG_EQ_NUM_MASK	0x000000000000003fULL
+#define	FO_PCI_IMU_EQS_ERROR_LOG_EQ_NUM_SHFT	0
+
+/*
+ * PCI ERR COR, ERR NONFATAL, ERR FATAL, PM PME and PME To ACK mapping
+ * registers
+ */
+#define	FO_PCI_ERR_PME_V			0x8000000000000000ULL
+#define	FO_PCI_ERR_PME_EQNUM_MASK		0x000000000000003fULL
+#define	FO_PCI_ERR_PME_EQNUM_SHFT		0
+
+/* PCI DMC core and block interrupt enable register */
+#define	FO_PCI_DMC_CORE_BLOCK_INT_EN_DMC	0x8000000000000000ULL
+#define	FO_PCI_DMC_CORE_BLOCK_INT_EN_MMU	0x0000000000000002ULL
+#define	FO_PCI_DMC_CORE_BLOCK_INT_EN_IMU	0x0000000000000001ULL
+
+/* PCI DMC core and block error status register */
+#define	FO_PCI_DMC_CORE_BLOCK_ERR_STAT_MMU	0x0000000000000002ULL
+#define	FO_PCI_DMC_CORE_BLOCK_ERR_STAT_IMU	0x0000000000000001ULL
+
+/* PCI multi core error status register */
+#define	FO_PCI_MULTI_CORE_ERR_STAT_PEC		0x0000000000000002ULL
+#define	FO_PCI_MULTI_CORE_ERR_STAT_DMC		0x0000000000000001ULL
+
+/* PCI MSI 32-bit address register */
+#define	FO_PCI_MSI_32_BIT_ADDR_MASK		0x00000000ffff0000ULL
+#define	FO_PCI_MSI_32_BIT_ADDR_SHFT		16
+
+/* PCI MSI 64-bit address register */
+#define	FO_PCI_MSI_64_BIT_ADDR_MASK		0x0000ffffffff0000ULL
+#define	FO_PCI_MSI_64_BIT_ADDR_SHFT		16
+
+/*
+ * PCI MMU interrupt enable, interrupt status and error status clear
+ * registers
+ */
+#define	FO_PCI_MMU_ERR_INT_S_MASK		0x0000ffff00000000ULL
+#define	FO_PCI_MMU_ERR_INT_S_SHFT		32
+#define	FO_PCI_MMU_ERR_INT_TBW_DPE_S		0x0000800000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_ERR_S		0x0000400000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_UDE_S		0x0000200000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_DME_S		0x0000100000000000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE3_S		0x0000080000000000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE2_S		0x0000040000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TTC_CAE_S		0x0000020000000000ULL
+#define	FIRE_PCI_MMU_ERR_INT_TTC_DPE_S		0x0000010000000000ULL
+#define	OBERON_PCI_MMU_ERR_INT_TTC_DUE_S	0x0000010000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TTE_PRT_S		0x0000008000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TTE_INV_S		0x0000004000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TRN_OOR_S		0x0000002000000000ULL
+#define	FO_PCI_MMU_ERR_INT_TRN_ERR_S		0x0000001000000000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE1_S		0x0000000800000000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE0_S		0x0000000400000000ULL
+#define	FO_PCI_MMU_ERR_INT_BYP_OOR_S		0x0000000200000000ULL
+#define	FO_PCI_MMU_ERR_INT_BYP_ERR_S		0x0000000100000000ULL
+#define	FO_PCI_MMU_ERR_INT_P_MASK		0x000000000000ffffULL
+#define	FO_PCI_MMU_ERR_INT_P_SHFT		0
+#define	FO_PCI_MMU_ERR_INT_TBW_DPE_P		0x0000000000008000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_ERR_P		0x0000000000004000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_UDE_P		0x0000000000002000ULL
+#define	FO_PCI_MMU_ERR_INT_TBW_DME_P		0x0000000000001000ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE3_P		0x0000000000000800ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE2_P		0x0000000000000400ULL
+#define	FO_PCI_MMU_ERR_INT_TTC_CAE_P		0x0000000000000200ULL
+#define	FIRE_PCI_MMU_ERR_INT_TTC_DPE_P		0x0000000000000100ULL
+#define	OBERON_PCI_MMU_ERR_INT_TTC_DUE_P	0x0000000000000100ULL
+#define	FO_PCI_MMU_ERR_INT_TTE_PRT_P		0x0000000000000080ULL
+#define	FO_PCI_MMU_ERR_INT_TTE_INV_P		0x0000000000000040ULL
+#define	FO_PCI_MMU_ERR_INT_TRN_OOR_P		0x0000000000000020ULL
+#define	FO_PCI_MMU_ERR_INT_TRN_ERR_P		0x0000000000000010ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE1_P		0x0000000000000008ULL
+#define	FO_PCI_MMU_ERR_INT_SPARE0_P		0x0000000000000004ULL
+#define	FO_PCI_MMU_ERR_INT_BYP_OOR_P		0x0000000000000002ULL
+#define	FO_PCI_MMU_ERR_INT_BYP_ERR_P		0x0000000000000001ULL
+
+/* PCI MMU translation fault address register */
+#define	FO_PCI_MMU_TRANS_FAULT_ADDR_VA_MASK	0xfffffffffffffffcULL
+#define	FO_PCI_MMU_TRANS_FAULT_ADDR_VA_SHFT	2
+
+/* PCI MMU translation fault status register */
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_ENTRY_MASK	0x000001ff00000000ULL
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_ENTRY_SHFT	32
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_TYPE_MASK	0x00000000007f0000ULL
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_TYPE_SHFT	16
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_ID_MASK	0x000000000000ffffULL
+#define	FO_PCI_MMU_TRANS_FAULT_STAT_ID_SHFT	0
+
+/*
+ * PCI ILU interrupt enable, interrupt status and error status clear
+ * registers
+ */
+#define	FO_PCI_ILU_ERR_INT_SPARE3_S		0x0000008000000000ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE2_S		0x0000004000000000ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE1_S		0x0000002000000000ULL
+#define	FIRE_PCI_ILU_ERR_INT_IHB_PE_S		0x0000001000000000ULL
+#define	OBERON_PCI_ILU_ERR_INT_IHB_UE_S		0x0000001000000000ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE3_P		0x0000000000000080ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE2_P		0x0000000000000040ULL
+#define	FO_PCI_ILU_ERR_INT_SPARE1_P		0x0000000000000020ULL
+#define	FIRE_PCI_ILU_ERR_INT_IHB_PE_P		0x0000000000000010ULL
+#define	OBERON_PCI_ILU_ERR_INT_IHB_UE_P		0x0000000000000010ULL
+
+/* PCI DMC debug select registers for port a/b */
+#define	FO_PCI_DMC_DBG_SEL_PORT_BLCK_MASK	0x00000000000003c0ULL
+#define	FO_PCI_DMC_DBG_SEL_PORT_BLCK_SHFT	6
+#define	FO_PCI_DMC_DBG_SEL_PORT_SUB_MASK	0x0000000000000038ULL
+#define	FO_PCI_DMC_DBG_SEL_PORT_SUB_SHFT	3
+#define	FO_PCI_DMC_DBG_SEL_PORT_SUB_SGNL_MASK	0x0000000000000007ULL
+#define	FO_PCI_DMC_DBG_SEL_PORT_SUB_SGNL_SHFT	0
+
+/* PCI PEC core and block interrupt enable register */
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_PEC	0x8000000000000000ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_ILU	0x0000000000000008ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_UERR	0x0000000000000004ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_CERR	0x0000000000000002ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_EN_OEVENT	0x0000000000000001ULL
+
+/* PCI PEC core and block interrupt status register */
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT_ILU	0x0000000000000008ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT_UERR	0x0000000000000004ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT_CERR	0x0000000000000002ULL
+#define	FO_PCI_PEC_CORE_BLOCK_INT_STAT_OEVENT	0x0000000000000001ULL
+
+/* PCI TLU control register */
+#define	FO_PCI_TLU_CTRL_L0S_TIM_MASK		0x00000000ff000000ULL
+#define	FO_PCI_TLU_CTRL_L0S_TIM_SHFT		24
+#define	FO_PCI_TLU_CTRL_NWPR_EN			0x0000000000100000ULL
+#define	FO_PCI_TLU_CTRL_CTO_SEL_MASK		0x0000000000070000ULL
+#define	FO_PCI_TLU_CTRL_CTO_SEL_SHFT		16
+#define	FO_PCI_TLU_CTRL_CFG_MASK		0x000000000000ffffULL
+#define	FO_PCI_TLU_CTRL_CFG_SHFT		0
+#define	FO_PCI_TLU_CTRL_CFG_REMAIN_DETECT_QUIET	0x0000000000000100ULL
+
+/*
+ * PCI TLU other event interrupt enable, interrupt status and status clear
+ * registers
+ */
+#define	FO_PCI_TLU_OEVENT_S_MASK		0x00ffffff00000000ULL
+#define	FO_PCI_TLU_OEVENT_S_SHFT		32
+#define	FO_PCI_TLU_OEVENT_SPARE_S		0x0080000000000000ULL
+#define	FO_PCI_TLU_OEVENT_MFC_S			0x0040000000000000ULL
+#define	FO_PCI_TLU_OEVENT_CTO_S			0x0020000000000000ULL
+#define	FO_PCI_TLU_OEVENT_NFP_S			0x0010000000000000ULL
+#define	FO_PCI_TLU_OEVENT_LWC_S			0x0008000000000000ULL
+#define	FO_PCI_TLU_OEVENT_MRC_S			0x0004000000000000ULL
+#define	FO_PCI_TLU_OEVENT_WUC_S			0x0002000000000000ULL
+#define	FO_PCI_TLU_OEVENT_RUC_S			0x0001000000000000ULL
+#define	FO_PCI_TLU_OEVENT_CRS_S			0x0000800000000000ULL
+#define	FO_PCI_TLU_OEVENT_IIP_S			0x0000400000000000ULL
+#define	FO_PCI_TLU_OEVENT_EDP_S			0x0000200000000000ULL
+#define	FIRE_PCI_TLU_OEVENT_EHP_S		0x0000100000000000ULL
+#define	OBERON_PCI_TLU_OEVENT_EHBUE_S		0x0000100000000000ULL
+#define	OBERON_PCI_TLU_OEVENT_EDBUE_S		0x0000100000000000ULL
+#define	FO_PCI_TLU_OEVENT_LIN_S			0x0000080000000000ULL
+#define	FO_PCI_TLU_OEVENT_LRS_S			0x0000040000000000ULL
+#define	FO_PCI_TLU_OEVENT_LDN_S			0x0000020000000000ULL
+#define	FO_PCI_TLU_OEVENT_LUP_S			0x0000010000000000ULL
+#define	FO_PCI_TLU_OEVENT_LPU_S_MASK		0x000000c000000000ULL
+#define	FO_PCI_TLU_OEVENT_LPU_S_SHFT		38
+#define	OBERON_PCI_TLU_OEVENT_TLUEITMO_S	0x0000008000000000ULL
+#define	FO_PCI_TLU_OEVENT_ERU_S			0x0000002000000000ULL
+#define	FO_PCI_TLU_OEVENT_ERO_S			0x0000001000000000ULL
+#define	FO_PCI_TLU_OEVENT_EMP_S			0x0000000800000000ULL
+#define	FO_PCI_TLU_OEVENT_EPE_S			0x0000000400000000ULL
+#define	FIRE_PCI_TLU_OEVENT_ERP_S		0x0000000200000000ULL
+#define	OBERON_PCI_TLU_OEVENT_ERBU_S		0x0000000200000000ULL
+#define	FIRE_PCI_TLU_OEVENT_EIP_S		0x0000000100000000ULL
+#define	OBERON_PCI_TLU_OEVENT_EIUE_S		0x0000000100000000ULL
+#define	FO_PCI_TLU_OEVENT_P_MASK		0x0000000000ffffffULL
+#define	FO_PCI_TLU_OEVENT_P_SHFT		0
+#define	FO_PCI_TLU_OEVENT_SPARE_P		0x0000000000800000ULL
+#define	FO_PCI_TLU_OEVENT_MFC_P			0x0000000000400000ULL
+#define	FO_PCI_TLU_OEVENT_CTO_P			0x0000000000200000ULL
+#define	FO_PCI_TLU_OEVENT_NFP_P			0x0000000000100000ULL
+#define	FO_PCI_TLU_OEVENT_LWC_P			0x0000000000080000ULL
+#define	FO_PCI_TLU_OEVENT_MRC_P			0x0000000000040000ULL
+#define	FO_PCI_TLU_OEVENT_WUC_P			0x0000000000020000ULL
+#define	FO_PCI_TLU_OEVENT_RUC_P			0x0000000000010000ULL
+#define	FO_PCI_TLU_OEVENT_CRS_P			0x0000000000008000ULL
+#define	FO_PCI_TLU_OEVENT_IIP_P			0x0000000000004000ULL
+#define	FO_PCI_TLU_OEVENT_EDP_P			0x0000000000002000ULL
+#define	FIRE_PCI_TLU_OEVENT_EHP_P		0x0000000000001000ULL
+#define	OBERON_PCI_TLU_OEVENT_EHBUE_P		0x0000000000001000ULL
+#define	OBERON_PCI_TLU_OEVENT_EDBUE_P		0x0000000000001000ULL
+#define	FO_PCI_TLU_OEVENT_LIN_P			0x0000000000000800ULL
+#define	FO_PCI_TLU_OEVENT_LRS_P			0x0000000000000400ULL
+#define	FO_PCI_TLU_OEVENT_LDN_P			0x0000000000000200ULL
+#define	FO_PCI_TLU_OEVENT_LUP_P			0x0000000000000100ULL
+#define	FO_PCI_TLU_OEVENT_LPU_P_MASK		0x00000000000000c0ULL
+#define	FO_PCI_TLU_OEVENT_LPU_P_SHFT		6
+#define	OBERON_PCI_TLU_OEVENT_TLUEITMO_P	0x0000000000000080ULL
+#define	FO_PCI_TLU_OEVENT_ERU_P			0x0000000000000020ULL
+#define	FO_PCI_TLU_OEVENT_ERO_P			0x0000000000000010ULL
+#define	FO_PCI_TLU_OEVENT_EMP_P			0x0000000000000008ULL
+#define	FO_PCI_TLU_OEVENT_EPE_P			0x0000000000000004ULL
+#define	FIRE_PCI_TLU_OEVENT_ERP_P		0x0000000000000002ULL
+#define	OBERON_PCI_TLU_OEVENT_ERBU_P		0x0000000000000002ULL
+#define	FIRE_PCI_TLU_OEVENT_EIP_P		0x0000000000000001ULL
+#define	OBERON_PCI_TLU_OEVENT_EIUE_P		0x0000000000000001ULL
+
+/* PCI receive/transmit DLU/TLU other event header 1/2 log registers */
+#define	FO_PCI_TLU_OEVENT_HDR_LOG_MASK		0xffffffffffffffffULL
+#define	FO_PCI_TLU_OEVENT_HDR_LOG_SHFT		0
+
+/* PCI TLU device control register */
+#define	FO_PCI_TLU_DEV_CTRL_MRRS_MASK		0x0000000000007000ULL
+#define	FO_PCI_TLU_DEV_CTRL_MRRS_SHFT		12
+#define	FO_PCI_TLU_DEV_CTRL_MPS_MASK		0x00000000000000e0ULL
+#define	FO_PCI_TLU_DEV_CTRL_MPS_SHFT		5
+
+/*
+ * PCI TLU uncorrectable error interrupt enable, interrupt status and
+ * status clear registers
+ */
+#define	FO_PCI_TLU_UERR_INT_S_MASK		0x001fffff00000000ULL
+#define	FO_PCI_TLU_UERR_INT_S_SHFT		32
+#define	FO_PCI_TLU_UERR_INT_UR_S		0x0010000000000000ULL
+#define	OBERON_PCI_TLU_UERR_INT_ECRC_S		0x0008000000000000ULL
+#define	FO_PCI_TLU_UERR_INT_MFP_S		0x0004000000000000ULL
+#define	FO_PCI_TLU_UERR_INT_ROF_S		0x0002000000000000ULL
+#define	FO_PCI_TLU_UERR_INT_UC_S		0x0001000000000000ULL
+#define	FO_PCI_TLU_UERR_INT_CA_S		0x0000800000000000ULL
+#define	FO_PCI_TLU_UERR_INT_CTO_S		0x0000400000000000ULL
+#define	FO_PCI_TLU_UERR_INT_FCP_S		0x0000200000000000ULL
+#define	FIRE_PCI_TLU_UERR_INT_PP_S		0x0000100000000000ULL
+#define	OBERON_PCI_TLU_UERR_INT_POIS_S		0x0000100000000000ULL
+#define	FO_PCI_TLU_UERR_INT_DLP_S		0x0000001000000000ULL
+#define	FO_PCI_TLU_UERR_INT_TE_S		0x0000000100000000ULL
+#define	FO_PCI_TLU_UERR_INT_P_MASK		0x00000000001fffffULL
+#define	FO_PCI_TLU_UERR_INT_P_SHFT		0
+#define	FO_PCI_TLU_UERR_INT_UR_P		0x0000000000100000ULL
+#define	OBERON_PCI_TLU_UERR_INT_ECRC_P		0x0000000000080000ULL
+#define	FO_PCI_TLU_UERR_INT_MFP_P		0x0000000000040000ULL
+#define	FO_PCI_TLU_UERR_INT_ROF_P		0x0000000000020000ULL
+#define	FO_PCI_TLU_UERR_INT_UC_P		0x0000000000010000ULL
+#define	FO_PCI_TLU_UERR_INT_CA_P		0x0000000000008000ULL
+#define	FO_PCI_TLU_UERR_INT_CTO_P		0x0000000000004000ULL
+#define	FO_PCI_TLU_UERR_INT_FCP_P		0x0000000000002000ULL
+#define	FIRE_PCI_TLU_UERR_INT_PP_P		0x0000000000001000ULL
+#define	OBERON_PCI_TLU_UERR_INT_POIS_P		0x0000000000001000ULL
+#define	FO_PCI_TLU_UERR_INT_DLP_P		0x0000000000000010ULL
+#define	FO_PCI_TLU_UERR_INT_TE_P		0x0000000000000001ULL
+
+/*
+ * PCI TLU correctable error interrupt enable, interrupt status and
+ * status clear registers
+ */
+#define	FO_PCI_TLU_CERR_INT_S_MASK		0x001fffff00000000ULL
+#define	FO_PCI_TLU_CERR_INT_S_SHFT		32
+#define	FO_PCI_TLU_CERR_INT_RTO_S		0x0000100000000000ULL
+#define	FO_PCI_TLU_CERR_INT_RNR_S		0x0000010000000000ULL
+#define	FO_PCI_TLU_CERR_INT_BDP_S		0x0000008000000000ULL
+#define	FO_PCI_TLU_CERR_INT_BTP_S		0x0000004000000000ULL
+#define	FO_PCI_TLU_CERR_INT_RE_S		0x0000000100000000ULL
+#define	FO_PCI_TLU_CERR_INT_P_MASK		0x00000000001fffffULL
+#define	FO_PCI_TLU_CERR_INT_P_SHFT		0
+#define	FO_PCI_TLU_CERR_INT_RTO_P		0x0000000000001000ULL
+#define	FO_PCI_TLU_CERR_INT_RNR_P		0x0000000000000100ULL
+#define	FO_PCI_TLU_CERR_INT_BDP_P		0x0000000000000080ULL
+#define	FO_PCI_TLU_CERR_INT_BTP_P		0x0000000000000040ULL
+#define	FO_PCI_TLU_CERR_INT_RE_P		0x0000000000000001ULL
+
+/* PCI TLU reset register */
+#define	FO_PCI_LPU_RST_WE			0x0000000080000000ULL
+#define	FO_PCI_LPU_RST_UNUSED_MASK		0x0000000000000e00ULL
+#define	FO_PCI_LPU_RST_UNUSED_SHFT		9
+#define	FO_PCI_LPU_RST_ERR			0x0000000000000100ULL
+#define	FO_PCI_LPU_RST_TXLINK			0x0000000000000080ULL
+#define	FO_PCI_LPU_RST_RXLINK			0x0000000000000040ULL
+#define	FO_PCI_LPU_RST_SMLINK			0x0000000000000020ULL
+#define	FO_PCI_LPU_RST_LTSSM			0x0000000000000010ULL
+#define	FO_PCI_LPU_RST_TXPHY			0x0000000000000008ULL
+#define	FO_PCI_LPU_RST_RXPHY			0x0000000000000004ULL
+#define	FO_PCI_LPU_RST_TXPCS			0x0000000000000002ULL
+#define	FO_PCI_LPU_RST_RXPCS			0x0000000000000001ULL
+
+/* PCI TLU link control register */
+#define	FO_PCI_TLU_LNK_CTRL_EXTSYNC		0x0000000000000080ULL
+#define	FO_PCI_TLU_LNK_CTRL_CLK			0x0000000000000040ULL
+#define	FO_PCI_TLU_LNK_CTRL_RETRAIN		0x0000000000000020ULL
+#define	FO_PCI_TLU_LNK_CTRL_DIS			0x0000000000000010ULL
+#define	FO_PCI_TLU_LNK_CTRL_RCB			0x0000000000000008ULL
+#define	FO_PCI_TLU_LNK_CTRL_ASPM_L0S_L1S	0x0000000000000003ULL
+#define	FO_PCI_TLU_LNK_CTRL_ASPM_L1S		0x0000000000000002ULL
+#define	FO_PCI_TLU_LNK_CTRL_ASPM_L0S		0x0000000000000001ULL
+#define	FO_PCI_TLU_LNK_CTRL_ASPM_DIS		0x0000000000000000ULL
+
+/* PCI TLU link status register */
+#define	FO_PCI_TLU_LNK_STAT_CLK			0x0000000000001000ULL
+#define	FO_PCI_TLU_LNK_STAT_TRAIN		0x0000000000000800ULL
+#define	FO_PCI_TLU_LNK_STAT_ERR			0x0000000000000400ULL
+#define	FO_PCI_TLU_LNK_STAT_WDTH_MASK		0x00000000000003f0ULL
+#define	FO_PCI_TLU_LNK_STAT_WDTH_SHFT		4
+#define	FO_PCI_TLU_LNK_STAT_SPEED_MASK		0x000000000000000fULL
+#define	FO_PCI_TLU_LNK_STAT_SPEED_SHFT		0
+
+/*
+ * PCI receive/transmit DLU/TLU uncorrectable error header 1/2 log
+ * registers
+ */
+#define	FO_PCI_TLU_UERR_HDR_LOG_MASK		0xffffffffffffffffULL
+#define	FO_PCI_TLU_UERR_HDR_LOG_SHFT		0
+
+/* PCI DLU/LPU interrupt status and mask registers */
+#define	FO_PCI_LPU_INT_INT			0x0000000080000000ULL
+#define	FIRE_PCI_LPU_INT_PRF_CNT2_OFLW		0x0000000000000080ULL
+#define	FIRE_PCI_LPU_INT_PRF_CNT1_OFLW		0x0000000000000040ULL
+#define	FO_PCI_LPU_INT_LNK_LYR			0x0000000000000020ULL
+#define	FO_PCI_LPU_INT_PHY_ERR			0x0000000000000010ULL
+#define	FIRE_PCI_LPU_INT_LTSSM			0x0000000000000008ULL
+#define	FIRE_PCI_LPU_INT_PHY_TX			0x0000000000000004ULL
+#define	FIRE_PCI_LPU_INT_PHY_RX			0x0000000000000002ULL
+#define	FIRE_PCI_LPU_INT_PHY_GB			0x0000000000000001ULL
+
+/* PCI DLU/LPU link layer config register */
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_AUTO_UPDT_DIS	0x0000000000080000ULL
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_FREQ_NAK_EN	0x0000000000040000ULL
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_RPLY_AFTER_REQ	0x0000000000020000ULL
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_LAT_THRS_WR_EN	0x0000000000010000ULL
+#define	FO_PCI_LPU_LNK_LYR_CFG_VC0_EN		0x0000000000000100ULL
+#define	FIRE_PCI_LPU_LNK_LYR_CFG_L0S_ADJ_FAC_EN	0x0000000000000010ULL
+#define	FIER_PCI_LPU_LNK_LYR_CFG_TLP_XMIT_FC_EN	0x0000000000000008ULL
+#define	FO_PCI_LPU_LNK_LYR_CFG_FREQ_ACK_EN	0x0000000000000004ULL
+#define	FO_PCI_LPU_LNK_LYR_CFG_RETRY_DIS	0x0000000000000002ULL
+
+/* PCI DLU/LPU link layer interrupt and status register */
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_LNK_ERR_ACT	0x0000000080000000ULL
+#define	OBERON_PCI_LPU_LNK_LYR_INT_STAT_PBUS_PE 0x0000000000800000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_USPRTD_DLLP	0x0000000000400000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_DLLP_RX_ERR	0x0000000000200000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_BAD_DLLP	0x0000000000100000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_TLP_RX_ERR	0x0000000000040000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_SRC_ERR_TLP	0x0000000000020000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_BAD_TLP	0x0000000000010000ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RBF_UDF_ERR	0x0000000000000200ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RBF_OVF_ERR	0x0000000000000100ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_EG_TLPM_ERR	0x0000000000000080ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_EG_TFRM_ERR	0x0000000000000040ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RBF_PE	0x0000000000000020ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_EGRESS_PE	0x0000000000000010ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RPLY_TMR_TO	0x0000000000000004ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_RPLY_NUM_RO	0x0000000000000002ULL
+#define	FO_PCI_LPU_LNK_LYR_INT_STAT_DLNK_PES	0x0000000000000001ULL
+
+/* PCI DLU/LPU flow control update control register */
+#define	FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_C_EN	0x0000000000000004ULL
+#define	FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_NP_EN	0x0000000000000002ULL
+#define	FO_PCI_LPU_FLW_CTRL_UPDT_CTRL_FC0_P_EN	0x0000000000000001ULL
+
+/* PCI DLU/LPU txlink ACKNAK latency timer threshold register */
+#define	FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS_MASK	0x000000000000ffffULL
+#define	FO_PCI_LPU_TXLNK_FREQ_LAT_TMR_THRS_SHFT	0
+
+/* PCI DLU/LPU txlink replay timer threshold register */
+#define	FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_MASK	0x00000000000fffffULL
+#define	FO_PCI_LPU_TXLNK_RPLY_TMR_THRS_SHFT	0
+
+/* PCI DLU/LPU txlink FIFO pointer register */
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_MASK	0x00000000ffff0000ULL
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_SHFT	16
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_MASK	0x000000000000ffffULL
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_SHFT	0
+
+/* PCI DLU/LPU phy layer interrupt and status register */
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_PHY_LYR_ERR	0x0000000080000000ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_KC_DLLP_ERR	0x0000000000000800ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_END_POS_ERR	0x0000000000000400ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_LNK_ERR	0x0000000000000200ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_TRN_ERR	0x0000000000000100ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_EDB_DET	0x0000000000000080ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_SDP_END	0x0000000000000040ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_STP_END_EDB	0x0000000000000020ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_INVC_ERR	0x0000000000000010ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_MULTI_SDP	0x0000000000000008ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_MULTI_STP	0x0000000000000004ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_ILL_SDP_POS	0x0000000000000002ULL
+#define	FO_PCI_LPU_PHY_LYR_INT_STAT_ILL_STP_POS	0x0000000000000001ULL
+
+/* PCI DLU/LPU LTSSM config2 register */
+#define	FO_PCI_LPU_LTSSM_CFG2_12_TO_MASK	0x00000000ffffffffULL
+#define	FO_PCI_LPU_LTSSM_CFG2_12_TO_SHFT	0
+
+/* PCI DLU/LPU LTSSM config3 register */
+#define	FO_PCI_LPU_LTSSM_CFG3_2_TO_MASK		0x00000000ffffffffULL
+#define	FO_PCI_LPU_LTSSM_CFG3_2_TO_SHFT		0
+
+/* PCI DLU/LPU LTSSM config4 register */
+#define	FO_PCI_LPU_LTSSM_CFG4_TRN_CTRL_MASK	0x00000000ff000000ULL
+#define	FO_PCI_LPU_LTSSM_CFG4_TRN_CTRL_SHFT	24
+#define	FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_MASK	0x0000000000ff0000ULL
+#define	FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_SHFT	16
+#define	FO_PCI_LPU_LTSSM_CFG4_N_FTS_MASK	0x000000000000ff00ULL
+#define	FO_PCI_LPU_LTSSM_CFG4_N_FTS_SHFT	8
+#define	FO_PCI_LPU_LTSSM_CFG4_LNK_NUM_MASK	0x00000000000000ffULL
+#define	FO_PCI_LPU_LTSSM_CFG4_LNK_NUM_SHFT	0
+
+/* PCI DLU/LPU LTSSM config5 register */
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED0_MASK	0x00000000ffffe000ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED0_SHFT	13
+#define	FO_PCI_LPU_LTSSM_CFG5_RCV_DET_TST_MODE	0x0000000000001000ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_POLL_CMPLNC_DIS	0x0000000000000800ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_TX_IDLE_TX_FTS	0x0000000000000400ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_RX_FTS_RVR_LK	0x0000000000000200ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED1_MASK	0x0000000000000180ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED1_SHFT	7
+#define	FO_PCI_LPU_LTSSM_CFG5_LPBK_NTRY_ACTIVE	0x0000000000000040ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_LPBK_NTRY_EXIT	0x0000000000000020ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_LPBK_ACTIVE_EXIT	0x0000000000000010ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_L1_IDLE_RCVRY_LK	0x0000000000000008ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_L0_TRN_CNTRL_RST	0x0000000000000004ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_L0_LPBK		0x0000000000000002ULL
+#define	FO_PCI_LPU_LTSSM_CFG5_UNUSED2		0x0000000000000001ULL
+
+/* Controller configuration and status registers */
+#define	FIRE_JBUS_PAR_CTRL			0x60010
+#define	FO_XBC_ERR_LOG_EN			0x61000
+#define	FO_XBC_INT_EN				0x61008
+#define	FO_XBC_INT_STAT				0x61010
+#define	FO_XBC_ERR_STAT_CLR			0x61018
+#define	FIRE_JBC_FATAL_RST_EN			0x61028
+#define	FIRE_JBCINT_ITRANS_ERR_LOG		0x61040
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2		0x61048
+#define	FIRE_JBCINT_OTRANS_ERR_LOG		0x61040
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2		0x61048
+#define	FIRE_FATAL_ERR_LOG			0x61050
+#define	FIRE_FATAL_ERR_LOG2			0x61058
+#define	FIRE_MERGE_TRANS_ERR_LOG		0x61060
+#define	FIRE_DMCINT_ODCD_ERR_LOG		0x61068
+#define	FIRE_DMCINT_IDC_ERR_LOG			0x61070
+#define	FIRE_JBC_CSR_ERR_LOG			0x61078
+#define	FIRE_JBC_CORE_BLOCK_INT_EN		0x61800
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT		0x61808
+#define	FO_XBC_PRF_CNT_SEL			0x62000
+#define	FO_XBC_PRF_CNT0				0x62008
+#define	FO_XBC_PRF_CNT1				0x62010
+
+/* JBus parity control register */
+#define	FIRE_JBUS_PAR_CTRL_P_EN			0x8000000000000000ULL
+#define	FIRE_JBUS_PAR_CTRL_INVRTD_PAR_MASK	0x000000000000003cULL
+#define	FIRE_JBUS_PAR_CTRL_INVRTD_PAR_SHFT	2
+#define	FIRE_JBUS_PAR_CTRL_NEXT_DATA		0x0000000000000002ULL
+#define	FIRE_JBUS_PAR_CTRL_NEXT_ADDR		0x0000000000000001ULL
+
+/* JBC error log enable register - may also apply to UBC */
+#define	FIRE_JBC_ERR_LOG_EN_SPARE_MASK		0x00000000e0000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_SPARE_SHFT		29
+#define	FIRE_JBC_ERR_LOG_EN_PIO_UNMAP_RD	0x0000000010000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_ILL_ACC_RD		0x0000000008000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_EBUS_TO		0x0000000004000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_MB_PEA		0x0000000002000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_MB_PER		0x0000000001000000ULL
+#define	FIRE_JBC_ERR_LOG_EN_MB_PEW		0x0000000000800000ULL
+#define	FIRE_JBC_ERR_LOG_EN_UE_ASYN		0x0000000000400000ULL
+#define	FIRE_JBC_ERR_LOG_EN_CE_ASYN		0x0000000000200000ULL
+#define	FIRE_JBC_ERR_LOG_EN_JTE			0x0000000000100000ULL
+#define	FIRE_JBC_ERR_LOG_EN_JBE			0x0000000000080000ULL
+#define	FIRE_JBC_ERR_LOG_EN_JUE			0x0000000000040000ULL
+#define	FIRE_JBC_ERR_LOG_EN_IJP			0x0000000000020000ULL
+#define	FIRE_JBC_ERR_LOG_EN_ICISE		0x0000000000010000ULL
+#define	FIRE_JBC_ERR_LOG_EN_CPE			0x0000000000008000ULL
+#define	FIRE_JBC_ERR_LOG_EN_APE			0x0000000000004000ULL
+#define	FIRE_JBC_ERR_LOG_EN_WR_DPE		0x0000000000002000ULL
+#define	FIRE_JBC_ERR_LOG_EN_RD_DPE		0x0000000000001000ULL
+#define	FIRE_JBC_ERR_LOG_EN_ILL_BMW		0x0000000000000800ULL
+#define	FIRE_JBC_ERR_LOG_EN_ILL_BMR		0x0000000000000400ULL
+#define	FIRE_JBC_ERR_LOG_EN_BJC			0x0000000000000200ULL
+#define	FIRE_JBC_ERR_LOG_EN_PIO_UNMAP		0x0000000000000100ULL
+#define	FIRE_JBC_ERR_LOG_EN_PIO_DPE		0x0000000000000080ULL
+#define	FIRE_JBC_ERR_LOG_EN_PIO_CPE		0x0000000000000040ULL
+#define	FIRE_JBC_ERR_LOG_EN_ILL_ACC		0x0000000000000020ULL
+#define	FIRE_JBC_ERR_LOG_EN_UNSOL_RD		0x0000000000000010ULL
+#define	FIRE_JBC_ERR_LOG_EN_UNSOL_INT		0x0000000000000008ULL
+#define	FIRE_JBC_ERR_LOG_EN_JTCEEW		0x0000000000000004ULL
+#define	FIRE_JBC_ERR_LOG_EN_JTCEEI		0x0000000000000002ULL
+#define	FIRE_JBC_ERR_LOG_EN_JTCEER		0x0000000000000001ULL
+
+/* JBC interrupt enable, interrupt status and error status clear registers */
+#define	FIRE_JBC_ERR_INT_SPARE_S_MASK		0xe000000000000000ULL
+#define	FIRE_JBC_ERR_INT_SPARE_S_SHFT		61
+#define	FIRE_JBC_ERR_INT_PIO_UNMAP_RD_S		0x1000000000000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_ACC_RD_S		0x0800000000000000ULL
+#define	FIRE_JBC_ERR_INT_EBUS_TO_S		0x0400000000000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PEA_S		0x0200000000000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PER_S		0x0100000000000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PEW_S		0x0080000000000000ULL
+#define	FIRE_JBC_ERR_INT_UE_ASYN_S		0x0040000000000000ULL
+#define	FIRE_JBC_ERR_INT_CE_ASYN_S		0x0020000000000000ULL
+#define	FIRE_JBC_ERR_INT_JTE_S			0x0010000000000000ULL
+#define	FIRE_JBC_ERR_INT_JBE_S			0x0008000000000000ULL
+#define	FIRE_JBC_ERR_INT_JUE_S			0x0004000000000000ULL
+#define	FIRE_JBC_ERR_INT_IJP_S			0x0002000000000000ULL
+#define	FIRE_JBC_ERR_INT_ICISE_S		0x0001000000000000ULL
+#define	FIRE_JBC_ERR_INT_CPE_S			0x0000800000000000ULL
+#define	FIRE_JBC_ERR_INT_APE_S			0x0000400000000000ULL
+#define	FIRE_JBC_ERR_INT_WR_DPE_S		0x0000200000000000ULL
+#define	FIRE_JBC_ERR_INT_RD_DPE_S		0x0000100000000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_BMW_S		0x0000080000000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_BMR_S		0x0000040000000000ULL
+#define	FIRE_JBC_ERR_INT_BJC_S			0x0000020000000000ULL
+#define	FIRE_JBC_ERR_INT_PIO_UNMAP_S		0x0000010000000000ULL
+#define	FIRE_JBC_ERR_INT_PIO_DPE_S		0x0000008000000000ULL
+#define	FIRE_JBC_ERR_INT_PIO_CPE_S		0x0000004000000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_ACC_S		0x0000002000000000ULL
+#define	FIRE_JBC_ERR_INT_UNSOL_RD_S		0x0000001000000000ULL
+#define	FIRE_JBC_ERR_INT_UNSOL_INT_S		0x0000000800000000ULL
+#define	FIRE_JBC_ERR_INT_JTCEEW_S		0x0000000400000000ULL
+#define	FIRE_JBC_ERR_INT_JTCEEI_S		0x0000000200000000ULL
+#define	FIRE_JBC_ERR_INT_JTCEER_S		0x0000000100000000ULL
+#define	FIRE_JBC_ERR_INT_SPARE_P_MASK		0x00000000e0000000ULL
+#define	FIRE_JBC_ERR_INT_SPARE_P_SHFT		29
+#define	FIRE_JBC_ERR_INT_PIO_UNMAP_RD_P		0x0000000010000000ULL
+#define	FIRE_JBC_ERR_INT_ILL_ACC_RD_P		0x0000000008000000ULL
+#define	FIRE_JBC_ERR_INT_EBUS_TO_P		0x0000000004000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PEA_P		0x0000000002000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PER_P		0x0000000001000000ULL
+#define	FIRE_JBC_ERR_INT_MB_PEW_P		0x0000000000800000ULL
+#define	FIRE_JBC_ERR_INT_UE_ASYN_P		0x0000000000400000ULL
+#define	FIRE_JBC_ERR_INT_CE_ASYN_P		0x0000000000200000ULL
+#define	FIRE_JBC_ERR_INT_JTE_P			0x0000000000100000ULL
+#define	FIRE_JBC_ERR_INT_JBE_P			0x0000000000080000ULL
+#define	FIRE_JBC_ERR_INT_JUE_P			0x0000000000040000ULL
+#define	FIRE_JBC_ERR_INT_IJP_P			0x0000000000020000ULL
+#define	FIRE_JBC_ERR_INT_ICISE_P		0x0000000000010000ULL
+#define	FIRE_JBC_ERR_INT_CPE_P			0x0000000000008000ULL
+#define	FIRE_JBC_ERR_INT_APE_P			0x0000000000004000ULL
+#define	FIRE_JBC_ERR_INT_WR_DPE_P		0x0000000000002000ULL
+#define	FIRE_JBC_ERR_INT_RD_DPE_P		0x0000000000001000ULL
+#define	FIRE_JBC_ERR_INT_ILL_BMW_P		0x0000000000000800ULL
+#define	FIRE_JBC_ERR_INT_ILL_BMR_P		0x0000000000000400ULL
+#define	FIRE_JBC_ERR_INT_BJC_P			0x0000000000000200ULL
+#define	FIRE_JBC_ERR_INT_PIO_UNMAP_P		0x0000000000000100ULL
+#define	FIRE_JBC_ERR_INT_PIO_DPE_P		0x0000000000000080ULL
+#define	FIRE_JBC_ERR_INT_PIO_CPE_P		0x0000000000000040ULL
+#define	FIRE_JBC_ERR_INT_ILL_ACC_P		0x0000000000000020ULL
+#define	FIRE_JBC_ERR_INT_UNSOL_RD_P		0x0000000000000010ULL
+#define	FIRE_JBC_ERR_INT_UNSOL_INT_P		0x0000000000000008ULL
+#define	FIRE_JBC_ERR_INT_JTCEEW_P		0x0000000000000004ULL
+#define	FIRE_JBC_ERR_INT_JTCEEI_P		0x0000000000000002ULL
+#define	FIRE_JBC_ERR_INT_JTCEER_P		0x0000000000000001ULL
+
+/* UBC interrupt enable, error status and error status clear registers */
+#define	OBERON_UBC_ERR_INT_PIORBEUE_S		0x0004000000000000ULL
+#define	OBERON_UBC_ERR_INT_PIOWBEUE_S		0x0002000000000000ULL
+#define	OBERON_UBC_ERR_INT_PIOWTUE_S		0x0001000000000000ULL
+#define	OBERON_UBC_ERR_INT_MEMWTAXB_S		0x0000080000000000ULL
+#define	OBERON_UBC_ERR_INT_MEMRDAXB_S		0x0000040000000000ULL
+#define	OBERON_UBC_ERR_INT_DMAWTUEB_S		0x0000020000000000ULL
+#define	OBERON_UBC_ERR_INT_DMARDUEB_S		0x0000010000000000ULL
+#define	OBERON_UBC_ERR_INT_MEMWTAXA_S		0x0000000800000000ULL
+#define	OBERON_UBC_ERR_INT_MEMRDAXA_S		0x0000000400000000ULL
+#define	OBERON_UBC_ERR_INT_DMAWTUEA_S		0x0000000200000000ULL
+#define	OBERON_UBC_ERR_INT_DMARDUEA_S		0x0000000100000000ULL
+#define	OBERON_UBC_ERR_INT_PIORBEUE_P		0x0000000000040000ULL
+#define	OBERON_UBC_ERR_INT_PIOWBEUE_P		0x0000000000020000ULL
+#define	OBERON_UBC_ERR_INT_PIOWTUE_P		0x0000000000010000ULL
+#define	OBERON_UBC_ERR_INT_MEMWTAXB_P		0x0000000000000800ULL
+#define	OBERON_UBC_ERR_INT_MEMRDAXB_P		0x0000000000000400ULL
+#define	OBERON_UBC_ERR_INT_DMARDUEB_P		0x0000000000000200ULL
+#define	OBERON_UBC_ERR_INT_DMAWTUEB_P		0x0000000000000100ULL
+#define	OBERON_UBC_ERR_INT_MEMWTAXA_P		0x0000000000000008ULL
+#define	OBERON_UBC_ERR_INT_MEMRDAXA_P		0x0000000000000004ULL
+#define	OBERON_UBC_ERR_INT_DMAWTUEA_P		0x0000000000000002ULL
+#define	OBERON_UBC_ERR_INT_DMARDUEA_P		0x0000000000000001ULL
+
+/* JBC fatal reset enable register */
+#define	FIRE_JBC_FATAL_RST_EN_SPARE_P_INT_MASK	0x000000000c000000ULL
+#define	FIRE_JBC_FATAL_RST_EN_SPARE_P_INT_SHFT	26
+#define	FIRE_JBC_FATAL_RST_EN_MB_PEA_P_INT	0x0000000002000000ULL
+#define	FIRE_JBC_FATAL_RST_EN_CPE_P_INT		0x0000000000008000ULL
+#define	FIRE_JBC_FATAL_RST_EN_APE_P_INT		0x0000000000004000ULL
+#define	FIRE_JBC_FATAL_RST_EN_PIO_CPE_INT	0x0000000000000040ULL
+#define	FIRE_JBC_FATAL_RST_EN_JTCEEW_P_INT	0x0000000000000004ULL
+#define	FIRE_JBC_FATAL_RST_EN_JTCEEI_P_INT	0x0000000000000002ULL
+#define	FIRE_JBC_FATAL_RST_EN_JTCEER_P_INT	0x0000000000000001ULL
+
+/* JBC JBCINT in transaction error log register */
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_Q_WORD_MASK	0x00c0000000000000ULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_Q_WORD_SHFT	54
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_TRANSID_MASK	0x0003000000000000ULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_TRANSID_SHFT	48
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_ADDR_MASK	0x000007ffffffffffULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG_ADDR_SHFT	0
+
+/* JBC JBCINT in transaction error log register 2 */
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_ARB_WN_MASK	0x000ffffff0000000ULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_ARB_WN_SHFT	28
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_J_REQ_MASK	0x000000000fe00000ULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_J_REQ_SHFT	21
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_J_PACK_MASK	0x00000000001fffffULL
+#define	FIRE_JBCINT_ITRANS_ERR_LOG2_J_PACK_SHFT	0
+
+/* JBC JBCINT out transaction error log register */
+#define	FIRE_JBCINT_OTRANS_ERR_LOG_TRANSID_MASK	0x003f000000000000ULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG_TRANSID_SHFT	48
+#define	FIRE_JBCINT_OTRANS_ERR_LOG_ADDR_MASK	0x000007ffffffffffULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG_ADDR_SHFT	0
+
+/* JBC JBCINT out transaction error log register 2 */
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_ARB_WN_MASK	0x000ffffff0000000ULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_ARB_WN_SHFT	28
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_J_REQ_MASK	0x000000000fe00000ULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_J_REQ_SHFT	21
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_J_PACK_MASK	0x00000000001fffffULL
+#define	FIRE_JBCINT_OTRANS_ERR_LOG2_J_PACK_SHFT	0
+
+/* JBC merge transaction error log register */
+#define	FIRE_FATAL_ERR_LOG_DATA_MASK		0xffffffffffffffffULL
+#define	FIRE_FATAL_ERR_LOG_DATA_SHFT		0
+
+/* JBC merge transaction error log register 2 */
+#define	FIRE_FATAL_ERR_LOG2_ARB_WN_MASK		0x000ffffff0000000ULL
+#define	FIRE_FATAL_ERR_LOG2_ARB_WN_SHFT		28
+#define	FIRE_FATAL_ERR_LOG2_J_REQ_MASK		0x000000000fe00000ULL
+#define	FIRE_FATAL_ERR_LOG2_J_REQ_SHFT		21
+#define	FIRE_FATAL_ERR_LOG2_J_PACK_MASK		0x00000000001fffffULL
+#define	FIRE_FATAL_ERR_LOG2_J_PACK_SHFT		0
+
+/* JBC merge transaction error log register */
+#define	FIRE_MERGE_TRANS_ERR_LOG_Q_WORD_MASK	0x00c0000000000000ULL
+#define	FIRE_MERGE_TRANS_ERR_LOG_Q_WORD_SHFT	54
+#define	FIRE_MERGE_TRANS_ERR_LOG_TRANSID_MASK	0x0003000000000000ULL
+#define	FIRE_MERGE_TRANS_ERR_LOG_TRANSID_SHFT	48
+#define	FIRE_MERGE_TRANS_ERR_LOG_JBC_TAG_MASK	0x0000f80000000000ULL
+#define	FIRE_MERGE_TRANS_ERR_LOG_JBC_TAG_SHFT	43
+#define	FIRE_MERGE_TRANS_ERR_LOG_ADDR_MASK	0x000007ffffffffffULL
+#define	FIRE_MERGE_TRANS_ERR_LOG_ADDR_SHFT	0
+
+/* JBC DMCINT ODCD error log register */
+#define	FIRE_DMCINT_ODCD_ERR_LOG_TRANS_ID_MASK	0x0030000000000000ULL
+#define	FIRE_DMCINT_ODCD_ERR_LOG_TRANS_ID_SHFT	52
+#define	FIRE_DMCINT_ODCD_ERR_LOG_AID_MASK	0x000f000000000000ULL
+#define	FIRE_DMCINT_ODCD_ERR_LOG_AID_SHFT	48
+#define	FIRE_DMCINT_ODCD_ERR_LOG_TTYPE_MASK	0x0000f80000000000ULL
+#define	FIRE_DMCINT_ODCD_ERR_LOG_TTYPE_SHFT	43
+#define	FIRE_DMCINT_ODCD_ERR_LOG_ADDR_MASK	0x000007ffffffffffULL
+#define	FIRE_DMCINT_ODCD_ERR_LOG_ADDR_SHFT	0
+
+/* JBC DMCINT IDC error log register */
+#define	FIRE_DMCINT_IDC_ERR_DMC_CTAG_MASK	0x000000000fff0000ULL
+#define	FIRE_DMCINT_IDC_ERR_DMC_CTAG_SHFT	16
+#define	FIRE_DMCINT_IDC_ERR_TRANSID_MASK	0x000000000000c000ULL
+#define	FIRE_DMCINT_IDC_ERR_AGNTID_MASK		0x0000000000003c00ULL
+#define	FIRE_DMCINT_IDC_ERR_AGNTID_SHFT		10
+#define	FIRE_DMCINT_IDC_ERR_SRCID_MASK		0x00000000000003e0ULL
+#define	FIRE_DMCINT_IDC_ERR_SRCID_SHFT		5
+#define	FIRE_DMCINT_IDC_ERR_TARGID_MASK		0x000000000000001fULL
+#define	FIRE_DMCINT_IDC_ERRO_TARGID_SHFT	0
+
+/* JBC CSR error log register */
+#define	FIRE_JBC_CSR_ERR_LOG_WR			0x0000040000000000ULL
+#define	FIRE_JBC_CSR_ERR_LOG_BMASK_MASK		0x000003fffc000000ULL
+#define	FIRE_JBC_CSR_ERR_LOG_BMASK_SHFT		26
+#define	FIRE_JBC_CSR_ERR_LOG_ADDR_MASK		0x0000000003ffffffULL
+#define	FIRE_JBC_CSR_ERR_LOG_ADDR_SHFT		0
+
+/* JBC core and block interrupt enable register */
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_JBC		0x8000000000000000ULL
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_CSR		0x0000000000000008ULL
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_MERGE	0x0000000000000004ULL
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_JBCINT	0x0000000000000002ULL
+#define	FIRE_JBC_CORE_BLOCK_INT_EN_DMCINT	0x0000000000000001ULL
+
+/* JBC core and block error status register */
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT_CSR	0x0000000000000008ULL
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT_MERGE	0x0000000000000004ULL
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT_JBCINT	0x0000000000000002ULL
+#define	FIRE_JBC_CORE_BLOCK_ERR_STAT_DMCINT	0x0000000000000001ULL
+
+/* JBC performance counter select register - may also apply to UBC */
+#define	FO_XBC_PRF_CNT_PIO_RD_PCIEB		0x0000000000000018ULL
+#define	FO_XBC_PRF_CNT_PIO_WR_PCIEB		0x0000000000000017ULL
+#define	FO_XBC_PRF_CNT_PIO_RD_PCIEA		0x0000000000000016ULL
+#define	FO_XBC_PRF_CNT_PIO_WR_PCIEA		0x0000000000000015ULL
+#define	FO_XBC_PRF_CNT_WB			0x0000000000000014ULL
+#define	FO_XBC_PRF_CNT_PIO_FRGN			0x0000000000000013ULL
+#define	FO_XBC_PRF_CNT_XB_NCHRNT		0x0000000000000012ULL
+#define	FO_XBC_PRF_CNT_FO_CHRNT			0x0000000000000011ULL
+#define	FO_XBC_PRF_CNT_XB_CHRNT			0x0000000000000010ULL
+#define	FO_XBC_PRF_CNT_AOKOFF_DOKOFF		0x000000000000000fULL
+#define	FO_XBC_PRF_CNT_DOKOFF			0x000000000000000eULL
+#define	FO_XBC_PRF_CNT_AOKOFF			0x000000000000000dULL
+#define	FO_XBC_PRF_CNT_RD_TOTAL			0x000000000000000cULL
+#define	FO_XBC_PRF_CNT_WR_TOTAL			0x000000000000000bULL
+#define	FO_XBC_PRF_CNT_WR_PARTIAL		0x000000000000000aULL
+#define	FO_XBC_PRF_CNT_PIOS_CSR_RINGB		0x0000000000000009ULL
+#define	FO_XBC_PRF_CNT_PIOS_CSR_RINGA		0x0000000000000008ULL
+#define	FO_XBC_PRF_CNT_PIOS_EBUS		0x0000000000000007ULL
+#define	FO_XBC_PRF_CNT_PIOS_I2C			0x0000000000000006ULL
+#define	FO_XBC_PRF_CNT_RD_LAT_SMPLS		0x0000000000000005ULL
+#define	FO_XBC_PRF_CNT_RD_LAT			0x0000000000000004ULL
+#define	FO_XBC_PRF_CNT_ON_XB			0x0000000000000003ULL
+#define	FO_XBC_PRF_CNT_XB_IDL			0x0000000000000002ULL
+#define	FO_XBC_PRF_CNT_XB_CLK			0x0000000000000001ULL
+#define	FO_XBC_PRF_CNT_NONE			0x0000000000000000ULL
+#define	FO_XBC_PRF_CNT_CNT1_SHFT		8
+#define	FO_XBC_PRF_CNT_CNT0_SHFT		0
+
+/* JBC performance counter 0/1 registers - may also apply to UBC */
+#define	FO_XBC_PRF_CNT_MASK			0xffffffffffffffffULL
+#define	FO_XBC_PRF_CNT_SHFT			0
+
+/* Lookup tables */
+const uint16_t const fire_freq_nak_tmr_thrs[6][4] = {
+	{ 0x00ed, 0x049, 0x043, 0x030 },
+	{ 0x01a0, 0x076, 0x06b, 0x048 },
+	{ 0x022f, 0x09a, 0x056, 0x056 },
+	{ 0x042f, 0x11a, 0x096, 0x096 },
+	{ 0x082f, 0x21a, 0x116, 0x116 },
+	{ 0x102f, 0x41a, 0x216, 0x216 }
+};
+
+const uint16_t const fire_rply_tmr_thrs[6][4] = {
+	{ 0x0379, 0x112, 0x0fc, 0x0b4 },
+	{ 0x0618, 0x1BA, 0x192, 0x10e },
+	{ 0x0831, 0x242, 0x143, 0x143 },
+	{ 0x0fb1, 0x422, 0x233, 0x233 },
+	{ 0x1eb0, 0x7e1, 0x412, 0x412 },
+	{ 0x3cb0, 0xf61, 0x7d2, 0x7d2 }
+};
+
+/* Register default values */
+#define	FO_PCI_TLU_CTRL_L0S_TIM_DFLT		0xda
+#define	FO_PCI_TLU_CTRL_CFG_DFLT		0x1
+#define	FO_PCI_LPU_LTSSM_CFG2_12_TO_DFLT	0x2dc6c0
+#define	FO_PCI_LPU_LTSSM_CFG3_2_TO_DFLT		0x7a120
+#define	FO_PCI_LPU_LTSSM_CFG4_DATA_RATE_DFLT	0x2
+#define	FO_PCI_LPU_LTSSM_CFG4_N_FTS_DFLT	0x8c
+#define	OBERON_PCI_LPU_TXLNK_RPLY_TMR_THRS_DFLT	0xc9
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_HD_DFLT	0x0
+#define	FO_PCI_LPU_TXLNK_RTR_FIFO_PTR_TL_DFLT	0xffff
+
+/* INO macros */
+#define	FO_EQ_FIRST_INO				0x18
+#define	FO_EQ_LAST_INO				0x3b
+#define	FO_DMC_PEC_INO				0x3e
+#define	FO_XCB_INO				0x3f
+#define	FO_MAX_INO				FO_XCB_INO
+
+/* Device space macros */
+#define	FO_CONF_BUS_SHFT			20
+#define	FO_CONF_DEV_SHFT			15
+#define	FO_CONF_FUNC_SHFT			12
+#define	FO_CONF_REG_SHFT			0
+#define	FO_IO_SIZE				0x10000000
+#define	FO_MEM_SIZE				0x1ffff0000
+
+#define	FO_CONF_OFF(bus, slot, func, reg)				\
+	(((bus) << FO_CONF_BUS_SHFT) |					\
+	((slot) << FO_CONF_DEV_SHFT) |					\
+	((func) << FO_CONF_FUNC_SHFT) |					\
+	((reg) << FO_CONF_REG_SHFT))
+
+/* Width of the physical addresses the IOMMU translates to */
+#define	FIRE_IOMMU_BITS				43
+#define	OBERON_IOMMU_BITS			47
+
+/* Event queue macros */
+#define	FO_EQ_ALIGNMENT				(512 * 1024)
+#define	FO_EQ_NRECORDS				128
+#define	FO_EQ_RECORD_SIZE			64
+
+/* Event queue record format */
+struct fo_msiq_record {
+	uint64_t	fomqr_word0;
+	uint64_t	fomqr_word1;
+	uint64_t	fomqr_reserved[6];
+};
+
+#define	FO_MQR_WORD0_FMT_TYPE_MASK		0x7f00000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_SHFT		56
+#define	FO_MQR_WORD0_FMT_TYPE_MSI64		0x7800000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_MSI32		0x5800000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_MSG		0x3000000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_MSG_ROUTE_MASK	0x0700000000000000ULL
+#define	FO_MQR_WORD0_FMT_TYPE_MSG_ROUTE_SHFT	56
+#define	FO_MQR_WORD0_LENGTH_MASK		0x00ffc00000000000ULL
+#define	FO_MQR_WORD0_LENGTH_SHFT		46
+#define	FO_MQR_WORD0_ADDR0_MASK			0x00003fff00000000ULL
+#define	FO_MQR_WORD0_ADDR0_SHFT			32
+#define	FO_MQR_WORD0_RID_MASK			0x00000000ffff0000ULL
+#define	FO_MQR_WORD0_RID_SHFT			16
+#define	FO_MQR_WORD0_DATA0_MASK			0x000000000000ffffULL
+#define	FO_MQR_WORD0_DATA0_SHFT			0
+#define	FO_MQR_WORD1_ADDR1_MASK			0xffffffffffff0000ULL
+#define	FO_MQR_WORD1_ADDR1_SHFT			16
+#define	FO_MQR_WORD1_DATA1_MASK			0x000000000000ffffULL
+#define	FO_MQR_WORD1_DATA1_SHFT			0
+
+#endif /* !_SPARC64_PCI_FIREREG_H_ */
diff --git a/sys/sparc64/pci/firevar.h b/sys/sparc64/pci/firevar.h
new file mode 100644
index 00000000000..58ba419daee
--- /dev/null
+++ b/sys/sparc64/pci/firevar.h
@@ -0,0 +1,98 @@
+/*-
+ * Copyright (c) 2009 by Marius Strobl .
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    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 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 _SPARC64_PCI_FIREVAR_H_
+#define	_SPARC64_PCI_FIREVAR_H_
+
+struct fire_softc {
+	struct iommu_state		sc_is;
+	struct bus_dma_methods		sc_dma_methods;
+
+	struct mtx			sc_msi_mtx;
+	struct mtx			sc_pcib_mtx;
+
+	struct resource			*sc_mem_res[FIRE_NREG];
+	struct resource			*sc_irq_res[FIRE_NINTR];
+	void				*sc_ihand[FIRE_NINTR];
+
+	struct rman			sc_pci_mem_rman;
+	struct rman			sc_pci_io_rman;
+	bus_space_handle_t		sc_pci_bh[FIRE_NRANGE];
+	bus_space_tag_t			sc_pci_cfgt;
+	bus_space_tag_t			sc_pci_iot;
+	bus_space_tag_t			sc_pci_memt;
+	bus_dma_tag_t			sc_pci_dmat;
+
+	device_t			sc_dev;
+
+	uint64_t			*sc_msiq;
+	u_char				*sc_msi_bitmap;
+	uint32_t			*sc_msi_msiq_table;
+	u_char				*sc_msiq_bitmap;
+	uint64_t			sc_msi_addr32;
+	uint64_t			sc_msi_addr64;
+	uint32_t			sc_msi_count;
+	uint32_t			sc_msi_first;
+	uint32_t			sc_msi_data_mask;
+	uint32_t			sc_msix_data_width;
+	uint32_t			sc_msiq_count;
+	uint32_t			sc_msiq_size;
+	uint32_t			sc_msiq_first;
+	uint32_t			sc_msiq_ino_first;
+
+	phandle_t			sc_node;
+
+	u_int				sc_mode;
+#define	FIRE_MODE_FIRE			0
+#define	FIRE_MODE_OBERON		1
+
+	u_int				sc_flags;
+#define	FIRE_MSIX			(1 << 0)
+
+	uint32_t			sc_ign;
+
+	uint32_t			sc_stats_ilu_err;
+	uint32_t			sc_stats_jbc_ce_async;
+	uint32_t			sc_stats_jbc_unsol_int;
+	uint32_t			sc_stats_jbc_unsol_rd;
+	uint32_t			sc_stats_mmu_err;
+	uint32_t			sc_stats_tlu_ce;
+	uint32_t			sc_stats_tlu_oe_non_fatal;
+	uint32_t			sc_stats_tlu_oe_rx_err;
+	uint32_t			sc_stats_tlu_oe_tx_err;
+	uint32_t			sc_stats_ubc_dmardue;
+
+	uint8_t				sc_pci_secbus;
+	uint8_t				sc_pci_subbus;
+
+	struct ofw_bus_iinfo		sc_pci_iinfo;
+};
+
+#endif /* !_SPARC64_PCI_FIREVAR_H_ */

From 217f185c22f1146368455cc0cdb8ef266c1c82c0 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Fri, 15 Jan 2010 22:19:51 +0000
Subject: [PATCH 1159/2592] MFC r201890: Set md_ldt after md_ldt_sd is
 populated.

---
 sys/amd64/amd64/sys_machdep.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c
index 1cba8a21c21..bb81664a3ed 100644
--- a/sys/amd64/amd64/sys_machdep.c
+++ b/sys/amd64/amd64/sys_machdep.c
@@ -420,13 +420,14 @@ user_ldt_alloc(struct proc *p, int force)
 		return (pldt);
 	}
 
-	mdp->md_ldt = new_ldt;
 	if (pldt != NULL) {
 		bcopy(pldt->ldt_base, new_ldt->ldt_base, max_ldt_segment *
 		    sizeof(struct user_segment_descriptor));
 		user_ldt_derefl(pldt);
 	}
 	ssdtosyssd(&sldt, &p->p_md.md_ldt_sd);
+	atomic_store_rel_ptr((volatile uintptr_t *)&mdp->md_ldt,
+	    (uintptr_t)new_ldt);
 	if (p == curproc)
 		set_user_ldt(mdp);
 

From 5ae425f88aa71ce258340b0ff04a59c1e4a637b6 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 15 Jan 2010 23:52:31 +0000
Subject: [PATCH 1160/2592] MFC r201658: Increase default block size from 4K to
 64K. It was reduces 6 yeard ago, when trees were big and FAST mode was
 enabled by default.

So small block size doesn't benefits linear I/O operations in FAST and
significantly slowdowns in ECONOMIC (default) mode. For single stream random
I/Os so small block doesn't give much benefits, as access time is usually
bigger then transfer time there. Same time it requires all heads to seek
together for every single request, reducing performance on parallel load.
---
 sbin/geom/class/stripe/geom_stripe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sbin/geom/class/stripe/geom_stripe.c b/sbin/geom/class/stripe/geom_stripe.c
index 13243c7505a..16808cc7afd 100644
--- a/sbin/geom/class/stripe/geom_stripe.c
+++ b/sbin/geom/class/stripe/geom_stripe.c
@@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
 uint32_t lib_version = G_LIB_VERSION;
 uint32_t version = G_STRIPE_VERSION;
 
-static intmax_t default_stripesize = 4096;
+static intmax_t default_stripesize = 65536;
 
 static void stripe_main(struct gctl_req *req, unsigned flags);
 static void stripe_clear(struct gctl_req *req);

From 8e7a844b9b63e8b67ca36a802eacc5840ed66b28 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 15 Jan 2010 23:56:19 +0000
Subject: [PATCH 1161/2592] MFC r201645: Change the way in which zero
 stripesize is handled. Instead of reporting zero stripeoffset in such case
 (as if device has no stripes), report offset from the beginning of the media
 (as if device has single infinite stripe).

This gives partitioning tools information, required to guess better
partition alignment, in case if hardware doesn't report it's stripe size.
For example, it should give disklabel info about odd offset made by fdisk.
---
 sys/geom/geom_slice.c  | 8 ++++----
 sys/geom/part/g_part.c | 9 ++++-----
 sys/geom/uzip/g_uzip.c | 6 ++----
 3 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/sys/geom/geom_slice.c b/sys/geom/geom_slice.c
index 0bdb10c8222..8a490180a68 100644
--- a/sys/geom/geom_slice.c
+++ b/sys/geom/geom_slice.c
@@ -393,10 +393,10 @@ g_slice_config(struct g_geom *gp, u_int idx, int how, off_t offset, off_t length
 	pp = g_new_providerf(gp, sbuf_data(sb));
 	pp2 = LIST_FIRST(&gp->consumer)->provider;
 	pp->flags = pp2->flags & G_PF_CANDELETE;
-	if (pp2->stripesize > 0) {
-		pp->stripesize = pp2->stripesize;
-		pp->stripeoffset = (pp2->stripeoffset + offset) % pp->stripesize;
-	}
+	pp->stripesize = pp2->stripesize;
+	pp->stripeoffset = pp2->stripeoffset + offset;
+	if (pp->stripesize > 0)
+		pp->stripeoffset %= pp->stripesize;
 	if (0 && bootverbose)
 		printf("GEOM: Configure %s, start %jd length %jd end %jd\n",
 		    pp->name, (intmax_t)offset, (intmax_t)length,
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 92a1db0f3ee..35d6b8bd5f8 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -268,11 +268,10 @@ g_part_new_provider(struct g_geom *gp, struct g_part_table *table,
 	entry->gpe_pp->mediasize -= entry->gpe_offset - offset;
 	entry->gpe_pp->sectorsize = pp->sectorsize;
 	entry->gpe_pp->flags = pp->flags & G_PF_CANDELETE;
-	if (pp->stripesize > 0) {
-		entry->gpe_pp->stripesize = pp->stripesize;
-		entry->gpe_pp->stripeoffset = (pp->stripeoffset +
-		    entry->gpe_offset) % pp->stripesize;
-	}
+	entry->gpe_pp->stripesize = pp->stripesize;
+	entry->gpe_pp->stripeoffset = pp->stripeoffset + entry->gpe_offset;
+	if (pp->stripesize > 0)
+		entry->gpe_pp->stripeoffset %= pp->stripesize;
 	g_error_provider(entry->gpe_pp, 0);
 }
 
diff --git a/sys/geom/uzip/g_uzip.c b/sys/geom/uzip/g_uzip.c
index 90eee02f248..2301efbe0e1 100644
--- a/sys/geom/uzip/g_uzip.c
+++ b/sys/geom/uzip/g_uzip.c
@@ -467,10 +467,8 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
 	pp2->sectorsize = 512;
 	pp2->mediasize = (off_t)sc->nblocks * sc->blksz;
         pp2->flags = pp->flags & G_PF_CANDELETE;
-        if (pp->stripesize > 0) {
-                pp2->stripesize = pp->stripesize;
-                pp2->stripeoffset = pp->stripeoffset;
-        }
+        pp2->stripesize = pp->stripesize;
+        pp2->stripeoffset = pp->stripeoffset;
 	g_error_provider(pp2, 0);
 	g_access(cp, -1, 0, 0);
 

From 392777822f582e0d7ca61c852a82c960b2ef022b Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 15 Jan 2010 23:58:37 +0000
Subject: [PATCH 1162/2592] MFC r202011: While AHCI specification tells that
 multi-vector MSI doesn't use global IS register, nVidia chipsets have
 different oppinion, requiring every interrupt to be acknowledged there.

While there, add interrupt descriptions in multi-vector MSI mode.
---
 sys/dev/ahci/ahci.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 698da60ab1f..784821d970c 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -570,6 +570,12 @@ ahci_setup_interrupt(device_t dev)
 			device_printf(dev, "unable to setup interrupt\n");
 			return ENXIO;
 		}
+		if (ctlr->numirqs > 1) {
+			bus_describe_intr(dev, ctlr->irqs[i].r_irq,
+			    ctlr->irqs[i].handle,
+			    ctlr->irqs[i].mode == AHCI_IRQ_MODE_ONE ?
+			    "ch%d" : "%d", i);
+		}
 	}
 	return (0);
 }
@@ -624,8 +630,14 @@ ahci_intr_one(void *data)
 	int unit;
 
 	unit = irq->r_irq_rid - 1;
+	/* Some controllers have edge triggered IS. */
+	if (ctlr->quirks & AHCI_Q_EDGEIS)
+		ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
 	if ((arg = ctlr->interrupt[unit].argument))
 	    ctlr->interrupt[unit].function(arg);
+	/* AHCI declares level triggered IS. */
+	if (!(ctlr->quirks & AHCI_Q_EDGEIS))
+		ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
 }
 
 static struct resource *

From 6bbfc14d02a3f2e19a578bd4f6e7e4f740ab727b Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Sat, 16 Jan 2010 04:24:10 +0000
Subject: [PATCH 1163/2592] MFC rev 201937: Implement the fo_readdir method.

---
 lib/libstand/dosfs.c | 69 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/lib/libstand/dosfs.c b/lib/libstand/dosfs.c
index 161d3300837..5ba10c11adf 100644
--- a/lib/libstand/dosfs.c
+++ b/lib/libstand/dosfs.c
@@ -47,6 +47,7 @@ static int	dos_close(struct open_file *fd);
 static int	dos_read(struct open_file *fd, void *buf, size_t size, size_t *resid);
 static off_t	dos_seek(struct open_file *fd, off_t offset, int whence);
 static int	dos_stat(struct open_file *fd, struct stat *sb);
+static int	dos_readdir(struct open_file *fd, struct dirent *d);
 
 struct fs_ops dosfs_fsops = {
 	"dosfs",
@@ -56,7 +57,7 @@ struct fs_ops dosfs_fsops = {
 	null_write,
 	dos_seek,
 	dos_stat,
-	null_readdir
+	dos_readdir
 };
 
 #define SECSIZ  512             /* sector size */
@@ -354,6 +355,72 @@ dos_stat(struct open_file *fd, struct stat *sb)
     return (0);
 }
 
+static int
+dos_readdir(struct open_file *fd, struct dirent *d)
+{
+    DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
+    u_char fn[261];
+    DOS_DIR dd;
+    size_t res;
+    u_int chk, i, x, xdn;
+    int err;
+
+    x = chk = 0;
+    while (1) {
+	xdn = x;
+	x = 0;
+	err = dos_read(fd, &dd, sizeof(dd), &res);
+	if (err)
+	    return (err);
+	if (res == sizeof(dd))
+	    return (ENOENT);
+	if (dd.de.name[0] == 0)
+	    return (ENOENT);
+
+	/* Skip deleted entries */
+	if (dd.de.name[0] == 0xe5)
+	    continue;
+
+	/* Skip volume labels */
+	if (dd.de.attr & FA_LABEL)
+	    continue;
+
+	if ((dd.de.attr & FA_MASK) == FA_XDE) {
+	    if (dd.xde.seq & 0x40)
+		chk = dd.xde.chk;
+	    else if (dd.xde.seq != xdn - 1 || dd.xde.chk != chk)
+		continue;
+	    x = dd.xde.seq & ~0x40;
+	    if (x < 1 || x > 20) {
+		x = 0;
+		continue;
+	    }
+	    cp_xdnm(fn, &dd.xde);
+	} else {
+	    if (xdn == 1) {
+		x = 0;
+		for (i = 0; i < 11; i++) {
+		    x = ((x & 1) << 7) | (x >> 1);
+		    x += dd.de.name[i];
+		    x &= 0xff;
+		}
+		if (x == chk)
+		    break;
+	    } else {
+		cp_sfn(fn, &dd.de);
+		break;
+	    }
+	    x = 0;
+	}
+    }
+
+    d->d_fileno = dd.de.clus[1] << 8 + dd.de.clus[0];
+    d->d_reclen = sizeof(*d);
+    d->d_type = (dd.de.attr & FA_DIR) ? DT_DIR : DT_REG;
+    memcpy(d->d_name, fn, sizeof(d->d_name));
+    return(0);
+}
+
 /*
  * Parse DOS boot sector
  */

From fdc6e8a3013c9ec0510219ae7ecab8ee32456996 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Sat, 16 Jan 2010 04:34:03 +0000
Subject: [PATCH 1164/2592] MFC rev 201941: Remove file system support based on
 the simple file system protocol.

MFC rev 201966:
Remove debugging printf().
---
 sys/boot/common/bootstrap.h   |   1 +
 sys/boot/efi/include/efilib.h |   4 +-
 sys/boot/efi/libefi/Makefile  |   4 +-
 sys/boot/efi/libefi/efifs.c   | 441 ----------------------------------
 sys/boot/efi/libefi/efipart.c | 265 ++++++++++++++++++++
 sys/boot/ia64/efi/conf.c      |   7 +-
 sys/boot/ia64/efi/main.c      |   2 -
 sys/boot/ia64/efi/version     |   3 +
 8 files changed, 276 insertions(+), 451 deletions(-)
 delete mode 100644 sys/boot/efi/libefi/efifs.c
 create mode 100644 sys/boot/efi/libefi/efipart.c

diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h
index 5f0848089f4..ff8f45924fe 100644
--- a/sys/boot/common/bootstrap.h
+++ b/sys/boot/common/bootstrap.h
@@ -45,6 +45,7 @@ struct devdesc
 #define	DEVT_CD		3
 #define DEVT_ZFS	4
     int			d_unit;
+    void		*d_opendata;
 };
 
 /* Commands and return values; nonzero return sets command_errmsg != NULL */
diff --git a/sys/boot/efi/include/efilib.h b/sys/boot/efi/include/efilib.h
index 220e01a6897..cf825a623cb 100644
--- a/sys/boot/efi/include/efilib.h
+++ b/sys/boot/efi/include/efilib.h
@@ -34,9 +34,7 @@ extern EFI_SYSTEM_TABLE		*ST;
 extern EFI_BOOT_SERVICES	*BS;
 extern EFI_RUNTIME_SERVICES	*RS;
 
-extern struct devsw efifs_dev;
-extern struct fs_ops efifs_fsops;
-
+extern struct devsw efipart_dev;
 extern struct devsw efinet_dev;
 extern struct netif_driver efinetif;
 
diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile
index 5c504a3fac8..55053e1042f 100644
--- a/sys/boot/efi/libefi/Makefile
+++ b/sys/boot/efi/libefi/Makefile
@@ -3,8 +3,8 @@
 LIB=	efi
 INTERNALLIB=
 
-SRCS=	delay.c efi_console.c efifs.c efinet.c errno.c handles.c libefi.c \
-	time.c
+SRCS=	delay.c efi_console.c efinet.c efipart.c errno.c handles.c \
+	libefi.c time.c
 
 CFLAGS+= -I${.CURDIR}/../include
 CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH:S/amd64/i386/}
diff --git a/sys/boot/efi/libefi/efifs.c b/sys/boot/efi/libefi/efifs.c
deleted file mode 100644
index 716102cf1d0..00000000000
--- a/sys/boot/efi/libefi/efifs.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*-
- * Copyright (c) 2001 Doug Rabson
- * Copyright (c) 2006 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 
-
-/* Perform I/O in blocks of size EFI_BLOCK_SIZE. */
-#define	EFI_BLOCK_SIZE	(1024 * 1024)
-
-union fileinfo {
-	EFI_FILE_INFO info;
-	char bytes[sizeof(EFI_FILE_INFO) + 508];
-};
-
-static EFI_GUID sfs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL;
-static EFI_GUID fs_guid = EFI_FILE_SYSTEM_INFO_ID;
-static EFI_GUID fi_guid = EFI_FILE_INFO_ID;
-
-static int
-efifs_open(const char *upath, struct open_file *f)
-{
-	struct devdesc *dev = f->f_devdata;
-	EFI_FILE_IO_INTERFACE *fsif;
-	EFI_FILE *file, *root;
-	EFI_HANDLE h;
-	EFI_STATUS status;
-	CHAR16 *cp, *path;
-
-	if (f->f_dev != &efifs_dev || dev->d_unit < 0)
-		return (EINVAL);
-
-	h = efi_find_handle(f->f_dev, dev->d_unit);
-	if (h == NULL)
-		return (EINVAL);
-
-	status = BS->HandleProtocol(h, &sfs_guid, (VOID **)&fsif);
-	if (EFI_ERROR(status))
-		return (efi_status_to_errno(status));
-
-	/* Get the root directory. */
-	status = fsif->OpenVolume(fsif, &root);
-	if (EFI_ERROR(status))
-		return (efi_status_to_errno(status));
-
-	while (*upath == '/')
-		upath++;
-
-	/* Special case: opening the root directory. */
-	if (*upath == '\0') {
-		f->f_fsdata = root;
-		return (0);
-	}
-
-	path = malloc((strlen(upath) + 1) * sizeof(CHAR16));
-	if (path == NULL) {
-		root->Close(root);
-		return (ENOMEM);
-	}
-
-	cp = path;
-	while (*upath != '\0') {
-		if (*upath == '/') {
-			*cp = '\\';
-			while (upath[1] == '/')
-				upath++;
-		} else
-			*cp = *upath;
-		upath++;
-		cp++;
-	}
-	*cp = 0;
-
-	/* Open the file. */
-	status = root->Open(root, &file, path,
-	    EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
-	if (status == EFI_ACCESS_DENIED || status == EFI_WRITE_PROTECTED)
-		status = root->Open(root, &file, path, EFI_FILE_MODE_READ, 0);
-	free(path);
-	root->Close(root);
-	if (EFI_ERROR(status))
-		return (efi_status_to_errno(status));
-
-	f->f_fsdata = file;
-	return (0);
-}
-
-static int
-efifs_close(struct open_file *f)
-{
-	EFI_FILE *file = f->f_fsdata;
-
-	if (file == NULL)
-		return (EBADF);
-
-	file->Close(file);
-	f->f_fsdata = NULL;
-	return (0);
-}
-
-static int
-efifs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
-{
-	EFI_FILE *file = f->f_fsdata;
-	EFI_STATUS status;
-	UINTN sz = size;
-	char *bufp;
-
-	if (file == NULL)
-		return (EBADF);
-
-	bufp = buf;
-	while (size > 0) {
-		sz = size;
-		if (sz > EFI_BLOCK_SIZE)
-			sz = EFI_BLOCK_SIZE;
-		status = file->Read(file, &sz, bufp);
-		if (EFI_ERROR(status))
-			return (efi_status_to_errno(status));
-		if (sz == 0)
-			break;
-		size -= sz;
-		bufp += sz;
-	}
-	if (resid)
-		*resid = size;
-	return (0);
-}
-
-static int
-efifs_write(struct open_file *f, void *buf, size_t size, size_t *resid)
-{
-	EFI_FILE *file = f->f_fsdata;
-	EFI_STATUS status;
-	UINTN sz = size;
-	char *bufp;
-
-	if (file == NULL)
-		return (EBADF);
-
-	bufp = buf;
-	while (size > 0) {
-		sz = size;
-		if (sz > EFI_BLOCK_SIZE)
-			sz = EFI_BLOCK_SIZE;
-		status = file->Write(file, &sz, bufp);
-		if (EFI_ERROR(status))
-			return (efi_status_to_errno(status));
-		if (sz == 0)
-			break;
-		size -= sz;
-		bufp += sz;
-	}
-	if (resid)
-		*resid = size;
-	return (0);
-}
-
-static off_t
-efifs_seek(struct open_file *f, off_t offset, int where)
-{
-	EFI_FILE *file = f->f_fsdata;
-	EFI_STATUS status;
-	UINT64 base;
-
-	if (file == NULL)
-		return (EBADF);
-
-	switch (where) {
-	case SEEK_SET:
-		break;
-
-	case SEEK_END:
-		status = file->SetPosition(file, ~0ULL);
-		if (EFI_ERROR(status))
-			return (-1);
-		/* FALLTHROUGH */
-
-	case SEEK_CUR:
-		status = file->GetPosition(file, &base);
-		if (EFI_ERROR(status))
-			return (-1);
-		offset = (off_t)(base + offset);
-		break;
-
-	default:
-		return (-1);
-	}
-	if (offset < 0)
-		return (-1);
-
-	status = file->SetPosition(file, (UINT64)offset);
-	return (EFI_ERROR(status) ? -1 : offset);
-}
-
-static int
-efifs_stat(struct open_file *f, struct stat *sb)
-{
-	EFI_FILE *file = f->f_fsdata;
-	union fileinfo fi;
-	EFI_STATUS status;
-	UINTN sz;
-
-	if (file == NULL)
-		return (EBADF);
-
-	bzero(sb, sizeof(*sb));
-
-	sz = sizeof(fi);
-	status = file->GetInfo(file, &fi_guid, &sz, &fi);
-	if (EFI_ERROR(status))
-		return (efi_status_to_errno(status));
-
-	sb->st_mode = S_IRUSR | S_IRGRP | S_IROTH;
-	if ((fi.info.Attribute & EFI_FILE_READ_ONLY) == 0)
-		sb->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
-	if (fi.info.Attribute & EFI_FILE_DIRECTORY)
-		sb->st_mode |= S_IFDIR;
-	else
-		sb->st_mode |= S_IFREG;
-	sb->st_nlink = 1;
-	sb->st_atime = efi_time(&fi.info.LastAccessTime);
-	sb->st_mtime = efi_time(&fi.info.ModificationTime);
-	sb->st_ctime = efi_time(&fi.info.CreateTime);
-	sb->st_size = fi.info.FileSize;
-	sb->st_blocks = fi.info.PhysicalSize / S_BLKSIZE;
-	sb->st_blksize = S_BLKSIZE;
-	sb->st_birthtime = sb->st_ctime;
-	return (0);
-}
-
-static int
-efifs_readdir(struct open_file *f, struct dirent *d)
-{
-	EFI_FILE *file = f->f_fsdata;
-	union fileinfo fi;
-	EFI_STATUS status;
-	UINTN sz;
-	int i;
-
-	if (file == NULL)
-		return (EBADF);
-
-	sz = sizeof(fi);
-	status = file->Read(file, &sz, &fi);
-	if (EFI_ERROR(status))
-		return (efi_status_to_errno(status));
-	if (sz == 0)
-		return (ENOENT);
-
-	d->d_fileno = 0;
-	d->d_reclen = sizeof(*d);
-	if (fi.info.Attribute & EFI_FILE_DIRECTORY)
-		d->d_type = DT_DIR;
-	else
-		d->d_type = DT_REG;
-	for (i = 0; fi.info.FileName[i] != 0; i++)
-		d->d_name[i] = fi.info.FileName[i];
-	d->d_name[i] = 0;
-	d->d_namlen = i;
-	return (0);
-}
-
-struct fs_ops efifs_fsops = {
-	.fs_name = "efifs",
-	.fo_open = efifs_open,
-	.fo_close = efifs_close,
-	.fo_read = efifs_read,
-	.fo_write = efifs_write,
-	.fo_seek = efifs_seek,
-	.fo_stat = efifs_stat,
-	.fo_readdir = efifs_readdir
-};
-
-static int
-efifs_dev_init(void) 
-{
-	EFI_HANDLE *handles;
-	EFI_STATUS status;
-	UINTN sz;
-	int err;
-
-	sz = 0;
-	status = BS->LocateHandle(ByProtocol, &sfs_guid, 0, &sz, 0);
-	if (status == EFI_BUFFER_TOO_SMALL) {
-		handles = (EFI_HANDLE *)malloc(sz);
-		status = BS->LocateHandle(ByProtocol, &sfs_guid, 0, &sz,
-		    handles);
-		if (EFI_ERROR(status))
-			free(handles);
-	}
-	if (EFI_ERROR(status))
-		return (efi_status_to_errno(status));
-	err = efi_register_handles(&efifs_dev, handles,
-	    sz / sizeof(EFI_HANDLE));
-	free(handles);
-	return (err);
-}
-
-/*
- * Print information about disks
- */
-static void
-efifs_dev_print(int verbose)
-{
-	union {
-		EFI_FILE_SYSTEM_INFO info;
-		char buffer[1024];
-	} fi;
-	char line[80];
-	EFI_FILE_IO_INTERFACE *fsif;
-	EFI_FILE *volume;
-	EFI_HANDLE h;
-	EFI_STATUS status;
-	UINTN sz;
-	int i, unit;
-
-	for (unit = 0, h = efi_find_handle(&efifs_dev, 0);
-	    h != NULL; h = efi_find_handle(&efifs_dev, ++unit)) {
-		sprintf(line, "    %s%d: ", efifs_dev.dv_name, unit);
-		pager_output(line);
-
-		status = BS->HandleProtocol(h, &sfs_guid, (VOID **)&fsif);
-		if (EFI_ERROR(status))
-			goto err;
-
-		status = fsif->OpenVolume(fsif, &volume);
-		if (EFI_ERROR(status))
-			goto err;
-
-		sz = sizeof(fi);
-		status = volume->GetInfo(volume, &fs_guid, &sz, &fi);
-		volume->Close(volume);
-		if (EFI_ERROR(status))
-			goto err;
-
-		if (fi.info.ReadOnly)
-			pager_output("[RO] ");
-		else
-			pager_output("     ");
-		for (i = 0; fi.info.VolumeLabel[i] != 0; i++)
-			fi.buffer[i] = fi.info.VolumeLabel[i];
-		fi.buffer[i] = 0;
-		if (fi.buffer[0] != 0)
-			pager_output(fi.buffer);
-		else
-			pager_output("EFI filesystem");
-		pager_output("\n");
-		continue;
-
-	err:
-		sprintf(line, "[--] error %d: unable to obtain information\n",
-		    efi_status_to_errno(status));
-		pager_output(line);
-	}
-}
-
-/*
- * Attempt to open the disk described by (dev) for use by (f).
- *
- * Note that the philosophy here is "give them exactly what
- * they ask for".  This is necessary because being too "smart"
- * about what the user might want leads to complications.
- * (eg. given no slice or partition value, with a disk that is
- *  sliced - are they after the first BSD slice, or the DOS
- *  slice before it?)
- */
-static int 
-efifs_dev_open(struct open_file *f, ...)
-{
-	va_list		args;
-	struct devdesc	*dev;
-
-	va_start(args, f);
-	dev = va_arg(args, struct devdesc*);
-	va_end(args);
-
-	if (dev->d_unit < 0)
-		return(ENXIO);
-	return (0);
-}
-
-static int 
-efifs_dev_close(struct open_file *f)
-{
-
-	return (0);
-}
-
-static int 
-efifs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize)
-{
-
-	return (ENOSYS);
-}
-
-struct devsw efifs_dev = {
-	.dv_name = "fs", 
-	.dv_type = DEVT_DISK, 
-	.dv_init = efifs_dev_init,
-	.dv_strategy = efifs_dev_strategy, 
-	.dv_open = efifs_dev_open, 
-	.dv_close = efifs_dev_close, 
-	.dv_ioctl = noioctl,
-	.dv_print = efifs_dev_print,
-	.dv_cleanup = NULL
-};
diff --git a/sys/boot/efi/libefi/efipart.c b/sys/boot/efi/libefi/efipart.c
new file mode 100644
index 00000000000..4c8c170f0d9
--- /dev/null
+++ b/sys/boot/efi/libefi/efipart.c
@@ -0,0 +1,265 @@
+/*-
+ * Copyright (c) 2010 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 
+
+static EFI_GUID blkio_guid = BLOCK_IO_PROTOCOL;
+
+static int efipart_init(void);
+static int efipart_strategy(void *, int, daddr_t, size_t, char *, size_t *);
+static int efipart_open(struct open_file *, ...);
+static int efipart_close(struct open_file *);
+static void efipart_print(int);
+
+struct devsw efipart_dev = {
+	.dv_name = "part",
+	.dv_type = DEVT_DISK,
+	.dv_init = efipart_init,
+	.dv_strategy = efipart_strategy,
+	.dv_open = efipart_open,
+	.dv_close = efipart_close,
+	.dv_ioctl = noioctl,
+	.dv_print = efipart_print,
+	.dv_cleanup = NULL
+};
+
+static int
+efipart_init(void) 
+{
+	EFI_BLOCK_IO *blkio;
+	EFI_HANDLE *hin, *hout;
+	EFI_STATUS status;
+	UINTN sz;
+	u_int n, nin, nout;
+	int err;
+
+	sz = 0;
+	status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, 0);
+	if (status == EFI_BUFFER_TOO_SMALL) {
+		hin = (EFI_HANDLE *)malloc(sz * 2);
+		status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz,
+		    hin);
+		if (EFI_ERROR(status))
+			free(hin);
+	}
+	if (EFI_ERROR(status))
+		return (efi_status_to_errno(status));
+
+	/* Filter handles to only include FreeBSD partitions. */
+	nin = sz / sizeof(EFI_HANDLE);
+	hout = hin + nin;
+	nout = 0;
+
+	for (n = 0; n < nin; n++) {
+		status = BS->HandleProtocol(hin[n], &blkio_guid, &blkio);
+		if (EFI_ERROR(status))
+			continue;
+		if (!blkio->Media->LogicalPartition)
+			continue;
+		hout[nout] = hin[n];
+		nout++;
+	}
+
+	err = efi_register_handles(&efipart_dev, hout, nout);
+	free(hin);
+	return (err);
+}
+
+static void
+efipart_print(int verbose)
+{
+	char line[80];
+	EFI_BLOCK_IO *blkio;
+	EFI_HANDLE h;
+	EFI_STATUS status;
+	u_int unit;
+
+	for (unit = 0, h = efi_find_handle(&efipart_dev, 0);
+	    h != NULL; h = efi_find_handle(&efipart_dev, ++unit)) {
+		sprintf(line, "    %s%d:", efipart_dev.dv_name, unit);
+		pager_output(line);
+
+		status = BS->HandleProtocol(h, &blkio_guid, &blkio);
+		if (!EFI_ERROR(status)) {
+			sprintf(line, "    %llu blocks",
+			    (unsigned long long)(blkio->Media->LastBlock + 1));
+			pager_output(line);
+			if (blkio->Media->RemovableMedia)
+				pager_output(" (removable)");
+		}
+		pager_output("\n");
+	}
+}
+
+static int 
+efipart_open(struct open_file *f, ...)
+{
+	va_list args;
+	struct devdesc *dev;
+	EFI_BLOCK_IO *blkio;
+	EFI_HANDLE h;
+	EFI_STATUS status;
+
+	va_start(args, f);
+	dev = va_arg(args, struct devdesc*);
+	va_end(args);
+
+	h = efi_find_handle(&efipart_dev, dev->d_unit);
+	if (h == NULL)
+		return (EINVAL);
+
+	status = BS->HandleProtocol(h, &blkio_guid, &blkio);
+	if (EFI_ERROR(status))
+		return (efi_status_to_errno(status));
+
+	if (!blkio->Media->MediaPresent)
+		return (EAGAIN);
+
+	dev->d_opendata = blkio;
+	return (0);
+}
+
+static int 
+efipart_close(struct open_file *f)
+{
+	struct devdesc *dev;
+
+	dev = (struct devdesc *)(f->f_devdata);
+	if (dev->d_opendata == NULL)
+		return (EINVAL);
+
+	dev->d_opendata = NULL;
+	return (0);
+}
+
+/*
+ * efipart_readwrite()
+ * Internal equivalent of efipart_strategy(), which operates on the
+ * media-native block size. This function expects all I/O requests
+ * to be within the media size and returns an error if such is not
+ * the case.
+ */
+static int
+efipart_readwrite(EFI_BLOCK_IO *blkio, int rw, daddr_t blk, daddr_t nblks,
+    char *buf)
+{
+	EFI_STATUS status;
+
+	if (blkio == NULL)
+		return (ENXIO);
+	if (blk < 0 || blk > blkio->Media->LastBlock)
+		return (EIO);
+	if ((blk + nblks - 1) > blkio->Media->LastBlock)
+		return (EIO);
+
+	switch (rw) {
+	case F_READ:
+		status = blkio->ReadBlocks(blkio, blkio->Media->MediaId, blk,
+		    nblks * blkio->Media->BlockSize, buf);
+		break;
+	case F_WRITE:
+		if (blkio->Media->ReadOnly)
+			return (EROFS);
+		status = blkio->WriteBlocks(blkio, blkio->Media->MediaId, blk,
+		    nblks * blkio->Media->BlockSize, buf);
+		break;
+	default:
+		return (ENOSYS);
+	}
+
+	if (EFI_ERROR(status))
+		printf("%s: rw=%d, status=%lu\n", __func__, rw, status);
+	return (efi_status_to_errno(status));
+}
+
+static int 
+efipart_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf,
+    size_t *rsize)
+{
+	struct devdesc *dev = (struct devdesc *)devdata;
+	EFI_BLOCK_IO *blkio;
+	off_t off;
+	char *blkbuf;
+	size_t blkoff, blksz;
+	int error;
+
+	if (dev == NULL || blk < 0)
+		return (EINVAL);
+
+	blkio = dev->d_opendata;
+	if (blkio == NULL)
+		return (ENXIO);
+
+	if (size == 0 || (size % 512) != 0)
+		return (EIO);
+
+	if (rsize != NULL)
+		*rsize = size;
+
+	if (blkio->Media->BlockSize == 512)
+		return (efipart_readwrite(blkio, rw, blk, size / 512, buf));
+
+	/*
+	 * The block size of the media is not 512B per sector.
+	 */
+	blkbuf = malloc(blkio->Media->BlockSize);
+	if (blkbuf == NULL)
+		return (ENOMEM);
+
+	error = 0;
+	off = blk * 512;
+	blk = off / blkio->Media->BlockSize;
+	blkoff = off % blkio->Media->BlockSize;
+	blksz = blkio->Media->BlockSize - blkoff;
+	while (size > 0) {
+		error = efipart_readwrite(blkio, rw, blk, 1, blkbuf);
+		if (error)
+			break;
+		if (size < blksz)
+			blksz = size;
+		bcopy(blkbuf + blkoff, buf, blksz);
+		buf += blksz;
+		size -= blksz;
+		blk++;
+		blkoff = 0;
+		blksz = blkio->Media->BlockSize;
+	}
+
+	free(blkbuf);
+	return (error);
+}
diff --git a/sys/boot/ia64/efi/conf.c b/sys/boot/ia64/efi/conf.c
index a72f79fd825..69d0927131c 100644
--- a/sys/boot/ia64/efi/conf.c
+++ b/sys/boot/ia64/efi/conf.c
@@ -49,15 +49,16 @@ __FBSDID("$FreeBSD$");
 
 /* Exported for libstand */
 struct devsw *devsw[] = {
-	&efifs_dev,
+	&efipart_dev,
 	&efinet_dev,
 	NULL
 };
 
 struct fs_ops *file_system[] = {
-	&efifs_fsops,
-	&nfs_fsops,
+	&dosfs_fsops,
 	&ufs_fsops,
+	&cd9660_fsops,
+	&nfs_fsops,
 	&gzipfs_fsops,
 	NULL
 };
diff --git a/sys/boot/ia64/efi/main.c b/sys/boot/ia64/efi/main.c
index 9419903e333..c9bb547c437 100644
--- a/sys/boot/ia64/efi/main.c
+++ b/sys/boot/ia64/efi/main.c
@@ -127,8 +127,6 @@ main(int argc, CHAR16 *argv[])
 	/* Get our loaded image protocol interface structure. */
 	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
 
-	printf("Image base: 0x%016lx\n", (u_long)img->ImageBase);
-
 	printf("\n");
 	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
 	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
diff --git a/sys/boot/ia64/efi/version b/sys/boot/ia64/efi/version
index 7d7f5665160..37a71c39e99 100644
--- a/sys/boot/ia64/efi/version
+++ b/sys/boot/ia64/efi/version
@@ -3,6 +3,9 @@ $FreeBSD$
 NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
 file is important.  Make sure the current version number is on line 6.
 
+2.0:	Provide devices based on the block I/O protocol, rather than the
+	simple file services protocol. Use the FreeBSD file system code
+	on top of those devices to access files.
 1.2:	Restructured. Has some user visible differences.
 1.1:	Pass the HCDP table address to the kernel via bootinfo if one
 	is present in the EFI system table.

From ea0c5a5936b9f9c54abf919306fb429d9c8d3a8f Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Sat, 16 Jan 2010 07:55:46 +0000
Subject: [PATCH 1165/2592] Partially revert r202428. There is no
 bus_describe_intr() on RELENG_8.

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

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 784821d970c..f0728ddc14b 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -570,12 +570,6 @@ ahci_setup_interrupt(device_t dev)
 			device_printf(dev, "unable to setup interrupt\n");
 			return ENXIO;
 		}
-		if (ctlr->numirqs > 1) {
-			bus_describe_intr(dev, ctlr->irqs[i].r_irq,
-			    ctlr->irqs[i].handle,
-			    ctlr->irqs[i].mode == AHCI_IRQ_MODE_ONE ?
-			    "ch%d" : "%d", i);
-		}
 	}
 	return (0);
 }

From 8f47948986f3545ba93df6571f87ae5b10ae2977 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sat, 16 Jan 2010 09:17:33 +0000
Subject: [PATCH 1166/2592] MFC: r201888

bridge(4) acts like a switch, not like a hub.
---
 share/man/man4/bridge.4 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/share/man/man4/bridge.4 b/share/man/man4/bridge.4
index a31891a0cdb..7d45356b974 100644
--- a/share/man/man4/bridge.4
+++ b/share/man/man4/bridge.4
@@ -35,7 +35,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 8, 2009
+.Dd January 9, 2010
 .Dt IF_BRIDGE 4
 .Os
 .Sh NAME
@@ -111,7 +111,7 @@ by-default.
 A bridge can be used to provide several services, such as a simple
 802.11-to-Ethernet bridge for wireless hosts, and traffic isolation.
 .Pp
-A bridge works like a hub, forwarding traffic from one interface
+A bridge works like a switch, forwarding traffic from one interface
 to another.
 Multicast and broadcast packets are always forwarded to all
 interfaces that are part of the bridge.

From 964863ced5d65ecbd4f7d3829f0d381b2ed46e28 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Sat, 16 Jan 2010 12:16:38 +0000
Subject: [PATCH 1167/2592] MFC: r201896

As nfsm_srvmtofh_xx() assumes the 4-byte alignment required by XDR
ensure the mbuf data is aligned accordingly by calling nfs_realign()
in fha_extract_info(). This fix is orthogonal to the problem solved
by r199274/r199284 (MFC'ed to stable/8 in r199733).

PR:		142102 (second part)
---
 sys/nfsserver/nfs.h         | 1 +
 sys/nfsserver/nfs_fha.c     | 8 ++++++--
 sys/nfsserver/nfs_srvkrpc.c | 2 +-
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h
index b907a060b4d..49ed0d334ab 100644
--- a/sys/nfsserver/nfs.h
+++ b/sys/nfsserver/nfs.h
@@ -240,6 +240,7 @@ extern int nfs_debug;
 
 #endif
 
+void	nfs_realign(struct mbuf **);
 struct mbuf *nfs_rephead(int, struct nfsrv_descript *, int, struct mbuf **,
 	    caddr_t *);
 void	nfsm_srvfattr(struct nfsrv_descript *, struct vattr *,
diff --git a/sys/nfsserver/nfs_fha.c b/sys/nfsserver/nfs_fha.c
index 0469e4a1880..67bf9da1803 100644
--- a/sys/nfsserver/nfs_fha.c
+++ b/sys/nfsserver/nfs_fha.c
@@ -158,9 +158,9 @@ SYSUNINIT(nfs_fha, SI_SUB_ROOT_CONF, SI_ORDER_ANY, nfs_fha_uninit, NULL);
 static void
 fha_extract_info(struct svc_req *req, struct fha_info *i)
 {
-	struct mbuf *md = req->rq_args;
+	struct mbuf *md;
 	nfsfh_t fh;
-	caddr_t dpos = mtod(md, caddr_t);
+	caddr_t dpos;
 	static u_int64_t random_fh = 0;
 	int error;
 	int v3 = (req->rq_vers == 3);
@@ -201,6 +201,10 @@ fha_extract_info(struct svc_req *req, struct fha_info *i)
 	    procnum == NFSPROC_NULL)
 		goto out;
 	
+	nfs_realign(&req->rq_args);
+	md = req->rq_args;
+	dpos = mtod(md, caddr_t);
+
 	/* Grab the filehandle. */
 	error = nfsm_srvmtofh_xx(&fh.fh_generic, v3, &md, &dpos);
 	if (error)
diff --git a/sys/nfsserver/nfs_srvkrpc.c b/sys/nfsserver/nfs_srvkrpc.c
index 54b1c4ac591..b7b3d4cfa3b 100644
--- a/sys/nfsserver/nfs_srvkrpc.c
+++ b/sys/nfsserver/nfs_srvkrpc.c
@@ -266,7 +266,7 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, int err,
  *	not occur with NFS/UDP and is supposed to only occassionally occur
  *	with TCP.  Use vfs.nfs.realign_count and realign_test to check this.
  */
-static void
+void
 nfs_realign(struct mbuf **pm)	/* XXX COMMON */
 {
 	struct mbuf *m;

From 08fe729d977543cc44be30d04617c15e86e42657 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Sat, 16 Jan 2010 12:18:44 +0000
Subject: [PATCH 1168/2592] MFC: r201899

Some style(9) fixes
---
 sys/nfsserver/nfs.h         |   5 +-
 sys/nfsserver/nfs_fha.c     | 125 ++++++++++++++++++------------------
 sys/nfsserver/nfs_srvkrpc.c |  24 ++++---
 3 files changed, 75 insertions(+), 79 deletions(-)

diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h
index 49ed0d334ab..00dbe5bcf5a 100644
--- a/sys/nfsserver/nfs.h
+++ b/sys/nfsserver/nfs.h
@@ -82,14 +82,13 @@
 #define IO_METASYNC	0
 #endif
 
-
 /* NFS state flags XXX -Wunused */
 #define	NFSRV_SNDLOCK		0x01000000  /* Send socket lock */
 #define	NFSRV_WANTSND		0x02000000  /* Want above */
 
 /*
- * Structures for the nfssvc(2) syscall. Not that anyone but nfsd and mount_nfs
- * should ever try and use it.
+ * Structures for the nfssvc(2) syscall.  Not that anyone but nfsd and
+ * mount_nfs should ever try and use it.
  */
 
 /*
diff --git a/sys/nfsserver/nfs_fha.c b/sys/nfsserver/nfs_fha.c
index 67bf9da1803..25e930fe413 100644
--- a/sys/nfsserver/nfs_fha.c
+++ b/sys/nfsserver/nfs_fha.c
@@ -71,16 +71,17 @@ static struct fha_global {
 	u_long hashmask;
 } g_fha;
 
-/* 
- * These are the entries in the filehandle hash. They talk about a specific 
- * file, requests against which are being handled by one or more nfsds. We keep
- * a chain of nfsds against the file. We only have more than one if reads are 
- * ongoing, and then only if the reads affect disparate regions of the file.
+/*
+ * These are the entries in the filehandle hash.  They talk about a specific
+ * file, requests against which are being handled by one or more nfsds.  We
+ * keep a chain of nfsds against the file. We only have more than one if reads
+ * are ongoing, and then only if the reads affect disparate regions of the
+ * file.
  *
- * In general, we want to assign a new request to an existing nfsd if it is 
- * going to contend with work happening already on that nfsd, or if the 
- * operation is a read and the nfsd is already handling a proximate read. We 
- * do this to avoid jumping around in the read stream unnecessarily, and to 
+ * In general, we want to assign a new request to an existing nfsd if it is
+ * going to contend with work happening already on that nfsd, or if the
+ * operation is a read and the nfsd is already handling a proximate read.  We
+ * do this to avoid jumping around in the read stream unnecessarily, and to
  * avoid contention between threads over single files.
  */
 struct fha_hash_entry {
@@ -101,7 +102,7 @@ struct fha_info {
 };
 
 static int fhe_stats_sysctl(SYSCTL_HANDLER_ARGS);
- 
+
 static void
 nfs_fha_init(void *foo)
 {
@@ -136,7 +137,7 @@ nfs_fha_init(void *foo)
 	    &fha_ctls.max_reqs_per_nfsd, 0, "Maximum requests that "
 	    "single nfsd thread should be working on at any time");
 
-	SYSCTL_ADD_OID(&fha_clist, SYSCTL_STATIC_CHILDREN(_vfs_nfsrv_fha), 
+	SYSCTL_ADD_OID(&fha_clist, SYSCTL_STATIC_CHILDREN(_vfs_nfsrv_fha),
 	    OID_AUTO, "fhe_stats", CTLTYPE_STRING | CTLFLAG_RD, 0, 0,
 	    fhe_stats_sysctl, "A", "");
 }
@@ -151,7 +152,7 @@ nfs_fha_uninit(void *foo)
 SYSINIT(nfs_fha, SI_SUB_ROOT_CONF, SI_ORDER_ANY, nfs_fha_init, NULL);
 SYSUNINIT(nfs_fha, SI_SUB_ROOT_CONF, SI_ORDER_ANY, nfs_fha_uninit, NULL);
 
-/* 
+/*
  * This just specifies that offsets should obey affinity when within
  * the same 1Mbyte (1<<20) chunk for the file (reads only for now).
  */
@@ -167,18 +168,18 @@ fha_extract_info(struct svc_req *req, struct fha_info *i)
 	u_int32_t *tl;
 	rpcproc_t procnum;
 
-	/* 
-	 * We start off with a random fh. If we get a reasonable
-	 * procnum, we set the fh. If there's a concept of offset 
+	/*
+	 * We start off with a random fh.  If we get a reasonable
+	 * procnum, we set the fh.  If there's a concept of offset
 	 * that we're interested in, we set that.
 	 */
 	i->fh = ++random_fh;
 	i->offset = 0;
 	i->locktype = LK_EXCLUSIVE;
-	
+
 	/*
 	 * Extract the procnum and convert to v3 form if necessary,
-	 * taking care to deal with out-of-range procnums. Caller will
+	 * taking care to deal with out-of-range procnums.  Caller will
 	 * ensure that rq_vers is either 2 or 3.
 	 */
 	procnum = req->rq_proc;
@@ -188,19 +189,19 @@ fha_extract_info(struct svc_req *req, struct fha_info *i)
 		procnum = nfsrv_nfsv3_procid[procnum];
 	}
 
-	/* 
-	 * We do affinity for most. However, we divide a realm of affinity 
-	 * by file offset so as to allow for concurrent random access. We 
-	 * only do this for reads today, but this may change when IFS supports 
+	/*
+	 * We do affinity for most.  However, we divide a realm of affinity
+	 * by file offset so as to allow for concurrent random access.  We
+	 * only do this for reads today, but this may change when IFS supports
 	 * efficient concurrent writes.
 	 */
 	if (procnum == NFSPROC_FSSTAT ||
 	    procnum == NFSPROC_FSINFO ||
 	    procnum == NFSPROC_PATHCONF ||
-	    procnum == NFSPROC_NOOP || 
+	    procnum == NFSPROC_NOOP ||
 	    procnum == NFSPROC_NULL)
 		goto out;
-	
+
 	nfs_realign(&req->rq_args);
 	md = req->rq_args;
 	dpos = mtod(md, caddr_t);
@@ -270,8 +271,8 @@ fha_hash_entry_new(u_int64_t fh)
 	e->num_writes = 0;
 	e->num_threads = 0;
 	LIST_INIT(&e->threads);
-	
-	return e;
+
+	return (e);
 }
 
 static void
@@ -296,10 +297,9 @@ fha_hash_entry_lookup(SVCPOOL *pool, u_int64_t fh)
 {
 	struct fha_hash_entry *fhe, *new_fhe;
 
-	LIST_FOREACH(fhe, &g_fha.hashtable[fh % g_fha.hashmask], link) {
+	LIST_FOREACH(fhe, &g_fha.hashtable[fh % g_fha.hashmask], link)
 		if (fhe->fh == fh)
 			break;
-	}
 
 	if (!fhe) {
 		/* Allocate a new entry. */
@@ -308,25 +308,24 @@ fha_hash_entry_lookup(SVCPOOL *pool, u_int64_t fh)
 		mtx_lock(&pool->sp_lock);
 
 		/* Double-check to make sure we still need the new entry. */
-		LIST_FOREACH(fhe, &g_fha.hashtable[fh % g_fha.hashmask], link) {
+		LIST_FOREACH(fhe, &g_fha.hashtable[fh % g_fha.hashmask], link)
 			if (fhe->fh == fh)
 				break;
-		}
 		if (!fhe) {
 			fhe = new_fhe;
 			LIST_INSERT_HEAD(&g_fha.hashtable[fh % g_fha.hashmask],
 			    fhe, link);
-		} else {
+		} else
 			fha_hash_entry_destroy(new_fhe);
-		}
 	}
 
-	return fhe;
+	return (fhe);
 }
 
 static void
 fha_hash_entry_add_thread(struct fha_hash_entry *fhe, SVCTHREAD *thread)
 {
+
 	LIST_INSERT_HEAD(&fhe->threads, thread, st_alink);
 	fhe->num_threads++;
 }
@@ -339,7 +338,7 @@ fha_hash_entry_remove_thread(struct fha_hash_entry *fhe, SVCTHREAD *thread)
 	fhe->num_threads--;
 }
 
-/* 
+/*
  * Account for an ongoing operation associated with this file.
  */
 static void
@@ -365,7 +364,7 @@ get_idle_thread(SVCPOOL *pool)
 }
 
 
-/* 
+/*
  * Get the service thread currently associated with the fhe that is
  * appropriate to handle this operation.
  */
@@ -387,15 +386,15 @@ fha_hash_entry_choose_thread(SVCPOOL *pool, struct fha_hash_entry *fhe,
 		/* If there are any writes in progress, use the first thread. */
 		if (fhe->num_writes) {
 #if 0
-			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO, 
+			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
 			    "fha: %p(%d)w", thread, req_count);
 #endif
 			return (thread);
 		}
 
-		/* 
-		 * Check for read locality, making sure that we won't 
-		 * exceed our per-thread load limit in the process. 
+		/*
+		 * Check for read locality, making sure that we won't
+		 * exceed our per-thread load limit in the process.
 		 */
 		offset1 = i->offset >> fha_ctls.bin_shift;
 		offset2 = STAILQ_FIRST(&thread->st_reqs)->rq_p3
@@ -404,21 +403,21 @@ fha_hash_entry_choose_thread(SVCPOOL *pool, struct fha_hash_entry *fhe,
 			if ((fha_ctls.max_reqs_per_nfsd == 0) ||
 			    (req_count < fha_ctls.max_reqs_per_nfsd)) {
 #if 0
-				ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO, 
+				ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
 				    "fha: %p(%d)r", thread, req_count);
 #endif
 				return (thread);
 			}
 		}
 
-		/* 
+		/*
 		 * We don't have a locality match, so skip this thread,
-		 * but keep track of the most attractive thread in case 
+		 * but keep track of the most attractive thread in case
 		 * we need to come back to it later.
 		 */
 #if 0
-		ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO, 
-		    "fha: %p(%d)s off1 %llu off2 %llu", thread, 
+		ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
+		    "fha: %p(%d)s off1 %llu off2 %llu", thread,
 		    req_count, offset1, offset2);
 #endif
 		if ((min_thread == NULL) || (req_count < min_count)) {
@@ -427,38 +426,38 @@ fha_hash_entry_choose_thread(SVCPOOL *pool, struct fha_hash_entry *fhe,
 		}
 	}
 
-	/* 
-	 * We didn't find a good match yet. See if we can add 
+	/*
+	 * We didn't find a good match yet.  See if we can add
 	 * a new thread to this file handle entry's thread list.
 	 */
-	if ((fha_ctls.max_nfsds_per_fh == 0) || 
+	if ((fha_ctls.max_nfsds_per_fh == 0) ||
 	    (fhe->num_threads < fha_ctls.max_nfsds_per_fh)) {
-		/* 
-		 * We can add a new thread, so try for an idle thread 
-		 * first, and fall back to this_thread if none are idle. 
+		/*
+		 * We can add a new thread, so try for an idle thread
+		 * first, and fall back to this_thread if none are idle.
 		 */
 		if (STAILQ_EMPTY(&this_thread->st_reqs)) {
 			thread = this_thread;
 #if 0
-			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO, 
+			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
 			    "fha: %p(%d)t", thread, thread->st_reqcount);
 #endif
 		} else if ((thread = get_idle_thread(pool))) {
 #if 0
-			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO, 
+			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
 			    "fha: %p(%d)i", thread, thread->st_reqcount);
 #endif
-		} else { 
+		} else {
 			thread = this_thread;
 #if 0
-			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO, 
+			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
 			    "fha: %p(%d)b", thread, thread->st_reqcount);
 #endif
 		}
 		fha_hash_entry_add_thread(fhe, thread);
 	} else {
-		/* 
-		 * We don't want to use any more threads for this file, so 
+		/*
+		 * We don't want to use any more threads for this file, so
 		 * go back to the most attractive nfsd we're already using.
 		 */
 		thread = min_thread;
@@ -467,8 +466,8 @@ fha_hash_entry_choose_thread(SVCPOOL *pool, struct fha_hash_entry *fhe,
 	return (thread);
 }
 
-/* 
- * After getting a request, try to assign it to some thread. Usually we
+/*
+ * After getting a request, try to assign it to some thread.  Usually we
  * handle it ourselves.
  */
 SVCTHREAD *
@@ -491,16 +490,16 @@ fha_assign(SVCTHREAD *this_thread, struct svc_req *req)
 	pool = req->rq_xprt->xp_pool;
 	fha_extract_info(req, &i);
 
-	/* 
-	 * We save the offset associated with this request for later 
+	/*
+	 * We save the offset associated with this request for later
 	 * nfsd matching.
 	 */
 	fhe = fha_hash_entry_lookup(pool, i.fh);
 	req->rq_p1 = fhe;
 	req->rq_p2 = i.locktype;
 	req->rq_p3 = i.offset;
-	
-	/* 
+
+	/*
 	 * Choose a thread, taking into consideration locality, thread load,
 	 * and the number of threads already working on this file.
 	 */
@@ -511,8 +510,8 @@ fha_assign(SVCTHREAD *this_thread, struct svc_req *req)
 	return (thread);
 }
 
-/* 
- * Called when we're done with an operation. The request has already
+/*
+ * Called when we're done with an operation.  The request has already
  * been de-queued.
  */
 void
diff --git a/sys/nfsserver/nfs_srvkrpc.c b/sys/nfsserver/nfs_srvkrpc.c
index b7b3d4cfa3b..bdfe4245b06 100644
--- a/sys/nfsserver/nfs_srvkrpc.c
+++ b/sys/nfsserver/nfs_srvkrpc.c
@@ -187,19 +187,18 @@ nfssvc_nfsserver(struct thread *td, struct nfssvc_args *uap)
 		}
 		error = nfssvc_addsock(fp, td);
 		fdrop(fp, td);
-	} else if (uap->flag & NFSSVC_OLDNFSD) {
+	} else if (uap->flag & NFSSVC_OLDNFSD)
 		error = nfssvc_nfsd(td, NULL);
-	} else if (uap->flag & NFSSVC_NFSD) {
-		if (!uap->argp) 
+	else if (uap->flag & NFSSVC_NFSD) {
+		if (!uap->argp)
 			return (EINVAL);
 		error = copyin(uap->argp, (caddr_t)&nfsdarg,
 		    sizeof(nfsdarg));
 		if (error)
 			return (error);
 		error = nfssvc_nfsd(td, &nfsdarg);
-	} else {
+	} else
 		error = ENXIO;
-	}
 	return (error);
 }
 
@@ -447,9 +446,8 @@ nfssvc_addsock(struct file *fp, struct thread *td)
 
 	siz = sb_max_adj;
 	error = soreserve(so, siz, siz);
-	if (error) {
+	if (error)
 		return (error);
-	}
 
 	/*
 	 * Steal the socket from userland so that it doesn't close
@@ -471,7 +469,7 @@ nfssvc_addsock(struct file *fp, struct thread *td)
 }
 
 /*
- * Called by nfssvc() for nfsds. Just loops around servicing rpc requests
+ * Called by nfssvc() for nfsds.  Just loops around servicing rpc requests
  * until it is killed by a signal.
  */
 static int
@@ -496,9 +494,9 @@ nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
 #endif
 
 	/*
-	 * Only the first nfsd actually does any work. The RPC code
-	 * adds threads to it as needed. Any extra processes offered
-	 * by nfsd just exit. If nfsd is new enough, it will call us
+	 * Only the first nfsd actually does any work.  The RPC code
+	 * adds threads to it as needed.  Any extra processes offered
+	 * by nfsd just exit.  If nfsd is new enough, it will call us
 	 * once with a structure that specifies how many threads to
 	 * use.
 	 */
@@ -522,7 +520,7 @@ nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
 			nfsrv_pool->sp_minthreads = 4;
 			nfsrv_pool->sp_maxthreads = 4;
 		}
-			
+
 		svc_run(nfsrv_pool);
 
 #ifdef KGSSAPI
@@ -541,7 +539,7 @@ nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
 
 /*
  * Size the NFS server's duplicate request cache at 1/2 the
- * nmbclusters, floating within a (64, 2048) range. This is to
+ * nmbclusters, floating within a (64, 2048) range.  This is to
  * prevent all mbuf clusters being tied up in the NFS dupreq
  * cache for small values of nmbclusters.
  */

From 3a911eccaa89474b07cf18a52daf007205367df4 Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Sat, 16 Jan 2010 15:00:35 +0000
Subject: [PATCH 1169/2592] MFC r200587:   ifconfig(8) is documented to take a
 ISO 3166-1 country code to set the   regulatory domain with the "country"
 parameter, but will also take a full   country name.  The man page warns that
 only the ISO code is unambiguous.   In reality, however, the first match on
 either would be accepted, leading   to "DE" being interpreted as the "DEBUG"
 country rather than Germany, and   "MO" selecting Morocco rather than the
 correct country, Macau.

  Fix this by always checking for an ISO CC match first, and only search on
  the full country name if that fails.

PR:		bin/140571
Tested by:	Dirk Meyer dirk.meyer dinoex.sub.org
Reviewed by:	sam
Approved by:	ed (mentor, implicit)
---
 sbin/ifconfig/regdomain.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/sbin/ifconfig/regdomain.c b/sbin/ifconfig/regdomain.c
index a06ba552d8c..414028958e5 100644
--- a/sbin/ifconfig/regdomain.c
+++ b/sbin/ifconfig/regdomain.c
@@ -694,8 +694,11 @@ lib80211_country_findbyname(const struct regdata *rdp, const char *name)
 
 	len = strlen(name);
 	LIST_FOREACH(cp, &rdp->countries, next) {
-		if (strcasecmp(cp->isoname, name) == 0 ||
-		    strncasecmp(cp->name, name, len) == 0)
+		if (strcasecmp(cp->isoname, name) == 0)
+			return cp;
+	}
+	LIST_FOREACH(cp, &rdp->countries, next) {
+		if (strncasecmp(cp->name, name, len) == 0)
 			return cp;
 	}
 	return NULL;

From d077836245157b808a3ba4c4a005300db40faf25 Mon Sep 17 00:00:00 2001
From: Mitsuru IWASAKI 
Date: Sun, 17 Jan 2010 06:24:09 +0000
Subject: [PATCH 1170/2592] MFC r201605: Update acpi_ibm syctl nodes on resume.

---
 sys/dev/acpi_support/acpi_ibm.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/sys/dev/acpi_support/acpi_ibm.c b/sys/dev/acpi_support/acpi_ibm.c
index 25db9b0be96..22899820b1f 100644
--- a/sys/dev/acpi_support/acpi_ibm.c
+++ b/sys/dev/acpi_support/acpi_ibm.c
@@ -255,6 +255,7 @@ ACPI_SERIAL_DECL(ibm, "ACPI IBM extras");
 static int	acpi_ibm_probe(device_t dev);
 static int	acpi_ibm_attach(device_t dev);
 static int	acpi_ibm_detach(device_t dev);
+static int	acpi_ibm_resume(device_t dev);
 
 static void	ibm_led(void *softc, int onoff);
 static void	ibm_led_task(struct acpi_ibm_softc *sc, int pending __unused);
@@ -273,6 +274,7 @@ static device_method_t acpi_ibm_methods[] = {
 	DEVMETHOD(device_probe, acpi_ibm_probe),
 	DEVMETHOD(device_attach, acpi_ibm_attach),
 	DEVMETHOD(device_detach, acpi_ibm_detach),
+	DEVMETHOD(device_resume, acpi_ibm_resume),
 
 	{0, 0}
 };
@@ -434,6 +436,34 @@ acpi_ibm_detach(device_t dev)
 	return (0);
 }
 
+static int
+acpi_ibm_resume(device_t dev)
+{
+	struct acpi_ibm_softc *sc = device_get_softc(dev);
+
+	ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
+
+	ACPI_SERIAL_BEGIN(ibm);
+	for (int i = 0; acpi_ibm_sysctls[i].name != NULL; i++) {
+		int val;
+
+		if ((acpi_ibm_sysctls[i].access & CTLFLAG_RD) == 0) {
+			continue;
+		}
+
+		val = acpi_ibm_sysctl_get(sc, i);
+
+		if ((acpi_ibm_sysctls[i].access & CTLFLAG_WR) == 0) {
+			continue;
+		}
+
+		acpi_ibm_sysctl_set(sc, i, val);
+	}
+	ACPI_SERIAL_END(ibm);
+
+	return (0);
+}
+
 static int
 acpi_ibm_eventmask_set(struct acpi_ibm_softc *sc, int val)
 {

From 322a94307061d6997acf2e978656146851b51f8b Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Sun, 17 Jan 2010 10:58:59 +0000
Subject: [PATCH 1171/2592] Merge r201429:   Fix return code in the case of
 successful file transfer, broken in   tftp.c 1.13

PR:		bin/117452
Submitted by:	Spencer Minear  minear securecomputing.com
Approved by:	ed (mentor, implicit)
---
 usr.bin/tftp/tftp.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/usr.bin/tftp/tftp.c b/usr.bin/tftp/tftp.c
index 2f032df30c4..43009029386 100644
--- a/usr.bin/tftp/tftp.c
+++ b/usr.bin/tftp/tftp.c
@@ -140,6 +140,7 @@ send_data:
 		    (struct sockaddr *)&peer, peer.ss_len);
 		if (n != size + 4) {
 			warn("sendto");
+			txrx_error = 1;
 			goto abort;
 		}
 		read_ahead(file, convert);
@@ -153,6 +154,7 @@ send_data:
 			alarm(0);
 			if (n < 0) {
 				warn("recvfrom");
+				txrx_error = 1;
 				goto abort;
 			}
 			if (!serv.ss_family)
@@ -160,6 +162,7 @@ send_data:
 			else if (!cmpport((struct sockaddr *)&serv,
 			    (struct sockaddr *)&from)) {
 				warn("server port mismatch");
+				txrx_error = 1;
 				goto abort;
 			}
 			peer = from;
@@ -202,7 +205,6 @@ abort:
 	stopclock();
 	if (amount > 0)
 		printstats("Sent", amount);
-	txrx_error = 1;
 }
 
 /*
@@ -255,6 +257,7 @@ send_ack:
 		    peer.ss_len) != size) {
 			alarm(0);
 			warn("sendto");
+			txrx_error = 1;
 			goto abort;
 		}
 		write_behind(file, convert);
@@ -268,6 +271,7 @@ send_ack:
 			alarm(0);
 			if (n < 0) {
 				warn("recvfrom");
+				txrx_error = 1;
 				goto abort;
 			}
 			if (!serv.ss_family)
@@ -275,6 +279,7 @@ send_ack:
 			else if (!cmpport((struct sockaddr *)&serv,
 			    (struct sockaddr *)&from)) {
 				warn("server port mismatch");
+				txrx_error = 1;
 				goto abort;
 			}
 			peer = from;
@@ -325,7 +330,6 @@ abort:						/* ok to ack, since user */
 	stopclock();
 	if (amount > 0)
 		printstats("Received", amount);
-	txrx_error = 1;
 }
 
 static int

From f0bbc7750431a77e129151afcc6e46ab0d8f6340 Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Sun, 17 Jan 2010 11:10:24 +0000
Subject: [PATCH 1172/2592] Merge r201440, r201445 from head:

  Don't complain when we encounter the "cache" source, it's valid.  Also fix
  the error message to include a line feed and not include a stray comma.

  Submitted by: Artis Caune  artis.caune gmail.com

  While here, change "> /dev/stderr" for more usual ">&2"

  Submitted by: jilles

PR:		bin/121671
Approved by:	ed (mentor, implicit)
---
 etc/rc.d/nsswitch | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/etc/rc.d/nsswitch b/etc/rc.d/nsswitch
index 1540583c163..8b0b228d77d 100755
--- a/etc/rc.d/nsswitch
+++ b/etc/rc.d/nsswitch
@@ -77,10 +77,10 @@ generate_host_conf()
 	nis)
 		echo "nis" >> $host_conf
 		;;
-	*=*)
+	cache | *=*)
 		;;
 	*)
-		printf "Warning: unrecognized source [%s]", $_s > "/dev/stderr"
+		printf "Warning: unrecognized source [%s]\n" $_s >&2
 		;;
 	esac
     done

From eecb07159d6e782edce920f5e90d3e6f3cdb832f Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Sun, 17 Jan 2010 11:20:53 +0000
Subject: [PATCH 1173/2592] Merge r197308 from head (originally by ed):

  Spell Israel correctly.

PR:		bin/138580
Submitted by:	Alexey Savartsov 
Approved by:	ed (mentor, implicit)
---
 usr.sbin/sysinstall/menus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/usr.sbin/sysinstall/menus.c b/usr.sbin/sysinstall/menus.c
index 9376ed114f9..8ea7f9876e3 100644
--- a/usr.sbin/sysinstall/menus.c
+++ b/usr.sbin/sysinstall/menus.c
@@ -691,7 +691,7 @@ DMenu MenuMediaFTP = {
       { " Ireland #3",	"ftp3.ie.freebsd.org", NULL, dmenuSetVariable, NULL,
 	VAR_FTP_PATH "=ftp://ftp3.ie.freebsd.org" },
 
-      { "Isreal",	"ftp.il.freebsd.org", NULL, dmenuSetVariable, NULL,
+      { "Israel",	"ftp.il.freebsd.org", NULL, dmenuSetVariable, NULL,
 	VAR_FTP_PATH "=ftp://ftp.il.freebsd.org" },
 
       { "Italy",	"ftp.it.freebsd.org", NULL, dmenuSetVariable, NULL,

From 06f863198851a40f5a170207b5e2822d38e927d8 Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Sun, 17 Jan 2010 13:23:53 +0000
Subject: [PATCH 1174/2592] MFC r201688:

  Correct a typo.

  Submitted by: sn_ (sn_ gmx.net) on hackers@
---
 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 ae52f1193bd..57f8d32c59a 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -296,7 +296,7 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
 	 * we should basically suppress sending an error (RFC 2463, Section
 	 * 2.4).
 	 * We have two exceptions (the item e.2 in that section):
-	 * - the Pakcet Too Big message can be sent for path MTU discovery.
+	 * - the Packet Too Big message can be sent for path MTU discovery.
 	 * - the Parameter Problem Message that can be allowed an icmp6 error
 	 *   in the option type field.  This check has been done in
 	 *   ip6_unknown_opt(), so we can just check the type and code.

From 71902ae69a54ab53293e1c7909ac7d04ee14136d Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Sun, 17 Jan 2010 13:28:06 +0000
Subject: [PATCH 1175/2592] MFC r201742:   After adding an SDT provider for
 opencrypto in r199884 we should also   depend on opt_kdtrace.h for the module
 build.

  Submitted by: (Andre.Albsmeier siemens.com)
---
 sys/modules/crypto/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/modules/crypto/Makefile b/sys/modules/crypto/Makefile
index 891f7e47347..be801db598d 100644
--- a/sys/modules/crypto/Makefile
+++ b/sys/modules/crypto/Makefile
@@ -16,6 +16,6 @@ SRCS	+= skipjack.c bf_enc.c bf_skey.c
 SRCS	+= des_ecb.c des_enc.c des_setkey.c
 SRCS	+= sha1.c sha2.c
 SRCS	+= opt_param.h cryptodev_if.h bus_if.h device_if.h
-SRCS	+= opt_ddb.h
+SRCS	+= opt_ddb.h opt_kdtrace.h
 SRCS	+= camellia.c camellia-api.c
 .include 

From 8f335c80b5a2dc48b3986b294f6d7a5995bda2c5 Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Sun, 17 Jan 2010 13:36:13 +0000
Subject: [PATCH 1176/2592] MFC r201898:   Add comments trying to explain what
 bad things happen here, i.e.   how hashed MD5/SHA are implemented, abusing
 Final() for padding and   sw_octx to transport the key from the beginning to
 the end.

  Enlightened about what was going on here by: cperciva
  Reviewed by:  cperciva
---
 sys/opencrypto/cryptosoft.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c
index 97b73a214f4..a404cbc75a2 100644
--- a/sys/opencrypto/cryptosoft.c
+++ b/sys/opencrypto/cryptosoft.c
@@ -434,7 +434,16 @@ swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
 	case CRYPTO_MD5_KPDK:
 	case CRYPTO_SHA1_KPDK:
 	{
-		/* We need a buffer that can hold an md5 and a sha1 result. */
+		/* 
+		 * We need a buffer that can hold an md5 and a sha1 result
+		 * just to throw it away.
+		 * What we do here is the initial part of:
+		 *   ALGO( key, keyfill, .. )
+		 * adding the key to sw_ictx and abusing Final() to get the
+		 * "keyfill" padding.
+		 * In addition we abuse the sw_octx to save the key to have
+		 * it to be able to append it at the end in swcr_authcompute().
+		 */
 		u_char buf[SHA1_RESULTLEN];
 
 		sw->sw_klen = klen;
@@ -495,9 +504,17 @@ swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
 
 	case CRYPTO_MD5_KPDK:
 	case CRYPTO_SHA1_KPDK:
+		/* If we have no key saved, return error. */
 		if (sw->sw_octx == NULL)
 			return EINVAL;
 
+		/*
+		 * Add the trailing copy of the key (see comment in
+		 * swcr_authprepare()) after the data:
+		 *   ALGO( .., key, algofill )
+		 * and let Final() do the proper, natural "algofill"
+		 * padding.
+		 */
 		axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
 		axf->Final(aalg, &ctx);
 		break;

From cd10550438b395a5fc3e0b5561d4677b3ca9a2a2 Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Sun, 17 Jan 2010 13:38:11 +0000
Subject: [PATCH 1177/2592] MFC r201995:   Correct a typo.

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

diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
index 00f99fdfa5c..a6b7a7c86cf 100644
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -323,7 +323,7 @@ epair_add_ifp_for_draining(struct ifnet *ifp)
 	STAILQ_FOREACH(elm, &epair_dpcpu->epair_ifp_drain_list, ifp_next)
 		if (elm->ifp == ifp)
 			break;
-	/* If the ipf is there already, return success. */
+	/* If the ifp is there already, return success. */
 	if (elm != NULL)
 		return (0);
 

From 66cbfdf2906bd116c28fb5fc70845e7ef689b3cc Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Sun, 17 Jan 2010 13:42:07 +0000
Subject: [PATCH 1178/2592] MFC r202116:   Adjust a comment to reflect reality,
 as we have proper source   address selection, even for IPv4, since r183571.

  Pointed out by:	Jase Thew (bazerka beardz.net)
---
 sys/kern/kern_jail.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 0900541f2cc..c3c2568da7d 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -753,7 +753,9 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
 			 * IP addresses are all sorted but ip[0] to preserve
 			 * the primary IP address as given from userland.
 			 * This special IP is used for unbound outgoing
-			 * connections as well for "loopback" traffic.
+			 * connections as well for "loopback" traffic in case
+			 * source address selection cannot find any more fitting
+			 * address to connect from.
 			 */
 			if (ip4s > 1)
 				qsort(ip4 + 1, ip4s - 1, sizeof(*ip4), qcmp_v4);

From f0e64789dd5e1955c5726a8a09553f13ae212b06 Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Sun, 17 Jan 2010 15:20:34 +0000
Subject: [PATCH 1179/2592] MFC r201806:   Switch traceroute over to make use
 of proper in-kernel source   address selection.

  Reviewed by:  rwatson, fenner
  PR:           kern/139454
  Tested by:    Frank Steinborn (steinex nognu.de)

MFC r201897:
  Correct spelling.

  Submitted by: (pluknet gmail.com)
---
 usr.sbin/traceroute/Makefile        |  4 +-
 usr.sbin/traceroute/findsaddr-udp.c | 94 +++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 2 deletions(-)
 create mode 100644 usr.sbin/traceroute/findsaddr-udp.c

diff --git a/usr.sbin/traceroute/Makefile b/usr.sbin/traceroute/Makefile
index 489c862089e..3898af8d0b5 100644
--- a/usr.sbin/traceroute/Makefile
+++ b/usr.sbin/traceroute/Makefile
@@ -5,7 +5,7 @@ TRACEROUTE_DISTDIR?= ${.CURDIR}/../../contrib/traceroute
 
 PROG=	traceroute
 MAN=	traceroute.8
-SRCS=	as.c version.c traceroute.c ifaddrlist.c findsaddr-socket.c
+SRCS=	as.c version.c traceroute.c ifaddrlist.c findsaddr-udp.c
 BINOWN=	root
 BINMODE=4555
 CLEANFILES=	version.c
@@ -29,7 +29,7 @@ DPADD=	${LIBIPSEC}
 LDADD=	-lipsec
 .endif
 
-CFLAGS+= -I${TRACEROUTE_DISTDIR}/lbl
+CFLAGS+= -I${TRACEROUTE_DISTDIR}/lbl -I${TRACEROUTE_DISTDIR}
 
 version.c: ${TRACEROUTE_DISTDIR}/VERSION
 	@rm -f ${.TARGET}
diff --git a/usr.sbin/traceroute/findsaddr-udp.c b/usr.sbin/traceroute/findsaddr-udp.c
new file mode 100644
index 00000000000..3da72c700a8
--- /dev/null
+++ b/usr.sbin/traceroute/findsaddr-udp.c
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2010 Bjoern A. Zeeb 
+ * 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$
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+
+#include "findsaddr.h"
+#include "traceroute.h"
+
+/*
+ * Return the source address for the given destination address.
+ *
+ * This makes use of proper source address selection in the FreeBSD kernel
+ * even taking jails into account (sys/netinet/in_pcb.c:in_pcbladdr()).
+ * We open a UDP socket, and connect to the destination, letting the kernel
+ * do the bind and then read the source IPv4 address using getsockname(2).
+ * This has multiple advantages: no need to do PF_ROUTE operations possibly
+ * needing special privileges, jails properly taken into account and most
+ * important - getting the result the kernel would give us rather than
+ * best-guessing ourselves.
+ */
+const char *
+findsaddr(register const struct sockaddr_in *to,
+    register struct sockaddr_in *from)
+{
+	const char *errstr;
+	struct sockaddr_in cto, cfrom;
+	int s;
+	socklen_t len;
+
+	s = socket(AF_INET, SOCK_DGRAM, 0);
+	if (s == -1)
+		return ("failed to open DGRAM socket for src addr selection.");
+
+	errstr = NULL;
+	len = sizeof(struct sockaddr_in);
+	memcpy(&cto, to, len);
+	cto.sin_port = htons(65535);	/* Dummy port for connect(2). */
+	if (connect(s, (struct sockaddr *)&cto, len) == -1) {
+		errstr = "failed to connect to peer for src addr selection.";
+		goto err;
+	}
+
+	if (getsockname(s, (struct sockaddr *)&cfrom, &len) == -1) {
+		errstr = "failed to get socket name for src addr selection.";
+		goto err;
+	}
+
+	if (len != sizeof(struct sockaddr_in) || cfrom.sin_family != AF_INET) {
+		errstr = "unexpected address family in src addr selection.";
+		goto err;
+	}
+
+	/* Update source address for traceroute. */
+	setsin(from, cfrom.sin_addr.s_addr);
+
+err:
+	(void) close(s);
+
+	/* No error (string) to return. */
+	return (errstr);
+}
+
+/* end */

From a8725a275afea9b0b901ecf825791b14a663fc29 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 16:58:37 +0000
Subject: [PATCH 1180/2592] MFC 198522:

Bugfix: Use formula from section 7.2.3 of RFC 4960. Reported by Martin Becke.
---
 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 801fc2d03551cf983e5c87ff6461a37544b6c49e Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 17:01:01 +0000
Subject: [PATCH 1181/2592] MFC 199369

Do not hold the lock longer than necessary.
---
 sys/netinet/sctputil.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 94dea3fa73d..3f0b2a2bc53 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -6156,11 +6156,11 @@ sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id)
 	 * newest first :-0
 	 */
 	LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
+	SCTP_IPI_ITERATOR_WQ_UNLOCK();
 	sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
 	    (struct sctp_inpcb *)NULL,
 	    (struct sctp_tcb *)NULL,
 	    (struct sctp_nets *)NULL);
-	SCTP_IPI_ITERATOR_WQ_UNLOCK();
 	return (0);
 }
 

From 24a263d9dad763e1a25fa2894d67c6d083dec182 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 17:03:40 +0000
Subject: [PATCH 1182/2592] MFC 199372

Do not start the iterator when there are no associations.
This fixes a bug found by Irene Ruengeler.
---
 sys/netinet/sctp_asconf.c | 74 ++++++++++++++++++++-------------------
 1 file changed, 38 insertions(+), 36 deletions(-)

diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index 404b5ad0aa7..9c46e7992ea 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -3180,24 +3180,6 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
 		ifa = NULL;
 	}
 	if (ifa != NULL) {
-		/* add this address */
-		struct sctp_asconf_iterator *asc;
-		struct sctp_laddr *wi;
-
-		SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
-		    sizeof(struct sctp_asconf_iterator),
-		    SCTP_M_ASC_IT);
-		if (asc == NULL) {
-			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
-			return (ENOMEM);
-		}
-		wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr),
-		    struct sctp_laddr);
-		if (wi == NULL) {
-			SCTP_FREE(asc, SCTP_M_ASC_IT);
-			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
-			return (ENOMEM);
-		}
 		if (type == SCTP_ADD_IP_ADDRESS) {
 			sctp_add_local_addr_ep(inp, ifa, type);
 		} else if (type == SCTP_DEL_IP_ADDRESS) {
@@ -3205,8 +3187,6 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
 
 			if (inp->laddr_count < 2) {
 				/* can't delete the last local address */
-				SCTP_FREE(asc, SCTP_M_ASC_IT);
-				SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
 				return (EINVAL);
 			}
@@ -3218,27 +3198,49 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
 				}
 			}
 		}
-		LIST_INIT(&asc->list_of_work);
-		asc->cnt = 1;
-		SCTP_INCR_LADDR_COUNT();
-		wi->ifa = ifa;
-		wi->action = type;
-		atomic_add_int(&ifa->refcount, 1);
-		LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
-		(void)sctp_initiate_iterator(sctp_asconf_iterator_ep,
-		    sctp_asconf_iterator_stcb,
-		    sctp_asconf_iterator_ep_end,
-		    SCTP_PCB_ANY_FLAGS,
-		    SCTP_PCB_ANY_FEATURES,
-		    SCTP_ASOC_ANY_STATE,
-		    (void *)asc, 0,
-		    sctp_asconf_iterator_end, inp, 0);
+		if (!LIST_EMPTY(&inp->sctp_asoc_list)) {
+			/*
+			 * There is no need to start the iterator if the inp
+			 * has no associations.
+			 */
+			struct sctp_asconf_iterator *asc;
+			struct sctp_laddr *wi;
+
+			SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
+			    sizeof(struct sctp_asconf_iterator),
+			    SCTP_M_ASC_IT);
+			if (asc == NULL) {
+				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
+				return (ENOMEM);
+			}
+			wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
+			if (wi == NULL) {
+				SCTP_FREE(asc, SCTP_M_ASC_IT);
+				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
+				return (ENOMEM);
+			}
+			LIST_INIT(&asc->list_of_work);
+			asc->cnt = 1;
+			SCTP_INCR_LADDR_COUNT();
+			wi->ifa = ifa;
+			wi->action = type;
+			atomic_add_int(&ifa->refcount, 1);
+			LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
+			(void)sctp_initiate_iterator(sctp_asconf_iterator_ep,
+			    sctp_asconf_iterator_stcb,
+			    sctp_asconf_iterator_ep_end,
+			    SCTP_PCB_ANY_FLAGS,
+			    SCTP_PCB_ANY_FEATURES,
+			    SCTP_ASOC_ANY_STATE,
+			    (void *)asc, 0,
+			    sctp_asconf_iterator_end, inp, 0);
+		}
+		return (0);
 	} else {
 		/* invalid address! */
 		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EADDRNOTAVAIL);
 		return (EADDRNOTAVAIL);
 	}
-	return (0);
 }
 
 void

From 33dabcc064b69f7ae48a4aa4fdc4d79caddbada0 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 17:05:59 +0000
Subject: [PATCH 1183/2592] MFC 199437

Use always LIST_EMPTY instead of sometime SCTP_LIST_EMPTY,
which is defined as LIST_EMPTY.
---
 sys/netinet/sctp_auth.c   |  2 +-
 sys/netinet/sctp_os_bsd.h |  1 -
 sys/netinet/sctp_pcb.c    | 14 +++++++-------
 sys/netinet/sctp_usrreq.c |  2 +-
 4 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c
index a166cb4b9c9..5e8c51890fe 100644
--- a/sys/netinet/sctp_auth.c
+++ b/sys/netinet/sctp_auth.c
@@ -573,7 +573,7 @@ sctp_insert_sharedkey(struct sctp_keyhead *shared_keys,
 		return (EINVAL);
 
 	/* insert into an empty list? */
-	if (SCTP_LIST_EMPTY(shared_keys)) {
+	if (LIST_EMPTY(shared_keys)) {
 		LIST_INSERT_HEAD(shared_keys, new_skey, next);
 		return (0);
 	}
diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h
index b77c9143eb2..349d1642f88 100644
--- a/sys/netinet/sctp_os_bsd.h
+++ b/sys/netinet/sctp_os_bsd.h
@@ -153,7 +153,6 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
  *
  */
 #define USER_ADDR_NULL	(NULL)	/* FIX ME: temp */
-#define SCTP_LIST_EMPTY(list)	LIST_EMPTY(list)
 
 #if defined(SCTP_DEBUG)
 #define SCTPDBG(level, params...)					\
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 8370dcc4c96..b2ebfbe8c10 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -452,7 +452,7 @@ sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap)
 			sctp_ifap->ifn_p->num_v4--;
 
 		ifn_index = sctp_ifap->ifn_p->ifn_index;
-		if (SCTP_LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) {
+		if (LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) {
 			/* remove the ifn, possibly freeing it */
 			sctp_delete_ifn(sctp_ifap->ifn_p, SCTP_ADDR_LOCKED);
 		} else {
@@ -4262,7 +4262,7 @@ sctp_delete_from_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
 	int i;
 
 	chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
-	if (!SCTP_LIST_EMPTY(chain)) {
+	if (!LIST_EMPTY(chain)) {
 		LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
 			for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
 				if ((twait_block->vtag_block[i].v_tag == tag) &&
@@ -4292,7 +4292,7 @@ sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
 
 	SCTP_INP_INFO_WLOCK();
 	chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
-	if (!SCTP_LIST_EMPTY(chain)) {
+	if (!LIST_EMPTY(chain)) {
 		LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
 			for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
 				if ((twait_block->vtag_block[i].v_tag == tag) &&
@@ -4326,7 +4326,7 @@ sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t
 	(void)SCTP_GETTIME_TIMEVAL(&now);
 	chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
 	set = 0;
-	if (!SCTP_LIST_EMPTY(chain)) {
+	if (!LIST_EMPTY(chain)) {
 		/* Block(s) present, lets find space, and expire on the fly */
 		LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
 			for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
@@ -4953,7 +4953,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
 		sctp_free_remote_addr(net);
 	}
 
-	while (!SCTP_LIST_EMPTY(&asoc->sctp_restricted_addrs)) {
+	while (!LIST_EMPTY(&asoc->sctp_restricted_addrs)) {
 		/* sa_ignore FREED_MEMORY */
 		laddr = LIST_FIRST(&asoc->sctp_restricted_addrs);
 		sctp_remove_laddr(laddr);
@@ -5617,7 +5617,7 @@ sctp_pcb_finish(void)
 	 */
 	for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
 		chain = &SCTP_BASE_INFO(vtag_timewait)[i];
-		if (!SCTP_LIST_EMPTY(chain)) {
+		if (!LIST_EMPTY(chain)) {
 			prev_twait_block = NULL;
 			LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
 				if (prev_twait_block) {
@@ -6387,7 +6387,7 @@ skip_vtag_check:
 
 	chain = &SCTP_BASE_INFO(vtag_timewait[(tag % SCTP_STACK_VTAG_HASH_SIZE))];
 	/* Now what about timed wait ? */
-	if (!SCTP_LIST_EMPTY(chain)) {
+	if (!LIST_EMPTY(chain)) {
 		/*
 		 * Block(s) are present, lets see if we have this tag in the
 		 * list
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index a8ea998a3b3..9e1c01a2c3b 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -759,7 +759,7 @@ sctp_disconnect(struct socket *so)
 	SCTP_INP_RLOCK(inp);
 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
 	    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
-		if (SCTP_LIST_EMPTY(&inp->sctp_asoc_list)) {
+		if (LIST_EMPTY(&inp->sctp_asoc_list)) {
 			/* No connection */
 			SCTP_INP_RUNLOCK(inp);
 			return (0);

From fb7bf5f3742c92c5c0ac2135e94bd6a412fdf216 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 17:10:17 +0000
Subject: [PATCH 1184/2592] MFC 198499

Improve the round robin stream scheduler.
---
 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 96057e559a0..6ce03ae9d72 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -7190,22 +7190,16 @@ 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);
 	}
 	/* Save off the last stream */
 	asoc->last_out_stream = strq;
 	return (strq);
-
 }
 
 

From c1bf101993883affee3b613749bb12780863dfbf Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sun, 17 Jan 2010 17:31:53 +0000
Subject: [PATCH 1185/2592] MFC: r201870, r201889

Various language fixes.  Also fixed the URL to totd, obtained from NetBSD.
---
 share/man/man4/faith.4   | 37 +++++++++--------
 usr.sbin/faithd/faithd.8 | 87 +++++++++++++++++++---------------------
 2 files changed, 60 insertions(+), 64 deletions(-)

diff --git a/share/man/man4/faith.4 b/share/man/man4/faith.4
index 3f13cd66255..b98ba394560 100644
--- a/share/man/man4/faith.4
+++ b/share/man/man4/faith.4
@@ -58,15 +58,15 @@ variable in
 .Xr rc.conf 5 .
 .Pp
 Special action will be taken when IPv6 TCP traffic is seen on a router,
-and routing table suggests to route it to
+and the routing table suggests to route it to the
 .Nm
 interface.
 In this case, the packet will be accepted by the router,
-regardless of list of IPv6 interface addresses assigned to the router.
-The packet will be captured by an IPv6 TCP socket, if it has
+regardless of the list of IPv6 interface addresses assigned to the router.
+The packet will be captured by an IPv6 TCP socket, if it has the
 .Dv IN6P_FAITH
-flag turned on and it has matching address/port pairs.
-In result,
+flag turned on and matching address/port pairs.
+As a result,
 .Nm
 will let you capture IPv6 TCP traffic to some specific destination addresses.
 Userland programs, such as
@@ -79,43 +79,42 @@ and perform application-specific address mapping to relay IPv6 TCP to IPv4 TCP.
 .Pp
 The
 .Dv IN6P_FAITH
-flag on IPv6 TCP socket can be set by using
+flag on a IPv6 TCP socket can be set by using
 .Xr setsockopt 2 ,
-with level equals to
+with level
 .Dv IPPROTO_IPV6
-and optname equals to
+and optname
 .Dv IPv6_FAITH .
 .Pp
-To handle error reports by ICMPv6, some of ICMPv6 packets routed to
+To handle error reports by ICMPv6, some ICMPv6 packets routed to an
 .Nm
 interface will be delivered to IPv6 TCP, as well.
 .Pp
 To understand how
 .Nm
-can be used, take a look at source code of
+can be used, take a look at the source code of
 .Xr faithd 8 .
 .Pp
-As
+As the
 .Nm
-interface implements potentially dangerous operation,
-great care must be taken when configuring
-.Nm
-interface.
-To avoid possible misuse,
+interface implements potentially dangerous operations,
+great care must be taken when configuring it.
+To avoid possible misuse, the
 .Xr sysctl 8
 variable
 .Li net.inet6.ip6.keepfaith
 must be set to
 .Li 1
-prior to the use of the interface.
+prior to using the interface.
 When
 .Li net.inet6.ip6.keepfaith
 is
 .Li 0 ,
-no packet will be captured by
+no packets will be captured by the
 .Nm
 interface.
 .Pp
+The
 .Nm
 interface is intended to be used on routers, not on hosts.
 .\"
@@ -130,5 +129,5 @@ interface is intended to be used on routers, not on hosts.
 .%O RFC3142
 .Re
 .Sh HISTORY
-The FAITH IPv6-to-IPv4 TCP relay translator was first appeared in
+The FAITH IPv6-to-IPv4 TCP relay translator first appeared in the
 WIDE hydrangea IPv6 stack.
diff --git a/usr.sbin/faithd/faithd.8 b/usr.sbin/faithd/faithd.8
index 5d16989902f..eef3ed91c27 100644
--- a/usr.sbin/faithd/faithd.8
+++ b/usr.sbin/faithd/faithd.8
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 17, 1998
+.Dd January 9, 2010
 .Dt FAITHD 8
 .Os
 .Sh NAME
@@ -44,20 +44,18 @@
 .Sh DESCRIPTION
 The
 .Nm
-utility provides IPv6-to-IPv4 TCP relay.
-It must be used on an IPv4/v6 dual stack router.
+utility provides IPv6-to-IPv4 TCP relaying.
+It can only be used on an IPv4/v6 dual stack router.
 .Pp
 When
 .Nm
 receives
 .Tn TCPv6
-traffic,
-.Nm
-will relay the
+traffic, it will relay the
 .Tn TCPv6
 traffic to
 .Tn TCPv4 .
-Destination for relayed
+The destination for the relayed
 .Tn TCPv4
 connection will be determined by the last 4 octets of the original
 .Tn IPv6
@@ -73,14 +71,14 @@ destination address is
 the traffic will be relayed to IPv4 destination
 .Li 10.1.1.1 .
 .Pp
-To use
+To use the
 .Nm
 translation service,
 an IPv6 address prefix must be reserved for mapping IPv4 addresses into.
-Kernel must be properly configured to route all the TCP connection
+The kernel must be properly configured to route all the TCP connections
 toward the reserved IPv6 address prefix into the
 .Xr faith 4
-pseudo interface, by using
+pseudo interface, using the
 .Xr route 8
 command.
 Also,
@@ -91,7 +89,7 @@ to
 .Dv 1 .
 .Pp
 The router must be configured to capture all the TCP traffic
-toward reserved
+for the reserved
 .Tn IPv6
 address prefix, by using
 .Xr route 8
@@ -101,21 +99,20 @@ commands.
 .Pp
 The
 .Nm
-utility needs a special name-to-address translation logic, so that
-hostnames gets resolved into special
+utility needs special name-to-address translation logic, so that
+hostnames get resolved into the special
 .Tn IPv6
 address prefix.
-For small-scale installation, use
-.Xr hosts 5 .
-For large-scale installation, it is useful to have
+For small-scale installations, use
+.Xr hosts 5 ;
+For large-scale installations, it is useful to have
 a DNS server with special address translation support.
 An implementation called
 .Nm totd
-is available
-at
-.Pa http://www.vermicelli.pasta.cs.uit.no/ipv6/software.html .
-Make sure you do not propagate translated DNS records to normal DNS cloud,
-it is highly harmful.
+is available at
+.Pa http://www.vermicelli.pasta.cs.uit.no/software/totd.html .
+Make sure you do not propagate translated DNS records over to normal
+DNS, as it can cause severe problems.
 .Ss Daemon mode
 When
 .Nm
@@ -150,9 +147,9 @@ to
 you can run local daemons on the router.
 The
 .Nm
-utility will invoke local daemon at
+utility will invoke a local daemon at
 .Ar serverpath
-if the destination address is local interface address,
+if the destination address is a local interface address,
 and will perform translation to IPv4 TCP in other cases.
 You can also specify
 .Ar serverargs
@@ -182,7 +179,7 @@ The
 .Nm
 utility includes special support for protocols used by
 .Xr ftp 1 .
-When translating FTP protocol,
+When translating the FTP protocol,
 .Nm
 translates network level addresses in
 .Li PORT/LPRT/EPRT
@@ -191,8 +188,8 @@ and
 commands.
 .Pp
 Inactive sessions will be disconnected in 30 minutes,
-to avoid stale sessions from chewing up resources.
-This may be inappropriate for some of the services
+to prevent stale sessions from chewing up resources.
+This may be inappropriate for some services
 (should this be configurable?).
 .Ss inetd mode
 When
@@ -200,13 +197,13 @@ When
 is invoked via
 .Xr inetd 8 ,
 .Nm
-will handle connection passed from standard input.
+will handle connections passed from standard input.
 If the connection endpoint is in the reserved IPv6 address prefix,
 .Nm
 will relay the connection.
 Otherwise,
 .Nm
-will invoke service-specific daemon like
+will invoke a service-specific daemon like
 .Xr telnetd 8 ,
 by using the command argument passed from
 .Xr inetd 8 .
@@ -219,16 +216,16 @@ For example, if
 .Nm
 is invoked via
 .Xr inetd 8
-on FTP port, it will operate as a FTP relay.
+on the FTP port, it will operate as an FTP relay.
 .Pp
 The operation mode requires special support for
 .Nm
 in
 .Xr inetd 8 .
 .Ss Access control
-To prevent malicious accesses,
+To prevent malicious access,
 .Nm
-implements a simple address-based access control.
+implements simple address-based access control.
 With
 .Pa /etc/faithd.conf
 (or
@@ -239,7 +236,7 @@ specified by
 will avoid relaying unwanted traffic.
 The
 .Pa faithd.conf
-contains directives with the following format:
+configuration file contains directives of the following format:
 .Bl -bullet
 .It
 .Ar src Ns / Ns Ar slen Cm deny Ar dst Ns / Ns Ar dlen
@@ -281,6 +278,7 @@ on error.
 .Sh EXAMPLES
 Before invoking
 .Nm ,
+the
 .Xr faith 4
 interface has to be configured properly.
 .Bd -literal -offset
@@ -334,12 +332,12 @@ ssh     stream  tcp6/faith  nowait  root  faithd  /usr/sbin/sshd -i
 .Ed
 .Pp
 .Xr inetd 8
-will open listening sockets with enabling kernel TCP relay support.
-Whenever connection comes in,
+will open listening sockets with kernel TCP relay support enabled.
+Whenever a connection comes in,
 .Nm
 will be invoked by
 .Xr inetd 8 .
-If it the connection endpoint is in the reserved IPv6 address prefix.
+If the connection endpoint is in the reserved IPv6 address prefix.
 The
 .Nm
 utility will relay the connection.
@@ -377,12 +375,12 @@ setting.
 .Sh HISTORY
 The
 .Nm
-utility first appeared in WIDE Hydrangea IPv6 protocol stack kit.
+utility first appeared in the WIDE Hydrangea IPv6 protocol stack kit.
 .\"
 .Pp
 IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
 was initially integrated into
-.Fx 4.0
+.Fx 4.0 .
 .Sh SECURITY CONSIDERATIONS
 It is very insecure to use IP-address based authentication, for connections relayed by
 .Nm ,
@@ -392,16 +390,15 @@ Administrators are advised to limit accesses to
 .Nm
 using
 .Pa faithd.conf ,
-or by using IPv6 packet filters.
-It is to protect
+or by using IPv6 packet filters, to protect the
 .Nm
-service from malicious parties and avoid theft of service/bandwidth.
-IPv6 destination address can be limited by
-carefully configuring routing entries that points to
+service from malicious parties, and to avoid theft of service/bandwidth.
+IPv6 destination addresses can be limited by
+carefully configuring routing entries that point to
 .Xr faith 4 ,
 using
 .Xr route 8 .
-IPv6 source address needs to be filtered by using packet filters.
-Documents listed in
+The IPv6 source address needs to be filtered using packet filters.
+The documents listed in
 .Sx SEE ALSO
-have more discussions on this topic.
+have more information on this topic.

From 53b14b72943b4eec5830ca0494f39a8c8b7c79ce Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 17:41:43 +0000
Subject: [PATCH 1186/2592] MFC 197341

Fix errnos.
---
 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 6ce03ae9d72..02bca9044c8 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);
@@ -7197,8 +7176,6 @@ sctp_select_a_stream(struct sctp_tcb *stcb, struct sctp_association *asoc)
 			strq = TAILQ_FIRST(&asoc->out_wheel);
 		}
 	}
-	/* Save off the last stream */
-	asoc->last_out_stream = strq;
 	return (strq);
 }
 
@@ -7274,7 +7251,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 533e1ca3108e0d078b408384fe2623c6dda70739 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 17:45:09 +0000
Subject: [PATCH 1187/2592] MFC 198621

Improve round robin stream scheduler and cleanup some code.
---
 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 64224569da744eb9f76082e0857fe8dcde8dadc7 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 17:46:48 +0000
Subject: [PATCH 1188/2592] MFC 199374

Fix a bug where queued ASCONF messags are not sent out.
From Irene Ruengeler.
---
 sys/netinet/sctp_output.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 8c29f70b7c4..60e18ab0259 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -9442,6 +9442,7 @@ sctp_chunk_output(struct sctp_inpcb *inp,
 
 	if ((un_sent <= 0) &&
 	    (TAILQ_EMPTY(&asoc->control_send_queue)) &&
+	    (TAILQ_EMPTY(&asoc->asconf_send_queue)) &&
 	    (asoc->sent_queue_retran_cnt == 0)) {
 		/* Nothing to do unless there is something to be sent left */
 		return;

From 45bde0da396e6f0d0b9a0aa2a0ce58e7667f5a7f Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 17:49:28 +0000
Subject: [PATCH 1189/2592] MFC 199459

Get rid of unused fields addr_over which is never really used,
only copied around.
---
 sys/netinet/sctp_output.c  | 5 -----
 sys/netinet/sctp_structs.h | 4 ----
 sys/netinet/sctputil.c     | 1 -
 3 files changed, 10 deletions(-)

diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 60e18ab0259..cbc9a9aabef 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -5875,10 +5875,8 @@ sctp_msg_append(struct sctp_tcb *stcb,
 	sp->strseq = 0;
 	if (sp->sinfo_flags & SCTP_ADDR_OVER) {
 		sp->net = net;
-		sp->addr_over = 1;
 	} else {
 		sp->net = stcb->asoc.primary_destination;
-		sp->addr_over = 0;
 	}
 	atomic_add_int(&sp->net->ref_count, 1);
 	(void)SCTP_GETTIME_TIMEVAL(&sp->ts);
@@ -7052,7 +7050,6 @@ dont_do_it:
 
 	chk->rec.data.timetodrop = sp->ts;
 	chk->flags = sp->act_flags;
-	chk->addr_over = sp->addr_over;
 
 	chk->whoTo = net;
 	atomic_add_int(&chk->whoTo->ref_count, 1);
@@ -12252,10 +12249,8 @@ skip_copy:
 	} else {
 		if (sp->sinfo_flags & SCTP_ADDR_OVER) {
 			sp->net = net;
-			sp->addr_over = 1;
 		} else {
 			sp->net = asoc->primary_destination;
-			sp->addr_over = 0;
 		}
 		atomic_add_int(&sp->net->ref_count, 1);
 		sctp_set_prsctp_policy(sp);
diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h
index 595c37c3e7a..b1a0f13a650 100644
--- a/sys/netinet/sctp_structs.h
+++ b/sys/netinet/sctp_structs.h
@@ -364,9 +364,6 @@ struct sctp_tmit_chunk {
 	uint8_t pad_inplace;
 	uint8_t do_rtt;
 	uint8_t book_size_scale;
-	uint8_t addr_over;	/* flag which is set if the dest address for
-				 * this chunk is overridden by user. Used for
-				 * CMT (iyengar@cis.udel.edu, 2005/06/21) */
 	uint8_t no_fr_allowed;
 	uint8_t pr_sctp_on;
 	uint8_t copy_by_ref;
@@ -444,7 +441,6 @@ struct sctp_stream_queue_pending {
 	uint8_t holds_key_ref;
 	uint8_t msg_is_complete;
 	uint8_t some_taken;
-	uint8_t addr_over;
 	uint8_t pr_sctp_on;
 	uint8_t sender_all_done;
 	uint8_t put_last_out;
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 3f0b2a2bc53..65de46229e4 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -4791,7 +4791,6 @@ next_on_sent:
 					chk->rec.data.payloadtype = sp->ppid;
 					chk->rec.data.context = sp->context;
 					chk->flags = sp->act_flags;
-					chk->addr_over = sp->addr_over;
 					chk->whoTo = sp->net;
 					atomic_add_int(&chk->whoTo->ref_count, 1);
 					chk->rec.data.TSN_seq = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1);

From c44809a53dd03bff6158dbafc12aacf41f968918 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sun, 17 Jan 2010 18:17:00 +0000
Subject: [PATCH 1190/2592] MFC: r197056 by des

Fix comment about KERNFAST.

PR:             142854
Submitted by:   Nikolay Denev 
---
 Makefile.inc1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.inc1 b/Makefile.inc1
index 3cc82fa4eae..0acee7d6d21 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -5,7 +5,7 @@
 #	-DNO_CLEANDIR run ${MAKE} clean, instead of ${MAKE} cleandir
 #	-DNO_CLEAN do not clean at all
 #	-DNO_SHARE do not go into share subdir
-#	-DKERNFAST define NO_KERNELCONFIG, NO_KERNELCLEAN and NO_KERNELCONFIG
+#	-DKERNFAST define NO_KERNELCONFIG, NO_KERNELCLEAN and NO_KERNELDEPEND
 #	-DNO_KERNELCONFIG do not run config in ${MAKE} buildkernel
 #	-DNO_KERNELCLEAN do not run ${MAKE} clean in ${MAKE} buildkernel
 #	-DNO_KERNELDEPEND do not run ${MAKE} depend in ${MAKE} buildkernel

From 06ee5047d5ed6272fc6b7bcd8c55edfc6f74e5b9 Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 17 Jan 2010 18:18:01 +0000
Subject: [PATCH 1191/2592] MFC 201523

Correct usage of parenthesis.
---
 sys/netinet/sctp_pcb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index b2ebfbe8c10..682af5e40c2 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -5528,7 +5528,7 @@ sctp_pcb_init()
 
 	/* Init the TIMEWAIT list */
 	for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
-		LIST_INIT(&SCTP_BASE_INFO(vtag_timewait[i]));
+		LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]);
 	}
 
 #if defined(SCTP_USE_THREAD_BASED_ITERATOR)
@@ -6385,7 +6385,7 @@ sctp_is_vtag_good(struct sctp_inpcb *inp, uint32_t tag, uint16_t lport, uint16_t
 	}
 skip_vtag_check:
 
-	chain = &SCTP_BASE_INFO(vtag_timewait[(tag % SCTP_STACK_VTAG_HASH_SIZE))];
+	chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
 	/* Now what about timed wait ? */
 	if (!LIST_EMPTY(chain)) {
 		/*

From bc4acc704fec2d77f671c909389b5c775e0d91ce Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:22:42 +0000
Subject: [PATCH 1192/2592] MFC r202181,202243,202270

 Add a driver by Fredrik Lindberg for Option HSDPA USB devices. These differ
 from standard 3G wireless units by supplying a raw IP/IPv6 endpoint rather than
 using PPP over serial. uhsoctl(1) is used to initiate and close the WAN
 connection.

Obtained from:	Fredrik Lindberg 
---
 share/man/man4/Makefile       |    1 +
 share/man/man4/uhso.4         |  126 +++
 sys/conf/NOTES                |    3 +
 sys/conf/files                |    3 +-
 sys/dev/usb/net/uhso.c        | 1814 +++++++++++++++++++++++++++++++++
 sys/dev/usb/usbdevs           |   12 +
 sys/modules/usb/uhso/Makefile |   37 +
 usr.sbin/Makefile             |    2 +
 usr.sbin/uhsoctl/Makefile     |   10 +
 usr.sbin/uhsoctl/uhsoctl.1    |  104 ++
 usr.sbin/uhsoctl/uhsoctl.c    | 1532 ++++++++++++++++++++++++++++
 11 files changed, 3643 insertions(+), 1 deletion(-)
 create mode 100644 share/man/man4/uhso.4
 create mode 100644 sys/dev/usb/net/uhso.c
 create mode 100644 sys/modules/usb/uhso/Makefile
 create mode 100644 usr.sbin/uhsoctl/Makefile
 create mode 100644 usr.sbin/uhsoctl/uhsoctl.1
 create mode 100644 usr.sbin/uhsoctl/uhsoctl.c

diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 76006acf6c0..ded69130180 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -421,6 +421,7 @@ MAN=	aac.4 \
 	ugen.4 \
 	uhci.4 \
 	uhid.4 \
+	uhso.4 \
 	uipaq.4 \
 	ukbd.4 \
 	ulpt.4 \
diff --git a/share/man/man4/uhso.4 b/share/man/man4/uhso.4
new file mode 100644
index 00000000000..7f10c6212a3
--- /dev/null
+++ b/share/man/man4/uhso.4
@@ -0,0 +1,126 @@
+.\" Copyright (c) 2009 Fredrik Lindberg
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 14, 2010
+.Os
+.Dt UHSO 4
+.Sh NAME
+.Nm uhso
+.Nd support for several HSxPA devices from Option N.V.
+.Sh SYNOPSIS
+The module can be loaded at boot time by placing the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+uhso_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for several HSxPA devices from Option N.V. that are
+based on their packet interface.
+Each device has a set of serial ports and a raw IP packet interface.
+The serial ports of the device are accessed through the
+.Xr ucom 4
+driver which makes them behave like a
+.Xr tty 4 .
+The packet interface is exposed as a network interface.
+.Pp
+Establishing a connection on the packet interface is achieved by using the
+proprietary AT commands
+.Dq Li AT_OWANCALL
+and
+.Dq Li AT_OWANDATA
+on any of the available serial ports.
+.Pp
+The network interface must be configured manually using the data obtain from
+these calls.
+.Pp
+Each device usually have at least two or more serial ports, their individual purpose
+can be identified through
+.Xr sysctl 8 .
+.Sh HARDWARE
+The
+.Nm
+driver supports at least the following cards
+.Pp
+.Bl -bullet -compact
+.It
+Option GlobeSurfer iCON 7.2 (new firmware)
+.It
+Option iCON 225
+.It
+Option iCON 505
+.El
+.Pp
+The device features a mass storage device referred to as
+.Dq Zero-CD
+which contains drivers for Microsoft Windows; this is the default
+mode for the device.
+The
+.Nm
+driver automatically switches the device from
+.Dq Zero-CD
+mode to modem mode.
+This behavior can be disabled by setting
+.Va hw.usb.uhso.auto_switch
+to 0 using
+.Xr sysctl 8
+.Sh EXAMPLES
+Establishing a packet interface connection
+.Bd -literal -offset indent
+AT+CGDCONT=1,,"apn.provider"
+AT_OWANCALL=1,1,1
+OK
+_OWANCALL=1,1
+
+AT_OWANDATA=1
+_OWANDATA: 1, 10.11.12.13, 0.0.0.0, 10.2.3.4, 10.2.3.5, \e
+	0.0.0.0, 0.0.0.0, 72000
+.Ed
+.Pp
+Configuring the interface
+.Bd -literal -offset indent
+ifconfig uhso0 10.11.12.13 up
+route add default -interface uhso0
+echo "nameserver 10.2.3.4" > /etc/resolv.conf
+echo "nameserver 10.2.3.5" >> /etc/resolv.conf
+.Ed
+.Pp
+The connection can be terminated with
+.Bd -literal -offset indent
+AT_OWANCALL=1,0,1
+.Ed
+.Sh FILES
+.Bl -tag -width "XXXXXX"
+.It Pa /dev/cuaU?.?
+.El
+.Sh SEE ALSO
+.Xr ucom 4 ,
+.Xr usb 4
+.Sh AUTHORS
+The
+.Nm
+driver was written by
+.An Fredrik Lindberg Aq fli@shapeshifter.se .
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 57f2dfd6186..3c2a99b663c 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2589,6 +2589,9 @@ device		rue
 #
 # Davicom DM9601E USB to fast ethernet. Supports the Corega FEther USB-TXC.
 device		udav
+#
+# HSxPA devices from Option N.V
+device		uhso
 
 #
 # Ralink Technology RT2501USB/RT2601USB wireless driver
diff --git a/sys/conf/files b/sys/conf/files
index 104c631891a..c1c8b7713c2 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1615,7 +1615,7 @@ dev/usb/usb_request.c		optional usb
 dev/usb/usb_transfer.c		optional usb
 dev/usb/usb_util.c		optional usb
 #
-# USB ethernet drivers
+# USB network drivers
 #
 dev/usb/net/if_aue.c		optional aue
 dev/usb/net/if_axe.c		optional axe
@@ -1626,6 +1626,7 @@ dev/usb/net/if_rue.c		optional rue
 dev/usb/net/if_udav.c		optional udav
 dev/usb/net/usb_ethernet.c	optional aue | axe | cdce | cue | kue | rue | \
 					 udav
+dev/usb/net/uhso.c		optional uhso
 #
 # USB WLAN drivers
 #
diff --git a/sys/dev/usb/net/uhso.c b/sys/dev/usb/net/uhso.c
new file mode 100644
index 00000000000..a810ec48c5d
--- /dev/null
+++ b/sys/dev/usb/net/uhso.c
@@ -0,0 +1,1814 @@
+/*-
+ * Copyright (c) 2009 Fredrik Lindberg 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include 
+__FBSDID("$FreeBSD$");
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#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 uhso_debug
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct uhso_tty {
+	struct uhso_softc *ht_sc;
+	struct usb_xfer	*ht_xfer[3];
+	int		ht_muxport; /* Mux. port no */
+	int		ht_open;
+	char		ht_name[32];
+};
+
+struct uhso_softc {
+	device_t		sc_dev;
+	struct usb_device	*sc_udev;
+	struct mtx		sc_mtx;
+	uint32_t		sc_type;	/* Interface definition */
+
+	struct usb_xfer		*sc_xfer[3];
+	uint8_t			sc_iface_no;
+	uint8_t			sc_iface_index;
+
+	/* Control pipe */
+	struct usb_xfer	*	sc_ctrl_xfer[2];
+	uint8_t			sc_ctrl_iface_no;
+
+	/* Network */
+	struct usb_xfer		*sc_if_xfer[2];
+	struct ifnet		*sc_ifp;
+	struct mbuf		*sc_mwait;	/* Partial packet */
+	size_t			sc_waitlen;	/* No. of outstanding bytes */
+	struct ifqueue		sc_rxq;
+	struct callout		sc_c;
+
+	/* TTY related structures */
+	struct ucom_super_softc sc_super_ucom;
+	int			sc_ttys;
+	struct uhso_tty		*sc_tty;
+	struct ucom_softc	*sc_ucom;
+	int			sc_msr;
+	int			sc_lsr;
+	int			sc_line;
+};
+
+#define UHSO_MAX_MTU		2048
+
+/*
+ * There are mainly two type of cards floating around.
+ * The first one has 2,3 or 4 interfaces with a multiplexed serial port
+ * and packet interface on the first interface and bulk serial ports
+ * on the others.
+ * The second type of card has several other interfaces, their purpose
+ * can be detected during run-time.
+ */
+#define UHSO_IFACE_SPEC(usb_type, port, port_type) \
+	(((usb_type) << 24) | ((port) << 16) | (port_type))
+
+#define UHSO_IFACE_USB_TYPE(x) ((x >> 24) & 0xff)
+#define UHSO_IFACE_PORT(x) ((x >> 16) & 0xff)
+#define UHSO_IFACE_PORT_TYPE(x) (x & 0xff)
+
+/*
+ * USB interface types
+ */
+#define UHSO_IF_NET		0x01	/* Network packet interface */
+#define UHSO_IF_MUX		0x02	/* Multiplexed serial port */
+#define UHSO_IF_BULK		0x04	/* Bulk interface */
+
+/*
+ * Port types
+ */
+#define UHSO_PORT_UNKNOWN	0x00
+#define UHSO_PORT_SERIAL	0x01	/* Serial port */
+#define UHSO_PORT_NETWORK	0x02	/* Network packet interface */
+
+/*
+ * Multiplexed serial port destination sub-port names
+ */
+#define UHSO_MPORT_TYPE_CTL	0x00	/* Control port */
+#define UHSO_MPORT_TYPE_APP	0x01	/* Application */
+#define UHSO_MPORT_TYPE_PCSC	0x02
+#define UHSO_MPORT_TYPE_GPS	0x03
+#define UHSO_MPORT_TYPE_APP2	0x04	/* Secondary application */
+#define UHSO_MPORT_TYPE_MAX	UHSO_MPORT_TYPE_APP2
+#define UHSO_MPORT_TYPE_NOMAX	8	/* Max number of mux ports */
+
+/*
+ * Port definitions
+ * Note that these definitions are arbitrary and do not match the values
+ * returned by the auto config descriptor.
+ */
+#define UHSO_PORT_TYPE_CTL	0x01
+#define UHSO_PORT_TYPE_APP	0x02
+#define UHSO_PORT_TYPE_APP2	0x03
+#define UHSO_PORT_TYPE_MODEM	0x04
+#define UHSO_PORT_TYPE_NETWORK	0x05
+#define UHSO_PORT_TYPE_DIAG	0x06
+#define UHSO_PORT_TYPE_DIAG2	0x07
+#define UHSO_PORT_TYPE_GPS	0x08
+#define UHSO_PORT_TYPE_GPSCTL	0x09
+#define UHSO_PORT_TYPE_PCSC	0x0a
+#define UHSO_PORT_TYPE_MSD	0x0b
+#define UHSO_PORT_TYPE_VOICE	0x0c
+#define UHSO_PORT_TYPE_MAX	0x0c
+
+static eventhandler_tag uhso_etag;
+
+/* Overall port type */
+static char *uhso_port[] = {
+	"Unknown",
+	"Serial",
+	"Network",
+	"Network/Serial"
+};
+
+/*
+ * Map between interface port type read from device and description type.
+ * The position in this array is a direct map to the auto config
+ * descriptor values.
+ */
+static unsigned char uhso_port_map[] = {
+	0,
+	UHSO_PORT_TYPE_DIAG,
+	UHSO_PORT_TYPE_GPS,
+	UHSO_PORT_TYPE_GPSCTL,
+	UHSO_PORT_TYPE_APP,
+	UHSO_PORT_TYPE_APP2,
+	UHSO_PORT_TYPE_CTL,
+	UHSO_PORT_TYPE_NETWORK,
+	UHSO_PORT_TYPE_MODEM,
+	UHSO_PORT_TYPE_MSD,
+	UHSO_PORT_TYPE_PCSC,
+	UHSO_PORT_TYPE_VOICE
+};
+static char uhso_port_map_max = sizeof(uhso_port_map) / sizeof(char);
+
+static unsigned char uhso_mux_port_map[] = {
+	UHSO_PORT_TYPE_CTL,
+	UHSO_PORT_TYPE_APP,
+	UHSO_PORT_TYPE_PCSC,
+	UHSO_PORT_TYPE_GPS,
+	UHSO_PORT_TYPE_APP2
+};
+
+static char *uhso_port_type[] = {
+	"Unknown",  /* Not a valid port */
+	"Control",
+	"Application",
+	"Application (Secondary)",
+	"Modem",
+	"Network",
+	"Diagnostic",
+	"Diagnostic (Secondary)",
+	"GPS",
+	"GPS Control",
+	"PC Smartcard",
+	"MSD",
+	"Voice",
+};
+
+static char *uhso_port_type_sysctl[] = {
+	"unknown",
+	"control",
+	"application",
+	"application",
+	"modem",
+	"network",
+	"diagnostic",
+	"diagnostic",
+	"gps",
+	"gps_control",
+	"pcsc",
+	"msd",
+	"voice",
+};
+
+#define UHSO_STATIC_IFACE	0x01
+#define UHSO_AUTO_IFACE		0x02
+
+static const struct usb_device_id uhso_devs[] = {
+#define	UHSO_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+	/* Option GlobeSurfer iCON 7.2 */
+	UHSO_DEV(OPTION, GSICON72, UHSO_STATIC_IFACE),
+	/* Option iCON 225 */
+	UHSO_DEV(OPTION, GTHSDPA, UHSO_STATIC_IFACE),
+	/* Option GlobeSurfer iCON HSUPA */
+	UHSO_DEV(OPTION, GSICONHSUPA, UHSO_STATIC_IFACE),
+	/* Option GlobeTrotter HSUPA */
+	UHSO_DEV(OPTION, GTHSUPA, UHSO_STATIC_IFACE),
+	/* GE40x */
+	UHSO_DEV(OPTION, GE40X, UHSO_AUTO_IFACE),
+	UHSO_DEV(OPTION, GE40X_1, UHSO_AUTO_IFACE),
+	UHSO_DEV(OPTION, GE40X_2, UHSO_AUTO_IFACE),
+	UHSO_DEV(OPTION, GE40X_3, UHSO_AUTO_IFACE),
+	/* Option GlobeSurfer iCON 401 */
+	UHSO_DEV(OPTION, ICON401, UHSO_AUTO_IFACE),
+	/* Option GlobeTrotter Module 382 */
+	UHSO_DEV(OPTION, GMT382, UHSO_AUTO_IFACE),
+	/* Option iCON EDGE */
+	UHSO_DEV(OPTION, ICONEDGE, UHSO_STATIC_IFACE),
+	/* Option Module HSxPA */
+	UHSO_DEV(OPTION, MODHSXPA, UHSO_STATIC_IFACE),
+	/* Option iCON 321 */
+	UHSO_DEV(OPTION, ICON321, UHSO_STATIC_IFACE),
+	/* Option iCON 322 */
+	UHSO_DEV(OPTION, GTICON322, UHSO_STATIC_IFACE),
+	/* Option iCON 505 */
+	UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE),
+#undef UHSO_DEV
+};
+
+SYSCTL_NODE(_hw_usb, OID_AUTO, uhso, CTLFLAG_RW, 0, "USB uhso");
+static int uhso_autoswitch = 1;
+SYSCTL_INT(_hw_usb_uhso, OID_AUTO, auto_switch, CTLFLAG_RW,
+    &uhso_autoswitch, 0, "Automatically switch to modem mode");
+
+#ifdef USB_DEBUG
+#ifdef UHSO_DEBUG
+static int uhso_debug = UHSO_DEBUG;
+#else
+static int uhso_debug = -1;
+#endif
+
+SYSCTL_INT(_hw_usb_uhso, OID_AUTO, debug, CTLFLAG_RW,
+    &uhso_debug, 0, "Debug level");
+
+#define UHSO_DPRINTF(n, x, ...) {\
+	if (uhso_debug >= n) {\
+		printf("%s: " x, __func__, ##__VA_ARGS__);\
+	}\
+}
+#else
+#define UHSO_DPRINTF(n, x, ...)
+#endif
+
+#ifdef UHSO_DEBUG_HEXDUMP
+# define UHSO_HEXDUMP(_buf, _len) do { \
+  { \
+        size_t __tmp; \
+        const char *__buf = (const char *)_buf; \
+        for (__tmp = 0; __tmp < _len; __tmp++) \
+                printf("%02hhx ", *__buf++); \
+    printf("\n"); \
+  } \
+} while(0)
+#else
+# define UHSO_HEXDUMP(_buf, _len)
+#endif
+
+enum {
+	UHSO_MUX_ENDPT_INTR = 0,
+	UHSO_MUX_ENDPT_MAX
+};
+
+enum {
+	UHSO_CTRL_READ = 0,
+	UHSO_CTRL_WRITE,
+	UHSO_CTRL_MAX
+};
+
+enum {
+	UHSO_IFNET_READ = 0,
+	UHSO_IFNET_WRITE,
+	UHSO_IFNET_MAX
+};
+
+enum {
+	UHSO_BULK_ENDPT_READ = 0,
+	UHSO_BULK_ENDPT_WRITE,
+	UHSO_BULK_ENDPT_INTR,
+	UHSO_BULK_ENDPT_MAX
+};
+
+static usb_callback_t uhso_mux_intr_callback;
+static usb_callback_t uhso_mux_read_callback;
+static usb_callback_t uhso_mux_write_callback;
+static usb_callback_t uhso_bs_read_callback;
+static usb_callback_t uhso_bs_write_callback;
+static usb_callback_t uhso_bs_intr_callback;
+static usb_callback_t uhso_ifnet_read_callback;
+static usb_callback_t uhso_ifnet_write_callback;
+
+/* Config used for the default control pipes */
+static const struct usb_config uhso_ctrl_config[UHSO_CTRL_MAX] = {
+	[UHSO_CTRL_READ] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,
+		.direction = UE_DIR_ANY,
+		.flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
+		.bufsize = sizeof(struct usb_device_request) + 1024,
+		.callback = &uhso_mux_read_callback
+	},
+
+	[UHSO_CTRL_WRITE] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,
+		.direction = UE_DIR_ANY,
+		.flags = { .pipe_bof = 1, .force_short_xfer = 1 },
+		.bufsize = sizeof(struct usb_device_request) + 1024,
+		.timeout = 1000,
+		.callback = &uhso_mux_write_callback
+	}
+};
+
+/* Config for the multiplexed serial ports */
+static const struct usb_config uhso_mux_config[UHSO_MUX_ENDPT_MAX] = {
+	[UHSO_MUX_ENDPT_INTR] = {
+		.type = UE_INTERRUPT,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.flags = { .short_xfer_ok = 1 },
+		.bufsize = 0,
+		.callback = &uhso_mux_intr_callback,
+	}
+};
+
+/* Config for the raw IP-packet interface */
+static const struct usb_config uhso_ifnet_config[UHSO_IFNET_MAX] = {
+	[UHSO_IFNET_READ] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
+		.bufsize = MCLBYTES,
+		.callback = &uhso_ifnet_read_callback
+	},
+	[UHSO_IFNET_WRITE] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.flags = { .pipe_bof = 1, .force_short_xfer = 1 },
+		.bufsize = MCLBYTES,
+		.timeout = 5 * USB_MS_HZ,
+		.callback = &uhso_ifnet_write_callback
+	}
+};
+
+/* Config for interfaces with normal bulk serial ports */
+static const struct usb_config uhso_bs_config[UHSO_BULK_ENDPT_MAX] = {
+	[UHSO_BULK_ENDPT_READ] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
+		.bufsize = 4096,
+		.callback = &uhso_bs_read_callback
+	},
+
+	[UHSO_BULK_ENDPT_WRITE] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.flags = { .pipe_bof = 1, .force_short_xfer = 1 },
+		.bufsize = 8192,
+		.callback = &uhso_bs_write_callback
+	},
+
+	[UHSO_BULK_ENDPT_INTR] = {
+		.type = UE_INTERRUPT,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.flags = { .short_xfer_ok = 1 },
+		.bufsize = 0,
+		.callback = &uhso_bs_intr_callback,
+	}
+};
+
+static int  uhso_probe_iface(struct uhso_softc *, int,
+    int (*probe)(struct uhso_softc *, int));
+static int  uhso_probe_iface_auto(struct uhso_softc *, int);
+static int  uhso_probe_iface_static(struct uhso_softc *, int);
+static int  uhso_attach_muxserial(struct uhso_softc *, struct usb_interface *,
+    int type);
+static int  uhso_attach_bulkserial(struct uhso_softc *, struct usb_interface *,
+    int type);
+static int  uhso_attach_ifnet(struct uhso_softc *, struct usb_interface *,
+    int type);
+static void uhso_test_autoinst(void *, struct usb_device *,
+		struct usb_attach_arg *);
+static int  uhso_driver_loaded(struct module *, int, void *);
+
+static void uhso_ucom_start_read(struct ucom_softc *);
+static void uhso_ucom_stop_read(struct ucom_softc *);
+static void uhso_ucom_start_write(struct ucom_softc *);
+static void uhso_ucom_stop_write(struct ucom_softc *);
+static void uhso_ucom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *);
+static void uhso_ucom_cfg_set_dtr(struct ucom_softc *, uint8_t);
+static void uhso_ucom_cfg_set_rts(struct ucom_softc *, uint8_t);
+static void uhso_if_init(void *);
+static void uhso_if_start(struct ifnet *);
+static void uhso_if_stop(struct uhso_softc *);
+static int  uhso_if_ioctl(struct ifnet *, u_long, caddr_t);
+static int  uhso_if_output(struct ifnet *, struct mbuf *, struct sockaddr *,
+    struct route *);
+static void uhso_if_rxflush(void *);
+
+static device_probe_t uhso_probe;
+static device_attach_t uhso_attach;
+static device_detach_t uhso_detach;
+
+static device_method_t uhso_methods[] = {
+	DEVMETHOD(device_probe,		uhso_probe),
+	DEVMETHOD(device_attach,	uhso_attach),
+	DEVMETHOD(device_detach,	uhso_detach),
+	{ 0, 0 }
+};
+
+static driver_t uhso_driver = {
+	"uhso",
+	uhso_methods,
+	sizeof(struct uhso_softc)
+};
+
+static devclass_t uhso_devclass;
+DRIVER_MODULE(uhso, uhub, uhso_driver, uhso_devclass, uhso_driver_loaded, 0);
+MODULE_DEPEND(uhso, ucom, 1, 1, 1);
+MODULE_DEPEND(uhso, usb, 1, 1, 1);
+MODULE_VERSION(uhso, 1);
+
+static struct ucom_callback uhso_ucom_callback = {
+	.ucom_cfg_get_status = &uhso_ucom_cfg_get_status,
+	.ucom_cfg_set_dtr = &uhso_ucom_cfg_set_dtr,
+	.ucom_cfg_set_rts = &uhso_ucom_cfg_set_rts,
+	.ucom_start_read = uhso_ucom_start_read,
+	.ucom_stop_read = uhso_ucom_stop_read,
+	.ucom_start_write = uhso_ucom_start_write,
+	.ucom_stop_write = uhso_ucom_stop_write
+};
+
+static int
+uhso_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.bConfigIndex != 0)
+		return (ENXIO);
+	if (uaa->device->ddesc.bDeviceClass != 0xff)
+		return (ENXIO);
+
+	return (usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa));
+}
+
+static int
+uhso_attach(device_t self)
+{
+	struct uhso_softc *sc = device_get_softc(self);
+	struct usb_attach_arg *uaa = device_get_ivars(self);
+	struct usb_config_descriptor *cd;
+	struct usb_interface_descriptor *id;
+	struct sysctl_ctx_list *sctx;
+	struct sysctl_oid *soid;
+	struct sysctl_oid *tree, *tty_node;
+	struct ucom_softc *ucom;
+	struct uhso_tty *ht;
+	int i, error, port;
+	void *probe_f;
+	usb_error_t uerr;
+	char *desc;
+
+	sc->sc_dev = self;
+	sc->sc_udev = uaa->device;
+	mtx_init(&sc->sc_mtx, "uhso", NULL, MTX_DEF);
+
+	sc->sc_ucom = NULL;
+	sc->sc_ttys = 0;
+
+	cd = usbd_get_config_descriptor(uaa->device);
+	id = usbd_get_interface_descriptor(uaa->iface);
+	sc->sc_ctrl_iface_no = id->bInterfaceNumber;
+
+	sc->sc_iface_no = uaa->info.bIfaceNum;
+	sc->sc_iface_index = uaa->info.bIfaceIndex;
+
+	/* Setup control pipe */
+	uerr = usbd_transfer_setup(uaa->device,
+	    &sc->sc_iface_index, sc->sc_ctrl_xfer,
+	    uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx);
+	if (uerr) {
+		device_printf(self, "Failed to setup control pipe: %s\n",
+		    usbd_errstr(uerr));
+		goto out;
+	}
+
+	if (USB_GET_DRIVER_INFO(uaa) == UHSO_STATIC_IFACE)
+		probe_f = uhso_probe_iface_static;
+	else if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE)
+		probe_f = uhso_probe_iface_auto;
+	else
+		goto out;
+
+	error = uhso_probe_iface(sc, uaa->info.bIfaceNum, probe_f);
+	if (error != 0)
+		goto out;
+
+	sctx = device_get_sysctl_ctx(sc->sc_dev);
+	soid = device_get_sysctl_tree(sc->sc_dev);
+
+	SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "type",
+	    CTLFLAG_RD, uhso_port[UHSO_IFACE_PORT(sc->sc_type)], 0,
+	    "Port available at this interface");
+
+	/*
+	 * The default interface description on most Option devices isn't
+	 * very helpful. So we skip device_set_usb_desc and set the
+	 * device description manually.
+	 */
+	device_set_desc_copy(self, uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)]); 
+	/* Announce device */
+	device_printf(self, "<%s port> at <%s %s> on %s\n",
+	    uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)],
+	    uaa->device->manufacturer, uaa->device->product,
+	    device_get_nameunit(uaa->device->bus->bdev));
+
+	if (sc->sc_ttys > 0) {
+		SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "ports",
+		    CTLFLAG_RD, &sc->sc_ttys, 0, "Number of attached serial ports");
+
+		tree = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
+		    "port", CTLFLAG_RD, NULL, "Serial ports");
+	}
+
+	/*
+	 * Loop through the number of found TTYs and create sysctl
+	 * nodes for them.
+	 */
+	for (i = 0; i < sc->sc_ttys; i++) {
+		ht = &sc->sc_tty[i];
+		ucom = &sc->sc_ucom[i];
+
+		if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX)
+			port = uhso_mux_port_map[ht->ht_muxport];
+		else
+			port = UHSO_IFACE_PORT_TYPE(sc->sc_type);
+
+		desc = uhso_port_type_sysctl[port];
+
+		tty_node = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+		    desc, CTLFLAG_RD, NULL, "");
+
+		ht->ht_name[0] = 0;
+		if (sc->sc_ttys == 1)
+			snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_unit);
+		else {
+			snprintf(ht->ht_name, 32, "cuaU%d.%d",
+			    ucom->sc_unit - ucom->sc_local_unit,
+			    ucom->sc_local_unit);
+		}
+
+		desc = uhso_port_type[port];
+		SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
+		    "tty", CTLFLAG_RD, ht->ht_name, 0, "");
+		SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
+		    "desc", CTLFLAG_RD, desc, 0, "");
+
+		if (bootverbose)
+			device_printf(sc->sc_dev,
+			    "\"%s\" port at %s\n", desc, ht->ht_name);
+	}
+
+	return (0);
+out:
+	uhso_detach(sc->sc_dev);
+	return (ENXIO);
+}
+
+static int
+uhso_detach(device_t self)
+{
+	struct uhso_softc *sc = device_get_softc(self);
+	int i;
+
+	usbd_transfer_unsetup(sc->sc_xfer, 3);
+	usbd_transfer_unsetup(sc->sc_ctrl_xfer, UHSO_CTRL_MAX);
+	if (sc->sc_ttys > 0) {
+		ucom_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_ttys);
+
+		for (i = 0; i < sc->sc_ttys; i++) {
+			if (sc->sc_tty[i].ht_muxport != -1) {
+				usbd_transfer_unsetup(sc->sc_tty[i].ht_xfer,
+				    UHSO_CTRL_MAX);
+			}
+		}
+
+		free(sc->sc_tty, M_USBDEV);
+		free(sc->sc_ucom, M_USBDEV);
+	}
+
+	if (sc->sc_ifp != NULL) {
+		callout_drain(&sc->sc_c);
+		mtx_lock(&sc->sc_mtx);
+		uhso_if_stop(sc);
+		bpfdetach(sc->sc_ifp);
+		if_detach(sc->sc_ifp);
+		if_free(sc->sc_ifp);
+		mtx_unlock(&sc->sc_mtx);
+		usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX);
+	}
+
+	mtx_destroy(&sc->sc_mtx);
+	return (0);
+}
+
+static void
+uhso_test_autoinst(void *arg, struct usb_device *udev,
+    struct usb_attach_arg *uaa)
+{
+	struct usb_interface *iface;
+	struct usb_interface_descriptor *id;
+
+	if (uaa->dev_state != UAA_DEV_READY || !uhso_autoswitch)
+		return;
+
+	iface = usbd_get_iface(udev, 0);
+	if (iface == NULL)
+		return;
+	id = iface->idesc;
+	if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
+		return;
+	if (usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa))
+		return;		/* no device match */
+
+	if (usb_msc_eject(udev, 0, MSC_EJECT_REZERO) == 0) {
+		/* success, mark the udev as disappearing */
+		uaa->dev_state = UAA_DEV_EJECTING;
+	}
+}
+
+static int
+uhso_driver_loaded(struct module *mod, int what, void *arg)
+{
+	switch (what) {
+	case MOD_LOAD:
+		/* register our autoinstall handler */
+		uhso_etag = EVENTHANDLER_REGISTER(usb_dev_configured,
+		    uhso_test_autoinst, NULL, EVENTHANDLER_PRI_ANY);
+		break;
+	case MOD_UNLOAD:
+		EVENTHANDLER_DEREGISTER(usb_dev_configured, uhso_etag);
+		break;
+	default:
+		return (EOPNOTSUPP);
+	}
+	return (0);
+}
+
+/*
+ * Probe the interface type by querying the device. The elements
+ * of an array indicates the capabilities of a particular interface.
+ * Returns a bit mask with the interface capabilities.
+ */
+static int
+uhso_probe_iface_auto(struct uhso_softc *sc, int index)
+{
+	struct usb_device_request req;
+	usb_error_t uerr;
+	uint16_t actlen = 0;
+	char port;
+	char buf[17] = {0};
+
+	req.bmRequestType = UT_READ_VENDOR_DEVICE;
+	req.bRequest = 0x86;
+	USETW(req.wValue, 0);
+	USETW(req.wIndex, 0);
+	USETW(req.wLength, 17);
+
+	uerr = usbd_do_request_flags(sc->sc_udev, NULL, &req, buf,
+	    0, &actlen, USB_MS_HZ);
+	if (uerr != 0) {
+		device_printf(sc->sc_dev, "usbd_do_request_flags failed: %s\n",
+		    usbd_errstr(uerr));
+		return (0);
+	}
+
+	UHSO_DPRINTF(1, "actlen=%d\n", actlen);
+	UHSO_HEXDUMP(buf, 17);
+
+	if (index < 0 || index > 16) {
+		UHSO_DPRINTF(0, "Index %d out of range\n", index);
+		return (0);
+	}
+
+	UHSO_DPRINTF(1, "index=%d, type=%x[%s]\n", index, buf[index],
+	    uhso_port_type[(int)uhso_port_map[(int)buf[index]]]);
+
+	if (buf[index] >= uhso_port_map_max)
+		port = 0;
+	else
+		port = uhso_port_map[(int)buf[index]];
+
+	switch (port) {
+	case UHSO_PORT_TYPE_NETWORK:
+		return (UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
+		    UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, port));
+	case UHSO_PORT_TYPE_VOICE:
+		/* Don't claim 'voice' ports */
+		return (0);
+	default:
+		return (UHSO_IFACE_SPEC(UHSO_IF_BULK,
+		    UHSO_PORT_SERIAL, port));
+	}
+
+	return (0);
+}
+
+static int
+uhso_probe_iface_static(struct uhso_softc *sc, int index)
+{
+	struct usb_config_descriptor *cd;
+
+	cd = usbd_get_config_descriptor(sc->sc_udev);
+	if (cd->bNumInterface <= 3) {
+		/* Cards with 3 or less interfaces */
+		switch (index) {
+		case 0:
+			return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
+			    UHSO_PORT_SERIAL | UHSO_PORT_NETWORK,
+			    UHSO_PORT_TYPE_NETWORK);
+		case 1:
+			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
+			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG);
+		case 2:
+			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
+			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM);
+		}
+	} else {
+		/* Cards with 4 interfaces */
+		switch (index) {
+		case 0:
+			return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
+			    UHSO_PORT_SERIAL | UHSO_PORT_NETWORK,
+			    UHSO_PORT_TYPE_NETWORK);
+		case 1:
+			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
+			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG2);
+		case 2:
+			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
+			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM);
+		case 3:
+			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
+			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG);
+		}
+	}
+	return (0);
+}
+
+/*
+ * Probes an interface for its particular capabilities and attaches if
+ * it's a supported interface.
+ */
+static int
+uhso_probe_iface(struct uhso_softc *sc, int index,
+    int (*probe)(struct uhso_softc *, int))
+{
+	struct usb_interface *iface;
+	int type, error;
+
+	UHSO_DPRINTF(1, "Probing for interface %d, probe_func=%p\n", index, probe);
+
+	type = probe(sc, index);
+	UHSO_DPRINTF(1, "Probe result %x\n", type);
+	if (type <= 0)
+		return (ENXIO);
+
+	sc->sc_type = type;
+	iface = usbd_get_iface(sc->sc_udev, index);
+
+	if (UHSO_IFACE_PORT_TYPE(type) == UHSO_PORT_TYPE_NETWORK) {
+		error = uhso_attach_ifnet(sc, iface, type);
+		if (error) {
+			UHSO_DPRINTF(1, "uhso_attach_ifnet failed");
+			return (ENXIO);
+		}
+
+		/*
+		 * If there is an additional interrupt endpoint on this
+		 * interface then we most likely have a multiplexed serial port
+		 * available.
+		 */
+		if (iface->idesc->bNumEndpoints < 3) {
+			sc->sc_type = UHSO_IFACE_SPEC( 
+			    UHSO_IFACE_USB_TYPE(type) & ~UHSO_IF_MUX,
+			    UHSO_IFACE_PORT(type) & ~UHSO_PORT_SERIAL,
+			    UHSO_IFACE_PORT_TYPE(type));
+			return (0);
+		}
+
+		UHSO_DPRINTF(1, "Trying to attach mux. serial\n");
+		error = uhso_attach_muxserial(sc, iface, type);
+		if (error == 0 && sc->sc_ttys > 0) {
+			error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom,
+			    sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx);
+			if (error) {
+				device_printf(sc->sc_dev, "ucom_attach failed\n");
+				return (ENXIO);
+			}
+
+			mtx_lock(&sc->sc_mtx);
+			usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
+			mtx_unlock(&sc->sc_mtx);
+		}
+	} else if ((UHSO_IFACE_USB_TYPE(type) & UHSO_IF_BULK) &&
+	    UHSO_IFACE_PORT(type) & UHSO_PORT_SERIAL) {
+
+		error = uhso_attach_bulkserial(sc, iface, type);
+		if (error)
+			return (ENXIO);
+
+		error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom,
+		    sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx);
+		if (error) {
+			device_printf(sc->sc_dev, "ucom_attach failed\n");
+			return (ENXIO);
+		}
+	}
+	else {
+		UHSO_DPRINTF(0, "Unknown type %x\n", type);
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+/*
+ * Expands allocated memory to fit an additional TTY.
+ * Two arrays are kept with matching indexes, one for ucom and one
+ * for our private data.
+ */
+static int
+uhso_alloc_tty(struct uhso_softc *sc)
+{
+
+	sc->sc_ttys++;
+	sc->sc_tty = reallocf(sc->sc_tty, sizeof(struct uhso_tty) * sc->sc_ttys,
+	    M_USBDEV, M_WAITOK | M_ZERO);
+	if (sc->sc_tty == NULL)
+		return (-1);
+
+	sc->sc_ucom = reallocf(sc->sc_ucom,
+	    sizeof(struct ucom_softc) * sc->sc_ttys, M_USBDEV, M_WAITOK | M_ZERO);
+	if (sc->sc_ucom == NULL)
+		return (-1);
+
+	sc->sc_tty[sc->sc_ttys - 1].ht_sc = sc;
+
+	UHSO_DPRINTF(1, "Allocated TTY %d\n", sc->sc_ttys - 1);	
+	return (sc->sc_ttys - 1);
+}
+
+/*
+ * Attach a multiplexed serial port
+ * Data is read/written with requests on the default control pipe. An interrupt
+ * endpoint returns when there is new data to be read.
+ */
+static int
+uhso_attach_muxserial(struct uhso_softc *sc, struct usb_interface *iface,
+    int type)
+{
+	struct usb_descriptor *desc;
+	int i, port, tty;
+	usb_error_t uerr;
+
+	/*
+	 * The class specific interface (type 0x24) descriptor subtype field
+	 * contains a bitmask that specifies which (and how many) ports that
+	 * are available through this multiplexed serial port.
+ 	 */
+	desc = usbd_find_descriptor(sc->sc_udev, NULL,
+	    iface->idesc->bInterfaceNumber, UDESC_CS_INTERFACE, 0xff, 0, 0);
+	if (desc == NULL) {
+		UHSO_DPRINTF(0, "Failed to find UDESC_CS_INTERFACE\n");
+		return (ENXIO);
+	}
+
+	UHSO_DPRINTF(1, "Mux port mask %x\n", desc->bDescriptorSubtype);
+	if (desc->bDescriptorSubtype == 0)
+		return (ENXIO);
+
+	/*
+	 * The bitmask is one octet, loop through the number of
+	 * bits that are set and create a TTY for each.
+	 */
+	for (i = 0; i < 8; i++) {
+		port = (1 << i);
+		if ((port & desc->bDescriptorSubtype) == port) {
+			UHSO_DPRINTF(2, "Found mux port %x (%d)\n", port, i);
+			tty = uhso_alloc_tty(sc);
+			if (tty < 0)
+				return (ENOMEM);
+			sc->sc_tty[tty].ht_muxport = i;
+			uerr = usbd_transfer_setup(sc->sc_udev,	
+			    &sc->sc_iface_index, sc->sc_tty[tty].ht_xfer,
+			    uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx);
+			if (uerr) {
+				device_printf(sc->sc_dev,
+				    "Failed to setup control pipe: %s\n",
+				    usbd_errstr(uerr));
+				return (ENXIO);
+			}
+		}
+	}
+
+	/* Setup the intr. endpoint */
+	uerr = usbd_transfer_setup(sc->sc_udev,
+	    &iface->idesc->bInterfaceNumber, sc->sc_xfer,
+	    uhso_mux_config, 1, sc, &sc->sc_mtx);
+	if (uerr)
+		return (ENXIO);
+
+	return (0);
+}
+
+/*
+ * Interrupt callback for the multiplexed serial port. Indicates
+ * which serial port has data waiting.
+ */
+static void
+uhso_mux_intr_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct usb_page_cache *pc;
+	struct usb_page_search res;
+	struct uhso_softc *sc = usbd_xfer_softc(xfer);
+	unsigned int i, mux;
+
+	UHSO_DPRINTF(3, "status %d\n", USB_GET_STATE(xfer));
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		/*
+		 * The multiplexed port number can be found at the first byte.
+		 * It contains a bit mask, we transform this in to an integer.
+		 */
+		pc = usbd_xfer_get_frame(xfer, 0);
+		usbd_get_page(pc, 0, &res);
+
+		i = *((unsigned char *)res.buffer);
+		mux = 0;
+		while (i >>= 1) {
+			mux++;
+		}
+
+		UHSO_DPRINTF(3, "mux port %d (%d)\n", mux, i);
+		if (mux > UHSO_MPORT_TYPE_NOMAX)
+			break;
+
+		/* Issue a read for this serial port */
+		usbd_xfer_set_priv(
+		    sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ],
+		    &sc->sc_tty[mux]);
+		usbd_transfer_start(sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ]);
+
+		break;
+	case USB_ST_SETUP:
+tr_setup:
+		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
+		usbd_transfer_submit(xfer);
+		break;
+	default:
+		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
+		if (error == USB_ERR_CANCELLED)
+			break;
+
+		usbd_xfer_set_stall(xfer);
+		goto tr_setup;
+	}
+}
+
+static void
+uhso_mux_read_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct uhso_softc *sc = usbd_xfer_softc(xfer);
+	struct usb_page_cache *pc;
+	struct usb_device_request req;
+	struct uhso_tty *ht;
+	int actlen, len;
+
+	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+	UHSO_DPRINTF(3, "status %d\n", USB_GET_STATE(xfer));
+
+	ht = usbd_xfer_get_priv(xfer);
+	UHSO_DPRINTF(3, "ht=%p open=%d\n", ht, ht->ht_open);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		/* Got data, send to ucom */
+		pc = usbd_xfer_get_frame(xfer, 1);
+		len = usbd_xfer_frame_len(xfer, 1);
+
+		UHSO_DPRINTF(3, "got %d bytes on mux port %d\n", len,
+		    ht->ht_muxport);
+		if (len <= 0) {
+			usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
+			break;
+		}
+
+		/* Deliver data if the TTY is open, discard otherwise */
+		if (ht->ht_open)
+			ucom_put_data(&sc->sc_ucom[ht->ht_muxport], pc, 0, len);
+		/* FALLTHROUGH */
+	case USB_ST_SETUP:
+tr_setup:
+		bzero(&req, sizeof(struct usb_device_request));
+		req.bmRequestType = UT_READ_CLASS_INTERFACE;
+		req.bRequest = UCDC_GET_ENCAPSULATED_RESPONSE;
+		USETW(req.wValue, 0);
+		USETW(req.wIndex, ht->ht_muxport);
+		USETW(req.wLength, 1024);
+
+		pc = usbd_xfer_get_frame(xfer, 0);
+		usbd_copy_in(pc, 0, &req, sizeof(req));
+
+		usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
+		usbd_xfer_set_frame_len(xfer, 1, 1024);
+		usbd_xfer_set_frames(xfer, 2);
+		usbd_transfer_submit(xfer);
+		break;
+	default:
+		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
+		if (error == USB_ERR_CANCELLED)
+			break;
+		usbd_xfer_set_stall(xfer);
+		goto tr_setup;
+	}
+}
+
+static void
+uhso_mux_write_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct uhso_softc *sc = usbd_xfer_softc(xfer);
+	struct uhso_tty *ht;
+	struct usb_page_cache *pc;
+	struct usb_device_request req;
+	int actlen;
+	struct usb_page_search res;
+
+	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+	ht = usbd_xfer_get_priv(xfer);
+	UHSO_DPRINTF(3, "status=%d, using mux port %d\n",
+	    USB_GET_STATE(xfer), ht->ht_muxport);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		UHSO_DPRINTF(3, "wrote %zd data bytes to muxport %d\n",
+		    actlen - sizeof(struct usb_device_request) ,
+		    ht->ht_muxport);
+		/* FALLTHROUGH */
+	case USB_ST_SETUP:
+		pc = usbd_xfer_get_frame(xfer, 1);
+		if (ucom_get_data(&sc->sc_ucom[ht->ht_muxport], pc,
+		    0, 32, &actlen)) {
+
+			usbd_get_page(pc, 0, &res);
+
+			bzero(&req, sizeof(struct usb_device_request));
+			req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+			req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND;
+			USETW(req.wValue, 0);
+			USETW(req.wIndex, ht->ht_muxport);
+			USETW(req.wLength, actlen);
+
+			pc = usbd_xfer_get_frame(xfer, 0);
+			usbd_copy_in(pc, 0, &req, sizeof(req));
+
+			usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
+			usbd_xfer_set_frame_len(xfer, 1, actlen);
+			usbd_xfer_set_frames(xfer, 2);
+
+			UHSO_DPRINTF(3, "Prepared %d bytes for transmit "
+			    "on muxport %d\n", actlen, ht->ht_muxport);
+
+			usbd_transfer_submit(xfer);
+		}
+		break;
+	default:
+		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
+		if (error == USB_ERR_CANCELLED)
+			break;
+		break;
+	}
+}
+
+static int
+uhso_attach_bulkserial(struct uhso_softc *sc, struct usb_interface *iface,
+    int type)
+{
+	usb_error_t uerr;
+	int tty;
+
+	/* Try attaching RD/WR/INTR first */
+	uerr = usbd_transfer_setup(sc->sc_udev,
+	    &iface->idesc->bInterfaceNumber, sc->sc_xfer,
+	    uhso_bs_config, UHSO_BULK_ENDPT_MAX, sc, &sc->sc_mtx);
+	if (uerr) {
+		/* Try only RD/WR */
+		uerr = usbd_transfer_setup(sc->sc_udev,
+		    &iface->idesc->bInterfaceNumber, sc->sc_xfer,
+		    uhso_bs_config, UHSO_BULK_ENDPT_MAX - 1, sc, &sc->sc_mtx);
+	}
+	if (uerr) {
+		UHSO_DPRINTF(0, "usbd_transfer_setup failed");
+		return (-1);
+	}
+
+	tty = uhso_alloc_tty(sc);
+	if (tty < 0) {
+		usbd_transfer_unsetup(sc->sc_xfer, UHSO_BULK_ENDPT_MAX);
+		return (ENOMEM);
+	}
+
+	sc->sc_tty[tty].ht_muxport = -1;
+	return (0);
+}
+
+static void
+uhso_bs_read_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct uhso_softc *sc = usbd_xfer_softc(xfer);
+	struct usb_page_cache *pc;
+	int actlen;
+
+	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+	UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		pc = usbd_xfer_get_frame(xfer, 0);
+		ucom_put_data(&sc->sc_ucom[0], pc, 0, actlen);
+		/* FALLTHROUGH */
+	case USB_ST_SETUP:
+tr_setup:
+		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
+		usbd_transfer_submit(xfer);
+	break;
+	default:
+		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
+		if (error == USB_ERR_CANCELLED)
+			break;
+		usbd_xfer_set_stall(xfer);
+		goto tr_setup;
+	}
+}
+
+static void
+uhso_bs_write_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct uhso_softc *sc = usbd_xfer_softc(xfer);
+	struct usb_page_cache *pc;
+	int actlen;
+
+	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+	UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+	case USB_ST_SETUP:
+tr_setup:
+		pc = usbd_xfer_get_frame(xfer, 0);
+		if (ucom_get_data(&sc->sc_ucom[0], pc, 0, 8192, &actlen)) {
+			usbd_xfer_set_frame_len(xfer, 0, actlen);
+			usbd_transfer_submit(xfer);
+		}
+		break;
+	break;
+	default:
+		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
+		if (error == USB_ERR_CANCELLED)
+			break;
+		usbd_xfer_set_stall(xfer);
+		goto tr_setup;
+	}
+}
+
+static void
+uhso_bs_cfg(struct uhso_softc *sc)
+{
+	struct usb_device_request req;
+	usb_error_t uerr;
+
+	if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK))
+		return;
+
+	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+	req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
+	USETW(req.wValue, sc->sc_line);
+	USETW(req.wIndex, sc->sc_iface_no);
+	USETW(req.wLength, 0);
+
+	uerr = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom[0], &req, NULL, 0, 1000);
+	if (uerr != 0) {
+		device_printf(sc->sc_dev, "failed to set ctrl line state to "
+		    "0x%02x: %s\n", sc->sc_line, usbd_errstr(uerr));
+	}
+}
+
+static void
+uhso_bs_intr_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct uhso_softc *sc = usbd_xfer_softc(xfer);
+	struct usb_page_cache *pc;
+	int actlen;
+	struct usb_cdc_notification cdc;
+
+	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+	UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		if (actlen < UCDC_NOTIFICATION_LENGTH) {
+			UHSO_DPRINTF(0, "UCDC notification too short: %d\n", actlen);
+			goto tr_setup;
+		}
+		else if (actlen > sizeof(struct usb_cdc_notification)) {
+			UHSO_DPRINTF(0, "UCDC notification too large: %d\n", actlen);
+			actlen = sizeof(struct usb_cdc_notification);
+		}
+
+		pc = usbd_xfer_get_frame(xfer, 0);
+		usbd_copy_out(pc, 0, &cdc, actlen);
+
+		if (UGETW(cdc.wIndex) != sc->sc_iface_no) {
+			UHSO_DPRINTF(0, "Interface mismatch, got %d expected %d\n",
+			    UGETW(cdc.wIndex), sc->sc_iface_no);
+			goto tr_setup;
+		}
+
+		if (cdc.bmRequestType == UCDC_NOTIFICATION &&
+		    cdc.bNotification == UCDC_N_SERIAL_STATE) {
+			UHSO_DPRINTF(2, "notify = 0x%02x\n", cdc.data[0]);
+
+			sc->sc_msr = 0;
+			sc->sc_lsr = 0;
+			if (cdc.data[0] & UCDC_N_SERIAL_RI)
+				sc->sc_msr |= SER_RI;
+			if (cdc.data[0] & UCDC_N_SERIAL_DSR)
+				sc->sc_msr |= SER_DSR;	
+			if (cdc.data[0] & UCDC_N_SERIAL_DCD)
+				sc->sc_msr |= SER_DCD;
+
+			ucom_status_change(&sc->sc_ucom[0]);
+		}
+	case USB_ST_SETUP:
+tr_setup:
+	default:
+		if (error == USB_ERR_CANCELLED)
+			break;
+		usbd_xfer_set_stall(xfer);
+		goto tr_setup;
+	}
+}
+
+static void
+uhso_ucom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
+{
+	struct uhso_softc *sc = ucom->sc_parent;
+
+	*lsr = sc->sc_lsr;
+	*msr = sc->sc_msr;
+}
+
+static void
+uhso_ucom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
+{
+	struct uhso_softc *sc = ucom->sc_parent;
+
+	if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK))
+		return;
+
+	if (onoff)
+		sc->sc_line |= UCDC_LINE_DTR;
+	else
+		sc->sc_line &= UCDC_LINE_DTR;
+
+	uhso_bs_cfg(sc);
+}
+
+static void
+uhso_ucom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff)
+{
+	struct uhso_softc *sc = ucom->sc_parent;
+
+	if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK))
+		return;
+
+	if (onoff)
+		sc->sc_line |= UCDC_LINE_RTS;
+	else
+		sc->sc_line &= UCDC_LINE_DTR;
+
+	uhso_bs_cfg(sc);
+}
+
+static void
+uhso_ucom_start_read(struct ucom_softc *ucom)
+{
+	struct uhso_softc *sc = ucom->sc_parent;
+
+	UHSO_DPRINTF(3, "unit=%d, local_unit=%d\n",
+	    ucom->sc_unit, ucom->sc_local_unit);
+
+	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
+		sc->sc_tty[ucom->sc_local_unit].ht_open = 1;
+		usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
+	}
+	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
+		sc->sc_tty[0].ht_open = 1;
+		usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]);
+		if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL)
+			usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]);
+	}
+}
+
+static void
+uhso_ucom_stop_read(struct ucom_softc *ucom)
+{
+
+	struct uhso_softc *sc = ucom->sc_parent;
+
+	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
+		sc->sc_tty[ucom->sc_local_unit].ht_open = 0;
+		usbd_transfer_stop(
+		    sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_READ]);
+	}
+	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
+		sc->sc_tty[0].ht_open = 0;
+		usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]);
+		if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL)
+			usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]);
+	}
+}
+
+static void
+uhso_ucom_start_write(struct ucom_softc *ucom)
+{
+	struct uhso_softc *sc = ucom->sc_parent;
+
+	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
+		UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_local_unit);
+
+		usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
+
+		usbd_xfer_set_priv(
+		    sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_WRITE],
+		    &sc->sc_tty[ucom->sc_local_unit]);
+		usbd_transfer_start(
+		    sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_WRITE]);
+
+	}
+	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
+		usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]);
+	}
+}
+
+static void
+uhso_ucom_stop_write(struct ucom_softc *ucom)
+{
+	struct uhso_softc *sc = ucom->sc_parent;
+
+	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
+		usbd_transfer_stop(
+		    sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_WRITE]);
+	}
+	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
+		usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]);
+	}
+}
+
+static int uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface *iface,
+    int type)
+{
+	struct ifnet *ifp;
+	usb_error_t uerr;
+	struct sysctl_ctx_list *sctx;
+	struct sysctl_oid *soid;
+
+	uerr = usbd_transfer_setup(sc->sc_udev,
+	    &iface->idesc->bInterfaceNumber, sc->sc_if_xfer,
+	    uhso_ifnet_config, UHSO_IFNET_MAX, sc, &sc->sc_mtx);
+	if (uerr) {
+		UHSO_DPRINTF(0, "usbd_transfer_setup failed: %s\n",
+		    usbd_errstr(uerr));
+		return (-1);
+	}
+
+	sc->sc_ifp = ifp = if_alloc(IFT_OTHER);
+	if (sc->sc_ifp == NULL) {
+		device_printf(sc->sc_dev, "if_alloc() failed\n");
+		return (-1);
+	}
+
+	callout_init_mtx(&sc->sc_c, &sc->sc_mtx, 0);
+	mtx_lock(&sc->sc_mtx);
+	callout_reset(&sc->sc_c, 1, uhso_if_rxflush, sc);
+	mtx_unlock(&sc->sc_mtx);
+
+	if_initname(ifp, device_get_name(sc->sc_dev), device_get_unit(sc->sc_dev));
+	ifp->if_mtu = UHSO_MAX_MTU;
+	ifp->if_ioctl = uhso_if_ioctl;
+	ifp->if_init = uhso_if_init;
+	ifp->if_start = uhso_if_start;
+	ifp->if_output = uhso_if_output;
+	ifp->if_flags = 0;
+	ifp->if_softc = sc;
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+	IFQ_SET_READY(&ifp->if_snd);
+
+	if_attach(ifp);
+	bpfattach(ifp, DLT_RAW, 0);
+
+	sctx = device_get_sysctl_ctx(sc->sc_dev);
+	soid = device_get_sysctl_tree(sc->sc_dev);
+	/* Unlocked read... */
+	SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "netif",
+	    CTLFLAG_RD, ifp->if_xname, 0, "Attached network interface");
+
+	return (0);
+}
+
+static void
+uhso_ifnet_read_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct uhso_softc *sc = usbd_xfer_softc(xfer);
+	struct mbuf *m;	
+	struct usb_page_cache *pc;
+	int actlen;
+
+	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+	UHSO_DPRINTF(3, "status=%d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		if (actlen > 0 && (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+			pc = usbd_xfer_get_frame(xfer, 0);
+			m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+			usbd_copy_out(pc, 0, mtod(m, uint8_t *), actlen);
+			m->m_pkthdr.len = m->m_len = actlen;
+			/* Enqueue frame for further processing */
+			_IF_ENQUEUE(&sc->sc_rxq, m);
+			if (!callout_pending(&sc->sc_c) ||
+			    !callout_active(&sc->sc_c)) {
+				callout_schedule(&sc->sc_c, 1);
+			}
+		}
+	/* FALLTHROUGH */
+	case USB_ST_SETUP:
+tr_setup:
+		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
+		usbd_transfer_submit(xfer);
+		break;
+	default:
+		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
+		if (error == USB_ERR_CANCELLED)
+			break;
+		usbd_xfer_set_stall(xfer);
+		goto tr_setup;
+	}
+}
+
+/*
+ * Deferred RX processing, called with mutex locked.
+ *
+ * Each frame we receive might contain several small ip-packets as well
+ * as partial ip-packets. We need to separate/assemble them into individual
+ * packets before sending them to the ip-layer.
+ */
+static void
+uhso_if_rxflush(void *arg)
+{
+	struct uhso_softc *sc = arg;
+	struct ifnet *ifp = sc->sc_ifp;
+	uint8_t *cp;
+	struct mbuf *m, *m0, *mwait;
+	struct ip *ip;
+#ifdef INET6
+	struct ip6_hdr *ip6;
+#endif
+	uint16_t iplen;
+	int len, isr;
+
+	m = NULL;
+	mwait = sc->sc_mwait;
+	for (;;) {
+		if (m == NULL) {
+			_IF_DEQUEUE(&sc->sc_rxq, m);
+			if (m == NULL)
+				break;
+			UHSO_DPRINTF(3, "dequeue m=%p, len=%d\n", m, m->m_len);
+		}
+		mtx_unlock(&sc->sc_mtx);
+
+		/* Do we have a partial packet waiting? */
+		if (mwait != NULL) {
+			m0 = mwait;
+			mwait = NULL;
+
+			UHSO_DPRINTF(3, "partial m0=%p(%d), concat w/ m=%p(%d)\n",
+			    m0, m0->m_len, m, m->m_len);
+			len = m->m_len + m0->m_len;
+
+			/* Concat mbufs and fix headers */
+			m_cat(m0, m);
+			m0->m_pkthdr.len = len;
+			m->m_flags &= ~M_PKTHDR;
+
+			m = m_pullup(m0, sizeof(struct ip));
+			if (m == NULL) {
+				ifp->if_ierrors++;
+				UHSO_DPRINTF(0, "m_pullup failed\n");
+				mtx_lock(&sc->sc_mtx);
+				continue;
+			}
+			UHSO_DPRINTF(3, "Constructed mbuf=%p, len=%d\n",
+			    m, m->m_pkthdr.len);
+		}
+
+		cp = mtod(m, uint8_t *);
+		ip = (struct ip *)cp;
+#ifdef INET6
+		ip6 = (struct ip6_hdr *)cp;
+#endif
+
+		/* Check for IPv4 */
+		if (ip->ip_v == IPVERSION) {
+			iplen = htons(ip->ip_len);
+			isr = NETISR_IP;
+		}
+#ifdef INET6
+		/* Check for IPv6 */
+		else if ((ip6->ip6_vfc & IPV6_VERSION_MASK) == IPV6_VERSION) {
+			iplen = htons(ip6->ip6_plen);
+			isr = NETISR_IPV6;
+		}
+#endif
+		else {
+			UHSO_DPRINTF(0, "got unexpected ip version %d, "
+			    "m=%p, len=%d\n", (*cp & 0xf0) >> 4, m, m->m_len);
+			ifp->if_ierrors++;
+			UHSO_HEXDUMP(cp, 4);
+			m_freem(m);
+			m = NULL;
+			mtx_lock(&sc->sc_mtx);
+			continue;
+		}
+
+		if (iplen == 0) {
+			UHSO_DPRINTF(0, "Zero IP length\n");
+			ifp->if_ierrors++;
+			m_freem(m);
+			m = NULL;
+			mtx_lock(&sc->sc_mtx);
+			continue;
+		}
+
+		UHSO_DPRINTF(3, "m=%p, len=%d, cp=%p, iplen=%d\n",
+		    m, m->m_pkthdr.len, cp, iplen);
+
+		m0 = NULL;
+
+		/* More IP packets in this mbuf */
+		if (iplen < m->m_pkthdr.len) {
+			m0 = m;
+
+			/*
+			 * Allocate a new mbuf for this IP packet and
+			 * copy the IP-packet into it.
+			 */
+			m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+			bcopy(mtod(m0, uint8_t *), mtod(m, uint8_t *), iplen);
+			m->m_pkthdr.len = m->m_len = iplen;
+
+			/* Adjust the size of the original mbuf */
+			m_adj(m0, iplen);
+			m0 = m_defrag(m0, M_WAIT);
+
+			UHSO_DPRINTF(3, "New mbuf=%p, len=%d/%d, m0=%p, "
+			    "m0_len=%d/%d\n", m, m->m_pkthdr.len, m->m_len,
+			    m0, m0->m_pkthdr.len, m0->m_len);
+		}
+		else if (iplen > m->m_pkthdr.len) {
+			UHSO_DPRINTF(3, "Deferred mbuf=%p, len=%d\n",
+			    m, m->m_pkthdr.len);
+			mwait = m;
+			m = NULL;
+			mtx_lock(&sc->sc_mtx);
+			continue;
+		}
+
+		ifp->if_ipackets++;
+		m->m_pkthdr.rcvif = ifp;
+
+		/* Dispatch to IP layer */
+		BPF_MTAP(sc->sc_ifp, m);
+		netisr_dispatch(isr, m);
+		m = m0 != NULL ? m0 : NULL;
+		mtx_lock(&sc->sc_mtx);
+	}
+	sc->sc_mwait = mwait;
+}
+
+static void
+uhso_ifnet_write_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct uhso_softc *sc = usbd_xfer_softc(xfer);
+	struct ifnet *ifp = sc->sc_ifp;
+	struct usb_page_cache *pc;
+	struct mbuf *m;
+	int actlen;
+
+	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+	UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		ifp->if_opackets++;
+		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	case USB_ST_SETUP:
+tr_setup:
+		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+		if (m == NULL)
+			break;
+
+		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+
+		if (m->m_pkthdr.len > MCLBYTES)
+			m->m_pkthdr.len = MCLBYTES;
+
+		usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len);
+		pc = usbd_xfer_get_frame(xfer, 0);
+		usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len);
+		usbd_transfer_submit(xfer);
+
+		BPF_MTAP(ifp, m);
+		m_freem(m);
+		break;
+	default:
+		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
+		if (error == USB_ERR_CANCELLED)
+			break;
+		usbd_xfer_set_stall(xfer);
+		goto tr_setup;
+	}
+}
+
+static int
+uhso_if_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	struct uhso_softc *sc;
+
+	sc = ifp->if_softc;
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		if (ifp->if_flags & IFF_UP) {
+			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+				uhso_if_init(sc);
+			}
+		}
+		else {
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+				mtx_lock(&sc->sc_mtx);
+				uhso_if_stop(sc);
+				mtx_unlock(&sc->sc_mtx);
+			}
+		}
+		break;
+	case SIOCSIFADDR:
+	case SIOCSIFDSTADDR:
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+static void
+uhso_if_init(void *priv)
+{
+	struct uhso_softc *sc = priv;
+	struct ifnet *ifp = sc->sc_ifp;
+
+	mtx_lock(&sc->sc_mtx);
+	uhso_if_stop(sc);
+	ifp = sc->sc_ifp;
+	ifp->if_flags |= IFF_UP;
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	mtx_unlock(&sc->sc_mtx);
+
+	UHSO_DPRINTF(2, "ifnet initialized\n");
+}
+
+static int
+uhso_if_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
+    struct route *ro)
+{
+	int error;
+
+	/* Only IPv4/6 support */
+	if (dst->sa_family != AF_INET
+#ifdef INET6
+	   && dst->sa_family != AF_INET6
+#endif
+	 ) {
+		return (EAFNOSUPPORT);
+	}
+
+	error = (ifp->if_transmit)(ifp, m0);
+	if (error) {
+		ifp->if_oerrors++;
+		return (ENOBUFS);
+	}
+	ifp->if_opackets++;
+	return (0);
+}
+
+static void
+uhso_if_start(struct ifnet *ifp)
+{
+	struct uhso_softc *sc = ifp->if_softc;
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+		UHSO_DPRINTF(1, "Not running\n");
+		return;
+	}
+
+	mtx_lock(&sc->sc_mtx);
+	usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_READ]);
+	usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_WRITE]);
+	mtx_unlock(&sc->sc_mtx);
+	UHSO_DPRINTF(3, "interface started\n");
+}
+
+static void
+uhso_if_stop(struct uhso_softc *sc)
+{
+
+	usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_READ]);
+	usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_WRITE]);
+	sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+}
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index e4ee8a9ab59..ee72a171064 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -2095,6 +2095,18 @@ product OPTION E7041		0x7041	3G modem
 product OPTION E7061		0x7061	3G modem
 product OPTION E7100		0x7100	3G modem
 product OPTION GTM380		0x7201	3G modem
+product OPTION GSICON72		0x6911	GlobeSurfer iCON
+product OPTION GSICONHSUPA	0x7251	Globetrotter HSUPA
+product OPTION ICON401		0x7401	GlobeSurfer iCON 401
+product OPTION GTHSUPA		0x7011	Globetrotter HSUPA
+product OPTION GMT382		0x7501	Globetrotter HSUPA
+product OPTION GE40X_1		0x7301	Globetrotter HSUPA
+product OPTION GE40X_2		0x7361	Globetrotter HSUPA
+product OPTION GE40X_3		0x7381	Globetrotter HSUPA
+product OPTION ICONEDGE		0xc031	GlobeSurfer iCON EDGE
+product OPTION MODHSXPA		0xd013	Globetrotter HSUPA
+product OPTION ICON321		0xd031	Globetrotter HSUPA
+product OPTION ICON505		0xd055	Globetrotter iCON 505
 
 /* OQO */
 product OQO WIFI01		0x0002	model 01 WiFi interface
diff --git a/sys/modules/usb/uhso/Makefile b/sys/modules/usb/uhso/Makefile
new file mode 100644
index 00000000000..b08dc42136c
--- /dev/null
+++ b/sys/modules/usb/uhso/Makefile
@@ -0,0 +1,37 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2010 Andrew Thompson. 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/net
+
+KMOD=	uhso
+SRCS=	opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h usbdevs.h \
+	opt_inet.h \
+	uhso.c
+
+.include 
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 99a06208262..5df3ca20229 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -189,6 +189,7 @@ SUBDIR=	${_ac} \
 	tzsetup \
 	${_uathload} \
 	ugidfw \
+	${_uhsoctl} \
 	${_usbdevs} \
 	${_usbconfig} \
 	${_vidcontrol} \
@@ -410,6 +411,7 @@ _crunch=	crunch
 .if ${MACHINE_ARCH} != "ia64"
 _uathload=	uathload
 .endif
+_uhsoctl=	uhsoctl
 #_usbdevs=	usbdevs
 _usbconfig=	usbconfig
 .endif
diff --git a/usr.sbin/uhsoctl/Makefile b/usr.sbin/uhsoctl/Makefile
new file mode 100644
index 00000000000..97049237fff
--- /dev/null
+++ b/usr.sbin/uhsoctl/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+PROG=	uhsoctl
+MAN=	uhsoctl.1
+WARNS=	1
+
+DPADD=	${LIBUTIL}
+LDADD=	-lutil
+
+.include 
diff --git a/usr.sbin/uhsoctl/uhsoctl.1 b/usr.sbin/uhsoctl/uhsoctl.1
new file mode 100644
index 00000000000..932cefa9261
--- /dev/null
+++ b/usr.sbin/uhsoctl/uhsoctl.1
@@ -0,0 +1,104 @@
+.\" Copyright (c) 2008-2009 Fredrik Lindberg
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd Aug 12, 2009
+.Os
+.Dt UHSOCTL 1
+.Sh NAME
+.Nm uhsoctl
+.Nd connection utility for Option based devices
+.Sh SYNOPSIS
+.Nm
+.Op Fl a Ar apn
+.Op Fl c Ar cid
+.Op Fl p Ar pin
+.Op Fl u Ar username
+.Op Fl k Ar password
+.Op Fl r Ar path
+.Op Fl f Ar path
+.Op Fl b | n
+.Ar interface
+.Nm
+.Fl d
+.Ar interface
+.Nm
+.Fl h
+.Sh DESCRIPTION
+.Nm
+is a small connection utility for Option N.V. devices that are based on Options
+packet interface and uses proprietary AT_* calls to establish connections.
+The utility (tries to) configure both default route and name servers
+(/etc/resolv.conf).
+.Pp
+By default
+.Nm
+detaches from the terminal upon on a successful connection, a few command-line
+options exists that allows this behavior to be changed.
+.Pp
+.Nm
+attempts to find a usable controlling serial port based on the provided network
+interface.
+If this fails you might specify a serial port manually.
+.Sh OPTIONS
+.Bl -tag -width XXXX
+.It Fl a Ar apn
+Specify APN to connect to.
+.It Fl c Ar cid
+Specify CID (Context ID) to use, by default CID 1 is used.
+If an APN has been configured once, it's enough to specify the CID used for
+further accesses.
+.It Fl p Ar pin
+Specify SIM PIN.
+.It Fl u Ar username
+Specify username.
+.It Fl k Ar password
+Specify username.
+.It Fl r Ar path
+Path to resolv.conf, default /etc/resolv.conf.
+Use /dev/null to disable updating of name servers.
+.It Fl f Ar path
+Explicitly set the serial port to use as controlling terminal.
+Might be needed if the automatic detection fails.
+.It Fl b
+Fork into background directly, before a connection has been established.
+.It Fl n
+Never fork into background, run entirely in foreground.
+.El
+.Sh EXAMPLES
+Connect to
+.Dq Li apn.example.com
+on interface
+.Dq Li uhso0
+and use PIN
+.Dq 1234
+to enable the SIM card.
+
+.Dl "uhsoctl -a apn.example.com -p 1234 uhso0"
+
+Disconnect from a previously established connection
+
+.Dl "uhsoctl -d uhso0"
+.Sh SEE ALSO
+.Xr uhso 4
diff --git a/usr.sbin/uhsoctl/uhsoctl.c b/usr.sbin/uhsoctl/uhsoctl.c
new file mode 100644
index 00000000000..6ed524544da
--- /dev/null
+++ b/usr.sbin/uhsoctl/uhsoctl.c
@@ -0,0 +1,1532 @@
+/*-
+ * Copyright (c) 2008-2009 Fredrik Lindberg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Connection utility to ease connectivity using the raw IP packet interface
+ * available on uhso(4) devices.
+ */
+
+#define TTY_NAME	"/dev/%s"
+#define SYSCTL_TEST	"dev.uhso.%d.%%driver"
+#define SYSCTL_PORTS	"dev.uhso.%d.ports"
+#define SYSCTL_NETIF	"dev.uhso.%d.netif"
+#define SYSCTL_NAME_TTY	"dev.uhso.%d.port.%s.tty"
+#define SYSCTL_NAME_DESC "dev.uhso.%d.port.%s.desc"
+#define RESOLV_PATH	"/etc/resolv.conf"
+#define PIDFILE		"/var/run/uhsoctl.%s.pid"
+
+static const char *network_access_type[] = {
+	"GSM",
+	"Compact GSM",
+	"UMTS",
+	"GSM (EGPRS)",
+	"HSDPA",
+	"HSUPA",
+	"HSDPA/HSUPA"
+};
+
+static const char *network_reg_status[] = {
+	"Not registered",
+	"Registered",
+	"Searching for network",
+	"Network registration denied",
+	"Unknown",
+	"Registered (roaming)"
+};
+
+struct ctx {
+	int fd;
+	int flags;
+#define IPASSIGNED	0x01
+#define FLG_NODAEMON	0x02 /* Don't detach from terminal */
+#define FLG_DAEMON	0x04 /* Running as daemon */
+#define FLG_DELAYED	0x08 /* Fork into background after connect */
+#define FLG_NEWDATA	0x10
+#define FLG_WATCHDOG	0x20 /* Watchdog enabled */
+#define FLG_WDEXP	0x40 /* Watchdog expired */
+	const char *ifnam;
+	const char *pin; /* device PIN */
+
+	char pidfile[128];
+	struct pidfh *pfh;
+
+	time_t watchdog;
+
+	/* PDP context settings */
+	int pdp_ctx;
+	const char *pdp_apn;
+	const char *pdp_user;
+	const char *pdp_pwd;
+
+	/* Connection status */
+	int con_status;		/* Connected? */
+	char *con_apn;		/* Connected APN */
+	char *con_oper;		/* Operator name */
+	int con_net_stat;	/* Network connection status */
+	int con_net_type;	/* Network connection type */
+
+	/* Misc. status */
+	int dbm;
+
+	/* IP and nameserver settings */
+	struct in_addr ip;
+	char **ns;
+	const char *resolv_path;
+	char *resolv;		/* Old resolv.conf */
+	size_t resolv_sz;
+};
+
+static int readline_buf(const char *, const char *, char *, size_t);
+static int readline(int, char *, size_t);
+static void daemonize(struct ctx *);
+
+static int at_cmd_async(int, const char *, ...);
+
+typedef union {
+	void *ptr;
+	uint32_t int32;
+} resp_data;
+typedef struct {
+	resp_data val[2];	
+} resp_arg;
+typedef void (*resp_cb)(resp_arg *, const char *, const char *);
+
+typedef void (*async_cb)(void *, const char *);
+struct async_handle {
+	const char *cmd;
+	async_cb func;
+};
+
+static void at_async_creg(void *, const char *);
+static void at_async_cgreg(void *, const char *);
+static void at_async_cops(void *, const char *);
+static void at_async_owancall(void *, const char *);
+static void at_async_owandata(void *, const char *);
+static void at_async_csq(void *, const char *);
+
+static struct async_handle async_cmd[] = {
+	{ "+CREG", at_async_creg },
+	{ "+CGREG", at_async_cgreg },
+	{ "+COPS", at_async_cops },
+	{ "+CSQ", at_async_csq },
+	{ "_OWANCALL", at_async_owancall },
+	{ "_OWANDATA", at_async_owandata },
+	{ NULL, NULL }
+};
+
+struct timer_entry;
+struct timers {
+	TAILQ_HEAD(, timer_entry) head;
+	int res;
+};
+
+typedef void (*tmr_cb)(int, void *);
+struct timer_entry {
+	TAILQ_ENTRY(timer_entry) next;
+	int id;
+	int timeout;
+	tmr_cb func;
+	void *arg;
+};
+
+
+static struct timers timers;
+static volatile int running = 1;
+static int syslog_open = 0;
+static char syslog_title[64];
+
+/* Periodic timer, runs ready timer tasks every tick */
+static void
+tmr_run(struct timers *tmrs)
+{
+	struct timer_entry *te, *te2;
+
+	te = TAILQ_FIRST(&tmrs->head);
+	if (te == NULL)
+		return;
+
+	te->timeout -= tmrs->res;
+	while (te->timeout <= 0) {
+		te2 = TAILQ_NEXT(te, next);
+		TAILQ_REMOVE(&tmrs->head, te, next);
+		if (te2 != NULL)
+			te2->timeout -= tmrs->res;
+
+		te->func(te->id, te->arg);
+		free(te);
+		te = te2;
+		if (te == NULL)
+			break;
+	}
+}
+
+/* Add a new timer */
+static void
+tmr_add(struct timers *tmrs, int id, int timeout, tmr_cb func, void *arg)
+{
+	struct timer_entry *te, *te2, *te3;
+
+	te = malloc(sizeof(struct timer_entry));
+	memset(te, 0, sizeof(struct timer_entry));
+
+	te->timeout = timeout;
+	te->func = func;
+	te->arg = arg;
+	te->id = id;
+
+	te2 = TAILQ_FIRST(&tmrs->head);
+
+	if (TAILQ_EMPTY(&tmrs->head)) {
+		TAILQ_INSERT_HEAD(&tmrs->head, te, next);
+	} else if (te->timeout < te2->timeout) {
+		te2->timeout -= te->timeout;
+		TAILQ_INSERT_HEAD(&tmrs->head, te, next);
+	} else {
+		while (te->timeout >= te2->timeout) {
+			te->timeout -= te2->timeout;
+			te3 = TAILQ_NEXT(te2, next);
+			if (te3 == NULL || te3->timeout > te->timeout)
+				break;
+			te2 = te3;
+		}
+		TAILQ_INSERT_AFTER(&tmrs->head, te2, te, next);
+	}
+}
+
+#define watchdog_enable(ctx) (ctx)->flags |= FLG_WATCHDOG
+#define watchdog_disable(ctx) (ctx)->flags &= ~FLG_WATCHDOG
+
+static void
+watchdog_reset(struct ctx *ctx, int timeout)
+{
+	struct timespec tp;
+
+	clock_gettime(CLOCK_MONOTONIC, &tp),
+	ctx->watchdog = tp.tv_sec + timeout;
+
+	watchdog_enable(ctx);
+}
+
+static void
+tmr_creg(int id, void *arg)
+{
+	struct ctx *ctx = arg;
+
+	at_cmd_async(ctx->fd, "AT+CREG?\r\n");
+	watchdog_reset(ctx, 10);
+}
+
+static void
+tmr_cgreg(int id, void *arg)
+{
+	struct ctx *ctx = arg;
+
+	at_cmd_async(ctx->fd, "AT+CGREG?\r\n");
+	watchdog_reset(ctx, 10);
+}
+
+static void
+tmr_status(int id, void *arg)
+{
+	struct ctx *ctx = arg;
+
+	at_cmd_async(ctx->fd, "AT+CSQ\r\n");
+	watchdog_reset(ctx, 10);
+}
+
+static void
+tmr_watchdog(int id, void *arg)
+{
+	struct ctx *ctx = arg;
+	pid_t self;
+	struct timespec tp;
+
+	tmr_add(&timers, 1, 5, tmr_watchdog, ctx);
+
+	if (!(ctx->flags & FLG_WATCHDOG))
+		return;
+
+	clock_gettime(CLOCK_MONOTONIC, &tp);
+
+	if (tp.tv_sec >= ctx->watchdog) {
+#ifdef DEBUG
+		fprintf(stderr, "Watchdog expired\n");
+#endif
+		ctx->flags |= FLG_WDEXP;
+		self = getpid();
+		kill(self, SIGHUP);	
+	}
+}
+
+static void
+sig_handle(int sig)
+{
+
+	switch (sig) {
+	case SIGHUP:
+	case SIGINT:
+	case SIGQUIT:
+	case SIGTERM:
+		running = 0;
+		break;
+	case SIGALRM:
+		tmr_run(&timers);
+		break;
+	}
+}
+
+static void
+logger(int pri, const char *fmt, ...)
+{
+	char *buf;
+	va_list ap;
+
+	va_start(ap, fmt);
+	vasprintf(&buf, fmt, ap);
+	if (syslog_open)
+		syslog(pri, buf);
+	else {
+		switch (pri) {
+		case LOG_INFO:
+		case LOG_NOTICE:
+			printf("%s\n", buf);
+			break;
+		default:
+			fprintf(stderr, "%s: %s\n", getprogname(), buf);
+			break;
+		}
+	}
+
+	free(buf);
+	va_end(ap);
+}
+
+/* Add/remove IP address from an interface */
+static int
+ifaddr_ad(int d, const char *ifnam, struct sockaddr *sa, struct sockaddr *mask)
+{
+	struct ifaliasreq req;
+	int fd, error;
+
+	fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (fd < 0)
+		return (-1);
+
+	memset(&req, 0, sizeof(struct ifaliasreq));
+	strlcpy(req.ifra_name, ifnam, sizeof(req.ifra_name));
+	memcpy(&req.ifra_addr, sa, sa->sa_len);
+	memcpy(&req.ifra_mask, mask, mask->sa_len);
+
+	error = ioctl(fd, d, (char *)&req);
+	close(fd);
+	return (error);
+}
+
+#define if_ifup(ifnam) if_setflags(ifnam, IFF_UP)
+#define if_ifdown(ifnam) if_setflags(ifnam, -IFF_UP)
+
+static int
+if_setflags(const char *ifnam, int flags)
+{
+	struct ifreq ifr;
+	int fd, error;
+	unsigned int oflags = 0;
+
+	memset(&ifr, 0, sizeof(struct ifreq));
+	strlcpy(ifr.ifr_name, ifnam, sizeof(ifr.ifr_name));
+
+	fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (fd < 0)
+		return (-1);
+
+	error = ioctl(fd, SIOCGIFFLAGS, &ifr);
+	if (error == 0) {
+		oflags = (ifr.ifr_flags & 0xffff)  | (ifr.ifr_flagshigh << 16);
+	}
+
+	if (flags < 0)
+		oflags &= ~(-flags);
+	else
+		oflags |= flags;
+
+	ifr.ifr_flags = oflags & 0xffff;
+	ifr.ifr_flagshigh = oflags >> 16;
+
+	error = ioctl(fd, SIOCSIFFLAGS, &ifr);
+	if (error != 0)
+		warn("ioctl SIOCSIFFLAGS");
+
+	close(fd);
+	return (error);
+}
+
+static int
+ifaddr_add(const char *ifnam, struct sockaddr *sa, struct sockaddr *mask)
+{
+	int error;
+
+	error = ifaddr_ad(SIOCAIFADDR, ifnam, sa, mask);
+	if (error != 0)
+		warn("ioctl SIOCAIFADDR");
+	return (error);
+}
+
+static int
+ifaddr_del(const char *ifnam, struct sockaddr *sa, struct sockaddr *mask)
+{
+	int error;
+
+	error = ifaddr_ad(SIOCDIFADDR, ifnam, sa, mask);
+	if (error != 0)
+		warn("ioctl SIOCDIFADDR");
+	return (error);
+}
+
+static int
+set_nameservers(struct ctx *ctx, const char *respath, int ns, ...)
+{
+	int i, n, fd;
+	FILE *fp;
+	char *p;
+	va_list ap;
+	struct stat sb;
+	char buf[512];
+	
+	if (ctx->ns != NULL) {
+		for (i = 0; ctx->ns[i] != NULL; i++) {
+			free(ctx->ns[i]);
+		}
+		free(ctx->ns);
+	}
+
+	fd = open(respath, O_RDWR | O_CREAT | O_NOFOLLOW);
+	if (fd < 0)
+		return (-1);
+
+	if (ns == 0) {
+		/* Attempt to restore old resolv.conf */
+		if (ctx->resolv != NULL) {
+			ftruncate(fd, 0);
+			lseek(fd, 0, SEEK_SET);
+			write(fd, ctx->resolv, ctx->resolv_sz);
+			free(ctx->resolv);
+			ctx->resolv = NULL;
+			ctx->resolv_sz = 0;
+		}
+		close(fd);
+		return (0);
+	}
+
+
+	ctx->ns = malloc(sizeof(char *) * (ns + 1));
+	if (ctx->ns == NULL) {
+		close(fd);
+		return (-1);
+	}
+
+	va_start(ap, ns);
+	for (i = 0; i < ns; i++) {
+		p = va_arg(ap, char *);
+		ctx->ns[i] = strdup(p);
+	}
+	ctx->ns[i] = NULL;
+	va_end(ap);
+
+	/* Attempt to backup the old resolv.conf */
+	if (ctx->resolv == NULL) {
+		i = fstat(fd, &sb);
+		if (i == 0 && sb.st_size != 0) {
+			ctx->resolv_sz = sb.st_size;
+			ctx->resolv = malloc(sb.st_size);
+			if (ctx->resolv != NULL) {
+				n = read(fd, ctx->resolv, sb.st_size);
+				if (n != sb.st_size) {
+					free(ctx->resolv);
+					ctx->resolv = NULL;
+				}
+			}
+		}
+	}
+
+
+	ftruncate(fd, 0);
+	lseek(fd, 0, SEEK_SET);
+	fp = fdopen(fd, "w");
+
+	/*
+	 * Write back everything other than nameserver entries to the
+	 * new resolv.conf
+	 */
+	if (ctx->resolv != NULL) {
+		p = ctx->resolv;
+		while ((i = readline_buf(p, ctx->resolv + ctx->resolv_sz, buf,
+		    sizeof(buf))) > 0) {
+			p += i;
+			if (strncasecmp(buf, "nameserver", 10) == 0)
+				continue;
+			fprintf(fp, "%s", buf);
+		}
+	}
+
+	for (i = 0; ctx->ns[i] != NULL; i++) {
+		fprintf(fp, "nameserver %s\n", ctx->ns[i]);
+	}
+	fclose(fp);
+	return (0);
+}
+
+/* Read a \n-terminated line from buffer */
+static int
+readline_buf(const char *s, const char *e, char *buf, size_t bufsz)
+{
+	int pos = 0;
+	char *p = buf;
+
+	for (; s < e; s++) {
+		*p = *s;
+		pos++;
+		if (pos >= (bufsz - 1))
+			break;
+		if (*p++ == '\n')
+			break;
+	}
+	*p = '\0';
+	return (pos);
+}
+
+/* Read a \n-terminated line from file */
+static int
+readline(int fd, char *buf, size_t bufsz)
+{
+	int n = 0, pos = 0;
+	char *p = buf;
+
+	for (;;) {
+		n = read(fd, p, 1);
+		if (n <= 0)
+			break;
+		pos++;
+		if (pos >= (bufsz - 1))
+			break;
+		if (*p++ == '\n')
+			break;
+	}
+	*p = '\0';
+	return (n <= 0 ? n : pos);
+}
+
+/*
+ * Synchronous AT command
+ */
+static int
+at_cmd(struct ctx *ctx, const char *resp, resp_cb cb, resp_arg *ra, const char *cf, ...)
+{
+	size_t l;
+	int n, error, retval = 0;
+	va_list ap;
+	fd_set set;
+	char buf[512];
+	char cmd[64];
+
+	va_start(ap, cf);
+	vsnprintf(cmd, sizeof(cmd), cf, ap);
+	va_end(ap);
+
+#ifdef DEBUG
+	fprintf(stderr, "SYNC_CMD: %s", cmd);
+#endif
+
+	l = strlen(cmd);
+	n = write(ctx->fd, cmd, l);
+	if (n <= 0)
+		return (-1);
+
+	if (resp != NULL) {
+		l = strlen(resp);
+#ifdef DEBUG
+		fprintf(stderr, "SYNC_EXP: %s (%d)\n", resp, l);
+#endif
+	}
+
+	for (;;) {
+		bzero(buf, sizeof(buf));
+
+		FD_ZERO(&set);
+		watchdog_reset(ctx, 5);
+		do {
+			FD_SET(ctx->fd, &set);
+			error = select(ctx->fd + 1, &set, NULL, NULL, NULL);
+			if (error < 0 && errno == EINTR && ctx->flags & FLG_WDEXP) {
+				watchdog_disable(ctx);
+				retval = -2;
+				break;
+			}
+		} while (error <= 0 && errno == EINTR);
+
+		if (error <= 0) {
+			retval = -2;
+			break;
+		}
+
+		n = readline(ctx->fd, buf, sizeof(buf));	
+		if (n <= 0) {
+			retval = -2;
+			break;
+		}
+		
+		if (strcmp(buf, "\r\n") == 0 || strcmp(buf, "\n") == 0)
+			continue;
+
+#ifdef DEBUG
+		fprintf(stderr, "SYNC_RESP: %s", buf);
+#endif
+
+		if (strncmp(buf, "OK", 2) == 0) {
+			break;
+		}
+		else if (strncmp(buf, "ERROR", 5) == 0) {
+			retval = -1;
+			break;
+		}
+
+		if (resp != NULL) {
+			retval = strncmp(resp, buf, l);
+			if (retval == 0 && cb != NULL) {
+				cb(ra, cmd, buf);
+			}
+		}
+	}
+#ifdef DEBUG
+	fprintf(stderr, "SYNC_RETVAL=%d\n", retval);
+#endif
+	return (retval);
+}
+
+static int
+at_cmd_async(int fd, const char *cf, ...)
+{
+	size_t l;
+	va_list ap;
+	char cmd[64];
+
+	va_start(ap, cf);
+	vsnprintf(cmd, sizeof(cmd), cf, ap);
+	va_end(ap);
+
+#ifdef DEBUG
+	fprintf(stderr, "CMD: %s", cmd);
+#endif
+	l = strlen(cmd);
+	return (write(fd, cmd, l));
+}
+
+static void
+saveresp(resp_arg *ra, const char *cmd, const char *resp)
+{
+	char **buf;
+	int i = ra->val[1].int32;
+
+	buf = realloc(ra->val[0].ptr, sizeof(char *) * (i + 1));
+	if (buf == NULL)
+		return;
+
+	buf[i] = strdup(resp);
+
+	ra->val[0].ptr = buf;
+	ra->val[1].int32 = i + 1;
+}
+
+static void
+at_async_creg(void *arg, const char *resp)
+{
+	struct ctx *ctx = arg;
+	int n, reg;
+
+	n = sscanf(resp, "+CREG: %*d,%d", ®);
+	if (n != 1) {
+		n = sscanf(resp, "+CREG: %d", ®);
+		if (n != 1)
+			return;
+	}
+
+	if (ctx->con_net_stat != 1 && ctx->con_net_stat != 5) {
+		tmr_add(&timers, 1, 1, tmr_creg, ctx);
+	}
+	else {
+		tmr_add(&timers, 1, 30, tmr_creg, ctx);
+	}
+
+	if (ctx->con_net_stat == reg)
+		return;
+
+	ctx->con_net_stat = reg;
+	at_cmd_async(ctx->fd, "AT+COPS?\r\n");
+}
+
+static void
+at_async_cgreg(void *arg, const char *resp)
+{
+	struct ctx *ctx = arg;
+	int n, reg;
+
+	n = sscanf(resp, "+CGREG: %*d,%d", ®);
+	if (n != 1) {
+		n = sscanf(resp, "+CGREG: %d", ®);
+		if (n != 1)
+			return;
+	}
+
+	if (ctx->con_net_stat != 1 && ctx->con_net_stat != 5) {
+		tmr_add(&timers, 1, 1, tmr_cgreg, ctx);
+	}
+	else {
+		tmr_add(&timers, 1, 30, tmr_cgreg, ctx);
+	}
+
+	if (ctx->con_net_stat == reg)
+		return;
+
+	ctx->con_net_stat = reg;
+	at_cmd_async(ctx->fd, "AT+COPS?\r\n");
+}
+
+
+static void
+at_async_cops(void *arg, const char *resp)
+{
+	struct ctx *ctx = arg;
+	int n, at;
+	char opr[64];
+
+	n = sscanf(resp, "+COPS: %*d,%*d,\"%[^\"]\",%d",
+	    opr, &at);
+	if (n != 2)
+		return;
+
+	if (ctx->con_oper != NULL) {
+		if (ctx->con_net_type == at &&
+		    strcasecmp(opr, ctx->con_oper) == 0)
+			return;
+		free(ctx->con_oper);
+	}
+
+	ctx->con_oper = strdup(opr);
+	ctx->con_net_type = at;
+
+	if (ctx->con_net_stat == 1 || ctx->con_net_stat == 5) {
+		logger(LOG_NOTICE, "%s to \"%s\" (%s)",
+		    network_reg_status[ctx->con_net_stat],
+		    ctx->con_oper, network_access_type[ctx->con_net_type]);
+		if (ctx->con_status != 1) {
+			at_cmd_async(ctx->fd, "AT_OWANCALL=%d,1,1\r\n",
+			    ctx->pdp_ctx);
+		}
+	}
+	else {
+		logger(LOG_NOTICE, "%s (%s)",
+		    network_reg_status[ctx->con_net_stat],
+		    network_access_type[ctx->con_net_type]);
+	}
+}
+
+/*
+ * Signal strength for pretty console output
+ *
+ * From 3GPP TS 27.007 V8.3.0, Section 8.5
+ * 0 = -113 dBm or less
+ * 1  = -111 dBm
+ * 2...30 = -109...-53 dBm
+ * 31 = -51 dBm or greater
+ *
+ * So, dbm = (rssi * 2) - 113
+*/
+static void
+at_async_csq(void *arg, const char *resp)
+{
+	struct ctx *ctx = arg;
+	int n, rssi;
+
+	n = sscanf(resp, "+CSQ: %d,%*d", &rssi);
+	if (n != 1)
+		return;
+	if (rssi == 99)
+		ctx->dbm = 0;
+	else {
+		ctx->dbm = (rssi * 2) - 113;
+		tmr_add(&timers, 1, 15, tmr_status, ctx);
+	}
+
+	ctx->flags |= FLG_NEWDATA;
+}
+
+static void
+at_async_owancall(void *arg, const char *resp)
+{
+	struct ctx *ctx = arg;
+	int n, i;
+
+	n = sscanf(resp, "_OWANCALL: %*d,%d", &i);
+	if (n != 1)
+		return;
+
+	if (i == ctx->con_status)
+		return;
+
+	at_cmd_async(ctx->fd, "AT_OWANDATA=%d\r\n", ctx->pdp_ctx);
+
+	ctx->con_status = i;
+	if (ctx->con_status == 1) {
+		logger(LOG_NOTICE, "Connected to \"%s\" (%s), %s",
+		    ctx->con_oper, ctx->con_apn,
+		    network_access_type[ctx->con_net_type]);
+	}
+	else {
+		logger(LOG_NOTICE, "Disconnected from \"%s\" (%s)",
+		    ctx->con_oper, ctx->con_apn);
+	}
+}
+
+static void
+at_async_owandata(void *arg, const char *resp)
+{
+	struct ctx *ctx = arg;
+	char ip[40], ns1[40], ns2[40];
+	int n, error, rs;
+	struct ifaddrs *ifap, *ifa;
+	struct sockaddr_in sin, mask;
+	struct sockaddr_dl sdl;
+	struct {
+		struct rt_msghdr rtm;
+		char buf[512];
+	} r;
+	char *cp = r.buf;
+
+	n = sscanf(resp, "_OWANDATA: %*d, %[^,], %*[^,], %[^,], %[^,]",
+	    ip, ns1, ns2);
+	if (n != 3)
+		return;
+
+	/* XXX: AF_INET assumption */
+
+	logger(LOG_NOTICE, "IP address: %s, Nameservers: %s, %s", ip, ns1, ns2);
+
+	sin.sin_len = mask.sin_len = sizeof(struct sockaddr_in);
+	memset(&mask.sin_addr.s_addr, 0xff, sizeof(mask.sin_addr.s_addr));
+	sin.sin_family = mask.sin_family = AF_INET;
+
+	if (ctx->flags & IPASSIGNED) {
+		memcpy(&sin.sin_addr.s_addr, &ctx->ip.s_addr,
+		    sizeof(sin.sin_addr.s_addr));
+		ifaddr_del(ctx->ifnam, (struct sockaddr *)&sin,
+		    (struct sockaddr *)&mask);
+	}
+	inet_pton(AF_INET, ip, &ctx->ip.s_addr);
+	memcpy(&sin.sin_addr.s_addr, &ctx->ip.s_addr,
+	    sizeof(sin.sin_addr.s_addr));
+
+	error = ifaddr_add(ctx->ifnam, (struct sockaddr *)&sin,
+	    (struct sockaddr *)&mask);
+	if (error != 0) {
+		logger(LOG_ERR, "failed to set ip-address");
+		return;
+	}
+
+	if_ifup(ctx->ifnam);
+
+	ctx->flags |= IPASSIGNED;
+
+	set_nameservers(ctx, ctx->resolv_path, 0);
+	error = set_nameservers(ctx, ctx->resolv_path, 2, ns1, ns2);
+	if (error != 0) {
+		logger(LOG_ERR, "failed to set nameservers");
+	}
+
+	error = getifaddrs(&ifap);
+	if (error != 0) {
+		logger(LOG_ERR, "getifaddrs: %s", strerror(errno));
+		return;
+	}
+
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr->sa_family != AF_LINK)
+			continue;
+		if (strcmp(ctx->ifnam, ifa->ifa_name) == 0) {
+			memcpy(&sdl, (struct sockaddr_dl *)ifa->ifa_addr,
+			    sizeof(struct sockaddr_dl));
+			break;	
+		}
+	}
+	if (ifa == NULL)
+		return;
+
+	rs = socket(PF_ROUTE, SOCK_RAW, 0);
+	if (rs < 0) {
+		logger(LOG_ERR, "socket PF_ROUTE: %s", strerror(errno));
+		return;
+	}
+
+	memset(&r, 0, sizeof(r));
+
+	r.rtm.rtm_version = RTM_VERSION;
+	r.rtm.rtm_type = RTM_ADD;
+	r.rtm.rtm_flags = RTF_UP | RTF_STATIC;
+	r.rtm.rtm_pid = getpid();
+	memset(&sin, 0, sizeof(struct sockaddr_in));
+	sin.sin_family = AF_INET;
+	sin.sin_len = sizeof(struct sockaddr_in);
+
+	memcpy(cp, &sin, sin.sin_len);
+	cp += SA_SIZE(&sin);
+	memcpy(cp, &sdl, sdl.sdl_len);
+	cp += SA_SIZE(&sdl);
+	memcpy(cp, &sin, sin.sin_len);
+	r.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
+	r.rtm.rtm_msglen = sizeof(r);
+
+	n = write(rs, &r, r.rtm.rtm_msglen);
+	if (n != r.rtm.rtm_msglen) {
+		r.rtm.rtm_type = RTM_DELETE;
+		n = write(rs, &r, r.rtm.rtm_msglen);
+		r.rtm.rtm_type = RTM_ADD;
+		n = write(rs, &r, r.rtm.rtm_msglen);
+	}
+
+	if (n != r.rtm.rtm_msglen) {
+		logger(LOG_ERR, "failed to set default route: %s",
+		    strerror(errno));
+	}
+	close(rs);
+
+	/* Delayed daemonization */
+	if ((ctx->flags & FLG_DELAYED) && !(ctx->flags & FLG_NODAEMON))
+		daemonize(ctx);
+}
+
+static int
+at_async(struct ctx *ctx, void *arg)
+{
+	int n, i;
+	size_t l;
+	char buf[512];
+
+	watchdog_reset(ctx, 15);
+
+	bzero(buf, sizeof(buf));	
+	n = readline(ctx->fd, buf, sizeof(buf));	
+	if (n <= 0)
+		return (n <= 0 ? -1 : 0);
+
+#ifdef DEBUG
+	fprintf(stderr, "AT_ASYNC_RESP: %s", buf);
+#endif
+	for (i = 0; async_cmd[i].cmd != NULL; i++) {
+		l = strlen(async_cmd[i].cmd);
+		if (strncmp(buf, async_cmd[i].cmd, l) == 0) {
+			async_cmd[i].func(arg, buf);
+		}
+	}
+	return (0);
+}
+
+static const char *port_type_list[] = {
+	"control", "application", "application2", NULL	
+};
+
+/*
+ * Attempts to find a list of control tty for the interface
+ * FreeBSD attaches USb devices per interface so we have to go through
+ * hoops to find which ttys that belong to our network interface.
+ */
+static char **
+get_tty(struct ctx *ctx)
+{
+	char buf[64];
+	char data[128];
+	size_t len;
+	int error;
+	unsigned int i;
+	char **list = NULL;
+	int list_size = 0;
+	const char **p;
+	
+	for (i = 0; ; i++) {
+		/* Basic test to check if we're even in the right ballpark */
+		snprintf(buf, 64, SYSCTL_TEST, i);
+		len = 127;
+		error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+		fprintf(stderr, "sysctl %s returned(%d): %s\n",
+		    buf, error, error == 0 ? data : "FAILED");
+#endif
+		if (error < 0)
+			return NULL;
+		if (strcasecmp(data, "uhso") != 0)
+			return NULL;
+
+		/* Check for interface */
+		snprintf(buf, 64, SYSCTL_NETIF, i);
+		len = 127;
+		error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+		fprintf(stderr, "sysctl %s returned(%d): %s\n",
+		    buf, error, error == 0 ? data : "FAILED");
+#endif
+		if (error < 0)
+			continue;
+
+		if (strcasecmp(data, ctx->ifnam) != 0)
+			continue;
+#ifdef DEBUG
+		fprintf(stderr, "Found %s at %s\n", ctx->ifnam, buf);
+#endif
+		break;
+	}
+
+	/* Add multiplexed ports */	
+	for (p = port_type_list; *p != NULL; p++) {
+		snprintf(buf, 64, SYSCTL_NAME_TTY, i, *p);
+		len = 127;
+		error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+		fprintf(stderr, "sysctl %s returned(%d): %s\n",
+		    buf, error, error == 0 ? data : "FAILED");
+#endif
+		if (error == 0) {
+			list = realloc(list, (list_size + 1) * sizeof(char *));
+			list[list_size] = malloc(strlen(data) + strlen(TTY_NAME));
+			sprintf(list[list_size], TTY_NAME, data);
+			list_size++;
+		}
+	}
+	
+	/*
+	 * We can return directly if we found multiplexed serial ports because
+	 * devices with these ports only have additional diagnostic ports (useless)
+	 * and modem ports (for used with pppd).
+	 */
+	if (list_size > 0) {
+		list = realloc(list, (list_size + 1) * sizeof(char *));
+		list[list_size] = NULL;
+		return list;
+	}
+
+	/*
+	 * The network port is on a high numbered interface so we walk backwards until
+	 * we hit anything other than application/control.
+	 */
+
+	for (--i; i >= 0; i--) {
+		/* Basic test to check if we're even in the right ballpark */
+		snprintf(buf, 64, SYSCTL_TEST, i);
+		len = 127;
+		error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+		fprintf(stderr, "sysctl %s returned(%d): %s\n",
+		    buf, error, error == 0 ? data : "FAILED");
+#endif
+		if (error < 0)
+			break;
+		if (strcasecmp(data, "uhso") != 0)
+			break;
+
+		/* Test for useable ports */
+		for (p = port_type_list; *p != NULL; p++) {
+			snprintf(buf, 64, SYSCTL_NAME_TTY, i, p);
+			len = 127;
+			error = sysctlbyname(buf, data, &len, NULL, 0);
+			if (error == 0) {
+				list = realloc(list, (list_size + 1) * sizeof(char *));
+				list[list_size] = malloc(strlen(data) + strlen(TTY_NAME));
+				sprintf(list[list_size], TTY_NAME, data);
+				list_size++;
+			}
+		}
+
+		/* HACK! first port is a diagnostic port, we abort here */
+		snprintf(buf, 64, SYSCTL_NAME_TTY, i, "diagnostic");
+		len = 127;
+		error = sysctlbyname(buf, data, &len, NULL, 0);
+#ifdef DEBUG
+		fprintf(stderr, "sysctl %s returned(%d): %s\n",
+		    buf, error, error == 0 ? data : "FAILED");
+#endif
+		if (error == 0)
+			break;
+	}
+
+	list = realloc(list, (list_size + 1) * sizeof(char *));
+	list[list_size] = NULL;
+	return list;	
+}
+
+static int
+do_connect(struct ctx *ctx, const char *tty)
+{
+	int i, error, needcfg;
+	resp_arg ra;
+	struct termios t;
+	char **buf;
+
+#ifdef DEBUG
+	fprintf(stderr, "Attempting to open %s\n", tty);
+#endif
+
+	ctx->fd = open(tty, O_RDWR);
+	if (ctx->fd < 0) {
+#ifdef DEBUG
+		fprintf(stderr, "Failed to open %s\n", tty);
+#endif
+		return (-1);
+	}
+
+	tcgetattr(ctx->fd, &t);
+	t.c_oflag = 0;
+	t.c_iflag = 0;
+	t.c_cflag = CLOCAL | CREAD;
+	t.c_lflag = 0;
+	tcsetattr(ctx->fd, TCSAFLUSH, &t);
+
+	error = at_cmd(ctx, NULL, NULL, NULL, "AT\r\n");
+	if (error == -2) {
+		warnx("failed to read from device");
+		return (-1);
+	}
+
+	/* Check for PIN */
+	error = at_cmd(ctx, "+CPIN: READY", NULL, NULL, "AT+CPIN?\r\n");
+	if (error != 0) {
+		if (ctx->pin == NULL) {
+			errx(1, "device requires PIN");
+		}
+
+		error = at_cmd(ctx, NULL, NULL, NULL, "AT+CPIN=\"%s\"\r\n",
+		    ctx->pin);
+		if (error != 0) {
+			errx(1, "wrong PIN");
+		}
+	}
+
+	/*
+	 * Check if a PDP context has been configured and configure one
+	 * if needed.
+	 */
+	ra.val[0].ptr = NULL;
+	ra.val[1].int32 = 0;
+	error = at_cmd(ctx, "+CGDCONT", saveresp, &ra, "AT+CGDCONT?\r\n");
+	buf = ra.val[0].ptr;
+	needcfg = 1;
+	for (i = 0; i < ra.val[1].int32; i++) {
+		char apn[256];
+		int cid;
+		error = sscanf(buf[i], "+CGDCONT: %d,\"%*[^\"]\",\"%[^\"]\"",
+		    &cid, apn);
+		if (error != 2) {
+			free(buf[i]);
+			continue;
+		}
+
+		if (cid == ctx->pdp_ctx) {
+			ctx->con_apn = strdup(apn);
+			if (ctx->pdp_apn != NULL) {
+				if (strcmp(apn, ctx->pdp_apn) == 0)
+					needcfg = 0;
+			}
+			else {
+				needcfg = 0;
+			}
+		}
+		free(buf[i]);
+	}
+	free(buf);
+
+	if (needcfg) {
+		if (ctx->pdp_apn == NULL)
+			errx(1, "device is not configured and no APN given");
+
+		error = at_cmd(ctx, NULL, NULL, NULL,
+		   "AT+CGDCONT=%d,,\"%s\"\r\n", ctx->pdp_ctx, ctx->pdp_apn);
+		if (error != 0) {
+			errx(1, "failed to configure device");
+		}
+		ctx->con_apn = strdup(ctx->pdp_apn);
+	}
+
+	if (ctx->pdp_user != NULL || ctx->pdp_pwd != NULL) {
+		at_cmd(ctx, NULL, NULL, NULL,
+		    "AT$QCPDPP=%d,1,\"%s\",\"%s\"\r\n", ctx->pdp_ctx,
+		    (ctx->pdp_user != NULL) ? ctx->pdp_user : "",
+		    (ctx->pdp_pwd != NULL) ? ctx->pdp_pwd : "");
+	}
+
+	error = at_cmd(ctx, NULL, NULL, NULL, "AT_OWANCALL=%d,0,0\r\n",
+	    ctx->pdp_ctx);
+	if (error != 0)
+		return (-1);
+
+	at_cmd_async(ctx->fd, "AT+CGREG?\r\n");
+	at_cmd_async(ctx->fd, "AT+CREG?\r\n");
+
+	tmr_add(&timers, 1, 5, tmr_status, ctx);
+	return (0);
+}
+
+static void
+do_disconnect(struct ctx *ctx)
+{
+	struct sockaddr_in sin, mask;
+
+	/* Disconnect */
+	at_cmd(ctx, NULL, NULL, NULL, "AT_OWANCALL=%d,0,0\r\n",
+	    ctx->pdp_ctx);
+	close(ctx->fd);
+
+	/* Remove ip-address from interface */
+	if (ctx->flags & IPASSIGNED) {
+		sin.sin_len = mask.sin_len = sizeof(struct sockaddr_in);
+		memset(&mask.sin_addr.s_addr, 0xff,
+		    sizeof(mask.sin_addr.s_addr));
+		sin.sin_family = mask.sin_family = AF_INET;
+		memcpy(&sin.sin_addr.s_addr, &ctx->ip.s_addr,
+		    sizeof(sin.sin_addr.s_addr));
+		ifaddr_del(ctx->ifnam, (struct sockaddr *)&sin,
+		    (struct sockaddr *)&mask);
+
+		if_ifdown(ctx->ifnam);
+		ctx->flags &= ~IPASSIGNED;
+	}
+
+	/* Attempt to reset resolv.conf */
+	set_nameservers(ctx, ctx->resolv_path, 0);
+}
+
+static void
+daemonize(struct ctx *ctx)
+{
+	struct pidfh *pfh;
+	pid_t opid;
+
+	snprintf(ctx->pidfile, 127, PIDFILE, ctx->ifnam);
+
+	pfh = pidfile_open(ctx->pidfile, 0600, &opid);
+	if (pfh == NULL) {
+		warn("Cannot create pidfile %s", ctx->pidfile);
+		return;
+	}
+
+	if (daemon(0, 0) == -1) {
+		warn("Cannot daemonize");
+		pidfile_remove(pfh);
+		return;
+	}
+	
+	pidfile_write(pfh);
+	ctx->pfh = pfh;
+	ctx->flags |= FLG_DAEMON;
+
+	snprintf(syslog_title, 63, "%s:%s", getprogname(), ctx->ifnam);
+	openlog(syslog_title, LOG_PID, LOG_USER);
+	syslog_open = 1;
+}
+
+static void
+send_disconnect(const char *ifnam)
+{
+	char pidfile[128];
+	FILE *fp;
+	pid_t pid;
+	int n;
+
+	snprintf(pidfile, 127, PIDFILE, ifnam);
+	fp = fopen(pidfile, "r");
+	if (fp == NULL) {
+		warn("Cannot open %s", pidfile);
+		return;
+	}
+
+	n = fscanf(fp, "%d", &pid);
+	fclose(fp);
+	if (n != 1) {
+		warnx("unable to read daemon pid");
+		return;
+	}
+#ifdef DEBUG
+	fprintf(stderr, "Sending SIGTERM to %d\n", pid);
+#endif
+	kill(pid, SIGTERM);
+}
+
+static void
+usage(const char *exec)
+{
+
+	printf("usage %s [-b] [-n] [-a apn] [-c cid] [-p pin] [-u username] "
+	    "[-k password] [-r resolvpath] [-f tty] interface\n", exec);
+	printf("usage %s -d interface\n", exec);
+}
+
+enum {
+	MODE_CONN,
+	MODE_DISC
+};
+
+int
+main(int argc, char *argv[])
+{
+	int ch, error, mode;
+	const char *ifnam = NULL;
+	char *tty = NULL;
+	char **p, **tty_list;
+	fd_set set;
+	struct ctx ctx;
+	struct itimerval it;
+
+	TAILQ_INIT(&timers.head);
+	timers.res = 1;
+
+	ctx.pdp_ctx = 1;
+	ctx.pdp_apn = ctx.pdp_user = ctx.pdp_pwd = NULL;
+	ctx.pin = NULL;
+
+	ctx.con_status = 0;
+	ctx.con_apn = NULL;
+	ctx.con_oper = NULL;
+	ctx.con_net_stat = 0;
+	ctx.con_net_type = -1;
+	ctx.flags = 0;
+	ctx.resolv_path = RESOLV_PATH;
+	ctx.resolv = NULL;
+	ctx.ns = NULL;
+	ctx.dbm = 0;
+
+	mode = MODE_CONN;
+	ctx.flags |= FLG_DELAYED;
+
+	while ((ch = getopt(argc, argv, "?ha:p:c:u:k:r:f:dbn")) != -1) {
+		switch (ch) {
+		case 'a':
+			ctx.pdp_apn = argv[optind - 1];
+			break;
+		case 'c':
+			ctx.pdp_ctx = strtol(argv[optind - 1], NULL, 10);
+			if (ctx.pdp_ctx < 1) {
+				warnx("Invalid context ID, defaulting to 1");
+				ctx.pdp_ctx = 1;
+			}
+			break;
+		case 'p':
+			ctx.pin = argv[optind - 1];
+			break;
+		case 'u':
+			ctx.pdp_user = argv[optind - 1];
+			break;
+		case 'k':
+			ctx.pdp_pwd = argv[optind - 1];
+			break;
+		case 'r':
+			ctx.resolv_path = argv[optind - 1];
+			break;
+		case 'd':
+			mode = MODE_DISC;
+			break;
+		case 'b':
+			ctx.flags &= ~FLG_DELAYED;
+			break;
+		case 'n':
+			ctx.flags |= FLG_NODAEMON;
+			break;
+		case 'f':
+			tty = argv[optind - 1];
+			break;
+		case 'h':
+		case '?':
+		default:
+			usage(argv[0]);
+			exit(EXIT_SUCCESS);
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc < 1)
+		errx(1, "no interface given");
+
+	ifnam = argv[argc - 1];
+	ctx.ifnam = strdup(ifnam);
+
+	switch (mode) {
+	case MODE_DISC:
+		printf("Disconnecting %s\n", ifnam);
+		send_disconnect(ifnam);
+		exit(EXIT_SUCCESS);
+	default:
+		break;
+	}
+
+	signal(SIGHUP, sig_handle);
+	signal(SIGINT, sig_handle);
+	signal(SIGQUIT, sig_handle);
+	signal(SIGTERM, sig_handle);
+	signal(SIGALRM, sig_handle);
+
+	it.it_interval.tv_sec = 1;
+	it.it_interval.tv_usec = 0;
+	it.it_value.tv_sec = 1;
+	it.it_value.tv_usec = 0;
+	error = setitimer(ITIMER_REAL, &it, NULL);
+	if (error != 0)
+		errx(1, "setitimer");
+
+	tmr_add(&timers, 1, 5, &tmr_watchdog, &ctx);
+	watchdog_reset(&ctx, 15);
+	
+	if (tty != NULL) {
+		error = do_connect(&ctx, tty);
+		if (error != 0)
+			errx(1, "Failed to open %s", tty);
+	}
+	else {
+		tty_list = get_tty(&ctx);
+#ifdef DEBUG
+		if (tty_list == NULL) {
+			fprintf(stderr, "get_tty returned empty list\n");
+		} else {
+			fprintf(stderr, "tty list:\n");
+			for (p = tty_list; *p != NULL; p++) {
+				fprintf(stderr, "\t %s\n", *p);
+			}
+		}
+#endif
+		for (p = tty_list; *p != NULL; p++) {
+			error = do_connect(&ctx, *p);
+			if (error == 0) {
+				tty = *p;
+				break;
+			}
+		}
+		if (*p == NULL)
+			errx(1, "Failed to obtain a control port, "
+			    "try specifying one manually");
+	}
+
+	if (!(ctx.flags & FLG_DELAYED) && !(ctx.flags & FLG_NODAEMON))
+		daemonize(&ctx);
+
+
+	FD_ZERO(&set);
+	FD_SET(ctx.fd, &set);
+	for (;;) {
+
+		watchdog_disable(&ctx);
+		error = select(ctx.fd + 1, &set, NULL, NULL, NULL);
+		if (error <= 0) {
+			if (running && errno == EINTR)
+				continue;
+			if (ctx.flags & FLG_WDEXP) {
+				ctx.flags &= ~FLG_WDEXP;
+				watchdog_reset(&ctx, 5);
+				do_disconnect(&ctx);
+				watchdog_reset(&ctx, 15);
+				do_connect(&ctx, tty);
+				running = 1;
+				continue;
+			}
+
+			break;
+		}
+
+		if (FD_ISSET(ctx.fd, &set)) {
+			watchdog_reset(&ctx, 15);
+			error = at_async(&ctx, &ctx);
+			if (error != 0)
+				break;
+		}
+		FD_SET(ctx.fd, &set);
+
+		if (!(ctx.flags & FLG_DAEMON) && (ctx.flags & IPASSIGNED)) {
+			printf("Status: %s (%s)",
+			    ctx.con_status ? "connected" : "disconnected",
+			    network_access_type[ctx.con_net_type]);
+			if (ctx.dbm < 0)
+				printf(", signal: %d dBm", ctx.dbm);
+			printf("\r");
+			fflush(stdout);
+		}
+	}
+	if (!(ctx.flags & FLG_DAEMON) && (ctx.flags & IPASSIGNED))
+		printf("\n");
+
+	signal(SIGHUP, SIG_DFL);
+	signal(SIGINT, SIG_DFL);
+	signal(SIGQUIT, SIG_DFL);
+	signal(SIGTERM, SIG_DFL);
+	signal(SIGALRM, SIG_IGN);
+
+	do_disconnect(&ctx);
+
+	if (ctx.flags & FLG_DAEMON) {
+		pidfile_remove(ctx.pfh);
+		if (syslog_open)
+			closelog();
+	}
+
+	return (0);
+}

From f08a4d065b0085afdc6c04d8a3161801fbe98bb9 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:24:40 +0000
Subject: [PATCH 1193/2592] MFC r202025

 Reset variable fields in case the transfer is opened again
---
 lib/libusb/libusb20.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c
index 41f9ac72de6..1c75fc16712 100644
--- a/lib/libusb/libusb20.c
+++ b/lib/libusb/libusb20.c
@@ -130,8 +130,19 @@ libusb20_tr_close(struct libusb20_transfer *xfer)
 	if (xfer->ppBuffer) {
 		free(xfer->ppBuffer);
 	}
-	/* clear some fields */
+	/* reset variable fields in case the transfer is opened again */
+	xfer->priv_sc0 = 0;
+	xfer->priv_sc1 = 0;
 	xfer->is_opened = 0;
+	xfer->is_pending = 0;
+	xfer->is_cancel = 0;
+	xfer->is_draining = 0;
+	xfer->is_restart = 0;
+	xfer->status = 0;
+	xfer->flags = 0;
+	xfer->nFrames = 0;
+	xfer->aFrames = 0;
+	xfer->timeout = 0;
 	xfer->maxFrames = 0;
 	xfer->maxTotalLength = 0;
 	xfer->maxPacketLen = 0;

From c38eb9217c6f9c40b361feda4ec94d4a1ad63afb Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:26:21 +0000
Subject: [PATCH 1194/2592] MFC r201705

 Sync to p4
  - Add new quirks commands and the '-d' option optionally to specify the ugen device.
---
 usr.sbin/usbconfig/dump.c      |  37 ++++++++
 usr.sbin/usbconfig/dump.h      |   6 ++
 usr.sbin/usbconfig/usbconfig.8 |  39 ++++++++-
 usr.sbin/usbconfig/usbconfig.c | 155 ++++++++++++++++++++++++++++-----
 4 files changed, 213 insertions(+), 24 deletions(-)

diff --git a/usr.sbin/usbconfig/dump.c b/usr.sbin/usbconfig/dump.c
index 6dfc6ec4dfb..4e527eaacbf 100644
--- a/usr.sbin/usbconfig/dump.c
+++ b/usr.sbin/usbconfig/dump.c
@@ -365,3 +365,40 @@ dump_config(struct libusb20_device *pdev, uint8_t all_cfg)
 	}
 	return;
 }
+
+void
+dump_string_by_index(struct libusb20_device *pdev, uint8_t str_index)
+{
+	char *pbuf;
+	uint8_t n;
+	uint8_t len;
+
+	pbuf = malloc(256);
+	if (pbuf == NULL)
+		err(1, "out of memory");
+
+	if (str_index == 0) {
+		/* language table */
+		if (libusb20_dev_req_string_sync(pdev,
+		    str_index, 0, pbuf, 256)) {
+			printf("STRING_0x%02x = \n", str_index);
+		} else {
+			printf("STRING_0x%02x = ", str_index);
+			len = (uint8_t)pbuf[0];
+			for (n = 0; n != len; n++) {
+				printf("0x%02x%s", (uint8_t)pbuf[n], 
+				    (n != (len-1)) ? ", " : "");
+			}
+			printf("\n");
+		}
+	} else {
+		/* ordinary string */
+		if (libusb20_dev_req_string_simple_sync(pdev,
+		    str_index, pbuf, 256)) {
+			printf("STRING_0x%02x = \n", str_index);
+		} else {
+			printf("STRING_0x%02x = <%s>\n", str_index, pbuf);
+		}
+	}
+	free(pbuf);
+}
diff --git a/usr.sbin/usbconfig/dump.h b/usr.sbin/usbconfig/dump.h
index 7fafdfd34db..581684a4cf2 100644
--- a/usr.sbin/usbconfig/dump.h
+++ b/usr.sbin/usbconfig/dump.h
@@ -24,11 +24,17 @@
  * SUCH DAMAGE.
  */
 
+#ifndef _DUMP_H_
+#define	_DUMP_H_
+
 const char *dump_mode(uint8_t value);
 const char *dump_speed(uint8_t value);
 const char *dump_power_mode(uint8_t value);
+void	dump_string_by_index(struct libusb20_device *pdev, uint8_t index);
 void	dump_device_info(struct libusb20_device *pdev, uint8_t show_drv);
 void	dump_be_quirk_names(struct libusb20_backend *pbe);
 void	dump_be_dev_quirks(struct libusb20_backend *pbe);
 void	dump_device_desc(struct libusb20_device *pdev);
 void	dump_config(struct libusb20_device *pdev, uint8_t all_cfg);
+
+#endif	/* _DUMP_H_ */
diff --git a/usr.sbin/usbconfig/usbconfig.8 b/usr.sbin/usbconfig/usbconfig.8
index 0914d9ebb17..971367d2650 100644
--- a/usr.sbin/usbconfig/usbconfig.8
+++ b/usr.sbin/usbconfig/usbconfig.8
@@ -1,6 +1,6 @@
 .\" $FreeBSD$
 .\"
-.\" Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+.\" Copyright (c) 2008-2010 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
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd November 1, 2009
+.Dd January 6, 2010
 .Dt USBCONFIG 8
 .Os
 .Sh NAME
@@ -34,6 +34,9 @@
 .Op Fl u Ar unit
 .Op Fl a Ar addr
 .Op cmds...
+.Nm
+.Op Fl d Ar [ugen].
+.Op cmds...
 .Sh DESCRIPTION
 The
 .Nm
@@ -46,6 +49,9 @@ Limit device range to USB devices connected to the given USBUS unit.
 .It Fl a Ar addr
 Limit device range to the given USB device index.
 Should only be used in conjunction with the unit argument.
+.It Fl d Ar [ugen].
+Limit device range to USB devices connected to the given unit and address.
+The unit and address coordinates may be prefixed by the lowercased word "ugen".
 .It Fl h
 Show help and available commands.
 .El
@@ -57,5 +63,34 @@ prints a list of all available USB devices.
 Show information about the device on USB bus 1 at address 2:
 .Pp
 .Dl usbconfig -u 1 -a 2 dump_info
+.Pp
+Dump HID descriptor for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 do_request 0x81 0x06 0x2200 0 0x100
+.Pp
+Dump string descriptor at index Z for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_string Z
+.Pp
+Dump current configuration descriptor for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_curr_config_desc
+.Pp
+Dump device descriptor for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_device_desc
+.Pp
+Program the device on USB bus 1 at address 2 to suspend, resume, power off, go into power save, or power on:
+.Pp
+.Dl usbconfig -u 1 -a 2 suspend
+.Dl usbconfig -u 1 -a 2 resume
+.Dl usbconfig -u 1 -a 2 power_off
+.Dl usbconfig -u 1 -a 2 power_save
+.Dl usbconfig -u 1 -a 2 power_on
+.Pp
+Display a list of available quirk names:
+.Pp
+.Dl usbconfig dump_quirk_names
+.Pp
 .Sh SEE ALSO
 .Xr usb 4
diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c
index 810e183bf89..fd701a7a8b0 100644
--- a/usr.sbin/usbconfig/usbconfig.c
+++ b/usr.sbin/usbconfig/usbconfig.c
@@ -1,6 +1,6 @@
 /* $FreeBSD$ */
 /*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2008-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
@@ -81,6 +81,8 @@ struct options {
 	uint8_t	got_show_iface_driver:1;
 	uint8_t	got_remove_device_quirk:1;
 	uint8_t	got_add_device_quirk:1;
+	uint8_t	got_remove_quirk:1;
+	uint8_t	got_add_quirk:1;
 	uint8_t	got_dump_string:1;
 	uint8_t	got_do_request:1;
 };
@@ -94,6 +96,7 @@ struct token {
 enum {
 	T_UNIT,
 	T_ADDR,
+	T_UGEN,
 	T_IFACE,
 	T_SET_CONFIG,
 	T_SET_ALT,
@@ -101,6 +104,8 @@ enum {
 	T_GET_TEMPLATE,
 	T_ADD_DEVICE_QUIRK,
 	T_REMOVE_DEVICE_QUIRK,
+	T_ADD_QUIRK,
+	T_REMOVE_QUIRK,
 	T_SHOW_IFACE_DRIVER,
 	T_DUMP_QUIRK_NAMES,
 	T_DUMP_DEVICE_QUIRKS,
@@ -124,6 +129,7 @@ static struct options options;
 static const struct token token[] = {
 	{"-u", T_UNIT, 1},
 	{"-a", T_ADDR, 1},
+	{"-d", T_UGEN, 1},
 	{"-i", T_IFACE, 1},
 	{"set_config", T_SET_CONFIG, 1},
 	{"set_alt", T_SET_ALT, 1},
@@ -131,6 +137,8 @@ static const struct token token[] = {
 	{"get_template", T_GET_TEMPLATE, 0},
 	{"add_dev_quirk_vplh", T_ADD_DEVICE_QUIRK, 5},
 	{"remove_dev_quirk_vplh", T_REMOVE_DEVICE_QUIRK, 5},
+	{"add_quirk", T_ADD_QUIRK, 1},
+	{"remove_quirk", T_REMOVE_QUIRK, 1},
 	{"dump_quirk_names", T_DUMP_QUIRK_NAMES, 0},
 	{"dump_device_quirks", T_DUMP_DEVICE_QUIRKS, 0},
 	{"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
@@ -246,12 +254,21 @@ get_int(const char *s)
 	return val;
 }
 
+static void
+duplicate_option(const char *ptr)
+{
+	printf("Syntax error: "
+	    "Duplicate option: '%s'\n", ptr);
+	exit(1);
+}
+
 static void
 usage(void)
 {
 	printf(""
 	    "usbconfig - configure the USB subsystem" "\n"
 	    "usage: usbconfig -u  -a  -i  [cmds...]" "\n"
+	    "usage: usbconfig -d [ugen]. -i  [cmds...]" "\n"
 	    "commands:" "\n"
 	    "  set_config " "\n"
 	    "  set_alt " "\n"
@@ -259,6 +276,8 @@ usage(void)
 	    "  get_template" "\n"
 	    "  add_dev_quirk_vplh     " "\n"
 	    "  remove_dev_quirk_vplh     " "\n"
+	    "  add_quirk " "\n"
+	    "  remove_quirk " "\n"
 	    "  dump_quirk_names" "\n"
 	    "  dump_device_quirks" "\n"
 	    "  dump_device_desc" "\n"
@@ -360,25 +379,33 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
 		}
 		matches++;
 
+		if (opt->got_remove_quirk) {
+			struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+	
+			ddesc = libusb20_dev_get_device_desc(pdev);
+
+			be_dev_remove_quirk(pbe,
+			    ddesc->idVendor, ddesc->idProduct, 
+			    ddesc->bcdDevice, ddesc->bcdDevice,
+			    opt->quirkname);
+		}
+
+		if (opt->got_add_quirk) {
+			struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+	
+			ddesc = libusb20_dev_get_device_desc(pdev);
+
+			be_dev_add_quirk(pbe,
+			    ddesc->idVendor, ddesc->idProduct, 
+			    ddesc->bcdDevice, ddesc->bcdDevice,
+			    opt->quirkname);
+		}
+
 		if (libusb20_dev_open(pdev, 0)) {
 			err(1, "could not open device");
 		}
 		if (opt->got_dump_string) {
-			char *pbuf;
-
-			pbuf = malloc(256);
-			if (pbuf == NULL) {
-				err(1, "out of memory");
-			}
-			if (libusb20_dev_req_string_simple_sync(pdev,
-			    opt->string_index, pbuf, 256)) {
-				printf("STRING_0x%02x = \n",
-				    opt->string_index);
-			} else {
-				printf("STRING_0x%02x = <%s>\n",
-				    opt->string_index, pbuf);
-			}
-			free(pbuf);
+			dump_string_by_index(pdev, opt->string_index);
 		}
 		if (opt->got_do_request) {
 			uint16_t actlen;
@@ -501,6 +528,9 @@ main(int argc, char **argv)
 {
 	struct libusb20_backend *pbe;
 	struct options *opt = &options;
+	const char *ptr;
+	int unit;
+	int addr;
 	int n;
 	int t;
 
@@ -518,6 +548,28 @@ main(int argc, char **argv)
 		if (t > 255)
 			t = 255;
 		switch (get_token(argv[n], t)) {
+		case T_ADD_QUIRK:
+			if (opt->got_add_quirk) {
+				flush_command(pbe, opt);
+			}
+			opt->quirkname = argv[n + 1];
+			n++;
+
+			opt->got_add_quirk = 1;
+			opt->got_any++;
+			break;
+
+		case T_REMOVE_QUIRK:
+			if (opt->got_remove_quirk) {
+				flush_command(pbe, opt);
+			}
+			opt->quirkname = argv[n + 1];
+			n++;
+
+			opt->got_remove_quirk = 1;
+			opt->got_any++;
+			break;
+
 		case T_ADD_DEVICE_QUIRK:
 			if (opt->got_add_device_quirk) {
 				flush_command(pbe, opt);
@@ -548,11 +600,15 @@ main(int argc, char **argv)
 			break;
 
 		case T_DUMP_QUIRK_NAMES:
+			if (opt->got_dump_quirk_names)
+				duplicate_option(argv[n]);
 			opt->got_dump_quirk_names = 1;
 			opt->got_any++;
 			break;
 
 		case T_DUMP_DEVICE_QUIRKS:
+			if (opt->got_dump_device_quirks)
+				duplicate_option(argv[n]);
 			opt->got_dump_device_quirks = 1;
 			opt->got_any++;
 			break;
@@ -561,6 +617,33 @@ main(int argc, char **argv)
 			opt->got_show_iface_driver = 1;
 			break;
 
+		case T_UGEN:
+			if (opt->got_any) {
+				/* allow multiple commands on the same line */
+				flush_command(pbe, opt);
+			}
+			ptr = argv[n + 1];
+
+			if ((ptr[0] == 'u') &&
+			    (ptr[1] == 'g') &&
+			    (ptr[2] == 'e') &&
+			    (ptr[3] == 'n'))
+				ptr += 4;
+
+			if ((sscanf(ptr, "%d.%d",
+			    &unit, &addr) != 2) ||
+			    (unit < 0) || (unit > 65535) ||
+			    (addr < 0) || (addr > 65535)) {
+				errx(1, "cannot "
+				    "parse '%s'", argv[n + 1]);
+			}
+			opt->bus = unit;
+			opt->addr = addr;
+			opt->got_bus = 1;
+;			opt->got_addr = 1;
+			n++;
+			break;
+
 		case T_UNIT:
 			if (opt->got_any) {
 				/* allow multiple commands on the same line */
@@ -581,84 +664,112 @@ main(int argc, char **argv)
 			n++;
 			break;
 		case T_SET_CONFIG:
+			if (opt->got_set_config)
+				duplicate_option(argv[n]);
 			opt->config_index = num_id(argv[n + 1], "cfg_index");
 			opt->got_set_config = 1;
 			opt->got_any++;
 			n++;
 			break;
 		case T_SET_ALT:
+			if (opt->got_set_alt)
+				duplicate_option(argv[n]);
 			opt->alt_index = num_id(argv[n + 1], "cfg_index");
 			opt->got_set_alt = 1;
 			opt->got_any++;
 			n++;
 			break;
 		case T_SET_TEMPLATE:
+			if (opt->got_set_template)
+				duplicate_option(argv[n]);
 			opt->template = get_int(argv[n + 1]);
 			opt->got_set_template = 1;
 			opt->got_any++;
 			n++;
 			break;
 		case T_GET_TEMPLATE:
+			if (opt->got_get_template)
+				duplicate_option(argv[n]);
 			opt->got_get_template = 1;
 			opt->got_any++;
 			break;
 		case T_DUMP_DEVICE_DESC:
+			if (opt->got_dump_device_desc)
+				duplicate_option(argv[n]);
 			opt->got_dump_device_desc = 1;
 			opt->got_any++;
 			break;
 		case T_DUMP_CURR_CONFIG_DESC:
+			if (opt->got_dump_curr_config)
+				duplicate_option(argv[n]);
 			opt->got_dump_curr_config = 1;
 			opt->got_any++;
 			break;
 		case T_DUMP_ALL_CONFIG_DESC:
+			if (opt->got_dump_all_config)
+				duplicate_option(argv[n]);
 			opt->got_dump_all_config = 1;
 			opt->got_any++;
 			break;
 		case T_DUMP_INFO:
+			if (opt->got_dump_info)
+				duplicate_option(argv[n]);
 			opt->got_dump_info = 1;
 			opt->got_any++;
 			break;
 		case T_DUMP_STRING:
-			if (opt->got_dump_string) {
-				flush_command(pbe, opt);
-			}
+			if (opt->got_dump_string)
+				duplicate_option(argv[n]);
 			opt->string_index = num_id(argv[n + 1], "str_index");
 			opt->got_dump_string = 1;
 			opt->got_any++;
 			n++;
 			break;
 		case T_SUSPEND:
+			if (opt->got_suspend)
+				duplicate_option(argv[n]);
 			opt->got_suspend = 1;
 			opt->got_any++;
 			break;
 		case T_RESUME:
+			if (opt->got_resume)
+				duplicate_option(argv[n]);
 			opt->got_resume = 1;
 			opt->got_any++;
 			break;
 		case T_POWER_OFF:
+			if (opt->got_power_off)
+				duplicate_option(argv[n]);
 			opt->got_power_off = 1;
 			opt->got_any++;
 			break;
 		case T_POWER_SAVE:
+			if (opt->got_power_save)
+				duplicate_option(argv[n]);
 			opt->got_power_save = 1;
 			opt->got_any++;
 			break;
 		case T_POWER_ON:
+			if (opt->got_power_on)
+				duplicate_option(argv[n]);
 			opt->got_power_on = 1;
 			opt->got_any++;
 			break;
 		case T_RESET:
+			if (opt->got_reset)
+				duplicate_option(argv[n]);
 			opt->got_reset = 1;
 			opt->got_any++;
 			break;
 		case T_LIST:
+			if (opt->got_list)
+				duplicate_option(argv[n]);
 			opt->got_list = 1;
 			opt->got_any++;
 			break;
 		case T_DO_REQUEST:
-			if (opt->got_do_request) {
-				flush_command(pbe, opt);
-			}
+			if (opt->got_do_request)
+				duplicate_option(argv[n]);
 			LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &opt->setup);
 			opt->setup.bmRequestType = num_id(argv[n + 1], "bmReqTyp");
 			opt->setup.bRequest = num_id(argv[n + 2], "bReq");

From f7a26bb3025cbc08568d4191732517bf6804fab5 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:27:13 +0000
Subject: [PATCH 1195/2592] MFC r201922

 Add missing library dependency.
---
 usr.sbin/usbconfig/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/usr.sbin/usbconfig/Makefile b/usr.sbin/usbconfig/Makefile
index 1cd0928b8a9..0aa51fae17f 100644
--- a/usr.sbin/usbconfig/Makefile
+++ b/usr.sbin/usbconfig/Makefile
@@ -4,6 +4,7 @@
 PROG=	usbconfig
 MAN=	usbconfig.8
 SRCS=	usbconfig.c dump.c
+DPADD+=	${LIBUSB}
 LDADD+= -lusb
 
 .include 

From 781ecb6a7484e79654c759d7bd2809474a6d0bf4 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:27:53 +0000
Subject: [PATCH 1196/2592] MFC r202026

 Print error messages to stderr.
---
 usr.sbin/usbconfig/usbconfig.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c
index fd701a7a8b0..2bd3668223b 100644
--- a/usr.sbin/usbconfig/usbconfig.c
+++ b/usr.sbin/usbconfig/usbconfig.c
@@ -175,7 +175,7 @@ be_dev_remove_quirk(struct libusb20_backend *pbe,
 
 	error = libusb20_be_remove_dev_quirk(pbe, &q);
 	if (error) {
-		printf("Removing quirk '%s' failed, continuing.\n", str);
+		fprintf(stderr, "Removing quirk '%s' failed, continuing.\n", str);
 	}
 	return;
 }
@@ -198,7 +198,7 @@ be_dev_add_quirk(struct libusb20_backend *pbe,
 
 	error = libusb20_be_add_dev_quirk(pbe, &q);
 	if (error) {
-		printf("Adding quirk '%s' failed, continuing.\n", str);
+		fprintf(stderr, "Adding quirk '%s' failed, continuing.\n", str);
 	}
 	return;
 }
@@ -257,7 +257,7 @@ get_int(const char *s)
 static void
 duplicate_option(const char *ptr)
 {
-	printf("Syntax error: "
+	fprintf(stderr, "Syntax error: "
 	    "Duplicate option: '%s'\n", ptr);
 	exit(1);
 }
@@ -265,7 +265,7 @@ duplicate_option(const char *ptr)
 static void
 usage(void)
 {
-	printf(""
+	fprintf(stderr, ""
 	    "usbconfig - configure the USB subsystem" "\n"
 	    "usage: usbconfig -u  -a  -i  [cmds...]" "\n"
 	    "usage: usbconfig -d [ugen]. -i  [cmds...]" "\n"
@@ -349,7 +349,7 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
 	if (opt->got_set_template) {
 		opt->got_any--;
 		if (libusb20_be_set_template(pbe, opt->template)) {
-			printf("Setting USB template %u failed, "
+			fprintf(stderr, "Setting USB template %u failed, "
 			    "continuing.\n", opt->template);
 		}
 	}

From e8f0a2d170a61ba0812e8fd9b9a6739ce6b06cab Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:29:30 +0000
Subject: [PATCH 1197/2592] MFC r201318

 Add new device ID to uipaq driver

PR:		usb/141936
Submitted by:	HASHI Hiroaki
---
 sys/dev/usb/serial/uipaq.c | 2 ++
 sys/dev/usb/usbdevs        | 1 +
 2 files changed, 3 insertions(+)

diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c
index 3bdb2307a5f..0efcaaf8206 100644
--- a/sys/dev/usb/serial/uipaq.c
+++ b/sys/dev/usb/serial/uipaq.c
@@ -1015,6 +1015,8 @@ static const struct usb_device_id uipaq_devs[] = {
 	/**/
 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WZERO3ES, 0)},
 	/**/
+	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WZERO3ADES, 0)},
+	/**/
 	{USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WILLCOM03, 0)},
 	/* Symbol USB Sync */
 	{USB_VPI(USB_VENDOR_SYMBOL, 0x2000, 0)},
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index ee72a171064..4df9a6af6d6 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -2417,6 +2417,7 @@ product SHARP SL5600		0x8006	Zaurus SL-5600 PDA
 product SHARP SLC700		0x8007	Zaurus SL-C700 PDA
 product SHARP SLC750		0x9031	Zaurus SL-C750 PDA
 product SHARP WZERO3ES		0x9123	W-ZERO3 ES Smartphone
+product SHARP WZERO3ADES	0x91ac	Advanced W-ZERO3 ES Smartphone
 product SHARP WILLCOM03		0x9242	WILLCOM03
 
 /* Shuttle Technology products */

From 6b5b582259aff92d0562448f88226688e058edfe Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:30:37 +0000
Subject: [PATCH 1198/2592] MFC r201680

 scratch_size was incorrectly passed as language ID when retrieving the language
 ID table, this broke string retrieval on some devices.

Submitted by:	Hans Petter Selasky
Reported by:	Renato Botelho
---
 sys/dev/usb/usb_device.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 7fdb7e4a2c2..a80c1300233 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -1691,8 +1691,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
 	    udev->ddesc.iSerialNumber) {
 		/* read out the language ID string */
 		err = usbd_req_get_string_desc(udev, NULL,
-		    (char *)scratch_ptr, 4, scratch_size,
-		    USB_LANGUAGE_TABLE);
+		    (char *)scratch_ptr, 4, 0, USB_LANGUAGE_TABLE);
 	} else {
 		err = USB_ERR_INVAL;
 	}

From 9d25e8387f1975dd187be91862897f0fbc9eed6d Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:31:27 +0000
Subject: [PATCH 1199/2592] MFC r201681

 Improve u3g device ejecting by providing additional methods for the eject
 command in the usb_msctest routines, as well as a general tidyup.
---
 sys/dev/usb/serial/u3g.c  | 231 ++++++++++++++++++----------------
 sys/dev/usb/usb_device.c  |   2 +-
 sys/dev/usb/usb_msctest.c | 258 +++++++++++++++++++++-----------------
 sys/dev/usb/usb_msctest.h |  13 +-
 4 files changed, 283 insertions(+), 221 deletions(-)

diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index 5b61948279a..5d2c81ca99d 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -86,10 +86,14 @@ SYSCTL_INT(_hw_usb_u3g, OID_AUTO, debug, CTLFLAG_RW,
 #define	U3GSP_HSPA		6
 #define	U3GSP_MAX		7
 
-#define	U3GFL_HUAWEI_INIT	0x0001	/* Init command required */
-#define	U3GFL_SCSI_EJECT	0x0002	/* SCSI eject command required */
-#define	U3GFL_SIERRA_INIT	0x0004	/* Init command required */
-#define	U3GFL_SAEL_M460_INIT	0x0008	/* Init device */
+#define	U3GINIT_HUAWEI		1	/* Requires Huawei init command */
+#define	U3GINIT_SIERRA		2	/* Requires Sierra init command */
+#define	U3GINIT_SCSIEJECT	3	/* Requires SCSI eject command */
+#define	U3GINIT_REZERO		4	/* Requires SCSI rezero command */
+#define	U3GINIT_ZTESTOR		5	/* Requires ZTE SCSI command */
+#define	U3GINIT_CMOTECH		6	/* Requires CMOTECH SCSI command */
+#define	U3GINIT_WAIT		7	/* Device reappears after a delay */
+#define	U3GINIT_SAEL_M460	8	/* Requires vendor init */
 
 enum {
 	U3G_BULK_WR,
@@ -192,6 +196,7 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(ANYDATA, ADU_E100X, 0),
 	U3G_DEV(AXESSTEL, DATAMODEM, 0),
 	U3G_DEV(CMOTECH, CDMA_MODEM1, 0),
+	U3G_DEV(CMOTECH, CGU628, U3GINIT_CMOTECH),
 	U3G_DEV(DELL, U5500, 0),
 	U3G_DEV(DELL, U5505, 0),
 	U3G_DEV(DELL, U5510, 0),
@@ -211,73 +216,73 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(DLINK3, DWM652, 0),
 	U3G_DEV(HP, EV2200, 0),
 	U3G_DEV(HP, HS2300, 0),
-	U3G_DEV(HUAWEI, E1401, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1402, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1403, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1404, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1405, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1406, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1407, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1408, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1409, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E140A, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E140B, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E140D, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E140E, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E140F, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1410, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1411, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1412, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1413, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1414, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1415, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1416, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1417, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1418, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1419, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E141A, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E141B, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E141C, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E141D, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E141E, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E141F, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1420, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1421, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1422, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1423, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1424, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1425, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1426, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1427, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1428, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1429, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E142A, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E142B, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E142C, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E142D, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E142E, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E142F, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1430, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1431, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1432, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1433, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1434, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1435, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1436, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1437, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1438, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E1439, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E143A, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E143B, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E143C, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E143D, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E143E, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E143F, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E14AC, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E180V, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E220, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, E220BIS, U3GFL_HUAWEI_INIT),
-	U3G_DEV(HUAWEI, MOBILE, U3GFL_HUAWEI_INIT),
+	U3G_DEV(HUAWEI, E1401, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1402, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1403, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1404, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1405, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1406, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1407, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1408, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1409, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E140A, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E140B, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E140D, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E140E, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E140F, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1410, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1411, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1412, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1413, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1414, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1415, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1416, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1417, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1418, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1419, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E141A, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E141B, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E141C, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E141D, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E141E, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E141F, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1420, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1421, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1422, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1423, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1424, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1425, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1426, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1427, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1428, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1429, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E142A, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E142B, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E142C, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E142D, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E142E, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E142F, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1430, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1431, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1432, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1433, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1434, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1435, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1436, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1437, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1438, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E1439, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E143A, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E143B, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E143C, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E143D, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E143E, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E143F, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E14AC, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E180V, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI),
+	U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI),
 	U3G_DEV(KYOCERA2, CDMA_MSM_K, 0),
 	U3G_DEV(KYOCERA2, KPC680, 0),
 	U3G_DEV(MERLIN, V620, 0),
@@ -294,7 +299,7 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(NOVATEL, U727_2, 0),
 	U3G_DEV(NOVATEL, U740, 0),
 	U3G_DEV(NOVATEL, U740_2, 0),
-	U3G_DEV(NOVATEL, U760, U3GFL_SCSI_EJECT),
+	U3G_DEV(NOVATEL, U760, U3GINIT_SCSIEJECT),
 	U3G_DEV(NOVATEL, U870, 0),
 	U3G_DEV(NOVATEL, V620, 0),
 	U3G_DEV(NOVATEL, V640, 0),
@@ -338,7 +343,7 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(QUALCOMMINC, AC2726, 0),
 	U3G_DEV(QUALCOMMINC, AC8700, 0),
 	U3G_DEV(QUALCOMMINC, AC8710, 0),
-	U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GFL_SCSI_EJECT),
+	U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GINIT_SCSIEJECT),
 	U3G_DEV(QUALCOMMINC, E0002, 0),
 	U3G_DEV(QUALCOMMINC, E0003, 0),
 	U3G_DEV(QUALCOMMINC, E0004, 0),
@@ -405,7 +410,6 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(QUALCOMMINC, E2003, 0),
 	U3G_DEV(QUALCOMMINC, MF626, 0),
 	U3G_DEV(QUALCOMMINC, MF628, 0),
-	U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GFL_SCSI_EJECT),
 	U3G_DEV(QUANTA, GKE, 0),
 	U3G_DEV(QUANTA, GLE, 0),
 	U3G_DEV(QUANTA, GLX, 0),
@@ -466,7 +470,7 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(SIERRA, MINI5725, 0),
 	U3G_DEV(SIERRA, T11, 0),
 	U3G_DEV(SIERRA, T598, 0),
-	U3G_DEV(SILABS, SAEL, U3GFL_SAEL_M460_INIT),
+	U3G_DEV(SILABS, SAEL, U3GINIT_SAEL_M460),
 	U3G_DEV(STELERA, C105, 0),
 	U3G_DEV(STELERA, E1003, 0),
 	U3G_DEV(STELERA, E1004, 0),
@@ -492,12 +496,14 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(TOSHIBA, HSDPA, 0),
 	U3G_DEV(YISO, C893, 0),
 	/* Autoinstallers */
-	U3G_DEV(NOVATEL, ZEROCD, U3GFL_SCSI_EJECT),
-	U3G_DEV(SIERRA, TRUINSTALL, U3GFL_SIERRA_INIT),
+	U3G_DEV(NOVATEL, ZEROCD, U3GINIT_SCSIEJECT),
+	U3G_DEV(OPTION, GTICON322, U3GINIT_REZERO),
+	U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GINIT_ZTESTOR),
+	U3G_DEV(SIERRA, TRUINSTALL, U3GINIT_SIERRA),
 #undef	U3G_DEV
 };
 
-static void
+static int
 u3g_sierra_init(struct usb_device *udev)
 {
 	struct usb_device_request req;
@@ -512,10 +518,10 @@ u3g_sierra_init(struct usb_device *udev)
 	    NULL, 0, NULL, USB_MS_HZ)) {
 		/* ignore any errors */
 	}
-	return;
+	return (0);
 }
 
-static void
+static int
 u3g_huawei_init(struct usb_device *udev)
 {
 	struct usb_device_request req;
@@ -530,7 +536,7 @@ u3g_huawei_init(struct usb_device *udev)
 	    NULL, 0, NULL, USB_MS_HZ)) {
 		/* ignore any errors */
 	}
-	return;
+	return (0);
 }
 
 static void
@@ -625,7 +631,7 @@ u3g_test_autoinst(void *arg, struct usb_device *udev,
 {
 	struct usb_interface *iface;
 	struct usb_interface_descriptor *id;
-	uint32_t flags;
+	int error;
 
 	if (uaa->dev_state != UAA_DEV_READY)
 		return;
@@ -636,25 +642,41 @@ u3g_test_autoinst(void *arg, struct usb_device *udev,
 	id = iface->idesc;
 	if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
 		return;
-	if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa)) {
-		/* no device match */
-		return;
-	}
-	flags = USB_GET_DRIVER_INFO(uaa);
+	if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa))
+		return;		/* no device match */
 
-	if (flags & U3GFL_HUAWEI_INIT) {
-		u3g_huawei_init(udev);
-	} else if (flags & U3GFL_SCSI_EJECT) {
-		if (usb_test_autoinstall(udev, 0, 1) != 0)
-			return;
-	} else if (flags & U3GFL_SIERRA_INIT) {
-		u3g_sierra_init(udev);
-	} else {
-		/* no quirks */
-		return;
+	switch (USB_GET_DRIVER_INFO(uaa)) {
+		case U3GINIT_HUAWEI:
+			error = u3g_huawei_init(udev);
+			break;
+		case U3GINIT_SCSIEJECT:
+			error = usb_msc_eject(udev, 0, MSC_EJECT_STOPUNIT);
+			break;
+		case U3GINIT_REZERO:
+			error = usb_msc_eject(udev, 0, MSC_EJECT_REZERO);
+			break;
+		case U3GINIT_ZTESTOR:
+			error = usb_msc_eject(udev, 0, MSC_EJECT_ZTESTOR);
+			break;
+		case U3GINIT_CMOTECH:
+			error = usb_msc_eject(udev, 0, MSC_EJECT_CMOTECH);
+			break;
+		case U3GINIT_SIERRA:
+			error = u3g_sierra_init(udev);
+			break;
+		case U3GINIT_WAIT:
+			/* Just pretend we ejected, the card will timeout */
+			error = 0;
+			break;
+		default:
+			/* no 3G eject quirks */
+			error = EOPNOTSUPP;
+			break;
+	}
+	if (error == 0) {
+		/* success, mark the udev as disappearing */
+		uaa->dev_state = UAA_DEV_EJECTING;
 	}
-	uaa->dev_state = UAA_DEV_EJECTING;
-	return;		/* success */
 }
 
 static int
@@ -701,15 +723,14 @@ u3g_attach(device_t dev)
 	struct usb_interface *iface;
 	struct usb_interface_descriptor *id;
 	uint32_t iface_valid;
-	int error, flags, nports;
+	int error, type, nports;
 	int ep, n;
 	uint8_t i;
 
 	DPRINTF("sc=%p\n", sc);
 
-	flags = USB_GET_DRIVER_INFO(uaa);
-
-	if (flags & U3GFL_SAEL_M460_INIT)
+	type = USB_GET_DRIVER_INFO(uaa);
+	if (type == U3GINIT_SAEL_M460)
 		u3g_sael_m460_init(uaa->device);
 
 	/* copy in USB config */
@@ -781,8 +802,8 @@ u3g_attach(device_t dev)
 		DPRINTF("ucom_attach failed\n");
 		goto detach;
 	}
-	if (sc->sc_numports > 1)
-		device_printf(dev, "Found %u ports.\n", sc->sc_numports);
+	device_printf(dev, "Found %u port%s.\n", sc->sc_numports,
+	    sc->sc_numports > 1 ? "s":"");
 	return (0);
 
 detach:
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index a80c1300233..5aef59d379d 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -1805,7 +1805,7 @@ repeat_set_config:
 			 * Try to figure out if we have an
 			 * auto-install disk there:
 			 */
-			if (usb_test_autoinstall(udev, 0, 0) == 0) {
+			if (usb_iface_is_cdrom(udev, 0)) {
 				DPRINTFN(0, "Found possible auto-install "
 				    "disk (trying next config)\n");
 				config_index++;
diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c
index 61df5f1925d..99aff3f13d2 100644
--- a/sys/dev/usb/usb_msctest.c
+++ b/sys/dev/usb/usb_msctest.c
@@ -67,8 +67,7 @@
 #include 
 #include 
 #include 
-
-#include 
+#include 
 
 enum {
 	ST_COMMAND,
@@ -86,7 +85,18 @@ enum {
 	DIR_NONE,
 };
 
+#define	SCSI_INQ_LEN	0x24
+static uint8_t scsi_test_unit_ready[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static uint8_t scsi_inquiry[] = { 0x12, 0x00, 0x00, 0x00, SCSI_INQ_LEN, 0x00 };
+static uint8_t scsi_rezero_init[] =     { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static uint8_t scsi_start_stop_unit[] = { 0x1b, 0x00, 0x00, 0x00, 0x02, 0x00 };
+static uint8_t scsi_ztestor_eject[] =   { 0x85, 0x01, 0x01, 0x01, 0x18, 0x01,
+					  0x01, 0x01, 0x01, 0x01, 0x00, 0x00 };
+static uint8_t scsi_cmotech_eject[] =   { 0xff, 0x52, 0x44, 0x45, 0x56, 0x43,
+					  0x48, 0x47 };
+
 #define	BULK_SIZE		64	/* dummy */
+#define	ERR_CSW_FAILED		-1
 
 /* Command Block Wrapper */
 struct bbb_cbw {
@@ -134,8 +144,8 @@ struct bbb_transfer {
 	uint8_t	dir;
 	uint8_t	lun;
 	uint8_t	state;
-	uint8_t	error;
 	uint8_t	status_try;
+	int	error;
 
 	uint8_t	buffer[256];
 };
@@ -147,6 +157,15 @@ static usb_callback_t bbb_data_write_callback;
 static usb_callback_t bbb_data_wr_cs_callback;
 static usb_callback_t bbb_status_callback;
 
+static void	bbb_done(struct bbb_transfer *, int);
+static void	bbb_transfer_start(struct bbb_transfer *, uint8_t);
+static void	bbb_data_clear_stall_callback(struct usb_xfer *, uint8_t,
+		    uint8_t);
+static uint8_t bbb_command_start(struct bbb_transfer *, uint8_t, uint8_t,
+		    void *, size_t, void *, size_t, usb_timeout_t);
+static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t);
+static void	bbb_detach(struct bbb_transfer *);
+
 static const struct usb_config bbb_config[ST_MAX] = {
 
 	[ST_COMMAND] = {
@@ -208,25 +227,9 @@ static const struct usb_config bbb_config[ST_MAX] = {
 };
 
 static void
-bbb_done(struct bbb_transfer *sc, uint8_t error)
+bbb_done(struct bbb_transfer *sc, int error)
 {
-	struct usb_xfer *xfer;
 
-	xfer = sc->xfer[sc->state];
-
-	/* verify the error code */
-
-	if (error) {
-		switch (USB_GET_STATE(xfer)) {
-		case USB_ST_SETUP:
-		case USB_ST_TRANSFERRED:
-			error = 1;
-			break;
-		default:
-			error = 2;
-			break;
-		}
-	}
 	sc->error = error;
 	sc->state = ST_COMMAND;
 	sc->status_try = 1;
@@ -253,7 +256,7 @@ bbb_data_clear_stall_callback(struct usb_xfer *xfer,
 			bbb_transfer_start(sc, next_xfer);
 			break;
 		default:
-			bbb_done(sc, 1);
+			bbb_done(sc, USB_ERR_STALLED);
 			break;
 		}
 	}
@@ -291,7 +294,7 @@ bbb_command_callback(struct usb_xfer *xfer, usb_error_t error)
 		break;
 
 	default:			/* Error */
-		bbb_done(sc, 1);
+		bbb_done(sc, error);
 		break;
 	}
 }
@@ -333,7 +336,7 @@ bbb_data_read_callback(struct usb_xfer *xfer, usb_error_t error)
 
 	default:			/* Error */
 		if (error == USB_ERR_CANCELLED) {
-			bbb_done(sc, 1);
+			bbb_done(sc, error);
 		} else {
 			bbb_transfer_start(sc, ST_DATA_RD_CS);
 		}
@@ -385,7 +388,7 @@ bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error)
 
 	default:			/* Error */
 		if (error == USB_ERR_CANCELLED) {
-			bbb_done(sc, 1);
+			bbb_done(sc, error);
 		} else {
 			bbb_transfer_start(sc, ST_DATA_WR_CS);
 		}
@@ -415,11 +418,11 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error)
 		/* very simple status check */
 
 		if (actlen < sizeof(sc->csw)) {
-			bbb_done(sc, 1);/* error */
+			bbb_done(sc, USB_ERR_SHORT_XFER);
 		} else if (sc->csw.bCSWStatus == CSWSTATUS_GOOD) {
-			bbb_done(sc, 0);/* success */
+			bbb_done(sc, 0);	/* success */
 		} else {
-			bbb_done(sc, 1);/* error */
+			bbb_done(sc, ERR_CSW_FAILED);	/* error */
 		}
 		break;
 
@@ -429,11 +432,11 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error)
 		break;
 
 	default:
-		DPRINTFN(0, "Failed to read CSW: %s, try %d\n",
+		DPRINTF("Failed to read CSW: %s, try %d\n",
 		    usbd_errstr(error), sc->status_try);
 
 		if (error == USB_ERR_CANCELLED || sc->status_try) {
-			bbb_done(sc, 1);
+			bbb_done(sc, error);
 		} else {
 			sc->status_try = 1;
 			bbb_transfer_start(sc, ST_DATA_RD_CS);
@@ -451,7 +454,7 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error)
  *------------------------------------------------------------------------*/
 static uint8_t
 bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
-    void *data_ptr, usb_size_t data_len, uint8_t cmd_len,
+    void *data_ptr, size_t data_len, void *cmd_ptr, size_t cmd_len,
     usb_timeout_t data_timeout)
 {
 	sc->lun = lun;
@@ -461,54 +464,46 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
 	sc->data_rem = data_len;
 	sc->data_timeout = (data_timeout + USB_MS_HZ);
 	sc->actlen = 0;
+	sc->data_ptr = data_ptr;
 	sc->cmd_len = cmd_len;
+	bzero(&sc->cbw.CBWCDB, sizeof(sc->cbw.CBWCDB));
+	bcopy(cmd_ptr, &sc->cbw.CBWCDB, cmd_len);
+	DPRINTFN(1, "SCSI cmd = %*D\n", cmd_len, &sc->cbw.CBWCDB, ":");
 
+	mtx_lock(&sc->mtx);
 	usbd_transfer_start(sc->xfer[sc->state]);
 
 	while (usbd_transfer_pending(sc->xfer[sc->state])) {
 		cv_wait(&sc->cv, &sc->mtx);
 	}
+	mtx_unlock(&sc->mtx);
 	return (sc->error);
 }
 
-/*------------------------------------------------------------------------*
- *	usb_test_autoinstall
- *
- * Return values:
- * 0: This interface is an auto install disk (CD-ROM)
- * Else: Not an auto install disk.
- *------------------------------------------------------------------------*/
-usb_error_t
-usb_test_autoinstall(struct usb_device *udev, uint8_t iface_index,
-    uint8_t do_eject)
+static struct bbb_transfer *
+bbb_attach(struct usb_device *udev, uint8_t iface_index)
 {
 	struct usb_interface *iface;
 	struct usb_interface_descriptor *id;
-	usb_error_t err;
-	uint8_t timeout;
-	uint8_t sid_type;
 	struct bbb_transfer *sc;
+	usb_error_t err;
 
-	if (udev == NULL) {
-		return (USB_ERR_INVAL);
-	}
 	iface = usbd_get_iface(udev, iface_index);
-	if (iface == NULL) {
-		return (USB_ERR_INVAL);
-	}
+	if (iface == NULL)
+		return (NULL);
+
 	id = iface->idesc;
-	if (id == NULL) {
-		return (USB_ERR_INVAL);
-	}
-	if (id->bInterfaceClass != UICLASS_MASS) {
-		return (USB_ERR_INVAL);
-	}
+	if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
+		return (NULL);
+
 	switch (id->bInterfaceSubClass) {
 	case UISUBCLASS_SCSI:
 	case UISUBCLASS_UFI:
+	case UISUBCLASS_SFF8020I:
+	case UISUBCLASS_SFF8070I:
 		break;
 	default:
-		return (USB_ERR_INVAL);
+		return (NULL);
 	}
 
 	switch (id->bInterfaceProtocol) {
@@ -516,75 +511,112 @@ usb_test_autoinstall(struct usb_device *udev, uint8_t iface_index,
 	case UIPROTO_MASS_BBB:
 		break;
 	default:
-		return (USB_ERR_INVAL);
+		return (NULL);
 	}
 
 	sc = malloc(sizeof(*sc), M_USB, M_WAITOK | M_ZERO);
-	if (sc == NULL) {
-		return (USB_ERR_NOMEM);
-	}
 	mtx_init(&sc->mtx, "USB autoinstall", NULL, MTX_DEF);
 	cv_init(&sc->cv, "WBBB");
 
-	err = usbd_transfer_setup(udev,
-	    &iface_index, sc->xfer, bbb_config,
+	err = usbd_transfer_setup(udev, &iface_index, sc->xfer, bbb_config,
 	    ST_MAX, sc, &sc->mtx);
-
 	if (err) {
-		goto done;
+		bbb_detach(sc);
+		return (NULL);
 	}
-	mtx_lock(&sc->mtx);
+	return (sc);
+}
 
-	timeout = 4;			/* tries */
-
-repeat_inquiry:
-
-	sc->cbw.CBWCDB[0] = 0x12;	/* INQUIRY */
-	sc->cbw.CBWCDB[1] = 0;
-	sc->cbw.CBWCDB[2] = 0;
-	sc->cbw.CBWCDB[3] = 0;
-	sc->cbw.CBWCDB[4] = 0x24;	/* length */
-	sc->cbw.CBWCDB[5] = 0;
-	err = bbb_command_start(sc, DIR_IN, 0,
-	    sc->buffer, 0x24, 6, USB_MS_HZ);
-
-	if ((sc->actlen != 0) && (err == 0)) {
-		sid_type = sc->buffer[0] & 0x1F;
-		if (sid_type == 0x05) {
-			/* CD-ROM */
-			if (do_eject) {
-				/* 0: opcode: SCSI START/STOP */
-				sc->cbw.CBWCDB[0] = 0x1b;
-				/* 1: byte2: Not immediate */
-				sc->cbw.CBWCDB[1] = 0x00;
-				/* 2..3: reserved */
-				sc->cbw.CBWCDB[2] = 0x00;
-				sc->cbw.CBWCDB[3] = 0x00;
-				/* 4: Load/Eject command */
-				sc->cbw.CBWCDB[4] = 0x02;
-				/* 5: control */
-				sc->cbw.CBWCDB[5] = 0x00;
-				err = bbb_command_start(sc, DIR_OUT, 0,
-				    NULL, 0, 6, USB_MS_HZ);
-
-				DPRINTFN(0, "Eject CD command "
-				    "status: %s\n", usbd_errstr(err));
-			}
-			err = 0;
-			goto done;
-		}
-	} else if ((err != 2) && --timeout) {
-		usb_pause_mtx(&sc->mtx, hz);
-		goto repeat_inquiry;
-	}
-	err = USB_ERR_INVAL;
-	goto done;
-
-done:
-	mtx_unlock(&sc->mtx);
+static void
+bbb_detach(struct bbb_transfer *sc)
+{
 	usbd_transfer_unsetup(sc->xfer, ST_MAX);
 	mtx_destroy(&sc->mtx);
 	cv_destroy(&sc->cv);
 	free(sc, M_USB);
-	return (err);
+}
+
+/*------------------------------------------------------------------------*
+ *	usb_iface_is_cdrom
+ *
+ * Return values:
+ * 1: This interface is an auto install disk (CD-ROM)
+ * 0: Not an auto install disk.
+ *------------------------------------------------------------------------*/
+int
+usb_iface_is_cdrom(struct usb_device *udev, uint8_t iface_index)
+{
+	struct bbb_transfer *sc;
+	usb_error_t err;
+	uint8_t timeout, is_cdrom;
+	uint8_t sid_type;
+
+	sc = bbb_attach(udev, iface_index);
+	if (sc == NULL)
+		return (0);
+
+	is_cdrom = 0;
+	timeout = 4;	/* tries */
+	while (--timeout) {
+		err = bbb_command_start(sc, DIR_IN, 0, sc->buffer,
+		    SCSI_INQ_LEN, &scsi_inquiry, sizeof(scsi_inquiry),
+		    USB_MS_HZ);
+
+		if (err == 0 && sc->actlen > 0) {
+			sid_type = sc->buffer[0] & 0x1F;
+			if (sid_type == 0x05)
+				is_cdrom = 1;
+			break;
+		} else if (err != ERR_CSW_FAILED)
+			break;	/* non retryable error */
+		usb_pause_mtx(NULL, hz);
+	}
+	bbb_detach(sc);
+	return (is_cdrom);
+}
+
+usb_error_t
+usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
+{
+	struct bbb_transfer *sc;
+	usb_error_t err;
+
+	sc = bbb_attach(udev, iface_index);
+	if (sc == NULL)
+		return (USB_ERR_INVAL);
+
+	err = 0;
+	switch (method) {
+	case MSC_EJECT_STOPUNIT:
+		err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
+		    &scsi_test_unit_ready, sizeof(scsi_test_unit_ready),
+		    USB_MS_HZ);
+		DPRINTF("Test unit ready status: %s\n", usbd_errstr(err));
+		err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
+		    &scsi_start_stop_unit, sizeof(scsi_start_stop_unit),
+		    USB_MS_HZ);
+		break;
+	case MSC_EJECT_REZERO:
+		err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
+		    &scsi_rezero_init, sizeof(scsi_rezero_init),
+		    USB_MS_HZ);
+		break;
+	case MSC_EJECT_ZTESTOR:
+		err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
+		    &scsi_ztestor_eject, sizeof(scsi_ztestor_eject),
+		    USB_MS_HZ);
+		break;
+	case MSC_EJECT_CMOTECH:
+		err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
+		    &scsi_cmotech_eject, sizeof(scsi_cmotech_eject),
+		    USB_MS_HZ);
+		break;
+	default:
+		printf("usb_msc_eject: unknown eject method (%d)\n", method);
+		break;
+	}
+	DPRINTF("Eject CD command status: %s\n", usbd_errstr(err));
+
+	bbb_detach(sc);
+	return (0);
 }
diff --git a/sys/dev/usb/usb_msctest.h b/sys/dev/usb/usb_msctest.h
index 44fa20d96c6..2310bba29e7 100644
--- a/sys/dev/usb/usb_msctest.h
+++ b/sys/dev/usb/usb_msctest.h
@@ -27,7 +27,16 @@
 #ifndef _USB_MSCTEST_H_
 #define	_USB_MSCTEST_H_
 
-usb_error_t usb_test_autoinstall(struct usb_device *udev,
-	    uint8_t iface_index, uint8_t do_eject);
+enum {
+	MSC_EJECT_STOPUNIT,
+	MSC_EJECT_REZERO,
+	MSC_EJECT_ZTESTOR,
+	MSC_EJECT_CMOTECH
+};
+
+int usb_iface_is_cdrom(struct usb_device *udev,
+	    uint8_t iface_index);
+usb_error_t usb_msc_eject(struct usb_device *udev,
+	    uint8_t iface_index, int method);
 
 #endif					/* _USB_MSCTEST_H_ */

From 09a54b8e7921e0239cc0bd55dcd2e1cfa3088cd2 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:32:20 +0000
Subject: [PATCH 1200/2592] MFC r201701

 Add new umass quirks for Western Digital MYBook and JMicron JM20337.

PR:		usb/142225, usb/142228
Submitted by:	Thomas Ward, Yoshikazu GOTO
---
 sys/dev/usb/quirk/usb_quirk.c | 6 +++++-
 sys/dev/usb/usbdevs           | 4 ++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index 9a18dee556d..63ad120b9c9 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -225,6 +225,9 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	USB_QUIRK(IOMEGA, ZIP100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_TEST_UNIT_READY), /* XXX ZIP drives can also use ATAPI */
+	USB_QUIRK(JMICRON, JM20337, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI,
+	    UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(KYOCERA, FINECAM_L3, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
 	USB_QUIRK(KYOCERA, FINECAM_S3X, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
@@ -413,7 +416,8 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
 	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE),
 	USB_QUIRK(WESTERN, MYBOOK, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
-	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY_EVPD),
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY_EVPD,
+	    UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(WESTERN, MYPASSWORD, 0x0000, 0xffff, UQ_MSC_FORCE_SHORT_INQ),
 	USB_QUIRK(WINMAXGROUP, FLASH64MC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 4df9a6af6d6..6379c076da5 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -603,6 +603,7 @@ vendor SUPERTOP		0x14cd	Super Top
 vendor PLANEX3		0x14ea	Planex Communications
 vendor SILICONPORTALS	0x1527	Silicon Portals
 vendor UBIQUAM		0x1529	UBIQUAM Co., Ltd.
+vendor JMICRON		0x152d	JMicron
 vendor UBLOX		0x1546	U-blox
 vendor PNY		0x154b	PNY
 vendor OQO		0x1557	OQO
@@ -1671,6 +1672,9 @@ product JABLOTRON PC60B		0x0001	PC-60B
 /* Jaton products */
 product JATON EDA		0x5704	Ethernet
 
+/* JMicron products */
+product JMICRON JM20337		0x2338	USB to ATA/ATAPI Bridge
+
 /* JVC products */
 product JVC GR_DX95		0x000a	GR-DX95
 product JVC MP_PRX1		0x3008	MP-PRX1 Ethernet

From dd079737f0631681f81af5fae7e64b71bb0afc13 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:33:05 +0000
Subject: [PATCH 1201/2592] MFC r201714

 Fix debug printf on 64bit arches.
---
 sys/dev/usb/usb_msctest.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c
index 99aff3f13d2..4325d7980e0 100644
--- a/sys/dev/usb/usb_msctest.c
+++ b/sys/dev/usb/usb_msctest.c
@@ -468,7 +468,7 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
 	sc->cmd_len = cmd_len;
 	bzero(&sc->cbw.CBWCDB, sizeof(sc->cbw.CBWCDB));
 	bcopy(cmd_ptr, &sc->cbw.CBWCDB, cmd_len);
-	DPRINTFN(1, "SCSI cmd = %*D\n", cmd_len, &sc->cbw.CBWCDB, ":");
+	DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, &sc->cbw.CBWCDB, ":");
 
 	mtx_lock(&sc->mtx);
 	usbd_transfer_start(sc->xfer[sc->state]);

From ebd44816856a8f0ef24fb23e9e793af9436e649a Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:33:47 +0000
Subject: [PATCH 1202/2592] MFC r201766

 Remove unneeded includes.
---
 sys/dev/usb/serial/u3g.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index 5d2c81ca99d..a7ae60b45d7 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -59,9 +59,7 @@
 #define	USB_DEBUG_VAR u3g_debug
 #include 
 #include 
-#include 
 #include 
-#include 
 
 #include 
 

From 300db511e299a4d276b1e6ac53c0db1908b29719 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:36:22 +0000
Subject: [PATCH 1203/2592] MFC r202054

 Add the Globetrotter GE40x.
---
 sys/dev/usb/serial/u3g.c | 1 +
 sys/dev/usb/usbdevs      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index a7ae60b45d7..6fc3651a81a 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -316,6 +316,7 @@ static const struct usb_device_id u3g_devs[] = {
 	U3G_DEV(OPTION, E7041, 0),
 	U3G_DEV(OPTION, E7061, 0),
 	U3G_DEV(OPTION, E7100, 0),
+	U3G_DEV(OPTION, GE40X, 0),
 	U3G_DEV(OPTION, GT3G, 0),
 	U3G_DEV(OPTION, GT3GPLUS, 0),
 	U3G_DEV(OPTION, GT3GQUAD, 0),
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 6379c076da5..53d676dc842 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -2099,6 +2099,7 @@ product OPTION E7041		0x7041	3G modem
 product OPTION E7061		0x7061	3G modem
 product OPTION E7100		0x7100	3G modem
 product OPTION GTM380		0x7201	3G modem
+product OPTION GE40X		0x7601	Globetrotter HSUPA
 product OPTION GSICON72		0x6911	GlobeSurfer iCON
 product OPTION GSICONHSUPA	0x7251	Globetrotter HSUPA
 product OPTION ICON401		0x7401	GlobeSurfer iCON 401

From e18bb09e1a78375ff89caab4867616db712dc7f3 Mon Sep 17 00:00:00 2001
From: Andrew Thompson 
Date: Sun, 17 Jan 2010 18:37:36 +0000
Subject: [PATCH 1204/2592] Hook up uhso to the build.

---
 sys/modules/usb/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/modules/usb/Makefile b/sys/modules/usb/Makefile
index 8c771d7c382..09ad669fe1e 100644
--- a/sys/modules/usb/Makefile
+++ b/sys/modules/usb/Makefile
@@ -31,7 +31,7 @@ SUBDIR += rum uath upgt ural zyd ${_urtw}
 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
+SUBDIR += uether aue axe cdce cue kue rue udav uhso
 SUBDIR += usfs umass urio
 SUBDIR += quirk template
 

From 05cb54875e2097194633080eeaae48c9a8360a4d Mon Sep 17 00:00:00 2001
From: Rick Macklem 
Date: Sun, 17 Jan 2010 20:18:59 +0000
Subject: [PATCH 1205/2592] MFC: r201439 Fix three related problems in the
 experimental nfs client when checking for conflicts w.r.t. byte range locks
 for NFSv4. 1 - Return 0 instead of EACCES when a conflict is found, for
 F_GETLK. 2 - Check for "same file" when checking for a conflict. 3 - Don't
 check for a conflict for the F_UNLCK case.

---
 sys/fs/nfsclient/nfs_clstate.c | 43 +++++++++++++++-------------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 67727e0c741..568c5de640a 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -116,8 +116,8 @@ static int nfscl_checkconflict(struct nfscllockownerhead *, struct nfscllock *,
     u_int8_t *, struct nfscllock **);
 static void nfscl_freelockowner(struct nfscllockowner *, int);
 static void nfscl_freealllocks(struct nfscllockownerhead *, int);
-static int nfscl_localconflict(struct nfsclclient *, struct nfscllock *,
-    u_int8_t *, struct nfscldeleg *, struct nfscllock **);
+static int nfscl_localconflict(struct nfsclclient *, u_int8_t *, int,
+    struct nfscllock *, u_int8_t *, struct nfscldeleg *, struct nfscllock **);
 static void nfscl_newopen(struct nfsclclient *, struct nfscldeleg *,
     struct nfsclowner **, struct nfsclowner **, struct nfsclopen **,
     struct nfsclopen **, u_int8_t *, u_int8_t *, int, int *);
@@ -955,7 +955,8 @@ nfscl_getbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
 			lhp = &op->nfso_lock;
 	}
 	if (!error && !recovery)
-		error = nfscl_localconflict(clp, nlop, ownp, ldp, NULL);
+		error = nfscl_localconflict(clp, np->n_fhp->nfh_fh,
+		    np->n_fhp->nfh_len, nlop, ownp, ldp, NULL);
 	if (error) {
 		if (!recovery) {
 			nfscl_clrelease(clp);
@@ -1047,7 +1048,7 @@ nfscl_relbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
 	struct nfscldeleg *dp;
 	struct nfsnode *np;
 	u_int8_t own[NFSV4CL_LOCKNAMELEN];
-	int ret = 0, fnd, error;
+	int ret = 0, fnd;
 
 	np = VTONFS(vp);
 	*lpp = NULL;
@@ -1082,16 +1083,6 @@ nfscl_relbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
 		dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh,
 		    np->n_fhp->nfh_len);
 
-	/* Search for a local conflict. */
-	error = nfscl_localconflict(clp, nlop, own, dp, NULL);
-	if (error) {
-		NFSUNLOCKCLSTATE();
-		FREE((caddr_t)nlop, M_NFSCLLOCK);
-		if (other_lop != NULL)
-			FREE((caddr_t)other_lop, M_NFSCLLOCK);
-		return (error);
-	}
-
 	/*
 	 * First, unlock any local regions on a delegation.
 	 */
@@ -3169,8 +3160,9 @@ nfscl_getmnt(u_int32_t cbident)
  *   a write lock or this is an unlock.
  */
 static int
-nfscl_localconflict(struct nfsclclient *clp, struct nfscllock *nlop,
-    u_int8_t *own, struct nfscldeleg *dp, struct nfscllock **lopp)
+nfscl_localconflict(struct nfsclclient *clp, u_int8_t *fhp, int fhlen,
+    struct nfscllock *nlop, u_int8_t *own, struct nfscldeleg *dp,
+    struct nfscllock **lopp)
 {
 	struct nfsclowner *owp;
 	struct nfsclopen *op;
@@ -3183,10 +3175,13 @@ nfscl_localconflict(struct nfsclclient *clp, struct nfscllock *nlop,
 	}
 	LIST_FOREACH(owp, &clp->nfsc_owner, nfsow_list) {
 		LIST_FOREACH(op, &owp->nfsow_open, nfso_list) {
-			ret = nfscl_checkconflict(&op->nfso_lock, nlop, own,
-			    lopp);
-			if (ret)
-				return (ret);
+			if (op->nfso_fhlen == fhlen &&
+			    !NFSBCMP(op->nfso_fh, fhp, fhlen)) {
+				ret = nfscl_checkconflict(&op->nfso_lock, nlop,
+				    own, lopp);
+				if (ret)
+					return (ret);
+			}
 		}
 	}
 	return (0);
@@ -3245,10 +3240,9 @@ nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off,
 	nfscl_filllockowner(p, own);
 	NFSLOCKCLSTATE();
 	dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len);
-	error = nfscl_localconflict(clp, &nlck, own, dp, &lop);
-	if (error == NFSERR_DENIED)
-		error = EACCES;
-	if (error) {
+	error = nfscl_localconflict(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len,
+	    &nlck, own, dp, &lop);
+	if (error != 0) {
 		fl->l_whence = SEEK_SET;
 		fl->l_start = lop->nfslo_first;
 		if (lop->nfslo_end == NFS64BITSSET)
@@ -3257,6 +3251,7 @@ nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off,
 			fl->l_len = lop->nfslo_end - lop->nfslo_first;
 		fl->l_pid = (pid_t)0;
 		fl->l_type = lop->nfslo_type;
+		error = -1;			/* no RPC required */
 	} else if (dp != NULL && ((dp->nfsdl_flags & NFSCLDL_WRITE) ||
 	    fl->l_type == F_RDLCK)) {
 		/*

From 8c271f67070405ea6de95eee2c699758d8010f29 Mon Sep 17 00:00:00 2001
From: Rick Macklem 
Date: Sun, 17 Jan 2010 20:49:34 +0000
Subject: [PATCH 1206/2592] MFC: r201442 The test for "same client" for the
 experimental nfs server over NFSv4 was broken w.r.t. byte range lock
 conflicts when it was the same client and the request used the
 open_to_lock_owner4 case, since lckstp->ls_clp was not set. This patch fixes
 it by using "clp" instead of "lckstp->ls_clp".

---
 sys/fs/nfsserver/nfs_nfsdstate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 77942783155..ba97c545e52 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -1753,7 +1753,7 @@ tryagain:
 		(new_lop->lo_flags == NFSLCK_WRITE ||
 		 lop->lo_flags == NFSLCK_WRITE) &&
 		lckstp != lop->lo_stp &&
-		(lckstp->ls_clp != lop->lo_stp->ls_clp ||
+		(clp != lop->lo_stp->ls_clp ||
 		 lckstp->ls_ownerlen != lop->lo_stp->ls_ownerlen ||
 		 NFSBCMP(lckstp->ls_owner, lop->lo_stp->ls_owner,
 		    lckstp->ls_ownerlen))) {

From 7578ff89fcbdc58b6c53f73d1b39b483105b7dc7 Mon Sep 17 00:00:00 2001
From: Warner Losh 
Date: Mon, 18 Jan 2010 00:53:21 +0000
Subject: [PATCH 1207/2592] MFC r202019:   Add INCLUDE_CONFIG_FILE in GENERIC
 on all non-embedded platforms.   # This is the resolution of removing it from
 DEFAULTS...

---
 sys/amd64/conf/GENERIC   | 1 +
 sys/i386/conf/GENERIC    | 1 +
 sys/ia64/conf/GENERIC    | 1 +
 sys/pc98/conf/GENERIC    | 1 +
 sys/powerpc/conf/GENERIC | 1 +
 sys/sparc64/conf/GENERIC | 1 +
 sys/sun4v/conf/GENERIC   | 2 +-
 7 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 6dc5c2ca1ae..e5a6955f1c5 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -75,6 +75,7 @@ options 	MAC			# TrustedBSD MAC Framework
 options		FLOWTABLE		# per-cpu routing cache
 #options 	KDTRACE_FRAME		# Ensure frames are compiled in
 #options 	KDTRACE_HOOKS		# Kernel DTrace hooks
+options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
 
 # Make an SMP-capable kernel by default
 options 	SMP			# Symmetric MultiProcessor Kernel
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 7b5d4911650..f066958fa61 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -75,6 +75,7 @@ options 	AUDIT			# Security event auditing
 options 	MAC			# TrustedBSD MAC Framework
 options		FLOWTABLE		# per-cpu routing cache
 #options 	KDTRACE_HOOKS		# Kernel DTrace hooks
+options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
 
 # To make an SMP kernel, the next two lines are needed
 options 	SMP			# Symmetric MultiProcessor Kernel
diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
index 98a63fb7485..6b7411e51fe 100644
--- a/sys/ia64/conf/GENERIC
+++ b/sys/ia64/conf/GENERIC
@@ -62,6 +62,7 @@ options 	UFS_DIRHASH	# Hash-based directory lookup scheme
 options 	UFS_GJOURNAL	# Enable gjournal-based UFS journaling
 options 	_KPOSIX_PRIORITY_SCHEDULING	# Posix P1003_1B RT extensions
 options 	HWPMC_HOOKS	# Necessary kernel hooks for hwpmc(4)
+options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
 
 # Various "busses"
 device		firewire	# FireWire bus code
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 821b563d97b..491bf656ee9 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -75,6 +75,7 @@ options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
 options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
 options 	AUDIT			# Security event auditing
 options 	MAC			# TrustedBSD MAC Framework
+options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
 
 # To make an SMP kernel, the next two lines are needed
 #options 	SMP			# Symmetric MultiProcessor Kernel
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index 4fc2ce83547..a80c141a214 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -66,6 +66,7 @@ options 	_KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
 options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
 options 	AUDIT			# Security event auditing
 options 	MAC			# TrustedBSD MAC Framework
+options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
 
 # To make an SMP kernel, the next line is needed
 #options 	SMP			# Symmetric MultiProcessor Kernel
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index a9c026c4f3d..e8662395475 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -72,6 +72,7 @@ options 	PRINTF_BUFR_SIZE=128	# Prevent printf output being interspersed.
 options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
 options 	AUDIT			# Security event auditing
 options 	MAC			# TrustedBSD MAC Framework
+options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
 
 # Make an SMP-capable kernel by default
 options 	SMP			# Symmetric MultiProcessor Kernel
diff --git a/sys/sun4v/conf/GENERIC b/sys/sun4v/conf/GENERIC
index e0e2cc25b8b..2ff3fa53119 100644
--- a/sys/sun4v/conf/GENERIC
+++ b/sys/sun4v/conf/GENERIC
@@ -66,6 +66,7 @@ options 	PRINTF_BUFR_SIZE=128	# Prevent printf output being interspersed.
 options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
 options 	AUDIT			# Security event auditing
 options 	MAC			# TrustedBSD MAC Framework
+options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
 
 # Debugging for use in -current
 options 	KDB			# Enable kernel debugger support.
@@ -219,4 +220,3 @@ device		ccd
 # on most arches and in most cases 1000Hz pessimizes performance
 # its choice was not adequately researched
 options 	HZ=100
-

From 48ca68836fce1146131b9f596a4142def29b8ebf Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Mon, 18 Jan 2010 04:58:14 +0000
Subject: [PATCH 1208/2592] MFC r210520:

Test index value is within the range before using it to reference
array member.

PR:		bin/141838
Submitted by:	Henning Petersen 
---
 usr.sbin/rtsold/probe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/usr.sbin/rtsold/probe.c b/usr.sbin/rtsold/probe.c
index 61c47bc6a58..6d0ea79fd39 100644
--- a/usr.sbin/rtsold/probe.c
+++ b/usr.sbin/rtsold/probe.c
@@ -118,7 +118,7 @@ defrouter_probe(struct ifinfo *ifinfo)
 		goto closeandend;
 	}
 
-	for (i = 0; dr.defrouter[i].if_index && i < PRLSTSIZ; i++) {
+	for (i = 0; i < DRLSTSIZ && dr.defrouter[i].if_index; i++) {
 		if (ifindex && dr.defrouter[i].if_index == ifindex) {
 			/* sanity check */
 			if (!IN6_IS_ADDR_LINKLOCAL(&dr.defrouter[i].rtaddr)) {

From d958a7e440245848d72f94113f822c109242d88d Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Mon, 18 Jan 2010 05:03:40 +0000
Subject: [PATCH 1209/2592] MFC r202129:

Report ZFS filesystem version instead of the zpool version when we say it.

Reported by:	Yuri Pankov (on -fs@)
Submitted by:	delphij
---
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 08996ee2a5b..1132483d48e 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -1388,7 +1388,7 @@ void
 zfs_init(void)
 {
 
-	printf("ZFS filesystem version " SPA_VERSION_STRING "\n");
+	printf("ZFS filesystem version " ZPL_VERSION_STRING "\n");
 
 	/*
 	 * Initialize znode cache, vnode ops, etc...

From 2c9e180f34eb7842b21e33e182c001e1fd554b3f Mon Sep 17 00:00:00 2001
From: Ed Schouten 
Date: Mon, 18 Jan 2010 09:04:53 +0000
Subject: [PATCH 1210/2592] MFC r201532:

  Make TIOCSTI work again.

  It looks like I didn't implement this when I imported MPSAFE TTY.
  Applications like mail(1) still use this. I think it's conceptually bad.

  Tested by:    Pete French 
---
 sys/kern/tty.c        | 22 ++++++++++++++++------
 sys/kern/tty_compat.c | 10 ++++++----
 sys/kern/tty_pts.c    |  2 +-
 sys/sys/tty.h         |  5 +++--
 4 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 34f8ddbdcb0..3ddee728047 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -504,12 +504,12 @@ ttydev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
 	case TIOCSPGRP:
 	case TIOCSTART:
 	case TIOCSTAT:
+	case TIOCSTI:
 	case TIOCSTOP:
 	case TIOCSWINSZ:
 #if 0
 	case TIOCSDRAINWAIT:
 	case TIOCSETD:
-	case TIOCSTI:
 #endif
 #ifdef COMPAT_43TTY
 	case  TIOCLBIC:
@@ -558,7 +558,7 @@ ttydev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
 			new->c_ospeed = old->c_ospeed;
 	}
 
-	error = tty_ioctl(tp, cmd, data, td);
+	error = tty_ioctl(tp, cmd, data, fflag, td);
 done:	tty_unlock(tp);
 
 	return (error);
@@ -1330,7 +1330,8 @@ tty_flush(struct tty *tp, int flags)
 }
 
 static int
-tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td)
+tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
+    struct thread *td)
 {
 	int error;
 
@@ -1657,17 +1658,26 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td)
 	case TIOCSTAT:
 		tty_info(tp);
 		return (0);
+	case TIOCSTI:
+		if ((fflag & FREAD) == 0 && priv_check(td, PRIV_TTY_STI))
+			return (EPERM);
+		if (!tty_is_ctty(tp, td->td_proc) &&
+		    priv_check(td, PRIV_TTY_STI))
+			return (EACCES);
+		ttydisc_rint(tp, *(char *)data, 0);
+		ttydisc_rint_done(tp);
+		return (0);
 	}
 
 #ifdef COMPAT_43TTY
-	return tty_ioctl_compat(tp, cmd, data, td);
+	return tty_ioctl_compat(tp, cmd, data, fflag, td);
 #else /* !COMPAT_43TTY */
 	return (ENOIOCTL);
 #endif /* COMPAT_43TTY */
 }
 
 int
-tty_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td)
+tty_ioctl(struct tty *tp, u_long cmd, void *data, int fflag, struct thread *td)
 {
 	int error;
 
@@ -1678,7 +1688,7 @@ tty_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td)
 	
 	error = ttydevsw_ioctl(tp, cmd, data, td);
 	if (error == ENOIOCTL)
-		error = tty_generic_ioctl(tp, cmd, data, td);
+		error = tty_generic_ioctl(tp, cmd, data, fflag, td);
 
 	return (error);
 }
diff --git a/sys/kern/tty_compat.c b/sys/kern/tty_compat.c
index 00764b89d3e..6dce01d0b6d 100644
--- a/sys/kern/tty_compat.c
+++ b/sys/kern/tty_compat.c
@@ -180,7 +180,8 @@ ttsetcompat(struct tty *tp, u_long *com, caddr_t data, struct termios *term)
 
 /*ARGSUSED*/
 int
-tty_ioctl_compat(struct tty *tp, u_long com, caddr_t data, struct thread *td)
+tty_ioctl_compat(struct tty *tp, u_long com, caddr_t data, int fflag,
+    struct thread *td)
 {
 	switch (com) {
 	case TIOCSETP:
@@ -196,7 +197,7 @@ tty_ioctl_compat(struct tty *tp, u_long com, caddr_t data, struct thread *td)
 		term = tp->t_termios;
 		if ((error = ttsetcompat(tp, &com, data, &term)) != 0)
 			return error;
-		return tty_ioctl(tp, com, &term, td);
+		return tty_ioctl(tp, com, &term, fflag, td);
 	}
 	case TIOCGETP: {
 		struct sgttyb *sg = (struct sgttyb *)data;
@@ -255,12 +256,13 @@ tty_ioctl_compat(struct tty *tp, u_long com, caddr_t data, struct thread *td)
 		int ldisczero = 0;
 
 		return (tty_ioctl(tp, TIOCSETD,
-			*(int *)data == 2 ? (caddr_t)&ldisczero : data, td));
+			*(int *)data == 2 ? (caddr_t)&ldisczero : data,
+			fflag, td));
 	    }
 
 	case OTIOCCONS:
 		*(int *)data = 1;
-		return (tty_ioctl(tp, TIOCCONS, data, td));
+		return (tty_ioctl(tp, TIOCCONS, data, fflag, td));
 
 	default:
 		return (ENOIOCTL);
diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
index d5045c17b4d..e1883d68082 100644
--- a/sys/kern/tty_pts.c
+++ b/sys/kern/tty_pts.c
@@ -396,7 +396,7 @@ ptsdev_ioctl(struct file *fp, u_long cmd, void *data,
 
 	/* Just redirect this ioctl to the slave device. */
 	tty_lock(tp);
-	error = tty_ioctl(tp, cmd, data, td);
+	error = tty_ioctl(tp, cmd, data, fp->f_flag, td);
 	tty_unlock(tp);
 	if (error == ENOIOCTL)
 		error = ENOTTY;
diff --git a/sys/sys/tty.h b/sys/sys/tty.h
index d5d38459ee4..de2aa7e78d6 100644
--- a/sys/sys/tty.h
+++ b/sys/sys/tty.h
@@ -182,9 +182,10 @@ void	tty_wakeup(struct tty *tp, int flags);
 int	tty_checkoutq(struct tty *tp);
 int	tty_putchar(struct tty *tp, char c);
 
-int	tty_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td);
-int	tty_ioctl_compat(struct tty *tp, u_long cmd, caddr_t data,
+int	tty_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
     struct thread *td);
+int	tty_ioctl_compat(struct tty *tp, u_long cmd, caddr_t data,
+    int fflag, struct thread *td);
 void	tty_init_console(struct tty *tp, speed_t speed);
 void	tty_flush(struct tty *tp, int flags);
 void	tty_hiwat_in_block(struct tty *tp);

From fbd1d818efeb7862946b851054d1d8f1bdc10a7f Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Mon, 18 Jan 2010 10:53:03 +0000
Subject: [PATCH 1211/2592] MFC: revision 201391

  Do kgzip to the loader on pc98, too.  Now pc98's boot2 works for ELF.
---
 release/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/release/Makefile b/release/Makefile
index 87d08a905e4..b873067f8a6 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -1347,7 +1347,7 @@ buildBootFloppy:
 	@mkdir ${IMAGEDIR}
 	@echo "Setting up /boot directory for ${FSIMAGE} floppy"
 	@mkdir -p ${IMAGEDIR}/boot
-.if ${TARGET} == "i386"
+.if ${TARGET_ARCH} == "i386"
 	@${WMAKEENV} kgzip -v -l ${RD}/trees/base/usr/lib/kgzldr.o -o \
 	    ${IMAGEDIR}/boot/loader ${BOOTDIR}/loader
 .else

From e3ab51c73dc47c513a5641036b641e03bd1be86d Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Mon, 18 Jan 2010 10:55:29 +0000
Subject: [PATCH 1212/2592] MFC: revision 201392

  Use UFS2 as default filesystem on pc98.  Now pc98's boot2 works for UFS2.
---
 usr.sbin/sysinstall/label.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/usr.sbin/sysinstall/label.c b/usr.sbin/sysinstall/label.c
index 2ca947a724d..08cd3dfe5e5 100644
--- a/usr.sbin/sysinstall/label.c
+++ b/usr.sbin/sysinstall/label.c
@@ -384,11 +384,7 @@ new_part(PartType type, char *mpoint, Boolean newfs)
 	pi->newfs_data.newfs_ufs.acls = FALSE;
 	pi->newfs_data.newfs_ufs.multilabel = FALSE;
 	pi->newfs_data.newfs_ufs.softupdates = strcmp(mpoint, "/");
-#ifdef PC98
-	pi->newfs_data.newfs_ufs.ufs1 = TRUE;
-#else
 	pi->newfs_data.newfs_ufs.ufs1 = FALSE;
-#endif
     }
 
     return pi;

From 0bd3076764aaae85801ca481d8bff2ff62a19316 Mon Sep 17 00:00:00 2001
From: Yoshihiro Takahashi 
Date: Mon, 18 Jan 2010 11:03:39 +0000
Subject: [PATCH 1213/2592] MFC: revision 201415

  Re-enable more options and devices.  Now kernel size problem is gone.
---
 sys/pc98/conf/GENERIC | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 491bf656ee9..95a20d066fb 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -38,7 +38,7 @@ options 	SCHED_4BSD		# 4BSD scheduler
 #options 	PREEMPTION		# Enable kernel thread preemption
 options 	INET			# InterNETworking
 options 	INET6			# IPv6 communications protocols
-#options 	SCTP			# Stream Control Transmission Protocol
+options 	SCTP			# Stream Control Transmission Protocol
 options 	FFS			# Berkeley Fast Filesystem
 options 	SOFTUPDATES		# Enable FFS soft updates support
 options 	UFS_ACL			# Support for access control lists
@@ -46,13 +46,13 @@ options 	UFS_DIRHASH		# Improve performance on big directories
 options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
 options 	MD_ROOT			# MD is a potential root device
 options 	NFSCLIENT		# Network Filesystem Client
-#options 	NFSSERVER		# Network Filesystem Server
-#options 	NFSLOCKD		# Network Lock Manager
+options 	NFSSERVER		# Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
 options 	NFS_ROOT		# NFS usable as /, requires NFSCLIENT
 options 	MSDOSFS			# MSDOS Filesystem
 options 	CD9660			# ISO 9660 Filesystem
-#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
-#options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
 options 	GEOM_PART_GPT		# GUID Partition Tables.
 options 	GEOM_LABEL		# Provides labelization
 options 	COMPAT_43TTY		# BSD 4.3 TTY compat (sgtty)
@@ -66,9 +66,9 @@ options 	EPSON_BOUNCEDMA		# use bounce buffer for 15-16M
 #options 	LINE30
 options 	KTRACE			# ktrace(1) support
 options 	STACK			# stack(9) support
-#options 	SYSVSHM			# SYSV-style shared memory
-#options 	SYSVMSG			# SYSV-style message queues
-#options 	SYSVSEM			# SYSV-style semaphores
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
 options 	P1003_1B_SEMAPHORES	# POSIX-style semaphores
 options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
 options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
@@ -106,9 +106,9 @@ device		sym		# NCR/Symbios Logic (newer chipsets + those of `ncr')
 device		aic		# PC-9801-100
 device		ct		# host adapter using WD33C93[ABC] chip (C bus)
 
-#device		ncv		# NCR 53C500
-#device		nsp		# Workbit Ninja SCSI-3
-#device		stg		# TMC 18C30/18C50
+device		ncv		# NCR 53C500
+device		nsp		# Workbit Ninja SCSI-3
+device		stg		# TMC 18C30/18C50
 
 # SCSI peripherals
 device		scbus		# SCSI bus (required for SCSI)
@@ -147,9 +147,9 @@ device		sc
 
 # PCCARD (PCMCIA) support
 # PCMCIA and cardbus bridge support
-#device		cbb		# cardbus (yenta) bridge
-#device		pccard		# PC Card (16-bit) bus
-#device		cardbus		# CardBus (32-bit) bus
+device		cbb		# cardbus (yenta) bridge
+device		pccard		# PC Card (16-bit) bus
+device		cardbus		# CardBus (32-bit) bus
 
 # Serial (COM) ports
 #options 	COM_MULTIPORT
@@ -161,15 +161,15 @@ device		mse
 #device		joy
 
 # NEW Parallel port
-#device		ppc
-#device		ppbus		# Parallel port bus (required)
-#device		lpt		# Printer
-#device		plip		# TCP/IP over parallel
-#device		ppi		# Parallel port interface device
+device		ppc
+device		ppbus		# Parallel port bus (required)
+device		lpt		# Printer
+device		plip		# TCP/IP over parallel
+device		ppi		# Parallel port interface device
 #device		vpo		# Requires scbus and da
 # OLD Parallel port
 # Please stay olpt driver after ppc driver
-#device		olpt
+device		olpt
 
 # PCI Ethernet NICs.
 device		de		# DEC/Intel DC21x4x (``Tulip'')

From 78fa0901dff9e94ab716cfe6cf25481cc7d5197c Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Mon, 18 Jan 2010 13:11:37 +0000
Subject: [PATCH 1214/2592] MFC: Sync Groff with trunk except libulog addition.

---
 contrib/groff/font/devutf8/R.proto |   2 +-
 contrib/groff/tmac/an-old.tmac     |  12 ++++
 contrib/groff/tmac/doc-common      |  70 +++++++++++++++----
 contrib/groff/tmac/doc-old.tmac    |   2 +-
 contrib/groff/tmac/doc-syms        |   2 +
 contrib/groff/tmac/doc.tmac        | 104 ++++++++++++++++++++++++++---
 contrib/groff/tmac/groff_mdoc.man  |  17 +++--
 gnu/usr.bin/groff/tmac/mdoc.local  |   4 +-
 8 files changed, 180 insertions(+), 33 deletions(-)

diff --git a/contrib/groff/font/devutf8/R.proto b/contrib/groff/font/devutf8/R.proto
index 3e69500db51..ac0828fe492 100644
--- a/contrib/groff/font/devutf8/R.proto
+++ b/contrib/groff/font/devutf8/R.proto
@@ -726,7 +726,7 @@ st	24	0	0x220B
 product	24	0	0x220F
 coproduct	24	0	0x2210
 sum	24	0	0x2211
-\-	24	0	0x002D
+\-	24	0	0x2212
 mi	"
 -+	24	0	0x2213
 **	24	0	0x2217
diff --git a/contrib/groff/tmac/an-old.tmac b/contrib/groff/tmac/an-old.tmac
index b51f2e2f4f6..2bf34b304a3 100644
--- a/contrib/groff/tmac/an-old.tmac
+++ b/contrib/groff/tmac/an-old.tmac
@@ -630,6 +630,18 @@
 .  hy \n[HY]
 .\}
 .
+.\" For UTF-8, map some characters conservatively for the sake
+.\" of easy cut and paste.
+.
+.if '\*[.T]'utf8' \{\
+.  rchar \- - ' `
+.
+.  char \- \N'45'
+.  char  - \N'45'
+.  char  ' \N'39'
+.  char  ` \N'96'
+.\}
+.
 .\" Load local modifications.
 .mso man.local
 .
diff --git a/contrib/groff/tmac/doc-common b/contrib/groff/tmac/doc-common
index dc8cc28c319..ff99165ef63 100644
--- a/contrib/groff/tmac/doc-common
+++ b/contrib/groff/tmac/doc-common
@@ -46,6 +46,7 @@
 .nr %Q 1
 .nr %R 1
 .nr %T 1
+.nr %U 1
 .nr %V 1
 .nr Ac 3
 .nr Ad 12n
@@ -77,6 +78,7 @@
 .nr Dq 12n
 .nr Ds 6n\" many manpages still use this as a -width value
 .nr Dv 12n
+.nr Dx 1
 .nr Ec 3
 .nr Ef 8n\" ?
 .nr Ek 8n\" ?
@@ -219,6 +221,7 @@
 .\" NS   doc-document-title
 .\" NS   doc-section
 .\" NS   doc-volume
+.\" NS   doc-command-name
 .\" NS
 .\" NS local variables:
 .\" NS   doc-volume-as-XXX
@@ -319,6 +322,7 @@
 .  ds doc-document-title UNTITLED
 .  ds doc-volume LOCAL
 .  ds doc-section Null
+.  ds doc-command-name
 .
 .  if !"\$1"" \
 .    ds doc-document-title "\$1
@@ -357,6 +361,12 @@
 .  if !"\$3"" \
 .    if "\*[doc-volume]"LOCAL" \
 .      ds doc-volume \$3
+.
+.  if !\n[cR] \
+.    if \n[nl] \{\
+  .    doc-setup-header
+.      bp
+.    \}
 ..
 .
 .
@@ -379,6 +389,7 @@
 .\" NS
 .\" NS modifies:
 .\" NS   doc-operating-system
+.\" NS   doc-command-name
 .\" NS
 .\" NS local variables:
 .\" NS   doc-operating-system-XXX-XXX
@@ -435,9 +446,14 @@
 .ds doc-operating-system-NetBSD-2.0   2.0
 .ds doc-operating-system-NetBSD-2.0.1 2.0.1
 .ds doc-operating-system-NetBSD-2.0.2 2.0.2
+.ds doc-operating-system-NetBSD-2.0.3 2.0.3
 .ds doc-operating-system-NetBSD-2.1   2.1
 .ds doc-operating-system-NetBSD-3.0   3.0
+.ds doc-operating-system-NetBSD-3.0.1 3.0.1
+.ds doc-operating-system-NetBSD-3.0.2 3.0.2
+.ds doc-operating-system-NetBSD-3.1   3.1
 .ds doc-operating-system-NetBSD-4.0   4.0
+.ds doc-operating-system-NetBSD-4.0.1 4.0.1
 .
 .ds doc-operating-system-FreeBSD-1.0     1.0
 .ds doc-operating-system-FreeBSD-1.1     1.1
@@ -486,23 +502,48 @@
 .ds doc-operating-system-FreeBSD-6.0     6.0
 .ds doc-operating-system-FreeBSD-6.1     6.1
 .ds doc-operating-system-FreeBSD-6.2     6.2
+.ds doc-operating-system-FreeBSD-6.3     6.3
+.ds doc-operating-system-FreeBSD-6.4     6.4
 .ds doc-operating-system-FreeBSD-7.0     7.0
+.ds doc-operating-system-FreeBSD-7.1     7.1
 .
-.ds doc-operating-system-Darwin-8.0.0 8.0.0
-.ds doc-operating-system-Darwin-8.1.0 8.1.0
-.ds doc-operating-system-Darwin-8.2.0 8.2.0
-.ds doc-operating-system-Darwin-8.3.0 8.3.0
-.ds doc-operating-system-Darwin-8.4.0 8.4.0
-.ds doc-operating-system-Darwin-8.5.0 8.5.0
+.ds doc-operating-system-Darwin-8.0.0  8.0.0
+.ds doc-operating-system-Darwin-8.1.0  8.1.0
+.ds doc-operating-system-Darwin-8.2.0  8.2.0
+.ds doc-operating-system-Darwin-8.3.0  8.3.0
+.ds doc-operating-system-Darwin-8.4.0  8.4.0
+.ds doc-operating-system-Darwin-8.5.0  8.5.0
+.ds doc-operating-system-Darwin-8.6.0  8.6.0
+.ds doc-operating-system-Darwin-8.7.0  8.7.0
+.ds doc-operating-system-Darwin-8.8.0  8.8.0
+.ds doc-operating-system-Darwin-8.9.0  8.9.0
+.ds doc-operating-system-Darwin-8.10.0 8.10.0
+.ds doc-operating-system-Darwin-8.11.0 8.11.0
+.ds doc-operating-system-Darwin-9.0.0  9.0.0
+.ds doc-operating-system-Darwin-9.1.0  9.1.0
+.ds doc-operating-system-Darwin-9.2.0  9.2.0
+.ds doc-operating-system-Darwin-9.3.0  9.3.0
+.ds doc-operating-system-Darwin-9.4.0  9.4.0
+.ds doc-operating-system-Darwin-9.5.0  9.5.0
+.ds doc-operating-system-Darwin-9.6.0  9.6.0
 .
-.ds doc-operating-system-DragonFly-1.0 1.0
-.ds doc-operating-system-DragonFly-1.1 1.1
-.ds doc-operating-system-DragonFly-1.2 1.2
-.ds doc-operating-system-DragonFly-1.3 1.3
-.ds doc-operating-system-DragonFly-1.4 1.4
-.ds doc-operating-system-DragonFly-1.5 1.5
+.ds doc-operating-system-DragonFly-1.0    1.0
+.ds doc-operating-system-DragonFly-1.1    1.1
+.ds doc-operating-system-DragonFly-1.2    1.2
+.ds doc-operating-system-DragonFly-1.3    1.3
+.ds doc-operating-system-DragonFly-1.4    1.4
+.ds doc-operating-system-DragonFly-1.5    1.5
+.ds doc-operating-system-DragonFly-1.6    1.6
+.ds doc-operating-system-DragonFly-1.8    1.8
+.ds doc-operating-system-DragonFly-1.8.1  1.8.1
+.ds doc-operating-system-DragonFly-1.10   1.10
+.ds doc-operating-system-DragonFly-1.12   1.12
+.ds doc-operating-system-DragonFly-1.12.2 1.12.2
+.ds doc-operating-system-DragonFly-2.0    2.0
 .
 .de Os
+.  ds doc-command-name
+.
 .  ie "\$1"" \
 .    ds doc-operating-system "\*[doc-default-operating-system]
 .  el \{ .ie "\$1"ATT" \{\
@@ -563,6 +604,7 @@
 .\" NS
 .\" NS modifies:
 .\" NS   doc-date-string
+.\" NS   doc-command-name
 .\" NS
 .\" NS local variables:
 .\" NS   doc-date-XXX
@@ -583,6 +625,8 @@
 .ds doc-date-12 December
 .
 .de Dd
+.  ds doc-command-name
+.
 .  ie \n[.$] \{\
 .    ie (\n[.$] == 3) \
 .      ds doc-date-string \$1\~\$2 \$3
@@ -1128,6 +1172,8 @@
 .  tm doc-reference-title-count == \n[doc-reference-title-count]
 .  tm doc-reference-title-name == `\*[doc-reference-title-name]'
 .  tm doc-reference-title-name-for-book == `\*[doc-reference-title-name-for-book]'
+.  tm doc-url-count == \n[doc-url-count]
+.  tm doc-url-name == `\*[doc-url-name]'
 .  tm doc-volume-count == \n[doc-volume-count]
 .  tm doc-volume-name == `\*[doc-volume-name]'
 .  tm doc-have-author == \n[doc-have-author]
diff --git a/contrib/groff/tmac/doc-old.tmac b/contrib/groff/tmac/doc-old.tmac
index b91fabf47d3..70eb4f5e249 100644
--- a/contrib/groff/tmac/doc-old.tmac
+++ b/contrib/groff/tmac/doc-old.tmac
@@ -40,7 +40,7 @@
 .ds aD \fI
 .\"	Argument Reference Style
 .ds aR \f(CO
-.\"	Interactive Comand Modifier (flag)
+.\"	Interactive Command Modifier (flag)
 .ds cM \f(CB
 .\"	Emphasis (in the English sense - usually italics)
 .ds eM \fI
diff --git a/contrib/groff/tmac/doc-syms b/contrib/groff/tmac/doc-syms
index 25cce80c744..7e96a65dd95 100644
--- a/contrib/groff/tmac/doc-syms
+++ b/contrib/groff/tmac/doc-syms
@@ -651,6 +651,8 @@
 .\" X/Open
 .ds doc-str-St--susv2          Version\~2 of the Single \*[doc-Tn-font-size]UNIX\*[doc-str-St] Specification
 .as doc-str-St--susv2          " (\*[Lq]\*[doc-Tn-font-size]SUSv2\*[doc-str-St]\*[Rq])
+.ds doc-str-St--susv3          Version\~3 of the Single \*[doc-Tn-font-size]UNIX\*[doc-str-St] Specification
+.as doc-str-St--susv3          " (\*[Lq]\*[doc-Tn-font-size]SUSv3\*[doc-str-St]\*[Rq])
 .ds doc-str-St--svid4          System\~V Interface Definition, Fourth Edition
 .as doc-str-St--svid4          " (\*[Lq]\*[doc-Tn-font-size]SVID\*[doc-str-St]\^4\*[Rq])
 .ds doc-str-St--xbd5           \*[doc-Tn-font-size]X/Open\*[doc-str-St] System Interface Definitions Issue\~5
diff --git a/contrib/groff/tmac/doc.tmac b/contrib/groff/tmac/doc.tmac
index 083b13a0550..017835e00bf 100644
--- a/contrib/groff/tmac/doc.tmac
+++ b/contrib/groff/tmac/doc.tmac
@@ -356,10 +356,10 @@
 .    ds doc-macro-name Fl
 .    doc-parse-args \$@
 .
-.    if !\n[.$] \{\
-.      \" no arguments
+.    \" no arguments
+.    if !\n[.$] \
 .      nop \|\-\|\f[]\s[0]
-.  \}\}
+.  \}
 .
 .  if !\n[doc-arg-limit] \
 .    return
@@ -481,8 +481,8 @@
 .  el \{\
 .    nr doc-reg-dpr \n[doc-arg-ptr]
 .
+.    \" the `\%' prevents hyphenation on a dash (`-')
 .    ie (\n[doc-reg-dpr1] == 2) \
-.      \" the `\%' prevents hyphenation on a dash (`-')
 .      nop \%\*[doc-str-dpr]\&\c
 .    el \{\
 .      \" punctuation character
@@ -595,10 +595,10 @@
 .    ds doc-macro-name Ar
 .    doc-parse-args \$@
 .
-.    if !\n[.$] \{\
-.      \" no argument
+.    \" no argument
+.    if !\n[.$] \
 .      nop \)\*[doc-str-Ar-default]\&\f[]\s[0]
-.  \}\}
+.  \}
 .
 .  if !\n[doc-arg-limit] \
 .    return
@@ -1034,10 +1034,10 @@
 .    ds doc-macro-name Pa
 .    doc-parse-args \$@
 .
-.    if !\n[.$] \{\
-.      \" default value
+.    \" default value
+.    if !\n[.$] \
 .      nop \*[doc-Pa-font]~\f[]\s[0]
-.  \}\}
+.  \}
 .
 .  if !\n[doc-arg-limit] \
 .    return
@@ -3430,6 +3430,8 @@
 .  nr doc-reference-title-count-saved \n[doc-reference-title-count]
 .  ds doc-reference-title-name-saved "\*[doc-reference-title-name]
 .  ds doc-reference-title-name-for-book-saved "\*[doc-reference-title-name-for-book]
+.  nr doc-url-count-saved \n[doc-url-count]
+.  ds doc-url-name-saved "\*[doc-url-name]
 .  nr doc-volume-count-saved \n[doc-volume-count]
 .  ds doc-volume-name-saved "\*[doc-volume-name]
 .  nr doc-have-author-saved \n[doc-have-author]
@@ -3570,6 +3572,8 @@
 .  nr doc-reference-title-count \n[doc-reference-title-count-saved]
 .  ds doc-reference-title-name "\*[doc-reference-title-name-saved]
 .  ds doc-reference-title-name-for-book "\*[doc-reference-title-name-for-book-saved]
+.  nr doc-url-count \n[doc-url-count-saved]
+.  ds doc-url-name "\*[doc-url-name-saved]
 .  nr doc-volume-count \n[doc-volume-count-saved]
 .  ds doc-volume-name "\*[doc-volume-name-saved]
 .  nr doc-have-author \n[doc-have-author-saved]
@@ -5194,6 +5198,8 @@
 .\" NS   doc-reference-title-name-for-book
 .\" NS   doc-report-count
 .\" NS   doc-report-name
+.\" NS   doc-url-count
+.\" NS   doc-url-name
 .\" NS   doc-volume-count
 .\" NS   doc-volume-name
 .
@@ -5208,6 +5214,7 @@
 .  nr doc-corporate-count 0
 .  nr doc-report-count 0
 .  nr doc-reference-title-count 0
+.  nr doc-url-count 0
 .  nr doc-volume-count 0
 .  nr doc-date-count 0
 .  nr doc-page-number-count 0
@@ -5222,6 +5229,7 @@
 .  ds doc-report-name
 .  ds doc-reference-title-name
 .  ds doc-reference-title-name-for-book
+.  ds doc-url-name
 .  ds doc-volume-name
 .  ds doc-date
 .  ds doc-page-number-string
@@ -5316,6 +5324,13 @@
 .    doc-finish-reference \n[doc-volume-count]
 .  \}
 .
+.  if \n[doc-url-count] \{\
+.    unformat doc-url-name
+.    chop doc-url-name
+.    nop \*[doc-url-name]\c
+.    doc-finish-reference \n[doc-url-count]
+.  \}
+.
 .  if \n[doc-page-number-count] \{\
 .    unformat doc-page-number-string
 .    chop doc-page-number-string
@@ -6019,6 +6034,18 @@
 ..
 .
 .
+.\" NS doc-url-count global register
+.\" NS   counter of hypertext references
+.
+.nr doc-url-count 0
+.
+.
+.\" NS doc-url-name global box
+.\" NS   string of collected hypertext references
+.
+.ds doc-url-name
+.
+.
 .\" NS doc-volume-count global register
 .\" NS   counter of reference title references
 .
@@ -6031,6 +6058,48 @@
 .ds doc-volume-name
 .
 .
+.\" NS %U user macro
+.\" NS   hypertext reference
+.\" NS
+.\" NS modifies:
+.\" NS   doc-arg-ptr
+.\" NS   doc-curr-font
+.\" NS   doc-curr-size
+.\" NS   doc-macro-name
+.\" NS   doc-reference-count
+.\" NS   doc-url-count
+.\" NS
+.\" NS local variables:
+.\" NS   doc-env-%U
+.\" NS
+.\" NS width register `%U' set in doc-common
+.
+.de %U
+.  if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\
+.    tm Usage: .%U URL ... (#\n[.c])
+.    return
+.  \}
+.
+.  nr doc-url-count +1
+.  nr doc-reference-count +1
+.
+.  ds doc-macro-name %U
+.  doc-parse-args \$@
+.
+.  nr doc-arg-ptr +1
+.  nr doc-curr-font \n[.f]
+.  nr doc-curr-size \n[.ps]
+.
+.  \" append to reference box
+.  boxa doc-url-name
+.  ev doc-env-%U
+.  evc 0
+.  in 0
+.  nf
+.  doc-do-references
+..
+.
+.
 .\" NS %V user macro
 .\" NS   reference volume
 .\" NS
@@ -6039,7 +6108,7 @@
 .\" NS   doc-curr-font
 .\" NS   doc-curr-size
 .\" NS   doc-macro-name
-.\" NS   doc-reference-title-count
+.\" NS   doc-reference-count
 .\" NS   doc-volume-count
 .\" NS
 .\" NS local variables:
@@ -6428,6 +6497,19 @@
 .ec
 .
 .
+.\" For UTF-8, map some characters conservatively for the sake
+.\" of easy cut and paste.
+.
+.if '\*[.T]'utf8' \{\
+.  rchar \- - ' `
+.
+.  char \- \N'45'
+.  char  - \N'45'
+.  char  ' \N'39'
+.  char  ` \N'96'
+.\}
+.
+.
 .\" load local modifications
 .mso mdoc.local
 .
diff --git a/contrib/groff/tmac/groff_mdoc.man b/contrib/groff/tmac/groff_mdoc.man
index 5aa11b538ce..174030b88f0 100644
--- a/contrib/groff/tmac/groff_mdoc.man
+++ b/contrib/groff/tmac/groff_mdoc.man
@@ -864,16 +864,18 @@ the release ID.
 .It NetBSD
 0.8, 0.8a, 0.9, 0.9a, 1.0, 1.0a, 1.1, 1.2, 1.2a, 1.2b, 1.2c, 1.2d, 1.2e,
 1.3, 1.3a, 1.4, 1.4.1, 1.4.2, 1.4.3, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.6, 1.6.1,
-1.6.2, 2.0, 2.0.1, 2.0.2, 2.1, 3.0
+1.6.2, 1.6.3, 2.0, 2.0.1, 2.0.2, 2.0.3, 2.1, 3.0, 3.0.1, 3.0.2, 3.1, 4.0,
+4.0.1
 .It FreeBSD
 1.0, 1.1, 1.1.5, 1.1.5.1, 2.0, 2.0.5, 2.1, 2.1.5, 2.1.6, 2.1.7, 2.2, 2.2.1,
 2.2.2, 2.2.5, 2.2.6, 2.2.7, 2.2.8, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 4.0, 4.1,
 4.1.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.6.2, 4.7, 4.8, 4.9, 4.10, 4.11, 5.0, 5.1,
-5.2, 5.2.1, 5.3, 5.4, 5.5, 6.0, 6.1, 6.2, 7.0
+5.2, 5.2.1, 5.3, 5.4, 5.5, 6.0, 6.1, 6.2, 6.3, 6.4, 7.0, 7.1
 .It DragonFly
-1.0, 1.1, 1.2, 1.3, 1.4, 1.5
+1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 1.8.1, 1.10, 1.12, 1.12.2, 2.0
 .It Darwin
-8.0.0, 8.1.0, 8.2.0, 8.3.0, 8.4.0, 8.5.0
+8.0.0, 8.1.0, 8.2.0, 8.3.0, 8.4.0, 8.5.0, 8.6.0, 8.7.0, 8.8.0, 8.9.0,
+8.10.0, 8.11.0, 9.0.0, 9.1.0, 9.2.0, 9.3.0, 9.4.0, 9.5.0, 9.6.0
 .El
 .Ed
 .Pp
@@ -1995,6 +1997,8 @@ X/Open
 .Pp
 .It Li \-susv2
 .St -susv2
+.It Li \-susv3
+.St -susv3
 .It Li \-svid4
 .St -svid4
 .It Li \-xbd5
@@ -2552,6 +2556,8 @@ Corporate or foreign author.
 Report name.
 .It Li .%T
 Title of article.
+.It Li .%U
+Optional hypertext reference.
 .It Li .%V
 Volume.
 .El
@@ -4086,11 +4092,12 @@ Definitions used for all other devices.
 .It Pa mdoc.local
 Local additions and customizations.
 .It Pa andoc.tmac
-This file checks whether the
+Use this file if you don't know whether the 
 .Nm \-mdoc
 or the
 .Nm \-man
 package should be used.
+Multiple man pages (in either format) can be handled.
 .El
 .
 .
diff --git a/gnu/usr.bin/groff/tmac/mdoc.local b/gnu/usr.bin/groff/tmac/mdoc.local
index 8c7392efe5a..a0389a08f87 100644
--- a/gnu/usr.bin/groff/tmac/mdoc.local
+++ b/gnu/usr.bin/groff/tmac/mdoc.local
@@ -69,12 +69,10 @@
 .ds doc-default-operating-system FreeBSD\~8.0
 .
 .\" FreeBSD releases not found in doc-common
-.ds doc-operating-system-FreeBSD-6.3    6.3
-.ds doc-operating-system-FreeBSD-6.4    6.4
-.ds doc-operating-system-FreeBSD-7.1    7.1
 .ds doc-operating-system-FreeBSD-7.2    7.2
 .ds doc-operating-system-FreeBSD-7.3    7.3
 .ds doc-operating-system-FreeBSD-8.0    8.0
+.ds doc-operating-system-FreeBSD-9.0    9.0
 .
 .\" Definitions not (yet) in doc-syms
 .ds doc-str-St--p1003.1-2008   \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1-2008

From 702748e988744c48c08fb688a2fda13ba5f8091f Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Mon, 18 Jan 2010 14:43:44 +0000
Subject: [PATCH 1215/2592] MFC r200447,201703,201709-201710: In current code,
 threads performing an interruptible sleep will leave the waiters flag on
 forcing the owner to do a wakeup even when the waiter queue is empty. That
 operation may lead to a deadlock in the case of doing a fake wakeup on the
 "preferred" queue while the other queue has real waiters on it, because
 nobody is going to wakeup the 2nd queue waiters and they will sleep
 indefinitively. A similar bug, is present, for lockmgr in the case the
 waiters are sleeping with LK_SLEEPFAIL on.

Add a sleepqueue interface which does report the actual number of waiters
on a specified queue of a waitchannel and track if at least one sleepfail
waiter is present or not. In presence of this or empty "preferred" queue,
wakeup both waiters queues.

Discussed with:	kib
Tested by:	Pete French ,
		Justin Head 
---
 share/man/man9/sleepqueue.9 |  13 ++-
 sys/kern/kern_lock.c        | 157 ++++++++++++++++++++++++++++++++----
 sys/kern/kern_sx.c          |   6 +-
 sys/kern/subr_sleepqueue.c  |  35 +++++++-
 sys/sys/lockmgr.h           |   3 +
 sys/sys/sleepqueue.h        |   1 +
 6 files changed, 194 insertions(+), 21 deletions(-)

diff --git a/share/man/man9/sleepqueue.9 b/share/man/man9/sleepqueue.9
index 144bdc0706e..d1d17cd63cf 100644
--- a/share/man/man9/sleepqueue.9
+++ b/share/man/man9/sleepqueue.9
@@ -23,7 +23,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd December 12, 2009
+.Dd January 18, 2010
 .Dt SLEEPQUEUE 9
 .Os
 .Sh NAME
@@ -41,6 +41,7 @@
 .Nm sleepq_remove ,
 .Nm sleepq_signal ,
 .Nm sleepq_set_timeout ,
+.Nm sleepq_sleepcnt ,
 .Nm sleepq_timedwait ,
 .Nm sleepq_timedwait_sig ,
 .Nm sleepq_wait ,
@@ -77,6 +78,8 @@
 .Fn sleepq_signal "void *wchan" "int flags" "int pri" "int queue"
 .Ft void
 .Fn sleepq_set_timeout "void *wchan" "int timo"
+.Ft u_int
+.Fn sleepq_sleepcnt "void *wchan" "int queue"
 .Ft int
 .Fn sleepq_timedwait "void *wchan"
 .Ft int
@@ -355,6 +358,14 @@ One possible use is waking up a specific thread from a widely shared sleep
 channel.
 .Pp
 The
+.Fn sleepq_sleepcnt
+function offer a simple way to retrieve the number of threads sleeping for
+the specified
+.Fa queue ,
+given a
+.Fa wchan .
+.Pp
+The
 .Fn sleepq_abort ,
 .Fn sleepq_broadcast ,
 and
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index 9557038e680..7ec001117d0 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -54,8 +54,8 @@ __FBSDID("$FreeBSD$");
 #include 
 #endif
 
-CTASSERT(((LK_ADAPTIVE | LK_NOSHARE) & LO_CLASSFLAGS) ==
-    (LK_ADAPTIVE | LK_NOSHARE));
+CTASSERT(((LK_ADAPTIVE | LK_EXSLPFAIL | LK_NOSHARE) & LO_CLASSFLAGS) ==
+    (LK_ADAPTIVE | LK_EXSLPFAIL | LK_NOSHARE));
 CTASSERT(LK_UNLOCKED == (LK_UNLOCKED &
     ~(LK_ALL_WAITERS | LK_EXCLUSIVE_SPINNERS)));
 
@@ -194,6 +194,14 @@ sleeplk(struct lock *lk, u_int flags, struct lock_object *ilk,
 
 	if (flags & LK_INTERLOCK)
 		class->lc_unlock(ilk);
+
+	/*
+	 * LK_EXSLPFAIL is not invariant during the lock pattern but it is
+	 * always protected by the sleepqueue spinlock, thus it is safe to
+	 * handle within the lo_flags.
+	 */
+	if (queue == SQ_EXCLUSIVE_QUEUE && (flags & LK_SLEEPFAIL) != 0)
+		lk->lock_object.lo_flags |= LK_EXSLPFAIL;
 	GIANT_SAVE();
 	sleepq_add(&lk->lock_object, NULL, wmesg, SLEEPQ_LK | (catch ?
 	    SLEEPQ_INTERRUPTIBLE : 0), queue);
@@ -222,6 +230,7 @@ static __inline int
 wakeupshlk(struct lock *lk, const char *file, int line)
 {
 	uintptr_t v, x;
+	u_int realexslp;
 	int queue, wakeup_swapper;
 
 	TD_LOCKS_DEC(curthread);
@@ -267,13 +276,45 @@ wakeupshlk(struct lock *lk, const char *file, int line)
 		/*
 		 * If the lock has exclusive waiters, give them preference in
 		 * order to avoid deadlock with shared runners up.
+		 * If interruptible sleeps left the exclusive queue empty
+		 * avoid a starvation for the threads sleeping on the shared
+		 * queue by giving them precedence and cleaning up the
+		 * exclusive waiters bit anyway.
+		 * Please note that the LK_EXSLPFAIL flag may be lying about
+		 * the real presence of waiters with the LK_SLEEPFAIL flag on
+		 * because they may be used in conjuction with interruptible
+		 * sleeps.
 		 */
-		if (x & LK_EXCLUSIVE_WAITERS) {
-			queue = SQ_EXCLUSIVE_QUEUE;
-			v |= (x & LK_SHARED_WAITERS);
+		realexslp = sleepq_sleepcnt(&lk->lock_object,
+		    SQ_EXCLUSIVE_QUEUE);
+		if ((x & LK_EXCLUSIVE_WAITERS) != 0 && realexslp != 0) {
+			if ((lk->lock_object.lo_flags & LK_EXSLPFAIL) == 0) {
+				lk->lock_object.lo_flags &= ~LK_EXSLPFAIL;
+				queue = SQ_EXCLUSIVE_QUEUE;
+				v |= (x & LK_SHARED_WAITERS);
+			} else {
+				lk->lock_object.lo_flags &= ~LK_EXSLPFAIL;
+				LOCK_LOG2(lk,
+				    "%s: %p has only LK_SLEEPFAIL sleepers",
+				    __func__, lk);
+				LOCK_LOG2(lk,
+			    "%s: %p waking up threads on the exclusive queue",
+				    __func__, lk);
+				wakeup_swapper =
+				    sleepq_broadcast(&lk->lock_object,
+				    SLEEPQ_LK, 0, SQ_EXCLUSIVE_QUEUE);
+				queue = SQ_SHARED_QUEUE;
+			}
+				
 		} else {
-			MPASS((x & ~LK_EXCLUSIVE_SPINNERS) ==
-			    LK_SHARED_WAITERS);
+
+			/*
+			 * Exclusive waiters sleeping with LK_SLEEPFAIL on
+			 * and using interruptible sleeps/timeout may have
+			 * left spourious LK_EXSLPFAIL flag on, so clean
+			 * it up anyway.
+			 */
+			lk->lock_object.lo_flags &= ~LK_EXSLPFAIL;
 			queue = SQ_SHARED_QUEUE;
 		}
 
@@ -285,7 +326,7 @@ wakeupshlk(struct lock *lk, const char *file, int line)
 		LOCK_LOG3(lk, "%s: %p waking up threads on the %s queue",
 		    __func__, lk, queue == SQ_SHARED_QUEUE ? "shared" :
 		    "exclusive");
-		wakeup_swapper = sleepq_broadcast(&lk->lock_object, SLEEPQ_LK,
+		wakeup_swapper |= sleepq_broadcast(&lk->lock_object, SLEEPQ_LK,
 		    0, queue);
 		sleepq_release(&lk->lock_object);
 		break;
@@ -362,6 +403,8 @@ lockdestroy(struct lock *lk)
 
 	KASSERT(lk->lk_lock == LK_UNLOCKED, ("lockmgr still held"));
 	KASSERT(lk->lk_recurse == 0, ("lockmgr still recursed"));
+	KASSERT((lk->lock_object.lo_flags & LK_EXSLPFAIL) == 0,
+	    ("lockmgr still exclusive waiters"));
 	lock_destroy(&lk->lock_object);
 }
 
@@ -373,7 +416,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
 	struct lock_class *class;
 	const char *iwmesg;
 	uintptr_t tid, v, x;
-	u_int op;
+	u_int op, realexslp;
 	int error, ipri, itimo, queue, wakeup_swapper;
 #ifdef LOCK_PROFILING
 	uint64_t waittime = 0;
@@ -903,14 +946,48 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
 		 	 * If the lock has exclusive waiters, give them
 			 * preference in order to avoid deadlock with
 			 * shared runners up.
+			 * If interruptible sleeps left the exclusive queue
+			 * empty avoid a starvation for the threads sleeping
+			 * on the shared queue by giving them precedence
+			 * and cleaning up the exclusive waiters bit anyway.
+			 * Please note that the LK_EXSLPFAIL flag may be lying
+			 * about the real presence of waiters with the
+			 * LK_SLEEPFAIL flag on because they may be used in
+			 * conjuction with interruptible sleeps.
 			 */
 			MPASS((x & LK_EXCLUSIVE_SPINNERS) == 0);
-			if (x & LK_EXCLUSIVE_WAITERS) {
-				queue = SQ_EXCLUSIVE_QUEUE;
-				v |= (x & LK_SHARED_WAITERS);
+			realexslp = sleepq_sleepcnt(&lk->lock_object,
+			    SQ_EXCLUSIVE_QUEUE);
+			if ((x & LK_EXCLUSIVE_WAITERS) != 0 && realexslp != 0) {
+				if ((lk->lock_object.lo_flags &
+				    LK_EXSLPFAIL) == 0) {
+					lk->lock_object.lo_flags &=
+					    ~LK_EXSLPFAIL;
+					queue = SQ_EXCLUSIVE_QUEUE;
+					v |= (x & LK_SHARED_WAITERS);
+				} else {
+					lk->lock_object.lo_flags &=
+					    ~LK_EXSLPFAIL;
+					LOCK_LOG2(lk,
+					"%s: %p has only LK_SLEEPFAIL sleepers",
+					    __func__, lk);
+					LOCK_LOG2(lk,
+			"%s: %p waking up threads on the exclusive queue",
+					    __func__, lk);
+					wakeup_swapper =
+					    sleepq_broadcast(&lk->lock_object,
+					    SLEEPQ_LK, 0, SQ_EXCLUSIVE_QUEUE);
+					queue = SQ_SHARED_QUEUE;
+				}
 			} else {
-				MPASS((x & LK_ALL_WAITERS) ==
-				    LK_SHARED_WAITERS);
+
+				/*
+				 * Exclusive waiters sleeping with LK_SLEEPFAIL
+				 * on and using interruptible sleeps/timeout
+				 * may have left spourious LK_EXSLPFAIL flag
+				 * on, so clean it up anyway.
+				 */
+				lk->lock_object.lo_flags &= ~LK_EXSLPFAIL;
 				queue = SQ_SHARED_QUEUE;
 			}
 
@@ -919,7 +996,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
 			    __func__, lk, queue == SQ_SHARED_QUEUE ? "shared" :
 			    "exclusive");
 			atomic_store_rel_ptr(&lk->lk_lock, v);
-			wakeup_swapper = sleepq_broadcast(&lk->lock_object,
+			wakeup_swapper |= sleepq_broadcast(&lk->lock_object,
 			    SLEEPQ_LK, 0, queue);
 			sleepq_release(&lk->lock_object);
 			break;
@@ -976,14 +1053,64 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
 			v = x & (LK_ALL_WAITERS | LK_EXCLUSIVE_SPINNERS);
 			if ((x & ~v) == LK_UNLOCKED) {
 				v = (x & ~LK_EXCLUSIVE_SPINNERS);
+
+				/*
+				 * If interruptible sleeps left the exclusive
+				 * queue empty avoid a starvation for the
+				 * threads sleeping on the shared queue by
+				 * giving them precedence and cleaning up the
+				 * exclusive waiters bit anyway.
+				 * Please note that the LK_EXSLPFAIL flag may
+				 * be lying about the real presence of waiters
+				 * with the LK_SLEEPFAIL flag on because they
+				 * may be used in conjuction with interruptible
+				 * sleeps.
+				 */
 				if (v & LK_EXCLUSIVE_WAITERS) {
 					queue = SQ_EXCLUSIVE_QUEUE;
 					v &= ~LK_EXCLUSIVE_WAITERS;
 				} else {
+
+					/*
+					 * Exclusive waiters sleeping with
+					 * LK_SLEEPFAIL on and using
+					 * interruptible sleeps/timeout may
+					 * have left spourious LK_EXSLPFAIL
+					 * flag on, so clean it up anyway.
+					 */
 					MPASS(v & LK_SHARED_WAITERS);
+					lk->lock_object.lo_flags &=
+					    ~LK_EXSLPFAIL;
 					queue = SQ_SHARED_QUEUE;
 					v &= ~LK_SHARED_WAITERS;
 				}
+				if (queue == SQ_EXCLUSIVE_QUEUE) {
+					realexslp =
+					    sleepq_sleepcnt(&lk->lock_object,
+					    SQ_EXCLUSIVE_QUEUE);
+					if ((lk->lock_object.lo_flags &
+					    LK_EXSLPFAIL) == 0) {
+						lk->lock_object.lo_flags &=
+						    ~LK_EXSLPFAIL;
+						queue = SQ_SHARED_QUEUE;
+						v &= ~LK_SHARED_WAITERS;
+						if (realexslp != 0) {
+							LOCK_LOG2(lk,
+					"%s: %p has only LK_SLEEPFAIL sleepers",
+							    __func__, lk);
+							LOCK_LOG2(lk,
+			"%s: %p waking up threads on the exclusive queue",
+							    __func__, lk);
+							wakeup_swapper =
+							    sleepq_broadcast(
+							    &lk->lock_object,
+							    SLEEPQ_LK, 0,
+							    SQ_EXCLUSIVE_QUEUE);
+						}
+					} else
+						lk->lock_object.lo_flags &=
+						    ~LK_EXSLPFAIL;
+				}
 				if (!atomic_cmpset_ptr(&lk->lk_lock, x, v)) {
 					sleepq_release(&lk->lock_object);
 					continue;
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index b15e669b5e8..0a484a1d05d 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -702,8 +702,12 @@ _sx_xunlock_hard(struct sx *sx, uintptr_t tid, const char *file, int line)
 	 * ideal.  It gives precedence to shared waiters if they are
 	 * present.  For this condition, we have to preserve the
 	 * state of the exclusive waiters flag.
+	 * If interruptible sleeps left the shared queue empty avoid a
+	 * starvation for the threads sleeping on the exclusive queue by giving
+	 * them precedence and cleaning up the shared waiters bit anyway.
 	 */
-	if (sx->sx_lock & SX_LOCK_SHARED_WAITERS) {
+	if ((sx->sx_lock & SX_LOCK_SHARED_WAITERS) != 0 &&
+	    sleepq_sleepcnt(&sx->lock_object, SQ_SHARED_QUEUE) != 0) {
 		queue = SQ_SHARED_QUEUE;
 		x |= (sx->sx_lock & SX_LOCK_EXCLUSIVE_WAITERS);
 	} else
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c
index b3ae6fddc04..a0496bdaad3 100644
--- a/sys/kern/subr_sleepqueue.c
+++ b/sys/kern/subr_sleepqueue.c
@@ -118,6 +118,7 @@ __FBSDID("$FreeBSD$");
  */
 struct sleepqueue {
 	TAILQ_HEAD(, thread) sq_blocked[NR_SLEEPQS];	/* (c) Blocked threads. */
+	u_int sq_blockedcnt[NR_SLEEPQS];	/* (c) N. of blocked threads. */
 	LIST_ENTRY(sleepqueue) sq_hash;		/* (c) Chain and free list. */
 	LIST_HEAD(, sleepqueue) sq_free;	/* (c) Free queues. */
 	void	*sq_wchan;			/* (c) Wait channel. */
@@ -306,9 +307,12 @@ sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags,
 		int i;
 
 		sq = td->td_sleepqueue;
-		for (i = 0; i < NR_SLEEPQS; i++)
+		for (i = 0; i < NR_SLEEPQS; i++) {
 			KASSERT(TAILQ_EMPTY(&sq->sq_blocked[i]),
-				("thread's sleep queue %d is not empty", i));
+			    ("thread's sleep queue %d is not empty", i));
+			KASSERT(sq->sq_blockedcnt[i] == 0,
+			    ("thread's sleep queue %d count mismatches", i));
+		}
 		KASSERT(LIST_EMPTY(&sq->sq_free),
 		    ("thread's sleep queue has a non-empty free list"));
 		KASSERT(sq->sq_wchan == NULL, ("stale sq_wchan pointer"));
@@ -334,6 +338,7 @@ sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags,
 	}
 	thread_lock(td);
 	TAILQ_INSERT_TAIL(&sq->sq_blocked[queue], td, td_slpq);
+	sq->sq_blockedcnt[queue]++;
 	td->td_sleepqueue = NULL;
 	td->td_sqqueue = queue;
 	td->td_wchan = wchan;
@@ -366,6 +371,22 @@ sleepq_set_timeout(void *wchan, int timo)
 	callout_reset_curcpu(&td->td_slpcallout, timo, sleepq_timeout, td);
 }
 
+/*
+ * Return the number of actual sleepers for the specified queue.
+ */
+u_int
+sleepq_sleepcnt(void *wchan, int queue)
+{
+	struct sleepqueue *sq;
+
+	KASSERT(wchan != NULL, ("%s: invalid NULL wait channel", __func__));
+	MPASS((queue >= 0) && (queue < NR_SLEEPQS));
+	sq = sleepq_lookup(wchan);
+	if (sq == NULL)
+		return (0);
+	return (sq->sq_blockedcnt[queue]);
+}
+
 /*
  * Marks the pending sleep of the current thread as interruptible and
  * makes an initial check for pending signals before putting a thread
@@ -665,6 +686,7 @@ sleepq_resume_thread(struct sleepqueue *sq, struct thread *td, int pri)
 	mtx_assert(&sc->sc_lock, MA_OWNED);
 
 	/* Remove the thread from the queue. */
+	sq->sq_blockedcnt[td->td_sqqueue]--;
 	TAILQ_REMOVE(&sq->sq_blocked[td->td_sqqueue], td, td_slpq);
 
 	/*
@@ -720,8 +742,10 @@ sleepq_dtor(void *mem, int size, void *arg)
 	int i;
 
 	sq = mem;
-	for (i = 0; i < NR_SLEEPQS; i++)
+	for (i = 0; i < NR_SLEEPQS; i++) {
 		MPASS(TAILQ_EMPTY(&sq->sq_blocked[i]));
+		MPASS(sq->sq_blockedcnt[i] == 0);
+	}
 }
 #endif
 
@@ -736,8 +760,10 @@ sleepq_init(void *mem, int size, int flags)
 
 	bzero(mem, size);
 	sq = mem;
-	for (i = 0; i < NR_SLEEPQS; i++)
+	for (i = 0; i < NR_SLEEPQS; i++) {
 		TAILQ_INIT(&sq->sq_blocked[i]);
+		sq->sq_blockedcnt[i] = 0;
+	}
 	LIST_INIT(&sq->sq_free);
 	return (0);
 }
@@ -1170,6 +1196,7 @@ found:
 					  td->td_tid, td->td_proc->p_pid,
 					  td->td_name);
 			}
+		db_printf("(expected: %u)\n", sq->sq_blockedcnt[i]);
 	}
 }
 
diff --git a/sys/sys/lockmgr.h b/sys/sys/lockmgr.h
index 545dfa26abd..c85c39bd84c 100644
--- a/sys/sys/lockmgr.h
+++ b/sys/sys/lockmgr.h
@@ -144,6 +144,9 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
 #define	LK_QUIET	0x000020
 #define	LK_ADAPTIVE	0x000040
 
+/* LK_EXSLPFAIL to follow, even if not used in lockinit() */
+#define	LK_EXSLPFAIL	0x000080
+
 /*
  * Additional attributes to be used in lockmgr().
  */
diff --git a/sys/sys/sleepqueue.h b/sys/sys/sleepqueue.h
index 362945aabeb..224d602c01f 100644
--- a/sys/sys/sleepqueue.h
+++ b/sys/sys/sleepqueue.h
@@ -109,6 +109,7 @@ void	sleepq_release(void *wchan);
 void	sleepq_remove(struct thread *td, void *wchan);
 int	sleepq_signal(void *wchan, int flags, int pri, int queue);
 void	sleepq_set_timeout(void *wchan, int timo);
+u_int	sleepq_sleepcnt(void *wchan, int queue);
 int	sleepq_timedwait(void *wchan, int pri);
 int	sleepq_timedwait_sig(void *wchan, int pri);
 void	sleepq_wait(void *wchan, int pri);

From 294a68ca62749137701f6177817f20a8bae3f07f Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Mon, 18 Jan 2010 21:17:03 +0000
Subject: [PATCH 1216/2592] MFC r202085   Simplify pmap_init().  Additionally,
 correct a harmless misbehavior on   i386.

---
 sys/amd64/amd64/pmap.c | 10 ++--------
 sys/i386/i386/locore.s |  2 --
 sys/i386/i386/pmap.c   |  7 ++++---
 3 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 70fc04115b0..b26cc68f751 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -626,7 +626,6 @@ pmap_page_init(vm_page_t m)
 void
 pmap_init(void)
 {
-	pd_entry_t *pd;
 	vm_page_t mpte;
 	vm_size_t s;
 	int i, pv_npg;
@@ -635,18 +634,13 @@ pmap_init(void)
 	 * Initialize the vm page array entries for the kernel pmap's
 	 * page table pages.
 	 */ 
-	pd = pmap_pde(kernel_pmap, KERNBASE);
 	for (i = 0; i < NKPT; i++) {
-		if ((pd[i] & (PG_PS | PG_V)) == (PG_PS | PG_V))
-			continue;
-		KASSERT((pd[i] & PG_V) != 0,
-		    ("pmap_init: page table page is missing"));
-		mpte = PHYS_TO_VM_PAGE(pd[i] & PG_FRAME);
+		mpte = PHYS_TO_VM_PAGE(KPTphys + (i << PAGE_SHIFT));
 		KASSERT(mpte >= vm_page_array &&
 		    mpte < &vm_page_array[vm_page_array_size],
 		    ("pmap_init: page table page is out of range"));
 		mpte->pindex = pmap_pde_pindex(KERNBASE) + i;
-		mpte->phys_addr = pd[i] & PG_FRAME;
+		mpte->phys_addr = KPTphys + (i << PAGE_SHIFT);
 	}
 
 	/*
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 94ac6702171..11cb09ad748 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -104,9 +104,7 @@ IdlePTD:	.long	0		/* phys addr of kernel PTD */
 IdlePDPT:	.long	0		/* phys addr of kernel PDPT */
 #endif
 
-#ifdef SMP
 	.globl	KPTphys
-#endif
 KPTphys:	.long	0		/* phys addr of kernel page tables */
 
 	.globl	proc0kstack
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 2a8bb1111c1..d6f5be572dd 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -206,6 +206,7 @@ int pseflag = 0;		/* PG_PS or-in */
 static int nkpt;
 vm_offset_t kernel_vm_end;
 extern u_int32_t KERNend;
+extern u_int32_t KPTphys;
 
 #ifdef PAE
 pt_entry_t pg_nx;
@@ -649,13 +650,13 @@ pmap_init(void)
 	 * Initialize the vm page array entries for the kernel pmap's
 	 * page table pages.
 	 */ 
-	for (i = 0; i < nkpt; i++) {
-		mpte = PHYS_TO_VM_PAGE(PTD[i + KPTDI] & PG_FRAME);
+	for (i = 0; i < NKPT; i++) {
+		mpte = PHYS_TO_VM_PAGE(KPTphys + (i << PAGE_SHIFT));
 		KASSERT(mpte >= vm_page_array &&
 		    mpte < &vm_page_array[vm_page_array_size],
 		    ("pmap_init: page table page is out of range"));
 		mpte->pindex = i + KPTDI;
-		mpte->phys_addr = PTD[i + KPTDI] & PG_FRAME;
+		mpte->phys_addr = KPTphys + (i << PAGE_SHIFT);
 	}
 
 	/*

From 92d8dadcf8bf80751c6f7135592652e9f8f86256 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 12:58:29 +0000
Subject: [PATCH 1217/2592] MFC r201139: Add BIO_DELETE support to ada(4): -
 For SSDs use TRIM feature of DATA SET MANAGEMENT command, as defined by ACS-2
 specification working draft. - For CompactFlash use CFA ERASE command, same
 as ad(4) does.

With this patch, `newfs -E /dev/ada1` was able to restore write speed of
my heavily weared OCZ Vertex SSD (firmware 1.4) up to the initial level
for the most part of it's capacity.

I have no idea whether it is normal, but for some reason it takes 200ms
to handle any TRIM command on this drive, that was making delete extremely
slow. But TRIM command is able to accept long list of LBAs and the length of
that list seems doesn't affect it's execution time. Implemented request
clusting algorithm allowed me to rise delete rate up to reasonable numbers,
when many parallel DELETE requests running.
---
 sys/cam/ata/ata_all.c |   8 +-
 sys/cam/ata/ata_da.c  | 352 +++++++++++++++++++++++++++++-------------
 sys/geom/geom_dev.c   |   4 +-
 sys/sys/ata.h         |  14 +-
 4 files changed, 261 insertions(+), 117 deletions(-)

diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c
index c433f02b114..25daea4eb7f 100644
--- a/sys/cam/ata/ata_all.c
+++ b/sys/cam/ata/ata_all.c
@@ -75,6 +75,11 @@ ata_op_string(struct ata_cmd *cmd)
 	switch (cmd->command) {
 	case 0x00: return ("NOP");
 	case 0x03: return ("CFA_REQUEST_EXTENDED_ERROR");
+	case 0x06:
+		switch (cmd->features) {
+	        case 0x01: return ("DSM TRIM");
+	        }
+	        return "DSM";
 	case 0x08: return ("DEVICE_RESET");
 	case 0x20: return ("READ");
 	case 0x24: return ("READ48");
@@ -338,7 +343,8 @@ ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features,
 	    cmd == ATA_WRITE_DMA_FUA48 ||
 	    cmd == ATA_WRITE_DMA_QUEUED48 ||
 	    cmd == ATA_WRITE_DMA_QUEUED_FUA48 ||
-	    cmd == ATA_WRITE_STREAM_DMA48)
+	    cmd == ATA_WRITE_STREAM_DMA48 ||
+	    cmd == ATA_DATA_SET_MANAGEMENT)
 		ataio->cmd.flags |= CAM_ATAIO_DMA;
 	ataio->cmd.command = cmd;
 	ataio->cmd.features = features;
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 204efe24f99..8d493096bff 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -74,8 +74,10 @@ typedef enum {
 	ADA_FLAG_CAN_DMA	= 0x010,
 	ADA_FLAG_NEED_OTAG	= 0x020,
 	ADA_FLAG_WENT_IDLE	= 0x040,
+	ADA_FLAG_CAN_TRIM	= 0x080,
 	ADA_FLAG_OPEN		= 0x100,
-	ADA_FLAG_SCTX_INIT	= 0x200
+	ADA_FLAG_SCTX_INIT	= 0x200,
+	ADA_FLAG_CAN_CFA        = 0x400
 } ada_flags;
 
 typedef enum {
@@ -86,6 +88,7 @@ typedef enum {
 	ADA_CCB_BUFFER_IO	= 0x03,
 	ADA_CCB_WAITING		= 0x04,
 	ADA_CCB_DUMP		= 0x05,
+	ADA_CCB_TRIM		= 0x06,
 	ADA_CCB_TYPE_MASK	= 0x0F,
 } ada_ccb_state;
 
@@ -101,13 +104,23 @@ struct disk_params {
 	u_int64_t sectors;	/* Total number sectors */
 };
 
+#define TRIM_MAX_BLOCKS	4
+#define TRIM_MAX_RANGES	TRIM_MAX_BLOCKS * 64
+struct trim_request {
+	uint8_t		data[TRIM_MAX_RANGES * 8];
+	struct bio	*bps[TRIM_MAX_RANGES];
+};
+
 struct ada_softc {
 	struct	 bio_queue_head bio_queue;
+	struct	 bio_queue_head trim_queue;
 	ada_state state;
 	ada_flags flags;	
 	ada_quirks quirks;
 	int	 ordered_tag_count;
 	int	 outstanding_cmds;
+	int	 trim_max_ranges;
+	int	 trim_running;
 	struct	 disk_params params;
 	struct	 disk *disk;
 	union	 ccb saved_ccb;
@@ -115,6 +128,7 @@ struct ada_softc {
 	struct sysctl_ctx_list	sysctl_ctx;
 	struct sysctl_oid	*sysctl_tree;
 	struct callout		sendordered_c;
+	struct trim_request	trim_req;
 };
 
 struct ada_quirk_entry {
@@ -309,6 +323,18 @@ adaclose(struct disk *dp)
 	return (0);	
 }
 
+static void
+adaschedule(struct cam_periph *periph)
+{
+	struct ada_softc *softc = (struct ada_softc *)periph->softc;
+
+	if (bioq_first(&softc->bio_queue) ||
+	    (!softc->trim_running && bioq_first(&softc->trim_queue))) {
+		/* Have more work to do, so ensure we stay scheduled */
+		xpt_schedule(periph, CAM_PRIORITY_NORMAL);
+	}
+}
+
 /*
  * Actually translate the requested transfer into one the physical driver
  * can understand.  The transfer is described by a buf and will include
@@ -341,12 +367,16 @@ adastrategy(struct bio *bp)
 	/*
 	 * Place it in the queue of disk activities for this disk
 	 */
-	bioq_disksort(&softc->bio_queue, bp);
+	if (bp->bio_cmd == BIO_DELETE &&
+	    (softc->flags & ADA_FLAG_CAN_TRIM))
+		bioq_disksort(&softc->trim_queue, bp);
+	else
+		bioq_disksort(&softc->bio_queue, bp);
 
 	/*
 	 * Schedule ourselves for performing the work.
 	 */
-	xpt_schedule(periph, CAM_PRIORITY_NORMAL);
+	adaschedule(periph);
 	cam_periph_unlock(periph);
 
 	return;
@@ -485,6 +515,7 @@ adaoninvalidate(struct cam_periph *periph)
 	 *     with XPT_ABORT_CCB.
 	 */
 	bioq_flush(&softc->bio_queue, NULL, ENXIO);
+	bioq_flush(&softc->trim_queue, NULL, ENXIO);
 
 	disk_gone(softc->disk);
 	xpt_print(periph->path, "lost device\n");
@@ -618,6 +649,7 @@ adaregister(struct cam_periph *periph, void *arg)
 	}
 
 	bioq_init(&softc->bio_queue);
+	bioq_init(&softc->trim_queue);
 
 	if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA)
 		softc->flags |= ADA_FLAG_CAN_DMA;
@@ -628,6 +660,17 @@ adaregister(struct cam_periph *periph, void *arg)
 	if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
 	    cgd->inq_flags & SID_CmdQue)
 		softc->flags |= ADA_FLAG_CAN_NCQ;
+	if (cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) {
+		softc->flags |= ADA_FLAG_CAN_TRIM;
+		softc->trim_max_ranges = TRIM_MAX_RANGES;
+		if (cgd->ident_data.max_dsm_blocks != 0) {
+			softc->trim_max_ranges =
+			    min(cgd->ident_data.max_dsm_blocks * 64,
+				softc->trim_max_ranges);
+		}
+	}
+	if (cgd->ident_data.support.command2 & ATA_SUPPORT_CFA)
+		softc->flags |= ADA_FLAG_CAN_CFA;
 	softc->state = ADA_STATE_NORMAL;
 
 	periph->softc = softc;
@@ -672,7 +715,7 @@ adaregister(struct cam_periph *periph, void *arg)
 		maxio = DFLTPHYS;	/* traditional default */
 	else if (maxio > MAXPHYS)
 		maxio = MAXPHYS;	/* for safety */
-	if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48)
+	if (softc->flags & ADA_FLAG_CAN_48BIT)
 		maxio = min(maxio, 65536 * softc->params.secsize);
 	else					/* 28bit ATA command limit */
 		maxio = min(maxio, 256 * softc->params.secsize);
@@ -681,6 +724,10 @@ 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;
+	if ((softc->flags & ADA_FLAG_CAN_TRIM) ||
+	    ((softc->flags & ADA_FLAG_CAN_CFA) &&
+	    !(softc->flags & ADA_FLAG_CAN_48BIT)))
+		softc->disk->d_flags |= DISKFLAG_CANDELETE;
 	strlcpy(softc->disk->d_ident, cgd->serial_num,
 	    MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1));
 
@@ -743,13 +790,10 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 	switch (softc->state) {
 	case ADA_STATE_NORMAL:
 	{
-		/* Pull a buffer from the queue and get going on it */		
 		struct bio *bp;
+		u_int8_t tag_code;
 
-		/*
-		 * See if there is a buf with work for us to do..
-		 */
-		bp = bioq_first(&softc->bio_queue);
+		/* Execute immediate CCB if waiting. */
 		if (periph->immediate_priority <= periph->pinfo.priority) {
 			CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
 					("queuing for immediate ccb\n"));
@@ -758,115 +802,188 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
 					  periph_links.sle);
 			periph->immediate_priority = CAM_PRIORITY_NONE;
 			wakeup(&periph->ccb_list);
-		} else if (bp == NULL) {
+			/* Have more work to do, so ensure we stay scheduled */
+			adaschedule(periph);
+			break;
+		}
+		/* Run TRIM if not running yet. */
+		if (!softc->trim_running &&
+		    (bp = bioq_first(&softc->trim_queue)) != 0) {
+			struct trim_request *req = &softc->trim_req;
+			struct bio *bp1;
+			int bps = 0, ranges = 0;
+
+			softc->trim_running = 1;
+			bzero(req, sizeof(*req));
+			bp1 = bp;
+			do {
+				uint64_t lba = bp1->bio_pblkno;
+				int count = bp1->bio_bcount /
+				    softc->params.secsize;
+
+				bioq_remove(&softc->trim_queue, bp1);
+				while (count > 0) {
+					int c = min(count, 0xffff);
+					int off = ranges * 8;
+
+					req->data[off + 0] = lba & 0xff;
+					req->data[off + 1] = (lba >> 8) & 0xff;
+					req->data[off + 2] = (lba >> 16) & 0xff;
+					req->data[off + 3] = (lba >> 24) & 0xff;
+					req->data[off + 4] = (lba >> 32) & 0xff;
+					req->data[off + 5] = (lba >> 40) & 0xff;
+					req->data[off + 6] = c & 0xff;
+					req->data[off + 7] = (c >> 8) & 0xff;
+					lba += c;
+					count -= c;
+					ranges++;
+				}
+				req->bps[bps++] = bp1;
+				bp1 = bioq_first(&softc->trim_queue);
+				if (bp1 == NULL ||
+				    bp1->bio_bcount / softc->params.secsize >
+				    (softc->trim_max_ranges - ranges) * 0xffff)
+					break;
+			} while (1);
+			cam_fill_ataio(ataio,
+			    ada_retry_count,
+			    adadone,
+			    CAM_DIR_OUT,
+			    0,
+			    req->data,
+			    ((ranges + 63) / 64) * 512,
+			    ada_default_timeout * 1000);
+			ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT,
+			    ATA_DSM_TRIM, 0, (ranges + 63) / 64);
+			start_ccb->ccb_h.ccb_state = ADA_CCB_TRIM;
+			goto out;
+		}
+		/* Run regular command. */
+		bp = bioq_first(&softc->bio_queue);
+		if (bp == NULL) {
 			xpt_release_ccb(start_ccb);
+			break;
+		}
+		bioq_remove(&softc->bio_queue, bp);
+
+		if ((softc->flags & ADA_FLAG_NEED_OTAG) != 0) {
+			softc->flags &= ~ADA_FLAG_NEED_OTAG;
+			softc->ordered_tag_count++;
+			tag_code = 0;
 		} else {
-			u_int8_t tag_code;
+			tag_code = 1;
+		}
+		switch (bp->bio_cmd) {
+		case BIO_READ:
+		case BIO_WRITE:
+		{
+			uint64_t lba = bp->bio_pblkno;
+			uint16_t count = bp->bio_bcount / softc->params.secsize;
 
-			bioq_remove(&softc->bio_queue, bp);
+			cam_fill_ataio(ataio,
+			    ada_retry_count,
+			    adadone,
+			    bp->bio_cmd == BIO_READ ?
+			        CAM_DIR_IN : CAM_DIR_OUT,
+			    tag_code,
+			    bp->bio_data,
+			    bp->bio_bcount,
+			    ada_default_timeout*1000);
 
-			if ((softc->flags & ADA_FLAG_NEED_OTAG) != 0) {
-				softc->flags &= ~ADA_FLAG_NEED_OTAG;
-				softc->ordered_tag_count++;
-				tag_code = 0;
-			} else {
-				tag_code = 1;
-			}
-			switch (bp->bio_cmd) {
-			case BIO_READ:
-			case BIO_WRITE:
-			{
-				uint64_t lba = bp->bio_pblkno;
-				uint16_t count = bp->bio_bcount / softc->params.secsize;
-
-				cam_fill_ataio(ataio,
-				    ada_retry_count,
-				    adadone,
-				    bp->bio_cmd == BIO_READ ?
-				        CAM_DIR_IN : CAM_DIR_OUT,
-				    tag_code,
-				    bp->bio_data,
-				    bp->bio_bcount,
-				    ada_default_timeout*1000);
-
-				if ((softc->flags & ADA_FLAG_CAN_NCQ) && tag_code) {
+			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);
+				} else {
+					ata_ncq_cmd(ataio, ATA_WRITE_FPDMA_QUEUED,
+					    lba, count);
+				}
+			} else if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
+			    (lba + count >= ATA_MAX_28BIT_LBA ||
+			    count > 256)) {
+				if (softc->flags & ADA_FLAG_CAN_DMA) {
 					if (bp->bio_cmd == BIO_READ) {
-						ata_ncq_cmd(ataio, ATA_READ_FPDMA_QUEUED,
-						    lba, count);
+						ata_48bit_cmd(ataio, ATA_READ_DMA48,
+						    0, lba, count);
 					} else {
-						ata_ncq_cmd(ataio, ATA_WRITE_FPDMA_QUEUED,
-						    lba, count);
-					}
-				} else if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
-				    (lba + count >= ATA_MAX_28BIT_LBA ||
-				    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 {
-						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);
-						}
+						ata_48bit_cmd(ataio, ATA_WRITE_DMA48,
+						    0, lba, count);
 					}
 				} else {
-					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);
-						}
+					if (bp->bio_cmd == BIO_READ) {
+						ata_48bit_cmd(ataio, ATA_READ_MUL48,
+						    0, lba, count);
 					} else {
-						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);
-						}
+						ata_48bit_cmd(ataio, ATA_WRITE_MUL48,
+						    0, lba, count);
+					}
+				}
+			} else {
+				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 {
+					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);
 					}
 				}
 			}
-				break;
-			case BIO_FLUSH:
-				cam_fill_ataio(ataio,
-				    1,
-				    adadone,
-				    CAM_DIR_NONE,
-				    0,
-				    NULL,
-				    0,
-				    ada_default_timeout*1000);
+			break;
+		}
+		case BIO_DELETE:
+		{
+			uint64_t lba = bp->bio_pblkno;
+			uint16_t count = bp->bio_bcount / softc->params.secsize;
 
-				if (softc->flags & ADA_FLAG_CAN_48BIT)
-					ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0);
-				else
-					ata_28bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0);
-				break;
-			}
-			start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO;
-			start_ccb->ccb_h.ccb_bp = bp;
-			softc->outstanding_cmds++;
-			xpt_action(start_ccb);
-			bp = bioq_first(&softc->bio_queue);
+			cam_fill_ataio(ataio,
+			    ada_retry_count,
+			    adadone,
+			    CAM_DIR_NONE,
+			    0,
+			    NULL,
+			    0,
+			    ada_default_timeout*1000);
+
+			if (count >= 256)
+				count = 0;
+			ata_28bit_cmd(ataio, ATA_CFA_ERASE, 0, lba, count);
+			break;
 		}
-		
-		if (bp != NULL) {
-			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
+		case BIO_FLUSH:
+			cam_fill_ataio(ataio,
+			    1,
+			    adadone,
+			    CAM_DIR_NONE,
+			    0,
+			    NULL,
+			    0,
+			    ada_default_timeout*1000);
+
+			if (softc->flags & ADA_FLAG_CAN_48BIT)
+				ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0);
+			else
+				ata_28bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0);
+			break;
 		}
+		start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO;
+out:
+		start_ccb->ccb_h.ccb_bp = bp;
+		softc->outstanding_cmds++;
+		xpt_action(start_ccb);
+
+		/* May have more work to do, so ensure we stay scheduled */
+		adaschedule(periph);
 		break;
 	}
 	}
@@ -882,6 +999,7 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
 	ataio = &done_ccb->ataio;
 	switch (ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) {
 	case ADA_CCB_BUFFER_IO:
+	case ADA_CCB_TRIM:
 	{
 		struct bio *bp;
 
@@ -908,13 +1026,6 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
 					    "Invalidating pack\n");
 					softc->flags |= ADA_FLAG_PACK_INVALID;
 				}
-
-				/*
-				 * return all queued I/O with EIO, so that
-				 * the client can retry these I/Os in the
-				 * proper order should it attempt to recover.
-				 */
-				bioq_flush(&softc->bio_queue, NULL, EIO);
 				bp->bio_error = error;
 				bp->bio_resid = bp->bio_bcount;
 				bp->bio_flags |= BIO_ERROR;
@@ -940,8 +1051,27 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
 		softc->outstanding_cmds--;
 		if (softc->outstanding_cmds == 0)
 			softc->flags |= ADA_FLAG_WENT_IDLE;
+		if ((ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) ==
+		    ADA_CCB_TRIM) {
+			struct trim_request *req =
+			    (struct trim_request *)ataio->data_ptr;
+			int i;
 
-		biodone(bp);
+			for (i = 1; i < softc->trim_max_ranges &&
+			    req->bps[i]; i++) {
+				struct bio *bp1 = req->bps[i];
+				
+				bp1->bio_resid = bp->bio_resid;
+				bp1->bio_error = bp->bio_error;
+				if (bp->bio_flags & BIO_ERROR)
+					bp1->bio_flags |= BIO_ERROR;
+				biodone(bp1);
+			}
+			softc->trim_running = 0;
+			biodone(bp);
+			adaschedule(periph);
+		} else
+			biodone(bp);
 		break;
 	}
 	case ADA_CCB_WAITING:
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index af05618f163..b2d9d3b94fb 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -299,8 +299,8 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread
 		}
 		while (length > 0) { 
 			chunk = length;
-			if (chunk > 1024 * cp->provider->sectorsize)
-				chunk = 1024 * cp->provider->sectorsize;
+			if (chunk > 65536 * cp->provider->sectorsize)
+				chunk = 65536 * cp->provider->sectorsize;
 			error = g_delete_data(cp, offset, chunk);
 			length -= chunk;
 			offset += chunk;
diff --git a/sys/sys/ata.h b/sys/sys/ata.h
index 91afb529b28..fab5e387ab2 100644
--- a/sys/sys/ata.h
+++ b/sys/sys/ata.h
@@ -101,7 +101,9 @@ struct ata_params {
 /*066*/ u_int16_t       mwdmarec;               /* rec. M/W DMA time ns */
 /*067*/ u_int16_t       pioblind;               /* min. PIO cycle w/o flow */
 /*068*/ u_int16_t       pioiordy;               /* min. PIO cycle IORDY flow */
-	u_int16_t       reserved69;
+/*069*/ u_int16_t       support3;
+#define ATA_SUPPORT_RZAT                0x0020
+#define ATA_SUPPORT_DRAT                0x4000
 	u_int16_t       reserved70;
 /*071*/ u_int16_t       rlsovlap;               /* rel time (us) for overlap */
 /*072*/ u_int16_t       rlsservice;             /* rel time (us) for service */
@@ -204,7 +206,8 @@ struct ata_params {
 	u_int16_t       lba_size48_2;
 	u_int16_t       lba_size48_3;
 	u_int16_t       lba_size48_4;
-	u_int16_t       reserved104[2];
+	u_int16_t       reserved104;
+/*105*/	u_int16_t       max_dsm_blocks;
 /*106*/	u_int16_t       pss;
 #define ATA_PSS_LSPPS			0x000F
 #define ATA_PSS_LSSABOVE512		0x1000
@@ -230,7 +233,10 @@ struct ata_params {
 /*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];
+	u_int16_t       reserved165[4];
+/*169*/	u_int16_t       support_dsm;
+#define ATA_SUPPORT_DSM_TRIM		0x0001
+	u_int16_t       reserved170[6];
 /*176*/ u_int8_t        media_serial[60];
 /*206*/ u_int16_t       sct;
 	u_int16_t       reserved206[2];
@@ -284,6 +290,8 @@ struct ata_params {
 #define ATA_NOP                         0x00    /* NOP */
 #define         ATA_NF_FLUSHQUEUE       0x00    /* flush queued cmd's */
 #define         ATA_NF_AUTOPOLL         0x01    /* start autopoll function */
+#define ATA_DATA_SET_MANAGEMENT		0x06
+#define 	ATA_DSM_TRIM		0x01
 #define ATA_DEVICE_RESET                0x08    /* reset device */
 #define ATA_READ                        0x20    /* read */
 #define ATA_READ48                      0x24    /* read 48bit LBA */

From b136f43d4477635afa0c339e60dc4608ea667689 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 13:00:33 +0000
Subject: [PATCH 1218/2592] MFC r201990: - Report SATA in legacy emulation mode
 still as SATA. - Make ATA XPT able to handle such case.

---
 sys/cam/ata/ata_xpt.c | 29 +++++++++++++----------------
 sys/dev/ata/ata-all.c |  8 +++-----
 2 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index f3f90af1dbd..99cf3141083 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -1001,7 +1001,6 @@ typedef struct {
 	union	ccb *request_ccb;
 	struct 	ccb_pathinq *cpi;
 	int	counter;
-	int	found;
 } ata_scan_bus_info;
 
 /*
@@ -1049,14 +1048,11 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
 		}
 		scan_info->request_ccb = request_ccb;
 		scan_info->cpi = &work_ccb->cpi;
-		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)
-			scan_info->counter = 15;
+			scan_info->counter = scan_info->cpi->max_target;
+		else
+			scan_info->counter = 0;
 
 		work_ccb = xpt_alloc_ccb_nowait();
 		if (work_ccb == NULL) {
@@ -1073,10 +1069,11 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
 		/* Free the current request path- we're done with it. */
 		xpt_free_path(work_ccb->ccb_h.path);
 		/* If there is PMP... */
-		if (scan_info->counter == 15) {
+		if ((scan_info->cpi->hba_inquiry & PI_SATAPM) &&
+		    (scan_info->counter == scan_info->cpi->max_target)) {
 			if (work_ccb->ccb_h.ppriv_field1 != 0) {
 				/* everything else willbe probed by it */
-				scan_info->found = 0x8000;
+				goto done;
 			} else {
 				struct ccb_trans_settings cts;
 
@@ -1091,11 +1088,10 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
 				xpt_action((union ccb *)&cts);
 			}
 		}
-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 -
-		    ((scan_info->cpi->hba_inquiry & PI_SATAPM) ? 1 : 0)) {
+		if (scan_info->counter ==
+		    ((scan_info->cpi->hba_inquiry & PI_SATAPM) ?
+		    0 : scan_info->cpi->max_target)) {
+done:
 			xpt_free_ccb(work_ccb);
 			xpt_free_ccb((union ccb *)scan_info->cpi);
 			request_ccb = scan_info->request_ccb;
@@ -1104,9 +1100,10 @@ take_next:
 			xpt_done(request_ccb);
 			break;
 		}
+		/* Take next device. Wrap from max (PMP) to 0. */
+		scan_info->counter = (scan_info->counter + 1 ) %
+		    (scan_info->cpi->max_target + 1);
 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);
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 6bbff47a945..f342c819ef1 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -1473,7 +1473,7 @@ ataaction(struct cam_sim *sim, union ccb *ccb)
 			d = &ch->curr[ccb->ccb_h.target_id];
 		else
 			d = &ch->user[ccb->ccb_h.target_id];
-		if ((ch->flags & ATA_SATA) && (ch->flags & ATA_NO_SLAVE)) {
+		if (ch->flags & ATA_SATA) {
 			if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION)
 				d->revision = cts->xport_specific.sata.revision;
 			if (cts->xport_specific.ata.valid & CTS_SATA_VALID_MODE) {
@@ -1497,8 +1497,6 @@ ataaction(struct cam_sim *sim, union ccb *ccb)
 			}
 			if (cts->xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)
 				d->bytecount = cts->xport_specific.ata.bytecount;
-			if (ch->flags & ATA_SATA)
-				d->bytecount = min(8192, d->bytecount);
 		}
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
@@ -1515,7 +1513,7 @@ ataaction(struct cam_sim *sim, union ccb *ccb)
 			d = &ch->user[ccb->ccb_h.target_id];
 		cts->protocol = PROTO_ATA;
 		cts->protocol_version = PROTO_VERSION_UNSPECIFIED;
-		if ((ch->flags & ATA_SATA) && (ch->flags & ATA_NO_SLAVE)) {
+		if (ch->flags & ATA_SATA) {
 			cts->transport = XPORT_SATA;
 			cts->transport_version = XPORT_VERSION_UNSPECIFIED;
 			cts->xport_specific.sata.mode = d->mode;
@@ -1604,7 +1602,7 @@ ataaction(struct cam_sim *sim, union ccb *ccb)
 		strncpy(cpi->hba_vid, "ATA", HBA_IDLEN);
 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 		cpi->unit_number = cam_sim_unit(sim);
-		if ((ch->flags & ATA_SATA) && (ch->flags & ATA_NO_SLAVE))
+		if (ch->flags & ATA_SATA)
 			cpi->transport = XPORT_SATA;
 		else
 			cpi->transport = XPORT_ATA;

From 928e4114fe5fe555ed695bae56599c33cfa1cd80 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 13:07:25 +0000
Subject: [PATCH 1219/2592] MFC r200655: Serverworks OSB4 has no 0x4a (piomode)
 register, do not touch it. Also OSB4 has some problems with UDMA transfers,
 limit it to WDMA2.

---
 sys/dev/ata/chipsets/ata-serverworks.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sys/dev/ata/chipsets/ata-serverworks.c b/sys/dev/ata/chipsets/ata-serverworks.c
index b5a3fc2e532..033d985157d 100644
--- a/sys/dev/ata/chipsets/ata-serverworks.c
+++ b/sys/dev/ata/chipsets/ata-serverworks.c
@@ -80,7 +80,7 @@ ata_serverworks_probe(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
     static struct ata_chip_id ids[] =
-    {{ ATA_ROSB4,     0x00, SWKS_33,  0, ATA_UDMA2, "ROSB4" },
+    {{ ATA_ROSB4,     0x00, SWKS_33,  0, ATA_WDMA2, "ROSB4" },
      { ATA_CSB5,      0x92, SWKS_100, 0, ATA_UDMA5, "CSB5" },
      { ATA_CSB5,      0x00, SWKS_66,  0, ATA_UDMA4, "CSB5" },
      { ATA_CSB6,      0x00, SWKS_100, 0, ATA_UDMA5, "CSB6" },
@@ -388,10 +388,12 @@ ata_serverworks_setmode(device_t dev, int target, int mode)
 	    piomode = mode;
 	}
 	/* Set PIO mode and timings, calculated above. */
-	pci_write_config(parent, 0x4a,
+	if (ctlr->chip->cfg1 != SWKS_33) {
+		pci_write_config(parent, 0x4a,
 			 (pci_read_config(parent, 0x4a, 2) &
 			  ~(0xf << (devno << 2))) |
 			 ((piomode - ATA_PIO0) << (devno<<2)),2);
+	}
 	pci_write_config(parent, 0x40, 
 			 (pci_read_config(parent, 0x40, 4) &
 			  ~(0xff << offset)) |

From 1c2e876f53c3822550749f66203f4a7a1ef3aad4 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 13:21:25 +0000
Subject: [PATCH 1220/2592] MFC r200753: Fairly set master/slave shared
 PIO/WDMA timings on ITE 821x controllers. Previous implementation could only
 limit mode, but not rise it back.

---
 sys/dev/ata/chipsets/ata-ite.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/sys/dev/ata/chipsets/ata-ite.c b/sys/dev/ata/chipsets/ata-ite.c
index f8bc57dff9b..8c0a2c598f6 100644
--- a/sys/dev/ata/chipsets/ata-ite.c
+++ b/sys/dev/ata/chipsets/ata-ite.c
@@ -105,6 +105,8 @@ ata_ite_chipinit(device_t dev)
 	pci_write_config(dev, 0x56, 0x31, 1);
 
 	ctlr->setmode = ata_ite_821x_setmode;
+	/* No timing restrictions initally. */
+	ctlr->chipset_data = (void *)0;
     }
     ctlr->ch_attach = ata_ite_ch_attach;
     return 0;
@@ -129,6 +131,7 @@ ata_ite_821x_setmode(device_t dev, int target, int mode)
 	struct ata_channel *ch = device_get_softc(dev);
 	int devno = (ch->unit << 1) + target;
 	int piomode;
+	uint8_t *timings = (uint8_t*)(&ctlr->chipset_data);
 	u_int8_t udmatiming[] =
 		{ 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 };
 	u_int8_t chtiming[] =
@@ -158,11 +161,10 @@ ata_ite_821x_setmode(device_t dev, int target, int mode)
 			     (1 << (devno + 3)), 1);
 		piomode = mode;
 	}
+	timings[devno] = chtiming[ata_mode2idx(piomode)];
 	/* set active and recover timing (shared between master & slave) */
-	if (pci_read_config(parent, 0x54 + (ch->unit << 2), 1) <
-	    chtiming[ata_mode2idx(piomode)])
-		pci_write_config(parent, 0x54 + (ch->unit << 2),
-				 chtiming[ata_mode2idx(piomode)], 1);
+	pci_write_config(parent, 0x54 + (ch->unit << 2),
+	    max(timings[ch->unit << 1], timings[(ch->unit << 1) + 1]), 1);
 	return (mode);
 }
 

From f59a7ba7ba323fde7b173e9db16acf70538793c5 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 13:24:11 +0000
Subject: [PATCH 1221/2592] MFC r200754: Add VIA CX700/VX800 chipsets SATA/PATA
 support.

PR:             kern/121521
---
 sys/dev/ata/ata-pci.h          |  5 +++
 sys/dev/ata/chipsets/ata-via.c | 63 ++++++++++++++++++++++++++++++----
 2 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index 7bfb7a25990..25e0588a860 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -482,6 +482,11 @@ struct ata_pci_controller {
 #define ATA_VIA6410             0x31641106
 #define ATA_VIA6420             0x31491106
 #define ATA_VIA6421             0x32491106
+#define ATA_VIACX700IDE         0x05811106
+#define ATA_VIACX700            0x83241106
+#define ATA_VIASATAIDE          0x53241106
+#define ATA_VIAVX800            0x83531106
+#define ATA_VIAVX855            0x84091106
 
 /* global prototypes ata-pci.c */
 int ata_pci_probe(device_t dev);
diff --git a/sys/dev/ata/chipsets/ata-via.c b/sys/dev/ata/chipsets/ata-via.c
index 9aea45d9a9f..ec22020a0e7 100644
--- a/sys/dev/ata/chipsets/ata-via.c
+++ b/sys/dev/ata/chipsets/ata-via.c
@@ -59,6 +59,9 @@ static void ata_via_reset(device_t dev);
 static int ata_via_old_setmode(device_t dev, int target, int mode);
 static void ata_via_southbridge_fixup(device_t dev);
 static int ata_via_new_setmode(device_t dev, int target, int mode);
+static int ata_via_sata_ch_attach(device_t dev);
+static int ata_via_sata_getrev(device_t dev, int target);
+static int ata_via_sata_setmode(device_t dev, int target, int mode);
 
 /* misc defines */
 #define VIA33           0
@@ -70,6 +73,7 @@ static int ata_via_new_setmode(device_t dev, int target, int mode);
 #define VIABUG          0x02
 #define VIABAR          0x04
 #define VIAAHCI         0x08
+#define VIASATA         0x10
 
 
 /*
@@ -98,6 +102,9 @@ ata_via_probe(device_t dev)
      { 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" },
+     { ATA_VIACX700,  0x00, VIA133, VIASATA, ATA_SA150, "CX700" },
+     { ATA_VIAVX800,  0x00, VIA133, VIASATA, ATA_SA150, "VX800" },
+     { ATA_VIAVX855,  0x00, VIA133, 0x00,    ATA_UDMA6, "VX855" },
      { 0, 0, 0, 0, 0, 0 }};
     static struct ata_chip_id new_ids[] =
     {{ ATA_VIA6410,   0x00, 0,      0x00,    ATA_UDMA6, "6410" },
@@ -113,7 +120,9 @@ ata_via_probe(device_t dev)
     if (pci_get_vendor(dev) != ATA_VIA_ID)
 	return ENXIO;
 
-    if (pci_get_devid(dev) == ATA_VIA82C571) {
+    if (pci_get_devid(dev) == ATA_VIA82C571 ||
+	pci_get_devid(dev) == ATA_VIACX700IDE ||
+	pci_get_devid(dev) == ATA_VIASATAIDE) {
 	if (!(ctlr->chip = ata_find_chip(dev, ids, -99))) 
 	    return ENXIO;
     }
@@ -134,12 +143,21 @@ ata_via_chipinit(device_t dev)
 
     if (ata_setup_interrupt(dev, ata_generic_intr))
 	return ENXIO;
-    
-    if (ctlr->chip->max_dma >= ATA_SA150) {
-	/* do we have AHCI capability ? */
-	if ((ctlr->chip->cfg2 == VIAAHCI) && ata_ahci_chipinit(dev) != ENXIO)
-	    return 0;
 
+    /* AHCI SATA */
+    if (ctlr->chip->cfg2 & VIAAHCI) {
+	if (ata_ahci_chipinit(dev) != ENXIO)
+	    return (0);
+    }
+    /* 2 SATA without SATA registers on first channel + 1 PATA on second */
+    if (ctlr->chip->cfg2 & VIASATA) {
+	ctlr->ch_attach = ata_via_sata_ch_attach;
+	ctlr->setmode = ata_via_sata_setmode;
+	ctlr->getrev = ata_via_sata_getrev;
+	return 0;
+    }
+    /* Legacy SATA/SATA+PATA with SATA registers in BAR(5). */
+    if (ctlr->chip->max_dma >= ATA_SA150) {
 	ctlr->r_type2 = SYS_RES_IOPORT;
 	ctlr->r_rid2 = PCIR_BAR(5);
 	if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
@@ -148,7 +166,6 @@ ata_via_chipinit(device_t dev)
 	    ctlr->ch_detach = ata_via_ch_detach;
 	    ctlr->reset = ata_via_reset;
 	}
-
 	if (ctlr->chip->cfg2 & VIABAR) {
 	    ctlr->channels = 3;
 	    ctlr->setmode = ata_via_new_setmode;
@@ -365,5 +382,37 @@ ata_via_southbridge_fixup(device_t dev)
     free(children, M_TEMP);
 }
 
+static int
+ata_via_sata_ch_attach(device_t dev)
+{
+	struct ata_channel *ch = device_get_softc(dev);
+
+	if (ata_pci_ch_attach(dev))
+		return ENXIO;
+	if (ch->unit == 0)
+		ch->flags |= ATA_SATA;
+	return (0);
+}
+
+static int
+ata_via_sata_getrev(device_t dev, int target)
+{
+	struct ata_channel *ch = device_get_softc(dev);
+
+	if (ch->unit == 0)
+		return (1);
+	return (0);
+}
+
+static int
+ata_via_sata_setmode(device_t dev, int target, int mode)
+{
+	struct ata_channel *ch = device_get_softc(dev);
+
+	if (ch->unit == 0)
+		return (mode);
+	return (ata_via_old_setmode(dev, target, mode));
+}
+
 ATA_DECLARE_DRIVER(ata_via);
 MODULE_DEPEND(ata_via, ata_ahci, 1, 1, 1);

From 44f39e7d59b9324d343a79afe27103910a0cdcb0 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 13:25:31 +0000
Subject: [PATCH 1222/2592] MFC r200817: Spell AMD properly.

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

diff --git a/sys/dev/ata/chipsets/ata-amd.c b/sys/dev/ata/chipsets/ata-amd.c
index 22ca546786f..589ffa0e8cb 100644
--- a/sys/dev/ata/chipsets/ata-amd.c
+++ b/sys/dev/ata/chipsets/ata-amd.c
@@ -61,7 +61,7 @@ static int ata_amd_setmode(device_t dev, int target, int mode);
 #define AMD_CABLE	0x02
 
 /*
- * American Micro Devices (AMD) chipset support functions
+ * Advanced Micro Devices (AMD) chipset support functions
  */
 static int
 ata_amd_probe(device_t dev)

From 4c75a1d302d9643504026199c4436d604b1eaa33 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 13:26:45 +0000
Subject: [PATCH 1223/2592] MFC r200857: Add support for Intel SCH PATA
 controller.

PR:             kern/140251
---
 sys/dev/ata/ata-pci.h            |  1 +
 sys/dev/ata/chipsets/ata-intel.c | 41 ++++++++++++++++++++++++++++++--
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index 25e0588a860..6f696a69eb4 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -204,6 +204,7 @@ struct ata_pci_controller {
 #define ATA_I82801JI_R1         0x3a258086
 #define ATA_I82801JI_S2         0x3a268086
 #define ATA_I31244              0x32008086
+#define ATA_ISCH                0x811a8086
 
 #define ATA_ITE_ID              0x1283
 #define ATA_IT8211F             0x82111283
diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c
index 95e40c1e3fc..ec05f30182b 100644
--- a/sys/dev/ata/chipsets/ata-intel.c
+++ b/sys/dev/ata/chipsets/ata-intel.c
@@ -57,6 +57,7 @@ static int ata_intel_ch_attach(device_t dev);
 static void ata_intel_reset(device_t dev);
 static int ata_intel_old_setmode(device_t dev, int target, int mode);
 static int ata_intel_new_setmode(device_t dev, int target, int mode);
+static int ata_intel_sch_setmode(device_t dev, int target, int mode);
 static int ata_intel_sata_getrev(device_t dev, int target);
 static int ata_intel_31244_ch_attach(device_t dev);
 static int ata_intel_31244_ch_detach(device_t dev);
@@ -140,6 +141,7 @@ ata_intel_probe(device_t dev)
      { 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" },
+     { ATA_ISCH,         0,          0, 1, ATA_UDMA5, "SCH" },
      { 0, 0, 0, 0, 0, 0}};
 
     if (pci_get_vendor(dev) != ATA_INTEL_ID)
@@ -183,7 +185,13 @@ ata_intel_chipinit(device_t dev)
 	ctlr->setmode = ata_sata_setmode;
 	ctlr->getrev = ata_sata_getrev;
     }
-
+    /* SCH */
+    else if (ctlr->chip->chipid == ATA_ISCH) {
+	ctlr->channels = 1;
+	ctlr->ch_attach = ata_intel_ch_attach;
+	ctlr->ch_detach = ata_pci_ch_detach;
+	ctlr->setmode = ata_intel_sch_setmode;
+    }
     /* non SATA intel chips goes here */
     else if (ctlr->chip->max_dma < ATA_SA150) {
 	ctlr->channels = ctlr->chip->cfg2;
@@ -245,7 +253,7 @@ ata_intel_ch_attach(device_t dev)
 		(pci_read_config(device_get_parent(dev), 0x90, 1) & 0x04) == 0)
 		    ch->flags |= ATA_NO_SLAVE;
 	    ch->flags |= ATA_SATA;
-    } else
+    } else if (ctlr->chip->chipid != ATA_ISCH)
 	    ch->flags |= ATA_CHECKS_CABLE;
     return 0;
 }
@@ -359,6 +367,35 @@ ata_intel_new_setmode(device_t dev, int target, int mode)
 	return (mode);
 }
 
+static int
+ata_intel_sch_setmode(device_t dev, int target, int mode)
+{
+	device_t parent = device_get_parent(dev);
+	struct ata_pci_controller *ctlr = device_get_softc(parent);
+	u_int8_t dtim = 0x80 + (target << 2);
+	u_int32_t tim = pci_read_config(parent, dtim, 4);
+	int piomode;
+
+	mode = min(mode, ctlr->chip->max_dma);
+	if (mode >= ATA_UDMA0) {
+		tim |= (0x1 << 31);
+		tim &= ~(0x7 << 16);
+		tim |= ((mode & ATA_MODE_MASK) << 16);
+		piomode = ATA_PIO4;
+	} else if (mode >= ATA_WDMA0) {
+		tim &= ~(0x1 << 31);
+		tim &= ~(0x3 << 8);
+		tim |= ((mode & ATA_MODE_MASK) << 8);
+		piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+		    (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+	} else
+		piomode = mode;
+	tim &= ~(0x7);
+	tim |= (piomode & 0x7);
+	pci_write_config(parent, dtim, tim, 4);
+	return (mode);
+}
+
 static int
 ata_intel_sata_getrev(device_t dev, int target)
 {

From 89dbf1bfd5d3ccb0bee6eebe22e367c8ff1a3ddb Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 13:27:54 +0000
Subject: [PATCH 1224/2592] MFC r201993: Report which of IXP700 legacy ATA
 channels are SATA.

---
 sys/dev/ata/chipsets/ata-ati.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/sys/dev/ata/chipsets/ata-ati.c b/sys/dev/ata/chipsets/ata-ati.c
index d464897243d..1dfd84b81f4 100644
--- a/sys/dev/ata/chipsets/ata-ati.c
+++ b/sys/dev/ata/chipsets/ata-ati.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 
 /* local prototypes */
 static int ata_ati_chipinit(device_t dev);
+static int ata_ati_ixp700_ch_attach(device_t dev);
 static int ata_ati_setmode(device_t dev, int target, int mode);
 
 /* misc defines */
@@ -121,7 +122,7 @@ ata_ati_chipinit(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
     device_t smbdev;
-    int satacfg;
+    uint8_t satacfg;
 
     if (ata_setup_interrupt(dev, ata_generic_intr))
 	return ENXIO;
@@ -145,13 +146,16 @@ ata_ati_chipinit(device_t dev)
 		    (satacfg & 0x01) == 0 ? "disabled" : "enabled",
 		    (satacfg & 0x08) == 0 ? "" : "combined mode, ",
 		    (satacfg & 0x10) == 0 ? "primary" : "secondary");
-
+	    ctlr->chipset_data = (void *)(uintptr_t)satacfg;
 	    /*
 	     * 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));
+	    else {
+	        ctlr->ch_attach = ata_ati_ixp700_ch_attach;
+	    }
 	}
 	break;
     }
@@ -160,6 +164,23 @@ ata_ati_chipinit(device_t dev)
     return 0;
 }
 
+static int
+ata_ati_ixp700_ch_attach(device_t dev)
+{
+	struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+	struct ata_channel *ch = device_get_softc(dev);
+	uint8_t satacfg = (uint8_t)(uintptr_t)ctlr->chipset_data;
+
+	/* Setup the usual register normal pci style. */
+	if (ata_pci_ch_attach(dev))
+		return ENXIO;
+
+	/* One of channels is PATA, another is SATA. */
+	if (ch->unit == ((satacfg & 0x10) >> 4))
+		ch->flags |= ATA_SATA;
+	return (0);
+}
+
 static int
 ata_ati_setmode(device_t dev, int target, int mode)
 {

From f288580266c0544bab20ccaccf9704c649928991 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 13:33:31 +0000
Subject: [PATCH 1225/2592] MFC r200814: Clear all ports interrupt status bits
 in single write. Clearing one by one causes additional MSIs messages sent if
 several ports asked for attention same time. Time window before clearing is
 not important, as these interrupts are level triggered by interrupt source.

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

diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index f0728ddc14b..bdb49a66800 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -596,20 +596,18 @@ ahci_intr(void *data)
 		unit = irq->r_irq_rid - 1;
 		is = ATA_INL(ctlr->r_mem, AHCI_IS);
 	}
+	/* Some controllers have edge triggered IS. */
+	if (ctlr->quirks & AHCI_Q_EDGEIS)
+		ATA_OUTL(ctlr->r_mem, AHCI_IS, is);
 	for (; unit < ctlr->channels; unit++) {
 		if ((is & (1 << unit)) != 0 &&
 		    (arg = ctlr->interrupt[unit].argument)) {
-			if (ctlr->quirks & AHCI_Q_EDGEIS) {
-				/* Some controller have edge triggered IS. */
-				ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
 				ctlr->interrupt[unit].function(arg);
-			} else {
-				/* but AHCI declares level triggered IS. */
-				ctlr->interrupt[unit].function(arg);
-				ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
-			}
 		}
 	}
+	/* AHCI declares level triggered IS. */
+	if (!(ctlr->quirks & AHCI_Q_EDGEIS))
+		ATA_OUTL(ctlr->r_mem, AHCI_IS, is);
 }
 
 /*

From 6c35bbee611f3dff00af090169c3cb78b568bb40 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Tue, 19 Jan 2010 13:36:12 +0000
Subject: [PATCH 1226/2592] MFC r201222: Usually these controllers are able to
 automatically decode command code to get required command protocol. But they
 have no idea about new commands, such as DATA SET MANAGEMENT (TRIM). As soon
 as this info any way provided by CAM, give controller specific instructions.

---
 sys/dev/siis/siis.c | 26 +++++++++++++++++++++-----
 sys/dev/siis/siis.h |  6 ++++++
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index a47ce2cebb1..1c6a2bb17e1 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -987,13 +987,29 @@ siis_execute_transaction(struct siis_slot *slot)
 	ctp->protocol_override = 0;
 	ctp->transfer_count = 0;
 	/* Special handling for Soft Reset command. */
-	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
-	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) {
-		ctp->control |= htole16(SIIS_PRB_SOFT_RESET);
+	if (ccb->ccb_h.func_code == XPT_ATA_IO) {
+		if (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) {
+			ctp->control |= htole16(SIIS_PRB_SOFT_RESET);
+		} else {
+			ctp->control |= htole16(SIIS_PRB_PROTOCOL_OVERRIDE);
+			if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) {
+				ctp->protocol_override |=
+				    htole16(SIIS_PRB_PROTO_NCQ);
+			}
+			if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
+				ctp->protocol_override |=
+				    htole16(SIIS_PRB_PROTO_READ);
+			} else
+			if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
+				ctp->protocol_override |=
+				    htole16(SIIS_PRB_PROTO_WRITE);
+			}
+		}
 	} else if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
-		if (ccb->ccb_h.flags & CAM_DIR_IN)
+		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
 			ctp->control |= htole16(SIIS_PRB_PACKET_READ);
-		if (ccb->ccb_h.flags & CAM_DIR_OUT)
+		else
+		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
 			ctp->control |= htole16(SIIS_PRB_PACKET_WRITE);
 	}
 	/* Setup the FIS for this request */
diff --git a/sys/dev/siis/siis.h b/sys/dev/siis/siis.h
index 2f8c046d7ce..f98d204384b 100644
--- a/sys/dev/siis/siis.h
+++ b/sys/dev/siis/siis.h
@@ -304,6 +304,12 @@ struct siis_cmd {
 #define SIIS_PRB_INTERRUPT_MASK		0x0040
 #define SIIS_PRB_SOFT_RESET		0x0080
     u_int16_t			protocol_override;
+#define SIIS_PRB_PROTO_PACKET		0x0001
+#define SIIS_PRB_PROTO_TCQ		0x0002
+#define SIIS_PRB_PROTO_NCQ		0x0004
+#define SIIS_PRB_PROTO_READ		0x0008
+#define SIIS_PRB_PROTO_WRITE		0x0010
+#define SIIS_PRB_PROTO_TRANSPARENT	0x0020
     u_int32_t			transfer_count;
     u_int8_t			fis[24];
     union {

From d24c3430ea131a45b20ab4e175f96fd0002b087a Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Tue, 19 Jan 2010 16:51:51 +0000
Subject: [PATCH 1227/2592] MFC: r201603

Fix a double free().
---
 lib/libc/rpc/getnetpath.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libc/rpc/getnetpath.c b/lib/libc/rpc/getnetpath.c
index 0563544df2a..d1ea554aa7b 100644
--- a/lib/libc/rpc/getnetpath.c
+++ b/lib/libc/rpc/getnetpath.c
@@ -101,7 +101,7 @@ setnetpath()
     if ((np_sessionp->nc_handlep = setnetconfig()) == NULL) {
 	free(np_sessionp);
 	syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
-	goto failed;
+    	return (NULL);
     }
     np_sessionp->valid = NP_VALID;
     np_sessionp->ncp_list = NULL;

From c321d2f3435d3281078eb5b733c45473d6b7e825 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Tue, 19 Jan 2010 17:09:18 +0000
Subject: [PATCH 1228/2592] MFC: r202176

Miscellaneous mdoc, spelling and inconsistency fixes.
---
 lib/libc/net/sctp_bindx.3           |  2 +-
 lib/libc/net/sctp_connectx.3        |  6 +++---
 lib/libc/net/sctp_getaddrlen.3      |  2 +-
 lib/libc/net/sctp_getassocid.3      |  2 +-
 lib/libc/net/sctp_getpaddrs.3       |  6 +++---
 lib/libc/net/sctp_opt_info.3        |  4 ++--
 lib/libc/net/sctp_recvmsg.3         | 19 ++++++++++---------
 lib/libc/net/sctp_send.3            |  2 +-
 lib/libc/net/sctp_sendmsg.3         |  4 ++--
 lib/libc/sys/sctp_generic_recvmsg.2 | 24 ++++++++++++++----------
 lib/libc/sys/sctp_generic_sendmsg.2 | 24 ++++++++++++++----------
 lib/libc/sys/sctp_peeloff.2         |  4 ++--
 12 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/lib/libc/net/sctp_bindx.3 b/lib/libc/net/sctp_bindx.3
index a2a260008bf..d0471267f98 100644
--- a/lib/libc/net/sctp_bindx.3
+++ b/lib/libc/net/sctp_bindx.3
@@ -90,7 +90,7 @@ The call returns 0 on success and -1 upon failure.
 .Sh ERRORS
 The
 .Fn sctp_bindx
-can return the following errors.
+function can return the following errors:
 .Bl -tag -width Er
 .It Bq Er EINVAL
 This value is returned if the
diff --git a/lib/libc/net/sctp_connectx.3 b/lib/libc/net/sctp_connectx.3
index 7b75f4ad300..d454bb9f5ba 100644
--- a/lib/libc/net/sctp_connectx.3
+++ b/lib/libc/net/sctp_connectx.3
@@ -44,7 +44,7 @@
 .In sys/socket.h
 .In netinet/sctp.h
 .Ft int
-.Fn sctp_connectx "int s" "struct sockaddr *" "int addrcnt" "sctp_assoc_t *"
+.Fn sctp_connectx "int sd" "struct sockaddr *addrs" "int addrcnt" "sctp_assoc_t *id"
 .Sh DESCRIPTION
 The
 .Fn sctp_connectx
@@ -75,7 +75,7 @@ the extra addresses sent in the
 call will be silently discarded from the association.
 On
 successful completion the provided
-.Fa "sctp_assoc_t *"
+.Fa id
 will be
 filled in with the association identification of the newly
 forming association.
@@ -84,7 +84,7 @@ The call returns 0 on success and -1 upon failure.
 .Sh ERRORS
 The
 .Fn sctp_connectx
-can return the following errors.
+function can return the following errors:
 .Bl -tag -width Er
 .It Bq Er EINVAL
 An address listed has an invalid family or no
diff --git a/lib/libc/net/sctp_getaddrlen.3 b/lib/libc/net/sctp_getaddrlen.3
index 325e2b0365c..ac7bfb375ac 100644
--- a/lib/libc/net/sctp_getaddrlen.3
+++ b/lib/libc/net/sctp_getaddrlen.3
@@ -76,7 +76,7 @@ system expects for the specific address family or -1.
 .Sh ERRORS
 The
 .Fn sctp_getaddrlen
-function can return the following errors.
+function can return the following errors:
 .Bl -tag -width Er
 .It Bq Er EINVAL
 The address family specified does NOT exist.
diff --git a/lib/libc/net/sctp_getassocid.3 b/lib/libc/net/sctp_getassocid.3
index ee0926a8cba..909b9c77344 100644
--- a/lib/libc/net/sctp_getassocid.3
+++ b/lib/libc/net/sctp_getassocid.3
@@ -58,7 +58,7 @@ The call returns the association id upon success and
 .Sh ERRORS
 The
 .Fn sctp_getassocid
-function can return the following errors.
+function can return the following errors:
 .Bl -tag -width Er
 .It Bq Er ENOENT
 The address does not have an association setup to it.
diff --git a/lib/libc/net/sctp_getpaddrs.3 b/lib/libc/net/sctp_getpaddrs.3
index 9f6d632cd03..6ad5ea03176 100644
--- a/lib/libc/net/sctp_getpaddrs.3
+++ b/lib/libc/net/sctp_getpaddrs.3
@@ -33,7 +33,7 @@
 .\" $FreeBSD$
 .\"
 .Dd December 15, 2006
-.Dt SCTP_GETPADDR 3
+.Dt SCTP_GETPADDRS 3
 .Os
 .Sh NAME
 .Nm sctp_getpaddrs ,
@@ -64,7 +64,7 @@ array of socket addresses returned in the argument
 .Fa addrs
 upon success.
 .Pp
-After the caller is through the function
+After the caller is finished, the function
 .Fn sctp_freepaddrs
 or
 .Fn sctp_freeladdrs
@@ -76,7 +76,7 @@ the number of addresses returned in
 .Fa addrs
 upon success.
 .Sh ERRORS
-The functions can return the following errors.
+The functions can return the following errors:
 .Bl -tag -width Er
 .It Bq Er EINVAL
 An address listed has an invalid family or no
diff --git a/lib/libc/net/sctp_opt_info.3 b/lib/libc/net/sctp_opt_info.3
index 560b3e47051..581a220fd62 100644
--- a/lib/libc/net/sctp_opt_info.3
+++ b/lib/libc/net/sctp_opt_info.3
@@ -45,7 +45,7 @@
 .In sys/socket.h
 .In netinet/sctp.h
 .Ft int
-.Fn sctp_opt_info "int s" "sctp_assoc_t" "int opt" "void *arg" "socklen_t *size"
+.Fn sctp_opt_info "int sd" "sctp_assoc_t id" "int opt" "void *arg" "socklen_t *size"
 .Sh DESCRIPTION
 The
 .Fn sctp_opt_info
@@ -90,7 +90,7 @@ socket options.
 .Sh ERRORS
 The
 .Fn sctp_opt_info
-function can return the following errors.
+function can return the following errors:
 .Bl -tag -width Er
 .It Bq Er EINVAL
 The argument
diff --git a/lib/libc/net/sctp_recvmsg.3 b/lib/libc/net/sctp_recvmsg.3
index b9ccfb8c0d8..f874880f6c8 100644
--- a/lib/libc/net/sctp_recvmsg.3
+++ b/lib/libc/net/sctp_recvmsg.3
@@ -160,7 +160,7 @@ struct sctp_sndrcvinfo {
 .Pp
 The
 .Fa sinfo->sinfo_ppid
-is an opaque 32 bit value that is passed transparently
+field is an opaque 32 bit value that is passed transparently
 through the stack from the peer endpoint. 
 Note that the stack passes this value without regard to byte
 order.
@@ -180,12 +180,13 @@ as soon as possible.
 When this flag is absent the message
 was delivered in order within the stream it was received.
 .Pp
+The
 .Fa sinfo->sinfo_stream
-is the SCTP stream that the message was received on. 
+field is the SCTP stream that the message was received on. 
 Streams in SCTP are reliable (or partially reliable) flows of ordered
 messages.
 .Pp
-The 
+The
 .Fa sinfo->sinfo_context
 field is used only if the local application set an association level
 context with the
@@ -197,7 +198,7 @@ association.
 .Pp
 The
 .Fa sinfo->sinfo_ssn
-will hold the stream sequence number assigned
+field will hold the stream sequence number assigned
 by the peer endpoint if the message is
 .Em not
 unordered.
@@ -205,7 +206,7 @@ For unordered messages this field holds an undefined value.
 .Pp
 The
 .Fa sinfo->sinfo_tsn
-holds a transport sequence number (TSN) that was assigned
+field holds a transport sequence number (TSN) that was assigned
 to this message by the peer endpoint.
 For messages that fit in or less
 than the path MTU this will be the only TSN assigned.
@@ -215,12 +216,12 @@ message.
 .Pp
 The
 .Fa sinfo->sinfo_cumtsn
-holds the current cumulative acknowledgment point of
+field holds the current cumulative acknowledgment point of
 the transport association.
 Note that this may be larger
 or smaller than the TSN assigned to the message itself.
 .Pp
-The 
+The
 .Fa sinfo->sinfo_assoc_id
 is the unique association identification that was assigned
 to the association.
@@ -232,10 +233,10 @@ setting various socket options on the specific association
 (see 
 .Xr sctp 4 ) .
 .Pp
-The 
+The
 .Fa sinfo->info_timetolive
 field is not used by 
-.Fa sctp_recvmsg .
+.Fn sctp_recvmsg .
 .Sh RETURN VALUES
 The call returns the number of characters sent, or -1
 if an error occurred.
diff --git a/lib/libc/net/sctp_send.3 b/lib/libc/net/sctp_send.3
index 230173024f0..f6f0c958dc8 100644
--- a/lib/libc/net/sctp_send.3
+++ b/lib/libc/net/sctp_send.3
@@ -294,7 +294,7 @@ if an error occurred.
 The
 .Fn sctp_send
 system call
-fail if:
+fails if:
 .Bl -tag -width Er
 .It Bq Er EBADF
 An invalid descriptor was specified.
diff --git a/lib/libc/net/sctp_sendmsg.3 b/lib/libc/net/sctp_sendmsg.3
index 61eec224cad..0c5fa024157 100644
--- a/lib/libc/net/sctp_sendmsg.3
+++ b/lib/libc/net/sctp_sendmsg.3
@@ -271,7 +271,7 @@ if an error occurred.
 The
 .Fn sctp_sendmsg
 system call
-fail if:
+fails if:
 .Bl -tag -width Er
 .It Bq Er EBADF
 An invalid descriptor was specified.
@@ -324,7 +324,7 @@ is not connected and is a one-to-one style socket.
 .Xr sendmsg 3 ,
 .Xr sctp 4
 .Sh BUGS
-Because in the one-to-many style socket the
+Because in the one-to-many style socket
 .Fn sctp_sendmsg 
 or
 .Fn sctp_sendmsgx
diff --git a/lib/libc/sys/sctp_generic_recvmsg.2 b/lib/libc/sys/sctp_generic_recvmsg.2
index ccdb9db6fad..d6fd1b564de 100644
--- a/lib/libc/sys/sctp_generic_recvmsg.2
+++ b/lib/libc/sys/sctp_generic_recvmsg.2
@@ -36,7 +36,7 @@
 .Os
 .Sh NAME
 .Nm sctp_generic_recvmsg
-.Nd receive data from a peer.
+.Nd receive data from a peer
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
@@ -46,16 +46,20 @@
 .Ft int
 .Fn sctp_generic_recvmsg "int s" "struct iovec *iov" "int iovlen" "struct sockaddr *from" "socklen_t *fromlen" "struct sctp_sndrcvinfo *sinfo" "int *msgflags"
 .Sh DESCRIPTION
-The
 .Fn sctp_generic_recvmsg
-is the true system calls used by the
-.Fn sctp_recvmsg
-function call. This call is more efficient since it is a
-true system calls but it is specific to FreeBSD and
-can be expected NOT to be present on any other Operating
-System. For detailed useage please see either the
-.Fn sctp_recvmsg 
-function call. 
+is the true system call used by the
+.Xr sctp_recvmsg 3
+function call.
+This call is more efficient since it is a
+true system call but it is specific to
+.Fx
+and can be expected
+.Em not
+to be present on any other operating
+system.
+For detailed usage please see the
+.Xr sctp_recvmsg 3
+function call.
 .Sh RETURN VALUES
 The call returns the number of bytes read on success and -1 upon failure.
 .Sh ERRORS
diff --git a/lib/libc/sys/sctp_generic_sendmsg.2 b/lib/libc/sys/sctp_generic_sendmsg.2
index d7050f22fe4..fee4211a9e6 100644
--- a/lib/libc/sys/sctp_generic_sendmsg.2
+++ b/lib/libc/sys/sctp_generic_sendmsg.2
@@ -37,7 +37,7 @@
 .Sh NAME
 .Nm sctp_generic_sendmsg
 .Nm sctp_generic_sendmsg_iov
-.Nd send data to a peer.
+.Nd send data to a peer
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
@@ -49,21 +49,25 @@
 .Ft int
 .Fn sctp_generic_sendmsg_iov "int s" "struct iovec *iov" "int iovlen" "struct sockaddr *to" "struct sctp_sndrcvinfo *sinfo" "int flags"
 .Sh DESCRIPTION
-The
 .Fn sctp_generic_sendmsg
 and
 .Fn sctp_generic_sendmsg_iov
 are the true system calls used by the
-.Fn sctp_sendmsg
+.Xr sctp_sendmsg 3
 and 
-.Fn sctp_send
-function calls. These are more efficient since they are
-true system calls but they are specific to FreeBSD and
-can be expected NOT to be present on any other Operating
-System. For detailed useage please see either the
-.Fn sctp_send
+.Xr sctp_send 3
+function calls.
+These are more efficient since they are
+true system calls but they are specific to
+.Fx
+and can be expected
+.Em not
+to be present on any other operating
+system.
+For detailed usage please see either the
+.Xr sctp_send 3
 or
-.Fn sctp_sendmsg
+.Xr sctp_sendmsg 3
 function calls. 
 .Sh RETURN VALUES
 The call returns the number of bytes written on success and -1 upon failure.
diff --git a/lib/libc/sys/sctp_peeloff.2 b/lib/libc/sys/sctp_peeloff.2
index 0ac5be6aa82..c513afaa12b 100644
--- a/lib/libc/sys/sctp_peeloff.2
+++ b/lib/libc/sys/sctp_peeloff.2
@@ -36,7 +36,7 @@
 .Os
 .Sh NAME
 .Nm sctp_peeloff
-.Nd detach an association from a one-to-many socket to its on fd
+.Nd detach an association from a one-to-many socket to its own fd
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
@@ -58,7 +58,7 @@ upon success.
 .Sh ERRORS
 The
 .Fn sctp_peeloff
-can return the following errors.
+system call can return the following errors:
 .Bl -tag -width Er
 .It Bq Er ENOTCONN
 The 

From 37c002faf861046e0af9f78f224ab7c91ff4a688 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Tue, 19 Jan 2010 20:48:23 +0000
Subject: [PATCH 1229/2592] MFC 202284,202650: - Update required headers for
 namei() to add  and remove   . - Add RETURN VALUES
 and ERROR sections for namei()'s error return values. - Add a missing link to
 NDHASGIANT.9.

---
 share/man/man9/Makefile |  1 +
 share/man/man9/namei.9  | 30 +++++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index d9c01d1e9b2..4b2799fbd60 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -898,6 +898,7 @@ MLINKS+=mutex.9 mtx_assert.9 \
 	mutex.9 mtx_unlock_spin.9 \
 	mutex.9 mtx_unlock_spin_flags.9
 MLINKS+=namei.9 NDFREE.9 \
+	namei.9 NDHASGIANT.9 \
 	namei.9 NDINIT.9
 MLINKS+=pbuf.9 getpbuf.9 \
 	pbuf.9 relpbuf.9 \
diff --git a/share/man/man9/namei.9 b/share/man/man9/namei.9
index 19516651949..1ffabfffa07 100644
--- a/share/man/man9/namei.9
+++ b/share/man/man9/namei.9
@@ -44,7 +44,7 @@
 .Nd pathname translation and lookup operations
 .Sh SYNOPSIS
 .In sys/param.h
-.In sys/proc.h
+.In sys/fcntl.h
 .In sys/namei.h
 .Ft int
 .Fn namei "struct nameidata *ndp"
@@ -315,6 +315,34 @@ flag can be passed to the
 .Fn NDFREE
 function.
 .El
+.Sh RETURN VALUES
+If successful,
+.Fn namei
+will return 0, otherwise it will return an error.
+.Sh ERRORS
+Errors which
+.Fn namei
+may return:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the specified pathname is not a directory when a directory is
+expected.
+.It Bq Er ENAMETOOLONG
+A component of a pathname exceeded 255 characters,
+or an entire pathname exceeded 1023 characters.
+.It Bq Er ENOENT
+A component of the specified pathname does not exist,
+or the pathname is an empty string.
+.It Bq Er ACCES
+An attempt is made to access a file in a way forbidden by its file access
+permissions.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname.
+.It Bq Er EISDIR
+An attempt is made to open a directory with write mode specified.
+.It Bq Er EROFS
+An attempt is made to modify a file or directory on a read-only file system.
+.El
 .Sh FILES
 .Bl -tag
 .It Pa src/sys/kern/vfs_lookup.c

From 53b6e7516f92f4de2a6db6833d0a916cdaf9b872 Mon Sep 17 00:00:00 2001
From: Fabien Thomas 
Date: Tue, 19 Jan 2010 20:55:57 +0000
Subject: [PATCH 1230/2592] MFC 202157:  Bug fix: add a missing initializer.

---
 lib/libpmc/libpmc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index ecc697da203..af716da157b 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -2507,6 +2507,7 @@ pmc_init(void)
 		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:

From 2f601d079e2b6193509bab9173998eebf0ea8168 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Tue, 19 Jan 2010 22:09:41 +0000
Subject: [PATCH 1231/2592] MFC: r202453

Update the sparc64 hardware list regarding machines that will be supported
by 7.3-RELEASE.
---
 release/doc/en_US.ISO8859-1/hardware/article.sgml | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/release/doc/en_US.ISO8859-1/hardware/article.sgml b/release/doc/en_US.ISO8859-1/hardware/article.sgml
index 53302c66027..83d9f039394 100644
--- a/release/doc/en_US.ISO8859-1/hardware/article.sgml
+++ b/release/doc/en_US.ISO8859-1/hardware/article.sgml
@@ -514,6 +514,10 @@
 	  &sun.fire; V210
 	
 
+	
+	  &sun.fire; V215 (support first appeared in 7.3-RELEASE)
+	
+
 	
 	  &sun.fire; V250
 	
@@ -523,6 +527,11 @@
 	    appeared in 8.0-RELEASE)
 	
 
+	
+	  &sun.fire; V480 (501-6780 and 501-6790 centerplanes only, for
+	    which support first appeared in 7.3-RELEASE)
+	
+
 	
 	  &sun.fire; V880
 	
@@ -543,6 +552,10 @@
 	
 	  &sun.fire; V240
 	
+
+	
+	  &sun.fire; V245 (support first appeared in 7.3-RELEASE)
+	
       
     
   

From 3895783a8af9700f2bd42758178adcfe5372e146 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Wed, 20 Jan 2010 00:43:15 +0000
Subject: [PATCH 1232/2592] MFC r200795:

Add support of using environment variable BURNCD_SPEED to specify
recodring speed.

PR:		bin/140530
Submitted by:	Alexander Best 
---
 usr.sbin/burncd/burncd.8 |  8 ++++++--
 usr.sbin/burncd/burncd.c | 20 +++++++++++++-------
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/usr.sbin/burncd/burncd.8 b/usr.sbin/burncd/burncd.8
index 18c1bc46a11..2501e7209c7 100644
--- a/usr.sbin/burncd/burncd.8
+++ b/usr.sbin/burncd/burncd.8
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 2, 2005
+.Dd December 21, 2009
 .Os
 .Dt BURNCD 8
 .Sh NAME
@@ -158,7 +158,11 @@ refers to stdin, and can only be used once.
 .Sh ENVIRONMENT
 The following environment variables affect the execution of
 .Nm :
-.Bl -tag -width ".Ev CDROM"
+.Bl -tag -width ".Ev BURNCD_SPEED"
+.It Ev BURNCD_SPEED
+The write speed to use if one is not specified with the
+.Fl s
+flag.
 .It Ev CDROM
 The CD device to use if one is not specified with the
 .Fl f
diff --git a/usr.sbin/burncd/burncd.c b/usr.sbin/burncd/burncd.c
index c4d1648e7bb..2931cf819bc 100644
--- a/usr.sbin/burncd/burncd.c
+++ b/usr.sbin/burncd/burncd.c
@@ -80,11 +80,13 @@ main(int argc, char **argv)
 	int dao = 0, eject = 0, fixate = 0, list = 0, multi = 0, preemp = 0;
 	int nogap = 0, speed = 4 * 177, test_write = 0, force = 0;
 	int block_size = 0, block_type = 0, cdopen = 0, dvdrw = 0;
-	const char *dev;
+	const char *dev, *env_speed;
 
 	if ((dev = getenv("CDROM")) == NULL)
 		dev = "/dev/acd0";
 
+	env_speed = getenv("BURNCD_SPEED");
+
 	while ((ch = getopt(argc, argv, "def:Flmnpqs:tv")) != -1) {
 		switch (ch) {
 		case 'd':
@@ -124,12 +126,7 @@ main(int argc, char **argv)
 			break;
 
 		case 's':
-			if (strcasecmp("max", optarg) == 0)
-				speed = CDR_MAX_SPEED;
-			else
-				speed = atoi(optarg) * 177;
-			if (speed <= 0)
-				errx(EX_USAGE, "Invalid speed: %s", optarg);
+			env_speed = optarg;
 			break;
 
 		case 't':
@@ -147,6 +144,15 @@ main(int argc, char **argv)
 	argc -= optind;
 	argv += optind;
 
+	if (env_speed == NULL)
+		;
+	else if (strcasecmp("max", env_speed) == 0)
+		speed = CDR_MAX_SPEED;
+	else
+		speed = atoi(env_speed) * 177;
+	if (speed <= 0)
+		errx(EX_USAGE, "Invalid speed: %s", optarg);
+
 	if (argc == 0)
 		usage();
 

From 49399ca706df781a3317bbf9b002f236b8012061 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Wed, 20 Jan 2010 00:52:24 +0000
Subject: [PATCH 1233/2592] MFC r200799:

K&R -> ANSI prototype.
---
 lib/libc/stdio/vsscanf.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c
index e5e96917b42..22b5d2bdac0 100644
--- a/lib/libc/stdio/vsscanf.c
+++ b/lib/libc/stdio/vsscanf.c
@@ -45,20 +45,15 @@ eofread(void *, char *, int);
 
 /* ARGSUSED */
 static int
-eofread(cookie, buf, len)
-	void *cookie;
-	char *buf;
-	int len;
+eofread(void *cookie, char *buf, int len)
 {
 
 	return (0);
 }
 
 int
-vsscanf(str, fmt, ap)
-	const char * __restrict str;
-	const char * __restrict fmt;
-	__va_list ap;
+vsscanf(const char * __restrict str, const char * __restrict fmt,
+	__va_list ap)
 {
 	FILE f;
 

From bf2d481d44256937ba57787654ae1f8097276525 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Wed, 20 Jan 2010 00:53:03 +0000
Subject: [PATCH 1234/2592] MFC r200800:

Use vsscanf instead of rolling our own.

PR:		bin/140530
Submitted by:	Jeremy Huddleston 
---
 lib/libc/stdio/sscanf.c | 25 +------------------------
 1 file changed, 1 insertion(+), 24 deletions(-)

diff --git a/lib/libc/stdio/sscanf.c b/lib/libc/stdio/sscanf.c
index 3c792e054ba..c793b86699c 100644
--- a/lib/libc/stdio/sscanf.c
+++ b/lib/libc/stdio/sscanf.c
@@ -41,37 +41,14 @@ __FBSDID("$FreeBSD$");
 #include 
 #include "local.h"
 
-static int eofread(void *, char *, int);
-
-/* ARGSUSED */
-static int
-eofread(cookie, buf, len)
-	void *cookie;
-	char *buf;
-	int len;
-{
-
-	return (0);
-}
-
 int
 sscanf(const char * __restrict str, char const * __restrict fmt, ...)
 {
 	int ret;
 	va_list ap;
-	FILE f;
 
-	f._file = -1;
-	f._flags = __SRD;
-	f._bf._base = f._p = (unsigned char *)str;
-	f._bf._size = f._r = strlen(str);
-	f._read = eofread;
-	f._ub._base = NULL;
-	f._lb._base = NULL;
-	f._orientation = 0;
-	memset(&f._mbstate, 0, sizeof(mbstate_t));
 	va_start(ap, fmt);
-	ret = __svfscanf(&f, fmt, ap);
+	ret = vsscanf(str, fmt, ap);
 	va_end(ap);
 	return (ret);
 }

From 6e6d19008bc00877ef94124cdeaede817bdf969f Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Wed, 20 Jan 2010 00:53:44 +0000
Subject: [PATCH 1235/2592] MFC r200802:

Use vsprintf instead of rolling our own.

PR:		bin/140496
Submitted by:	Jeremy Huddleston 
---
 lib/libc/stdio/sprintf.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c
index aaaae5535d2..b55bd6cfa2c 100644
--- a/lib/libc/stdio/sprintf.c
+++ b/lib/libc/stdio/sprintf.c
@@ -46,17 +46,9 @@ sprintf(char * __restrict str, char const * __restrict fmt, ...)
 {
 	int ret;
 	va_list ap;
-	FILE f;
 
-	f._file = -1;
-	f._flags = __SWR | __SSTR;
-	f._bf._base = f._p = (unsigned char *)str;
-	f._bf._size = f._w = INT_MAX;
-	f._orientation = 0;
-	memset(&f._mbstate, 0, sizeof(mbstate_t));
 	va_start(ap, fmt);
-	ret = __vfprintf(&f, fmt, ap);
+	ret = vsprintf(str, fmt, ap);
 	va_end(ap);
-	*f._p = 0;
 	return (ret);
 }

From ac07939f0eee4754d3df839c4116dcc58acb6c2c Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Wed, 20 Jan 2010 01:13:52 +0000
Subject: [PATCH 1236/2592] MFC r201689:

Instead of assuming all vdevs are healthy, check the newest vdev label
for each vdev's status.  Booting from a degraded vdev should now be
more robust.

Submitted by:	Matt Reimer 
Sponsored by:	VPOP Technologies, Inc.
---
 sys/boot/zfs/zfsimpl.c      | 88 +++++++++++++++++++++++++++----------
 sys/cddl/boot/zfs/zfsimpl.h | 13 +++++-
 2 files changed, 78 insertions(+), 23 deletions(-)

diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c
index adddb6a4f2a..1e95daccd60 100644
--- a/sys/boot/zfs/zfsimpl.c
+++ b/sys/boot/zfs/zfsimpl.c
@@ -404,7 +404,7 @@ vdev_create(uint64_t guid, vdev_read_t *read)
 }
 
 static int
-vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp)
+vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp, int is_newer)
 {
 	int rc;
 	uint64_t guid, id, ashift, nparity;
@@ -412,7 +412,8 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp)
 	const char *path;
 	vdev_t *vdev, *kid;
 	const unsigned char *kids;
-	int nkids, i;
+	int nkids, i, is_new;
+	uint64_t is_offline, is_faulted, is_degraded, is_removed;
 
 	if (nvlist_find(nvlist, ZPOOL_CONFIG_GUID,
 			DATA_TYPE_UINT64, 0, &guid)
@@ -424,17 +425,6 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp)
 		return (ENOENT);
 	}
 
-	/*
-	 * Assume that if we've seen this vdev tree before, this one
-	 * will be identical.
-	 */
-	vdev = vdev_find(guid);
-	if (vdev) {
-		if (vdevp)
-			*vdevp = vdev;
-		return (0);
-	}
-
 	if (strcmp(type, VDEV_TYPE_MIRROR)
 	    && strcmp(type, VDEV_TYPE_DISK)
 	    && strcmp(type, VDEV_TYPE_RAIDZ)) {
@@ -442,6 +432,21 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp)
 		return (EIO);
 	}
 
+	is_offline = is_removed = is_faulted = is_degraded = 0;
+
+	nvlist_find(nvlist, ZPOOL_CONFIG_OFFLINE, DATA_TYPE_UINT64, 0,
+			&is_offline);
+	nvlist_find(nvlist, ZPOOL_CONFIG_REMOVED, DATA_TYPE_UINT64, 0,
+			&is_removed);
+	nvlist_find(nvlist, ZPOOL_CONFIG_FAULTED, DATA_TYPE_UINT64, 0,
+			&is_faulted);
+	nvlist_find(nvlist, ZPOOL_CONFIG_DEGRADED, DATA_TYPE_UINT64, 0,
+			&is_degraded);
+
+	vdev = vdev_find(guid);
+	if (!vdev) {
+		is_new = 1;
+
 	if (!strcmp(type, VDEV_TYPE_MIRROR))
 		vdev = vdev_create(guid, vdev_mirror_read);
 	else if (!strcmp(type, VDEV_TYPE_RAIDZ))
@@ -480,6 +485,39 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp)
 			vdev->v_name = strdup(type);
 		}
 	}
+
+		if (is_offline)
+			vdev->v_state = VDEV_STATE_OFFLINE;
+		else if (is_removed)
+			vdev->v_state = VDEV_STATE_REMOVED;
+		else if (is_faulted)
+			vdev->v_state = VDEV_STATE_FAULTED;
+		else if (is_degraded)
+			vdev->v_state = VDEV_STATE_DEGRADED;
+		else
+			vdev->v_state = VDEV_STATE_HEALTHY;
+	} else {
+		is_new = 0;
+
+		if (is_newer) {
+			/*
+			 * We've already seen this vdev, but from an older
+			 * vdev label, so let's refresh its state from the
+			 * newer label.
+			 */
+			if (is_offline)
+				vdev->v_state = VDEV_STATE_OFFLINE;
+			else if (is_removed)
+				vdev->v_state = VDEV_STATE_REMOVED;
+			else if (is_faulted)
+				vdev->v_state = VDEV_STATE_FAULTED;
+			else if (is_degraded)
+				vdev->v_state = VDEV_STATE_DEGRADED;
+			else
+				vdev->v_state = VDEV_STATE_HEALTHY;
+		}
+	}
+
 	rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN,
 			 DATA_TYPE_NVLIST_ARRAY, &nkids, &kids);
 	/*
@@ -488,10 +526,12 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp)
 	if (rc == 0) {
 		vdev->v_nchildren = nkids;
 		for (i = 0; i < nkids; i++) {
-			rc = vdev_init_from_nvlist(kids, &kid);
+			rc = vdev_init_from_nvlist(kids, &kid, is_newer);
 			if (rc)
 				return (rc);
-			STAILQ_INSERT_TAIL(&vdev->v_children, kid, v_childlink);
+			if (is_new)
+				STAILQ_INSERT_TAIL(&vdev->v_children, kid,
+						   v_childlink);
 			kids = nvlist_next(kids);
 		}
 	} else {
@@ -593,7 +633,9 @@ state_name(vdev_state_t state)
 		"UNKNOWN",
 		"CLOSED",
 		"OFFLINE",
+		"REMOVED",
 		"CANT_OPEN",
+		"FAULTED",
 		"DEGRADED",
 		"ONLINE"
 	};
@@ -711,7 +753,7 @@ vdev_probe(vdev_phys_read_t *read, void *read_priv, spa_t **spap)
 	uint64_t pool_txg, pool_guid;
 	const char *pool_name;
 	const unsigned char *vdevs;
-	int i, rc;
+	int i, rc, is_newer;
 	char upbuf[1024];
 	const struct uberblock *up;
 
@@ -793,12 +835,15 @@ vdev_probe(vdev_phys_read_t *read, void *read_priv, spa_t **spap)
 		spa = spa_create(pool_guid);
 		spa->spa_name = strdup(pool_name);
 	}
-	if (pool_txg > spa->spa_txg)
+	if (pool_txg > spa->spa_txg) {
 		spa->spa_txg = pool_txg;
+		is_newer = 1;
+	} else
+		is_newer = 0;
 
 	/*
 	 * Get the vdev tree and create our in-core copy of it.
-	 * If we already have a healthy vdev with this guid, this must
+	 * If we already have a vdev with this guid, this must
 	 * be some kind of alias (overlapping slices, dangerously dedicated
 	 * disks etc).
 	 */
@@ -808,16 +853,16 @@ vdev_probe(vdev_phys_read_t *read, void *read_priv, spa_t **spap)
 		return (EIO);
 	}
 	vdev = vdev_find(guid);
-	if (vdev && vdev->v_state == VDEV_STATE_HEALTHY) {
+	if (vdev && vdev->v_phys_read)	/* Has this vdev already been inited? */
 		return (EIO);
-	}
 
 	if (nvlist_find(nvlist,
 			ZPOOL_CONFIG_VDEV_TREE,
 			DATA_TYPE_NVLIST, 0, &vdevs)) {
 		return (EIO);
 	}
-	rc = vdev_init_from_nvlist(vdevs, &top_vdev);
+
+	rc = vdev_init_from_nvlist(vdevs, &top_vdev, is_newer);
 	if (rc)
 		return (rc);
 
@@ -838,7 +883,6 @@ vdev_probe(vdev_phys_read_t *read, void *read_priv, spa_t **spap)
 	if (vdev) {
 		vdev->v_phys_read = read;
 		vdev->v_read_priv = read_priv;
-		vdev->v_state = VDEV_STATE_HEALTHY;
 	} else {
 		printf("ZFS: inconsistent nvlist contents\n");
 		return (EIO);
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index 1149eac95d0..ef13487a8e0 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -548,7 +548,6 @@ typedef enum {
 #define	ZPOOL_CONFIG_DTL		"DTL"
 #define	ZPOOL_CONFIG_STATS		"stats"
 #define	ZPOOL_CONFIG_WHOLE_DISK		"whole_disk"
-#define	ZPOOL_CONFIG_OFFLINE		"offline"
 #define	ZPOOL_CONFIG_ERRCOUNT		"error_count"
 #define	ZPOOL_CONFIG_NOT_PRESENT	"not_present"
 #define	ZPOOL_CONFIG_SPARES		"spares"
@@ -558,6 +557,16 @@ typedef enum {
 #define	ZPOOL_CONFIG_HOSTNAME		"hostname"
 #define	ZPOOL_CONFIG_TIMESTAMP		"timestamp" /* not stored on disk */
 
+/*
+ * The persistent vdev state is stored as separate values rather than a single
+ * 'vdev_state' entry.  This is because a device can be in multiple states, such
+ * as offline and degraded.
+ */
+#define	ZPOOL_CONFIG_OFFLINE            "offline"
+#define	ZPOOL_CONFIG_FAULTED            "faulted"
+#define	ZPOOL_CONFIG_DEGRADED           "degraded"
+#define	ZPOOL_CONFIG_REMOVED            "removed"
+
 #define	VDEV_TYPE_ROOT			"root"
 #define	VDEV_TYPE_MIRROR		"mirror"
 #define	VDEV_TYPE_REPLACING		"replacing"
@@ -590,7 +599,9 @@ typedef enum vdev_state {
 	VDEV_STATE_UNKNOWN = 0,	/* Uninitialized vdev			*/
 	VDEV_STATE_CLOSED,	/* Not currently open			*/
 	VDEV_STATE_OFFLINE,	/* Not allowed to open			*/
+	VDEV_STATE_REMOVED,	/* Explicitly removed from system	*/
 	VDEV_STATE_CANT_OPEN,	/* Tried to open, but failed		*/
+	VDEV_STATE_FAULTED,	/* External request to fault device	*/
 	VDEV_STATE_DEGRADED,	/* Replicated vdev with unhealthy kids	*/
 	VDEV_STATE_HEALTHY	/* Presumed good			*/
 } vdev_state_t;

From b1ebb318cb8ea7f120ee4d5c18d5419632a6fbff Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Wed, 20 Jan 2010 01:14:54 +0000
Subject: [PATCH 1237/2592] MFC r201690:

Space cleanup for revision 202669 committed separately for easier review.
This commit is purely space changes.

Submitted by:	Matt Reimer
Sponsored by:	VPOP Technologies, Inc.
---
 sys/boot/zfs/zfsimpl.c | 70 +++++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c
index 1e95daccd60..1407eb5d9c7 100644
--- a/sys/boot/zfs/zfsimpl.c
+++ b/sys/boot/zfs/zfsimpl.c
@@ -447,44 +447,44 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp, int is_newer)
 	if (!vdev) {
 		is_new = 1;
 
-	if (!strcmp(type, VDEV_TYPE_MIRROR))
-		vdev = vdev_create(guid, vdev_mirror_read);
-	else if (!strcmp(type, VDEV_TYPE_RAIDZ))
-		vdev = vdev_create(guid, vdev_raidz_read);
-	else
-		vdev = vdev_create(guid, vdev_disk_read);
+		if (!strcmp(type, VDEV_TYPE_MIRROR))
+			vdev = vdev_create(guid, vdev_mirror_read);
+		else if (!strcmp(type, VDEV_TYPE_RAIDZ))
+			vdev = vdev_create(guid, vdev_raidz_read);
+		else
+			vdev = vdev_create(guid, vdev_disk_read);
 
-	vdev->v_id = id;
-	if (nvlist_find(nvlist, ZPOOL_CONFIG_ASHIFT,
-		DATA_TYPE_UINT64, 0, &ashift) == 0)
-		vdev->v_ashift = ashift;
-	else
-		vdev->v_ashift = 0;
-	if (nvlist_find(nvlist, ZPOOL_CONFIG_NPARITY,
-		DATA_TYPE_UINT64, 0, &nparity) == 0)
-		vdev->v_nparity = nparity;
-	else
-		vdev->v_nparity = 0;
-	if (nvlist_find(nvlist, ZPOOL_CONFIG_PATH,
-			DATA_TYPE_STRING, 0, &path) == 0) {
-		if (strlen(path) > 5
-		    && path[0] == '/'
-		    && path[1] == 'd'
-		    && path[2] == 'e'
-		    && path[3] == 'v'
-		    && path[4] == '/')
-			path += 5;
-		vdev->v_name = strdup(path);
-	} else {
-		if (!strcmp(type, "raidz")) {
-			if (vdev->v_nparity == 1)
-				vdev->v_name = "raidz1";
-			else
-				vdev->v_name = "raidz2";
+		vdev->v_id = id;
+		if (nvlist_find(nvlist, ZPOOL_CONFIG_ASHIFT,
+			DATA_TYPE_UINT64, 0, &ashift) == 0)
+			vdev->v_ashift = ashift;
+		else
+			vdev->v_ashift = 0;
+		if (nvlist_find(nvlist, ZPOOL_CONFIG_NPARITY,
+			DATA_TYPE_UINT64, 0, &nparity) == 0)
+			vdev->v_nparity = nparity;
+		else
+			vdev->v_nparity = 0;
+		if (nvlist_find(nvlist, ZPOOL_CONFIG_PATH,
+				DATA_TYPE_STRING, 0, &path) == 0) {
+			if (strlen(path) > 5
+			    && path[0] == '/'
+			    && path[1] == 'd'
+			    && path[2] == 'e'
+			    && path[3] == 'v'
+			    && path[4] == '/')
+				path += 5;
+			vdev->v_name = strdup(path);
 		} else {
-			vdev->v_name = strdup(type);
+			if (!strcmp(type, "raidz")) {
+				if (vdev->v_nparity == 1)
+					vdev->v_name = "raidz1";
+				else
+					vdev->v_name = "raidz2";
+			} else {
+				vdev->v_name = strdup(type);
+			}
 		}
-	}
 
 		if (is_offline)
 			vdev->v_state = VDEV_STATE_OFFLINE;

From 28b4af9852607f4db0fa9530748fde548352e0ae Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 20 Jan 2010 14:48:42 +0000
Subject: [PATCH 1238/2592] MFC 202285: - Note that if_xname, if_dname, and
 if_dunit are usually initialized via   if_initname(). - Document if_drv_flags
 and replace references to IFF_(RUNNING|OACTIVE)   with references to
 IFF_DRV_(RUNNING|OACTIVE). - Complete truncated sentence in the description
 of if_transmit by copying   from the description in if_qflush. - Add missing
 line breaks for translators.

---
 share/man/man9/ifnet.9 | 56 ++++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 16 deletions(-)

diff --git a/share/man/man9/ifnet.9 b/share/man/man9/ifnet.9
index 532f6cd6e41..e3bf5917fd4 100644
--- a/share/man/man9/ifnet.9
+++ b/share/man/man9/ifnet.9
@@ -237,11 +237,15 @@ The name of the interface,
 .Dq Li fxp0
 or
 .Dq Li lo0 ) .
-(Initialized by driver.)
+(Initialized by driver
+(usually via
+.Fn if_initname ) . )
 .It Va if_dname
 .Pq Vt "const char *"
 The name of the driver.
-(Initialized by driver.)
+(Initialized by driver
+(usually via
+.Fn if_initname ) . )
 .It Va if_dunit
 .Pq Vt int
 A unique number assigned to each interface managed by a particular
@@ -249,7 +253,9 @@ driver.
 Drivers may choose to set this to
 .Dv IF_DUNIT_NONE
 if a unit number is not associated with the device.
-(Initialized by driver.)
+(Initialized by driver
+(usually via
+.Fn if_initname ) . )
 .It Va if_addrhead
 .Pq Vt "struct ifaddrhead"
 The head of the
@@ -289,7 +295,11 @@ decremented by generic watchdog code.)
 .It Va if_flags
 .Pq Vt int
 Flags describing operational parameters of this interface (see below).
-(Manipulated by both driver and generic code.)
+(Manipulated by generic code.)
+.It Va if_drv_flags
+.Pq Vt int
+Flags describing operational status of this interface (see below).
+(Manipulated by driver.)
 .It Va if_capabilities
 .Pq Vt int
 Flags describing the capabilities the interface supports (see below).
@@ -356,18 +366,26 @@ Output a packet on interface
 or queue it on the output queue if the interface is already active.
 .It Fn if_transmit
 Transmit a packet on an interface or queue it if the interface is
-in use. This function will return
+in use.
+This function will return
 .Dv ENOBUFS
-if the devices software and hardware queues are both full. This 
-function must be installed after 
+if the devices software and hardware queues are both full.
+This function must be installed after
+.Fn if_attach 
+to override the default implementation.
+This function is exposed in order to allow drivers to manage their own queues
+and to reduce the latency caused by a frequently gratuitous enqueue / dequeue
+pair to ifq.
+The suggested internal software queueing mechanism is buf_ring.
 .It Fn if_qflush
 Free mbufs in internally managed queues when the interface is marked down.
 This function must be installed after 
 .Fn if_attach 
-to override the default implementation. This function is exposed in order
-to allow drivers to manage their own queues and to reduce the latency 
-caused by a frequently gratuitous enqueue / dequeue pair to ifq. The 
-suggested internal software queueing mechanism is buf_ring.
+to override the default implementation.
+This function is exposed in order to allow drivers to manage their own queues
+and to reduce the latency caused by a frequently gratuitous enqueue / dequeue
+pair to ifq.
+The suggested internal software queueing mechanism is buf_ring.
 .It Fn if_start
 Start queued output on an interface.
 This function is exposed in
@@ -376,10 +394,10 @@ order to provide for some interface classes to share a
 among all drivers.
 .Fn if_start
 may only be called when the
-.Dv IFF_OACTIVE
+.Dv IFF_DRV_OACTIVE
 flag is not set.
 (Thus,
-.Dv IFF_OACTIVE
+.Dv IFF_DRV_OACTIVE
 does not literally mean that output is active, but rather that the
 device's internal output queue is full.) Please note that this function
 will soon be deprecated.
@@ -418,7 +436,7 @@ Initialize and bring up the hardware,
 e.g., reset the chip and the watchdog timer and enable the receiver unit.
 Should mark the interface running,
 but not active
-.Dv ( IFF_RUNNING , ~IIF_OACTIVE ) .
+.Dv ( IFF_DRV_RUNNING , ~IIF_DRV_OACTIVE ) .
 .It Fn if_resolvemulti
 Check the requested multicast group membership,
 .Fa addr ,
@@ -437,6 +455,12 @@ Flags of the former kind are marked
 .Aq S
 in this table; the latter are marked
 .Aq D .
+Flags which begin with
+.Dq IFF_DRV_
+are stored in
+.Va if_drv_flags ;
+all other flags are stored in
+.Va if_flags .
 .Pp
 The macro
 .Dv IFF_CANTCHANGE
@@ -466,7 +490,7 @@ The interface is a loopback device.
 The interface is point-to-point;
 .Dq broadcast
 address is actually the address of the other end.
-.It Dv IFF_RUNNING
+.It Dv IFF_DRV_RUNNING
 .Aq D*
 The interface has been configured and dynamic resources were
 successfully allocated.
@@ -485,7 +509,7 @@ This interface is in the permanently promiscuous mode (implies
 .It Dv IFF_ALLMULTI
 .Aq D*
 This interface is in all-multicasts mode (used by multicast routers).
-.It Dv IFF_OACTIVE
+.It Dv IFF_DRV_OACTIVE
 .Aq D*
 The interface's hardware output queue (if any) is full; output packets
 are to be queued.

From fdba687e8e3e2858e2c24faf056bc66fff17f145 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Wed, 20 Jan 2010 15:13:38 +0000
Subject: [PATCH 1239/2592] MFC 198344: 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.

---
 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 dc657f6117e57a7836689ab9a83d2ab1162b5084 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Wed, 20 Jan 2010 15:22:34 +0000
Subject: [PATCH 1240/2592] MFC r198429, r198439, r198468, r201209, r201822,
 r201882: Syncronize iwn(4) driver in stable/8 with HEAD.

Approved by:	rpaulo
---
 sys/conf/files                                |   76 +-
 sys/contrib/dev/iwn/LICENSE                   |   78 +-
 .../dev/iwn/iwlwifi-1000-128.50.3.1.fw.uu     | 5920 ++++++++++++
 .../dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu    |    0
 .../dev/iwn/iwlwifi-4965-228.61.2.24.fw.uu    | 3339 +++++++
 .../dev/iwn/iwlwifi-4965-4.44.17.fw.uu        | 3398 -------
 .../dev/iwn/iwlwifi-5000-5.4.A.11.fw.uu       |    0
 .../dev/iwn/iwlwifi-5000-8.24.2.12.fw.uu      | 6239 +++++++++++++
 .../dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu       | 5961 ++++++++++++
 .../dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu      | 8112 +++++++++++++++++
 sys/dev/iwn/if_iwn.c                          | 7696 ++++++++++------
 sys/dev/iwn/if_iwnreg.h                       | 1495 ++-
 sys/dev/iwn/if_iwnvar.h                       |  165 +-
 sys/modules/iwnfw/Makefile                    |   12 +-
 sys/modules/iwnfw/Makefile.inc                |   13 +
 sys/modules/iwnfw/iwn1000/Makefile            |    6 +
 sys/modules/iwnfw/iwn4965/Makefile            |    6 +
 sys/modules/iwnfw/iwn5000/Makefile            |    6 +
 sys/modules/iwnfw/iwn5150/Makefile            |    6 +
 sys/modules/iwnfw/iwn6000/Makefile            |    6 +
 20 files changed, 35767 insertions(+), 6767 deletions(-)
 create mode 100644 sys/contrib/dev/iwn/iwlwifi-1000-128.50.3.1.fw.uu
 create mode 100644 sys/contrib/dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu
 create mode 100644 sys/contrib/dev/iwn/iwlwifi-4965-228.61.2.24.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-5000-8.24.2.12.fw.uu
 create mode 100644 sys/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu
 create mode 100644 sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu
 create mode 100644 sys/modules/iwnfw/Makefile.inc
 create mode 100644 sys/modules/iwnfw/iwn1000/Makefile
 create mode 100644 sys/modules/iwnfw/iwn4965/Makefile
 create mode 100644 sys/modules/iwnfw/iwn5000/Makefile
 create mode 100644 sys/modules/iwnfw/iwn5150/Makefile
 create mode 100644 sys/modules/iwnfw/iwn6000/Makefile

diff --git a/sys/conf/files b/sys/conf/files
index c1c8b7713c2..77a1b344e4f 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1079,20 +1079,76 @@ 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}" \
+iwn1000fw.c			optional iwn1000fw | iwnfw		\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk iwn1000.fw:iwn1000fw -miwn1000fw -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		"iwn1000fw.c"
+iwn1000fw.fwo			optional iwn1000fw | iwnfw		\
+	dependency	"iwn1000.fw"					\
+	compile-with	"${LD} -b binary -d -warn-common -r -d -o ${.TARGET} iwn1000.fw" \
 	no-implicit-rule						\
-	clean		"iwnfw.fwo"
-iwn.fw			optional iwnfw					\
+	clean		"iwn1000fw.fwo"
+iwn1000.fw			optional iwn1000fw | 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-1000-128.50.3.1.fw.uu" \
 	no-obj no-implicit-rule						\
-	clean		"iwn.fw"
+	clean		"iwn1000.fw"
+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		"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		"iwn4965fw.fwo"
+iwn4965.fw			optional iwn4965fw | iwnfw		\
+	dependency	".PHONY"					\
+	compile-with	"uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-4965-228.61.2.24.fw.uu" \
+	no-obj no-implicit-rule						\
+	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-8.24.2.12.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"
+iwn6000fw.c			optional iwn6000fw | iwnfw		\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk iwn6000.fw:iwn6000fw -miwn6000fw -c${.TARGET}" \
+	no-implicit-rule before-depend local				\
+	clean		"iwn6000fw.c"
+iwn6000fw.fwo			optional iwn6000fw | iwnfw		\
+	dependency	"iwn6000.fw"					\
+	compile-with	"${LD} -b binary -d -warn-common -r -d -o ${.TARGET} iwn6000.fw" \
+	no-implicit-rule						\
+	clean		"iwn6000fw.fwo"
+iwn6000.fw			optional iwn6000fw | iwnfw		\
+	dependency	".PHONY"					\
+	compile-with	"uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu" \
+	no-obj no-implicit-rule						\
+	clean		"iwn6000.fw"
 dev/ixgb/if_ixgb.c		optional ixgb
 dev/ixgb/ixgb_ee.c		optional ixgb
 dev/ixgb/ixgb_hw.c		optional ixgb
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-1000-128.50.3.1.fw.uu b/sys/contrib/dev/iwn/iwlwifi-1000-128.50.3.1.fw.uu
new file mode 100644
index 00000000000..6e7de6131ed
--- /dev/null
+++ b/sys/contrib/dev/iwn/iwlwifi-1000-128.50.3.1.fw.uu
@@ -0,0 +1,5920 @@
+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-1000-128.50.3.1.fw.uu
+AQMygLA0AABE4wEAAMAAAHC5AQAAwAAAAAAAACAggA8AAEAAaSAAAGkgQABpIAAAaSBAACAggA8A
+AOgAaSAAAGkgQABpIAAAaSBAACAggA8AAIgFaSAAAGkgQABpIAAASiAAAEohAABKIgAASiMAAEok
+AABKJQAASiYAAEonAABKIAAQSiEAEEoiABBKIwAQSiQAEEolABBKJgAQSicAEEogACBKIQAgSiIA
+IEojACBKJAAgSiUAIEomACBKJwAgSiAAMEohADAKJIA/gAAAwEEsnDBALJwwQiQcNAoigD+AAERZ
+CiMANwYPAABKJgBwaSBAAEomAHBKJgBwSiYAcEomAHAAFgBwgAB0BEB4ICBAhwAAAAAAAAAAAAAK
+yM9xoADIHw4ZGIALyA8ZGIAMyBAZGIANEgI2AMhEeBEZGIAOyC0ZGIDgfuHE/BzIvvwcSL7hwOHB
+4cLhw/wcCLH8HEix/ByIsfwcyLH8HAiy/BxIsvwciLL8HMiy/BwIv2okgBDhxGokwBDhxPHAz3Cg
+ANAbFIDPcYAAcAQEIICPz1EE4QChCvIvKQEAz3CAAGAJ8CBAAEB42v/RwMHEayTAEMHEaySAEMHE
+n3QEFAs0BBQKNAQUCTQEFAg0BBQHNAQUBjQEFAU0BBQENMHDwcLBwcHAwcRFLH4QCiZAfsHEaySA
+FMHEICBAhwrIh7gKGhgwC8ibuAsaGDAMyAwaGDANyIe4DRoYMA7IhSDDDw4aGDDgfuB48cAKyJW4
+ChoYMAvIm7gLGhgwDciKuI24kLgNGhgwz3CAAIgKGIiB4Av0DcjPcQAAbAqsuA0aGDCuDSAAD9jR
+wOB+4HjPcIAARJsAgIYg/oEI9A3IBSCADwAAANQNGhgwRPHgePHAz3EDAEANz3CgAKggLaDPcoAA
+sAQgggFpAKLeDCABSNjPcIAAxAglgCOBIIHHcQAAiBOGDMAH0fHgeM9wgADECBUEwAfgePHA4gtA
+AYDgz3aAAHAEBvKB4Ab0AdgD8ADYC66A4QbygeEG9AHYA/AA2AqugOIG8oHiBvQB2APwANgMrgDY
+z3WgAMgfGB0YkAuOgOCKIRAADvIIjoDgDPLPcAMAQA1FHRgQMKUC2BgdGJAD8DGlCo6A4BryCY6A
+4Bbyz3ABAETjIB0YkM9wgAAoACEdGJDPcIAAbAQiHRiQGBUAlkUgAAMYHRiQDI6A4AfyGBUAloUg
+AQQYHRiQgOMY8gDYlLjPdoAApAQApnHYBrg6D+AA/Nkghs9wAABMHCoP4ACfuRgVAJaFuBgdGJBl
+A0ABz3Gqqru7z3CfALj/NqA2oDagNqDPcaAAyDsOgYi4DqFpIEAA/vHgePHApcFBwELBDBwAMRAc
+QDHPcYAAfFo0GcAPMBkADywZwA4oGYAOJBlADs9wgAB8WiAYQAvPcIAAfFocGAALz3CAAHxaGBjA
+Cs9wgAB8WhQYgArPcIAAfFoQGMAIz3CAAHxaDBiACM9wgAB8WggYQAjPcYAAAFqAGQAIfBnAB3gZ
+gAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZQAVQGQAFTBnABEgZgAREGUAEQBkA
+BO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlAARAZAAFjoWogAAPYGQAAaiDAAtQZ
+AABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGoggAC8GQAAaiBAALgZAABqIAAAtBkA
+AGoggAHMGQAA0NifuM9xnwC4/x2hz3CAAAAAxIBTJcQ1UybFNde6AebTvsSgUyPABAUmjh/Q/gAA
+1qEFIIAPsP4AABahGIFTJ841AN2UuBihQMMBwALByXMMFAYwSgpgARAUBzDPcKAAtA+8oE4LQAGG
+DeAAqXAI2ADZSg3gAJm5FvHgePHA8ghgAXvYyglgAdfZz3GAAHxaNBnADzAZAA8sGcAOKBmADiQZ
+QA7PcIAAfFogGEALz3CAAHxaHBgAC89wgAB8WhgYwArPcIAAfFoUGIAKz3CAAHxaEBjACM9wgAB8
+WgwYgAjPcIAAfFoIGEAIz3GAAABagBkACHwZwAd4GYAHdBlAB3AZAAdsGQAHaBmABmQZQAZgGQAG
+XBnABVgZgAVUGUAFUBkABUwZwARIGYAERBlABEAZAATvoc6hraGMoSwZwAIoGYACJBlAAiAZAAIc
+GcABGBmAARQZQAEQGQABY6FqIAAD2BkAAGogwALUGQAAaiCAAtAZAABqIEAByBkAAGogAAHEGQAA
+aiDAAMAZAABqIIAAvBkAAGogQAC4GQAAaiAAALQZAABqIIABzBkAAOt2z3WgAMgfGRURls9wAABE
+HN4IIAEKIMAvWnDPcIAAZBYjgM9znwC4/893gAAAAASHgOEB4NO4JPIZFQKWUSLAgB7yXYNA3p++
+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
+AACfBQXY4fMgwAAcBDCE4Mohyw/KIssHyiOLDwAAowWmB+v/yiBrAYbgAdnCIUoAz3CAAM4GIKih
+wNHA4H7gePwciLb8HEi2/BwItvwcyLX8HIi1/BxItfwcCLX8HMi0/ByItPwcSLT8HAi0/BzIs/wc
+iLP8HEiz4H7geATcON018OB4BNw03TPw4HgE3DDdMfDgeATcLN0v8OB4BNwo3S3w4HgE3CTdK/Dg
+eATcIN0p8OB4BNwc3Sfw4HgE3BjdJfDgeATcFN0j8OB4BNwQ3SHw4HgE3AzdH/DgeATcCN0c8OB4
+BNwE3RnwNBQaMDAUGTAsFBgwKBQXMCQUFjAgFBUwHBQUMBgUEzAUFBIwEBQRMAwUEDACxwHGsCRN
+M7AkHzPgfvHASg/P/89zgABUEEODAN/PdaAALCCwhdJq1H5+ZqWmBKYB4owiAoAmpkOjhfcCg+Oj
+AeACo30Hz//geADYz3GgAMgfGKEZoQHYDqHgfuB48cD6Du//OXEZcshx6HIB3c92oADIH7OmBd/P
+dYAAwA/gpQGlBMBIpQmlFYYnpQqlGIYYHUARC6UZhhQdABEMpaAWABBkpQ2lpBYAEAwdABIOpagW
+ABAIHUASD6XPcAEAMoAQpZ4Pr/8k2AQggA8AAAD4EaWOD6//ANgSpVMnwHUTpQHIVB0AFxalEhYA
+llAdABcXpRMWAJbPcoAAwA8YpRQWAJZKJEB5GaUVFgCWANkapSQWAJYbpRYWAJYcpc9wgAAoDxCA
+HaXPcIAAwA94GIAKz3CAAMAPfBjACs9wgAA8EAQYAAuEGkALz3CgAMgcCICIGgAAqCCAAvAiQwDP
+cJ8AuP8B4XagWQbP/+B+4HjgfuB44H7geOB+4HgA2Za5z3CgAKwvPKDgfuB48cChwYtwCgyv/wHZ
+QNjmD6//QMC+C4//ocDRwOB+4HjxwAohwA/rcgXYMNuKJMMP1QKv/rhz4HjgfuB44H7geOB+4Hjg
+fuB44H8B2OB+4HjgfuB44H8B2PHAag3P/6/BCHcA3s9woABkLvAg0gMZEhA2GRrYM/XYBbh6Ca//
+6XEZyM91oADUBxodGJAPFRGWGRUAloDgLPLA5kX3GRUOlvzxABYAQAAWBUAAHEAxIMCc4D/0gcBa
+C6//DtkjwGG4Y8AMwIDgDvLPcZ8AuP8aoS3AG6EDwB6hz3AAbAQAGaEPHViUTg7ABQ8VEZbPcKAA
+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
+4H7geOB+4HjgfuB44H7geOB+4HjgfwDY4H8A2OB+4HihweB/ocDgeOB+4HjxwOHFAcjPdYAAZDIA
+pQRtUggv8wLZz3GADgQA7HAgoO4O7/IAhXUCT/PgeOB+4HjgfuB48cAAFgBBz3KAAGQyBrIAFgVB
+QCIBBA4aRAFMJYCEyiHCD8oiwgfKIGIByiOCDwAARAD0BuLxyiQiAADaB/AAFgBBFCGMAAC0AeIv
+IEIBEHK39qIPz/LRwOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjPcIAA
+XAjgfwCA4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB/AdjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB48cDhxc91gACkMqlw0g7v8gPZABWFEEQl
+QAGF4MohwQ/KIsEHyiBhAcojgQ8AAE8ApAXh8cokYQABjYPgw/ZjuAGtYg7P8tEAT/PgePHAUghP
+889ygACkMmCKUSMAgDfyz3OAAGQIoIuA5cwhIYAv8oHgB/TPcIAAnIihgALwAN2O5QT3gOUD9ADd
+z3eAAJyIGI+A4AP0gOUD9ADeA/CihwTez3CAAIgKGIiD4MwgIoHMIOKBzCAiggn0CpIQdQn0C5IQ
+dswhIYAD9ADYD/AB2M9xoADIHw2hqrLLskGLBL7FfRC6pXp/GZiAHQBP8+B48cCuDy/zCHEA39X/
+gOAs8iDdz3agAMgfsKYy2EMeGBAA2DoN7/KNuLGmsKYe2EMeGBAA2CYN7/KNuLGmfxYAls9ygABk
+CDC4IYrEuDBwAdnCIUoAgOAgqsb27aaB4QT0BNgBqrEHD/PPcIAApDIAiFEggIAH8s9xoADAHQCB
+gLgAoeB+z3CAAKQyAIhRIICAB/LPcaAAwB0AgaC4AKHgfvHA4cWhwc9wgAC8CACQz3WAACSkqXGK
+IgQKLg0v8wHbgOAP9AohwA/rcgXYz3MAAJ0LSiQAABEE7/EKJQABAI2E4Mohyw/KIssHyiBrAcoj
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAA
+AAAAwACQANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAACAAAAHz7AAB4+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGIeAANBLAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAADyHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgAA
+AAYACAAJAAAABwAAAAAAAAAAAAAAAAAAAAIAAAACAAAAgwAAAJIAAADoAAAA9wAAAE4BAABdAQAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAXJiAAMShAQAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAPR8gABAtQEAAAAAAAAAAAAAAAAAAAAAAPR8gAAAvAEAAAAAAAAAAAD0fIAA
+bL0BAAAAAAAAAAAAAAAAAPR8gAAAAAAAAAAAAAAAAAD/AAAAAAcAAAAAAAAAAAAAAAAAAAB/fwAB
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgQIAAgQIAEAAAAAAAAAAAAAAAEA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAcAABUAAAAUG4AAUAoAAFAKAABQCgAAUAoA
+AFAKAABQCgAAUAoAAFAKAABQCgAAUAoAAFAKAABQCgAAUAoAAFAKAABQCgAAUAoAAFAKAABQCgAA
+UAoAAFAKAABQCgAAUAoAAFAKAABQCgAAUAoAAFAKAABQCgAAUAoAAFAKAABQCgAAUAoAAHQLAAAA
+AAAA1BUBAFAKAACYCAAAUAoAAFAKAABQCgAAwAgAAMz9AACITgAAUAoAAFAKAAD4CAAA+AgAAPgI
+AAD4CAAA+AgAAPgIAAD4CAAAUAoAAFAKAABQCgAAUAoAABwKAABQCgAAUAoAAFAKAABQCgAAUAoA
+AHgLAABQCgAAUAoAAHwIAAADAAAA/MIBAAIAAADIIAEABAAAALQwAAAGAAAArMQBABEAAABYnAEA
+BwAAAMC3AQAIAAAALMUBAAwAAAAkNwEADQAAADw7AQAOAAAAdDsBABYAAAA8FQEACwAAADBPAQAU
+AAAApE8AAA8AAAAkXgAAEAAAAAQNAQABAAAAnLMBABIAAAAQYwEAEwAAAGxUAQAFAAAAxGAAABUA
+AAA02AEAFwAAAHQLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAGCQAABgkAAAYJAAAJDIAABgkAAAYJAAAGDIAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgk
+AAAYJAAAGCQAABAaAAC4GwAAyBsAAEAdAADIHQAARB0AABgkAAAYJAAAqDoAAAQ+AADYPgAAGCQA
+ABgkAAAYJAAAbDkAAHiqAAB0qgAAsKoAABgkAAAYJAAAGCQAACgyAAAYJAAAGCQAABgkAAAYJAAA
+GCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAY
+JAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgk
+AAAYJAAAGDMAABgkAAAYJAAAGCQAABgkAAAYJAAA/DMAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQA
+ABgkAAAYJAAAGCQAABgkAAAYJAAA1DAAABgkAAD0MAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAA
+GCQAABgkAAC8YQAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAD8
+TQEAhFEBABgkAAC4NwEAGCQAACQ5AQCwKQEAGCQAABgkAABUPwAAGCQAABgkAAAYJAAAGCQAABgk
+AAD8ogEA2J0BABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAABExAEASMQBABgkAAAYJAAAGCQA
+ABgkAAAYJAAAGCQAAIy3AQAYJAAAWLoBABgkAACE2QEAGCQAAOwgAADwIAAAGCQAABgkAAAExgEA
+qE8AABgkAAAYJAAAGCQAABSyAQAYJAAAGCQAAOQNAQBYVAEAGCQAABgkAAAYJAAA3FsBACwlAQAY
+JAAAGCQAABgkAAAYJAAAGCQAABgkAAB4bgEAGCQAABDFAQAUxQEAIMUBACTFAQAYxQEAHMUBACjF
+AQAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAsQQAAGCQAABgkAAAYJAAAGCQA
+ABgkAACAxAEAtMQBADA2AAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAA
+GCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAY
+JAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAAGCQAABgkAAAYJAAA1DYAAFQ3
+AADcNwAAeDgAAMRcAABQOAAAGCQAABgkAAAYJAAAGCQAABgkAADMNgAA0DYAABgkAAAYJAAAhD8A
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAIAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOED
+Dh7h4QMOHuHBAgoe4YEFDB7hAAAAAAAAAAAAAOEDDh7h4QMOHuHBAgYe4YEFDB7hwQIGHuGBBQwe
+4cECBh7hgQUMHuHBAgYe4YEFDB7hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBDQ0NDQ0NDQ0NDQ0NDQ0NDQMDAwMDAwMDAwMD
+AwMDAwMAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQ0NDQ0NDQ0NDQ0NDQ0NDQ0DAwMD
+AwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQENDQ0NDQ0NDQ0NDQ0N
+DQ0NAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAACRAgAAMcovAJECAAAxyi8AkQIAADHK
+LwCRAgAAMcovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAJECAAAxyi8AQwEAADHKLwBDAQAAMcov
+AEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEANAADeAwkA
+AAAAAAAAAAAAAAAAgPQAAAEAAADUGoAAAAAAAAAAAAAAAAAAEPUAABUAAAAUG4AAgICAgICAgIAB
+gAKAgICAgAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQagADUGoAApCCgADggoAABAAAA/P///wAAAAAAAAAA
+9BqAAPQagACoIKAAPCCgAAgAAADz////AAAAAAAAAAAUG4AAFBuAAKwgoABsIKAAMAAAAM////8A
+AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAA+A0BAAUA
+AAAUG4AAJBMBAAD/AwBEEwEAAP8FADAUAQAA/y0AVBQBAAD/PQAMFAEAAP8EAPATAQAA/yUAUBoB
+ACQbAQCMGwEAFBcBAIwWAQBMHAEArBwBAPAcAQA0HQEAAAAAACwBAABeAQAAAQAAAAEAAAABAAAA
+AQAAAAMAAAAAAAAAAAAAAAAAAAADAAAAAgAAAAMAAAADAAAAAwAAAAEAAAAAAAAAAQAAAAAAAAAA
+AAAAAAAAACgiAQAKAAAA1BqAAAAAAAAAAAAAAAAAAIgiAQAKAAAA1BqAAAAAAAAAAAAAAAAAAJwi
+AQAKAAAA1BqAAAAAAAAAAAAAAAAAAOgiAQAKAAAA1BqAAAAAAAAAAAAAAAAAALAjAQAKAAAA1BqA
+AAAAAAAAAAAAAAAAAFQjAQAKAAAA1BqAAAAAAAAAAAAAAAAAAOwoAQAGAAAA1BqAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAgAAAAACgABAnAADoAwAA6AMAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQPgEAUD8BAPRBAQCQRAEA9EYBACxKAQDgQAEAIAWAALx8
+gAAYAAAAfHyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREwBAAYAAADUGoAAAAAAAAAAAAAAAAAA3P8A
+AAoAAADUGoAAAAAAAAAAAAAAAAAA3P8AAAoAAADUGoAAAAAAAAAAAAAAAAAA3P8AAAoAAADUGoAA
+AAAAAAAAAAAAAAAA3P8AAAoAAADUGoAAAAAAAAAAAAAAAAAA3P8AAAoAAADUGoAAAAAAAAAAAAAA
+AAAA3P8AAAoAAADUGoAAAAAAAAAAAAAAAAAA3P8AAAoAAADUGoAAAAAAAAAAAAAAAAAA3P8AAAoA
+AADUGoAAAAAAAAAAAAAAAAAA3P8AAAoAAADUGoAAAAAAAAAAAAAAAAAA3P8AAAoAAADUGoAAAAAA
+AAAAAAAAAAAA3P8AAAoAAADUGoAAAAAAAAAAAAAAAAAA3P8AAAoAAADUGoAAAAAAAAAAAAAAAAAA
+nFIBAAoAAADUGoAA/////wAAAAD/////AAAAAAAAAAAAAAAA6FMBAAUAAAAUG4AAZABkAGkA3ADI
+AFoAqgC+AIYBfQA+AGQAZABpANwAyABaAKoAvgCGAX0APgAAAAAAAQEAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAABAgEBAAIBAAECAgIAAQEAAgECAQIAAgABAgMAAAAA4G0BAOx6AQC4iIAAQAUAAAAA
+AADgbQEADG8BAPiNgAAgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARH8BAEh9AQAYj4AAVAAA
+AAAAAADgbQEAeH0BAJiPgABQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA4G0BAPB5AQAoJYAA
+UAEAAAAAAABYfwEAAHwBANAGgAACAAAAAAAAAOBtAQAsfAEA1AaAAAQAAAAAAAAAMH8BAAxvAQBs
+j4AALAAAAAAAAADgbQEAmHwBAAAAAAAAAAAAAAAAAOBtAQBYfAEA2AaAAAQAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHACAAIAAhACIAIgAjACQAJAAl
+ACYAJgBDAEQARABFAEYARgBHAEgASABJAEoASgBLAEwATABNAE4ATgBPAFAAUABRAG4AbgBvAHAA
+cABxAHIAcgBzAHQAdAB1AHYAdgB3AHgAeAB4AHgAeAB4AHgAeAB4AA8APwAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAABAAEAAgADAAMABAAFAAUABgAHAAcACAAJAAkACgAjACMAJAAlACUA
+JgAnACcAKAApACkARgBHAEcASABJAEkAZgBnAGcAaABpAGkAagBrAGsAbABtAG0AbgBvAG8AcABx
+AHEAcgBzAHMAdAB1AHUAdgB3AHcAeAB4AHgAeAB4AHgAeAB4AA4APwAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHACAAIAAhACIAIgAjACQAJAAlACYAJgBD
+AEQARABFAEYARgBHAEgASABJAEoASgBLAEwATABNAE4ATgBPAFAAUABRAG4AbgBvAHAAcABxAHIA
+cgBzAHQAdAB1AHYAdgB3AHgAeAB4AHgAeAB4AHgAeAB4AA8AQwAAAAAAAAAAAAAAAAAAAAAAAAAB
+AAEAAgADAAMABAAFAAUABgAHAAcACAAJAAkACgAjACMAJAAlACUAJgAnACcAKAApACkARgBHAEcA
+SABJAEkAZgBnAGcAaABpAGkAagBrAGsAbABtAG0AbgBvAG8AcABxAHEAcgBzAHMAdAB1AHUAdgB3
+AHcAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AAgAQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHACAAIAAhACIAIgAjACQAJAAlACYAJgBDAEQARABF
+AEYARgBHAEgASABJAEoASgBLAEwATABNAE4ATgBPAFAAUABRAG4AbgBvAHAAcABxAHIAcgBzAHQA
+dAB1AHYAdgB3AHgAeAB4AHgAeAB4AHgAeAB4AA8AQwAAAAAAAAAAAAAAAQABAAIAAwADAAQABQAF
+AAYABwAHAAgACQAJAAoAIwAjACQAJQAlACYAJwAnACgAKQApAEYARwBHAEgASQBJAGYAZwBnAGgA
+aQBpAGoAawBrAGwAbQBtAG4AbwBvAHAAcQBxAHIAcwBzAHQAdQB1AHYAdwB3AHgAeAB4AHgAeAB4
+AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AAQAPwBUWgEAEtIAAAAAAAD//w8ACHgBALYAAAAAAAAA
+/wAAAAh4AQC3AAAAAAAAAP8AAAAIeAEAuAAAAAAAAAD/AAAACHgBALkAAAAAAAAA/wAAAAh4AQC6
+AAAAAAAAAP8AAAAIeAEAuwAAAAAAAAD/AAAACHgBAL0AAAAAAAAA/wAAAAh4AQC+AAAAAAAAAP8A
+AAAIeAEAvwAAAAAAAAD/AAAACHgBAMAAAAAAAAAA/wAAAAh4AQDBAAAAAAAAAP8AAAAIeAEAwgAA
+AAAAAAD/AAAAVFoBABPSAAAAAAAA//8PAAh4AQAbAQAAAAAAAP8AAAAIeAEAHAEAAAAAAAD/AAAA
+CHgBAB0BAAAAAAAA/wAAAAh4AQAeAQAAAAAAAP8AAAAIeAEAHwEAAAAAAAD/AAAACHgBACABAAAA
+AAAA/wAAAAh4AQAiAQAAAAAAAP8AAAAIeAEAIwEAAAAAAAD/AAAACHgBACQBAAAAAAAA/wAAAAh4
+AQAlAQAAAAAAAP8AAAAIeAEAJgEAAAAAAAD/AAAACHgBACcBAAAAAAAA/wAAAFRaAQAU0gAAAAAA
+AP//DwAIeAEAggEAAAAAAAD/AAAACHgBAIMBAAAAAAAA/wAAAAh4AQCEAQAAAAAAAP8AAAAIeAEA
+hQEAAAAAAAD/AAAACHgBAIYBAAAAAAAA/wAAAAh4AQCHAQAAAAAAAP8AAAAIeAEAiQEAAAAAAAD/
+AAAACHgBAIoBAAAAAAAA/wAAAAh4AQCLAQAAAAAAAP8AAAAIeAEAjAEAAAAAAAD/AAAACHgBAI0B
+AAAAAAAA/wAAAAh4AQCOAQAAAAAAAP8AAABUWgEACNIAAAAAAAD//wMAdFoBAACCAAAAAAAA/wEA
+AHRaAQABggAAAAAAAP8BAABUWgEACdIAAAAAAAD//wMAdFoBAAKCAAAAAAAA/wEAAHRaAQADggAA
+AAAAAP8BAABUWgEACtIAAAAAAAD//wMAdFoBAASCAAAAAAAA/wEAAHRaAQAFggAAAAAAAP8BAABU
+WgEABtIAAAAAAAD/AQAAVFoBAAfSAAAAAAAA/wMAAFRaAQAG0gAACQAAAAD+AwBUWgEAB9IAAAoA
+AAAA/A8AVFoBAAbSAAASAAAAAAD8B1RaAQAH0gAAFAAAAAAA8D9UWgEAFdIAAAAAAAD/AwAAVFoB
+AAzSAAAAAAAA/wEAAFRaAQAV0gAACgAAAAD8DwBUWgEADNIAAAkAAAAA/gMAVFoBABXSAAAUAAAA
+AADwP1RaAQAM0gAAEgAAAAAA/AcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAc0g3SEdIQ0gLSAdID0hvSC9IAgAXSEtIT0hTSBEMG0gfSBNIJEHDStQAaAYEBBQAEAAYACAAJ
+AAoACwAMAIMAkgDoAPcATgFdAQ8ALgAAAGwAAAB0AAAAgAAAAIwAAACdAAAABwAAAAQAAAAIAAAA
+EAAAAEAAAACAAAAAIAAAAAAAAAAJAAAAEgAAAAAAAAAKAAAAFAAAACAFgAC8fIAAGAAAAHx8gAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAABonwEABgAAANQagAAAAAAAAAAAAAAAAAAQtQEABgAAANQagAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAFgAC8fIAA
+GAAAAHx8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAIAWAALx8gAAYAAAAfHyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqMABAAQA
+AADUGoAAAAAAAAAAAAAAAAAAyL8BAAQAAADUGoAAAAAAAAAAAAAAAAAATMEBAAYAAADUGoAAAAAA
+AAAAAAAAAAAAyL8BAAQAAADUGoAAAAAAAAAAAAAAAAAAqMABAAQAAADUGoAAAAAAAAAAAAAAAAAA
+yL8BAAQAAADUGoAAAAAAAAAAAAAAAAAAqMABAAQAAADUGoAAAAAAAAAAAAAAAAAAyL8BAAQAAADU
+GoAAAAAAAAAAAAAAAAAATMEBAAYAAADUGoAAAAAAAAAAAAAAAAAAyL8BAAQAAADUGoAAAAAAAAAA
+AAAAAAAAqMABAAQAAADUGoAAAAAAAAAAAAAAAAAATMEBAAYAAADUGoAAAAAAAAAAAAAAAAAAqMAB
+AAQAAADUGoAAAAAAAAAAAAAAAAAAqMABAAQAAADUGoAAAAAAAAAAAAAAAAAATMEBAAYAAADUGoAA
+IAWAALx8gAAYAAAAfHyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUBQAAAAAAAAAAAAAAAAAAAAAA/wD/AAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAQE
+BAQFBgcICAgICAkKCwwNAAAABQYHCA0ODxAVFhcYGQAACg0RFAoNERQKDREUCgoAAAAAAAAGBgYG
+CQkJCQAGAABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluOGg4YjhcOG43aDdiN1w3biloKWIpXClu
+KGgoYihcKG4naCdiJ1wnbhloGWIZXBluGGgYYhhcGG4XaBdiF1wXbgloCWIJXAluCGgIYghcCG4H
+aAdiB1wHbgZoBmIGXAZuBWgFYgVcBW4EaARiBFwEbgNoA2IDXANuAmgCYgJcAm4BaAFiAVwBbgBo
+AGIAXABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluOGg4YjhcOG43aDdiN1w3biloKWIpXCluKGgo
+YihcKG4naCdiJ1wnbhloGWIZXBluGGgYYhhcGG4XaBdiF1wXbgloCWIJXAluCGgIYghcCG4HaAdi
+B1wHbgZoBmIGXAZuBWgFYgVcBW4EaARiBFwEbgNoA2IDXANuAmgCYgJcAm4BaAFiAVwBbgBoAGIA
+XABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluOGg4YjhcOG43aDdiN1w3bjZoNmI2XDZuNWg1YjVc
+NW40aDRiNFw0bjNoM2IzXDNuMmgyYjJcMm4xaDFiMVwxbjBoMG4iaCJiIlwibiFoIWIhbhNoE2IT
+XBNuEmgSYhJcEm4RaBFiEVwRbgNoA2IDXANuAmgCYgJcAm4BaAFiAVwBbgBoAGIAXABcAFwAXAAA
+G0EAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABA
+AEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAA
+QABAAEAAQABAAEAAQABAAEAAQABAAEAAQAFBAEABQAFBAEABQAFAAUEBQQFBAUEBQQFBAUEBQQFB
+AUEBQQFBAUEBQQFBAUEBQQFBAUEBQQFBAUIBQQBCAEIAQgBCAEIAQgBCAEIAQgBCAEIAQgBCAEIA
+QwBDAEIAQgBCAEIAQwBDAEMAQwBDAEMARABDAEQAQwBEAEQARABEAUQBRAFEAUQBRQFEAUUBRQFE
+AUUBRQFEAUUBRQFFAUUBRQFFAUUBRQFFAUUBRgFGAUYBRgFHAUYBRwFHAkcBRwJHAkcCSAJHAkgC
+SAJIAkgCSAJIAkgCSAJJAkgCSQJJAkkCSQJJAkkCSgJKAkoCSgJKAkoCSwJKAksCSwJLAksCTAJM
+AkwCTAJNAk0CTQJNAk4CTgJOAk4CTwJOAk8CTwJPAk8CUAJQAlACUANRAlECUgNRA1ICUgNSA1IC
+UwJTAlQCUwJVAlQCVQJVAlYCVgJWAlYCVwJXAlgCVwFZAlgBWgFZAVoBWgFbAVsAWwBbAFwAXABd
+AFz/XQBd/17/Xv9e/17/X/9f/2D/YP5g/2D+Yf5h/mL+Yf1j/mP9ZP1k/Gb9Zfto+2f6afpo+Wr5
+avhr+Wr4a/hr92z4bPZt9231bfZt9W31bfVt9W31bPVt9Wv1bPVr9Wv1avVq9Wn1avVp9Wn1aPVo
+9Wf1aPVn9Wf1ZvVm9WX1ZvZl9mX2ZPZk9mT2ZPZj9mP2YvZj9mL2YvZh9mH2YfZh9mD2YPZf9mD2
+X/Zf9l72X/Ze9l72XfZe9l32XfZc9l33XPZc91v3W/db91v3Wvda91r3WvdZ91n3WfdZ91j3WPdY
+91j3V/dY91f3V/dW91f3VvdW91X3VvdV91X3VfdV91T3VPdU91T3U/dT91P3U/dS91P4UvdS+FL4
+UvhR+FH4UfhR+FD4UfhQ+FD4UPhQ+E/4T/hP+E/4TvhP+E74TvhO+E74TfhO+E34TfhN+E34TPhM
++Ez4TPhM+Ez4S/hL+Ev4S/hL+Ev4SvhK+Er4SvhK+Er4SfhJ+En4SfhJ+En5SPlI+Uj5SPlI+Uj5
+R/lH+Uf5R/lH+Uf5RvlG+Ub5RvlG+Ub5RflG+UX5RflF+UX5RflF+UT5RPlE+UT5RPlE+UP5RPlD
++UP5Q/lD+UP5Q/lC+UL5QvlC+UL5QvlC+UL5QflB+UH5QflB+UH5QPlB+UD5QPlA+UD5QPlAAAAA
+AAAAAAAAAAAAdNsBAAgAAAAUG4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAA/////////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/////////////////////////////
+/////////////////////////////////////////////////wEEAAACBQEAAwYCAAQHAwAFCAQA
+BgkFAAcKBgAICwcACQwIAAoNCQALDgoADA8LAA0QDAAOEQ0AAUEABAJCAQQDQwIEBEQDBAVFBAQG
+RgUEB0cGBLcTIgC4FCMAuRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgcAQALHQIADB4DABAf
+BAAiIQUAJCIGACYjBwAoJAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsPAEAsEABkLhEAaC8S
+AGwwEwBwMRQAdDIVAHgzFgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0AmTweAJ09HwChPiAA
+pT8hACRJBgIsSgoCNEsNATxMDwFkTREBbE4TAXRPFQF8UBcBhFEZAZVSHQGdUx8BAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFggWFhYMFhYWFhYWFhAAAAAADwA/AAEAAAAPAD8AAQAA
+AA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAIAAAAPAD8AAQAAAAAAAAABAAAA
+AgAAAAMAAAAAAAAABAAAAAIAAAAFAAAAMoABpQA8ODQwLCgkIBwYFBAMCAQADAgEADw4NDAsKCQg
+HBgUEAwIBAIAFQ8bAAAAIQAAAAIAAAIAAAAAAQEAAQIBAQEBAQEBAQEBAQICAgICAgICAwMDAwMD
+AwMEBAQEBAQEBAECAgICAgIDAwMDAwMDAwMDAwMDAwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAA
+AAABAQIBAgIDf/8HDx8/AQMBAw8HAQcPHz9///8FAAcCAwQGBnTRRRfooosuDQ8FBwkLAQMKFDdu
+VVVVAUtoLwFVVVUF4ziOA6qqqgJxHMcBqqqqCsdxHAcoACgAMAAsACwAKAA8ADQAKAAoADQAMAAs
+ACwARAA8AEAAPACMAGwAWABIAPQAsAAsACwAPAA0ADAALABUAEQAVABUAGwAYABcAFQAjAB4ADoB
+AgHVAN8A2gCiAHUAfwBqARoB2QDoAAoBugB5AIgAigUqAzkBqAGKBcoC2QBIAcoBSgHiAPkAygHq
+AIIAmQBm5gAAndiJnU7sxE40SIM0J3ZiJxqkQRoTO7ETERiBEQ/8wA9O7MROJ3ZiJxqkQRoTO7ET
+DdIgDYmd2AkIjMAIB37gBzRIgzQapEEaERiBEQ3SIA0IjMAIBmmQBrCy1QUFVEAFJ3ZiJxM7sRMN
+0iANiZ3YCQZpkAbETuwEBEZgBAM/8AOqqqqqGqRBGhM7sRMP/MAPERiBEQ3SIA0KqIAKEzuxEw/8
+wA8P/MAPDdIgDQu0QAsLtEALiZ3YCQ3SIA0KqIAKCqiACgiMwAgHeIAHB3iABwZpkAYP/MAPDdIg
+DQu0QAsN0iANC7RAC4md2AkIjMAIiZ3YCQiMwAgHfuAHB37gB8EsKQcKqIAKCIzACAd4gAcIjMAI
+B3iABwZpkAawstUFBmmQBrCy1QUFVEAFBVRABdYdxgQNABoAJwA0AE4AaAB1AIIAGgA0AE4AaACc
+ANAA6gAEAScATgB1AJwA6gA4AV8BhgE0AGgAnADQADgBoAHUAQgCDABOAGgAggB1AJwAwwBoAIIA
+ggCcALYAtgDQAJwAwwDDAOoAEQERATgBggCcALYAnAC2ANAA6gDQAOoABAEEAR4BwwDqABEB6gAR
+ATgBXwE4AV8BhgGGAa0BAAAwAAAANgAAAAwAAAASAAAAGAAAACQAAAAGAAAACQAAAAAAAAAAAAAA
+GCAUFA4OFBQFBgECAwQAAAABAQIBAgIDBAwMCAQMBARAAAAAgAAAAAABAAAAAgAAQAAAAAAEAABA
+AAAAQAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vQEFCQ0RFRkdISUpLTE1OT1BR
+UlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+fy0ADyAA8GEAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAKXGhPiZ7o32Df+91rHeVJFQYAMCqc59VhnnYrXmTZrsRY+dH0CJ
+h/oV7+uyyY4L++xBZ7P9X+pFvyP3U5bkW5vCdRzhrj1qTFpsQX4C9U+DXGj0UTTRCPmT4nOrU2I/
+KgwIUpVlRl6dKDChNw8KtS8JDjYkmxs93ybNaU7Nf5/qGxKeHXRYLjQtNrLc7rT7W/akTXZht859
+e1I+3XFelxP1pmi5AAAswWBAH+PIee22vtRGjdlnS3LelNSY6LBKhWu7KsXlTxbtxYbXmlVmlBHP
+ihDpBgSB/vCgRHi6JeNL86L+XcCAigWtP7whSHAE8d9jwXd1r2NCMCAa5Q79bb9MgRQYNSYvw+G+
+ojXMiDkuV5PyVYL8R3qsyOe6KzKV5qDAmBnRnn+jZkR+VKs7gwvKjCnH02s8KHmn4rwdFnatO9tW
+ZE50HhTbkgoMbEjkuF2fbr3vQ6bEqDmkMTfTi/Iy1UOLWW632owBZLHSnOBJtNj6rAfzJc+vyo70
+6UcYENVviPBvSnJcJDjxV8dzUZcjy3yhnOghPt2W3GGGDYUPkOBCfMRxqszYkAUGAfcSHKPCX2r5
+rtBpkRdYmSc6uSc42RPrsyszIrvScKmJB6czti0iPJIVIMlJh/+qeFB6pY8D+FmACRca2mUx18aE
+uNDDgrApd1oRHst7/KjWbTosAAECBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgECAwQAAAUGBwgJCgAAAAUGAAIEAAUAAAAAAAUH
+AQMEAAUBAAAAQCNAJSEhISFAQEBAQAUEBAEBQEBAQAUFQEAMDEANDAwBAQEFQEAFBQAEAARAQAAE
+QEBABUBAQEBABUBAQAUFBQEBAQFABQUFAQUBAUAFBQVABUAFBQUFBQQAAAAcEQAAHDIAABwzAAAE
+AAAAHBUAAAIAFwBsAHAEdAh0DAAEBAYAAAAAAAAAAGQAAAAAkAEACgAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA
+AQAAABAAAAAAAAAAAQAAAAEAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAGzBAQAAAAAAAAQAAGQAAAAH
+BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcG
+BgYGBgUFBQUFBAQEBAQDAwMDAwICAgICAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbFABAHRQAQB8UAEA1FABANxQAQDkUAEAAAolQ8dO
+fJgABxUoWS8AAAAEDgkdLTcAAAQOCR0sOwABEAABAAAAAoAAAUIGAhAAAiAAAAPAAAFDBgMQAALA
+AAADwAABQwYEEAACQAAAAoAAAUQGBREAAEAAAAPAAAFFBgYRAADgAAADwAABRQYHEQABAAAAAoAA
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAICCADwAAQABpIAAAaSBAAGkgAABpIEAAICCADwAA6ABpIAAAaSBAAGkg
+AABpIEAAICCADwAAeAVpIAAAaSBAAGkgAABKIAAASiEAAEoiAABKIwAASiQAAEolAABKJgAASicA
+AEogABBKIQAQSiIAEEojABBKJAAQSiUAEEomABBKJwAQSiAAIEohACBKIgAgSiMAIEokACBKJQAg
+SiYAIEonACBKIAAwSiEAMAokgD+AAADAQSycMEAsnDBCJBw0CiKAP4AAaFMKIwA37g4AAEomAHBp
+IEAASiYAcEomAHBKJgBwSiYAcAAWAHCAAHQEQHggIECHAAAAAAAAAAAAAArIz3GgAMgfDhkYgAvI
+DxkYgAzIEBkYgA0SAjYAyER4ERkYgA7ILRkYgOB+4cT8HMi+/BxIvuHA4cHhwuHD/BwIsfwcSLH8
+HIix/BzIsfwcCLL8HEiy/ByIsvwcyLL8HAi/aiSAEOHEaiTAEOHE8cDPcKAA0BsUgM9xgABwBAQg
+gI/PUQThAKEK8i8pAQDPcIAAhAnwIEAAQHja/9HAwcRrJMAQwcRrJIAQwcSfdAQUCzQEFAo0BBQJ
+NAQUCDQEFAc0BBQGNAQUBTQEFAQ0wcPBwsHBwcDBxEUsfhAKJkB+wcRrJIAUwcQgIECHCsiHuAoa
+GDALyJu4CxoYMAzIDBoYMA3Ih7gNGhgwDsiFIMMPDhoYMOB+4HjxwArIlbgKGhgwC8ibuAsaGDAN
+yIq4jbiQuA0aGDDPcIAApAoYiBsIUQANyM9xAABICqy4DRoYMJYNIAAP2NHA4H7geM9wgABQjwCA
+hiD+gQj0DcgFIIAPAAAA1A0aGDBE8eB48cDPcQMAQA3PcKAAqCAtoM9ygACwBCCCAWkAoiIMIAFI
+2M9wgADoCCWAI4EggcdxAACIE6YLgAfR8eB4z3CAAOgIOQOAB+B48cDqCkABz3aAAHAEBegPCFEA
+AdgC8ADYC64G6Q0JUQAB2APwANgKrgXqDwpRAAHYAvAA2AyuANjPdaAAyB8YHRiQC46KIRAADegI
+jgvoz3ADAEANRR0YEDClAtgYHRiQAvAxpQqOGegJjhfoz3ABAG65IB0YkM9wgAAoACEdGJDPcIAA
+bAQiHRiQGBUAlkUgAAMYHRiQDI4H6BgVAJaFIAEEGB0YkBnrANiUuM92gACkBACmcdgGuJYO4AD8
+2SCGz3AAAEwcig7gAJ+5GBUAloW4GB0YkIECQAHgeM9xqqq7u89wnwC4/zagNqA2oDagz3GgAMg7
+DoGIuA6haSBAAP7x4HjxwKXBQcBCwQwcADEQHEAxz3GAAHxUNBnADzAZAA8sGcAOKBmADiQZQA7P
+cIAAfFQgGEALz3CAAHxUHBgAC89wgAB8VBgYwArPcIAAfFQUGIAKz3CAAHxUEBjACM9wgAB8VAwY
+gAjPcIAAfFQIGEAIz3GAAABUgBkACHwZwAd4GYAHdBlAB3AZAAdsGQAHaBmABmQZQAZgGQAGXBnA
+BVgZgAVUGUAFUBkABUwZwARIGYAERBlABEAZAATvoc6hraGMoSwZwAIoGYACJBlAAiAZAAIcGcAB
+GBmAARQZQAEQGQABY6FqIAAD2BkAAGogwALUGQAAaiCAAtAZAABqIEAByBkAAGogAAHEGQAAaiDA
+AMAZAABqIIAAvBkAAGogQAC4GQAAaiAAALQZAABqIIABzBkAANDYn7jPcZ8AuP8doc9wgAAAAMSA
+UyXENVMmxTXXugHm077EoFMjwAQFJo4f0P4AANahBSCAD7D+AAAWoRiBUyfONQDdlLgYoUDDAcAC
+wclzDBQGMGIJYAEQFAcwz3CgALQPvKBmCkAB4gzgAKlwCNgA2aYM4ACZuRbx4HjxwAoIYAF72OII
+YAHX2c9xgAB8VDQZwA8wGQAPLBnADigZgA4kGUAOz3CAAHxUIBhAC89wgAB8VBwYAAvPcIAAfFQY
+GMAKz3CAAHxUFBiACs9wgAB8VBAYwAjPcIAAfFQMGIAIz3CAAHxUCBhACM9xgAAAVIAZAAh8GcAH
+eBmAB3QZQAdwGQAHbBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARA
+GQAE76HOoa2hjKEsGcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC
+1BkAAGoggALQGQAAaiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0
+GQAAaiCAAcwZAADrds91oADIHxkVEZbPcAAARBwyCCABCiDAL1pwz3CAAIAoI4DPc58AuP/Pd4AA
+AAAEhwHg07gi6RkVApZBCt4AXYNA3p++3aMEpwUggA/Q/gAAFqNYG4AHIRUAliIVAJYEIYEP/wD8
+/wCBFqMI2BkdGJBWo12joQYAAdDZn7k9owSnBSCAD9D+AAAWo89wgACkBACACyCAhAjyWBuABDIM
+wAEM2CjwjCEBoCHyQiFBIEMJFQQzJkFwgAA0SEAngHI0eAB4SiFAIA3YFPBKIYAgBNgQ8BPYSiEA
+IQzwSiEAIhTYCPBKIQAkFdgE8BbYAvAP2M9zgABED3CDCnHJcgokQAQdBO//CiWABMkCz//xwOYO
+AAFyCwAAWg8AAor+nggAAAohwA/rcgbYiiPKAkokAADtA+//CiUAAfHABOkZCBIICiHAD+tyBdjs
+20okQADRA+//uHPPcoAAhAkVeiCi0cDgfuB4ANmeuRl5z3KAAHwJAYIleOB/AaIA2Z65GXnPcoAA
+fAkBgiZ44H8BogDZnrkZec9wgAB8CQGAJHhCIACA4H/KIGIA4HjPcIAAfAkBgOB/LygBAOB48cCe
+CM//4HjgeOB44HhpIIABbyE/AGkgAAD38fHAANiNuOoL4AIIGhgwEMyGIP+KCPLPcIAABQUAiIDg
+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
+QSjDAQ27ZXlFeYC5z3KgAOwnJqJALMEA5XnPcqsAoP86os9xoAC0D7yhIY7PcqcANET2GlgAJZZh
+lvNp9X8QvwUj0gP1GpgEZI7ljlEgQID3GtgA+BrYA89zpwAUSEEpgiFYGwABV6PPcqAAgERwgs93
+pQCs/0YjAwVwogDCBCKCDyEAAMEmulWnyiCCDwEA//8G9ADAGgvv+BThGKcgwIm4jrgZpwCOEwhe
+AEAmABPyCq/zFNkD8ADdz3agAPQHpKaeDU/yz3GAAGyOAYmF6ACJEwhfAAHZkLnPcKcAmEc8oAPY
+BKYDCB5Dz3GAAGyOAYmF6ACJFwhfAM9ypwCYR3AagAQIiYC4GqIAiXUIXgCpCB7D/QjewfoLj/WM
+IAKDzCCCjwAA/AAM8gohwA/rcgXYiiPOBEokQABxBm/yuHOMIAKDGPTPdYAAbI6pcMIOb/MD2QCN
+USAAgMohwg/KIsIHyiOCDwAAmAPKIGIB5fVb/wTwWgwP9AIOb/OA2Abw+g1v84DYVv8A2s9xoAD0
+B0ShA9gKoQmhSaFKCO/8CnA5AO/zocDgePHAz3KAAPBdJJIA2ILhzCFigMogYQAvJgfwz3GAAGyO
+AIkP8kCSEQqRAYYgPg6FIAEBBvCGID8FRSAACgCpCwgeAFX/AvA8/xsBz//xwM9wgABsjhIOb/MD
+2er/BwHP/z0FT/M5BU/z4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB/ANjgfwDY4H7geKHB
+4H+hwOB44H7gePHA4cUByM91gADYRwClBG26DW/zAtnPcYAOBADscCCgVgxv8wCFmQeP8+B44H7g
+eOB+4HjxwAAWAEHPcoAA2EcGsgAWBUFAIgEEDhpEAUwlgITKIcIPyiLCB8ogYgHKI4IPAABEAAAF
+YvLKJCIAANoH8AAWAEEUIYwAALQB4i8gQgHzCgKACg1P89HA4H7geOB+4HjgfuB44H7geOB+4Hjg
+fuB44H7geOB+4HjgfuB44H7geM9wgADcCOB/AIDgeOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H8B2OB+4HjgfuB4
+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
+sPIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJh+gAAAQQEAAAAAAAAAAAAAAAAAAAAAAAAAAAC8foAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAD/AQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQEBAgAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgAAAAYACAAJAAAA
+BwAAAAAAAAAAAAAAAAAAAAIAAAACAAAAgwAAAJIAAADoAAAA9wAAAE4BAABdAQAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAcAAAAAAAEAAgAAAAMAEwAjADIAfwAgABAACAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPR2gAAEnwEAAAAAAAAAAAAAAAAAAAAAAPR2
+gACQpQEAAAAAAAAAAAD0doAA+KYBAAAAAAAAAAAAAAAAAPR2gAAAAAAAAAAAAAEADwBkAAEAuAiA
+AAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAcAAAAAAAAAAAAA
+AAAAALQHAAAVAAAAGC2AACwKAAAsCgAALAoAACwKAAAsCgAALAoAACwKAAAsCgAALAoAACwKAAAs
+CgAALAoAACwKAAAsCgAALAoAACwKAAAsCgAALAoAACwKAAAsCgAALAoAACwKAAAsCgAALAoAACwK
+AAAsCgAALAoAACwKAAAsCgAALAoAACwKAABQCwAAAAAAAGgMAQAsCgAAgAgAACwKAAAsCgAALAoA
+AKgIAAD49AAA6FAAACwKAAAsCgAA3AgAANwIAADcCAAA3AgAANwIAADcCAAA3AgAACwKAAAsCgAA
+LAoAACwKAAD4CQAALAoAACwKAAAsCgAALAoAACwKAABUCwAALAoAACwKAABkCAAAAwAAAGysAQAC
+AAAAGBcBAAQAAAC8LwAABgAAAJC2AQARAAAArJgBAAcAAABooQEACAAAABC3AQAMAAAA1CwBAA0A
+AADQMAEADgAAAAgxAQAWAAAA0AsBAAsAAABQRAEAFAAAAABSAAAPAAAASGAAABAAAADIAwEAAQAA
+AGSdAQASAAAA+FEBABMAAABsSQEABQAAANBiAAAXAAAAUAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkIwAAZCMAAGQjAABUNQAAZCMAAGQjAAAYMQAAZCMA
+AGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAlBkAACwbAAAwGwAApBwAACQdAACoHAAA
+ZCMAAGQjAAC4PQAACEEAANhBAABkIwAAZCMAAGQjAACEPAAAHKkAABipAAAgqQAABDIAABQzAAC8
+VwEAWDUAANAzAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQj
+AABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMA
+AGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABENgAAZCMAAGQjAABkIwAAZCMAAGQjAAAkNwAA
+ZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAADcLwAAZCMAAPwvAABk
+IwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAMRjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQj
+AABkIwAAZCMAAGQjAABkIwAAZCMAABxDAQCgRgEAZCMAAGQtAQBkIwAAxC4BALgfAQBkIwAAZCMA
+AFBCAABkIwAAZCMAAGQjAABkIwAAZCMAAFCZAQDEmAEAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAA
+KO8AACi2AQAstgEAZCMAABS2AQBkIwAAZCMAAGQjAABkIwAARKEBAGQjAAD0owEAZCMAAGQjAABk
+IwAAPCAAAEAgAABkIwAAzEsBAOi3AQAEUgAAZCMAAGQjAABkIwAA6JsBAGQjAABkIwAAoAQBAFhJ
+AQBkIwAAZCMAAGQjAADMUAEAaBsBAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAHhbAQBkIwAA9LYB
+APi2AQAEtwEACLcBAPy2AQAAtwEADLcBAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAA
+ZCMAAChEAABkIwAAZCMAAGQjAABkIwAAZCMAAGS2AQCYtgEATDkAAGQjAABkIwAAZCMAAGQjAABk
+IwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAMRZ
+AQBkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMAAGQjAABkIwAAZCMA
+AGQjAABkIwAAZCMAAGQjAADwOQAAcDoAAPQ6AACQOwAAAF8AAGg7AABkIwAAZCMAAGQjAABkIwAA
+ZCMAAOg5AADsOQAAZCMAAGQjAACAQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAEAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA4QMOHuHhAw4e4cECCh7hgQUMHuEAAAAAAAAAAAAA4QMOHuHhAw4e4cECBh7h
+gQUMHuHBAgYe4YEFDB7hwQIGHuGBBQwe4cECBh7hgQUMHuEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQENDQ0NDQ0NDQ0NDQ0N
+DQ0NAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBDQ0NDQ0N
+DQ0NDQ0NDQ0NDQMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEB
+AQ0NDQ0NDQ0NDQ0NDQ0NDQ0DAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAJECAAAxyi8A
+kQIAADHKLwCRAgAAMcovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAJECAAAxyi8AkQIAADHKLwBD
+AQAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEMB
+AAAxyi8AQA0AAN4DCQAAAAAAAAAAAAAAAAAU7QAAAQAAANgsgACAgICAgICAgAGAAoCAgICAAQAA
+AAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAA2CyAANgsgACkIKAAOCCgAAEAAAD8////AAAAAAAAAAD4LIAA+CyAAKgg
+oAA8IKAACAAAAPP///8AAAAAAAAAABgtgAAYLYAArCCgAGwgoAAwAAAAz////wAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAC0BAEABQAAABgtgADICQEA
+AP8DAOgJAQAA/wUAzAoBAAD/LQDwCgEAAP89AKgKAQAA/wQAjAoBAAD/JQDMEAEAnBEBAAASAQCk
+DQEAIA0BALwSAQAYEwEAXBMBAKATAQAAAAAALAEAAF4BAAABAAAAAQAAAAEAAAABAAAAAwAAAAAA
+AAAAAAAAAAAAAAMAAAACAAAAAwAAAAMAAAADAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAbBgB
+AAoAAADYLIAAAAAAAAAAAAAAAAAAzBgBAAoAAADYLIAAAAAAAAAAAAAAAAAA4BgBAAoAAADYLIAA
+AAAAAAAAAAAAAAAALBkBAAoAAADYLIAAAAAAAAAAAAAAAAAA9BkBAAoAAADYLIAAAAAAAAAAAAAA
+AAAAmBkBAAoAAADYLIAAAAAAAAAAAAAAAAAAAB8BAAYAAADYLIAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAEAAAAACAAAAAAKAAECcAAOgDAADoAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAANwzAQDUNAEAYDcBAPA5AQBMPAEAZD8BAFw2AQAgBYAAvHaAABgAAAB8doAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAB0QQEABgAAANgsgAAAAAAAAAAAAAAAAAD09gAACgAAANgsgAAA
+AAAAAAAAAAAAAAD09gAACgAAANgsgAAAAAAAAAAAAAAAAAD09gAACgAAANgsgAAAAAAAAAAAAAAA
+AAD09gAACgAAANgsgAAAAAAAAAAAAAAAAAD09gAACgAAANgsgAAAAAAAAAAAAAAAAAD09gAACgAA
+ANgsgAAAAAAAAAAAAAAAAAD09gAACgAAANgsgAAAAAAAAAAAAAAAAAD09gAACgAAANgsgAAAAAAA
+AAAAAAAAAAD09gAACgAAANgsgAAAAAAAAAAAAAAAAAD09gAACgAAANgsgAAAAAAAAAAAAAAAAAD0
+9gAACgAAANgsgAAAAAAAAAAAAAAAAAD09gAACgAAANgsgAAAAAAAAAAAAAAAAACwRwEACgAAANgs
+gAD/////AAAAAP////8AAAAAAAAAAAAAAADsSAEABQAAABgtgABkAGQAaQDcAMgAWgCqAL4AhgF9
+AD4AZABkAGkA3ADIAFoAqgC+AIYBfQA+AAAAAAABAQAAAAAAAAABAgEBAAIBAAECAgIAAQEAAgEC
+AQIAAgABAgMAAAAA6FoBANxnAQD0gIAAQAUAAAAAAADoWgEABFwBADSGgAAgAQAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAFGwBADBqAQBUh4AAVAAAAAAAAADoWgEAXGoBANSHgABQAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAABAAAA6FoBAOBmAQBwNoAAUAEAAAAAAAAYbAEA7GgBAMwGgAACAAAAAAAA
+AOhaAQAYaQEA0AaAAAQAAAAAAAAAEGwBAARcAQCoh4AALAAAAAAAAADoWgEAhGkBAAAAAAAAAAAA
+AAAAAOhaAQBEaQEA1AaAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAgAD
+AAQABAAFAAYABgAHACAAIAAhACIAIgAjACQAJAAlACYAJgBDAEQARABFAEYARgBHAEgASABJAEoA
+SgBLAEwATABNAE4ATgBPAFAAUABRAG4AbgBvAHAAcABxAHIAcgBzAHQAdAB1AHYAdgB3AHgAeAB4
+AHgAeAB4AHgAeAB4AA8APwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAgADAAMA
+BAAFAAUABgAHAAcACAAJAAkACgAjACMAJAAlACUAJgAnACcAKAApACkARgBHAEcASABJAEkAZgBn
+AGcAaABpAGkAagBrAGsAbABtAG0AbgBvAG8AcABxAHEAcgBzAHMAdAB1AHUAdgB3AHcAeAB4AHgA
+eAB4AHgAeAB4AA4APwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAF
+AAYABgAHACAAIAAhACIAIgAjACQAJAAlACYAJgBDAEQARABFAEYARgBHAEgASABJAEoASgBLAEwA
+TABNAE4ATgBPAFAAUABRAG4AbgBvAHAAcABxAHIAcgBzAHQAdAB1AHYAdgB3AHgAeAB4AHgAeAB4
+AHgAeAB4AA8AQwAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAgADAAMABAAFAAUABgAHAAcACAAJAAkA
+CgAjACMAJAAlACUAJgAnACcAKAApACkARgBHAEcASABJAEkAZgBnAGcAaABpAGkAagBrAGsAbABt
+AG0AbgBvAG8AcABxAHEAcgBzAHMAdAB1AHUAdgB3AHcAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgA
+eAB4AAgAQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAH
+ACAAIAAhACIAIgAjACQAJAAlACYAJgBDAEQARABFAEYARgBHAEgASABJAEoASgBLAEwATABNAE4A
+TgBPAFAAUABRAG4AbgBvAHAAcABxAHIAcgBzAHQAdAB1AHYAdgB3AHgAeAB4AHgAeAB4AHgAeAB4
+AA8AQwAAAAAAAAAAAAAAAQABAAIAAwADAAQABQAFAAYABwAHAAgACQAJAAoAIwAjACQAJQAlACYA
+JwAnACgAKQApAEYARwBHAEgASQBJAGYAZwBnAGgAaQBpAGoAawBrAGwAbQBtAG4AbwBvAHAAcQBx
+AHIAcwBzAHQAdQB1AHYAdwB3AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AAQA
+PwBETwEAEtIAAAAAAAD//w8A/GQBALYAAAAAAAAA/wAAAPxkAQC3AAAAAAAAAP8AAAD8ZAEAuAAA
+AAAAAAD/AAAA/GQBALkAAAAAAAAA/wAAAPxkAQC6AAAAAAAAAP8AAAD8ZAEAuwAAAAAAAAD/AAAA
+/GQBAL0AAAAAAAAA/wAAAPxkAQC+AAAAAAAAAP8AAAD8ZAEAvwAAAAAAAAD/AAAA/GQBAMAAAAAA
+AAAA/wAAAPxkAQDBAAAAAAAAAP8AAAD8ZAEAwgAAAAAAAAD/AAAARE8BABPSAAAAAAAA//8PAPxk
+AQAbAQAAAAAAAP8AAAD8ZAEAHAEAAAAAAAD/AAAA/GQBAB0BAAAAAAAA/wAAAPxkAQAeAQAAAAAA
+AP8AAAD8ZAEAHwEAAAAAAAD/AAAA/GQBACABAAAAAAAA/wAAAPxkAQAiAQAAAAAAAP8AAAD8ZAEA
+IwEAAAAAAAD/AAAA/GQBACQBAAAAAAAA/wAAAPxkAQAlAQAAAAAAAP8AAAD8ZAEAJgEAAAAAAAD/
+AAAA/GQBACcBAAAAAAAA/wAAAERPAQAU0gAAAAAAAP//DwD8ZAEAggEAAAAAAAD/AAAA/GQBAIMB
+AAAAAAAA/wAAAPxkAQCEAQAAAAAAAP8AAAD8ZAEAhQEAAAAAAAD/AAAA/GQBAIYBAAAAAAAA/wAA
+APxkAQCHAQAAAAAAAP8AAAD8ZAEAiQEAAAAAAAD/AAAA/GQBAIoBAAAAAAAA/wAAAPxkAQCLAQAA
+AAAAAP8AAAD8ZAEAjAEAAAAAAAD/AAAA/GQBAI0BAAAAAAAA/wAAAPxkAQCOAQAAAAAAAP8AAABE
+TwEACNIAAAAAAAD//wMAZE8BAACCAAAAAAAA/wEAAGRPAQABggAAAAAAAP8BAABETwEACdIAAAAA
+AAD//wMAZE8BAAKCAAAAAAAA/wEAAGRPAQADggAAAAAAAP8BAABETwEACtIAAAAAAAD//wMAZE8B
+AASCAAAAAAAA/wEAAGRPAQAFggAAAAAAAP8BAABETwEABtIAAAAAAAD/AQAARE8BAAfSAAAAAAAA
+/wMAAERPAQAG0gAACQAAAAD+AwBETwEAB9IAAAoAAAAA/A8ARE8BAAbSAAASAAAAAAD8B0RPAQAH
+0gAAFAAAAAAA8D9ETwEAFdIAAAAAAAD/AwAARE8BAAzSAAAAAAAA/wEAAERPAQAV0gAACgAAAAD8
+DwBETwEADNIAAAkAAAAA/gMARE8BABXSAAAUAAAAAADwP0RPAQAM0gAAEgAAAAAA/AcAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc0g3SEdIQ0gLSAdID0hvSC9IAgAXSEtIT
+0hTSBEMG0gfSBNIJEHDStQAaAYEBBQAEAAYACAAJAAoACwAMAIMAkgDoAPcATgFdAQ8ALgAAAGwA
+AAB0AAAAgAAAAIwAAACdAAAABwAAAAQAAAAIAAAAEAAAAEAAAACAAAAAIAAAAAAAAAAJAAAAEgAA
+AAAAAAAKAAAAFAAAAP////8AAAAALQEAAN0BAABaAgAAugIAAAoDAABNAwAAhwMAALoDAADoAwAA
+EQQAADcEAABZBAAAegQAAJgEAAC0BAAAzgQAAOcEAAD+BAAAFQUAACoFAAA+BQAAUQUAAGQFAAB1
+BQAAhgUAAJcFAACnBQAAtgUAAMUFAADTBQAA4QUAAO4FAAD7BQAACAYAABQGAAAgBgAAKwYAADcG
+AABCBgAATAYAAFcGAABhBgAAawYAAHUGAAB+BgAAiAYAAJEGAACaBgAAogYAAKsGAAC0BgAAvAYA
+AMQGAADMBgAA1AYAANsGAADjBgAA6gYAAPIGAAD5BgAAAAcAAAcHAAAOBwAAFAcAABsHAAAiBwAA
+KAcAAC4HAAA1BwAAOwcAAEEHAABHBwAATQcAAFMHAABYBwAAXgcAAGQHAABpBwAAbwcAAHQHAAB5
+BwAAfwcAAIQHAACJBwAAjgcAAJMHAACYBwAAnQcAAKIHAACnBwAAqwcAALAHAAC1BwAAuQcAAL4H
+AADCBwAAxwcAAMsHAADQBwAA1AcAANgHAADcBwAA4QcAAOUHAADpBwAA7QcAAPEHAAD1BwAA+QcA
+AP0HAAABCAAABQgAAAgIAAAMCAAAEAgAABQIAAAXCAAAGwgAAB8IAAAiCAAAJggAACkIAAAtCAAA
+MAgAADQIAAA3CAAAOwgAAD4IAABBCAAARQgAAEgIAABLCAAATwgAAFIIAABVCAAAWAgAAFsIAABf
+CAAAYggAAGUIAABoCAAAawgAAG4IAABxCAAAdAgAAHcIAAB6CAAAfQgAAIAIAACCCAAAhQgAAIgI
+AACLCAAAjggAAJEIAACTCAAAlggAAJkIAAAAAAAAAAAAAAoAAAAN0hHSENIC0gHSA9Ib0gvSAIAF
+0hLSE9IU0gRDCNIJ0grSHNIG0gfScNIAAAEAAAAAAAAAAAAAAAAAAAADAAAABAAAAAMAAAAAAAAA
+AwAAAAAAAAAAAAAAAAAAAAAAAAD/AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALUAGgGB
+AQQADwCDAOgATgGSAPcAXQEGAAgACQAKAAsADAAFAAAAAAAAACwAAQAAAAAAAAAAAAAAAAAAAAAA
+AAACAAIAAgAAAN8AAAAZAQAAYgEAAL4BAAAyAgAAwwIAAHsDAABiBAAAhAUAAPIGAAC+CAAAAgsA
+AAEAAAACAAAAAAAAAAvSDtIN0gjSCdIK0hLSE9IU0hHSENIC0gHSA9IAgAXSBEMb0hzSBNIARTDS
+MdIAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAHAAAAAAAAAAMAAAAE
+AAAAAwAAAAAAAAD/AwAAAwAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAtQAaAYEB
+BQAEAA8AEAAKAAsADAAAAAAAAAAAACwAAQAAAAIAAgACAAAAAAABAAEAAgACAAIAAwADAAQABAAF
+AAUABgAGAAcABwAIAAgACQAJAAoACgALAAsADAAMAA0ADQAOAA4ADwAAAAAAAAAAAAAAAADUngEA
+BgAAANgsgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAACAFgAC8doAAGAAAAHx2gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA
+AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAWAALx2gAAYAAAAfHaAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAKKoBAAQAAADYLIAAAAAAAAAAAAAAAAAAUKkBAAQAAADYLIAAAAAAAAAAAAAAAAAA
+yKoBAAYAAADYLIAAAAAAAAAAAAAAAAAAUKkBAAQAAADYLIAAAAAAAAAAAAAAAAAAKKoBAAQAAADY
+LIAAAAAAAAAAAAAAAAAAUKkBAAQAAADYLIAAAAAAAAAAAAAAAAAAKKoBAAQAAADYLIAAAAAAAAAA
+AAAAAAAAUKkBAAQAAADYLIAAAAAAAAAAAAAAAAAAyKoBAAYAAADYLIAAAAAAAAAAAAAAAAAAUKkB
+AAQAAADYLIAAAAAAAAAAAAAAAAAAKKoBAAQAAADYLIAAAAAAAAAAAAAAAAAAyKoBAAYAAADYLIAA
+AAAAAAAAAAAAAAAAKKoBAAQAAADYLIAAAAAAAAAAAAAAAAAAKKoBAAQAAADYLIAAAAAAAAAAAAAA
+AAAAyKoBAAYAAADYLIAAIAWAALx2gAAYAAAAfHaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUBQAAAAAAAAAAAAAAAAAAAAAA
+/wD/AAAAAAAABBYIFhYWDBYWFhYWFhYQAAAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwAB
+AAAADwA/AAEAAAAPAD8AAQAAAA8APwACAAAADwA/AAEAAAAAAAAAAQAAAAIAAAADAAAAAAAAAAQA
+AAACAAAABQAAADKAAaUAPDg0MCwoJCAcGBQQDAgEAAwIBAA8ODQwLCgkIBwYFBAMCAQCABQOGgAA
+ACAAAAACAAACAAAAAAEBAAECAQEBAQEBAQEBAQECAgICAgICAgMDAwMDAwMDBAQEBAQEBAQBAgIC
+AgICAwMDAwMDAwMDAwMDAwMEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAQECAQICA3//Bw8f
+PwEDAQMPBwEHDx8/f///BQAHAgMEBgZ00UUX6KKLLg0PBQcJCwEDChQ3blVVVQFLaC8BVVVVBeM4
+jgOqqqoCcRzHAaqqqgrHcRwHKAAoADAALAAsACgAPAA0ACgAKAA0ADAALAAsAEQAPABAADwAjABs
+AFgASAD0ALAALAAsADwANAAwACwAVABEAFQAVABsAGAAXABUAIwAeAA6AQIB1QDfANoAogB1AH8A
+agEaAdkA6AAKAboAeQCIAIoFKgM5AagBigXKAtkASAHKAUoB4gD5AMoB6gCCAJkAZuYAAJ3YiZ1O
+7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzETid2YicapEEaEzuxEw3SIA2JndgJCIzACAd+
+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUFBVRABSd2YicTO7ETDdIgDYmd2AkGaZAGxE7s
+BARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN0iANCqiAChM7sRMP/MAPD/zADw3SIA0LtEAL
+C7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4gAcGaZAGD/zADw3SIA0LtEALDdIgDQu0QAuJ
+ndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiACgiMwAgHeIAHCIzACAd4gAcGaZAGsLLVBQZp
+kAawstUFBVRABQVUQAXWHcYEDQAaACcANABOAGgAdQCCABoANABOAGgAnADQAOoABAEnAE4AdQCc
+AOoAOAFfAYYBNABoAJwA0AA4AaAB1AEIAgwATgBoAIIAdQCcAMMAaACCAIIAnAC2ALYA0ACcAMMA
+wwDqABEBEQE4AYIAnAC2AJwAtgDQAOoA0ADqAAQBBAEeAcMA6gARAeoAEQE4AV8BOAFfAYYBhgGt
+AQAAMAAAADYAAAAMAAAAEgAAABgAAAAkAAAABgAAAAkAAAAAAAAAAAAAABggFBQODhQUBQYBAgME
+AAAAAQECAQICAwQMDAgEDAQEQAAAAIAAAAAAAQAAAAIAAEAAAAAABAAAQAAAAEAAAAAQERITFBUW
+FxgZGhscHR4fICEiIyQlJicoKSorLC0uL0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f
+YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8tAA8gAPBhAAAAAAAAAAAAAAECBAQAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
+AgECAwQAAAUGBwgJCgAAAAUGAAIEAAUAAAAAAAUHAQMEAAUBAAAAQCNAJSEhISFAQEBAQAUEBAEB
+QEBAQAUFQEAMDEANDAwBAQEFQEAFBQAEAARAQAAEQEBABUBAQEBABUBAQAUFBQEBAQFABQUFAQUB
+AUAFBQVABUAFBQUFBWwAcAR0CHQMAAQEBgAAAAAAAAAAZAAAAACQAQAKAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA
+AAABAAAAEAAAAAAAAAABAAAAAQAAAAAAAAD/AAAA/wAAAAAAAAAAAAAA6KoBAAAAAAAABAAAZAAA
+AAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwYGBgYGBQUFBQUEBAQEBAMDAwMDAgICAgIBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMRQEAlEUBAJxFAQDwRQEA+EUBAABGAQAACiVD
+xE56lQAHEyRUKwAAAAQOCR0tNwAABA4JHSw7AAEQAAEAAAACgAABQgYCEAACIAAAA8AAAUMGAxAA
+AsAAAAPAAAFDBgQQAAJAAAACgAABRAYFEQAAQAAAA8AAAUUGBhEAAOAAAAPAAAFFBgcRAAEAAAAC
+gAABRgYIEQACIAAAA8AAAUcGCREAAsAAAAPAAAFHBgoRAAJAAAACgAABSAYLEgAAQAAAA8AAAUkG
+DBIAAOAAAAPAAAFJBg0SAAEAAAACgAABSgYOEgACAAAAAoAAAUwGAAAiFgAAgAAAAwAAAVkAJBYA
+AQAAAAMAAAFaACYWAAIAAAAEAAABWgAoFgACAAAAAwAAAVsAKhYAAoAAAAMAAAFcACwXAAAAAAAE
+AAABXAAuFwAAgAAAAwAAAV0AMBcAAQAAAAMAAAFeADQXAAIAAAADAAABXwA2FwACgAAAAwAAAWAA
+OBgAAAAAAAQAAAFgADwYAAEAAAADAAABYgA+GAACAAAABAAAAWIAQBgAAgAAAAMAAAFjAGQbAAIA
+AAADAAABbwFmGwACgAAAAwAAAXABaBwAAAAAAAQAAAFwAWwcAAEAAAADAAABcgFuHAACAAAABAAA
+AXIBcBwAAgAAAAMAAAFzAnQdAAAAAAAEAAABdAJ2HQAAgAAAAwAAAXUCeB0AAQAAAAMAAAF2Anwd
+AAIAAAADAAABdwN+HQACgAAAAwAAAXgDgB4AAAAAAAQAAAF4A4QeAAEAAAADAAABegOGHgACAAAA
+BAAAAXoEiB4AAgAAAAMAAAF7BIwfAAAAAAAEAAABfASRHwABQAAAAwAAAX4ElR8AAwAAAAQAAAF/
+BZcfAALAAAADAAABgAWZIAAAQAAAAwAAAYEFnSAAAUAAAAMAAAGCBZ8gAAHAAAADAAABgwWhIAAD
+AAAABAAAAYMFpSEAAEAAAAMAAAGFBQAAAAAAAAAAAAAkogEALKIBAJSiAQAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAD/////AAAAAAAAAAABAAAAAAAAAGAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAA
+AAAAAAUFBQUFBQUFAAAAAIANAAAAIAAAgA0AAIANAAAAIAAAgA0AAAAGAAAABAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAA==
+====
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..e69de29bb2d
diff --git a/sys/contrib/dev/iwn/iwlwifi-4965-228.61.2.24.fw.uu b/sys/contrib/dev/iwn/iwlwifi-4965-228.61.2.24.fw.uu
new file mode 100644
index 00000000000..270a4d80bfd
--- /dev/null
+++ b/sys/contrib/dev/iwn/iwlwifi-4965-228.61.2.24.fw.uu
@@ -0,0 +1,3339 @@
+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-4965-228.61.2.24.fw.uu
+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
+8cDhxc9yoADIH89xoADIHKiBSBoYgAbYCiQAcOB4qCBAAeB44HitAu/2qXDxwM9xoADIH0kZGIAG
+2AokAHDgeKggAAHgeOB40cDgfvHACgrv9gHYAN7PdaAAxCcSpaYP7/8D2Bpwz3AJAAYAEKXPcMAA
+BkMQpc9wwAAGTBClz3DAAAZVEKXPcqUA8MwYGoCDAdjPcaQADEIUoSvZz3CkAJBBPqAS389zpAAU
+QfijLNtooM9zpACgPzyjP9kroHTYFBoAgM9wpACYfZ8YmAO6DiAAyXCKIcQAz3CkABxANqAg2M9x
+pAAMQgyhFNgNoTnZz3ClAFANMBhAgM9wPwACwRClz3BgAALMEKXPcAEAAssQpc9wCAACiRClz3B3
+AAKQEKXPcMcAAosQpc9wXwACGBClz3AFAAIZEKXPcAMAAsAQpc9wIAACXhClz3BjAAJlEKXPcAYA
+AmYQpc9wAQAC2BClz3BgAALSEKXGDu//CnBJAc/2bPHgeADaDfBUeGOIIojPcKwA1AEB4k96NXiL
+GNiAz3CAANAVIIgwcuAgygfu8eB48cDhxQh1z3GAAMgDBYmA4AT0BImA4A/y7/8H2gDYz3GsANQB
+2BmAgIDlyiChAtAZAID9AM/24HjxwOHFCHUhkECQz3CjANj9VXiKGFgAIJUp2BK48CBBAAGVMHAK
+8qIPL/eKINEDiiDRA5YPL/cghb0Az/bxwOHFCHUhkECQz3CoANQDVXgLGFiAIJUV2BO48CBBAAGV
+MHAK8mYPL/eKINEDiiDRA1oPL/cghYEAz/bxwOHFCHUhkECQz3CsANQBVXiLGFiAIJUr2BK48CBB
+AAGVMHAK8ioPL/eKINEDiiDRAx4PL/cghUUAz/bxwOHFCHUAkM9yoADsJwi4TyBBAAGVELgleM9x
+oADEJxChAJUIuEUgwAAQoSqCAZUwcAvy3g4v94og0QOKINED0g4v9yCF/QeP9uB4z3GsANQBANiL
+GRiAjBkYgAfYjRkYgAbZkbnPcKAAxCcwoM9xGAAHAjCgz3KAAHR7NIqA4QX0z3EQAAYCMKAggoDh
+UfIG2Za5MKDPcXgAAoUwoM9xAgACgTCgz3FVAAKCMKDPcRAAAoYwoM9xQQAChzCgz3EHAALTMKDP
+cQEAAoowoM9xAAACpTCgz3EAAAKmMKDPcQAAAqcwoM9xBgACqDCgz3EGAAKpMKDPcQYAAqowoM9x
+/wAHxTCgz3H/AAfbMKDPcf8AByYwoM9x/wAHIzCgz3EYAAIfMKDPccwAAh5X8AfZlrkwoM9xAQAC
+hzCgz3EDAALFMKDPcYAAAtswoM9xcAAChTCgz3FwAAKBMKDPcQYAAtMwoM9xIQACijCgz3EFAAKl
+MKDPcQUAAqYwoM9xBQACpzCgz3EMAAKoMKDPcQwAAqkwoM9xDAACqjCgz3FEAAImMKDPcUQAAiMw
+oM9xKAACFjCgz3GZAAIVMKDPcf8AB4IwoM9x/wAHhjCgz3H/AAcfMKDPcf8ABx4woOB+4HjxwLhw
+z3CAAHR7ABAEAEwkAIAA2A7yz3KAABxEAvAB4I7gVfcWIgEAIImwcfn1F/DPcoAAjEQD8AHgpuBH
+9xYiAQAgibBx+vUJ8ArYCiHAD+tyzguv9onbANjRwOB+4HjPcoAAdHs0ioDhAYIH9DWKgOHCIKIA
+wCChAMTxz3CAAHR7QIAigM9wgAAcRIDiNngD8uB/B4jgf3cQgADxwEYNj/bPdYAAIREAjYDgHAAC
+AM9wAACQZQokAHDgeKggAAHgeOB4AdgArQbYkLjPdaAAxCcQpc9wgAB0e0CAIoDPd6AA7CfPcIAA
+HESA4gXyNngG2Za5BfBw4DZ4B9mWuTClz3YEAAe8z3EQAAe40KUwpc9xCgAHvDClz3E/AALBMKUi
+iBC5BSGBDwAAArIwpSGIELkFIYEPAAACszClJYgQuQUhgQ8AAAK0MKUkiBC5BSGBDwAAArUwpSOI
+ELkFIYEPAAACtjClBogQuAUggA8AAAK3EKXPcAQABrwQpc9wAQAGsRClz3ADAAauEKXPcAEABrwQ
+pc9wAwAGABClz3AIAAa8EKXPcBAABrgQpc9wAACgKAokAHDgeKggAAHgeOB4z3AgAAa8EKXPcAAA
+KAoKJABw4HioIAAB4HjgeM9wAAAD8BClCoeEIAEPQSiRAM9wIAAHvBClz3AAAAPvEKUoFxAQCiUA
+BIQlAQiMJQGIDPIR2AohwA/rcoojxAcCCq/2CiQABEwhgKFTIAAhTfeP4MogYQTAIGIAELgFIIAP
+AAAC2xCl0KX9A4/24HjxwKILr/aKIQYEz3WgALAfGIV+C4/8CHYM8AjYCiHAD+tyx9tKJAAAqgmv
+9golAAHPcgAAA/DPcaAAxCfPcKAA7CdQoQqA57gI9BiFogov/MlxguDu9ePxtQOP9vHA4cXPdYAA
+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
+4b3RJeKQBPLkvQzyBdgKIcAP63KKI1gKmHM2Ca/0uHZhA6/0ocDgePHA9gqP9BXIXBKNMFMgDgCK
+IAcCJgov9alxyXCpcU79AYjkuAvyBdgKIcAP63KKIxkAmHPyCK/0uHUpA4/0AAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAJQBAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPht
+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAALAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAQD/APDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgGAAAYBgAAGAY
+AABYIAAAYBgAAGAYAAAwIAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAA9BEA
+AAASAABgGAAAoBIAAMgTAABIEwAAYBgAAGAYAACUJAAAQCcAAOgnAABgGAAAYBgAAGAYAADIIwAA
+YBgAACQpAABkKgAAYBgAAGAYAABgGAAAXCAAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABg
+GAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAY
+AABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAACgIAAAYBgA
+AGAYAABgGAAAYBgAAGAYAAB0IQAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAA
+YBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABg
+GAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAADQBAQAwBAEAYBgAAJQG
+AQBgGAAAQAgBANzPAADc0AAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAADA9AQDcTwEAYBgA
+AGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAA
+qFYBAGAYAACEWAEAYBgAAGAYAABgGAAAVBQAAHAcAQBgGAAAYBgAAABmAQAsMAAAYBgAAGAYAABg
+GAAAANUAAGAYAABgGAAAdMQAAEgjAQBgGAAAYBgAAGAYAABcMwEAtNUAAGAYAABgGAAAYBgAAGAY
+AABgGAAAYBgAAOwoAQBgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgA
+AGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAHwwAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAA
+YBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABg
+GAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAY
+AABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAGAYAABgGAAAYBgA
+AGAYAABgGAAAYBgAAGAYAABgGAAAYBgAAPAiAAD0IgAAYBgAAGAYAABgGAAAGAAN/A5zD3AdIB9A
+IEAhQCIxJWYmDydmKA8rHSxELR0uRDEQMgkzEDQJb1pwAHEAcgMAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcA
+AOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA
+5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAADMCAAAAAAAADzHAADk
+BwAA4AYAAOQHAADIGwEAFAcAAIiyAADkBwAA5AcAAOQHAADkBwAA5AcAAOQHAACcBwAAOAcAADgH
+AAA4BwAAOAcAALQIAADkBwAA5AcAAOQHAACwBwAA5AcAAOQHAADkBwAA5AcAAOQHAADQCAAA5AcA
+AOQHAADQBgAAAwAAANRkAQAEAAAAMN8AAA4AAAD0VQEACAAAAAgeAQACAAAAKFoBAAoAAADoHgEA
+CwAAAJQKAQAMAAAAyAoBABEAAADgxgAACQAAABwCAQAQAAAAKDAAAA0AAAB8wwAAAQAAAJTUAAAP
+AAAA7DkBABIAAADMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAEAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAEAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAEAAAAIyQAA3MkAAPDMAAAkywAAJMoAALzNAABAzgAAeM4AALzOAAAAAAAALAEAAF4B
+AAABAAAAAQAAAAEAAAABAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAACAAAAAwAAAAMAAAADAAAAAQAA
+AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsDQAAAAAAAAAAAAAAAAAAAP8A/wD/AP//
+/wD/AP8AAAEAAAAAAAAABQAAAAAAAAAAAAAAEAAAAACAAAAAAKAAECcAAOgDAADoAwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwNAQDoDgEAbBEBAFgTAQDIFQEA
++BgBAEgQAQCUD4AAbGOAABgAAABMY4AAAAAAAAAAAABkMoAApGOAAAAbAQAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQICAwQEBQYGBwgICQoKCwwMDQ4OD2ZmZ2hoaWpqa2xsbW5u
+b3BwcXJyc3R0dXZ2d3h4eXp6e3x8fX5+FT8AAAAAAAAAAAAAAAAAAQICAwQEBQYGBwgICQoKCwwM
+DSgoKSoqKywsLUdISUlKS0tMTU1OT09QUVFSbW1ub29wcXFyc3N0dXV2d3d4eXl6e3x9DD8ELQEA
+UHAAAAQtAQBRcAAAuC0BAEUAAAC4LQEARAAAALgtAQBJAAAAuC0BAEgAAAAELQEAUnAAAAQtAQBT
+cAAAuC0BAE4AAAC4LQEATQAAALgtAQBSAAAAuC0BAFEAAAAELQEAQNIAAAQtAQBB0gAAuC0BAFcA
+AAC4LQEAVgAAALgtAQBbAAAAuC0BAFoAAAAELQEACNIAAAQtAQAJ0gAAQC0BAACCAABALQEAAYIA
+AAQtAQBF0gAABC0BAEbSAABALQEAAIIAAEAtAQABggAABC0BAAbSAAAELQEAPpAAAAQtAQBD0gAA
+BC0BAETSAAAELQEAUNIAAAQtAQBR0gAABC0BAFLSAAAELQEAU9IAAAQtAQA/kAAABC0BABPSAAAE
+LQEAQJAAAAQtAQAV0gAABC0BAD/SAAAELQEAPtIAAAQtAQA/kAAABC0BABPSAABkAGQAaQDcAMgA
+WgCqAL4AhgF9AD4AZABkAGkA3ADIAFoAqgC+AIYBfQA+AAAAAAABAQAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAACUD4AAbGOAABgAAABMY4AAAAAAAAAAAABUNoAApGOAAAAAAACUD4AAbGOAABgA
+AABMY4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAuDaAAKRjgABwXgEAlA+AAGxjgAAYAAAATGOAAAAAAAAAAAAA
+lA+AAGxjgAAYAAAATGOAAAAAAAAAAAAA0DaAAKRjgABwZQEAABQFAAAAAAAAAAAAAAAAAAAAAAD/
+AP8AAAAAAD97P3U/bj9oP2I+bj5oPmI9bj1oPWI8bjxoPGI7bjtoO2I6bjpoOmI5bjloOWI4bjho
+OGI3bjdoN2I2bjZoNmI1bjVoNWI0bjRoNGIzbjNoM2IybjJoMmIxbjFoMWIwbjBoMGIlbiVoJWIk
+biRoJGIjbiNoI2IibhhoGGIXbhdoF2IWbhZoFmIVbhVoFWIUbhRoFGITbhNoE2ISbghoCGIHbgdo
+B2IGbgZoBmIFbgVoBWIEbgRoBGIDbgNoA2ICbgJoAmIBbgFoAWIAbgBoAGIAXQBYAFMATj9uP2g/
+Yj5uPmg+Yj1uPWg9YjxuPGg8YjtuO2g7YjpuOmg6YjluOWg5YjhuOGg4YjduN2g3YjZuNmg2YjVu
+NWg1YjRuNGg0YjNuM2gzYjJuMmgyYjFuMWgxYjBuMGgwYgZuBmgGYgVuBWgFYgRuBGgEYgNuA2gD
+YgJuAmgCYgFuAWgBYgBuAGgAYgBhAGAAXwBeAF0AXABbAFoAWQBYAFcAVgBVAFQAUwBSAFEAUABP
+AE4ATQBMAEsASgBJAEgARwBGAEUARAAA/////////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/////////
+/////////////////////////////////////////////////////////////////////wAAAAAP
+AD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8A
+PwACAAAAAQAAAD3kAaUALSonJCEeGxgVEg8MCQYDAAwIBAA8ODQwLCgkIBwYFBAMCAR//wcPHz8B
+AwEDDwcBBw8fP3///wUABwIDBAYGdNFFF+iiiy4NDwUHCQsBAwoUN25VVVUBS2gvAVVVVQXjOI4D
+qqqqAnEcxwGqqqoKx3EcBw8PDwcGBwIDBAUAAQgJCwooACgAMAAsACwAKAA8ADQAKAAoADQAMAAs
+ACwARAA8AEAAPACMAGwAWABIAPQAsAAsACwAPAA0ADAALABUAEQAVABUAGwAYABcAFQAjAB4ADoB
+AgHVAN8A2gCiAHUAfwBqARoB2QDoAAoBugB5AIgAigUqAzkBqAGKBcoC2QBIAcoBSgHiAPkAygHq
+AIIAmQD0AkQCtQHVAZQChAH1AEECrACQAIQAgAB4AHgAeAB0AGYOAACJndgJxE7sBIM0SANiJ3YC
+QRqkAbETOwGBERgBwA/8AC+hvQSX0F4CD4uUAUtoLwGHRcoAJbSXAAXZhgDrXHkAqqqqCgANAAAA
+GgAAACcAAAA0AAAATgAAAGgAAAB1AAAAggAAABsAAAA2AAAAUQAAAGwAAACiAAAA2AAAAPMAAAAO
+AQCd2ImdTuzETjRIgzQndmInGqRBGhM7sRMRGIERD/zAD07sxE4ndmInGqRBGhM7sRMN0iANiZ3Y
+CQiMwAgHfuAHNEiDNBqkQRoRGIERDdIgDQiMwAgGaZAGsLLVBQVUQAUndmInEzuxEw3SIA2JndgJ
+BmmQBsRO7AQERmAEAz/wA6qqqqoapEEaEzuxEw/8wA8RGIERDdIgDQqogAoTO7ETD/zADw/8wA8N
+0iANC7RACwu0QAuJndgJDdIgDQqogAoKqIAKCIzACAd4gAcHeIAHBmmQBg/8wA8N0iANC7RACw3S
+IA0LtEALiZ3YCQiMwAiJndgJCIzACAd+4AcHfuAHwSwpBwqogAoIjMAIB3iABwiMwAgHeIAHBmmQ
+BrCy1QUGaZAGsLLVBQVUQAUFVEAF1h3GBAAAAAAAAAAAGCAUFA4OFBQFBgECAwQAAAAAAAAABwgI
+AAAABwoNEBEAAAAHCw4QEQAHCw4VGx8iAAAAAAcKCw0AAAcKDxUXGgAACAsQFRgbAAsQFiEsMTYA
+AAAHCw8QEgAHCw8WHSEkAAgMDxceIiUIDxceLTxESwAICw8WHSElCA8WHSw6QkkIEBcfLj1ETBAf
+Lj1beYiXAAcHDwcPDw8EDAwIBAwEBEAAAACAAAAAAAEAAAACAABAAAAAAAQAAEAAAABAAAAAMxMA
+AAAFCg8BAQABAgEBAaXGhPiZ7o32Df+91rHeVJFQYAMCqc59VhnnYrXmTZrsRY+dH0CJh/oV7+uy
+yY4L++xBZ7P9X+pFvyP3U5bkW5vCdRzhrj1qTFpsQX4C9U+DXGj0UTTRCPmT4nOrU2I/KgwIUpVl
+Rl6dKDChNw8KtS8JDjYkmxs93ybNaU7Nf5/qGxKeHXRYLjQtNrLc7rT7W/akTXZht859e1I+3XFe
+lxP1pmi5AAAswWBAH+PIee22vtRGjdlnS3LelNSY6LBKhWu7KsXlTxbtxYbXmlVmlBHPihDpBgSB
+/vCgRHi6JeNL86L+XcCAigWtP7whSHAE8d9jwXd1r2NCMCAa5Q79bb9MgRQYNSYvw+G+ojXMiDku
+V5PyVYL8R3qsyOe6KzKV5qDAmBnRnn+jZkR+VKs7gwvKjCnH02s8KHmn4rwdFnatO9tWZE50HhTb
+kgoMbEjkuF2fbr3vQ6bEqDmkMTfTi/Iy1UOLWW632owBZLHSnOBJtNj6rAfzJc+vyo706UcYENVv
+iPBvSnJcJDjxV8dzUZcjy3yhnOghPt2W3GGGDYUPkOBCfMRxqszYkAUGAfcSHKPCX2r5rtBpkRdY
+mSc6uSc42RPrsyszIrvScKmJB6czti0iPJIVIMlJh/+qeFB6pY8D+FmACRca2mUx18aEuNDDgrAp
+d1oRHst7/KjWbTosCKAAAKScAACYnwAAVJ0AAABBAAAAQgAAfEAAAEBCAAAAAMAAcESgAGwAAIAA
+ALAABAigAAAAAAAEALAAGAigAAEAAAAAALAAHAigAAMAAAAAALAA7BygADAAAAAAALAAUBSgAAMA
+AAAAALAABBigAAMAAAAAALAAQESgAAAAAAAAALAAGAigAAAAAAAAAAAABCigAAIBAAAAAAAAXEin
+AAAAAAAAAAAABCigAAJpAAACkPEABCigAAEAAAAAgAEAGCigAAAAAAAAAAAA8BygAAIAAAAAAAAA
+7BygAAEAAAAAoAEACACsAAAAAAAAEAIAMECkAAAAAAAAAAAAEBygAAAAcAAAAAAA4BygAAAAAAAA
+AACAJBCgAAEAAAAAADAAJBCgAAAAAAAAAAAAOBygAACAAAAAAIACOBygAAAAAQAAUEAABCigAAID
+AAAAYFAABCigAAIEAAAEIAAABCigAAEAAAAAQAAACACsAAAAAAAAAKAA7BygAAIAAAAAAJAAcESg
+ACQAAIAAsAIAAAiqAAAAAAAAwAIABAiqAAAAAAAFABABcESgAIQAAIAAMAAAGCigAAAAAAAAAAAA
+OBygAAAAAQAAgAAA4BygAAAAAAAAcKAACAiqAAAAAAAAkKAABACqAAAAAAAAcJAAKEinAAAAAAAA
+kJAAAACmAAAAAAADAAAABAigAAMAAAAAAAAApCCgAAAAAAAAAACAACCgAAAAYAAAAACAOBygAAAA
+AQAAoAGACACsAAAAAAAEkAEABCigAAEAAAAAkAEABCigAAEAAAAAoAGACACsAAAAAAAAAAAAXEin
+AAEAAAAAIAIACACsAAAAAAAAAAAAMEmnAAIAAAAAAAAABCigAAIBQAAAAAAACEinAP8AAAAAAAAA
+BCigAAJpIQAAAAAAZECmAAAIAAAAAAAALEmnAAAAAAAAAACAAEinAAEAAAABAgECAwQAAAUGBwgJ
+CgAAAAUGAAIEAAAABQcBAwQAAEAjQCUhISEhQEBAQEAFBAQBAUBAQEAFBUBADAxADQwMAQEBBUBA
+BQUABAAEQEAABEBAQAVAQEBAQAVAQEAFBQUBAQEBQAUFBQEFAQFABQUFQAVABQUFBQUEAAAAHBEA
+ABwyAAAcMwAABAAAABwVAAAAAAAAAAAAAGQAAAAAkAEACgAAAAAEBAcAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAHECQAAAAAAAAAAAAAAAAAAAQAAAAUAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAA
+AAAAAAAA/wAAAAAAAAABAAAAEAAAAAAAAAABAAAAAQAAAAAAAAD/AAAA/wAAAAAAAAAAAAAA3GMB
+AFwDAQBgAwEAZAMBAMADAQDIAwEA0AMBAAAECwkVJS8AAAQRCRwnMgABgAARgAAWBAIgABKAABYE
+A0AAEIAAFwQE4AAQgAAXBAWAABGAABcEBiAAEoAAFwQHQAAQgAAYBAjgABCAABgECYAAEYAAGAQK
+IAASgAAYBAtAABCAABkEDOAAEIAAGQQNgAARgAAZBA6AABCAABoEIoAAGAAAFgAkAAAZAAAWASYA
+ACIAABYBKAAAGgAAFgEqgAAaAAAWASwAACAAABcBLoAAGAAAFwEwAAAZAAAXATQAABoAABcBNoAA
+GgAAFwE4AAAgAAAYATwAABkAABgBPgAAIgAAGAFAAAAaAAAYAWQAABoAABsCZoAAGgAAGwJoAAAg
+AAAcAmwAABkAABwCbgAAIgAAHAJwAAAaAAAcAnQAACAAAB0CdoAAGAAAHQJ4AAAZAAAdAnwAABoA
+AB0CfoAAGgAAHQKAAAAgAAAeAoQAABkAAB4ChgAAIgAAHgKIAAAaAAAeAowAACAAAB8CkUAAGQAA
+HwOVAAAjAAAfA5fAABoAAB8DmUAAGAAAIAOdQAAZAAAgA5/AABkAACADoQAAIwAAIAOlQAAYAAAh
+A/ROAQBIPwEAFEEBAEhCAQCkRAEAUEcBAFxLAQDUTAEA+E0BADxbAQBUWwEAwFsBAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAADQAQABMAFgAaACAAJgAtADUAQABMAFoAawCAAJgAtAAmAC0ANQBAAEwAWgBrAIAAmAC0ANYA
+AAEwAWkBrQEAAmsAgACYALQA1gAAATABaQGtAQACYALTAl0DAATBBKYFMAFpAa0BAAJgAtMCXQMA
+BMEEpgW3BgAIgglMC24NABBQAF8AcQCHAKEAvwDjAA8BQgF/AccBHgKEAv4CjgM8BP//////////
+//////////////////////////////////////////////////////////////////////////8w
+AWkBrQEAAmAC0wJdAwAEwQSmBbcGAAiCCUwLbg0AEAAAAAAAAgQGAwkGCQAJAAkACQAJAAkAAAAA
+AAAAAAAAAAAAAAAAAAD/////AAAAAGAAAAAFBQUFBQUFBQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+DgAAAA4AAAAOAAAADgAAAAQAAIAAAACAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICCADwAAQABpIAAAaSBAAGkgAABpIEAAICCADwAA6ABp
+IAAAaSBAAGkgAABpIEAAICCADwAAGAFpIAAAaSBAAGkgAABKIAAASiEAAEoiAABKIwAASiQAAEol
+AABKJgAASicAAEogABBKIQAQSiIAEEojABBKJAAQSiUAEEomABBKJwAQSiAAIEohACBKIgAgSiMA
+IEokACBKJQAgSiYAIEonACBKIAAwSiEAMAokgD+AAACgQSycMEAsnDBCJBw0CiKAP4AADDMKIwA3
+UggAAEomAHBpIEAASiYAcEomAHBKJgBwSiYAcAAWAHCAAAQPQHggIECHAAAAAAAAAAAAAIoh/w/P
+cKAAyB8TGFiAICCADwAAAADgfuB+4HjxwFYJIAAB2M91AACECEB9z3agAMAvFIbPd6AArC+LuBmn
+FIbjuP/1YH0C2IogCAAWp2B9A9jPd6AAyB8A2A4fGJAPHxiQEB8YkBEfGJCOCyAAPNhPIEEAGgog
+ADzYSgtAAGIKAABgfQXYz3GgAIQ0BIHPcqAAvDf/uPnzFBESABgREwAMEREABIHTuBpwNhoYgGB9
+B9jPcYAAAA8CIYAPgAAAAEEoAgEAIoMEAiMCIGhwMghgAAHbYH0J2M9woADQGxGA/bj882B9CtgA
+2J24Ex8YkGB9C9jPcYAA7AMC2AChN4bPcIAABAQgoDqGz3CAAAgEIKBgfQzYKnAA2Qpy4g8gAChz
+ANiduA8fGJDPcIAA2AMAEBoAz3EAbQAQz3CfANj/MaBgfQ3YaSCAAG8hPwB9AAAA4Hj8HIi2/BxI
+tvwcCLb8HMi1/ByItfwcSLX8HAi1/BzItPwciLT8HEi0/BwItPwcyLP8HIiz/BxIs+B+4HgE3Djd
+NfDgeATcNN0z8OB4BNww3THw4HgE3CzdL/DgeATcKN0t8OB4BNwk3Svw4HgE3CDdKfDgeATcHN0n
+8OB4BNwY3SXw4HgE3BTdI/DgeATcEN0h8OB4BNwM3R/w4HgE3AjdHPDgeATcBN0Z8DQUGjAwFBkw
+LBQYMCgUFzAkFBYwIBQVMBwUFDAYFBMwFBQSMBAUETAMFBAwAscBxrAkTTOwJB8z4H7hxaHBCHPP
+dYAACA8BlQAchDBPIMIDAeAQeAIchDCPuAG1R2kEIoIPAAD8/+xwQKAAwkCgIrkF8ECgBONhuYHh
+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
+SiZAAOggIgMvIACALyFLAAIhvoDAIIYBwiGGAEomAABCIP6QziCCAUQgfpDOIYIB4H4FAMAA4Hjx
+wCYMr/8B2s9xoADIH89woACwH1agvBEOABHYCgrv/424EfDPcKAAsB8B2lagz3GgAMgfvBEAAMJ4
+jCAfhHAADQDPdaAArC8Yhc9xoADAL+C46vMYhZG4E6EW2AokAHDgeKggQAHgeOB4Eti6Ce//jbgY
+hfG4BPRvIT8Az3WgAKwvGIXPcaAAwC+zuBOhE9iWCe//jbgYhfO4BPJvIT8AFNiGCe//jbjpA4//
+byE/AJMHz//xwM9xgABsOSCBgOEA2Q/yz3OAAEwxA/AB4Y7hVPcWI0IAQIpQcPr1FvDPc4AAvDEC
+8AHhpuFI9xYjQgBAilBw+fUK8M9wAAAHMCoJz/9vIT8AANnRwOB/KHDgeM9wgABsOQGAzvHgeM9w
+gABsOUCAIoDPcIAATDGA4jZ4A/LgfweI4H93EIAAz3GsANQBANiLGRiAjBkYgAfYjRkYgAbZkbnP
+cKAAxCcwoM9xGAAHAjCgz3KAAGw5NIqA4QX0z3EQAAYCMKAggoDhUfIG2Za5MKDPcXgAAoUwoM9x
+AgACgTCgz3FVAAKCMKDPcRAAAoYwoM9xQQAChzCgz3EHAALTMKDPcQEAAoowoM9xAAACpTCgz3EA
+AAKmMKDPcQAAAqcwoM9xBgACqDCgz3EGAAKpMKDPcQYAAqowoM9x/wAHxTCgz3H/AAfbMKDPcf8A
+ByYwoM9x/wAHIzCgz3EYAAIfMKDPccwAAh5X8AfZlrkwoM9xAQAChzCgz3EDAALFMKDPcYAAAtsw
+oM9xcAAChTCgz3FwAAKBMKDPcQYAAtMwoM9xIQACijCgz3EFAAKlMKDPcQUAAqYwoM9xBQACpzCg
+z3EMAAKoMKDPcQwAAqkwoM9xDAACqjCgz3FEAAImMKDPcUQAAiMwoM9xKAACFjCgz3GZAAIVMKDP
+cf8AB4IwoM9x/wAHhjCgz3H/AAcfMKDPcf8ABx4woOB+4HjxwFIJj//PdYAAFA8AjYDgHAACAM9w
+AACQZQokAHDgeKggAAHgeOB4AdgArQbYkLjPdaAAxCcQpc9wgABsOUCAIoDPdqAA7CfPcIAATDGA
+4gXyNngG2Za5BfBw4DZ4B9mWuTClz3EEAAe8MKXPcRAAB7gwpc9xCgAHvDClz3E/AALBMKUiiBC5
+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
+7/4A2RpwSHXPdoAAuA8A2ACm/9pBpkohgCAA2M9zpwA0RPgbGAAU4alwz3cAAHQmYH8B2yCGAqZB
+hqlwFOFgfwLbIIYDpkGGqXB0uWB/AdsghgSmQYapcHS5YH8C2wWmAIbZ///aAKYIcc9wpwA0RPgY
+mABBhqlwFOJgfwPbQYYCpiCGqXAU4mB/BNtBhgOmIIapcHS6YH8D20GGBKYghqlwdLpgfwTbBaYB
+hsb/IIYIcgGmQiFAIIDgYgft/zpwz3OAALACgOUWIwMEBPQgs0GzBPAis0Oz6QLP/vHAigrP/hpw
+KHZId891gAC4MH4N7/6pcM9xoADEJ4DmCfLPcDUAAgMQoc9wNQACBAjwz3AyAAIDEKHPcDIAAgQQ
+oQpwyXHpcrb/gg3v/qlwnQLP/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA
+AAAAAAAAAAIAAAAPAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAF+gAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoPERQAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAtL/AAAAAgAZkEAfAAACAAHSAwAAAAIABNIAAAAA
+AgAF0gAAAACCAArSbm4AAIIAGNIBAAAAggA80gAAAACCAE3SAAAAAIIAS9IDAAAAggAX0gEAAACC
+AD3SAAAAAIIATtIAAAAAggBP0gAAAACCAEzSAAAAAIQAAgAfAAAAhQAAAAsAAACFAAYAQAAAAIUA
+CAAJAAAAhQAJAAkAAACFAAoACQAAAIUAfwAMAAAAAAAAAAAAAAAAAAAAAAAAAAIAAtL/AAAAAgAZ
+kEAfAACFAAcADwAAAIQAAAAAAAAAhAABAAAAAAACABfSAAAAAAIAUHAAAAAAAgBRcAAAAAACAFJw
+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
+nQBkAR8AAQCCAALS/wAAAIIAGZBAHwAAAgAI0gAAAAACAAnSAAAAAAIARdIAAAAAAgBG0gAAAACC
+AAXSAAAAAIIABtIAAAAAggA+kAAAAACCAEPSAAAAAIIARNIAAAAAAAAAAAAAAAAAAAAAAAAAAJQK
+AACcCgAAuAoAANQKAADwBQAAmAoAAKgKAADECgAA4AoAAAwGAAAJAAAAAYAAEYAAFgQCIAASgAAW
+BANAABCAABcEBOAAEIAAFwQFgAARgAAXBAYgABKAABcEB0AAEIAAGAQI4AAQgAAYBAmAABGAABgE
+CiAAEoAAGAQLQAAQgAAZBAzgABCAABkEDYAAEYAAGQQOgAAQgAAaBCKAABgAABYAJAAAGQAAFgEm
+AAAiAAAWASgAABoAABYBKoAAGgAAFgEsAAAgAAAXAS6AABgAABcBMAAAGQAAFwE0AAAaAAAXATaA
+ABoAABcBOAAAIAAAGAE8AAAZAAAYAT4AACIAABgBQAAAGgAAGAFkAAAaAAAbAmaAABoAABsCaAAA
+IAAAHAJsAAAZAAAcAm4AACIAABwCcAAAGgAAHAJ0AAAgAAAdAnaAABgAAB0CeAAAGQAAHQJ8AAAa
+AAAdAn6AABoAAB0CgAAAIAAAHgKEAAAZAAAeAoYAACIAAB4CiAAAGgAAHgKMAAAgAAAfApFAABkA
+AB8DlQAAIwAAHwOXwAAaAAAfA5lAABgAACADnUAAGQAAIAOfwAAZAAAgA6EAACMAACADpUAAGAAA
+IQMAAwkAAwMJAAkAAwkOAAAAKgAAAAcAAAALAAAAAAIEBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIIAP
+AABAAGkgAABpIEAAaSAAAGkgQAAgIIAPAADoAGkgAABpIEAAaSAAAGkgQAAgIIAPAABgAWkgAABp
+IEAAaSAAAEogAABKIQAASiIAAEojAABKJAAASiUAAEomAABKJwAASiAAEEohABBKIgAQSiMAEEok
+ABBKJQAQSiYAEEonABBKIAAgSiEAIEoiACBKIwAgSiQAIEolACBKJgAgSicAIEogADBKIQAwCiSA
+P4AAAKBBLJwwQCycMEIkHDQKIoA/gAAIDwojADeaCAAASiYAcGkgQABKJgBwSiYAcEomAHBKJgBw
+ABYAcIAABA9AeCAgQIcAAAAAAAAAAAAA4cWYcCh1BLjPcZ8A2P8SoQQkgA8A8AAARXgTobahgOMF
+8s9wAG0AEBGh4H/BxeB4z3KfANj/EqIzomnYGLgRouB+4HjPcZ8A2P/Pcp8AuP8SoWrYGLgRoRyC
+4H7gfuB44H7gePHA+gggAADZz3agAMAvFIbPcqAArC/PdaAAhDSLuBmiZYUYFQQQDBUFEBAVBhAU
+huO4//WKIAgAFqLPdaAAyB/Pd6AA0BsOHViQDx1YkBAdWJARHViQPNji/08gQQA82Nv/aHAA2Ze5
+iHIB28z/EYf9uP/zAN+dv89xgADsAwHYEx3YkwChN4bPcIAABATIciCgOobPcIAACAQgoKhwANko
+c7//Dx3Yk89wgADYAwAQGgDPcQBtABDPcJ8A2P8xoGkggABvIT8AmQAAAPwciLb8HEi2/BwItvwc
+yLX8HIi1/BxItfwcCLX8HMi0/ByItPwcSLT8HAi0/BzIs/wciLP8HEiz4H7geATcON018OB4BNw0
+3TPw4HgE3DDdMfDgeATcLN0v8OB4BNwo3S3w4HgE3CTdK/DgeATcIN0p8OB4BNwc3Sfw4HgE3Bjd
+JfDgeATcFN0j8OB4BNwQ3SHw4HgE3AzdH/DgeATcCN0c8OB4BNwE3RnwNBQaMDAUGTAsFBgwKBQX
+MCQUFjAgFBUwHBQUMBgUEzAUFBIwEBQRMAwUEDACxwHGsCRNM7AkHzPgfg==
+====
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
-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
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-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..e69de29bb2d
diff --git a/sys/contrib/dev/iwn/iwlwifi-5000-8.24.2.12.fw.uu b/sys/contrib/dev/iwn/iwlwifi-5000-8.24.2.12.fw.uu
new file mode 100644
index 00000000000..72e45e32920
--- /dev/null
+++ b/sys/contrib/dev/iwn/iwlwifi-5000-8.24.2.12.fw.uu
@@ -0,0 +1,6239 @@
+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-5000-8.24.2.12.fw.uu
+DAIYCIz+AQAAwAAANOUBAADAAAAAAAAAICCADwAAQABpIAAAaSBAAGkgAABpIEAAICCADwAA6ABp
+IAAAaSBAAGkgAABpIEAAICCADwAAnAVpIAAAaSBAAGkgAABKIAAASiEAAEoiAABKIwAASiQAAEol
+AABKJgAASicAAEogABBKIQAQSiIAEEojABBKJAAQSiUAEEomABBKJwAQSiAAIEohACBKIgAgSiMA
+IEokACBKJQAgSiYAIEonACBKIAAwSiEAMAokgD+AAADAQSycMEAsnDBCJBw0CiKAP4AA8FoKIwA3
+Gg8AAEomAHBpIEAASiYAcEomAHBKJgBwSiYAcAAWAHCAAFgEQHggIECHAAAAAAAAAAAAAArIz3Gg
+AMgfDhkYgAvIDxkYgAzIEBkYgA0SAjYAyER4ERkYgA7ILRkYgOB+4cT8HMi+/BxIvuHA4cHhwuHD
+/BwIsfwcSLH8HIix/BzIsfwcCLL8HEiy/ByIsvwcyLL8HAi/aiSAEOHEaiTAEOHE8cDPcKAA0BsU
+gM9xgABUBAQggI/PUQThAKEK8i8pAQDPcIAAPAnwIEAAQHja/9HAwcRrJMAQwcRrJIAQwcSfdAQU
+CzQEFAo0BBQJNAQUCDQEFAc0BBQGNAQUBTQEFAQ0wcPBwsHBwcDBxEUsfhAKJkB+wcRrJIAUwcQg
+IECHCsiHuAoaGDALyJu4CxoYMAzIDBoYMA3Ih7gNGhgwDsiFIMMPDhoYMOB+4HjxwArIlbgKGhgw
+C8ibuAsaGDANyIq4jbiQuA0aGDDPcIAAZAoYiIHgC/QNyM9xAACgCqy4DRoYMM4NIAAP2GfY5g7g
+AIohhgjRwOB+z3CAAOSbAICGIP6BCPQNyAUggA8AAADUDRoYMEDx4HjxwM9xAwBADc9woACoIC2g
+z3KAAJQEIIIBaQCiWg4gAUjYz3CAAKAIJYAjgSCBx3EAAIgTjgyACNLx4HjPcIAAoAgdBIAI4Hjx
+wMoKQAGA4M92gABUBAbygeAG9AHYA/AA2AuugOEG8oHhBvQB2APwANgKroDiBvKB4gb0AdgD8ADY
+DK4A2M91oADIHxgdGJALjoDgiiEQAA7yCI6A4Azyz3ADAEANRR0YEDClAtgYHRiQA/AxpQqOgOAa
+8gmOgOAW8s9wAQCK/iAdGJDPcIAAJAAhHRiQz3CAAFAEIh0YkBgVAJZFIAADGB0YkAyOgOAH8hgV
+AJaFIAEEGB0YkIDjGPIA2JS4z3aAAIgEAKZx2Aa4tgggAfzZIIbPcAAATBymCCABn7kYFQCWhbgY
+HRiQTQJAAc9xqqq7u89wnwC4/zagNqA2oDagz3GgAMg7DoGIuA6haSBAAP7x4HjxwKXBQcBCwQwc
+ADEQHEAxz3GAAPxbNBnADzAZAA8sGcAOKBmADiQZQA7PcIAA/FsgGEALz3CAAPxbHBgAC89wgAD8
+WxgYwArPcIAA/FsUGIAKz3CAAPxbEBjACM9wgAD8WwwYgAjPcIAA/FsIGEAIz3GAAIBbgBkACHwZ
+wAd4GYAHdBlAB3AZAAdsGQAHaBmABmQZQAZgGQAGXBnABVgZgAVUGUAFUBkABUwZwARIGYAERBlA
+BEAZAATvoc6hraGMoSwZwAIoGYACJBlAAiAZAAIcGcABGBmAARQZQAEQGQABY6FqIAAD2BkAAGog
+wALUGQAAaiCAAtAZAABqIEAByBkAAGogAAHEGQAAaiDAAMAZAABqIIAAvBkAAGogQAC4GQAAaiAA
+ALQZAABqIIABzBkAANDYn7jPcZ8AuP8doc9wgAAAAMSAUyXENVMmxTXXugHm077EoFMjwAQFJo4f
+0P4AANahBSCAD7D+AAAWoRiBUyfONQDdlLgYoUDDAcACwclzDBQGMCYM4AAQFAcwz3CgALQPvKDP
+caAAyDsugb4L4AB92FoMQAH2DuAAqXAI2ADZtg7gAJm5EPHxwM4PIAF72JoL4ADX2c9xgAD8WzQZ
+wA8wGQAPLBnADigZgA4kGUAOz3CAAPxbIBhAC89wgAD8WxwYAAvPcIAA/FsYGMAKz3CAAPxbFBiA
+Cs9wgAD8WxAYwAjPcIAA/FsMGIAIz3CAAPxbCBhACM9xgACAW4AZAAh8GcAHeBmAB3QZQAdwGQAH
+bBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARAGQAE76HOoa2hjKEs
+GcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC1BkAAGoggALQGQAA
+aiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0GQAAaiCAAcwZAADr
+ds91oADIHxkVEZbPcAAARBxOCiABCiDAL1pwz3CAANwoI4DPc58AuP/Pd4AAAAAEh4DhAeDTuCTy
+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
+BwBCJSaiz3EAAII+JqLPcQAAQj4mos9xAQCCPiaiz3EBAEI+JqLPcQIAgj4mos9xAwBCPiaiz3ED
+AII+JqLPcQcAQj4mos9xAADCVyaiz3EAAEJYJqLPcQEAwlcmos9xAQBCWCaiz3ECAMJXJqLPcQMA
+Qlgmos9xAwDCVyaiz3EHAEJYJqLPcRsAAh4mos9xGwBCNyaiz3EbAMJQJqLPcQAAQiEmos9xAACC
+ISaiz3EGAMIhJqLPcwEAQiFmos9zAQCCIWaiJqLPcwIAQiFmos9zAwCCIWaiJqLPcwMAQiFmos9z
+BwCCIWaiJqLPcQAAwjomos9xAACCOiaiz3MGAAI7ZqLPcQEAwjomos9xAQCCOiaiZqLPcQIAwjom
+os9xAwCCOiaiZqLPcQMAwjomos9xBwCCOiaiZqLPcQAAQlQmos9xAAACVCaiz3MGAIJUZqLPcQEA
+QlQmos9xAQACVCaiZqLPcQIAQlQmos9xAwACVCaiZqLPcQMAQlQmos9xBwACVCaiZqLPcXkAwh8m
+os9xeQACOSaiz3F5AIJSJqLPcRAAQiomos9xMwCCKiaiz3EBAMIqJqLPcRAAgkMmos9xMwDCQyai
+z3EBAAJEJqLPcRAAAl0mos9xMwBCXSaiz3EBAIJdJqKA4A7yz3EtAEIeJqLPcS0Agjcmos9xLQAC
+UQ3wz3FqAEIeJqLPcWoAgjcmos9xagACUSaiz3E/AIIpJqLPcQEAwikmos9xPwDCQiaiz3EBAAJD
+JqLPcT8AQlwmos9xAQCCXCaiz3EIAAIBJqKA4BLyz3AAAAIqBqLPcAIAAisGos9wAABCQwaiz3AC
+AEJEBqLPcP8AAmcGos9w/wBCZwaiz3D/AIJnBqLPcP8AwmcGos9w/wBCdQaiz3D/AIJ1BqLPcP8A
+wnUGos9w/wCCHQaiz3D/AMI2BqLPcP8AQlAGos9wgAACDAaiz3ADAMYABqIg3s91oADIH9ClMthD
+HRgQANiSD6/0jbjRpScEz//gePHA4cXPcYAAcGUEkc9ygADMiYDgANtgohHygeAn8oLgPvIKIcAP
+63IF2Iojhw1KJEAAYQWv80olAAAH2Bi4AKJhqmKqSiTAcGhwqCAAAwDbjrsWIg0AYaUD2w67YqUB
+4APYBrEHsQDYF/AA2Jm4AKJS2AGqSiTAcAKqqCCAAgDdj70WIsAAoaCioAHjUtgC22axAdtnsSUH
+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
+7/4F2Aylw9jPdqAA7CcGpgqGz3erAKD/ALWKIMQABqYKhgG1iiDFAAamCoYCtYogywAGpgqGA7WK
+IM8ABqYKhgS1z3AAAIMNBqYKhgW1z3AAAMMNBqYKhga1z3AAAAMOBqYKhge1z3CnABRICIAEpc9w
+pwCYRzyAJaXPcacAFEhXgTaBRqUnpc9xpQAIDCKBxtoopTiHkLoppTmHKqU6hyulz3EFAMYDJqYB
+2Uamz3IsAAIBRqbPcloAQgFGpooiiwBGps9yQACHDUamz3LRAMINRqbPcsAABw5Gps9ypwAUSCii
+z3JQAP8AXKDPcKcAFEg3oADZNqDPcKUACAxQ2SKg/NgYp3PYGacah4G4GqfPcBEABg4GpotwgcGV
+/zOFAMBShSJ4NIUKuLILr/tCeYQohANCKUFyNrkBwidxSrmCIcQCz3CAADByMKVVoDagz3BAAIYN
+BqbPcBAAAg4GpotwgcGD/zOFAMBShSJ4NIUKuGoLr/tCeQQogA8AAHQJQilBcja5AcIncUq5T+HP
+cIAAMHIxpVegOKABlRC4hSCEAAamApUQuIUghQAGpgOVELiFIIsABqYElRC4hSCPAAamBZUQuAUg
+gA8AAIINBqYGlRC4BSCADwAAwg0GpgeVELgFIIAPAAACDgamJIXPcKcAFEgooCaFIBUFEDegJ4VM
+JQCANqDPcKUACAwIGEAByiHCD8oiwgfKIGIByiOCDwAA9QAkAGLzyiQiAAmFGKcKhRmnC4Uap64K
+7/4MhYog0QVmDS/0MIUQhRkCr/SiwPHAqgmP9M9wgABwZQeIgOAcAiEAosE+Ce/+BdjPdYAA5D0M
+pcPYz3agAOwnBqYKhgDbALWKIMQABqYKhs9xpwCYRwG1iiDFAAamCobPd6sAoP8CtYogywAGpgqG
+A7WKIM8ABqYKhgS1z3AAAIMNBqYKhgW1z3AAAMMNBqYKhga1z3AAAAMOBqYKhge1z3CnABRICIAE
+pRyBBaXPcKcAFEhXgBaARqUHpc9wpQAIDAKAxtoIpRiHkLoJpRmHCqUahwulz3AFAMYDBqYB2Eam
+z3IsAAIBRqbPcloAQgFGpooiiwBGps9yQACHDUamz3LRAMINRqbPcsAABw5Gps9ypwAUSAiiz3JQ
+AP8AXKHPcacAFEgXoXahz3ClAAgMUNkioPzYGKdz2BmnGoeBuBqnz3AqAAIOBqaLcIHB+v4Awc9w
+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
+aqAxGEIBMhhCAduwWrAeCG/yDOABhQjZMqgEwYDhBvLPcIAAJAgkoGIK7/SpcGUBT/LgeM9wgABA
+fiiAz3CfALj/ANo2oAjZ7HAgoAPZz3CgABQEJaAByOxxAKHPcKAA1AtNoOB+4HjPcYAAOAjgfwCh
+4HjPcIAAOAjgfwCA4Hi1AA/ysQAP8uB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwDY4H8A
+2OB+4HihweB/ocDgeOB+4HjxwOHFAcjPdYAAZEMApQRtMgkv8gLZz3GADgQA7HAgoM4P7/EAhcEA
+T/LgeOB+4HjgfuB48cAAFgBBz3KAAGRDBrIAFgVBQCIBBA4aRAFMJYCEyiHCD8oiwgfKIGIByiOC
+DwAARABYBuLwyiQiAADaB/AAFgBBFCGMAAC0AeIvIEIBEHK39oIID/LRwOB+4HjgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjPcIAAPAjgfwCA4HjgfuB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
+4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB/Adjg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB48cDhxc91gACkQ6lwsg/v8QPZABWFEEQlQAGF4MohwQ/KIsEHyiBhAcojgQ8AAE8ACAXh
+8MokYQABjYPgw/ZjuAGtQg/P8R0HD/LgePHAmg4P8hpxz3aAAKRDII5RIQCARvLPcYAARAggiYDh
+zCAhoD7ygeAG9M9wgADoiaGAA/AA3Y7lA/eA5QL0AN3PcYAA6IkYiYDgBPSA5QT0AN8E8KKBBN+K
+IBMB7gnv8alxiiBTAeYJ7/Hpcc9wgABkChiIg+DMICKBzCDigcwgIoII8oogEwHCCe/xi9kK8AqW
+EHUI9AuWEHfMICGgBPQA2CHwAdjPcaAAyB8Noc9wgABECAGI67aqtgS/ELjlfQV9iiATAYYJ7/Gi
+2YogEwF6Ce/xqXHPcKAAyB9/GFiDAdgdBg/y4HjxwLYNL/IIccT/gOA88iDdz3agAMgfsKYy2EMe
+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
+IAkAACAJAAB4CgAAeAoAAHgKAAB4CgAARAoAAHgKAAB4CgAAeAoAAHgKAAB4CgAAwAsAAHgKAAB4
+CgAAnAgAAAMAAACg4wEAAgAAAMw7AQAEAAAAHDEAAAYAAABQ5QEAEQAAAKi0AQAHAAAANNcBAAgA
+AADQ5QEADAAAAJxUAQANAAAAtFgBAA4AAADsWAEAFgAAAFQuAQALAAAAqGwBABQAAAAwVQAADwAA
+ALhjAAAQAAAA9CUBAAEAAAAQ0wEAEgAAADyBAQATAAAAsHIBAAUAAAAUZwAAFQAAALD0AQAXAAAA
+vAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnCUAAJwlAACcJQAAPDcAAJwlAACcJQAAMDcAAJwl
+AACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAHQaAAAYHAAAHBwAAJQdAAAcHgAAmB0A
+AJwlAACcJQAA7D8AAGBDAAA0RAAAnCUAAJwlAACcJQAAsD4AAPixAAD0sQAAMLIAAJwlAACcJQAA
+nCUAAEA3AACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACc
+JQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwl
+AACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAMDgAAJwlAACcJQAAnCUAAJwlAACcJQAAFDkA
+AJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAVP4AAJwlAAB8/wAA
+nCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACoZgAAnCUAAJwlAACcJQAAnCUAAJwlAACc
+JQAAnCUAAJwlAACcJQAAnCUAAJwlAAB0awEA/G4BAJwlAAAwVQEAnCUAAJxWAQBIRgEAnCUAAJwl
+AACwRAAAnCUAAJwlAACcJQAAnCUAAJwlAAC4vAEAYLYBAJwlAACcJQAAnCUAAJwlAACcJQAAnCUA
+AJwlAADo5AEA7OQBAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAADXAQCcJQAANNoBAJwlAADY9QEA
+nCUAAPQgAAD4IAAAnCUAAJwlAACo5gEANFUAAJwlAACcJQAAnCUAAHzRAQCcJQAAnCUAAPAmAQCc
+cgEAnCUAAJwlAACcJQAAeHkBAGRBAQCcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACshwEAnCUAALTl
+AQC45QEAxOUBAMjlAQC85QEAwOUBAMzlAQCcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUA
+AJwlAACIRgAAnCUAAJwlAACcJQAAnCUAAJwlAAAk5QEAWOUBAEg7AACcJQAAnCUAAJwlAACcJQAA
+nCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACc
+JQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwlAACcJQAAnCUAAJwl
+AACcJQAAnCUAAJwlAACcJQAA7DsAAGw8AAD0PAAAkD0AAFhiAABoPQAAnCUAAJwlAACcJQAAnCUA
+AJwlAADkOwAA6DsAAJwlAACcJQAA4EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAABAAAAABAAAAAQEAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAADhAw4e4eEDDh7hwQIKHuGBBQwe4eEDDh7h4QMOHuHBAgYe4YEFDB7hAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEB
+AQ0NDQ0NDQ0NDQ0NDQ0NDQ0DAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEB
+AQEBAQEBAQENDQ0NDQ0NDQ0NDQ0NDQ0NAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAB
+AQEBAQEBAQEBAQEBAQEBDQ0NDQ0NDQ0NDQ0NDQ0NDQMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAA
+AAAAAAAAkQIAADHKLwCRAgAAMcovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAJECAAAxyi8AkQIA
+ADHKLwCRAgAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAA
+McovAEMBAAAxyi8AQwEAADHKLwBADQAA3gMJAAAAAAAAAAAAAAAAALz9AAABAAAAMC2AAAAAAAAA
+AAAAAAAAAEz+AAAVAAAAcC2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA
+AAADAAAAAAAAAAgAAAAAAAAAQEIPABQCAQD4AgEACAQBANQFAQAIBAEA1AUBAIAHAQAECAEAgICA
+gICAgIABgAKAgICAgAAAAABwEAEAcBABAAAAAAAAAAAAAAAAAAAAAABwEAEAcBABAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAwLYAAMC2AAKQgoAA4IKAAAQAAAPz///8AAAAAAAAAAFAtgABQ
+LYAAqCCgADwgoAAIAAAA8////wAAAAAAAAAAcC2AAHAtgACsIKAAbCCgADAAAADP////AAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAQnAQAFAAAAcC2A
+ADAsAQAA/wMAUCwBAAD/BQA8LQEAAP8tAGAtAQAA/z0AGC0BAAD/BAD8LAEAAP8lABQ0AQAANQEA
+dDUBAJAwAQDILwEAYDYBAOg2AQAsNwEAfDcBAAAAAAAsAQAAXgEAAAEAAAABAAAAAQAAAAEAAAAD
+AAAAAAAAAAAAAAAAAAAAAwAAAAIAAAADAAAAAwAAAAMAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAA
+AAA0PQEACgAAADAtgAAAAAAAAAAAAAAAAADAPQEACgAAADAtgAAAAAAAAAAAAAAAAAD0PQEACgAA
+ADAtgAAAAAAAAAAAAAAAAABsPgEACgAAADAtgAAAAAAAAAAAAAAAAACMPwEACgAAADAtgAAAAAAA
+AAAAAAAAAAAEPwEACgAAADAtgAAAAAAAAAAAAAAAAACERQEABgAAADAtgAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAQAAAAAIAAAAAAoAAQJwAA6AMAAOgDAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAyFsBAMhcAQBsXwEACGIBAGxkAQCkZwEAWF4BABwFgAAIfoAAGAAA
+AMh9gAAAAAAAAAAAAAAAAAAAAAAAAAAAALxpAQAGAAAAMC2AAAAAAAAAAAAAAAAAAOwXAQAKAAAA
+MC2AAAAAAAAAAAAAAAAAAOwXAQAKAAAAMC2AAAAAAAAAAAAAAAAAAOwXAQAKAAAAMC2AAAAAAAAA
+AAAAAAAAAOwXAQAKAAAAMC2AAAAAAAAAAAAAAAAAAOwXAQAKAAAAMC2AAAAAAAAAAAAAAAAAAOwX
+AQAKAAAAMC2AAAAAAAAAAAAAAAAAAOwXAQAKAAAAMC2AAAAAAAAAAAAAAAAAAOwXAQAKAAAAMC2A
+AAAAAAAAAAAAAAAAAOwXAQAKAAAAMC2AAAAAAAAAAAAAAAAAAOwXAQAKAAAAMC2AAAAAAAAAAAAA
+AAAAAOwXAQAKAAAAMC2AAAAAAAAAAAAAAAAAAOwXAQAKAAAAMC2AAAAAAAAAAAAAAAAAAKhwAQAK
+AAAAMC2AAAAAAAD//////////wAAAAAAAAAAAAAAACxyAQAFAAAAcC2AAGQAZABpANwAyABaAKoA
+vgCGAX0APgBkAGQAaQDcAMgAWgCqAL4AhgF9AD4AAAAAAAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAQIBAQACAQABAgICAAEBAAIBAgECAAIAAQIDAAAAABSHAQCElAEABIqAAMADAAAAAAAAFIcB
+AECIAQDEjYAA+AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANyYAQDglgEAvI+AAFQAAAAAAAAA
+FIcBABCXAQA8kIAAUAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABSHAQCIkwEAhDeAAFABAAAA
+AAAA8JgBAJiVAQC8BoAAAgAAAAAAAAAUhwEAxJUBAMAGgAAEAAAAAAAAAMiYAQBAiAEAEJCAACwA
+AAAAAAAAFIcBADCWAQAAAAAAAAAAAAAAAAAUhwEA8JUBAMQGgAAEAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAgACAAIQAiACIAIwAkACQAJQAmACYA
+QwBEAEQARQBGAEYARwBIAEgASQBKAEoASwBMAEwATQBOAE4ATwBQAFAAUQBuAG4AbwBwAHAAcQBy
+AHIAcwB0AHQAdQB2AHYAdwB4AHgAeAB4AHgAeAB4AHgAeAAPAD8AAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAQABAAIAAwADAAQABQAFAAYABwAHAAgACQAJAAoAIwAjACQAJQAlACYAJwAn
+ACgAKQApAEYARwBHAEgASQBJAGYAZwBnAGgAaQBpAGoAawBrAGwAbQBtAG4AbwBvAHAAcQBxAHIA
+cwBzAHQAdQB1AHYAdwB3AHgAeAB4AHgAeAB4AHgAeAAOAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAgACAAIQAiACIAIwAkACQAJQAmACYAQwBEAEQA
+RQBGAEYARwBIAEgASQBKAEoASwBMAEwATQBOAE4ATwBQAFAAUQBuAG4AbwBwAHAAcQByAHIAcwB0
+AHQAdQB2AHYAdwB4AHgAeAB4AHgAeAB4AHgAeAAPAEMAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAIA
+AwADAAQABQAFAAYABwAHAAgACQAJAAoAIwAjACQAJQAlACYAJwAnACgAKQApAEYARwBHAEgASQBJ
+AGYAZwBnAGgAaQBpAGoAawBrAGwAbQBtAG4AbwBvAHAAcQBxAHIAcwBzAHQAdQB1AHYAdwB3AHgA
+eAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAIAEMAeHcBABLSAAAAAAAA//8PAOCQAQC2AAAAAAAA
+AP8AAADgkAEAtwAAAAAAAAD/AAAA4JABALgAAAAAAAAA/wAAAOCQAQC5AAAAAAAAAP8AAADgkAEA
+ugAAAAAAAAD/AAAA4JABALsAAAAAAAAA/wAAAOCQAQC9AAAAAAAAAP8AAADgkAEAvgAAAAAAAAD/
+AAAA4JABAL8AAAAAAAAA/wAAAOCQAQDAAAAAAAAAAP8AAADgkAEAwQAAAAAAAAD/AAAA4JABAMIA
+AAAAAAAA/wAAAHh3AQAT0gAAAAAAAP//DwDgkAEAGwEAAAAAAAD/AAAA4JABABwBAAAAAAAA/wAA
+AOCQAQAdAQAAAAAAAP8AAADgkAEAHgEAAAAAAAD/AAAA4JABAB8BAAAAAAAA/wAAAOCQAQAgAQAA
+AAAAAP8AAADgkAEAIgEAAAAAAAD/AAAA4JABACMBAAAAAAAA/wAAAOCQAQAkAQAAAAAAAP8AAADg
+kAEAJQEAAAAAAAD/AAAA4JABACYBAAAAAAAA/wAAAOCQAQAnAQAAAAAAAP8AAAB4dwEAFNIAAAAA
+AAD//w8A4JABAIIBAAAAAAAA/wAAAOCQAQCDAQAAAAAAAP8AAADgkAEAhAEAAAAAAAD/AAAA4JAB
+AIUBAAAAAAAA/wAAAOCQAQCGAQAAAAAAAP8AAADgkAEAhwEAAAAAAAD/AAAA4JABAIkBAAAAAAAA
+/wAAAOCQAQCKAQAAAAAAAP8AAADgkAEAiwEAAAAAAAD/AAAA4JABAIwBAAAAAAAA/wAAAOCQAQCN
+AQAAAAAAAP8AAADgkAEAjgEAAAAAAAD/AAAAeHcBAAjSAAAAAAAA//8DALh3AQAAggAAAAAAAP8B
+AAC4dwEAAYIAAAAAAAD/AQAAeHcBAAnSAAAAAAAA//8DALh3AQACggAAAAAAAP8BAAC4dwEAA4IA
+AAAAAAD/AQAAeHcBAArSAAAAAAAA//8DALh3AQAEggAAAAAAAP8BAAC4dwEABYIAAAAAAAD/AQAA
+eHcBAAbSAAAAAAAA/wEAAHh3AQAH0gAAAAAAAP8DAAB4dwEABtIAAAkAAAAA/gMAeHcBAAfSAAAK
+AAAAAPwPAHh3AQAG0gAAEgAAAAAA/Ad4dwEAB9IAABQAAAAAAPA/eHcBABXSAAAAAAAA/wMAAHh3
+AQAM0gAAAAAAAP8BAAB4dwEAFdIAAAoAAAAA/A8AeHcBAAzSAAAJAAAAAP4DAHh3AQAV0gAAFAAA
+AAAA8D94dwEADNIAABIAAAAAAPwHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHNIN0hHSENIC
+0gHSA9Ib0gvSAIAF0hLSE9IU0gRDBtIH0gTSCRAAALUAGgGBAQUABAAGAAgACQAKAAsADACDAJIA
+6AD3AE4BXQEPAC4AAABsAAAAdAAAAIAAAACMAAAAnQAAAAcAAAAEAAAACAAAABAAAABAAAAAgAAA
+ACAAAAAAAAAACQAAABIAAAAAAAAACgAAABQAAAAcBYAACH6AABgAAADIfYAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAATLgBAAYAAAAwLYAAAAAAAAAAAAAAAAAAhNQBAAYAAAAwLYAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcBYAACH6AABgAAADIfYAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAABwFgAAIfoAAGAAAAMh9gAAAAAAAAAAAAAAAAAAAAAAAAAAAABThAQAEAAAAMC2AAAAAAAAA
+AAAAAAAAAOjfAQAEAAAAMC2AAAAAAAAAAAAAAAAAANzhAQAGAAAAMC2AAAAAAAAAAAAAAAAAAOjf
+AQAEAAAAMC2AAAAAAAAAAAAAAAAAABThAQAEAAAAMC2AAAAAAAAAAAAAAAAAAOjfAQAEAAAAMC2A
+AAAAAAAAAAAAAAAAABThAQAEAAAAMC2AAAAAAAAAAAAAAAAAAOjfAQAEAAAAMC2AAAAAAAAAAAAA
+AAAAANzhAQAGAAAAMC2AAAAAAAAAAAAAAAAAAOjfAQAEAAAAMC2AAAAAAAAAAAAAAAAAABThAQAE
+AAAAMC2AAAAAAAAAAAAAAAAAANzhAQAGAAAAMC2AAAAAAAAAAAAAAAAAABThAQAEAAAAMC2AAAAA
+AAAAAAAAAAAAABThAQAEAAAAMC2AAAAAAAAAAAAAAAAAANzhAQAGAAAAMC2AABwFgAAIfoAAGAAA
+AMh9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAFAUAAAAAAAAAAAAAAAAAAAAAAP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECAwQEBAQEBQYHCAgICAgJ
+CgsMDQAAAAUGBwgNDg8QFRYXGBkAAAoNERQKDREUCg0RFAoKAAAAAAAABgYGBgkJCQkABgAAbjto
+O2I7XDtuOmg6YjpcOm45aDliOVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbihoKGIoXChuJ2gn
+YidcJ24ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24JaAliCVwJbghoCGIIXAhuB2gHYgdcB24GaAZi
+BlwGbgVoBWIFXAVuBGgEYgRcBG4DaANiA1wDbgJoAmICXAJuAWgBYgFcAW4AaABiAFwAbjtoO2I7
+XDtuOmg6YjpcOm45aDliOVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbihoKGIoXChuJ2gnYidc
+J24ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24JaAliCVwJbghoCGIIXAhuB2gHYgdcB24GaAZiBlwG
+bgVoBWIFXAVuBGgEYgRcBG4DaANiA1wDbgJoAmICXAJuAWgBYgFcAW4AaABiAFwAAAAAAAAAAAAA
+AAAAUPoBAAgAAABwLYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAA/////////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/////////////////////////////////////
+/////////////////////////////////////////wEEAAACBQEAAwYCAAQHAwAFCAQABgkFAAcK
+BgAICwcACQwIAAoNCQALDgoADA8LAA0QDAAOEQ0AAUEABAJCAQQDQwIEBEQDBAVFBAQGRgUEB0cG
+BLcTIgC4FCMAuRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgcAQALHQIADB4DABAfBAAiIQUA
+JCIGACYjBwAoJAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsPAEAsEABkLhEAaC8SAGwwEwBw
+MRQAdDIVAHgzFgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0AmTweAJ09HwChPiAApT8hACRJ
+BgIsSgoCNEsNATxMDwFkTREBbEMTAXRPFQF8UBcBhFEZAZVSHQGdUx8BAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQWCBYWFgwWFhYWFhYW
+EAAAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8A
+AgAAAA8APwABAAAAAAAAAAEAAAACAAAAAwAAAAAAAAAEAAAAAgAAAAUAAAAYCAGlDAIApQA8ODQw
+LCgkIBwYFBAMCAQADAgEADw4NDAsKCQgHBgUEAwIBAIAFQ8AAAAAGwAAAAEBAAECAQEBAQEBAQEB
+AQECAgICAgICAgMDAwMDAwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQEBAQEBAQE
+BAQEBAQEBAQEBAQEBAQAAAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgMEBgZ00UUX
+6KKLLg0PBQcJCwEDChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHKAAoADAALAAs
+ACgAPAA0ACgAKAA0ADAALAAsAEQAPABAADwAjABsAFgASAD0ALAALAAsADwANAAwACwAVABEAFQA
+VABsAGAAXABUAIwAeAA6AQIB1QDfANoAogB1AH8AagEaAdkA6AAKAboAeQCIAIoFKgM5AagBigXK
+AtkASAHKAUoB4gD5AMoB6gCCAJkAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAP
+TuzETid2YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAaw
+stUFBVRABSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEY
+gREN0iANCqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iA
+Bwd4gAcGaZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkH
+CqiACgiMwAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEDQAaACcANABO
+AGgAdQCCABoANABOAGgAnADQAOoABAEnAE4AdQCcAOoAOAFfAYYBNABoAJwA0AA4AaAB1AEIAgwA
+TgBoAIIAdQCcAMMAaACCAIIAnAC2ALYA0ACcAMMAwwDqABEBEQE4AYIAnAC2AJwAtgDQAOoA0ADq
+AAQBBAEeAcMA6gARAeoAEQE4AV8BOAFfAYYBhgGtAQAAMAAAADYAAAAMAAAAEgAAABgAAAAkAAAA
+BgAAAAkAAAAAAAAAAAAAABggFBQODhQUBQYBAgMEAAAAAQECAQICAwQMDAgEDAQEQAAAAIAAAAAA
+AQAAAAIAAEAAAAAABAAAQAAAAEAAAAAQERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uL0BB
+QkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6
+e3x9fn8tAA8gAPBhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApcaE+JnujfYN/73Wsd5UkVBg
+AwKpzn1WGediteZNmuxFj50fQImH+hXv67LJjgv77EFns/1f6kW/I/dTluRbm8J1HOGuPWpMWmxB
+fgL1T4NcaPRRNNEI+ZPic6tTYj8qDAhSlWVGXp0oMKE3Dwq1LwkONiSbGz3fJs1pTs1/n+obEp4d
+dFguNC02stzutPtb9qRNdmG3zn17Uj7dcV6XE/WmaLkAACzBYEAf48h57ba+1EaN2WdLct6U1Jjo
+sEqFa7sqxeVPFu3FhteaVWaUEc+KEOkGBIH+8KBEeLol40vzov5dwICKBa0/vCFIcATx32PBd3Wv
+Y0IwIBrlDv1tv0yBFBg1Ji/D4b6iNcyIOS5Xk/JVgvxHeqzI57orMpXmoMCYGdGef6NmRH5UqzuD
+C8qMKcfTazwoeafivB0Wdq0721ZkTnQeFNuSCgxsSOS4XZ9uve9DpsSoOaQxN9OL8jLVQ4tZbrfa
+jAFksdKc4Em02PqsB/Mlz6/KjvTpRxgQ1W+I8G9KclwkOPFXx3NRlyPLfKGc6CE+3ZbcYYYNhQ+Q
+4EJ8xHGqzNiQBQYB9xIco8Jfavmu0GmRF1iZJzq5JzjZE+uzKzMiu9JwqYkHpzO2LSI8khUgyUmH
+/6p4UHqljwP4WYAJFxraZTHXxoS40MOCsCl3WhEey3v8qNZtOiwAAQIEBAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAFk4wAB0wLLAnMBtAACwsGUGsH2GsLBKAAkAAAACAAAAAAAAAAAAAAAJAAAAAgAA
+AAAAAAAAAAAACQAAAAMAAAABAAAACQAAAAkAAAACAAAAAgAAAAkAAAABAgECAwQAAAUGBwgJCgAA
+AAUGAAIEAAUAAAAAAAUHAQMEAAUBAAAAQCNAJSEhISFAQEBAQAUEBAEBQEBAQAUFQEAMDEANDAwB
+AQEFQEAFBQAEAARAQAAEQEBABUBAQEBABUBAQAUFBQEBAQFABQUFAQUBAUAFBQVABUAFBQUFBQQA
+AAAcEQAAHDIAABwzAAAEAAAAHBUAAAIAFwBsAHAEdAh0DAAEBAYAAAAAAAAAAGQAAAAAkAEACgAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAAAAAAAAAAAAAAAAP8AAAAA
+AAAAAAAAAAAAAAAAAAAAAQAAABAAAAAAAAAAAQAAAAEAAAAAAAAA/wAAAP8AAAAAAAAAAAAAABDi
+AQAAAAAAAAQAAGQAAAAHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcGBgYGBgUFBQUFBAQEBAQDAwMDAwICAgICAQEBAQEAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5G0BAOxtAQD0bQEATG4B
+AFRuAQBcbgEAAAQOCR0tNwAABA4JHSw7AAEQAAEAAAACgAABQgYCEAACIAAAA8AAAUMGAxAAAsAA
+AAPAAAFDBgQQAAJAAAACgAABRAYFEQAAQAAAA8AAAUUGBhEAAOAAAAPAAAFFBgcRAAEAAAACgAAB
+RgYIEQACIAAAA8AAAUcGCREAAsAAAAPAAAFHBgoRAAJAAAACgAABSAYLEgAAQAAAA8AAAUkGDBIA
+AOAAAAPAAAFJBg0SAAEAAAACgAABSgYOEgACAAAAAoAAAUwGAAAiFgAAgAAAAwAAAVkAJBYAAQAA
+AAMAAAFaACYWAAIAAAAEAAABWgAoFgACAAAAAwAAAVsAKhYAAoAAAAMAAAFcACwXAAAAAAAEAAAB
+XAAuFwAAgAAAAwAAAV0AMBcAAQAAAAMAAAFeADQXAAIAAAADAAABXwA2FwACgAAAAwAAAWAAOBgA
+AAAAAAQAAAFgADwYAAEAAAADAAABYgA+GAACAAAABAAAAWIAQBgAAgAAAAMAAAFjAGQbAAIAAAAD
+AAABbwFmGwACgAAAAwAAAXABaBwAAAAAAAQAAAFwAWwcAAEAAAADAAABcgFuHAACAAAABAAAAXIB
+cBwAAgAAAAMAAAFzAnQdAAAAAAAEAAABdAJ2HQAAgAAAAwAAAXUCeB0AAQAAAAMAAAF2AnwdAAIA
+AAADAAABdwN+HQACgAAAAwAAAXgDgB4AAAAAAAQAAAF4A4QeAAEAAAADAAABegOGHgACAAAABAAA
+AXoEiB4AAgAAAAMAAAF7BIwfAAAAAAAEAAABfASRHwABQAAAAwAAAX4ElR8AAwAAAAQAAAF/BZcf
+AALAAAADAAABgAWZIAAAQAAAAwAAAYEFnSAAAUAAAAMAAAGCBZ8gAAHAAAADAAABgwWhIAADAAAA
+BAAAAYMFpSEAAEAAAAMAAAGFBQAAAAAAAAAAAADEzgEASL8BAAjBAQBswgEAeMQBAPjGAQDYygEA
+nMwBAOTNAQA82AEAUNgBALzYAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAA
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIIAPAABAAGkgAABpIEAA
+aSAAAGkgQAAgIIAPAADoAGkgAABpIEAAaSAAAGkgQAAgIIAPAACcBWkgAABpIEAAaSAAAEogAABK
+IQAASiIAAEojAABKJAAASiUAAEomAABKJwAASiAAEEohABBKIgAQSiMAEEokABBKJQAQSiYAEEon
+ABBKIAAgSiEAIEoiACBKIwAgSiQAIEolACBKJgAgSicAIEogADBKIQAwCiSAP4AAAMBBLJwwQCyc
+MEIkHDQKIoA/gABgWgojADcSDwAASiYAcGkgQABKJgBwSiYAcEomAHBKJgBwABYAcIAAWARAeCAg
+QIcAAAAAAAAAAAAACsjPcaAAyB8OGRiAC8gPGRiADMgQGRiADRICNgDIRHgRGRiADsgtGRiA4H7h
+xPwcyL78HEi+4cDhweHC4cP8HAix/BxIsfwciLH8HMix/BwIsvwcSLL8HIiy/BzIsvwcCL9qJIAQ
+4cRqJMAQ4cTxwM9woADQGxSAz3GAAFQEBCCAj89RBOEAoQryLykBAM9wgACoCfAgQABAeNr/0cDB
+xGskwBDBxGskgBDBxJ90BBQLNAQUCjQEFAk0BBQINAQUBzQEFAY0BBQFNAQUBDTBw8HCwcHBwMHE
+RSx+EAomQH7BxGskgBTBxCAgQIcKyIe4ChoYMAvIm7gLGhgwDMgMGhgwDciHuA0aGDAOyIUgww8O
+Ghgw4H7gePHACsiVuAoaGDALyJu4CxoYMA3IiriNuJC4DRoYMM9wgADQChiIGwhRAA3Iz3EAAIwK
+rLgNGhgwxg0gAA/YZ9hqDuAAiiGGCNHA4H7xwM9wgABElgCAhiD+gQn0DcgFIIAPAAAA1A0aGDCg
+/4ogVQU6DuAAiiHGDOjx4HjxwM9xAwBADc9woACoIC2gz3KAAJQEIIIBaQCiwg0gAUjYz3CAAAwJ
+JYAjgSCBx3EAAIgT7gwACMrx4HjPcIAADAmBBAAI4HjxwBYKQAHPdoAAVAQF6A8IUQAB2ALwANgL
+rgbpDQlRAAHYA/AA2AquBeoPClEAAdgC8ADYDK4A2M91oADIHxgdGJALjoohEAAN6AiOC+jPcAMA
+QA1FHRgQMKUC2BgdGJAC8DGlCo4Z6AmOF+jPcAEAMuUgHRiQz3CAACQAIR0YkM9wgABQBCIdGJAY
+FQCWRSAAAxgdGJAMjgfoGBUAloUgAQQYHRiQGesA2JS4z3aAAIgEAKZx2Aa4NgggAfzZIIbPcAAA
+TBwqCCABn7kYFQCWhbgYHRiQrQFAAeB4z3Gqqru7z3CfALj/NqA2oDagNqDPcaAAyDsOgYi4DqFp
+IEAA/vHgePHApcFBwELBDBwAMRAcQDHPcYAAfFs0GcAPMBkADywZwA4oGYAOJBlADs9wgAB8WyAY
+QAvPcIAAfFscGAALz3CAAHxbGBjACs9wgAB8WxQYgArPcIAAfFsQGMAIz3CAAHxbDBiACM9wgAB8
+WwgYQAjPcYAAAFuAGQAIfBnAB3gZgAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZ
+QAVQGQAFTBnABEgZgAREGUAEQBkABO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlA
+ARAZAAFjoWogAAPYGQAAaiDAAtQZAABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGog
+gAC8GQAAaiBAALgZAABqIAAAtBkAAGoggAHMGQAA0NifuM9xnwC4/x2hz3CAAAAAxIBTJcQ1UybF
+Nde6AebTvsSgUyPABAUmjh/Q/gAA1qEFIIAPsP4AABahGIFTJ841AN2UuBihQMMBwALByXMMFAYw
+qgvgABAUBzDPcKAAtA+8oM9xoADIOy6BQgvgAH3YpgtAAXYO4ACpcAjYANk2DuAAmbkQ8fHAKg8g
+AXvYHgvgANfZz3GAAHxbNBnADzAZAA8sGcAOKBmADiQZQA7PcIAAfFsgGEALz3CAAHxbHBgAC89w
+gAB8WxgYwArPcIAAfFsUGIAKz3CAAHxbEBjACM9wgAB8WwwYgAjPcIAAfFsIGEAIz3GAAABbgBkA
+CHwZwAd4GYAHdBlAB3AZAAdsGQAHaBmABmQZQAZgGQAGXBnABVgZgAVUGUAFUBkABUwZwARIGYAE
+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
+5BiAAB0GQADPcIAA3FtdAyAA6NnxwJoNQAAAFoNAABaPQAAWjUAAFpBAw7+j6M9xgADcW9aJFBGF
+ANF1zCNBgRDyCiHAD+tyEL1AKw8EBdiKI9sIBSWEE00EL/8FJcUDQCEOBvWpz3WAAISYhR3CEyHw
+z3CAAJCbApAXDQEQz3WAAISYwhUAFsC4HQsAAAohwA/rcgXYiiMbC5hzCQQv/0olAADPdoAAkJfP
+cIAA6JvpqEAgQSBJIQEGO3nuDSAAyXBCIMAlSCAAABsIdAAA2wDaABYBQAHi+wqUgAHj9QsEgFYm
+ABbGDSAABNnPcIAARJYAgDMIXgDPcYAA3FvPcIAAkJsCkFaJEQoBAMIVABY0icC4EwkAAMMVABYL
+CF4BCYUVCF8BPgtgAMlwz3CAAEAL9ag6DQAA2QRAAADYbPHxwKHBi3BmDSAAAdkAFAUwTCUAgMoh
+wQ/KIsEHyiBhAcojgQ8AACIHPAMh/8okYQDPcIAAiIf6DCAAAxhCAaHA0cDgfvHALgxAAM9zgAAA
+DEODAN/PdaAALCCwhdJq1H5+ZqWmBKYB4owiCIAmpkOjhfcCg+OjAeACo2EEQADgeADYz3GgAMgf
+GKEZoQHYDqHgfuB48cDeC2AAOXEZcshx6HIB3c92oADIH7OmBd/PdYAAcAvgpQGlBMBIpQmlFYYn
+pQqlGIYYHUARC6UZhhQdABEMpaAWABBkpQ2lpBYAEAwdABIOpagWABAIHUASD6XPcAEAGAgQpTIP
+IAAk2AQggA8AAAD4EaUiDyAAANgSpVMnwHUTpQHIVB0AFxalEhYAllAdABcXpRMWAJbPcoAAcAsY
+pRQWAJZKJAB5GaUVFgCWANkapRYWAJYbpc9wgAAQKBCAHKXPcIAAcAt0GIAKz3CAAHALeBjACs9w
+gABwC3wYAAuAGkALz3CgAMgcCICEGgAAqCBAAvAiQwDPcJ8AuP8B4XagRQNAAOB48cDPcYAAECgQ
+oeB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeNHA4H7geOHF
+4cZAKQ0CJX1ALQMUpXslCjQCCHVTJX6QBvIBHVIQYbr78UEqjgDBukImTpAEHdAQ/fUJ6i8kiXDg
+eKggQAEBHVIQ4HjBxuB/wcUocgDZ2PHgePHA4cUIdc9wgAAkCwGIFegH8NoPz/5aD+//iiCRD89w
+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
+N/DPcYAAHD0c4FYPb/8A2gSFz3GAAFw9BLgUePhgKfDPcYAAPD0U4DYPb/8A2gSFz3GAAFw9BLgU
+eEJwGfDPcYAAHD0k4BoPb/8A2gSFz3GAADw9BLgUeCJwBg9v/wDaBIXPcYAAXD0EuBR4AnDyDm//
+AdrdBE/18cAKJQCAz3GAALwGIBEEACLyz3KkALg9ANsfDBEAmxIABgmhphIABgqhkhIABguhoxIA
+BgyhmxrYAP/YphoYAJIaGACjGhgAAdrPcKAAtA9coCfwTCQAgMohwQ/KIsEHyiOBDwAA+wQUAyH0
+yiBhAQmBz3KkALg9mxoYAAqBphoYAAuBkhoYAAyBoxoYAAPIz3KgALQPhiD/DiK4HKIgGUABJvF5
+Bg/1dQYP9fHAcg4P9W/+HPHgeM9wgAB8PeB/EYDgePHAwgtP9Qh3GnEB2c9wpwCYRzqgIN7PdaAA
+yB/QpQrYQx0YEADYBgwv9Y240aXPcacAFEgMgQToHoED8B2BABgAIPe4xSCCDwD/AADTIOEFmg3v
++6DZ0QNv9QCn8cBqC0/1z3CAAPBkJoiA4c91gAB8PWQCIQCiwQeIgOBYAgEAiiCRBRYP7/QA2fIL
+L/8F2Aylw9jPdqAA7CcGpgqGz3erAKD/ALWKIMQABqYKhgG1iiDFAAamCoYCtYogywAGpgqGA7WK
+IM8ABqYKhgS1z3AAAIMNBqYKhgW1z3AAAMMNBqYKhga1z3AAAAMOBqYKhge1z3CnABRICIAEpc9w
+pwCYRzyAJaXPcacAFEhXgTaBRqUnpc9xpQAIDCKBxtoopTiHkLoppTmHKqU6hyulz3EFAMYDJqYB
+2Uamz3IsAAIBRqbPcloAQgFGpooiiwBGps9yQACHDUamz3LRAMINRqbPcsAABw5Gps9ypwAUSCii
+z3JQAP8AXKDPcKcAFEg3oADZNqDPcKUACAxQ2SKg/NgYp3PYGacah4G4GqfPcBEABg4GpotwgcGW
+/zOFAMBShSJ4NIUKuDYM7/tCeYQohANCKUFyNrkBwidxSrmCIcQCz3CAALBxMKVVoDagz3BAAIYN
+BqbPcBAAAg4GpotwgcGE/zOFAMBShSJ4NIUKuO4L7/tCeQQogA8AAHQJQilBcja5AcIncUq5T+HP
+cIAAsHExpVegOKABlRC4hSCEAAamApUQuIUghQAGpgOVELiFIIsABqYElRC4hSCPAAamBZUQuAUg
+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
+AMCOCW/4FOEYpyDAibiOuBmnAI4TCF4AQCYAE3YO7/IU2QPwAN3PdqAA9Aekpq4Pj/HPcYAAYJUB
+iYXoAIkTCF8AAdmQuc9wpwCYRzygA9gEpgMIHkPPcYAAYJUBiYXoAIkXCF8Az3KnAJhHcBqABAiJ
+gLgaogCJdQheAKkIHsP9CN7BRggP9YwgAoPMIIKPAAD8AAzyCiHAD+tyBdiKI44CSiRAAIEA7/G4
+c4wgAoMY9M91gABglalwcgrv8gPZAI1RIACAyiHCD8oiwgfKI4IPAACPA8ogYgHl9Vv/BPBuD0/z
+sgnv8oDYBvCqCe/ygNhW/wDaz3GgAPQHRKED2AqhCaFJoSYL7/wKcHUBL/OhwOB48cDPcYAA8GQk
+kQDYguHMIWKAA/QB2C8mB/DPcYAAYJUAiQfyhiA/BUUgAAoAqQsIHgBZ/wLwQP/PAM//8cDPcIAA
+YJXSCe/yA9nu/7sAz//9AM/y+QDP8uB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwDY4H8A
+2OB+4HihweB/ocDgeOB+4HjxwOHFAcjPdYAAPEcApQRtegnv8gLZz3GADgQA7HAgoBYI7/IAheUA
+D/PgeOB+4HjgfuB48cAAFgBBz3KAADxHBrIAFgVBQCIBBA4aRAFMJYCEyiHCD8oiwgfKIGIByiOC
+DwAARAAgB6LxyiQiAADaB/AAFgBBFCGMAAC0AeIvIEIB8woCgMoIz/LRwOB+4HjgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjPcIAAqAjgfwCA4HjgfuB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
+4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB/Adjg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB48cDhxc91gAB8R6lw+g+v8gPZABWFEEQlQAGF4MohwQ/KIsEHyiBhAcojgQ8AAE8A0AWh
+8cokYQABjQsIEgFjuAGtig+P8kEHz/LgePHAvg7P8hpxz3aAAHxHII6JCR4Az3GAALAIIImA4cwg
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAZIWAAFBZAQAAAAAAAAAAAAAAAAAAAAAAAAAAAIiFgAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+/wEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEBAQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAABgAIAAkAAAAHAAAAAAAAAAIAAAACAAAAgwAA
+AJIAAADoAAAA9wAAAE4BAABdAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAfYAALLMBAAAAAAAAAAAA
+AAAAAAAAAADAfYAAPLoBAAAAAAAAAAAAwH2AALC7AQAAAAAAAAAAAAAAAADAfYAAAAAAAAAAAAAB
+AA8AZAABAIgIgAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAcAAAAA
+AAAAAAAAAAAAAH9/AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgQIAAgQ
+IAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYBwAAFQAAAMQtgABkCgAA
+ZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABk
+CgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQKAABkCgAAZAoAAGQK
+AABkCgAAqAsAAAAAAADUHgEAZAoAALAIAABkCgAAZAoAAGQKAADgCAAAWAYBAJhSAABkCgAAZAoA
+ABQJAAAUCQAAFAkAABQJAAAUCQAAFAkAABQJAABkCgAAZAoAAGQKAABkCgAAMAoAAGQKAABkCgAA
+ZAoAAGQKAABkCgAArAsAAGQKAABkCgAAlAgAAAMAAADcwQEAAgAAAHArAQAEAAAAbDAAAAYAAACI
+zAEAEQAAAGysAQAHAAAAoLUBAAgAAAAIzQEADAAAAKBDAQANAAAAIEgBAA4AAABYSAEAFgAAADwe
+AQALAAAA6FwBABQAAACwUwAADwAAAARiAAAQAAAADBYBAAEAAACMsQEAEgAAABRrAQATAAAANGMB
+AAUAAABIZQAAFQAAAJjbAQAXAAAAqAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCUAABwlAAAc
+JQAAcDYAABwlAAAcJQAAZDYAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwa
+AAC0GwAAuBsAACwdAACsHQAAMB0AABwlAAAcJQAA/D4AAGRCAAA0QwAAHCUAABwlAAAcJQAAyD0A
+APysAAD4rAAAAK0AABwlAAAcJQAAHCUAAHQ2AAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAA
+HCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAc
+JQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAYDcAABwl
+AAAcJQAAHCUAABwlAAAcJQAAQDgAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUA
+ABwlAAAcJQAAyPIAABwlAADo8wAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAADcZAAA
+HCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAACoWwEAOF8BABwlAABM
+RAEAHCUAAPhFAQCoNQEAHCUAABwlAACsQwAAHCUAABwlAAAcJQAAHCUAABwlAAAQrQEAhKwBABwl
+AAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAgzAEAJMwBABwlAAAcJQAAHCUAABwlAAAcJQAAHCUA
+AGy1AQAcJQAAlLgBABwlAAC03AEAHCUAAHggAAB8IAAAHCUAABwlAADgzQEAtFMAABwlAAAcJQAA
+HCUAAASwAQAcJQAAHCUAAAAXAQAgYwEAHCUAABwlAAAcJQAA1GkBAPQwAQAcJQAAHCUAABwlAAAc
+JQAAHCUAABwlAABIcAEAHCUAAOzMAQDwzAEA/MwBAADNAQD0zAEA+MwBAATNAQAcJQAAHCUAABwl
+AAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAACERQAAHCUAABwlAAAcJQAAHCUAABwlAABczAEAkMwB
+AGg6AAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAA
+HCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAc
+JQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAAHCUAABwlAAAcJQAADDsAAIw7AAAQPAAArDwAALxg
+AACEPAAAHCUAABwlAAAcJQAAHCUAABwlAAAEOwAACDsAABwlAAAcJQAA3EMAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAABAAAAAQEAAAAAAAAQAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhAw4e4eEDDh7hwQIKHuGBBQwe4eEDDh7h
+4QMOHuHBAgYe4YEFDB7hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAQEBAQEBAQEBAQEBAQEBAQ0NDQ0NDQ0NDQ0NDQ0NDQ0DAwMDAwMDAwMDAwMDAwMDAAAA
+AAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQENDQ0NDQ0NDQ0NDQ0NDQ0NAwMDAwMDAwMDAwMD
+AwMDAwAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBDQ0NDQ0NDQ0NDQ0NDQ0NDQMDAwMD
+AwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAkQIAADHKLwCRAgAAMcovAJECAAAxyi8AkQIAADHK
+LwCRAgAAMcovAJECAAAxyi8AkQIAADHKLwCRAgAAMcovAEMBAAAxyi8AQwEAADHKLwBDAQAAMcov
+AEMBAAAxyi8AQwEAADHKLwBDAQAAMcovAEMBAAAxyi8AQwEAADHKLwBADQAA3gMJAAAAAAAAAAAA
+AAAAAMDyAAABAAAAhC2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAD
+AAAAAAAAAAgAAAAAAAAAQEIPAHT2AABY9wAAaPgAADD6AABo+AAAMPoAANj7AABc/AAAgICAgICA
+gIABgAKAgICAgAAAAAAEAQEABAEBAAAAAAAAAAAAAAAAAAAAAAAEAQEABAEBAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAACELYAAhC2AAKQgoAA4IKAAAQAAAPz///8AAAAAAAAAAKQtgACkLYAA
+qCCgADwgoAAIAAAA8////wAAAAAAAAAAxC2AAMQtgACsIKAAbCCgADAAAADP////AAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAABQXAQAFAAAAxC2AACgc
+AQAA/wMASBwBAAD/BQAsHQEAAP8tAFAdAQAA/z0ACB0BAAD/BADsHAEAAP8lAOAjAQDIJAEAOCUB
+AHAgAQCwHwEAICYBAKQmAQDoJgEAOCcBAAAAAAAsAQAAXgEAAAEAAAABAAAAAQAAAAEAAAADAAAA
+AAAAAAAAAAAAAAAAAwAAAAIAAAADAAAAAwAAAAMAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAADQ
+LAEACgAAAIQtgAAAAAAAAAAAAAAAAABcLQEACgAAAIQtgAAAAAAAAAAAAAAAAACQLQEACgAAAIQt
+gAAAAAAAAAAAAAAAAAAILgEACgAAAIQtgAAAAAAAAAAAAAAAAAAkLwEACgAAAIQtgAAAAAAAAAAA
+AAAAAACcLgEACgAAAIQtgAAAAAAAAAAAAAAAAADwNAEABgAAAIQtgAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAQAAAAAIAAAAAAoAAQJwAA6AMAAOgDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAALEsBADBMAQDYTgEAgFEBAPRTAQBYVwEAwE0BABwFgACIfYAAGAAAAEh9
+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAOBZAQAGAAAAhC2AAAAAAAAAAAAAAAAAAFQIAQAKAAAAhC2A
+AAAAAAAAAAAAAAAAAFQIAQAKAAAAhC2AAAAAAAAAAAAAAAAAAFQIAQAKAAAAhC2AAAAAAAAAAAAA
+AAAAAFQIAQAKAAAAhC2AAAAAAAAAAAAAAAAAAFQIAQAKAAAAhC2AAAAAAAAAAAAAAAAAAFQIAQAK
+AAAAhC2AAAAAAAAAAAAAAAAAAFQIAQAKAAAAhC2AAAAAAAAAAAAAAAAAAFQIAQAKAAAAhC2AAAAA
+AAAAAAAAAAAAAFQIAQAKAAAAhC2AAAAAAAAAAAAAAAAAAFQIAQAKAAAAhC2AAAAAAAAAAAAAAAAA
+AFQIAQAKAAAAhC2AAAAAAAAAAAAAAAAAAFQIAQAKAAAAhC2AAAAAAAAAAAAAAAAAACxhAQAKAAAA
+hC2AAAAAAAD//////////wAAAAAAAAAAAAAAALRiAQAFAAAAxC2AAGQAZABpANwAyABaAKoAvgCG
+AX0APgBkAGQAaQDcAMgAWgCqAL4AhgF9AD4AAAAAAAEBAAAAAAAAAAECAQEAAgEAAQICAgABAQAC
+AQIBAgACAAECAwAAAAC4bwEA1HwBAMCHgADAAwAAAAAAALhvAQDUcAEAgIuAAPgBAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAMgQEAKH8BAHiNgABUAAAAAAAAALhvAQBUfwEA+I2AAFABAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAEAAAC4bwEA2HsBABw3gABQAQAAAAAAABCBAQDkfQEAvAaAAAIAAAAA
+AAAAuG8BABB+AQDABoAABAAAAAAAAAAIgQEA1HABAMyNgAAsAAAAAAAAALhvAQB8fgEAAAAAAAAA
+AAAAAAAAuG8BADx+AQDEBoAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgAC
+AAMABAAEAAUABgAGAAcAIAAgACEAIgAiACMAJAAkACUAJgAmAEMARABEAEUARgBGAEcASABIAEkA
+SgBKAEsATABMAE0ATgBOAE8AUABQAFEAbgBuAG8AcABwAHEAcgByAHMAdAB0AHUAdgB2AHcAeAB4
+AHgAeAB4AHgAeAB4AHgADwA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQACAAMA
+AwAEAAUABQAGAAcABwAIAAkACQAKACMAIwAkACUAJQAmACcAJwAoACkAKQBGAEcARwBIAEkASQBm
+AGcAZwBoAGkAaQBqAGsAawBsAG0AbQBuAG8AbwBwAHEAcQByAHMAcwB0AHUAdQB2AHcAdwB4AHgA
+eAB4AHgAeAB4AHgADgA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgACAAMABAAE
+AAUABgAGAAcAIAAgACEAIgAiACMAJAAkACUAJgAmAEMARABEAEUARgBGAEcASABIAEkASgBKAEsA
+TABMAE0ATgBOAE8AUABQAFEAbgBuAG8AcABwAHEAcgByAHMAdAB0AHUAdgB2AHcAeAB4AHgAeAB4
+AHgAeAB4AHgADwBDAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQACAAMAAwAEAAUABQAGAAcABwAIAAkA
+CQAKACMAIwAkACUAJQAmACcAJwAoACkAKQBGAEcARwBIAEkASQBmAGcAZwBoAGkAaQBqAGsAawBs
+AG0AbQBuAG8AbwBwAHEAcQByAHMAcwB0AHUAdQB2AHcAdwB4AHgAeAB4AHgAeAB4AHgAeAB4AHgA
+eAB4AHgACABDANhnAQAS0gAAAAAAAP//DwA4eQEAtgAAAAAAAAD/AAAAOHkBALcAAAAAAAAA/wAA
+ADh5AQC4AAAAAAAAAP8AAAA4eQEAuQAAAAAAAAD/AAAAOHkBALoAAAAAAAAA/wAAADh5AQC7AAAA
+AAAAAP8AAAA4eQEAvQAAAAAAAAD/AAAAOHkBAL4AAAAAAAAA/wAAADh5AQC/AAAAAAAAAP8AAAA4
+eQEAwAAAAAAAAAD/AAAAOHkBAMEAAAAAAAAA/wAAADh5AQDCAAAAAAAAAP8AAADYZwEAE9IAAAAA
+AAD//w8AOHkBABsBAAAAAAAA/wAAADh5AQAcAQAAAAAAAP8AAAA4eQEAHQEAAAAAAAD/AAAAOHkB
+AB4BAAAAAAAA/wAAADh5AQAfAQAAAAAAAP8AAAA4eQEAIAEAAAAAAAD/AAAAOHkBACIBAAAAAAAA
+/wAAADh5AQAjAQAAAAAAAP8AAAA4eQEAJAEAAAAAAAD/AAAAOHkBACUBAAAAAAAA/wAAADh5AQAm
+AQAAAAAAAP8AAAA4eQEAJwEAAAAAAAD/AAAA2GcBABTSAAAAAAAA//8PADh5AQCCAQAAAAAAAP8A
+AAA4eQEAgwEAAAAAAAD/AAAAOHkBAIQBAAAAAAAA/wAAADh5AQCFAQAAAAAAAP8AAAA4eQEAhgEA
+AAAAAAD/AAAAOHkBAIcBAAAAAAAA/wAAADh5AQCJAQAAAAAAAP8AAAA4eQEAigEAAAAAAAD/AAAA
+OHkBAIsBAAAAAAAA/wAAADh5AQCMAQAAAAAAAP8AAAA4eQEAjQEAAAAAAAD/AAAAOHkBAI4BAAAA
+AAAA/wAAANhnAQAI0gAAAAAAAP//AwAYaAEAAIIAAAAAAAD/AQAAGGgBAAGCAAAAAAAA/wEAANhn
+AQAJ0gAAAAAAAP//AwAYaAEAAoIAAAAAAAD/AQAAGGgBAAOCAAAAAAAA/wEAANhnAQAK0gAAAAAA
+AP//AwAYaAEABIIAAAAAAAD/AQAAGGgBAAWCAAAAAAAA/wEAANhnAQAG0gAAAAAAAP8BAADYZwEA
+B9IAAAAAAAD/AwAA2GcBAAbSAAAJAAAAAP4DANhnAQAH0gAACgAAAAD8DwDYZwEABtIAABIAAAAA
+APwH2GcBAAfSAAAUAAAAAADwP9hnAQAV0gAAAAAAAP8DAADYZwEADNIAAAAAAAD/AQAA2GcBABXS
+AAAKAAAAAPwPANhnAQAM0gAACQAAAAD+AwDYZwEAFdIAABQAAAAAAPA/2GcBAAzSAAASAAAAAAD8
+BwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzSDdIR0hDSAtIB0gPSG9IL0gCABdIS0hPSFNIE
+QwbSB9IE0gkQAAC1ABoBgQEFAAQABgAIAAkACgALAAwAgwCSAOgA9wBOAV0BDwAuAAAAbAAAAHQA
+AACAAAAAjAAAAJ0AAAAHAAAABAAAAAgAAAAQAAAAQAAAAIAAAAAgAAAAAAAAAAkAAAASAAAAAAAA
+AAoAAAAUAAAA/////wAAAAAtAQAA3QEAAFoCAAC6AgAACgMAAE0DAACHAwAAugMAAOgDAAARBAAA
+NwQAAFkEAAB6BAAAmAQAALQEAADOBAAA5wQAAP4EAAAVBQAAKgUAAD4FAABRBQAAZAUAAHUFAACG
+BQAAlwUAAKcFAAC2BQAAxQUAANMFAADhBQAA7gUAAPsFAAAIBgAAFAYAACAGAAArBgAANwYAAEIG
+AABMBgAAVwYAAGEGAABrBgAAdQYAAH4GAACIBgAAkQYAAJoGAACiBgAAqwYAALQGAAC8BgAAxAYA
+AMwGAADUBgAA2wYAAOMGAADqBgAA8gYAAPkGAAAABwAABwcAAA4HAAAUBwAAGwcAACIHAAAoBwAA
+LgcAADUHAAA7BwAAQQcAAEcHAABNBwAAUwcAAFgHAABeBwAAZAcAAGkHAABvBwAAdAcAAHkHAAB/
+BwAAhAcAAIkHAACOBwAAkwcAAJgHAACdBwAAogcAAKcHAACrBwAAsAcAALUHAAC5BwAAvgcAAMIH
+AADHBwAAywcAANAHAADUBwAA2AcAANwHAADhBwAA5QcAAOkHAADtBwAA8QcAAPUHAAD5BwAA/QcA
+AAEIAAAFCAAACAgAAAwIAAAQCAAAFAgAABcIAAAbCAAAHwgAACIIAAAmCAAAKQgAAC0IAAAwCAAA
+NAgAADcIAAA7CAAAPggAAEEIAABFCAAASAgAAEsIAABPCAAAUggAAFUIAABYCAAAWwgAAF8IAABi
+CAAAZQgAAGgIAABrCAAAbggAAHEIAAB0CAAAdwgAAHoIAAB9CAAAgAgAAIIIAACFCAAAiAgAAIsI
+AACOCAAAkQgAAJMIAACWCAAAmQgAAC4AAABsAAAAdAAAAIAAAACMAAAAnQAAAAcAAAAAAAAAAAAA
+AAoAAAAN0hHSENIC0gHSA9Ib0gvSAIAF0hLSE9IU0gRDCNIJ0grSHNIG0gfSAQAAAAAAAAAAAAAA
+AAAAAAMAAAAEAAAAAwAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAP8DAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAC1ABoBgQEEAA8AgwDoAE4BkgD3AF0BBgAIAAkACgALAAwABQAAAAAAAAAsAAEA
+AAAAAAAAAAAAAAAAAAAAAAAAAgACAAIAAADfAAAAGQEAAGIBAAC+AQAAMgIAAMMCAAB7AwAAYgQA
+AIQFAADyBgAAvggAAAILAAABAAAAAgAAAAAAAAAL0g7SDdII0gnSCtIS0hPSFNIR0hDSAtIB0gPS
+AIAF0gRDG9Ic0gTSAEUw0jHSAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH
+AAAABwAAAAAAAAADAAAABAAAAAMAAAAAAAAA/wMAAAMAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAA
+AAAAAAAAAAAAALUAGgGBAQUABAAPABAACgALAAwAAAAAAAAAAAAsAAEAAAACAAIAAgAAAAAAAQAB
+AAIAAgACAAMAAwAEAAQABQAFAAYABgAHAAcACAAIAAkACQAKAAoACwALAAwADAANAA0ADgAOAA8A
+AAAAAAAAAAAAAAAA/LIBAAYAAACELYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcBYAAiH2AABgAAABIfYAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwFgACIfYAAGAAA
+AEh9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAFy/AQAEAAAAhC2AAAAAAAAAAAAAAAAAADi+AQAEAAAA
+hC2AAAAAAAAAAAAAAAAAACTAAQAGAAAAhC2AAAAAAAAAAAAAAAAAADi+AQAEAAAAhC2AAAAAAAAA
+AAAAAAAAAFy/AQAEAAAAhC2AAAAAAAAAAAAAAAAAADi+AQAEAAAAhC2AAAAAAAAAAAAAAAAAAFy/
+AQAEAAAAhC2AAAAAAAAAAAAAAAAAADi+AQAEAAAAhC2AAAAAAAAAAAAAAAAAACTAAQAGAAAAhC2A
+AAAAAAAAAAAAAAAAADi+AQAEAAAAhC2AAAAAAAAAAAAAAAAAAFy/AQAEAAAAhC2AAAAAAAAAAAAA
+AAAAACTAAQAGAAAAhC2AAAAAAAAAAAAAAAAAAFy/AQAEAAAAhC2AAAAAAAAAAAAAAAAAAFy/AQAE
+AAAAhC2AAAAAAAAAAAAAAAAAACTAAQAGAAAAhC2AABwFgACIfYAAGAAAAEh9gAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAUA
+AAAAAAAAAAAAAAAAAAAAAP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECAwQEBAQEBQYHCAgICAgJCgsMDQAAAAUGBwgNDg8Q
+FRYXGBkAAAoNERQKDREUCg0RFAoKAAAAAAAABgYGBgkJCQkABgAAbjtoO2I7XDtuOmg6YjpcOm45
+aDliOVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbihoKGIoXChuJ2gnYidcJ24ZaBliGVwZbhho
+GGIYXBhuF2gXYhdcF24JaAliCVwJbghoCGIIXAhuB2gHYgdcB24GaAZiBlwGbgVoBWIFXAVuBGgE
+YgRcBG4DaANiA1wDbgJoAmICXAJuAWgBYgFcAW4AaABiAFwAbjtoO2I7XDtuOmg6YjpcOm45aDli
+OVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbihoKGIoXChuJ2gnYidcJ24ZaBliGVwZbhhoGGIY
+XBhuF2gXYhdcF24JaAliCVwJbghoCGIIXAhuB2gHYgdcB24GaAZiBlwGbgVoBWIFXAVuBGgEYgRc
+BG4DaANiA1wDbgJoAmICXAJuAWgBYgFcAW4AaABiAFwAAAAAAAAAAAAAAAAAEOEBAAgAAADELYAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////wAB//8C
+A////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/////////////////////////////////////////////////////////
+/////////////////////wEEAAACBQEAAwYCAAQHAwAFCAQABgkFAAcKBgAICwcACQwIAAoNCQAL
+DgoADA8LAA0QDAAOEQ0AAUEABAJCAQQDQwIEBEQDBAVFBAQGRgUEB0cGBLcTIgC4FCMAuRUkALsW
+JQC8FyYAvRgnAMAZKADEGikABxsAAAgcAQALHQIADB4DABAfBAAiIQUAJCIGACYjBwAoJAgAKiUJ
+ACwmCgAuJwsAMCgMADQpDQA4Kg4APCsPAEAsEABkLhEAaC8SAGwwEwBwMRQAdDIVAHgzFgB8NBcA
+gDUYAIQ2GQCINxoAjDgbAJE6HACVOx0AmTweAJ09HwChPiAApT8hACRJBgIsSgoCNEsNATxMDwFk
+TREBbEMTAXRPFQF8UBcBhFEZAZVSHQGdUx8BAAQWCBYWFgwWFhYWFhYWEAAAAAAPAD8AAQAAAA8A
+PwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAgAAAA8APwABAAAAAAAA
+AAEAAAACAAAAAwAAAAAAAAAEAAAAAgAAAAUAAAAYCAGlDAIApQA8ODQwLCgkIBwYFBAMCAQADAgE
+ADw4NDAsKCQgHBgUEAwIBAIAFA4AAAAAGgAAAAEBAAECAQEBAQEBAQEBAQECAgICAgICAgMDAwMD
+AwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQA
+AAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgMEBgZ00UUX6KKLLg0PBQcJCwEDChQ3
+blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHKAAoADAALAAsACgAPAA0ACgAKAA0ADAA
+LAAsAEQAPABAADwAjABsAFgASAD0ALAALAAsADwANAAwACwAVABEAFQAVABsAGAAXABUAIwAeAA6
+AQIB1QDfANoAogB1AH8AagEaAdkA6AAKAboAeQCIAIoFKgM5AagBigXKAtkASAHKAUoB4gD5AMoB
+6gCCAJkAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzETid2YicapEEaEzux
+Ew3SIA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUFBVRABSd2YicTO7ET
+DdIgDYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN0iANCqiAChM7sRMP
+/MAPD/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4gAcGaZAGD/zADw3S
+IA0LtEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiACgiMwAgHeIAHCIzA
+CAd4gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEDQAaACcANABOAGgAdQCCABoANABOAGgA
+nADQAOoABAEnAE4AdQCcAOoAOAFfAYYBNABoAJwA0AA4AaAB1AEIAgwATgBoAIIAdQCcAMMAaACC
+AIIAnAC2ALYA0ACcAMMAwwDqABEBEQE4AYIAnAC2AJwAtgDQAOoA0ADqAAQBBAEeAcMA6gARAeoA
+EQE4AV8BOAFfAYYBhgGtAQAAMAAAADYAAAAMAAAAEgAAABgAAAAkAAAABgAAAAkAAAAAAAAAAAAA
+ABggFBQODhQUBQYBAgMEAAAAAQECAQICAwQMDAgEDAQEQAAAAIAAAAAAAQAAAAIAAEAAAAAABAAA
+QAAAAEAAAAAQERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uL0BBQkNERUZHSElKS0xNTk9Q
+UVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8tAA8gAPBhAAAA
+AAAAAAAAAAECBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYN74Ac76wvpq+bAAArq5kBq58ha6u
+SQAJAAAAAgAAAAAAAAAAAAAACQAAAAIAAAAAAAAAAAAAAAkAAAADAAAAAQAAAAkAAAAJAAAAAgAA
+AAIAAAAJAAAAAQIBAgMEAAAFBgcICQoAAAAFBgACBAAFAAAAAAAFBwEDBAAFAQAAAEAjQCUhISEh
+QEBAQEAFBAQBAUBAQEAFBUBADAxADQwMAQEBBUBABQUABAAEQEAABEBAQAVAQEBAQAVAQEAFBQUB
+AQEBQAUFBQEFAQFABQUFQAVABQUFBQVsAHAEdAh0DAAEBAYAAAAAAAAAAGQAAAAAkAEACgAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAAAAAAAAAAAAAAAAP8AAAAAAAAA
+AAAAAAAAAAAAAAAAAQAAABAAAAAAAAAAAQAAAAEAAAAAAAAA/wAAAP8AAAAAAAAAAAAAAFjAAQAA
+AAAAAAQAAGQAAAAHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcHBwcGBgYGBgUFBQUFBAQEBAQDAwMDAwICAgICAQEBAQEAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJF4BACxeAQA0XgEAiF4BAJBe
+AQCYXgEAAAQOCR0tNwAABA4JHSw7AAEQAAEAAAACgAABQgYCEAACIAAAA8AAAUMGAxAAAsAAAAPA
+AAFDBgQQAAJAAAACgAABRAYFEQAAQAAAA8AAAUUGBhEAAOAAAAPAAAFFBgcRAAEAAAACgAABRgYI
+EQACIAAAA8AAAUcGCREAAsAAAAPAAAFHBgoRAAJAAAACgAABSAYLEgAAQAAAA8AAAUkGDBIAAOAA
+AAPAAAFJBg0SAAEAAAACgAABSgYOEgACAAAAAoAAAUwGAAAiFgAAgAAAAwAAAVkAJBYAAQAAAAMA
+AAFaACYWAAIAAAAEAAABWgAoFgACAAAAAwAAAVsAKhYAAoAAAAMAAAFcACwXAAAAAAAEAAABXAAu
+FwAAgAAAAwAAAV0AMBcAAQAAAAMAAAFeADQXAAIAAAADAAABXwA2FwACgAAAAwAAAWAAOBgAAAAA
+AAQAAAFgADwYAAEAAAADAAABYgA+GAACAAAABAAAAWIAQBgAAgAAAAMAAAFjAGQbAAIAAAADAAAB
+bwFmGwACgAAAAwAAAXABaBwAAAAAAAQAAAFwAWwcAAEAAAADAAABcgFuHAACAAAABAAAAXIBcBwA
+AgAAAAMAAAFzAnQdAAAAAAAEAAABdAJ2HQAAgAAAAwAAAXUCeB0AAQAAAAMAAAF2AnwdAAIAAAAD
+AAABdwN+HQACgAAAAwAAAXgDgB4AAAAAAAQAAAF4A4QeAAEAAAADAAABegOGHgACAAAABAAAAXoE
+iB4AAgAAAAMAAAF7BIwfAAAAAAAEAAABfASRHwABQAAAAwAAAX4ElR8AAwAAAAQAAAF/BZcfAALA
+AAADAAABgAWZIAAAQAAAAwAAAYEFnSAAAUAAAAMAAAGCBZ8gAAHAAAADAAABgwWhIAADAAAABAAA
+AYMFpSEAAEAAAAMAAAGFBQAAAAAAAAAAAACotgEAvLYBACS3AQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAkAAAAABQkRExcAAA4AAAAqAAAABwAAAAsAAAD/////AAAAAAAAAAAB
+AAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAQAAAAEAAAAAAAAAAAAAAAUFBQUFBQUFAAAAAIANAAAAIAAAgA0AAIANAAAAIAAAgA0A
+AAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAA=
+====
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
+/AhVBK/zKKAOeCx4KWoA2A8gQAAncFp44H8OIMAA4HjxwL4Lj/PPcIAA/AgRiAXwQCdAAA94+HDP
+cIAA/AgSiIkIwgEA2QfYRCk+B1lwL3AZcYQvAwEncM9xgADUqQAhBAAfFMQAGWEeEcUAOXAA3gAh
+jR+AANSp1X3njYhxBdrpcAUVwxDh/0AogRA0eYQvAQUncdR5x3GAAEis2HEAqelwqHEH2gYVwxDY
+/wHmz37BDrKRAR4CAEIiQBBAIEEQiQh1gC95tvF9A4/zl+iMIcKNAdpX9kokgHGoIEAEz3OAALWq
+RCo+BzIjQw4XC0MAB+sTCpABAeJPegDaA/Bhuk964H9IcOB48cDKCo/zGnA6cpEJcgAA31pxFSDA
+I6CIAogbCRAgz3aAAORIFX4CuBR4x3CAAGhLCvDPdoAAHEkVfgK4FHjHcIAAEEwhiEsJHgAFEMEA
+Iq4GEMAAA64qcKlx2/8AroDgzCBigMogIQAS8kQoPgcAIYB/gADUqcUQggDhEIEAAiWAEBB4B7hi
+Cu/5QnkBrkIiQSCBCXWAAeeNAo/z8cA6Cq/ziiAHCAHfz3aAAPwI8K4A3bGusq7yDS/zqXFx/4j/
+z3CAACisBIgE6CQewhME8CQeQhOKIAcIzg0v8wHZj/+KIAcIwg0v8wLZz3GAAERZIIHPcIAACE8B
+2sL/iiAHCKYNL/MD2c9xgABIWSCBz3CAAFxPANq7/4ogBwiKDS/zBNkdAo/z4HjxwLhxLQhRAAkN
+UgAXDdIDCiHAD+tyBdiKI8oFdQBv8phzQC2AAGS4x3CAAORIG/DPcIAACE4yIEEBjCHDj8ohwQ/K
+IsEHyiBhAcojgQ8AAJwCQABh8sokwQDPcIAAHEk1eNHA4H7geAJ5LXlMeQ8JMwAvclkiAQID8FYi
+AQJHuThg4H8PeOB48cAiCY/zCHYodUh3GnNPeRC5D3gIuAV5iiBHCNoML/Olec9wgAD8CAGIgODq
+AQIAgOfMICKgCfIsbS95z3CAAPwIM6gG8M9wgAD8CLOoqXHPcoAA/Ai0qtWq9qoXGgIEyXDG/wAQ
+hwDhiM9wgAD8CNGIEogQdpgBCQBELz4HL3GELgMRCiRADgAhTQ7PcIAA2KkdZUAvggBUeoQuARUK
+JUAOACJADgAgiA+AAEisACaDH4AAGAlMJwCAzCdigCb0GhXAEADZDKsbFcAQSiSAcRCrGI0Uq6gg
+QAYUIEAQQYhzbnR7NXvHc4AAQK0AEMAARKsVJUIQBasBEsAAAeEGqwCKL3kHq3vwARXAEJfoANpM
+q1CrVKtKJIBxANmoIIADE24UeDV4x3CAAECtRKhFqEaoR6gB4S95YfBsugAiQAF8uQAkRAAAIIYP
+gABIrAAkgA+AANipGog6jelyof8MqwAkgA+AANipG4g7jelynf8Qq89ygADYqQAkgAAYiDiNACSF
+AOlyl/8UqwDbSiGAERQmywAUIMQQAROAEAEUgQDpcpD/M240eXV5ACGKD4AAQK0EGgIQABOAEAAU
+gQDpcoj/BRoCEBUlywAVJcQQAROAEAEUgQDpcoL/BhoCEAATgBAAFIEA6XJ+/wcaAhBCIUkQAeOd
+CXWQb3sB5s9wgAD8CBKIz34QdnIGzP8A2c9wgAD8CCCocQdP8+B48cAKD2/ziiCHCM91gAD8CMoK
+L/MzjQGNgOCJ9BWNM41P/xYVhhAMFcIQEQ4QAAMQwAARCIMAB/ACEMAABwiCAEhwLyEFEM9xgADc
+WhSNdokZCwEAFY00iREIQQANFcAQCSBAAi8hBRASjTGNvwhCABMVhBAVFYUQDhWHECQViBAA20ok
+gHPgeKggAQMhDxAARCm+AwAjQA7PdoAAeK2CJhATHmaWJgIRQK468M9wgAAYCc92gAAASm5mfLgC
+IY8T7X9IJ04QzX5MIACQzCUigA/yHw4RABsLEwPPd4AAKKwUJw8R4o/7fwknjhPNfjhgMBCPAM9w
+gADwSWhgRCm+AwJ/CSeOEwAjQA7Pd4AAeK2CJxATH2eWJwIRwK8B4297AeESjS95VQhDgEkGT/Pg
+eOHF4cYAEc0ACQ0TEADdoKkR6NDlg/dP3aCpz3CAALBKFCBOA6COoKoAEcEANHgBiBDw0OWD90/d
+oKnPcIAAEEoUIE4DoI6gqgARwQA0eAGIAKvBxuB/wcWhwfHAfg1P86HBZcIIdih1z3CAAIoGhcGL
+ckAkQzAAiOL/RC6+FgAlQB4UFMIwz3GAAGypOGBfDTMWWKhTJYAQPwhTAUYlwBEPe8K4YQhTASDH
+ARSNMAAmgB+AANB4dnigqOSoRC6+FgAjQA44YFioAeNve1MjgADfCFKBGPABFIAwx3aAANB4tn4A
+riDABK4O8AEUgDB4vcd2gADQeK99tn7AHgIQIMDEHgIQCNw/BW/zocDxwL4MT/MacIogBwmSCC/z
+CnHPcIAA/AgBiIDgSiMAIJr0z3CAAPwI0YgSiM9xgADESRB2IAEpADIhEgRqdwohwCQD8Hp1z3CA
+ABgJfLjYYCwQwQDPcoAAeK1ELr4TACJALoIiEAMaYjMigw8AACAEz3CAAPwIGIh7e217Bdof/kok
+gHEA3aggQAVzbnR7tXvPcoAAQK15YiWJemIK6SMJAAApCEIALw1TEQHlr30L8EIlkRAvIUckYb2v
+fQ7wBxLPAADZanUL8IDlANnKJWEQA/IpbS95OnEB2S3pc250exUjQgPPd4AAQK1ZZwAnhRAVI0ME
+emdFiiWJf2c1CmMA548CIYQABxWBAAS/8H9CeAS5LyQIAQInQxBseC8gRg6+C6/5iHEOeAJ/COfu
+f0S/7X8LCBImCOftf8lwCnHpcoP/AebPcIAA/AgSiM9+EHb0Bsz/wQNP8/HAcgtP889woAC0D3AQ
+EADPdoAA/AiKIMcILg/v8iaGAY4A3aMIEQDPcKAAtA+8oFKOcY4jCsIAz3CAAGypf9kUI88AH2cs
+r62vAeNvewXZ7wrjgC6vAN8O3c9wgADgSehgkv9hvQHn8w11kO9/MY7PcIAAeK2CIBADRCm+Aydw
+MyCADwAAIAQxCBIFD44W6M9xgADcWhSOVokhCgEAFY5UiRkKAQAWjgHagOASicB6CQoBAAHYAK4G
+hs9xoAC0DwemcBkABBEDT/PgePHAz3KAAPwIIYqM6QDZA6oPiiKqgOAgqtQNIvLKIGIFPwHP//HA
+igpv8yhyCHYAgADdgOBE9gHdE3gApmlqANkPIcEAOGAA2XIKr/kPIYEAAKYE7RN4AKbBAk/z8cBS
+Ck/zz3GAAGypFXlAgaHBOOoPCt4FBSKCDwD/AABAoc9xgAD8CDWJz3CAANSpAYiE6US4D3hTIEMA
+QrhTIEEAz3CAABgJfLh4YDQQjQDPcIAANAlCIAAOOGA4EI4ArHoAHEA+i3AM2dj/AMCsfidwgCDD
+jwwABACMIMOPxPaKIAcNDng5Am/zocDxwMYJT/PPdYAA/AgEjRQgAQDHcYAAbKlOiQDei+qKIIcJ
+z3H+/v7+ag3P8setAdgh8GG6TqkxjYHhyiCBA87/jCAHjcoggQ8AAOYByiGBD7q7rdvq80SNz3GA
+ABgJfLkNe1lhKBHBABiNB9pg/QatANjBAU/z4HjxwEoJb/MA2EokgAHPcoAA/AjPdYAAQK3Eigok
+AHFmiqggQATzbvR/FX/5ZSSJv2cK6R0JwAAhCcIAJwhQAQHgD3gI8CpoKaphuA3wBo8LqgDYC/CF
+6ADYCaoB2APwKWgpqgqqAdhNAU/z4HjxwOIIT/PPdoAA/AhkjgO7Co50exUjAQDPcIAAQK09YEmO
+pI1Ve3pgRIobYzhgMQ2jEAaIAiJBA6aLBLgweRB4BL1mjqJ4YnoMeqYIr/kvIEYODni4YAjgDnhE
+uPEAb/MLruB44cXhxs9ygAD8CCOKz3CAAMRJK2AEis9xgAB4rYIhEANEKL4DJ3N5YTMhgQ8AACAE
+O3lrii15FHjHcIAAbKkCI00AIW08eS8hRYAc8gwQzgDRfs9+MX0TDrIQr31hvgkmTROvfQLwAd0J
+CVIArXkE8LN5LXksqG2oAdgIqgDYBfAA226oAdhvAu//J6rxwPIPL/MV2D4LL/IA3s91gAD8CA+N
+ywgQACKNnQmVATMmQXCAADxZQCcAcjR4AHjHrRGNyK3FrQStff8C2SKtLPCZ/wToA9gCrSXwBNgC
+rSHwsP/88cj/BdkirR7wJY3PcIAA4EkpYASNRCi+BgAhQg4AIoMPgABsqXiLBxXCEHpiTXp6/gWN
+AeAPeAsIswMFrQDYAvAB2CDoBI0A2gHgMo0PeEWtKQkjAAStCI0Z6AHYAK1CrRXwCiHAD+tyBdiK
+I9ULmHYNBu/xuHZmCi/yFdgB2AKtBfBaCi/yFdiBBw/z4HjxwOHFz3WAAGQGiiDHCc4K7/IghQCF
+Bg9v+Yoh/w7PcoAA/AgogjhgIYoGoorpJ4JtaDBzwCBsAcwhDIBYC8n/QQcP8/HAABaAQM9xgAD8
+CAypABaEQAAWgEBQJL6BDakAFoBAyiHCD8oiwgfKIGIByiOCDwAAaADPI+ICcAXi8colwgBRJICB
+ANjKIGEAD6nPcIAAiAYAkAPo2v2+/ioPz/IfBY//4HjxwLhxLQhRAAkNUgAVDdIDCiHAD+tyBdiM
+2y0F7/GYc0AtgAAUeGy4x3CAAGhLHPDPcIAACE4yIEABjCDDj8ohwQ/KIsEHyiBhAcojgQ8AAJEA
+9ATh8cokwQACuBR4x3CAABBM0cDgfvHA+g0P8892gACKBgCOz3eAAIgGII/h/0GIz3WAADgJIJcR
+Ct4AAdgArYogxwND8AKABugA2ACtkLk78F8KHgHPcoAA3FoWilMJAQAAlnSKSwjBAM9wgACMBgCI
+Uoo/CgEAz3CAABgLCYAzCF4BQYUA2w7qz3CgACwgEIBCeBEIhQ8xAQAtAdpArQTwYK0A2hC6iiBH
+A0V5DfABjQboAdgArYogBwMH8ADYAK2RuYogBwQaCc/yrQUv8wCN8cBCDS/z2HEKJoCQiHXMIyKA
+BvJCJgYBLyaHAchxsP/PcYAAOAkDoR7uJIgCuTR5Q4gD4WKIHQofAAohwA/rcgXYiiNIAJhz2QPv
+8QolgAEIYRcIXwAKIcAP63IF2IojCAHz8WGI4LvKIcEPyiLBB8ojgQ8AAA8CyiBhAeXz4b3RIyKB
+yiHCD8oiwgfKI4IPAAAVAsogYgHX9SENHhBRI8CAyiHBD8oiwQfKI4EPAAAbAsogYQHJ8/UED/Px
+wH4MD/MacM9xgADcWs92gACIBgCWVonPdYAAOAknCgEAz3CAAIoGAJBUiRcKAQDPcIAAjAYAiDKJ
+CwkBAAKNAvAA2AGtkf/PcIAAjAZAiM9xgACKBgCJII6A4gHawHoKcwDfmHe4/wOFAYgglhEIHgEB
+2AOtiiBHAwXw462KIIcD0g+P8l0ED/PgeM9xgADcWs9wgACIBgCQVokrCgEAz3CAAIoGAJBUiR8K
+AQDPcIAAjAYAiDKJDwkBAM9xgAA4CQGJAqngfuHFUyANAKCpBCCBDwAGAABCIQGABCCAD0AAAADK
+IWIAIKrXcEAAAAAB2MB4AKvgf8HF4HjxwH4LD/OhwQh2KHcacgDdz3CgALQPcBARAIogxwA6D6/y
+yXHPcKAAtA+8oItxQCRCMEAkgzDpcOX/DQgRIEokAAAJ8M9wgADoggGI+ehKJIAAIMABFIIwyXEC
+FIMwe//PcIAAOAkpiIDhzCZCkAXyI4CqqKKhMQ9eEc9xgADcWlaJJQ6BEFSJUycDEBkLgQAEJ48f
+AAYAAIDnAdoyicB6CwpAAKKooaCgqIogxwCqDq/yyXHPcaAAtA9wGUAEIQMv86HAhCgLCgAhgX+A
+AJyjKBGAACiBANqU8eB48cCP6BH/z3GgACwgMIHHcUlrANIioGYOr/KKIIcFkQTP/+B48cDYcYno
+CP8A2SKgiiDHBUYOr/LIcXUEz//gePHA4cXPdYAAOAmKIEcGLg6v8imNBNiGCW/8AdkIjSmN6P/B
+Ag/z4HjxwM9xgAA4CYogxwYGDq/yKYnPcIAAUEsyDU/5KQTP/xEIHgIEIL6PAAAAGAHYA/QA2OB/
+AKngePHABgoP86HBCHUA3s9woAC0D3AQEADPcKAAtA/coOONiiAHAbYNr/LpcQSVi3FAJIMwgOAB
+2MB4LycAAAWFQCRCMIT/CoVAJEEw6P81D3QQlSVDHlYlABjwIIADViUBHNR5IInAuAUgwAEvJAcA
+IMABFIIwAhSDMBX/AebZDsSTiiAHAVYNr/Lpcc9xoAC0D3AZAATVAS/zocDgePHAZgkP86HBGnAA
+3s9woAC0D3AQEQDPcKAAtA/coIogRwEeDa/yCnGEKAYvACGNf4AA0H4h8EAlABcWIIQDBRSAAIYg
+/ocY8gSFi3FAJIMwQCRPMOlyWP+oFQAQ6XG8/yDABBSBAAEUgjACFIMwSiTAAPD+AeYMlb8OBJCK
+IEcBvgyv8gpxz3GgALQPcBlABAvx4HjxwN4IL/OKIAcGz3aAADgJmgyv8iSGFd0EhjJoAeA0ecdx
+gAAQTASmAoES6M9zoAAsIHCDYnjXcElrANIA2sj3QqGKIMcFZgyv8iCJBIYLCJQKANgEpmG9wQ1V
+kO0AD/PxwM9xgABkBooghwE+DK/yIIHk/89wgACIBgCQgOBkCsL/XQLP/+B48cBOCC/z2HGhwRpw
+i3FAJEIwQCSDMMhwIP8BFIAwCegCFIAwBehCIBAhLyAHJCDACnFw/gEUgTAD6aKIAvChiIogxwHe
+C6/yyHFAKAAmQC0CFAV6ARSAMAIUgTAIuAV6iiDHAb4Lr/JFeeG90SXikAPyHQ0eEQohwA/rcgXY
+iiOMBphzsQav8QolAAQo8eB48cC+D8/yz3CAABgLKBCQAKiAiiAHAn4Lr/IKcVMlABAKcVD+AYhR
+IACByiHCD8oiwgfKIGIByiOCDwAAMQPKJMIAZAai8colAgTZB8/y4HjPcaAAYB0SsRSR4H7xwGYP
+7/KYcLhyfwlyAADaFSSAAOCIoojYccOIIYjPcIAATAkBkDhgEHjz/wQggQ8AAAD/R7lMJQCAAr20
+fcAlgh+AAGhLwCWBH4AAEEzgrQPrAq0C8AGtJQgeAAzrA43ybvR/gLgDrfhlA4i/Z4G4A6/ErQPr
+Jq0C8CWtQiZBAJEJdYAB4kkHz/LgePHAz3CAAAhPDtkB2gDb2v/PcIAAQE8H2QHaSHPW/89wgABc
+TyrZANoA29P/z3CAAARQC9kA2gHbz//RwOB+4HjxwGbYyf/PcoAATAkBsmfYxv8AsgGSAeAQeMT/
+ArIBkgLgEHjB/wOy5v86DE//5/HxwOHFCHUocwfwqXC7/wIbFAAB5bB9YbqMIv+P9/XFBs/yAAAA
+AAAAAAAAAAAAAAABAAAAAAAAALgLgABIDIAAAFqAABAAgAAECMAQCgATZDwFgIEAAMAWBAETYg9c
+ACIKAABAAAYAcB8AAGEAABMkAAATJQAAwBfIIMAQcEXAEBAIwBD//1wzAAATJAAAEyUECMARDxQV
+IgQAFSb7/zAyAwATJBgIwBEcCMARDxQVIgEAFSYEADAwAAJFcAIAAGEBABMkLBDAETAAEyTsHMAR
+AwATJFAUwBEEGMARAAATJBBFwBEYCMARD3wTIggAzBEBEBMkBCjAEQ8UFSICABUmD3oTIhgowBEP
+exMiAAoTMgACE24AIBMwAAgTbgBAEzAPFBUiBAAVJgEAEzAEKMARD00TIgQQxRECABMk8BzAEQEA
+EyTsHMARAAATJHAAEyUQHMARAAATJQAAEyTgHMARAQATJCQQwBEAAAAhAAATJQAAEyQPRQAiAFwA
+OQMAAGICYABiAABYOE0AAGEkEMARAIATJDgcwBEPcxMiBQATQEIFEzAEKMARAWATJAQowBEPchMi
+CADMEQ9EACIKAABAAEAAcA4AAGEAABMlAgATJOwcwBEPdhMiGAjKEQkAE0AcCMoRCQATQCAIyhEP
+eBMiBADKEQAAASQAAAElBgAAYQ92EyIsSMcRD3gTIgAAxhEDAAEkAAABJQ8UFSICABUmD0UAIgBc
+ADkhAABkAAATJAEAEyU4HMARD3cTIuAcwBEPARMiBAjAEQ8UFSIBABUmDwMTIv/wEzIYKMARAAMT
+OP/zEzIYKMARAAMTOBgowBEDABMkAAATJQQIwBEAABMkOEXAEQ8DEyL/PxMy8P8TMw8TAiJgSICB
+AADAFgACEzgYKMARARETJAQowBEEAABhAABYOAAAEyQBABMlOBzAEVhIgIEAAMAWCAATYgAAEyUD
+ABMkVATFEX8CEyQEAMURXEiAgQAAwBYIAMURAAAAIbhZgIEAAMAWPATAEQAFgIEAAMAWBAEbYhAE
+wBADABskVATAESQEwBEIBMAQeFmAgQAAwBcIBMAQWFmAgQAAwBcAABslAxwbYkAAGyQwHMARBQAA
+YQQFgIEAAMAWDxsZIggEoIE48MSAAAAbJAIAGyU4HMARAAAAIQAFgIEAAMAWTATAEQQFgIEAAMAW
+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/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu b/sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu
new file mode 100644
index 00000000000..636a7ba4b26
--- /dev/null
+++ b/sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu
@@ -0,0 +1,8112 @@
+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-6000-9.176.4.1.fw.uu
+AQSwCds9AAAUQwIAAEABAKhBAgAAQAEAAAAAACAggA8AAEAAaSAAAGkgQABpIAAAaSBAACAggA8A
+AOgAaSAAAGkgQABpIAAAaSBAACAggA8AAHgGaSAAAGkgQABpIAAASiAAAEohAABKIgAASiMAAEok
+AABKJQAASiYAAEonAABKIAAQSiEAEEoiABBKIwAQSiQAEEolABBKJgAQSicAEEogACBKIQAgSiIA
+IEojACBKJAAgSiUAIEomACBKJwAgSiAAMEohADAKJIA/gQAAQEEsnDBALJwwQiQcNAoigD+AADBr
+CiMAN/4PAABKJgBwaSBAAEomAHBKJgBwSiYAcEomAHAAFgBwgABkBEB4ICBAhwAAAAAAAAAAAADh
+wOHB4cLPcKAAyB8WEAGGz3KAAJh/IKISEAGGIaITEAGGIqIUEAGGI6IVEAGGJKIkEAGGJqLPcZ8A
+uP9WoYoh/w8SGFiAExhYgBQYWIAVGFiAJBhYgMHCwcHBwCAgQIcMyM9yoADIHw4aGIANyA8aGIAO
+yBAaGIAPEgE2AcgkeBEaGIAQyC0aGIDgfuHE/BzIvvwcSL7hwOHB4cLhw/wcCLH8HEix/ByIsfwc
+yLH8HAiy/BxIsvwciLL8HMiy/BwIv2okgBDhxGokwBDhxPHAz3CgANAbFIDPcYAAYAQEIICPz1EE
+4QChCvIvKQEAz3CAAOQN8CBAAEB42v/RwMHEayTAEMHEaySAEMHEn3QEFAs0BBQKNAQUCTQEFAg0
+BBQHNAQUBjQEFAU0BBQENMHDwcLBwcHAwcRFLH4QCiZAfsHEaySAFMHEICBAhwzIh7gMGhgwDcib
+uA0aGDAOyA4aGDAPyIe4DxoYMBDIEBoYMOB+4HjxwAzIlbgMGhgwDcibuA0aGDAPyIq4jbiQuA8a
+GDDPcIAAHA8YiIHgC/QPyM9xAAC0DKy4DxoYMFYOIAAP2GfYNgsgAYohBgrRwOB+8cDPcIAAsK8A
+gIYg/oEJ9A/IBSCADwAAANQPGhgwof+KIFUFBgsgAYohRg7o8eB4z3EDAEANz3CgAKggLaDPcYAA
+jARAgQFqAKHPcKAAOC4FgAQggA/AAAAA13DAAAAACvJI2M9xnwC4/xqhW6Fp2Bi4GaHPcIAAeAgl
+gCOBIIHHcQAAiBMNA8AJ4HjPcIAAeAidAsAJ4HjxwB4MAAGA4M93gABgBIh1BfKB4AX0AdgC8ADY
+C6+A4QXygeEF9AHYAvAA2AqvgOIF8oHiBfQB2ALwANgMrwDYz3agAMgfGB4YkAuPgOCKIRAAD/II
+j4DgC/LPcAMAQA1FHhgQMKYC2BgeGJAC8DGmCo+A4BnyCY+A4Bfyz3ACABRDIB4YkM9wgAAoACEe
+GJDPcIAAXAQiHhiQGBYAlkUgAAMYHhiQDI+A4AjyGBYAloUgAQQYHhiQgeMH9BgWAJaIuBgeGJDP
+cIAAMHQAkI7gzCCiggb0GBYAloC4GB4YkIDlGfIA2JS4z3WAAIAEAKVx2Aa4Zg0gAfzZIIXPcAAA
+TBxaDSABn7kYFgCWhbgYHhiQdQMAAeB4z3Gqqru7z3CfALj/NqA2oDagNqDPcaAAyDsOgYi4DqFp
+IEAA/vHgePHApcFBwELBDBwAMRAcQDHPcYAAfGw0GcAPMBkADywZwA4oGYAOJBlADs9wgAB8bCAY
+QAvPcIAAfGwcGAALz3CAAHxsGBjACs9wgAB8bBQYgArPcIAAfGwQGMAIz3CAAHxsDBiACM9wgAB8
+bAgYQAjPcYAAAGyAGQAIfBnAB3gZgAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZ
+QAVQGQAFTBnABEgZgAREGUAEQBkABO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlA
+ARAZAAFjoWogAAPYGQAAaiDAAtQZAABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGog
+gAC8GQAAaiBAALgZAABqIAAAtBkAAGoggAHMGQAA0NifuM9xnwC4/x2hz3CAAAAAxIBTJcQ1UybF
+Nde6AebTvsSgUyPABAUmjh/Q/gAA1qEFIIAPsP4AABahGIFTJ841AN2UuBihQMMBwALByXMMFAYw
+GgggARAUBzDPcKAAtA+8oM9xoADIOy6Bsg/gAH3YMg9AAboLIAGpcAjYANlmCyABmbnPcIAAMHQA
+kI7gzCCigsoggQ/gAMQxyiEhAJAIYQHPIaEF/QXP//HA1gggAXvYag/gAOHZz3GAAHxsNBnADzAZ
+AA8sGcAOKBmADiQZQA7PcIAAfGwgGEALz3CAAHxsHBgAC89wgAB8bBgYwArPcIAAfGwUGIAKz3CA
+AHxsEBjACM9wgAB8bAwYgAjPcIAAfGwIGEAIz3GAAABsgBkACHwZwAd4GYAHdBlAB3AZAAdsGQAH
+aBmABmQZQAZgGQAGXBnABVgZgAVUGUAFUBkABUwZwARIGYAERBlABEAZAATvoc6hraGMoSwZwAIo
+GYACJBlAAiAZAAIcGcABGBmAARQZQAEQGQABY6FqIAAD2BkAAGogwALUGQAAaiCAAtAZAABqIEAB
+yBkAAGogAAHEGQAAaiDAAMAZAABqIIAAvBkAAGogQAC4GQAAaiAAALQZAABqIIABzBkAAOt2z3Wg
+AMgfGRURls9wAABEHCoIYAEKIMAvWnDPcIAAHCkjgM9znwC4/893gAAAAASHgOEB4NO4JPIZFQKW
+USLAgB7yXYNA3p++3aMEpwUggA/Q/gAAFqNYG4AHIRUAliIVAJYEIYEP/wD8/wCBFqMI2BkdGJBW
+o12jaQfAANDZn7k9owSnBSCAD9D+AAAWo89wgACABACACyCAhAjyWBuABPYKQAIM2C7wjCEEoCfy
+jCEBoCPyQiFBII/hRgANADMmQXCAAABUQCeAcjR4AHhKIUAgDdgW8EohgCAE2BLwE9hKIQAhDvBK
+IQAiFNgK8EohACQV2AbwFtgE8BfYAvAP2M9zgACQDHCDCnHJcgokQATdA+//CiWABC0Cz//xwF4N
+wAB12BoN4ACKIQoDwgwAAP4PgAJb/qIIAAAKIcAP63IG2IojSgdKJAAApQPv/wolAAHgeIDh8cAD
+8qDgi/YKIcAP63IF2OPbSiRAAIED7/+4c89ygADkDRV6IKLRwOB+ANmeuRl5z3KAANwNAYIleOB/
+AaIA2Z65GXnPcoAA3A0BgiZ44H8BogDZnrkZec9wgADcDQGAJHhCIACA4H/KIGIA4HjPcIAA3A0B
+gOB/LygBAOB48cDiD4//4HjgeOB44HhpIIABbyE/AGkgAAD38fHAathKDOAAiiHEBQDYjbgKCuAD
+ChoYMBTMhiD/ignyz3CAACkFAIiA4AwPwgOw8fHAMg/AA89xgACQCPAhAABAeM9woADQG4DaUKDP
+cIAAAAAAgFEgAIIA2Qbyz3CfALj/PaCU8eB48cByDcAAz3GAAAAAAIFRIMCAG/IBgVEgwIBA2M8g
+4gfKIIEPAADQAM8g4QfPcp8AuP8dogSBAeDTuAShBSCAD9D+AAAWos9wgABgBKCAz3CAABwPCIAE
+JY0fDwAA4Ou4Ad4G9FIIAAyA4A70z3GgALRHANhLGRiAdxmYgwDYnrhUGRiAz3KAAJgEIILhggQl
+hB8BAAAAQCyAAKR4BCWDHwAAAEAHeQO7IKKkewR5Z38GJUAQ4aIEJYEfAAAAgC8iAgFFeQK55HsE
+JY0fAgAAAGZ4pHkmeC8oAQBOIEEEz3CAAHRr8CBCAM9wgABEtYQqCwwwIEAOUyBAgBsaWDAt9M9w
+nwC4/zighuEZ9M9ygACIfgmSgOAM8hsamDPJcc9ygACQDBuCAeAbohfwDJKA4BPyBNkbGlgw8/GE
+4cwhYoAL9M9wgACIfg6QgOAF8gbZGxpYMOXxz3KgABQEKqLPcIAA9AcAiIHgBfQJgrjgANiC9wHY
+gOAI9M9woACIIDV4wKA58M9xgAAwBQDYAKEA2ZG5z3CgAMgfExhYgM9wgADQAhB4z3WgALRHSR0Y
+kM9xgADEjc9wgAA0BSCgbydDEFQd2JPuD6ADChqYM+oOwAuA4BH0ANiRuM9xoADIHxMZGIDPcIAA
+AAQQeEkdGJBUHdiT6QPAAOB48cB6C8AAz3GAAGANgBEAAM91oADIHy8uARDPcAMAQA2f5kUdGBAA
+3x/yz3KAAAAAAILyuBnyAYLyuEDbzyPiB8ojgQ8AANAAzyPhB89wnwC4/32gZIIB49O7ZKIFI4MP
+0P4AAHag8CGAA0B4n+YM8s9wgAAAAACA8rgG8s9wnwC4//2ggNgVHRiQWQPAAOB48cDPcYAAYAR8
+2FYJ4AAggQohwA/rcgXY/dtKJAAA8Qev/wolAAHgePHA4cXPcIAAYASggGvYBCWNHw8AAOAiCeAA
+iiEICy8oQQOaC6APTiBABAolAIDKIcIPyiLCB8ogYgHKI4IPAAAyAqQHov/KJGIAf9gKuM9xoADQ
+GxOhf9gQoeECwADgePHA4cXPdYAAAAAAhe+4GvIBhe+4QNjPIOIHyiCBDwAA0ADPIOEHz3GfALj/
+HaEEhQHg07gEpQUggA/Q/gAAFqFr2JYI4ACKIcgPEgugDwTYCiUAgMohwg/KIsIHyiBiAcojgg8A
+AEECHAei/8okYgAAhe+4BvIA2c9wnwC4/z2gWQLAAEokwHUA2aggwAPPcIAAZA42eGGAQIDPcIAA
+YA0B4VV4YKDgfuB+4HhRIUDHBfINyL24DRoYMADZnbnPcKAA0BsxoOB+4H7gePHAgeDMIKKABfTP
+coAAHA8E8M9ygABYss9xgAC0f4HgzCDigCn0aIJgoWmCYaF8imipfYppqSoSgwBqqSsSgwBrqSwS
+gwBsqXSSdqltkmexd5JosWiCwLt0qWiCBCODDwAGAACA4wHbwHtyqYQSAgBUGZgAHPBggWiiYYFp
+omiJfKppiX2qaokqGsIAa4krGsIAbIksGsIAdol0smeRbbJokXeyVBEDBoQawACC4Ab0mgwgAUAh
+AAbRwOB+z3CAAFiyIIDPcqAAgCUmoiKQJ6IigCqiJpAros9xgACwryCBUSFAgCCAFfQooiKQKaIi
+gDGiJpAyoiKAN6ImkDiiIoA7oiaQPKIggDmiIpA6oiCANaIikDairQfAD+B48cB6CMAAz3CAAHiW
+AN7UqM9wgACwrwCAUSBAgBPyCN/JdYDlzCWikMwlIpHMJWKR3AhiBMogQgNhv4DnAeUz9xzwiiQB
+cc9xgACIfqggQAEEGZAD4HgA2UokAHLPcoAA4ICoIAADFiJAAHaQz3CAAAB/NHgB4WCwz3WAAFiy
+z3eAAFCSQCUAEiRvfg3gAAbaqXBAJ4EScg3gAAbaQCUAEkAnARRiDeAABtoYjYTgD/SKIA8KOg6g
+AIohmggoFYAQGg/gECiFig2ADwmFUSBAgQnyiiCHDhoOoACKIRoORgzACc9wgACwrwCAUSBAgEQI
+gQTPcQAA///PcIAABI8soCugBRqYM6f/2QeAAPHAbg+gAADahCgLDAAhg3+AAFiytRuYAM92gAAQ
+VLRoumZSggKGACGBf4AAVLTPd4AABIG6G5gAYYbcGcAAZYbgGQAABobkGcAA6BkAABYngBAWJoEQ
+COAE4UIM4AUI2t1lFIUWfhZ/QCcAEiRuLgzgBQjaYQeAAPHAANjh/8YN4AUA2M9wgACULVIOQAnP
+cIAA1C1GDkAJUggABq4NAAUB2ADZUgogD4DaPgxADE4LgA8SC8AJRg3ACmoKQAoA2K4P4A8Icc9w
+gABESwCIUSCAgAjyz3GgAMAdAIGguAChzgzADN4LAAqpBc//8cDhxQDdz3CAAFwFoKDPcIAAXJas
+sD4O4AmpcOIJj/+eDmAMqXC2CkAG/gtABAYMQAsiD6AMqXDuDoAMvQaAAPHARg6AAILgo8EG9M91
+gAAcDwjwhCgLDAAhjX+AAFiyguAG9M92gACsnAnwz3GAACC1hCgLDAAhTg4tlTx6KHCGIfEPR7nC
+uoYg/gMkekS4UHHKIcIPyiLCB8ogYgHKI4IPAAA8BMokIgD8AqL/yiUCAUiFO7pTIgKAQK5NlcC6
+Qa4M8neVhiP/CUO7Z653lYYj/gdFu2iugOIS8s9ygADcNhUiAwAAizV6Aq4BiwOuAosErgOLBa4D
+igvwAdkprgLYAq4jrgDYBK4D2AWuBq6LcMlxmgrgBQzaAMABwfYP4AwCwotwyXGGCuAFDNoAwAHB
+YgggDQLCz3GAANAGAKENlUS44LgA2S+lBfKKIQgAL6XhuAPyi7kvpVEggIAE8o25L6WNBaAAo8Dg
+ePHAFg2gAJhwhCgLDAAhgH+AAFiyVSBGCiiAVSDFC89ygAAYBVEhwICKIQgAyiEhACCiSiQAcgDZ
+qCCAD891gABYWPyILmXkfi8qgQNOIoMHz3KAAHxYb2IAJkMA4KtUEI8A5H4vLoETTiaPF+5iyKvI
+gFEmwJAP8l2IhuHTIqYALyqBAE4ijQfPcoAAhFiqYhDwz3aAAGxYLmbOZbyIxH1sEI4AxH0vLUET
+TiWOF8piUKsB4UokAHIA2qgggQDciM9zgABkWE9jz3WAAHxY5H4vKYEDTiGPB+9lACaBAPypVBCP
+AOR+Ly6BE04mjxfuZSQZggPIgFEmwJAP8n2IgOLTI6EALyvBAE4jjQfPc4AAhFirYxHwgOID8slq
+AvBIds5jfIjEe2wQjgDEey8rwQBOI44Hy2UsGcIAAeJKJABxANqoIEAFz3GAAGBYfYhJYQAljAAB
+4mR5LylBAE4hgwfPcYAAhFhpYSCsWg2gCIhwDQSAAPHAoguAAILgBfTPcYAAHA8H8IQoCwwAIYF/
+gABYsumBWIlBL8MQwLsXu8dzAACAHOS/zyMiBuC/Tt3PI6IAyiWCHwAATgGG4s8lYRLlvyz0z3KA
+ALR/FhKFAM9ygABktUaSsHLPdoAAWLLFFgQWDPTEFgIWUyIFAM9ygAC0f1SKsHIL8kEsQgFRIgCA
+BfJJhlEiQIEJ9FEkQIEG9EmGUSJAgQPygbvPcoAATLVUiofizyPhAFEnAJLPI6IFguCIGcAAjBlA
+Awb0z3GAABwPCPCEKAsMACGBf4AAWLJpEYMAThEOAQ4jgg8AADoBCbpifkV+WpFiehK6RX5bkWJ6
+QCrNBcV9BCW+nwDwAADKIcIPyiLCB8ogYgHKI4IPAADFAM8j4gLKJMIAnAdi/8olQgOC4JAZQAMG
+9M91gAAcDwjwhCgLDAAhjX+AAFiyz3CAADB0AJCO4MwgooIq8gfYtgrgAAq4BCCADwcAAAAwuIfg
+ZAANADMmAHCAAHRUQCcBchR5AHmKIAQAlB0AEB7wiiAQAJQdABAa8ADYi7iUHQAQFPAA2Iy4lB0A
+EBDwANiNuJQdABAK8APYDLiUHQAQBvAA2I64lB0AEIIgAQE9AqAAlB0AEAohwA/rcgXY+tuLu0ok
+AADhBm//CiUAAfHAtgmAAILgCHUG9M92gAAcDwjwhC0LHAAhjn+AAFiyAdloHkIQAN+AHsATTNhO
+HgQQBdgQpgrYG7YQ2Bq2FNhMHgQQLdhQHgQQJthSHgQQSiQAculwqCCADc9ygAC4WPQiAwDPcoAA
+HJAUemCyz3KAAMhY9CIDAM9ygAAskBR6YLLPcoAA2Fj0IgMAz3KAADyQFHpgss9ygADoWPQiAwDP
+coAATJAUemCyz3KAAPhY9CIDAM9ygABckBR6AeBgsgiG5bgF8gTaYh6CEAPwYh7CE+S4CvIJ2Woe
+RBAu2l22AtppHoIQCvAU2moehBAy2l22aR5CEBTZWY5RIACAWWEweWoeRBAa4Ty2CvIK2GQeBBAG
+2GYeBBAH2AjwENhkHgQQZh7EEwXYEKapcJL+PI4ocFQeQhCGIAMA5rlsHgIQyiJBAAvyUCHDAW96
+VB7CEFAgwwFveGwewhDluQfySHOGIwMAb3pUHsIQ5LkE8qW4bB4CEFEhwIAE8qS6VB6CEILlGPKp
+cMf+z3CAACy1hC0LHDAgQA5RIECA8djAKCIByiCBDwAAkwDAKCEBoB4AEBjYjbgXpgiGUSDAgM9w
+gABYsgbyvhCAAIm4BPClEIAAFqbPcKAArC8ZgDC4wLiKCiAQVR4CEAiGBCC+jwAGAAAL8ja4wLgb
+eAHgbh4EEALYgB4AEAPwbh7EEwDYHKYdpqlwAf8ohgHaSHNBKQAFNblSIAAAUiEBAMC4wLluC2//
+mHLtB0AA4HjPcIAAHA8IgM9xpAAcQMC4E3jBuBKh4H7xwOHFz3WAABwPV5XPcYAA1AbgulfYAKED
+8l/YAKHiugPyhbgAoVEiQIAE8oe4AKHPcYAArJxAiQDZgOLKIEEAz3GlAOgPBqHPcaAApDABgYDi
+zyDiANAg4QABoXoJQA0whc9woADIHCigKgqgDQ+FbQdAAOHFz3CAABwPKYBEIYOAANok9JDiigAG
+AAAijQ+AAIArAI2guACtgBWAEKC4gB0CEEAVgBCguEAdAhAQjaC4EK2QFYAQoLiQHQIQUBWAEKC4
+UB0CEAHi3/GQ4kYABgAAIo0PgACAKwCNgLgArYAVgBCAuIAdAhBAFYAQgLhAHQIQEI2AuBCtkBWA
+EIC4kB0CEFAVgBCAuFAdAhAB4t7x5rkQ8s9ygACAKwiKgLgIqogSgACAuIgaAgBIEoAAgLgS8IDj
+EvTPcoAAgCsIiqC4CKqIEoAAoLiIGgIASBKAAKC4SBoCAFEhAIAA2B7ySiQAdOB4qCBABuK4FPIA
+IIMPgACAKyATgQCAuSAbQgCgE4EAgLmgG0IAYBOBAIC5YBtCAAHgHfBKJAB04HioIEAG4rgU8gAg
+gw+AAIArIBOCAKC6IBuCAKATggCguqAbggBgE4IAoLpgG4IAAeDgf8HF4HjxwJINYAAH2s92oADI
+H0gemJDPdYAAHA+AFQAQz3GrAKD/TB4YkADYGaFaoRihiiAEAA+mahUAEc93gAAwdLAeABC0HgAQ
+H9gIuA6mCIVRIACAANiLuBXyEKaqD4APz3GgAKQwAYGEuAGhBJeF4Br0ANmUuc9woAAERCWgEvAR
+ptIPgA/PcaAApDABgaS4AaEEl4XgBvTPcaAABEQA2AWhz3CAAMwEAIDguAryhiD/DiK4FLjPcaAA
+BEQFoVb/ng7ADFv/d//PcAAAVVVaHhiQAdhZHhiQCIXPcaYAKADzuAbyANgPoe4PwA8E8AHYD6Fu
+FQERz3CmAOgHJqBuCIADIgygDA2VB4+A4AvyiiDYCfYKYAAB2WIJIAMC2ATwAg9gAwHYiBUAEM9x
+oADEJw8ZGICMFQIQz3CgADAQRKDPcIAAFIkQeI8ZGIDPcoAAxIlQeJYiAgAQukV4kBkYgIogBACS
+GRiAkBUAEECXQBkAgM9wgACAK1MZGIAPEQCGjuKfuA8ZGIDMIqKCCPQIEQCAhSCEAAgZAICK4gf0
+CBEAgIq4CBkAgA/YEBkAgJQVABAcGRiACIX9uA3yCgugDwDYDgugDwHYz3GmAPTPAdgSoQPw9gqA
+DyUEQADgePHAsgtAAAolAJDPcIAAWLIacQX0xRABBgLwKYAluVEhAIAo8s9ygAC0f89xgABktSaR
+doowcwj0xBABBlSKwLlQcQvyxRABBlEhQIEF8imAUSFAgQ70CiHAD+tyBdjPcwAAEQlKJAAAcQBv
+/wolAAGELQscL3fPdoAAHA/4YMlxdgigACnaz3GAAKycACeAH4AAILWuCKAADNrPcKAAtA8A3/yg
+SIZTIgAAhg0gDDSW5g/AAlz/gOWoDqEMyiBhAATIUSCAgAXyugkABAvwANmeuc9woAD8RCGgz3Cg
+ALQP/KBMIACguAyiD8ogYgDPdYAAoAQMjYDgBfQKCoANAdgMrRUDQADgePHAogpAAAolAJAB2BHy
+BMhRIICADPQKIcAP63IF2IojRw5KJAAArQcv/7hzANiELQscz3aAAFiyACZPHoQoCwxAJgEZMCFA
+DkmHJbglulMgEQBTIhIA6XDqDmAADdk2C6AQqXAJh4DlJbhTIBAABvQD2Cr8cPwE8K4KgA9MIACg
+HvJMIgCgyiHCD8oiwgfKI4IPAAAbAsogYgHF9SYNQAgqCOAAAdhMIQCgz3eAALCvBfTWDIAK2gyA
+ChfwDgjgAADYgOXPd4AAsK8E9Lv8CfBSCoAPAIdRIECAWAqCD0whAKBMC4H/qXAE/pYLoAGpcEwh
+AKAE2AQaGDAx9M9xgAC0f89wgABktQaQVokQcgj0xBYAFjSJwLgwcA/yxRYAFlEgQIEJ8gmGUSBA
+gQXyAIdRIECAE/SpcApxcP9/2RG5z3CgALAfNKCqDwAID8gFIIAPAQAA/A8aGDAAh1EgQIAg8s9x
+gAC0f89wgABktQaQVokQcgf0xBYAFjSJwLgwcAnyxRYAFlEgQIEJhtEgYoEI9BiOz3GAABwPGKkJ
+hgmhAd5KCSAMyXDPcIAAsQZiD+ALwKiB5Qz0z3CAAEy1FIiH4Ab0TCAAoMgJgg+eCYAPegxACCoN
+QABeC6ACANghAUAA4HjxwADYhv/GCw//z3GAALR/FomiC2AQNInVB0//8cCqCEAAgeDPdoAAWLII
+dQP06YYD8MUWDxYlv4QtCxwAJlAeJBAAIMC/USBAgcohwQ/KIsEHyiBhAcojgQ8AAK0CyiQhAIwF
+If/KJQEBz3CAAHAPgOUBiMxxNPRAgc9xgAC0f0ChABYDQIDgYaEAFoNAaKkAFoNAaakAFgBBA/IP
+tgAWgEAEIoIPAAYAAAqpABaAQIDiC6kAFoBAAdoMqQAWgEAAFgBBwHoHsQAWAEEIsQAWAEBSqWIO
+b/8E2DnwIIHPcoAAULbEHlgQABYBQIDgxR5YEAAWgUAUGkKAABaBQBUaQoDMcAfyIJDPcIAAZLUh
+sALwAJAAFoBAz3GAAFS2IhoCgAAWgEAjGgKAABaAQCQaAoAAFoBAABYAQQ4ZBIAAFgBBIhkEgAAW
+AECveHL9TgmgAalwz3GAALR/VomA589wgABktQaQIPQQcgj0xBYAFjSJwLgwcBLyxRYAFlEgQIEM
+8gmGUSBAgQjyz3CAALCvAIBRIECACPQkEAEgqXAlucC53f7iD0APcgtAAH0HAADxwADYmv/PcYAA
+tH8WifYJYBA0iSkGT//xwADZz3CgALQPPKBmCQANNg0ADeoKAAwWCmANANj/2c9wqwCg/zmgAtgq
+C2AABBoYMPUFT//geIQoCwwAIYB/gABUtOAQAgDPcYAAsIHcEAMAYBmAgOQQAgDoEAAAXBnAgGwZ
+gIDgf3AZAIDxwI4OIAAS2anBCHYCDWAAi3BKJABxANqoIIACFiSAMCiIgeHD9mG5KKgB4gHCAsGE
+LgscACGAf4AAVLTcGIAABcLgGEAABsG0buQYgADHdYAAEFRIFREQ6BhAAM9wgAAEgQogQC4WIEAE
+COCDwVYLYAUI2vSFz3CAAASBh8H2eAjgQgtgBQjaAMAAII0vgABYslEgAIC1HRgQCPK6HdgTuxUA
+FoC4B/C6HVgUuxUAFqC4ux0YEM9wgAA0slSINohEKj4LACGAf4AAkLA1eAaIEHb8DuH/yiCBA7UV
+ABZRIECA8djAKCIByiCBDwAAkwDAKCEB8glgAKAdABDxBSAAqcDgeADYfvHxwKXBi3AeCmAABdkA
+wuC6E/LPcIAAHA8YiIHgDfQA2Jq4z3GgAMgfD6EBwKQZAADD2Bq4DqFRIoCAFvIGEgI2ANlKJABy
+4HioIIADuHGDcSiJESJAgAAiQDFkGEIACfJAJUEAeglAAKXA0cDgfgohwA/rcgXYiiOPAzkCL/9K
+JEAA4HjxwM9wgAAcDwmAUSBAgcohwg/KIsIHyiBiAcojgg8AABcHyiRiAAgCIv/KJcIAHgtADKoM
+YAkB2M9wgABMtRSIh+Aj9M9wgABAtQuAUSBAgRvyz3CAANywCpDPcYAAqJYlgQq4MHDKIcIPyiLC
+B8ogYgHKI4IPAAAhB8okIgCwASL/yiXCAAIID/++DOALANiWCsALxghAAJUDT//xwALYrfy2/YkD
+T//xwGIMAAAA3s91oAC0D9ylyg7gC2h3+P/2D2AM6XAEyFEggIAE8goLwAMJ8ADZnrnPcKAA/EQh
+oNylkQQAAOB4hCgLDM9xgABAtTAhQg7PcIAA4IBWeHaQz3GAALR/xBncABeQz3OAALCBxRkcAM9w
+gAAEgVZ4DIiQGwKAANjgf8cZHADxwOoMT/9ODEAPVg1P//UCT//gePHAzgsgAETaz3WAABBUxG3P
+cYAACIFCCWAAqXBKJIBwANmoIIAIFGnYYHGAhCkLDAAhgn+AAFiyACGAf4AAVLS6GtgAANu1GtgA
+YYVChQHh3BjAAGWF4BiAAEaF5BjAAOgYgADVAwAAz3CAALR/pQQgAIohBQXgePHATgsgAADaocFA
+wgAWjkAAFo1AABaDQAAWkECA5R3yqXfPcYAA1JwjiYYn/BdFv8O95nngucoiQgNgwuG5yiJCA8oi
+IQABHIIwUSGAgMolIRACHEIzgOAk9M9wgAC0f7aI9Iixc8wmwZMR8gohwA/rckArBAQQvgXYiiNd
+CwUkRAP1B+/+BSbFEwDFQCAOBs93gABYslQYWAOEH0ATIfDPcIAAZLUGkBBzCvTPd4AAWLLEFwAW
+wLgQdg3yCiHAD+tyBdiKI50NmHOtB+/+SiUAAADFz3aAAPyw3R9YE0AgQSBJIQEGNHn+DiAAyXBC
+IMAlSCAAAIDgANvL9wDaABYBQAHig+K99wHjEHO491YmABnWDiAABtnPcIAAsK8AgFEgQIAa8s9x
+gAC0f89wgABktQaQVokQcgf0xBcAFjSJwLgQcQryxRcAFlEgQIEG8gmHUSBAgQ70rg1gAMlwz3CA
+AJgPoqCKIBINXgggAKlxMg4AAD0CIAChwOB4ANhC8fHAocGLcGIOIAAB2QAUBTBMJQCAyiHBD8oi
+wQfKIGEByiOBDwAArgfMBuH+yiRhAM9wgADUnO4NIAADGEIBocDRwOB+8cCOCQAAz3OAAFQQQ4MA
+3891oAAsILCF0mrUfn5mpaYEpgHijCIIgCamQ6OF9wKD46MB4AKjwQEAAOB4ANjPcaAAyB8YoRmh
+AdgOoeB+4HjxwD4JIABZcTlyyHHocgHdz3agAMgfs6YF3891gADAD+ClAaUEwEilCaUVhielCqUY
+hhgdQBELpRmGFB0AEQyloBYAEGSlDaWkFgAQDB1AEg6lqBYAEAgdgBIPpc9wAQCwCRClSglgACjY
+EaVCCWAAANgSpVMnwHUTpQLIVB0AFxalEhYAllAdABcXpRMWAJbPcoAAwA8YpRQWAJZKJEB5GaUV
+FgCWANkapSQWAJYbpRYWAJYcpc9wgACQDBCAHaXPcIAAwA94GIAKz3CAAMAPfBjACs9wgAA8EAQY
+AAuEGkALz3CgAMgcCICIGgAAz3CAAIAFAICMGgAAqCCAAvAiQwDPcJ8AuP8B4XagmQAAAPwciLb8
+HEi2/BwItvwcyLX8HIi1/BxItfwcCLX8HMi0/ByItPwcSLT8HAi0/BzIs/wciLP8HEiz4H7geATc
+ON018OB4BNw03TPw4HgE3DDdMfDgeATcLN0v8OB4BNwo3S3w4HgE3CTdK/DgeATcIN0p8OB4BNwc
+3Sfw4HgE3BjdJfDgeATcFN0j8OB4BNwQ3SHw4HgE3AzdH/DgeATcCN0c8OB4BNwE3RnwNBQaMDAU
+GTAsFBgwKBQXMCQUFjAgFBUwHBQUMBgUEzAUFBIwEBQRMAwUEDACxwHGsCRNM7AkHzPgfvHAz3GA
+AJAMEKHgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjRwOB+
+4HjhxeHGQCkNAiV9QC0DFIjipXsIdZD3UyV+kAbyAR1SEGG6+/FBKo4AwbpCJk6QBB3QEP31gOIK
+8i8kiXDgeKgggAEBHVIQ4HjBxuB/wcXgeChyANnW8eB48cCuDs//ocEId892oACsLxmGBCCAD3AA
+AADXcCAAAAAB2MB4LyYH8Ch1GnIT9IogSQb2DO//iiFNBDmG6gzv/4ogCQaKIAkG3gzv/6lxANgk
+8BHMABxEM08gwQMB4BB4BCCADwAA/7+PuAIcRDARGhwwRgmgD0AnABIH5wQnjx8AAPz/BScAFJ24
+n7jscQChAMHscCCgAdh5Bu//ocDgeCK5BvDscmCiBOBhuYHhYIA69wDZz3CgANQLbaDPcKAARB01
+oOB+4HjxwO4Nz/8Idih1KHBIcWhyyv+B4MoggQPAD+H/yiFBAzkGz//hxc9ygACwBKSKgOXPcp8A
+uP8G8s9z0Lr+yn6iGqI7ooDlDvLPcKAAOC4FgAQggA/AAAAA13DAAAAA9vNp2Bi4GaLgf8HF4Hjx
+wH4Nz/8Id89xgACwBAWJAN6A4KnBQMZD9AHdpanPcYAAgHbPcKAAzCstoADYj7gRGhwwIRqCM34I
+IA2LcCoJAAjPcAEAsAlBwIogUABCwM9wgAD8YgCIZMUC3REcAjAAwBIcQjMTHAIwz3CAAFQQRcDP
+cIAAwA9GwM9wgACABQCAQ8Yg2QHaR8BIx4HAPdsXu8H/CNgB2cj/BBpYM0kF7/+pwAPaz3GgABQE
+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
+8cAAFgBBz3KAAARLBrIAFgVBQCIBBA4aRAFMJYCEyiHCD8oiwgfKIGIByiOCDwAAcwBEBaLvyiQi
+AADaB/AAFgBBFCGMAAC0AeIvIEIBEHK39lIMz/DRwOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
+4HjgfuB44H7geOB+4HjPcIAA6AfgfwCA4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
+4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwHY4H7geOB+4Hjg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB48cD+Do/w
+GnHPd4AAREsgj1EhAIBG8s9xgADwByCJgOHMICGgPvKB4Ab0z3CAALicoYAD8ADdjuUD94DlAvQA
+3c9xgAC4nBiJgOAE9IDlBPQA3gTwooEE3oogEwEaDa/wqXGKIFMBEg2v8Mlxz3CAABwPGIiD4Mwg
+IoHMIOKBzCAiggjyiiATAe4Mr/Cl2QrwCpcQdQj0C5cQdswgIaAE9ADYIfAB2M9xoADIHw2hz3CA
+APAHAYjLt6q3BL4QuMV9BX2KIBMBsgyv8LzZiiATAaYMr/Cpcc9woADIH38YWIMB2IEGj/DgePHA
+Gg6v8AhxxP+A4DzyIN3PdqAAyB+wpjLYQx4YEADY8gnv8I24saawph7YQx4YEADY4gnv8I24saZ/
+Fg+WiiATAUEvDRTEvUYMr/Dm2YogEwE+DK/w6XGKIBMBMgyv8Klxz3GAAPAHAYkB2hB1wiKKAIDl
+QKnI9gDYDaaB4gT0BNgBqf0Fj/Dhxc9ygABESyCKAN3guWTYyiBBA+G5z3OgAMAdBqIJ8gzYAKMB
+ggOiAoIEogTwoKOjoqSiz3CAABwPCYBRIECB0SGigATyAIOAuACj4H/BxfHA4cUA3c9woADAHaCg
+qXCpcYz/z3CAAERLo6CkoJ0Fr/CmoIDgz3GAAERLBPRAIQADBPBAIQAEAIDPcaAAwB1RIACAAIHP
+IOIA0CDhAACh4H7gePHA8gyv8APZz3aAAERLdgnv8MlwoI5EJUARheAM9AohwA/rcgXYadtKJEAA
+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
+QgITMAQowBEPFBUiAQAVJg9yEyIIAMwRD0QAIgoAAEAAQABwDgAAYQAAEyUCABMk7BzAEQ92EyIY
+CMoRCQATQBwIyhEJABNAIAjKEQ94EyIEAMoRAAABJAAAASUGAABhD3YTIixIxxEPeBMiAADGEQMA
+ASQAAAElAAATJcIsEyQEKMARAkYTJAQowBHCXxMkBCjAEQ9FACIAXAA5JwAAZAAAEyQBABMlOBzA
+EQ93EyLgHMARDwETIgQIwBEPAhMiBCjAEQ8HEyIEKMARDwQTIgQowBECAHFwBwAAYf8AEyUCEBMk
+BCjAEQAAEyUAABMkyEnHEQYAAGEAABMlAhATJAQowBEAABMlSQATJMhJxxEPcBMiAQATMAQowBED
+ABMkAAATJQQIwBEAABMkOEXAEQ8DEyIYKMARBAAAYQAAWDgAABMkAQATJTgcwBEAAAAhnGuAgQAA
+wBY8BMARMAWAgQAAwBYEARtiEATAEAMAGyRUBMARJATAEQgEwBBca4CBAADAFwgEwBA4a4CBAADA
+FwAAGyUDHBtiQAAbJDAcwBEFAABhNAWAgQAAwBYPGxkiCASggTjwxIAAABskAgAbJTgcwBEAAAAh
+MAWAgQAAwBZMBMARNAWAgQAAwBYPGxkiSASggTjwxIAAABskAgAbJTgcwBEAAAAhAAAAhTAFgIEA
+AMAWDxsEIhAEG2YPARtoFBzAEAoAG0AEABtuAwAAYQ8cHSIBAB0m+Q8AYWQMABAAwAYRAQAEJ/wA
+BGQAABskAgAbJTgcwBEAAAAhAAAbJUAAGyQwHMARAAAAIQ8cHSIYAR0mGADHEPySgIEAAMAXIADH
+EASTgIEAAMAXAAAAIXwxgIECAFxuEQAAYfhBxBAPGwkiAAsJOQIACmIDAQpiBAIKYgAACUAEAABh
+CQAJQAIAAGEKAAlAAAAAYQIACUEACRooAADAFgEAGyYAAMAXBAAdJgEACCfpAAhkAAAAIQAAAACM
+AQAAAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsOQAAODsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAABSEgAAAAAAAAAAAAAAAAAABAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+wACQANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAADIkoAAAAAAAAAAAABAl4AA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAsAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAiJyAACycAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMisgACY9gEAAAAA
+AAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIkoAAhP8BAAAAAADIkoAA
+UAYCAAAAAAAAAAAAyJKAAOgHAgAAAAAAAAAAAAAAAADIkoAAAAAAAAAAAAAAAAAA/wAAAAAHAAAA
+AAAAAAAAABgbAgAYGwIAGBsCABwbAgAAAAAAHQAAAAAAAAAAAAAAAAAAAAAAAAB/fwABAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAQIECAAIECAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADECAAAFQAAANQtgAA4KwAAOCsAADgrAAAMQgAA
+OCsAADgrAABYPQAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAArB4AAFwgAAB0
+IAAA5CEAAGwiAADoIQAAOCsAADgrAACATgAASFAAADRRAAA4KwAAOCsAADgrAAD8TAAAFGQAABBk
+AABoZAAAOCsAADgrAAA4KwAAGEQAADgrAABMZAAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsA
+ADgrAAAQQgAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAA
+OCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAAIRQAAOCsAADgrAAA4
+KwAAOCsAADgrAADwRQAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgr
+AABQawAAOCsAAHhsAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAACBvAAA4KwAAOCsA
+ADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAAMyAAQAkhAEAOCsAAHiGAQA4KwAA
+KIgBABRUAQA4KwAAOCsAAABSAAA4KwAAOCsAADgrAAA4KwAAOCsAADzeAQDE8QEAOCsAADgrAAA4
+KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAACsGAIAOCsAADgrAAA4KwAA2P0BADgr
+AADUAQIAOCsAAPwpAgA4KwAAoCUAAKQlAAA4KwAAOCsAAIgSAgBMcgAAOCsAADgrAAA4KwAAfPsB
+ADgrAAA4KwAAWE0BAAygAQA4KwAAOCsAADgrAAD8qAEANFUBADgrAAA4KwAAOCsAADgrAAA4KwAA
+OCsAALSzAQA4KwAAgA8CAIQPAgCQDwIAlA8CAIgPAgCMDwIAmA8CADgrAAA4KwAAOCsAADgrAAA4
+KwAAOCsAADgrAAA4KwAAOCsAAPBTAAA4KwAAOCsAADgrAAA4KwAAOCsAANQOAgAkDwIAEEgAADgr
+AAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsA
+ADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAA
+OCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAACQSQAAGEoAAKxKAABgSwAAJIEAADhLAAA4
+KwAAOCsAADgrAAA4KwAAOCsAAIhJAACMSQAAOCsAADgrAAAwUgAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwM
+AACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwA
+AIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAAC8DQAAAAAAALxaAQCMDAAAnAkAAIwMAACMDAAA
+jAwAAMwJAADoPAEAZIMAAIwMAACMDAAABAoAAAQKAAAECgAABAoAAAQKAAAECgAABAoAAIwMAACM
+DAAAjAwAAIwMAAD8CwAAjAwAAIwMAACMDAAAjAwAAIwMAADADQAAjAwAAIwMAACACQAAAwAAAJwM
+AgACAAAA6GgBAAQAAACcaQEABQAAANwNAAAGAAAAIDQAAAgAAAAADwIAEwAAACz4AQAJAAAAgAMC
+AAoAAACcDwIADgAAABSdAQAPAAAAYIoBABAAAACYigEAGAAAACRaAQANAAAAEIIBABcAAABIcgAA
+EQAAAKSBAAASAAAAWEwBAAEAAABY/QEAFAAAAMCwAQAVAAAAQKABAAcAAACQbwAAFgAAAOwpAgAZ
+AAAAvA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAABAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAABAQAAAAAA
+ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e
+4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7hPDw8PDw8PDw8PDw8PDw8PDw8PDw8
+PDw8PDw8PDw8PDwVFRUVPDw8PBUVFRU8PDw8AAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8
+PDw8PDw8PDw8PDw8PDw8PDw8FRUVFTw8PDwVFRUVPDw8PAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8
+PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8PDw8FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAA
+kAYAADH6rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6rwCQ
+BgAAMfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAEMF
+AAAx+q8AQwUAADH6rwAAAAAA3sMJAAAAAAAAAAAAAAAAALQqAQABAAAAlC2AAAAAAAAAAAAAAAAA
+AFQrAQAVAAAA1C2AAAAAAAAAAAAAAgAAAAMAAAAAAAAACAAAAAAAAAAwjBEAIL8CAAAAAADIKwEA
+cCwBAHQtAQAgLwEAdC0BACAvAQDQMAEAWDEBALgxAQCAgICAgICAgAGAAoCAgICAAAAAALg3AQC4
+NwEAAAAAAAAAAAAAAAAAAAAAALg3AQC4NwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJQt
+gACULYAApCCgADggoAABAAAA/P///wAAAAAAAAAAtC2AALQtgACoIKAAPCCgAAgAAADz////AAAA
+AAAAAADULYAA1C2AAKwgoABsIKAAMAAAAM////8AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA
+AAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAbE0BAAUAAADULYAAwFIBAAD/AwDgUgEAAP8FAMxTAQAA
+/y0A8FMBAAD/PQCoUwEAAP8EAIxTAQAA/yUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAABgWQEABgAAAJQtgAAAAAAALAEAAF4BAAABAAAAAQAAAAEAAAABAAAAAwAAAAAAAAAAAAAA
+vGABALxhAQA4YgEAQF0BAGhcAQBoYwEA8GMBADRkAQCIZAEAAAAAAAMAAAACAAAAAwAAAAMAAAAD
+AAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAbGoBAAoAAACULYAAAAAAAAAAAAAAAAAA+GoBAAoA
+AACULYAAAAAAAAAAAAAAAAAArGsBAAoAAACULYAAAAAAAAAAAAAAAAAAzGwBAAoAAACULYAAAAAA
+AAAAAAAAAAAAMGsBAAoAAACULYAAAAAAAAAAAAAAAAAARGwBAAoAAACULYAAAAAAABAAAAAAgAAA
+AACgABAnAADoAwAA6AMAAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAK
+AAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAA
+AAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAA
+APg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAA
+lC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAA
+AAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAASGAQAKAAAAlC2AAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4jQEAhI4BAHCRAQAklAEApJYBACiaAQA0kAEARAWAAJCS
+gAAYAAAAUJKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvJwBAAYAAACULYAA/////wAAAAD/////////
+/wAAAAAAAAAAAAAAAJyfAQAFAAAA1C2AAG4AbgBpAMAAoABQAIAAvgBQAX0APgBuAG4AaQDAAKAA
+UACAAL4AUAF9AD4AAAAAAAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIBAQACAQABAgICAAEB
+AAIBAgECAAIAAQID//8AALkB3wCxABsAFgEbAHwBGwCvABsAFAEbAHoBGwBsAKAA0QCgADcBoABv
+AIMAcQCDAHYAgwBzADMAbgAzAHAAMwByADMA1wAzAD0BMwDUAQYA0AEAAH4APADjADwASQE8AHgA
+SQDdAEkAQwFJAH8AWgDkAFoASgFaAKoAPwCrAAEADwE/ABABAQB1AT8AdgEBAHkAagDeAGoARAFq
+AKgAAAANAQAAcwEAAKYANwCnAAEACwE3AAwBAQBxATcAcgEBAAQACACcAcwAnQHMAJ4BzACfAcwA
+1QHMANYBzADXAcwAtABHABkBRwCAAUcAkAAiAPUAIgBbASIAoQCIAAYBiABsAYgAlAAAAJUAAACY
+AMAAmQCgAJYAkACXAAAAlAABAJUAAQCYAMAAmQCgAJYAkACXAAAAlAACAJUAAwCYAMAAmQCgAJYA
+kACXAAAAlAADAJUABwCYAMAAmQCgAJYAkACXAAAA+gAAAPkAAAACAZAAAwHTAAABgwD+ABMA/AAz
+AP0AdwD6AAEA+QABAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoAAgD5AAMAAgGQAAMB0wAAAYMA
+/gATAPwAMwD9AHcA+gADAPkABwACAZIAAwHTAAABgwD+ABMA/AAzAP0AdwBfAQAAYQEAAGgBkABp
+AdMAZgGDAGQBEwBiATMAYwF3AF8BAQBhAQEAaAGQAGkB0wBmAYMAZAETAGIBMwBjAXcAXwECAGEB
+AwBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwBfAQMAYQEHAGgBkABpAdMAZgGDAGQBEwBiATMAYwF3
+AIUAAACGAAAAhwBQAIgAAACJAKAAigAAAIsA0ACMAAAAhQABAIYAAQCHAFAAiAAAAIkAoACKAAAA
+iwDQAIwAAACFAAIAhgADAIcAUACIAAAAiQCgAIoAAACLANAAjAAAAIUAAwCGAAcAhwBQAIgAAACJ
+AKAAigAAAIsA0ACMAAAA6wAAAOoAAADsAFAA7QAAAO4AoADvAAAA8ADQAPEAAADrAAEA6gABAOwA
+UADtAAAA7gCgAO8AAADwANAA8QAAAOsAAgDqAAMA7ABQAO0AAADuAKAA7wAAAPAA0ADxAAAA6wAD
+AOoABwDsAFAA7QAAAO4AoADvAAAA8ADQAPEAAABRAQAAUAEAAFIBUABTAQAAVAGgAFUBAABWAdAA
+VwEAAFEBAQBQAQEAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQECAFABAwBSAVAAUwEAAFQBoABV
+AQAAVgHQAFcBAABRAQMAUAEHAFIBUABTAQAAVAGgAFUBAABWAdAAVwEAAPv/AAD//wAAuQHfALEA
+GwAWARsAfAEbAK8AGwAUARsAegEbAGwAoADRAKAANwGgAG8AgwBxAIMAdgCDAHMAMwBuADMAcAAz
+AHIAMwDXADMAPQEzANQBBgDQAQAAfgA8AOMAPABJATwAeABJAN0ASQBDAUkAfwBaAOQAWgBKAVoA
+qgA/AKsAAQAPAT8AEAEBAHUBPwB2AQEAeQBqAN4AagBEAWoAqAAAAA0BAABzAQAApgA3AKcAAQAL
+ATcADAEBAHEBNwByAQEABAAIAJwBzACdAcwAngHMAJ8BiADVAcwA1gHMANcBzAC0AEcAGQFHAIAB
+RwCQACIA9QAiAFsBIgChAIgABgGIAGwBiAD6AAAA+QAAAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3
+APoAAQD5AAEAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gACAPkAAwACAZcAAwHQAAABjQD+ABEA
+/AAzAP0AdwD6AAMA+QAHAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3AF8BAABhAQAAaAGXAGkB0ABm
+AY0AZAERAGIBMwBjAXcAXwEBAGEBAQBoAZcAaQHQAGYBjQBkAREAYgEzAGMBdwBfAQIAYQEDAGgB
+lwBpAdAAZgGNAGQBEQBiATMAYwF3AF8BAwBhAQcAaAGXAGkB0ABmAY0AZAERAGIBMwBjAXcA6wAA
+AOoAAADsAFUA7QAAAO4AqgDvAAAA8ADdAPEAAADrAAEA6gABAOwAVQDtAAAA7gCqAO8AAADwAN0A
+8QAAAOsAAgDqAAMA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAA6wADAOoABwDsAFUA7QAAAO4AqgDv
+AAAA8ADdAPEAAABRAQAAUAEAAFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAFEBAQBQAQEAUgFVAFMB
+AABUAaoAVQEAAFYB3QBXAQAAUQECAFABAwBSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAABRAQMAUAEH
+AFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAPv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAcswEAINQBAPScgABABQAAAAAAAByzAQBItAEANKKAAPgBAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAD42AEA/NYBACykgABUAAAAAAAAAByzAQAs1wEArKSAAFABAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAEAAAAcswEAQNMBAEA/gABQAQAAAAAAAByzAQBY1QEA8AaAAAIAAAAAAAAA
+HLMBALDVAQD0BoAABAAAAAAAAAD02AEASLQBAICkgAAqAAAAAAAAAByzAQBM1gEAAAAAAAAAAAAA
+AAAAHLMBAAzWAQD4BoAABAAAAAAAAAAAAAAAAAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkA
+CgAKAAsADAAMAA0ADgAOAA8AJgAnACgAKAApACoARgBGAEcASABIAEkASgBKAEsATABoAGkAagBq
+AGsAbABsAG0AbgBuAG8AcABwAHEAcgByAHMAdAB0AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUA
+dQB1AHUAdQB1AHUADwA/AAAAAAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAIAAgACQAK
+AAoACwAkACQAJQAmACYAJwBEAEQARQBGAEYARwBIAEgASQBKAEoASwBMAEwATQBqAGoAawBsAGwA
+bQBuAG4AbwBwAHAAcQByAHIAcwB0AHQAdQB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2
+AHYAdgB2AHYADgA/AESmAQAS0gAAAAAAAP//DwBwwgEAtgAAAAAAAAD/AAAAcMIBALcAAAAAAAAA
+/wAAAHDCAQC4AAAAAAAAAP8AAABwwgEAuQAAAAAAAAD/AAAAcMIBALoAAAAAAAAA/wAAAHDCAQC7
+AAAAAAAAAP8AAABwwgEAvQAAAAAAAAD/AAAAcMIBAL4AAAAAAAAA/wAAAHDCAQC/AAAAAAAAAP8A
+AABwwgEAwAAAAAAAAAD/AAAAcMIBAMEAAAAAAAAA/wAAAHDCAQDCAAAAAAAAAP8AAABEpgEAE9IA
+AAAAAAD//w8AcMIBABsBAAAAAAAA/wAAAHDCAQAcAQAAAAAAAP8AAABwwgEAHQEAAAAAAAD/AAAA
+cMIBAB4BAAAAAAAA/wAAAHDCAQAfAQAAAAAAAP8AAABwwgEAIAEAAAAAAAD/AAAAcMIBACIBAAAA
+AAAA/wAAAHDCAQAjAQAAAAAAAP8AAABwwgEAJAEAAAAAAAD/AAAAcMIBACUBAAAAAAAA/wAAAHDC
+AQAmAQAAAAAAAP8AAABwwgEAJwEAAAAAAAD/AAAARKYBABTSAAAAAAAA//8PAHDCAQCCAQAAAAAA
+AP8AAABwwgEAgwEAAAAAAAD/AAAAcMIBAIQBAAAAAAAA/wAAAHDCAQCFAQAAAAAAAP8AAABwwgEA
+hgEAAAAAAAD/AAAAcMIBAIcBAAAAAAAA/wAAAHDCAQCJAQAAAAAAAP8AAABwwgEAigEAAAAAAAD/
+AAAAcMIBAIsBAAAAAAAA/wAAAHDCAQCMAQAAAAAAAP8AAABwwgEAjQEAAAAAAAD/AAAAcMIBAI4B
+AAAAAAAA/wAAAESmAQAI0gAAAAAAAP//AwCEpgEAAIIAAAAAAAD/AQAAhKYBAAGCAAAAAAAA/wEA
+AESmAQAJ0gAAAAAAAP//AwCEpgEAAoIAAAAAAAD/AQAAhKYBAAOCAAAAAAAA/wEAAESmAQAK0gAA
+AAAAAP//AwCEpgEABIIAAAAAAAD/AQAAhKYBAAWCAAAAAAAA/wEAAESmAQAG0gAAAAAAAP8BAABE
+pgEAB9IAAAAAAAD/AwAARKYBAAbSAAAJAAAAAP4DAESmAQAH0gAACgAAAAD8DwBEpgEABtIAABIA
+AAAAAPwHRKYBAAfSAAAUAAAAAADwP0SmAQAV0gAAAAAAAP8DAABEpgEADNIAAAAAAAD/AQAARKYB
+ABXSAAAKAAAAAPwPAESmAQAM0gAACQAAAAD+AwBEpgEAFdIAABQAAAAAAPA/RKYBAAzSAAASAAAA
+AAD8BzCAAACqqqqqMYAAAKqqqqoygAAAAKqqqjOAAAAAAAAANIAAAAAAAAA1gAAAAAAAADaAAAAA
+AAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAAAAAAA7gAAAAAAAADyAAAAAAAAAPYAAAKqq
+CgA+gAAAqqqqqj+AAACqqqqqQIAAAAAAAAAwgAAAqqqqqjGAAACqqqqqMoAAAACqqqozgAAAAAAA
+ADSAAAAAAAAANYAAAAAAAAA2gAAAAAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAAADqAAAAAAAAA
+O4AAAAAAAAA8gAAAAAAAAD2AAACqqgoAPoAAAKqqqqo/gAAAqqqqqkCAAAAAAAAAMIAAAAAAAAAx
+gAAAAAAAADKAAAAAAAAAM4AAAAAAAAA0gAAAqqqqqjWAAACqqqqqNoAAAAAAAAA3gAAAAAAAADiA
+AAAAAAAAOYAAAAAAAAA6gAAAqqqqCjuAAACqqqqqPIAAAAAAAAA9gAAAAAAAAD6AAAAAAAAAP4AA
+AAAAAABAgAAAAAAAADCAAAAAAAAAMYAAAAAAAAAygAAAAAAAADOAAAAAAAAANIAAAKqqqqo1gAAA
+qqqqqjaAAAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAKqqqgo7gAAAqqqqqjyAAAAA
+AAAAPYAAAAAAAAA+gAAAAAAAAD+AAAAAAAAAQIAAAAAAAABEBYAAkJKAABgAAABQkoAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAsPMBAAYAAACULYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAABEBYAAkJKAABgAAABQkoAAAAAAAAAAAAAAAAAAAAAAAAAAAABU
+/wEABgAAAJQtgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAEQFgACQkoAAGAAAAFCSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2A
+AAAAAAAAAAAAAAAAAHAKAgAEAAAAlC2AAAAAAAAAAAAAAAAAAGgMAgAGAAAAlC2AAAAAAAAAAAAA
+AAAAAHAKAgAEAAAAlC2AAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAHAKAgAE
+AAAAlC2AAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAHAKAgAEAAAAlC2AAAAA
+AAAAAAAAAAAAAGgMAgAGAAAAlC2AAAAAAAAAAAAAAAAAAHAKAgAEAAAAlC2AAAAAAAAAAAAAAAAA
+AKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAGgMAgAGAAAAlC2AAAAAAAAAAAAAAAAAAKALAgAEAAAA
+lC2AAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAGgMAgAGAAAAlC2AAEQFgACQ
+koAAGAAAAFCSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAFAUAAAAAAAAAAAAAAAAAAAAAAP8A/wAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECAwQEBAQEBQYH
+CAgICAgJCgsMDQAAAAUGBwgNDg8QFRYXGBkAAAoNERQKDREUGRkZGQoKAAAAAAAABgYGBgkJCQkA
+BgAAbjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bitoK2IrXCtuKmgqYipcKm4paCliKVwpbhtoG2Ib
+XBtuGmgaYhpcGm4ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24WaBZiFlwWbhVoFWIVXBVuFGgUYhRc
+FG4TaBNiE1wTbhJoEmISXBJuEWgRYhFcEW4QaBBiEFwQVxBSEE0QSRBuAWgBYgFcAW4AaABiAFwA
+bjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbihoKGIoXChu
+J2gnYidcJ24ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24JaAliCVwJbghoCGIIXAhuB2gHYgdcB24G
+aAZiBlwGbgVoBWIFXAVuBGgEYgRcBG4DaANiA1wDbgJoAmICXAJuAWgBYgFcAW4AaABiAFwAAAAA
+AAAAAAAAAAAALCwCAAgAAADULYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAA/////////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/////////////////////////////
+/////////////////////////////////////////////////wEEAAACBQEAAwYCAAQHAwAFCAQA
+BgkFAAcKBgAICwcACQwIAAoNCQALDgoADA8LAA0QDAAOEQ0AAUAABAJBAQQDQgIEBEMDBAVEBAQG
+RQUEB0YGBAhHBwQJSAgEtxMiALgUIwC5FSQAuxYlALwXJgC9GCcAwBkoAMQaKQAHGwAACBwBAAsd
+AgAMHgMAEB8EACIhBQAkIgYAJiMHACgkCAAqJQkALCYKAC4nCwAwKAwANCkNADgqDgA8Kw8AQCwQ
+AGQuEQBoLxIAbDATAHAxFAB0MhUAeDMWAHw0FwCANRgAhDYZAIg3GgCMOBsAkTocAJU7HQCZPB4A
+nT0fAKE+IAClPyEAJEkGAixKCgI0Sw0BPEwPAWRNEQFsThMBdE8VAXxQFwGEURkBlVIdAZ1THwEA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQYCBgYGAwYGBgYGBgYEAAAAAAPAD8AAQAA
+AA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAgAAAA8APwABAAAA
+AAAAAAEAAAACAAAAAwAAAAAAAAAEAAAAAgAAAAUAAAAPFBkeKAoFALAJAaUAPDg0MCwoJCAcGBQQ
+DAgEAAwIBAA8ODQwLCgkIBwYFBAMCAQCCAAOAAAADgEBAAECAQEBAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClxoT4me6N9g3/vdax3lSRUGADAqnOfVYZ52K1
+5k2a7EWPnR9AiYf6Fe/rssmOC/vsQWez/V/qRb8j91OW5FubwnUc4a49akxabEF+AvVPg1xo9FE0
+0Qj5k+Jzq1NiPyoMCFKVZUZenSgwoTcPCrUvCQ42JJsbPd8mzWlOzX+f6hsSnh10WC40LTay3O60
++1v2pE12YbfOfXtSPt1xXpcT9aZouQAALMFgQB/jyHnttr7URo3ZZ0ty3pTUmOiwSoVruyrF5U8W
+7cWG15pVZpQRz4oQ6QYEgf7woER4uiXjS/Oi/l3AgIoFrT+8IUhwBPHfY8F3da9jQjAgGuUO/W2/
+TIEUGDUmL8PhvqI1zIg5LleT8lWC/Ed6rMjnuisyleagwJgZ0Z5/o2ZEflSrO4MLyowpx9NrPCh5
+p+K8HRZ2rTvbVmROdB4U25IKDGxI5Lhdn26970OmxKg5pDE304vyMtVDi1lut9qMAWSx0pzgSbTY
++qwH8yXPr8qO9OlHGBDVb4jwb0pyXCQ48VfHc1GXI8t8oZzoIT7dltxhhg2FD5DgQnzEcarM2JAF
+BgH3Ehyjwl9q+a7QaZEXWJknOrknONkT67MrMyK70nCpiQenM7YtIjySFSDJSYf/qnhQeqWPA/hZ
+gAkXGtplMdfGhLjQw4KwKXdaER7Le/yo1m06LAEBAQEBAQEBAgICAgICAgIDAwMDAwMDAwQEBAQE
+BAQEAQICAgICAgMDAwMDAwMDAwMDAwMDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAEBAgEC
+AgN//wcPHz8BAwEDDwcBBw8fP3///wUABwIDBAYGdNFFF+iiiy4NDwUHCQsBAwoUN25VVVUBS2gv
+AVVVVQXjOI4DqqqqAnEcxwGqqqoKx3EcBw8PDwcGBwIDBAUAAQgJCwooACgAMAAsACwAKAA8ADQA
+KAAoADQAMAAsACwARAA8AEAAPACMAGwAWABIAPQAsAAsACwAPAA0ADAALABUAEQAVABUAGwAYABc
+AFQAjAB4ADoBAgHVAN8A2gCiAHUAfwBqARoB2QDoAAoBugB5AIgAigUqAzkBqAGKBcoC2QBIAcoB
+SgHiAPkAygHqAIIAmQD0AkQCtQHVAZQChAH1AEECrACQAIQAgAB4AHgAeAB0AGbmAACd2ImdTuzE
+TjRIgzQndmInGqRBGhM7sRMRGIERD/zAD07sxE4ndmInGqRBGhM7sRMN0iANiZ3YCQiMwAgHfuAH
+NEiDNBqkQRoRGIERDdIgDQiMwAgGaZAGsLLVBQVUQAUndmInEzuxEw3SIA2JndgJBmmQBsRO7AQE
+RmAEAz/wA6qqqqoapEEaEzuxEw/8wA8RGIERDdIgDQqogAoTO7ETD/zADw/8wA8N0iANC7RACwu0
+QAuJndgJDdIgDQqogAoKqIAKCIzACAd4gAcHeIAHBmmQBg/8wA8N0iANC7RACw3SIA0LtEALiZ3Y
+CQiMwAiJndgJCIzACAd+4AcHfuAHwSwpBwqogAoIjMAIB3iABwiMwAgHeIAHBmmQBrCy1QUGaZAG
+sLLVBQVUQAUFVEAF1h3GBEADgAbACQANgBMAGkAdgCCABgANgBMAGgAnADSAOgBBwAmAE0AdACeA
+OgBOwFeAYZkDMwfZCnMOphXmHIAgGSQzB3MOphXmHFkrzDkAQTNI2QqmFYAgWSsAQaZWgGFZbDAA
+AAA2AAAADAAAABIAAAAYAAAAJAAAAAYAAAAJAAAAAAAAAAAAAAAYIBQUDg4UFAUGAQIDBAAAAAEB
+AgECAgMEDAwIBAwEBEAAAACAAAAAAAEAAAACAABAAAAAAAQAAEAAAABAAAAAEBESExQVFhcYGRob
+HB0eHyAhIiMkJSYnKCkqKywtLi9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNk
+ZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/MxMAAAAHBw8HDw8XLQAPIADwYQAAAAAAAAAAAAAB
+AgQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAADA5OjUyOjE5AAAAAE8usABqsKKwkrBjAAGtrXsArZOcra1gAAkAAAACAAAAAAAA
+AAAAAAAJAAAAAgAAAAAAAAAAAAAACQAAAAMAAAABAAAACQAAAAkAAAACAAAAAgAAAAkAAAABAgEC
+AwQAAAUGBwgJCgAAAAUGAAIEAAUAAAAAAAUHAQMEAAUBAAAAQCNAJSEhISFAQEBAQAUEBAEBQEBA
+QAUFQEAMDEANDAwBAQEFQEAFBQAEAARAQAAEQEBABUBAQEBABUBAQAUFBQEBAQFABQUFAQUBAUAF
+BQVABUAFBQUFBQQAAAAcEQAAHDIAABwzAAAEAAAAHBUAAAIAFwBsAHAEdAh0DAAEBAYAAAAAAAAA
+AGQAAAAAkAEACgAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAQAAABAAAAAAAAAA
+AQAAAAEAAAAAAAAA/wAAAP8AAAAAAAAAAAAAALx8AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAEAAAAFAAAAAAQAAGQAAABQgwEAWIMBAGCDAQC4gwEAwIMBAMiDAQAHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcGBgYGBgUF
+BQUFBAQEBAQDAwMDAwICAgICAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAolQ8BOfJgABxctYDQAAAAEDgkdLTcAAAQOCR0sOwABEAAB
+AAAAAoAAAUIGAhAAAiAAAAPAAAFDBgMQAALAAAADwAABQwYEEAACQAAAAoAAAUQGBREAAEAAAAPA
+AAFFBgYRAADgAAADwAABRQYHEQABAAAAAoAAAUYGCBEAAiAAAAPAAAFHBgkRAALAAAADwAABRwYK
+EQACQAAAAoAAAUgGCxIAAEAAAAPAAAFJBgwSAADgAAADwAABSQYNEgABAAAAAoAAAUoGDhIAAgAA
+AAKAAAFMBgAAIhYAAIAAAAMAAAFZACQWAAEAAAADAAABWgAmFgACAAAABAAAAVoAKBYAAgAAAAMA
+AAFbACoWAAKAAAADAAABXAAsFwAAAAAABAAAAVwALhcAAIAAAAMAAAFdADAXAAEAAAADAAABXgA0
+FwACAAAAAwAAAV8ANhcAAoAAAAMAAAFgADgYAAAAAAAEAAABYAA8GAABAAAAAwAAAWIAPhgAAgAA
+AAQAAAFiAEAYAAIAAAADAAABYwBkGwACAAAAAwAAAW8BZhsAAoAAAAMAAAFwAWgcAAAAAAAEAAAB
+cAFsHAABAAAAAwAAAXIBbhwAAgAAAAQAAAFyAXAcAAIAAAADAAABcwJ0HQAAAAAABAAAAXQCdh0A
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIIAPAABAAGkgAABpIEAAaSAAAGkgQAAgIIAPAADo
+AGkgAABpIEAAaSAAAGkgQAAgIIAPAABkBmkgAABpIEAAaSAAAEogAABKIQAASiIAAEojAABKJAAA
+SiUAAEomAABKJwAASiAAEEohABBKIgAQSiMAEEokABBKJQAQSiYAEEonABBKIAAgSiEAIEoiACBK
+IwAgSiQAIEolACBKJgAgSicAIEogADBKIQAwCiSAP4EAAEBBLJwwQCycMEIkHDQKIoA/gAA4cwoj
+ADfmDwAASiYAcGkgQABKJgBwSiYAcEomAHBKJgBwABYAcIAAZARAeCAgQIcAAAAAAAAAAAAA4cDh
+weHCz3CgAMgfFhABhs9ygACYhyCiEhABhiGiExABhiKiFBABhiOiFRABhiSiJBABhiaiz3GfALj/
+VqGKIf8PEhhYgBMYWIAUGFiAFRhYgCQYWIDBwsHBwcAgIECHDMjPcqAAyB8OGhiADcgPGhiADsgQ
+GhiADxIBNgHIJHgRGhiAEMgtGhiA4H7hxPwcyL78HEi+4cDhweHC4cP8HAix/BxIsfwciLH8HMix
+/BwIsvwcSLL8HIiy/BzIsvwcCL9qJIAQ4cRqJMAQ4cTxwM9woADQGxSAz3GAAGAEBCCAj89RBOEA
+oQryLykBAM9wgAA0D/AgQABAeNr/0cDBxGskwBDBxGskgBDBxJ90BBQLNAQUCjQEFAk0BBQINAQU
+BzQEFAY0BBQFNAQUBDTBw8HCwcHBwMHERSx+EAomQH7BxGskgBTBxCAgQIcMyIe4DBoYMA3Im7gN
+GhgwDsgOGhgwD8iHuA8aGDAQyBAaGDDgfuB48cAMyJW4DBoYMA3Im7gNGhgwD8iKuI24kLgPGhgw
+z3CAAGwQGIgbCFEAD8jPcQAAiAysuA8aGDA+DiAAD9hn2IYKIAGKIQYK0cDgfvHAz3CAALy1AICG
+IP6BCfQPyAUggA8AAADUDxoYMKH/iiBVBVYKIAGKIUYO6PHgeM9xAwBADc9woACoIC2gz3GAAIwE
+QIEBagChz3CgADguBYAEIIAPwAAAAB0IgA/AAAAASNjPcZ8AuP8aoVuhadgYuBmhz3CAAMgJJYAj
+gSCBx3EAAIgT5QLACeB4z3CAAMgJeQLACeB48cBuCwABz3eAAGAEiHUG6A0IUQAB2APwANgLrwXp
+DwlRAAHYAvAA2AqvBuoNClEAAdgD8ADYDK8A2M92oADIHxgeGJALj4ohEAAO6AiPDOjPcAMAQA1F
+HhgQMKYC2BgeGJAD8DGmCo8Y6AmPFujPcAIApkEgHhiQz3CAACgAIR4YkM9wgABcBCIeGJAYFgCW
+RSAAAxgeGJAMjwjoGBYAloUgAQQYHhiQDwtRABgWAJaIuBgeGJDPcIAAMHwAkI7gzCCiggb0GBYA
+loC4GB4YkBjtANiUuM91gACABAClcdgGuMYMIAH82SCFz3AAAEwctgwgAZ+5GBYAloW4GB4YkNUC
+AAHPcaqqu7vPcJ8AuP82oDagNqA2oM9xoADIOw6BiLgOoWkgQAD+8eB48cClwUHAQsEMHAAxEBxA
+Mc9xgAB8dDQZwA8wGQAPLBnADigZgA4kGUAOz3CAAHx0IBhAC89wgAB8dBwYAAvPcIAAfHQYGMAK
+z3CAAHx0FBiACs9wgAB8dBAYwAjPcIAAfHQMGIAIz3CAAHx0CBhACM9xgAAAdIAZAAh8GcAHeBmA
+B3QZQAdwGQAHbBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARAGQAE
+76HOoa2hjKEsGcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC1BkA
+AGoggALQGQAAaiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0GQAA
+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
+GYYUHQARDKWgFgAQZKUNpaQWABAMHUASDqWoFgAQCB2AEg+lz3ABALAJEKUuCWAAKNgRpSYJYAAA
+2BKlUyfAdROlAshUHQAXFqUSFgCWUB0AFxelExYAls9ygAAQERilFBYAlkokQHkZpRUWAJYA2Rql
+JBYAlhulFhYAlhylz3CAAOANEIAdpc9wgAAQEXgYgArPcIAAEBF8GMAKz3CAAIwRBBgAC4QaQAvP
+cKAAyBwIgIgaAADPcIAAgAUAgIwaAACoIIAC8CJDAM9wnwC4/wHhdqCZAAAA/ByItvwcSLb8HAi2
+/BzItfwciLX8HEi1/BwItfwcyLT8HIi0/BxItPwcCLT8HMiz/ByIs/wcSLPgfuB4BNw43TXw4HgE
+3DTdM/DgeATcMN0x8OB4BNws3S/w4HgE3CjdLfDgeATcJN0r8OB4BNwg3Snw4HgE3BzdJ/DgeATc
+GN0l8OB4BNwU3SPw4HgE3BDdIfDgeATcDN0f8OB4BNwI3Rzw4HgE3ATdGfA0FBowMBQZMCwUGDAo
+FBcwJBQWMCAUFTAcFBQwGBQTMBQUEjAQFBEwDBQQMALHAcawJE0zsCQfM+B+8cDPcYAA4A0QoeB4
+4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeNHA4H7geOHF4cZA
+KQ0CJX1ALQMUpXslCjQCCHVTJX6QBvIBHVIQYbr78UEqjgDBukImTpAEHdAQ/fUJ6i8kiXDgeKgg
+QAEBHVIQ4HjBxuB/wcUocgDZ2PHgePHAsg7P/6HBCHfPdqAArC8ZhgQggA9wAAAA13AgAAAAAdjA
+eC8mB/AodRpyE/SKIEkG+gzv/4ohTQQ5hu4M7/+KIAkGiiAJBuIM7/+pcQDYJPARzAAcRDNPIMED
+AeAQeAQggA8AAP+/j7gCHEQwERocMN4JoA9AJwASB+cEJ48fAAD8/wUnABSduJ+47HEAoQDB7HAg
+oAHYfQbv/6HA4HgiuQbw7HJgogTgYbn5CbWAYIAA2c9woADUC22gz3CgAEQdNaDgfuB48cDyDc//
+CHYodShwSHFocsr/geDKIIEDwA/h/8ohQQM9Bs//4cXPcoAAsASkis9ynwC4/wXtz3PQuv7KfqIa
+ojuiDu3PcKAAOC4FgAQggA/AAAAA8QiAj8AAAABp2Bi4GaLgf8HF4HjxwIYNz/8Id89xgACwBAWJ
+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
+HgLPcIAAAGAyIEACDwiSAM9wpgDo/w2AA/AA2AamBaYA2EokgHAG2o26qCBAAynbErvwI48AQCYD
+HxV7AeLgowHgAJE4HgARVSZBFBq2z3CAAGCXBgyv/gjaGxUAls9xpQDYyxmmHBUAlhqmHRUAlhum
+DoEcpg+BHaYmFQCWHqbPcKQAkH8cgAUHb/4fpuB48cCGDm/+ANvPcaAAyB9AEQAGz3egANAPGRcA
+ls9yoADEJ08SDoa4gc9wgAD4tKigEczPdYAAFJELDgAQH4ULCJ4AAd4E8BEanDNodlISEIYVEhOG
+G9gWGhiAEQvfIFEgQKBKIgAgB/QdhQHeWnaEuB2lDQseIVQVgBAE6ADYBvAdhYW4HaUB2DpwTCIA
+oMwhIaBY8s9ynwC4/1gaAAgQh89wgADAEA+IFqIA2s9woAD8RJ66QaBloB6FsLgepagVABBk4B6h
+ENgOoQHYFRkYgLYJr/4J2BcIX0fPcYAA4A0LgQHgUg9gAguhvgpAAhsJECDPcYAARH0FgQHgegtg
+AgWhOQIAAM91gAAUkccKECAdhYS4HaXPcIAARH0RC94gIoAB4SKgiiCFCQfwIYAB4SGgiiDFCNYL
+T/7aDkACS/BCEgCGBCC+jwDAAABD8gG1HoV7CN4EiiCEDrILb/6KIRADJgiABwCVhiD8AIwgAoAx
+9IoOQAev6APYEh8YkOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
+4HjgeOB44HjgeOB44HjgeOB44HgSHxiQE8wRGhwwBfAAla4LoAg0lawVARAI6ZcVgBAAqQDYrB0A
+EFQVgBAh6M92oAD8JTSGAdrPc4AARH0GgzhgBqMF6c9xgACZCUCpU4Yng1lhJ6M+hQHenwgQAJsJ
+3gEB2c9wgACEBSCgRfAhCB4gAdnPcIAAmQkgqM9xgABEfQOBAeADoT6F6/ED2c9woADUCzGg4Hjg
+eOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
+4HjgeDGgE8wRGhwwGQoRIB2Fz3GAAER9grgdpQSBAeAEoQHeHoUXCB4ElRWAEKQVARCpcg4P4AIB
+2wPwdgpAAx+FDwgeAM9wgADgl44OgATPd4AACJ0ZhwbougoABADYGaeGCUACz3CAAGwQCIAjCN4C
+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
+HgmgAItxgsZqcBYJoADJcUpwDgmgAITBqXAGCaAAhsGIxelw+gigAKlxKnDyCKAAisEKcOoIoACM
+walwisFOCaAAkMKLcMlxQgmgAJLCyXCEwToJoACUwobAqXEuCaAAlsKYxpDAksHCCKAAyXKax5TA
+lsG2CKAA6XLJcOlxDgmgAJzCnMCeweIIoACOwp/FhgigAARtjsCWCaAAJG23CBAAhsCKwaYIoABA
+JQITi3CEwZoIoABAJQIVlMBAJQETagigAMlykMBAJQEVXgigAOlyyXDpcbYIoACcwozAnMFKCKAA
+yXLCCKAAyXDJcI7BegigAEAlAheSwEAlARMuCKAAyXKWwEAlARUiCKAA6XLJcOlxdgigAJzCjMCc
+wQ4IoADJcslwjsFCCKAAQCUCGTYIoABAJQAXz3GAAPwHGKEmCKAAQCUAGc9xgAD8BxmhB/AA2c9w
+gAD8BzigOaCZAi/ygCQCOuB48cBSCi/yCtqqwQh2dg8v8otxBtguCmAAAcEI2CYKYAABwQnYHgpg
+AAHBEBQEMMlwAMECwgolgA+t3u++og1gAAPDyXBd/38I0ADPdYAA/AcchRgUBDASpR2FAMEKJYAP
+rd7vvgLCFaXJcHYNYAAFw8lwUv9PCNAAHIUgFAQwE6UdhQDBCiWAD63e774CwhalyXBODWAAB8PJ
+cEj/JwjQAHyFdBUGEMlwVBUEEFgVBRB0pSQUBzAyhVwdgBFThW3/ANj9AS/yqsDxwG4JL/IM2Lpx
+OnLPd4AA/AeEFxMQfBcQEADdmnDPcIAADE3wIFIDanDSC6/6SnECcBN4xguv+oohDwoIdogXABC6
+C6/6SnGAFwEQOGATeKoLr/qKIQ8KumVUekAtwSA2eVlhx3GAAEywDQkRIMSpBakJ8AsJUSDGqQep
+A/DIqQmpQiRAIJkIdYAB5TEBL/IA2OB48cDKCA/yp8G6cADfRsdKJ8AgSiSAIUojwCRKIIA1z3aA
+APwH66bpcVp3gOHKIoEvAAAI0sojISXKIOE1yifhJMokoSWB4coigS8AAAnSyiMhJcog4TXKJ2El
+yiQhJoLhyiKBLwAACtIT2cojQSDKIKEFyiABMMokASDKJ0EgANkH2EXAz3WAABxMNX0AhdpxAdmO
+4MIhTgAqpoDhyiHBJcohwiSA4cogASXKIAImogtAAM9xgAA4TMlwA9oKCmAAAtsKhiuGCtqt/s9w
+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
+AQQOGkQBTCWAhMohwg/KIsIHyiBiAcojgg8AAHMA6ANi78okIgAA2gfwABYAQRQhjAAAtAHiLyBC
+AfMKAoBSCo/w0cDgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4z3CAADwJ
+4H8AgOB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
+eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
+4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H8B2OB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
+fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwHY8cDPcIAA
+RL56Ca/wA9kyCY/w0cDgfuB4AtjPcaAAwB0NoSHYBqEB2Aeh4H4A2c9woADAHSegJqAtoOB+z3GA
+AEQJDQhRAAHYAKkBqQCJgeDKIIEPAADECcoggg8AAIAA4H8BoQDYz3KAAEQJAaoAqs9xgAAwfAaJ
+COgHiQboAJEJCJEDAdgAqgDY2vHxwOHFCHXPcIAAwBABiCsIUQAH8IIIT+8KDW/wT9jPcKAA1AsY
+gADZQiAACIDgyiBMAOUIRIOtBE/w4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjxwAohwA/rcgXY
+JttKJAAAxQFv7wolAAHxwAohwA/rcgXYK9tKJAAArQFv7wolAAHPcAIAKBvPcYAATAkAoc9wAgAk
+GwGhz3ACACwbAqHPcAIAMBvgfwOhz3ACAKgaz3GAAEwJAKEBoQKhz3ACAKwa4H8DoeB+4HjgfuB4
+4H7geOB+4HjxwJYLb/Bq2KLBi3EB2sII4ABIc43oCiHAD+tyBdiKI88LiiSBCi0Bb+9KJQAAgcFE
+2AHamgjgAEhzjugKIcAP63IF2IojzwyKJAEBBQFv70olAAAEFAAxXwiCDwAAMgRAJIEwa9gB2mYI
+4ABIc47oCiHAD+tyBdiKI88PiiTBCtEAb+9KJQAAAhQAMc92gABcCRt4QSjFAEwlAIoEHkAR0fYK
+IcAP63IF2Ioj0AClAG/viiTBCh3Yz3aAAFwJAaa4cAAUADHPdYAAXL5ALYIAqXH+D6AAAduN6AAU
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAMAAADImoAAAAAAAAAAAABAn4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAD/
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiKSAAOSZAQAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAA
+AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAEBAQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAABAAIAAAAAAAAABwAAAAcAAAAHAAAAAgAAAAIAAACDAAAAkgAAAOgA
+AAD3AAAATgEAAF0BAAAAAAEAAgAAAAYACAAJAAAABwAAAAAAAAACAAAAAgAAAIMAAACSAAAA6AAA
+APcAAABOAQAAXQEAAAAAAQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAAgwAAAJIAAADo
+AAAA9wAAAE4BAABdAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiagAD8/wEAAAAAAMiagACgBgIAAAAAAAAAAADI
+moAAOAgCAAAAAAAAAAAAAAAAAMiagAAAAAAAAAAAAAEADwBkAAEAHAmAAAAAAAAAAAAABwAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAKgaAgCoGgIAqBoCAKwaAgAAAAAAHQAA
+AAAAAAAAAAAAAAAAAAAAAAB/fwABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIECAAIECAAAAAA
+AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACs
+CAAAFQAAAAwvgACAKgAAgCoAAIAqAAC8QAAAgCoAAIAqAABAPAAAgCoAAIAqAACAKgAAgCoAAIAq
+AACAKgAAgCoAAIAqAACAKgAAIB4AAMgfAADgHwAATCEAAMwhAABQIQAAgCoAAIAqAAAETQAAxE4A
+AKxPAACAKgAAgCoAAIAqAACISwAA7GEAAOhhAABAYgAAgCoAAIAqAACAKgAAyEIAAIAqAAAkYgAA
+gCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAADAQAAAgCoAAIAqAACAKgAAgCoAAIAqAACA
+KgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAq
+AACAKgAAgCoAAIAqAAC0QwAAgCoAAIAqAACAKgAAgCoAAIAqAACYRAAAgCoAAIAqAACAKgAAgCoA
+AIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAAAYaQAAgCoAADxqAACAKgAAgCoAAIAqAACAKgAA
+gCoAAIAqAACAKgAAgCoAANRsAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACA
+KgAAgCoAAAh/AQBYggEAgCoAAKSEAQCAKgAAUIYBAHRTAQCAKgAAgCoAAHBQAACAKgAAgCoAAIAq
+AACAKgAAgCoAAID4AQDU+AEAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoA
+AIAqAABodAAAgCoAAIAqAACAKgAAWP4BAIAqAABAAgIAgCoAACgpAgCAKgAA8CQAAPQkAACAKgAA
+gCoAANAZAgAodwAAgCoAAIAqAACAKgAADPwBAIAqAACAKgAA3EwBALCdAQCAKgAAgCoAAIAqAAB4
+pgEAkFQBAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAGypAQCAKgAAyBgCAMwYAgDYGAIA3BgCANAY
+AgDUGAIA4BgCAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAGBSAACAKgAAgCoA
+AIAqAACAKgAAgCoAABwYAgBsGAIArEYAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAA
+gCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACA
+KgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAq
+AAAkSAAArEgAADxJAADwSQAA3IUAAMhJAACAKgAAgCoAAIAqAACAKgAAgCoAABxIAAAgSAAAgCoA
+AIAqAACgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAMAABgDAAAYAwA
+AGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAA
+YAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAACQ
+DQAAAAAAAORZAQBgDAAAhAkAAGAMAABgDAAAYAwAALQJAADMPAEA/IcAAGAMAABgDAAA6AkAAOgJ
+AADoCQAA6AkAAOgJAADoCQAA6AkAAGAMAABgDAAAYAwAAGAMAADQCwAAYAwAAGAMAABgDAAAYAwA
+AGAMAACUDQAAYAwAAGAMAABoCQAAAwAAAOQMAgACAAAAyGcBAAQAAAB4aAEABQAAALANAAAGAAAA
+NDMAAAgAAABIGAIAEwAAAGT5AQAJAAAA3AMCAAoAAADkGAIADgAAAMyaAQAPAAAAfIgBABAAAAC0
+iAEAGAAAAExZAQANAAAATIABABcAAAAkdwAAEQAAAFCGAAASAAAA5EsBAAEAAADc/QEAFAAAALin
+AQAVAAAA4J0BAAcAAABEbQAAFgAAABgpAgAZAAAAkA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAACAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAEAAAAAEAAAABAQAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//
+////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAA4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e
+4eEDDh7hPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwVFRUVPDw8PBUVFRU8PDw8AAAA
+AAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8FRUVFTw8PDwVFRUV
+PDw8PAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8
+PDw8FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAAkAYAADH6rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6
+rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6rwCQBgAAMfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqv
+AEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAEMFAAAx+q8AQwUAADH6rwAAAAAA3sMJAAAAAAAAAAAA
+AAAAAIwrAQABAAAAzC6AAAAAAAAAAAAAAgAAAAMAAAAAAAAACAAAAAAAAAAwjBEAIL8CAAAAAAD8
+KwEAoCwBAKQtAQBMLwEApC0BAEwvAQD8MAEAhDEBAOQxAQCAgICAgICAgAGAAoCAgICAAAAAALQ3
+AQC0NwEAAAAAAAAAAAAAAAAAAAAAALQ3AQC0NwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AMwugADMLoAApCCgADggoAABAAAA/P///wAAAAAAAAAA7C6AAOwugACoIKAAPCCgAAgAAADz////
+AAAAAAAAAAAML4AADC+AAKwgoABsIKAAMAAAAM////8AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA
+AAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAA8EwBAAUAAAAML4AAKFIBAAD/AwBIUgEAAP8FACxT
+AQAA/y0AUFMBAAD/PQAIUwEAAP8EAOxSAQAA/yUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAACUWAEABgAAAMwugAAAAAAALAEAAF4BAAABAAAAAQAAAAEAAAABAAAAAwAAAAAAAAAA
+AAAAxF8BAMBgAQA4YQEAWFwBAIhbAQBkYgEA6GIBACxjAQB8YwEAAAAAAAMAAAACAAAAAwAAAAMA
+AAADAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAARGkBAAoAAADMLoAAAAAAAAAAAAAAAAAA0GkB
+AAoAAADMLoAAAAAAAAAAAAAAAAAAhGoBAAoAAADMLoAAAAAAAAAAAAAAAAAApGsBAAoAAADMLoAA
+AAAAAAAAAAAAAAAACGoBAAoAAADMLoAAAAAAAAAAAAAAAAAAHGsBAAoAAADMLoAAAAAAABAAAAAA
+gAAAAACgABAnAADoAwAA6AMAAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+
+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6A
+AAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAA
+AAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAK
+AAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAA
+AAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAADCEAQAKAAAAzC6AAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMiwEAkIwBAGCPAQAMkgEAhJQBAOiXAQA0jgEARAWA
+AJCagAAYAAAAUJqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdJoBAAYAAADMLoAA/////wAAAAD/////
+/////wAAAAAAAAAAAAAAAECdAQAFAAAADC+AAG4AbgBpAMAAoABQAIAAvgBQAX0APgBuAG4AaQDA
+AKAAUACAAL4AUAF9AD4AAAAAAAEBAAAAAAAAAAECAQEAAgEAAQICAgABAQACAQIBAgACAAECA///
+AAC5Ad8AsQAbABYBGwB8ARsArwAbABQBGwB6ARsAbACgANEAoAA3AaAAbwCDAHEAgwB2AIMAcwAz
+AG4AMwBwADMAcgAzANcAMwA9ATMA1AEGANABAAB+ADwA4wA8AEkBPAB4AEkA3QBJAEMBSQB/AFoA
+5ABaAEoBWgCqAD8AqwABAA8BPwAQAQEAdQE/AHYBAQB5AGoA3gBqAEQBagCoAAAADQEAAHMBAACm
+ADcApwABAAsBNwAMAQEAcQE3AHIBAQAEAAgAnAHMAJ0BzACeAcwAnwHMANUBzADWAcwA1wHMALQA
+RwAZAUcAgAFHAJAAIgD1ACIAWwEiAKEAiAAGAYgAbAGIAJQAAACVAAAAmADAAJkAoACWAJAAlwAA
+AJQAAQCVAAEAmADAAJkAoACWAJAAlwAAAJQAAgCVAAMAmADAAJkAoACWAJAAlwAAAJQAAwCVAAcA
+mADAAJkAoACWAJAAlwAAAPoAAAD5AAAAAgGQAAMB0wAAAYMA/gATAPwAMwD9AHcA+gABAPkAAQAC
+AZAAAwHTAAABgwD+ABMA/AAzAP0AdwD6AAIA+QADAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoA
+AwD5AAcAAgGSAAMB0wAAAYMA/gATAPwAMwD9AHcAXwEAAGEBAABoAZAAaQHTAGYBgwBkARMAYgEz
+AGMBdwBfAQEAYQEBAGgBkABpAdMAZgGDAGQBEwBiATMAYwF3AF8BAgBhAQMAaAGQAGkB0wBmAYMA
+ZAETAGIBMwBjAXcAXwEDAGEBBwBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwCFAAAAhgAAAIcAUACI
+AAAAiQCgAIoAAACLANAAjAAAAIUAAQCGAAEAhwBQAIgAAACJAKAAigAAAIsA0ACMAAAAhQACAIYA
+AwCHAFAAiAAAAIkAoACKAAAAiwDQAIwAAACFAAMAhgAHAIcAUACIAAAAiQCgAIoAAACLANAAjAAA
+AOsAAADqAAAA7ABQAO0AAADuAKAA7wAAAPAA0ADxAAAA6wABAOoAAQDsAFAA7QAAAO4AoADvAAAA
+8ADQAPEAAADrAAIA6gADAOwAUADtAAAA7gCgAO8AAADwANAA8QAAAOsAAwDqAAcA7ABQAO0AAADu
+AKAA7wAAAPAA0ADxAAAAUQEAAFABAABSAVAAUwEAAFQBoABVAQAAVgHQAFcBAABRAQEAUAEBAFIB
+UABTAQAAVAGgAFUBAABWAdAAVwEAAFEBAgBQAQMAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQED
+AFABBwBSAVAAUwEAAFQBoABVAQAAVgHQAFcBAAD7/wAA//8AALkB3wCxABsAFgEbAHwBGwCvABsA
+FAEbAHoBGwBsAKAA0QCgADcBoABvAIMAcQCDAHYAgwBzADMAbgAzAHAAMwByADMA1wAzAD0BMwDU
+AQYA0AEAAH4APADjADwASQE8AHgASQDdAEkAQwFJAH8AWgDkAFoASgFaAKoAPwCrAAEADwE/ABAB
+AQB1AT8AdgEBAHkAagDeAGoARAFqAKgAAAANAQAAcwEAAKYANwCnAAEACwE3AAwBAQBxATcAcgEB
+AAQACACcAcwAnQHMAJ4BzACfAYgA1QHMANYBzADXAcwAtABHABkBRwCAAUcAkAAiAPUAIgBbASIA
+oQCIAAYBiABsAYgA+gAAAPkAAAACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAEA+QABAAIBlwAD
+AdAAAAGNAP4AEQD8ADMA/QB3APoAAgD5AAMAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gADAPkA
+BwACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwBfAQAAYQEAAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3
+AF8BAQBhAQEAaAGXAGkB0ABmAY0AZAERAGIBMwBjAXcAXwECAGEBAwBoAZcAaQHQAGYBjQBkAREA
+YgEzAGMBdwBfAQMAYQEHAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3AOsAAADqAAAA7ABVAO0AAADu
+AKoA7wAAAPAA3QDxAAAA6wABAOoAAQDsAFUA7QAAAO4AqgDvAAAA8ADdAPEAAADrAAIA6gADAOwA
+VQDtAAAA7gCqAO8AAADwAN0A8QAAAOsAAwDqAAcA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAAUQEA
+AFABAABSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAABRAQEAUAEBAFIBVQBTAQAAVAGqAFUBAABWAd0A
+VwEAAFEBAgBQAQMAUgFVAFMBAABUAaoAVQEAAFYB3QBXAQAAUQEDAFABBwBSAVUAUwEAAFQBqgBV
+AQAAVgHdAFcBAAD7/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KgB
+AJDJAQCwpYAAQAUAAAAAAADcqAEA/KkBAPCqgAD4AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+XM4BAGjMAQDorIAAVAAAAAAAAADcqAEAlMwBAGitgABQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
+AAAA3KgBALDIAQC8P4AAUAEAAAAAAADcqAEAyMoBAPgGgAACAAAAAAAAANyoAQAgywEA/AaAAAQA
+AAAAAAAAWM4BAPypAQA8rYAAKgAAAAAAAADcqAEAvMsBAAAAAAAAAAAAAAAAANyoAQB8ywEAAAeA
+AAQAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHAAgACAAJAAoACgALAAwADAANAA4A
+DgAPACYAJwAoACgAKQAqAEYARgBHAEgASABJAEoASgBLAEwAaABpAGoAagBrAGwAbABtAG4AbgBv
+AHAAcABxAHIAcgBzAHQAdAB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AA8A
+PwAAAAAAAAAAAAAAAAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkACgAKAAsAJAAkACUAJgAm
+ACcARABEAEUARgBGAEcASABIAEkASgBKAEsATABMAE0AagBqAGsAbABsAG0AbgBuAG8AcABwAHEA
+cgByAHMAdAB0AHUAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AA4APwDE
+owEAEtIAAAAAAAD//w8A6LcBALYAAAAAAAAA/wAAAOi3AQC3AAAAAAAAAP8AAADotwEAuAAAAAAA
+AAD/AAAA6LcBALkAAAAAAAAA/wAAAOi3AQC6AAAAAAAAAP8AAADotwEAuwAAAAAAAAD/AAAA6LcB
+AL0AAAAAAAAA/wAAAOi3AQC+AAAAAAAAAP8AAADotwEAvwAAAAAAAAD/AAAA6LcBAMAAAAAAAAAA
+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
+ENIC0gHSA9Ib0gvSAIAF0hLSE9IU0gRDCNIJ0grSHNIG0gfScNIAAAEAAAAAAAAAAAAAAAAAAAAD
+AAAABAAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAD/AwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAALUAGgGBAQQADwCDAOgATgGSAPcAXQEGAAgACQAKAAsADAAFAAAAAAAAACwAAQAA
+AAAAAAAAAAAAAAAAAAAAAAABAAEAAQAAAP////8AAAAALQEAAN0BAABaAgAAugIAAAoDAABNAwAA
+hwMAALoDAADoAwAAEQQAADcEAABZBAAAegQAAJgEAAC0BAAAzgQAAOcEAAD+BAAAFQUAACoFAAA+
+BQAAUQUAAGQFAAB1BQAAhgUAAJcFAACnBQAAtgUAAMUFAADTBQAA4QUAAO4FAAD7BQAACAYAABQG
+AAAgBgAAKwYAADcGAABCBgAATAYAAFcGAABhBgAAawYAAHUGAAB+BgAAiAYAAJEGAACaBgAAogYA
+AKsGAAC0BgAAvAYAAMQGAADMBgAA1AYAANsGAADjBgAA6gYAAPIGAAD5BgAAAAcAAAcHAAAOBwAA
+FAcAABsHAAAiBwAAKAcAAC4HAAA1BwAAOwcAAEEHAABHBwAATQcAAFMHAABYBwAAXgcAAGQHAABp
+BwAAbwcAAHQHAAB5BwAAfwcAAIQHAACJBwAAjgcAAJMHAACYBwAAnQcAAKIHAACnBwAAqwcAALAH
+AAC1BwAAuQcAAL4HAADCBwAAxwcAAMsHAADQBwAA1AcAANgHAADcBwAA4QcAAOUHAADpBwAA7QcA
+APEHAAD1BwAA+QcAAP0HAAABCAAABQgAAAgIAAAMCAAAEAgAABQIAAAXCAAAGwgAAB8IAAAiCAAA
+JggAACkIAAAtCAAAMAgAADQIAAA3CAAAOwgAAD4IAABBCAAARQgAAEgIAABLCAAATwgAAFIIAABV
+CAAAWAgAAFsIAABfCAAAYggAAGUIAABoCAAAawgAAG4IAABxCAAAdAgAAHcIAAB6CAAAfQgAAIAI
+AACCCAAAhQgAAIgIAACLCAAAjggAAJEIAACTCAAAlggAAJkIAAA4AAAAaAAAAHQAAACAAAAAjAAA
+AJ0AAAAHAAAAAAAAAAAAAAAKAAAADdIR0hDSAtIB0gPSG9IL0gCABdIS0hPSFNIEQwjSCdIK0hzS
+BtIH0nDSAAABAAAAAAAAAAAAAAAAAAAAAwAAAAQAAAADAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAA
+AAAA/wMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1ABoBgQEEAA8AgwDoAE4BkgD3AF0B
+BgAIAAkACgALAAwABQAAAAAAAAAsAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAADfAAAAGQEA
+AGIBAAC+AQAAMgIAAMMCAAB7AwAAYgQAAIQFAADyBgAAvggAAAILAAABAAAAAgAAAAAAAAAL0g7S
+DdII0gnSCtIS0hPSFNIR0hDSAtIB0gPSAIAF0gRDG9Ic0gTSAEUw0jHSAAAAAAAAAQAAAAEAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAADAAAABAAAAAMAAAAAAAAA/wMAAAMA
+AAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAALUAGgGBAQUABAAPABAACgALAAwATgAA
+AAAAAAAAAAAALAABAAAAAQABAAEAAAAAAAAAAAABAAEAAgACAAIAAwADAAQABAAFAAUABgAGAAcA
+BwAIAAgACQAJAAoACgALAAsADAAMAA0ADQAOAA4ADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQFgACQmoAAGAAAAFCagAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAMz/AQAGAAAAzC6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAARAWAAJCagAAYAAAAUJqAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAwAoCAAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYAAADM
+LoAAAAAAAAAAAAAAAAAAwAoCAAQAAADMLoAAAAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAA
+AAAAAAAAwAoCAAQAAADMLoAAAAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAwAoC
+AAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYAAADMLoAAAAAAAAAAAAAAAAAAwAoCAAQAAADMLoAA
+AAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYAAADMLoAAAAAAAAAAAAAA
+AAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYA
+AADMLoAARAWAAJCagAAYAAAAUJqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMEBAQEBAUGBwgICAgICQoLDA0AAAAFBgcI
+DQ4PEBUWFxgZAAAKDREUCg0RFBkZGRkKCgAAAAAAAAYGBgYJCQkJAAYAAG47aDtiO1w7bjpoOmI6
+XDpuOWg5YjlcOW4raCtiK1wrbipoKmIqXCpuKWgpYilcKW4baBtiG1wbbhpoGmIaXBpuGWgZYhlc
+GW4YaBhiGFwYbhdoF2IXXBduFmgWYhZcFm4VaBViFVwVbhRoFGIUXBRuE2gTYhNcE24SaBJiElwS
+bhFoEWIRXBFuEGgQYhBcEFcQUhBNEEkQbgFoAWIBXAFuAGgAYgBcAG47aDtiO1w7bjpoOmI6XDpu
+OWg5YjlcOW44aDhiOFw4bjdoN2I3XDduKWgpYilcKW4oaChiKFwobidoJ2InXCduGWgZYhlcGW4Y
+aBhiGFwYbhdoF2IXXBduCWgJYglcCW4IaAhiCFwIbgdoB2IHXAduBmgGYgZcBm4FaAViBVwFbgRo
+BGIEXARuA2gDYgNcA24CaAJiAlwCbgFoAWIBXAFuAGgAYgBcAAAAAAAAAAAAAAAAAEArAgAIAAAA
+DC+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////8A
+Af//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////////////////////////////////////////////////////
+//////////////////////////8BBAAAAgUBAAMGAgAEBwMABQgEAAYJBQAHCgYACAsHAAkMCAAK
+DQkACw4KAAwPCwANEAwADhENAAFAAAQCQQEEA0ICBARDAwQFRAQEBkUFBAdGBgQIRwcECUgIBLcT
+IgC4FCMAuRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgcAQALHQIADB4DABAfBAAiIQUAJCIG
+ACYjBwAoJAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsPAEAsEABkLhEAaC8SAGwwEwBwMRQA
+dDIVAHgzFgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0AmTweAJ09HwChPiAApT8hACRJBgIs
+SgoCNEsNATxMDwFkTREBbE4TAXRPFQF8UBcBhFEZAZVSHQGdUx8BAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAABBgIGBgYDBgYGBgYGBgQAAAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/
+AAEAAAAPAD8AAQAAAA8APwACAAAADwA/AAEAAAAAAAAAAQAAAAIAAAADAAAAAAAAAAQAAAACAAAA
+BQAAAA8UGR4oCgUAsAkBpQA8ODQwLCgkIBwYFBAMCAQADAgEADw4NDAsKCQgHBgUEAwIBAIIAA4A
+AAAOAQEAAQIBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AKXGhPiZ7o32Df+91rHeVJFQYAMCqc59VhnnYrXmTZrsRY+dH0CJh/oV7+uyyY4L++xBZ7P9X+pF
+vyP3U5bkW5vCdRzhrj1qTFpsQX4C9U+DXGj0UTTRCPmT4nOrU2I/KgwIUpVlRl6dKDChNw8KtS8J
+DjYkmxs93ybNaU7Nf5/qGxKeHXRYLjQtNrLc7rT7W/akTXZht859e1I+3XFelxP1pmi5AAAswWBA
+H+PIee22vtRGjdlnS3LelNSY6LBKhWu7KsXlTxbtxYbXmlVmlBHPihDpBgSB/vCgRHi6JeNL86L+
+XcCAigWtP7whSHAE8d9jwXd1r2NCMCAa5Q79bb9MgRQYNSYvw+G+ojXMiDkuV5PyVYL8R3qsyOe6
+KzKV5qDAmBnRnn+jZkR+VKs7gwvKjCnH02s8KHmn4rwdFnatO9tWZE50HhTbkgoMbEjkuF2fbr3v
+Q6bEqDmkMTfTi/Iy1UOLWW632owBZLHSnOBJtNj6rAfzJc+vyo706UcYENVviPBvSnJcJDjxV8dz
+UZcjy3yhnOghPt2W3GGGDYUPkOBCfMRxqszYkAUGAfcSHKPCX2r5rtBpkRdYmSc6uSc42RPrsysz
+IrvScKmJB6czti0iPJIVIMlJh/+qeFB6pY8D+FmACRca2mUx18aEuNDDgrApd1oRHst7/KjWbTos
+AQEBAQEBAQECAgICAgICAgMDAwMDAwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQE
+BAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgME
+BgZ00UUX6KKLLg0PBQcJCwEDChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHDw8P
+BwYHAgMEBQABCAkLCigAKAAwACwALAAoADwANAAoACgANAAwACwALABEADwAQAA8AIwAbABYAEgA
+9ACwACwALAA8ADQAMAAsAFQARABUAFQAbABgAFwAVACMAHgAOgECAdUA3wDaAKIAdQB/AGoBGgHZ
+AOgACgG6AHkAiACKBSoDOQGoAYoFygLZAEgBygFKAeIA+QDKAeoAggCZAPQCRAK1AdUBlAKEAfUA
+QQKsAJAAhACAAHgAeAB4AHQAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzE
+Tid2YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUF
+BVRABSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN
+0iANCqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4
+gAcGaZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiA
+CgiMwAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEQAOABsAJAA2AEwAa
+QB2AIIAGAA2AEwAaACcANIA6AEHACYATQB0AJ4A6AE7AV4BhmQMzB9kKcw6mFeYcgCAZJDMHcw6m
+FeYcWSvMOQBBM0jZCqYVgCBZKwBBplaAYVlsMAAAADYAAAAMAAAAEgAAABgAAAAkAAAABgAAAAkA
+AAAAAAAAAAAAABggFBQODhQUBQYBAgMEAAAAAQECAQICAwQMDAgEDAQEQAAAAIAAAAAAAQAAAAIA
+AEAAAAAABAAAQAAAAEAAAAAQERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uL0BBQkNERUZH
+SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8z
+EwAAAAcHDwcPDxctAA8gAPBhAAAAAAAAAAAAAAECBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDk6NDk6MDkAAAAATi2uAGmu
+oK6QrmIAAaysegCskpusrF8ACQAAAAIAAAAAAAAAAAAAAAkAAAACAAAAAAAAAAAAAAAJAAAAAwAA
+AAEAAAAJAAAACQAAAAIAAAACAAAACQAAAAECAQIDBAAABQYHCAkKAAAABQYAAgQABQAAAAAABQcB
+AwQABQEAAABAI0AlISEhIUBAQEBABQQEAQFAQEBABQVAQAwMQA0MDAEBAQVAQAUFAAQABEBAAARA
+QEAFQEBAQEAFQEBABQUFAQEBAUAFBQUBBQEBQAUFBUAFQAUFBQUFBAAAABwRAAAcMgAAHDMAAAQA
+AAAcFQAAAgAXAGwAcAR0CHQMAAQEBgAAAAAAAAAAZAAAAACQAQAKAAAAAAAAAAAAAAAAAAAA/wAA
+AAAAAAAAAAAAAAAAAAAAAAABAAAAEAAAAAAAAAABAAAAAQAAAAAAAAD/AAAA/wAAAAAAAAAAAAAA
+HHsBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAABAAAZAAAAIyB
+AQCUgQEAnIEBAPCBAQD4gQEAAIIBAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwYGBgYGBQUFBQUEBAQEBAMDAwMDAgICAgIBAQEBAQAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACiVDvU56
+lQAHFCdZLgAAAAQOCR0tNwAABA4JHSw7AAEQAAEAAAACgAABQgYCEAACIAAAA8AAAUMGAxAAAsAA
+AAPAAAFDBgQQAAJAAAACgAABRAYFEQAAQAAAA8AAAUUGBhEAAOAAAAPAAAFFBgcRAAEAAAACgAAB
+RgYIEQACIAAAA8AAAUcGCREAAsAAAAPAAAFHBgoRAAJAAAACgAABSAYLEgAAQAAAA8AAAUkGDBIA
+AOAAAAPAAAFJBg0SAAEAAAACgAABSgYOEgACAAAAAoAAAUwGAAAiFgAAgAAAAwAAAVkAJBYAAQAA
+AAMAAAFaACYWAAIAAAAEAAABWgAoFgACAAAAAwAAAVsAKhYAAoAAAAMAAAFcACwXAAAAAAAEAAAB
+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
+AAAAAAUFBQUFBQUFAAAAAIANAAAAIAAAgA0AAIANAAAAIAAAgA0AAAAGAAAABAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAA=
+====
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 51dea2236b7..3eab6704cee 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 WiFi Link 4965 and 1000/5000/6000 Series 802.11 network
+ * adapters.
  */
 
 #include 
@@ -73,29 +74,30 @@ __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_ict(struct iwn_softc *);
+void		iwn_free_ict(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 +105,117 @@ 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]);
+void		iwn5000_ict_reset(struct iwn_softc *);
+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 *, int,
+		    uint32_t);
+void		iwn_read_eeprom_enhinfo(struct iwn_softc *);
+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 *);
+#if 0	/* HT */
+void		iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
+		    struct iwn_rx_data *);
+#endif
+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 *);
 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		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		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, int);
+int		iwn_add_broadcast_node(struct iwn_softc *, int);
 int		iwn_wme_update(struct ieee80211com *);
+static void	iwn_update_mcast(struct ifnet *);
 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		iwn5000_send_wimax_coex(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 *);
+int		iwn_clock_wait(struct iwn_softc *);
+int		iwn_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 *);
+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 +225,16 @@ 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 int	iwn_setregdomain(struct ieee80211com *,
+		    struct ieee80211_regdomain *, int,
+		    struct ieee80211_channel []);
+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 +273,101 @@ 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" },
+	{ 0x8086, 0x0086, "Intel(R) PRO/Wireless 6050" },
+	{ 0x8086, 0x0087, "Intel(R) PRO/Wireless 6050" },
+	{ 0, 0, NULL }
+};
+
+static const struct iwn_hal iwn4965_hal = {
+	iwn4965_load_firmware,
+	iwn4965_read_eeprom,
+	iwn4965_post_alive,
+	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,
+#if 0	/* HT */
+	iwn4965_ampdu_tx_start,
+	iwn4965_ampdu_tx_stop,
+#endif
+	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_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,
+#if 0	/* HT */
+	iwn5000_ampdu_tx_start,
+	iwn5000_ampdu_tx_stop,
+#endif
+	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 +376,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 +424,69 @@ 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;
+	}
+
+	/* 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 ICT table for 5000 Series. */
+	if (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
+	    (error = iwn_alloc_ict(sc)) != 0) {
+		device_printf(dev,
+		    "%s: could not allocate ICT table, error %d\n",
+		    __func__, error);
+		goto fail;
+	}
+
+	/* 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 +496,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 +504,19 @@ iwn_attach(device_t dev)
 		goto fail;
 	}
 
+	/* Clear pending interrupts. */
+	IWN_WRITE(sc, IWN_INT, 0xffffffff);
+
+	/* Count the number of available chains. */
+	sc->ntxchains =
+	    ((sc->txchainmask >> 2) & 1) +
+	    ((sc->txchainmask >> 1) & 1) +
+	    ((sc->txchainmask >> 0) & 1);
+	sc->nrxchains =
+	    ((sc->rxchainmask >> 2) & 1) +
+	    ((sc->rxchainmask >> 1) & 1) +
+	    ((sc->rxchainmask >> 0) & 1);
+
 	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
 	if (ifp == NULL) {
 		device_printf(dev, "can not allocate ifnet structure\n");
@@ -366,11 +524,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 */
@@ -378,13 +536,13 @@ iwn_attach(device_t dev)
 		| IEEE80211_C_SHSLOT		/* short slot time supported */
 		| IEEE80211_C_WPA
 		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
-#if 0
 		| IEEE80211_C_BGSCAN		/* background scanning */
+#if 0
 		| IEEE80211_C_IBSS		/* ibss/adhoc mode */
 #endif
 		| IEEE80211_C_WME		/* WME */
 		;
-#if 0
+#if 0	/* HT */
 	/* XXX disable until HT channel setup works */
 	ic->ic_htcaps =
 		  IEEE80211_HTCAP_SMPS_ENA	/* SM PS mode enabled */
@@ -398,9 +556,40 @@ iwn_attach(device_t dev)
 		| IEEE80211_HTC_AMPDU		/* tx A-MPDU */
 		| IEEE80211_HTC_AMSDU		/* tx A-MSDU */
 		;
+
+	/* Set HT capabilities. */
+	ic->ic_htcaps =
+#if IWN_RBUF_SIZE == 8192
+	    IEEE80211_HTCAP_AMSDU7935 |
+#endif
+	    IEEE80211_HTCAP_SMPS_DIS |
+	    IEEE80211_HTCAP_CBW20_40 |
+	    IEEE80211_HTCAP_SGI20 |
+	    IEEE80211_HTCAP_SGI40;
+	if (sc->hw_type != IWN_HW_REV_TYPE_4965)
+		ic->ic_htcaps |= IEEE80211_HTCAP_GF;
+#endif
+
+	/* 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;
+	}
+
+	device_printf(sc->sc_dev, "MIMO %dT%dR, %.4s, address %6D\n",
+	    sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
+	    macaddr, ":");
+
+#if 0	/* HT */
+	/* Set supported HT rates. */
+	ic->ic_sup_mcs[0] = 0xff;
+	if (sc->nrxchains > 1)
+		ic->ic_sup_mcs[1] = 0xff;
+	if (sc->nrxchains > 2)
+		ic->ic_sup_mcs[2] = 0xff;
 #endif
-	/* read supported channels and MAC address from EEPROM */
-	iwn_read_eeprom(sc, macaddr);
 
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_softc = sc;
@@ -408,7 +597,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 +607,130 @@ 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_update_mcast = iwn_update_mcast;
+	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;
+	ic->ic_setregdomain = iwn_setregdomain;
+#if 0	/* HT */
+	ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
+	ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
+	ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
+	ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
+#endif
 
+	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->limits = &iwn4965_sensitivity_limits;
+		sc->fwname = "iwn4965fw";
+		sc->txchainmask = IWN_ANT_AB;
+		sc->rxchainmask = IWN_ANT_ABC;
+		break;
+	case IWN_HW_REV_TYPE_5100:
+		sc->sc_hal = &iwn5000_hal;
+		sc->limits = &iwn5000_sensitivity_limits;
+		sc->fwname = "iwn5000fw";
+		sc->txchainmask = IWN_ANT_B;
+		sc->rxchainmask = IWN_ANT_AB;
+		break;
+	case IWN_HW_REV_TYPE_5150:
+		sc->sc_hal = &iwn5000_hal;
+		sc->limits = &iwn5150_sensitivity_limits;
+		sc->fwname = "iwn5150fw";
+		sc->txchainmask = IWN_ANT_A;
+		sc->rxchainmask = IWN_ANT_AB;
+		break;
+	case IWN_HW_REV_TYPE_5300:
+	case IWN_HW_REV_TYPE_5350:
+		sc->sc_hal = &iwn5000_hal;
+		sc->limits = &iwn5000_sensitivity_limits;
+		sc->fwname = "iwn5000fw";
+		sc->txchainmask = IWN_ANT_ABC;
+		sc->rxchainmask = IWN_ANT_ABC;
+		break;
+	case IWN_HW_REV_TYPE_1000:
+		sc->sc_hal = &iwn5000_hal;
+		sc->limits = &iwn5000_sensitivity_limits;
+		sc->fwname = "iwn1000fw";
+		sc->txchainmask = IWN_ANT_A;
+		sc->rxchainmask = IWN_ANT_AB;
+		break;
+	case IWN_HW_REV_TYPE_6000:
+		sc->sc_hal = &iwn5000_hal;
+		sc->limits = &iwn6000_sensitivity_limits;
+		sc->fwname = "iwn6000fw";
+		switch (pci_get_device(sc->sc_dev)) {
+		case 0x422C:
+		case 0x4239:
+			sc->sc_flags |= IWN_FLAG_INTERNAL_PA;
+			sc->txchainmask = IWN_ANT_BC;
+			sc->rxchainmask = IWN_ANT_BC;
+			break;
+		default:
+			sc->txchainmask = IWN_ANT_ABC;
+			sc->rxchainmask = IWN_ANT_ABC;
+			break;
+		}
+		break;
+	case IWN_HW_REV_TYPE_6050:
+		sc->sc_hal = &iwn5000_hal;
+		sc->limits = &iwn6000_sensitivity_limits;
+		sc->fwname = "iwn6000fw";
+		sc->txchainmask = IWN_ANT_AB;
+		sc->rxchainmask = IWN_ANT_AB;
+		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 +751,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 +777,313 @@ 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);
+	}
+
+	/* Free DMA resources. */
+	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);
+	if (sc->ict != NULL)
+		iwn_free_ict(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);
+	IWN_BARRIER_READ_WRITE(sc);
+	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_BARRIER_WRITE(sc);
+	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);
+	IWN_BARRIER_READ_WRITE(sc);
+	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_BARRIER_WRITE(sc);
+	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)
+{
+	uint32_t base;
+	uint16_t next;
+	int count, error;
+
+	/* Wait for clock stabilization before accessing prph. */
+	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);
+
+	/* Set auto clock gate disable bit for HW with OTP shadow RAM. */
+	if (sc->hw_type != IWN_HW_REV_TYPE_1000) {
+		IWN_SETBITS(sc, IWN_DBG_LINK_PWR_MGMT,
+		    IWN_RESET_LINK_PWR_MGMT_DIS);
+	}
+	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);
+
+	/*
+	 * Find last valid OTP block (contains the EEPROM image) for HW
+	 * without OTP shadow RAM.
+	 */
+	if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
+		/* Switch to absolute addressing mode. */
+		IWN_CLRBITS(sc, IWN_OTP_GP, IWN_OTP_GP_RELATIVE_ACCESS);
+		base = 0;
+		for (count = 0; count < IWN1000_OTP_NBLOCKS; count++) {
+			error = iwn_read_prom_data(sc, base, &next, 2);
+			if (error != 0)
+				return error;
+			if (next == 0)	/* End of linked-list. */
+				break;
+			base = le16toh(next);
+		}
+		if (base == 0 || count == IWN1000_OTP_NBLOCKS)
+			return EIO;
+		/* Skip "next" word. */
+		sc->prom_base = base + 1;
+	}
+	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;
+
+	addr += sc->prom_base;
+	for (; count > 0; count -= 2, addr++) {
+		IWN_WRITE(sc, IWN_EEPROM, addr << 2);
+		for (ntries = 0; ntries < 10; ntries++) {
+			val = IWN_READ(sc, IWN_EEPROM);
+			if (val & IWN_EEPROM_READ_VALID)
+				break;
+			DELAY(5);
+		}
+		if (ntries == 10) {
+			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 +1100,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) {
@@ -655,7 +1116,7 @@ fail:
 	return error;
 }
 
-static void
+void
 iwn_dma_contig_free(struct iwn_dma_info *dma)
 {
 	if (dma->tag != NULL) {
@@ -672,26 +1133,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
@@ -700,13 +1160,26 @@ iwn_free_kw(struct iwn_softc *sc)
 	iwn_dma_contig_free(&sc->kw_dma);
 }
 
+int
+iwn_alloc_ict(struct iwn_softc *sc)
+{
+	/* ICT table must be aligned on a 4KB boundary. */
+	return iwn_dma_contig_alloc(sc, &sc->ict_dma,
+	    (void **)&sc->ict, IWN_ICT_SIZE, 4096, BUS_DMA_NOWAIT);
+}
+
+void
+iwn_free_ict(struct iwn_softc *sc)
+{
+	iwn_dma_contig_free(&sc->ict_dma);
+}
+
 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,37 +1191,49 @@ 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->data_dmat);
+	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;
+	}
 
 	/*
-	 * 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);
@@ -758,30 +1243,31 @@ iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 			    __func__, error);
 			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;
 			goto fail;
 		}
-		/* map page */
+
+		/* Map page. */
 		error = bus_dmamap_load(ring->data_dmat, 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->data_dmat, data->map, 
+		bus_dmamap_sync(ring->data_dmat, 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 +1283,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,56 +1308,80 @@ 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_sync(ring->data_dmat, data->map,
+			    BUS_DMASYNC_POSTREAD);
+			bus_dmamap_unload(ring->data_dmat, data->map);
+			m_freem(data->m);
+		}
+		if (data->map != NULL)
+			bus_dmamap_destroy(ring->data_dmat, data->map);
+	}
 }
 
 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->data_dmat);
+	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];
 
+		data->cmd_paddr = paddr;
+		data->scratch_paddr = paddr + 12;
+		paddr += sizeof (struct iwn_tx_cmd);
+
 		error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
 		if (error != 0) {
 			device_printf(sc->sc_dev,
@@ -877,7 +1389,7 @@ iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
 			    __func__, error);
 			goto fail;
 		}
-		bus_dmamap_sync(ring->data_dmat, data->map, 
+		bus_dmamap_sync(ring->data_dmat, data->map,
 		    BUS_DMASYNC_PREWRITE);
 	}
 	return 0;
@@ -889,24 +1401,7 @@ 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];
@@ -917,7 +1412,11 @@ iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
 			data->m = NULL;
 		}
 	}
-
+	/* 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;
 }
@@ -930,1514 +1429,127 @@ iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
 	iwn_dma_contig_free(&ring->desc_dma);
 	iwn_dma_contig_free(&ring->cmd_dma);
 
-	if (ring->data != NULL) {
-		for (i = 0; i < IWN_TX_RING_COUNT; i++) {
-			struct iwn_tx_data *data = &ring->data[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);
-				m_freem(data->m);
-			}
+		if (data->m != NULL) {
+			bus_dmamap_sync(ring->data_dmat, data->map,
+			    BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(ring->data_dmat, data->map);
+			m_freem(data->m);
 		}
+		if (data->map != NULL)
+			bus_dmamap_destroy(ring->data_dmat, data->map);
 	}
 }
 
-struct ieee80211_node *
-iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
-{
-	return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
-}
-
 void
-iwn_newassoc(struct ieee80211_node *ni, int isnew)
+iwn5000_ict_reset(struct iwn_softc *sc)
 {
-	struct ieee80211vap *vap = ni->ni_vap;
+	/* Disable interrupts. */
+	IWN_WRITE(sc, IWN_INT_MASK, 0);
 
-	ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
-	   &IWN_NODE(ni)->amn, ni);
+	/* Reset ICT table. */
+	memset(sc->ict, 0, IWN_ICT_SIZE);
+	sc->ict_cur = 0;
+
+	/* Set physical address of ICT table (4KB aligned.) */
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s: enabling ICT\n", __func__);
+	IWN_WRITE(sc, IWN_DRAM_INT_TBL, IWN_DRAM_INT_TBL_ENABLE |
+	    IWN_DRAM_INT_TBL_WRAP_CHECK | sc->ict_dma.paddr >> 12);
+
+	/* Enable periodic RX interrupt. */
+	sc->int_mask |= IWN_INT_RX_PERIODIC;
+	/* Switch to ICT interrupt mode in driver. */
+	sc->sc_flags |= IWN_FLAG_USE_ICT;
+
+	/* Re-enable interrupts. */
+	IWN_WRITE(sc, IWN_INT, 0xffffffff);
+	IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
 }
 
 int
-iwn_media_change(struct ifnet *ifp)
-{
-	int error = ieee80211_media_change(ifp);
-	/* NB: only the fixed rate can change and that doesn't need a reset */
-	return (error == ENETRESET ? 0 : error);
-}
-
-int
-iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
-	struct iwn_vap *ivp = IWN_VAP(vap);
-	struct ieee80211com *ic = vap->iv_ic;
-	struct iwn_softc *sc = ic->ic_ifp->if_softc;
-	int error;
-
-	DPRINTF(sc, IWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
-		ieee80211_state_name[vap->iv_state],
-		ieee80211_state_name[nstate]);
-
-	IEEE80211_UNLOCK(ic);
-	IWN_LOCK(sc);
-	callout_stop(&sc->sc_timer_to);
-
-	if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) {
-		/* !AUTH -> AUTH requires adapter config */
-		error = iwn_auth(sc, vap);
-	}
-	if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
-		/*
-		 * !RUN -> RUN requires setting the association id
-		 * which is done with a firmware cmd.  We also defer
-		 * starting the timers until that work is done.
-		 */
-		error = iwn_run(sc, vap);
-	}
-	if (nstate == IEEE80211_S_RUN) {
-		/*
-		 * RUN -> RUN transition; just restart the timers.
-		 */
-		iwn_calib_reset(sc);
-	}
-	IWN_UNLOCK(sc);
-	IEEE80211_LOCK(ic);
-	return ivp->iv_newstate(vap, nstate, arg);
-}
-
-/*
- * Grab exclusive access to NIC memory.
- */
-void
-iwn_mem_lock(struct iwn_softc *sc)
-{
-	uint32_t tmp;
-	int ntries;
-
-	tmp = IWN_READ(sc, IWN_GPIO_CTL);
-	IWN_WRITE(sc, IWN_GPIO_CTL, tmp | IWN_GPIO_MAC);
-
-	/* 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;
-        }
-}
-
-static void
-iwn_timer_timeout(void *arg)
-{
-	struct iwn_softc *sc = arg;
-
-	IWN_LOCK_ASSERT(sc);
-
-	if (sc->calib_cnt && --sc->calib_cnt == 0) {
-		DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",
-		    "send statistics request");
-		(void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, NULL, 0, 1);
-		sc->calib_cnt = 60;	/* do calibration every 60s */
-	}
-	iwn_watchdog(sc);		/* NB: piggyback tx watchdog */
-	callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
-}
-
-static void
-iwn_calib_reset(struct iwn_softc *sc)
-{
-	callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, 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)
-{
-	switch (iwnrate) {
-	/* CCK rates */
-	case  10: return   2;
-	case  20: return   4;
-	case  55: return  11;
-	case 110: return  22;
-	/* OFDM rates */
-	case 0xd: return  12;
-	case 0xf: return  18;
-	case 0x5: return  24;
-	case 0x7: return  36;
-	case 0x9: return  48;
-	case 0xb: return  72;
-	case 0x1: return  96;
-	case 0x3: return 108;
-	/* XXX MCS */
-	}
-	/* unknown rate: should not happen */
-	return 0;
-}
-
-void
-iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
-    struct iwn_rx_data *data)
-{
-	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 iwn_rx_stat *stat;
-	caddr_t head;
-	uint32_t *tail;
-	int8_t rssi, nf;
-	int len, error;
-	bus_addr_t paddr;
-
-	if (desc->type == IWN_AMPDU_RX_DONE) {
-		/* check for prior AMPDU_RX_START */
-		if (!sc->last_rx_valid) {
-			DPRINTF(sc, IWN_DEBUG_ANY,
-			    "%s: missing AMPDU_RX_START\n", __func__);
-			ifp->if_ierrors++;
-			return;
-		}
-		sc->last_rx_valid = 0;
-		stat = &sc->last_rx_stat;
-	} else
-		stat = (struct iwn_rx_stat *)(desc + 1);
-
-	if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
-		device_printf(sc->sc_dev,
-		    "%s: invalid rx statistic header, len %d\n",
-		    __func__, stat->cfg_phy_len);
-		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);
-	} 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) {
-		DPRINTF(sc, IWN_DEBUG_RECV, "%s: rx flags error %x\n",
-		    __func__, le32toh(*tail));
-		ifp->if_ierrors++;
-		return;
-	}
-	if (len < sizeof (struct ieee80211_frame)) {
-		DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n",
-		    __func__, len);
-		ifp->if_ierrors++;
-		return;
-	}
-
-	/* XXX don't need mbuf, just dma buffer */
-	mnew = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
-	if (mnew == 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,
-	    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);
-		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;
-	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 = iwn_get_rssi(sc, stat);
-
-	/* 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;
-
-	if (ieee80211_radiotap_active(ic)) {
-		struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
-
-		tap->wr_tsft = htole64(stat->tstamp);
-		tap->wr_flags = 0;
-		if (stat->flags & htole16(IWN_CONFIG_SHPREAMBLE))
-			tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
-		tap->wr_rate = maprate(stat->rate);
-		tap->wr_dbm_antsignal = rssi;
-		tap->wr_dbm_antnoise = nf;
-	}
-
-	IWN_UNLOCK(sc);
-
-	/* send the frame to the 802.11 layer */
-	if (ni != NULL) {
-		(void) ieee80211_input(ni, m, rssi - nf, nf);
-		ieee80211_free_node(ni);
-	} else
-		(void) ieee80211_input_all(ic, m, rssi - nf, nf);
-
-	IWN_LOCK(sc);
-}
-
-void
-iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc)
-{
-	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);
-
-	/* 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);
-
-	/* test if temperature has changed */
-	if (stats->general.temp != sc->rawtemp) {
-		int temp;
-
-		sc->rawtemp = stats->general.temp;
-		temp = iwn_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);
-	}
-
-	if (desc->type != IWN_BEACON_STATISTICS)
-		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)) {
-		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);
-	else if (calib->state == IWN_CALIB_STATE_RUN)
-		iwn_tune_sensitivity(sc, &stats->rx);
-}
-
-void
-iwn_tx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
-{
-	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);
-
-	m = data->m, data->m = NULL;
-	ni = data->ni, data->ni = NULL;
-
-	if (m->m_flags & M_TXCB) {
-		/*
-		 * Channels marked for "radar" require traffic to be received
-		 * to unlock before we can transmit.  Until traffic is seen
-		 * any attempt to transmit is returned immediately with status
-		 * set to IWN_TX_FAIL_TX_LOCKED.  Unfortunately this can easily
-		 * happen on first authenticate after scanning.  To workaround
-		 * this we ignore a failure of this sort in AUTH state so the
-		 * 802.11 layer will fall back to using a timeout to wait for
-		 * the AUTH reply.  This allows the firmware time to see
-		 * traffic so a subsequent retry of AUTH succeeds.  It's
-		 * unclear why the firmware does not maintain state for
-		 * channels recently visited as this would allow immediate
-		 * use of the channel after a scan (where we see traffic).
-		 */
-		if (status == IWN_TX_FAIL_TX_LOCKED &&
-		    ni->ni_vap->iv_state == IEEE80211_S_AUTH)
-			ieee80211_process_callback(ni, m, 0);
-		else
-			ieee80211_process_callback(ni, m,
-			    (status & IWN_TX_FAIL) != 0);
-	}
-	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);
-}
-
-void
-iwn_cmd_intr(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 */
-
-	data = &ring->data[desc->idx];
-
-	/* if the command was mapped in a mbuf, free it */
-	if (data->m != NULL) {
-		bus_dmamap_unload(ring->data_dmat, data->map);
-		m_freem(data->m);
-		data->m = NULL;
-	}
-
-	wakeup(&ring->cmd[desc->idx]);
-}
-
-void
-iwn_notif_intr(struct iwn_softc *sc)
-{
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
-	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
-	uint16_t hw;
-
-	hw = le16toh(sc->shared->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;
-
-		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,
-		    desc->type, iwn_intr_str(desc->type),
-		    le16toh(desc->len));
-
-		if (!(desc->qid & 0x80))	/* reply to a command */
-			iwn_cmd_intr(sc, desc);
-
-		switch (desc->type) {
-		case IWN_RX_DONE:
-		case IWN_AMPDU_RX_DONE:
-			iwn_rx_intr(sc, desc, data);
-			break;
-
-		case IWN_AMPDU_RX_START:
-			iwn_ampdu_rx_start(sc, desc);
-			break;
-
-		case IWN_TX_DONE:
-			/* a 802.11 frame has been transmitted */
-			iwn_tx_intr(sc, desc);
-			break;
-
-		case IWN_RX_STATISTICS:
-		case IWN_BEACON_STATISTICS:
-			iwn_rx_statistics(sc, desc);
-			break;
-
-		case IWN_BEACON_MISSED: {
-			struct iwn_beacon_missed *miss =
-			    (struct iwn_beacon_missed *)(desc + 1);
-			int misses = le32toh(miss->consecutive);
-
-			/* 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.
-			 */
-			if (vap->iv_state == IEEE80211_S_RUN && misses > 5)
-				(void) iwn_init_sensitivity(sc);
-			if (misses >= vap->iv_bmissthreshold)
-				ieee80211_beacon_miss(ic);
-			break;
-		}
-		case IWN_UC_READY: {
-			struct iwn_ucode_info *uc =
-			    (struct iwn_ucode_info *)(desc + 1);
-
-			/* the microcontroller is ready */
-			DPRINTF(sc, IWN_DEBUG_RESET,
-			    "microcode alive notification version=%d.%d "
-			    "subtype=%x alive=%x\n", uc->major, uc->minor,
-			    uc->subtype, le32toh(uc->valid));
-
-			if (le32toh(uc->valid) != 1) {
-				device_printf(sc->sc_dev,
-				"microcontroller initialization failed");
-				break;
-			}
-			if (uc->subtype == IWN_UCODE_INIT) {
-				/* save microcontroller's report */
-				memcpy(&sc->ucode_info, uc, sizeof (*uc));
-			}
-			break;
-		}
-		case IWN_STATE_CHANGED: {
-			uint32_t *status = (uint32_t *)(desc + 1);
-
-			/*
-			 * State change allows hardware switch change to be
-			 * 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: {
-			struct iwn_start_scan *scan =
-			    (struct iwn_start_scan *)(desc + 1);
-
-			DPRINTF(sc, IWN_DEBUG_ANY,
-			    "%s: scanning channel %d status %x\n",
-			    __func__, scan->chan, le32toh(scan->status));
-			break;
-		}
-		case IWN_STOP_SCAN: {
-			struct iwn_stop_scan *scan =
-			    (struct iwn_stop_scan *)(desc + 1);
-
-			DPRINTF(sc, IWN_DEBUG_STATE,
-			    "scan finished nchan=%d status=%d chan=%d\n",
-			    scan->nchan, scan->status, scan->chan);
-
-			ieee80211_scan_next(vap);
-			break;
-		}
-		}
-		sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
-	}
-
-	/* 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);
-}
-
-static 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);
-
-	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)
-		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)
-{
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
-	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
-
-	IWN_LOCK_ASSERT(sc);
-
-	device_printf(sc->sc_dev, "error, INTR=%b STATUS=0x%x\n",
-	    r1, IWN_INTR_BITS, r2);
-	if (vap != NULL)
-		ieee80211_cancel_scan(vap);
-	ieee80211_runtask(ic, &sc->sc_reinit_task);
-}
-
-void
-iwn_intr(void *arg)
-{
-	struct iwn_softc *sc = arg;
-	uint32_t r1, r2;
-
-	IWN_LOCK(sc);
-
-	/* 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);
-
-	DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
-
-	if (r1 & IWN_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);
-		goto done;
-	}
-	if ((r1 & (IWN_RX_INTR | IWN_SW_RX_INTR)) || (r2 & IWN_RX_STATUS_INTR))
-		iwn_notif_intr(sc);
-	if (r1 & IWN_ALIVE_INTR)
-		wakeup(sc);
-
-	/* re-enable interrupts */
-	IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
-done:
-	IWN_UNLOCK(sc);
-}
-
-uint8_t
-iwn_plcp_signal(int rate)
-{
-	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;
-
-	/* 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;
-}
-
-/* determine if a given rate is CCK or OFDM */
-#define IWN_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
-
-int
-iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
-    struct iwn_tx_ring *ring)
-{
-	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_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 mbuf *mnew;
-	int rate, error, pad, nsegs, i, ismcast, id;
-	bus_dma_segment_t segs[IWN_MAX_SCATTER];
-
-	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);
-	hdrlen = ieee80211_anyhdrsize(wh);
-
-	/* pick a tx rate */
-	/* XXX ni_chan */
-	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
-	if (type == IEEE80211_FC0_TYPE_MGT)
-		rate = tp->mgmtrate;
-	else if (ismcast)
-		rate = tp->mcastrate;
-	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
-		rate = tp->ucastrate;
-	else {
-		(void) ieee80211_amrr_choose(ni, &IWN_NODE(ni)->amn);
-		rate = ni->ni_txrate;
-	}
-
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
-		k = ieee80211_crypto_encap(ni, m0);
-		if (k == NULL) {
-			m_freem(m0);
-			return ENOBUFS;
-		}
-		/* packet header may have moved, reset our local pointer */
-		wh = mtod(m0, struct ieee80211_frame *);
-	} else
-		k = NULL;
-
-	if (ieee80211_radiotap_active_vap(vap)) {
-		struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
-
-		tap->wt_flags = 0;
-		tap->wt_rate = rate;
-		if (k != NULL)
-			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
-
-		ieee80211_radiotap_tx(vap, m0);
-	}
-
-	flags = IWN_TX_AUTO_SEQ;
-	/* XXX honor ACM */
-	if (!ismcast)
-		flags |= IWN_TX_NEED_ACK;
-
-	if (ismcast || type != IEEE80211_FC0_TYPE_DATA)
-		id = IWN_ID_BROADCAST;
-	else
-		id = IWN_ID_BSS;
-
-	/* 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;
-		} 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;
-			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
-				flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
-		}
-	}
-
-	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 */
-		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);
-		else
-			timeout = htole16(2);
-	} else
-		timeout = htole16(0);
-
-	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;
-
-	desc = &ring->desc[ring->cur];
-	data = &ring->data[ring->cur];
-
-	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 = 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;
-
-	if (k != NULL) {
-		/* XXX fill in */;
-	} else
-		tx->security = 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);
-	}
-
-	/* copy and trim IEEE802.11 header */
-	memcpy((uint8_t *)(tx + 1), wh, hdrlen);
-	m_adj(m0, hdrlen);
-
-	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;
-}
-
-void
-iwn_start(struct ifnet *ifp)
-{
-	struct iwn_softc *sc = ifp->if_softc;
-
-	IWN_LOCK(sc);
-	iwn_start_locked(ifp);
-	IWN_UNLOCK(sc);
-}
-
-void
-iwn_start_locked(struct ifnet *ifp)
-{
-	struct iwn_softc *sc = ifp->if_softc;
-	struct ieee80211_node *ni;
-	struct iwn_tx_ring *txq;
-	struct mbuf *m;
-	int pri;
-
-	IWN_LOCK_ASSERT(sc);
-
-	for (;;) {
-		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;
-		}
-	}
-}
-
-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)
-{
-	if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
-		struct ifnet *ifp = sc->sc_ifp;
-		struct ieee80211com *ic = ifp->if_l2com;
-
-		if_printf(ifp, "device timeout\n");
-		ieee80211_runtask(ic, &sc->sc_reinit_task);
-	}
-}
-
-int
-iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
-	struct iwn_softc *sc = ifp->if_softc;
-	struct ieee80211com *ic = ifp->if_l2com;
-	struct ifreq *ifr = (struct ifreq *) data;
-	int error = 0, startall = 0;
-
-	switch (cmd) {
-	case SIOCSIFFLAGS:
-		IWN_LOCK(sc);
-		if (ifp->if_flags & IFF_UP) {
-			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-				iwn_init_locked(sc);
-				startall = 1;
-			}
-		} else {
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-				iwn_stop_locked(sc);
-		}
-		IWN_UNLOCK(sc);
-		if (startall)
-			ieee80211_start_all(ic);
-		break;
-	case SIOCGIFMEDIA:
-		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
-		break;
-	case SIOCGIFADDR:
-		error = ether_ioctl(ifp, cmd, data);
-		break;
-	default:
-		error = EINVAL;
-		break;
-	}
-	return error;
-}
-
-void
 iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
 {
-	char domain[4];
+	const struct iwn_hal *hal = sc->sc_hal;
+	int error;
 	uint16_t val;
-	int i, error;
 
-	if ((error = iwn_eeprom_lock(sc)) != 0) {
+	/* 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");
+
+	/* Adapter has to be powered on for EEPROM access to work. */
+	error = iwn_apm_init(sc);
+	if (error != 0) {
 		device_printf(sc->sc_dev,
-		    "%s: could not lock EEPROM, error %d\n", __func__, error);
-		return;
+		    "%s: could not power ON adapter, error %d\n",
+		    __func__, error);
+		return error;
 	}
-	/* 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 */
+	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);
+		if (error != 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);
-	printf(", address %6D\n", macaddr, ":");
 
-	/* read the list of authorized channels */
-	iwn_read_eeprom_channels(sc);
+	/* Read adapter-specific information from EEPROM. */
+	hal->read_eeprom(sc);
 
-	/* read maximum allowed Tx power for 2GHz and 5GHz bands */
-	iwn_read_prom_data(sc, IWN_EEPROM_MAXPOW, &val, 2);
+	iwn_apm_stop(sc);	/* Power OFF adapter. */
+
+	iwn_eeprom_unlock(sc);
+	return 0;
+}
+
+void
+iwn4965_read_eeprom(struct iwn_softc *sc)
+{
+	uint32_t addr;
+	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 (20MHz ones only.) */
+	for (i = 0; i < 5; i++) {
+		addr = iwn4965_regulatory_bands[i];
+		iwn_read_eeprom_channels(sc, i, addr);
+	}
+
+	/* 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 correct */
+	/* 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)
@@ -2445,42 +1557,135 @@ iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
 	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);
+	/* 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);
 
-	/* read power groups */
-	iwn_read_prom_data(sc, IWN_EEPROM_BANDS, sc->bands, sizeof sc->bands);
 #ifdef IWN_DEBUG
+	/* Print samples. */
 	if (sc->sc_debug & IWN_DEBUG_ANY) {
 		for (i = 0; i < IWN_NBANDS; i++)
-			iwn_print_power_group(sc, i);
+			iwn4965_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];
-};
+#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;
+	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 (20MHz ones only.) */
+	for (i = 0; i < 5; i++) {
+		addr = base + iwn5000_regulatory_bands[i];
+		iwn_read_eeprom_channels(sc, i, addr);
+	}
+
+	/* Read enhanced TX power information for 6000 Series. */
+	if (sc->hw_type >= IWN_HW_REV_TYPE_6000)
+		iwn_read_eeprom_enhinfo(sc);
+
+	iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
+	base = le16toh(val);
+	if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
+		/* Compute temperature offset. */
+		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);
+		sc->temp_off = temp - (volt / -5);
+		DPRINTF(sc, IWN_DEBUG_CALIBRATE, "temp=%d volt=%d offset=%dK\n",
+		    temp, volt, sc->temp_off);
+	} 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));
+	}
+}
+
+/*
+ * Translate EEPROM flags to net80211.
+ */
+static uint32_t
+iwn_eeprom_channel_flags(struct iwn_eeprom_chan *channel)
+{
+	uint32_t nflags;
+
+	nflags = 0;
+	if ((channel->flags & IWN_EEPROM_CHAN_ACTIVE) == 0)
+		nflags |= IEEE80211_CHAN_PASSIVE;
+	if ((channel->flags & IWN_EEPROM_CHAN_IBSS) == 0)
+		nflags |= IEEE80211_CHAN_NOADHOC;
+	if (channel->flags & IWN_EEPROM_CHAN_RADAR) {
+		nflags |= IEEE80211_CHAN_DFS;
+		/* XXX apparently IBSS may still be marked */
+		nflags |= IEEE80211_CHAN_NOADHOC;
+	}
+
+	return nflags;
+}
 
 static void
-iwn_read_eeprom_band(struct iwn_softc *sc, const struct iwn_chan_band *band)
+iwn_read_eeprom_band(struct iwn_softc *sc, int n)
 {
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
-	struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
+	struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
+	const struct iwn_chan_band *band = &iwn_bands[n];
 	struct ieee80211_channel *c;
-	int i, chan, flags;
-
-	iwn_read_prom_data(sc, band->addr, channels,
-	    band->nchan * sizeof (struct iwn_eeprom_chan));
+	int i, chan, nflags;
 
 	for (i = 0; i < band->nchan; i++) {
 		if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
@@ -2491,18 +1696,7 @@ iwn_read_eeprom_band(struct iwn_softc *sc, const struct iwn_chan_band *band)
 			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;
-		}
+		nflags = iwn_eeprom_channel_flags(&channels[i]);
 
 		DPRINTF(sc, IWN_DEBUG_RESET,
 		    "add chan %d flags 0x%x maxpwr %d\n",
@@ -2510,40 +1704,46 @@ iwn_read_eeprom_band(struct iwn_softc *sc, const struct iwn_chan_band *band)
 
 		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) {
+		if (n == 0) {	/* 2GHz band */
+			c->ic_freq = ieee80211_ieee2mhz(chan,
+			    IEEE80211_CHAN_G);
+
 			/* G =>'s B is supported */
-			c->ic_flags = IEEE80211_CHAN_B | flags;
+			c->ic_flags = IEEE80211_CHAN_B | nflags;
 
 			c = &ic->ic_channels[ic->ic_nchans++];
 			c[0] = c[-1];
-			c->ic_flags = IEEE80211_CHAN_G | flags;
+			c->ic_flags = IEEE80211_CHAN_G | nflags;
 		} else {	/* 5GHz band */
-			c->ic_flags = IEEE80211_CHAN_A | flags;
+			c->ic_freq = ieee80211_ieee2mhz(chan,
+			    IEEE80211_CHAN_A);
+			c->ic_flags = IEEE80211_CHAN_A | nflags;
+			sc->sc_flags |= IWN_FLAG_HAS_5GHZ;
 		}
+#if 0	/* HT */
 		/* 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? */
+#endif
 	}
 }
 
+#if 0	/* HT */
 static void
-iwn_read_eeprom_ht40(struct iwn_softc *sc, const struct iwn_chan_band *band)
+iwn_read_eeprom_ht40(struct iwn_softc *sc, int n)
 {
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
-	struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
+	struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
+	const struct iwn_chan_band *band = &iwn_bands[n];
 	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)) {
@@ -2590,75 +1790,1592 @@ iwn_read_eeprom_ht40(struct iwn_softc *sc, const struct iwn_chan_band *band)
 		c->ic_flags |= IEEE80211_CHAN_HT40D;
 	}
 }
+#endif
 
 static void
-iwn_read_eeprom_channels(struct iwn_softc *sc)
+iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
 {
-#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;
+
+	iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n],
+	    iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan));
+
+	if (n < 5)
+		iwn_read_eeprom_band(sc, n);
+#if 0	/* HT */
+	else
+		iwn_read_eeprom_ht40(sc, n);
+#endif
+	ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
+}
+
+#define nitems(_a)	(sizeof((_a)) / sizeof((_a)[0]))
+
+void
+iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
+{
+	struct iwn_eeprom_enhinfo enhinfo[35];
+	uint16_t val, base;
+	int8_t maxpwr;
 	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
+	iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
+	base = le16toh(val);
+	iwn_read_prom_data(sc, base + IWN6000_EEPROM_ENHINFO,
+	    enhinfo, sizeof enhinfo);
+
+	memset(sc->enh_maxpwr, 0, sizeof sc->enh_maxpwr);
+	for (i = 0; i < nitems(enhinfo); i++) {
+		if (enhinfo[i].chan == 0 || enhinfo[i].reserved != 0)
+			continue;	/* Skip invalid entries. */
+
+		maxpwr = 0;
+		if (sc->txchainmask & IWN_ANT_A)
+			maxpwr = MAX(maxpwr, enhinfo[i].chain[0]);
+		if (sc->txchainmask & IWN_ANT_B)
+			maxpwr = MAX(maxpwr, enhinfo[i].chain[1]);
+		if (sc->txchainmask & IWN_ANT_C)
+			maxpwr = MAX(maxpwr, enhinfo[i].chain[2]);
+		if (sc->ntxchains == 2)
+			maxpwr = MAX(maxpwr, enhinfo[i].mimo2);
+		else if (sc->ntxchains == 3)
+			maxpwr = MAX(maxpwr, enhinfo[i].mimo3);
+		maxpwr /= 2;	/* Convert half-dBm to dBm. */
+
+		DPRINTF(sc, IWN_DEBUG_RESET, "enhinfo %d, maxpwr=%d\n", i,
+		    maxpwr);
+		sc->enh_maxpwr[i] = maxpwr;
+	}
 }
 
-#ifdef IWN_DEBUG
-void
-iwn_print_power_group(struct iwn_softc *sc, int i)
+struct ieee80211_node *
+iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
 {
-	struct iwn_eeprom_band *band = &sc->bands[i];
-	struct iwn_eeprom_chan_samples *chans = band->chans;
-	int j, c;
+	return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
+}
 
-	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);
-		}
+void
+iwn_newassoc(struct ieee80211_node *ni, int isnew)
+{
+	struct ieee80211vap *vap = ni->ni_vap;
+	struct iwn_node *wn = (void *)ni;
+
+	ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
+	    &wn->amn, ni);
+}
+
+int
+iwn_media_change(struct ifnet *ifp)
+{
+	int error = ieee80211_media_change(ifp);
+	/* NB: only the fixed rate can change and that doesn't need a reset */
+	return (error == ENETRESET ? 0 : error);
+}
+
+int
+iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
+{
+	struct iwn_vap *ivp = IWN_VAP(vap);
+	struct ieee80211com *ic = vap->iv_ic;
+	struct iwn_softc *sc = ic->ic_ifp->if_softc;
+	int error;
+
+	DPRINTF(sc, IWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
+		ieee80211_state_name[vap->iv_state],
+		ieee80211_state_name[nstate]);
+
+	IEEE80211_UNLOCK(ic);
+	IWN_LOCK(sc);
+	callout_stop(&sc->sc_timer_to);
+
+	if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) {
+		/* !AUTH -> AUTH requires adapter config */
+		/* 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);
 	}
-	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);
-		}
+	if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
+		/*
+		 * !RUN -> RUN requires setting the association id
+		 * which is done with a firmware cmd.  We also defer
+		 * starting the timers until that work is done.
+		 */
+		error = iwn_run(sc, vap);
 	}
+	if (nstate == IEEE80211_S_RUN) {
+		/*
+		 * RUN -> RUN transition; just restart the timers.
+		 */
+		iwn_calib_reset(sc);
+	}
+	IWN_UNLOCK(sc);
+	IEEE80211_LOCK(ic);
+	return ivp->iv_newstate(vap, nstate, arg);
+}
+
+/*
+ * Process an RX_PHY firmware notification.  This is usually immediately
+ * followed by an MPDU_RX_DONE notification.
+ */
+void
+iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc,
+    struct iwn_rx_data *data)
+{
+	struct iwn_rx_stat *stat = (struct iwn_rx_stat *)(desc + 1);
+
+	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: received PHY stats\n", __func__);
+
+	/* 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
+iwn_timer_timeout(void *arg)
+{
+	struct iwn_softc *sc = arg;
+	uint32_t flags = 0;
+
+	IWN_LOCK_ASSERT(sc);
+
+	if (sc->calib_cnt && --sc->calib_cnt == 0) {
+		DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",
+		    "send statistics request");
+		(void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags,
+		    sizeof flags, 1);
+		sc->calib_cnt = 60;	/* do calibration every 60s */
+	}
+	iwn_watchdog(sc);		/* NB: piggyback tx watchdog */
+	callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
+}
+
+static void
+iwn_calib_reset(struct iwn_softc *sc)
+{
+	callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
+	sc->calib_cnt = 60;		/* do calibration every 60s */
+}
+
+/*
+ * 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_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, *m1;
+	struct iwn_rx_stat *stat;
+	caddr_t head;
+	bus_addr_t paddr;
+	uint32_t flags;
+	int error, len, rssi, nf;
+
+	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 RX_PHY\n", __func__);
+			ifp->if_ierrors++;
+			return;
+		}
+		sc->last_rx_valid = 0;
+		stat = &sc->last_rx_stat;
+	} else
+		stat = (struct iwn_rx_stat *)(desc + 1);
+
+	bus_dmamap_sync(ring->data_dmat, 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",
+		    __func__, stat->cfg_phy_len);
+		ifp->if_ierrors++;
+		return;
+	}
+	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);
+	}
+
+	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__, flags);
+		ifp->if_ierrors++;
+		return;
+	}
+	/* 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++;
+		return;
+	}
+
+	/* XXX don't need mbuf, just dma buffer */
+	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;
+	}
+	bus_dmamap_unload(ring->data_dmat, data->map);
+
+	error = bus_dmamap_load(ring->data_dmat, 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(m1);
+		ifp->if_ierrors++;
+		return;
+	}
+
+	m = data->m;
+	data->m = m1;
+	/* Update RX descriptor. */
+	ring->desc[ring->cur] = htole32(paddr >> 8);
+	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+
+	/* Finalize mbuf. */
+	m->m_pkthdr.rcvif = ifp;
+	m->m_data = head;
+	m->m_pkthdr.len = m->m_len = len;
+
+	rssi = hal->get_rssi(sc, stat);
+
+	/* 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;
+
+	if (ieee80211_radiotap_active(ic)) {
+		struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
+
+		tap->wr_tsft = htole64(stat->tstamp);
+		tap->wr_flags = 0;
+		if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
+			tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+		switch (stat->rate) {
+		/* CCK rates. */
+		case  10: tap->wr_rate =   2; break;
+		case  20: tap->wr_rate =   4; break;
+		case  55: tap->wr_rate =  11; break;
+		case 110: tap->wr_rate =  22; break;
+		/* OFDM rates. */
+		case 0xd: tap->wr_rate =  12; break;
+		case 0xf: tap->wr_rate =  18; break;
+		case 0x5: tap->wr_rate =  24; break;
+		case 0x7: tap->wr_rate =  36; break;
+		case 0x9: tap->wr_rate =  48; break;
+		case 0xb: tap->wr_rate =  72; break;
+		case 0x1: tap->wr_rate =  96; break;
+		case 0x3: tap->wr_rate = 108; break;
+		/* Unknown rate: should not happen. */
+		default:  tap->wr_rate =   0;
+		}
+		tap->wr_dbm_antsignal = rssi;
+		tap->wr_dbm_antnoise = nf;
+	}
+
+	IWN_UNLOCK(sc);
+
+	/* 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);
+
+	IWN_LOCK(sc);
+}
+
+#if 0	/* HT */
+/* Process an incoming Compressed BlockAck. */
+void
+iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
+    struct iwn_rx_data *data)
+{
+	struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1);
+	struct iwn_tx_ring *txq;
+
+	txq = &sc->txq[letoh16(ba->qid)];
+	/* XXX TBD */
 }
 #endif
 
+/*
+ * Process a CALIBRATION_RESULT notification sent by the initialization
+ * firmware on response to a CMD_CALIB_CONFIG command (5000 only.)
+ */
+void
+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_CALIB_DONE)
+		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_PERIODIC:
+		if (sc->hw_type < IWN_HW_REV_TYPE_6000 &&
+		    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. */
+	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);	/* Reset TX power calibration timeout. */
+
+	/* Test if temperature has changed. */
+	if (stats->general.temp != sc->rawtemp) {
+		/* Convert "raw" temperature to degC. */
+		sc->rawtemp = stats->general.temp;
+		temp = hal->get_temperature(sc);
+		DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d\n",
+		    __func__, 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. */
+
+	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 (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_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
+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->ackfailcnt,
+	    stat->btkillcnt, stat->rate, le16toh(stat->duration),
+	    le32toh(stat->status));
+
+	iwn_tx_done(sc, desc, stat->ackfailcnt, 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->ackfailcnt,
+	    stat->btkillcnt, stat->rate, le16toh(stat->duration),
+	    le32toh(stat->status));
+
+#ifdef notyet
+	/* Reset TX scheduler slot. */
+	iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
+#endif
+	iwn_tx_done(sc, desc, stat->ackfailcnt, 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 ackfailcnt,
+    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_node *wn = (void *)data->ni;
+	struct mbuf *m;
+	struct ieee80211_node *ni;
+
+	KASSERT(data->ni != NULL, ("no node"));
+
+	/* Unmap and free mbuf. */
+	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTWRITE);
+	bus_dmamap_unload(ring->data_dmat, data->map);
+	m = data->m, data->m = NULL;
+	ni = data->ni, data->ni = NULL;
+
+	if (m->m_flags & M_TXCB) {
+		/*
+		 * Channels marked for "radar" require traffic to be received
+		 * to unlock before we can transmit.  Until traffic is seen
+		 * any attempt to transmit is returned immediately with status
+		 * set to IWN_TX_FAIL_TX_LOCKED.  Unfortunately this can easily
+		 * happen on first authenticate after scanning.  To workaround
+		 * this we ignore a failure of this sort in AUTH state so the
+		 * 802.11 layer will fall back to using a timeout to wait for
+		 * the AUTH reply.  This allows the firmware time to see
+		 * traffic so a subsequent retry of AUTH succeeds.  It's
+		 * unclear why the firmware does not maintain state for
+		 * channels recently visited as this would allow immediate
+		 * use of the channel after a scan (where we see traffic).
+		 */
+		if (status == IWN_TX_FAIL_TX_LOCKED &&
+		    ni->ni_vap->iv_state == IEEE80211_S_AUTH)
+			ieee80211_process_callback(ni, m, 0);
+		else
+			ieee80211_process_callback(ni, m,
+			    (status & IWN_TX_FAIL) != 0);
+	}
+
+	/*
+	 * Update rate control statistics for the node.
+	 */
+	if (status & 0x80) {
+		ifp->if_oerrors++;
+		ieee80211_amrr_tx_complete(&wn->amn,
+		    IEEE80211_AMRR_FAILURE, ackfailcnt);
+	} else {
+		ieee80211_amrr_tx_complete(&wn->amn,
+		    IEEE80211_AMRR_SUCCESS, ackfailcnt);
+	}
+	m_freem(m);
+	ieee80211_free_node(ni);
+
+	sc->sc_tx_timer = 0;
+	if (--ring->queued < IWN_TX_RING_LOMARK) {
+		sc->qfullmsk &= ~(1 << ring->qid);
+		if (sc->qfullmsk == 0 &&
+		    (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
+			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_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. */
+
+	data = &ring->data[desc->idx];
+
+	/* If the command was mapped in an mbuf, free it. */
+	if (data->m != NULL) {
+		bus_dmamap_unload(ring->data_dmat, data->map);
+		m_freem(data->m);
+		data->m = NULL;
+	}
+	wakeup(&ring->desc[desc->idx]);
+}
+
+/*
+ * Process an INT_FH_RX or INT_SW_RX interrupt.
+ */
+void
+iwn_notif_intr(struct iwn_softc *sc)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+	uint16_t hw;
+
+	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;
+
+		bus_dmamap_sync(sc->rxq.data_dmat, data->map,
+		    BUS_DMASYNC_POSTREAD);
+		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 & 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_done(sc, desc);
+
+		switch (desc->type) {
+		case IWN_RX_PHY:
+			iwn_rx_phy(sc, desc, data);
+			break;
+
+		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;
+
+#if 0	/* HT */
+		case IWN_RX_COMPRESSED_BA:
+			/* A Compressed BlockAck has been received. */
+			iwn_rx_compressed_ba(sc, desc, data);
+			break;
+#endif
+
+		case IWN_TX_DONE:
+			/* 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, data);
+			break;
+
+		case IWN_BEACON_MISSED:
+		{
+			struct iwn_beacon_missed *miss =
+			    (struct iwn_beacon_missed *)(desc + 1);
+			int misses = le32toh(miss->consecutive);
+
+			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
+			    BUS_DMASYNC_POSTREAD);
+
+			/* 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.
+			 */
+			if (vap->iv_state == IEEE80211_S_RUN && misses > 5)
+				(void) iwn_init_sensitivity(sc);
+			if (misses >= vap->iv_bmissthreshold) {
+				IWN_UNLOCK(sc);
+				ieee80211_beacon_miss(ic);
+				IWN_LOCK(sc);
+			}
+			break;
+		}
+		case IWN_UC_READY:
+		{
+			struct iwn_ucode_info *uc =
+			    (struct iwn_ucode_info *)(desc + 1);
+
+			/* The microcontroller is ready. */
+			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
+			    BUS_DMASYNC_POSTREAD);
+			DPRINTF(sc, IWN_DEBUG_RESET,
+			    "microcode alive notification version=%d.%d "
+			    "subtype=%x alive=%x\n", uc->major, uc->minor,
+			    uc->subtype, le32toh(uc->valid));
+
+			if (le32toh(uc->valid) != 1) {
+				device_printf(sc->sc_dev,
+				    "microcontroller initialization failed");
+				break;
+			}
+			if (uc->subtype == IWN_UCODE_INIT) {
+				/* Save microcontroller 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:
+		{
+			uint32_t *status = (uint32_t *)(desc + 1);
+
+			/*
+			 * State change allows hardware switch change to be
+			 * noted. However, we handle this in iwn_intr as we
+			 * get both the enable/disble intr.
+			 */
+			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
+			    BUS_DMASYNC_POSTREAD);
+			DPRINTF(sc, IWN_DEBUG_INTR, "state changed to %x\n",
+			    le32toh(*status));
+			break;
+		}
+		case IWN_START_SCAN:
+		{
+			struct iwn_start_scan *scan =
+			    (struct iwn_start_scan *)(desc + 1);
+
+			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
+			    BUS_DMASYNC_POSTREAD);
+			DPRINTF(sc, IWN_DEBUG_ANY,
+			    "%s: scanning channel %d status %x\n",
+			    __func__, scan->chan, le32toh(scan->status));
+			break;
+		}
+		case IWN_STOP_SCAN:
+		{
+			struct iwn_stop_scan *scan =
+			    (struct iwn_stop_scan *)(desc + 1);
+
+			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
+			    BUS_DMASYNC_POSTREAD);
+			DPRINTF(sc, IWN_DEBUG_STATE,
+			    "scan finished nchan=%d status=%d chan=%d\n",
+			    scan->nchan, scan->status, scan->chan);
+
+			IWN_UNLOCK(sc);
+			ieee80211_scan_next(vap);
+			IWN_LOCK(sc);
+			break;
+		}
+		case IWN5000_CALIBRATION_RESULT:
+			iwn5000_rx_calib_results(sc, desc, data);
+			break;
+
+		case IWN5000_CALIBRATION_DONE:
+			sc->sc_flags |= IWN_FLAG_CALIB_DONE;
+			wakeup(sc);
+			break;
+		}
+
+		sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
+	}
+
+	/* Tell the firmware what we have processed. */
+	hw = (hw == 0) ? IWN_RX_RING_COUNT - 1 : hw - 1;
+	IWN_WRITE(sc, IWN_FH_RX_WPTR, hw & ~7);
+}
+
+/*
+ * 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 < sc->sc_hal->ntxqs; 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_GP_CNTRL);
+
+	IWN_LOCK_ASSERT(sc);
+
+	device_printf(sc->sc_dev, "RF switch: radio %s\n",
+	    (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);
+}
+
+/*
+ * 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)
+{
+	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_fw_dump dump;
+	int i;
+
+	IWN_LOCK_ASSERT(sc);
+
+	/* Force a complete recalibration on next init. */
+	sc->sc_flags &= ~IWN_FLAG_CALIB_DONE;
+
+	/* 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);
+}
+
+void
+iwn_intr(void *arg)
+{
+	struct iwn_softc *sc = arg;
+	struct ifnet *ifp = sc->sc_ifp;
+	uint32_t r1, r2, tmp;
+
+	IWN_LOCK(sc);
+
+	/* Disable interrupts. */
+	IWN_WRITE(sc, IWN_INT_MASK, 0);
+
+	/* Read interrupts from ICT (fast) or from registers (slow). */
+	if (sc->sc_flags & IWN_FLAG_USE_ICT) {
+		tmp = 0;
+		while (sc->ict[sc->ict_cur] != 0) {
+			tmp |= sc->ict[sc->ict_cur];
+			sc->ict[sc->ict_cur] = 0;	/* Acknowledge. */
+			sc->ict_cur = (sc->ict_cur + 1) % IWN_ICT_COUNT;
+		}
+		tmp = le32toh(tmp);
+		if (tmp == 0xffffffff)
+			tmp = 0;	/* Shouldn't happen. */
+		r1 = (tmp & 0xff00) << 16 | (tmp & 0xff);
+		r2 = 0;	/* Unused. */
+	} else {
+		r1 = IWN_READ(sc, IWN_INT);
+		if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
+			return;	/* Hardware gone! */
+		r2 = IWN_READ(sc, IWN_FH_INT);
+	}
+
+	DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
+
+	if (r1 == 0 && r2 == 0)
+		goto done;	/* Interrupt not for us. */
+
+	/* Acknowledge interrupts. */
+	IWN_WRITE(sc, IWN_INT, r1);
+	if (!(sc->sc_flags & IWN_FLAG_USE_ICT))
+		IWN_WRITE(sc, IWN_FH_INT, r2);
+
+	if (r1 & IWN_INT_RF_TOGGLED) {
+		iwn_rftoggle_intr(sc);
+		goto done;
+	}
+	if (r1 & IWN_INT_CT_REACHED) {
+		device_printf(sc->sc_dev, "%s: critical temperature reached!\n",
+		    __func__);
+	}
+	if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) {
+		iwn_fatal_intr(sc);
+		ifp->if_flags &= ~IFF_UP;
+		iwn_stop_locked(sc);
+		goto done;
+	}
+	if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX | IWN_INT_RX_PERIODIC)) ||
+	    (r2 & IWN_FH_INT_RX)) {
+		if (sc->sc_flags & IWN_FLAG_USE_ICT) {
+			if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX))
+				IWN_WRITE(sc, IWN_FH_INT, IWN_FH_INT_RX);
+			IWN_WRITE_1(sc, IWN_INT_PERIODIC,
+			    IWN_INT_PERIODIC_DIS);
+			iwn_notif_intr(sc);
+			if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX)) {
+				IWN_WRITE_1(sc, IWN_INT_PERIODIC,
+				    IWN_INT_PERIODIC_ENA);
+			}
+		} else
+			iwn_notif_intr(sc);
+	}
+
+	if ((r1 & IWN_INT_FH_TX) || (r2 & IWN_FH_INT_TX)) {
+		if (sc->sc_flags & IWN_FLAG_USE_ICT)
+			IWN_WRITE(sc, IWN_FH_INT, 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);
+
+done:
+	/* Re-enable interrupts. */
+	if (ifp->if_flags & IFF_UP)
+		IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
+
+	IWN_UNLOCK(sc);
+}
+
+/*
+ * 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)
+{
+	uint16_t *w = &sc->sched[qid * IWN4965_SCHED_COUNT + idx];
+
+	*w = htole16(len + 8);
+	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
+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));
+
+	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
+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);
+	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);
+	}
+}
+
+static uint8_t
+iwn_plcp_signal(int rate) {
+	int i;
+
+	for (i = 0; i < IWN_RIDX_MAX + 1; i++) {
+		if (rate == iwn_rates[i].rate)
+			return i;
+	}
+
+	return 0;
+}
+
+int
+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 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 = NULL;
+	struct mbuf *mnew;
+	bus_dma_segment_t segs[IWN_MAX_SCATTER];
+	uint32_t flags;
+	u_int hdrlen;
+	int totlen, error, pad, nsegs = 0, i, rate;
+	uint8_t ridx, type, txant;
+
+	IWN_LOCK_ASSERT(sc);
+
+	wh = mtod(m, 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. */
+	tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
+	if (type == IEEE80211_FC0_TYPE_MGT)
+		rate = tp->mgmtrate;
+	else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
+		rate = tp->mcastrate;
+	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
+		rate = tp->ucastrate;
+	else {
+		(void) ieee80211_amrr_choose(ni, &wn->amn);
+		rate = ni->ni_txrate;
+	}
+	ridx = iwn_plcp_signal(rate);
+	rinfo = &iwn_rates[ridx];
+
+	/* Encrypt the frame if need be. */
+	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+		k = ieee80211_crypto_encap(ni, m);
+		if (k == NULL) {
+			m_freem(m);
+			return ENOBUFS;
+		}
+		/* 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;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rinfo->rate;
+		if (k != NULL)
+			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
+
+		ieee80211_radiotap_tx(vap, m);
+	}
+
+	/* 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 (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
+		flags |= IWN_TX_MORE_FRAG;	/* Cannot happen yet. */
+
+	/* 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) &&
+		    ridx >= IWN_RIDX_OFDM6) {
+			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
+				flags |= IWN_TX_NEED_CTS;
+			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
+				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;
+		}
+	}
+
+	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 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)
+			tx->timeout = htole16(3);
+		else
+			tx->timeout = htole16(2);
+	} else
+		tx->timeout = htole16(0);
+
+	if (hdrlen & 3) {
+		/* First segment 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;
+	tx->data_ntries = 15;
+	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
+	tx->plcp = rinfo->plcp;
+	tx->rflags = rinfo->flags;
+	if (tx->id == hal->broadcast_id) {
+		/* Group or management frame. */
+		tx->linkq = 0;
+		/* XXX Alternate between antenna A and B? */
+		txant = IWN_LSB(sc->txchainmask);
+		tx->rflags |= IWN_RFLAG_ANT(txant);
+	} else {
+		tx->linkq = 0;
+		flags |= IWN_TX_LINKQ;	/* enable MRR */
+	}
+
+	/* Set physical address of "scratch area". */
+	tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
+	tx->hiaddr = IWN_HIADDR(data->scratch_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);
+
+	if (m->m_len > 0) {
+		error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map,
+		    m, segs, &nsegs, BUS_DMA_NOWAIT);
+		if (error == EFBIG) {
+			/* too many fragments, linearize */
+			mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
+			if (mnew == NULL) {
+				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->data_dmat,
+			    data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
+		}
+		if (error != 0) {
+			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(data->cmd_paddr));
+	desc->segs[0].len  = htole16(IWN_HIADDR(data->cmd_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->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(ring->data_dmat, ring->cmd_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+
+#ifdef notyet
+	/* Update TX scheduler. */
+	hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
+#endif
+
+	/* 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 *m,
+    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 = 0, i, rate;
+	uint8_t ridx, type, txant;
+
+	IWN_LOCK_ASSERT(sc);
+
+	wh = mtod(m, 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(m);
+		return EINVAL;
+	}
+	ridx = iwn_plcp_signal(rate);
+	rinfo = &iwn_rates[ridx];
+
+	totlen = m->m_pkthdr.len;
+
+	/* 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 ((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->timeout = htole16(0);
+
+	if (hdrlen & 3) {
+		/* First segment 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, m);
+	}
+
+	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;
+	/* Group or management frame. */
+	tx->linkq = 0;
+	txant = IWN_LSB(sc->txchainmask);
+	tx->rflags |= IWN_RFLAG_ANT(txant);
+	/* 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);
+
+	if (m->m_len > 0) {
+		error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map,
+		    m, segs, &nsegs, BUS_DMA_NOWAIT);
+		if (error == EFBIG) {
+			/* Too many fragments, linearize. */
+			mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
+			if (mnew == NULL) {
+				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->data_dmat,
+			    data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
+		}
+		if (error != 0) {
+			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(data->cmd_paddr));
+	desc->segs[0].len  = htole16(IWN_HIADDR(data->cmd_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->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(ring->data_dmat, ring->cmd_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
+	    BUS_DMASYNC_PREWRITE);
+
+#ifdef notyet
+	/* Update TX scheduler. */
+	hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
+#endif
+
+	/* 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_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)
+{
+	struct iwn_softc *sc = ifp->if_softc;
+
+	IWN_LOCK(sc);
+	iwn_start_locked(ifp);
+	IWN_UNLOCK(sc);
+}
+
+void
+iwn_start_locked(struct ifnet *ifp)
+{
+	struct iwn_softc *sc = ifp->if_softc;
+	struct ieee80211_node *ni;
+	struct iwn_tx_ring *txq;
+	struct mbuf *m;
+	int pri;
+
+	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 (iwn_tx_data(sc, m, ni, txq) != 0) {
+			ifp->if_oerrors++;
+			ieee80211_free_node(ni);
+			break;
+		}
+		sc->sc_tx_timer = 5;
+	}
+}
+
+static void
+iwn_watchdog(struct iwn_softc *sc)
+{
+	if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
+		struct ifnet *ifp = sc->sc_ifp;
+		struct ieee80211com *ic = ifp->if_l2com;
+
+		if_printf(ifp, "device timeout\n");
+		ieee80211_runtask(ic, &sc->sc_reinit_task);
+	}
+}
+
+int
+iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	struct iwn_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+	struct ifreq *ifr = (struct ifreq *) data;
+	int error = 0, startall = 0, stop = 0;
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		IWN_LOCK(sc);
+		if (ifp->if_flags & IFF_UP) {
+			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+				iwn_init_locked(sc);
+				if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)
+					startall = 1;
+				else
+					stop = 1;
+			}
+		} else {
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+				iwn_stop_locked(sc);
+		}
+		IWN_UNLOCK(sc);
+		if (startall)
+			ieee80211_start_all(ic);
+		else if (vap != NULL && stop)
+			ieee80211_stop(vap);
+		break;
+	case SIOCGIFMEDIA:
+		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
+		break;
+	case SIOCGIFADDR:
+		error = ether_ioctl(ifp, cmd, data);
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	return error;
+}
+
 /*
  * Send a command to the firmware.
  */
@@ -2667,15 +3384,37 @@ iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
 {
 	struct iwn_tx_ring *ring = &sc->txq[4];
 	struct iwn_tx_desc *desc;
+	struct iwn_tx_data *data;
 	struct iwn_tx_cmd *cmd;
+	struct mbuf *m;
 	bus_addr_t paddr;
+	int totlen, error;
 
 	IWN_LOCK_ASSERT(sc);
 
-	KASSERT(size <= sizeof cmd->data, ("Command too big"));
-
 	desc = &ring->desc[ring->cur];
-	cmd = &ring->cmd[ring->cur];
+	data = &ring->data[ring->cur];
+	totlen = 4 + size;
+
+	if (size > sizeof cmd->data) {
+		/* Command is too large to fit in a descriptor. */
+		if (totlen > MCLBYTES)
+			return EINVAL;
+		m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
+		if (m == NULL)
+			return ENOMEM;
+		cmd = mtod(m, struct iwn_tx_cmd *);
+		error = bus_dmamap_load(ring->data_dmat, 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;
@@ -2683,27 +3422,63 @@ 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);
-
-	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 */
-	ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
-	IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
+	if (size > sizeof cmd->data) {
+		bus_dmamap_sync(ring->data_dmat, data->map,
+		    BUS_DMASYNC_PREWRITE);
+	} else {
+		bus_dmamap_sync(ring->data_dmat, ring->cmd_dma.map,
+		    BUS_DMASYNC_PREWRITE);
+	}
+	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
+	    BUS_DMASYNC_PREWRITE);
 
-	return async ? 0 : msleep(cmd, &sc->sc_mtx, PCATCH, "iwncmd", hz);
+#ifdef notyet
+	/* Update TX scheduler. */
+	sc->sc_hal->update_sched(sc, ring->qid, ring->cur, 0, 0);
+#endif
+
+	/* Kick command ring. */
+	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(desc, &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);
+}
+
+#if 0	/* HT */
 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 */
@@ -2716,6 +3491,7 @@ static const uint8_t iwn_mimo_mcs_to_plcp[] = {
 	0, 0, 0, 0, 			/* CCK */
 	8, 8, 9, 10, 11, 12, 13, 14, 15	/* HT */
 };
+#endif
 static const uint8_t iwn_prev_ridx[] = {
 	/* NB: allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
 	0, 0, 1, 5,			/* CCK */
@@ -2727,100 +3503,97 @@ static const uint8_t iwn_prev_ridx[] = {
  * node operating on the specified channel.
  */
 int
-iwn_set_link_quality(struct iwn_softc *sc, uint8_t id,
-	const struct ieee80211_channel *c, int async)
+iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)
 {
-	struct iwn_cmd_link_quality lq;
-	int i, ridx;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct iwn_cmd_link_quality linkq;
+	const struct iwn_rate *rinfo;
+	int i;
+	uint8_t txant, ridx;
 
-	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->txchainmask);
+
+	memset(&linkq, 0, sizeof linkq);
+	linkq.id = id;
+	linkq.antmsk_1stream = txant;
+	linkq.antmsk_2stream = IWN_ANT_AB;
+	linkq.ampdu_max = 31;
+	linkq.ampdu_threshold = 3;
+	linkq.ampdu_limit = htole16(4000);	/* 4ms */
+
+#if 0	/* HT */
+	if (IEEE80211_IS_CHAN_HT(c))
+		linkq.mimo = 1;
+#endif
 
 	if (id == IWN_ID_BSS)
-		ridx = IWN_RATE_OFDM54;
-	else if (IEEE80211_IS_CHAN_A(c))
-		ridx = IWN_RATE_OFDM6;
+		ridx = IWN_RIDX_OFDM54;
+	else if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
+		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 */
+		rinfo = &iwn_rates[ridx];
+#if 0	/* HT */
 		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;
+		} else
+#endif
+		{
+			linkq.retry[i].plcp = rinfo->plcp;
+			linkq.retry[i].rflags = rinfo->flags;
 		}
+		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, 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);
+	error = iwn_set_link_quality(sc, hal->broadcast_id, async);
+	return error;
 }
-#endif
 
 int
 iwn_wme_update(struct ieee80211com *ic)
@@ -2842,119 +3615,113 @@ iwn_wme_update(struct ieee80211com *ic)
 		cmd.ac[i].txoplimit =
 		    htole16(IWN_TXOP_TO_US(wmep->wmep_txopLimit));
 	}
+	IEEE80211_UNLOCK(ic);
 	IWN_LOCK(sc);
 	(void) iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1 /*async*/);
 	IWN_UNLOCK(sc);
+	IEEE80211_LOCK(ic);
 	return 0;
 #undef IWN_TXOP_TO_US
 #undef IWN_EXP2
 }
 
+static void
+iwn_update_mcast(struct ifnet *ifp)
+{
+	/* Ignore */
+}
+
 void
 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 stop the radio
+ * and 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;
+	int32_t 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);
 
+	if (sc->hw_type == IWN_HW_REV_TYPE_5150)
+		temp = (IWN_CTOK(110) - sc->temp_off) * -5;
+	else if (sc->hw_type == IWN_HW_REV_TYPE_4965)
+		temp = IWN_CTOK(110);
+	else
+		temp = 110;
 	memset(&crit, 0, sizeof crit);
 	crit.tempR = htole32(temp);
-	DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %u\n", temp);
+	DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %d\n",
+	    temp);
 	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,15 +3729,17 @@ 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 */
+	/* Retrieve channel number. */
 	chan = ieee80211_chan2ieee(ic, ch);
+	DPRINTF(sc, IWN_DEBUG_RESET, "setting TX power for channel %d\n",
+	    chan);
 
 	memset(&cmd, 0, sizeof cmd);
 	cmd.band = IEEE80211_IS_CHAN_5GHZ(ch) ? 0 : 1;
@@ -2978,15 +3747,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 +3765,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 attenuation group. */
 	if (chan <= 20)		/* 1-20 */
 		grp = 4;
 	else if (chan <= 43)	/* 34-43 */
@@ -3010,16 +3779,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 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 +3807,31 @@ 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;
-			}
+			/* Convert dBm to half-dBm. */
+			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 max TX power. */
 			if (pwr > maxchpwr)
 				pwr = maxchpwr;
 
@@ -3071,11 +3844,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 +3866,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) & IWN_ANT_ABC;
+	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[1], phy->rssi[2],
 	    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 +3948,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 +3971,236 @@ 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;
 
+	DPRINTF(sc, IWN_DEBUG_ANY, "temperature %dK/%dC\n", temp,
+	    IWN_KTOC(temp));
 	return IWN_KTOC(temp);
 }
 
+int
+iwn5000_get_temperature(struct iwn_softc *sc)
+{
+	int32_t temp;
+
+	/*
+	 * 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.
+	 */
+	temp = le32toh(sc->rawtemp);
+	if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
+		temp = (temp / -5) + sc->temp_off;
+		temp = IWN_KTOC(temp);
+	}
+	return temp;
+}
+
 /*
  * 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     = sc->limits->min_ofdm_x1;
+	calib->ofdm_mrc_x1 = sc->limits->min_ofdm_mrc_x1;
+	calib->ofdm_x4     = 90;
+	calib->ofdm_mrc_x4 = sc->limits->min_ofdm_mrc_x4;
+	calib->cck_x4      = 125;
+	calib->cck_mrc_x4  = sc->limits->min_cck_mrc_x4;
+	calib->energy_cck  = sc->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 */
-	sc->antmsk = 0;
+	/* Determine which antennas are connected. */
+	sc->chainmask = 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! */
+			sc->chainmask |= 1 << i;
+	/* If none of the TX antennas are connected, keep at least one. */
+	if ((sc->chainmask & sc->txchainmask) == 0)
+		sc->chainmask |= IWN_LSB(sc->txchainmask);
 
-	/* 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->chainmask));
+	(void)iwn_cmd(sc, IWN_CMD_RXON, &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_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 antenna. */
+	for (i = 0; i < 3; i++)
+		if (sc->chainmask & (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;
+		if (sc->chainmask & (1 << i)) {
+			/* 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->chainmask);
+	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, ant, delta;
+
+	if (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;
+	/* Get first available RX antenna as referential. */
+	ant = IWN_LSB(sc->rxchainmask);
+	/* Set differential gains for other antennas. */
+	for (i = ant + 1; i < 3; i++) {
+		if (sc->chainmask & (1 << i)) {
+			/* The delta is relative to antenna "ant". */
+			delta = ((int32_t)calib->noise[ant] -
+			    (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->chainmask);
+	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 +4208,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,134 +4217,136 @@ iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
 		needs_update = 1;		\
 	}
 
+	const struct iwn_sensitivity_limits *limits = sc->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;
 
-	/* check that we've been enabled long enough */
-	if ((rxena = le32toh(stats->general.load)) == 0)
+	/* Check that we've been enabled long enough. */
+	rxena = le32toh(stats->general.load);
+	if (rxena == 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
@@ -3428,115 +4357,436 @@ iwn_send_sensitivity(struct iwn_softc *sc)
 
 	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(sc->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);
+	/* Retrieve PCIe Active State Power Management (ASPM). */
+	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;
+	uint32_t txmask;
+	int error;
+	uint16_t rxchain;
+
+	/* Configure valid TX chains for 5000 Series. */
+	if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
+		txmask = htole32(sc->txchainmask);
+		DPRINTF(sc, IWN_DEBUG_RESET,
+		    "%s: configuring valid TX chains 0x%x\n", __func__, txmask);
+		error = iwn_cmd(sc, IWN5000_CMD_TX_ANT_CONFIG, &txmask,
+		    sizeof txmask, 0);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "%s: could not configure valid TX chains, "
+			    "error %d\n", __func__, error);
+			return error;
+		}
+	}
+
+	/* Configure bluetooth coexistence. */
+	memset(&bluetooth, 0, sizeof bluetooth);
+	bluetooth.flags = IWN_BT_COEX_MODE_4WIRE;
+	bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF;
+	bluetooth.max_kill = IWN_BT_MAX_KILL_DEF;
+	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;
+	}
+
+	/* Set mode, channel, RX filter and enable RX. */
+	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));
+	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_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;
+	sc->rxon.ht_triple_mask = 0xff;
+	rxchain =
+	    IWN_RXCHAIN_VALID(sc->rxchainmask) |
+	    IWN_RXCHAIN_MIMO_COUNT(2) |
+	    IWN_RXCHAIN_IDLE_COUNT(2);
+	sc->rxon.rxchain = htole16(rxchain);
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s: setting configuration\n", __func__);
+	error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: RXON command failed\n", __func__);
+		return error;
+	}
+
+	error = iwn_add_broadcast_node(sc, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not add broadcast node\n", __func__);
+		return error;
+	}
+
+	/* 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_set_critical_temp(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: ccould not set critical temperature\n", __func__);
+		return error;
+	}
+
+	/* Set power saving level to CAM during initialization. */
+	error = iwn_set_pslevel(sc, 0, 0, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not set power saving level\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;
+	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_VALID(sc->rxchainmask) |
+	    IWN_RXCHAIN_FORCE_MIMO_SEL(sc->rxchainmask) |
+	    IWN_RXCHAIN_DRIVER_FORCE;
+	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_FORCE_SEL(IWN_ANT_BC);
+	} else	/* Use all available RX antennas. */
+		rxchain |= IWN_RXCHAIN_FORCE_SEL(sc->rxchainmask);
+	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)) {
+		/* Send probe requests at 6Mbps. */
+		tx->plcp = iwn_rates[IWN_RIDX_OFDM6].plcp;
+		rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
+	} 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;
+		rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
+	}
+	/* Use the first valid TX antenna. */
+	txant = IWN_LSB(sc->txchainmask);
+	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;
+
+	/* 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 = htole16(ieee80211_chan2ieee(ic, c));
+	chan->flags = 0;
+	if (ss->ss_nssid > 0)
+		chan->flags |= htole32(IWN_CHAN_NPBREQS(1));
+	chan->dsp_gain = 0x6e;
+	if (IEEE80211_IS_CHAN_5GHZ(c) &&
+	    !(c->ic_flags & IEEE80211_CHAN_PASSIVE)) {
+		chan->rf_gain = 0x3b;
+		chan->active  = htole16(24);
+		chan->passive = htole16(110);
+		chan->flags |= htole32(IWN_CHAN_ACTIVE);
+	} else if (IEEE80211_IS_CHAN_5GHZ(c)) {
+		chan->rf_gain = 0x3b;
+		chan->active  = htole16(24);
+		if (sc->rxon.associd)
+			chan->passive = htole16(78);
+		else
+			chan->passive = htole16(110);
+		hdr->crc_threshold = htole16(1);
+	} else if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE)) {
+		chan->rf_gain = 0x28;
+		chan->active  = htole16(36);
+		chan->passive = htole16(120);
+		chan->flags |= htole32(IWN_CHAN_ACTIVE);
+	} else {
+		chan->rf_gain = 0x28;
+		chan->active  = htole16(36);
+		if (sc->rxon.associd)
+			chan->passive = htole16(88);
+		else
+			chan->passive = htole16(120);
+		hdr->crc_threshold = htole16(1);
+	}
+
+	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++;
+	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 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_RXON, &sc->rxon, hal->rxonsz, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
-		    "%s: could not configure, error %d\n", __func__, error);
+		    "%s: RXON command failed, error %d\n", __func__, error);
 		return error;
 	}
-	sc->sc_curchan = ic->ic_curchan;
 
-	/* 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;
 	}
-
 	/*
-	 * Reconfiguring clears the adapter's nodes table so we must
+	 * Reconfiguring RXON clears the firmware 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, 1);
 	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, 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,94 +4797,121 @@ 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;
 	struct iwn_node_info node;
-	int error, maxrxampdu, ampdudensity;
+	int error;
 
 	sc->calib.state = IWN_CALIB_STATE_INIT;
 
 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
-		/* link LED blinks while monitoring */
+		/* Link LED blinks while monitoring. */
 		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 configuration. */
+	IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
+	sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
+	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);
+	sc->rxon.flags |= htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
+	if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
+		sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
+	else
+		sc->rxon.flags &= ~htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
 	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_A(ni->ni_chan)) {
+		sc->rxon.cck_mask  = 0;
+		sc->rxon.ofdm_mask = 0x15;
+	} else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {
+		sc->rxon.cck_mask  = 0x03;
+		sc->rxon.ofdm_mask = 0;
+	} else {
+		/* XXX assume 802.11b/g */
+		sc->rxon.cck_mask  = 0x0f;
+		sc->rxon.ofdm_mask = 0x15;
+	}
+#if 0	/* HT */
 	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);
+#endif
+	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_RXON, &sc->rxon, hal->rxonsz, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not update configuration, error %d\n",
 		    __func__, error);
 		return error;
 	}
-	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));
+#ifdef notyet
+	node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(3) |
+	    IWN_AMDPU_DENSITY(5));	/* 2us */
+#endif
 	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);
+	DPRINTF(sc, IWN_DEBUG_STATE, "setting link quality for node %d\n",
+	    node.id);
+	error = iwn_set_link_quality(sc, node.id, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not setup MRR for node %d, error %d\n",
@@ -3650,594 +4927,1176 @@ 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;
 #undef MS
 }
 
+#if 0	/* HT */
 /*
- * 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.
+ * This function is called by upper layer when an ADDBA request is received
+ * from another STA and before the ADDBA response is sent.
  */
 int
-iwn_scan(struct iwn_softc *sc)
+iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
+    uint8_t tid)
 {
-	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;
+	struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
+	struct iwn_softc *sc = ic->ic_softc;
+	struct iwn_node *wn = (void *)ni;
+	struct iwn_node_info node;
 
-	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 */
+	memset(&node, 0, sizeof node);
+	node.id = wn->id;
+	node.control = IWN_NODE_UPDATE;
+	node.flags = IWN_FLAG_SET_ADDBA;
+	node.addba_tid = tid;
+	node.addba_ssn = htole16(ba->ba_winstart);
+	DPRINTF(sc, IWN_DEBUG_RECV, "ADDBA RA=%d TID=%d SSN=%d\n",
+	    wn->id, tid, ba->ba_winstart));
+	return sc->sc_hal->add_node(sc, &node, 1);
 }
 
-int
-iwn_config(struct iwn_softc *sc)
+/*
+ * This function is called by upper layer on teardown of an HT-immediate
+ * Block Ack agreement (eg. uppon receipt of a DELBA frame.)
+ */
+void
+iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
+    uint8_t tid)
 {
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
-	struct iwn_power power;
-	struct iwn_bluetooth bluetooth;
+	struct iwn_softc *sc = ic->ic_softc;
+	struct iwn_node *wn = (void *)ni;
+	struct iwn_node_info node;
+
+	memset(&node, 0, sizeof node);
+	node.id = wn->id;
+	node.control = IWN_NODE_UPDATE;
+	node.flags = IWN_FLAG_SET_DELBA;
+	node.delba_tid = tid;
+	DPRINTF(sc, IWN_DEBUG_RECV, "DELBA RA=%d TID=%d\n", wn->id, tid);
+	(void)sc->sc_hal->add_node(sc, &node, 1);
+}
+
+/*
+ * This function is called by upper layer when an ADDBA response is received
+ * from another STA.
+ */
+int
+iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
+    uint8_t tid)
+{
+	struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
+	struct iwn_softc *sc = ic->ic_softc;
+	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_node *wn = (void *)ni;
 	struct iwn_node_info node;
 	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",
-	    __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);
-		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));
-
-	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;
-
-	/* 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 */
+	/* Enable TX for the specified RA/TID. */
+	wn->disable_tid &= ~(1 << tid);
 	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);
+	node.id = wn->id;
+	node.control = IWN_NODE_UPDATE;
+	node.flags = IWN_FLAG_SET_DISABLE_TID;
+	node.disable_tid = htole16(wn->disable_tid);
+	error = hal->add_node(sc, &node, 1);
+	if (error != 0)
 		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);
+	if ((error = iwn_nic_lock(sc)) != 0)
 		return error;
+	hal->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);
+	iwn_nic_unlock(sc);
+	return 0;
+}
+
+void
+iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
+    uint8_t tid)
+{
+	struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
+	struct iwn_softc *sc = ic->ic_softc;
+	int error;
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return;
+	sc->sc_hal->ampdu_tx_stop(sc, tid, ba->ba_winstart);
+	iwn_nic_unlock(sc);
+}
+
+void
+iwn4965_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
+    uint8_t tid, uint16_t ssn)
+{
+	struct iwn_node *wn = (void *)ni;
+	int qid = 7 + tid;
+
+	/* Stop TX scheduler while we're changing its configuration. */
+	iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
+	    IWN4965_TXQ_STATUS_CHGACT);
+
+	/* Assign RA/TID translation to the queue. */
+	iwn_mem_write_2(sc, sc->sched_base + IWN4965_SCHED_TRANS_TBL(qid),
+	    wn->id << 4 | tid);
+
+	/* Enable chain-building mode for the queue. */
+	iwn_prph_setbits(sc, IWN4965_SCHED_QCHAIN_SEL, 1 << qid);
+
+	/* Set starting sequence number from the ADDBA request. */
+	IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
+	iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
+
+	/* 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 the queue. */
+	iwn_prph_setbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
+
+	/* Mark the queue as active. */
+	iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
+	    IWN4965_TXQ_STATUS_ACTIVE | IWN4965_TXQ_STATUS_AGGR_ENA |
+	    iwn_tid2fifo[tid] << 1);
+}
+
+void
+iwn4965_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
+{
+	int qid = 7 + tid;
+
+	/* Stop TX scheduler while we're changing its configuration. */
+	iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
+	    IWN4965_TXQ_STATUS_CHGACT);
+
+	/* Set starting sequence number from the ADDBA request. */
+	IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
+	iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
+
+	/* Disable interrupts for the queue. */
+	iwn_prph_clrbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
+
+	/* Mark the queue as inactive. */
+	iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
+	    IWN4965_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid] << 1);
+}
+
+void
+iwn5000_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
+    uint8_t tid, uint16_t ssn)
+{
+	struct iwn_node *wn = (void *)ni;
+	int qid = 10 + tid;
+
+	/* Stop TX scheduler while we're changing its configuration. */
+	iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
+	    IWN5000_TXQ_STATUS_CHGACT);
+
+	/* Assign RA/TID translation to the queue. */
+	iwn_mem_write_2(sc, sc->sched_base + IWN5000_SCHED_TRANS_TBL(qid),
+	    wn->id << 4 | tid);
+
+	/* Enable chain-building mode for the queue. */
+	iwn_prph_setbits(sc, IWN5000_SCHED_QCHAIN_SEL, 1 << qid);
+
+	/* Enable aggregation for the queue. */
+	iwn_prph_setbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
+
+	/* Set starting sequence number from the ADDBA request. */
+	IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
+	iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
+
+	/* 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 the queue. */
+	iwn_prph_setbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
+
+	/* Mark the queue as active. */
+	iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
+	    IWN5000_TXQ_STATUS_ACTIVE | iwn_tid2fifo[tid]);
+}
+
+void
+iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
+{
+	int qid = 10 + tid;
+
+	/* Stop TX scheduler while we're changing its configuration. */
+	iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
+	    IWN5000_TXQ_STATUS_CHGACT);
+
+	/* Disable aggregation for the queue. */
+	iwn_prph_clrbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
+
+	/* Set starting sequence number from the ADDBA request. */
+	IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
+	iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
+
+	/* Disable interrupts for the queue. */
+	iwn_prph_clrbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
+
+	/* Mark the queue as inactive. */
+	iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
+	    IWN5000_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid]);
+}
+#endif
+
+/*
+ * Query calibration tables from the initialization firmware.  We do this
+ * only once at first boot.  Called from a process context.
+ */
+int
+iwn5000_query_calibration(struct iwn_softc *sc)
+{
+	struct iwn5000_calib_config cmd;
+	int error;
+
+	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, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0);
+	if (error != 0)
+		return error;
+
+	/* Wait at most two seconds for calibration to complete. */
+	if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE))
+		error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 2 * hz);
+	return error;
+}
+
+/*
+ * 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;
+
+	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).
- */
-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)
+iwn5000_send_wimax_coex(struct iwn_softc *sc)
 {
-	uint32_t tmp;
-	int ntries;
+	struct iwn5000_wimax_coex wimax;
 
-	/* clear any pending interrupts */
-	IWN_WRITE(sc, IWN_INTR, 0xffffffff);
+#ifdef notyet
+	if (sc->hw_type == IWN_HW_REV_TYPE_6050) {
+		/* Enable WiMAX coexistence for combo adapters. */
+		wimax.flags =
+		    IWN_WIMAX_COEX_ASSOC_WA_UNMASK |
+		    IWN_WIMAX_COEX_UNASSOC_WA_UNMASK |
+		    IWN_WIMAX_COEX_STA_TABLE_VALID |
+		    IWN_WIMAX_COEX_ENABLE;
+		memcpy(wimax.events, iwn6050_wimax_events,
+		    sizeof iwn6050_wimax_events);
+	} else
+#endif
+	{
+		/* Disable WiMAX coexistence. */
+		wimax.flags = 0;
+		memset(wimax.events, 0, sizeof wimax.events);
+	}
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s: Configuring WiMAX coexistence\n",
+	    __func__);
+	return iwn_cmd(sc, IWN5000_CMD_WIMAX_COEX, &wimax, sizeof wimax, 0);
+}
 
-	tmp = IWN_READ(sc, IWN_CHICKEN);
-	IWN_WRITE(sc, IWN_CHICKEN, tmp | IWN_CHICKEN_DISLOS);
+/*
+ * This function is called after the runtime firmware notifies us of its
+ * readiness (called in a process context.)
+ */
+int
+iwn4965_post_alive(struct iwn_softc *sc)
+{
+	int error, qid;
 
-	tmp = IWN_READ(sc, IWN_GPIO_CTL);
-	IWN_WRITE(sc, IWN_GPIO_CTL, tmp | IWN_GPIO_INIT);
+	if ((error = iwn_nic_lock(sc)) != 0)
+		return error;
 
-	/* wait for clock stabilization */
+	/* Clear TX scheduler 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 / sizeof (uint32_t));
+
+	/* Set physical address of TX scheduler rings (1KB aligned.) */
+	iwn_prph_write(sc, IWN4965_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
+
+	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)
+{
+	int error, qid;
+
+	/* Switch to using ICT interrupt mode. */
+	iwn5000_ict_reset(sc);
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+
+	/* Clear TX scheduler 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 / sizeof (uint32_t));
+
+	/* 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 queues, except command queue. */
+	iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffef);
+	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 coexistence for combo adapters. */
+	error = iwn5000_send_wimax_coex(sc);
+	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_CALIB_DONE)) {
+		/* Query calibration from the initialization firmware. */
+		error = iwn5000_query_calibration(sc);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "%s: could not query calibration, error %d\n",
+			    __func__, error);
+			return error;
+		}
+		/*
+		 * We have the calibration results now, reboot with the
+		 * runtime firmware (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);
+	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);
+	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);
+	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);
+	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);
+	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
+
+	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_CALIB_DONE) ?
+	    &sc->fw.main : &sc->fw.init;
+
+	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;
+	struct iwn_fw_info *fw = &sc->fw;
+	const uint32_t *ptr;
+	uint32_t rev;
+	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 < 28) {
+		device_printf(sc->sc_dev,
+		    "%s: truncated firmware header: %zu bytes\n",
+		    __func__, size);
+		return EINVAL;
+	}
+
+	/* Process firmware header. */
+	ptr = (const uint32_t *)sc->fw_fp->data;
+	rev = le32toh(*ptr++);
+	/* Check firmware API version. */
+	if (IWN_FW_API(rev) <= 1) {
+		device_printf(sc->sc_dev,
+		    "%s: bad firmware, need API version >=2\n", __func__);
+		return EINVAL;
+	}
+	if (IWN_FW_API(rev) >= 3) {
+		/* Skip build number (version 2 header). */
+		size -= 4;
+		ptr++;
+	}
+	fw->main.textsz = le32toh(*ptr++);
+	fw->main.datasz = le32toh(*ptr++);
+	fw->init.textsz = le32toh(*ptr++);
+	fw->init.datasz = le32toh(*ptr++);
+	fw->boot.textsz = le32toh(*ptr++);
+	size -= 24;
+
+	/* 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 (fw->main.textsz + fw->main.datasz + fw->init.textsz +
+	    fw->init.datasz + fw->boot.textsz > size) {
+		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 *)ptr;
+	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;
+}
+
+int
+iwn_clock_wait(struct iwn_softc *sc)
+{
+	int ntries;
+
+	/* Set "initialization complete" bit. */
+	IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
+
+	/* Wait for clock stabilization. */
+	for (ntries = 0; ntries < 2500; ntries++) {
+		if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_MAC_CLOCK_READY)
+			return 0;
+		DELAY(10);
+	}
+	device_printf(sc->sc_dev,
+	    "%s: timeout waiting for clock stabilization\n", __func__);
+	return ETIMEDOUT;
+}
+
+int
+iwn_apm_init(struct iwn_softc *sc)
+{
+	uint32_t tmp;
+	int error;
+
+	/* Disable L0s exit timer (NMI bug workaround.) */
+	IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
+	/* Don't wait for ICH L0s (ICH bug workaround.) */
+	IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
+
+	/* Set FH wait threshold to max (HW bug under stress workaround.) */
+	IWN_SETBITS(sc, IWN_DBG_HPET_MEM, 0xffff0000);
+
+	/* Enable HAP INTA to move adapter from L1a to L0s. */
+	IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A);
+
+	/* Retrieve PCIe Active State Power Management (ASPM). */
+	tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
+	/* Workaround for HW instability in PCIe L0->L0s->L1 transition. */
+	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 (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
+	    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);
+
+	/* Wait for clock stabilization before accessing prph. */
+	error = iwn_clock_wait(sc);
+	if (error != 0)
+		return error;
+
+	error = iwn_nic_lock(sc);
+	if (error != 0)
+		return error;
+
+	if (sc->hw_type == IWN_HW_REV_TYPE_4965) {
+		/* Enable DMA and BSM (Bootstrap State Machine.) */
+		iwn_prph_write(sc, IWN_APMG_CLK_EN,
+		    IWN_APMG_CLK_CTRL_DMA_CLK_RQT |
+		    IWN_APMG_CLK_CTRL_BSM_CLK_RQT);
+	} else {
+		/* Enable DMA. */
+		iwn_prph_write(sc, IWN_APMG_CLK_EN,
+		    IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
+	}
+	DELAY(20);
+
+	/* Disable L1-Active. */
+	iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
+	iwn_nic_unlock(sc);
+
 	return 0;
 }
 
 void
-iwn_hw_config(struct iwn_softc *sc)
+iwn_apm_stop_master(struct iwn_softc *sc)
 {
-	uint32_t tmp, hw;
+	int ntries;
 
-	/* enable interrupts mitigation */
-	IWN_WRITE(sc, IWN_INTR_MIT, 512 / 32);
+	/* Stop busmaster DMA activity. */
+	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__);
+}
 
-	/* 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);
+void
+iwn_apm_stop(struct iwn_softc *sc)
+{
+	iwn_apm_stop_master(sc);
+
+	/* Reset the entire device. */
+	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)
+{
+	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;
+
+	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);
+
+	if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
+		/*
+		 * Select first Switching Voltage Regulator (1.32V) to
+		 * solve a stability issue related to noisy DC2DC line
+		 * in the silicon of 1000 Series.
+		 */
+		tmp = iwn_prph_read(sc, IWN_APMG_DIGITAL_SVR);
+		tmp &= ~IWN_APMG_DIGITAL_SVR_VOLTAGE_MASK;
+		tmp |= IWN_APMG_DIGITAL_SVR_VOLTAGE_1_32;
+		iwn_prph_write(sc, IWN_APMG_DIGITAL_SVR, tmp);
+	}
+	iwn_nic_unlock(sc);
+
+	if (sc->sc_flags & IWN_FLAG_INTERNAL_PA) {
+		/* Use internal power amplifier only. */
+		IWN_WRITE(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_2X2_IPA);
+	}
+	return 0;
+}
+
+/*
+ * Take NIC ownership over Intel Active Management Technology (AMT).
+ */
+int
+iwn_hw_prepare(struct iwn_softc *sc)
+{
+	int ntries;
+
+	/* Check if hardware is ready. */
+	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);
 	}
 
-	/* 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 );
+	/* Hardware not ready, force into ready state. */
+	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;
 
-	hw = IWN_READ(sc, IWN_HWCONFIG);
-	IWN_WRITE(sc, IWN_HWCONFIG, hw | 0x310);
+	/* Hardware should be ready now. */
+	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;
+}
 
-	iwn_mem_lock(sc);
-	tmp = iwn_mem_read(sc, IWN_MEM_POWER);
-	iwn_mem_write(sc, IWN_MEM_POWER, tmp | IWN_POWER_RESET);
+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 = iwn_apm_init(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not power ON adapter, error %d\n",
+		    __func__, error);
+		return error;
+	}
+
+	/* 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);
+
+	/* Perform adapter-specific initialization. */
+	error = hal->nic_config(sc);
+	if (error != 0)
+		return error;
+
+	/* 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_INT_MASK, sc->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_INT_MASK, 0);
+	IWN_WRITE(sc, IWN_INT, 0xffffffff);
+	IWN_WRITE(sc, IWN_FH_INT, 0xffffffff);
+	sc->sc_flags &= ~IWN_FLAG_USE_ICT;
+
+	/* 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_CTRL_DMA_CLK_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;
-	}
-
-	error = iwn_reset(sc);
+	error = iwn_hw_prepare(sc);
 	if (error != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not reset adapter, error %d\n", __func__, error);
-		return;
+		device_printf(sc->sc_dev, "%s: hardware not ready, eror %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);
+	/* Initialize interrupt mask to default value. */
+	sc->int_mask = IWN_INT_MASK_DEF;
+	sc->sc_flags &= ~IWN_FLAG_USE_ICT;
 
-	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)) {
+	/* 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,
 		    "radio is disabled by hardware switch\n");
+
+		/* Enable interrupts to get RF toggle notifications. */
+		IWN_WRITE(sc, IWN_INT, 0xffffffff);
+		IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
 		return;
 	}
 
-	error = iwn_transfer_firmware(sc);
+	/* Read firmware images from the filesystem. */
+	error = iwn_read_firmware(sc);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
-		    "%s: could not load firmware, error %d\n", __func__, error);
-		return;
+		    "%s: could not read firmware, 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);
+	/* Initialize hardware and upload firmware. */
+	error = iwn_hw_init(sc);
+	firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
+	sc->fw_fp = NULL;
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not initialize hardware, error %d\n",
+		    __func__, error);
+		goto fail;
+	}
 
+	/* 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,38 +6118,15 @@ 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);
-
 	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
@@ -4322,7 +6158,16 @@ iwn_scan_start(struct ieee80211com *ic)
 static void
 iwn_scan_end(struct ieee80211com *ic)
 {
-	/* ignore */
+	struct ifnet *ifp = ic->ic_ifp;
+	struct iwn_softc *sc = ifp->if_softc;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+
+	IWN_LOCK(sc);
+	if (vap->iv_state == IEEE80211_S_RUN) {
+		/* Set link LED to ON status if we are associated */
+		iwn_set_led(sc, IWN_LED_LINK, 0, 1);
+	}
+	IWN_UNLOCK(sc);
 }
 
 /*
@@ -4331,30 +6176,15 @@ 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 */
 
 	IWN_LOCK(sc);
-	if (c != sc->sc_curchan) {
-		sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
-		sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
-		sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
-		sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
-
-		error = iwn_config(sc);
-		if (error != 0) {
-			DPRINTF(sc, IWN_DEBUG_STATE,
-			    "%s: set chan failed, cancel scan\n",
-			    __func__);
-			//XXX Handle failed scan correctly
-			ieee80211_cancel_scan(vap);
-		}
-	}
+	sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
+	sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
+	sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
+	sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
 	IWN_UNLOCK(sc);
 }
 
@@ -4386,35 +6216,90 @@ iwn_scan_mindwell(struct ieee80211_scan_state *ss)
 	/* NB: don't try to abort scan; wait for firmware to finish */
 }
 
+static struct iwn_eeprom_chan *
+iwn_find_eeprom_channel(struct iwn_softc *sc, struct ieee80211_channel *c)
+{
+	int i, j;
+
+	for (j = 0; j < 7; j++) {
+		for (i = 0; i < iwn_bands[j].nchan; i++) {
+			if (iwn_bands[j].chan[i] == c->ic_ieee)
+				return &sc->eeprom_channels[j][i];
+		}
+	}
+
+	return NULL;
+}
+
+/*
+ * Enforce flags read from EEPROM.
+ */
+static int
+iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
+    int nchan, struct ieee80211_channel chans[])
+{
+	struct iwn_softc *sc = ic->ic_ifp->if_softc;
+	int i;
+
+	for (i = 0; i < nchan; i++) {
+		struct ieee80211_channel *c = &chans[i];
+		struct iwn_eeprom_chan *channel;
+
+		channel = iwn_find_eeprom_channel(sc, c);
+		if (channel == NULL) {
+			if_printf(ic->ic_ifp,
+			    "%s: invalid channel %u freq %u/0x%x\n",
+			    __func__, c->ic_ieee, c->ic_freq, c->ic_flags);
+			return EINVAL;
+		}
+		c->ic_flags |= iwn_eeprom_channel_flags(channel);
+	}
+
+	return 0;
+}
+
 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;
 	struct ieee80211com *ic = ifp->if_l2com;
 
+	iwn_stop(sc);
 	iwn_init(sc);
 	ieee80211_notify_radio(ic, 1);
 }
 
 static void
-iwn_radioon(void *arg0, int pending)
-{
-	struct iwn_softc *sc = arg0;
-
-	iwn_init(sc);
-}
-
-static void
-iwn_radiooff(void *arg0, int pending)
+iwn_radio_on(void *arg0, int pending)
 {
 	struct iwn_softc *sc = arg0;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 
+	if (vap != NULL) {
+		iwn_init(sc);
+		ieee80211_init(vap);
+	}
+}
+
+static void
+iwn_radio_off(void *arg0, int pending)
+{
+	struct iwn_softc *sc = arg0;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+
+	iwn_stop(sc);
+	if (vap != NULL)
+		ieee80211_stop(vap);
+
+	/* Enable interrupts to get RF toggle notification. */
 	IWN_LOCK(sc);
-	ieee80211_notify_radio(ic, 0);
-	iwn_stop_locked(sc);
+	IWN_WRITE(sc, IWN_INT, 0xffffffff);
+	IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
 	IWN_UNLOCK(sc);
 }
 
@@ -4431,6 +6316,50 @@ 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);
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+
+	iwn_stop(sc);
+	if (vap != NULL)
+		ieee80211_stop(vap);
+	return 0;
+}
+
+static int
+iwn_resume(device_t dev)
+{
+	struct iwn_softc *sc = device_get_softc(dev);
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+
+	/* Clear device-specific "PCI retry timeout" register (41h). */
+	pci_write_config(dev, 0x41, 0, 1);
+
+	if (ifp->if_flags & IFF_UP) {
+		iwn_init(sc);
+		if (vap != NULL)
+			ieee80211_init(vap);
+		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			iwn_start(ifp);
+	}
+	return 0;
+}
+
 #ifdef IWN_DEBUG
 static const char *
 iwn_intr_str(uint8_t cmd)
@@ -4446,47 +6375,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_RXON:		return "IWN_CMD_RXON";
+	case IWN_CMD_RXON_ASSOC:	return "IWN_CMD_RXON_ASSOC";
 	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..08ef36cabfe 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.34 2009/11/08 11:54:48 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,354 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#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
+
+#define IWN_ICT_SIZE		4096
+#define IWN_ICT_COUNT		(IWN_ICT_SIZE / sizeof (uint32_t))
+
+/* 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_MASK		0x00c
-#define IWN_INTR_STATUS		0x010
+#define IWN_HW_IF_CONFIG	0x000
+#define IWN_INT_COALESCING	0x004
+#define IWN_INT_PERIODIC	0x005	/* use IWN_WRITE_1 */
+#define IWN_INT			0x008
+#define IWN_INT_MASK		0x00c
+#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_GP_DRIVER		0x050
+#define IWN_UCODE_GP1_CLR	0x05c
+#define IWN_LED			0x094
+#define IWN_DRAM_INT_TBL	0x0a0
+#define IWN_GIO_CHICKEN		0x100
+#define IWN_ANA_PLL		0x20c
+#define IWN_HW_REV_WA		0x22c
+#define IWN_DBG_HPET_MEM	0x240
+#define IWN_DBG_LINK_PWR_MGMT	0x250
+#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	0x3000
+#define IWN_APMG_CLK_EN		0x3004
+#define IWN_APMG_CLK_DIS	0x3008
+#define IWN_APMG_PS		0x300c
+#define IWN_APMG_DIGITAL_SVR	0x3058
+#define IWN_APMG_ANALOG_SVR	0x306c
+#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 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 register IWN_HWCONFIG */
-#define IWN_HW_EEPROM_LOCKED	(1 << 21)
+/* Possible values for register IWN_INT_PERIODIC. */
+#define IWN_INT_PERIODIC_DIS	0x00
+#define IWN_INT_PERIODIC_ENA	0xff
 
-/* 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)
+#define IWN_RESET_LINK_PWR_MGMT_DIS	(1 << 31)
 
-/* 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_GP_DRIVER. */
+#define IWN_GP_DRIVER_RADIO_3X3_HYB	(0 << 0)
+#define IWN_GP_DRIVER_RADIO_2X2_HYB	(1 << 0)
+#define IWN_GP_DRIVER_RADIO_2X2_IPA	(2 << 0)
 
-/* 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 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)
 
-#define	IWN_INTR_BITS	"\20\1ALIVE\2WAKEUP\3SW_RX\6CT_REACHED\7RF_TOGGLED" \
-	"\32SW_ERROR\34TX_INTR\36HW_ERROR\40RX_INTR"
+/* 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_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_DRAM_INT_TBL. */
+#define IWN_DRAM_INT_TBL_WRAP_CHECK	(1 << 27)
+#define IWN_DRAM_INT_TBL_ENABLE		(1 << 31)
 
-/* 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 values for register IWN_ANA_PLL. */
+#define IWN_ANA_PLL_INIT	0x00880300
 
-/* possible flags for register IWN_TX_STATUS */
-#define IWN_TX_IDLE(qid)	(1 << ((qid) + 24) | 1 << ((qid) + 16))
+/* Possible flags for register IWN_FH_RX_STATUS. */
+#define	IWN_FH_RX_STATUS_IDLE	(1 << 24)
 
-/* possible flags/masks for register IWN_EEPROM_CTL */
-#define IWN_EEPROM_READY	(1 << 0)
-#define IWN_EEPROM_MSK		(1 << 1)
+/* 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_TXQ_STATUS */
-#define IWN_TXQ_STATUS_ACTIVE	0x0007fc01
+/* 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_SCHED		(1 << 26)
+#define IWN_INT_FH_TX		(1 << 27)
+#define IWN_INT_RX_PERIODIC	(1 << 28)
+#define IWN_INT_HW_ERR		(1 << 29)
+#define IWN_INT_FH_RX		(1 << 31)
 
-/* possible flags for register IWN_MEM_POWER */
-#define IWN_POWER_RESET	(1 << 26)
+/* Shortcut. */
+#define IWN_INT_MASK_DEF						\
+	(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_MEM_TEXT_SIZE */
+/* 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/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/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 registers IWN_APMG_CLK_*. */
+#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 register IWN_APMG_DIGITAL_SVR. */
+#define IWN_APMG_DIGITAL_SVR_VOLTAGE(x)		(((x) & 0xf) << 5)
+#define IWN_APMG_DIGITAL_SVR_VOLTAGE_MASK	\
+	IWN_APMG_DIGITAL_SVR_VOLTAGE(0xf)
+#define IWN_APMG_DIGITAL_SVR_VOLTAGE_1_32	\
+	IWN_APMG_DIGITAL_SVR_VOLTAGE(3)
+
+/* 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 +373,82 @@ 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
+#define IWN_RX_COMPRESSED_BA		197
 
 	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_RXON			 16
+#define IWN_CMD_RXON_ASSOC		 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_DBM		149
+#define IWN_CMD_TXPOWER			151
+#define IWN5000_CMD_TX_ANT_CONFIG	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)
+/* Shortcuts. */
+#define IWN_ANT_AB	(IWN_ANT_A | IWN_ANT_B)
+#define IWN_ANT_BC	(IWN_ANT_B | IWN_ANT_C)
+#define IWN_ANT_ABC	(IWN_ANT_A | IWN_ANT_B | IWN_ANT_C)
+
+/* Structure for command IWN_CMD_RXON. */
+struct iwn_rxon {
 	uint8_t		myaddr[IEEE80211_ADDR_LEN];
 	uint16_t	reserved1;
 	uint8_t		bssid[IEEE80211_ADDR_LEN];
@@ -287,54 +460,55 @@ 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_DRIVER_FORCE	(1 << 0)
+#define IWN_RXCHAIN_VALID(x)		(((x) & IWN_ANT_ABC) << 1)
+#define IWN_RXCHAIN_FORCE_SEL(x)	(((x) & IWN_ANT_ABC) << 4)
+#define IWN_RXCHAIN_FORCE_MIMO_SEL(x)	(((x) & IWN_ANT_ABC) << 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		(1 <<  0)
+#define IWN_RXON_CCK		(1 <<  1)
+#define IWN_RXON_AUTO		(1 <<  2)
+#define IWN_RXON_SHSLOT		(1 <<  4)
+#define IWN_RXON_SHPREAMBLE	(1 <<  5)
+#define IWN_RXON_NODIVERSITY	(1 <<  7)
+#define IWN_RXON_ANTENNA_A	(1 <<  8)
+#define IWN_RXON_ANTENNA_B	(1 <<  9)
+#define IWN_RXON_TSF		(1 << 15)
+#define IWN_RXON_CTS_TO_SELF	(1 << 30)
+
 	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 +517,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)
@@ -355,11 +529,11 @@ struct iwn_edca_params {
 		uint8_t		aifsn;
 		uint8_t		reserved;
 		uint16_t	txoplimit;
-	} __packed	ac[EDCA_NUM_AC];
+	} __packed	ac[WME_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 +542,110 @@ 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_CCK		(1 << 1)
+#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 +653,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 +670,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[WME_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 +705,61 @@ 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;
+#define IWN_WIMAX_COEX_STA_TABLE_VALID		(1 << 0)
+#define IWN_WIMAX_COEX_UNASSOC_WA_UNMASK	(1 << 2)
+#define IWN_WIMAX_COEX_ASSOC_WA_UNMASK		(1 << 3)
+#define IWN_WIMAX_COEX_ENABLE			(1 << 7)
 
-	uint8_t		alive;
+	struct iwn5000_wimax_event {
+		uint8_t	request;
+		uint8_t	window;
+		uint8_t	reserved;
+		uint8_t	flags;
+	} __packed	events[16];
+} __packed;
+
+/* 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 +770,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,59 +779,84 @@ 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;
-	uint8_t		kill;
+#define IWN_BT_COEX_DISABLE	0
+#define IWN_BT_COEX_MODE_2WIRE	1
+#define IWN_BT_COEX_MODE_3WIRE	2
+#define IWN_BT_COEX_MODE_4WIRE	3
+
+	uint8_t		lead_time;
+#define IWN_BT_LEAD_TIME_DEF	30
+
+	uint8_t		max_kill;
+#define IWN_BT_MAX_KILL_DEF	5
+
 	uint8_t		reserved;
-	uint32_t	ack;
-	uint32_t	cts;
+	uint32_t	kill_ack;
+	uint32_t	kill_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 +875,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_PERIODIC	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 +956,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		btkillcnt;
+	uint8_t		rtsfailcnt;
+	uint8_t		ackfailcnt;
 	uint8_t		rate;
 	uint8_t		rflags;
 	uint16_t	xrflags;
@@ -649,16 +990,30 @@ 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		btkillcnt;
+	uint8_t		rtsfailcnt;
+	uint8_t		ackfailcnt;
+	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;
+	uint8_t		tlc;
+	uint8_t		ratid;
+	uint8_t		fc[2];
+	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 +1021,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 +1050,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 +1061,21 @@ struct iwn_rx_stat {
 	uint16_t	reserve3;
 } __packed;
 
-/* structure for IWN_START_SCAN notification */
+#define IWN_RSSI_TO_DBM	44
+
+/* Structure for IWN_RX_COMPRESSED_BA notification. */
+struct iwn_compressed_ba {
+	uint8_t		macaddr[IEEE80211_ADDR_LEN];
+	uint16_t	reserved;
+	uint8_t		id;
+	uint8_t		tid;
+	uint16_t	seq;
+	uint64_t	bitmap;
+	uint16_t	qid;
+	uint16_t	ssn;
+} __packed;
+
+/* Structure for IWN_START_SCAN notification. */
 struct iwn_start_scan {
 	uint64_t	tstamp;
 	uint32_t	tbeacon;
@@ -707,7 +1085,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 +1094,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;
+
+/* Structures for IWN_{RX,BEACON}_STATISTICS notification. */
 struct iwn_rx_phy_stats {
 	uint32_t	ina;
 	uint32_t	fina;
@@ -833,77 +1243,183 @@ struct iwn_stats {
 } __packed;
 
 
-/* firmware image header */
-struct iwn_firmware_hdr {
-	uint32_t	version;
-	uint32_t	main_textsz;
-	uint32_t	main_datasz;
-	uint32_t	init_textsz;
-	uint32_t	init_datasz;
-	uint32_t	boot_textsz;
+/* 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;
 
-#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
 
+#define IWN_FW_API(x)	(((x) >> 8) & 0xff)
 
 /*
  * 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 IWN6000_EEPROM_ENHINFO	0x054
+#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_WIDE	(1 << 5)	/* HT40 */
-#define IWN_EEPROM_CHAN_NARROW	(1 << 6)	/* HT20 */
+#define IWN_EEPROM_CHAN_IBSS	(1 << 1)
+#define IWN_EEPROM_CHAN_ACTIVE	(1 << 3)
+#define IWN_EEPROM_CHAN_RADAR	(1 << 4)
 
 	int8_t	maxpwr;
 } __packed;
 
+struct iwn_eeprom_enhinfo {
+	uint16_t	chan;
+	int8_t		chain[3];	/* max power in half-dBm */
+	uint8_t		reserved;
+	int8_t		mimo2;		/* max power in half-dBm */
+	int8_t		mimo3;		/* max power in half-dBm */
+} __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 IWN1000_OTP_NBLOCKS	3
+#define IWN6000_OTP_NBLOCKS	4
+#define IWN6050_OTP_NBLOCKS	7
+
+/* 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 +1432,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 +1449,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 +1462,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 +1475,195 @@ 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,
+	220, 270,
+	 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
+};
+
+static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = {
+	105, 105,	/* min = max for performance bug in DSP. */
+	220, 220,	/* min = max for performance bug in DSP. */
+	 90, 120,
+	170, 210,
+	125, 200,
+	170, 400,
+	 95,
+	 95,
+	 95
+};
+
+static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = {
+	105, 145,
+	192, 232,
+	 80, 145,
+	128, 232,
+	125, 175,
+	160, 310,
+	 97,
+	 97,
+	100
+};
+
+/* 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
+};
+
+/* WiFi/WiMAX coexist event priority table for 6050. */
+static const struct iwn5000_wimax_event iwn6050_wimax_events[] = {
+	{ 0x04, 0x03, 0x00, 0x00 },
+	{ 0x04, 0x03, 0x00, 0x03 },
+	{ 0x04, 0x03, 0x00, 0x03 },
+	{ 0x04, 0x03, 0x00, 0x03 },
+	{ 0x04, 0x03, 0x00, 0x00 },
+	{ 0x04, 0x03, 0x00, 0x07 },
+	{ 0x04, 0x03, 0x00, 0x00 },
+	{ 0x04, 0x03, 0x00, 0x03 },
+	{ 0x04, 0x03, 0x00, 0x03 },
+	{ 0x04, 0x03, 0x00, 0x00 },
+	{ 0x06, 0x03, 0x00, 0x07 },
+	{ 0x04, 0x03, 0x00, 0x00 },
+	{ 0x06, 0x06, 0x00, 0x03 },
+	{ 0x04, 0x03, 0x00, 0x07 },
+	{ 0x04, 0x03, 0x00, 0x00 },
+	{ 0x04, 0x03, 0x00, 0x00 }
+};
+
+/* 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_WRITE_1(sc, reg, val)					\
+	bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+
+#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))
+
+#define IWN_BARRIER_WRITE(sc)						\
+	bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz,	\
+	    BUS_SPACE_BARRIER_WRITE)
+
+#define IWN_BARRIER_READ_WRITE(sc)					\
+	bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz,	\
+	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index 19cc0250b94..98c9c948553 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.16 2009/11/04 17:46:52 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;
 };
@@ -76,14 +80,18 @@ struct iwn_tx_ring {
 	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;
@@ -92,23 +100,26 @@ struct iwn_rx_ring {
 struct iwn_node {
 	struct	ieee80211_node		ni;	/* must be the first */
 	struct	ieee80211_amrr_node	amn;
+	uint16_t			disable_tid;
+	uint8_t				id;
+	uint8_t				ridx[IEEE80211_RATE_MAXSIZE];
 };
-#define	IWN_NODE(_ni)	((struct iwn_node *)(_ni))
 
 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,64 @@ 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		(*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 *);
+#if 0	/* HT */
+	void		(*ampdu_tx_start)(struct iwn_softc *,
+			    struct ieee80211_node *, uint8_t, uint16_t);
+	void		(*ampdu_tx_stop)(struct iwn_softc *, uint8_t,
+			    uint16_t);
+#endif
+	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 +205,106 @@ 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 */
+	/* 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_CALIB_DONE	(1 << 2)
+#define IWN_FLAG_USE_ICT	(1 << 3)
+#define IWN_FLAG_INTERNAL_PA	(1 << 4)
 
-	/* "keep warm" page */
+	uint8_t 		hw_type;
+	const struct iwn_hal	*sc_hal;
+	const char		*fwname;
+	const struct iwn_sensitivity_limits
+				*limits;
+
+	/* 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];
+	/* ICT table. */
+	struct iwn_dma_info	ict_dma;
+	uint32_t		*ict;
+	int			ict_cur;
+
+	/* 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];
+	uint32_t		prom_base;
+	struct iwn4965_eeprom_band
+				bands[IWN_NBANDS];
+	struct iwn_eeprom_chan	eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND];
+	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];
+	int8_t			enh_maxpwr[35];
+
+	int32_t			temp_off;
+	uint32_t		int_mask;
+	uint8_t			ntxchains;
+	uint8_t			nrxchains;
+	uint8_t			txchainmask;
+	uint8_t			rxchainmask;
+	uint8_t			chainmask;
+
+	struct callout		sc_timer_to;
+	int			sc_tx_timer;
+
+	struct iwn_rx_radiotap_header sc_rxtap;
+	struct iwn_tx_radiotap_header sc_txtap;
 };
 
 #define IWN_LOCK_INIT(_sc) \
diff --git a/sys/modules/iwnfw/Makefile b/sys/modules/iwnfw/Makefile
index 498afcf19eb..41556df8c59 100644
--- a/sys/modules/iwnfw/Makefile
+++ b/sys/modules/iwnfw/Makefile
@@ -1,13 +1,5 @@
 # $FreeBSD$
 
-.PATH: ${.CURDIR}/../../contrib/dev/iwn
+SUBDIR=	iwn1000 iwn4965 iwn5000 iwn5150 iwn6000
 
-KMOD=	iwnfw
-FIRMWS=	iwlwifi-4965-4.44.17.fw:iwnfw:44417
-
-CLEANFILES=	iwlwifi-4965-4.44.17.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}
-
-.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/iwn1000/Makefile b/sys/modules/iwnfw/iwn1000/Makefile
new file mode 100644
index 00000000000..68b343e0883
--- /dev/null
+++ b/sys/modules/iwnfw/iwn1000/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD=	iwn1000fw
+IMG=	iwlwifi-1000-128.50.3.1
+
+.include 
diff --git a/sys/modules/iwnfw/iwn4965/Makefile b/sys/modules/iwnfw/iwn4965/Makefile
new file mode 100644
index 00000000000..c1cc961342e
--- /dev/null
+++ b/sys/modules/iwnfw/iwn4965/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD=	iwn4965fw
+IMG=	iwlwifi-4965-228.61.2.24
+
+.include 
diff --git a/sys/modules/iwnfw/iwn5000/Makefile b/sys/modules/iwnfw/iwn5000/Makefile
new file mode 100644
index 00000000000..a1031d2aa16
--- /dev/null
+++ b/sys/modules/iwnfw/iwn5000/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD=	iwn5000fw
+IMG=	iwlwifi-5000-8.24.2.12
+
+.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 
diff --git a/sys/modules/iwnfw/iwn6000/Makefile b/sys/modules/iwnfw/iwn6000/Makefile
new file mode 100644
index 00000000000..c0295a92cf1
--- /dev/null
+++ b/sys/modules/iwnfw/iwn6000/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD=	iwn6000fw
+IMG=	iwlwifi-6000-9.176.4.1
+
+.include 

From 038d31fa9ca94600c1057740ad09ccc1275b4fcd Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Wed, 20 Jan 2010 15:24:24 +0000
Subject: [PATCH 1241/2592] MFC r198470, r198521: Syncronize iwn(4) manpages
 with HEAD.

---
 share/man/man4/iwn.4   | 27 ++++++++++++++++++++++-----
 share/man/man4/iwnfw.4 | 17 ++++++++++++++---
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/share/man/man4/iwn.4 b/share/man/man4/iwn.4
index 7ddded24fab..1edb425c696 100644
--- a/share/man/man4/iwn.4
+++ b/share/man/man4/iwn.4
@@ -25,36 +25,53 @@
 .\"
 .\" $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.
+Choose 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
+module at boot time, place the following lines 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 72021ea2429..700d20ab40e 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 75a2f19f2031d613ac6f625ca4a96bde83bbaa74 Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Wed, 20 Jan 2010 16:28:39 +0000
Subject: [PATCH 1242/2592] MFC r200018:

Bump limits on PowerPC. This allows large executables like parts of LLVM
to function.

Reviewed by:	grehan
Obtained from:	NetBSD
---
 sys/powerpc/include/vmparam.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/sys/powerpc/include/vmparam.h b/sys/powerpc/include/vmparam.h
index 8b6ef2b13fe..e77823363a1 100644
--- a/sys/powerpc/include/vmparam.h
+++ b/sys/powerpc/include/vmparam.h
@@ -38,23 +38,23 @@
 #define	USRSTACK	VM_MAXUSER_ADDRESS
 
 #ifndef	MAXTSIZ
-#define	MAXTSIZ		(16*1024*1024)		/* max text size */
+#define	MAXTSIZ		(64*1024*1024)		/* max text size */
 #endif
 
 #ifndef	DFLDSIZ
-#define	DFLDSIZ		(32*1024*1024)		/* default data size */
+#define	DFLDSIZ		(128*1024*1024)		/* default data size */
 #endif
 
 #ifndef	MAXDSIZ
-#define	MAXDSIZ		(512*1024*1024)		/* max data size */
+#define	MAXDSIZ		(1*1024*1024*1024)	/* max data size */
 #endif
 
 #ifndef	DFLSSIZ
-#define	DFLSSIZ		(1*1024*1024)		/* default stack size */
+#define	DFLSSIZ		(8*1024*1024)		/* default stack size */
 #endif
 
 #ifndef	MAXSSIZ
-#define	MAXSSIZ		(32*1024*1024)		/* max stack size */
+#define	MAXSSIZ		(64*1024*1024)		/* max stack size */
 #endif
 
 /*

From d92c7395bf65869ccc39918b113a6ed91397be1c Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 21 Jan 2010 00:37:14 +0000
Subject: [PATCH 1243/2592] MFC r202269:   Add BCM5754 PHY id that is found on
 Dell Studio XPS 16.

---
 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 3e3c9504391..393005c1cd5 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -133,6 +133,7 @@ static const struct mii_phydesc brgphys[] = {
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5708S),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709CAX),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5722),
+	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5784),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5761),
 	MII_PHY_DESC(BROADCOM2, BCM5906),
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
index f3aa2e9999b..325d733c3f5 100644
--- a/sys/dev/mii/miidevs
+++ b/sys/dev/mii/miidevs
@@ -153,6 +153,7 @@ model xxBROADCOM_ALT1 BCM5787	0x000e BCM5787 10/100/1000baseTX PHY
 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 BCM5784	0x003a BCM5784 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

From 29a6686087546d38685be47bbc89180e9b886bad Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 21 Jan 2010 00:45:12 +0000
Subject: [PATCH 1244/2592] MFC r202293:   For controllers that has dual mode
 PHY(copper or fiber) interfaces   over GMII, make sure to enable GMII. With
 this change brgphy(4) is   used to handle the dual mode PHY. Since we still
 don't have a sane   way to pass PHY specific information to mii(4) layer
 special   handling is needed in brgphy(4) to determine which mode of PHY was 
  configured in parent interface.   This change make BCM5715S work.

  Tested by:	olli
  Obtained from:	OpenBSD
  PR:	kern/122551
---
 sys/dev/bge/if_bge.c    | 34 ++++++++++++++++++++++------------
 sys/dev/bge/if_bgereg.h |  1 +
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index b4f49159913..85c95e7cf58 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -901,7 +901,8 @@ bge_miibus_statchg(device_t dev)
 	mii = device_get_softc(sc->bge_miibus);
 
 	BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE);
-	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T)
+	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
+	    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX)
 		BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII);
 	else
 		BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_MII);
@@ -1782,13 +1783,20 @@ bge_blockinit(struct bge_softc *sc)
 	if (!(BGE_IS_5705_PLUS(sc)))
 		CSR_WRITE_4(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);
 
+	val = BGE_MACMODE_TXDMA_ENB | BGE_MACMODE_RXDMA_ENB |
+	    BGE_MACMODE_RX_STATS_CLEAR | BGE_MACMODE_TX_STATS_CLEAR |
+	    BGE_MACMODE_RX_STATS_ENB | BGE_MACMODE_TX_STATS_ENB |
+	    BGE_MACMODE_FRMHDR_DMA_ENB;
+
+	if (sc->bge_flags & BGE_FLAG_TBI)
+		val |= BGE_PORTMODE_TBI;
+	else if (sc->bge_flags & BGE_FLAG_MII_SERDES)
+		val |= BGE_PORTMODE_GMII;
+	else
+		val |= BGE_PORTMODE_MII;
+
 	/* Turn on DMA, clear stats */
-	CSR_WRITE_4(sc, BGE_MAC_MODE, BGE_MACMODE_TXDMA_ENB |
-	    BGE_MACMODE_RXDMA_ENB | BGE_MACMODE_RX_STATS_CLEAR |
-	    BGE_MACMODE_TX_STATS_CLEAR | BGE_MACMODE_RX_STATS_ENB |
-	    BGE_MACMODE_TX_STATS_ENB | BGE_MACMODE_FRMHDR_DMA_ENB |
-	    ((sc->bge_flags & BGE_FLAG_TBI) ?
-	    BGE_PORTMODE_TBI : BGE_PORTMODE_MII));
+	CSR_WRITE_4(sc, BGE_MAC_MODE, val);
 
 	/* Set misc. local control, enable interrupts on attentions */
 	CSR_WRITE_4(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_ONATTN);
@@ -2849,12 +2857,14 @@ bge_attach(device_t dev)
 		hwcfg = ntohl(hwcfg);
 	}
 
-	if ((hwcfg & BGE_HWCFG_MEDIA) == BGE_MEDIA_FIBER)
-		sc->bge_flags |= BGE_FLAG_TBI;
-
 	/* The SysKonnect SK-9D41 is a 1000baseSX card. */
-	if ((pci_read_config(dev, BGE_PCI_SUBSYS, 4) >> 16) == SK_SUBSYSID_9D41)
-		sc->bge_flags |= BGE_FLAG_TBI;
+	if ((pci_read_config(dev, BGE_PCI_SUBSYS, 4) >> 16) ==
+	    SK_SUBSYSID_9D41 || (hwcfg & BGE_HWCFG_MEDIA) == BGE_MEDIA_FIBER) {
+		if (BGE_IS_5714_FAMILY(sc))
+			sc->bge_flags |= BGE_FLAG_MII_SERDES;
+		else
+			sc->bge_flags |= BGE_FLAG_TBI;
+	}
 
 	if (sc->bge_flags & BGE_FLAG_TBI) {
 		ifmedia_init(&sc->bge_ifmedia, IFM_IMASK, bge_ifmedia_upd,
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index 2694c77a6fb..23a97093202 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -2602,6 +2602,7 @@ struct bge_softc {
 #define	BGE_FLAG_JUMBO		0x00000002
 #define	BGE_FLAG_WIRESPEED	0x00000004
 #define	BGE_FLAG_EADDR		0x00000008
+#define	BGE_FLAG_MII_SERDES	0x00000010
 #define	BGE_FLAG_MSI		0x00000100
 #define	BGE_FLAG_PCIX		0x00000200
 #define	BGE_FLAG_PCIE		0x00000400

From 85f51ebea94076d1737713bab927b9dbdec3e61f Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 21 Jan 2010 00:49:14 +0000
Subject: [PATCH 1245/2592] MFC r202294:   Add check for fiber mode for BCM5714
 PHY. This PHY supports both   copper and fiber interfaces over GMII so an
 explicit check is   necessary to know whether it was configured for fiber
 interface.   This change make BCM5715S work.

  Tested by:	olli
  PR:	kern/122551
---
 sys/dev/mii/brgphy.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index 393005c1cd5..1f7d2ebbae0 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -197,6 +197,7 @@ brgphy_attach(device_t dev)
 	case MII_OUI_xxBROADCOM:
 		switch (bsc->mii_model) {
 			case MII_MODEL_xxBROADCOM_BCM5706:
+			case MII_MODEL_xxBROADCOM_BCM5714:
 				/*
 				 * The 5464 PHY used in the 5706 supports both copper
 				 * and fiber interfaces over GMII.  Need to check the

From eac2bf0ee0ba1a7ed8082459d54d929e7d8f48d8 Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Thu, 21 Jan 2010 00:53:00 +0000
Subject: [PATCH 1246/2592] MFC r202406:   Don't free mbuf chains when bge(4)
 fails to collapse the mbuf   chains. This part of code is to enhance
 performance so failing the   collapsing should not free TX frames. Otherwise
 bge(4) will   unnecessarily drop frames which in turn can freeze the network 
  connection.

  Reported by:	Igor Sysoev (is <> rambler-co dot ru)
  Tested by:	Igor Sysoev (is <> rambler-co dot ru)
---
 sys/dev/bge/if_bge.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 85c95e7cf58..8eeb149beb2 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -3948,11 +3948,8 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
 			m = m_defrag(m, M_DONTWAIT);
 		else
 			m = m_collapse(m, M_DONTWAIT, sc->bge_forced_collapse);
-		if (m == NULL) {
-			m_freem(*m_head);
-			*m_head = NULL;
-			return (ENOBUFS);
-		}
+		if (m == NULL)
+			m = *m_head;
 		*m_head = m;
 	}
 

From e0d8d4df287687af519c6d2439d79f62b0bed98b Mon Sep 17 00:00:00 2001
From: Navdeep Parhar 
Date: Thu, 21 Jan 2010 03:06:52 +0000
Subject: [PATCH 1247/2592] MFC r201907,202671,202678

r201907:
Extra parantheses to keep certain compilers happy.

r202671:
Fix for a cxgb(4) panic.  cxgb_ioctl can be called by the IP and IPv6
layers with non-sleepable locks held.  Don't (potentially) sleep in
those situations.

r202678:
Complain if freelist queue sizes are significantly less than desired.
---
 sys/dev/cxgb/common/cxgb_t3_hw.c |   2 +-
 sys/dev/cxgb/cxgb_adapter.h      |   1 -
 sys/dev/cxgb/cxgb_main.c         | 285 ++++++++++++++++---------------
 sys/dev/cxgb/cxgb_sge.c          |   8 +-
 4 files changed, 150 insertions(+), 146 deletions(-)

diff --git a/sys/dev/cxgb/common/cxgb_t3_hw.c b/sys/dev/cxgb/common/cxgb_t3_hw.c
index e340058552e..2c205ec2383 100644
--- a/sys/dev/cxgb/common/cxgb_t3_hw.c
+++ b/sys/dev/cxgb/common/cxgb_t3_hw.c
@@ -4443,7 +4443,7 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
 
 	adapter->params.info = ai;
 	adapter->params.nports = ai->nports0 + ai->nports1;
-	adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1);
+	adapter->params.chan_map = (!!ai->nports0) | (!!ai->nports1 << 1);
 	adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
 
 	/*
diff --git a/sys/dev/cxgb/cxgb_adapter.h b/sys/dev/cxgb/cxgb_adapter.h
index 71f540223a4..c5b366bc74f 100644
--- a/sys/dev/cxgb/cxgb_adapter.h
+++ b/sys/dev/cxgb/cxgb_adapter.h
@@ -136,7 +136,6 @@ enum {
 };
 #define IS_DOOMED(p)	(p->flags & DOOMED)
 #define SET_DOOMED(p)	do {p->flags |= DOOMED;} while (0)
-#define DOOMED(p)	(p->flags & DOOMED)
 #define IS_BUSY(sc)	(sc->flags & CXGB_BUSY)
 #define SET_BUSY(sc)	do {sc->flags |= CXGB_BUSY;} while (0)
 #define CLR_BUSY(sc)	do {sc->flags &= ~CXGB_BUSY;} while (0)
diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c
index 02942b98d8d..eeb61d40b01 100644
--- a/sys/dev/cxgb/cxgb_main.c
+++ b/sys/dev/cxgb/cxgb_main.c
@@ -84,11 +84,9 @@ __FBSDID("$FreeBSD$");
 
 static int cxgb_setup_interrupts(adapter_t *);
 static void cxgb_teardown_interrupts(adapter_t *);
-static int cxgb_begin_op(struct port_info *, const char *);
-static int cxgb_begin_detach(struct port_info *);
-static int cxgb_end_op(struct port_info *);
 static void cxgb_init(void *);
-static int cxgb_init_synchronized(struct port_info *);
+static int cxgb_init_locked(struct port_info *);
+static int cxgb_uninit_locked(struct port_info *);
 static int cxgb_uninit_synchronized(struct port_info *);
 static int cxgb_ioctl(struct ifnet *, unsigned long, caddr_t);
 static int cxgb_media_change(struct ifnet *);
@@ -1113,7 +1111,14 @@ cxgb_port_detach(device_t dev)
 	p = device_get_softc(dev);
 	sc = p->adapter;
 
-	cxgb_begin_detach(p);
+	/* Tell cxgb_ioctl and if_init that the port is going away */
+	ADAPTER_LOCK(sc);
+	SET_DOOMED(p);
+	wakeup(&sc->flags);
+	while (IS_BUSY(sc))
+		mtx_sleep(&sc->flags, &sc->lock, 0, "cxgbdtch", 0);
+	SET_BUSY(sc);
+	ADAPTER_UNLOCK(sc);
 
 	if (p->port_cdev != NULL)
 		destroy_dev(p->port_cdev);
@@ -1133,7 +1138,10 @@ cxgb_port_detach(device_t dev)
 	if_free(p->ifp);
 	p->ifp = NULL;
 
-	cxgb_end_op(p);
+	ADAPTER_LOCK(sc);
+	CLR_BUSY(sc);
+	wakeup_one(&sc->flags);
+	ADAPTER_UNLOCK(sc);
 	return (0);
 }
 
@@ -1688,12 +1696,13 @@ cxgb_up(struct adapter *sc)
 {
 	int err = 0;
 
-	ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
 	KASSERT(sc->open_device_map == 0, ("%s: device(s) already open (%x)",
 					   __func__, sc->open_device_map));
 
 	if ((sc->flags & FULL_INIT_DONE) == 0) {
 
+		ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
+
 		if ((sc->flags & FW_UPTODATE) == 0)
 			if ((err = upgrade_fw(sc)))
 				goto out;
@@ -1755,8 +1764,6 @@ out:
 static void
 cxgb_down(struct adapter *sc)
 {
-	ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
-
 	t3_sge_stop(sc);
 	t3_intr_disable(sc);
 }
@@ -1767,8 +1774,6 @@ offload_open(struct port_info *pi)
 	struct adapter *sc = pi->adapter;
 	struct t3cdev *tdev = &sc->tdev;
 
-	ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
-
 	setbit(&sc->open_device_map, OFFLOAD_DEVMAP_BIT);
 
 	t3_tp_set_offload_mode(sc, 1);
@@ -1802,95 +1807,6 @@ offload_close(struct t3cdev *tdev)
 	return (0);
 }
 
-/*
- * Begin a synchronized operation.  If this call succeeds, it is guaranteed that
- * no one will remove the port or its ifp from underneath the caller.  Caller is
- * also granted exclusive access to open_device_map.
- *
- * operation here means init, uninit, detach, and ioctl service.
- *
- * May fail.
- * EINTR (ctrl-c pressed during ifconfig for example).
- * ENXIO (port is about to detach - due to kldunload for example).
- */
-int
-cxgb_begin_op(struct port_info *p, const char *wmsg)
-{
-	int rc = 0;
-	struct adapter *sc = p->adapter;
-
-	ADAPTER_LOCK(sc);
-
-	while (!IS_DOOMED(p) && IS_BUSY(sc)) {
-		if (mtx_sleep(&sc->flags, &sc->lock, PCATCH, wmsg, 0)) {
-			rc = EINTR;
-			goto done;
-		}
-	}
-
-	if (IS_DOOMED(p))
-		rc = ENXIO;
-	else if (!IS_BUSY(sc))
-		SET_BUSY(sc);
-	else {
-		KASSERT(0, ("%s: port %d, p->flags = %x , sc->flags = %x",
-			    __func__, p->port_id, p->flags, sc->flags));
-		rc = EDOOFUS;
-	}
-
-done:
-	ADAPTER_UNLOCK(sc);
-	return (rc);
-}
-
-/*
- * End a synchronized operation.  Read comment block above cxgb_begin_op.
- */
-int
-cxgb_end_op(struct port_info *p)
-{
-	struct adapter *sc = p->adapter;
-
-	ADAPTER_LOCK(sc);
-	KASSERT(IS_BUSY(sc), ("%s: not busy.", __func__));
-	CLR_BUSY(sc);
-	wakeup_one(&sc->flags);
-	ADAPTER_UNLOCK(sc);
-
-	return (0);
-}
-
-/*
- * Prepare for port detachment.  Detach is a special kind of synchronized
- * operation.  Also read comment before cxgb_begin_op.
- */
-static int
-cxgb_begin_detach(struct port_info *p)
-{
-	struct adapter *sc = p->adapter;
-
-	/*
-	 * Inform those waiting for this port that it is going to be destroyed
-	 * and they should not continue further.  (They'll return with ENXIO).
-	 */
-	ADAPTER_LOCK(sc);
-	SET_DOOMED(p);
-	wakeup(&sc->flags);
-	ADAPTER_UNLOCK(sc);
-
-	/*
-	 * Wait for in-progress operations.
-	 */
-	ADAPTER_LOCK(sc);
-	while (IS_BUSY(sc)) {
-		mtx_sleep(&sc->flags, &sc->lock, 0, "cxgbdtch", 0);
-	}
-	SET_BUSY(sc);
-	ADAPTER_UNLOCK(sc);
-
-	return (0);
-}
-
 /*
  * if_init for cxgb ports.
  */
@@ -1898,25 +1814,49 @@ static void
 cxgb_init(void *arg)
 {
 	struct port_info *p = arg;
+	struct adapter *sc = p->adapter;
 
-	if (cxgb_begin_op(p, "cxgbinit"))
-		return;
-
-	cxgb_init_synchronized(p);
-	cxgb_end_op(p);
+	ADAPTER_LOCK(sc);
+	cxgb_init_locked(p); /* releases adapter lock */
+	ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
 }
 
 static int
-cxgb_init_synchronized(struct port_info *p)
+cxgb_init_locked(struct port_info *p)
 {
 	struct adapter *sc = p->adapter;
 	struct ifnet *ifp = p->ifp;
 	struct cmac *mac = &p->mac;
-	int i, rc;
+	int i, rc = 0, may_sleep = 0;
+
+	ADAPTER_LOCK_ASSERT_OWNED(sc);
+
+	while (!IS_DOOMED(p) && IS_BUSY(sc)) {
+		if (mtx_sleep(&sc->flags, &sc->lock, PCATCH, "cxgbinit", 0)) {
+			rc = EINTR;
+			goto done;
+		}
+	}
+	if (IS_DOOMED(p)) {
+		rc = ENXIO;
+		goto done;
+	}
+	KASSERT(!IS_BUSY(sc), ("%s: controller busy.", __func__));
+
+	/*
+	 * The code that runs during one-time adapter initialization can sleep
+	 * so it's important not to hold any locks across it.
+	 */
+	may_sleep = sc->flags & FULL_INIT_DONE ? 0 : 1;
+
+	if (may_sleep) {
+		SET_BUSY(sc);
+		ADAPTER_UNLOCK(sc);
+	}
 
 	if (sc->open_device_map == 0) {
 		if ((rc = cxgb_up(sc)) != 0)
-			return (rc);
+			goto done;
 
 		if (is_offload(sc) && !ofld_disable && offload_open(p))
 			log(LOG_WARNING,
@@ -1924,6 +1864,11 @@ cxgb_init_synchronized(struct port_info *p)
 	}
 
 	PORT_LOCK(p);
+	if (isset(&sc->open_device_map, p->port_id) &&
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+		PORT_UNLOCK(p);
+		goto done;
+	}
 	t3_port_intr_enable(sc, p->port_id);
 	if (!mac->multiport) 
 		t3_mac_init(mac);
@@ -1947,7 +1892,48 @@ cxgb_init_synchronized(struct port_info *p)
 	/* all ok */
 	setbit(&sc->open_device_map, p->port_id);
 
-	return (0);
+done:
+	if (may_sleep) {
+		ADAPTER_LOCK(sc);
+		KASSERT(IS_BUSY(sc), ("%s: controller not busy.", __func__));
+		CLR_BUSY(sc);
+		wakeup_one(&sc->flags);
+	}
+	ADAPTER_UNLOCK(sc);
+	return (rc);
+}
+
+static int
+cxgb_uninit_locked(struct port_info *p)
+{
+	struct adapter *sc = p->adapter;
+	int rc;
+
+	ADAPTER_LOCK_ASSERT_OWNED(sc);
+
+	while (!IS_DOOMED(p) && IS_BUSY(sc)) {
+		if (mtx_sleep(&sc->flags, &sc->lock, PCATCH, "cxgbunin", 0)) {
+			rc = EINTR;
+			goto done;
+		}
+	}
+	if (IS_DOOMED(p)) {
+		rc = ENXIO;
+		goto done;
+	}
+	KASSERT(!IS_BUSY(sc), ("%s: controller busy.", __func__));
+	SET_BUSY(sc);
+	ADAPTER_UNLOCK(sc);
+
+	rc = cxgb_uninit_synchronized(p);
+
+	ADAPTER_LOCK(sc);
+	KASSERT(IS_BUSY(sc), ("%s: controller not busy.", __func__));
+	CLR_BUSY(sc);
+	wakeup_one(&sc->flags);
+done:
+	ADAPTER_UNLOCK(sc);
+	return (rc);
 }
 
 /*
@@ -1959,6 +1945,11 @@ cxgb_uninit_synchronized(struct port_info *pi)
 	struct adapter *sc = pi->adapter;
 	struct ifnet *ifp = pi->ifp;
 
+	/*
+	 * taskqueue_drain may cause a deadlock if the adapter lock is held.
+	 */
+	ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
+
 	/*
 	 * Clear this port's bit from the open device map, and then drain all
 	 * the tasks that can access/manipulate this port's port_info or ifp.
@@ -2036,19 +2027,21 @@ static int
 cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
 {
 	struct port_info *p = ifp->if_softc;
+	struct adapter *sc = p->adapter;
 	struct ifreq *ifr = (struct ifreq *)data;
-	int flags, error = 0, mtu, handle_unsynchronized = 0;
+	int flags, error = 0, mtu;
 	uint32_t mask;
 
-	if ((error = cxgb_begin_op(p, "cxgbioct")) != 0)
-		return (error);
-
-	/*
-	 * Only commands that should be handled within begin-op/end-op are
-	 * serviced in this switch statement.  See handle_unsynchronized.
-	 */
 	switch (command) {
 	case SIOCSIFMTU:
+		ADAPTER_LOCK(sc);
+		error = IS_DOOMED(p) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
+		if (error) {
+fail:
+			ADAPTER_UNLOCK(sc);
+			return (error);
+		}
+
 		mtu = ifr->ifr_mtu;
 		if ((mtu < ETHERMIN) || (mtu > ETHERMTU_JUMBO)) {
 			error = EINVAL;
@@ -2058,35 +2051,57 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
 			cxgb_update_mac_settings(p);
 			PORT_UNLOCK(p);
 		}
-
+		ADAPTER_UNLOCK(sc);
 		break;
 	case SIOCSIFFLAGS:
+		ADAPTER_LOCK(sc);
+		if (IS_DOOMED(p)) {
+			error = ENXIO;
+			goto fail;
+		}
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				flags = p->if_flags;
 				if (((ifp->if_flags ^ flags) & IFF_PROMISC) ||
 				    ((ifp->if_flags ^ flags) & IFF_ALLMULTI)) {
+					if (IS_BUSY(sc)) {
+						error = EBUSY;
+						goto fail;
+					}
 					PORT_LOCK(p);
 					cxgb_update_mac_settings(p);
 					PORT_UNLOCK(p);
 				}
+				ADAPTER_UNLOCK(sc);
 			} else
-				error = cxgb_init_synchronized(p);
+				error = cxgb_init_locked(p);
 			p->if_flags = ifp->if_flags;
 		} else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-			error = cxgb_uninit_synchronized(p);
-		
+			error = cxgb_uninit_locked(p);
+
+		ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		ADAPTER_LOCK(sc);
+		error = IS_DOOMED(p) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
+		if (error)
+			goto fail;
+
 		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 			PORT_LOCK(p);
 			cxgb_update_mac_settings(p);
 			PORT_UNLOCK(p);
 		}
+		ADAPTER_UNLOCK(sc);
 
 		break;
 	case SIOCSIFCAP:
+		ADAPTER_LOCK(sc);
+		error = IS_DOOMED(p) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
+		if (error)
+			goto fail;
+
 		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 		if (mask & IFCAP_TXCSUM) {
 			if (IFCAP_TXCSUM & ifp->if_capenable) {
@@ -2136,34 +2151,20 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
 				PORT_UNLOCK(p);
 			}
 		}
-		if (mask & IFCAP_VLAN_HWCSUM) {
+		if (mask & IFCAP_VLAN_HWCSUM)
 			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
-		}
 
 #ifdef VLAN_CAPABILITIES
 		VLAN_CAPABILITIES(ifp);
 #endif
+		ADAPTER_UNLOCK(sc);
+		break;
+	case SIOCSIFMEDIA:
+	case SIOCGIFMEDIA:
+		error = ifmedia_ioctl(ifp, ifr, &p->media, command);
 		break;
 	default:
-		handle_unsynchronized = 1;
-		break;
-	}
-
-	/*
-	 * We don't want to call anything outside the driver while inside a
-	 * begin-op/end-op block.  If it calls us back (eg.  ether_ioctl may
-	 * call cxgb_init) we may deadlock if the state is already marked busy.
-	 *
-	 * XXX: this probably opens a small race window with kldunload...
-	 */
-	cxgb_end_op(p);
-
-	/* The IS_DOOMED check is racy, we're clutching at straws here */
-	if (handle_unsynchronized && !IS_DOOMED(p)) {
-		if (command == SIOCSIFMEDIA || command == SIOCGIFMEDIA)
-			error = ifmedia_ioctl(ifp, ifr, &p->media, command);
-		else
-			error = ether_ioctl(ifp, command, data);
+		error = ether_ioctl(ifp, command, data);
 	}
 
 	return (error);
diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c
index 7565347c040..d993df7dc32 100644
--- a/sys/dev/cxgb/cxgb_sge.c
+++ b/sys/dev/cxgb/cxgb_sge.c
@@ -541,8 +541,12 @@ t3_sge_prep(adapter_t *adap, struct sge_params *p)
 	jumbo_q_size = min(nmbjumbo4/(3*nqsets), JUMBO_Q_SIZE);
 #endif
 	while (!powerof2(jumbo_q_size))
-		jumbo_q_size--;		
-	
+		jumbo_q_size--;
+
+	if (fl_q_size < (FL_Q_SIZE / 4) || jumbo_q_size < (JUMBO_Q_SIZE / 2))
+		device_printf(adap->dev,
+		    "Insufficient clusters and/or jumbo buffers.\n");
+
 	/* XXX Does ETHER_ALIGN need to be accounted for here? */
 	p->max_pkt_size = adap->sge.qs[0].fl[1].buf_size - sizeof(struct cpl_rx_data);
 

From cbbe4a754c59dbf434df492ef2006dc101aec306 Mon Sep 17 00:00:00 2001
From: Navdeep Parhar 
Date: Thu, 21 Jan 2010 10:12:21 +0000
Subject: [PATCH 1248/2592] MFC r201416:

Avoid NULL dereference in arpresolve.

Requested by: kib@
---
 sys/netinet/if_ether.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 09b82609166..47588b41132 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -366,8 +366,8 @@ retry:
 	if (la->la_asked < V_arp_maxtries)
 		error = EWOULDBLOCK;	/* First request. */
 	else
-		error =
-			(rt0->rt_flags & RTF_GATEWAY) ? EHOSTUNREACH : EHOSTDOWN;
+		error = rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) ?
+		    EHOSTUNREACH : EHOSTDOWN;
 
 	if (renew) {
 		LLE_ADDREF(la);

From 73510ebf05c186924c30ad5efe0e839671197242 Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Thu, 21 Jan 2010 10:16:21 +0000
Subject: [PATCH 1249/2592] MFC of 202280, 202281

- Remove -d option, whois.nic.mil doesn't exist anymore.

- Make whois capable of searching for IPv6 addresses just like it can
  do for IPv4 addresses without having to explicetly specify that the
  ARIN server should be used to get the initial information.

PR:		bin/142507, bin/128725
Submitted by:	Dan Mahoney , "Matt D. Harris" 
---
 usr.bin/whois/whois.1 |  7 +------
 usr.bin/whois/whois.c | 12 ++++++------
 2 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/usr.bin/whois/whois.1 b/usr.bin/whois/whois.1
index 56db1606f0e..45b38678687 100644
--- a/usr.bin/whois/whois.1
+++ b/usr.bin/whois/whois.1
@@ -40,7 +40,7 @@
 .Nd "Internet domain name and network number directory service"
 .Sh SYNOPSIS
 .Nm
-.Op Fl aAbdfgiIklmQrR
+.Op Fl aAbfgiIklmQrR
 .Op Fl c Ar country-code | Fl h Ar host
 .Op Fl p Ar port
 .Ar name ...
@@ -82,11 +82,6 @@ This is the equivalent of using the
 .Fl h
 option with an argument of
 .Qq Ar country-code Ns Li .whois-servers.net .
-.It Fl d
-Use the US Department of Defense
-database.
-It contains points of contact for subdomains of
-.Pa .MIL .
 .It Fl f
 Use the African Network Information Centre
 .Pq Tn AfriNIC
diff --git a/usr.bin/whois/whois.c b/usr.bin/whois/whois.c
index adb62320390..864a58539b5 100644
--- a/usr.bin/whois/whois.c
+++ b/usr.bin/whois/whois.c
@@ -63,7 +63,6 @@ __FBSDID("$FreeBSD$");
 #define	ABUSEHOST	"whois.abuse.net"
 #define	NICHOST		"whois.crsnic.net"
 #define	INICHOST	"whois.networksolutions.com"
-#define	DNICHOST	"whois.nic.mil"
 #define	GNICHOST	"whois.nic.gov"
 #define	ANICHOST	"whois.arin.net"
 #define	LNICHOST	"whois.lacnic.net"
@@ -109,7 +108,7 @@ main(int argc, char *argv[])
 
 	country = host = qnichost = NULL;
 	flags = use_qnichost = 0;
-	while ((ch = getopt(argc, argv, "aAbc:dfgh:iIklmp:QrR6")) != -1) {
+	while ((ch = getopt(argc, argv, "aAbc:fgh:iIklmp:QrR6")) != -1) {
 		switch (ch) {
 		case 'a':
 			host = ANICHOST;
@@ -123,9 +122,6 @@ main(int argc, char *argv[])
 		case 'c':
 			country = optarg;
 			break;
-		case 'd':
-			host = DNICHOST;
-			break;
 		case 'f':
 			host = FNICHOST;
 			break;
@@ -219,6 +215,10 @@ choose_server(char *domain)
 {
 	char *pos, *retval;
 
+	if (strchr(domain, ':')) {
+		s_asprintf(&retval, "%s", ANICHOST);
+		return (retval);
+	}
 	for (pos = strchr(domain, '\0'); pos > domain && *--pos == '.';)
 		*pos = '\0';
 	if (*domain == '\0')
@@ -364,7 +364,7 @@ static void
 usage(void)
 {
 	fprintf(stderr,
-	    "usage: whois [-aAbdfgiIklmQrR6] [-c country-code | -h hostname] "
+	    "usage: whois [-aAbfgiIklmQrR6] [-c country-code | -h hostname] "
 	    "[-p port] name ...\n");
 	exit(EX_USAGE);
 }

From a5cc755e58ff9cad66a5d055f9cac61c3dc86030 Mon Sep 17 00:00:00 2001
From: Ruslan Ermilov 
Date: Thu, 21 Jan 2010 13:15:14 +0000
Subject: [PATCH 1250/2592] MFC r202578 and r202579:

If CTAGS is not set or set to something other than "ctags" or "gtags",
"cleandepend" was not removing the .depend file; fixed. [1]

Allow the CTAGS to be set to something other than "gtags" or "ctags",
but assume it supports a ctags(1)-compatible syntax. [2]

PR:		126747 [1], 46676 [2]
---
 share/mk/bsd.dep.mk | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/share/mk/bsd.dep.mk b/share/mk/bsd.dep.mk
index cdcadb034b4..7711d80ed0b 100644
--- a/share/mk/bsd.dep.mk
+++ b/share/mk/bsd.dep.mk
@@ -58,14 +58,14 @@ DEPENDFILE?=	.depend
 # Keep `tags' here, before SRCS are mangled below for `depend'.
 .if !target(tags) && defined(SRCS) && !defined(NO_TAGS)
 tags: ${SRCS}
-.if ${CTAGS:T} == "ctags"
-	@${CTAGS} ${CTAGSFLAGS} -f /dev/stdout \
-	    ${.ALLSRC:N*.h} | sed "s;${.CURDIR}/;;" > ${.TARGET}
-.elif ${CTAGS:T} == "gtags"
+.if ${CTAGS:T} == "gtags"
 	@cd ${.CURDIR} && ${CTAGS} ${GTAGSFLAGS} ${.OBJDIR}
 .if defined(HTML)
 	@cd ${.CURDIR} && htags ${HTAGSFLAGS} -d ${.OBJDIR} ${.OBJDIR}
 .endif
+.else
+	@${CTAGS} ${CTAGSFLAGS} -f /dev/stdout \
+	    ${.ALLSRC:N*.h} | sed "s;${.CURDIR}/;;" > ${.TARGET}
 .endif
 .endif
 
@@ -175,13 +175,13 @@ afterdepend:
 .if !target(cleandepend)
 cleandepend:
 .if defined(SRCS)
-.if ${CTAGS:T} == "ctags"
-	rm -f ${DEPENDFILE} tags
-.elif ${CTAGS:T} == "gtags"
+.if ${CTAGS:T} == "gtags"
 	rm -f ${DEPENDFILE} GPATH GRTAGS GSYMS GTAGS
 .if defined(HTML)
 	rm -rf HTML
 .endif
+.else
+	rm -f ${DEPENDFILE} tags
 .endif
 .endif
 .endif

From 4b2625a76f4cc1d9c1d0fb85c28f45210d42b9c2 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 21 Jan 2010 15:10:20 +0000
Subject: [PATCH 1251/2592] MFC 202286: Update the ident for the XENHVM kernel
 config to match the filename.

---
 sys/amd64/conf/XENHVM | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/amd64/conf/XENHVM b/sys/amd64/conf/XENHVM
index 1536e3c74b6..f875f5af7ed 100644
--- a/sys/amd64/conf/XENHVM
+++ b/sys/amd64/conf/XENHVM
@@ -19,7 +19,7 @@
 # $FreeBSD$
 
 cpu		HAMMER
-ident		GENERIC
+ident		XENHVM
 
 # To statically compile in device wiring instead of /boot/device.hints
 #hints		"GENERIC.hints"		# Default places to look for devices.

From 4e31204f251576c275f614cf8f1ccf3227a939f3 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Thu, 21 Jan 2010 16:31:45 +0000
Subject: [PATCH 1252/2592] MFC: r202290

Build iwi(4) and iwifw(4) modules on amd64 as well.
---
 sys/modules/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 3432da12854..044976dc3d4 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -508,6 +508,8 @@ _ipmi=		ipmi
 _ips=		ips
 _ipw=		ipw
 _ipwfw=		ipwfw
+_iwi=		iwi
+_iwifw=		iwifw
 _iwn=		iwn
 _iwnfw=		iwnfw
 _ixgb=		ixgb

From 828c6b73abc7ab3bbf545a88a59618326e0695a3 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Thu, 21 Jan 2010 17:37:25 +0000
Subject: [PATCH 1253/2592] MFC: r202587

Add epic(4) also here.
---
 sys/sparc64/conf/NOTES | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/sparc64/conf/NOTES b/sys/sparc64/conf/NOTES
index e189286bd90..d9c5be538ea 100644
--- a/sys/sparc64/conf/NOTES
+++ b/sys/sparc64/conf/NOTES
@@ -43,6 +43,7 @@ device		mc146818	# Motorola MC146818 and compatible clocks
 #
 
 device		auxio		# auxiliary I/O device
+device		epic		# Sun Fire V215/V245 LEDs
 device		creator		# Creator, Creator3D and Elite3D framebuffers
 device		machfb		# ATI Mach64 framebuffers
 

From 7b10638c5b53a09b1f3ac58c4a48df0433288ade Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 21 Jan 2010 17:54:29 +0000
Subject: [PATCH 1254/2592] MFC 198134,198149,198170,198171,198391,200948: 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, i386, and sparc64 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().

---
 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/sparc64/include/intr_machdep.h |   1 +
 sys/sparc64/pci/psycho.c           |  14 ++++
 sys/sparc64/pci/schizo.c           |  14 ++++
 sys/sparc64/sparc64/intr_machdep.c |  25 +++++++
 sys/sparc64/sparc64/nexus.c        |  16 ++++-
 sys/sys/bus.h                      |   5 ++
 sys/sys/interrupt.h                |   4 +-
 18 files changed, 357 insertions(+), 7 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..989780fdc60
--- /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 systat 1 ,
+.Xr vmstat 8 ,
+.Xr device 9 ,
+.Xr printf 9
+.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 4b2799fbd60..8af826cab4f 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 \
@@ -404,6 +405,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..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
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..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
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..d22bfeaa311 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 found 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 225ebb61c62..f470487b3e7 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -3529,6 +3529,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().
  *
@@ -3833,6 +3851,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/sparc64/include/intr_machdep.h b/sys/sparc64/include/intr_machdep.h
index ef24d187ae1..46a61969389 100644
--- a/sys/sparc64/include/intr_machdep.h
+++ b/sys/sparc64/include/intr_machdep.h
@@ -93,6 +93,7 @@ extern struct intr_vector intr_vectors[];
 void	intr_add_cpu(u_int cpu);
 #endif
 int	intr_bind(int vec, u_char cpu);
+int	intr_describe(int vec, void *ih, const char *descr);
 void	intr_setup(int level, ih_func_t *ihf, int pri, iv_func_t *ivf,
 	    void *iva);
 void	intr_init1(void);
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index 0eadc4b557f..486136a4600 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -115,6 +115,7 @@ static bus_alloc_resource_t psycho_alloc_resource;
 static bus_activate_resource_t psycho_activate_resource;
 static bus_deactivate_resource_t psycho_deactivate_resource;
 static bus_release_resource_t psycho_release_resource;
+static bus_describe_intr_t psycho_describe_intr;
 static bus_get_dma_tag_t psycho_get_dma_tag;
 static pcib_maxslots_t psycho_maxslots;
 static pcib_read_config_t psycho_read_config;
@@ -139,6 +140,7 @@ static device_method_t psycho_methods[] = {
 	DEVMETHOD(bus_activate_resource,	psycho_activate_resource),
 	DEVMETHOD(bus_deactivate_resource,	psycho_deactivate_resource),
 	DEVMETHOD(bus_release_resource,	psycho_release_resource),
+	DEVMETHOD(bus_describe_intr,	psycho_describe_intr),
 	DEVMETHOD(bus_get_dma_tag,	psycho_get_dma_tag),
 
 	/* pcib interface */
@@ -1261,6 +1263,18 @@ psycho_teardown_intr(device_t dev, device_t child, struct resource *vec,
 	return (bus_generic_teardown_intr(dev, child, vec, cookie));
 }
 
+static int
+psycho_describe_intr(device_t dev, device_t child, struct resource *vec,
+    void *cookie, const char *descr)
+{
+	struct psycho_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->sc_mode == PSYCHO_MODE_SABRE)
+		cookie = ((struct psycho_dma_sync *)cookie)->pds_cookie;
+	return (bus_generic_describe_intr(dev, child, vec, cookie, descr));
+}
+
 static struct resource *
 psycho_alloc_resource(device_t bus, device_t child, int type, int *rid,
     u_long start, u_long end, u_long count, u_int flags)
diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index 4703571f131..f783b23f1c4 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -113,6 +113,7 @@ static bus_alloc_resource_t schizo_alloc_resource;
 static bus_activate_resource_t schizo_activate_resource;
 static bus_deactivate_resource_t schizo_deactivate_resource;
 static bus_release_resource_t schizo_release_resource;
+static bus_describe_intr_t schizo_describe_intr;
 static bus_get_dma_tag_t schizo_get_dma_tag;
 static pcib_maxslots_t schizo_maxslots;
 static pcib_read_config_t schizo_read_config;
@@ -137,6 +138,7 @@ static device_method_t schizo_methods[] = {
 	DEVMETHOD(bus_activate_resource,	schizo_activate_resource),
 	DEVMETHOD(bus_deactivate_resource,	schizo_deactivate_resource),
 	DEVMETHOD(bus_release_resource,	schizo_release_resource),
+	DEVMETHOD(bus_describe_intr,	schizo_describe_intr),
 	DEVMETHOD(bus_get_dma_tag,	schizo_get_dma_tag),
 
 	/* pcib interface */
@@ -1282,6 +1284,18 @@ schizo_teardown_intr(device_t dev, device_t child, struct resource *vec,
 	return (bus_generic_teardown_intr(dev, child, vec, cookie));
 }
 
+static int
+schizo_describe_intr(device_t dev, device_t child, struct resource *vec,
+    void *cookie, const char *descr)
+{
+	struct schizo_softc *sc;
+
+	sc = device_get_softc(dev);
+	if ((sc->sc_flags & SCHIZO_FLAGS_CDMA) != 0)
+		cookie = ((struct schizo_dma_sync *)cookie)->sds_cookie;
+	return (bus_generic_describe_intr(dev, child, vec, cookie, descr));
+}
+
 static struct resource *
 schizo_alloc_resource(device_t bus, device_t child, int type, int *rid,
     u_long start, u_long end, u_long count, u_int flags)
diff --git a/sys/sparc64/sparc64/intr_machdep.c b/sys/sparc64/sparc64/intr_machdep.c
index f47ad0eed1a..7a73bbc6768 100644
--- a/sys/sparc64/sparc64/intr_machdep.c
+++ b/sys/sparc64/sparc64/intr_machdep.c
@@ -413,6 +413,31 @@ inthand_remove(int vec, void *cookie)
 	return (error);
 }
 
+/* Add a description to an active interrupt handler. */
+int
+intr_describe(int vec, void *ih, const char *descr)
+{
+	struct intr_vector *iv;
+	int error;
+
+	if (vec < 0 || vec >= IV_MAX)
+		return (EINVAL);
+	sx_xlock(&intr_table_lock);
+	iv = &intr_vectors[vec];
+	if (iv == NULL) {
+		sx_xunlock(&intr_table_lock);
+		return (EINVAL);
+	}
+	error = intr_event_describe_handler(iv->iv_event, ih, descr);
+	if (error) {
+		sx_xunlock(&intr_table_lock);
+		return (error);
+	}
+	intrcnt_updatename(vec, iv->iv_event->ie_fullname, 0);
+	sx_xunlock(&intr_table_lock);
+	return (error);
+}
+
 #ifdef SMP
 /*
  * Support for balancing interrupt sources across CPUs.  For now we just
diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c
index 04c2ddbcbee..0f96a2101d3 100644
--- a/sys/sparc64/sparc64/nexus.c
+++ b/sys/sparc64/sparc64/nexus.c
@@ -90,12 +90,13 @@ static bus_activate_resource_t nexus_activate_resource;
 static bus_deactivate_resource_t nexus_deactivate_resource;
 static bus_release_resource_t nexus_release_resource;
 static bus_get_resource_list_t nexus_get_resource_list;
+#ifdef SMP
+static bus_bind_intr_t nexus_bind_intr;
+#endif
+static bus_describe_intr_t nexus_describe_intr;
 static bus_get_dma_tag_t nexus_get_dma_tag;
 static ofw_bus_get_devinfo_t nexus_get_devinfo;
 
-#ifdef SMP
-static int nexus_bind_intr(device_t, device_t, struct resource *, int);
-#endif
 static int nexus_inlist(const char *, const char *const *);
 static struct nexus_devinfo * nexus_setup_dinfo(device_t, phandle_t);
 static void nexus_destroy_dinfo(struct nexus_devinfo *);
@@ -128,6 +129,7 @@ static device_method_t nexus_methods[] = {
 #ifdef SMP
 	DEVMETHOD(bus_bind_intr,	nexus_bind_intr),
 #endif
+	DEVMETHOD(bus_describe_intr,	nexus_describe_intr),
 	DEVMETHOD(bus_get_dma_tag,	nexus_get_dma_tag),
 
 	/* ofw_bus interface */
@@ -329,6 +331,14 @@ nexus_bind_intr(device_t dev, device_t child, struct resource *r, int cpu)
 }
 #endif
 
+static int
+nexus_describe_intr(device_t dev, device_t child, struct resource *r,
+    void *cookie, const char *descr)
+{
+
+	return (intr_describe(rman_get_start(r), cookie, descr));
+}
+
 static struct resource *
 nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
     u_long start, u_long end, u_long count, u_int flags)
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..028fa7f3098 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. */
@@ -168,6 +168,8 @@ 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);

From 49cc13441b0f01b031ce131443f8416eb979e766 Mon Sep 17 00:00:00 2001
From: John Baldwin 
Date: Thu, 21 Jan 2010 19:11:18 +0000
Subject: [PATCH 1255/2592] MFC 198411: - 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[].

---
 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 f470487b3e7..eaec75b83de 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -3862,8 +3862,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 4b5ab111138e1aade234dffa8fc06f076424bc50 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Fri, 22 Jan 2010 03:50:43 +0000
Subject: [PATCH 1256/2592] MFC rev. 202097: Use io(4) for I/O port access on
 ia64, rather than through sysarch(2).

---
 sys/amd64/amd64/io.c          |   9 ++
 sys/amd64/include/iodev.h     |   1 +
 sys/conf/files.ia64           |   2 +
 sys/dev/io/iodev.c            |   3 +-
 sys/i386/i386/io.c            |   9 ++
 sys/i386/include/iodev.h      |   1 +
 sys/ia64/conf/DEFAULTS        |   1 +
 sys/ia64/ia64/iodev_machdep.c | 160 ++++++++++++++++++++++++++++++++++
 sys/ia64/ia64/sys_machdep.c   |  63 -------------
 sys/ia64/include/iodev.h      |  51 +++++++++++
 sys/ia64/include/sysarch.h    |   9 --
 11 files changed, 235 insertions(+), 74 deletions(-)
 create mode 100644 sys/ia64/ia64/iodev_machdep.c
 create mode 100644 sys/ia64/include/iodev.h

diff --git a/sys/amd64/amd64/io.c b/sys/amd64/amd64/io.c
index 02d9c8dab23..09d6e896582 100644
--- a/sys/amd64/amd64/io.c
+++ b/sys/amd64/amd64/io.c
@@ -76,3 +76,12 @@ ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
 
 	return (0);
 }
+
+/* ARGSUSED */
+int
+ioioctl(struct cdev *dev __unused, u_long cmd __unused, caddr_t data __unused,
+    int fflag __unused, struct thread *td __unused)
+{
+
+	return (ENXIO);
+}
diff --git a/sys/amd64/include/iodev.h b/sys/amd64/include/iodev.h
index 4b35d8b03fa..1a0a17a9561 100644
--- a/sys/amd64/include/iodev.h
+++ b/sys/amd64/include/iodev.h
@@ -28,3 +28,4 @@
 
 d_open_t	ioopen;
 d_close_t	ioclose;
+d_ioctl_t	ioioctl;
diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64
index 032407c073b..4ad5aa76884 100644
--- a/sys/conf/files.ia64
+++ b/sys/conf/files.ia64
@@ -56,6 +56,7 @@ dev/atkbdc/psm.c		optional	psm atkbdc
 dev/fb/fb.c			optional	fb | vga
 dev/fb/vga.c			optional	vga
 dev/hwpmc/hwpmc_ia64.c		optional	hwpmc
+dev/io/iodev.c			optional	io
 dev/kbd/kbd.c			optional	atkbd | sc | ukbd | usb2_input_kbd
 dev/syscons/scterm-teken.c	optional	sc
 dev/syscons/scvgarndr.c		optional	sc vga
@@ -89,6 +90,7 @@ 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/iodev_machdep.c	optional	io
 ia64/ia64/locore.S		standard	no-obj
 ia64/ia64/machdep.c		standard
 ia64/ia64/mca.c			standard
diff --git a/sys/dev/io/iodev.c b/sys/dev/io/iodev.c
index 8c2cebdf364..b142a39c610 100644
--- a/sys/dev/io/iodev.c
+++ b/sys/dev/io/iodev.c
@@ -41,8 +41,6 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 
-#include 
-
 #include 
 #include 
 
@@ -54,6 +52,7 @@ static struct cdevsw io_cdevsw = {
 	.d_version =	D_VERSION,
 	.d_open =	ioopen,
 	.d_close =	ioclose,
+	.d_ioctl =	ioioctl,
 	.d_name =	"io",
 };
 
diff --git a/sys/i386/i386/io.c b/sys/i386/i386/io.c
index eb0deb67c5f..c392af5f38d 100644
--- a/sys/i386/i386/io.c
+++ b/sys/i386/i386/io.c
@@ -76,3 +76,12 @@ ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
 
 	return (0);
 }
+
+/* ARGSUSED */
+int
+ioioctl(struct cdev *dev __unused, u_long cmd __unused, caddr_t data __unused,
+    int fflag __unused, struct thread *td __unused)
+{
+
+	return (ENXIO);
+}
diff --git a/sys/i386/include/iodev.h b/sys/i386/include/iodev.h
index 4b35d8b03fa..1a0a17a9561 100644
--- a/sys/i386/include/iodev.h
+++ b/sys/i386/include/iodev.h
@@ -28,3 +28,4 @@
 
 d_open_t	ioopen;
 d_close_t	ioclose;
+d_ioctl_t	ioioctl;
diff --git a/sys/ia64/conf/DEFAULTS b/sys/ia64/conf/DEFAULTS
index 625ff90955c..2cb2330054b 100644
--- a/sys/ia64/conf/DEFAULTS
+++ b/sys/ia64/conf/DEFAULTS
@@ -9,6 +9,7 @@ machine		ia64
 device		acpi		# ACPI support
 
 # Pseudo devices.
+device		io		# I/O & EFI runtime device
 device		mem		# Memory and kernel memory devices
 
 # UART chips on this platform
diff --git a/sys/ia64/ia64/iodev_machdep.c b/sys/ia64/ia64/iodev_machdep.c
new file mode 100644
index 00000000000..498a042cfce
--- /dev/null
+++ b/sys/ia64/ia64/iodev_machdep.c
@@ -0,0 +1,160 @@
+/*-
+ * Copyright (c) 2010 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 int iodev_pio_read(struct iodev_pio_req *req);
+static int iodev_pio_write(struct iodev_pio_req *req);
+
+/* ARGSUSED */
+int
+ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
+    struct thread *td)
+{
+	int error;
+
+	error = priv_check(td, PRIV_IO);
+	if (error == 0)
+		error = securelevel_gt(td->td_ucred, 0);
+
+	return (error);
+}
+
+/* ARGSUSED */
+int
+ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
+    struct thread *td __unused)
+{
+
+	return (0);
+}
+
+/* ARGSUSED */
+int
+ioioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
+    int fflag __unused, struct thread *td __unused)
+{
+	struct iodev_pio_req *pio_req;
+	int error;
+
+	error = ENOIOCTL;
+	switch (cmd) {
+	case IODEV_PIO:
+		pio_req = (struct iodev_pio_req *)data;
+		switch (pio_req->access) {
+		case IODEV_PIO_READ:
+			error = iodev_pio_read(pio_req);
+			break;
+		case IODEV_PIO_WRITE:
+			error = iodev_pio_write(pio_req);
+			break;
+		default:
+			error = EINVAL;
+			break;
+		}
+		break;
+	}
+
+	return (error);
+}
+
+static int
+iodev_pio_read(struct iodev_pio_req *req)
+{
+
+	switch (req->width) {
+	case 1:
+		req->val = bus_space_read_io_1(req->port);
+		break;
+	case 2:
+		if (req->port & 1) {
+			req->val = bus_space_read_io_1(req->port);
+			req->val |= bus_space_read_io_1(req->port + 1) << 8;
+		} else
+			req->val = bus_space_read_io_2(req->port);
+		break;
+	case 4:
+		if (req->port & 1) {
+			req->val = bus_space_read_io_1(req->port);
+			req->val |= bus_space_read_io_2(req->port + 1) << 8;
+			req->val |= bus_space_read_io_1(req->port + 3) << 24;
+		} else if (req->port & 2) {
+			req->val = bus_space_read_io_2(req->port);
+			req->val |= bus_space_read_io_2(req->port + 2) << 16;
+		} else
+			req->val = bus_space_read_io_4(req->port);
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+static int
+iodev_pio_write(struct iodev_pio_req *req)
+{
+
+	switch (req->width) {
+	case 1:
+		bus_space_write_io_1(req->port, req->val);
+		break;
+	case 2:
+		if (req->port & 1) {
+			bus_space_write_io_1(req->port, req->val);
+			bus_space_write_io_1(req->port + 1, req->val >> 8);
+		} else
+			bus_space_write_io_2(req->port, req->val);
+		break;
+	case 4:
+		if (req->port & 1) {
+			bus_space_write_io_1(req->port, req->val);
+			bus_space_write_io_2(req->port + 1, req->val >> 8);
+			bus_space_write_io_1(req->port + 3, req->val >> 24);
+		} else if (req->port & 2) {
+			bus_space_write_io_2(req->port, req->val);
+			bus_space_write_io_2(req->port + 2, req->val >> 16);
+		} else
+			bus_space_write_io_4(req->port, req->val);
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}
diff --git a/sys/ia64/ia64/sys_machdep.c b/sys/ia64/ia64/sys_machdep.c
index e39cbab621e..764df2ea027 100644
--- a/sys/ia64/ia64/sys_machdep.c
+++ b/sys/ia64/ia64/sys_machdep.c
@@ -49,72 +49,9 @@ struct sysarch_args {
 int
 sysarch(struct thread *td, struct sysarch_args *uap)
 {
-	struct ia64_iodesc iod;
 	int error;
 
-	error = 0;
 	switch(uap->op) {
-	case IA64_IORD:
-		copyin(uap->parms, &iod, sizeof(iod));
-		switch (iod.width) {
-		case 1:
-			iod.val = inb(iod.port);
-			break;
-		case 2:
-			if (iod.port & 1) {
-				iod.val = inb(iod.port);
-				iod.val |= inb(iod.port + 1) << 8;
-			} else
-				iod.val = inw(iod.port);
-			break;
-		case 4:
-			if (iod.port & 3) {
-				if (iod.port & 1) {
-					iod.val = inb(iod.port);
-					iod.val |= inw(iod.port + 1) << 8;
-					iod.val |= inb(iod.port + 3) << 24;
-				} else {
-					iod.val = inw(iod.port);
-					iod.val |= inw(iod.port + 2) << 16;
-				}
-			} else
-				iod.val = inl(iod.port);
-			break;
-		default:
-			error = EINVAL;
-		}
-		copyout(&iod, uap->parms, sizeof(iod));
-		break;
-	case IA64_IOWR:
-		copyin(uap->parms, &iod, sizeof(iod));
-		switch (iod.width) {
-		case 1:
-			outb(iod.port, iod.val);
-			break;
-		case 2:
-			if (iod.port & 1) {
-				outb(iod.port, iod.val);
-				outb(iod.port + 1, iod.val >> 8);
-			} else
-				outw(iod.port, iod.val);
-			break;
-		case 4:
-			if (iod.port & 3) {
-				if (iod.port & 1) {
-					outb(iod.port, iod.val);
-					outw(iod.port + 1, iod.val >> 8);
-					outb(iod.port + 3, iod.val >> 24);
-				} else {
-					outw(iod.port, iod.val);
-					outw(iod.port + 2, iod.val >> 16);
-				}
-			} else
-				outl(iod.port, iod.val);
-			break;
-		default:
-			error = EINVAL;
-		}
-		break;
 	default:
 		error = EINVAL;
 		break;
diff --git a/sys/ia64/include/iodev.h b/sys/ia64/include/iodev.h
new file mode 100644
index 00000000000..11d05fc1c21
--- /dev/null
+++ b/sys/ia64/include/iodev.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2010 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_IODEV_H_
+#define	_MACHINE_IODEV_H_
+
+struct iodev_pio_req {
+	u_int access;
+#define	IODEV_PIO_READ		0
+#define	IODEV_PIO_WRITE		1
+	u_int port;
+	u_int width;
+	u_int val;
+};
+
+#define	IODEV_PIO	_IOWR('I', 0, struct iodev_pio_req)
+
+#ifdef _KERNEL
+
+d_open_t	ioopen;
+d_close_t	ioclose;
+d_ioctl_t	ioioctl;
+
+#endif
+
+#endif /* _MACHINE_IODEV_H_ */
diff --git a/sys/ia64/include/sysarch.h b/sys/ia64/include/sysarch.h
index a7f39de2ffe..c46d100beea 100644
--- a/sys/ia64/include/sysarch.h
+++ b/sys/ia64/include/sysarch.h
@@ -32,15 +32,6 @@
 #ifndef _MACHINE_SYSARCH_H_
 #define	_MACHINE_SYSARCH_H_
 
-#define	IA64_IORD	0
-#define	IA64_IOWR	1
-
-struct ia64_iodesc {
-	int port;
-	int width;
-	unsigned long val;
-};
-
 #ifndef _KERNEL
 #include 
 

From a354a30d5e4473af9a310029ad9036aee0e3bb12 Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Fri, 22 Jan 2010 03:59:05 +0000
Subject: [PATCH 1257/2592] MFC rev. 202271-202273: o  Add wrappers for the RT
 Variable Services. o  Add ioctl requests to /dev/io on ia64 for reading and
 writing    EFI variables.

---
 sys/ia64/ia64/efi.c           |  72 ++++++++++++++++-
 sys/ia64/ia64/iodev_machdep.c | 140 ++++++++++++++++++++++++++++++++++
 sys/ia64/include/efi.h        |   5 +-
 sys/ia64/include/iodev.h      |  18 +++++
 4 files changed, 232 insertions(+), 3 deletions(-)

diff --git a/sys/ia64/ia64/efi.c b/sys/ia64/ia64/efi.c
index 161572d9971..7e6fdaa9ef8 100644
--- a/sys/ia64/ia64/efi.c
+++ b/sys/ia64/ia64/efi.c
@@ -41,6 +41,45 @@ static struct efi_systbl *efi_systbl;
 static struct efi_cfgtbl *efi_cfgtbl;
 static struct efi_rt *efi_runtime;
 
+static int efi_status2err[25] = {
+	0,		/* EFI_SUCCESS */
+	ENOEXEC,	/* EFI_LOAD_ERROR */
+	EINVAL,		/* EFI_INVALID_PARAMETER */
+	ENOSYS,		/* EFI_UNSUPPORTED */
+	EMSGSIZE, 	/* EFI_BAD_BUFFER_SIZE */
+	EOVERFLOW,	/* EFI_BUFFER_TOO_SMALL */
+	EBUSY,		/* EFI_NOT_READY */
+	EIO,		/* EFI_DEVICE_ERROR */
+	EROFS,		/* EFI_WRITE_PROTECTED */
+	EAGAIN,		/* EFI_OUT_OF_RESOURCES */
+	EIO,		/* EFI_VOLUME_CORRUPTED */
+	ENOSPC,		/* EFI_VOLUME_FULL */
+	ENXIO,		/* EFI_NO_MEDIA */
+	ESTALE,		/* EFI_MEDIA_CHANGED */
+	ENOENT,		/* EFI_NOT_FOUND */
+	EACCES,		/* EFI_ACCESS_DENIED */
+	ETIMEDOUT,	/* EFI_NO_RESPONSE */
+	EADDRNOTAVAIL,	/* EFI_NO_MAPPING */
+	ETIMEDOUT,	/* EFI_TIMEOUT */
+	EDOOFUS,	/* EFI_NOT_STARTED */
+	EALREADY,	/* EFI_ALREADY_STARTED */
+	ECANCELED,	/* EFI_ABORTED */
+	EPROTO,		/* EFI_ICMP_ERROR */
+	EPROTO,		/* EFI_TFTP_ERROR */
+	EPROTO		/* EFI_PROTOCOL_ERROR */
+};
+
+static int
+efi_status_to_errno(efi_status status)
+{
+	u_long code;
+	int error;
+
+	code = status & 0x3ffffffffffffffful;
+	error = (code < 25) ? efi_status2err[code] : EDOOFUS;
+	return (error);
+}
+
 void
 efi_boot_finish(void)
 {
@@ -148,9 +187,38 @@ efi_reset_system(void)
 	panic("%s: unable to reset the machine", __func__);
 }
 
-efi_status
+int
 efi_set_time(struct efi_tm *tm)
 {
 
-	return (efi_runtime->rt_settime(tm));
+	return (efi_status_to_errno(efi_runtime->rt_settime(tm)));
+}
+
+int
+efi_var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib,
+    size_t *datasize, void *data)
+{
+	efi_status status;
+
+	status = efi_runtime->rt_getvar(name, vendor, attrib, datasize, data);
+	return (efi_status_to_errno(status));
+}
+
+int
+efi_var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor)
+{
+	efi_status status;
+
+	status = efi_runtime->rt_scanvar(namesize, name, vendor);
+	return (efi_status_to_errno(status));
+}
+ 
+int
+efi_var_set(efi_char *name, struct uuid *vendor, uint32_t attrib,
+    size_t datasize, void *data)
+{
+	efi_status status;
+ 
+	status = efi_runtime->rt_setvar(name, vendor, attrib, datasize, data);
+	return (efi_status_to_errno(status));
 }
diff --git a/sys/ia64/ia64/iodev_machdep.c b/sys/ia64/ia64/iodev_machdep.c
index 498a042cfce..d255aae127b 100644
--- a/sys/ia64/ia64/iodev_machdep.c
+++ b/sys/ia64/ia64/iodev_machdep.c
@@ -31,16 +31,22 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 
 #include 
+#include 
 #include 
 
 static int iodev_pio_read(struct iodev_pio_req *req);
 static int iodev_pio_write(struct iodev_pio_req *req);
 
+static int iodev_efivar_getvar(struct iodev_efivar_req *req);
+static int iodev_efivar_nextname(struct iodev_efivar_req *req);
+static int iodev_efivar_setvar(struct iodev_efivar_req *req);
+
 /* ARGSUSED */
 int
 ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
@@ -69,6 +75,7 @@ int
 ioioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
     int fflag __unused, struct thread *td __unused)
 {
+	struct iodev_efivar_req *efivar_req;
 	struct iodev_pio_req *pio_req;
 	int error;
 
@@ -88,6 +95,24 @@ ioioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
 			break;
 		}
 		break;
+	case IODEV_EFIVAR:
+		efivar_req = (struct iodev_efivar_req *)data;
+		efivar_req->result = 0;		/* So it's well-defined */
+		switch (efivar_req->access) {
+		case IODEV_EFIVAR_GETVAR:
+			error = iodev_efivar_getvar(efivar_req);
+			break;
+		case IODEV_EFIVAR_NEXTNAME:
+			error = iodev_efivar_nextname(efivar_req);
+			break;
+		case IODEV_EFIVAR_SETVAR:
+			error = iodev_efivar_setvar(efivar_req);
+			break;
+		default:
+			error = EINVAL;
+			break;
+		}
+		break;
 	}
 
 	return (error);
@@ -158,3 +183,118 @@ iodev_pio_write(struct iodev_pio_req *req)
 
 	return (0);
 }
+
+static int
+iodev_efivar_getvar(struct iodev_efivar_req *req)
+{
+	void *data;
+	efi_char *name;
+	int error;
+
+	if ((req->namesize & 1) != 0 || req->namesize < 4)
+		return (EINVAL);
+	if (req->datasize == 0)
+		return (EINVAL);
+
+	/*
+	 * Pre-zero the allocated memory and don't copy the last 2 bytes
+	 * of the name. That should be the closing nul character (ucs-2)
+	 * and if not, then we ensured a nul-terminating string. This is
+	 * to protect the firmware and thus ourselves.
+	 */
+	name = malloc(req->namesize, M_TEMP, M_WAITOK | M_ZERO);
+	error = copyin(req->name, name, req->namesize - 2);
+	if (error) {
+		free(name, M_TEMP);
+		return (error);
+	}
+
+	data = malloc(req->datasize, M_TEMP, M_WAITOK);
+	error = efi_var_get(name, &req->vendor, &req->attrib, &req->datasize,
+	    data);
+	if (error == EOVERFLOW || error == ENOENT) {
+		req->result = error;
+		error = 0;
+	}
+	if (!error && !req->result)
+		error = copyout(data, req->data, req->datasize);
+
+	free(data, M_TEMP);
+	free(name, M_TEMP);
+	return (error);
+}
+
+static int 
+iodev_efivar_nextname(struct iodev_efivar_req *req) 
+{
+	efi_char *name;
+	int error;
+
+	/* Enforce a reasonable minimum size of the name buffer. */
+	if (req->namesize < 4)
+		return (EINVAL);
+
+	name = malloc(req->namesize, M_TEMP, M_WAITOK);
+	error = copyin(req->name, name, req->namesize);
+	if (error) {
+		free(name, M_TEMP);
+		return (error);
+	}
+
+	error = efi_var_nextname(&req->namesize, name, &req->vendor);
+	if (error == EOVERFLOW || error == ENOENT) {
+		req->result = error;
+		error = 0;
+	}
+	if (!error && !req->result)
+		error = copyout(name, req->name, req->namesize);
+
+	free(name, M_TEMP);
+	return (error);
+}
+
+static int 
+iodev_efivar_setvar(struct iodev_efivar_req *req) 
+{
+	void *data;
+	efi_char *name;
+	int error;
+
+	if ((req->namesize & 1) != 0 || req->namesize < 4)
+		return (EINVAL);
+
+	/*
+	 * Pre-zero the allocated memory and don't copy the last 2 bytes
+	 * of the name. That should be the closing nul character (ucs-2)
+	 * and if not, then we ensured a nul-terminating string. This is
+	 * to protect the firmware and thus ourselves.
+	 */
+	name = malloc(req->namesize, M_TEMP, M_WAITOK | M_ZERO);
+	error = copyin(req->name, name, req->namesize - 2);
+	if (error) {
+		free(name, M_TEMP);
+		return (error);
+	}
+
+	if (req->datasize) {
+		data = malloc(req->datasize, M_TEMP, M_WAITOK);
+		error = copyin(req->data, data, req->datasize);
+		if (error) {
+			free(data, M_TEMP);
+			free(name, M_TEMP);
+			return (error);
+		}
+	} else
+		data = NULL;
+
+	error = efi_var_set(name, &req->vendor, req->attrib, req->datasize,
+	    data);
+	if (error == EAGAIN || error == ENOENT) {
+		req->result = error;
+		error = 0;
+	}
+
+	free(data, M_TEMP);
+	free(name, M_TEMP);
+	return (error);
+}
diff --git a/sys/ia64/include/efi.h b/sys/ia64/include/efi.h
index fe0052367f3..53ff11750c4 100644
--- a/sys/ia64/include/efi.h
+++ b/sys/ia64/include/efi.h
@@ -158,6 +158,9 @@ void efi_get_time(struct efi_tm *);
 struct efi_md *efi_md_first(void);
 struct efi_md *efi_md_next(struct efi_md *);
 void efi_reset_system(void);
-efi_status efi_set_time(struct efi_tm *);
+int efi_set_time(struct efi_tm *);
+int efi_var_get(efi_char *, struct uuid *, uint32_t *, size_t *, void *);
+int efi_var_nextname(size_t *, efi_char *, struct uuid *);
+int efi_var_set(efi_char *, struct uuid *, uint32_t, size_t, void *);
 
 #endif /* _MACHINE_EFI_H_ */
diff --git a/sys/ia64/include/iodev.h b/sys/ia64/include/iodev.h
index 11d05fc1c21..6d2ae19d36d 100644
--- a/sys/ia64/include/iodev.h
+++ b/sys/ia64/include/iodev.h
@@ -29,6 +29,8 @@
 #ifndef _MACHINE_IODEV_H_
 #define	_MACHINE_IODEV_H_
 
+#include 
+
 struct iodev_pio_req {
 	u_int access;
 #define	IODEV_PIO_READ		0
@@ -40,6 +42,22 @@ struct iodev_pio_req {
 
 #define	IODEV_PIO	_IOWR('I', 0, struct iodev_pio_req)
 
+struct iodev_efivar_req {
+	u_int	access;
+#define	IODEV_EFIVAR_GETVAR	0
+#define	IODEV_EFIVAR_NEXTNAME	1
+#define	IODEV_EFIVAR_SETVAR	2
+	u_int	result;			/* errno value */
+	size_t	namesize;
+	u_short	*name;			/* UCS-2 */
+	struct uuid vendor;
+	uint32_t attrib;
+	size_t	datasize;
+	void	*data;
+};
+
+#define	IODEV_EFIVAR	_IOWR('I', 1, struct iodev_efivar_req)
+
 #ifdef _KERNEL
 
 d_open_t	ioopen;

From cd58d51b0fceffa8524dbb3cd3ea646d9483efb7 Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Fri, 22 Jan 2010 09:27:31 +0000
Subject: [PATCH 1258/2592] MFC r202585: fix a comment typo

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

diff --git a/lib/libstand/bzipfs.c b/lib/libstand/bzipfs.c
index 46a151bc1cd..1b2e9ebff13 100644
--- a/lib/libstand/bzipfs.c
+++ b/lib/libstand/bzipfs.c
@@ -279,7 +279,7 @@ bzf_rewind(struct open_file *f)
     /*
      * Since bzip2 does not have an equivalent inflateReset function a crude
      * one needs to be provided.  The functions all called in such a way that
-     * at any time an error occurs a role back can be done (effectively making
+     * at any time an error occurs a roll back can be done (effectively making
      * this rewind 'atomic', either the reset occurs successfully or not at all,
      * with no 'undefined' state happening).
      */

From 773425fadeea59617a97a21d22160b49d21de82e Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Fri, 22 Jan 2010 09:34:57 +0000
Subject: [PATCH 1259/2592] MFC r202558: acpi_ec: clean up 'private' ivar when
 freeing memory

---
 sys/dev/acpica/acpi_ec.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/acpica/acpi_ec.c b/sys/dev/acpica/acpi_ec.c
index b339ba10ed0..c101292b7e4 100644
--- a/sys/dev/acpica/acpi_ec.c
+++ b/sys/dev/acpica/acpi_ec.c
@@ -469,6 +469,7 @@ acpi_ec_attach(device_t dev)
     sc->ec_gpehandle = params->gpe_handle;
     sc->ec_uid = params->uid;
     sc->ec_suspending = FALSE;
+    acpi_set_private(dev, NULL);
     free(params, M_TEMP);
 
     /* Attach bus resources for data and command/status ports. */

From 83279a93f54e3f49647d175b8c2463a29fc2a0b9 Mon Sep 17 00:00:00 2001
From: Andriy Gapon 
Date: Fri, 22 Jan 2010 09:41:09 +0000
Subject: [PATCH 1260/2592] MFC r202567: acpi_ec: remove redundant
 acpi_disabled check

---
 sys/dev/acpica/acpi_ec.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sys/dev/acpica/acpi_ec.c b/sys/dev/acpica/acpi_ec.c
index c101292b7e4..9348a2ad470 100644
--- a/sys/dev/acpica/acpi_ec.c
+++ b/sys/dev/acpica/acpi_ec.c
@@ -366,8 +366,7 @@ acpi_ec_probe(device_t dev)
     if (params != NULL) {
 	ecdt = 1;
 	ret = 0;
-    } else if (!acpi_disabled("ec") &&
-	ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids)) {
+    } else if (ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids)) {
 	params = malloc(sizeof(struct acpi_ec_params), M_TEMP,
 			M_WAITOK | M_ZERO);
 	h = acpi_get_handle(dev);

From d871d872fadda3aaa6ec6a6f8c25a0d585d3f35b Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 22 Jan 2010 11:16:46 +0000
Subject: [PATCH 1261/2592] MFC r197420: Lock bus scan.

---
 sys/dev/ppbus/vpo.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/sys/dev/ppbus/vpo.c b/sys/dev/ppbus/vpo.c
index 40091787a4f..673a7858d4d 100644
--- a/sys/dev/ppbus/vpo.c
+++ b/sys/dev/ppbus/vpo.c
@@ -176,9 +176,6 @@ vpo_attach(device_t dev)
 		return (ENXIO);
 	}
 	ppb_unlock(ppbus);
-
-	/* all went ok */
-
 	vpo_cam_rescan(vpo);	/* have CAM rescan the bus */
 
 	return (0);
@@ -194,12 +191,15 @@ vpo_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
 static void
 vpo_cam_rescan(struct vpo_data *vpo)
 {
+	device_t ppbus = device_get_parent(vpo->vpo_dev);
 	struct cam_path *path;
 	union ccb *ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO);
 
+	ppb_lock(ppbus);
 	if (xpt_create_path(&path, xpt_periph, cam_sim_path(vpo->sim), 0, 0)
 	    != CAM_REQ_CMP) {
 		/* A failure is benign as the user can do a manual rescan */
+		ppb_unlock(ppbus);
 		free(ccb, M_TEMP);
 		return;
 	}
@@ -209,6 +209,7 @@ vpo_cam_rescan(struct vpo_data *vpo)
 	ccb->ccb_h.cbfcnp = vpo_cam_rescan_callback;
 	ccb->crcn.flags = CAM_FLAG_NONE;
 	xpt_action(ccb);
+	ppb_unlock(ppbus);
 
 	/* The scan is in progress now. */
 }

From c6ce4527912edba080e0344cde0764e61556e7f6 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 22 Jan 2010 11:30:32 +0000
Subject: [PATCH 1262/2592] MFC r202166: Make default recording source choosing
 more intelligent. Change default recording level from 0 to 75. It should
 increase chances for things to work just out of the box.

---
 sys/dev/sound/pcm/mixer.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
index 2b8d6ce771c..fdef0d5b372 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -87,7 +87,7 @@ static u_int16_t snd_mixerdefaults[SOUND_MIXER_NRDEVICES] = {
 	[SOUND_MIXER_IGAIN]	= 0,
 	[SOUND_MIXER_LINE1]	= 75,
 	[SOUND_MIXER_VIDEO]	= 75,
-	[SOUND_MIXER_RECLEV]	= 0,
+	[SOUND_MIXER_RECLEV]	= 75,
 	[SOUND_MIXER_OGAIN]	= 50,
 	[SOUND_MIXER_MONITOR]	= 75,
 };
@@ -352,7 +352,13 @@ mixer_setrecsrc(struct snd_mixer *mixer, u_int32_t src)
 		dropmtx = 0;
 	src &= mixer->recdevs;
 	if (src == 0)
-		src = SOUND_MASK_MIC;
+		src = mixer->recdevs & SOUND_MASK_MIC;
+	if (src == 0)
+		src = mixer->recdevs & SOUND_MASK_MONITOR;
+	if (src == 0)
+		src = mixer->recdevs & SOUND_MASK_LINE;
+	if (src == 0 && mixer->recdevs != 0)
+		src = (1 << (ffs(mixer->recdevs) - 1));
 	/* It is safe to drop this mutex due to Giant. */
 	MIXER_SET_UNLOCK(mixer, dropmtx);
 	recsrc = MIXER_SETRECSRC(mixer, src);
@@ -716,7 +722,7 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
 		mixer_set(m, i, v | (v << 8));
 	}
 
-	mixer_setrecsrc(m, SOUND_MASK_MIC);
+	mixer_setrecsrc(m, 0); /* Set default input. */
 
 	unit = device_get_unit(dev);
 	devunit = snd_mkunit(unit, SND_DEV_CTL, 0);

From 858bc163b7952290b85a9bff58024288b371b339 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 22 Jan 2010 11:31:49 +0000
Subject: [PATCH 1263/2592] MFC r202267: Hide from default sndstat some
 information not used on daily basis, to make it readable by average user with
 average screen size.

---
 sys/dev/sound/pcm/sndstat.c |  8 +++-----
 sys/dev/sound/pcm/sndstat.h | 19 +++++++++++++------
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c
index 6d35803de87..4daca5f6aac 100644
--- a/sys/dev/sound/pcm/sndstat.c
+++ b/sys/dev/sound/pcm/sndstat.c
@@ -81,7 +81,7 @@ static int sndstat_files = 0;
 
 static SLIST_HEAD(, sndstat_entry) sndstat_devlist = SLIST_HEAD_INITIALIZER(none);
 
-int snd_verbose = 1;
+int snd_verbose = 0;
 TUNABLE_INT("hw.snd.verbose", &snd_verbose);
 
 #ifdef SND_DEBUG
@@ -372,12 +372,10 @@ sndstat_prepare(struct sbuf *s)
 			PCM_ACQUIRE_QUICK(d);
 			sbuf_printf(s, "%s:", device_get_nameunit(ent->dev));
 			sbuf_printf(s, " <%s>", device_get_desc(ent->dev));
-			sbuf_printf(s, " %s [%s]", ent->str,
-			    (d->flags & SD_F_MPSAFE) ? "MPSAFE" : "GIANT");
+			if (snd_verbose > 0)
+				sbuf_printf(s, " %s", ent->str);
 			if (ent->handler)
 				ent->handler(s, ent->dev, snd_verbose);
-			else
-				sbuf_printf(s, " [no handler]");
 			sbuf_printf(s, "\n");
 			PCM_RELEASE_QUICK(d);
 		}
diff --git a/sys/dev/sound/pcm/sndstat.h b/sys/dev/sound/pcm/sndstat.h
index 0c3a9bffcb2..0bdb96ac01f 100644
--- a/sys/dev/sound/pcm/sndstat.h
+++ b/sys/dev/sound/pcm/sndstat.h
@@ -37,9 +37,6 @@
 	struct pcm_channel *c;						\
 	struct pcm_feeder *f;						\
 									\
-	if (verbose < 1)						\
-		return (0);						\
-									\
 	d = device_get_softc(dev);					\
 	PCM_BUSYASSERT(d);						\
 									\
@@ -48,9 +45,19 @@
 		return (0);						\
 	}								\
 									\
-	sbuf_printf(s, " (%dp:%dv/%dr:%dv channels %splex%s)",		\
-	    d->playcount, d->pvchancount, d->reccount, d->rvchancount,	\
-	    (d->flags & SD_F_SIMPLEX) ? "sim" : "du",			\
+	if (verbose < 1) {						\
+		sbuf_printf(s, " (%s%s%s",				\
+		    d->playcount ? "play" : "",				\
+		    (d->playcount && d->reccount) ? "/" : "",		\
+		    d->reccount ? "rec" : "");				\
+	} else {							\
+		sbuf_printf(s, " (%dp:%dv/%dr:%dv",			\
+		    d->playcount, d->pvchancount,			\
+		    d->reccount, d->rvchancount);			\
+	}								\
+	sbuf_printf(s, "%s)%s",						\
+	    ((d->playcount != 0 && d->reccount != 0) &&			\
+	    (d->flags & SD_F_SIMPLEX)) ? " simplex" : "",		\
 	    (device_get_unit(dev) == snd_unit) ? " default" : "")
 
 

From 320cdf733e55e96dcb7566b11a639ed2dbe23cb6 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 22 Jan 2010 11:37:19 +0000
Subject: [PATCH 1264/2592] MFC r202127, r202156: Add multichannel (4.0, 5.1
 and 7.1) playback support.

Stereo stream is no more duplicated to all ports. If you loose sound, check
you are using right connectors. Front speakers connector is usually green,
center/LFE - orange, rear - black, side - gray.
---
 sys/dev/sound/pci/hda/hdac.c         | 148 +++++++++++++++++++--------
 sys/dev/sound/pci/hda/hdac_private.h |   3 +-
 2 files changed, 107 insertions(+), 44 deletions(-)

diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 7a9dd82a2c7..ce3372889fc 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -86,7 +86,7 @@
 
 #include "mixer_if.h"
 
-#define HDA_DRV_TEST_REV	"20091113_0138"
+#define HDA_DRV_TEST_REV	"20100112_0140"
 
 SND_DECLARE_FILE("$FreeBSD$");
 
@@ -3455,7 +3455,11 @@ hdac_stream_setup(struct hdac_chan *ch)
 	int i, chn, totalchn, c;
 	nid_t cad = ch->devinfo->codec->cad;
 	uint16_t fmt, dfmt;
+	uint16_t chmap[2][5] = {{ 0x0010, 0x0001, 0x0201, 0x0231, 0x0231 }, /* 5.1 */
+				{ 0x0010, 0x0001, 0x2001, 0x2031, 0x2431 }};/* 7.1 */
+	int map = -1;
 
+	totalchn = AFMT_CHANNEL(ch->fmt);
 	HDA_BOOTHVERBOSE(
 		device_printf(ch->pdevinfo->dev,
 		    "PCMDIR_%s: Stream setup fmt=%08x speed=%d\n",
@@ -3469,7 +3473,6 @@ hdac_stream_setup(struct hdac_chan *ch)
 		fmt |= ch->bit32 << 4;
 	else
 		fmt |= 1 << 4;
-
 	for (i = 0; i < HDA_RATE_TAB_LEN; i++) {
 		if (hda_rate_tab[i].valid && ch->spd == hda_rate_tab[i].rate) {
 			fmt |= hda_rate_tab[i].base;
@@ -3478,10 +3481,13 @@ hdac_stream_setup(struct hdac_chan *ch)
 			break;
 		}
 	}
+	fmt |= (totalchn - 1);
 
-	totalchn = AFMT_CHANNEL(ch->fmt);
-	if (totalchn > 1)
-		fmt |= 1;
+	/* Set channel mapping for known speaker setups. */
+	if (as->pinset == 0x0007 || as->pinset == 0x0013) /* Standard 5.1 */
+		map = 0;
+	else if (as->pinset == 0x0017) /* Standard 7.1 */
+		map = 1;
 
 	HDAC_WRITE_2(&sc->mem, ch->off + HDAC_SDFMT, fmt);
 		
@@ -3495,14 +3501,26 @@ hdac_stream_setup(struct hdac_chan *ch)
 		if (w == NULL)
 			continue;
 
-		if (as->hpredir >= 0 && i == as->pincnt)
-			chn = 0;
+		/* If HP redirection is enabled, but failed to use same
+		   DAC, make last DAC to duplicate first one. */
+		if (as->hpredir >= 0 && i == as->pincnt) {
+			c = (ch->sid << 4);
+		} else {
+			if (map >= 0) /* Map known speaker setups. */
+				chn = (((chmap[map][totalchn / 2] >> i * 4) &
+				    0xf) - 1) * 2;
+			if (chn < 0 || chn >= totalchn) {
+				c = 0;
+			} else {
+				c = (ch->sid << 4) | chn;
+			}
+		}
 		HDA_BOOTHVERBOSE(
 			device_printf(ch->pdevinfo->dev,
 			    "PCMDIR_%s: Stream setup nid=%d: "
-			    "fmt=0x%04x, dfmt=0x%04x\n",
+			    "fmt=0x%04x, dfmt=0x%04x, chan=0x%04x\n",
 			    (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC",
-			    ch->io[i], fmt, dfmt);
+			    ch->io[i], fmt, dfmt, c);
 		);
 		hdac_command(sc,
 		    HDA_CMD_SET_CONV_FMT(cad, ch->io[i], fmt), cad);
@@ -3511,17 +3529,6 @@ hdac_stream_setup(struct hdac_chan *ch)
 			    HDA_CMD_SET_DIGITAL_CONV_FMT1(cad, ch->io[i], dfmt),
 			    cad);
 		}
-		/* If HP redirection is enabled, but failed to use same
-		   DAC make last DAC one to duplicate first one. */
-		if (as->hpredir >= 0 && i == as->pincnt) {
-			c = (ch->sid << 4);
-		} else if (chn >= totalchn) {
-			/* This is until OSS will support multichannel.
-			   Should be: c = 0; to disable unused DAC */
-			c = (ch->sid << 4);
-		}else {
-			c = (ch->sid << 4) | chn;
-		}
 		hdac_command(sc,
 		    HDA_CMD_SET_CONV_STREAM_CHAN(cad, ch->io[i], c), cad);
 #if 0
@@ -3532,12 +3539,36 @@ hdac_stream_setup(struct hdac_chan *ch)
 		hdac_command(sc,
 		    HDA_CMD_SET_HDMI_CHAN_SLOT(cad, ch->io[i], 0x11), cad);
 #endif
-		chn +=
-		    HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap) ?
-		    2 : 1;
+		chn += HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) + 1;
 	}
 }
 
+/*
+ * Greatest Common Divisor.
+ */
+static unsigned
+gcd(unsigned a, unsigned b)
+{
+	u_int c;
+
+	while (b != 0) {
+		c = a;
+		a = b;
+		b = (c % b);
+	}
+	return (a);
+}
+
+/*
+ * Least Common Multiple.
+ */
+static unsigned
+lcm(unsigned a, unsigned b)
+{
+
+	return ((a * b) / gcd(a, b));
+}
+
 static int
 hdac_channel_setfragments(kobj_t obj, void *data,
 					uint32_t blksz, uint32_t blkcnt)
@@ -3545,7 +3576,7 @@ hdac_channel_setfragments(kobj_t obj, void *data,
 	struct hdac_chan *ch = data;
 	struct hdac_softc *sc = ch->devinfo->codec->sc;
 
-	blksz &= HDA_BLK_ALIGN;
+	blksz -= blksz % lcm(HDAC_DMA_ALIGNMENT, sndbuf_getalign(ch->b));
 
 	if (blksz > (sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN))
 		blksz = sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN;
@@ -6436,7 +6467,8 @@ hdac_pcmchannel_setup(struct hdac_chan *ch)
 	struct hdac_audio_as *as = devinfo->function.audio.as;
 	struct hdac_widget *w;
 	uint32_t cap, fmtcap, pcmcap;
-	int i, j, ret, max;
+	int i, j, ret, channels, onlystereo;
+	uint16_t pinset;
 
 	ch->caps = hdac_caps;
 	ch->caps.fmtlist = ch->fmtlist;
@@ -6446,11 +6478,13 @@ hdac_pcmchannel_setup(struct hdac_chan *ch)
 	ch->pcmrates[1] = 0;
 
 	ret = 0;
+	channels = 0;
+	onlystereo = 1;
+	pinset = 0;
 	fmtcap = devinfo->function.audio.supp_stream_formats;
 	pcmcap = devinfo->function.audio.supp_pcm_size_rate;
-	max = (sizeof(ch->io) / sizeof(ch->io[0])) - 1;
 
-	for (i = 0; i < 16 && ret < max; i++) {
+	for (i = 0; i < 16; i++) {
 		/* Check as is correct */
 		if (ch->as < 0)
 			break;
@@ -6468,15 +6502,11 @@ hdac_pcmchannel_setup(struct hdac_chan *ch)
 		w = hdac_widget_get(devinfo, as[ch->as].dacs[i]);
 		if (w == NULL || w->enable == 0)
 			continue;
-		if (!HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap))
-			continue;
 		cap = w->param.supp_stream_formats;
-		/*if (HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32(cap)) {
-		}*/
 		if (!HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap) &&
 		    !HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap))
 			continue;
-		/* Many codec does not declare AC3 support on SPDIF.
+		/* Many CODECs does not declare AC3 support on SPDIF.
 		   I don't beleave that they doesn't support it! */
 		if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
 			cap |= HDA_PARAM_SUPP_STREAM_FORMATS_AC3_MASK;
@@ -6488,9 +6518,24 @@ hdac_pcmchannel_setup(struct hdac_chan *ch)
 			pcmcap &= w->param.supp_pcm_size_rate;
 		}
 		ch->io[ret++] = as[ch->as].dacs[i];
+		/* Do not count redirection pin/dac channels. */
+		if (i == 15 && as[ch->as].hpredir >= 0)
+			continue;
+		channels += HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) + 1;
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) != 1)
+			onlystereo = 0;
+		pinset |= (1 << i);
 	}
 	ch->io[ret] = -1;
 
+	if (as[ch->as].fakeredir)
+		ret--;
+	/* Standard speaks only about stereo pins and playback, ... */
+	if ((!onlystereo) || as[ch->as].dir != HDA_CTL_OUT)
+		pinset = 0;
+	/* ..., but there it gives us info about speakers layout. */
+	as[ch->as].pinset = pinset;
+
 	ch->supp_stream_formats = fmtcap;
 	ch->supp_pcm_size_rate = pcmcap;
 
@@ -6514,17 +6559,34 @@ hdac_pcmchannel_setup(struct hdac_chan *ch)
 				ch->bit32 = 3;
 			else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(pcmcap))
 				ch->bit32 = 2;
-			if (!(devinfo->function.audio.quirks & HDA_QUIRK_FORCESTEREO))
-				ch->fmtlist[i++] =
-				    SND_FORMAT(AFMT_S16_LE, 1, 0);
-			ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 2, 0);
-			if (ch->bit32 > 0) {
-				if (!(devinfo->function.audio.quirks &
-				    HDA_QUIRK_FORCESTEREO))
-					ch->fmtlist[i++] =
-					    SND_FORMAT(AFMT_S32_LE, 1, 0);
-				ch->fmtlist[i++] =
-				    SND_FORMAT(AFMT_S32_LE, 2, 0);
+			if (!(devinfo->function.audio.quirks & HDA_QUIRK_FORCESTEREO)) {
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 1, 0);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 1, 0);
+			}
+			if (channels >= 2) {
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 2, 0);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 2, 0);
+			}
+			if (channels == 4 || /* Any 4-channel */
+			    pinset == 0x0007 || /* 5.1 */
+			    pinset == 0x0013 || /* 5.1 */
+			    pinset == 0x0017) {  /* 7.1 */
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 4, 0);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 4, 0);
+			}
+			if (channels == 6 || /* Any 6-channel */
+			    pinset == 0x0017) {  /* 7.1 */
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 6, 1);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 6, 1);
+			}
+			if (channels == 8) { /* Any 8-channel */
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 8, 1);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 8, 1);
 			}
 		}
 		if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(fmtcap)) {
diff --git a/sys/dev/sound/pci/hda/hdac_private.h b/sys/dev/sound/pci/hda/hdac_private.h
index 2369a9a8d1d..24beed74643 100644
--- a/sys/dev/sound/pci/hda/hdac_private.h
+++ b/sys/dev/sound/pci/hda/hdac_private.h
@@ -221,6 +221,7 @@ struct hdac_audio_as {
 	u_char pincnt;
 	u_char fakeredir;
 	u_char digital;
+	uint16_t pinset;
 	nid_t hpredir;
 	nid_t pins[16];
 	nid_t dacs[16];
@@ -281,7 +282,7 @@ struct hdac_chan {
 	struct hdac_devinfo *devinfo;
 	struct hdac_pcm_devinfo *pdevinfo;
 	struct hdac_dma	bdl_dma;
-	uint32_t spd, fmt, fmtlist[8], pcmrates[16];
+	uint32_t spd, fmt, fmtlist[16], pcmrates[16];
 	uint32_t supp_stream_formats, supp_pcm_size_rate;
 	uint32_t ptr, prevptr, blkcnt, blksz;
 	uint32_t *dmapos;

From 3af7dcdafa8fa7c10a7a08cb851c97e8772f3f45 Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 22 Jan 2010 11:40:55 +0000
Subject: [PATCH 1265/2592] MFC r202160: Update, reflecting added multichannel
 playback support.

---
 share/man/man4/snd_hda.4 | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/share/man/man4/snd_hda.4 b/share/man/man4/snd_hda.4
index 4734f45f5c0..c3b379495e2 100644
--- a/share/man/man4/snd_hda.4
+++ b/share/man/man4/snd_hda.4
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 13, 2009
+.Dd January 12, 2010
 .Dt SND_HDA 4
 .Os
 .Sh NAME
@@ -125,12 +125,14 @@ such as
 .Dq Li nofixedrate ,
 will do the opposite and takes precedence.
 Options can be separated by whitespace and commas.
+.Pp
 .Dq Li GPIO Ns s
 are a codec's General Purpose I/O pins which system integrators sometimes
 use to control external muters, amplifiers and so on.
 If you have no sound, or sound volume is not adequate, you may have to
 experiment a bit with the GPIO setup to find the optimal setup for your
 system.
+.Pp
 The
 .Dq Li ivref Ns Ar X
 and
@@ -178,6 +180,11 @@ A unique, per-association number used to order pins inside the
 particular association.
 Sequence numbers can be specified as numeric values from 0 to 15.
 .Pp
+For output assotiations sequence numbers encode speaker pairs positions:
+0 - Front, 1 - Center/LFE, 2 - Back, 3 - Front Wide Center, 4 - Side.
+Standard combinations are: (0) - Stereo; (0, 2), (0, 4) - Quadro;
+(0, 1, 2), (0, 1, 4) - 5.1; (0, 1, 2, 4) - 7.1.
+.Pp
 The sequence number 15 has a special meaning for output associations.
 Output pins with this number and device type
 .Dq Ar Headphones
@@ -639,6 +646,3 @@ to control external amplifiers. In some cases setting proper combination of
 GPIO bits may be needed to make sound work on specific device.
 .Pp
 HDMI and DisplayPort audio may also require support from video driver.
-.Pp
-Due to OSS limitation multichannel (not multidevice) playback is not
-supported.

From e6b95cac7da04e4b9c1a0dcf0bc1366068cc508a Mon Sep 17 00:00:00 2001
From: Alexander Motin 
Date: Fri, 22 Jan 2010 11:42:23 +0000
Subject: [PATCH 1266/2592] MFC r202798: Add "MIXER CONTROLS" chapter.

---
 share/man/man4/snd_hda.4 | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/share/man/man4/snd_hda.4 b/share/man/man4/snd_hda.4
index c3b379495e2..cdb1503c1cd 100644
--- a/share/man/man4/snd_hda.4
+++ b/share/man/man4/snd_hda.4
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 12, 2010
+.Dd January 22, 2010
 .Dt SND_HDA 4
 .Os
 .Sh NAME
@@ -459,6 +459,42 @@ mic and line-in) and headset (headphones and mic) at front connectors.
 .Li pcm1
 for internal speaker playback.
 On headphones connection rear connectors will be muted.
+.Sh MIXER CONTROLS
+Depending on codec configuration, these controls and signal sources could be
+reported to
+.Xr sound 4 :
+.Pp
+.Bl -tag -width ".Va speaker" -offset indent
+.It Va vol
+overall output level (volume)
+.It Va rec
+overall recording level
+.It Va igain
+input-to-output monitoring loopback level
+.It Va ogain
+external amplifier control
+.It Va pcm
+PCM playback
+.It Va mix
+input mix
+.It Va mic
+first external or second internal microphone input
+.It Va monitor
+first internal or second external microphone input
+.It Va line , Va line1 , Va line2, Va line3
+analog (line) inputs
+.It Va dig1 , Va dig2 , Va dig3
+digital (S/PDIF, HDMI or DisplayPort) inputs
+.It Va cd
+CD input
+.It Va speaker
+PC speaker input
+.It Va phin , Va phout , Va radio . Va video
+other random inputs
+.El
+.Pp
+Controls have different precision. Some could be just an on/off triggers.
+Most of controls use logarithmic scale.
 .Sh HARDWARE
 The
 .Nm

From 7468bbeaead0aa8f1ee70e17213d45083c075876 Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Fri, 22 Jan 2010 17:03:49 +0000
Subject: [PATCH 1267/2592] MFC: r201848

Free allocated sbufs before returning ENOMEM.
---
 sys/kern/kern_cpu.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/sys/kern/kern_cpu.c b/sys/kern/kern_cpu.c
index 9f7f6156704..4c4f961931f 100644
--- a/sys/kern/kern_cpu.c
+++ b/sys/kern/kern_cpu.c
@@ -935,8 +935,10 @@ cpufreq_levels_sysctl(SYSCTL_HANDLER_ARGS)
 	/* Get settings from the device and generate the output string. */
 	count = CF_MAX_LEVELS;
 	levels = malloc(count * sizeof(*levels), M_TEMP, M_NOWAIT);
-	if (levels == NULL)
+	if (levels == NULL) {
+		sbuf_delete(&sb);
 		return (ENOMEM);
+	}
 	error = CPUFREQ_LEVELS(sc->dev, levels, &count);
 	if (error) {
 		if (error == E2BIG)
@@ -974,8 +976,10 @@ cpufreq_settings_sysctl(SYSCTL_HANDLER_ARGS)
 	/* Get settings from the device and generate the output string. */
 	set_count = MAX_SETTINGS;
 	sets = malloc(set_count * sizeof(*sets), M_TEMP, M_NOWAIT);
-	if (sets == NULL)
+	if (sets == NULL) {
+		sbuf_delete(&sb);
 		return (ENOMEM);
+	}
 	error = CPUFREQ_DRV_SETTINGS(dev, sets, &set_count);
 	if (error)
 		goto out;

From 8374d905b633594ee1d7ff56c7abd546f694df52 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Fri, 22 Jan 2010 17:30:36 +0000
Subject: [PATCH 1268/2592] MFC r202582: Update named.conf for documentation IP
 addresses and domains

---
 etc/namedb/named.conf | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/etc/namedb/named.conf b/etc/namedb/named.conf
index 2fb72d8fce1..57b7bf5252f 100644
--- a/etc/namedb/named.conf
+++ b/etc/namedb/named.conf
@@ -125,7 +125,7 @@ zone "in-addr.arpa" {
 	1. Faster local resolution for your users
 	2. No spurious traffic will be sent from your network to the roots
 */
-// RFC 1912
+// RFC 1912 (and BCP 32 for localhost)
 zone "localhost"	{ type master; file "/etc/namedb/master/localhost-forward.db"; };
 zone "127.in-addr.arpa"	{ type master; file "/etc/namedb/master/localhost-reverse.db"; };
 zone "255.in-addr.arpa"	{ type master; file "/etc/namedb/master/empty.db"; };
@@ -159,8 +159,21 @@ zone "168.192.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; }
 // Link-local/APIPA (RFCs 3330 and 3927)
 zone "254.169.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; };
 
-// TEST-NET for Documentation (RFC 3330)
+// TEST-NET-[1-3] for Documentation (RFC 5737)
 zone "2.0.192.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; };
+zone "100.51.198.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; };
+zone "113.0.203.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; };
+
+// IPv6 Range for Documentation (RFC 3849)
+zone "0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa" { type master; file "/etc/namedb/master/empty.db"; };
+
+// Domain Names for Documentation and Testing (BCP 32)
+zone "test" { type master; file "/etc/namedb/master/empty.db"; };
+zone "example" { type master; file "/etc/namedb/master/empty.db"; };
+zone "invalid" { type master; file "/etc/namedb/master/empty.db"; };
+zone "example.com" { type master; file "/etc/namedb/master/empty.db"; };
+zone "example.net" { type master; file "/etc/namedb/master/empty.db"; };
+zone "example.org" { type master; file "/etc/namedb/master/empty.db"; };
 
 // Router Benchmark Testing (RFC 3330)
 zone "18.198.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; };

From 52c240aaf4a3f966f7fdd584acb6386b6ec566fd Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Fri, 22 Jan 2010 19:51:34 +0000
Subject: [PATCH 1269/2592] MFC r201350:

  The devices that supported EVFILT_NETDEV kqueue filters were removed in
  r195175.  Remove all definitions, documentation, and usage.

The change of function signature for vlan_link_state() was not merged to
maintain the ABI.
---
 lib/libc/sys/kqueue.2                       |  20 ----
 sys/kern/kern_event.c                       |   2 +-
 sys/net/if.c                                |   9 +-
 sys/sys/event.h                             |   9 +-
 tools/regression/fifo/fifo_misc/fifo_misc.c | 109 --------------------
 usr.bin/truss/syscalls.c                    |   2 +-
 6 files changed, 4 insertions(+), 147 deletions(-)

diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2
index e899a1befe8..326632d440a 100644
--- a/lib/libc/sys/kqueue.2
+++ b/lib/libc/sys/kqueue.2
@@ -438,19 +438,6 @@ There is a system wide limit on the number of timers
 which is controlled by the
 .Va kern.kq_calloutmax
 sysctl.
-.It Dv EVFILT_NETDEV
-Takes a descriptor to a network interface as the identifier, and the events to watch for in
-.Va fflags .
-It returns, when one or more of the requested events occur on the descriptor.
-The events to monitor are:
-.Bl -tag -width XXNOTE_LINKDOWN
-.It Dv NOTE_LINKUP
-The link is up.
-.It Dv NOTE_LINKDOWN
-The link is down.
-.It Dv NOTE_LINKINV
-The link state is invalid.
-.El
 .Pp
 On return,
 .Va fflags
@@ -595,13 +582,6 @@ system and this manual page were written by
 .An Jonathan Lemon Aq jlemon@FreeBSD.org .
 .Sh BUGS
 The
-.Dv EVFILT_NETDEV
-filter is currently only implemented for devices that use the
-.Xr miibus 4
-driver for LINKUP and LINKDOWN operations.
-Therefore, it will not work with many non-ethernet devices.
-.Pp
-The
 .Fa timeout
 value is limited to 24 hours; longer timeouts will be silently
 reinterpreted as 24 hours.
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 47a17fb8976..ad0acd83410 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -264,7 +264,7 @@ static struct {
 	{ &proc_filtops },			/* EVFILT_PROC */
 	{ &sig_filtops },			/* EVFILT_SIGNAL */
 	{ &timer_filtops },			/* EVFILT_TIMER */
-	{ &file_filtops },			/* EVFILT_NETDEV */
+	{ &null_filtops },			/* former EVFILT_NETDEV */
 	{ &fs_filtops },			/* EVFILT_FS */
 	{ &null_filtops },			/* EVFILT_LIO */
 	{ &user_filtops },			/* EVFILT_USER */
diff --git a/sys/net/if.c b/sys/net/if.c
index 7ffa2687c8c..fe0a304f927 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1878,19 +1878,12 @@ do_link_state_change(void *arg, int pending)
 {
 	struct ifnet *ifp = (struct ifnet *)arg;
 	int link_state = ifp->if_link_state;
-	int link;
 	CURVNET_SET(ifp->if_vnet);
 
 	/* Notify that the link state has changed. */
 	rt_ifmsg(ifp);
-	if (link_state == LINK_STATE_UP)
-		link = NOTE_LINKUP;
-	else if (link_state == LINK_STATE_DOWN)
-		link = NOTE_LINKDOWN;
-	else
-		link = NOTE_LINKINV;
 	if (ifp->if_vlantrunk != NULL)
-		(*vlan_link_state_p)(ifp, link);
+		(*vlan_link_state_p)(ifp, 0);
 
 	if ((ifp->if_type == IFT_ETHER || ifp->if_type == IFT_L2VLAN) &&
 	    IFP2AC(ifp)->ac_netgraph != NULL)
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 4365e44e58d..d92eb55d43d 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -38,7 +38,7 @@
 #define EVFILT_PROC		(-5)	/* attached to struct proc */
 #define EVFILT_SIGNAL		(-6)	/* attached to struct proc */
 #define EVFILT_TIMER		(-7)	/* timers */
-#define EVFILT_NETDEV		(-8)	/* network devices */
+/*	EVFILT_NETDEV		(-8)	   no longer supported */
 #define EVFILT_FS		(-9)	/* filesystem events */
 #define EVFILT_LIO		(-10)	/* attached to lio requests */
 #define EVFILT_USER		(-11)	/* User events */
@@ -131,13 +131,6 @@ struct kevent {
 #define	NOTE_TRACKERR	0x00000002		/* could not track child */
 #define	NOTE_CHILD	0x00000004		/* am a child process */
 
-/*
- * data/hint flags for EVFILT_NETDEV, shared with userspace
- */
-#define NOTE_LINKUP	0x0001			/* link is up */
-#define NOTE_LINKDOWN	0x0002			/* link is down */
-#define NOTE_LINKINV	0x0004			/* link state is invalid */
-
 struct knote;
 SLIST_HEAD(klist, knote);
 struct kqueue;
diff --git a/tools/regression/fifo/fifo_misc/fifo_misc.c b/tools/regression/fifo/fifo_misc/fifo_misc.c
index b379d18c057..d0a2cf7f70c 100644
--- a/tools/regression/fifo/fifo_misc/fifo_misc.c
+++ b/tools/regression/fifo/fifo_misc/fifo_misc.c
@@ -148,114 +148,6 @@ test_truncate(void)
 	cleanfifo("testfifo", -1, -1);
 }
 
-struct filter_entry {
-	int		 fe_filter;
-	const char	*fe_name;
-	int		 fe_error;
-	const char	*fe_errorname;
-};
-
-static const struct filter_entry good_filter_types[] = {
-	{ EVFILT_READ, "EVFILT_READ", 0, "0" },
-	{ EVFILT_WRITE, "EVFILT_WRITE", 0, "0" },
-#if WORKING_EVFILT_VNODE_ON_FIFOS
-	{ EVFILT_VNODE, "EVFILT_VNODE", EINVAL, "EINVAL" },
-#endif
-};
-static const int good_filter_types_len = sizeof(good_filter_types) /
-    sizeof(good_filter_types[0]);
-
-static const struct filter_entry bad_filter_types[] = {
-	{ EVFILT_NETDEV, "EVFILT_NETDEV", EINVAL, "EINVAL" },
-};
-static const int bad_filter_types_len = sizeof(bad_filter_types) /
-    sizeof(bad_filter_types[0]);
-
-/*
- * kqueue event-related tests are in fifo_io.c; however, that tests only
- * valid invocations of kqueue.  Check to make sure that some invalid filters
- * that are generally allowed on file descriptors are not allowed to be
- * registered with kqueue, and that if attempts are made, we get the right
- * error.
- */
-static void
-test_kqueue(void)
-{
-	int kqueue_fd, reader_fd, writer_fd;
-	struct kevent kev_set;
-	struct timespec timeout;
-	int i, ret;
-
-	makefifo("testfifo", __func__);
-
-	if (openfifo("testfifo", __func__, &reader_fd, &writer_fd) < 0) {
-		warn("%s: openfifo", __func__);
-		cleanfifo("testfifo", -1, -1);
-		exit(-1);
-	}
-
-	kqueue_fd = kqueue();
-	if (kqueue_fd < 0) {
-		warn("%s: kqueue", __func__);
-		cleanfifo("testfifo", reader_fd, writer_fd);
-		exit(-1);
-	}
-
-	timeout.tv_sec = 0;
-	timeout.tv_nsec = 0;
-
-	for (i = 0; i < good_filter_types_len; i++) {
-		bzero(&kev_set, sizeof(kev_set));
-		EV_SET(&kev_set, reader_fd, good_filter_types[i].fe_filter,
-		    EV_ADD, 0, 0, 0);
-		ret = kevent(kqueue_fd, &kev_set, 1, NULL, 0, &timeout);
-		if (ret < 0) {
-			warn("%s: kevent: adding good filter %s", __func__,
-			    good_filter_types[i].fe_name);
-			close(kqueue_fd);
-			cleanfifo("testfifo", reader_fd, writer_fd);
-			exit(-1);
-		}
-		bzero(&kev_set, sizeof(kev_set));
-		EV_SET(&kev_set, reader_fd, good_filter_types[i].fe_filter,
-		    EV_DELETE, 0, 0, 0);
-		ret = kevent(kqueue_fd, &kev_set, 1, NULL, 0, &timeout);
-		if (ret < 0) {
-			warn("%s: kevent: deleting good filter %s", __func__,
-			    good_filter_types[i].fe_name);
-			close(kqueue_fd);
-			cleanfifo("testfifo", reader_fd, writer_fd);
-			exit(-1);
-		}
-	}
-
-	for (i = 0; i < bad_filter_types_len; i++) {
-		bzero(&kev_set, sizeof(kev_set));
-		EV_SET(&kev_set, reader_fd, bad_filter_types[i].fe_filter,
-		    EV_ADD, 0, 0, 0);
-		ret = kevent(kqueue_fd, &kev_set, 1, NULL, 0, &timeout);
-		if (ret >= 0) {
-			warnx("%s: kevent: bad filter %s succeeded, expected "
-			    "EINVAL", __func__, bad_filter_types[i].fe_name);
-			close(kqueue_fd);
-			cleanfifo("testfifo", reader_fd, writer_fd);
-			exit(-1);
-		}
-		if (errno != bad_filter_types[i].fe_error) {
-			warn("%s: kevent: bad filter %s failed with error "
-			    "not %s", __func__,
-			    bad_filter_types[i].fe_name,
-			    bad_filter_types[i].fe_errorname);
-			close(kqueue_fd);
-			cleanfifo("testfifo", reader_fd, writer_fd);
-			exit(-1);
-		}
-	}
-
-	close(kqueue_fd);
-	cleanfifo("testfifo", reader_fd, writer_fd);
-}
-
 static int
 test_ioctl_setclearflag(int fd, int flag, const char *testname,
     const char *fdname, const char *flagname)
@@ -345,7 +237,6 @@ main(int argc, char *argv[])
 
 	test_lseek();
 	test_truncate();
-	test_kqueue();
 	test_ioctl();
 
 	return (0);
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index d9278156649..ccceed04ff1 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -259,7 +259,7 @@ struct xlat {
 static struct xlat kevent_filters[] = {
 	X(EVFILT_READ) X(EVFILT_WRITE) X(EVFILT_AIO) X(EVFILT_VNODE)
 	X(EVFILT_PROC) X(EVFILT_SIGNAL) X(EVFILT_TIMER)
-	X(EVFILT_NETDEV) X(EVFILT_FS) X(EVFILT_READ) XEND
+	X(EVFILT_FS) X(EVFILT_READ) XEND
 };
 
 static struct xlat kevent_flags[] = {

From 2be621fabafaef301498d68c2dcbe867c7592d22 Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Fri, 22 Jan 2010 20:02:22 +0000
Subject: [PATCH 1270/2592] Merge r201647 from head:   Print leading zeros in
 the UFS2 FSID.

PR:		bin/142155
Submitted by:	Efstratios Karatzas  gpf.kira gmail.com
Approved by:	ed (mentor, implicit)
---
 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..6b17f232cda 100644
--- a/sbin/dumpfs/dumpfs.c
+++ b/sbin/dumpfs/dumpfs.c
@@ -160,7 +160,7 @@ dumpfs(const char *name)
 		fstime = afs.fs_old_time;
 		printf("magic\t%x (UFS1)\ttime\t%s",
 		    afs.fs_magic, ctime(&fstime));
-		printf("id\t[ %x %x ]\n", afs.fs_id[0], afs.fs_id[1]);
+		printf("id\t[ %08x %08x ]\n", afs.fs_id[0], afs.fs_id[1]);
 		printf("ncg\t%d\tsize\t%jd\tblocks\t%jd\n",
 		    afs.fs_ncg, (intmax_t)fssize, (intmax_t)afs.fs_dsize);
 		break;

From 2ca586a5acf7f900a6cd2f8563fe3381432bebe5 Mon Sep 17 00:00:00 2001
From: Brooks Davis 
Date: Fri, 22 Jan 2010 20:24:55 +0000
Subject: [PATCH 1271/2592] MFC r201261:   Add missing `void' keywords.

---
 sys/dev/aic7xxx/aicasm/aicasm.c            | 12 ++++++------
 sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l |  2 +-
 sys/dev/aic7xxx/aicasm/aicasm_scan.l       |  2 +-
 sys/dev/aic7xxx/aicasm/aicasm_symbol.c     |  4 ++--
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/sys/dev/aic7xxx/aicasm/aicasm.c b/sys/dev/aic7xxx/aicasm/aicasm.c
index 3c9109ce38d..6c88f90000a 100644
--- a/sys/dev/aic7xxx/aicasm/aicasm.c
+++ b/sys/dev/aic7xxx/aicasm/aicasm.c
@@ -306,7 +306,7 @@ main(int argc, char *argv[])
 }
 
 static void
-usage()
+usage(void)
 {
 
 	(void)fprintf(stderr,
@@ -318,7 +318,7 @@ usage()
 }
 
 static void
-back_patch()
+back_patch(void)
 {
 	struct instruction *cur_instr;
 
@@ -347,7 +347,7 @@ back_patch()
 }
 
 static void
-output_code()
+output_code(void)
 {
 	struct instruction *cur_instr;
 	patch_t *cur_patch;
@@ -733,7 +733,7 @@ stop(const char *string, int err_code)
 }
 
 struct instruction *
-seq_alloc()
+seq_alloc(void)
 {
 	struct instruction *new_instr;
 
@@ -747,7 +747,7 @@ seq_alloc()
 }
 
 critical_section_t *
-cs_alloc()
+cs_alloc(void)
 {
 	critical_section_t *new_cs;
 
@@ -761,7 +761,7 @@ cs_alloc()
 }
 
 scope_t *
-scope_alloc()
+scope_alloc(void)
 {
 	scope_t *new_scope;
 
diff --git a/sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l b/sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l
index b8700eb4adf..ad06507486f 100644
--- a/sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l
+++ b/sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l
@@ -152,7 +152,7 @@ MCARG		[^(), \t]+
 %%
 
 int
-mmwrap()
+mmwrap(void)
 {
 	stop("EOF encountered in macro call", EX_DATAERR);
 	return (1);
diff --git a/sys/dev/aic7xxx/aicasm/aicasm_scan.l b/sys/dev/aic7xxx/aicasm/aicasm_scan.l
index 9dd98946159..28218621aea 100644
--- a/sys/dev/aic7xxx/aicasm/aicasm_scan.l
+++ b/sys/dev/aic7xxx/aicasm/aicasm_scan.l
@@ -590,7 +590,7 @@ next_substitution(struct symbol *mac_symbol, const char *body_pos,
 }
 
 int
-yywrap()
+yywrap(void)
 {
 	include_t *include;
 
diff --git a/sys/dev/aic7xxx/aicasm/aicasm_symbol.c b/sys/dev/aic7xxx/aicasm/aicasm_symbol.c
index e7bbb699bf6..2e5d5c4feed 100644
--- a/sys/dev/aic7xxx/aicasm/aicasm_symbol.c
+++ b/sys/dev/aic7xxx/aicasm/aicasm_symbol.c
@@ -129,7 +129,7 @@ symbol_delete(symbol_t *symbol)
 }
 
 void
-symtable_open()
+symtable_open(void)
 {
 	symtable = dbopen(/*filename*/NULL,
 			  O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH,
@@ -143,7 +143,7 @@ symtable_open()
 }
 
 void
-symtable_close()
+symtable_close(void)
 {
 	if (symtable != NULL) {
 		DBT	 key;

From aa780fe9b5a7a37244f9a16673fee962b7cf813a Mon Sep 17 00:00:00 2001
From: Florent Thoumie 
Date: Fri, 22 Jan 2010 23:13:46 +0000
Subject: [PATCH 1272/2592] Synchronize pkg_install with HEAD.

---
 usr.sbin/pkg_install/add/main.c        |  2 +-
 usr.sbin/pkg_install/create/main.c     |  2 +-
 usr.sbin/pkg_install/delete/Makefile   |  1 -
 usr.sbin/pkg_install/delete/main.c     |  2 +-
 usr.sbin/pkg_install/info/Makefile     |  1 -
 usr.sbin/pkg_install/info/main.c       |  2 +-
 usr.sbin/pkg_install/lib/lib.h         | 12 ++++++------
 usr.sbin/pkg_install/updating/Makefile |  1 -
 usr.sbin/pkg_install/version/Makefile  |  1 -
 usr.sbin/pkg_install/version/main.c    |  2 +-
 10 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/usr.sbin/pkg_install/add/main.c b/usr.sbin/pkg_install/add/main.c
index eaed0c0c2eb..d9b381bdd9b 100644
--- a/usr.sbin/pkg_install/add/main.c
+++ b/usr.sbin/pkg_install/add/main.c
@@ -344,7 +344,7 @@ getpackagesite(void)
 }
 
 static void
-usage()
+usage(void)
 {
     fprintf(stderr, "%s\n%s\n",
 	"usage: pkg_add [-viInfFrRMSK] [-t template] [-p prefix] [-P prefix] [-C chrootdir]",
diff --git a/usr.sbin/pkg_install/create/main.c b/usr.sbin/pkg_install/create/main.c
index b98b21ee9db..d85392dc9c7 100644
--- a/usr.sbin/pkg_install/create/main.c
+++ b/usr.sbin/pkg_install/create/main.c
@@ -249,7 +249,7 @@ main(int argc, char **argv)
 }
 
 static void
-usage()
+usage(void)
 {
     fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
 "usage: pkg_create [-YNOhjnvyz] [-C conflicts] [-P pkgs] [-p prefix]",
diff --git a/usr.sbin/pkg_install/delete/Makefile b/usr.sbin/pkg_install/delete/Makefile
index c346ea705d7..c9a0fdebea2 100644
--- a/usr.sbin/pkg_install/delete/Makefile
+++ b/usr.sbin/pkg_install/delete/Makefile
@@ -5,7 +5,6 @@ SRCS=	main.c perform.c
 
 CFLAGS+= -I${.CURDIR}/../lib
 
-WARNS?=	6
 WFORMAT?=	1
 
 DPADD=	${LIBINSTALL} ${LIBMD}
diff --git a/usr.sbin/pkg_install/delete/main.c b/usr.sbin/pkg_install/delete/main.c
index 6075f72ab10..f09a432f2bb 100644
--- a/usr.sbin/pkg_install/delete/main.c
+++ b/usr.sbin/pkg_install/delete/main.c
@@ -170,7 +170,7 @@ main(int argc, char **argv)
 }
 
 static void
-usage()
+usage(void)
 {
     fprintf(stderr, "%s\n%s\n",
 	"usage: pkg_delete [-dDfGinrvxX] [-p prefix] pkg-name ...",
diff --git a/usr.sbin/pkg_install/info/Makefile b/usr.sbin/pkg_install/info/Makefile
index 675f7ca454a..485cb226321 100644
--- a/usr.sbin/pkg_install/info/Makefile
+++ b/usr.sbin/pkg_install/info/Makefile
@@ -5,7 +5,6 @@ SRCS=	main.c perform.c show.c
 
 CFLAGS+= -I${.CURDIR}/../lib
 
-WARNS?=	6
 WFORMAT?=	1
 
 DPADD=	${LIBINSTALL} ${LIBFETCH} ${LIBMD}
diff --git a/usr.sbin/pkg_install/info/main.c b/usr.sbin/pkg_install/info/main.c
index 08ab23b2295..2de638e4cad 100644
--- a/usr.sbin/pkg_install/info/main.c
+++ b/usr.sbin/pkg_install/info/main.c
@@ -282,7 +282,7 @@ main(int argc, char **argv)
 }
 
 static void
-usage()
+usage(void)
 {
     fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
 	"usage: pkg_info [-bcdDEfgGiIjkKLmopPqQrRsvVxX] [-e package] [-l prefix]",
diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h
index acbd017c83c..a3d04138797 100644
--- a/usr.sbin/pkg_install/lib/lib.h
+++ b/usr.sbin/pkg_install/lib/lib.h
@@ -84,14 +84,14 @@
 #define DISPLAY_FNAME		"+DISPLAY"
 #define MTREE_FNAME		"+MTREE_DIRS"
 
-#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000
+#define INDEX_FNAME		"INDEX-9"
+#elif defined(__FreeBSD_version) && __FreeBSD_version >= 800000
 #define INDEX_FNAME		"INDEX-8"
 #elif defined(__FreeBSD_version) && __FreeBSD_version >= 700000
 #define INDEX_FNAME		"INDEX-7"
 #elif defined(__FreeBSD_version) && __FreeBSD_version >= 600000
 #define INDEX_FNAME		"INDEX-6"
-#elif defined(__FreeBSD_version) && __FreeBSD_version >= 500036
-#define INDEX_FNAME		"INDEX-5"
 #else
 #define INDEX_FNAME		"INDEX"
 #endif
@@ -102,10 +102,10 @@
 #define PKG_PREFIX_VNAME	"PKG_PREFIX"
 
 /*
- * Version of the package tools - increase only when some
- * functionality used by bsd.port.mk is changed, added or removed
+ * Version of the package tools - increase whenever you make a change
+ * in the code that is not cosmetic only.
  */
-#define PKG_INSTALL_VERSION	20090519
+#define PKG_INSTALL_VERSION	20090902
 
 #define PKG_WRAPCONF_FNAME	"/var/db/pkg_install.conf"
 #define main(argc, argv)	real_main(argc, argv)
diff --git a/usr.sbin/pkg_install/updating/Makefile b/usr.sbin/pkg_install/updating/Makefile
index cf8bfc8718c..b0d3689779e 100644
--- a/usr.sbin/pkg_install/updating/Makefile
+++ b/usr.sbin/pkg_install/updating/Makefile
@@ -5,7 +5,6 @@ SRCS=	main.c
 
 CFLAGS+= -I${.CURDIR}/../lib
 
-WARNS?=	6
 WFORMAT?= 1
 
 DPADD=	${LIBINSTALL} ${LIBFETCH} ${LIBMD}
diff --git a/usr.sbin/pkg_install/version/Makefile b/usr.sbin/pkg_install/version/Makefile
index 71168ee3d23..3e1d7a522f2 100644
--- a/usr.sbin/pkg_install/version/Makefile
+++ b/usr.sbin/pkg_install/version/Makefile
@@ -5,7 +5,6 @@ SRCS=	main.c perform.c
 
 CFLAGS+= -I${.CURDIR}/../lib
 
-WARNS?=	6
 WFORMAT?=	1
 
 DPADD=	${LIBINSTALL} ${LIBFETCH} ${LIBMD}
diff --git a/usr.sbin/pkg_install/version/main.c b/usr.sbin/pkg_install/version/main.c
index f46d945f4ef..cad8583c23b 100644
--- a/usr.sbin/pkg_install/version/main.c
+++ b/usr.sbin/pkg_install/version/main.c
@@ -127,7 +127,7 @@ main(int argc, char **argv)
 }
 
 static void
-usage()
+usage(void)
 {
     fprintf(stderr, "%s\n%s\n%s\n",
 	"usage: pkg_version [-hIoqv] [-l limchar] [-L limchar] [[-X] -s string] [-O origin] [index]",

From bd277cec42dc437631f95e87fa0fa8acdaa76c58 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sat, 23 Jan 2010 00:32:19 +0000
Subject: [PATCH 1273/2592] MFC r200930:

Adapt OpenBSD pf's "sloopy" TCP state machine which is useful for Direct
Server Return mode, where not all packets would be visible to the load
balancer or gateway.

This commit should be reverted when we merge future pf versions.  The
benefit it would provide is that this version does not break any existing
public interface and thus won't be a problem if we want to MFC it to
earlier FreeBSD releases.

Discussed with:	mlaier
Obtained from:	OpenBSD
Sponsored by:	iXsystems, Inc.
---
 contrib/pf/man/pf.conf.5          |  11 +-
 contrib/pf/pfctl/parse.y          |  28 +-
 contrib/pf/pfctl/pf_print_state.c |   2 +
 contrib/pf/pfctl/pfctl_parser.c   |   8 +
 sys/contrib/pf/net/if_pfsync.c    |   4 +-
 sys/contrib/pf/net/if_pfsync.h    |   2 +-
 sys/contrib/pf/net/pf.c           | 798 +++++++++++++++++-------------
 sys/contrib/pf/net/pfvar.h        |   5 +-
 8 files changed, 510 insertions(+), 348 deletions(-)

diff --git a/contrib/pf/man/pf.conf.5 b/contrib/pf/man/pf.conf.5
index 67cb717540e..98c3d0ea878 100644
--- a/contrib/pf/man/pf.conf.5
+++ b/contrib/pf/man/pf.conf.5
@@ -28,7 +28,7 @@
 .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd October 30, 2006
+.Dd June 10, 2008
 .Dt PF.CONF 5
 .Os
 .Sh NAME
@@ -2059,6 +2059,13 @@ Changes the timeout values used for states created by this rule.
 For a list of all valid timeout names, see
 .Sx OPTIONS
 above.
+.It Ar sloppy
+Uses a sloppy TCP connection tracker that does not check sequence
+numbers at all, which makes insertion and ICMP teardown attacks way
+easier.
+This is intended to be used in situations where one does not see all
+packets of a connection, i.e. in asymmetric routing situations.
+Cannot be used with modulate or synproxy state.
 .El
 .Pp
 Multiple options can be specified, separated by commas:
@@ -2923,7 +2930,7 @@ tos            = "tos" ( "lowdelay" | "throughput" | "reliability" |
                  [ "0x" ] number )
 
 state-opts     = state-opt [ [ "," ] state-opts ]
-state-opt      = ( "max" number | "no-sync" | timeout |
+state-opt      = ( "max" number | "no-sync" | timeout | sloppy |
                  "source-track" [ ( "rule" | "global" ) ] |
                  "max-src-nodes" number | "max-src-states" number |
                  "max-src-conn" number |
diff --git a/contrib/pf/pfctl/parse.y b/contrib/pf/pfctl/parse.y
index 9817e8e2378..c22a0b662e6 100644
--- a/contrib/pf/pfctl/parse.y
+++ b/contrib/pf/pfctl/parse.y
@@ -128,7 +128,7 @@ enum	{ PF_STATE_OPT_MAX, PF_STATE_OPT_NOSYNC, PF_STATE_OPT_SRCTRACK,
 	    PF_STATE_OPT_MAX_SRC_STATES, PF_STATE_OPT_MAX_SRC_CONN,
 	    PF_STATE_OPT_MAX_SRC_CONN_RATE, PF_STATE_OPT_MAX_SRC_NODES,
 	    PF_STATE_OPT_OVERLOAD, PF_STATE_OPT_STATELOCK,
-	    PF_STATE_OPT_TIMEOUT };
+	    PF_STATE_OPT_TIMEOUT, PF_STATE_OPT_SLOPPY };
 
 enum	{ PF_SRCTRACK_NONE, PF_SRCTRACK, PF_SRCTRACK_GLOBAL, PF_SRCTRACK_RULE };
 
@@ -423,7 +423,7 @@ typedef struct {
 %token	QUEUE PRIORITY QLIMIT RTABLE
 %token	LOAD RULESET_OPTIMIZATION
 %token	STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
-%token	MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH
+%token	MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY
 %token	TAGGED TAG IFBOUND FLOATING STATEPOLICY ROUTE
 %token			STRING
 %token				PORTBINARY
@@ -1891,6 +1891,14 @@ pfrule		: action dir logquick interface route af proto fromto
 					statelock = 1;
 					r.rule_flag |= o->data.statelock;
 					break;
+				case PF_STATE_OPT_SLOPPY:
+					if (r.rule_flag & PFRULE_STATESLOPPY) {
+						yyerror("state sloppy option: "
+						    "multiple definitions");
+						YYERROR;
+					}
+					r.rule_flag |= PFRULE_STATESLOPPY;
+					break;
 				case PF_STATE_OPT_TIMEOUT:
 					if (o->data.timeout.number ==
 					    PFTM_ADAPTIVE_START ||
@@ -3216,6 +3224,14 @@ state_opt_item	: MAXIMUM number		{
 			$$->next = NULL;
 			$$->tail = $$;
 		}
+		| SLOPPY {
+			$$ = calloc(1, sizeof(struct node_state_opt));
+			if ($$ == NULL)
+				err(1, "state_opt_item: calloc");
+			$$->type = PF_STATE_OPT_SLOPPY;
+			$$->next = NULL;
+			$$->tail = $$;
+		}
 		| STRING number			{
 			int	i;
 
@@ -4101,6 +4117,13 @@ filter_consistent(struct pf_rule *r, int anchor_call)
 		yyerror("keep state on block rules doesn't make sense");
 		problems++;
 	}
+	if (r->rule_flag & PFRULE_STATESLOPPY &&
+	    (r->keep_state == PF_STATE_MODULATE ||
+	    r->keep_state == PF_STATE_SYNPROXY)) {
+		yyerror("sloppy state matching cannot be used with "
+		    "synproxy state or modulate state");
+		problems++;
+	}
 	return (-problems);
 }
 
@@ -4969,6 +4992,7 @@ lookup(char *s)
 		{ "scrub",		SCRUB},
 		{ "set",		SET},
 		{ "skip",		SKIP},
+		{ "sloppy",		SLOPPY},
 		{ "source-hash",	SOURCEHASH},
 		{ "source-track",	SOURCETRACK},
 		{ "state",		STATE},
diff --git a/contrib/pf/pfctl/pf_print_state.c b/contrib/pf/pfctl/pf_print_state.c
index b3a693a5986..02a39b32156 100644
--- a/contrib/pf/pfctl/pf_print_state.c
+++ b/contrib/pf/pfctl/pf_print_state.c
@@ -294,6 +294,8 @@ print_state(struct pf_state *s, int opts)
 			printf(", anchor %u", s->anchor.nr);
 		if (s->rule.nr != -1)
 			printf(", rule %u", s->rule.nr);
+		if (s->state_flags & PFSTATE_SLOPPY)
+			printf(", sloppy");
 		if (s->src_node != NULL)
 			printf(", source-track");
 		if (s->nat_src_node != NULL)
diff --git a/contrib/pf/pfctl/pfctl_parser.c b/contrib/pf/pfctl/pfctl_parser.c
index 9f232bdb783..c9b2e1189b6 100644
--- a/contrib/pf/pfctl/pfctl_parser.c
+++ b/contrib/pf/pfctl/pfctl_parser.c
@@ -873,6 +873,8 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
 		opts = 1;
 	if (r->rule_flag & PFRULE_IFBOUND)
 		opts = 1;
+	if (r->rule_flag & PFRULE_STATESLOPPY)
+		opts = 1;
 	for (i = 0; !opts && i < PFTM_MAX; ++i)
 		if (r->timeout[i])
 			opts = 1;
@@ -939,6 +941,12 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
 			printf("if-bound");
 			opts = 0;
 		}
+		if (r->rule_flag & PFRULE_STATESLOPPY) {
+			if (!opts)
+				printf(", ");
+			printf("sloppy");
+			opts = 0;
+		}
 		for (i = 0; i < PFTM_MAX; ++i)
 			if (r->timeout[i]) {
 				int j;
diff --git a/sys/contrib/pf/net/if_pfsync.c b/sys/contrib/pf/net/if_pfsync.c
index 0925edb094b..94661185917 100644
--- a/sys/contrib/pf/net/if_pfsync.c
+++ b/sys/contrib/pf/net/if_pfsync.c
@@ -465,7 +465,7 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
 	st->direction = sp->direction;
 	st->log = sp->log;
 	st->timeout = sp->timeout;
-	st->allow_opts = sp->allow_opts;
+	st->state_flags = sp->state_flags;
 
 	bcopy(sp->id, &st->id, sizeof(st->id));
 	st->creatorid = sp->creatorid;
@@ -1578,7 +1578,7 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
 		sp->proto = st->proto;
 		sp->direction = st->direction;
 		sp->log = st->log;
-		sp->allow_opts = st->allow_opts;
+		sp->state_flags = st->state_flags;
 		sp->timeout = st->timeout;
 
 		if (flags & PFSYNC_FLAG_STALE)
diff --git a/sys/contrib/pf/net/if_pfsync.h b/sys/contrib/pf/net/if_pfsync.h
index f7edca3e400..f306610fb3d 100644
--- a/sys/contrib/pf/net/if_pfsync.h
+++ b/sys/contrib/pf/net/if_pfsync.h
@@ -80,7 +80,7 @@ struct pfsync_state {
 	u_int8_t	 proto;
 	u_int8_t	 direction;
 	u_int8_t	 log;
-	u_int8_t	 allow_opts;
+	u_int8_t	 state_flags;
 	u_int8_t	 timeout;
 	u_int8_t	 sync_flags;
 	u_int8_t	 updates;
diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c
index e8031ac7dfe..ebe73c2e932 100644
--- a/sys/contrib/pf/net/pf.c
+++ b/sys/contrib/pf/net/pf.c
@@ -253,6 +253,13 @@ int			 pf_test_fragment(struct pf_rule **, int,
 			    struct pfi_kif *, struct mbuf *, void *,
 			    struct pf_pdesc *, struct pf_rule **,
 			    struct pf_ruleset **);
+int			 pf_tcp_track_full(struct pf_state_peer *,
+			    struct pf_state_peer *, struct pf_state **,
+			    struct pfi_kif *, struct mbuf *, int,
+			    struct pf_pdesc *, u_short *, int *);
+int			 pf_tcp_track_sloppy(struct pf_state_peer *,
+			    struct pf_state_peer *, struct pf_state **,
+			    struct pf_pdesc *, u_short *);
 int			 pf_test_state_tcp(struct pf_state **, int,
 			    struct pfi_kif *, struct mbuf *, int,
 			    void *, struct pf_pdesc *, u_short *);
@@ -3528,7 +3535,10 @@ cleanup:
 		s->nat_rule.ptr = nr;
 		s->anchor.ptr = a;
 		STATE_INC_COUNTERS(s);
-		s->allow_opts = r->allow_opts;
+		if (r->allow_opts)
+			s->state_flags |= PFSTATE_ALLOWOPTS;
+		if (r->rule_flag & PFRULE_STATESLOPPY)
+			s->state_flags |= PFSTATE_SLOPPY;
 		s->log = r->log & PF_LOG_ALL;
 		if (nr != NULL)
 			s->log |= nr->log & PF_LOG_ALL;
@@ -3925,7 +3935,10 @@ cleanup:
 		s->nat_rule.ptr = nr;
 		s->anchor.ptr = a;
 		STATE_INC_COUNTERS(s);
-		s->allow_opts = r->allow_opts;
+		if (r->allow_opts)
+			s->state_flags |= PFSTATE_ALLOWOPTS;
+ 		if (r->rule_flag & PFRULE_STATESLOPPY)
+			s->state_flags |= PFSTATE_SLOPPY;
 		s->log = r->log & PF_LOG_ALL;
 		if (nr != NULL)
 			s->log |= nr->log & PF_LOG_ALL;
@@ -4238,7 +4251,10 @@ cleanup:
 		s->nat_rule.ptr = nr;
 		s->anchor.ptr = a;
 		STATE_INC_COUNTERS(s);
-		s->allow_opts = r->allow_opts;
+		if (r->allow_opts)
+			s->state_flags |= PFSTATE_ALLOWOPTS;
+ 		if (r->rule_flag & PFRULE_STATESLOPPY)
+			s->state_flags |= PFSTATE_SLOPPY;
 		s->log = r->log & PF_LOG_ALL;
 		if (nr != NULL)
 			s->log |= nr->log & PF_LOG_ALL;
@@ -4525,7 +4541,10 @@ cleanup:
 		s->nat_rule.ptr = nr;
 		s->anchor.ptr = a;
 		STATE_INC_COUNTERS(s);
-		s->allow_opts = r->allow_opts;
+		if (r->allow_opts)
+			s->state_flags |= PFSTATE_ALLOWOPTS;
+ 		if (r->rule_flag & PFRULE_STATESLOPPY)
+			s->state_flags |= PFSTATE_SLOPPY;
 		s->log = r->log & PF_LOG_ALL;
 		if (nr != NULL)
 			s->log |= nr->log & PF_LOG_ALL;
@@ -4665,6 +4684,430 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
 	return (PF_PASS);
 }
 
+int
+pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst,
+	struct pf_state **state, struct pfi_kif *kif, struct mbuf *m, int off,
+	struct pf_pdesc *pd, u_short *reason, int *copyback)
+{
+ 	struct tcphdr		*th = pd->hdr.tcp;
+ 	u_int16_t		 win = ntohs(th->th_win);
+ 	u_int32_t		 ack, end, seq, orig_seq;
+ 	u_int8_t		 sws, dws;
+ 	int			 ackskew;
+
+	if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
+		sws = src->wscale & PF_WSCALE_MASK;
+		dws = dst->wscale & PF_WSCALE_MASK;
+	} else
+		sws = dws = 0;
+
+	/*
+	 * Sequence tracking algorithm from Guido van Rooij's paper:
+	 *   http://www.madison-gurkha.com/publications/tcp_filtering/
+	 *	tcp_filtering.ps
+	 */
+
+	orig_seq = seq = ntohl(th->th_seq);
+	if (src->seqlo == 0) {
+		/* First packet from this end. Set its state */
+
+		if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
+		    src->scrub == NULL) {
+			if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
+				REASON_SET(reason, PFRES_MEMORY);
+				return (PF_DROP);
+			}
+		}
+
+		/* Deferred generation of sequence number modulator */
+		if (dst->seqdiff && !src->seqdiff) {
+#ifdef __FreeBSD__
+			while ((src->seqdiff = pf_new_isn(*state) - seq) == 0)
+				;
+#else
+			while ((src->seqdiff = tcp_rndiss_next() - seq) == 0)
+				;
+#endif
+			ack = ntohl(th->th_ack) - dst->seqdiff;
+			pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
+			    src->seqdiff), 0);
+			pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
+			*copyback = 1;
+		} else {
+			ack = ntohl(th->th_ack);
+		}
+
+		end = seq + pd->p_len;
+		if (th->th_flags & TH_SYN) {
+			end++;
+			if (dst->wscale & PF_WSCALE_FLAG) {
+				src->wscale = pf_get_wscale(m, off, th->th_off,
+				    pd->af);
+				if (src->wscale & PF_WSCALE_FLAG) {
+					/* Remove scale factor from initial
+					 * window */
+					sws = src->wscale & PF_WSCALE_MASK;
+					win = ((u_int32_t)win + (1 << sws) - 1)
+					    >> sws;
+					dws = dst->wscale & PF_WSCALE_MASK;
+				} else {
+					/* fixup other window */
+					dst->max_win <<= dst->wscale &
+					    PF_WSCALE_MASK;
+					/* in case of a retrans SYN|ACK */
+					dst->wscale = 0;
+				}
+			}
+		}
+		if (th->th_flags & TH_FIN)
+			end++;
+
+		src->seqlo = seq;
+		if (src->state < TCPS_SYN_SENT)
+			src->state = TCPS_SYN_SENT;
+
+		/*
+		 * May need to slide the window (seqhi may have been set by
+		 * the crappy stack check or if we picked up the connection
+		 * after establishment)
+		 */
+		if (src->seqhi == 1 ||
+		    SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
+			src->seqhi = end + MAX(1, dst->max_win << dws);
+		if (win > src->max_win)
+			src->max_win = win;
+
+	} else {
+		ack = ntohl(th->th_ack) - dst->seqdiff;
+		if (src->seqdiff) {
+			/* Modulate sequence numbers */
+			pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
+			    src->seqdiff), 0);
+			pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
+			*copyback = 1;
+		}
+		end = seq + pd->p_len;
+		if (th->th_flags & TH_SYN)
+			end++;
+		if (th->th_flags & TH_FIN)
+			end++;
+	}
+
+	if ((th->th_flags & TH_ACK) == 0) {
+		/* Let it pass through the ack skew check */
+		ack = dst->seqlo;
+	} else if ((ack == 0 &&
+	    (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
+	    /* broken tcp stacks do not set ack */
+	    (dst->state < TCPS_SYN_SENT)) {
+		/*
+		 * Many stacks (ours included) will set the ACK number in an
+		 * FIN|ACK if the SYN times out -- no sequence to ACK.
+		 */
+		ack = dst->seqlo;
+	}
+
+	if (seq == end) {
+		/* Ease sequencing restrictions on no data packets */
+		seq = src->seqlo;
+		end = seq;
+	}
+
+	ackskew = dst->seqlo - ack;
+
+
+	/*
+	 * Need to demodulate the sequence numbers in any TCP SACK options
+	 * (Selective ACK). We could optionally validate the SACK values
+	 * against the current ACK window, either forwards or backwards, but
+	 * I'm not confident that SACK has been implemented properly
+	 * everywhere. It wouldn't surprise me if several stacks accidently
+	 * SACK too far backwards of previously ACKed data. There really aren't
+	 * any security implications of bad SACKing unless the target stack
+	 * doesn't validate the option length correctly. Someone trying to
+	 * spoof into a TCP connection won't bother blindly sending SACK
+	 * options anyway.
+	 */
+	if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) {
+		if (pf_modulate_sack(m, off, pd, th, dst))
+			*copyback = 1;
+	}
+
+
+#define MAXACKWINDOW (0xffff + 1500)	/* 1500 is an arbitrary fudge factor */
+	if (SEQ_GEQ(src->seqhi, end) &&
+	    /* Last octet inside other's window space */
+	    SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
+	    /* Retrans: not more than one window back */
+	    (ackskew >= -MAXACKWINDOW) &&
+	    /* Acking not more than one reassembled fragment backwards */
+	    (ackskew <= (MAXACKWINDOW << sws)) &&
+	    /* Acking not more than one window forward */
+	    ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
+	    (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) {
+	    /* Require an exact/+1 sequence match on resets when possible */
+
+		if (dst->scrub || src->scrub) {
+			if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
+			    *state, src, dst, copyback))
+				return (PF_DROP);
+		}
+
+		/* update max window */
+		if (src->max_win < win)
+			src->max_win = win;
+		/* synchronize sequencing */
+		if (SEQ_GT(end, src->seqlo))
+			src->seqlo = end;
+		/* slide the window of what the other end can send */
+		if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
+			dst->seqhi = ack + MAX((win << sws), 1);
+
+
+		/* update states */
+		if (th->th_flags & TH_SYN)
+			if (src->state < TCPS_SYN_SENT)
+				src->state = TCPS_SYN_SENT;
+		if (th->th_flags & TH_FIN)
+			if (src->state < TCPS_CLOSING)
+				src->state = TCPS_CLOSING;
+		if (th->th_flags & TH_ACK) {
+			if (dst->state == TCPS_SYN_SENT) {
+				dst->state = TCPS_ESTABLISHED;
+				if (src->state == TCPS_ESTABLISHED &&
+				    (*state)->src_node != NULL &&
+				    pf_src_connlimit(state)) {
+					REASON_SET(reason, PFRES_SRCLIMIT);
+					return (PF_DROP);
+				}
+			} else if (dst->state == TCPS_CLOSING)
+				dst->state = TCPS_FIN_WAIT_2;
+		}
+		if (th->th_flags & TH_RST)
+			src->state = dst->state = TCPS_TIME_WAIT;
+
+		/* update expire time */
+		(*state)->expire = time_second;
+		if (src->state >= TCPS_FIN_WAIT_2 &&
+		    dst->state >= TCPS_FIN_WAIT_2)
+			(*state)->timeout = PFTM_TCP_CLOSED;
+		else if (src->state >= TCPS_CLOSING &&
+		    dst->state >= TCPS_CLOSING)
+			(*state)->timeout = PFTM_TCP_FIN_WAIT;
+		else if (src->state < TCPS_ESTABLISHED ||
+		    dst->state < TCPS_ESTABLISHED)
+			(*state)->timeout = PFTM_TCP_OPENING;
+		else if (src->state >= TCPS_CLOSING ||
+		    dst->state >= TCPS_CLOSING)
+			(*state)->timeout = PFTM_TCP_CLOSING;
+		else
+			(*state)->timeout = PFTM_TCP_ESTABLISHED;
+
+		/* Fall through to PASS packet */
+
+	} else if ((dst->state < TCPS_SYN_SENT ||
+		dst->state >= TCPS_FIN_WAIT_2 ||
+		src->state >= TCPS_FIN_WAIT_2) &&
+	    SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
+	    /* Within a window forward of the originating packet */
+	    SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
+	    /* Within a window backward of the originating packet */
+
+		/*
+		 * This currently handles three situations:
+		 *  1) Stupid stacks will shotgun SYNs before their peer
+		 *     replies.
+		 *  2) When PF catches an already established stream (the
+		 *     firewall rebooted, the state table was flushed, routes
+		 *     changed...)
+		 *  3) Packets get funky immediately after the connection
+		 *     closes (this should catch Solaris spurious ACK|FINs
+		 *     that web servers like to spew after a close)
+		 *
+		 * This must be a little more careful than the above code
+		 * since packet floods will also be caught here. We don't
+		 * update the TTL here to mitigate the damage of a packet
+		 * flood and so the same code can handle awkward establishment
+		 * and a loosened connection close.
+		 * In the establishment case, a correct peer response will
+		 * validate the connection, go through the normal state code
+		 * and keep updating the state TTL.
+		 */
+
+		if (pf_status.debug >= PF_DEBUG_MISC) {
+			printf("pf: loose state match: ");
+			pf_print_state(*state);
+			pf_print_flags(th->th_flags);
+			printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
+			    "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len,
+#ifdef __FreeBSD__
+			    ackskew, (unsigned long long)(*state)->packets[0],
+			    (unsigned long long)(*state)->packets[1]);
+#else
+			    ackskew, (*state)->packets[0],
+			    (*state)->packets[1]);
+#endif
+		}
+
+		if (dst->scrub || src->scrub) {
+			if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
+			    *state, src, dst, copyback))
+				return (PF_DROP);
+		}
+
+		/* update max window */
+		if (src->max_win < win)
+			src->max_win = win;
+		/* synchronize sequencing */
+		if (SEQ_GT(end, src->seqlo))
+			src->seqlo = end;
+		/* slide the window of what the other end can send */
+		if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
+			dst->seqhi = ack + MAX((win << sws), 1);
+
+		/*
+		 * Cannot set dst->seqhi here since this could be a shotgunned
+		 * SYN and not an already established connection.
+		 */
+
+		if (th->th_flags & TH_FIN)
+			if (src->state < TCPS_CLOSING)
+				src->state = TCPS_CLOSING;
+		if (th->th_flags & TH_RST)
+			src->state = dst->state = TCPS_TIME_WAIT;
+
+		/* Fall through to PASS packet */
+
+	} else {
+		if ((*state)->dst.state == TCPS_SYN_SENT &&
+		    (*state)->src.state == TCPS_SYN_SENT) {
+			/* Send RST for state mismatches during handshake */
+			if (!(th->th_flags & TH_RST))
+#ifdef __FreeBSD__
+				pf_send_tcp(m, (*state)->rule.ptr, pd->af,
+#else
+				pf_send_tcp((*state)->rule.ptr, pd->af,
+#endif
+				    pd->dst, pd->src, th->th_dport,
+				    th->th_sport, ntohl(th->th_ack), 0,
+				    TH_RST, 0, 0,
+				    (*state)->rule.ptr->return_ttl, 1, 0,
+				    pd->eh, kif->pfik_ifp);
+			src->seqlo = 0;
+			src->seqhi = 1;
+			src->max_win = 1;
+		} else if (pf_status.debug >= PF_DEBUG_MISC) {
+			printf("pf: BAD state: ");
+			pf_print_state(*state);
+			pf_print_flags(th->th_flags);
+			printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
+#ifdef notyet
+			    "pkts=%llu:%llu dir=%s,%s\n",
+#else
+			    "pkts=%llu:%llu%s\n",
+#endif
+			    seq, orig_seq, ack, pd->p_len, ackskew,
+#ifdef __FreeBSD__
+			    (unsigned long long)(*state)->packets[0],
+			    (unsigned long long)(*state)->packets[1],
+#else
+			    (*state)->packets[0], (*state)->packets[1],
+#endif
+#ifdef notyet
+			    direction == PF_IN ? "in" : "out",
+			    direction == (*state)->direction ? "fwd" : "rev");
+#else
+			    "");
+#endif
+			printf("pf: State failure on: %c %c %c %c | %c %c\n",
+			    SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
+			    SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
+			    ' ': '2',
+			    (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
+			    (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
+			    SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
+			    SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
+		}
+		REASON_SET(reason, PFRES_BADSTATE);
+		return (PF_DROP);
+	}
+
+	/* Any packets which have gotten here are to be passed */
+	return (PF_PASS);
+}
+
+int
+pf_tcp_track_sloppy(struct pf_state_peer *src, struct pf_state_peer *dst,
+	struct pf_state **state, struct pf_pdesc *pd, u_short *reason)
+{
+	struct tcphdr		*th = pd->hdr.tcp;
+
+	if (th->th_flags & TH_SYN)
+		if (src->state < TCPS_SYN_SENT)
+			src->state = TCPS_SYN_SENT;
+	if (th->th_flags & TH_FIN)
+		if (src->state < TCPS_CLOSING)
+			src->state = TCPS_CLOSING;
+	if (th->th_flags & TH_ACK) {
+		if (dst->state == TCPS_SYN_SENT) {
+			dst->state = TCPS_ESTABLISHED;
+			if (src->state == TCPS_ESTABLISHED &&
+			    (*state)->src_node != NULL &&
+			    pf_src_connlimit(state)) {
+				REASON_SET(reason, PFRES_SRCLIMIT);
+				return (PF_DROP);
+			}
+		} else if (dst->state == TCPS_CLOSING) {
+			dst->state = TCPS_FIN_WAIT_2;
+		} else if (src->state == TCPS_SYN_SENT &&
+		    dst->state < TCPS_SYN_SENT) {
+			/*
+			 * Handle a special sloppy case where we only see one
+			 * half of the connection. If there is a ACK after
+			 * the initial SYN without ever seeing a packet from
+			 * the destination, set the connection to established.
+			 */
+			dst->state = src->state = TCPS_ESTABLISHED;
+			if ((*state)->src_node != NULL &&
+			    pf_src_connlimit(state)) {
+				REASON_SET(reason, PFRES_SRCLIMIT);
+				return (PF_DROP);
+			}
+		} else if (src->state == TCPS_CLOSING &&
+		    dst->state == TCPS_ESTABLISHED &&
+		    dst->seqlo == 0) {
+			/*
+			 * Handle the closing of half connections where we
+			 * don't see the full bidirectional FIN/ACK+ACK
+			 * handshake.
+			 */
+			dst->state = TCPS_CLOSING;
+		}
+	}
+	if (th->th_flags & TH_RST)
+		src->state = dst->state = TCPS_TIME_WAIT;
+
+	/* update expire time */
+	(*state)->expire = time_second;
+	if (src->state >= TCPS_FIN_WAIT_2 &&
+	    dst->state >= TCPS_FIN_WAIT_2)
+		(*state)->timeout = PFTM_TCP_CLOSED;
+	else if (src->state >= TCPS_CLOSING &&
+	    dst->state >= TCPS_CLOSING)
+		(*state)->timeout = PFTM_TCP_FIN_WAIT;
+	else if (src->state < TCPS_ESTABLISHED ||
+	    dst->state < TCPS_ESTABLISHED)
+		(*state)->timeout = PFTM_TCP_OPENING;
+	else if (src->state >= TCPS_CLOSING ||
+	    dst->state >= TCPS_CLOSING)
+		(*state)->timeout = PFTM_TCP_CLOSING;
+	else
+		(*state)->timeout = PFTM_TCP_ESTABLISHED;
+
+	return (PF_PASS);
+}
+
+
 int
 pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
     struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
@@ -4672,10 +5115,6 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
 {
 	struct pf_state_cmp	 key;
 	struct tcphdr		*th = pd->hdr.tcp;
-	u_int16_t		 win = ntohs(th->th_win);
-	u_int32_t		 ack, end, seq, orig_seq;
-	u_int8_t		 sws, dws;
-	int			 ackskew;
 	int			 copyback = 0;
 	struct pf_state_peer	*src, *dst;
 
@@ -4826,337 +5265,15 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
 		return (PF_DROP);
 	}
 
-	if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
-		sws = src->wscale & PF_WSCALE_MASK;
-		dws = dst->wscale & PF_WSCALE_MASK;
-	} else
-		sws = dws = 0;
-
-	/*
-	 * Sequence tracking algorithm from Guido van Rooij's paper:
-	 *   http://www.madison-gurkha.com/publications/tcp_filtering/
-	 *	tcp_filtering.ps
-	 */
-
-	orig_seq = seq = ntohl(th->th_seq);
-	if (src->seqlo == 0) {
-		/* First packet from this end. Set its state */
-
-		if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
-		    src->scrub == NULL) {
-			if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
-				REASON_SET(reason, PFRES_MEMORY);
-				return (PF_DROP);
-			}
-		}
-
-		/* Deferred generation of sequence number modulator */
-		if (dst->seqdiff && !src->seqdiff) {
-#ifdef __FreeBSD__
-			while ((src->seqdiff = pf_new_isn(*state) - seq) == 0)
-				;
-#else
-			while ((src->seqdiff = tcp_rndiss_next() - seq) == 0)
-				;
-#endif
-			ack = ntohl(th->th_ack) - dst->seqdiff;
-			pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
-			    src->seqdiff), 0);
-			pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
-			copyback = 1;
-		} else {
-			ack = ntohl(th->th_ack);
-		}
-
-		end = seq + pd->p_len;
-		if (th->th_flags & TH_SYN) {
-			end++;
-			if (dst->wscale & PF_WSCALE_FLAG) {
-				src->wscale = pf_get_wscale(m, off, th->th_off,
-				    pd->af);
-				if (src->wscale & PF_WSCALE_FLAG) {
-					/* Remove scale factor from initial
-					 * window */
-					sws = src->wscale & PF_WSCALE_MASK;
-					win = ((u_int32_t)win + (1 << sws) - 1)
-					    >> sws;
-					dws = dst->wscale & PF_WSCALE_MASK;
-				} else {
-					/* fixup other window */
-					dst->max_win <<= dst->wscale &
-					    PF_WSCALE_MASK;
-					/* in case of a retrans SYN|ACK */
-					dst->wscale = 0;
-				}
-			}
-		}
-		if (th->th_flags & TH_FIN)
-			end++;
-
-		src->seqlo = seq;
-		if (src->state < TCPS_SYN_SENT)
-			src->state = TCPS_SYN_SENT;
-
-		/*
-		 * May need to slide the window (seqhi may have been set by
-		 * the crappy stack check or if we picked up the connection
-		 * after establishment)
-		 */
-		if (src->seqhi == 1 ||
-		    SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
-			src->seqhi = end + MAX(1, dst->max_win << dws);
-		if (win > src->max_win)
-			src->max_win = win;
-
+	if ((*state)->state_flags & PFSTATE_SLOPPY) {
+		if (pf_tcp_track_sloppy(src, dst, state, pd, reason) == PF_DROP)
+			return (PF_DROP);
 	} else {
-		ack = ntohl(th->th_ack) - dst->seqdiff;
-		if (src->seqdiff) {
-			/* Modulate sequence numbers */
-			pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
-			    src->seqdiff), 0);
-			pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
-			copyback = 1;
-		}
-		end = seq + pd->p_len;
-		if (th->th_flags & TH_SYN)
-			end++;
-		if (th->th_flags & TH_FIN)
-			end++;
+		if (pf_tcp_track_full(src, dst, state, kif, m, off, pd, reason,
+		    ©back) == PF_DROP)
+			return (PF_DROP);
 	}
 
-	if ((th->th_flags & TH_ACK) == 0) {
-		/* Let it pass through the ack skew check */
-		ack = dst->seqlo;
-	} else if ((ack == 0 &&
-	    (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
-	    /* broken tcp stacks do not set ack */
-	    (dst->state < TCPS_SYN_SENT)) {
-		/*
-		 * Many stacks (ours included) will set the ACK number in an
-		 * FIN|ACK if the SYN times out -- no sequence to ACK.
-		 */
-		ack = dst->seqlo;
-	}
-
-	if (seq == end) {
-		/* Ease sequencing restrictions on no data packets */
-		seq = src->seqlo;
-		end = seq;
-	}
-
-	ackskew = dst->seqlo - ack;
-
-
-	/*
-	 * Need to demodulate the sequence numbers in any TCP SACK options
-	 * (Selective ACK). We could optionally validate the SACK values
-	 * against the current ACK window, either forwards or backwards, but
-	 * I'm not confident that SACK has been implemented properly
-	 * everywhere. It wouldn't surprise me if several stacks accidently
-	 * SACK too far backwards of previously ACKed data. There really aren't
-	 * any security implications of bad SACKing unless the target stack
-	 * doesn't validate the option length correctly. Someone trying to
-	 * spoof into a TCP connection won't bother blindly sending SACK
-	 * options anyway.
-	 */
-	if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) {
-		if (pf_modulate_sack(m, off, pd, th, dst))
-			copyback = 1;
-	}
-
-
-#define MAXACKWINDOW (0xffff + 1500)	/* 1500 is an arbitrary fudge factor */
-	if (SEQ_GEQ(src->seqhi, end) &&
-	    /* Last octet inside other's window space */
-	    SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
-	    /* Retrans: not more than one window back */
-	    (ackskew >= -MAXACKWINDOW) &&
-	    /* Acking not more than one reassembled fragment backwards */
-	    (ackskew <= (MAXACKWINDOW << sws)) &&
-	    /* Acking not more than one window forward */
-	    ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
-	    (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) {
-	    /* Require an exact/+1 sequence match on resets when possible */
-
-		if (dst->scrub || src->scrub) {
-			if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
-			    *state, src, dst, ©back))
-				return (PF_DROP);
-		}
-
-		/* update max window */
-		if (src->max_win < win)
-			src->max_win = win;
-		/* synchronize sequencing */
-		if (SEQ_GT(end, src->seqlo))
-			src->seqlo = end;
-		/* slide the window of what the other end can send */
-		if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
-			dst->seqhi = ack + MAX((win << sws), 1);
-
-
-		/* update states */
-		if (th->th_flags & TH_SYN)
-			if (src->state < TCPS_SYN_SENT)
-				src->state = TCPS_SYN_SENT;
-		if (th->th_flags & TH_FIN)
-			if (src->state < TCPS_CLOSING)
-				src->state = TCPS_CLOSING;
-		if (th->th_flags & TH_ACK) {
-			if (dst->state == TCPS_SYN_SENT) {
-				dst->state = TCPS_ESTABLISHED;
-				if (src->state == TCPS_ESTABLISHED &&
-				    (*state)->src_node != NULL &&
-				    pf_src_connlimit(state)) {
-					REASON_SET(reason, PFRES_SRCLIMIT);
-					return (PF_DROP);
-				}
-			} else if (dst->state == TCPS_CLOSING)
-				dst->state = TCPS_FIN_WAIT_2;
-		}
-		if (th->th_flags & TH_RST)
-			src->state = dst->state = TCPS_TIME_WAIT;
-
-		/* update expire time */
-		(*state)->expire = time_second;
-		if (src->state >= TCPS_FIN_WAIT_2 &&
-		    dst->state >= TCPS_FIN_WAIT_2)
-			(*state)->timeout = PFTM_TCP_CLOSED;
-		else if (src->state >= TCPS_CLOSING &&
-		    dst->state >= TCPS_CLOSING)
-			(*state)->timeout = PFTM_TCP_FIN_WAIT;
-		else if (src->state < TCPS_ESTABLISHED ||
-		    dst->state < TCPS_ESTABLISHED)
-			(*state)->timeout = PFTM_TCP_OPENING;
-		else if (src->state >= TCPS_CLOSING ||
-		    dst->state >= TCPS_CLOSING)
-			(*state)->timeout = PFTM_TCP_CLOSING;
-		else
-			(*state)->timeout = PFTM_TCP_ESTABLISHED;
-
-		/* Fall through to PASS packet */
-
-	} else if ((dst->state < TCPS_SYN_SENT ||
-		dst->state >= TCPS_FIN_WAIT_2 ||
-		src->state >= TCPS_FIN_WAIT_2) &&
-	    SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
-	    /* Within a window forward of the originating packet */
-	    SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
-	    /* Within a window backward of the originating packet */
-
-		/*
-		 * This currently handles three situations:
-		 *  1) Stupid stacks will shotgun SYNs before their peer
-		 *     replies.
-		 *  2) When PF catches an already established stream (the
-		 *     firewall rebooted, the state table was flushed, routes
-		 *     changed...)
-		 *  3) Packets get funky immediately after the connection
-		 *     closes (this should catch Solaris spurious ACK|FINs
-		 *     that web servers like to spew after a close)
-		 *
-		 * This must be a little more careful than the above code
-		 * since packet floods will also be caught here. We don't
-		 * update the TTL here to mitigate the damage of a packet
-		 * flood and so the same code can handle awkward establishment
-		 * and a loosened connection close.
-		 * In the establishment case, a correct peer response will
-		 * validate the connection, go through the normal state code
-		 * and keep updating the state TTL.
-		 */
-
-		if (pf_status.debug >= PF_DEBUG_MISC) {
-			printf("pf: loose state match: ");
-			pf_print_state(*state);
-			pf_print_flags(th->th_flags);
-			printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
-			    "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len,
-#ifdef __FreeBSD__
-			    ackskew, (unsigned long long)(*state)->packets[0],
-			    (unsigned long long)(*state)->packets[1]);
-#else
-			    ackskew, (*state)->packets[0],
-			    (*state)->packets[1]);
-#endif
-		}
-
-		if (dst->scrub || src->scrub) {
-			if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
-			    *state, src, dst, ©back))
-				return (PF_DROP);
-		}
-
-		/* update max window */
-		if (src->max_win < win)
-			src->max_win = win;
-		/* synchronize sequencing */
-		if (SEQ_GT(end, src->seqlo))
-			src->seqlo = end;
-		/* slide the window of what the other end can send */
-		if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
-			dst->seqhi = ack + MAX((win << sws), 1);
-
-		/*
-		 * Cannot set dst->seqhi here since this could be a shotgunned
-		 * SYN and not an already established connection.
-		 */
-
-		if (th->th_flags & TH_FIN)
-			if (src->state < TCPS_CLOSING)
-				src->state = TCPS_CLOSING;
-		if (th->th_flags & TH_RST)
-			src->state = dst->state = TCPS_TIME_WAIT;
-
-		/* Fall through to PASS packet */
-
-	} else {
-		if ((*state)->dst.state == TCPS_SYN_SENT &&
-		    (*state)->src.state == TCPS_SYN_SENT) {
-			/* Send RST for state mismatches during handshake */
-			if (!(th->th_flags & TH_RST))
-#ifdef __FreeBSD__
-				pf_send_tcp(m, (*state)->rule.ptr, pd->af,
-#else
-				pf_send_tcp((*state)->rule.ptr, pd->af,
-#endif
-				    pd->dst, pd->src, th->th_dport,
-				    th->th_sport, ntohl(th->th_ack), 0,
-				    TH_RST, 0, 0,
-				    (*state)->rule.ptr->return_ttl, 1, 0,
-				    pd->eh, kif->pfik_ifp);
-			src->seqlo = 0;
-			src->seqhi = 1;
-			src->max_win = 1;
-		} else if (pf_status.debug >= PF_DEBUG_MISC) {
-			printf("pf: BAD state: ");
-			pf_print_state(*state);
-			pf_print_flags(th->th_flags);
-			printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
-			    "pkts=%llu:%llu dir=%s,%s\n",
-			    seq, orig_seq, ack, pd->p_len, ackskew,
-#ifdef __FreeBSD__
-			    (unsigned long long)(*state)->packets[0],
-			    (unsigned long long)(*state)->packets[1],
-#else
-			    (*state)->packets[0], (*state)->packets[1],
-#endif
-			    direction == PF_IN ? "in" : "out",
-			    direction == (*state)->direction ? "fwd" : "rev");
-			printf("pf: State failure on: %c %c %c %c | %c %c\n",
-			    SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
-			    SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
-			    ' ': '2',
-			    (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
-			    (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
-			    SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
-			    SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
-		}
-		REASON_SET(reason, PFRES_BADSTATE);
-		return (PF_DROP);
-	}
-
-	/* Any packets which have gotten here are to be passed */
-
 	/* translate source/destination address, if necessary */
 	if (STATE_TRANSLATE(*state)) {
 		if (direction == PF_OUT)
@@ -5533,8 +5650,9 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
 				copyback = 1;
 			}
 
-			if (!SEQ_GEQ(src->seqhi, seq) ||
-			    !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) {
+			if (!((*state)->state_flags & PFSTATE_SLOPPY) &&
+			    (!SEQ_GEQ(src->seqhi, seq) ||
+			    !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)))) {
 				if (pf_status.debug >= PF_DEBUG_MISC) {
 					printf("pf: BAD ICMP %d:%d ",
 					    icmptype, pd->hdr.icmp->icmp_code);
@@ -7052,7 +7170,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
 
 done:
 	if (action == PF_PASS && h->ip_hl > 5 &&
-	    !((s && s->allow_opts) || r->allow_opts)) {
+	    !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {
 		action = PF_DROP;
 		REASON_SET(&reason, PFRES_IPOPTIONS);
 		log = 1;
@@ -7513,7 +7631,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
 done:
 	/* handle dangerous IPv6 extension headers. */
 	if (action == PF_PASS && rh_cnt &&
-	    !((s && s->allow_opts) || r->allow_opts)) {
+	    !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {
 		action = PF_DROP;
 		REASON_SET(&reason, PFRES_IPOPTIONS);
 		log = 1;
diff --git a/sys/contrib/pf/net/pfvar.h b/sys/contrib/pf/net/pfvar.h
index 32e721c5733..de175b1a021 100644
--- a/sys/contrib/pf/net/pfvar.h
+++ b/sys/contrib/pf/net/pfvar.h
@@ -700,6 +700,7 @@ struct pf_rule {
 
 /* rule flags again */
 #define PFRULE_IFBOUND		0x00010000	/* if-bound */
+#define PFRULE_STATESLOPPY	0x00020000	/* sloppy state tracking */
 
 #define PFSTATE_HIWAT		10000	/* default state table size */
 #define PFSTATE_ADAPT_START	6000	/* default adaptive timeout start */
@@ -800,7 +801,9 @@ struct pf_state {
 	u_int8_t	 pad;
 #endif
 	u_int8_t	 log;
-	u_int8_t	 allow_opts;
+	u_int8_t	 state_flags;
+#define	PFSTATE_ALLOWOPTS	0x01
+#define	PFSTATE_SLOPPY		0x02
 	u_int8_t	 timeout;
 	u_int8_t	 sync_flags;
 #define	PFSTATE_NOSYNC	 0x01

From deacfb8431a4e72476c5148f40eb7d2c89292855 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sat, 23 Jan 2010 00:43:44 +0000
Subject: [PATCH 1274/2592] MFC r201892:

Add a set of manual pages for pthread[_attr]_[sg]etaffinity(3).

Reviewed by:	davidxu
---
 lib/libc/sys/cpuset.2                     |   6 +-
 lib/libc/sys/cpuset_getaffinity.2         |   6 +-
 share/man/man3/Makefile                   |   8 +-
 share/man/man3/pthread.3                  |   4 +-
 share/man/man3/pthread_affinity_np.3      | 157 ++++++++++++++++++++++
 share/man/man3/pthread_attr.3             |   4 +-
 share/man/man3/pthread_attr_affinity_np.3 | 150 +++++++++++++++++++++
 7 files changed, 327 insertions(+), 8 deletions(-)
 create mode 100644 share/man/man3/pthread_affinity_np.3
 create mode 100644 share/man/man3/pthread_attr_affinity_np.3

diff --git a/lib/libc/sys/cpuset.2 b/lib/libc/sys/cpuset.2
index fb9a7709cd2..1cdff680f0d 100644
--- a/lib/libc/sys/cpuset.2
+++ b/lib/libc/sys/cpuset.2
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 29, 2008
+.Dd January 8, 2010
 .Dt CPUSET 2
 .Os
 .Sh NAME
@@ -216,7 +216,9 @@ for allocation.
 .Xr cpuset 1 ,
 .Xr cpuset_getaffinity 2 ,
 .Xr cpuset_setaffinity 2 ,
-.Xr CPU_SET 3
+.Xr CPU_SET 3 ,
+.Xr pthread_affinity_np 3 ,
+.Xr pthread_attr_affinity_np 3
 .Sh HISTORY
 The
 .Nm
diff --git a/lib/libc/sys/cpuset_getaffinity.2 b/lib/libc/sys/cpuset_getaffinity.2
index b065ac362da..c8b272f0aef 100644
--- a/lib/libc/sys/cpuset_getaffinity.2
+++ b/lib/libc/sys/cpuset_getaffinity.2
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 29, 2008
+.Dd January 8, 2010
 .Dt CPUSET 2
 .Os
 .Sh NAME
@@ -147,7 +147,9 @@ operation.
 .Xr cpuset 2 ,
 .Xr cpuset_getid 2 ,
 .Xr cpuset_setid 2 ,
-.Xr CPU_SET 3
+.Xr CPU_SET 3 ,
+.Xr pthread_affinity_np 3 ,
+.Xr pthread_attr_affinity_np 3
 .Sh HISTORY
 The
 .Nm
diff --git a/share/man/man3/Makefile b/share/man/man3/Makefile
index d93a689b50c..ad176aa946e 100644
--- a/share/man/man3/Makefile
+++ b/share/man/man3/Makefile
@@ -155,8 +155,10 @@ MLINKS+=	tree.3 RB_EMPTY.3 \
 
 .if ${MK_LIBTHR} != "no"
 PTHREAD_MAN=	pthread.3 \
+		pthread_affinity_np.3 \
 		pthread_atfork.3 \
 		pthread_attr.3 \
+		pthread_attr_affinity_np.3 \
 		pthread_attr_get_np.3 \
 		pthread_attr_setcreatesuspend_np.3 \
 		pthread_barrierattr.3 \
@@ -218,7 +220,9 @@ PTHREAD_MAN=	pthread.3 \
 		pthread_testcancel.3 \
 		pthread_yield.3
 
-PTHREAD_MLINKS=	pthread_attr.3 pthread_attr_destroy.3 \
+PTHREAD_MLINKS=	pthread_affinity_np.3 pthread_getaffinity_np.3 \
+		pthread_affinity_np.3 pthread_setaffinity_np.3
+PTHREAD_MLINKS+=pthread_attr.3 pthread_attr_destroy.3 \
 		pthread_attr.3 pthread_attr_getdetachstate.3 \
 		pthread_attr.3 pthread_attr_getguardsize.3 \
 		pthread_attr.3 pthread_attr_getinheritsched.3 \
@@ -238,6 +242,8 @@ PTHREAD_MLINKS=	pthread_attr.3 pthread_attr_destroy.3 \
 		pthread_attr.3 pthread_attr_setstack.3 \
 		pthread_attr.3 pthread_attr_setstackaddr.3 \
 		pthread_attr.3 pthread_attr_setstacksize.3
+PTHREAD_MLINKS+=pthread_attr_affinity_np.3 pthread_attr_getaffinity_np.3 \
+		pthread_attr_affinity_np.3 pthread_attr_setaffinity_np.3
 PTHREAD_MLINKS+=pthread_barrierattr.3 pthread_barrierattr_destroy.3 \
 		pthread_barrierattr.3 pthread_barrierattr_getpshared.3 \
 		pthread_barrierattr.3 pthread_barrierattr_init.3 \
diff --git a/share/man/man3/pthread.3 b/share/man/man3/pthread.3
index 5fe2afdb0fa..caa7f7412e3 100644
--- a/share/man/man3/pthread.3
+++ b/share/man/man3/pthread.3
@@ -30,7 +30,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 1, 2009
+.Dd January 8, 2010
 .Dt PTHREAD 3
 .Os
 .Sh NAME
@@ -478,7 +478,9 @@ functions and the thread functions.
 Threaded applications are linked with this library.
 .Sh SEE ALSO
 .Xr libthr 3 ,
+.Xr pthread_affinity_np 3 ,
 .Xr pthread_atfork 3 ,
+.Xr pthread_attr 3 ,
 .Xr pthread_cancel 3 ,
 .Xr pthread_cleanup_pop 3 ,
 .Xr pthread_cleanup_push 3 ,
diff --git a/share/man/man3/pthread_affinity_np.3 b/share/man/man3/pthread_affinity_np.3
new file mode 100644
index 00000000000..b08720c3e9a
--- /dev/null
+++ b/share/man/man3/pthread_affinity_np.3
@@ -0,0 +1,157 @@
+.\"-
+.\" Copyright (c) 2010 Xin LI 
+.\" 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 January 8, 2010
+.Dt PTHREAD_AFFINITY_NP 3
+.Os
+.Sh NAME
+.Nm pthread_getaffinity_np ,
+.Nm pthread_setaffinity_np
+.Nd manage CPU affinity
+.Sh LIBRARY
+.Lb libpthread
+.Sh SYNOPSIS
+.In pthread_np.h
+.Ft int
+.Fn pthread_getaffinity_np "pthread_t td" "size_t cpusetsize" "cpuset_t *cpusetp"
+.Ft int
+.Fn pthread_setaffinity_np "pthread_t td" "size_t cpusetsize" "const cpuset_t *cpusetp"
+.Sh DESCRIPTION
+.Fn pthread_getaffinity_np
+and
+.Fn pthread_setaffinity_np
+allow the manipulation of sets of CPUs available to specified thread.
+.Pp
+Masks of type
+.Ft cpuset_t
+are composed using the
+.Xr CPU_SET 2
+macros.
+The kernel tolerates large sets as long as all CPUs specified
+in the set exist.
+Sets smaller than the kernel uses generate an error on calls to
+.Fn  pthread_getaffinity_np
+even if the result set would fit within the user supplied set.
+Calls to
+.Fn pthread_setaffinity_np
+tolerate small sets with no restrictions.
+.Pp
+The supplied mask should have a size of
+.Fa cpusetsize
+bytes.
+This size is usually provided by calling
+.Li sizeof(cpuset_t)
+which is ultimately determined by the value of
+.Dv CPU_SETSIZE
+as defined in
+.In sys/cpuset.h .
+.Pp
+.Fn pthread_getaffinity_np
+retrieves the
+mask from the thread specified by
+.Fa td ,
+and stores it in the space provided by
+.Fa cpumaskp .
+.Pp
+.Fn pthread_setaffinity_np
+attempts to set the mask for the thread specified by
+.Fa td
+to the value in
+.Fa cpumaskp .
+.Pp
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_getaffinity_np
+and
+.Fn pthread_setaffinity_np
+functions will return zero.
+Otherwise an error number will be returned
+to indicate the error.
+.Sh ERRORS
+The
+.Fn pthread_getaffinity_np
+and
+.Fn pthread_setaffinity_np
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EDEADLK
+The
+.Fn pthread_setaffinity_np
+call would leave a thread without a valid CPU to run on because the set
+does not overlap with the thread's anonymous mask.
+.It Bq Er EFAULT
+The
+.Fa cpumaskp
+pointer passed was invalid.
+.It Bq Er ESRCH
+The thread specified by the
+.Fa td
+argument could not be found.
+.It Bq Er ERANGE
+The
+.Fa cpusetsize
+was either preposterously large or smaller than the kernel set size.
+.It Bq Er EPERM
+The calling thread did not have the credentials required to complete the
+operation.
+.El
+.Sh SEE ALSO
+.Xr cpuset 1 ,
+.Xr cpuset 2 ,
+.Xr cpuset_getid 2 ,
+.Xr cpuset_setid 2 ,
+.Xr CPU_SET 3 ,
+.Xr pthread 3 ,
+.Xr pthread_attr_get_affinity_np 3 ,
+.Xr pthread_attr_set_affinity_np 3 .
+.Sh STANDARDS
+The
+.Nm pthread_getaffinity_np
+and
+.Nm pthread_setaffinity_np
+functions are non-standard
+.Fx
+extensions and may be not available on other operating systems.
+.Sh HISTORY
+The
+.Nm pthread_getaffinity_np
+and
+.Nm pthread_setaffinity_np
+function first appeared in
+.Fx 7.2 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm pthread_getaffinity_np
+and
+.Nm pthread_setaffinity_np
+functions were written by
+.An David Xu
+.Aq davidxu@FreeBSD.org ,
+and this manpage was written by
+.An Xin LI
+.Aq delphij@FreeBSD.org .
diff --git a/share/man/man3/pthread_attr.3 b/share/man/man3/pthread_attr.3
index 3253b176cf0..a99d32d626c 100644
--- a/share/man/man3/pthread_attr.3
+++ b/share/man/man3/pthread_attr.3
@@ -26,7 +26,7 @@
 .\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" $FreeBSD$
-.Dd April 28, 2000
+.Dd January 8, 2010
 .Dt PTHREAD_ATTR 3
 .Os
 .Sh NAME
@@ -209,9 +209,9 @@ Invalid or unsupported value for
 .El
 .Sh SEE ALSO
 .Xr pthread_attr_get_np 3 ,
+.Xr pthread_attr_affinity_np 3 ,
 .Xr pthread_create 3
 .Sh STANDARDS
-The
 .Fn pthread_attr_init ,
 .Fn pthread_attr_destroy ,
 .Fn pthread_attr_setstacksize ,
diff --git a/share/man/man3/pthread_attr_affinity_np.3 b/share/man/man3/pthread_attr_affinity_np.3
new file mode 100644
index 00000000000..ea3879183f9
--- /dev/null
+++ b/share/man/man3/pthread_attr_affinity_np.3
@@ -0,0 +1,150 @@
+.\"-
+.\" Copyright (c) 2010 Xin LI 
+.\" 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 January 8, 2010
+.Dt PTHREAD_ATTR_AFFINITY_NP 3
+.Os
+.Sh NAME
+.Nm pthread_attr_getaffinity_np ,
+.Nm pthread_attr_setaffinity_np
+.Nd manage CPU affinity in thread attribute object
+.Sh LIBRARY
+.Lb libpthread
+.Sh SYNOPSIS
+.In pthread_np.h
+.Ft int
+.Fn pthread_attr_getaffinity_np "const pthread_attr_t *pattr" "size_t cpusetsize" "cpuset_t *cpusetp"
+.Ft int
+.Fn pthread_attr_setaffinity_np "pthread_attr_t *pattr" "size_t cpusetsize" "const cpuset_t *cpusetp"
+.Sh DESCRIPTION
+.Fn pthread_attr_getaffinity_np
+and
+.Fn pthread_attr_setaffinity_np
+allow the manipulation of sets of CPUs available to specified thread attribute object.
+.Pp
+Masks of type
+.Ft cpuset_t
+are composed using the
+.Xr CPU_SET 2
+macros.
+The kernel tolerates large sets as long as all CPUs specified
+in the set exist.
+Sets smaller than the kernel uses generate an error on calls to
+.Fn  pthread_attr_getaffinity_np
+even if the result set would fit within the user supplied set.
+Calls to
+.Fn pthread_attr_setaffinity_np
+tolerate small sets with no restrictions.
+.Pp
+The supplied mask should have a size of
+.Fa cpusetsize
+bytes.
+This size is usually provided by calling
+.Li sizeof(cpuset_t)
+which is ultimately determined by the value of
+.Dv CPU_SETSIZE
+as defined in
+.In sys/cpuset.h .
+.Pp
+.Fn pthread_attr_getaffinity_np
+retrieves the
+mask from the thread attribute object specified by
+.Fa pattr ,
+and stores it in the space provided by
+.Fa cpumaskp .
+.Pp
+.Fn pthread_attr_setaffinity_np
+set the mask for the thread attribute object specified by
+.Fa pattr
+to the value in
+.Fa cpumaskp .
+.Pp
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_attr_getaffinity_np
+and
+.Fn pthread_attr_setaffinity_np
+functions will return zero.
+Otherwise an error number will be returned
+to indicate the error.
+.Sh ERRORS
+The
+.Fn pthread_attr_getaffinity_np
+and
+.Fn pthread_attr_setaffinity_np
+functions will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa pattr
+or the attribute specified by it is NULL.
+.El
+.Pp
+The
+.Fn pthread_attr_setaffinity_np
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa pattr
+or the attribute specified by it is NULL.
+.It Bq Er ENOMEM
+Insufficient memory exists to store the cpuset mask.
+.El
+.Sh SEE ALSO
+.Xr cpuset 1 ,
+.Xr cpuset 2 ,
+.Xr cpuset_getid 2 ,
+.Xr cpuset_setid 2 ,
+.Xr CPU_SET 3 ,
+.Xr pthread_get_affinity_np 3 ,
+.Xr pthread_set_affinity_np 3 .
+.Sh STANDARDS
+The
+.Nm pthread_attr_getaffinity_np
+and
+.Nm pthread_attr_setaffinity_np
+functions are non-standard
+.Fx
+extensions and may be not available on other operating systems.
+.Sh HISTORY
+The
+.Nm pthread_attr_getaffinity_np
+and
+.Nm pthread_attr_setaffinity_np
+functions first appeared in
+.Fx 7.2 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm pthread_attr_getaffinity_np
+and
+.Nm pthread_attr_setaffinity_np
+functions were written by
+.An David Xu Aq davidxu@FreeBSD.org ,
+and this manpage was written by
+.An Xin LI Aq delphij@FreeBSD.org .

From 7d230b5cebf87dd5fd6e6cd0391acb8dde5143d3 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sat, 23 Jan 2010 00:49:10 +0000
Subject: [PATCH 1275/2592] MFC r201894:

Fix formatting.
---
 share/man/man4/uart.4 | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/share/man/man4/uart.4 b/share/man/man4/uart.4
index be9d70031d5..7bd4732f013 100644
--- a/share/man/man4/uart.4
+++ b/share/man/man4/uart.4
@@ -28,11 +28,9 @@
 .Dd March 12, 2008
 .Dt UART 4
 .Os
-.\"
 .Sh NAME
 .Nm uart
 .Nd driver for Universal Asynchronous Receiver/Transmitter (UART) devices
-.\"
 .Sh SYNOPSIS
 .Cd "device uart"
 .Pp
@@ -42,7 +40,6 @@
 .Cd "device scc"
 .Cd "device uart"
 .Pp
-.Bd -ragged offset -compact
 In
 .Pa /boot/device.hints :
 .Cd hint.uart.0.disabled="1"

From aa0cab05173af275978dd31f695b623550dfe932 Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sat, 23 Jan 2010 00:52:32 +0000
Subject: [PATCH 1276/2592] MFC r202709:

Give the right value when complaining it being wrong.

Reported by:	danfe
---
 usr.sbin/burncd/burncd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/usr.sbin/burncd/burncd.c b/usr.sbin/burncd/burncd.c
index 2931cf819bc..43a0a09f1cb 100644
--- a/usr.sbin/burncd/burncd.c
+++ b/usr.sbin/burncd/burncd.c
@@ -151,7 +151,7 @@ main(int argc, char **argv)
 	else
 		speed = atoi(env_speed) * 177;
 	if (speed <= 0)
-		errx(EX_USAGE, "Invalid speed: %s", optarg);
+		errx(EX_USAGE, "Invalid speed: %s", env_speed);
 
 	if (argc == 0)
 		usage();

From 11ad45c9ce52ff738d503b23e75a32044126eb0b Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Sat, 23 Jan 2010 01:25:09 +0000
Subject: [PATCH 1277/2592] MFC r202268:

 o Add PCI ID for BCM 5756.
 o Don't enable BGE_FLAG_BER_BUG on both 5722 and 5756, and based
   on their PCI IDs rather than their chip IDs.

Reported by:    several PC-BSD users via kmoore
Reviewed by:    yongari, imp, jhb, davidch
Sponsored by:   iXsystems, Inc.
---
 sys/dev/bge/if_bge.c    | 4 +++-
 sys/dev/bge/if_bgereg.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 8eeb149beb2..4d8f3f48293 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -187,6 +187,7 @@ static const struct bge_type {
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5754M },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5755 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5755M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5756 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5761 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5761E },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5761S },
@@ -2612,7 +2613,8 @@ bge_attach(device_t dev)
 		    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)
+			if (pci_get_device(dev) != BCOM_DEVICEID_BCM5722 &&
+			    pci_get_device(dev) != BCOM_DEVICEID_BCM5756)
 				sc->bge_flags |= BGE_FLAG_JITTER_BUG;
 		} else if (sc->bge_asicrev != BGE_ASICREV_BCM5906)
 			sc->bge_flags |= BGE_FLAG_BER_BUG;
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index 23a97093202..e7388bf9f96 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -2138,6 +2138,7 @@ struct bge_status_block {
 #define	BCOM_DEVICEID_BCM5754M		0x1672
 #define	BCOM_DEVICEID_BCM5755		0x167B
 #define	BCOM_DEVICEID_BCM5755M		0x1673
+#define	BCOM_DEVICEID_BCM5756		0x1674
 #define	BCOM_DEVICEID_BCM5761		0x1681
 #define	BCOM_DEVICEID_BCM5761E		0x1680
 #define	BCOM_DEVICEID_BCM5761S		0x1688

From 5a183eb8e4f771ea535c2af98dc195e3ee1de86c Mon Sep 17 00:00:00 2001
From: Marcel Moolenaar 
Date: Sat, 23 Jan 2010 06:29:34 +0000
Subject: [PATCH 1278/2592] MFC rev 202552: Add command-line option -dev to set
 the default value of the currdev variable.

---
 sys/boot/ia64/efi/main.c  | 71 +++++++++++++++++++++++++++++++--------
 sys/boot/ia64/efi/version |  1 +
 2 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/sys/boot/ia64/efi/main.c b/sys/boot/ia64/efi/main.c
index c9bb547c437..3f0b07123bb 100644
--- a/sys/boot/ia64/efi/main.c
+++ b/sys/boot/ia64/efi/main.c
@@ -50,7 +50,6 @@ extern char bootprog_rev[];
 extern char bootprog_date[];
 extern char bootprog_maker[];
 
-struct devdesc currdev;		/* our current device */
 struct arch_switch archsw;	/* MI/MD interface boundary */
 
 extern u_int64_t	ia64_pal_entry;
@@ -101,10 +100,49 @@ find_pal_proc(void)
 	return;
 }
 
+static int
+usc2cmp(CHAR16 *s1, CHAR16 *s2)
+{
+
+	while (*s1 == *s2++) {
+		if (*s1++ == 0)
+			return (0);
+	}
+	return (*s1 - *(s2 - 1));
+}
+
+static char *
+get_dev_option(int argc, CHAR16 *argv[])
+{
+	static char dev[32];
+	CHAR16 *arg;
+	char *devp;
+	int i, j;
+
+	devp = NULL;
+	for (i = 0; i < argc; i++) {
+		if (usc2cmp(argv[i], L"-dev") == 0 && i < argc - 1) {
+			arg = argv[i + 1];
+			j = 0;
+			while (j < sizeof(dev) && *arg != 0)
+				dev[j++] = *arg++;
+			if (j == sizeof(dev))
+				j--;
+			dev[j] = '\0';
+			devp = dev;
+			break;
+		}
+	}
+
+	return (devp);
+}
+
 EFI_STATUS
 main(int argc, CHAR16 *argv[])
 {
+	struct devdesc currdev;
 	EFI_LOADED_IMAGE *img;
+	char *dev;
 	int i;
 
 	/* 
@@ -115,6 +153,10 @@ main(int argc, CHAR16 *argv[])
 	 */
 	cons_probe();
 
+	printf("\n");
+	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+
 	find_pal_proc();
 
 	/*
@@ -124,16 +166,6 @@ main(int argc, CHAR16 *argv[])
 		if (devsw[i]->dv_init != NULL)
 			(devsw[i]->dv_init)();
 
-	/* Get our loaded image protocol interface structure. */
-	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
-
-	printf("\n");
-	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
-	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
-
-	efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
-	currdev.d_type = currdev.d_dev->dv_type;
-
 	/*
 	 * Disable the watchdog timer. By default the boot manager sets
 	 * the timer to 5 minutes before invoking a boot option. If we
@@ -145,13 +177,24 @@ main(int argc, CHAR16 *argv[])
 	 */
 	BS->SetWatchdogTimer(0, 0, 0, NULL);
 
-	env_setenv("currdev", EV_VOLATILE, ia64_fmtdev(&currdev),
-	    ia64_setcurrdev, env_nounset);
+	/* Get our loaded image protocol interface structure. */
+	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
+
+	bzero(&currdev, sizeof(currdev));
+	efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
+	currdev.d_type = currdev.d_dev->dv_type;
+
 	env_setenv("loaddev", EV_VOLATILE, ia64_fmtdev(&currdev), env_noset,
 	    env_nounset);
 
+	dev = get_dev_option(argc, argv);
+	if (dev == NULL)
+		dev = ia64_fmtdev(&currdev);
+
+	env_setenv("currdev", EV_VOLATILE, dev, ia64_setcurrdev, env_nounset);
+
 	setenv("LINES", "24", 1);	/* optional */
-    
+
 	archsw.arch_autoload = ia64_autoload;
 	archsw.arch_getdev = ia64_getdev;
 	archsw.arch_copyin = ia64_copyin;
diff --git a/sys/boot/ia64/efi/version b/sys/boot/ia64/efi/version
index 37a71c39e99..148ed4c5980 100644
--- a/sys/boot/ia64/efi/version
+++ b/sys/boot/ia64/efi/version
@@ -3,6 +3,7 @@ $FreeBSD$
 NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
 file is important.  Make sure the current version number is on line 6.
 
+2.1:	Add support for "-dev " argument parsing.
 2.0:	Provide devices based on the block I/O protocol, rather than the
 	simple file services protocol. Use the FreeBSD file system code
 	on top of those devices to access files.

From c78cb5e4f148453f0dacee95eae52594680737e1 Mon Sep 17 00:00:00 2001
From: Navdeep Parhar 
Date: Sat, 23 Jan 2010 08:37:04 +0000
Subject: [PATCH 1279/2592] MFC r202863

Don't forget to release the adapter lock for a no-op.
---
 sys/dev/cxgb/cxgb_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c
index eeb61d40b01..59e7fec8eed 100644
--- a/sys/dev/cxgb/cxgb_main.c
+++ b/sys/dev/cxgb/cxgb_main.c
@@ -2078,6 +2078,8 @@ fail:
 			p->if_flags = ifp->if_flags;
 		} else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 			error = cxgb_uninit_locked(p);
+		else
+			ADAPTER_UNLOCK(sc);
 
 		ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
 		break;

From 9a1203308836b97594c95c0900baafcc6f8e7d5c Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Sat, 23 Jan 2010 14:12:40 +0000
Subject: [PATCH 1280/2592] MFC: r202162

Various fixes.
---
 share/man/man3/pthread_affinity_np.3      | 17 ++++++++--------
 share/man/man3/pthread_attr_affinity_np.3 | 24 ++++++++++++-----------
 2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/share/man/man3/pthread_affinity_np.3 b/share/man/man3/pthread_affinity_np.3
index b08720c3e9a..a04ba97b483 100644
--- a/share/man/man3/pthread_affinity_np.3
+++ b/share/man/man3/pthread_affinity_np.3
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 8, 2010
+.Dd January 12, 2010
 .Dt PTHREAD_AFFINITY_NP 3
 .Os
 .Sh NAME
@@ -44,17 +44,17 @@
 .Fn pthread_getaffinity_np
 and
 .Fn pthread_setaffinity_np
-allow the manipulation of sets of CPUs available to specified thread.
+allow the manipulation of sets of CPUs available to the specified thread.
 .Pp
 Masks of type
 .Ft cpuset_t
 are composed using the
-.Xr CPU_SET 2
+.Xr CPU_SET 3
 macros.
 The kernel tolerates large sets as long as all CPUs specified
 in the set exist.
 Sets smaller than the kernel uses generate an error on calls to
-.Fn  pthread_getaffinity_np
+.Fn pthread_getaffinity_np
 even if the result set would fit within the user supplied set.
 Calls to
 .Fn pthread_setaffinity_np
@@ -75,14 +75,13 @@ retrieves the
 mask from the thread specified by
 .Fa td ,
 and stores it in the space provided by
-.Fa cpumaskp .
+.Fa cpusetp .
 .Pp
 .Fn pthread_setaffinity_np
 attempts to set the mask for the thread specified by
 .Fa td
 to the value in
-.Fa cpumaskp .
-.Pp
+.Fa cpusetp .
 .Sh RETURN VALUES
 If successful, the
 .Fn pthread_getaffinity_np
@@ -105,7 +104,7 @@ call would leave a thread without a valid CPU to run on because the set
 does not overlap with the thread's anonymous mask.
 .It Bq Er EFAULT
 The
-.Fa cpumaskp
+.Fa cpusetp
 pointer passed was invalid.
 .It Bq Er ESRCH
 The thread specified by the
@@ -127,7 +126,7 @@ operation.
 .Xr CPU_SET 3 ,
 .Xr pthread 3 ,
 .Xr pthread_attr_get_affinity_np 3 ,
-.Xr pthread_attr_set_affinity_np 3 .
+.Xr pthread_attr_set_affinity_np 3
 .Sh STANDARDS
 The
 .Nm pthread_getaffinity_np
diff --git a/share/man/man3/pthread_attr_affinity_np.3 b/share/man/man3/pthread_attr_affinity_np.3
index ea3879183f9..c61f69988fb 100644
--- a/share/man/man3/pthread_attr_affinity_np.3
+++ b/share/man/man3/pthread_attr_affinity_np.3
@@ -31,7 +31,7 @@
 .Sh NAME
 .Nm pthread_attr_getaffinity_np ,
 .Nm pthread_attr_setaffinity_np
-.Nd manage CPU affinity in thread attribute object
+.Nd manage CPU affinity in thread attribute objects
 .Sh LIBRARY
 .Lb libpthread
 .Sh SYNOPSIS
@@ -41,20 +41,21 @@
 .Ft int
 .Fn pthread_attr_setaffinity_np "pthread_attr_t *pattr" "size_t cpusetsize" "const cpuset_t *cpusetp"
 .Sh DESCRIPTION
+The
 .Fn pthread_attr_getaffinity_np
 and
 .Fn pthread_attr_setaffinity_np
-allow the manipulation of sets of CPUs available to specified thread attribute object.
+functions allow the manipulation of sets of CPUs available to the specified thread attribute object.
 .Pp
 Masks of type
 .Ft cpuset_t
 are composed using the
-.Xr CPU_SET 2
+.Xr CPU_SET 3
 macros.
 The kernel tolerates large sets as long as all CPUs specified
 in the set exist.
 Sets smaller than the kernel uses generate an error on calls to
-.Fn  pthread_attr_getaffinity_np
+.Fn pthread_attr_getaffinity_np
 even if the result set would fit within the user supplied set.
 Calls to
 .Fn pthread_attr_setaffinity_np
@@ -75,14 +76,13 @@ retrieves the
 mask from the thread attribute object specified by
 .Fa pattr ,
 and stores it in the space provided by
-.Fa cpumaskp .
+.Fa cpusetp .
 .Pp
 .Fn pthread_attr_setaffinity_np
-set the mask for the thread attribute object specified by
+sets the mask for the thread attribute object specified by
 .Fa pattr
 to the value in
-.Fa cpumaskp .
-.Pp
+.Fa cpusetp .
 .Sh RETURN VALUES
 If successful, the
 .Fn pthread_attr_getaffinity_np
@@ -101,7 +101,8 @@ functions will fail if:
 .It Bq Er EINVAL
 The
 .Fa pattr
-or the attribute specified by it is NULL.
+or the attribute specified by it is
+.Dv NULL .
 .El
 .Pp
 The
@@ -111,7 +112,8 @@ function will fail if:
 .It Bq Er EINVAL
 The
 .Fa pattr
-or the attribute specified by it is NULL.
+or the attribute specified by it is
+.Dv NULL .
 .It Bq Er ENOMEM
 Insufficient memory exists to store the cpuset mask.
 .El
@@ -122,7 +124,7 @@ Insufficient memory exists to store the cpuset mask.
 .Xr cpuset_setid 2 ,
 .Xr CPU_SET 3 ,
 .Xr pthread_get_affinity_np 3 ,
-.Xr pthread_set_affinity_np 3 .
+.Xr pthread_set_affinity_np 3
 .Sh STANDARDS
 The
 .Nm pthread_attr_getaffinity_np

From c79d8f1fb50d55631442b9b1ddf27c51b46e32ba Mon Sep 17 00:00:00 2001
From: Robert Noland 
Date: Sat, 23 Jan 2010 16:29:04 +0000
Subject: [PATCH 1281/2592] MFC r200764

Fix a handful of issues with via agp support.

  * Read the pci capability register to identify AGP 3 support
  * Add missing smaller aperture sizes for AGP3 chips.
  * Fix the aperture size calculation on AGP2 chips.
    All sizes between 32M and 256M reported as 256M.
  * Add \n to error string.
---
 sys/dev/agp/agp_via.c | 56 +++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 32 deletions(-)

diff --git a/sys/dev/agp/agp_via.c b/sys/dev/agp/agp_via.c
index 76ce382488b..c561513b1d4 100644
--- a/sys/dev/agp/agp_via.c
+++ b/sys/dev/agp/agp_via.c
@@ -165,39 +165,16 @@ agp_via_attach(device_t dev)
 	struct agp_gatt *gatt;
 	int error;
 	u_int32_t agpsel;
+	u_int32_t capid;
 
-	/* XXX: This should be keying off of whether the bridge is AGP3 capable,
-	 * rather than a bunch of device ids for chipsets that happen to do 8x.
-	 */
-	switch (pci_get_devid(dev)) {
-	case 0x01981106:
-	case 0x02591106:
-	case 0x02691106:
-	case 0x02961106:
-	case 0x03141106:
-	case 0x03241106:
-	case 0x03271106:
-	case 0x03641106:
-	case 0x31231106:
-	case 0x31681106:
-	case 0x31891106:
-	case 0x32051106:
-	case 0x32581106:
-	case 0xb1981106:
-		/* The newer VIA chipsets will select the AGP version based on
-		 * what AGP versions the card supports.  We still have to
-		 * program it using the v2 registers if it has chosen to use
-		 * compatibility mode.
-		 */
+	sc->regs = via_v2_regs;
+
+	/* Look at the capability register to see if we handle AGP3 */
+	capid = pci_read_config(dev, agp_find_caps(dev) + AGP_CAPID, 4);
+	if (((capid >> 20) & 0x0f) >= 3) { 
 		agpsel = pci_read_config(dev, AGP_VIA_AGPSEL, 1);
 		if ((agpsel & (1 << 1)) == 0)
 			sc->regs = via_v3_regs;
-		else
-			sc->regs = via_v2_regs;
-		break;
-	default:
-		sc->regs = via_v2_regs;
-		break;
 	}
 	
 	error = agp_generic_attach(dev);
@@ -235,7 +212,7 @@ agp_via_attach(device_t dev)
 		pci_write_config(dev, sc->regs[REG_ATTBASE], gatt->ag_physical, 4);
 		
 		/* Enable the aperture. */
-		gartctrl = pci_read_config(dev, sc->regs[REG_ATTBASE], 4);
+		gartctrl = pci_read_config(dev, sc->regs[REG_GARTCTRL], 4);
 		pci_write_config(dev, sc->regs[REG_GARTCTRL], gartctrl | (3 << 7), 4);
 	}
 
@@ -268,7 +245,7 @@ agp_via_get_aperture(device_t dev)
 	u_int32_t apsize;
 
 	if (sc->regs == via_v2_regs) {
-		apsize = pci_read_config(dev, sc->regs[REG_APSIZE], 1) & 0x1f;
+		apsize = pci_read_config(dev, sc->regs[REG_APSIZE], 1);
 
 		/*
 		 * The size is determined by the number of low bits of
@@ -295,8 +272,14 @@ agp_via_get_aperture(device_t dev)
 			return 0x04000000;
 		case 0xf38:
 			return 0x02000000;
+		case 0xf3c:
+			return 0x01000000;
+		case 0xf3e:
+			return 0x00800000;
+		case 0xf3f:
+			return 0x00400000;
 		default:
-			device_printf(dev, "Invalid aperture setting 0x%x",
+			device_printf(dev, "Invalid aperture setting 0x%x\n",
 			    pci_read_config(dev, sc->regs[REG_APSIZE], 2));
 			return 0;
 		}
@@ -345,6 +328,15 @@ agp_via_set_aperture(device_t dev, u_int32_t aperture)
 		case 0x02000000:
 			key = 0xf38;
 			break;
+		case 0x01000000:
+			key = 0xf3c;
+			break;
+		case 0x00800000:
+			key = 0xf3e;
+			break;
+		case 0x00400000:
+			key = 0xf3f;
+			break;
 		default:
 			device_printf(dev, "Invalid aperture size (%dMb)\n",
 			    aperture / 1024 / 1024);

From 3bcceea40e03305fc48c713e91b839f6048cab29 Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Sat, 23 Jan 2010 16:40:35 +0000
Subject: [PATCH 1282/2592] MFC r202468:

  Add ip4.saddrsel/ip4.nosaddrsel (and equivalent for ip6) to control
  whether to use source address selection (default) or the primary
  jail address for unbound outgoing connections.

  This is intended to be used by people upgrading from single-IP
  jails to multi-IP jails but not having to change firewall rules,
  application ACLs, ... but to force their connections (unless
  otherwise changed) to the primry jail IP they had been used for
  years, as well as for people prefering to implement similar policies.

  Note that for IPv6, if configured incorrectly, this might lead to
  scope violations, which single-IPv6 jails could as well, as by the
  design of jails. [1]

  Reviewed by:		jamie, hrs (ipv6 part)
  Pointed out by:	hrs [1]
---
 sys/kern/kern_jail.c   | 110 ++++++++++++++++++++++++++++++++++++++++-
 sys/netinet/in_pcb.c   |   7 +++
 sys/netinet6/in6_src.c |   7 +++
 sys/sys/jail.h         |   6 +++
 usr.sbin/jail/jail.8   |  16 ++++--
 5 files changed, 140 insertions(+), 6 deletions(-)

diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index c3c2568da7d..01a57f9324a 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -77,6 +77,21 @@ __FBSDID("$FreeBSD$");
 
 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
 
+/* Keep struct prison prison0 and some code in kern_jail_set() readable. */
+#ifdef INET
+#ifdef INET6
+#define	_PR_IP_SADDRSEL	PR_IP4_SADDRSEL|PR_IP6_SADDRSEL
+#else
+#define	_PR_IP_SADDRSEL	PR_IP4_SADDRSEL
+#endif
+#else /* !INET */
+#ifdef INET6
+#define	_PR_IP_SADDRSEL	PR_IP6_SADDRSEL
+#else
+#define	_PR_IP_SADDRSEL	0
+#endif
+#endif
+
 /* prison0 describes what is "real" about the system. */
 struct prison prison0 = {
 	.pr_id		= 0,
@@ -89,9 +104,9 @@ struct prison prison0 = {
 	.pr_hostuuid	= DEFAULT_HOSTUUID,
 	.pr_children	= LIST_HEAD_INITIALIZER(&prison0.pr_children),
 #ifdef VIMAGE
-	.pr_flags	= PR_HOST|PR_VNET,
+	.pr_flags	= PR_HOST|PR_VNET|_PR_IP_SADDRSEL,
 #else
-	.pr_flags	= PR_HOST,
+	.pr_flags	= PR_HOST|_PR_IP_SADDRSEL,
 #endif
 	.pr_allow	= PR_ALLOW_ALL,
 };
@@ -129,10 +144,22 @@ static int prison_restrict_ip6(struct prison *pr, struct in6_addr *newip6);
  */
 static char *pr_flag_names[] = {
 	[0] = "persist",
+#ifdef INET
+	[7] = "ip4.saddrsel",
+#endif
+#ifdef INET6
+	[8] = "ip6.saddrsel",
+#endif
 };
 
 static char *pr_flag_nonames[] = {
 	[0] = "nopersist",
+#ifdef INET
+	[7] = "ip4.nosaddrsel",
+#endif
+#ifdef INET6
+	[8] = "ip6.nosaddrsel",
+#endif
 };
 
 struct jailsys_flags {
@@ -1199,6 +1226,9 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
 #endif
 		}
 #endif
+		/* Source address selection is always on by default. */
+		pr->pr_flags |= _PR_IP_SADDRSEL;
+
 		pr->pr_securelevel = ppr->pr_securelevel;
 		pr->pr_allow = JAIL_DEFAULT_ALLOW & ppr->pr_allow;
 		pr->pr_enforce_statfs = JAIL_DEFAULT_ENFORCE_STATFS;
@@ -2658,6 +2688,41 @@ prison_get_ip4(struct ucred *cred, struct in_addr *ia)
 	return (0);
 }
 
+/*
+ * Return 1 if we should do proper source address selection or are not jailed.
+ * We will return 0 if we should bypass source address selection in favour
+ * of the primary jail IPv4 address. Only in this case *ia will be updated and
+ * returned in NBO.
+ * Return EAFNOSUPPORT, in case this jail does not allow IPv4.
+ */
+int
+prison_saddrsel_ip4(struct ucred *cred, struct in_addr *ia)
+{
+	struct prison *pr;
+	struct in_addr lia;
+	int error;
+
+	KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
+	KASSERT(ia != NULL, ("%s: ia is NULL", __func__));
+
+	if (!jailed(cred))
+		return (1);
+
+	pr = cred->cr_prison;
+	if (pr->pr_flags & PR_IP4_SADDRSEL)
+		return (1);
+
+	lia.s_addr = INADDR_ANY;
+	error = prison_get_ip4(cred, &lia);
+	if (error)
+		return (error);
+	if (lia.s_addr == INADDR_ANY)
+		return (1);
+
+	ia->s_addr = lia.s_addr;
+	return (0);
+}
+
 /*
  * Return true if pr1 and pr2 have the same IPv4 address restrictions.
  */
@@ -2963,6 +3028,41 @@ prison_get_ip6(struct ucred *cred, struct in6_addr *ia6)
 	return (0);
 }
 
+/*
+ * Return 1 if we should do proper source address selection or are not jailed.
+ * We will return 0 if we should bypass source address selection in favour
+ * of the primary jail IPv6 address. Only in this case *ia will be updated and
+ * returned in NBO.
+ * Return EAFNOSUPPORT, in case this jail does not allow IPv6.
+ */
+int
+prison_saddrsel_ip6(struct ucred *cred, struct in6_addr *ia6)
+{
+	struct prison *pr;
+	struct in6_addr lia6;
+	int error;
+
+	KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
+	KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__));
+
+	if (!jailed(cred))
+		return (1);
+
+	pr = cred->cr_prison;
+	if (pr->pr_flags & PR_IP6_SADDRSEL)
+		return (1);
+
+	lia6 = in6addr_any;
+	error = prison_get_ip6(cred, &lia6);
+	if (error)
+		return (error);
+	if (IN6_IS_ADDR_UNSPECIFIED(&lia6))
+		return (1);
+
+	bcopy(&lia6, ia6, sizeof(struct in6_addr));
+	return (0);
+}
+
 /*
  * Return true if pr1 and pr2 have the same IPv6 address restrictions.
  */
@@ -4116,12 +4216,18 @@ SYSCTL_JAIL_PARAM_SYS_NODE(ip4, CTLFLAG_RDTUN,
     "Jail IPv4 address virtualization");
 SYSCTL_JAIL_PARAM_STRUCT(_ip4, addr, CTLFLAG_RW, sizeof(struct in_addr),
     "S,in_addr,a", "Jail IPv4 addresses");
+SYSCTL_JAIL_PARAM(_ip4, saddrsel, CTLTYPE_INT | CTLFLAG_RW,
+    "B", "Do (not) use IPv4 source address selection rather than the "
+    "primary jail IPv4 address.");
 #endif
 #ifdef INET6
 SYSCTL_JAIL_PARAM_SYS_NODE(ip6, CTLFLAG_RDTUN,
     "Jail IPv6 address virtualization");
 SYSCTL_JAIL_PARAM_STRUCT(_ip6, addr, CTLFLAG_RW, sizeof(struct in6_addr),
     "S,in6_addr,a", "Jail IPv6 addresses");
+SYSCTL_JAIL_PARAM(_ip6, saddrsel, CTLTYPE_INT | CTLFLAG_RW,
+    "B", "Do (not) use IPv6 source address selection rather than the "
+    "primary jail IPv6 address.");
 #endif
 
 SYSCTL_JAIL_PARAM_NODE(allow, "Jail permission flags");
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 7a4ac10ad63..204d90453bd 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -552,6 +552,13 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
 
 	KASSERT(laddr != NULL, ("%s: laddr NULL", __func__));
 
+	/*
+	 * Bypass source address selection and use the primary jail IP
+	 * if requested.
+	 */
+	if (cred != NULL && !prison_saddrsel_ip4(cred, laddr))
+		return (0);
+
 	error = 0;
 	bzero(&sro, sizeof(sro));
 
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index 8e82ef117ae..ea302a52fa4 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -270,6 +270,13 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
 		return (0);
 	}
 
+	/*
+	 * Bypass source address selection and use the primary jail IP
+	 * if requested.
+	 */
+	if (cred != NULL && !prison_saddrsel_ip6(cred, srcp))
+		return (0);
+
 	/*
 	 * If the address is not specified, choose the best one based on
 	 * the outgoing interface and the destination address.
diff --git a/sys/sys/jail.h b/sys/sys/jail.h
index 2c5d1787786..d7a0622f3cd 100644
--- a/sys/sys/jail.h
+++ b/sys/sys/jail.h
@@ -191,6 +191,10 @@ struct prison {
 #define	PR_VNET		0x00000010	/* Virtual network stack */
 #define	PR_IP4_DISABLE	0x00000020	/* Disable IPv4 */
 #define	PR_IP6_DISABLE	0x00000040	/* Disable IPv6 */
+#define	PR_IP4_SADDRSEL	0x00000080	/* Do IPv4 src addr sel. or use the */
+					/* primary jail address. */
+#define	PR_IP6_SADDRSEL	0x00000100	/* Do IPv6 src addr sel. or use the */
+					/* primary jail address. */
 
 /* Internal flag bits */
 #define	PR_REMOVE	0x01000000	/* In process of being removed */
@@ -362,12 +366,14 @@ int prison_get_ip4(struct ucred *cred, struct in_addr *ia);
 int prison_local_ip4(struct ucred *cred, struct in_addr *ia);
 int prison_remote_ip4(struct ucred *cred, struct in_addr *ia);
 int prison_check_ip4(struct ucred *cred, struct in_addr *ia);
+int prison_saddrsel_ip4(struct ucred *, struct in_addr *);
 #ifdef INET6
 int prison_equal_ip6(struct prison *, struct prison *);
 int prison_get_ip6(struct ucred *, struct in6_addr *);
 int prison_local_ip6(struct ucred *, struct in6_addr *, int);
 int prison_remote_ip6(struct ucred *, struct in6_addr *);
 int prison_check_ip6(struct ucred *, struct in6_addr *);
+int prison_saddrsel_ip6(struct ucred *, struct in6_addr *);
 #endif
 int prison_check_af(struct ucred *cred, int af);
 int prison_if(struct ucred *cred, struct sockaddr *sa);
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index 4c1a963a7b0..f09157f4308 100644
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -34,7 +34,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 18, 2009
+.Dd January 17, 2010
 .Dt JAIL 8
 .Os
 .Sh NAME
@@ -252,6 +252,13 @@ match.
 It is only possible to start multiple jails with the same IP address,
 if none of the jails has more than this single overlapping IP address
 assigned to itself.
+.It Va ip4.saddrsel
+A boolean option to change the formerly mentioned behaviour and disable
+IPv4 source address selection for the prison in favour of the primary
+IPv4 address of the jail.
+Source address selection is enabled by default for all jails and a
+.Va ip4.nosaddrsel
+setting of a parent jail is not inherited for any child jails.
 .It Va ip4
 Control the availablity of IPv4 addresses.
 Possible values are
@@ -267,9 +274,10 @@ Setting the
 .Va ip4.addr
 parameter implies a value of
 .Dq new .
-.It Va ip6.addr , Va ip6
-A list of IPv6 addresses assigned to the prison, the counterpart to
-.Va ip4.addr
+.It Va ip6.addr , Va ip6.saddrsel , Va ip6
+A set of IPv6 options for the prison, the counterparts to
+.Va ip4.addr ,
+.Va ip4.saddrsel
 and
 .Va ip4
 above.

From 3dd81e030682132b1201276574545be0c920e8fd Mon Sep 17 00:00:00 2001
From: Max Khon 
Date: Sun, 24 Jan 2010 08:59:33 +0000
Subject: [PATCH 1283/2592] MFC: Send link state change control messages to
 "orphans" hook as well.

---
 sys/netgraph/ng_ether.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c
index fab06226610..dc38d4157db 100644
--- a/sys/netgraph/ng_ether.c
+++ b/sys/netgraph/ng_ether.c
@@ -359,9 +359,6 @@ ng_ether_link_state(struct ifnet *ifp, int state)
 	struct ng_mesg *msg;
 	int cmd, dummy_error = 0;
 
-	if (priv->lower == NULL)
-                return;
-
 	if (state == LINK_STATE_UP)
 		cmd = NGM_LINK_IS_UP;
 	else if (state == LINK_STATE_DOWN)
@@ -369,9 +366,16 @@ ng_ether_link_state(struct ifnet *ifp, int state)
 	else
 		return;
 
-	NG_MKMESSAGE(msg, NGM_FLOW_COOKIE, cmd, 0, M_NOWAIT);
-	if (msg != NULL)
-		NG_SEND_MSG_HOOK(dummy_error, node, msg, priv->lower, 0);
+	if (priv->lower != NULL) {
+		NG_MKMESSAGE(msg, NGM_FLOW_COOKIE, cmd, 0, M_NOWAIT);
+		if (msg != NULL)
+			NG_SEND_MSG_HOOK(dummy_error, node, msg, priv->lower, 0);
+	}
+	if (priv->orphan != NULL) {
+		NG_MKMESSAGE(msg, NGM_FLOW_COOKIE, cmd, 0, M_NOWAIT);
+		if (msg != NULL)
+			NG_SEND_MSG_HOOK(dummy_error, node, msg, priv->orphan, 0);
+	}
 }
 
 /******************************************************************

From be6797dde88efc84055db6a0661ab512eeabe8a5 Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Sun, 24 Jan 2010 12:22:38 +0000
Subject: [PATCH 1284/2592] MFC r202469:   Garbage collect references to the no
 longer implemented tcp_fasttimo().

---
 sys/netinet/tcp_var.h    | 1 -
 sys/netinet6/in6_proto.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 96353f3df53..4d426943fd4 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -639,7 +639,6 @@ int	 tcp_ctloutput(struct socket *, struct sockopt *);
 struct tcpcb *
 	 tcp_drop(struct tcpcb *, int);
 void	 tcp_drain(void);
-void	 tcp_fasttimo(void);
 void	 tcp_init(void);
 #ifdef VIMAGE
 void	 tcp_destroy(void);
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index c31743f0f66..40acb1e38b9 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -173,7 +173,6 @@ struct ip6protosw inet6sw[] = {
 	.pr_ctloutput =		tcp_ctloutput,
 #ifndef INET	/* don't call initialization and timeout routines twice */
 	.pr_init =		tcp_init,
-	.pr_fasttimo =		tcp_fasttimo,
 	.pr_slowtimo =		tcp_slowtimo,
 #endif
 	.pr_drain =		tcp_drain,

From b3c4be736e48225b08b699ae9200e585441a8d5e Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sun, 24 Jan 2010 12:35:36 +0000
Subject: [PATCH 1285/2592] Merge scandir(3) interface update to stable/8.

MFC r201512:
Modernize scandir(3) and alphasort(3) interfaces according to the IEEE
Std 1003.1-2008.

MFC r201602:
Move scandir(3) and alphasort(3) into XSI namespace.

MFC r201604:
Use thunks to adapt alphasort-like interface to the comparision function
required by qsort() and qsort_r().

MFC r202556 (by ache):
Use strcoll() in opendir() and alphasort(). Remove some comments.

MFC r202572 (by ache):
Revert to using strcmp() for opendir().

MFC r202677 (by ache):
Style.

MFC r202679 (by ache):
Style: rename internal function to opendir_compar().

MFC r202691 (by ache):
For alphasort(3) add reference to strcoll(3).

MFC r202693 (by ache):
Style: reword comment.
---
 include/dirent.h                   |  9 +++++---
 lib/libc/gen/opendir.c             | 11 +++++++++-
 lib/libc/gen/scandir.3             | 13 ++++++-----
 lib/libc/gen/scandir.c             | 35 +++++++++++++++++++-----------
 usr.bin/catman/catman.c            | 10 +++++++--
 usr.bin/makewhatis/makewhatis.c    |  4 ++--
 usr.sbin/lpr/common_source/lp.h    |  2 +-
 usr.sbin/lpr/common_source/rmjob.c |  2 +-
 8 files changed, 57 insertions(+), 29 deletions(-)

diff --git a/include/dirent.h b/include/dirent.h
index 63626b59bc7..375a3d2301b 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -93,9 +93,11 @@ typedef	void *	DIR;
 #ifndef _KERNEL
 
 __BEGIN_DECLS
+#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE >= 700
+int	 alphasort(const struct dirent **, const struct dirent **);
+#endif
 #if __BSD_VISIBLE
 DIR	*__opendir2(const char *, int);
-int	 alphasort(const void *, const void *);
 int	 getdents(int, char *, int);
 int	 getdirentries(int, char *, int, long *);
 #endif
@@ -107,9 +109,10 @@ struct dirent *
 int	 readdir_r(DIR *, struct dirent *, struct dirent **);
 #endif
 void	 rewinddir(DIR *);
-#if __BSD_VISIBLE
+#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE >= 700
 int	 scandir(const char *, struct dirent ***,
-	    int (*)(struct dirent *), int (*)(const void *, const void *));
+	    int (*)(const struct dirent *), int (*)(const struct dirent **,
+	    const struct dirent **));
 #endif
 #if __XSI_VISIBLE
 void	 seekdir(DIR *, long);
diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c
index 9625ec69094..b312c89d76a 100644
--- a/lib/libc/gen/opendir.c
+++ b/lib/libc/gen/opendir.c
@@ -92,6 +92,14 @@ __opendir2(const char *name, int flags)
 	return __opendir_common(fd, name, flags);
 }
 
+static int
+opendir_compar(const void *p1, const void *p2)
+{
+
+	return (strcmp((*(const struct dirent **)p1)->d_name,
+	    (*(const struct dirent **)p2)->d_name));
+}
+
 /*
  * Common routine for opendir(3), __opendir2(3) and fdopendir(3).
  */
@@ -240,7 +248,8 @@ __opendir_common(int fd, const char *name, int flags)
 				/*
 				 * This sort must be stable.
 				 */
-				mergesort(dpv, n, sizeof(*dpv), alphasort);
+				mergesort(dpv, n, sizeof(*dpv),
+				    opendir_compar);
 
 				dpv[n] = NULL;
 				xp = NULL;
diff --git a/lib/libc/gen/scandir.3 b/lib/libc/gen/scandir.3
index 42ccac2465c..e32b0d819e8 100644
--- a/lib/libc/gen/scandir.3
+++ b/lib/libc/gen/scandir.3
@@ -28,7 +28,7 @@
 .\"     @(#)scandir.3	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd June 4, 1993
+.Dd January 3, 2010
 .Dt SCANDIR 3
 .Os
 .Sh NAME
@@ -38,12 +38,11 @@
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
-.In sys/types.h
 .In dirent.h
 .Ft int
-.Fn scandir "const char *dirname" "struct dirent ***namelist" "int \\*(lp*select\\*(rp\\*(lpstruct dirent *\\*(rp" "int \\*(lp*compar\\*(rp\\*(lpconst void *, const void *\\*(rp"
+.Fn scandir "const char *dirname" "struct dirent ***namelist" "int \\*(lp*select\\*(rp\\*(lpconst struct dirent *\\*(rp" "int \\*(lp*compar\\*(rp\\*(lpconst struct dirent **, const struct dirent **\\*(rp"
 .Ft int
-.Fn alphasort "const void *d1" "const void *d2"
+.Fn alphasort "const struct dirent **d1" "const struct dirent **d2"
 .Sh DESCRIPTION
 The
 .Fn scandir
@@ -82,7 +81,8 @@ The
 function
 is a routine which can be used for the
 .Fa compar
-argument to sort the array alphabetically.
+argument to sort the array alphabetically using
+.Xr strcoll 3 .
 .Pp
 The memory allocated for the array can be deallocated with
 .Xr free 3 ,
@@ -95,7 +95,8 @@ cannot allocate enough memory to hold all the data structures.
 .Xr directory 3 ,
 .Xr malloc 3 ,
 .Xr qsort 3 ,
-.Xr dir 5
+.Xr dir 5 ,
+.Xr strcoll 3
 .Sh HISTORY
 The
 .Fn scandir
diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c
index 1dae85d12a9..93bc8523c90 100644
--- a/lib/libc/gen/scandir.c
+++ b/lib/libc/gen/scandir.c
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
 #include 
 #include "un-namespace.h"
 
+static int alphasort_thunk(void *thunk, const void *p1, const void *p2);
+
 /*
  * The DIRSIZ macro is the minimum record length which will hold the directory
  * entry.  This requires the amount of space in struct dirent without the
@@ -58,11 +60,9 @@ __FBSDID("$FreeBSD$");
 	    (((dp)->d_namlen + 1 + 3) &~ 3))
 
 int
-scandir(dirname, namelist, select, dcomp)
-	const char *dirname;
-	struct dirent ***namelist;
-	int (*select)(struct dirent *);
-	int (*dcomp)(const void *, const void *);
+scandir(const char *dirname, struct dirent ***namelist,
+    int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **,
+	const struct dirent **))
 {
 	struct dirent *d, *p, **names = NULL;
 	size_t nitems = 0;
@@ -111,26 +111,35 @@ scandir(dirname, namelist, select, dcomp)
 	}
 	closedir(dirp);
 	if (nitems && dcomp != NULL)
-		qsort(names, nitems, sizeof(struct dirent *), dcomp);
+		qsort_r(names, nitems, sizeof(struct dirent *),
+		    &dcomp, alphasort_thunk);
 	*namelist = names;
-	return(nitems);
+	return (nitems);
 
 fail:
 	while (nitems > 0)
 		free(names[--nitems]);
 	free(names);
 	closedir(dirp);
-	return -1;
+	return (-1);
 }
 
 /*
  * Alphabetic order comparison routine for those who want it.
+ * POSIX 2008 requires that alphasort() uses strcoll().
  */
 int
-alphasort(d1, d2)
-	const void *d1;
-	const void *d2;
+alphasort(const struct dirent **d1, const struct dirent **d2)
 {
-	return(strcmp((*(struct dirent **)d1)->d_name,
-	    (*(struct dirent **)d2)->d_name));
+
+	return (strcoll((*d1)->d_name, (*d2)->d_name));
+}
+
+static int
+alphasort_thunk(void *thunk, const void *p1, const void *p2)
+{
+	int (*dc)(const struct dirent **, const struct dirent **);
+
+	dc = *(int (**)(const struct dirent **, const struct dirent **))thunk;
+	return (dc((const struct dirent **)p1, (const struct dirent **)p2));
 }
diff --git a/usr.bin/catman/catman.c b/usr.bin/catman/catman.c
index ba3ad248a2c..c17a091593c 100644
--- a/usr.bin/catman/catman.c
+++ b/usr.bin/catman/catman.c
@@ -589,9 +589,15 @@ process_section(char *mandir, char *section)
 }
 
 static int
-select_sections(struct dirent *entry)
+select_sections(const struct dirent *entry)
 {
-	return directory_type(entry->d_name) == MAN_SECTION_DIR;
+	char *name;
+	int ret;
+
+	name = strdup(entry->d_name);
+	ret = directory_type(name) == MAN_SECTION_DIR;
+	free(name);
+	return (ret);
 }
 
 /*
diff --git a/usr.bin/makewhatis/makewhatis.c b/usr.bin/makewhatis/makewhatis.c
index 6b2dce4e595..f2ae3709d6d 100644
--- a/usr.bin/makewhatis/makewhatis.c
+++ b/usr.bin/makewhatis/makewhatis.c
@@ -879,9 +879,9 @@ process_section(char *section_dir)
  * Returns whether the directory entry is a man page section.
  */
 static int
-select_sections(struct dirent *entry)
+select_sections(const struct dirent *entry)
 {
-	char *p = &entry->d_name[3];
+	const char *p = &entry->d_name[3];
 
 	if (strncmp(entry->d_name, "man", 3) != 0)
 		return 0;
diff --git a/usr.sbin/lpr/common_source/lp.h b/usr.sbin/lpr/common_source/lp.h
index 891ed2f1bda..63f2ff1a477 100644
--- a/usr.sbin/lpr/common_source/lp.h
+++ b/usr.sbin/lpr/common_source/lp.h
@@ -280,7 +280,7 @@ void	 inform(const struct printer *_pp, char *_cf);
 void	 init_printer(struct printer *_pp);
 void	 init_request(struct request *_rp);
 int	 inlist(char *_uname, char *_cfile);
-int	 iscf(struct dirent *_d);
+int	 iscf(const struct dirent *_d);
 void	 ldump(const char *_nfile, const char *_datafile, int _copies);
 void	 lastprinter(void);
 int	 lockchk(struct printer *_pp, char *_slockf);
diff --git a/usr.sbin/lpr/common_source/rmjob.c b/usr.sbin/lpr/common_source/rmjob.c
index d6fd6148ccd..33fcdacc4da 100644
--- a/usr.sbin/lpr/common_source/rmjob.c
+++ b/usr.sbin/lpr/common_source/rmjob.c
@@ -384,7 +384,7 @@ rmremote(const struct printer *pp)
  * Return 1 if the filename begins with 'cf'
  */
 int
-iscf(struct dirent *d)
+iscf(const struct dirent *d)
 {
 	return(d->d_name[0] == 'c' && d->d_name[1] == 'f');
 }

From 2af4053ea7948a4c885e88de893379a4b02f8450 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sun, 24 Jan 2010 12:37:30 +0000
Subject: [PATCH 1286/2592] Bump __FreeBSD_version for scandir(3) and
 alphasort(3) interface changes.

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

diff --git a/sys/sys/param.h b/sys/sys/param.h
index d3ee0677c2a..f52eee618c2 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 800500	/* Master, propagated to newvers */
+#define __FreeBSD_version 800501	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include 

From eb63bf5c833bb930c7998a47bd5c8363e02c122f Mon Sep 17 00:00:00 2001
From: Ed Schouten 
Date: Sun, 24 Jan 2010 14:30:57 +0000
Subject: [PATCH 1287/2592] MFC r202500:

  Fix a regression that was introduced in r191882.

  I changed login_tty() to only work when the application is not a session
  leader yet. This works fine for applications in the base system, but it
  turns out various applications call this function after daemonizing,
  which means they already use their own session.

  If setsid() fails, just call tcsetsid() on the current session.
  tcsetsid() will already perform proper security checks.

Reported by:	Oliver Lehmann
---
 lib/libutil/login_tty.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libutil/login_tty.c b/lib/libutil/login_tty.c
index a14e244e45a..92dc87fe710 100644
--- a/lib/libutil/login_tty.c
+++ b/lib/libutil/login_tty.c
@@ -50,7 +50,7 @@ login_tty(int fd)
 
 	s = setsid();
 	if (s == -1)
-		return (-1);
+		s = getsid(0);
 	if (tcsetsid(fd, s) == -1)
 		return (-1);
 	(void) dup2(fd, 0);

From 903d5593ab0ce02ab5a829ed98fae5c704b37c29 Mon Sep 17 00:00:00 2001
From: David Schultz 
Date: Sun, 24 Jan 2010 20:15:59 +0000
Subject: [PATCH 1288/2592] MFC r197752:

  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.
---
 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 7ac856b829073d2716fa6f170c34ce19ed5e7eaa Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Sun, 24 Jan 2010 22:01:04 +0000
Subject: [PATCH 1289/2592] Merge r202000 from head:

  Don't panic on attach if we can't allocate ifp

Approved by:	ed (mentor, implicit)
---
 sys/dev/ae/if_ae.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/ae/if_ae.c b/sys/dev/ae/if_ae.c
index d3e95ef1eb8..68181f4b6d4 100644
--- a/sys/dev/ae/if_ae.c
+++ b/sys/dev/ae/if_ae.c
@@ -367,6 +367,7 @@ ae_attach(device_t dev)
 	if (ifp == NULL) {
 		device_printf(dev, "could not allocate ifnet structure.\n");
 		error = ENXIO;
+		goto fail;
 	}
 
 	ifp->if_softc = sc;

From b93b253dc62fdfe001199bd18c61c394b19d02ce Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Sun, 24 Jan 2010 22:17:08 +0000
Subject: [PATCH 1290/2592] MFC 202449:

Get rid of support of an old version of the SCTP-AUTH draft.
Get rid of unused MD5 code.
---
 sys/netinet/sctp_auth.c   | 499 +-------------------------------------
 sys/netinet/sctp_auth.h   |   6 -
 sys/netinet/sctp_os_bsd.h |   6 -
 sys/netinet/sctp_output.c |   8 -
 sys/netinet/sctp_pcb.c    |  17 +-
 sys/netinet/sctp_uio.h    |   1 -
 6 files changed, 2 insertions(+), 535 deletions(-)

diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c
index 5e8c51890fe..928f572cbe2 100644
--- a/sys/netinet/sctp_auth.c
+++ b/sys/netinet/sctp_auth.c
@@ -456,21 +456,6 @@ sctp_compute_hashkey(sctp_key_t * key1, sctp_key_t * key2, sctp_key_t * shared)
 
 	/* concatenate the keys */
 	if (sctp_compare_key(key1, key2) <= 0) {
-#ifdef SCTP_AUTH_DRAFT_04
-		/* key is key1 + shared + key2 */
-		if (sctp_get_keylen(key1)) {
-			bcopy(key1->key, key_ptr, key1->keylen);
-			key_ptr += key1->keylen;
-		}
-		if (sctp_get_keylen(shared)) {
-			bcopy(shared->key, key_ptr, shared->keylen);
-			key_ptr += shared->keylen;
-		}
-		if (sctp_get_keylen(key2)) {
-			bcopy(key2->key, key_ptr, key2->keylen);
-			key_ptr += key2->keylen;
-		}
-#else
 		/* key is shared + key1 + key2 */
 		if (sctp_get_keylen(shared)) {
 			bcopy(shared->key, key_ptr, shared->keylen);
@@ -484,23 +469,7 @@ sctp_compute_hashkey(sctp_key_t * key1, sctp_key_t * key2, sctp_key_t * shared)
 			bcopy(key2->key, key_ptr, key2->keylen);
 			key_ptr += key2->keylen;
 		}
-#endif
 	} else {
-#ifdef SCTP_AUTH_DRAFT_04
-		/* key is key2 + shared + key1 */
-		if (sctp_get_keylen(key2)) {
-			bcopy(key2->key, key_ptr, key2->keylen);
-			key_ptr += key2->keylen;
-		}
-		if (sctp_get_keylen(shared)) {
-			bcopy(shared->key, key_ptr, shared->keylen);
-			key_ptr += shared->keylen;
-		}
-		if (sctp_get_keylen(key1)) {
-			bcopy(key1->key, key_ptr, key1->keylen);
-			key_ptr += key1->keylen;
-		}
-#else
 		/* key is shared + key2 + key1 */
 		if (sctp_get_keylen(shared)) {
 			bcopy(shared->key, key_ptr, shared->keylen);
@@ -514,7 +483,6 @@ sctp_compute_hashkey(sctp_key_t * key1, sctp_key_t * key2, sctp_key_t * shared)
 			bcopy(key1->key, key_ptr, key1->keylen);
 			key_ptr += key1->keylen;
 		}
-#endif
 	}
 	return (new_key);
 }
@@ -739,7 +707,7 @@ sctp_auth_add_hmacid(sctp_hmaclist_t * list, uint16_t hmac_id)
 	    (hmac_id != SCTP_AUTH_HMAC_ID_SHA384) &&
 	    (hmac_id != SCTP_AUTH_HMAC_ID_SHA512) &&
 #endif
-	    (hmac_id != SCTP_AUTH_HMAC_ID_MD5)) {
+	    1) {
 		return (-1);
 	}
 	/* Now is it already in the list */
@@ -802,12 +770,6 @@ sctp_negotiate_hmacid(sctp_hmaclist_t * peer, sctp_hmaclist_t * local)
 	for (i = 0; i < peer->num_algo; i++) {
 		for (j = 0; j < local->num_algo; j++) {
 			if (peer->hmac[i] == local->hmac[j]) {
-#ifndef SCTP_AUTH_DRAFT_04
-				/* "skip" MD5 as it's been deprecated */
-				if (peer->hmac[i] == SCTP_AUTH_HMAC_ID_MD5)
-					continue;
-#endif
-
 				/* found the "best" one */
 				SCTPDBG(SCTP_DEBUG_AUTH1,
 				    "SCTP: negotiated peer HMAC id %u\n",
@@ -911,8 +873,6 @@ sctp_get_hmac_digest_len(uint16_t hmac_algo)
 	switch (hmac_algo) {
 	case SCTP_AUTH_HMAC_ID_SHA1:
 		return (SCTP_AUTH_DIGEST_LEN_SHA1);
-	case SCTP_AUTH_HMAC_ID_MD5:
-		return (SCTP_AUTH_DIGEST_LEN_MD5);
 #ifdef HAVE_SHA224
 	case SCTP_AUTH_HMAC_ID_SHA224:
 		return (SCTP_AUTH_DIGEST_LEN_SHA224);
@@ -936,7 +896,6 @@ sctp_get_hmac_block_len(uint16_t hmac_algo)
 {
 	switch (hmac_algo) {
 		case SCTP_AUTH_HMAC_ID_SHA1:
-		case SCTP_AUTH_HMAC_ID_MD5:
 #ifdef HAVE_SHA224
 		case SCTP_AUTH_HMAC_ID_SHA224:
 #endif
@@ -962,9 +921,6 @@ sctp_hmac_init(uint16_t hmac_algo, sctp_hash_context_t * ctx)
 		case SCTP_AUTH_HMAC_ID_SHA1:
 		SHA1_Init(&ctx->sha1);
 		break;
-	case SCTP_AUTH_HMAC_ID_MD5:
-		MD5_Init(&ctx->md5);
-		break;
 #ifdef HAVE_SHA224
 	case SCTP_AUTH_HMAC_ID_SHA224:
 		break;
@@ -995,9 +951,6 @@ sctp_hmac_update(uint16_t hmac_algo, sctp_hash_context_t * ctx,
 		case SCTP_AUTH_HMAC_ID_SHA1:
 		SHA1_Update(&ctx->sha1, text, textlen);
 		break;
-	case SCTP_AUTH_HMAC_ID_MD5:
-		MD5_Update(&ctx->md5, text, textlen);
-		break;
 #ifdef HAVE_SHA224
 	case SCTP_AUTH_HMAC_ID_SHA224:
 		break;
@@ -1028,9 +981,6 @@ sctp_hmac_final(uint16_t hmac_algo, sctp_hash_context_t * ctx,
 		case SCTP_AUTH_HMAC_ID_SHA1:
 		SHA1_Final(digest, &ctx->sha1);
 		break;
-	case SCTP_AUTH_HMAC_ID_MD5:
-		MD5_Final(digest, &ctx->md5);
-		break;
 #ifdef HAVE_SHA224
 	case SCTP_AUTH_HMAC_ID_SHA224:
 		break;
@@ -1636,15 +1586,6 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
 		    (uint8_t *) & tmp_param);
 	}
 	/* concatenate the full random key */
-#ifdef SCTP_AUTH_DRAFT_04
-	keylen = random_len;
-	new_key = sctp_alloc_key(keylen);
-	if (new_key != NULL) {
-		/* copy in the RANDOM */
-		if (p_random != NULL)
-			bcopy(p_random->random_data, new_key->key, random_len);
-	}
-#else
 	keylen = sizeof(*p_random) + random_len + sizeof(*hmacs) + hmacs_len;
 	if (chunks != NULL) {
 		keylen += sizeof(*chunks) + num_chunks;
@@ -1668,15 +1609,10 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
 			    sizeof(*hmacs) + hmacs_len);
 		}
 	}
-#endif
 	if (stcb->asoc.authinfo.random != NULL)
 		sctp_free_key(stcb->asoc.authinfo.random);
 	stcb->asoc.authinfo.random = new_key;
 	stcb->asoc.authinfo.random_len = random_len;
-#ifdef SCTP_AUTH_DRAFT_04
-	/* don't include the chunks and hmacs for draft -04 */
-	stcb->asoc.authinfo.random->keylen = random_len;
-#endif
 	sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid);
 	sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.recv_keyid);
 
@@ -2143,11 +2079,6 @@ sctp_initialize_auth_params(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
 	    &stcb->asoc.shared_keys);
 
 	/* now set the concatenated key (random + chunks + hmacs) */
-#ifdef SCTP_AUTH_DRAFT_04
-	/* don't include the chunks and hmacs for draft -04 */
-	keylen = random_len;
-	new_key = sctp_generate_random_key(keylen);
-#else
 	/* key includes parameter headers */
 	keylen = (3 * sizeof(struct sctp_paramhdr)) + random_len + chunks_len +
 	    hmacs_len;
@@ -2188,436 +2119,8 @@ sctp_initialize_auth_params(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
 		(void)sctp_serialize_hmaclist(stcb->asoc.local_hmacs,
 		    new_key->key + keylen);
 	}
-#endif
 	if (stcb->asoc.authinfo.random != NULL)
 		sctp_free_key(stcb->asoc.authinfo.random);
 	stcb->asoc.authinfo.random = new_key;
 	stcb->asoc.authinfo.random_len = random_len;
 }
-
-
-#ifdef SCTP_HMAC_TEST
-/*
- * HMAC and key concatenation tests
- */
-static void
-sctp_print_digest(uint8_t * digest, uint32_t digestlen, const char *str)
-{
-	uint32_t i;
-
-	printf("\n%s: 0x", str);
-	if (digest == NULL)
-		return;
-
-	for (i = 0; i < digestlen; i++)
-		printf("%02x", digest[i]);
-}
-
-static int
-sctp_test_hmac(const char *str, uint16_t hmac_id, uint8_t * key,
-    uint32_t keylen, uint8_t * text, uint32_t textlen,
-    uint8_t * digest, uint32_t digestlen)
-{
-	uint8_t computed_digest[SCTP_AUTH_DIGEST_LEN_MAX];
-
-	printf("\n%s:", str);
-	sctp_hmac(hmac_id, key, keylen, text, textlen, computed_digest);
-	sctp_print_digest(digest, digestlen, "Expected digest");
-	sctp_print_digest(computed_digest, digestlen, "Computed digest");
-	if (memcmp(digest, computed_digest, digestlen) != 0) {
-		printf("\nFAILED");
-		return (-1);
-	} else {
-		printf("\nPASSED");
-		return (0);
-	}
-}
-
-
-/*
- * RFC 2202: HMAC-SHA1 test cases
- */
-void
-sctp_test_hmac_sha1(void)
-{
-	uint8_t *digest;
-	uint8_t key[128];
-	uint32_t keylen;
-	uint8_t text[128];
-	uint32_t textlen;
-	uint32_t digestlen = 20;
-	int failed = 0;
-
-	/*-
-	 * test_case =     1
-	 * key =           0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-	 * key_len =       20
-	 * data =          "Hi There"
-	 * data_len =      8
-	 * digest =        0xb617318655057264e28bc0b6fb378c8ef146be00
-	 */
-	keylen = 20;
-	memset(key, 0x0b, keylen);
-	textlen = 8;
-	strcpy(text, "Hi There");
-	digest = "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00";
-	if (sctp_test_hmac("SHA1 test case 1", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     2
-	 * key =           "Jefe"
-	 * key_len =       4
-	 * data =          "what do ya want for nothing?"
-	 * data_len =      28
-	 * digest =        0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79
-	 */
-	keylen = 4;
-	strcpy(key, "Jefe");
-	textlen = 28;
-	strcpy(text, "what do ya want for nothing?");
-	digest = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79";
-	if (sctp_test_hmac("SHA1 test case 2", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     3
-	 * key =           0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-	 * key_len =       20
-	 * data =          0xdd repeated 50 times
-	 * data_len =      50
-	 * digest =        0x125d7342b9ac11cd91a39af48aa17b4f63f175d3
-	 */
-	keylen = 20;
-	memset(key, 0xaa, keylen);
-	textlen = 50;
-	memset(text, 0xdd, textlen);
-	digest = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3";
-	if (sctp_test_hmac("SHA1 test case 3", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     4
-	 * key =           0x0102030405060708090a0b0c0d0e0f10111213141516171819
-	 * key_len =       25
-	 * data =          0xcd repeated 50 times
-	 * data_len =      50
-	 * digest =        0x4c9007f4026250c6bc8414f9bf50c86c2d7235da
-	 */
-	keylen = 25;
-	memcpy(key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", keylen);
-	textlen = 50;
-	memset(text, 0xcd, textlen);
-	digest = "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda";
-	if (sctp_test_hmac("SHA1 test case 4", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     5
-	 * key =           0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
-	 * key_len =       20
-	 * data =          "Test With Truncation"
-	 * data_len =      20
-	 * digest =        0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04
-	 * digest-96 =     0x4c1a03424b55e07fe7f27be1
-	 */
-	keylen = 20;
-	memset(key, 0x0c, keylen);
-	textlen = 20;
-	strcpy(text, "Test With Truncation");
-	digest = "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04";
-	if (sctp_test_hmac("SHA1 test case 5", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     6
-	 * key =           0xaa repeated 80 times
-	 * key_len =       80
-	 * data =          "Test Using Larger Than Block-Size Key - Hash Key First"
-	 * data_len =      54
-	 * digest =        0xaa4ae5e15272d00e95705637ce8a3b55ed402112
-	 */
-	keylen = 80;
-	memset(key, 0xaa, keylen);
-	textlen = 54;
-	strcpy(text, "Test Using Larger Than Block-Size Key - Hash Key First");
-	digest = "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12";
-	if (sctp_test_hmac("SHA1 test case 6", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     7
-	 * key =           0xaa repeated 80 times
-	 * key_len =       80
-	 * data =          "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
-	 * data_len =      73
-	 * digest =        0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91
-	 */
-	keylen = 80;
-	memset(key, 0xaa, keylen);
-	textlen = 73;
-	strcpy(text, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data");
-	digest = "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91";
-	if (sctp_test_hmac("SHA1 test case 7", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/* done with all tests */
-	if (failed)
-		printf("\nSHA1 test results: %d cases failed", failed);
-	else
-		printf("\nSHA1 test results: all test cases passed");
-}
-
-/*
- * RFC 2202: HMAC-MD5 test cases
- */
-void
-sctp_test_hmac_md5(void)
-{
-	uint8_t *digest;
-	uint8_t key[128];
-	uint32_t keylen;
-	uint8_t text[128];
-	uint32_t textlen;
-	uint32_t digestlen = 16;
-	int failed = 0;
-
-	/*-
-	 * test_case =     1
-	 * key =           0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-	 * key_len =       16
-	 * data =          "Hi There"
-	 * data_len =      8
-	 * digest =        0x9294727a3638bb1c13f48ef8158bfc9d
-	 */
-	keylen = 16;
-	memset(key, 0x0b, keylen);
-	textlen = 8;
-	strcpy(text, "Hi There");
-	digest = "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d";
-	if (sctp_test_hmac("MD5 test case 1", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     2
-	 * key =           "Jefe"
-	 * key_len =       4
-	 * data =          "what do ya want for nothing?"
-	 * data_len =      28
-	 * digest =        0x750c783e6ab0b503eaa86e310a5db738
-	 */
-	keylen = 4;
-	strcpy(key, "Jefe");
-	textlen = 28;
-	strcpy(text, "what do ya want for nothing?");
-	digest = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
-	if (sctp_test_hmac("MD5 test case 2", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     3
-	 * key =           0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-	 * key_len =       16
-	 * data =          0xdd repeated 50 times
-	 * data_len =	   50
-	 * digest =        0x56be34521d144c88dbb8c733f0e8b3f6
-	 */
-	keylen = 16;
-	memset(key, 0xaa, keylen);
-	textlen = 50;
-	memset(text, 0xdd, textlen);
-	digest = "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6";
-	if (sctp_test_hmac("MD5 test case 3", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     4
-	 * key =           0x0102030405060708090a0b0c0d0e0f10111213141516171819
-	 * key_len =       25
-	 * data =          0xcd repeated 50 times
-	 * data_len =      50
-	 * digest =        0x697eaf0aca3a3aea3a75164746ffaa79
-	 */
-	keylen = 25;
-	memcpy(key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", keylen);
-	textlen = 50;
-	memset(text, 0xcd, textlen);
-	digest = "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79";
-	if (sctp_test_hmac("MD5 test case 4", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     5
-	 * key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
-	 * key_len =       16
-	 * data =          "Test With Truncation"
-	 * data_len =      20
-	 * digest =        0x56461ef2342edc00f9bab995690efd4c
-	 * digest-96 =     0x56461ef2342edc00f9bab995
-	 */
-	keylen = 16;
-	memset(key, 0x0c, keylen);
-	textlen = 20;
-	strcpy(text, "Test With Truncation");
-	digest = "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c";
-	if (sctp_test_hmac("MD5 test case 5", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     6
-	 * key =           0xaa repeated 80 times
-	 * key_len =       80
-	 * data =          "Test Using Larger Than Block-Size Key - Hash Key First"
-	 * data_len =      54
-	 * digest =        0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd
-	 */
-	keylen = 80;
-	memset(key, 0xaa, keylen);
-	textlen = 54;
-	strcpy(text, "Test Using Larger Than Block-Size Key - Hash Key First");
-	digest = "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd";
-	if (sctp_test_hmac("MD5 test case 6", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/*-
-	 * test_case =     7
-	 * key =           0xaa repeated 80 times
-	 * key_len =       80
-	 * data =          "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
-	 * data_len =      73
-	 * digest =        0x6f630fad67cda0ee1fb1f562db3aa53e
-	 */
-	keylen = 80;
-	memset(key, 0xaa, keylen);
-	textlen = 73;
-	strcpy(text, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data");
-	digest = "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e";
-	if (sctp_test_hmac("MD5 test case 7", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
-	    text, textlen, digest, digestlen) < 0)
-		failed++;
-
-	/* done with all tests */
-	if (failed)
-		printf("\nMD5 test results: %d cases failed", failed);
-	else
-		printf("\nMD5 test results: all test cases passed");
-}
-
-/*
- * test assoc key concatenation
- */
-static int
-sctp_test_key_concatenation(sctp_key_t * key1, sctp_key_t * key2,
-    sctp_key_t * expected_key)
-{
-	sctp_key_t *key;
-	int ret_val;
-
-	sctp_show_key(key1, "\nkey1");
-	sctp_show_key(key2, "\nkey2");
-	key = sctp_compute_hashkey(key1, key2, NULL);
-	sctp_show_key(expected_key, "\nExpected");
-	sctp_show_key(key, "\nComputed");
-	if (memcmp(key, expected_key, expected_key->keylen) != 0) {
-		printf("\nFAILED");
-		ret_val = -1;
-	} else {
-		printf("\nPASSED");
-		ret_val = 0;
-	}
-	sctp_free_key(key1);
-	sctp_free_key(key2);
-	sctp_free_key(expected_key);
-	sctp_free_key(key);
-	return (ret_val);
-}
-
-
-void
-sctp_test_authkey(void)
-{
-	sctp_key_t *key1, *key2, *expected_key;
-	int failed = 0;
-
-	/* test case 1 */
-	key1 = sctp_set_key("\x01\x01\x01\x01", 4);
-	key2 = sctp_set_key("\x01\x02\x03\x04", 4);
-	expected_key = sctp_set_key("\x01\x01\x01\x01\x01\x02\x03\x04", 8);
-	if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
-		failed++;
-
-	/* test case 2 */
-	key1 = sctp_set_key("\x00\x00\x00\x01", 4);
-	key2 = sctp_set_key("\x02", 1);
-	expected_key = sctp_set_key("\x00\x00\x00\x01\x02", 5);
-	if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
-		failed++;
-
-	/* test case 3 */
-	key1 = sctp_set_key("\x01", 1);
-	key2 = sctp_set_key("\x00\x00\x00\x02", 4);
-	expected_key = sctp_set_key("\x01\x00\x00\x00\x02", 5);
-	if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
-		failed++;
-
-	/* test case 4 */
-	key1 = sctp_set_key("\x00\x00\x00\x01", 4);
-	key2 = sctp_set_key("\x01", 1);
-	expected_key = sctp_set_key("\x01\x00\x00\x00\x01", 5);
-	if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
-		failed++;
-
-	/* test case 5 */
-	key1 = sctp_set_key("\x01", 1);
-	key2 = sctp_set_key("\x00\x00\x00\x01", 4);
-	expected_key = sctp_set_key("\x01\x00\x00\x00\x01", 5);
-	if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
-		failed++;
-
-	/* test case 6 */
-	key1 = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07", 11);
-	key2 = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x08", 11);
-	expected_key = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x08", 22);
-	if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
-		failed++;
-
-	/* test case 7 */
-	key1 = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x08", 11);
-	key2 = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07", 11);
-	expected_key = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x08", 22);
-	if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
-		failed++;
-
-	/* done with all tests */
-	if (failed)
-		printf("\nKey concatenation test results: %d cases failed", failed);
-	else
-		printf("\nKey concatenation test results: all test cases passed");
-}
-
-
-#if defined(STANDALONE_HMAC_TEST)
-int
-main(void)
-{
-	sctp_test_hmac_sha1();
-	sctp_test_hmac_md5();
-	sctp_test_authkey();
-}
-
-#endif				/* STANDALONE_HMAC_TEST */
-
-#endif				/* SCTP_HMAC_TEST */
diff --git a/sys/netinet/sctp_auth.h b/sys/netinet/sctp_auth.h
index 8602c97ac3c..cecdb907bc6 100644
--- a/sys/netinet/sctp_auth.h
+++ b/sys/netinet/sctp_auth.h
@@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
 
 /* digest lengths */
 #define SCTP_AUTH_DIGEST_LEN_SHA1	20
-#define SCTP_AUTH_DIGEST_LEN_MD5	16
 #define SCTP_AUTH_DIGEST_LEN_SHA224	28
 #define SCTP_AUTH_DIGEST_LEN_SHA256	32
 #define SCTP_AUTH_DIGEST_LEN_SHA384	48
@@ -52,7 +51,6 @@ __FBSDID("$FreeBSD$");
 /* union of all supported HMAC algorithm contexts */
 typedef union sctp_hash_context {
 	SHA1_CTX sha1;
-	MD5_CTX md5;
 #ifdef HAVE_SHA2
 	SHA256_CTX sha256;
 	SHA384_CTX sha384;
@@ -234,8 +232,4 @@ sctp_initialize_auth_params(struct sctp_inpcb *inp,
     struct sctp_tcb *stcb);
 
 /* test functions */
-extern void sctp_test_hmac_sha1(void);
-extern void sctp_test_hmac_md5(void);
-extern void sctp_test_authkey(void);
-
 #endif				/* __SCTP_AUTH_H__ */
diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h
index 349d1642f88..cec568d52c6 100644
--- a/sys/netinet/sctp_os_bsd.h
+++ b/sys/netinet/sctp_os_bsd.h
@@ -478,12 +478,6 @@ sctp_get_mbuf_for_msg(unsigned int space_needed,
 #include 
 #endif
 
-#include 
-/* map standard crypto API names */
-#define MD5_Init	MD5Init
-#define MD5_Update	MD5Update
-#define MD5_Final	MD5Final
-
 #endif
 
 #define SCTP_DECREMENT_AND_CHECK_REFCOUNT(addr) (atomic_fetchadd_int(addr, -1) == 1)
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index cbc9a9aabef..50ccc93ca9f 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -4313,16 +4313,8 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
 		if (stcb->asoc.authinfo.random != NULL) {
 			randp = (struct sctp_auth_random *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
 			p_len = sizeof(*randp) + stcb->asoc.authinfo.random_len;
-#ifdef SCTP_AUTH_DRAFT_04
-			randp->ph.param_type = htons(SCTP_RANDOM);
-			randp->ph.param_length = htons(p_len);
-			bcopy(stcb->asoc.authinfo.random->key,
-			    randp->random_data,
-			    stcb->asoc.authinfo.random_len);
-#else
 			/* random key already contains the header */
 			bcopy(stcb->asoc.authinfo.random->key, randp, p_len);
-#endif
 			/* zero out any padding required */
 			bzero((caddr_t)randp + p_len, SCTP_SIZE32(p_len) - p_len);
 			SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 682af5e40c2..73e7991c659 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -6254,15 +6254,6 @@ next_param:
 		return (-33);
 	}
 	/* concatenate the full random key */
-#ifdef SCTP_AUTH_DRAFT_04
-	keylen = random_len;
-	new_key = sctp_alloc_key(keylen);
-	if (new_key != NULL) {
-		/* copy in the RANDOM */
-		if (p_random != NULL)
-			bcopy(p_random->random_data, new_key->key, random_len);
-	}
-#else
 	keylen = sizeof(*p_random) + random_len + sizeof(*hmacs) + hmacs_len;
 	if (chunks != NULL) {
 		keylen += sizeof(*chunks) + num_chunks;
@@ -6285,19 +6276,13 @@ next_param:
 			bcopy(hmacs, new_key->key + keylen,
 			    sizeof(*hmacs) + hmacs_len);
 		}
-	}
-#endif
-	else {
+	} else {
 		/* failed to get memory for the key */
 		return (-34);
 	}
 	if (stcb->asoc.authinfo.peer_random != NULL)
 		sctp_free_key(stcb->asoc.authinfo.peer_random);
 	stcb->asoc.authinfo.peer_random = new_key;
-#ifdef SCTP_AUTH_DRAFT_04
-	/* don't include the chunks and hmacs for draft -04 */
-	stcb->asoc.authinfo.peer_random->keylen = random_len;
-#endif
 	sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid);
 	sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.recv_keyid);
 
diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h
index 2f16b94c2d6..3b34941fc67 100644
--- a/sys/netinet/sctp_uio.h
+++ b/sys/netinet/sctp_uio.h
@@ -526,7 +526,6 @@ struct sctp_hmacalgo {
 /* AUTH hmac_id */
 #define SCTP_AUTH_HMAC_ID_RSVD		0x0000
 #define SCTP_AUTH_HMAC_ID_SHA1		0x0001	/* default, mandatory */
-#define SCTP_AUTH_HMAC_ID_MD5		0x0002	/* deprecated */
 #define SCTP_AUTH_HMAC_ID_SHA256	0x0003
 #define SCTP_AUTH_HMAC_ID_SHA224	0x0004
 #define SCTP_AUTH_HMAC_ID_SHA384	0x0005

From aa16019d6654bd4cc4c28c2252453b6c3280437c Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Mon, 25 Jan 2010 11:56:53 +0000
Subject: [PATCH 1291/2592] MFC r201790: - Set td_slptick to 0 when moving
 threads out of sleepqueues. - Move td_slptick from u_int to int in order to
 follow 'ticks' signedness   and wrap up accordingly.

Sponsored by:	Sandvine Incorporated
---
 sys/kern/sched_4bsd.c | 2 +-
 sys/sys/proc.h        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index 573296af257..456f853702d 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -1050,7 +1050,7 @@ sched_wakeup(struct thread *td)
 		updatepri(td);
 		resetpriority(td);
 	}
-	td->td_slptick = ticks;
+	td->td_slptick = 0;
 	ts->ts_slptime = 0;
 	sched_add(td, SRQ_BORING);
 }
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 29722944cb3..642a6307fdc 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -216,7 +216,7 @@ struct thread {
 	int		td_pinned;	/* (k) Temporary cpu pin count. */
 	struct ucred	*td_ucred;	/* (k) Reference to credentials. */
 	u_int		td_estcpu;	/* (t) estimated cpu utilization */
-	u_int		td_slptick;	/* (t) Time at sleep. */
+	int		td_slptick;	/* (t) Time at sleep. */
 	struct rusage	td_ru;		/* (t) rusage information */
 	uint64_t	td_incruntime;	/* (t) Cpu ticks to transfer to proc. */
 	uint64_t	td_runtime;	/* (t) How many cpu ticks we've run. */

From 93a45f0f56e40a34d1d9a6590fa4442334a474a4 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Mon, 25 Jan 2010 12:05:51 +0000
Subject: [PATCH 1292/2592] MFC r201879: Introduce the new kernel thread called
 "deadlock resolver". It is used in order to seek within the threads state and
 heuristically understand if there is any deadlock happening.

In order to implement it, the sq_type in sleepqueues is mandatory and not
only compiled along with INVARIANTS option. Additively, a new sleepqueue
function, sleepq_type() is added, returning the type of the sleepqueue
linked to a wchan.
Three new sysctls are added in order to configure the thread:
debug.deadlkres.slptime_threshold
debug.deadlkres.blktime_threshold
debug.deadlkres.sleepfreq

rappresenting the thresholds for sleep and block time that will lead to
a deadlock matching (when exceeded), while the sleepfreq rappresents the
number of seconds between 2 consecutive thread runnings.
In order to enable the deadlock resolver thread recompile your kernel
with the option DEADLKRES.

Sponsored by:	Sandvine Incorporated
---
 UPDATING                    |   5 ++
 share/man/man9/sleepqueue.9 |  11 +++-
 sys/conf/NOTES              |   5 ++
 sys/conf/options            |   1 +
 sys/kern/kern_clock.c       | 122 +++++++++++++++++++++++++++++++++++-
 sys/kern/subr_sleepqueue.c  |  28 ++++++++-
 sys/kern/subr_turnstile.c   |   2 +
 sys/sys/proc.h              |   1 +
 sys/sys/sleepqueue.h        |   1 +
 9 files changed, 171 insertions(+), 5 deletions(-)

diff --git a/UPDATING b/UPDATING
index cba0fb95f37..28892561183 100644
--- a/UPDATING
+++ b/UPDATING
@@ -15,6 +15,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
 	debugging tools present in HEAD were left in place because
 	sun4v support still needs work to become production ready.
 
+20100125:
+	Introduce the kernel thread "deadlock resolver" (which can be enabled
+	via the DEADLKRES option, see NOTES for more details) and the
+	sleepq_type() function for sleepqueues.
+
 20090929:
 	802.11s D3.03 support was committed. This is incompatible with
 	the previous code, which was based on D3.0.
diff --git a/share/man/man9/sleepqueue.9 b/share/man/man9/sleepqueue.9
index d1d17cd63cf..63d0ebbfded 100644
--- a/share/man/man9/sleepqueue.9
+++ b/share/man/man9/sleepqueue.9
@@ -23,7 +23,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 18, 2010
+.Dd January 25, 2010
 .Dt SLEEPQUEUE 9
 .Os
 .Sh NAME
@@ -44,6 +44,7 @@
 .Nm sleepq_sleepcnt ,
 .Nm sleepq_timedwait ,
 .Nm sleepq_timedwait_sig ,
+.Nm sleepq_type ,
 .Nm sleepq_wait ,
 .Nm sleepq_wait_sig
 .Nd manage the queues of sleeping threads
@@ -84,6 +85,8 @@
 .Fn sleepq_timedwait "void *wchan"
 .Ft int
 .Fn sleepq_timedwait_sig "void *wchan" "int signal_caught"
+.Ft int
+.Fn sleepq_type "void *wchan"
 .Ft void
 .Fn sleepq_wait "void *wchan"
 .Ft int
@@ -366,6 +369,12 @@ given a
 .Fa wchan .
 .Pp
 The
+.Fn sleepq_type
+function returns the type of
+.Fa wchan
+associated to a sleepqueue.
+.Pp
+The
 .Fn sleepq_abort ,
 .Fn sleepq_broadcast ,
 and
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 3c2a99b663c..3d737246a9a 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2472,6 +2472,11 @@ options 	BOOTP_BLOCKSIZE=8192 # Override NFS block size
 #
 options 	SW_WATCHDOG
 
+#
+# Add the software deadlock resolver thread.
+#
+options		DEADLKRES
+
 #
 # Disable swapping of stack pages.  This option removes all
 # code which actually performs swapping, so it's not possible to turn
diff --git a/sys/conf/options b/sys/conf/options
index 5405559567e..e336fdc84a0 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -72,6 +72,7 @@ COMPAT_FREEBSD6	opt_compat.h
 COMPAT_FREEBSD7	opt_compat.h
 COMPILING_LINT	opt_global.h
 CY_PCI_FASTINTR
+DEADLKRES	opt_watchdog.h
 DIRECTIO
 FULL_PREEMPTION	opt_sched.h
 IPI_PREEMPTION	opt_sched.h
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index e95bc19152c..2844103fa40 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -48,14 +48,16 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -159,6 +161,124 @@ sysctl_kern_cp_times(SYSCTL_HANDLER_ARGS)
 SYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE,
     0,0, sysctl_kern_cp_times, "LU", "per-CPU time statistics");
 
+#ifdef DEADLKRES
+static int slptime_threshold = 1800;
+static int blktime_threshold = 900;
+static int sleepfreq = 3;
+
+static void
+deadlkres(void)
+{
+	struct proc *p;
+	struct thread *td;
+	void *wchan;
+	int blkticks, slpticks, slptype, tryl, tticks;
+
+	tryl = 0;
+	for (;;) {
+		blkticks = blktime_threshold * hz;
+		slpticks = slptime_threshold * hz;
+
+		/*
+		 * Avoid to sleep on the sx_lock in order to avoid a possible
+		 * priority inversion problem leading to starvation.
+		 * If the lock can't be held after 100 tries, panic.
+		 */
+		if (!sx_try_slock(&allproc_lock)) {
+			if (tryl > 100)
+		panic("%s: possible deadlock detected on allproc_lock\n",
+				    __func__);
+			tryl++;
+			pause("allproc_lock deadlkres", sleepfreq * hz);
+			continue;
+		}
+		tryl = 0;
+		FOREACH_PROC_IN_SYSTEM(p) {
+			PROC_LOCK(p);
+			FOREACH_THREAD_IN_PROC(p, td) {
+				thread_lock(td);
+				if (TD_ON_LOCK(td)) {
+
+					/*
+					 * The thread should be blocked on a
+					 * turnstile, simply check if the
+					 * turnstile channel is in good state.
+					 */
+					MPASS(td->td_blocked != NULL);
+					tticks = ticks - td->td_blktick;
+					thread_unlock(td);
+					if (tticks > blkticks) {
+
+						/*
+						 * Accordingly with provided
+						 * thresholds, this thread is
+						 * stuck for too long on a
+						 * turnstile.
+						 */
+						PROC_UNLOCK(p);
+						sx_sunlock(&allproc_lock);
+	panic("%s: possible deadlock detected for %p, blocked for %d ticks\n",
+						    __func__, td, tticks);
+					}
+				} else if (TD_IS_SLEEPING(td)) {
+
+					/*
+					 * Check if the thread is sleeping on a
+					 * lock, otherwise skip the check.
+					 * Drop the thread lock in order to
+					 * avoid a LOR with the sleepqueue
+					 * spinlock.
+					 */
+					wchan = td->td_wchan;
+					tticks = ticks - td->td_slptick;
+					thread_unlock(td);
+					slptype = sleepq_type(wchan);
+					if ((slptype == SLEEPQ_SX ||
+					    slptype == SLEEPQ_LK) &&
+					    tticks > slpticks) {
+
+						/*
+						 * Accordingly with provided
+						 * thresholds, this thread is
+						 * stuck for too long on a
+						 * sleepqueue.
+						 */
+						PROC_UNLOCK(p);
+						sx_sunlock(&allproc_lock);
+	panic("%s: possible deadlock detected for %p, blocked for %d ticks\n",
+						    __func__, td, tticks);
+					}
+				} else
+					thread_unlock(td);
+			}
+			PROC_UNLOCK(p);
+		}
+		sx_sunlock(&allproc_lock);
+
+		/* Sleep for sleepfreq seconds. */
+		pause("deadlkres", sleepfreq * hz);
+	}
+}
+
+static struct kthread_desc deadlkres_kd = {
+	"deadlkres",
+	deadlkres,
+	(struct thread **)NULL
+};
+
+SYSINIT(deadlkres, SI_SUB_CLOCKS, SI_ORDER_ANY, kthread_start, &deadlkres_kd);
+
+SYSCTL_NODE(_debug, OID_AUTO, deadlkres, CTLFLAG_RW, 0, "Deadlock resolver");
+SYSCTL_INT(_debug_deadlkres, OID_AUTO, slptime_threshold, CTLFLAG_RW,
+    &slptime_threshold, 0,
+    "Number of seconds within is valid to sleep on a sleepqueue");
+SYSCTL_INT(_debug_deadlkres, OID_AUTO, blktime_threshold, CTLFLAG_RW,
+    &blktime_threshold, 0,
+    "Number of seconds within is valid to block on a turnstile");
+SYSCTL_INT(_debug_deadlkres, OID_AUTO, sleepfreq, CTLFLAG_RW, &sleepfreq, 0,
+    "Number of seconds between any deadlock resolver thread run");
+#endif	/* DEADLKRES */
+
 void
 read_cpu_time(long *cp_time)
 {
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c
index a0496bdaad3..5df74d06e9e 100644
--- a/sys/kern/subr_sleepqueue.c
+++ b/sys/kern/subr_sleepqueue.c
@@ -122,8 +122,8 @@ struct sleepqueue {
 	LIST_ENTRY(sleepqueue) sq_hash;		/* (c) Chain and free list. */
 	LIST_HEAD(, sleepqueue) sq_free;	/* (c) Free queues. */
 	void	*sq_wchan;			/* (c) Wait channel. */
-#ifdef INVARIANTS
 	int	sq_type;			/* (c) Queue type. */
+#ifdef INVARIANTS
 	struct lock_object *sq_lock;		/* (c) Associated lock. */
 #endif
 };
@@ -317,7 +317,6 @@ sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags,
 		    ("thread's sleep queue has a non-empty free list"));
 		KASSERT(sq->sq_wchan == NULL, ("stale sq_wchan pointer"));
 		sq->sq_lock = lock;
-		sq->sq_type = flags & SLEEPQ_TYPE;
 #endif
 #ifdef SLEEPQUEUE_PROFILING
 		sc->sc_depth++;
@@ -330,6 +329,7 @@ sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags,
 		sq = td->td_sleepqueue;
 		LIST_INSERT_HEAD(&sc->sc_queues, sq, sq_hash);
 		sq->sq_wchan = wchan;
+		sq->sq_type = flags & SLEEPQ_TYPE;
 	} else {
 		MPASS(wchan == sq->sq_wchan);
 		MPASS(lock == sq->sq_lock);
@@ -668,6 +668,28 @@ sleepq_timedwait_sig(void *wchan, int pri)
 	return (rvalt);
 }
 
+/*
+ * Returns the type of sleepqueue given a waitchannel.
+ */
+int
+sleepq_type(void *wchan)
+{
+	struct sleepqueue *sq;
+	int type;
+
+	MPASS(wchan != NULL);
+
+	sleepq_lock(wchan);
+	sq = sleepq_lookup(wchan);
+	if (sq == NULL) {
+		sleepq_release(wchan);
+		return (-1);
+	}
+	type = sq->sq_type;
+	sleepq_release(wchan);
+	return (type);
+}
+
 /*
  * Removes a thread from a sleep queue and makes it
  * runnable.
@@ -1176,8 +1198,8 @@ DB_SHOW_COMMAND(sleepq, db_show_sleepqueue)
 	return;
 found:
 	db_printf("Wait channel: %p\n", sq->sq_wchan);
-#ifdef INVARIANTS
 	db_printf("Queue type: %d\n", sq->sq_type);
+#ifdef INVARIANTS
 	if (sq->sq_lock) {
 		lock = sq->sq_lock;
 		db_printf("Associated Interlock: %p - (%s) %s\n", lock,
diff --git a/sys/kern/subr_turnstile.c b/sys/kern/subr_turnstile.c
index 31c8cfc4837..d8f774899d1 100644
--- a/sys/kern/subr_turnstile.c
+++ b/sys/kern/subr_turnstile.c
@@ -733,6 +733,7 @@ turnstile_wait(struct turnstile *ts, struct thread *owner, int queue)
 	td->td_tsqueue = queue;
 	td->td_blocked = ts;
 	td->td_lockname = lock->lo_name;
+	td->td_blktick = ticks;
 	TD_SET_LOCK(td);
 	mtx_unlock_spin(&tc->tc_lock);
 	propagate_priority(td);
@@ -925,6 +926,7 @@ turnstile_unpend(struct turnstile *ts, int owner_type)
 		MPASS(TD_CAN_RUN(td));
 		td->td_blocked = NULL;
 		td->td_lockname = NULL;
+		td->td_blktick = 0;
 #ifdef INVARIANTS
 		td->td_tsqueue = 0xff;
 #endif
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 642a6307fdc..c0af11f6b3d 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -217,6 +217,7 @@ struct thread {
 	struct ucred	*td_ucred;	/* (k) Reference to credentials. */
 	u_int		td_estcpu;	/* (t) estimated cpu utilization */
 	int		td_slptick;	/* (t) Time at sleep. */
+	int		td_blktick;	/* (t) Time spent blocked. */
 	struct rusage	td_ru;		/* (t) rusage information */
 	uint64_t	td_incruntime;	/* (t) Cpu ticks to transfer to proc. */
 	uint64_t	td_runtime;	/* (t) How many cpu ticks we've run. */
diff --git a/sys/sys/sleepqueue.h b/sys/sys/sleepqueue.h
index 224d602c01f..3e33e6b34c7 100644
--- a/sys/sys/sleepqueue.h
+++ b/sys/sys/sleepqueue.h
@@ -112,6 +112,7 @@ void	sleepq_set_timeout(void *wchan, int timo);
 u_int	sleepq_sleepcnt(void *wchan, int queue);
 int	sleepq_timedwait(void *wchan, int pri);
 int	sleepq_timedwait_sig(void *wchan, int pri);
+int	sleepq_type(void *wchan);
 void	sleepq_wait(void *wchan, int pri);
 int	sleepq_wait_sig(void *wchan, int pri);
 

From b83b25d7b153227b685f90a53273c638bc0ca4d6 Mon Sep 17 00:00:00 2001
From: Marko Zec 
Date: Mon, 25 Jan 2010 14:17:13 +0000
Subject: [PATCH 1293/2592] MFC r201895:   Reduce recursions on curvnet and
 thus spamming the console with warning   messages for kernels built with
 options VIMAGE and VNET_DEBUG enabled.

  Reviewed by:  bz
---
 sys/nfsclient/nfs_vfsops.c | 11 +++++++----
 sys/nfsclient/nfs_vnops.c  |  5 -----
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index 0e100935f14..2346d41932a 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -423,14 +423,18 @@ nfs_mountroot(struct mount *mp)
 	char buf[128];
 	char *cp;
 
+	CURVNET_SET(TD_TO_VNET(td));
+
 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
 	bootpc_init();		/* use bootp to get nfs_diskless filled in */
 #elif defined(NFS_ROOT)
 	nfs_setup_diskless();
 #endif
 
-	if (nfs_diskless_valid == 0)
+	if (nfs_diskless_valid == 0) {
+		CURVNET_RESTORE();
 		return (-1);
+	}
 	if (nfs_diskless_valid == 1)
 		nfs_convert_diskless();
 
@@ -516,6 +520,7 @@ nfs_mountroot(struct mount *mp)
 	nd->root_args.hostname = buf;
 	if ((error = nfs_mountdiskless(buf,
 	    &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
+		CURVNET_RESTORE();
 		return (error);
 	}
 
@@ -529,6 +534,7 @@ nfs_mountroot(struct mount *mp)
 	    sizeof (prison0.pr_hostname));
 	mtx_unlock(&prison0.pr_mtx);
 	inittodr(ntohl(nd->root_time));
+	CURVNET_RESTORE();
 	return (0);
 }
 
@@ -827,8 +833,6 @@ nfs_mount(struct mount *mp)
 	has_fh_opt = 0;
 	has_hostname_opt = 0;
 
-	CURVNET_SET(CRED_TO_VNET(curthread->td_ucred));
-
 	if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
 		error = EINVAL;
 		goto out;
@@ -1128,7 +1132,6 @@ out:
 		mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
 		MNT_IUNLOCK(mp);
 	}
-	CURVNET_RESTORE();
 	return (error);
 }
 
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index b3c28a3cdd0..7d6bb307e36 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -1555,19 +1555,15 @@ nfs_create(struct vop_create_args *ap)
 	struct vattr vattr;
 	int v3 = NFS_ISV3(dvp);
 
-	CURVNET_SET(CRED_TO_VNET(curthread->td_ucred));
-
 	/*
 	 * Oops, not for me..
 	 */
 	if (vap->va_type == VSOCK) {
 		error = nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap);
-		CURVNET_RESTORE();
 		return (error);
 	}
 
 	if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0) {
-		CURVNET_RESTORE();
 		return (error);
 	}
 	if (vap->va_vaflags & VA_EXCLUSIVE)
@@ -1665,7 +1661,6 @@ nfsmout:
 		KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
 	}
 	mtx_unlock(&(VTONFS(dvp))->n_mtx);
-	CURVNET_RESTORE();
 	return (error);
 }
 

From 38cd0240f4c21812842f8dc4fdea3ca24f5ad14f Mon Sep 17 00:00:00 2001
From: Maksim Yevmenkin 
Date: Tue, 26 Jan 2010 00:38:56 +0000
Subject: [PATCH 1294/2592] MFC SVN rev 198492

Fix typo in bluetooth.3
Do not use reserved C++ keyword "new"
---
 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 179cbbba9532550b99b3bc24463b1977962a751e Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 26 Jan 2010 09:20:33 +0000
Subject: [PATCH 1295/2592] MFC r202884: Document pthread_timedjoin_np. Note
 implementation-defined EOPNOTSUPP error [1].

---
 share/man/man3/pthread_join.3 | 42 +++++++++++++++++++++++++++++++----
 1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/share/man/man3/pthread_join.3 b/share/man/man3/pthread_join.3
index 1aa593222b4..b01069a6b61 100644
--- a/share/man/man3/pthread_join.3
+++ b/share/man/man3/pthread_join.3
@@ -30,11 +30,12 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 4, 1996
+.Dd January 23, 2010
 .Dt PTHREAD_JOIN 3
 .Os
 .Sh NAME
-.Nm pthread_join
+.Nm pthread_join ,
+.Nm pthread_timedjoin_np
 .Nd wait for thread termination
 .Sh LIBRARY
 .Lb libpthread
@@ -42,6 +43,8 @@
 .In pthread.h
 .Ft int
 .Fn pthread_join "pthread_t thread" "void **value_ptr"
+.Ft int
+.Fn pthread_timedjoin_np "pthread_t thread" "void **value_ptr" "const struct timespec *abstime"
 .Sh DESCRIPTION
 The
 .Fn pthread_join
@@ -70,18 +73,30 @@ If the thread calling
 .Fn pthread_join
 is cancelled, then the target thread is not detached.
 .Pp
+The
+.Fn pthread_timedjoin_np
+function is equivalent to the
+.Fn pthread_join
+function except it will return
+.Er ETIMEDOUT
+if target thread does not exit before specified absolute time passes.
+.Pp
 A thread that has exited but remains unjoined counts against
 [_POSIX_THREAD_THREADS_MAX].
 .Sh RETURN VALUES
 If successful, the
 .Fn pthread_join
-function will return zero.
+and
+.Fn pthread_timedjoin_np
+functions will return zero.
 Otherwise an error number will be returned to
 indicate the error.
 .Sh ERRORS
 The
 .Fn pthread_join
-function will fail if:
+and
+.Fn pthread_timedjoin_np
+functions will fail if:
 .Bl -tag -width Er
 .It Bq Er EINVAL
 The implementation has detected that the value specified by
@@ -95,6 +110,19 @@ thread ID,
 A deadlock was detected or the value of
 .Fa thread
 specifies the calling thread.
+.It Bq Er EOPNOTSUPP
+The implementation detected that another caller is already waiting on
+.Fa thread .
+.El
+.Pp
+Additionally, the
+.Fn pthread_join
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er ETIMEDOUT
+The specified absolute time passed while
+.Fn pthread_timedjoin_np
+waited for thread exit.
 .El
 .Sh SEE ALSO
 .Xr wait 2 ,
@@ -104,3 +132,9 @@ The
 .Fn pthread_join
 function conforms to
 .St -p1003.1-96 .
+The
+.Fn pthread_timedjoin_np
+is
+.Fx
+extension, first appeared in
+.Fx 6.1 .

From 8a37c82c6c63397a62bf32484ec94ca0dfefceff Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Tue, 26 Jan 2010 11:15:03 +0000
Subject: [PATCH 1296/2592] MFC of tzdata2010b, r203019

Mexico's House of Representatives has approved a proposal for
northern Mexico's border cities to share the same daylight saving
schedule as the United States.
---
 share/zoneinfo/northamerica | 100 ++++++++++++++++++++++++++++++++++--
 share/zoneinfo/zone.tab     |  11 ++--
 2 files changed, 102 insertions(+), 9 deletions(-)

diff --git a/share/zoneinfo/northamerica b/share/zoneinfo/northamerica
index 236922d7545..5c25664b234 100644
--- a/share/zoneinfo/northamerica
+++ b/share/zoneinfo/northamerica
@@ -1,5 +1,5 @@
 # 
-# @(#)northamerica	8.28
+# @(#)northamerica	8.30
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -1955,6 +1955,58 @@ Zone America/Dawson	-9:17:40 -	LMT	1900 Aug 20
 # http://www.conae.gob.mx/ahorro/horaver2001_m1_2002.html (2002-02-20)
 # confirms this.  Sonora as usual is the only state where DST is not applied.
 
+# From Steffen Thorsen (2009-12-28):
+#
+# Steffen Thorsen wrote:
+# > Mexico's House of Representatives has approved a proposal for northern
+# > Mexico's border cities to share the same daylight saving schedule as
+# > the United States.
+# Now this has passed both the Congress and the Senate, so starting from
+# 2010, some border regions will be the same:
+# 
+# http://www.signonsandiego.com/news/2009/dec/28/clocks-will-match-both-sides-border/
+# 
+# 
+# http://www.elmananarey.com/diario/noticia/nacional/noticias/empatan_horario_de_frontera_con_eu/621939
+# 
+# (Spanish)
+#
+# Could not find the new law text, but the proposed law text changes are here:
+# 
+# http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/20091210-V.pdf
+# 
+# (Gaceta Parlamentaria)
+#
+# There is also a list of the votes here:
+# 
+# http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/V2-101209.html
+# 
+#
+# Our page:
+# 
+# http://www.timeanddate.com/news/time/north-mexico-dst-change.html
+# 
+
+# From Arthur David Olson (2010-01-20):
+# The page
+# 
+# http://dof.gob.mx/nota_detalle.php?codigo=5127480&fecha=06/01/2010
+# 
+# includes this text:
+# En los municipios fronterizos de Tijuana y Mexicali en Baja California;
+# Juárez y Ojinaga en Chihuahua; Acuña y Piedras Negras en Coahuila;
+# Anáhuac en Nuevo León; y Nuevo Laredo, Reynosa y Matamoros en
+# Tamaulipas, la aplicación de este horario estacional surtirá efecto
+# desde las dos horas del segundo domingo de marzo y concluirá a las dos
+# horas del primer domingo de noviembre.
+# En los municipios fronterizos que se encuentren ubicados en la franja
+# fronteriza norte en el territorio comprendido entre la línea
+# internacional y la línea paralela ubicada a una distancia de veinte
+# kilómetros, así como la Ciudad de Ensenada, Baja California, hacia el
+# interior del país, la aplicación de este horario estacional surtirá
+# efecto desde las dos horas del segundo domingo de marzo y concluirá a
+# las dos horas del primer domingo de noviembre.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Mexico	1939	only	-	Feb	5	0:00	1:00	D
 Rule	Mexico	1939	only	-	Jun	25	0:00	0	S
@@ -1981,13 +2033,19 @@ Zone America/Merida	-5:58:28 -	LMT	1922 Jan  1  0:01:32
 			-6:00	-	CST	1981 Dec 23
 			-5:00	-	EST	1982 Dec  2
 			-6:00	Mexico	C%sT
-# Coahuila, Durango, Nuevo Leon, Tamaulipas
+# Coahuila, Durango, Nuevo Leon, Tamaulipas (near US border)
+Zone America/Matamoros	-6:40:00 -	LMT	1921 Dec 31 23:20:00
+			-6:00	-	CST	1988
+			-6:00	US	C%sT	1989
+			-6:00	Mexico	C%sT	2010
+			-6:00	US	C%sT
+# Coahuila, Durango, Nuevo Leon, Tamaulipas (away from US border)
 Zone America/Monterrey	-6:41:16 -	LMT	1921 Dec 31 23:18:44
 			-6:00	-	CST	1988
 			-6:00	US	C%sT	1989
 			-6:00	Mexico	C%sT
 # Central Mexico
-Zone America/Mexico_City -6:36:36 -	LMT	1922 Jan  1  0:23:24
+Zone America/Mexico_City -6:36:36 -	LMT	1922 Jan  1 0:23:24
 			-7:00	-	MST	1927 Jun 10 23:00
 			-6:00	-	CST	1930 Nov 15
 			-7:00	-	MST	1931 May  1 23:00
@@ -1996,7 +2054,19 @@ Zone America/Mexico_City -6:36:36 -	LMT	1922 Jan  1  0:23:24
 			-6:00	Mexico	C%sT	2001 Sep 30 02:00
 			-6:00	-	CST	2002 Feb 20
 			-6:00	Mexico	C%sT
-# Chihuahua
+# Chihuahua (near US border)
+Zone America/Ojinaga	-6:57:40 -	LMT	1922 Jan 1 0:02:20
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1996
+			-6:00	Mexico	C%sT	1998
+			-6:00	-	CST	1998 Apr Sun>=1 3:00
+			-7:00	Mexico	M%sT	2010
+			-7:00	US	M%sT
+# Chihuahua (away from US border)
 Zone America/Chihuahua	-7:04:20 -	LMT	1921 Dec 31 23:55:40
 			-7:00	-	MST	1927 Jun 10 23:00
 			-6:00	-	CST	1930 Nov 15
@@ -2030,8 +2100,28 @@ Zone America/Mazatlan	-7:05:40 -	LMT	1921 Dec 31 23:54:20
 			-7:00	-	MST	1949 Jan 14
 			-8:00	-	PST	1970
 			-7:00	Mexico	M%sT
-# Baja California
+# Baja California (near US border)
 Zone America/Tijuana	-7:48:04 -	LMT	1922 Jan  1  0:11:56
+			-7:00	-	MST	1924
+			-8:00	-	PST	1927 Jun 10 23:00
+			-7:00	-	MST	1930 Nov 15
+			-8:00	-	PST	1931 Apr  1
+			-8:00	1:00	PDT	1931 Sep 30
+			-8:00	-	PST	1942 Apr 24
+			-8:00	1:00	PWT	1945 Aug 14 23:00u
+			-8:00	1:00	PPT	1945 Nov 12 # Peace
+			-8:00	-	PST	1948 Apr  5
+			-8:00	1:00	PDT	1949 Jan 14
+			-8:00	-	PST	1954
+			-8:00	CA	P%sT	1961
+			-8:00	-	PST	1976
+			-8:00	US	P%sT	1996
+			-8:00	Mexico	P%sT	2001
+			-8:00	US	P%sT	2002 Feb 20
+			-8:00	Mexico	P%sT	2010
+			-8:00	US	P%sT
+# Baja California (away from US border)
+Zone America/Santa_Isabel	-7:39:28 -	LMT	1922 Jan  1  0:20:32
 			-7:00	-	MST	1924
 			-8:00	-	PST	1927 Jun 10 23:00
 			-7:00	-	MST	1930 Nov 15
diff --git a/share/zoneinfo/zone.tab b/share/zoneinfo/zone.tab
index dab18c318d1..c8fb2503db8 100644
--- a/share/zoneinfo/zone.tab
+++ b/share/zoneinfo/zone.tab
@@ -1,5 +1,5 @@
 # 
-# @(#)zone.tab	8.31
+# @(#)zone.tab	8.33
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 #
@@ -279,11 +279,14 @@ MW	-1547+03500	Africa/Blantyre
 MX	+1924-09909	America/Mexico_City	Central Time - most locations
 MX	+2105-08646	America/Cancun	Central Time - Quintana Roo
 MX	+2058-08937	America/Merida	Central Time - Campeche, Yucatan
-MX	+2540-10019	America/Monterrey	Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas
+MX	+2540-10019	America/Monterrey	Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border
+MX	+2550-09730	America/Matamoros	US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border
 MX	+2313-10625	America/Mazatlan	Mountain Time - S Baja, Nayarit, Sinaloa
-MX	+2838-10605	America/Chihuahua	Mountain Time - Chihuahua
+MX	+2838-10605	America/Chihuahua	Mexican Mountain Time - Chihuahua away from US border
+MX	+2934-10425	America/Ojinaga	US Mountain Time - Chihuahua near US border
 MX	+2904-11058	America/Hermosillo	Mountain Standard Time - Sonora
-MX	+3232-11701	America/Tijuana	Pacific Time
+MX	+3232-11701	America/Tijuana	US Pacific Time - Baja California near US border
+MX	+3018-11452	America/Santa_Isabel	Mexican Pacific Time - Baja California away from US border
 MY	+0310+10142	Asia/Kuala_Lumpur	peninsular Malaysia
 MY	+0133+11020	Asia/Kuching	Sabah & Sarawak
 MZ	-2558+03235	Africa/Maputo

From da4af7b6c44e2b05be0c1b43b123d343d6ee76f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= 
Date: Tue, 26 Jan 2010 14:15:12 +0000
Subject: [PATCH 1297/2592] MFH (r202613, r202623): HTTP digest authentication
 support.

---
 lib/libfetch/Makefile |   7 +-
 lib/libfetch/http.c   | 886 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 823 insertions(+), 70 deletions(-)

diff --git a/lib/libfetch/Makefile b/lib/libfetch/Makefile
index 3576db7b20a..5091adf7c33 100644
--- a/lib/libfetch/Makefile
+++ b/lib/libfetch/Makefile
@@ -16,8 +16,11 @@ CFLAGS+=	-DINET6
 
 .if ${MK_OPENSSL} != "no"
 CFLAGS+=	-DWITH_SSL
-DPADD=		${LIBSSL} ${LIBCRYPTO}
-LDADD=		-lssl -lcrypto
+DPADD=		${LIBSSL} ${LIBCRYPTO} ${LIBMD}
+LDADD=		-lssl -lcrypto -lmd
+.else
+DPADD=		${LIBMD}
+LDADD=		-lmd
 .endif
 
 CFLAGS+=	-DFTP_COMBINE_CWDS
diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c
index dd983493e39..f44366e6ff2 100644
--- a/lib/libfetch/http.c
+++ b/lib/libfetch/http.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -343,7 +344,8 @@ typedef enum {
 	hdr_last_modified,
 	hdr_location,
 	hdr_transfer_encoding,
-	hdr_www_authenticate
+	hdr_www_authenticate,
+	hdr_proxy_authenticate,
 } hdr_t;
 
 /* Names of interesting headers */
@@ -357,6 +359,7 @@ static struct {
 	{ hdr_location,			"Location" },
 	{ hdr_transfer_encoding,	"Transfer-Encoding" },
 	{ hdr_www_authenticate,		"WWW-Authenticate" },
+	{ hdr_proxy_authenticate,	"Proxy-Authenticate" },
 	{ hdr_unknown,			NULL },
 };
 
@@ -446,21 +449,114 @@ http_match(const char *str, const char *hdr)
 	return (hdr);
 }
 
-/*
- * Get the next header and return the appropriate symbolic code.
- */
-static hdr_t
-http_next_header(conn_t *conn, const char **p)
-{
-	int i;
 
-	if (fetch_getln(conn) == -1)
-		return (hdr_syserror);
-	while (conn->buflen && isspace((unsigned char)conn->buf[conn->buflen - 1]))
+/*
+ * Get the next header and return the appropriate symbolic code.  We
+ * need to read one line ahead for checking for a continuation line
+ * belonging to the current header (continuation lines start with
+ * white space). 
+ *
+ * We get called with a fresh line already in the conn buffer, either
+ * from the previous http_next_header() invocation, or, the first
+ * time, from a fetch_getln() performed by our caller.
+ *
+ * This stops when we encounter an empty line (we dont read beyond the header
+ * area).
+ * 
+ * Note that the "headerbuf" is just a place to return the result. Its
+ * contents are not used for the next call. This means that no cleanup
+ * is needed when ie doing another connection, just call the cleanup when
+ * fully done to deallocate memory.
+ */
+
+/* Limit the max number of continuation lines to some reasonable value */
+#define HTTP_MAX_CONT_LINES 10
+
+/* Place into which to build a header from one or several lines */
+typedef struct {
+	char	*buf;		/* buffer */
+	size_t	 bufsize;	/* buffer size */
+	size_t	 buflen;	/* length of buffer contents */
+} http_headerbuf_t;
+
+static void
+init_http_headerbuf(http_headerbuf_t *buf)
+{
+	buf->buf = NULL;
+	buf->bufsize = 0;
+	buf->buflen = 0;
+}
+
+static void 
+clean_http_headerbuf(http_headerbuf_t *buf)
+{
+	if (buf->buf)
+		free(buf->buf);
+	init_http_headerbuf(buf);
+}
+
+/* Remove whitespace at the end of the buffer */
+static void 
+http_conn_trimright(conn_t *conn)
+{
+	while (conn->buflen && 
+	       isspace((unsigned char)conn->buf[conn->buflen - 1]))
 		conn->buflen--;
 	conn->buf[conn->buflen] = '\0';
+}
+
+static hdr_t
+http_next_header(conn_t *conn, http_headerbuf_t *hbuf, const char **p)
+{
+	int i, len;
+
+	/* 
+	 * Have to do the stripping here because of the first line. So
+	 * it's done twice for the subsequent lines. No big deal 
+	 */
+	http_conn_trimright(conn);
 	if (conn->buflen == 0)
 		return (hdr_end);
+
+	/* Copy the line to the headerbuf */
+	if (hbuf->bufsize < conn->buflen + 1) {
+		if ((hbuf->buf = realloc(hbuf->buf, conn->buflen + 1)) == NULL)
+			return (hdr_syserror);
+		hbuf->bufsize = conn->buflen + 1;
+	}
+	strcpy(hbuf->buf, conn->buf);
+	hbuf->buflen = conn->buflen;
+
+	/* 
+	 * Fetch possible continuation lines. Stop at 1st non-continuation
+	 * and leave it in the conn buffer 
+         */
+	for (i = 0; i < HTTP_MAX_CONT_LINES; i++) {
+		if (fetch_getln(conn) == -1)
+			return (hdr_syserror);
+
+		/* 
+		 * Note: we carry on the idea from the previous version
+		 * that a pure whitespace line is equivalent to an empty
+		 * one (so it's not continuation and will be handled when
+		 * we are called next) 
+		 */
+		http_conn_trimright(conn);
+		if (conn->buf[0] != ' ' && conn->buf[0] != "\t"[0])
+			break;
+
+		/* Got a continuation line. Concatenate to previous */
+		len = hbuf->buflen + conn->buflen;
+		if (hbuf->bufsize < len + 1) {
+			len *= 2;
+			if ((hbuf->buf = realloc(hbuf->buf, len + 1)) == NULL)
+				return (hdr_syserror);
+			hbuf->bufsize = len + 1;
+		}
+		strcpy(hbuf->buf + hbuf->buflen, conn->buf);
+		hbuf->buflen += conn->buflen;
+	} 
+
 	/*
 	 * We could check for malformed headers but we don't really care.
 	 * A valid header starts with a token immediately followed by a
@@ -468,11 +564,290 @@ http_next_header(conn_t *conn, const char **p)
 	 * characters except "()<>@,;:\\\"{}".
 	 */
 	for (i = 0; hdr_names[i].num != hdr_unknown; i++)
-		if ((*p = http_match(hdr_names[i].name, conn->buf)) != NULL)
+		if ((*p = http_match(hdr_names[i].name, hbuf->buf)) != NULL)
 			return (hdr_names[i].num);
+
 	return (hdr_unknown);
 }
 
+/**************************
+ * [Proxy-]Authenticate header parsing
+ */
+
+/* 
+ * Read doublequote-delimited string into output buffer obuf (allocated 
+ * by caller, whose responsibility it is to ensure that it's big enough)
+ * cp points to the first char after the initial '"'
+ * Handles \ quoting 
+ * Returns pointer to the first char after the terminating double quote, or 
+ * NULL for error.
+ */
+static const char *
+http_parse_headerstring(const char *cp, char *obuf)
+{
+	for (;;) {
+		switch (*cp) {
+		case 0: /* Unterminated string */
+			*obuf = 0;
+			return (NULL);
+		case '"': /* Ending quote */
+			*obuf = 0;
+			return (++cp);
+		case '\\':
+			if (*++cp == 0) {
+				*obuf = 0;
+				return (NULL);
+			}
+			/* FALLTHROUGH */
+		default:
+			*obuf++ = *cp++;
+		}
+	}
+}
+
+/* Http auth challenge schemes */
+typedef enum {HTTPAS_UNKNOWN, HTTPAS_BASIC,HTTPAS_DIGEST} http_auth_schemes_t;
+
+/* Data holder for a Basic or Digest challenge. */
+typedef struct {
+	http_auth_schemes_t scheme;
+	char	*realm;
+	char	*qop;
+	char	*nonce;
+	char	*opaque;
+	char	*algo;
+	int	 stale;
+	int	 nc; /* Nonce count */
+} http_auth_challenge_t;
+
+static void 
+init_http_auth_challenge(http_auth_challenge_t *b)
+{
+	b->scheme = HTTPAS_UNKNOWN;
+	b->realm = b->qop = b->nonce = b->opaque = b->algo = NULL;
+	b->stale = b->nc = 0;
+}
+
+static void 
+clean_http_auth_challenge(http_auth_challenge_t *b)
+{
+	if (b->realm) 
+		free(b->realm);
+	if (b->qop) 
+		free(b->qop);
+	if (b->nonce) 
+		free(b->nonce);
+	if (b->opaque) 
+		free(b->opaque);
+	if (b->algo) 
+		free(b->algo);
+	init_http_auth_challenge(b);
+}
+
+/* Data holder for an array of challenges offered in an http response. */
+#define MAX_CHALLENGES 10
+typedef struct {
+	http_auth_challenge_t *challenges[MAX_CHALLENGES];
+	int	count; /* Number of parsed challenges in the array */
+	int	valid; /* We did parse an authenticate header */
+} http_auth_challenges_t;
+
+static void 
+init_http_auth_challenges(http_auth_challenges_t *cs)
+{
+	int i;
+	for (i = 0; i < MAX_CHALLENGES; i++)
+		cs->challenges[i] = NULL;
+	cs->count = cs->valid = 0;
+}
+
+static void 
+clean_http_auth_challenges(http_auth_challenges_t *cs)
+{
+	int i;
+	/* We rely on non-zero pointers being allocated, not on the count */
+	for (i = 0; i < MAX_CHALLENGES; i++) {
+		if (cs->challenges[i] != NULL) {
+			clean_http_auth_challenge(cs->challenges[i]);
+			free(cs->challenges[i]);
+		}
+	}
+	init_http_auth_challenges(cs);
+}
+
+/* 
+ * Enumeration for lexical elements. Separators will be returned as their own
+ * ascii value
+ */
+typedef enum {HTTPHL_WORD=256, HTTPHL_STRING=257, HTTPHL_END=258,
+	      HTTPHL_ERROR = 259} http_header_lex_t;
+
+/* 
+ * Determine what kind of token comes next and return possible value
+ * in buf, which is supposed to have been allocated big enough by
+ * caller. Advance input pointer and return element type. 
+ */
+static int 
+http_header_lex(const char **cpp, char *buf)
+{
+	size_t l;
+	/* Eat initial whitespace */
+	*cpp += strspn(*cpp, " \t");
+	if (**cpp == 0)
+		return (HTTPHL_END);
+
+	/* Separator ? */
+	if (**cpp == ',' || **cpp == '=')
+		return (*((*cpp)++));
+
+	/* String ? */
+	if (**cpp == '"') {
+		*cpp = http_parse_headerstring(++*cpp, buf);
+		if (*cpp == NULL)
+			return (HTTPHL_ERROR);
+		return (HTTPHL_STRING);
+	}
+
+	/* Read other token, until separator or whitespace */
+	l = strcspn(*cpp, " \t,=");
+	memcpy(buf, *cpp, l);
+	buf[l] = 0;
+	*cpp += l;
+	return (HTTPHL_WORD);
+}
+
+/* 
+ * Read challenges from http xxx-authenticate header and accumulate them
+ * in the challenges list structure.
+ *
+ * Headers with multiple challenges are specified by rfc2617, but
+ * servers (ie: squid) often send them in separate headers instead,
+ * which in turn is forbidden by the http spec (multiple headers with
+ * the same name are only allowed for pure comma-separated lists, see
+ * rfc2616 sec 4.2).
+ *
+ * We support both approaches anyway
+ */
+static int 
+http_parse_authenticate(const char *cp, http_auth_challenges_t *cs)
+{
+	int ret = -1;
+	http_header_lex_t lex;
+	char *key = malloc(strlen(cp) + 1);
+	char *value = malloc(strlen(cp) + 1);
+	char *buf = malloc(strlen(cp) + 1);
+
+	if (key == NULL || value == NULL || buf == NULL) {
+		fetch_syserr();
+		goto out;
+	}
+
+	/* In any case we've seen the header and we set the valid bit */
+	cs->valid = 1;
+
+	/* Need word first */
+	lex = http_header_lex(&cp, key);
+	if (lex != HTTPHL_WORD)
+		goto out;
+
+	/* Loop on challenges */
+	for (; cs->count < MAX_CHALLENGES; cs->count++) {
+		cs->challenges[cs->count] = 
+			malloc(sizeof(http_auth_challenge_t));
+		if (cs->challenges[cs->count] == NULL) {
+			fetch_syserr();
+			goto out;
+		}
+		init_http_auth_challenge(cs->challenges[cs->count]);
+		if (!strcasecmp(key, "basic")) {
+			cs->challenges[cs->count]->scheme = HTTPAS_BASIC;
+		} else if (!strcasecmp(key, "digest")) {
+			cs->challenges[cs->count]->scheme = HTTPAS_DIGEST;
+		} else {
+			cs->challenges[cs->count]->scheme = HTTPAS_UNKNOWN;
+			/* 
+                         * Continue parsing as basic or digest may
+			 * follow, and the syntax is the same for
+			 * all. We'll just ignore this one when
+			 * looking at the list
+			 */
+		}
+	
+		/* Loop on attributes */
+		for (;;) {
+			/* Key */
+			lex = http_header_lex(&cp, key);
+			if (lex != HTTPHL_WORD)
+				goto out;
+
+			/* Equal sign */
+			lex = http_header_lex(&cp, buf);
+			if (lex != '=')
+				goto out;
+
+			/* Value */
+			lex = http_header_lex(&cp, value);
+			if (lex != HTTPHL_WORD && lex != HTTPHL_STRING)
+				goto out;
+
+			if (!strcasecmp(key, "realm"))
+				cs->challenges[cs->count]->realm = 
+					strdup(value);
+			else if (!strcasecmp(key, "qop"))
+				cs->challenges[cs->count]->qop = 
+					strdup(value);
+			else if (!strcasecmp(key, "nonce"))
+				cs->challenges[cs->count]->nonce = 
+					strdup(value);
+			else if (!strcasecmp(key, "opaque"))
+				cs->challenges[cs->count]->opaque = 
+					strdup(value);
+			else if (!strcasecmp(key, "algorithm"))
+				cs->challenges[cs->count]->algo = 
+					strdup(value);
+			else if (!strcasecmp(key, "stale"))
+				cs->challenges[cs->count]->stale = 
+					strcasecmp(value, "no");
+			/* Else ignore unknown attributes */
+
+			/* Comma or Next challenge or End */
+			lex = http_header_lex(&cp, key);
+			/* 
+                         * If we get a word here, this is the beginning of the
+			 * next challenge. Break the attributes loop 
+                         */
+			if (lex == HTTPHL_WORD)
+				break;
+
+			if (lex == HTTPHL_END) {
+				/* End while looking for ',' is normal exit */
+				cs->count++;
+				ret = 0;
+				goto out;
+			}
+			/* Anything else is an error */
+			if (lex != ',')
+				goto out;
+
+		} /* End attributes loop */
+	} /* End challenge loop */
+
+	/* 
+         * Challenges max count exceeded. This really can't happen
+	 * with normal data, something's fishy -> error 
+	 */ 
+
+out:
+	if (key)
+		free(key);
+	if (value)
+		free(value);
+	if (buf)
+		free(buf);
+	return (ret);
+}
+
+
 /*
  * Parse a last-modified header
  */
@@ -618,6 +993,291 @@ http_base64(const char *src)
 	return (str);
 }
 
+
+/*
+ * Extract authorization parameters from environment value.
+ * The value is like scheme:realm:user:pass
+ */
+typedef struct {
+	char	*scheme;
+	char	*realm;
+	char	*user;
+	char	*password;
+} http_auth_params_t;
+
+static void
+init_http_auth_params(http_auth_params_t *s)
+{
+	s->scheme = s->realm = s->user = s->password = 0;
+}
+
+static void 
+clean_http_auth_params(http_auth_params_t *s)
+{
+	if (s->scheme) 
+		free(s->scheme);
+	if (s->realm) 
+		free(s->realm);
+	if (s->user) 
+		free(s->user);
+	if (s->password) 
+		free(s->password);
+	init_http_auth_params(s);
+}
+
+static int
+http_authfromenv(const char *p, http_auth_params_t *parms)
+{
+	int ret = -1;
+	char *v, *ve;
+	char *str = strdup(p);
+
+	if (str == NULL) {
+		fetch_syserr();
+		return (-1);
+	}
+	v = str;
+
+	if ((ve = strchr(v, ':')) == NULL)
+		goto out;
+
+	*ve = 0;
+	if ((parms->scheme = strdup(v)) == NULL) {
+		fetch_syserr();
+		goto out;
+	}
+	v = ve + 1;
+
+	if ((ve = strchr(v, ':')) == NULL)
+		goto out;
+
+	*ve = 0;
+	if ((parms->realm = strdup(v)) == NULL) {
+		fetch_syserr();
+		goto out;
+	}
+	v = ve + 1;
+
+	if ((ve = strchr(v, ':')) == NULL)
+		goto out;
+
+	*ve = 0;
+	if ((parms->user = strdup(v)) == NULL) {
+		fetch_syserr();
+		goto out;
+	}
+	v = ve + 1;
+
+
+	if ((parms->password = strdup(v)) == NULL) {
+		fetch_syserr();
+		goto out;
+	}
+	ret = 0;
+out:
+	if (ret == -1) 
+		clean_http_auth_params(parms);
+	if (str)
+		free(str);
+	return (ret);
+}
+
+
+/* 
+ * Digest response: the code to compute the digest is taken from the
+ * sample implementation in RFC2616 
+ */
+#define IN
+#define OUT
+
+#define HASHLEN 16
+typedef char HASH[HASHLEN];
+#define HASHHEXLEN 32
+typedef char HASHHEX[HASHHEXLEN+1];
+
+static const char *hexchars = "0123456789abcdef";
+static void 
+CvtHex(IN HASH Bin, OUT HASHHEX Hex)
+{
+	unsigned short i;
+	unsigned char j;
+
+	for (i = 0; i < HASHLEN; i++) {
+		j = (Bin[i] >> 4) & 0xf;
+		Hex[i*2] = hexchars[j];
+		j = Bin[i] & 0xf;
+		Hex[i*2+1] = hexchars[j];
+	};
+	Hex[HASHHEXLEN] = '\0';
+};
+
+/* calculate H(A1) as per spec */
+static void 
+DigestCalcHA1(
+	IN char * pszAlg,
+	IN char * pszUserName,
+	IN char * pszRealm,
+	IN char * pszPassword,
+	IN char * pszNonce,
+	IN char * pszCNonce,
+	OUT HASHHEX SessionKey
+	)
+{
+	MD5_CTX Md5Ctx;
+	HASH HA1;
+
+	MD5Init(&Md5Ctx);
+	MD5Update(&Md5Ctx, pszUserName, strlen(pszUserName));
+	MD5Update(&Md5Ctx, ":", 1);
+	MD5Update(&Md5Ctx, pszRealm, strlen(pszRealm));
+	MD5Update(&Md5Ctx, ":", 1);
+	MD5Update(&Md5Ctx, pszPassword, strlen(pszPassword));
+	MD5Final(HA1, &Md5Ctx);
+	if (strcasecmp(pszAlg, "md5-sess") == 0) {
+
+		MD5Init(&Md5Ctx);
+		MD5Update(&Md5Ctx, HA1, HASHLEN);
+		MD5Update(&Md5Ctx, ":", 1);
+		MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
+		MD5Update(&Md5Ctx, ":", 1);
+		MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
+		MD5Final(HA1, &Md5Ctx);
+	};
+	CvtHex(HA1, SessionKey);
+}
+
+/* calculate request-digest/response-digest as per HTTP Digest spec */
+static void 
+DigestCalcResponse(
+	IN HASHHEX HA1,           /* H(A1) */
+	IN char * pszNonce,       /* nonce from server */
+	IN char * pszNonceCount,  /* 8 hex digits */
+	IN char * pszCNonce,      /* client nonce */
+	IN char * pszQop,         /* qop-value: "", "auth", "auth-int" */
+	IN char * pszMethod,      /* method from the request */
+	IN char * pszDigestUri,   /* requested URL */
+	IN HASHHEX HEntity,       /* H(entity body) if qop="auth-int" */
+	OUT HASHHEX Response      /* request-digest or response-digest */
+	)
+{
+/*	DEBUG(fprintf(stderr, 
+		      "Calc: HA1[%s] Nonce[%s] qop[%s] method[%s] URI[%s]\n",
+		      HA1, pszNonce, pszQop, pszMethod, pszDigestUri));*/
+	MD5_CTX Md5Ctx;
+	HASH HA2;
+	HASH RespHash;
+	HASHHEX HA2Hex;
+
+	// calculate H(A2)
+	MD5Init(&Md5Ctx);
+	MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod));
+	MD5Update(&Md5Ctx, ":", 1);
+	MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri));
+	if (strcasecmp(pszQop, "auth-int") == 0) {
+		MD5Update(&Md5Ctx, ":", 1);
+		MD5Update(&Md5Ctx, HEntity, HASHHEXLEN);
+	};
+	MD5Final(HA2, &Md5Ctx);
+	CvtHex(HA2, HA2Hex);
+
+	// calculate response
+	MD5Init(&Md5Ctx);
+	MD5Update(&Md5Ctx, HA1, HASHHEXLEN);
+	MD5Update(&Md5Ctx, ":", 1);
+	MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
+	MD5Update(&Md5Ctx, ":", 1);
+	if (*pszQop) {
+		MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount));
+		MD5Update(&Md5Ctx, ":", 1);
+		MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
+		MD5Update(&Md5Ctx, ":", 1);
+		MD5Update(&Md5Ctx, pszQop, strlen(pszQop));
+		MD5Update(&Md5Ctx, ":", 1);
+	};
+	MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN);
+	MD5Final(RespHash, &Md5Ctx);
+	CvtHex(RespHash, Response);
+}
+
+/* 
+ * Generate/Send a Digest authorization header 
+ * This looks like: [Proxy-]Authorization: credentials
+ *
+ *  credentials      = "Digest" digest-response
+ *  digest-response  = 1#( username | realm | nonce | digest-uri
+ *                      | response | [ algorithm ] | [cnonce] |
+ *                      [opaque] | [message-qop] |
+ *                          [nonce-count]  | [auth-param] )
+ *  username         = "username" "=" username-value
+ *  username-value   = quoted-string
+ *  digest-uri       = "uri" "=" digest-uri-value
+ *  digest-uri-value = request-uri   ; As specified by HTTP/1.1
+ *  message-qop      = "qop" "=" qop-value
+ *  cnonce           = "cnonce" "=" cnonce-value
+ *  cnonce-value     = nonce-value
+ *  nonce-count      = "nc" "=" nc-value
+ *  nc-value         = 8LHEX
+ *  response         = "response" "=" request-digest
+ *  request-digest = <"> 32LHEX <">
+ */
+static int
+http_digest_auth(conn_t *conn, const char *hdr, http_auth_challenge_t *c,
+		 http_auth_params_t *parms, struct url *url)
+{
+	int r;
+	char noncecount[10];
+	char cnonce[40];
+	char *options = 0;
+
+	if (!c->realm || !c->nonce) {
+		DEBUG(fprintf(stderr, "realm/nonce not set in challenge\n"));
+		return(-1);
+	}
+	if (!c->algo) 
+		c->algo = strdup("");
+
+	if (asprintf(&options, "%s%s%s%s", 
+		     *c->algo? ",algorithm=" : "", c->algo,
+		     c->opaque? ",opaque=" : "", c->opaque?c->opaque:"")== -1)
+		return (-1);
+
+	if (!c->qop) {
+		c->qop = strdup("");
+		*noncecount = 0;
+		*cnonce = 0;
+	} else {
+		c->nc++;
+		sprintf(noncecount, "%08x", c->nc);
+		/* We don't try very hard with the cnonce ... */
+		sprintf(cnonce, "%x%lx", getpid(), (unsigned long)time(0));
+	}
+
+	HASHHEX HA1;
+	DigestCalcHA1(c->algo, parms->user, c->realm,
+		      parms->password, c->nonce, cnonce, HA1);
+	DEBUG(fprintf(stderr, "HA1: [%s]\n", HA1));
+	HASHHEX digest;
+	DigestCalcResponse(HA1, c->nonce, noncecount, cnonce, c->qop,
+			   "GET", url->doc, "", digest);
+
+	if (c->qop[0]) {
+		r = http_cmd(conn, "%s: Digest username=\"%s\",realm=\"%s\","
+			     "nonce=\"%s\",uri=\"%s\",response=\"%s\","
+			     "qop=\"auth\", cnonce=\"%s\", nc=%s%s",
+			     hdr, parms->user, c->realm, 
+			     c->nonce, url->doc, digest,
+			     cnonce, noncecount, options);
+	} else {
+		r = http_cmd(conn, "%s: Digest username=\"%s\",realm=\"%s\","
+			     "nonce=\"%s\",uri=\"%s\",response=\"%s\"%s",
+			     hdr, parms->user, c->realm, 
+			     c->nonce, url->doc, digest, options);
+	}
+	if (options)
+		free(options);
+	return (r);
+}
+
 /*
  * Encode username and password
  */
@@ -627,8 +1287,8 @@ http_basic_auth(conn_t *conn, const char *hdr, const char *usr, const char *pwd)
 	char *upw, *auth;
 	int r;
 
-	DEBUG(fprintf(stderr, "usr: [%s]\n", usr));
-	DEBUG(fprintf(stderr, "pwd: [%s]\n", pwd));
+	DEBUG(fprintf(stderr, "basic: usr: [%s]\n", usr));
+	DEBUG(fprintf(stderr, "basic: pwd: [%s]\n", pwd));
 	if (asprintf(&upw, "%s:%s", usr, pwd) == -1)
 		return (-1);
 	auth = http_base64(upw);
@@ -641,33 +1301,49 @@ http_basic_auth(conn_t *conn, const char *hdr, const char *usr, const char *pwd)
 }
 
 /*
- * Send an authorization header
+ * Chose the challenge to answer and call the appropriate routine to 
+ * produce the header.
  */
 static int
-http_authorize(conn_t *conn, const char *hdr, const char *p)
+http_authorize(conn_t *conn, const char *hdr, http_auth_challenges_t *cs,
+	       http_auth_params_t *parms, struct url *url)
 {
-	/* basic authorization */
-	if (strncasecmp(p, "basic:", 6) == 0) {
-		char *user, *pwd, *str;
-		int r;
+	http_auth_challenge_t *basic = NULL;
+	http_auth_challenge_t *digest = NULL;
+	int i;
 
-		/* skip realm */
-		for (p += 6; *p && *p != ':'; ++p)
-			/* nothing */ ;
-		if (!*p || strchr(++p, ':') == NULL)
-			return (-1);
-		if ((str = strdup(p)) == NULL)
-			return (-1); /* XXX */
-		user = str;
-		pwd = strchr(str, ':');
-		*pwd++ = '\0';
-		r = http_basic_auth(conn, hdr, user, pwd);
-		free(str);
-		return (r);
+	/* If user or pass are null we're not happy */
+	if (!parms->user || !parms->password) {
+		DEBUG(fprintf(stderr, "NULL usr or pass\n"));
+		return (-1);
 	}
-	return (-1);
-}
 
+	/* Look for a Digest and a Basic challenge */
+	for (i = 0; i < cs->count; i++) {
+		if (cs->challenges[i]->scheme == HTTPAS_BASIC)
+			basic = cs->challenges[i];
+		if (cs->challenges[i]->scheme == HTTPAS_DIGEST)
+			digest = cs->challenges[i];
+	}
+
+	/* Error if "Digest" was specified and there is no Digest challenge */
+	if (!digest && (parms->scheme && 
+			!strcasecmp(parms->scheme, "digest"))) {
+		DEBUG(fprintf(stderr, 
+			      "Digest auth in env, not supported by peer\n"));
+		return (-1);
+	}
+	/* 
+         * If "basic" was specified in the environment, or there is no Digest
+	 * challenge, do the basic thing. Don't need a challenge for this,
+	 * so no need to check basic!=NULL 
+	 */
+	if (!digest || (parms->scheme && !strcasecmp(parms->scheme,"basic")))
+		return (http_basic_auth(conn,hdr,parms->user,parms->password));
+
+	/* Else, prefer digest. We just checked that it's not NULL */
+	return (http_digest_auth(conn, hdr, digest, parms, url));
+}
 
 /*****************************************************************************
  * Helper functions for connecting to a server or proxy
@@ -797,13 +1473,13 @@ http_print_html(FILE *out, FILE *in)
  */
 FILE *
 http_request(struct url *URL, const char *op, struct url_stat *us,
-    struct url *purl, const char *flags)
+	struct url *purl, const char *flags)
 {
 	char timebuf[80];
 	char hbuf[MAXHOSTNAMELEN + 7], *host;
 	conn_t *conn;
 	struct url *url, *new;
-	int chunked, direct, ims, need_auth, noredirect, verbose;
+	int chunked, direct, ims, noredirect, verbose;
 	int e, i, n, val;
 	off_t offset, clength, length, size;
 	time_t mtime;
@@ -811,6 +1487,14 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 	FILE *f;
 	hdr_t h;
 	struct tm *timestruct;
+	http_headerbuf_t headerbuf;
+	http_auth_challenges_t server_challenges;
+	http_auth_challenges_t proxy_challenges;
+
+	/* The following calls don't allocate anything */
+	init_http_headerbuf(&headerbuf); 
+	init_http_auth_challenges(&server_challenges);
+	init_http_auth_challenges(&proxy_challenges);
 
 	direct = CHECK_FLAG('d');
 	noredirect = CHECK_FLAG('A');
@@ -830,7 +1514,6 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 	i = 0;
 
 	e = HTTP_PROTOCOL_ERROR;
-	need_auth = 0;
 	do {
 		new = NULL;
 		chunked = 0;
@@ -895,27 +1578,67 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 		/* virtual host */
 		http_cmd(conn, "Host: %s", host);
 
-		/* proxy authorization */
-		if (purl) {
-			if (*purl->user || *purl->pwd)
-				http_basic_auth(conn, "Proxy-Authorization",
-				    purl->user, purl->pwd);
-			else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL && *p != '\0')
-				http_authorize(conn, "Proxy-Authorization", p);
+		/* 
+                 * Proxy authorization: we only send auth after we received
+		 * a 407 error. We do not first try basic anyway (changed 
+                 * when support was added for digest-auth)
+                 */
+		if (purl && proxy_challenges.valid) {
+			http_auth_params_t aparams;
+			init_http_auth_params(&aparams);
+			if (*purl->user || *purl->pwd) {
+				aparams.user = purl->user ? 
+					strdup(purl->user) : strdup("");
+				aparams.password = purl->pwd?
+					strdup(purl->pwd) : strdup("");
+			} else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL && 
+				   *p != '\0') {
+				if (http_authfromenv(p, &aparams) < 0) {
+					http_seterr(HTTP_NEED_PROXY_AUTH);
+					goto ouch;
+				}
+			}
+			http_authorize(conn, "Proxy-Authorization", 
+				       &proxy_challenges, &aparams, url);
+			clean_http_auth_params(&aparams);
 		}
 
-		/* server authorization */
-		if (need_auth || *url->user || *url->pwd) {
-			if (*url->user || *url->pwd)
-				http_basic_auth(conn, "Authorization", url->user, url->pwd);
-			else if ((p = getenv("HTTP_AUTH")) != NULL && *p != '\0')
-				http_authorize(conn, "Authorization", p);
-			else if (fetchAuthMethod && fetchAuthMethod(url) == 0) {
-				http_basic_auth(conn, "Authorization", url->user, url->pwd);
+		/* 
+                 * Server authorization: we never send "a priori"
+		 * Basic auth, which used to be done if user/pass were
+		 * set in the url. This would be weird because we'd send the
+		 * password in the clear even if Digest is finally to be 
+		 * used (it would have made more sense for the
+		 * pre-digest version to do this when Basic was specified 
+                 * in the environment) 
+                 */
+		if (server_challenges.valid) {
+			http_auth_params_t aparams;
+			init_http_auth_params(&aparams);
+			if (*url->user || *url->pwd) {
+				aparams.user = url->user ? 
+					strdup(url->user) : strdup("");
+				aparams.password = url->pwd ? 
+					strdup(url->pwd) : strdup("");
+			} else if ((p = getenv("HTTP_AUTH")) != NULL && 
+				   *p != '\0') {
+				if (http_authfromenv(p, &aparams) < 0) {
+					http_seterr(HTTP_NEED_AUTH);
+					goto ouch;
+				}
+			} else if (fetchAuthMethod && 
+				   fetchAuthMethod(url) == 0) {
+				aparams.user = url->user ? 
+					strdup(url->user) : strdup("");
+				aparams.password = url->pwd ? 
+					strdup(url->pwd) : strdup("");
 			} else {
 				http_seterr(HTTP_NEED_AUTH);
 				goto ouch;
 			}
+			http_authorize(conn, "Authorization", 
+				       &server_challenges, &aparams, url);
+			clean_http_auth_params(&aparams);
 		}
 
 		/* other headers */
@@ -965,7 +1688,7 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 			 */
 			break;
 		case HTTP_NEED_AUTH:
-			if (need_auth) {
+			if (server_challenges.valid) {
 				/*
 				 * We already sent out authorization code,
 				 * so there's nothing more we can do.
@@ -978,13 +1701,18 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 				fetch_info("server requires authorization");
 			break;
 		case HTTP_NEED_PROXY_AUTH:
-			/*
-			 * If we're talking to a proxy, we already sent
-			 * our proxy authorization code, so there's
-			 * nothing more we can do.
-			 */
-			http_seterr(conn->err);
-			goto ouch;
+			if (proxy_challenges.valid) {
+				/*
+				 * We already sent our proxy
+				 * authorization code, so there's
+				 * nothing more we can do. */
+				http_seterr(conn->err);
+				goto ouch;
+			}
+			/* try again, but send the password this time */
+			if (verbose)
+				fetch_info("proxy requires authorization");
+			break;
 		case HTTP_BAD_RANGE:
 			/*
 			 * This can happen if we ask for 0 bytes because
@@ -1004,9 +1732,13 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 			/* fall through so we can get the full error message */
 		}
 
-		/* get headers */
+		/* get headers. http_next_header expects one line readahead */
+		if (fetch_getln(conn) == -1) {
+		    fetch_syserr();
+		    goto ouch;
+		}
 		do {
-			switch ((h = http_next_header(conn, &p))) {
+		    switch ((h = http_next_header(conn, &headerbuf, &p))) {
 			case hdr_syserror:
 				fetch_syserr();
 				goto ouch;
@@ -1054,7 +1786,12 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 			case hdr_www_authenticate:
 				if (conn->err != HTTP_NEED_AUTH)
 					break;
-				/* if we were smarter, we'd check the method and realm */
+				http_parse_authenticate(p, &server_challenges);
+				break;
+			case hdr_proxy_authenticate:
+				if (conn->err != HTTP_NEED_PROXY_AUTH)
+					break;
+				http_parse_authenticate(p, &proxy_challenges);
 				break;
 			case hdr_end:
 				/* fall through */
@@ -1065,9 +1802,17 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 		} while (h > hdr_end);
 
 		/* we need to provide authentication */
-		if (conn->err == HTTP_NEED_AUTH) {
+		if (conn->err == HTTP_NEED_AUTH || 
+		    conn->err == HTTP_NEED_PROXY_AUTH) {
 			e = conn->err;
-			need_auth = 1;
+			if ((conn->err == HTTP_NEED_AUTH && 
+			     !server_challenges.valid) || 
+			    (conn->err == HTTP_NEED_PROXY_AUTH && 
+			     !proxy_challenges.valid)) {
+				/* 401/7 but no www/proxy-authenticate ?? */
+				DEBUG(fprintf(stderr, "401/7 and no auth header\n"));
+				goto ouch;
+			}
 			fetch_close(conn);
 			conn = NULL;
 			continue;
@@ -1096,7 +1841,7 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 
 		/* all other cases: we got a redirect */
 		e = conn->err;
-		need_auth = 0;
+		clean_http_auth_challenges(&server_challenges);
 		fetch_close(conn);
 		conn = NULL;
 		if (!new) {
@@ -1172,7 +1917,9 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
 		fclose(f);
 		f = NULL;
 	}
-
+	clean_http_headerbuf(&headerbuf);
+	clean_http_auth_challenges(&server_challenges);
+	clean_http_auth_challenges(&proxy_challenges);
 	return (f);
 
 ouch:
@@ -1182,6 +1929,9 @@ ouch:
 		fetchFreeURL(purl);
 	if (conn != NULL)
 		fetch_close(conn);
+	clean_http_headerbuf(&headerbuf);
+	clean_http_auth_challenges(&server_challenges);
+	clean_http_auth_challenges(&proxy_challenges);
 	return (NULL);
 }
 

From aae70d8491e2f3e9f3bb95be67f3016f4a515f52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= 
Date: Tue, 26 Jan 2010 15:07:47 +0000
Subject: [PATCH 1298/2592] insta-mfh r203028 (doc update)

---
 lib/libfetch/fetch.3 | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/lib/libfetch/fetch.3 b/lib/libfetch/fetch.3
index 9b312b0a1f1..aaf1a8da408 100644
--- a/lib/libfetch/fetch.3
+++ b/lib/libfetch/fetch.3
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd December 14, 2008
+.Dd January 26, 2010
 .Dt FETCH 3
 .Os
 .Sh NAME
@@ -509,9 +509,13 @@ Specifies HTTP authorization parameters as a colon-separated list of
 items.
 The first and second item are the authorization scheme and realm
 respectively; further items are scheme-dependent.
-Currently, only basic authorization is supported.
+Currently, the
+.Dq basic
+and
+.Dq digest
+authorization methods are supported.
 .Pp
-Basic authorization requires two parameters: the user name and
+Both methods require two parameters: the user name and
 password, in that order.
 .Pp
 This variable is only used if the server requires authorization and
@@ -656,12 +660,14 @@ The
 .Nm fetch
 library was mostly written by
 .An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org
-with numerous suggestions from
+with numerous suggestions and contributions from
 .An Jordan K. Hubbard Aq jkh@FreeBSD.org ,
-.An Eugene Skepner Aq eu@qub.com
-and other
-.Fx
-developers.
+.An Eugene Skepner Aq eu@qub.com ,
+.An Hajimu Umemoto Aq ume@FreeBSD.org ,
+.An Henry Whincup Aq henry@techiebod.com ,
+.An Jukka A. Ukkonen Aq jau@iki.fi ,
+.An Jean-Fran\(,cois Dockes Aq jf@dockes.org
+and others.
 It replaces the older
 .Nm ftpio
 library written by

From 5915044ff5d9fd4a18d55b5c50be94daf0aa36e6 Mon Sep 17 00:00:00 2001
From: Doug Barton 
Date: Tue, 26 Jan 2010 18:24:13 +0000
Subject: [PATCH 1299/2592] MFC r202817:

Make -U once again honor -D after my change to consolidate setting
of MTREEDB with DESTDIR.

PR:		bin/143089
Submitted by:	Anton Yuzhaninov 
---
 usr.sbin/mergemaster/mergemaster.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh
index 1b0753b8925..d21d80bcfd1 100755
--- a/usr.sbin/mergemaster/mergemaster.sh
+++ b/usr.sbin/mergemaster/mergemaster.sh
@@ -261,11 +261,6 @@ if [ -r "$HOME/.mergemasterrc" ]; then
   . "$HOME/.mergemasterrc"
 fi
 
-# Assign the location of the mtree database
-#
-MTREEDB=${MTREEDB:-${DESTDIR}/var/db}
-MTREEFILE="${MTREEDB}/mergemaster.mtree"
-
 # Check the command line options
 #
 while getopts ":ascrvhipCPm:t:du:w:D:A:FU" COMMAND_LINE_ARGUMENT ; do
@@ -342,6 +337,11 @@ while getopts ":ascrvhipCPm:t:du:w:D:A:FU" COMMAND_LINE_ARGUMENT ; do
   esac
 done
 
+# Assign the location of the mtree database
+#
+MTREEDB=${MTREEDB:-${DESTDIR}/var/db}
+MTREEFILE="${MTREEDB}/mergemaster.mtree"
+
 # Don't force the user to set this in the mergemaster rc file
 if [ -n "${PRESERVE_FILES}" -a -z "${PRESERVE_FILES_DIR}" ]; then
   PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S`

From ce77b9149af5bc8eeaddcfaddb7a0036f53a73f1 Mon Sep 17 00:00:00 2001
From: "Bjoern A. Zeeb" 
Date: Wed, 27 Jan 2010 09:45:07 +0000
Subject: [PATCH 1300/2592] MFC r202915:   Correct a typo.

  Submitted by: kensmith
---
 sys/netinet6/in6_pcb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index d40a9e35101..7995b43ab0b 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -332,7 +332,7 @@ in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam,
 	 * Do not update this earlier, in case we return with an error.
 	 *
 	 * XXX: this in6_selectsrc result might replace the bound local
-	 * aaddress with the address specified by setsockopt(IPV6_PKTINFO).
+	 * address with the address specified by setsockopt(IPV6_PKTINFO).
 	 * Is it the intended behavior?
 	 */
 	*plocal_addr6 = in6a;

From 1f9b7387d81636be1750a34fbf52fbbf68378aad Mon Sep 17 00:00:00 2001
From: Joerg Wunsch 
Date: Wed, 27 Jan 2010 10:32:02 +0000
Subject: [PATCH 1301/2592] Merge of r202870,202898:

Overhaul of the pcii driver:

. Properly allocate all IO space resources.  These cards scatter their
  IO addresses over a range of 0x1600 bytes, and they require an
  additional address for "special interrupt handling".

. Implement the "special interrupt handling" per the GPIB-PCIIA
  Technical Reference Manual; this was apparently not declared for the
  clone card this driver has been originally implemented for, but it
  turned out to be needed for both, an original NI brand PCII/PCIIA
  card as well as the Axiom AX5488 clone.

. Add some diagnostic messages for various resource allocation etc.
  failures during probe.

. Add some comments about the structure of the IO address space that
  is used by these cards.
---
 sys/dev/ieee488/pcii.c    | 104 +++++++++++++++++++++++++++++++++-----
 sys/dev/ieee488/tnt4882.c |   3 ++
 sys/dev/ieee488/upd7210.c |  38 ++++++++++----
 sys/dev/ieee488/upd7210.h |   2 +
 4 files changed, 124 insertions(+), 23 deletions(-)

diff --git a/sys/dev/ieee488/pcii.c b/sys/dev/ieee488/pcii.c
index 7e5e23ec0a0..7e924328ba6 100644
--- a/sys/dev/ieee488/pcii.c
+++ b/sys/dev/ieee488/pcii.c
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2005 Poul-Henning Kamp 
+ * Copyright (c) 2010 Joerg Wunsch 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,6 +34,8 @@
  *
  *    Tested and known working:
  *	"B&C Microsystems PC488A-0"
+ *	"National Instruments GPIB-PCII/PCIIA" (in PCIIa mode)
+ *	"Axiom AX5488"
  *
  */
 
@@ -56,7 +59,7 @@ __FBSDID("$FreeBSD$");
 
 struct pcii_softc {
 	int foo;
-	struct resource	*res[3];
+	struct resource	*res[11];
 	void *intr_handler;
 	struct upd7210	upd7210;
 };
@@ -79,6 +82,14 @@ static struct resource_spec pcii_res_spec[] = {
 	{ SYS_RES_IRQ,		0, RF_ACTIVE | RF_SHAREABLE},
 	{ SYS_RES_DRQ,		0, RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL},
 	{ SYS_RES_IOPORT,	0, RF_ACTIVE},
+	{ SYS_RES_IOPORT,	1, RF_ACTIVE},
+	{ SYS_RES_IOPORT,	2, RF_ACTIVE},
+	{ SYS_RES_IOPORT,	3, RF_ACTIVE},
+	{ SYS_RES_IOPORT,	4, RF_ACTIVE},
+	{ SYS_RES_IOPORT,	5, RF_ACTIVE},
+	{ SYS_RES_IOPORT,	6, RF_ACTIVE},
+	{ SYS_RES_IOPORT,	7, RF_ACTIVE},
+	{ SYS_RES_IOPORT,	8, RF_ACTIVE | RF_SHAREABLE},
 	{ -1, 0, 0 }
 };
 
@@ -92,7 +103,7 @@ static int
 pcii_probe(device_t dev)
 {
 	int rid, i, j;
-	u_long start, count;
+	u_long start, count, addr;
 	int error = 0;
 	struct pcii_softc *sc;
 
@@ -102,30 +113,90 @@ pcii_probe(device_t dev)
 	rid = 0;
 	if (bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count) != 0)
 		return ENXIO;
-	if ((start & 0x3ff) != 0x2e1)
+	/*
+	 * The PCIIA decodes a fixed pattern of 0x2e1 for the lower 10
+	 * address bits A0 ... A9.  Bits A10 through A12 are used by
+	 * the µPD7210 register select lines.  This makes the
+	 * individual 7210 register being 0x400 bytes apart in the ISA
+	 * bus address space.  Address bits A13 and A14 are compared
+	 * to a DIP switch setting on the card, allowing for up to 4
+	 * different cards being installed (at base addresses 0x2e1,
+	 * 0x22e1, 0x42e1, and 0x62e1, respectively).  A15 has been
+	 * used to select an optional on-board time-of-day clock chip
+	 * (MM58167A) on the original PCIIA rather than the µPD7210
+	 * (which is not implemented on later boards).  The
+	 * documentation states the respective addresses for that chip
+	 * should be handled as reserved addresses, which we don't do
+	 * (right now).  Finally, the IO addresses 0x2f0 ... 0x2f7 for
+	 * a "special interrupt handling feature" (re-enable
+	 * interrupts so the IRQ can be shared).
+	 *
+	 * Usually, the user will only set the base address in the
+	 * device hints, so we handle the rest here.
+	 *
+	 * (Source: GPIB-PCIIA Technical Reference Manual, September
+	 * 1989 Edition, National Instruments.)
+	 */
+	if ((start & 0x3ff) != 0x2e1) {
+		if (bootverbose)
+			printf("pcii_probe: PCIIA base address 0x%lx not "
+			       "0x2e1/0x22e1/0x42e1/0x62e1\n",
+			       start);
 		return (ENXIO);
-	count = 1;
-	if (bus_set_resource(dev, SYS_RES_IOPORT, rid, start, count) != 0)
+	}
+
+	for (rid = 0, addr = start; rid < 8; rid++, addr += 0x400) {
+		if (bus_set_resource(dev, SYS_RES_IOPORT, rid, addr, 1) != 0) {
+			printf("pcii_probe: could not set IO port 0x%lx\n",
+			       addr);
+			return (ENXIO);
+		}
+	}
+	if (bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &count) != 0) {
+		printf("pcii_probe: cannot obtain IRQ level\n");
 		return ENXIO;
+	}
+	if (start > 7) {
+		printf("pcii_probe: IRQ level %lu too high\n", start);
+		return ENXIO;
+	}
+
+	if (bus_set_resource(dev, SYS_RES_IOPORT, 8, 0x2f0 + start, 1) != 0) {
+		printf("pcii_probe: could not set IO port 0x%3lx\n",
+		       0x2f0 + start);
+		return (ENXIO);
+	}
+
 	error = bus_alloc_resources(dev, pcii_res_spec, sc->res);
-	if (error)
+	if (error) {
+		printf("pcii_probe: Could not allocate resources\n");
 		return (error);
+	}
 	error = ENXIO;
+	/*
+	 * Perform some basic tests on the µPD7210 registers.  At
+	 * least *some* register must read different from 0x00 or
+	 * 0xff.
+	 */
 	for (i = 0; i < 8; i++) {
-		j = bus_read_1(sc->res[2], i * 0x400);
+		j = bus_read_1(sc->res[2 + i], 0);
 		if (j != 0x00 && j != 0xff)
 			error = 0;
 	}
+	/* SPSR/SPMR read/write test */
 	if (!error) {
-		bus_write_1(sc->res[2], 3 * 0x400, 0x55);
-		if (bus_read_1(sc->res[2], 3 * 0x400) != 0x55)
+		bus_write_1(sc->res[2 + 3], 0, 0x55);
+		if (bus_read_1(sc->res[2 + 3], 0) != 0x55)
 			error = ENXIO;
 	}
 	if (!error) {
-		bus_write_1(sc->res[2], 3 * 0x400, 0xaa);
-		if (bus_read_1(sc->res[2], 3 * 0x400) != 0xaa)
+		bus_write_1(sc->res[2 + 3], 0, 0xaa);
+		if (bus_read_1(sc->res[2 + 3], 0) != 0xaa)
 			error = ENXIO;
 	}
+	if (error)
+		printf("pcii_probe: probe failure\n");
+
 	bus_release_resources(dev, pcii_res_spec, sc->res);
 	return (error);
 }
@@ -134,6 +205,7 @@ static int
 pcii_attach(device_t dev)
 {
 	struct pcii_softc *sc;
+	u_long		start, count;
 	int		unit;
 	int		rid;
 	int		error = 0;
@@ -144,6 +216,11 @@ pcii_attach(device_t dev)
 
 	device_set_desc(dev, "PCII IEEE-4888 controller");
 
+	if (bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &count) != 0) {
+		printf("pcii_attach: cannot obtain IRQ number\n");
+		return ENXIO;
+	}
+
 	error = bus_alloc_resources(dev, pcii_res_spec, sc->res);
 	if (error)
 		return (error);
@@ -157,9 +234,10 @@ pcii_attach(device_t dev)
 	}
 
 	for (rid = 0; rid < 8; rid++) {
-		sc->upd7210.reg_res[rid] = sc->res[2];
-		sc->upd7210.reg_offset[rid] = 0x400 * rid;
+		sc->upd7210.reg_res[rid] = sc->res[2 + rid];
+		sc->upd7210.reg_offset[rid] = 0;
 	}
+	sc->upd7210.irq_clear_res = sc->res[10];
 
 	if (sc->res[1] == NULL)
 		sc->upd7210.dmachan = -1;
diff --git a/sys/dev/ieee488/tnt4882.c b/sys/dev/ieee488/tnt4882.c
index 1f21731809c..a4222a671eb 100644
--- a/sys/dev/ieee488/tnt4882.c
+++ b/sys/dev/ieee488/tnt4882.c
@@ -309,6 +309,9 @@ tnt_attach(device_t dev)
 	/* No DMA help */
 	sc->upd7210.dmachan = -1;
 
+	/* No "special interrupt handling" needed here. */
+	sc->upd7210.irq_clear_res = NULL;
+
 	upd7210attach(&sc->upd7210);
 
 	return (0);
diff --git a/sys/dev/ieee488/upd7210.c b/sys/dev/ieee488/upd7210.c
index 27359e2a175..b245a650a91 100644
--- a/sys/dev/ieee488/upd7210.c
+++ b/sys/dev/ieee488/upd7210.c
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2005 Poul-Henning Kamp 
+ * Copyright (c) 2010 Joerg Wunsch 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -96,19 +97,36 @@ upd7210intr(void *arg)
 	mtx_lock(&u->mutex);
 	isr1 = upd7210_rd(u, ISR1);
 	isr2 = upd7210_rd(u, ISR2);
-	if (u->busy == 0 || u->irq == NULL || !u->irq(u, 1)) {
+	if (isr1 != 0 || isr2 != 0) {
+		if (u->busy == 0 || u->irq == NULL || !u->irq(u, 1)) {
 #if 0
-		printf("upd7210intr [%02x %02x %02x",
-		    upd7210_rd(u, DIR), isr1, isr2);
-		printf(" %02x %02x %02x %02x %02x] ",
-		    upd7210_rd(u, SPSR),
-		    upd7210_rd(u, ADSR),
-		    upd7210_rd(u, CPTR),
-		    upd7210_rd(u, ADR0),
+			printf("upd7210intr [%02x %02x %02x",
+			       upd7210_rd(u, DIR), isr1, isr2);
+			printf(" %02x %02x %02x %02x %02x] ",
+			       upd7210_rd(u, SPSR),
+			       upd7210_rd(u, ADSR),
+			       upd7210_rd(u, CPTR),
+			       upd7210_rd(u, ADR0),
 		    upd7210_rd(u, ADR1));
-		upd7210_print_isr(isr1, isr2);
-		printf("\n");
+			upd7210_print_isr(isr1, isr2);
+			printf("\n");
 #endif
+		}
+		/*
+		 * "special interrupt handling"
+		 *
+		 * In order to implement shared IRQs, the original
+		 * PCIIa uses IO locations 0x2f0 + (IRQ#) as an output
+		 * location.  If an ISR for a particular card has
+		 * detected this card triggered the IRQ, it must reset
+		 * the card's IRQ by writing (anything) to that IO
+		 * location.
+		 *
+		 * Some clones apparently don't implement this
+		 * feature, but National Instrument cards do.
+		 */
+		if (u->irq_clear_res != NULL)
+			bus_write_1(u->irq_clear_res, 0, 42);
 	}
 	mtx_unlock(&u->mutex);
 }
diff --git a/sys/dev/ieee488/upd7210.h b/sys/dev/ieee488/upd7210.h
index da1032c311b..9d619b78931 100644
--- a/sys/dev/ieee488/upd7210.h
+++ b/sys/dev/ieee488/upd7210.h
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2005 Poul-Henning Kamp 
+ * Copyright (c) 2010 Joerg Wunsch 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,6 +49,7 @@ typedef int upd7210_irq_t(struct upd7210 *, int);
 
 struct upd7210 {
 	struct resource		*reg_res[8];
+	struct resource		*irq_clear_res;
 	u_int			reg_offset[8];
 	int			dmachan;
 	int			unit;

From c14674316011322579b1274337857d63d611b5da Mon Sep 17 00:00:00 2001
From: Joerg Wunsch 
Date: Wed, 27 Jan 2010 10:42:34 +0000
Subject: [PATCH 1302/2592] Merge r202943: Add man pages for the gpib(4),
 pcii(4), and tnt4882(4) drivers.

---
 share/man/man4/Makefile  |  3 ++
 share/man/man4/gpib.4    | 67 +++++++++++++++++++++++++++
 share/man/man4/pcii.4    | 97 ++++++++++++++++++++++++++++++++++++++++
 share/man/man4/tnt4882.4 | 55 +++++++++++++++++++++++
 4 files changed, 222 insertions(+)
 create mode 100644 share/man/man4/gpib.4
 create mode 100644 share/man/man4/pcii.4
 create mode 100644 share/man/man4/tnt4882.4

diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index ded69130180..924488c1990 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -117,6 +117,7 @@ MAN=	aac.4 \
 	geom_linux_lvm.4 \
 	geom_uzip.4 \
 	gif.4 \
+	gpib.4 \
 	gre.4 \
 	harp.4 \
 	hatm.4 \
@@ -297,6 +298,7 @@ MAN=	aac.4 \
 	pci.4 \
 	pcib.4 \
 	pcic.4 \
+	pcii.4 \
 	pcm.4 \
 	pcn.4 \
 	pim.4 \
@@ -394,6 +396,7 @@ MAN=	aac.4 \
 	textdump.4 \
 	ti.4 \
 	tl.4 \
+	tnt4882.4 \
 	trm.4 \
 	tty.4 \
 	tun.4 \
diff --git a/share/man/man4/gpib.4 b/share/man/man4/gpib.4
new file mode 100644
index 00000000000..e5e7a1b48ab
--- /dev/null
+++ b/share/man/man4/gpib.4
@@ -0,0 +1,67 @@
+.\" Copyright (c) 2010, Joerg Wunsch
+.\" 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 January 24, 2010
+.Dt GPIB 4
+.Os
+.Sh NAME
+.Nm gpib
+.Nd General-Purpose Instrument Bus (GPIB) driver
+.Sh SYNOPSIS
+Either of the
+.Xr pcii 4
+or
+.Xr tnt4882 4
+drivers use this driver as the backend.
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for driving an IEEE-488 bus, also called
+IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument
+Bus), or GPIB (General Purpose Instrument Bus).
+The device can become either a listener, talker, controller, and
+in particular a master controller on the bus.
+.Sh FILES
+.Bl -tag -width /dev/gpibNNib
+.It Pa /dev/gpib Ns Em N Ns "ib"
+Main device node to access the driver.
+.It Pa /dev/gpib Ns Em N Ns "l"
+Listen-only entry to the driver.
+When opening, an instrument can send data to this device on the
+bus in an unaddressed mode, for example hard-copy printer data.
+.El
+.Sh SEE ALSO
+.\" .Xr libgpib 3 ,
+.Xr gpib 4 ,
+.Xr tnt4882 4
+.Sh HISTORY
+The
+.Nm
+driver was written by Poul-Henning Kamp, and first appeared in
+.Fx 5.4 .
+.Sh AUTHORS
+This manual page was written by
+.An J\(:org Wunsch .
diff --git a/share/man/man4/pcii.4 b/share/man/man4/pcii.4
new file mode 100644
index 00000000000..026d6963da0
--- /dev/null
+++ b/share/man/man4/pcii.4
@@ -0,0 +1,97 @@
+.\" Copyright (c) 2010, Joerg Wunsch
+.\" 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 January 24, 2010
+.Dt PCII 4
+.Os
+.Sh NAME
+.Nm pcii
+.Nd National Instruments PCIIA GPIB controller driver
+.Sh SYNOPSIS
+.Cd "device pcii"
+.Pp
+In
+.Pa /boot/device.hints :
+.Cd hint.pcii.0.at="isa"
+.Cd hint.pcii.0.port="0x2e1"
+.Cd hint.pcii.0.irq="7"
+.Cd hint.pcii.0.drq="1"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for driving an IEEE-488 bus, also called
+IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument
+Bus), or GPIB (General Purpose Instrument Bus).
+The driver supports National Instruments PCIIA cards (sometimes
+also refered to as PC2A) and compatibles.
+These cards use a NEC \(mcPD7210 controller IC as the main
+interface between the host computer and the instrument bus.
+.Ss IO memory space layout
+The PCIIA cards use a very specific IO memory space allocation layout.
+The address bits A0 through A9 (which have traditionally been the only
+address bits evaluated on IBM PC XT extension cards) are hardwired to
+address 0x2e1.
+Bits A10 through A12 are used by the \(mcPD7210 register select lines.
+This makes the individual 7210 registers being 0x400 bytes apart in the
+ISA bus address space.
+Address bits A13 and A14 are compared to a DIP switch setting on the
+card, allowing for up to 4 different cards being installed (at base
+addresses 0x2e1, 0x22e1, 0x42e1, and 0x62e1, respectively).
+A15 has been used to select an optional on-board time-of-day clock
+chip (MM58167A) on the original PCIIA rather than the \(mcPD7210
+(which is not implemented on later boards and clones).
+Finally, the IO addresses 0x2f0 ... 0x2f7 are used for a
+.Em special interrupt handling feature
+(re-enable interrupts so the IRQ can be shared), where actually only
+address 0x2f0 plus the actual IRQ level is required for each card.
+Some clones do not appear to require this special IRQ handling, and
+are thus likely to not support the shared IRQ feature.
+.Pp
+Only the base address of the card needs to be specified in the ISA
+device hints; the driver takes care to derive all other IO addresses
+needed during the probe phase.
+.Ss Supported cards
+The following cards are known to be supported:
+.Bl -bullet -offset indent
+.It
+B&C Microsystems PC488A-0
+.It
+National Instruments GPIB-PCII/PCIIA (in PCIIa mode)
+.It
+Axiom AX5488
+.El
+.Sh SEE ALSO
+.\" .Xr libgpib 3 ,
+.Xr gpib 4 ,
+.Xr device.hints 5
+.Sh HISTORY
+The
+.Nm
+driver was written by Poul-Henning Kamp, and first appeared in
+.Fx 5.4 .
+.Sh AUTHORS
+This manual page was written by
+.An J\(:org Wunsch .
diff --git a/share/man/man4/tnt4882.4 b/share/man/man4/tnt4882.4
new file mode 100644
index 00000000000..f96599a0f2a
--- /dev/null
+++ b/share/man/man4/tnt4882.4
@@ -0,0 +1,55 @@
+.\" Copyright (c) 2010, Joerg Wunsch
+.\" 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 January 24, 2010
+.Dt TNT4882 4
+.Os
+.Sh NAME
+.Nm tnt4882
+.Nd National Instruments TNT4882A GPIB controller driver
+.Sh SYNOPSIS
+.Cd "device tnt4882"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for driving an IEEE-488 bus, also called
+IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument
+Bus), or GPIB (General Purpose Instrument Bus).
+The driver supports National Instruments PCI GPIB cards using
+the TNT4882 bus interface chip.
+This chip emulates a NEC \(mcPD7210 controller IC as the main
+interface between the host computer and the instrument bus.
+.Sh SEE ALSO
+.\" .Xr libgpib 3 ,
+.Xr gpib 4 ,
+.Sh HISTORY
+The
+.Nm
+driver was written by Poul-Henning Kamp, and first appeared in
+.Fx 5.4 .
+.Sh AUTHORS
+This manual page was written by
+.An J\(:org Wunsch .

From 18fab66957432795458d8a217bfc86b810e4991f Mon Sep 17 00:00:00 2001
From: Gavin Atkinson 
Date: Wed, 27 Jan 2010 15:36:19 +0000
Subject: [PATCH 1303/2592] Merge r200318 from head:  add myself to
 calendar.freebsd.

---
 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..bb569e4df53 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -283,6 +283,7 @@
 11/18	Thomas Quinot  born in Paris, France, 1977
 11/19	Konstantin Belousov  born in Kiev, USSR, 1972
 11/20	Dmitry Morozovsky  born in Moscow, USSR, 1968
+11/20	Gavin Atkinson  born in Middlesbrough, United Kingdom, 1979
 11/23	Josef Lawrence Karthauser  born in Pembury, Kent, United Kingdom, 1972
 11/24	Andrey Zakhvatov  born in Chelyabinsk, Russian Federation, 1974
 11/24	Daniel Gerzo  born in Bratislava, Slovakia, 1986

From df4743bc4a05d26825b0a3a24aab9bf327f73501 Mon Sep 17 00:00:00 2001
From: Alberto Villa 
Date: Wed, 27 Jan 2010 18:12:22 +0000
Subject: [PATCH 1305/2592] - MFC r197788, r203040, r203045, r203048

Approved by:	tabthorpe (mentor)
---
 usr.bin/calendar/calendars/calendar.freebsd | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd
index bb569e4df53..6d56e5f37d9 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -158,6 +158,7 @@
 06/02	Jean-Marc Zucconi  born in Pontarlier, France, 1954
 06/02	Alexander Botero-Lowry  born in Austin, TX, USA, 1986
 06/03	CHOI Junho  born in Seoul, Korea, 1974
+06/03	Wesley Shields  born in Binghamton, NY, USA, 1981
 06/04	Julian Elischer  born in Perth, Australia, 1959
 06/04	Jason Evans  born in Greeley, Colorado, United States, 1973
 06/04	Justin Gibbs  born in San Pedro, California, United States, 1973
@@ -203,6 +204,7 @@
 07/22	Lukas Ertl  born in Weissenbach/Enns, Steiermark, Austria, 1976
 07/23	Sergey A. Osokin  born in Krasnogorsky, Stepnogorsk, Akmolinskaya region, Kazakhstan, 1972
 07/24	Alexander Nedotsukov  born in Ulyanovsk, Russian Federation, 1974
+07/24	Alberto Villa  born in Vercelli, Italy, 1987
 07/28	Jim Mock  born in Bethlehem, Pennsylvania, United States, 1974
 07/28	Tom Hukins  born in Manchester, United Kingdom, 1976
 07/29	Dirk Meyer  born in Kassel, Hessen, Germany, 1965
@@ -244,6 +246,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
@@ -253,6 +256,7 @@
 09/28	Alex Dupre  born in Milano, Italy, 1980
 09/29	Matthew Hunt  born in Johnstown, Pennsylvania, United States, 1976
 09/30	Hiten M. Pandya  born in Dar-es-Salaam, Tanzania, East Africa, 1986
+10/02	Beat Gaetzi  born in Zurich, Switzerland, 1980
 10/05	Hiroki Sato  born in Yamagata, Japan, 1977
 10/05	Chris Costello  born in Houston, Texas, United States, 1985
 10/09	Stefan Walter  born in Werne, Nordrhein-Westfalen, 1978

From ef096f9d2afecf448a1655996ca65037cd47dd9e Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Thu, 28 Jan 2010 02:33:20 +0000
Subject: [PATCH 1306/2592] MFC r200135:
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Make umount(8) WARNS=6 clean:
 - Cast delimiter width to integer [1]
 - Solve name conflicts against system header
 - Constify parameters to avoid qualifier conflict

PR:		bin/140017 [1]
Submitted by:	Ulrich Spörlein  [1]
Sponsored by:	iXsystems, Inc
---
 sbin/umount/Makefile            |  1 -
 sbin/umount/umount.c            | 55 +++++++++++++++++----------------
 usr.sbin/rpc.umntall/mounttab.c | 14 ++++-----
 3 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/sbin/umount/Makefile b/sbin/umount/Makefile
index 70ccc5a0662..e472b41de49 100644
--- a/sbin/umount/Makefile
+++ b/sbin/umount/Makefile
@@ -4,7 +4,6 @@
 
 PROG=	umount
 SRCS=	umount.c vfslist.c mounttab.c
-WARNS?=	0
 MAN=	umount.8
 
 MOUNT=	${.CURDIR}/../mount
diff --git a/sbin/umount/umount.c b/sbin/umount/umount.c
index cbacb4bcb25..32ffbb32701 100644
--- a/sbin/umount/umount.c
+++ b/sbin/umount/umount.c
@@ -75,7 +75,7 @@ char   **makevfslist (const char *);
 size_t	 mntinfo (struct statfs **);
 int	 namematch (struct addrinfo *);
 int	 parsehexfsid(const char *hex, fsid_t *fsid);
-int	 sacmp (struct sockaddr *, struct sockaddr *);
+int	 sacmp (void *, void *);
 int	 umountall (char **);
 int	 checkname (char *, char **);
 int	 umountfs(struct statfs *sfs);
@@ -225,7 +225,7 @@ umountall(char **typelist)
  * Do magic checks on mountpoint/device/fsid, and then call unmount(2).
  */
 int
-checkname(char *name, char **typelist)
+checkname(char *mntname, char **typelist)
 {
 	char buf[MAXPATHLEN];
 	struct statfs sfsbuf;
@@ -238,25 +238,25 @@ checkname(char *name, char **typelist)
 	/*
 	 * 1. Check if the name exists in the mounttable.
 	 */
-	sfs = checkmntlist(name);
+	sfs = checkmntlist(mntname);
 	/*
 	 * 2. Remove trailing slashes if there are any. After that
 	 * we look up the name in the mounttable again.
 	 */
 	if (sfs == NULL) {
-		len = strlen(name);
-		while (len > 1 && name[len - 1] == '/')
-			name[--len] = '\0';
-		sfs = checkmntlist(name);
+		len = strlen(mntname);
+		while (len > 1 && mntname[len - 1] == '/')
+			mntname[--len] = '\0';
+		sfs = checkmntlist(mntname);
 	}
 	/*
 	 * 3. Check if the deprecated NFS syntax with an '@' has been used
 	 * and translate it to the ':' syntax. Look up the name in the
 	 * mount table again.
 	 */
-	if (sfs == NULL && (delimp = strrchr(name, '@')) != NULL) {
-		snprintf(buf, sizeof(buf), "%s:%.*s", delimp + 1, delimp - name,
-		    name);
+	if (sfs == NULL && (delimp = strrchr(mntname, '@')) != NULL) {
+		snprintf(buf, sizeof(buf), "%s:%.*s", delimp + 1,
+		    (int)(delimp - mntname), mntname);
 		len = strlen(buf);
 		while (len > 1 && buf[len - 1] == '/')
 			buf[--len] = '\0';
@@ -271,28 +271,28 @@ checkname(char *name, char **typelist)
 	 * mount list and reality.
 	 * We also do this if an ambiguous mount point was specified.
 	 */
-	if (sfs == NULL || (getmntentry(NULL, name, NULL, FIND) != NULL &&
-	    getmntentry(NULL, name, NULL, CHECKUNIQUE) == NULL)) {
-		if (statfs(name, &sfsbuf) != 0) {
-			warn("%s: statfs", name);
-		} else if (stat(name, &sb) != 0) {
-			warn("%s: stat", name);
+	if (sfs == NULL || (getmntentry(NULL, mntname, NULL, FIND) != NULL &&
+	    getmntentry(NULL, mntname, NULL, CHECKUNIQUE) == NULL)) {
+		if (statfs(mntname, &sfsbuf) != 0) {
+			warn("%s: statfs", mntname);
+		} else if (stat(mntname, &sb) != 0) {
+			warn("%s: stat", mntname);
 		} else if (S_ISDIR(sb.st_mode)) {
-			/* Check that `name' is the root directory. */
+			/* Check that `mntname' is the root directory. */
 			dev = sb.st_dev;
-			snprintf(buf, sizeof(buf), "%s/..", name);
+			snprintf(buf, sizeof(buf), "%s/..", mntname);
 			if (stat(buf, &sb) != 0) {
 				warn("%s: stat", buf);
 			} else if (sb.st_dev == dev) {
 				warnx("%s: not a file system root directory",
-				    name);
+				    mntname);
 				return (1);
 			} else
 				sfs = &sfsbuf;
 		}
 	}
 	if (sfs == NULL) {
-		warnx("%s: unknown file system", name);
+		warnx("%s: unknown file system", mntname);
 		return (1);
 	}
 	if (checkvfsname(sfs->f_fstypename, typelist))
@@ -469,15 +469,16 @@ getmntentry(const char *fromname, const char *onname, fsid_t *fsid, dowhat what)
 }
 
 int
-sacmp(struct sockaddr *sa1, struct sockaddr *sa2)
+sacmp(void *sa1, void *sa2)
 {
 	void *p1, *p2;
 	int len;
 
-	if (sa1->sa_family != sa2->sa_family)
+	if (((struct sockaddr *)sa1)->sa_family !=
+	    ((struct sockaddr *)sa2)->sa_family)
 		return (1);
 
-	switch (sa1->sa_family) {
+	switch (((struct sockaddr *)sa1)->sa_family) {
 	case AF_INET:
 		p1 = &((struct sockaddr_in *)sa1)->sin_addr;
 		p2 = &((struct sockaddr_in *)sa2)->sin_addr;
@@ -520,18 +521,18 @@ namematch(struct addrinfo *ai)
 }
 
 struct statfs *
-checkmntlist(char *name)
+checkmntlist(char *mntname)
 {
 	struct statfs *sfs;
 	fsid_t fsid;
 
 	sfs = NULL;
-	if (parsehexfsid(name, &fsid) == 0)
+	if (parsehexfsid(mntname, &fsid) == 0)
 		sfs = getmntentry(NULL, NULL, &fsid, FIND);
 	if (sfs == NULL)
-		sfs = getmntentry(NULL, name, NULL, FIND);
+		sfs = getmntentry(NULL, mntname, NULL, FIND);
 	if (sfs == NULL)
-		sfs = getmntentry(name, NULL, NULL, FIND);
+		sfs = getmntentry(mntname, NULL, NULL, FIND);
 	return (sfs);
 }
 
diff --git a/usr.sbin/rpc.umntall/mounttab.c b/usr.sbin/rpc.umntall/mounttab.c
index 9d7fe2f89ed..9765f4f7fe2 100644
--- a/usr.sbin/rpc.umntall/mounttab.c
+++ b/usr.sbin/rpc.umntall/mounttab.c
@@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
 
 struct mtablist *mtabhead;
 
-static void badline(char *field, char *bad);
+static void badline(const char *field, const char *bad);
 
 /*
  * Add an entry to PATH_MOUNTTAB for each mounted NFS filesystem,
@@ -69,12 +69,12 @@ add_mtab(char *hostp, char *dirp) {
  * Read mounttab line for line and return struct mtablist.
  */
 int
-read_mtab() {
+read_mtab(void) {
 	struct mtablist **mtabpp, *mtabp;
 	char *hostp, *dirp, *cp;
 	char str[STRSIZ];
 	char *timep, *endp;
-	time_t time;
+	time_t actiontime;
 	u_long ultmp;
 	FILE *mtabfile;
 
@@ -86,7 +86,7 @@ read_mtab() {
 			return (0);
 		}
 	}
-	time = 0;
+	actiontime = 0;
 	mtabpp = &mtabhead;
 	while (fgets(str, STRSIZ, mtabfile) != NULL) {
 		cp = str;
@@ -113,13 +113,13 @@ read_mtab() {
 			badline("time", timep);
 			continue;
 		}
-		time = ultmp;
+		actiontime = ultmp;
 		if ((mtabp = malloc(sizeof (struct mtablist))) == NULL) {
 			syslog(LOG_ERR, "malloc");
 			fclose(mtabfile);
 			return (0);
 		}
-		mtabp->mtab_time = time;
+		mtabp->mtab_time = actiontime;
 		memmove(mtabp->mtab_host, hostp, MNTNAMLEN);
 		mtabp->mtab_host[MNTNAMLEN - 1] = '\0';
 		memmove(mtabp->mtab_dirp, dirp, MNTPATHLEN);
@@ -218,7 +218,7 @@ free_mtab() {
  * Print bad lines to syslog.
  */
 static void
-badline(char *field, char *bad) {
+badline(const char *field, const char *bad) {
 	syslog(LOG_ERR, "bad mounttab %s field '%s'", field,
 	    (bad == NULL) ? "" : bad);
 }

From fbbbfe0ba5006db319f43fa3f4af330bdc5388ea Mon Sep 17 00:00:00 2001
From: "George V. Neville-Neil" 
Date: Thu, 28 Jan 2010 16:48:44 +0000
Subject: [PATCH 1307/2592] MFC r196797:

Add ARP statistics to the kernel and netstat.
---
 sys/net/if_arp.h          | 27 ++++++++++++++++++++++++-
 sys/netinet/if_ether.c    | 21 +++++++++++++++++++-
 usr.bin/netstat/inet.c    | 42 +++++++++++++++++++++++++++++++++++++++
 usr.bin/netstat/main.c    |  4 ++++
 usr.bin/netstat/netstat.h |  1 +
 5 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/sys/net/if_arp.h b/sys/net/if_arp.h
index 1e18804ffde..2bb63582800 100644
--- a/sys/net/if_arp.h
+++ b/sys/net/if_arp.h
@@ -108,6 +108,31 @@ struct	arpcom {
 #define IFP2AC(ifp) ((struct arpcom *)(ifp->if_l2com))
 #define AC2IFP(ac) ((ac)->ac_ifp)
 
-#endif
+#endif /* _KERNEL */
+
+struct arpstat {
+	/* Normal things that happen: */
+	u_long txrequests;	/* # of ARP requests sent by this host. */
+	u_long txreplies;	/* # of ARP replies sent by this host. */
+	u_long rxrequests;	/* # of ARP requests received by this host. */
+	u_long rxreplies;	/* # of ARP replies received by this host. */
+	u_long received;	/* # of ARP packets received by this host. */
+
+	u_long arp_spares[4];	/* For either the upper or lower half. */
+	/* Abnormal event and error  counting: */
+	u_long dropped;		/* # of packets dropped waiting for a reply. */
+	u_long timeouts;	/* # of times with entries removed */
+				/* due to timeout. */
+	u_long dupips;		/* # of duplicate IPs detected. */
+};
+
+/*
+ * In-kernel consumers can use these accessor macros directly to update
+ * stats.
+ */
+#define	ARPSTAT_ADD(name, val)	V_arpstat.name += (val)
+#define	ARPSTAT_SUB(name, val)	V_arpstat.name -= (val)
+#define	ARPSTAT_INC(name)	ARPSTAT_ADD(name, 1)
+#define	ARPSTAT_DEC(name)	ARPSTAT_SUB(name, 1)
 
 #endif /* !_NET_IF_ARP_H_ */
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 47588b41132..4319035d72a 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$");
 
 SYSCTL_DECL(_net_link_ether);
 SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
+SYSCTL_NODE(_net_link_ether, PF_ARP, arp, CTLFLAG_RW, 0, "");
 
 VNET_DEFINE(int, useloopback) = 1;	/* use loopback interface for
 					 * local traffic */
@@ -91,11 +92,13 @@ 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)
 
 SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW,
 	&VNET_NAME(arpt_keep), 0,
@@ -110,6 +113,9 @@ SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, useloopback, CTLFLAG_RW,
 SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW,
 	&VNET_NAME(arp_proxyall), 0,
 	"Enable proxy ARP for all suitable requests");
+SYSCTL_VNET_STRUCT(_net_link_ether_arp, OID_AUTO, stats, CTLFLAG_RW,
+	&VNET_NAME(arpstat), arpstat,
+	"ARP statistics (struct arpstat, net/if_arp.h)");
 
 static void	arp_init(void);
 void		arprequest(struct ifnet *,
@@ -166,6 +172,7 @@ arptimer(void *arg)
 		return;
 	}
 	ifp = lle->lle_tbl->llt_ifp;
+	CURVNET_SET(ifp->if_vnet);
 	IF_AFDATA_LOCK(ifp);
 	LLE_WLOCK(lle);
 	if (lle->la_flags & LLE_STATIC)
@@ -174,6 +181,7 @@ arptimer(void *arg)
 		if (!callout_pending(&lle->la_timer) &&
 		    callout_active(&lle->la_timer)) {
 			(void) llentry_free(lle);
+			ARPSTAT_INC(timeouts);
 		} 
 #ifdef DIAGNOSTIC
 		else {
@@ -186,6 +194,7 @@ arptimer(void *arg)
 #endif
 	}
 	IF_AFDATA_UNLOCK(ifp);
+	CURVNET_RESTORE();
 }
 
 /*
@@ -247,6 +256,7 @@ arprequest(struct ifnet *ifp, struct in_addr *sip, struct in_addr  *tip,
 	sa.sa_len = 2;
 	m->m_flags |= M_BCAST;
 	(*ifp->if_output)(ifp, m, &sa, NULL);
+	ARPSTAT_INC(txrequests);
 }
 
 /*
@@ -348,8 +358,10 @@ retry:
 	 * latest one.
 	 */
 	if (m != NULL) {
-		if (la->la_hold != NULL)
+		if (la->la_hold != NULL) {
 			m_freem(la->la_hold);
+			ARPSTAT_INC(dropped);
+		}
 		la->la_hold = m;
 		if (renew == 0 && (flags & LLE_EXCLUSIVE)) {
 			flags &= ~LLE_EXCLUSIVE;
@@ -422,6 +434,7 @@ arpintr(struct mbuf *m)
 		ar = mtod(m, struct arphdr *);
 	}
 
+	ARPSTAT_INC(received);
 	switch (ntohs(ar->ar_pro)) {
 #ifdef INET
 	case ETHERTYPE_IP:
@@ -502,6 +515,9 @@ in_arpinput(struct mbuf *m)
 	(void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
 	(void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
 
+	if (op == ARPOP_REPLY)
+		ARPSTAT_INC(rxreplies);
+
 	/*
 	 * For a bridge, we want to check the address irrespective
 	 * of the receive interface. (This will change slightly
@@ -612,6 +628,7 @@ match:
 		   ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
 		   inet_ntoa(isaddr), ifp->if_xname);
 		itaddr = myaddr;
+		ARPSTAT_INC(dupips);
 		goto reply;
 	}
 	if (ifp->if_flags & IFF_STATICARP)
@@ -695,6 +712,7 @@ match:
 reply:
 	if (op != ARPOP_REQUEST)
 		goto drop;
+	ARPSTAT_INC(rxrequests);
 
 	if (itaddr.s_addr == myaddr.s_addr) {
 		/* Shortcut.. the receiving interface is the target. */
@@ -791,6 +809,7 @@ reply:
 	sa.sa_family = AF_ARP;
 	sa.sa_len = 2;
 	(*ifp->if_output)(ifp, m, &sa, NULL);
+	ARPSTAT_INC(txreplies);
 	return;
 
 drop:
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
index 8be6840d853..51b71c79aa9 100644
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -871,6 +872,47 @@ ip_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 #undef p1a
 }
 
+/*
+ * Dump ARP statistics structure.
+ */
+void
+arp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
+{
+	struct arpstat arpstat, zerostat;
+	size_t len = sizeof(arpstat);
+
+	if (live) {
+		if (zflag)
+			memset(&zerostat, 0, len);
+		if (sysctlbyname("net.link.ether.arp.stats", &arpstat, &len,
+		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
+			warn("sysctl: net.link.ether.arp.stats");
+			return;
+		}
+	} else
+		kread(off, &arpstat, len);
+
+	printf("%s:\n", name);
+
+#define	p(f, m) if (arpstat.f || sflag <= 1) \
+    printf(m, arpstat.f, plural(arpstat.f))
+#define	p2(f, m) if (arpstat.f || sflag <= 1) \
+    printf(m, arpstat.f, pluralies(arpstat.f))
+
+	p(txrequests, "\t%lu ARP request%s sent\n");
+	p2(txreplies, "\t%lu ARP repl%s sent\n");
+	p(rxrequests, "\t%lu ARP request%s received\n");
+	p2(rxreplies, "\t%lu ARP repl%s received\n");
+	p(received, "\t%lu ARP packet%s received\n");
+	p(dropped, "\t%lu total packet%s dropped due to no ARP entry\n");
+	p(timeouts, "\t%lu ARP entry%s timed out\n");
+	p(dupips, "\t%lu Duplicate IP%s seen\n");
+#undef p
+#undef p2
+}
+
+
+
 static	const char *icmpnames[ICMP_MAXTYPE + 1] = {
 	"echo reply",			/* RFC 792 */
 	"#1",
diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c
index 8b25ff520b5..ebbe1d24fbf 100644
--- a/usr.bin/netstat/main.c
+++ b/usr.bin/netstat/main.c
@@ -184,6 +184,8 @@ static struct nlist nl[] = {
 	{ .n_name = "_sctpstat" },
 #define	N_MFCTABLESIZE	54
 	{ .n_name = "_mfctablesize" },
+#define N_ARPSTAT       55
+	{ .n_name = "_arpstat" },
 	{ .n_name = NULL },
 };
 
@@ -232,6 +234,8 @@ struct protox {
 	  carp_stats,	NULL,		"carp",	1,	0 },
 	{ -1,		N_PFSYNCSTAT,	1,	NULL,
 	  pfsync_stats,	NULL,		"pfsync", 1,	0 },
+	{ -1,		N_ARPSTAT,	1,	NULL,
+	  arp_stats,	NULL,		"arp", 1,	0 },
 	{ -1,		-1,		0,	NULL,
 	  NULL,		NULL,		NULL,	0,	0 }
 };
diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h
index 483bd6c43ef..f834495e32b 100644
--- a/usr.bin/netstat/netstat.h
+++ b/usr.bin/netstat/netstat.h
@@ -75,6 +75,7 @@ void	udp_stats(u_long, const char *, int, int);
 void	sctp_protopr(u_long, const char *, int, int);
 void	sctp_stats(u_long, const char *, int, int);
 #endif
+void	arp_stats(u_long, const char *, int, int);
 void	ip_stats(u_long, const char *, int, int);
 void	icmp_stats(u_long, const char *, int, int);
 void	igmp_stats(u_long, const char *, int, int);

From 3716ed4726ccb3e2ddc7e2b50cf68ec7b8be8a6d Mon Sep 17 00:00:00 2001
From: Christian Brueffer 
Date: Thu, 28 Jan 2010 17:07:14 +0000
Subject: [PATCH 1308/2592] MFC: r202317

Add manpages for ipwfw(4) and iwifw(4), based on iwnfw(4).
---
 share/man/man4/Makefile |  2 ++
 share/man/man4/ipwfw.4  | 75 +++++++++++++++++++++++++++++++++++++++++
 share/man/man4/iwifw.4  | 75 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 152 insertions(+)
 create mode 100644 share/man/man4/ipwfw.4
 create mode 100644 share/man/man4/iwifw.4

diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 924488c1990..1dec7814d7f 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -154,10 +154,12 @@ MAN=	aac.4 \
 	ips.4 \
 	ipsec.4 \
 	ipw.4 \
+	ipwfw.4 \
 	iscsi_initiator.4 \
 	isp.4 \
 	ispfw.4 \
 	iwi.4 \
+	iwifw.4 \
 	iwn.4 \
 	iwnfw.4 \
 	ixgb.4 \
diff --git a/share/man/man4/ipwfw.4 b/share/man/man4/ipwfw.4
new file mode 100644
index 00000000000..b901de8c0ee
--- /dev/null
+++ b/share/man/man4/ipwfw.4
@@ -0,0 +1,75 @@
+.\" Copyright (c) 2009 Sam Leffler, Errno Consulting
+.\" 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. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 14, 2010
+.Dt IPWFW 4
+.Os
+.Sh NAME
+.Nm ipwfw
+.Nd "Firmware Module for Intel PRO/Wireless 2100 driver"
+.Sh SYNOPSIS
+To compile this module into the kernel,
+place the following line in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device ipwfw"
+.Ed
+.Pp
+This will include three firmware images inside the kernel.
+If you want to pick only the firmware image for the mode you want to operate
+your network adapter in choose one of the following:
+.Bd -ragged -offset indent
+.Cd "device ipwbssfw"
+.Cd "device ipwibssfw"
+.Cd "device ipwmonitorfw"
+.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
+ipw_bss_load="YES"
+ipw_ibss_load="YES"
+ipw_monitor_load="YES"
+.Ed
+.Sh DESCRIPTION
+This module provides access to firmware sets for the
+Intel PRO/Wireless 2100 series of IEEE 802.11 adapters.
+It may be statically linked into the kernel, or loaded as a module.
+.Pp
+For the loaded firmware to be enabled for use the license at
+.Pa /usr/share/doc/legal/intel_ipw/LICENSE
+must be agreed to by adding the following line to
+.Xr loader.conf 5 :
+.Pp
+.Dl "legal.intel_ipw.license_ack=1"
+.Sh FILES
+.Bl -tag -width ".Pa /usr/share/doc/legal/intel_ipw/LICENSE" -compact
+.It Pa /usr/share/doc/legal/intel_ipw/LICENSE
+.Nm
+firmware license
+.El
+.Sh SEE ALSO
+.Xr ipw 4 ,
+.Xr firmware 9
diff --git a/share/man/man4/iwifw.4 b/share/man/man4/iwifw.4
new file mode 100644
index 00000000000..7effd3db717
--- /dev/null
+++ b/share/man/man4/iwifw.4
@@ -0,0 +1,75 @@
+.\" Copyright (c) 2009 Sam Leffler, Errno Consulting
+.\" 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. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 14, 2010
+.Dt IWIFW 4
+.Os
+.Sh NAME
+.Nm iwifw
+.Nd "Firmware Module for Intel PRO/Wireless 2200BG/2225BG/2915ABG driver"
+.Sh SYNOPSIS
+To compile this module into the kernel,
+place the following line in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device iwifw"
+.Ed
+.Pp
+This will include three firmware images inside the kernel.
+If you want to pick only the firmware image for the mode you want to operate
+your network adapter in choose one of the following:
+.Bd -ragged -offset indent
+.Cd "device iwibssfw"
+.Cd "device iwiibssfw"
+.Cd "device iwimonitorfw"
+.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
+iwi_bss_load="YES"
+iwi_ibss_load="YES"
+iwi_monitor_load="YES"
+.Ed
+.Sh DESCRIPTION
+This module provides access to firmware sets for the
+Intel PRO/Wireless 2200BG/2225BG/2915ABG series of IEEE 802.11 adapters.
+It may be statically linked into the kernel, or loaded as a module.
+.Pp
+For the loaded firmware to be enabled for use the license at
+.Pa /usr/share/doc/legal/intel_iwi/LICENSE
+must be agreed to by adding the following line to
+.Xr loader.conf 5 :
+.Pp
+.Dl "legal.intel_iwi.license_ack=1"
+.Sh FILES
+.Bl -tag -width ".Pa /usr/share/doc/legal/intel_iwi/LICENSE" -compact
+.It Pa /usr/share/doc/legal/intel_iwi/LICENSE
+.Nm
+firmware license
+.El
+.Sh SEE ALSO
+.Xr iwi 4 ,
+.Xr firmware 9

From 74d5ebae0e161f4b7a4ea6f5b7ff1d0199b09818 Mon Sep 17 00:00:00 2001
From: Jilles Tjoelker 
Date: Thu, 28 Jan 2010 22:15:29 +0000
Subject: [PATCH 1309/2592] MFC r202324: In 'make delete-old', use 'exec' to
 redirect an fd persistently

That is, write 'exec 3<&0' instead of '3<&0'. Due to an sh(1) bug fixed in
head in r199953, the latter also persisted, provided that fd 3 was not open
before.  With newer sh or fd 3 open, it would not delete orphaned catpages.
---
 Makefile.inc1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.inc1 b/Makefile.inc1
index 0acee7d6d21..ad237dd0f18 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -1248,7 +1248,7 @@ delete-old-files:
 		fi; \
 	done
 # Remove catpages without corresponding manpages.
-	@3<&0; \
+	@exec 3<&0; \
 	find ${DESTDIR}/usr/share/man/cat* ! -type d | \
 	sed -ep -e's:${DESTDIR}/usr/share/man/cat:${DESTDIR}/usr/share/man/man:' | \
 	while read catpage; do \

From 6481e96423f65e44d35ea91bb32f8e02a367be9e Mon Sep 17 00:00:00 2001
From: Joerg Wunsch 
Date: Fri, 29 Jan 2010 10:38:54 +0000
Subject: [PATCH 1310/2592] MFC r203125: fix typo in .Xr.

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

diff --git a/share/man/man4/gpib.4 b/share/man/man4/gpib.4
index e5e7a1b48ab..948e5ee003e 100644
--- a/share/man/man4/gpib.4
+++ b/share/man/man4/gpib.4
@@ -55,7 +55,7 @@ bus in an unaddressed mode, for example hard-copy printer data.
 .El
 .Sh SEE ALSO
 .\" .Xr libgpib 3 ,
-.Xr gpib 4 ,
+.Xr pcii 4 ,
 .Xr tnt4882 4
 .Sh HISTORY
 The

From 83858bcb892a6770239b37a70c9438663522784f Mon Sep 17 00:00:00 2001
From: Edwin Groothuis 
Date: Fri, 29 Jan 2010 11:30:40 +0000
Subject: [PATCH 1311/2592] MFC of 203066, 203067

Git has been added as port 9418:
http://www.iana.org/assignments/port-numbers

The Erlang Port Mapper Daemon (from ports/lang/erlang) has been
assigned official port number 4369 by IANA.

PR:		conf/143259 conf/113265
Submitted by:	Denny Lin  Jimmy Olgeni 
---
 etc/services | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/etc/services b/etc/services
index 729f20be11d..c5f30f6a8ef 100644
--- a/etc/services
+++ b/etc/services
@@ -2227,6 +2227,8 @@ rwhois		4321/tcp   #Remote Who Is
 rwhois		4321/udp   #Remote Who Is
 unicall		4343/tcp
 unicall		4343/udp
+epmd		4369/tcp   #Erlang Port Mapper Daemon
+epmd		4369/udp   #Erlang Port Mapper Daemon
 krb524		4444/tcp
 krb524		4444/udp
 # PROBLEM krb524 assigned the port,
@@ -2372,6 +2374,8 @@ dlip		7201/udp
 ftp-proxy	8021/tcp   # FTP proxy
 natd		8668/divert # Network Address Translation
 jetdirect	9100/tcp   #HP JetDirect card
+git		9418/tcp   #git pack transfer service
+git		9418/udp   #git pack transfer service
 man		9535/tcp
 man		9535/udp
 sd		9876/tcp   #Session Director

From 623592e0c0bad8608f0547f4381d0911b9da8aa4 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Fri, 29 Jan 2010 18:18:18 +0000
Subject: [PATCH 1312/2592] MFC r202967:    Call ieee80211_radiotap_rx, not
 ieee80211_radiotap_tx on sta_input()

   PR:		143163
   Submitted by:Alexander Egorenkov 
---
 sys/net80211/ieee80211_sta.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
index fe8c9fa10eb..26d6f157373 100644
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -759,7 +759,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
 
 		/* copy to listener after decrypt */
 		if (ieee80211_radiotap_active_vap(vap))
-			ieee80211_radiotap_tx(vap, m);
+			ieee80211_radiotap_rx(vap, m);
 		need_tap = 0;
 
 		/*

From b85fb2f79cb6a85c9eb64e0c7bc84b52dce1cf5d Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Fri, 29 Jan 2010 18:19:43 +0000
Subject: [PATCH 1313/2592] MFC r202986:   o add more notification strings in
 iwn_intr_str()   o sync with OpenBSD code

  Submitted by:	Bernhard Schmidt 
  MFC after:	3 days
---
 sys/dev/iwn/if_iwn.c    | 15 +++++++++++++--
 sys/dev/iwn/if_iwnreg.h |  3 +++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 3eab6704cee..bbd8dd9453e 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -1927,6 +1927,7 @@ iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 	struct iwn_rx_stat *stat = (struct iwn_rx_stat *)(desc + 1);
 
 	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: received PHY stats\n", __func__);
+	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 
 	/* Save RX statistics, they will be used on MPDU_RX_DONE. */
 	memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
@@ -2140,6 +2141,7 @@ iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 	if (sc->sc_flags & IWN_FLAG_CALIB_DONE)
 		return;
 
+	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 	len = (le32toh(desc->len) & 0x3fff) - 4;
 
 	switch (calib->code) {
@@ -2202,6 +2204,7 @@ iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 	    (ic->ic_flags & IEEE80211_F_SCAN))
 		return;
 
+	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 	DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: cmd %d\n", __func__, desc->type);
 	iwn_calib_reset(sc);	/* Reset TX power calibration timeout. */
 
@@ -2253,6 +2256,7 @@ iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 	    stat->btkillcnt, stat->rate, le16toh(stat->duration),
 	    le32toh(stat->status));
 
+	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 	iwn_tx_done(sc, desc, stat->ackfailcnt, le32toh(stat->status) & 0xff);
 }
 
@@ -2272,6 +2276,8 @@ 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);
 #endif
+
+	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 	iwn_tx_done(sc, desc, stat->ackfailcnt, le16toh(stat->status) & 0xff);
 }
 
@@ -2433,10 +2439,11 @@ iwn_notif_intr(struct iwn_softc *sc)
 		{
 			struct iwn_beacon_missed *miss =
 			    (struct iwn_beacon_missed *)(desc + 1);
-			int misses = le32toh(miss->consecutive);
+			int misses;
 
 			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
 			    BUS_DMASYNC_POSTREAD);
+			misses = le32toh(miss->consecutive);
 
 			/* XXX not sure why we're notified w/ zero */
 			if (misses == 0)
@@ -4372,7 +4379,7 @@ iwn_send_sensitivity(struct iwn_softc *sc)
 	cmd.corr_barker      = htole16(190);
 	cmd.corr_barker_mrc  = htole16(390);
 
-	DPRINTF(sc, IWN_DEBUG_RESET,
+	DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 	    "%s: set sensitivity %d/%d/%d/%d/%d/%d/%d\n", __func__,
 	    calib->ofdm_x1, calib->ofdm_mrc_x1, calib->ofdm_x4,
 	    calib->ofdm_mrc_x4, calib->cck_x4,
@@ -6388,10 +6395,14 @@ iwn_intr_str(uint8_t cmd)
 	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 IWN5000_CMD_CALIB_RESULT:	return "IWN5000_CMD_CALIB_RESULT";
+	case IWN5000_CMD_CALIB_COMPLETE: return "IWN5000_CMD_CALIB_COMPLETE";
 	case IWN_CMD_SET_POWER_MODE:	return "IWN_CMD_SET_POWER_MODE";
 	case IWN_CMD_SCAN:		return "IWN_CMD_SCAN";
+	case IWN_CMD_SCAN_RESULTS:	return "IWN_CMD_SCAN_RESULTS";
 	case IWN_CMD_TXPOWER:		return "IWN_CMD_TXPOWER";
 	case IWN_CMD_TXPOWER_DBM:	return "IWN_CMD_TXPOWER_DBM";
+	case IWN5000_CMD_TX_ANT_CONFIG:	return "IWN5000_CMD_TX_ANT_CONFIG";
 	case IWN_CMD_BT_COEX:		return "IWN_CMD_BT_COEX";
 	case IWN_CMD_SET_CRITICAL_TEMP:	return "IWN_CMD_SET_CRITICAL_TEMP";
 	case IWN_CMD_SET_SENSITIVITY:	return "IWN_CMD_SET_SENSITIVITY";
diff --git a/sys/dev/iwn/if_iwnreg.h b/sys/dev/iwn/if_iwnreg.h
index 08ef36cabfe..0aa76693823 100644
--- a/sys/dev/iwn/if_iwnreg.h
+++ b/sys/dev/iwn/if_iwnreg.h
@@ -421,8 +421,11 @@ struct iwn_tx_cmd {
 #define IWN_CMD_SET_LED			 72
 #define IWN5000_CMD_WIMAX_COEX		 90
 #define IWN5000_CMD_CALIB_CONFIG	101
+#define IWN5000_CMD_CALIB_RESULT	102
+#define IWN5000_CMD_CALIB_COMPLETE	103
 #define IWN_CMD_SET_POWER_MODE		119
 #define IWN_CMD_SCAN			128
+#define IWN_CMD_SCAN_RESULTS		131
 #define IWN_CMD_TXPOWER_DBM		149
 #define IWN_CMD_TXPOWER			151
 #define IWN5000_CMD_TX_ANT_CONFIG	152

From c9dc5d496d391e68b7b67c85723c4d75d4e5d6dc Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Fri, 29 Jan 2010 20:02:28 +0000
Subject: [PATCH 1314/2592] MFC r202692: Remove the signal from sigqueue before
 notifying the debugger for traced process, fixing the race between resuming
 from stopped state and other thread noting the old signal on the queue and
 acting.

---
 sys/kern/kern_sig.c | 45 ++++++++++++++++++++++++++++++---------------
 sys/sys/signalvar.h |  1 +
 2 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 9c74bc6ca6a..62a15364a72 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -353,7 +353,10 @@ sigqueue_add(sigqueue_t *sq, int signo, ksiginfo_t *si)
 
 	/* directly insert the ksi, don't copy it */
 	if (si->ksi_flags & KSI_INS) {
-		TAILQ_INSERT_TAIL(&sq->sq_list, si, ksi_link);
+		if (si->ksi_flags & KSI_HEAD)
+			TAILQ_INSERT_HEAD(&sq->sq_list, si, ksi_link);
+		else
+			TAILQ_INSERT_TAIL(&sq->sq_list, si, ksi_link);
 		si->ksi_sigq = sq;
 		goto out_set_bit;
 	}
@@ -374,7 +377,10 @@ sigqueue_add(sigqueue_t *sq, int signo, ksiginfo_t *si)
 			p->p_pendingcnt++;
 		ksiginfo_copy(si, ksi);
 		ksi->ksi_signo = signo;
-		TAILQ_INSERT_TAIL(&sq->sq_list, ksi, ksi_link);
+		if (si->ksi_flags & KSI_HEAD)
+			TAILQ_INSERT_HEAD(&sq->sq_list, ksi, ksi_link);
+		else
+			TAILQ_INSERT_TAIL(&sq->sq_list, ksi, ksi_link);
 		ksi->ksi_sigq = sq;
 	}
 
@@ -2488,6 +2494,7 @@ issignal(struct thread *td, int stop_allowed)
 	struct sigacts *ps;
 	struct sigqueue *queue;
 	sigset_t sigpending;
+	ksiginfo_t ksi;
 	int sig, prop, newsig;
 
 	p = td->td_proc;
@@ -2525,24 +2532,22 @@ issignal(struct thread *td, int stop_allowed)
 		if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
 			/*
 			 * If traced, always stop.
+			 * Remove old signal from queue before the stop.
+			 * XXX shrug off debugger, it causes siginfo to
+			 * be thrown away.
 			 */
+			queue = &td->td_sigqueue;
+			ksi.ksi_signo = 0;
+			if (sigqueue_get(queue, sig, &ksi) == 0) {
+				queue = &p->p_sigqueue;
+				sigqueue_get(queue, sig, &ksi);
+			}
+
 			mtx_unlock(&ps->ps_mtx);
 			newsig = ptracestop(td, sig);
 			mtx_lock(&ps->ps_mtx);
 
 			if (sig != newsig) {
-				ksiginfo_t ksi;
-
-				queue = &td->td_sigqueue;
-				/*
-				 * clear old signal.
-				 * XXX shrug off debugger, it causes siginfo to
-				 * be thrown away.
-				 */
-				if (sigqueue_get(queue, sig, &ksi) == 0) {
-					queue = &p->p_sigqueue;
-					sigqueue_get(queue, sig, &ksi);
-				}
 
 				/*
 				 * If parent wants us to take the signal,
@@ -2557,10 +2562,20 @@ 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(queue->sq_signals, sig);
+				sigqueue_add(queue, sig, NULL);
 				if (SIGISMEMBER(td->td_sigmask, sig))
 					continue;
 				signotify(td);
+			} else {
+				if (ksi.ksi_signo != 0) {
+					ksi.ksi_flags |= KSI_HEAD;
+					if (sigqueue_add(&td->td_sigqueue, sig,
+					    &ksi) != 0)
+						ksi.ksi_signo = 0;
+				}
+				if (ksi.ksi_signo == 0)
+					sigqueue_add(&td->td_sigqueue, sig,
+					    NULL);
 			}
 
 			/*
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index fd0fac3d3a4..267c59d94e7 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -234,6 +234,7 @@ typedef struct ksiginfo {
 #define	KSI_EXT		0x02	/* Externally managed ksi. */
 #define KSI_INS		0x04	/* Directly insert ksi, not the copy */
 #define	KSI_SIGQ	0x08	/* Generated by sigqueue, might ret EGAIN. */
+#define	KSI_HEAD	0x10	/* Insert into head, not tail. */
 #define	KSI_COPYMASK	(KSI_TRAP|KSI_SIGQ)
 
 #define	KSI_ONQ(ksi)	((ksi)->ksi_sigq != NULL)

From d75104804840a7eab69fc1f843ec0a467a8fcc9a Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Fri, 29 Jan 2010 20:42:03 +0000
Subject: [PATCH 1315/2592] MFC r202880: Do not check for existence of symlink
 source for the link action.

---
 etc/rc.d/devfs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/etc/rc.d/devfs b/etc/rc.d/devfs
index cd50b15a977..82278af53cf 100755
--- a/etc/rc.d/devfs
+++ b/etc/rc.d/devfs
@@ -44,7 +44,7 @@ read_devfs_conf()
 		while read action devicelist parameter; do
 			case "${action}" in
 			l*)	for device in ${devicelist}; do
-					if [ -c ${device} -a ! -e ${parameter} ]; then
+					if [ ! -e ${parameter} ]; then
 						ln -fs ${device} ${parameter}
 					fi
 				done

From 6d41eae028e76358093cf450b69369ef0b9f973f Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Sat, 30 Jan 2010 06:23:28 +0000
Subject: [PATCH 1316/2592] MFC r202894   Handle a race between pmap_kextract()
 and pmap_promote_pde().

---
 sys/i386/i386/pmap.c    | 27 +++++++++++++++++++++++++--
 sys/i386/include/pmap.h | 21 +++++++++++++++++++--
 2 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index d6f5be572dd..3ef2a5da261 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -243,8 +243,9 @@ struct sysmaps {
 	caddr_t	CADDR2;
 };
 static struct sysmaps sysmaps_pcpu[MAXCPU];
-pt_entry_t *CMAP1 = 0;
+pt_entry_t *CMAP1 = 0, *KPTmap;
 static pt_entry_t *CMAP3;
+static pd_entry_t *KPTD;
 caddr_t CADDR1 = 0, ptvmmap = 0;
 static caddr_t CADDR3;
 struct msgbuf *msgbufp = 0;
@@ -439,6 +440,21 @@ pmap_bootstrap(vm_paddr_t firstaddr)
 	 */
 	SYSMAP(struct msgbuf *, unused, msgbufp, atop(round_page(MSGBUF_SIZE)))
 
+	/*
+	 * KPTmap is used by pmap_kextract().
+	 */
+	SYSMAP(pt_entry_t *, KPTD, KPTmap, KVA_PAGES)
+
+	for (i = 0; i < NKPT; i++)
+		KPTD[i] = (KPTphys + (i << PAGE_SHIFT)) | PG_RW | PG_V;
+
+	/*
+	 * Adjust the start of the KPTD and KPTmap so that the implementation
+	 * of pmap_kextract() and pmap_growkernel() can be made simpler.
+	 */
+	KPTD -= KPTDI;
+	KPTmap -= i386_btop(KPTDI << PDRSHIFT);
+
 	/*
 	 * ptemap is used for pmap_pte_quick
 	 */
@@ -1829,6 +1845,7 @@ pmap_growkernel(vm_offset_t addr)
 	vm_page_t nkpg;
 	pd_entry_t newpdir;
 	pt_entry_t *pde;
+	boolean_t updated_PTD;
 
 	mtx_assert(&kernel_map->system_mtx, MA_OWNED);
 	if (kernel_vm_end == 0) {
@@ -1868,14 +1885,20 @@ pmap_growkernel(vm_offset_t addr)
 			pmap_zero_page(nkpg);
 		ptppaddr = VM_PAGE_TO_PHYS(nkpg);
 		newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M);
-		pdir_pde(PTD, kernel_vm_end) = newpdir;
+		pdir_pde(KPTD, kernel_vm_end) = newpdir;
 
+		updated_PTD = FALSE;
 		mtx_lock_spin(&allpmaps_lock);
 		LIST_FOREACH(pmap, &allpmaps, pm_list) {
+			if ((pmap->pm_pdir[PTDPTDI] & PG_FRAME) == (PTDpde[0] &
+			    PG_FRAME))
+				updated_PTD = TRUE;
 			pde = pmap_pde(pmap, kernel_vm_end);
 			pde_store(pde, newpdir);
 		}
 		mtx_unlock_spin(&allpmaps_lock);
+		KASSERT(updated_PTD,
+		    ("pmap_growkernel: current page table is not in allpmaps"));
 		kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
 		if (kernel_vm_end - 1 >= kernel_map->max_offset) {
 			kernel_vm_end = kernel_map->max_offset;
diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h
index 54e8c206cd4..bd6b2bced4a 100644
--- a/sys/i386/include/pmap.h
+++ b/sys/i386/include/pmap.h
@@ -265,6 +265,16 @@ pte_load_store_ma(pt_entry_t *ptep, pt_entry_t v)
 #define	pde_store_ma(ptep, pte)	pte_load_store_ma((ptep), (pt_entry_t)pte)
 
 #elif !defined(XEN)
+
+/*
+ * KPTmap is a linear mapping of the kernel page table.  It differs from the
+ * recursive mapping in two ways: (1) it only provides access to kernel page
+ * table pages, and not user page table pages, and (2) it provides access to
+ * a kernel page table page after the corresponding virtual addresses have
+ * been promoted to a 2/4MB page mapping.
+ */
+extern pt_entry_t *KPTmap;
+
 /*
  *	Routine:	pmap_kextract
  *	Function:
@@ -279,10 +289,17 @@ pmap_kextract(vm_offset_t va)
 	if ((pa = PTD[va >> PDRSHIFT]) & PG_PS) {
 		pa = (pa & PG_PS_FRAME) | (va & PDRMASK);
 	} else {
-		pa = *vtopte(va);
+		/*
+		 * Beware of a concurrent promotion that changes the PDE at
+		 * this point!  For example, vtopte() must not be used to
+		 * access the PTE because it would use the new PDE.  It is,
+		 * however, safe to use the old PDE because the page table
+		 * page is preserved by the promotion.
+		 */
+		pa = KPTmap[i386_btop(va)];
 		pa = (pa & PG_FRAME) | (va & PAGE_MASK);
 	}
-	return pa;
+	return (pa);
 }
 
 #define PT_UPDATES_FLUSH()

From e2b36efde5fd60df4195a726045f06e2feb6de5e Mon Sep 17 00:00:00 2001
From: Antoine Brodin 
Date: Sat, 30 Jan 2010 12:11:21 +0000
Subject: [PATCH 1317/2592] MFC r201145 to stable/8:   (S)LIST_HEAD_INITIALIZER
 takes a (S)LIST_HEAD as an argument.   Fix some wrong usages.   Note: this
 does not affect generated binaries as this argument is not used.

  PR:		137213
  Submitted by:	Eygene Ryabinkin (initial version)
---
 bin/pkill/pkill.c                       | 16 ++++++++--------
 lib/libc/gen/sem.c                      |  2 +-
 lib/libgssapi/gss_mech_switch.c         |  2 +-
 lib/librpcsec_gss/rpcsec_gss_conf.c     |  4 ++--
 lib/librpcsec_gss/svc_rpcsec_gss.c      |  4 ++--
 sbin/fsck_ffs/gjournal.c                |  2 +-
 sbin/ggate/ggated/ggated.c              |  4 ++--
 sbin/natd/natd.c                        |  2 +-
 sbin/routed/if.c                        |  2 +-
 sys/boot/ofw/libofw/ofw_disk.c          |  2 +-
 sys/dev/ksyms/ksyms.c                   |  2 +-
 sys/dev/led/led.c                       |  2 +-
 sys/dev/md/md.c                         |  2 +-
 sys/dev/sound/pcm/channel.c             |  2 +-
 sys/dev/sound/pcm/sndstat.c             |  2 +-
 sys/geom/gate/g_gate.c                  |  2 +-
 sys/ia64/ia64/sscdisk.c                 |  2 +-
 sys/kern/kern_conf.c                    |  2 +-
 sys/kern/kern_jail.c                    |  2 +-
 sys/kern/uipc_accf.c                    |  2 +-
 sys/kern/vfs_mount.c                    |  2 +-
 sys/netgraph/atm/uni/ng_uni.c           | 20 ++++++++++----------
 sys/netgraph/ng_base.c                  |  2 +-
 sys/netinet/ip_encap.c                  |  2 +-
 sys/netinet/libalias/alias_mod.c        |  4 ++--
 sys/rpc/rpcsec_gss/svc_rpcsec_gss.c     |  4 ++--
 sys/vm/uma_core.c                       |  4 ++--
 tools/regression/geom/ConfCmp/ConfCmp.c |  2 +-
 usr.sbin/cpucontrol/cpucontrol.c        |  2 +-
 usr.sbin/pmcstat/pmcstat_log.c          |  2 +-
 30 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/bin/pkill/pkill.c b/bin/pkill/pkill.c
index b4b96b880f4..69349c3c589 100644
--- a/bin/pkill/pkill.c
+++ b/bin/pkill/pkill.c
@@ -113,14 +113,14 @@ static int	cflags = REG_EXTENDED;
 static kvm_t	*kd;
 static pid_t	mypid;
 
-static struct listhead euidlist = SLIST_HEAD_INITIALIZER(list);
-static struct listhead ruidlist = SLIST_HEAD_INITIALIZER(list);
-static struct listhead rgidlist = SLIST_HEAD_INITIALIZER(list);
-static struct listhead pgrplist = SLIST_HEAD_INITIALIZER(list);
-static struct listhead ppidlist = SLIST_HEAD_INITIALIZER(list);
-static struct listhead tdevlist = SLIST_HEAD_INITIALIZER(list);
-static struct listhead sidlist = SLIST_HEAD_INITIALIZER(list);
-static struct listhead jidlist = SLIST_HEAD_INITIALIZER(list);
+static struct listhead euidlist = SLIST_HEAD_INITIALIZER(euidlist);
+static struct listhead ruidlist = SLIST_HEAD_INITIALIZER(ruidlist);
+static struct listhead rgidlist = SLIST_HEAD_INITIALIZER(rgidlist);
+static struct listhead pgrplist = SLIST_HEAD_INITIALIZER(pgrplist);
+static struct listhead ppidlist = SLIST_HEAD_INITIALIZER(ppidlist);
+static struct listhead tdevlist = SLIST_HEAD_INITIALIZER(tdevlist);
+static struct listhead sidlist = SLIST_HEAD_INITIALIZER(sidlist);
+static struct listhead jidlist = SLIST_HEAD_INITIALIZER(jidlist);
 
 static void	usage(void) __attribute__((__noreturn__));
 static int	killact(const struct kinfo_proc *);
diff --git a/lib/libc/gen/sem.c b/lib/libc/gen/sem.c
index 439f0fe5c41..cd31d31e04a 100644
--- a/lib/libc/gen/sem.c
+++ b/lib/libc/gen/sem.c
@@ -73,7 +73,7 @@
 static sem_t sem_alloc(unsigned int value, semid_t semid, int system_sem);
 static void  sem_free(sem_t sem);
 
-static LIST_HEAD(, sem) named_sems = LIST_HEAD_INITIALIZER(&named_sems);
+static LIST_HEAD(, sem) named_sems = LIST_HEAD_INITIALIZER(named_sems);
 static pthread_mutex_t named_sems_mtx = PTHREAD_MUTEX_INITIALIZER;
 
 __weak_reference(__sem_init, sem_init);
diff --git a/lib/libgssapi/gss_mech_switch.c b/lib/libgssapi/gss_mech_switch.c
index feb88f1a68c..d07db8865d3 100644
--- a/lib/libgssapi/gss_mech_switch.c
+++ b/lib/libgssapi/gss_mech_switch.c
@@ -42,7 +42,7 @@
 #endif
 
 struct _gss_mech_switch_list _gss_mechs =
-	SLIST_HEAD_INITIALIZER(&_gss_mechs);
+	SLIST_HEAD_INITIALIZER(_gss_mechs);
 gss_OID_set _gss_mech_oids;
 
 /*
diff --git a/lib/librpcsec_gss/rpcsec_gss_conf.c b/lib/librpcsec_gss/rpcsec_gss_conf.c
index 4a0349be152..14e063c60d8 100644
--- a/lib/librpcsec_gss/rpcsec_gss_conf.c
+++ b/lib/librpcsec_gss/rpcsec_gss_conf.c
@@ -55,7 +55,7 @@ struct mech_info {
 };
 SLIST_HEAD(mech_info_list, mech_info);
 
-static struct mech_info_list mechs = SLIST_HEAD_INITIALIZER(&mechs);
+static struct mech_info_list mechs = SLIST_HEAD_INITIALIZER(mechs);
 static const char **mech_names;
 
 struct qop_info {
@@ -66,7 +66,7 @@ struct qop_info {
 };
 SLIST_HEAD(qop_info_list, qop_info);
 
-static struct qop_info_list qops = SLIST_HEAD_INITIALIZER(&qops);
+static struct qop_info_list qops = SLIST_HEAD_INITIALIZER(qops);
 
 static int
 _rpc_gss_string_to_oid(const char* s, gss_OID oid)
diff --git a/lib/librpcsec_gss/svc_rpcsec_gss.c b/lib/librpcsec_gss/svc_rpcsec_gss.c
index 276126b59cf..d0599be0330 100644
--- a/lib/librpcsec_gss/svc_rpcsec_gss.c
+++ b/lib/librpcsec_gss/svc_rpcsec_gss.c
@@ -90,7 +90,7 @@ struct svc_rpc_gss_callback {
 	rpc_gss_callback_t	cb_callback;
 };
 static SLIST_HEAD(svc_rpc_gss_callback_list, svc_rpc_gss_callback)
-	svc_rpc_gss_callbacks = SLIST_HEAD_INITIALIZER(&svc_rpc_gss_callbacks);
+	svc_rpc_gss_callbacks = SLIST_HEAD_INITIALIZER(svc_rpc_gss_callbacks);
 
 struct svc_rpc_gss_svc_name {
 	SLIST_ENTRY(svc_rpc_gss_svc_name) sn_link;
@@ -102,7 +102,7 @@ struct svc_rpc_gss_svc_name {
 	u_int			sn_version;
 };
 static SLIST_HEAD(svc_rpc_gss_svc_name_list, svc_rpc_gss_svc_name)
-	svc_rpc_gss_svc_names = SLIST_HEAD_INITIALIZER(&svc_rpc_gss_svc_names);
+	svc_rpc_gss_svc_names = SLIST_HEAD_INITIALIZER(svc_rpc_gss_svc_names);
 
 enum svc_rpc_gss_client_state {
 	CLIENT_NEW,				/* still authenticating */
diff --git a/sbin/fsck_ffs/gjournal.c b/sbin/fsck_ffs/gjournal.c
index 903763ddea2..bd887cab850 100644
--- a/sbin/fsck_ffs/gjournal.c
+++ b/sbin/fsck_ffs/gjournal.c
@@ -86,7 +86,7 @@ struct cgchain {
 
 #define	MAX_CACHED_CGS	1024
 static unsigned ncgs = 0;
-static LIST_HEAD(, cgchain) cglist = LIST_HEAD_INITIALIZER(&cglist);
+static LIST_HEAD(, cgchain) cglist = LIST_HEAD_INITIALIZER(cglist);
 
 static const char *devnam;
 static struct uufsd *disk = NULL;
diff --git a/sbin/ggate/ggated/ggated.c b/sbin/ggate/ggated/ggated.c
index 52d2428a052..3b2a0a574c9 100644
--- a/sbin/ggate/ggated/ggated.c
+++ b/sbin/ggate/ggated/ggated.c
@@ -99,8 +99,8 @@ static TAILQ_HEAD(, ggd_request) outqueue = TAILQ_HEAD_INITIALIZER(outqueue);
 pthread_mutex_t inqueue_mtx, outqueue_mtx;
 pthread_cond_t inqueue_cond, outqueue_cond;
 
-static SLIST_HEAD(, ggd_export) exports = SLIST_HEAD_INITIALIZER(&exports);
-static LIST_HEAD(, ggd_connection) connections = LIST_HEAD_INITIALIZER(&connection);
+static SLIST_HEAD(, ggd_export) exports = SLIST_HEAD_INITIALIZER(exports);
+static LIST_HEAD(, ggd_connection) connections = LIST_HEAD_INITIALIZER(connections);
 
 static void *recv_thread(void *arg);
 static void *disk_thread(void *arg);
diff --git a/sbin/natd/natd.c b/sbin/natd/natd.c
index 445077f4fbe..f6b3fdb78f9 100644
--- a/sbin/natd/natd.c
+++ b/sbin/natd/natd.c
@@ -68,7 +68,7 @@ struct instance {
 	int			divertInOut;
 };
 
-static LIST_HEAD(, instance) root = LIST_HEAD_INITIALIZER(&root);
+static LIST_HEAD(, instance) root = LIST_HEAD_INITIALIZER(root);
 
 struct libalias *mla;
 struct instance *mip;
diff --git a/sbin/routed/if.c b/sbin/routed/if.c
index 61ac412b2e1..1c185d76fe5 100644
--- a/sbin/routed/if.c
+++ b/sbin/routed/if.c
@@ -42,7 +42,7 @@ __RCSID("$Revision: 2.27 $");
 #endif
 
 struct ifhead ifnet = LIST_HEAD_INITIALIZER(ifnet);	/* all interfaces */
-struct ifhead remote_if = LIST_HEAD_INITIALIZER(ifnet);	/* remote interfaces */
+struct ifhead remote_if = LIST_HEAD_INITIALIZER(remote_if);	/* remote interfaces */
 
 /* hash table for all interfaces, big enough to tolerate ridiculous
  * numbers of IP aliases.  Crazy numbers of aliases such as 7000
diff --git a/sys/boot/ofw/libofw/ofw_disk.c b/sys/boot/ofw/libofw/ofw_disk.c
index c3649841c5e..aaad196eefd 100644
--- a/sys/boot/ofw/libofw/ofw_disk.c
+++ b/sys/boot/ofw/libofw/ofw_disk.c
@@ -67,7 +67,7 @@ struct opened_dev {
 	SLIST_ENTRY(opened_dev)	link;
 };
 
-SLIST_HEAD(, opened_dev) opened_devs = SLIST_HEAD_INITIALIZER(opened_dev);
+SLIST_HEAD(, opened_dev) opened_devs = SLIST_HEAD_INITIALIZER(opened_devs);
 
 static int
 ofwd_init(void)
diff --git a/sys/dev/ksyms/ksyms.c b/sys/dev/ksyms/ksyms.c
index fc368c7dca0..bca64482a52 100644
--- a/sys/dev/ksyms/ksyms.c
+++ b/sys/dev/ksyms/ksyms.c
@@ -94,7 +94,7 @@ struct ksyms_softc {
 static struct mtx 		 ksyms_mtx;
 static struct cdev 		*ksyms_dev;
 static LIST_HEAD(, ksyms_softc)	 ksyms_list = 
-	LIST_HEAD_INITIALIZER(&ksyms_list);
+	LIST_HEAD_INITIALIZER(ksyms_list);
 
 static const char 	ksyms_shstrtab[] = 
 	"\0" STR_SYMTAB "\0" STR_STRTAB "\0" STR_SHSTRTAB "\0";
diff --git a/sys/dev/led/led.c b/sys/dev/led/led.c
index 1d902d56aa7..fdd0fa2d006 100644
--- a/sys/dev/led/led.c
+++ b/sys/dev/led/led.c
@@ -40,7 +40,7 @@ struct ledsc {
 static struct unrhdr *led_unit;
 static struct mtx led_mtx;
 static struct sx led_sx;
-static LIST_HEAD(, ledsc) led_list = LIST_HEAD_INITIALIZER(&led_list);
+static LIST_HEAD(, ledsc) led_list = LIST_HEAD_INITIALIZER(led_list);
 static struct callout led_ch;
 
 static MALLOC_DEFINE(M_LED, "LED", "LED driver");
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index 87e5ac9e6a6..20060999a23 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -152,7 +152,7 @@ struct g_class g_md_class = {
 DECLARE_GEOM_CLASS(g_md_class, g_md);
 
 
-static LIST_HEAD(, md_s) md_softc_list = LIST_HEAD_INITIALIZER(&md_softc_list);
+static LIST_HEAD(, md_s) md_softc_list = LIST_HEAD_INITIALIZER(md_softc_list);
 
 #define NINDIR	(PAGE_SIZE / sizeof(uintptr_t))
 #define NMASK	(NINDIR-1)
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index 42ea86faab4..ec7cb9802ac 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -220,7 +220,7 @@ MTX_SYSINIT(pcm_syncgroup, &snd_pcm_syncgroups_mtx, "PCM channel sync group lock
  *
  * See SNDCTL_DSP_SYNCGROUP for more information.
  */
-struct pcm_synclist snd_pcm_syncgroups = SLIST_HEAD_INITIALIZER(head);
+struct pcm_synclist snd_pcm_syncgroups = SLIST_HEAD_INITIALIZER(snd_pcm_syncgroups);
 
 static void
 chn_lockinit(struct pcm_channel *c, int dir)
diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c
index 4daca5f6aac..11d17642770 100644
--- a/sys/dev/sound/pcm/sndstat.c
+++ b/sys/dev/sound/pcm/sndstat.c
@@ -79,7 +79,7 @@ static int sndstat_files = 0;
 	}								\
 } while (0)
 
-static SLIST_HEAD(, sndstat_entry) sndstat_devlist = SLIST_HEAD_INITIALIZER(none);
+static SLIST_HEAD(, sndstat_entry) sndstat_devlist = SLIST_HEAD_INITIALIZER(sndstat_devlist);
 
 int snd_verbose = 0;
 TUNABLE_INT("hw.snd.verbose", &snd_verbose);
diff --git a/sys/geom/gate/g_gate.c b/sys/geom/gate/g_gate.c
index 3737ee05868..26df0f41855 100644
--- a/sys/geom/gate/g_gate.c
+++ b/sys/geom/gate/g_gate.c
@@ -72,7 +72,7 @@ static struct cdevsw g_gate_cdevsw = {
 
 
 static LIST_HEAD(, g_gate_softc) g_gate_list =
-    LIST_HEAD_INITIALIZER(&g_gate_list);
+    LIST_HEAD_INITIALIZER(g_gate_list);
 static struct mtx g_gate_list_mtx;
 
 
diff --git a/sys/ia64/ia64/sscdisk.c b/sys/ia64/ia64/sscdisk.c
index 0d5e32190cc..f9abc0abd25 100644
--- a/sys/ia64/ia64/sscdisk.c
+++ b/sys/ia64/ia64/sscdisk.c
@@ -76,7 +76,7 @@ MALLOC_DEFINE(M_SSC, "ssc_disk", "Simulator Disk");
 
 static d_strategy_t sscstrategy;
 
-static LIST_HEAD(, ssc_s) ssc_softc_list = LIST_HEAD_INITIALIZER(&ssc_softc_list);
+static LIST_HEAD(, ssc_s) ssc_softc_list = LIST_HEAD_INITIALIZER(ssc_softc_list);
 
 struct ssc_s {
 	int unit;
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index 8504e48d3e5..e570fddbea3 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -63,7 +63,7 @@ static struct cdev *make_dev_credv(int flags,
 static struct cdev_priv_list cdevp_free_list =
     TAILQ_HEAD_INITIALIZER(cdevp_free_list);
 static SLIST_HEAD(free_cdevsw, cdevsw) cdevsw_gt_post_list =
-    SLIST_HEAD_INITIALIZER();
+    SLIST_HEAD_INITIALIZER(cdevsw_gt_post_list);
 
 void
 dev_lock(void)
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 01a57f9324a..7dcf479c5d0 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -102,7 +102,7 @@ struct prison prison0 = {
 	.pr_securelevel	= -1,
 	.pr_childmax	= JAIL_MAX,
 	.pr_hostuuid	= DEFAULT_HOSTUUID,
-	.pr_children	= LIST_HEAD_INITIALIZER(&prison0.pr_children),
+	.pr_children	= LIST_HEAD_INITIALIZER(prison0.pr_children),
 #ifdef VIMAGE
 	.pr_flags	= PR_HOST|PR_VNET|_PR_IP_SADDRSEL,
 #else
diff --git a/sys/kern/uipc_accf.c b/sys/kern/uipc_accf.c
index 102c04f2663..236b60d01cf 100644
--- a/sys/kern/uipc_accf.c
+++ b/sys/kern/uipc_accf.c
@@ -54,7 +54,7 @@ MTX_SYSINIT(accept_filter, &accept_filter_mtx, "accept_filter_mtx",
 #define	ACCEPT_FILTER_UNLOCK()	mtx_unlock(&accept_filter_mtx)
 
 static SLIST_HEAD(, accept_filter) accept_filtlsthd =
-	SLIST_HEAD_INITIALIZER(&accept_filtlsthd);
+	SLIST_HEAD_INITIALIZER(accept_filtlsthd);
 
 MALLOC_DEFINE(M_ACCF, "accf", "accept filter data");
 
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index a75a019cb53..37b5f965040 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -1354,7 +1354,7 @@ struct root_hold_token {
 };
 
 static LIST_HEAD(, root_hold_token)	root_holds =
-    LIST_HEAD_INITIALIZER(&root_holds);
+    LIST_HEAD_INITIALIZER(root_holds);
 
 static int root_mount_complete;
 
diff --git a/sys/netgraph/atm/uni/ng_uni.c b/sys/netgraph/atm/uni/ng_uni.c
index e6fa04ba55a..5b2a7ff712a 100644
--- a/sys/netgraph/atm/uni/ng_uni.c
+++ b/sys/netgraph/atm/uni/ng_uni.c
@@ -771,18 +771,18 @@ struct unimem_debug {
 LIST_HEAD(unimem_debug_list, unimem_debug);
 
 static struct unimem_debug_list nguni_freemem[UNIMEM_TYPES] = {
-    LIST_HEAD_INITIALIZER(unimem_debug),
-    LIST_HEAD_INITIALIZER(unimem_debug),
-    LIST_HEAD_INITIALIZER(unimem_debug),
-    LIST_HEAD_INITIALIZER(unimem_debug),
-    LIST_HEAD_INITIALIZER(unimem_debug),
+    LIST_HEAD_INITIALIZER(nguni_freemem[0]),
+    LIST_HEAD_INITIALIZER(nguni_freemem[1]),
+    LIST_HEAD_INITIALIZER(nguni_freemem[2]),
+    LIST_HEAD_INITIALIZER(nguni_freemem[3]),
+    LIST_HEAD_INITIALIZER(nguni_freemem[4]),
 };
 static struct unimem_debug_list nguni_usedmem[UNIMEM_TYPES] = {
-    LIST_HEAD_INITIALIZER(unimem_debug),
-    LIST_HEAD_INITIALIZER(unimem_debug),
-    LIST_HEAD_INITIALIZER(unimem_debug),
-    LIST_HEAD_INITIALIZER(unimem_debug),
-    LIST_HEAD_INITIALIZER(unimem_debug),
+    LIST_HEAD_INITIALIZER(nguni_usedmem[0]),
+    LIST_HEAD_INITIALIZER(nguni_usedmem[1]),
+    LIST_HEAD_INITIALIZER(nguni_usedmem[2]),
+    LIST_HEAD_INITIALIZER(nguni_usedmem[3]),
+    LIST_HEAD_INITIALIZER(nguni_usedmem[4]),
 };
 
 static struct mtx nguni_unilist_mtx;
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c
index 65707b20914..fdfe878dbc9 100644
--- a/sys/netgraph/ng_base.c
+++ b/sys/netgraph/ng_base.c
@@ -120,7 +120,7 @@ struct ng_node ng_deadnode = {
 	0,	/* numhooks */
 	NULL,	/* private */
 	0,	/* ID */
-	LIST_HEAD_INITIALIZER(ng_deadnode.hooks),
+	LIST_HEAD_INITIALIZER(ng_deadnode.nd_hooks),
 	{},	/* all_nodes list entry */
 	{},	/* id hashtable list entry */
 	{	0,
diff --git a/sys/netinet/ip_encap.c b/sys/netinet/ip_encap.c
index 0efd22aaf0d..ce1319d447e 100644
--- a/sys/netinet/ip_encap.c
+++ b/sys/netinet/ip_encap.c
@@ -103,7 +103,7 @@ static void encap_fillarg(struct mbuf *, const struct encaptab *);
  */
 static struct mtx encapmtx;
 MTX_SYSINIT(encapmtx, &encapmtx, "encapmtx", MTX_DEF);
-LIST_HEAD(, encaptab) encaptab = LIST_HEAD_INITIALIZER(&encaptab);
+LIST_HEAD(, encaptab) encaptab = LIST_HEAD_INITIALIZER(encaptab);
 
 /*
  * We currently keey encap_init() for source code compatibility reasons --
diff --git a/sys/netinet/libalias/alias_mod.c b/sys/netinet/libalias/alias_mod.c
index 2713137ec20..b2576da6be6 100644
--- a/sys/netinet/libalias/alias_mod.c
+++ b/sys/netinet/libalias/alias_mod.c
@@ -52,11 +52,11 @@ __FBSDID("$FreeBSD$");
 #endif
 
 /* Protocol and userland module handlers chains. */
-LIST_HEAD(handler_chain, proto_handler) handler_chain = LIST_HEAD_INITIALIZER(foo);
+LIST_HEAD(handler_chain, proto_handler) handler_chain = LIST_HEAD_INITIALIZER(handler_chain);
 #ifdef _KERNEL
 struct rwlock   handler_rw;
 #endif
-SLIST_HEAD(dll_chain, dll) dll_chain = SLIST_HEAD_INITIALIZER(foo); 
+SLIST_HEAD(dll_chain, dll) dll_chain = SLIST_HEAD_INITIALIZER(dll_chain); 
 
 #ifdef _KERNEL
 
diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
index b6e328e6760..55c0a8309ed 100644
--- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
+++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
@@ -100,7 +100,7 @@ struct svc_rpc_gss_callback {
 	rpc_gss_callback_t	cb_callback;
 };
 static SLIST_HEAD(svc_rpc_gss_callback_list, svc_rpc_gss_callback)
-	svc_rpc_gss_callbacks = SLIST_HEAD_INITIALIZER(&svc_rpc_gss_callbacks);
+	svc_rpc_gss_callbacks = SLIST_HEAD_INITIALIZER(svc_rpc_gss_callbacks);
 
 struct svc_rpc_gss_svc_name {
 	SLIST_ENTRY(svc_rpc_gss_svc_name) sn_link;
@@ -112,7 +112,7 @@ struct svc_rpc_gss_svc_name {
 	u_int			sn_version;
 };
 static SLIST_HEAD(svc_rpc_gss_svc_name_list, svc_rpc_gss_svc_name)
-	svc_rpc_gss_svc_names = SLIST_HEAD_INITIALIZER(&svc_rpc_gss_svc_names);
+	svc_rpc_gss_svc_names = SLIST_HEAD_INITIALIZER(svc_rpc_gss_svc_names);
 
 enum svc_rpc_gss_client_state {
 	CLIENT_NEW,				/* still authenticating */
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 81254828ead..a2d5633bd51 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -122,14 +122,14 @@ static MALLOC_DEFINE(M_UMAHASH, "UMAHash", "UMA Hash Buckets");
 static int bucketdisable = 1;
 
 /* Linked list of all kegs in the system */
-static LIST_HEAD(,uma_keg) uma_kegs = LIST_HEAD_INITIALIZER(&uma_kegs);
+static LIST_HEAD(,uma_keg) uma_kegs = LIST_HEAD_INITIALIZER(uma_kegs);
 
 /* This mutex protects the keg list */
 static struct mtx uma_mtx;
 
 /* Linked list of boot time pages */
 static LIST_HEAD(,uma_slab) uma_boot_pages =
-    LIST_HEAD_INITIALIZER(&uma_boot_pages);
+    LIST_HEAD_INITIALIZER(uma_boot_pages);
 
 /* This mutex protects the boot time pages list */
 static struct mtx uma_boot_pages_mtx;
diff --git a/tools/regression/geom/ConfCmp/ConfCmp.c b/tools/regression/geom/ConfCmp/ConfCmp.c
index 8c551cf8e84..599a953b1b8 100644
--- a/tools/regression/geom/ConfCmp/ConfCmp.c
+++ b/tools/regression/geom/ConfCmp/ConfCmp.c
@@ -74,7 +74,7 @@ struct ref {
 	char			*k2;
 };
 
-LIST_HEAD(, ref)		refs = LIST_HEAD_INITIALIZER(&refs);
+LIST_HEAD(, ref)		refs = LIST_HEAD_INITIALIZER(refs);
 
 static struct node *
 new_node(void)
diff --git a/usr.sbin/cpucontrol/cpucontrol.c b/usr.sbin/cpucontrol/cpucontrol.c
index 8b3ca1dad5c..b0ef9a3700a 100644
--- a/usr.sbin/cpucontrol/cpucontrol.c
+++ b/usr.sbin/cpucontrol/cpucontrol.c
@@ -83,7 +83,7 @@ struct datadir {
 	const char		*path;
 	SLIST_ENTRY(datadir)	next;
 };
-static SLIST_HEAD(, datadir) datadirs = SLIST_HEAD_INITIALIZER(&datadirs);
+static SLIST_HEAD(, datadir) datadirs = SLIST_HEAD_INITIALIZER(datadirs);
 
 struct ucode_handler {
 	ucode_probe_t *probe;
diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c
index 98141268503..a403852edf5 100644
--- a/usr.sbin/pmcstat/pmcstat_log.c
+++ b/usr.sbin/pmcstat/pmcstat_log.c
@@ -141,7 +141,7 @@ struct pmcstat_pmcrecord {
 };
 
 static LIST_HEAD(,pmcstat_pmcrecord)	pmcstat_pmcs =
-	LIST_HEAD_INITIALIZER(&pmcstat_pmcs);
+	LIST_HEAD_INITIALIZER(pmcstat_pmcs);
 
 
 /*

From 7ecc6d21d94358281f9e96e19c7ed9ed464e53b6 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 14:40:42 +0000
Subject: [PATCH 1318/2592] MFC r196711:

Make the code more readable and fix chmod(1) on symlinks with
NFSv4 enabled.
---
 bin/chmod/chmod.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/bin/chmod/chmod.c b/bin/chmod/chmod.c
index d003b5fbc86..f70161120f4 100644
--- a/bin/chmod/chmod.c
+++ b/bin/chmod/chmod.c
@@ -42,6 +42,7 @@ static char sccsid[] = "@(#)chmod.c	8.8 (Berkeley) 4/1/94";
 __FBSDID("$FreeBSD$");
 
 #include 
+#include 
 #include 
 
 #include 
@@ -54,7 +55,7 @@ __FBSDID("$FreeBSD$");
 #include 
 
 static void usage(void);
-static int may_have_nfs4acl(const FTSENT *ent);
+static int may_have_nfs4acl(const FTSENT *ent, int hflag);
 
 int
 main(int argc, char *argv[])
@@ -62,11 +63,10 @@ main(int argc, char *argv[])
 	FTS *ftsp;
 	FTSENT *p;
 	mode_t *set;
-	int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval;
+	int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, error;
 	int vflag;
 	char *mode;
 	mode_t newmode;
-	int (*change_mode)(const char *, mode_t);
 
 	set = NULL;
 	Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
@@ -140,11 +140,6 @@ done:	argv += optind;
 	} else
 		fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL;
 
-	if (hflag)
-		change_mode = lchmod;
-	else
-		change_mode = chmod;
-
 	mode = *argv;
 	if ((set = setmode(mode)) == NULL)
 		errx(1, "invalid file mode: %s", mode);
@@ -186,10 +181,14 @@ done:	argv += optind;
 		 * identical to the one computed from an ACL will change
 		 * that ACL.
 		 */
-		if (may_have_nfs4acl(p) == 0 &&
+		if (may_have_nfs4acl(p, hflag) == 0 &&
 		    (newmode & ALLPERMS) == (p->fts_statp->st_mode & ALLPERMS))
 				continue;
-		if ((*change_mode)(p->fts_accpath, newmode) && !fflag) {
+		if (hflag)
+			error = lchmod(p->fts_accpath, newmode);
+		else
+			error = chmod(p->fts_accpath, newmode);
+		if (error && !fflag) {
 			warn("%s", p->fts_path);
 			rval = 1;
 		} else {
@@ -228,17 +227,20 @@ usage(void)
 }
 
 static int
-may_have_nfs4acl(const FTSENT *ent)
+may_have_nfs4acl(const FTSENT *ent, int hflag)
 {
 	int ret;
-	static dev_t previous_dev = (dev_t)-1;
+	static dev_t previous_dev = NODEV;
 	static int supports_acls = -1;
 
 	if (previous_dev != ent->fts_statp->st_dev) {
 		previous_dev = ent->fts_statp->st_dev;
 		supports_acls = 0;
 
-		ret = pathconf(ent->fts_accpath, _PC_ACL_NFS4);
+		if (hflag)
+			ret = lpathconf(ent->fts_accpath, _PC_ACL_NFS4);
+		else
+			ret = pathconf(ent->fts_accpath, _PC_ACL_NFS4);
 		if (ret > 0)
 			supports_acls = 1;
 		else if (ret < 0 && errno != EINVAL)

From af0a0fb12e389bef146535f50ff62548ad4ea381 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 14:44:32 +0000
Subject: [PATCH 1319/2592] MFC r196712:

Add NFSv4 ACL support to ls(1).

MFC r196773:

Fix regression introduced in r196712 - the 'name' string needs
to be rewritten for each file we want to check ACL on.  Without
this change, ls(1) would check only the ACL on the first file
to list.
---
 bin/ls/print.c | 102 ++++++++++++++++++++++++++-----------------------
 1 file changed, 54 insertions(+), 48 deletions(-)

diff --git a/bin/ls/print.c b/bin/ls/print.c
index 4825d2e1052..3b80d93aefe 100644
--- a/bin/ls/print.c
+++ b/bin/ls/print.c
@@ -70,7 +70,7 @@ static void	printsize(size_t, off_t);
 static void	endcolor(int);
 static int	colortype(mode_t);
 #endif
-static void	aclmode(char *, const FTSENT *, int *);
+static void	aclmode(char *, const FTSENT *);
 
 #define	IS_NOPRINT(p)	((p)->fts_number == NO_PRINT)
 
@@ -139,16 +139,12 @@ printlong(const DISPLAY *dp)
 #ifdef COLORLS
 	int color_printed = 0;
 #endif
-	int haveacls;
-	dev_t prevdev;
 
 	if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
 	    (f_longform || f_size)) {
 		(void)printf("total %lu\n", howmany(dp->btotal, blocksize));
 	}
 
-	haveacls = 1;
-	prevdev = (dev_t)-1;
 	for (p = dp->list; p; p = p->fts_link) {
 		if (IS_NOPRINT(p))
 			continue;
@@ -159,14 +155,7 @@ printlong(const DISPLAY *dp)
 			(void)printf("%*jd ",
 			    dp->s_block, howmany(sp->st_blocks, blocksize));
 		strmode(sp->st_mode, buf);
-		/*
-		 * Cache whether or not the filesystem supports ACL's to
-		 * avoid expensive syscalls. Try again when we change devices.
-		 */
-		if (haveacls || sp->st_dev != prevdev) {
-			aclmode(buf, p, &haveacls);
-			prevdev = sp->st_dev;
-		}
+		aclmode(buf, p);
 		np = p->fts_pointer;
 		(void)printf("%s %*u %-*s  %-*s  ", buf, dp->s_nlink,
 		    sp->st_nlink, dp->s_user, np->user, dp->s_group,
@@ -612,56 +601,73 @@ printsize(size_t width, off_t bytes)
 		(void)printf("%*jd ", (u_int)width, bytes);
 }
 
+/*
+ * Add a + after the standard rwxrwxrwx mode if the file has an
+ * ACL. strmode() reserves space at the end of the string.
+ */
 static void
-aclmode(char *buf, const FTSENT *p, int *haveacls)
+aclmode(char *buf, const FTSENT *p)
 {
 	char name[MAXPATHLEN + 1];
-	int entries, ret;
+	int ret, trivial;
+	static dev_t previous_dev = NODEV;
+	static int supports_acls = -1;
+	static int type = ACL_TYPE_ACCESS;
 	acl_t facl;
-	acl_entry_t ae;
 
 	/*
-	 * Add a + after the standard rwxrwxrwx mode if the file has an
-	 * extended ACL. strmode() reserves space at the end of the string.
+	 * XXX: ACLs are not supported on whiteouts and device files
+	 * residing on UFS.
 	 */
+	if (S_ISCHR(p->fts_statp->st_mode) || S_ISBLK(p->fts_statp->st_mode) ||
+	    S_ISWHT(p->fts_statp->st_mode))
+		return;
+
+	if (previous_dev == p->fts_statp->st_dev && supports_acls == 0)
+		return;
+
 	if (p->fts_level == FTS_ROOTLEVEL)
 		snprintf(name, sizeof(name), "%s", p->fts_name);
 	else
 		snprintf(name, sizeof(name), "%s/%s",
 		    p->fts_parent->fts_accpath, p->fts_name);
-	/*
-	 * We have no way to tell whether a symbolic link has an ACL since
-	 * pathconf() and acl_get_file() both follow them.  They also don't
-	 * support whiteouts.
-	 */
-	if (S_ISLNK(p->fts_statp->st_mode) || S_ISWHT(p->fts_statp->st_mode)) {
-		*haveacls = 1;
-		return;
-	}
-	if ((ret = pathconf(name, _PC_ACL_EXTENDED)) <= 0) {
-		if (ret < 0 && errno != EINVAL)
+
+	if (previous_dev != p->fts_statp->st_dev) {
+		previous_dev = p->fts_statp->st_dev;
+		supports_acls = 0;
+
+		ret = lpathconf(name, _PC_ACL_NFS4);
+		if (ret > 0) {
+			type = ACL_TYPE_NFS4;
+			supports_acls = 1;
+		} else if (ret < 0 && errno != EINVAL) {
 			warn("%s", name);
-		else
-			*haveacls = 0;
+			return;
+		}
+		if (supports_acls == 0) {
+			ret = lpathconf(name, _PC_ACL_EXTENDED);
+			if (ret > 0) {
+				type = ACL_TYPE_ACCESS;
+				supports_acls = 1;
+			} else if (ret < 0 && errno != EINVAL) {
+				warn("%s", name);
+				return;
+			}
+		}
+	}
+	if (supports_acls == 0)
+		return;
+	facl = acl_get_link_np(name, type);
+	if (facl == NULL) {
+		warn("%s", name);
 		return;
 	}
-	*haveacls = 1;
-	if ((facl = acl_get_file(name, ACL_TYPE_ACCESS)) != NULL) {
-		if (acl_get_entry(facl, ACL_FIRST_ENTRY, &ae) == 1) {
-			entries = 1;
-			while (acl_get_entry(facl, ACL_NEXT_ENTRY, &ae) == 1)
-				if (++entries > 3)
-					break;
-			/*
-			 * POSIX.1e requires that ACLs of type ACL_TYPE_ACCESS
-			 * must have at least three entries (owner, group,
-			 * and other). So anything with more than 3 ACLs looks
-			 * interesting to us.
-			 */
-			if (entries > 3)
-				buf[10] = '+';
-		}
+	if (acl_is_trivial_np(facl, &trivial)) {
 		acl_free(facl);
-	} else
 		warn("%s", name);
+		return;
+	}
+	if (!trivial)
+		buf[10] = '+';
+	acl_free(facl);
 }

From 3736d570d36c11706b83ef33d3e8504079801544 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 14:47:23 +0000
Subject: [PATCH 1320/2592] MFC r196753:

- Don't include both  and 

- Keep variables sorted

- Fix logic error with -f and -v options - don't print
  the usual -v output if there was an error, whether or not
  we were passed -f

- Don't call free(3) just before exit(2)

- Whitespace fixes

Submitted by:	bde
---
 bin/chmod/chmod.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/bin/chmod/chmod.c b/bin/chmod/chmod.c
index f70161120f4..dc51faa39b0 100644
--- a/bin/chmod/chmod.c
+++ b/bin/chmod/chmod.c
@@ -41,7 +41,6 @@ static char sccsid[] = "@(#)chmod.c	8.8 (Berkeley) 4/1/94";
 #include 
 __FBSDID("$FreeBSD$");
 
-#include 
 #include 
 #include 
 
@@ -63,7 +62,7 @@ main(int argc, char *argv[])
 	FTS *ftsp;
 	FTSENT *p;
 	mode_t *set;
-	int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, error;
+	int Hflag, Lflag, Rflag, ch, error, fflag, fts_options, hflag, rval;
 	int vflag;
 	char *mode;
 	mode_t newmode;
@@ -170,7 +169,6 @@ done:	argv += optind;
 			 */
 			if (!hflag)
 				continue;
-			/* else */
 			/* FALLTHROUGH */
 		default:
 			break;
@@ -188,9 +186,11 @@ done:	argv += optind;
 			error = lchmod(p->fts_accpath, newmode);
 		else
 			error = chmod(p->fts_accpath, newmode);
-		if (error && !fflag) {
-			warn("%s", p->fts_path);
-			rval = 1;
+		if (error) {
+			if (!fflag) {
+				warn("%s", p->fts_path);
+				rval = 1;
+			}
 		} else {
 			if (vflag) {
 				(void)printf("%s", p->fts_path);
@@ -201,7 +201,6 @@ done:	argv += optind;
 					strmode(p->fts_statp->st_mode, m1);
 					strmode((p->fts_statp->st_mode &
 					    S_IFMT) | newmode, m2);
-
 					(void)printf(": 0%o [%s] -> 0%o [%s]",
 					    p->fts_statp->st_mode, m1,
 					    (p->fts_statp->st_mode & S_IFMT) |
@@ -209,12 +208,10 @@ done:	argv += optind;
 				}
 				(void)printf("\n");
 			}
-
 		}
 	}
 	if (errno)
 		err(1, "fts_read");
-	free(set);
 	exit(rval);
 }
 

From 1ed226c0a910baca514cf02b2c3901033e6b8af6 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 14:49:17 +0000
Subject: [PATCH 1321/2592] MFC r196754:

Add NFSv4 ACL support to cp(1) and fix a few memory leaks.

Note that this changes error reporting behaviour somewhat - before,
no error was reported if ACL couldn't be copied because the target
filesystem doesn't support ACLs.  Now, it will be reported - of course,
only if there actually is an ACL to copy.

Reviewed by:	rwatson
---
 bin/cp/utils.c | 127 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 95 insertions(+), 32 deletions(-)

diff --git a/bin/cp/utils.c b/bin/cp/utils.c
index c27c788a358..63eba422f3d 100644
--- a/bin/cp/utils.c
+++ b/bin/cp/utils.c
@@ -377,24 +377,52 @@ setfile(struct stat *fs, int fd)
 int
 preserve_fd_acls(int source_fd, int dest_fd)
 {
-	struct acl *aclp;
 	acl_t acl;
+	acl_type_t acl_type;
+	int acl_supported = 0, ret, trivial;
 
-	if (fpathconf(source_fd, _PC_ACL_EXTENDED) != 1 ||
-	    fpathconf(dest_fd, _PC_ACL_EXTENDED) != 1)
+	ret = fpathconf(source_fd, _PC_ACL_NFS4);
+	if (ret > 0 ) {
+		acl_supported = 1;
+		acl_type = ACL_TYPE_NFS4;
+	} else if (ret < 0 && errno != EINVAL) {
+		warn("fpathconf(..., _PC_ACL_NFS4) failed for %s", to.p_path);
+		return (1);
+	}
+	if (acl_supported == 0) {
+		ret = fpathconf(source_fd, _PC_ACL_EXTENDED);
+		if (ret > 0 ) {
+			acl_supported = 1;
+			acl_type = ACL_TYPE_ACCESS;
+		} else if (ret < 0 && errno != EINVAL) {
+			warn("fpathconf(..., _PC_ACL_EXTENDED) failed for %s",
+			    to.p_path);
+			return (1);
+		}
+	}
+	if (acl_supported == 0)
 		return (0);
-	acl = acl_get_fd(source_fd);
+
+	acl = acl_get_fd_np(source_fd, acl_type);
 	if (acl == NULL) {
 		warn("failed to get acl entries while setting %s", to.p_path);
 		return (1);
 	}
-	aclp = &acl->ats_acl;
-	if (aclp->acl_cnt == 3)
-		return (0);
-	if (acl_set_fd(dest_fd, acl) < 0) {
-		warn("failed to set acl entries for %s", to.p_path);
+	if (acl_is_trivial_np(acl, &trivial)) {
+		warn("acl_is_trivial() failed for %s", to.p_path);
+		acl_free(acl);
 		return (1);
 	}
+	if (trivial) {
+		acl_free(acl);
+		return (0);
+	}
+	if (acl_set_fd_np(dest_fd, acl, acl_type) < 0) {
+		warn("failed to set acl entries for %s", to.p_path);
+		acl_free(acl);
+		return (1);
+	}
+	acl_free(acl);
 	return (0);
 }
 
@@ -405,10 +433,31 @@ preserve_dir_acls(struct stat *fs, char *source_dir, char *dest_dir)
 	int (*aclsetf)(const char *, acl_type_t, acl_t);
 	struct acl *aclp;
 	acl_t acl;
+	acl_type_t acl_type;
+	int acl_supported = 0, ret, trivial;
 
-	if (pathconf(source_dir, _PC_ACL_EXTENDED) != 1 ||
-	    pathconf(dest_dir, _PC_ACL_EXTENDED) != 1)
+	ret = pathconf(source_dir, _PC_ACL_NFS4);
+	if (ret > 0) {
+		acl_supported = 1;
+		acl_type = ACL_TYPE_NFS4;
+	} else if (ret < 0 && errno != EINVAL) {
+		warn("fpathconf(..., _PC_ACL_NFS4) failed for %s", source_dir);
+		return (1);
+	}
+	if (acl_supported == 0) {
+		ret = pathconf(source_dir, _PC_ACL_EXTENDED);
+		if (ret > 0) {
+			acl_supported = 1;
+			acl_type = ACL_TYPE_ACCESS;
+		} else if (ret < 0 && errno != EINVAL) {
+			warn("fpathconf(..., _PC_ACL_EXTENDED) failed for %s",
+			    source_dir);
+			return (1);
+		}
+	}
+	if (acl_supported == 0)
 		return (0);
+
 	/*
 	 * If the file is a link we will not follow it
 	 */
@@ -419,34 +468,48 @@ preserve_dir_acls(struct stat *fs, char *source_dir, char *dest_dir)
 		aclgetf = acl_get_file;
 		aclsetf = acl_set_file;
 	}
-	/*
-	 * Even if there is no ACL_TYPE_DEFAULT entry here, a zero
-	 * size ACL will be returned. So it is not safe to simply
-	 * check the pointer to see if the default ACL is present.
-	 */
-	acl = aclgetf(source_dir, ACL_TYPE_DEFAULT);
-	if (acl == NULL) {
-		warn("failed to get default acl entries on %s",
-		    source_dir);
-		return (1);
+	if (acl_type == ACL_TYPE_ACCESS) {
+		/*
+		 * Even if there is no ACL_TYPE_DEFAULT entry here, a zero
+		 * size ACL will be returned. So it is not safe to simply
+		 * check the pointer to see if the default ACL is present.
+		 */
+		acl = aclgetf(source_dir, ACL_TYPE_DEFAULT);
+		if (acl == NULL) {
+			warn("failed to get default acl entries on %s",
+			    source_dir);
+			return (1);
+		}
+		aclp = &acl->ats_acl;
+		if (aclp->acl_cnt != 0 && aclsetf(dest_dir,
+		    ACL_TYPE_DEFAULT, acl) < 0) {
+			warn("failed to set default acl entries on %s",
+			    dest_dir);
+			acl_free(acl);
+			return (1);
+		}
+		acl_free(acl);
 	}
-	aclp = &acl->ats_acl;
-	if (aclp->acl_cnt != 0 && aclsetf(dest_dir,
-	    ACL_TYPE_DEFAULT, acl) < 0) {
-		warn("failed to set default acl entries on %s",
-		    dest_dir);
-		return (1);
-	}
-	acl = aclgetf(source_dir, ACL_TYPE_ACCESS);
+	acl = aclgetf(source_dir, acl_type);
 	if (acl == NULL) {
 		warn("failed to get acl entries on %s", source_dir);
 		return (1);
 	}
-	aclp = &acl->ats_acl;
-	if (aclsetf(dest_dir, ACL_TYPE_ACCESS, acl) < 0) {
-		warn("failed to set acl entries on %s", dest_dir);
+	if (acl_is_trivial_np(acl, &trivial)) {
+		warn("acl_is_trivial() failed on %s", source_dir);
+		acl_free(acl);
 		return (1);
 	}
+	if (trivial) {
+		acl_free(acl);
+		return (0);
+	}
+	if (aclsetf(dest_dir, acl_type, acl) < 0) {
+		warn("failed to set acl entries on %s", dest_dir);
+		acl_free(acl);
+		return (1);
+	}
+	acl_free(acl);
 	return (0);
 }
 

From 113c95e756c5ba113864576cf0f5f5244fb90ba3 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 14:51:24 +0000
Subject: [PATCH 1322/2592] MFC r196827:

Add NFSv4 ACL support to getfacl(1).
---
 bin/getfacl/getfacl.1 | 16 ++++++++--
 bin/getfacl/getfacl.c | 73 ++++++++++++++++++++++++++++++++++---------
 2 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/bin/getfacl/getfacl.1 b/bin/getfacl/getfacl.1
index 913530935a3..58202299f65 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 March 13, 2006
+.Dd September 04, 2009
 .Dt GETFACL 1
 .Os
 .Sh NAME
@@ -38,7 +38,7 @@
 .Nd get ACL information
 .Sh SYNOPSIS
 .Nm
-.Op Fl dhq
+.Op Fl dhinqv
 .Op Ar
 .Sh DESCRIPTION
 The
@@ -61,13 +61,25 @@ The operation applies to the default ACL of a directory instead of the
 access ACL.
 An error is generated if a default ACL cannot be associated with
 .Ar file .
+This option is not valid for NFSv4 ACLs.
 .It Fl h
 If the target of the operation is a symbolic link, return the ACL from
 the symbolic link itself rather than following the link.
+.It Fl i
+For NFSv4 ACLs, append numerical ID at the end of each entry containing
+user or group name.
+Ignored for POSIX.1e ACLs.
+.It Fl n
+Display user and group IDs numerically rather than converting to
+a user or group name.
+Ignored for POSIX.1e ACLs.
 .It Fl q
 Do not write commented information about file name and ownership.
 This is
 useful when dealing with filenames with unprintable characters.
+.It Fl v
+For NFSv4 ACLs, display access mask and flags in a verbose form.
+Ignored for POSIX.1e ACLs.
 .El
 .Pp
 The following operand is available:
diff --git a/bin/getfacl/getfacl.c b/bin/getfacl/getfacl.c
index 1ab86cde273..ea376c78f0e 100644
--- a/bin/getfacl/getfacl.c
+++ b/bin/getfacl/getfacl.c
@@ -54,7 +54,7 @@ static void
 usage(void)
 {
 
-	fprintf(stderr, "getfacl [-dhq] [file ...]\n");
+	fprintf(stderr, "getfacl [-dhnqv] [file ...]\n");
 }
 
 static char *
@@ -175,22 +175,39 @@ acl_from_stat(struct stat sb)
 }
 
 static int
-print_acl(char *path, acl_type_t type, int hflag, int qflag)
+print_acl(char *path, acl_type_t type, int hflag, int iflag, int nflag,
+    int qflag, int vflag)
 {
 	struct stat	sb;
 	acl_t	acl;
 	char	*acl_text;
-	int	error;
+	int	error, flags = 0, ret;
 
 	if (hflag)
 		error = lstat(path, &sb);
 	else
 		error = stat(path, &sb);
 	if (error == -1) {
-		warn("%s", path);
+		warn("%s: stat() failed", path);
 		return(-1);
 	}
 
+	if (hflag)
+		ret = lpathconf(path, _PC_ACL_NFS4);
+	else
+		ret = pathconf(path, _PC_ACL_NFS4);
+	if (ret > 0) {
+		if (type == ACL_TYPE_DEFAULT) {
+			warnx("%s: there are no default entries in NFSv4 ACLs",
+			    path);
+			return (-1);
+		}
+		type = ACL_TYPE_NFS4;
+	} else if (ret < 0 && errno != EINVAL) {
+		warn("%s: pathconf(..., _PC_ACL_NFS4) failed", path);
+		return (-1);
+	}
+
 	if (more_than_one)
 		printf("\n");
 	else
@@ -210,18 +227,27 @@ print_acl(char *path, acl_type_t type, int hflag, int qflag)
 			return(-1);
 		}
 		errno = 0;
-		if (type != ACL_TYPE_ACCESS)
+		if (type == ACL_TYPE_DEFAULT)
 			return(0);
 		acl = acl_from_stat(sb);
 		if (!acl) {
-			warn("acl_from_stat()");
+			warn("%s: acl_from_stat() failed", path);
 			return(-1);
 		}
 	}
 
-	acl_text = acl_to_text(acl, 0);
+	if (iflag)
+		flags |= ACL_TEXT_APPEND_ID;
+
+	if (nflag)
+		flags |= ACL_TEXT_NUMERIC_IDS;
+
+	if (vflag)
+		flags |= ACL_TEXT_VERBOSE;
+
+	acl_text = acl_to_text_np(acl, 0, flags);
 	if (!acl_text) {
-		warn("%s", path);
+		warn("%s: acl_to_text_np() failed", path);
 		return(-1);
 	}
 
@@ -234,7 +260,8 @@ print_acl(char *path, acl_type_t type, int hflag, int qflag)
 }
 
 static int
-print_acl_from_stdin(acl_type_t type, int hflag, int qflag)
+print_acl_from_stdin(acl_type_t type, int hflag, int iflag, int nflag,
+    int qflag, int vflag)
 {
 	char	*p, pathname[PATH_MAX];
 	int	carried_error = 0;
@@ -242,7 +269,8 @@ print_acl_from_stdin(acl_type_t type, int hflag, int qflag)
 	while (fgets(pathname, (int)sizeof(pathname), stdin)) {
 		if ((p = strchr(pathname, '\n')) != NULL)
 			*p = '\0';
-		if (print_acl(pathname, type, hflag, qflag) == -1) {
+		if (print_acl(pathname, type, hflag, iflag, nflag,
+		    qflag, vflag) == -1) {
 			carried_error = -1;
 		}
 	}
@@ -256,11 +284,14 @@ main(int argc, char *argv[])
 	acl_type_t	type = ACL_TYPE_ACCESS;
 	int	carried_error = 0;
 	int	ch, error, i;
-	int	hflag, qflag;
+	int	hflag, iflag, qflag, nflag, vflag;
 
 	hflag = 0;
+	iflag = 0;
 	qflag = 0;
-	while ((ch = getopt(argc, argv, "dhq")) != -1)
+	nflag = 0;
+	vflag = 0;
+	while ((ch = getopt(argc, argv, "dhinqv")) != -1)
 		switch(ch) {
 		case 'd':
 			type = ACL_TYPE_DEFAULT;
@@ -268,9 +299,18 @@ main(int argc, char *argv[])
 		case 'h':
 			hflag = 1;
 			break;
+		case 'i':
+			iflag = 1;
+			break;
+		case 'n':
+			nflag = 1;
+			break;
 		case 'q':
 			qflag = 1;
 			break;
+		case 'v':
+			vflag = 1;
+			break;
 		default:
 			usage();
 			return(-1);
@@ -279,17 +319,20 @@ main(int argc, char *argv[])
 	argv += optind;
 
 	if (argc == 0) {
-		error = print_acl_from_stdin(type, hflag, qflag);
+		error = print_acl_from_stdin(type, hflag, iflag, nflag,
+		    qflag, vflag);
 		return(error ? 1 : 0);
 	}
 
 	for (i = 0; i < argc; i++) {
 		if (!strcmp(argv[i], "-")) {
-			error = print_acl_from_stdin(type, hflag, qflag);
+			error = print_acl_from_stdin(type, hflag, iflag, nflag,
+			    qflag, vflag);
 			if (error == -1)
 				carried_error = -1;
 		} else {
-			error = print_acl(argv[i], type, hflag, qflag);
+			error = print_acl(argv[i], type, hflag, iflag, nflag,
+			    qflag, vflag);
 			if (error == -1)
 				carried_error = -1;
 		}

From 4e86d39db2fc24f70a2dd0c8aa09b1b738d3a48b Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 14:54:12 +0000
Subject: [PATCH 1323/2592] MFC r196839:

Add NFSv4 ACL support to find(1).
---
 usr.bin/find/function.c | 64 ++++++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 27 deletions(-)

diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index bfa0a36a9c5..c11d24f8bab 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -371,38 +371,48 @@ c_mXXdepth(OPTION *option, char ***argvp)
 int
 f_acl(PLAN *plan __unused, FTSENT *entry)
 {
-	int match, entries;
-	acl_entry_t ae;
 	acl_t facl;
+	acl_type_t acl_type;
+	int acl_supported = 0, ret, trivial;
 
 	if (S_ISLNK(entry->fts_statp->st_mode))
 		return 0;
-	if ((match = pathconf(entry->fts_accpath, _PC_ACL_EXTENDED)) <= 0) {
-		if (match < 0 && errno != EINVAL)
-			warn("%s", entry->fts_accpath);
-	else
-		return 0;
-	}
-	match = 0;
-	if ((facl = acl_get_file(entry->fts_accpath,ACL_TYPE_ACCESS)) != NULL) {
-		if (acl_get_entry(facl, ACL_FIRST_ENTRY, &ae) == 1) {
-			/*
-			 * POSIX.1e requires that ACLs of type ACL_TYPE_ACCESS
-			 * must have at least three entries (owner, group,
-			 * other).
-			 */
-			entries = 1;
-			while (acl_get_entry(facl, ACL_NEXT_ENTRY, &ae) == 1) {
-				if (++entries > 3) {
-					match = 1;
-					break;
-				}
-			}
-		}
-		acl_free(facl);
-	} else
+	ret = pathconf(entry->fts_accpath, _PC_ACL_NFS4);
+	if (ret > 0) {
+		acl_supported = 1;
+		acl_type = ACL_TYPE_NFS4;
+	} else if (ret < 0 && errno != EINVAL) {
 		warn("%s", entry->fts_accpath);
-	return match;
+		return (0);
+	}
+	if (acl_supported == 0) {
+		ret = pathconf(entry->fts_accpath, _PC_ACL_EXTENDED);
+		if (ret > 0) {
+			acl_supported = 1;
+			acl_type = ACL_TYPE_ACCESS;
+		} else if (ret < 0 && errno != EINVAL) {
+			warn("%s", entry->fts_accpath);
+			return (0);
+		}
+	}
+	if (acl_supported == 0)
+		return (0);
+
+	facl = acl_get_file(entry->fts_accpath, acl_type);
+	if (facl == NULL) {
+		warn("%s", entry->fts_accpath);
+		return (0);
+	}
+	ret = acl_is_trivial_np(facl, &trivial);
+	acl_free(facl);
+	if (ret) {
+		warn("%s", entry->fts_accpath);
+		acl_free(facl);
+		return (0);
+	}
+	if (trivial)
+		return (0);
+	return (1);
 }
 
 PLAN *

From e0649d28d9ae4fa60b7b397e45cc5e357720846c Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 14:56:13 +0000
Subject: [PATCH 1324/2592] MFC r196841:

Add NFSv4 ACL support to mv(1).
---
 bin/mv/mv.c | 70 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 58 insertions(+), 12 deletions(-)

diff --git a/bin/mv/mv.c b/bin/mv/mv.c
index 22bdec19a45..1f98f94657f 100644
--- a/bin/mv/mv.c
+++ b/bin/mv/mv.c
@@ -74,6 +74,8 @@ static int	copy(const char *, const char *);
 static int	do_move(const char *, const char *);
 static int	fastcopy(const char *, const char *, struct stat *);
 static void	usage(void);
+static void	preserve_fd_acls(int source_fd, int dest_fd, const char *source_path,
+		    const char *dest_path);
 
 int
 main(int argc, char *argv[])
@@ -260,7 +262,6 @@ fastcopy(const char *from, const char *to, struct stat *sbp)
 	struct timeval tval[2];
 	static u_int blen;
 	static char *bp;
-	acl_t acl;
 	mode_t oldmode;
 	int nread, from_fd, to_fd;
 
@@ -311,23 +312,15 @@ err:		if (unlink(to))
 			sbp->st_mode &= ~(S_ISUID | S_ISGID);
 		}
 	}
+	if (fchmod(to_fd, sbp->st_mode))
+		warn("%s: set mode (was: 0%03o)", to, oldmode);
 	/*
 	 * POSIX 1003.2c states that if _POSIX_ACL_EXTENDED is in effect
 	 * for dest_file, then its ACLs shall reflect the ACLs of the
 	 * source_file.
 	 */
-	if (fpathconf(to_fd, _PC_ACL_EXTENDED) == 1 &&
-	    fpathconf(from_fd, _PC_ACL_EXTENDED) == 1) {
-		acl = acl_get_fd(from_fd);
-		if (acl == NULL)
-			warn("failed to get acl entries while setting %s",
-			    from);
-		else if (acl_set_fd(to_fd, acl) < 0)
-			warn("failed to set acl entries for %s", to);
-	}
+	preserve_fd_acls(from_fd, to_fd, from, to);
 	(void)close(from_fd);
-	if (fchmod(to_fd, sbp->st_mode))
-		warn("%s: set mode (was: 0%03o)", to, oldmode);
 	/*
 	 * XXX
 	 * NFS doesn't support chflags; ignore errors unless there's reason
@@ -438,6 +431,59 @@ copy(const char *from, const char *to)
 	return (0);
 }
 
+static void
+preserve_fd_acls(int source_fd, int dest_fd, const char *source_path,
+    const char *dest_path)
+{
+	acl_t acl;
+	acl_type_t acl_type;
+	int acl_supported = 0, ret, trivial;
+
+	ret = fpathconf(source_fd, _PC_ACL_NFS4);
+	if (ret > 0 ) {
+		acl_supported = 1;
+		acl_type = ACL_TYPE_NFS4;
+	} else if (ret < 0 && errno != EINVAL) {
+		warn("fpathconf(..., _PC_ACL_NFS4) failed for %s",
+		    source_path);
+		return;
+	}
+	if (acl_supported == 0) {
+		ret = fpathconf(source_fd, _PC_ACL_EXTENDED);
+		if (ret > 0 ) {
+			acl_supported = 1;
+			acl_type = ACL_TYPE_ACCESS;
+		} else if (ret < 0 && errno != EINVAL) {
+			warn("fpathconf(..., _PC_ACL_EXTENDED) failed for %s",
+			    source_path);
+			return;
+		}
+	}
+	if (acl_supported == 0)
+		return;
+
+	acl = acl_get_fd_np(source_fd, acl_type);
+	if (acl == NULL) {
+		warn("failed to get acl entries for %s", source_path);
+		return;
+	}
+	if (acl_is_trivial_np(acl, &trivial)) {
+		warn("acl_is_trivial() failed for %s", source_path);
+		acl_free(acl);
+		return;
+	}
+	if (trivial) {
+		acl_free(acl);
+		return;
+	}
+	if (acl_set_fd_np(dest_fd, acl, acl_type) < 0) {
+		warn("failed to set acl entries for %s", dest_path);
+		acl_free(acl);
+		return;
+	}
+	acl_free(acl);
+}
+
 static void
 usage(void)
 {

From d91f45d608e24542487a3c20c822178912c39338 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 14:58:25 +0000
Subject: [PATCH 1325/2592] MFC r196936:

Add NFSv4 support to setfacl(1).
---
 bin/setfacl/mask.c    |  11 +--
 bin/setfacl/merge.c   | 191 ++++++++++++++++++++++++++++++++++-------
 bin/setfacl/remove.c  | 170 ++++++++++++++++++-------------------
 bin/setfacl/setfacl.1 | 176 ++++++++++++++++++++++++++++++++++----
 bin/setfacl/setfacl.c | 193 ++++++++++++++++++++++++++----------------
 bin/setfacl/setfacl.h |  21 +++--
 6 files changed, 540 insertions(+), 222 deletions(-)

diff --git a/bin/setfacl/mask.c b/bin/setfacl/mask.c
index b275893b1f5..547830279cc 100644
--- a/bin/setfacl/mask.c
+++ b/bin/setfacl/mask.c
@@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
 
 /* set the appropriate mask the given ACL's */
 int
-set_acl_mask(acl_t *prev_acl)
+set_acl_mask(acl_t *prev_acl, const char *filename)
 {
 	acl_entry_t entry;
 	acl_t acl;
@@ -59,7 +59,7 @@ set_acl_mask(acl_t *prev_acl)
 
 	acl = acl_dup(*prev_acl);
 	if (acl == NULL)
-		err(1, "acl_dup() failed");
+		err(1, "%s: acl_dup() failed", filename);
 
 	if (n_flag == 0) {
 		/*
@@ -70,7 +70,7 @@ set_acl_mask(acl_t *prev_acl)
 		 * class in the resulting ACL
 		 */
 		if (acl_calc_mask(&acl)) {
-			warn("acl_calc_mask() failed");
+			warn("%s: acl_calc_mask() failed", filename);
 			acl_free(acl);
 			return (-1);
 		}
@@ -86,7 +86,8 @@ set_acl_mask(acl_t *prev_acl)
 		while (acl_get_entry(acl, entry_id, &entry) == 1) {
 			entry_id = ACL_NEXT_ENTRY;
 			if (acl_get_tag_type(entry, &tag) == -1)
-				err(1, "acl_get_tag_type() failed");
+				err(1, "%s: acl_get_tag_type() failed",
+				    filename);
 
 			if (tag == ACL_MASK) {
 				acl_free(acl);
@@ -100,7 +101,7 @@ set_acl_mask(acl_t *prev_acl)
 		 * file, then write an error message to standard error and
 		 * continue with the next file.
 		 */
-		warnx("warning: no mask entry");
+		warnx("%s: warning: no mask entry", filename);
 		acl_free(acl);
 		return (0);
 	}
diff --git a/bin/setfacl/merge.c b/bin/setfacl/merge.c
index 9f1b5dd48f4..495e66c45a2 100644
--- a/bin/setfacl/merge.c
+++ b/bin/setfacl/merge.c
@@ -36,12 +36,15 @@ __FBSDID("$FreeBSD$");
 
 #include "setfacl.h"
 
-static int merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new);
+static int merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new,
+    int acl_brand);
 
 static int
-merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new)
+merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new, int acl_brand)
 {
 	acl_permset_t permset;
+	acl_entry_type_t entry_type;
+	acl_flagset_t flagset;
 	int have_entry;
 	uid_t *id, *id_new;
 
@@ -59,6 +62,18 @@ merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new)
 			err(1, "acl_get_permset() failed");
 		if (acl_set_permset(*entry_new, permset) == -1)
 			err(1, "acl_set_permset() failed");
+
+		if (acl_brand == ACL_BRAND_NFS4) {
+			if (acl_get_entry_type_np(*entry, &entry_type))
+				err(1, "acl_get_entry_type_np() failed");
+			if (acl_set_entry_type_np(*entry_new, entry_type))
+				err(1, "acl_set_entry_type_np() failed");
+			if (acl_get_flagset_np(*entry, &flagset))
+				err(1, "acl_get_flagset_np() failed");
+			if (acl_set_flagset_np(*entry_new, flagset))
+				err(1, "acl_set_flagset_np() failed");
+		}
+
 		have_entry = 1;
 	}
 	acl_free(id);
@@ -71,20 +86,31 @@ merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new)
  * merge an ACL into existing file's ACL
  */
 int
-merge_acl(acl_t acl, acl_t *prev_acl)
+merge_acl(acl_t acl, acl_t *prev_acl, const char *filename)
 {
 	acl_entry_t entry, entry_new;
 	acl_permset_t permset;
 	acl_t acl_new;
 	acl_tag_t tag, tag_new;
-	int entry_id, entry_id_new, have_entry;
+	acl_entry_type_t entry_type, entry_type_new;
+	acl_flagset_t flagset;
+	int entry_id, entry_id_new, have_entry, entry_number = 0;
+	int acl_brand, prev_acl_brand;
 
-	if (acl_type == ACL_TYPE_ACCESS)
-		acl_new = acl_dup(prev_acl[ACCESS_ACL]);
-	else
-		acl_new = acl_dup(prev_acl[DEFAULT_ACL]);
+	acl_get_brand_np(acl, &acl_brand);
+	acl_get_brand_np(*prev_acl, &prev_acl_brand);
+
+	if (acl_brand != prev_acl_brand) {
+		warnx("%s: branding mismatch; existing ACL is %s, "
+		    "entry to be merged is %s", filename,
+		    prev_acl_brand == ACL_BRAND_NFS4 ? "NFSv4" : "POSIX.1e",
+		    acl_brand == ACL_BRAND_NFS4 ? "NFSv4" : "POSIX.1e");
+		return (-1);
+	}
+
+	acl_new = acl_dup(*prev_acl);
 	if (acl_new == NULL)
-		err(1, "acl_dup() failed");
+		err(1, "%s: acl_dup() failed", filename);
 
 	entry_id = ACL_FIRST_ENTRY;
 
@@ -94,28 +120,45 @@ merge_acl(acl_t acl, acl_t *prev_acl)
 
 		/* keep track of existing ACL_MASK entries */
 		if (acl_get_tag_type(entry, &tag) == -1)
-			err(1, "acl_get_tag_type() failed - invalid ACL entry");
+			err(1, "%s: acl_get_tag_type() failed - "
+			    "invalid ACL entry", filename);
 		if (tag == ACL_MASK)
 			have_mask = 1;
 
 		/* check against the existing ACL entries */
 		entry_id_new = ACL_FIRST_ENTRY;
-		while (have_entry == 0 &&
-		    acl_get_entry(acl_new, entry_id_new, &entry_new) == 1) {
+		while (acl_get_entry(acl_new, entry_id_new, &entry_new) == 1) {
 			entry_id_new = ACL_NEXT_ENTRY;
 
 			if (acl_get_tag_type(entry, &tag) == -1)
-				err(1, "acl_get_tag_type() failed");
+				err(1, "%s: acl_get_tag_type() failed",
+				    filename);
 			if (acl_get_tag_type(entry_new, &tag_new) == -1)
-				err(1, "acl_get_tag_type() failed");
+				err(1, "%s: acl_get_tag_type() failed",
+				    filename);
 			if (tag != tag_new)
 				continue;
 
+			/*
+			 * For NFSv4, in addition to "tag" and "id" we also
+			 * compare "entry_type".
+			 */
+			if (acl_brand == ACL_BRAND_NFS4) {
+				if (acl_get_entry_type_np(entry, &entry_type))
+					err(1, "%s: acl_get_entry_type_np() "
+					    "failed", filename);
+				if (acl_get_entry_type_np(entry_new, &entry_type_new))
+					err(1, "%s: acl_get_entry_type_np() "
+					    "failed", filename);
+				if (entry_type != entry_type_new)
+					continue;
+			}
+		
 			switch(tag) {
 			case ACL_USER:
 			case ACL_GROUP:
 				have_entry = merge_user_group(&entry,
-				    &entry_new);
+				    &entry_new, acl_brand);
 				if (have_entry == 0)
 					break;
 				/* FALLTHROUGH */
@@ -123,37 +166,127 @@ merge_acl(acl_t acl, acl_t *prev_acl)
 			case ACL_GROUP_OBJ:
 			case ACL_OTHER:
 			case ACL_MASK:
+			case ACL_EVERYONE:
 				if (acl_get_permset(entry, &permset) == -1)
-					err(1, "acl_get_permset() failed");
+					err(1, "%s: acl_get_permset() failed",
+					    filename);
 				if (acl_set_permset(entry_new, permset) == -1)
-					err(1, "acl_set_permset() failed");
+					err(1, "%s: acl_set_permset() failed",
+					    filename);
+
+				if (acl_brand == ACL_BRAND_NFS4) {
+					if (acl_get_entry_type_np(entry, &entry_type))
+						err(1, "%s: acl_get_entry_type_np() failed",
+						    filename);
+					if (acl_set_entry_type_np(entry_new, entry_type))
+						err(1, "%s: acl_set_entry_type_np() failed",
+						    filename);
+					if (acl_get_flagset_np(entry, &flagset))
+						err(1, "%s: acl_get_flagset_np() failed",
+						    filename);
+					if (acl_set_flagset_np(entry_new, flagset))
+						err(1, "%s: acl_set_flagset_np() failed",
+						    filename);
+				}
 				have_entry = 1;
 				break;
 			default:
 				/* should never be here */
-				errx(1, "Invalid tag type: %i", tag);
+				errx(1, "%s: invalid tag type: %i", filename, tag);
 				break;
 			}
 		}
 
 		/* if this entry has not been found, it must be new */
 		if (have_entry == 0) {
-			if (acl_create_entry(&acl_new, &entry_new) == -1) {
-				acl_free(acl_new);
-				return (-1);
+
+			/*
+			 * NFSv4 ACL entries must be prepended to the ACL.
+			 * Appending them at the end makes no sense, since
+			 * in most cases they wouldn't even get evaluated.
+			 */
+			if (acl_brand == ACL_BRAND_NFS4) {
+				if (acl_create_entry_np(&acl_new, &entry_new, entry_number) == -1) {
+					warn("%s: acl_create_entry_np() failed", filename); 
+					acl_free(acl_new);
+					return (-1);
+				}
+				/*
+				 * Without this increment, adding several
+				 * entries at once, for example
+				 * "setfacl -m user:1:r:allow,user:2:r:allow",
+				 * would make them appear in reverse order.
+				 */
+				entry_number++;
+			} else {
+				if (acl_create_entry(&acl_new, &entry_new) == -1) {
+					warn("%s: acl_create_entry() failed", filename); 
+					acl_free(acl_new);
+					return (-1);
+				}
 			}
 			if (acl_copy_entry(entry_new, entry) == -1)
-				err(1, "acl_copy_entry() failed");
+				err(1, "%s: acl_copy_entry() failed", filename);
 		}
 	}
 
-	if (acl_type == ACL_TYPE_ACCESS) {
-		acl_free(prev_acl[ACCESS_ACL]);
-		prev_acl[ACCESS_ACL] = acl_new;
-	} else {
-		acl_free(prev_acl[DEFAULT_ACL]);
-		prev_acl[DEFAULT_ACL] = acl_new;
-	}
+	acl_free(*prev_acl);
+	*prev_acl = acl_new;
+
+	return (0);
+}
+
+int
+add_acl(acl_t acl, uint entry_number, acl_t *prev_acl, const char *filename)
+{
+	acl_entry_t entry, entry_new;
+	acl_t acl_new;
+	int entry_id, acl_brand, prev_acl_brand;
+
+	acl_get_brand_np(acl, &acl_brand);
+	acl_get_brand_np(*prev_acl, &prev_acl_brand);
+
+	if (prev_acl_brand != ACL_BRAND_NFS4) {
+		warnx("%s: the '-a' option is only applicable to NFSv4 ACLs",
+		    filename);
+		return (-1);
+	}
+
+	if (acl_brand != ACL_BRAND_NFS4) {
+		warnx("%s: branding mismatch; existing ACL is NFSv4, "
+		    "entry to be added is POSIX.1e", filename);
+		return (-1);
+	}
+
+	acl_new = acl_dup(*prev_acl);
+	if (acl_new == NULL)
+		err(1, "%s: acl_dup() failed", filename);
+
+	entry_id = ACL_FIRST_ENTRY;
+
+	while (acl_get_entry(acl, entry_id, &entry) == 1) {
+		entry_id = ACL_NEXT_ENTRY;
+
+		if (acl_create_entry_np(&acl_new, &entry_new, entry_number) == -1) {
+			warn("%s: acl_create_entry_np() failed", filename); 
+			acl_free(acl_new);
+			return (-1);
+		}
+
+		/*
+		 * Without this increment, adding several
+		 * entries at once, for example
+		 * "setfacl -m user:1:r:allow,user:2:r:allow",
+		 * would make them appear in reverse order.
+		 */
+		entry_number++;
+
+		if (acl_copy_entry(entry_new, entry) == -1)
+			err(1, "%s: acl_copy_entry() failed", filename);
+	}
+
+	acl_free(*prev_acl);
+	*prev_acl = acl_new;
 
 	return (0);
 }
diff --git a/bin/setfacl/remove.c b/bin/setfacl/remove.c
index 23240554a34..6cd82b36d9e 100644
--- a/bin/setfacl/remove.c
+++ b/bin/setfacl/remove.c
@@ -41,21 +41,31 @@ __FBSDID("$FreeBSD$");
  * remove ACL entries from an ACL
  */
 int
-remove_acl(acl_t acl, acl_t *prev_acl)
+remove_acl(acl_t acl, acl_t *prev_acl, const char *filename)
 {
 	acl_entry_t	entry;
 	acl_t		acl_new;
 	acl_tag_t	tag;
-	int		carried_error, entry_id;
+	int		carried_error, entry_id, acl_brand, prev_acl_brand;
 
 	carried_error = 0;
 
-	if (acl_type == ACL_TYPE_ACCESS)
-		acl_new = acl_dup(prev_acl[ACCESS_ACL]);
-	else
-		acl_new = acl_dup(prev_acl[DEFAULT_ACL]);
+	acl_get_brand_np(acl, &acl_brand);
+	acl_get_brand_np(*prev_acl, &prev_acl_brand);
+
+	if (acl_brand != prev_acl_brand) {
+		warnx("%s: branding mismatch; existing ACL is %s, "
+		    "entry to be removed is %s", filename,
+		    prev_acl_brand == ACL_BRAND_NFS4 ? "NFSv4" : "POSIX.1e",
+		    acl_brand == ACL_BRAND_NFS4 ? "NFSv4" : "POSIX.1e");
+		return (-1);
+	}
+
+	carried_error = 0;
+
+	acl_new = acl_dup(*prev_acl);
 	if (acl_new == NULL)
-		err(1, "acl_dup() failed");
+		err(1, "%s: acl_dup() failed", filename);
 
 	tag = ACL_UNDEFINED_TAG;
 
@@ -64,23 +74,68 @@ remove_acl(acl_t acl, acl_t *prev_acl)
 	while (acl_get_entry(acl, entry_id, &entry) == 1) {
 		entry_id = ACL_NEXT_ENTRY;
 		if (acl_get_tag_type(entry, &tag) == -1)
-			err(1, "acl_get_tag_type() failed");
+			err(1, "%s: acl_get_tag_type() failed", filename);
 		if (tag == ACL_MASK)
 			have_mask++;
 		if (acl_delete_entry(acl_new, entry) == -1) {
 			carried_error++;
-			warnx("cannot remove non-existent acl entry");
+			warnx("%s: cannot remove non-existent ACL entry",
+			    filename);
 		}
 	}
 
-	if (acl_type == ACL_TYPE_ACCESS) {
-		acl_free(prev_acl[ACCESS_ACL]);
-		prev_acl[ACCESS_ACL] = acl_new;
-	} else {
-		acl_free(prev_acl[DEFAULT_ACL]);
-		prev_acl[DEFAULT_ACL] = acl_new;
+	acl_free(*prev_acl);
+	*prev_acl = acl_new;
+
+	if (carried_error)
+		return (-1);
+
+	return (0);
+}
+
+int
+remove_by_number(uint entry_number, acl_t *prev_acl, const char *filename)
+{
+	acl_entry_t	entry;
+	acl_t		acl_new;
+	acl_tag_t	tag;
+	int		carried_error, entry_id;
+	uint		i;
+
+	carried_error = 0;
+
+	acl_new = acl_dup(*prev_acl);
+	if (acl_new == NULL)
+		err(1, "%s: acl_dup() failed", filename);
+
+	tag = ACL_UNDEFINED_TAG;
+
+	/*
+	 * Find out whether we're removing the mask entry,
+	 * to behave the same as the routine above.
+	 *
+	 * XXX: Is this loop actually needed?
+	 */
+	entry_id = ACL_FIRST_ENTRY;
+	i = 0;
+	while (acl_get_entry(acl_new, entry_id, &entry) == 1) {
+		entry_id = ACL_NEXT_ENTRY;
+		if (i != entry_number)
+			continue;
+		if (acl_get_tag_type(entry, &tag) == -1)
+			err(1, "%s: acl_get_tag_type() failed", filename);
+		if (tag == ACL_MASK)
+			have_mask++;
 	}
 
+	if (acl_delete_entry_np(acl_new, entry_number) == -1) {
+		carried_error++;
+		warn("%s: acl_delete_entry_np() failed", filename);
+	}
+
+	acl_free(*prev_acl);
+	*prev_acl = acl_new;
+
 	if (carried_error)
 		return (-1);
 
@@ -91,18 +146,14 @@ remove_acl(acl_t acl, acl_t *prev_acl)
  * remove default entries
  */
 int
-remove_default(acl_t *prev_acl)
+remove_default(acl_t *prev_acl, const char *filename)
 {
 
-	if (prev_acl[1]) {
-		acl_free(prev_acl[1]);
-		prev_acl[1] = acl_init(ACL_MAX_ENTRIES);
-		if (prev_acl[1] == NULL)
-			err(1, "acl_init() failed");
-	} else {
-		warn("cannot remove default ACL");
-		return (-1);
-	}
+	acl_free(*prev_acl);
+	*prev_acl = acl_init(ACL_MAX_ENTRIES);
+	if (*prev_acl == NULL)
+		err(1, "%s: acl_init() failed", filename);
+
 	return (0);
 }
 
@@ -110,71 +161,14 @@ remove_default(acl_t *prev_acl)
  * remove extended entries
  */
 void
-remove_ext(acl_t *prev_acl)
+remove_ext(acl_t *prev_acl, const char *filename)
 {
-	acl_t acl_new, acl_old;
-	acl_entry_t entry, entry_new;
-	acl_permset_t perm;
-	acl_tag_t tag;
-	int entry_id, have_mask_entry;
+	acl_t acl_new;
 
-	if (acl_type == ACL_TYPE_ACCESS)
-		acl_old = acl_dup(prev_acl[ACCESS_ACL]);
-	else
-		acl_old = acl_dup(prev_acl[DEFAULT_ACL]);
-	if (acl_old == NULL)
-		err(1, "acl_dup() failed");
-
-	have_mask_entry = 0;
-	acl_new = acl_init(ACL_MAX_ENTRIES);
+	acl_new = acl_strip_np(*prev_acl, !n_flag);
 	if (acl_new == NULL)
-		err(1, "acl_init() failed");
-	tag = ACL_UNDEFINED_TAG;
+		err(1, "%s: acl_strip_np() failed", filename);
 
-	/* only save the default user/group/other entries */
-	entry_id = ACL_FIRST_ENTRY;
-	while (acl_get_entry(acl_old, entry_id, &entry) == 1) {
-		entry_id = ACL_NEXT_ENTRY;
-
-		if (acl_get_tag_type(entry, &tag) == -1)
-			err(1, "acl_get_tag_type() failed");
-
-		switch(tag) {
-		case ACL_USER_OBJ:
-		case ACL_GROUP_OBJ:
-		case ACL_OTHER:
-			if (acl_get_tag_type(entry, &tag) == -1)
-				err(1, "acl_get_tag_type() failed");
-			if (acl_get_permset(entry, &perm) == -1)
-				err(1, "acl_get_permset() failed");
-			if (acl_create_entry(&acl_new, &entry_new) == -1)
-				err(1, "acl_create_entry() failed");
-			if (acl_set_tag_type(entry_new, tag) == -1)
-				err(1, "acl_set_tag_type() failed");
-			if (acl_set_permset(entry_new, perm) == -1)
-				err(1, "acl_get_permset() failed");
-			if (acl_copy_entry(entry_new, entry) == -1)
-				err(1, "acl_copy_entry() failed");
-			break;
-		case ACL_MASK:
-			have_mask_entry = 1;
-			break;
-		default:
-			break;
-		}
-	}
-	if (have_mask_entry && n_flag == 0) {
-		if (acl_calc_mask(&acl_new) == -1)
-			err(1, "acl_calc_mask() failed");
-	} else {
-		have_mask = 1;
-	}
-
-	if (acl_type == ACL_TYPE_ACCESS) {
-		acl_free(prev_acl[ACCESS_ACL]);
-		prev_acl[ACCESS_ACL] = acl_new;
-	} else {
-		acl_free(prev_acl[DEFAULT_ACL]);
-		prev_acl[DEFAULT_ACL] = acl_new;
-	}
+	acl_free(*prev_acl);
+	*prev_acl = acl_new;
 }
diff --git a/bin/setfacl/setfacl.1 b/bin/setfacl/setfacl.1
index e49d18a185a..f527bbbfb3d 100644
--- a/bin/setfacl/setfacl.1
+++ b/bin/setfacl/setfacl.1
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 7, 2001
+.Dd September 5, 2009
 .Dt SETFACL 1
 .Os
 .Sh NAME
@@ -34,9 +34,10 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl bdhkn
+.Op Fl a Ar position entries
 .Op Fl m Ar entries
 .Op Fl M Ar file
-.Op Fl x Ar entries
+.Op Fl x Ar entries | position
 .Op Fl X Ar file
 .Op Ar
 .Sh DESCRIPTION
@@ -50,9 +51,19 @@ the file names are taken from the standard input.
 .Pp
 The following options are available:
 .Bl -tag -width indent
+.It Fl a Ar position entries
+Modify the ACL on the specified files by inserting new
+ACL entries
+specified in
+.Ar entries ,
+starting at position
+.Ar position ,
+counting from zero.
+This option is only applicable to NFSv4 ACLs.
 .It Fl b
-Remove all ACL entries except for the three required entries.
-If the ACL contains a
+Remove all ACL entries except for the three required entries
+(POSIX.1e ACLs) or six "canonical" entries (NFSv4 ACLs).
+If the POSIX.1e ACL contains a
 .Dq Li mask
 entry, the permissions of the
 .Dq Li group
@@ -66,7 +77,7 @@ entries of the current ACL.
 The operations apply to the default ACL entries instead of
 access ACL entries.
 Currently only directories may have
-default ACL's.
+default ACL's.  This option is not applicable to NFSv4 ACLs.
 .It Fl h
 If the target of the operation is a symbolic link, perform the operation
 on the symbolic link itself, rather than following the link.
@@ -77,7 +88,7 @@ is not considered an error if the specified files do not have
 any default ACL entries.
 An error will be reported if any of
 the specified files cannot have a default entry (i.e.\&
-non-directories).
+non-directories).  This option is not applicable to NFSv4 ACLs.
 .It Fl m Ar entries
 Modify the ACL entries on the specified files by adding new
 entries and modifying existing ACL entries with the ACL entries
@@ -95,11 +106,15 @@ is
 the input is taken from stdin.
 .It Fl n
 Do not recalculate the permissions associated with the ACL
-mask entry.
-.It Fl x Ar entries
-Remove the ACL entries specified in
+mask entry.  This option is not applicable to NFSv4 ACLs.
+.It Fl x Ar entries | position
+If
 .Ar entries
+is specified, remove the ACL entries specified there
 from the access or default ACL of the specified files.
+Otherwise, remove entry at index
+.Ar position ,
+counting from zero.
 .It Fl X Ar file
 Remove the ACL entries specified in the file
 .Ar file
@@ -108,8 +123,8 @@ from the access or default ACL of the specified files.
 .Pp
 The above options are evaluated in the order specified
 on the command-line.
-.Sh ACL ENTRIES
-An ACL entry contains three colon-separated fields:
+.Sh POSIX.1e ACL ENTRIES
+A POSIX.1E ACL entry contains three colon-separated fields:
 an ACL tag, an ACL qualifier, and discretionary access
 permissions:
 .Bl -tag -width indent
@@ -223,7 +238,7 @@ previously specified; whitespace is ignored; any text after a
 .Ql #
 is ignored (comments).
 .Pp
-When ACL entries are evaluated, the access check algorithm checks
+When POSIX.1e ACL entries are evaluated, the access check algorithm checks
 the ACL entries in the following order: file owner,
 .Dq Li user
 ACL entries, file owning group,
@@ -243,13 +258,135 @@ ACL entries for user, group, other and mask must be set.
 For more details see the examples below.
 Default ACLs can be created by using
 .Fl d .
+.Sh NFSv4 ACL ENTRIES
+An NFSv4 ACL entry contains four or five colon-separated fields: an ACL tag,
+an ACL qualifier (only for
+.Dq Li user
+and
+.Dq Li group
+tags), discretionary access permissions, ACL inheritance flags, and ACL type:
+.Bl -tag -width indent
+.It Ar "ACL tag"
+The ACL tag specifies the ACL entry type and consists of
+one of the following:
+.Dq Li user
+or
+.Ql u
+specifying the access
+granted to the specified user;
+.Dq Li group
+or
+.Ql g
+specifying the access granted to the specified group;
+.Dq Li owner@
+specifying the access granted to the owner of the file;
+.Dq Li group@
+specifying the access granted to the file owning group;
+.Dq Li everyone@
+specifying everyone.  Note that
+.Dq Li everyone@
+is not the same as traditional Unix
+.Dq Li other
+- it means,
+literally, everyone, including file owner and owning group.
+.It Ar "ACL qualifier"
+The ACL qualifier field describes the user or group associated with
+the ACL entry.
+It may consist of one of the following: uid or
+user name, or gid or group name.  In entries whose tag type is
+one of 
+.Dq Li owner@ ,
+.Dq Li group@ ,
+or
+.Dq Li everyone@ ,
+this field is ommited altogether, including the trailing comma.
+.It Ar "access permissions"
+Access permissions may be specified in either short or long form.
+Short and long forms may not be mixed.
+Permissions in long form are separated by the
+.Ql /
+character; in short form, they are concatenated together.
+Valid permissions are:
+.Bl -tag -width ".Dv short"
+.It Short
+Long
+.It r
+read_data
+.It w
+write_data
+.It x
+execute
+.It p
+append_data
+.It d
+delete_child
+.It D
+delete
+.It a
+read_attributes
+.It A
+write_attributes
+.It R
+read_xattr
+.It W
+write_xattr
+.It c
+read_acl
+.It C
+write_acl
+.It o
+write_owner
+.It S
+synchronize
+.El
+.It Ar "ACL inheritance flags"
+Inheritance flags may be specified in either short or long form.
+Short and long forms may not be mixed.
+Access flags in long form are separated by the
+.Ql /
+character; in short form, they are concatenated together.
+Valid inheritance flags are:
+.Bl -tag -width ".Dv short"
+.It Short
+Long
+.It f
+file_inherit
+.It d
+dir_inherit
+.It i
+inherit_only
+.It n
+no_propagate
+.El
+.Pp
+Inheritance flags may be only set on directories.
+.It Ar "ACL type"
+The ACL type field is either
+.Dq Li allow
+or
+.Dq Li deny .
+.El
+.Pp
+ACL entries applied from a file using the
+.Fl M
+or
+.Fl X
+options shall be of the following form: one ACL entry per line, as
+previously specified; whitespace is ignored; any text after a
+.Ql #
+is ignored (comments).
+.Pp
+NFSv4 ACL entries are evaluated in their visible order.
+.Pp
+Multiple ACL entries specified on the command line are
+separated by commas.
 .Sh EXIT STATUS
 .Ex -std
 .Sh EXAMPLES
 .Dl setfacl -d -m u::rwx,g::rx,o::rx,mask::rwx dir
 .Dl setfacl -d -m g:admins:rwx dir
 .Pp
-The first command sets the mandatory elements of the default ACL.
+The first command sets the mandatory elements of the POSIX.1e default ACL.
 The second command specifies that users in group admins can have read, write, and execute
 permissions for directory named "dir".
 It should be noted that any files or directories created underneath "dir" will
@@ -259,9 +396,13 @@ inherit these default ACLs upon creation.
 .Pp
 Sets read, write, and execute permissions for the
 .Pa file
-owner's ACL entry and read and write permissions for group mail on
+owner's POSIX.1e ACL entry and read and write permissions for group mail on
 .Pa file .
 .Pp
+.Dl setfacl -m owner@:rwxp::allow,g:mail:rwp::allow file
+.Pp
+Semantically equal to the example above, but for NFSv4 ACL.
+.Pp
 .Dl setfacl -M file1 file2
 .Pp
 Sets/updates the ACL entries contained in
@@ -271,10 +412,15 @@ on
 .Pp
 .Dl setfacl -x g:mail:rw file
 .Pp
-Remove the group mail ACL entry containing read/write permissions
+Remove the group mail POSIX.1e ACL entry containing read/write permissions
 from
 .Pa file .
 .Pp
+.Dl setfacl -x0 file
+.Pp
+Remove the first entry from the NFSv4 ACL from
+.Pa file .
+.Pp
 .Dl setfacl -bn file
 .Pp
 Remove all
diff --git a/bin/setfacl/setfacl.c b/bin/setfacl/setfacl.c
index 2286efb244a..2835ba894c4 100644
--- a/bin/setfacl/setfacl.c
+++ b/bin/setfacl/setfacl.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -41,9 +42,8 @@ __FBSDID("$FreeBSD$");
 
 #include "setfacl.h"
 
-static void   add_filename(const char *filename);
-static acl_t *get_file_acls(const char *filename);
-static void   usage(void);
+static void	add_filename(const char *filename);
+static void	usage(void);
 
 static void
 add_filename(const char *filename)
@@ -59,57 +59,28 @@ add_filename(const char *filename)
 	TAILQ_INSERT_TAIL(&filelist, file, next);
 }
 
-static acl_t *
-get_file_acls(const char *filename)
-{
-	acl_t *acl;
-	struct stat sb;
-
-	if (stat(filename, &sb) == -1) {
-		warn("stat() of %s failed", filename);
-		return (NULL);
-	}
-
-	acl = zmalloc(sizeof(acl_t) * 2);
-	if (h_flag)
-		acl[ACCESS_ACL] = acl_get_link_np(filename, ACL_TYPE_ACCESS);
-	else
-		acl[ACCESS_ACL] = acl_get_file(filename, ACL_TYPE_ACCESS);
-	if (acl[ACCESS_ACL] == NULL)
-		err(1, "acl_get_file() failed");
-	if (S_ISDIR(sb.st_mode)) {
-		if (h_flag)
-			acl[DEFAULT_ACL] = acl_get_link_np(filename,
-			    ACL_TYPE_DEFAULT);
-		else
-			acl[DEFAULT_ACL] = acl_get_file(filename,
-			    ACL_TYPE_DEFAULT);
-		if (acl[DEFAULT_ACL] == NULL)
-			err(1, "acl_get_file() failed");
-	} else
-		acl[DEFAULT_ACL] = NULL;
-
-	return (acl);
-}
-
 static void
 usage(void)
 {
 
-	fprintf(stderr, "usage: setfacl [-bdhkn] [-m entries] [-M file] "
-	    "[-x entries] [-X file] [file ...]\n");
+	fprintf(stderr, "usage: setfacl [-bdhkn] [-a position entries] "
+	    "[-m entries] [-M file] [-x entries] [-X file] [file ...]\n");
 	exit(1);
 }
 
 int
 main(int argc, char *argv[])
 {
-	acl_t *acl, final_acl;
+	acl_t acl;
+	acl_type_t acl_type;
 	char filename[PATH_MAX];
-	int local_error, carried_error, ch, i;
+	int local_error, carried_error, ch, i, entry_number, ret;
+	int h_flag;
 	struct sf_file *file;
 	struct sf_entry *entry;
 	const char *fn_dup;
+	char *end;
+	struct stat sb;
 
 	acl_type = ACL_TYPE_ACCESS;
 	carried_error = local_error = 0;
@@ -118,13 +89,13 @@ main(int argc, char *argv[])
 	TAILQ_INIT(&entrylist);
 	TAILQ_INIT(&filelist);
 
-	while ((ch = getopt(argc, argv, "M:X:bdhkm:nx:")) != -1)
+	while ((ch = getopt(argc, argv, "M:X:a:bdhkm:nx:")) != -1)
 		switch(ch) {
 		case 'M':
 			entry = zmalloc(sizeof(struct sf_entry));
 			entry->acl = get_acl_from_file(optarg);
 			if (entry->acl == NULL)
-				err(1, "get_acl_from_file() failed");
+				err(1, "%s: get_acl_from_file() failed", optarg);
 			entry->op = OP_MERGE_ACL;
 			TAILQ_INSERT_TAIL(&entrylist, entry, next);
 			break;
@@ -134,6 +105,25 @@ main(int argc, char *argv[])
 			entry->op = OP_REMOVE_ACL;
 			TAILQ_INSERT_TAIL(&entrylist, entry, next);
 			break;
+		case 'a':
+			entry = zmalloc(sizeof(struct sf_entry));
+
+			entry_number = strtol(optarg, &end, 10);
+			if (end - optarg != (int)strlen(optarg))
+				errx(1, "%s: invalid entry number", optarg);
+			if (entry_number < 0)
+				errx(1, "%s: entry number cannot be less than zero", optarg);
+			entry->entry_number = entry_number;
+
+			if (argv[optind] == NULL)
+				errx(1, "missing ACL");
+			entry->acl = acl_from_text(argv[optind]);
+			if (entry->acl == NULL)
+				err(1, "%s", argv[optind]);
+			optind++;
+			entry->op = OP_ADD_ACL;
+			TAILQ_INSERT_TAIL(&entrylist, entry, next);
+			break;
 		case 'b':
 			entry = zmalloc(sizeof(struct sf_entry));
 			entry->op = OP_REMOVE_EXT;
@@ -163,10 +153,18 @@ main(int argc, char *argv[])
 			break;
 		case 'x':
 			entry = zmalloc(sizeof(struct sf_entry));
-			entry->acl = acl_from_text(optarg);
-			if (entry->acl == NULL)
-				err(1, "%s", optarg);
-			entry->op = OP_REMOVE_ACL;
+			entry_number = strtol(optarg, &end, 10);
+			if (end - optarg == (int)strlen(optarg)) {
+				if (entry_number < 0)
+					errx(1, "%s: entry number cannot be less than zero", optarg);
+				entry->entry_number = entry_number;
+				entry->op = OP_REMOVE_BY_NUMBER;
+			} else {
+				entry->acl = acl_from_text(optarg);
+				if (entry->acl == NULL)
+					err(1, "%s", optarg);
+				entry->op = OP_REMOVE_ACL;
+			}
 			TAILQ_INSERT_TAIL(&entrylist, entry, next);
 			break;
 		default:
@@ -199,16 +197,51 @@ main(int argc, char *argv[])
 
 	/* cycle through each file */
 	TAILQ_FOREACH(file, &filelist, next) {
-		/* get our initial access and default ACL's */
-		acl = get_file_acls(file->filename);
-		if (acl == NULL)
-			continue;
-		if ((acl_type == ACL_TYPE_DEFAULT) && !acl[1]) {
-			warnx("Default ACL not valid for %s", file->filename);
+		local_error = 0;
+
+		if (stat(file->filename, &sb) == -1) {
+			warn("%s: stat() failed", file->filename);
 			continue;
 		}
 
-		local_error = 0;
+		if (acl_type == ACL_TYPE_DEFAULT && S_ISDIR(sb.st_mode) == 0) {
+			warnx("%s: default ACL may only be set on a directory",
+			    file->filename);
+			continue;
+		}
+
+		if (h_flag)
+			ret = lpathconf(file->filename, _PC_ACL_NFS4);
+		else
+			ret = pathconf(file->filename, _PC_ACL_NFS4);
+		if (ret > 0) {
+			if (acl_type == ACL_TYPE_DEFAULT) {
+				warnx("%s: there are no default entries "
+			           "in NFSv4 ACLs", file->filename);
+				continue;
+			}
+			acl_type = ACL_TYPE_NFS4;
+		} else if (ret == 0) {
+			if (acl_type == ACL_TYPE_NFS4)
+				acl_type = ACL_TYPE_ACCESS;
+		} else if (ret < 0 && errno != EINVAL) {
+			warn("%s: pathconf(..., _PC_ACL_NFS4) failed",
+			    file->filename);
+		}
+
+		if (h_flag)
+			acl = acl_get_link_np(file->filename, acl_type);
+		else
+			acl = acl_get_file(file->filename, acl_type);
+		if (acl == NULL) {
+			if (h_flag)
+				warn("%s: acl_get_link_np() failed",
+				    file->filename);
+			else
+				warn("%s: acl_get_file() failed",
+				    file->filename);
+			continue;
+		}
 
 		/* cycle through each option */
 		TAILQ_FOREACH(entry, &entrylist, next) {
@@ -216,24 +249,44 @@ main(int argc, char *argv[])
 				continue;
 
 			switch(entry->op) {
+			case OP_ADD_ACL:
+				local_error += add_acl(entry->acl,
+				    entry->entry_number, &acl, file->filename);
+				break;
 			case OP_MERGE_ACL:
-				local_error += merge_acl(entry->acl, acl);
+				local_error += merge_acl(entry->acl, &acl,
+				    file->filename);
 				need_mask = 1;
 				break;
 			case OP_REMOVE_EXT:
-				remove_ext(acl);
+				remove_ext(&acl, file->filename);
 				need_mask = 0;
 				break;
 			case OP_REMOVE_DEF:
+				if (acl_type == ACL_TYPE_NFS4) {
+					warnx("%s: there are no default entries in NFSv4 ACLs; "
+					    "cannot remove", file->filename);
+					local_error++;
+					break;
+				}
 				if (acl_delete_def_file(file->filename) == -1) {
-					warn("acl_delete_def_file() failed");
+					warn("%s: acl_delete_def_file() failed",
+					    file->filename);
 					local_error++;
 				}
-				local_error += remove_default(acl);
+				if (acl_type == ACL_TYPE_DEFAULT)
+					local_error += remove_default(&acl,
+					    file->filename);
 				need_mask = 0;
 				break;
 			case OP_REMOVE_ACL:
-				local_error += remove_acl(entry->acl, acl);
+				local_error += remove_acl(entry->acl, &acl,
+				    file->filename);
+				need_mask = 1;
+				break;
+			case OP_REMOVE_BY_NUMBER:
+				local_error += remove_by_number(entry->entry_number,
+				    &acl, file->filename);
 				need_mask = 1;
 				break;
 			}
@@ -245,35 +298,27 @@ main(int argc, char *argv[])
 			continue;
 		}
 
-		if (acl_type == ACL_TYPE_ACCESS) {
-			final_acl = acl[ACCESS_ACL];
-			acl_free(acl[DEFAULT_ACL]);
-		} else {
-			final_acl = acl[DEFAULT_ACL];
-			acl_free(acl[ACCESS_ACL]);
-		}
-
-		if (need_mask && (set_acl_mask(&final_acl) == -1)) {
-			warnx("failed to set ACL mask on %s", file->filename);
+		if (acl_type != ACL_TYPE_NFS4 && need_mask &&
+		    set_acl_mask(&acl, file->filename) == -1) {
+			warnx("%s: failed to set ACL mask", file->filename);
 			carried_error++;
 		} else if (h_flag) {
 			if (acl_set_link_np(file->filename, acl_type,
-			    final_acl) == -1) {
+			    acl) == -1) {
 				carried_error++;
-				warn("acl_set_link_np() failed for %s",
+				warn("%s: acl_set_link_np() failed",
 				    file->filename);
 			}
 		} else {
 			if (acl_set_file(file->filename, acl_type,
-			    final_acl) == -1) {
+			    acl) == -1) {
 				carried_error++;
-				warn("acl_set_file() failed for %s",
+				warn("%s: acl_set_file() failed",
 				    file->filename);
 			}
 		}
 
-		acl_free(final_acl);
-		free(acl);
+		acl_free(acl);
 	}
 
 	return (carried_error);
diff --git a/bin/setfacl/setfacl.h b/bin/setfacl/setfacl.h
index bdf052ba0a8..7c11b3a14f7 100644
--- a/bin/setfacl/setfacl.h
+++ b/bin/setfacl/setfacl.h
@@ -38,15 +38,14 @@
 #define	OP_REMOVE_DEF		0x01	/* remove default acl's (-k) */
 #define	OP_REMOVE_EXT		0x02	/* remove extended acl's (-b) */
 #define	OP_REMOVE_ACL		0x03	/* remove acl's (-xX) */
-
-/* ACL types for the acl array */
-#define ACCESS_ACL	0
-#define DEFAULT_ACL	1
+#define OP_REMOVE_BY_NUMBER	0x04	/* remove acl's (-xX) by acl entry number */
+#define OP_ADD_ACL		0x05	/* add acls entries at a given position */
 
 /* TAILQ entry for acl operations */
 struct sf_entry {
 	uint	op;
 	acl_t	acl;
+	uint	entry_number;
 	TAILQ_ENTRY(sf_entry) next;
 };
 TAILQ_HEAD(, sf_entry) entrylist;
@@ -61,21 +60,21 @@ TAILQ_HEAD(, sf_file) filelist;
 /* files.c */
 acl_t  get_acl_from_file(const char *filename);
 /* merge.c */
-int    merge_acl(acl_t acl, acl_t *prev_acl);
+int    merge_acl(acl_t acl, acl_t *prev_acl, const char *filename);
+int    add_acl(acl_t acl, uint entry_number, acl_t *prev_acl, const char *filename);
 /* remove.c */
-int    remove_acl(acl_t acl, acl_t *prev_acl);
-int    remove_default(acl_t *prev_acl);
-void   remove_ext(acl_t *prev_acl);
+int    remove_acl(acl_t acl, acl_t *prev_acl, const char *filename);
+int    remove_by_number(uint entry_number, acl_t *prev_acl, const char *filename);
+int    remove_default(acl_t *prev_acl, const char *filename);
+void   remove_ext(acl_t *prev_acl, const char *filename);
 /* mask.c */
-int    set_acl_mask(acl_t *prev_acl);
+int    set_acl_mask(acl_t *prev_acl, const char *filename);
 /* util.c */
 void  *zmalloc(size_t size);
 
-acl_type_t acl_type;
 uint       have_mask;
 uint       need_mask;
 uint       have_stdin;
-uint       h_flag;
 uint       n_flag;
 
 #endif /* _SETFACL_H */

From c261b5023b850f1bbd30e4a8071024b68c21d637 Mon Sep 17 00:00:00 2001
From: Antoine Brodin 
Date: Sat, 30 Jan 2010 15:28:14 +0000
Subject: [PATCH 1326/2592] MFC r202448 to stable/8:   Do not build netgraph
 kernel modules if WITHOUT_NETGRAPH is set in src.conf   Submitted by:	bf

---
 sys/modules/Makefile | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 044976dc3d4..e76d63ad39a 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -191,7 +191,7 @@ SUBDIR=	${_3dfx} \
 	${_ncp} \
 	${_ncv} \
 	${_ndis} \
-	netgraph \
+	${_netgraph} \
 	${_nfe} \
 	nfscl \
 	nfsclient \
@@ -324,6 +324,10 @@ _random=	random
 _ipfilter=	ipfilter
 .endif
 
+.if ${MK_NETGRAPH} != "no" || defined(ALL_MODULES)
+_netgraph=	netgraph
+.endif
+
 .if ${MK_PF} != "no" || defined(ALL_MODULES)
 _pf=		pf
 _pflog=		pflog

From c9e0de01794404e26c369012ccf185950f0d2ab9 Mon Sep 17 00:00:00 2001
From: Antoine Brodin 
Date: Sat, 30 Jan 2010 15:40:00 +0000
Subject: [PATCH 1327/2592] MFC r202440 to stable/8:   Unbreak world
 WITHOUT_NETGRAPH.

  PR:		137487
  Submitted by:	bf (previous version)
  No objections:	net@
---
 share/mk/bsd.own.mk   | 5 +++++
 usr.sbin/ppp/Makefile | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk
index 4206969b19a..84ae433b16b 100644
--- a/share/mk/bsd.own.mk
+++ b/share/mk/bsd.own.mk
@@ -468,6 +468,11 @@ MK_MAILWRAPPER:= no
 MK_SENDMAIL:=	no
 .endif
 
+.if ${MK_NETGRAPH} == "no"
+MK_ATM:=	no
+MK_BLUETOOTH:=	no
+.endif
+
 .if ${MK_OPENSSL} == "no"
 MK_OPENSSH:=	no
 MK_KERBEROS:=	no
diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile
index e8ae0e3de3d..11003d750ae 100644
--- a/usr.sbin/ppp/Makefile
+++ b/usr.sbin/ppp/Makefile
@@ -25,6 +25,9 @@ PPP_NO_SUID=
 .if ${MK_ATM} == "no"
 PPP_NO_ATM=
 .endif
+.if ${MK_NETGRAPH} == "no"
+PPP_NO_NETGRAPH=
+.endif
 .if ${MK_PAM_SUPPORT} == "no"
 PPP_NO_PAM=
 .endif

From 7ca8d389fe2915a2170634c46c36a916943f9bf6 Mon Sep 17 00:00:00 2001
From: Antoine Brodin 
Date: Sat, 30 Jan 2010 15:42:06 +0000
Subject: [PATCH 1328/2592] Regenerate.

---
 share/man/man5/src.conf.5 | 250 +++++++++++++++++++-------------------
 1 file changed, 127 insertions(+), 123 deletions(-)

diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
index 7cacc67ad52..8c53f160765 100644
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -1,7 +1,7 @@
 .\" DO NOT EDIT-- this file is automatically generated.
-.\" from FreeBSD: head/tools/build/options/makeman 188848 2009-02-20 11:09:55Z mtm
+.\" from FreeBSD: stable/8/tools/build/options/makeman 188848 2009-02-20 11:09:55Z mtm
 .\" $FreeBSD$
-.Dd June  1, 2009
+.Dd January 30, 2010
 .Dt SRC.CONF 5
 .Os
 .Sh NAME
@@ -78,51 +78,51 @@ The following list provides a name and short description for variables
 that can be used for source builds.
 .Bl -tag -width indent
 .It Va WITHOUT_ACCT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_ACCT 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_ACCT 183242 2008-09-21 22:02:26Z sam
 Set to not build process accounting tools such as
 .Xr ac 8 
 and
 .Xr accton 8 .
 .It Va WITHOUT_ACPI
-.\" from FreeBSD: head/tools/build/options/WITHOUT_ACPI 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_ACPI 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr acpiconf 8 ,
 .Xr acpidump 8
 and related programs.
 .It Va WITHOUT_AMD
-.\" from FreeBSD: head/tools/build/options/WITHOUT_AMD 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_AMD 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr amd 8 ,
 and related programs.
 .It Va WITHOUT_APM
-.\" from FreeBSD: head/tools/build/options/WITHOUT_APM 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_APM 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr apm 8 ,
 .Xr apmd 8
 and related programs.
 .It Va WITHOUT_ASSERT_DEBUG
-.\" from FreeBSD: head/tools/build/options/WITHOUT_ASSERT_DEBUG 162215 2006-09-11 13:55:27Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_ASSERT_DEBUG 162215 2006-09-11 13:55:27Z ru
 Set to compile programs and libraries without the
 .Xr assert 3
 checks.
 .It Va WITHOUT_AT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_AT 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_AT 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr at 1
 and related utilities.
 .It Va WITHOUT_ATM
-.\" from FreeBSD: head/tools/build/options/WITHOUT_ATM 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_ATM 156932 2006-03-21 07:50:50Z ru
 Set to not build
 programs and libraries related to ATM networking.
 .It Va WITHOUT_AUDIT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_AUDIT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_AUDIT 156932 2006-03-21 07:50:50Z ru
 Set to not build audit support into system programs.
 .It Va WITHOUT_AUTHPF
-.\" from FreeBSD: head/tools/build/options/WITHOUT_AUTHPF 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_AUTHPF 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr authpf 8 .
 .It Va WITHOUT_BIND
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BIND 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BIND 156932 2006-03-21 07:50:50Z ru
 Setting this variable will prevent any part of BIND from being built.
 When set, it also enforces the following options:
 .Pp
@@ -141,31 +141,31 @@ When set, it also enforces the following options:
 .Va WITHOUT_BIND_UTILS
 .El
 .It Va WITHOUT_BIND_DNSSEC
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BIND_DNSSEC 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BIND_DNSSEC 156932 2006-03-21 07:50:50Z ru
 Set to avoid building or installing the DNSSEC related binaries,
 .Xr dnssec-keygen 8
 and
 .Xr dnssec-signzone 8 .
 .It Va WITHOUT_BIND_ETC
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BIND_ETC 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BIND_ETC 156932 2006-03-21 07:50:50Z ru
 Set to avoid installing the default files to
 .Pa /var/named/etc/namedb .
 .It Va WITH_BIND_IDN
-.\" from FreeBSD: head/tools/build/options/WITH_BIND_IDN 193280 2009-06-01 21:58:59Z dougb
+.\" from FreeBSD: stable/8/tools/build/options/WITH_BIND_IDN 193280 2009-06-01 21:58:59Z dougb
 Set to enable IDN support for dig, host, and nslookup.
 This requires ports/dns/idnkit to be installed in /usr/local.
 .It Va WITH_BIND_LARGE_FILE
-.\" from FreeBSD: head/tools/build/options/WITH_BIND_LARGE_FILE 193280 2009-06-01 21:58:59Z dougb
+.\" from FreeBSD: stable/8/tools/build/options/WITH_BIND_LARGE_FILE 193280 2009-06-01 21:58:59Z dougb
 Set to enable 64-bit file support.
 .It Va WITH_BIND_LIBS
-.\" from FreeBSD: head/tools/build/options/WITH_BIND_LIBS 193280 2009-06-01 21:58:59Z dougb
+.\" from FreeBSD: stable/8/tools/build/options/WITH_BIND_LIBS 193280 2009-06-01 21:58:59Z dougb
 Set to install BIND libraries and include files.
 .It Va WITHOUT_BIND_LIBS_LWRES
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BIND_LIBS_LWRES 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BIND_LIBS_LWRES 156932 2006-03-21 07:50:50Z ru
 Set to avoid installing the lightweight resolver library in
 .Pa /usr/lib .
 .It Va WITHOUT_BIND_MTREE
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BIND_MTREE 157717 2006-04-13 10:37:29Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BIND_MTREE 157717 2006-04-13 10:37:29Z ru
 Set to avoid running
 .Xr mtree 8
 to create the chroot directory structure under
@@ -180,7 +180,7 @@ When set, it also enforces the following options:
 .Va WITHOUT_BIND_ETC
 .El
 .It Va WITHOUT_BIND_NAMED
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BIND_NAMED 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BIND_NAMED 156932 2006-03-21 07:50:50Z ru
 Set to avoid building or installing
 .Xr named 8 ,
 .Xr named.reload 8 ,
@@ -190,10 +190,10 @@ Set to avoid building or installing
 and
 .Xr rndc-confgen 8 .
 .It Va WITH_BIND_SIGCHASE
-.\" from FreeBSD: head/tools/build/options/WITH_BIND_SIGCHASE 193280 2009-06-01 21:58:59Z dougb
+.\" from FreeBSD: stable/8/tools/build/options/WITH_BIND_SIGCHASE 193280 2009-06-01 21:58:59Z dougb
 Set to enable DNSSEC validation support for dig, host, and nslookup.
 .It Va WITHOUT_BIND_UTILS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BIND_UTILS 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BIND_UTILS 156932 2006-03-21 07:50:50Z ru
 Set to avoid building or installing the BIND userland utilities,
 .Xr dig 1 ,
 .Xr host 1 ,
@@ -201,26 +201,26 @@ Set to avoid building or installing the BIND userland utilities,
 and
 .Xr nsupdate 8 .
 .It Va WITH_BIND_XML
-.\" from FreeBSD: head/tools/build/options/WITH_BIND_XML 193280 2009-06-01 21:58:59Z dougb
+.\" from FreeBSD: stable/8/tools/build/options/WITH_BIND_XML 193280 2009-06-01 21:58:59Z dougb
 Set to enable the http statistics interface for named.
 This requires ports/textproc/libxml2 to be installed in /usr/local.
 .It Va WITHOUT_BLUETOOTH
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BLUETOOTH 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BLUETOOTH 156932 2006-03-21 07:50:50Z ru
 Set to not build Bluetooth related kernel modules, programs and libraries.
 .It Va WITHOUT_BOOT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BOOT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BOOT 156932 2006-03-21 07:50:50Z ru
 Set to not build the boot blocks and loader.
 .It Va WITHOUT_BSD_CPIO
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BSD_CPIO 179813 2008-06-16 05:48:15Z dougb
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BSD_CPIO 179813 2008-06-16 05:48:15Z dougb
 Set to not build the BSD licensed version of cpio based on
 .Xr libarchive 3 .
 .It Va WITHOUT_BSNMP
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BSNMP 183306 2008-09-23 16:15:42Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BSNMP 183306 2008-09-23 16:15:42Z sam
 Set to not build or install
 .Xr bsnmpd 1
 and related libraries and data files.
 .It Va WITHOUT_BZIP2
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BZIP2 174550 2007-12-12 16:43:17Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BZIP2 174550 2007-12-12 16:43:17Z ru
 Set to not build contributed bzip2 software as a part of the base system.
 .Bf -symbolic
 The option has no effect yet.
@@ -232,14 +232,14 @@ When set, it also enforces the following options:
 .Va WITHOUT_BZIP2_SUPPORT
 .El
 .It Va WITHOUT_BZIP2_SUPPORT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_BZIP2_SUPPORT 166255 2007-01-26 10:19:08Z delphij
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_BZIP2_SUPPORT 166255 2007-01-26 10:19:08Z delphij
 Set to build some programs without optional bzip2 support.
 .It Va WITHOUT_CALENDAR
-.\" from FreeBSD: head/tools/build/options/WITHOUT_CALENDAR 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_CALENDAR 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr calendar 1 .
 .It Va WITHOUT_CDDL
-.\" from FreeBSD: head/tools/build/options/WITHOUT_CDDL 163861 2006-11-01 09:02:11Z jb
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_CDDL 163861 2006-11-01 09:02:11Z jb
 Set to not build code licensed under Sun's CDDL.
 When set, it also enforces the following options:
 .Pp
@@ -248,11 +248,11 @@ When set, it also enforces the following options:
 .Va WITHOUT_ZFS
 .El
 .It Va WITHOUT_CPP
-.\" from FreeBSD: head/tools/build/options/WITHOUT_CPP 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_CPP 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr cpp 1 .
 .It Va WITHOUT_CRYPT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_CRYPT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_CRYPT 156932 2006-03-21 07:50:50Z ru
 Set to not build any crypto code.
 When set, it also enforces the following options:
 .Pp
@@ -271,62 +271,62 @@ When set, it also enforces the following options:
 .Va WITHOUT_OPENSSL
 .El
 .It Va WITHOUT_CTM
-.\" from FreeBSD: head/tools/build/options/WITHOUT_CTM 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_CTM 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr ctm 1
 and related utilities.
 .It Va WITHOUT_CVS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_CVS 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_CVS 156932 2006-03-21 07:50:50Z ru
 Set to not build CVS.
 .It Va WITHOUT_CXX
-.\" from FreeBSD: head/tools/build/options/WITHOUT_CXX 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_CXX 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr g++ 1
 and related libraries.
 .It Va WITHOUT_DICT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_DICT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_DICT 156932 2006-03-21 07:50:50Z ru
 Set to not build the Webster dictionary files.
 .It Va WITHOUT_DYNAMICROOT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_DYNAMICROOT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_DYNAMICROOT 156932 2006-03-21 07:50:50Z ru
 Set this if you do not want to link
 .Pa /bin
 and
 .Pa /sbin
 dynamically.
 .It Va WITHOUT_EXAMPLES
-.\" from FreeBSD: head/tools/build/options/WITHOUT_EXAMPLES 156938 2006-03-21 09:06:24Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_EXAMPLES 156938 2006-03-21 09:06:24Z ru
 Set to avoid installing examples to
 .Pa /usr/share/examples/ .
 .It Va WITHOUT_FLOPPY
-.\" from FreeBSD: head/tools/build/options/WITHOUT_FLOPPY 183306 2008-09-23 16:15:42Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_FLOPPY 183306 2008-09-23 16:15:42Z sam
 Set to not build or install programs 
 for operating floppy disk driver.
 .It Va WITHOUT_FORTH
-.\" from FreeBSD: head/tools/build/options/WITHOUT_FORTH 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_FORTH 156932 2006-03-21 07:50:50Z ru
 Set to build bootloaders without Forth support.
 .It Va WITHOUT_FP_LIBC
-.\" from FreeBSD: head/tools/build/options/WITHOUT_FP_LIBC 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_FP_LIBC 156932 2006-03-21 07:50:50Z ru
 Set to build
 .Nm libc
 without floating-point support.
 .It Va WITHOUT_FREEBSD_UPDATE
-.\" from FreeBSD: head/tools/build/options/WITHOUT_FREEBSD_UPDATE 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_FREEBSD_UPDATE 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr freebsd-update 8 .
 .It Va WITHOUT_GAMES
-.\" from FreeBSD: head/tools/build/options/WITHOUT_GAMES 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GAMES 156932 2006-03-21 07:50:50Z ru
 Set to not build games.
 .It Va WITHOUT_GCOV
-.\" from FreeBSD: head/tools/build/options/WITHOUT_GCOV 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GCOV 156932 2006-03-21 07:50:50Z ru
 Set to not build the
 .Xr gcov 1
 tool.
 .It Va WITHOUT_GDB
-.\" from FreeBSD: head/tools/build/options/WITHOUT_GDB 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GDB 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr gdb 1 .
 .It Va WITHOUT_GNU
-.\" from FreeBSD: head/tools/build/options/WITHOUT_GNU 174550 2007-12-12 16:43:17Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GNU 174550 2007-12-12 16:43:17Z ru
 Set to not build contributed GNU software as a part of the base system.
 This option can be useful if the system built must not contain any code
 covered by the GNU Public License due to legal reasons.
@@ -340,43 +340,43 @@ When set, it also enforces the following options:
 .Va WITHOUT_GNU_SUPPORT
 .El
 .It Va WITH_GNU_CPIO
-.\" from FreeBSD: head/tools/build/options/WITH_GNU_CPIO 179813 2008-06-16 05:48:15Z dougb
+.\" from FreeBSD: stable/8/tools/build/options/WITH_GNU_CPIO 179813 2008-06-16 05:48:15Z dougb
 Set to build GNU cpio as a part of the base system,
 and symlink
 .Pa /usr/bin/cpio
 to this version.
 (This will override the symlink to the BSD version.)
 .It Va WITHOUT_GNU_GREP
-.\" from FreeBSD: head/tools/build/options/WITHOUT_GNU_GREP 179813 2008-06-16 05:48:15Z dougb
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GNU_GREP 179813 2008-06-16 05:48:15Z dougb
 Set to not build GNU grep as a part of the base system.
 .It Va WITHOUT_GNU_SUPPORT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_GNU_SUPPORT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GNU_SUPPORT 156932 2006-03-21 07:50:50Z ru
 Set to build some programs without optional GNU support.
 .It Va WITHOUT_GPIB
-.\" from FreeBSD: head/tools/build/options/WITHOUT_GPIB 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GPIB 156932 2006-03-21 07:50:50Z ru
 Set to not build GPIB bus support.
 .It Va WITHOUT_GROFF
-.\" from FreeBSD: head/tools/build/options/WITHOUT_GROFF 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GROFF 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr groff 1 .
 .It Va WITHOUT_GSSAPI
-.\" from FreeBSD: head/tools/build/options/WITHOUT_GSSAPI 174548 2007-12-12 16:39:32Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GSSAPI 174548 2007-12-12 16:39:32Z ru
 Set to not build libgssapi.
 .It Va WITH_HESIOD
-.\" from FreeBSD: head/tools/build/options/WITH_HESIOD 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITH_HESIOD 156932 2006-03-21 07:50:50Z ru
 Set to build Hesiod support.
 .It Va WITHOUT_HTML
-.\" from FreeBSD: head/tools/build/options/WITHOUT_HTML 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_HTML 156932 2006-03-21 07:50:50Z ru
 Set to not build HTML docs.
 .It Va WITH_IDEA
-.\" from FreeBSD: head/tools/build/options/WITH_IDEA 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITH_IDEA 156932 2006-03-21 07:50:50Z ru
 Set to build the IDEA encryption code.
 This code is patented in the USA and many European countries.
 It is
 .Em "YOUR RESPONSIBILITY"
 to determine if you can legally use IDEA.
 .It Va WITHOUT_INET6
-.\" from FreeBSD: head/tools/build/options/WITHOUT_INET6 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_INET6 156932 2006-03-21 07:50:50Z ru
 Set to not build
 programs and libraries related to IPv6 networking.
 When set, it also enforces the following options:
@@ -386,27 +386,27 @@ When set, it also enforces the following options:
 .Va WITHOUT_INET6_SUPPORT
 .El
 .It Va WITHOUT_INET6_SUPPORT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_INET6_SUPPORT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_INET6_SUPPORT 156932 2006-03-21 07:50:50Z ru
 Set to build libraries, programs, and kernel modules without IPv6 support.
 .It Va WITHOUT_INFO
-.\" from FreeBSD: head/tools/build/options/WITHOUT_INFO 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_INFO 156932 2006-03-21 07:50:50Z ru
 Set to not make or install
 .Xr info 5
 files.
 .It Va WITHOUT_INSTALLLIB
-.\" from FreeBSD: head/tools/build/options/WITHOUT_INSTALLLIB 174497 2007-12-09 21:56:21Z dougb
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_INSTALLLIB 174497 2007-12-09 21:56:21Z dougb
 Set this if you do not want to install optional libraries.
 For example when creating a
 .Xr nanobsd 8
 image.
 .It Va WITHOUT_IPFILTER
-.\" from FreeBSD: head/tools/build/options/WITHOUT_IPFILTER 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_IPFILTER 156932 2006-03-21 07:50:50Z ru
 Set to not build IP Filter package.
 .It Va WITHOUT_IPFW
-.\" from FreeBSD: head/tools/build/options/WITHOUT_IPFW 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_IPFW 183242 2008-09-21 22:02:26Z sam
 Set to not build IPFW tools.
 .It Va WITHOUT_IPX
-.\" from FreeBSD: head/tools/build/options/WITHOUT_IPX 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_IPX 156932 2006-03-21 07:50:50Z ru
 Set to not build programs and libraries related to IPX networking.
 When set, it also enforces the following options:
 .Pp
@@ -417,14 +417,14 @@ When set, it also enforces the following options:
 .Va WITHOUT_NCP
 .El
 .It Va WITHOUT_IPX_SUPPORT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_IPX_SUPPORT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_IPX_SUPPORT 156932 2006-03-21 07:50:50Z ru
 Set to build some programs without IPX support.
 .It Va WITHOUT_JAIL
-.\" from FreeBSD: head/tools/build/options/WITHOUT_JAIL 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_JAIL 183242 2008-09-21 22:02:26Z sam
 Set to not build tools for the support of jails; e.g.
 .Xr jail 8 .
 .It Va WITHOUT_KERBEROS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_KERBEROS 174549 2007-12-12 16:42:03Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_KERBEROS 174549 2007-12-12 16:42:03Z ru
 Set this if you do not want to build Kerberos 5 (KTH Heimdal).
 When set, it also enforces the following options:
 .Pp
@@ -437,7 +437,7 @@ When set, it also enforces the following options:
 .Va WITHOUT_KERBEROS_SUPPORT
 .El
 .It Va WITHOUT_KERBEROS_SUPPORT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_KERBEROS_SUPPORT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_KERBEROS_SUPPORT 156932 2006-03-21 07:50:50Z ru
 Set to build some programs without Kerberos support, like
 .Xr cvs 1 ,
 .Xr ssh 1 ,
@@ -446,7 +446,7 @@ Set to build some programs without Kerberos support, like
 and
 .Xr telnetd 8 .
 .It Va WITHOUT_KVM
-.\" from FreeBSD: head/tools/build/options/WITHOUT_KVM 174550 2007-12-12 16:43:17Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_KVM 174550 2007-12-12 16:43:17Z ru
 Set to not build the
 .Nm libkvm
 library as a part of the base system.
@@ -460,23 +460,23 @@ When set, it also enforces the following options:
 .Va WITHOUT_KVM_SUPPORT
 .El
 .It Va WITHOUT_KVM_SUPPORT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_KVM_SUPPORT 170644 2007-06-13 02:08:04Z sepotvin
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_KVM_SUPPORT 170644 2007-06-13 02:08:04Z sepotvin
 Set to build some programs without optional
 .Nm libkvm
 support.
 .It Va WITHOUT_LEGACY_CONSOLE
-.\" from FreeBSD: head/tools/build/options/WITHOUT_LEGACY_CONSOLE 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_LEGACY_CONSOLE 183242 2008-09-21 22:02:26Z sam
 Set to not build programs that support a legacy PC console; e.g.
 .Xr kbdcontrol 8
 and
 .Xr vidcontrol 8 .
 .It Va WITHOUT_LIB32
-.\" from FreeBSD: head/tools/build/options/WITHOUT_LIB32 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_LIB32 156932 2006-03-21 07:50:50Z ru
 On amd64, set to not build 32-bit library set and a
 .Nm ld-elf32.so.1
 runtime linker.
 .It Va WITHOUT_LIBPTHREAD
-.\" from FreeBSD: head/tools/build/options/WITHOUT_LIBPTHREAD 188848 2009-02-20 11:09:55Z mtm
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_LIBPTHREAD 188848 2009-02-20 11:09:55Z mtm
 Set to not build the
 .Nm libpthread
 providing library,
@@ -502,7 +502,7 @@ When set, it also enforces the following options:
 .Va WITHOUT_LIBTHR
 .El
 .It Va WITHOUT_LIBTHR
-.\" from FreeBSD: head/tools/build/options/WITHOUT_LIBTHR 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_LIBTHR 156932 2006-03-21 07:50:50Z ru
 Set to not build the
 .Nm libthr
 (1:1 threading)
@@ -526,21 +526,21 @@ When set, it also enforces the following options:
 .Va WITHOUT_BIND_UTILS
 .El
 .It Va WITHOUT_LOCALES
-.\" from FreeBSD: head/tools/build/options/WITHOUT_LOCALES 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_LOCALES 156932 2006-03-21 07:50:50Z ru
 Set to not build localization files; see
 .Xr locale 1 .
 .It Va WITHOUT_LOCATE
-.\" from FreeBSD: head/tools/build/options/WITHOUT_LOCATE 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_LOCATE 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr locate 1
 and related programs.
 .It Va WITHOUT_LPR
-.\" from FreeBSD: head/tools/build/options/WITHOUT_LPR 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_LPR 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr lpr 1
 and related programs.
 .It Va WITHOUT_MAIL
-.\" from FreeBSD: head/tools/build/options/WITHOUT_MAIL 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_MAIL 183242 2008-09-21 22:02:26Z sam
 Set to not build any mail support (MUA or MTA).
 When set, it also enforces the following options:
 .Pp
@@ -551,46 +551,50 @@ When set, it also enforces the following options:
 .Va WITHOUT_SENDMAIL
 .El
 .It Va WITHOUT_MAILWRAPPER
-.\" from FreeBSD: head/tools/build/options/WITHOUT_MAILWRAPPER 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_MAILWRAPPER 156932 2006-03-21 07:50:50Z ru
 Set to not build the
 .Xr mailwrapper 8
 MTA selector.
 .It Va WITHOUT_MAKE
-.\" from FreeBSD: head/tools/build/options/WITHOUT_MAKE 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_MAKE 183242 2008-09-21 22:02:26Z sam
 Set to not install
 .Xr make 1
 and related support files.
 .It Va WITHOUT_MAN
-.\" from FreeBSD: head/tools/build/options/WITHOUT_MAN 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_MAN 156932 2006-03-21 07:50:50Z ru
 Set to not build manual pages.
 .It Va WITHOUT_NCP
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NCP 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NCP 156932 2006-03-21 07:50:50Z ru
 Set to not build programs, libraries, and kernel modules
 related to NetWare Core protocol.
 .It Va WITHOUT_NDIS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NDIS 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NDIS 183242 2008-09-21 22:02:26Z sam
 Set to not build programs and libraries
 related to NDIS emulation support.
 .It Va WITHOUT_NETCAT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NETCAT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NETCAT 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr nc 1
 utility.
 .It Va WITHOUT_NETGRAPH
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NETGRAPH 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NETGRAPH 183242 2008-09-21 22:02:26Z sam
 Set to not build applications to support
 .Xr netgraph 4 .
 When set, it also enforces the following options:
 .Pp
 .Bl -item -compact
 .It
+.Va WITHOUT_ATM
+.It
+.Va WITHOUT_BLUETOOTH
+.It
 .Va WITHOUT_NETGRAPH_SUPPORT
 .El
 .It Va WITHOUT_NETGRAPH_SUPPORT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NETGRAPH_SUPPORT 183305 2008-09-23 16:11:15Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NETGRAPH_SUPPORT 183305 2008-09-23 16:11:15Z sam
 Set to build libraries, programs, and kernel modules without netgraph support.
 .It Va WITHOUT_NIS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NIS 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NIS 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr NIS 8
 support and related programs.
@@ -600,14 +604,14 @@ and remove
 .Sq nis
 entries.
 .It Va WITHOUT_NLS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NLS 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NLS 156932 2006-03-21 07:50:50Z ru
 Set to not build NLS catalogs.
 .It Va WITHOUT_NLS_CATALOGS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NLS_CATALOGS 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NLS_CATALOGS 156932 2006-03-21 07:50:50Z ru
 Set to not build NLS catalog support for
 .Xr csh 1 .
 .It Va WITHOUT_NS_CACHING
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NS_CACHING 172803 2007-10-19 14:01:25Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NS_CACHING 172803 2007-10-19 14:01:25Z ru
 Set to disable name caching in the
 .Pa nsswitch
 subsystem.
@@ -615,18 +619,18 @@ The generic caching daemon,
 .Xr nscd 8 ,
 will not be built either if this option is set.
 .It Va WITHOUT_NTP
-.\" from FreeBSD: head/tools/build/options/WITHOUT_NTP 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_NTP 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr ntpd 8
 and related programs.
 .It Va WITHOUT_OBJC
-.\" from FreeBSD: head/tools/build/options/WITHOUT_OBJC 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_OBJC 156932 2006-03-21 07:50:50Z ru
 Set to not build Objective C support.
 .It Va WITHOUT_OPENSSH
-.\" from FreeBSD: head/tools/build/options/WITHOUT_OPENSSH 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_OPENSSH 156932 2006-03-21 07:50:50Z ru
 Set to not build OpenSSH.
 .It Va WITHOUT_OPENSSL
-.\" from FreeBSD: head/tools/build/options/WITHOUT_OPENSSL 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_OPENSSL 156932 2006-03-21 07:50:50Z ru
 Set to not build OpenSSL.
 When set, it also enforces the following options:
 .Pp
@@ -643,7 +647,7 @@ When set, it also enforces the following options:
 .Va WITHOUT_OPENSSH
 .El
 .It Va WITHOUT_PAM
-.\" from FreeBSD: head/tools/build/options/WITHOUT_PAM 174550 2007-12-12 16:43:17Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_PAM 174550 2007-12-12 16:43:17Z ru
 Set to not build PAM library and modules.
 .Bf -symbolic
 This option is deprecated and does nothing.
@@ -655,13 +659,13 @@ When set, it also enforces the following options:
 .Va WITHOUT_PAM_SUPPORT
 .El
 .It Va WITHOUT_PAM_SUPPORT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_PAM_SUPPORT 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_PAM_SUPPORT 156932 2006-03-21 07:50:50Z ru
 Set to build some programs without PAM support, particularly
 .Xr ftpd 8
 and
 .Xr ppp 8 .
 .It Va WITHOUT_PF
-.\" from FreeBSD: head/tools/build/options/WITHOUT_PF 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_PF 156932 2006-03-21 07:50:50Z ru
 Set to not build PF firewall package.
 When set, it also enforces the following options:
 .Pp
@@ -670,35 +674,35 @@ When set, it also enforces the following options:
 .Va WITHOUT_AUTHPF
 .El
 .It Va WITHOUT_PKGTOOLS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_PKGTOOLS 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_PKGTOOLS 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr pkg_add 8
 and related programs.
 .It Va WITHOUT_PMC
-.\" from FreeBSD: head/tools/build/options/WITHOUT_PMC 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_PMC 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr pmccontrol 8
 and related programs.
 .It Va WITHOUT_PORTSNAP
-.\" from FreeBSD: head/tools/build/options/WITHOUT_PORTSNAP 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_PORTSNAP 183242 2008-09-21 22:02:26Z sam
 Set to not build or install
 .Xr portsnap 8
 and related files.
 .It Va WITHOUT_PPP
-.\" from FreeBSD: head/tools/build/options/WITHOUT_PPP 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_PPP 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr ppp 8
 and related programs.
 .It Va WITHOUT_PROFILE
-.\" from FreeBSD: head/tools/build/options/WITHOUT_PROFILE 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_PROFILE 156932 2006-03-21 07:50:50Z ru
 Set to avoid compiling profiled libraries.
 .It Va WITHOUT_QUOTAS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_QUOTAS 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_QUOTAS 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr quota 8
 and related programs.
 .It Va WITHOUT_RCMDS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_RCMDS 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_RCMDS 156932 2006-03-21 07:50:50Z ru
 Disable building of the
 .Bx
 r-commands.
@@ -707,63 +711,63 @@ This includes
 .Xr rsh 1 ,
 etc.
 .It Va WITHOUT_RCS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_RCS 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_RCS 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr rcs 1
 and related utilities.
 .It Va WITHOUT_RESCUE
-.\" from FreeBSD: head/tools/build/options/WITHOUT_RESCUE 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_RESCUE 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr rescue 8 .
 .It Va WITHOUT_ROUTED
-.\" from FreeBSD: head/tools/build/options/WITHOUT_ROUTED 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_ROUTED 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr routed 8
 utility.
 .It Va WITHOUT_SENDMAIL
-.\" from FreeBSD: head/tools/build/options/WITHOUT_SENDMAIL 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_SENDMAIL 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr sendmail 8
 and related programs.
 .It Va WITHOUT_SETUID_LOGIN
-.\" from FreeBSD: head/tools/build/options/WITHOUT_SETUID_LOGIN 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_SETUID_LOGIN 156932 2006-03-21 07:50:50Z ru
 Set this to disable the installation of
 .Xr login 1
 as a set-user-ID root program.
 .It Va WITHOUT_SHAREDOCS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_SHAREDOCS 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_SHAREDOCS 156932 2006-03-21 07:50:50Z ru
 Set to not build the
 .Bx 4.4
 legacy docs.
 .It Va WITHOUT_SSP
-.\" from FreeBSD: head/tools/build/options/WITHOUT_SSP 180012 2008-06-25 21:33:28Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_SSP 180012 2008-06-25 21:33:28Z ru
 Set to not build world with propolice stack smashing protection.
 .It Va WITHOUT_SYMVER
-.\" from FreeBSD: head/tools/build/options/WITHOUT_SYMVER 169649 2007-05-17 05:03:24Z deischen
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_SYMVER 169649 2007-05-17 05:03:24Z deischen
 Set to disable symbol versioning when building shared libraries.
 .It Va WITHOUT_SYSCONS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_SYSCONS 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_SYSCONS 156932 2006-03-21 07:50:50Z ru
 Set to not build
 .Xr syscons 4
 support files such as keyboard maps, fonts, and screen output maps.
 .It Va WITHOUT_SYSINSTALL
-.\" from FreeBSD: head/tools/build/options/WITHOUT_SYSINSTALL 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_SYSINSTALL 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr sysinstall 8
 and related programs.
 .It Va WITHOUT_TCSH
-.\" from FreeBSD: head/tools/build/options/WITHOUT_TCSH 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_TCSH 156932 2006-03-21 07:50:50Z ru
 Set to not build and install
 .Pa /bin/csh
 (which is
 .Xr tcsh 1 ) .
 .It Va WITHOUT_TELNET
-.\" from FreeBSD: head/tools/build/options/WITHOUT_TELNET 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_TELNET 183242 2008-09-21 22:02:26Z sam
 Set to not build
 .Xr telnet 8
 and related programs.
 .It Va WITHOUT_TEXTPROC
-.\" from FreeBSD: head/tools/build/options/WITHOUT_TEXTPROC 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_TEXTPROC 183242 2008-09-21 22:02:26Z sam
 Set to not build
 programs used for text processing.
 When set, it also enforces the following options:
@@ -773,7 +777,7 @@ When set, it also enforces the following options:
 .Va WITHOUT_GROFF
 .El
 .It Va WITHOUT_TOOLCHAIN
-.\" from FreeBSD: head/tools/build/options/WITHOUT_TOOLCHAIN 174550 2007-12-12 16:43:17Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_TOOLCHAIN 174550 2007-12-12 16:43:17Z ru
 Set to not install
 programs used for program development,
 compilers, debuggers etc.
@@ -787,10 +791,10 @@ When set, it also enforces the following options:
 .Va WITHOUT_GDB
 .El
 .It Va WITHOUT_USB
-.\" from FreeBSD: head/tools/build/options/WITHOUT_USB 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_USB 156932 2006-03-21 07:50:50Z ru
 Set to not build USB-related programs and libraries.
 .It Va WITHOUT_WIRELESS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_WIRELESS 183242 2008-09-21 22:02:26Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_WIRELESS 183242 2008-09-21 22:02:26Z sam
 Set to not build programs used for 802.11 wireless networks; especially
 .Xr wpa_supplicant 8
 and
@@ -802,21 +806,21 @@ When set, it also enforces the following options:
 .Va WITHOUT_WIRELESS_SUPPORT
 .El
 .It Va WITHOUT_WIRELESS_SUPPORT
-.\" from FreeBSD: head/tools/build/options/WITHOUT_WIRELESS_SUPPORT 183305 2008-09-23 16:11:15Z sam
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_WIRELESS_SUPPORT 183305 2008-09-23 16:11:15Z sam
 Set to build libraries, programs, and kernel modules without
 802.11 wireless support.
 .It Va WITHOUT_WPA_SUPPLICANT_EAPOL
-.\" from FreeBSD: head/tools/build/options/WITHOUT_WPA_SUPPLICANT_EAPOL 156932 2006-03-21 07:50:50Z ru
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_WPA_SUPPLICANT_EAPOL 156932 2006-03-21 07:50:50Z ru
 Build
 .Xr wpa_supplicant 8
 without support for the IEEE 802.1X protocol and without
 support for EAP-PEAP, EAP-TLS, EAP-LEAP, and EAP-TTLS
 protocols (usable only via 802.1X).
 .It Va WITHOUT_ZFS
-.\" from FreeBSD: head/tools/build/options/WITHOUT_ZFS 168409 2007-04-06 02:13:30Z pjd
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_ZFS 168409 2007-04-06 02:13:30Z pjd
 Set to not build ZFS file system.
 .It Va WITHOUT_ZONEINFO
-.\" from FreeBSD: head/tools/build/options/WITHOUT_ZONEINFO 171994 2007-08-27 20:01:08Z remko
+.\" from FreeBSD: stable/8/tools/build/options/WITHOUT_ZONEINFO 171994 2007-08-27 20:01:08Z remko
 Set to not build the timezone database
 .El
 .Sh FILES

From e8fdbf3d5c60e41d79057e57a6bdecf8b7872fbf Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 15:50:01 +0000
Subject: [PATCH 1329/2592] MFC r201016:

Improve ACL branding mismatch detection and reporting in some rare cases,
such as "setfacl -m ''".
---
 bin/setfacl/merge.c   | 10 +++++-----
 bin/setfacl/remove.c  |  5 ++---
 bin/setfacl/setfacl.h |  2 ++
 bin/setfacl/util.c    | 23 +++++++++++++++++++++++
 4 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/bin/setfacl/merge.c b/bin/setfacl/merge.c
index 495e66c45a2..0a42eecb74c 100644
--- a/bin/setfacl/merge.c
+++ b/bin/setfacl/merge.c
@@ -100,11 +100,10 @@ merge_acl(acl_t acl, acl_t *prev_acl, const char *filename)
 	acl_get_brand_np(acl, &acl_brand);
 	acl_get_brand_np(*prev_acl, &prev_acl_brand);
 
-	if (acl_brand != prev_acl_brand) {
+	if (branding_mismatch(acl_brand, prev_acl_brand)) {
 		warnx("%s: branding mismatch; existing ACL is %s, "
 		    "entry to be merged is %s", filename,
-		    prev_acl_brand == ACL_BRAND_NFS4 ? "NFSv4" : "POSIX.1e",
-		    acl_brand == ACL_BRAND_NFS4 ? "NFSv4" : "POSIX.1e");
+		    brand_name(prev_acl_brand), brand_name(acl_brand));
 		return (-1);
 	}
 
@@ -252,9 +251,10 @@ add_acl(acl_t acl, uint entry_number, acl_t *prev_acl, const char *filename)
 		return (-1);
 	}
 
-	if (acl_brand != ACL_BRAND_NFS4) {
+	if (branding_mismatch(acl_brand, ACL_BRAND_NFS4)) {
 		warnx("%s: branding mismatch; existing ACL is NFSv4, "
-		    "entry to be added is POSIX.1e", filename);
+		    "entry to be added is %s", filename,
+		    brand_name(acl_brand));
 		return (-1);
 	}
 
diff --git a/bin/setfacl/remove.c b/bin/setfacl/remove.c
index 6cd82b36d9e..e6feef9bead 100644
--- a/bin/setfacl/remove.c
+++ b/bin/setfacl/remove.c
@@ -53,11 +53,10 @@ remove_acl(acl_t acl, acl_t *prev_acl, const char *filename)
 	acl_get_brand_np(acl, &acl_brand);
 	acl_get_brand_np(*prev_acl, &prev_acl_brand);
 
-	if (acl_brand != prev_acl_brand) {
+	if (branding_mismatch(acl_brand, prev_acl_brand)) {
 		warnx("%s: branding mismatch; existing ACL is %s, "
 		    "entry to be removed is %s", filename,
-		    prev_acl_brand == ACL_BRAND_NFS4 ? "NFSv4" : "POSIX.1e",
-		    acl_brand == ACL_BRAND_NFS4 ? "NFSv4" : "POSIX.1e");
+		    brand_name(prev_acl_brand), brand_name(acl_brand));
 		return (-1);
 	}
 
diff --git a/bin/setfacl/setfacl.h b/bin/setfacl/setfacl.h
index 7c11b3a14f7..290ac5b4d1d 100644
--- a/bin/setfacl/setfacl.h
+++ b/bin/setfacl/setfacl.h
@@ -71,6 +71,8 @@ void   remove_ext(acl_t *prev_acl, const char *filename);
 int    set_acl_mask(acl_t *prev_acl, const char *filename);
 /* util.c */
 void  *zmalloc(size_t size);
+const char *brand_name(int brand);
+int    branding_mismatch(int brand1, int brand2);
 
 uint       have_mask;
 uint       need_mask;
diff --git a/bin/setfacl/util.c b/bin/setfacl/util.c
index 46b9abb6ff6..3c429797b14 100644
--- a/bin/setfacl/util.c
+++ b/bin/setfacl/util.c
@@ -43,3 +43,26 @@ zmalloc(size_t size)
 		err(1, "calloc() failed");
 	return (ptr);
 }
+
+const char *
+brand_name(int brand)
+{
+	switch (brand) {
+	case ACL_BRAND_NFS4:
+		return "NFSv4";
+	case ACL_BRAND_POSIX:
+		return "POSIX.1e";
+	default:
+		return "unknown";
+	}
+}
+
+int
+branding_mismatch(int brand1, int brand2)
+{
+	if (brand1 == ACL_BRAND_UNKNOWN || brand2 == ACL_BRAND_UNKNOWN)
+		return (0);
+	if (brand1 != brand2)
+		return (1);
+	return (1);
+}

From f4d24e0ea3c722999424c9f4c112786a116fcb16 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sat, 30 Jan 2010 15:53:32 +0000
Subject: [PATCH 1330/2592] MFC r201018:

Fix breakage introduced in last commit.
---
 bin/setfacl/util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bin/setfacl/util.c b/bin/setfacl/util.c
index 3c429797b14..a7fb6a61bc5 100644
--- a/bin/setfacl/util.c
+++ b/bin/setfacl/util.c
@@ -64,5 +64,5 @@ branding_mismatch(int brand1, int brand2)
 		return (0);
 	if (brand1 != brand2)
 		return (1);
-	return (1);
+	return (0);
 }

From 7782c5efe849ef65c6c79d1418e5cdc0482275b8 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sun, 31 Jan 2010 02:11:14 +0000
Subject: [PATCH 1331/2592] MFC r196949:

Enable NFSv4 ACL support in ZFS.

MFC r197435:

In VOP_SETACL(9) and VOP_GETACL(9), specifying wrong ACL type should result
in EINVAL, not EOPNOTSUPP.
---
 .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 41 +++++++++++++++----
 1 file changed, 33 insertions(+), 8 deletions(-)

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 a8649704213..4f61f5f3f5e 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
@@ -3851,7 +3851,15 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
 #endif
 
 	case _PC_ACL_EXTENDED:
-		*valp = 0;	/* TODO */
+		*valp = 0;
+		return (0);
+
+	case _PC_ACL_NFS4:
+		*valp = 1;
+		return (0);
+
+	case _PC_ACL_PATH_MAX:
+		*valp = ACL_MAX_ENTRIES;
 		return (0);
 
 	case _PC_MIN_HOLE_SIZE:
@@ -4471,6 +4479,26 @@ zfs_freebsd_pathconf(ap)
 	return (error);
 }
 
+static int
+zfs_freebsd_fifo_pathconf(ap)
+	struct vop_pathconf_args /* {
+		struct vnode *a_vp;
+		int a_name;
+		register_t *a_retval;
+	} */ *ap;
+{
+
+	switch (ap->a_name) {
+	case _PC_ACL_EXTENDED:
+	case _PC_ACL_NFS4:
+	case _PC_ACL_PATH_MAX:
+	case _PC_MAC_PRESENT:
+		return (zfs_freebsd_pathconf(ap));
+	default:
+		return (fifo_specops.vop_pathconf(ap));
+	}
+}
+
 /*
  * FreeBSD's extended attributes namespace defines file name prefix for ZFS'
  * extended attribute name:
@@ -4865,7 +4893,7 @@ zfs_freebsd_getacl(ap)
 	vsecattr_t      vsecattr;
 
 	if (ap->a_type != ACL_TYPE_NFS4)
-		return (EOPNOTSUPP);
+		return (EINVAL);
 
 	vsecattr.vsa_mask = VSA_ACE | VSA_ACECNT;
 	if (error = zfs_getsecattr(ap->a_vp, &vsecattr, 0, ap->a_cred, NULL))
@@ -4894,13 +4922,13 @@ zfs_freebsd_setacl(ap)
 	aclent_t	*aaclp;
 
 	if (ap->a_type != ACL_TYPE_NFS4)
-		return (EOPNOTSUPP);
+		return (EINVAL);
 
 	if (ap->a_aclp->acl_cnt < 1 || ap->a_aclp->acl_cnt > MAX_ACL_ENTRIES)
 		return (EINVAL);
 
 	/*
-	 * With NFS4 ACLs, chmod(2) may need to add additional entries,
+	 * With NFSv4 ACLs, chmod(2) may need to add additional entries,
 	 * splitting every entry into two and appending "canonical six"
 	 * entries at the end.  Don't allow for setting an ACL that would
 	 * cause chmod(2) to run out of ACL entries.
@@ -4974,11 +5002,9 @@ struct vop_vector zfs_vnodeops = {
 	.vop_deleteextattr =	zfs_deleteextattr,
 	.vop_setextattr =	zfs_setextattr,
 	.vop_listextattr =	zfs_listextattr,
-#ifdef notyet
 	.vop_getacl =		zfs_freebsd_getacl,
 	.vop_setacl =		zfs_freebsd_setacl,
 	.vop_aclcheck =		zfs_freebsd_aclcheck,
-#endif
 };
 
 struct vop_vector zfs_fifoops = {
@@ -4991,10 +5017,9 @@ struct vop_vector zfs_fifoops = {
 	.vop_reclaim =		zfs_freebsd_reclaim,
 	.vop_setattr =		zfs_freebsd_setattr,
 	.vop_write =		VOP_PANIC,
+	.vop_pathconf = 	zfs_freebsd_fifo_pathconf,
 	.vop_fid =		zfs_freebsd_fid,
-#ifdef notyet
 	.vop_getacl =		zfs_freebsd_getacl,
 	.vop_setacl =		zfs_freebsd_setacl,
 	.vop_aclcheck =		zfs_freebsd_aclcheck,
-#endif
 };

From 30718ea4ebac82f5da484ab3f1890ed69ac916cc Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sun, 31 Jan 2010 02:17:01 +0000
Subject: [PATCH 1332/2592] MFC r196710:

Add regression test for ACLs on device files - mostly to make
sure we don't crash on attempt to set ACL on them.
---
 tools/regression/acltools/tools-posix.test | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/tools/regression/acltools/tools-posix.test b/tools/regression/acltools/tools-posix.test
index 9ce94cdb5fd..bfb7ae003ad 100644
--- a/tools/regression/acltools/tools-posix.test
+++ b/tools/regression/acltools/tools-posix.test
@@ -387,3 +387,19 @@ $ ls -l fff | cut -d' ' -f1
 
 $ rm fff
 
+# Test if we deal properly with device files.
+$ mknod bbb b 1 1
+$ setfacl -m u:42:r,g:43:w bbb
+> setfacl: acl_get_file() failed: Operation not supported
+$ ls -l bbb | cut -d' ' -f1
+> brw-r--r--
+
+$ rm bbb
+
+$ mknod ccc c 1 1
+$ setfacl -m u:42:r,g:43:w ccc
+> setfacl: acl_get_file() failed: Operation not supported
+$ ls -l ccc | cut -d' ' -f1
+> crw-r--r--
+
+$ rm ccc

From 83b5041c81b6970ebc7b67e33ea97b82fa423618 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sun, 31 Jan 2010 02:18:28 +0000
Subject: [PATCH 1333/2592] MFC r196736:

Adapt to the fact that ls(1) correctly prints '+' for symlinks with ACLs now.
---
 tools/regression/acltools/tools-posix.test | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/regression/acltools/tools-posix.test b/tools/regression/acltools/tools-posix.test
index bfb7ae003ad..6ae31f36edd 100644
--- a/tools/regression/acltools/tools-posix.test
+++ b/tools/regression/acltools/tools-posix.test
@@ -77,9 +77,8 @@ $ getfacl -h lll
 > mask::rwx
 > other::r-x
 
-# XXX: Why doesn't ls(1) print '+' for symbolic links with ACL set?
 $ ls -l lll | cut -d' ' -f1
-> lrwxrwxr-x
+> lrwxrwxr-x+
 
 # Check whether the original file is left untouched.
 $ ls -l xxx | cut -d' ' -f1

From d17e98a73298828bf8f8b4aeba093c953b52fc95 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sun, 31 Jan 2010 02:20:01 +0000
Subject: [PATCH 1334/2592] MFC r196938:

Add regression tests for NFSv4 ACLs and update POSIX.1e tests to the changed
error messages.
---
 tools/regression/acltools/00.t             |  31 +-
 tools/regression/acltools/01.t             |  86 +++
 tools/regression/acltools/tools-nfs4.test  | 829 +++++++++++++++++++++
 tools/regression/acltools/tools-posix.test |  93 ++-
 4 files changed, 1013 insertions(+), 26 deletions(-)
 create mode 100644 tools/regression/acltools/01.t
 create mode 100644 tools/regression/acltools/tools-nfs4.test

diff --git a/tools/regression/acltools/00.t b/tools/regression/acltools/00.t
index d2809f42f10..c76b39efb4f 100644
--- a/tools/regression/acltools/00.t
+++ b/tools/regression/acltools/00.t
@@ -1,5 +1,32 @@
 #!/bin/sh
 #
+# Copyright (c) 2008, 2009 Edward Tomasz Napierała 
+# 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$
+#
+
 # This is a wrapper script to run tools-posix.test.
 #
 # If any of the tests fails, here is how to debug it: go to
@@ -9,9 +36,6 @@
 # /usr/src/tools/regression/acltools/run /usr/src/tools/regression/acltools/tools-posix.test
 #
 # Output should be obvious.
-#
-# $FreeBSD$
-#
 
 echo "1..4"
 
@@ -59,4 +83,3 @@ rmdir $MNT
 mdconfig -du $MD
 
 echo "ok 4"
-
diff --git a/tools/regression/acltools/01.t b/tools/regression/acltools/01.t
new file mode 100644
index 00000000000..1f9968252ed
--- /dev/null
+++ b/tools/regression/acltools/01.t
@@ -0,0 +1,86 @@
+#!/bin/sh
+#
+# Copyright (c) 2008, 2009 Edward Tomasz Napierała 
+# 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$
+#
+
+# This is a wrapper script to run tools-nfs4.test on ZFS filesystem.
+#
+# WARNING: It uses hardcoded ZFS pool name "acltools"
+#
+# If any of the tests fails, here is how to debug it: go to
+# the directory with problematic filesystem mounted on it,
+# and do /path/to/test run /path/to/test tools-nfs4.test, e.g.
+#
+# /usr/src/tools/regression/acltools/run /usr/src/tools/regression/acltools/tools-nfs4.test
+#
+# Output should be obvious.
+
+echo "1..4"
+
+if [ `whoami` != "root" ]; then
+	echo "not ok 1 - you need to be root to run this test."
+	exit 1
+fi
+
+TESTDIR=`dirname $0`
+
+# Set up the test filesystem.
+MD=`mdconfig -at swap -s 64m`
+MNT=`mktemp -dt acltools`
+zpool create -R $MNT acltools /dev/$MD
+if [ $? -ne 0 ]; then
+	echo "not ok 1 - 'zpool create' failed."
+	exit 1
+fi
+
+echo "ok 1"
+
+cd $MNT
+
+# First, check whether we can crash the kernel by creating too many
+# entries.  For some reason this won't work in the test file.
+touch xxx
+setfacl -x5 xxx
+while :; do setfacl -a0 u:42:rwx:allow xxx 2> /dev/null; if [ $? -ne 0 ]; then break; fi; done
+chmod 600 xxx
+rm xxx
+echo "ok 2"
+
+perl $TESTDIR/run $TESTDIR/tools-nfs4.test > /dev/null
+
+if [ $? -eq 0 ]; then
+	echo "ok 3"
+else
+	echo "not ok 3"
+fi
+
+cd /
+zpool destroy -f acltools
+rmdir $MNT
+mdconfig -du $MD
+
+echo "ok 4"
diff --git a/tools/regression/acltools/tools-nfs4.test b/tools/regression/acltools/tools-nfs4.test
new file mode 100644
index 00000000000..3e41add3ce5
--- /dev/null
+++ b/tools/regression/acltools/tools-nfs4.test
@@ -0,0 +1,829 @@
+# Copyright (c) 2008, 2009 Edward Tomasz Napierała 
+# 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$
+#
+
+# This is a tools-level test for NFSv4 ACL functionality.  Run it as root
+# using ACL-enabled kernel:
+#
+# /usr/src/tools/regression/acltools/run /usr/src/tools/regression/acltools/tools-nfs4.test
+#
+# WARNING: Creates files in unsafe way.
+
+$ whoami
+> root
+$ umask 022
+
+# Smoke test for getfacl(1).
+$ touch xxx
+$ getfacl xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+$ getfacl -q xxx
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+# Check verbose mode formatting.
+$ getfacl -v xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>             owner@:execute::deny
+>             owner@:read_data/write_data/append_data/write_attributes/write_xattr/write_acl/write_owner::allow
+>             group@:write_data/execute/append_data::deny
+>             group@:read_data::allow
+>          everyone@:write_data/execute/append_data/write_attributes/write_xattr/write_acl/write_owner::deny
+>          everyone@:read_data/read_attributes/read_xattr/read_acl/synchronize::allow
+
+# Test setfacl -a.
+$ setfacl -a2 u:0:write_acl:allow,g:1:read_acl:deny xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             user:0:-----------C--:------:allow
+>            group:1:----------c---:------:deny
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+# Test user and group name resolving.
+$ rm xxx
+$ touch xxx
+$ setfacl -a2 u:root:write_acl:allow,g:daemon:read_acl:deny xxx
+$ getfacl xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>          user:root:-----------C--:------:allow
+>       group:daemon:----------c---:------:deny
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+# Check whether ls correctly marks files with "+".
+$ ls -l xxx | cut -d' ' -f1
+> -rw-r--r--+
+
+# Test removing entries by number.
+$ setfacl -x 4 xxx
+$ setfacl -x 4 xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             user:0:-----------C--:------:allow
+>            group:1:----------c---:------:deny
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+# Test setfacl -m.
+$ setfacl -a0 everyone@:rwx:deny xxx
+$ setfacl -a0 everyone@:rwx:deny xxx
+$ setfacl -a0 everyone@:rwx:deny xxx
+$ setfacl -m everyone@::deny xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>          everyone@:--------------:------:deny
+>          everyone@:--------------:------:deny
+>          everyone@:--------------:------:deny
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             user:0:-----------C--:------:allow
+>            group:1:----------c---:------:deny
+>          everyone@:--------------:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+# Test getfacl -i.
+$ getfacl -i xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>          everyone@:--------------:------:deny
+>          everyone@:--------------:------:deny
+>          everyone@:--------------:------:deny
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>          user:root:-----------C--:------:allow:0
+>       group:daemon:----------c---:------:deny:1
+>          everyone@:--------------:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+# Make sure cp without any flags does not copy copy the ACL.
+$ cp xxx yyy
+$ ls -l yyy | cut -d' ' -f1
+> -rw-r--r--
+
+# Make sure it does with the "-p" flag.
+$ rm yyy
+$ cp -p xxx yyy
+$ getfacl -n yyy
+> # file: yyy
+> # owner: root
+> # group: wheel
+>          everyone@:--------------:------:deny
+>          everyone@:--------------:------:deny
+>          everyone@:--------------:------:deny
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             user:0:-----------C--:------:allow
+>            group:1:----------c---:------:deny
+>          everyone@:--------------:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+$ rm yyy
+
+# Test removing entries by...  by example?
+$ setfacl -x everyone@::deny xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             user:0:-----------C--:------:allow
+>            group:1:----------c---:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+# Test setfacl -b.
+$ setfacl -b xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+$ ls -l xxx | cut -d' ' -f1
+> -rw-r--r--
+
+# Check setfacl(1) and getfacl(1) with multiple files.
+$ touch xxx yyy zzz
+
+$ ls -l xxx yyy zzz | cut -d' ' -f1
+> -rw-r--r--
+> -rw-r--r--
+> -rw-r--r--
+
+$ setfacl -m u:42:x:allow,g:43:w:allow nnn xxx yyy zzz
+> setfacl: nnn: stat() failed: No such file or directory
+
+$ ls -l nnn xxx yyy zzz | cut -d' ' -f1
+> ls: nnn: No such file or directory
+> -rw-r--r--+
+> -rw-r--r--+
+> -rw-r--r--+
+
+$ getfacl -nq nnn xxx yyy zzz
+> getfacl: nnn: stat() failed: No such file or directory
+>            user:42:--x-----------:------:allow
+>           group:43:-w------------:------:allow
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+>
+>            user:42:--x-----------:------:allow
+>           group:43:-w------------:------:allow
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+>
+>            user:42:--x-----------:------:allow
+>           group:43:-w------------:------:allow
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+$ setfacl -b nnn xxx yyy zzz
+> setfacl: nnn: stat() failed: No such file or directory
+
+$ ls -l nnn xxx yyy zzz | cut -d' ' -f1
+> ls: nnn: No such file or directory
+> -rw-r--r--
+> -rw-r--r--
+> -rw-r--r--
+
+$ rm xxx yyy zzz
+
+# Test applying mode to an ACL.
+$ touch xxx
+$ setfacl -a0 user:42:r:allow,user:43:w:deny,user:43:w:allow,user:44:x:allow -x everyone@::allow xxx
+$ chmod 600 xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+>            user:42:r-------------:------:deny
+>            user:42:r-------------:------:allow
+>            user:43:-w------------:------:deny
+>            user:43:-w------------:------:allow
+>            user:44:--x-----------:------:deny
+>            user:44:--x-----------:------:allow
+>             owner@:--------------:------:deny
+>             owner@:-------A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:-------A-W-Co-:------:deny
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:rwxp----------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:rwxp---A-W-Co-:------:deny
+>          everyone@:------a-R-c--s:------:allow
+$ ls -l xxx | cut -d' ' -f1
+> -rw-------+
+
+$ rm xxx
+$ touch xxx
+$ chown 42 xxx
+$ setfacl -a0 user:42:r:allow,user:43:w:deny,user:43:w:allow,user:44:x:allow xxx
+$ chmod 600 xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: 42
+> # group: wheel
+>            user:42:--------------:------:deny
+>            user:42:r-------------:------:allow
+>            user:43:-w------------:------:deny
+>            user:43:-w------------:------:allow
+>            user:44:--x-----------:------:deny
+>            user:44:--x-----------:------:allow
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:rwxp----------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:rwxp---A-W-Co-:------:deny
+>          everyone@:------a-R-c--s:------:allow
+$ ls -l xxx | cut -d' ' -f1
+> -rw-------+
+
+$ rm xxx
+$ touch xxx
+$ chown 43 xxx
+$ setfacl -a0 user:42:r:allow,user:43:w:deny,user:43:w:allow,user:44:x:allow xxx
+$ chmod 124 xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: 43
+> # group: wheel
+>            user:42:r-------------:------:deny
+>            user:42:r-------------:------:allow
+>            user:43:-w------------:------:deny
+>            user:43:-w------------:------:allow
+>            user:44:--x-----------:------:deny
+>            user:44:--x-----------:------:allow
+>             owner@:rw-p----------:------:deny
+>             owner@:--x----A-W-Co-:------:allow
+>             group@:r-x-----------:------:deny
+>             group@:-w-p----------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+$ ls -l xxx | cut -d' ' -f1
+> ---x-w-r--+
+
+$ rm xxx
+$ touch xxx
+$ chown 43 xxx
+$ setfacl -a0 user:42:r:allow,user:43:w:deny,user:43:w:allow,user:44:x:allow xxx
+$ chmod 412 xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: 43
+> # group: wheel
+>            user:42:r-------------:------:deny
+>            user:42:r-------------:------:allow
+>            user:43:-w------------:------:deny
+>            user:43:-w------------:------:allow
+>            user:44:--------------:------:deny
+>            user:44:--x-----------:------:allow
+>             owner@:-wxp----------:------:deny
+>             owner@:r------A-W-Co-:------:allow
+>             group@:rw-p----------:------:deny
+>             group@:--x-----------:------:allow
+>          everyone@:r-x----A-W-Co-:------:deny
+>          everyone@:-w-p--a-R-c--s:------:allow
+$ ls -l xxx | cut -d' ' -f1
+> -r----x-w-+
+
+$ mkdir ddd
+$ setfacl -a0 group:44:rwapd:allow ddd
+$ setfacl -a0 group:43:write_data/delete_child:d:deny,group@:ad:allow ddd
+$ setfacl -a0 user:42:rx:fi:allow,group:42:write_data/delete_child:d:allow ddd
+$ setfacl -m everyone@:-w-p--a-R-c--s:fi:allow ddd
+$ getfacl -n ddd
+> # file: ddd
+> # owner: root
+> # group: wheel
+>            user:42:r-x-----------:f-i---:allow
+>           group:42:-w--D---------:-d----:allow
+>           group:43:-w--D---------:-d----:deny
+>             group@:-----da-------:------:allow
+>           group:44:rw-p-da-------:------:allow
+>             owner@:--------------:------:deny
+>             owner@:rwxp---A-W-Co-:------:allow
+>             group@:-w-p----------:------:deny
+>             group@:r-x-----------:------:allow
+>          everyone@:-w-p---A-W-Co-:------:deny
+>          everyone@:-w-p--a-R-c--s:f-i---:allow
+$ chmod 777 ddd
+$ getfacl -n ddd
+> # file: ddd
+> # owner: root
+> # group: wheel
+>            user:42:r-x-----------:f-i---:allow
+>           group:42:-w--D---------:-di---:allow
+>           group:42:--------------:------:deny
+>           group:42:-w--D---------:------:allow
+>           group:43:-w--D---------:-di---:deny
+>           group:43:-w--D---------:------:deny
+>             group@:-----da-------:------:allow
+>           group:44:--------------:------:deny
+>           group:44:rw-p-da-------:------:allow
+>             owner@:--------------:------:deny
+>             owner@:-------A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:-------A-W-Co-:------:deny
+>          everyone@:-w-p--a-R-c--s:f-i---:allow
+>             owner@:--------------:------:deny
+>             owner@:rwxp---A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:rwxp----------:------:allow
+>          everyone@:-------A-W-Co-:------:deny
+>          everyone@:rwxp--a-R-c--s:------:allow
+
+$ rmdir ddd
+$ mkdir ddd
+$ setfacl -a0 group:44:rwapd:allow ddd
+$ setfacl -a0 group:43:write_data/delete_child:d:deny,group@:ad:allow ddd
+$ setfacl -a0 user:42:rx:fi:allow,group:42:write_data/delete_child:d:allow ddd
+$ setfacl -m everyone@:-w-p--a-R-c--s:fi:allow ddd
+$ chmod 124 ddd
+$ getfacl -n ddd
+> # file: ddd
+> # owner: root
+> # group: wheel
+>            user:42:r-x-----------:f-i---:allow
+>           group:42:-w--D---------:-di---:allow
+>           group:42:--------------:------:deny
+>           group:42:----D---------:------:allow
+>           group:43:-w--D---------:-di---:deny
+>           group:43:-w--D---------:------:deny
+>             group@:-----da-------:------:allow
+>           group:44:r-------------:------:deny
+>           group:44:r----da-------:------:allow
+>             owner@:--------------:------:deny
+>             owner@:-------A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:-------A-W-Co-:------:deny
+>          everyone@:-w-p--a-R-c--s:f-i---:allow
+>             owner@:rw-p----------:------:deny
+>             owner@:--x----A-W-Co-:------:allow
+>             group@:r-x-----------:------:deny
+>             group@:-w-p----------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+$ rmdir ddd
+$ mkdir ddd
+$ setfacl -a0 group:44:rwapd:allow ddd
+$ setfacl -a0 group:43:write_data/delete_child:d:deny,group@:ad:allow ddd
+$ setfacl -a0 user:42:rx:allow,user:42:rx:fi:allow,group:42:write_data/delete_child:d:allow ddd
+$ setfacl -m everyone@:-w-p--a-R-c--s:fi:allow ddd
+$ chmod 412 ddd
+$ getfacl -n ddd
+> # file: ddd
+> # owner: root
+> # group: wheel
+>            user:42:r-------------:------:deny
+>            user:42:r-x-----------:------:allow
+>            user:42:r-x-----------:f-i---:allow
+>           group:42:-w--D---------:-di---:allow
+>           group:42:-w------------:------:deny
+>           group:42:-w--D---------:------:allow
+>           group:43:-w--D---------:-di---:deny
+>           group:43:-w--D---------:------:deny
+>             group@:-----da-------:------:allow
+>           group:44:rw-p----------:------:deny
+>           group:44:rw-p-da-------:------:allow
+>             owner@:--------------:------:deny
+>             owner@:-------A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:-------A-W-Co-:------:deny
+>          everyone@:-w-p--a-R-c--s:f-i---:allow
+>             owner@:-wxp----------:------:deny
+>             owner@:r------A-W-Co-:------:allow
+>             group@:rw-p----------:------:deny
+>             group@:--x-----------:------:allow
+>          everyone@:r-x----A-W-Co-:------:deny
+>          everyone@:-w-p--a-R-c--s:------:allow
+
+$ rmdir ddd
+$ mkdir ddd
+$ setfacl -a0 group:44:rwapd:allow ddd
+$ setfacl -a0 group:43:write_data/delete_child:d:deny,group@:ad:allow ddd
+$ setfacl -a0 user:42:rx:allow,user:42:rx:fi:allow,group:42:write_data/delete_child:d:allow ddd
+$ setfacl -m everyone@:-w-p--a-R-c--s:fi:allow ddd
+$ chown 42 ddd
+$ chmod 412 ddd
+$ getfacl -n ddd
+> # file: ddd
+> # owner: 42
+> # group: wheel
+>            user:42:--x-----------:------:deny
+>            user:42:r-x-----------:------:allow
+>            user:42:r-x-----------:f-i---:allow
+>           group:42:-w--D---------:-di---:allow
+>           group:42:-w------------:------:deny
+>           group:42:-w--D---------:------:allow
+>           group:43:-w--D---------:-di---:deny
+>           group:43:-w--D---------:------:deny
+>             group@:-----da-------:------:allow
+>           group:44:rw-p----------:------:deny
+>           group:44:rw-p-da-------:------:allow
+>             owner@:--------------:------:deny
+>             owner@:-------A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:-------A-W-Co-:------:deny
+>          everyone@:-w-p--a-R-c--s:f-i---:allow
+>             owner@:-wxp----------:------:deny
+>             owner@:r------A-W-Co-:------:allow
+>             group@:rw-p----------:------:deny
+>             group@:--x-----------:------:allow
+>          everyone@:r-x----A-W-Co-:------:deny
+>          everyone@:-w-p--a-R-c--s:------:allow
+
+# Test applying ACL to mode.
+$ rmdir ddd
+$ mkdir ddd
+$ setfacl -a0 u:42:rwx:fi:allow ddd
+$ ls -ld ddd | cut -d' ' -f1
+> drwxr-xr-x+
+
+$ rmdir ddd
+$ mkdir ddd
+$ chmod 0 ddd
+$ setfacl -a0 owner@:r:allow,group@:w:deny,group@:wx:allow ddd
+$ ls -ld ddd | cut -d' ' -f1
+> dr----x---+
+
+# XXX: This one is fishy.  Shouldn't it be "dr---wx---+"?
+$ rmdir ddd
+$ mkdir ddd
+$ chmod 0 ddd
+$ setfacl -a0 owner@:r:allow,group@:w:fi:deny,group@:wx:allow ddd
+$ ls -ld ddd | cut -d' ' -f1
+> dr---wx---+
+
+$ rmdir ddd
+$ mkdir ddd
+$ chmod 0 ddd
+$ setfacl -a0 owner@:r:allow,group:43:w:deny,group:43:wx:allow ddd
+$ ls -ld ddd | cut -d' ' -f1
+> dr--------+
+
+$ rmdir ddd
+$ mkdir ddd
+$ chmod 0 ddd
+$ setfacl -a0 owner@:r:allow,user:43:w:deny,user:43:wx:allow ddd
+$ ls -ld ddd | cut -d' ' -f1
+> dr--------+
+
+# Test inheritance.
+$ rmdir ddd
+$ mkdir ddd
+$ setfacl -a0 group:43:write_data/write_acl:fin:deny,u:43:rwxp:allow ddd
+$ setfacl -a0 user:42:rx:fi:allow,group:42:write_data/delete_child:dn:deny ddd
+$ setfacl -a0 user:42:write_acl/write_owner:fi:allow ddd
+$ setfacl -a0 group:41:read_data/read_attributes:dni:allow ddd
+$ setfacl -a0 user:41:write_data/write_attributes:fn:allow ddd
+$ getfacl -qn ddd
+>            user:41:-w-----A------:f--n--:allow
+>           group:41:r-----a-------:-din--:allow
+>            user:42:-----------Co-:f-i---:allow
+>            user:42:r-x-----------:f-i---:allow
+>           group:42:-w--D---------:-d-n--:deny
+>           group:43:-w---------C--:f-in--:deny
+>            user:43:rwxp----------:------:allow
+>             owner@:--------------:------:deny
+>             owner@:rwxp---A-W-Co-:------:allow
+>             group@:-w-p----------:------:deny
+>             group@:r-x-----------:------:allow
+>          everyone@:-w-p---A-W-Co-:------:deny
+>          everyone@:r-x---a-R-c--s:------:allow
+
+$ cd ddd
+$ touch xxx
+$ getfacl -qn xxx
+>            user:41:-w------------:------:deny
+>            user:41:-w-----A------:------:allow
+>            user:42:--------------:------:deny
+>            user:42:--------------:------:allow
+>            user:42:--x-----------:------:deny
+>            user:42:r-x-----------:------:allow
+>           group:43:-w---------C--:------:deny
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+$ rm xxx
+$ umask 077
+$ touch xxx
+$ getfacl -qn xxx
+>            user:41:-w------------:------:deny
+>            user:41:-w-----A------:------:allow
+>            user:42:--------------:------:deny
+>            user:42:--------------:------:allow
+>            user:42:r-x-----------:------:deny
+>            user:42:r-x-----------:------:allow
+>           group:43:-w---------C--:------:deny
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:rwxp----------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:rwxp---A-W-Co-:------:deny
+>          everyone@:------a-R-c--s:------:allow
+
+$ rm xxx
+$ umask 770
+$ touch xxx
+$ getfacl -qn xxx
+>            user:41:-w------------:------:deny
+>            user:41:-w-----A------:------:allow
+>            user:42:--------------:------:deny
+>            user:42:--------------:------:allow
+>            user:42:r-x-----------:------:deny
+>            user:42:r-x-----------:------:allow
+>           group:43:-w---------C--:------:deny
+>             owner@:rwxp----------:------:deny
+>             owner@:-------A-W-Co-:------:allow
+>             group@:rwxp----------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:--x----A-W-Co-:------:deny
+>          everyone@:rw-p--a-R-c--s:------:allow
+
+$ rm xxx
+$ umask 707
+$ touch xxx
+$ getfacl -qn xxx
+>            user:41:--------------:------:deny
+>            user:41:-w-----A------:------:allow
+>            user:42:--------------:------:deny
+>            user:42:--------------:------:allow
+>            user:42:--x-----------:------:deny
+>            user:42:r-x-----------:------:allow
+>           group:43:-w---------C--:------:deny
+>             owner@:rwxp----------:------:deny
+>             owner@:-------A-W-Co-:------:allow
+>             group@:--x-----------:------:deny
+>             group@:rw-p----------:------:allow
+>          everyone@:rwxp---A-W-Co-:------:deny
+>          everyone@:------a-R-c--s:------:allow
+
+$ umask 077
+$ mkdir yyy
+$ getfacl -qn yyy
+>           group:41:r-------------:------:deny
+>           group:41:r-----a-------:------:allow
+>            user:42:-----------Co-:f-i---:allow
+>            user:42:r-x-----------:f-i---:allow
+>           group:42:-w--D---------:------:deny
+>             owner@:--------------:------:deny
+>             owner@:rwxp---A-W-Co-:------:allow
+>             group@:rwxp----------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:rwxp---A-W-Co-:------:deny
+>          everyone@:------a-R-c--s:------:allow
+
+$ rmdir yyy
+$ umask 770
+$ mkdir yyy
+$ getfacl -qn yyy
+>           group:41:r-------------:------:deny
+>           group:41:r-----a-------:------:allow
+>            user:42:-----------Co-:f-i---:allow
+>            user:42:r-x-----------:f-i---:allow
+>           group:42:-w--D---------:------:deny
+>             owner@:rwxp----------:------:deny
+>             owner@:-------A-W-Co-:------:allow
+>             group@:rwxp----------:------:deny
+>             group@:--------------:------:allow
+>          everyone@:-------A-W-Co-:------:deny
+>          everyone@:rwxp--a-R-c--s:------:allow
+
+$ rmdir yyy
+$ umask 707
+$ mkdir yyy
+$ getfacl -qn yyy
+>           group:41:--------------:------:deny
+>           group:41:------a-------:------:allow
+>            user:42:-----------Co-:f-i---:allow
+>            user:42:r-x-----------:f-i---:allow
+>           group:42:-w--D---------:------:deny
+>             owner@:rwxp----------:------:deny
+>             owner@:-------A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:rwxp----------:------:allow
+>          everyone@:rwxp---A-W-Co-:------:deny
+>          everyone@:------a-R-c--s:------:allow
+
+# There is some complication regarding how write_acl and write_owner flags
+# get inherited.  Make sure we got it right.
+$ setfacl -b .
+$ setfacl -a0 u:42:Co:f:allow .
+$ setfacl -a0 u:43:Co:d:allow .
+$ setfacl -a0 u:44:Co:fd:allow .
+$ setfacl -a0 u:45:Co:fi:allow .
+$ setfacl -a0 u:46:Co:di:allow .
+$ setfacl -a0 u:47:Co:fdi:allow .
+$ setfacl -a0 u:48:Co:fn:allow .
+$ setfacl -a0 u:49:Co:dn:allow .
+$ setfacl -a0 u:50:Co:fdn:allow .
+$ setfacl -a0 u:51:Co:fni:allow .
+$ setfacl -a0 u:52:Co:dni:allow .
+$ setfacl -a0 u:53:Co:fdni:allow .
+$ umask 022
+$ rm xxx
+$ touch xxx
+$ getfacl -nq xxx
+>            user:53:--------------:------:deny
+>            user:53:--------------:------:allow
+>            user:51:--------------:------:deny
+>            user:51:--------------:------:allow
+>            user:50:--------------:------:deny
+>            user:50:--------------:------:allow
+>            user:48:--------------:------:deny
+>            user:48:--------------:------:allow
+>            user:47:--------------:------:deny
+>            user:47:--------------:------:allow
+>            user:45:--------------:------:deny
+>            user:45:--------------:------:allow
+>            user:44:--------------:------:deny
+>            user:44:--------------:------:allow
+>            user:42:--------------:------:deny
+>            user:42:--------------:------:allow
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+$ rmdir yyy
+$ mkdir yyy
+$ getfacl -nq yyy
+>            user:53:--------------:------:deny
+>            user:53:--------------:------:allow
+>            user:52:--------------:------:deny
+>            user:52:--------------:------:allow
+>            user:50:--------------:------:deny
+>            user:50:--------------:------:allow
+>            user:49:--------------:------:deny
+>            user:49:--------------:------:allow
+>            user:47:-----------Co-:fdi---:allow
+>            user:47:--------------:------:deny
+>            user:47:--------------:------:allow
+>            user:46:-----------Co-:-di---:allow
+>            user:46:--------------:------:deny
+>            user:46:--------------:------:allow
+>            user:45:-----------Co-:f-i---:allow
+>            user:44:-----------Co-:fdi---:allow
+>            user:44:--------------:------:deny
+>            user:44:--------------:------:allow
+>            user:43:-----------Co-:-di---:allow
+>            user:43:--------------:------:deny
+>            user:43:--------------:------:allow
+>            user:42:-----------Co-:f-i---:allow
+>             owner@:--------------:------:deny
+>             owner@:rwxp---A-W-Co-:------:allow
+>             group@:-w-p----------:------:deny
+>             group@:r-x-----------:------:allow
+>          everyone@:-w-p---A-W-Co-:------:deny
+>          everyone@:r-x---a-R-c--s:------:allow
+
+$ setfacl -b .
+$ setfacl -a0 u:42:Co:f:deny .
+$ setfacl -a0 u:43:Co:d:deny .
+$ setfacl -a0 u:44:Co:fd:deny .
+$ setfacl -a0 u:45:Co:fi:deny .
+$ setfacl -a0 u:46:Co:di:deny .
+$ setfacl -a0 u:47:Co:fdi:deny .
+$ setfacl -a0 u:48:Co:fn:deny .
+$ setfacl -a0 u:49:Co:dn:deny .
+$ setfacl -a0 u:50:Co:fdn:deny .
+$ setfacl -a0 u:51:Co:fni:deny .
+$ setfacl -a0 u:52:Co:dni:deny .
+$ setfacl -a0 u:53:Co:fdni:deny .
+$ umask 022
+$ rm xxx
+$ touch xxx
+$ getfacl -nq xxx
+>            user:53:-----------Co-:------:deny
+>            user:51:-----------Co-:------:deny
+>            user:50:-----------Co-:------:deny
+>            user:48:-----------Co-:------:deny
+>            user:47:-----------Co-:------:deny
+>            user:45:-----------Co-:------:deny
+>            user:44:-----------Co-:------:deny
+>            user:42:-----------Co-:------:deny
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+$ rmdir yyy
+$ mkdir yyy
+$ getfacl -nq yyy
+>            user:53:-----------Co-:------:deny
+>            user:52:-----------Co-:------:deny
+>            user:50:-----------Co-:------:deny
+>            user:49:-----------Co-:------:deny
+>            user:47:-----------Co-:fdi---:deny
+>            user:47:-----------Co-:------:deny
+>            user:46:-----------Co-:-di---:deny
+>            user:46:-----------Co-:------:deny
+>            user:45:-----------Co-:f-i---:deny
+>            user:44:-----------Co-:fdi---:deny
+>            user:44:-----------Co-:------:deny
+>            user:43:-----------Co-:-di---:deny
+>            user:43:-----------Co-:------:deny
+>            user:42:-----------Co-:f-i---:deny
+>             owner@:--------------:------:deny
+>             owner@:rwxp---A-W-Co-:------:allow
+>             group@:-w-p----------:------:deny
+>             group@:r-x-----------:------:allow
+>          everyone@:-w-p---A-W-Co-:------:deny
+>          everyone@:r-x---a-R-c--s:------:allow
+
+$ rmdir yyy
+$ rm xxx
+$ cd ..
+$ rmdir ddd
+
+$ rm xxx
+
diff --git a/tools/regression/acltools/tools-posix.test b/tools/regression/acltools/tools-posix.test
index 6ae31f36edd..4741db383fd 100644
--- a/tools/regression/acltools/tools-posix.test
+++ b/tools/regression/acltools/tools-posix.test
@@ -1,11 +1,36 @@
+# Copyright (c) 2008, 2009 Edward Tomasz Napierała 
+# 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$
+#
+
 # This is a tools-level test for POSIX.1e ACL functionality.  Run it as root
 # using ACL-enabled kernel:
 #
 # /usr/src/tools/regression/acltools/run /usr/src/tools/regression/acltools/tools-posix.test
 #
 # WARNING: Creates files in unsafe way.
-#
-# $FreeBSD$
 
 $ whoami
 > root
@@ -13,7 +38,7 @@ $ umask 022
 
 # Smoke test for getfacl(1).
 $ touch xxx
-$ getfacl xxx
+$ getfacl -n xxx
 > # file: xxx
 > # owner: root
 > # group: wheel
@@ -27,7 +52,7 @@ $ getfacl -q xxx
 > other::r--
 
 $ setfacl -m u:42:r,g:43:w xxx
-$ getfacl xxx
+$ getfacl -n xxx
 > # file: xxx
 > # owner: root
 > # group: wheel
@@ -98,8 +123,32 @@ $ getfacl xxx
 > mask::rw-
 > other::r--
 
+$ setfacl -m u:42:r xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+> user::rw-
+> user:42:r--
+> group::r--
+> group:43:-w-
+> mask::rw-
+> other::r--
+
+# Test removing entries by number.
+$ setfacl -x 1 xxx
+$ getfacl -n xxx
+> # file: xxx
+> # owner: root
+> # group: wheel
+> user::rw-
+> group::r--
+> group:43:-w-
+> mask::rw-
+> other::r--
+
 $ setfacl -m g:43:r xxx
-$ getfacl xxx
+$ getfacl -n xxx
 > # file: xxx
 > # owner: root
 > # group: wheel
@@ -117,7 +166,7 @@ $ ls -l yyy | cut -d' ' -f1
 # Make sure it does with the "-p" flag.
 $ rm yyy
 $ cp -p xxx yyy
-$ getfacl yyy
+$ getfacl -n yyy
 > # file: yyy
 > # owner: root
 > # group: wheel
@@ -132,7 +181,7 @@ $ rm yyy
 # Test removing entries by...  by example?
 $ setfacl -m u:42:r,g:43:w xxx
 $ setfacl -x u:42: xxx
-$ getfacl xxx
+$ getfacl -n xxx
 > # file: xxx
 > # owner: root
 > # group: wheel
@@ -144,7 +193,7 @@ $ getfacl xxx
 
 # Test setfacl -b.
 $ setfacl -b xxx
-$ getfacl xxx
+$ getfacl -n xxx
 > # file: xxx
 > # owner: root
 > # group: wheel
@@ -157,7 +206,7 @@ $ ls -l xxx | cut -d' ' -f1
 > -rw-r--r--+
 
 $ setfacl -nb xxx
-$ getfacl xxx
+$ getfacl -n xxx
 > # file: xxx
 > # owner: root
 > # group: wheel
@@ -177,7 +226,7 @@ $ ls -l xxx yyy zzz | cut -d' ' -f1
 > -rw-r--r--
 
 $ setfacl -m u:42:x,g:43:w nnn xxx yyy zzz
-> setfacl: stat() of nnn failed: No such file or directory
+> setfacl: nnn: stat() failed: No such file or directory
 
 $ ls -l nnn xxx yyy zzz | cut -d' ' -f1
 > ls: nnn: No such file or directory
@@ -185,8 +234,8 @@ $ ls -l nnn xxx yyy zzz | cut -d' ' -f1
 > -rw-rwxr--+
 > -rw-rwxr--+
 
-$ getfacl -q nnn xxx yyy zzz
-> getfacl: nnn: No such file or directory
+$ getfacl -nq nnn xxx yyy zzz
+> getfacl: nnn: stat() failed: No such file or directory
 > user::rw-
 > user:42:--x
 > group::r--
@@ -209,7 +258,7 @@ $ getfacl -q nnn xxx yyy zzz
 > other::r--
 
 $ setfacl -b nnn xxx yyy zzz
-> setfacl: stat() of nnn failed: No such file or directory
+> setfacl: nnn: stat() failed: No such file or directory
 
 $ ls -l nnn xxx yyy zzz | cut -d' ' -f1
 > ls: nnn: No such file or directory
@@ -218,7 +267,7 @@ $ ls -l nnn xxx yyy zzz | cut -d' ' -f1
 > -rw-r--r--+
 
 $ setfacl -bn nnn xxx yyy zzz
-> setfacl: stat() of nnn failed: No such file or directory
+> setfacl: nnn: stat() failed: No such file or directory
 
 $ ls -l nnn xxx yyy zzz | cut -d' ' -f1
 > ls: nnn: No such file or directory
@@ -232,7 +281,7 @@ $ rm xxx yyy zzz
 $ touch xxx
 $ setfacl -m u:42:rwx,g:43:rwx xxx
 $ chmod 600 xxx
-$ getfacl xxx
+$ getfacl -n xxx
 > # file: xxx
 > # owner: root
 > # group: wheel
@@ -244,7 +293,7 @@ $ getfacl xxx
 > other::---
 
 $ chmod 060 xxx
-$ getfacl xxx
+$ getfacl -n xxx
 > # file: xxx
 > # owner: root
 > # group: wheel
@@ -258,7 +307,7 @@ $ getfacl xxx
 # Test default ACLs.
 $ umask 022
 $ mkdir ddd
-$ getfacl -q ddd
+$ getfacl -qn ddd
 > user::rwx
 > group::r-x
 > other::r-x
@@ -268,7 +317,7 @@ $ ls -l | grep ddd | cut -d' ' -f1
 
 $ getfacl -dq ddd
 $ setfacl -dm u::rwx,g::rx,o::rx,mask::rwx ddd
-$ getfacl -dq ddd
+$ getfacl -dqn ddd
 > user::rwx
 > group::r-x
 > mask::rwx
@@ -280,7 +329,7 @@ $ ls -l | grep ddd | cut -d' ' -f1
 
 $ setfacl -dm g:42:rwx,u:42:r ddd
 $ setfacl -dm g::w ddd
-$ getfacl -dq ddd
+$ getfacl -dqn ddd
 > user::rwx
 > user:42:r--
 > group::-w-
@@ -289,7 +338,7 @@ $ getfacl -dq ddd
 > other::r-x
 
 $ setfacl -dx group:42: ddd
-$ getfacl -dq ddd
+$ getfacl -dqn ddd
 > user::rwx
 > user:42:r--
 > group::-w-
@@ -389,7 +438,7 @@ $ rm fff
 # Test if we deal properly with device files.
 $ mknod bbb b 1 1
 $ setfacl -m u:42:r,g:43:w bbb
-> setfacl: acl_get_file() failed: Operation not supported
+> setfacl: bbb: acl_get_file() failed: Operation not supported
 $ ls -l bbb | cut -d' ' -f1
 > brw-r--r--
 
@@ -397,7 +446,7 @@ $ rm bbb
 
 $ mknod ccc c 1 1
 $ setfacl -m u:42:r,g:43:w ccc
-> setfacl: acl_get_file() failed: Operation not supported
+> setfacl: ccc: acl_get_file() failed: Operation not supported
 $ ls -l ccc | cut -d' ' -f1
 > crw-r--r--
 

From 5f16df94072473c251a87cf7cacd7ace3ebd3e88 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sun, 31 Jan 2010 02:22:31 +0000
Subject: [PATCH 1335/2592] MFC r197434:

Add ACL fuzzer.  It's not used by the regression tests right now,
but I'd prefert to have it here, so it won't get lost.
---
 tools/regression/acltools/aclfuzzer.sh | 225 +++++++++++++++++++++++++
 1 file changed, 225 insertions(+)
 create mode 100755 tools/regression/acltools/aclfuzzer.sh

diff --git a/tools/regression/acltools/aclfuzzer.sh b/tools/regression/acltools/aclfuzzer.sh
new file mode 100755
index 00000000000..dff07d8218d
--- /dev/null
+++ b/tools/regression/acltools/aclfuzzer.sh
@@ -0,0 +1,225 @@
+#!/bin/sh
+#
+# Copyright (c) 2008, 2009 Edward Tomasz Napierała 
+# 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$
+#
+
+# This is an NFSv4 ACL fuzzer.  It expects to be run by non-root in a scratch
+# directory on a filesystem with NFSv4 ACLs support.  Output it generates
+# is expected to be fed to /usr/src/tools/regression/acltools/run script.
+
+NUMBER_OF_COMMANDS=300
+
+run_command()
+{
+	echo "\$ $1"
+	eval $1 2>&1 | sed 's/^/> /'
+}
+
+rnd_from_0_to()
+{
+	max=`expr $1 + 1`
+	rnd=`jot -r 1`
+	rnd=`expr $rnd % $max`
+
+	echo $rnd
+}
+
+rnd_path()
+{
+	rnd=`rnd_from_0_to 3`
+	case $rnd in
+		0) echo "$TMP/aaa" ;;
+		1) echo "$TMP/bbb" ;;
+		2) echo "$TMP/aaa/ccc" ;;
+		3) echo "$TMP/bbb/ddd" ;;
+	esac
+}
+
+f_prepend_random_acl_on()
+{
+	rnd=`rnd_from_0_to 4`
+	case $rnd in
+		0) u="owner@" ;;
+		1) u="group@" ;;
+		2) u="everyone@" ;;
+		3) u="u:1138" ;;
+		4) u="g:1138" ;;
+	esac
+
+	p=""
+	while :; do
+		rnd=`rnd_from_0_to 30`
+		if [ -n "$p" -a $rnd -ge 14 ]; then
+			break;
+		fi
+
+		case $rnd in
+			0) p="${p}r" ;;
+			1) p="${p}w" ;;
+			2) p="${p}x" ;;
+			3) p="${p}p" ;;
+			4) p="${p}d" ;;
+			5) p="${p}D" ;;
+			6) p="${p}a" ;;
+			7) p="${p}A" ;;
+			8) p="${p}R" ;;
+			9) p="${p}W" ;;
+			10) p="${p}R" ;;
+			11) p="${p}c" ;;
+			12) p="${p}C" ;;
+			13) p="${p}o" ;;
+			14) p="${p}s" ;;
+		esac
+	done
+
+	f=""
+	while :; do
+		rnd=`rnd_from_0_to 10`
+		if [ $rnd -ge 6 ]; then
+			break;
+		fi
+
+		case $rnd in
+			0) f="${f}f" ;;
+			1) f="${f}d" ;;
+			2) f="${f}n" ;;
+			3) f="${f}i" ;;
+		esac
+	done
+
+	rnd=`rnd_from_0_to 1`
+	case $rnd in
+		0) x="allow" ;;
+		1) x="deny" ;;
+	esac
+
+	acl="$u:$p:$f:$x"
+
+	file=`rnd_path`
+	run_command "setfacl -a0 $acl $file"
+}
+
+f_getfacl()
+{
+	file=`rnd_path`
+	run_command "getfacl -qn $file"
+}
+
+f_ls_mode()
+{
+	file=`rnd_path`
+	run_command "ls -al $file | sed -n '2p' | cut -d' ' -f1"
+}
+
+f_chmod()
+{
+	b1=`rnd_from_0_to 7`
+	b2=`rnd_from_0_to 7`
+	b3=`rnd_from_0_to 7`
+	b4=`rnd_from_0_to 7`
+	file=`rnd_path`
+
+	run_command "chmod $b1$b2$b3$b4 $file $2"
+}
+
+f_touch()
+{
+	file=`rnd_path`
+	run_command "touch $file"
+}
+
+f_rm()
+{
+	file=`rnd_path`
+	run_command "rm -f $file"
+}
+
+f_mkdir()
+{
+	file=`rnd_path`
+	run_command "mkdir $file"
+}
+
+f_rmdir()
+{
+	file=`rnd_path`
+	run_command "rmdir $file"
+}
+
+f_mv()
+{
+	from=`rnd_path`
+	to=`rnd_path`
+	run_command "mv -f $from $to"
+}
+
+# XXX: To be implemented: chown(8), setting times with touch(1).
+
+switch_to_random_user()
+{
+	# XXX: To be implemented.
+}
+
+execute_random_command()
+{
+	rnd=`rnd_from_0_to 20`
+
+	case $rnd in
+		0|10|11|12|13|15) cmd=f_prepend_random_acl_on ;;
+		1) cmd=f_getfacl ;;
+		2) cmd=f_ls_mode ;;
+		3) cmd=f_chmod ;;
+		4|18|19) cmd=f_touch ;;
+		5) cmd=f_rm ;;
+		6|16|17) cmd=f_mkdir ;;
+		7) cmd=f_rmdir ;;
+		8) cmd=f_mv ;;
+	esac
+
+	$cmd "XXX"
+}
+
+echo "# Fuzzing; will stop after $NUMBER_OF_COMMANDS commands."
+TMP="aclfuzzer_`dd if=/dev/random bs=1k count=1 2>/dev/null | openssl md5`"
+
+run_command "whoami"
+umask 022
+run_command "umask 022"
+run_command "mkdir $TMP"
+
+i=0;
+while [ "$i" -lt "$NUMBER_OF_COMMANDS" ]; do
+	switch_to_random_user
+	execute_random_command
+	i=`expr $i + 1`
+done
+
+run_command "find $TMP -exec setfacl -a0 everyone@:rxd:allow {} \;"
+run_command "rm -rfv $TMP"
+
+echo "# Fuzzed, thank you."
+

From 8dc3de711c3412eae0f755ef0eac9b87d51050ea Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sun, 31 Jan 2010 02:23:53 +0000
Subject: [PATCH 1336/2592] MFC r197436:

Add cross-filesystem regression tests for ACLs.
---
 tools/regression/acltools/00.t               |   2 +-
 tools/regression/acltools/03.t               | 110 ++++++++++++
 tools/regression/acltools/tools-crossfs.test | 178 +++++++++++++++++++
 3 files changed, 289 insertions(+), 1 deletion(-)
 create mode 100644 tools/regression/acltools/03.t
 create mode 100644 tools/regression/acltools/tools-crossfs.test

diff --git a/tools/regression/acltools/00.t b/tools/regression/acltools/00.t
index c76b39efb4f..1f91de339c0 100644
--- a/tools/regression/acltools/00.t
+++ b/tools/regression/acltools/00.t
@@ -27,7 +27,7 @@
 # $FreeBSD$
 #
 
-# This is a wrapper script to run tools-posix.test.
+# This is a wrapper script to run tools-posix.test on UFS filesystem.
 #
 # If any of the tests fails, here is how to debug it: go to
 # the directory with problematic filesystem mounted on it,
diff --git a/tools/regression/acltools/03.t b/tools/regression/acltools/03.t
new file mode 100644
index 00000000000..8e56af5e593
--- /dev/null
+++ b/tools/regression/acltools/03.t
@@ -0,0 +1,110 @@
+#!/bin/sh
+#
+# Copyright (c) 2008, 2009 Edward Tomasz Napierała 
+# 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$
+#
+
+# This is a wrapper script to run tools-crossfs.test between UFS without
+# ACLs, UFS with POSIX.1e ACLs, and ZFS with NFSv4 ACLs.
+#
+# WARNING: It uses hardcoded ZFS pool name "acltools"
+#
+# Output should be obvious.
+
+echo "1..5"
+
+if [ `whoami` != "root" ]; then
+	echo "not ok 1 - you need to be root to run this test."
+	exit 1
+fi
+
+TESTDIR=`dirname $0`
+MNTROOT=`mktemp -dt acltools`
+
+# Set up the test filesystems.
+MD1=`mdconfig -at swap -s 64m`
+MNT1=$MNTROOT/nfs4
+mkdir $MNT1
+zpool create -R $MNT1 acltools /dev/$MD1
+if [ $? -ne 0 ]; then
+	echo "not ok 1 - 'zpool create' failed."
+	exit 1
+fi
+
+echo "ok 1"
+
+MD2=`mdconfig -at swap -s 10m`
+MNT2=$MNTROOT/posix
+mkdir $MNT2
+newfs /dev/$MD2 > /dev/null
+mount -o acls /dev/$MD2 $MNT2
+if [ $? -ne 0 ]; then
+	echo "not ok 2 - mount failed."
+	exit 1
+fi
+
+echo "ok 2"
+
+MD3=`mdconfig -at swap -s 10m`
+MNT3=$MNTROOT/none
+mkdir $MNT3
+newfs /dev/$MD3 > /dev/null
+mount /dev/$MD3 $MNT3
+if [ $? -ne 0 ]; then
+	echo "not ok 3 - mount failed."
+	exit 1
+fi
+
+echo "ok 3"
+
+cd $MNTROOT
+
+perl $TESTDIR/run $TESTDIR/tools-crossfs.test > /dev/null
+
+if [ $? -eq 0 ]; then
+	echo "ok 4"
+else
+	echo "not ok 4"
+fi
+
+cd /
+
+umount -f $MNT3
+rmdir $MNT3
+mdconfig -du $MD3
+
+umount -f $MNT2
+rmdir $MNT2
+mdconfig -du $MD2
+
+zpool destroy -f acltools
+rmdir $MNT1
+mdconfig -du $MD1
+
+rmdir $MNTROOT
+
+echo "ok 5"
+
diff --git a/tools/regression/acltools/tools-crossfs.test b/tools/regression/acltools/tools-crossfs.test
new file mode 100644
index 00000000000..f6c5ed408b7
--- /dev/null
+++ b/tools/regression/acltools/tools-crossfs.test
@@ -0,0 +1,178 @@
+# Copyright (c) 2008, 2009 Edward Tomasz Napierała 
+# 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$
+#
+
+# This is a tools-level test intended to verify that cp(1) and mv(1)
+# do the right thing with respect to ACLs.  Run it as root using
+# ACL-enabled kernel:
+#
+# /usr/src/tools/regression/acltools/run /usr/src/tools/regression/acltools/tools-nfs4.test
+#
+# You need to have three subdirectories, named nfs4, posix and none,
+# with filesystems with NFSv4 ACLs, POSIX.1e ACLs and no ACLs enabled,
+# respectively, mounted on them, in your current directory.
+#
+# WARNING: Creates files in unsafe way.
+
+$ whoami
+> root
+$ umask 022
+
+$ touch nfs4/xxx
+$ getfacl -nq nfs4/xxx
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+$ touch posix/xxx
+$ getfacl -nq posix/xxx
+> user::rw-
+> group::r--
+> other::r--
+
+$ rm posix/xxx
+
+# mv without any ACLs.
+$ chmod 456 nfs4/xxx
+$ mv nfs4/xxx posix/
+$ ls -l posix/xxx | cut -d' ' -f1
+> -r--r-xrw-
+
+# mv with POSIX.1e ACLs.
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ rm -f posix/yyy
+$ mv posix/xxx posix/yyy
+$ getfacl -nq posix/yyy
+> user::r--
+> user:42:--x
+> group::r-x
+> group:43:-w-
+> mask::rwx
+> other::rw-
+
+# mv from POSIX.1e to NFSv4.
+$ rm -f nfs4/xxx
+$ mv posix/yyy nfs4/xxx
+> mv: failed to set acl entries for nfs4/xxx: Invalid argument
+$ getfacl -nq nfs4/xxx
+>             owner@:-wxp----------:------:deny
+>             owner@:r------A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:rwxp----------:------:allow
+>          everyone@:--x----A-W-Co-:------:deny
+>          everyone@:rw-p--a-R-c--s:------:allow
+
+# mv with NFSv4 ACLs.
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ rm -f nfs4/yyy
+$ mv nfs4/xxx nfs4/yyy
+$ getfacl -nq nfs4/yyy
+>            user:42:--x-----------:------:allow
+>           group:43:-w------------:------:allow
+>             owner@:-wxp----------:------:deny
+>             owner@:r------A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:rwxp----------:------:allow
+>          everyone@:--x----A-W-Co-:------:deny
+>          everyone@:rw-p--a-R-c--s:------:allow
+
+# mv from NFSv4 to POSIX.1e.
+$ rm -f posix/xxx
+$ mv nfs4/yyy posix/xxx
+> mv: failed to set acl entries for posix/xxx: Invalid argument
+$ ls -l posix/xxx | cut -d' ' -f1
+> -r--rwxrw-
+
+# mv from POSIX.1e to none.
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ mv posix/xxx none/xxx
+> mv: failed to set acl entries for none/xxx: Operation not supported
+$ ls -l none/xxx | cut -d' ' -f1
+> -r--rwxrw-
+
+# cp with POSIX.1e ACLs.
+$ rm -f posix/xxx
+$ touch posix/xxx
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ getfacl -nq posix/xxx
+> user::rw-
+> user:42:--x
+> group::r--
+> group:43:-w-
+> mask::rwx
+> other::r--
+
+$ rm -f posix/yyy
+$ cp posix/xxx posix/yyy
+$ getfacl -nq posix/yyy
+> user::rw-
+> group::r-x
+> other::r--
+
+$ rm -f posix/yyy
+$ cp -p posix/xxx posix/yyy
+$ getfacl -nq posix/yyy
+> user::rw-
+> user:42:--x
+> group::r--
+> group:43:-w-
+> mask::rwx
+> other::r--
+
+# mv from POSIX.1e to NFSv4.
+$ rm -f nfs4/xxx
+$ cp -p posix/xxx nfs4/xxx
+> cp: failed to set acl entries for nfs4/xxx: Invalid argument
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> -rw-rwxr--
+
+# cp with NFSv4 ACLs.
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ rm -f nfs4/yyy
+$ cp -p nfs4/xxx nfs4/yyy
+$ getfacl -nq nfs4/yyy
+>            user:42:--x-----------:------:allow
+>           group:43:-w------------:------:allow
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:--------------:------:deny
+>             group@:rwxp----------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+
+# cp from NFSv4 to POSIX.1e.
+$ rm -f posix/xxx
+$ cp -p nfs4/xxx posix/xxx
+> cp: failed to set acl entries for posix/xxx: Invalid argument
+$ ls -l posix/xxx | cut -d' ' -f1
+> -rw-rwxr--
+
+$ cp -p nfs4/yyy none/xxx
+> cp: failed to set acl entries for none/xxx: Operation not supported
+

From ca9c0141f2f52c12f0e3f01f17dfa76d11d5c2f9 Mon Sep 17 00:00:00 2001
From: Edward Tomasz Napierala 
Date: Sun, 31 Jan 2010 02:25:15 +0000
Subject: [PATCH 1337/2592] MFC r201048:

Make tests for ACL preservation by mv(1) and cp(1) more complete
and easier to follow.
---
 tools/regression/acltools/tools-crossfs.test | 243 +++++++++++++++----
 1 file changed, 198 insertions(+), 45 deletions(-)

diff --git a/tools/regression/acltools/tools-crossfs.test b/tools/regression/acltools/tools-crossfs.test
index f6c5ed408b7..6652a120bef 100644
--- a/tools/regression/acltools/tools-crossfs.test
+++ b/tools/regression/acltools/tools-crossfs.test
@@ -56,17 +56,14 @@ $ getfacl -nq posix/xxx
 > group::r--
 > other::r--
 
-$ rm posix/xxx
-
-# mv without any ACLs.
-$ chmod 456 nfs4/xxx
-$ mv nfs4/xxx posix/
+# mv with POSIX.1e ACLs.
+$ rm -f posix/xxx
+$ rm -f posix/yyy
+$ touch posix/xxx
+$ chmod 456 posix/xxx
 $ ls -l posix/xxx | cut -d' ' -f1
 > -r--r-xrw-
-
-# mv with POSIX.1e ACLs.
 $ setfacl -m u:42:x,g:43:w posix/xxx
-$ rm -f posix/yyy
 $ mv posix/xxx posix/yyy
 $ getfacl -nq posix/yyy
 > user::r--
@@ -75,9 +72,30 @@ $ getfacl -nq posix/yyy
 > group:43:-w-
 > mask::rwx
 > other::rw-
+$ ls -l posix/yyy | cut -d' ' -f1
+> -r--rwxrw-+
+
+# mv from POSIX.1e to none.
+$ rm -f posix/xxx
+$ rm -f none/xxx
+$ touch posix/xxx
+$ chmod 345 posix/xxx
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ ls -l posix/xxx | cut -d' ' -f1
+> --wxrwxr-x+
+$ mv posix/xxx none/xxx
+> mv: failed to set acl entries for none/xxx: Operation not supported
+$ ls -l none/xxx | cut -d' ' -f1
+> --wxrwxr-x
 
 # mv from POSIX.1e to NFSv4.
+$ rm -f posix/xxx
 $ rm -f nfs4/xxx
+$ touch posix/xxx
+$ chmod 456 posix/xxx
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ ls -l posix/xxx | cut -d' ' -f1
+> -r--rwxrw-+
 $ mv posix/yyy nfs4/xxx
 > mv: failed to set acl entries for nfs4/xxx: Invalid argument
 $ getfacl -nq nfs4/xxx
@@ -87,37 +105,82 @@ $ getfacl -nq nfs4/xxx
 >             group@:rwxp----------:------:allow
 >          everyone@:--x----A-W-Co-:------:deny
 >          everyone@:rw-p--a-R-c--s:------:allow
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> -r--rwxrw-
 
 # mv with NFSv4 ACLs.
-$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ rm -f nfs4/xxx
 $ rm -f nfs4/yyy
+$ touch nfs4/xxx
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
 $ mv nfs4/xxx nfs4/yyy
 $ getfacl -nq nfs4/yyy
 >            user:42:--x-----------:------:allow
 >           group:43:-w------------:------:allow
->             owner@:-wxp----------:------:deny
->             owner@:r------A-W-Co-:------:allow
->             group@:--------------:------:deny
->             group@:rwxp----------:------:allow
->          everyone@:--x----A-W-Co-:------:deny
->          everyone@:rw-p--a-R-c--s:------:allow
+>             owner@:--x-----------:------:deny
+>             owner@:rw-p---A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:-wxp---A-W-Co-:------:deny
+>          everyone@:r-----a-R-c--s:------:allow
+$ ls -l nfs4/yyy | cut -d' ' -f1
+> -rw-r--r--+
 
-# mv from NFSv4 to POSIX.1e.
+# mv from NFSv4 to POSIX.1e without any ACLs.
+$ rm -f nfs4/xxx
 $ rm -f posix/xxx
-$ mv nfs4/yyy posix/xxx
-> mv: failed to set acl entries for posix/xxx: Invalid argument
+$ touch nfs4/xxx
+$ chmod 456 nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> -r--r-xrw-
+$ mv nfs4/xxx posix/xxx
 $ ls -l posix/xxx | cut -d' ' -f1
-> -r--rwxrw-
+> -r--r-xrw-
 
-# mv from POSIX.1e to none.
-$ setfacl -m u:42:x,g:43:w posix/xxx
-$ mv posix/xxx none/xxx
+# mv from NFSv4 to none.
+$ rm -f nfs4/xxx
+$ rm -f none/xxx
+$ touch nfs4/xxx
+$ chmod 345 nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> --wxr--r-x
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> --wxr--r-x+
+$ mv nfs4/xxx none/xxx
 > mv: failed to set acl entries for none/xxx: Operation not supported
 $ ls -l none/xxx | cut -d' ' -f1
-> -r--rwxrw-
+> --wxr--r-x
+
+# mv from NFSv4 to POSIX.1e.
+$ rm -f nfs4/xxx
+$ rm -f posix/xxx
+$ touch nfs4/xxx
+$ chmod 345 nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> --wxr--r-x
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> --wxr--r-x+
+$ mv nfs4/xxx posix/xxx
+> mv: failed to set acl entries for posix/xxx: Invalid argument
+$ ls -l posix/xxx | cut -d' ' -f1
+> --wxr--r-x
 
 # cp with POSIX.1e ACLs.
 $ rm -f posix/xxx
+$ rm -f posix/yyy
+$ touch posix/xxx
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ ls -l posix/xxx | cut -d' ' -f1
+> -rw-rwxr--+
+$ cp posix/xxx posix/yyy
+$ ls -l posix/yyy | cut -d' ' -f1
+> -rw-r-xr--
+
+# cp -p with POSIX.1e ACLs.
+$ rm -f posix/xxx
+$ rm -f posix/yyy
 $ touch posix/xxx
 $ setfacl -m u:42:x,g:43:w posix/xxx
 $ getfacl -nq posix/xxx
@@ -127,15 +190,8 @@ $ getfacl -nq posix/xxx
 > group:43:-w-
 > mask::rwx
 > other::r--
-
-$ rm -f posix/yyy
-$ cp posix/xxx posix/yyy
-$ getfacl -nq posix/yyy
-> user::rw-
-> group::r-x
-> other::r--
-
-$ rm -f posix/yyy
+$ ls -l posix/xxx | cut -d' ' -f1
+> -rw-rwxr--+
 $ cp -p posix/xxx posix/yyy
 $ getfacl -nq posix/yyy
 > user::rw-
@@ -144,35 +200,132 @@ $ getfacl -nq posix/yyy
 > group:43:-w-
 > mask::rwx
 > other::r--
+$ ls -l posix/yyy | cut -d' ' -f1
+> -rw-rwxr--+
 
-# mv from POSIX.1e to NFSv4.
+# cp from POSIX.1e to none.
+$ rm -f posix/xxx
+$ rm -f none/xxx
+$ touch posix/xxx
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ ls -l posix/xxx | cut -d' ' -f1
+> -rw-rwxr--+
+$ cp posix/xxx none/xxx
+$ ls -l none/xxx | cut -d' ' -f1
+> -rw-r-xr--
+
+# cp -p from POSIX.1e to none.
+$ rm -f posix/xxx
+$ rm -f none/xxx
+$ touch posix/xxx
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ ls -l posix/xxx | cut -d' ' -f1
+> -rw-rwxr--+
+$ cp -p posix/xxx none/xxx
+> cp: failed to set acl entries for none/xxx: Operation not supported
+$ ls -l none/xxx | cut -d' ' -f1
+> -rw-rwxr--
+
+# cp from POSIX.1e to NFSv4.
+$ rm -f posix/xxx
 $ rm -f nfs4/xxx
+$ touch posix/xxx
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ ls -l posix/xxx | cut -d' ' -f1
+> -rw-rwxr--+
+$ cp posix/xxx nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> -rw-r-xr--
+
+# cp -p from POSIX.1e to NFSv4.
+$ rm -f posix/xxx
+$ rm -f nfs4/xxx
+$ touch posix/xxx
+$ setfacl -m u:42:x,g:43:w posix/xxx
+$ ls -l posix/xxx | cut -d' ' -f1
+> -rw-rwxr--+
 $ cp -p posix/xxx nfs4/xxx
 > cp: failed to set acl entries for nfs4/xxx: Invalid argument
 $ ls -l nfs4/xxx | cut -d' ' -f1
 > -rw-rwxr--
 
 # cp with NFSv4 ACLs.
-$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ rm -f nfs4/xxx
 $ rm -f nfs4/yyy
+$ touch nfs4/xxx
+$ chmod 543 nfs4/xxx
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> -r-xr---wx+
+$ cp nfs4/xxx nfs4/yyy
+$ ls -l nfs4/yyy | cut -d' ' -f1
+> -r-xr----x
+
+# cp -p with NFSv4 ACLs.
+$ rm -f nfs4/xxx
+$ rm -f nfs4/yyy
+$ touch nfs4/xxx
+$ chmod 543 nfs4/xxx
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
 $ cp -p nfs4/xxx nfs4/yyy
 $ getfacl -nq nfs4/yyy
 >            user:42:--x-----------:------:allow
 >           group:43:-w------------:------:allow
->             owner@:--x-----------:------:deny
->             owner@:rw-p---A-W-Co-:------:allow
->             group@:--------------:------:deny
->             group@:rwxp----------:------:allow
->          everyone@:-wxp---A-W-Co-:------:deny
->          everyone@:r-----a-R-c--s:------:allow
+>             owner@:-w-p----------:------:deny
+>             owner@:r-x----A-W-Co-:------:allow
+>             group@:-wxp----------:------:deny
+>             group@:r-------------:------:allow
+>          everyone@:r------A-W-Co-:------:deny
+>          everyone@:-wxp--a-R-c--s:------:allow
+$ ls -l nfs4/yyy | cut -d' ' -f1
+> -r-xr---wx+
+
+# cp from NFSv4 to none.
+$ rm -f nfs4/xxx
+$ rm -f none/xxx
+$ touch nfs4/xxx
+$ chmod 543 nfs4/xxx
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> -r-xr---wx+
+$ cp nfs4/xxx none/xxx
+$ ls -l none/xxx | cut -d' ' -f1
+> -r-xr----x
+
+# cp -p from NFSv4 to none.
+$ rm -f nfs4/xxx
+$ rm -f none/xxx
+$ touch nfs4/xxx
+$ chmod 543 nfs4/xxx
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> -r-xr---wx+
+$ cp -p nfs4/xxx none/xxx
+> cp: failed to set acl entries for none/xxx: Operation not supported
+$ ls -l none/xxx | cut -d' ' -f1
+> -r-xr---wx
 
 # cp from NFSv4 to POSIX.1e.
+$ rm -f nfs4/xxx
 $ rm -f posix/xxx
+$ touch nfs4/xxx
+$ chmod 543 nfs4/xxx
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> -r-xr---wx+
+$ cp nfs4/xxx posix/xxx
+$ ls -l posix/xxx | cut -d' ' -f1
+> -r-xr----x
+
+# cp -p from NFSv4 to POSIX.1e.
+$ rm -f nfs4/xxx
+$ rm -f posix/xxx
+$ touch nfs4/xxx
+$ chmod 543 nfs4/xxx
+$ setfacl -a0 u:42:x:allow,g:43:w:allow nfs4/xxx
+$ ls -l nfs4/xxx | cut -d' ' -f1
+> -r-xr---wx+
 $ cp -p nfs4/xxx posix/xxx
 > cp: failed to set acl entries for posix/xxx: Invalid argument
 $ ls -l posix/xxx | cut -d' ' -f1
-> -rw-rwxr--
-
-$ cp -p nfs4/yyy none/xxx
-> cp: failed to set acl entries for none/xxx: Operation not supported
-
+> -r-xr---wx

From 3ddba6330c62a1d0d0c134a9aa17d0d059f46f7b Mon Sep 17 00:00:00 2001
From: Shteryana Shopova 
Date: Sun, 31 Jan 2010 11:30:28 +0000
Subject: [PATCH 1338/2592] MFC r202935: While flushing the multicast filter of
 an interface, do not zero the relevant ifmultiaddr structures' reference to
 the parent interface, unless the parent interface is really detaching. While
 here, program only link layer multicast filters to a wlan's hardware parent
 interface.

PR:		kern/142391, kern/142392
Reviewed by:	sam, rpaulo, bms
---
 sys/net/if.c                   | 21 +++++++++++++++++++--
 sys/net/if_var.h               |  2 +-
 sys/net80211/ieee80211_ioctl.c |  7 +++++--
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/sys/net/if.c b/sys/net/if.c
index fe0a304f927..17240611f36 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -773,9 +773,10 @@ if_purgeaddrs(struct ifnet *ifp)
 }
 
 /*
- * Remove any multicast network addresses from an interface.
+ * Remove any multicast network addresses from an interface when an ifnet
+ * is going away.
  */
-void
+static void
 if_purgemaddrs(struct ifnet *ifp)
 {
 	struct ifmultiaddr *ifma;
@@ -3004,6 +3005,22 @@ if_delmulti(struct ifnet *ifp, struct sockaddr *sa)
 	return (0);
 }
 
+/*
+ * Delete all multicast group membership for an interface.
+ * Should be used to quickly flush all multicast filters.
+ */
+void
+if_delallmulti(struct ifnet *ifp)
+{
+	struct ifmultiaddr *ifma;
+	struct ifmultiaddr *next;
+
+	IF_ADDR_LOCK(ifp);
+	TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next)
+		if_delmulti_locked(ifp, ifma, 0);
+	IF_ADDR_UNLOCK(ifp);
+}
+
 /*
  * Delete a multicast group membership by group membership pointer.
  * Network-layer protocol domains must use this routine.
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 58e2837ff25..eac7dbf9783 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -832,7 +832,7 @@ void	if_delmulti_ifma(struct ifmultiaddr *);
 void	if_detach(struct ifnet *);
 void	if_vmove(struct ifnet *, struct vnet *);
 void	if_purgeaddrs(struct ifnet *);
-void	if_purgemaddrs(struct ifnet *);
+void	if_delallmulti(struct ifnet *);
 void	if_down(struct ifnet *);
 struct ifmultiaddr *
 	if_findmulti(struct ifnet *, struct sockaddr *);
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 35c79819bdf..237e556f30c 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -3199,15 +3199,18 @@ ieee80211_ioctl_updatemulti(struct ieee80211com *ic)
 	void *ioctl;
 
 	IEEE80211_LOCK(ic);
-	if_purgemaddrs(parent);
+	if_delallmulti(parent);
 	ioctl = parent->if_ioctl;	/* XXX WAR if_allmulti */
 	parent->if_ioctl = NULL;
 	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 		struct ifnet *ifp = vap->iv_ifp;
 		struct ifmultiaddr *ifma;
 
-		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
+		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+			if (ifma->ifma_addr->sa_family != AF_LINK)
+				continue;
 			(void) if_addmulti(parent, ifma->ifma_addr, NULL);
+		}
 	}
 	parent->if_ioctl = ioctl;
 	ieee80211_runtask(ic, &ic->ic_mcast_task);

From 8abe3cc36b1392cdcc0b3b9bb97819c89c6e47c3 Mon Sep 17 00:00:00 2001
From: Jaakko Heinonen 
Date: Sun, 31 Jan 2010 15:07:38 +0000
Subject: [PATCH 1339/2592] MFC r202944:

Print full path in the error message. It's possible that fts(3)
provides an empty fts_name and reporting the full path is more
appropriate especially with the -R option.

PR:		bin/107515
Approved by:	trasz (mentor)
---
 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..4ad01f4d4a9 100644
--- a/bin/ls/ls.c
+++ b/bin/ls/ls.c
@@ -508,7 +508,7 @@ traverse(int argc, char *argv[], int options)
 			break;
 		case FTS_DNR:
 		case FTS_ERR:
-			warnx("%s: %s", p->fts_name, strerror(p->fts_errno));
+			warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
 			rval = 1;
 			break;
 		case FTS_D:

From 6c8d1299a2098b1fb4f83abd4020aed03ee49962 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Sun, 31 Jan 2010 17:17:24 +0000
Subject: [PATCH 1340/2592] MFC: r203094

- Zero the MSI/MSI-X queue argument, otherwise mtx_init(9) can panic
  indicating an already initialized lock.
- Check for an empty MSI/MSI-X queue entry before asserting that we have
  received a MSI/MSI-X message in order to not panic in case of stray MSI/
  MSI-X queue interrupts which may happen in case of using an interrupt
  handler rather than a filter.
---
 sys/sparc64/pci/fire.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/sparc64/pci/fire.c b/sys/sparc64/pci/fire.c
index f8a18c1fe18..4a3b0604b5b 100644
--- a/sys/sparc64/pci/fire.c
+++ b/sys/sparc64/pci/fire.c
@@ -852,7 +852,7 @@ fire_intr_register(struct fire_softc *sc, u_int ino)
 		return (ENXIO);
 	fica = malloc((ino >= FO_EQ_FIRST_INO && ino <= FO_EQ_LAST_INO) ?
 	    sizeof(struct fire_msiqarg) : sizeof(struct fire_icarg), M_DEVBUF,
-	    M_NOWAIT);
+	    M_NOWAIT | M_ZERO);
 	if (fica == NULL)
 		return (ENOMEM);
 	fica->fica_sc = sc;
@@ -1838,13 +1838,13 @@ fire_msiq_common(struct intr_vector *iv, struct fire_msiqarg *fmqa)
 	qrec = &fmqa->fmqa_base[head];
 	word0 = qrec->fomqr_word0;
 	for (;;) {
+		if (__predict_false((word0 & FO_MQR_WORD0_FMT_TYPE_MASK) == 0))
+			break;
 		KASSERT((word0 & FO_MQR_WORD0_FMT_TYPE_MSI64) != 0 ||
 		    (word0 & FO_MQR_WORD0_FMT_TYPE_MSI32) != 0,
 		    ("%s: received non-MSI/MSI-X message in event queue %d "
 		    "(word0 %#llx)", device_get_nameunit(dev), msiq,
 		    (unsigned long long)word0));
-		if (__predict_false((word0 & FO_MQR_WORD0_FMT_TYPE_MASK) == 0))
-			break;
 		msi = (word0 & FO_MQR_WORD0_DATA0_MASK) >>
 		    FO_MQR_WORD0_DATA0_SHFT;
 		/*

From 36a153df8baf60a7397eb354f12bb1d582190ab8 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Sun, 31 Jan 2010 17:43:22 +0000
Subject: [PATCH 1341/2592] MFC: r202903

On LP64 struct ifid is 64-bit aligned while struct fid is 32-bit aligned
so on architectures with strict alignment requirements we can't just simply
cast the latter to the former but need to copy it bytewise instead.

PR:		143010
---
 sys/fs/cd9660/cd9660_vfsops.c |  8 +++++---
 sys/fs/cd9660/cd9660_vnops.c  | 19 ++++++++++++-------
 2 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c
index b4c65e10929..e27daf8bb04 100644
--- a/sys/fs/cd9660/cd9660_vfsops.c
+++ b/sys/fs/cd9660/cd9660_vfsops.c
@@ -589,17 +589,19 @@ cd9660_fhtovp(mp, fhp, vpp)
 	struct fid *fhp;
 	struct vnode **vpp;
 {
-	struct ifid *ifhp = (struct ifid *)fhp;
+	struct ifid ifh;
 	struct iso_node *ip;
 	struct vnode *nvp;
 	int error;
 
+	memcpy(&ifh, fhp, sizeof(ifh));
+
 #ifdef	ISOFS_DBG
 	printf("fhtovp: ino %d, start %ld\n",
-	       ifhp->ifid_ino, ifhp->ifid_start);
+	    ifh.ifid_ino, ifh.ifid_start);
 #endif
 
-	if ((error = VFS_VGET(mp, ifhp->ifid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
+	if ((error = VFS_VGET(mp, ifh.ifid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
 		*vpp = NULLVP;
 		return (error);
 	}
diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c
index 55ea46b57e3..5f4780f936b 100644
--- a/sys/fs/cd9660/cd9660_vnops.c
+++ b/sys/fs/cd9660/cd9660_vnops.c
@@ -819,20 +819,25 @@ cd9660_vptofh(ap)
 		struct fid *a_fhp;
 	} */ *ap;
 {
+	struct ifid ifh;
 	struct iso_node *ip = VTOI(ap->a_vp);
-	struct ifid *ifhp;
 
-	ifhp = (struct ifid *)ap->a_fhp;
-	ifhp->ifid_len = sizeof(struct ifid);
+	ifh.ifid_len = sizeof(struct ifid);
 
-	ifhp->ifid_ino = ip->i_number;
-	ifhp->ifid_start = ip->iso_start;
+	ifh.ifid_ino = ip->i_number;
+	ifh.ifid_start = ip->iso_start;
+	/*
+	 * This intentionally uses sizeof(ifh) in order to not copy stack
+	 * garbage on ILP32.
+	 */
+	memcpy(ap->a_fhp, &ifh, sizeof(ifh));
 
 #ifdef	ISOFS_DBG
 	printf("vptofh: ino %d, start %ld\n",
-	       ifhp->ifid_ino,ifhp->ifid_start);
+	    ifh.ifid_ino, ifh.ifid_start);
 #endif
-	return 0;
+
+	return (0);
 }
 
 /*

From 661f092a6d705338595591683d6e3b81312709ce Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sun, 31 Jan 2010 18:25:57 +0000
Subject: [PATCH 1342/2592] MFC r202881: Staticise sigqueue manipulation
 functions used only in kern_sig.c.

---
 sys/kern/kern_sig.c | 16 ++++++++--------
 sys/sys/signalvar.h | 10 +---------
 2 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 62a15364a72..4b7ba349420 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -275,7 +275,7 @@ sigqueue_init(sigqueue_t *list, struct proc *p)
  * 	0	-	signal not found
  *	others	-	signal number
  */ 
-int
+static int
 sigqueue_get(sigqueue_t *sq, int signo, ksiginfo_t *si)
 {
 	struct proc *p = sq->sq_proc;
@@ -337,7 +337,7 @@ sigqueue_take(ksiginfo_t *ksi)
 		SIGDELSET(sq->sq_signals, ksi->ksi_signo);
 }
 
-int
+static int
 sigqueue_add(sigqueue_t *sq, int signo, ksiginfo_t *si)
 {
 	struct proc *p = sq->sq_proc;
@@ -422,7 +422,7 @@ sigqueue_flush(sigqueue_t *sq)
 	SIGEMPTYSET(sq->sq_kill);
 }
 
-void
+static void
 sigqueue_collect_set(sigqueue_t *sq, sigset_t *set)
 {
 	ksiginfo_t *ksi;
@@ -434,7 +434,7 @@ sigqueue_collect_set(sigqueue_t *sq, sigset_t *set)
 	SIGSETOR(*set, sq->sq_kill);
 }
 
-void
+static void
 sigqueue_move_set(sigqueue_t *src, sigqueue_t *dst, sigset_t *setp)
 {
 	sigset_t tmp, set;
@@ -478,7 +478,7 @@ sigqueue_move_set(sigqueue_t *src, sigqueue_t *dst, sigset_t *setp)
 	sigqueue_collect_set(src, &src->sq_signals);
 }
 
-void
+static void
 sigqueue_move(sigqueue_t *src, sigqueue_t *dst, int signo)
 {
 	sigset_t set;
@@ -488,7 +488,7 @@ sigqueue_move(sigqueue_t *src, sigqueue_t *dst, int signo)
 	sigqueue_move_set(src, dst, &set);
 }
 
-void
+static void
 sigqueue_delete_set(sigqueue_t *sq, sigset_t *set)
 {
 	struct proc *p = sq->sq_proc;
@@ -522,7 +522,7 @@ sigqueue_delete(sigqueue_t *sq, int signo)
 }
 
 /* Remove a set of signals for a process */
-void
+static void
 sigqueue_delete_set_proc(struct proc *p, sigset_t *set)
 {
 	sigqueue_t worklist;
@@ -549,7 +549,7 @@ sigqueue_delete_proc(struct proc *p, int signo)
 	sigqueue_delete_set_proc(p, &set);
 }
 
-void
+static void
 sigqueue_delete_stopmask_proc(struct proc *p)
 {
 	sigset_t set;
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index 267c59d94e7..f5d8f8a3e19 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -355,18 +355,10 @@ void	ksiginfo_free(ksiginfo_t *);
 void	sigqueue_init(struct sigqueue *queue, struct proc *p);
 void	sigqueue_flush(struct sigqueue *queue);
 void	sigqueue_delete_proc(struct proc *p, int sig);
-void	sigqueue_delete_set(struct sigqueue *queue, sigset_t *set);
 void	sigqueue_delete(struct sigqueue *queue, int sig);
-void	sigqueue_move_set(struct sigqueue *src, sigqueue_t *dst, sigset_t *);
-int	sigqueue_get(struct sigqueue *queue, int sig, ksiginfo_t *info);
-int	sigqueue_add(struct sigqueue *queue, int sig, ksiginfo_t *info);
-void	sigqueue_collect_set(struct sigqueue *queue, sigset_t *set);
-void	sigqueue_move(struct sigqueue *, struct sigqueue *, int sig);
-void	sigqueue_delete_set_proc(struct proc *, sigset_t *);
-void	sigqueue_delete_stopmask_proc(struct proc *);
 void	sigqueue_take(ksiginfo_t *ksi);
 int	kern_sigtimedwait(struct thread *, sigset_t,
-		ksiginfo_t *, struct timespec *);
+	    ksiginfo_t *, struct timespec *);
 int	kern_sigprocmask(struct thread *td, int how,
 	    sigset_t *set, sigset_t *oset, int flags);
 /*

From f2d58a1d9bb8d72b8aa4db0610ac53371ca4f5af Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sun, 31 Jan 2010 18:38:03 +0000
Subject: [PATCH 1343/2592] MFC r199827: Implement sighold, sigignore,
 sigpause, sigrelse, sigset functions.

MFC r200881 (by cognet):
Don't name parameters.
---
 include/signal.h                |   5 +
 lib/libc/compat-43/Makefile.inc |   5 +
 lib/libc/compat-43/Symbol.map   |   8 ++
 lib/libc/compat-43/sigcompat.c  |  85 ++++++++++++++++-
 lib/libc/compat-43/sigpause.2   | 160 ++++++++++++++++++++++++++++++--
 sys/sys/signal.h                |   5 +-
 sys/sys/signalvar.h             |   2 +-
 7 files changed, 258 insertions(+), 12 deletions(-)

diff --git a/include/signal.h b/include/signal.h
index fdb4b3ed6d0..13742c6c631 100644
--- a/include/signal.h
+++ b/include/signal.h
@@ -99,7 +99,12 @@ int	sigwaitinfo(const sigset_t * __restrict, siginfo_t * __restrict);
 #if __XSI_VISIBLE
 int	killpg(__pid_t, int);
 int	sigaltstack(const stack_t * __restrict, stack_t * __restrict); 
+int	sighold(int);
+int	sigignore(int);
 int	sigpause(int);
+int	sigrelse(int);
+void	(*sigset(int, void (*)(int)))(int);
+int	xsi_sigpause(int);
 #endif
 
 #if __XSI_VISIBLE >= 600
diff --git a/lib/libc/compat-43/Makefile.inc b/lib/libc/compat-43/Makefile.inc
index 836f0a60ca5..8505ff22787 100644
--- a/lib/libc/compat-43/Makefile.inc
+++ b/lib/libc/compat-43/Makefile.inc
@@ -13,6 +13,11 @@ MAN+=	creat.2 killpg.2 sigpause.2 sigsetmask.2 sigvec.2
 MAN+=	gethostid.3 setruid.3
 
 MLINKS+=gethostid.3 sethostid.3
+MLINKS+=sigpause.2 sighold.2
+MLINKS+=sigpause.2 sigignore.2
+MLINKS+=sigpause.2 sigrelse.2
+MLINKS+=sigpause.2 sigset.2
+MLINKS+=sigpause.2 xsi_sigpause.2
 MLINKS+=setruid.3 setrgid.3
 
 MLINKS+=sigsetmask.2 sigblock.2
diff --git a/lib/libc/compat-43/Symbol.map b/lib/libc/compat-43/Symbol.map
index e859a310cb0..bd49f99e2df 100644
--- a/lib/libc/compat-43/Symbol.map
+++ b/lib/libc/compat-43/Symbol.map
@@ -17,6 +17,14 @@ FBSD_1.0 {
 	sigvec;
 };
 
+FBSD_1.2 {
+	sighold;
+	sigignore;
+	sigrelse;
+	sigset;
+	xsi_sigpause;
+};
+
 FBSDprivate_1.0 {
 	__creat;
 	_creat;
diff --git a/lib/libc/compat-43/sigcompat.c b/lib/libc/compat-43/sigcompat.c
index 6280183238f..c3ba30a41f4 100644
--- a/lib/libc/compat-43/sigcompat.c
+++ b/lib/libc/compat-43/sigcompat.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include "namespace.h"
 #include 
 #include 
+#include 
 #include "un-namespace.h"
 #include "libc_private.h"
 
@@ -97,8 +98,7 @@ sigblock(mask)
 }
 
 int
-sigpause(mask)
-	int mask;
+sigpause(int mask)
 {
 	sigset_t set;
 
@@ -106,3 +106,84 @@ sigpause(mask)
 	set.__bits[0] = mask;
 	return (_sigsuspend(&set));
 }
+
+int
+xsi_sigpause(int sig)
+{
+	sigset_t set;
+
+	sigemptyset(&set);
+	sigaddset(&set, sig);
+	return (_sigsuspend(&set));
+}
+
+int
+sighold(int sig)
+{
+	sigset_t set;
+
+	sigemptyset(&set);
+	sigaddset(&set, sig);
+	return (_sigprocmask(SIG_BLOCK, &set, NULL));
+}
+
+int
+sigignore(int sig)
+{
+	struct sigaction sa;
+
+	bzero(&sa, sizeof(sa));
+	sa.sa_handler = SIG_IGN;
+	return (_sigaction(sig, &sa, NULL));
+}
+
+int
+sigrelse(int sig)
+{
+	sigset_t set;
+
+	sigemptyset(&set);
+	sigaddset(&set, sig);
+	return (_sigprocmask(SIG_UNBLOCK, &set, NULL));
+}
+
+void
+(*sigset(int sig, void (*disp)(int)))(int)
+{
+	sigset_t set, pset;
+	struct sigaction sa, psa;
+	int error;
+
+	sigemptyset(&set);
+	sigaddset(&set, sig);
+	error = _sigprocmask(SIG_BLOCK, NULL, &pset);
+	if (error == -1)
+		return (SIG_ERR);
+	if ((__sighandler_t *)disp == SIG_HOLD) {
+		error = _sigprocmask(SIG_BLOCK, &set, &pset);
+		if (error == -1)
+			return (SIG_ERR);
+		if (sigismember(&pset, sig))
+			return (SIG_HOLD);
+		else {
+			error = _sigaction(sig, NULL, &psa);
+			if (error == -1)
+				return (SIG_ERR);
+			return (psa.sa_handler);
+		}
+	} else {
+		error = _sigprocmask(SIG_UNBLOCK, &set, &pset);
+		if (error == -1)
+			return (SIG_ERR);
+	}
+
+	bzero(&sa, sizeof(sa));
+	sa.sa_handler = disp;
+	error = _sigaction(sig, &sa, &psa);
+	if (error == -1)
+		return (SIG_ERR);
+	if (sigismember(&pset, sig))
+		return (SIG_HOLD);
+	else
+		return (psa.sa_handler);
+}
diff --git a/lib/libc/compat-43/sigpause.2 b/lib/libc/compat-43/sigpause.2
index 39edb0b5c18..bf3cf0bef8f 100644
--- a/lib/libc/compat-43/sigpause.2
+++ b/lib/libc/compat-43/sigpause.2
@@ -28,21 +28,118 @@
 .\"     @(#)sigpause.2	8.1 (Berkeley) 6/2/93
 .\" $FreeBSD$
 .\"
+.\" Part of the content of the man page was derived from
+.\" The Open Group Base Specifications Issue 7
+.\" IEEE Std 1003.1-2008
+.\"
 .Dd June 2, 1993
 .Dt SIGPAUSE 2
 .Os
 .Sh NAME
-.Nm sigpause
-.Nd atomically release blocked signals and wait for interrupt
+.Nm sighold ,
+.Nm sigignore ,
+.Nm sigpause ,
+.Nm sigrelse ,
+.Nm sigset
+.Nd legacy interface for signal management
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .In signal.h
 .Ft int
+.Fn sighold "int sig"
+.Ft int
+.Fn sigignore "int sig"
+.Ft int
+.Fn xsi_sigpause "int sigmask"
+.Ft int
+.Fn sigrelse "int sig"
+.Ft void (*)(int)
+.Fn sigset "int" "void (*disp)(int)"
+.Ft int
 .Fn sigpause "int sigmask"
 .Sh DESCRIPTION
 .Sy This interface is made obsolete by
-.Xr sigsuspend 2 .
+.Xr sigsuspend 2
+.Sy and
+.Xr sigaction 2
+.Pp
+The
+.Fn sigset
+function modifies signal dispositions.
+The
+.Fa sig
+argument specifies the signal, which may be any signal except
+.Dv SIGKILL
+and
+.Dv SIGSTOP .
+The
+.Fa disp
+argument specifies the signal's disposition,
+which may be
+.Dv SIG_DFL ,
+.Dv SIG_IGN ,
+or the address of a signal handler.
+If
+.Fn sigset
+is used, and
+.Fa disp
+is the address of a signal handler, the
+system adds
+.Fa sig
+to the signal mask of the calling process before executing the signal
+handler; when the signal handler returns, the system restores the
+signal mask of the calling process to its state prior to the delivery
+of the signal.
+In addition, if
+.Fn sigset
+is used, and
+.Fa disp
+is equal to
+.Dv SIG_HOLD ,
+.Fa sig
+is added to the signal
+mask of the calling process and
+.Fa sig 's
+disposition remains unchanged.
+If
+.Fn sigset
+is used, and
+.Fa disp
+is not equal to
+.Dv SIG_HOLD ,
+.Fa sig
+is removed from the signal mask of the calling process.
+.Pp
+The
+.Fn sighold
+function adds
+.Fa sig
+to the signal mask of the calling process.
+.Pp
+The
+.Fn sigrelse
+function removes
+.Fa sig
+from the signal mask of the calling process.
+.Pp
+The
+.Fn sigignore
+function sets the disposition of
+.Fa sig
+to
+.Dv SIG_IGN .
+.Pp
+The
+.Fn xsi_sigpause
+function removes
+.Fa sig
+from the signal mask of the calling process and suspend the calling process
+until a signal is received.
+The
+.Fn xsi_sigpause
+function restores the signal mask of the process to its original state before
+returning.
 .Pp
 The
 .Fn sigpause
@@ -57,13 +154,47 @@ The
 argument
 is usually 0 to indicate that no
 signals are to be blocked.
+.Sh RETURN VALUES
 The
 .Fn sigpause
-function
-always terminates by being interrupted, returning -1 with
+and
+.Fn xsi_sigpause
+functions
+always terminate by being interrupted, returning -1 with
 .Va errno
 set to
-.Er EINTR
+.Er EINTR .
+.Pp
+Upon successful completion,
+.Fn sigset
+returns
+.Dv SIG_HOLD
+if the signal had been blocked and the signal's previous disposition if
+it had not been blocked.
+Otherwise,
+.Dv SIG_ERR is returned and
+.Va errno
+set to indicate the error.
+.Pp
+For all other functions, upon successful completion, 0 is returned.
+Otherwise, -1 is returned and
+.Va errno
+is set to indicate the error:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa sig
+argument
+is not a valid signal number.
+.It Bq Er EINVAL
+For
+.Fn sigset
+and
+.Fn sigignore
+functions, an attempt was made to catch or ignore
+.Dv SIGKILL
+or
+.Dv SIGSTOP .
 .Sh SEE ALSO
 .Xr kill 2 ,
 .Xr sigaction 2 ,
@@ -85,9 +216,26 @@ and was copied from there into the
 .Pq Tn XSI
 option of
 .St -p1003.1-2001 .
+.Fx
+implements it under the name
+.Fn xsi_sigpause .
+The
+.Fn sighold ,
+.Fn sigignore ,
+.Fn sigrelse
+and
+.Fn sigset
+functions are implemented for compatibility with
+.Sy System V
+and
+.Sy XSI
+interfaces.
 .Sh HISTORY
 The
 .Fn sigpause
 function appeared in
 .Bx 4.2
 and has been deprecated.
+All other functions appeared in
+.Fx 9.0
+and were deprecated before being implemented.
diff --git a/sys/sys/signal.h b/sys/sys/signal.h
index 81d45a9cc42..ff2d1fcbed2 100644
--- a/sys/sys/signal.h
+++ b/sys/sys/signal.h
@@ -119,9 +119,8 @@
 #define	SIG_DFL		((__sighandler_t *)0)
 #define	SIG_IGN		((__sighandler_t *)1)
 #define	SIG_ERR		((__sighandler_t *)-1)
-/*
- * XXX missing SIG_HOLD.
- */
+/* #define	SIG_CATCH	((__sighandler_t *)2) See signalvar.h */
+#define SIG_HOLD        ((__sighandler_t *)3)
 
 /*-
  * Type of a signal handling function.
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index f5d8f8a3e19..552a8351723 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -97,7 +97,7 @@ typedef void __osiginfohandler_t(int, osiginfo_t *, void *);
 
 /* additional signal action values, used only temporarily/internally */
 #define	SIG_CATCH	((__sighandler_t *)2)
-#define SIG_HOLD        ((__sighandler_t *)3)
+/* #define SIG_HOLD        ((__sighandler_t *)3) See signal.h */
 
 /*
  * get signal action for process and signal; currently only for current process

From 613bd3f32b4d03cf8dd36fb421ad274c8bac0f90 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Sun, 31 Jan 2010 18:41:00 +0000
Subject: [PATCH 1344/2592] Bump __FreeBSD_version for sigpause(3) addition.

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

diff --git a/sys/sys/param.h b/sys/sys/param.h
index f52eee618c2..2776d063f28 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 800501	/* Master, propagated to newvers */
+#define __FreeBSD_version 800502	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include 

From 95697f42122df6dea657de82f5d96f9a36e03560 Mon Sep 17 00:00:00 2001
From: Gregory Neil Shapiro 
Date: Sun, 31 Jan 2010 18:59:03 +0000
Subject: [PATCH 1345/2592] MFC: Merge sendmail 8.14.4

---
 contrib/sendmail/CACerts                      | 205 ++++++------------
 contrib/sendmail/LICENSE                      |   6 +-
 contrib/sendmail/PGPKEYS                      |  75 ++++++-
 contrib/sendmail/README                       |   3 +-
 contrib/sendmail/RELEASE_NOTES                |  89 +++++++-
 contrib/sendmail/cf/README                    |   4 +-
 contrib/sendmail/cf/cf/submit.cf              |  14 +-
 contrib/sendmail/cf/feature/ldap_routing.m4   |  36 ++-
 contrib/sendmail/cf/m4/cfhead.m4              |   6 +-
 contrib/sendmail/cf/m4/proto.m4               |  17 +-
 contrib/sendmail/cf/m4/version.m4             |   6 +-
 contrib/sendmail/contrib/qtool.pl             |   8 +-
 contrib/sendmail/contrib/smcontrol.pl         |   4 +-
 contrib/sendmail/doc/op/op.me                 |  42 +++-
 contrib/sendmail/include/libmilter/mfapi.h    |  13 +-
 contrib/sendmail/include/libmilter/mfdef.h    |  18 +-
 contrib/sendmail/include/sm/conf.h            |  23 +-
 contrib/sendmail/include/sm/ldap.h            |   4 +-
 contrib/sendmail/include/sm/sem.h             |   5 +-
 contrib/sendmail/libmilter/Makefile.m4        |   2 +-
 contrib/sendmail/libmilter/comm.c             |  17 +-
 contrib/sendmail/libmilter/docs/api.html      |   8 +-
 contrib/sendmail/libmilter/docs/overview.html |   6 +-
 .../libmilter/docs/smfi_addheader.html        |  10 +-
 .../libmilter/docs/smfi_chgheader.html        |   9 +-
 .../libmilter/docs/smfi_insheader.html        |   9 +-
 contrib/sendmail/libmilter/engine.c           | 143 +++++++++++-
 contrib/sendmail/libmilter/example.c          |   4 +-
 contrib/sendmail/libmilter/handler.c          |  21 +-
 contrib/sendmail/libmilter/libmilter.h        |   3 +-
 contrib/sendmail/libmilter/listener.c         |   7 +-
 contrib/sendmail/libmilter/main.c             |   2 +-
 contrib/sendmail/libmilter/worker.c           |  47 ++--
 contrib/sendmail/libsm/debug.c                |  31 ++-
 contrib/sendmail/libsm/ldap.c                 |  33 ++-
 contrib/sendmail/libsm/mbdb.c                 |  19 +-
 contrib/sendmail/libsm/sem.c                  |  46 +++-
 contrib/sendmail/libsm/t-sem.c                |  70 +++++-
 contrib/sendmail/libsmdb/smdb1.c              |  25 ++-
 contrib/sendmail/libsmdb/smdb2.c              |  13 +-
 contrib/sendmail/libsmutil/safefile.c         |   3 +-
 contrib/sendmail/praliases/praliases.8        |  10 +-
 contrib/sendmail/praliases/praliases.c        |   7 +-
 contrib/sendmail/src/Makefile.m4              |   2 +-
 contrib/sendmail/src/README                   |   5 +-
 contrib/sendmail/src/TRACEFLAGS               |   3 +-
 contrib/sendmail/src/collect.c                |   5 +-
 contrib/sendmail/src/conf.c                   |  62 +++++-
 contrib/sendmail/src/conf.h                   |  15 +-
 contrib/sendmail/src/daemon.c                 |  11 +-
 contrib/sendmail/src/deliver.c                |  37 ++--
 contrib/sendmail/src/envelope.c               |  18 +-
 contrib/sendmail/src/headers.c                |  17 +-
 contrib/sendmail/src/main.c                   |  35 ++-
 contrib/sendmail/src/map.c                    |  42 +++-
 contrib/sendmail/src/milter.c                 |  95 ++++++--
 contrib/sendmail/src/queue.c                  |  83 +++++--
 contrib/sendmail/src/ratectrl.c               |  52 +----
 contrib/sendmail/src/readcf.c                 | 165 +++++++++++++-
 contrib/sendmail/src/savemail.c               |   4 +-
 contrib/sendmail/src/sendmail.8               |   6 +-
 contrib/sendmail/src/sendmail.h               |  26 ++-
 contrib/sendmail/src/sfsasl.c                 |   4 +-
 contrib/sendmail/src/srvrsmtp.c               | 105 ++++++---
 contrib/sendmail/src/tls.c                    |  80 +++++--
 contrib/sendmail/src/usersmtp.c               |  13 +-
 contrib/sendmail/src/util.c                   |   8 +-
 contrib/sendmail/src/version.c                |   6 +-
 contrib/sendmail/vacation/vacation.c          |  31 ++-
 69 files changed, 1501 insertions(+), 552 deletions(-)

diff --git a/contrib/sendmail/CACerts b/contrib/sendmail/CACerts
index b74fb7f1917..dee28194ebc 100644
--- a/contrib/sendmail/CACerts
+++ b/contrib/sendmail/CACerts
@@ -1,4 +1,4 @@
-# $Id: CACerts,v 8.3 2007/06/11 22:04:46 ca Exp $
+# $Id: CACerts,v 8.4 2009/06/26 05:46:10 ca Exp $
 # This file contains some CA certificates that are used to sign the
 # certificates of mail servers of members of the sendmail consortium
 # who may reply to questions etc sent to sendmail.org.
@@ -6,73 +6,6 @@
 # a certificate signed by one of these CA certificates.
 #
 
-Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number: 0 (0x0)
-        Signature Algorithm: md5WithRSAEncryption
-        Issuer: C=US, ST=California, L=Berkeley, O=Sendmail Consortium, CN=Certificate Authority/emailAddress=certificates@sendmail.org
-        Validity
-            Not Before: Feb  1 21:51:47 2003 GMT
-            Not After : Jan 31 21:51:47 2008 GMT
-        Subject: C=US, ST=California, L=Berkeley, O=Sendmail Consortium, CN=Certificate Authority/emailAddress=certificates@sendmail.org
-        Subject Public Key Info:
-            Public Key Algorithm: rsaEncryption
-            RSA Public Key: (1024 bit)
-                Modulus (1024 bit):
-                    00:9a:fb:dc:4c:a3:58:21:1b:84:78:0a:53:56:b3:
-                    8d:84:05:b7:db:dd:d7:81:ea:dd:c1:ab:d4:be:d9:
-                    2b:12:e0:6d:3a:31:d5:f0:7b:13:fc:d8:da:09:0b:
-                    71:11:8e:b9:48:c4:ab:ae:f5:9c:4c:e2:04:27:8e:
-                    c8:03:3a:aa:00:8b:46:f2:79:09:ae:65:b2:9a:66:
-                    e7:ac:a9:ea:32:f7:4a:4e:fd:da:41:48:34:5a:9d:
-                    b0:42:ea:55:40:17:27:5e:67:9e:e5:ce:dc:84:6d:
-                    1d:48:37:23:11:68:9d:a8:d4:58:02:05:ea:88:35:
-                    bd:0d:b6:28:d5:cd:d4:d8:95
-                Exponent: 65537 (0x10001)
-        X509v3 extensions:
-            X509v3 Subject Key Identifier: 
-            DE:CD:6E:B8:89:34:06:3D:E9:CD:A7:FE:45:4F:4E:FB:E1:8D:E7:79
-            X509v3 Authority Key Identifier: 
-            keyid:DE:CD:6E:B8:89:34:06:3D:E9:CD:A7:FE:45:4F:4E:FB:E1:8D:E7:79
-            DirName:/C=US/ST=California/L=Berkeley/O=Sendmail Consortium/CN=Certificate Authority/emailAddress=certificates@sendmail.org
-            serial:00
-
-            X509v3 Basic Constraints: 
-            CA:TRUE
-    Signature Algorithm: md5WithRSAEncryption
-        66:92:b9:57:17:3b:6a:0e:72:b1:85:29:53:9f:11:68:a0:0d:
-        79:43:d0:7c:48:73:b9:71:09:50:08:02:03:0b:28:0c:33:9a:
-        00:ac:94:69:4f:bc:0f:45:6b:f5:3a:ca:6a:87:a1:7f:28:f7:
-        9a:c4:b6:b0:f3:dc:a3:eb:42:95:9f:99:19:f8:b8:84:6d:f1:
-        1d:bc:9f:f0:a0:cc:60:2d:00:6b:17:55:33:16:85:d1:73:e1:
-        00:59:89:33:19:c4:2e:29:5a:39:a7:0e:e7:9b:d2:4c:c7:b9:
-        7d:6a:3e:b4:00:83:86:d3:16:28:fd:ad:55:65:60:4e:14:02:
-        46:d3
------BEGIN CERTIFICATE-----
-MIIDsDCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBnTELMAkGA1UEBhMCVVMx
-EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCEJlcmtlbGV5MRwwGgYDVQQK
-ExNTZW5kbWFpbCBDb25zb3J0aXVtMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBBdXRo
-b3JpdHkxKDAmBgkqhkiG9w0BCQEWGWNlcnRpZmljYXRlc0BzZW5kbWFpbC5vcmcw
-HhcNMDMwMjAxMjE1MTQ3WhcNMDgwMTMxMjE1MTQ3WjCBnTELMAkGA1UEBhMCVVMx
-EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCEJlcmtlbGV5MRwwGgYDVQQK
-ExNTZW5kbWFpbCBDb25zb3J0aXVtMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBBdXRo
-b3JpdHkxKDAmBgkqhkiG9w0BCQEWGWNlcnRpZmljYXRlc0BzZW5kbWFpbC5vcmcw
-gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJr73EyjWCEbhHgKU1azjYQFt9vd
-14Hq3cGr1L7ZKxLgbTox1fB7E/zY2gkLcRGOuUjEq671nEziBCeOyAM6qgCLRvJ5
-Ca5lsppm56yp6jL3Sk792kFINFqdsELqVUAXJ15nnuXO3IRtHUg3IxFonajUWAIF
-6og1vQ22KNXN1NiVAgMBAAGjgf0wgfowHQYDVR0OBBYEFN7NbriJNAY96c2n/kVP
-Tvvhjed5MIHKBgNVHSMEgcIwgb+AFN7NbriJNAY96c2n/kVPTvvhjed5oYGjpIGg
-MIGdMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMI
-QmVya2VsZXkxHDAaBgNVBAoTE1NlbmRtYWlsIENvbnNvcnRpdW0xHjAcBgNVBAMT
-FUNlcnRpZmljYXRlIEF1dGhvcml0eTEoMCYGCSqGSIb3DQEJARYZY2VydGlmaWNh
-dGVzQHNlbmRtYWlsLm9yZ4IBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUA
-A4GBAGaSuVcXO2oOcrGFKVOfEWigDXlD0HxIc7lxCVAIAgMLKAwzmgCslGlPvA9F
-a/U6ymqHoX8o95rEtrDz3KPrQpWfmRn4uIRt8R28n/CgzGAtAGsXVTMWhdFz4QBZ
-iTMZxC4pWjmnDueb0kzHuX1qPrQAg4bTFij9rVVlYE4UAkbT
------END CERTIFICATE-----
-
-
 Certificate:
     Data:
         Version: 3 (0x2)
@@ -144,93 +77,93 @@ Certificate:
     Data:
         Version: 3 (0x2)
         Serial Number:
-            fa:7c:2c:80:29:3f:c2:64
+            c2:3c:61:67:3b:0a:cc:5e
         Signature Algorithm: md5WithRSAEncryption
-        Issuer: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2007/emailAddress=ca+ca-rsa2007@esmtp.org
+        Issuer: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2009/emailAddress=ca+ca-rsa2009@esmtp.org
         Validity
-            Not Before: May  4 02:07:56 2007 GMT
-            Not After : May  3 02:07:56 2010 GMT
-        Subject: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2007/emailAddress=ca+ca-rsa2007@esmtp.org
+            Not Before: May 14 04:42:18 2009 GMT
+            Not After : May 13 04:42:18 2012 GMT
+        Subject: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2009/emailAddress=ca+ca-rsa2009@esmtp.org
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
             RSA Public Key: (2048 bit)
                 Modulus (2048 bit):
-                    00:b0:28:91:31:af:82:ce:72:ef:36:ab:7d:e9:b1:
-                    f5:77:66:38:4b:38:1f:5f:3d:12:d3:c8:fd:9a:f4:
-                    d4:f6:b8:90:f9:26:5f:29:f7:43:f9:34:ec:65:62:
-                    01:bb:64:f1:5d:ea:75:04:3d:92:65:60:a2:06:62:
-                    fa:88:ca:d8:20:50:c8:1e:38:53:b5:18:dd:b7:bd:
-                    c7:08:35:4c:d9:dc:c6:97:56:37:b6:65:33:74:5a:
-                    b2:c3:85:08:2b:b7:26:70:ff:38:02:1a:67:6a:d0:
-                    49:18:10:4b:f8:db:af:06:9c:b1:a8:82:a1:b1:75:
-                    d2:52:9b:53:0c:ca:a7:e3:15:38:79:6d:a1:f5:ef:
-                    7c:8b:fd:bd:04:78:f9:e8:1e:b9:92:ea:74:d7:45:
-                    1e:4c:c8:bd:f4:5c:fc:1a:7f:e7:31:c6:ab:cb:78:
-                    c7:4d:2f:b5:72:10:35:27:4a:1a:fa:53:19:f8:a7:
-                    59:63:eb:e9:15:ab:dc:71:69:8c:42:1c:96:4e:89:
-                    80:66:c9:9e:21:d5:3d:08:19:74:a5:f5:07:a0:ae:
-                    de:79:af:fd:42:c2:79:7e:8c:f8:39:22:3b:c3:c4:
-                    58:3b:d0:0d:e6:a9:11:b6:a2:cd:2e:e5:16:66:fd:
-                    7e:65:33:94:b0:36:80:27:f5:80:76:a9:e5:df:f2:
-                    cf:ef
+                    00:d5:f8:d3:48:38:75:df:2e:6b:8b:c4:8d:1d:41:
+                    5e:ad:4b:96:3d:48:c2:dc:e5:ff:61:98:95:32:03:
+                    e9:b6:71:5a:68:31:bc:e1:5c:aa:0e:70:a7:bc:51:
+                    b7:13:6a:78:54:ae:a6:d0:44:49:1b:5e:37:5b:59:
+                    20:01:47:a7:ec:41:4c:11:79:8c:25:c1:1b:c0:ed:
+                    85:b2:de:0f:10:9f:e7:b2:a3:c4:f1:fc:85:51:aa:
+                    d6:68:49:51:3e:04:e1:eb:e9:cd:87:1b:d0:9d:97:
+                    7b:4c:e1:1e:b1:6a:be:01:0a:a9:97:9a:50:89:e3:
+                    66:06:4c:07:cb:7e:99:70:13:e8:b4:9c:e7:e6:52:
+                    38:c0:64:90:42:d0:f5:cf:22:46:22:60:e9:34:70:
+                    1d:e3:d1:13:33:3a:31:ba:13:06:a8:c2:34:90:47:
+                    c5:a1:bd:2d:7d:98:21:70:de:22:d0:13:11:e5:08:
+                    dd:a0:77:0b:df:34:a7:07:55:de:5a:71:f6:6c:9e:
+                    ec:f7:45:75:1f:22:a9:84:06:c6:4f:84:3d:4e:05:
+                    d7:e4:e5:98:41:61:7b:8e:c9:3b:a6:ed:31:80:7d:
+                    fd:fa:f0:dc:b7:07:82:b8:ec:27:20:39:5f:78:95:
+                    f1:0d:93:8d:f9:4d:21:08:fd:72:89:01:ff:2c:a0:
+                    71:9d
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                B2:49:6B:52:45:EE:90:36:D2:79:47:03:33:D9:A0:BA:80:50:DA:1C
+            A7:61:FA:31:AF:A8:E2:5E:93:B6:84:9E:74:08:A2:76:50:87:69:7C
             X509v3 Authority Key Identifier: 
-                keyid:B2:49:6B:52:45:EE:90:36:D2:79:47:03:33:D9:A0:BA:80:50:DA:1C
-                DirName:/C=US/ST=California/L=Berkeley/O=Endmail Org/OU=MTA/CN=Claus Assmann CA RSA 2007/emailAddress=ca+ca-rsa2007@esmtp.org
-                serial:FA:7C:2C:80:29:3F:C2:64
+            keyid:A7:61:FA:31:AF:A8:E2:5E:93:B6:84:9E:74:08:A2:76:50:87:69:7C
+            DirName:/C=US/ST=California/L=Berkeley/O=Endmail Org/OU=MTA/CN=Claus Assmann CA RSA 2009/emailAddress=ca+ca-rsa2009@esmtp.org
+            serial:C2:3C:61:67:3B:0A:CC:5E
 
             X509v3 Basic Constraints: 
-                CA:TRUE
+            CA:TRUE
             X509v3 Subject Alternative Name: 
-                email:ca+ca-rsa2007@esmtp.org
+            email:ca+ca-rsa2009@esmtp.org
             X509v3 Issuer Alternative Name: 
-                email:ca+ca-rsa2007@esmtp.org
+            email:ca+ca-rsa2009@esmtp.org
     Signature Algorithm: md5WithRSAEncryption
-        98:98:7c:d3:d0:5b:72:47:15:e6:22:68:bb:78:0e:78:66:e9:
-        56:16:d8:bc:9d:5a:dc:27:29:fb:91:2d:6a:21:35:18:56:b4:
-        4f:2a:09:c0:08:6f:9a:59:2b:2e:72:9a:fb:50:ba:c7:a9:91:
-        a0:f9:6c:be:cf:78:42:43:02:70:53:97:ba:6a:e3:da:17:e8:
-        1f:c7:3a:5b:e7:bc:eb:e5:24:4c:f5:cf:61:34:1e:20:ed:17:
-        63:ef:81:d3:9e:25:fe:cc:05:19:cc:8a:82:c9:4c:3a:b5:6b:
-        49:51:76:46:02:aa:60:bb:c4:b9:61:48:33:da:79:8d:46:a3:
-        06:20:98:f3:b2:db:3b:ad:c9:1d:0e:97:3d:b7:14:19:d3:7d:
-        04:8b:6a:81:e0:11:5b:e1:35:a3:ff:2f:11:86:1c:31:85:7a:
-        fd:3f:36:ef:99:25:46:2e:b0:cb:43:45:4a:ec:be:d3:3f:a4:
-        77:9b:79:cc:ce:92:63:a5:d9:ed:db:a0:9d:5d:7c:d7:80:f6:
-        c9:41:fb:02:96:8e:fd:f3:da:05:9d:81:a7:25:da:26:35:3b:
-        a9:0c:8c:f5:a7:5d:48:ec:87:c7:7a:60:51:76:f2:de:9b:14:
-        2b:55:8a:43:df:99:19:f3:eb:e7:03:e6:a7:a2:a2:28:dd:d5:
-        07:6a:3f:f7
+        b3:38:e0:da:a8:07:d8:cc:b8:4d:8c:20:a6:06:2c:f8:27:db:
+        8e:28:0f:39:bd:d9:24:c7:9f:e0:4d:d6:b6:63:42:36:0f:d8:
+        70:41:e7:9e:a2:24:64:05:ea:85:97:ac:f2:cc:c2:a6:71:bb:
+        30:21:c1:c7:c4:54:34:1d:30:09:f0:9b:74:27:93:59:12:4c:
+        53:0b:8c:3e:d0:39:ed:4a:d0:d9:66:24:d8:e7:e5:9c:a8:6d:
+        5f:56:5d:9a:91:fe:1b:7d:b9:7c:79:9e:1c:b9:71:74:14:f8:
+        0c:30:50:f9:b1:22:56:a8:4d:6f:4b:9b:e5:8a:81:33:1b:77:
+        75:f6:d8:ce:d4:90:34:86:34:d1:86:75:a9:e1:23:e6:af:c1:
+        8e:28:97:47:20:4d:1b:57:09:39:f4:56:01:d2:87:43:3e:29:
+        f6:c4:5b:7d:8f:9e:bd:ad:36:79:cf:09:70:43:30:21:98:23:
+        31:c8:0d:39:ee:77:e1:4a:44:1a:5c:79:2f:6c:ec:8a:3c:db:
+        99:a0:11:bc:1a:46:24:51:e7:75:d6:9a:db:ad:dd:55:d4:dd:
+        ca:81:a0:10:77:96:91:9c:76:30:38:18:f0:82:43:b3:7c:41:
+        64:4c:4e:da:66:22:67:cf:b7:d7:10:ba:ed:f4:6d:43:59:00:
+        d0:82:1e:07
 -----BEGIN CERTIFICATE-----
-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
+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
-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
+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
-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
+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
-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
-dvLemxQrVYpD35kZ8+vnA+anoqIo3dUHaj/3
+BgNVBAsTA01UQTEiMCAGA1UEAxMZQ2xhdXMgQXNzbWFubiBDQSBSU0EgMjAwOTEm
+MCQGCSqGSIb3DQEJARYXY2ErY2EtcnNhMjAwOUBlc210cC5vcmeCCQDCPGFnOwrM
+XjAMBgNVHRMEBTADAQH/MCIGA1UdEQQbMBmBF2NhK2NhLXJzYTIwMDlAZXNtdHAu
+b3JnMCIGA1UdEgQbMBmBF2NhK2NhLXJzYTIwMDlAZXNtdHAub3JnMA0GCSqGSIb3
+DQEBBAUAA4IBAQCzOODaqAfYzLhNjCCmBiz4J9uOKA85vdkkx5/gTda2Y0I2D9hw
+QeeeoiRkBeqFl6zyzMKmcbswIcHHxFQ0HTAJ8Jt0J5NZEkxTC4w+0DntStDZZiTY
+5+WcqG1fVl2akf4bfbl8eZ4cuXF0FPgMMFD5sSJWqE1vS5vlioEzG3d19tjO1JA0
+hjTRhnWp4SPmr8GOKJdHIE0bVwk59FYB0odDPin2xFt9j569rTZ5zwlwQzAhmCMx
+yA057nfhSkQaXHkvbOyKPNuZoBG8GkYkUed11prbrd1V1N3KgaAQd5aRnHYwOBjw
+gkOzfEFkTE7aZiJnz7fXELrt9G1DWQDQgh4H
 -----END CERTIFICATE-----
diff --git a/contrib/sendmail/LICENSE b/contrib/sendmail/LICENSE
index e8639f5a5a9..2c604033ee3 100644
--- a/contrib/sendmail/LICENSE
+++ b/contrib/sendmail/LICENSE
@@ -1,7 +1,7 @@
 			     SENDMAIL LICENSE
 
 The following license terms and conditions apply, unless a different
-license is obtained from Sendmail, Inc., 6425 Christie Ave, Fourth Floor,
+license is obtained from Sendmail, Inc., 6475 Christie Ave, Suite 350,
 Emeryville, CA 94608, USA, or by electronic mail at license@sendmail.com.
 
 License Terms:
@@ -33,7 +33,7 @@ each of the following conditions is met:
    forth as paragraph 6 below, in the documentation and/or other materials
    provided with the distribution.  For the purposes of binary distribution
    the "Copyright Notice" refers to the following language:
-   "Copyright (c) 1998-2004 Sendmail, Inc.  All rights reserved."
+   "Copyright (c) 1998-2009 Sendmail, Inc.  All rights reserved."
 
 4. Neither the name of Sendmail, Inc. nor the University of California nor
    the names of their contributors may be used to endorse or promote
@@ -76,4 +76,4 @@ each of the following conditions is met:
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 
-$Revision: 8.13 $, Last updated $Date: 2004/05/11 23:57:57 $
+$Revision: 8.15 $, Last updated $Date: 2009/03/04 19:58:04 $
diff --git a/contrib/sendmail/PGPKEYS b/contrib/sendmail/PGPKEYS
index 3f7e9226d96..5f89ed43942 100644
--- a/contrib/sendmail/PGPKEYS
+++ b/contrib/sendmail/PGPKEYS
@@ -141,6 +141,79 @@ gpExpdV7qPrw9k01j5rod5PjZlG8zV0=
 =SR28
 -----END PGP PUBLIC KEY BLOCK-----
 
+Type Bits KeyID      Created    Expires    Algorithm       Use
+pub  1024 0xA77F2429 2009-01-01 ---------- RSA             Sign & Encrypt
+f16    Fingerprint16 = 33 3A 62 61 2C F3 21 AA  4E 87 47 F2 2F 2C 40 4D
+uid  Sendmail Signing Key/2009 
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.8 (OpenBSD)
+
+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
+wzfu
+=RCyv
+-----END PGP PUBLIC KEY BLOCK-----
+
 Type Bits KeyID      Created    Expires    Algorithm       Use
 pub  1024 0xF6B30729 2008-01-18 ---------- RSA             Sign & Encrypt
 f16    Fingerprint16 = 07 FB 9A F9 F7 94 4B E4  0F 28 D1 8E 23 6F A2 B0
@@ -1792,4 +1865,4 @@ DnF3FZZEzV7oqPwC2jzv/1dD6GFhtgy0cnyoPGUJCyc=
 =nES8
 -----END PGP PUBLIC KEY BLOCK-----
 
-$Revision: 8.26 $, Last updated $Date: 2008/01/22 06:20:27 $
+$Revision: 8.29 $, Last updated $Date: 2009/01/06 05:59:03 $
diff --git a/contrib/sendmail/README b/contrib/sendmail/README
index a8db16227a3..8175b1a879c 100644
--- a/contrib/sendmail/README
+++ b/contrib/sendmail/README
@@ -38,6 +38,7 @@ the latest updates.
 4. Read cf/README.
 
 Sendmail is a trademark of Sendmail, Inc.
+US Patent Numbers 6865671, 6986037.
 
 +-----------------------+
 | DIRECTORY PERMISSIONS |
@@ -464,4 +465,4 @@ sendmail	Source for the sendmail program itself.
 test		Some test scripts (currently only for compilation aids).
 vacation	Source for the vacation program.  NOT PART OF SENDMAIL!
 
-$Revision: 8.94 $, Last updated $Date: 2008/02/12 16:40:05 $
+$Revision: 8.95 $, Last updated $Date: 2009/04/10 17:49:18 $
diff --git a/contrib/sendmail/RELEASE_NOTES b/contrib/sendmail/RELEASE_NOTES
index 0d8ed8663c0..4e1e8f38305 100644
--- a/contrib/sendmail/RELEASE_NOTES
+++ b/contrib/sendmail/RELEASE_NOTES
@@ -1,11 +1,96 @@
 			SENDMAIL RELEASE NOTES
-      $Id: RELEASE_NOTES,v 8.1926 2008/05/03 03:34:26 ca Exp $
+      $Id: RELEASE_NOTES,v 8.1963 2009/12/23 04:43:46 ca Exp $
 
 
 This listing shows the version of the sendmail binary, the version
 of the sendmail configuration files, the date of release, and a
 summary of the changes in that release.
 
+8.14.4/8.14.4	2009/12/30
+	SECURITY: Handle bogus certificates containing NUL characters
+		in CNs by placing a string indicating a bad certificate
+		in the {cn_subject} or {cn_issuer} macro.  Patch inspired
+		by Matthias Andree's changes for fetchmail.
+	During the generation of a queue identifier an integer overflow
+		could occur which might result in bogus characters
+		being used.  Based on patch from John Vannoy of
+		Pepperdine University.
+	The value of headers, e.g., Precedence, Content-Type, et.al.,
+		was not processed correctly.  Patch from Per Hedeland.
+	Between 8.11.7 and 8.12.0 the length limitation on a return
+		path was erroneously reduced from MAXNAME (256) to
+		MAXSHORTSTR (203).  Patch from John Gardiner Myers
+		of Proofpoint; the problem was also noted by Steve
+		Hubert of University of Washington.
+	Prevent a crash when a hostname lookup returns a seemingly
+		valid result which contains a NULL pointer (this seems
+		to be happening on some Linux versions).
+	The process title was missing the current load average when
+		the MTA was delaying connections due to DelayLA.
+		Patch from Dick St.Peters of NetHeaven.
+	Do not reset the number of queue entries in shared memory if
+		only some of them are processed.
+	Fix overflow of an internal array when parsing some replies
+		from a milter.  Problem found by Scott Rotondo
+		of Sun Microsystems.
+	If STARTTLS is turned off in the server (via M=S) then it
+		would not be initialized for use in the client either.
+		Patch from Kazuteru Okahashi of IIJ.
+	If a Diffie-Hellman cipher is selected for STARTTLS, the
+		handshake could fail with some TLS implementations
+		because the prime used by the server is not long enough.
+		Note: the initialization of the DSA/DH parameters for
+		the server can take a significant amount of time on slow
+		machines. This can be turned off by setting DHParameters
+		to none or a file (see doc/op/op.me).  Patch from
+		Petr Lampa of the Brno University of Technology.
+	Fix handling of `b' modifier for DaemonPortOptions on little
+		endian machines for loopback address.  Patch from
+		John Beck of Sun Microsystems.
+	Fix a potential memory leak in libsmdb/smdb1.c found by parfait.
+		Based on patch from Jonathan Gray of OpenBSD.
+	If a milter sets the reply code to "421" during the transfer
+		of the body, the SMTP server will terminate the SMTP session
+		with that error to match the behavior of the other callbacks.
+	Return EX_IOERR (instead of 0) if a mail submission fails due to
+		missing disk space in the mail queue.  Based on patch
+		from Martin Poole of RedHat.
+	CONFIG: Using FEATURE(`ldap_routing')'s `nodomain' argument would
+		cause addresses not found in LDAP to be misparsed.
+	CONFIG: Using a CN restriction did not work for TLS_Clt as it
+		referred to a wrong macro.  Patch from John Gardiner
+		Myers of Proofpoint.
+	CONFIG: The option relaytofulladdress of FEATURE(`access_db')
+		did not work if FEATURE(`relay_hosts_only') is used too.
+		Problem noted by Kristian Shaw.
+	CONFIG: The internal function lower() was broken and hence
+		strcasecmp() did not work either, which could cause
+		problems for some FEATURE()s if upper case arguments
+		were used.  Patch from Vesa-Matti J Kari of the
+		University of Helsinki.
+	LIBMILTER: Fix internal check whether a milter application
+		is compiled against the same version of libmilter as
+		it is linked against (especially useful for dynamic
+		libraries).
+	LIBMILTER: Fix memory leak that occurred when smfi_setsymlist()
+		was used.  Based on patch by Dan Lukes.
+	LIBMILTER: Document the effect of SMFIP_HDR_LEADSPC for filters
+		which add, insert, or replace headers.  From Benjamin
+		Pineau.
+	LIBMILTER: Fix error messages which refer to "select()" to be
+		correct if SM_CONF_POLL is used.  Based on patch from
+		John Nemeth.
+	LIBSM: Fix handling of LDAP search failures where the error is
+		carried in the search result itself, such as seen with
+		OpenLDAP proxy servers.
+	VACATION: Do not refer to a local variable outside its scope.
+		Based on patch from Mark Costlow of Southwest Cyberport.
+	Portability:
+		Enable HAVE_NANOSLEEP for SunOS 5.11. Patch from
+		John Beck of Sun Microsystems.
+		Drop NISPLUS from default SunOS 5.11 map definitions.
+		Patch from John Beck of Sun Microsystems.
+
 8.14.3/8.14.3	2008/05/03
 	During ruleset processing the generation of a key for a map
 		lookup and the parsing of the default value was broken
@@ -37,7 +122,7 @@ summary of the changes in that release.
 		Support shared libraries in Darwin 8 and 9.  Patch from
 		Chris Behrens of Concentric.
 		Add support for SCO OpenServer 6, patch from Boyd Gerber.
-	DEVTOOLS: Clarify that confSHAREDLIBDIR requires a trailing path.
+	DEVTOOLS: Clarify that confSHAREDLIBDIR requires a trailing slash.
 	Added Files:
 		devtools/OS/Darwin.9.x
 		devtools/OS/OSR.i386
diff --git a/contrib/sendmail/cf/README b/contrib/sendmail/cf/README
index 43737f60bce..e3496e927b6 100644
--- a/contrib/sendmail/cf/README
+++ b/contrib/sendmail/cf/README
@@ -3142,7 +3142,7 @@ starts with '+' and the items are separated by '++'.  Allowed
 extensions are:
 
 CN:name		name must match ${cn_subject}
-CN		${server_name} must match ${cn_subject}
+CN		${client_name}/${server_name} must match ${cn_subject}
 CS:name		name must match ${cert_subject}
 CI:name		name must match ${cert_issuer}
 
@@ -4701,4 +4701,4 @@ M4 DIVERSIONS
    8	DNS based blacklists
    9	special local rulesets (1 and 2)
 
-$Revision: 8.724 $, Last updated $Date: 2008/02/15 23:05:32 $
+$Revision: 8.727 $, Last updated $Date: 2009/05/07 23:46:17 $
diff --git a/contrib/sendmail/cf/cf/submit.cf b/contrib/sendmail/cf/cf/submit.cf
index 11f3820eaa3..5286c681be0 100644
--- a/contrib/sendmail/cf/cf/submit.cf
+++ b/contrib/sendmail/cf/cf/submit.cf
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
+# Copyright (c) 1998-2004, 2009 Sendmail, Inc. and its suppliers.
 #	All rights reserved.
 # Copyright (c) 1983, 1995 Eric P. Allman.  All rights reserved.
 # Copyright (c) 1988, 1993
@@ -16,8 +16,8 @@
 #####
 #####		SENDMAIL CONFIGURATION FILE
 #####
-##### built by ca@wiz.smi.sendmail.com on Fri May 2 20:39:00 PDT 2008
-##### in /extra/home/ca/sm-8.14.3/OpenSource/sendmail-8.14.3/cf/cf
+##### built by ca@wiz.smi.sendmail.com on Tue Dec 22 20:49:09 PST 2009
+##### in /extra/home/ca/sm-8.14.4/OpenSource/sendmail-8.14.4/cf/cf
 ##### using ../ as configuration include directory
 #####
 ######################################################################
@@ -27,7 +27,7 @@
 ######################################################################
 ######################################################################
 
-#####  $Id: cfhead.m4,v 8.116 2004/01/28 22:02:22 ca Exp $  #####
+#####  $Id: cfhead.m4,v 8.120 2009/01/23 22:39:21 ca Exp $  #####
 #####  $Id: cf.m4,v 8.32 1999/02/07 07:26:14 gshapiro Exp $  #####
 #####  $Id: submit.mc,v 8.14 2006/04/05 05:54:41 ca Exp $  #####
 #####  $Id: msp.m4,v 1.33 2004/02/09 22:32:38 ca Exp $  #####
@@ -35,7 +35,7 @@
 #####  $Id: no_default_msa.m4,v 8.2 2001/02/14 05:03:22 gshapiro Exp $  #####
 
 
-#####  $Id: proto.m4,v 8.734 2008/01/24 23:42:01 ca Exp $  #####
+#####  $Id: proto.m4,v 8.741 2009/12/11 00:04:53 ca Exp $  #####
 
 # level 10 config file format
 V10/Berkeley
@@ -114,7 +114,7 @@ D{MTAHost}[127.0.0.1]
 
 
 # Configuration version number
-DZ8.14.3/Submit
+DZ8.14.4/Submit
 
 
 ###############
@@ -440,6 +440,7 @@ O RunAsUser=smmsp
 # once the threshold number of recipients have been rejected
 #O BadRcptThrottle=0
 
+
 # shall we get local names from our installed interfaces?
 O DontProbeInterfaces=True
 
@@ -500,6 +501,7 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid
 # SMTP STARTTLS server options
 #O TLSSrvOptions
 
+
 # Input mail filters
 #O InputMailFilters
 
diff --git a/contrib/sendmail/cf/feature/ldap_routing.m4 b/contrib/sendmail/cf/feature/ldap_routing.m4
index a474f17fbe4..227060c20e9 100644
--- a/contrib/sendmail/cf/feature/ldap_routing.m4
+++ b/contrib/sendmail/cf/feature/ldap_routing.m4
@@ -1,6 +1,6 @@
 divert(-1)
 #
-# Copyright (c) 1999-2002, 2004, 2007 Sendmail, Inc. and its suppliers.
+# Copyright (c) 1999-2002, 2004, 2007, 2009 Sendmail, Inc. and its suppliers.
 #	All rights reserved.
 #
 # By using this file, you agree to the terms and conditions set
@@ -10,7 +10,7 @@ divert(-1)
 #
 
 divert(0)
-VERSIONID(`$Id: ldap_routing.m4,v 8.15 2007/05/01 17:38:25 ca Exp $')
+VERSIONID(`$Id: ldap_routing.m4,v 8.17 2009/06/26 21:11:08 ca Exp $')
 divert(-1)
 
 # Check first two arguments.  If they aren't set, may need to warn in proto.m4
@@ -35,12 +35,40 @@ ifelse(len(X`'_ARG6_), `1', `define(`_LDAP_ROUTE_MAPTEMP_', `_QUEUE_')',
        _ARG6_, `tempfail', `define(`_LDAP_ROUTE_MAPTEMP_', `_TEMPFAIL_')',
        _ARG6_, `queue', `define(`_LDAP_ROUTE_MAPTEMP_', `_QUEUE_')')
 
+define(`_ATMPF_', `')dnl
+dnl check whether arg contains -T`'_ATMPF_
+dnl unless it is a sequence map or just LDAP
+dnl note: this does not work if ARG1 begins with space(s), however, as
+dnl we issue a warning, hopefully the user will fix it...
+ifelse(defn(`_ARG1_'), `', `',
+  defn(`_ARG1_'), `LDAP', `',
+  `ifelse(index(_ARG1_, `sequence '), `0', `',
+    `ifelse(index(_ARG1_, _ATMPF_), `-1',
+      `errprint(`*** WARNING: missing -T'_ATMPF_` in first argument of FEATURE(`ldap_routing')
+')
+      define(`_ABP_', index(_ARG1_, ` '))
+      define(`_NARG1_', `substr(_ARG1_, 0, _ABP_) -T'_ATMPF_` substr(_ARG1_, _ABP_)')
+      ')
+    ')
+  ')
+ifelse(defn(`_ARG2_'), `', `',
+  defn(`_ARG2_'), `LDAP', `',
+  `ifelse(index(_ARG2_, `sequence '), `0', `',
+    `ifelse(index(_ARG2_, _ATMPF_), `-1',
+      `errprint(`*** WARNING: missing -T'_ATMPF_` in second argument of FEATURE(`ldap_routing')
+')
+      define(`_ABP_', index(_ARG2_, ` '))
+      define(`_NARG2_', `substr(_ARG2_, 0, _ABP_) -T'_ATMPF_` substr(_ARG2_, _ABP_)')
+      ')
+    ')
+  ')
+
 LOCAL_CONFIG
 # LDAP routing maps
 Kldapmh ifelse(len(X`'_ARG1_), `1',
 	       `ldap -1 -T -v mailHost -k (&(objectClass=inetLocalMailRecipient)(mailLocalAddress=%0))',
-	       `_ARG1_')
+	       defn(`_NARG1_'), `', `_ARG1_', `_NARG1_')
 
 Kldapmra ifelse(len(X`'_ARG2_), `1',
 		`ldap -1 -T -v mailRoutingAddress -k (&(objectClass=inetLocalMailRecipient)(mailLocalAddress=%0))',
-		`_ARG2_')
+		defn(`_NARG2_'), `', `_ARG2_', `_NARG2_')
diff --git a/contrib/sendmail/cf/m4/cfhead.m4 b/contrib/sendmail/cf/m4/cfhead.m4
index dc1d8ba6561..c2d0df7c8e1 100644
--- a/contrib/sendmail/cf/m4/cfhead.m4
+++ b/contrib/sendmail/cf/m4/cfhead.m4
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
+# Copyright (c) 1998-2004, 2009 Sendmail, Inc. and its suppliers.
 #	All rights reserved.
 # Copyright (c) 1983, 1995 Eric P. Allman.  All rights reserved.
 # Copyright (c) 1988, 1993
@@ -49,7 +49,7 @@ define(`OSTYPE',
 	define(`_ARG_', $2)
 	include(_CF_DIR_`'ostype/$1.m4)POPDIVERT`'')
 ## helpful functions
-define(`lower', `translit(`$1', `ABCDEFGHIJKLMNOPQRSTUVWXYZ', `abcdefghijklmnopqrstuvwx')')
+define(`lower', `translit(`$1', `ABCDEFGHIJKLMNOPQRSTUVWXYZ', `abcdefghijklmnopqrstuvwxyz')')
 define(`strcasecmp', `ifelse(lower($1), lower($2), `1', `0')')
 ## access to further arguments in FEATURE/HACK
 define(`_ACC_ARG_1_',`$1')
@@ -308,4 +308,4 @@ define(`confMILTER_MACROS_EOM', `{msg_id}')
 
 
 divert(0)dnl
-VERSIONID(`$Id: cfhead.m4,v 8.116 2004/01/28 22:02:22 ca Exp $')
+VERSIONID(`$Id: cfhead.m4,v 8.120 2009/01/23 22:39:21 ca Exp $')
diff --git a/contrib/sendmail/cf/m4/proto.m4 b/contrib/sendmail/cf/m4/proto.m4
index 4e314b3e41b..c021581c377 100644
--- a/contrib/sendmail/cf/m4/proto.m4
+++ b/contrib/sendmail/cf/m4/proto.m4
@@ -1,6 +1,6 @@
 divert(-1)
 #
-# Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers.
+# Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers.
 #	All rights reserved.
 # Copyright (c) 1983, 1995 Eric P. Allman.  All rights reserved.
 # Copyright (c) 1988, 1993
@@ -13,7 +13,7 @@ divert(-1)
 #
 divert(0)
 
-VERSIONID(`$Id: proto.m4,v 8.734 2008/01/24 23:42:01 ca Exp $')
+VERSIONID(`$Id: proto.m4,v 8.741 2009/12/11 00:04:53 ca Exp $')
 
 # level CF_LEVEL config file format
 V`'CF_LEVEL/ifdef(`VENDOR_NAME', `VENDOR_NAME', `Berkeley')
@@ -580,6 +580,7 @@ _OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `0')
 # once the threshold number of recipients have been rejected
 _OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0')
 
+
 # shall we get local names from our installed interfaces?
 _OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
 
@@ -640,6 +641,7 @@ _OPTION(AuthMaxBits, `confAUTH_MAX_BITS', `')
 # SMTP STARTTLS server options
 _OPTION(TLSSrvOptions, `confTLS_SRV_OPTIONS', `')
 
+
 # Input mail filters
 _OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
 
@@ -1509,7 +1511,9 @@ ifdef(`_LDAP_ROUTE_DETAIL_',
 # try without +detail
 R<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <$2 @ $4> <+$3>')dnl
 
-ifdef(`_LDAP_ROUTE_NODOMAIN_', `dnl', `
+ifdef(`_LDAP_ROUTE_NODOMAIN_', `
+# pretend we did the @domain lookup
+R<> <> <$+> <$+ @ $+> <$*>	$: <> <> <$1> <@ $3> <$4>', `
 # if still no mailRoutingAddress and no mailHost,
 # try @domain
 ifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
@@ -2139,7 +2143,10 @@ R$+ < @ $=w >		$@ RELAY
 ifdef(`_RELAY_HOSTS_ONLY_',
 `R$+ < @ $=R >		$@ RELAY
 ifdef(`_ACCESS_TABLE_', `dnl
-R$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>
+ifdef(`_RELAY_FULL_ADDR_', `dnl
+R$+ < @ $+ >		$: <$(access To:$1@$2 $: ? $)> <$1 < @ $2 >>
+R <$+ < @ $+ >>	$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>',`
+R$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>')
 dnl workspace:  >
 R <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
 `R$+ < @ $* $=R >	$@ RELAY
@@ -2691,7 +2698,7 @@ R$*  $#$*		$#$2
 R$*  $*		$: $1', `dnl')
 ifdef(`_ACCESS_TABLE_', `dnl
 dnl store name of other side
-R$*		$: $(macro {TLS_Name} $@ $&{server_name} $) $1
+R$*		$: $(macro {TLS_Name} $@ $&{client_name} $) $1
 dnl ignore second arg for now
 dnl maybe use it to distinguish permanent/temporary error?
 dnl if MAIL: permanent (STARTTLS has not been offered)
diff --git a/contrib/sendmail/cf/m4/version.m4 b/contrib/sendmail/cf/m4/version.m4
index bd722ac3a89..5ad5ffb9024 100644
--- a/contrib/sendmail/cf/m4/version.m4
+++ b/contrib/sendmail/cf/m4/version.m4
@@ -1,6 +1,6 @@
 divert(-1)
 #
-# Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers.
+# Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers.
 #	All rights reserved.
 # Copyright (c) 1983 Eric P. Allman.  All rights reserved.
 # Copyright (c) 1988, 1993
@@ -11,8 +11,8 @@ divert(-1)
 # the sendmail distribution.
 #
 #
-VERSIONID(`$Id: version.m4,v 8.195 2008/04/17 17:04:30 ca Exp $')
+VERSIONID(`$Id: version.m4,v 8.205 2009/12/23 04:43:09 ca Exp $')
 #
 divert(0)
 # Configuration version number
-DZ8.14.3`'ifdef(`confCF_VERSION', `/confCF_VERSION')
+DZ8.14.4`'ifdef(`confCF_VERSION', `/confCF_VERSION')
diff --git a/contrib/sendmail/contrib/qtool.pl b/contrib/sendmail/contrib/qtool.pl
index d6a63ec17eb..f2d33c27b4a 100755
--- a/contrib/sendmail/contrib/qtool.pl
+++ b/contrib/sendmail/contrib/qtool.pl
@@ -3,7 +3,7 @@
 ## Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
 ##	All rights reserved.
 ##
-## $Id: qtool.pl,v 8.29 2007/02/16 01:12:08 ca Exp $
+## $Id: qtool.pl,v 8.30 2009/03/04 16:57:30 ca Exp $
 ##
 use strict;
 use File::Basename;
@@ -450,7 +450,7 @@ sub unlock_file
 ##
 ##	Parameters:
 ##		src_name -- The name of the file to be move.
-##		dst_nome -- The name of the place to move it to.
+##		dst_name -- The name of the place to move it to.
 ##
 ##	Returns:
 ##		error_string -- If undef then no problem. Otherwise it is a 
@@ -1193,7 +1193,7 @@ sub bounce
 ##
 ##	This Condition Class checks the modification time of the
 ##	source file and returns true if the file's modification time is
-##	older than the number of seconds the class was initialzed with.
+##	older than the number of seconds the class was initialized with.
 ##
 
 package OlderThan;
@@ -1286,7 +1286,7 @@ sub check_move
 ## Eval
 ##
 ##	Takes a perl expression and evaluates it. The ControlFile object
-##	for the source QueuedMessage is avaliable through the name '$msg'.
+##	for the source QueuedMessage is available through the name '$msg'.
 ##
 
 package Eval;
diff --git a/contrib/sendmail/contrib/smcontrol.pl b/contrib/sendmail/contrib/smcontrol.pl
index 4987460e4d4..43ae5759132 100755
--- a/contrib/sendmail/contrib/smcontrol.pl
+++ b/contrib/sendmail/contrib/smcontrol.pl
@@ -1,4 +1,6 @@
-#!/usr/local/bin/perl -w
+#!/usr/bin/perl -w
+
+# $Id: smcontrol.pl,v 8.8 2008/07/21 21:31:43 ca Exp $
 
 use strict;
 use Getopt::Std;
diff --git a/contrib/sendmail/doc/op/op.me b/contrib/sendmail/doc/op/op.me
index 74c2d6679a4..be078102436 100644
--- a/contrib/sendmail/doc/op/op.me
+++ b/contrib/sendmail/doc/op/op.me
@@ -9,7 +9,7 @@
 .\" the sendmail distribution.
 .\"
 .\"
-.\"	$Id: op.me,v 8.741 2007/06/22 23:08:59 ca Exp $
+.\"	$Id: op.me,v 8.745 2009/12/13 04:12:46 ca Exp $
 .\"
 .\" eqn op.me | pic | troff -me
 .\"
@@ -90,13 +90,14 @@ Sendmail, Inc.
 .de Ve
 Version \\$2
 ..
-.Ve $Revision: 8.741 $
+.Ve $Revision: 8.745 $
 .rm Ve
 .sp
 For Sendmail Version 8.14
 .)l
 .(f
 Sendmail is a trademark of Sendmail, Inc.
+US Patent Numbers 6865671, 6986037.
 .)f
 .sp 2
 .pp
@@ -4952,9 +4953,21 @@ as "(may be forged)".
 .ip ${cn_issuer}
 The CN (common name) of the CA that signed the presented certificate
 (STARTTLS only).
+Note: if the CN cannot be extracted properly it will be replaced by
+one of these strings based on the encountered error:
+.(b
+.ta 25n
+BadCertificateContainsNUL	CN contains a NUL character
+BadCertificateTooLong	CN is too long
+BadCertificateUnknown	CN could not be extracted
+.)b
+In the last case, some other (unspecific) error occurred.
 .ip ${cn_subject}
 The CN (common name) of the presented certificate
 (STARTTLS only).
+See
+.b ${cn_issuer}
+for possible replacements.
 .ip ${currHeader}
 Header value as quoted string
 (possibly truncated to
@@ -5130,7 +5143,7 @@ The total number of incoming connections over the time interval specified
 by ConnectionRateWindowSize.
 .ip ${verify}
 The result of the verification of the presented cert;
-only defined after STARTTLS has been used.
+only defined after STARTTLS has been used (or attempted).
 Possible values are:
 .(b
 .ta 13n
@@ -6710,10 +6723,25 @@ CRL checking requires at least OpenSSL version 0.9.7.
 Note: if a CRLFile is specified but the file is unusable,
 STARTTLS is disabled.
 .ip DHParameters
-File with DH parameters for STARTTLS.
+Possible values are:
+.(b
+.ta 1i
+5	use 512 bit prime
+1	use 1024 bit prime
+none	do not use Diffie-Hellman
+NAME	load prime from file
+.)b
 This is only required if a ciphersuite containing DSA/DH is used.
-This is only for people with a good knowledge of TLS, all others
-can ignore this option.
+If ``5'' is selected, then precomputed, fixed primes are used.
+This is the default for the client side.
+If ``1'' is selected, then prime values are computed during startup.
+This is the default for the server side.
+Note: this operation can take a significant amount of time on a
+slow machine (several seconds), but it is only done once at startup.
+If ``none'' is selected, then TLS ciphersuites containing DSA/DH
+cannot be used.
+If a file name is specified (which must be an absolute path),
+then the primes are read from it.
 .ip DaemonPortOptions=\fIoptions\fP
 [O]
 Set server SMTP options.
@@ -11435,7 +11463,7 @@ replace it with a blank sheet for double-sided output.
 .\".sz 10
 .\"Eric Allman
 .\".sp
-.\"Version $Revision: 8.741 $
+.\"Version $Revision: 8.745 $
 .\".ce 0
 .bp 3
 .ce
diff --git a/contrib/sendmail/include/libmilter/mfapi.h b/contrib/sendmail/include/libmilter/mfapi.h
index 7d7fb1d99f5..8e3a1732861 100644
--- a/contrib/sendmail/include/libmilter/mfapi.h
+++ b/contrib/sendmail/include/libmilter/mfapi.h
@@ -7,7 +7,7 @@
  * the sendmail distribution.
  *
  *
- *	$Id: mfapi.h,v 8.78 2008/02/27 22:30:34 ca Exp $
+ *	$Id: mfapi.h,v 8.80 2009/11/06 00:57:08 ca Exp $
  */
 
 /*
@@ -18,7 +18,14 @@
 # define _LIBMILTER_MFAPI_H	1
 
 #ifndef SMFI_VERSION
-# define SMFI_VERSION	0x01000001	/* libmilter version number */
+# if _FFR_MDS_NEGOTIATE
+#  define SMFI_VERSION	0x01000002	/* libmilter version number */
+
+   /* first libmilter version that has MDS support */
+#  define SMFI_VERSION_MDS	0x01000002
+# else /* _FFR_MDS_NEGOTIATE */
+#  define SMFI_VERSION	0x01000001	/* libmilter version number */
+# endif /* _FFR_MDS_NEGOTIATE */
 #endif /* ! SMFI_VERSION */
 
 #define SM_LM_VRS_MAJOR(v)	(((v) & 0x7f000000) >> 24)
@@ -163,9 +170,7 @@ LIBMILTER_API int smfi_setdbg __P((int));
 LIBMILTER_API int smfi_settimeout __P((int));
 LIBMILTER_API int smfi_setconn __P((char *));
 LIBMILTER_API int smfi_stop __P((void));
-#if _FFR_MAXDATASIZE
 LIBMILTER_API size_t smfi_setmaxdatasize __P((size_t));
-#endif /* _FFR_MAXDATASIZE */
 LIBMILTER_API int smfi_version __P((unsigned int *, unsigned int *, unsigned int *));
 
 /*
diff --git a/contrib/sendmail/include/libmilter/mfdef.h b/contrib/sendmail/include/libmilter/mfdef.h
index 674856707de..f42ec026cc9 100644
--- a/contrib/sendmail/include/libmilter/mfdef.h
+++ b/contrib/sendmail/include/libmilter/mfdef.h
@@ -7,7 +7,7 @@
  * the sendmail distribution.
  *
  *
- *	$Id: mfdef.h,v 8.38 2007/03/27 18:53:48 ca Exp $
+ *	$Id: mfdef.h,v 8.39 2009/11/06 00:57:08 ca Exp $
  */
 
 /*
@@ -27,6 +27,12 @@
 #define MILTER_CHUNK_SIZE	65535	/* body chunk size */
 #define MILTER_MAX_DATA_SIZE	65535	/* default milter command data limit */
 
+#if _FFR_MDS_NEGOTIATE
+# define MILTER_MDS_64K	((64 * 1024) - 1)
+# define MILTER_MDS_256K ((256 * 1024) - 1)
+# define MILTER_MDS_1M	((1024 * 1024) - 1)
+#endif /* _FFR_MDS_NEGOTIATE */
+
 /* These apply to SMFIF_* flags */
 #define SMFI_V1_ACTS	0x0000000FL	/* The actions of V1 filter */
 #define SMFI_V2_ACTS	0x0000003FL	/* The actions of V2 filter */
@@ -100,6 +106,9 @@
 #define SMFIP_NR_EOH	0x00040000L	/* No reply for eoh */
 #define SMFIP_NR_BODY	0x00080000L	/* No reply for body chunk */
 #define SMFIP_HDR_LEADSPC 0x00100000L	/* header value leading space */
+#define SMFIP_MDS_256K	0x10000000L	/* MILTER_MAX_DATA_SIZE=256K */
+#define SMFIP_MDS_1M	0x20000000L	/* MILTER_MAX_DATA_SIZE=1M */
+/* #define SMFIP_	0x40000000L	reserved: see SMFI_INTERNAL*/
 
 #define SMFI_V1_PROT	0x0000003FL	/* The protocol of V1 filter */
 #define SMFI_V2_PROT	0x0000007FL	/* The protocol of V2 filter */
@@ -107,4 +116,11 @@
 /* all defined protocol bits */
 #define SMFI_CURR_PROT	0x001FFFFFL
 
+/* internal flags: only used between MTA and libmilter */
+#define SMFI_INTERNAL	0x70000000L
+
+#if _FFR_MILTER_CHECK
+# define SMFIP_TEST	0x80000000L
+#endif /* _FFR_MILTER_CHECK */
+
 #endif /* !_LIBMILTER_MFDEF_H */
diff --git a/contrib/sendmail/include/sm/conf.h b/contrib/sendmail/include/sm/conf.h
index 13b3b50cafc..5b1875426af 100644
--- a/contrib/sendmail/include/sm/conf.h
+++ b/contrib/sendmail/include/sm/conf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
  * Copyright (c) 1988, 1993
@@ -10,7 +10,7 @@
  * the sendmail distribution.
  *
  *
- *	$Id: conf.h,v 1.134 2007/09/24 23:05:37 ca Exp $
+ *	$Id: conf.h,v 1.139 2009/06/16 23:41:32 ca Exp $
  */
 
 /*
@@ -460,6 +460,7 @@ typedef int		pid_t;
 #   endif /* SOLARIS >= 21000 || (SOLARIS < 10000 && SOLARIS >= 210) */
 #   if SOLARIS >= 21100 || (SOLARIS < 10000 && SOLARIS >= 211)
 #    define GETLDAPALIASBYNAME_VERSION 2	/* changed in S11 */
+#    define HAVE_NANOSLEEP	1	/* moved from librt to libc in S11 */
 #   endif /* SOLARIS >= 21100 || (SOLARIS < 10000 && SOLARIS >= 211) */
 #   ifndef HASGETUSERSHELL
 #    define HASGETUSERSHELL 0	/* getusershell(3) causes core dumps pre-2.7 */
@@ -1021,6 +1022,10 @@ extern unsigned int sleepX __P((unsigned int seconds));
 #      define SMRSH_PATH	"/bin:/usr/bin"
 #     endif /* ! SMRSH_PATH */
 #    endif /* __FreeBSD_version >= 330000 */
+#    if __FreeBSD_version >= 430000	/* 4.3.0-release and later */
+#     define SOCKADDR_LEN_T	socklen_t	/* e.g., arg#3 to accept, getsockname */
+#     define SOCKOPT_LEN_T	socklen_t	/* arg#5 to getsockopt */
+#    endif /* __FreeBSD_version >= 430000 */
 #    define USESYSCTL		1	/* use sysctl(3) for getting ncpus */
 #    include 
 #   endif /* __FreeBSD__ >= 2 */
@@ -2800,6 +2805,20 @@ struct utsname
 #  define MAXHOSTNAMELEN	256
 # endif /* !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_) && !defined(NonStop_UX_BXX) && !defined(ALTOS_SYSTEM_V) */
 
+
+# if _FFR_LINUX_MHNL && defined(__linux__) && MAXHOSTNAMELEN < 255
+   /*
+   **  override Linux wierdness: a FQHN can be 255 chars long
+   **  SUSv3 requires HOST_NAME_MAX ("Maximum length of a host
+   **  name (not including the terminating null) as returned from the
+   **  gethostname() function.") to be at least 255.  c.f.:
+   **  http://www.opengroup.org/onlinepubs/009695399
+   **  but Linux defines that to 64 too.
+   */
+#  undef MAXHOSTNAMELEN
+#  define MAXHOSTNAMELEN	256
+# endif /* _FFR_LINUX_MHNL && defined(__linux__) && MAXHOSTNAMELEN < 255 */
+
 # if !defined(SIGCHLD) && defined(SIGCLD)
 #  define SIGCHLD	SIGCLD
 # endif /* !defined(SIGCHLD) && defined(SIGCLD) */
diff --git a/contrib/sendmail/include/sm/ldap.h b/contrib/sendmail/include/sm/ldap.h
index fc9a325feef..b0a9cc05804 100644
--- a/contrib/sendmail/include/sm/ldap.h
+++ b/contrib/sendmail/include/sm/ldap.h
@@ -6,7 +6,7 @@
  * forth in the LICENSE file which can be found at the top level of
  * the sendmail distribution.
  *
- *	$Id: ldap.h,v 1.33 2007/10/10 00:06:44 ca Exp $
+ *	$Id: ldap.h,v 1.34 2008/11/17 21:02:54 ca Exp $
  */
 
 #ifndef	SM_LDAP_H
@@ -92,7 +92,7 @@ struct sm_ldap_struct
 	char		ldap_attrsep;
 
 # if _FFR_LDAP_NETWORK_TIMEOUT
-	struct timeval	ldap_networktmo;
+	int		ldap_networktmo;
 # endif /* _FFR_LDAP_NETWORK_TIMEOUT */
 
 	/* Linked list of maps sharing the same LDAP binding */
diff --git a/contrib/sendmail/include/sm/sem.h b/contrib/sendmail/include/sm/sem.h
index 7b691a43adc..3ac0bc61cc3 100644
--- a/contrib/sendmail/include/sm/sem.h
+++ b/contrib/sendmail/include/sm/sem.h
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2001, 2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 2000-2001, 2005, 2008 Sendmail, Inc. and its suppliers.
  *      All rights reserved.
  *
  * By using this file, you agree to the terms and conditions set
  * forth in the LICENSE file which can be found at the top level of
  * the sendmail distribution.
  *
- *	$Id: sem.h,v 1.9 2005/02/17 22:08:58 ca Exp $
+ *	$Id: sem.h,v 1.10 2008/05/30 16:26:39 ca Exp $
  */
 
 #ifndef SM_SEM_H
@@ -47,6 +47,7 @@ extern int sm_sem_stop __P((int));
 extern int sm_sem_acq __P((int, int, int));
 extern int sm_sem_rel __P((int, int, int));
 extern int sm_sem_get __P((int, int));
+extern int sm_semsetowner __P((int, uid_t, gid_t, mode_t));
 
 # else /* SM_CONF_SEM > 0 */
 #  define sm_sem_start(key, nsem, semflg, owner) 0
diff --git a/contrib/sendmail/libmilter/Makefile.m4 b/contrib/sendmail/libmilter/Makefile.m4
index 929ec7519ef..bc9bc66d671 100644
--- a/contrib/sendmail/libmilter/Makefile.m4
+++ b/contrib/sendmail/libmilter/Makefile.m4
@@ -1,4 +1,4 @@
-dnl $Id: Makefile.m4,v 8.80 2008/04/08 05:23:44 ca Exp $
+dnl $Id: Makefile.m4,v 8.85 2009/11/24 21:59:33 ca Exp $
 include(confBUILDTOOLSDIR`/M4/switch.m4')
 
 dnl only required for compilation of EXTRAS
diff --git a/contrib/sendmail/libmilter/comm.c b/contrib/sendmail/libmilter/comm.c
index a7a44dffa7b..e04681c8d0b 100644
--- a/contrib/sendmail/libmilter/comm.c
+++ b/contrib/sendmail/libmilter/comm.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers.
+ *  Copyright (c) 1999-2004, 2009 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  *
  * By using this file, you agree to the terms and conditions set
@@ -9,7 +9,7 @@
  */
 
 #include 
-SM_RCSID("@(#)$Id: comm.c,v 8.67 2006/11/02 17:54:44 ca Exp $")
+SM_RCSID("@(#)$Id: comm.c,v 8.70 2009/12/16 16:33:48 ca Exp $")
 
 #include "libmilter.h"
 #include 
@@ -18,7 +18,6 @@ SM_RCSID("@(#)$Id: comm.c,v 8.67 2006/11/02 17:54:44 ca Exp $")
 static ssize_t	retry_writev __P((socket_t, struct iovec *, int, struct timeval *));
 static size_t Maxdatasize = MILTER_MAX_DATA_SIZE;
 
-#if _FFR_MAXDATASIZE
 /*
 **  SMFI_SETMAXDATASIZE -- set limit for milter data read/write.
 **
@@ -39,7 +38,6 @@ smfi_setmaxdatasize(sz)
 	Maxdatasize = sz;
 	return old;
 }
-#endif /* _FFR_MAXDATASIZE */
 
 /*
 **  MI_RD_CMD -- read a command
@@ -122,8 +120,8 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name)
 	else if (ret < 0)
 	{
 		smi_log(SMI_LOG_ERR,
-			"%s: mi_rd_cmd: select returned %d: %s",
-			name, ret, sm_errstring(errno));
+			"%s: mi_rd_cmd: %s() returned %d: %s",
+			name, MI_POLLSELECT, ret, sm_errstring(errno));
 		*cmd = SMFIC_RECVERR;
 		return NULL;
 	}
@@ -214,8 +212,8 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name)
 	if (ret < 0)
 	{
 		smi_log(SMI_LOG_ERR,
-			"%s: mi_rd_cmd: select returned %d: %s",
-			name, ret, sm_errstring(save_errno));
+			"%s: mi_rd_cmd: %s() returned %d: %s",
+			name, MI_POLLSELECT, ret, sm_errstring(save_errno));
 		*cmd = SMFIC_RECVERR;
 		return NULL;
 	}
@@ -326,7 +324,7 @@ mi_wr_cmd(sd, timeout, cmd, buf, len)
 	char *buf;
 	size_t len;
 {
-	size_t sl, i;
+	size_t sl;
 	ssize_t l;
 	mi_int32 nl;
 	int iovcnt;
@@ -339,7 +337,6 @@ mi_wr_cmd(sd, timeout, cmd, buf, len)
 	nl = htonl(len + 1);	/* add 1 for the cmd char */
 	(void) memcpy(data, (void *) &nl, MILTER_LEN_BYTES);
 	data[MILTER_LEN_BYTES] = (char) cmd;
-	i = 0;
 	sl = MILTER_LEN_BYTES + 1;
 
 	/* set up the vector for the size / command */
diff --git a/contrib/sendmail/libmilter/docs/api.html b/contrib/sendmail/libmilter/docs/api.html
index 4214df4dd87..578e0ca686a 100644
--- a/contrib/sendmail/libmilter/docs/api.html
+++ b/contrib/sendmail/libmilter/docs/api.html
@@ -2,7 +2,7 @@
 Milter API
 
 
 

Milter API

@@ -80,7 +80,9 @@ The following functions change a message's contents and attributes. They may only be called in xxfi_eom. All of these functions may invoke additional communication with the MTA. They will return either MI_SUCCESS or MI_FAILURE to indicate the status of -the operation. +the operation. Message data (senders, recipients, headers, body chunks) +passed to these functions via parameters is copied and does not need to be +preserved (i.e., allocated memory can be freed).

A filter must have set the appropriate flag (listed below) in the @@ -310,7 +312,7 @@ for a protocol stage.


-Copyright (c) 2000, 2003, 2006 Sendmail, Inc. and its suppliers. +Copyright (c) 2000, 2003, 2006, 2009 Sendmail, Inc. and its suppliers. All rights reserved.
By using this file, you agree to the terms and conditions set diff --git a/contrib/sendmail/libmilter/docs/overview.html b/contrib/sendmail/libmilter/docs/overview.html index b7e80dfdbed..5c6f21ce4ce 100644 --- a/contrib/sendmail/libmilter/docs/overview.html +++ b/contrib/sendmail/libmilter/docs/overview.html @@ -4,7 +4,7 @@

Technical Overview

@@ -60,7 +60,9 @@ returns to MESSAGE. For each of N connections { For each filter - process connection/helo (xxfi_connect, xxfi_helo) + process connection (xxfi_connect) + For each filter + process helo/ehlo (xxfi_helo) MESSAGE:For each message in this connection (sequentially) { For each filter diff --git a/contrib/sendmail/libmilter/docs/smfi_addheader.html b/contrib/sendmail/libmilter/docs/smfi_addheader.html index d068f9fdb93..460b4caf7cf 100644 --- a/contrib/sendmail/libmilter/docs/smfi_addheader.html +++ b/contrib/sendmail/libmilter/docs/smfi_addheader.html @@ -2,7 +2,7 @@ smfi_addheader

smfi_addheader

@@ -90,7 +90,11 @@ To change a header's current value, use the MTA will add this automatically. It is the filter writer's responsibility to ensure that no standards are violated. -
  • The MTA adds a leading space to an added header value. +
  • The MTA adds a leading space to an added header value unless + the flag +SMFIP_HDR_LEADSPC + is set, in which case the milter + must include any desired leading spaces itself. @@ -116,7 +120,7 @@ To change a header's current value, use
    -Copyright (c) 2000-2003, 2006 Sendmail, Inc. and its suppliers. +Copyright (c) 2000-2003, 2006, 2009 Sendmail, Inc. and its suppliers. All rights reserved.
    By using this file, you agree to the terms and conditions set diff --git a/contrib/sendmail/libmilter/docs/smfi_chgheader.html b/contrib/sendmail/libmilter/docs/smfi_chgheader.html index 0701a3671aa..517b5ba4c1c 100644 --- a/contrib/sendmail/libmilter/docs/smfi_chgheader.html +++ b/contrib/sendmail/libmilter/docs/smfi_chgheader.html @@ -2,7 +2,7 @@ smfi_chgheader

    smfi_chgheader

    @@ -85,6 +85,11 @@ Otherwise, it returns MI_SUCCESS. carriage return (ASCII 0x0d); the MTA will add this automatically. It is the filter writer's responsibility to ensure that no standards are violated. +
  • The MTA adds a leading space to a header value unless + the flag +SMFIP_HDR_LEADSPC + is set, in which case the milter + must include any desired leading spaces itself. @@ -110,7 +115,7 @@ Otherwise, it returns MI_SUCCESS.
    -Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers. +Copyright (c) 2000-2003, 2009 Sendmail, Inc. and its suppliers. All rights reserved.
    By using this file, you agree to the terms and conditions set diff --git a/contrib/sendmail/libmilter/docs/smfi_insheader.html b/contrib/sendmail/libmilter/docs/smfi_insheader.html index a4ba77f33d4..5962e61afea 100644 --- a/contrib/sendmail/libmilter/docs/smfi_insheader.html +++ b/contrib/sendmail/libmilter/docs/smfi_insheader.html @@ -2,7 +2,7 @@ smfi_insheader

    smfi_insheader

    @@ -111,6 +111,11 @@ Otherwise, it returns MI_SUCCESS. the MTA will add this automatically. It is the filter writer's responsibility to ensure that no standards are violated. +
  • The MTA adds a leading space to an inserted header value unless + the flag +SMFIP_HDR_LEADSPC + is set, in which case the milter + must include any desired leading spaces itself. @@ -135,7 +140,7 @@ Otherwise, it returns MI_SUCCESS.
    -Copyright (c) 2004, 2006 Sendmail, Inc. and its suppliers. +Copyright (c) 2004, 2006, 2009 Sendmail, Inc. and its suppliers. All rights reserved.
    By using this file, you agree to the terms and conditions set diff --git a/contrib/sendmail/libmilter/engine.c b/contrib/sendmail/libmilter/engine.c index 9002a0bab96..a2d3e1e3f3f 100644 --- a/contrib/sendmail/libmilter/engine.c +++ b/contrib/sendmail/libmilter/engine.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: engine.c,v 8.162 2008/02/27 01:34:14 ca Exp $") +SM_RCSID("@(#)$Id: engine.c,v 8.166 2009/11/06 00:57:07 ca Exp $") #include "libmilter.h" @@ -113,6 +113,7 @@ static void fix_stm __P((SMFICTX_PTR)); static bool trans_ok __P((int, int)); static char **dec_argv __P((char *, size_t)); static int dec_arg2 __P((char *, size_t, char **, char **)); +static void mi_clr_symlist __P((SMFICTX_PTR)); #if _FFR_WORKERS_POOL static bool mi_rd_socket_ready __P((int)); @@ -757,6 +758,69 @@ mi_clr_macros(ctx, m) } } +/* +** MI_CLR_SYMLIST -- clear list of macros +** +** Parameters: +** ctx -- context structure +** +** Returns: +** None. +*/ + +static void +mi_clr_symlist(ctx) + SMFICTX *ctx; +{ + int i; + + SM_ASSERT(ctx != NULL); + for (i = SMFIM_FIRST; i <= SMFIM_LAST; i++) + { + if (ctx->ctx_mac_list[i] != NULL) + { + free(ctx->ctx_mac_list[i]); + ctx->ctx_mac_list[i] = NULL; + } + } +} + +/* +** MI_CLR_CTX -- clear context +** +** Parameters: +** ctx -- context structure +** +** Returns: +** None. +*/ + +void +mi_clr_ctx(ctx) + SMFICTX *ctx; +{ + SM_ASSERT(ctx != NULL); + if (ValidSocket(ctx->ctx_sd)) + { + (void) closesocket(ctx->ctx_sd); + ctx->ctx_sd = INVALID_SOCKET; + } + if (ctx->ctx_reply != NULL) + { + free(ctx->ctx_reply); + ctx->ctx_reply = NULL; + } + if (ctx->ctx_privdata != NULL) + { + smi_log(SMI_LOG_WARN, + "%s: private data not NULL", + ctx->ctx_smfi->xxfi_name); + } + mi_clr_macros(ctx, 0); + mi_clr_symlist(ctx); + free(ctx); +} + /* ** ST_OPTIONNEG -- negotiate options ** @@ -771,8 +835,11 @@ static int st_optionneg(g) genarg *g; { - mi_int32 i, v, fake_pflags; + mi_int32 i, v, fake_pflags, internal_pflags; SMFICTX_PTR ctx; +#if _FFR_MILTER_CHECK + bool testmode = false; +#endif /* _FFR_MILTER_CHECK */ int (*fi_negotiate) __P((SMFICTX *, unsigned long, unsigned long, unsigned long, unsigned long, @@ -826,6 +893,7 @@ st_optionneg(g) v = SMFI_V1_ACTS; ctx->ctx_mta_aflags = v; /* MTA action flags */ + internal_pflags = 0; (void) memcpy((void *) &i, (void *) &(g->a_buf[MILTER_LEN_BYTES * 2]), MILTER_LEN_BYTES); v = ntohl(i); @@ -833,7 +901,51 @@ st_optionneg(g) /* no flags? set to default value for V1 protocol */ if (v == 0) v = SMFI_V1_PROT; - ctx->ctx_mta_pflags = v; /* MTA protocol flags */ +#if _FFR_MDS_NEGOTIATE + else if (ctx->ctx_smfi->xxfi_version >= SMFI_VERSION_MDS) + { + /* + ** Allow changing the size only if milter is compiled + ** against a version that supports this. + ** If a milter is dynamically linked against a newer + ** libmilter version, we don't want to "surprise" + ** it with a larger buffer as it may rely on it + ** even though it is not documented as a limit. + */ + + if (bitset(SMFIP_MDS_1M, v)) + { + internal_pflags |= SMFIP_MDS_1M; + (void) smfi_setmaxdatasize(MILTER_MDS_1M); + } + else if (bitset(SMFIP_MDS_256K, v)) + { + internal_pflags |= SMFIP_MDS_256K; + (void) smfi_setmaxdatasize(MILTER_MDS_256K); + } + } +# if 0 + /* don't log this for now... */ + else if (ctx->ctx_smfi->xxfi_version < SMFI_VERSION_MDS && + bitset(SMFIP_MDS_1M|SMFIP_MDS_256K, v)) + { + smi_log(SMI_LOG_WARN, + "%s: st_optionneg[%ld]: milter version=%X, trying flags=%X", + ctx->ctx_smfi->xxfi_name, + (long) ctx->ctx_id, ctx->ctx_smfi->xxfi_version, v); + } +# endif /* 0 */ +#endif /* _FFR_MDS_NEGOTIATE */ + + /* + ** MTA protocol flags. + ** We pass the internal flags to the milter as "read only", + ** i.e., a milter can read them so it knows which size + ** will be used, but any changes by a milter will be ignored + ** (see below, search for SMFI_INTERNAL). + */ + + ctx->ctx_mta_pflags = (v & ~SMFI_INTERNAL) | internal_pflags; /* ** Copy flags from milter struct into libmilter context; @@ -880,6 +992,12 @@ st_optionneg(g) 0, 0, &m_aflags, &m_pflags, &m_f2, &m_f3); +#if _FFR_MILTER_CHECK + testmode = bitset(SMFIP_TEST, m_pflags); + if (testmode) + m_pflags &= ~SMFIP_TEST; +#endif /* _FFR_MILTER_CHECK */ + /* ** Types of protocol flags (pflags): ** 1. do NOT send protocol step X @@ -1011,6 +1129,25 @@ st_optionneg(g) , ctx->ctx_mta_aflags, ctx->ctx_mta_pflags , ctx->ctx_aflags, ctx->ctx_pflags); +#if _FFR_MILTER_CHECK + if (ctx->ctx_dbg > 3) + sm_dprintf("[%ld] milter_negotiate:" + " testmode=%d, pflags2mta=%X, internal_pflags=%X\n" + , (long) ctx->ctx_id, testmode + , ctx->ctx_pflags2mta, internal_pflags); + + /* in test mode: take flags without further modifications */ + if (!testmode) + /* Warning: check statement below! */ +#endif /* _FFR_MILTER_CHECK */ + + /* + ** Remove the internal flags that might have been set by a milter + ** and set only those determined above. + */ + + ctx->ctx_pflags2mta = (ctx->ctx_pflags2mta & ~SMFI_INTERNAL) + | internal_pflags; return _SMFIS_OPTIONS; } diff --git a/contrib/sendmail/libmilter/example.c b/contrib/sendmail/libmilter/example.c index 5a09f1da973..cef4b0f33aa 100644 --- a/contrib/sendmail/libmilter/example.c +++ b/contrib/sendmail/libmilter/example.c @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: example.c,v 8.3 2006/12/20 21:22:34 ca Exp $ + * $Id: example.c,v 8.4 2008/07/22 15:12:47 ca Exp $ */ /* @@ -252,7 +252,7 @@ struct smfiDesc smfilter = mlfi_close, /* connection cleanup */ mlfi_unknown, /* unknown/unimplemented SMTP commands */ mlfi_data, /* DATA command filter */ - mlfi_negotiate /* option negotation at connection startup */ + mlfi_negotiate /* option negotiation at connection startup */ }; int diff --git a/contrib/sendmail/libmilter/handler.c b/contrib/sendmail/libmilter/handler.c index 5fd4b2630a9..2c34f1f05db 100644 --- a/contrib/sendmail/libmilter/handler.c +++ b/contrib/sendmail/libmilter/handler.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: handler.c,v 8.38 2006/11/02 02:38:22 ca Exp $") +SM_RCSID("@(#)$Id: handler.c,v 8.39 2008/11/25 01:14:16 ca Exp $") #include "libmilter.h" @@ -43,24 +43,7 @@ mi_handle_session(ctx) ret = MI_FAILURE; else ret = mi_engine(ctx); - if (ValidSocket(ctx->ctx_sd)) - { - (void) closesocket(ctx->ctx_sd); - ctx->ctx_sd = INVALID_SOCKET; - } - if (ctx->ctx_reply != NULL) - { - free(ctx->ctx_reply); - ctx->ctx_reply = NULL; - } - if (ctx->ctx_privdata != NULL) - { - smi_log(SMI_LOG_WARN, - "%s: private data not NULL", - ctx->ctx_smfi->xxfi_name); - } - mi_clr_macros(ctx, 0); - free(ctx); + mi_clr_ctx(ctx); ctx = NULL; return ret; } diff --git a/contrib/sendmail/libmilter/libmilter.h b/contrib/sendmail/libmilter/libmilter.h index 5a124097492..5824151da37 100644 --- a/contrib/sendmail/libmilter/libmilter.h +++ b/contrib/sendmail/libmilter/libmilter.h @@ -19,7 +19,7 @@ #ifdef _DEFINE # define EXTERN # define INIT(x) = x -SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.74 2006/12/19 18:19:52 ca Exp $") +SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.77 2008/11/25 18:28:18 ca Exp $") #else /* _DEFINE */ # define EXTERN extern # define INIT(x) @@ -282,6 +282,7 @@ extern int mi_handle_session __P((SMFICTX_PTR)); extern int mi_engine __P((SMFICTX_PTR)); extern int mi_listener __P((char *, int, smfiDesc_ptr, time_t, int)); extern void mi_clr_macros __P((SMFICTX_PTR, int)); +extern void mi_clr_ctx __P((SMFICTX_PTR)); extern int mi_stop __P((void)); extern int mi_control_startup __P((char *)); extern void mi_stop_milters __P((int)); diff --git a/contrib/sendmail/libmilter/listener.c b/contrib/sendmail/libmilter/listener.c index 6e68ae55d4a..48c552fddd4 100644 --- a/contrib/sendmail/libmilter/listener.c +++ b/contrib/sendmail/libmilter/listener.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: listener.c,v 8.124 2007/04/23 22:22:50 ca Exp $") +SM_RCSID("@(#)$Id: listener.c,v 8.126 2009/12/16 16:40:23 ca Exp $") /* ** listener.c -- threaded network listener @@ -777,8 +777,9 @@ mi_listener(conn, dbg, smfi, timeout, backlog) continue; scnt++; smi_log(SMI_LOG_ERR, - "%s: select() failed (%s), %s", - smfi->xxfi_name, sm_errstring(save_errno), + "%s: %s() failed (%s), %s", + smfi->xxfi_name, MI_POLLSELECT, + sm_errstring(save_errno), scnt >= MAX_FAILS_S ? "abort" : "try again"); MI_SLEEP(scnt); if (scnt >= MAX_FAILS_S) diff --git a/contrib/sendmail/libmilter/main.c b/contrib/sendmail/libmilter/main.c index 2da9a824a66..d6e727959dc 100644 --- a/contrib/sendmail/libmilter/main.c +++ b/contrib/sendmail/libmilter/main.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: main.c,v 8.83 2007/04/23 22:22:50 ca Exp $") +SM_RCSID("@(#)$Id: main.c,v 8.84 2008/09/02 05:37:06 ca Exp $") #define _DEFINE 1 #include "libmilter.h" diff --git a/contrib/sendmail/libmilter/worker.c b/contrib/sendmail/libmilter/worker.c index fd4b66ec741..28d404fa3a2 100644 --- a/contrib/sendmail/libmilter/worker.c +++ b/contrib/sendmail/libmilter/worker.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004, 2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 2003-2004, 2007, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -11,7 +11,7 @@ */ #include -SM_RCSID("@(#)$Id: worker.c,v 8.10 2007/12/03 22:06:05 ca Exp $") +SM_RCSID("@(#)$Id: worker.c,v 8.17 2009/06/15 15:34:54 ca Exp $") #include "libmilter.h" @@ -210,23 +210,7 @@ mi_close_session(ctx) SM_ASSERT(ctx != NULL); (void) mi_list_del_ctx(ctx); - if (ValidSocket(ctx->ctx_sd)) - { - (void) closesocket(ctx->ctx_sd); - ctx->ctx_sd = INVALID_SOCKET; - } - if (ctx->ctx_reply != NULL) - { - free(ctx->ctx_reply); - ctx->ctx_reply = NULL; - } - if (ctx->ctx_privdata != NULL) - { - smi_log(SMI_LOG_WARN, "%s: private data not NULL", - ctx->ctx_smfi->xxfi_name); - } - mi_clr_macros(ctx, 0); - free(ctx); + mi_clr_ctx(ctx); return MI_SUCCESS; } @@ -259,7 +243,7 @@ mi_pool_controller_init() if (pipe(Tskmgr.tm_p) != 0) { smi_log(SMI_LOG_ERR, "can't create event pipe: %s", - sm_errstring(r)); + sm_errstring(errno)); return MI_FAILURE; } @@ -328,6 +312,7 @@ mi_pool_controller(arg) int dim_pfd = 0; bool rebuild_set = true; int pcnt = 0; /* error count for poll() failures */ + time_t lastcheck; Tskmgr.tm_tid = sthread_get_id(); if (pthread_detach(Tskmgr.tm_tid) != 0) @@ -345,12 +330,12 @@ mi_pool_controller(arg) } dim_pfd = PFD_STEP; + lastcheck = time(NULL); for (;;) { SMFICTX_PTR ctx; int nfd, rfd, i; time_t now; - time_t lastcheck; POOL_LEV_DPRINTF(4, ("Let's %s again...", WAITFN)); @@ -364,20 +349,20 @@ mi_pool_controller(arg) /* check for timed out sessions? */ if (lastcheck + DT_CHECK_OLD_SESSIONS < now) { - SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link) + ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD); + while (ctx != SM_TAILQ_END(&WRK_CTX_HEAD)) { + SMFICTX_PTR ctx_nxt; + + ctx_nxt = SM_TAILQ_NEXT(ctx, ctx_link); if (ctx->ctx_wstate == WKST_WAITING) { if (ctx->ctx_wait == 0) - { ctx->ctx_wait = now; - continue; - } - - /* if session timed out, close it */ - if (ctx->ctx_wait + OLD_SESSION_TIMEOUT - < now) + else if (ctx->ctx_wait + OLD_SESSION_TIMEOUT + < now) { + /* if session timed out, close it */ sfsistat (*fi_close) __P((SMFICTX *)); POOL_LEV_DPRINTF(4, @@ -389,10 +374,9 @@ mi_pool_controller(arg) (void) (*fi_close)(ctx); mi_close_session(ctx); - ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD); - continue; } } + ctx = ctx_nxt; } lastcheck = now; } @@ -465,6 +449,7 @@ mi_pool_controller(arg) } } } + rebuild_set = false; } TASKMGR_UNLOCK(); diff --git a/contrib/sendmail/libsm/debug.c b/contrib/sendmail/libsm/debug.c index f9281fd5e71..ea9cd846ace 100644 --- a/contrib/sendmail/libsm/debug.c +++ b/contrib/sendmail/libsm/debug.c @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: debug.c,v 1.30 2004/08/03 20:10:26 ca Exp $") +SM_RCSID("@(#)$Id: debug.c,v 1.32 2009/09/20 05:38:46 ca Exp $") /* ** libsm debugging and tracing @@ -17,6 +17,10 @@ SM_RCSID("@(#)$Id: debug.c,v 1.30 2004/08/03 20:10:26 ca Exp $") #include #include +#if _FFR_DEBUG_PID_TIME +#include +#include +#endif /* _FFR_DEBUG_PID_TIME */ #include #include #include @@ -112,6 +116,11 @@ sm_debug_close() ** none. */ +#if _FFR_DEBUG_PID_TIME +SM_DEBUG_T SmDBGPidTime = SM_DEBUG_INITIALIZER("sm_trace_pid_time", + "@(#)$Debug: sm_trace_pid_time - print pid and time in debug $"); +#endif /* _FFR_DEBUG_PID_TIME */ + void #if SM_VA_STD sm_dprintf(char *fmt, ...) @@ -125,6 +134,26 @@ sm_dprintf(fmt, va_alist) if (SmDebugOutput == NULL) return; +#if _FFR_DEBUG_PID_TIME + /* note: this is ugly if the output isn't a full line! */ + if (sm_debug_active(&SmDBGPidTime, 1)) + { + static char str[32] = "[1900-00-00/00:00:00] "; + struct tm *tmp; + time_t currt; + + currt = time((time_t *)0); + tmp = localtime(&currt); + snprintf(str, sizeof(str), "[%d-%02d-%02d/%02d:%02d:%02d] ", + 1900 + tmp->tm_year, /* HACK */ + tmp->tm_mon + 1, + tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + sm_io_fprintf(SmDebugOutput, SmDebugOutput->f_timeout, + "%ld: %s ", (long) getpid(), str); + } +#endif /* _FFR_DEBUG_PID_TIME */ + SM_VA_START(ap, fmt); sm_io_vfprintf(SmDebugOutput, SmDebugOutput->f_timeout, fmt, ap); SM_VA_END(ap); diff --git a/contrib/sendmail/libsm/ldap.c b/contrib/sendmail/libsm/ldap.c index 252e5475378..7ee57fcbb68 100644 --- a/contrib/sendmail/libsm/ldap.c +++ b/contrib/sendmail/libsm/ldap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 2001-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -11,7 +11,7 @@ #define LDAP_DEPRECATED 1 #include -SM_RCSID("@(#)$Id: ldap.c,v 1.80 2007/10/12 00:19:44 ca Exp $") +SM_RCSID("@(#)$Id: ldap.c,v 1.83 2009/06/19 22:02:26 guenther Exp $") #if LDAPMAP # include @@ -1099,7 +1099,21 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result, if (ret == 0) save_errno = ETIMEDOUT; else - save_errno = sm_ldap_geterrno(lmap->ldap_ld); + { + int rc; + + /* + ** We may have gotten an LDAP_RES_SEARCH_RESULT response + ** with an error inside it, so we have to extract that + ** with ldap_parse_result(). This can happen when talking + ** to an LDAP proxy whose backend has gone down. + */ + + save_errno = ldap_parse_result(lmap->ldap_ld, lmap->ldap_res, + &rc, NULL, NULL, NULL, NULL, 0); + if (save_errno == LDAP_SUCCESS) + save_errno = rc; + } if (save_errno != LDAP_SUCCESS) { statp = EX_TEMPFAIL; @@ -1370,9 +1384,16 @@ sm_ldap_setopts(ld, lmap) ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &lmap->ldap_sizelimit); ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &lmap->ldap_timelimit); -# if _FFR_LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT) - ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &lmap->ldap_networktmo); -# endif /* _FFR_LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT) */ +# if _FFR_LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT) + if (lmap->ldap_networktmo > 0) + { + struct timeval tmo; + + tmo.tv_sec = lmap->ldap_networktmo; + tmo.tv_usec = 0; + ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tmo); + } +# endif /* _FFR_LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT) */ # ifdef LDAP_OPT_RESTART ldap_set_option(ld, LDAP_OPT_RESTART, LDAP_OPT_ON); # endif /* LDAP_OPT_RESTART */ diff --git a/contrib/sendmail/libsm/mbdb.c b/contrib/sendmail/libsm/mbdb.c index ad0e7ccbd13..3bb514df516 100644 --- a/contrib/sendmail/libsm/mbdb.c +++ b/contrib/sendmail/libsm/mbdb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 2001-2003,2009 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: mbdb.c,v 1.40 2003/12/10 03:19:07 gshapiro Exp $") +SM_RCSID("@(#)$Id: mbdb.c,v 1.41 2009/06/19 22:02:26 guenther Exp $") #include @@ -564,7 +564,20 @@ mbdb_ldap_lookup(name, user) entry = ldap_first_entry(LDAPLMAP.ldap_ld, LDAPLMAP.ldap_res); if (entry == NULL) { - save_errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld); + int rc; + + /* + ** We may have gotten an LDAP_RES_SEARCH_RESULT response + ** with an error inside it, so we have to extract that + ** with ldap_parse_result(). This can happen when talking + ** to an LDAP proxy whose backend has gone down. + */ + + save_errno = ldap_parse_result(LDAPLMAP.ldap_ld, + LDAPLMAP.ldap_res, &rc, NULL, + NULL, NULL, NULL, 0); + if (save_errno == LDAP_SUCCESS) + save_errno = rc; if (save_errno == LDAP_SUCCESS) { errno = ENOENT; diff --git a/contrib/sendmail/libsm/sem.c b/contrib/sendmail/libsm/sem.c index 89394cbee4d..83a54e32e1e 100644 --- a/contrib/sendmail/libsm/sem.c +++ b/contrib/sendmail/libsm/sem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001, 2005 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2001, 2005, 2008 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,11 +8,12 @@ */ #include -SM_RCSID("@(#)$Id: sem.c,v 1.13 2005/08/12 20:39:59 ca Exp $") +SM_RCSID("@(#)$Id: sem.c,v 1.14 2008/05/30 16:26:38 ca Exp $") #if SM_CONF_SEM # include # include +# include # include # include # include @@ -200,4 +201,45 @@ sm_sem_get(semid, semnum) return -1; return semval; } + +/* +** SM_SEMSETOWNER -- set owner/group/mode of semaphores. +** +** Parameters: +** semid -- id for semaphores. +** uid -- uid to use +** gid -- gid to use +** mode -- mode to use +** +** Returns: +** 0 on success. +** < 0 on failure. +*/ + +int +sm_semsetowner(semid, uid, gid, mode) + int semid; + uid_t uid; + gid_t gid; + mode_t mode; +{ + int r; + struct semid_ds semidds; + union semun { + int val; + struct semid_ds *buf; + ushort *array; + } arg; + + memset(&semidds, 0, sizeof(semidds)); + arg.buf = &semidds; + if ((r = semctl(semid, 1, IPC_STAT, arg)) < 0) + return r; + semidds.sem_perm.uid = uid; + semidds.sem_perm.gid = gid; + semidds.sem_perm.mode = mode; + if ((r = semctl(semid, 1, IPC_SET, arg)) < 0) + return r; + return 0; +} #endif /* SM_CONF_SEM */ diff --git a/contrib/sendmail/libsm/t-sem.c b/contrib/sendmail/libsm/t-sem.c index 24d056365fa..662b4f6d43c 100644 --- a/contrib/sendmail/libsm/t-sem.c +++ b/contrib/sendmail/libsm/t-sem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001, 2005-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2001, 2005-2008 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: t-sem.c,v 1.16 2007/03/21 23:22:10 ca Exp $") +SM_RCSID("@(#)$Id: t-sem.c,v 1.17 2008/05/30 16:26:38 ca Exp $") #include @@ -127,6 +127,20 @@ sem_cleanup(sig) exit(EX_UNAVAILABLE); } +static int +drop_priv(uid, gid) + uid_t uid; + gid_t gid; +{ + int r; + + r = setgid(gid); + if (r != 0) + return r; + r = setuid(uid); + return r; +} + /* ** SEMTEST -- test of semaphores ** @@ -141,12 +155,23 @@ sem_cleanup(sig) # define MAX_CNT 10 static int -semtest(owner) +semtest(owner, uid, gid) int owner; + uid_t uid; + gid_t gid; { int semid, r; int cnt = 0; + if (!owner && uid != 0) + { + r = drop_priv(uid, gid); + if (r < 0) + { + perror("drop_priv child failed"); + return -1; + } + } semid = sm_sem_start(T_SM_SEM_KEY, 1, 0, owner); if (semid < 0) { @@ -156,6 +181,22 @@ semtest(owner) if (owner) { + if (uid != 0) + { + r = sm_semsetowner(semid, uid, gid, 0660); + if (r < 0) + { + perror("sm_semsetowner failed"); + return -1; + } + r = drop_priv(uid, gid); + if (r < 0) + { + perror("drop_priv owner failed"); + return -1; + } + } + /* just in case someone kills the program... */ semid_c = semid; (void) sm_signal(SIGHUP, sem_cleanup); @@ -281,18 +322,31 @@ main(argc, argv) { bool interactive = false; bool owner = false; - int ch; - int r = 0; + int ch, r; + uid_t uid; + gid_t gid; -# define OPTIONS "io" + uid = 0; + gid = 0; + r = 0; + +# define OPTIONS "iog:u:" while ((ch = getopt(argc, argv, OPTIONS)) != -1) { switch ((char) ch) { + case 'g': + gid = (gid_t)strtoul(optarg, 0, 0); + break; + case 'i': interactive = true; break; + case 'u': + uid = (uid_t)strtoul(optarg, 0, 0); + break; + case 'o': owner = true; break; @@ -323,11 +377,11 @@ main(argc, argv) { /* give the parent the chance to setup data */ sleep(1); - r = semtest(false); + r = semtest(false, uid, gid); } else { - r = semtest(true); + r = semtest(true, uid, gid); } SM_TEST(r == 0); return sm_test_end(); diff --git a/contrib/sendmail/libsmdb/smdb1.c b/contrib/sendmail/libsmdb/smdb1.c index e45de7c7f8f..842d4b2ecab 100644 --- a/contrib/sendmail/libsmdb/smdb1.c +++ b/contrib/sendmail/libsmdb/smdb1.c @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. +** Copyright (c) 1999-2002, 2004, 2009 Sendmail, Inc. and its suppliers. ** All rights reserved. ** ** By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: smdb1.c,v 8.59 2004/08/03 20:58:39 ca Exp $") +SM_RCSID("@(#)$Id: smdb1.c,v 8.62 2009/11/12 23:04:18 ca Exp $") #include #include @@ -397,15 +397,19 @@ smdb1_cursor(database, cursor, flags) if (db1->smdb1_cursor_in_use) return SMDBE_ONLY_SUPPORTS_ONE_CURSOR; - db1->smdb1_cursor_in_use = true; db1_cursor = (SMDB_DB1_CURSOR *) malloc(sizeof(SMDB_DB1_CURSOR)); - db1_cursor->db = db1; - - cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR)); - - if (cur == NULL) + if (db1_cursor == NULL) return SMDBE_MALLOC; + cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR)); + if (cur == NULL) + { + free(db1_cursor); + return SMDBE_MALLOC; + } + + db1->smdb1_cursor_in_use = true; + db1_cursor->db = db1; cur->smdbc_impl = db1_cursor; cur->smdbc_close = smdb1_cursor_close; cur->smdbc_del = smdb1_cursor_del; @@ -502,7 +506,12 @@ smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, smdb_db = smdb_malloc_database(); db1 = smdb1_malloc_database(); if (smdb_db == NULL || db1 == NULL) + { + (void) smdb_unlock_file(lock_fd); + smdb_free_database(smdb_db); + free(db1); return SMDBE_MALLOC; + } db1->smdb1_lock_fd = lock_fd; params = NULL; diff --git a/contrib/sendmail/libsmdb/smdb2.c b/contrib/sendmail/libsmdb/smdb2.c index be07d636b47..15806619ee5 100644 --- a/contrib/sendmail/libsmdb/smdb2.c +++ b/contrib/sendmail/libsmdb/smdb2.c @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers. +** Copyright (c) 1999-2003, 2009 Sendmail, Inc. and its suppliers. ** All rights reserved. ** ** By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: smdb2.c,v 8.79 2003/06/13 21:33:11 ca Exp $") +SM_RCSID("@(#)$Id: smdb2.c,v 8.80 2009/11/12 23:07:49 ca Exp $") #include #include @@ -620,12 +620,13 @@ smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, db_params } smdb_db = smdb_malloc_database(); - if (smdb_db == NULL) - return SMDBE_MALLOC; - db2 = smdb2_malloc_database(); - if (db2 == NULL) + if (db2 == NULL || smdb_db == NULL) + { + smdb_unlock_file(lock_fd); + smdb_free_database(smdb_db); /* ok to be NULL */ return SMDBE_MALLOC; + } db2->smdb2_lock_fd = lock_fd; diff --git a/contrib/sendmail/libsmutil/safefile.c b/contrib/sendmail/libsmutil/safefile.c index 8488534280e..f299e105355 100644 --- a/contrib/sendmail/libsmutil/safefile.c +++ b/contrib/sendmail/libsmutil/safefile.c @@ -15,7 +15,7 @@ #include #include -SM_RCSID("@(#)$Id: safefile.c,v 8.128 2004/09/30 18:15:49 ca Exp $") +SM_RCSID("@(#)$Id: safefile.c,v 8.129 2008/08/04 18:07:04 gshapiro Exp $") /* @@ -699,7 +699,6 @@ safeopen(fn, omode, cmode, sff) if (bitset(O_CREAT, omode)) sff |= SFF_CREAT; omode &= ~O_CREAT; - smode = 0; switch (omode & O_ACCMODE) { case O_RDONLY: diff --git a/contrib/sendmail/praliases/praliases.8 b/contrib/sendmail/praliases/praliases.8 index 2c78cacff53..1f11014f41c 100644 --- a/contrib/sendmail/praliases/praliases.8 +++ b/contrib/sendmail/praliases/praliases.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1998-2000, 2008 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" .\" By using this file, you agree to the terms and conditions set @@ -6,9 +6,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: praliases.8,v 8.17 2000/12/15 19:53:45 gshapiro Exp $ +.\" $Id: praliases.8,v 8.19 2008/07/10 20:13:10 ca Exp $ .\" -.TH PRALIASES 8 "$Date: 2000/12/15 19:53:45 $" +.TH PRALIASES 8 "$Date: 2008/07/10 20:13:10 $" .SH NAME praliases \- display system mail aliases @@ -30,12 +30,12 @@ The special internal @:@ alias will be displayed if present. .PP The options are as follows: .TP -.B \-C +.BI "\-C " file Read the specified sendmail configuration file instead of the default .B sendmail configuration file. .TP -.B \-f +.BI "\-f " file Read the specified file instead of the configured .B sendmail system aliases file(s). diff --git a/contrib/sendmail/praliases/praliases.c b/contrib/sendmail/praliases/praliases.c index 984981ff77a..d0ee54e37a0 100644 --- a/contrib/sendmail/praliases/praliases.c +++ b/contrib/sendmail/praliases/praliases.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2001, 2008 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -20,7 +20,7 @@ SM_IDSTR(copyright, Copyright (c) 1988, 1993\n\ The Regents of the University of California. All rights reserved.\n") -SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.94 2007/05/11 18:50:36 ca Exp $") +SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.96 2008/07/10 20:13:10 ca Exp $") #include #include @@ -99,7 +99,8 @@ main(argc, argv) case '?': default: (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, - "usage: praliases [-C cffile] [-f aliasfile]\n"); + "usage: praliases [-C cffile] [-f aliasfile]" + " [key ...]\n"); exit(EX_USAGE); } } diff --git a/contrib/sendmail/src/Makefile.m4 b/contrib/sendmail/src/Makefile.m4 index fd015b4937a..0fa337467d4 100644 --- a/contrib/sendmail/src/Makefile.m4 +++ b/contrib/sendmail/src/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.115 2008/03/27 16:13:33 ca Exp $ +dnl $Id: Makefile.m4,v 8.121 2009/12/15 22:39:23 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README index 34313fc8506..9c4628ffede 100644 --- a/contrib/sendmail/src/README +++ b/contrib/sendmail/src/README @@ -9,7 +9,7 @@ # the sendmail distribution. # # -# $Id: README,v 8.391 2008/02/12 16:38:21 ca Exp $ +# $Id: README,v 8.392 2009/04/10 17:49:19 gshapiro Exp $ # This directory contains the source files for sendmail(TM). @@ -32,6 +32,7 @@ For detailed instructions, please read the document ../doc/op/op.me: cd ../doc/op ; make op.ps op.txt Sendmail is a trademark of Sendmail, Inc. +US Patent Numbers 6865671, 6986037. +-------------------+ @@ -1847,4 +1848,4 @@ util.c Some general purpose routines used by sendmail. version.c The version number and information about this version of sendmail. -(Version $Revision: 8.391 $, last update $Date: 2008/02/12 16:38:21 $ ) +(Version $Revision: 8.392 $, last update $Date: 2009/04/10 17:49:19 $ ) diff --git a/contrib/sendmail/src/TRACEFLAGS b/contrib/sendmail/src/TRACEFLAGS index a6249fd2c47..6fdfdd97df1 100644 --- a/contrib/sendmail/src/TRACEFLAGS +++ b/contrib/sendmail/src/TRACEFLAGS @@ -1,4 +1,4 @@ -# $Id: TRACEFLAGS,v 8.47 2006/09/11 22:36:32 ca Exp $ +# $Id: TRACEFLAGS,v 8.48 2008/11/03 21:09:26 gshapiro Exp $ 0, 4 main.c main canonical name, UUCP node name, a.k.a.s 0, 15 main.c main print configuration 0, 44 util.c printav print address of each string @@ -86,6 +86,7 @@ 70 queue.c quarantining 71,>99 milter.c quarantine on errors 73 queue.c shared memory updates +74,>99 map.c LDAP map defer 80 content length 81 sun remote mode 83 collect.c timeout diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c index 0a2cdaba83e..f5d72477c51 100644 --- a/contrib/sendmail/src/collect.c +++ b/contrib/sendmail/src/collect.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: collect.c,v 8.282 2008/01/31 18:48:29 ca Exp $") +SM_RCSID("@(#)$Id: collect.c,v 8.284 2008/08/06 05:26:24 ca Exp $") static void eatfrom __P((char *volatile, ENVELOPE *)); static void collect_doheader __P((ENVELOPE *)); @@ -847,6 +847,9 @@ readerr: } /* Log collection information. */ + if (tTd(92, 2)) + sm_dprintf("collect: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); if (bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4) { logsender(e, e->e_msgid); diff --git a/contrib/sendmail/src/conf.c b/contrib/sendmail/src/conf.c index bf9705712c4..8d8f9ed6b14 100644 --- a/contrib/sendmail/src/conf.c +++ b/contrib/sendmail/src/conf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: conf.c,v 8.1141 2008/04/14 02:09:35 ca Exp $") +SM_RCSID("@(#)$Id: conf.c,v 8.1153 2009/12/18 17:25:12 ca Exp $") #include #include @@ -392,6 +392,9 @@ setdefaults(e) #if REQUIRES_DIR_FSYNC RequiresDirfsync = true; #endif /* REQUIRES_DIR_FSYNC */ +#if _FFR_RCPTTHROTDELAY + BadRcptThrottleDelay = 1; +#endif /* _FFR_RCPTTHROTDELAY */ ConnectionRateWindowSize = 60; setupmaps(); setupqueues(); @@ -782,7 +785,7 @@ inithostmaps() else if (strcmp(maptype[i], "ldap") == 0 && stab("aliases.ldap", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "aliases.ldap ldap -b . -h localhost -k mail=%0 -v mailgroup", + (void) sm_strlcpy(buf, "aliases.ldap ldap -b . -h localhost -k mail=%0 -v mailgroup", sizeof buf); (void) makemapentry(buf); } @@ -968,7 +971,10 @@ switch_map_find(service, maptype, mapreturn) p = strpbrk(buf, "#\n"); if (p != NULL) *p = '\0'; - p = strpbrk(buf, " \t"); +#ifndef SM_NSSWITCH_DELIMS +# define SM_NSSWITCH_DELIMS " \t" +#endif /* SM_NSSWITCH_DELIMS */ + p = strpbrk(buf, SM_NSSWITCH_DELIMS); if (p != NULL) *p++ = '\0'; if (buf[0] == '\0') @@ -981,7 +987,7 @@ switch_map_find(service, maptype, mapreturn) buf); continue; } - while (isspace(*p)) + while (isascii(*p) && isspace(*p)) p++; if (*p == '\0') continue; @@ -1007,7 +1013,7 @@ switch_map_find(service, maptype, mapreturn) if (p == NULL) break; *p++ = '\0'; - while (isspace(*p)) + while (isascii(*p) && isspace(*p)) p++; } if (svcno < MAXMAPSTACK) @@ -2282,7 +2288,8 @@ refuseconnections(e, dn, active) # define MIN_DELAY_LOG 90 /* wait before logging this again */ # define D_MSG_LA "delaying connections on daemon %s: load average=%d >= %d" /* sleep to flatten out connection load */ - sm_setproctitle(true, e, D_MSG_LA, Daemons[dn].d_name, limit); + sm_setproctitle(true, e, D_MSG_LA, Daemons[dn].d_name, + CurrentLA, limit); if (LogLevel > 8 && (now = curtime()) > log_delay) { sm_syslog(LOG_INFO, NOQID, D_MSG_LA, @@ -3374,6 +3381,10 @@ enoughdiskspace(msize, e) { int i; +#if _FFR_TESTS + if (tTd(4, 101)) + return false; +#endif /* _FFR_TESTS */ if (MinBlocksFree <= 0 && msize <= 0) { if (tTd(4, 80)) @@ -4074,7 +4085,7 @@ strtol(nptr, endptr, base) */ do { c = *s++; - } while (isspace(c)); + } while (isascii(c) && isspace(c)); if (c == '-') { neg = 1; c = *s++; @@ -4110,9 +4121,9 @@ strtol(nptr, endptr, base) cutlim = cutoff % (unsigned long) base; cutoff /= (unsigned long) base; for (acc = 0, any = 0;; c = *s++) { - if (isdigit(c)) + if (isascii(c) && isdigit(c)) c -= '0'; - else if (isalpha(c)) + else if (isascii(c) && isalpha(c)) c -= isupper(c) ? 'A' - 10 : 'a' - 10; else break; @@ -6043,6 +6054,10 @@ char *FFRCompileOptions[] = /* Deal with MTAs that send a reply during the DATA phase. */ "_FFR_CATCH_BROKEN_MTAS", #endif /* _FFR_CATCH_BROKEN_MTAS */ +#if _FFR_CHECKCONFIG + /* New OpMode to check the configuration file */ + "_FFR_CHECKCONFIG", +#endif /* _FFR_CHECKCONFIG */ #if _FFR_CHK_QUEUE /* Stricter checks about queue directory permissions. */ "_FFR_CHK_QUEUE", @@ -6117,6 +6132,10 @@ char *FFRCompileOptions[] = /* EightBitAddrOK: allow 8-bit e-mail addresses */ "_FFR_EIGHT_BIT_ADDR_OK", #endif /* _FFR_EIGHT_BIT_ADDR_OK */ +#if _FFR_EXPDELAY + /* exponential queue delay */ + "_FFR_EXPDELAY", +#endif /* _FFR_EXPDELAY */ #if _FFR_EXTRA_MAP_CHECK /* perform extra checks on $( $) in R lines */ "_FFR_EXTRA_MAP_CHECK", @@ -6175,10 +6194,17 @@ char *FFRCompileOptions[] = /* Ignore extensions offered in response to HELO */ "_FFR_IGNORE_EXT_ON_HELO", #endif /* _FFR_IGNORE_EXT_ON_HELO */ +#if _FFR_LINUX_MHNL + /* Set MAXHOSTNAMELEN to 256 (Linux) */ + "_FFR_LINUX_MHNL", +#endif /* _FFR_LINUX_MHNL */ #if _FFR_LOCAL_DAEMON /* Local daemon mode (-bl) which only accepts loopback connections */ "_FFR_LOCAL_DAEMON", #endif /* _FFR_LOCAL_DAEMON */ +#if _FFR_MAIL_MACRO + "_FFR_MAIL_MACRO", +#endif /* _FFR_MAIL_MACRO */ #if _FFR_MAXDATASIZE /* ** It is possible that a header is larger than MILTER_CHUNK_SIZE, @@ -6199,6 +6225,10 @@ char *FFRCompileOptions[] = /* Limit sleep(2) time in libsm/clock.c */ "_FFR_MAX_SLEEP_TIME", #endif /* _FFR_MAX_SLEEP_TIME */ +#if _FFR_MDS_NEGOTIATE + /* MaxDataSize negotation with libmilter */ + "_FFR_MDS_NEGOTIATE", +#endif /* _FFR_MDS_NEGOTIATE */ #if _FFR_MEMSTAT /* Check free memory */ "_FFR_MEMSTAT", @@ -6232,6 +6262,10 @@ char *FFRCompileOptions[] = "_FFR_MILTER_CHECK_REJECTIONS_TOO", #endif /* _FFR_MILTER_CHECK_REJECTIONS_TOO */ +#if _FFR_MILTER_ENHSC + /* extract enhanced status code from milter replies for dsn= logging */ + "_FFR_MILTER_ENHSC", +#endif /* _FFR_MILTER_ENHSC */ #if _FFR_MIME7TO8_OLD /* Old mime7to8 code, the new is broken for at least one example. */ "_FFR_MIME7TO8_OLD", @@ -6285,6 +6319,10 @@ char *FFRCompileOptions[] = /* Debug output for the queue scheduler. */ "_FFR_QUEUE_SCHED_DBG", #endif /* _FFR_QUEUE_SCHED_DBG */ +#if _FFR_RCPTTHROTDELAY + /* configurable delay for BadRcptThrottle */ + "_FFR_RCPTTHROTDELAY" +#endif /* _FFR_RCPTTHROTDELAY */ #if _FFR_REDIRECTEMPTY /* ** envelope <> can't be sent to mailing lists, only owner- @@ -6361,6 +6399,10 @@ char *FFRCompileOptions[] = /* SuperSafe per DaemonPortOptions: 'T' (better letter?) */ "_FFR_SS_PER_DAEMON", #endif /* _FFR_SS_PER_DAEMON */ +#if _FFR_TESTS + /* enable some test code */ + "_FFR_TESTS", +#endif /* _FFR_TESTS */ #if _FFR_TIMERS /* Donated code (unused). */ "_FFR_TIMERS", diff --git a/contrib/sendmail/src/conf.h b/contrib/sendmail/src/conf.h index f1386c4b61f..dff37ff99fe 100644 --- a/contrib/sendmail/src/conf.h +++ b/contrib/sendmail/src/conf.h @@ -10,7 +10,7 @@ * the sendmail distribution. * * - * $Id: conf.h,v 8.574 2006/11/29 00:36:06 ca Exp $ + * $Id: conf.h,v 8.575 2009/03/25 20:04:00 ca Exp $ */ /* @@ -123,9 +123,18 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ #define DATA_PROGRESS_TIMEOUT 300 /* how often to check DATA progress */ #define ENHSCLEN 10 /* max len of enhanced status code */ #define DEFAULT_MAX_RCPT 100 /* max number of RCPTs per envelope */ -#define MAXQUEUEGROUPS 50 /* max # of queue groups */ +#ifndef MAXQUEUEGROUPS +# define MAXQUEUEGROUPS 50 /* max # of queue groups */ /* must be less than BITMAPBITS for DoQueueRun */ -#define MAXWORKGROUPS 50 /* max # of work groups */ +#endif /* MAXQUEUEGROUPS */ +#if MAXQUEUEGROUPS >= BITMAPBITS + ERROR _MAXQUEUEGROUPS must be less than _BITMAPBITS +#endif /* MAXQUEUEGROUPS >= BITMAPBITS */ + +#ifndef MAXWORKGROUPS +# define MAXWORKGROUPS 50 /* max # of work groups */ +#endif /* MAXWORKGROUPS */ + #define MAXFILESYS BITMAPBITS /* max # of queue file systems * must be <= BITMAPBITS */ #ifndef FILESYS_UPDATE_INTERVAL diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c index 06a36c7e648..983ad2fe3ed 100644 --- a/contrib/sendmail/src/daemon.c +++ b/contrib/sendmail/src/daemon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2007, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include #include "map.h" -SM_RCSID("@(#)$Id: daemon.c,v 8.680 2008/02/14 00:20:26 ca Exp $") +SM_RCSID("@(#)$Id: daemon.c,v 8.683 2009/12/18 01:12:40 ca Exp $") #if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__) # define USE_SOCK_STREAM 1 @@ -199,7 +199,7 @@ getrequests(e) if (tTd(15, 1)) { for (idx = 0; idx < NDaemons; idx++) - sm_dprintf("getrequests: daemon %s: %d\n", + sm_dprintf("getrequests: daemon %s: socket %d\n", Daemons[idx].d_name, Daemons[idx].d_socket); } @@ -2161,7 +2161,8 @@ makeconnection(host, port, mci, e, enough) case AF_INET: clt_addr.sin.sin_addr.s_addr = inet_addr(p); if (clt_addr.sin.sin_addr.s_addr != INADDR_NONE && - clt_addr.sin.sin_addr.s_addr != INADDR_LOOPBACK) + clt_addr.sin.sin_addr.s_addr != + htonl(INADDR_LOOPBACK)) { clt_bind = true; socksize = sizeof(struct sockaddr_in); @@ -2342,7 +2343,7 @@ makeconnection(host, port, mci, e, enough) } } gothostent: - if (hp == NULL) + if (hp == NULL || hp->h_addr == NULL) { #if NAMED_BIND /* check for name server timeouts */ diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c index ed60e47a3c9..0322c956ef2 100644 --- a/contrib/sendmail/src/deliver.c +++ b/contrib/sendmail/src/deliver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include #include -SM_RCSID("@(#)$Id: deliver.c,v 8.1015 2007/10/17 21:35:30 ca Exp $") +SM_RCSID("@(#)$Id: deliver.c,v 8.1020 2009/12/18 17:08:01 ca Exp $") #if HASSETUSERCONTEXT # include @@ -575,12 +575,12 @@ sendall(e, mode) #endif /* HASFLOCK */ if (e->e_nrcpts > 0) e->e_flags |= EF_INQUEUE; - dropenvelope(e, splitenv != NULL, true); + (void) dropenvelope(e, splitenv != NULL, true); for (ee = splitenv; ee != NULL; ee = ee->e_sibling) { if (ee->e_nrcpts > 0) ee->e_flags |= EF_INQUEUE; - dropenvelope(ee, false, true); + (void) dropenvelope(ee, false, true); } return; @@ -602,7 +602,7 @@ sendall(e, mode) /* now drop the envelope in the parent */ e->e_flags |= EF_INQUEUE; - dropenvelope(e, splitenv != NULL, false); + (void) dropenvelope(e, splitenv != NULL, false); /* arrange to reacquire lock after fork */ e->e_id = qid; @@ -615,7 +615,7 @@ sendall(e, mode) /* drop envelope in parent */ ee->e_flags |= EF_INQUEUE; - dropenvelope(ee, false, false); + (void) dropenvelope(ee, false, false); /* and save qid for reacquisition */ ee->e_id = qid; @@ -762,14 +762,14 @@ sendall(e, mode) } sendenvelope(e, mode); - dropenvelope(e, true, true); + (void) dropenvelope(e, true, true); for (ee = splitenv; ee != NULL; ee = ee->e_sibling) { CurEnv = ee; if (mode != SM_VERIFY) openxscript(ee); sendenvelope(ee, mode); - dropenvelope(ee, true, true); + (void) dropenvelope(ee, true, true); } CurEnv = e; @@ -1391,7 +1391,7 @@ deliver(e, firstto) else p = e->e_from.q_paddr; rpath = remotename(p, m, RF_SENDERADDR|RF_CANONICAL, &rcode, e); - if (strlen(rpath) > MAXSHORTSTR) + if (strlen(rpath) > MAXNAME) { rpath = shortenstring(rpath, MAXSHORTSTR); @@ -2978,7 +2978,7 @@ reconnect: /* after switching to an encrypted connection */ char *s; /* - ** TLS negotation failed, what to do? + ** TLS negotiation failed, what to do? ** fall back to unencrypted connection ** or abort? How to decide? ** set a macro and call a ruleset. @@ -3021,7 +3021,7 @@ reconnect: /* after switching to an encrypted connection */ /* ** rcode == EX_SOFTWARE is special: - ** the TLS negotation failed + ** the TLS negotiation failed ** we have to drop the connection no matter what ** However, we call tls_server to give it the chance ** to log the problem and return an appropriate @@ -6075,8 +6075,9 @@ initclttls(tls_ok) return false; if (clt_ctx != NULL) return true; /* already done */ - tls_ok_clt = inittls(&clt_ctx, TLS_I_CLT, false, CltCertFile, - CltKeyFile, CACertPath, CACertFile, DHParams); + tls_ok_clt = inittls(&clt_ctx, TLS_I_CLT, Clt_SSL_Options, false, + CltCertFile, CltKeyFile, + CACertPath, CACertFile, DHParams); return tls_ok_clt; } @@ -6108,6 +6109,16 @@ starttls(m, mci, e) if (clt_ctx == NULL && !initclttls(true)) return EX_TEMPFAIL; + +# if USE_OPENSSL_ENGINE + if (!SSL_set_engine(NULL)) + { + sm_syslog(LOG_ERR, NOQID, + "STARTTLS=client, SSL_set_engine=failed"); + return EX_TEMPFAIL; + } +# endif /* USE_OPENSSL_ENGINE */ + smtpmessage("STARTTLS", m, mci); /* get the reply */ diff --git a/contrib/sendmail/src/envelope.c b/contrib/sendmail/src/envelope.c index 641c621a416..022c3ca8b2d 100644 --- a/contrib/sendmail/src/envelope.c +++ b/contrib/sendmail/src/envelope.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: envelope.c,v 8.305 2008/03/31 16:32:13 ca Exp $") +SM_RCSID("@(#)$Id: envelope.c,v 8.310 2009/12/18 17:08:01 ca Exp $") /* ** CLRSESSENVELOPE -- clear session oriented data in an envelope @@ -163,14 +163,14 @@ newenvelope(e, parent, rpool) ** split -- if true, split by recipient if message is queued up ** ** Returns: -** none. +** EX_* status (currently: 0: success, EX_IOERR on panic) ** ** Side Effects: ** housekeeping necessary to dispose of an envelope. ** Unlocks this queue file. */ -void +int dropenvelope(e, fulldrop, split) register ENVELOPE *e; bool fulldrop; @@ -209,12 +209,15 @@ dropenvelope(e, fulldrop, split) /* we must have an id to remove disk files */ if (id == NULL) - return; + return EX_OK; /* if verify-only mode, we can skip most of this */ if (OpMode == MD_VERIFY) goto simpledrop; + if (tTd(92, 2)) + sm_dprintf("dropenvelope: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) logsender(e, NULL); e->e_flags &= ~EF_LOGSENDER; @@ -618,7 +621,11 @@ simpledrop: } e->e_id = NULL; e->e_flags &= ~EF_HAS_DF; + if (panic) + return EX_IOERR; + return EX_OK; } + /* ** CLEARENVELOPE -- clear an envelope without unlocking ** @@ -714,6 +721,9 @@ clearenvelope(e, fullclear, rpool) bh = bh->h_link; nhp = &(*nhp)->h_link; } +#if _FFR_MILTER_ENHSC + e->e_enhsc[0] = '\0'; +#endif /* _FFR_MILTER_ENHSC */ } /* ** INITSYS -- initialize instantiation of system diff --git a/contrib/sendmail/src/headers.c b/contrib/sendmail/src/headers.c index 8e70fed7618..c4bdc877002 100644 --- a/contrib/sendmail/src/headers.c +++ b/contrib/sendmail/src/headers.c @@ -14,7 +14,7 @@ #include #include -SM_RCSID("@(#)$Id: headers.c,v 8.312 2007/06/19 18:52:11 ca Exp $") +SM_RCSID("@(#)$Id: headers.c,v 8.317 2008/08/27 20:11:55 gshapiro Exp $") static HDR *allocheader __P((char *, char *, int, SM_RPOOL_T *, bool)); static size_t fix_mime_header __P((HDR *, ENVELOPE *)); @@ -715,7 +715,16 @@ hvalue(field, header) { if (!bitset(H_DEFAULT, h->h_flags) && sm_strcasecmp(h->h_field, field) == 0) - return h->h_value; + { + char *s; + + s = h->h_value; + if (s == NULL) + return NULL; + while (isascii(*s) && isspace(*s)) + s++; + return s; + } } return NULL; } @@ -1065,6 +1074,10 @@ eatheader(e, full, log) ** Log collection information. */ + if (tTd(92, 2)) + sm_dprintf("eatheader: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d, log=%d\n", + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel, + log); if (log && bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4) { logsender(e, e->e_msgid); diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c index d68d5b590d6..1bbb070dace 100644 --- a/contrib/sendmail/src/main.c +++ b/contrib/sendmail/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2006, 2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2006, 2008, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -26,7 +26,7 @@ SM_UNUSED(static char copyright[]) = The Regents of the University of California. All rights reserved.\n"; #endif /* ! lint */ -SM_RCSID("@(#)$Id: main.c,v 8.967 2008/03/31 16:32:13 ca Exp $") +SM_RCSID("@(#)$Id: main.c,v 8.971 2009/12/18 17:08:01 ca Exp $") #if NETINET || NETINET6 @@ -129,7 +129,7 @@ int SyslogPrefixLen; /* estimated length of syslog prefix */ { \ if (extraprivs && \ OpMode != MD_DELIVER && OpMode != MD_SMTP && \ - OpMode != MD_ARPAFTP && \ + OpMode != MD_ARPAFTP && OpMode != MD_CHECKCONFIG && \ OpMode != MD_VERIFY && OpMode != MD_TEST) \ { \ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, \ @@ -401,6 +401,9 @@ main(argc, argv, envp) case MD_HOSTSTAT: case MD_PURGESTAT: case MD_ARPAFTP: +#if _FFR_CHECKCONFIG + case MD_CHECKCONFIG: +#endif /* _FFR_CHECKCONFIG */ OpMode = j; break; @@ -1192,7 +1195,7 @@ main(argc, argv, envp) } /* if we've had errors so far, exit now */ - if ((ExitStat != EX_OK && OpMode != MD_TEST) || + if ((ExitStat != EX_OK && OpMode != MD_TEST && OpMode != MD_CHECKCONFIG) || ExitStat == EX_OSERR) { finis(false, true, ExitStat); @@ -1566,6 +1569,7 @@ main(argc, argv, envp) break; case MD_TEST: + case MD_CHECKCONFIG: case MD_PRINT: case MD_PRINTNQE: case MD_FREEZE: @@ -1626,6 +1630,9 @@ main(argc, argv, envp) case MD_TEST: /* don't have persistent host status in test mode */ HostStatDir = NULL; + /* FALLTHROUGH */ + + case MD_CHECKCONFIG: if (Verbose == 0) Verbose = 2; BlankEnvelope.e_errormode = EM_PRINT; @@ -1933,8 +1940,8 @@ main(argc, argv, envp) } } - /* if we've had errors so far, exit now */ - if (ExitStat != EX_OK && OpMode != MD_TEST) + /* if checking config or have had errors so far, exit now */ + if (OpMode == MD_CHECKCONFIG || (ExitStat != EX_OK && OpMode != MD_TEST)) { finis(false, true, ExitStat); /* NOTREACHED */ @@ -1958,7 +1965,7 @@ main(argc, argv, envp) case MD_PRINT: /* print the queue */ HoldErrs = false; - dropenvelope(&BlankEnvelope, true, false); + (void) dropenvelope(&BlankEnvelope, true, false); (void) sm_signal(SIGPIPE, sigpipe); if (qgrp != NOQGRP) { @@ -1981,7 +1988,7 @@ main(argc, argv, envp) case MD_PRINTNQE: /* print number of entries in queue */ - dropenvelope(&BlankEnvelope, true, false); + (void) dropenvelope(&BlankEnvelope, true, false); (void) sm_signal(SIGPIPE, sigpipe); printnqe(smioout, NULL); finis(false, true, EX_OK); @@ -2133,8 +2140,8 @@ main(argc, argv, envp) else if (OpMode == MD_DAEMON || OpMode == MD_FGDAEMON || OpMode == MD_SMTP) { - /* check whether STARTTLS is turned off for the server */ - if (chkdaemonmodifiers(D_NOTLS)) + /* check whether STARTTLS is turned off */ + if (chkdaemonmodifiers(D_NOTLS) && chkclientmodifiers(D_NOTLS)) tls_ok = false; } else /* other modes don't need STARTTLS */ @@ -2530,7 +2537,7 @@ main(argc, argv, envp) } } } - dropenvelope(&MainEnvelope, true, false); + (void) dropenvelope(&MainEnvelope, true, false); #if STARTTLS /* init TLS for server, ignore result for now */ @@ -2952,7 +2959,11 @@ finis(drop, cleanup, exitstat) { if (CurEnv->e_id != NULL) { - dropenvelope(CurEnv, true, false); + int r; + + r = dropenvelope(CurEnv, true, false); + if (exitstat == EX_OK) + exitstat = r; sm_rpool_free(CurEnv->e_rpool); CurEnv->e_rpool = NULL; diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c index 4248fd90f51..be88685babd 100644 --- a/contrib/sendmail/src/map.c +++ b/contrib/sendmail/src/map.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1992, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: map.c,v 8.699 2007/10/10 00:06:45 ca Exp $") +SM_RCSID("@(#)$Id: map.c,v 8.705 2009/08/11 22:22:40 ca Exp $") #if LDAPMAP # include @@ -730,7 +730,7 @@ getcanonname(host, hbsize, trymx, pttl) int mapno; bool found = false; bool got_tempfail = false; - auto int status; + auto int status = EX_UNAVAILABLE; char *maptype[MAXMAPSTACK]; short mapreturn[MAXMAPACTIONS]; #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) @@ -1710,7 +1710,7 @@ lockdbm: { map->map_mflags |= MF_OPEN; map->map_pid = CurrentPid; - if ((omode && O_ACCMODE) == O_RDWR) + if ((omode & O_ACCMODE) == O_RDWR) map->map_mflags |= MF_WRITABLE; goto lockdbm; } @@ -2359,7 +2359,7 @@ db_map_lookup(map, name, av, statp) { map->map_mflags |= MF_OPEN; map->map_pid = CurrentPid; - if ((omode && O_ACCMODE) == O_RDWR) + if ((omode & O_ACCMODE) == O_RDWR) map->map_mflags |= MF_WRITABLE; db = (DB *) map->map_db2; goto lockdb; @@ -3415,6 +3415,18 @@ ldapmap_open(map, mode) else id = "localhost"; + if (tTd(74, 104)) + { + extern MAPCLASS NullMapClass; + + /* debug mode: don't actually open an LDAP connection */ + map->map_orgclass = map->map_class; + map->map_class = &NullMapClass; + map->map_mflags |= MF_OPEN; + map->map_pid = CurrentPid; + return true; + } + /* No connection yet, connect */ if (!sm_ldap_start(map->map_mname, lmap)) { @@ -3514,12 +3526,12 @@ sunet_id_hash(str) p_last = p; while (*p != '\0') { - if (islower(*p) || isdigit(*p)) + if (isascii(*p) && (islower(*p) || isdigit(*p))) { *p_last = *p; p_last++; } - else if (isupper(*p)) + else if (isascii(*p) && isupper(*p)) { *p_last = tolower(*p); p_last++; @@ -3967,6 +3979,10 @@ ldapmap_parseargs(map, args) map->map_coldelim = ' '; } +# if _FFR_LDAP_NETWORK_TIMEOUT + lmap->ldap_networktmo = 120; +# endif /* _FFR_LDAP_NETWORK_TIMEOUT */ + for (;;) { while (isascii(*p) && isspace(*p)) @@ -4066,7 +4082,7 @@ ldapmap_parseargs(map, args) case 'c': /* network (connect) timeout */ while (isascii(*++p) && isspace(*p)) continue; - lmap->ldap_networktmo.tv_sec = atoi(p); + lmap->ldap_networktmo = atoi(p); break; # endif /* _FFR_LDAP_NETWORK_TIMEOUT */ @@ -6687,6 +6703,13 @@ null_map_store(map, key, val) return; } +MAPCLASS NullMapClass = +{ + "null-map", NULL, 0, + NULL, null_map_lookup, null_map_store, + null_map_open, null_map_close, +}; + /* ** BOGUS stubs */ @@ -7325,7 +7348,8 @@ arith_map_lookup(map, name, av, statp) if (LogLevel > 10) sm_syslog(LOG_WARNING, NOQID, "arith_map: unknown operator %c", - isprint(*name) ? *name : '?'); + (isascii(*name) && isprint(*name)) ? + *name : '?'); return NULL; } if (boolres) diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c index 816c7bf7d4a..773dfa8f9c6 100644 --- a/contrib/sendmail/src/milter.c +++ b/contrib/sendmail/src/milter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2006 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ #include -SM_RCSID("@(#)$Id: milter.c,v 8.269 2007/06/06 17:26:12 ca Exp $") +SM_RCSID("@(#)$Id: milter.c,v 8.277 2009/11/06 00:57:06 ca Exp $") #if MILTER # include @@ -514,7 +514,6 @@ milter_write(m, cmd, buf, len, to, e, where) ENVELOPE *e; const char *where; { - time_t writestart = (time_t) 0; ssize_t sl, i; int num_vectors; mi_int32 nl; @@ -532,12 +531,16 @@ milter_write(m, cmd, buf, len, to, e, where) if (len < 0 || len > MilterMaxDataSize) { if (tTd(64, 5)) - sm_dprintf("milter_write(%s): length %ld out of range\n", - m->mf_name, (long) len); + { + sm_dprintf("milter_write(%s): length %ld out of range, cmd=%c\n", + m->mf_name, (long) len, command); + sm_dprintf("milter_write(%s): buf=%s\n", + m->mf_name, str2prt(buf)); + } if (MilterLogLevel > 0) sm_syslog(LOG_ERR, e->e_id, - "milter_write(%s): length %ld out of range", - m->mf_name, (long) len); + "milter_write(%s): length %ld out of range, cmd=%c", + m->mf_name, (long) len, command); milter_error(m, e); return NULL; } @@ -594,10 +597,7 @@ milter_write(m, cmd, buf, len, to, e, where) } if (to > 0) - { - writestart = curtime(); MILTER_TIMEOUT("write", to, true, started, where); - } /* write the vector(s) */ i = writev(m->mf_sock, vector, num_vectors); @@ -1572,10 +1572,10 @@ static struct milteropt # define MO_LOGLEVEL 0x07 { "loglevel", MO_LOGLEVEL }, -# if _FFR_MAXDATASIZE +# if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE # define MO_MAXDATASIZE 0x08 { "maxdatasize", MO_MAXDATASIZE }, -# endif /* _FFR_MAXDATASIZE */ +# endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */ { NULL, (unsigned char)-1 }, }; @@ -1631,11 +1631,29 @@ milter_set_option(name, val, sticky) MilterLogLevel = atoi(val); break; -#if _FFR_MAXDATASIZE +# if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE case MO_MAXDATASIZE: +# if _FFR_MDS_NEGOTIATE MilterMaxDataSize = (size_t)atol(val); + if (MilterMaxDataSize != MILTER_MDS_64K && + MilterMaxDataSize != MILTER_MDS_256K && + MilterMaxDataSize != MILTER_MDS_1M) + { + sm_syslog(LOG_WARNING, NOQID, + "WARNING: Milter.%s=%d, allowed are only %d, %d, and %d", + name, MilterMaxDataSize, + MILTER_MDS_64K, MILTER_MDS_256K, + MILTER_MDS_1M); + if (MilterMaxDataSize < MILTER_MDS_64K) + MilterMaxDataSize = MILTER_MDS_64K; + else if (MilterMaxDataSize < MILTER_MDS_256K) + MilterMaxDataSize = MILTER_MDS_256K; + else + MilterMaxDataSize = MILTER_MDS_1M; + } +# endif /* _FFR_MDS_NEGOTIATE */ break; -#endif /* _FFR_MAXDATASIZE */ +# endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */ case MO_MACROS_CONNECT: if (macros == NULL) @@ -2411,6 +2429,12 @@ milter_negotiate(m, e, milters) mta_prot_flags = SMFI_CURR_PROT; mta_actions = SMFI_CURR_ACTS; #endif /* _FFR_MILTER_CHECK */ +#if _FFR_MDS_NEGOTIATE + if (MilterMaxDataSize == MILTER_MDS_256K) + mta_prot_flags |= SMFIP_MDS_256K; + else if (MilterMaxDataSize == MILTER_MDS_1M) + mta_prot_flags |= SMFIP_MDS_1M; +#endif /* _FFR_MDS_NEGOTIATE */ fvers = htonl(mta_prot_vers); pflags = htonl(mta_prot_flags); @@ -2525,6 +2549,39 @@ milter_negotiate(m, e, milters) goto error; } +#if _FFR_MDS_NEGOTIATE + /* use a table instead of sequence? */ + if (bitset(SMFIP_MDS_1M, m->mf_pflags)) + { + if (MilterMaxDataSize != MILTER_MDS_1M) + { + /* this should not happen... */ + sm_syslog(LOG_WARNING, NOQID, + "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d", + MilterMaxDataSize, MILTER_MDS_1M); + MilterMaxDataSize = MILTER_MDS_1M; + } + } + else if (bitset(SMFIP_MDS_256K, m->mf_pflags)) + { + if (MilterMaxDataSize != MILTER_MDS_256K) + { + sm_syslog(LOG_WARNING, NOQID, + "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d", + MilterMaxDataSize, MILTER_MDS_256K); + MilterMaxDataSize = MILTER_MDS_256K; + } + } + else if (MilterMaxDataSize != MILTER_MDS_64K) + { + sm_syslog(LOG_WARNING, NOQID, + "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d", + MilterMaxDataSize, MILTER_MDS_64K); + MilterMaxDataSize = MILTER_MDS_64K; + } + m->mf_pflags &= ~SMFI_INTERNAL; +#endif /* _FFR_MDS_NEGOTIATE */ + /* check for protocol feature mismatch */ if ((m->mf_pflags & mta_prot_flags) != m->mf_pflags) { @@ -2976,7 +3033,7 @@ milter_addheader(m, response, rlen, e) h->h_value = mh_value; else { - h->h_value = addleadingspace (mh_value, e->e_rpool); + h->h_value = addleadingspace(mh_value, e->e_rpool); SM_FREE(mh_value); } h->h_flags |= H_USER; @@ -3277,7 +3334,7 @@ milter_changeheader(m, response, rlen, e) h->h_value = mh_value; else { - h->h_value = addleadingspace (mh_value, e->e_rpool); + h->h_value = addleadingspace(mh_value, e->e_rpool); SM_FREE(mh_value); } h->h_flags |= H_USER; @@ -3330,7 +3387,7 @@ milter_split_response(response, rlen, pargc) return NULL; /* last entry is only for the name */ - s = (char **)malloc(nelem * (sizeof(*s))); + s = (char **)malloc((nelem + 1) * (sizeof(*s))); if (s == NULL) return NULL; s[0] = response; @@ -3813,7 +3870,7 @@ milter_init(e, state, milters) m->mf_sock < 0 ? "open" : "negotiate"); - /* if negotation failure, close socket */ + /* if negotiation failure, close socket */ milter_error(m, e); MILTER_CHECK_ERROR(true, continue); continue; @@ -4383,7 +4440,7 @@ milter_data(e, state) response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e, - "body"); + "eom"); if (m->mf_state == SMFS_ERROR) break; diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c index d4c6369d0e6..194f5250d66 100644 --- a/contrib/sendmail/src/queue.c +++ b/contrib/sendmail/src/queue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include #include -SM_RCSID("@(#)$Id: queue.c,v 8.977 2008/02/15 23:19:58 ca Exp $") +SM_RCSID("@(#)$Id: queue.c,v 8.987 2009/12/18 17:08:01 ca Exp $") #include @@ -134,7 +134,7 @@ static const char EmptyString[] = ""; static void grow_wlist __P((int, int)); static int multiqueue_cache __P((char *, int, QUEUEGRP *, int, unsigned int *)); -static int gatherq __P((int, int, bool, bool *, bool *)); +static int gatherq __P((int, int, bool, bool *, bool *, int *)); static int sortq __P((int)); static void printctladdr __P((ADDRESS *, SM_FILE_T *)); static bool readqf __P((ENVELOPE *, bool)); @@ -2106,7 +2106,7 @@ run_work_group(wgrp, flags) for (i = 0; i < Queue[qgrp]->qg_numqueues; i++) { - h = gatherq(qgrp, qdir, false, &full, &more); + (void) gatherq(qgrp, qdir, false, &full, &more, &h); #if SM_CONF_SHM if (ShmId != SM_SHM_NO_ID) QSHM_ENTRIES(Queue[qgrp]->qg_qpaths[qdir].qp_idx) = h; @@ -2450,6 +2450,7 @@ runqueueevent(ignore) ** full -- (optional) to be set 'true' if WorkList is full ** more -- (optional) to be set 'true' if there are still more ** messages in this queue not added to WorkList +** pnentries -- (optional) total nuber of entries in queue ** ** Returns: ** The number of request in the queue (not necessarily @@ -2472,25 +2473,26 @@ static int WorkListSize = 0; /* current max size of WorkList */ static int WorkListCount = 0; /* # of work items in WorkList */ static int -gatherq(qgrp, qdir, doall, full, more) +gatherq(qgrp, qdir, doall, full, more, pnentries) int qgrp; int qdir; bool doall; bool *full; bool *more; + int *pnentries; { register struct dirent *d; register WORK *w; register char *p; DIR *f; - int i, num_ent; - int wn; + int i, num_ent, wn, nentries; QUEUE_CHAR *check; char qd[MAXPATHLEN]; char qf[MAXPATHLEN]; wn = WorkListCount - 1; num_ent = 0; + nentries = 0; if (qdir == NOQDIR) (void) sm_strlcpy(qd, ".", sizeof(qd)); else @@ -2600,6 +2602,7 @@ gatherq(qgrp, qdir, doall, full, more) continue; } + ++nentries; check = QueueLimitId; while (check != NULL) { @@ -2855,6 +2858,21 @@ gatherq(qgrp, qdir, doall, full, more) break; case 'K': +#if _FFR_EXPDELAY + if (MaxQueueAge > 0) + { + time_t lasttry, delay; + + lasttry = (time_t) atol(&lbuf[1]); + delay = MIN(lasttry - w->w_ctime, + MaxQueueAge); + age = curtime() - lasttry; + if (age < delay) + w->w_tooyoung = true; + break; + } +#endif /* _FFR_EXPDELAY */ + age = curtime() - (time_t) atol(&lbuf[1]); if (age >= 0 && MinQueueAge > 0 && age < MinQueueAge) @@ -2900,6 +2918,8 @@ gatherq(qgrp, qdir, doall, full, more) *full = (wn >= MaxQueueRun && MaxQueueRun > 0) || (WorkList == NULL && wn > 0); + if (pnentries != NULL) + *pnentries = nentries; return i; } /* @@ -3331,8 +3351,8 @@ workcmpf4(a, b) ** WORKCMPF5 -- compare based on assigned random number ** ** Parameters: -** a -- the first argument (ignored). -** b -- the second argument (ignored). +** a -- the first argument. +** b -- the second argument. ** ** Returns: ** randomly 1/-1 @@ -3682,7 +3702,7 @@ dowork(qgrp, qdir, id, forkflag, requeueflag, e) finis(true, true, ExitStat); else { - dropenvelope(e, true, false); + (void) dropenvelope(e, true, false); sm_rpool_free(rpool); e->e_rpool = NULL; } @@ -3859,7 +3879,7 @@ doworklist(el, forkflag, requeueflag) /* do the delivery */ sendall(&e, SM_DELIVER); - dropenvelope(&e, true, false); + (void) dropenvelope(&e, true, false); } else { @@ -4834,7 +4854,7 @@ print_single_queue(qgrp, qdir) ** Read and order the queue. */ - nrequests = gatherq(qgrp, qdir, true, NULL, NULL); + nrequests = gatherq(qgrp, qdir, true, NULL, NULL, NULL); (void) sortq(Queue[qgrp]->qg_maxlist); /* @@ -5332,31 +5352,31 @@ static const char QueueIdChars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh */ # define queuenextid() CurrentPid - +#define QIC_LEN_SQR (QIC_LEN * QIC_LEN) void assign_queueid(e) register ENVELOPE *e; { pid_t pid = queuenextid(); - static int cX = 0; - static long random_offset; + static unsigned int cX = 0; + static unsigned int random_offset; struct tm *tm; char idbuf[MAXQFNAME - 2]; - int seq; + unsigned int seq; if (e->e_id != NULL) return; /* see if we need to get a new base time/pid */ - if (cX >= QIC_LEN * QIC_LEN || LastQueueTime == 0 || - LastQueuePid != pid) + if (cX >= QIC_LEN_SQR || LastQueueTime == 0 || LastQueuePid != pid) { time_t then = LastQueueTime; /* if the first time through, pick a random offset */ if (LastQueueTime == 0) - random_offset = get_random(); + random_offset = ((unsigned int)get_random()) + % QIC_LEN_SQR; while ((LastQueueTime = curtime()) == then && LastQueuePid == pid) @@ -5368,16 +5388,16 @@ assign_queueid(e) } /* - ** Generate a new sequence number between 0 and QIC_LEN*QIC_LEN-1. - ** This lets us generate up to QIC_LEN*QIC_LEN unique queue ids + ** Generate a new sequence number between 0 and QIC_LEN_SQR-1. + ** This lets us generate up to QIC_LEN_SQR unique queue ids ** per second, per process. With envelope splitting, ** a single message can consume many queue ids. */ - seq = (int)((cX + random_offset) % (QIC_LEN * QIC_LEN)); + seq = (cX + random_offset) % QIC_LEN_SQR; ++cX; if (tTd(7, 50)) - sm_dprintf("assign_queueid: random_offset = %ld (%d)\n", + sm_dprintf("assign_queueid: random_offset=%u (%u)\n", random_offset, seq); tm = gmtime(&LastQueueTime); @@ -5430,6 +5450,7 @@ sync_queue_time() { #if FAST_PID_RECYCLE if (OpMode != MD_TEST && + OpMode != MD_CHECKCONFIG && OpMode != MD_VERIFY && LastQueueTime > 0 && LastQueuePid == CurrentPid && @@ -5740,6 +5761,10 @@ pickqdir(qg, fsize, e) else qdir = get_rand_mod(qg->qg_numqueues); +#if _FFR_TESTS + if (tTd(4, 101)) + return NOQDIR; +#endif /* _FFR_TESTS */ if (MinBlocksFree <= 0 && fsize <= 0) return qdir; @@ -6600,6 +6625,16 @@ init_sem(owner) (long) SemKey, SemId, sm_errstring(-SemId)); return; } + if (owner && RunAsUid != 0) + { + int r; + + r = sm_semsetowner(SemId, RunAsUid, RunAsGid, 0660); + if (r != 0) + sm_syslog(LOG_ERR, NOQID, + "key=%ld, sm_semsetowner=%d, RunAsUid=%d, RunAsGid=%d", + (long) SemKey, r, RunAsUid, RunAsGid); + } #endif /* SM_CONF_SEM */ #endif /* _FFR_USE_SEM_LOCKING */ return; @@ -8826,7 +8861,7 @@ quarantine_queue(reason, qgrplimit) if (StopRequest) stop_sendmail(); - nrequests = gatherq(qgrp, qdir, true, NULL, NULL); + nrequests = gatherq(qgrp, qdir, true, NULL, NULL, NULL); /* first see if there is anything */ if (nrequests <= 0) diff --git a/contrib/sendmail/src/ratectrl.c b/contrib/sendmail/src/ratectrl.c index 8b95b3753df..773955a6db0 100644 --- a/contrib/sendmail/src/ratectrl.c +++ b/contrib/sendmail/src/ratectrl.c @@ -45,7 +45,7 @@ */ #include -SM_RCSID("@(#)$Id: ratectrl.c,v 8.12 2008/02/11 22:56:05 ca Exp $") +SM_RCSID("@(#)$Id: ratectrl.c,v 8.13 2009/05/05 23:19:34 ca Exp $") /* ** stuff included - given some warnings (inet_ntoa) @@ -69,9 +69,6 @@ SM_RCSID("@(#)$Id: ratectrl.c,v 8.12 2008/02/11 22:56:05 ca Exp $") /* forward declarations */ static int client_rate __P((time_t, SOCKADDR *, bool)); static int total_rate __P((time_t, bool)); -#if 0 -static int sockaddrcmp __P((SOCKADDR *, SOCKADDR *)); -#endif /* 0 */ /* ** CONNECTION_RATE_CHECK - updates connection history data @@ -485,50 +482,3 @@ total_rate(now, update) return cnt; } - -#if 0 -/* -** SOCKADDRCMP - compare two SOCKADDR structures -** this function may be used to compare SOCKADDR -** structures when using bsearch and qsort functions -** in the same way we do with strcmp -** -** Parameters: -** a, b - addresses -** -** Returns: -** 1 if a > b -** -1 if a < b -** 0 if a = b -** -** OBS: This call isn't used at the moment, it will -** be used when code will be extended to work with IPV6 -*/ - -static int -sockaddrcmp(a, b) - SOCKADDR *a; - SOCKADDR *b; -{ - if (a->sa.sa_family > b->sa.sa_family) - return 1; - if (a->sa.sa_family < b->sa.sa_family) - return -1; - - switch (a->sa.sa_family) - { - case AF_INET: - if (a->sin.sin_addr.s_addr > b->sin.sin_addr.s_addr) - return 1; - if (a->sin.sin_addr.s_addr < b->sin.sin_addr.s_addr) - return -1; - return 0; - break; - - case AF_INET6: - /* TO BE DONE */ - break; - } - return 0; -} -#endif /* 0 */ diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c index 445df9e1068..c6d48a8cfea 100644 --- a/contrib/sendmail/src/readcf.c +++ b/contrib/sendmail/src/readcf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2006, 2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2006, 2008, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include #include -SM_RCSID("@(#)$Id: readcf.c,v 8.666 2008/02/14 17:25:14 ca Exp $") +SM_RCSID("@(#)$Id: readcf.c,v 8.674 2009/10/26 17:47:00 ca Exp $") #if NETINET || NETINET6 # include @@ -113,6 +113,9 @@ readcf(cfname, safe, e) FileName = cfname; LineNumber = 0; +#if STARTTLS + Srv_SSL_Options = Clt_SSL_Options = SSL_OP_ALL; +#endif /* STARTTLS */ if (DontLockReadFiles) sff |= SFF_NOLOCK; cf = safefopen(cfname, O_RDONLY, 0444, sff); @@ -136,7 +139,7 @@ readcf(cfname, safe, e) if (OpMode != MD_TEST && bitset(S_IWGRP|S_IWOTH, statb.st_mode)) { - if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS) + if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS || OpMode == MD_CHECKCONFIG) (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s: WARNING: dangerous write permissions\n", FileName); @@ -462,7 +465,7 @@ readcf(cfname, safe, e) rwp = RewriteRules[ruleset]; if (rwp != NULL) { - if (OpMode == MD_TEST) + if (OpMode == MD_TEST || OpMode == MD_CHECKCONFIG) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "WARNING: Ruleset %s has multiple definitions\n", @@ -534,7 +537,6 @@ readcf(cfname, safe, e) p++; while (isascii(*p) && isspace(*p)) p++; - file = p; } else optional = false; @@ -2255,10 +2257,101 @@ static struct optioninfo # define O_RCPTSHUTDG 0xe2 { "BadRcptShutdownGood", O_RCPTSHUTDG, OI_SAFE }, #endif /* _FFR_BADRCPT_SHUTDOWN */ +#if STARTTLS && _FFR_TLS_1 +# define O_SRV_SSL_OPTIONS 0xe3 + { "ServerSSLOptions", O_SRV_SSL_OPTIONS, OI_NONE }, +# define O_CLT_SSL_OPTIONS 0xe4 + { "ClientSSLOptions", O_CLT_SSL_OPTIONS, OI_NONE }, +#endif /* STARTTLS && _FFR_TLS_1 */ +#if _FFR_EXPDELAY +# define O_MAX_QUEUE_AGE 0xe5 + { "MaxQueueAge", O_MAX_QUEUE_AGE, OI_NONE }, +#endif /* _FFR_EXPDELAY */ +#if _FFR_RCPTTHROTDELAY +# define O_RCPTTHROTDELAY 0xe6 + { "BadRcptThrottleDelay", O_RCPTTHROTDELAY, OI_SAFE }, +#endif /* _FFR_RCPTTHROTDELAY */ { NULL, '\0', OI_NONE } }; +#if STARTTLS && _FFR_TLS_1 +static struct ssl_options +{ + const char *sslopt_name; /* name of the flag */ + long sslopt_bits; /* bits to set/clear */ +} SSL_Option[] = +{ +/* these are turned on by default */ +#ifdef SSL_OP_MICROSOFT_SESS_ID_BUG + { "SSL_OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG }, +#endif /* SSL_OP_MICROSOFT_SESS_ID_BUG */ +#ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG + { "SSL_OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG }, +#endif /* SSL_OP_NETSCAPE_CHALLENGE_BUG */ +#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG + { "SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG }, +#endif /* SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG */ +#ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG + { "SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG }, +#endif /* SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG */ +#ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER + { "SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER }, +#endif /* SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER */ +#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING + { "SSL_OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING }, +#endif /* SSL_OP_MSIE_SSLV2_RSA_PADDING */ +#ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG + { "SSL_OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG }, +#endif /* SSL_OP_SSLEAY_080_CLIENT_DH_BUG */ +#ifdef SSL_OP_TLS_D5_BUG + { "SSL_OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG }, +#endif /* SSL_OP_TLS_D5_BUG */ +#ifdef SSL_OP_TLS_BLOCK_PADDING_BUG + { "SSL_OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG }, +#endif /* SSL_OP_TLS_BLOCK_PADDING_BUG */ +#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + { "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS }, +#endif /* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */ + { "SSL_OP_ALL", SSL_OP_ALL }, +#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + { "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION }, +#endif /* SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION */ +#ifdef SSL_OP_EPHEMERAL_RSA + { "SSL_OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA }, +#endif /* SSL_OP_EPHEMERAL_RSA */ +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE + { "SSL_OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE }, +#endif /* SSL_OP_CIPHER_SERVER_PREFERENCE */ +#ifdef SSL_OP_TLS_ROLLBACK_BUG + { "SSL_OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG }, +#endif /* SSL_OP_TLS_ROLLBACK_BUG */ +#ifdef SSL_OP_NO_SSLv2 + { "SSL_OP_NO_SSLv2", SSL_OP_NO_SSLv2 }, +#endif /* SSL_OP_NO_SSLv2 */ +#ifdef SSL_OP_NO_SSLv3 + { "SSL_OP_NO_SSLv3", SSL_OP_NO_SSLv3 }, +#endif /* SSL_OP_NO_SSLv3 */ +#ifdef SSL_OP_NO_TLSv1 + { "SSL_OP_NO_TLSv1", SSL_OP_NO_TLSv1 }, +#endif /* SSL_OP_NO_TLSv1 */ +#ifdef SSL_OP_PKCS1_CHECK_1 + { "SSL_OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1 }, +#endif /* SSL_OP_PKCS1_CHECK_1 */ +#ifdef SSL_OP_PKCS1_CHECK_2 + { "SSL_OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2 }, +#endif /* SSL_OP_PKCS1_CHECK_2 */ +#ifdef SSL_OP_NETSCAPE_CA_DN_BUG + { "SSL_OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG }, +#endif /* SSL_OP_NETSCAPE_CA_DN_BUG */ +#ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG + { "SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG }, +#endif /* SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG */ + { NULL, 0 } +}; +#endif /* STARTTLS && _FFR_TLS_1 */ + + # define CANONIFY(val) # define SET_OPT_DEFAULT(opt, val) opt = val @@ -2299,6 +2392,9 @@ setoption(opt, val, safe, sticky, e) char *newval; char exbuf[MAXLINE]; #endif /* STARTTLS || SM_CONF_SHM */ +#if STARTTLS && _FFR_TLS_1 + long *pssloptions = NULL; +#endif /* STARTTLS && _FFR_TLS_1 */ errno = 0; if (opt == ' ') @@ -2995,6 +3091,12 @@ setoption(opt, val, safe, sticky, e) MinQueueAge = convtime(val, 'm'); break; +#if _FFR_EXPDELAY + case O_MAX_QUEUE_AGE: + MaxQueueAge = convtime(val, 'm'); + break; +#endif /* _FFR_EXPDELAY */ + case O_DEFCHARSET: /* default character set for mimefying */ DefaultCharSet = newstr(denlstring(val, true, true)); break; @@ -3317,6 +3419,12 @@ setoption(opt, val, safe, sticky, e) BadRcptThrottle = atoi(val); break; +#if _FFR_RCPTTHROTDELAY + case O_RCPTTHROTDELAY: + BadRcptThrottleDelay = atoi(val); + break; +#endif /* _FFR_RCPTTHROTDELAY */ + case O_DEADLETTER: CANONIFY(val); PSTRSET(DeadLetterDrop, val); @@ -3578,7 +3686,51 @@ setoption(opt, val, safe, sticky, e) SET_STRING_EXP(DHParams5); case O_CIPHERLIST: SET_STRING_EXP(CipherList); + case O_SRV_SSL_OPTIONS: + pssloptions = &Srv_SSL_Options; + case O_CLT_SSL_OPTIONS: + if (pssloptions == NULL) + pssloptions = &Clt_SSL_Options; + for (p = val; *p != 0; ) + { + bool clearmode; + char *q; + struct ssl_options *sslopts; + + while (*p == ' ') + p++; + if (*p == '\0') + break; + clearmode = false; + if (*p == '-' || *p == '+') + clearmode = *p++ == '-'; + q = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p++ = '\0'; + for (sslopts = SSL_Option; + sslopts->sslopt_name != NULL; sslopts++) + { + if (sm_strcasecmp(q, sslopts->sslopt_name) == 0) + break; + } + if (sslopts->sslopt_name == NULL) + { + errno = 0; + syserr("readcf: %s option value %s unrecognized", + o->o_name, q); + } + else if (clearmode) + *pssloptions &= ~sslopts->sslopt_bits; + else + *pssloptions |= sslopts->sslopt_bits; + } + pssloptions = NULL; + break; + # endif /* _FFR_TLS_1 */ + case O_CRLFILE: # if OPENSSL_VERSION_NUMBER > 0x00907000L SET_STRING_EXP(CRLFile); @@ -4026,8 +4178,7 @@ strtorwset(p, endp, stabmode) char *q = NULL; q = p; - while (*p != '\0' && isascii(*p) && - (isalnum(*p) || *p == '_')) + while (*p != '\0' && isascii(*p) && (isalnum(*p) || *p == '_')) p++; if (q == p || !(isascii(*q) && isalpha(*q))) { diff --git a/contrib/sendmail/src/savemail.c b/contrib/sendmail/src/savemail.c index cf72e8d497e..4178245cc5a 100644 --- a/contrib/sendmail/src/savemail.c +++ b/contrib/sendmail/src/savemail.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: savemail.c,v 8.313 2006/11/29 00:20:41 ca Exp $") +SM_RCSID("@(#)$Id: savemail.c,v 8.314 2009/12/18 17:08:01 ca Exp $") static bool errbody __P((MCI *, ENVELOPE *, char *)); static bool pruneroute __P((char *)); @@ -705,7 +705,7 @@ returntosender(msg, returnq, flags, e) sendall(ee, SM_DELIVER); /* restore state */ - dropenvelope(ee, true, false); + (void) dropenvelope(ee, true, false); sm_rpool_free(ee->e_rpool); CurEnv = oldcur; returndepth--; diff --git a/contrib/sendmail/src/sendmail.8 b/contrib/sendmail/src/sendmail.8 index 540d55480ae..e5ce9aeef9d 100644 --- a/contrib/sendmail/src/sendmail.8 +++ b/contrib/sendmail/src/sendmail.8 @@ -9,9 +9,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: sendmail.8,v 8.58 2007/08/02 05:42:33 ca Exp $ +.\" $Id: sendmail.8,v 8.59 2009/04/10 17:49:19 gshapiro Exp $ .\" -.TH SENDMAIL 8 "$Date: 2007/08/02 05:42:33 $" +.TH SENDMAIL 8 "$Date: 2009/04/10 17:49:19 $" .SH NAME sendmail \- an electronic mail transport agent @@ -741,6 +741,8 @@ Internet Request For Comments No. 8, SMM. .PP http://www.sendmail.org/ +.PP +US Patent Numbers 6865671, 6986037. .SH HISTORY The .B sendmail diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h index b6b231d844e..b170c2bbb3d 100644 --- a/contrib/sendmail/src/sendmail.h +++ b/contrib/sendmail/src/sendmail.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -52,7 +52,7 @@ #ifdef _DEFINE # ifndef lint -SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1059 2008/02/15 23:19:58 ca Exp $"; +SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1068 2009/12/18 17:08:01 ca Exp $"; # endif /* ! lint */ #endif /* _DEFINE */ @@ -607,7 +607,7 @@ extern bool filesys_free __P((long)); ERROR: change SASL_SEC_MASK_ notify sendmail.org! # endif /* SASL_SEC_NOPLAINTEXT & SASL_SEC_MASK) == 0 ... */ # endif /* SASL >= 20101 */ -# define MAXOUTLEN 8192 /* length of output buffer */ +# define MAXOUTLEN 8192 /* length of output buffer, should be 2^n */ /* functions */ extern char *intersect __P((char *, char *, SM_RPOOL_T *)); @@ -931,6 +931,10 @@ struct envelope int e_dlvr_flag; /* deliver by flag */ SM_RPOOL_T *e_rpool; /* resource pool for this envelope */ unsigned int e_features; /* server features */ +#if _FFR_MILTER_ENHSC +#define ENHSC_LEN 11 + char e_enhsc[ENHSC_LEN]; /* enhanced status code */ +#endif /* _FFR_MILTER_ENHSC */ }; /* values for e_flags */ @@ -982,7 +986,7 @@ extern ENVELOPE BlankEnvelope; /* functions */ extern void clearenvelope __P((ENVELOPE *, bool, SM_RPOOL_T *)); -extern void dropenvelope __P((ENVELOPE *, bool, bool)); +extern int dropenvelope __P((ENVELOPE *, bool, bool)); extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *, SM_RPOOL_T *)); extern void clrsessenvelope __P((ENVELOPE *)); extern void printenvflags __P((ENVELOPE *)); @@ -1561,6 +1565,7 @@ extern void stabapply __P((void (*)(STAB *, int), int)); #define MD_HOSTSTAT 'h' /* print persistent host stat info */ #define MD_PURGESTAT 'H' /* purge persistent host stat info */ #define MD_QUEUERUN 'q' /* queue run */ +#define MD_CHECKCONFIG 'C' /* check configuration file */ #if _FFR_LOCAL_DAEMON EXTERN bool LocalDaemon; @@ -1880,7 +1885,7 @@ struct termescape /* functions */ extern bool init_tls_library __P((void)); -extern bool inittls __P((SSL_CTX **, unsigned long, bool, char *, char *, char *, char *, char *)); +extern bool inittls __P((SSL_CTX **, unsigned long, long, bool, char *, char *, char *, char *, char *)); extern bool initclttls __P((bool)); extern void setclttls __P((bool)); extern bool initsrvtls __P((bool)); @@ -1906,6 +1911,7 @@ EXTERN char *CRLFile; /* file CRLs */ EXTERN char *CRLPath; /* path to CRLs (dir. with hashes) */ #endif /* _FFR_CRLPATH */ EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */ +EXTERN long Srv_SSL_Options, Clt_SSL_Options; /* SSL options */ #endif /* STARTTLS */ /* @@ -1986,6 +1992,9 @@ EXTERN int QueueFileMode; /* mode on files in mail queue */ EXTERN int QueueMode; /* which queue items to act upon */ EXTERN int QueueSortOrder; /* queue sorting order algorithm */ EXTERN time_t MinQueueAge; /* min delivery interval */ +#if _FFR_EXPDELAY +EXTERN time_t MaxQueueAge; /* max delivery interval */ +#endif /* _FFR_EXPDELAY */ EXTERN time_t QueueIntvl; /* intervals between running the queue */ EXTERN char *QueueDir; /* location of queue directory */ EXTERN QUEUE_CHAR *QueueLimitId; /* limit queue run to id */ @@ -2235,11 +2244,16 @@ EXTERN bool UseNameServer; /* using DNS -- interpret h_errno & MX RRs */ EXTERN char InetMode; /* default network for daemon mode */ EXTERN char OpMode; /* operation mode, see below */ EXTERN char SpaceSub; /* substitution for */ -EXTERN int BadRcptThrottle; /* Throttle rejected RCPTs per SMTP message */ #if _FFR_BADRCPT_SHUTDOWN EXTERN int BadRcptShutdown; /* Shutdown connection for rejected RCPTs */ EXTERN int BadRcptShutdownGood; /* above even when there are good RCPTs */ #endif /* _FFR_BADRCPT_SHUTDOWN */ +EXTERN int BadRcptThrottle; /* Throttle rejected RCPTs per SMTP message */ +#if _FFR_RCPTTHROTDELAY +EXTERN unsigned int BadRcptThrottleDelay; /* delay for BadRcptThrottle */ +#else +# define BadRcptThrottleDelay 1 +#endif /* _FFR_RCPTTHROTDELAY */ EXTERN int CheckpointInterval; /* queue file checkpoint interval */ EXTERN int ConfigLevel; /* config file level */ EXTERN int ConnRateThrottle; /* throttle for SMTP connection rate */ diff --git a/contrib/sendmail/src/sfsasl.c b/contrib/sendmail/src/sfsasl.c index 67e919f34df..cad16db1686 100644 --- a/contrib/sendmail/src/sfsasl.c +++ b/contrib/sendmail/src/sfsasl.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: sfsasl.c,v 8.117 2008/01/31 18:48:29 ca Exp $") +SM_RCSID("@(#)$Id: sfsasl.c,v 8.118 2008/07/22 15:12:48 ca Exp $") #include #include #include @@ -296,7 +296,7 @@ sasl_write(fp, buf, size) /* ** Fetch the maximum input buffer size for sasl_encode(). ** This can be less than the size set in attemptauth() - ** due to a negotation with the other side, e.g., + ** due to a negotiation with the other side, e.g., ** Cyrus IMAP lmtp program sets maxbuf=4096, ** digestmd5 substracts 25 and hence we'll get 4071 ** instead of 8192 (MAXOUTLEN). diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c index fffcd0d37ab..49016e4572b 100644 --- a/contrib/sendmail/src/srvrsmtp.c +++ b/contrib/sendmail/src/srvrsmtp.c @@ -17,7 +17,7 @@ # include #endif /* MILTER */ -SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.975 2008/03/31 16:32:13 ca Exp $") +SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.989 2009/12/18 17:08:01 ca Exp $") #include #include @@ -479,6 +479,9 @@ do \ e->e_sendqueue = NULL; \ e->e_flags |= EF_CLRQUEUE; \ \ + if (tTd(92, 2)) \ + sm_dprintf("CLEAR_STATE: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",\ + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel);\ if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) \ logsender(e, NULL); \ e->e_flags &= ~EF_LOGSENDER; \ @@ -486,7 +489,7 @@ do \ /* clean up a bit */ \ smtp.sm_gotmail = false; \ SuprErrs = true; \ - dropenvelope(e, true, false); \ + (void) dropenvelope(e, true, false); \ sm_rpool_free(e->e_rpool); \ e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL)); \ CurEnv = e; \ @@ -906,6 +909,16 @@ smtp(nullserver, d_flags, e) #endif /* SASL */ #if STARTTLS +# if USE_OPENSSL_ENGINE + if (tls_ok_srv && bitset(SRV_OFFER_TLS, features) && + !SSL_set_engine(NULL)) + { + sm_syslog(LOG_ERR, NOQID, + "STARTTLS=server, SSL_set_engine=failed"); + tls_ok_srv = false; + } +# endif /* USE_OPENSSL_ENGINE */ + set_tls_rd_tmo(TimeOuts.to_nextcommand); #endif /* STARTTLS */ @@ -1272,7 +1285,8 @@ smtp(nullserver, d_flags, e) { if (++np_log < 3) sm_syslog(LOG_INFO, NOQID, - "unauthorized PIPELINING, sleeping"); + "unauthorized PIPELINING, sleeping, relay=%.100s", + CurSmtpClient); sleep(1); } @@ -1447,8 +1461,9 @@ smtp(nullserver, d_flags, e) message("454 4.5.4 Internal error: unable to encode64"); if (LogLevel > 5) sm_syslog(LOG_WARNING, e->e_id, - "AUTH encode64 error [%d for \"%s\"]", - result, out); + "AUTH encode64 error [%d for \"%s\"], relay=%.100s", + result, out, + CurSmtpClient); /* start over? */ authenticating = SASL_NOT_AUTH; } @@ -1469,16 +1484,17 @@ smtp(nullserver, d_flags, e) message("535 5.7.0 authentication failed"); if (LogLevel > 9) sm_syslog(LOG_WARNING, e->e_id, - "AUTH failure (%s): %s (%d) %s", + "AUTH failure (%s): %s (%d) %s, relay=%.100s", auth_type, sasl_errstring(result, NULL, NULL), result, # if SASL >= 20000 - sasl_errdetail(conn)); + sasl_errdetail(conn), # else /* SASL >= 20000 */ - errstr == NULL ? "" : errstr); + errstr == NULL ? "" : errstr, # endif /* SASL >= 20000 */ + CurSmtpClient); RESET_SASLCONN; authenticating = SASL_NOT_AUTH; } @@ -1700,8 +1716,9 @@ smtp(nullserver, d_flags, e) q); if (LogLevel > 5) sm_syslog(LOG_WARNING, e->e_id, - "AUTH decode64 error [%d for \"%s\"]", - result, q); + "AUTH decode64 error [%d for \"%s\"], relay=%.100s", + result, q, + CurSmtpClient); /* start over? */ authenticating = SASL_NOT_AUTH; # if SASL >= 20000 @@ -1734,16 +1751,17 @@ smtp(nullserver, d_flags, e) message("535 5.7.0 authentication failed"); if (LogLevel > 9) sm_syslog(LOG_ERR, e->e_id, - "AUTH failure (%s): %s (%d) %s", + "AUTH failure (%s): %s (%d) %s, relay=%.100s", p, sasl_errstring(result, NULL, NULL), result, # if SASL >= 20000 - sasl_errdetail(conn)); + sasl_errdetail(conn), # else /* SASL >= 20000 */ - errstr); + errstr, # endif /* SASL >= 20000 */ + CurSmtpClient); RESET_SASLCONN; break; } @@ -1893,8 +1911,9 @@ smtp(nullserver, d_flags, e) if (LogLevel > 5) { sm_syslog(LOG_WARNING, NOQID, - "STARTTLS=server, error: accept failed=%d, SSL_error=%d, errno=%d, retry=%d", - r, ssl_err, errno, i); + "STARTTLS=server, error: accept failed=%d, SSL_error=%d, errno=%d, retry=%d, relay=%.100s", + r, ssl_err, errno, i, + CurSmtpClient); if (LogLevel > 8) tlslogerr("server"); } @@ -2532,7 +2551,7 @@ smtp(nullserver, d_flags, e) #if _FFR_BADRCPT_SHUTDOWN /* ** hack to deal with hack, see below: - ** n_badrcpts is increased is limit is reached. + ** n_badrcpts is increased if limit is reached. */ n_badrcpts_adj = (BadRcptThrottle > 0 && @@ -2576,12 +2595,12 @@ smtp(nullserver, d_flags, e) /* ** Don't use exponential backoff for now. - ** Some servers will open more connections + ** Some systems will open more connections ** and actually overload the receiver even ** more. */ - (void) sleep(1); + (void) sleep(BadRcptThrottleDelay); } if (!smtp.sm_gotmail) { @@ -3147,6 +3166,11 @@ doquit: milter_quit(e); #endif /* MILTER */ + if (tTd(92, 2)) + sm_dprintf("QUIT: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", + e->e_id, + bitset(EF_LOGSENDER, e->e_flags), + LogLevel); if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) logsender(e, NULL); e->e_flags &= ~EF_LOGSENDER; @@ -3358,6 +3382,11 @@ smtp_data(smtp, e) response); LogUsrErrs = false; } +#if _FFR_MILTER_ENHSC + if (ISSMTPCODE(response)) + (void) extenhsc(response + 4, ' ', e->e_enhsc); +#endif /* _FFR_MILTER_ENHSC */ + usrerr(response); if (strncmp(response, "421 ", 4) == 0 || strncmp(response, "421-", 4) == 0) @@ -3374,6 +3403,10 @@ smtp_data(smtp, e) "Milter: cmd=data, reject=550 5.7.1 Command rejected"); LogUsrErrs = false; } +#if _FFR_MILTER_ENHSC + (void) sm_strlcpy(e->e_enhsc, "5.7.1", + sizeof(e->e_enhsc)); +#endif /* _FFR_MILTER_ENHSC */ usrerr("550 5.7.1 Command rejected"); return true; @@ -3392,6 +3425,9 @@ smtp_data(smtp, e) MSG_TEMPFAIL); LogUsrErrs = false; } +#if _FFR_MILTER_ENHSC + (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc); +#endif /* _FFR_MILTER_ENHSC */ usrerr(MSG_TEMPFAIL); return true; @@ -3467,7 +3503,14 @@ smtp_data(smtp, e) "Milter: data, reject=%s", response); milteraccept = false; +#if _FFR_MILTER_ENHSC + if (ISSMTPCODE(response)) + (void) extenhsc(response + 4, ' ', e->e_enhsc); +#endif /* _FFR_MILTER_ENHSC */ usrerr(response); + if (strncmp(response, "421 ", 4) == 0 + || strncmp(response, "421-", 4) == 0) + rv = false; break; case SMFIR_REJECT: @@ -3492,6 +3535,9 @@ smtp_data(smtp, e) "Milter: data, reject=%s", MSG_TEMPFAIL); milteraccept = false; +#if _FFR_MILTER_ENHSC + (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc); +#endif /* _FFR_MILTER_ENHSC */ usrerr(MSG_TEMPFAIL); break; @@ -3782,6 +3828,9 @@ smtp_data(smtp, e) } abortmessage: + if (tTd(92, 2)) + sm_dprintf("abortmessage: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) logsender(e, NULL); e->e_flags &= ~EF_LOGSENDER; @@ -3795,7 +3844,7 @@ smtp_data(smtp, e) */ if (aborting || bitset(EF_DISCARD, e->e_flags)) - dropenvelope(e, true, false); + (void) dropenvelope(e, true, false); else { for (ee = e; ee != NULL; ee = ee->e_sibling) @@ -3804,11 +3853,11 @@ smtp_data(smtp, e) QueueMode != QM_QUARANTINE && ee->e_quarmsg != NULL) { - dropenvelope(ee, true, false); + (void) dropenvelope(ee, true, false); continue; } if (WILL_BE_QUEUED(ee->e_sendmode)) - dropenvelope(ee, true, false); + (void) dropenvelope(ee, true, false); } } @@ -3870,8 +3919,13 @@ logundelrcpts(e, msg, level, all) if (!QS_IS_UNDELIVERED(a->q_state) && !all) continue; e->e_to = a->q_paddr; - logdelivery(NULL, NULL, a->q_status, msg, NULL, - (time_t) 0, e); + logdelivery(NULL, NULL, +#if _FFR_MILTER_ENHSC + (a->q_status == NULL && e->e_enhsc[0] != '\0') + ? e->e_enhsc : +#endif /* _FFR_MILTER_ENHSC */ + a->q_status, + msg, NULL, (time_t) 0, e); } e->e_to = NULL; } @@ -4692,8 +4746,9 @@ initsrvtls(tls_ok) return false; /* do NOT remove assignment */ - tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, true, SrvCertFile, - SrvKeyFile, CACertPath, CACertFile, DHParams); + tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, Srv_SSL_Options, true, + SrvCertFile, SrvKeyFile, + CACertPath, CACertFile, DHParams); return tls_ok_srv; } #endif /* STARTTLS */ diff --git a/contrib/sendmail/src/tls.c b/contrib/sendmail/src/tls.c index 1a213cab68e..70319944950 100644 --- a/contrib/sendmail/src/tls.c +++ b/contrib/sendmail/src/tls.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2006 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2006, 2008, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ #include -SM_RCSID("@(#)$Id: tls.c,v 8.107 2006/10/12 21:35:11 ca Exp $") +SM_RCSID("@(#)$Id: tls.c,v 8.114 2009/08/10 15:11:09 ca Exp $") #if STARTTLS # include @@ -486,6 +486,7 @@ tls_safe_f(var, sff, srv) ** Parameters: ** ctx -- pointer to context ** req -- requirements for initialization (see sendmail.h) +** options -- options ** srv -- server side? ** certfile -- filename of certificate ** keyfile -- filename of private key @@ -514,9 +515,10 @@ static char server_session_id_context[] = "sendmail8"; #endif bool -inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) +inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) SSL_CTX **ctx; unsigned long req; + long options; bool srv; char *certfile, *keyfile, *cacertpath, *cacertfile, *dhparam; { @@ -525,7 +527,7 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) # endif /* !NO_DH */ int r; bool ok; - long sff, status, options; + long sff, status; char *who; # if _FFR_TLS_1 char *cf2, *kf2; @@ -643,7 +645,10 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) } } if (dhparam == NULL) + { dhparam = srv ? "1" : "5"; + req |= (srv ? TLS_I_DH1024 : TLS_I_DH512); + } else if (*dhparam == '/') { TLS_OK_F(dhparam, "DHParameters", @@ -913,7 +918,6 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) /* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */ - options = SSL_OP_ALL; /* bug compatibility? */ #if SM_SSL_OP_TLS_BLOCK_PADDING_BUG /* @@ -1196,23 +1200,62 @@ tls_get_info(ssl, srv, host, mac, certreq) if (cert != NULL) { unsigned int n; + X509_NAME *subj, *issuer; unsigned char md[EVP_MAX_MD_SIZE]; char buf[MAXNAME]; - X509_NAME_oneline(X509_get_subject_name(cert), - buf, sizeof(buf)); + subj = X509_get_subject_name(cert); + issuer = X509_get_issuer_name(cert); + X509_NAME_oneline(subj, buf, sizeof(buf)); macdefine(mac, A_TEMP, macid("{cert_subject}"), xtextify(buf, "<>\")")); - X509_NAME_oneline(X509_get_issuer_name(cert), - buf, sizeof(buf)); + X509_NAME_oneline(issuer, buf, sizeof(buf)); macdefine(mac, A_TEMP, macid("{cert_issuer}"), xtextify(buf, "<>\")")); - X509_NAME_get_text_by_NID(X509_get_subject_name(cert), - NID_commonName, buf, sizeof(buf)); + +#define CHECK_X509_NAME(which) \ + do { \ + if (r == -1) \ + { \ + sm_strlcpy(buf, "BadCertificateUnknown", sizeof(buf)); \ + if (LogLevel > 7) \ + sm_syslog(LOG_INFO, NOQID, \ + "STARTTLS=%s, relay=%.100s, field=%s, status=failed to extract CN", \ + who, \ + host == NULL ? "local" : host, \ + which); \ + } \ + else if ((size_t)r >= sizeof(buf) - 1) \ + { \ + sm_strlcpy(buf, "BadCertificateTooLong", sizeof(buf)); \ + if (LogLevel > 7) \ + sm_syslog(LOG_INFO, NOQID, \ + "STARTTLS=%s, relay=%.100s, field=%s, status=CN too long", \ + who, \ + host == NULL ? "local" : host, \ + which); \ + } \ + else if ((size_t)r > strlen(buf)) \ + { \ + sm_strlcpy(buf, "BadCertificateContainsNUL", \ + sizeof(buf)); \ + if (LogLevel > 7) \ + sm_syslog(LOG_INFO, NOQID, \ + "STARTTLS=%s, relay=%.100s, field=%s, status=CN contains NUL", \ + who, \ + host == NULL ? "local" : host, \ + which); \ + } \ + } while (0) + + r = X509_NAME_get_text_by_NID(subj, NID_commonName, buf, + sizeof buf); + CHECK_X509_NAME("cn_subject"); macdefine(mac, A_TEMP, macid("{cn_subject}"), xtextify(buf, "<>\")")); - X509_NAME_get_text_by_NID(X509_get_issuer_name(cert), - NID_commonName, buf, sizeof(buf)); + r = X509_NAME_get_text_by_NID(issuer, NID_commonName, buf, + sizeof buf); + CHECK_X509_NAME("cn_issuer"); macdefine(mac, A_TEMP, macid("{cn_issuer}"), xtextify(buf, "<>\")")); n = 0; @@ -1596,14 +1639,19 @@ tls_verify_cb(ctx, unused) { int ok; + /* + ** man SSL_CTX_set_cert_verify_callback(): + ** callback should return 1 to indicate verification success + ** and 0 to indicate verification failure. + */ + ok = X509_verify_cert(ctx); - if (ok == 0) + if (ok <= 0) { if (LogLevel > 13) return tls_verify_log(ok, ctx, "TLS"); - return 1; /* override it */ } - return ok; + return 1; } /* ** TLSLOGERR -- log the errors from the TLS error stack diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c index b29495c3ae7..23278b0b59d 100644 --- a/contrib/sendmail/src/usersmtp.c +++ b/contrib/sendmail/src/usersmtp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2006, 2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2006, 2008, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: usersmtp.c,v 8.472 2008/01/31 18:48:29 ca Exp $") +SM_RCSID("@(#)$Id: usersmtp.c,v 8.473 2009/06/17 17:26:51 ca Exp $") #include @@ -1568,7 +1568,9 @@ attemptauth(m, mci, e, sai) sasl_interact_t *client_interact = NULL; char *mechusing; sasl_security_properties_t ssp; - char in64[MAXOUTLEN]; + + /* MUST NOT be a multiple of 4: bug in some sasl_encode64() versions */ + char in64[MAXOUTLEN + 1]; #if NETINET || (NETINET6 && SASL >= 20000) extern SOCKADDR CurHostAddr; #endif /* NETINET || (NETINET6 && SASL >= 20000) */ @@ -1770,7 +1772,8 @@ attemptauth(m, mci, e, sai) } else { - saslresult = sasl_encode64(out, outlen, in64, MAXOUTLEN, NULL); + saslresult = sasl_encode64(out, outlen, in64, sizeof(in64), + NULL); if (saslresult != SASL_OK) /* internal error */ { if (LogLevel > 8) @@ -1837,7 +1840,7 @@ attemptauth(m, mci, e, sai) if (outlen > 0) { saslresult = sasl_encode64(out, outlen, in64, - MAXOUTLEN, NULL); + sizeof(in64), NULL); if (saslresult != SASL_OK) { /* give an error reply to the other side! */ diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c index dab59613050..ab491fbfe52 100644 --- a/contrib/sendmail/src/util.c +++ b/contrib/sendmail/src/util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2007, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: util.c,v 8.414 2007/11/02 17:30:38 ca Exp $") +SM_RCSID("@(#)$Id: util.c,v 8.416 2009/12/18 17:05:26 ca Exp $") #include #include @@ -868,7 +868,7 @@ xputs(fp, s) c &= 0177; } printchar: - if (isprint(c)) + if (isascii(c) && isprint(c)) { (void) sm_io_putc(fp, SM_TIME_DEFAULT, c); continue; @@ -895,7 +895,7 @@ xputs(fp, s) TermEscape.te_rv_on); shiftout = true; } - if (isprint(c)) + if (isascii(c) && isprint(c)) { (void) sm_io_putc(fp, SM_TIME_DEFAULT, '\\'); (void) sm_io_putc(fp, SM_TIME_DEFAULT, c); diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c index 3e5ee8e6fdc..cb94d0f2c57 100644 --- a/contrib/sendmail/src/version.c +++ b/contrib/sendmail/src/version.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,6 +13,6 @@ #include -SM_RCSID("@(#)$Id: version.c,v 8.208 2008/04/17 17:04:30 ca Exp $") +SM_RCSID("@(#)$Id: version.c,v 8.218 2009/12/23 04:43:09 ca Exp $") -char Version[] = "8.14.3"; +char Version[] = "8.14.4"; diff --git a/contrib/sendmail/vacation/vacation.c b/contrib/sendmail/vacation/vacation.c index 10712b8ed8b..2ead0b86cbe 100644 --- a/contrib/sendmail/vacation/vacation.c +++ b/contrib/sendmail/vacation/vacation.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2002, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1987, 1993 * The Regents of the University of California. All rights reserved. @@ -14,13 +14,13 @@ #include SM_IDSTR(copyright, -"@(#) Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.\n\ +"@(#) Copyright (c) 1999-2002, 2009 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1983, 1987, 1993\n\ The Regents of the University of California. All rights reserved.\n\ Copyright (c) 1983 Eric P. Allman. All rights reserved.\n") -SM_IDSTR(id, "@(#)$Id: vacation.c,v 8.144 2007/05/11 18:50:36 ca Exp $") +SM_IDSTR(id, "@(#)$Id: vacation.c,v 8.146 2009/08/07 21:28:39 ca Exp $") #include @@ -153,7 +153,7 @@ main(argc, argv) char *dbfilename = NULL; char *msgfilename = NULL; char *cfpath = NULL; - char *name; + char *name = NULL; char *returnaddr = NULL; SMDB_USER_INFO user_info; static char rnamebuf[MAXNAME]; @@ -299,7 +299,7 @@ main(argc, argv) "vacation: no such user uid %u.\n", getuid()); EXITM(EX_NOUSER); } - name = pw->pw_name; + name = strdup(pw->pw_name); user_info.smdbu_id = pw->pw_uid; user_info.smdbu_group_id = pw->pw_gid; (void) sm_strlcpy(user_info.smdbu_name, pw->pw_name, @@ -314,7 +314,7 @@ main(argc, argv) } else if (runasuser) { - name = *argv; + name = strdup(*argv); if (dbfilename == NULL || msgfilename == NULL) { msglog(LOG_NOTICE, @@ -358,7 +358,7 @@ main(argc, argv) sm_strexit(err)); EXITM(err); } - name = user.mbdb_name; + name = strdup(user.mbdb_name); if (chdir(user.mbdb_homedir) != 0) { msglog(LOG_NOTICE, @@ -371,6 +371,12 @@ main(argc, argv) (void) sm_strlcpy(user_info.smdbu_name, user.mbdb_name, SMDB_MAX_USER_NAME_LEN); } + if (name == NULL) + { + msglog(LOG_ERR, + "vacation: can't allocate memory for username.\n"); + EXITM(EX_OSERR); + } if (dbfilename == NULL) dbfilename = VDB; @@ -1032,6 +1038,14 @@ sendmessage(myname, msgfn, sender) (void *) &(pvect[1]), SM_IO_WRONLY, NULL)) != NULL) { +#if _FFR_VAC_WAIT4SM +# ifdef WAITUNION + union wait st; +# else /* WAITUNION */ + auto int st; +# endif /* WAITUNION */ +#endif /* _FFR_VAC_WAIT4SM */ + (void) sm_io_fprintf(sfp, SM_TIME_DEFAULT, "To: %s\n", From); (void) sm_io_fprintf(sfp, SM_TIME_DEFAULT, "Auto-Submitted: auto-replied\n"); @@ -1039,6 +1053,9 @@ sendmessage(myname, msgfn, sender) (void) sm_io_fputs(sfp, SM_TIME_DEFAULT, buf); (void) sm_io_close(mfp, SM_TIME_DEFAULT); (void) sm_io_close(sfp, SM_TIME_DEFAULT); +#if _FFR_VAC_WAIT4SM + (void) wait(&st); +#endif /* _FFR_VAC_WAIT4SM */ } else { From a41da5f1033d6a81a8e6dca88c2a57250b1db6c6 Mon Sep 17 00:00:00 2001 From: Gregory Neil Shapiro Date: Sun, 31 Jan 2010 19:00:39 +0000 Subject: [PATCH 1346/2592] MFC: Update FreeBSD information --- contrib/sendmail/FREEBSD-upgrade | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/sendmail/FREEBSD-upgrade b/contrib/sendmail/FREEBSD-upgrade index 670c6d6faa0..5d4cf6512e9 100644 --- a/contrib/sendmail/FREEBSD-upgrade +++ b/contrib/sendmail/FREEBSD-upgrade @@ -1,6 +1,6 @@ $FreeBSD$ -sendmail 8.14.3 +sendmail 8.14.4 originals can be found at: ftp://ftp.sendmail.org/pub/sendmail/ For the import of sendmail, the following directories were renamed: @@ -110,4 +110,4 @@ infrastructure in FreeBSD: usr.sbin/mailwrapper/Makefile gshapiro@FreeBSD.org -27-August-2008 +25-January-2010 From 33978ef79db48dfae8d33ef0c3f6ba5ccf03d7e2 Mon Sep 17 00:00:00 2001 From: Gregory Neil Shapiro Date: Sun, 31 Jan 2010 19:04:52 +0000 Subject: [PATCH 1347/2592] MFC: Minor changes to force commit these files so new freebsd*.cf files are built to use the new sendmail-8.14.4/cf tree. --- etc/sendmail/freebsd.mc | 2 +- etc/sendmail/freebsd.submit.mc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/etc/sendmail/freebsd.mc b/etc/sendmail/freebsd.mc index b6b02c2d094..4bf41a56340 100644 --- a/etc/sendmail/freebsd.mc +++ b/etc/sendmail/freebsd.mc @@ -34,7 +34,7 @@ divert(-1) # # -# This is a generic configuration file for FreeBSD 5.X and later systems. +# This is a generic configuration file for FreeBSD 6.X and later systems. # If you want to customize it, copy it to a name appropriate for your # environment and do the modifications there. # diff --git a/etc/sendmail/freebsd.submit.mc b/etc/sendmail/freebsd.submit.mc index c6ec6555359..0fd8d63237a 100644 --- a/etc/sendmail/freebsd.submit.mc +++ b/etc/sendmail/freebsd.submit.mc @@ -25,3 +25,4 @@ define(`confBIND_OPTS', `WorkAroundBrokenAAAA')dnl dnl dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:::1] FEATURE(`msp', `[127.0.0.1]')dnl + From b8370f7d4206dec461a46ef7c45d316feebf0f18 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Sun, 31 Jan 2010 19:41:58 +0000 Subject: [PATCH 1348/2592] Merge r202931 from head: Add support for four more nfsmb controllers, shipping on at least the ASUS Atom ION boards. PR: kern/142571 Submitted by: oliver Approved by: ed (mentor, implicit) --- sys/pci/nfsmb.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sys/pci/nfsmb.c b/sys/pci/nfsmb.c index ce3753f08f4..a178ae36235 100644 --- a/sys/pci/nfsmb.c +++ b/sys/pci/nfsmb.c @@ -65,6 +65,10 @@ static int nfsmb_debug = 0; #define NFSMB_DEVICEID_NF4_55_SMB 0x0368 #define NFSMB_DEVICEID_NF4_61_SMB 0x03eb #define NFSMB_DEVICEID_NF4_65_SMB 0x0446 +#define NFSMB_DEVICEID_NF4_67_SMB 0x0542 +#define NFSMB_DEVICEID_NF4_73_SMB 0x07d8 +#define NFSMB_DEVICEID_NF4_78S_SMB 0x0752 +#define NFSMB_DEVICEID_NF4_79_SMB 0x0aa2 /* PCI Configuration space registers */ #define NF2PCI_SMBASE_1 PCIR_BAR(4) @@ -158,6 +162,10 @@ nfsmb_probe(device_t dev) case NFSMB_DEVICEID_NF4_55_SMB: case NFSMB_DEVICEID_NF4_61_SMB: case NFSMB_DEVICEID_NF4_65_SMB: + case NFSMB_DEVICEID_NF4_67_SMB: + case NFSMB_DEVICEID_NF4_73_SMB: + case NFSMB_DEVICEID_NF4_78S_SMB: + case NFSMB_DEVICEID_NF4_79_SMB: device_set_desc(dev, "nForce2/3/4 MCP SMBus Controller"); return (BUS_PROBE_DEFAULT); } @@ -245,6 +253,10 @@ nfsmb_attach(device_t dev) case NFSMB_DEVICEID_NF4_55_SMB: case NFSMB_DEVICEID_NF4_61_SMB: case NFSMB_DEVICEID_NF4_65_SMB: + case NFSMB_DEVICEID_NF4_67_SMB: + case NFSMB_DEVICEID_NF4_73_SMB: + case NFSMB_DEVICEID_NF4_78S_SMB: + case NFSMB_DEVICEID_NF4_79_SMB: /* Trying to add secondary device as slave */ nfsmb_sc->subdev = device_add_child(dev, "nfsmb", -1); if (!nfsmb_sc->subdev) { From adf302d928a45c9970ae76a087fc6a81e1d6291e Mon Sep 17 00:00:00 2001 From: Gregory Neil Shapiro Date: Sun, 31 Jan 2010 19:57:28 +0000 Subject: [PATCH 1349/2592] Note sendmail 8.14.4 upgrade. --- release/doc/en_US.ISO8859-1/relnotes/article.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.sgml b/release/doc/en_US.ISO8859-1/relnotes/article.sgml index e7d53db18ca..ca6ec0fae97 100644 --- a/release/doc/en_US.ISO8859-1/relnotes/article.sgml +++ b/release/doc/en_US.ISO8859-1/relnotes/article.sgml @@ -2401,7 +2401,7 @@ options NFSD # for NFS server one of ISC BIND 9.4.3. sendmail has been updated from - version 8.14.2 to version 8.14.3. + version 8.14.2 to version 8.14.4. From 72c12306f91e6c388570326002fd2778c26de2cf Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 1 Feb 2010 09:29:32 +0000 Subject: [PATCH 1350/2592] Reduce diff against OpenSolaris - move Giant acquire/release to zfs_znode.c. As a side effect this also eliminates two potential Giant leaks. Approved by: pjd --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c | 5 ----- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c index 10d3b867108..77511bd9f67 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c @@ -557,9 +557,6 @@ zfs_rmnode(znode_t *zp) dmu_tx_t *tx; uint64_t acl_obj; int error; - int vfslocked; - - vfslocked = VFS_LOCK_GIANT(zfsvfs->z_vfs); ASSERT(zp->z_phys->zp_links == 0); @@ -593,7 +590,6 @@ zfs_rmnode(znode_t *zp) */ zfs_znode_dmu_fini(zp); zfs_znode_free(zp); - VFS_UNLOCK_GIANT(vfslocked); return; } } @@ -666,7 +662,6 @@ zfs_rmnode(znode_t *zp) out: if (xzp) VN_RELE(ZTOV(xzp)); - VFS_UNLOCK_GIANT(vfslocked); } static uint64_t 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 7157930f729..900087b8b32 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 @@ -1017,6 +1017,7 @@ zfs_zinactive(znode_t *zp) vnode_t *vp = ZTOV(zp); zfsvfs_t *zfsvfs = zp->z_zfsvfs; uint64_t z_id = zp->z_id; + int vfslocked; ASSERT(zp->z_dbuf && zp->z_phys); @@ -1049,7 +1050,9 @@ zfs_zinactive(znode_t *zp) ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); ASSERT(vp->v_count == 0); vrecycle(vp, curthread); + vfslocked = VFS_LOCK_GIANT(zfsvfs->z_vfs); zfs_rmnode(zp); + VFS_UNLOCK_GIANT(vfslocked); return; } mutex_exit(&zp->z_lock); From 546b397a1f7947681f1e2656b69a6c41a95bbdc7 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 1 Feb 2010 10:45:23 +0000 Subject: [PATCH 1351/2592] MFC r203175: The MAP_ENTRY_NEEDS_COPY flag belongs to protoeflags, cow variable uses different namespace. --- sys/vm/vm_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 06ae63e622b..373c8040f74 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -1136,7 +1136,7 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset, ((protoeflags & MAP_ENTRY_NEEDS_COPY) || object == NULL))) { if (!(cow & MAP_ACC_CHARGED) && !swap_reserve(end - start)) return (KERN_RESOURCE_SHORTAGE); - KASSERT(object == NULL || (cow & MAP_ENTRY_NEEDS_COPY) || + KASSERT(object == NULL || (protoeflags & MAP_ENTRY_NEEDS_COPY) || object->uip == NULL, ("OVERCOMMIT: vm_map_insert o %p", object)); uip = curthread->td_ucred->cr_ruidinfo; From 85f1d756704113ff36c7f6929700c5796cede54b Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Mon, 1 Feb 2010 16:02:14 +0000 Subject: [PATCH 1352/2592] MFC r202573: Print sizes up to INT64_MAX in md_prthumanval(). PR: bin/125365 Approved by: trasz (mentor) --- sbin/mdconfig/mdconfig.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sbin/mdconfig/mdconfig.c b/sbin/mdconfig/mdconfig.c index 107a2597509..ec667c51ad5 100644 --- a/sbin/mdconfig/mdconfig.c +++ b/sbin/mdconfig/mdconfig.c @@ -454,14 +454,15 @@ static void md_prthumanval(char *length) { char buf[6]; - uint64_t bytes; + uintmax_t bytes; char *endptr; - bytes = strtoul(length, &endptr, 10); - if (bytes == (unsigned)ULONG_MAX || *endptr != '\0') + errno = 0; + bytes = strtoumax(length, &endptr, 10); + if (errno != 0 || *endptr != '\0' || bytes > INT64_MAX) return; - humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), - bytes, "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); + humanize_number(buf, sizeof(buf), (int64_t)bytes, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); (void)printf("%6s", buf); } From d362c2a208010e14dc1767b487d956af38c5dbe6 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 1 Feb 2010 22:01:48 +0000 Subject: [PATCH 1353/2592] MFC 203070: Initialize the ifnet before calling mii_phy_probe() as some phy drivers (e.g. e1000phy(4)) expect if_dname to be valid when they are probed. --- sys/dev/nve/if_nve.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/dev/nve/if_nve.c b/sys/dev/nve/if_nve.c index a987c6c89ac..1d8fdbe721e 100644 --- a/sys/dev/nve/if_nve.c +++ b/sys/dev/nve/if_nve.c @@ -526,14 +526,6 @@ nve_attach(device_t dev) goto fail; } - /* Probe device for MII interface to PHY */ - DEBUGOUT(NVE_DEBUG_INIT, "nve: do mii_phy_probe\n"); - if (mii_phy_probe(dev, &sc->miibus, nve_ifmedia_upd, nve_ifmedia_sts)) { - device_printf(dev, "MII without any phy!\n"); - error = ENXIO; - goto fail; - } - /* Setup interface parameters */ ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); @@ -551,6 +543,14 @@ nve_attach(device_t dev) ifp->if_capabilities |= IFCAP_VLAN_MTU; ifp->if_capenable |= IFCAP_VLAN_MTU; + /* Probe device for MII interface to PHY */ + DEBUGOUT(NVE_DEBUG_INIT, "nve: do mii_phy_probe\n"); + if (mii_phy_probe(dev, &sc->miibus, nve_ifmedia_upd, nve_ifmedia_sts)) { + device_printf(dev, "MII without any phy!\n"); + error = ENXIO; + goto fail; + } + /* Attach to OS's managers. */ ether_ifattach(ifp, eaddr); From 0fb14c6f0d0afa3a2e66f4d158de68f35e70087c Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 1 Feb 2010 23:57:42 +0000 Subject: [PATCH 1354/2592] MFC r203082: Add initial support for RTL8103E PCIe fastethernet. PR: kern/142974 --- sys/dev/re/if_re.c | 9 ++++++++- sys/pci/if_rlreg.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index aeb9cf20d7e..a642925b50c 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -172,7 +172,7 @@ static struct rl_type re_devs[] = { { RT_VENDORID, RT_DEVICEID_8139, 0, "RealTek 8139C+ 10/100BaseTX" }, { RT_VENDORID, RT_DEVICEID_8101E, 0, - "RealTek 8101E/8102E/8102EL PCIe 10/100baseTX" }, + "RealTek 8101E/8102E/8102EL/8103E PCIe 10/100baseTX" }, { RT_VENDORID, RT_DEVICEID_8168, 0, "RealTek 8168/8168B/8168C/8168CP/8168D/8168DP/" "8111B/8111C/8111CP/8111DP PCIe Gigabit Ethernet" }, @@ -212,6 +212,7 @@ static struct rl_hwrev re_hwrevs[] = { { RL_HWREV_8102E, RL_8169, "8102E"}, { RL_HWREV_8102EL, RL_8169, "8102EL"}, { RL_HWREV_8102EL_SPIN1, RL_8169, "8102EL"}, + { RL_HWREV_8103E, RL_8169, "8103E"}, { RL_HWREV_8168_SPIN2, RL_8169, "8168"}, { RL_HWREV_8168_SPIN3, RL_8169, "8168"}, { RL_HWREV_8168C, RL_8169, "8168C/8111C"}, @@ -1268,6 +1269,12 @@ re_attach(device_t dev) RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD; break; + case RL_HWREV_8103E: + sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_PHYWAKE | + RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | + RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD | + RL_FLAG_MACSLEEP; + break; case RL_HWREV_8168_SPIN1: case RL_HWREV_8168_SPIN2: sc->rl_flags |= RL_FLAG_WOLRXENB; diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h index d112d024c5a..b5752895a85 100644 --- a/sys/pci/if_rlreg.h +++ b/sys/pci/if_rlreg.h @@ -166,6 +166,7 @@ #define RL_HWREV_8100E 0x30800000 #define RL_HWREV_8101E 0x34000000 #define RL_HWREV_8102E 0x34800000 +#define RL_HWREV_8103E 0x34C00000 #define RL_HWREV_8168_SPIN2 0x38000000 #define RL_HWREV_8168_SPIN3 0x38400000 #define RL_HWREV_8168C 0x3C000000 From 281e5d86dbb384946d5bf79a02108f228d90e35b Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 2 Feb 2010 00:32:15 +0000 Subject: [PATCH 1355/2592] MFC r202640: Update to 4.6. Note: the -V option from OpenBSD is implemented using setfib(2) on FreeBSD. --- contrib/netcat/FREEBSD-vendor | 2 +- contrib/netcat/nc.1 | 9 +++++++-- contrib/netcat/netcat.c | 32 ++++++++++++++++++++++++++++---- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/contrib/netcat/FREEBSD-vendor b/contrib/netcat/FREEBSD-vendor index 1009e388e2e..c808f5bbc5a 100644 --- a/contrib/netcat/FREEBSD-vendor +++ b/contrib/netcat/FREEBSD-vendor @@ -1,5 +1,5 @@ # $FreeBSD$ Project: netcat (aka src/usr.bin/nc in OpenBSD) ProjectURL: http://www.openbsd.org/ -Version: 4.4 +Version: 4.6 License: BSD diff --git a/contrib/netcat/nc.1 b/contrib/netcat/nc.1 index b770a527e09..4375ae84cea 100644 --- a/contrib/netcat/nc.1 +++ b/contrib/netcat/nc.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: nc.1,v 1.48 2008/09/19 13:24:41 sobrado Exp $ +.\" $OpenBSD: nc.1,v 1.50 2009/06/05 06:47:12 jmc Exp $ .\" .\" Copyright (c) 1996 David Sacerdote .\" All rights reserved. @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 6 2008 +.Dd June 5 2009 .Dt NC 1 .Os .Sh NAME @@ -46,6 +46,7 @@ .Op Fl p Ar source_port .Op Fl s Ar source_ip_address .Op Fl T Ar ToS +.Op Fl V Ar fib .Op Fl w Ar timeout .Op Fl X Ar proxy_protocol .Oo Xo @@ -208,6 +209,9 @@ to script telnet sessions. Specifies to use Unix Domain Sockets. .It Fl u Use UDP instead of the default option of TCP. +.It Fl V Ar fib +Set the routing table (FIB). +The default is 0. .It Fl v Have .Nm @@ -449,6 +453,7 @@ if the proxy requires it: .Ex -std .Sh SEE ALSO .Xr cat 1 , +.Xr setfib 1 , .Xr ssh 1 , .Xr tcp 4 .Sh AUTHORS diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c index d0c3881e3fa..a9ce18bb9b5 100644 --- a/contrib/netcat/netcat.c +++ b/contrib/netcat/netcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.92 2008/09/19 13:24:41 sobrado Exp $ */ +/* $OpenBSD: netcat.c,v 1.93 2009/06/05 00:18:10 claudio Exp $ */ /* * Copyright (c) 2001 Eric Jackson * @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -94,6 +95,7 @@ int Iflag; /* TCP receive buffer size */ int Oflag; /* TCP send buffer size */ int Sflag; /* TCP MD5 signature option */ int Tflag = -1; /* IP Type of Service */ +u_int rdomain; int timeout = -1; int family = AF_UNSPEC; @@ -124,6 +126,8 @@ int main(int argc, char *argv[]) { int ch, s, ret, socksv, ipsec_count; + int numfibs; + size_t intsize = sizeof(int); char *host, *uport; struct addrinfo hints; struct servent *sv; @@ -137,6 +141,7 @@ main(int argc, char *argv[]) { NULL, 0, NULL, 0 } }; + rdomain = 0; ret = 1; ipsec_count = 0; s = 0; @@ -146,7 +151,7 @@ main(int argc, char *argv[]) sv = NULL; while ((ch = getopt_long(argc, argv, - "46e:DEdhi:jklnoI:O:P:p:rSs:tT:Uuvw:X:x:z", + "46DdEe:hI:i:jklnO:oP:p:rSs:tT:UuV:vw:X:x:z", longopts, NULL)) != -1) { switch (ch) { case '4': @@ -229,6 +234,14 @@ main(int argc, char *argv[]) case 'u': uflag = 1; break; + case 'V': + if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1) + errx(1, "Multiple FIBS not supported"); + rdomain = (unsigned int)strtonum(optarg, 0, + numfibs - 1, &errstr); + if (errstr) + errx(1, "FIB %s: %s", errstr, optarg); + break; case 'v': vflag = 1; break; @@ -550,6 +563,11 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) add_ipsec_policy(s, ipsec_policy[1]); #endif + if (rdomain) { + if (setfib(rdomain) == -1) + err(1, "setfib"); + } + /* Bind to a local port or source address if specified. */ if (sflag || pflag) { struct addrinfo ahints, *ares; @@ -620,6 +638,11 @@ local_listen(char *host, char *port, struct addrinfo hints) res0->ai_protocol)) < 0) continue; + if (rdomain) { + if (setfib(rdomain) == -1) + err(1, "setfib"); + } + ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); if (ret == -1) err(1, NULL); @@ -930,6 +953,7 @@ help(void) \t-t Answer TELNET negotiation\n\ \t-U Use UNIX domain socket\n\ \t-u UDP mode\n\ + \t-V fib Specify alternate routing table (FIB)\n\ \t-v Verbose\n\ \t-w secs\t Timeout for connects and final net reads\n\ \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ @@ -974,8 +998,8 @@ usage(int ret) "usage: nc [-46DdhklnorStUuvz] [-I length] [-i interval] [-O length]\n" #endif "\t [-P proxy_username] [-p source_port] [-s source_ip_address] [-T ToS]\n" - "\t [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]] [hostname]\n" - "\t [port]\n"); + "\t [-V fib] [-w timeout] [-X proxy_protocol]\n" + "\t [-x proxy_address[:port]] [hostname] [port]\n"); if (ret) exit(1); } From 1d784069d71ccddc7b27b5c365364b62cfac394e Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 2 Feb 2010 18:43:08 +0000 Subject: [PATCH 1356/2592] MFC 203031: Remove slattach from the install mfsroot since it doesn't exist anymore to quiet a warning from crunchgen. --- release/amd64/boot_crunch.conf | 1 - release/i386/boot_crunch.conf | 1 - release/pc98/boot_crunch.conf | 1 - release/powerpc/boot_crunch.conf | 1 - release/sparc64/boot_crunch.conf | 1 - release/sun4v/boot_crunch.conf | 1 - 6 files changed, 6 deletions(-) diff --git a/release/amd64/boot_crunch.conf b/release/amd64/boot_crunch.conf index 887a1735cf0..94ccedb2caa 100644 --- a/release/amd64/boot_crunch.conf +++ b/release/amd64/boot_crunch.conf @@ -20,7 +20,6 @@ progs mount_nfs progs newfs progs route progs rtsol -progs slattach progs tunefs ln fsck_ffs fsck_4.2bsd ln fsck_ffs fsck_ufs diff --git a/release/i386/boot_crunch.conf b/release/i386/boot_crunch.conf index 887a1735cf0..94ccedb2caa 100644 --- a/release/i386/boot_crunch.conf +++ b/release/i386/boot_crunch.conf @@ -20,7 +20,6 @@ progs mount_nfs progs newfs progs route progs rtsol -progs slattach progs tunefs ln fsck_ffs fsck_4.2bsd ln fsck_ffs fsck_ufs diff --git a/release/pc98/boot_crunch.conf b/release/pc98/boot_crunch.conf index 2939daa198d..2164dd645e8 100644 --- a/release/pc98/boot_crunch.conf +++ b/release/pc98/boot_crunch.conf @@ -20,7 +20,6 @@ progs mount_nfs progs newfs progs route progs rtsol -progs slattach progs tunefs ln fsck_ffs fsck_4.2bsd ln fsck_ffs fsck_ufs diff --git a/release/powerpc/boot_crunch.conf b/release/powerpc/boot_crunch.conf index fb5a40ebd37..9f7a3010b11 100644 --- a/release/powerpc/boot_crunch.conf +++ b/release/powerpc/boot_crunch.conf @@ -22,7 +22,6 @@ progs newfs progs newfs_msdos progs route progs rtsol -progs slattach progs tunefs ln fsck_ffs fsck_4.2bsd ln fsck_ffs fsck_ufs diff --git a/release/sparc64/boot_crunch.conf b/release/sparc64/boot_crunch.conf index 93f6c936162..ef9f3e1ecd0 100644 --- a/release/sparc64/boot_crunch.conf +++ b/release/sparc64/boot_crunch.conf @@ -20,7 +20,6 @@ progs mount_nfs progs newfs progs route progs rtsol -progs slattach progs tunefs ln fsck_ffs fsck_4.2bsd ln fsck_ffs fsck_ufs diff --git a/release/sun4v/boot_crunch.conf b/release/sun4v/boot_crunch.conf index 93f6c936162..ef9f3e1ecd0 100644 --- a/release/sun4v/boot_crunch.conf +++ b/release/sun4v/boot_crunch.conf @@ -20,7 +20,6 @@ progs mount_nfs progs newfs progs route progs rtsol -progs slattach progs tunefs ln fsck_ffs fsck_4.2bsd ln fsck_ffs fsck_ufs From ca999e2992f594bec593c59dee088443f7f49055 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 2 Feb 2010 18:50:02 +0000 Subject: [PATCH 1357/2592] MFC 203032: Don't pop up the menu to select a documentation language for non-interactive installs. Default to not installing any documentation in that case. --- usr.sbin/sysinstall/dist.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/usr.sbin/sysinstall/dist.c b/usr.sbin/sysinstall/dist.c index 3c84a1d2ed6..cf5566f4c10 100644 --- a/usr.sbin/sysinstall/dist.c +++ b/usr.sbin/sysinstall/dist.c @@ -783,6 +783,10 @@ distSetDoc(dialogMenuItem *self) { int i; + /* Assume no docs for non-interactive installs. */ + if (variable_get(VAR_NONINTERACTIVE)) + return DITEM_SUCCESS | DITEM_RESTORE; + dialog_clear_norefresh(); if (!dmenuOpenSimple(&MenuDocInstall, FALSE)) i = DITEM_FAILURE; From 335287096d9e234ddc4211609c6eddb63c27f327 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Tue, 2 Feb 2010 19:37:26 +0000 Subject: [PATCH 1358/2592] Merge r203025,r203026 from head: Correct the HISTORY section of these man pages to show when the function, not the "manual page example" was introduced. Approved by: ed (mentor, implicit) --- lib/librpcsec_gss/rpc_gss_get_error.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_get_mech_info.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_get_mechanisms.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_get_principal_name.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_get_versions.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_getcred.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_is_installed.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_max_data_length.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_mech_to_oid.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_oid_to_mech.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_qop_to_num.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_seccreate.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_set_callback.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_set_defaults.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_set_svc_name.3 | 4 ++-- lib/librpcsec_gss/rpc_gss_svc_max_data_length.3 | 4 ++-- lib/librpcsec_gss/rpcsec_gss.3 | 4 ++-- 17 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lib/librpcsec_gss/rpc_gss_get_error.3 b/lib/librpcsec_gss/rpc_gss_get_error.3 index e108766322f..74d2fa0f7db 100644 --- a/lib/librpcsec_gss/rpc_gss_get_error.3 +++ b/lib/librpcsec_gss/rpc_gss_get_error.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_GET_ERROR 3 .Os .Sh NAME @@ -50,7 +50,7 @@ A pointer to a structure where the error details will be returned .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_get_mech_info.3 b/lib/librpcsec_gss/rpc_gss_get_mech_info.3 index a7f7d6b4d46..945b00bedd6 100644 --- a/lib/librpcsec_gss/rpc_gss_get_mech_info.3 +++ b/lib/librpcsec_gss/rpc_gss_get_mech_info.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_GET_MECH_INFO 3 .Os .Sh NAME @@ -60,7 +60,7 @@ otherwise .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_get_mechanisms.3 b/lib/librpcsec_gss/rpc_gss_get_mechanisms.3 index 4b57ac6fe58..e18a64874d8 100644 --- a/lib/librpcsec_gss/rpc_gss_get_mechanisms.3 +++ b/lib/librpcsec_gss/rpc_gss_get_mechanisms.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_GET_MECHANISMS 3 .Os .Sh NAME @@ -47,7 +47,7 @@ terminated list of installed security mechanisms. .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_get_principal_name.3 b/lib/librpcsec_gss/rpc_gss_get_principal_name.3 index 6f572125996..19297f65a71 100644 --- a/lib/librpcsec_gss/rpc_gss_get_principal_name.3 +++ b/lib/librpcsec_gss/rpc_gss_get_principal_name.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_GET_PRINCIPAL_NAME 3 .Os .Sh NAME @@ -74,7 +74,7 @@ otherwise .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_get_versions.3 b/lib/librpcsec_gss/rpc_gss_get_versions.3 index f82406677be..78ebe73d437 100644 --- a/lib/librpcsec_gss/rpc_gss_get_versions.3 +++ b/lib/librpcsec_gss/rpc_gss_get_versions.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_GET_VERSIONS 3 .Os .Sh NAME @@ -56,7 +56,7 @@ is set to the lowest suppored protocol version .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_getcred.3 b/lib/librpcsec_gss/rpc_gss_getcred.3 index 2ede33e6ceb..844e61ee41e 100644 --- a/lib/librpcsec_gss/rpc_gss_getcred.3 +++ b/lib/librpcsec_gss/rpc_gss_getcred.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_GETCRED 3 .Os .Sh NAME @@ -77,7 +77,7 @@ otherwise. .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_is_installed.3 b/lib/librpcsec_gss/rpc_gss_is_installed.3 index 2859ed2e691..a043c45abb2 100644 --- a/lib/librpcsec_gss/rpc_gss_is_installed.3 +++ b/lib/librpcsec_gss/rpc_gss_is_installed.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_IS_INSTALLED 3 .Os .Sh NAME @@ -57,7 +57,7 @@ otherwise. .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_max_data_length.3 b/lib/librpcsec_gss/rpc_gss_max_data_length.3 index 89571192105..a600192bfbf 100644 --- a/lib/librpcsec_gss/rpc_gss_max_data_length.3 +++ b/lib/librpcsec_gss/rpc_gss_max_data_length.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_MAX_DATA_LENGTH 3 .Os .Sh NAME @@ -56,7 +56,7 @@ The maximum message size that can be encoded .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_mech_to_oid.3 b/lib/librpcsec_gss/rpc_gss_mech_to_oid.3 index c1f9f2a32f8..95d0cd7b105 100644 --- a/lib/librpcsec_gss/rpc_gss_mech_to_oid.3 +++ b/lib/librpcsec_gss/rpc_gss_mech_to_oid.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_MECH_TO_OID 3 .Os .Sh NAME @@ -60,7 +60,7 @@ is returned, otherwise .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_oid_to_mech.3 b/lib/librpcsec_gss/rpc_gss_oid_to_mech.3 index 6183f26076e..c91a2f569af 100644 --- a/lib/librpcsec_gss/rpc_gss_oid_to_mech.3 +++ b/lib/librpcsec_gss/rpc_gss_oid_to_mech.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_OID_TO_MECH 3 .Os .Sh NAME @@ -60,7 +60,7 @@ is returned, otherwise .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_qop_to_num.3 b/lib/librpcsec_gss/rpc_gss_qop_to_num.3 index e58d553e149..38d2725ac1d 100644 --- a/lib/librpcsec_gss/rpc_gss_qop_to_num.3 +++ b/lib/librpcsec_gss/rpc_gss_qop_to_num.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_QOP_TO_NUM 3 .Os .Sh NAME @@ -62,7 +62,7 @@ is returned, otherwise .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_seccreate.3 b/lib/librpcsec_gss/rpc_gss_seccreate.3 index 0f7dfabb4d8..07204cb1394 100644 --- a/lib/librpcsec_gss/rpc_gss_seccreate.3 +++ b/lib/librpcsec_gss/rpc_gss_seccreate.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_SECCREATE 3 .Os .Sh NAME @@ -104,7 +104,7 @@ to this value. .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_set_callback.3 b/lib/librpcsec_gss/rpc_gss_set_callback.3 index 0ad861f89df..f701cf12a95 100644 --- a/lib/librpcsec_gss/rpc_gss_set_callback.3 +++ b/lib/librpcsec_gss/rpc_gss_set_callback.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_SET_CALLBACK 3 .Os .Sh NAME @@ -100,7 +100,7 @@ otherwise .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_set_defaults.3 b/lib/librpcsec_gss/rpc_gss_set_defaults.3 index 241cf9ecf64..c4a24cff5e1 100644 --- a/lib/librpcsec_gss/rpc_gss_set_defaults.3 +++ b/lib/librpcsec_gss/rpc_gss_set_defaults.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_SET_DEFAULTS 3 .Os .Sh NAME @@ -62,7 +62,7 @@ if the values were set .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_set_svc_name.3 b/lib/librpcsec_gss/rpc_gss_set_svc_name.3 index 9be8fdffae8..79a9c680cf9 100644 --- a/lib/librpcsec_gss/rpc_gss_set_svc_name.3 +++ b/lib/librpcsec_gss/rpc_gss_set_svc_name.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_SET_SVC_NAME 3 .Os .Sh NAME @@ -79,7 +79,7 @@ otherwise. .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpc_gss_svc_max_data_length.3 b/lib/librpcsec_gss/rpc_gss_svc_max_data_length.3 index 2445f7553f6..ef4871f4f56 100644 --- a/lib/librpcsec_gss/rpc_gss_svc_max_data_length.3 +++ b/lib/librpcsec_gss/rpc_gss_svc_max_data_length.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_SVC_MAX_DATA_LENGTH 3 .Os .Sh NAME @@ -56,7 +56,7 @@ The maximum message size that can be encoded .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 8.0 . .Sh AUTHORS This diff --git a/lib/librpcsec_gss/rpcsec_gss.3 b/lib/librpcsec_gss/rpcsec_gss.3 index 793f0129d39..45bd82fb39c 100644 --- a/lib/librpcsec_gss/rpcsec_gss.3 +++ b/lib/librpcsec_gss/rpcsec_gss.3 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 4, 2008 +.Dd January 26, 2010 .Dt RPC_GSS_SECCREATE 3 .Os .Sh NAME @@ -222,7 +222,7 @@ Calculate maximum server message sizes. .Sh HISTORY The .Nm -manual page example first appeared in +library first appeared in .Fx 8.0 . .Sh AUTHORS This From c11be0301d680c969d4f0d63bde62f25b68bbad9 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Tue, 2 Feb 2010 19:44:52 +0000 Subject: [PATCH 1359/2592] Merge r203027 from head: Correct the HISTORY section of these man pages to show when the function, not the "manual page example" was introduced. Approved by: ed (mentor, implicit) --- lib/libgssapi/gss_accept_sec_context.3 | 4 ++-- lib/libgssapi/gss_acquire_cred.3 | 4 ++-- lib/libgssapi/gss_add_cred.3 | 4 ++-- lib/libgssapi/gss_add_oid_set_member.3 | 4 ++-- lib/libgssapi/gss_canonicalize_name.3 | 4 ++-- lib/libgssapi/gss_compare_name.3 | 4 ++-- lib/libgssapi/gss_context_time.3 | 4 ++-- lib/libgssapi/gss_create_empty_oid_set.3 | 4 ++-- lib/libgssapi/gss_delete_sec_context.3 | 4 ++-- lib/libgssapi/gss_display_name.3 | 4 ++-- lib/libgssapi/gss_display_status.3 | 4 ++-- lib/libgssapi/gss_duplicate_name.3 | 4 ++-- lib/libgssapi/gss_export_name.3 | 4 ++-- lib/libgssapi/gss_export_sec_context.3 | 4 ++-- lib/libgssapi/gss_get_mic.3 | 4 ++-- lib/libgssapi/gss_import_name.3 | 4 ++-- lib/libgssapi/gss_import_sec_context.3 | 4 ++-- lib/libgssapi/gss_indicate_mechs.3 | 4 ++-- lib/libgssapi/gss_init_sec_context.3 | 4 ++-- lib/libgssapi/gss_inquire_context.3 | 4 ++-- lib/libgssapi/gss_inquire_cred.3 | 4 ++-- lib/libgssapi/gss_inquire_cred_by_mech.3 | 4 ++-- lib/libgssapi/gss_inquire_mechs_for_name.3 | 4 ++-- lib/libgssapi/gss_inquire_names_for_mech.3 | 4 ++-- lib/libgssapi/gss_process_context_token.3 | 4 ++-- lib/libgssapi/gss_release_buffer.3 | 4 ++-- lib/libgssapi/gss_release_cred.3 | 4 ++-- lib/libgssapi/gss_release_name.3 | 4 ++-- lib/libgssapi/gss_release_oid_set.3 | 4 ++-- lib/libgssapi/gss_test_oid_set_member.3 | 4 ++-- lib/libgssapi/gss_unwrap.3 | 4 ++-- lib/libgssapi/gss_verify_mic.3 | 4 ++-- lib/libgssapi/gss_wrap.3 | 4 ++-- lib/libgssapi/gss_wrap_size_limit.3 | 4 ++-- lib/libgssapi/gssapi.3 | 4 ++-- lib/libgssapi/mech.5 | 4 ++-- 36 files changed, 72 insertions(+), 72 deletions(-) diff --git a/lib/libgssapi/gss_accept_sec_context.3 b/lib/libgssapi/gss_accept_sec_context.3 index 6b575183553..8957831e145 100644 --- a/lib/libgssapi/gss_accept_sec_context.3 +++ b/lib/libgssapi/gss_accept_sec_context.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_ACCEPT_SEC_CONTEXT 3 PRM .Sh NAME @@ -451,7 +451,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_acquire_cred.3 b/lib/libgssapi/gss_acquire_cred.3 index b43185cbdea..c48a46838d0 100644 --- a/lib/libgssapi/gss_acquire_cred.3 +++ b/lib/libgssapi/gss_acquire_cred.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_ACQUIRE_CRED 3 PRM .Sh NAME @@ -205,7 +205,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_add_cred.3 b/lib/libgssapi/gss_add_cred.3 index 72f2ab0a104..53df140d555 100644 --- a/lib/libgssapi/gss_add_cred.3 +++ b/lib/libgssapi/gss_add_cred.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_ADD_CRED 3 PRM .Sh NAME @@ -305,7 +305,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_add_oid_set_member.3 b/lib/libgssapi/gss_add_oid_set_member.3 index 255050b3b39..fb2119cefe8 100644 --- a/lib/libgssapi/gss_add_oid_set_member.3 +++ b/lib/libgssapi/gss_add_oid_set_member.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_ADD_OID_SET_MEMBER 3 PRM .Sh NAME @@ -97,7 +97,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_canonicalize_name.3 b/lib/libgssapi/gss_canonicalize_name.3 index b38ca93e3e2..86957dc0584 100644 --- a/lib/libgssapi/gss_canonicalize_name.3 +++ b/lib/libgssapi/gss_canonicalize_name.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_CANONICALIZE_NAME 3 PRM .Sh NAME @@ -104,7 +104,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_compare_name.3 b/lib/libgssapi/gss_compare_name.3 index 561c9944161..7f69d430b27 100644 --- a/lib/libgssapi/gss_compare_name.3 +++ b/lib/libgssapi/gss_compare_name.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_COMPARE_NAME PRM .Sh NAME @@ -89,7 +89,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_context_time.3 b/lib/libgssapi/gss_context_time.3 index 96f61a9c3f2..9fb43eacab0 100644 --- a/lib/libgssapi/gss_context_time.3 +++ b/lib/libgssapi/gss_context_time.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_CONTEXT_TIME 3 PRM .Sh NAME @@ -75,7 +75,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_create_empty_oid_set.3 b/lib/libgssapi/gss_create_empty_oid_set.3 index fd6cca6495c..08d82f6b2ba 100644 --- a/lib/libgssapi/gss_create_empty_oid_set.3 +++ b/lib/libgssapi/gss_create_empty_oid_set.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_CREATE_EMPTY_OID_SET 3 PRM .Sh NAME @@ -78,7 +78,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_delete_sec_context.3 b/lib/libgssapi/gss_delete_sec_context.3 index d24644ac4bd..a0c26df7f3e 100644 --- a/lib/libgssapi/gss_delete_sec_context.3 +++ b/lib/libgssapi/gss_delete_sec_context.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_DELETE_SEC_CONTEXT 3 PRM .Sh NAME @@ -130,7 +130,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_display_name.3 b/lib/libgssapi/gss_display_name.3 index 4f508700b3a..2441eef4c49 100644 --- a/lib/libgssapi/gss_display_name.3 +++ b/lib/libgssapi/gss_display_name.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_DISPLAY_NAME 3 PRM .Sh NAME @@ -118,7 +118,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_display_status.3 b/lib/libgssapi/gss_display_status.3 index 3b3c3236559..2b1affd4e35 100644 --- a/lib/libgssapi/gss_display_status.3 +++ b/lib/libgssapi/gss_display_status.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_DISPLAY_STATUS 3 PRM .Sh NAME @@ -177,7 +177,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_duplicate_name.3 b/lib/libgssapi/gss_duplicate_name.3 index af885bfb229..334a1268410 100644 --- a/lib/libgssapi/gss_duplicate_name.3 +++ b/lib/libgssapi/gss_duplicate_name.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_DUPLICATE_NAME 3 PRM .Sh NAME @@ -90,7 +90,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_export_name.3 b/lib/libgssapi/gss_export_name.3 index c10f472d2ba..e1feee22bd6 100644 --- a/lib/libgssapi/gss_export_name.3 +++ b/lib/libgssapi/gss_export_name.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_EXPORT_NAME 3 PRM .Sh NAME @@ -95,7 +95,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_export_sec_context.3 b/lib/libgssapi/gss_export_sec_context.3 index d8359c8be30..1f7f01df9d3 100644 --- a/lib/libgssapi/gss_export_sec_context.3 +++ b/lib/libgssapi/gss_export_sec_context.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_EXPORT_SEC_CONTEXT 3 PRM .Sh NAME @@ -135,7 +135,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_get_mic.3 b/lib/libgssapi/gss_get_mic.3 index 8f435d6fe08..8892808f022 100644 --- a/lib/libgssapi/gss_get_mic.3 +++ b/lib/libgssapi/gss_get_mic.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_GET_MIC 3 PRM .Sh NAME @@ -132,7 +132,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_import_name.3 b/lib/libgssapi/gss_import_name.3 index ed16278b93d..3119f04534b 100644 --- a/lib/libgssapi/gss_import_name.3 +++ b/lib/libgssapi/gss_import_name.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_IMPORT_NAME 3 PRM .Sh NAME @@ -106,7 +106,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_import_sec_context.3 b/lib/libgssapi/gss_import_sec_context.3 index f4dda843c4a..a889e2b7fa4 100644 --- a/lib/libgssapi/gss_import_sec_context.3 +++ b/lib/libgssapi/gss_import_sec_context.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_IMPORT_SEC_CONTEXT 3 PRM .Sh NAME @@ -87,7 +87,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_indicate_mechs.3 b/lib/libgssapi/gss_indicate_mechs.3 index 469ad1db466..26ffaa60162 100644 --- a/lib/libgssapi/gss_indicate_mechs.3 +++ b/lib/libgssapi/gss_indicate_mechs.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_INDICATE_MECHS 3 PRM .Sh NAME @@ -74,7 +74,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_init_sec_context.3 b/lib/libgssapi/gss_init_sec_context.3 index 5c39de457df..787aff32721 100644 --- a/lib/libgssapi/gss_init_sec_context.3 +++ b/lib/libgssapi/gss_init_sec_context.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_INIT_SEC_CONTEXT 3 PRM .Sh NAME @@ -538,7 +538,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_inquire_context.3 b/lib/libgssapi/gss_inquire_context.3 index 2ecd4d60567..51fa18db829 100644 --- a/lib/libgssapi/gss_inquire_context.3 +++ b/lib/libgssapi/gss_inquire_context.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_INQUIRE_CONTEXT 3 PRM .Sh NAME @@ -251,7 +251,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_inquire_cred.3 b/lib/libgssapi/gss_inquire_cred.3 index 979f96e7ce0..99c20ce01fb 100644 --- a/lib/libgssapi/gss_inquire_cred.3 +++ b/lib/libgssapi/gss_inquire_cred.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_INQUIRE_CRED 3 PRM .Sh NAME @@ -125,7 +125,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_inquire_cred_by_mech.3 b/lib/libgssapi/gss_inquire_cred_by_mech.3 index 85b5ecc8e44..22319bd4613 100644 --- a/lib/libgssapi/gss_inquire_cred_by_mech.3 +++ b/lib/libgssapi/gss_inquire_cred_by_mech.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_INQUIRE_CRED_BY_MECH 3 PRM .Sh NAME @@ -139,7 +139,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_inquire_mechs_for_name.3 b/lib/libgssapi/gss_inquire_mechs_for_name.3 index 91d1c81082c..b56e663a18d 100644 --- a/lib/libgssapi/gss_inquire_mechs_for_name.3 +++ b/lib/libgssapi/gss_inquire_mechs_for_name.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_INQUIRE_MECHS_FOR_NAME 3 PRM .Sh NAME @@ -100,7 +100,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_inquire_names_for_mech.3 b/lib/libgssapi/gss_inquire_names_for_mech.3 index 64d8c9c0940..8b7f069f915 100644 --- a/lib/libgssapi/gss_inquire_names_for_mech.3 +++ b/lib/libgssapi/gss_inquire_names_for_mech.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_INQUIRE_NAMES_FOR_MECH 3 PRM .Sh NAME @@ -74,7 +74,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_process_context_token.3 b/lib/libgssapi/gss_process_context_token.3 index 884a5568acd..85e1029aab0 100644 --- a/lib/libgssapi/gss_process_context_token.3 +++ b/lib/libgssapi/gss_process_context_token.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_PROCESS_CONTEXT_TOKEN 3 PRM .Sh NAME @@ -103,7 +103,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_release_buffer.3 b/lib/libgssapi/gss_release_buffer.3 index 4cc449f9eae..432d42276c5 100644 --- a/lib/libgssapi/gss_release_buffer.3 +++ b/lib/libgssapi/gss_release_buffer.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_RELEASE_BUFFER 3 PRM .Sh NAME @@ -78,7 +78,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_release_cred.3 b/lib/libgssapi/gss_release_cred.3 index 2f9fca6cbc3..ca99fc40a8f 100644 --- a/lib/libgssapi/gss_release_cred.3 +++ b/lib/libgssapi/gss_release_cred.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_RELEASE_CRED 3 PRM .Sh NAME @@ -75,7 +75,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_release_name.3 b/lib/libgssapi/gss_release_name.3 index a6d858c30e2..7bf1181f22a 100644 --- a/lib/libgssapi/gss_release_name.3 +++ b/lib/libgssapi/gss_release_name.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_RELEASE_NAME 3 PRM .Sh NAME @@ -71,7 +71,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_release_oid_set.3 b/lib/libgssapi/gss_release_oid_set.3 index 1e11f44de39..0142e2feec1 100644 --- a/lib/libgssapi/gss_release_oid_set.3 +++ b/lib/libgssapi/gss_release_oid_set.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_RELEASE_OID_SET 3 PRM .Sh NAME @@ -76,7 +76,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_test_oid_set_member.3 b/lib/libgssapi/gss_test_oid_set_member.3 index 38e5f3fe453..86e06b35bb7 100644 --- a/lib/libgssapi/gss_test_oid_set_member.3 +++ b/lib/libgssapi/gss_test_oid_set_member.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_TEST_OID_SET_MEMBER 3 PRM .Sh NAME @@ -83,7 +83,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_unwrap.3 b/lib/libgssapi/gss_unwrap.3 index 770d9c924af..4cf3c6d22cb 100644 --- a/lib/libgssapi/gss_unwrap.3 +++ b/lib/libgssapi/gss_unwrap.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_UNWRAP 3 PRM .Sh NAME @@ -158,7 +158,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_verify_mic.3 b/lib/libgssapi/gss_verify_mic.3 index e482dbf6d3e..b72f468ce7d 100644 --- a/lib/libgssapi/gss_verify_mic.3 +++ b/lib/libgssapi/gss_verify_mic.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_VERIFY_MIC 3 PRM .Sh NAME @@ -139,7 +139,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_wrap.3 b/lib/libgssapi/gss_wrap.3 index a80cf46edd0..c432b482c1b 100644 --- a/lib/libgssapi/gss_wrap.3 +++ b/lib/libgssapi/gss_wrap.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_WRAP 3 PRM .Sh NAME @@ -146,7 +146,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gss_wrap_size_limit.3 b/lib/libgssapi/gss_wrap_size_limit.3 index a3e5a9d1f78..c1d40da014d 100644 --- a/lib/libgssapi/gss_wrap_size_limit.3 +++ b/lib/libgssapi/gss_wrap_size_limit.3 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" .\" The following commands are required for all man pages. -.Dd October 30, 2007 +.Dd January 26, 2010 .Os .Dt GSS_WRAP_SIZE_LIMIT 3 PRM .Sh NAME @@ -131,7 +131,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page example first appeared in +function first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/gssapi.3 b/lib/libgssapi/gssapi.3 index ce26e7eed4e..2ed54a9b3c8 100644 --- a/lib/libgssapi/gssapi.3 +++ b/lib/libgssapi/gssapi.3 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 30, 2005 +.Dd January 26, 2010 .Dt GSSAPI 3 .Os .Sh NAME @@ -229,7 +229,7 @@ Generic Security Service API Version 2 : C-bindings .Sh HISTORY The .Nm -manual page first appeared in +library first appeared in .Fx 7.0 . .Sh AUTHORS John Wray, Iris Associates diff --git a/lib/libgssapi/mech.5 b/lib/libgssapi/mech.5 index fd17e3a21b0..6078828e97f 100644 --- a/lib/libgssapi/mech.5 +++ b/lib/libgssapi/mech.5 @@ -23,7 +23,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd November 14, 2005 +.Dd January 26, 2010 .Dt MECH 5 .Os .Sh NAME @@ -93,7 +93,7 @@ GSS_KRB5_CONF_C_QOP_DES 0x0100 kerberosv5 .Sh HISTORY The .Nm -manual page example first appeared in +manual page first appeared in .Fx 7.0 . .Sh AUTHORS This From 86aedb0946d3913f3d35217c55fb21be6d644a3d Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Tue, 2 Feb 2010 19:51:30 +0000 Subject: [PATCH 1360/2592] Merge r201401 from head: Remove dead code. This section of code is only run in the (sblock.fs_magic == FS_UFS1_MAGIC) case, so the check within the loop is redundant. PR: bin/115174 (partly) Submitted by: Nate Eldredge nge cs.hmc.edu Reviewed by: mjacob Approved by: ed (mentor, implicit) --- sbin/growfs/growfs.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c index 89b14dac27f..cc58fc6267d 100644 --- a/sbin/growfs/growfs.c +++ b/sbin/growfs/growfs.c @@ -376,7 +376,6 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag) long d, dlower, dupper, blkno, start; ufs2_daddr_t i, cbase, dmax; struct ufs1_dinode *dp1; - struct ufs2_dinode *dp2; struct csum *cs; if (iobuf == NULL && (iobuf = malloc(sblock.fs_bsize)) == NULL) { @@ -455,16 +454,11 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag) for (i = 2 * sblock.fs_frag; i < sblock.fs_ipg / INOPF(&sblock); i += sblock.fs_frag) { dp1 = (struct ufs1_dinode *)iobuf; - dp2 = (struct ufs2_dinode *)iobuf; #ifdef FSIRAND - for (j = 0; j < INOPB(&sblock); j++) - if (sblock.fs_magic == FS_UFS1_MAGIC) { - dp1->di_gen = random(); - dp1++; - } else { - dp2->di_gen = random(); - dp2++; - } + for (j = 0; j < INOPB(&sblock); j++) { + dp1->di_gen = random(); + dp1++; + } #endif wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i), sblock.fs_bsize, iobuf, fso, Nflag); From db265fb4a8341299c7ee56a10daa5d1e9cd143e2 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 3 Feb 2010 18:42:14 +0000 Subject: [PATCH 1361/2592] MFC r202668+r200806: Don't consider non-existence of a PID file an error, we should be able to proceed anyway as this most likely mean that the process has been terminated. [1] Add a new option, -P, which reverts newsyslog(8) to the old behavior, which stops to proceed further, as it is possible that processes which fails to create PID file get screwed by rotation. [2] PR: bin/140397 Submitted by: Dan Lukes [1] Requested by: stas [2] --- usr.sbin/newsyslog/newsyslog.8 | 8 ++++++-- usr.sbin/newsyslog/newsyslog.c | 21 ++++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/usr.sbin/newsyslog/newsyslog.8 b/usr.sbin/newsyslog/newsyslog.8 index 3db563f2964..06714aa4c56 100644 --- a/usr.sbin/newsyslog/newsyslog.8 +++ b/usr.sbin/newsyslog/newsyslog.8 @@ -17,7 +17,7 @@ .\" the suitability of this software for any purpose. It is .\" provided "as is" without express or implied warranty. .\" -.Dd February 24, 2005 +.Dd January 19, 2010 .Dt NEWSYSLOG 8 .Os .Sh NAME @@ -25,7 +25,7 @@ .Nd maintain system log files to manageable sizes .Sh SYNOPSIS .Nm -.Op Fl CFNnrsv +.Op Fl CFNPnrsv .Op Fl R Ar tagname .Op Fl a Ar directory .Op Fl d Ar directory @@ -169,6 +169,10 @@ This option is intended to be used with the or .Fl CC options when creating log files is the only objective. +.It Fl P +Prevent further action if we should send signal but the +.Dq pidfile +is empty or does not exist. .It Fl R Ar tagname Specify that .Nm diff --git a/usr.sbin/newsyslog/newsyslog.c b/usr.sbin/newsyslog/newsyslog.c index ef74f23917c..4cadda43203 100644 --- a/usr.sbin/newsyslog/newsyslog.c +++ b/usr.sbin/newsyslog/newsyslog.c @@ -167,6 +167,7 @@ int needroot = 1; /* Root privs are necessary */ int noaction = 0; /* Don't do anything, just show it */ int norotate = 0; /* Don't rotate */ int nosignal; /* Do not send any signals */ +int enforcepid = 0; /* If PID file does not exist or empty, do nothing */ int force = 0; /* Force the trim no matter what */ int rotatereq = 0; /* -R = Always rotate the file(s) as given */ /* on the command (this also requires */ @@ -580,7 +581,7 @@ parse_args(int argc, char **argv) *p = '\0'; /* Parse command line options. */ - while ((ch = getopt(argc, argv, "a:d:f:nrsvCD:FNR:")) != -1) + while ((ch = getopt(argc, argv, "a:d:f:nrsvCD:FNPR:")) != -1) switch (ch) { case 'a': archtodir++; @@ -624,6 +625,9 @@ parse_args(int argc, char **argv) case 'N': norotate++; break; + case 'P': + enforcepid++; + break; case 'R': rotatereq++; requestor = strdup(optarg); @@ -1779,7 +1783,18 @@ set_swpid(struct sigwork_entry *swork, const struct conf_entry *ent) f = fopen(ent->pid_file, "r"); if (f == NULL) { - warn("can't open pid file: %s", ent->pid_file); + if (errno == ENOENT && enforcepid == 0) { + /* + * Warn if the PID file doesn't exist, but do + * not consider it an error. Most likely it + * means the process has been terminated, + * so it should be safe to rotate any log + * files that the process would have been using. + */ + swork->sw_pidok = 1; + warnx("pid file doesn't exist: %s", ent->pid_file); + } else + warn("can't open pid file: %s", ent->pid_file); return; } @@ -1790,7 +1805,7 @@ set_swpid(struct sigwork_entry *swork, const struct conf_entry *ent) * has terminated, so it should be safe to rotate any * log files that the process would have been using. */ - if (feof(f)) { + if (feof(f) && enforcepid == 0) { swork->sw_pidok = 1; warnx("pid file is empty: %s", ent->pid_file); } else From 89ae8d84763e7c3df499d3121421ad83bde4d7f9 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 4 Feb 2010 16:57:01 +0000 Subject: [PATCH 1362/2592] MFC: r202767 Add a timeout for the negative name cache entries in the NFS client. This avoids a bogus negative name cache entry from persisting forever when another client creates an entry with the same name within the same NFS server time of day clock tick. The mount option negnametimeo can be used to override the default timeout interval on a per-mount-point basis. Setting negnametimeo to 0 disables negative name caching for the mount point. I also fixed one obvious typo where args.timeo should be args.maxgrouplist. Submitted by: jhb (earlier version) Reviewed by: jhb --- sys/nfsclient/nfs_vfsops.c | 24 ++++++++++++++++++------ sys/nfsclient/nfs_vnops.c | 11 +++++++++-- sys/nfsclient/nfsmount.h | 5 +++++ sys/nfsclient/nfsnode.h | 1 + 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index 2346d41932a..72ca2ce3fe3 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -114,7 +114,7 @@ static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp, const char *hostname); static int mountnfs(struct nfs_args *, struct mount *, struct sockaddr *, char *, struct vnode **, - struct ucred *cred); + struct ucred *cred, int); static vfs_mount_t nfs_mount; static vfs_cmount_t nfs_cmount; static vfs_unmount_t nfs_unmount; @@ -551,7 +551,7 @@ nfs_mountdiskless(char *path, nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK); if ((error = mountnfs(args, mp, nam, path, vpp, - td->td_ucred)) != 0) { + td->td_ucred, NFS_DEFAULT_NEGNAMETIMEO)) != 0) { printf("nfs_mountroot: mount %s on /: %d\n", path, error); return (error); } @@ -778,7 +778,7 @@ static const char *nfs_opts[] = { "from", "nfs_args", "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize", "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3", "sec", - "maxgroups", "principal", + "maxgroups", "principal", "negnametimeo", NULL }; /* @@ -827,6 +827,7 @@ nfs_mount(struct mount *mp) size_t len; u_char nfh[NFSX_V3FHMAX]; char *opt; + int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO; has_nfs_args_opt = 0; has_addr_opt = 0; @@ -1029,7 +1030,7 @@ nfs_mount(struct mount *mp) } if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) { ret = sscanf(opt, "%d", &args.maxgrouplist); - if (ret != 1 || args.timeo <= 0) { + if (ret != 1 || args.maxgrouplist <= 0) { vfs_mount_error(mp, "illegal maxgroups: %s", opt); error = EINVAL; @@ -1037,6 +1038,16 @@ nfs_mount(struct mount *mp) } args.flags |= NFSMNT_MAXGRPS; } + if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL) + == 0) { + ret = sscanf(opt, "%d", &negnametimeo); + if (ret != 1 || negnametimeo < 0) { + vfs_mount_error(mp, "illegal negnametimeo: %s", + opt); + error = EINVAL; + goto out; + } + } if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr, &args.addrlen) == 0) { has_addr_opt = 1; @@ -1125,7 +1136,7 @@ nfs_mount(struct mount *mp) } } error = mountnfs(&args, mp, nam, args.hostname, &vp, - curthread->td_ucred); + curthread->td_ucred, negnametimeo); out: if (!error) { MNT_ILOCK(mp); @@ -1167,7 +1178,7 @@ nfs_cmount(struct mntarg *ma, void *data, int flags) */ static int mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, - char *hst, struct vnode **vpp, struct ucred *cred) + char *hst, struct vnode **vpp, struct ucred *cred, int negnametimeo) { struct nfsmount *nmp; struct nfsnode *np; @@ -1217,6 +1228,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, nmp->nm_numgrps = NFS_MAXGRPS; nmp->nm_readahead = NFS_DEFRAHEAD; nmp->nm_deadthresh = NFS_MAXDEADTHRESH; + nmp->nm_negnametimeo = negnametimeo; nmp->nm_tprintf_delay = nfs_tprintf_delay; if (nmp->nm_tprintf_delay < 0) nmp->nm_tprintf_delay = 0; diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 7d6bb307e36..c74a6bed518 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -982,8 +982,13 @@ nfs_lookup(struct vop_lookup_args *ap) * modification time of the parent directory matches * our cached copy. Otherwise, we discard all of the * negative cache entries for this directory. + * negative cache entries for this directory. We also + * only trust -ve cache entries for less than + * nm_negative_namecache_timeout seconds. */ - if (VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 && + if ((u_int)(ticks - np->n_dmtime_ticks) < + (nmp->nm_negnametimeo * hz) && + VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 && vattr.va_mtime.tv_sec == np->n_dmtime) { nfsstats.lookupcache_hits++; return (ENOENT); @@ -1157,8 +1162,10 @@ nfsmout: */ mtx_lock(&np->n_mtx); if (np->n_dmtime <= dmtime) { - if (np->n_dmtime == 0) + if (np->n_dmtime == 0) { np->n_dmtime = dmtime; + np->n_dmtime_ticks = ticks; + } mtx_unlock(&np->n_mtx); cache_enter(dvp, NULL, cnp); } else diff --git a/sys/nfsclient/nfsmount.h b/sys/nfsclient/nfsmount.h index 47d7ef305f6..d47957c0066 100644 --- a/sys/nfsclient/nfsmount.h +++ b/sys/nfsclient/nfsmount.h @@ -85,6 +85,7 @@ struct nfsmount { struct rpc_timers nm_timers[NFS_MAX_TIMER]; /* RTT Timers for rpcs */ char nm_principal[MNAMELEN]; /* GSS-API principal of server */ gss_OID nm_mech_oid; /* OID of selected GSS-API mechanism */ + int nm_negnametimeo; /* timeout for -ve entries (sec) */ /* NFSv4 */ uint64_t nm_clientid; @@ -107,6 +108,10 @@ struct nfsmount { #define NFS_TPRINTF_DELAY 30 #endif +#ifndef NFS_DEFAULT_NEGNAMETIMEO +#define NFS_DEFAULT_NEGNAMETIMEO 60 +#endif + #define NFS_PCATCH (PCATCH | PBDRY) #endif diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index 29198d8c20a..402fc796023 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -114,6 +114,7 @@ struct nfsnode { struct timespec n_mtime; /* Prev modify time. */ time_t n_ctime; /* Prev create time. */ time_t n_dmtime; /* Prev dir modify time. */ + int n_dmtime_ticks; /* Tick of -ve cache entry */ time_t n_expiry; /* Lease expiry time */ nfsfh_t *n_fhp; /* NFS File Handle */ struct vnode *n_vnode; /* associated vnode */ From 653c9e47e5dcfcb5cd4e603c74e336d97d909c13 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Thu, 4 Feb 2010 16:59:36 +0000 Subject: [PATCH 1363/2592] MFC r203342: ManageSieve has been added as port 4190: http://www.iana.org/assignments/port-numbers --- etc/services | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/services b/etc/services index c5f30f6a8ef..318562cd31f 100644 --- a/etc/services +++ b/etc/services @@ -2223,6 +2223,8 @@ nuts_dem 4132/tcp #NUTS Daemon nuts_dem 4132/udp #NUTS Daemon nuts_bootp 4133/tcp #NUTS Bootp Server nuts_bootp 4133/udp #NUTS Bootp Server +sieve 4190/tcp #ManageSieve Protocol +sieve 4190/udp #ManageSieve Protocol rwhois 4321/tcp #Remote Who Is rwhois 4321/udp #Remote Who Is unicall 4343/tcp From 4c8732b699348c8a39e9b7e2ccb3e628f049d1fc Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 4 Feb 2010 17:13:38 +0000 Subject: [PATCH 1364/2592] MFC: r202772 Document the negnametimeo option for mount_nfs as implemented by r202767. This is a content change. --- sbin/mount_nfs/mount_nfs.8 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8 index 3d8c4d653c2..39334306112 100644 --- a/sbin/mount_nfs/mount_nfs.8 +++ b/sbin/mount_nfs/mount_nfs.8 @@ -151,6 +151,10 @@ Force the mount protocol to use UDP transport, even for TCP NFS mounts. (Necessary for some old .Bx servers.) +.It Cm negnametimeo Ns = Ns Aq Ar value +Override the default of NFS_DEFAULT_NEGNAMETIMEO for the timeout (in seconds) +for negative name cache entries. If this is set to 0 it disables negative +name caching for the mount point. .It Cm nfsv2 Use the NFS Version 2 protocol (the default is to try version 3 first then version 2). From e3feb3a780a00cd4183a8aa27b32d4c7f6e7ce92 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 4 Feb 2010 17:31:34 +0000 Subject: [PATCH 1365/2592] MFC: r202774 Fix a typo in a comment introduced by r202767. --- sys/nfsclient/nfs_vnops.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index c74a6bed518..6b13bb4573c 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -981,7 +981,6 @@ nfs_lookup(struct vop_lookup_args *ap) * We only accept a negative hit in the cache if the * modification time of the parent directory matches * our cached copy. Otherwise, we discard all of the - * negative cache entries for this directory. * negative cache entries for this directory. We also * only trust -ve cache entries for less than * nm_negative_namecache_timeout seconds. From d9ef258b32116fb6ac035a8561c1f1690fe5d225 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Thu, 4 Feb 2010 17:35:11 +0000 Subject: [PATCH 1366/2592] MFC: r202659 We don't support isdn devices anymore (since May 2008). --- .../doc/en_US.ISO8859-1/hardware/article.sgml | 132 ------------------ 1 file changed, 132 deletions(-) diff --git a/release/doc/en_US.ISO8859-1/hardware/article.sgml b/release/doc/en_US.ISO8859-1/hardware/article.sgml index 83d9f039394..3bf62352fc3 100644 --- a/release/doc/en_US.ISO8859-1/hardware/article.sgml +++ b/release/doc/en_US.ISO8859-1/hardware/article.sgml @@ -979,138 +979,6 @@ &hwlist.cm; - - ISDN Interfaces - - [&arch.i386;] AcerISDN P10 ISA PnP (experimental) - - [&arch.i386;] Asuscom ISDNlink 128K ISA - - [&arch.i386;] ASUSCOM P-IN100-ST-D (and other Winbond - W6692-based cards) - - [&arch.i386;] AVM - - - - A1 - - - - B1 ISA (tested with V2.0) - - - - B1 PCI (tested with V4.0) - - - - Fritz!Card classic - - - - Fritz!Card PnP - - - - Fritz!Card PCI - - - - Fritz!Card PCI, Version 2 - - - - T1 - - - - [&arch.i386;] Creatix - - - - ISDN-S0 - - - - ISDN-S0 P&P - - - - [&arch.i386;] Compaq Microcom 610 ISDN (Compaq series - PSB2222I) ISA PnP - - [&arch.i386;] Dr. Neuhaus Niccy Go@ and compatibles - - [&arch.i386;] Dynalink IS64PPH and IS64PPH+ - - [&arch.i386;] Eicon Diehl DIVA 2.0 and 2.02 - - [&arch.i386;] ELSA - - - - ELSA PCC-16 - - - - QuickStep 1000pro ISA - - - - MicroLink ISDN/PCI - - - - QuickStep 1000pro PCI - - - - [&arch.i386;] ITK ix1 Micro ( < V.3, non-PnP version - ) - - [&arch.i386;] Sedlbauer Win Speed - - [&arch.i386;] Siemens I-Surf 2.0 - - [&arch.i386;] TELEINT ISDN SPEED No.1 - (experimental) - - [&arch.i386;] Teles - - - - S0/8 - - - - S0/16 - - - - S0/16.3 - - - - S0/16.3 PnP - - - - 16.3c ISA PnP (experimental) - - - - Teles PCI-TJ - - - - [&arch.i386;] Traverse Technologies NETjet-S PCI - - [&arch.i386;] USRobotics Sportster ISDN TA intern - - [&arch.i386;] Winbond W6692 based PCI cards - - Serial Interfaces From 5998ac2fc6fd8ffbb0bd90e3b63988f391dfdf96 Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Thu, 4 Feb 2010 19:47:26 +0000 Subject: [PATCH 1367/2592] MFC r203357: teach groff about libgpib. --- gnu/usr.bin/groff/tmac/mdoc.local | 1 + 1 file changed, 1 insertion(+) diff --git a/gnu/usr.bin/groff/tmac/mdoc.local b/gnu/usr.bin/groff/tmac/mdoc.local index a0389a08f87..85b1f61c4b7 100644 --- a/gnu/usr.bin/groff/tmac/mdoc.local +++ b/gnu/usr.bin/groff/tmac/mdoc.local @@ -46,6 +46,7 @@ .ds doc-str-Lb-libelf ELF Parsing Library (libelf, \-lelf) .ds doc-str-Lb-libfetch File Transfer Library (libfetch, \-lfetch) .ds doc-str-Lb-libgeom Userland API Library for kernel GEOM subsystem (libgeom, \-lgeom) +.ds doc-str-Lb-libgpib General-Purpose Instrument Bus (GPIB) library (libgpib, \-lgpib) .ds doc-str-Lb-libipx IPX Address Conversion Support Library (libipx, \-lipx) .ds doc-str-Lb-libjail Jail Library (libjail, \-ljail) .ds doc-str-Lb-libkiconv Kernel side iconv library (libkiconv, \-lkiconv) From a387b53227b2a35a9c655732e2f701410a51e9f9 Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Thu, 4 Feb 2010 19:49:07 +0000 Subject: [PATCH 1368/2592] MFC r203356: add a manpage for gpib(3). --- lib/libgpib/Makefile | 19 ++ lib/libgpib/gpib.3 | 738 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 757 insertions(+) create mode 100644 lib/libgpib/gpib.3 diff --git a/lib/libgpib/Makefile b/lib/libgpib/Makefile index 5465d8b993a..0ead93f41ca 100644 --- a/lib/libgpib/Makefile +++ b/lib/libgpib/Makefile @@ -7,4 +7,23 @@ INCSDIR= ${INCLUDEDIR}/gpib SRCS= ibfoo.c WARNS?= 6 +MAN= gpib.3 + +# MLINKS are only provided for functions that are actually +# implemented; update this if missing pieces have been filled in. +MLINKS+= gpib.3 ibclr.3 +MLINKS+= gpib.3 ibdev.3 +MLINKS+= gpib.3 ibdma.3 +MLINKS+= gpib.3 ibeos.3 +MLINKS+= gpib.3 ibeot.3 +MLINKS+= gpib.3 ibloc.3 +MLINKS+= gpib.3 ibonl.3 +MLINKS+= gpib.3 ibpad.3 +MLINKS+= gpib.3 ibrd.3 +MLINKS+= gpib.3 ibsad.3 +MLINKS+= gpib.3 ibsic.3 +MLINKS+= gpib.3 ibtmo.3 +MLINKS+= gpib.3 ibtrg.3 +MLINKS+= gpib.3 ibwrt.3 + .include diff --git a/lib/libgpib/gpib.3 b/lib/libgpib/gpib.3 new file mode 100644 index 00000000000..a57d3a42e50 --- /dev/null +++ b/lib/libgpib/gpib.3 @@ -0,0 +1,738 @@ +.\" Copyright (c) 2010, Joerg Wunsch +.\" 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 February 1, 2010 +.Dt GPIB 3 +.Os +.Sh NAME +.\" .Nm ibask , +.\" .Nm ibbna , +.\" .Nm ibcac , +.Nm ibclr , +.\" .Nm ibcmd , +.\" .Nm ibcmda , +.\" .Nm ibconfig , +.Nm ibdev , +.\" .Nm ibdiag , +.Nm ibdma , +.Nm ibeos , +.Nm ibeot , +.\" .Nm ibevent , +.\" .Nm ibfind , +.\" .Nm ibgts , +.\" .Nm ibist , +.\" .Nm iblines , +.\" .Nm ibllo , +.\" .Nm ibln , +.Nm ibloc , +.Nm ibonl , +.Nm ibpad , +.\" .Nm ibpct , +.\" .Nm ibpoke , +.\" .Nm ibppc , +.Nm ibrd , +.\" .Nm ibrda , +.\" .Nm ibrdf , +.\" .Nm ibrdkey , +.\" .Nm ibrpp , +.\" .Nm ibrsc , +.\" .Nm ibrsp , +.\" .Nm ibrsv , +.Nm ibsad , +.\" .Nm ibsgnl , +.Nm ibsic , +.\" .Nm ibsre , +.\" .Nm ibsrq , +.\" .Nm ibstop , +.Nm ibtmo , +.\" .Nm ibtrap , +.Nm ibtrg , +.\" .Nm ibwait , +.Nm ibwrt +.\" .Nm ibwrta , +.\" .Nm ibwrtf , +.\" .Nm ibwrtkey , +.\" .Nm ibxtrc +.Nd "GPIB library" +.Sh LIBRARY +.Lb libgpib +.Sh SYNOPSIS +.In gpib.h +.Pp +.Dv extern int ibcnt , +.Dv iberr , +.Dv ibsta ; +.Pp +.Ft int +.Fn ibask "int handle" "int option" "int *retval" +.Ft int +.Fn ibbna "int handle" "char *bdname" +.Ft int +.Fn ibcac "int handle" "int v" +.Ft int +.Fn ibclr "int handle" +.Ft int +.Fn ibcmd "int handle" "void *buffer" "long cnt" +.Ft int +.Fn ibcmda "int handle" "void *buffer" "long cnt" +.Ft int +.Fn ibconfig "int handle" "int option" "int value" +.Ft int +.Fn ibdev "int boardID" "int pad" "int sad" "int tmo" "int eot" "int eos" +.Ft int +.Fn ibdiag "int handle" "void *buffer" "long cnt" +.Ft int +.Fn ibdma "int handle" "int v" +.Ft int +.Fn ibeos "int handle" "int eos" +.Ft int +.Fn ibeot "int handle" "int eot" +.Ft int +.Fn ibevent "int handle" "short *event" +.Ft int +.Fn ibfind "char *bdname" +.Ft int +.Fn ibgts "int handle" "int v" +.Ft int +.Fn ibist "int handle" "int v" +.Ft int +.Fn iblines "int handle" "short *lines" +.Ft int +.Fn ibllo "int handle" +.Ft int +.Fn ibln "int handle" "int padval" "int sadval" "short *listenflag" +.Ft int +.Fn ibloc "int handle" +.Ft int +.Fn ibonl "int handle" "int v" +.Ft int +.Fn ibpad "int handle" "int pad" +.Ft int +.Fn ibpct "int handle" +.Ft int +.Fn ibpoke "int handle" "int option" "int value" +.Ft int +.Fn ibppc "int handle" "int v" +.Ft int +.Fn ibrd "int handle" "void *buffer" "long cnt" +.Ft int +.Fn ibrda "int handle" "void *buffer" "long cnt" +.Ft int +.Fn ibrdf "int handle" "char *flname" +.Ft int +.Fn ibrdkey "int handle" "void *buffer" "int cnt" +.Ft int +.Fn ibrpp "int handle" "char *ppr" +.Ft int +.Fn ibrsc "int handle" "int v" +.Ft int +.Fn ibrsp "int handle" "char *spr" +.Ft int +.Fn ibrsv "int handle" "int v" +.Ft int +.Fn ibsad "int handle" "int sad" +.Ft int +.Fn ibsgnl "int handle" "int v" +.Ft int +.Fn ibsic "int handle" +.Ft int +.Fn ibsre "int handle" "int v" +.Ft int +.Fn ibsrq "(*func) void)" +.Ft int +.Fn ibstop "int handle" +.Ft int +.Fn ibtmo "int handle" "int tmo" +.Ft int +.Fn ibtrap "int mask" "int mode" +.Ft int +.Fn ibtrg "int handle" +.Ft int +.Fn ibwait "int handle" "int mask" +.Ft int +.Fn ibwrt "int handle" "const void *buffer" "long cnt" +.Ft int +.Fn ibwrta "int handle" "const void *buffer" "long cnt" +.Ft int +.Fn ibwrtf "int handle" "const char *flname" +.Ft int +.Fn ibwrtkey "int handle" "const void *buffer" "int cnt" +.Ft int +.Fn ibxtrc "int handle" "void *buffer" "long cnt" +.Sh DESCRIPTION +The +.Nm +library provides access to the +.Xr gpib 4 +kernel devices. +.Ss Variable Description +The variable +.Dv ibcnt +contains the number of bytes transferred in the most recent call to +.Fn ibcmd , +.Fn ibrd , +or +.Fn ibwrt . +.Pp +The name +.Dv ibcntl +is an alias for +.Dv ibcnt , +provided for backwards compatibility. +.Pp +The variable +.Dv iberr +provides an error code for the most recent library call. +The possible error codes are: +.Bl -tag -offset indent -compact +.It EDVR +System error +.It ECIC +Not Active Controller +.It ENOL +Nobody listening +.It EADR +Controller not addressed +.It EARG +Invalid argument +.It ESAC +Not System Controller +.It EABO +I/O Aborted/Time out +.It ENEB +No such controller +.It EOIP +Async I/O in progress +.It ECAP +No such capability +.It EFSO +File system error +.It EBUS +Command byte xfer error +.It ESTB +Serial poll status byte lost +.It ESRQ +SRQ line stuck +.It ETAB +Table problem +.El +.Pp +The variable +.Dv ibsta +contains the controller status. +This is an ORed status value, with the following individual bit names: +.Bl -tag -offset indent -compact +.It ERR +Error +.It TIMO +Timeout +.It END +EOI/EOS +.It SRQI +SRQ +.It RQS +Device requests service +.It SPOLL +Serial Poll +.It EVENT +Event occured +.It CMPL +I/O complete +.It LOK +Lockout +.It REM +Remote +.It CIC +CIC +.It ATN +ATN +.It TACS +Talker +.It LACS +Listener +.It DTAS +Device trigger status +.It DCAS +Device clear state +.El +.Ss Function Description +.Pp +The function +.Fn ibdev +is used to open the GPIB device, and establish the parameters to +communicate with a particular bus device. The device is selected +by its primary address +.Fa pad , +a numerical value between 0 and 30, possibly additionally by its +secondary address +.Fa sad , +a numerical value between 96 and 126, or 0 to not use secondary +addressing. +The +.Fa tmo +value specifies the timeout to use when communicating with the device. +This can be any of the constants +.Dv TNONE , +.Dv T10us , +.Dv T30us , +.Dv T100us , +.Dv T300us , +.Dv T1ms , +.Dv T3ms , +.Dv T10ms , +.Dv T30ms , +.Dv T100ms , +.Dv T300ms , +.Dv T1s , +.Dv T3s , +.Dv T10s , +.Dv T30s , +.Dv T100s , +.Dv T300s , +or +.Dv T1000s . +The boolean parameter +.Fa eot +specifies whether the bus signal +.Li EOI +(end-or-identify) should be asserted when sending the last byte of a +message to the device. +Finally, the +.Fa eos +parameter determines whether any special character should be used to +identify the end of a device message when transferring messages on the +bus. +The lower 8 bits of +.Fa eos +are interpreted as an end-of-string character, +.Li EOS . +This character can be ORed with the following values: +.Bl -tag -compact -offset indent +.It Dv REOS +When receiving a message byte on the bus that matches the +.Li EOS +character, treat it as if the +.Li EOI +signal were asserted, and stop receiving. +.It Dv XEOS +When transmitting a message byte on the bus that matches the +.Li EOS +character, assert the +.Li EOI +bus signal by the same time, and stop sending. +.It Dv BIN +If set, include all 8 bits of the +.Li EOS +character in the comparison; if unset, compare only 7 bit ASCII +values. +.El +Passing 0 as +.Fa eos +will turn off any special character treatment, allowing for a fully +8-bit transparent communications channel to the device. +.Pp +The function +.Fn ibfind +is meant to find the +.Em board index +of a board identified by the name +.Fa bdname . +.Em This function is currently not implemented. +.Pp +All remaining functions take the handle returned by calling +.Fn ibdev +as their first argument +.Fa handle . +.Pp +The function +.Fn ibask +is used to query configuration values that have been set with +.Fn ibconfig . +.Em This function is currently not implemented. +.Pp +The function +.Fn ibbna +is meant to change the access board for the given device to +a new one, named +.Fa bdname . +.Em This function is currently not implemented. +.Pp +The function +.Fn ibcac +is used to become the active controller on the bus, by asserting the +.Li ATN +signal line. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibclr +is used to transmit a +.Em Selected Device Clear +command to the device. +.Pp +The function +.Fn ibcmd +is used to directly write +.Fa cnt +GPIB command bytes from a buffer starting at +.Fa buffer +to the device. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibcmda +does the same as +.Fn ibcmd +except it operates asynchronously, so it returns to the caller +immediately. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibconfig +is used to set certain configuration parameters. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibdiag +is obsolete, and not implemented. +.Pp +The function +.Fn ibdma +is used to enable or disable DMA transfers. +Parameter +.Fa v +is a boolean parameter indicating DMA transfers are to be used. +Depending on the hardware and operating system configuration, DMA +transfers might not be available for a particular access board. +.Pp +The function +.Fn ibeos +configures the end-of-string character. +See +.Fn ibdev +for an explanation. +.Pp +The function +.Fn ibeot +configures the assertion of the +.Li EOI +signal line when transmitting the last byte of a message; see +.Fn ibdev +for an explanation. +.Pp +The function +.Fn ibevent +is used to obtain an event from the board's event queue. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibgts +makes the current controller the standby controller, by deasserting +the +.Li ATN +signal line. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibist +sets the individual status bits of the controller to the value +.Fa v . +.Em This function is currently not implemented. +.Pp +The function +.Fn iblines +returns the status of the control and handshake bus lines into the +area pointed to by +.Fa lines . +.Em This function is currently not implemented. +.Pp +The function +.Fn ibllo +is obsolete, and not implemented. +.Pp +The function +.Fn ibln +checks for a listener at the primary address +.Fa padval +and the optional secondary address +.Fa sadval . +If a listener was found, the value pointed to by +.Fa listenflag +will be set to a non-zero value. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibloc +turns the device into local mode. +.Pp +The function +.Fn ibonl +is used to close or reinitialize a device handle. +If parameter +.Fa v +is passed as zero, the handle will be closed, and cannot be used +again. +If it is passed as a non-zero value, all parameters of the handle +will be returned to their defaults; +.Em this functionality is currently unsupported. +.Pp +The function +.Fn ibpad +is used to change the primary address of the device being communicated +with to +.Fa pad . +See +.Fn ibdev +for an explanation. +.Pp +The function +.Fn ibpct +is used to make the device associated with the handle the +controller-in-charge. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibpoke +is obsolete, and not implemented. +.Pp +The function +.Fn ibppc +is used to configure the parallel poll response to +.Fa v . +.Em This function is currently not implemented. +.Pp +The fucntion +.Fn ibrd +is used to receive +.Fa cnt +bytes from the device, and store it to the address passed as +.Fa buffer . +.Pp +The function +.Fn ibrda +behaves similar to +.Fn ibrd +except it operates asynchronously, and returns immediately to the +caller. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibrdf +read data from the device, and appends it to the file with the name +.Fa flname . +.Em This function is currently not implemented. +.Pp +The function +.Fn ibrdkey +is obsolete, and not implemented. +.Pp +The function +.Fn ibrpp +performs a parallel poll, and stores the result at the location +pointed to by +.Fa ppr . +.Em This function is currently not implemented. +.Pp +The function +.Fn ibrsc +makes the board specified by the handle the +.Em system controller +if the argument +.Fa v +is non-zero. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibrsp +conducts a serial poll, and stores the result in the byte pointed +to by +.Fa spr . +.Em This function is currently not implemented. +.Pp +The function +.Fn ibrsv +sets the serial poll response of the board to +.Fa v , +possibly requesting service from the controller if the SRQ bit (0x40) +is set. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibsad +changes the secondary address of the device being communicated with to +.Fa sad . +See +.Fn ibdev +for an explanation. +.Pp +The function +.Fn ibsgnl +is obsolete, and not implemented. +.Pp +The function +.Fn ibsic +asserts the +.Em Interface Clear (IFC) +signal line on the bus for at least 100 microseconds. +This will make all devices attached to the bus to unlisten and untalk. +This function should only be executed on the system controller. +.Pp +The function +.Fn ibsre +asserts the +.Em Remote Enable (REN) +signal line on the bus if argument +.Fa v +is non-zero, or deasserts it otherwise. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibsrq +is obsolete, and not implemented. +.Pp +The function +.Fn ibstop +stops or aborts any asynchronous I/O operation. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibtmo +reconfigures the communication timeout. +See +.Fn ibdev +for an explanation. +.Pp +The function +.Fn ibtrap +is obsolete, and not implemented. +.Pp +The function +.Fn ibtrg +sends a +.Em Group Execute Trigger (GET) +command to the device. +.Pp +The function +.Fn ibwait +waits for a status condition as specified by +.Fa mask . +If +.Fa mask +is given as zero, it returns immediately. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibwrt +is used to send +.Fa cnt +bytes to the device, starting at the address pointed to by +.Fa buffer . +.Pp +The function +.Fn ibwrta +performs the same operation as +.Fn ibwrt +in an asynchronous way, returning immediately to the caller. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibwrtf +opens the file named by +.Fa flname , +and sends its contents to the device. +.Em This function is currently not implemented. +.Pp +The function +.Fn ibwrtkey +is obsolete, and not implemented +.Pp +The function +.Fn ibxtrc +is obsolete, and not implemented. +.Sh RETURN VALUES +The function +.Fn ibdev +returns a handle to be used for the remaining functions. +Upon failure, -1 is returned. +.Pp +All other functions return the value of the variable +.Dv ibsta . +.Sh DIAGNOSTICS +None. +.Sh COMPATIBILITY +The +.Nm +library tries to be compatible with the Linux GPIB library, +which in turn appears to be compatible with the GPIB library +shipped by National Instruments. +.Sh ERRORS +Errors in the functions above might set +.Dv errno +to one of these values: +.Bl -tag -width Er +.It Bq Er ENOENT +No such file or directory. +.It Bq Er EIO +Input/output error. +.It Bq Er ENXIO +Device not configured. +.It Bq Er E2BIG +Argument list too long. +.It Bq Er ENOMEM +Cannot allocate memory. +.It Bq Er EACCES +Permission denied. +.It Bq Er EFAULT +Bad address. +.It Bq Er EBUSY +Device busy. +.It Bq Er EINVAL +Invalid argument. +.It Bq Er ENFILE +Too many open files in system. +.It Bq Er EMFILE +Too many open files. +.It Bq Er EOPNOTSUPP +Operation not supported. +.El +.Sh SEE ALSO +.Xr gpib 4 +.Sh HISTORY +The +.Nm +library was written by +.An Poul-Henning Kamp +and first appeared in +.Fx 5.4 . +.Sh AUTHORS +This manual page was written by +.An J\(:org Wunsch . +.Sh BUGS +Currently, the library can only handle a single +.Xr gpib 4 +device with instance number 0. +.Pp +Many functions are currently not implemented, see above for details. From 0ad7cd49e7837e704de8eb3b247cddb96bf8831e Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Thu, 4 Feb 2010 19:49:41 +0000 Subject: [PATCH 1369/2592] MFC r203359: active xrefs to gpib(3) now that it's actually there. --- share/man/man4/gpib.4 | 2 +- share/man/man4/pcii.4 | 2 +- share/man/man4/tnt4882.4 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/share/man/man4/gpib.4 b/share/man/man4/gpib.4 index 948e5ee003e..6420e4f411a 100644 --- a/share/man/man4/gpib.4 +++ b/share/man/man4/gpib.4 @@ -54,7 +54,7 @@ When opening, an instrument can send data to this device on the bus in an unaddressed mode, for example hard-copy printer data. .El .Sh SEE ALSO -.\" .Xr libgpib 3 , +.Xr gpib 3 , .Xr pcii 4 , .Xr tnt4882 4 .Sh HISTORY diff --git a/share/man/man4/pcii.4 b/share/man/man4/pcii.4 index 026d6963da0..d496113f2a6 100644 --- a/share/man/man4/pcii.4 +++ b/share/man/man4/pcii.4 @@ -84,7 +84,7 @@ National Instruments GPIB-PCII/PCIIA (in PCIIa mode) Axiom AX5488 .El .Sh SEE ALSO -.\" .Xr libgpib 3 , +.Xr gpib 3 , .Xr gpib 4 , .Xr device.hints 5 .Sh HISTORY diff --git a/share/man/man4/tnt4882.4 b/share/man/man4/tnt4882.4 index f96599a0f2a..d95ff8981cf 100644 --- a/share/man/man4/tnt4882.4 +++ b/share/man/man4/tnt4882.4 @@ -43,7 +43,7 @@ the TNT4882 bus interface chip. This chip emulates a NEC \(mcPD7210 controller IC as the main interface between the host computer and the instrument bus. .Sh SEE ALSO -.\" .Xr libgpib 3 , +.Xr gpib 3 , .Xr gpib 4 , .Sh HISTORY The From 24f890094ee5799831798f5af116bdaecdaf181b Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 5 Feb 2010 08:32:07 +0000 Subject: [PATCH 1370/2592] MFC r202736: Print playback channels paths in order of their sequence numbers, not nids. --- sys/dev/sound/pci/hda/hdac.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index ce3372889fc..4283ff41651 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -7091,27 +7091,27 @@ hdac_dump_dac(struct hdac_pcm_devinfo *pdevinfo) { struct hdac_devinfo *devinfo = pdevinfo->devinfo; struct hdac_softc *sc = devinfo->codec->sc; + struct hdac_audio_as *as; struct hdac_widget *w; int i, printed = 0; if (pdevinfo->play < 0) return; - for (i = devinfo->startnode; i < devinfo->endnode; i++) { - w = hdac_widget_get(devinfo, i); + as = &devinfo->function.audio.as[sc->chans[pdevinfo->play].as]; + for (i = 0; i < 16; i++) { + if (as->pins[i] <= 0) + continue; + w = hdac_widget_get(devinfo, as->pins[i]); if (w == NULL || w->enable == 0) continue; - if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) - continue; - if (w->bindas != sc->chans[pdevinfo->play].as) - continue; if (printed == 0) { printed = 1; device_printf(pdevinfo->dev, "\n"); device_printf(pdevinfo->dev, "Playback:\n"); } device_printf(pdevinfo->dev, "\n"); - hdac_dump_dst_nid(pdevinfo, i, 0); + hdac_dump_dst_nid(pdevinfo, as->pins[i], 0); } } From 9eb48f44f2fcd1db0a70a848206fca7dbf3cb0bc Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 5 Feb 2010 08:36:33 +0000 Subject: [PATCH 1371/2592] MFC r202789, r202796: - Improve tracer, to handle more cases of input-to-output monitoring loopback. - Use "igain" mixer control for input-to-output monitoring loopback. - Allow AD1981HD codecs to use playback mixer. Now driver should be able to really use it. - Fix bug in shared muters operation. --- sys/dev/sound/pci/hda/hdac.c | 154 +++++++++++++++++++++-------------- 1 file changed, 94 insertions(+), 60 deletions(-) diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 4283ff41651..84fc32283a6 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -86,7 +86,7 @@ #include "mixer_if.h" -#define HDA_DRV_TEST_REV "20100112_0140" +#define HDA_DRV_TEST_REV "20100122_0141" SND_DECLARE_FILE("$FreeBSD$"); @@ -3934,8 +3934,8 @@ hdac_audio_ctl_ossmixer_set(struct snd_mixer *m, unsigned dev, rvol = rvol * pdevinfo->right[j] / 100; } } - mute = (left == 0) ? HDA_AMP_MUTE_LEFT : 0; - mute |= (right == 0) ? HDA_AMP_MUTE_RIGHT : 0; + mute = (lvol == 0) ? HDA_AMP_MUTE_LEFT : 0; + mute |= (rvol == 0) ? HDA_AMP_MUTE_RIGHT : 0; lvol = (lvol * ctl->step + 50) / 100; rvol = (rvol * ctl->step + 50) / 100; hdac_audio_ctl_amp_set(ctl, mute, lvol, rvol); @@ -4757,37 +4757,6 @@ hdac_vendor_patch_parse(struct hdac_devinfo *devinfo) } switch (id) { -#if 0 - case HDA_CODEC_ALC883: - /* - * nid: 24/25 = External (jack) or Internal (fixed) Mic. - * Clear vref cap for jack connectivity. - */ - w = hdac_widget_get(devinfo, 24); - if (w != NULL && w->enable != 0 && w->type == - HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && - (w->wclass.pin.config & - HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) == - HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK) - w->wclass.pin.cap &= ~( - HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK | - HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK | - HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK); - w = hdac_widget_get(devinfo, 25); - if (w != NULL && w->enable != 0 && w->type == - HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && - (w->wclass.pin.config & - HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) == - HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK) - w->wclass.pin.cap &= ~( - HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK | - HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK | - HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK); - /* - * nid: 26 = Line-in, leave it alone. - */ - break; -#endif case HDA_CODEC_AD1983: /* * This codec has several possible usages, but none @@ -4900,10 +4869,19 @@ hdac_vendor_patch_parse(struct hdac_devinfo *devinfo) w = hdac_widget_get(devinfo, 31); if (w != NULL) w->enable = 0; - /* Disable playback mixer, use direct bypass. */ - w = hdac_widget_get(devinfo, 14); + /* Disable direct playback, use mixer. */ + w = hdac_widget_get(devinfo, 5); if (w != NULL) - w->enable = 0; + w->connsenable[0] = 0; + w = hdac_widget_get(devinfo, 6); + if (w != NULL) + w->connsenable[0] = 0; + w = hdac_widget_get(devinfo, 9); + if (w != NULL) + w->connsenable[0] = 0; + w = hdac_widget_get(devinfo, 24); + if (w != NULL) + w->connsenable[0] = 0; break; } } @@ -5279,6 +5257,8 @@ hdac_audio_trace_to_out(struct hdac_devinfo *devinfo, nid_t nid, int depth) " %*snid %d found output association %d\n", depth + 1, "", w->nid, w->bindas); ); + if (w->bindas >= 0) + w->pflags |= HDA_ADC_MONITOR; return (1); } else { HDA_BOOTHVERBOSE( @@ -5321,7 +5301,7 @@ hdac_audio_trace_to_out(struct hdac_devinfo *devinfo, nid_t nid, int depth) } break; } - if (res) + if (res && w->bindas == -1) w->bindas = -2; HDA_BOOTHVERBOSE( @@ -5368,11 +5348,39 @@ hdac_audio_trace_as_extra(struct hdac_devinfo *devinfo) " nid %d is input monitor\n", w->nid); ); - w->pflags |= HDA_ADC_MONITOR; w->ossdev = SOUND_MIXER_IMIX; } } + /* Other inputs monitor */ + /* Find input pins supplying signal for output associations. + Hope it will be input monitoring. */ + HDA_BOOTVERBOSE( + device_printf(devinfo->codec->sc->dev, + "Tracing other input monitors\n"); + ); + for (j = devinfo->startnode; j < devinfo->endnode; j++) { + w = hdac_widget_get(devinfo, j); + if (w == NULL || w->enable == 0) + continue; + if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) + continue; + if (w->bindas < 0 || as[w->bindas].dir != HDA_CTL_IN) + continue; + HDA_BOOTVERBOSE( + device_printf(devinfo->codec->sc->dev, + " Tracing nid %d to out\n", + j); + ); + if (hdac_audio_trace_to_out(devinfo, w->nid, 0)) { + HDA_BOOTVERBOSE( + device_printf(devinfo->codec->sc->dev, + " nid %d is input monitor\n", + w->nid); + ); + } + } + /* Beeper */ HDA_BOOTVERBOSE( device_printf(devinfo->codec->sc->dev, @@ -5748,6 +5756,7 @@ hdac_audio_disable_notselected(struct hdac_devinfo *devinfo) static void hdac_audio_disable_crossas(struct hdac_devinfo *devinfo) { + struct hdac_audio_as *ases = devinfo->function.audio.as; struct hdac_widget *w, *cw; struct hdac_audio_ctl *ctl; int i, j; @@ -5770,7 +5779,10 @@ hdac_audio_disable_crossas(struct hdac_devinfo *devinfo) cw = hdac_widget_get(devinfo, w->conns[j]); if (cw == NULL || w->enable == 0) continue; - if (cw->bindas == -2) + if (cw->bindas == -2 || + ((w->pflags & HDA_ADC_MONITOR) && + cw->bindas >= 0 && + ases[cw->bindas].dir == HDA_CTL_IN)) continue; if (w->bindas == cw->bindas && (w->bindseqmask & cw->bindseqmask) != 0) @@ -5789,8 +5801,12 @@ hdac_audio_disable_crossas(struct hdac_devinfo *devinfo) while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { if (ctl->enable == 0 || ctl->childwidget == NULL) continue; - if (ctl->widget->bindas == -2 || - ctl->childwidget->bindas == -2) + if (ctl->widget->bindas == -2) + continue; + if (ctl->childwidget->bindas == -2 || + ((ctl->widget->pflags & HDA_ADC_MONITOR) && + ctl->childwidget->bindas >= 0 && + ases[ctl->childwidget->bindas].dir == HDA_CTL_IN)) continue; if (ctl->widget->bindas != ctl->childwidget->bindas || (ctl->widget->bindseqmask & ctl->childwidget->bindseqmask) == 0) { @@ -5909,7 +5925,7 @@ hdac_audio_ctl_source_amp(struct hdac_devinfo *devinfo, nid_t nid, int index, * Find controls to control amplification for destination. */ static void -hdac_audio_ctl_dest_amp(struct hdac_devinfo *devinfo, nid_t nid, +hdac_audio_ctl_dest_amp(struct hdac_devinfo *devinfo, nid_t nid, int index, int ossdev, int depth, int need) { struct hdac_audio_as *as = devinfo->function.audio.as; @@ -5968,6 +5984,8 @@ hdac_audio_ctl_dest_amp(struct hdac_devinfo *devinfo, nid_t nid, int tneed = need; if (w->connsenable[i] == 0) continue; + if (index >= 0 && i != index) + continue; ctl = hdac_audio_ctl_amp_get(devinfo, w->nid, HDA_CTL_IN, i, 1); if (ctl) { @@ -5977,7 +5995,7 @@ hdac_audio_ctl_dest_amp(struct hdac_devinfo *devinfo, nid_t nid, ctl->possmask |= (1 << ossdev); tneed &= ~HDA_CTL_GIVE(ctl); } - hdac_audio_ctl_dest_amp(devinfo, w->conns[i], ossdev, + hdac_audio_ctl_dest_amp(devinfo, w->conns[i], -1, ossdev, depth + 1, tneed); } } @@ -6184,8 +6202,8 @@ hdac_audio_assign_mixers(struct hdac_devinfo *devinfo) { struct hdac_audio_as *as = devinfo->function.audio.as; struct hdac_audio_ctl *ctl; - struct hdac_widget *w; - int i; + struct hdac_widget *w, *cw; + int i, j; /* Assign mixers to the tree. */ for (i = devinfo->startnode; i < devinfo->endnode; i++) { @@ -6200,23 +6218,38 @@ hdac_audio_assign_mixers(struct hdac_devinfo *devinfo) continue; hdac_audio_ctl_source_amp(devinfo, w->nid, -1, w->ossdev, 1, 0, 1); - } else if ((w->pflags & HDA_ADC_MONITOR) != 0) { - if (w->ossdev < 0) - continue; + } else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) { + hdac_audio_ctl_dest_amp(devinfo, w->nid, -1, + SOUND_MIXER_RECLEV, 0, 1); + } else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && + as[w->bindas].dir == HDA_CTL_OUT) { + hdac_audio_ctl_dest_amp(devinfo, w->nid, -1, + SOUND_MIXER_VOLUME, 0, 1); + } + if (w->ossdev == SOUND_MIXER_IMIX) { if (hdac_audio_ctl_source_amp(devinfo, w->nid, -1, w->ossdev, 1, 0, 1)) { /* If we are unable to control input monitor as source - try to control it as destination. */ - hdac_audio_ctl_dest_amp(devinfo, w->nid, + hdac_audio_ctl_dest_amp(devinfo, w->nid, -1, w->ossdev, 0, 1); } - } else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) { - hdac_audio_ctl_dest_amp(devinfo, w->nid, - SOUND_MIXER_RECLEV, 0, 1); - } else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && - as[w->bindas].dir == HDA_CTL_OUT) { - hdac_audio_ctl_dest_amp(devinfo, w->nid, - SOUND_MIXER_VOLUME, 0, 1); + } + if (w->pflags & HDA_ADC_MONITOR) { + for (j = 0; j < w->nconns; j++) { + if (!w->connsenable[j]) + continue; + cw = hdac_widget_get(devinfo, w->conns[j]); + if (cw == NULL || cw->enable == 0) + continue; + if (cw->bindas == -1) + continue; + if (cw->bindas >= 0 && + as[cw->bindas].dir != HDA_CTL_IN) + continue; + hdac_audio_ctl_dest_amp(devinfo, + w->nid, j, SOUND_MIXER_IGAIN, 0, 1); + } } } /* Treat unrequired as possible. */ @@ -6715,8 +6748,8 @@ hdac_dump_ctls(struct hdac_pcm_devinfo *pdevinfo, const char *banner, uint32_t f if (flag == 0) { flag = ~(SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_CD | SOUND_MASK_LINE | SOUND_MASK_RECLEV | - SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_OGAIN | - SOUND_MASK_IMIX | SOUND_MASK_MONITOR); + SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IGAIN | + SOUND_MASK_OGAIN | SOUND_MASK_IMIX | SOUND_MASK_MONITOR); } for (j = 0; j < SOUND_MIXER_NRDEVICES; j++) { @@ -7160,7 +7193,7 @@ hdac_dump_mix(struct hdac_pcm_devinfo *pdevinfo) w = hdac_widget_get(devinfo, i); if (w == NULL || w->enable == 0) continue; - if ((w->pflags & HDA_ADC_MONITOR) == 0) + if (w->ossdev != SOUND_MIXER_IMIX) continue; if (printed == 0) { printed = 1; @@ -8127,6 +8160,7 @@ hdac_pcm_attach(device_t dev) hdac_dump_ctls(pdevinfo, "Speaker/Beep Volume", SOUND_MASK_SPEAKER); hdac_dump_ctls(pdevinfo, "Recording Level", SOUND_MASK_RECLEV); hdac_dump_ctls(pdevinfo, "Input Mix Level", SOUND_MASK_IMIX); + hdac_dump_ctls(pdevinfo, "Input Monitoring Level", SOUND_MASK_IGAIN); hdac_dump_ctls(pdevinfo, NULL, 0); device_printf(dev, "\n"); ); From 3a5d679ee579dc7d0d42d7797b89b579a9bf4535 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 5 Feb 2010 08:48:44 +0000 Subject: [PATCH 1372/2592] MFC r202694: - Add -v argument to `camcontrol identify` command. It makes camcontrol print full identify data block. - Improve identify result view a bit and add TRIM support. --- sbin/camcontrol/camcontrol.8 | 3 ++- sbin/camcontrol/camcontrol.c | 51 ++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8 index 0509ef7372c..d1e9587ab95 100644 --- a/sbin/camcontrol/camcontrol.8 +++ b/sbin/camcontrol/camcontrol.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 9, 2009 +.Dd January 20, 2010 .Dt CAMCONTROL 8 .Os .Sh NAME @@ -62,6 +62,7 @@ .Ic identify .Op device id .Op generic args +.Op Fl v .Nm .Ic reportluns .Op device id diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 1e71ae0caae..c98d5c9428b 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -1166,8 +1166,6 @@ atacapprint(struct ata_params *parm) } printf("\n"); - printf("overlap%ssupported\n", - parm->capabilities1 & ATA_SUPPORT_OVERLAP ? " " : " not "); if (parm->media_rotation_rate == 1) { printf("media RPM non-rotating\n"); } else if (parm->media_rotation_rate >= 0x0401 && @@ -1187,20 +1185,26 @@ atacapprint(struct ata_params *parm) printf("flush cache %s %s\n", parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no", parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no"); - if (parm->satacapabilities && parm->satacapabilities != 0xffff) { - printf("Native Command Queuing (NCQ) %s " - " %d/0x%02X\n", - parm->satacapabilities & ATA_SUPPORT_NCQ ? - "yes" : "no", - (parm->satacapabilities & ATA_SUPPORT_NCQ) ? - ATA_QUEUE_LEN(parm->queue) : 0, - (parm->satacapabilities & ATA_SUPPORT_NCQ) ? - ATA_QUEUE_LEN(parm->queue) : 0); - } - printf("Tagged Command Queuing (TCQ) %s %s %d/0x%02X\n", + printf("overlap %s\n", + parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no"); + printf("Tagged Command Queuing (TCQ) %s %s", parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no", - parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no", - ATA_QUEUE_LEN(parm->queue), ATA_QUEUE_LEN(parm->queue)); + parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no"); + if (parm->support.command2 & ATA_SUPPORT_QUEUED) { + printf(" %d tags\n", + ATA_QUEUE_LEN(parm->queue) + 1); + } else + printf("\n"); + if (parm->satacapabilities && parm->satacapabilities != 0xffff) { + printf("Native Command Queuing (NCQ) %s ", + parm->satacapabilities & ATA_SUPPORT_NCQ ? + "yes" : "no"); + if (parm->satacapabilities & ATA_SUPPORT_NCQ) { + printf(" %d tags\n", + ATA_QUEUE_LEN(parm->queue) + 1); + } else + printf("\n"); + } printf("SMART %s %s\n", parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no", parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no"); @@ -1241,6 +1245,8 @@ atacapprint(struct ata_params *parm) printf("free-fall %s %s\n", parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no", parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no"); + printf("data set management (TRIM) %s\n", + parm->support_dsm & ATA_SUPPORT_DSM_TRIM ? "yes" : "no"); } @@ -1327,8 +1333,18 @@ ataidentify(struct cam_device *device, int retry_count, int timeout) for (i = 0; i < sizeof(struct ata_params) / 2; i++) ptr[i] = le16toh(ptr[i]); + if (arglist & CAM_ARG_VERBOSE) { + fprintf(stdout, "%s%d: Raw identify data:\n", + device->device_name, device->dev_unit_num); + for (i = 0; i < sizeof(struct ata_params) / 2; i++) { + if ((i % 8) == 0) + fprintf(stdout, " %3d: ", i); + fprintf(stdout, "%04x ", (uint16_t)ptr[i]); + if ((i % 8) == 7) + fprintf(stdout, "\n"); + } + } ident_buf = (struct ata_params *)ptr; - if (strncmp(ident_buf->model, "FX", 2) && strncmp(ident_buf->model, "NEC", 3) && strncmp(ident_buf->model, "Pioneer", 7) && @@ -2286,6 +2302,7 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, error = 1; goto scsicmd_bailout; } + bzero(data_ptr, data_bytes); /* * If the user supplied "-" instead of a format, he * wants the data to be read from stdin. @@ -4305,7 +4322,7 @@ usage(int verbose) " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n" " camcontrol tur [dev_id][generic args]\n" " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n" -" camcontrol identify [dev_id][generic args]\n" +" camcontrol identify [dev_id][generic args] [-v]\n" " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n" " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n" " [-q] [-s]\n" From 75cf52103d463aa83358381aa1a6b18a7c7b20b9 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Fri, 5 Feb 2010 08:52:51 +0000 Subject: [PATCH 1373/2592] Merge r202161 from head: Spell "Hz" correctly wherever it is user-visible. PR: bin/142566 Submitted by: N.J. Mann njm njm.me.uk --- sbin/ifconfig/ifieee80211.c | 10 +++++----- share/man/man4/ath.4 | 2 +- share/man/man4/cpufreq.4 | 2 +- share/man/man4/vge.4 | 2 +- sys/amd64/amd64/local_apic.c | 2 +- sys/dev/aic7xxx/aic79xx_pci.c | 8 ++++---- sys/dev/ath/ath_hal/ar5210/ar5210_reset.c | 2 +- sys/dev/ath/if_ath.c | 2 +- sys/dev/ct/ct_isa.c | 2 +- sys/dev/mly/mly.c | 2 +- sys/i386/i386/local_apic.c | 2 +- tools/tools/ath/athdecode/main.c | 6 +++--- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index ccb650c6e99..48201bd74ef 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -3429,9 +3429,9 @@ get_chaninfo(const struct ieee80211_channel *c, int precise, else if (IEEE80211_IS_CHAN_B(c)) strlcat(buf, " 11b", bsize); if (IEEE80211_IS_CHAN_HALF(c)) - strlcat(buf, "/10Mhz", bsize); + strlcat(buf, "/10MHz", bsize); if (IEEE80211_IS_CHAN_QUARTER(c)) - strlcat(buf, "/5Mhz", bsize); + strlcat(buf, "/5MHz", bsize); if (IEEE80211_IS_CHAN_TURBO(c)) strlcat(buf, " Turbo", bsize); if (precise) { @@ -3453,7 +3453,7 @@ print_chaninfo(const struct ieee80211_channel *c, int verb) { char buf[14]; - printf("Channel %3u : %u%c Mhz%-14.14s", + printf("Channel %3u : %u%c MHz%-14.14s", ieee80211_mhz2ieee(c->ic_freq, c->ic_flags), c->ic_freq, IEEE80211_IS_CHAN_PASSIVE(c) ? '*' : ' ', get_chaninfo(c, verb, buf, sizeof(buf))); @@ -3562,7 +3562,7 @@ list_channels(int s, int allchans) static void print_txpow(const struct ieee80211_channel *c) { - printf("Channel %3u : %u Mhz %3.1f reg %2d ", + printf("Channel %3u : %u MHz %3.1f reg %2d ", c->ic_ieee, c->ic_freq, c->ic_maxpower/2., c->ic_maxregpower); } @@ -4244,7 +4244,7 @@ ieee80211_status(int s) c = getcurchan(s); if (c->ic_freq != IEEE80211_CHAN_ANY) { char buf[14]; - printf(" channel %d (%u Mhz%s)", c->ic_ieee, c->ic_freq, + printf(" channel %d (%u MHz%s)", c->ic_ieee, c->ic_freq, get_chaninfo(c, 1, buf, sizeof(buf))); } else if (verbose) printf(" channel UNDEF"); diff --git a/share/man/man4/ath.4 b/share/man/man4/ath.4 index cfc256c84d8..c2344cba419 100644 --- a/share/man/man4/ath.4 +++ b/share/man/man4/ath.4 @@ -249,7 +249,7 @@ This should not happen. An invalid transmit rate was specified for an outgoing frame. The frame is discarded. This should not happen. -.It "ath%d: ath_chan_set: unable to reset channel %u (%u Mhz)" +.It "ath%d: ath_chan_set: unable to reset channel %u (%u MHz)" The Atheros Hardware Access Layer was unable to reset the hardware when switching channels during scanning. This should not happen. diff --git a/share/man/man4/cpufreq.4 b/share/man/man4/cpufreq.4 index aa1da043fc4..bd6885eb4f5 100644 --- a/share/man/man4/cpufreq.4 +++ b/share/man/man4/cpufreq.4 @@ -234,7 +234,7 @@ The driver should set unknown or irrelevant values to All the following elements for each setting should be returned: .Bd -literal struct cf_setting { - int freq; /* CPU clock in Mhz or 100ths of a percent. */ + int freq; /* CPU clock in MHz or 100ths of a percent. */ int volts; /* Voltage in mV. */ int power; /* Power consumed in mW. */ int lat; /* Transition latency in us. */ diff --git a/share/man/man4/vge.4 b/share/man/man4/vge.4 index 7efc99ee121..f6ce47c85b9 100644 --- a/share/man/man4/vge.4 +++ b/share/man/man4/vge.4 @@ -58,7 +58,7 @@ driver provides support for various NICs and embedded Ethernet interfaces based on the VIA Technologies VT6120, VT6122, VT6130 and VT6132 Velocity Family Gigabit Ethernet controller chips. .Pp -The VT6120/VT6122 is a 33/66Mhz 64-bit PCI device which combines a tri-speed +The VT6120/VT6122 is a 33/66MHz 64-bit PCI device which combines a tri-speed MAC with an integrated 10/100/1000 copper PHY. (Some older cards use an external PHY.) The VT6130/VT6132 is the PCI express version of Velocity family. diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c index 87bec91b6c4..98ed4df8307 100644 --- a/sys/amd64/amd64/local_apic.c +++ b/sys/amd64/amd64/local_apic.c @@ -448,7 +448,7 @@ lapic_setup_clock(void) panic("lapic: Divisor too big"); value /= 2; if (bootverbose) - printf("lapic: Divisor %lu, Frequency %lu hz\n", + printf("lapic: Divisor %lu, Frequency %lu Hz\n", lapic_timer_divisor, value); /* diff --git a/sys/dev/aic7xxx/aic79xx_pci.c b/sys/dev/aic7xxx/aic79xx_pci.c index 928012e0475..1e3bbed392f 100644 --- a/sys/dev/aic7xxx/aic79xx_pci.c +++ b/sys/dev/aic7xxx/aic79xx_pci.c @@ -248,10 +248,10 @@ static const char *pci_bus_modes[] = "PCI bus mode unknown", "PCI bus mode unknown", "PCI bus mode unknown", - "PCI-X 101-133Mhz", - "PCI-X 67-100Mhz", - "PCI-X 50-66Mhz", - "PCI 33 or 66Mhz" + "PCI-X 101-133MHz", + "PCI-X 67-100MHz", + "PCI-X 50-66MHz", + "PCI 33 or 66MHz" }; #define TESTMODE 0x00000800ul diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c b/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c index dd35e2b7bf0..43e97ede3bb 100644 --- a/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c +++ b/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c @@ -87,7 +87,7 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode, if (!IEEE80211_IS_CHAN_5GHZ(chan)) { /* Only 11a mode */ - HALDEBUG(ah, HAL_DEBUG_ANY, "%s: channel not 5Ghz\n", __func__); + HALDEBUG(ah, HAL_DEBUG_ANY, "%s: channel not 5GHz\n", __func__); FAIL(HAL_EINVAL); } /* diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 5628addc33a..c1e43eb54de 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -5352,7 +5352,7 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) ath_stoprecv(sc); /* turn off frame recv */ if (!ath_hal_reset(ah, sc->sc_opmode, chan, AH_TRUE, &status)) { if_printf(ifp, "%s: unable to reset " - "channel %u (%u Mhz, flags 0x%x), hal status %u\n", + "channel %u (%u MHz, flags 0x%x), hal status %u\n", __func__, ieee80211_chan2ieee(ic, chan), chan->ic_freq, chan->ic_flags, status); return EIO; diff --git a/sys/dev/ct/ct_isa.c b/sys/dev/ct/ct_isa.c index a1e30457b18..693572fe1c6 100644 --- a/sys/dev/ct/ct_isa.c +++ b/sys/dev/ct/ct_isa.c @@ -316,7 +316,7 @@ ct_isa_attach(device_t dev) break; } #if 0 - printf("%s: chiprev %s chipclk %d Mhz\n", + printf("%s: chiprev %s chipclk %d MHz\n", slp->sl_dev.dv_xname, s, ct->sc_chipclk); #endif diff --git a/sys/dev/mly/mly.c b/sys/dev/mly/mly.c index 1f61542ba03..0c013bce5d5 100644 --- a/sys/dev/mly/mly.c +++ b/sys/dev/mly/mly.c @@ -2528,7 +2528,7 @@ mly_describe_controller(struct mly_softc *sc) mly_describe_code(mly_table_memorytype, mi->memory_type), mi->memory_parity ? "+parity": "",mi->memory_ecc ? "+ECC": "", mi->cache_size); - mly_printf(sc, "CPU: %s @ %dMHZ\n", + mly_printf(sc, "CPU: %s @ %dMHz\n", mly_describe_code(mly_table_cputype, mi->cpu[0].type), mi->cpu[0].speed); if (mi->l2cache_size != 0) mly_printf(sc, "%dKB L2 cache\n", mi->l2cache_size); diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c index 9b1d1b3173e..1451ec808e3 100644 --- a/sys/i386/i386/local_apic.c +++ b/sys/i386/i386/local_apic.c @@ -450,7 +450,7 @@ lapic_setup_clock(void) panic("lapic: Divisor too big"); value /= 2; if (bootverbose) - printf("lapic: Divisor %lu, Frequency %lu hz\n", + printf("lapic: Divisor %lu, Frequency %lu Hz\n", lapic_timer_divisor, value); /* diff --git a/tools/tools/ath/athdecode/main.c b/tools/tools/ath/athdecode/main.c index e27c4e49bb7..977ae1400f4 100644 --- a/tools/tools/ath/athdecode/main.c +++ b/tools/tools/ath/athdecode/main.c @@ -125,13 +125,13 @@ opmark(FILE *fd, int i, const struct athregrec *r) fprintf(fd, "ar%uReset (done), OK", state.chipnum); break; case AH_MARK_CHIPRESET: - fprintf(fd, "ar%uChipReset, channel %u Mhz", state.chipnum, r->val); + fprintf(fd, "ar%uChipReset, channel %u MHz", state.chipnum, r->val); break; case AH_MARK_PERCAL: - fprintf(fd, "ar%uPerCalibration, channel %u Mhz", state.chipnum, r->val); + fprintf(fd, "ar%uPerCalibration, channel %u MHz", state.chipnum, r->val); break; case AH_MARK_SETCHANNEL: - fprintf(fd, "ar%uSetChannel, channel %u Mhz", state.chipnum, r->val); + fprintf(fd, "ar%uSetChannel, channel %u MHz", state.chipnum, r->val); break; case AH_MARK_ANI_RESET: switch (r->val) { From 9ab219c83ff7634bcf94889557402adeabacfcfb Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 5 Feb 2010 11:52:28 +0000 Subject: [PATCH 1375/2592] MFC r201264: Call wakeup() only for the first request on the queue. --- sys/geom/geom_io.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c index c95840a1a3b..0b6525e79e8 100644 --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -391,6 +391,7 @@ void g_io_request(struct bio *bp, struct g_consumer *cp) { struct g_provider *pp; + int first; KASSERT(cp != NULL, ("NULL cp in g_io_request")); KASSERT(bp != NULL, ("NULL bp in g_io_request")); @@ -463,12 +464,14 @@ g_io_request(struct bio *bp, struct g_consumer *cp) pp->nstart++; cp->nstart++; + first = TAILQ_EMPTY(&g_bio_run_down.bio_queue); TAILQ_INSERT_TAIL(&g_bio_run_down.bio_queue, bp, bio_queue); g_bio_run_down.bio_queue_length++; g_bioq_unlock(&g_bio_run_down); /* Pass it on down. */ - wakeup(&g_wait_down); + if (first) + wakeup(&g_wait_down); } void @@ -476,6 +479,7 @@ g_io_deliver(struct bio *bp, int error) { struct g_consumer *cp; struct g_provider *pp; + int first; KASSERT(bp != NULL, ("NULL bp in g_io_deliver")); pp = bp->bio_to; @@ -536,11 +540,13 @@ g_io_deliver(struct bio *bp, int error) pp->nend++; if (error != ENOMEM) { bp->bio_error = error; + first = TAILQ_EMPTY(&g_bio_run_up.bio_queue); TAILQ_INSERT_TAIL(&g_bio_run_up.bio_queue, bp, bio_queue); bp->bio_flags |= BIO_ONQUEUE; g_bio_run_up.bio_queue_length++; g_bioq_unlock(&g_bio_run_up); - wakeup(&g_wait_up); + if (first) + wakeup(&g_wait_up); return; } g_bioq_unlock(&g_bio_run_up); From 9185a702048bcc604c3d44d2bcc4dbd56e8ad0b9 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 5 Feb 2010 11:53:41 +0000 Subject: [PATCH 1376/2592] MFC r201545: Slightly optimize XOR calculation. --- sys/geom/raid3/g_raid3.c | 55 ++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c index 6425b2ee944..dc180f754ac 100644 --- a/sys/geom/raid3/g_raid3.c +++ b/sys/geom/raid3/g_raid3.c @@ -231,31 +231,31 @@ g_raid3_uma_dtor(void *mem, int size, void *arg) sz->sz_inuse--; } -#define g_raid3_xor(src1, src2, dst, size) \ - _g_raid3_xor((uint64_t *)(src1), (uint64_t *)(src2), \ +#define g_raid3_xor(src, dst, size) \ + _g_raid3_xor((uint64_t *)(src), \ (uint64_t *)(dst), (size_t)size) static void -_g_raid3_xor(uint64_t *src1, uint64_t *src2, uint64_t *dst, size_t size) +_g_raid3_xor(uint64_t *src, uint64_t *dst, size_t size) { KASSERT((size % 128) == 0, ("Invalid size: %zu.", size)); for (; size > 0; size -= 128) { - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); - *dst++ = (*src1++) ^ (*src2++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); + *dst++ ^= (*src++); } } @@ -1049,6 +1049,7 @@ g_raid3_scatter(struct bio *pbp) struct g_raid3_disk *disk; struct bio *bp, *cbp, *tmpbp; off_t atom, cadd, padd, left; + int first; sc = pbp->bio_to->geom->softc; bp = NULL; @@ -1079,12 +1080,18 @@ g_raid3_scatter(struct bio *pbp) /* * Calculate parity. */ - bzero(bp->bio_data, bp->bio_length); + first = 1; G_RAID3_FOREACH_SAFE_BIO(pbp, cbp, tmpbp) { if (cbp == bp) continue; - g_raid3_xor(cbp->bio_data, bp->bio_data, bp->bio_data, - bp->bio_length); + if (first) { + bcopy(cbp->bio_data, bp->bio_data, + bp->bio_length); + first = 0; + } else { + g_raid3_xor(cbp->bio_data, bp->bio_data, + bp->bio_length); + } if ((cbp->bio_cflags & G_RAID3_BIO_CFLAG_NODISK) != 0) g_raid3_destroy_bio(sc, cbp); } @@ -1216,7 +1223,7 @@ g_raid3_gather(struct bio *pbp) G_RAID3_FOREACH_BIO(pbp, cbp) { if ((cbp->bio_cflags & G_RAID3_BIO_CFLAG_PARITY) != 0) continue; - g_raid3_xor(cbp->bio_data, xbp->bio_data, xbp->bio_data, + g_raid3_xor(cbp->bio_data, xbp->bio_data, xbp->bio_length); } xbp->bio_cflags &= ~G_RAID3_BIO_CFLAG_PARITY; @@ -1639,7 +1646,7 @@ g_raid3_sync_request(struct bio *bp) bcopy(src, dst, atom); src += atom; for (n = 1; n < sc->sc_ndisks - 1; n++) { - g_raid3_xor(src, dst, dst, atom); + g_raid3_xor(src, dst, atom); src += atom; } dst += atom; From 981b11104a2cc0aae5044ddb5e778966ffe9f32c Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 5 Feb 2010 11:56:12 +0000 Subject: [PATCH 1377/2592] MFC r201566, r201567: Move wakeup() out of mutex to reduce contention. --- sys/geom/mirror/g_mirror.c | 8 ++++---- sys/geom/raid3/g_raid3.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 25de44a5eff..404ab986b35 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -868,8 +868,8 @@ g_mirror_done(struct bio *bp) bp->bio_cflags = G_MIRROR_BIO_FLAG_REGULAR; mtx_lock(&sc->sc_queue_mtx); bioq_disksort(&sc->sc_queue, bp); - wakeup(sc); mtx_unlock(&sc->sc_queue_mtx); + wakeup(sc); } static void @@ -954,9 +954,9 @@ g_mirror_regular_request(struct bio *bp) pbp->bio_error = 0; mtx_lock(&sc->sc_queue_mtx); bioq_disksort(&sc->sc_queue, pbp); + mtx_unlock(&sc->sc_queue_mtx); G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc); wakeup(sc); - mtx_unlock(&sc->sc_queue_mtx); } break; case BIO_DELETE: @@ -994,8 +994,8 @@ g_mirror_sync_done(struct bio *bp) bp->bio_cflags = G_MIRROR_BIO_FLAG_SYNC; mtx_lock(&sc->sc_queue_mtx); bioq_disksort(&sc->sc_queue, bp); - wakeup(sc); mtx_unlock(&sc->sc_queue_mtx); + wakeup(sc); } static void @@ -1107,9 +1107,9 @@ g_mirror_start(struct bio *bp) } mtx_lock(&sc->sc_queue_mtx); bioq_disksort(&sc->sc_queue, bp); + mtx_unlock(&sc->sc_queue_mtx); G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc); wakeup(sc); - mtx_unlock(&sc->sc_queue_mtx); } /* diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c index dc180f754ac..08792fe3599 100644 --- a/sys/geom/raid3/g_raid3.c +++ b/sys/geom/raid3/g_raid3.c @@ -1271,9 +1271,9 @@ g_raid3_done(struct bio *bp) G_RAID3_LOGREQ(3, bp, "Regular request done (error=%d).", bp->bio_error); mtx_lock(&sc->sc_queue_mtx); bioq_insert_head(&sc->sc_queue, bp); + mtx_unlock(&sc->sc_queue_mtx); wakeup(sc); wakeup(&sc->sc_queue); - mtx_unlock(&sc->sc_queue_mtx); } static void @@ -1379,9 +1379,9 @@ g_raid3_sync_done(struct bio *bp) bp->bio_cflags |= G_RAID3_BIO_CFLAG_SYNC; mtx_lock(&sc->sc_queue_mtx); bioq_insert_head(&sc->sc_queue, bp); + mtx_unlock(&sc->sc_queue_mtx); wakeup(sc); wakeup(&sc->sc_queue); - mtx_unlock(&sc->sc_queue_mtx); } static void @@ -1459,9 +1459,9 @@ g_raid3_start(struct bio *bp) } mtx_lock(&sc->sc_queue_mtx); bioq_insert_tail(&sc->sc_queue, bp); + mtx_unlock(&sc->sc_queue_mtx); G_RAID3_DEBUG(4, "%s: Waking up %p.", __func__, sc); wakeup(sc); - mtx_unlock(&sc->sc_queue_mtx); } /* From dc65878eb6290c648968aa574d48362bf1c3491d Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 5 Feb 2010 12:07:53 +0000 Subject: [PATCH 1378/2592] MFC r203033: Clear ch->devices, if hard-reset failed. This makes hot-plug work better. --- sys/dev/ata/chipsets/ata-promise.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c index 3dad5d01f4f..723016eac4d 100644 --- a/sys/dev/ata/chipsets/ata-promise.c +++ b/sys/dev/ata/chipsets/ata-promise.c @@ -821,7 +821,8 @@ ata_promise_mio_reset(device_t dev) device_printf(dev, "promise_mio_reset devices=%08x\n", ch->devices); - } + } else + ch->devices = 0; /* reset and enable plug/unplug intr */ ATA_OUTL(ctlr->r_res2, 0x060, (0x00000011 << ch->unit)); From 3ca74a280b2e549c22800f756f07880d0f01850d Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 5 Feb 2010 12:09:43 +0000 Subject: [PATCH 1379/2592] MFC r203034: Restore SATA speed reporting, broken by ATA_CAM changes. --- sys/dev/ata/chipsets/ata-promise.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c index 723016eac4d..9d79a3ad61a 100644 --- a/sys/dev/ata/chipsets/ata-promise.c +++ b/sys/dev/ata/chipsets/ata-promise.c @@ -73,6 +73,7 @@ static u_int32_t ata_promise_mio_softreset(device_t dev, int port); static void ata_promise_mio_dmainit(device_t dev); static void ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); static int ata_promise_mio_setmode(device_t dev, int target, int mode); +static int ata_promise_mio_getrev(device_t dev, int target); static void ata_promise_sx4_intr(void *data); static int ata_promise_sx4_command(struct ata_request *request); static int ata_promise_apkt(u_int8_t *bytep, struct ata_request *request); @@ -341,6 +342,7 @@ sataii: ctlr->ch_detach = ata_promise_mio_ch_detach; ctlr->reset = ata_promise_mio_reset; ctlr->setmode = ata_promise_mio_setmode; + ctlr->getrev = ata_promise_mio_getrev; return 0; } @@ -999,7 +1001,7 @@ ata_promise_mio_setmode(device_t dev, int target, int mode) if ( (ctlr->chip->cfg2 == PR_SATA) || ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) || - (ctlr->chip->cfg2 == PR_SATA2) || + (ctlr->chip->cfg2 == PR_SATA2) || ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) mode = ata_sata_setmode(dev, target, mode); else @@ -1007,6 +1009,21 @@ ata_promise_mio_setmode(device_t dev, int target, int mode) return (mode); } +static int +ata_promise_mio_getrev(device_t dev, int target) +{ + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + struct ata_channel *ch = device_get_softc(dev); + + if ( (ctlr->chip->cfg2 == PR_SATA) || + ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) || + (ctlr->chip->cfg2 == PR_SATA2) || + ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) + return (ata_sata_getrev(dev, target)); + else + return (0); +} + static void ata_promise_sx4_intr(void *data) { From f8451095fa9f151cdd917dc93e014289e20ae4c9 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 5 Feb 2010 12:17:14 +0000 Subject: [PATCH 1380/2592] MFC r203043, r203058: Do not place fake interrupt register on chip. Now we have better place for it. --- sys/dev/ata/chipsets/ata-promise.c | 33 +++++++----------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c index 9d79a3ad61a..3054552c305 100644 --- a/sys/dev/ata/chipsets/ata-promise.c +++ b/sys/dev/ata/chipsets/ata-promise.c @@ -218,7 +218,7 @@ static int ata_promise_chipinit(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); - int fake_reg, stat_reg; + int stat_reg; if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; @@ -312,7 +312,6 @@ ata_promise_chipinit(device_t dev) case PR_SATA: ctlr->channels = 4; sata150: - fake_reg = 0x60; stat_reg = 0x6c; break; @@ -323,13 +322,12 @@ sata150: default: ctlr->channels = 4; sataii: - fake_reg = 0x54; stat_reg = 0x60; break; } /* prime fake interrupt register */ - ATA_OUTL(ctlr->r_res2, fake_reg, 0xffffffff); + ctlr->chipset_data = (void *)(uintptr_t)0xffffffff; /* clear SATA status and unmask interrupts */ ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff); @@ -590,38 +588,23 @@ ata_promise_mio_intr(void *data) struct ata_pci_controller *ctlr = data; struct ata_channel *ch; u_int32_t vector; - int unit, fake_reg; - - switch (ctlr->chip->cfg2) { - case PR_PATA: - case PR_CMBO: - case PR_SATA: - fake_reg = 0x60; - break; - case PR_CMBO2: - case PR_SATA2: - default: - fake_reg = 0x54; - break; - } + int unit; /* * since reading interrupt status register on early "mio" chips * clears the status bits we cannot read it for each channel later on * in the generic interrupt routine. - * store the bits in an unused register in the chip so we can read - * it from there safely to get around this "feature". */ vector = ATA_INL(ctlr->r_res2, 0x040); ATA_OUTL(ctlr->r_res2, 0x040, vector); - ATA_OUTL(ctlr->r_res2, fake_reg, vector); + ctlr->chipset_data = (void *)(uintptr_t)vector; for (unit = 0; unit < ctlr->channels; unit++) { if ((ch = ctlr->interrupt[unit].argument)) ctlr->interrupt[unit].function(ch); } - ATA_OUTL(ctlr->r_res2, fake_reg, 0xffffffff); + ctlr->chipset_data = (void *)(uintptr_t)0xffffffff; } static int @@ -629,25 +612,23 @@ ata_promise_mio_status(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); - u_int32_t fake_reg, stat_reg, vector, status; + u_int32_t stat_reg, vector, status; switch (ctlr->chip->cfg2) { case PR_PATA: case PR_CMBO: case PR_SATA: - fake_reg = 0x60; stat_reg = 0x6c; break; case PR_CMBO2: case PR_SATA2: default: - fake_reg = 0x54; stat_reg = 0x60; break; } /* read and acknowledge interrupt */ - vector = ATA_INL(ctlr->r_res2, fake_reg); + vector = (uint32_t)(uintptr_t)ctlr->chipset_data; /* read and clear interface status */ status = ATA_INL(ctlr->r_res2, stat_reg); From f8d5cb4579a3f17fb9a0d4a5aa1dc946314b5ba3 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Sat, 6 Feb 2010 11:39:33 +0000 Subject: [PATCH 1381/2592] MFC r200441: The input line length limit mentioned on the manual page was removed by r179374. --- usr.bin/comm/comm.1 | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/usr.bin/comm/comm.1 b/usr.bin/comm/comm.1 index 2402ab5a1ce..02b508cf626 100644 --- a/usr.bin/comm/comm.1 +++ b/usr.bin/comm/comm.1 @@ -35,7 +35,7 @@ .\" From: @(#)comm.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd January 26, 2005 +.Dd December 12, 2009 .Os .Dt COMM 1 .Sh NAME @@ -118,7 +118,3 @@ A .Nm command appeared in .At v4 . -.Sh BUGS -Input lines are limited to -.Dv LINE_MAX -(2048) characters in length. From 37a33496e21bf4eb292ce9296c451d4be2de4042 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Sat, 6 Feb 2010 11:42:23 +0000 Subject: [PATCH 1382/2592] MFC r200632: The input line length limit mentioned on the manual page was removed by r176119. --- usr.bin/uniq/uniq.1 | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/usr.bin/uniq/uniq.1 b/usr.bin/uniq/uniq.1 index a12ad3a6ef1..ec94d05877d 100644 --- a/usr.bin/uniq/uniq.1 +++ b/usr.bin/uniq/uniq.1 @@ -35,7 +35,7 @@ .\" From: @(#)uniq.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd July 3, 2004 +.Dd December 17, 2009 .Dt UNIQ 1 .Os .Sh NAME @@ -153,7 +153,3 @@ A .Nm command appeared in .At v3 . -.Sh BUGS -Input lines are limited to -.Dv LINE_MAX -(2048) bytes in length. From e21bbd174361a79e37072b311e96dc46827c02b7 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 6 Feb 2010 12:03:25 +0000 Subject: [PATCH 1383/2592] MFC r197104,197105,197106,197107,197688,198237,199337,199338,200553,200554, 202771,202773: bring acpica version to 20100121 MFC details: r197104 | jkim | 2009-09-12 01:48:53 +0300 (Sat, 12 Sep 2009) | 4 lines MFV: r196804 Import ACPICA 20090903 r197105 | jkim | 2009-09-12 01:49:34 +0300 (Sat, 12 Sep 2009) | 2 lines Catch up with ACPICA 20090903. r197106 | jkim | 2009-09-12 01:50:15 +0300 (Sat, 12 Sep 2009) | 2 lines Catch up with ACPICA 20090903. r197107 | jkim | 2009-09-12 01:56:08 +0300 (Sat, 12 Sep 2009) | 2 lines Canonify include paths for newly added files. r197688 | jkim | 2009-10-01 23:56:15 +0300 (Thu, 01 Oct 2009) | 4 lines 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. r198237 | jkim | 2009-10-19 19:12:58 +0300 (Mon, 19 Oct 2009) | 2 lines Merge ACPICA 20091013. r199337 | jkim | 2009-11-16 23:47:12 +0200 (Mon, 16 Nov 2009) | 2 lines Merge ACPICA 20091112. r199338 | jkim | 2009-11-16 23:53:56 +0200 (Mon, 16 Nov 2009) | 2 lines Add a forgotten module Makefile change from the previous commit. r200553 | jkim | 2009-12-15 00:24:04 +0200 (Tue, 15 Dec 2009) | 2 lines Merge ACPICA 20091214. r200554 | jkim | 2009-12-15 00:28:32 +0200 (Tue, 15 Dec 2009) | 3 lines Remove _FDE quirk handling as these quirks are automatically repaired by ACPICA layer since ACPICA 20091214. r202771 | jkim | 2010-01-21 23:14:28 +0200 (Thu, 21 Jan 2010) | 2 lines Merge ACPICA 20100121. r202773 | jkim | 2010-01-21 23:31:39 +0200 (Thu, 21 Jan 2010) | 2 lines Fix a new header inclusion. Discussed with: jkim, jhb No objections from: acpi@ --- sys/conf/files | 201 +-- sys/contrib/dev/acpica/acpica_prep.sh | 6 +- sys/contrib/dev/acpica/changes.txt | 472 ++++++- sys/contrib/dev/acpica/common/adfile.c | 26 +- sys/contrib/dev/acpica/common/adisasm.c | 161 +-- sys/contrib/dev/acpica/common/adwalk.c | 36 +- sys/contrib/dev/acpica/common/dmextern.c | 646 ++++++++++ sys/contrib/dev/acpica/common/dmrestag.c | 4 +- sys/contrib/dev/acpica/common/dmtable.c | 110 +- sys/contrib/dev/acpica/common/dmtbdump.c | 368 +++++- sys/contrib/dev/acpica/common/dmtbinfo.c | 454 +++++-- sys/contrib/dev/acpica/common/getopt.c | 10 +- sys/contrib/dev/acpica/compiler/aslanalyze.c | 10 +- sys/contrib/dev/acpica/compiler/aslcodegen.c | 2 +- sys/contrib/dev/acpica/compiler/aslcompile.c | 33 +- sys/contrib/dev/acpica/compiler/aslcompiler.h | 10 +- sys/contrib/dev/acpica/compiler/aslcompiler.l | 3 +- sys/contrib/dev/acpica/compiler/aslcompiler.y | 6 +- sys/contrib/dev/acpica/compiler/asldefine.h | 6 +- sys/contrib/dev/acpica/compiler/aslerror.c | 17 +- sys/contrib/dev/acpica/compiler/aslfiles.c | 224 +++- sys/contrib/dev/acpica/compiler/aslfold.c | 2 +- sys/contrib/dev/acpica/compiler/aslglobal.h | 13 +- sys/contrib/dev/acpica/compiler/asllength.c | 2 +- sys/contrib/dev/acpica/compiler/asllisting.c | 2 +- sys/contrib/dev/acpica/compiler/aslload.c | 24 +- sys/contrib/dev/acpica/compiler/asllookup.c | 11 +- sys/contrib/dev/acpica/compiler/aslmain.c | 249 +++- sys/contrib/dev/acpica/compiler/aslmap.c | 37 +- sys/contrib/dev/acpica/compiler/aslopcodes.c | 10 +- sys/contrib/dev/acpica/compiler/asloperands.c | 30 +- sys/contrib/dev/acpica/compiler/aslopt.c | 2 +- sys/contrib/dev/acpica/compiler/aslresource.c | 4 +- sys/contrib/dev/acpica/compiler/aslrestype1.c | 2 +- sys/contrib/dev/acpica/compiler/aslrestype2.c | 2 +- sys/contrib/dev/acpica/compiler/aslstartup.c | 2 +- sys/contrib/dev/acpica/compiler/aslstubs.c | 9 +- .../dev/acpica/compiler/asltransform.c | 63 +- sys/contrib/dev/acpica/compiler/asltree.c | 4 +- sys/contrib/dev/acpica/compiler/asltypes.h | 23 +- sys/contrib/dev/acpica/compiler/aslutils.c | 28 +- sys/contrib/dev/acpica/debugger/dbcmds.c | 157 ++- sys/contrib/dev/acpica/debugger/dbdisply.c | 60 +- sys/contrib/dev/acpica/debugger/dbexec.c | 15 +- sys/contrib/dev/acpica/debugger/dbfileio.c | 7 +- sys/contrib/dev/acpica/debugger/dbhistry.c | 2 +- sys/contrib/dev/acpica/debugger/dbinput.c | 4 +- sys/contrib/dev/acpica/debugger/dbstats.c | 4 +- sys/contrib/dev/acpica/debugger/dbutils.c | 6 +- sys/contrib/dev/acpica/debugger/dbxface.c | 2 +- .../dev/acpica/disassembler/dmbuffer.c | 2 +- sys/contrib/dev/acpica/disassembler/dmnames.c | 2 +- .../dev/acpica/disassembler/dmobject.c | 2 +- .../dev/acpica/disassembler/dmopcode.c | 6 +- sys/contrib/dev/acpica/disassembler/dmresrc.c | 2 +- .../dev/acpica/disassembler/dmresrcl.c | 2 +- .../dev/acpica/disassembler/dmresrcs.c | 2 +- sys/contrib/dev/acpica/disassembler/dmutils.c | 120 +- sys/contrib/dev/acpica/disassembler/dmwalk.c | 107 +- sys/contrib/dev/acpica/dispatcher/dsfield.c | 30 +- sys/contrib/dev/acpica/dispatcher/dsinit.c | 4 +- sys/contrib/dev/acpica/dispatcher/dsmethod.c | 20 +- sys/contrib/dev/acpica/dispatcher/dsmthdat.c | 12 +- sys/contrib/dev/acpica/dispatcher/dsobject.c | 29 +- sys/contrib/dev/acpica/dispatcher/dsopcode.c | 2 +- sys/contrib/dev/acpica/dispatcher/dsutils.c | 2 +- sys/contrib/dev/acpica/dispatcher/dswexec.c | 2 +- sys/contrib/dev/acpica/dispatcher/dswload.c | 162 +-- sys/contrib/dev/acpica/dispatcher/dswscope.c | 2 +- sys/contrib/dev/acpica/dispatcher/dswstate.c | 2 +- sys/contrib/dev/acpica/events/evevent.c | 2 +- sys/contrib/dev/acpica/events/evgpe.c | 6 +- sys/contrib/dev/acpica/events/evgpeblk.c | 10 +- sys/contrib/dev/acpica/events/evmisc.c | 2 +- sys/contrib/dev/acpica/events/evregion.c | 93 +- sys/contrib/dev/acpica/events/evrgnini.c | 70 +- sys/contrib/dev/acpica/events/evsci.c | 2 +- sys/contrib/dev/acpica/events/evxface.c | 6 +- sys/contrib/dev/acpica/events/evxfevnt.c | 6 +- sys/contrib/dev/acpica/events/evxfregn.c | 6 +- sys/contrib/dev/acpica/executer/exconfig.c | 27 +- sys/contrib/dev/acpica/executer/exconvrt.c | 17 +- sys/contrib/dev/acpica/executer/excreate.c | 2 +- sys/contrib/dev/acpica/executer/exdump.c | 2 +- sys/contrib/dev/acpica/executer/exfield.c | 86 +- sys/contrib/dev/acpica/executer/exfldio.c | 57 +- sys/contrib/dev/acpica/executer/exmisc.c | 16 +- sys/contrib/dev/acpica/executer/exmutex.c | 20 +- sys/contrib/dev/acpica/executer/exnames.c | 2 +- sys/contrib/dev/acpica/executer/exoparg1.c | 44 +- sys/contrib/dev/acpica/executer/exoparg2.c | 6 +- sys/contrib/dev/acpica/executer/exoparg3.c | 4 +- sys/contrib/dev/acpica/executer/exoparg6.c | 13 +- sys/contrib/dev/acpica/executer/exprep.c | 2 +- sys/contrib/dev/acpica/executer/exregion.c | 68 +- sys/contrib/dev/acpica/executer/exresnte.c | 2 +- sys/contrib/dev/acpica/executer/exresolv.c | 2 +- sys/contrib/dev/acpica/executer/exresop.c | 2 +- sys/contrib/dev/acpica/executer/exstore.c | 2 +- sys/contrib/dev/acpica/executer/exstoren.c | 2 +- sys/contrib/dev/acpica/executer/exstorob.c | 16 +- sys/contrib/dev/acpica/executer/exsystem.c | 4 +- sys/contrib/dev/acpica/executer/exutils.c | 71 +- sys/contrib/dev/acpica/hardware/hwacpi.c | 2 +- sys/contrib/dev/acpica/hardware/hwgpe.c | 27 +- sys/contrib/dev/acpica/hardware/hwregs.c | 227 +++- sys/contrib/dev/acpica/hardware/hwsleep.c | 20 +- sys/contrib/dev/acpica/hardware/hwtimer.c | 6 +- sys/contrib/dev/acpica/hardware/hwvalid.c | 2 +- sys/contrib/dev/acpica/hardware/hwxface.c | 202 +-- sys/contrib/dev/acpica/include/acapps.h | 34 +- sys/contrib/dev/acpica/include/accommon.h | 2 +- sys/contrib/dev/acpica/include/acconfig.h | 16 +- sys/contrib/dev/acpica/include/acdebug.h | 13 +- sys/contrib/dev/acpica/include/acdisasm.h | 111 +- sys/contrib/dev/acpica/include/acdispat.h | 2 +- sys/contrib/dev/acpica/include/acevents.h | 4 +- sys/contrib/dev/acpica/include/acexcep.h | 2 +- sys/contrib/dev/acpica/include/acglobal.h | 8 +- sys/contrib/dev/acpica/include/achware.h | 18 +- sys/contrib/dev/acpica/include/acinterp.h | 50 +- sys/contrib/dev/acpica/include/aclocal.h | 49 +- sys/contrib/dev/acpica/include/acmacros.h | 18 +- sys/contrib/dev/acpica/include/acnames.h | 2 +- sys/contrib/dev/acpica/include/acnamesp.h | 69 +- sys/contrib/dev/acpica/include/acobject.h | 12 +- sys/contrib/dev/acpica/include/acopcode.h | 2 +- sys/contrib/dev/acpica/include/acoutput.h | 10 +- sys/contrib/dev/acpica/include/acparser.h | 3 +- sys/contrib/dev/acpica/include/acpi.h | 2 +- sys/contrib/dev/acpica/include/acpiosxf.h | 6 +- sys/contrib/dev/acpica/include/acpixf.h | 13 +- sys/contrib/dev/acpica/include/acpredef.h | 88 +- sys/contrib/dev/acpica/include/acresrc.h | 2 +- sys/contrib/dev/acpica/include/acrestyp.h | 4 +- sys/contrib/dev/acpica/include/acstruct.h | 2 +- sys/contrib/dev/acpica/include/actables.h | 2 +- sys/contrib/dev/acpica/include/actbl.h | 85 +- sys/contrib/dev/acpica/include/actbl1.h | 1024 ++++----------- sys/contrib/dev/acpica/include/actbl2.h | 1124 +++++++++++++++++ sys/contrib/dev/acpica/include/actypes.h | 136 +- sys/contrib/dev/acpica/include/acutils.h | 83 +- sys/contrib/dev/acpica/include/amlcode.h | 3 +- sys/contrib/dev/acpica/include/amlresrc.h | 2 +- .../dev/acpica/include/platform/acenv.h | 10 +- .../dev/acpica/include/platform/acfreebsd.h | 2 +- .../dev/acpica/include/platform/acgcc.h | 2 +- sys/contrib/dev/acpica/namespace/nsaccess.c | 4 +- sys/contrib/dev/acpica/namespace/nsalloc.c | 95 +- sys/contrib/dev/acpica/namespace/nsdump.c | 6 +- sys/contrib/dev/acpica/namespace/nsdumpdv.c | 4 +- sys/contrib/dev/acpica/namespace/nseval.c | 198 ++- sys/contrib/dev/acpica/namespace/nsinit.c | 24 +- sys/contrib/dev/acpica/namespace/nsload.c | 5 +- sys/contrib/dev/acpica/namespace/nsnames.c | 4 +- sys/contrib/dev/acpica/namespace/nsobject.c | 2 +- sys/contrib/dev/acpica/namespace/nsparse.c | 2 +- sys/contrib/dev/acpica/namespace/nspredef.c | 812 ++++++------ sys/contrib/dev/acpica/namespace/nsrepair.c | 876 +++++++++++++ sys/contrib/dev/acpica/namespace/nsrepair2.c | 696 ++++++++++ sys/contrib/dev/acpica/namespace/nssearch.c | 2 +- sys/contrib/dev/acpica/namespace/nsutils.c | 65 +- sys/contrib/dev/acpica/namespace/nswalk.c | 249 ++-- sys/contrib/dev/acpica/namespace/nsxfeval.c | 106 +- sys/contrib/dev/acpica/namespace/nsxfname.c | 260 +++- sys/contrib/dev/acpica/namespace/nsxfobj.c | 14 +- sys/contrib/dev/acpica/osunixxf.c | 6 +- sys/contrib/dev/acpica/parser/psargs.c | 4 +- sys/contrib/dev/acpica/parser/psloop.c | 151 ++- sys/contrib/dev/acpica/parser/psopcode.c | 2 +- sys/contrib/dev/acpica/parser/psparse.c | 6 +- sys/contrib/dev/acpica/parser/psscope.c | 2 +- sys/contrib/dev/acpica/parser/pstree.c | 2 +- sys/contrib/dev/acpica/parser/psutils.c | 2 +- sys/contrib/dev/acpica/parser/pswalk.c | 2 +- sys/contrib/dev/acpica/parser/psxface.c | 13 +- sys/contrib/dev/acpica/resources/rsaddr.c | 2 +- sys/contrib/dev/acpica/resources/rscalc.c | 2 +- sys/contrib/dev/acpica/resources/rscreate.c | 4 +- sys/contrib/dev/acpica/resources/rsdump.c | 2 +- sys/contrib/dev/acpica/resources/rsinfo.c | 2 +- sys/contrib/dev/acpica/resources/rsio.c | 2 +- sys/contrib/dev/acpica/resources/rsirq.c | 2 +- sys/contrib/dev/acpica/resources/rslist.c | 2 +- sys/contrib/dev/acpica/resources/rsmemory.c | 2 +- sys/contrib/dev/acpica/resources/rsmisc.c | 2 +- sys/contrib/dev/acpica/resources/rsutils.c | 2 +- sys/contrib/dev/acpica/resources/rsxface.c | 4 +- sys/contrib/dev/acpica/tables/tbfadt.c | 2 +- sys/contrib/dev/acpica/tables/tbfind.c | 2 +- sys/contrib/dev/acpica/tables/tbinstal.c | 2 +- sys/contrib/dev/acpica/tables/tbutils.c | 91 +- sys/contrib/dev/acpica/tables/tbxface.c | 2 +- sys/contrib/dev/acpica/tables/tbxfroot.c | 2 +- .../dev/acpica/tools/acpiexec/aecommon.h | 20 +- sys/contrib/dev/acpica/utilities/utalloc.c | 2 +- sys/contrib/dev/acpica/utilities/utcache.c | 2 +- sys/contrib/dev/acpica/utilities/utcopy.c | 29 +- sys/contrib/dev/acpica/utilities/utdebug.c | 4 +- sys/contrib/dev/acpica/utilities/utdelete.c | 2 +- sys/contrib/dev/acpica/utilities/uteval.c | 415 +----- sys/contrib/dev/acpica/utilities/utglobal.c | 21 +- sys/contrib/dev/acpica/utilities/utids.c | 497 ++++++++ sys/contrib/dev/acpica/utilities/utinit.c | 26 +- sys/contrib/dev/acpica/utilities/utlock.c | 2 +- sys/contrib/dev/acpica/utilities/utmath.c | 30 +- sys/contrib/dev/acpica/utilities/utmisc.c | 153 ++- sys/contrib/dev/acpica/utilities/utmutex.c | 20 +- sys/contrib/dev/acpica/utilities/utobject.c | 37 +- sys/contrib/dev/acpica/utilities/utresrc.c | 2 +- sys/contrib/dev/acpica/utilities/utstate.c | 2 +- sys/contrib/dev/acpica/utilities/uttrack.c | 2 +- sys/contrib/dev/acpica/utilities/utxface.c | 33 +- sys/dev/acpi_support/acpi_ibm.c | 4 +- sys/dev/acpi_support/acpi_panasonic.c | 16 +- sys/dev/acpi_support/acpi_wmi.c | 8 +- sys/dev/acpica/Osd/OsdHardware.c | 2 +- sys/dev/acpica/Osd/OsdSchedule.c | 2 +- sys/dev/acpica/acpi.c | 190 ++- sys/dev/acpica/acpi_cpu.c | 6 +- sys/dev/acpica/acpi_dock.c | 6 +- sys/dev/acpica/acpi_ec.c | 14 +- sys/dev/acpica/acpi_if.m | 8 +- sys/dev/acpica/acpi_package.c | 4 +- sys/dev/acpica/acpi_pci.c | 2 +- sys/dev/acpica/acpi_pcib_acpi.c | 14 +- sys/dev/acpica/acpi_powerres.c | 4 +- sys/dev/acpica/acpi_smbat.c | 4 +- sys/dev/acpica/acpi_video.c | 2 +- sys/dev/acpica/acpivar.h | 4 +- sys/dev/fdc/fdc_acpi.c | 61 +- sys/modules/acpi/acpi/Makefile | 27 +- usr.sbin/acpi/acpidb/Makefile | 10 +- usr.sbin/acpi/acpidb/acpidb.c | 14 +- usr.sbin/acpi/iasl/Makefile | 3 +- 235 files changed, 9686 insertions(+), 4025 deletions(-) create mode 100644 sys/contrib/dev/acpica/common/dmextern.c create mode 100644 sys/contrib/dev/acpica/include/actbl2.h create mode 100644 sys/contrib/dev/acpica/namespace/nsrepair.c create mode 100644 sys/contrib/dev/acpica/namespace/nsrepair2.c create mode 100644 sys/contrib/dev/acpica/utilities/utids.c diff --git a/sys/conf/files b/sys/conf/files index 77a1b344e4f..d14c1ee886f 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -171,105 +171,108 @@ contrib/dev/acpica/dispatcher/dswexec.c optional acpi contrib/dev/acpica/dispatcher/dswload.c optional acpi contrib/dev/acpica/dispatcher/dswscope.c optional acpi contrib/dev/acpica/dispatcher/dswstate.c optional acpi -contrib/dev/acpica/events/evevent.c optional acpi -contrib/dev/acpica/events/evgpe.c optional acpi -contrib/dev/acpica/events/evgpeblk.c optional acpi -contrib/dev/acpica/events/evmisc.c optional acpi -contrib/dev/acpica/events/evregion.c optional acpi -contrib/dev/acpica/events/evrgnini.c optional acpi -contrib/dev/acpica/events/evsci.c optional acpi -contrib/dev/acpica/events/evxface.c optional acpi -contrib/dev/acpica/events/evxfevnt.c optional acpi -contrib/dev/acpica/events/evxfregn.c optional acpi -contrib/dev/acpica/executer/exconfig.c optional acpi -contrib/dev/acpica/executer/exconvrt.c optional acpi -contrib/dev/acpica/executer/excreate.c optional acpi -contrib/dev/acpica/executer/exdump.c optional acpi -contrib/dev/acpica/executer/exfield.c optional acpi -contrib/dev/acpica/executer/exfldio.c optional acpi -contrib/dev/acpica/executer/exmisc.c optional acpi -contrib/dev/acpica/executer/exmutex.c optional acpi -contrib/dev/acpica/executer/exnames.c optional acpi -contrib/dev/acpica/executer/exoparg1.c optional acpi -contrib/dev/acpica/executer/exoparg2.c optional acpi -contrib/dev/acpica/executer/exoparg3.c optional acpi -contrib/dev/acpica/executer/exoparg6.c optional acpi -contrib/dev/acpica/executer/exprep.c optional acpi -contrib/dev/acpica/executer/exregion.c optional acpi -contrib/dev/acpica/executer/exresnte.c optional acpi -contrib/dev/acpica/executer/exresolv.c optional acpi -contrib/dev/acpica/executer/exresop.c optional acpi -contrib/dev/acpica/executer/exstore.c optional acpi -contrib/dev/acpica/executer/exstoren.c optional acpi -contrib/dev/acpica/executer/exstorob.c optional acpi -contrib/dev/acpica/executer/exsystem.c optional acpi -contrib/dev/acpica/executer/exutils.c optional acpi -contrib/dev/acpica/hardware/hwacpi.c optional acpi -contrib/dev/acpica/hardware/hwgpe.c optional acpi -contrib/dev/acpica/hardware/hwregs.c optional acpi -contrib/dev/acpica/hardware/hwsleep.c optional acpi -contrib/dev/acpica/hardware/hwtimer.c optional acpi -contrib/dev/acpica/hardware/hwvalid.c optional acpi -contrib/dev/acpica/hardware/hwxface.c optional acpi -contrib/dev/acpica/namespace/nsaccess.c optional acpi -contrib/dev/acpica/namespace/nsalloc.c optional acpi -contrib/dev/acpica/namespace/nsdump.c optional acpi -contrib/dev/acpica/namespace/nseval.c optional acpi -contrib/dev/acpica/namespace/nsinit.c optional acpi -contrib/dev/acpica/namespace/nsload.c optional acpi -contrib/dev/acpica/namespace/nsnames.c optional acpi -contrib/dev/acpica/namespace/nsobject.c optional acpi -contrib/dev/acpica/namespace/nsparse.c optional acpi -contrib/dev/acpica/namespace/nspredef.c optional acpi -contrib/dev/acpica/namespace/nssearch.c optional acpi -contrib/dev/acpica/namespace/nsutils.c optional acpi -contrib/dev/acpica/namespace/nswalk.c optional acpi -contrib/dev/acpica/namespace/nsxfeval.c optional acpi -contrib/dev/acpica/namespace/nsxfname.c optional acpi -contrib/dev/acpica/namespace/nsxfobj.c optional acpi -contrib/dev/acpica/parser/psargs.c optional acpi -contrib/dev/acpica/parser/psloop.c optional acpi -contrib/dev/acpica/parser/psopcode.c optional acpi -contrib/dev/acpica/parser/psparse.c optional acpi -contrib/dev/acpica/parser/psscope.c optional acpi -contrib/dev/acpica/parser/pstree.c optional acpi -contrib/dev/acpica/parser/psutils.c optional acpi -contrib/dev/acpica/parser/pswalk.c optional acpi -contrib/dev/acpica/parser/psxface.c optional acpi -contrib/dev/acpica/resources/rsaddr.c optional acpi -contrib/dev/acpica/resources/rscalc.c optional acpi -contrib/dev/acpica/resources/rscreate.c optional acpi -contrib/dev/acpica/resources/rsdump.c optional acpi -contrib/dev/acpica/resources/rsinfo.c optional acpi -contrib/dev/acpica/resources/rsio.c optional acpi -contrib/dev/acpica/resources/rsirq.c optional acpi -contrib/dev/acpica/resources/rslist.c optional acpi -contrib/dev/acpica/resources/rsmemory.c optional acpi -contrib/dev/acpica/resources/rsmisc.c optional acpi -contrib/dev/acpica/resources/rsutils.c optional acpi -contrib/dev/acpica/resources/rsxface.c optional acpi -contrib/dev/acpica/tables/tbfadt.c optional acpi -contrib/dev/acpica/tables/tbfind.c optional acpi -contrib/dev/acpica/tables/tbinstal.c optional acpi -contrib/dev/acpica/tables/tbutils.c optional acpi -contrib/dev/acpica/tables/tbxface.c optional acpi -contrib/dev/acpica/tables/tbxfroot.c optional acpi -contrib/dev/acpica/utilities/utalloc.c optional acpi -contrib/dev/acpica/utilities/utcache.c optional acpi -contrib/dev/acpica/utilities/utcopy.c optional acpi -contrib/dev/acpica/utilities/utdebug.c optional acpi -contrib/dev/acpica/utilities/utdelete.c optional acpi -contrib/dev/acpica/utilities/uteval.c optional acpi -contrib/dev/acpica/utilities/utglobal.c optional acpi -contrib/dev/acpica/utilities/utinit.c optional acpi -contrib/dev/acpica/utilities/utlock.c optional acpi -contrib/dev/acpica/utilities/utmath.c optional acpi -contrib/dev/acpica/utilities/utmisc.c optional acpi -contrib/dev/acpica/utilities/utmutex.c optional acpi -contrib/dev/acpica/utilities/utobject.c optional acpi -contrib/dev/acpica/utilities/utresrc.c optional acpi -contrib/dev/acpica/utilities/utstate.c optional acpi -contrib/dev/acpica/utilities/utxface.c optional acpi +contrib/dev/acpica/events/evevent.c optional acpi +contrib/dev/acpica/events/evgpe.c optional acpi +contrib/dev/acpica/events/evgpeblk.c optional acpi +contrib/dev/acpica/events/evmisc.c optional acpi +contrib/dev/acpica/events/evregion.c optional acpi +contrib/dev/acpica/events/evrgnini.c optional acpi +contrib/dev/acpica/events/evsci.c optional acpi +contrib/dev/acpica/events/evxface.c optional acpi +contrib/dev/acpica/events/evxfevnt.c optional acpi +contrib/dev/acpica/events/evxfregn.c optional acpi +contrib/dev/acpica/executer/exconfig.c optional acpi +contrib/dev/acpica/executer/exconvrt.c optional acpi +contrib/dev/acpica/executer/excreate.c optional acpi +contrib/dev/acpica/executer/exdump.c optional acpi +contrib/dev/acpica/executer/exfield.c optional acpi +contrib/dev/acpica/executer/exfldio.c optional acpi +contrib/dev/acpica/executer/exmisc.c optional acpi +contrib/dev/acpica/executer/exmutex.c optional acpi +contrib/dev/acpica/executer/exnames.c optional acpi +contrib/dev/acpica/executer/exoparg1.c optional acpi +contrib/dev/acpica/executer/exoparg2.c optional acpi +contrib/dev/acpica/executer/exoparg3.c optional acpi +contrib/dev/acpica/executer/exoparg6.c optional acpi +contrib/dev/acpica/executer/exprep.c optional acpi +contrib/dev/acpica/executer/exregion.c optional acpi +contrib/dev/acpica/executer/exresnte.c optional acpi +contrib/dev/acpica/executer/exresolv.c optional acpi +contrib/dev/acpica/executer/exresop.c optional acpi +contrib/dev/acpica/executer/exstore.c optional acpi +contrib/dev/acpica/executer/exstoren.c optional acpi +contrib/dev/acpica/executer/exstorob.c optional acpi +contrib/dev/acpica/executer/exsystem.c optional acpi +contrib/dev/acpica/executer/exutils.c optional acpi +contrib/dev/acpica/hardware/hwacpi.c optional acpi +contrib/dev/acpica/hardware/hwgpe.c optional acpi +contrib/dev/acpica/hardware/hwregs.c optional acpi +contrib/dev/acpica/hardware/hwsleep.c optional acpi +contrib/dev/acpica/hardware/hwtimer.c optional acpi +contrib/dev/acpica/hardware/hwvalid.c optional acpi +contrib/dev/acpica/hardware/hwxface.c optional acpi +contrib/dev/acpica/namespace/nsaccess.c optional acpi +contrib/dev/acpica/namespace/nsalloc.c optional acpi +contrib/dev/acpica/namespace/nsdump.c optional acpi +contrib/dev/acpica/namespace/nseval.c optional acpi +contrib/dev/acpica/namespace/nsinit.c optional acpi +contrib/dev/acpica/namespace/nsload.c optional acpi +contrib/dev/acpica/namespace/nsnames.c optional acpi +contrib/dev/acpica/namespace/nsobject.c optional acpi +contrib/dev/acpica/namespace/nsparse.c optional acpi +contrib/dev/acpica/namespace/nspredef.c optional acpi +contrib/dev/acpica/namespace/nsrepair.c optional acpi +contrib/dev/acpica/namespace/nsrepair2.c optional acpi +contrib/dev/acpica/namespace/nssearch.c optional acpi +contrib/dev/acpica/namespace/nsutils.c optional acpi +contrib/dev/acpica/namespace/nswalk.c optional acpi +contrib/dev/acpica/namespace/nsxfeval.c optional acpi +contrib/dev/acpica/namespace/nsxfname.c optional acpi +contrib/dev/acpica/namespace/nsxfobj.c optional acpi +contrib/dev/acpica/parser/psargs.c optional acpi +contrib/dev/acpica/parser/psloop.c optional acpi +contrib/dev/acpica/parser/psopcode.c optional acpi +contrib/dev/acpica/parser/psparse.c optional acpi +contrib/dev/acpica/parser/psscope.c optional acpi +contrib/dev/acpica/parser/pstree.c optional acpi +contrib/dev/acpica/parser/psutils.c optional acpi +contrib/dev/acpica/parser/pswalk.c optional acpi +contrib/dev/acpica/parser/psxface.c optional acpi +contrib/dev/acpica/resources/rsaddr.c optional acpi +contrib/dev/acpica/resources/rscalc.c optional acpi +contrib/dev/acpica/resources/rscreate.c optional acpi +contrib/dev/acpica/resources/rsdump.c optional acpi +contrib/dev/acpica/resources/rsinfo.c optional acpi +contrib/dev/acpica/resources/rsio.c optional acpi +contrib/dev/acpica/resources/rsirq.c optional acpi +contrib/dev/acpica/resources/rslist.c optional acpi +contrib/dev/acpica/resources/rsmemory.c optional acpi +contrib/dev/acpica/resources/rsmisc.c optional acpi +contrib/dev/acpica/resources/rsutils.c optional acpi +contrib/dev/acpica/resources/rsxface.c optional acpi +contrib/dev/acpica/tables/tbfadt.c optional acpi +contrib/dev/acpica/tables/tbfind.c optional acpi +contrib/dev/acpica/tables/tbinstal.c optional acpi +contrib/dev/acpica/tables/tbutils.c optional acpi +contrib/dev/acpica/tables/tbxface.c optional acpi +contrib/dev/acpica/tables/tbxfroot.c optional acpi +contrib/dev/acpica/utilities/utalloc.c optional acpi +contrib/dev/acpica/utilities/utcache.c optional acpi +contrib/dev/acpica/utilities/utcopy.c optional acpi +contrib/dev/acpica/utilities/utdebug.c optional acpi +contrib/dev/acpica/utilities/utdelete.c optional acpi +contrib/dev/acpica/utilities/uteval.c optional acpi +contrib/dev/acpica/utilities/utglobal.c optional acpi +contrib/dev/acpica/utilities/utids.c optional acpi +contrib/dev/acpica/utilities/utinit.c optional acpi +contrib/dev/acpica/utilities/utlock.c optional acpi +contrib/dev/acpica/utilities/utmath.c optional acpi +contrib/dev/acpica/utilities/utmisc.c optional acpi +contrib/dev/acpica/utilities/utmutex.c optional acpi +contrib/dev/acpica/utilities/utobject.c optional acpi +contrib/dev/acpica/utilities/utresrc.c optional acpi +contrib/dev/acpica/utilities/utstate.c optional acpi +contrib/dev/acpica/utilities/utxface.c optional acpi contrib/ipfilter/netinet/fil.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_auth.c optional ipfilter inet \ diff --git a/sys/contrib/dev/acpica/acpica_prep.sh b/sys/contrib/dev/acpica/acpica_prep.sh index b07f153bfcf..3a17041846f 100755 --- a/sys/contrib/dev/acpica/acpica_prep.sh +++ b/sys/contrib/dev/acpica/acpica_prep.sh @@ -21,7 +21,7 @@ fulldirs="common compiler debugger disassembler dispatcher events \ # files to remove stripdirs="acpisrc acpixtract examples generate os_specific" stripfiles="Makefile README acintel.h aclinux.h acmsvc.h acnetbsd.h \ - acos2.h accygwin.h acefi.h actbl2.h acwin.h acwin64.h aeexec.c \ + acos2.h accygwin.h acefi.h acwin.h acwin64.h aeexec.c \ aehandlers.c aemain.c aetables.c osunixdir.c readme.txt \ utclib.c" @@ -31,8 +31,8 @@ src_headers="acapps.h accommon.h acconfig.h acdebug.h acdisasm.h \ aclocal.h acmacros.h acnames.h acnamesp.h acobject.h acopcode.h \ acoutput.h acparser.h acpi.h acpiosxf.h acpixf.h acpredef.h \ acresrc.h acrestyp.h acstruct.h actables.h actbl.h actbl1.h \ - actypes.h acutils.h amlcode.h amlresrc.h platform/acenv.h \ - platform/acfreebsd.h platform/acgcc.h" + actbl2.h actypes.h acutils.h amlcode.h amlresrc.h \ + platform/acenv.h platform/acfreebsd.h platform/acgcc.h" comp_headers="aslcompiler.h asldefine.h aslglobal.h asltypes.h" platform_headers="acfreebsd.h acgcc.h" diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt index 89f62326145..60620ce4f76 100644 --- a/sys/contrib/dev/acpica/changes.txt +++ b/sys/contrib/dev/acpica/changes.txt @@ -1,8 +1,468 @@ +---------------------------------------- +21 January 2010. Summary of changes for version 20100121: + +1) ACPI CA Core Subsystem: + +Added the 2010 copyright to all module headers and signons. This affects +virtually every file in the ACPICA core subsystem, the iASL compiler, the +tools/utilities, and the test suites. + +Implemented a change to the AcpiGetDevices interface to eliminate unnecessary +invocations of the _STA method. In the case where a specific _HID is +requested, do not run _STA until a _HID match is found. This eliminates +potentially dozens of _STA calls during a search for a particular device/HID, +which in turn can improve boot times. ACPICA BZ 828. Lin Ming. + +Implemented an additional repair for predefined method return values. Attempt +to repair unexpected NULL elements within returned Package objects. Create an +Integer of value zero, a NULL String, or a zero-length Buffer as appropriate. +ACPICA BZ 818. Lin Ming, Bob Moore. + +Removed the obsolete ACPI_INTEGER data type. This type was introduced as the +code was migrated from ACPI 1.0 (with 32-bit AML integers) to ACPI 2.0 (with +64-bit AML integers). It is now obsolete and this change removes it from the +ACPICA code base, replaced by UINT64. The original typedef has been retained +for now for compatibility with existing device driver code. ACPICA BZ 824. + +Removed the unused UINT32_STRUCT type, and the obsolete Integer64 field in +the parse tree object. + +Added additional warning options for the gcc-4 generation. Updated the source +accordingly. This includes some code restructuring to eliminate unreachable +code, elimination of some gotos, elimination of unused return values, some +additional casting, and removal of redundant declarations. + +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: 87.0K Code, 18.0K Data, 105.0K Total + Debug Version: 163.4K Code, 50.8K Data, 214.2K Total + Current Release: + Non-Debug Version: 87.1K Code, 18.0K Data, 105.1K Total + Debug Version: 163.5K Code, 50.9K Data, 214.4K Total + +2) iASL Compiler/Disassembler and Tools: + +No functional changes for this release. + +---------------------------------------- +14 December 2009. Summary of changes for version 20091214: + +1) ACPI CA Core Subsystem: + +Enhanced automatic data type conversions for predefined name repairs. This +change expands the automatic repairs/conversions for predefined name return +values to make Integers, Strings, and Buffers fully interchangeable. Also, a +Buffer can be converted to a Package of Integers if necessary. The nsrepair.c +module was completely restructured. Lin Ming, Bob Moore. + +Implemented automatic removal of null package elements during predefined name +repairs. This change will automatically remove embedded and trailing NULL +package elements from returned package objects that are defined to contain a +variable number of sub-packages. The driver is then presented with a package +with no null elements to deal with. ACPICA BZ 819. + +Implemented a repair for the predefined _FDE and _GTM names. The expected +return value for both names is a Buffer of 5 DWORDs. This repair fixes two +possible problems (both seen in the field), where a package of integers is +returned, or a buffer of BYTEs is returned. With assistance from Jung-uk Kim. + +Implemented additional module-level code support. This change will properly +execute module-level code that is not at the root of the namespace (under a +Device object, etc.). Now executes the code within the current scope instead +of the root. ACPICA BZ 762. Lin Ming. + +Fixed possible mutex acquisition errors when running _REG methods. Fixes a +problem where mutex errors can occur when running a _REG method that is in +the same scope as a method-defined operation region or an operation region +under a module-level IF block. This type of code is rare, so the problem has +not been seen before. ACPICA BZ 826. Lin Ming, Bob Moore. + +Fixed a possible memory leak during module-level code execution. An object +could be leaked for each block of executed module-level code if the +interpreter slack mode is enabled This change deletes any implicitly returned +object from the module-level code block. Lin Ming. + +Removed messages for successful predefined repair(s). The repair mechanism +was considered too wordy. Now, messages are only unconditionally emitted if +the return object cannot be repaired. Existing messages for successful +repairs were converted to ACPI_DEBUG_PRINT messages for now. ACPICA BZ 827. + +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: 86.6K Code, 18.2K Data, 104.8K Total + Debug Version: 162.7K Code, 50.8K Data, 213.5K Total + Current Release: + Non-Debug Version: 87.0K Code, 18.0K Data, 105.0K Total + Debug Version: 163.4K Code, 50.8K Data, 214.2K Total + +2) iASL Compiler/Disassembler and Tools: + +iASL: Fixed a regression introduced in 20091112 where intermediate .SRC files +were no longer automatically removed at the termination of the compile. + +acpiexec: Implemented the -f option to specify default region fill value. +This option specifies the value used to initialize buffers that simulate +operation regions. Default value is zero. Useful for debugging problems that +depend on a specific initial value for a region or field. + +---------------------------------------- +12 November 2009. Summary of changes for version 20091112: + +1) ACPI CA Core Subsystem: + +Implemented a post-order callback to AcpiWalkNamespace. The existing +interface only has a pre-order callback. This change adds an additional +parameter for a post-order callback which will be more useful for bus scans. +ACPICA BZ 779. Lin Ming. Updated the ACPICA Programmer Reference. + +Modified the behavior of the operation region memory mapping cache for +SystemMemory. Ensure that the memory mappings created for operation regions +do not cross 4K page boundaries. Crossing a page boundary while mapping +regions can cause kernel warnings on some hosts if the pages have different +attributes. Such regions are probably BIOS bugs, and this is the workaround. +Linux BZ 14445. Lin Ming. + +Implemented an automatic repair for predefined methods that must return +sorted lists. This change will repair (by sorting) packages returned by _ALR, +_PSS, and _TSS. Drivers can now assume that the packages are correctly sorted +and do not contain NULL package elements. Adds one new file, +namespace/nsrepair2.c. ACPICA BZ 784. Lin Ming, Bob Moore. + +Fixed a possible fault during predefined name validation if a return Package +object contains NULL elements. Also adds a warning if a NULL element is +followed by any non-null elements. ACPICA BZ 813, 814. Future enhancement may +include repair or removal of all such NULL elements where possible. + +Implemented additional module-level executable AML code support. This change +will execute module-level code that is not at the root of the namespace +(under a Device object, etc.) at table load time. Module-level executable AML +code has been illegal since ACPI 2.0. ACPICA BZ 762. Lin Ming. + +Implemented a new internal function to create Integer objects. This function +simplifies miscellaneous object creation code. ACPICA BZ 823. + +Reduced the severity of predefined repair messages, Warning to Info. Since +the object was successfully repaired, a warning is too severe. Reduced to an +info message for now. These messages may eventually be changed to debug-only. +ACPICA BZ 812. + +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.8K Code, 18.0K Data, 103.8K Total + Debug Version: 161.8K Code, 50.6K Data, 212.4K Total + Current Release: + Non-Debug Version: 86.6K Code, 18.2K Data, 104.8K Total + Debug Version: 162.7K Code, 50.8K Data, 213.5K Total + +2) iASL Compiler/Disassembler and Tools: + +iASL: Implemented Switch() with While(1) so that Break works correctly. This +change correctly implements the Switch operator with a surrounding While(1) +so that the Break operator works as expected. ACPICA BZ 461. Lin Ming. + +iASL: Added a message if a package initializer list is shorter than package +length. Adds a new remark for a Package() declaration if an initializer list +exists, but is shorter than the declared length of the package. Although +technically legal, this is probably a coding error and it is seen in the +field. ACPICA BZ 815. Lin Ming, Bob Moore. + +iASL: Fixed a problem where the compiler could fault after the maximum number +of errors was reached (200). + +acpixtract: Fixed a possible warning for pointer cast if the compiler warning +level set very high. + +---------------------------------------- +13 October 2009. Summary of changes for version 20091013: + +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 +\_SB._INI. Lin Ming. + +Fixed a possible memory leak in the interpreter for AML package objects if +the package initializer list is longer than the defined size of the package. +This apparently can only happen if the BIOS changes the package size on the +fly (seen in a _PSS object), as ASL compilers do not allow this. The +interpreter will truncate the package to the defined size (and issue an error +message), but previously could leave the extra objects undeleted if they were +pre-created during the argument processing (such is the case if the package +consists of a number of sub-packages as in the _PSS.) ACPICA BZ 805. + +Fixed a problem seen when a Buffer or String is stored to itself via ASL. +This has been reported in the field. Previously, ACPICA would zero out the +buffer/string. Now, the operation is treated as a noop. Provides Windows +compatibility. ACPICA BZ 803. Lin Ming. + +Removed an extraneous error message for ASL constructs of the form +Store(LocalX,LocalX) when LocalX is uninitialized. These curious statements +are seen in many BIOSs and are once again treated as NOOPs and no error is +emitted when they are encountered. ACPICA BZ 785. + +Fixed an extraneous warning message if a _DSM reserved method returns a +Package object. _DSM can return any type of object, so validation on the +return type cannot be performed. ACPICA BZ 802. + +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.5K Code, 18.0K Data, 103.5K Total + Debug Version: 161.6K Code, 50.9K Data, 212.5K Total + Current Release: + Non-Debug Version: 85.6K Code, 18.0K Data, 103.6K Total + Debug Version: 161.7K Code, 50.9K Data, 212.6K Total + +2) iASL Compiler/Disassembler and Tools: + +iASL: Fixed a problem with the use of the Alias operator and Resource +Templates. The correct alias is now constructed and no error is emitted. +ACPICA BZ 738. + +iASL: Implemented the -I option to specify additional search directories for +include files. Allows multiple additional search paths for include files. +Directories are searched in the order specified on the command line (after +the local directory is searched.) ACPICA BZ 800. + +iASL: Fixed a problem where the full pathname for include files was not +emitted for warnings/errors. This caused the IDE support to not work +properly. ACPICA BZ 765. + +iASL: Implemented the -@ option to specify a Windows-style response file +containing additional command line options. ACPICA BZ 801. + +AcpiExec: Added support to load multiple AML files simultaneously (such as a +DSDT and multiple SSDTs). Also added support for wildcards within the AML +pathname. These features allow all machine tables to be easily loaded and +debugged together. ACPICA BZ 804. + +Disassembler: Added missing support for disassembly of HEST table Error Bank +subtables. + +---------------------------------------- +30 July 2009. Summary of changes for version 20090730: + +The ACPI 4.0 implementation for ACPICA is complete with this release. + +1) ACPI CA Core Subsystem: + +ACPI 4.0: Added header file support for all new and changed ACPI tables. +Completely new tables are: IBFT, IVRS, MSCT, and WAET. Tables that are new +for ACPI 4.0, but have previously been supported in ACPICA are: CPEP, BERT, +EINJ, ERST, and HEST. Other newly supported tables are: UEFI and WDAT. There +have been some ACPI 4.0 changes to other existing tables. Split the large +actbl1.h header into the existing actbl2.h header. ACPICA BZ 774. + +ACPI 4.0: Implemented predefined name validation for all new names. There are +31 new names in ACPI 4.0. The predefined validation module was split into two +files. The new file is namespace/nsrepair.c. ACPICA BZ 770. + +Implemented support for so-called "module-level executable code". This is +executable AML code that exists outside of any control method and is intended +to be executed at table load time. Although illegal since ACPI 2.0, this type +of code still exists and is apparently still being created. Blocks of this +code are now detected and executed as intended. Currently, the code blocks +must exist under either an If, Else, or While construct; these are the +typical cases seen in the field. ACPICA BZ 762. Lin Ming. + +Implemented an automatic dynamic repair for predefined names that return +nested Package objects. This applies to predefined names that are defined to +return a variable-length Package of sub-packages. If the number of sub- +packages is one, BIOS code is occasionally seen that creates a simple single +package with no sub-packages. This code attempts to fix the problem by +wrapping a new package object around the existing package. These methods can +be repaired: _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, and _TSS. ACPICA BZ +790. + +Fixed a regression introduced in 20090625 for the AcpiGetDevices interface. +The _HID/_CID matching was broken and no longer matched IDs correctly. ACPICA +BZ 793. + +Fixed a problem with AcpiReset where the reset would silently fail if the +register was one of the protected I/O ports. AcpiReset now bypasses the port +validation mechanism. This may eventually be driven into the AcpiRead/Write +interfaces. + +Fixed a regression related to the recent update of the AcpiRead/Write +interfaces. A sleep/suspend could fail if the optional PM2 Control register +does not exist during an attempt to write the Bus Master Arbitration bit. +(However, some hosts already delete the code that writes this bit, and the +code may in fact be obsolete at this date.) ACPICA BZ 799. + +Fixed a problem where AcpiTerminate could fault if inadvertently called twice +in succession. ACPICA BZ 795. + +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: 84.7K Code, 17.8K Data, 102.5K Total + Debug Version: 160.5K Code, 50.6K Data, 211.1K Total + Current Release: + Non-Debug Version: 85.5K Code, 18.0K Data, 103.5K Total + Debug Version: 161.6K Code, 50.9K Data, 212.5K Total + +2) iASL Compiler/Disassembler and Tools: + +ACPI 4.0: Implemented disassembler support for all new ACPI tables and +changes to existing tables. ACPICA BZ 775. + +---------------------------------------- +25 June 2009. Summary of changes for version 20090625: + +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. + +1) ACPI CA Core Subsystem: + +ACPI 4.0: Implemented interpreter support for the IPMI operation region +address space. Includes support for bi-directional data buffers and an IPMI +address space handler (to be installed by an IPMI device driver.) ACPICA BZ +773. Lin Ming. + +ACPI 4.0: Added changes for existing ACPI tables - FACS and SRAT. Includes +support in both the header files and the disassembler. + +Completed a major update for the AcpiGetObjectInfo external interface. +Changes include: + - Support for variable, unlimited length HID, UID, and CID strings. + - Support Processor objects the same as Devices (HID,UID,CID,ADR,STA, etc.) + - Call the _SxW power methods on behalf of a device object. + - Determine if a device is a PCI root bridge. + - Change the ACPI_BUFFER parameter to ACPI_DEVICE_INFO. +These changes will require an update to all callers of this interface. See +the updated ACPICA Programmer Reference for details. One new source file has +been added - utilities/utids.c. ACPICA BZ 368, 780. + +Updated the AcpiRead and AcpiWrite external interfaces to support 64-bit +transfers. The Value parameter has been extended from 32 bits to 64 bits in +order to support new ACPI 4.0 tables. These changes will require an update to +all callers of these interfaces. See the ACPICA Programmer Reference for +details. ACPICA BZ 768. + +Fixed several problems with AcpiAttachData. The handler was not invoked when +the host node was deleted. The data sub-object was not automatically deleted +when the host node was deleted. The interface to the handler had an unused +parameter, this was removed. ACPICA BZ 778. + +Enhanced the function that dumps ACPI table headers. All non-printable +characters in the string fields are now replaced with '?' (Signature, OemId, +OemTableId, and CompilerId.) ACPI tables with non-printable characters in +these fields are occasionally seen in the field. ACPICA BZ 788. + +Fixed a problem with predefined method repair code where the code that +attempts to repair/convert an object of incorrect type is only executed on +the first time the predefined method is called. The mechanism that disables +warnings on subsequent calls was interfering with the repair mechanism. +ACPICA BZ 781. + +Fixed a possible memory leak in the predefined validation/repair code when a +buffer is automatically converted to an expected string object. + +Removed obsolete 16-bit files from the distribution and from the current git +tree head. ACPICA BZ 776. + +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: 83.4K Code, 17.5K Data, 100.9K Total + Debug Version: 158.9K Code, 50.0K Data, 208.9K Total + Current Release: + Non-Debug Version: 84.7K Code, 17.8K Data, 102.5K Total + Debug Version: 160.5K Code, 50.6K Data, 211.1K Total + +2) iASL Compiler/Disassembler and Tools: + +ACPI 4.0: iASL and Disassembler - implemented support for the new IPMI +operation region keyword. ACPICA BZ 771, 772. Lin Ming. + +ACPI 4.0: iASL - implemented compile-time validation support for all new +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. @@ -74,8 +534,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 @@ -623,9 +1081,6 @@ header. 29 July 2008. Summary of changes for version 20080729: -This release is available at http://acpica.org/downloads -Direct git access via http://www.acpica.org/repos/acpica.git - 1) ACPI CA Core Subsystem: Fix a possible deadlock in the GPE dispatch. Remove call to @@ -715,9 +1170,6 @@ completion message. Previously, no message was displayed in this case. ---------------------------------------- 01 July 2008. Summary of changes for version 20080701: -This release is available at http://acpica.org/downloads -Direct git access via http://www.acpica.org/repos/acpica.git - 0) Git source tree / acpica.org Fixed a problem where a git-clone from http would not transfer the entire diff --git a/sys/contrib/dev/acpica/common/adfile.c b/sys/contrib/dev/acpica/common/adfile.c index ad5e54419a1..d72f36900aa 100644 --- a/sys/contrib/dev/acpica/common/adfile.c +++ b/sys/contrib/dev/acpica/common/adfile.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -119,7 +119,6 @@ #include #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/sys/contrib/dev/acpica/common/adisasm.c b/sys/contrib/dev/acpica/common/adisasm.c index 873f42a46db..fe5ae35731d 100644 --- a/sys/contrib/dev/acpica/common/adisasm.c +++ b/sys/contrib/dev/acpica/common/adisasm.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -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/sys/contrib/dev/acpica/common/adwalk.c b/sys/contrib/dev/acpica/common/adwalk.c index a260cc591fd..6bb4be5741b 100644 --- a/sys/contrib/dev/acpica/common/adwalk.c +++ b/sys/contrib/dev/acpica/common/adwalk.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -118,7 +118,6 @@ #include #include #include -#include #include #include #include @@ -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/sys/contrib/dev/acpica/common/dmextern.c b/sys/contrib/dev/acpica/common/dmextern.c new file mode 100644 index 00000000000..943a3c2f1e6 --- /dev/null +++ b/sys/contrib/dev/acpica/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 - 2010, 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 +#include +#include +#include +#include + + +/* + * 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/sys/contrib/dev/acpica/common/dmrestag.c b/sys/contrib/dev/acpica/common/dmrestag.c index 59a11bea1ea..4abbf53a1f2 100644 --- a/sys/contrib/dev/acpica/common/dmrestag.c +++ b/sys/contrib/dev/acpica/common/dmrestag.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -387,7 +387,7 @@ static ACPI_RESOURCE_TAG *AcpiGbl_ResourceTags [] = static UINT32 AcpiGbl_NextResourceId = 0; static UINT8 AcpiGbl_NextPrefix = 0; -static UINT8 AcpiGbl_Prefix[ACPI_NUM_RES_PREFIX] = +static char AcpiGbl_Prefix[ACPI_NUM_RES_PREFIX] = {'Y','Z','J','K','X'}; diff --git a/sys/contrib/dev/acpica/common/dmtable.c b/sys/contrib/dev/acpica/common/dmtable.c index d0b26f2b154..70858911150 100644 --- a/sys/contrib/dev/acpica/common/dmtable.c +++ b/sys/contrib/dev/acpica/common/dmtable.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -132,6 +132,7 @@ AcpiDmGetTableData ( static void AcpiDmCheckAscii ( UINT8 *Target, + char *RepairedName, UINT32 Count); UINT8 @@ -156,17 +157,18 @@ static const char *AcpiDmDmarSubnames[] = "Hardware Unit Definition", "Reserved Memory Region", "Root Port ATS Capability", + "Remapping Hardware Static Affinity", "Unknown SubTable Type" /* Reserved */ }; static const char *AcpiDmHestSubnames[] = { - "XPF Machine Check Exception", - "XPF Corrected Machine Check", - "NOT USED???", - "XPF Non-Maskable Interrupt", - "IPF Corrected Machine Check", - "IPF Corrected Platform Error", + "IA-32 Machine Check Exception", + "IA-32 Corrected Machine Check", + "IA-32 Non-Maskable Interrupt", + "Unknown SubTable Type", /* 3 - Reserved */ + "Unknown SubTable Type", /* 4 - Reserved */ + "Unknown SubTable Type", /* 5 - Reserved */ "PCI Express Root Port AER", "PCI Express AER (AER Endpoint)", "PCI Express/PCI-X Bridge AER", @@ -208,6 +210,13 @@ static const char *AcpiDmSratSubnames[] = "Unknown SubTable Type" /* Reserved */ }; +static const char *AcpiDmIvrsSubnames[] = +{ + "Hardware Definition Block", + "Memory Definition Block", + "Unknown SubTable Type" /* Reserved */ +}; + #define ACPI_FADT_PM_RESERVED 8 @@ -224,11 +233,12 @@ static const char *AcpiDmFadtProfiles[] = "Unknown Profile Type" }; - /******************************************************************************* * * ACPI Table Data, indexed by signature. * + * Each entry contains: Signature, Table Info, Handler, Description + * * Simple tables have only a TableInfo structure, complex tables have a handler. * This table must be NULL terminated. RSDP and FACS are special-cased * elsewhere. @@ -249,8 +259,10 @@ static ACPI_DMTABLE_DATA AcpiDmTableData[] = {ACPI_SIG_FADT, NULL, AcpiDmDumpFadt, "Fixed ACPI Description Table"}, {ACPI_SIG_HEST, NULL, AcpiDmDumpHest, "Hardware Error Source Table"}, {ACPI_SIG_HPET, AcpiDmTableInfoHpet, NULL, "High Precision Event Timer table"}, + {ACPI_SIG_IVRS, NULL, AcpiDmDumpIvrs, "I/O Virtualization Reporting Structure"}, {ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, "Multiple APIC Description Table"}, {ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, "Memory Mapped Configuration table"}, + {ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, "Maximum System Characteristics Table"}, {ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, "Root System Description Table"}, {ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, "Smart Battery Specification Table"}, {ACPI_SIG_SLIC, AcpiDmTableInfoSlic, NULL, "Software Licensing Description Table"}, @@ -259,6 +271,9 @@ static ACPI_DMTABLE_DATA AcpiDmTableData[] = {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi, NULL, "Server Platform Management Interface table"}, {ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, "System Resource Affinity Table"}, {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa, NULL, "Trusted Computing Platform Alliance table"}, + {ACPI_SIG_UEFI, AcpiDmTableInfoUefi, NULL, "UEFI Boot Optimization Table"}, + {ACPI_SIG_WAET, AcpiDmTableInfoWaet, NULL, "Windows ACPI Emulated Devices Table"}, + {ACPI_SIG_WDAT, NULL, AcpiDmDumpWdat, "Watchdog Action Table"}, {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt, NULL, "Watchdog Resource Table"}, {ACPI_SIG_XSDT, NULL, AcpiDmDumpXsdt, "Extended System Description Table"}, {NULL, NULL, NULL, NULL} @@ -511,7 +526,9 @@ AcpiDmDumpTable ( UINT8 Temp8; UINT16 Temp16; ACPI_DMTABLE_DATA *TableData; + const char *Name; BOOLEAN LastOutputBlankLine = FALSE; + char RepairedName[8]; if (!Info) @@ -547,6 +564,7 @@ AcpiDmDumpTable ( case ACPI_DMT_UINT8: case ACPI_DMT_CHKSUM: case ACPI_DMT_SPACEID: + case ACPI_DMT_IVRS: case ACPI_DMT_MADT: case ACPI_DMT_SRAT: case ACPI_DMT_ASF: @@ -577,6 +595,9 @@ AcpiDmDumpTable ( case ACPI_DMT_NAME8: ByteLength = 8; break; + case ACPI_DMT_BUF16: + ByteLength = 16; + break; case ACPI_DMT_STRING: ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1; break; @@ -677,17 +698,28 @@ AcpiDmDumpTable ( ACPI_FORMAT_UINT64 (ACPI_GET64 (Target))); break; + case ACPI_DMT_BUF16: + + /* Buffer of length 16 */ + + for (Temp8 = 0; Temp8 < 16; Temp8++) + { + AcpiOsPrintf ("%2.2X,", Target[Temp8]); + } + AcpiOsPrintf ("\n"); + break; + case ACPI_DMT_STRING: - AcpiOsPrintf ("%s\n", ACPI_CAST_PTR (char, Target)); + AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target)); break; /* Fixed length ASCII name fields */ case ACPI_DMT_SIG: - AcpiDmCheckAscii (Target, 4); - AcpiOsPrintf ("\"%4.4s\" ", Target); + AcpiDmCheckAscii (Target, RepairedName, 4); + AcpiOsPrintf ("\"%.4s\" ", RepairedName); TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target)); if (TableData) { @@ -698,20 +730,20 @@ AcpiDmDumpTable ( case ACPI_DMT_NAME4: - AcpiDmCheckAscii (Target, 4); - AcpiOsPrintf ("\"%4.4s\"\n", Target); + AcpiDmCheckAscii (Target, RepairedName, 4); + AcpiOsPrintf ("\"%.4s\"\n", RepairedName); break; case ACPI_DMT_NAME6: - AcpiDmCheckAscii (Target, 6); - AcpiOsPrintf ("\"%6.6s\"\n", Target); + AcpiDmCheckAscii (Target, RepairedName, 6); + AcpiOsPrintf ("\"%.6s\"\n", RepairedName); break; case ACPI_DMT_NAME8: - AcpiDmCheckAscii (Target, 8); - AcpiOsPrintf ("\"%8.8s\"\n", Target); + AcpiDmCheckAscii (Target, RepairedName, 8); + AcpiOsPrintf ("\"%.8s\"\n", RepairedName); break; /* Special Data Types */ @@ -742,8 +774,8 @@ AcpiDmDumpTable ( /* Generic Address Structure */ AcpiOsPrintf ("\n"); - AcpiDmDumpTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length, - CurrentOffset, Target, sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas); + AcpiDmDumpTable (TableLength, CurrentOffset, Target, + sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas); AcpiOsPrintf ("\n"); LastOutputBlankLine = TRUE; break; @@ -790,8 +822,8 @@ AcpiDmDumpTable ( case ACPI_DMT_HESTNTFY: AcpiOsPrintf ("\n"); - AcpiDmDumpTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length, - CurrentOffset, Target, sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify); + AcpiDmDumpTable (TableLength, CurrentOffset, Target, + sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify); AcpiOsPrintf ("\n"); LastOutputBlankLine = TRUE; break; @@ -849,6 +881,31 @@ AcpiDmDumpTable ( AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]); break; + case ACPI_DMT_IVRS: + + /* IVRS subtable types */ + + Temp8 = *Target; + switch (Temp8) + { + case ACPI_IVRS_TYPE_HARDWARE: + Name = AcpiDmIvrsSubnames[0]; + break; + + case ACPI_IVRS_TYPE_MEMORY1: + case ACPI_IVRS_TYPE_MEMORY2: + case ACPI_IVRS_TYPE_MEMORY3: + Name = AcpiDmIvrsSubnames[1]; + break; + + default: + Name = AcpiDmIvrsSubnames[2]; + break; + } + + AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name); + break; + case ACPI_DMT_EXIT: return (AE_OK); @@ -888,6 +945,7 @@ AcpiDmDumpTable ( static void AcpiDmCheckAscii ( UINT8 *Name, + char *RepairedName, UINT32 Count) { UINT32 i; @@ -895,9 +953,15 @@ AcpiDmCheckAscii ( for (i = 0; i < Count; i++) { - if (!Name[i] || !isprint (Name[i])) + RepairedName[i] = (char) Name[i]; + + if (!Name[i]) { - Name[i] = ' '; + return; + } + if (!isprint (Name[i])) + { + RepairedName[i] = ' '; } } } diff --git a/sys/contrib/dev/acpica/common/dmtbdump.c b/sys/contrib/dev/acpica/common/dmtbdump.c index 1f9f3ccd396..2c9725d8206 100644 --- a/sys/contrib/dev/acpica/common/dmtbdump.c +++ b/sys/contrib/dev/acpica/common/dmtbdump.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -306,6 +306,7 @@ AcpiDmDumpAsf ( UINT32 DataLength = 0; UINT32 DataOffset = 0; UINT32 i; + UINT8 Type; /* No main table, only sub-tables */ @@ -322,7 +323,11 @@ AcpiDmDumpAsf ( return; } - switch (SubTable->Header.Type & 0x7F) /* Mask off top bit */ + /* The actual type is the lower 7 bits of Type */ + + Type = (UINT8) (SubTable->Header.Type & 0x7F); + + switch (Type) { case ACPI_ASF_TYPE_INFO: InfoTable = AcpiDmTableInfoAsf0; @@ -332,8 +337,8 @@ AcpiDmDumpAsf ( InfoTable = AcpiDmTableInfoAsf1; DataInfoTable = AcpiDmTableInfoAsf1a; DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ALERT)); - DataCount = ((ACPI_ASF_ALERT *) SubTable)->Alerts; - DataLength = ((ACPI_ASF_ALERT *) SubTable)->DataLength; + DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->Alerts; + DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->DataLength; DataOffset = Offset + sizeof (ACPI_ASF_ALERT); break; @@ -341,8 +346,8 @@ AcpiDmDumpAsf ( InfoTable = AcpiDmTableInfoAsf2; DataInfoTable = AcpiDmTableInfoAsf2a; DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_REMOTE)); - DataCount = ((ACPI_ASF_REMOTE *) SubTable)->Controls; - DataLength = ((ACPI_ASF_REMOTE *) SubTable)->DataLength; + DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->Controls; + DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->DataLength; DataOffset = Offset + sizeof (ACPI_ASF_REMOTE); break; @@ -353,7 +358,7 @@ AcpiDmDumpAsf ( case ACPI_ASF_TYPE_ADDRESS: InfoTable = AcpiDmTableInfoAsf4; DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ADDRESS)); - DataLength = ((ACPI_ASF_ADDRESS *) SubTable)->Devices; + DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, SubTable)->Devices; DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS); break; @@ -371,7 +376,7 @@ AcpiDmDumpAsf ( /* Dump variable-length extra data */ - switch (SubTable->Header.Type & 0x7F) /* Mask off top bit */ + switch (Type) { case ACPI_ASF_TYPE_ALERT: case ACPI_ASF_TYPE_CONTROL: @@ -471,7 +476,7 @@ AcpiDmDumpCpep ( { AcpiOsPrintf ("\n"); Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoCpep0); + SubTable->Header.Length, AcpiDmTableInfoCpep0); if (ACPI_FAILURE (Status)) { return; @@ -479,8 +484,9 @@ AcpiDmDumpCpep ( /* Point to next sub-table */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, SubTable, SubTable->Length); + Offset += SubTable->Header.Length; + SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, SubTable, + SubTable->Header.Length); } } @@ -550,6 +556,10 @@ AcpiDmDumpDmar ( InfoTable = AcpiDmTableInfoDmar2; ScopeOffset = sizeof (ACPI_DMAR_ATSR); break; + case ACPI_DMAR_HARDWARE_AFFINITY: + InfoTable = AcpiDmTableInfoDmar3; + ScopeOffset = sizeof (ACPI_DMAR_RHSA); + break; default: AcpiOsPrintf ("\n**** Unknown DMAR sub-table type %X\n\n", SubTable->Type); return; @@ -737,6 +747,8 @@ AcpiDmDumpHest ( UINT32 Offset = sizeof (ACPI_TABLE_HEST); ACPI_DMTABLE_INFO *InfoTable; UINT32 SubTableLength; + UINT32 BankCount; + ACPI_HEST_IA_ERROR_BANK *BankTable; /* Main table */ @@ -752,31 +764,26 @@ AcpiDmDumpHest ( SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset); while (Offset < Table->Length) { + BankCount = 0; switch (SubTable->Type) { - case ACPI_HEST_TYPE_XPF_MACHINE_CHECK: + case ACPI_HEST_TYPE_IA32_CHECK: InfoTable = AcpiDmTableInfoHest0; - SubTableLength = sizeof (ACPI_HEST_XPF_MACHINE_CHECK); + SubTableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK); + BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, + SubTable))->NumHardwareBanks; break; - case ACPI_HEST_TYPE_XPF_CORRECTED_MACHINE_CHECK: + case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: InfoTable = AcpiDmTableInfoHest1; - SubTableLength = sizeof (ACPI_HEST_XPF_CORRECTED); + SubTableLength = sizeof (ACPI_HEST_IA_CORRECTED); + BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, + SubTable))->NumHardwareBanks; break; - case ACPI_HEST_TYPE_XPF_NON_MASKABLE_INTERRUPT: - InfoTable = AcpiDmTableInfoHest3; - SubTableLength = sizeof (ACPI_HEST_XPF_NMI); - break; - - case ACPI_HEST_TYPE_IPF_CORRECTED_MACHINE_CHECK: - InfoTable = AcpiDmTableInfoHest4; - SubTableLength = sizeof (ACPI_HEST_IPF_CORRECTED); - break; - - case ACPI_HEST_TYPE_IPF_CORRECTED_PLATFORM_ERROR: - InfoTable = AcpiDmTableInfoHest5; - SubTableLength = sizeof (ACPI_HEST_IPF_CORRECTED_PLATFORM); + case ACPI_HEST_TYPE_IA32_NMI: + InfoTable = AcpiDmTableInfoHest2; + SubTableLength = sizeof (ACPI_HEST_IA_NMI); break; case ACPI_HEST_TYPE_AER_ROOT_PORT: @@ -794,7 +801,7 @@ AcpiDmDumpHest ( SubTableLength = sizeof (ACPI_HEST_AER_BRIDGE); break; - case ACPI_HEST_TYPE_GENERIC_HARDWARE_ERROR_SOURCE: + case ACPI_HEST_TYPE_GENERIC_ERROR: InfoTable = AcpiDmTableInfoHest9; SubTableLength = sizeof (ACPI_HEST_GENERIC); break; @@ -814,14 +821,212 @@ AcpiDmDumpHest ( return; } - /* Point to next sub-table (each subtable is of fixed length) */ + /* Point to end of current subtable (each subtable above is of fixed length) */ Offset += SubTableLength; + + /* If there are any (fixed-length) Error Banks from above, dump them now */ + + if (BankCount) + { + BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, SubTable, SubTableLength); + SubTableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK); + + while (BankCount) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, BankTable, + sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank); + if (ACPI_FAILURE (Status)) + { + return; + } + Offset += sizeof (ACPI_HEST_IA_ERROR_BANK); + BankTable++; + BankCount--; + } + } + + /* Point to next sub-table */ + SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, SubTable, SubTableLength); } } +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpIvrs + * + * PARAMETERS: Table - A IVRS table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a IVRS + * + ******************************************************************************/ + +static UINT8 EntrySizes[] = {4,8,16,32}; + +void +AcpiDmDumpIvrs ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_IVRS); + UINT32 EntryOffset; + UINT32 EntryLength; + UINT32 EntryType; + ACPI_IVRS_DE_HEADER *DeviceEntry; + ACPI_IVRS_HEADER *SubTable; + ACPI_DMTABLE_INFO *InfoTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoIvrsHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (SubTable->Type) + { + case ACPI_IVRS_TYPE_HARDWARE: + InfoTable = AcpiDmTableInfoIvrs0; + break; + case ACPI_IVRS_TYPE_MEMORY1: + case ACPI_IVRS_TYPE_MEMORY2: + case ACPI_IVRS_TYPE_MEMORY3: + InfoTable = AcpiDmTableInfoIvrs1; + break; + default: + AcpiOsPrintf ("\n**** Unknown IVRS sub-table type %X\n", + SubTable->Type); + + /* Attempt to continue */ + + if (!SubTable->Length) + { + AcpiOsPrintf ("Invalid zero length subtable\n"); + return; + } + goto NextSubTable; + } + + /* Dump the subtable */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* The hardware subtable can contain multiple device entries */ + + if (SubTable->Type == ACPI_IVRS_TYPE_HARDWARE) + { + EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE); + DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, SubTable, + sizeof (ACPI_IVRS_HARDWARE)); + + while (EntryOffset < (Offset + SubTable->Length)) + { + AcpiOsPrintf ("\n"); + /* + * Upper 2 bits of Type encode the length of the device entry + * + * 00 = 4 byte + * 01 = 8 byte + * 10 = 16 byte - currently no entries defined + * 11 = 32 byte - currently no entries defined + */ + EntryType = DeviceEntry->Type; + EntryLength = EntrySizes [EntryType >> 6]; + + switch (EntryType) + { + /* 4-byte device entries */ + + case ACPI_IVRS_TYPE_PAD4: + case ACPI_IVRS_TYPE_ALL: + case ACPI_IVRS_TYPE_SELECT: + case ACPI_IVRS_TYPE_START: + case ACPI_IVRS_TYPE_END: + + InfoTable = AcpiDmTableInfoIvrs4; + break; + + /* 8-byte entries, type A */ + + case ACPI_IVRS_TYPE_ALIAS_SELECT: + case ACPI_IVRS_TYPE_ALIAS_START: + + InfoTable = AcpiDmTableInfoIvrs8a; + break; + + /* 8-byte entries, type B */ + + case ACPI_IVRS_TYPE_PAD8: + case ACPI_IVRS_TYPE_EXT_SELECT: + case ACPI_IVRS_TYPE_EXT_START: + + InfoTable = AcpiDmTableInfoIvrs8b; + break; + + /* 8-byte entries, type C */ + + case ACPI_IVRS_TYPE_SPECIAL: + + InfoTable = AcpiDmTableInfoIvrs8c; + break; + + default: + InfoTable = AcpiDmTableInfoIvrs4; + AcpiOsPrintf ( + "\n**** Unknown IVRS device entry type/length: " + "%.2X/%X at offset %.4X: (header below)\n", + EntryType, EntryLength, EntryOffset); + break; + } + + /* Dump the Device Entry */ + + Status = AcpiDmDumpTable (Table->Length, EntryOffset, + DeviceEntry, EntryLength, InfoTable); + + EntryOffset += EntryLength; + DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, DeviceEntry, + EntryLength); + } + } + +NextSubTable: + /* Point to next sub-table */ + + Offset += SubTable->Length; + SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, SubTable, SubTable->Length); + } +} + + /******************************************************************************* * * FUNCTION: AcpiDmDumpMadt @@ -991,6 +1196,58 @@ AcpiDmDumpMcfg ( } +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpMsct + * + * PARAMETERS: Table - A MSCT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a MSCT + * + ******************************************************************************/ + +void +AcpiDmDumpMsct ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_MSCT); + ACPI_MSCT_PROXIMITY *SubTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next sub-table */ + + Offset += sizeof (ACPI_MSCT_PROXIMITY); + SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, SubTable, sizeof (ACPI_MSCT_PROXIMITY)); + } +} + + /******************************************************************************* * * FUNCTION: AcpiDmDumpSlit @@ -1149,3 +1406,54 @@ NextSubTable: } } + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpWdat + * + * PARAMETERS: Table - A WDAT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a WDAT + * + ******************************************************************************/ + +void +AcpiDmDumpWdat ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_WDAT); + ACPI_WDAT_ENTRY *SubTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoWdat); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + sizeof (ACPI_WDAT_ENTRY), AcpiDmTableInfoWdat0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next sub-table */ + + Offset += sizeof (ACPI_WDAT_ENTRY); + SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, SubTable, sizeof (ACPI_WDAT_ENTRY)); + } +} diff --git a/sys/contrib/dev/acpica/common/dmtbinfo.c b/sys/contrib/dev/acpica/common/dmtbinfo.c index 796c8972430..6d3b500e0c0 100644 --- a/sys/contrib/dev/acpica/common/dmtbinfo.c +++ b/sys/contrib/dev/acpica/common/dmtbinfo.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -139,14 +139,19 @@ #define ACPI_ERST_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_ERST,f) #define ACPI_HEST_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_HEST,f) #define ACPI_HPET_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_HPET,f) +#define ACPI_IVRS_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_IVRS,f) #define ACPI_MADT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MADT,f) #define ACPI_MCFG_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MCFG,f) +#define ACPI_MSCT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MSCT,f) #define ACPI_SBST_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SBST,f) #define ACPI_SLIT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SLIT,f) #define ACPI_SPCR_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SPCR,f) #define ACPI_SPMI_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SPMI,f) #define ACPI_SRAT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SRAT,f) #define ACPI_TCPA_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_TCPA,f) +#define ACPI_UEFI_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_UEFI,f) +#define ACPI_WAET_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_WAET,f) +#define ACPI_WDAT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_WDAT,f) #define ACPI_WDRT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_WDRT,f) /* Subtables */ @@ -163,17 +168,24 @@ #define ACPI_DMAR0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_DMAR_HARDWARE_UNIT,f) #define ACPI_DMAR1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_DMAR_RESERVED_MEMORY,f) #define ACPI_DMAR2_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_DMAR_ATSR,f) +#define ACPI_DMAR3_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_DMAR_RHSA,f) #define ACPI_EINJ0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_WHEA_HEADER,f) -#define ACPI_HEST0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_XPF_MACHINE_CHECK,f) -#define ACPI_HEST1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_XPF_CORRECTED,f) -#define ACPI_HEST3_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_XPF_NMI,f) -#define ACPI_HEST4_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_IPF_CORRECTED,f) -#define ACPI_HEST5_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_IPF_CORRECTED_PLATFORM,f) +#define ACPI_HEST0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_IA_MACHINE_CHECK,f) +#define ACPI_HEST1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_IA_CORRECTED,f) +#define ACPI_HEST2_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_IA_NMI,f) #define ACPI_HEST6_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_AER_ROOT,f) #define ACPI_HEST7_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_AER,f) #define ACPI_HEST8_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_AER_BRIDGE,f) #define ACPI_HEST9_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_GENERIC,f) #define ACPI_HESTN_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_NOTIFY,f) +#define ACPI_HESTB_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_IA_ERROR_BANK,f) +#define ACPI_IVRSH_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_IVRS_HEADER,f) +#define ACPI_IVRS0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_IVRS_HARDWARE,f) +#define ACPI_IVRS1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_IVRS_MEMORY,f) +#define ACPI_IVRSD_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_IVRS_DE_HEADER,f) +#define ACPI_IVRS8A_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_IVRS_DEVICE8A,f) +#define ACPI_IVRS8B_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_IVRS_DEVICE8B,f) +#define ACPI_IVRS8C_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_IVRS_DEVICE8C,f) #define ACPI_MADT0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MADT_LOCAL_APIC,f) #define ACPI_MADT1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MADT_IO_APIC,f) #define ACPI_MADT2_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MADT_INTERRUPT_OVERRIDE,f) @@ -187,10 +199,12 @@ #define ACPI_MADT10_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MADT_LOCAL_X2APIC_NMI,f) #define ACPI_MADTH_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_SUBTABLE_HEADER,f) #define ACPI_MCFG0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MCFG_ALLOCATION,f) +#define ACPI_MSCT0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MSCT_PROXIMITY,f) #define ACPI_SRATH_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_SUBTABLE_HEADER,f) #define ACPI_SRAT0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_SRAT_CPU_AFFINITY,f) #define ACPI_SRAT1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_SRAT_MEM_AFFINITY,f) #define ACPI_SRAT2_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_SRAT_X2APIC_CPU_AFFINITY,f) +#define ACPI_WDAT0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_WDAT_ENTRY,f) /* * Simplify access to flag fields by breaking them up into bytes @@ -299,12 +313,16 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoFacs[] = {ACPI_DMT_NAME4, ACPI_FACS_OFFSET (Signature[0]), "Signature"}, {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (Length), "Length"}, {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (HardwareSignature), "Hardware Signature"}, - {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (FirmwareWakingVector), "Firmware Waking Vector(32)"}, + {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (FirmwareWakingVector), "32 Firmware Waking Vector"}, {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (GlobalLock), "Global Lock"}, {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (Flags), "Flags (decoded below)"}, {ACPI_DMT_FLAG0, ACPI_FACS_FLAG_OFFSET (Flags,0), "S4BIOS Support Present"}, - {ACPI_DMT_UINT64, ACPI_FACS_OFFSET (XFirmwareWakingVector), "Firmware Waking Vector(64)"}, + {ACPI_DMT_FLAG1, ACPI_FACS_FLAG_OFFSET (Flags,0), "64-bit Wake Supported (V2)"}, + {ACPI_DMT_UINT64, ACPI_FACS_OFFSET (XFirmwareWakingVector), "64 Firmware Waking Vector"}, {ACPI_DMT_UINT8, ACPI_FACS_OFFSET (Version), "Version"}, + {ACPI_DMT_UINT24, ACPI_FACS_OFFSET (Reserved[0]), "Reserved"}, + {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (OspmFlags), "OspmFlags (decoded below)"}, + {ACPI_DMT_FLAG0, ACPI_FACS_FLAG_OFFSET (OspmFlags,0), "64-bit Wake Env Required (V2)"}, {ACPI_DMT_EXIT, 0, NULL} }; @@ -454,9 +472,9 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoAsfHdr[] = ACPI_DMTABLE_INFO AcpiDmTableInfoAsf0[] = { {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (MinResetValue), "Minimum Reset Value"}, - {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (MinResetValue), "Minimum Polling Interval"}, + {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (MinPollInterval), "Minimum Polling Interval"}, {ACPI_DMT_UINT16, ACPI_ASF0_OFFSET (SystemId), "System ID"}, - {ACPI_DMT_UINT32, ACPI_ASF0_OFFSET (SystemId), "Manufacturer ID"}, + {ACPI_DMT_UINT32, ACPI_ASF0_OFFSET (MfgId), "Manufacturer ID"}, {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (Flags), "Flags"}, {ACPI_DMT_UINT24, ACPI_ASF0_OFFSET (Reserved2[0]), "Reserved"}, {ACPI_DMT_EXIT, 0, NULL} @@ -579,8 +597,8 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoCpep[] = ACPI_DMTABLE_INFO AcpiDmTableInfoCpep0[] = { - {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Type), "Subtable Type"}, - {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Length), "Length"}, + {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Header.Type), "Subtable Type"}, + {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Header.Length), "Length"}, {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Id), "Processor ID"}, {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Eid), "Processor EID"}, {ACPI_DMT_UINT32, ACPI_CPEP0_OFFSET (Interval), "Polling Interval"}, @@ -671,6 +689,16 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoDmar2[] = {ACPI_DMT_EXIT, 0, NULL} }; +/* 3: Remapping Hardware Static Affinity Structure */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDmar3[] = +{ + {ACPI_DMT_UINT32, ACPI_DMAR3_OFFSET (Reserved), "Reserved"}, + {ACPI_DMT_UINT64, ACPI_DMAR3_OFFSET (BaseAddress), "Base Address"}, + {ACPI_DMT_UINT32, ACPI_DMAR3_OFFSET (ProximityDomain), "Proximity Domain"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + /******************************************************************************* * @@ -698,7 +726,8 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoEcdt[] = ACPI_DMTABLE_INFO AcpiDmTableInfoEinj[] = { {ACPI_DMT_UINT32, ACPI_EINJ_OFFSET (HeaderLength), "Injection Header Length"}, - {ACPI_DMT_UINT32, ACPI_EINJ_OFFSET (Reserved), "Reserved"}, + {ACPI_DMT_UINT8, ACPI_EINJ_OFFSET (Flags), "Flags"}, + {ACPI_DMT_UINT24, ACPI_EINJ_OFFSET (Reserved[0]), "Reserved"}, {ACPI_DMT_UINT32, ACPI_EINJ_OFFSET (Entries), "Injection Entry Count"}, {ACPI_DMT_EXIT, 0, NULL} }; @@ -743,97 +772,84 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoHest[] = {ACPI_DMT_EXIT, 0, NULL} }; +/* Common HEST structures for subtables */ + +#define ACPI_DM_HEST_HEADER \ + {ACPI_DMT_HEST, ACPI_HEST0_OFFSET (Header.Type), "Subtable Type"}, \ + {ACPI_DMT_UINT16, ACPI_HEST0_OFFSET (Header.SourceId), "Source Id"} + +#define ACPI_DM_HEST_AER \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Reserved1), "Reserved"}, \ + {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Flags), "Flags"}, \ + {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Enabled), "Enabled"}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.RecordsToPreallocate), "Records To Preallocate"}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.MaxSectionsPerRecord), "Max Sections Per Record"}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.Bus), "Bus"}, \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Device), "Device"}, \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Function), "Function"}, \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.DeviceControl), "DeviceControl"}, \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Reserved2), "Reserved"}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableMask), "Uncorrectable Mask"}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableSeverity), "Uncorrectable Severity"}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.CorrectableMask), "Correctable Mask"}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.AdvancedCapabilities), "Advanced Capabilities"} + + /* HEST Subtables */ -/* 0: XPF Machine Check Exception */ +/* 0: IA32 Machine Check Exception */ ACPI_DMTABLE_INFO AcpiDmTableInfoHest0[] = { - {ACPI_DMT_HEST, ACPI_HEST0_OFFSET (Header.Type), "Subtable Type"}, - {ACPI_DMT_UINT16, ACPI_HEST0_OFFSET (SourceId), "Source Id"}, - {ACPI_DMT_UINT16, ACPI_HEST0_OFFSET (ConfigWriteEnable), "Configuration Write Enable"}, + ACPI_DM_HEST_HEADER, + {ACPI_DMT_UINT16, ACPI_HEST0_OFFSET (Reserved1), "Reserved"}, {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (Flags), "Flags"}, - {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (Reserved1), "Reserved"}, - {ACPI_DMT_UINT32, ACPI_HEST0_OFFSET (RecordsToPreAllocate), "Records To Preallocate"}, + {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (Enabled), "Enabled"}, + {ACPI_DMT_UINT32, ACPI_HEST0_OFFSET (RecordsToPreallocate), "Records To Preallocate"}, {ACPI_DMT_UINT32, ACPI_HEST0_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record"}, {ACPI_DMT_UINT64, ACPI_HEST0_OFFSET (GlobalCapabilityData), "Global Capability Data"}, {ACPI_DMT_UINT64, ACPI_HEST0_OFFSET (GlobalControlData), "Global Control Data"}, {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (NumHardwareBanks), "Num Hardware Banks"}, - {ACPI_DMT_UINT56, ACPI_HEST0_OFFSET (Reserved2), "Reserved"}, + {ACPI_DMT_UINT56, ACPI_HEST0_OFFSET (Reserved3[0]), "Reserved"}, {ACPI_DMT_EXIT, 0, NULL} }; -/* 1: XPF Corrected Machine Check */ +/* 1: IA32 Corrected Machine Check */ ACPI_DMTABLE_INFO AcpiDmTableInfoHest1[] = { - {ACPI_DMT_HEST, ACPI_HEST1_OFFSET (Header.Type), "Subtable Type"}, - {ACPI_DMT_UINT16, ACPI_HEST1_OFFSET (SourceId), "Source Id"}, - {ACPI_DMT_UINT16, ACPI_HEST1_OFFSET (ConfigWriteEnable), "Configuration Write Enable"}, + ACPI_DM_HEST_HEADER, + {ACPI_DMT_UINT16, ACPI_HEST1_OFFSET (Reserved1), "Reserved"}, {ACPI_DMT_UINT8, ACPI_HEST1_OFFSET (Flags), "Flags"}, {ACPI_DMT_UINT8, ACPI_HEST1_OFFSET (Enabled), "Enabled"}, - {ACPI_DMT_UINT32, ACPI_HEST1_OFFSET (RecordsToPreAllocate), "Records To Preallocate"}, + {ACPI_DMT_UINT32, ACPI_HEST1_OFFSET (RecordsToPreallocate), "Records To Preallocate"}, {ACPI_DMT_UINT32, ACPI_HEST1_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record"}, {ACPI_DMT_HESTNTFY, ACPI_HEST1_OFFSET (Notify), "Notify"}, {ACPI_DMT_UINT8, ACPI_HEST1_OFFSET (NumHardwareBanks), "Num Hardware Banks"}, - {ACPI_DMT_UINT24, ACPI_HEST1_OFFSET (Reserved), "Reserved"}, + {ACPI_DMT_UINT24, ACPI_HEST1_OFFSET (Reserved2[0]), "Reserved"}, {ACPI_DMT_EXIT, 0, NULL} }; -/* 3: XPF Non-Maskable Interrupt */ +/* 2: IA32 Non-Maskable Interrupt */ -ACPI_DMTABLE_INFO AcpiDmTableInfoHest3[] = +ACPI_DMTABLE_INFO AcpiDmTableInfoHest2[] = { - {ACPI_DMT_HEST, ACPI_HEST3_OFFSET (Header.Type), "Subtable Type"}, - {ACPI_DMT_UINT16, ACPI_HEST3_OFFSET (SourceId), "Source Id"}, - {ACPI_DMT_UINT32, ACPI_HEST3_OFFSET (Reserved), "Reserved"}, - {ACPI_DMT_UINT32, ACPI_HEST3_OFFSET (RecordsToPreAllocate), "Records To Preallocate"}, - {ACPI_DMT_UINT32, ACPI_HEST3_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record"}, - {ACPI_DMT_UINT32, ACPI_HEST3_OFFSET (MaxRawDataLength), "Max Raw Data Length"}, + ACPI_DM_HEST_HEADER, + {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (Reserved), "Reserved"}, + {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (RecordsToPreallocate), "Records To Preallocate"}, + {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record"}, + {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (MaxRawDataLength), "Max Raw Data Length"}, {ACPI_DMT_EXIT, 0, NULL} }; -/* 4: IPF Corrected Machine Check */ - -ACPI_DMTABLE_INFO AcpiDmTableInfoHest4[] = -{ - {ACPI_DMT_HEST, ACPI_HEST4_OFFSET (Header.Type), "Subtable Type"}, - {ACPI_DMT_UINT8, ACPI_HEST4_OFFSET (Enabled), "Enabled"}, - {ACPI_DMT_UINT8, ACPI_HEST4_OFFSET (Reserved), "Reserved"}, - {ACPI_DMT_EXIT, 0, NULL} -}; - -/* 5: IPF Corrected Platform Error */ - -ACPI_DMTABLE_INFO AcpiDmTableInfoHest5[] = -{ - {ACPI_DMT_HEST, ACPI_HEST5_OFFSET (Header.Type), "Subtable Type"}, - {ACPI_DMT_UINT8, ACPI_HEST5_OFFSET (Enabled), "Enabled"}, - {ACPI_DMT_UINT8, ACPI_HEST5_OFFSET (Reserved), "Reserved"}, - {ACPI_DMT_EXIT, 0, NULL} -}; /* 6: PCI Express Root Port AER */ ACPI_DMTABLE_INFO AcpiDmTableInfoHest6[] = { - {ACPI_DMT_HEST, ACPI_HEST6_OFFSET (Header.Type), "Subtable Type"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.SourceId), "Source Id"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.ConfigWriteEnable), "Configuration Write Enable"}, - {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Flags), "Flags"}, - {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Enabled), "Enabled"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.RecordsToPreAllocate), "Records To Preallocate"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.MaxSectionsPerRecord), "Max Sections Per Record"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.Bus), "Bus"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Device), "Device"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Function), "Function"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.DeviceControl), "DeviceControl"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Reserved), "Reserved"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableErrorMask), "Uncorrectable Error Mask"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableErrorSeverity), "Uncorrectable Error Severity"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.CorrectableErrorMask), "Correctable Error Mask"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.AdvancedErrorCapabilities), "Advanced Error Capabilities"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (RootErrorCommand), "Root Error Command"}, + ACPI_DM_HEST_HEADER, + ACPI_DM_HEST_AER, + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (RootErrorCommand), "Root Error Command"}, {ACPI_DMT_EXIT, 0, NULL} }; @@ -841,22 +857,8 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoHest6[] = ACPI_DMTABLE_INFO AcpiDmTableInfoHest7[] = { - {ACPI_DMT_HEST, ACPI_HEST6_OFFSET (Header.Type), "Subtable Type"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.SourceId), "Source Id"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.ConfigWriteEnable), "Configuration Write Enable"}, - {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Flags), "Flags"}, - {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Enabled), "Enabled"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.RecordsToPreAllocate), "Records To Preallocate"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.MaxSectionsPerRecord), "Max Sections Per Record"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.Bus), "Bus"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Device), "Device"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Function), "Function"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.DeviceControl), "DeviceControl"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Reserved), "Reserved"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableErrorMask), "Uncorrectable Error Mask"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableErrorSeverity), "Uncorrectable Error Severity"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.CorrectableErrorMask), "Correctable Error Mask"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.AdvancedErrorCapabilities), "Advanced Error Capabilities"}, + ACPI_DM_HEST_HEADER, + ACPI_DM_HEST_AER, {ACPI_DMT_EXIT, 0, NULL} }; @@ -864,25 +866,11 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoHest7[] = ACPI_DMTABLE_INFO AcpiDmTableInfoHest8[] = { - {ACPI_DMT_HEST, ACPI_HEST6_OFFSET (Header.Type), "Subtable Type"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.SourceId), "Source Id"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.ConfigWriteEnable), "Configuration Write Enable"}, - {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Flags), "Flags"}, - {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Enabled), "Enabled"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.RecordsToPreAllocate), "Records To Preallocate"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.MaxSectionsPerRecord), "Max Sections Per Record"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.Bus), "Bus"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Device), "Device"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Function), "Function"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.DeviceControl), "DeviceControl"}, - {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Reserved), "Reserved"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableErrorMask), "Uncorrectable Error Mask"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableErrorSeverity), "Uncorrectable Error Severity"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.CorrectableErrorMask), "Correctable Error Mask"}, - {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.AdvancedErrorCapabilities), "Advanced Error Capabilities"}, - {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (SecondaryUncorrectableErrorMask), "2nd Uncorrectable Err Mask"}, - {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (SecondaryUncorrectableErrorSeverity), "2nd Uncorrectable Err Severity"}, - {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (SecondaryAdvancedCapabilities), "2nd Advanced Capabilities"}, + ACPI_DM_HEST_HEADER, + ACPI_DM_HEST_AER, + {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (UncorrectableMask2), "2nd Uncorrectable Mask"}, + {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (UncorrectableSeverity2), "2nd Uncorrectable Severity"}, + {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (AdvancedCapabilities2), "2nd Advanced Capabilities"}, {ACPI_DMT_EXIT, 0, NULL} }; @@ -890,21 +878,20 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoHest8[] = ACPI_DMTABLE_INFO AcpiDmTableInfoHest9[] = { - {ACPI_DMT_HEST, ACPI_HEST9_OFFSET (Header.Type), "Subtable Type"}, - {ACPI_DMT_UINT16, ACPI_HEST9_OFFSET (SourceId), "Source Id"}, + ACPI_DM_HEST_HEADER, {ACPI_DMT_UINT16, ACPI_HEST9_OFFSET (RelatedSourceId), "Related Source Id"}, - {ACPI_DMT_UINT8, ACPI_HEST9_OFFSET (ConfigWriteEnable), "Configuration Write Enable"}, + {ACPI_DMT_UINT8, ACPI_HEST9_OFFSET (Reserved), "Reserved"}, {ACPI_DMT_UINT8, ACPI_HEST9_OFFSET (Enabled), "Enabled"}, - {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (RecordsToPreAllocate), "Records To Preallocate"}, + {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (RecordsToPreallocate), "Records To Preallocate"}, {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record"}, {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (MaxRawDataLength), "Max Raw Data Length"}, {ACPI_DMT_GAS, ACPI_HEST9_OFFSET (ErrorStatusAddress), "Error Status Address"}, {ACPI_DMT_HESTNTFY, ACPI_HEST9_OFFSET (Notify), "Notify"}, - {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (ErrorStatusBlockLength), "Error Status Block Length"}, + {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (ErrorBlockLength), "Error Status Block Length"}, {ACPI_DMT_EXIT, 0, NULL} }; -ACPI_DMTABLE_INFO AcpiDmTableInfoHestNotify[10] = +ACPI_DMTABLE_INFO AcpiDmTableInfoHestNotify[] = { {ACPI_DMT_HESTNTYP, ACPI_HESTN_OFFSET (Type), "Notify Type"}, {ACPI_DMT_UINT8, ACPI_HESTN_OFFSET (Length), "Notify Length"}, @@ -919,6 +906,25 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoHestNotify[10] = }; +/* + * IA32 Error Bank(s) - Follows the ACPI_HEST_IA_MACHINE_CHECK and + * ACPI_HEST_IA_CORRECTED structures. + */ +ACPI_DMTABLE_INFO AcpiDmTableInfoHestBank[] = +{ + {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (BankNumber), "Bank Number"}, + {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (ClearStatusOnInit), "Clear Status On Init"}, + {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (StatusFormat), "Status Format"}, + {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (Reserved), "Reserved"}, + {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (ControlRegister), "Control Register"}, + {ACPI_DMT_UINT64, ACPI_HESTB_OFFSET (ControlData), "Control Data"}, + {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (StatusRegister), "Status Register"}, + {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (AddressRegister), "Address Register"}, + {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (MiscRegister), "Misc Register"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + + /******************************************************************************* * * HPET - High Precision Event Timer table @@ -932,9 +938,104 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoHpet[] = {ACPI_DMT_UINT8, ACPI_HPET_OFFSET (Sequence), "Sequence Number"}, {ACPI_DMT_UINT16, ACPI_HPET_OFFSET (MinimumTick), "Minimum Clock Ticks"}, {ACPI_DMT_UINT8, ACPI_HPET_OFFSET (Flags), "Flags (decoded below)"}, - {ACPI_DMT_FLAG0, ACPI_HPET_FLAG_OFFSET (Flags,0), "Page Protect"}, - {ACPI_DMT_FLAG1, ACPI_HPET_FLAG_OFFSET (Flags,0), "4K Page Protect"}, - {ACPI_DMT_FLAG2, ACPI_HPET_FLAG_OFFSET (Flags,0), "64K Page Protect"}, + {ACPI_DMT_FLAG0, ACPI_HPET_FLAG_OFFSET (Flags,0), "4K Page Protect"}, + {ACPI_DMT_FLAG1, ACPI_HPET_FLAG_OFFSET (Flags,0), "64K Page Protect"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + + +/******************************************************************************* + * + * IVRS - I/O Virtualization Reporting Structure + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs[] = +{ + {ACPI_DMT_UINT32, ACPI_IVRS_OFFSET (Info), "Virtualization Info"}, + {ACPI_DMT_UINT64, ACPI_IVRS_OFFSET (Reserved), "Reserved"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + +/* Common Subtable header (one per Subtable) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrsHdr[] = +{ + {ACPI_DMT_IVRS, ACPI_IVRSH_OFFSET (Type), "Subtable Type"}, + {ACPI_DMT_UINT8, ACPI_IVRSH_OFFSET (Flags), "Flags"}, + {ACPI_DMT_UINT16, ACPI_IVRSH_OFFSET (Length), "Length"}, + {ACPI_DMT_UINT16, ACPI_IVRSH_OFFSET (DeviceId), "DeviceId"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + +/* IVRS subtables */ + +/* 0x10: I/O Virtualization Hardware Definition (IVHD) Block */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs0[] = +{ + {ACPI_DMT_UINT16, ACPI_IVRS0_OFFSET (CapabilityOffset), "Capability Offset"}, + {ACPI_DMT_UINT64, ACPI_IVRS0_OFFSET (BaseAddress), "Base Address"}, + {ACPI_DMT_UINT16, ACPI_IVRS0_OFFSET (PciSegmentGroup), "PCI Segment Group"}, + {ACPI_DMT_UINT16, ACPI_IVRS0_OFFSET (Info), "Virtualization Info"}, + {ACPI_DMT_UINT32, ACPI_IVRS0_OFFSET (Reserved), "Reserved"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + +/* 0x20, 0x21, 0x22: I/O Virtualization Memory Definition (IVMD) Block */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs1[] = +{ + {ACPI_DMT_UINT16, ACPI_IVRS1_OFFSET (AuxData), "Auxiliary Data"}, + {ACPI_DMT_UINT64, ACPI_IVRS1_OFFSET (Reserved), "Reserved"}, + {ACPI_DMT_UINT64, ACPI_IVRS1_OFFSET (StartAddress), "Start Address"}, + {ACPI_DMT_UINT64, ACPI_IVRS1_OFFSET (MemoryLength), "Memory Length"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + +/* Device entry header for IVHD block */ + +#define ACPI_DMT_IVRS_DE_HEADER \ + {ACPI_DMT_UINT8, ACPI_IVRSD_OFFSET (Type), "Entry Type"}, \ + {ACPI_DMT_UINT16, ACPI_IVRSD_OFFSET (Id), "Device ID"}, \ + {ACPI_DMT_UINT8, ACPI_IVRSD_OFFSET (DataSetting), "Data Setting"} + +/* 4-byte device entry */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs4[] = +{ + ACPI_DMT_IVRS_DE_HEADER, + {ACPI_DMT_EXIT, 0, NULL} +}; + +/* 8-byte device entry */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8a[] = +{ + ACPI_DMT_IVRS_DE_HEADER, + {ACPI_DMT_UINT8, ACPI_IVRS8A_OFFSET (Reserved1), "Reserved"}, + {ACPI_DMT_UINT16, ACPI_IVRS8A_OFFSET (UsedId), "Source Used Device ID"}, + {ACPI_DMT_UINT8, ACPI_IVRS8A_OFFSET (Reserved2), "Reserved"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + +/* 8-byte device entry */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8b[] = +{ + ACPI_DMT_IVRS_DE_HEADER, + {ACPI_DMT_UINT32, ACPI_IVRS8B_OFFSET (ExtendedData), "Extended Data"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + +/* 8-byte device entry */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8c[] = +{ + ACPI_DMT_IVRS_DE_HEADER, + {ACPI_DMT_UINT8, ACPI_IVRS8C_OFFSET (Handle), "Handle"}, + {ACPI_DMT_UINT16, ACPI_IVRS8C_OFFSET (UsedId), "Source Used Device ID"}, + {ACPI_DMT_UINT8, ACPI_IVRS8C_OFFSET (Variety), "Variety"}, {ACPI_DMT_EXIT, 0, NULL} }; @@ -1074,7 +1175,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMadt8[] = {ACPI_DMT_EXIT, 0, NULL} }; -/* 9: Processor Local X2_APIC (07/2008) */ +/* 9: Processor Local X2_APIC (ACPI 4.0) */ ACPI_DMTABLE_INFO AcpiDmTableInfoMadt9[] = { @@ -1086,7 +1187,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMadt9[] = {ACPI_DMT_EXIT, 0, NULL} }; -/* 10: Local X2_APIC NMI (07/2008) */ +/* 10: Local X2_APIC NMI (ACPI 4.0) */ ACPI_DMTABLE_INFO AcpiDmTableInfoMadt10[] = { @@ -1123,6 +1224,35 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg0[] = }; +/******************************************************************************* + * + * MSCT - Maximum System Characteristics Table (ACPI 4.0) + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMsct[] = +{ + {ACPI_DMT_UINT32, ACPI_MSCT_OFFSET (ProximityOffset), "Proximity Offset"}, + {ACPI_DMT_UINT32, ACPI_MSCT_OFFSET (MaxProximityDomains), "Max Proximity Domains"}, + {ACPI_DMT_UINT32, ACPI_MSCT_OFFSET (MaxClockDomains), "Max Clock Domains"}, + {ACPI_DMT_UINT64, ACPI_MSCT_OFFSET (MaxAddress), "Max Physical Address"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + +/* Subtable - Maximum Proximity Domain Information. Version 1 */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMsct0[] = +{ + {ACPI_DMT_UINT8, ACPI_MSCT0_OFFSET (Revision), "Revision"}, + {ACPI_DMT_UINT8, ACPI_MSCT0_OFFSET (Length), "Length"}, + {ACPI_DMT_UINT32, ACPI_MSCT0_OFFSET (RangeStart), "Domain Range Start"}, + {ACPI_DMT_UINT32, ACPI_MSCT0_OFFSET (RangeEnd), "Domain Range End"}, + {ACPI_DMT_UINT32, ACPI_MSCT0_OFFSET (ProcessorCapacity), "Processor Capacity"}, + {ACPI_DMT_UINT64, ACPI_MSCT0_OFFSET (MemoryCapacity), "Memory Capacity"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + + /******************************************************************************* * * SBST - Smart Battery Specification Table @@ -1203,8 +1333,8 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoSpcr[] = ACPI_DMTABLE_INFO AcpiDmTableInfoSpmi[] = { - {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (Reserved), "Reserved"}, {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (InterfaceType), "Interface Type"}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (Reserved), "Reserved"}, {ACPI_DMT_UINT16, ACPI_SPMI_OFFSET (SpecRevision), "IPMI Spec Version"}, {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (InterruptType), "Interrupt Type"}, {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (GpeNumber), "GPE Number"}, @@ -1216,6 +1346,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoSpmi[] = {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciBus), "PCI Bus"}, {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciDevice), "PCI Device"}, {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciFunction), "PCI Function"}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (Reserved2), "Reserved"}, {ACPI_DMT_EXIT, 0, NULL} }; @@ -1275,7 +1406,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoSrat1[] = {ACPI_DMT_EXIT, 0, NULL} }; -/* 2: Processor Local X2_APIC Affinity (07/2008) */ +/* 2: Processor Local X2_APIC Affinity (ACPI 4.0) */ ACPI_DMTABLE_INFO AcpiDmTableInfoSrat2[] = { @@ -1284,6 +1415,8 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoSrat2[] = {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (ApicId), "Apic ID"}, {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (Flags), "Flags (decoded below)"}, {ACPI_DMT_FLAG0, ACPI_SRAT2_FLAG_OFFSET (Flags,0), "Enabled"}, + {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (ClockDomain), "Clock Domain"}, + {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (Reserved2), "Reserved"}, {ACPI_DMT_EXIT, 0, NULL} }; @@ -1303,6 +1436,74 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoTcpa[] = }; +/******************************************************************************* + * + * UEFI - UEFI Boot optimization Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoUefi[] = +{ + {ACPI_DMT_BUF16, ACPI_UEFI_OFFSET (Identifier[0]), "UUID Identifier"}, + {ACPI_DMT_UINT16, ACPI_UEFI_OFFSET (DataOffset), "Data Offset"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + + +/******************************************************************************* + * + * WAET - Windows ACPI Emulated devices Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoWaet[] = +{ + {ACPI_DMT_UINT32, ACPI_WAET_OFFSET (Flags), "Flags (decoded below)"}, + {ACPI_DMT_FLAG0, ACPI_WAET_OFFSET (Flags), "RTC needs no INT ack"}, + {ACPI_DMT_FLAG1, ACPI_WAET_OFFSET (Flags), "PM timer, one read only"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + + +/******************************************************************************* + * + * WDAT - Watchdog Action Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoWdat[] = +{ + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (HeaderLength), "Header Length"}, + {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciSegment), "PCI Segment"}, + {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciBus), "PCI Bus"}, + {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciDevice), "PCI Device"}, + {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciFunction), "PCI Function"}, + {ACPI_DMT_UINT24, ACPI_WDAT_OFFSET (Reserved[0]), "Reserved"}, + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (TimerPeriod), "Timer Period"}, + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (MaxCount), "Max Count"}, + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (MinCount), "Min Count"}, + {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (Flags), "Flags (decoded below)"}, + {ACPI_DMT_FLAG0, ACPI_WDAT_OFFSET (Flags), "Enabled"}, + {ACPI_DMT_FLAG7, ACPI_WDAT_OFFSET (Flags), "Stopped When Asleep"}, + {ACPI_DMT_UINT24, ACPI_WDAT_OFFSET (Reserved2[0]), "Reserved"}, + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (Entries), "Watchdog Entry Count"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + +/* WDAT Subtables - Watchdog Instruction Entries */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoWdat0[] = +{ + {ACPI_DMT_UINT8, ACPI_WDAT0_OFFSET (Action), "Watchdog Action"}, + {ACPI_DMT_UINT8, ACPI_WDAT0_OFFSET (Instruction), "Instruction"}, + {ACPI_DMT_UINT16, ACPI_WDAT0_OFFSET (Reserved), "Reserved"}, + {ACPI_DMT_GAS, ACPI_WDAT0_OFFSET (RegisterRegion), "Register Region"}, + {ACPI_DMT_UINT32, ACPI_WDAT0_OFFSET (Value), "Value"}, + {ACPI_DMT_UINT32, ACPI_WDAT0_OFFSET (Mask), "Register Mask"}, + {ACPI_DMT_EXIT, 0, NULL} +}; + + /******************************************************************************* * * WDRT - Watchdog Resource Table @@ -1311,19 +1512,16 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoTcpa[] = ACPI_DMTABLE_INFO AcpiDmTableInfoWdrt[] = { - {ACPI_DMT_UINT32, ACPI_WDRT_OFFSET (HeaderLength), "Header Length"}, - {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciSegment), "PCI Segment"}, + {ACPI_DMT_GAS, ACPI_WDRT_OFFSET (ControlRegister), "Control Register"}, + {ACPI_DMT_GAS, ACPI_WDRT_OFFSET (CountRegister), "Count Register"}, + {ACPI_DMT_UINT16, ACPI_WDRT_OFFSET (PciDeviceId), "PCI Device ID"}, + {ACPI_DMT_UINT16, ACPI_WDRT_OFFSET (PciVendorId), "PCI Vendor ID"}, {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciBus), "PCI Bus"}, {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciDevice), "PCI Device"}, {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciFunction), "PCI Function"}, - {ACPI_DMT_UINT32, ACPI_WDRT_OFFSET (TimerPeriod), "Timer Period"}, - {ACPI_DMT_UINT32, ACPI_WDRT_OFFSET (MaxCount), "Max Count"}, - {ACPI_DMT_UINT32, ACPI_WDRT_OFFSET (MinCount), "Min Count"}, - {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (Flags), "Flags (decoded below)"}, - {ACPI_DMT_FLAG0, ACPI_WDRT_OFFSET (Flags), "Enabled"}, - {ACPI_DMT_FLAG7, ACPI_WDRT_OFFSET (Flags), "Stopped When Asleep"}, - {ACPI_DMT_UINT24, ACPI_WDRT_OFFSET (Reserved[0]), "Reserved"}, - {ACPI_DMT_UINT32, ACPI_WDRT_OFFSET (Entries), "Watchdog Entries"}, + {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciSegment), "PCI Segment"}, + {ACPI_DMT_UINT16, ACPI_WDRT_OFFSET (MaxCount), "Max Count"}, + {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (Units), "Counter Units"}, {ACPI_DMT_EXIT, 0, NULL} }; diff --git a/sys/contrib/dev/acpica/common/getopt.c b/sys/contrib/dev/acpica/common/getopt.c index 56c7332817f..b4a5b9e1e1d 100644 --- a/sys/contrib/dev/acpica/common/getopt.c +++ b/sys/contrib/dev/acpica/common/getopt.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -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/sys/contrib/dev/acpica/compiler/aslanalyze.c b/sys/contrib/dev/acpica/compiler/aslanalyze.c index 65052d50353..46a6db00723 100644 --- a/sys/contrib/dev/acpica/compiler/aslanalyze.c +++ b/sys/contrib/dev/acpica/compiler/aslanalyze.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -667,8 +667,8 @@ AnCheckForReservedName ( { /* The next two characters must be hex digits */ - if ((isxdigit (Name[2])) && - (isxdigit (Name[3]))) + if ((isxdigit ((int) Name[2])) && + (isxdigit ((int) Name[3]))) { return (ACPI_EVENT_RESERVED_NAME); } @@ -1236,7 +1236,7 @@ AnMethodAnalysisWalkBegin ( */ for (i = 0; Next->Asl.Value.String[i]; i++) { - if (!isalnum (Next->Asl.Value.String[i])) + if (!isalnum ((int) Next->Asl.Value.String[i])) { AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, Next, Next->Asl.Value.String); @@ -2157,7 +2157,7 @@ AnOtherSemanticAnalysisWalkBegin ( */ if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) || (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER)) && - (ArgNode->Asl.Value.Integer >= (ACPI_INTEGER) ACPI_WAIT_FOREVER)) + (ArgNode->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER)) { break; } diff --git a/sys/contrib/dev/acpica/compiler/aslcodegen.c b/sys/contrib/dev/acpica/compiler/aslcodegen.c index 6e0c764b5d1..6821a69e492 100644 --- a/sys/contrib/dev/acpica/compiler/aslcodegen.c +++ b/sys/contrib/dev/acpica/compiler/aslcodegen.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/compiler/aslcompile.c b/sys/contrib/dev/acpica/compiler/aslcompile.c index dda3ce3238c..443273c62c7 100644 --- a/sys/contrib/dev/acpica/compiler/aslcompile.c +++ b/sys/contrib/dev/acpica/compiler/aslcompile.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -895,6 +895,14 @@ CmCleanupAndExit ( 10) / Gbl_NsLookupCount); } + + if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) + { + printf ("\nMaximum error count (%d) exceeded\n", ASL_MAX_ERROR_COUNT); + } + + UtDisplaySummary (ASL_FILE_STDOUT); + /* Close all open files */ for (i = 2; i < ASL_MAX_FILE_TYPE; i++) @@ -902,14 +910,6 @@ CmCleanupAndExit ( FlCloseFile (i); } - /* - * TBD: SourceOutput should be .TMP, then rename if we want to keep it? - */ - if (!Gbl_SourceOutputFlag) - { - remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); - } - /* Delete AML file if there are errors */ if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors)) @@ -917,12 +917,19 @@ CmCleanupAndExit ( remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename); } - if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) + /* + * Delete intermediate ("combined") source file (if -ls flag not set) + * + * TBD: SourceOutput should be .TMP, then rename if we want to keep it? + */ + if (!Gbl_SourceOutputFlag) { - printf ("\nMaximum error count (%d) exceeded\n", ASL_MAX_ERROR_COUNT); + if (remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename)) + { + printf ("Could not remove SRC file, %s\n", + Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); + } } - - UtDisplaySummary (ASL_FILE_STDOUT); } diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.h b/sys/contrib/dev/acpica/compiler/aslcompiler.h index a698f5fc761..16b5f723d45 100644 --- a/sys/contrib/dev/acpica/compiler/aslcompiler.h +++ b/sys/contrib/dev/acpica/compiler/aslcompiler.h @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -511,7 +511,7 @@ TrCreateLeafNode ( ACPI_PARSE_OBJECT * TrCreateValuedLeafNode ( UINT32 ParseOpcode, - ACPI_INTEGER Value); + UINT64 Value); ACPI_PARSE_OBJECT * TrLinkChildren ( @@ -555,6 +555,10 @@ void AslAbort ( void); +void +FlAddIncludeDirectory ( + char *Dir); + void FlOpenIncludeFile ( ACPI_PARSE_OBJECT *Op); @@ -714,7 +718,7 @@ UtCheckIntegerRange ( UINT32 LowValue, UINT32 HighValue); -ACPI_INTEGER +UINT64 UtDoConstant ( char *String); diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.l b/sys/contrib/dev/acpica/compiler/aslcompiler.l index aff60d6026a..bf9077f495a 100644 --- a/sys/contrib/dev/acpica/compiler/aslcompiler.l +++ b/sys/contrib/dev/acpica/compiler/aslcompiler.l @@ -10,7 +10,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -386,6 +386,7 @@ NamePathTail [.]{NameSeg} "SMBus" { count (0); return (PARSEOP_REGIONSPACE_SMBUS); } "SystemCMOS" { count (0); return (PARSEOP_REGIONSPACE_CMOS); } "PciBarTarget" { count (0); return (PARSEOP_REGIONSPACE_PCIBAR); } +"IPMI" { count (0); return (PARSEOP_REGIONSPACE_IPMI); } "FFixedHW" { count (0); return (PARSEOP_ADDRESSSPACE_FFIXEDHW); } diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.y b/sys/contrib/dev/acpica/compiler/aslcompiler.y index 2122cf1dfb5..d5120def8e1 100644 --- a/sys/contrib/dev/acpica/compiler/aslcompiler.y +++ b/sys/contrib/dev/acpica/compiler/aslcompiler.y @@ -10,7 +10,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -400,6 +400,7 @@ AslLocalAllocate (unsigned int Size); %token PARSEOP_REGIONSPACE_CMOS %token PARSEOP_REGIONSPACE_EC %token PARSEOP_REGIONSPACE_IO +%token PARSEOP_REGIONSPACE_IPMI %token PARSEOP_REGIONSPACE_MEM %token PARSEOP_REGIONSPACE_PCI %token PARSEOP_REGIONSPACE_PCIBAR @@ -2175,6 +2176,7 @@ RegionSpaceKeyword | PARSEOP_REGIONSPACE_SMBUS {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_SMBUS);} | PARSEOP_REGIONSPACE_CMOS {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_CMOS);} | PARSEOP_REGIONSPACE_PCIBAR {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_PCIBAR);} + | PARSEOP_REGIONSPACE_IPMI {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_IPMI);} ; AddressSpaceKeyword @@ -2386,7 +2388,7 @@ QWordConstExpr ConstExprTerm : PARSEOP_ZERO {$$ = TrCreateValuedLeafNode (PARSEOP_ZERO, 0);} | PARSEOP_ONE {$$ = TrCreateValuedLeafNode (PARSEOP_ONE, 1);} - | PARSEOP_ONES {$$ = TrCreateValuedLeafNode (PARSEOP_ONES, ACPI_INTEGER_MAX);} + | PARSEOP_ONES {$$ = TrCreateValuedLeafNode (PARSEOP_ONES, ACPI_UINT64_MAX);} ; /* OptionalCount must appear before ByteList or an incorrect reduction will result */ diff --git a/sys/contrib/dev/acpica/compiler/asldefine.h b/sys/contrib/dev/acpica/compiler/asldefine.h index c66040bbe4b..75345a5d7f4 100644 --- a/sys/contrib/dev/acpica/compiler/asldefine.h +++ b/sys/contrib/dev/acpica/compiler/asldefine.h @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -127,8 +127,8 @@ #define IntelAcpiCA "Intel ACPI Component Architecture" #define CompilerId "ASL Optimizing Compiler" #define DisassemblerId "AML Disassembler" -#define CompilerCopyright "Copyright (C) 2000 - 2009 Intel Corporation" -#define CompilerCompliance "Supports ACPI Specification Revision 3.0a" +#define CompilerCopyright "Copyright (c) 2000 - 2010 Intel Corporation" +#define CompilerCompliance "Supports ACPI Specification Revision 4.0" #define CompilerName "iasl" #define CompilerCreatorId "INTL" diff --git a/sys/contrib/dev/acpica/compiler/aslerror.c b/sys/contrib/dev/acpica/compiler/aslerror.c index 2591dfe8c8b..1fa78a5d81b 100644 --- a/sys/contrib/dev/acpica/compiler/aslerror.c +++ b/sys/contrib/dev/acpica/compiler/aslerror.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -169,13 +169,7 @@ AeAddToErrorLog ( ASL_ERROR_MSG *Prev; - if (!Gbl_ErrorLog) - { - Gbl_ErrorLog = Enode; - return; - } - - /* List is sorted according to line number */ + /* If Gbl_ErrorLog is null, this is the first error node */ if (!Gbl_ErrorLog) { @@ -183,8 +177,10 @@ AeAddToErrorLog ( return; } - /* Walk error list until we find a line number greater than ours */ - + /* + * Walk error list until we find a line number greater than ours. + * List is sorted according to line number. + */ Prev = NULL; Next = Gbl_ErrorLog; @@ -535,6 +531,7 @@ AslCommonError ( Gbl_NextError = Gbl_ErrorLog; CmDoOutputFiles (); CmCleanupAndExit (); + exit(1); } return; diff --git a/sys/contrib/dev/acpica/compiler/aslfiles.c b/sys/contrib/dev/acpica/compiler/aslfiles.c index 5f262fe14be..f2e2dca3fc3 100644 --- a/sys/contrib/dev/acpica/compiler/aslfiles.c +++ b/sys/contrib/dev/acpica/compiler/aslfiles.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -128,10 +128,11 @@ FlOpenFile ( char *Filename, char *Mode); -static FILE * -FlOpenLocalFile ( - char *LocalName, - char *Mode); +FILE * +FlOpenIncludeWithPrefix ( + char *PrefixDir, + char *Filename); + #ifdef ACPI_OBSOLETE_FUNCTIONS ACPI_STATUS @@ -170,45 +171,6 @@ AslAbort ( } -/******************************************************************************* - * - * FUNCTION: FlOpenLocalFile - * - * PARAMETERS: LocalName - Single filename (not a pathname) - * Mode - Open mode for fopen - * - * RETURN: File descriptor - * - * DESCRIPTION: Build a complete pathname for the input filename and open - * the file. - * - ******************************************************************************/ - -static FILE * -FlOpenLocalFile ( - char *LocalName, - char *Mode) -{ - - StringBuffer[0] = 0; - - /* Check for an absolute pathname */ - - if ((LocalName[0] != '/') && /* Forward slash */ - (LocalName[0] != '\\') && /* backslash (Win) */ - (LocalName[1] != ':')) /* Device name (Win) */ - { - /* The include file path is relative, prepend the directory path */ - - strcat (StringBuffer, Gbl_DirectoryPath); - } - strcat (StringBuffer, LocalName); - - DbgPrint (ASL_PARSE_OUTPUT, "FlOpenLocalFile: %s\n", StringBuffer); - return (fopen (StringBuffer, (const char *) Mode)); -} - - /******************************************************************************* * * FUNCTION: FlFileError @@ -479,6 +441,122 @@ FlSetLineNumber ( } +/******************************************************************************* + * + * FUNCTION: FlAddIncludeDirectory + * + * PARAMETERS: Dir - Directory pathname string + * + * RETURN: None + * + * DESCRIPTION: Add a directory the list of include prefix directories. + * + ******************************************************************************/ + +void +FlAddIncludeDirectory ( + char *Dir) +{ + ASL_INCLUDE_DIR *NewDir; + ASL_INCLUDE_DIR *NextDir; + ASL_INCLUDE_DIR *PrevDir = NULL; + UINT32 NeedsSeparator = 0; + size_t DirLength; + + + DirLength = strlen (Dir); + if (!DirLength) + { + return; + } + + /* Make sure that the pathname ends with a path separator */ + + if ((Dir[DirLength-1] != '/') && + (Dir[DirLength-1] != '\\')) + { + NeedsSeparator = 1; + } + + NewDir = ACPI_ALLOCATE_ZEROED (sizeof (ASL_INCLUDE_DIR)); + NewDir->Dir = ACPI_ALLOCATE (DirLength + 1 + NeedsSeparator); + strcpy (NewDir->Dir, Dir); + if (NeedsSeparator) + { + strcat (NewDir->Dir, "/"); + } + + /* + * Preserve command line ordering of -I options by adding new elements + * at the end of the list + */ + NextDir = Gbl_IncludeDirList; + while (NextDir) + { + PrevDir = NextDir; + NextDir = NextDir->Next; + } + + if (PrevDir) + { + PrevDir->Next = NewDir; + } + else + { + Gbl_IncludeDirList = NewDir; + } +} + + +/******************************************************************************* + * + * FUNCTION: FlOpenIncludeWithPrefix + * + * PARAMETERS: PrefixDir - Prefix directory pathname. Can be a zero + * length string. + * Filename - The include filename from the source ASL. + * + * RETURN: Valid file descriptor if successful. Null otherwise. + * + * DESCRIPTION: Open an include file and push it on the input file stack. + * + ******************************************************************************/ + +FILE * +FlOpenIncludeWithPrefix ( + char *PrefixDir, + char *Filename) +{ + FILE *IncludeFile; + char *Pathname; + + + /* Build the full pathname to the file */ + + Pathname = ACPI_ALLOCATE (strlen (PrefixDir) + strlen (Filename) + 1); + + strcpy (Pathname, PrefixDir); + strcat (Pathname, Filename); + + DbgPrint (ASL_PARSE_OUTPUT, "\nAttempt to open include file: path %s\n\n", + Pathname); + + /* Attempt to open the file, push if successful */ + + IncludeFile = fopen (Pathname, "r"); + if (IncludeFile) + { + /* Push the include file on the open input file stack */ + + AslPushInputFileStack (IncludeFile, Pathname); + return (IncludeFile); + } + + ACPI_FREE (Pathname); + return (NULL); +} + + /******************************************************************************* * * FUNCTION: FlOpenIncludeFile @@ -495,7 +573,8 @@ void FlOpenIncludeFile ( ACPI_PARSE_OBJECT *Op) { - FILE *IncFile; + FILE *IncludeFile; + ASL_INCLUDE_DIR *NextDir; /* Op must be valid */ @@ -518,21 +597,58 @@ FlOpenIncludeFile ( FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n"); Gbl_CurrentLineOffset++; - /* Prepend the directory pathname and open the include file */ - DbgPrint (ASL_PARSE_OUTPUT, "\nOpen include file: path %s\n\n", - Op->Asl.Value.String); - IncFile = FlOpenLocalFile (Op->Asl.Value.String, "r"); - if (!IncFile) + /* Attempt to open the include file */ + + /* If the file specifies an absolute path, just open it */ + + if ((Op->Asl.Value.String[0] == '/') || + (Op->Asl.Value.String[0] == '\\') || + (Op->Asl.Value.String[1] == ':')) { - sprintf (MsgBuffer, "%s (%s)", Op->Asl.Value.String, strerror (errno)); - AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, MsgBuffer); + IncludeFile = FlOpenIncludeWithPrefix ("", Op->Asl.Value.String); + if (!IncludeFile) + { + goto ErrorExit; + } return; } - /* Push the include file on the open input file stack */ + /* + * The include filename is not an absolute path. + * + * First, search for the file within the "local" directory -- meaning + * the same directory that contains the source file. + * + * Construct the file pathname from the global directory name. + */ + IncludeFile = FlOpenIncludeWithPrefix (Gbl_DirectoryPath, Op->Asl.Value.String); + if (IncludeFile) + { + return; + } - AslPushInputFileStack (IncFile, Op->Asl.Value.String); + /* + * Second, search for the file within the (possibly multiple) directories + * specified by the -I option on the command line. + */ + NextDir = Gbl_IncludeDirList; + while (NextDir) + { + IncludeFile = FlOpenIncludeWithPrefix (NextDir->Dir, Op->Asl.Value.String); + if (IncludeFile) + { + return; + } + + NextDir = NextDir->Next; + } + + /* We could not open the include file after trying very hard */ + +ErrorExit: + sprintf (MsgBuffer, "%s, %s", Op->Asl.Value.String, strerror (errno)); + AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, MsgBuffer); } diff --git a/sys/contrib/dev/acpica/compiler/aslfold.c b/sys/contrib/dev/acpica/compiler/aslfold.c index d250c332b6c..9b5efa8aa5e 100644 --- a/sys/contrib/dev/acpica/compiler/aslfold.c +++ b/sys/contrib/dev/acpica/compiler/aslfold.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/compiler/aslglobal.h b/sys/contrib/dev/acpica/compiler/aslglobal.h index 4cb91216fbb..69fcf8438a1 100644 --- a/sys/contrib/dev/acpica/compiler/aslglobal.h +++ b/sys/contrib/dev/acpica/compiler/aslglobal.h @@ -10,7 +10,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -148,7 +148,7 @@ extern char HexLookup[]; #define ASL_LINE_BUFFER_SIZE 512 #define ASL_MSG_BUFFER_SIZE 4096 #define HEX_TABLE_LINE_SIZE 8 -#define HEX_LISTING_LINE_SIZE 16 +#define HEX_LISTING_LINE_SIZE 8 /* Source code buffers and pointers for error reporting */ @@ -165,7 +165,6 @@ ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_LineBufPtr, Gbl_Curren ASL_EXTERN ASL_ERROR_MSG ASL_INIT_GLOBAL (*Gbl_ErrorLog,NULL); ASL_EXTERN ASL_ERROR_MSG ASL_INIT_GLOBAL (*Gbl_NextError,NULL); -extern UINT32 Gbl_ExceptionCount[]; /* Option flags */ @@ -212,6 +211,7 @@ ASL_EXTERN char *Gbl_DirectoryPath; ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_ExternalFilename, NULL); ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_IncludeFilename, NULL); ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_OutputFilenamePrefix, NULL); +ASL_EXTERN ASL_INCLUDE_DIR ASL_INIT_GLOBAL (*Gbl_IncludeDirList, NULL); ASL_EXTERN char *Gbl_CurrentInputFilename; ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_HasIncludeFiles, FALSE); @@ -277,5 +277,12 @@ ASL_EXTERN char MsgBuffer[ASL_MSG_BUFFER_SIZE]; ASL_EXTERN char StringBuffer[ASL_MSG_BUFFER_SIZE]; ASL_EXTERN char StringBuffer2[ASL_MSG_BUFFER_SIZE]; + +#ifdef _DECLARE_GLOBALS +UINT32 Gbl_ExceptionCount[ASL_NUM_REPORT_LEVELS] = {0,0,0,0,0,0}; +#else +extern UINT32 Gbl_ExceptionCount[ASL_NUM_REPORT_LEVELS]; +#endif + #endif /* __ASLGLOBAL_H */ diff --git a/sys/contrib/dev/acpica/compiler/asllength.c b/sys/contrib/dev/acpica/compiler/asllength.c index 75361dc2a0d..d17bab97eab 100644 --- a/sys/contrib/dev/acpica/compiler/asllength.c +++ b/sys/contrib/dev/acpica/compiler/asllength.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/compiler/asllisting.c b/sys/contrib/dev/acpica/compiler/asllisting.c index ff1e2baf421..ebac9ca4996 100644 --- a/sys/contrib/dev/acpica/compiler/asllisting.c +++ b/sys/contrib/dev/acpica/compiler/asllisting.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/compiler/aslload.c b/sys/contrib/dev/acpica/compiler/aslload.c index 25bb4fc8d6a..980b69b8c62 100644 --- a/sys/contrib/dev/acpica/compiler/aslload.c +++ b/sys/contrib/dev/acpica/compiler/aslload.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -353,6 +353,7 @@ LdLoadResourceElements ( Node->Value = (UINT32) Op->Asl.Value.Integer; Node->Op = Op; + Op->Asl.Node = Node; /* * Now enter the predefined fields, for easy lookup when referenced @@ -533,7 +534,7 @@ LdNamespace1Begin ( if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC) { Status = LdLoadResourceElements (Op, WalkState); - goto Exit; + return_ACPI_STATUS (Status); } ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); @@ -574,8 +575,10 @@ LdNamespace1Begin ( goto FinishNode; } - AslCoreSubsystemError (Op, Status, "Failure from lookup\n", FALSE); - goto Exit; + AslCoreSubsystemError (Op, Status, + "Failure from namespace lookup", FALSE); + + return_ACPI_STATUS (Status); } /* We found a node with this name, now check the type */ @@ -710,15 +713,14 @@ LdNamespace1Begin ( AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, Op->Asl.ExternalName); - Status = AE_OK; - goto Exit; + return_ACPI_STATUS (AE_OK); } } else { AslCoreSubsystemError (Op, Status, - "Failure from lookup %s\n", FALSE); - goto Exit; + "Failure from namespace lookup", FALSE); + return_ACPI_STATUS (Status); } } @@ -756,8 +758,7 @@ FinishNode: Node->Value = (UINT32) Op->Asl.Extra; } -Exit: - return (Status); + return_ACPI_STATUS (Status); } @@ -884,7 +885,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/sys/contrib/dev/acpica/compiler/asllookup.c b/sys/contrib/dev/acpica/compiler/asllookup.c index 3aa1e8c6c95..1f9fb4c3cb9 100644 --- a/sys/contrib/dev/acpica/compiler/asllookup.c +++ b/sys/contrib/dev/acpica/compiler/asllookup.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -526,7 +526,7 @@ LsDisplayNamespace ( /* Walk entire namespace from the root */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, + ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL, NULL, NULL); /* Print the full pathname for each namespace node */ @@ -534,7 +534,7 @@ LsDisplayNamespace ( FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n"); Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, LsDoOnePathname, + ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL, NULL, NULL); return (Status); @@ -598,7 +598,7 @@ LkObjectExists ( /* Walk entire namespace from the supplied root */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, + ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL, Name, NULL); if (Status == AE_CTRL_TRUE) { @@ -753,7 +753,7 @@ LkFindUnreferencedObjects ( /* Walk entire namespace from the supplied root */ (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, + ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL, NULL, NULL); } @@ -1337,6 +1337,7 @@ LkNamespaceLocateBegin ( break; case REGION_SMBUS: + case REGION_IPMI: if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER) { diff --git a/sys/contrib/dev/acpica/compiler/aslmain.c b/sys/contrib/dev/acpica/compiler/aslmain.c index c635bcdccc3..9b9e9568543 100644 --- a/sys/contrib/dev/acpica/compiler/aslmain.c +++ b/sys/contrib/dev/acpica/compiler/aslmain.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -150,6 +150,25 @@ AslCommandLine ( int argc, char **argv); +static int +AslDoOptions ( + int argc, + char **argv, + BOOLEAN IsResponseFile); + +static void +AslMergeOptionTokens ( + char *InBuffer, + char *OutBuffer); + +static int +AslDoResponseFile ( + char *Filename); + + +#define ASL_TOKEN_SEPARATORS " \t\n" +#define ASL_SUPPORTED_OPTIONS "@:2b:cd^e:fgh^i^I:l^o:p:r:s:t:v:w:x:" + /******************************************************************************* * @@ -168,8 +187,12 @@ Options ( void) { - printf ("General Output:\n"); - printf (" -p Specify path/filename prefix for all output files\n"); + printf ("Global:\n"); + printf (" -@ Specify command file\n"); + printf (" -I Specify additional include directory\n"); + + printf ("\nGeneral Output:\n"); + printf (" -p Specify path/filename prefix for all output files\n"); printf (" -va Disable all errors and warnings (summary only)\n"); printf (" -vi Less verbose errors and warnings for use with IDEs\n"); printf (" -vo Enable optimization comments\n"); @@ -310,39 +333,149 @@ AslInitialize ( /******************************************************************************* * - * FUNCTION: AslCommandLine + * FUNCTION: AslMergeOptionTokens * - * PARAMETERS: argc/argv + * PARAMETERS: InBuffer - Input containing an option string + * OutBuffer - Merged output buffer * * RETURN: None * - * DESCRIPTION: Command line processing + * DESCRIPTION: Remove all whitespace from an option string. + * + ******************************************************************************/ + +static void +AslMergeOptionTokens ( + char *InBuffer, + char *OutBuffer) +{ + char *Token; + + + *OutBuffer = 0; + + Token = strtok (InBuffer, ASL_TOKEN_SEPARATORS); + while (Token) + { + strcat (OutBuffer, Token); + Token = strtok (NULL, ASL_TOKEN_SEPARATORS); + } +} + + +/******************************************************************************* + * + * FUNCTION: AslDoResponseFile + * + * PARAMETERS: Filename - Name of the response file + * + * RETURN: Status + * + * DESCRIPTION: Open a response file and process all options within. * ******************************************************************************/ static int -AslCommandLine ( - int argc, - char **argv) +AslDoResponseFile ( + char *Filename) +{ + char *argv = StringBuffer2; + FILE *ResponseFile; + int OptStatus = 0; + int Opterr; + int Optind; + + + ResponseFile = fopen (Filename, "r"); + if (!ResponseFile) + { + printf ("Could not open command file %s, %s\n", + Filename, strerror (errno)); + return -1; + } + + /* Must save the current GetOpt globals */ + + Opterr = AcpiGbl_Opterr; + Optind = AcpiGbl_Optind; + + /* + * Process all lines in the response file. There must be one complete + * option per line + */ + while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ResponseFile)) + { + /* Compress all tokens, allowing us to use a single argv entry */ + + AslMergeOptionTokens (StringBuffer, StringBuffer2); + + /* Process the option */ + + AcpiGbl_Opterr = 0; + AcpiGbl_Optind = 0; + + OptStatus = AslDoOptions (1, &argv, TRUE); + if (OptStatus) + { + printf ("Invalid option in command file %s: %s\n", + Filename, StringBuffer); + break; + } + } + + /* Restore the GetOpt globals */ + + AcpiGbl_Opterr = Opterr; + AcpiGbl_Optind = Optind; + + fclose (ResponseFile); + return (OptStatus); +} + + +/******************************************************************************* + * + * FUNCTION: AslDoOptions + * + * PARAMETERS: argc/argv - Standard argc/argv + * IsResponseFile - TRUE if executing a response file. + * + * RETURN: Status + * + * DESCRIPTION: Command line option processing + * + ******************************************************************************/ + +static int +AslDoOptions ( + int argc, + char **argv, + BOOLEAN IsResponseFile) { - BOOLEAN BadCommandLine = FALSE; int j; - /* Minimum command line contains at least one option or an input file */ - - if (argc < 2) - { - AslCompilerSignon (ASL_FILE_STDOUT); - Usage (); - exit (1); - } - /* Get the command line options */ - while ((j = AcpiGetopt (argc, argv, "2b:cd^e:fgh^i^l^o:p:r:s:t:v:w:x:")) != EOF) switch (j) + while ((j = AcpiGetopt (argc, argv, ASL_SUPPORTED_OPTIONS)) != EOF) switch (j) { + case '@': /* Begin a response file */ + + if (IsResponseFile) + { + printf ("Nested command files are not supported\n"); + return -1; + } + + if (AslDoResponseFile (AcpiGbl_Optarg)) + { + return -1; + } + break; + + case '2': + Gbl_Acpi2 = TRUE; break; @@ -364,8 +497,7 @@ AslCommandLine ( default: printf ("Unknown option: -b%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } /* Produce debug output file */ @@ -394,8 +526,7 @@ AslCommandLine ( default: printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } Gbl_DisasmFlag = TRUE; @@ -444,12 +575,17 @@ AslCommandLine ( default: printf ("Unknown option: -h%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } break; + case 'I': /* Add an include file search directory */ + + FlAddIncludeDirectory (AcpiGbl_Optarg); + break; + + case 'i': switch (AcpiGbl_Optarg[0]) @@ -470,8 +606,7 @@ AslCommandLine ( default: printf ("Unknown option: -s%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } break; @@ -500,8 +635,7 @@ AslCommandLine ( default: printf ("Unknown option: -l%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } break; @@ -549,8 +683,7 @@ AslCommandLine ( default: printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } break; @@ -589,8 +722,7 @@ AslCommandLine ( default: printf ("Unknown option: -s%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } break; @@ -611,8 +743,7 @@ AslCommandLine ( default: printf ("Unknown option: -t%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } break; @@ -647,8 +778,7 @@ AslCommandLine ( default: printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } break; @@ -671,8 +801,7 @@ AslCommandLine ( default: printf ("Unknown option: -w%s\n", AcpiGbl_Optarg); - BadCommandLine = TRUE; - break; + return (-1); } break; @@ -685,10 +814,46 @@ AslCommandLine ( default: - BadCommandLine = TRUE; - break; + return (-1); } + return (0); +} + + +/******************************************************************************* + * + * FUNCTION: AslCommandLine + * + * PARAMETERS: argc/argv + * + * RETURN: Last argv index + * + * DESCRIPTION: Command line processing + * + ******************************************************************************/ + +static int +AslCommandLine ( + int argc, + char **argv) +{ + int BadCommandLine = 0; + + + /* Minimum command line contains at least the command and an input file */ + + if (argc < 2) + { + AslCompilerSignon (ASL_FILE_STDOUT); + Usage (); + exit (1); + } + + /* Process all command line options */ + + BadCommandLine = AslDoOptions (argc, argv, FALSE); + /* Next parameter must be the input filename */ if (!argv[AcpiGbl_Optind] && diff --git a/sys/contrib/dev/acpica/compiler/aslmap.c b/sys/contrib/dev/acpica/compiler/aslmap.c index 55d0bb9a69f..be43b229ce5 100644 --- a/sys/contrib/dev/acpica/compiler/aslmap.c +++ b/sys/contrib/dev/acpica/compiler/aslmap.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -232,7 +232,8 @@ MpDisplayReservedNames ( * * Name - The ACPI reserved name * Args - Number of arguments to the method - * Flags - Whether this method must return a value or not + * Flags - Whether this method must return a value or not. Or if the + * name is a resource descriptor label. * ******************************************************************************/ @@ -264,24 +265,30 @@ const ASL_RESERVED_INFO ReservedMethods[] = { {"_ALP", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_ALR", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_ALT", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ + {"_ART", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_ASI", 0, ASL_RSVD_RESOURCE_NAME}, {"_ASZ", 0, ASL_RSVD_RESOURCE_NAME}, {"_BAS", 0, ASL_RSVD_RESOURCE_NAME}, {"_BBN", 0, ASL_RSVD_RETURN_VALUE}, {"_BCL", 0, ASL_RSVD_RETURN_VALUE}, {"_BCM", 1, 0}, + {"_BCT", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_BDN", 0, ASL_RSVD_RETURN_VALUE}, {"_BFS", 1, 0}, {"_BIF", 0, ASL_RSVD_RETURN_VALUE}, + {"_BIX", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_BLT", 3, 0}, /* Acpi 3.0 */ {"_BM_", 0, ASL_RSVD_RESOURCE_NAME}, + {"_BMA", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_BMC", 1, 0}, /* Acpi 3.0 */ {"_BMD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ + {"_BMS", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_BQC", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_BST", 0, ASL_RSVD_RETURN_VALUE}, {"_BTM", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_BTP", 1, 0}, {"_CBA", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ + {"_CDM", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_CID", 0, ASL_RSVD_RETURN_VALUE}, {"_CRS", 0, ASL_RSVD_RETURN_VALUE}, {"_CRT", 0, ASL_RSVD_RETURN_VALUE}, @@ -300,6 +307,7 @@ const ASL_RESERVED_INFO ReservedMethods[] = { {"_DSM", 4, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_DSS", 1, 0}, {"_DSW", 3, 0}, /* Acpi 3.0 */ + {"_DTI", 1, 0}, /* Acpi 4.0 */ {"_EC_", 0, ASL_RSVD_RETURN_VALUE}, {"_EDL", 0, ASL_RSVD_RETURN_VALUE}, {"_EJ0", 1, 0}, @@ -312,7 +320,13 @@ const ASL_RESERVED_INFO ReservedMethods[] = { {"_FDE", 0, ASL_RSVD_RETURN_VALUE}, {"_FDI", 0, ASL_RSVD_RETURN_VALUE}, {"_FDM", 1, 0}, + {"_FIF", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_FIX", 0, ASL_RSVD_RETURN_VALUE}, + {"_FPS", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ + {"_FSL", 1, 0}, /* Acpi 4.0 */ + {"_FST", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ + {"_GAI", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ + {"_GHL", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_GL_", 0, ASL_RSVD_RETURN_VALUE}, {"_GLK", 0, ASL_RSVD_RETURN_VALUE}, {"_GPD", 0, ASL_RSVD_RETURN_VALUE}, @@ -338,28 +352,39 @@ const ASL_RESERVED_INFO ReservedMethods[] = { {"_MAF", 0, ASL_RSVD_RESOURCE_NAME}, {"_MAT", 0, ASL_RSVD_RETURN_VALUE}, {"_MAX", 0, ASL_RSVD_RESOURCE_NAME}, + {"_MBM", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_MEM", 0, ASL_RSVD_RESOURCE_NAME}, {"_MIF", 0, ASL_RSVD_RESOURCE_NAME}, {"_MIN", 0, ASL_RSVD_RESOURCE_NAME}, {"_MLS", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_MSG", 1, 0}, + {"_MSM", 4, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_MTP", 0, ASL_RSVD_RESOURCE_NAME}, + {"_NTT", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_OFF", 0, 0}, {"_ON_", 0, 0}, {"_OS_", 0, ASL_RSVD_RETURN_VALUE}, {"_OSC", 4, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_OSI", 1, ASL_RSVD_RETURN_VALUE}, {"_OST", 3, 0}, /* Acpi 3.0 */ + {"_PAI", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_PCL", 0, ASL_RSVD_RETURN_VALUE}, {"_PCT", 0, ASL_RSVD_RETURN_VALUE}, {"_PDC", 1, 0}, + {"_PDL", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_PIC", 1, 0}, + {"_PIF", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_PLD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ + {"_PMC", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ + {"_PMD", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ + {"_PMM", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_PPC", 0, ASL_RSVD_RETURN_VALUE}, {"_PPE", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_PR0", 0, ASL_RSVD_RETURN_VALUE}, {"_PR1", 0, ASL_RSVD_RETURN_VALUE}, {"_PR2", 0, ASL_RSVD_RETURN_VALUE}, + {"_PR3", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ + {"_PRL", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_PRS", 0, ASL_RSVD_RETURN_VALUE}, {"_PRT", 0, ASL_RSVD_RETURN_VALUE}, {"_PRW", 0, ASL_RSVD_RETURN_VALUE}, @@ -375,7 +400,9 @@ const ASL_RESERVED_INFO ReservedMethods[] = { {"_PSV", 0, ASL_RSVD_RETURN_VALUE}, {"_PSW", 1, 0}, {"_PTC", 0, ASL_RSVD_RETURN_VALUE}, + {"_PTP", 2, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_PTS", 1, 0}, + {"_PUR", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_PXM", 0, ASL_RSVD_RETURN_VALUE}, {"_RBO", 0, ASL_RSVD_RESOURCE_NAME}, {"_RBW", 0, ASL_RSVD_RESOURCE_NAME}, @@ -407,6 +434,7 @@ const ASL_RESERVED_INFO ReservedMethods[] = { {"_SCP", 0x13, 0}, /* Acpi 1.0 - one arg; Acpi 3.0 - three args */ {"_SDD", 1, 0}, /* Acpi 3.0 */ {"_SEG", 0, ASL_RSVD_RETURN_VALUE}, + {"_SHL", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_SHR", 0, ASL_RSVD_RESOURCE_NAME}, {"_SI_", 0, ASL_RSVD_SCOPE}, {"_SIZ", 0, ASL_RSVD_RESOURCE_NAME}, @@ -417,12 +445,16 @@ const ASL_RESERVED_INFO ReservedMethods[] = { {"_SST", 1, 0}, {"_STA", 0, ASL_RSVD_RETURN_VALUE}, {"_STM", 3, 0}, + {"_STP", 2, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_STR", 0, ASL_RSVD_RETURN_VALUE}, + {"_STV", 2, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_SUN", 0, ASL_RSVD_RETURN_VALUE}, {"_SWS", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_TC1", 0, ASL_RSVD_RETURN_VALUE}, {"_TC2", 0, ASL_RSVD_RETURN_VALUE}, {"_TDL", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0b */ + {"_TIP", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ + {"_TIV", 1, ASL_RSVD_RETURN_VALUE}, /* Acpi 4.0 */ {"_TMP", 0, ASL_RSVD_RETURN_VALUE}, {"_TPC", 0, ASL_RSVD_RETURN_VALUE}, /* Acpi 3.0 */ {"_TPT", 1, 0}, /* Acpi 3.0 */ @@ -681,6 +713,7 @@ const ASL_MAPPING_ENTRY AslKeywordMapping [] = /* REGIONSPACE_CMOS */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, REGION_CMOS, 0, 0), /* REGIONSPACE_EC */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, REGION_EC, 0, 0), /* REGIONSPACE_IO */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, REGION_IO, 0, 0), +/* REGIONSPACE_IPMI */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, REGION_IPMI, 0, 0), /* REGIONSPACE_MEM */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, REGION_MEMORY, 0, 0), /* REGIONSPACE_PCI */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, REGION_PCI_CONFIG, 0, 0), /* REGIONSPACE_PCIBAR */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, REGION_PCI_BAR, 0, 0), diff --git a/sys/contrib/dev/acpica/compiler/aslopcodes.c b/sys/contrib/dev/acpica/compiler/aslopcodes.c index ba5b41c7b5d..b1a56921de3 100644 --- a/sys/contrib/dev/acpica/compiler/aslopcodes.c +++ b/sys/contrib/dev/acpica/compiler/aslopcodes.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -328,7 +328,7 @@ OpcSetOptimalIntegerSize ( } break; - case ACPI_INTEGER_MAX: + case ACPI_UINT64_MAX: /* Check for table integer width (32 or 64) */ @@ -568,7 +568,7 @@ OpcDoEisaId ( if (i < 3) { - if (!isupper (InString[i])) + if (!isupper ((int) InString[i])) { Status = AE_BAD_PARAMETER; } @@ -576,7 +576,7 @@ OpcDoEisaId ( /* Last 4 characters must be hex digits */ - else if (!isxdigit (InString[i])) + else if (!isxdigit ((int) InString[i])) { Status = AE_BAD_PARAMETER; } @@ -666,7 +666,7 @@ OpcDoUuId ( } else { - if (!isxdigit (InString[i])) + if (!isxdigit ((int) InString[i])) { Status = AE_BAD_PARAMETER; } diff --git a/sys/contrib/dev/acpica/compiler/asloperands.c b/sys/contrib/dev/acpica/compiler/asloperands.c index 4e6d3b1e9ef..772c89da699 100644 --- a/sys/contrib/dev/acpica/compiler/asloperands.c +++ b/sys/contrib/dev/acpica/compiler/asloperands.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -604,7 +604,7 @@ OpnDoRegion ( } else { - Op->Asl.Value.Integer = ACPI_INTEGER_MAX; + Op->Asl.Value.Integer = ACPI_UINT64_MAX; } } @@ -788,20 +788,30 @@ OpnDoPackage ( if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER) || (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST)) { - if (PackageLengthOp->Asl.Value.Integer >= PackageLength) + if (PackageLengthOp->Asl.Value.Integer > PackageLength) { - /* Allow package to be longer than the initializer list */ + /* + * Allow package length to be longer than the initializer + * list -- but if the length of initializer list is nonzero, + * issue a message since this is probably a coding error, + * even though technically legal. + */ + if (PackageLength > 0) + { + AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT, + PackageLengthOp, NULL); + } PackageLength = (UINT32) PackageLengthOp->Asl.Value.Integer; } - else + else if (PackageLengthOp->Asl.Value.Integer < PackageLength) { /* - * Initializer list is longer than the package length. This - * is an error as per the ACPI spec. + * The package length is smaller than the length of the + * initializer list. This is an error as per the ACPI spec. */ - AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH, - PackageLengthOp->Asl.Next, NULL); + AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG, + PackageLengthOp, NULL); } } @@ -997,7 +1007,7 @@ OpnDoDefinitionBlock ( for (i = 0; i < 4; i++) { - if (!isalnum (Gbl_TableSignature[i])) + if (!isalnum ((int) Gbl_TableSignature[i])) { AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child, "Contains non-alphanumeric characters"); diff --git a/sys/contrib/dev/acpica/compiler/aslopt.c b/sys/contrib/dev/acpica/compiler/aslopt.c index 53ae3ce1328..89c7baab141 100644 --- a/sys/contrib/dev/acpica/compiler/aslopt.c +++ b/sys/contrib/dev/acpica/compiler/aslopt.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/compiler/aslresource.c b/sys/contrib/dev/acpica/compiler/aslresource.c index 59b75c20c38..3242ba700d6 100644 --- a/sys/contrib/dev/acpica/compiler/aslresource.c +++ b/sys/contrib/dev/acpica/compiler/aslresource.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -184,7 +184,7 @@ RsCreateBitField ( { Op->Asl.ExternalName = Name; - Op->Asl.Value.Integer = ((ACPI_INTEGER) ByteOffset * 8) + BitOffset; + Op->Asl.Value.Integer = ((UINT64) ByteOffset * 8) + BitOffset; Op->Asl.CompileFlags |= (NODE_IS_RESOURCE_FIELD | NODE_IS_BIT_OFFSET); } diff --git a/sys/contrib/dev/acpica/compiler/aslrestype1.c b/sys/contrib/dev/acpica/compiler/aslrestype1.c index 0de4d6fd693..036abdf116f 100644 --- a/sys/contrib/dev/acpica/compiler/aslrestype1.c +++ b/sys/contrib/dev/acpica/compiler/aslrestype1.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/compiler/aslrestype2.c b/sys/contrib/dev/acpica/compiler/aslrestype2.c index 672c31a4d4b..48be8536600 100644 --- a/sys/contrib/dev/acpica/compiler/aslrestype2.c +++ b/sys/contrib/dev/acpica/compiler/aslrestype2.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/compiler/aslstartup.c b/sys/contrib/dev/acpica/compiler/aslstartup.c index 45ec82be2f8..bbaa6085501 100644 --- a/sys/contrib/dev/acpica/compiler/aslstartup.c +++ b/sys/contrib/dev/acpica/compiler/aslstartup.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/compiler/aslstubs.c b/sys/contrib/dev/acpica/compiler/aslstubs.c index 227b1cf1431..ebc0a7d321a 100644 --- a/sys/contrib/dev/acpica/compiler/aslstubs.c +++ b/sys/contrib/dev/acpica/compiler/aslstubs.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -119,6 +119,7 @@ #include #include #include +#include #define _COMPONENT ACPI_COMPILER ACPI_MODULE_NAME ("aslstubs") @@ -136,6 +137,12 @@ AeLocalGetRootPointer ( return 0; } +void +AcpiNsExecModuleCodeList ( + void) +{ +} + ACPI_STATUS AcpiHwReadPort ( ACPI_IO_ADDRESS Address, diff --git a/sys/contrib/dev/acpica/compiler/asltransform.c b/sys/contrib/dev/acpica/compiler/asltransform.c index ca0d4b82159..f03f1fe97f8 100644 --- a/sys/contrib/dev/acpica/compiler/asltransform.c +++ b/sys/contrib/dev/acpica/compiler/asltransform.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -468,6 +468,8 @@ TrDoSwitch ( ACPI_PARSE_OBJECT *NewOp; ACPI_PARSE_OBJECT *NewOp2; ACPI_PARSE_OBJECT *MethodOp; + ACPI_PARSE_OBJECT *StoreOp; + ACPI_PARSE_OBJECT *BreakOp; char *PredicateValueName; UINT16 Index; UINT32 Btype; @@ -552,7 +554,7 @@ TrDoSwitch ( NewOp = NewOp2; NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, - (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName)); + (UINT64) ACPI_TO_INTEGER (PredicateValueName)); NewOp->Asl.Next = NewOp2; TrAmlInitLineNumbers (NewOp2, Predicate); @@ -610,7 +612,7 @@ TrDoSwitch ( * CaseOp->Child->Peer is the beginning of the case block */ NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, - (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName)); + (UINT64) ACPI_TO_INTEGER (PredicateValueName)); NewOp->Asl.Next = Predicate; TrAmlInitLineNumbers (NewOp, Predicate); @@ -638,11 +640,7 @@ TrDoSwitch ( */ if (CurrentParentNode == StartNode) { - Conditional->Asl.Parent = CurrentParentNode->Asl.Parent; - - /* Link IF into the peer list */ - - TrAmlInsertPeer (CurrentParentNode, Conditional); + Conditional->Asl.Next = NULL; } else { @@ -695,6 +693,7 @@ TrDoSwitch ( { return; } + TrAmlInitNode (DefaultOp, PARSEOP_ELSE); DefaultOp->Asl.Parent = Conditional->Asl.Parent; @@ -762,7 +761,7 @@ TrDoSwitch ( /* Create the NameSeg child for the Name node */ NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESEG, - (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName)); + (UINT64) ACPI_TO_INTEGER (PredicateValueName)); NewOp2->Asl.CompileFlags |= NODE_IS_NAME_DECLARATION; NewOp->Asl.Child = NewOp2; @@ -772,22 +771,22 @@ TrDoSwitch ( { case ACPI_BTYPE_INTEGER: NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_ZERO, - (ACPI_INTEGER) 0); + (UINT64) 0); break; case ACPI_BTYPE_STRING: NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_STRING_LITERAL, - (ACPI_INTEGER) ACPI_TO_INTEGER ("")); + (UINT64) ACPI_TO_INTEGER ("")); break; case ACPI_BTYPE_BUFFER: (void) TrLinkPeerNode (NewOp2, TrCreateValuedLeafNode (PARSEOP_BUFFER, - (ACPI_INTEGER) 0)); + (UINT64) 0)); Next = NewOp2->Asl.Next; (void) TrLinkChildren (Next, 1, TrCreateValuedLeafNode (PARSEOP_ZERO, - (ACPI_INTEGER) 1)); + (UINT64) 1)); (void) TrLinkPeerNode (Next->Asl.Child, - TrCreateValuedLeafNode (PARSEOP_DEFAULT_ARG, (ACPI_INTEGER) 0)); + TrCreateValuedLeafNode (PARSEOP_DEFAULT_ARG, (UINT64) 0)); TrAmlSetSubtreeParent (Next->Asl.Child, Next); break; @@ -799,22 +798,44 @@ TrDoSwitch ( TrAmlSetSubtreeParent (NewOp2, NewOp); /* - * Transform the Switch() into a Store() node which will be used to save the + * Transform the Switch() into a While(One)-Break node. + * And create a Store() node which will be used to save the * Switch() value. The store is of the form: Store (Value, _T_x) * where _T_x is the temp variable. */ - TrAmlInitNode (StartNode, PARSEOP_STORE); - StartNode->Asl.Child = NULL; + TrAmlInitNode (StartNode, PARSEOP_WHILE); + NewOp = TrCreateLeafNode (PARSEOP_ONE); + NewOp->Asl.Next = Predicate->Asl.Next; + NewOp->Asl.Parent = StartNode; + StartNode->Asl.Child = NewOp; + + /* Create a Store() node */ + + StoreOp = TrCreateLeafNode (PARSEOP_STORE); + StoreOp->Asl.Parent = StartNode; + TrAmlInsertPeer (NewOp, StoreOp); /* Complete the Store subtree */ - StartNode->Asl.Child = Predicate; - Predicate->Asl.Parent = StartNode; + StoreOp->Asl.Child = Predicate; + Predicate->Asl.Parent = StoreOp; NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESEG, - (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName)); - NewOp->Asl.Parent = StartNode; + (UINT64) ACPI_TO_INTEGER (PredicateValueName)); + NewOp->Asl.Parent = StoreOp; Predicate->Asl.Next = NewOp; + + /* Create a Break() node and insert it into the end of While() */ + + Conditional = StartNode->Asl.Child; + while (Conditional->Asl.Next) + { + Conditional = Conditional->Asl.Next; + } + + BreakOp = TrCreateLeafNode (PARSEOP_BREAK); + BreakOp->Asl.Parent = StartNode; + TrAmlInsertPeer (Conditional, BreakOp); } diff --git a/sys/contrib/dev/acpica/compiler/asltree.c b/sys/contrib/dev/acpica/compiler/asltree.c index 7e161a770c7..438a235e43e 100644 --- a/sys/contrib/dev/acpica/compiler/asltree.c +++ b/sys/contrib/dev/acpica/compiler/asltree.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -490,7 +490,7 @@ TrCreateLeafNode ( ACPI_PARSE_OBJECT * TrCreateValuedLeafNode ( UINT32 ParseOpcode, - ACPI_INTEGER Value) + UINT64 Value) { ACPI_PARSE_OBJECT *Op; diff --git a/sys/contrib/dev/acpica/compiler/asltypes.h b/sys/contrib/dev/acpica/compiler/asltypes.h index 6b3c4243bb0..9e1d426d2b7 100644 --- a/sys/contrib/dev/acpica/compiler/asltypes.h +++ b/sys/contrib/dev/acpica/compiler/asltypes.h @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -255,6 +255,14 @@ typedef enum #define ASL_NUM_FILES (ASL_MAX_FILE_TYPE + 1) +typedef struct asl_include_dir +{ + char *Dir; + struct asl_include_dir *Next; + +} ASL_INCLUDE_DIR; + + /* An entry in the exception list, one for each error/warning */ typedef struct asl_error_msg @@ -361,7 +369,8 @@ typedef enum ASL_MSG_INVALID_TIME, ASL_MSG_INVALID_TYPE, ASL_MSG_INVALID_UUID, - ASL_MSG_LIST_LENGTH, + ASL_MSG_LIST_LENGTH_LONG, + ASL_MSG_LIST_LENGTH_SHORT, ASL_MSG_LISTING_FILE_OPEN, ASL_MSG_LISTING_FILENAME, ASL_MSG_LOCAL_INIT, @@ -480,7 +489,8 @@ char *AslMessages [] = { /* ASL_MSG_INVALID_TIME */ "Time parameter too long (255 max)", /* ASL_MSG_INVALID_TYPE */ "Invalid type", /* ASL_MSG_INVALID_UUID */ "UUID string must be of the form \"aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\"", -/* ASL_MSG_LIST_LENGTH */ "Initializer list too long", +/* ASL_MSG_LIST_LENGTH_LONG */ "Initializer list longer than declared package length", +/* ASL_MSG_LIST_LENGTH_SHORT */ "Initializer list shorter than declared package length", /* ASL_MSG_LISTING_FILE_OPEN */ "Could not open listing file", /* ASL_MSG_LISTING_FILENAME */ "Could not create listing filename", /* ASL_MSG_LOCAL_INIT */ "Method local variable is not initialized", @@ -561,11 +571,6 @@ char *AslErrorLevel [ASL_NUM_REPORT_LEVELS] = { #define ASL_ERROR_LEVEL_LENGTH 8 /* Length of strings above */ -/* Exception counters */ - -UINT32 Gbl_ExceptionCount[ASL_NUM_REPORT_LEVELS] = {0,0,0,0,0,0}; - -#endif - +#endif /* ASL_EXCEPTIONS */ #endif /* __ASLTYPES_H */ diff --git a/sys/contrib/dev/acpica/compiler/aslutils.c b/sys/contrib/dev/acpica/compiler/aslutils.c index a226a3dde18..bc315ccc9a3 100644 --- a/sys/contrib/dev/acpica/compiler/aslutils.c +++ b/sys/contrib/dev/acpica/compiler/aslutils.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -142,7 +142,7 @@ static ACPI_STATUS UtStrtoul64 ( char *String, UINT32 Base, - ACPI_INTEGER *RetInteger); + UINT64 *RetInteger); static void UtPadNameWithUnderscores ( @@ -846,12 +846,12 @@ UtAttachNamepathToOwner ( * ******************************************************************************/ -ACPI_INTEGER +UINT64 UtDoConstant ( char *String) { ACPI_STATUS Status; - ACPI_INTEGER Converted; + UINT64 Converted; char ErrBuf[64]; @@ -888,11 +888,11 @@ static ACPI_STATUS UtStrtoul64 ( char *String, UINT32 Base, - ACPI_INTEGER *RetInteger) + UINT64 *RetInteger) { UINT32 Index; UINT32 Sign; - ACPI_INTEGER ReturnValue = 0; + UINT64 ReturnValue = 0; ACPI_STATUS Status = AE_OK; @@ -916,7 +916,7 @@ UtStrtoul64 ( /* Skip over any white space in the buffer: */ - while (isspace (*String) || *String == '\t') + while (isspace ((int) *String) || *String == '\t') { ++String; } @@ -948,7 +948,7 @@ UtStrtoul64 ( { if (*String == '0') { - if (tolower (*(++String)) == 'x') + if (tolower ((int) *(++String)) == 'x') { Base = 16; ++String; @@ -975,7 +975,7 @@ UtStrtoul64 ( if (Base == 16 && *String == '0' && - tolower (*(++String)) == 'x') + tolower ((int) *(++String)) == 'x') { String++; } @@ -984,14 +984,14 @@ UtStrtoul64 ( while (*String) { - if (isdigit (*String)) + if (isdigit ((int) *String)) { Index = ((UINT8) *String) - '0'; } else { - Index = (UINT8) toupper (*String); - if (isupper ((char) Index)) + Index = (UINT8) toupper ((int) *String); + if (isupper ((int) Index)) { Index = Index - 'A' + 10; } @@ -1008,8 +1008,8 @@ UtStrtoul64 ( /* Check to see if value is out of range: */ - if (ReturnValue > ((ACPI_INTEGER_MAX - (ACPI_INTEGER) Index) / - (ACPI_INTEGER) Base)) + if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / + (UINT64) Base)) { goto ErrorExit; } diff --git a/sys/contrib/dev/acpica/debugger/dbcmds.c b/sys/contrib/dev/acpica/debugger/dbcmds.c index 0ea12a20eb7..0c704e7e386 100644 --- a/sys/contrib/dev/acpica/debugger/dbcmds.c +++ b/sys/contrib/dev/acpica/debugger/dbcmds.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -130,6 +130,7 @@ #define _COMPONENT ACPI_CA_DEBUGGER ACPI_MODULE_NAME ("dbcmds") + /* Local prototypes */ static ACPI_STATUS @@ -382,7 +383,7 @@ AcpiDbFindReferences ( /* Search all nodes in namespace */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkForReferences, (void *) ObjDesc, NULL); + AcpiDbWalkForReferences, NULL, (void *) ObjDesc, NULL); } @@ -474,7 +475,7 @@ AcpiDbCheckPredefinedNames ( /* Search all nodes in namespace */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkForPredefinedNames, (void *) &Count, NULL); + AcpiDbWalkForPredefinedNames, NULL, (void *) &Count, NULL); AcpiOsPrintf ("Found %d predefined names in the namespace\n", Count); } @@ -500,17 +501,16 @@ AcpiDbWalkForExecute ( void *Context, void **ReturnValue) { - ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; - UINT32 *Count = (UINT32 *) Context; - const ACPI_PREDEFINED_INFO *Predefined; - ACPI_BUFFER ReturnObj; - ACPI_STATUS Status; - char *Pathname; - ACPI_BUFFER Buffer; + ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; + ACPI_EXECUTE_WALK *Info = (ACPI_EXECUTE_WALK *) Context; + ACPI_BUFFER ReturnObj; + ACPI_STATUS Status; + char *Pathname; UINT32 i; ACPI_DEVICE_INFO *ObjInfo; ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; + const ACPI_PREDEFINED_INFO *Predefined; Predefined = AcpiNsCheckForPredefinedName (Node); @@ -532,8 +532,7 @@ AcpiDbWalkForExecute ( /* Get the object info for number of method parameters */ - Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; - Status = AcpiGetObjectInfo (ObjHandle, &Buffer); + Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo); if (ACPI_FAILURE (Status)) { return (Status); @@ -542,10 +541,8 @@ AcpiDbWalkForExecute ( ParamObjects.Pointer = NULL; ParamObjects.Count = 0; - ObjInfo = Buffer.Pointer; if (ObjInfo->Type == ACPI_TYPE_METHOD) { - /* Setup default parameters */ for (i = 0; i < ObjInfo->ParamCount; i++) @@ -558,12 +555,10 @@ AcpiDbWalkForExecute ( ParamObjects.Count = ObjInfo->ParamCount; } - ACPI_FREE (Buffer.Pointer); - + ACPI_FREE (ObjInfo); ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; - /* Do the actual method execution */ AcpiGbl_MethodExecuting = TRUE; @@ -572,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); } @@ -584,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, NULL, (void *) &Info, NULL); - AcpiOsPrintf ("Executed %d predefined names in the namespace\n", Count); + AcpiOsPrintf ("Executed %d predefined names in the namespace\n", Info.Count); } @@ -1150,15 +1165,13 @@ AcpiDbSetMethodData ( /* Create and initialize the new object */ - ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ObjDesc = AcpiUtCreateIntegerObject ((UINT64) Value); if (!ObjDesc) { AcpiOsPrintf ("Could not create an internal object\n"); return; } - ObjDesc->Integer.Value = Value; - /* Store the new object into the target */ switch (Type) @@ -1310,7 +1323,7 @@ AcpiDbDisplayObjects ( /* Walk the namespace from the root */ (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkForSpecificObjects, (void *) &Info, NULL); + AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL); AcpiOsPrintf ( "\nFound %u objects of type [%s] in the current ACPI Namespace\n", @@ -1426,7 +1439,7 @@ AcpiDbFindNameInNamespace ( /* Walk the namespace from the root */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkAndMatchName, AcpiName, NULL); + AcpiDbWalkAndMatchName, NULL, AcpiName, NULL); AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); return (AE_OK); @@ -1927,7 +1940,7 @@ AcpiDbCheckIntegrity ( /* Search all nodes in namespace */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbIntegrityWalk, (void *) &Info, NULL); + AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL); AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n", Info.Nodes, Info.Objects); @@ -1997,12 +2010,17 @@ AcpiDbBusWalk ( ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; ACPI_STATUS Status; ACPI_BUFFER Buffer; - ACPI_INTEGER ADR; - ACPI_DEVICE_ID Id; - ACPI_COMPATIBLE_ID_LIST *Cid; ACPI_NAMESPACE_NODE *TempNode; + ACPI_DEVICE_INFO *Info; + UINT32 i; + if ((Node->Type != ACPI_TYPE_DEVICE) && + (Node->Type != ACPI_TYPE_PROCESSOR)) + { + return (AE_OK); + } + /* Exit if there is no _PRT under this device */ Status = AcpiGetHandle (Node, METHOD_NAME__PRT, @@ -2022,57 +2040,70 @@ AcpiDbBusWalk ( return (AE_OK); } + Status = AcpiGetObjectInfo (ObjHandle, &Info); + if (ACPI_FAILURE (Status)) + { + return (AE_OK); + } + /* Display the full path */ - AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer); + AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type); ACPI_FREE (Buffer.Pointer); + if (Info->Flags & ACPI_PCI_ROOT_BRIDGE) + { + AcpiOsPrintf (" - Is PCI Root Bridge"); + } + AcpiOsPrintf ("\n"); + /* _PRT info */ - AcpiOsPrintf ("_PRT=%p", TempNode); + AcpiOsPrintf ("_PRT: %p\n", TempNode); - /* Get the _ADR value */ + /* Dump _ADR, _HID, _UID, _CID */ - Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR); - if (ACPI_FAILURE (Status)) + if (Info->Valid & ACPI_VALID_ADR) { - AcpiOsPrintf (" No _ADR "); + AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address)); } else { - AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR); + AcpiOsPrintf ("_ADR: \n"); } - /* Get the _HID if present */ - - Status = AcpiUtExecute_HID (Node, &Id); - if (ACPI_SUCCESS (Status)) + if (Info->Valid & ACPI_VALID_HID) { - AcpiOsPrintf (" _HID=%s", Id.Value); + AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String); } else { - AcpiOsPrintf (" "); + AcpiOsPrintf ("_HID: \n"); } - /* Get the _UID if present */ - - Status = AcpiUtExecute_UID (Node, &Id); - if (ACPI_SUCCESS (Status)) + if (Info->Valid & ACPI_VALID_UID) { - AcpiOsPrintf (" _UID=%s", Id.Value); + AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String); } - - /* Get the _CID if present */ - - Status = AcpiUtExecute_CID (Node, &Cid); - if (ACPI_SUCCESS (Status)) + else { - AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value); - ACPI_FREE (Cid); + AcpiOsPrintf ("_UID: \n"); } - AcpiOsPrintf ("\n"); + if (Info->Valid & ACPI_VALID_CID) + { + for (i = 0; i < Info->CompatibleIdList.Count; i++) + { + AcpiOsPrintf ("_CID: %s\n", + Info->CompatibleIdList.Ids[i].String); + } + } + else + { + AcpiOsPrintf ("_CID: \n"); + } + + ACPI_FREE (Info); return (AE_OK); } @@ -2095,8 +2126,8 @@ AcpiDbGetBusInfo ( { /* Search all nodes in namespace */ - (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbBusWalk, NULL, NULL); + (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + AcpiDbBusWalk, NULL, NULL, NULL); } #endif /* ACPI_DEBUGGER */ diff --git a/sys/contrib/dev/acpica/debugger/dbdisply.c b/sys/contrib/dev/acpica/debugger/dbdisply.c index 13ae52843b3..179f6f66de9 100644 --- a/sys/contrib/dev/acpica/debugger/dbdisply.c +++ b/sys/contrib/dev/acpica/debugger/dbdisply.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -682,42 +682,52 @@ AcpiDbDisplayObjectType ( char *ObjectArg) { ACPI_HANDLE Handle; - ACPI_BUFFER Buffer; ACPI_DEVICE_INFO *Info; ACPI_STATUS Status; UINT32 i; Handle = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16)); - Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; - Status = AcpiGetObjectInfo (Handle, &Buffer); - if (ACPI_SUCCESS (Status)) + Status = AcpiGetObjectInfo (Handle, &Info); + if (ACPI_FAILURE (Status)) { - Info = Buffer.Pointer; - AcpiOsPrintf ( - "S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X HID: %s, ADR: %8.8X%8.8X, Status %8.8X\n", - Info->HighestDstates[0], Info->HighestDstates[1], - Info->HighestDstates[2], Info->HighestDstates[3], - Info->HardwareId.Value, - ACPI_FORMAT_UINT64 (Info->Address), - Info->CurrentStatus); + AcpiOsPrintf ("Could not get object info, %s\n", + AcpiFormatException (Status)); + return; + } - if (Info->Valid & ACPI_VALID_CID) + AcpiOsPrintf ("ADR: %8.8X%8.8X, STA: %8.8X, Flags: %X\n", + ACPI_FORMAT_UINT64 (Info->Address), + Info->CurrentStatus, Info->Flags); + + AcpiOsPrintf ("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n", + Info->HighestDstates[0], Info->HighestDstates[1], + Info->HighestDstates[2], Info->HighestDstates[3]); + + AcpiOsPrintf ("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n", + Info->LowestDstates[0], Info->LowestDstates[1], + Info->LowestDstates[2], Info->LowestDstates[3], + Info->LowestDstates[4]); + + if (Info->Valid & ACPI_VALID_HID) + { + AcpiOsPrintf ("HID: %s\n", Info->HardwareId.String); + } + if (Info->Valid & ACPI_VALID_UID) + { + AcpiOsPrintf ("UID: %s\n", Info->UniqueId.String); + } + if (Info->Valid & ACPI_VALID_CID) + { + for (i = 0; i < Info->CompatibleIdList.Count; i++) { - for (i = 0; i < Info->CompatibilityId.Count; i++) - { - AcpiOsPrintf ("CID #%d: %s\n", i, - Info->CompatibilityId.Id[i].Value); - } + AcpiOsPrintf ("CID %d: %s\n", i, + Info->CompatibleIdList.Ids[i].String); } + } - ACPI_FREE (Info); - } - else - { - AcpiOsPrintf ("%s\n", AcpiFormatException (Status)); - } + ACPI_FREE (Info); } diff --git a/sys/contrib/dev/acpica/debugger/dbexec.c b/sys/contrib/dev/acpica/debugger/dbexec.c index 0c0e6caa8e2..d940384b4bb 100644 --- a/sys/contrib/dev/acpica/debugger/dbexec.c +++ b/sys/contrib/dev/acpica/debugger/dbexec.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -176,7 +176,6 @@ AcpiDbExecuteMethod ( ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; ACPI_HANDLE Handle; - ACPI_BUFFER Buffer; UINT32 i; ACPI_DEVICE_INFO *ObjInfo; @@ -196,8 +195,7 @@ AcpiDbExecuteMethod ( /* Get the object info for number of method parameters */ - Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; - Status = AcpiGetObjectInfo (Handle, &Buffer); + Status = AcpiGetObjectInfo (Handle, &ObjInfo); if (ACPI_FAILURE (Status)) { return (Status); @@ -206,7 +204,6 @@ AcpiDbExecuteMethod ( ParamObjects.Pointer = NULL; ParamObjects.Count = 0; - ObjInfo = Buffer.Pointer; if (ObjInfo->Type == ACPI_TYPE_METHOD) { /* Are there arguments to the method? */ @@ -246,7 +243,7 @@ AcpiDbExecuteMethod ( default: Params[i].Type = ACPI_TYPE_INTEGER; - Params[i].Integer.Value = i * (ACPI_INTEGER) 0x1000; + Params[i].Integer.Value = i * (UINT64) 0x1000; break; } } @@ -256,7 +253,7 @@ AcpiDbExecuteMethod ( } } - ACPI_FREE (Buffer.Pointer); + ACPI_FREE (ObjInfo); /* Prepare for a return object of arbitrary size */ @@ -456,7 +453,7 @@ AcpiDbExecute ( if (*Name == '*') { (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL); + ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL); return; } else @@ -487,7 +484,7 @@ AcpiDbExecute ( * Allow any handlers in separate threads to complete. * (Such as Notify handlers invoked from AML executed above). */ - AcpiOsSleep ((ACPI_INTEGER) 10); + AcpiOsSleep ((UINT64) 10); #ifdef ACPI_DEBUG_OUTPUT diff --git a/sys/contrib/dev/acpica/debugger/dbfileio.c b/sys/contrib/dev/acpica/debugger/dbfileio.c index 47cf825483b..ab38a6adbee 100644 --- a/sys/contrib/dev/acpica/debugger/dbfileio.c +++ b/sys/contrib/dev/acpica/debugger/dbfileio.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -150,9 +150,6 @@ AcpiDbCheckTextModeCorruption ( UINT32 TableLength, UINT32 FileLength); -static ACPI_STATUS -AeLocalLoadTable ( - ACPI_TABLE_HEADER *TablePtr); #endif /******************************************************************************* @@ -424,7 +421,7 @@ AcpiDbReadTable ( { /* Now validate the checksum */ - Status = AcpiTbChecksum ((void *) *Table, + Status = AcpiTbVerifyChecksum ((void *) *Table, ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length); if (Status == AE_BAD_CHECKSUM) diff --git a/sys/contrib/dev/acpica/debugger/dbhistry.c b/sys/contrib/dev/acpica/debugger/dbhistry.c index 23aec92e858..44394050a16 100644 --- a/sys/contrib/dev/acpica/debugger/dbhistry.c +++ b/sys/contrib/dev/acpica/debugger/dbhistry.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/debugger/dbinput.c b/sys/contrib/dev/acpica/debugger/dbinput.c index 358600ef866..67510fabf36 100644 --- a/sys/contrib/dev/acpica/debugger/dbinput.c +++ b/sys/contrib/dev/acpica/debugger/dbinput.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -644,7 +644,7 @@ AcpiDbCommandDispatch ( break; case CMD_BATCH: - AcpiDbBatchExecute (); + AcpiDbBatchExecute (AcpiGbl_DbArgs[1]); break; case CMD_BREAKPOINT: diff --git a/sys/contrib/dev/acpica/debugger/dbstats.c b/sys/contrib/dev/acpica/debugger/dbstats.c index 688d5b31255..da5f6c0afc9 100644 --- a/sys/contrib/dev/acpica/debugger/dbstats.c +++ b/sys/contrib/dev/acpica/debugger/dbstats.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -446,7 +446,7 @@ AcpiDbCountNamespaceObjects ( } (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL); + ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL, NULL); } diff --git a/sys/contrib/dev/acpica/debugger/dbutils.c b/sys/contrib/dev/acpica/debugger/dbutils.c index f394876a7b1..ab66d42e368 100644 --- a/sys/contrib/dev/acpica/debugger/dbutils.c +++ b/sys/contrib/dev/acpica/debugger/dbutils.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -275,6 +275,10 @@ AcpiDbDumpExternalObject ( AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length); if (ObjDesc->Buffer.Length) { + if (ObjDesc->Buffer.Length > 16) + { + AcpiOsPrintf ("\n"); + } AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer), ObjDesc->Buffer.Length, DB_DWORD_DISPLAY, _COMPONENT); } diff --git a/sys/contrib/dev/acpica/debugger/dbxface.c b/sys/contrib/dev/acpica/debugger/dbxface.c index 71ef17124a0..b0162c2dd2a 100644 --- a/sys/contrib/dev/acpica/debugger/dbxface.c +++ b/sys/contrib/dev/acpica/debugger/dbxface.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/disassembler/dmbuffer.c b/sys/contrib/dev/acpica/disassembler/dmbuffer.c index 02a8465e361..a408355376f 100644 --- a/sys/contrib/dev/acpica/disassembler/dmbuffer.c +++ b/sys/contrib/dev/acpica/disassembler/dmbuffer.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/disassembler/dmnames.c b/sys/contrib/dev/acpica/disassembler/dmnames.c index c095d811fbe..f210fe017f5 100644 --- a/sys/contrib/dev/acpica/disassembler/dmnames.c +++ b/sys/contrib/dev/acpica/disassembler/dmnames.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/disassembler/dmobject.c b/sys/contrib/dev/acpica/disassembler/dmobject.c index affae381eb2..1bfeadd5f8b 100644 --- a/sys/contrib/dev/acpica/disassembler/dmobject.c +++ b/sys/contrib/dev/acpica/disassembler/dmobject.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/disassembler/dmopcode.c b/sys/contrib/dev/acpica/disassembler/dmopcode.c index d1781a1a577..57dfa95833e 100644 --- a/sys/contrib/dev/acpica/disassembler/dmopcode.c +++ b/sys/contrib/dev/acpica/disassembler/dmopcode.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -473,8 +473,8 @@ AcpiDmDisassembleOneOp ( case AML_QWORD_OP: - AcpiOsPrintf ("0x%8.8X%8.8X", Op->Common.Value.Integer64.Hi, - Op->Common.Value.Integer64.Lo); + AcpiOsPrintf ("0x%8.8X%8.8X", + ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); break; diff --git a/sys/contrib/dev/acpica/disassembler/dmresrc.c b/sys/contrib/dev/acpica/disassembler/dmresrc.c index 4293c00babc..ed3b1c105ae 100644 --- a/sys/contrib/dev/acpica/disassembler/dmresrc.c +++ b/sys/contrib/dev/acpica/disassembler/dmresrc.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/disassembler/dmresrcl.c b/sys/contrib/dev/acpica/disassembler/dmresrcl.c index 9b07e5406de..132263b3bac 100644 --- a/sys/contrib/dev/acpica/disassembler/dmresrcl.c +++ b/sys/contrib/dev/acpica/disassembler/dmresrcl.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/disassembler/dmresrcs.c b/sys/contrib/dev/acpica/disassembler/dmresrcs.c index 8ac99745a19..798d113d685 100644 --- a/sys/contrib/dev/acpica/disassembler/dmresrcs.c +++ b/sys/contrib/dev/acpica/disassembler/dmresrcs.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/disassembler/dmutils.c b/sys/contrib/dev/acpica/disassembler/dmutils.c index 912c9286603..7bd0f450ee0 100644 --- a/sys/contrib/dev/acpica/disassembler/dmutils.c +++ b/sys/contrib/dev/acpica/disassembler/dmutils.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -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/sys/contrib/dev/acpica/disassembler/dmwalk.c b/sys/contrib/dev/acpica/disassembler/dmwalk.c index 78745b12671..bd89ddc6047 100644 --- a/sys/contrib/dev/acpica/disassembler/dmwalk.c +++ b/sys/contrib/dev/acpica/disassembler/dmwalk.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -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,69 +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 +470,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 +501,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/sys/contrib/dev/acpica/dispatcher/dsfield.c b/sys/contrib/dev/acpica/dispatcher/dsfield.c index 17d538af4b0..e33d6a865be 100644 --- a/sys/contrib/dev/acpica/dispatcher/dsfield.c +++ b/sys/contrib/dev/acpica/dispatcher/dsfield.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -211,9 +211,12 @@ AcpiDsCreateBufferField ( Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND; - /* Mark node temporary if we are executing a method */ - - if (WalkState->MethodNode) + /* + * Mark node temporary if we are executing a normal control + * method. (Don't mark if this is a module-level code method) + */ + if (WalkState->MethodNode && + !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) { Flags |= ACPI_NS_TEMPORARY; } @@ -311,7 +314,7 @@ AcpiDsGetFieldNames ( ACPI_PARSE_OBJECT *Arg) { ACPI_STATUS Status; - ACPI_INTEGER Position; + UINT64 Position; ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info); @@ -335,8 +338,8 @@ AcpiDsGetFieldNames ( { case AML_INT_RESERVEDFIELD_OP: - Position = (ACPI_INTEGER) Info->FieldBitPosition - + (ACPI_INTEGER) Arg->Common.Value.Size; + Position = (UINT64) Info->FieldBitPosition + + (UINT64) Arg->Common.Value.Size; if (Position > ACPI_UINT32_MAX) { @@ -403,8 +406,8 @@ AcpiDsGetFieldNames ( /* Keep track of bit position for the next field */ - Position = (ACPI_INTEGER) Info->FieldBitPosition - + (ACPI_INTEGER) Arg->Common.Value.Size; + Position = (UINT64) Info->FieldBitPosition + + (UINT64) Arg->Common.Value.Size; if (Position > ACPI_UINT32_MAX) { @@ -566,9 +569,12 @@ AcpiDsInitFieldObjects ( Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND; - /* Mark node(s) temporary if we are executing a method */ - - if (WalkState->MethodNode) + /* + * Mark node(s) temporary if we are executing a normal control + * method. (Don't mark if this is a module-level code method) + */ + if (WalkState->MethodNode && + !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) { Flags |= ACPI_NS_TEMPORARY; } diff --git a/sys/contrib/dev/acpica/dispatcher/dsinit.c b/sys/contrib/dev/acpica/dispatcher/dsinit.c index 54293b61e6e..79249e4ecbc 100644 --- a/sys/contrib/dev/acpica/dispatcher/dsinit.c +++ b/sys/contrib/dev/acpica/dispatcher/dsinit.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -283,7 +283,7 @@ AcpiDsInitializeObjects ( * the namespace reader lock. */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, &Info, NULL); + ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace")); diff --git a/sys/contrib/dev/acpica/dispatcher/dsmethod.c b/sys/contrib/dev/acpica/dispatcher/dsmethod.c index 41b5fcbe68c..e54bb608c80 100644 --- a/sys/contrib/dev/acpica/dispatcher/dsmethod.c +++ b/sys/contrib/dev/acpica/dispatcher/dsmethod.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -519,7 +519,7 @@ AcpiDsCallControlMethod ( if (ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY) { - Status = ObjDesc->Method.Implementation (NextWalkState); + Status = ObjDesc->Method.Extra.Implementation (NextWalkState); if (Status == AE_OK) { Status = AE_CTRL_TERMINATE; @@ -693,10 +693,15 @@ AcpiDsTerminateControlMethod ( } /* - * Delete any namespace objects created anywhere within - * the namespace by the execution of this method + * Delete any namespace objects created anywhere within the + * namespace by the execution of this method. Unless this method + * is a module-level executable code method, in which case we + * want make the objects permanent. */ - AcpiNsDeleteNamespaceByOwner (MethodDesc->Method.OwnerId); + if (!(MethodDesc->Method.Flags & AOPOBJ_MODULE_LEVEL)) + { + AcpiNsDeleteNamespaceByOwner (MethodDesc->Method.OwnerId); + } } /* Decrement the thread count on the method */ @@ -745,7 +750,10 @@ AcpiDsTerminateControlMethod ( /* No more threads, we can free the OwnerId */ - AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId); + if (!(MethodDesc->Method.Flags & AOPOBJ_MODULE_LEVEL)) + { + AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId); + } } return_VOID; diff --git a/sys/contrib/dev/acpica/dispatcher/dsmthdat.c b/sys/contrib/dev/acpica/dispatcher/dsmthdat.c index 8b936cc05a3..8d2342f5f7d 100644 --- a/sys/contrib/dev/acpica/dispatcher/dsmthdat.c +++ b/sys/contrib/dev/acpica/dispatcher/dsmthdat.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -524,13 +524,12 @@ AcpiDsMethodDataGetValue ( if (AcpiGbl_EnableInterpreterSlack) { - Object = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + Object = AcpiUtCreateIntegerObject ((UINT64) 0); if (!Object) { return_ACPI_STATUS (AE_NO_MEMORY); } - Object->Integer.Value = 0; Node->Object = Object; } @@ -548,9 +547,10 @@ AcpiDsMethodDataGetValue ( case ACPI_REFCLASS_LOCAL: - ACPI_ERROR ((AE_INFO, - "Uninitialized Local[%d] at node %p", Index, Node)); - + /* + * No error message for this case, will be trapped again later to + * detect and ignore cases of Store(LocalX,LocalX) + */ return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL); default: diff --git a/sys/contrib/dev/acpica/dispatcher/dsobject.c b/sys/contrib/dev/acpica/dispatcher/dsobject.c index 576e799a5ae..3e1c45e7037 100644 --- a/sys/contrib/dev/acpica/dispatcher/dsobject.c +++ b/sys/contrib/dev/acpica/dispatcher/dsobject.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -570,23 +570,36 @@ AcpiDsBuildInternalPackageObj ( { /* * NumElements was exhausted, but there are remaining elements in the - * PackageList. + * PackageList. Truncate the package to NumElements. * * Note: technically, this is an error, from ACPI spec: "It is an error * for NumElements to be less than the number of elements in the - * PackageList". However, for now, we just print an error message and - * no exception is returned. + * PackageList". However, we just print a message and + * no exception is returned. This provides Windows compatibility. Some + * BIOSs will alter the NumElements on the fly, creating this type + * of ill-formed package object. */ while (Arg) { + /* + * We must delete any package elements that were created earlier + * and are not going to be used because of the package truncation. + */ + if (Arg->Common.Node) + { + AcpiUtRemoveReference ( + ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node)); + Arg->Common.Node = NULL; + } + /* Find out how many elements there really are */ i++; Arg = Arg->Common.Next; } - ACPI_ERROR ((AE_INFO, - "Package List length (%X) larger than NumElements count (%X), truncated\n", + ACPI_INFO ((AE_INFO, + "Actual Package length (0x%X) is larger than NumElements field (0x%X), truncated\n", i, ElementCount)); } else if (i < ElementCount) @@ -596,7 +609,7 @@ AcpiDsBuildInternalPackageObj ( * Note: this is not an error, the package is padded out with NULLs. */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n", + "Package List length (0x%X) smaller than NumElements count (0x%X), padded with null elements\n", i, ElementCount)); } @@ -774,7 +787,7 @@ AcpiDsInitObjectFromOp ( case AML_ONES_OP: - ObjDesc->Integer.Value = ACPI_INTEGER_MAX; + ObjDesc->Integer.Value = ACPI_UINT64_MAX; /* Truncate value if we are executing from a 32-bit ACPI table */ diff --git a/sys/contrib/dev/acpica/dispatcher/dsopcode.c b/sys/contrib/dev/acpica/dispatcher/dsopcode.c index f62c5814992..b1c6dc36d98 100644 --- a/sys/contrib/dev/acpica/dispatcher/dsopcode.c +++ b/sys/contrib/dev/acpica/dispatcher/dsopcode.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/dispatcher/dsutils.c b/sys/contrib/dev/acpica/dispatcher/dsutils.c index 98f799eed96..3710da03de2 100644 --- a/sys/contrib/dev/acpica/dispatcher/dsutils.c +++ b/sys/contrib/dev/acpica/dispatcher/dsutils.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/dispatcher/dswexec.c b/sys/contrib/dev/acpica/dispatcher/dswexec.c index 187b1b840f1..cad6f5101f9 100644 --- a/sys/contrib/dev/acpica/dispatcher/dswexec.c +++ b/sys/contrib/dev/acpica/dispatcher/dswexec.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/dispatcher/dswload.c b/sys/contrib/dev/acpica/dispatcher/dswload.c index 2e8088af849..7ae09319ac2 100644 --- a/sys/contrib/dev/acpica/dispatcher/dswload.c +++ b/sys/contrib/dev/acpica/dispatcher/dswload.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -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); @@ -296,18 +296,19 @@ AcpiDsLoad1BeginOp ( case ACPI_TYPE_BUFFER: /* - * These types we will allow, but we will change the type. This - * enables some existing code of the form: + * These types we will allow, but we will change the type. + * This enables some existing code of the form: * * Name (DEB, 0) * Scope (DEB) { ... } * - * Note: silently change the type here. On the second pass, we will report - * a warning + * Note: silently change the type here. On the second pass, + * we will report a warning */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n", - Path, AcpiUtGetTypeName (Node->Type))); + "Type override - [%4.4s] had invalid type (%s) " + "for Scope operator, changed to type ANY\n", + AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type))); Node->Type = ACPI_TYPE_ANY; WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY; @@ -318,8 +319,9 @@ AcpiDsLoad1BeginOp ( /* All other types are an error */ ACPI_ERROR ((AE_INFO, - "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)", - AcpiUtGetTypeName (Node->Type), Path)); + "Invalid type (%s) for target of " + "Scope operator [%4.4s] (Cannot override)", + AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } @@ -672,20 +674,6 @@ AcpiDsLoad2BeginOp ( (WalkState->Opcode != AML_INT_NAMEPATH_OP)) || (!(WalkState->OpInfo->Flags & AML_NAMED))) { -#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE - if ((WalkState->OpInfo->Class == AML_CLASS_EXECUTE) || - (WalkState->OpInfo->Class == AML_CLASS_CONTROL)) - { - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "Begin/EXEC: %s (fl %8.8X)\n", WalkState->OpInfo->Name, - WalkState->OpInfo->Flags)); - - /* Executing a type1 or type2 opcode outside of a method */ - - Status = AcpiDsExecBeginOp (WalkState, OutOp); - return_ACPI_STATUS (Status); - } -#endif return_ACPI_STATUS (AE_OK); } @@ -746,29 +734,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); + } } /* @@ -792,15 +796,16 @@ AcpiDsLoad2BeginOp ( case ACPI_TYPE_BUFFER: /* - * These types we will allow, but we will change the type. This - * enables some existing code of the form: + * These types we will allow, but we will change the type. + * This enables some existing code of the form: * * Name (DEB, 0) * Scope (DEB) { ... } */ ACPI_WARNING ((AE_INFO, - "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)", - BufferPtr, AcpiUtGetTypeName (Node->Type))); + "Type override - [%4.4s] had invalid type (%s) " + "for Scope operator, changed to type ANY\n", + AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type))); Node->Type = ACPI_TYPE_ANY; WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY; @@ -811,8 +816,9 @@ AcpiDsLoad2BeginOp ( /* All other types are an error */ ACPI_ERROR ((AE_INFO, - "Invalid type (%s) for target of Scope operator [%4.4s]", - AcpiUtGetTypeName (Node->Type), BufferPtr)); + "Invalid type (%s) for target of " + "Scope operator [%4.4s] (Cannot override)", + AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node))); return (AE_AML_OPERAND_TYPE); } @@ -862,7 +868,12 @@ AcpiDsLoad2BeginOp ( { /* Execution mode, node cannot already exist, node is temporary */ - Flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY); + Flags |= ACPI_NS_ERROR_IF_FOUND; + + if (!(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) + { + Flags |= ACPI_NS_TEMPORARY; + } } /* Add new entry or lookup existing entry */ @@ -952,24 +963,6 @@ AcpiDsLoad2EndOp ( if (!(WalkState->OpInfo->Flags & AML_NSOBJECT)) { -#ifndef ACPI_NO_METHOD_EXECUTION -#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE - /* No namespace object. Executable opcode? */ - - if ((WalkState->OpInfo->Class == AML_CLASS_EXECUTE) || - (WalkState->OpInfo->Class == AML_CLASS_CONTROL)) - { - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "End/EXEC: %s (fl %8.8X)\n", WalkState->OpInfo->Name, - WalkState->OpInfo->Flags)); - - /* Executing a type1 or type2 opcode outside of a method */ - - Status = AcpiDsExecEndOp (WalkState); - return_ACPI_STATUS (Status); - } -#endif -#endif return_ACPI_STATUS (AE_OK); } @@ -1165,33 +1158,40 @@ AcpiDsLoad2EndOp ( } /* - * If we are executing a method, initialize the region + * The OpRegion is not fully parsed at this time. The only valid + * argument is the SpaceId. (We must save the address of the + * AML of the address and length operands) + * + * If we have a valid region, initialize it. The namespace is + * unlocked at this point. + * + * Need to unlock interpreter if it is locked (if we are running + * a control method), in order to allow _REG methods to be run + * during AcpiEvInitializeRegion. */ if (WalkState->MethodNode) { + /* + * Executing a method: initialize the region and unlock + * the interpreter + */ Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length, RegionSpace, WalkState); if (ACPI_FAILURE (Status)) { return (Status); } + + AcpiExExitInterpreter (); } - /* - * The OpRegion is not fully parsed at this time. Only valid - * argument is the SpaceId. (We must save the address of the - * AML of the address and length operands) - */ - - /* - * If we have a valid region, initialize it - * Namespace is NOT locked at this point. - * - * TBD: need to unlock interpreter if it is locked, in order - * to allow _REG methods to be run. - */ Status = AcpiEvInitializeRegion (AcpiNsGetAttachedObject (Node), FALSE); + if (WalkState->MethodNode) + { + AcpiExEnterInterpreter (); + } + if (ACPI_FAILURE (Status)) { /* diff --git a/sys/contrib/dev/acpica/dispatcher/dswscope.c b/sys/contrib/dev/acpica/dispatcher/dswscope.c index f7c1a3582bd..7a36e50a940 100644 --- a/sys/contrib/dev/acpica/dispatcher/dswscope.c +++ b/sys/contrib/dev/acpica/dispatcher/dswscope.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/dispatcher/dswstate.c b/sys/contrib/dev/acpica/dispatcher/dswstate.c index 73a0ef6540d..19bb45b3f39 100644 --- a/sys/contrib/dev/acpica/dispatcher/dswstate.c +++ b/sys/contrib/dev/acpica/dispatcher/dswstate.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/events/evevent.c b/sys/contrib/dev/acpica/events/evevent.c index 165959a8516..2c41639433c 100644 --- a/sys/contrib/dev/acpica/events/evevent.c +++ b/sys/contrib/dev/acpica/events/evevent.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/events/evgpe.c b/sys/contrib/dev/acpica/events/evgpe.c index 200fb4e2ab5..48355689fdc 100644 --- a/sys/contrib/dev/acpica/events/evgpe.c +++ b/sys/contrib/dev/acpica/events/evgpe.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -543,7 +543,7 @@ AcpiEvGpeDetect ( /* Read the Status Register */ - Status = AcpiRead (&StatusReg, &GpeRegisterInfo->StatusAddress); + Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress); if (ACPI_FAILURE (Status)) { goto UnlockAndExit; @@ -551,7 +551,7 @@ AcpiEvGpeDetect ( /* Read the Enable Register */ - Status = AcpiRead (&EnableReg, &GpeRegisterInfo->EnableAddress); + Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress); if (ACPI_FAILURE (Status)) { goto UnlockAndExit; diff --git a/sys/contrib/dev/acpica/events/evgpeblk.c b/sys/contrib/dev/acpica/events/evgpeblk.c index 6ff403b197d..fe55162cae1 100644 --- a/sys/contrib/dev/acpica/events/evgpeblk.c +++ b/sys/contrib/dev/acpica/events/evgpeblk.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -995,7 +995,7 @@ AcpiEvCreateGpeInfoBlocks ( /* Disable all GPEs within this register */ - Status = AcpiWrite (0x00, &ThisRegister->EnableAddress); + Status = AcpiHwWrite (0x00, &ThisRegister->EnableAddress); if (ACPI_FAILURE (Status)) { goto ErrorExit; @@ -1003,7 +1003,7 @@ AcpiEvCreateGpeInfoBlocks ( /* Clear any pending GPE events within this register */ - Status = AcpiWrite (0xFF, &ThisRegister->StatusAddress); + Status = AcpiHwWrite (0xFF, &ThisRegister->StatusAddress); if (ACPI_FAILURE (Status)) { goto ErrorExit; @@ -1110,7 +1110,7 @@ AcpiEvCreateGpeBlock ( Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, - AcpiEvSaveMethodInfo, GpeBlock, NULL); + AcpiEvSaveMethodInfo, NULL, GpeBlock, NULL); /* Return the new block */ @@ -1192,7 +1192,7 @@ AcpiEvInitializeGpeBlock ( Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - AcpiEvMatchPrwAndGpe, &GpeInfo, NULL); + AcpiEvMatchPrwAndGpe, NULL, &GpeInfo, NULL); } /* diff --git a/sys/contrib/dev/acpica/events/evmisc.c b/sys/contrib/dev/acpica/events/evmisc.c index b138fa0d5c4..1ee7f9d4a78 100644 --- a/sys/contrib/dev/acpica/events/evmisc.c +++ b/sys/contrib/dev/acpica/events/evmisc.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/events/evregion.c b/sys/contrib/dev/acpica/events/evregion.c index a5ffca235db..467a846e78c 100644 --- a/sys/contrib/dev/acpica/events/evregion.c +++ b/sys/contrib/dev/acpica/events/evregion.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -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); @@ -339,25 +400,21 @@ AcpiEvExecuteRegMethod ( * connection status 1 for connecting the handler, 0 for disconnecting * the handler (Passed as a parameter) */ - Args[0] = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId); if (!Args[0]) { Status = AE_NO_MEMORY; goto Cleanup1; } - Args[1] = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function); if (!Args[1]) { Status = AE_NO_MEMORY; goto Cleanup2; } - /* Setup the parameter objects */ - - Args[0]->Integer.Value = RegionObj->Region.SpaceId; - Args[1]->Integer.Value = Function; - Args[2] = NULL; + Args[2] = NULL; /* Terminate list */ /* Execute the method, no return value */ @@ -385,7 +442,7 @@ Cleanup1: * RegionOffset - Where in the region to read or write * BitWidth - Field width in bits (8, 16, 32, or 64) * Value - Pointer to in or out value, must be - * full 64-bit ACPI_INTEGER + * a full 64-bit integer * * RETURN: Status * @@ -400,7 +457,7 @@ AcpiEvAddressSpaceDispatch ( UINT32 Function, UINT32 RegionOffset, UINT32 BitWidth, - ACPI_INTEGER *Value) + UINT64 *Value) { ACPI_STATUS Status; ACPI_ADR_SPACE_HANDLER Handler; @@ -788,7 +845,7 @@ AcpiEvInstallHandler ( /* Convert and validate the device handle */ - Node = AcpiNsMapHandleToNode (ObjHandle); + Node = AcpiNsValidateHandle (ObjHandle); if (!Node) { return (AE_BAD_PARAMETER); @@ -1112,7 +1169,7 @@ AcpiEvInstallSpaceHandler ( * of the branch */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, + ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, NULL, HandlerObj, NULL); UnlockAndExit: @@ -1152,7 +1209,7 @@ AcpiEvExecuteRegMethods ( * regions of this Space ID before we can run any _REG methods) */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, + ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &SpaceId, NULL); return_ACPI_STATUS (Status); @@ -1186,7 +1243,7 @@ AcpiEvRegRun ( /* Convert and validate the device handle */ - Node = AcpiNsMapHandleToNode (ObjHandle); + Node = AcpiNsValidateHandle (ObjHandle); if (!Node) { return (AE_BAD_PARAMETER); diff --git a/sys/contrib/dev/acpica/events/evrgnini.c b/sys/contrib/dev/acpica/events/evrgnini.c index 82c96e443aa..e2b0bcfdfa7 100644 --- a/sys/contrib/dev/acpica/events/evrgnini.c +++ b/sys/contrib/dev/acpica/events/evrgnini.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -126,10 +126,6 @@ /* Local prototypes */ -static BOOLEAN -AcpiEvMatchPciRootBridge ( - char *Id); - static BOOLEAN AcpiEvIsPciRootBridge ( ACPI_NAMESPACE_NODE *Node); @@ -264,7 +260,7 @@ AcpiEvPciConfigRegionSetup ( void **RegionContext) { ACPI_STATUS Status = AE_OK; - ACPI_INTEGER PciValue; + UINT64 PciValue; ACPI_PCI_ID *PciId = *RegionContext; ACPI_OPERAND_OBJECT *HandlerObj; ACPI_NAMESPACE_NODE *ParentNode; @@ -442,42 +438,6 @@ AcpiEvPciConfigRegionSetup ( } -/******************************************************************************* - * - * FUNCTION: AcpiEvMatchPciRootBridge - * - * PARAMETERS: Id - The HID/CID in string format - * - * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge - * - * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. - * - ******************************************************************************/ - -static BOOLEAN -AcpiEvMatchPciRootBridge ( - char *Id) -{ - - /* - * Check if this is a PCI root. - * ACPI 3.0+: check for a PCI Express root also. - */ - if (!(ACPI_STRNCMP (Id, - PCI_ROOT_HID_STRING, - sizeof (PCI_ROOT_HID_STRING))) || - - !(ACPI_STRNCMP (Id, - PCI_EXPRESS_ROOT_HID_STRING, - sizeof (PCI_EXPRESS_ROOT_HID_STRING)))) - { - return (TRUE); - } - - return (FALSE); -} - - /******************************************************************************* * * FUNCTION: AcpiEvIsPciRootBridge @@ -496,9 +456,10 @@ AcpiEvIsPciRootBridge ( ACPI_NAMESPACE_NODE *Node) { ACPI_STATUS Status; - ACPI_DEVICE_ID Hid; - ACPI_COMPATIBLE_ID_LIST *Cid; + ACPI_DEVICE_ID *Hid; + ACPI_DEVICE_ID_LIST *Cid; UINT32 i; + BOOLEAN Match; /* Get the _HID and check for a PCI Root Bridge */ @@ -509,7 +470,10 @@ AcpiEvIsPciRootBridge ( return (FALSE); } - if (AcpiEvMatchPciRootBridge (Hid.Value)) + Match = AcpiUtIsPciRootBridge (Hid->String); + ACPI_FREE (Hid); + + if (Match) { return (TRUE); } @@ -526,7 +490,7 @@ AcpiEvIsPciRootBridge ( for (i = 0; i < Cid->Count; i++) { - if (AcpiEvMatchPciRootBridge (Cid->Id[i].Value)) + if (AcpiUtIsPciRootBridge (Cid->Ids[i].String)) { ACPI_FREE (Cid); return (TRUE); @@ -752,6 +716,20 @@ AcpiEvInitializeRegion ( HandlerObj = ObjDesc->ThermalZone.Handler; break; + case ACPI_TYPE_METHOD: + /* + * If we are executing module level code, the original + * Node's object was replaced by this Method object and we + * saved the handler in the method object. + * + * See AcpiNsExecModuleCode + */ + if (ObjDesc->Method.Flags & AOPOBJ_MODULE_LEVEL) + { + HandlerObj = ObjDesc->Method.Extra.Handler; + } + break; + default: /* Ignore other objects */ break; diff --git a/sys/contrib/dev/acpica/events/evsci.c b/sys/contrib/dev/acpica/events/evsci.c index 49639efd61b..c358a48ffa3 100644 --- a/sys/contrib/dev/acpica/events/evsci.c +++ b/sys/contrib/dev/acpica/events/evsci.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/events/evxface.c b/sys/contrib/dev/acpica/events/evxface.c index 5ecf4a76fea..abffad6536e 100644 --- a/sys/contrib/dev/acpica/events/evxface.c +++ b/sys/contrib/dev/acpica/events/evxface.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -368,7 +368,7 @@ AcpiInstallNotifyHandler ( /* Convert and validate the device handle */ - Node = AcpiNsMapHandleToNode (Device); + Node = AcpiNsValidateHandle (Device); if (!Node) { Status = AE_BAD_PARAMETER; @@ -555,7 +555,7 @@ AcpiRemoveNotifyHandler ( /* Convert and validate the device handle */ - Node = AcpiNsMapHandleToNode (Device); + Node = AcpiNsValidateHandle (Device); if (!Node) { Status = AE_BAD_PARAMETER; diff --git a/sys/contrib/dev/acpica/events/evxfevnt.c b/sys/contrib/dev/acpica/events/evxfevnt.c index a583dacdac0..92b6d4d69db 100644 --- a/sys/contrib/dev/acpica/events/evxfevnt.c +++ b/sys/contrib/dev/acpica/events/evxfevnt.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -805,7 +805,7 @@ AcpiInstallGpeBlock ( return (Status); } - Node = AcpiNsMapHandleToNode (GpeDevice); + Node = AcpiNsValidateHandle (GpeDevice); if (!Node) { Status = AE_BAD_PARAMETER; @@ -905,7 +905,7 @@ AcpiRemoveGpeBlock ( return (Status); } - Node = AcpiNsMapHandleToNode (GpeDevice); + Node = AcpiNsValidateHandle (GpeDevice); if (!Node) { Status = AE_BAD_PARAMETER; diff --git a/sys/contrib/dev/acpica/events/evxfregn.c b/sys/contrib/dev/acpica/events/evxfregn.c index 8ec140241f2..d06c6f73db7 100644 --- a/sys/contrib/dev/acpica/events/evxfregn.c +++ b/sys/contrib/dev/acpica/events/evxfregn.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -171,7 +171,7 @@ AcpiInstallAddressSpaceHandler ( /* Convert and validate the device handle */ - Node = AcpiNsMapHandleToNode (Device); + Node = AcpiNsValidateHandle (Device); if (!Node) { Status = AE_BAD_PARAMETER; @@ -244,7 +244,7 @@ AcpiRemoveAddressSpaceHandler ( /* Convert and validate the device handle */ - Node = AcpiNsMapHandleToNode (Device); + Node = AcpiNsValidateHandle (Device); if (!Node || ((Node->Type != ACPI_TYPE_DEVICE) && (Node->Type != ACPI_TYPE_PROCESSOR) && diff --git a/sys/contrib/dev/acpica/executer/exconfig.c b/sys/contrib/dev/acpica/executer/exconfig.c index a591c4ab0d2..95b78eda3b8 100644 --- a/sys/contrib/dev/acpica/executer/exconfig.c +++ b/sys/contrib/dev/acpica/executer/exconfig.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -196,8 +196,15 @@ AcpiExAddTable ( { AcpiUtRemoveReference (ObjDesc); *DdbHandle = NULL; + return_ACPI_STATUS (Status); } + /* Execute any module-level code that was found in the table */ + + AcpiExExitInterpreter (); + AcpiNsExecModuleCodeList (); + AcpiExEnterInterpreter (); + return_ACPI_STATUS (Status); } @@ -256,15 +263,13 @@ AcpiExLoadTableOp ( /* Table not found, return an Integer=0 and AE_OK */ - DdbHandle = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + DdbHandle = AcpiUtCreateIntegerObject ((UINT64) 0); if (!DdbHandle) { return_ACPI_STATUS (AE_NO_MEMORY); } - DdbHandle->Integer.Value = 0; *ReturnDesc = DdbHandle; - return_ACPI_STATUS (AE_OK); } @@ -382,7 +387,7 @@ AcpiExRegionRead ( UINT8 *Buffer) { ACPI_STATUS Status; - ACPI_INTEGER Value; + UINT64 Value; UINT32 RegionOffset = 0; UINT32 i; @@ -605,7 +610,10 @@ AcpiExLoadOp ( Status = AcpiTbAddTable (&TableDesc, &TableIndex); if (ACPI_FAILURE (Status)) { - goto Cleanup; + /* Delete allocated table buffer */ + + AcpiTbDeleteTable (&TableDesc); + return_ACPI_STATUS (Status); } /* @@ -648,13 +656,6 @@ AcpiExLoadOp ( AcpiGbl_TableHandlerContext); } -Cleanup: - if (ACPI_FAILURE (Status)) - { - /* Delete allocated table buffer */ - - AcpiTbDeleteTable (&TableDesc); - } return_ACPI_STATUS (Status); } diff --git a/sys/contrib/dev/acpica/executer/exconvrt.c b/sys/contrib/dev/acpica/executer/exconvrt.c index b69157695c9..a67122c12d4 100644 --- a/sys/contrib/dev/acpica/executer/exconvrt.c +++ b/sys/contrib/dev/acpica/executer/exconvrt.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -129,7 +129,7 @@ static UINT32 AcpiExConvertToAscii ( - ACPI_INTEGER Integer, + UINT64 Integer, UINT16 Base, UINT8 *String, UINT8 MaxLength); @@ -158,7 +158,7 @@ AcpiExConvertToInteger ( { ACPI_OPERAND_OBJECT *ReturnDesc; UINT8 *Pointer; - ACPI_INTEGER Result; + UINT64 Result; UINT32 i; UINT32 Count; ACPI_STATUS Status; @@ -247,7 +247,7 @@ AcpiExConvertToInteger ( * Little endian is used, meaning that the first byte of the buffer * is the LSB of the integer */ - Result |= (((ACPI_INTEGER) Pointer[i]) << (i * 8)); + Result |= (((UINT64) Pointer[i]) << (i * 8)); } break; @@ -260,7 +260,7 @@ AcpiExConvertToInteger ( /* Create a new integer */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject (Result); if (!ReturnDesc) { return_ACPI_STATUS (AE_NO_MEMORY); @@ -271,7 +271,6 @@ AcpiExConvertToInteger ( /* Save the Result */ - ReturnDesc->Integer.Value = Result; AcpiExTruncateFor32bitTable (ReturnDesc); *ResultDesc = ReturnDesc; return_ACPI_STATUS (AE_OK); @@ -390,12 +389,12 @@ AcpiExConvertToBuffer ( static UINT32 AcpiExConvertToAscii ( - ACPI_INTEGER Integer, + UINT64 Integer, UINT16 Base, UINT8 *String, UINT8 DataWidth) { - ACPI_INTEGER Digit; + UINT64 Digit; UINT32 i; UINT32 j; UINT32 k = 0; @@ -660,7 +659,7 @@ AcpiExConvertToString ( for (i = 0; i < ObjDesc->Buffer.Length; i++) { NewBuf += AcpiExConvertToAscii ( - (ACPI_INTEGER) ObjDesc->Buffer.Pointer[i], Base, + (UINT64) ObjDesc->Buffer.Pointer[i], Base, NewBuf, 1); *NewBuf++ = Separator; /* each separated by a comma or space */ } diff --git a/sys/contrib/dev/acpica/executer/excreate.c b/sys/contrib/dev/acpica/executer/excreate.c index 1466fdbb12d..f6c2700e0d0 100644 --- a/sys/contrib/dev/acpica/executer/excreate.c +++ b/sys/contrib/dev/acpica/executer/excreate.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/executer/exdump.c b/sys/contrib/dev/acpica/executer/exdump.c index 655a4998638..870eb07253f 100644 --- a/sys/contrib/dev/acpica/executer/exdump.c +++ b/sys/contrib/dev/acpica/executer/exdump.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/executer/exfield.c b/sys/contrib/dev/acpica/executer/exfield.c index 62e65195ec4..0e06eefa74d 100644 --- a/sys/contrib/dev/acpica/executer/exfield.c +++ b/sys/contrib/dev/acpica/executer/exfield.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -151,6 +151,7 @@ AcpiExReadDataFromField ( ACPI_OPERAND_OBJECT *BufferDesc; ACPI_SIZE Length; void *Buffer; + UINT32 Function; ACPI_FUNCTION_TRACE_PTR (ExReadDataFromField, ObjDesc); @@ -183,13 +184,27 @@ AcpiExReadDataFromField ( } } else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && - (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS)) + (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS || + ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI)) { /* - * This is an SMBus read. We must create a buffer to hold the data - * and directly access the region handler. + * This is an SMBus or IPMI read. We must create a buffer to hold + * the data and then directly access the region handler. + * + * Note: Smbus protocol value is passed in upper 16-bits of Function */ - BufferDesc = AcpiUtCreateBufferObject (ACPI_SMBUS_BUFFER_SIZE); + if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS) + { + Length = ACPI_SMBUS_BUFFER_SIZE; + Function = ACPI_READ | (ObjDesc->Field.Attribute << 16); + } + else /* IPMI */ + { + Length = ACPI_IPMI_BUFFER_SIZE; + Function = ACPI_READ; + } + + BufferDesc = AcpiUtCreateBufferObject (Length); if (!BufferDesc) { return_ACPI_STATUS (AE_NO_MEMORY); @@ -199,13 +214,11 @@ AcpiExReadDataFromField ( AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); - /* - * Perform the read. - * Note: Smbus protocol value is passed in upper 16-bits of Function - */ + /* Call the region handler for the read */ + Status = AcpiExAccessRegion (ObjDesc, 0, - ACPI_CAST_PTR (ACPI_INTEGER, BufferDesc->Buffer.Pointer), - ACPI_READ | (ObjDesc->Field.Attribute << 16)); + ACPI_CAST_PTR (UINT64, BufferDesc->Buffer.Pointer), + Function); AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); goto Exit; } @@ -213,7 +226,7 @@ AcpiExReadDataFromField ( /* * Allocate a buffer for the contents of the field. * - * If the field is larger than the size of an ACPI_INTEGER, create + * If the field is larger than the current integer width, create * a BUFFER to hold it. Otherwise, use an INTEGER. This allows * the use of arithmetic operators on the returned value if the * field size is equal or smaller than an Integer. @@ -236,14 +249,13 @@ AcpiExReadDataFromField ( { /* Field will fit within an Integer (normal case) */ - BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + BufferDesc = AcpiUtCreateIntegerObject ((UINT64) 0); if (!BufferDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Length = AcpiGbl_IntegerByteWidth; - BufferDesc->Integer.Value = 0; Buffer = &BufferDesc->Integer.Value; } @@ -304,6 +316,7 @@ AcpiExWriteDataToField ( UINT32 Length; void *Buffer; ACPI_OPERAND_OBJECT *BufferDesc; + UINT32 Function; ACPI_FUNCTION_TRACE_PTR (ExWriteDataToField, ObjDesc); @@ -332,40 +345,59 @@ AcpiExWriteDataToField ( } } else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && - (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS)) + (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS || + ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI)) { /* - * This is an SMBus write. We will bypass the entire field mechanism - * and handoff the buffer directly to the handler. + * This is an SMBus or IPMI write. We will bypass the entire field + * mechanism and handoff the buffer directly to the handler. For + * these address spaces, the buffer is bi-directional; on a write, + * return data is returned in the same buffer. * - * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE). + * Source must be a buffer of sufficient size: + * ACPI_SMBUS_BUFFER_SIZE or ACPI_IPMI_BUFFER_SIZE. + * + * Note: SMBus protocol type is passed in upper 16-bits of Function */ if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) { - ACPI_ERROR ((AE_INFO, "SMBus write requires Buffer, found type %s", + ACPI_ERROR ((AE_INFO, + "SMBus or IPMI write requires Buffer, found type %s", AcpiUtGetObjectTypeName (SourceDesc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - if (SourceDesc->Buffer.Length < ACPI_SMBUS_BUFFER_SIZE) + if (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS) + { + Length = ACPI_SMBUS_BUFFER_SIZE; + Function = ACPI_WRITE | (ObjDesc->Field.Attribute << 16); + } + else /* IPMI */ + { + Length = ACPI_IPMI_BUFFER_SIZE; + Function = ACPI_WRITE; + } + + if (SourceDesc->Buffer.Length < Length) { ACPI_ERROR ((AE_INFO, - "SMBus write requires Buffer of length %X, found length %X", - ACPI_SMBUS_BUFFER_SIZE, SourceDesc->Buffer.Length)); + "SMBus or IPMI write requires Buffer of length %X, found length %X", + Length, SourceDesc->Buffer.Length)); return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); } - BufferDesc = AcpiUtCreateBufferObject (ACPI_SMBUS_BUFFER_SIZE); + /* Create the bi-directional buffer */ + + BufferDesc = AcpiUtCreateBufferObject (Length); if (!BufferDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Buffer = BufferDesc->Buffer.Pointer; - ACPI_MEMCPY (Buffer, SourceDesc->Buffer.Pointer, - ACPI_SMBUS_BUFFER_SIZE); + ACPI_MEMCPY (Buffer, SourceDesc->Buffer.Pointer, Length); /* Lock entire transaction if requested */ @@ -374,11 +406,9 @@ AcpiExWriteDataToField ( /* * Perform the write (returns status and perhaps data in the * same buffer) - * Note: SMBus protocol type is passed in upper 16-bits of Function. */ Status = AcpiExAccessRegion (ObjDesc, 0, - (ACPI_INTEGER *) Buffer, - ACPI_WRITE | (ObjDesc->Field.Attribute << 16)); + (UINT64 *) Buffer, Function); AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); *ResultDesc = BufferDesc; diff --git a/sys/contrib/dev/acpica/executer/exfldio.c b/sys/contrib/dev/acpica/executer/exfldio.c index f59dd6214c3..8fbc9920adb 100644 --- a/sys/contrib/dev/acpica/executer/exfldio.c +++ b/sys/contrib/dev/acpica/executer/exfldio.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -133,13 +133,13 @@ static ACPI_STATUS AcpiExFieldDatumIo ( ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, - ACPI_INTEGER *Value, + UINT64 *Value, UINT32 ReadWrite); static BOOLEAN AcpiExRegisterOverflow ( ACPI_OPERAND_OBJECT *ObjDesc, - ACPI_INTEGER Value); + UINT64 Value); static ACPI_STATUS AcpiExSetupRegion ( @@ -202,12 +202,13 @@ AcpiExSetupRegion ( } /* - * Exit now for SMBus address space, it has a non-linear address space + * Exit now for SMBus or IPMI address space, it has a non-linear address space * and the request cannot be directly validated */ - if (RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_SMBUS) + if (RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_SMBUS || + RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_IPMI) { - /* SMBus has a non-linear address space */ + /* SMBus or IPMI has a non-linear address space */ return_ACPI_STATUS (AE_OK); } @@ -295,7 +296,7 @@ AcpiExSetupRegion ( * FieldDatumByteOffset - Byte offset of this datum within the * parent field * Value - Where to store value (must at least - * the size of ACPI_INTEGER) + * 64 bits) * Function - Read or Write flag plus other region- * dependent flags * @@ -309,7 +310,7 @@ ACPI_STATUS AcpiExAccessRegion ( ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, - ACPI_INTEGER *Value, + UINT64 *Value, UINT32 Function) { ACPI_STATUS Status; @@ -407,7 +408,7 @@ AcpiExAccessRegion ( static BOOLEAN AcpiExRegisterOverflow ( ACPI_OPERAND_OBJECT *ObjDesc, - ACPI_INTEGER Value) + UINT64 Value) { if (ObjDesc->CommonField.BitLength >= ACPI_INTEGER_BIT_SIZE) @@ -419,7 +420,7 @@ AcpiExRegisterOverflow ( return (FALSE); } - if (Value >= ((ACPI_INTEGER) 1 << ObjDesc->CommonField.BitLength)) + if (Value >= ((UINT64) 1 << ObjDesc->CommonField.BitLength)) { /* * The Value is larger than the maximum value that can fit into @@ -456,11 +457,11 @@ static ACPI_STATUS AcpiExFieldDatumIo ( ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, - ACPI_INTEGER *Value, + UINT64 *Value, UINT32 ReadWrite) { ACPI_STATUS Status; - ACPI_INTEGER LocalValue; + UINT64 LocalValue; ACPI_FUNCTION_TRACE_U32 (ExFieldDatumIo, FieldDatumByteOffset); @@ -542,7 +543,7 @@ AcpiExFieldDatumIo ( * the register */ if (AcpiExRegisterOverflow (ObjDesc->BankField.BankObj, - (ACPI_INTEGER) ObjDesc->BankField.Value)) + (UINT64) ObjDesc->BankField.Value)) { return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); } @@ -585,7 +586,7 @@ AcpiExFieldDatumIo ( * the register */ if (AcpiExRegisterOverflow (ObjDesc->IndexField.IndexObj, - (ACPI_INTEGER) ObjDesc->IndexField.Value)) + (UINT64) ObjDesc->IndexField.Value)) { return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); } @@ -614,7 +615,7 @@ AcpiExFieldDatumIo ( "Read from Data Register\n")); Status = AcpiExExtractFromField (ObjDesc->IndexField.DataObj, - Value, sizeof (ACPI_INTEGER)); + Value, sizeof (UINT64)); } else { @@ -625,7 +626,7 @@ AcpiExFieldDatumIo ( ACPI_FORMAT_UINT64 (*Value))); Status = AcpiExInsertIntoField (ObjDesc->IndexField.DataObj, - Value, sizeof (ACPI_INTEGER)); + Value, sizeof (UINT64)); } break; @@ -678,13 +679,13 @@ AcpiExFieldDatumIo ( ACPI_STATUS AcpiExWriteWithUpdateRule ( ACPI_OPERAND_OBJECT *ObjDesc, - ACPI_INTEGER Mask, - ACPI_INTEGER FieldValue, + UINT64 Mask, + UINT64 FieldValue, UINT32 FieldDatumByteOffset) { ACPI_STATUS Status = AE_OK; - ACPI_INTEGER MergedValue; - ACPI_INTEGER CurrentValue; + UINT64 MergedValue; + UINT64 CurrentValue; ACPI_FUNCTION_TRACE_U32 (ExWriteWithUpdateRule, Mask); @@ -696,7 +697,7 @@ AcpiExWriteWithUpdateRule ( /* If the mask is all ones, we don't need to worry about the update rule */ - if (Mask != ACPI_INTEGER_MAX) + if (Mask != ACPI_UINT64_MAX) { /* Decode the update rule */ @@ -786,8 +787,8 @@ AcpiExExtractFromField ( UINT32 BufferLength) { ACPI_STATUS Status; - ACPI_INTEGER RawDatum; - ACPI_INTEGER MergedDatum; + UINT64 RawDatum; + UINT64 MergedDatum; UINT32 FieldOffset = 0; UINT32 BufferOffset = 0; UINT32 BufferTailBits; @@ -916,10 +917,10 @@ AcpiExInsertIntoField ( UINT32 BufferLength) { ACPI_STATUS Status; - ACPI_INTEGER Mask; - ACPI_INTEGER WidthMask; - ACPI_INTEGER MergedDatum; - ACPI_INTEGER RawDatum = 0; + UINT64 Mask; + UINT64 WidthMask; + UINT64 MergedDatum; + UINT64 RawDatum = 0; UINT32 FieldOffset = 0; UINT32 BufferOffset = 0; UINT32 BufferTailBits; @@ -971,7 +972,7 @@ AcpiExInsertIntoField ( */ if (ObjDesc->CommonField.AccessBitWidth == ACPI_INTEGER_BIT_SIZE) { - WidthMask = ACPI_INTEGER_MAX; + WidthMask = ACPI_UINT64_MAX; } else { diff --git a/sys/contrib/dev/acpica/executer/exmisc.c b/sys/contrib/dev/acpica/executer/exmisc.c index 18699ee7072..a639afb285c 100644 --- a/sys/contrib/dev/acpica/executer/exmisc.c +++ b/sys/contrib/dev/acpica/executer/exmisc.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -508,11 +508,11 @@ Cleanup: * ******************************************************************************/ -ACPI_INTEGER +UINT64 AcpiExDoMathOp ( UINT16 Opcode, - ACPI_INTEGER Integer0, - ACPI_INTEGER Integer1) + UINT64 Integer0, + UINT64 Integer1) { ACPI_FUNCTION_ENTRY (); @@ -615,8 +615,8 @@ AcpiExDoMathOp ( ACPI_STATUS AcpiExDoLogicalNumericOp ( UINT16 Opcode, - ACPI_INTEGER Integer0, - ACPI_INTEGER Integer1, + UINT64 Integer0, + UINT64 Integer1, BOOLEAN *LogicalResult) { ACPI_STATUS Status = AE_OK; @@ -690,8 +690,8 @@ AcpiExDoLogicalOp ( BOOLEAN *LogicalResult) { ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1; - ACPI_INTEGER Integer0; - ACPI_INTEGER Integer1; + UINT64 Integer0; + UINT64 Integer1; UINT32 Length0; UINT32 Length1; ACPI_STATUS Status = AE_OK; diff --git a/sys/contrib/dev/acpica/executer/exmutex.c b/sys/contrib/dev/acpica/executer/exmutex.c index 286fceb8ae0..0bd66b35623 100644 --- a/sys/contrib/dev/acpica/executer/exmutex.c +++ b/sys/contrib/dev/acpica/executer/exmutex.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -490,6 +490,15 @@ AcpiExReleaseMutex ( return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED); } + /* Must have a valid thread ID */ + + if (!WalkState->Thread) + { + ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info", + AcpiUtGetNodeName (ObjDesc->Mutex.Node))); + return_ACPI_STATUS (AE_AML_INTERNAL); + } + /* * The Mutex is owned, but this thread must be the owner. * Special case for Global Lock, any thread can release @@ -505,15 +514,6 @@ AcpiExReleaseMutex ( return_ACPI_STATUS (AE_AML_NOT_OWNER); } - /* Must have a valid thread ID */ - - if (!WalkState->Thread) - { - ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info", - AcpiUtGetNodeName (ObjDesc->Mutex.Node))); - return_ACPI_STATUS (AE_AML_INTERNAL); - } - /* * The sync level of the mutex must be equal to the current sync level. In * other words, the current level means that at least one mutex at that diff --git a/sys/contrib/dev/acpica/executer/exnames.c b/sys/contrib/dev/acpica/executer/exnames.c index d83ca597009..7134c62d6a4 100644 --- a/sys/contrib/dev/acpica/executer/exnames.c +++ b/sys/contrib/dev/acpica/executer/exnames.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/executer/exoparg1.c b/sys/contrib/dev/acpica/executer/exoparg1.c index dd4767f236b..dff76c61b52 100644 --- a/sys/contrib/dev/acpica/executer/exoparg1.c +++ b/sys/contrib/dev/acpica/executer/exoparg1.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -183,13 +183,12 @@ AcpiExOpcode_0A_0T_1R ( /* Create a return object of type Integer */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ()); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } - ReturnDesc->Integer.Value = AcpiOsGetTimer (); break; default: /* Unknown opcode */ @@ -369,8 +368,8 @@ AcpiExOpcode_1A_1T_1R ( ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL; UINT32 Temp32; UINT32 i; - ACPI_INTEGER PowerOfTen; - ACPI_INTEGER Digit; + UINT64 PowerOfTen; + UINT64 Digit; ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R, @@ -478,7 +477,7 @@ AcpiExOpcode_1A_1T_1R ( /* Sum the digit into the result with the current power of 10 */ ReturnDesc->Integer.Value += - (((ACPI_INTEGER) Temp32) * PowerOfTen); + (((UINT64) Temp32) * PowerOfTen); /* Shift to next BCD digit */ @@ -507,7 +506,7 @@ AcpiExOpcode_1A_1T_1R ( * remainder from above */ ReturnDesc->Integer.Value |= - (((ACPI_INTEGER) Temp32) << ACPI_MUL_4 (i)); + (((UINT64) Temp32) << ACPI_MUL_4 (i)); } /* Overflow if there is any data left in Digit */ @@ -554,7 +553,7 @@ AcpiExOpcode_1A_1T_1R ( /* The object exists in the namespace, return TRUE */ - ReturnDesc->Integer.Value = ACPI_INTEGER_MAX; + ReturnDesc->Integer.Value = ACPI_UINT64_MAX; goto Cleanup; @@ -720,7 +719,7 @@ AcpiExOpcode_1A_0T_1R ( ACPI_OPERAND_OBJECT *ReturnDesc = NULL; ACPI_STATUS Status = AE_OK; UINT32 Type; - ACPI_INTEGER Value; + UINT64 Value; ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R, @@ -733,7 +732,7 @@ AcpiExOpcode_1A_0T_1R ( { case AML_LNOT_OP: /* LNot (Operand) */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0); if (!ReturnDesc) { Status = AE_NO_MEMORY; @@ -746,7 +745,7 @@ AcpiExOpcode_1A_0T_1R ( */ if (!Operand[0]->Integer.Value) { - ReturnDesc->Integer.Value = ACPI_INTEGER_MAX; + ReturnDesc->Integer.Value = ACPI_UINT64_MAX; } break; @@ -838,14 +837,12 @@ AcpiExOpcode_1A_0T_1R ( /* Allocate a descriptor to hold the type. */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } - - ReturnDesc->Integer.Value = Type; break; @@ -917,14 +914,12 @@ AcpiExOpcode_1A_0T_1R ( * Now that we have the size of the object, create a result * object to hold the value */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject (Value); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } - - ReturnDesc->Integer.Value = Value; break; @@ -1089,21 +1084,18 @@ AcpiExOpcode_1A_0T_1R ( * NOTE: index into a buffer is NOT a pointer to a * sub-buffer of the main buffer, it is only a pointer to a * single element (byte) of the buffer! + * + * Since we are returning the value of the buffer at the + * indexed location, we don't need to add an additional + * reference to the buffer itself. */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) + TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } - - /* - * Since we are returning the value of the buffer at the - * indexed location, we don't need to add an additional - * reference to the buffer itself. - */ - ReturnDesc->Integer.Value = - TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]; break; diff --git a/sys/contrib/dev/acpica/executer/exoparg2.c b/sys/contrib/dev/acpica/executer/exoparg2.c index 899388b7c36..b6e8478f22f 100644 --- a/sys/contrib/dev/acpica/executer/exoparg2.c +++ b/sys/contrib/dev/acpica/executer/exoparg2.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -383,7 +383,7 @@ AcpiExOpcode_2A_1T_1R ( { ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; ACPI_OPERAND_OBJECT *ReturnDesc = NULL; - ACPI_INTEGER Index; + UINT64 Index; ACPI_STATUS Status = AE_OK; ACPI_SIZE Length; @@ -716,7 +716,7 @@ StoreLogicalResult: */ if (LogicalResult) { - ReturnDesc->Integer.Value = ACPI_INTEGER_MAX; + ReturnDesc->Integer.Value = ACPI_UINT64_MAX; } Cleanup: diff --git a/sys/contrib/dev/acpica/executer/exoparg3.c b/sys/contrib/dev/acpica/executer/exoparg3.c index 75ffcf66ca0..c94a26d272f 100644 --- a/sys/contrib/dev/acpica/executer/exoparg3.c +++ b/sys/contrib/dev/acpica/executer/exoparg3.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -239,7 +239,7 @@ AcpiExOpcode_3A_1T_1R ( ACPI_OPERAND_OBJECT *ReturnDesc = NULL; char *Buffer = NULL; ACPI_STATUS Status = AE_OK; - ACPI_INTEGER Index; + UINT64 Index; ACPI_SIZE Length; diff --git a/sys/contrib/dev/acpica/executer/exoparg6.c b/sys/contrib/dev/acpica/executer/exoparg6.c index 5284ea6234c..d13e9f6117a 100644 --- a/sys/contrib/dev/acpica/executer/exoparg6.c +++ b/sys/contrib/dev/acpica/executer/exoparg6.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -305,7 +305,7 @@ AcpiExOpcode_6A_0T_1R ( ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; ACPI_OPERAND_OBJECT *ReturnDesc = NULL; ACPI_STATUS Status = AE_OK; - ACPI_INTEGER Index; + UINT64 Index; ACPI_OPERAND_OBJECT *ThisElement; @@ -344,8 +344,9 @@ AcpiExOpcode_6A_0T_1R ( } /* Create an integer for the return value */ + /* Default return value is ACPI_UINT64_MAX if no match found */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject (ACPI_UINT64_MAX); if (!ReturnDesc) { Status = AE_NO_MEMORY; @@ -353,10 +354,6 @@ AcpiExOpcode_6A_0T_1R ( } - /* Default return value if no match found */ - - ReturnDesc->Integer.Value = ACPI_INTEGER_MAX; - /* * Examine each element until a match is found. Both match conditions * must be satisfied for a match to occur. Within the loop, @@ -365,7 +362,7 @@ AcpiExOpcode_6A_0T_1R ( * * Upon finding a match, the loop will terminate via "break" at * the bottom. If it terminates "normally", MatchValue will be - * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no + * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no * match was found. */ for ( ; Index < Operand[0]->Package.Count; Index++) diff --git a/sys/contrib/dev/acpica/executer/exprep.c b/sys/contrib/dev/acpica/executer/exprep.c index 067d1bbaccc..b60e09cc15b 100644 --- a/sys/contrib/dev/acpica/executer/exprep.c +++ b/sys/contrib/dev/acpica/executer/exprep.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/executer/exregion.c b/sys/contrib/dev/acpica/executer/exregion.c index 73447ddf08e..3969c584bb0 100644 --- a/sys/contrib/dev/acpica/executer/exregion.c +++ b/sys/contrib/dev/acpica/executer/exregion.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -149,7 +149,7 @@ AcpiExSystemMemorySpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext) { @@ -157,7 +157,8 @@ AcpiExSystemMemorySpaceHandler ( void *LogicalAddrPtr = NULL; ACPI_MEM_SPACE_CONTEXT *MemInfo = RegionContext; UINT32 Length; - ACPI_SIZE WindowSize; + ACPI_SIZE MapLength; + ACPI_SIZE PageBoundaryMapLength; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED UINT32 Remainder; #endif @@ -197,7 +198,7 @@ AcpiExSystemMemorySpaceHandler ( * Hardware does not support non-aligned data transfers, we must verify * the request. */ - (void) AcpiUtShortDivide ((ACPI_INTEGER) Address, Length, NULL, &Remainder); + (void) AcpiUtShortDivide ((UINT64) Address, Length, NULL, &Remainder); if (Remainder != 0) { return_ACPI_STATUS (AE_AML_ALIGNMENT); @@ -210,8 +211,8 @@ AcpiExSystemMemorySpaceHandler ( * 2) Address beyond the current mapping? */ if ((Address < MemInfo->MappedPhysicalAddress) || - (((ACPI_INTEGER) Address + Length) > - ((ACPI_INTEGER) + (((UINT64) Address + Length) > + ((UINT64) MemInfo->MappedPhysicalAddress + MemInfo->MappedLength))) { /* @@ -227,26 +228,45 @@ AcpiExSystemMemorySpaceHandler ( } /* - * Don't attempt to map memory beyond the end of the region, and - * constrain the maximum mapping size to something reasonable. + * October 2009: Attempt to map from the requested address to the + * end of the region. However, we will never map more than one + * page, nor will we cross a page boundary. */ - WindowSize = (ACPI_SIZE) + MapLength = (ACPI_SIZE) ((MemInfo->Address + MemInfo->Length) - Address); - if (WindowSize > ACPI_SYSMEM_REGION_WINDOW_SIZE) + /* + * If mapping the entire remaining portion of the region will cross + * a page boundary, just map up to the page boundary, do not cross. + * On some systems, crossing a page boundary while mapping regions + * can cause warnings if the pages have different attributes + * due to resource management. + * + * This has the added benefit of constraining a single mapping to + * one page, which is similar to the original code that used a 4k + * maximum window. + */ + PageBoundaryMapLength = + ACPI_ROUND_UP (Address, ACPI_DEFAULT_PAGE_SIZE) - Address; + if (PageBoundaryMapLength == 0) { - WindowSize = ACPI_SYSMEM_REGION_WINDOW_SIZE; + PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE; + } + + if (MapLength > PageBoundaryMapLength) + { + MapLength = PageBoundaryMapLength; } /* Create a new mapping starting at the address given */ MemInfo->MappedLogicalAddress = AcpiOsMapMemory ( - (ACPI_PHYSICAL_ADDRESS) Address, WindowSize); + (ACPI_PHYSICAL_ADDRESS) Address, MapLength); if (!MemInfo->MappedLogicalAddress) { ACPI_ERROR ((AE_INFO, "Could not map memory at %8.8X%8.8X, size %X", - ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) WindowSize)); + ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) MapLength)); MemInfo->MappedLength = 0; return_ACPI_STATUS (AE_NO_MEMORY); } @@ -254,7 +274,7 @@ AcpiExSystemMemorySpaceHandler ( /* Save the physical address and mapping size */ MemInfo->MappedPhysicalAddress = Address; - MemInfo->MappedLength = WindowSize; + MemInfo->MappedLength = MapLength; } /* @@ -262,7 +282,7 @@ AcpiExSystemMemorySpaceHandler ( * access */ LogicalAddrPtr = MemInfo->MappedLogicalAddress + - ((ACPI_INTEGER) Address - (ACPI_INTEGER) MemInfo->MappedPhysicalAddress); + ((UINT64) Address - (UINT64) MemInfo->MappedPhysicalAddress); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", @@ -284,19 +304,19 @@ AcpiExSystemMemorySpaceHandler ( switch (BitWidth) { case 8: - *Value = (ACPI_INTEGER) ACPI_GET8 (LogicalAddrPtr); + *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr); break; case 16: - *Value = (ACPI_INTEGER) ACPI_GET16 (LogicalAddrPtr); + *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr); break; case 32: - *Value = (ACPI_INTEGER) ACPI_GET32 (LogicalAddrPtr); + *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr); break; case 64: - *Value = (ACPI_INTEGER) ACPI_GET64 (LogicalAddrPtr); + *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr); break; default: @@ -363,7 +383,7 @@ AcpiExSystemIoSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext) { @@ -427,7 +447,7 @@ AcpiExPciConfigSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext) { @@ -507,7 +527,7 @@ AcpiExCmosSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext) { @@ -544,7 +564,7 @@ AcpiExPciBarSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext) { @@ -581,7 +601,7 @@ AcpiExDataTableSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext) { diff --git a/sys/contrib/dev/acpica/executer/exresnte.c b/sys/contrib/dev/acpica/executer/exresnte.c index 1265d1a56ae..9a45afde900 100644 --- a/sys/contrib/dev/acpica/executer/exresnte.c +++ b/sys/contrib/dev/acpica/executer/exresnte.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/executer/exresolv.c b/sys/contrib/dev/acpica/executer/exresolv.c index df8c8021ca3..e587bd1d493 100644 --- a/sys/contrib/dev/acpica/executer/exresolv.c +++ b/sys/contrib/dev/acpica/executer/exresolv.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/executer/exresop.c b/sys/contrib/dev/acpica/executer/exresop.c index 72ca085e672..22dd558b7d1 100644 --- a/sys/contrib/dev/acpica/executer/exresop.c +++ b/sys/contrib/dev/acpica/executer/exresop.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/executer/exstore.c b/sys/contrib/dev/acpica/executer/exstore.c index a4fd02d7fba..ff9b940e5bc 100644 --- a/sys/contrib/dev/acpica/executer/exstore.c +++ b/sys/contrib/dev/acpica/executer/exstore.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/executer/exstoren.c b/sys/contrib/dev/acpica/executer/exstoren.c index c70c0acf92d..4df2a40a35b 100644 --- a/sys/contrib/dev/acpica/executer/exstoren.c +++ b/sys/contrib/dev/acpica/executer/exstoren.c @@ -10,7 +10,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/executer/exstorob.c b/sys/contrib/dev/acpica/executer/exstorob.c index 38e29b93016..3c67aa612fb 100644 --- a/sys/contrib/dev/acpica/executer/exstorob.c +++ b/sys/contrib/dev/acpica/executer/exstorob.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -150,6 +150,13 @@ AcpiExStoreBufferToBuffer ( ACPI_FUNCTION_TRACE_PTR (ExStoreBufferToBuffer, SourceDesc); + /* If Source and Target are the same, just return */ + + if (SourceDesc == TargetDesc) + { + return_ACPI_STATUS (AE_OK); + } + /* We know that SourceDesc is a buffer by now */ Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->Buffer.Pointer); @@ -248,6 +255,13 @@ AcpiExStoreStringToString ( ACPI_FUNCTION_TRACE_PTR (ExStoreStringToString, SourceDesc); + /* If Source and Target are the same, just return */ + + if (SourceDesc == TargetDesc) + { + return_ACPI_STATUS (AE_OK); + } + /* We know that SourceDesc is a string by now */ Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->String.Pointer); diff --git a/sys/contrib/dev/acpica/executer/exsystem.c b/sys/contrib/dev/acpica/executer/exsystem.c index 8ef0d0daf9f..c9f746acb36 100644 --- a/sys/contrib/dev/acpica/executer/exsystem.c +++ b/sys/contrib/dev/acpica/executer/exsystem.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -293,7 +293,7 @@ AcpiExSystemDoStall ( ACPI_STATUS AcpiExSystemDoSuspend ( - ACPI_INTEGER HowLong) + UINT64 HowLong) { ACPI_FUNCTION_ENTRY (); diff --git a/sys/contrib/dev/acpica/executer/exutils.c b/sys/contrib/dev/acpica/executer/exutils.c index 22328f89e94..d90d6ea69ac 100644 --- a/sys/contrib/dev/acpica/executer/exutils.c +++ b/sys/contrib/dev/acpica/executer/exutils.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -144,7 +144,7 @@ static UINT32 AcpiExDigitsNeeded ( - ACPI_INTEGER Value, + UINT64 Value, UINT32 Base); @@ -334,7 +334,7 @@ AcpiExTruncateFor32bitTable ( * We are running a method that exists in a 32-bit ACPI table. * Truncate the value to 32 bits by zeroing out the upper 32-bit field */ - ObjDesc->Integer.Value &= (ACPI_INTEGER) ACPI_UINT32_MAX; + ObjDesc->Integer.Value &= (UINT64) ACPI_UINT32_MAX; } } @@ -446,17 +446,17 @@ AcpiExReleaseGlobalLock ( static UINT32 AcpiExDigitsNeeded ( - ACPI_INTEGER Value, + UINT64 Value, UINT32 Base) { UINT32 NumDigits; - ACPI_INTEGER CurrentValue; + UINT64 CurrentValue; ACPI_FUNCTION_TRACE (ExDigitsNeeded); - /* ACPI_INTEGER is unsigned, so we don't worry about a '-' prefix */ + /* UINT64 is unsigned, so we don't worry about a '-' prefix */ if (Value == 0) { @@ -482,59 +482,76 @@ AcpiExDigitsNeeded ( * * FUNCTION: AcpiExEisaIdToString * - * PARAMETERS: NumericId - EISA ID to be converted + * PARAMETERS: CompressedId - EISAID to be converted * OutString - Where to put the converted string (8 bytes) * * RETURN: None * - * DESCRIPTION: Convert a numeric EISA ID to string representation + * DESCRIPTION: Convert a numeric EISAID to string representation. Return + * buffer must be large enough to hold the string. The string + * returned is always exactly of length ACPI_EISAID_STRING_SIZE + * (includes null terminator). The EISAID is always 32 bits. * ******************************************************************************/ void AcpiExEisaIdToString ( - UINT32 NumericId, - char *OutString) + char *OutString, + UINT64 CompressedId) { - UINT32 EisaId; + UINT32 SwappedId; ACPI_FUNCTION_ENTRY (); + /* The EISAID should be a 32-bit integer */ + + if (CompressedId > ACPI_UINT32_MAX) + { + ACPI_WARNING ((AE_INFO, + "Expected EISAID is larger than 32 bits: 0x%8.8X%8.8X, truncating", + ACPI_FORMAT_UINT64 (CompressedId))); + } + /* Swap ID to big-endian to get contiguous bits */ - EisaId = AcpiUtDwordByteSwap (NumericId); + SwappedId = AcpiUtDwordByteSwap ((UINT32) CompressedId); - OutString[0] = (char) ('@' + (((unsigned long) EisaId >> 26) & 0x1f)); - OutString[1] = (char) ('@' + ((EisaId >> 21) & 0x1f)); - OutString[2] = (char) ('@' + ((EisaId >> 16) & 0x1f)); - OutString[3] = AcpiUtHexToAsciiChar ((ACPI_INTEGER) EisaId, 12); - OutString[4] = AcpiUtHexToAsciiChar ((ACPI_INTEGER) EisaId, 8); - OutString[5] = AcpiUtHexToAsciiChar ((ACPI_INTEGER) EisaId, 4); - OutString[6] = AcpiUtHexToAsciiChar ((ACPI_INTEGER) EisaId, 0); + /* First 3 bytes are uppercase letters. Next 4 bytes are hexadecimal */ + + OutString[0] = (char) (0x40 + (((unsigned long) SwappedId >> 26) & 0x1F)); + OutString[1] = (char) (0x40 + ((SwappedId >> 21) & 0x1F)); + OutString[2] = (char) (0x40 + ((SwappedId >> 16) & 0x1F)); + OutString[3] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 12); + OutString[4] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 8); + OutString[5] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 4); + OutString[6] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 0); OutString[7] = 0; } /******************************************************************************* * - * FUNCTION: AcpiExUnsignedIntegerToString + * FUNCTION: AcpiExIntegerToString * - * PARAMETERS: Value - Value to be converted - * OutString - Where to put the converted string (8 bytes) + * PARAMETERS: OutString - Where to put the converted string. At least + * 21 bytes are needed to hold the largest + * possible 64-bit integer. + * Value - Value to be converted * * RETURN: None, string * - * DESCRIPTION: Convert a number to string representation. Assumes string - * buffer is large enough to hold the string. + * DESCRIPTION: Convert a 64-bit integer to decimal string representation. + * Assumes string buffer is large enough to hold the string. The + * largest string is (ACPI_MAX64_DECIMAL_DIGITS + 1). * ******************************************************************************/ void -AcpiExUnsignedIntegerToString ( - ACPI_INTEGER Value, - char *OutString) +AcpiExIntegerToString ( + char *OutString, + UINT64 Value) { UINT32 Count; UINT32 DigitsNeeded; diff --git a/sys/contrib/dev/acpica/hardware/hwacpi.c b/sys/contrib/dev/acpica/hardware/hwacpi.c index 2f30774593a..9d7b89821b7 100644 --- a/sys/contrib/dev/acpica/hardware/hwacpi.c +++ b/sys/contrib/dev/acpica/hardware/hwacpi.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/hardware/hwgpe.c b/sys/contrib/dev/acpica/hardware/hwgpe.c index 9b53da87a71..5b02856d699 100644 --- a/sys/contrib/dev/acpica/hardware/hwgpe.c +++ b/sys/contrib/dev/acpica/hardware/hwgpe.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -161,7 +161,7 @@ AcpiHwLowDisableGpe ( /* Get current value of the enable register that contains this GPE */ - Status = AcpiRead (&EnableMask, &GpeRegisterInfo->EnableAddress); + Status = AcpiHwRead (&EnableMask, &GpeRegisterInfo->EnableAddress); if (ACPI_FAILURE (Status)) { return (Status); @@ -175,7 +175,7 @@ AcpiHwLowDisableGpe ( /* Write the updated enable mask */ - Status = AcpiWrite (EnableMask, &GpeRegisterInfo->EnableAddress); + Status = AcpiHwWrite (EnableMask, &GpeRegisterInfo->EnableAddress); return (Status); } @@ -215,7 +215,7 @@ AcpiHwWriteGpeEnableReg ( /* Write the entire GPE (runtime) enable register */ - Status = AcpiWrite (GpeRegisterInfo->EnableForRun, + Status = AcpiHwWrite (GpeRegisterInfo->EnableForRun, &GpeRegisterInfo->EnableAddress); return (Status); @@ -252,7 +252,7 @@ AcpiHwClearGpe ( * Write a one to the appropriate bit in the status register to * clear this GPE. */ - Status = AcpiWrite (RegisterBit, + Status = AcpiHwWrite (RegisterBit, &GpeEventInfo->RegisterInfo->StatusAddress); return (Status); @@ -317,10 +317,10 @@ AcpiHwGetGpeStatus ( /* GPE currently active (status bit == 1)? */ - Status = AcpiRead (&InByte, &GpeRegisterInfo->StatusAddress); + Status = AcpiHwRead (&InByte, &GpeRegisterInfo->StatusAddress); if (ACPI_FAILURE (Status)) { - goto UnlockAndExit; + return (Status); } if (RegisterBit & InByte) @@ -331,10 +331,7 @@ AcpiHwGetGpeStatus ( /* Set return value */ (*EventStatus) = LocalEventStatus; - - -UnlockAndExit: - return (Status); + return (AE_OK); } @@ -367,7 +364,7 @@ AcpiHwDisableGpeBlock ( { /* Disable all GPEs in this register */ - Status = AcpiWrite (0x00, &GpeBlock->RegisterInfo[i].EnableAddress); + Status = AcpiHwWrite (0x00, &GpeBlock->RegisterInfo[i].EnableAddress); if (ACPI_FAILURE (Status)) { return (Status); @@ -407,7 +404,7 @@ AcpiHwClearGpeBlock ( { /* Clear status on all GPEs in this register */ - Status = AcpiWrite (0xFF, &GpeBlock->RegisterInfo[i].StatusAddress); + Status = AcpiHwWrite (0xFF, &GpeBlock->RegisterInfo[i].StatusAddress); if (ACPI_FAILURE (Status)) { return (Status); @@ -455,7 +452,7 @@ AcpiHwEnableRuntimeGpeBlock ( /* Enable all "runtime" GPEs in this register */ - Status = AcpiWrite (GpeBlock->RegisterInfo[i].EnableForRun, + Status = AcpiHwWrite (GpeBlock->RegisterInfo[i].EnableForRun, &GpeBlock->RegisterInfo[i].EnableAddress); if (ACPI_FAILURE (Status)) { @@ -502,7 +499,7 @@ AcpiHwEnableWakeupGpeBlock ( /* Enable all "wake" GPEs in this register */ - Status = AcpiWrite (GpeBlock->RegisterInfo[i].EnableForWake, + Status = AcpiHwWrite (GpeBlock->RegisterInfo[i].EnableForWake, &GpeBlock->RegisterInfo[i].EnableAddress); if (ACPI_FAILURE (Status)) { diff --git a/sys/contrib/dev/acpica/hardware/hwregs.c b/sys/contrib/dev/acpica/hardware/hwregs.c index bf564989385..26ee46299f4 100644 --- a/sys/contrib/dev/acpica/hardware/hwregs.c +++ b/sys/contrib/dev/acpica/hardware/hwregs.c @@ -10,7 +10,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -140,6 +140,209 @@ AcpiHwWriteMultiple ( ACPI_GENERIC_ADDRESS *RegisterB); +/****************************************************************************** + * + * FUNCTION: AcpiHwValidateRegister + * + * PARAMETERS: Reg - GAS register structure + * MaxBitWidth - Max BitWidth supported (32 or 64) + * Address - Pointer to where the gas->address + * is returned + * + * RETURN: Status + * + * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS + * pointer, Address, SpaceId, BitWidth, and BitOffset. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiHwValidateRegister ( + ACPI_GENERIC_ADDRESS *Reg, + UINT8 MaxBitWidth, + UINT64 *Address) +{ + + /* Must have a valid pointer to a GAS structure */ + + if (!Reg) + { + return (AE_BAD_PARAMETER); + } + + /* + * Copy the target address. This handles possible alignment issues. + * Address must not be null. A null address also indicates an optional + * ACPI register that is not supported, so no error message. + */ + ACPI_MOVE_64_TO_64 (Address, &Reg->Address); + if (!(*Address)) + { + return (AE_BAD_ADDRESS); + } + + /* Validate the SpaceID */ + + if ((Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && + (Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) + { + ACPI_ERROR ((AE_INFO, + "Unsupported address space: 0x%X", Reg->SpaceId)); + return (AE_SUPPORT); + } + + /* Validate the BitWidth */ + + if ((Reg->BitWidth != 8) && + (Reg->BitWidth != 16) && + (Reg->BitWidth != 32) && + (Reg->BitWidth != MaxBitWidth)) + { + ACPI_ERROR ((AE_INFO, + "Unsupported register bit width: 0x%X", Reg->BitWidth)); + return (AE_SUPPORT); + } + + /* Validate the BitOffset. Just a warning for now. */ + + if (Reg->BitOffset != 0) + { + ACPI_WARNING ((AE_INFO, + "Unsupported register bit offset: 0x%X", Reg->BitOffset)); + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiHwRead + * + * PARAMETERS: Value - Where the value is returned + * Reg - GAS register structure + * + * RETURN: Status + * + * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max + * version of AcpiRead, used internally since the overhead of + * 64-bit values is not needed. + * + * LIMITATIONS: + * BitWidth must be exactly 8, 16, or 32. + * SpaceID must be SystemMemory or SystemIO. + * BitOffset and AccessWidth are currently ignored, as there has + * not been a need to implement these. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiHwRead ( + UINT32 *Value, + ACPI_GENERIC_ADDRESS *Reg) +{ + UINT64 Address; + ACPI_STATUS Status; + + + ACPI_FUNCTION_NAME (HwRead); + + + /* Validate contents of the GAS register */ + + Status = AcpiHwValidateRegister (Reg, 32, &Address); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Initialize entire 32-bit return value to zero */ + + *Value = 0; + + /* + * Two address spaces supported: Memory or IO. PCI_Config is + * not supported here because the GAS structure is insufficient + */ + if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) + { + Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) + Address, Value, Reg->BitWidth); + } + else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ + { + Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) + Address, Value, Reg->BitWidth); + } + + ACPI_DEBUG_PRINT ((ACPI_DB_IO, + "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", + *Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address), + AcpiUtGetRegionName (Reg->SpaceId))); + + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiHwWrite + * + * PARAMETERS: Value - Value to be written + * Reg - GAS register structure + * + * RETURN: Status + * + * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max + * version of AcpiWrite, used internally since the overhead of + * 64-bit values is not needed. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiHwWrite ( + UINT32 Value, + ACPI_GENERIC_ADDRESS *Reg) +{ + UINT64 Address; + ACPI_STATUS Status; + + + ACPI_FUNCTION_NAME (HwWrite); + + + /* Validate contents of the GAS register */ + + Status = AcpiHwValidateRegister (Reg, 32, &Address); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* + * Two address spaces supported: Memory or IO. PCI_Config is + * not supported here because the GAS structure is insufficient + */ + if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) + { + Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS) + Address, Value, Reg->BitWidth); + } + else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ + { + Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) + Address, Value, Reg->BitWidth); + } + + ACPI_DEBUG_PRINT ((ACPI_DB_IO, + "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", + Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address), + AcpiUtGetRegionName (Reg->SpaceId))); + + return (Status); +} + + /******************************************************************************* * * FUNCTION: AcpiHwClearAcpiStatus @@ -245,7 +448,7 @@ AcpiHwWritePm1Control ( ACPI_FUNCTION_TRACE (HwWritePm1Control); - Status = AcpiWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock); + Status = AcpiHwWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); @@ -253,7 +456,7 @@ AcpiHwWritePm1Control ( if (AcpiGbl_FADT.XPm1bControlBlock.Address) { - Status = AcpiWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock); + Status = AcpiHwWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock); } return_ACPI_STATUS (Status); } @@ -319,13 +522,13 @@ AcpiHwRegisterRead ( case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ - Status = AcpiRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock); + Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - Status = AcpiRead (&Value, &AcpiGbl_FADT.XPmTimerBlock); + Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPmTimerBlock); break; @@ -450,7 +653,7 @@ AcpiHwRegisterWrite ( * For control registers, all reserved bits must be preserved, * as per the ACPI spec. */ - Status = AcpiRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock); + Status = AcpiHwRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock); if (ACPI_FAILURE (Status)) { goto Exit; @@ -460,13 +663,13 @@ AcpiHwRegisterWrite ( ACPI_INSERT_BITS (Value, ACPI_PM2_CONTROL_PRESERVED_BITS, ReadValue); - Status = AcpiWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock); + Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - Status = AcpiWrite (Value, &AcpiGbl_FADT.XPmTimerBlock); + Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPmTimerBlock); break; @@ -517,7 +720,7 @@ AcpiHwReadMultiple ( /* The first register is always required */ - Status = AcpiRead (&ValueA, RegisterA); + Status = AcpiHwRead (&ValueA, RegisterA); if (ACPI_FAILURE (Status)) { return (Status); @@ -527,7 +730,7 @@ AcpiHwReadMultiple ( if (RegisterB->Address) { - Status = AcpiRead (&ValueB, RegisterB); + Status = AcpiHwRead (&ValueB, RegisterB); if (ACPI_FAILURE (Status)) { return (Status); @@ -574,7 +777,7 @@ AcpiHwWriteMultiple ( /* The first register is always required */ - Status = AcpiWrite (Value, RegisterA); + Status = AcpiHwWrite (Value, RegisterA); if (ACPI_FAILURE (Status)) { return (Status); @@ -594,7 +797,7 @@ AcpiHwWriteMultiple ( */ if (RegisterB->Address) { - Status = AcpiWrite (Value, RegisterB); + Status = AcpiHwWrite (Value, RegisterB); } return (Status); diff --git a/sys/contrib/dev/acpica/hardware/hwsleep.c b/sys/contrib/dev/acpica/hardware/hwsleep.c index f13b7492ec1..7026c69a025 100644 --- a/sys/contrib/dev/acpica/hardware/hwsleep.c +++ b/sys/contrib/dev/acpica/hardware/hwsleep.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -346,10 +346,13 @@ AcpiEnterSleepState ( if (SleepState != ACPI_STATE_S5) { - /* Disable BM arbitration */ - + /* + * Disable BM arbitration. This feature is contained within an + * optional register (PM2 Control), so ignore a BAD_ADDRESS + * exception. + */ Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 1); - if (ACPI_FAILURE (Status)) + if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS)) { return_ACPI_STATUS (Status); } @@ -694,10 +697,13 @@ AcpiLeaveSleepState ( AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId, ACPI_CLEAR_STATUS); - /* Enable BM arbitration */ - + /* + * Enable BM arbitration. This feature is contained within an + * optional register (PM2 Control), so ignore a BAD_ADDRESS + * exception. + */ Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 0); - if (ACPI_FAILURE (Status)) + if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS)) { return_ACPI_STATUS (Status); } diff --git a/sys/contrib/dev/acpica/hardware/hwtimer.c b/sys/contrib/dev/acpica/hardware/hwtimer.c index 96aa0885436..b9b60318469 100644 --- a/sys/contrib/dev/acpica/hardware/hwtimer.c +++ b/sys/contrib/dev/acpica/hardware/hwtimer.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -187,7 +187,7 @@ AcpiGetTimer ( return_ACPI_STATUS (AE_BAD_PARAMETER); } - Status = AcpiRead (Ticks, &AcpiGbl_FADT.XPmTimerBlock); + Status = AcpiHwRead (Ticks, &AcpiGbl_FADT.XPmTimerBlock); return_ACPI_STATUS (Status); } @@ -232,7 +232,7 @@ AcpiGetTimerDuration ( { ACPI_STATUS Status; UINT32 DeltaTicks; - ACPI_INTEGER Quotient; + UINT64 Quotient; ACPI_FUNCTION_TRACE (AcpiGetTimerDuration); diff --git a/sys/contrib/dev/acpica/hardware/hwvalid.c b/sys/contrib/dev/acpica/hardware/hwvalid.c index 395c995c69a..8c369b18bc2 100644 --- a/sys/contrib/dev/acpica/hardware/hwvalid.c +++ b/sys/contrib/dev/acpica/hardware/hwvalid.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/hardware/hwxface.c b/sys/contrib/dev/acpica/hardware/hwxface.c index c87731661f7..e7815ccf69e 100644 --- a/sys/contrib/dev/acpica/hardware/hwxface.c +++ b/sys/contrib/dev/acpica/hardware/hwxface.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -157,9 +157,23 @@ AcpiReset ( return_ACPI_STATUS (AE_NOT_EXIST); } - /* Write the reset value to the reset register */ + if (ResetReg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO) + { + /* + * For I/O space, write directly to the OSL. This bypasses the port + * validation mechanism, which may block a valid write to the reset + * register. + */ + Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address, + AcpiGbl_FADT.ResetValue, ResetReg->BitWidth); + } + else + { + /* Write the reset value to the reset register */ + + Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg); + } - Status = AcpiWrite (AcpiGbl_FADT.ResetValue, ResetReg); return_ACPI_STATUS (Status); } @@ -177,13 +191,20 @@ ACPI_EXPORT_SYMBOL (AcpiReset) * * DESCRIPTION: Read from either memory or IO space. * + * LIMITATIONS: + * BitWidth must be exactly 8, 16, 32, or 64. + * SpaceID must be SystemMemory or SystemIO. + * BitOffset and AccessWidth are currently ignored, as there has + * not been a need to implement these. + * ******************************************************************************/ ACPI_STATUS AcpiRead ( - UINT32 *Value, + UINT64 *ReturnValue, ACPI_GENERIC_ADDRESS *Reg) { + UINT32 Value; UINT32 Width; UINT64 Address; ACPI_STATUS Status; @@ -192,63 +213,85 @@ AcpiRead ( ACPI_FUNCTION_NAME (AcpiRead); - /* - * Must have a valid pointer to a GAS structure, and a non-zero address - * within. - */ - if (!Reg) + if (!ReturnValue) { return (AE_BAD_PARAMETER); } - /* Get a local copy of the address. Handles possible alignment issues */ + /* Validate contents of the GAS register. Allow 64-bit transfers */ - ACPI_MOVE_64_TO_64 (&Address, &Reg->Address); - if (!Address) + Status = AcpiHwValidateRegister (Reg, 64, &Address); + if (ACPI_FAILURE (Status)) { - return (AE_BAD_ADDRESS); + return (Status); } - /* Supported widths are 8/16/32 */ - Width = Reg->BitWidth; - if ((Width != 8) && (Width != 16) && (Width != 32)) + if (Width == 64) { - return (AE_SUPPORT); + Width = 32; /* Break into two 32-bit transfers */ } - /* Initialize entire 32-bit return value to zero */ + /* Initialize entire 64-bit return value to zero */ - *Value = 0; + *ReturnValue = 0; + Value = 0; /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ - switch (Reg->SpaceId) + if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) { - case ACPI_ADR_SPACE_SYSTEM_MEMORY: + Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) + Address, &Value, Width); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + *ReturnValue = Value; - Status = AcpiOsReadMemory ( - (ACPI_PHYSICAL_ADDRESS) Address, Value, Width); - break; + if (Reg->BitWidth == 64) + { + /* Read the top 32 bits */ + Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) + (Address + 4), &Value, 32); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + *ReturnValue |= ((UINT64) Value << 32); + } + } + else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ + { + Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) + Address, &Value, Width); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + *ReturnValue = Value; - case ACPI_ADR_SPACE_SYSTEM_IO: + if (Reg->BitWidth == 64) + { + /* Read the top 32 bits */ - Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address, Value, Width); - break; - - - default: - ACPI_ERROR ((AE_INFO, - "Unsupported address space: %X", Reg->SpaceId)); - return (AE_BAD_PARAMETER); + Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) + (Address + 4), &Value, 32); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + *ReturnValue |= ((UINT64) Value << 32); + } } ACPI_DEBUG_PRINT ((ACPI_DB_IO, - "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", - *Value, Width, ACPI_FORMAT_UINT64 (Address), + "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", + ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth, + ACPI_FORMAT_UINT64 (Address), AcpiUtGetRegionName (Reg->SpaceId))); return (Status); @@ -261,7 +304,7 @@ ACPI_EXPORT_SYMBOL (AcpiRead) * * FUNCTION: AcpiWrite * - * PARAMETERS: Value - To be written + * PARAMETERS: Value - Value to be written * Reg - GAS register structure * * RETURN: Status @@ -272,7 +315,7 @@ ACPI_EXPORT_SYMBOL (AcpiRead) ACPI_STATUS AcpiWrite ( - UINT32 Value, + UINT64 Value, ACPI_GENERIC_ADDRESS *Reg) { UINT32 Width; @@ -283,60 +326,67 @@ AcpiWrite ( ACPI_FUNCTION_NAME (AcpiWrite); - /* - * Must have a valid pointer to a GAS structure, and a non-zero address - * within. - */ - if (!Reg) + /* Validate contents of the GAS register. Allow 64-bit transfers */ + + Status = AcpiHwValidateRegister (Reg, 64, &Address); + if (ACPI_FAILURE (Status)) { - return (AE_BAD_PARAMETER); + return (Status); } - /* Get a local copy of the address. Handles possible alignment issues */ - - ACPI_MOVE_64_TO_64 (&Address, &Reg->Address); - if (!Address) - { - return (AE_BAD_ADDRESS); - } - - /* Supported widths are 8/16/32 */ - Width = Reg->BitWidth; - if ((Width != 8) && (Width != 16) && (Width != 32)) + if (Width == 64) { - return (AE_SUPPORT); + Width = 32; /* Break into two 32-bit transfers */ } /* - * Two address spaces supported: Memory or IO. - * PCI_Config is not supported here because the GAS struct is insufficient + * Two address spaces supported: Memory or IO. PCI_Config is + * not supported here because the GAS structure is insufficient */ - switch (Reg->SpaceId) + if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) { - case ACPI_ADR_SPACE_SYSTEM_MEMORY: + Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS) + Address, ACPI_LODWORD (Value), Width); + if (ACPI_FAILURE (Status)) + { + return (Status); + } - Status = AcpiOsWriteMemory ( - (ACPI_PHYSICAL_ADDRESS) Address, Value, Width); - break; + if (Reg->BitWidth == 64) + { + Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS) + (Address + 4), ACPI_HIDWORD (Value), 32); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + } + else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ + { + Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) + Address, ACPI_LODWORD (Value), Width); + if (ACPI_FAILURE (Status)) + { + return (Status); + } - - case ACPI_ADR_SPACE_SYSTEM_IO: - - Status = AcpiHwWritePort ( - (ACPI_IO_ADDRESS) Address, Value, Width); - break; - - - default: - ACPI_ERROR ((AE_INFO, - "Unsupported address space: %X", Reg->SpaceId)); - return (AE_BAD_PARAMETER); + if (Reg->BitWidth == 64) + { + Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) + (Address + 4), ACPI_HIDWORD (Value), 32); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } } ACPI_DEBUG_PRINT ((ACPI_DB_IO, - "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", - Value, Width, ACPI_FORMAT_UINT64 (Address), + "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", + ACPI_FORMAT_UINT64 (Value), Reg->BitWidth, + ACPI_FORMAT_UINT64 (Address), AcpiUtGetRegionName (Reg->SpaceId))); return (Status); diff --git a/sys/contrib/dev/acpica/include/acapps.h b/sys/contrib/dev/acpica/include/acapps.h index e1f31b791b7..418e20fb084 100644 --- a/sys/contrib/dev/acpica/include/acapps.h +++ b/sys/contrib/dev/acpica/include/acapps.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -124,21 +124,21 @@ #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 int AcpiGbl_Opterr; +extern char *AcpiGbl_Optarg; + + /* * adisasm */ @@ -151,7 +151,8 @@ AdAmlDisassemble ( BOOLEAN GetAllTables); void -AdPrintStatistics (void); +AdPrintStatistics ( + void); ACPI_STATUS AdFindDsdt( @@ -159,7 +160,8 @@ AdFindDsdt( UINT32 *DsdtLength); void -AdDumpTables (void); +AdDumpTables ( + void); ACPI_STATUS AdGetLocalTables ( @@ -179,7 +181,9 @@ AdDisplayTables ( ACPI_TABLE_HEADER *Table); ACPI_STATUS -AdDisplayStatistics (void); +AdDisplayStatistics ( + void); + /* * adwalk @@ -209,6 +213,7 @@ AcpiDmConvertResourceIndexes ( ACPI_PARSE_OBJECT *ParseTreeRoot, ACPI_NAMESPACE_NODE *NamespaceRoot); + /* * adfile */ @@ -227,11 +232,6 @@ FlSplitInputPathname ( char **OutDirectoryPath, char **OutFilename); -char * -FlGenerateFilename ( - char *InputFilename, - char *Suffix); - char * AdGenerateFilename ( char *Prefix, diff --git a/sys/contrib/dev/acpica/include/accommon.h b/sys/contrib/dev/acpica/include/accommon.h index 98331d6da0a..5853e6f7c93 100644 --- a/sys/contrib/dev/acpica/include/accommon.h +++ b/sys/contrib/dev/acpica/include/accommon.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/acconfig.h b/sys/contrib/dev/acpica/include/acconfig.h index 7b458cc457f..9417b449dc7 100644 --- a/sys/contrib/dev/acpica/include/acconfig.h +++ b/sys/contrib/dev/acpica/include/acconfig.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -177,9 +177,9 @@ #define ACPI_MAX_REFERENCE_COUNT 0x800 -/* Size of cached memory mapping for system memory operation region */ +/* Default page size for use in mapping memory for operation regions */ -#define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096 +#define ACPI_DEFAULT_PAGE_SIZE 4096 /* Must be power of 2 */ /* OwnerId tracking. 8 entries allows for 255 OwnerIds */ @@ -236,7 +236,7 @@ /* Operation regions */ -#define ACPI_NUM_PREDEFINED_REGIONS 8 +#define ACPI_NUM_PREDEFINED_REGIONS 9 #define ACPI_USER_REGION_BEGIN 0x80 /* Maximum SpaceIds for Operation Regions */ @@ -252,9 +252,15 @@ #define ACPI_RSDP_CHECKSUM_LENGTH 20 #define ACPI_RSDP_XCHECKSUM_LENGTH 36 -/* SMBus bidirectional buffer size */ +/* SMBus and IPMI bidirectional buffer size */ #define ACPI_SMBUS_BUFFER_SIZE 34 +#define ACPI_IPMI_BUFFER_SIZE 66 + +/* _SxD and _SxW control methods */ + +#define ACPI_NUM_SxD_METHODS 4 +#define ACPI_NUM_SxW_METHODS 5 /****************************************************************************** diff --git a/sys/contrib/dev/acpica/include/acdebug.h b/sys/contrib/dev/acpica/include/acdebug.h index 7e72094803c..2be2fd409b9 100644 --- a/sys/contrib/dev/acpica/include/acdebug.h +++ b/sys/contrib/dev/acpica/include/acdebug.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -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 @@ -313,6 +319,7 @@ AcpiDbDisplayArgumentObject ( ACPI_OPERAND_OBJECT *ObjDesc, ACPI_WALK_STATE *WalkState); + /* * dbexec - debugger control method execution */ diff --git a/sys/contrib/dev/acpica/include/acdisasm.h b/sys/contrib/dev/acpica/include/acdisasm.h index ccc15f22777..6c61f84f38b 100644 --- a/sys/contrib/dev/acpica/include/acdisasm.h +++ b/sys/contrib/dev/acpica/include/acdisasm.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -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 { @@ -183,6 +171,9 @@ typedef const struct acpi_dmtable_info #define ACPI_DMT_EXIT 30 #define ACPI_DMT_SIG 31 #define ACPI_DMT_FADTPM 32 +#define ACPI_DMT_BUF16 33 +#define ACPI_DMT_IVRS 34 + typedef void (*ACPI_DMTABLE_HANDLER) ( @@ -250,6 +241,7 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmarScope[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar1[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar2[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoDmar3[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoEcdt[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoEinj[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoEinj0[]; @@ -263,15 +255,22 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoHeader[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest1[]; -extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest3[]; -extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest4[]; -extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest5[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest2[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest6[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest7[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest8[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoHest9[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoHestNotify[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoHestBank[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoHpet[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs0[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs1[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs4[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8a[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8b[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8c[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoIvrsHdr[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt1[]; @@ -287,6 +286,8 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadt10[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoMadtHdr[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg0[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoMsct[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoMsct0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoRsdp1[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoRsdp2[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoSbst[]; @@ -300,6 +301,10 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoSrat0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoSrat1[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoSrat2[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpa[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoUefi[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoWaet[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoWdat[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoWdat0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoWdrt[]; @@ -363,6 +368,10 @@ void AcpiDmDumpHest ( ACPI_TABLE_HEADER *Table); +void +AcpiDmDumpIvrs ( + ACPI_TABLE_HEADER *Table); + void AcpiDmDumpMcfg ( ACPI_TABLE_HEADER *Table); @@ -371,6 +380,10 @@ void AcpiDmDumpMadt ( ACPI_TABLE_HEADER *Table); +void +AcpiDmDumpMsct ( + ACPI_TABLE_HEADER *Table); + UINT32 AcpiDmDumpRsdp ( ACPI_TABLE_HEADER *Table); @@ -387,6 +400,10 @@ void AcpiDmDumpSrat ( ACPI_TABLE_HEADER *Table); +void +AcpiDmDumpWdat ( + ACPI_TABLE_HEADER *Table); + void AcpiDmDumpXsdt ( ACPI_TABLE_HEADER *Table); @@ -446,14 +463,6 @@ void AcpiDmMatchOp ( ACPI_PARSE_OBJECT *Op); -BOOLEAN -AcpiDmCommaIfListMember ( - ACPI_PARSE_OBJECT *Op); - -void -AcpiDmCommaIfFieldMember ( - ACPI_PARSE_OBJECT *Op); - /* * dmnames @@ -526,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 */ @@ -560,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); @@ -698,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/sys/contrib/dev/acpica/include/acdispat.h b/sys/contrib/dev/acpica/include/acdispat.h index 2aa86232b2f..d7af8003df2 100644 --- a/sys/contrib/dev/acpica/include/acdispat.h +++ b/sys/contrib/dev/acpica/include/acdispat.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/acevents.h b/sys/contrib/dev/acpica/include/acevents.h index 0cd5e2e2869..567ac1ec0e1 100644 --- a/sys/contrib/dev/acpica/include/acevents.h +++ b/sys/contrib/dev/acpica/include/acevents.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -265,7 +265,7 @@ AcpiEvAddressSpaceDispatch ( UINT32 Function, UINT32 RegionOffset, UINT32 BitWidth, - ACPI_INTEGER *Value); + UINT64 *Value); ACPI_STATUS AcpiEvAttachRegion ( diff --git a/sys/contrib/dev/acpica/include/acexcep.h b/sys/contrib/dev/acpica/include/acexcep.h index dfe2e2ee734..89fe5c66898 100644 --- a/sys/contrib/dev/acpica/include/acexcep.h +++ b/sys/contrib/dev/acpica/include/acexcep.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/acglobal.h b/sys/contrib/dev/acpica/include/acglobal.h index 42b7b158c4b..4469ee334e3 100644 --- a/sys/contrib/dev/acpica/include/acglobal.h +++ b/sys/contrib/dev/acpica/include/acglobal.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -324,7 +324,8 @@ extern char const *AcpiGbl_ExceptionNames_Ctrl[]; extern BOOLEAN AcpiGbl_Shutdown; extern UINT32 AcpiGbl_StartupFlags; extern const char *AcpiGbl_SleepStateNames[ACPI_S_STATE_COUNT]; -extern const char *AcpiGbl_HighestDstateNames[4]; +extern const char *AcpiGbl_LowestDstateNames[ACPI_NUM_SxW_METHODS]; +extern const char *AcpiGbl_HighestDstateNames[ACPI_NUM_SxD_METHODS]; extern const ACPI_OPCODE_INFO AcpiGbl_AmlOpInfo[AML_NUM_OPCODES]; extern const char *AcpiGbl_RegionTypes[ACPI_NUM_PREDEFINED_REGIONS]; #endif @@ -355,6 +356,8 @@ ACPI_EXTERN BOOLEAN AcpiGbl_DisplayFinalMemStats; ACPI_EXTERN ACPI_NAMESPACE_NODE AcpiGbl_RootNodeStruct; ACPI_EXTERN ACPI_NAMESPACE_NODE *AcpiGbl_RootNode; ACPI_EXTERN ACPI_NAMESPACE_NODE *AcpiGbl_FadtGpeDevice; +ACPI_EXTERN ACPI_OPERAND_OBJECT *AcpiGbl_ModuleCodeList; + extern const UINT8 AcpiGbl_NsProperties [ACPI_NUM_NS_TYPES]; extern const ACPI_PREDEFINED_NAMES AcpiGbl_PreDefinedNames [NUM_PREDEFINED_NAMES]; @@ -443,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/sys/contrib/dev/acpica/include/achware.h b/sys/contrib/dev/acpica/include/achware.h index 05da01b44db..be0b4df327d 100644 --- a/sys/contrib/dev/acpica/include/achware.h +++ b/sys/contrib/dev/acpica/include/achware.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -141,6 +141,22 @@ AcpiHwGetMode ( /* * hwregs - ACPI Register I/O */ +ACPI_STATUS +AcpiHwValidateRegister ( + ACPI_GENERIC_ADDRESS *Reg, + UINT8 MaxBitWidth, + UINT64 *Address); + +ACPI_STATUS +AcpiHwRead ( + UINT32 *Value, + ACPI_GENERIC_ADDRESS *Reg); + +ACPI_STATUS +AcpiHwWrite ( + UINT32 Value, + ACPI_GENERIC_ADDRESS *Reg); + ACPI_BIT_REGISTER_INFO * AcpiHwGetBitRegisterInfo ( UINT32 RegisterId); diff --git a/sys/contrib/dev/acpica/include/acinterp.h b/sys/contrib/dev/acpica/include/acinterp.h index b0f4b921854..de7dbf8030e 100644 --- a/sys/contrib/dev/acpica/include/acinterp.h +++ b/sys/contrib/dev/acpica/include/acinterp.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -214,13 +214,13 @@ AcpiExCommonBufferSetup ( ACPI_STATUS AcpiExWriteWithUpdateRule ( ACPI_OPERAND_OBJECT *ObjDesc, - ACPI_INTEGER Mask, - ACPI_INTEGER FieldValue, + UINT64 Mask, + UINT64 FieldValue, UINT32 FieldDatumByteOffset); void AcpiExGetBufferDatum( - ACPI_INTEGER *Datum, + UINT64 *Datum, void *Buffer, UINT32 BufferLength, UINT32 ByteGranularity, @@ -228,7 +228,7 @@ AcpiExGetBufferDatum( void AcpiExSetBufferDatum ( - ACPI_INTEGER MergedDatum, + UINT64 MergedDatum, void *Buffer, UINT32 BufferLength, UINT32 ByteGranularity, @@ -266,7 +266,7 @@ ACPI_STATUS AcpiExAccessRegion ( ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, - ACPI_INTEGER *Value, + UINT64 *Value, UINT32 ReadWrite); @@ -296,8 +296,8 @@ AcpiExDoConcatenate ( ACPI_STATUS AcpiExDoLogicalNumericOp ( UINT16 Opcode, - ACPI_INTEGER Integer0, - ACPI_INTEGER Integer1, + UINT64 Integer0, + UINT64 Integer1, BOOLEAN *LogicalResult); ACPI_STATUS @@ -307,11 +307,11 @@ AcpiExDoLogicalOp ( ACPI_OPERAND_OBJECT *Operand1, BOOLEAN *LogicalResult); -ACPI_INTEGER +UINT64 AcpiExDoMathOp ( UINT16 Opcode, - ACPI_INTEGER Operand0, - ACPI_INTEGER Operand1); + UINT64 Operand0, + UINT64 Operand1); ACPI_STATUS AcpiExCreateMutex ( @@ -425,7 +425,7 @@ AcpiExSystemDoNotifyOp ( ACPI_STATUS AcpiExSystemDoSuspend( - ACPI_INTEGER Time); + UINT64 Time); ACPI_STATUS AcpiExSystemDoStall ( @@ -696,13 +696,13 @@ AcpiExReleaseGlobalLock ( void AcpiExEisaIdToString ( - UINT32 NumericId, - char *OutString); + char *Dest, + UINT64 CompressedId); void -AcpiExUnsignedIntegerToString ( - ACPI_INTEGER Value, - char *OutString); +AcpiExIntegerToString ( + char *Dest, + UINT64 Value); /* @@ -713,7 +713,7 @@ AcpiExSystemMemorySpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); @@ -722,7 +722,7 @@ AcpiExSystemIoSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); @@ -731,7 +731,7 @@ AcpiExPciConfigSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); @@ -740,7 +740,7 @@ AcpiExCmosSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); @@ -749,7 +749,7 @@ AcpiExPciBarSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); @@ -758,7 +758,7 @@ AcpiExEmbeddedControllerSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); @@ -767,7 +767,7 @@ AcpiExSmBusSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); @@ -777,7 +777,7 @@ AcpiExDataTableSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); diff --git a/sys/contrib/dev/acpica/include/aclocal.h b/sys/contrib/dev/acpica/include/aclocal.h index 99955c31bf1..0aeacff6c52 100644 --- a/sys/contrib/dev/acpica/include/aclocal.h +++ b/sys/contrib/dev/acpica/include/aclocal.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -493,6 +493,24 @@ typedef union acpi_predefined_info } ACPI_PREDEFINED_INFO; + +/* Data block used during object validation */ + +typedef struct acpi_predefined_data +{ + char *Pathname; + const ACPI_PREDEFINED_INFO *Predefined; + union acpi_operand_object *ParentPackage; + UINT32 Flags; + UINT8 NodeFlags; + +} ACPI_PREDEFINED_DATA; + +/* Defines for Flags field above */ + +#define ACPI_OBJECT_REPAIRED 1 + + /* * Bitmapped return value types * Note: the actual data types must be contiguous, a loop in nspredef.c @@ -835,8 +853,7 @@ typedef struct acpi_opcode_info typedef union acpi_parse_value { - ACPI_INTEGER Integer; /* Integer constant (Up to 64 bits) */ - UINT64_STRUCT Integer64; /* Structure overlay for 2 32-bit Dwords */ + UINT64 Integer; /* Integer constant (Up to 64 bits) */ UINT32 Size; /* bytelist or field size */ char *String; /* NULL terminated string */ UINT8 *Buffer; /* buffer or string */ @@ -1110,6 +1127,9 @@ typedef struct acpi_bit_register_info #define ACPI_OSI_WIN_XP_SP2 0x05 #define ACPI_OSI_WINSRV_2003_SP1 0x06 #define ACPI_OSI_WIN_VISTA 0x07 +#define ACPI_OSI_WINSRV_2008 0x08 +#define ACPI_OSI_WIN_VISTA_SP1 0x09 +#define ACPI_OSI_WIN_7 0x0A #define ACPI_ALWAYS_ILLEGAL 0x00 @@ -1196,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/sys/contrib/dev/acpica/include/acmacros.h b/sys/contrib/dev/acpica/include/acmacros.h index b9c323ebd7d..e9a6f42cbf2 100644 --- a/sys/contrib/dev/acpica/include/acmacros.h +++ b/sys/contrib/dev/acpica/include/acmacros.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -335,8 +335,8 @@ * MASK_BITS_ABOVE creates a mask starting AT the position and above * MASK_BITS_BELOW creates a mask starting one bit BELOW the position */ -#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_INTEGER_MAX) << ((UINT32) (position)))) -#define ACPI_MASK_BITS_BELOW(position) ((ACPI_INTEGER_MAX) << ((UINT32) (position))) +#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_UINT64_MAX) << ((UINT32) (position)))) +#define ACPI_MASK_BITS_BELOW(position) ((ACPI_UINT64_MAX) << ((UINT32) (position))) /* Bitfields within ACPI registers */ @@ -402,6 +402,8 @@ */ #define ACPI_ERROR_NAMESPACE(s, e) AcpiNsReportError (AE_INFO, s, e); #define ACPI_ERROR_METHOD(s, n, p, e) AcpiNsReportMethodError (AE_INFO, s, n, p, e); +#define ACPI_WARN_PREDEFINED(plist) AcpiUtPredefinedWarning plist +#define ACPI_INFO_PREDEFINED(plist) AcpiUtPredefinedInfo plist #else @@ -409,6 +411,8 @@ #define ACPI_ERROR_NAMESPACE(s, e) #define ACPI_ERROR_METHOD(s, n, p, e) +#define ACPI_WARN_PREDEFINED(plist) +#define ACPI_INFO_PREDEFINED(plist) #endif /* ACPI_NO_ERROR_MESSAGES */ @@ -469,16 +473,16 @@ AcpiUtPtrExit (ACPI_DEBUG_PARAMETERS, (UINT8 *) _s); \ return (_s); }) #define return_VALUE(s) ACPI_DO_WHILE0 ({ \ - register ACPI_INTEGER _s = (s); \ + register UINT64 _s = (s); \ AcpiUtValueExit (ACPI_DEBUG_PARAMETERS, _s); \ return (_s); }) #define return_UINT8(s) ACPI_DO_WHILE0 ({ \ register UINT8 _s = (UINT8) (s); \ - AcpiUtValueExit (ACPI_DEBUG_PARAMETERS, (ACPI_INTEGER) _s); \ + AcpiUtValueExit (ACPI_DEBUG_PARAMETERS, (UINT64) _s); \ return (_s); }) #define return_UINT32(s) ACPI_DO_WHILE0 ({ \ register UINT32 _s = (UINT32) (s); \ - AcpiUtValueExit (ACPI_DEBUG_PARAMETERS, (ACPI_INTEGER) _s); \ + AcpiUtValueExit (ACPI_DEBUG_PARAMETERS, (UINT64) _s); \ return (_s); }) #else /* Use original less-safe macros */ @@ -489,7 +493,7 @@ AcpiUtPtrExit (ACPI_DEBUG_PARAMETERS, (UINT8 *) (s)); \ return((s)); }) #define return_VALUE(s) ACPI_DO_WHILE0 ({ \ - AcpiUtValueExit (ACPI_DEBUG_PARAMETERS, (ACPI_INTEGER) (s)); \ + AcpiUtValueExit (ACPI_DEBUG_PARAMETERS, (UINT64) (s)); \ return((s)); }) #define return_UINT8(s) return_VALUE(s) #define return_UINT32(s) return_VALUE(s) diff --git a/sys/contrib/dev/acpica/include/acnames.h b/sys/contrib/dev/acpica/include/acnames.h index eb9944aa16e..12dd89ce14d 100644 --- a/sys/contrib/dev/acpica/include/acnames.h +++ b/sys/contrib/dev/acpica/include/acnames.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/acnamesp.h b/sys/contrib/dev/acpica/include/acnamesp.h index 3f9a6ce6faf..9ddd12e210b 100644 --- a/sys/contrib/dev/acpica/include/acnamesp.h +++ b/sys/contrib/dev/acpica/include/acnamesp.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -146,6 +146,14 @@ #define ACPI_NS_WALK_UNLOCK 0x01 #define ACPI_NS_WALK_TEMP_NODES 0x02 +/* Object is not a package element */ + +#define ACPI_NOT_PACKAGE_ELEMENT ACPI_UINT32_MAX + +/* Always emit warning message, not dependent on node flags */ + +#define ACPI_WARN_ALWAYS 0 + /* * nsinit - Namespace initialization @@ -181,7 +189,8 @@ AcpiNsWalkNamespace ( ACPI_HANDLE StartObject, UINT32 MaxDepth, UINT32 Flags, - ACPI_WALK_CALLBACK UserFunction, + ACPI_WALK_CALLBACK PreOrderVisit, + ACPI_WALK_CALLBACK PostOrderVisit, void *Context, void **ReturnValue); @@ -240,6 +249,10 @@ void AcpiNsDeleteNode ( ACPI_NAMESPACE_NODE *Node); +void +AcpiNsRemoveNode ( + ACPI_NAMESPACE_NODE *Node); + void AcpiNsDeleteNamespaceSubtree ( ACPI_NAMESPACE_NODE *ParentHandle); @@ -310,6 +323,10 @@ ACPI_STATUS AcpiNsEvaluate ( ACPI_EVALUATE_INFO *Info); +void +AcpiNsExecModuleCodeList ( + void); + /* * nspredef - Support for predefined/reserved names @@ -411,6 +428,48 @@ AcpiNsGetAttachedData ( void **Data); +/* + * nsrepair - General return object repair for all + * predefined methods/objects + */ +ACPI_STATUS +AcpiNsRepairObject ( + ACPI_PREDEFINED_DATA *Data, + UINT32 ExpectedBtypes, + UINT32 PackageIndex, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +ACPI_STATUS +AcpiNsRepairPackageList ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ObjDescPtr); + +ACPI_STATUS +AcpiNsRepairNullElement ( + ACPI_PREDEFINED_DATA *Data, + UINT32 ExpectedBtypes, + UINT32 PackageIndex, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +void +AcpiNsRemoveNullElements ( + ACPI_PREDEFINED_DATA *Data, + UINT8 PackageType, + ACPI_OPERAND_OBJECT *ObjDesc); + + +/* + * nsrepair2 - Return object repair for specific + * predefined methods/objects + */ +ACPI_STATUS +AcpiNsComplexRepairs ( + ACPI_PREDEFINED_DATA *Data, + ACPI_NAMESPACE_NODE *Node, + ACPI_STATUS ValidateStatus, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + + /* * nssearch - Namespace searching and entry */ @@ -496,13 +555,9 @@ AcpiNsExternalizeName ( char **ConvertedName); ACPI_NAMESPACE_NODE * -AcpiNsMapHandleToNode ( +AcpiNsValidateHandle ( ACPI_HANDLE Handle); -ACPI_HANDLE -AcpiNsConvertEntryToHandle( - ACPI_NAMESPACE_NODE *Node); - void AcpiNsTerminate ( void); diff --git a/sys/contrib/dev/acpica/include/acobject.h b/sys/contrib/dev/acpica/include/acobject.h index 59418592099..f86f8392679 100644 --- a/sys/contrib/dev/acpica/include/acobject.h +++ b/sys/contrib/dev/acpica/include/acobject.h @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -170,6 +170,7 @@ #define AOPOBJ_OBJECT_INITIALIZED 0x08 #define AOPOBJ_SETUP_COMPLETE 0x10 #define AOPOBJ_SINGLE_DATUM 0x20 +#define AOPOBJ_MODULE_LEVEL 0x40 /****************************************************************************** @@ -189,7 +190,7 @@ typedef struct acpi_object_integer { ACPI_OBJECT_COMMON_HEADER UINT8 Fill[3]; /* Prevent warning on some compilers */ - ACPI_INTEGER Value; + UINT64 Value; } ACPI_OBJECT_INTEGER; @@ -287,7 +288,12 @@ typedef struct acpi_object_method UINT8 SyncLevel; union acpi_operand_object *Mutex; UINT8 *AmlStart; - ACPI_INTERNAL_METHOD Implementation; + union + { + ACPI_INTERNAL_METHOD Implementation; + union acpi_operand_object *Handler; + } Extra; + UINT32 AmlLength; UINT8 ThreadCount; ACPI_OWNER_ID OwnerId; diff --git a/sys/contrib/dev/acpica/include/acopcode.h b/sys/contrib/dev/acpica/include/acopcode.h index bb309c78d3f..94d585d2273 100644 --- a/sys/contrib/dev/acpica/include/acopcode.h +++ b/sys/contrib/dev/acpica/include/acopcode.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/acoutput.h b/sys/contrib/dev/acpica/include/acoutput.h index 2b796b541a6..8018fed5384 100644 --- a/sys/contrib/dev/acpica/include/acoutput.h +++ b/sys/contrib/dev/acpica/include/acoutput.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -158,7 +158,8 @@ #define ACPI_LV_INIT 0x00000001 #define ACPI_LV_DEBUG_OBJECT 0x00000002 #define ACPI_LV_INFO 0x00000004 -#define ACPI_LV_ALL_EXCEPTIONS 0x00000007 +#define ACPI_LV_REPAIR 0x00000008 +#define ACPI_LV_ALL_EXCEPTIONS 0x0000000F /* Trace verbosity level 1 [Standard Trace Level] */ @@ -217,6 +218,7 @@ #define ACPI_DB_INIT ACPI_DEBUG_LEVEL (ACPI_LV_INIT) #define ACPI_DB_DEBUG_OBJECT ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT) #define ACPI_DB_INFO ACPI_DEBUG_LEVEL (ACPI_LV_INFO) +#define ACPI_DB_REPAIR ACPI_DEBUG_LEVEL (ACPI_LV_REPAIR) #define ACPI_DB_ALL_EXCEPTIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS) /* Trace level -- also used in the global "DebugLevel" */ @@ -248,8 +250,8 @@ /* Defaults for DebugLevel, debug and normal */ -#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT) -#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT) +#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT | ACPI_LV_REPAIR) +#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT | ACPI_LV_REPAIR) #define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) diff --git a/sys/contrib/dev/acpica/include/acparser.h b/sys/contrib/dev/acpica/include/acparser.h index b65177b10de..35fe0060f1a 100644 --- a/sys/contrib/dev/acpica/include/acparser.h +++ b/sys/contrib/dev/acpica/include/acparser.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -137,6 +137,7 @@ #define ACPI_PARSE_DEFERRED_OP 0x0100 #define ACPI_PARSE_DISASSEMBLE 0x0200 +#define ACPI_PARSE_MODULE_LEVEL 0x0400 /****************************************************************************** * diff --git a/sys/contrib/dev/acpica/include/acpi.h b/sys/contrib/dev/acpica/include/acpi.h index 0d82345917c..d462294325f 100644 --- a/sys/contrib/dev/acpica/include/acpi.h +++ b/sys/contrib/dev/acpica/include/acpi.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/acpiosxf.h b/sys/contrib/dev/acpica/include/acpiosxf.h index b10d12b4803..13570b4f173 100644 --- a/sys/contrib/dev/acpica/include/acpiosxf.h +++ b/sys/contrib/dev/acpica/include/acpiosxf.h @@ -12,7 +12,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -346,7 +346,7 @@ AcpiOsWaitEventsComplete ( void AcpiOsSleep ( - ACPI_INTEGER Milliseconds); + UINT64 Milliseconds); void AcpiOsStall ( @@ -401,7 +401,7 @@ ACPI_STATUS AcpiOsWritePciConfiguration ( ACPI_PCI_ID *PciId, UINT32 Reg, - ACPI_INTEGER Value, + UINT64 Value, UINT32 Width); diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h index 466fb27654f..7111984df6a 100644 --- a/sys/contrib/dev/acpica/include/acpixf.h +++ b/sys/contrib/dev/acpica/include/acpixf.h @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -120,7 +120,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20090521 +#define ACPI_CA_VERSION 0x20100121 #include #include @@ -267,7 +267,8 @@ AcpiWalkNamespace ( ACPI_OBJECT_TYPE Type, ACPI_HANDLE StartObject, UINT32 MaxDepth, - ACPI_WALK_CALLBACK UserFunction, + ACPI_WALK_CALLBACK PreOrderVisit, + ACPI_WALK_CALLBACK PostOrderVisit, void *Context, void **ReturnValue); @@ -336,7 +337,7 @@ AcpiEvaluateObjectTyped ( ACPI_STATUS AcpiGetObjectInfo ( ACPI_HANDLE Handle, - ACPI_BUFFER *ReturnBuffer); + ACPI_DEVICE_INFO **ReturnBuffer); ACPI_STATUS AcpiInstallMethod ( @@ -573,12 +574,12 @@ AcpiReset ( ACPI_STATUS AcpiRead ( - UINT32 *Value, + UINT64 *Value, ACPI_GENERIC_ADDRESS *Reg); ACPI_STATUS AcpiWrite ( - UINT32 Value, + UINT64 Value, ACPI_GENERIC_ADDRESS *Reg); ACPI_STATUS diff --git a/sys/contrib/dev/acpica/include/acpredef.h b/sys/contrib/dev/acpica/include/acpredef.h index 9e5a5247e76..9b881fb8007 100644 --- a/sys/contrib/dev/acpica/include/acpredef.h +++ b/sys/contrib/dev/acpica/include/acpredef.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -136,8 +136,8 @@ * (Used for _PRW) * * - * 2) PTYPE2 packages contain a Variable-length number of sub-packages. Each of the - * different types describe the contents of each of the sub-packages. + * 2) PTYPE2 packages contain a Variable-length number of sub-packages. Each + * of the different types describe the contents of each of the sub-packages. * * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types: * object type @@ -157,12 +157,15 @@ * count * (Used for _CST) * - * ACPI_PTYPE2_Fixed-length: Each subpackage is of Fixed-length length + * ACPI_PTYPE2_FIXED: Each subpackage is of Fixed-length * (Used for _PRT) * * ACPI_PTYPE2_MIN: Each subpackage has a Variable-length but minimum length * (Used for _HPX) * + * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length + * (Used for _ART, _FPS) + * *****************************************************************************/ enum AcpiReturnPackageTypes @@ -174,10 +177,12 @@ enum AcpiReturnPackageTypes ACPI_PTYPE2_COUNT = 5, ACPI_PTYPE2_PKG_COUNT = 6, ACPI_PTYPE2_FIXED = 7, - ACPI_PTYPE2_MIN = 8 + ACPI_PTYPE2_MIN = 8, + ACPI_PTYPE2_REV_FIXED = 9 }; +#ifdef ACPI_CREATE_PREDEFINED_TABLE /* * Predefined method/object information table. * @@ -188,7 +193,7 @@ enum AcpiReturnPackageTypes * AcpiEvaluateObject: * _Lxx and _Exx GPE methods * _Qxx EC methods - * _T_x compiler temporary Variable-lengths + * _T_x compiler temporary variables * * 2) Predefined names that never actually exist within the AML code: * Predefined resource descriptor field names @@ -263,21 +268,30 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, {{"_ALT", 0, ACPI_RTYPE_INTEGER}}, + {{"_ART", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(rev), n Pkg (2 Ref/11 Int) */ + {{{ACPI_PTYPE2_REV_FIXED,ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER}, 11,0}}, + {{"_BBN", 0, ACPI_RTYPE_INTEGER}}, {{"_BCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, {{"_BCM", 1, 0}}, + {{"_BCT", 1, ACPI_RTYPE_INTEGER}}, {{"_BDN", 0, ACPI_RTYPE_INTEGER}}, {{"_BFS", 1, 0}}, {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}}, + {{"_BIX", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int),(4 Str) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4,0}}, + {{"_BLT", 3, 0}}, + {{"_BMA", 1, ACPI_RTYPE_INTEGER}}, {{"_BMC", 1, 0}}, {{"_BMD", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (5 Int) */ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, + {{"_BMS", 1, ACPI_RTYPE_INTEGER}}, {{"_BQC", 0, ACPI_RTYPE_INTEGER}}, {{"_BST", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, @@ -285,6 +299,7 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{"_BTM", 1, ACPI_RTYPE_INTEGER}}, {{"_BTP", 1, 0}}, {{"_CBA", 0, ACPI_RTYPE_INTEGER}}, /* See PCI firmware spec 3.0 */ + {{"_CDM", 0, ACPI_RTYPE_INTEGER}}, {{"_CID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints/Strs) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0,0}, 0,0}}, @@ -310,6 +325,7 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{"_DSM", 4, ACPI_RTYPE_ALL}}, /* Must return a type, but it can be of any type */ {{"_DSS", 1, 0}}, {{"_DSW", 3, 0}}, + {{"_DTI", 1, 0}}, {{"_EC_", 0, ACPI_RTYPE_INTEGER}}, {{"_EDL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs)*/ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, @@ -325,9 +341,22 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16,0}, 0,0}}, {{"_FDM", 1, 0}}, + {{"_FIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, + {{"_FIX", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, + {{"_FPS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(rev), n Pkg (5 Int) */ + {{{ACPI_PTYPE2_REV_FIXED,ACPI_RTYPE_INTEGER, 5, 0}, 0,0}}, + + {{"_FSL", 1, 0}}, + {{"_FST", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (3 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3,0}, 0,0}}, + + + {{"_GAI", 0, ACPI_RTYPE_INTEGER}}, + {{"_GHL", 0, ACPI_RTYPE_INTEGER}}, {{"_GLK", 0, ACPI_RTYPE_INTEGER}}, {{"_GPD", 0, ACPI_RTYPE_INTEGER}}, {{"_GPE", 0, ACPI_RTYPE_INTEGER}}, /* _GPE method, not _GPE scope */ @@ -355,15 +384,21 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{"_LCK", 1, 0}}, {{"_LID", 0, ACPI_RTYPE_INTEGER}}, {{"_MAT", 0, ACPI_RTYPE_BUFFER}}, + {{"_MBM", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (8 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 8,0}, 0,0}}, + {{"_MLS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (2 Str) */ {{{ACPI_PTYPE2, ACPI_RTYPE_STRING, 2,0}, 0,0}}, {{"_MSG", 1, 0}}, + {{"_MSM", 4, ACPI_RTYPE_INTEGER}}, + {{"_NTT", 0, ACPI_RTYPE_INTEGER}}, {{"_OFF", 0, 0}}, {{"_ON_", 0, 0}}, {{"_OS_", 0, ACPI_RTYPE_STRING}}, {{"_OSC", 4, ACPI_RTYPE_BUFFER}}, {{"_OST", 3, 0}}, + {{"_PAI", 1, ACPI_RTYPE_INTEGER}}, {{"_PCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, @@ -371,10 +406,21 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, {{"_PDC", 1, 0}}, + {{"_PDL", 0, ACPI_RTYPE_INTEGER}}, {{"_PIC", 1, 0}}, + {{"_PIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (3 Int),(3 Str) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, ACPI_RTYPE_STRING}, 3,0}}, + {{"_PLD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Bufs) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0,0}, 0,0}}, + {{"_PMC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (11 Int),(3 Str) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 11, ACPI_RTYPE_STRING}, 3,0}}, + + {{"_PMD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_PMM", 0, ACPI_RTYPE_INTEGER}}, {{"_PPC", 0, ACPI_RTYPE_INTEGER}}, {{"_PPE", 0, ACPI_RTYPE_INTEGER}}, /* See dig64 spec */ {{"_PR0", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ @@ -386,17 +432,26 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{"_PR2", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + {{"_PR3", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_PRL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + {{"_PRS", 0, ACPI_RTYPE_BUFFER}}, /* - * For _PRT, many BIOSs reverse the 2nd and 3rd Package elements. This bug is so prevalent that there - * is code in the ACPICA Resource Manager to detect this and switch them back. For now, do not allow - * and issue a warning. To allow this and eliminate the warning, add the ACPI_RTYPE_REFERENCE - * type to the 2nd element (index 1) in the statement below. + * For _PRT, many BIOSs reverse the 3rd and 4th Package elements (Source + * and SourceIndex). This bug is so prevalent that there is code in the + * ACPICA Resource Manager to detect this and switch them back. For now, + * do not allow and issue a warning. To allow this and eliminate the + * warning, add the ACPI_RTYPE_REFERENCE type to the 4th element (index 3) + * in the statement below. */ {{"_PRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (4): Int,Int,Int/Ref,Int */ {{{ACPI_PTYPE2_FIXED, 4, ACPI_RTYPE_INTEGER,ACPI_RTYPE_INTEGER}, - ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE,ACPI_RTYPE_INTEGER}}, + ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE, + ACPI_RTYPE_INTEGER}}, {{"_PRW", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each: Pkg/Int,Int,[Variable-length Refs] (Pkg is Ref/Int) */ {{{ACPI_PTYPE1_OPTION, 2, ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE, @@ -422,7 +477,11 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{"_PTC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Buf) */ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, + {{"_PTP", 2, ACPI_RTYPE_INTEGER}}, {{"_PTS", 1, 0}}, + {{"_PUR", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, + {{"_PXM", 0, ACPI_RTYPE_INTEGER}}, {{"_REG", 2, 0}}, {{"_REV", 0, ACPI_RTYPE_INTEGER}}, @@ -468,6 +527,7 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = /* Note: the 3-arg definition may be removed for ACPI 4.0 */ {{"_SDD", 1, 0}}, {{"_SEG", 0, ACPI_RTYPE_INTEGER}}, + {{"_SHL", 1, ACPI_RTYPE_INTEGER}}, {{"_SLI", 0, ACPI_RTYPE_BUFFER}}, {{"_SPD", 1, ACPI_RTYPE_INTEGER}}, {{"_SRS", 1, 0}}, @@ -475,11 +535,15 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{"_SST", 1, 0}}, {{"_STA", 0, ACPI_RTYPE_INTEGER}}, {{"_STM", 3, 0}}, + {{"_STP", 2, ACPI_RTYPE_INTEGER}}, {{"_STR", 0, ACPI_RTYPE_BUFFER}}, + {{"_STV", 2, ACPI_RTYPE_INTEGER}}, {{"_SUN", 0, ACPI_RTYPE_INTEGER}}, {{"_SWS", 0, ACPI_RTYPE_INTEGER}}, {{"_TC1", 0, ACPI_RTYPE_INTEGER}}, {{"_TC2", 0, ACPI_RTYPE_INTEGER}}, + {{"_TIP", 1, ACPI_RTYPE_INTEGER}}, + {{"_TIV", 1, ACPI_RTYPE_INTEGER}}, {{"_TMP", 0, ACPI_RTYPE_INTEGER}}, {{"_TPC", 0, ACPI_RTYPE_INTEGER}}, {{"_TPT", 1, 0}}, @@ -530,5 +594,5 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = _PRT - currently ignore reversed entries. Attempt to fix here? Think about possibly fixing package elements like _BIF, etc. #endif - +#endif #endif diff --git a/sys/contrib/dev/acpica/include/acresrc.h b/sys/contrib/dev/acpica/include/acresrc.h index 9e3698adb25..ed5926163d5 100644 --- a/sys/contrib/dev/acpica/include/acresrc.h +++ b/sys/contrib/dev/acpica/include/acresrc.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/acrestyp.h b/sys/contrib/dev/acpica/include/acrestyp.h index 7eb7600d982..0a85d29f5a4 100644 --- a/sys/contrib/dev/acpica/include/acrestyp.h +++ b/sys/contrib/dev/acpica/include/acrestyp.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -534,7 +534,7 @@ typedef struct acpi_pci_routing_table { UINT32 Length; UINT32 Pin; - ACPI_INTEGER Address; /* here for 64-bit alignment */ + UINT64 Address; /* here for 64-bit alignment */ UINT32 SourceIndex; char Source[4]; /* pad to 64 bits so sizeof() works in all cases */ diff --git a/sys/contrib/dev/acpica/include/acstruct.h b/sys/contrib/dev/acpica/include/acstruct.h index 45c85fe0b2f..d4696b83005 100644 --- a/sys/contrib/dev/acpica/include/acstruct.h +++ b/sys/contrib/dev/acpica/include/acstruct.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/actables.h b/sys/contrib/dev/acpica/include/actables.h index e4428e64155..54fdaae9b1a 100644 --- a/sys/contrib/dev/acpica/include/actables.h +++ b/sys/contrib/dev/acpica/include/actables.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/actbl.h b/sys/contrib/dev/acpica/include/actbl.h index ce1f0718ac4..05775a87873 100644 --- a/sys/contrib/dev/acpica/include/actbl.h +++ b/sys/contrib/dev/acpica/include/actbl.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -116,9 +116,25 @@ #ifndef __ACTBL_H__ #define __ACTBL_H__ + +/******************************************************************************* + * + * Fundamental ACPI tables + * + * This file contains definitions for the ACPI tables that are directly consumed + * by ACPICA. All other tables are consumed by the OS-dependent ACPI-related + * device drivers and other OS support code. + * + * The RSDP and FACS do not use the common ACPI table header. All other ACPI + * tables use the header. + * + ******************************************************************************/ + + /* - * Values for description table header signatures. Useful because they make - * it more difficult to inadvertently type in the wrong signature. + * Values for description table header signatures for tables defined in this + * file. Useful because they make it more difficult to inadvertently type in + * the wrong signature. */ #define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */ #define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */ @@ -137,23 +153,17 @@ */ #pragma pack(1) - /* - * These are the ACPI tables that are directly consumed by the subsystem. - * - * The RSDP and FACS do not use the common ACPI table header. All other ACPI - * tables use the header. - * * Note about bitfields: The UINT8 type is used for bitfields in ACPI tables. * This is the only type that is even remotely portable. Anything else is not * portable, so do not use any other bitfield types. */ + /******************************************************************************* * - * ACPI Table Header. This common header is used by all tables except the - * RSDP and FACS. The define is used for direct inclusion of header into - * other ACPI tables + * Master ACPI Table Header. This common header is used by all ACPI tables + * except the RSDP and FACS. * ******************************************************************************/ @@ -172,13 +182,16 @@ typedef struct acpi_table_header } ACPI_TABLE_HEADER; -/* +/******************************************************************************* + * * GAS - Generic Address Structure (ACPI 2.0+) * * Note: Since this structure is used in the ACPI tables, it is byte aligned. - * If misalignment is not supported, access to the Address field must be - * performed with care. - */ + * If misaliged access is not supported by the hardware, accesses to the + * 64-bit Address field must be performed with care. + * + ******************************************************************************/ + typedef struct acpi_generic_address { UINT8 SpaceId; /* Address space where struct or register exists */ @@ -193,6 +206,7 @@ typedef struct acpi_generic_address /******************************************************************************* * * RSDP - Root System Description Pointer (Signature is "RSD PTR ") + * Version 2 * ******************************************************************************/ @@ -216,6 +230,7 @@ typedef struct acpi_table_rsdp /******************************************************************************* * * RSDT/XSDT - Root System Description Tables + * Version 1 (both) * ******************************************************************************/ @@ -250,23 +265,31 @@ typedef struct acpi_table_facs UINT32 Flags; UINT64 XFirmwareWakingVector; /* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */ UINT8 Version; /* Version of this table (ACPI 2.0+) */ - UINT8 Reserved[31]; /* Reserved, must be zero */ + UINT8 Reserved[3]; /* Reserved, must be zero */ + UINT32 OspmFlags; /* Flags to be set by OSPM (ACPI 4.0) */ + UINT8 Reserved1[24]; /* Reserved, must be zero */ } ACPI_TABLE_FACS; -/* Flag macros */ +/* Masks for GlobalLock flag field above */ -#define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */ +#define ACPI_GLOCK_PENDING (1) /* 00: Pending global lock ownership */ +#define ACPI_GLOCK_OWNED (1<<1) /* 01: Global lock is owned */ -/* Global lock flags */ +/* Masks for Flags field above */ -#define ACPI_GLOCK_PENDING 0x01 /* 00: Pending global lock ownership */ -#define ACPI_GLOCK_OWNED 0x02 /* 01: Global lock is owned */ +#define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */ +#define ACPI_FACS_64BIT_WAKE (1<<1) /* 01: 64-bit wake vector supported (ACPI 4.0) */ + +/* Masks for OspmFlags field above */ + +#define ACPI_FACS_64BIT_ENVIRONMENT (1) /* 00: 64-bit wake environment is required (ACPI 4.0) */ /******************************************************************************* * * FADT - Fixed ACPI Description Table (Signature "FACP") + * Version 4 * ******************************************************************************/ @@ -330,7 +353,7 @@ typedef struct acpi_table_fadt } ACPI_TABLE_FADT; -/* FADT Boot Architecture Flags (BootFlags) */ +/* Masks for FADT Boot Architecture Flags (BootFlags) */ #define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */ #define ACPI_FADT_8042 (1<<1) /* 01: [V3] System has an 8042 controller on port 60/64 */ @@ -338,7 +361,7 @@ typedef struct acpi_table_fadt #define ACPI_FADT_NO_MSI (1<<3) /* 03: [V4] Message Signaled Interrupts (MSI) must not be enabled */ #define ACPI_FADT_NO_ASPM (1<<4) /* 04: [V4] PCIe ASPM control must not be enabled */ -/* FADT flags */ +/* Masks for FADT flags */ #define ACPI_FADT_WBINVD (1) /* 00: [V1] The wbinvd instruction works properly */ #define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] wbinvd flushes but does not invalidate caches */ @@ -362,7 +385,7 @@ typedef struct acpi_table_fadt #define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: [V4] All local xAPICs must use physical dest mode (ACPI 3.0) */ -/* FADT Prefered Power Management Profiles */ +/* Values for PreferredProfile (Prefered Power Management Profiles) */ enum AcpiPreferedPmProfiles { @@ -381,6 +404,9 @@ enum AcpiPreferedPmProfiles #pragma pack() +/* + * Internal table-related structures + */ typedef union acpi_name_union { UINT32 Integer; @@ -388,9 +414,9 @@ typedef union acpi_name_union } ACPI_NAME_UNION; -/* - * Internal ACPI Table Descriptor. One per ACPI table - */ + +/* Internal ACPI Table Descriptor. One per ACPI table. */ + typedef struct acpi_table_desc { ACPI_PHYSICAL_ADDRESS Address; @@ -402,7 +428,7 @@ typedef struct acpi_table_desc } ACPI_TABLE_DESC; -/* Flags for above */ +/* Masks for Flags field above */ #define ACPI_TABLE_ORIGIN_UNKNOWN (0) #define ACPI_TABLE_ORIGIN_MAPPED (1) @@ -416,6 +442,7 @@ typedef struct acpi_table_desc * Get the remaining ACPI tables */ #include +#include /* Macros used to generate offsets to specific table fields */ diff --git a/sys/contrib/dev/acpica/include/actbl1.h b/sys/contrib/dev/acpica/include/actbl1.h index dc5519b6226..ac11a3fe6b3 100644 --- a/sys/contrib/dev/acpica/include/actbl1.h +++ b/sys/contrib/dev/acpica/include/actbl1.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -119,42 +119,32 @@ /******************************************************************************* * - * Additional ACPI Tables + * Additional ACPI Tables (1) * * These tables are not consumed directly by the ACPICA subsystem, but are * included here to support device drivers and the AML disassembler. * + * The tables in this file are fully defined within the ACPI specification. + * ******************************************************************************/ /* - * Values for description table header signatures. Useful because they make - * it more difficult to inadvertently type in the wrong signature. + * Values for description table header signatures for tables defined in this + * file. Useful because they make it more difficult to inadvertently type in + * the wrong signature. */ -#define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ #define ACPI_SIG_BERT "BERT" /* Boot Error Record Table */ -#define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ #define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ -#define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ -#define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ #define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */ #define ACPI_SIG_EINJ "EINJ" /* Error Injection table */ #define ACPI_SIG_ERST "ERST" /* Error Record Serialization Table */ #define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */ -#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ -#define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */ #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ -#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ +#define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */ #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ -#define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */ #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ -#define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ -#define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ #define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */ -#define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ -#define ACPI_SIG_UEFI "UEFI" /* Uefi Boot Optimization Table */ -#define ACPI_SIG_WDAT "WDAT" /* Watchdog Action Table */ -#define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ /* @@ -170,7 +160,13 @@ */ -/* Common Subtable header (used in MADT, SRAT, etc.) */ +/******************************************************************************* + * + * Common subtable headers + * + ******************************************************************************/ + +/* Generic subtable header (used in MADT, SRAT, etc.) */ typedef struct acpi_subtable_header { @@ -180,7 +176,7 @@ typedef struct acpi_subtable_header } ACPI_SUBTABLE_HEADER; -/* Common Subtable header for WHEA tables (EINJ, ERST, WDAT) */ +/* Subtable header for WHEA tables (EINJ, ERST, WDAT) */ typedef struct acpi_whea_header { @@ -197,138 +193,8 @@ typedef struct acpi_whea_header /******************************************************************************* * - * ASF - Alert Standard Format table (Signature "ASF!") - * - * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003 - * - ******************************************************************************/ - -typedef struct acpi_table_asf -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - -} ACPI_TABLE_ASF; - - -/* ASF subtable header */ - -typedef struct acpi_asf_header -{ - UINT8 Type; - UINT8 Reserved; - UINT16 Length; - -} ACPI_ASF_HEADER; - - -/* Values for Type field above */ - -enum AcpiAsfType -{ - ACPI_ASF_TYPE_INFO = 0, - ACPI_ASF_TYPE_ALERT = 1, - ACPI_ASF_TYPE_CONTROL = 2, - ACPI_ASF_TYPE_BOOT = 3, - ACPI_ASF_TYPE_ADDRESS = 4, - ACPI_ASF_TYPE_RESERVED = 5 -}; - -/* - * ASF subtables - */ - -/* 0: ASF Information */ - -typedef struct acpi_asf_info -{ - ACPI_ASF_HEADER Header; - UINT8 MinResetValue; - UINT8 MinPollInterval; - UINT16 SystemId; - UINT32 MfgId; - UINT8 Flags; - UINT8 Reserved2[3]; - -} ACPI_ASF_INFO; - -/* 1: ASF Alerts */ - -typedef struct acpi_asf_alert -{ - ACPI_ASF_HEADER Header; - UINT8 AssertMask; - UINT8 DeassertMask; - UINT8 Alerts; - UINT8 DataLength; - -} ACPI_ASF_ALERT; - -typedef struct acpi_asf_alert_data -{ - UINT8 Address; - UINT8 Command; - UINT8 Mask; - UINT8 Value; - UINT8 SensorType; - UINT8 Type; - UINT8 Offset; - UINT8 SourceType; - UINT8 Severity; - UINT8 SensorNumber; - UINT8 Entity; - UINT8 Instance; - -} ACPI_ASF_ALERT_DATA; - -/* 2: ASF Remote Control */ - -typedef struct acpi_asf_remote -{ - ACPI_ASF_HEADER Header; - UINT8 Controls; - UINT8 DataLength; - UINT16 Reserved2; - -} ACPI_ASF_REMOTE; - -typedef struct acpi_asf_control_data -{ - UINT8 Function; - UINT8 Address; - UINT8 Command; - UINT8 Value; - -} ACPI_ASF_CONTROL_DATA; - -/* 3: ASF RMCP Boot Options */ - -typedef struct acpi_asf_rmcp -{ - ACPI_ASF_HEADER Header; - UINT8 Capabilities[7]; - UINT8 CompletionCode; - UINT32 EnterpriseId; - UINT8 Command; - UINT16 Parameter; - UINT16 BootOptions; - UINT16 OemParameters; - -} ACPI_ASF_RMCP; - -/* 4: ASF Address */ - -typedef struct acpi_asf_address -{ - ACPI_ASF_HEADER Header; - UINT8 EpromAddress; - UINT8 Devices; - -} ACPI_ASF_ADDRESS; - - -/******************************************************************************* - * - * BERT - Boot Error Record Table + * BERT - Boot Error Record Table (ACPI 4.0) + * Version 1 * ******************************************************************************/ @@ -341,44 +207,47 @@ typedef struct acpi_table_bert } ACPI_TABLE_BERT; -/* Boot Error Region */ +/* Boot Error Region (not a subtable, pointed to by Address field above) */ typedef struct acpi_bert_region { - UINT32 BlockStatus; - UINT32 RawDataOffset; - UINT32 RawDataLength; - UINT32 DataLength; - UINT32 ErrorSeverity; + UINT32 BlockStatus; /* Type of error information */ + UINT32 RawDataOffset; /* Offset to raw error data */ + UINT32 RawDataLength; /* Length of raw error data */ + UINT32 DataLength; /* Length of generic error data */ + UINT32 ErrorSeverity; /* Severity code */ } ACPI_BERT_REGION; -/* BlockStatus Flags */ +/* Values for BlockStatus flags above */ #define ACPI_BERT_UNCORRECTABLE (1) -#define ACPI_BERT_CORRECTABLE (2) -#define ACPI_BERT_MULTIPLE_UNCORRECTABLE (4) -#define ACPI_BERT_MULTIPLE_CORRECTABLE (8) +#define ACPI_BERT_CORRECTABLE (1<<1) +#define ACPI_BERT_MULTIPLE_UNCORRECTABLE (1<<2) +#define ACPI_BERT_MULTIPLE_CORRECTABLE (1<<3) +#define ACPI_BERT_ERROR_ENTRY_COUNT (0xFF<<4) /* 8 bits, error count */ +/* Values for ErrorSeverity above */ -/******************************************************************************* - * - * BOOT - Simple Boot Flag Table - * - ******************************************************************************/ - -typedef struct acpi_table_boot +enum AcpiBertErrorSeverity { - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT8 CmosIndex; /* Index in CMOS RAM for the boot register */ - UINT8 Reserved[3]; + ACPI_BERT_ERROR_CORRECTABLE = 0, + ACPI_BERT_ERROR_FATAL = 1, + ACPI_BERT_ERROR_CORRECTED = 2, + ACPI_BERT_ERROR_NONE = 3, + ACPI_BERT_ERROR_RESERVED = 4 /* 4 and greater are reserved */ +}; -} ACPI_TABLE_BOOT; +/* + * Note: The generic error data that follows the ErrorSeverity field above + * uses the ACPI_HEST_GENERIC_DATA defined under the HEST table below + */ /******************************************************************************* * - * CPEP - Corrected Platform Error Polling table + * CPEP - Corrected Platform Error Polling table (ACPI 4.0) + * Version 1 * ******************************************************************************/ @@ -394,8 +263,7 @@ typedef struct acpi_table_cpep typedef struct acpi_cpep_polling { - UINT8 Type; - UINT8 Length; + ACPI_SUBTABLE_HEADER Header; UINT8 Id; /* Processor ID */ UINT8 Eid; /* Processor EID */ UINT32 Interval; /* Polling interval (msec) */ @@ -403,145 +271,10 @@ typedef struct acpi_cpep_polling } ACPI_CPEP_POLLING; -/******************************************************************************* - * - * DBGP - Debug Port table - * - ******************************************************************************/ - -typedef struct acpi_table_dbgp -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT8 Type; /* 0=full 16550, 1=subset of 16550 */ - UINT8 Reserved[3]; - ACPI_GENERIC_ADDRESS DebugPort; - -} ACPI_TABLE_DBGP; - - -/******************************************************************************* - * - * DMAR - DMA Remapping table - * From "Intel Virtualization Technology for Directed I/O", Sept. 2007 - * - ******************************************************************************/ - -typedef struct acpi_table_dmar -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT8 Width; /* Host Address Width */ - UINT8 Flags; - UINT8 Reserved[10]; - -} ACPI_TABLE_DMAR; - -/* Flags */ - -#define ACPI_DMAR_INTR_REMAP (1) - -/* DMAR subtable header */ - -typedef struct acpi_dmar_header -{ - UINT16 Type; - UINT16 Length; - -} ACPI_DMAR_HEADER; - -/* Values for subtable type in ACPI_DMAR_HEADER */ - -enum AcpiDmarType -{ - ACPI_DMAR_TYPE_HARDWARE_UNIT = 0, - ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, - ACPI_DMAR_TYPE_ATSR = 2, - ACPI_DMAR_TYPE_RESERVED = 3 /* 3 and greater are reserved */ -}; - -typedef struct acpi_dmar_device_scope -{ - UINT8 EntryType; - UINT8 Length; - UINT16 Reserved; - UINT8 EnumerationId; - UINT8 Bus; - -} ACPI_DMAR_DEVICE_SCOPE; - -/* Values for EntryType in ACPI_DMAR_DEVICE_SCOPE */ - -enum AcpiDmarScopeType -{ - ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0, - ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1, - ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2, - ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3, - ACPI_DMAR_SCOPE_TYPE_HPET = 4, - ACPI_DMAR_SCOPE_TYPE_RESERVED = 5 /* 5 and greater are reserved */ -}; - -typedef struct acpi_dmar_pci_path -{ - UINT8 Device; - UINT8 Function; - -} ACPI_DMAR_PCI_PATH; - -/* - * DMAR Sub-tables, correspond to Type in ACPI_DMAR_HEADER - */ - -/* 0: Hardware Unit Definition */ - -typedef struct acpi_dmar_hardware_unit -{ - ACPI_DMAR_HEADER Header; - UINT8 Flags; - UINT8 Reserved; - UINT16 Segment; - UINT64 Address; /* Register Base Address */ - -} ACPI_DMAR_HARDWARE_UNIT; - -/* Flags */ - -#define ACPI_DMAR_INCLUDE_ALL (1) - -/* 1: Reserved Memory Defininition */ - -typedef struct acpi_dmar_reserved_memory -{ - ACPI_DMAR_HEADER Header; - UINT16 Reserved; - UINT16 Segment; - UINT64 BaseAddress; /* 4K aligned base address */ - UINT64 EndAddress; /* 4K aligned limit address */ - -} ACPI_DMAR_RESERVED_MEMORY; - -/* Flags */ - -#define ACPI_DMAR_ALLOW_ALL (1) - -/* 2: Root Port ATS Capability Reporting Structure */ - -typedef struct acpi_dmar_atsr -{ - ACPI_DMAR_HEADER Header; - UINT8 Flags; - UINT8 Reserved; - UINT16 Segment; - -} ACPI_DMAR_ATSR; - -/* Flags */ - -#define ACPI_DMAR_ALL_PORTS (1) - - /******************************************************************************* * * ECDT - Embedded Controller Boot Resources Table + * Version 1 * ******************************************************************************/ @@ -559,7 +292,8 @@ typedef struct acpi_table_ecdt /******************************************************************************* * - * EINJ - Error Injection Table + * EINJ - Error Injection Table (ACPI 4.0) + * Version 1 * ******************************************************************************/ @@ -567,11 +301,13 @@ typedef struct acpi_table_einj { ACPI_TABLE_HEADER Header; /* Common ACPI table header */ UINT32 HeaderLength; - UINT32 Reserved; + UINT8 Flags; + UINT8 Reserved[3]; UINT32 Entries; } ACPI_TABLE_EINJ; + /* EINJ Injection Instruction Entries (actions) */ typedef struct acpi_einj_entry @@ -580,6 +316,10 @@ typedef struct acpi_einj_entry } ACPI_EINJ_ENTRY; +/* Masks for Flags field above */ + +#define ACPI_EINJ_PRESERVE (1) + /* Values for Action field above */ enum AcpiEinjActions @@ -608,6 +348,7 @@ enum AcpiEinjInstructions ACPI_EINJ_INSTRUCTION_RESERVED = 5 /* 5 and greater are reserved */ }; + /* EINJ Trigger Error Action Table */ typedef struct acpi_einj_trigger @@ -619,10 +360,37 @@ typedef struct acpi_einj_trigger } ACPI_EINJ_TRIGGER; +/* Command status return values */ + +enum AcpiEinjCommandStatus +{ + ACPI_EINJ_SUCCESS = 0, + ACPI_EINJ_FAILURE = 1, + ACPI_EINJ_INVALID_ACCESS = 2, + ACPI_EINJ_STATUS_RESERVED = 3 /* 3 and greater are reserved */ +}; + + +/* Error types returned from ACPI_EINJ_GET_ERROR_TYPE (bitfield) */ + +#define ACPI_EINJ_PROCESSOR_CORRECTABLE (1) +#define ACPI_EINJ_PROCESSOR_UNCORRECTABLE (1<<1) +#define ACPI_EINJ_PROCESSOR_FATAL (1<<2) +#define ACPI_EINJ_MEMORY_CORRECTABLE (1<<3) +#define ACPI_EINJ_MEMORY_UNCORRECTABLE (1<<4) +#define ACPI_EINJ_MEMORY_FATAL (1<<5) +#define ACPI_EINJ_PCIX_CORRECTABLE (1<<6) +#define ACPI_EINJ_PCIX_UNCORRECTABLE (1<<7) +#define ACPI_EINJ_PCIX_FATAL (1<<8) +#define ACPI_EINJ_PLATFORM_CORRECTABLE (1<<9) +#define ACPI_EINJ_PLATFORM_UNCORRECTABLE (1<<10) +#define ACPI_EINJ_PLATFORM_FATAL (1<<11) + /******************************************************************************* * - * ERST - Error Record Serialization Table + * ERST - Error Record Serialization Table (ACPI 4.0) + * Version 1 * ******************************************************************************/ @@ -635,6 +403,7 @@ typedef struct acpi_table_erst } ACPI_TABLE_ERST; + /* ERST Serialization Entries (actions) */ typedef struct acpi_erst_entry @@ -643,20 +412,24 @@ typedef struct acpi_erst_entry } ACPI_ERST_ENTRY; +/* Masks for Flags field above */ + +#define ACPI_ERST_PRESERVE (1) + /* Values for Action field above */ enum AcpiErstActions { - ACPI_ERST_BEGIN_WRITE_OPERATION = 0, - ACPI_ERST_BEGIN_READ_OPERATION = 1, - ACPI_ERST_BETGIN_CLEAR_OPERATION= 2, - ACPI_ERST_END_OPERATION = 3, + ACPI_ERST_BEGIN_WRITE = 0, + ACPI_ERST_BEGIN_READ = 1, + ACPI_ERST_BEGIN_CLEAR = 2, + ACPI_ERST_END = 3, ACPI_ERST_SET_RECORD_OFFSET = 4, ACPI_ERST_EXECUTE_OPERATION = 5, ACPI_ERST_CHECK_BUSY_STATUS = 6, ACPI_ERST_GET_COMMAND_STATUS = 7, - ACPI_ERST_GET_RECORD_IDENTIFIER = 8, - ACPI_ERST_SET_RECORD_IDENTIFIER = 9, + ACPI_ERST_GET_RECORD_ID = 8, + ACPI_ERST_SET_RECORD_ID = 9, ACPI_ERST_GET_RECORD_COUNT = 10, ACPI_ERST_BEGIN_DUMMY_WRIITE = 11, ACPI_ERST_NOT_USED = 12, @@ -692,10 +465,34 @@ enum AcpiErstInstructions ACPI_ERST_INSTRUCTION_RESERVED = 19 /* 19 and greater are reserved */ }; +/* Command status return values */ + +enum AcpiErstCommandStatus +{ + ACPI_ERST_SUCESS = 0, + ACPI_ERST_NO_SPACE = 1, + ACPI_ERST_NOT_AVAILABLE = 2, + ACPI_ERST_FAILURE = 3, + ACPI_ERST_RECORD_EMPTY = 4, + ACPI_ERST_NOT_FOUND = 5, + ACPI_ERST_STATUS_RESERVED = 6 /* 6 and greater are reserved */ +}; + + +/* Error Record Serialization Information */ + +typedef struct acpi_erst_info +{ + UINT16 Signature; /* Should be "ER" */ + UINT8 Data[48]; + +} ACPI_ERST_INFO; + /******************************************************************************* * - * HEST - Hardware Error Source Table + * HEST - Hardware Error Source Table (ACPI 4.0) + * Version 1 * ******************************************************************************/ @@ -712,6 +509,7 @@ typedef struct acpi_table_hest typedef struct acpi_hest_header { UINT16 Type; + UINT16 SourceId; } ACPI_HEST_HEADER; @@ -720,92 +518,69 @@ typedef struct acpi_hest_header enum AcpiHestTypes { - ACPI_HEST_TYPE_XPF_MACHINE_CHECK = 0, - ACPI_HEST_TYPE_XPF_CORRECTED_MACHINE_CHECK = 1, - ACPI_HEST_TYPE_XPF_UNUSED = 2, - ACPI_HEST_TYPE_XPF_NON_MASKABLE_INTERRUPT = 3, - ACPI_HEST_TYPE_IPF_CORRECTED_MACHINE_CHECK = 4, - ACPI_HEST_TYPE_IPF_CORRECTED_PLATFORM_ERROR = 5, - ACPI_HEST_TYPE_AER_ROOT_PORT = 6, - ACPI_HEST_TYPE_AER_ENDPOINT = 7, - ACPI_HEST_TYPE_AER_BRIDGE = 8, - ACPI_HEST_TYPE_GENERIC_HARDWARE_ERROR_SOURCE = 9, - ACPI_HEST_TYPE_RESERVED = 10 /* 10 and greater are reserved */ + ACPI_HEST_TYPE_IA32_CHECK = 0, + ACPI_HEST_TYPE_IA32_CORRECTED_CHECK = 1, + ACPI_HEST_TYPE_IA32_NMI = 2, + ACPI_HEST_TYPE_NOT_USED3 = 3, + ACPI_HEST_TYPE_NOT_USED4 = 4, + ACPI_HEST_TYPE_NOT_USED5 = 5, + ACPI_HEST_TYPE_AER_ROOT_PORT = 6, + ACPI_HEST_TYPE_AER_ENDPOINT = 7, + ACPI_HEST_TYPE_AER_BRIDGE = 8, + ACPI_HEST_TYPE_GENERIC_ERROR = 9, + ACPI_HEST_TYPE_RESERVED = 10 /* 10 and greater are reserved */ }; /* - * HEST Sub-subtables + * HEST substructures contained in subtables */ -/* XPF Machine Check Error Bank */ - -typedef struct acpi_hest_xpf_error_bank +/* + * IA32 Error Bank(s) - Follows the ACPI_HEST_IA_MACHINE_CHECK and + * ACPI_HEST_IA_CORRECTED structures. + */ +typedef struct acpi_hest_ia_error_bank { UINT8 BankNumber; UINT8 ClearStatusOnInit; UINT8 StatusFormat; - UINT8 ConfigWriteEnable; + UINT8 Reserved; UINT32 ControlRegister; - UINT64 ControlInitData; + UINT64 ControlData; UINT32 StatusRegister; UINT32 AddressRegister; UINT32 MiscRegister; -} ACPI_HEST_XPF_ERROR_BANK; +} ACPI_HEST_IA_ERROR_BANK; -/* Generic Error Status */ - -typedef struct acpi_hest_generic_status -{ - UINT32 BlockStatus; - UINT32 RawDataOffset; - UINT32 RawDataLength; - UINT32 DataLength; - UINT32 ErrorSeverity; - -} ACPI_HEST_GENERIC_STATUS; - - -/* Generic Error Data */ - -typedef struct acpi_hest_generic_data -{ - UINT8 SectionType[16]; - UINT32 ErrorSeverity; - UINT16 Revision; - UINT8 ValidationBits; - UINT8 Flags; - UINT32 ErrorDataLength; - UINT8 FruId[16]; - UINT8 FruText[20]; - -} ACPI_HEST_GENERIC_DATA; - - -/* Common HEST structure for PCI/AER types below (6,7,8) */ +/* Common HEST sub-structure for PCI/AER structures below (6,7,8) */ typedef struct acpi_hest_aer_common { - UINT16 SourceId; - UINT16 ConfigWriteEnable; + UINT16 Reserved1; UINT8 Flags; UINT8 Enabled; - UINT32 RecordsToPreAllocate; + UINT32 RecordsToPreallocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; - UINT16 Reserved; - UINT32 UncorrectableErrorMask; - UINT32 UncorrectableErrorSeverity; - UINT32 CorrectableErrorMask; - UINT32 AdvancedErrorCapabilities; + UINT16 Reserved2; + UINT32 UncorrectableMask; + UINT32 UncorrectableSeverity; + UINT32 CorrectableMask; + UINT32 AdvancedCapabilities; } ACPI_HEST_AER_COMMON; +/* Masks for HEST Flags fields */ + +#define ACPI_HEST_FIRMWARE_FIRST (1) +#define ACPI_HEST_GLOBAL (1<<1) + /* Hardware Error Notification */ @@ -835,87 +610,69 @@ enum AcpiHestNotifyTypes ACPI_HEST_NOTIFY_RESERVED = 5 /* 5 and greater are reserved */ }; +/* Values for ConfigWriteEnable bitfield above */ + +#define ACPI_HEST_TYPE (1) +#define ACPI_HEST_POLL_INTERVAL (1<<1) +#define ACPI_HEST_POLL_THRESHOLD_VALUE (1<<2) +#define ACPI_HEST_POLL_THRESHOLD_WINDOW (1<<3) +#define ACPI_HEST_ERR_THRESHOLD_VALUE (1<<4) +#define ACPI_HEST_ERR_THRESHOLD_WINDOW (1<<5) + /* * HEST subtables - * - * From WHEA Design Document, 16 May 2007. - * Note: There is no subtable type 2 in this version of the document, - * and there are two different subtable type 3s. */ - /* 0: XPF Machine Check Exception */ +/* 0: IA32 Machine Check Exception */ -typedef struct acpi_hest_xpf_machine_check +typedef struct acpi_hest_ia_machine_check { ACPI_HEST_HEADER Header; - UINT16 SourceId; - UINT16 ConfigWriteEnable; + UINT16 Reserved1; UINT8 Flags; - UINT8 Reserved1; - UINT32 RecordsToPreAllocate; + UINT8 Enabled; + UINT32 RecordsToPreallocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityData; UINT64 GlobalControlData; UINT8 NumHardwareBanks; - UINT8 Reserved2[7]; + UINT8 Reserved3[7]; -} ACPI_HEST_XPF_MACHINE_CHECK; +} ACPI_HEST_IA_MACHINE_CHECK; -/* 1: XPF Corrected Machine Check */ +/* 1: IA32 Corrected Machine Check */ -typedef struct acpi_table_hest_xpf_corrected +typedef struct acpi_hest_ia_corrected { ACPI_HEST_HEADER Header; - UINT16 SourceId; - UINT16 ConfigWriteEnable; + UINT16 Reserved1; UINT8 Flags; UINT8 Enabled; - UINT32 RecordsToPreAllocate; + UINT32 RecordsToPreallocate; UINT32 MaxSectionsPerRecord; ACPI_HEST_NOTIFY Notify; UINT8 NumHardwareBanks; - UINT8 Reserved[3]; + UINT8 Reserved2[3]; -} ACPI_HEST_XPF_CORRECTED; +} ACPI_HEST_IA_CORRECTED; -/* 3: XPF Non-Maskable Interrupt */ +/* 2: IA32 Non-Maskable Interrupt */ -typedef struct acpi_hest_xpf_nmi +typedef struct acpi_hest_ia_nmi { ACPI_HEST_HEADER Header; - UINT16 SourceId; UINT32 Reserved; - UINT32 RecordsToPreAllocate; + UINT32 RecordsToPreallocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; -} ACPI_HEST_XPF_NMI; +} ACPI_HEST_IA_NMI; -/* 4: IPF Corrected Machine Check */ - -typedef struct acpi_hest_ipf_corrected -{ - ACPI_HEST_HEADER Header; - UINT8 Enabled; - UINT8 Reserved; - -} ACPI_HEST_IPF_CORRECTED; - - -/* 5: IPF Corrected Platform Error */ - -typedef struct acpi_hest_ipf_corrected_platform -{ - ACPI_HEST_HEADER Header; - UINT8 Enabled; - UINT8 Reserved; - -} ACPI_HEST_IPF_CORRECTED_PLATFORM; - +/* 3,4,5: Not used */ /* 6: PCI Express Root Port AER */ @@ -944,9 +701,9 @@ typedef struct acpi_hest_aer_bridge { ACPI_HEST_HEADER Header; ACPI_HEST_AER_COMMON Aer; - UINT32 SecondaryUncorrectableErrorMask; - UINT32 SecondaryUncorrectableErrorSeverity; - UINT32 SecondaryAdvancedCapabilities; + UINT32 UncorrectableMask2; + UINT32 UncorrectableSeverity2; + UINT32 AdvancedCapabilities2; } ACPI_HEST_AER_BRIDGE; @@ -956,156 +713,60 @@ typedef struct acpi_hest_aer_bridge typedef struct acpi_hest_generic { ACPI_HEST_HEADER Header; - UINT16 SourceId; UINT16 RelatedSourceId; - UINT8 ConfigWriteEnable; + UINT8 Reserved; UINT8 Enabled; - UINT32 RecordsToPreAllocate; + UINT32 RecordsToPreallocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; ACPI_GENERIC_ADDRESS ErrorStatusAddress; ACPI_HEST_NOTIFY Notify; - UINT32 ErrorStatusBlockLength; + UINT32 ErrorBlockLength; } ACPI_HEST_GENERIC; -/******************************************************************************* - * - * HPET - High Precision Event Timer table - * - ******************************************************************************/ +/* Generic Error Status block */ -typedef struct acpi_table_hpet +typedef struct acpi_hest_generic_status { - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT32 Id; /* Hardware ID of event timer block */ - ACPI_GENERIC_ADDRESS Address; /* Address of event timer block */ - UINT8 Sequence; /* HPET sequence number */ - UINT16 MinimumTick; /* Main counter min tick, periodic mode */ + UINT32 BlockStatus; + UINT32 RawDataOffset; + UINT32 RawDataLength; + UINT32 DataLength; + UINT32 ErrorSeverity; + +} ACPI_HEST_GENERIC_STATUS; + +/* Values for BlockStatus flags above */ + +#define ACPI_HEST_UNCORRECTABLE (1) +#define ACPI_HEST_CORRECTABLE (1<<1) +#define ACPI_HEST_MULTIPLE_UNCORRECTABLE (1<<2) +#define ACPI_HEST_MULTIPLE_CORRECTABLE (1<<3) +#define ACPI_HEST_ERROR_ENTRY_COUNT (0xFF<<4) /* 8 bits, error count */ + + +/* Generic Error Data entry */ + +typedef struct acpi_hest_generic_data +{ + UINT8 SectionType[16]; + UINT32 ErrorSeverity; + UINT16 Revision; + UINT8 ValidationBits; UINT8 Flags; + UINT32 ErrorDataLength; + UINT8 FruId[16]; + UINT8 FruText[20]; -} ACPI_TABLE_HPET; - -/*! Flags */ - -#define ACPI_HPET_PAGE_PROTECT (1) /* 00: No page protection */ -#define ACPI_HPET_PAGE_PROTECT_4 (1<<1) /* 01: 4KB page protected */ -#define ACPI_HPET_PAGE_PROTECT_64 (1<<2) /* 02: 64KB page protected */ - -/*! [End] no source code translation !*/ - - -/******************************************************************************* - * - * IBFT - Boot Firmware Table - * - ******************************************************************************/ - -typedef struct acpi_table_ibft -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT8 Reserved[12]; - -} ACPI_TABLE_IBFT; - - -/* IBFT common subtable header */ - -typedef struct acpi_ibft_header -{ - UINT8 Type; - UINT8 Version; - UINT16 Length; - UINT8 Index; - UINT8 Flags; - -} ACPI_IBFT_HEADER; - - -/* Values for Type field above */ - -enum AcpiIbftType -{ - ACPI_IBFT_TYPE_NOT_USED = 0, - ACPI_IBFT_TYPE_CONTROL = 1, - ACPI_IBFT_TYPE_INITIATOR = 2, - ACPI_IBFT_TYPE_NIC = 3, - ACPI_IBFT_TYPE_TARGET = 4, - ACPI_IBFT_TYPE_EXTENSIONS = 5, - ACPI_IBFT_TYPE_RESERVED = 6 /* 6 and greater are reserved */ -}; - - -/* IBFT subtables */ - -typedef struct acpi_ibft_control -{ - ACPI_IBFT_HEADER Header; - UINT16 Extensions; - UINT16 InitiatorOffset; - UINT16 Nic0Offset; - UINT16 Target0Offset; - UINT16 Nic1Offset; - UINT16 Target1Offset; - -} ACPI_IBFT_CONTROL; - -typedef struct acpi_ibft_initiator -{ - ACPI_IBFT_HEADER Header; - UINT8 SnsServer[16]; - UINT8 SlpServer[16]; - UINT8 PrimaryServer[16]; - UINT8 SecondaryServer[16]; - UINT16 NameLength; - UINT16 NameOffset; - -} ACPI_IBFT_INITIATOR; - -typedef struct acpi_ibft_nic -{ - ACPI_IBFT_HEADER Header; - UINT8 IpAddress[16]; - UINT8 SubnetMaskPrefix; - UINT8 Origin; - UINT8 Gateway[16]; - UINT8 PrimaryDns[16]; - UINT8 SecondaryDns[16]; - UINT8 Dhcp[16]; - UINT16 Vlan; - UINT8 MacAddress[6]; - UINT16 PciAddress; - UINT16 NameLength; - UINT16 NameOffset; - -} ACPI_IBFT_NIC; - -typedef struct acpi_ibft_target -{ - ACPI_IBFT_HEADER Header; - UINT8 TargetIpAddress[16]; - UINT16 TargetIpSocket; - UINT8 TargetBootLun[8]; - UINT8 ChapType; - UINT8 NicAssociation; - UINT16 TargetNameLength; - UINT16 TargetNameOffset; - UINT16 ChapNameLength; - UINT16 ChapNameOffset; - UINT16 ChapSecretLength; - UINT16 ChapSecretOffset; - UINT16 ReverseChapNameLength; - UINT16 ReverseChapNameOffset; - UINT16 ReverseChapSecretLength; - UINT16 ReverseChapSecretOffset; - -} ACPI_IBFT_TARGET; +} ACPI_HEST_GENERIC_DATA; /******************************************************************************* * * MADT - Multiple APIC Description Table + * Version 3 * ******************************************************************************/ @@ -1117,9 +778,9 @@ typedef struct acpi_table_madt } ACPI_TABLE_MADT; -/* Flags */ +/* Masks for Flags field above */ -#define ACPI_MADT_PCAT_COMPAT (1) /* 00: System also has dual 8259s */ +#define ACPI_MADT_PCAT_COMPAT (1) /* 00: System also has dual 8259s */ /* Values for PCATCompat flag */ @@ -1127,7 +788,7 @@ typedef struct acpi_table_madt #define ACPI_MADT_MULTIPLE_APIC 1 -/* Values for subtable type in ACPI_SUBTABLE_HEADER */ +/* Values for MADT subtable type in ACPI_SUBTABLE_HEADER */ enum AcpiMadtType { @@ -1161,6 +822,7 @@ typedef struct acpi_madt_local_apic } ACPI_MADT_LOCAL_APIC; + /* 1: IO APIC */ typedef struct acpi_madt_io_apic @@ -1173,6 +835,7 @@ typedef struct acpi_madt_io_apic } ACPI_MADT_IO_APIC; + /* 2: Interrupt Override */ typedef struct acpi_madt_interrupt_override @@ -1185,6 +848,7 @@ typedef struct acpi_madt_interrupt_override } ACPI_MADT_INTERRUPT_OVERRIDE; + /* 3: NMI Source */ typedef struct acpi_madt_nmi_source @@ -1195,6 +859,7 @@ typedef struct acpi_madt_nmi_source } ACPI_MADT_NMI_SOURCE; + /* 4: Local APIC NMI */ typedef struct acpi_madt_local_apic_nmi @@ -1206,6 +871,7 @@ typedef struct acpi_madt_local_apic_nmi } ACPI_MADT_LOCAL_APIC_NMI; + /* 5: Address Override */ typedef struct acpi_madt_local_apic_override @@ -1216,6 +882,7 @@ typedef struct acpi_madt_local_apic_override } ACPI_MADT_LOCAL_APIC_OVERRIDE; + /* 6: I/O Sapic */ typedef struct acpi_madt_io_sapic @@ -1228,6 +895,7 @@ typedef struct acpi_madt_io_sapic } ACPI_MADT_IO_SAPIC; + /* 7: Local Sapic */ typedef struct acpi_madt_local_sapic @@ -1243,6 +911,7 @@ typedef struct acpi_madt_local_sapic } ACPI_MADT_LOCAL_SAPIC; + /* 8: Platform Interrupt Source */ typedef struct acpi_madt_interrupt_source @@ -1258,11 +927,12 @@ typedef struct acpi_madt_interrupt_source } ACPI_MADT_INTERRUPT_SOURCE; -/* Flags field above */ +/* Masks for Flags field above */ #define ACPI_MADT_CPEI_OVERRIDE (1) -/* 9: Processor Local X2APIC (07/2008) */ + +/* 9: Processor Local X2APIC (ACPI 4.0) */ typedef struct acpi_madt_local_x2apic { @@ -1274,7 +944,8 @@ typedef struct acpi_madt_local_x2apic } ACPI_MADT_LOCAL_X2APIC; -/* 10: Local X2APIC NMI (07/2008) */ + +/* 10: Local X2APIC NMI (ACPI 4.0) */ typedef struct acpi_madt_local_x2apic_nmi { @@ -1315,34 +986,40 @@ typedef struct acpi_madt_local_x2apic_nmi /******************************************************************************* * - * MCFG - PCI Memory Mapped Configuration table and sub-table + * MSCT - Maximum System Characteristics Table (ACPI 4.0) + * Version 1 * ******************************************************************************/ -typedef struct acpi_table_mcfg +typedef struct acpi_table_msct { ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT8 Reserved[8]; + UINT32 ProximityOffset; /* Location of proximity info struct(s) */ + UINT32 MaxProximityDomains;/* Max number of proximity domains */ + UINT32 MaxClockDomains; /* Max number of clock domains */ + UINT64 MaxAddress; /* Max physical address in system */ -} ACPI_TABLE_MCFG; +} ACPI_TABLE_MSCT; -/* Subtable */ +/* Subtable - Maximum Proximity Domain Information. Version 1 */ -typedef struct acpi_mcfg_allocation +typedef struct acpi_msct_proximity { - UINT64 Address; /* Base address, processor-relative */ - UINT16 PciSegment; /* PCI segment group number */ - UINT8 StartBusNumber; /* Starting PCI Bus number */ - UINT8 EndBusNumber; /* Final PCI Bus number */ - UINT32 Reserved; + UINT8 Revision; + UINT8 Length; + UINT32 RangeStart; /* Start of domain range */ + UINT32 RangeEnd; /* End of domain range */ + UINT32 ProcessorCapacity; + UINT64 MemoryCapacity; /* In bytes */ -} ACPI_MCFG_ALLOCATION; +} ACPI_MSCT_PROXIMITY; /******************************************************************************* * * SBST - Smart Battery Specification Table + * Version 1 * ******************************************************************************/ @@ -1359,6 +1036,7 @@ typedef struct acpi_table_sbst /******************************************************************************* * * SLIT - System Locality Distance Information Table + * Version 1 * ******************************************************************************/ @@ -1371,68 +1049,10 @@ typedef struct acpi_table_slit } ACPI_TABLE_SLIT; -/******************************************************************************* - * - * SPCR - Serial Port Console Redirection table - * - ******************************************************************************/ - -typedef struct acpi_table_spcr -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT8 InterfaceType; /* 0=full 16550, 1=subset of 16550 */ - UINT8 Reserved[3]; - ACPI_GENERIC_ADDRESS SerialPort; - UINT8 InterruptType; - UINT8 PcInterrupt; - UINT32 Interrupt; - UINT8 BaudRate; - UINT8 Parity; - UINT8 StopBits; - UINT8 FlowControl; - UINT8 TerminalType; - UINT8 Reserved1; - UINT16 PciDeviceId; - UINT16 PciVendorId; - UINT8 PciBus; - UINT8 PciDevice; - UINT8 PciFunction; - UINT32 PciFlags; - UINT8 PciSegment; - UINT32 Reserved2; - -} ACPI_TABLE_SPCR; - - -/******************************************************************************* - * - * SPMI - Server Platform Management Interface table - * - ******************************************************************************/ - -typedef struct acpi_table_spmi -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT8 Reserved; - UINT8 InterfaceType; - UINT16 SpecRevision; /* Version of IPMI */ - UINT8 InterruptType; - UINT8 GpeNumber; /* GPE assigned */ - UINT8 Reserved1; - UINT8 PciDeviceFlag; - UINT32 Interrupt; - ACPI_GENERIC_ADDRESS IpmiRegister; - UINT8 PciSegment; - UINT8 PciBus; - UINT8 PciDevice; - UINT8 PciFunction; - -} ACPI_TABLE_SPMI; - - /******************************************************************************* * * SRAT - System Resource Affinity Table + * Version 3 * ******************************************************************************/ @@ -1472,6 +1092,11 @@ typedef struct acpi_srat_cpu_affinity } ACPI_SRAT_CPU_AFFINITY; +/* Flags */ + +#define ACPI_SRAT_CPU_USE_AFFINITY (1) /* 00: Use affinity structure */ + + /* 1: Memory Affinity */ typedef struct acpi_srat_mem_affinity @@ -1493,7 +1118,8 @@ typedef struct acpi_srat_mem_affinity #define ACPI_SRAT_MEM_HOT_PLUGGABLE (1<<1) /* 01: Memory region is hot pluggable */ #define ACPI_SRAT_MEM_NON_VOLATILE (1<<2) /* 02: Memory region is non-volatile */ -/* 2: Processor Local X2_APIC Affinity (07/2008) */ + +/* 2: Processor Local X2_APIC Affinity (ACPI 4.0) */ typedef struct acpi_srat_x2apic_cpu_affinity { @@ -1502,6 +1128,8 @@ typedef struct acpi_srat_x2apic_cpu_affinity UINT32 ProximityDomain; UINT32 ApicId; UINT32 Flags; + UINT32 ClockDomain; + UINT32 Reserved2; } ACPI_SRAT_X2APIC_CPU_AFFINITY; @@ -1510,132 +1138,6 @@ typedef struct acpi_srat_x2apic_cpu_affinity #define ACPI_SRAT_CPU_ENABLED (1) /* 00: Use affinity structure */ -/******************************************************************************* - * - * TCPA - Trusted Computing Platform Alliance table - * - ******************************************************************************/ - -typedef struct acpi_table_tcpa -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT16 Reserved; - UINT32 MaxLogLength; /* Maximum length for the event log area */ - UINT64 LogAddress; /* Address of the event log area */ - -} ACPI_TABLE_TCPA; - - -/******************************************************************************* - * - * UEFI - UEFI Boot optimization Table - * - ******************************************************************************/ - -typedef struct acpi_table_uefi -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT8 Identifier[16]; /* UUID identifier */ - UINT16 DataOffset; /* Offset of remaining data in table */ - UINT8 Data; - -} ACPI_TABLE_UEFI; - - -/******************************************************************************* - * - * WDAT - Watchdog Action Table - * - ******************************************************************************/ - -typedef struct acpi_table_wdat -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT32 HeaderLength; /* Watchdog Header Length */ - UINT16 PciSegment; /* PCI Segment number */ - UINT8 PciBus; /* PCI Bus number */ - UINT8 PciDevice; /* PCI Device number */ - UINT8 PciFunction; /* PCI Function number */ - UINT8 Reserved[3]; - UINT32 TimerPeriod; /* Period of one timer count (msec) */ - UINT32 MaxCount; /* Maximum counter value supported */ - UINT32 MinCount; /* Minimum counter value */ - UINT8 Flags; - UINT8 Reserved2[3]; - UINT32 Entries; /* Number of watchdog entries that follow */ - -} ACPI_TABLE_WDAT; - -/* WDAT Instruction Entries (actions) */ - -typedef struct acpi_wdat_entry -{ - ACPI_WHEA_HEADER WheaHeader; /* Common header for WHEA tables */ - -} ACPI_WDAT_ENTRY; - -/* Values for Action field above */ - -enum AcpiWdatActions -{ - ACPI_WDAT_RESET = 1, - ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4, - ACPI_WDAT_GET_COUNTDOWN = 5, - ACPI_WDAT_SET_COUNTDOWN = 6, - ACPI_WDAT_GET_RUNNING_STATE = 8, - ACPI_WDAT_SET_RUNNING_STATE = 9, - ACPI_WDAT_GET_STOPPED_STATE = 10, - ACPI_WDAT_SET_STOPPED_STATE = 11, - ACPI_WDAT_GET_REBOOT = 16, - ACPI_WDAT_SET_REBOOT = 17, - ACPI_WDAT_GET_SHUTDOWN = 18, - ACPI_WDAT_SET_SHUTDOWN = 19, - ACPI_WDAT_GET_STATUS = 32, - ACPI_WDAT_SET_STATUS = 33, - ACPI_WDAT_ACTION_RESERVED = 34 /* 34 and greater are reserved */ -}; - -/* Values for Instruction field above */ - -enum AcpiWdatInstructions -{ - ACPI_WDAT_READ_VALUE = 0, - ACPI_WDAT_READ_COUNTDOWN = 1, - ACPI_WDAT_WRITE_VALUE = 2, - ACPI_WDAT_WRITE_COUNTDOWN = 3, - ACPI_WDAT_INSTRUCTION_RESERVED = 4, /* 4 and greater are reserved */ - ACPI_WDAT_PRESERVE_REGISTER = 0x80 /* Except for this value */ -}; - - -/******************************************************************************* - * - * WDRT - Watchdog Resource Table - * - ******************************************************************************/ - -typedef struct acpi_table_wdrt -{ - ACPI_TABLE_HEADER Header; /* Common ACPI table header */ - UINT32 HeaderLength; /* Watchdog Header Length */ - UINT8 PciSegment; /* PCI Segment number */ - UINT8 PciBus; /* PCI Bus number */ - UINT8 PciDevice; /* PCI Device number */ - UINT8 PciFunction; /* PCI Function number */ - UINT32 TimerPeriod; /* Period of one timer count (msec) */ - UINT32 MaxCount; /* Maximum counter value supported */ - UINT32 MinCount; /* Minimum counter value */ - UINT8 Flags; - UINT8 Reserved[3]; - UINT32 Entries; /* Number of watchdog entries that follow */ - -} ACPI_TABLE_WDRT; - -/* Flags */ - -#define ACPI_WDRT_TIMER_ENABLED (1) /* 00: Timer enabled */ - - /* Reset to default packing */ #pragma pack() diff --git a/sys/contrib/dev/acpica/include/actbl2.h b/sys/contrib/dev/acpica/include/actbl2.h new file mode 100644 index 00000000000..c96715d3c05 --- /dev/null +++ b/sys/contrib/dev/acpica/include/actbl2.h @@ -0,0 +1,1124 @@ +/****************************************************************************** + * + * Name: actbl2.h - ACPI Specification Revision 2.0 Tables + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2010, 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. + * + *****************************************************************************/ + +#ifndef __ACTBL2_H__ +#define __ACTBL2_H__ + + +/******************************************************************************* + * + * Additional ACPI Tables (2) + * + * These tables are not consumed directly by the ACPICA subsystem, but are + * included here to support device drivers and the AML disassembler. + * + * The tables in this file are defined by third-party specifications, and are + * not defined directly by the ACPI specification itself. + * + ******************************************************************************/ + + +/* + * Values for description table header signatures for tables defined in this + * file. Useful because they make it more difficult to inadvertently type in + * the wrong signature. + */ +#define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ +#define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ +#define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ +#define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ +#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ +#define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */ +#define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */ +#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ +#define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */ +#define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ +#define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ +#define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ +#define ACPI_SIG_UEFI "UEFI" /* Uefi Boot Optimization Table */ +#define ACPI_SIG_WAET "WAET" /* Windows ACPI Emulated devices Table */ +#define ACPI_SIG_WDAT "WDAT" /* Watchdog Action Table */ +#define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ + + +/* + * All tables must be byte-packed to match the ACPI specification, since + * the tables are provided by the system BIOS. + */ +#pragma pack(1) + +/* + * Note about bitfields: The UINT8 type is used for bitfields in ACPI tables. + * This is the only type that is even remotely portable. Anything else is not + * portable, so do not use any other bitfield types. + */ + + +/******************************************************************************* + * + * ASF - Alert Standard Format table (Signature "ASF!") + * Revision 0x10 + * + * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003 + * + ******************************************************************************/ + +typedef struct acpi_table_asf +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + +} ACPI_TABLE_ASF; + + +/* ASF subtable header */ + +typedef struct acpi_asf_header +{ + UINT8 Type; + UINT8 Reserved; + UINT16 Length; + +} ACPI_ASF_HEADER; + + +/* Values for Type field above */ + +enum AcpiAsfType +{ + ACPI_ASF_TYPE_INFO = 0, + ACPI_ASF_TYPE_ALERT = 1, + ACPI_ASF_TYPE_CONTROL = 2, + ACPI_ASF_TYPE_BOOT = 3, + ACPI_ASF_TYPE_ADDRESS = 4, + ACPI_ASF_TYPE_RESERVED = 5 +}; + +/* + * ASF subtables + */ + +/* 0: ASF Information */ + +typedef struct acpi_asf_info +{ + ACPI_ASF_HEADER Header; + UINT8 MinResetValue; + UINT8 MinPollInterval; + UINT16 SystemId; + UINT32 MfgId; + UINT8 Flags; + UINT8 Reserved2[3]; + +} ACPI_ASF_INFO; + +/* Masks for Flags field above */ + +#define ACPI_ASF_SMBUS_PROTOCOLS (1) + + +/* 1: ASF Alerts */ + +typedef struct acpi_asf_alert +{ + ACPI_ASF_HEADER Header; + UINT8 AssertMask; + UINT8 DeassertMask; + UINT8 Alerts; + UINT8 DataLength; + +} ACPI_ASF_ALERT; + +typedef struct acpi_asf_alert_data +{ + UINT8 Address; + UINT8 Command; + UINT8 Mask; + UINT8 Value; + UINT8 SensorType; + UINT8 Type; + UINT8 Offset; + UINT8 SourceType; + UINT8 Severity; + UINT8 SensorNumber; + UINT8 Entity; + UINT8 Instance; + +} ACPI_ASF_ALERT_DATA; + + +/* 2: ASF Remote Control */ + +typedef struct acpi_asf_remote +{ + ACPI_ASF_HEADER Header; + UINT8 Controls; + UINT8 DataLength; + UINT16 Reserved2; + +} ACPI_ASF_REMOTE; + +typedef struct acpi_asf_control_data +{ + UINT8 Function; + UINT8 Address; + UINT8 Command; + UINT8 Value; + +} ACPI_ASF_CONTROL_DATA; + + +/* 3: ASF RMCP Boot Options */ + +typedef struct acpi_asf_rmcp +{ + ACPI_ASF_HEADER Header; + UINT8 Capabilities[7]; + UINT8 CompletionCode; + UINT32 EnterpriseId; + UINT8 Command; + UINT16 Parameter; + UINT16 BootOptions; + UINT16 OemParameters; + +} ACPI_ASF_RMCP; + + +/* 4: ASF Address */ + +typedef struct acpi_asf_address +{ + ACPI_ASF_HEADER Header; + UINT8 EpromAddress; + UINT8 Devices; + +} ACPI_ASF_ADDRESS; + + +/******************************************************************************* + * + * BOOT - Simple Boot Flag Table + * Version 1 + * + * Conforms to the "Simple Boot Flag Specification", Version 2.1 + * + ******************************************************************************/ + +typedef struct acpi_table_boot +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT8 CmosIndex; /* Index in CMOS RAM for the boot register */ + UINT8 Reserved[3]; + +} ACPI_TABLE_BOOT; + + +/******************************************************************************* + * + * DBGP - Debug Port table + * Version 1 + * + * Conforms to the "Debug Port Specification", Version 1.00, 2/9/2000 + * + ******************************************************************************/ + +typedef struct acpi_table_dbgp +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT8 Type; /* 0=full 16550, 1=subset of 16550 */ + UINT8 Reserved[3]; + ACPI_GENERIC_ADDRESS DebugPort; + +} ACPI_TABLE_DBGP; + + +/******************************************************************************* + * + * DMAR - DMA Remapping table + * Version 1 + * + * Conforms to "Intel Virtualization Technology for Directed I/O", + * Version 1.2, Sept. 2008 + * + ******************************************************************************/ + +typedef struct acpi_table_dmar +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT8 Width; /* Host Address Width */ + UINT8 Flags; + UINT8 Reserved[10]; + +} ACPI_TABLE_DMAR; + +/* Masks for Flags field above */ + +#define ACPI_DMAR_INTR_REMAP (1) + + +/* DMAR subtable header */ + +typedef struct acpi_dmar_header +{ + UINT16 Type; + UINT16 Length; + +} ACPI_DMAR_HEADER; + +/* Values for subtable type in ACPI_DMAR_HEADER */ + +enum AcpiDmarType +{ + ACPI_DMAR_TYPE_HARDWARE_UNIT = 0, + ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, + ACPI_DMAR_TYPE_ATSR = 2, + ACPI_DMAR_HARDWARE_AFFINITY = 3, + ACPI_DMAR_TYPE_RESERVED = 4 /* 4 and greater are reserved */ +}; + + +/* DMAR Device Scope structure */ + +typedef struct acpi_dmar_device_scope +{ + UINT8 EntryType; + UINT8 Length; + UINT16 Reserved; + UINT8 EnumerationId; + UINT8 Bus; + +} ACPI_DMAR_DEVICE_SCOPE; + +/* Values for EntryType in ACPI_DMAR_DEVICE_SCOPE */ + +enum AcpiDmarScopeType +{ + ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0, + ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1, + ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2, + ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3, + ACPI_DMAR_SCOPE_TYPE_HPET = 4, + ACPI_DMAR_SCOPE_TYPE_RESERVED = 5 /* 5 and greater are reserved */ +}; + +typedef struct acpi_dmar_pci_path +{ + UINT8 Device; + UINT8 Function; + +} ACPI_DMAR_PCI_PATH; + + +/* + * DMAR Sub-tables, correspond to Type in ACPI_DMAR_HEADER + */ + +/* 0: Hardware Unit Definition */ + +typedef struct acpi_dmar_hardware_unit +{ + ACPI_DMAR_HEADER Header; + UINT8 Flags; + UINT8 Reserved; + UINT16 Segment; + UINT64 Address; /* Register Base Address */ + +} ACPI_DMAR_HARDWARE_UNIT; + +/* Masks for Flags field above */ + +#define ACPI_DMAR_INCLUDE_ALL (1) + + +/* 1: Reserved Memory Defininition */ + +typedef struct acpi_dmar_reserved_memory +{ + ACPI_DMAR_HEADER Header; + UINT16 Reserved; + UINT16 Segment; + UINT64 BaseAddress; /* 4K aligned base address */ + UINT64 EndAddress; /* 4K aligned limit address */ + +} ACPI_DMAR_RESERVED_MEMORY; + +/* Masks for Flags field above */ + +#define ACPI_DMAR_ALLOW_ALL (1) + + +/* 2: Root Port ATS Capability Reporting Structure */ + +typedef struct acpi_dmar_atsr +{ + ACPI_DMAR_HEADER Header; + UINT8 Flags; + UINT8 Reserved; + UINT16 Segment; + +} ACPI_DMAR_ATSR; + +/* Masks for Flags field above */ + +#define ACPI_DMAR_ALL_PORTS (1) + + +/* 3: Remapping Hardware Static Affinity Structure */ + +typedef struct acpi_dmar_rhsa +{ + ACPI_DMAR_HEADER Header; + UINT32 Reserved; + UINT64 BaseAddress; + UINT32 ProximityDomain; + +} ACPI_DMAR_RHSA; + + +/******************************************************************************* + * + * HPET - High Precision Event Timer table + * Version 1 + * + * Conforms to "IA-PC HPET (High Precision Event Timers) Specification", + * Version 1.0a, October 2004 + * + ******************************************************************************/ + +typedef struct acpi_table_hpet +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT32 Id; /* Hardware ID of event timer block */ + ACPI_GENERIC_ADDRESS Address; /* Address of event timer block */ + UINT8 Sequence; /* HPET sequence number */ + UINT16 MinimumTick; /* Main counter min tick, periodic mode */ + UINT8 Flags; + +} ACPI_TABLE_HPET; + +/* Masks for Flags field above */ + +#define ACPI_HPET_PAGE_PROTECT_MASK (3) + +/* Values for Page Protect flags */ + +enum AcpiHpetPageProtect +{ + ACPI_HPET_NO_PAGE_PROTECT = 0, + ACPI_HPET_PAGE_PROTECT4 = 1, + ACPI_HPET_PAGE_PROTECT64 = 2 +}; + + +/******************************************************************************* + * + * IBFT - Boot Firmware Table + * Version 1 + * + * Conforms to "iSCSI Boot Firmware Table (iBFT) as Defined in ACPI 3.0b + * Specification", Version 1.01, March 1, 2007 + * + * Note: It appears that this table is not intended to appear in the RSDT/XSDT. + * Therefore, it is not currently supported by the disassembler. + * + ******************************************************************************/ + +typedef struct acpi_table_ibft +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT8 Reserved[12]; + +} ACPI_TABLE_IBFT; + + +/* IBFT common subtable header */ + +typedef struct acpi_ibft_header +{ + UINT8 Type; + UINT8 Version; + UINT16 Length; + UINT8 Index; + UINT8 Flags; + +} ACPI_IBFT_HEADER; + +/* Values for Type field above */ + +enum AcpiIbftType +{ + ACPI_IBFT_TYPE_NOT_USED = 0, + ACPI_IBFT_TYPE_CONTROL = 1, + ACPI_IBFT_TYPE_INITIATOR = 2, + ACPI_IBFT_TYPE_NIC = 3, + ACPI_IBFT_TYPE_TARGET = 4, + ACPI_IBFT_TYPE_EXTENSIONS = 5, + ACPI_IBFT_TYPE_RESERVED = 6 /* 6 and greater are reserved */ +}; + + +/* IBFT subtables */ + +typedef struct acpi_ibft_control +{ + ACPI_IBFT_HEADER Header; + UINT16 Extensions; + UINT16 InitiatorOffset; + UINT16 Nic0Offset; + UINT16 Target0Offset; + UINT16 Nic1Offset; + UINT16 Target1Offset; + +} ACPI_IBFT_CONTROL; + +typedef struct acpi_ibft_initiator +{ + ACPI_IBFT_HEADER Header; + UINT8 SnsServer[16]; + UINT8 SlpServer[16]; + UINT8 PrimaryServer[16]; + UINT8 SecondaryServer[16]; + UINT16 NameLength; + UINT16 NameOffset; + +} ACPI_IBFT_INITIATOR; + +typedef struct acpi_ibft_nic +{ + ACPI_IBFT_HEADER Header; + UINT8 IpAddress[16]; + UINT8 SubnetMaskPrefix; + UINT8 Origin; + UINT8 Gateway[16]; + UINT8 PrimaryDns[16]; + UINT8 SecondaryDns[16]; + UINT8 Dhcp[16]; + UINT16 Vlan; + UINT8 MacAddress[6]; + UINT16 PciAddress; + UINT16 NameLength; + UINT16 NameOffset; + +} ACPI_IBFT_NIC; + +typedef struct acpi_ibft_target +{ + ACPI_IBFT_HEADER Header; + UINT8 TargetIpAddress[16]; + UINT16 TargetIpSocket; + UINT8 TargetBootLun[8]; + UINT8 ChapType; + UINT8 NicAssociation; + UINT16 TargetNameLength; + UINT16 TargetNameOffset; + UINT16 ChapNameLength; + UINT16 ChapNameOffset; + UINT16 ChapSecretLength; + UINT16 ChapSecretOffset; + UINT16 ReverseChapNameLength; + UINT16 ReverseChapNameOffset; + UINT16 ReverseChapSecretLength; + UINT16 ReverseChapSecretOffset; + +} ACPI_IBFT_TARGET; + + +/******************************************************************************* + * + * IVRS - I/O Virtualization Reporting Structure + * Version 1 + * + * Conforms to "AMD I/O Virtualization Technology (IOMMU) Specification", + * Revision 1.26, February 2009. + * + ******************************************************************************/ + +typedef struct acpi_table_ivrs +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT32 Info; /* Common virtualization info */ + UINT64 Reserved; + +} ACPI_TABLE_IVRS; + +/* Values for Info field above */ + +#define ACPI_IVRS_PHYSICAL_SIZE 0x00007F00 /* 7 bits, physical address size */ +#define ACPI_IVRS_VIRTUAL_SIZE 0x003F8000 /* 7 bits, virtual address size */ +#define ACPI_IVRS_ATS_RESERVED 0x00400000 /* ATS address translation range reserved */ + + +/* IVRS subtable header */ + +typedef struct acpi_ivrs_header +{ + UINT8 Type; /* Subtable type */ + UINT8 Flags; + UINT16 Length; /* Subtable length */ + UINT16 DeviceId; /* ID of IOMMU */ + +} ACPI_IVRS_HEADER; + +/* Values for subtable Type above */ + +enum AcpiIvrsType +{ + ACPI_IVRS_TYPE_HARDWARE = 0x10, + ACPI_IVRS_TYPE_MEMORY1 = 0x20, + ACPI_IVRS_TYPE_MEMORY2 = 0x21, + ACPI_IVRS_TYPE_MEMORY3 = 0x22 +}; + +/* Masks for Flags field above for IVHD subtable */ + +#define ACPI_IVHD_TT_ENABLE (1) +#define ACPI_IVHD_PASS_PW (1<<1) +#define ACPI_IVHD_RES_PASS_PW (1<<2) +#define ACPI_IVHD_ISOC (1<<3) +#define ACPI_IVHD_IOTLB (1<<4) + +/* Masks for Flags field above for IVMD subtable */ + +#define ACPI_IVMD_UNITY (1) +#define ACPI_IVMD_READ (1<<1) +#define ACPI_IVMD_WRITE (1<<2) +#define ACPI_IVMD_EXCLUSION_RANGE (1<<3) + + +/* + * IVRS subtables, correspond to Type in ACPI_IVRS_HEADER + */ + +/* 0x10: I/O Virtualization Hardware Definition Block (IVHD) */ + +typedef struct acpi_ivrs_hardware +{ + ACPI_IVRS_HEADER Header; + UINT16 CapabilityOffset; /* Offset for IOMMU control fields */ + UINT64 BaseAddress; /* IOMMU control registers */ + UINT16 PciSegmentGroup; + UINT16 Info; /* MSI number and unit ID */ + UINT32 Reserved; + +} ACPI_IVRS_HARDWARE; + +/* Masks for Info field above */ + +#define ACPI_IVHD_MSI_NUMBER_MASK 0x001F /* 5 bits, MSI message number */ +#define ACPI_IVHD_UNIT_ID_MASK 0x1F00 /* 5 bits, UnitID */ + + +/* + * Device Entries for IVHD subtable, appear after ACPI_IVRS_HARDWARE structure. + * Upper two bits of the Type field are the (encoded) length of the structure. + * Currently, only 4 and 8 byte entries are defined. 16 and 32 byte entries + * are reserved for future use but not defined. + */ +typedef struct acpi_ivrs_de_header +{ + UINT8 Type; + UINT16 Id; + UINT8 DataSetting; + +} ACPI_IVRS_DE_HEADER; + +/* Length of device entry is in the top two bits of Type field above */ + +#define ACPI_IVHD_ENTRY_LENGTH 0xC0 + +/* Values for device entry Type field above */ + +enum AcpiIvrsDeviceEntryType +{ + /* 4-byte device entries, all use ACPI_IVRS_DEVICE4 */ + + ACPI_IVRS_TYPE_PAD4 = 0, + ACPI_IVRS_TYPE_ALL = 1, + ACPI_IVRS_TYPE_SELECT = 2, + ACPI_IVRS_TYPE_START = 3, + ACPI_IVRS_TYPE_END = 4, + + /* 8-byte device entries */ + + ACPI_IVRS_TYPE_PAD8 = 64, + ACPI_IVRS_TYPE_NOT_USED = 65, + ACPI_IVRS_TYPE_ALIAS_SELECT = 66, /* Uses ACPI_IVRS_DEVICE8A */ + ACPI_IVRS_TYPE_ALIAS_START = 67, /* Uses ACPI_IVRS_DEVICE8A */ + ACPI_IVRS_TYPE_EXT_SELECT = 70, /* Uses ACPI_IVRS_DEVICE8B */ + ACPI_IVRS_TYPE_EXT_START = 71, /* Uses ACPI_IVRS_DEVICE8B */ + ACPI_IVRS_TYPE_SPECIAL = 72 /* Uses ACPI_IVRS_DEVICE8C */ +}; + +/* Values for Data field above */ + +#define ACPI_IVHD_INIT_PASS (1) +#define ACPI_IVHD_EINT_PASS (1<<1) +#define ACPI_IVHD_NMI_PASS (1<<2) +#define ACPI_IVHD_SYSTEM_MGMT (3<<4) +#define ACPI_IVHD_LINT0_PASS (1<<6) +#define ACPI_IVHD_LINT1_PASS (1<<7) + + +/* Types 0-4: 4-byte device entry */ + +typedef struct acpi_ivrs_device4 +{ + ACPI_IVRS_DE_HEADER Header; + +} ACPI_IVRS_DEVICE4; + +/* Types 66-67: 8-byte device entry */ + +typedef struct acpi_ivrs_device8a +{ + ACPI_IVRS_DE_HEADER Header; + UINT8 Reserved1; + UINT16 UsedId; + UINT8 Reserved2; + +} ACPI_IVRS_DEVICE8A; + +/* Types 70-71: 8-byte device entry */ + +typedef struct acpi_ivrs_device8b +{ + ACPI_IVRS_DE_HEADER Header; + UINT32 ExtendedData; + +} ACPI_IVRS_DEVICE8B; + +/* Values for ExtendedData above */ + +#define ACPI_IVHD_ATS_DISABLED (1<<31) + +/* Type 72: 8-byte device entry */ + +typedef struct acpi_ivrs_device8c +{ + ACPI_IVRS_DE_HEADER Header; + UINT8 Handle; + UINT16 UsedId; + UINT8 Variety; + +} ACPI_IVRS_DEVICE8C; + +/* Values for Variety field above */ + +#define ACPI_IVHD_IOAPIC 1 +#define ACPI_IVHD_HPET 2 + + +/* 0x20, 0x21, 0x22: I/O Virtualization Memory Definition Block (IVMD) */ + +typedef struct acpi_ivrs_memory +{ + ACPI_IVRS_HEADER Header; + UINT16 AuxData; + UINT64 Reserved; + UINT64 StartAddress; + UINT64 MemoryLength; + +} ACPI_IVRS_MEMORY; + + +/******************************************************************************* + * + * MCFG - PCI Memory Mapped Configuration table and sub-table + * Version 1 + * + * Conforms to "PCI Firmware Specification", Revision 3.0, June 20, 2005 + * + ******************************************************************************/ + +typedef struct acpi_table_mcfg +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT8 Reserved[8]; + +} ACPI_TABLE_MCFG; + + +/* Subtable */ + +typedef struct acpi_mcfg_allocation +{ + UINT64 Address; /* Base address, processor-relative */ + UINT16 PciSegment; /* PCI segment group number */ + UINT8 StartBusNumber; /* Starting PCI Bus number */ + UINT8 EndBusNumber; /* Final PCI Bus number */ + UINT32 Reserved; + +} ACPI_MCFG_ALLOCATION; + + +/******************************************************************************* + * + * SPCR - Serial Port Console Redirection table + * Version 1 + * + * Conforms to "Serial Port Console Redirection Table", + * Version 1.00, January 11, 2002 + * + ******************************************************************************/ + +typedef struct acpi_table_spcr +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT8 InterfaceType; /* 0=full 16550, 1=subset of 16550 */ + UINT8 Reserved[3]; + ACPI_GENERIC_ADDRESS SerialPort; + UINT8 InterruptType; + UINT8 PcInterrupt; + UINT32 Interrupt; + UINT8 BaudRate; + UINT8 Parity; + UINT8 StopBits; + UINT8 FlowControl; + UINT8 TerminalType; + UINT8 Reserved1; + UINT16 PciDeviceId; + UINT16 PciVendorId; + UINT8 PciBus; + UINT8 PciDevice; + UINT8 PciFunction; + UINT32 PciFlags; + UINT8 PciSegment; + UINT32 Reserved2; + +} ACPI_TABLE_SPCR; + +/* Masks for PciFlags field above */ + +#define ACPI_SPCR_DO_NOT_DISABLE (1) + + +/******************************************************************************* + * + * SPMI - Server Platform Management Interface table + * Version 5 + * + * Conforms to "Intelligent Platform Management Interface Specification + * Second Generation v2.0", Document Revision 1.0, February 12, 2004 with + * June 12, 2009 markup. + * + ******************************************************************************/ + +typedef struct acpi_table_spmi +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT8 InterfaceType; + UINT8 Reserved; /* Must be 1 */ + UINT16 SpecRevision; /* Version of IPMI */ + UINT8 InterruptType; + UINT8 GpeNumber; /* GPE assigned */ + UINT8 Reserved1; + UINT8 PciDeviceFlag; + UINT32 Interrupt; + ACPI_GENERIC_ADDRESS IpmiRegister; + UINT8 PciSegment; + UINT8 PciBus; + UINT8 PciDevice; + UINT8 PciFunction; + UINT8 Reserved2; + +} ACPI_TABLE_SPMI; + +/* Values for InterfaceType above */ + +enum AcpiSpmiInterfaceTypes +{ + ACPI_SPMI_NOT_USED = 0, + ACPI_SPMI_KEYBOARD = 1, + ACPI_SPMI_SMI = 2, + ACPI_SPMI_BLOCK_TRANSFER = 3, + ACPI_SPMI_SMBUS = 4, + ACPI_SPMI_RESERVED = 5 /* 5 and above are reserved */ +}; + + +/******************************************************************************* + * + * TCPA - Trusted Computing Platform Alliance table + * Version 1 + * + * Conforms to "TCG PC Specific Implementation Specification", + * Version 1.1, August 18, 2003 + * + ******************************************************************************/ + +typedef struct acpi_table_tcpa +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT16 Reserved; + UINT32 MaxLogLength; /* Maximum length for the event log area */ + UINT64 LogAddress; /* Address of the event log area */ + +} ACPI_TABLE_TCPA; + + +/******************************************************************************* + * + * UEFI - UEFI Boot optimization Table + * Version 1 + * + * Conforms to "Unified Extensible Firmware Interface Specification", + * Version 2.3, May 8, 2009 + * + ******************************************************************************/ + +typedef struct acpi_table_uefi +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT8 Identifier[16]; /* UUID identifier */ + UINT16 DataOffset; /* Offset of remaining data in table */ + +} ACPI_TABLE_UEFI; + + +/******************************************************************************* + * + * WAET - Windows ACPI Emulated devices Table + * Version 1 + * + * Conforms to "Windows ACPI Emulated Devices Table", version 1.0, April 6, 2009 + * + ******************************************************************************/ + +typedef struct acpi_table_waet +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT32 Flags; + +} ACPI_TABLE_WAET; + +/* Masks for Flags field above */ + +#define ACPI_WAET_RTC_NO_ACK (1) /* RTC requires no int acknowledge */ +#define ACPI_WAET_TIMER_ONE_READ (1<<1) /* PM timer requires only one read */ + + +/******************************************************************************* + * + * WDAT - Watchdog Action Table + * Version 1 + * + * Conforms to "Hardware Watchdog Timers Design Specification", + * Copyright 2006 Microsoft Corporation. + * + ******************************************************************************/ + +typedef struct acpi_table_wdat +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + UINT32 HeaderLength; /* Watchdog Header Length */ + UINT16 PciSegment; /* PCI Segment number */ + UINT8 PciBus; /* PCI Bus number */ + UINT8 PciDevice; /* PCI Device number */ + UINT8 PciFunction; /* PCI Function number */ + UINT8 Reserved[3]; + UINT32 TimerPeriod; /* Period of one timer count (msec) */ + UINT32 MaxCount; /* Maximum counter value supported */ + UINT32 MinCount; /* Minimum counter value */ + UINT8 Flags; + UINT8 Reserved2[3]; + UINT32 Entries; /* Number of watchdog entries that follow */ + +} ACPI_TABLE_WDAT; + +/* Masks for Flags field above */ + +#define ACPI_WDAT_ENABLED (1) +#define ACPI_WDAT_STOPPED 0x80 + + +/* WDAT Instruction Entries (actions) */ + +typedef struct acpi_wdat_entry +{ + UINT8 Action; + UINT8 Instruction; + UINT16 Reserved; + ACPI_GENERIC_ADDRESS RegisterRegion; + UINT32 Value; /* Value used with Read/Write register */ + UINT32 Mask; /* Bitmask required for this register instruction */ + +} ACPI_WDAT_ENTRY; + +/* Values for Action field above */ + +enum AcpiWdatActions +{ + ACPI_WDAT_RESET = 1, + ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4, + ACPI_WDAT_GET_COUNTDOWN = 5, + ACPI_WDAT_SET_COUNTDOWN = 6, + ACPI_WDAT_GET_RUNNING_STATE = 8, + ACPI_WDAT_SET_RUNNING_STATE = 9, + ACPI_WDAT_GET_STOPPED_STATE = 10, + ACPI_WDAT_SET_STOPPED_STATE = 11, + ACPI_WDAT_GET_REBOOT = 16, + ACPI_WDAT_SET_REBOOT = 17, + ACPI_WDAT_GET_SHUTDOWN = 18, + ACPI_WDAT_SET_SHUTDOWN = 19, + ACPI_WDAT_GET_STATUS = 32, + ACPI_WDAT_SET_STATUS = 33, + ACPI_WDAT_ACTION_RESERVED = 34 /* 34 and greater are reserved */ +}; + +/* Values for Instruction field above */ + +enum AcpiWdatInstructions +{ + ACPI_WDAT_READ_VALUE = 0, + ACPI_WDAT_READ_COUNTDOWN = 1, + ACPI_WDAT_WRITE_VALUE = 2, + ACPI_WDAT_WRITE_COUNTDOWN = 3, + ACPI_WDAT_INSTRUCTION_RESERVED = 4, /* 4 and greater are reserved */ + ACPI_WDAT_PRESERVE_REGISTER = 0x80 /* Except for this value */ +}; + + +/******************************************************************************* + * + * WDRT - Watchdog Resource Table + * Version 1 + * + * Conforms to "Watchdog Timer Hardware Requirements for Windows Server 2003", + * Version 1.01, August 28, 2006 + * + ******************************************************************************/ + +typedef struct acpi_table_wdrt +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + ACPI_GENERIC_ADDRESS ControlRegister; + ACPI_GENERIC_ADDRESS CountRegister; + UINT16 PciDeviceId; + UINT16 PciVendorId; + UINT8 PciBus; /* PCI Bus number */ + UINT8 PciDevice; /* PCI Device number */ + UINT8 PciFunction; /* PCI Function number */ + UINT8 PciSegment; /* PCI Segment number */ + UINT16 MaxCount; /* Maximum counter value supported */ + UINT8 Units; + +} ACPI_TABLE_WDRT; + + +/* Reset to default packing */ + +#pragma pack() + +#endif /* __ACTBL2_H__ */ + diff --git a/sys/contrib/dev/acpica/include/actypes.h b/sys/contrib/dev/acpica/include/actypes.h index 8f970d97296..8d0d06ad62c 100644 --- a/sys/contrib/dev/acpica/include/actypes.h +++ b/sys/contrib/dev/acpica/include/actypes.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -415,7 +415,7 @@ typedef UINT32 ACPI_PHYSICAL_ADDRESS; /* PM Timer ticks per second (HZ) */ -#define PM_TIMER_FREQUENCY 3579545 +#define PM_TIMER_FREQUENCY 3579545 /******************************************************************************* @@ -470,22 +470,7 @@ typedef union uint64_overlay } UINT64_OVERLAY; -typedef struct uint32_struct -{ - UINT32 Lo; - UINT32 Hi; -} UINT32_STRUCT; - - -/* - * Acpi integer width. In ACPI version 1, integers are 32 bits. In ACPI - * version 2, integers are 64 bits. Note that this pertains to the ACPI integer - * type only, not other integers used in the implementation of the ACPI CA - * subsystem. - */ -typedef UINT64 ACPI_INTEGER; -#define ACPI_INTEGER_MAX ACPI_UINT64_MAX #define ACPI_INTEGER_BIT_SIZE 64 #define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */ #define ACPI_MAX64_DECIMAL_DIGITS 20 @@ -500,6 +485,19 @@ typedef UINT64 ACPI_INTEGER; #define ACPI_WAIT_FOREVER 0xFFFF /* UINT16, as per ACPI spec */ #define ACPI_DO_NOT_WAIT 0 +/* + * Obsolete: Acpi integer width. In ACPI version 1 (1996), integers are 32 bits. + * In ACPI version 2 (2000) and later, integers are 64 bits. Note that this + * pertains to the ACPI integer type only, not to other integers used in the + * implementation of the ACPICA subsystem. + * + * 01/2010: This type is obsolete and has been removed from the entire ACPICA + * code base. It remains here for compatibility with device drivers that use + * the type. However, it will be removed in the future. + */ +typedef UINT64 ACPI_INTEGER; +#define ACPI_INTEGER_MAX ACPI_UINT64_MAX + /******************************************************************************* * @@ -816,7 +814,8 @@ typedef UINT8 ACPI_ADR_SPACE_TYPE; #define ACPI_ADR_SPACE_SMBUS (ACPI_ADR_SPACE_TYPE) 4 #define ACPI_ADR_SPACE_CMOS (ACPI_ADR_SPACE_TYPE) 5 #define ACPI_ADR_SPACE_PCI_BAR_TARGET (ACPI_ADR_SPACE_TYPE) 6 -#define ACPI_ADR_SPACE_DATA_TABLE (ACPI_ADR_SPACE_TYPE) 7 +#define ACPI_ADR_SPACE_IPMI (ACPI_ADR_SPACE_TYPE) 7 +#define ACPI_ADR_SPACE_DATA_TABLE (ACPI_ADR_SPACE_TYPE) 8 #define ACPI_ADR_SPACE_FIXED_HARDWARE (ACPI_ADR_SPACE_TYPE) 127 @@ -889,7 +888,7 @@ typedef union acpi_object struct { ACPI_OBJECT_TYPE Type; /* ACPI_TYPE_INTEGER */ - ACPI_INTEGER Value; /* The actual number */ + UINT64 Value; /* The actual number */ } Integer; struct @@ -1056,7 +1055,6 @@ void (*ACPI_NOTIFY_HANDLER) ( typedef void (*ACPI_OBJECT_HANDLER) ( ACPI_HANDLE Object, - UINT32 Function, void *Data); typedef @@ -1094,7 +1092,7 @@ ACPI_STATUS (*ACPI_ADR_SPACE_HANDLER) ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); @@ -1123,46 +1121,67 @@ ACPI_STATUS (*ACPI_WALK_CALLBACK) ( #define ACPI_INTERRUPT_NOT_HANDLED 0x00 #define ACPI_INTERRUPT_HANDLED 0x01 +/* Length of 32-bit EISAID values when converted back to a string */ -/* Length of _HID, _UID, _CID, and UUID values */ +#define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */ + +/* Length of UUID (string) values */ -#define ACPI_DEVICE_ID_LENGTH 0x09 -#define ACPI_MAX_CID_LENGTH 48 #define ACPI_UUID_LENGTH 16 -/* Common string version of device HIDs and UIDs */ + +/* Structures used for device/processor HID, UID, CID */ typedef struct acpi_device_id { - char Value[ACPI_DEVICE_ID_LENGTH]; + UINT32 Length; /* Length of string + null */ + char *String; } ACPI_DEVICE_ID; -/* Common string version of device CIDs */ - -typedef struct acpi_compatible_id +typedef struct acpi_device_id_list { - char Value[ACPI_MAX_CID_LENGTH]; + UINT32 Count; /* Number of IDs in Ids array */ + UINT32 ListSize; /* Size of list, including ID strings */ + ACPI_DEVICE_ID Ids[1]; /* ID array */ -} ACPI_COMPATIBLE_ID; +} ACPI_DEVICE_ID_LIST; -typedef struct acpi_compatible_id_list +/* + * Structure returned from AcpiGetObjectInfo. + * Optimized for both 32- and 64-bit builds + */ +typedef struct acpi_device_info { - UINT32 Count; - UINT32 Size; - ACPI_COMPATIBLE_ID Id[1]; + UINT32 InfoSize; /* Size of info, including ID strings */ + UINT32 Name; /* ACPI object Name */ + ACPI_OBJECT_TYPE Type; /* ACPI object Type */ + UINT8 ParamCount; /* If a method, required parameter count */ + UINT8 Valid; /* Indicates which optional fields are valid */ + UINT8 Flags; /* Miscellaneous info */ + UINT8 HighestDstates[4]; /* _SxD values: 0xFF indicates not valid */ + UINT8 LowestDstates[5]; /* _SxW values: 0xFF indicates not valid */ + UINT32 CurrentStatus; /* _STA value */ + UINT64 Address; /* _ADR value */ + ACPI_DEVICE_ID HardwareId; /* _HID value */ + ACPI_DEVICE_ID UniqueId; /* _UID value */ + ACPI_DEVICE_ID_LIST CompatibleIdList; /* _CID list */ -} ACPI_COMPATIBLE_ID_LIST; +} ACPI_DEVICE_INFO; +/* Values for Flags field above (AcpiGetObjectInfo) */ -/* Structure and flags for AcpiGetObjectInfo */ +#define ACPI_PCI_ROOT_BRIDGE 0x01 -#define ACPI_VALID_STA 0x0001 -#define ACPI_VALID_ADR 0x0002 -#define ACPI_VALID_HID 0x0004 -#define ACPI_VALID_UID 0x0008 -#define ACPI_VALID_CID 0x0010 -#define ACPI_VALID_SXDS 0x0020 +/* Flags for Valid field above (AcpiGetObjectInfo) */ + +#define ACPI_VALID_STA 0x01 +#define ACPI_VALID_ADR 0x02 +#define ACPI_VALID_HID 0x04 +#define ACPI_VALID_UID 0x08 +#define ACPI_VALID_CID 0x10 +#define ACPI_VALID_SXDS 0x20 +#define ACPI_VALID_SXWS 0x40 /* Flags for _STA method */ @@ -1174,36 +1193,6 @@ typedef struct acpi_compatible_id_list #define ACPI_STA_BATTERY_PRESENT 0x10 -#define ACPI_COMMON_OBJ_INFO \ - ACPI_OBJECT_TYPE Type; /* ACPI object type */ \ - ACPI_NAME Name /* ACPI object Name */ - - -typedef struct acpi_obj_info_header -{ - ACPI_COMMON_OBJ_INFO; - -} ACPI_OBJ_INFO_HEADER; - - -/* Structure returned from Get Object Info */ - -typedef struct acpi_device_info -{ - ACPI_COMMON_OBJ_INFO; - - UINT32 ParamCount; /* If a method, required parameter count */ - UINT32 Valid; /* Indicates which fields below are valid */ - UINT32 CurrentStatus; /* _STA value */ - ACPI_INTEGER Address; /* _ADR value if any */ - ACPI_DEVICE_ID HardwareId; /* _HID value if any */ - ACPI_DEVICE_ID UniqueId; /* _UID value if any */ - UINT8 HighestDstates[4]; /* _SxD values: 0xFF indicates not valid */ - ACPI_COMPATIBLE_ID_LIST CompatibilityId; /* List of _CIDs if any */ - -} ACPI_DEVICE_INFO; - - /* Context structs for address space handlers */ typedef struct acpi_pci_id @@ -1215,7 +1204,6 @@ typedef struct acpi_pci_id } ACPI_PCI_ID; - typedef struct acpi_mem_space_context { UINT32 Length; diff --git a/sys/contrib/dev/acpica/include/acutils.h b/sys/contrib/dev/acpica/include/acutils.h index 5573754e89f..ae406c3882a 100644 --- a/sys/contrib/dev/acpica/include/acutils.h +++ b/sys/contrib/dev/acpica/include/acutils.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -235,7 +235,7 @@ AcpiUtGetEventName ( char AcpiUtHexToAsciiChar ( - ACPI_INTEGER Integer, + UINT64 Integer, UINT32 Position); BOOLEAN @@ -470,7 +470,7 @@ AcpiUtValueExit ( const char *FunctionName, const char *ModuleName, UINT32 ComponentId, - ACPI_INTEGER Value); + UINT64 Value); void AcpiUtPtrExit ( @@ -550,17 +550,7 @@ ACPI_STATUS AcpiUtEvaluateNumericObject ( char *ObjectName, ACPI_NAMESPACE_NODE *DeviceNode, - ACPI_INTEGER *Address); - -ACPI_STATUS -AcpiUtExecute_HID ( - ACPI_NAMESPACE_NODE *DeviceNode, - ACPI_DEVICE_ID *Hid); - -ACPI_STATUS -AcpiUtExecute_CID ( - ACPI_NAMESPACE_NODE *DeviceNode, - ACPI_COMPATIBLE_ID_LIST **ReturnCidList); + UINT64 *Value); ACPI_STATUS AcpiUtExecute_STA ( @@ -568,14 +558,31 @@ AcpiUtExecute_STA ( UINT32 *StatusFlags); ACPI_STATUS -AcpiUtExecute_UID ( +AcpiUtExecutePowerMethods ( ACPI_NAMESPACE_NODE *DeviceNode, - ACPI_DEVICE_ID *Uid); + const char **MethodNames, + UINT8 MethodCount, + UINT8 *OutValues); + + +/* + * utids - device ID support + */ +ACPI_STATUS +AcpiUtExecute_HID ( + ACPI_NAMESPACE_NODE *DeviceNode, + ACPI_DEVICE_ID **ReturnId); ACPI_STATUS -AcpiUtExecute_Sxds ( +AcpiUtExecute_UID ( ACPI_NAMESPACE_NODE *DeviceNode, - UINT8 *Highest); + ACPI_DEVICE_ID **ReturnId); + +ACPI_STATUS +AcpiUtExecute_CID ( + ACPI_NAMESPACE_NODE *DeviceNode, + ACPI_DEVICE_ID_LIST **ReturnCidList); + /* * utlock - reader/writer locks @@ -636,6 +643,10 @@ ACPI_OPERAND_OBJECT * AcpiUtCreatePackageObject ( UINT32 Count); +ACPI_OPERAND_OBJECT * +AcpiUtCreateIntegerObject ( + UINT64 Value); + ACPI_OPERAND_OBJECT * AcpiUtCreateBufferObject ( ACPI_SIZE BufferSize); @@ -709,16 +720,16 @@ AcpiUtDeleteGenericState ( */ ACPI_STATUS AcpiUtDivide ( - ACPI_INTEGER InDividend, - ACPI_INTEGER InDivisor, - ACPI_INTEGER *OutQuotient, - ACPI_INTEGER *OutRemainder); + UINT64 InDividend, + UINT64 InDivisor, + UINT64 *OutQuotient, + UINT64 *OutRemainder); ACPI_STATUS AcpiUtShortDivide ( - ACPI_INTEGER InDividend, + UINT64 InDividend, UINT32 Divisor, - ACPI_INTEGER *OutQuotient, + UINT64 *OutQuotient, UINT32 *OutRemainder); /* @@ -728,6 +739,10 @@ const char * AcpiUtValidateException ( ACPI_STATUS Status); +BOOLEAN +AcpiUtIsPciRootBridge ( + char *Id); + BOOLEAN AcpiUtIsAmlTable ( ACPI_TABLE_HEADER *Table); @@ -773,7 +788,25 @@ ACPI_STATUS AcpiUtStrtoul64 ( char *String, UINT32 Base, - ACPI_INTEGER *RetInteger); + UINT64 *RetInteger); + +void ACPI_INTERNAL_VAR_XFACE +AcpiUtPredefinedWarning ( + const char *ModuleName, + UINT32 LineNumber, + char *Pathname, + UINT8 NodeFlags, + const char *Format, + ...); + +void ACPI_INTERNAL_VAR_XFACE +AcpiUtPredefinedInfo ( + const char *ModuleName, + UINT32 LineNumber, + char *Pathname, + UINT8 NodeFlags, + const char *Format, + ...); /* Values for Base above (16=Hex, 10=Decimal) */ diff --git a/sys/contrib/dev/acpica/include/amlcode.h b/sys/contrib/dev/acpica/include/amlcode.h index 7694acc14cf..d6fc7d00ce3 100644 --- a/sys/contrib/dev/acpica/include/amlcode.h +++ b/sys/contrib/dev/acpica/include/amlcode.h @@ -10,7 +10,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -485,6 +485,7 @@ typedef enum REGION_SMBUS, REGION_CMOS, REGION_PCI_BAR, + REGION_IPMI, REGION_DATA_TABLE, /* Internal use only */ REGION_FIXED_HW = 0x7F diff --git a/sys/contrib/dev/acpica/include/amlresrc.h b/sys/contrib/dev/acpica/include/amlresrc.h index 689564c6289..9084e44540a 100644 --- a/sys/contrib/dev/acpica/include/amlresrc.h +++ b/sys/contrib/dev/acpica/include/amlresrc.h @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/platform/acenv.h b/sys/contrib/dev/acpica/include/platform/acenv.h index 7756fb71363..b9ef33fa4f4 100644 --- a/sys/contrib/dev/acpica/include/platform/acenv.h +++ b/sys/contrib/dev/acpica/include/platform/acenv.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -262,11 +262,11 @@ /* Global Lock acquire/release */ #ifndef ACPI_ACQUIRE_GLOBAL_LOCK -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) Acq = 1 +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acquired) Acquired = 1 #endif #ifndef ACPI_RELEASE_GLOBAL_LOCK -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) Acq = 0 +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Pending) Pending = 0 #endif /* Flush CPU cache - used when going to sleep. Wbinvd or similar. */ @@ -424,8 +424,8 @@ typedef char *va_list; #define ACPI_MEMCMP(s1,s2,n) AcpiUtMemcmp((const char *)(s1), (const char *)(s2), (ACPI_SIZE)(n)) #define ACPI_MEMCPY(d,s,n) (void) AcpiUtMemcpy ((d), (s), (ACPI_SIZE)(n)) #define ACPI_MEMSET(d,v,n) (void) AcpiUtMemset ((d), (v), (ACPI_SIZE)(n)) -#define ACPI_TOUPPER AcpiUtToUpper -#define ACPI_TOLOWER AcpiUtToLower +#define ACPI_TOUPPER(c) AcpiUtToUpper ((int) (c)) +#define ACPI_TOLOWER(c) AcpiUtToLower ((int) (c)) #endif /* ACPI_USE_SYSTEM_CLIBRARY */ diff --git a/sys/contrib/dev/acpica/include/platform/acfreebsd.h b/sys/contrib/dev/acpica/include/platform/acfreebsd.h index 8fea3cf97a0..20ec3a20bf9 100644 --- a/sys/contrib/dev/acpica/include/platform/acfreebsd.h +++ b/sys/contrib/dev/acpica/include/platform/acfreebsd.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/include/platform/acgcc.h b/sys/contrib/dev/acpica/include/platform/acgcc.h index 449942278c9..d0098b1800a 100644 --- a/sys/contrib/dev/acpica/include/platform/acgcc.h +++ b/sys/contrib/dev/acpica/include/platform/acgcc.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/namespace/nsaccess.c b/sys/contrib/dev/acpica/namespace/nsaccess.c index b7bc11c1eb1..e360e28370a 100644 --- a/sys/contrib/dev/acpica/namespace/nsaccess.c +++ b/sys/contrib/dev/acpica/namespace/nsaccess.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -251,7 +251,7 @@ AcpiNsRootInitialize ( /* Mark this as a very SPECIAL method */ ObjDesc->Method.MethodFlags = AML_METHOD_INTERNAL_ONLY; - ObjDesc->Method.Implementation = AcpiUtOsiImplementation; + ObjDesc->Method.Extra.Implementation = AcpiUtOsiImplementation; #endif break; diff --git a/sys/contrib/dev/acpica/namespace/nsalloc.c b/sys/contrib/dev/acpica/namespace/nsalloc.c index be8e1ffcea6..222977abac7 100644 --- a/sys/contrib/dev/acpica/namespace/nsalloc.c +++ b/sys/contrib/dev/acpica/namespace/nsalloc.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -181,20 +181,78 @@ AcpiNsCreateNode ( * * RETURN: None * - * DESCRIPTION: Delete a namespace node + * DESCRIPTION: Delete a namespace node. All node deletions must come through + * here. Detaches any attached objects, including any attached + * data. If a handler is associated with attached data, it is + * invoked before the node is deleted. * ******************************************************************************/ void AcpiNsDeleteNode ( ACPI_NAMESPACE_NODE *Node) +{ + ACPI_OPERAND_OBJECT *ObjDesc; + + + ACPI_FUNCTION_NAME (NsDeleteNode); + + + /* Detach an object if there is one */ + + AcpiNsDetachObject (Node); + + /* + * Delete an attached data object if present (an object that was created + * and attached via AcpiAttachData). Note: After any normal object is + * detached above, the only possible remaining object is a data object. + */ + ObjDesc = Node->Object; + if (ObjDesc && + (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA)) + { + /* Invoke the attached data deletion handler if present */ + + if (ObjDesc->Data.Handler) + { + ObjDesc->Data.Handler (Node, ObjDesc->Data.Pointer); + } + + AcpiUtRemoveReference (ObjDesc); + } + + /* Now we can delete the node */ + + (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node); + + ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n", + Node, AcpiGbl_CurrentNodeCount)); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsRemoveNode + * + * PARAMETERS: Node - Node to be removed/deleted + * + * RETURN: None + * + * DESCRIPTION: Remove (unlink) and delete a namespace node + * + ******************************************************************************/ + +void +AcpiNsRemoveNode ( + ACPI_NAMESPACE_NODE *Node) { ACPI_NAMESPACE_NODE *ParentNode; ACPI_NAMESPACE_NODE *PrevNode; ACPI_NAMESPACE_NODE *NextNode; - ACPI_FUNCTION_TRACE_PTR (NsDeleteNode, Node); + ACPI_FUNCTION_TRACE_PTR (NsRemoveNode, Node); ParentNode = AcpiNsGetParentNode (Node); @@ -237,12 +295,9 @@ AcpiNsDeleteNode ( } } - ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); + /* Delete the node and any attached objects */ - /* Detach an object if there is one, then delete the node */ - - AcpiNsDetachObject (Node); - (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node); + AcpiNsDeleteNode (Node); return_VOID; } @@ -385,23 +440,11 @@ AcpiNsDeleteChildren ( ParentNode, ChildNode)); } - /* Now we can free this child object */ - - ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); - - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", - ChildNode, AcpiGbl_CurrentNodeCount)); - - /* Detach an object if there is one, then free the child node */ - - AcpiNsDetachObject (ChildNode); - - /* Now we can delete the node */ - - (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, ChildNode); - - /* And move on to the next child in the list */ - + /* + * Delete this child node and move on to the next child in the list. + * No need to unlink the node since we are deleting the entire branch. + */ + AcpiNsDeleteNode (ChildNode); ChildNode = NextNode; } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); @@ -561,7 +604,7 @@ AcpiNsDeleteNamespaceByOwner ( if (DeletionNode) { AcpiNsDeleteChildren (DeletionNode); - AcpiNsDeleteNode (DeletionNode); + AcpiNsRemoveNode (DeletionNode); DeletionNode = NULL; } diff --git a/sys/contrib/dev/acpica/namespace/nsdump.c b/sys/contrib/dev/acpica/namespace/nsdump.c index 78b083fa992..a1ae96e5919 100644 --- a/sys/contrib/dev/acpica/namespace/nsdump.c +++ b/sys/contrib/dev/acpica/namespace/nsdump.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -286,7 +286,7 @@ AcpiNsDumpOneObject ( return (AE_OK); } - ThisNode = AcpiNsMapHandleToNode (ObjHandle); + ThisNode = AcpiNsValidateHandle (ObjHandle); if (!ThisNode) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Invalid object handle %p\n", @@ -736,7 +736,7 @@ AcpiNsDumpObjects ( (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth, ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES, - AcpiNsDumpOneObject, (void *) &Info, NULL); + AcpiNsDumpOneObject, NULL, (void *) &Info, NULL); } diff --git a/sys/contrib/dev/acpica/namespace/nsdumpdv.c b/sys/contrib/dev/acpica/namespace/nsdumpdv.c index ade6656ba6a..5dc61287587 100644 --- a/sys/contrib/dev/acpica/namespace/nsdumpdv.c +++ b/sys/contrib/dev/acpica/namespace/nsdumpdv.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -225,7 +225,7 @@ AcpiNsDumpRootDevices ( Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, SysBusHandle, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, - AcpiNsDumpOneDevice, NULL, NULL); + AcpiNsDumpOneDevice, NULL, NULL, NULL); } #endif diff --git a/sys/contrib/dev/acpica/namespace/nseval.c b/sys/contrib/dev/acpica/namespace/nseval.c index a1fe0879933..3d4926c442b 100644 --- a/sys/contrib/dev/acpica/namespace/nseval.c +++ b/sys/contrib/dev/acpica/namespace/nseval.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -126,6 +126,13 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME ("nseval") +/* Local prototypes */ + +static void +AcpiNsExecModuleCode ( + ACPI_OPERAND_OBJECT *MethodObj, + ACPI_EVALUATE_INFO *Info); + /******************************************************************************* * @@ -360,3 +367,192 @@ AcpiNsEvaluate ( return_ACPI_STATUS (Status); } + +/******************************************************************************* + * + * FUNCTION: AcpiNsExecModuleCodeList + * + * PARAMETERS: None + * + * RETURN: None. Exceptions during method execution are ignored, since + * we cannot abort a table load. + * + * DESCRIPTION: Execute all elements of the global module-level code list. + * Each element is executed as a single control method. + * + ******************************************************************************/ + +void +AcpiNsExecModuleCodeList ( + void) +{ + ACPI_OPERAND_OBJECT *Prev; + ACPI_OPERAND_OBJECT *Next; + ACPI_EVALUATE_INFO *Info; + UINT32 MethodCount = 0; + + + ACPI_FUNCTION_TRACE (NsExecModuleCodeList); + + + /* Exit now if the list is empty */ + + Next = AcpiGbl_ModuleCodeList; + if (!Next) + { + return_VOID; + } + + /* Allocate the evaluation information block */ + + Info = ACPI_ALLOCATE (sizeof (ACPI_EVALUATE_INFO)); + if (!Info) + { + return_VOID; + } + + /* Walk the list, executing each "method" */ + + while (Next) + { + Prev = Next; + Next = Next->Method.Mutex; + + /* Clear the link field and execute the method */ + + Prev->Method.Mutex = NULL; + AcpiNsExecModuleCode (Prev, Info); + MethodCount++; + + /* Delete the (temporary) method object */ + + AcpiUtRemoveReference (Prev); + } + + ACPI_INFO ((AE_INFO, + "Executed %u blocks of module-level executable AML code", + MethodCount)); + + ACPI_FREE (Info); + AcpiGbl_ModuleCodeList = NULL; + return_VOID; +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsExecModuleCode + * + * PARAMETERS: MethodObj - Object container for the module-level code + * Info - Info block for method evaluation + * + * RETURN: None. Exceptions during method execution are ignored, since + * we cannot abort a table load. + * + * DESCRIPTION: Execute a control method containing a block of module-level + * executable AML code. The control method is temporarily + * installed to the root node, then evaluated. + * + ******************************************************************************/ + +static void +AcpiNsExecModuleCode ( + ACPI_OPERAND_OBJECT *MethodObj, + ACPI_EVALUATE_INFO *Info) +{ + ACPI_OPERAND_OBJECT *ParentObj; + ACPI_NAMESPACE_NODE *ParentNode; + ACPI_OBJECT_TYPE Type; + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (NsExecModuleCode); + + + /* + * Get the parent node. We cheat by using the NextObject field + * of the method object descriptor. + */ + ParentNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, + MethodObj->Method.NextObject); + Type = AcpiNsGetType (ParentNode); + + /* + * Get the region handler and save it in the method object. We may need + * this if an operation region declaration causes a _REG method to be run. + * + * We can't do this in AcpiPsLinkModuleCode because + * AcpiGbl_RootNode->Object is NULL at PASS1. + */ + if ((Type == ACPI_TYPE_DEVICE) && ParentNode->Object) + { + MethodObj->Method.Extra.Handler = + ParentNode->Object->Device.Handler; + } + + /* Must clear NextObject (AcpiNsAttachObject needs the field) */ + + MethodObj->Method.NextObject = NULL; + + /* Initialize the evaluation information block */ + + ACPI_MEMSET (Info, 0, sizeof (ACPI_EVALUATE_INFO)); + Info->PrefixNode = ParentNode; + + /* + * Get the currently attached parent object. Add a reference, because the + * ref count will be decreased when the method object is installed to + * the parent node. + */ + ParentObj = AcpiNsGetAttachedObject (ParentNode); + if (ParentObj) + { + AcpiUtAddReference (ParentObj); + } + + /* Install the method (module-level code) in the parent node */ + + Status = AcpiNsAttachObject (ParentNode, MethodObj, + ACPI_TYPE_METHOD); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + /* Execute the parent node as a control method */ + + Status = AcpiNsEvaluate (Info); + + ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Executed module-level code at %p\n", + MethodObj->Method.AmlStart)); + + /* Delete a possible implicit return value (in slack mode) */ + + if (Info->ReturnObject) + { + AcpiUtRemoveReference (Info->ReturnObject); + } + + /* Detach the temporary method object */ + + AcpiNsDetachObject (ParentNode); + + /* Restore the original parent object */ + + if (ParentObj) + { + Status = AcpiNsAttachObject (ParentNode, ParentObj, Type); + } + else + { + ParentNode->Type = (UINT8) Type; + } + +Exit: + if (ParentObj) + { + AcpiUtRemoveReference (ParentObj); + } + return_VOID; +} + diff --git a/sys/contrib/dev/acpica/namespace/nsinit.c b/sys/contrib/dev/acpica/namespace/nsinit.c index 3869fc9ab66..5dfb23efedd 100644 --- a/sys/contrib/dev/acpica/namespace/nsinit.c +++ b/sys/contrib/dev/acpica/namespace/nsinit.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -185,7 +185,7 @@ AcpiNsInitializeObjects ( /* Walk entire namespace from the supplied root */ Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, AcpiNsInitOneObject, + ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL, &Info, NULL); if (ACPI_FAILURE (Status)) { @@ -249,7 +249,7 @@ AcpiNsInitializeDevices ( /* Tree analysis: find all subtrees that contain _INI methods */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, &Info, NULL); + ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL); if (ACPI_FAILURE (Status)) { goto ErrorExit; @@ -264,10 +264,26 @@ AcpiNsInitializeDevices ( goto ErrorExit; } + /* + * Execute the "global" _INI method that may appear at the root. This + * support is provided for Windows compatibility (Vista+) and is not + * part of the ACPI specification. + */ + Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode; + Info.EvaluateInfo->Pathname = METHOD_NAME__INI; + Info.EvaluateInfo->Parameters = NULL; + Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE; + + Status = AcpiNsEvaluate (Info.EvaluateInfo); + if (ACPI_SUCCESS (Status)) + { + Info.Num_INI++; + } + /* Walk namespace to execute all _INIs on present devices */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, &Info, NULL); + ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL); ACPI_FREE (Info.EvaluateInfo); if (ACPI_FAILURE (Status)) diff --git a/sys/contrib/dev/acpica/namespace/nsload.c b/sys/contrib/dev/acpica/namespace/nsload.c index 2a5e36aa0d7..7d67c5b2397 100644 --- a/sys/contrib/dev/acpica/namespace/nsload.c +++ b/sys/contrib/dev/acpica/namespace/nsload.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -376,8 +376,7 @@ AcpiNsDeleteSubtree ( /* Now delete the starting object, and we are done */ - AcpiNsDeleteNode (ChildHandle); - + AcpiNsRemoveNode (ChildHandle); return_ACPI_STATUS (AE_OK); } diff --git a/sys/contrib/dev/acpica/namespace/nsnames.c b/sys/contrib/dev/acpica/namespace/nsnames.c index c299d7e747d..c23e6de4f7f 100644 --- a/sys/contrib/dev/acpica/namespace/nsnames.c +++ b/sys/contrib/dev/acpica/namespace/nsnames.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -337,7 +337,7 @@ AcpiNsHandleToPathname ( ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle); - Node = AcpiNsMapHandleToNode (TargetHandle); + Node = AcpiNsValidateHandle (TargetHandle); if (!Node) { return_ACPI_STATUS (AE_BAD_PARAMETER); diff --git a/sys/contrib/dev/acpica/namespace/nsobject.c b/sys/contrib/dev/acpica/namespace/nsobject.c index cb8482502be..ca7f7a4703d 100644 --- a/sys/contrib/dev/acpica/namespace/nsobject.c +++ b/sys/contrib/dev/acpica/namespace/nsobject.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/namespace/nsparse.c b/sys/contrib/dev/acpica/namespace/nsparse.c index efa0188e188..8c71b80c618 100644 --- a/sys/contrib/dev/acpica/namespace/nsparse.c +++ b/sys/contrib/dev/acpica/namespace/nsparse.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/namespace/nspredef.c b/sys/contrib/dev/acpica/namespace/nspredef.c index 30a660959ed..48cf8fecae8 100644 --- a/sys/contrib/dev/acpica/namespace/nspredef.c +++ b/sys/contrib/dev/acpica/namespace/nspredef.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -113,7 +113,7 @@ * *****************************************************************************/ -#define __NSPREDEF_C__ +#define ACPI_CREATE_PREDEFINED_TABLE #include #include @@ -146,17 +146,24 @@ * ******************************************************************************/ + /* Local prototypes */ static ACPI_STATUS AcpiNsCheckPackage ( - char *Pathname, - ACPI_OPERAND_OBJECT **ReturnObjectPtr, - const ACPI_PREDEFINED_INFO *Predefined); + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS +AcpiNsCheckPackageList ( + ACPI_PREDEFINED_DATA *Data, + const ACPI_PREDEFINED_INFO *Package, + ACPI_OPERAND_OBJECT **Elements, + UINT32 Count); static ACPI_STATUS AcpiNsCheckPackageElements ( - char *Pathname, + ACPI_PREDEFINED_DATA *Data, ACPI_OPERAND_OBJECT **Elements, UINT8 Type1, UINT32 Count1, @@ -166,21 +173,20 @@ AcpiNsCheckPackageElements ( static ACPI_STATUS AcpiNsCheckObjectType ( - char *Pathname, + ACPI_PREDEFINED_DATA *Data, ACPI_OPERAND_OBJECT **ReturnObjectPtr, UINT32 ExpectedBtypes, UINT32 PackageIndex); static ACPI_STATUS AcpiNsCheckReference ( - char *Pathname, + ACPI_PREDEFINED_DATA *Data, ACPI_OPERAND_OBJECT *ReturnObject); -static ACPI_STATUS -AcpiNsRepairObject ( - UINT32 ExpectedBtypes, - UINT32 PackageIndex, - ACPI_OPERAND_OBJECT **ReturnObjectPtr); +static void +AcpiNsGetExpectedTypes ( + char *Buffer, + UINT32 ExpectedBtypes); /* * Names for the types that can be returned by the predefined objects. @@ -195,14 +201,14 @@ static const char *AcpiRtypeNames[] = "/Reference", }; -#define ACPI_NOT_PACKAGE ACPI_UINT32_MAX - /******************************************************************************* * * FUNCTION: AcpiNsCheckPredefinedNames * * PARAMETERS: Node - Namespace node for the method/object + * UserParamCount - Number of parameters actually passed + * ReturnStatus - Status from the object evaluation * ReturnObjectPtr - Pointer to the object returned from the * evaluation of a method or object * @@ -223,13 +229,14 @@ AcpiNsCheckPredefinedNames ( ACPI_STATUS Status = AE_OK; const ACPI_PREDEFINED_INFO *Predefined; char *Pathname; + ACPI_PREDEFINED_DATA *Data; /* Match the name for this method/object against the predefined list */ Predefined = AcpiNsCheckForPredefinedName (Node); - /* Get the full pathname to the object, for use in error messages */ + /* Get the full pathname to the object, for use in warning messages */ Pathname = AcpiNsGetExternalPathname (Node); if (!Pathname) @@ -248,30 +255,18 @@ AcpiNsCheckPredefinedNames ( if (!Predefined) { - goto Exit; - } - - /* If the method failed, we cannot validate the return object */ - - if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE)) - { - goto Exit; + goto Cleanup; } /* - * Only validate the return value on the first successful evaluation of - * the method. This ensures that any warnings will only be emitted during - * the very first evaluation of the method/object. + * If the method failed or did not actually return an object, we cannot + * validate the return object */ - if (Node->Flags & ANOBJ_EVALUATED) + if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE)) { - goto Exit; + goto Cleanup; } - /* Mark the node as having been successfully evaluated */ - - Node->Flags |= ANOBJ_EVALUATED; - /* * If there is no return value, check if we require a return value for * this predefined name. Either one return value is expected, or none, @@ -284,45 +279,87 @@ AcpiNsCheckPredefinedNames ( if ((Predefined->Info.ExpectedBtypes) && (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE))) { - ACPI_ERROR ((AE_INFO, - "%s: Missing expected return value", Pathname)); + ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, + "Missing expected return value")); Status = AE_AML_NO_RETURN_VALUE; } - goto Exit; + goto Cleanup; } /* - * We have a return value, but if one wasn't expected, just exit, this is - * not a problem + * 1) We have a return value, but if one wasn't expected, just exit, this is + * not a problem. For example, if the "Implicit Return" feature is + * enabled, methods will always return a value. * - * For example, if the "Implicit Return" feature is enabled, methods will - * always return a value + * 2) If the return value can be of any type, then we cannot perform any + * validation, exit. */ - if (!Predefined->Info.ExpectedBtypes) + if ((!Predefined->Info.ExpectedBtypes) || + (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL)) { - goto Exit; + goto Cleanup; } + /* Create the parameter data block for object validation */ + + Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA)); + if (!Data) + { + goto Cleanup; + } + Data->Predefined = Predefined; + Data->NodeFlags = Node->Flags; + Data->Pathname = Pathname; + /* - * Check that the type of the return object is what is expected for - * this predefined name + * Check that the type of the main return object is what is expected + * for this predefined name */ - Status = AcpiNsCheckObjectType (Pathname, ReturnObjectPtr, - Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE); + Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr, + Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT); if (ACPI_FAILURE (Status)) { goto Exit; } - /* For returned Package objects, check the type of all sub-objects */ - - if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE) + /* + * For returned Package objects, check the type of all sub-objects. + * Note: Package may have been newly created by call above. + */ + if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE) { - Status = AcpiNsCheckPackage (Pathname, ReturnObjectPtr, Predefined); + Data->ParentPackage = *ReturnObjectPtr; + Status = AcpiNsCheckPackage (Data, ReturnObjectPtr); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } } + /* + * The return object was OK, or it was successfully repaired above. + * Now make some additional checks such as verifying that package + * objects are sorted correctly (if required) or buffer objects have + * the correct data width (bytes vs. dwords). These repairs are + * performed on a per-name basis, i.e., the code is specific to + * particular predefined names. + */ + Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr); + Exit: + /* + * If the object validation failed or if we successfully repaired one + * or more objects, mark the parent node to suppress further warning + * messages during the next evaluation of the same method/object. + */ + if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED)) + { + Node->Flags |= ANOBJ_EVALUATED; + } + ACPI_FREE (Data); + +Cleanup: ACPI_FREE (Pathname); return (Status); } @@ -365,11 +402,11 @@ AcpiNsCheckParameterCount ( ParamCount = Node->Object->Method.ParamCount; } - /* Argument count check for non-predefined methods/objects */ - if (!Predefined) { /* + * Check the parameter count for non-predefined methods/objects. + * * Warning if too few or too many arguments have been passed by the * caller. An incorrect number of arguments may not cause the method * to fail. However, the method will fail if there are too few @@ -377,58 +414,49 @@ AcpiNsCheckParameterCount ( */ if (UserParamCount < ParamCount) { - ACPI_WARNING ((AE_INFO, - "%s: Insufficient arguments - needs %d, found %d", - Pathname, ParamCount, UserParamCount)); + ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, + "Insufficient arguments - needs %u, found %u", + ParamCount, UserParamCount)); } else if (UserParamCount > ParamCount) { - ACPI_WARNING ((AE_INFO, - "%s: Excess arguments - needs %d, found %d", - Pathname, ParamCount, UserParamCount)); + ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, + "Excess arguments - needs %u, found %u", + ParamCount, UserParamCount)); } return; } - /* Allow two different legal argument counts (_SCP, etc.) */ - + /* + * Validate the user-supplied parameter count. + * Allow two different legal argument counts (_SCP, etc.) + */ RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F; RequiredParamsOld = Predefined->Info.ParamCount >> 4; if (UserParamCount != ACPI_UINT32_MAX) { - /* Validate the user-supplied parameter count */ - if ((UserParamCount != RequiredParamsCurrent) && (UserParamCount != RequiredParamsOld)) { - ACPI_WARNING ((AE_INFO, - "%s: Parameter count mismatch - " - "caller passed %d, ACPI requires %d", - Pathname, UserParamCount, RequiredParamsCurrent)); + ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, + "Parameter count mismatch - " + "caller passed %u, ACPI requires %u", + UserParamCount, RequiredParamsCurrent)); } } - /* - * Only validate the argument count on the first successful evaluation of - * the method. This ensures that any warnings will only be emitted during - * the very first evaluation of the method/object. - */ - if (Node->Flags & ANOBJ_EVALUATED) - { - return; - } - /* * Check that the ASL-defined parameter count is what is expected for - * this predefined name. + * this predefined name (parameter count as defined by the ACPI + * specification) */ if ((ParamCount != RequiredParamsCurrent) && (ParamCount != RequiredParamsOld)) { - ACPI_WARNING ((AE_INFO, - "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", - Pathname, ParamCount, RequiredParamsCurrent)); + ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags, + "Parameter count mismatch - ASL declared %u, ACPI requires %u", + ParamCount, RequiredParamsCurrent)); } } @@ -466,8 +494,6 @@ AcpiNsCheckForPredefinedName ( { if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name)) { - /* Return pointer to this table entry */ - return (ThisName); } @@ -483,7 +509,7 @@ AcpiNsCheckForPredefinedName ( ThisName++; } - return (NULL); + return (NULL); /* Not found */ } @@ -491,10 +517,9 @@ AcpiNsCheckForPredefinedName ( * * FUNCTION: AcpiNsCheckPackage * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * ReturnObjectPtr - Pointer to the object returned from the * evaluation of a method or object - * Predefined - Pointer to entry in predefined name table * * RETURN: Status * @@ -505,20 +530,16 @@ AcpiNsCheckForPredefinedName ( static ACPI_STATUS AcpiNsCheckPackage ( - char *Pathname, - ACPI_OPERAND_OBJECT **ReturnObjectPtr, - const ACPI_PREDEFINED_INFO *Predefined) + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; const ACPI_PREDEFINED_INFO *Package; - ACPI_OPERAND_OBJECT *SubPackage; ACPI_OPERAND_OBJECT **Elements; - ACPI_OPERAND_OBJECT **SubElements; - ACPI_STATUS Status; + ACPI_STATUS Status = AE_OK; UINT32 ExpectedCount; UINT32 Count; UINT32 i; - UINT32 j; ACPI_FUNCTION_NAME (NsCheckPackage); @@ -526,11 +547,17 @@ AcpiNsCheckPackage ( /* The package info for this name is in the next table entry */ - Package = Predefined + 1; + Package = Data->Predefined + 1; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s Validating return Package of Type %X, Count %X\n", - Pathname, Package->RetInfo.Type, ReturnObject->Package.Count)); + Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count)); + + /* + * For variable-length Packages, we can safely remove all embedded + * and trailing NULL package elements + */ + AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject); /* Extract package count and elements array */ @@ -541,8 +568,8 @@ AcpiNsCheckPackage ( if (!Count) { - ACPI_WARNING ((AE_INFO, - "%s: Return Package has no elements (empty)", Pathname)); + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Return Package has no elements (empty)")); return (AE_AML_OPERAND_VALUE); } @@ -570,20 +597,17 @@ AcpiNsCheckPackage ( } else if (Count > ExpectedCount) { - ACPI_WARNING ((AE_INFO, + ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, "%s: Return Package is larger than needed - " - "found %u, expected %u", Pathname, Count, ExpectedCount)); + "found %u, expected %u\n", + Data->Pathname, Count, ExpectedCount)); } /* Validate all elements of the returned package */ - Status = AcpiNsCheckPackageElements (Pathname, Elements, + Status = AcpiNsCheckPackageElements (Data, Elements, Package->RetInfo.ObjectType1, Package->RetInfo.Count1, Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0); - if (ACPI_FAILURE (Status)) - { - return (Status); - } break; @@ -595,7 +619,7 @@ AcpiNsCheckPackage ( */ for (i = 0; i < Count; i++) { - Status = AcpiNsCheckObjectType (Pathname, Elements, + Status = AcpiNsCheckObjectType (Data, Elements, Package->RetInfo.ObjectType1, i); if (ACPI_FAILURE (Status)) { @@ -629,7 +653,7 @@ AcpiNsCheckPackage ( { /* These are the required package elements (0, 1, or 2) */ - Status = AcpiNsCheckObjectType (Pathname, Elements, + Status = AcpiNsCheckObjectType (Data, Elements, Package->RetInfo3.ObjectType[i], i); if (ACPI_FAILURE (Status)) { @@ -640,7 +664,7 @@ AcpiNsCheckPackage ( { /* These are the optional package elements */ - Status = AcpiNsCheckObjectType (Pathname, Elements, + Status = AcpiNsCheckObjectType (Data, Elements, Package->RetInfo3.TailObjectType, i); if (ACPI_FAILURE (Status)) { @@ -652,11 +676,31 @@ AcpiNsCheckPackage ( break; + case ACPI_PTYPE2_REV_FIXED: + + /* First element is the (Integer) revision */ + + Status = AcpiNsCheckObjectType (Data, Elements, + ACPI_RTYPE_INTEGER, 0); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Elements++; + Count--; + + /* Examine the sub-packages */ + + Status = AcpiNsCheckPackageList (Data, Package, Elements, Count); + break; + + case ACPI_PTYPE2_PKG_COUNT: /* First element is the (Integer) count of sub-packages to follow */ - Status = AcpiNsCheckObjectType (Pathname, Elements, + Status = AcpiNsCheckObjectType (Data, Elements, ACPI_RTYPE_INTEGER, 0); if (ACPI_FAILURE (Status)) { @@ -676,9 +720,10 @@ AcpiNsCheckPackage ( Count = ExpectedCount; Elements++; - /* Now we can walk the sub-packages */ + /* Examine the sub-packages */ - /*lint -fallthrough */ + Status = AcpiNsCheckPackageList (Data, Package, Elements, Count); + break; case ACPI_PTYPE2: @@ -687,135 +732,35 @@ AcpiNsCheckPackage ( case ACPI_PTYPE2_COUNT: /* - * These types all return a single package that consists of a variable - * number of sub-packages + * These types all return a single Package that consists of a + * variable number of sub-Packages. + * + * First, ensure that the first element is a sub-Package. If not, + * the BIOS may have incorrectly returned the object as a single + * package instead of a Package of Packages (a common error if + * there is only one entry). We may be able to repair this by + * wrapping the returned Package with a new outer Package. */ - for (i = 0; i < Count; i++) + if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE)) { - SubPackage = *Elements; - SubElements = SubPackage->Package.Elements; + /* Create the new outer package and populate it */ - /* Each sub-object must be of type Package */ - - Status = AcpiNsCheckObjectType (Pathname, &SubPackage, - ACPI_RTYPE_PACKAGE, i); + Status = AcpiNsRepairPackageList (Data, ReturnObjectPtr); if (ACPI_FAILURE (Status)) { return (Status); } - /* Examine the different types of sub-packages */ + /* Update locals to point to the new package (of 1 element) */ - switch (Package->RetInfo.Type) - { - case ACPI_PTYPE2: - case ACPI_PTYPE2_PKG_COUNT: - - /* Each subpackage has a fixed number of elements */ - - ExpectedCount = - Package->RetInfo.Count1 + Package->RetInfo.Count2; - if (SubPackage->Package.Count != ExpectedCount) - { - Count = SubPackage->Package.Count; - goto PackageTooSmall; - } - - Status = AcpiNsCheckPackageElements (Pathname, SubElements, - Package->RetInfo.ObjectType1, - Package->RetInfo.Count1, - Package->RetInfo.ObjectType2, - Package->RetInfo.Count2, 0); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - break; - - case ACPI_PTYPE2_FIXED: - - /* Each sub-package has a fixed length */ - - ExpectedCount = Package->RetInfo2.Count; - if (SubPackage->Package.Count < ExpectedCount) - { - Count = SubPackage->Package.Count; - goto PackageTooSmall; - } - - /* Check the type of each sub-package element */ - - for (j = 0; j < ExpectedCount; j++) - { - Status = AcpiNsCheckObjectType (Pathname, &SubElements[j], - Package->RetInfo2.ObjectType[j], j); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - } - break; - - case ACPI_PTYPE2_MIN: - - /* Each sub-package has a variable but minimum length */ - - ExpectedCount = Package->RetInfo.Count1; - if (SubPackage->Package.Count < ExpectedCount) - { - Count = SubPackage->Package.Count; - goto PackageTooSmall; - } - - /* Check the type of each sub-package element */ - - Status = AcpiNsCheckPackageElements (Pathname, SubElements, - Package->RetInfo.ObjectType1, - SubPackage->Package.Count, 0, 0, 0); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - break; - - case ACPI_PTYPE2_COUNT: - - /* First element is the (Integer) count of elements to follow */ - - Status = AcpiNsCheckObjectType (Pathname, SubElements, - ACPI_RTYPE_INTEGER, 0); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - - /* Make sure package is large enough for the Count */ - - ExpectedCount = (UINT32) (*SubElements)->Integer.Value; - if (SubPackage->Package.Count < ExpectedCount) - { - Count = SubPackage->Package.Count; - goto PackageTooSmall; - } - - /* Check the type of each sub-package element */ - - Status = AcpiNsCheckPackageElements (Pathname, - (SubElements + 1), - Package->RetInfo.ObjectType1, - (ExpectedCount - 1), 0, 0, 1); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - break; - - default: - break; - } - - Elements++; + ReturnObject = *ReturnObjectPtr; + Elements = ReturnObject->Package.Elements; + Count = 1; } + + /* Examine the sub-packages */ + + Status = AcpiNsCheckPackageList (Data, Package, Elements, Count); break; @@ -823,22 +768,225 @@ AcpiNsCheckPackage ( /* Should not get here if predefined info table is correct */ - ACPI_WARNING ((AE_INFO, - "%s: Invalid internal return type in table entry: %X", - Pathname, Package->RetInfo.Type)); + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Invalid internal return type in table entry: %X", + Package->RetInfo.Type)); return (AE_AML_INTERNAL); } + return (Status); + + +PackageTooSmall: + + /* Error exit for the case with an incorrect package count */ + + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Return Package is too small - found %u elements, expected %u", + Count, ExpectedCount)); + + return (AE_AML_OPERAND_VALUE); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsCheckPackageList + * + * PARAMETERS: Data - Pointer to validation data structure + * Package - Pointer to package-specific info for method + * Elements - Element list of parent package. All elements + * of this list should be of type Package. + * Count - Count of subpackages + * + * RETURN: Status + * + * DESCRIPTION: Examine a list of subpackages + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiNsCheckPackageList ( + ACPI_PREDEFINED_DATA *Data, + const ACPI_PREDEFINED_INFO *Package, + ACPI_OPERAND_OBJECT **Elements, + UINT32 Count) +{ + ACPI_OPERAND_OBJECT *SubPackage; + ACPI_OPERAND_OBJECT **SubElements; + ACPI_STATUS Status; + UINT32 ExpectedCount; + UINT32 i; + UINT32 j; + + + /* + * Validate each sub-Package in the parent Package + * + * NOTE: assumes list of sub-packages contains no NULL elements. + * Any NULL elements should have been removed by earlier call + * to AcpiNsRemoveNullElements. + */ + for (i = 0; i < Count; i++) + { + SubPackage = *Elements; + SubElements = SubPackage->Package.Elements; + Data->ParentPackage = SubPackage; + + /* Each sub-object must be of type Package */ + + Status = AcpiNsCheckObjectType (Data, &SubPackage, + ACPI_RTYPE_PACKAGE, i); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Examine the different types of expected sub-packages */ + + Data->ParentPackage = SubPackage; + switch (Package->RetInfo.Type) + { + case ACPI_PTYPE2: + case ACPI_PTYPE2_PKG_COUNT: + case ACPI_PTYPE2_REV_FIXED: + + /* Each subpackage has a fixed number of elements */ + + ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; + if (SubPackage->Package.Count < ExpectedCount) + { + goto PackageTooSmall; + } + + Status = AcpiNsCheckPackageElements (Data, SubElements, + Package->RetInfo.ObjectType1, + Package->RetInfo.Count1, + Package->RetInfo.ObjectType2, + Package->RetInfo.Count2, 0); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + break; + + + case ACPI_PTYPE2_FIXED: + + /* Each sub-package has a fixed length */ + + ExpectedCount = Package->RetInfo2.Count; + if (SubPackage->Package.Count < ExpectedCount) + { + goto PackageTooSmall; + } + + /* Check the type of each sub-package element */ + + for (j = 0; j < ExpectedCount; j++) + { + Status = AcpiNsCheckObjectType (Data, &SubElements[j], + Package->RetInfo2.ObjectType[j], j); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + break; + + + case ACPI_PTYPE2_MIN: + + /* Each sub-package has a variable but minimum length */ + + ExpectedCount = Package->RetInfo.Count1; + if (SubPackage->Package.Count < ExpectedCount) + { + goto PackageTooSmall; + } + + /* Check the type of each sub-package element */ + + Status = AcpiNsCheckPackageElements (Data, SubElements, + Package->RetInfo.ObjectType1, + SubPackage->Package.Count, 0, 0, 0); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + break; + + + case ACPI_PTYPE2_COUNT: + + /* + * First element is the (Integer) count of elements, including + * the count field (the ACPI name is NumElements) + */ + Status = AcpiNsCheckObjectType (Data, SubElements, + ACPI_RTYPE_INTEGER, 0); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* + * Make sure package is large enough for the Count and is + * is as large as the minimum size + */ + ExpectedCount = (UINT32) (*SubElements)->Integer.Value; + if (SubPackage->Package.Count < ExpectedCount) + { + goto PackageTooSmall; + } + if (SubPackage->Package.Count < Package->RetInfo.Count1) + { + ExpectedCount = Package->RetInfo.Count1; + goto PackageTooSmall; + } + if (ExpectedCount == 0) + { + /* + * Either the NumEntries element was originally zero or it was + * a NULL element and repaired to an Integer of value zero. + * In either case, repair it by setting NumEntries to be the + * actual size of the subpackage. + */ + ExpectedCount = SubPackage->Package.Count; + (*SubElements)->Integer.Value = ExpectedCount; + } + + /* Check the type of each sub-package element */ + + Status = AcpiNsCheckPackageElements (Data, (SubElements + 1), + Package->RetInfo.ObjectType1, + (ExpectedCount - 1), 0, 0, 1); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + break; + + + default: /* Should not get here, type was validated by caller */ + + return (AE_AML_INTERNAL); + } + + Elements++; + } + return (AE_OK); PackageTooSmall: - /* Error exit for the case with an incorrect package count */ + /* The sub-package count was smaller than required */ - ACPI_WARNING ((AE_INFO, "%s: Return Package is too small - " - "found %u, expected %u", Pathname, Count, ExpectedCount)); + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Return Sub-Package[%u] is too small - found %u elements, expected %u", + i, SubPackage->Package.Count, ExpectedCount)); return (AE_AML_OPERAND_VALUE); } @@ -848,7 +996,7 @@ PackageTooSmall: * * FUNCTION: AcpiNsCheckPackageElements * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * Elements - Pointer to the package elements array * Type1 - Object type for first group * Count1 - Count for first group @@ -865,7 +1013,7 @@ PackageTooSmall: static ACPI_STATUS AcpiNsCheckPackageElements ( - char *Pathname, + ACPI_PREDEFINED_DATA *Data, ACPI_OPERAND_OBJECT **Elements, UINT8 Type1, UINT32 Count1, @@ -885,7 +1033,7 @@ AcpiNsCheckPackageElements ( */ for (i = 0; i < Count1; i++) { - Status = AcpiNsCheckObjectType (Pathname, ThisElement, + Status = AcpiNsCheckObjectType (Data, ThisElement, Type1, i + StartIndex); if (ACPI_FAILURE (Status)) { @@ -896,7 +1044,7 @@ AcpiNsCheckPackageElements ( for (i = 0; i < Count2; i++) { - Status = AcpiNsCheckObjectType (Pathname, ThisElement, + Status = AcpiNsCheckObjectType (Data, ThisElement, Type2, (i + Count1 + StartIndex)); if (ACPI_FAILURE (Status)) { @@ -913,12 +1061,13 @@ AcpiNsCheckPackageElements ( * * FUNCTION: AcpiNsCheckObjectType * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * ReturnObjectPtr - Pointer to the object returned from the * evaluation of a method or object * ExpectedBtypes - Bitmap of expected return type(s) * PackageIndex - Index of object within parent package (if - * applicable - ACPI_NOT_PACKAGE otherwise) + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) * * RETURN: Status * @@ -929,7 +1078,7 @@ AcpiNsCheckPackageElements ( static ACPI_STATUS AcpiNsCheckObjectType ( - char *Pathname, + ACPI_PREDEFINED_DATA *Data, ACPI_OPERAND_OBJECT **ReturnObjectPtr, UINT32 ExpectedBtypes, UINT32 PackageIndex) @@ -938,17 +1087,22 @@ AcpiNsCheckObjectType ( ACPI_STATUS Status = AE_OK; UINT32 ReturnBtype; char TypeBuffer[48]; /* Room for 5 types */ - UINT32 ThisRtype; - UINT32 i; - UINT32 j; /* - * If we get a NULL ReturnObject here, it is a NULL package element, - * and this is always an error. + * If we get a NULL ReturnObject here, it is a NULL package element. + * Since all extraneous NULL package elements were removed earlier by a + * call to AcpiNsRemoveNullElements, this is an unexpected NULL element. + * We will attempt to repair it. */ if (!ReturnObject) { + Status = AcpiNsRepairNullElement (Data, ExpectedBtypes, + PackageIndex, ReturnObjectPtr); + if (ACPI_SUCCESS (Status)) + { + return (AE_OK); /* Repair was successful */ + } goto TypeErrorExit; } @@ -956,9 +1110,9 @@ AcpiNsCheckObjectType ( if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) { - ACPI_WARNING ((AE_INFO, - "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", - Pathname, ReturnObject->Node.Name.Ascii, + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Invalid return type - Found a Namespace node [%4.4s] type %s", + ReturnObject->Node.Name.Ascii, AcpiUtGetTypeName (ReturnObject->Node.Type))); return (AE_AML_OPERAND_TYPE); } @@ -1001,60 +1155,45 @@ AcpiNsCheckObjectType ( /* Is the object one of the expected types? */ - if (!(ReturnBtype & ExpectedBtypes)) + if (ReturnBtype & ExpectedBtypes) { - /* Type mismatch -- attempt repair of the returned object */ + /* For reference objects, check that the reference type is correct */ - Status = AcpiNsRepairObject (ExpectedBtypes, PackageIndex, - ReturnObjectPtr); - if (ACPI_SUCCESS (Status)) + if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) { - return (Status); + Status = AcpiNsCheckReference (Data, ReturnObject); } - goto TypeErrorExit; + + return (Status); } - /* For reference objects, check that the reference type is correct */ + /* Type mismatch -- attempt repair of the returned object */ - if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) + Status = AcpiNsRepairObject (Data, ExpectedBtypes, + PackageIndex, ReturnObjectPtr); + if (ACPI_SUCCESS (Status)) { - Status = AcpiNsCheckReference (Pathname, ReturnObject); + return (AE_OK); /* Repair was successful */ } - return (Status); - TypeErrorExit: /* Create a string with all expected types for this predefined object */ - j = 1; - TypeBuffer[0] = 0; - ThisRtype = ACPI_RTYPE_INTEGER; + AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes); - for (i = 0; i < ACPI_NUM_RTYPES; i++) + if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) { - /* If one of the expected types, concatenate the name of this type */ - - if (ExpectedBtypes & ThisRtype) - { - ACPI_STRCAT (TypeBuffer, &AcpiRtypeNames[i][j]); - j = 0; /* Use name separator from now on */ - } - ThisRtype <<= 1; /* Next Rtype */ - } - - if (PackageIndex == ACPI_NOT_PACKAGE) - { - ACPI_WARNING ((AE_INFO, - "%s: Return type mismatch - found %s, expected %s", - Pathname, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Return type mismatch - found %s, expected %s", + AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); } else { - ACPI_WARNING ((AE_INFO, - "%s: Return Package type mismatch at index %u - " - "found %s, expected %s", Pathname, PackageIndex, + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Return Package type mismatch at index %u - " + "found %s, expected %s", PackageIndex, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); } @@ -1066,7 +1205,7 @@ TypeErrorExit: * * FUNCTION: AcpiNsCheckReference * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * ReturnObject - Object returned from the evaluation of a * method or object * @@ -1080,7 +1219,7 @@ TypeErrorExit: static ACPI_STATUS AcpiNsCheckReference ( - char *Pathname, + ACPI_PREDEFINED_DATA *Data, ACPI_OPERAND_OBJECT *ReturnObject) { @@ -1094,10 +1233,9 @@ AcpiNsCheckReference ( return (AE_OK); } - ACPI_WARNING ((AE_INFO, - "%s: Return type mismatch - " - "unexpected reference object type [%s] %2.2X", - Pathname, AcpiUtGetReferenceName (ReturnObject), + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Return type mismatch - unexpected reference object type [%s] %2.2X", + AcpiUtGetReferenceName (ReturnObject), ReturnObject->Reference.Class)); return (AE_AML_OPERAND_TYPE); @@ -1106,91 +1244,41 @@ AcpiNsCheckReference ( /******************************************************************************* * - * FUNCTION: AcpiNsRepairObject + * FUNCTION: AcpiNsGetExpectedTypes * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) - * PackageIndex - Used to determine if target is in a package - * ReturnObjectPtr - Pointer to the object returned from the - * evaluation of a method or object + * PARAMETERS: Buffer - Pointer to where the string is returned + * ExpectedBtypes - Bitmap of expected return type(s) * - * RETURN: Status. AE_OK if repair was successful. + * RETURN: Buffer is populated with type names. * - * DESCRIPTION: Attempt to repair/convert a return object of a type that was - * not expected. + * DESCRIPTION: Translate the expected types bitmap into a string of ascii + * names of expected types, for use in warning messages. * ******************************************************************************/ -static ACPI_STATUS -AcpiNsRepairObject ( - UINT32 ExpectedBtypes, - UINT32 PackageIndex, - ACPI_OPERAND_OBJECT **ReturnObjectPtr) +static void +AcpiNsGetExpectedTypes ( + char *Buffer, + UINT32 ExpectedBtypes) { - ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; - ACPI_OPERAND_OBJECT *NewObject; - ACPI_SIZE Length; + UINT32 ThisRtype; + UINT32 i; + UINT32 j; - switch (ReturnObject->Common.Type) + j = 1; + Buffer[0] = 0; + ThisRtype = ACPI_RTYPE_INTEGER; + + for (i = 0; i < ACPI_NUM_RTYPES; i++) { - case ACPI_TYPE_BUFFER: + /* If one of the expected types, concatenate the name of this type */ - if (!(ExpectedBtypes & ACPI_RTYPE_STRING)) + if (ExpectedBtypes & ThisRtype) { - return (AE_AML_OPERAND_TYPE); + ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]); + j = 0; /* Use name separator from now on */ } - - /* - * Have a Buffer, expected a String, convert. Use a ToString - * conversion, no transform performed on the buffer data. The best - * example of this is the _BIF method, where the string data from - * the battery is often (incorrectly) returned as buffer object(s). - */ - Length = 0; - while ((Length < ReturnObject->Buffer.Length) && - (ReturnObject->Buffer.Pointer[Length])) - { - Length++; - } - - /* Allocate a new string object */ - - NewObject = AcpiUtCreateStringObject (Length); - if (!NewObject) - { - return (AE_NO_MEMORY); - } - - /* - * Copy the raw buffer data with no transform. String is already NULL - * terminated at Length+1. - */ - ACPI_MEMCPY (NewObject->String.Pointer, - ReturnObject->Buffer.Pointer, Length); - - /* Install the new return object */ - - AcpiUtRemoveReference (ReturnObject); - *ReturnObjectPtr = NewObject; - - /* - * If the object is a package element, we need to: - * 1. Decrement the reference count of the orignal object, it was - * incremented when building the package - * 2. Increment the reference count of the new object, it will be - * decremented when releasing the package - */ - if (PackageIndex != ACPI_NOT_PACKAGE) - { - AcpiUtRemoveReference (ReturnObject); - AcpiUtAddReference (NewObject); - } - return (AE_OK); - - default: - break; + ThisRtype <<= 1; /* Next Rtype */ } - - return (AE_AML_OPERAND_TYPE); } - diff --git a/sys/contrib/dev/acpica/namespace/nsrepair.c b/sys/contrib/dev/acpica/namespace/nsrepair.c new file mode 100644 index 00000000000..b2191a754ab --- /dev/null +++ b/sys/contrib/dev/acpica/namespace/nsrepair.c @@ -0,0 +1,876 @@ +/****************************************************************************** + * + * Module Name: nsrepair - Repair for objects returned by predefined methods + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2010, 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. + * + *****************************************************************************/ + +#define __NSREPAIR_C__ + +#include +#include +#include +#include +#include + +#define _COMPONENT ACPI_NAMESPACE + ACPI_MODULE_NAME ("nsrepair") + + +/******************************************************************************* + * + * This module attempts to repair or convert objects returned by the + * predefined methods to an object type that is expected, as per the ACPI + * specification. The need for this code is dictated by the many machines that + * return incorrect types for the standard predefined methods. Performing these + * conversions here, in one place, eliminates the need for individual ACPI + * device drivers to do the same. Note: Most of these conversions are different + * than the internal object conversion routines used for implicit object + * conversion. + * + * The following conversions can be performed as necessary: + * + * Integer -> String + * Integer -> Buffer + * String -> Integer + * String -> Buffer + * Buffer -> Integer + * Buffer -> String + * Buffer -> Package of Integers + * Package -> Package of one Package + * + * Additional possible repairs: + * + * Optional/unnecessary NULL package elements removed + * Required package elements that are NULL replaced by Integer/String/Buffer + * Incorrect standalone package wrapped with required outer package + * + ******************************************************************************/ + + +/* Local prototypes */ + +static ACPI_STATUS +AcpiNsConvertToInteger ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject); + +static ACPI_STATUS +AcpiNsConvertToString ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject); + +static ACPI_STATUS +AcpiNsConvertToBuffer ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject); + +static ACPI_STATUS +AcpiNsConvertToPackage ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject); + + +/******************************************************************************* + * + * FUNCTION: AcpiNsRepairObject + * + * PARAMETERS: Data - Pointer to validation data structure + * ExpectedBtypes - Object types expected + * PackageIndex - Index of object within parent package (if + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if repair was successful. + * + * DESCRIPTION: Attempt to repair/convert a return object of a type that was + * not expected. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiNsRepairObject ( + ACPI_PREDEFINED_DATA *Data, + UINT32 ExpectedBtypes, + UINT32 PackageIndex, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_OPERAND_OBJECT *NewObject; + ACPI_STATUS Status; + + + ACPI_FUNCTION_NAME (NsRepairObject); + + + /* + * 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 by converting it to one of the expected object + * types for this predefined name. + */ + if (ExpectedBtypes & ACPI_RTYPE_INTEGER) + { + Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); + if (ACPI_SUCCESS (Status)) + { + goto ObjectRepaired; + } + } + if (ExpectedBtypes & ACPI_RTYPE_STRING) + { + Status = AcpiNsConvertToString (ReturnObject, &NewObject); + if (ACPI_SUCCESS (Status)) + { + goto ObjectRepaired; + } + } + if (ExpectedBtypes & ACPI_RTYPE_BUFFER) + { + Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject); + if (ACPI_SUCCESS (Status)) + { + goto ObjectRepaired; + } + } + if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) + { + Status = AcpiNsConvertToPackage (ReturnObject, &NewObject); + if (ACPI_SUCCESS (Status)) + { + goto ObjectRepaired; + } + } + + /* We cannot repair this object */ + + return (AE_AML_OPERAND_TYPE); + + +ObjectRepaired: + + /* 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_DEBUG_PRINT ((ACPI_DB_REPAIR, + "%s: Converted %s to expected %s at index %u\n", + Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject), + AcpiUtGetObjectTypeName (NewObject), PackageIndex)); + } + else + { + ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, + "%s: Converted %s to expected %s\n", + Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject), + AcpiUtGetObjectTypeName (NewObject))); + } + + /* Delete old object, install the new return object */ + + AcpiUtRemoveReference (ReturnObject); + *ReturnObjectPtr = NewObject; + Data->Flags |= ACPI_OBJECT_REPAIRED; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsConvertToInteger + * + * PARAMETERS: OriginalObject - Object to be converted + * ReturnObject - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiNsConvertToInteger ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject) +{ + ACPI_OPERAND_OBJECT *NewObject; + ACPI_STATUS Status; + UINT64 Value = 0; + UINT32 i; + + + switch (OriginalObject->Common.Type) + { + case ACPI_TYPE_STRING: + + /* String-to-Integer conversion */ + + Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer, + ACPI_ANY_BASE, &Value); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + break; + + case ACPI_TYPE_BUFFER: + + /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ + + if (OriginalObject->Buffer.Length > 8) + { + return (AE_AML_OPERAND_TYPE); + } + + /* Extract each buffer byte to create the integer */ + + for (i = 0; i < OriginalObject->Buffer.Length; i++) + { + Value |= ((UINT64) OriginalObject->Buffer.Pointer[i] << (i * 8)); + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + NewObject = AcpiUtCreateIntegerObject (Value); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + *ReturnObject = NewObject; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsConvertToString + * + * PARAMETERS: OriginalObject - Object to be converted + * ReturnObject - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiNsConvertToString ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject) +{ + ACPI_OPERAND_OBJECT *NewObject; + ACPI_SIZE Length; + ACPI_STATUS Status; + + + switch (OriginalObject->Common.Type) + { + case ACPI_TYPE_INTEGER: + /* + * Integer-to-String conversion. Commonly, convert + * an integer of value 0 to a NULL string. The last element of + * _BIF and _BIX packages occasionally need this fix. + */ + if (OriginalObject->Integer.Value == 0) + { + /* Allocate a new NULL string object */ + + NewObject = AcpiUtCreateStringObject (0); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + } + else + { + Status = AcpiExConvertToString (OriginalObject, &NewObject, + ACPI_IMPLICIT_CONVERT_HEX); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + break; + + case ACPI_TYPE_BUFFER: + /* + * Buffer-to-String conversion. Use a ToString + * conversion, no transform performed on the buffer data. The best + * example of this is the _BIF method, where the string data from + * the battery is often (incorrectly) returned as buffer object(s). + */ + Length = 0; + while ((Length < OriginalObject->Buffer.Length) && + (OriginalObject->Buffer.Pointer[Length])) + { + Length++; + } + + /* Allocate a new string object */ + + NewObject = AcpiUtCreateStringObject (Length); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + /* + * Copy the raw buffer data with no transform. String is already NULL + * terminated at Length+1. + */ + ACPI_MEMCPY (NewObject->String.Pointer, + OriginalObject->Buffer.Pointer, Length); + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *ReturnObject = NewObject; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsConvertToBuffer + * + * PARAMETERS: OriginalObject - Object to be converted + * ReturnObject - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiNsConvertToBuffer ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject) +{ + ACPI_OPERAND_OBJECT *NewObject; + ACPI_STATUS Status; + ACPI_OPERAND_OBJECT **Elements; + UINT32 *DwordBuffer; + UINT32 Count; + UINT32 i; + + + switch (OriginalObject->Common.Type) + { + case ACPI_TYPE_INTEGER: + /* + * Integer-to-Buffer conversion. + * Convert the Integer to a packed-byte buffer. _MAT and other + * objects need 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 (OriginalObject, &NewObject); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + break; + + case ACPI_TYPE_STRING: + + /* String-to-Buffer conversion. Simple data copy */ + + NewObject = AcpiUtCreateBufferObject (OriginalObject->String.Length); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (NewObject->Buffer.Pointer, + OriginalObject->String.Pointer, OriginalObject->String.Length); + break; + + case ACPI_TYPE_PACKAGE: + /* + * This case is often seen for predefined names that must return a + * Buffer object with multiple DWORD integers within. For example, + * _FDE and _GTM. The Package can be converted to a Buffer. + */ + + /* All elements of the Package must be integers */ + + Elements = OriginalObject->Package.Elements; + Count = OriginalObject->Package.Count; + + for (i = 0; i < Count; i++) + { + if ((!*Elements) || + ((*Elements)->Common.Type != ACPI_TYPE_INTEGER)) + { + return (AE_AML_OPERAND_TYPE); + } + Elements++; + } + + /* Create the new buffer object to replace the Package */ + + NewObject = AcpiUtCreateBufferObject (ACPI_MUL_4 (Count)); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + /* Copy the package elements (integers) to the buffer as DWORDs */ + + Elements = OriginalObject->Package.Elements; + DwordBuffer = ACPI_CAST_PTR (UINT32, NewObject->Buffer.Pointer); + + for (i = 0; i < Count; i++) + { + *DwordBuffer = (UINT32) (*Elements)->Integer.Value; + DwordBuffer++; + Elements++; + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *ReturnObject = NewObject; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsConvertToPackage + * + * PARAMETERS: OriginalObject - Object to be converted + * ReturnObject - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of + * the buffer is converted to a single integer package element. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiNsConvertToPackage ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject) +{ + ACPI_OPERAND_OBJECT *NewObject; + ACPI_OPERAND_OBJECT **Elements; + UINT32 Length; + UINT8 *Buffer; + + + switch (OriginalObject->Common.Type) + { + case ACPI_TYPE_BUFFER: + + /* Buffer-to-Package conversion */ + + Length = OriginalObject->Buffer.Length; + NewObject = AcpiUtCreatePackageObject (Length); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + /* Convert each buffer byte to an integer package element */ + + Elements = NewObject->Package.Elements; + Buffer = OriginalObject->Buffer.Pointer; + + while (Length--) + { + *Elements = AcpiUtCreateIntegerObject ((UINT64) *Buffer); + if (!*Elements) + { + AcpiUtRemoveReference (NewObject); + return (AE_NO_MEMORY); + } + Elements++; + Buffer++; + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *ReturnObject = NewObject; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsRepairNullElement + * + * PARAMETERS: Data - Pointer to validation data structure + * ExpectedBtypes - Object types expected + * PackageIndex - Index of object within parent package (if + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if repair was successful. + * + * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiNsRepairNullElement ( + ACPI_PREDEFINED_DATA *Data, + UINT32 ExpectedBtypes, + UINT32 PackageIndex, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_OPERAND_OBJECT *NewObject; + + + ACPI_FUNCTION_NAME (NsRepairNullElement); + + + /* No repair needed if return object is non-NULL */ + + if (ReturnObject) + { + return (AE_OK); + } + + /* + * Attempt to repair a NULL element of a Package object. This applies to + * predefined names that return a fixed-length package and each element + * is required. It does not apply to variable-length packages where NULL + * elements are allowed, especially at the end of the package. + */ + if (ExpectedBtypes & ACPI_RTYPE_INTEGER) + { + /* Need an Integer - create a zero-value integer */ + + NewObject = AcpiUtCreateIntegerObject (0); + } + else if (ExpectedBtypes & ACPI_RTYPE_STRING) + { + /* Need a String - create a NULL string */ + + NewObject = AcpiUtCreateStringObject (0); + } + else if (ExpectedBtypes & ACPI_RTYPE_BUFFER) + { + /* Need a Buffer - create a zero-length buffer */ + + NewObject = AcpiUtCreateBufferObject (0); + } + else + { + /* Error for all other expected types */ + + return (AE_AML_OPERAND_TYPE); + } + + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + /* Set the reference count according to the parent Package object */ + + NewObject->Common.ReferenceCount = Data->ParentPackage->Common.ReferenceCount; + + ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, + "%s: Converted NULL package element to expected %s at index %u\n", + Data->Pathname, AcpiUtGetObjectTypeName (NewObject), PackageIndex)); + + *ReturnObjectPtr = NewObject; + Data->Flags |= ACPI_OBJECT_REPAIRED; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRemoveNullElements + * + * PARAMETERS: Data - Pointer to validation data structure + * PackageType - An AcpiReturnPackageTypes value + * ObjDesc - A Package object + * + * RETURN: None. + * + * DESCRIPTION: Remove all NULL package elements from packages that contain + * a variable number of sub-packages. For these types of + * packages, NULL elements can be safely removed. + * + *****************************************************************************/ + +void +AcpiNsRemoveNullElements ( + ACPI_PREDEFINED_DATA *Data, + UINT8 PackageType, + ACPI_OPERAND_OBJECT *ObjDesc) +{ + ACPI_OPERAND_OBJECT **Source; + ACPI_OPERAND_OBJECT **Dest; + UINT32 Count; + UINT32 NewCount; + UINT32 i; + + + ACPI_FUNCTION_NAME (NsRemoveNullElements); + + + /* + * PTYPE1 packages contain no subpackages. + * PTYPE2 packages contain a variable number of sub-packages. We can + * safely remove all NULL elements from the PTYPE2 packages. + */ + switch (PackageType) + { + case ACPI_PTYPE1_FIXED: + case ACPI_PTYPE1_VAR: + case ACPI_PTYPE1_OPTION: + return; + + case ACPI_PTYPE2: + case ACPI_PTYPE2_COUNT: + case ACPI_PTYPE2_PKG_COUNT: + case ACPI_PTYPE2_FIXED: + case ACPI_PTYPE2_MIN: + case ACPI_PTYPE2_REV_FIXED: + break; + + default: + return; + } + + Count = ObjDesc->Package.Count; + NewCount = Count; + + Source = ObjDesc->Package.Elements; + Dest = Source; + + /* Examine all elements of the package object, remove nulls */ + + for (i = 0; i < Count; i++) + { + if (!*Source) + { + NewCount--; + } + else + { + *Dest = *Source; + Dest++; + } + Source++; + } + + /* Update parent package if any null elements were removed */ + + if (NewCount < Count) + { + ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, + "%s: Found and removed %u NULL elements\n", + Data->Pathname, (Count - NewCount))); + + /* NULL terminate list and update the package count */ + + *Dest = NULL; + ObjDesc->Package.Count = NewCount; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsRepairPackageList + * + * PARAMETERS: Data - Pointer to validation data structure + * ObjDescPtr - Pointer to the object to repair. The new + * package object is returned here, + * overwriting the old object. + * + * RETURN: Status, new object in *ObjDescPtr + * + * DESCRIPTION: Repair a common problem with objects that are defined to return + * a variable-length Package of Packages. If the variable-length + * is one, some BIOS code mistakenly simply declares a single + * Package instead of a Package with one sub-Package. This + * function attempts to repair this error by wrapping a Package + * object around the original Package, creating the correct + * Package with one sub-Package. + * + * Names that can be repaired in this manner include: + * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS + * + ******************************************************************************/ + +ACPI_STATUS +AcpiNsRepairPackageList ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ObjDescPtr) +{ + ACPI_OPERAND_OBJECT *PkgObjDesc; + + + ACPI_FUNCTION_NAME (NsRepairPackageList); + + + /* + * Create the new outer package and populate it. The new package will + * have a single element, the lone subpackage. + */ + PkgObjDesc = AcpiUtCreatePackageObject (1); + if (!PkgObjDesc) + { + return (AE_NO_MEMORY); + } + + PkgObjDesc->Package.Elements[0] = *ObjDescPtr; + + /* Return the new object in the object pointer */ + + *ObjDescPtr = PkgObjDesc; + Data->Flags |= ACPI_OBJECT_REPAIRED; + + ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, + "%s: Repaired incorrectly formed Package\n", Data->Pathname)); + + return (AE_OK); +} diff --git a/sys/contrib/dev/acpica/namespace/nsrepair2.c b/sys/contrib/dev/acpica/namespace/nsrepair2.c new file mode 100644 index 00000000000..25fc47c2bb2 --- /dev/null +++ b/sys/contrib/dev/acpica/namespace/nsrepair2.c @@ -0,0 +1,696 @@ +/****************************************************************************** + * + * Module Name: nsrepair2 - Repair for objects returned by specific + * predefined methods + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2010, 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. + * + *****************************************************************************/ + +#define __NSREPAIR2_C__ + +#include +#include +#include + +#define _COMPONENT ACPI_NAMESPACE + ACPI_MODULE_NAME ("nsrepair2") + + +/* + * Information structure and handler for ACPI predefined names that can + * be repaired on a per-name basis. + */ +typedef +ACPI_STATUS (*ACPI_REPAIR_FUNCTION) ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +typedef struct acpi_repair_info +{ + char Name[ACPI_NAME_SIZE]; + ACPI_REPAIR_FUNCTION RepairFunction; + +} ACPI_REPAIR_INFO; + + +/* Local prototypes */ + +static const ACPI_REPAIR_INFO * +AcpiNsMatchRepairableName ( + ACPI_NAMESPACE_NODE *Node); + +static ACPI_STATUS +AcpiNsRepair_ALR ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS +AcpiNsRepair_FDE ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS +AcpiNsRepair_PSS ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS +AcpiNsRepair_TSS ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS +AcpiNsCheckSortedList ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT *ReturnObject, + UINT32 ExpectedCount, + UINT32 SortIndex, + UINT8 SortDirection, + char *SortKeyName); + +static void +AcpiNsSortList ( + ACPI_OPERAND_OBJECT **Elements, + UINT32 Count, + UINT32 Index, + UINT8 SortDirection); + +/* Values for SortDirection above */ + +#define ACPI_SORT_ASCENDING 0 +#define ACPI_SORT_DESCENDING 1 + + +/* + * This table contains the names of the predefined methods for which we can + * perform more complex repairs. + * + * As necessary: + * + * _ALR: Sort the list ascending by AmbientIlluminance + * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs + * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs + * _PSS: Sort the list descending by Power + * _TSS: Sort the list descending by Power + */ +static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] = +{ + {"_ALR", AcpiNsRepair_ALR}, + {"_FDE", AcpiNsRepair_FDE}, + {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */ + {"_PSS", AcpiNsRepair_PSS}, + {"_TSS", AcpiNsRepair_TSS}, + {{0,0,0,0}, NULL} /* Table terminator */ +}; + + +#define ACPI_FDE_FIELD_COUNT 5 +#define ACPI_FDE_BYTE_BUFFER_SIZE 5 +#define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * sizeof (UINT32)) + + +/****************************************************************************** + * + * FUNCTION: AcpiNsComplexRepairs + * + * PARAMETERS: Data - Pointer to validation data structure + * Node - Namespace node for the method/object + * ValidateStatus - Original status of earlier validation + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if repair was successful. If name is not + * matched, ValidateStatus is returned. + * + * DESCRIPTION: Attempt to repair/convert a return object of a type that was + * not expected. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiNsComplexRepairs ( + ACPI_PREDEFINED_DATA *Data, + ACPI_NAMESPACE_NODE *Node, + ACPI_STATUS ValidateStatus, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + const ACPI_REPAIR_INFO *Predefined; + ACPI_STATUS Status; + + + /* Check if this name is in the list of repairable names */ + + Predefined = AcpiNsMatchRepairableName (Node); + if (!Predefined) + { + return (ValidateStatus); + } + + Status = Predefined->RepairFunction (Data, ReturnObjectPtr); + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsMatchRepairableName + * + * PARAMETERS: Node - Namespace node for the method/object + * + * RETURN: Pointer to entry in repair table. NULL indicates not found. + * + * DESCRIPTION: Check an object name against the repairable object list. + * + *****************************************************************************/ + +static const ACPI_REPAIR_INFO * +AcpiNsMatchRepairableName ( + ACPI_NAMESPACE_NODE *Node) +{ + const ACPI_REPAIR_INFO *ThisName; + + + /* Search info table for a repairable predefined method/object name */ + + ThisName = AcpiNsRepairableNames; + while (ThisName->RepairFunction) + { + if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) + { + return (ThisName); + } + ThisName++; + } + + return (NULL); /* Not found */ +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRepair_ALR + * + * PARAMETERS: Data - Pointer to validation data structure + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list + * ascending by the ambient illuminance values. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRepair_ALR ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_STATUS Status; + + + Status = AcpiNsCheckSortedList (Data, ReturnObject, 2, 1, + ACPI_SORT_ASCENDING, "AmbientIlluminance"); + + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRepair_FDE + * + * PARAMETERS: Data - Pointer to validation data structure + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return + * value is a Buffer of 5 DWORDs. This function repairs a common + * problem where the return value is a Buffer of BYTEs, not + * DWORDs. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRepair_FDE ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_OPERAND_OBJECT *BufferObject; + UINT8 *ByteBuffer; + UINT32 *DwordBuffer; + UINT32 i; + + + ACPI_FUNCTION_NAME (NsRepair_FDE); + + + switch (ReturnObject->Common.Type) + { + case ACPI_TYPE_BUFFER: + + /* This is the expected type. Length should be (at least) 5 DWORDs */ + + if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE) + { + return (AE_OK); + } + + /* We can only repair if we have exactly 5 BYTEs */ + + if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE) + { + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Incorrect return buffer length %u, expected %u", + ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE)); + + return (AE_AML_OPERAND_TYPE); + } + + /* Create the new (larger) buffer object */ + + BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE); + if (!BufferObject) + { + return (AE_NO_MEMORY); + } + + /* Expand each byte to a DWORD */ + + ByteBuffer = ReturnObject->Buffer.Pointer; + DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer); + + for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++) + { + *DwordBuffer = (UINT32) *ByteBuffer; + DwordBuffer++; + ByteBuffer++; + } + + ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, + "%s Expanded Byte Buffer to expected DWord Buffer\n", + Data->Pathname)); + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + /* Delete the original return object, return the new buffer object */ + + AcpiUtRemoveReference (ReturnObject); + *ReturnObjectPtr = BufferObject; + + Data->Flags |= ACPI_OBJECT_REPAIRED; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRepair_TSS + * + * PARAMETERS: Data - Pointer to validation data structure + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list + * descending by the power dissipation values. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRepair_TSS ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_STATUS Status; + + + Status = AcpiNsCheckSortedList (Data, ReturnObject, 5, 1, + ACPI_SORT_DESCENDING, "PowerDissipation"); + + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRepair_PSS + * + * PARAMETERS: Data - Pointer to validation data structure + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list + * by the CPU frequencies. Check that the power dissipation values + * are all proportional to CPU frequency (i.e., sorting by + * frequency should be the same as sorting by power.) + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRepair_PSS ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_OPERAND_OBJECT **OuterElements; + UINT32 OuterElementCount; + ACPI_OPERAND_OBJECT **Elements; + ACPI_OPERAND_OBJECT *ObjDesc; + UINT32 PreviousValue; + ACPI_STATUS Status; + UINT32 i; + + + /* + * Entries (sub-packages) in the _PSS Package must be sorted by power + * dissipation, in descending order. If it appears that the list is + * incorrectly sorted, sort it. We sort by CpuFrequency, since this + * should be proportional to the power. + */ + Status =AcpiNsCheckSortedList (Data, ReturnObject, 6, 0, + ACPI_SORT_DESCENDING, "CpuFrequency"); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* + * We now know the list is correctly sorted by CPU frequency. Check if + * the power dissipation values are proportional. + */ + PreviousValue = ACPI_UINT32_MAX; + OuterElements = ReturnObject->Package.Elements; + OuterElementCount = ReturnObject->Package.Count; + + for (i = 0; i < OuterElementCount; i++) + { + Elements = (*OuterElements)->Package.Elements; + ObjDesc = Elements[1]; /* Index1 = PowerDissipation */ + + if ((UINT32) ObjDesc->Integer.Value > PreviousValue) + { + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "SubPackage[%u,%u] - suspicious power dissipation values", + i-1, i)); + } + + PreviousValue = (UINT32) ObjDesc->Integer.Value; + OuterElements++; + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsCheckSortedList + * + * PARAMETERS: Data - Pointer to validation data structure + * ReturnObject - Pointer to the top-level returned object + * ExpectedCount - Minimum length of each sub-package + * SortIndex - Sub-package entry to sort on + * SortDirection - Ascending or descending + * SortKeyName - Name of the SortIndex field + * + * RETURN: Status. AE_OK if the list is valid and is sorted correctly or + * has been repaired by sorting the list. + * + * DESCRIPTION: Check if the package list is valid and sorted correctly by the + * SortIndex. If not, then sort the list. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsCheckSortedList ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT *ReturnObject, + UINT32 ExpectedCount, + UINT32 SortIndex, + UINT8 SortDirection, + char *SortKeyName) +{ + UINT32 OuterElementCount; + ACPI_OPERAND_OBJECT **OuterElements; + ACPI_OPERAND_OBJECT **Elements; + ACPI_OPERAND_OBJECT *ObjDesc; + UINT32 i; + UINT32 PreviousValue; + + + ACPI_FUNCTION_NAME (NsCheckSortedList); + + + /* The top-level object must be a package */ + + if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) + { + return (AE_AML_OPERAND_TYPE); + } + + /* + * NOTE: assumes list of sub-packages contains no NULL elements. + * Any NULL elements should have been removed by earlier call + * to AcpiNsRemoveNullElements. + */ + OuterElements = ReturnObject->Package.Elements; + OuterElementCount = ReturnObject->Package.Count; + if (!OuterElementCount) + { + return (AE_AML_PACKAGE_LIMIT); + } + + PreviousValue = 0; + if (SortDirection == ACPI_SORT_DESCENDING) + { + PreviousValue = ACPI_UINT32_MAX; + } + + /* Examine each subpackage */ + + for (i = 0; i < OuterElementCount; i++) + { + /* Each element of the top-level package must also be a package */ + + if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE) + { + return (AE_AML_OPERAND_TYPE); + } + + /* Each sub-package must have the minimum length */ + + if ((*OuterElements)->Package.Count < ExpectedCount) + { + return (AE_AML_PACKAGE_LIMIT); + } + + Elements = (*OuterElements)->Package.Elements; + ObjDesc = Elements[SortIndex]; + + if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) + { + return (AE_AML_OPERAND_TYPE); + } + + /* + * The list must be sorted in the specified order. If we detect a + * discrepancy, sort the entire list. + */ + if (((SortDirection == ACPI_SORT_ASCENDING) && + (ObjDesc->Integer.Value < PreviousValue)) || + ((SortDirection == ACPI_SORT_DESCENDING) && + (ObjDesc->Integer.Value > PreviousValue))) + { + AcpiNsSortList (ReturnObject->Package.Elements, + OuterElementCount, SortIndex, SortDirection); + + Data->Flags |= ACPI_OBJECT_REPAIRED; + + ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, + "%s: Repaired unsorted list - now sorted by %s\n", + Data->Pathname, SortKeyName)); + return (AE_OK); + } + + PreviousValue = (UINT32) ObjDesc->Integer.Value; + OuterElements++; + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsSortList + * + * PARAMETERS: Elements - Package object element list + * Count - Element count for above + * Index - Sort by which package element + * SortDirection - Ascending or Descending sort + * + * RETURN: None + * + * DESCRIPTION: Sort the objects that are in a package element list. + * + * NOTE: Assumes that all NULL elements have been removed from the package, + * and that all elements have been verified to be of type Integer. + * + *****************************************************************************/ + +static void +AcpiNsSortList ( + ACPI_OPERAND_OBJECT **Elements, + UINT32 Count, + UINT32 Index, + UINT8 SortDirection) +{ + ACPI_OPERAND_OBJECT *ObjDesc1; + ACPI_OPERAND_OBJECT *ObjDesc2; + ACPI_OPERAND_OBJECT *TempObj; + UINT32 i; + UINT32 j; + + + /* Simple bubble sort */ + + for (i = 1; i < Count; i++) + { + for (j = (Count - 1); j >= i; j--) + { + ObjDesc1 = Elements[j-1]->Package.Elements[Index]; + ObjDesc2 = Elements[j]->Package.Elements[Index]; + + if (((SortDirection == ACPI_SORT_ASCENDING) && + (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) || + + ((SortDirection == ACPI_SORT_DESCENDING) && + (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value))) + { + TempObj = Elements[j-1]; + Elements[j-1] = Elements[j]; + Elements[j] = TempObj; + } + } + } +} diff --git a/sys/contrib/dev/acpica/namespace/nssearch.c b/sys/contrib/dev/acpica/namespace/nssearch.c index 03863888165..b583fab1287 100644 --- a/sys/contrib/dev/acpica/namespace/nssearch.c +++ b/sys/contrib/dev/acpica/namespace/nssearch.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/namespace/nsutils.c b/sys/contrib/dev/acpica/namespace/nsutils.c index 666c79096fa..cc42f68b592 100644 --- a/sys/contrib/dev/acpica/namespace/nsutils.c +++ b/sys/contrib/dev/acpica/namespace/nsutils.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -857,25 +857,26 @@ AcpiNsExternalizeName ( /******************************************************************************* * - * FUNCTION: AcpiNsMapHandleToNode + * FUNCTION: AcpiNsValidateHandle * - * PARAMETERS: Handle - Handle to be converted to an Node + * PARAMETERS: Handle - Handle to be validated and typecast to a + * namespace node. * - * RETURN: A Name table entry pointer + * RETURN: A pointer to a namespace node * - * DESCRIPTION: Convert a namespace handle to a real Node + * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special + * cases for the root node. * - * Note: Real integer handles would allow for more verification + * NOTE: Real integer handles would allow for more verification * and keep all pointers within this subsystem - however this introduces - * more (and perhaps unnecessary) overhead. - * - * The current implemenation is basically a placeholder until such time comes - * that it is needed. + * more overhead and has not been necessary to this point. Drivers + * holding handles are typically notified before a node becomes invalid + * due to a table unload. * ******************************************************************************/ ACPI_NAMESPACE_NODE * -AcpiNsMapHandleToNode ( +AcpiNsValidateHandle ( ACPI_HANDLE Handle) { @@ -900,48 +901,6 @@ AcpiNsMapHandleToNode ( } -/******************************************************************************* - * - * FUNCTION: AcpiNsConvertEntryToHandle - * - * PARAMETERS: Node - Node to be converted to a Handle - * - * RETURN: A user handle - * - * DESCRIPTION: Convert a real Node to a namespace handle - * - ******************************************************************************/ - -ACPI_HANDLE -AcpiNsConvertEntryToHandle ( - ACPI_NAMESPACE_NODE *Node) -{ - - - /* - * Simple implementation for now; - */ - return ((ACPI_HANDLE) Node); - - -/* Example future implementation --------------------- - - if (!Node) - { - return (NULL); - } - - if (Node == AcpiGbl_RootNode) - { - return (ACPI_ROOT_OBJECT); - } - - - return ((ACPI_HANDLE) Node); -------------------------------------------------------*/ -} - - /******************************************************************************* * * FUNCTION: AcpiNsTerminate diff --git a/sys/contrib/dev/acpica/namespace/nswalk.c b/sys/contrib/dev/acpica/namespace/nswalk.c index fcfa5e1c228..f5eb8ff1157 100644 --- a/sys/contrib/dev/acpica/namespace/nswalk.c +++ b/sys/contrib/dev/acpica/namespace/nswalk.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -247,24 +247,27 @@ AcpiNsGetNextNodeTyped ( * MaxDepth - Depth to which search is to reach * Flags - Whether to unlock the NS before invoking * the callback routine - * UserFunction - Called when an object of "Type" is found - * Context - Passed to user function - * ReturnValue - from the UserFunction if terminated early. - * Otherwise, returns NULL. + * PreOrderVisit - Called during tree pre-order visit + * when an object of "Type" is found + * PostOrderVisit - Called during tree post-order visit + * when an object of "Type" is found + * Context - Passed to user function(s) above + * ReturnValue - from the UserFunction if terminated + * early. Otherwise, returns NULL. * RETURNS: Status * * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, * starting (and ending) at the node specified by StartHandle. - * The UserFunction is called whenever a node that matches - * the type parameter is found. If the user function returns + * The callback function is called whenever a node that matches + * the type parameter is found. If the callback function returns * a non-zero value, the search is terminated immediately and * this value is returned to the caller. * * The point of this procedure is to provide a generic namespace * walk routine that can be called from multiple places to - * provide multiple services; the User Function can be tailored - * to each task, whether it is a print function, a compare - * function, etc. + * provide multiple services; the callback function(s) can be + * tailored to each task, whether it is a print function, + * a compare function, etc. * ******************************************************************************/ @@ -274,7 +277,8 @@ AcpiNsWalkNamespace ( ACPI_HANDLE StartNode, UINT32 MaxDepth, UINT32 Flags, - ACPI_WALK_CALLBACK UserFunction, + ACPI_WALK_CALLBACK PreOrderVisit, + ACPI_WALK_CALLBACK PostOrderVisit, void *Context, void **ReturnValue) { @@ -284,6 +288,7 @@ AcpiNsWalkNamespace ( ACPI_NAMESPACE_NODE *ParentNode; ACPI_OBJECT_TYPE ChildType; UINT32 Level; + BOOLEAN NodePreviouslyVisited = FALSE; ACPI_FUNCTION_TRACE (NsWalkNamespace); @@ -299,7 +304,7 @@ AcpiNsWalkNamespace ( /* Null child means "get first node" */ ParentNode = StartNode; - ChildNode = NULL; + ChildNode = AcpiNsGetNextNode (ParentNode, NULL); ChildType = ACPI_TYPE_ANY; Level = 1; @@ -308,103 +313,139 @@ AcpiNsWalkNamespace ( * started. When Level is zero, the loop is done because we have * bubbled up to (and passed) the original parent handle (StartEntry) */ - while (Level > 0) + while (Level > 0 && ChildNode) { - /* Get the next node in this scope. Null if not found */ - Status = AE_OK; + + /* Found next child, get the type if we are not searching for ANY */ + + if (Type != ACPI_TYPE_ANY) + { + ChildType = ChildNode->Type; + } + + /* + * Ignore all temporary namespace nodes (created during control + * method execution) unless told otherwise. These temporary nodes + * can cause a race condition because they can be deleted during + * the execution of the user function (if the namespace is + * unlocked before invocation of the user function.) Only the + * debugger namespace dump will examine the temporary nodes. + */ + if ((ChildNode->Flags & ANOBJ_TEMPORARY) && + !(Flags & ACPI_NS_WALK_TEMP_NODES)) + { + Status = AE_CTRL_DEPTH; + } + + /* Type must match requested type */ + + else if (ChildType == Type) + { + /* + * Found a matching node, invoke the user callback function. + * Unlock the namespace if flag is set. + */ + if (Flags & ACPI_NS_WALK_UNLOCK) + { + MutexStatus = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (MutexStatus)) + { + return_ACPI_STATUS (MutexStatus); + } + } + + /* + * Invoke the user function, either pre-order or post-order + * or both. + */ + if (!NodePreviouslyVisited) + { + if (PreOrderVisit) + { + Status = PreOrderVisit (ChildNode, Level, + Context, ReturnValue); + } + } + else + { + if (PostOrderVisit) + { + Status = PostOrderVisit (ChildNode, Level, + Context, ReturnValue); + } + } + + if (Flags & ACPI_NS_WALK_UNLOCK) + { + MutexStatus = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (MutexStatus)) + { + return_ACPI_STATUS (MutexStatus); + } + } + + switch (Status) + { + case AE_OK: + case AE_CTRL_DEPTH: + + /* Just keep going */ + break; + + case AE_CTRL_TERMINATE: + + /* Exit now, with OK status */ + + return_ACPI_STATUS (AE_OK); + + default: + + /* All others are valid exceptions */ + + return_ACPI_STATUS (Status); + } + } + + /* + * Depth first search: Attempt to go down another level in the + * namespace if we are allowed to. Don't go any further if we have + * reached the caller specified maximum depth or if the user + * function has specified that the maximum depth has been reached. + */ + if (!NodePreviouslyVisited && + (Level < MaxDepth) && + (Status != AE_CTRL_DEPTH)) + { + if (ChildNode->Child) + { + /* There is at least one child of this node, visit it */ + + Level++; + ParentNode = ChildNode; + ChildNode = AcpiNsGetNextNode (ParentNode, NULL); + continue; + } + } + + /* No more children, re-visit this node */ + + if (!NodePreviouslyVisited) + { + NodePreviouslyVisited = TRUE; + continue; + } + + /* No more children, visit peers */ + ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode); if (ChildNode) { - /* Found next child, get the type if we are not searching for ANY */ - - if (Type != ACPI_TYPE_ANY) - { - ChildType = ChildNode->Type; - } - - /* - * Ignore all temporary namespace nodes (created during control - * method execution) unless told otherwise. These temporary nodes - * can cause a race condition because they can be deleted during - * the execution of the user function (if the namespace is - * unlocked before invocation of the user function.) Only the - * debugger namespace dump will examine the temporary nodes. - */ - if ((ChildNode->Flags & ANOBJ_TEMPORARY) && - !(Flags & ACPI_NS_WALK_TEMP_NODES)) - { - Status = AE_CTRL_DEPTH; - } - - /* Type must match requested type */ - - else if (ChildType == Type) - { - /* - * Found a matching node, invoke the user callback function. - * Unlock the namespace if flag is set. - */ - if (Flags & ACPI_NS_WALK_UNLOCK) - { - MutexStatus = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (MutexStatus)) - { - return_ACPI_STATUS (MutexStatus); - } - } - - Status = UserFunction (ChildNode, Level, Context, ReturnValue); - - if (Flags & ACPI_NS_WALK_UNLOCK) - { - MutexStatus = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (MutexStatus)) - { - return_ACPI_STATUS (MutexStatus); - } - } - - switch (Status) - { - case AE_OK: - case AE_CTRL_DEPTH: - - /* Just keep going */ - break; - - case AE_CTRL_TERMINATE: - - /* Exit now, with OK status */ - - return_ACPI_STATUS (AE_OK); - - default: - - /* All others are valid exceptions */ - - return_ACPI_STATUS (Status); - } - } - - /* - * Depth first search: Attempt to go down another level in the - * namespace if we are allowed to. Don't go any further if we have - * reached the caller specified maximum depth or if the user - * function has specified that the maximum depth has been reached. - */ - if ((Level < MaxDepth) && (Status != AE_CTRL_DEPTH)) - { - if (ChildNode->Child) - { - /* There is at least one child of this node, visit it */ - - Level++; - ParentNode = ChildNode; - ChildNode = NULL; - } - } + NodePreviouslyVisited = FALSE; } + + /* No peers, re-visit parent */ + else { /* @@ -414,6 +455,8 @@ AcpiNsWalkNamespace ( Level--; ChildNode = ParentNode; ParentNode = AcpiNsGetParentNode (ParentNode); + + NodePreviouslyVisited = TRUE; } } diff --git a/sys/contrib/dev/acpica/namespace/nsxfeval.c b/sys/contrib/dev/acpica/namespace/nsxfeval.c index 8eedd2a835e..8f8ee66034c 100644 --- a/sys/contrib/dev/acpica/namespace/nsxfeval.c +++ b/sys/contrib/dev/acpica/namespace/nsxfeval.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -281,7 +281,7 @@ AcpiEvaluateObject ( /* Convert and validate the device handle */ - Info->PrefixNode = AcpiNsMapHandleToNode (Handle); + Info->PrefixNode = AcpiNsValidateHandle (Handle); if (!Info->PrefixNode) { Status = AE_BAD_PARAMETER; @@ -544,8 +544,11 @@ AcpiNsResolveReferences ( * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for * StartObject - Handle in namespace where search begins * MaxDepth - Depth to which search is to reach - * UserFunction - Called when an object of "Type" is found - * Context - Passed to user function + * PreOrderVisit - Called during tree pre-order visit + * when an object of "Type" is found + * PostOrderVisit - Called during tree post-order visit + * when an object of "Type" is found + * Context - Passed to user function(s) above * ReturnValue - Location where return value of * UserFunction is put if terminated early * @@ -554,16 +557,16 @@ AcpiNsResolveReferences ( * * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, * starting (and ending) at the object specified by StartHandle. - * The UserFunction is called whenever an object that matches - * the type parameter is found. If the user function returns + * The callback function is called whenever an object that matches + * the type parameter is found. If the callback function returns * a non-zero value, the search is terminated immediately and this * value is returned to the caller. * * The point of this procedure is to provide a generic namespace * walk routine that can be called from multiple places to - * provide multiple services; the User Function can be tailored - * to each task, whether it is a print function, a compare - * function, etc. + * provide multiple services; the callback function(s) can be + * tailored to each task, whether it is a print function, + * a compare function, etc. * ******************************************************************************/ @@ -572,7 +575,8 @@ AcpiWalkNamespace ( ACPI_OBJECT_TYPE Type, ACPI_HANDLE StartObject, UINT32 MaxDepth, - ACPI_WALK_CALLBACK UserFunction, + ACPI_WALK_CALLBACK PreOrderVisit, + ACPI_WALK_CALLBACK PostOrderVisit, void *Context, void **ReturnValue) { @@ -586,7 +590,7 @@ AcpiWalkNamespace ( if ((Type > ACPI_TYPE_LOCAL_MAX) || (!MaxDepth) || - (!UserFunction)) + (!PreOrderVisit && !PostOrderVisit)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -621,7 +625,8 @@ AcpiWalkNamespace ( } Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, - ACPI_NS_WALK_UNLOCK, UserFunction, Context, ReturnValue); + ACPI_NS_WALK_UNLOCK, PreOrderVisit, + PostOrderVisit, Context, ReturnValue); (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); @@ -658,10 +663,11 @@ AcpiNsGetDeviceCallback ( ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; UINT32 Flags; - ACPI_DEVICE_ID Hid; - ACPI_COMPATIBLE_ID_LIST *Cid; + ACPI_DEVICE_ID *Hid; + ACPI_DEVICE_ID_LIST *Cid; UINT32 i; BOOLEAN Found; + int NoMatch; Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); @@ -670,7 +676,7 @@ AcpiNsGetDeviceCallback ( return (Status); } - Node = AcpiNsMapHandleToNode (ObjHandle); + Node = AcpiNsValidateHandle (ObjHandle); Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { @@ -682,27 +688,20 @@ AcpiNsGetDeviceCallback ( return (AE_BAD_PARAMETER); } - /* Run _STA to determine if device is present */ - - Status = AcpiUtExecute_STA (Node, &Flags); - if (ACPI_FAILURE (Status)) - { - return (AE_CTRL_DEPTH); - } - - if (!(Flags & ACPI_STA_DEVICE_PRESENT) && - !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) - { - /* - * Don't examine the children of the device only when the - * device is neither present nor functional. See ACPI spec, - * description of _STA for more information. - */ - return (AE_CTRL_DEPTH); - } - - /* Filter based on device HID & CID */ - + /* + * First, filter based on the device HID and CID. + * + * 01/2010: For this case where a specific HID is requested, we don't + * want to run _STA until we have an actual HID match. Thus, we will + * not unnecessarily execute _STA on devices for which the caller + * doesn't care about. Previously, _STA was executed unconditionally + * on all devices found here. + * + * A side-effect of this change is that now we will continue to search + * for a matching HID even under device trees where the parent device + * would have returned a _STA that indicates it is not present or + * not functioning (thus aborting the search on that branch). + */ if (Info->Hid != NULL) { Status = AcpiUtExecute_HID (Node, &Hid); @@ -715,7 +714,10 @@ AcpiNsGetDeviceCallback ( return (AE_CTRL_DEPTH); } - if (ACPI_STRNCMP (Hid.Value, Info->Hid, sizeof (Hid.Value)) != 0) + NoMatch = ACPI_STRCMP (Hid->String, Info->Hid); + ACPI_FREE (Hid); + + if (NoMatch) { /* * HID does not match, attempt match within the @@ -736,8 +738,7 @@ AcpiNsGetDeviceCallback ( Found = FALSE; for (i = 0; i < Cid->Count; i++) { - if (ACPI_STRNCMP (Cid->Id[i].Value, Info->Hid, - sizeof (ACPI_COMPATIBLE_ID)) == 0) + if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0) { /* Found a matching CID */ @@ -754,6 +755,25 @@ AcpiNsGetDeviceCallback ( } } + /* Run _STA to determine if device is present */ + + Status = AcpiUtExecute_STA (Node, &Flags); + if (ACPI_FAILURE (Status)) + { + return (AE_CTRL_DEPTH); + } + + if (!(Flags & ACPI_STA_DEVICE_PRESENT) && + !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) + { + /* + * Don't examine the children of the device only when the + * device is neither present nor functional. See ACPI spec, + * description of _STA for more information. + */ + return (AE_CTRL_DEPTH); + } + /* We have a valid device, invoke the user function */ Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, @@ -830,7 +850,7 @@ AcpiGetDevices ( Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - AcpiNsGetDeviceCallback, &Info, ReturnValue); + AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue); (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (Status); @@ -880,7 +900,7 @@ AcpiAttachData ( /* Convert and validate the handle */ - Node = AcpiNsMapHandleToNode (ObjHandle); + Node = AcpiNsValidateHandle (ObjHandle); if (!Node) { Status = AE_BAD_PARAMETER; @@ -935,7 +955,7 @@ AcpiDetachData ( /* Convert and validate the handle */ - Node = AcpiNsMapHandleToNode (ObjHandle); + Node = AcpiNsValidateHandle (ObjHandle); if (!Node) { Status = AE_BAD_PARAMETER; @@ -993,7 +1013,7 @@ AcpiGetData ( /* Convert and validate the handle */ - Node = AcpiNsMapHandleToNode (ObjHandle); + Node = AcpiNsValidateHandle (ObjHandle); if (!Node) { Status = AE_BAD_PARAMETER; diff --git a/sys/contrib/dev/acpica/namespace/nsxfname.c b/sys/contrib/dev/acpica/namespace/nsxfname.c index a2cd482150d..81344e1181a 100644 --- a/sys/contrib/dev/acpica/namespace/nsxfname.c +++ b/sys/contrib/dev/acpica/namespace/nsxfname.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -126,6 +126,14 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME ("nsxfname") +/* Local prototypes */ + +static char * +AcpiNsCopyDeviceId ( + ACPI_DEVICE_ID *Dest, + ACPI_DEVICE_ID *Source, + char *StringArea); + /****************************************************************************** * @@ -170,7 +178,7 @@ AcpiGetHandle ( if (Parent) { - PrefixNode = AcpiNsMapHandleToNode (Parent); + PrefixNode = AcpiNsValidateHandle (Parent); if (!PrefixNode) { return (AE_BAD_PARAMETER); @@ -192,7 +200,7 @@ AcpiGetHandle ( if (!ACPI_STRCMP (Pathname, ACPI_NS_ROOT_PATH)) { - *RetHandle = AcpiNsConvertEntryToHandle (AcpiGbl_RootNode); + *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, AcpiGbl_RootNode); return (AE_OK); } } @@ -208,7 +216,7 @@ AcpiGetHandle ( Status = AcpiNsGetNode (PrefixNode, Pathname, ACPI_NS_NO_UPSEARCH, &Node); if (ACPI_SUCCESS (Status)) { - *RetHandle = AcpiNsConvertEntryToHandle (Node); + *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node); } return (Status); @@ -274,7 +282,7 @@ AcpiGetName ( return (Status); } - Node = AcpiNsMapHandleToNode (Handle); + Node = AcpiNsValidateHandle (Handle); if (!Node) { Status = AE_BAD_PARAMETER; @@ -306,12 +314,44 @@ UnlockAndExit: ACPI_EXPORT_SYMBOL (AcpiGetName) +/****************************************************************************** + * + * FUNCTION: AcpiNsCopyDeviceId + * + * PARAMETERS: Dest - Pointer to the destination DEVICE_ID + * Source - Pointer to the source DEVICE_ID + * StringArea - Pointer to where to copy the dest string + * + * RETURN: Pointer to the next string area + * + * DESCRIPTION: Copy a single DEVICE_ID, including the string data. + * + ******************************************************************************/ + +static char * +AcpiNsCopyDeviceId ( + ACPI_DEVICE_ID *Dest, + ACPI_DEVICE_ID *Source, + char *StringArea) +{ + /* Create the destination DEVICE_ID */ + + Dest->String = StringArea; + Dest->Length = Source->Length; + + /* Copy actual string and return a pointer to the next string area */ + + ACPI_MEMCPY (StringArea, Source->String, Source->Length); + return (StringArea + Source->Length); +} + + /****************************************************************************** * * FUNCTION: AcpiGetObjectInfo * - * PARAMETERS: Handle - Object Handle - * Buffer - Where the info is returned + * PARAMETERS: Handle - Object Handle + * ReturnBuffer - Where the info is returned * * RETURN: Status * @@ -319,100 +359,98 @@ ACPI_EXPORT_SYMBOL (AcpiGetName) * namespace node and possibly by running several standard * control methods (Such as in the case of a device.) * + * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA, + * _ADR, _SxW, and _SxD methods. + * + * Note: Allocates the return buffer, must be freed by the caller. + * ******************************************************************************/ ACPI_STATUS AcpiGetObjectInfo ( ACPI_HANDLE Handle, - ACPI_BUFFER *Buffer) + ACPI_DEVICE_INFO **ReturnBuffer) { - ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; ACPI_DEVICE_INFO *Info; - ACPI_DEVICE_INFO *ReturnInfo; - ACPI_COMPATIBLE_ID_LIST *CidList = NULL; - ACPI_SIZE Size; + ACPI_DEVICE_ID_LIST *CidList = NULL; + ACPI_DEVICE_ID *Hid = NULL; + ACPI_DEVICE_ID *Uid = NULL; + char *NextIdString; + ACPI_OBJECT_TYPE Type; + ACPI_NAME Name; + UINT8 ParamCount= 0; + UINT8 Valid = 0; + UINT32 InfoSize; + UINT32 i; + ACPI_STATUS Status; /* Parameter validation */ - if (!Handle || !Buffer) + if (!Handle || !ReturnBuffer) { return (AE_BAD_PARAMETER); } - Status = AcpiUtValidateBuffer (Buffer); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - - Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_DEVICE_INFO)); - if (!Info) - { - return (AE_NO_MEMORY); - } - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { goto Cleanup; } - Node = AcpiNsMapHandleToNode (Handle); + Node = AcpiNsValidateHandle (Handle); if (!Node) { (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - Status = AE_BAD_PARAMETER; - goto Cleanup; + return (AE_BAD_PARAMETER); } - /* Init return structure */ + /* Get the namespace node data while the namespace is locked */ - Size = sizeof (ACPI_DEVICE_INFO); - - Info->Type = Node->Type; - Info->Name = Node->Name.Integer; - Info->Valid = 0; + InfoSize = sizeof (ACPI_DEVICE_INFO); + Type = Node->Type; + Name = Node->Name.Integer; if (Node->Type == ACPI_TYPE_METHOD) { - Info->ParamCount = Node->Object->Method.ParamCount; + ParamCount = Node->Object->Method.ParamCount; } Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { - goto Cleanup; + return (Status); } - /* If not a device, we are all done */ - - if (Info->Type == ACPI_TYPE_DEVICE) + if ((Type == ACPI_TYPE_DEVICE) || + (Type == ACPI_TYPE_PROCESSOR)) { /* - * Get extra info for ACPI Devices objects only: - * Run the Device _HID, _UID, _CID, _STA, _ADR and _SxD methods. + * Get extra info for ACPI Device/Processor objects only: + * Run the Device _HID, _UID, and _CID methods. * * Note: none of these methods are required, so they may or may - * not be present for this device. The Info->Valid bitfield is used - * to indicate which methods were found and ran successfully. + * not be present for this device. The Info->Valid bitfield is used + * to indicate which methods were found and run successfully. */ /* Execute the Device._HID method */ - Status = AcpiUtExecute_HID (Node, &Info->HardwareId); + Status = AcpiUtExecute_HID (Node, &Hid); if (ACPI_SUCCESS (Status)) { - Info->Valid |= ACPI_VALID_HID; + InfoSize += Hid->Length; + Valid |= ACPI_VALID_HID; } /* Execute the Device._UID method */ - Status = AcpiUtExecute_UID (Node, &Info->UniqueId); + Status = AcpiUtExecute_UID (Node, &Uid); if (ACPI_SUCCESS (Status)) { - Info->Valid |= ACPI_VALID_UID; + InfoSize += Uid->Length; + Valid |= ACPI_VALID_UID; } /* Execute the Device._CID method */ @@ -420,57 +458,151 @@ AcpiGetObjectInfo ( Status = AcpiUtExecute_CID (Node, &CidList); if (ACPI_SUCCESS (Status)) { - Size += CidList->Size; - Info->Valid |= ACPI_VALID_CID; + /* Add size of CID strings and CID pointer array */ + + InfoSize += (CidList->ListSize - sizeof (ACPI_DEVICE_ID_LIST)); + Valid |= ACPI_VALID_CID; } + } + + /* + * Now that we have the variable-length data, we can allocate the + * return buffer + */ + Info = ACPI_ALLOCATE_ZEROED (InfoSize); + if (!Info) + { + Status = AE_NO_MEMORY; + goto Cleanup; + } + + /* Get the fixed-length data */ + + if ((Type == ACPI_TYPE_DEVICE) || + (Type == ACPI_TYPE_PROCESSOR)) + { + /* + * Get extra info for ACPI Device/Processor objects only: + * Run the _STA, _ADR and, SxW, and _SxD methods. + * + * Note: none of these methods are required, so they may or may + * not be present for this device. The Info->Valid bitfield is used + * to indicate which methods were found and run successfully. + */ /* Execute the Device._STA method */ Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus); if (ACPI_SUCCESS (Status)) { - Info->Valid |= ACPI_VALID_STA; + Valid |= ACPI_VALID_STA; } /* Execute the Device._ADR method */ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, - &Info->Address); + &Info->Address); if (ACPI_SUCCESS (Status)) { - Info->Valid |= ACPI_VALID_ADR; + Valid |= ACPI_VALID_ADR; + } + + /* Execute the Device._SxW methods */ + + Status = AcpiUtExecutePowerMethods (Node, + AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS, + Info->LowestDstates); + if (ACPI_SUCCESS (Status)) + { + Valid |= ACPI_VALID_SXWS; } /* Execute the Device._SxD methods */ - Status = AcpiUtExecute_Sxds (Node, Info->HighestDstates); + Status = AcpiUtExecutePowerMethods (Node, + AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS, + Info->HighestDstates); if (ACPI_SUCCESS (Status)) { - Info->Valid |= ACPI_VALID_SXDS; + Valid |= ACPI_VALID_SXDS; } } - /* Validate/Allocate/Clear caller buffer */ - - Status = AcpiUtInitializeBuffer (Buffer, Size); - if (ACPI_FAILURE (Status)) + /* + * Create a pointer to the string area of the return buffer. + * Point to the end of the base ACPI_DEVICE_INFO structure. + */ + NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids); + if (CidList) { - goto Cleanup; + /* Point past the CID DEVICE_ID array */ + + NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_DEVICE_ID)); } - /* Populate the return buffer */ + /* + * Copy the HID, UID, and CIDs to the return buffer. The variable-length + * strings are copied to the reserved area at the end of the buffer. + * + * For HID and CID, check if the ID is a PCI Root Bridge. + */ + if (Hid) + { + NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId, + Hid, NextIdString); - ReturnInfo = Buffer->Pointer; - ACPI_MEMCPY (ReturnInfo, Info, sizeof (ACPI_DEVICE_INFO)); + if (AcpiUtIsPciRootBridge (Hid->String)) + { + Info->Flags |= ACPI_PCI_ROOT_BRIDGE; + } + } + + if (Uid) + { + NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId, + Uid, NextIdString); + } if (CidList) { - ACPI_MEMCPY (&ReturnInfo->CompatibilityId, CidList, CidList->Size); + Info->CompatibleIdList.Count = CidList->Count; + Info->CompatibleIdList.ListSize = CidList->ListSize; + + /* Copy each CID */ + + for (i = 0; i < CidList->Count; i++) + { + NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i], + &CidList->Ids[i], NextIdString); + + if (AcpiUtIsPciRootBridge (CidList->Ids[i].String)) + { + Info->Flags |= ACPI_PCI_ROOT_BRIDGE; + } + } } + /* Copy the fixed-length data */ + + Info->InfoSize = InfoSize; + Info->Type = Type; + Info->Name = Name; + Info->ParamCount = ParamCount; + Info->Valid = Valid; + + *ReturnBuffer = Info; + Status = AE_OK; + Cleanup: - ACPI_FREE (Info); + if (Hid) + { + ACPI_FREE (Hid); + } + if (Uid) + { + ACPI_FREE (Uid); + } if (CidList) { ACPI_FREE (CidList); diff --git a/sys/contrib/dev/acpica/namespace/nsxfobj.c b/sys/contrib/dev/acpica/namespace/nsxfobj.c index 26859ef0201..b43917b4574 100644 --- a/sys/contrib/dev/acpica/namespace/nsxfobj.c +++ b/sys/contrib/dev/acpica/namespace/nsxfobj.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -172,7 +172,7 @@ AcpiGetType ( /* Convert and validate the handle */ - Node = AcpiNsMapHandleToNode (Handle); + Node = AcpiNsValidateHandle (Handle); if (!Node) { (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); @@ -233,7 +233,7 @@ AcpiGetParent ( /* Convert and validate the handle */ - Node = AcpiNsMapHandleToNode (Handle); + Node = AcpiNsValidateHandle (Handle); if (!Node) { Status = AE_BAD_PARAMETER; @@ -243,7 +243,7 @@ AcpiGetParent ( /* Get the parent entry */ ParentNode = AcpiNsGetParentNode (Node); - *RetHandle = AcpiNsConvertEntryToHandle (ParentNode); + *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, ParentNode); /* Return exception if parent is null */ @@ -312,7 +312,7 @@ AcpiGetNextObject ( { /* Start search at the beginning of the specified scope */ - ParentNode = AcpiNsMapHandleToNode (Parent); + ParentNode = AcpiNsValidateHandle (Parent); if (!ParentNode) { Status = AE_BAD_PARAMETER; @@ -324,7 +324,7 @@ AcpiGetNextObject ( /* Non-null handle, ignore the parent */ /* Convert and validate the handle */ - ChildNode = AcpiNsMapHandleToNode (Child); + ChildNode = AcpiNsValidateHandle (Child); if (!ChildNode) { Status = AE_BAD_PARAMETER; @@ -343,7 +343,7 @@ AcpiGetNextObject ( if (RetHandle) { - *RetHandle = AcpiNsConvertEntryToHandle (Node); + *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node); } diff --git a/sys/contrib/dev/acpica/osunixxf.c b/sys/contrib/dev/acpica/osunixxf.c index 727916e4f88..a0e38e46c0a 100644 --- a/sys/contrib/dev/acpica/osunixxf.c +++ b/sys/contrib/dev/acpica/osunixxf.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -871,7 +871,7 @@ AcpiOsStall ( void AcpiOsSleep ( - ACPI_INTEGER milliseconds) + UINT64 milliseconds) { sleep (milliseconds / 1000); /* Sleep for whole seconds */ @@ -976,7 +976,7 @@ ACPI_STATUS AcpiOsWritePciConfiguration ( ACPI_PCI_ID *PciId, UINT32 Register, - ACPI_INTEGER Value, + UINT64 Value, UINT32 Width) { diff --git a/sys/contrib/dev/acpica/parser/psargs.c b/sys/contrib/dev/acpica/parser/psargs.c index c36982c6a6b..275993d99a9 100644 --- a/sys/contrib/dev/acpica/parser/psargs.c +++ b/sys/contrib/dev/acpica/parser/psargs.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -514,7 +514,7 @@ AcpiPsGetNextSimpleArg ( /* Get 1 byte from the AML stream */ Opcode = AML_BYTE_OP; - Arg->Common.Value.Integer = (ACPI_INTEGER) *Aml; + Arg->Common.Value.Integer = (UINT64) *Aml; Length = 1; break; diff --git a/sys/contrib/dev/acpica/parser/psloop.c b/sys/contrib/dev/acpica/parser/psloop.c index 09cbafe264f..73bfdf82656 100644 --- a/sys/contrib/dev/acpica/parser/psloop.c +++ b/sys/contrib/dev/acpica/parser/psloop.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -171,6 +171,13 @@ AcpiPsCompleteFinalOp ( ACPI_PARSE_OBJECT *Op, ACPI_STATUS Status); +static void +AcpiPsLinkModuleCode ( + ACPI_PARSE_OBJECT *ParentOp, + UINT8 *AmlStart, + UINT32 AmlLength, + ACPI_OWNER_ID OwnerId); + /******************************************************************************* * @@ -502,6 +509,7 @@ AcpiPsGetArguments ( { ACPI_STATUS Status = AE_OK; ACPI_PARSE_OBJECT *Arg = NULL; + const ACPI_OPCODE_INFO *OpInfo; ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState); @@ -558,13 +566,11 @@ AcpiPsGetArguments ( } - /* Special processing for certain opcodes */ - - /* TBD (remove): Temporary mechanism to disable this code if needed */ - -#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE - - if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS1) && + /* + * Handle executable code at "module-level". This refers to + * executable opcodes that appear outside of any control method. + */ + if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2) && ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0)) { /* @@ -580,6 +586,19 @@ AcpiPsGetArguments ( case AML_ELSE_OP: case AML_WHILE_OP: + /* + * Currently supported module-level opcodes are: + * IF/ELSE/WHILE. These appear to be the most common, + * and easiest to support since they open an AML + * package. + */ + if (WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1) + { + AcpiPsLinkModuleCode (Op->Common.Parent, AmlOpStart, + (UINT32) (WalkState->ParserState.PkgEnd - AmlOpStart), + WalkState->OwnerId); + } + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Pass1: Skipping an If/Else/While body\n")); @@ -590,10 +609,33 @@ AcpiPsGetArguments ( break; default: + /* + * Check for an unsupported executable opcode at module + * level. We must be in PASS1, the parent must be a SCOPE, + * The opcode class must be EXECUTE, and the opcode must + * not be an argument to another opcode. + */ + if ((WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1) && + (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP)) + { + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + if ((OpInfo->Class == AML_CLASS_EXECUTE) && + (!Arg)) + { + ACPI_WARNING ((AE_INFO, + "Detected an unsupported executable opcode " + "at module-level: [0x%.4X] at table offset 0x%.4X", + Op->Common.AmlOpcode, + (UINT32) (ACPI_PTR_DIFF (AmlOpStart, + WalkState->ParserState.AmlStart) + + sizeof (ACPI_TABLE_HEADER)))); + } + } break; } } -#endif + + /* Special processing for certain opcodes */ switch (Op->Common.AmlOpcode) { @@ -659,6 +701,97 @@ AcpiPsGetArguments ( } +/******************************************************************************* + * + * FUNCTION: AcpiPsLinkModuleCode + * + * PARAMETERS: ParentOp - Parent parser op + * AmlStart - Pointer to the AML + * AmlLength - Length of executable AML + * OwnerId - OwnerId of module level code + * + * RETURN: None. + * + * DESCRIPTION: Wrap the module-level code with a method object and link the + * object to the global list. Note, the mutex field of the method + * object is used to link multiple module-level code objects. + * + ******************************************************************************/ + +static void +AcpiPsLinkModuleCode ( + ACPI_PARSE_OBJECT *ParentOp, + UINT8 *AmlStart, + UINT32 AmlLength, + ACPI_OWNER_ID OwnerId) +{ + ACPI_OPERAND_OBJECT *Prev; + ACPI_OPERAND_OBJECT *Next; + ACPI_OPERAND_OBJECT *MethodObj; + ACPI_NAMESPACE_NODE *ParentNode; + + + /* Get the tail of the list */ + + Prev = Next = AcpiGbl_ModuleCodeList; + while (Next) + { + Prev = Next; + Next = Next->Method.Mutex; + } + + /* + * Insert the module level code into the list. Merge it if it is + * adjacent to the previous element. + */ + if (!Prev || + ((Prev->Method.AmlStart + Prev->Method.AmlLength) != AmlStart)) + { + /* Create, initialize, and link a new temporary method object */ + + MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); + if (!MethodObj) + { + return; + } + + if (ParentOp->Common.Node) + { + ParentNode = ParentOp->Common.Node; + } + else + { + ParentNode = AcpiGbl_RootNode; + } + + MethodObj->Method.AmlStart = AmlStart; + MethodObj->Method.AmlLength = AmlLength; + MethodObj->Method.OwnerId = OwnerId; + MethodObj->Method.Flags |= AOPOBJ_MODULE_LEVEL; + + /* + * Save the parent node in NextObject. This is cheating, but we + * don't want to expand the method object. + */ + MethodObj->Method.NextObject = + ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParentNode); + + if (!Prev) + { + AcpiGbl_ModuleCodeList = MethodObj; + } + else + { + Prev->Method.Mutex = MethodObj; + } + } + else + { + Prev->Method.AmlLength += AmlLength; + } +} + + /******************************************************************************* * * FUNCTION: AcpiPsCompleteOp diff --git a/sys/contrib/dev/acpica/parser/psopcode.c b/sys/contrib/dev/acpica/parser/psopcode.c index 9ce095f772f..6b65d79e5e3 100644 --- a/sys/contrib/dev/acpica/parser/psopcode.c +++ b/sys/contrib/dev/acpica/parser/psopcode.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/parser/psparse.c b/sys/contrib/dev/acpica/parser/psparse.c index eda132bd7fb..22783c233cb 100644 --- a/sys/contrib/dev/acpica/parser/psparse.c +++ b/sys/contrib/dev/acpica/parser/psparse.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -705,13 +705,11 @@ AcpiPsParseAml ( !PreviousWalkState->ImplicitReturnObj) { PreviousWalkState->ImplicitReturnObj = - AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + AcpiUtCreateIntegerObject ((UINT64) 0); if (!PreviousWalkState->ImplicitReturnObj) { return_ACPI_STATUS (AE_NO_MEMORY); } - - PreviousWalkState->ImplicitReturnObj->Integer.Value = 0; } /* Restart the calling control method */ diff --git a/sys/contrib/dev/acpica/parser/psscope.c b/sys/contrib/dev/acpica/parser/psscope.c index ce50c4a1c63..bf72f4562a6 100644 --- a/sys/contrib/dev/acpica/parser/psscope.c +++ b/sys/contrib/dev/acpica/parser/psscope.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/parser/pstree.c b/sys/contrib/dev/acpica/parser/pstree.c index d29b561126f..f4ffe4b1abe 100644 --- a/sys/contrib/dev/acpica/parser/pstree.c +++ b/sys/contrib/dev/acpica/parser/pstree.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/parser/psutils.c b/sys/contrib/dev/acpica/parser/psutils.c index c67ef366bc6..c34d0159d67 100644 --- a/sys/contrib/dev/acpica/parser/psutils.c +++ b/sys/contrib/dev/acpica/parser/psutils.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/parser/pswalk.c b/sys/contrib/dev/acpica/parser/pswalk.c index f5f3e902529..321d96e30d3 100644 --- a/sys/contrib/dev/acpica/parser/pswalk.c +++ b/sys/contrib/dev/acpica/parser/pswalk.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/parser/psxface.c b/sys/contrib/dev/acpica/parser/psxface.c index 5e9a4918af0..e9fc45de689 100644 --- a/sys/contrib/dev/acpica/parser/psxface.c +++ b/sys/contrib/dev/acpica/parser/psxface.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -394,11 +394,16 @@ AcpiPsExecuteMethod ( goto Cleanup; } + if (Info->ObjDesc->Method.Flags & AOPOBJ_MODULE_LEVEL) + { + WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL; + } + /* Invoke an internal method if necessary */ if (Info->ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY) { - Status = Info->ObjDesc->Method.Implementation (WalkState); + Status = Info->ObjDesc->Method.Extra.Implementation (WalkState); Info->ReturnObject = WalkState->ReturnDesc; /* Cleanup states */ @@ -417,15 +422,13 @@ AcpiPsExecuteMethod ( if (AcpiGbl_EnableInterpreterSlack) { WalkState->ImplicitReturnObj = - AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + AcpiUtCreateIntegerObject ((UINT64) 0); if (!WalkState->ImplicitReturnObj) { Status = AE_NO_MEMORY; AcpiDsDeleteWalkState (WalkState); goto Cleanup; } - - WalkState->ImplicitReturnObj->Integer.Value = 0; } /* Parse the AML */ diff --git a/sys/contrib/dev/acpica/resources/rsaddr.c b/sys/contrib/dev/acpica/resources/rsaddr.c index f3ce1071b6d..7ce78a59264 100644 --- a/sys/contrib/dev/acpica/resources/rsaddr.c +++ b/sys/contrib/dev/acpica/resources/rsaddr.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rscalc.c b/sys/contrib/dev/acpica/resources/rscalc.c index 8ef95f85c75..d3aca948553 100644 --- a/sys/contrib/dev/acpica/resources/rscalc.c +++ b/sys/contrib/dev/acpica/resources/rscalc.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rscreate.c b/sys/contrib/dev/acpica/resources/rscreate.c index d63c7c4d0a0..8e460d2e53c 100644 --- a/sys/contrib/dev/acpica/resources/rscreate.c +++ b/sys/contrib/dev/acpica/resources/rscreate.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -270,7 +270,7 @@ AcpiRsCreatePciRoutingTable ( /* * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a - * package that in turn contains an ACPI_INTEGER Address, a UINT8 Pin, + * package that in turn contains an UINT64 Address, a UINT8 Pin, * a Name, and a UINT8 SourceIndex. */ TopObjectList = PackageObject->Package.Elements; diff --git a/sys/contrib/dev/acpica/resources/rsdump.c b/sys/contrib/dev/acpica/resources/rsdump.c index e9d54d697f2..d73a0719dde 100644 --- a/sys/contrib/dev/acpica/resources/rsdump.c +++ b/sys/contrib/dev/acpica/resources/rsdump.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rsinfo.c b/sys/contrib/dev/acpica/resources/rsinfo.c index e52c6fd2210..f1bb441ee17 100644 --- a/sys/contrib/dev/acpica/resources/rsinfo.c +++ b/sys/contrib/dev/acpica/resources/rsinfo.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rsio.c b/sys/contrib/dev/acpica/resources/rsio.c index 9806f60206d..946b4d4d93e 100644 --- a/sys/contrib/dev/acpica/resources/rsio.c +++ b/sys/contrib/dev/acpica/resources/rsio.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rsirq.c b/sys/contrib/dev/acpica/resources/rsirq.c index 54e04229f0f..c409dc11e20 100644 --- a/sys/contrib/dev/acpica/resources/rsirq.c +++ b/sys/contrib/dev/acpica/resources/rsirq.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rslist.c b/sys/contrib/dev/acpica/resources/rslist.c index 44c2f023534..1b73cf21835 100644 --- a/sys/contrib/dev/acpica/resources/rslist.c +++ b/sys/contrib/dev/acpica/resources/rslist.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rsmemory.c b/sys/contrib/dev/acpica/resources/rsmemory.c index c20fe56c280..b7c64a225d6 100644 --- a/sys/contrib/dev/acpica/resources/rsmemory.c +++ b/sys/contrib/dev/acpica/resources/rsmemory.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rsmisc.c b/sys/contrib/dev/acpica/resources/rsmisc.c index 7ad344f25e6..37c1a050a7d 100644 --- a/sys/contrib/dev/acpica/resources/rsmisc.c +++ b/sys/contrib/dev/acpica/resources/rsmisc.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rsutils.c b/sys/contrib/dev/acpica/resources/rsutils.c index fabea698fe8..b0cd5380eb3 100644 --- a/sys/contrib/dev/acpica/resources/rsutils.c +++ b/sys/contrib/dev/acpica/resources/rsutils.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/resources/rsxface.c b/sys/contrib/dev/acpica/resources/rsxface.c index b72d58b8e3e..3e6399cceb9 100644 --- a/sys/contrib/dev/acpica/resources/rsxface.c +++ b/sys/contrib/dev/acpica/resources/rsxface.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -191,7 +191,7 @@ AcpiRsValidateParameters ( return_ACPI_STATUS (AE_BAD_PARAMETER); } - Node = AcpiNsMapHandleToNode (DeviceHandle); + Node = AcpiNsValidateHandle (DeviceHandle); if (!Node) { return_ACPI_STATUS (AE_BAD_PARAMETER); diff --git a/sys/contrib/dev/acpica/tables/tbfadt.c b/sys/contrib/dev/acpica/tables/tbfadt.c index e6e46799341..7f2ae36f435 100644 --- a/sys/contrib/dev/acpica/tables/tbfadt.c +++ b/sys/contrib/dev/acpica/tables/tbfadt.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/tables/tbfind.c b/sys/contrib/dev/acpica/tables/tbfind.c index a3a862dfe2e..d6cee630e13 100644 --- a/sys/contrib/dev/acpica/tables/tbfind.c +++ b/sys/contrib/dev/acpica/tables/tbfind.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/tables/tbinstal.c b/sys/contrib/dev/acpica/tables/tbinstal.c index d03b2949c33..be5561249e9 100644 --- a/sys/contrib/dev/acpica/tables/tbinstal.c +++ b/sys/contrib/dev/acpica/tables/tbinstal.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/tables/tbutils.c b/sys/contrib/dev/acpica/tables/tbutils.c index 28cd8dcbcae..25b0652943b 100644 --- a/sys/contrib/dev/acpica/tables/tbutils.c +++ b/sys/contrib/dev/acpica/tables/tbutils.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -124,6 +124,16 @@ /* Local prototypes */ +static void +AcpiTbFixString ( + char *String, + ACPI_SIZE Length); + +static void +AcpiTbCleanupTableHeader ( + ACPI_TABLE_HEADER *OutHeader, + ACPI_TABLE_HEADER *Header); + static ACPI_PHYSICAL_ADDRESS AcpiTbGetRootTableEntry ( UINT8 *TableEntry, @@ -183,6 +193,67 @@ AcpiTbTablesLoaded ( } +/******************************************************************************* + * + * FUNCTION: AcpiTbFixString + * + * PARAMETERS: String - String to be repaired + * Length - Maximum length + * + * RETURN: None + * + * DESCRIPTION: Replace every non-printable or non-ascii byte in the string + * with a question mark '?'. + * + ******************************************************************************/ + +static void +AcpiTbFixString ( + char *String, + ACPI_SIZE Length) +{ + + while (Length && *String) + { + if (!ACPI_IS_PRINT (*String)) + { + *String = '?'; + } + String++; + Length--; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbCleanupTableHeader + * + * PARAMETERS: OutHeader - Where the cleaned header is returned + * Header - Input ACPI table header + * + * RETURN: Returns the cleaned header in OutHeader + * + * DESCRIPTION: Copy the table header and ensure that all "string" fields in + * the header consist of printable characters. + * + ******************************************************************************/ + +static void +AcpiTbCleanupTableHeader ( + ACPI_TABLE_HEADER *OutHeader, + ACPI_TABLE_HEADER *Header) +{ + + ACPI_MEMCPY (OutHeader, Header, sizeof (ACPI_TABLE_HEADER)); + + AcpiTbFixString (OutHeader->Signature, ACPI_NAME_SIZE); + AcpiTbFixString (OutHeader->OemId, ACPI_OEM_ID_SIZE); + AcpiTbFixString (OutHeader->OemTableId, ACPI_OEM_TABLE_ID_SIZE); + AcpiTbFixString (OutHeader->AslCompilerId, ACPI_NAME_SIZE); +} + + /******************************************************************************* * * FUNCTION: AcpiTbPrintTableHeader @@ -201,6 +272,8 @@ AcpiTbPrintTableHeader ( ACPI_PHYSICAL_ADDRESS Address, ACPI_TABLE_HEADER *Header) { + ACPI_TABLE_HEADER LocalHeader; + /* * The reason that the Address is cast to a void pointer is so that we @@ -218,23 +291,29 @@ AcpiTbPrintTableHeader ( { /* RSDP has no common fields */ + ACPI_MEMCPY (LocalHeader.OemId, + ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId, ACPI_OEM_ID_SIZE); + AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE); + ACPI_INFO ((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", ACPI_CAST_PTR (void, Address), (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ? ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20, ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision, - ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId)); + LocalHeader.OemId)); } else { /* Standard ACPI table with full common header */ + AcpiTbCleanupTableHeader (&LocalHeader, Header); + ACPI_INFO ((AE_INFO, "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", - Header->Signature, ACPI_CAST_PTR (void, Address), - Header->Length, Header->Revision, Header->OemId, - Header->OemTableId, Header->OemRevision, Header->AslCompilerId, - Header->AslCompilerRevision)); + LocalHeader.Signature, ACPI_CAST_PTR (void, Address), + LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId, + LocalHeader.OemTableId, LocalHeader.OemRevision, + LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision)); } } diff --git a/sys/contrib/dev/acpica/tables/tbxface.c b/sys/contrib/dev/acpica/tables/tbxface.c index e6e9a291242..26f9472c5aa 100644 --- a/sys/contrib/dev/acpica/tables/tbxface.c +++ b/sys/contrib/dev/acpica/tables/tbxface.c @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/tables/tbxfroot.c b/sys/contrib/dev/acpica/tables/tbxfroot.c index c0d2b756c0b..021e2b60a05 100644 --- a/sys/contrib/dev/acpica/tables/tbxfroot.c +++ b/sys/contrib/dev/acpica/tables/tbxfroot.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/tools/acpiexec/aecommon.h b/sys/contrib/dev/acpica/tools/acpiexec/aecommon.h index 21d9cbdcbb1..0ceddea4960 100644 --- a/sys/contrib/dev/acpica/tools/acpiexec/aecommon.h +++ b/sys/contrib/dev/acpica/tools/acpiexec/aecommon.h @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -135,8 +135,17 @@ #include #include -extern FILE *AcpiGbl_DebugFile; -extern BOOLEAN AcpiGbl_IgnoreErrors; +extern FILE *AcpiGbl_DebugFile; +extern BOOLEAN AcpiGbl_IgnoreErrors; +extern UINT8 AcpiGbl_RegionFillValue; + + +typedef struct ae_table_desc +{ + ACPI_TABLE_HEADER *Table; + struct ae_table_desc *Next; + +} AE_TABLE_DESC; /* * Debug Regions @@ -170,7 +179,8 @@ AeCtrlCHandler ( ACPI_STATUS AeBuildLocalTables ( - ACPI_TABLE_HEADER *UserTable); + UINT32 TableCount, + AE_TABLE_DESC *TableList); ACPI_STATUS AeInstallTables ( @@ -222,7 +232,7 @@ AeRegionHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, void *HandlerContext, void *RegionContext); diff --git a/sys/contrib/dev/acpica/utilities/utalloc.c b/sys/contrib/dev/acpica/utilities/utalloc.c index aff2e1c4d31..8c6ed0b60bf 100644 --- a/sys/contrib/dev/acpica/utilities/utalloc.c +++ b/sys/contrib/dev/acpica/utilities/utalloc.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/utilities/utcache.c b/sys/contrib/dev/acpica/utilities/utcache.c index 42bef0c4238..cb487a19967 100644 --- a/sys/contrib/dev/acpica/utilities/utcache.c +++ b/sys/contrib/dev/acpica/utilities/utcache.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/utilities/utcopy.c b/sys/contrib/dev/acpica/utilities/utcopy.c index 8d919abe548..b16e14c1439 100644 --- a/sys/contrib/dev/acpica/utilities/utcopy.c +++ b/sys/contrib/dev/acpica/utilities/utcopy.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -422,11 +422,11 @@ AcpiUtCopyIelementToEelement ( * RETURN: Status * * DESCRIPTION: This function is called to place a package object in a user - * buffer. A package object by definition contains other objects. + * buffer. A package object by definition contains other objects. * * The buffer is assumed to have sufficient space for the object. - * The caller must have verified the buffer length needed using the - * AcpiUtGetObjectSize function before calling this function. + * The caller must have verified the buffer length needed using + * the AcpiUtGetObjectSize function before calling this function. * ******************************************************************************/ @@ -485,12 +485,12 @@ AcpiUtCopyIpackageToEpackage ( * FUNCTION: AcpiUtCopyIobjectToEobject * * PARAMETERS: InternalObject - The internal object to be converted - * BufferPtr - Where the object is returned + * RetBuffer - Where the object is returned * * RETURN: Status * - * DESCRIPTION: This function is called to build an API object to be returned to - * the caller. + * DESCRIPTION: This function is called to build an API object to be returned + * to the caller. * ******************************************************************************/ @@ -742,7 +742,7 @@ AcpiUtCopyEpackageToIpackage ( * PARAMETERS: ExternalObject - The external object to be converted * InternalObject - Where the internal object is returned * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: Converts an external object to an internal object. * @@ -784,7 +784,7 @@ AcpiUtCopyEobjectToIobject ( * * RETURN: Status * - * DESCRIPTION: Simple copy of one internal object to another. Reference count + * DESCRIPTION: Simple copy of one internal object to another. Reference count * of the destination object is preserved. * ******************************************************************************/ @@ -1034,10 +1034,11 @@ ErrorExit: * * FUNCTION: AcpiUtCopyIpackageToIpackage * - * PARAMETERS: *SourceObj - Pointer to the source package object - * *DestObj - Where the internal object is returned + * PARAMETERS: SourceObj - Pointer to the source package object + * DestObj - Where the internal object is returned + * WalkState - Current Walk state descriptor * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: This function is called to copy an internal package object * into another internal package object. @@ -1093,9 +1094,9 @@ AcpiUtCopyIpackageToIpackage ( * * FUNCTION: AcpiUtCopyIobjectToIobject * - * PARAMETERS: WalkState - Current walk state - * SourceDesc - The internal object to be copied + * PARAMETERS: SourceDesc - The internal object to be copied * DestDesc - Where the copied object is returned + * WalkState - Current walk state * * RETURN: Status * diff --git a/sys/contrib/dev/acpica/utilities/utdebug.c b/sys/contrib/dev/acpica/utilities/utdebug.c index 9dacaabb18f..99670b58f36 100644 --- a/sys/contrib/dev/acpica/utilities/utdebug.c +++ b/sys/contrib/dev/acpica/utilities/utdebug.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -598,7 +598,7 @@ AcpiUtValueExit ( const char *FunctionName, const char *ModuleName, UINT32 ComponentId, - ACPI_INTEGER Value) + UINT64 Value) { AcpiDebugPrint (ACPI_LV_FUNCTIONS, diff --git a/sys/contrib/dev/acpica/utilities/utdelete.c b/sys/contrib/dev/acpica/utilities/utdelete.c index 1b975a22179..bd6490dac3b 100644 --- a/sys/contrib/dev/acpica/utilities/utdelete.c +++ b/sys/contrib/dev/acpica/utilities/utdelete.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/utilities/uteval.c b/sys/contrib/dev/acpica/utilities/uteval.c index 9241afa7623..be1e45e1aa9 100644 --- a/sys/contrib/dev/acpica/utilities/uteval.c +++ b/sys/contrib/dev/acpica/utilities/uteval.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -118,32 +118,18 @@ #include #include #include -#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("uteval") -/* Local prototypes */ - -static void -AcpiUtCopyIdString ( - char *Destination, - char *Source, - ACPI_SIZE MaxLength); - -static ACPI_STATUS -AcpiUtTranslateOneCid ( - ACPI_OPERAND_OBJECT *ObjDesc, - ACPI_COMPATIBLE_ID *OneCid); - /* * Strings supported by the _OSI predefined (internal) method. * * March 2009: Removed "Linux" as this host no longer wants to respond true * for this string. Basically, the only safe OS strings are windows-related - * and in many or most cases represent the only test path within the + * and in many or most cases represent the only test path within the * BIOS-provided ASL code. * * The second element of each entry is used to track the newest version of @@ -160,6 +146,9 @@ static const ACPI_INTERFACE_INFO AcpiInterfacesSupported[] = {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ + {"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ + {"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ + {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ /* Feature Group Strings */ @@ -280,7 +269,7 @@ Exit: * RETURN: Status * * DESCRIPTION: Evaluates a namespace object and verifies the type of the - * return object. Common code that simplifies accessing objects + * return object. Common code that simplifies accessing objects * that have required return objects of fixed types. * * NOTE: Internal function, no parameter validation @@ -376,7 +365,7 @@ AcpiUtEvaluateObject ( (!ExpectedReturnBtypes)) { /* - * We received a return object, but one was not expected. This can + * We received a return object, but one was not expected. This can * happen frequently if the "implicit return" feature is enabled. * Just delete the return object and return AE_OK. */ @@ -419,12 +408,12 @@ Cleanup: * * PARAMETERS: ObjectName - Object name to be evaluated * DeviceNode - Node for the device - * Address - Where the value is returned + * Value - Where the value is returned * * RETURN: Status * * DESCRIPTION: Evaluates a numeric namespace object for a selected device - * and stores result in *Address. + * and stores result in *Value. * * NOTE: Internal function, no parameter validation * @@ -434,7 +423,7 @@ ACPI_STATUS AcpiUtEvaluateNumericObject ( char *ObjectName, ACPI_NAMESPACE_NODE *DeviceNode, - ACPI_INTEGER *Address) + UINT64 *Value) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; @@ -452,326 +441,7 @@ AcpiUtEvaluateNumericObject ( /* Get the returned Integer */ - *Address = ObjDesc->Integer.Value; - - /* On exit, we must delete the return object */ - - AcpiUtRemoveReference (ObjDesc); - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiUtCopyIdString - * - * PARAMETERS: Destination - Where to copy the string - * Source - Source string - * MaxLength - Length of the destination buffer - * - * RETURN: None - * - * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. - * Performs removal of a leading asterisk if present -- workaround - * for a known issue on a bunch of machines. - * - ******************************************************************************/ - -static void -AcpiUtCopyIdString ( - char *Destination, - char *Source, - ACPI_SIZE MaxLength) -{ - - /* - * Workaround for ID strings that have a leading asterisk. This construct - * is not allowed by the ACPI specification (ID strings must be - * alphanumeric), but enough existing machines have this embedded in their - * ID strings that the following code is useful. - */ - if (*Source == '*') - { - Source++; - } - - /* Do the actual copy */ - - ACPI_STRNCPY (Destination, Source, MaxLength); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiUtExecute_HID - * - * PARAMETERS: DeviceNode - Node for the device - * Hid - Where the HID is returned - * - * RETURN: Status - * - * DESCRIPTION: Executes the _HID control method that returns the hardware - * ID of the device. - * - * NOTE: Internal function, no parameter validation - * - ******************************************************************************/ - -ACPI_STATUS -AcpiUtExecute_HID ( - ACPI_NAMESPACE_NODE *DeviceNode, - ACPI_DEVICE_ID *Hid) -{ - ACPI_OPERAND_OBJECT *ObjDesc; - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (UtExecute_HID); - - - Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__HID, - ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - - if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) - { - /* Convert the Numeric HID to string */ - - AcpiExEisaIdToString ((UINT32) ObjDesc->Integer.Value, Hid->Value); - } - else - { - /* Copy the String HID from the returned object */ - - AcpiUtCopyIdString (Hid->Value, ObjDesc->String.Pointer, - sizeof (Hid->Value)); - } - - /* On exit, we must delete the return object */ - - AcpiUtRemoveReference (ObjDesc); - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiUtTranslateOneCid - * - * PARAMETERS: ObjDesc - _CID object, must be integer or string - * OneCid - Where the CID string is returned - * - * RETURN: Status - * - * DESCRIPTION: Return a numeric or string _CID value as a string. - * (Compatible ID) - * - * NOTE: Assumes a maximum _CID string length of - * ACPI_MAX_CID_LENGTH. - * - ******************************************************************************/ - -static ACPI_STATUS -AcpiUtTranslateOneCid ( - ACPI_OPERAND_OBJECT *ObjDesc, - ACPI_COMPATIBLE_ID *OneCid) -{ - - - switch (ObjDesc->Common.Type) - { - case ACPI_TYPE_INTEGER: - - /* Convert the Numeric CID to string */ - - AcpiExEisaIdToString ((UINT32) ObjDesc->Integer.Value, OneCid->Value); - return (AE_OK); - - case ACPI_TYPE_STRING: - - if (ObjDesc->String.Length > ACPI_MAX_CID_LENGTH) - { - return (AE_AML_STRING_LIMIT); - } - - /* Copy the String CID from the returned object */ - - AcpiUtCopyIdString (OneCid->Value, ObjDesc->String.Pointer, - ACPI_MAX_CID_LENGTH); - return (AE_OK); - - default: - - return (AE_TYPE); - } -} - - -/******************************************************************************* - * - * FUNCTION: AcpiUtExecute_CID - * - * PARAMETERS: DeviceNode - Node for the device - * ReturnCidList - Where the CID list is returned - * - * RETURN: Status - * - * DESCRIPTION: Executes the _CID control method that returns one or more - * compatible hardware IDs for the device. - * - * NOTE: Internal function, no parameter validation - * - ******************************************************************************/ - -ACPI_STATUS -AcpiUtExecute_CID ( - ACPI_NAMESPACE_NODE *DeviceNode, - ACPI_COMPATIBLE_ID_LIST **ReturnCidList) -{ - ACPI_OPERAND_OBJECT *ObjDesc; - ACPI_STATUS Status; - UINT32 Count; - UINT32 Size; - ACPI_COMPATIBLE_ID_LIST *CidList; - UINT32 i; - - - ACPI_FUNCTION_TRACE (UtExecute_CID); - - - /* Evaluate the _CID method for this device */ - - Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CID, - ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, - &ObjDesc); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - - /* Get the number of _CIDs returned */ - - Count = 1; - if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE) - { - Count = ObjDesc->Package.Count; - } - - /* Allocate a worst-case buffer for the _CIDs */ - - Size = (((Count - 1) * sizeof (ACPI_COMPATIBLE_ID)) + - sizeof (ACPI_COMPATIBLE_ID_LIST)); - - CidList = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) Size); - if (!CidList) - { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* Init CID list */ - - CidList->Count = Count; - CidList->Size = Size; - - /* - * A _CID can return either a single compatible ID or a package of - * compatible IDs. Each compatible ID can be one of the following: - * 1) Integer (32 bit compressed EISA ID) or - * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") - */ - - /* The _CID object can be either a single CID or a package (list) of CIDs */ - - if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE) - { - /* Translate each package element */ - - for (i = 0; i < Count; i++) - { - Status = AcpiUtTranslateOneCid (ObjDesc->Package.Elements[i], - &CidList->Id[i]); - if (ACPI_FAILURE (Status)) - { - break; - } - } - } - else - { - /* Only one CID, translate to a string */ - - Status = AcpiUtTranslateOneCid (ObjDesc, CidList->Id); - } - - /* Cleanup on error */ - - if (ACPI_FAILURE (Status)) - { - ACPI_FREE (CidList); - } - else - { - *ReturnCidList = CidList; - } - - /* On exit, we must delete the _CID return object */ - - AcpiUtRemoveReference (ObjDesc); - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiUtExecute_UID - * - * PARAMETERS: DeviceNode - Node for the device - * Uid - Where the UID is returned - * - * RETURN: Status - * - * DESCRIPTION: Executes the _UID control method that returns the hardware - * ID of the device. - * - * NOTE: Internal function, no parameter validation - * - ******************************************************************************/ - -ACPI_STATUS -AcpiUtExecute_UID ( - ACPI_NAMESPACE_NODE *DeviceNode, - ACPI_DEVICE_ID *Uid) -{ - ACPI_OPERAND_OBJECT *ObjDesc; - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (UtExecute_UID); - - - Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__UID, - ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - - if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) - { - /* Convert the Numeric UID to string */ - - AcpiExUnsignedIntegerToString (ObjDesc->Integer.Value, Uid->Value); - } - else - { - /* Copy the String UID from the returned object */ - - AcpiUtCopyIdString (Uid->Value, ObjDesc->String.Pointer, - sizeof (Uid->Value)); - } + *Value = ObjDesc->Integer.Value; /* On exit, we must delete the return object */ @@ -838,63 +508,68 @@ AcpiUtExecute_STA ( /******************************************************************************* * - * FUNCTION: AcpiUtExecute_Sxds + * FUNCTION: AcpiUtExecutePowerMethods * * PARAMETERS: DeviceNode - Node for the device - * Flags - Where the status flags are returned + * MethodNames - Array of power method names + * MethodCount - Number of methods to execute + * OutValues - Where the power method values are returned * - * RETURN: Status + * RETURN: Status, OutValues * - * DESCRIPTION: Executes _STA for selected device and stores results in - * *Flags. + * DESCRIPTION: Executes the specified power methods for the device and returns + * the result(s). * * NOTE: Internal function, no parameter validation * ******************************************************************************/ ACPI_STATUS -AcpiUtExecute_Sxds ( +AcpiUtExecutePowerMethods ( ACPI_NAMESPACE_NODE *DeviceNode, - UINT8 *Highest) + const char **MethodNames, + UINT8 MethodCount, + UINT8 *OutValues) { ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; + ACPI_STATUS FinalStatus = AE_NOT_FOUND; UINT32 i; - ACPI_FUNCTION_TRACE (UtExecute_Sxds); + ACPI_FUNCTION_TRACE (UtExecutePowerMethods); - for (i = 0; i < 4; i++) + for (i = 0; i < MethodCount; i++) { - Highest[i] = 0xFF; + /* + * Execute the power method (_SxD or _SxW). The only allowable + * return type is an Integer. + */ Status = AcpiUtEvaluateObject (DeviceNode, - ACPI_CAST_PTR (char, AcpiGbl_HighestDstateNames[i]), + ACPI_CAST_PTR (char, MethodNames[i]), ACPI_BTYPE_INTEGER, &ObjDesc); - if (ACPI_FAILURE (Status)) + if (ACPI_SUCCESS (Status)) { - if (Status != AE_NOT_FOUND) - { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "%s on Device %4.4s, %s\n", - ACPI_CAST_PTR (char, AcpiGbl_HighestDstateNames[i]), - AcpiUtGetNodeName (DeviceNode), - AcpiFormatException (Status))); - - return_ACPI_STATUS (Status); - } - } - else - { - /* Extract the Dstate value */ - - Highest[i] = (UINT8) ObjDesc->Integer.Value; + OutValues[i] = (UINT8) ObjDesc->Integer.Value; /* Delete the return object */ AcpiUtRemoveReference (ObjDesc); + FinalStatus = AE_OK; /* At least one value is valid */ + continue; } + + OutValues[i] = ACPI_UINT8_MAX; + if (Status == AE_NOT_FOUND) + { + continue; /* Ignore if not found */ + } + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Failed %s on Device %4.4s, %s\n", + ACPI_CAST_PTR (char, MethodNames[i]), + AcpiUtGetNodeName (DeviceNode), AcpiFormatException (Status))); } - return_ACPI_STATUS (AE_OK); + return_ACPI_STATUS (FinalStatus); } diff --git a/sys/contrib/dev/acpica/utilities/utglobal.c b/sys/contrib/dev/acpica/utilities/utglobal.c index b7c6657be3d..df32fc069f8 100644 --- a/sys/contrib/dev/acpica/utilities/utglobal.c +++ b/sys/contrib/dev/acpica/utilities/utglobal.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -172,7 +172,16 @@ const char *AcpiGbl_SleepStateNames[ACPI_S_STATE_COUNT] = "\\_S5_" }; -const char *AcpiGbl_HighestDstateNames[4] = +const char *AcpiGbl_LowestDstateNames[ACPI_NUM_SxW_METHODS] = +{ + "_S0W", + "_S1W", + "_S2W", + "_S3W", + "_S4W" +}; + +const char *AcpiGbl_HighestDstateNames[ACPI_NUM_SxD_METHODS] = { "_S1D", "_S2D", @@ -322,7 +331,7 @@ static const char AcpiGbl_HexToAscii[] = char AcpiUtHexToAsciiChar ( - ACPI_INTEGER Integer, + UINT64 Integer, UINT32 Position) { @@ -398,6 +407,7 @@ const char *AcpiGbl_RegionTypes[ACPI_NUM_PREDEFINED_REGIONS] = "SMBus", "SystemCMOS", "PCIBARTarget", + "IPMI", "DataTable" }; @@ -928,6 +938,7 @@ AcpiUtInitGlobals ( /* Namespace */ + AcpiGbl_ModuleCodeList = NULL; AcpiGbl_RootNode = NULL; AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME; AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED; @@ -938,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 diff --git a/sys/contrib/dev/acpica/utilities/utids.c b/sys/contrib/dev/acpica/utilities/utids.c new file mode 100644 index 00000000000..6e5f8333ffb --- /dev/null +++ b/sys/contrib/dev/acpica/utilities/utids.c @@ -0,0 +1,497 @@ +/****************************************************************************** + * + * Module Name: utids - support for device IDs - HID, UID, CID + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2010, 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. + * + *****************************************************************************/ + +#define __UTIDS_C__ + +#include +#include +#include + + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utids") + +/* Local prototypes */ + +static void +AcpiUtCopyIdString ( + char *Destination, + char *Source); + + +/******************************************************************************* + * + * FUNCTION: AcpiUtCopyIdString + * + * PARAMETERS: Destination - Where to copy the string + * Source - Source string + * + * RETURN: None + * + * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. + * Performs removal of a leading asterisk if present -- workaround + * for a known issue on a bunch of machines. + * + ******************************************************************************/ + +static void +AcpiUtCopyIdString ( + char *Destination, + char *Source) +{ + + /* + * Workaround for ID strings that have a leading asterisk. This construct + * is not allowed by the ACPI specification (ID strings must be + * alphanumeric), but enough existing machines have this embedded in their + * ID strings that the following code is useful. + */ + if (*Source == '*') + { + Source++; + } + + /* Do the actual copy */ + + ACPI_STRCPY (Destination, Source); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtExecute_HID + * + * PARAMETERS: DeviceNode - Node for the device + * ReturnId - Where the string HID is returned + * + * RETURN: Status + * + * DESCRIPTION: Executes the _HID control method that returns the hardware + * ID of the device. The HID is either an 32-bit encoded EISAID + * Integer or a String. A string is always returned. An EISAID + * is converted to a string. + * + * NOTE: Internal function, no parameter validation + * + ******************************************************************************/ + +ACPI_STATUS +AcpiUtExecute_HID ( + ACPI_NAMESPACE_NODE *DeviceNode, + ACPI_DEVICE_ID **ReturnId) +{ + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_DEVICE_ID *Hid; + UINT32 Length; + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (UtExecute_HID); + + + Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__HID, + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + /* Get the size of the String to be returned, includes null terminator */ + + if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) + { + Length = ACPI_EISAID_STRING_SIZE; + } + else + { + Length = ObjDesc->String.Length + 1; + } + + /* Allocate a buffer for the HID */ + + Hid = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_DEVICE_ID) + (ACPI_SIZE) Length); + if (!Hid) + { + Status = AE_NO_MEMORY; + goto Cleanup; + } + + /* Area for the string starts after DEVICE_ID struct */ + + Hid->String = ACPI_ADD_PTR (char, Hid, sizeof (ACPI_DEVICE_ID)); + + /* Convert EISAID to a string or simply copy existing string */ + + if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) + { + AcpiExEisaIdToString (Hid->String, ObjDesc->Integer.Value); + } + else + { + AcpiUtCopyIdString (Hid->String, ObjDesc->String.Pointer); + } + + Hid->Length = Length; + *ReturnId = Hid; + + +Cleanup: + + /* On exit, we must delete the return object */ + + AcpiUtRemoveReference (ObjDesc); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtExecute_UID + * + * PARAMETERS: DeviceNode - Node for the device + * ReturnId - Where the string UID is returned + * + * RETURN: Status + * + * DESCRIPTION: Executes the _UID control method that returns the unique + * ID of the device. The UID is either a 64-bit Integer (NOT an + * EISAID) or a string. Always returns a string. A 64-bit integer + * is converted to a decimal string. + * + * NOTE: Internal function, no parameter validation + * + ******************************************************************************/ + +ACPI_STATUS +AcpiUtExecute_UID ( + ACPI_NAMESPACE_NODE *DeviceNode, + ACPI_DEVICE_ID **ReturnId) +{ + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_DEVICE_ID *Uid; + UINT32 Length; + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (UtExecute_UID); + + + Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__UID, + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + /* Get the size of the String to be returned, includes null terminator */ + + if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) + { + Length = ACPI_MAX64_DECIMAL_DIGITS + 1; + } + else + { + Length = ObjDesc->String.Length + 1; + } + + /* Allocate a buffer for the UID */ + + Uid = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_DEVICE_ID) + (ACPI_SIZE) Length); + if (!Uid) + { + Status = AE_NO_MEMORY; + goto Cleanup; + } + + /* Area for the string starts after DEVICE_ID struct */ + + Uid->String = ACPI_ADD_PTR (char, Uid, sizeof (ACPI_DEVICE_ID)); + + /* Convert an Integer to string, or just copy an existing string */ + + if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) + { + AcpiExIntegerToString (Uid->String, ObjDesc->Integer.Value); + } + else + { + AcpiUtCopyIdString (Uid->String, ObjDesc->String.Pointer); + } + + Uid->Length = Length; + *ReturnId = Uid; + + +Cleanup: + + /* On exit, we must delete the return object */ + + AcpiUtRemoveReference (ObjDesc); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtExecute_CID + * + * PARAMETERS: DeviceNode - Node for the device + * ReturnCidList - Where the CID list is returned + * + * RETURN: Status, list of CID strings + * + * DESCRIPTION: Executes the _CID control method that returns one or more + * compatible hardware IDs for the device. + * + * NOTE: Internal function, no parameter validation + * + * A _CID method can return either a single compatible ID or a package of + * compatible IDs. Each compatible ID can be one of the following: + * 1) Integer (32 bit compressed EISA ID) or + * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") + * + * The Integer CIDs are converted to string format by this function. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiUtExecute_CID ( + ACPI_NAMESPACE_NODE *DeviceNode, + ACPI_DEVICE_ID_LIST **ReturnCidList) +{ + ACPI_OPERAND_OBJECT **CidObjects; + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_DEVICE_ID_LIST *CidList; + char *NextIdString; + UINT32 StringAreaSize; + UINT32 Length; + UINT32 CidListSize; + ACPI_STATUS Status; + UINT32 Count; + UINT32 i; + + + ACPI_FUNCTION_TRACE (UtExecute_CID); + + + /* Evaluate the _CID method for this device */ + + Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CID, + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, + &ObjDesc); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + /* + * Get the count and size of the returned _CIDs. _CID can return either + * a Package of Integers/Strings or a single Integer or String. + * Note: This section also validates that all CID elements are of the + * correct type (Integer or String). + */ + if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE) + { + Count = ObjDesc->Package.Count; + CidObjects = ObjDesc->Package.Elements; + } + else /* Single Integer or String CID */ + { + Count = 1; + CidObjects = &ObjDesc; + } + + StringAreaSize = 0; + for (i = 0; i < Count; i++) + { + /* String lengths include null terminator */ + + switch (CidObjects[i]->Common.Type) + { + case ACPI_TYPE_INTEGER: + StringAreaSize += ACPI_EISAID_STRING_SIZE; + break; + + case ACPI_TYPE_STRING: + StringAreaSize += CidObjects[i]->String.Length + 1; + break; + + default: + Status = AE_TYPE; + goto Cleanup; + } + } + + /* + * Now that we know the length of the CIDs, allocate return buffer: + * 1) Size of the base structure + + * 2) Size of the CID DEVICE_ID array + + * 3) Size of the actual CID strings + */ + CidListSize = sizeof (ACPI_DEVICE_ID_LIST) + + ((Count - 1) * sizeof (ACPI_DEVICE_ID)) + + StringAreaSize; + + CidList = ACPI_ALLOCATE_ZEROED (CidListSize); + if (!CidList) + { + Status = AE_NO_MEMORY; + goto Cleanup; + } + + /* Area for CID strings starts after the CID DEVICE_ID array */ + + NextIdString = ACPI_CAST_PTR (char, CidList->Ids) + + ((ACPI_SIZE) Count * sizeof (ACPI_DEVICE_ID)); + + /* Copy/convert the CIDs to the return buffer */ + + for (i = 0; i < Count; i++) + { + if (CidObjects[i]->Common.Type == ACPI_TYPE_INTEGER) + { + /* Convert the Integer (EISAID) CID to a string */ + + AcpiExEisaIdToString (NextIdString, CidObjects[i]->Integer.Value); + Length = ACPI_EISAID_STRING_SIZE; + } + else /* ACPI_TYPE_STRING */ + { + /* Copy the String CID from the returned object */ + + AcpiUtCopyIdString (NextIdString, CidObjects[i]->String.Pointer); + Length = CidObjects[i]->String.Length + 1; + } + + CidList->Ids[i].String = NextIdString; + CidList->Ids[i].Length = Length; + NextIdString += Length; + } + + /* Finish the CID list */ + + CidList->Count = Count; + CidList->ListSize = CidListSize; + *ReturnCidList = CidList; + + +Cleanup: + + /* On exit, we must delete the _CID return object */ + + AcpiUtRemoveReference (ObjDesc); + return_ACPI_STATUS (Status); +} + diff --git a/sys/contrib/dev/acpica/utilities/utinit.c b/sys/contrib/dev/acpica/utilities/utinit.c index 4ab8bd9c860..fe8e3dcdacd 100644 --- a/sys/contrib/dev/acpica/utilities/utinit.c +++ b/sys/contrib/dev/acpica/utilities/utinit.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -184,12 +184,12 @@ AcpiUtTerminate ( * * FUNCTION: AcpiUtSubsystemShutdown * - * PARAMETERS: none + * PARAMETERS: None * - * RETURN: none + * RETURN: None * - * DESCRIPTION: Shutdown the various subsystems. Don't delete the mutex - * objects here -- because the AML debugger may be still running. + * DESCRIPTION: Shutdown the various components. Do not delete the mutex + * objects here, because the AML debugger may be still running. * ******************************************************************************/ @@ -197,24 +197,8 @@ void AcpiUtSubsystemShutdown ( void) { - ACPI_FUNCTION_TRACE (UtSubsystemShutdown); - /* Just exit if subsystem is already shutdown */ - - if (AcpiGbl_Shutdown) - { - ACPI_ERROR ((AE_INFO, - "ACPI Subsystem is already terminated")); - return_VOID; - } - - /* Subsystem appears active, go ahead and shut it down */ - - AcpiGbl_Shutdown = TRUE; - AcpiGbl_StartupFlags = 0; - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Shutting down ACPI Subsystem\n")); #ifndef ACPI_ASL_COMPILER diff --git a/sys/contrib/dev/acpica/utilities/utlock.c b/sys/contrib/dev/acpica/utilities/utlock.c index cbe1cb92802..9d4423f6ce2 100644 --- a/sys/contrib/dev/acpica/utilities/utlock.c +++ b/sys/contrib/dev/acpica/utilities/utlock.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/utilities/utmath.c b/sys/contrib/dev/acpica/utilities/utmath.c index ec9449b4817..f6d5f7cddb5 100644 --- a/sys/contrib/dev/acpica/utilities/utmath.c +++ b/sys/contrib/dev/acpica/utilities/utmath.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -149,9 +149,9 @@ ACPI_STATUS AcpiUtShortDivide ( - ACPI_INTEGER Dividend, + UINT64 Dividend, UINT32 Divisor, - ACPI_INTEGER *OutQuotient, + UINT64 *OutQuotient, UINT32 *OutRemainder) { UINT64_OVERLAY DividendOvl; @@ -213,10 +213,10 @@ AcpiUtShortDivide ( ACPI_STATUS AcpiUtDivide ( - ACPI_INTEGER InDividend, - ACPI_INTEGER InDivisor, - ACPI_INTEGER *OutQuotient, - ACPI_INTEGER *OutRemainder) + UINT64 InDividend, + UINT64 InDivisor, + UINT64 *OutQuotient, + UINT64 *OutRemainder) { UINT64_OVERLAY Dividend; UINT64_OVERLAY Divisor; @@ -293,8 +293,8 @@ AcpiUtDivide ( * The 64-bit remainder must be generated. */ Partial1 = Quotient.Part.Lo * Divisor.Part.Hi; - Partial2.Full = (ACPI_INTEGER) Quotient.Part.Lo * Divisor.Part.Lo; - Partial3.Full = (ACPI_INTEGER) Partial2.Part.Hi + Partial1; + Partial2.Full = (UINT64) Quotient.Part.Lo * Divisor.Part.Lo; + Partial3.Full = (UINT64) Partial2.Part.Hi + Partial1; Remainder.Part.Hi = Partial3.Part.Lo; Remainder.Part.Lo = Partial2.Part.Lo; @@ -362,9 +362,9 @@ AcpiUtDivide ( ACPI_STATUS AcpiUtShortDivide ( - ACPI_INTEGER InDividend, + UINT64 InDividend, UINT32 Divisor, - ACPI_INTEGER *OutQuotient, + UINT64 *OutQuotient, UINT32 *OutRemainder) { @@ -395,10 +395,10 @@ AcpiUtShortDivide ( ACPI_STATUS AcpiUtDivide ( - ACPI_INTEGER InDividend, - ACPI_INTEGER InDivisor, - ACPI_INTEGER *OutQuotient, - ACPI_INTEGER *OutRemainder) + UINT64 InDividend, + UINT64 InDivisor, + UINT64 *OutQuotient, + UINT64 *OutRemainder) { ACPI_FUNCTION_TRACE (UtDivide); diff --git a/sys/contrib/dev/acpica/utilities/utmisc.c b/sys/contrib/dev/acpica/utilities/utmisc.c index 6652e0102a6..3bef62c1c6e 100644 --- a/sys/contrib/dev/acpica/utilities/utmisc.c +++ b/sys/contrib/dev/acpica/utilities/utmisc.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -124,6 +124,12 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utmisc") +/* + * Common suffix for messages + */ +#define ACPI_COMMON_MSG_SUFFIX \ + AcpiOsPrintf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, ModuleName, LineNumber) + /******************************************************************************* * @@ -205,6 +211,40 @@ AcpiUtValidateException ( } +/******************************************************************************* + * + * FUNCTION: AcpiUtIsPciRootBridge + * + * PARAMETERS: Id - The HID/CID in string format + * + * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge + * + * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. + * + ******************************************************************************/ + +BOOLEAN +AcpiUtIsPciRootBridge ( + char *Id) +{ + + /* + * Check if this is a PCI root bridge. + * ACPI 3.0+: check for a PCI Express root also. + */ + if (!(ACPI_STRCMP (Id, + PCI_ROOT_HID_STRING)) || + + !(ACPI_STRCMP (Id, + PCI_EXPRESS_ROOT_HID_STRING))) + { + return (TRUE); + } + + return (FALSE); +} + + /******************************************************************************* * * FUNCTION: AcpiUtIsAmlTable @@ -889,12 +929,12 @@ ACPI_STATUS AcpiUtStrtoul64 ( char *String, UINT32 Base, - ACPI_INTEGER *RetInteger) + UINT64 *RetInteger) { UINT32 ThisDigit = 0; - ACPI_INTEGER ReturnValue = 0; - ACPI_INTEGER Quotient; - ACPI_INTEGER Dividend; + UINT64 ReturnValue = 0; + UINT64 Quotient; + UINT64 Dividend; UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE); UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4); UINT8 ValidDigits = 0; @@ -1031,7 +1071,7 @@ AcpiUtStrtoul64 ( /* Divide the digit into the correct position */ - (void) AcpiUtShortDivide ((Dividend - (ACPI_INTEGER) ThisDigit), + (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL); if (ReturnValue > Quotient) @@ -1283,7 +1323,7 @@ AcpiError ( va_start (args, Format); AcpiOsVprintf (Format, args); - AcpiOsPrintf (" %8.8X %s-%u\n", ACPI_CA_VERSION, ModuleName, LineNumber); + ACPI_COMMON_MSG_SUFFIX; va_end (args); } @@ -1302,7 +1342,7 @@ AcpiException ( va_start (args, Format); AcpiOsVprintf (Format, args); - AcpiOsPrintf (" %8.8X %s-%u\n", ACPI_CA_VERSION, ModuleName, LineNumber); + ACPI_COMMON_MSG_SUFFIX; va_end (args); } @@ -1320,7 +1360,7 @@ AcpiWarning ( va_start (args, Format); AcpiOsVprintf (Format, args); - AcpiOsPrintf (" %8.8X %s-%u\n", ACPI_CA_VERSION, ModuleName, LineNumber); + ACPI_COMMON_MSG_SUFFIX; va_end (args); } @@ -1353,3 +1393,98 @@ ACPI_EXPORT_SYMBOL (AcpiWarning) ACPI_EXPORT_SYMBOL (AcpiInfo) +/******************************************************************************* + * + * FUNCTION: AcpiUtPredefinedWarning + * + * PARAMETERS: ModuleName - Caller's module name (for error output) + * LineNumber - Caller's line number (for error output) + * Pathname - Full pathname to the node + * NodeFlags - From Namespace node for the method/object + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Warnings for the predefined validation module. Messages are + * only emitted the first time a problem with a particular + * method/object is detected. This prevents a flood of error + * messages for methods that are repeatedly evaluated. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiUtPredefinedWarning ( + const char *ModuleName, + UINT32 LineNumber, + char *Pathname, + UINT8 NodeFlags, + const char *Format, + ...) +{ + va_list args; + + + /* + * Warning messages for this method/object will be disabled after the + * first time a validation fails or an object is successfully repaired. + */ + if (NodeFlags & ANOBJ_EVALUATED) + { + return; + } + + AcpiOsPrintf ("ACPI Warning for %s: ", Pathname); + + va_start (args, Format); + AcpiOsVprintf (Format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end (args); +} + +/******************************************************************************* + * + * FUNCTION: AcpiUtPredefinedInfo + * + * PARAMETERS: ModuleName - Caller's module name (for error output) + * LineNumber - Caller's line number (for error output) + * Pathname - Full pathname to the node + * NodeFlags - From Namespace node for the method/object + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Info messages for the predefined validation module. Messages + * are only emitted the first time a problem with a particular + * method/object is detected. This prevents a flood of + * messages for methods that are repeatedly evaluated. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiUtPredefinedInfo ( + const char *ModuleName, + UINT32 LineNumber, + char *Pathname, + UINT8 NodeFlags, + const char *Format, + ...) +{ + va_list args; + + + /* + * Warning messages for this method/object will be disabled after the + * first time a validation fails or an object is successfully repaired. + */ + if (NodeFlags & ANOBJ_EVALUATED) + { + return; + } + + AcpiOsPrintf ("ACPI Info for %s: ", Pathname); + + va_start (args, Format); + AcpiOsVprintf (Format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end (args); +} diff --git a/sys/contrib/dev/acpica/utilities/utmutex.c b/sys/contrib/dev/acpica/utilities/utmutex.c index e9bb4a84543..d0d47d496d7 100644 --- a/sys/contrib/dev/acpica/utilities/utmutex.c +++ b/sys/contrib/dev/acpica/utilities/utmutex.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -128,7 +128,7 @@ static ACPI_STATUS AcpiUtCreateMutex ( ACPI_MUTEX_HANDLE MutexId); -static ACPI_STATUS +static void AcpiUtDeleteMutex ( ACPI_MUTEX_HANDLE MutexId); @@ -216,7 +216,7 @@ AcpiUtMutexTerminate ( for (i = 0; i < ACPI_NUM_MUTEX; i++) { - (void) AcpiUtDeleteMutex (i); + AcpiUtDeleteMutex (i); } /* Delete the spinlocks */ @@ -253,11 +253,6 @@ AcpiUtCreateMutex ( ACPI_FUNCTION_TRACE_U32 (UtCreateMutex, MutexId); - if (MutexId > ACPI_MAX_MUTEX) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - if (!AcpiGbl_MutexInfo[MutexId].Mutex) { Status = AcpiOsCreateMutex (&AcpiGbl_MutexInfo[MutexId].Mutex); @@ -281,7 +276,7 @@ AcpiUtCreateMutex ( * ******************************************************************************/ -static ACPI_STATUS +static void AcpiUtDeleteMutex ( ACPI_MUTEX_HANDLE MutexId) { @@ -289,17 +284,10 @@ AcpiUtDeleteMutex ( ACPI_FUNCTION_TRACE_U32 (UtDeleteMutex, MutexId); - if (MutexId > ACPI_MAX_MUTEX) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - AcpiOsDeleteMutex (AcpiGbl_MutexInfo[MutexId].Mutex); AcpiGbl_MutexInfo[MutexId].Mutex = NULL; AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED; - - return_ACPI_STATUS (AE_OK); } diff --git a/sys/contrib/dev/acpica/utilities/utobject.c b/sys/contrib/dev/acpica/utilities/utobject.c index 3c96d78f6f2..f3ec7920c4f 100644 --- a/sys/contrib/dev/acpica/utilities/utobject.c +++ b/sys/contrib/dev/acpica/utilities/utobject.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -279,6 +279,41 @@ AcpiUtCreatePackageObject ( } +/******************************************************************************* + * + * FUNCTION: AcpiUtCreateIntegerObject + * + * PARAMETERS: InitialValue - Initial value for the integer + * + * RETURN: Pointer to a new Integer object, null on failure + * + * DESCRIPTION: Create an initialized integer object + * + ******************************************************************************/ + +ACPI_OPERAND_OBJECT * +AcpiUtCreateIntegerObject ( + UINT64 InitialValue) +{ + ACPI_OPERAND_OBJECT *IntegerDesc; + + + ACPI_FUNCTION_TRACE (UtCreateIntegerObject); + + + /* Create and initialize a new integer object */ + + IntegerDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + if (!IntegerDesc) + { + return_PTR (NULL); + } + + IntegerDesc->Integer.Value = InitialValue; + return_PTR (IntegerDesc); +} + + /******************************************************************************* * * FUNCTION: AcpiUtCreateBufferObject diff --git a/sys/contrib/dev/acpica/utilities/utresrc.c b/sys/contrib/dev/acpica/utilities/utresrc.c index 541b9708ed0..e07cee4333c 100644 --- a/sys/contrib/dev/acpica/utilities/utresrc.c +++ b/sys/contrib/dev/acpica/utilities/utresrc.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/utilities/utstate.c b/sys/contrib/dev/acpica/utilities/utstate.c index fd18dda34f4..39afcda86ac 100644 --- a/sys/contrib/dev/acpica/utilities/utstate.c +++ b/sys/contrib/dev/acpica/utilities/utstate.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/utilities/uttrack.c b/sys/contrib/dev/acpica/utilities/uttrack.c index f399d97bf3d..5c48544792e 100644 --- a/sys/contrib/dev/acpica/utilities/uttrack.c +++ b/sys/contrib/dev/acpica/utilities/uttrack.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License diff --git a/sys/contrib/dev/acpica/utilities/utxface.c b/sys/contrib/dev/acpica/utilities/utxface.c index df3ded7cf61..d000b0c765a 100644 --- a/sys/contrib/dev/acpica/utilities/utxface.c +++ b/sys/contrib/dev/acpica/utilities/utxface.c @@ -8,7 +8,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. * All rights reserved. * * 2. License @@ -359,6 +359,16 @@ AcpiInitializeObjects ( } } + /* + * Execute any module-level code that was detected during the table load + * phase. Although illegal since ACPI 2.0, there are many machines that + * contain this type of code. Each block of detected executable AML code + * outside of any control method is wrapped with a temporary control + * method object and placed on a global list. The methods on this list + * are executed below. + */ + AcpiNsExecModuleCodeList (); + /* * Initialize the objects that remain uninitialized. This runs the * executable AML that may be part of the declaration of these objects: @@ -437,7 +447,7 @@ ACPI_EXPORT_SYMBOL (AcpiInitializeObjects) * * RETURN: Status * - * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources. + * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources. * ******************************************************************************/ @@ -451,15 +461,28 @@ AcpiTerminate ( ACPI_FUNCTION_TRACE (AcpiTerminate); + /* Just exit if subsystem is already shutdown */ + + if (AcpiGbl_Shutdown) + { + ACPI_ERROR ((AE_INFO, "ACPI Subsystem is already terminated")); + return_ACPI_STATUS (AE_OK); + } + + /* Subsystem appears active, go ahead and shut it down */ + + AcpiGbl_Shutdown = TRUE; + AcpiGbl_StartupFlags = 0; + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); + /* Terminate the AML Debugger if present */ - ACPI_DEBUGGER_EXEC(AcpiGbl_DbTerminateThreads = TRUE); + ACPI_DEBUGGER_EXEC (AcpiGbl_DbTerminateThreads = TRUE); /* Shutdown and free all resources */ AcpiUtSubsystemShutdown (); - /* Free the mutex objects */ AcpiUtMutexTerminate (); @@ -480,8 +503,8 @@ AcpiTerminate ( ACPI_EXPORT_SYMBOL (AcpiTerminate) -#ifndef ACPI_ASL_COMPILER +#ifndef ACPI_ASL_COMPILER /******************************************************************************* * * FUNCTION: AcpiSubsystemStatus diff --git a/sys/dev/acpi_support/acpi_ibm.c b/sys/dev/acpi_support/acpi_ibm.c index 22899820b1f..2b6ac5dc187 100644 --- a/sys/dev/acpi_support/acpi_ibm.c +++ b/sys/dev/acpi_support/acpi_ibm.c @@ -526,7 +526,7 @@ out: static int acpi_ibm_sysctl_get(struct acpi_ibm_softc *sc, int method) { - ACPI_INTEGER val_ec; + UINT64 val_ec; int val = 0, key; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); @@ -657,7 +657,7 @@ static int acpi_ibm_sysctl_set(struct acpi_ibm_softc *sc, int method, int arg) { int val, step; - ACPI_INTEGER val_ec; + UINT64 val_ec; ACPI_OBJECT Arg; ACPI_OBJECT_LIST Args; ACPI_STATUS status; diff --git a/sys/dev/acpi_support/acpi_panasonic.c b/sys/dev/acpi_support/acpi_panasonic.c index 595ca08e524..ad8b2391bc5 100644 --- a/sys/dev/acpi_support/acpi_panasonic.c +++ b/sys/dev/acpi_support/acpi_panasonic.c @@ -82,9 +82,9 @@ static int acpi_panasonic_attach(device_t dev); static int acpi_panasonic_detach(device_t dev); static int acpi_panasonic_shutdown(device_t dev); static int acpi_panasonic_sysctl(SYSCTL_HANDLER_ARGS); -static ACPI_INTEGER acpi_panasonic_sinf(ACPI_HANDLE h, ACPI_INTEGER index); -static void acpi_panasonic_sset(ACPI_HANDLE h, ACPI_INTEGER index, - ACPI_INTEGER val); +static UINT64 acpi_panasonic_sinf(ACPI_HANDLE h, UINT64 index); +static void acpi_panasonic_sset(ACPI_HANDLE h, UINT64 index, + UINT64 val); static int acpi_panasonic_hkey_event(struct acpi_panasonic_softc *sc, ACPI_HANDLE h, UINT32 *arg); static void acpi_panasonic_hkey_action(struct acpi_panasonic_softc *sc, @@ -265,12 +265,12 @@ out: return (error); } -static ACPI_INTEGER -acpi_panasonic_sinf(ACPI_HANDLE h, ACPI_INTEGER index) +static UINT64 +acpi_panasonic_sinf(ACPI_HANDLE h, UINT64 index) { ACPI_BUFFER buf; ACPI_OBJECT *res; - ACPI_INTEGER ret; + UINT64 ret; ACPI_SERIAL_ASSERT(panasonic); ret = -1; @@ -286,7 +286,7 @@ acpi_panasonic_sinf(ACPI_HANDLE h, ACPI_INTEGER index) } static void -acpi_panasonic_sset(ACPI_HANDLE h, ACPI_INTEGER index, ACPI_INTEGER val) +acpi_panasonic_sset(ACPI_HANDLE h, UINT64 index, UINT64 val) { ACPI_OBJECT_LIST args; ACPI_OBJECT obj[2]; @@ -394,7 +394,7 @@ acpi_panasonic_hkey_event(struct acpi_panasonic_softc *sc, ACPI_HANDLE h, { ACPI_BUFFER buf; ACPI_OBJECT *res; - ACPI_INTEGER val; + UINT64 val; int status; ACPI_SERIAL_ASSERT(panasonic); diff --git a/sys/dev/acpi_support/acpi_wmi.c b/sys/dev/acpi_support/acpi_wmi.c index 07c2d712eb6..9da790c5fda 100644 --- a/sys/dev/acpi_support/acpi_wmi.c +++ b/sys/dev/acpi_support/acpi_wmi.c @@ -141,7 +141,7 @@ static void acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context); static ACPI_STATUS acpi_wmi_ec_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, UINT32 width, - ACPI_INTEGER *value, void *context, + UINT64 *value, void *context, void *region_context); /* helpers */ static ACPI_STATUS acpi_wmi_read_wdg_blocks(ACPI_HANDLE h); @@ -646,12 +646,12 @@ acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) */ static ACPI_STATUS acpi_wmi_ec_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, - UINT32 width, ACPI_INTEGER *value, void *context, + UINT32 width, UINT64 *value, void *context, void *region_context) { struct acpi_wmi_softc *sc; int i; - ACPI_INTEGER ec_data; + UINT64 ec_data; UINT8 ec_addr; ACPI_STATUS status; @@ -672,7 +672,7 @@ acpi_wmi_ec_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, case ACPI_READ: status = ACPI_EC_READ(sc->ec_dev, ec_addr, &ec_data, 1); if (ACPI_SUCCESS(status)) - *value |= ((ACPI_INTEGER)ec_data) << i; + *value |= ((UINT64)ec_data) << i; break; case ACPI_WRITE: ec_data = (UINT8)((*value) >> i); diff --git a/sys/dev/acpica/Osd/OsdHardware.c b/sys/dev/acpica/Osd/OsdHardware.c index cf3cdd74e73..822bf78545d 100644 --- a/sys/dev/acpica/Osd/OsdHardware.c +++ b/sys/dev/acpica/Osd/OsdHardware.c @@ -145,7 +145,7 @@ AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, void *Value, ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *PciId, UINT32 Register, - ACPI_INTEGER Value, UINT32 Width) + UINT64 Value, UINT32 Width) { u_int32_t byte_width = Width / 8; diff --git a/sys/dev/acpica/Osd/OsdSchedule.c b/sys/dev/acpica/Osd/OsdSchedule.c index b8153a33fb7..70717d5d650 100644 --- a/sys/dev/acpica/Osd/OsdSchedule.c +++ b/sys/dev/acpica/Osd/OsdSchedule.c @@ -215,7 +215,7 @@ AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, } void -AcpiOsSleep(ACPI_INTEGER Milliseconds) +AcpiOsSleep(UINT64 Milliseconds) { int timo; diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 0ba8f9f6b59..8de8d900472 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -864,24 +864,20 @@ static int acpi_child_pnpinfo_str_method(device_t cbdev, device_t child, char *buf, size_t buflen) { - ACPI_BUFFER adbuf = {ACPI_ALLOCATE_BUFFER, NULL}; - ACPI_DEVICE_INFO *adinfo; struct acpi_device *dinfo = device_get_ivars(child); - char *end; - int error; + ACPI_DEVICE_INFO *adinfo; - error = AcpiGetObjectInfo(dinfo->ad_handle, &adbuf); - adinfo = (ACPI_DEVICE_INFO *) adbuf.Pointer; - if (error) + if (ACPI_FAILURE(AcpiGetObjectInfo(dinfo->ad_handle, &adinfo))) { snprintf(buf, buflen, "unknown"); - else - snprintf(buf, buflen, "_HID=%s _UID=%lu", - (adinfo->Valid & ACPI_VALID_HID) ? - adinfo->HardwareId.Value : "none", - (adinfo->Valid & ACPI_VALID_UID) ? - strtoul(adinfo->UniqueId.Value, &end, 10) : 0); - if (adinfo) - AcpiOsFree(adinfo); + return (0); + } + + snprintf(buf, buflen, "_HID=%s _UID=%lu", + (adinfo->Valid & ACPI_VALID_HID) ? + adinfo->HardwareId.String : "none", + (adinfo->Valid & ACPI_VALID_UID) ? + strtoul(adinfo->UniqueId.String, NULL, 10) : 0UL); + AcpiOsFree(adinfo); return (0); } @@ -1315,31 +1311,21 @@ static uint32_t acpi_isa_get_logicalid(device_t dev) { ACPI_DEVICE_INFO *devinfo; - ACPI_BUFFER buf; ACPI_HANDLE h; - ACPI_STATUS error; - u_int32_t pnpid; + uint32_t pnpid; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); - pnpid = 0; - buf.Pointer = NULL; - buf.Length = ACPI_ALLOCATE_BUFFER; - /* Fetch and validate the HID. */ - if ((h = acpi_get_handle(dev)) == NULL) - goto out; - error = AcpiGetObjectInfo(h, &buf); - if (ACPI_FAILURE(error)) - goto out; - devinfo = (ACPI_DEVICE_INFO *)buf.Pointer; + if ((h = acpi_get_handle(dev)) == NULL || + ACPI_FAILURE(AcpiGetObjectInfo(h, &devinfo))) + return_VALUE (0); - if ((devinfo->Valid & ACPI_VALID_HID) != 0) - pnpid = PNP_EISAID(devinfo->HardwareId.Value); + pnpid = (devinfo->Valid & ACPI_VALID_HID) != 0 && + devinfo->HardwareId.Length >= ACPI_EISAID_STRING_SIZE ? + PNP_EISAID(devinfo->HardwareId.String) : 0; + AcpiOsFree(devinfo); -out: - if (buf.Pointer != NULL) - AcpiOsFree(buf.Pointer); return_VALUE (pnpid); } @@ -1347,41 +1333,36 @@ static int acpi_isa_get_compatid(device_t dev, uint32_t *cids, int count) { ACPI_DEVICE_INFO *devinfo; - ACPI_BUFFER buf; + ACPI_DEVICE_ID *ids; ACPI_HANDLE h; - ACPI_STATUS error; uint32_t *pnpid; - int valid, i; + int i, valid; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); pnpid = cids; - valid = 0; - buf.Pointer = NULL; - buf.Length = ACPI_ALLOCATE_BUFFER; /* Fetch and validate the CID */ - if ((h = acpi_get_handle(dev)) == NULL) - goto out; - error = AcpiGetObjectInfo(h, &buf); - if (ACPI_FAILURE(error)) - goto out; - devinfo = (ACPI_DEVICE_INFO *)buf.Pointer; - if ((devinfo->Valid & ACPI_VALID_CID) == 0) - goto out; + if ((h = acpi_get_handle(dev)) == NULL || + ACPI_FAILURE(AcpiGetObjectInfo(h, &devinfo))) + return_VALUE (0); - if (devinfo->CompatibilityId.Count < count) - count = devinfo->CompatibilityId.Count; - for (i = 0; i < count; i++) { - if (strncmp(devinfo->CompatibilityId.Id[i].Value, "PNP", 3) != 0) - continue; - *pnpid++ = PNP_EISAID(devinfo->CompatibilityId.Id[i].Value); - valid++; + if ((devinfo->Valid & ACPI_VALID_CID) == 0) { + AcpiOsFree(devinfo); + return_VALUE (0); } -out: - if (buf.Pointer != NULL) - AcpiOsFree(buf.Pointer); + if (devinfo->CompatibleIdList.Count < count) + count = devinfo->CompatibleIdList.Count; + ids = devinfo->CompatibleIdList.Ids; + for (i = 0, valid = 0; i < count; i++) + if (ids[i].Length >= ACPI_EISAID_STRING_SIZE && + strncmp(ids[i].String, "PNP", 3) == 0) { + *pnpid++ = PNP_EISAID(ids[i].String); + valid++; + } + AcpiOsFree(devinfo); + return_VALUE (valid); } @@ -1389,10 +1370,14 @@ static char * acpi_device_id_probe(device_t bus, device_t dev, char **ids) { ACPI_HANDLE h; + ACPI_OBJECT_TYPE t; int i; h = acpi_get_handle(dev); - if (ids == NULL || h == NULL || acpi_get_type(dev) != ACPI_TYPE_DEVICE) + if (ids == NULL || h == NULL) + return (NULL); + t = acpi_get_type(dev); + if (t != ACPI_TYPE_DEVICE && t != ACPI_TYPE_PROCESSOR) return (NULL); /* Try to match one of the array of IDs with a HID or CID. */ @@ -1538,7 +1523,7 @@ acpi_device_scan_children(device_t bus, device_t dev, int max_depth, ctx.arg = arg; ctx.parent = h; return (AcpiWalkNamespace(ACPI_TYPE_ANY, h, max_depth, - acpi_device_scan_cb, &ctx, NULL)); + acpi_device_scan_cb, NULL, &ctx, NULL)); } /* @@ -1664,7 +1649,7 @@ acpi_probe_children(device_t bus) */ ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "namespace scan\n")); AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 100, acpi_probe_child, - bus, NULL); + NULL, bus, NULL); /* Pre-allocate resources for our rman from any sysresource devices. */ acpi_sysres_alloc(bus); @@ -1821,7 +1806,7 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status) * placeholder object handler so we can store a device_t in an ACPI_HANDLE. */ void -acpi_fake_objhandler(ACPI_HANDLE h, UINT32 fn, void *data) +acpi_fake_objhandler(ACPI_HANDLE h, void *data) { } @@ -1910,30 +1895,18 @@ acpi_DeviceIsPresent(device_t dev) { ACPI_DEVICE_INFO *devinfo; ACPI_HANDLE h; - ACPI_BUFFER buf; - ACPI_STATUS error; - int ret; + BOOLEAN present; - ret = FALSE; - if ((h = acpi_get_handle(dev)) == NULL) + if ((h = acpi_get_handle(dev)) == NULL || + ACPI_FAILURE(AcpiGetObjectInfo(h, &devinfo))) return (FALSE); - buf.Pointer = NULL; - buf.Length = ACPI_ALLOCATE_BUFFER; - error = AcpiGetObjectInfo(h, &buf); - if (ACPI_FAILURE(error)) - return (FALSE); - devinfo = (ACPI_DEVICE_INFO *)buf.Pointer; /* If no _STA method, must be present */ - if ((devinfo->Valid & ACPI_VALID_STA) == 0) - ret = TRUE; + present = (devinfo->Valid & ACPI_VALID_STA) == 0 || + ACPI_DEVICE_PRESENT(devinfo->CurrentStatus) ? TRUE : FALSE; - /* Return true for 'present' and 'functioning' */ - if (ACPI_DEVICE_PRESENT(devinfo->CurrentStatus)) - ret = TRUE; - - AcpiOsFree(buf.Pointer); - return (ret); + AcpiOsFree(devinfo); + return (present); } /* @@ -1944,30 +1917,18 @@ acpi_BatteryIsPresent(device_t dev) { ACPI_DEVICE_INFO *devinfo; ACPI_HANDLE h; - ACPI_BUFFER buf; - ACPI_STATUS error; - int ret; + BOOLEAN present; - ret = FALSE; - if ((h = acpi_get_handle(dev)) == NULL) + if ((h = acpi_get_handle(dev)) == NULL || + ACPI_FAILURE(AcpiGetObjectInfo(h, &devinfo))) return (FALSE); - buf.Pointer = NULL; - buf.Length = ACPI_ALLOCATE_BUFFER; - error = AcpiGetObjectInfo(h, &buf); - if (ACPI_FAILURE(error)) - return (FALSE); - devinfo = (ACPI_DEVICE_INFO *)buf.Pointer; /* If no _STA method, must be present */ - if ((devinfo->Valid & ACPI_VALID_STA) == 0) - ret = TRUE; + present = (devinfo->Valid & ACPI_VALID_STA) == 0 || + ACPI_BATTERY_PRESENT(devinfo->CurrentStatus) ? TRUE : FALSE; - /* Return true for 'present', 'battery present', and 'functioning' */ - if (ACPI_BATTERY_PRESENT(devinfo->CurrentStatus)) - ret = TRUE; - - AcpiOsFree(buf.Pointer); - return (ret); + AcpiOsFree(devinfo); + return (present); } /* @@ -1977,33 +1938,26 @@ static BOOLEAN acpi_MatchHid(ACPI_HANDLE h, const char *hid) { ACPI_DEVICE_INFO *devinfo; - ACPI_BUFFER buf; - ACPI_STATUS error; - int ret, i; + BOOLEAN ret; + int i; + + if (hid == NULL || h == NULL || + ACPI_FAILURE(AcpiGetObjectInfo(h, &devinfo))) + return (FALSE); ret = FALSE; - if (hid == NULL || h == NULL) - return (ret); - buf.Pointer = NULL; - buf.Length = ACPI_ALLOCATE_BUFFER; - error = AcpiGetObjectInfo(h, &buf); - if (ACPI_FAILURE(error)) - return (ret); - devinfo = (ACPI_DEVICE_INFO *)buf.Pointer; - if ((devinfo->Valid & ACPI_VALID_HID) != 0 && - strcmp(hid, devinfo->HardwareId.Value) == 0) + strcmp(hid, devinfo->HardwareId.String) == 0) ret = TRUE; - else if ((devinfo->Valid & ACPI_VALID_CID) != 0) { - for (i = 0; i < devinfo->CompatibilityId.Count; i++) { - if (strcmp(hid, devinfo->CompatibilityId.Id[i].Value) == 0) { + else if ((devinfo->Valid & ACPI_VALID_CID) != 0) + for (i = 0; i < devinfo->CompatibleIdList.Count; i++) { + if (strcmp(hid, devinfo->CompatibleIdList.Ids[i].String) == 0) { ret = TRUE; break; } } - } - AcpiOsFree(buf.Pointer); + AcpiOsFree(devinfo); return (ret); } @@ -2825,7 +2779,7 @@ acpi_wake_prep_walk(int sstate) if (ACPI_SUCCESS(AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &sb_handle))) AcpiWalkNamespace(ACPI_TYPE_DEVICE, sb_handle, 100, - acpi_wake_prep, &sstate, NULL); + acpi_wake_prep, NULL, &sstate, NULL); return (0); } diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index 3c4fd71e84c..c16dcb17416 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -940,7 +940,7 @@ acpi_cpu_idle() * get the time very close to the CPU start/stop clock logic, this * is the only reliable time source. */ - AcpiRead(&start_time, &AcpiGbl_FADT.XPmTimerBlock); + AcpiHwRead(&start_time, &AcpiGbl_FADT.XPmTimerBlock); CPU_GET_REG(cx_next->p_lvlx, 1); /* @@ -949,8 +949,8 @@ acpi_cpu_idle() * the processor has stopped. Doing it again provides enough * margin that we are certain to have a correct value. */ - AcpiRead(&end_time, &AcpiGbl_FADT.XPmTimerBlock); - AcpiRead(&end_time, &AcpiGbl_FADT.XPmTimerBlock); + AcpiHwRead(&end_time, &AcpiGbl_FADT.XPmTimerBlock); + AcpiHwRead(&end_time, &AcpiGbl_FADT.XPmTimerBlock); /* Enable bus master arbitration and disable bus master wakeup. */ if (cx_next->type == ACPI_STATE_C3 && diff --git a/sys/dev/acpica/acpi_dock.c b/sys/dev/acpica/acpi_dock.c index b7d2e3e444a..2e77b934b96 100644 --- a/sys/dev/acpica/acpi_dock.c +++ b/sys/dev/acpica/acpi_dock.c @@ -224,7 +224,7 @@ acpi_dock_insert_child(ACPI_HANDLE handle, UINT32 level, void *context, ACPI_INIT_WALK_INFO Info; AcpiNsWalkNamespace(ACPI_TYPE_ANY, handle, - 100, TRUE, AcpiNsInitOneDevice, &Info, NULL); + 100, TRUE, AcpiNsInitOneDevice, NULL, &Info, NULL); #endif dev = acpi_get_device(handle); @@ -249,7 +249,7 @@ acpi_dock_insert_children(device_t dev) status = AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &sb_handle); if (ACPI_SUCCESS(status)) { AcpiWalkNamespace(ACPI_TYPE_DEVICE, sb_handle, - 100, acpi_dock_insert_child, dev, NULL); + 100, acpi_dock_insert_child, NULL, dev, NULL); } } @@ -319,7 +319,7 @@ acpi_dock_eject_children(device_t dev) status = AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &sb_handle); if (ACPI_SUCCESS(status)) { AcpiWalkNamespace(ACPI_TYPE_DEVICE, sb_handle, - 100, acpi_dock_eject_child, &dev, NULL); + 100, acpi_dock_eject_child, NULL, &dev, NULL); } } diff --git a/sys/dev/acpica/acpi_ec.c b/sys/dev/acpica/acpi_ec.c index 9348a2ad470..d4ef0191b88 100644 --- a/sys/dev/acpica/acpi_ec.c +++ b/sys/dev/acpica/acpi_ec.c @@ -223,7 +223,7 @@ static ACPI_STATUS EcSpaceSetup(ACPI_HANDLE Region, UINT32 Function, void *Context, void **return_Context); static ACPI_STATUS EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, - UINT32 width, ACPI_INTEGER *Value, + UINT32 width, UINT64 *Value, void *Context, void *RegionContext); static ACPI_STATUS EcWaitEvent(struct acpi_ec_softc *sc, EC_EVENT Event, u_int gen_count); @@ -238,9 +238,9 @@ static int acpi_ec_suspend(device_t dev); static int acpi_ec_resume(device_t dev); static int acpi_ec_shutdown(device_t dev); static int acpi_ec_read_method(device_t dev, u_int addr, - ACPI_INTEGER *val, int width); + UINT64 *val, int width); static int acpi_ec_write_method(device_t dev, u_int addr, - ACPI_INTEGER val, int width); + UINT64 val, int width); static device_method_t acpi_ec_methods[] = { /* Device interface */ @@ -581,7 +581,7 @@ acpi_ec_shutdown(device_t dev) /* Methods to allow other devices (e.g., smbat) to read/write EC space. */ static int -acpi_ec_read_method(device_t dev, u_int addr, ACPI_INTEGER *val, int width) +acpi_ec_read_method(device_t dev, u_int addr, UINT64 *val, int width) { struct acpi_ec_softc *sc; ACPI_STATUS status; @@ -594,7 +594,7 @@ acpi_ec_read_method(device_t dev, u_int addr, ACPI_INTEGER *val, int width) } static int -acpi_ec_write_method(device_t dev, u_int addr, ACPI_INTEGER val, int width) +acpi_ec_write_method(device_t dev, u_int addr, UINT64 val, int width) { struct acpi_ec_softc *sc; ACPI_STATUS status; @@ -724,7 +724,7 @@ EcSpaceSetup(ACPI_HANDLE Region, UINT32 Function, void *Context, static ACPI_STATUS EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 width, - ACPI_INTEGER *Value, void *Context, void *RegionContext) + UINT64 *Value, void *Context, void *RegionContext) { struct acpi_ec_softc *sc = (struct acpi_ec_softc *)Context; ACPI_STATUS Status; @@ -765,7 +765,7 @@ EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 width, case ACPI_READ: Status = EcRead(sc, EcAddr, &EcData); if (ACPI_SUCCESS(Status)) - *Value |= ((ACPI_INTEGER)EcData) << i; + *Value |= ((UINT64)EcData) << i; break; case ACPI_WRITE: EcData = (UINT8)((*Value) >> i); diff --git a/sys/dev/acpica/acpi_if.m b/sys/dev/acpica/acpi_if.m index 4d90109d750..36fad85bd77 100644 --- a/sys/dev/acpica/acpi_if.m +++ b/sys/dev/acpica/acpi_if.m @@ -177,13 +177,13 @@ STATICMETHOD int get_features { # # device_t dev: EC device # u_int addr: Address to read from in EC space -# ACPI_INTEGER *val: Location to store read value +# UINT64 *val: Location to store read value # int width: Size of area to read in bytes # METHOD int ec_read { device_t dev; u_int addr; - ACPI_INTEGER *val; + UINT64 *val; int width; }; @@ -192,13 +192,13 @@ METHOD int ec_read { # # device_t dev: EC device # u_int addr: Address to write to in EC space -# ACPI_INTEGER val: Value to write +# UINT64 val: Value to write # int width: Size of value to write in bytes # METHOD int ec_write { device_t dev; u_int addr; - ACPI_INTEGER val; + UINT64 val; int width; }; diff --git a/sys/dev/acpica/acpi_package.c b/sys/dev/acpica/acpi_package.c index 55eaf93608c..e38fea55521 100644 --- a/sys/dev/acpica/acpi_package.c +++ b/sys/dev/acpica/acpi_package.c @@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$"); */ int -acpi_PkgInt(ACPI_OBJECT *res, int idx, ACPI_INTEGER *dst) +acpi_PkgInt(ACPI_OBJECT *res, int idx, UINT64 *dst) { ACPI_OBJECT *obj; @@ -60,7 +60,7 @@ acpi_PkgInt(ACPI_OBJECT *res, int idx, ACPI_INTEGER *dst) int acpi_PkgInt32(ACPI_OBJECT *res, int idx, uint32_t *dst) { - ACPI_INTEGER tmp; + UINT64 tmp; int error; error = acpi_PkgInt(res, idx, &tmp); diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c index 7c1bd86120e..9cf064ee39d 100644 --- a/sys/dev/acpica/acpi_pci.c +++ b/sys/dev/acpica/acpi_pci.c @@ -314,7 +314,7 @@ acpi_pci_attach(device_t dev) */ pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo)); AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1, - acpi_pci_save_handle, dev, NULL); + acpi_pci_save_handle, NULL, dev, NULL); return (bus_generic_attach(dev)); } diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c index 471412587d0..b20fc741eb1 100644 --- a/sys/dev/acpica/acpi_pcib_acpi.c +++ b/sys/dev/acpica/acpi_pcib_acpi.c @@ -131,14 +131,18 @@ MODULE_DEPEND(acpi_pcib, acpi, 1, 1, 1); static int acpi_pcib_acpi_probe(device_t dev) { - static char *pcib_ids[] = { "PNP0A03", "PNP0A08", NULL }; + ACPI_DEVICE_INFO *devinfo; + ACPI_HANDLE h; + int root; - if (acpi_disabled("pcib") || - ACPI_ID_PROBE(device_get_parent(dev), dev, pcib_ids) == NULL) + if (acpi_disabled("pcib") || (h = acpi_get_handle(dev)) == NULL || + ACPI_FAILURE(AcpiGetObjectInfo(h, &devinfo))) + return (ENXIO); + root = (devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0; + AcpiOsFree(devinfo); + if (!root || pci_cfgregopen() == 0) return (ENXIO); - if (pci_cfgregopen() == 0) - return (ENXIO); device_set_desc(dev, "ACPI Host-PCI bridge"); return (0); } diff --git a/sys/dev/acpica/acpi_powerres.c b/sys/dev/acpica/acpi_powerres.c index 0988871c246..9c43c880ad9 100644 --- a/sys/dev/acpica/acpi_powerres.c +++ b/sys/dev/acpica/acpi_powerres.c @@ -88,8 +88,8 @@ struct acpi_powerresource { TAILQ_ENTRY(acpi_powerresource) ap_link; TAILQ_HEAD(,acpi_powerreference) ap_references; ACPI_HANDLE ap_resource; - ACPI_INTEGER ap_systemlevel; - ACPI_INTEGER ap_order; + UINT64 ap_systemlevel; + UINT64 ap_order; int ap_state; }; diff --git a/sys/dev/acpica/acpi_smbat.c b/sys/dev/acpica/acpi_smbat.c index 145e240dca1..02a461e1ed6 100644 --- a/sys/dev/acpica/acpi_smbat.c +++ b/sys/dev/acpica/acpi_smbat.c @@ -190,7 +190,7 @@ acpi_smbus_read_2(struct acpi_smbat_softc *sc, uint8_t addr, uint8_t cmd, uint16_t *ptr) { int error, to; - ACPI_INTEGER val; + UINT64 val; ACPI_SERIAL_ASSERT(smbat); @@ -257,7 +257,7 @@ static int acpi_smbus_read_multi_1(struct acpi_smbat_softc *sc, uint8_t addr, uint8_t cmd, uint8_t *ptr, uint16_t len) { - ACPI_INTEGER val; + UINT64 val; uint8_t to; int error; diff --git a/sys/dev/acpica/acpi_video.c b/sys/dev/acpica/acpi_video.c index 048a45c4d47..c253abceaf6 100644 --- a/sys/dev/acpica/acpi_video.c +++ b/sys/dev/acpica/acpi_video.c @@ -840,7 +840,7 @@ vid_enum_outputs(ACPI_HANDLE handle, argset.dod_pkg = res; argset.count = 0; status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, handle, 1, - vid_enum_outputs_subr, &argset, NULL); + vid_enum_outputs_subr, NULL, &argset, NULL); if (ACPI_FAILURE(status)) printf("failed walking down %s - %s\n", acpi_name(handle), AcpiFormatException(status)); diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index 9141656eb3b..5c827f2b534 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -254,7 +254,7 @@ __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) -void acpi_fake_objhandler(ACPI_HANDLE h, UINT32 fn, void *data); +void acpi_fake_objhandler(ACPI_HANDLE h, void *data); static __inline device_t acpi_get_device(ACPI_HANDLE handle) { @@ -447,7 +447,7 @@ int acpi_acad_get_acline(int *); #define ACPI_PKG_VALID(pkg, size) \ ((pkg) != NULL && (pkg)->Type == ACPI_TYPE_PACKAGE && \ (pkg)->Package.Count >= (size)) -int acpi_PkgInt(ACPI_OBJECT *res, int idx, ACPI_INTEGER *dst); +int acpi_PkgInt(ACPI_OBJECT *res, int idx, UINT64 *dst); int acpi_PkgInt32(ACPI_OBJECT *res, int idx, uint32_t *dst); int acpi_PkgStr(ACPI_OBJECT *res, int idx, void *dst, size_t size); int acpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *type, diff --git a/sys/dev/fdc/fdc_acpi.c b/sys/dev/fdc/fdc_acpi.c index 79fa66b93a1..97ec9cb3e5e 100644 --- a/sys/dev/fdc/fdc_acpi.c +++ b/sys/dev/fdc/fdc_acpi.c @@ -97,9 +97,7 @@ fdc_acpi_attach(device_t dev) struct fdc_data *sc; ACPI_BUFFER buf; device_t bus; - int error, fde_count, i; - ACPI_OBJECT *obj, *pkg; - uint32_t fde[ACPI_FDC_MAXDEVS]; + int error; /* Get our softc and use the same accessor as ISA. */ sc = device_get_softc(dev); @@ -128,63 +126,12 @@ fdc_acpi_attach(device_t dev) */ bus = device_get_parent(dev); if (ACPI_FAILURE(ACPI_EVALUATE_OBJECT(bus, dev, "_FDE", NULL, &buf))) { - error = ENXIO; - goto out_hintsprobe; - } - - /* Parse the output of _FDE in various ways. */ - obj = pkg = (ACPI_OBJECT *)buf.Pointer; - switch (obj->Type) { - case ACPI_TYPE_BUFFER: - /* - * The spec says _FDE should be a buffer of five 32-bit - * integers. In violation of the spec, some systems use - * five bytes instead. - */ - switch (obj->Buffer.Length) { - case ACPI_FDC_FDE_LEN: - bcopy(obj->Buffer.Pointer, fde, ACPI_FDC_FDE_LEN); - break; - case ACPI_FDC_MAXDEVS: - for (i = 0; i < ACPI_FDC_MAXDEVS; i++) - fde[i] = ((uint8_t *)obj->Buffer.Pointer)[i]; - break; - default: - device_printf(dev, "_FDE wrong length: %d\n", - obj->Buffer.Length); - error = ENXIO; - goto out_hintsprobe; - } - break; - case ACPI_TYPE_PACKAGE: - /* - * In violation of the spec, systems including the ASUS - * K8V return a package of five integers instead of a - * buffer of five 32-bit integers. - */ - fde_count = min(ACPI_FDC_MAXDEVS, pkg->Package.Count); - for (i = 0; i < fde_count; i++) { - obj = &pkg->Package.Elements[i]; - if (obj->Type == ACPI_TYPE_INTEGER) - fde[i] = (uint32_t)obj->Integer.Value; - } - break; - default: - device_printf(dev, "invalid _FDE type %d\n", obj->Type); - error = ENXIO; - goto out_hintsprobe; + error = fdc_hints_probe(dev); + goto out; } /* Add fd child devices as specified. */ - error = fdc_acpi_probe_children(bus, dev, fde); - -out_hintsprobe: - /* - * If there was a problem with the _FDE drive enumeration, fall - * back to the hints-based probe. - */ - if (error) - error = fdc_hints_probe(dev); + error = fdc_acpi_probe_children(bus, dev, buf.Pointer); out: if (buf.Pointer) diff --git a/sys/modules/acpi/acpi/Makefile b/sys/modules/acpi/acpi/Makefile index b1c4fbceeb7..992c59c09a6 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 @@ -37,16 +41,16 @@ SRCS+= exprep.c exregion.c exresnte.c exresolv.c exresop.c exstore.c SRCS+= exstoren.c exstorob.c exsystem.c exutils.c SRCS+= hwacpi.c hwgpe.c hwregs.c hwsleep.c hwtimer.c hwvalid.c hwxface.c SRCS+= nsaccess.c nsalloc.c nsdump.c nseval.c nsinit.c nsload.c nsnames.c -SRCS+= nsobject.c nsparse.c nspredef.c nssearch.c nsutils.c nswalk.c -SRCS+= nsxfeval.c nsxfname.c nsxfobj.c +SRCS+= nsobject.c nsparse.c nspredef.c nsrepair.c nsrepair2.c nssearch.c +SRCS+= nsutils.c nswalk.c nsxfeval.c nsxfname.c nsxfobj.c SRCS+= psargs.c psloop.c psopcode.c psparse.c psscope.c pstree.c psutils.c SRCS+= pswalk.c psxface.c SRCS+= rsaddr.c rscalc.c rscreate.c rsdump.c rsinfo.c rsio.c rsirq.c rslist.c SRCS+= rsmemory.c rsmisc.c rsutils.c rsxface.c SRCS+= tbfadt.c tbfind.c tbinstal.c tbutils.c tbxface.c tbxfroot.c SRCS+= utalloc.c utcache.c utcopy.c utdebug.c utdelete.c uteval.c utglobal.c -SRCS+= utinit.c utlock.c utmath.c utmisc.c utmutex.c utobject.c utresrc.c -SRCS+= utstate.c utxface.c +SRCS+= utids.c utinit.c utlock.c utmath.c utmisc.c utmutex.c utobject.c +SRCS+= utresrc.c utstate.c utxface.c # OSPM layer and core hardware drivers SRCS+= acpi.c acpi_button.c acpi_isab.c acpi_package.c acpi_pci.c acpi_pcib.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 \ diff --git a/usr.sbin/acpi/acpidb/Makefile b/usr.sbin/acpi/acpidb/Makefile index 16948678f17..5981f38d3db 100644 --- a/usr.sbin/acpi/acpidb/Makefile +++ b/usr.sbin/acpi/acpidb/Makefile @@ -38,8 +38,8 @@ SRCS+= psargs.c psloop.c psopcode.c psparse.c psscope.c \ # namespace SRCS+= nsaccess.c nsalloc.c nsdump.c nseval.c nsinit.c \ nsload.c nsnames.c nsobject.c nsparse.c nspredef.c \ - nssearch.c nsutils.c nswalk.c nsxfeval.c nsxfname.c \ - nsxfobj.c + nsrepair.c nsrepair2.c nssearch.c nsutils.c nswalk.c \ + nsxfeval.c nsxfname.c nsxfobj.c # resources SRCS+= rsaddr.c rscalc.c rscreate.c rsdump.c rsinfo.c \ @@ -52,9 +52,9 @@ SRCS+= tbfadt.c tbfind.c tbinstal.c tbutils.c tbxface.c \ # utilities SRCS+= utalloc.c utcache.c utcopy.c utdebug.c utdelete.c \ - uteval.c utglobal.c utinit.c utlock.c utmath.c utmisc.c \ - utmutex.c utobject.c utresrc.c utstate.c uttrack.c \ - utxface.c + uteval.c utglobal.c utids.c utinit.c utlock.c utmath.c \ + utmisc.c utmutex.c utobject.c utresrc.c utstate.c \ + uttrack.c utxface.c MAN= acpidb.8 WARNS?= 2 diff --git a/usr.sbin/acpi/acpidb/acpidb.c b/usr.sbin/acpi/acpidb/acpidb.c index 53d9db1145f..325dfae12a2 100644 --- a/usr.sbin/acpi/acpidb/acpidb.c +++ b/usr.sbin/acpi/acpidb/acpidb.c @@ -81,7 +81,7 @@ static int aml_simulate_regcontent_read(int regtype, static int aml_simulate_regcontent_write(int regtype, ACPI_PHYSICAL_ADDRESS addr, UINT8 *valuep); -static ACPI_INTEGER aml_simulate_prompt(char *msg, ACPI_INTEGER def_val); +static UINT64 aml_simulate_prompt(char *msg, UINT64 def_val); static void aml_simulation_regload(const char *dumpfile); static void aml_simulation_regdump(const char *dumpfile); @@ -161,11 +161,11 @@ aml_simulate_regcontent_write(int regtype, ACPI_PHYSICAL_ADDRESS addr, UINT8 *va return (aml_simulate_regcontent_add(regtype, addr, *valuep)); } -static ACPI_INTEGER -aml_simulate_prompt(char *msg, ACPI_INTEGER def_val) +static UINT64 +aml_simulate_prompt(char *msg, UINT64 def_val) { char buf[16], *ep; - ACPI_INTEGER val; + UINT64 val; val = def_val; printf("DEBUG"); @@ -271,12 +271,12 @@ aml_vm_space_handler( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, - ACPI_INTEGER *Value, + UINT64 *Value, int Prompt) { int state; UINT8 val; - ACPI_INTEGER value, i; + UINT64 value, i; char msg[256]; static const char *space_names[] = { "SYSTEM_MEMORY", "SYSTEM_IO", "PCI_CONFIG", @@ -336,7 +336,7 @@ aml_vm_space_handler_##name ( \ UINT32 Function, \ ACPI_PHYSICAL_ADDRESS Address, \ UINT32 BitWidth, \ - ACPI_INTEGER *Value) \ + UINT64 *Value) \ { \ return (aml_vm_space_handler(id, Function, Address, \ BitWidth, Value, aml_debug_prompt)); \ diff --git a/usr.sbin/acpi/iasl/Makefile b/usr.sbin/acpi/iasl/Makefile index 551bfc6311f..ff6ebd7fbee 100644 --- a/usr.sbin/acpi/iasl/Makefile +++ b/usr.sbin/acpi/iasl/Makefile @@ -5,7 +5,8 @@ SRCS= adfile.c adisasm.c adwalk.c SRCS+= osunixxf.c # common -SRCS+= dmrestag.c dmtable.c dmtbdump.c dmtbinfo.c getopt.c +SRCS+= dmextern.c dmrestag.c dmtable.c dmtbdump.c dmtbinfo.c \ + getopt.c # compiler SRCS+= aslanalyze.c aslcodegen.c aslcompile.c aslcompiler.y.h \ From bb07fbe3c1a0af42358a3551f900f5c04af79c52 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 6 Feb 2010 12:17:20 +0000 Subject: [PATCH 1384/2592] MFC r203160: add static qualifier to definition of a static function --- sys/amd64/amd64/msi.c | 2 +- sys/i386/i386/msi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/amd64/amd64/msi.c b/sys/amd64/amd64/msi.c index 91a8cbbd004..6745ce2f599 100644 --- a/sys/amd64/amd64/msi.c +++ b/sys/amd64/amd64/msi.c @@ -288,7 +288,7 @@ msi_init(void) mtx_init(&msi_lock, "msi", NULL, MTX_DEF); } -void +static void msi_create_source(void) { struct msi_intsrc *msi; diff --git a/sys/i386/i386/msi.c b/sys/i386/i386/msi.c index 91a8cbbd004..6745ce2f599 100644 --- a/sys/i386/i386/msi.c +++ b/sys/i386/i386/msi.c @@ -288,7 +288,7 @@ msi_init(void) mtx_init(&msi_lock, "msi", NULL, MTX_DEF); } -void +static void msi_create_source(void) { struct msi_intsrc *msi; From 1cddf840fbfe55a492e435989dc12d47abcd9275 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sat, 6 Feb 2010 15:32:42 +0000 Subject: [PATCH 1385/2592] MFC r203200; Allow use of -6 option to "server" and "peer" in ntp.conf. --- etc/rc.d/ntpdate | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/etc/rc.d/ntpdate b/etc/rc.d/ntpdate index c76f7a0e7f5..3f93e271807 100755 --- a/etc/rc.d/ntpdate +++ b/etc/rc.d/ntpdate @@ -19,7 +19,9 @@ ntpdate_start() if [ -z "$ntpdate_hosts" -a -f ${ntpdate_config} ]; then ntpdate_hosts=`awk ' /^server[ \t]*127.127/ {next} - /^(server|peer)/ {print $2} + /^(server|peer)/ { + if ($2 ~/^-/) {print $3} + else {print $2}} ' < ${ntpdate_config}` fi if [ -n "$ntpdate_hosts" -o -n "$rc_flags" ]; then From 901c651d7ba3a5b19f40f098371ae97ea8e2c0fa Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sat, 6 Feb 2010 17:33:39 +0000 Subject: [PATCH 1386/2592] MFC: r203185 Implement handling of the third argument of cpu_switch(). PR: 143215 --- sys/sparc64/sparc64/genassym.c | 1 + sys/sparc64/sparc64/swtch.S | 89 +++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/sys/sparc64/sparc64/genassym.c b/sys/sparc64/sparc64/genassym.c index 8073b692e83..9efaa74883c 100644 --- a/sys/sparc64/sparc64/genassym.c +++ b/sys/sparc64/sparc64/genassym.c @@ -239,6 +239,7 @@ ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); ASSYM(TD_FRAME, offsetof(struct thread, td_frame)); ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack)); +ASSYM(TD_LOCK, offsetof(struct thread, td_lock)); ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); ASSYM(TD_PROC, offsetof(struct thread, td_proc)); ASSYM(TD_MD, offsetof(struct thread, td_md)); diff --git a/sys/sparc64/sparc64/swtch.S b/sys/sparc64/sparc64/swtch.S index d9e86d218dd..af0531627aa 100644 --- a/sys/sparc64/sparc64/swtch.S +++ b/sys/sparc64/sparc64/swtch.S @@ -46,15 +46,14 @@ ENTRY(cpu_throw) save %sp, -CCFSZ, %sp flushw ba %xcc, .Lsw1 - mov %i1, %i0 + mov %g0, %i2 END(cpu_throw) /* - * void cpu_switch(struct thread *old, struct thread *new) + * void cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx) */ ENTRY(cpu_switch) save %sp, -CCFSZ, %sp - mov %i1, %i0 /* * If the current thread was using floating point in the kernel, save @@ -63,7 +62,7 @@ ENTRY(cpu_switch) */ rd %fprs, %l2 andcc %l2, FPRS_FEF, %g0 - bz,a,pt %xcc, 1f + bz,a,pt %xcc, 1f nop call savefpctx add PCB_REG, PCB_KFP, %o0 @@ -104,24 +103,24 @@ ENTRY(cpu_switch) .Lsw1: #if KTR_COMPILE & KTR_PROC CATR(KTR_PROC, "cpu_switch: new td=%p pc=%#lx fp=%#lx" - , %g1, %g2, %g3, 7, 8, 9) - stx %i0, [%g1 + KTR_PARM1] - ldx [%i0 + TD_PCB], %g2 + , %g1, %g2, %g3, 8, 9, 10) + stx %i1, [%g1 + KTR_PARM1] + ldx [%i1 + TD_PCB], %g2 ldx [%g2 + PCB_PC], %g3 stx %g3, [%g1 + KTR_PARM2] ldx [%g2 + PCB_SP], %g3 stx %g3, [%g1 + KTR_PARM3] -9: +10: #endif - ldx [%i0 + TD_PCB], %i1 + ldx [%i1 + TD_PCB], %l0 - stx %i0, [PCPU(CURTHREAD)] - stx %i1, [PCPU(CURPCB)] + stx %i1, [PCPU(CURTHREAD)] + stx %l0, [PCPU(CURPCB)] wrpr %g0, PSTATE_NORMAL, %pstate - mov %i1, PCB_REG + mov %l0, PCB_REG wrpr %g0, PSTATE_ALT, %pstate - mov %i1, PCB_REG + mov %l0, PCB_REG wrpr %g0, PSTATE_KERNEL, %pstate ldx [PCB_REG + PCB_SP], %fp @@ -132,24 +131,24 @@ ENTRY(cpu_switch) * Point to the pmaps of the new process, and of the last non-kernel * process to run. */ - ldx [%i0 + TD_PROC], %i2 + ldx [%i1 + TD_PROC], %l1 ldx [PCPU(PMAP)], %l2 - ldx [%i2 + P_VMSPACE], %i5 - add %i5, VM_PMAP, %i2 + ldx [%l1 + P_VMSPACE], %i5 + add %i5, VM_PMAP, %l1 #if KTR_COMPILE & KTR_PROC CATR(KTR_PROC, "cpu_switch: new pmap=%p old pmap=%p" - , %g1, %g2, %g3, 7, 8, 9) - stx %i2, [%g1 + KTR_PARM1] + , %g1, %g2, %g3, 8, 9, 10) + stx %l1, [%g1 + KTR_PARM1] stx %l2, [%g1 + KTR_PARM2] -9: +10: #endif /* * If they are the same we are done. */ - cmp %l2, %i2 - be,a,pn %xcc, 5f + cmp %l2, %l1 + be,a,pn %xcc, 7f nop /* @@ -158,21 +157,20 @@ ENTRY(cpu_switch) */ SET(vmspace0, %i4, %i3) cmp %i5, %i3 - be,a,pn %xcc, 5f + be,a,pn %xcc, 7f nop /* * If there was no non-kernel pmap, don't try to deactivate it. */ - brz,a,pn %l2, 3f - nop + brz,pn %l2, 3f + lduw [PCPU(CPUMASK)], %l4 /* * Mark the pmap of the last non-kernel vmspace to run as no longer * active on this CPU. */ lduw [%l2 + PM_ACTIVE], %l3 - lduw [PCPU(CPUMASK)], %l4 andn %l3, %l4, %l3 stw %l3, [%l2 + PM_ACTIVE] @@ -185,25 +183,28 @@ ENTRY(cpu_switch) mov -1, %l5 stw %l5, [%l3 + %l4] +3: cmp %i2, %g0 + be,pn %xcc, 4f + lduw [PCPU(TLB_CTX_MAX)], %i4 + stx %i2, [%i0 + TD_LOCK] + /* * Find a new TLB context. If we've run out we have to flush all * user mappings from the TLB and reset the context numbers. */ -3: lduw [PCPU(TLB_CTX)], %i3 - lduw [PCPU(TLB_CTX_MAX)], %i4 +4: lduw [PCPU(TLB_CTX)], %i3 cmp %i3, %i4 - bne,a,pt %xcc, 4f + bne,a,pt %xcc, 5f nop SET(tlb_flush_user, %i5, %i4) ldx [%i4], %i5 call %i5 - nop - lduw [PCPU(TLB_CTX_MIN)], %i3 + lduw [PCPU(TLB_CTX_MIN)], %i3 /* * Advance next free context. */ -4: add %i3, 1, %i4 +5: add %i3, 1, %i4 stw %i4, [PCPU(TLB_CTX)] /* @@ -211,36 +212,36 @@ ENTRY(cpu_switch) */ lduw [PCPU(CPUID)], %i4 sllx %i4, INT_SHIFT, %i4 - add %i2, PM_CONTEXT, %i5 + add %l1, PM_CONTEXT, %i5 stw %i3, [%i4 + %i5] /* * Mark the pmap as active on this CPU. */ - lduw [%i2 + PM_ACTIVE], %i4 + lduw [%l1 + PM_ACTIVE], %i4 lduw [PCPU(CPUMASK)], %i5 or %i4, %i5, %i4 - stw %i4, [%i2 + PM_ACTIVE] + stw %i4, [%l1 + PM_ACTIVE] /* * Make note of the change in pmap. */ - stx %i2, [PCPU(PMAP)] + stx %l1, [PCPU(PMAP)] /* * Fiddle the hardware bits. Set the TSB registers and install the * new context number in the CPU. */ - ldx [%i2 + PM_TSB], %i4 + ldx [%l1 + PM_TSB], %i4 mov AA_DMMU_TSB, %i5 stxa %i4, [%i5] ASI_DMMU mov AA_IMMU_TSB, %i5 stxa %i4, [%i5] ASI_IMMU setx TLB_PCXR_PGSZ_MASK, %i5, %i4 mov AA_DMMU_PCXR, %i5 - ldxa [%i5] ASI_DMMU, %i2 - and %i2, %i4, %i2 - or %i3, %i2, %i3 + ldxa [%i5] ASI_DMMU, %l1 + and %l1, %i4, %l1 + or %i3, %l1, %i3 sethi %hi(KERNBASE), %i4 stxa %i3, [%i5] ASI_DMMU flush %i4 @@ -248,7 +249,15 @@ ENTRY(cpu_switch) /* * Done, return and load the new process's window from the stack. */ -5: ret + +6: ret + restore + +7: cmp %i2, %g0 + be,a,pn %xcc, 6b + nop + stx %i2, [%i0 + TD_LOCK] + ret restore END(cpu_switch) From 9ed7f3a23afcb755179d5626289a4c8d80e7aac4 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sun, 7 Feb 2010 04:27:18 +0000 Subject: [PATCH 1387/2592] MFC r202916: Make strsignal(3) thread-safe. --- lib/libc/string/strsignal.c | 52 ++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/lib/libc/string/strsignal.c b/lib/libc/string/strsignal.c index e4267a32f01..c51f34da9eb 100644 --- a/lib/libc/string/strsignal.c +++ b/lib/libc/string/strsignal.c @@ -33,22 +33,64 @@ static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; #include __FBSDID("$FreeBSD$"); +#include "namespace.h" #if defined(NLS) #include #endif - #include #include +#include #include #include +#include "reentrant.h" +#include "un-namespace.h" #define UPREFIX "Unknown signal" +static char sig_ebuf[NL_TEXTMAX]; +static char sig_ebuf_err[NL_TEXTMAX]; +static once_t sig_init_once = ONCE_INITIALIZER; +static thread_key_t sig_key; +static int sig_keycreated = 0; + +static void +sig_keycreate(void) +{ + sig_keycreated = (thr_keycreate(&sig_key, free) == 0); +} + +static char * +sig_tlsalloc(void) +{ + char *ebuf = NULL; + + if (thr_main() != 0) + ebuf = sig_ebuf; + else { + if (thr_once(&sig_init_once, sig_keycreate) != 0 || + !sig_keycreated) + goto thr_err; + if ((ebuf = thr_getspecific(sig_key)) == NULL) { + if ((ebuf = malloc(sizeof(sig_ebuf))) == NULL) + goto thr_err; + if (thr_setspecific(sig_key, ebuf) != 0) { + free(ebuf); + ebuf = NULL; + goto thr_err; + } + } + } +thr_err: + if (ebuf == NULL) + ebuf = sig_ebuf_err; + return (ebuf); +} + /* XXX: negative 'num' ? (REGR) */ char * strsignal(int num) { - static char ebuf[NL_TEXTMAX]; + char *ebuf; char tmp[20]; size_t n; int signum; @@ -60,6 +102,8 @@ strsignal(int num) catd = catopen("libc", NL_CAT_LOCALE); #endif + ebuf = sig_tlsalloc(); + if (num > 0 && num < sys_nsig) { n = strlcpy(ebuf, #if defined(NLS) @@ -67,7 +111,7 @@ strsignal(int num) #else sys_siglist[num], #endif - sizeof(ebuf)); + sizeof(sig_ebuf)); } else { n = strlcpy(ebuf, #if defined(NLS) @@ -75,7 +119,7 @@ strsignal(int num) #else UPREFIX, #endif - sizeof(ebuf)); + sizeof(sig_ebuf)); } signum = num; From 2227955399c3bb65f89eb6f4095843fd6abf8187 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Sun, 7 Feb 2010 06:22:28 +0000 Subject: [PATCH 1388/2592] MFC: r203486: Shortening a passphrase caused wrong authentication key to be used. --- sbin/ifconfig/ifcarp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sbin/ifconfig/ifcarp.c b/sbin/ifconfig/ifcarp.c index 36f1bb6a47b..2306717e63b 100644 --- a/sbin/ifconfig/ifcarp.c +++ b/sbin/ifconfig/ifcarp.c @@ -96,6 +96,7 @@ setcarp_passwd(const char *val, int d, int s, const struct afswtch *afp) if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1) err(1, "SIOCGVH"); + memset(carpr.carpr_key, 0, sizeof(carpr.carpr_key)); /* XXX Should hash the password into the key here, perhaps? */ strlcpy(carpr.carpr_key, val, CARP_KEY_LEN); From 2ae7ec29fdc503579c8cc2b62714e3057c800ce2 Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Sun, 7 Feb 2010 09:00:22 +0000 Subject: [PATCH 1389/2592] MFC of 197952 and 198075 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. and 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. --- sys/net/if_bridge.c | 41 +++++++------- sys/net/if_enc.c | 8 +-- 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 +- 16 files changed, 203 insertions(+), 134 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_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 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 0ae889a6f27..df0e30fe571 100644 --- a/sys/net/pfil.c +++ b/sys/net/pfil.c @@ -58,8 +58,9 @@ 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. @@ -99,7 +100,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(); @@ -110,7 +111,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); } @@ -145,7 +146,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 f53f787ed87..31565d1ad85 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 d6915d7bf95..8ffa01ab8a2 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 4c08bc5d17b..1ccbf2bcb78 100644 --- a/sys/netinet/ipfw/ip_fw2.c +++ b/sys/netinet/ipfw/ip_fw2.c @@ -2581,6 +2581,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) { /* @@ -4760,29 +4764,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 a re cuaranteed 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). @@ -4866,21 +4862,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. */ @@ -4890,9 +4897,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 */); @@ -4926,21 +4942,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: @@ -4989,4 +4994,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 aba1f5f4a11..3573472bf25 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; /* @@ -542,8 +542,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; @@ -605,8 +605,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 4958d748a89..5bc38bdc9aa 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 e9560b4089780771f0d916745a7af91e1ae7fabb Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 7 Feb 2010 10:44:44 +0000 Subject: [PATCH 1390/2592] MFC r202528: Add vunref(9). --- sys/kern/vfs_subr.c | 123 +++++++++++++++++++------------------------- sys/sys/vnode.h | 1 + 2 files changed, 54 insertions(+), 70 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index d681fca6f23..a9c1a247ef2 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2149,37 +2149,44 @@ vrefcnt(struct vnode *vp) return (usecnt); } +#define VPUTX_VRELE 1 +#define VPUTX_VPUT 2 +#define VPUTX_VUNREF 3 -/* - * Vnode put/release. - * If count drops to zero, call inactive routine and return to freelist. - */ -void -vrele(struct vnode *vp) +static void +vputx(struct vnode *vp, int func) { - struct thread *td = curthread; /* XXX */ + int error; - KASSERT(vp != NULL, ("vrele: null vp")); + KASSERT(vp != NULL, ("vputx: null vp")); + if (func == VPUTX_VUNREF) + ASSERT_VOP_ELOCKED(vp, "vunref"); + else if (func == VPUTX_VPUT) + ASSERT_VOP_LOCKED(vp, "vput"); + else + KASSERT(func == VPUTX_VRELE, ("vputx: wrong func")); VFS_ASSERT_GIANT(vp->v_mount); - + CTR2(KTR_VFS, "%s: vp %p", __func__, vp); VI_LOCK(vp); /* Skip this v_writecount check if we're going to panic below. */ VNASSERT(vp->v_writecount < vp->v_usecount || vp->v_usecount < 1, vp, - ("vrele: missed vn_close")); - CTR2(KTR_VFS, "%s: vp %p", __func__, vp); + ("vputx: missed vn_close")); + error = 0; if (vp->v_usecount > 1 || ((vp->v_iflag & VI_DOINGINACT) && vp->v_usecount == 1)) { + if (func == VPUTX_VPUT) + VOP_UNLOCK(vp, 0); v_decr_usecount(vp); return; } + if (vp->v_usecount != 1) { #ifdef DIAGNOSTIC - vprint("vrele: negative ref count", vp); + vprint("vputx: negative ref count", vp); #endif - VI_UNLOCK(vp); - panic("vrele: negative ref cnt"); + panic("vputx: negative ref cnt"); } CTR2(KTR_VFS, "%s: return vnode %p to the freelist", __func__, vp); /* @@ -2193,21 +2200,35 @@ vrele(struct vnode *vp) * as VI_DOINGINACT to avoid recursion. */ vp->v_iflag |= VI_OWEINACT; - if (vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK) == 0) { + if (func == VPUTX_VRELE) { + error = vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK); VI_LOCK(vp); - if (vp->v_usecount > 0) - vp->v_iflag &= ~VI_OWEINACT; + } else if (func == VPUTX_VPUT && VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { + error = VOP_LOCK(vp, LK_UPGRADE | LK_INTERLOCK | LK_NOWAIT); + VI_LOCK(vp); + } + if (vp->v_usecount > 0) + vp->v_iflag &= ~VI_OWEINACT; + if (error == 0) { if (vp->v_iflag & VI_OWEINACT) - vinactive(vp, td); - VOP_UNLOCK(vp, 0); - } else { - VI_LOCK(vp); - if (vp->v_usecount > 0) - vp->v_iflag &= ~VI_OWEINACT; + vinactive(vp, curthread); + if (func != VPUTX_VUNREF) + VOP_UNLOCK(vp, 0); } vdropl(vp); } +/* + * Vnode put/release. + * If count drops to zero, call inactive routine and return to freelist. + */ +void +vrele(struct vnode *vp) +{ + + vputx(vp, VPUTX_VRELE); +} + /* * Release an already locked vnode. This give the same effects as * unlock+vrele(), but takes less time and avoids releasing and @@ -2216,56 +2237,18 @@ vrele(struct vnode *vp) void vput(struct vnode *vp) { - struct thread *td = curthread; /* XXX */ - int error; - KASSERT(vp != NULL, ("vput: null vp")); - ASSERT_VOP_LOCKED(vp, "vput"); - VFS_ASSERT_GIANT(vp->v_mount); - CTR2(KTR_VFS, "%s: vp %p", __func__, vp); - VI_LOCK(vp); - /* Skip this v_writecount check if we're going to panic below. */ - VNASSERT(vp->v_writecount < vp->v_usecount || vp->v_usecount < 1, vp, - ("vput: missed vn_close")); - error = 0; + vputx(vp, VPUTX_VPUT); +} - if (vp->v_usecount > 1 || ((vp->v_iflag & VI_DOINGINACT) && - vp->v_usecount == 1)) { - VOP_UNLOCK(vp, 0); - v_decr_usecount(vp); - return; - } +/* + * Release an exclusively locked vnode. Do not unlock the vnode lock. + */ +void +vunref(struct vnode *vp) +{ - if (vp->v_usecount != 1) { -#ifdef DIAGNOSTIC - vprint("vput: negative ref count", vp); -#endif - panic("vput: negative ref cnt"); - } - CTR2(KTR_VFS, "%s: return to freelist the vnode %p", __func__, vp); - /* - * We want to hold the vnode until the inactive finishes to - * prevent vgone() races. We drop the use count here and the - * hold count below when we're done. - */ - v_decr_useonly(vp); - vp->v_iflag |= VI_OWEINACT; - if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { - error = VOP_LOCK(vp, LK_UPGRADE|LK_INTERLOCK|LK_NOWAIT); - VI_LOCK(vp); - if (error) { - if (vp->v_usecount > 0) - vp->v_iflag &= ~VI_OWEINACT; - goto done; - } - } - if (vp->v_usecount > 0) - vp->v_iflag &= ~VI_OWEINACT; - if (vp->v_iflag & VI_OWEINACT) - vinactive(vp, td); - VOP_UNLOCK(vp, 0); -done: - vdropl(vp); + vputx(vp, VPUTX_VUNREF); } /* diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 2c043411706..96482bce5e9 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -629,6 +629,7 @@ void vholdl(struct vnode *); int vinvalbuf(struct vnode *vp, int save, int slpflag, int slptimeo); int vtruncbuf(struct vnode *vp, struct ucred *cred, struct thread *td, off_t length, int blksize); +void vunref(struct vnode *); void vn_printf(struct vnode *vp, const char *fmt, ...) __printflike(2,3); #define vprint(label, vp) vn_printf((vp), "%s\n", (label)) int vrecycle(struct vnode *vp, struct thread *td); From 02d65815cb3b4da5b911e77d012f9b85b39dc20b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 7 Feb 2010 10:51:17 +0000 Subject: [PATCH 1391/2592] MFC r202529: vunref() the vnode in vm object deallocation code for OBJT_VNODE appropriate number of times to prevent possible vnode reference leak. --- sys/vm/vm_pageout.c | 2 ++ sys/vm/vnode_pager.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 19edce173ff..723b14d2175 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -951,6 +951,8 @@ rescan0: vnodes_skipped++; goto unlock_and_continue; } + KASSERT(mp != NULL, + ("vp %p with NULL v_mount", vp)); vm_page_unlock_queues(); vm_object_reference_locked(object); VM_OBJECT_UNLOCK(object); diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index faa6f37f831..179afbf9a1e 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -250,13 +250,16 @@ static void vnode_pager_dealloc(object) vm_object_t object; { - struct vnode *vp = object->handle; + struct vnode *vp; + int refs; + vp = object->handle; if (vp == NULL) panic("vnode_pager_dealloc: pager already dealloced"); VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); vm_object_pip_wait(object, "vnpdea"); + refs = object->ref_count; object->handle = NULL; object->type = OBJT_DEAD; @@ -267,6 +270,8 @@ vnode_pager_dealloc(object) ASSERT_VOP_ELOCKED(vp, "vnode_pager_dealloc"); vp->v_object = NULL; vp->v_vflag &= ~VV_TEXT; + while (refs-- > 0) + vunref(vp); } static boolean_t From c329abd0d3c60c5d6fdaa34ad6d798cd5f5fdbe7 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 7 Feb 2010 11:37:38 +0000 Subject: [PATCH 1392/2592] MFC r202882: For i386, amd64 and ia32 on amd64 MD syscall(), reread syscall number and arguments after ptracestop(), if debugger modified anything in the process environment. --- sys/amd64/amd64/trap.c | 178 ++++++++++++++++++++------------- sys/amd64/ia32/ia32_syscall.c | 155 ++++++++++++++++++----------- sys/i386/i386/trap.c | 179 ++++++++++++++++++++-------------- sys/kern/sys_process.c | 5 + sys/sys/proc.h | 1 + 5 files changed, 317 insertions(+), 201 deletions(-) diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 5583c824143..41ca7581071 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -884,6 +884,73 @@ dblfault_handler(struct trapframe *frame) panic("double fault"); } +struct syscall_args { + u_int code; + struct sysent *callp; + register_t args[8]; + register_t *argp; + int narg; +}; + +static int +fetch_syscall_args(struct thread *td, struct syscall_args *sa) +{ + struct proc *p; + struct trapframe *frame; + caddr_t params; + int reg, regcnt, error; + + p = td->td_proc; + frame = td->td_frame; + reg = 0; + regcnt = 6; + + params = (caddr_t)frame->tf_rsp + sizeof(register_t); + sa->code = frame->tf_rax; + + if (p->p_sysent->sv_prepsyscall) { + (*p->p_sysent->sv_prepsyscall)(frame, (int *)sa->args, + &sa->code, ¶ms); + } else { + if (sa->code == SYS_syscall || sa->code == SYS___syscall) { + sa->code = frame->tf_rdi; + reg++; + regcnt--; + } + } + if (p->p_sysent->sv_mask) + sa->code &= p->p_sysent->sv_mask; + + if (sa->code >= p->p_sysent->sv_size) + sa->callp = &p->p_sysent->sv_table[0]; + else + sa->callp = &p->p_sysent->sv_table[sa->code]; + + sa->narg = sa->callp->sy_narg; + KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]), + ("Too many syscall arguments!")); + error = 0; + sa->argp = &frame->tf_rdi; + sa->argp += reg; + bcopy(sa->argp, sa->args, sizeof(sa->args[0]) * regcnt); + if (sa->narg > regcnt) { + KASSERT(params != NULL, ("copyin args with no params!")); + error = copyin(params, &sa->args[regcnt], + (sa->narg - regcnt) * sizeof(sa->args[0])); + } + sa->argp = &sa->args[0]; + + /* + * This may result in two records if debugger modified + * registers or memory during sleep at stop/ptrace point. + */ +#ifdef KTRACE + if (KTRPOINT(td, KTR_SYSCALL)) + ktrsyscall(sa->code, sa->narg, sa->argp); +#endif + return (error); +} + /* * syscall - system call request C handler * @@ -892,20 +959,17 @@ dblfault_handler(struct trapframe *frame) void syscall(struct trapframe *frame) { - caddr_t params; - struct sysent *callp; - struct thread *td = curthread; - struct proc *p = td->td_proc; + struct thread *td; + struct proc *p; + struct syscall_args sa; register_t orig_tf_rflags; int error; - int narg; - register_t args[8]; - register_t *argp; - u_int code; - int reg, regcnt; ksiginfo_t ksi; PCPU_INC(cnt.v_syscall); + td = curthread; + p = td->td_proc; + td->td_syscalls++; #ifdef DIAGNOSTIC if (ISPL(frame->tf_cs) != SEL_UPL) { @@ -914,65 +978,37 @@ syscall(struct trapframe *frame) } #endif - reg = 0; - regcnt = 6; td->td_pticks = 0; td->td_frame = frame; if (td->td_ucred != p->p_ucred) cred_update_thread(td); - params = (caddr_t)frame->tf_rsp + sizeof(register_t); - code = frame->tf_rax; orig_tf_rflags = frame->tf_rflags; - - if (p->p_sysent->sv_prepsyscall) { - (*p->p_sysent->sv_prepsyscall)(frame, (int *)args, &code, ¶ms); - } else { - if (code == SYS_syscall || code == SYS___syscall) { - code = frame->tf_rdi; - reg++; - regcnt--; - } + if (p->p_flag & P_TRACED) { + PROC_LOCK(p); + td->td_dbgflags &= ~TDB_USERWR; + PROC_UNLOCK(p); } - - if (p->p_sysent->sv_mask) - code &= p->p_sysent->sv_mask; - - if (code >= p->p_sysent->sv_size) - callp = &p->p_sysent->sv_table[0]; - else - callp = &p->p_sysent->sv_table[code]; - - narg = callp->sy_narg; - KASSERT(narg <= sizeof(args) / sizeof(args[0]), - ("Too many syscall arguments!")); - error = 0; - argp = &frame->tf_rdi; - argp += reg; - bcopy(argp, args, sizeof(args[0]) * regcnt); - if (narg > regcnt) { - KASSERT(params != NULL, ("copyin args with no params!")); - error = copyin(params, &args[regcnt], - (narg - regcnt) * sizeof(args[0])); - } - argp = &args[0]; - -#ifdef KTRACE - if (KTRPOINT(td, KTR_SYSCALL)) - ktrsyscall(code, narg, argp); -#endif + error = fetch_syscall_args(td, &sa); CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td, - td->td_proc->p_pid, td->td_name, code); - - td->td_syscalls++; + td->td_proc->p_pid, td->td_name, sa.code); if (error == 0) { td->td_retval[0] = 0; td->td_retval[1] = frame->tf_rdx; - STOPEVENT(p, S_SCE, narg); - + STOPEVENT(p, S_SCE, sa.narg); PTRACESTOP_SC(p, td, S_PT_SCE); + if (td->td_dbgflags & TDB_USERWR) { + /* + * Reread syscall number and arguments if + * debugger modified registers or memory. + */ + error = fetch_syscall_args(td, &sa); + if (error != 0) + goto retval; + td->td_retval[1] = frame->tf_rdx; + } #ifdef KDTRACE_HOOKS /* @@ -980,13 +1016,13 @@ syscall(struct trapframe *frame) * callback and if there is a probe active for the * syscall 'entry', process the probe. */ - if (systrace_probe_func != NULL && callp->sy_entry != 0) - (*systrace_probe_func)(callp->sy_entry, code, callp, - args); + if (systrace_probe_func != NULL && sa.callp->sy_entry != 0) + (*systrace_probe_func)(sa.callp->sy_entry, sa.code, + sa.callp, sa.args); #endif - AUDIT_SYSCALL_ENTER(code, td); - error = (*callp->sy_call)(td, argp); + AUDIT_SYSCALL_ENTER(sa.code, td); + error = (*sa.callp->sy_call)(td, sa.argp); AUDIT_SYSCALL_EXIT(error, td); /* Save the latest error return value. */ @@ -998,12 +1034,12 @@ syscall(struct trapframe *frame) * callback and if there is a probe active for the * syscall 'return', process the probe. */ - if (systrace_probe_func != NULL && callp->sy_return != 0) - (*systrace_probe_func)(callp->sy_return, code, callp, - args); + if (systrace_probe_func != NULL && sa.callp->sy_return != 0) + (*systrace_probe_func)(sa.callp->sy_return, sa.code, + sa.callp, sa.args); #endif } - + retval: cpu_set_syscall_retval(td, error); /* @@ -1022,14 +1058,16 @@ syscall(struct trapframe *frame) * Check for misbehavior. */ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", - (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + syscallnames[sa.code] : "???"); KASSERT(td->td_critnest == 0, ("System call %s returning in a critical section", - (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???")); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + syscallnames[sa.code] : "???")); KASSERT(td->td_locks == 0, ("System call %s returning with %d locks held", - (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???", - td->td_locks)); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + syscallnames[sa.code] : "???", td->td_locks)); /* * Handle reschedule and other end-of-syscall issues @@ -1037,11 +1075,11 @@ syscall(struct trapframe *frame) userret(td, frame); CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td, - td->td_proc->p_pid, td->td_name, code); + td->td_proc->p_pid, td->td_name, sa.code); #ifdef KTRACE if (KTRPOINT(td, KTR_SYSRET)) - ktrsysret(code, error, td->td_retval[0]); + ktrsysret(sa.code, error, td->td_retval[0]); #endif /* @@ -1049,7 +1087,7 @@ syscall(struct trapframe *frame) * register set. If we ever support an emulation where this * is not the case, this code will need to be revisited. */ - STOPEVENT(p, S_SCX, code); + STOPEVENT(p, S_SCX, sa.code); PTRACESTOP_SC(p, td, S_PT_SCX); } diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c index 5e2087607d4..aa1ae6cbd71 100644 --- a/sys/amd64/ia32/ia32_syscall.c +++ b/sys/amd64/ia32/ia32_syscall.c @@ -88,101 +88,136 @@ extern const char *freebsd32_syscallnames[]; void ia32_syscall(struct trapframe *frame); /* Called from asm code */ -void -ia32_syscall(struct trapframe *frame) -{ - caddr_t params; - int i; - struct sysent *callp; - struct thread *td = curthread; - struct proc *p = td->td_proc; - register_t orig_tf_rflags; - int error; - int narg; - u_int32_t args[8]; - u_int64_t args64[8]; +struct ia32_syscall_args { u_int code; - ksiginfo_t ksi; + caddr_t params; + struct sysent *callp; + u_int64_t args64[8]; + int narg; +}; - PCPU_INC(cnt.v_syscall); - td->td_pticks = 0; - td->td_frame = frame; - if (td->td_ucred != p->p_ucred) - cred_update_thread(td); - params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t); - code = frame->tf_rax; - orig_tf_rflags = frame->tf_rflags; +static int +fetch_ia32_syscall_args(struct thread *td, struct ia32_syscall_args *sa) +{ + struct proc *p; + struct trapframe *frame; + u_int32_t args[8]; + int error, i; + + p = td->td_proc; + frame = td->td_frame; + + sa->params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t); + sa->code = frame->tf_rax; if (p->p_sysent->sv_prepsyscall) { /* * The prep code is MP aware. */ - (*p->p_sysent->sv_prepsyscall)(frame, args, &code, ¶ms); + (*p->p_sysent->sv_prepsyscall)(frame, args, &sa->code, + &sa->params); } else { /* * Need to check if this is a 32 bit or 64 bit syscall. * fuword is MP aware. */ - if (code == SYS_syscall) { + if (sa->code == SYS_syscall) { /* * Code is first argument, followed by actual args. */ - code = fuword32(params); - params += sizeof(int); - } else if (code == SYS___syscall) { + sa->code = fuword32(sa->params); + sa->params += sizeof(int); + } else if (sa->code == SYS___syscall) { /* * Like syscall, but code is a quad, so as to maintain * quad alignment for the rest of the arguments. * We use a 32-bit fetch in case params is not * aligned. */ - code = fuword32(params); - params += sizeof(quad_t); + sa->code = fuword32(sa->params); + sa->params += sizeof(quad_t); } } - if (p->p_sysent->sv_mask) - code &= p->p_sysent->sv_mask; - - if (code >= p->p_sysent->sv_size) - callp = &p->p_sysent->sv_table[0]; + sa->code &= p->p_sysent->sv_mask; + if (sa->code >= p->p_sysent->sv_size) + sa->callp = &p->p_sysent->sv_table[0]; else - callp = &p->p_sysent->sv_table[code]; + sa->callp = &p->p_sysent->sv_table[sa->code]; + sa->narg = sa->callp->sy_narg; - narg = callp->sy_narg; - - /* - * copyin and the ktrsyscall()/ktrsysret() code is MP-aware - */ - if (params != NULL && narg != 0) - error = copyin(params, (caddr_t)args, - (u_int)(narg * sizeof(int))); + if (sa->params != NULL && sa->narg != 0) + error = copyin(sa->params, (caddr_t)args, + (u_int)(sa->narg * sizeof(int))); else error = 0; - for (i = 0; i < narg; i++) - args64[i] = args[i]; + for (i = 0; i < sa->narg; i++) + sa->args64[i] = args[i]; #ifdef KTRACE if (KTRPOINT(td, KTR_SYSCALL)) - ktrsyscall(code, narg, args64); + ktrsyscall(sa->code, sa->narg, sa->args64); #endif + + return (error); +} + +void +ia32_syscall(struct trapframe *frame) +{ + struct thread *td; + struct proc *p; + struct ia32_syscall_args sa; + register_t orig_tf_rflags; + int error; + ksiginfo_t ksi; + + PCPU_INC(cnt.v_syscall); + td = curthread; + p = td->td_proc; + td->td_syscalls++; + + td->td_pticks = 0; + td->td_frame = frame; + if (td->td_ucred != p->p_ucred) + cred_update_thread(td); + orig_tf_rflags = frame->tf_rflags; + if (p->p_flag & P_TRACED) { + PROC_LOCK(p); + td->td_dbgflags &= ~TDB_USERWR; + PROC_UNLOCK(p); + } + error = fetch_ia32_syscall_args(td, &sa); + CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td, - td->td_proc->p_pid, td->td_proc->p_comm, code); + td->td_proc->p_pid, td->td_name, sa.code); if (error == 0) { td->td_retval[0] = 0; td->td_retval[1] = frame->tf_rdx; - STOPEVENT(p, S_SCE, narg); - + STOPEVENT(p, S_SCE, sa.narg); PTRACESTOP_SC(p, td, S_PT_SCE); + if (td->td_dbgflags & TDB_USERWR) { + /* + * Reread syscall number and arguments if + * debugger modified registers or memory. + */ + error = fetch_ia32_syscall_args(td, &sa); + if (error != 0) + goto retval; + td->td_retval[1] = frame->tf_rdx; + } - AUDIT_SYSCALL_ENTER(code, td); - error = (*callp->sy_call)(td, args64); + AUDIT_SYSCALL_ENTER(sa.code, td); + error = (*sa.callp->sy_call)(td, sa.args64); AUDIT_SYSCALL_EXIT(error, td); - } + /* Save the latest error return value. */ + td->td_errno = error; + } + retval: cpu_set_syscall_retval(td, error); /* @@ -201,14 +236,16 @@ ia32_syscall(struct trapframe *frame) * Check for misbehavior. */ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", - (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???"); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + freebsd32_syscallnames[sa.code] : "???"); KASSERT(td->td_critnest == 0, ("System call %s returning in a critical section", - (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???")); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + freebsd32_syscallnames[sa.code] : "???")); KASSERT(td->td_locks == 0, ("System call %s returning with %d locks held", - (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???", - td->td_locks)); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + freebsd32_syscallnames[sa.code] : "???", td->td_locks)); /* * Handle reschedule and other end-of-syscall issues @@ -216,10 +253,10 @@ ia32_syscall(struct trapframe *frame) userret(td, frame); CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td, - td->td_proc->p_pid, td->td_proc->p_comm, code); + td->td_proc->p_pid, td->td_proc->p_comm, sa.code); #ifdef KTRACE if (KTRPOINT(td, KTR_SYSRET)) - ktrsysret(code, error, td->td_retval[0]); + ktrsysret(sa.code, error, td->td_retval[0]); #endif /* @@ -227,7 +264,7 @@ ia32_syscall(struct trapframe *frame) * register set. If we ever support an emulation where this * is not the case, this code will need to be revisited. */ - STOPEVENT(p, S_SCX, code); + STOPEVENT(p, S_SCX, sa.code); PTRACESTOP_SC(p, td, S_PT_SCX); } diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index f8d0ea02634..e3d53f32d62 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -971,6 +971,72 @@ dblfault_handler() panic("double fault"); } +struct syscall_args { + u_int code; + struct sysent *callp; + int args[8]; + register_t *argp; + int narg; +}; + +static int +fetch_syscall_args(struct thread *td, struct syscall_args *sa) +{ + struct proc *p; + struct trapframe *frame; + caddr_t params; + int error; + + p = td->td_proc; + frame = td->td_frame; + + params = (caddr_t)frame->tf_esp + sizeof(int); + sa->code = frame->tf_eax; + + if (p->p_sysent->sv_prepsyscall) { + (*p->p_sysent->sv_prepsyscall)(frame, sa->args, &sa->code, + ¶ms); + } else { + /* + * Need to check if this is a 32 bit or 64 bit syscall. + */ + if (sa->code == SYS_syscall) { + /* + * Code is first argument, followed by actual args. + */ + sa->code = fuword(params); + params += sizeof(int); + } else if (sa->code == SYS___syscall) { + /* + * Like syscall, but code is a quad, so as to maintain + * quad alignment for the rest of the arguments. + */ + sa->code = fuword(params); + params += sizeof(quad_t); + } + } + + if (p->p_sysent->sv_mask) + sa->code &= p->p_sysent->sv_mask; + if (sa->code >= p->p_sysent->sv_size) + sa->callp = &p->p_sysent->sv_table[0]; + else + sa->callp = &p->p_sysent->sv_table[sa->code]; + sa->narg = sa->callp->sy_narg; + + if (params != NULL && sa->narg != 0) + error = copyin(params, (caddr_t)sa->args, + (u_int)(sa->narg * sizeof(int))); + else + error = 0; + +#ifdef KTRACE + if (KTRPOINT(td, KTR_SYSCALL)) + ktrsyscall(sa->code, sa->narg, sa->args); +#endif + return (error); +} + /* * syscall - system call request C handler * @@ -979,18 +1045,17 @@ dblfault_handler() void syscall(struct trapframe *frame) { - caddr_t params; - struct sysent *callp; - struct thread *td = curthread; - struct proc *p = td->td_proc; + struct thread *td; + struct proc *p; + struct syscall_args sa; register_t orig_tf_eflags; int error; - int narg; - int args[8]; - u_int code; ksiginfo_t ksi; PCPU_INC(cnt.v_syscall); + td = curthread; + p = td->td_proc; + td->td_syscalls++; #ifdef DIAGNOSTIC if (ISPL(frame->tf_cs) != SEL_UPL) { @@ -1003,65 +1068,33 @@ syscall(struct trapframe *frame) td->td_frame = frame; if (td->td_ucred != p->p_ucred) cred_update_thread(td); - params = (caddr_t)frame->tf_esp + sizeof(int); - code = frame->tf_eax; orig_tf_eflags = frame->tf_eflags; - - if (p->p_sysent->sv_prepsyscall) { - (*p->p_sysent->sv_prepsyscall)(frame, args, &code, ¶ms); - } else { - /* - * Need to check if this is a 32 bit or 64 bit syscall. - */ - if (code == SYS_syscall) { - /* - * Code is first argument, followed by actual args. - */ - code = fuword(params); - params += sizeof(int); - } else if (code == SYS___syscall) { - /* - * Like syscall, but code is a quad, so as to maintain - * quad alignment for the rest of the arguments. - */ - code = fuword(params); - params += sizeof(quad_t); - } + if (p->p_flag & P_TRACED) { + PROC_LOCK(p); + td->td_dbgflags &= ~TDB_USERWR; + PROC_UNLOCK(p); } - - if (p->p_sysent->sv_mask) - code &= p->p_sysent->sv_mask; - - if (code >= p->p_sysent->sv_size) - callp = &p->p_sysent->sv_table[0]; - else - callp = &p->p_sysent->sv_table[code]; - - narg = callp->sy_narg; - - if (params != NULL && narg != 0) - error = copyin(params, (caddr_t)args, - (u_int)(narg * sizeof(int))); - else - error = 0; - -#ifdef KTRACE - if (KTRPOINT(td, KTR_SYSCALL)) - ktrsyscall(code, narg, args); -#endif + error = fetch_syscall_args(td, &sa); CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td, - td->td_proc->p_pid, td->td_name, code); - - td->td_syscalls++; + td->td_proc->p_pid, td->td_name, sa.code); if (error == 0) { td->td_retval[0] = 0; td->td_retval[1] = frame->tf_edx; - STOPEVENT(p, S_SCE, narg); - + STOPEVENT(p, S_SCE, sa.narg); PTRACESTOP_SC(p, td, S_PT_SCE); + if (td->td_dbgflags & TDB_USERWR) { + /* + * Reread syscall number and arguments if + * debugger modified registers or memory. + */ + error = fetch_syscall_args(td, &sa); + if (error != 0) + goto retval; + td->td_retval[1] = frame->tf_edx; + } #ifdef KDTRACE_HOOKS /* @@ -1069,13 +1102,13 @@ syscall(struct trapframe *frame) * callback and if there is a probe active for the * syscall 'entry', process the probe. */ - if (systrace_probe_func != NULL && callp->sy_entry != 0) - (*systrace_probe_func)(callp->sy_entry, code, callp, - args); + if (systrace_probe_func != NULL && sa.callp->sy_entry != 0) + (*systrace_probe_func)(sa.callp->sy_entry, sa.code, + sa.callp, sa.args); #endif - AUDIT_SYSCALL_ENTER(code, td); - error = (*callp->sy_call)(td, args); + AUDIT_SYSCALL_ENTER(sa.code, td); + error = (*sa.callp->sy_call)(td, sa.args); AUDIT_SYSCALL_EXIT(error, td); /* Save the latest error return value. */ @@ -1087,12 +1120,12 @@ syscall(struct trapframe *frame) * callback and if there is a probe active for the * syscall 'return', process the probe. */ - if (systrace_probe_func != NULL && callp->sy_return != 0) - (*systrace_probe_func)(callp->sy_return, code, callp, - args); + if (systrace_probe_func != NULL && sa.callp->sy_return != 0) + (*systrace_probe_func)(sa.callp->sy_return, sa.code, + sa.callp, sa.args); #endif } - + retval: cpu_set_syscall_retval(td, error); /* @@ -1111,14 +1144,16 @@ syscall(struct trapframe *frame) * Check for misbehavior. */ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", - (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + syscallnames[sa.code] : "???"); KASSERT(td->td_critnest == 0, ("System call %s returning in a critical section", - (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???")); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + syscallnames[sa.code] : "???")); KASSERT(td->td_locks == 0, ("System call %s returning with %d locks held", - (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???", - td->td_locks)); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + syscallnames[sa.code] : "???", td->td_locks)); /* * Handle reschedule and other end-of-syscall issues @@ -1126,11 +1161,11 @@ syscall(struct trapframe *frame) userret(td, frame); CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td, - td->td_proc->p_pid, td->td_name, code); + td->td_proc->p_pid, td->td_name, sa.code); #ifdef KTRACE if (KTRPOINT(td, KTR_SYSRET)) - ktrsysret(code, error, td->td_retval[0]); + ktrsysret(sa.code, error, td->td_retval[0]); #endif /* @@ -1138,7 +1173,7 @@ syscall(struct trapframe *frame) * register set. If we ever support an emulation where this * is not the case, this code will need to be revisited. */ - STOPEVENT(p, S_SCX, code); + STOPEVENT(p, S_SCX, sa.code); PTRACESTOP_SC(p, td, S_PT_SCX); } diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index b8803af0c83..a4e0be8438b 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -809,6 +809,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) case PT_WRITE_I: case PT_WRITE_D: + td2->td_dbgflags |= TDB_USERWR; write = 1; /* FALLTHROUGH */ case PT_READ_I: @@ -877,6 +878,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) break; case PIOD_WRITE_D: case PIOD_WRITE_I: + td2->td_dbgflags |= TDB_USERWR; uio.uio_rw = UIO_WRITE; break; default: @@ -899,6 +901,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) goto sendsig; /* in PT_CONTINUE above */ case PT_SETREGS: + td2->td_dbgflags |= TDB_USERWR; error = PROC_WRITE(regs, td2, addr); break; @@ -907,6 +910,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) break; case PT_SETFPREGS: + td2->td_dbgflags |= TDB_USERWR; error = PROC_WRITE(fpregs, td2, addr); break; @@ -915,6 +919,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) break; case PT_SETDBREGS: + td2->td_dbgflags |= TDB_USERWR; error = PROC_WRITE(dbregs, td2, addr); break; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index c0af11f6b3d..a2e6f323c5a 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -343,6 +343,7 @@ do { \ /* Userland debug flags */ #define TDB_SUSPEND 0x00000001 /* Thread is suspended by debugger */ #define TDB_XSIG 0x00000002 /* Thread is exchanging signal under trace */ +#define TDB_USERWR 0x00000004 /* Debugger modified memory or registers */ /* * "Private" flags kept in td_pflags: From 73769927aeab05f575ca2fe3d25b040d7c9dd9e6 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sun, 7 Feb 2010 11:59:55 +0000 Subject: [PATCH 1393/2592] MFC: r202900 Merge r203608 from amd64/i386: In syscall(), reread syscall number and arguments after ptracestop(), if debugger modified anything in the process environment. --- sys/sparc64/sparc64/trap.c | 173 ++++++++++++++++++++++--------------- 1 file changed, 104 insertions(+), 69 deletions(-) diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c index 1e58351e9f5..30a40f013b9 100644 --- a/sys/sparc64/sparc64/trap.c +++ b/sys/sparc64/sparc64/trap.c @@ -93,9 +93,18 @@ __FBSDID("$FreeBSD$"); #include #include +struct syscall_args { + u_long code; + struct sysent *callp; + register_t args[8]; + register_t *argp; + int narg; +}; + void trap(struct trapframe *tf); void syscall(struct trapframe *tf); +static int fetch_syscall_args(struct thread *td, struct syscall_args *sa); static int trap_pfault(struct thread *td, struct trapframe *tf); extern char copy_fault[]; @@ -525,38 +534,93 @@ trap_pfault(struct thread *td, struct trapframe *tf) /* Maximum number of arguments that can be passed via the out registers. */ #define REG_MAXARGS 6 +static int +fetch_syscall_args(struct thread *td, struct syscall_args *sa) +{ + struct trapframe *tf; + struct proc *p; + int reg; + int regcnt; + int error; + + p = td->td_proc; + tf = td->td_frame; + reg = 0; + regcnt = REG_MAXARGS; + + sa->code = tf->tf_global[1]; + + if (p->p_sysent->sv_prepsyscall) { +#if 0 + (*p->p_sysent->sv_prepsyscall)(tf, sa->args, &sa->code, + ¶ms); +#endif + } else if (sa->code == SYS_syscall || sa->code == SYS___syscall) { + sa->code = tf->tf_out[reg++]; + regcnt--; + } + + if (p->p_sysent->sv_mask) + sa->code &= p->p_sysent->sv_mask; + + if (sa->code >= p->p_sysent->sv_size) + sa->callp = &p->p_sysent->sv_table[0]; + else + sa->callp = &p->p_sysent->sv_table[sa->code]; + + sa->narg = sa->callp->sy_narg; + KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]), + ("Too many syscall arguments!")); + error = 0; + sa->argp = sa->args; + bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt); + if (sa->narg > regcnt) + error = copyin((void *)(tf->tf_out[6] + SPOFF + + offsetof(struct frame, fr_pad[6])), &sa->args[regcnt], + (sa->narg - regcnt) * sizeof(sa->args[0])); + + /* + * This may result in two records if debugger modified + * registers or memory during sleep at stop/ptrace point. + */ +#ifdef KTRACE + if (KTRPOINT(td, KTR_SYSCALL)) + ktrsyscall(sa->code, sa->narg, sa->argp); +#endif + return (error); +} + /* - * Syscall handler. The arguments to the syscall are passed in the o registers - * by the caller, and are saved in the trap frame. The syscall number is passed - * in %g1 (and also saved in the trap frame). + * Syscall handler + * The arguments to the syscall are passed in the out registers by the caller, + * and are saved in the trap frame. The syscall number is passed in %g1 (and + * also saved in the trap frame). */ void syscall(struct trapframe *tf) { - struct sysent *callp; + struct syscall_args sa; struct thread *td; - register_t args[8]; - register_t *argp; struct proc *p; - u_long code; - int reg; - int regcnt; - int narg; int error; td = curthread; KASSERT(td != NULL, ("trap: curthread NULL")); KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); - p = td->td_proc; - PCPU_INC(cnt.v_syscall); + p = td->td_proc; + td->td_syscalls++; td->td_pticks = 0; td->td_frame = tf; if (td->td_ucred != p->p_ucred) cred_update_thread(td); - code = tf->tf_global[1]; + if ((p->p_flag & P_TRACED) != 0) { + PROC_LOCK(p); + td->td_dbgflags &= ~TDB_USERWR; + PROC_UNLOCK(p); + } /* * For syscalls, we don't want to retry the faulting instruction @@ -565,97 +629,68 @@ syscall(struct trapframe *tf) td->td_pcb->pcb_tpc = tf->tf_tpc; TF_DONE(tf); - reg = 0; - regcnt = REG_MAXARGS; - if (p->p_sysent->sv_prepsyscall) { - /* - * The prep code is MP aware. - */ -#if 0 - (*p->p_sysent->sv_prepsyscall)(tf, args, &code, ¶ms); -#endif - } else if (code == SYS_syscall || code == SYS___syscall) { - code = tf->tf_out[reg++]; - regcnt--; - } - - if (p->p_sysent->sv_mask) - code &= p->p_sysent->sv_mask; - - if (code >= p->p_sysent->sv_size) - callp = &p->p_sysent->sv_table[0]; - else - callp = &p->p_sysent->sv_table[code]; - - narg = callp->sy_narg; - - KASSERT(narg <= sizeof(args) / sizeof(args[0]), - ("Too many syscall arguments!")); - error = 0; - argp = args; - bcopy(&tf->tf_out[reg], args, sizeof(args[0]) * regcnt); - if (narg > regcnt) - error = copyin((void *)(tf->tf_out[6] + SPOFF + - offsetof(struct frame, fr_pad[6])), - &args[regcnt], (narg - regcnt) * sizeof(args[0])); - + error = fetch_syscall_args(td, &sa); CTR5(KTR_SYSC, "syscall: td=%p %s(%#lx, %#lx, %#lx)", td, - syscallnames[code], argp[0], argp[1], argp[2]); - -#ifdef KTRACE - if (KTRPOINT(td, KTR_SYSCALL)) - ktrsyscall(code, narg, argp); -#endif - - td->td_syscalls++; + syscallnames[sa.code], sa.argp[0], sa.argp[1], sa.argp[2]); if (error == 0) { td->td_retval[0] = 0; td->td_retval[1] = 0; - STOPEVENT(p, S_SCE, narg); /* MP aware */ - + STOPEVENT(p, S_SCE, sa.narg); PTRACESTOP_SC(p, td, S_PT_SCE); + if ((td->td_dbgflags & TDB_USERWR) != 0) { + /* + * Reread syscall number and arguments if + * debugger modified registers or memory. + */ + error = fetch_syscall_args(td, &sa); + if (error != 0) + goto retval; + td->td_retval[1] = 0; + } - AUDIT_SYSCALL_ENTER(code, td); - error = (*callp->sy_call)(td, argp); + AUDIT_SYSCALL_ENTER(sa.code, td); + error = (*sa.callp->sy_call)(td, sa.argp); AUDIT_SYSCALL_EXIT(error, td); - CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx ", p, - error, syscallnames[code], td->td_retval[0], + CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx", + p, error, syscallnames[sa.code], td->td_retval[0], td->td_retval[1]); } - + retval: cpu_set_syscall_retval(td, error); /* * Check for misbehavior. */ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", - (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + syscallnames[sa.code] : "???"); KASSERT(td->td_critnest == 0, ("System call %s returning in a critical section", - (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???")); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + syscallnames[sa.code] : "???")); KASSERT(td->td_locks == 0, ("System call %s returning with %d locks held", - (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???", - td->td_locks)); + (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? + syscallnames[sa.code] : "???", td->td_locks)); /* - * Handle reschedule and other end-of-syscall issues + * Handle reschedule and other end-of-syscall issues. */ userret(td, tf); #ifdef KTRACE if (KTRPOINT(td, KTR_SYSRET)) - ktrsysret(code, error, td->td_retval[0]); + ktrsysret(sa.code, error, td->td_retval[0]); #endif /* * This works because errno is findable through the * register set. If we ever support an emulation where this * is not the case, this code will need to be revisited. */ - STOPEVENT(p, S_SCX, code); + STOPEVENT(p, S_SCX, sa.code); PTRACESTOP_SC(p, td, S_PT_SCX); } From ac8e3748c2a34f2606b8ecc44a7293cd2b09dc3b Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sun, 7 Feb 2010 20:26:45 +0000 Subject: [PATCH 1394/2592] MFC 202960: Copyright-only changes to generated files as part of the 9.6.1-P3 update --- lib/bind/dns/code.h | 2 +- lib/bind/dns/dns/enumclass.h | 2 +- lib/bind/dns/dns/enumtype.h | 2 +- lib/bind/dns/dns/rdatastruct.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/bind/dns/code.h b/lib/bind/dns/code.h index db8d8c5a89a..264fc119fe7 100644 --- a/lib/bind/dns/code.h +++ b/lib/bind/dns/code.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any diff --git a/lib/bind/dns/dns/enumclass.h b/lib/bind/dns/dns/enumclass.h index b1e363f2a3f..e33d4c421f5 100644 --- a/lib/bind/dns/dns/enumclass.h +++ b/lib/bind/dns/dns/enumclass.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any diff --git a/lib/bind/dns/dns/enumtype.h b/lib/bind/dns/dns/enumtype.h index 74a6db77b83..4ad3358e1cd 100644 --- a/lib/bind/dns/dns/enumtype.h +++ b/lib/bind/dns/dns/enumtype.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any diff --git a/lib/bind/dns/dns/rdatastruct.h b/lib/bind/dns/dns/rdatastruct.h index d723941f8db..94f57b89e4e 100644 --- a/lib/bind/dns/dns/rdatastruct.h +++ b/lib/bind/dns/dns/rdatastruct.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any From 5719469a1228341ae4ad6a3773ea47f62312ad02 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sun, 7 Feb 2010 20:28:24 +0000 Subject: [PATCH 1395/2592] MFC 202961: Upgrade to BIND 9.6.1-P3. This version address the following vulnerabilities: BIND 9 Cache Update from Additional Section https://www.isc.org/advisories/CVE-2009-4022v6 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-4022 A nameserver with DNSSEC validation enabled may incorrectly add unauthenticated records to its cache that are received during the resolution of a recursive client query BIND 9 DNSSEC validation code could cause bogus NXDOMAIN responses https://www.isc.org/advisories/CVE-2010-0097 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0097 There was an error in the DNSSEC NSEC/NSEC3 validation code that could cause bogus NXDOMAIN responses (that is, NXDOMAIN responses for records proven by NSEC or NSEC3 to exist) to be cached as if they had validated correctly These issues only affect systems with DNSSEC validation enabled. --- contrib/bind9/CHANGES | 12 + contrib/bind9/FAQ | 29 +- contrib/bind9/FAQ.xml | 31 +- contrib/bind9/bin/dnssec/dnssec-signzone.8 | 364 +- contrib/bind9/bin/dnssec/dnssec-signzone.html | 16 +- contrib/bind9/bin/named/query.c | 54 +- contrib/bind9/doc/arm/Bv9ARM.pdf | 16222 ++++++++-------- .../bind9/doc/arm/man.dnssec-signzone.html | 16 +- .../bind9/doc/arm/man.named-checkconf.html | 12 +- .../bind9/doc/arm/man.named-checkzone.html | 12 +- contrib/bind9/doc/arm/man.named.html | 16 +- contrib/bind9/doc/arm/man.nsupdate.html | 14 +- contrib/bind9/doc/arm/man.rndc-confgen.html | 12 +- contrib/bind9/doc/arm/man.rndc.conf.html | 12 +- contrib/bind9/doc/arm/man.rndc.html | 12 +- contrib/bind9/lib/dns/include/dns/db.h | 19 +- contrib/bind9/lib/dns/include/dns/ncache.h | 4 +- contrib/bind9/lib/dns/include/dns/types.h | 4 +- contrib/bind9/lib/dns/rbtdb.c | 4 +- contrib/bind9/lib/dns/resolver.c | 36 +- contrib/bind9/lib/dns/validator.c | 14 +- contrib/bind9/lib/lwres/man/lwres.html | 14 +- contrib/bind9/lib/lwres/man/lwres_buffer.html | 6 +- contrib/bind9/lib/lwres/man/lwres_config.html | 12 +- .../bind9/lib/lwres/man/lwres_context.html | 10 +- contrib/bind9/lib/lwres/man/lwres_gabn.html | 10 +- .../lib/lwres/man/lwres_gai_strerror.html | 8 +- .../lib/lwres/man/lwres_getaddrinfo.html | 10 +- .../bind9/lib/lwres/man/lwres_gethostent.html | 12 +- .../bind9/lib/lwres/man/lwres_getipnode.html | 10 +- .../lib/lwres/man/lwres_getnameinfo.html | 12 +- .../lib/lwres/man/lwres_getrrsetbyname.html | 10 +- contrib/bind9/lib/lwres/man/lwres_gnba.html | 10 +- .../bind9/lib/lwres/man/lwres_hstrerror.html | 10 +- .../bind9/lib/lwres/man/lwres_inetntop.html | 10 +- contrib/bind9/lib/lwres/man/lwres_noop.html | 10 +- contrib/bind9/lib/lwres/man/lwres_packet.html | 8 +- .../bind9/lib/lwres/man/lwres_resutil.html | 10 +- contrib/bind9/version | 4 +- 39 files changed, 8692 insertions(+), 8399 deletions(-) diff --git a/contrib/bind9/CHANGES b/contrib/bind9/CHANGES index fd065d0da2b..0e9c9a6b498 100644 --- a/contrib/bind9/CHANGES +++ b/contrib/bind9/CHANGES @@ -1,3 +1,15 @@ + --- 9.6.1-P3 released --- + +2831. [security] Do not attempt to validate or cache + out-of-bailiwick data returned with a secure + answer; it must be re-fetched from its original + source and validated in that context. [RT #20819] + +2828. [security] Cached CNAME or DNAME RR could be returned to clients + without DNSSEC validation. [RT #20737] + +2827. [security] Bogus NXDOMAIN could be cached as if valid. [RT #20712] + --- 9.6.1-P2 released --- 2772. [security] When validating, track whether pending data was from diff --git a/contrib/bind9/FAQ b/contrib/bind9/FAQ index 2846b31fe09..b256ed8b10a 100644 --- a/contrib/bind9/FAQ +++ b/contrib/bind9/FAQ @@ -153,24 +153,29 @@ A: BIND 9.3 and later: Use TSIG to select the appropriate view. Master 10.0.1.1: key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; + algorithm hmac-sha256; + secret "xxxxxxxxxxxxxxxxxxxxxxxx"; }; view "internal" { - match-clients { !key external; 10.0.1/24; }; + match-clients { !key external; // reject message ment for the + // external view. + 10.0.1/24; }; // accept from these addresses. ... }; view "external" { match-clients { key external; any; }; - server 10.0.1.2 { keys external; }; + server 10.0.1.2 { keys external; }; // tag messages from the + // external view to the + // other servers for the + // view. recursion no; ... }; Slave 10.0.1.2: key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; + algorithm hmac-sha256; + secret "xxxxxxxxxxxxxxxxxxxxxxxx"; }; view "internal" { match-clients { !key external; 10.0.1/24; }; @@ -220,13 +225,13 @@ A: You choose one view to be master and the second a slave and transfer Master 10.0.1.1: key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; + algorithm hmac-sha256; + secret "xxxxxxxxxxxxxxxxxxxxxxxx"; }; key "mykey" { - algorithm hmac-md5; - secret "yyyyyyyy"; + algorithm hmac-sha256; + secret "yyyyyyyyyyyyyyyyyyyyyyyy"; }; view "internal" { @@ -239,7 +244,7 @@ A: You choose one view to be master and the second a slave and transfer type master; file "internal/example.db"; allow-update { key mykey; }; - notify-also { 10.0.1.1; }; + also-notify { 10.0.1.1; }; }; }; @@ -249,7 +254,7 @@ A: You choose one view to be master and the second a slave and transfer type slave; file "external/example.db"; masters { 10.0.1.1; }; - transfer-source { 10.0.1.1; }; + transfer-source 10.0.1.1; // allow-update-forwarding { any; }; // allow-notify { ... }; }; diff --git a/contrib/bind9/FAQ.xml b/contrib/bind9/FAQ.xml index 95346f7d052..65e8efc53a2 100644 --- a/contrib/bind9/FAQ.xml +++ b/contrib/bind9/FAQ.xml @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - +
    Frequently Asked Questions about BIND 9 @@ -319,24 +319,29 @@ Slave: 10.0.1.3 (internal), 10.0.1.4 (external, IP alias) Master 10.0.1.1: key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; + algorithm hmac-sha256; + secret "xxxxxxxxxxxxxxxxxxxxxxxx"; }; view "internal" { - match-clients { !key external; 10.0.1/24; }; + match-clients { !key external; // reject message ment for the + // external view. + 10.0.1/24; }; // accept from these addresses. ... }; view "external" { match-clients { key external; any; }; - server 10.0.1.2 { keys external; }; + server 10.0.1.2 { keys external; }; // tag messages from the + // external view to the + // other servers for the + // view. recursion no; ... }; Slave 10.0.1.2: key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; + algorithm hmac-sha256; + secret "xxxxxxxxxxxxxxxxxxxxxxxx"; }; view "internal" { match-clients { !key external; 10.0.1/24; }; @@ -424,13 +429,13 @@ named-checkzone example.com tmp Master 10.0.1.1: key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; + algorithm hmac-sha256; + secret "xxxxxxxxxxxxxxxxxxxxxxxx"; }; key "mykey" { - algorithm hmac-md5; - secret "yyyyyyyy"; + algorithm hmac-sha256; + secret "yyyyyyyyyyyyyyyyyyyyyyyy"; }; view "internal" { @@ -443,7 +448,7 @@ Master 10.0.1.1: type master; file "internal/example.db"; allow-update { key mykey; }; - notify-also { 10.0.1.1; }; + also-notify { 10.0.1.1; }; }; }; @@ -453,7 +458,7 @@ Master 10.0.1.1: type slave; file "external/example.db"; masters { 10.0.1.1; }; - transfer-source { 10.0.1.1; }; + transfer-source 10.0.1.1; // allow-update-forwarding { any; }; // allow-notify { ... }; }; diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.8 b/contrib/bind9/bin/dnssec/dnssec-signzone.8 index 84e613f721b..1e779271c34 100644 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.8 +++ b/contrib/bind9/bin/dnssec/dnssec-signzone.8 @@ -13,163 +13,287 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: dnssec-signzone.8,v 1.47.44.4 2009/06/09 01:47:19 each Exp $ +.\" $Id: dnssec-signzone.8,v 1.47.44.4.8.1 2009/12/31 23:17:46 tbox Exp $ .\" .hy 0 .ad l -.\"Generated by db2man.xsl. Don't modify this, modify the source. -.de Sh \" Subsection -.br -.if t .Sp -.ne 5 -.PP -\fB\\$1\fR -.PP -.. -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Ip \" List item -.br -.ie \\n(.$>=3 .ne \\$3 -.el .ne 3 -.IP "\\$1" \\$2 -.. -.TH "DNSSEC-SIGNZONE" 8 "June 08, 2009" "" "" -.SH NAME -dnssec-signzone \- DNSSEC zone signing tool +.\" Title: dnssec\-signzone +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: June 08, 2009 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "DNSSEC\-SIGNZONE" "8" "June 08, 2009" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +dnssec\-signzone \- DNSSEC zone signing tool .SH "SYNOPSIS" .HP 16 -\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fIclass\fR\fR] [\fB\-d\ \fIdirectory\fR\fR] [\fB\-e\ \fIend\-time\fR\fR] [\fB\-f\ \fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fIkey\fR\fR] [\fB\-l\ \fIdomain\fR\fR] [\fB\-i\ \fIinterval\fR\fR] [\fB\-I\ \fIinput\-format\fR\fR] [\fB\-j\ \fIjitter\fR\fR] [\fB\-N\ \fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fIorigin\fR\fR] [\fB\-O\ \fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-r\ \fIrandomdev\fR\fR] [\fB\-s\ \fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fIlevel\fR\fR] [\fB\-z\fR] [\fB\-3\ \fIsalt\fR\fR] [\fB\-H\ \fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...] +\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...] .SH "DESCRIPTION" .PP -\fBdnssec\-signzone\fR signs a zone\&. It generates NSEC and RRSIG records and produces a signed version of the zone\&. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a \fIkeyset\fR file for each child zone\&. +\fBdnssec\-signzone\fR +signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a +\fIkeyset\fR +file for each child zone. .SH "OPTIONS" -.TP +.PP \-a -Verify all generated signatures\&. -.TP -\-c \fIclass\fR -Specifies the DNS class of the zone\&. -.TP -\-k \fIkey\fR -Treat specified key as a key signing key ignoring any key flags\&. This option may be specified multiple times\&. -.TP -\-l \fIdomain\fR -Generate a DLV set in addition to the key (DNSKEY) and DS sets\&. The domain is appended to the name of the records\&. -.TP -\-d \fIdirectory\fR -Look for \fIkeyset\fR files in \fBdirectory\fR as the directory -.TP -\-g -Generate DS records for child zones from keyset files\&. Existing DS records will be removed\&. -.TP -\-s \fIstart\-time\fR -Specify the date and time when the generated RRSIG records become valid\&. This can be either an absolute or relative time\&. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000\&. A relative start time is indicated by +N, which is N seconds from the current time\&. If no \fBstart\-time\fR is specified, the current time minus 1 hour (to allow for clock skew) is used\&. -.TP -\-e \fIend\-time\fR -Specify the date and time when the generated RRSIG records expire\&. As with \fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation\&. A time relative to the start time is indicated with +N, which is N seconds from the start time\&. A time relative to the current time is indicated with now+N\&. If no \fBend\-time\fR is specified, 30 days from the start time is used as a default\&. -.TP -\-f \fIoutput\-file\fR -The name of the output file containing the signed zone\&. The default is to append \fI\&.signed\fR to the input filename\&. -.TP -\-h -Prints a short summary of the options and arguments to \fBdnssec\-signzone\fR\&. -.TP -\-i \fIinterval\fR -When a previously\-signed zone is passed as input, records may be resigned\&. The \fBinterval\fR option specifies the cycle interval as an offset from the current time (in seconds)\&. If a RRSIG record expires after the cycle interval, it is retained\&. Otherwise, it is considered to be expiring soon, and it will be replaced\&. -The default cycle interval is one quarter of the difference between the signature end and start times\&. So if neither \fBend\-time\fR or \fBstart\-time\fR are specified, \fBdnssec\-signzone\fR generates signatures that are valid for 30 days, with a cycle interval of 7\&.5 days\&. Therefore, if any existing RRSIG records are due to expire in less than 7\&.5 days, they would be replaced\&. -.TP -\-I \fIinput\-format\fR -The format of the input zone file\&. Possible formats are \fB"text"\fR (default) and \fB"raw"\fR\&. This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non\-text format containing updates can be signed directly\&. The use of this option does not make much sense for non\-dynamic zones\&. -.TP -\-j \fIjitter\fR -When signing a zone with a fixed signature lifetime, all RRSIG records issued at the time of signing expires simultaneously\&. If the zone is incrementally signed, i\&.e\&. a previously\-signed zone is passed as input to the signer, all expired signatures have to be regenerated at about the same time\&. The \fBjitter\fR option specifies a jitter window that will be used to randomize the signature expire time, thus spreading incremental signature regeneration over time\&. -Signature lifetime jitter also to some extent benefits validators and servers by spreading out cache expiration, i\&.e\&. if large numbers of RRSIGs don't expire at the same time from all caches there will be less congestion than if all validators need to refetch at mostly the same time\&. -.TP -\-n \fIncpus\fR -Specifies the number of threads to use\&. By default, one thread is started for each detected CPU\&. -.TP -\-N \fIsoa\-serial\-format\fR -The SOA serial number format of the signed zone\&. Possible formats are \fB"keep"\fR (default), \fB"increment"\fR and \fB"unixtime"\fR\&. -.RS -.TP -\fB"keep"\fR -Do not modify the SOA serial number\&. -.TP -\fB"increment"\fR -Increment the SOA serial number using RFC 1982 arithmetics\&. -.TP -\fB"unixtime"\fR -Set the SOA serial number to the number of seconds since epoch\&. +.RS 4 +Verify all generated signatures. .RE -.IP -.TP +.PP +\-c \fIclass\fR +.RS 4 +Specifies the DNS class of the zone. +.RE +.PP +\-k \fIkey\fR +.RS 4 +Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times. +.RE +.PP +\-l \fIdomain\fR +.RS 4 +Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records. +.RE +.PP +\-d \fIdirectory\fR +.RS 4 +Look for +\fIkeyset\fR +files in +\fBdirectory\fR +as the directory +.RE +.PP +\-g +.RS 4 +Generate DS records for child zones from keyset files. Existing DS records will be removed. +.RE +.PP +\-s \fIstart\-time\fR +.RS 4 +Specify the date and time when the generated RRSIG records become valid. This can be either an absolute or relative time. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000. A relative start time is indicated by +N, which is N seconds from the current time. If no +\fBstart\-time\fR +is specified, the current time minus 1 hour (to allow for clock skew) is used. +.RE +.PP +\-e \fIend\-time\fR +.RS 4 +Specify the date and time when the generated RRSIG records expire. As with +\fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no +\fBend\-time\fR +is specified, 30 days from the start time is used as a default. +.RE +.PP +\-f \fIoutput\-file\fR +.RS 4 +The name of the output file containing the signed zone. The default is to append +\fI.signed\fR +to the input filename. +.RE +.PP +\-h +.RS 4 +Prints a short summary of the options and arguments to +\fBdnssec\-signzone\fR. +.RE +.PP +\-i \fIinterval\fR +.RS 4 +When a previously\-signed zone is passed as input, records may be resigned. The +\fBinterval\fR +option specifies the cycle interval as an offset from the current time (in seconds). If a RRSIG record expires after the cycle interval, it is retained. Otherwise, it is considered to be expiring soon, and it will be replaced. +.sp +The default cycle interval is one quarter of the difference between the signature end and start times. So if neither +\fBend\-time\fR +or +\fBstart\-time\fR +are specified, +\fBdnssec\-signzone\fR +generates signatures that are valid for 30 days, with a cycle interval of 7.5 days. Therefore, if any existing RRSIG records are due to expire in less than 7.5 days, they would be replaced. +.RE +.PP +\-I \fIinput\-format\fR +.RS 4 +The format of the input zone file. Possible formats are +\fB"text"\fR +(default) and +\fB"raw"\fR. This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non\-text format containing updates can be signed directly. The use of this option does not make much sense for non\-dynamic zones. +.RE +.PP +\-j \fIjitter\fR +.RS 4 +When signing a zone with a fixed signature lifetime, all RRSIG records issued at the time of signing expires simultaneously. If the zone is incrementally signed, i.e. a previously\-signed zone is passed as input to the signer, all expired signatures have to be regenerated at about the same time. The +\fBjitter\fR +option specifies a jitter window that will be used to randomize the signature expire time, thus spreading incremental signature regeneration over time. +.sp +Signature lifetime jitter also to some extent benefits validators and servers by spreading out cache expiration, i.e. if large numbers of RRSIGs don't expire at the same time from all caches there will be less congestion than if all validators need to refetch at mostly the same time. +.RE +.PP +\-n \fIncpus\fR +.RS 4 +Specifies the number of threads to use. By default, one thread is started for each detected CPU. +.RE +.PP +\-N \fIsoa\-serial\-format\fR +.RS 4 +The SOA serial number format of the signed zone. Possible formats are +\fB"keep"\fR +(default), +\fB"increment"\fR +and +\fB"unixtime"\fR. +.RS 4 +.PP +\fB"keep"\fR +.RS 4 +Do not modify the SOA serial number. +.RE +.PP +\fB"increment"\fR +.RS 4 +Increment the SOA serial number using RFC 1982 arithmetics. +.RE +.PP +\fB"unixtime"\fR +.RS 4 +Set the SOA serial number to the number of seconds since epoch. +.RE +.RE +.RE +.PP \-o \fIorigin\fR -The zone origin\&. If not specified, the name of the zone file is assumed to be the origin\&. -.TP +.RS 4 +The zone origin. If not specified, the name of the zone file is assumed to be the origin. +.RE +.PP \-O \fIoutput\-format\fR -The format of the output file containing the signed zone\&. Possible formats are \fB"text"\fR (default) and \fB"raw"\fR\&. -.TP +.RS 4 +The format of the output file containing the signed zone. Possible formats are +\fB"text"\fR +(default) and +\fB"raw"\fR. +.RE +.PP \-p -Use pseudo\-random data when signing the zone\&. This is faster, but less secure, than using real random data\&. This option may be useful when signing large zones or when the entropy source is limited\&. -.TP +.RS 4 +Use pseudo\-random data when signing the zone. This is faster, but less secure, than using real random data. This option may be useful when signing large zones or when the entropy source is limited. +.RE +.PP \-r \fIrandomdev\fR -Specifies the source of randomness\&. If the operating system does not provide a \fI/dev/random\fR or equivalent device, the default source of randomness is keyboard input\&. \fIrandomdev\fR specifies the name of a character device or file containing random data to be used instead of the default\&. The special value \fIkeyboard\fR indicates that keyboard input should be used\&. -.TP +.RS 4 +Specifies the source of randomness. If the operating system does not provide a +\fI/dev/random\fR +or equivalent device, the default source of randomness is keyboard input. +\fIrandomdev\fR +specifies the name of a character device or file containing random data to be used instead of the default. The special value +\fIkeyboard\fR +indicates that keyboard input should be used. +.RE +.PP \-t -Print statistics at completion\&. -.TP +.RS 4 +Print statistics at completion. +.RE +.PP \-v \fIlevel\fR -Sets the debugging level\&. -.TP +.RS 4 +Sets the debugging level. +.RE +.PP \-z -Ignore KSK flag on key when determining what to sign\&. -.TP +.RS 4 +Ignore KSK flag on key when determining what to sign. +.RE +.PP \-3 \fIsalt\fR -Generate a NSEC3 chain with the given hex encoded salt\&. A dash (\fIsalt\fR) can be used to indicate that no salt is to be used when generating the NSEC3 chain\&. -.TP +.RS 4 +Generate a NSEC3 chain with the given hex encoded salt. A dash (\fIsalt\fR) can be used to indicate that no salt is to be used when generating the NSEC3 chain. +.RE +.PP \-H \fIiterations\fR -When generating a NSEC3 chain use this many interations\&. The default is 100\&. -.TP +.RS 4 +When generating a NSEC3 chain use this many interations. The default is 100. +.RE +.PP \-A -When generating a NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations\&. -.TP +.RS 4 +When generating a NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations. +.RE +.PP zonefile -The file containing the zone to be signed\&. -.TP +.RS 4 +The file containing the zone to be signed. +.RE +.PP key -Specify which keys should be used to sign the zone\&. If no keys are specified, then the zone will be examined for DNSKEY records at the zone apex\&. If these are found and there are matching private keys, in the current directory, then these will be used for signing\&. +.RS 4 +Specify which keys should be used to sign the zone. If no keys are specified, then the zone will be examined for DNSKEY records at the zone apex. If these are found and there are matching private keys, in the current directory, then these will be used for signing. +.RE .SH "EXAMPLE" .PP -The following command signs the \fBexample\&.com\fR zone with the DSA key generated by \fBdnssec\-keygen\fR (Kexample\&.com\&.+003+17247)\&. The zone's keys must be in the master file (\fIdb\&.example\&.com\fR)\&. This invocation looks for \fIkeyset\fR files, in the current directory, so that DS records can be generated from them (\fB\-g\fR)\&. +The following command signs the +\fBexample.com\fR +zone with the DSA key generated by +\fBdnssec\-keygen\fR +(Kexample.com.+003+17247). The zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for +\fIkeyset\fR +files, in the current directory, so that DS records can be generated from them (\fB\-g\fR). +.sp +.RS 4 .nf -% dnssec\-signzone \-g \-o example\&.com db\&.example\&.com \\ -Kexample\&.com\&.+003+17247 -db\&.example\&.com\&.signed +% dnssec\-signzone \-g \-o example.com db.example.com \\ +Kexample.com.+003+17247 +db.example.com.signed % .fi +.RE .PP -In the above example, \fBdnssec\-signzone\fR creates the file \fIdb\&.example\&.com\&.signed\fR\&. This file should be referenced in a zone statement in a \fInamed\&.conf\fR file\&. +In the above example, +\fBdnssec\-signzone\fR +creates the file +\fIdb.example.com.signed\fR. This file should be referenced in a zone statement in a +\fInamed.conf\fR +file. .PP -This example re\-signs a previously signed zone with default parameters\&. The private keys are assumed to be in the current directory\&. +This example re\-signs a previously signed zone with default parameters. The private keys are assumed to be in the current directory. +.sp +.RS 4 .nf -% cp db\&.example\&.com\&.signed db\&.example\&.com -% dnssec\-signzone \-o example\&.com db\&.example\&.com -db\&.example\&.com\&.signed +% cp db.example.com.signed db.example.com +% dnssec\-signzone \-o example.com db.example.com +db.example.com.signed % .fi +.RE .SH "KNOWN BUGS" .PP - \fBdnssec\-signzone\fR was designed so that it could sign a zone partially, using only a subset of the DNSSEC keys needed to produce a fully\-signed zone\&. This permits a zone administrator, for example, to sign a zone with one key on one machine, move the resulting partially\-signed zone to a second machine, and sign it again with a second key\&. +\fBdnssec\-signzone\fR +was designed so that it could sign a zone partially, using only a subset of the DNSSEC keys needed to produce a fully\-signed zone. This permits a zone administrator, for example, to sign a zone with one key on one machine, move the resulting partially\-signed zone to a second machine, and sign it again with a second key. .PP -An unfortunate side\-effect of this flexibility is that \fBdnssec\-signzone\fR does not check to make sure it's signing a zone with any valid keys at all\&. An attempt to sign a zone without any keys will appear to succeed, producing a "signed" zone with no signatures\&. There is no warning issued when a zone is not fully signed\&. +An unfortunate side\-effect of this flexibility is that +\fBdnssec\-signzone\fR +does not check to make sure it's signing a zone with any valid keys at all. An attempt to sign a zone without any keys will appear to succeed, producing a "signed" zone with no signatures. There is no warning issued when a zone is not fully signed. .PP -This will be corrected in a future release\&. In the meantime, ISC recommends examining the output of \fBdnssec\-signzone\fR to confirm that the zone is properly signed by all keys before using it\&. +This will be corrected in a future release. In the meantime, ISC recommends examining the output of +\fBdnssec\-signzone\fR +to confirm that the zone is properly signed by all keys before using it. .SH "SEE ALSO" .PP -\fBdnssec\-keygen\fR(8), BIND 9 Administrator Reference Manual, RFC 4033\&. +\fBdnssec\-keygen\fR(8), +BIND 9 Administrator Reference Manual, +RFC 4033. .SH "AUTHOR" .PP -Internet Systems Consortium +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004\-2009 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000\-2003 Internet Software Consortium. +.br diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.html b/contrib/bind9/bin/dnssec/dnssec-signzone.html index 5eb8626e643..652d5c4355f 100644 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.html +++ b/contrib/bind9/bin/dnssec/dnssec-signzone.html @@ -14,12 +14,12 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + dnssec-signzone - +
    @@ -32,7 +32,7 @@

    dnssec-signzone [-a] [-c class] [-d directory] [-e end-time] [-f output-file] [-g] [-h] [-k key] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-p] [-r randomdev] [-s start-time] [-t] [-v level] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

    -

    DESCRIPTION

    +

    DESCRIPTION

    dnssec-signzone signs a zone. It generates NSEC and RRSIG records and produces a signed version of the @@ -43,7 +43,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -a

    @@ -258,7 +258,7 @@

    -

    EXAMPLE

    +

    EXAMPLE

    The following command signs the example.com zone with the DSA key generated by dnssec-keygen @@ -287,7 +287,7 @@ db.example.com.signed %

  • -

    KNOWN BUGS

    +

    KNOWN BUGS

    dnssec-signzone was designed so that it could sign a zone partially, using only a subset of the DNSSEC keys @@ -312,14 +312,14 @@ db.example.com.signed

    -

    SEE ALSO

    +

    SEE ALSO

    dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 4033.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/bin/named/query.c b/contrib/bind9/bin/named/query.c index 602948497a4..a56d2e646f7 100644 --- a/contrib/bind9/bin/named/query.c +++ b/contrib/bind9/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.313.20.7.12.1 2009/11/18 23:58:04 marka Exp $ */ +/* $Id: query.c,v 1.313.20.7.12.4 2009/12/31 22:53:03 each Exp $ */ /*! \file */ @@ -1160,7 +1160,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { goto cleanup; } result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, + client->query.dboptions | + DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, client->now, &node, fname, rdataset, sigrdataset); if (result == DNS_R_GLUE && @@ -1645,7 +1646,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { goto try_glue; result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, + client->query.dboptions | + DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, client->now, &node, fname, NULL, NULL); if (result == ISC_R_SUCCESS) goto found; @@ -3718,8 +3720,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) dns_rdataset_t *noqname; isc_boolean_t resuming; int line = -1; - dns_rdataset_t tmprdataset; - unsigned int dboptions; CTRACE("query_find"); @@ -3937,49 +3937,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) /* * Now look for an answer in the database. */ - dboptions = client->query.dboptions; - if (sigrdataset == NULL && client->view->enablednssec) { - /* - * If the client doesn't want DNSSEC we still want to - * look for any data pending validation to save a remote - * lookup if possible. - */ - dns_rdataset_init(&tmprdataset); - sigrdataset = &tmprdataset; - dboptions |= DNS_DBFIND_PENDINGOK; - } - refind: result = dns_db_find(db, client->query.qname, version, type, - dboptions, client->now, &node, fname, - rdataset, sigrdataset); - /* - * If we have found pending data try to validate it. - * If the data does not validate as secure and we can't - * use the unvalidated data requery the database with - * pending disabled to prevent infinite looping. - */ - if (result != ISC_R_SUCCESS || !DNS_TRUST_PENDING(rdataset->trust)) - goto validation_done; - if (validate(client, db, fname, rdataset, sigrdataset)) - goto validation_done; - if (rdataset->trust != dns_trust_pending_answer || - !PENDINGOK(client->query.dboptions)) { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (sigrdataset == &tmprdataset) - sigrdataset = NULL; - dns_db_detachnode(db, &node); - dboptions &= ~DNS_DBFIND_PENDINGOK; - goto refind; - } - validation_done: - if (sigrdataset == &tmprdataset) { - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - sigrdataset = NULL; - } + client->query.dboptions, client->now, + &node, fname, rdataset, sigrdataset); resume: CTRACE("query_find: resume"); diff --git a/contrib/bind9/doc/arm/Bv9ARM.pdf b/contrib/bind9/doc/arm/Bv9ARM.pdf index b56a05d5296..fbb664f8b27 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.pdf +++ b/contrib/bind9/doc/arm/Bv9ARM.pdf @@ -480,596 +480,608 @@ endobj (6.2.10.2 The category Phrase) endobj 325 0 obj -<< /S /GoTo /D (subsection.6.2.11) >> +<< /S /GoTo /D (subsubsection.6.2.10.3) >> endobj 328 0 obj -(6.2.11 lwres Statement Grammar) +(6.2.10.3 The query-errors Category) endobj 329 0 obj -<< /S /GoTo /D (subsection.6.2.12) >> +<< /S /GoTo /D (subsection.6.2.11) >> endobj 332 0 obj -(6.2.12 lwres Statement Definition and Usage) +(6.2.11 lwres Statement Grammar) endobj 333 0 obj -<< /S /GoTo /D (subsection.6.2.13) >> +<< /S /GoTo /D (subsection.6.2.12) >> endobj 336 0 obj -(6.2.13 masters Statement Grammar) +(6.2.12 lwres Statement Definition and Usage) endobj 337 0 obj -<< /S /GoTo /D (subsection.6.2.14) >> +<< /S /GoTo /D (subsection.6.2.13) >> endobj 340 0 obj -(6.2.14 masters Statement Definition and Usage) +(6.2.13 masters Statement Grammar) endobj 341 0 obj -<< /S /GoTo /D (subsection.6.2.15) >> +<< /S /GoTo /D (subsection.6.2.14) >> endobj 344 0 obj -(6.2.15 options Statement Grammar) +(6.2.14 masters Statement Definition and Usage) endobj 345 0 obj -<< /S /GoTo /D (subsection.6.2.16) >> +<< /S /GoTo /D (subsection.6.2.15) >> endobj 348 0 obj -(6.2.16 options Statement Definition and Usage) +(6.2.15 options Statement Grammar) endobj 349 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.1) >> +<< /S /GoTo /D (subsection.6.2.16) >> endobj 352 0 obj -(6.2.16.1 Boolean Options) +(6.2.16 options Statement Definition and Usage) endobj 353 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.2) >> +<< /S /GoTo /D (subsubsection.6.2.16.1) >> endobj 356 0 obj -(6.2.16.2 Forwarding) +(6.2.16.1 Boolean Options) endobj 357 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.3) >> +<< /S /GoTo /D (subsubsection.6.2.16.2) >> endobj 360 0 obj -(6.2.16.3 Dual-stack Servers) +(6.2.16.2 Forwarding) endobj 361 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.4) >> +<< /S /GoTo /D (subsubsection.6.2.16.3) >> endobj 364 0 obj -(6.2.16.4 Access Control) +(6.2.16.3 Dual-stack Servers) endobj 365 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.5) >> +<< /S /GoTo /D (subsubsection.6.2.16.4) >> endobj 368 0 obj -(6.2.16.5 Interfaces) +(6.2.16.4 Access Control) endobj 369 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.6) >> +<< /S /GoTo /D (subsubsection.6.2.16.5) >> endobj 372 0 obj -(6.2.16.6 Query Address) +(6.2.16.5 Interfaces) endobj 373 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.7) >> +<< /S /GoTo /D (subsubsection.6.2.16.6) >> endobj 376 0 obj -(6.2.16.7 Zone Transfers) +(6.2.16.6 Query Address) endobj 377 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.8) >> +<< /S /GoTo /D (subsubsection.6.2.16.7) >> endobj 380 0 obj -(6.2.16.8 UDP Port Lists) +(6.2.16.7 Zone Transfers) endobj 381 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.9) >> +<< /S /GoTo /D (subsubsection.6.2.16.8) >> endobj 384 0 obj -(6.2.16.9 Operating System Resource Limits) +(6.2.16.8 UDP Port Lists) endobj 385 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.10) >> +<< /S /GoTo /D (subsubsection.6.2.16.9) >> endobj 388 0 obj -(6.2.16.10 Server Resource Limits) +(6.2.16.9 Operating System Resource Limits) endobj 389 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.11) >> +<< /S /GoTo /D (subsubsection.6.2.16.10) >> endobj 392 0 obj -(6.2.16.11 Periodic Task Intervals) +(6.2.16.10 Server Resource Limits) endobj 393 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.12) >> +<< /S /GoTo /D (subsubsection.6.2.16.11) >> endobj 396 0 obj -(6.2.16.12 Topology) +(6.2.16.11 Periodic Task Intervals) endobj 397 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.13) >> +<< /S /GoTo /D (subsubsection.6.2.16.12) >> endobj 400 0 obj -(6.2.16.13 The sortlist Statement) +(6.2.16.12 Topology) endobj 401 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.14) >> +<< /S /GoTo /D (subsubsection.6.2.16.13) >> endobj 404 0 obj -(6.2.16.14 RRset Ordering) +(6.2.16.13 The sortlist Statement) endobj 405 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.15) >> +<< /S /GoTo /D (subsubsection.6.2.16.14) >> endobj 408 0 obj -(6.2.16.15 Tuning) +(6.2.16.14 RRset Ordering) endobj 409 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.16) >> +<< /S /GoTo /D (subsubsection.6.2.16.15) >> endobj 412 0 obj -(6.2.16.16 Built-in server information zones) +(6.2.16.15 Tuning) endobj 413 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.17) >> +<< /S /GoTo /D (subsubsection.6.2.16.16) >> endobj 416 0 obj -(6.2.16.17 Built-in Empty Zones) +(6.2.16.16 Built-in server information zones) endobj 417 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.18) >> +<< /S /GoTo /D (subsubsection.6.2.16.17) >> endobj 420 0 obj -(6.2.16.18 Additional Section Caching) +(6.2.16.17 Built-in Empty Zones) endobj 421 0 obj -<< /S /GoTo /D (subsection.6.2.17) >> +<< /S /GoTo /D (subsubsection.6.2.16.18) >> endobj 424 0 obj -(6.2.17 statistics-channels Statement Grammar) +(6.2.16.18 Additional Section Caching) endobj 425 0 obj -<< /S /GoTo /D (subsection.6.2.18) >> +<< /S /GoTo /D (subsection.6.2.17) >> endobj 428 0 obj -(6.2.18 statistics-channels Statement Definition and Usage) +(6.2.17 server Statement Grammar) endobj 429 0 obj -<< /S /GoTo /D (subsection.6.2.19) >> +<< /S /GoTo /D (subsection.6.2.18) >> endobj 432 0 obj -(6.2.19 server Statement Grammar) +(6.2.18 server Statement Definition and Usage) endobj 433 0 obj -<< /S /GoTo /D (subsection.6.2.20) >> +<< /S /GoTo /D (subsection.6.2.19) >> endobj 436 0 obj -(6.2.20 server Statement Definition and Usage) +(6.2.19 statistics-channels Statement Grammar) endobj 437 0 obj -<< /S /GoTo /D (subsection.6.2.21) >> +<< /S /GoTo /D (subsection.6.2.20) >> endobj 440 0 obj -(6.2.21 trusted-keys Statement Grammar) +(6.2.20 statistics-channels Statement Definition and Usage) endobj 441 0 obj -<< /S /GoTo /D (subsection.6.2.22) >> +<< /S /GoTo /D (subsection.6.2.21) >> endobj 444 0 obj -(6.2.22 trusted-keys Statement Definition and Usage) +(6.2.21 trusted-keys Statement Grammar) endobj 445 0 obj -<< /S /GoTo /D (subsection.6.2.23) >> +<< /S /GoTo /D (subsection.6.2.22) >> endobj 448 0 obj -(6.2.23 view Statement Grammar) +(6.2.22 trusted-keys Statement Definition and Usage) endobj 449 0 obj -<< /S /GoTo /D (subsection.6.2.24) >> +<< /S /GoTo /D (subsection.6.2.23) >> endobj 452 0 obj -(6.2.24 view Statement Definition and Usage) +(6.2.23 view Statement Grammar) endobj 453 0 obj -<< /S /GoTo /D (subsection.6.2.25) >> +<< /S /GoTo /D (subsection.6.2.24) >> endobj 456 0 obj -(6.2.25 zone Statement Grammar) +(6.2.24 view Statement Definition and Usage) endobj 457 0 obj -<< /S /GoTo /D (subsection.6.2.26) >> +<< /S /GoTo /D (subsection.6.2.25) >> endobj 460 0 obj -(6.2.26 zone Statement Definition and Usage) +(6.2.25 zone Statement Grammar) endobj 461 0 obj -<< /S /GoTo /D (subsubsection.6.2.26.1) >> +<< /S /GoTo /D (subsection.6.2.26) >> endobj 464 0 obj -(6.2.26.1 Zone Types) +(6.2.26 zone Statement Definition and Usage) endobj 465 0 obj -<< /S /GoTo /D (subsubsection.6.2.26.2) >> +<< /S /GoTo /D (subsubsection.6.2.26.1) >> endobj 468 0 obj -(6.2.26.2 Class) +(6.2.26.1 Zone Types) endobj 469 0 obj -<< /S /GoTo /D (subsubsection.6.2.26.3) >> +<< /S /GoTo /D (subsubsection.6.2.26.2) >> endobj 472 0 obj -(6.2.26.3 Zone Options) +(6.2.26.2 Class) endobj 473 0 obj -<< /S /GoTo /D (subsubsection.6.2.26.4) >> +<< /S /GoTo /D (subsubsection.6.2.26.3) >> endobj 476 0 obj -(6.2.26.4 Dynamic Update Policies) +(6.2.26.3 Zone Options) endobj 477 0 obj -<< /S /GoTo /D (section.6.3) >> +<< /S /GoTo /D (subsubsection.6.2.26.4) >> endobj 480 0 obj -(6.3 Zone File) +(6.2.26.4 Dynamic Update Policies) endobj 481 0 obj -<< /S /GoTo /D (subsection.6.3.1) >> +<< /S /GoTo /D (section.6.3) >> endobj 484 0 obj -(6.3.1 Types of Resource Records and When to Use Them) +(6.3 Zone File) endobj 485 0 obj -<< /S /GoTo /D (subsubsection.6.3.1.1) >> +<< /S /GoTo /D (subsection.6.3.1) >> endobj 488 0 obj -(6.3.1.1 Resource Records) +(6.3.1 Types of Resource Records and When to Use Them) endobj 489 0 obj -<< /S /GoTo /D (subsubsection.6.3.1.2) >> +<< /S /GoTo /D (subsubsection.6.3.1.1) >> endobj 492 0 obj -(6.3.1.2 Textual expression of RRs) +(6.3.1.1 Resource Records) endobj 493 0 obj -<< /S /GoTo /D (subsection.6.3.2) >> +<< /S /GoTo /D (subsubsection.6.3.1.2) >> endobj 496 0 obj -(6.3.2 Discussion of MX Records) +(6.3.1.2 Textual expression of RRs) endobj 497 0 obj -<< /S /GoTo /D (subsection.6.3.3) >> +<< /S /GoTo /D (subsection.6.3.2) >> endobj 500 0 obj -(6.3.3 Setting TTLs) +(6.3.2 Discussion of MX Records) endobj 501 0 obj -<< /S /GoTo /D (subsection.6.3.4) >> +<< /S /GoTo /D (subsection.6.3.3) >> endobj 504 0 obj -(6.3.4 Inverse Mapping in IPv4) +(6.3.3 Setting TTLs) endobj 505 0 obj -<< /S /GoTo /D (subsection.6.3.5) >> +<< /S /GoTo /D (subsection.6.3.4) >> endobj 508 0 obj -(6.3.5 Other Zone File Directives) +(6.3.4 Inverse Mapping in IPv4) endobj 509 0 obj -<< /S /GoTo /D (subsubsection.6.3.5.1) >> +<< /S /GoTo /D (subsection.6.3.5) >> endobj 512 0 obj -(6.3.5.1 The \044ORIGIN Directive) +(6.3.5 Other Zone File Directives) endobj 513 0 obj -<< /S /GoTo /D (subsubsection.6.3.5.2) >> +<< /S /GoTo /D (subsubsection.6.3.5.1) >> endobj 516 0 obj -(6.3.5.2 The \044INCLUDE Directive) +(6.3.5.1 The \044ORIGIN Directive) endobj 517 0 obj -<< /S /GoTo /D (subsubsection.6.3.5.3) >> +<< /S /GoTo /D (subsubsection.6.3.5.2) >> endobj 520 0 obj -(6.3.5.3 The \044TTL Directive) +(6.3.5.2 The \044INCLUDE Directive) endobj 521 0 obj -<< /S /GoTo /D (subsection.6.3.6) >> +<< /S /GoTo /D (subsubsection.6.3.5.3) >> endobj 524 0 obj -(6.3.6 BIND Master File Extension: the \044GENERATE Directive) +(6.3.5.3 The \044TTL Directive) endobj 525 0 obj -<< /S /GoTo /D (subsection.6.3.7) >> +<< /S /GoTo /D (subsection.6.3.6) >> endobj 528 0 obj -(6.3.7 Additional File Formats) +(6.3.6 BIND Master File Extension: the \044GENERATE Directive) endobj 529 0 obj -<< /S /GoTo /D (section.6.4) >> +<< /S /GoTo /D (subsection.6.3.7) >> endobj 532 0 obj -(6.4 BIND9 Statistics) +(6.3.7 Additional File Formats) endobj 533 0 obj -<< /S /GoTo /D (subsubsection.6.4.0.1) >> +<< /S /GoTo /D (section.6.4) >> endobj 536 0 obj -(6.4.0.1 The Statistics File) +(6.4 BIND9 Statistics) endobj 537 0 obj -<< /S /GoTo /D (subsection.6.4.1) >> +<< /S /GoTo /D (subsubsection.6.4.0.1) >> endobj 540 0 obj -(6.4.1 Statistics Counters) +(6.4.0.1 The Statistics File) endobj 541 0 obj -<< /S /GoTo /D (subsubsection.6.4.1.1) >> +<< /S /GoTo /D (subsection.6.4.1) >> endobj 544 0 obj -(6.4.1.1 Name Server Statistics Counters) +(6.4.1 Statistics Counters) endobj 545 0 obj -<< /S /GoTo /D (subsubsection.6.4.1.2) >> +<< /S /GoTo /D (subsubsection.6.4.1.1) >> endobj 548 0 obj -(6.4.1.2 Zone Maintenance Statistics Counters) +(6.4.1.1 Name Server Statistics Counters) endobj 549 0 obj -<< /S /GoTo /D (subsubsection.6.4.1.3) >> +<< /S /GoTo /D (subsubsection.6.4.1.2) >> endobj 552 0 obj -(6.4.1.3 Resolver Statistics Counters) +(6.4.1.2 Zone Maintenance Statistics Counters) endobj 553 0 obj -<< /S /GoTo /D (subsubsection.6.4.1.4) >> +<< /S /GoTo /D (subsubsection.6.4.1.3) >> endobj 556 0 obj -(6.4.1.4 Compatibility with BIND 8 Counters) +(6.4.1.3 Resolver Statistics Counters) endobj 557 0 obj -<< /S /GoTo /D (chapter.7) >> +<< /S /GoTo /D (subsubsection.6.4.1.4) >> endobj 560 0 obj -(7 BIND 9 Security Considerations) +(6.4.1.4 Socket I/O Statistics Counters) endobj 561 0 obj -<< /S /GoTo /D (section.7.1) >> +<< /S /GoTo /D (subsubsection.6.4.1.5) >> endobj 564 0 obj -(7.1 Access Control Lists) +(6.4.1.5 Compatibility with BIND 8 Counters) endobj 565 0 obj -<< /S /GoTo /D (section.7.2) >> +<< /S /GoTo /D (chapter.7) >> endobj 568 0 obj -(7.2 Chroot and Setuid) +(7 BIND 9 Security Considerations) endobj 569 0 obj -<< /S /GoTo /D (subsection.7.2.1) >> +<< /S /GoTo /D (section.7.1) >> endobj 572 0 obj -(7.2.1 The chroot Environment) +(7.1 Access Control Lists) endobj 573 0 obj -<< /S /GoTo /D (subsection.7.2.2) >> +<< /S /GoTo /D (section.7.2) >> endobj 576 0 obj -(7.2.2 Using the setuid Function) +(7.2 Chroot and Setuid) endobj 577 0 obj -<< /S /GoTo /D (section.7.3) >> +<< /S /GoTo /D (subsection.7.2.1) >> endobj 580 0 obj -(7.3 Dynamic Update Security) +(7.2.1 The chroot Environment) endobj 581 0 obj -<< /S /GoTo /D (chapter.8) >> +<< /S /GoTo /D (subsection.7.2.2) >> endobj 584 0 obj -(8 Troubleshooting) +(7.2.2 Using the setuid Function) endobj 585 0 obj -<< /S /GoTo /D (section.8.1) >> +<< /S /GoTo /D (section.7.3) >> endobj 588 0 obj -(8.1 Common Problems) +(7.3 Dynamic Update Security) endobj 589 0 obj -<< /S /GoTo /D (subsection.8.1.1) >> +<< /S /GoTo /D (chapter.8) >> endobj 592 0 obj -(8.1.1 It's not working; how can I figure out what's wrong?) +(8 Troubleshooting) endobj 593 0 obj -<< /S /GoTo /D (section.8.2) >> +<< /S /GoTo /D (section.8.1) >> endobj 596 0 obj -(8.2 Incrementing and Changing the Serial Number) +(8.1 Common Problems) endobj 597 0 obj -<< /S /GoTo /D (section.8.3) >> +<< /S /GoTo /D (subsection.8.1.1) >> endobj 600 0 obj -(8.3 Where Can I Get Help?) +(8.1.1 It's not working; how can I figure out what's wrong?) endobj 601 0 obj -<< /S /GoTo /D (appendix.A) >> +<< /S /GoTo /D (section.8.2) >> endobj 604 0 obj -(A Appendices) +(8.2 Incrementing and Changing the Serial Number) endobj 605 0 obj -<< /S /GoTo /D (section.A.1) >> +<< /S /GoTo /D (section.8.3) >> endobj 608 0 obj -(A.1 Acknowledgments) +(8.3 Where Can I Get Help?) endobj 609 0 obj -<< /S /GoTo /D (subsection.A.1.1) >> +<< /S /GoTo /D (appendix.A) >> endobj 612 0 obj -(A.1.1 A Brief History of the DNS and BIND) +(A Appendices) endobj 613 0 obj -<< /S /GoTo /D (section.A.2) >> +<< /S /GoTo /D (section.A.1) >> endobj 616 0 obj -(A.2 General DNS Reference Information) +(A.1 Acknowledgments) endobj 617 0 obj -<< /S /GoTo /D (subsection.A.2.1) >> +<< /S /GoTo /D (subsection.A.1.1) >> endobj 620 0 obj -(A.2.1 IPv6 addresses \(AAAA\)) +(A.1.1 A Brief History of the DNS and BIND) endobj 621 0 obj -<< /S /GoTo /D (section.A.3) >> +<< /S /GoTo /D (section.A.2) >> endobj 624 0 obj -(A.3 Bibliography \(and Suggested Reading\)) +(A.2 General DNS Reference Information) endobj 625 0 obj -<< /S /GoTo /D (subsection.A.3.1) >> +<< /S /GoTo /D (subsection.A.2.1) >> endobj 628 0 obj -(A.3.1 Request for Comments \(RFCs\)) +(A.2.1 IPv6 addresses \(AAAA\)) endobj 629 0 obj -<< /S /GoTo /D (subsection.A.3.2) >> +<< /S /GoTo /D (section.A.3) >> endobj 632 0 obj -(A.3.2 Internet Drafts) +(A.3 Bibliography \(and Suggested Reading\)) endobj 633 0 obj -<< /S /GoTo /D (subsection.A.3.3) >> +<< /S /GoTo /D (subsection.A.3.1) >> endobj 636 0 obj -(A.3.3 Other Documents About BIND) +(A.3.1 Request for Comments \(RFCs\)) endobj 637 0 obj -<< /S /GoTo /D (appendix.B) >> +<< /S /GoTo /D (subsection.A.3.2) >> endobj 640 0 obj -(B Manual pages) +(A.3.2 Internet Drafts) endobj 641 0 obj -<< /S /GoTo /D (section.B.1) >> +<< /S /GoTo /D (subsection.A.3.3) >> endobj 644 0 obj -(B.1 dig) +(A.3.3 Other Documents About BIND) endobj 645 0 obj -<< /S /GoTo /D (section.B.2) >> +<< /S /GoTo /D (appendix.B) >> endobj 648 0 obj -(B.2 host) +(B Manual pages) endobj 649 0 obj -<< /S /GoTo /D (section.B.3) >> +<< /S /GoTo /D (section.B.1) >> endobj 652 0 obj -(B.3 dnssec-dsfromkey) +(B.1 dig) endobj 653 0 obj -<< /S /GoTo /D (section.B.4) >> +<< /S /GoTo /D (section.B.2) >> endobj 656 0 obj -(B.4 dnssec-keyfromlabel) +(B.2 host) endobj 657 0 obj -<< /S /GoTo /D (section.B.5) >> +<< /S /GoTo /D (section.B.3) >> endobj 660 0 obj -(B.5 dnssec-keygen) +(B.3 dnssec-dsfromkey) endobj 661 0 obj -<< /S /GoTo /D (section.B.6) >> +<< /S /GoTo /D (section.B.4) >> endobj 664 0 obj -(B.6 dnssec-signzone) +(B.4 dnssec-keyfromlabel) endobj 665 0 obj -<< /S /GoTo /D (section.B.7) >> +<< /S /GoTo /D (section.B.5) >> endobj 668 0 obj -(B.7 named-checkconf) +(B.5 dnssec-keygen) endobj 669 0 obj -<< /S /GoTo /D (section.B.8) >> +<< /S /GoTo /D (section.B.6) >> endobj 672 0 obj -(B.8 named-checkzone) +(B.6 dnssec-signzone) endobj 673 0 obj -<< /S /GoTo /D (section.B.9) >> +<< /S /GoTo /D (section.B.7) >> endobj 676 0 obj -(B.9 named) +(B.7 named-checkconf) endobj 677 0 obj -<< /S /GoTo /D (section.B.10) >> +<< /S /GoTo /D (section.B.8) >> endobj 680 0 obj -(B.10 nsupdate) +(B.8 named-checkzone) endobj 681 0 obj -<< /S /GoTo /D (section.B.11) >> +<< /S /GoTo /D (section.B.9) >> endobj 684 0 obj -(B.11 rndc) +(B.9 named) endobj 685 0 obj -<< /S /GoTo /D (section.B.12) >> +<< /S /GoTo /D (section.B.10) >> endobj 688 0 obj -(B.12 rndc.conf) +(B.10 nsupdate) endobj 689 0 obj -<< /S /GoTo /D (section.B.13) >> +<< /S /GoTo /D (section.B.11) >> endobj 692 0 obj -(B.13 rndc-confgen) +(B.11 rndc) endobj 693 0 obj -<< /S /GoTo /D [694 0 R /FitH ] >> +<< /S /GoTo /D (section.B.12) >> endobj -697 0 obj << +696 0 obj +(B.12 rndc.conf) +endobj +697 0 obj +<< /S /GoTo /D (section.B.13) >> +endobj +700 0 obj +(B.13 rndc-confgen) +endobj +701 0 obj +<< /S /GoTo /D [702 0 R /FitH ] >> +endobj +705 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚÁJA †ïó9¶‡M'™d2s´T¥‚Beoâai·Rp·t­ïïÔÕ*êArÉÿ‘ü /A}È–ՓºsžŠvíèƒ ¨B)þP+!ÃlQ¡bJÕÂwìNì1úÈP©)&>áóÚÍ®˜€-A½bEM¦pæêÍÃd¾¼[L+V?ÉcºØt»~÷ršã~[÷í¶Ú~ÝNë a¤(±øË˜’å÷9·MÿÚ<ŸwYŸÝQ DËr;yƒ|ê~üÁÁýhÌ–ÁbïVV_§æŒlåP}&ûÿsßC+WDendstream endobj -694 0 obj << +702 0 obj << /Type /Page -/Contents 697 0 R -/Resources 696 0 R +/Contents 705 0 R +/Resources 704 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 703 0 R +/Parent 711 0 R >> endobj -695 0 obj << +703 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./isc-logo.pdf) /PTEX.PageNumber 1 -/PTEX.InfoDict 704 0 R +/PTEX.InfoDict 712 0 R /Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] /BBox [0.00000000 0.00000000 255.00000000 149.00000000] /Resources << /ProcSet [ /PDF /Text ] /ColorSpace << -/R15 705 0 R -/R9 706 0 R -/R11 707 0 R -/R13 708 0 R +/R15 713 0 R +/R9 714 0 R +/R11 715 0 R +/R13 716 0 R >>/ExtGState << -/R17 709 0 R -/R8 710 0 R ->>/Font << /R19 711 0 R >> +/R17 717 0 R +/R8 718 0 R +>>/Font << /R19 719 0 R >> >> -/Length 712 0 R +/Length 720 0 R /Filter /FlateDecode >> stream @@ -1085,7 +1097,7 @@ x FÑÞIca­Ç0Ú) ¹A¿+ÇÀº ¸|-Tuùa>‚s:½¯•~K“ÒÞV׋„OÒAŠI… ɪÁr2Q“°Ø¨Á>.zÎCN’¦{Õ«'^5Mã»Åûæ¡æÔÊý¹U1z6õßvãpF)ÂÏåìÊ›C£i#]bÝLkS#ˆQÁŽv–¨Ô­«•ÇcHŸ$¬Áê³DI­ÌÑptÅ73*_åª'ŽÚ¿¢ÚòQŒ×è Œ‚,É*Ñ+ôÚ™%vŽ&u߉ xœÉ-¾kz˜ Ï‡Ú Q´Pë3ÈZ§q¢Æ0¯ˆwMÍ?©=õ*_Ç£RïÑªëÆ¬¡”’¢g!SeRâÅéz·ÝŠFLÚŸv ÏÆï¤«eÇNdæÌdï"gK2cëÉ—GoOá8GëÏϦ:B Àht[~Ðåõ—×SÒÜ£uˆQk·%È´ÔÛ†ëiATÆÌp[OU‡Ç(zßQã³* *Ñûø®á¾FÅÍ„Ï'µV‡¾;1aŠÑüËŒÜr$¿Íâ9Ë8ˆü ý‚TóþÏÍ÷_oôô¢ññCÙõ"ú*~uÊqæþéïÛ{Ç"ß~±Úú"ú…bùz+·£]OZ,SÏ¥._^·§_\^þ†56g‡3^®Ç5Z©®©¹Uý¶õòÇí÷O¿½<Ó#rYëé»Ë^~¹ÁÇ<ц®5%¥Ü~ÿñsõ\êídŽ3¼4ü~èé[iþÂÈg óžµ|¥Ïà5³m“XSô7…ÿúáò¬ä>!»Î“O÷hKYð¿þîÇ Ó3/¡úôÃgë¾4EO=öï¦üì“­‡v5”ùÜþû‚ék”ùôñR”Ì¡ÌlöÅ·ß_DÍη„Rf.{úÏåYӎͧÿ^ž©í5¬?ývýüeûMüó?Ò ƒendstream endobj -704 0 obj +712 0 obj << /Producer (AFPL Ghostscript 8.51) /CreationDate (D:20050606145621) @@ -1095,46 +1107,46 @@ endobj /Author (Douglas E. Appelt) >> endobj -705 0 obj -[/Separation/PANTONE#201805#20C/DeviceCMYK 713 0 R] +713 0 obj +[/Separation/PANTONE#201805#20C/DeviceCMYK 721 0 R] endobj -706 0 obj -[/Separation/PANTONE#207506#20C/DeviceCMYK 714 0 R] +714 0 obj +[/Separation/PANTONE#207506#20C/DeviceCMYK 722 0 R] endobj -707 0 obj -[/Separation/PANTONE#20301#20C/DeviceCMYK 715 0 R] +715 0 obj +[/Separation/PANTONE#20301#20C/DeviceCMYK 723 0 R] endobj -708 0 obj -[/Separation/PANTONE#20871#20C/DeviceCMYK 716 0 R] +716 0 obj +[/Separation/PANTONE#20871#20C/DeviceCMYK 724 0 R] endobj -709 0 obj +717 0 obj << /Type /ExtGState /SA true >> endobj -710 0 obj +718 0 obj << /Type /ExtGState /OPM 1 >> endobj -711 0 obj +719 0 obj << /BaseFont /NVXWCK#2BTrajanPro-Bold -/FontDescriptor 717 0 R +/FontDescriptor 725 0 R /Type /Font /FirstChar 67 /LastChar 136 /Widths [ 800 0 0 0 0 0 452 0 0 0 0 0 0 0 0 0 582 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 841 633 576 686 590 540 923 827 407 760] -/Encoding 718 0 R +/Encoding 726 0 R /Subtype /Type1 >> endobj -712 0 obj +720 0 obj 2362 endobj -713 0 obj +721 0 obj << /Filter /FlateDecode /FunctionType 4 @@ -1145,7 +1157,7 @@ endobj stream xœ«N)-P0PÈ-ÍQH­HÎPsõ, QE¸zFÆ`^-=1°endstream endobj -714 0 obj +722 0 obj << /Filter /FlateDecode /FunctionType 4 @@ -1156,7 +1168,7 @@ endobj stream xœ«N)-P0PÈ-ÍQH­HÎPsõ LÑE ‘D Êk8/«endstream endobj -715 0 obj +723 0 obj << /Filter /FlateDecode /FunctionType 4 @@ -1167,7 +1179,7 @@ endobj stream xœ«N)-P0TÈ-ÍQH­HÎPq ôLLÑD\=C 0¯=D³endstream endobj -716 0 obj +724 0 obj << /Filter /FlateDecode /FunctionType 4 @@ -1178,7 +1190,7 @@ endobj stream xœ«N)-P0Ð365³TÈ-ÍQH­HÎP€Š™X ‹™›#Ä ô -,ŒÀüZ&‹ˆendstream endobj -717 0 obj +725 0 obj << /Type /FontDescriptor /FontName /NVXWCK#2BTrajanPro-Bold @@ -1191,17 +1203,17 @@ endobj /StemV 138 /MissingWidth 500 /CharSet (/Msmall/C/Ysmall/Nsmall/Osmall/Esmall/Rsmall/S/Ssmall/I/Tsmall/Ismall/Usmall) -/FontFile3 719 0 R +/FontFile3 727 0 R >> endobj -718 0 obj +726 0 obj << /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [ 127/Nsmall/Tsmall/Esmall/Rsmall/Ysmall/Ssmall/Msmall/Osmall/Ismall/Usmall] >> endobj -719 0 obj +727 0 obj << /Filter /FlateDecode /Subtype /Type1C @@ -1224,44 +1236,40 @@ x ȼLçÇ<;— *X³«¥×ÛGâ_Y1ETïƒ4ˆÒ-U…_>´üØ¢æ}õï÷v¼ §ádù#¹rÛŸå¥@ÔÁ\5l…hð<8Ús·’?h¹†!-¶‚*JŠ»,\G/Wé9OW—×µ.Ÿ—­€&¨[”ÄIÁÚ´Ó½7ýáÐäKý¡«¨ðúš.cxQn<¼À°üÖëgöõÁúhíY8³¶+oî^÷ë°‹>9p¯“°¥!ÑÚÙ®ŠðK´¢†#©óRÄlxŽJ”ب¬Ò–àá•{ϳwÿaû’ožÇ£ëHõÅâH9”ç/.~å÷Ë »O·Øèv61Bá5*È<6ÞÍ,‡bh‘˜¶ž\Î]Çé#¹#ØÔÍ1Oúñ°Ï¤5oÂ]цÆß4}h˜î0$å,6ü¼”A,¯?/å;Rôcy6Ò½UJ¿§Y½X^é¶ÙÉŸ‡‹º–2¸K|o½Ø”/Ȩ/ƒ( Â2Ð#žNMKðrˆ rœÛf9ËyZ¸Ú}$«Ö õ–©)  h`iÎGàAç÷´€H+Šˆ…Õ&*áX$žèìVŽhª”—›¾÷‡A1Ý£¤œÏ0‰÷—Hi éƒw~I(Áö2;à]¸L ™x4[¡OÜ,¾®ÆûÂQQ°”FdQ“ƒ¢¬„%\î¢Åâ:Ó;ÈÑ”ÌEb1ž’¡ˆÿ§=$¸¥?Iš¿CÐõ3¾C=VÐ'>·¯ôÌÒ+Ü~8 ç#;úÁ_£×á*qň+ô 8®‚ãÆpêŒ_YR”¾d%a ç¡H\eÄõãDf£Ñ¨­ŽR[kφG¸ù/WT®ò•A5”H¥ÛVoo8hnû)¼ÞÃDn…ñëqÌzfåhý&þcQbµXÇß‚çLŽúõ;{²Ðñðué¿ÊÛÙ†-©[SÄ-Û¼ÔyubÜñhüm´œ4^Ë™ ääšLÿQ‹¡endstream endobj -698 0 obj << -/D [694 0 R /XYZ 85.0394 794.5015 null] +706 0 obj << +/D [702 0 R /XYZ 85.0394 794.5015 null] >> endobj -699 0 obj << -/D [694 0 R /XYZ 85.0394 769.5949 null] +707 0 obj << +/D [702 0 R /XYZ 85.0394 769.5949 null] >> endobj -696 0 obj << -/Font << /F21 702 0 R >> -/XObject << /Im1 695 0 R >> +704 0 obj << +/Font << /F21 710 0 R >> +/XObject << /Im1 703 0 R >> /ProcSet [ /PDF /Text ] >> endobj -722 0 obj << -/Length 999 +730 0 obj << +/Length 1001 /Filter /FlateDecode >> stream -xÚµV]“¢:}÷Wð¨UC6|å‘AT¶\ÀÚÚÝGq†ªQ¼‚;5ÿþ6$Qï¼lÝò!ô±ûôI'„h~D3-dqÊ5›ÈÄÄÔÖ»Ö^À7‰ÁšŽãNëügðó7Ö6ú:«ï0ÁˆpNµÝÀ02 ÆÔÊÛ |;‡ºðª€×Ùtƒ˜È´¨¡éÌ@°»DÝ ·e3GÓm“#‹QÖ ³Á— ˜q‹ZZ¶Õ88M“hgT¶ù9ôÊÃDZxy­G¿³¯š‰‘yK cX7Ž/b\DÒ)²-n·š(Ü/PN@{I EP0DlAcãa¤S7¦Ù™VgÚé+Ø×ùqŸ×b–~Tu¾«ÄÄ+÷Uy¬‹ÓîAa×h¤3‚‰Qj©× 0% ¿Ÿ•#Œ‚Ì–¥Ùàæ§2ŸÑú%üVgÂlØ`›wQÿKhú -;IgÒÎdwÕ-·õûê8"Î0¿–]ëgaÄ©åh6eÀŒÏäS`ý}«že"ŽÒÅlÊYäÇ]QUE¹œêRŒ§*—õ¬AÞ!d(ç»rSl{+«ýF›¢ªÅó©–Ö¯…ì¦ê¦ømyTÿþÆát<”•t¿õ«°®Y)ORÌm.q Ùu8øŒ€„ nš´-í5ùžeü—ã -6d#IZgù§ØäÅvU+KF_=—òNÑeít_ÖÅ:¿ª¿«÷p%k~8ä+YT!ý«··¶Âؤæ$\V¹‹¼j›sÄŒæR"6âŒÚ-$›ù²ÍâIö4âtè&r%HŸHâïÁØ‹YsrÝT!š™°Ýh¬=aŒÁ -Ý`.Án -CfIÜ( |é| -²™°ê&cq$á¢e¤_RÖ¨ h6Sï¼p9¢éUò`¾UË=&ñDŒs?ñfàÙÆÐ}  ûÑÚ°³7[±#-»IE~š"ÅAŒ‘äë÷!ž <ë)½%õ0pCiOâDe•éÓ…ïnø 4N|¯å¨nÛèf B´ @029ç}=½8JýoK AeLwîNÏr\çïyŸfn“(Kc¨-Q˜.Ãvõ¬þ$‰ç²¶8ítnXa÷âÕ/S_•'·{ÐçM b§ЇœôewÕèeAõwÊη'SäOÃ`êGžßÏ·‘ÛËÂ@Ô!¤¿å¢!“³¡àx™^攑Ý$HÏZÄˬO%¾¢ Ô"ÿ‚rw4ÎgêmmsøáÐqá'Ðä„g#å×£¤îc(ãIœ¨ª²|ºð½À ”ljïµÕÓ6ºY‚mŒLÎyßO/ŽRÿÛˆAR™Ó»Ó³×õ{»O3·)”¥1hKԦ˰]=»?Iâ¹Ô§Ï +Œà¹xuÆËÔWòDúö ú| )ÁìôAñð¡‘“¾í®½,ˆ£þé‚ì,q{6Eþ4 ¦~äùýJq›¹}Xˆ:„ô\4d2b6Ž—éeM™ÙM‚ôìE¼ÌúTâ+Ú@-ò/(wWã|WÁ ÞÑ6—>z&.üšgîvz&ŸÝš›7‰úc&j¾’î~Œ©zý1¦«jºa#æ8ôþ›ˆ:ðƲٙTû^½!}N™Eï0ÿŸûh~endstream endobj -721 0 obj << +729 0 obj << /Type /Page -/Contents 722 0 R -/Resources 720 0 R +/Contents 730 0 R +/Resources 728 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 703 0 R +/Parent 711 0 R >> endobj -723 0 obj << -/D [721 0 R /XYZ 56.6929 794.5015 null] +731 0 obj << +/D [729 0 R /XYZ 56.6929 794.5015 null] >> endobj -720 0 obj << -/Font << /F23 726 0 R /F14 729 0 R >> +728 0 obj << +/Font << /F23 734 0 R /F14 737 0 R >> /ProcSet [ /PDF /Text ] >> endobj -732 0 obj << +740 0 obj << /Length 2891 /Filter /FlateDecode >> @@ -1281,1389 +1289,1394 @@ W M…­æ:h¾nêãô¨ýèá·oðÐkƒh—#öùlk…lMfR,`5("qP,Þ„b‰Ðø˜Ž~]í»=Ãמ,Åzž%húg°º ÁîGÓäm2ƒÅREŽ7XD‚ ˆ \@pÁ,tûµDÀ'/œÕ½ÊýØø@Á_™'Hûd !E–•B*Åéö®ÒŒ‘@aaëêdz¿µÍ:ê°uõÕ¶HA‰©”!;2¬3ÁX$1Ò5–$LCK¢[ÎÂéÌù›ödŽ÷ÇršgľڀŠL% Ù¤a½ Ò"AP‡…r=|Ê?SRxÐRèWywqqvê:ûñÌ7ƒÊ'*SƒVZâï<Ž`¨ðwæ2ciìÈÛÕ÷ Ε[~©‘&Å3çë™SÿÀóøóp%ðö?ž­®Bendstream endobj -731 0 obj << +739 0 obj << /Type /Page -/Contents 732 0 R -/Resources 730 0 R +/Contents 740 0 R +/Resources 738 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 703 0 R -/Annots [ 735 0 R 736 0 R 737 0 R 738 0 R 739 0 R 740 0 R 741 0 R 742 0 R 743 0 R 744 0 R 745 0 R 746 0 R 747 0 R 748 0 R 749 0 R 750 0 R 751 0 R 752 0 R 753 0 R 754 0 R 755 0 R 756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R 762 0 R 763 0 R 764 0 R 765 0 R 766 0 R 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 774 0 R 775 0 R 776 0 R 777 0 R 778 0 R 779 0 R 780 0 R 781 0 R 782 0 R 783 0 R 784 0 R ] +/Parent 711 0 R +/Annots [ 743 0 R 744 0 R 745 0 R 746 0 R 747 0 R 748 0 R 749 0 R 750 0 R 751 0 R 752 0 R 753 0 R 754 0 R 755 0 R 756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R 762 0 R 763 0 R 764 0 R 765 0 R 766 0 R 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 774 0 R 775 0 R 776 0 R 777 0 R 778 0 R 779 0 R 780 0 R 781 0 R 782 0 R 783 0 R 784 0 R 785 0 R 786 0 R 787 0 R 788 0 R 789 0 R 790 0 R 791 0 R 792 0 R ] >> endobj -735 0 obj << +743 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 688.709 539.579 697.2967] /Subtype /Link /A << /S /GoTo /D (chapter.1) >> >> endobj -736 0 obj << +744 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 676.5858 539.579 685.4425] /Subtype /Link /A << /S /GoTo /D (section.1.1) >> >> endobj -737 0 obj << +745 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 664.4876 539.579 673.3442] /Subtype /Link /A << /S /GoTo /D (section.1.2) >> >> endobj -738 0 obj << +746 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 652.3894 539.579 661.246] /Subtype /Link /A << /S /GoTo /D (section.1.3) >> >> endobj -739 0 obj << +747 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 640.1914 539.579 649.1477] /Subtype /Link /A << /S /GoTo /D (section.1.4) >> >> endobj -740 0 obj << +748 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 628.0932 539.579 637.0495] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.1) >> >> endobj -741 0 obj << +749 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 615.995 539.579 624.9512] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.2) >> >> endobj -742 0 obj << +750 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 603.8967 539.579 612.853] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.3) >> >> endobj -743 0 obj << +751 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 591.7985 539.579 600.7547] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.4) >> >> endobj -744 0 obj << +752 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 579.7002 539.579 588.6565] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.4.1) >> >> endobj -745 0 obj << +753 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 567.6019 539.579 576.5582] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.4.2) >> >> endobj -746 0 obj << +754 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 555.5037 539.579 564.46] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.4.3) >> >> endobj -747 0 obj << +755 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 543.4055 539.579 552.5112] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.5) >> >> endobj -748 0 obj << +756 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 531.3072 539.579 540.413] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.5.1) >> >> endobj -749 0 obj << +757 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 519.209 539.579 528.3147] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.6) >> >> endobj -750 0 obj << +758 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 496.7003 539.579 505.4125] /Subtype /Link /A << /S /GoTo /D (chapter.2) >> >> endobj -751 0 obj << +759 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 484.5772 539.579 493.5832] /Subtype /Link /A << /S /GoTo /D (section.2.1) >> >> endobj -752 0 obj << +760 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 472.4789 539.579 481.485] /Subtype /Link /A << /S /GoTo /D (section.2.2) >> >> endobj -753 0 obj << +761 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 460.3806 539.579 469.3867] /Subtype /Link /A << /S /GoTo /D (section.2.3) >> >> endobj -754 0 obj << +762 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 448.2824 539.579 457.2885] /Subtype /Link /A << /S /GoTo /D (section.2.4) >> >> endobj -755 0 obj << +763 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 436.1841 539.579 445.1902] /Subtype /Link /A << /S /GoTo /D (section.2.5) >> >> endobj -756 0 obj << +764 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 413.4314 539.579 422.288] /Subtype /Link /A << /S /GoTo /D (chapter.3) >> >> endobj -757 0 obj << +765 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 401.353 539.579 410.4588] /Subtype /Link /A << /S /GoTo /D (section.3.1) >> >> endobj -758 0 obj << +766 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 389.2548 539.579 398.3605] /Subtype /Link /A << /S /GoTo /D (subsection.3.1.1) >> >> endobj -759 0 obj << +767 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 377.1565 539.579 386.2623] /Subtype /Link /A << /S /GoTo /D (subsection.3.1.2) >> >> endobj -760 0 obj << +768 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 365.1579 539.579 374.164] /Subtype /Link /A << /S /GoTo /D (section.3.2) >> >> endobj -761 0 obj << +769 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 353.0597 539.579 362.0658] /Subtype /Link /A << /S /GoTo /D (section.3.3) >> >> endobj -762 0 obj << +770 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 340.9614 539.579 349.9675] /Subtype /Link /A << /S /GoTo /D (subsection.3.3.1) >> >> endobj -763 0 obj << +771 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 328.7635 539.579 337.8693] /Subtype /Link /A << /S /GoTo /D (subsubsection.3.3.1.1) >> >> endobj -764 0 obj << +772 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 316.6653 539.579 325.771] /Subtype /Link /A << /S /GoTo /D (subsubsection.3.3.1.2) >> >> endobj -765 0 obj << +773 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 304.567 539.579 313.6728] /Subtype /Link /A << /S /GoTo /D (subsection.3.3.2) >> >> endobj -766 0 obj << +774 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 281.9139 539.579 290.7706] /Subtype /Link /A << /S /GoTo /D (chapter.4) >> >> endobj -767 0 obj << +775 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 269.8356 539.579 278.9413] /Subtype /Link /A << /S /GoTo /D (section.4.1) >> >> endobj -768 0 obj << +776 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 257.7373 539.579 266.8431] /Subtype /Link /A << /S /GoTo /D (section.4.2) >> >> endobj -769 0 obj << +777 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 245.6391 539.579 254.7448] /Subtype /Link /A << /S /GoTo /D (subsection.4.2.1) >> >> endobj -770 0 obj << +778 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 233.5408 539.579 242.4971] /Subtype /Link /A << /S /GoTo /D (section.4.3) >> >> endobj -771 0 obj << +779 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 221.4426 539.579 230.3988] /Subtype /Link /A << /S /GoTo /D (section.4.4) >> >> endobj -772 0 obj << +780 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 209.3443 539.579 218.3006] /Subtype /Link /A << /S /GoTo /D (subsection.4.4.1) >> >> endobj -773 0 obj << +781 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 197.2461 539.579 206.2023] /Subtype /Link /A << /S /GoTo /D (section.4.5) >> >> endobj -774 0 obj << +782 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 185.1478 539.579 194.1041] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.1) >> >> endobj -775 0 obj << +783 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 173.0496 539.579 182.0058] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.5.1.1) >> >> endobj -776 0 obj << +784 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 161.051 539.579 170.0571] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.5.1.2) >> >> endobj -777 0 obj << +785 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 148.9527 539.579 157.9588] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.2) >> >> endobj -778 0 obj << +786 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 136.8545 539.579 145.8606] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.3) >> >> endobj -779 0 obj << +787 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 124.7562 539.579 133.7623] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.4) >> >> endobj -780 0 obj << +788 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 112.5583 539.579 121.5146] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.5) >> >> endobj -781 0 obj << +789 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 100.4601 539.579 109.4163] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.6) >> >> endobj -782 0 obj << +790 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 88.3618 539.579 97.3181] /Subtype /Link /A << /S /GoTo /D (section.4.6) >> >> endobj -783 0 obj << +791 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 76.2636 539.579 85.2199] /Subtype /Link /A << /S /GoTo /D (section.4.7) >> >> endobj -784 0 obj << +792 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 64.1653 539.579 73.1216] /Subtype /Link /A << /S /GoTo /D (section.4.8) >> >> endobj -733 0 obj << -/D [731 0 R /XYZ 85.0394 794.5015 null] +741 0 obj << +/D [739 0 R /XYZ 85.0394 794.5015 null] >> endobj -734 0 obj << -/D [731 0 R /XYZ 85.0394 711.9273 null] +742 0 obj << +/D [739 0 R /XYZ 85.0394 711.9273 null] >> endobj -730 0 obj << -/Font << /F21 702 0 R /F23 726 0 R >> +738 0 obj << +/Font << /F21 710 0 R /F23 734 0 R >> /ProcSet [ /PDF /Text ] >> endobj -787 0 obj << -/Length 3167 +795 0 obj << +/Length 3159 /Filter /FlateDecode >> stream -xÚí[wÛ6Çßý)ôh?‹ûå1מvw“4q_¶ÛVfJ¢W’›Í~úEZàÈØ­ÓØR{Z;1‡3žÿO ’lBý¿l¢4ÑŽ»‰q’(ÊÔd¶<£“kÿ³ïÎXÌ44…G=¿<ûËka&Ž8ÍõäòãD*E¸ÚÌj-›\^ý|þâí›ËWo.?\ürùÃÙ«ËxVè™QÑžò_g?ÿB'W>€Î(ΪÉgÿJ˜s|²<“J%…³8ûpöcÖëz5«Ç3N~ïñ`ã- Z°ñŒÓa™ÚóšýL1KŒéWuo³©y=s‹W‹zY¯¶~¢˜9Ö~e”ÒâO0Ä>YP2Œ“L/¨÷0i¥š©UÀe¼Qù{µ} -EyÓ¢¢ ?õ´wP é,Fb¨@¹G%† -êqM¤`r¢<4†I›`Ùá"Úõ/«mõï‹©pê´´zPb*KA†(©Prq  àÞ(–m ð”—u[‡VóT…ªÕUè{«ëvuþ[˜éUö˜¥b€!ÆTAˆq2q`  Þûº¢ %Zy<®²/Û™F¿ŠÚÊšÓ¨¢ÒYŒ -0ÄPra¨dâÀPA½§áBY¢™3 –S]ù_A ©,b @©0P2q`  Þ(ReSsãA9Õ•}B–ІP!ÇÈÄ1€zý­mÑ¡°ðûõ·ß­«å²jWŒ8µ·wp -Æb¸@Å0\2q`¸ ÞÃ4„s¢¸ •¥­+ÞýÁˆµTzíQÕlÑ3‚áŒÛþ˜Ûj[§iL¤Ëp{êc΋y†OPS¡ÆyÊÄñ„z<ùÃ¥'þ8.eÖ±§7 õ©-¦&ÙaÐá0föƒÀÁ\÷ÄHg‰Ô±âDDfÖ¬¶ëf±Ép#¡LðòîICcèÄ—² x"ôäâ@ðÁ½~¬Ÿûr—*˜|0~î1…Vü1à2ÊIÈe1'Àãj%Æ·5æâÀ8A½NŒl7`GLÔALæ«ÙâöªÎQ¢‰qìÐdÇ2~Tóäábx’ÆÐCg?ŒÌuGûš¤ušÓè‡"çðøòµ¯çÿÁ›5b*‹†#P*1¾%6F ê=`¢(tRæ &¿Õ_rS__‚œ!ìiÕ7漘'`ˆñ5ÅxÊÄñ„z< KM£Ž}œ8Š>½N*¤¶˜šd‡A„ØÙCsˆážÃ2î 2‹æúºÝI–)TÆyNZÏQò¨vÆ£ 1v „<™80zPï&ýáN§¥@úPüÜc¢óçì²úÃîËbN€!Æ ÔJŒïïÎÅq‚zW™$å„Sã)íõHÛo[Þ‡FSßUË0ë}ªV«:·êç9©”î{÷i]m< ZðãšÕ„ôà 1x |<™80xPïá<,´Sí -àñÉu³ÎÍt$%Úš;ðHjªBÅô– xòI: -O.Ü{_¡„±„I *Ôá«U‹Ïë:·ÐÇ}}аŒMo¸ÒG|Ý3¦»%`ˆ¡å”ã[ðrq`(¡ÞJZ{z8(aüAP:<Ó‘Ì=¡Ñ'¤µ`ˆ!eÃÉÄ!ƒzÈ(I¨eý•{ÌýUÌe1'Àãj…q’‰ãõ8í„vW‡/U57­Ô›üëÏvðR;®©MÈq1?Àãjˆñ“‰ãõøa†8«AÒÅÏ}.XÉG]B.‹9†'P+9¾q"Æ ê=µâT§$¨H:¬ã,!IÅC ãÛ{rq` ÞFM‡ã;Ñ››fÑ\û†ÁszÀIžÃbB€!FÈ@#„L!¨÷DˆfD9,¢'äÛ7~æ¸ðsÆÜ•.I(gnÿJ—°ê8nŽÉ-Fbè ÄŽc. Ô{BG:¢$ÖÙ¡óþý¦î;Š·Ý…Ž:¼äât›UÊ\1Àãb Ìøâe.Œ Ô{âB¢†}S±æÐóÛþYËúhŒSKŸÎbV’† - !e? Ìuâ„+"ÍEw <¿/¶Óðš“ èWæ«»×ÄÿiVíZ¸1îQY(Öb²<¾&™‹“õž4f‚Hy§19_-o¶_Ò;³Ú«ßÐÔÃö !IÅC ã›brq` Þ”Éô€Ûðìêj·Õ©Z„kݳô¹~QÍ>í -…Óú iÝg£Xêd‡) s=¾Ðœ ÓsÝŽ+Á=H‡oÖßø†À7óÙfÚßÀ–Û.çû\©ì¡'ƒøIÉ##ÆØI,eØ!l $ß • au^MeˆP ök°q;ñÝŸˆÂèûªúd¿®*Ùao«‚R o¸Û{Wæ:<õ_ÁAKpøNú~ΗYV ¾„èƒ7Òsó”‰ñw²ìò\þF–`†¾%ih·±Ü`øß)w^òìkHüŒ8¥øÿÿÂàô^cÙÞXfGödqK‰kßÅ%ü°"úû1‘ZvÈÿ 9†Sendstream +xÚí[wÛ¸Çßý)ôh?Åýò˜ûɶM²±÷¥Û}`dÆÖ‰$z%9©ûé Š8´À‘ÐÆili÷ìÚ‰9œñüÂ`@d#êÿe#¥‰vÜŒ“DQ¦F“ù ]ùŸ½9aí1ãpÐõüâä/¯…9â4×£‹Ï#©ájs2K¨µltqùûé‹÷ï.^½»8?ûãâ—“Wñ¬Ð3£¢>åŸ'¿ÿAG—>€_N(ΪÑ7ÿJ˜s|4?‘J%…3;9?ù5žütcšüM%\hžøU¸¿JýCÅFF9¢…ÿIý‹Hb ;3Néé›rQ.‹õtqu6択þµ¼[­æ§äl¬üï‹tî»ì¾ÔÔgÝÝåsK›åÕ¨ùæ#T+Ø¡á¶ZÛç¯õâz+Ž ~*ŒÔ{`E¢)Õ‘Þ²r>½ZDPÖ×eóÍ?ª…ÿÎP}$%&d5›`ˆUÈIăzÄE”¶.#Zb^T‹Rʯn—‘›órùµ\Öc ‡ŠÊ #!ÙŒCŒ¨7ÃŒ$âÀA½æ‡íË#÷UMÞBâ<"ÔóðöÃWÝ’q{sS-×ͦ‹æëó·ï^6ßyÇÙãd~@!ÇÙC ¨!·Ã%âÀB½‡A†1?ÏQ¡,¹8…yvy¹Ï«jæ§ÃÙ |ûe $âÞ:ï&kn8kàtX¶¶¼¦*©ÖŠ0Él“­Í8XWÒ˜¯áô´?þ´,–w¾œJù”Kæ !}ÙŸ$`ˆ}’ <‰806Pï‘ %c”·lð–·‹®u+RT¼,Êyå']Ψƒ›U ’’™M +0ÄHba¤$âÀHÙòžs%–ºSÝŽ¹[Cm×Áëiµä|.—åbRg.œ|ïñ`ã- Z°áŒÓa™ÚòšüL1KŒiWuo“©y= s‹W³r^.Ö~¢˜9Ô~eÒìO0Ä>YP2Œ“D/¨÷0i¥š©UÀe¸Qù{±ž\‡¢¼ªQц{Ú{¨„tf£ 1T \‚£’ˆCõθ&R09Räí`Ùà"êõ»Åºø×ÙX8u\ZÝ”˜Ê\P !JO*”T(¸÷ˉ¶‚Px Ê˲®C‹iW…ŠÅeè{‹«zuþg˜éÿˆUö˜¥l€!ÆTAˆaq`  ÞÛº¢ %Zy<®²Ïë™F»ŠÚŽʚ㨢Ò™ +0ÄPra¨$âÀPA½wÃ…²D3g:XŽuå¿%¤2`ˆ¥Â@IÄ‚zï@‘š(Û57”c]Ùf d)›`ˆ1Ur˜D¨÷Ðß*Q + ߯¿}³,æó¢^=2âØÞÞÃ%d4`ˆáÃpIÄá‚zÓΉâ2T–º®x÷÷l#ÖRéÔG“Y{LoR„3nÛcÎןì¦1‘.Ãí±Ž9Ïæ b?{Ltþ?»¬¾[Ãr™Í 0Ä8Zaœ$âÀ8A½Ç«L’r©q€”úz¤m·-oC£©ïªe˜õN®‹Å¢L­úùAN*¥Ûã>\/‹•gA ~X³šÞlx€!”O ߊƒõáÎÃb@;UŸ ?\UËÔLGR¢­¹¤ö *TLo.<Ч'Ÿ¤ƒð¤â@àÁ½wðK˜”°FÕ·§î ÏŸ·åòn\.—Õ2µø§,q҆ſ4/´Ô r2™Í 0Ä8JÉáýu©80NPïíLÆ÷ê„1êÓ³oË2Å÷ó˜8¨ Mƒ¹Ò|}<¦;%`ˆ¡åÄPJÄ¡„z()I¨e¼C‰?J»gÄ’¹'T¥BZ³‘†2P69¼ +† ê= #9¡Ò©™ÝW4çÅj]&kRÝGI§wöáú°f9!ÇÙüCŒ¨!ÆO"ŒÔ{àGÔsØ]ɇâgŸ>Ü=æ><æ2›`ˆqµÂ8IÄq‚zœ0CœÕ 4í¾¤YÝÔR¯Ò¦¬w¹ó’&;¬©MÈq6?Àãjˆñ“ˆãõø¡Š8%AÒÅÏ>6壮G!—ÙœCŒ¨•¾°™Šãõ»nîqœ[@JXï{^U³²hE}ßÒ1VÂðUɘ®\ !CO9¼~—Š÷ÞÁ`ýˆà`G¤ÃúÝëjù­hžÄ³y<¤üxûÉ=6Bö²Ù†P5\PRq`l Þ;6´#VÁÖG‡å¹—·Ål¼Z“/÷ž'~¾[Û~È R• 0Ä@€R` $âÀ@@½w (C,7½Š!žM&ñ–ùõFÌz¼¨fuÑ8Þß%. `ˆa…Á°HÄazï°Š§ÄB5X¼]øösáÙ8kÊŽ·¹¦ñ ÌÆbx@ÔðFîT¨÷!ˆÑ½Ž„è_ë+7íƒÿàƒ7„1G*bÞ²©†PŒŠD¨÷Ž +ΈýîÃ4T4O+®¡¸8sôtY,VŸ7“ +eØ‹˜¸l,€!†F oBIÅazï° ŽÊzµÄ6XüöòCCŇøÚö‰Øg'åò™M +0ÄPéé5ü@¥T,¨÷Ž&ˆ”÷:ÝÐòüv:[ÃëpV _™.>o^_wHü»ZÔkáÆ¸G¹s&f![c`ˆiÜËòðšd*LcÔ{§1eD2ݓؤ$~5¿Yßu¯V«/nüDKPÛ‚´9Ê ³Ãô‡ + oˆI©¹Žâ[G„•¢'¾mÄvy¹ÙäTÌÂUîI÷‰~QL®7uÂiýtdÙÈ•Ø!2÷r=¼Äœ‘u^PeˆP|Âw?ΡÎõŒè÷Rsó”' +ƒo¼jý«Î{ß”yÝÕvØÛ®0×Ὂšû@øìó,¼§Ðs¶ùÌwK0CßÜÒi…¼+k+‚-Dâ»~ÇÜyi“/,ñÿ1â”âÿû«…»7 ËúÖ";°=‹[J\ýÖ.á篢½s¹%fsˆü?ìÑTÿendstream endobj -786 0 obj << +794 0 obj << /Type /Page -/Contents 787 0 R -/Resources 785 0 R +/Contents 795 0 R +/Resources 793 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 703 0 R -/Annots [ 792 0 R 793 0 R 794 0 R 795 0 R 796 0 R 797 0 R 798 0 R 799 0 R 800 0 R 801 0 R 802 0 R 803 0 R 804 0 R 805 0 R 806 0 R 807 0 R 808 0 R 809 0 R 810 0 R 811 0 R 812 0 R 813 0 R 814 0 R 815 0 R 816 0 R 817 0 R 818 0 R 819 0 R 820 0 R 821 0 R 822 0 R 823 0 R 824 0 R 825 0 R 826 0 R 827 0 R 828 0 R 829 0 R 830 0 R 831 0 R 832 0 R 833 0 R 834 0 R 835 0 R 836 0 R 837 0 R 838 0 R 839 0 R 840 0 R 841 0 R 842 0 R 843 0 R 844 0 R 845 0 R 846 0 R 847 0 R 848 0 R ] +/Parent 711 0 R +/Annots [ 800 0 R 801 0 R 802 0 R 803 0 R 804 0 R 805 0 R 806 0 R 807 0 R 808 0 R 809 0 R 810 0 R 811 0 R 812 0 R 813 0 R 814 0 R 815 0 R 816 0 R 817 0 R 818 0 R 819 0 R 820 0 R 821 0 R 822 0 R 823 0 R 824 0 R 825 0 R 826 0 R 827 0 R 828 0 R 829 0 R 830 0 R 831 0 R 832 0 R 833 0 R 834 0 R 835 0 R 836 0 R 837 0 R 838 0 R 839 0 R 840 0 R 841 0 R 842 0 R 843 0 R 844 0 R 845 0 R 846 0 R 847 0 R 848 0 R 849 0 R 850 0 R 851 0 R 852 0 R 853 0 R 854 0 R 855 0 R 856 0 R ] >> endobj -792 0 obj << +800 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 758.4766 511.2325 767.4329] /Subtype /Link /A << /S /GoTo /D (subsection.4.8.1) >> >> endobj -793 0 obj << +801 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 746.445 511.2325 755.4012] /Subtype /Link /A << /S /GoTo /D (subsection.4.8.2) >> >> endobj -794 0 obj << +802 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 734.5129 511.2325 743.3696] /Subtype /Link /A << /S /GoTo /D (subsection.4.8.3) >> >> endobj -795 0 obj << +803 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 722.3816 511.2325 731.3379] /Subtype /Link /A << /S /GoTo /D (section.4.9) >> >> endobj -796 0 obj << +804 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 710.3499 511.2325 719.3062] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.1) >> >> endobj -797 0 obj << +805 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 698.3182 511.2325 707.2745] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.2) >> >> endobj -798 0 obj << +806 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 675.998 511.2325 684.7301] /Subtype /Link /A << /S /GoTo /D (chapter.5) >> >> endobj -799 0 obj << +807 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 663.9862 511.2325 672.9425] /Subtype /Link /A << /S /GoTo /D (section.5.1) >> >> endobj -800 0 obj << +808 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 651.9545 511.2325 660.9108] /Subtype /Link /A << /S /GoTo /D (section.5.2) >> >> endobj -801 0 obj << +809 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 629.6343 511.2325 638.4909] /Subtype /Link /A << /S /GoTo /D (chapter.6) >> >> endobj -802 0 obj << +810 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 617.6225 511.2325 626.7282] /Subtype /Link /A << /S /GoTo /D (section.6.1) >> >> endobj -803 0 obj << +811 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 605.5908 511.2325 614.5471] /Subtype /Link /A << /S /GoTo /D (subsection.6.1.1) >> >> endobj -804 0 obj << +812 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 593.5591 511.2325 602.5154] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.1.1) >> >> endobj -805 0 obj << +813 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 581.5275 511.2325 590.4837] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.1.2) >> >> endobj -806 0 obj << +814 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 569.4958 511.2325 578.4521] /Subtype /Link /A << /S /GoTo /D (subsection.6.1.2) >> >> endobj -807 0 obj << +815 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 557.4641 511.2325 566.4204] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.2.1) >> >> endobj -808 0 obj << +816 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 545.4324 511.2325 554.5382] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.2.2) >> >> endobj -809 0 obj << +817 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 533.4007 511.2325 542.5065] /Subtype /Link /A << /S /GoTo /D (section.6.2) >> >> endobj -810 0 obj << +818 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 521.3691 511.2325 530.3254] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.1) >> >> endobj -811 0 obj << +819 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 509.3374 511.2325 518.2937] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.2) >> >> endobj -812 0 obj << +820 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 497.3057 511.2325 506.262] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.3) >> >> endobj -813 0 obj << +821 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 485.274 511.2325 494.2303] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.4) >> >> endobj -814 0 obj << +822 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 473.2424 511.2325 482.1986] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.5) >> >> endobj -815 0 obj << +823 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 461.2107 511.2325 470.167] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.6) >> >> endobj -816 0 obj << +824 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 449.179 511.2325 458.1353] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.7) >> >> endobj -817 0 obj << +825 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 437.1473 511.2325 446.1036] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.8) >> >> endobj -818 0 obj << +826 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 425.1157 511.2325 434.0719] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.9) >> >> endobj -819 0 obj << +827 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 413.084 511.2325 422.0403] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.10) >> >> endobj -820 0 obj << +828 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 401.0523 511.2325 410.0086] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.10.1) >> >> endobj -821 0 obj << +829 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 389.0206 511.2325 398.1264] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.10.2) >> >> endobj -822 0 obj << +830 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 377.0886 511.2325 386.0947] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.11) >> ->> endobj -823 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 365.0569 511.2325 374.063] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.12) >> ->> endobj -824 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 353.0252 511.2325 362.0313] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.13) >> ->> endobj -825 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 340.9936 511.2325 349.9997] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.14) >> ->> endobj -826 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 328.9619 511.2325 337.968] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.15) >> ->> endobj -827 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 316.8305 511.2325 325.9363] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.16) >> ->> endobj -828 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 304.8985 511.2325 313.9046] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.1) >> ->> endobj -829 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 292.7672 511.2325 301.7235] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.2) >> ->> endobj -830 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 280.7355 511.2325 289.6918] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.3) >> +/A << /S /GoTo /D (subsubsection.6.2.10.3) >> >> endobj 831 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 268.7038 511.2325 277.6601] +/Rect [499.2773 365.0569 511.2325 374.063] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.4) >> +/A << /S /GoTo /D (subsection.6.2.11) >> >> endobj 832 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 256.6722 511.2325 265.7779] +/Rect [499.2773 352.9256 511.2325 362.0313] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.5) >> +/A << /S /GoTo /D (subsection.6.2.12) >> >> endobj 833 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 244.6405 511.2325 253.7462] +/Rect [499.2773 340.8939 511.2325 349.9997] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.6) >> +/A << /S /GoTo /D (subsection.6.2.13) >> >> endobj 834 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 232.6088 511.2325 241.5651] +/Rect [499.2773 328.8622 511.2325 337.968] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.7) >> +/A << /S /GoTo /D (subsection.6.2.14) >> >> endobj 835 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 220.5771 511.2325 229.5334] +/Rect [499.2773 316.8305 511.2325 325.9363] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.8) >> +/A << /S /GoTo /D (subsection.6.2.15) >> >> endobj 836 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 208.5455 511.2325 217.5017] +/Rect [499.2773 304.7989 511.2325 313.9046] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.9) >> +/A << /S /GoTo /D (subsection.6.2.16) >> >> endobj 837 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 196.5138 511.2325 205.4701] +/Rect [499.2773 292.7672 511.2325 301.873] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.10) >> +/A << /S /GoTo /D (subsubsection.6.2.16.1) >> >> endobj 838 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 184.4821 511.2325 193.4384] +/Rect [499.2773 280.7355 511.2325 289.6918] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.11) >> +/A << /S /GoTo /D (subsubsection.6.2.16.2) >> >> endobj 839 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 172.4504 511.2325 181.4067] +/Rect [499.2773 268.7038 511.2325 277.6601] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.12) >> +/A << /S /GoTo /D (subsubsection.6.2.16.3) >> >> endobj 840 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 160.4187 511.2325 169.5245] +/Rect [499.2773 256.6722 511.2325 265.6285] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.13) >> +/A << /S /GoTo /D (subsubsection.6.2.16.4) >> >> endobj 841 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 148.3871 511.2325 157.3433] +/Rect [499.2773 244.6405 511.2325 253.5968] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.14) >> +/A << /S /GoTo /D (subsubsection.6.2.16.5) >> >> endobj 842 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 136.3554 511.2325 145.3117] +/Rect [499.2773 232.6088 511.2325 241.5651] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.15) >> +/A << /S /GoTo /D (subsubsection.6.2.16.6) >> >> endobj 843 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 124.3237 511.2325 133.4295] +/Rect [499.2773 220.5771 511.2325 229.5334] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.16) >> +/A << /S /GoTo /D (subsubsection.6.2.16.7) >> >> endobj 844 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 112.292 511.2325 121.2483] +/Rect [499.2773 208.5455 511.2325 217.5017] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.17) >> +/A << /S /GoTo /D (subsubsection.6.2.16.8) >> >> endobj 845 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 100.2604 511.2325 109.2166] +/Rect [499.2773 196.5138 511.2325 205.4701] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.18) >> +/A << /S /GoTo /D (subsubsection.6.2.16.9) >> >> endobj 846 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 88.2287 511.2325 97.185] +/Rect [499.2773 184.4821 511.2325 193.4384] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.17) >> +/A << /S /GoTo /D (subsubsection.6.2.16.10) >> >> endobj 847 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 76.197 511.2325 85.1533] +/Rect [499.2773 172.4504 511.2325 181.5562] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.18) >> +/A << /S /GoTo /D (subsubsection.6.2.16.11) >> >> endobj 848 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 64.1653 511.2325 73.1216] +/Rect [499.2773 160.4187 511.2325 169.5245] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.19) >> +/A << /S /GoTo /D (subsubsection.6.2.16.12) >> >> endobj -788 0 obj << -/D [786 0 R /XYZ 56.6929 794.5015 null] +849 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [499.2773 148.3871 511.2325 157.3433] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.6.2.16.13) >> >> endobj -785 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R >> -/ProcSet [ /PDF /Text ] +850 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [499.2773 136.3554 511.2325 145.3117] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.6.2.16.14) >> >> endobj 851 0 obj << -/Length 3445 -/Filter /FlateDecode ->> -stream -xÚí[SGÇßùzHÕ½}¿ì>laÀ){1©lm’YƒÊH"º@¼Ÿ~{4ÓÝG¨ç@oÖáW -æÌ9:ÿßœ¾Îˆõ¨ÿÇzV*œì'‰¢Lõã-Ú;óï½Ùbí1»á ]xÔ«Ó­¿¾¦çˆÓ\÷N?ƒsYB­e½ÓáÏÛûïOO?îüzúÃÖái<)t̨¨ÏøÛÖÏ¿ÒÞÐûÿa‹á¬ê]û_(aÎñÞxK*A”"üåbëãÖ?ã Á»+ÓÜQÂe¹É|.À'aœëŒN9¢…¯þ(špÂiýAüá .±–Jï£>l^Í®ªY{<«ðqk­ÛÃ>.ú‹j\M;»\ÑíƒêJùd´M'Í_ú“aóâÇyÿ¬ÚÙµŽn“]Eïå‡t®Èà†ÜŠ[¢9e)£úÌÎzÍ‹¨X°Û…†›Šmž¥˜Ýˆ#‹ãõžx‘†(Eyâ…ÝÊËb¶œ/ªáî—êëáøc¨ÜFLÈi11À#fM3×ML&ŒÔ{"F("µÄðoJÌíu†+ñÈJJHa1 ÀdM"L ¨÷DXÍ âV@®FÕu .ý2ê–R¢„x0¥äÿY_îSHw1LÀƒiMN¦LL¨÷cDP `’ߦ۫Œvúñ±Ó MHk14ÀƒfM6šL4¨÷vηJ …R·2óŸé¤Ê3C3· kŸrå¹…¥íR”€BÔÒ°N2A ¡®FÖ&Eú›Pt{å1Š=æªMj1,Ñ c% fD7*`¤ ~™’ÄãzÚ(B•‘P!Ìq¼„ÿ®‰X‰yºã‡Ã_/«¹Ï|à–{("!…Å`C (G& Ô{DsâüˆÂ@ö/ús„ ü1!ñÍ9¹ —Ðb\€!† ÌÈn\2q`¸ Þ.ŠúHXˆ‹¸YOÞ_Ö-F)#Q·¹b.€!ÆTƨn.2q`\ ÞÞÀ2¶Æ…l¸8ø:éGƒ¶ßp9ô]Œæõ‡éÅh0ª[©Ô“•=$¦Xv`ˆÉoL·ì™80ÙQï¾ê¬=ÿ+1ÜwÕ}!`t­¼]øWJ¹Gß‚<èŽk¡˜1`ˆ1e6ÝCæ\c¨÷4Öa’hi"duÿ•qºÖm­Y›~n~žTóér¶Ãìö  -LWÎo c~:¯Ú‘Íb6¡S|^ýLj‡7I3R¬70Äô†ÇôÎÄézOM åDiô^).n—Ö -ö,{!aÅ8C (†C& Ô{ÄA9J¤àÀ[|àÛÕï‹eÿ¢¡¡úýrC5ŸÇ)‹XNVcýT˜§R - !BÁš–wR‹¡÷e,‘”% -xÛŒæƒeFîwÿÊy¯òß÷ÌzÌa1!À#j„’‰#õžÑ æT$D´„|¬‹Ñä¬mÕOß®8/ýËr~B†‹ù†?PAÛ=–‹ãõžøñ &ñ#[~Ž&WÕ,ô -ßõ//#L£¶æ}¸òs+^†"1‹ÅŒCŒ¨ÆH&ŒÔ{bDrÂü±‘Õ2ò~q^Ín~W )£¦[2XŒ®êáŠì9·C!‹ÅŒCŒ¨’íž!ÍÅ1‚zOýUA 50‡/~H™Y§Óþx&ÃÜwïOŽÞg–ê¤ñeŒóö¸5¤vvbOuÏZLh1.Àà -†á’‰Ãõžpa†8ÇÀ…—àrt¼ÿöǃÃÜÖ5E¨]¼pñôêJHe1(ÀJ…’‰õž@¡Š8ê (¢ßóÍ­ÿkb¥ë€ÄÜÏ´üýu^BŠ‹†@PB  L@¨÷Øy‘N<é¶óòêèø ônç‹ÐI½—ÃßÕ¤aÿÍ÷\Ý^dqcF{PUØÄöÝ›ÃãÓ½z†æ4W´ ” -™OÿIãô.bªJA€†kRØîµº\¸÷‚eÄH•@0-{Ãáj¯O˜NK¼žÎÆý…ï¹j£_91ÅxC (ÕÝxdâÀð@½‡5=©ÑZ„m­²]Ó«‹„k`¨w‰æ‹Ñ Þ/Ä_–ïþ0N!ãÅ8C '¨(†S& 'Ô{ì·He¼‹<º6Ú *gùsœf‹ +Æb8@Al÷Ž\¨÷ÔøHE|# a1÷&ûÓåÄ÷EêU=êžyýè$¥Íe1(Éã(…a²F æ:Õ !ˆd&AKÆqjFskh¶~$x$·Zá6Å -';LafLáÍ 0…1×IaΈÔ8í‘&PßõG^ÆI2¨nÓÙ—–‡>?r±˜ÀS¦Ôvß­›‹Óõž¥ŽpÅ¡ ìÚ¸¸Ãµj5Bµ9ä£Xm`ˆ© ó©‰SõÕÎf¨jËVíýéøÒ+üit1Z|m$¾-Λ)áÖúÆ·4Ü\»š†ÈÌP"â *ö&3Z<´ÎA1e¥@@Cˆ5Il÷.\›ÞYæ1ÂH¢™m–þëéº6¯ŽÕ`9‹TìO'óѰšõ›Íây §öÜ-_À`3âÍóÖ!»îÛ·àé°isØáäªYN˜Nš{Y…ϧ vr2_Ì0ĸ‚Êb\eâÀ¸B½'®êÛM\…ý¡?Îãv­üº•Ñþ ŒÅNu•5J «©¯—“AsW´4Ï¡±í„*¤½*`ˆAeÅ ÊÄA…zÍ+“„S˜ -w7uÞÏ–º·Fé—)Ë<0!§ÅÀC ¨L& ˜ ï¹QwŒhÕ>ƶ£ ÓÆØölºütQÍÏ}ûU×£®ôÄ3Üu° ÁÎZd®{ÁžIǦ×ÜõÃ#Ê´OZ±q°³?ÃnýM;íS3®óR¾ŒmŠ/©˜æÒK -"—ÔšŒ;™80†Pï±a纞$â¡Ø_våâ œûçýÉÙZ/,Â.–ãåøS=ù,´{Ýø6IÅÚG3Lú$¦üF˜ðˆß¨»Dðö(6ö³~ª·Ô§‹tÿÆeü¦j/Úï«‹KJùÒ\Ü  íb„€!TÃ(Ò†÷lŒÓzb³¤¹ç 7çÛ{——Õd8TÝsÌÑìÎÝ.`€u»`8®{…žËÁ†×ìåD½w'ÚÔ ¦1> ƒ/“éõE5<« i½ÚÆÝKg«üê É-¾z€!võ@ñ0b2q`ä Þcg‹9M4kïàÜkz[®¾„šJûj6ªÚÛk¿ÍÓÙ×õ{ncó{püñF;ݬiÊž -1Y¥(@C…51rq (àÞCaVÅ] 7EäM5©f¡_E>©>·-uܨq4ù¼Ú1¼š"Óîy­9Å܃ 10 6®{é?ê=ÕÉ”í˜{Í ~]#Ž>\éö¢ÃS³Y~ñº=ÿŸÿÉêE{ó²ë7汘`ˆQuÂ(ÉÄQ‚zåCS"´ -ˆ¦|¼}ºMÏfýË󯉋ØF|\žUõÃØCYéýÈ®AFpþLŠGÈ\1ÀÃ*ƒa‘‰ÃõžŠ‡ô#{ÛÞk¹×<Ë©.'ÕoK/}#¼o:ÂVˆqÛY ¬œ¼ÞŸ7@XÁŸG3¦¬`ˆ%Á€ÈÄzO@M| Þ¶&õþ®IâÌúŸk œã/ÃŒA´°&eõ®Ì´v»Ð0ÇÌÍóת1ڽ̒ ƒuŸ á’0ÖÞG¹×<ꥆ<…á`:X‚Ú±÷)Îñ6#ÅžzùR…\£ 1 ( -™@06Üçæ{eDiÓÌY¾ª[±ý®?‰»ìŸå¦}BìÁú¶iŸ˜`›ö¹yÞ&'ÝO)çÃr±á6×粎H«ÚT¬Vᶇ£³'U6Ám\-AŽÒëØ!—#,ê;pf ‘T´˜ñ³óiÝySæ…³?³VŽRÌ’BšQäûß6BÀ¾(qŸ+¬ˆà¡’‰¶’Mæój°;œnfÇ_*?ˆöûMAß Ms):É AHÈEžF~3„ tâ—QîrG¬µ¹ÆÒÿψSͽíì»/Ó7tÖ\²]ß)&¨ó‘SÙ«¿yL4׈B6Ó®‘ÿî£A{endstream -endobj -850 0 obj << -/Type /Page -/Contents 851 0 R -/Resources 849 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 703 0 R -/Annots [ 853 0 R 854 0 R 855 0 R 856 0 R 857 0 R 858 0 R 859 0 R 860 0 R 861 0 R 862 0 R 863 0 R 864 0 R 865 0 R 866 0 R 867 0 R 868 0 R 869 0 R 870 0 R 871 0 R 872 0 R 873 0 R 874 0 R 875 0 R 876 0 R 877 0 R 878 0 R 879 0 R 880 0 R 881 0 R 882 0 R 886 0 R 887 0 R 888 0 R 889 0 R 890 0 R 891 0 R 892 0 R 893 0 R 894 0 R 895 0 R 896 0 R 897 0 R 898 0 R 899 0 R 900 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R 909 0 R 910 0 R ] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [499.2773 124.3237 511.2325 133.4295] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.6.2.16.15) >> +>> endobj +852 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [499.2773 112.292 511.2325 121.2483] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.6.2.16.16) >> >> endobj 853 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 758.4766 539.579 767.4329] +/Rect [499.2773 100.2604 511.2325 109.2166] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.20) >> +/A << /S /GoTo /D (subsubsection.6.2.16.17) >> >> endobj 854 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 746.3946 539.579 755.3509] +/Rect [499.2773 88.2287 511.2325 97.185] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.21) >> +/A << /S /GoTo /D (subsubsection.6.2.16.18) >> >> endobj 855 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 734.3125 539.579 743.2688] +/Rect [499.2773 76.197 511.2325 85.1533] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.22) >> +/A << /S /GoTo /D (subsection.6.2.17) >> >> endobj 856 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 722.2305 539.579 731.1868] +/Rect [499.2773 64.1653 511.2325 73.1216] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.23) >> +/A << /S /GoTo /D (subsection.6.2.18) >> >> endobj -857 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 710.1484 539.579 719.1047] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.24) >> +796 0 obj << +/D [794 0 R /XYZ 56.6929 794.5015 null] >> endobj -858 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 698.1661 539.579 707.1721] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.25) >> +793 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 859 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 685.9843 539.579 694.9406] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.26) >> ->> endobj -860 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 673.9023 539.579 682.8586] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.26.1) >> +/Length 3451 +/Filter /FlateDecode +>> +stream +xÚíKSGÇï| +ŽX8P®gWÕîa’qXH 8¼±¶£™tˆéÁóËŸ~«§»ªr˜êj½2°# †ÎΜüÿ:ëݰmêþeÛF*¬ÜÖVE™ÚŽ·èö…ûÝ›-Ö]³ç/ÚƒW½:ßúöµÐÛ–Ø‚ÛçÁ½ ¡Æ°íóÑÏ;ïNÎNÎÏv=ÿ~ëè<Ü:fT4wümëç_éöÈùÿ~‹aÚ¾uÿC ³–o·¤DI!üO®¶Î¶þn~»4M}% Q†ëÄ'á|Æ91V»è”%…p¿k>JA¸sÜ|w9— FŒ¡Òùh.›Íój6¯†³½á堮˫Yg#V“%•±Í™³)Çe=ßÝãŠî¼™ÆãÁtwOr½Cv÷¥øEZ{¿+ïH¬¸!§,fqM“éÅvûÍ)TÉÛíAÃu•Öï¿TÉ®ÅáUOÅ1‚zŒHM”¢<0Âé_ÁÈaù ¥¼®æÕ¤n2¨Gí7?Î¥Å> ½,øle³ 1VÔ@XHı€z,'Ya l# óéb6/G{ŸÊÏ)”!–›bC¡0’>|¡È­÷$Æç4›`ˆ5Ó´Ÿ˜D1¨÷H D˜‚Ebø%fsÙàJVJ‰âÑ”’ÿg}¹'L>ÝÙ0C &('S" &Ô{€©°ÖÐ<É/ÂÒæ"SØâëC§ŸÕ\d€B ÔL³^`A ¼ ®#.F&#-j#-Lê2M ÕVoª<Æ<å’³‰¢6ÙÙ3Œ¡(¤æý­E€„øi7ÌWÚF„Š/‚Ðæ‚£{:THk6,ÀÃʦe?0‰80dPïLI¢µûmQpbÝà@C˜â81ÿÓ°±”õ|×n?_—3—+ùÈ;,PK| +³† P" D ¨÷ˆ¢®¼á- Wƒ™CBPþ5!ñÅ9Ù„‹Oh6.Àà +¦U?.‰80\Pïg`[ÁEÜ­'ï®›¶£A‡¿”‘ ›Ï\6Àã*£‹~.q`\ Þ#ŽÍ]—p![.?׃q5ìz×#×Ùh¿?¹ª†UÓêH¥ž¬ì>1Ù²CLv˜xmúeOÄÉŽzwk„Ø.˜¹JíUw…€Ñ•Jðººj&Ï•ýê[GÝ…õ2d3 1Ơ̦ž%Æê=Ž{('ªP²¦ÿÊ8]é¶6¬M>¶_OËÙd1ÝefgXúŸ 'ËŒfw4?]–Ýg>ñCß)¾,Çn¨£Å㛤 ÉÖbzÃŒcz'âÀôF½‡¦DYJ¤EÔ{©¸Ø,­ì9ö,BÂrq€†+‚ 8¤â@pÀ½G´!’2ˆïpp€ï”¿Ïƒ«–†ò÷ë% ål&/BY8]ŽeЧÚ„ãÙ8C '¨(†S" 'Ô{ì·HE\úrÕ††ˆÚ+ù¶ý›2Rq jãÞ£ÚÍ+'ŒjËNí³ÉðSÙ%9þöÝ&Ñ‹¿x)ö ©íó‘­60ÄÔ†ùÆÔNÄ©zjëf²¦]·å—X +9¾vÒ~¨®ªùçVÛÛj~ÙNø»ÒÔ®“HýQêå¤Sb>R&™5XÄcëöáS– 0Ä€€’Øþ“Œ©80 Ö¼³ÄKiœðD*Ù.Ô7“GteÑO”ÃÅ4Pq0©gÕ¨œÚ£½yó·vÜ/_À`=âõû.óÕ¿7ÞËÓš×ÔTŠp× Í»³‚ËŽl3•²?–³PëùrêsÒ͹ýàÊäòwòe^%ÿ©ó Ï~ê€!öÔAA1Šq`4¡ÞMÍÉ,K=M©W[¸¡¶e’uåóàr:™ÌEVHB]?½»¬Ù ˜Î·D(-üÑr¾¨F©[×9”¦»ì™oòÿ_ˆõ¢f 1b!4¶¿L*ŒXÔ{˜òLNM@6nÝO.!)æ¸4ž¹a/¾n¬Ø<-íeGõM»x4©Û3Ì¢ϧ örå3ŸÍ0ĸ‚Êb\%âÀ¸B½G®¨C‰"påwÿ8 ›óÒ«”ºpw`¾ôÍzË%š†µó׋zØž†—ú94¶½Pù´gC 1¨ ¬T‰80¨Pï¾yuåÌUé™ògÙzO/Æî­VÅË4u˜Ó\` !ÌŠf0©8`Ö½§FA¼h´ÜT—ƒ ó]ÆØÎt²øpUÎ.]óÕ”£Þìt7¸ïP\Œt`X¶±Ü ËÄ]—É'G)Ò½„É„AÎÁd<ög2Þ·í³ËɸÄKù2¦É”Ú$g?HÁ {Œ¢€1k`à ~C3Î¥ ‚w¯F1ÝRÏrËýüoÝø¸žtS‰·“é'÷0ý£ý¿ËÉmûÍpà÷à·_šW×\´G»:=Yø;\Âmo»ãÅ?]ùfæµ±!'ÙJCLk˜sLíD˜Þ¨÷P)š®»T^pÞÕŠãzØ*ÖtàC.Ò=¸Ô+ý:¿ +XùJ'‹ñ‡fAö tÞCš²†PŒD¨÷À³„ÝûKLègýÔ ˆOíÁçú_Rø®¼ºv­”/ÍÆ½PòÙÎF b(A51”q`(­yOõÀ˜-HÁº#©û®’s¾³}]Ö£jXöÏ1³ûv¼ ÒóZ Çö/ÀÂÛ!9X÷šzœ˜‘DqÛå iAµvY~ª'·Wåè¢)©ÍÚ*·/®ì§'$7÷é†ÈÓ³"FL"ŒÔ{è~1͉”ÝyËý¶ûe›G¨­´¯¦UÙ¦þ®šÍ'ÓÏ«'¬CC|xrv§Ånׂ +Êž +>YÙ(C (†B" Ô{("%¢PžÞ‘7e]N}+ˆ|Z~ìZê°-ç¸þ¸Ü¾œ"+ì3YsÄ5P:æî¾`tv{Ð0ÆÝû7Ú0Ú¿öŸ +#u‹„týtÓ¦Üo§ð›"qüþ¦èžúÑÈ¿tÿŠç×£Ûwÿ¸¯¬Yµ×Ïx“·—Ñç1`ˆauB1I‚a‚ºDÄU1O‰h È«êÃU5¹˜®/?G0B+q¶¸¸(›—ïûÂ2¹Q^ËŒàü™”Ÿ¹l.€!ÆTå"Æê>–. cÝ™Éýöå]Mù8-[8í[å]ëáwCŒ»þª‡åôõÁ¬%ÂþÄ;^1Ÿ²l"€!F”%"Fê>Á¸½éHï”fWí‡ù‡ÓÁdžkùËå>Ðø¬fC 1h jŒö/µ¤Á AÝhšvFuç%÷Ûwû4Ì€×nN† P;ö?„yßv0¢Ø3)>U¹ ;„(†A" +„‚5ߩ٭‰¤-€¯šæ@ì¼ÔáÕo׃‹Ô”Ovg»iÂÇç"^žšîY½g›‰þÃÜñ^ØŸ¹ã0ù²UEoWi^-›QawFÕÅ“ª‘_Á1½NýNܧ,š!P#k=„5ÂÂrÜã–$÷§7ÿe,<~îïFÆ¿nÙ¼¬ÆôýÁ.A­‹œ6‰Is¯æƒ*dKîò"ùû\,Œendstream +endobj +858 0 obj << +/Type /Page +/Contents 859 0 R +/Resources 857 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 711 0 R +/Annots [ 861 0 R 862 0 R 863 0 R 864 0 R 865 0 R 866 0 R 867 0 R 868 0 R 869 0 R 870 0 R 871 0 R 872 0 R 873 0 R 874 0 R 875 0 R 876 0 R 877 0 R 878 0 R 879 0 R 880 0 R 881 0 R 882 0 R 883 0 R 884 0 R 885 0 R 886 0 R 887 0 R 888 0 R 889 0 R 890 0 R 891 0 R 892 0 R 896 0 R 897 0 R 898 0 R 899 0 R 900 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R 909 0 R 910 0 R 911 0 R 912 0 R 913 0 R 914 0 R 915 0 R 916 0 R 917 0 R 918 0 R ] >> endobj 861 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 661.9199 539.579 670.926] +/Rect [527.6238 758.4766 539.579 767.4329] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.26.2) >> +/A << /S /GoTo /D (subsection.6.2.19) >> >> endobj 862 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 649.7382 539.579 658.6945] +/Rect [527.6238 746.3946 539.579 755.3509] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.26.3) >> +/A << /S /GoTo /D (subsection.6.2.20) >> >> endobj 863 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 637.7558 539.579 646.6124] +/Rect [527.6238 734.3125 539.579 743.2688] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.26.4) >> +/A << /S /GoTo /D (subsection.6.2.21) >> >> endobj 864 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 625.5741 539.579 634.5304] +/Rect [527.6238 722.2305 539.579 731.1868] /Subtype /Link -/A << /S /GoTo /D (section.6.3) >> +/A << /S /GoTo /D (subsection.6.2.22) >> >> endobj 865 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 613.4921 539.579 622.4483] +/Rect [527.6238 710.1484 539.579 719.1047] /Subtype /Link -/A << /S /GoTo /D (subsection.6.3.1) >> +/A << /S /GoTo /D (subsection.6.2.23) >> >> endobj 866 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 601.41 539.579 610.3663] +/Rect [527.6238 698.1661 539.579 707.1721] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.1.1) >> +/A << /S /GoTo /D (subsection.6.2.24) >> >> endobj 867 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 589.328 539.579 598.2842] +/Rect [527.6238 686.084 539.579 694.9406] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.1.2) >> +/A << /S /GoTo /D (subsection.6.2.25) >> >> endobj 868 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 577.2459 539.579 586.2022] +/Rect [527.6238 674.002 539.579 683.008] /Subtype /Link -/A << /S /GoTo /D (subsection.6.3.2) >> +/A << /S /GoTo /D (subsection.6.2.26) >> >> endobj 869 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 565.1639 539.579 574.1201] +/Rect [527.6238 661.9199 539.579 670.926] /Subtype /Link -/A << /S /GoTo /D (subsection.6.3.3) >> +/A << /S /GoTo /D (subsubsection.6.2.26.1) >> >> endobj 870 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 553.0818 539.579 562.0381] +/Rect [527.6238 649.7382 539.579 658.6945] /Subtype /Link -/A << /S /GoTo /D (subsection.6.3.4) >> +/A << /S /GoTo /D (subsubsection.6.2.26.2) >> >> endobj 871 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 540.9998 539.579 550.1055] +/Rect [527.6238 637.6562 539.579 646.6124] /Subtype /Link -/A << /S /GoTo /D (subsection.6.3.5) >> +/A << /S /GoTo /D (subsubsection.6.2.26.3) >> >> endobj 872 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 528.9177 539.579 538.0235] +/Rect [527.6238 625.5741 539.579 634.5304] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.5.1) >> +/A << /S /GoTo /D (subsubsection.6.2.26.4) >> >> endobj 873 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 516.8357 539.579 525.9414] +/Rect [527.6238 613.4921 539.579 622.4483] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.5.2) >> +/A << /S /GoTo /D (section.6.3) >> >> endobj 874 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 504.7536 539.579 513.8594] +/Rect [527.6238 601.41 539.579 610.3663] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.5.3) >> +/A << /S /GoTo /D (subsection.6.3.1) >> >> endobj 875 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 492.6716 539.579 501.6279] +/Rect [527.6238 589.328 539.579 598.2842] /Subtype /Link -/A << /S /GoTo /D (subsection.6.3.6) >> +/A << /S /GoTo /D (subsubsection.6.3.1.1) >> >> endobj 876 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 480.5895 539.579 489.5458] +/Rect [527.6238 577.2459 539.579 586.2022] /Subtype /Link -/A << /S /GoTo /D (subsection.6.3.7) >> +/A << /S /GoTo /D (subsubsection.6.3.1.2) >> >> endobj 877 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 468.5075 539.579 477.4638] +/Rect [527.6238 565.1639 539.579 574.1201] /Subtype /Link -/A << /S /GoTo /D (section.6.4) >> +/A << /S /GoTo /D (subsection.6.3.2) >> >> endobj 878 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 456.4254 539.579 465.3817] +/Rect [527.6238 553.0818 539.579 562.1876] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.0.1) >> +/A << /S /GoTo /D (subsection.6.3.3) >> >> endobj 879 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 444.3434 539.579 453.2997] +/Rect [527.6238 540.9998 539.579 550.1055] /Subtype /Link -/A << /S /GoTo /D (subsection.6.4.1) >> +/A << /S /GoTo /D (subsection.6.3.4) >> >> endobj 880 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 432.2613 539.579 441.2176] +/Rect [527.6238 528.9177 539.579 537.874] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.1.1) >> +/A << /S /GoTo /D (subsection.6.3.5) >> >> endobj 881 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 420.1793 539.579 429.1356] +/Rect [527.6238 516.8357 539.579 525.792] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.1.2) >> +/A << /S /GoTo /D (subsubsection.6.3.5.1) >> >> endobj 882 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 408.0972 539.579 417.0535] +/Rect [527.6238 504.7536 539.579 513.7099] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.1.3) >> +/A << /S /GoTo /D (subsubsection.6.3.5.2) >> +>> endobj +883 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 492.6716 539.579 501.6279] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.6.3.5.3) >> +>> endobj +884 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 480.5895 539.579 489.5458] +/Subtype /Link +/A << /S /GoTo /D (subsection.6.3.6) >> +>> endobj +885 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 468.5075 539.579 477.4638] +/Subtype /Link +/A << /S /GoTo /D (subsection.6.3.7) >> >> endobj 886 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 396.0152 539.579 404.9715] +/Rect [527.6238 456.4254 539.579 465.3817] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.1.4) >> +/A << /S /GoTo /D (section.6.4) >> >> endobj 887 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 373.4431 539.579 382.2997] +/Rect [527.6238 444.3434 539.579 453.2997] /Subtype /Link -/A << /S /GoTo /D (chapter.7) >> +/A << /S /GoTo /D (subsubsection.6.4.0.1) >> >> endobj 888 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 361.3809 539.579 370.4867] +/Rect [527.6238 432.2613 539.579 441.2176] /Subtype /Link -/A << /S /GoTo /D (section.7.1) >> +/A << /S /GoTo /D (subsection.6.4.1) >> >> endobj 889 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 349.2989 539.579 358.2551] +/Rect [527.6238 420.1793 539.579 429.1356] /Subtype /Link -/A << /S /GoTo /D (section.7.2) >> +/A << /S /GoTo /D (subsubsection.6.4.1.1) >> >> endobj 890 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 337.2168 539.579 346.1731] +/Rect [527.6238 408.0972 539.579 417.0535] /Subtype /Link -/A << /S /GoTo /D (subsection.7.2.1) >> +/A << /S /GoTo /D (subsubsection.6.4.1.2) >> >> endobj 891 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 325.1348 539.579 334.091] +/Rect [527.6238 396.0152 539.579 404.9715] /Subtype /Link -/A << /S /GoTo /D (subsection.7.2.2) >> +/A << /S /GoTo /D (subsubsection.6.4.1.3) >> >> endobj 892 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 313.0527 539.579 322.009] +/Rect [527.6238 383.9331 539.579 392.8894] /Subtype /Link -/A << /S /GoTo /D (section.7.3) >> ->> endobj -893 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 290.4806 539.579 299.2128] -/Subtype /Link -/A << /S /GoTo /D (chapter.8) >> ->> endobj -894 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 278.4184 539.579 287.3747] -/Subtype /Link -/A << /S /GoTo /D (section.8.1) >> ->> endobj -895 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 266.3364 539.579 275.2927] -/Subtype /Link -/A << /S /GoTo /D (subsection.8.1.1) >> +/A << /S /GoTo /D (subsubsection.6.4.1.4) >> >> endobj 896 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 254.2544 539.579 263.2106] +/Rect [527.6238 371.8511 539.579 380.9568] /Subtype /Link -/A << /S /GoTo /D (section.8.2) >> +/A << /S /GoTo /D (subsubsection.6.4.1.5) >> >> endobj 897 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 242.1723 539.579 251.1286] +/Rect [527.6238 349.279 539.579 358.0111] /Subtype /Link -/A << /S /GoTo /D (section.8.3) >> +/A << /S /GoTo /D (chapter.7) >> >> endobj 898 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 219.6002 539.579 228.3323] +/Rect [527.6238 337.2168 539.579 346.1731] /Subtype /Link -/A << /S /GoTo /D (appendix.A) >> +/A << /S /GoTo /D (section.7.1) >> >> endobj 899 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 207.538 539.579 216.4943] +/Rect [527.6238 325.1348 539.579 334.2405] /Subtype /Link -/A << /S /GoTo /D (section.A.1) >> +/A << /S /GoTo /D (section.7.2) >> >> endobj 900 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 195.456 539.579 204.4123] +/Rect [527.6238 313.0527 539.579 322.1585] /Subtype /Link -/A << /S /GoTo /D (subsection.A.1.1) >> +/A << /S /GoTo /D (subsection.7.2.1) >> >> endobj 901 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 183.3739 539.579 192.3302] +/Rect [527.6238 300.9707 539.579 310.0764] /Subtype /Link -/A << /S /GoTo /D (section.A.2) >> +/A << /S /GoTo /D (subsection.7.2.2) >> >> endobj 902 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 171.2919 539.579 180.2482] +/Rect [527.6238 288.8886 539.579 297.9944] /Subtype /Link -/A << /S /GoTo /D (subsection.A.2.1) >> +/A << /S /GoTo /D (section.7.3) >> >> endobj 903 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 159.2098 539.579 168.1661] +/Rect [527.6238 266.3165 539.579 275.0487] /Subtype /Link -/A << /S /GoTo /D (section.A.3) >> +/A << /S /GoTo /D (chapter.8) >> >> endobj 904 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 147.1278 539.579 156.0841] +/Rect [527.6238 254.2544 539.579 263.2106] /Subtype /Link -/A << /S /GoTo /D (subsection.A.3.1) >> +/A << /S /GoTo /D (section.8.1) >> >> endobj 905 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 135.0457 539.579 144.1515] +/Rect [527.6238 242.1723 539.579 251.1286] /Subtype /Link -/A << /S /GoTo /D (subsection.A.3.2) >> +/A << /S /GoTo /D (subsection.8.1.1) >> >> endobj 906 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 122.9637 539.579 132.0694] +/Rect [527.6238 230.0903 539.579 239.0465] /Subtype /Link -/A << /S /GoTo /D (subsection.A.3.3) >> +/A << /S /GoTo /D (section.8.2) >> >> endobj 907 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 100.3916 539.579 109.2482] +/Rect [527.6238 218.0082 539.579 226.9645] /Subtype /Link -/A << /S /GoTo /D (appendix.B) >> +/A << /S /GoTo /D (section.8.3) >> >> endobj 908 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 88.3294 539.579 97.4352] +/Rect [527.6238 195.4361 539.579 204.1683] /Subtype /Link -/A << /S /GoTo /D (section.B.1) >> +/A << /S /GoTo /D (appendix.A) >> >> endobj 909 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 76.2474 539.579 85.3531] +/Rect [527.6238 183.3739 539.579 192.3302] /Subtype /Link -/A << /S /GoTo /D (section.B.2) >> +/A << /S /GoTo /D (section.A.1) >> >> endobj 910 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 64.1653 539.579 73.2711] +/Rect [527.6238 171.2919 539.579 180.2482] /Subtype /Link -/A << /S /GoTo /D (section.B.3) >> +/A << /S /GoTo /D (subsection.A.1.1) >> >> endobj -852 0 obj << -/D [850 0 R /XYZ 85.0394 794.5015 null] +911 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [522.6425 159.2098 539.579 168.3156] +/Subtype /Link +/A << /S /GoTo /D (section.A.2) >> >> endobj -849 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F39 885 0 R >> -/ProcSet [ /PDF /Text ] +912 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [522.6425 147.1278 539.579 156.2335] +/Subtype /Link +/A << /S /GoTo /D (subsection.A.2.1) >> >> endobj 913 0 obj << -/Length 762 -/Filter /FlateDecode ->> -stream -xÚíÙKOÜ0à{~…»‡L=~Ï• -*q jÉ q »a[Á†–mUµ¿¾NˆƒaWá!$X¡aã±ÇžO–qÿƒL0$ˆYR 9j¶Xœ­ü½ömÊШŒ[íUÅ»iaXuÎ”Ö t×™î²jy2{ÿñ¨Ú?ªŽç§Õa±_ ½Æ##—m—?Š“SΖ>ƒ$§Ùoÿ$l](-A+)Ã7—Åqñiè0ºÛ…&g‚„4"1!£©X#ON“¿ð·Ú™ìš—$i¶l6›zQ^ÔίçèfWë˳/õå¼tœf0/5ç¯å—¢'˜Ñ½Ê+òNÈ/ê°º[¥º^±›‹ÏQñ†¸2Ü.Þvÿmõq‹`ÐJ$g';ü`GY0ÖboGß·³ª¿¾J¿21/§)¬÷dMQ`NS\OD9®)‘HNSvøA“Ô`R¯ÉÜÑ´ù¶jþ^5uëIî =RXêÉ¢À¤¸”ˆzR"‘¤ìð$!ÁãzHöRs¶®—åâk½¸X\5çóÒh±ô`Aa' Šs‚â"ºqA‰Dr‚²Ã‚Á!š^ÛÔoEz·=\PXãÉ‚¢Àœ ¸†ˆ4.(‘HNPvø ÈÓFõ‚(äÑô–ŽDÏGë?†Lf„Ý©1 -1*,•HFX~øA˜³@Ãr¿¨-±Í¯ï˳Ÿ~wÒVíx='¯P€É¼¢À¯¸À(Ô8¯D"9^Ùá^V)žíü£eÇëºY.üº·¾½€·P‘ÉÞ¢Àœ·¸â(Æ\©DrÞ²ÃÞŒ"žþ°ÛMß(ŒÚ -„ª¢mÔR„î(ßµ¼Ó«Áö”gû–;£Oê0Tj²Ã(0ç0–€büà–J$ç0;üàP àR‡‡G”·û^ÙbëÞiI”»=îiQ…eŸŒ* -Ì¡ŠËŠrüEi*‘-TËøÒ Ã…M½‹÷ÒÿæÿöÊ‚tN¤§+²’˜ÔÐöÕNÖŒNµoeþwã¹endstream -endobj -912 0 obj << -/Type /Page -/Contents 913 0 R -/Resources 911 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 703 0 R -/Annots [ 915 0 R 916 0 R 917 0 R 918 0 R 919 0 R 920 0 R 921 0 R 922 0 R 926 0 R 927 0 R ] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [522.6425 135.0457 539.579 144.1515] +/Subtype /Link +/A << /S /GoTo /D (section.A.3) >> +>> endobj +914 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [522.6425 122.9637 539.579 132.0694] +/Subtype /Link +/A << /S /GoTo /D (subsection.A.3.1) >> >> endobj 915 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 758.5763 511.2325 767.5824] +/Rect [522.6425 110.8816 539.579 119.9874] /Subtype /Link -/A << /S /GoTo /D (section.B.4) >> +/A << /S /GoTo /D (subsection.A.3.2) >> >> endobj 916 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 746.5215 511.2325 755.6272] +/Rect [522.6425 98.7996 539.579 107.9053] /Subtype /Link -/A << /S /GoTo /D (section.B.5) >> +/A << /S /GoTo /D (subsection.A.3.3) >> >> endobj 917 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 734.5663 511.2325 743.672] +/Rect [522.6425 76.2275 539.579 85.0841] /Subtype /Link -/A << /S /GoTo /D (section.B.6) >> +/A << /S /GoTo /D (appendix.B) >> >> endobj 918 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 722.6111 511.2325 731.7169] +/Rect [522.6425 64.1653 539.579 73.2711] /Subtype /Link -/A << /S /GoTo /D (section.B.7) >> +/A << /S /GoTo /D (section.B.1) >> >> endobj -919 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 710.656 511.2325 719.7617] -/Subtype /Link -/A << /S /GoTo /D (section.B.8) >> +860 0 obj << +/D [858 0 R /XYZ 85.0394 794.5015 null] >> endobj -920 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 698.8005 511.2325 707.8065] -/Subtype /Link -/A << /S /GoTo /D (section.B.9) >> +857 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 921 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 686.8453 511.2325 695.8514] -/Subtype /Link -/A << /S /GoTo /D (section.B.10) >> +/Length 844 +/Filter /FlateDecode +>> +stream +xÚíÙOOÛ0ð{>EŽí!žŸÿûÊ“80mô†8°&” Ún”iÚ>ýœ66¯ÔyR ì!”@ýìg¿ŸÒ8’‡(µaÆ _Z¯˜æ Ëù²àå"|ö©€®MU¸Õɬøp&mé™7”³ÛRiÍ„ÞvæwÊY}5ùøùbvz1»œ^Ï΋ÓYê \¶]þ,®®yY‡ΠΤwºüþà ¼å²PZ2­¤Œÿy(.‹/©Côé64;àLH#2SMÅ3Ò„ä´'á£v&'LL+/ýän½yšVÚŠ ÎÇÃö ¼?Zg/°(hùP‡Tƒê>.ÊÝÉWTïWáÀÃzö߀¨€r‰PÜÈá7e™±:nrÇ­^m6ͼª7·Sp“õò¾ù3­¤s£¦W3Š =˜ +¤áBˆ~F™D(Fäð‰‘ÔÌ +ð#µÇ(à‰Žn¾5ÓÊq?Ú`'®î`;(²ƒ« ûíd¡ìÃ';B2kŒëìè—vÍ*¬¯Òã÷Ú‘4Åõ¬ Ršp=t¿¦L"”&rø¤ €9Ói2{š6ß«¿ëUÓz’#¤·BŠK= +¤ áRØ~H™D(Häð’ñž9mTÉî ­n–M]Íïšùý|½ºVF‹QÐk¥5*‚öjzå!ÑÃ'AÎ2Ï!nåÜ îR¤ÇkÐëÅ5,R‚p AôßVç¡‘Ã'AV3¯LÜy$(ÜD{=îÿßÿŸj0X +¤„áƒPýÂ2‰PÂÈá“0#™÷ySœqÇãîo÷ìÙÔVæAµC´ZŠl{+¿m¹×«vÃi»–£Ñ£:Œ•ìR±Ä[&Ê!9|r(\À§ãæäóu¯j±mŸiIã5â²F…)T¸¬ ‰{µL"¨ÒëÃJ{ѾšT¹7ˆá˜×Z¼ý}åókUe™tNä§+gÞJ_JÍÚ¾ÚÉšÞ©vPæÿ¾ªË“endstream +endobj +920 0 obj << +/Type /Page +/Contents 921 0 R +/Resources 919 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 711 0 R +/Annots [ 923 0 R 924 0 R 925 0 R 926 0 R 927 0 R 928 0 R 929 0 R 930 0 R 931 0 R 932 0 R 936 0 R 937 0 R ] >> endobj -922 0 obj << +923 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 674.7905 511.2325 683.8962] +/Rect [494.296 758.4766 511.2325 767.5824] /Subtype /Link -/A << /S /GoTo /D (section.B.11) >> +/A << /S /GoTo /D (section.B.2) >> +>> endobj +924 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 746.6211 511.2325 755.6272] +/Subtype /Link +/A << /S /GoTo /D (section.B.3) >> +>> endobj +925 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 734.5663 511.2325 743.672] +/Subtype /Link +/A << /S /GoTo /D (section.B.4) >> >> endobj 926 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 662.8353 511.2325 671.941] +/Rect [494.296 722.6111 511.2325 731.7169] /Subtype /Link -/A << /S /GoTo /D (section.B.12) >> +/A << /S /GoTo /D (section.B.5) >> >> endobj 927 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 710.7556 511.2325 719.7617] +/Subtype /Link +/A << /S /GoTo /D (section.B.6) >> +>> endobj +928 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 698.8005 511.2325 707.8065] +/Subtype /Link +/A << /S /GoTo /D (section.B.7) >> +>> endobj +929 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 686.8453 511.2325 695.8514] +/Subtype /Link +/A << /S /GoTo /D (section.B.8) >> +>> endobj +930 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 674.8901 511.2325 683.8962] +/Subtype /Link +/A << /S /GoTo /D (section.B.9) >> +>> endobj +931 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 662.935 511.2325 671.941] +/Subtype /Link +/A << /S /GoTo /D (section.B.10) >> +>> endobj +932 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 650.8801 511.2325 659.9859] /Subtype /Link +/A << /S /GoTo /D (section.B.11) >> +>> endobj +936 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 638.925 511.2325 648.0307] +/Subtype /Link +/A << /S /GoTo /D (section.B.12) >> +>> endobj +937 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 626.9698 511.2325 636.0755] +/Subtype /Link /A << /S /GoTo /D (section.B.13) >> >> endobj -914 0 obj << -/D [912 0 R /XYZ 56.6929 794.5015 null] +922 0 obj << +/D [920 0 R /XYZ 56.6929 794.5015 null] >> endobj -911 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R >> +919 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -930 0 obj << -/Length 2197 +940 0 obj << +/Length 2175 /Filter /FlateDecode >> stream -xÚÝYÝã¶÷_áG-pfù)‘y¼»¦¸ ¸¢Ý òæA+qmádÉÑÇnœ¿¾C)˶|wé-РX`M†äpæ7¿ÚlMá­µ"T¹ÎŒ$Š2µ.ö+ºÞ»¿­XБJ%…€‡…·%4QšgëÍ|‘·«¿|ÏÙšS’¦\­ž¦½ÒL#¤Y?”?'ïvùa°Ý݆+š°»_~Ài’d:cn…-É Õ~‡fèÚr,†ªm‚ºXbRžFí æ‚¹Nûagaiºi¶kì€OïÛ}^58þ˜ïƒÎý±ìÇÿ¦Š¾ÿxÌ ²¤h›¾ê‡_·Oø9Äõûc3ä¿ad[TOÇ Íö»XÅ6C5T(Í’êŽ% Ý$8£;cÄ(Å£Âa§‰;ˆà,ÉñqWÙ.ïî˜NŠ]Uä5J÷yÓ€›3™¼Ðh{ÓÝéd¬Ýæn‘±·%ÊŸÚ¥­í6ªfö‡]ÛU˜yDIûlƒ®?\Ø!oÂJa+Nò>;ó'ªö‡ÚîÁ¹ë†ƒ¡Ã.wáÊT’Ø×õåûüÐã(ºT¼ÏA4‹³›X–Þ¶ïmOÀ-ˆ*ª–ù£ZÕÇ•+° jœ ܳ‡ˆ[·~­v< ¢·›@ÒUãàQKñpR·ùcî­Š˜g’™ò€bI Obž!£”&÷E{°¸‚|¾o‹Ñyn9¸&ifÎ’&om÷ ‚êýiÎRƒÆtù)I¨O‡·>¾ùo§ˆõ¨‘ãG'J2‹&½í /£OüÓãö\•6¼ÏW« ÚGØ lÇ0sÖ+õp®Õ”8(0¶^Q† ÌfNÎ]8òMa|üÒvC5îñÙyüÃý»àp8÷ã\ÙChbð£oŸ†—™)49äŧ|ÐéN/rŒór_5®ùÐvDobô |Ž©ú…M#öÂ1=½ŒÚEÛ…¤;´M¦ûüüÌ)Húu‰ÀC"ü£ÛæMõû‘“M'“¿>3>8 -¥ŽrÜ\AÕ„ 78Y˜ÙdÍHÊ%¬áƒh±ùùla+°_¥™ê@0ˆF(ažsý®7 °t2ÏRN†, -ôœA)*ìaˆÔqf§†dJfKÖñ›Öñ  RyEÃBÛé kÑFdœ(&ø9˜Q÷×±ÂÁÄ S¬4MƒÙ Ï 0Bš1ÉsÞUíæÙæk¿d¹äÄjž°8ùÚ‚§D -}å7A,û+£c”ú…%%”Æ8yÿiU ¢¿^OI¢ LQ¦=úP -F”Qò܇‡àðYÔ

    ÑÚШ€<øÈÌ; 3š0ןW±9ùºtKD8h¬o ՟⻩Üb’Âvƒ/µî¡=¸Ó/3B -½´HÙ5#¤‰ºÁFˆ%FH#U¥362(¨«ínx±î  ªˆàF.ÑDßÖÏØºÒ¥¡5ɸm *Þ¹ À.ë2ø°¤òŠƒÝ„t)ø0dY$ƒS™Ì®“ Dyغ -+úF…ÓŸ°3±|;•>cÊCºÍ–âùÚfÛbJù©Pì&ÀD1"”¿³Œir܈rLLÊÂZô2﮽d2¢…WN‚©Ù’“àǦ 9kÃ~¶¡ï?¢þBTBoë‘ç -hÇqÕR®°„ë%KôMK¢á³´ýP>ÇG¸²ìÚÖçâMÎiªÏñ¶³õÁqØÚ_‘ĶV&myœ³žŒ|ÖB‚¸ -ä8'&éˆÉK{ h ,$_ÆœQ“SÛ”•«ü ‰—¦áöŒª/»ÀKÒ;2b²îhOcãJx=Ã%úú8­3sîY»ûƹE%ýèöqï?‹Ÿ"\Lèx¬ëªÝvùaw\ª~‚}‚’oa`a讀ì|‹ã ̬;ºlô]:‰©âˆX ý+OD0ˆ·7öw—L†p.õy2aÃýu¦&ôåÏŽvÛ&t•?öñfW5ßÖqbçž:Nÿø:köE¯ w šlmãÁ‡JÇF¯7®ŸÌÿÎYµúëÃôÕI¡UÔॠM¡¡+ö«_W?ÿB×劮XQ"ŒVëx „Ã×û•0¤JGI½º_ýó¿œí˜5 7-ÀyÖ -Ãêó¥6ñLæÒ‰j6}ugA˜°Œ„«‡‘á¶ã[§pS‰•ïÊm‚+zz=ßâÛ¬ž–ü‚ÙÚFérúÌìŸî8MnÂ¥Žõõ!”ëS¥^ñ’ÃÕƒBÖoÂÜÿœ8ð„øœ)θ 'DnŒ8}·)áäÚL‰l“»VXÂ=|عoBÝJ÷zÊk; xòã¿þþ5wm?Ì4×êXÝ.¾9¨H1ºAß_€Ã¿±/¶ÛŸ¿ -}ëmDÏNùmŽ›!úÒsàž%DÏ<÷}õ›ãØè÷¥*‡Ým𾚽"ðÆ@¿"RC¤Té—ÀË¡‚Gˆ §²¬ÒÅšw?ƒŸÙF¯Æˆ—ÆCU_ÂÏÜø€~òò÷m]Þ†Ò«™þ %¸SPÃÌ—D)´:°Åé[ ×–D6‡Ïh¶ÅkaèÒê4·ú -B·€ójæþYpÃÝ]KÝ‚ˆŒËùÏ~W?ÿqOÁ@¨0_k½øaüéo#q¿$.¢G@ -Nå:(¹(dWn¿6žVŠ»ýñG¬endstream +xÚÝYÝoã6÷_áGXëø%‘ìãî¶ÅÅî’¢½>(c kK®>’ºý 9C[ŠåÍö6ÀE€ˆ¤†äpæ7¿Ê|Éà/M–2iÕR[•fŒgËõ~Á–x÷ý‚“ŒÊdš))¡3óv•I“fFèåj¼ÈÛ»Å?¾|)Xšç"[Þ=œöʵI­TvyWþ’¼Û‡Þµ7+‘±„ßüz÷NS©6šûi ¶ÈRm™ >Ô}۔ú¯ššÄåÒ¦6y”Ö0ÔõÒw[K›ÜOsmízì½oöEUcûc±'™Ûc×»=¶ÿÃ2öþã-<¸Ðɺ©»ªë;|Ý<à³ëwǺ/~§Á†Æn]=ŸIÖ°ß³U\ÝW}…£:©nxRcÓO‚3úSqžÚ,Ñt)Xâ"O +ìn+×í 7Éz[­‹Žî‹º3k•¼iPÿ¦½1ɰó›ûE†Î•8þдØ(ÝÎmоª7´ÏÐo›¶êAÍ#Ž4ŽdÃáh‡¢¦•h+F +žœˆ‡UûÃÎíÁEðëJ€¢ý¶ðîÒYR¬û¡ØíŽ8¾/¶¢)A$؆F~öË2XÂuëRPÂÈ¼Š¢eÑ(Vuqå +4¨joßñË`wÖj†Ž‚÷f|SHÚê~èÃ"Ùœ?ü¨ßü¾ZEÌs•J• B±b©È%bž§BÎKn×ÍÁá +<ð|߬o¹ù`&͵KÞºö85ØÓNBƒÅp€ñs°o?||OñoOëP¢ÀG'HM‘Œε"~4à*ÎðRÃþÞÑ<.Xl5ga‚¢È$*x–[8_p$Œ—Ñ&¡w@¿=V¥£÷`ùjͪ…öv0PÜ7MĘ B]KÕ%6ÖèÛ ¨È)£™'ãÎù¦C7¾~iÚ¾öØ÷ÿpûŽ ÞüØSv¤K,>ºæ¡©Â’C±þTl¨ƒF÷r‘ã ]”ûªöp-ú¦E 5Ð3ð9B¦êf6Ø£cz"´×MKAwhê’¦‡øüÌ)ÒüËAP ü³ÝuõÇÉ#gÎ*yd|8QNE|ô'K;šl §e<‡E¦ à3{)éÓ +†A8Bs]ÜÖá®—0F4•Ò`„LC‹ÖîÐGî˜('˜NY.ÔœvâEí BÖÀ^Q1òc3 a2ZI-RÃa‹ šQö·¡ÂF¤- |Щ¦®1|¡O$ˆieòX´U3ÐkòiLaÕýeÕ¦¤jŠóGϾMM¥åO]¼ÞUõW–¡ŒŽsÏegè>Q¬ƒ¿Ÿ܈Aâ–l\À‡BÇzï8;Qýo¼V‹oïNßolu …gêF)üǛ߿üÊ–å‚-X°TZ“-Ÿ ÃÀšP)îJB“e&Žì·‹ý³¢£Báª8ÁZÔŒèž.µŠgZqNÌðÓ©)šàC*XFA޶Ю<¡|¢ëJÌ~f“‡s³oñuZŸ–|Am ¥£‚ÊgªöÏ7‚%WáÒõÇÝå!2‘§*ϲW<„Pf1ŸôiîÿNB¦\ü'Îg\…“€¢ÝZyþÀ)gá$5P +²MáÓŽ‚Ëx¿õŸC ®•’p¹gbçN"ùéß?¾AÉmÓõ#IàµPÏ|>Ø‘¢wI>Ü‚éž_»'‚€k÷ÓWT¾^Gôè”_g¸¢Ÿ[Ì3‡è‘徫~÷›ý>Ue¿½ÞWÓ÷/ÞèèWäB¡Êò—ÀËeʤˆëÏiX¥9ï0|?£^Ÿ+¯Ì,~ÆÊôsPh¾mvåu(½šêk(Y2ËíKHbpMÓ°Åùˆ/K" ýç@4Úâµ0ô\ë+4ÖúB×€ójêþUp#àŽÍ4‡Ú #µPãßþ.~‚ýíÔ7ÆÌþPÿƒÛZêNœE„”‚©% y/è ³ÇŸÏ+ÅÝþ üLtendstream endobj -929 0 obj << +939 0 obj << /Type /Page -/Contents 930 0 R -/Resources 928 0 R +/Contents 940 0 R +/Resources 938 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 941 0 R +/Parent 951 0 R >> endobj -931 0 obj << -/D [929 0 R /XYZ 85.0394 794.5015 null] +941 0 obj << +/D [939 0 R /XYZ 85.0394 794.5015 null] >> endobj 6 0 obj << -/D [929 0 R /XYZ 85.0394 769.5949 null] +/D [939 0 R /XYZ 85.0394 769.5949 null] >> endobj -932 0 obj << -/D [929 0 R /XYZ 85.0394 582.8476 null] +942 0 obj << +/D [939 0 R /XYZ 85.0394 582.8476 null] >> endobj 10 0 obj << -/D [929 0 R /XYZ 85.0394 512.9824 null] +/D [939 0 R /XYZ 85.0394 512.9824 null] >> endobj -933 0 obj << -/D [929 0 R /XYZ 85.0394 474.7837 null] +943 0 obj << +/D [939 0 R /XYZ 85.0394 474.7837 null] >> endobj 14 0 obj << -/D [929 0 R /XYZ 85.0394 399.5462 null] ->> endobj -934 0 obj << -/D [929 0 R /XYZ 85.0394 363.8828 null] ->> endobj -18 0 obj << -/D [929 0 R /XYZ 85.0394 223.0066 null] ->> endobj -935 0 obj << -/D [929 0 R /XYZ 85.0394 190.9009 null] ->> endobj -936 0 obj << -/D [929 0 R /XYZ 85.0394 170.4169 null] ->> endobj -937 0 obj << -/D [929 0 R /XYZ 85.0394 158.4617 null] ->> endobj -928 0 obj << -/Font << /F21 702 0 R /F23 726 0 R /F39 885 0 R /F41 925 0 R /F48 940 0 R >> -/ProcSet [ /PDF /Text ] +/D [939 0 R /XYZ 85.0394 399.5462 null] >> endobj 944 0 obj << +/D [939 0 R /XYZ 85.0394 363.8828 null] +>> endobj +18 0 obj << +/D [939 0 R /XYZ 85.0394 223.0066 null] +>> endobj +945 0 obj << +/D [939 0 R /XYZ 85.0394 190.9009 null] +>> endobj +946 0 obj << +/D [939 0 R /XYZ 85.0394 170.4169 null] +>> endobj +947 0 obj << +/D [939 0 R /XYZ 85.0394 158.4617 null] +>> endobj +938 0 obj << +/Font << /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F48 950 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +954 0 obj << /Length 3187 /Filter /FlateDecode >> @@ -2690,66 +2703,66 @@ W ½þ`J9ÿdÑÆÇVþ¢Ì!ûȨÀÌBÖ?e‘úñcΗ`ùX¹žŸš¦-zXæç-@fØ:\a½ã¶Gî7žÛù¨ß•=Éȧv)½»@2wl(kz+0h´zx6éqŸSS> u»žQ¶àðI¼þ˜CÍ-í‚f¡œoMoqÓâ›äÚµ|Éï…2VDÓWÜãÒ|ññþkÿ=êø_bP*˜4Õ/øÃ[Df@ ž!þêóy©òendstream endobj -943 0 obj << +953 0 obj << /Type /Page -/Contents 944 0 R -/Resources 942 0 R +/Contents 954 0 R +/Resources 952 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 941 0 R -/Annots [ 951 0 R 952 0 R ] +/Parent 951 0 R +/Annots [ 961 0 R 962 0 R ] >> endobj -951 0 obj << +961 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [272.8897 207.1951 329.1084 219.2548] /Subtype /Link /A << /S /GoTo /D (types_of_resource_records_and_when_to_use_them) >> >> endobj -952 0 obj << +962 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [190.6691 179.6723 249.6573 189.0819] /Subtype /Link /A << /S /GoTo /D (rfcs) >> >> endobj -945 0 obj << -/D [943 0 R /XYZ 56.6929 794.5015 null] +955 0 obj << +/D [953 0 R /XYZ 56.6929 794.5015 null] >> endobj -946 0 obj << -/D [943 0 R /XYZ 56.6929 756.8229 null] +956 0 obj << +/D [953 0 R /XYZ 56.6929 756.8229 null] >> endobj -947 0 obj << -/D [943 0 R /XYZ 56.6929 744.8677 null] +957 0 obj << +/D [953 0 R /XYZ 56.6929 744.8677 null] >> endobj 22 0 obj << -/D [943 0 R /XYZ 56.6929 651.295 null] ->> endobj -948 0 obj << -/D [943 0 R /XYZ 56.6929 612.4036 null] ->> endobj -26 0 obj << -/D [943 0 R /XYZ 56.6929 555.4285 null] ->> endobj -949 0 obj << -/D [943 0 R /XYZ 56.6929 530.6703 null] ->> endobj -30 0 obj << -/D [943 0 R /XYZ 56.6929 416.0112 null] ->> endobj -950 0 obj << -/D [943 0 R /XYZ 56.6929 391.253 null] ->> endobj -34 0 obj << -/D [943 0 R /XYZ 56.6929 164.815 null] ->> endobj -953 0 obj << -/D [943 0 R /XYZ 56.6929 137.4068 null] ->> endobj -942 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F39 885 0 R /F41 925 0 R /F21 702 0 R >> -/ProcSet [ /PDF /Text ] +/D [953 0 R /XYZ 56.6929 651.295 null] >> endobj 958 0 obj << +/D [953 0 R /XYZ 56.6929 612.4036 null] +>> endobj +26 0 obj << +/D [953 0 R /XYZ 56.6929 555.4285 null] +>> endobj +959 0 obj << +/D [953 0 R /XYZ 56.6929 530.6703 null] +>> endobj +30 0 obj << +/D [953 0 R /XYZ 56.6929 416.0112 null] +>> endobj +960 0 obj << +/D [953 0 R /XYZ 56.6929 391.253 null] +>> endobj +34 0 obj << +/D [953 0 R /XYZ 56.6929 164.815 null] +>> endobj +963 0 obj << +/D [953 0 R /XYZ 56.6929 137.4068 null] +>> endobj +952 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F21 710 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +968 0 obj << /Length 3415 /Filter /FlateDecode >> @@ -2768,60 +2781,60 @@ J$ ?6`³> endobj -961 0 obj << +971 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [519.8432 463.1122 539.579 475.1718] /Subtype /Link /A << /S /GoTo /D (diagnostic_tools) >> >> endobj -962 0 obj << +972 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [84.0431 451.8246 133.308 463.2167] /Subtype /Link /A << /S /GoTo /D (diagnostic_tools) >> >> endobj -959 0 obj << -/D [957 0 R /XYZ 85.0394 794.5015 null] +969 0 obj << +/D [967 0 R /XYZ 85.0394 794.5015 null] >> endobj 38 0 obj << -/D [957 0 R /XYZ 85.0394 570.5252 null] +/D [967 0 R /XYZ 85.0394 570.5252 null] >> endobj -960 0 obj << -/D [957 0 R /XYZ 85.0394 541.3751 null] +970 0 obj << +/D [967 0 R /XYZ 85.0394 541.3751 null] >> endobj 42 0 obj << -/D [957 0 R /XYZ 85.0394 434.1868 null] +/D [967 0 R /XYZ 85.0394 434.1868 null] >> endobj -963 0 obj << -/D [957 0 R /XYZ 85.0394 406.5769 null] +973 0 obj << +/D [967 0 R /XYZ 85.0394 406.5769 null] >> endobj 46 0 obj << -/D [957 0 R /XYZ 85.0394 301.1559 null] +/D [967 0 R /XYZ 85.0394 301.1559 null] >> endobj -964 0 obj << -/D [957 0 R /XYZ 85.0394 276.6843 null] +974 0 obj << +/D [967 0 R /XYZ 85.0394 276.6843 null] >> endobj 50 0 obj << -/D [957 0 R /XYZ 85.0394 200.1512 null] +/D [967 0 R /XYZ 85.0394 200.1512 null] >> endobj -965 0 obj << -/D [957 0 R /XYZ 85.0394 175.6796 null] +975 0 obj << +/D [967 0 R /XYZ 85.0394 175.6796 null] >> endobj -956 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F39 885 0 R /F41 925 0 R /F21 702 0 R >> +966 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F21 710 0 R >> /ProcSet [ /PDF /Text ] >> endobj -969 0 obj << +979 0 obj << /Length 2458 /Filter /FlateDecode >> @@ -2834,39 +2847,39 @@ Y K³ËZ! U¢|õ },ä-T\Èiù)¶†—™M¬)¢Ût‡KBaŒÂ´˜ŸS7`\&Ö^±¡‰&&Ú¡Ù’å^_ˆ¼=¢ µŽ¸Š©/@ð$.˜Á²n 0ãf—«{/Qc‡çöùޱÉñ¡ÚÖ=¯tñÍX>Ëî)z /{0„öG1Y C*5÷Hò|ÅjAÀùеa0ÂXë–KƯ,†•p=†”Fä9‰ñléÜî|uÚ$1Sû52Ñ”*?õVù8ijÞC@üû 3ß‚ü¹=á¬zÛ”SsÀÖ'¨‹«ƒNøÒÕæOwíi¸þáñé=|ë5ë~ÒÅÀªƒtk¨€ƒ6¼Ý ]´Né!)½=Á˜*5$ÐyúÿPŠrla±Ö¯æj§›íb5% îÖfÏX.]äü©pšwzc 4vÖ׳Ü]Õ°»“™2_$¡OæÖ#ç’_åpÚÐذö4uîëÜzû.—H38Bn«‚'äô°…ïúýuoõÖV1J¹–cݽŒñ=Ãm}„R/"$•§Ž4÷•>‚tùª[«_Ð@âIŠý[†a{ÓШk/O \¯\iܽŒ‹µyîbm^`8O_Š­j˜=:9M®<uH&)!Íf¹² E ¤òïFÜÙ Ív¤Yžú*Ï]‚ÍŽb7KFY!ëö4¹é>a±¬z Ù\˜"T‘2»Œ·SCNE˜"¿ÄTz[Õ•=L A05h1„u”»œdkM9C€/¥x$ue¿r~EÇðyΟ¯Ž&áèBg Ú½.ßóh¦·\Q&ɧw%±»Üéu©®Œ¡™ÐÙ^ôÃo)Ó$TK …3¸U£©UPk\‘;cpËÜÓ…à8~*”©DGÊR³)=„ò6MÄU$ä¨U“—¿pf¥ÉÖ\:âç¥Z¾þ®Úé=YO½å¼zxã¿H_ø‡ÈÂ?!á˜èþïÿ]¦¿Ÿ¢4PY&—ÿRÁá("Ì”K©á çþš[Öÿ xK:óendstream endobj -968 0 obj << +978 0 obj << /Type /Page -/Contents 969 0 R -/Resources 967 0 R +/Contents 979 0 R +/Resources 977 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 941 0 R +/Parent 951 0 R >> endobj -970 0 obj << -/D [968 0 R /XYZ 56.6929 794.5015 null] +980 0 obj << +/D [978 0 R /XYZ 56.6929 794.5015 null] >> endobj 54 0 obj << -/D [968 0 R /XYZ 56.6929 717.7272 null] +/D [978 0 R /XYZ 56.6929 717.7272 null] >> endobj -971 0 obj << -/D [968 0 R /XYZ 56.6929 690.4227 null] +981 0 obj << +/D [978 0 R /XYZ 56.6929 690.4227 null] >> endobj 58 0 obj << -/D [968 0 R /XYZ 56.6929 550.0786 null] +/D [978 0 R /XYZ 56.6929 550.0786 null] >> endobj -972 0 obj << -/D [968 0 R /XYZ 56.6929 525.2967 null] +982 0 obj << +/D [978 0 R /XYZ 56.6929 525.2967 null] >> endobj 62 0 obj << -/D [968 0 R /XYZ 56.6929 393.0502 null] +/D [978 0 R /XYZ 56.6929 393.0502 null] >> endobj -973 0 obj << -/D [968 0 R /XYZ 56.6929 363.1913 null] +983 0 obj << +/D [978 0 R /XYZ 56.6929 363.1913 null] >> endobj -967 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F39 885 0 R >> +977 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R >> /ProcSet [ /PDF /Text ] >> endobj -976 0 obj << +986 0 obj << /Length 2095 /Filter /FlateDecode >> @@ -2884,66 +2897,66 @@ D Õmíš™Q‘‚z â~ó ¯ fÙ"‡èâ9Lt¨ž¹£j¡ mK(ÈÏbµÌ¥X2¼É6õpT!h_¥^ÁO8,uU•a¸‡àk"¿°•6ª ÇsÓ÷Oã_IZ:ä[²ÑiÉ*Np’êZÀu ‰¡‰ñìK—!Gµ&¯!cÖ`þû$8‘ôbGÊ=6ü¡ºJ¬« z¸Äã5Âr‘> endobj -982 0 obj << +992 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [519.8432 268.1131 539.579 280.1727] /Subtype /Link /A << /S /GoTo /D (acache) >> >> endobj -983 0 obj << +993 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [84.0431 256.1579 143.5361 268.2175] /Subtype /Link /A << /S /GoTo /D (acache) >> >> endobj -977 0 obj << -/D [975 0 R /XYZ 85.0394 794.5015 null] +987 0 obj << +/D [985 0 R /XYZ 85.0394 794.5015 null] >> endobj 66 0 obj << -/D [975 0 R /XYZ 85.0394 769.5949 null] ->> endobj -978 0 obj << -/D [975 0 R /XYZ 85.0394 574.3444 null] ->> endobj -70 0 obj << -/D [975 0 R /XYZ 85.0394 574.3444 null] ->> endobj -979 0 obj << -/D [975 0 R /XYZ 85.0394 540.5052 null] ->> endobj -74 0 obj << -/D [975 0 R /XYZ 85.0394 447.7637 null] ->> endobj -980 0 obj << -/D [975 0 R /XYZ 85.0394 410.3389 null] ->> endobj -78 0 obj << -/D [975 0 R /XYZ 85.0394 348.7624 null] ->> endobj -981 0 obj << -/D [975 0 R /XYZ 85.0394 311.223 null] ->> endobj -82 0 obj << -/D [975 0 R /XYZ 85.0394 189.9853 null] ->> endobj -984 0 obj << -/D [975 0 R /XYZ 85.0394 156.0037 null] ->> endobj -974 0 obj << -/Font << /F21 702 0 R /F23 726 0 R >> -/ProcSet [ /PDF /Text ] +/D [985 0 R /XYZ 85.0394 769.5949 null] >> endobj 988 0 obj << +/D [985 0 R /XYZ 85.0394 574.3444 null] +>> endobj +70 0 obj << +/D [985 0 R /XYZ 85.0394 574.3444 null] +>> endobj +989 0 obj << +/D [985 0 R /XYZ 85.0394 540.5052 null] +>> endobj +74 0 obj << +/D [985 0 R /XYZ 85.0394 447.7637 null] +>> endobj +990 0 obj << +/D [985 0 R /XYZ 85.0394 410.3389 null] +>> endobj +78 0 obj << +/D [985 0 R /XYZ 85.0394 348.7624 null] +>> endobj +991 0 obj << +/D [985 0 R /XYZ 85.0394 311.223 null] +>> endobj +82 0 obj << +/D [985 0 R /XYZ 85.0394 189.9853 null] +>> endobj +994 0 obj << +/D [985 0 R /XYZ 85.0394 156.0037 null] +>> endobj +984 0 obj << +/Font << /F21 710 0 R /F23 734 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +998 0 obj << /Length 605 /Filter /FlateDecode >> @@ -2952,77 +2965,80 @@ xÚ¥T 4‹$çÉ™‘•2' £JëØé}•ª±Ö¶Ìì¢öìJçÕ¥-ÙZ³ØÖ>ðAY³ìöwªv™÷ö»)ó?A‘ÿR¶Ph÷ÑÆÑ~»¥Ý…ÁeêsƒLÕù“éÛôÖwC’œ[yžTÝäºgGE8ìIƒ‹|7ðÒ¾omè[”—™~nlNÓímhë<ïRBHì640; ó}å*!²á ]ÖÑUA«ƒlÛ*kyÓÚ Ë54<ªàmgvd¦gíTúä,¥ì¢}Tã?9_¸ûÿcZ8^¾Klue…zR…]fù •Úµº~±®Û´î0lÒqÐÝPµS#HÓÖù]ךÃ@ÿ;ÆQ?+G†Ä¼îPÿ{$ÿ©0BLz˜¶éTÐH PGª—œÐÌÇÙýHý/š@endstream endobj -987 0 obj << +997 0 obj << /Type /Page -/Contents 988 0 R -/Resources 986 0 R +/Contents 998 0 R +/Resources 996 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 941 0 R +/Parent 951 0 R >> endobj -989 0 obj << -/D [987 0 R /XYZ 56.6929 794.5015 null] +999 0 obj << +/D [997 0 R /XYZ 56.6929 794.5015 null] >> endobj 86 0 obj << -/D [987 0 R /XYZ 56.6929 769.5949 null] +/D [997 0 R /XYZ 56.6929 769.5949 null] >> endobj -990 0 obj << -/D [987 0 R /XYZ 56.6929 744.7247 null] +1000 0 obj << +/D [997 0 R /XYZ 56.6929 744.7247 null] >> endobj -986 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R >> +996 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R >> /ProcSet [ /PDF /Text ] >> endobj -993 0 obj << -/Length 1222 +1003 0 obj << +/Length 1215 /Filter /FlateDecode >> stream -xÚÍWIãD¾÷¯ˆúäH¸âZ¼©OͰ‰Hs`8TìrbSeìrBƒæ¿ójs6sàÊÁµ¼ý}ïsŒW üðªHQBK¶ÊK†Ò§«êø”¬öp÷ýö2,¥(e”Âfá6NiÒ‚ä«øÚÈ×Û§Íw¯H‚²Œ¤«m3ûÊrP  °­Þx¯Å°ŽIšDtýÛöG§ÆP^䨍%à"C¸¤Vþ'~Nø1œ‚â;%?$ ÙO×­’Þ ]•¨ÌHæ­d%yά™$(i¤íhV,EeUíñY¸Ã~Xã"R§¶îbTG5Nû½µ¨ÝEuÁGJŽî‚wJî½ÕVœò~‹]+…jŒÆB­_N£€ ´ŽfÑûuI¢Æ´M’&-ŒQ™¦Ä¦e"r± >*Éw¯Ø‰w“õëFùÒUbм•n£z_XBëVîG473DYF|9FYRbë—"¼Žq’@Wø±þîº2^ …­!ŠÉ<ÀÐlêÕ[áÕ∕ìÞÜÉÛMRƒ2W—íh…V]§Î­éˆÙŽ-T¸ó·ÕŒì¡ˆyòÞ£¡Z®ƒ=ß8+àÜÄkN¤×úó˜¥s0‡¦Ëv±óòU× -©Ç¥·†EòS€Š2Of=§&ü¡W.tÀLFXôÚyÉß'1´¦÷fÓ¸<Žn§&=Z|KÁµ½áDnãÖ [;ÑiteL-dçÞ^z@3Š Ñr0¡sSùØò¶Ð°´@EžQ/ëph‘@#†I¨„ƒÜkg+¡Û“€:cŒ£¯&L0À3LDc‚o`Â=æÕÔÕn¹ó"¦iâ$ü©ÏÍZ™Z}!W‰37µu£VDS' 0|‹Cš R&®}› ô ½=+·-n;N;)LùÍæìÏíxp+íµl)Ýrn¬Ù4ƒ:¢[ظbñª»ø»xøË=pIÎ -ÄP²!ìåö0¿>üô²J×­Ù¦‘ %*м¼•«ÛZ  ÿVòy#tµ1ÃQïžs*ô^ mÌæ¢¸”Û®®³ -©Þ†/F¶œWˆåçÁ¿líÝc° £?;7ÌÁÚ¹¶Ý:øëN©~Ç«Þ@]bôÕÂê ?¼”ÙŸJz ÏVd[}ćž?±àú­Ÿ#„WÕ°˜eÓvÁK§*ÞÔ¨¤÷ü²“Tºm|¡¥úrMøžÒ`^g¾'ïý‹çuÒ5ÀÔ™Ùþ—´oÉ—–è-ËÃè>²<8Á³2pÁ¢1‚3•ƒŒ>píNƒ?Û{³p…T™ý| „-KR”x+:BØ#†Ë›‚WÀè%Á9*))¼ëÍžô\Ç=Ïuü$îþ\¨tÚÕê8ÿMøLÌ:›$4 1Ë= -q/ÇV”ðç^Ƕġà2…¿@¡žKñÿ‹ubóÆ7Ü#ar/¼o°+ߨ £ØœWÕL ìõ…Áýñqùvå»`W¾Ý@˜UxÎ$U‹†O^re˜†ÑŽJûÓÌ©¿¦L¯ -/9ƒ¶‹Ôïè˜PTâ„ý'tüôívþÊ ß.4EæKhé;(ˆÄ÷txšd¨ e ™¼0½÷6R=ºû*Š™Üendstream +xÚÍW9ã6îçWSÉ@DóЉ©&“Iˆ-²)h™¶…•EE¢ìL‚ýïyä#e{¬Ý-¶HàB<Þñ½ë“Å~lQ¤„Š2YäeBRÊÒEu| ‹=ÜýøÀ¼L’ +’&BÀfæ6NEAÒ‚ç‹øÚÈ·ë‡Õœ-8%YÆÓÅz7ùÊrP °Þþ½dgT¿ŒyJ#±ücý3ª%$/rfÕ(¸È+…“ÿE +ÿ¦úSP|Ñí{Jù~쥩uë͈EIÊŒgÞJÆÍóÄ™ù©ÅœEæPvE£jÇg…Ï®_²"Ò§z«PjÐG5Œû½ŒÚⶺEàÊF·{o²6\íG0×Ô­òB;Ý0ªöËqPd‹œGï–%.>c›†1R¦)wÑX ˜‡WÉA·rÓøDd3:_ið‹JõFÖ-ntç²æÖƒ2¦n÷™jÁ"’Œû,&Œd´dί l3J¡òØ/oS1 +!ÁÏ|€¡ÉÔ³·"«àˆuÛ¼âÉ]ég«ÌSÛ\˜—õD–BØM£Ïµ­…Ý€vÉ¢Æß¾©Ú¾°OÙù&èúZš`´m&€7rƒ×ž´¯óç[Ud VÀB‰q±ñòUS«Ö s®[hÍV6 ˜¦‘Ñö™8Ï©…ßw¡CÏd<‰ž/ùç¨úÚÖÞnvÇwz4ƒkkk)¸v7›7¸ÞØ-ŠŽ¦Ñâ€ô†Ú^j 2A Ðb°Ð¥Í|l¼Î,-H‘gÂËbºÎƒFãœð„ñ l¹çÆeÂÔ'yfŒEß`OX0ØÀS›¨¿S•ŽJÍ—/b‹¦NÊŸúØœ•±6—²í™8K›[µ"%a·}((á%Åò­VPhíõYã"”Láv7­²é·›³?<×ÃWÆk¹Târ*¬Ýìz}$·mƒÉ’Usñwñð>XÉ Ë +’ºâÉÓía~}øñi®)±Z“M+ÁKRyy+·­{(†ú;ÉÇ•2ÕÊÇvóhØÃ¡wºÿàj`7Źخúê:ªê-ôxÙ|\˯½'~—{|ôÐ,ýàÏŽÀ X7×®ZÝhÝmdõÁØn{5øl1ù…›‹ìoÝz Ndë6¶úDö|übÂÍk7!„7T?å®n‚—FW²9èÁïñiS«M½ó‰nõ—s:Ã÷ tÌëÄ÷<ð½ñ<æ {˜:;Û_Iû޼YéˆÞ±<Œî=˃ +ž•á@ú 9ƒÆ +NT2æ ž®öv‰¿W™ü¼ç<™!Ž„¦$çðVDBT¹#†Ë›„WÀè÷)a9)/¼ç ¯õ\'=Ï5ò¤Þü7¸Pé¸Ùêãô7á˜T–R‘ÌížÜóØŠþŠkls +.Sø«ê¹”ý¿X'¶o|uÃ=-Lî…wà våã;d̛˪š¨!=ZŸÜOŸl_¯|É•o» +ω¤¶j'ÇÆÌ9‚4ŒýàF%Œ}ÌÄgcê®)ÓëŸÂKÆ ®Ô,u°7tÌ)Mþ:~ø~=}Ü„O‘û4÷ùDâ‹ ~û\w¼ )x™C6.&Þz›¾¤îÝý ?»˜endstream endobj -992 0 obj << +1002 0 obj << /Type /Page -/Contents 993 0 R -/Resources 991 0 R +/Contents 1003 0 R +/Resources 1001 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 999 0 R +/Parent 1009 0 R >> endobj -994 0 obj << -/D [992 0 R /XYZ 85.0394 794.5015 null] +1004 0 obj << +/D [1002 0 R /XYZ 85.0394 794.5015 null] >> endobj 90 0 obj << -/D [992 0 R /XYZ 85.0394 769.5949 null] +/D [1002 0 R /XYZ 85.0394 769.5949 null] >> endobj -995 0 obj << -/D [992 0 R /XYZ 85.0394 575.896 null] +1005 0 obj << +/D [1002 0 R /XYZ 85.0394 575.896 null] >> endobj 94 0 obj << -/D [992 0 R /XYZ 85.0394 529.2011 null] +/D [1002 0 R /XYZ 85.0394 529.2011 null] >> endobj -996 0 obj << -/D [992 0 R /XYZ 85.0394 492.9468 null] +1006 0 obj << +/D [1002 0 R /XYZ 85.0394 492.9468 null] >> endobj 98 0 obj << -/D [992 0 R /XYZ 85.0394 492.9468 null] +/D [1002 0 R /XYZ 85.0394 492.9468 null] >> endobj -997 0 obj << -/D [992 0 R /XYZ 85.0394 466.0581 null] +1007 0 obj << +/D [1002 0 R /XYZ 85.0394 466.0581 null] >> endobj 102 0 obj << -/D [992 0 R /XYZ 85.0394 237.1121 null] +/D [1002 0 R /XYZ 85.0394 237.1121 null] >> endobj -998 0 obj << -/D [992 0 R /XYZ 85.0394 206.4074 null] +1008 0 obj << +/D [1002 0 R /XYZ 85.0394 206.4074 null] >> endobj -991 0 obj << -/Font << /F21 702 0 R /F23 726 0 R /F41 925 0 R >> +1001 0 obj << +/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1002 0 obj << +1012 0 obj << /Length 1860 /Filter /FlateDecode >> @@ -3038,185 +3054,187 @@ g:+ n9ê®ÐB©ªWúQEBŽ| ÌNuë`:ôkn‹}8ÔXÅÇtªëmý÷­¯ý=^¤8æñ Ç̃€×á<ÊÃ>%Åê+'Йú>êçòE@Û߈¶¿4E¢þhh!V²ŠúO@º¬bºMæ1áwÿ$‰%7BܲÌê½>ìsëD7c¸¦1êÿ0§‘ÌÁ¬‡^˜yö·èl™ê.$ ˆßf’È:®Ò¹ïXÀŽ2³—à‰+YÔÑ\÷¦ =n ˆi¬¢> endobj -1007 0 obj << +1017 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [55.6967 190.8043 126.3509 202.8639] /Subtype /Link /A << /S /GoTo /D (rrset_ordering) >> >> endobj -1003 0 obj << -/D [1001 0 R /XYZ 56.6929 794.5015 null] +1013 0 obj << +/D [1011 0 R /XYZ 56.6929 794.5015 null] >> endobj 106 0 obj << -/D [1001 0 R /XYZ 56.6929 480.2651 null] ->> endobj -1004 0 obj << -/D [1001 0 R /XYZ 56.6929 441.7923 null] ->> endobj -1005 0 obj << -/D [1001 0 R /XYZ 56.6929 373.7178 null] ->> endobj -1006 0 obj << -/D [1001 0 R /XYZ 56.6929 361.7627 null] ->> endobj -110 0 obj << -/D [1001 0 R /XYZ 56.6929 167.4388 null] ->> endobj -1008 0 obj << -/D [1001 0 R /XYZ 56.6929 126.8733 null] ->> endobj -114 0 obj << -/D [1001 0 R /XYZ 56.6929 126.8733 null] ->> endobj -1009 0 obj << -/D [1001 0 R /XYZ 56.6929 98.4089 null] ->> endobj -1000 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F21 702 0 R /F23 726 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1013 0 obj << -/Length 2705 -/Filter /FlateDecode ->> -stream -xÚÕZÝsÛ¸÷_¡—NåéÅA°O—Ë%×ÜÌ%×ÄiÒÌ”– ‰w©);Îôï À$EJÎø©ãàò·ËÅ~f3 -l¦SBE.gY.IJY:[ì®èl Ï~ºbž& DI—ꇛ«¿¾Ù,'¹âjv³ê`iBµf³›å§ùË¿¿øõæÕûë„§t.Èu’*:ûâ—W¸ò¥éüŸâå»·¯ßüôñý‹ëLÎoÞ¼{{d4—ðæåwßýúêñ½ןo~¾zu¿¢û¥Œ -û \}úLgKøàŸ¯(¹Ng÷0¡„å9Ÿí®d*H*…+Û«Wÿˆ€§îÕ1Í¥B“TólDuœ©.͉\8ÕÙof„]'ŒR:ÿ±,ÖUÝ´å¿öæš16¯ëmc¿ðDήHγÜ!ÝlŒ'ê2e9¡)³²Zše¹b’äRhOóÝŠ$Z$Ø€€c(9*ã%á’Í‹j9Çaw¸–ž´j¶uýûq?‚)SÐ>Ë<áþpÍô¼^Š]ðBÏ ·bì$ŸÛ-®.êÝÎ2v“mYµNŽtUp èŽðÞÎþ8šÃCY­qV;ܘÃ94ÄJ8KÏ@ëvž1’§)êÀM[–++ÕÊp^VøÛ´[ƒC”õ±Ý[ƒP»¢%'6MaÁÑ”ÎÁ¸r6(éRM›`¤êE—g¯hÁÏó D#<{vAÁ¼”LûL­µ&œfóe½+œ†¨M¡ʺ‡kÜñ½S%ÌÿMS:fäR°6ñ VH 1Ë™·A¢µo7²›Ò¸] -Ü5XÛoMëéëUhü’7h7vfqçjþÆoŠÆÛR -’S¡ú¶ÔÞ×׉  DYšæo׉d|Þ”–)®—UkÅ¢-ïÌ#!Žœi ˆ%ΰçðš³oRÀ=“øEöÉmÑ.6C¨ûMͳ8¶¦ÁYÑ…³ßAûò£{I›Ât ÀŸmÙx«wÚ³Þa@ÛÅ'ˆì)+cÕ'¿Øž>¯÷Ö\ã,¦iÊÛàt+4¦Îp»að-<·S„TÇ5xƒTD0H‡#ÞÀ  •ÂxÌU¼@Šèbœú'£0–ê‘“ÕæÇ¦X›I™„$"ÕêY2u0œLrT¦@\,Q`eŸ¾GWK»®&R¢UšzWÃè‰d=d¡·õdŸG€‚Qy¿ÆPq -$ÑR O#@)ɳLyg=Iû°7#Xœ³,ÕQ(üÊ1Ù ®{˜‹mÑ4# *%Y*äô/#¨\ÜV.]T4ñØŒ‘Lôô7K„t¿ïŸ’ËÊ-×ӌƕò§‹ò[ß2U{qË>Äkˆ9‘”C‚Ò‚Cñõ˜7ÀSÍ1D‹qÙô㊳T;¸/Côh‹ßÍ ؼ3’Xhw„úÞ›42 ,Ä%´¬Î¼cîƒþ:Í]ÝbýœØ­&CiqW”Û"Æ=àšaéó»~;*9U„çOËÏgØŒH!ƒÛODÜCøš¬jR0Õªš.ÕtU©ºUj—© y’*užk¤a+Qز¸Çwº g’Ÿ¯ 9¸3ñð…GÙºÊ4›Ýj†òšÍ¿š—œÕ—‹Hâ+^ I×ù,9ƒ€p -›Ai:ÿÁ/ͪ8n[»ùJ WufÝ6øÖ­iï©ðÑ‹"X¶e±¯^$ôLŠòkPÑÀÞØ"¥2Þ8‹åͺiL0ºÛPú–­·ÎÕ±ZX³,ü§[ó vtë-Ô|iMµ4ËàÖífàÌ'1À›údbO)'TÁN>#‰v1¦{¤º˜ØeÊ….é92u1¦{¤Š¦‰á=)^.·Õ¡¹¹¿ ?YŒå~¯eÈnS9çÐDSHòöbùP-ëv/6¥°½8‘øû™+âýë2^¹3ÐÇ=!ÉyÈ÷#·5Q9—ýÄ}0í¡4ÍÓ±wÅ]m‹õØçCÐË4âÉ8RcZ¯±¶ãšæ‘B,è+´o+ûeÏA3>÷ÿ5¹NgF{Zv•<³GMò|víRMg×H5<³éeX®¡ŸÍøyΑêk‰•iØÂIÞ§çEZçá¼ÈvÙ ÏöÓvúi‘fýÚ>Ä̓AUWIç©MÚ§³.=6ÊîÍí¶¾¼6~²ÐÓ¤Ê œz|'RfKDÈê®›…™?s‚‘whàqŽ=u–=Ú,ÕPKA¤êÖÈI['«2!÷[_M Žþ_ä“xvè:ŸÇ³„ÑTå½äÐ÷l£„‘3Jø5–ÄYÕî7®2Î)D \Á³§õÑ6¼MwÉC­¾Â¡=ÆDû…‰/ÅqâY‡3gÏ [W¹8w%îÒaŽ.škQÅÊØ2¦ü€fÝéÐsç½0Ý<ì"E‘ÿ“üÙ›Zçl]ðÆ@ÿ°¼„佂ÎQtÕiFBL§‘dfü h4¨0“sÜ®#ÐI<< §Ÿ0²Û_ŒGv„ -µ#÷‚+ÏÌ.¹cWø}ìzì¬'¬#[õBcå–jü½õO¬ ÖÖ•,¿r4êÓ’À°Á_T3 ·Ü>íl‹ëµ?Pgè£îLfq3où§{³(-²²ó» -#¿UÃ¥ìœôý©e0fÆOØGG÷ãÑê‹aº°¿®™´”úGGà32’ØMZ ÿ&ƒÃ`3GÕÚK!¤M4Ý×Û•[³)îÊÚIdÒ¹žß{¤¥—¡ª=-â9ØÅðEàð{»]ëÈ•™&™Œ%â¹J&•…>ËœlÌø5œÚo8Ó¢¡5Å’Œ€%Lä¶µU6‰%™ìÜor¿ùb¹++På¡ÀSï8±;{?\ëÙZx[<„B<ø­YÇk…}qhû×ñÌêiH£ÞÂOƒÊÀÇjm&3BµºPkw©¦kíHa™,6fñ;Xâê¤äV)š,?/@¤‘ ¿ß”@$æ}&µ˜ŠɈ˜lÍIÆs~z›ë[)ûj3Ø—æ¡j‹/Ã=9­œõÉxýì„!r(N¸Ri¼ ¤|;}éco{5eâ9Tcºª‹T«:Ơϱ¥Òsdê`LWu‘jl‡}q÷ÛÝ׳§/L1F­cœ9˜E[ãÍáð˜@ÅSö­—/«rk&ÀŠ5§ª{`0æ¼SuÞui¦×Ó ´õµ®Ì©ÛÂFI¦Ï±Ž4'¼ûº€,Âï2?ç°úÔaƒ€C‡•°qâI[„0Ú´áb+Þ¯œús<-‰ v·ÓÓ7°)œ=ë®3"œ¹}Eši7ô›-Rbÿ5h„!—kÏþ¤ÇÌSZóq#T¡çYÊ -ÏÒ¡äñ_•NEÿ…6_0endstream -endobj -1012 0 obj << -/Type /Page -/Contents 1013 0 R -/Resources 1011 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 999 0 R +/D [1011 0 R /XYZ 56.6929 480.2651 null] >> endobj 1014 0 obj << -/D [1012 0 R /XYZ 85.0394 794.5015 null] +/D [1011 0 R /XYZ 56.6929 441.7923 null] >> endobj -118 0 obj << -/D [1012 0 R /XYZ 85.0394 769.5949 null] +1015 0 obj << +/D [1011 0 R /XYZ 56.6929 373.7178 null] >> endobj -966 0 obj << -/D [1012 0 R /XYZ 85.0394 749.3395 null] +1016 0 obj << +/D [1011 0 R /XYZ 56.6929 361.7627 null] >> endobj -122 0 obj << -/D [1012 0 R /XYZ 85.0394 221.8894 null] +110 0 obj << +/D [1011 0 R /XYZ 56.6929 167.4388 null] >> endobj 1018 0 obj << -/D [1012 0 R /XYZ 85.0394 197.4323 null] +/D [1011 0 R /XYZ 56.6929 126.8733 null] >> endobj -1011 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F53 1017 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1021 0 obj << -/Length 3394 -/Filter /FlateDecode ->> -stream -xÚå[ݓ۶¿¿BoáÍX>‚lŸœÄN™Ú‰ïÒ´ãø'RwŒ%R©;Ë“?¾»ø")‚’'éL;é܃Àår±X,~Ø]àØ‚Â[È„$Ï*‹‰¤L.VÛ+º¸‡wß^1˳tLË!×W·W_¾j‘‘,áÉâv=•š¦lq[¼‹ä$Ðèõ󿿸^rI£›o¯¥Œþ?úùÍ÷/Þ>¿VqtûêÍë›ë¥¢Y}ý·çßß:ŽË2¾~óúå«oìå\¿¿ýîêÅ­Åp¤Œ -¯WïÞÓEþ¥rñ”°,ã‹íU,‘±޲¹º¹úÁ ¼ÕŸ†,KJ¤Œåb)b’Bÿ!.–L$Ú! -ôf)‡†ÌH"¸ðÆÙÀø)#2ËäÂs¡ñë|[ËÕC¹úð©©ËëeBiônYüòëã7ïÝÓ --õåK)Ò˜‚yCPÊj“·­auÉ3’¦*³\^^'$Œ^:͡ۺ€Ä1›—Ø]”XTûrÕ5ûc@¨ŒIÂ%;ú -³„sÊÔbÉɤä¿Wú‡‹*ÿL%­îëf_VXcFÒX8©¿„q¢[†§|_¤pA2tõÏ”²Î« hÅæ¦:=dý'äÔŸ -: -O‰¢iÃú,cÆ ';tÕ¦êp}-Ê«r×:H ¶"È×üm—ï»@W°ÿdIìvfVЈEòäT侜 -¡~&=Ÿ¡;Ðè顺fÑêÁ|üd‘À<国H‰¨n:«°™!M¯ê燔B5&Ò2óûÕ­¿zÈëºÜáÛ¦(Á¹xý«µñYŒù’D&cÐ;6\ûë4:„T -"¿T^ð7MáÔ~ªº‡æ`1¯-€6;\­ESûö©Bo4€Úî6ùq²‡6¿·ˆ¼-Ûþ!oÚêåý— ÔBr€VL%”³ô¤#CS$véˆçÂáÿ¨QIbÖ˜Àrùý* EÌgHžËOÛ™Dr‡ÑE–²±5‡SïÝÿ¾z,ë~’gç8Î(¼° -†\ósì¹Ì¯! yMò(=7É“´yvzþ˳C’,žµ¦çššód–4„J#{Þ@&[Ü -þäo›W˜{æ:†·9àïõˆuy¦Ä_pñÇe|œº]»=x4 ¤øÒ—AÿîcÏ8¬Î³õ\S‹ŽÝ ”aldÒ·½IÏN¶õ “HnOx·9d¢6œó A‰<¾à®3>á¸t¡k_–Ÿ\±üO‰˜HA ËÎÕsM­:ö ˆš!)äc³ÞÚ]‰Û»qtØyW¶æë -”¥ð§8Öù¶Z™ K™pLØ4©núW¦UYAº µ´¥AbqZŠ0Õ.ÌS3Þ¦k0Ò¤þ<52[Kói+<´Fù²ÀÊ‹!bÔq^ -)¼¶>äVRYT%›º‰ŒîJój›åð)È¥¾l­ËeXbñÐqjjl‡†½;â/C£AÎmíφ µM Õí ³I¾±µÊ­6?¶!A¾7LWóh‹4ú¥9ìë|c\¨†œugÛ#½Õ -€¿±\¶4DÇó`×÷’sóqW‡âƒ>ñÁ‡‡ÐÖöÎ;ûì*lzb°ççû™÷"|0Ö0ßæ]Wnwzn¸Ï³9=‘¹ûXµžªMp­z8sÑ¿…µOe=‹_°0ˆL“ô<~ ¹æñËsµò§yô#Ê -dÿWÀËŨg-ÚG²“†#Ù‘M_ÔùvÂ$í±‹'™ñH ææ±ŸwCî½^Z,I¢± ß×MÿÊP*+±ÌA™HIœÒ“SÉj€eÊc™rX¦ÆºÀ³Ç65Ä6¬ÑãØ4²·;dK=Fà¶D¬\ÁÂÃh„ÙPÈìðL ·yø ¨ÚÏBЦ¡’i+riTChâl°/C¿ÀC¾Ö`"† ͨƒ­‡Ü -À3¢MÙé¡J.£çî3®·ø±[ -ðVV4.&md#¦,C8à¦XÒoŒjxzšáwÓÒÚ¸è®tF7³XÁñKßbæjN?÷®3sï¸LîÓ×3G!˜Ö˜Ó ={®i×㚈IŒw†F}ûÊ€HÜ©e¨ÑoÿÐ6‘4úkpÝÐè†`(2w^šDEc¹KA<—«¶«êû^ư×ÖžPp󘡪4ÉL–Eby–â8ކò?–†fb+­2qØŠß´æýÚÅA@¨© 57„õðcZ—ä‚“8ñ§4Ã’ÕÈò‚AúêÏŸžœ¾ §‡ÿÌn8@ÎÍãÆì úD¨õa{gL±’iމ“k¶|Œ‚n{ÑЦ÷Žñ‰FþØTE{âùuYºú…Èò# © §ú|°)ô~·Ô »jë:œÔXÊØ©œ__”¼$j C®3ëËqéÚ~—wí´ÜÊ`/Wò|·žkÚïxq±\ xÔñO˜7ï«ÎÚÂoÙØÐãWíØêÞp§ Æz³ÆÃ‹bT° ÓkÞxž Çðë¡Ü7Í<8í¹§I×apõ}{ñ¨¹¿×™SFlÂê2ÀŒG?L^˜V¸‘j. é,‰ù`ËíÇåÇݦZUÝæhèEe誳"S—G@Á)4qo»ª´wB`Å”÷þîÚhô8?Üo™ýåÐY6"óÇ`öD59Àׯë›!öZJÆa©tg¿€L`ãOÂZ4Jc@:=p‹ ïÚÜè¢N`¥9Ñz[©8+þzÌúØk5ìEq’òÔ}ª=ÄFëBé}îd»@WÖ êX¶ >bþ|ÛÝ©™µ\œ%þ6¥=>Ë„`fb9˜AËɘǟc9™AÔ#‘çáÏÐTr¡†?ä:ŽK_É£¯éáó ˜Ú:¥éÆäï‡ûCèsqšúê¶›½EAÀ0î_ýó%^×gÃ3Áö¾íÌ›bçÂе2WO‚¯ÑEèú…Žÿ†œ¾FŠT{–¬ãYíƒÀ°Ü™wÚó°[çy`3÷FÀ/,ƒ½A·*Ûvî_ `Fñÿ³Mýuˆ?üoýcགྷ4;ªSX3!V)4?K¦W/)¬þ„Tÿ7ˆ²endstream -endobj -1020 0 obj << -/Type /Page -/Contents 1021 0 R -/Resources 1019 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 999 0 R ->> endobj -1022 0 obj << -/D [1020 0 R /XYZ 56.6929 794.5015 null] +114 0 obj << +/D [1011 0 R /XYZ 56.6929 126.8733 null] >> endobj 1019 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F53 1017 0 R /F14 729 0 R /F21 702 0 R /F23 726 0 R /F48 940 0 R /F55 1025 0 R >> +/D [1011 0 R /XYZ 56.6929 98.4089 null] +>> endobj +1010 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1028 0 obj << -/Length 3881 +1023 0 obj << +/Length 2720 /Filter /FlateDecode >> stream -xÚ­ÙrÛ8òÝ_á·•«"' î>erÌxª63›xª™<Ð$eqC‘‘ŠÇ[ûñÛx ’\5[©q4ÐFßù5ƒüÚèˆÉT]'©Š4ãú:ß]±ë˜ûþŠ;˜µZO¡¾»»zýA&×i”Æ"¾¾ÛLö23†_ß¿¬Þþðæç»÷ŸnÖB³•ŒnÖ:f«oþúžF>Ô֫xˆ·?}üpûýß?½¹IÔêîö§7ë„¥ -V^^ûÓÏïÇuŸo¾Üýxõþn8Åô¤œI<ÂoW¿|a×øÇ+ÉÔèë'è°ˆ§©¸Þ])-#­¤ô#õÕç«¿ NfíÒç´4‘6" °NÈ ë¸ä‘‰¥¹NtÅæwUq³–±YU}÷7ܬÊþ°oʸÇzu·õ“Y]·O¾Ýзü½/÷MVc/]=Úõm^v¬oé[”¶«š’ºOÛÒ­o²]éhØfí’·»ÇÈ`8åšó(ÕZXŠ»¾}|¬š‡hÉ}ÎV%× #“0d×µž‚Yv)3eƒ¶ŠÇÍ÷6«{` -c«_Ö_Žˆe”(%/ࡎ ˜ßWl¢DèŸáô ŠB®úm‰ ±êÊý·rOƒÕ¸Ye}Y?ßpÎWp…’ñÕ§2/›ž@òmÖ<”7|ÕQ—¥ß‘nïð°¥ân§Ê Íá±€}i¢uènÿõᓽ#¸6.næW•‘4 \¯š¶§F—}³7M+\ÑYp`—u=žÛ¿2&ê²{=ÉW÷·ü©ªkjÝ»EDu]û]7íþ‰P´ý† v©Göïöà$wÄæpx:à™Ò5 ËË#¼2Œ”é¼êï\E•Š þÍß69ÝÏŽtY¹uÌ#¹é;Íõ -2(²šG‰IùÌêóœ£:Ž’„©9êÿGÙ¾éÇù6;Ã7…ÄoêC·=©èçñŠ~„7¬è3ÄqùÆåY¾='R"†Fj.±fv†5j` šé€2ƒ cR§ÌhF` -V BÐ z¨cçÓàHtveÖ¸íý¦÷ýÈ¡¥å© ²¥Ga Í qÁ” FqÉ2Î’sŒ1m$1B   ÞžNc}Y*“HÈá–â0Ï‘«­5®éðØV–ÔÍëìЕݟƒ&=¡:K‚(\Ÿ”Ä=;/Ñàüøb¿^ -2ûj Hy2úl[[j€–«5rAœR.ñkl÷áànGlZ |tðN¹¯¼aŠå ùBÀ(dغwp`˜û,'¿][tBêÚ€e_ûÓÍTyÝVSffò‹¡\ä©§‰NA3¡}«lJè -oœ{ŸZJ,Dõ`ÜÅË$ ì+3bq=Zyœz(kW ¢Ì º_­iÁ¾;@Õ»µÓkrI…Q6q¼('Ú•‰ž†Øµ±V‚o©ÉŽËÁcœð*i$UrdBÌRà¸4/Ô›$ÒBzÜcNãNA,ƒ†]NC-}É$î -IÅ!v!‡©ðnÛCí8ÂÚ@F+ª‰v¢ -š* xW½Èäq“ÚݤÞïC¹IÞ4H³çàön Ÿ åPEàÛãøn–}~[è-!:V¡¨î„‡/‰ä·*àŒİ£nF’sh«t–¾à2lr P`Ô€¨ -m^p·)÷èž÷ùXáò©‘CçHˆ’ˆ‰A'¨:äsšÒkó¨tuÛ»ÃvÏ`ö~÷¹2R-R Œ€Ñ\Dæ±ÚýˆDŸ*|%¸Á¹+Á¿Åd¼‹­!4cÐŒ¿‹ÒÅõ›>¹Ð$P:伕ˆùy -x¤âA¿üA7-þàÊFÛšl’$ãç°Ž„½ò‰­ŽRÃÞÀGc¬vëë„«‹ÀHF[¥fÑî2«UE{»¢—ÿaPº²/ŠõT×jÝ8®CVÛÝ˶‚LÖ²(ßâÍý…êYýö`)=]¿'aƒÅuõµ Er¿ -¡B5p<º\ÈúòMXëÀB&«Lü’è ØÕ˜ðÏóÖÃŽëé–Gy©€{;c’(•C´gÏ:+eÔõ¦è’\Õ)l•R´Â­KX%@@A+å§–FÎ…«°U¬‡žÕí¬Æ.€T%¿ ©æÉœIê!ÉÃÔ¤ 9FG`8ÅhZÿÜV¾¸æÇ…Õi²¿3‘ -çâÕc¶ïl¼¦b¥A+Ëóò±wíæ™ƒØ*M!…òI’Š—1£ryÎxæ ¨äè @(·žíçjË/ÑŒí.Ë×»B‡ïÈ!sp¢gÅåe¯q/k˜¾Ùßu RçQ&™ãÄ¿gî-$ëÊu¬üóFÞþoàw¡ŠíÄÕúðÖýÖW+ãœ4wL¼ÈE|Ç3—bM© -!Ù˜Owd©2&? ýi4 ã÷þ(Ù 'e‘ ¯}'TŽ–j¦ÈåÞ#-³g~ÈËü#»à®°^€ª”¾0» È⡺l=—àSÏ%¨r‰_ô\‚¹„ (²Ç–­#Șpá±› qÌ` #yAhg’1p¸v@fåÖ®aãlqò§“fÔ0u¾ -´VÀØ$ ÄÄá;çéĬņŸàl<Æñ')†íè°pp«l7ôhh›øÚ$4Ü5%®l9N¹ÐÔŽ´4pïÖPhŠ#®Ÿ¨é{"ꃤ÷D»¥«ÛÀáÐÆq €¯?ÿdi hÔ`/„]’¥é‚ãûÑäýÖ…Ú“÷Y˲Íó"]™`š‡âà Œ¾øþ6ç(Ë¢Ç#—eM8J•¦:âO¤Žðï pøïäñÿÙÂø×èááRºd1é°# -Í“%åÃß7“þ?(†endstream +xÚÕZÝsÛ¸÷_¡—NåéÅA°O—Ë%×ÜÌ%×ÄiÒÌ”– ‰w©);Îôï À$EJÎø©ãàrw¹Øf3 +l¦SBE.gY.IJY:[ì®èl Ï~ºbž& DI—ꇛ«¿¾Ù,'¹âjv³êðÒ„jÍf7ËOó—ñëÍ«÷× Oé\ë$UtþöÅ/¯påÛ]ÉTT +V¶W®þvžºWÇ,— +MRͳÓq6fº4'JpáLg¿™v0JéüDzXWuÓ– üÚ›kÆØ¼®·ýRà':üè,áŠä<˧›ñD]¡,'4eVWK³,×#Œ˜$¹ÚÓ|7ÂE­A l@Á1.9*ã‘KÂ%›Õr„‡ÝáZzÒªÙÖõïÇýO™‚õYæ ÷‡k¦çõúPì`/ô¼p+ÆNòy±Ýâê¢Þí¬`7Ù–•ÁQëìèHWõ×€îï=àì£9<”ÕgU±óœs¸3‡†X g ãXÂÎ3Fò4åÁü¸iËreµZ™ÎË +›öakpˆÚÁ >¶ûc‹cPjW´äħ)ì šÒ98WÎÆ£×%]ªiŒT§èÊÌá-øy™hDfÏ/(¸—’i_¨õÖ„Ól¾¬w…³Õ`)´AYWøp;¾w¦„ù¿iJÇœ\JÞ&¾ÁËCžeƒÂÛ ÑÎú·ÙMmܮƒí·¦õôõ*2hü’wh7vnyçjþÆ3Þ÷¥4§Bõ}©½¯¯A¨²4Í߮ɸ¼)­P\/«ÖŠE[Þ™GB9×K +œ7àÏá5çß.¥@x +&ñ‹ì“Û¢]l†¬î7eX4_ÌâØšgE—ýÚ×à \Ú–A7 +üÙ–÷zg=¬]lq‚œ=ee¬ù£óÛÓçõÞºKã¹Ç|`'‹…išò6Ý +i‡3Ün0 +NåãSÅ)#Ɉ–"0ú4Â(%y–)Oà¼'iöf„ç,KuT +¿rL7¨‚ëÏŶhš¦*%Y*ä€é_F¸rAr‹\º\ÑÅGØfŒd¢g¿Y"¤«øý€ü”\6n¹ž4n”?]Ô߯–©Ú‹[öy$_Cn̉¤ + @ àë±n@¤›cÈ!3ⲉye¤PPPMçç EF¤Á{ïËtÚâw3ȶ\ˆˆ !£wyLã‚HuÈŒ ‡¬çèÔå1 "UtM¬Iñr¹­ÍÍý](Éb¬ ˆ{-Cqœ*¡<‡3è°%o/¢jY·“üâ™62l/2œÀ ýÂùýë2¿rgàø„éY¾a e_•sÙ¯ûÓJÓ<÷«m±û|Hz™æC~2ŽÔ¾ëë;îÌ=‚?ÉòÈý"Àû6ÄÙG<ËøÜÿ×â:]týýiÕUòÌvªäùêÚ¥š®®‘jØòéUX®á8œñó’#ÕÑ ++Ó°…“²OÛMC»ÉÒž <ŽÛA8Ž‹4ëÁíCÜ<Tu•tžÚÒ©}9ëÒã9Û½¹ÝÖ÷AÖÆ/B:`™T9a‚óA‹À©”YˆU݆aæ[V0ò!çœã‘<Ë}ž9·…µâ¶v¥†w°\Êúèß³Þä‡þ•‡¬~ùª¨ÐþߎK®ø €‘i¯q€Å0Çð^;ügó·}³"¡7"к6¬€Ý–8rÁ“ ,ývlüÈW{Lf…bô‰9†8XˆÙÜøÕA°óÐå€ýëxÄcƒ¹‡ô'Q„È8ÔAö,Ñå1""ÕE!%)WÏêxtyL£ˆHÕ Q_;0B š0>u—‚HÕÅÈI['«2t û'gM þ_”“xq:ŸÇ«¤ÑTå½âÐl§„‘sJø5–ÄyÕî7ç²®`ëj}´ç妻äY­}…CÛEÿ…‰‡â8ñάCËÚ Ã#,ŒÎÄ]ºèˆã¢»FUDÆV0åtë¾ÂH‡!˜»è…éæa,RTù?ÉŸ}×ÕÒ¸`ë2o œ–—x#¹å^EB稺êFRLç 1¨Ìø¸Ñ`ÂLÎIdävä#ÁÓÐ<…‘UØþb>²#4¨¹\yavÉumá÷ñÔcg=eÙªÇ!¬ÜR¿·þ‰ ¡ Ú†’•WŽfÝàZ6ø‹f†Áã–Û§mq'Bíû1ð cÔµd`7sð–º7‹Òr6Cq~Waä÷A¢i¸Tƒ“þ|jŒ¹ñöÑÑýx´öbX.ì¯;LÚê çGGà+2’ØMZ ÿ&vÑa°Š•£jíÒ‚%(îëíÊ­Ùweí4²}x®ç÷žÓÒëPÕžbm‰jx8üÞó/@L™ŒñȤ²pÎò}÷¿ÅÓ@û = ­)–d´e&r{´U¶ˆ%™ì\r=úb¹++0å¡à©W¤x:{?Ü +Z,¼-¿5ëx+±/mÿ6#ö OCõ~šT.8†µ™ÌÕêÖîRMcíHa™,6fñ;xâêr«”&ËÏ+©F4èï7%‰y_…ɦSñD2¢æ€·æ$ã9?½ öG)ûj3Ø—æ¡j‹/Ã=9ÅÎûd¼½vÊ ='\©4^$R¾¾3²—Åš2ñÕå1ê"ÕETÇœs,TzŽNÓ¨.Rí°w¿Ý}=Û}aŠpjóÌÁ,Ú/‡mIOÙ·Þݬʭ™h<€kNU·a0¼Su>ti¦×Ó ¬õµ®ÌiØÂFI¦Ï‰Ž4'²û¶€*Âï +?°ú4`ƒ‚À•°qâI[„4Ú´áb+Þ³œÆsì–Ä»ÀËíé Ü”ΞuU9œ¹¼Ešé0ô›-Rbÿ³hD wsÏþ¦ÇÿëWZóq'T£çYPÊ*ÏÒ¡æñ?NUÿ£^mšendstream endobj -1027 0 obj << +1022 0 obj << /Type /Page -/Contents 1028 0 R -/Resources 1026 0 R +/Contents 1023 0 R +/Resources 1021 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 999 0 R -/Annots [ 1030 0 R ] +/Parent 1009 0 R >> endobj +1024 0 obj << +/D [1022 0 R /XYZ 85.0394 794.5015 null] +>> endobj +118 0 obj << +/D [1022 0 R /XYZ 85.0394 769.5949 null] +>> endobj +976 0 obj << +/D [1022 0 R /XYZ 85.0394 749.3395 null] +>> endobj +122 0 obj << +/D [1022 0 R /XYZ 85.0394 221.8894 null] +>> endobj +1028 0 obj << +/D [1022 0 R /XYZ 85.0394 197.4323 null] +>> endobj +1021 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1031 0 obj << +/Length 3424 +/Filter /FlateDecode +>> +stream +xÚå[ݓ۶¿¿BoáÍX>H€lŸœÄN™Ú‰ïÒ´ãø'RwŒ)R©;Ë“?¾»øâ·äI:ÓN:÷@Z,‹Å» [Qøc«H™ðd¥’D”E«Íîá·o¯˜¥Y;¢uŸê«Û«/_ +µJH"¹\Ýn{¼bB㘭n³w ‚\¼~þ÷×kÑàæÅÛë( +þ]óý‹·Ï¯Uܾzóúæz­h_ÿíù÷·Žâ2¯ß¼~ùêÛ;>×ïo¿»zqëgÑŸ)£§ðëÕ»÷t•Á„¿»¢D$q´z‚ +%,IøjwF‚D¡®¥¼º¹úÁ3ìýª»Îi.Œ(‰¢0Z­EHbŽŠI’AyŽ…¹YÌ¡%D +.¼òCÖS~ÌH”$ÑÊS¡ò«t—gëÍC¾ùð©®ò뵤4x·Î~ùõñ›÷®¶AM}ù2=nLÁº¡DÈeS¦McˆCò„ıJ,•çWÏðÌ>r ëc»?¶3‡džc{‘cVòM[N3L£H±1Ó§¦°J¸¦L­ÖŒ‘$Šøïåþá¢È?Óˆ÷U}È ) {¤!#q(×_f˜q¢¤ +-ÁSz¨f¸pA4õÏä²M‹¤bKK'Yý '9µçŸf …ÇDÑ8ÊzºŸ)èÌþµB +½÷/±y7Ã&"‰RÒi®(s”N¡"1§ª/ÐzQŒÉ•¢QJÍŸ1–fÝ#Ò(ÇÙÜc‰z Wïö  ›jx&„±HßM(ö;MHpSìŠ2=ÀA$¢ µø7;Œ¥Ì©zËÏl‡þ8±[ð½´ÔÌ ý ƒ´|JOiËŽ»}cšÛ‡Ü´´Ç¦M]µyÕzÙLwSmöù¦ø™Ržg(ÂjÍiH¸¤ÌY5³VMy™›c-¼=í‹MZ–'ÓTT曚OVl¯Yló~ÌÐм­»´Eƒ&Kæ!¥ ñ%óè-›‡#BéU¶¨a2JÎŽèh¦#Ö‰*1ñV¯BÌ£]ÝÚºÞ=PbA–BseZq…4e]šÔñŒ 1˜ ý¦vó Ä)Ay<ü2ÃsoF¸?¤;ÓëW?5FšÖ Üœš6wÙ®¨Š¦=¤pò™&m>s#m@ ´FµÖú°XïsàRà„ ƒzk¾©ù­*‚&?<‚Ù€î^¨8l¬j“ª¯^½þÆ”Ÿͩ' ,8» 8ß©?-šã~_ÚÆÊS–¦ õ•]ZeÏÉíîdŠçŠRéàs^žuÈ8¡b¤°c[”E‹û t‘Üäûvf ¾¥I¿¦oÚôÐÎ çO"Cw2ôf•^$—c–‡|‘)¸úIäôù ÍOÅ5 6¦ó“ESKË­H‰ ª[+°Y!Ý^T Æ!…:«Lp¤£ÄŸW_4†ýæ!­ª¼4Ìwu–ƒq °úW[c³èóIÉ!è꣮ÃuçD +<¿8º`oŠÂ‰ýT´õÑ"bZY­÷¸7‹¦ö×§­Ñj³/ÓÓdMzoy—7]%mÚêíý— ÔBp€Z”ŒÊYü‘>‹)»pÄSáôÔ‚.ˆaÔ(a»ü~‘ú,–#$Oå—íL 1„³Î¾ø¶Åý\à" D‚bì:6d y³9ù˜ãþ"GÜJsÎÞÀMöüNù}ÈçÂîo”ÈÏvA-’ÎùŽ1á,aŸë…ža¤ýkKFy?·"Á‘Pèá(’ÄIwbÏ‚!“Þ? <Ä@Eçn¦…Ý‚ÆÃÂÖ|Í)ë7gQÝO¶§³ä(¢x–]°öŽÈ{îòP¼7&V¼{e­/ ¼³u—a{Ô ƒ#?/m7oEX1Ú0}Ó¶Íw{½6ÜÇÙœŽxnA?V¬§‡¢œ„G«Μ÷oaíS^-âl Å2>_}ªeüòTF¬ôi½†ˆò‡Ùÿðr>êYvžìD¥óžì@§/ªôN¡Œ;ìâ21 ©©vënš;+„-– )5–áïUÝýdZ +˱ÌA™ˆIÓÑ­dÑÃ2å±L9,SCY î±Mõ± sô87l`íÙbØÁ¦ˆ•KX˜ÆÚfÖÕï;öHÚ²ÆÍ¤•,BÄ”õ¸%ŽhÏ69<½Ìð-k@ZëÝå.Áèñf+8Þ)yÁ×éS-c…§Ò¢×m±=ý_Å»guÙ¡ÄD™ó(1ÐæÛ¼É]ãõ›ÛW/ÿ5ÈÑ6KaÐÙØ‡cê[,<ÍéÖ¾Guf핉}º|æ #ËrzadO5z˜! ñÍÐ`lŸÒÝZÊ™ì4úãÊÆS€B×¹cÐn†"q÷¥2ÈjKUÛ†TA=ÿX4mQÝw<ú£6ö†€‚™‡|U¹ f’$(Ë“çq2-écnÚŒo¥±5’[±Oc~ß:?Új*Óšš†íðcš—ä‚“Pú[š~Êj yÁ |õ÷OON^ÓÃbhNMµ4gƒ¾Q€Ö긻3ƘÉ4×Ä2Äœ-¢ ;^4´é³cx£‘>ÖEÖŒ,¿Ês—²™4uîTÖ™>ï6½¼a[ìÜ€“kO»”Ëû‹r€y!·Ð§:³¿•Îí·iÛLÓ­ ÎrÖSMÇn.&Á‚ÿ„qó¡h­.ü‘e -~Ó µî7&0Ú[T>£‚]8˜úTËÊóT8‡_ùáTÖËàtväœ&CσÓ`ìÛë„õý½Žt˜2²`v4\ ÁxðÃäÓaƒ[mÀM:JbÞÙ²¶sþq_›¢-O¦=+ÌÝ´–eì⨌¡‰{ݹ};&¿÷o׳ÇõáþÈì‡ÌÝe! foTg èºëuý2Ä>K™1EX¹ ‰Óß O`ãoÂTJm@ß8Æúomt3¬%'°Ók},W\ÿ2-Äø¶nêÉöŸ”éTpƒA/£&èíECFùý´I¯û3ë5¸J3²mÞ}±’‰œ ‡’. +{DËöçˆÌÑ^ïý•üÄ*D4"QñÙÁ=Ñdôá R°×„ †¿Ñà »4]Ü{;…±*Á.ý€¯pôùA“ 9:¥!µ~{‚{ÎègzXïåc›§4Øøýxÿ`ºXœÆ>»†åú`Q°”;ÁWÿ|ù-°—€À +.ø¡i±"ƒ|çÌ´£²D9»W>kè:•Æâ•öÿ°³§ô9R¬Ø»dða¹}õ3~!Îð1€Ùæî•ÅÈU€øRŠÞ-?²=¡¿G¤°·ÔàÙçLS%ý¡/,gûbo“7ÍÒ¿2€áÿÌXõÏ/þð¿9tÿýïâxéjPaŽ +˜X¡p*LNŸz¢F$Ÿýßð3*endstream +endobj 1030 0 obj << +/Type /Page +/Contents 1031 0 R +/Resources 1029 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1009 0 R +>> endobj +1032 0 obj << +/D [1030 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1029 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F53 1027 0 R /F14 737 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F55 1035 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1038 0 obj << +/Length 3965 +/Filter /FlateDecode +>> +stream +xÚ­[ÝsÛ6÷_á·“g"Ÿ$x÷”¦IëÎ\ÚK|3mhвx¡HW¤âúæþøÛÅIA’;½Éd‚ `±Øß.h~Íà¿6:a2W×Y®͸¾.·WìúÞ}wÅÍÒ-ÇTßÜ]½~/³ë<ÉS‘^ß­Gs™„ïïV?/Þ~ÿæ§»wo–B³…Ln–:e‹oþúŽz>Á+­ÿðoüðþö»¿|s“©ÅÝín–ËŒ¼<öÇŸÞÆ}ºù|÷ÃÕ»»°‹ñN9“¸…_¯~þÌ®W°á®X"s£¯Ÿà%<ÏÅõöJi™h%¥ïi®>]ý-L8zk‡Æ$§¥I´YDtBŽDÇ%OL*Íu¦ó$•ðeW¯n–2U‹ºÇ_½ØÝp³¨†ý®­V TËÅÝÆ¿,š¦{êi@ÑR_õÛPíÚ¢¡ÞG;¾+«Þ‘ ‘­* ÛÖmEÝO›ªEé|Ä£d:áW°3d®-¶ÕÊ‘·"U’ +•:ªMáöPvÛÇÖ±C®—RæI–§×KΓ\ka‰û¡{|¬Û‡d~vœ)˜_e×O“1v ZŽÉ¬°• ›A8 TÄh3€H[ü¼|ü|Ä@*“L)yOuÌÀô´S“dBÏ8ø»Er1l*lˆE_í¾V;ꬷ ﺪæù†s¾Œ/>VeÕDRnŠö¡ºá‹žž·Åªò3ÒÙï6Ô±z†ó«KZfÿ¸‚yéEç–»ý×ûǔ›éQ¤‹À׋¶¨Ñ_«5­nqE{ÁŽmѸlÿ˜hªþ*W€,Šìï¬t½9`°Æßê·Ç¦.kwV_‹fFêÚ °—¤>&;-õ@e-­‹«,8¡ÌäüÂÊžêxå©DušdSÓ¥ÿ_egä¦3X8½(·Ù¹y*d~ÝìûÍIC?¿n0ô£uã†>Yø=.\½@peQnΩ”H¡‘›K¢‘§ +¢A1fPaL>róG æàÕl_`ÐS38•a(V¤3ã2|¨¿VÎ8-c¶u@PÞ*OžŠKò“–w "] ûþha~“Cr~aOu¼ðÌ‚xx;YùÛºl + Lx6l»[㯇¶,@[€Þ‡np¯†M1ø–ëj÷Û{ Ê` +šJ,þaÉÍ^·e³_ù§0ªn(ežÌ(´ &œÞÝ×íêõÛï#àoŠABLÁ .îÝ÷j¦ +«j]ì!›8^pR®™\ÉëÛ‘(2Sølj½KÖë°¢‡á¶Ûé…ã§# éow4kÙµˆ@ö4çêŒæBæ«ØÅ?&;£¹ž +w»«Êý®Gß~*;¿vHÀŽÖŽ'`“Å¿ÝogGÙÔ½“Sçdþë¾ÚÕU¬Ì$¹‡ò{«?3Ø6‰½šçÑ9y8 væP„Ht~ŒÉÎЧBŠÔ Ö]ëä®ýo·^vO§Î…N´Èý&¿ÖÕ'IⲦñª`‹F0Ÿ¹%ßÂä‰È¤>¿Å@u¼Å©yAŽ&´Ê§{|×÷ :„›ãïªîß~øôéÝ[jb}#ßш7ébÕö}U.+Z)æi4p&nc§_¤ØÃëvÀ¡¶ðdvä¤Z@§³ªê BBL«Zy®Z€}Ò3xKÝÖº¡YÂÞ‚û«¨¬ÜT•ËÞ†WØ‘º0c'<8} ´~ÛŽ^?Ùè ƒëpiø×zåFxŽähzÓÙ¹=Ûm¬:BE!ÆÕñá é+.¶B¥wÖ™Jâ¢×te °®C W”™0—€Ý:åܵ«2¦Á"1,õH2—r|Q»î#õ“%R4úºÊ׸Z³­#K yaê ëéº`ÉÕ¬bk\Bå!&Å&ó@÷H9¶Ôì{T²/Ü9@+Hl²aí9øÔe¯D)ż“îC³¶½>L>žMxÄ©òø€Žu·oW¯"‡‰Ò‡žåS :U—™ðLº +!ãÎ-b«éº/ÔªÛˆ$2•è”§GGú¥zŽ( Z–y—ý Ó 5'³©ÐU/‘b“ÊkMÿÜ£º¬ê]dþTìÔ¾ü÷Tô4ùªBY¶ÖÛØµl‘Zä§ ñÍí‡o]=–ñ$Õ<›æý¾nP7ÐWá¬Â#:؇Vï¢ZÃAÚ© +à䌜ýƒP³ '§ÎSãâU[íÈb·­%ÁïîÆ,ömë ÞQÍO'êP?Åõ—(Ë›†ÁèeáNXpå­6"íË]}.2™äBÏ”Ž4f‚§‡Ã„\\‚1H´EÐËÝÃ55>Ž‘•§_ŽD çѼTñ(V™p¢b•,™2>á'ZɲT—¸8šÍ&"$¢„ÏŸÆhë½ñ\ô‡L)³Hþåq*¯‡+,!r[7Ån|ÿäc$öt±¢: µD+ÎÇÀú”GÖ9Ú— y)sá.`úV§>Z½k1&Ó÷;§-à%Oóùýè3–SñæB¤Ù‰hÉEÎøÄ­öñ‹26s”ÂH擟rÈMY–½tv¢w"Ï=bšMTÂ…K¹cs¥`hÊÁAfZ@ËA¡zt ùÃ;|V‡K%|ùD0ZEßw%Þ|ÑÙ¼4Ãäbâÿ(R™t +jL†‚ëéEDøK¤Ù¨ ½.¢bkS—¢Ògê<ðÛªhÝô~Ò{¿|rèiyîàPvtoeÚ„Œ…d„Kæ83äôˆ1-Œ0$tf±ÑÓÓyª/ke–N90‡yŽ\l¬sÍÃ}bUÑcÙû¾êÿu镇\DpyRSŒ@ì¼FCðã³ùND)Èð Ïy¦Nh7DžÃ¶ý¬ÝnˆM«’Ì(ÏBsp ð³9×’‹$Íæ÷©'å!ì=¹‡/CñÅ&òô³él…Z®DÉÝá"Éjår?Æ>>ì݉bM+ A„ŽÞ©#÷;L±ü½()ô ÃÖ½£Ç<%Å}x´µ*䮋xö¥ßÝÄ”—ý °š33Ñ_´å§':+zCÚ£XûÂÖÕë4w­5×X@õàÜÅË4 ü+3bv¾ë>£ÖÊ¸ðŽ°‰wƒ7€æšØ”:b’2ñž> endobj +1040 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [120.1376 318.9001 176.3563 328.1154] /Subtype /Link /A << /S /GoTo /D (controls_statement_definition_and_usage) >> >> endobj -1029 0 obj << -/D [1027 0 R /XYZ 85.0394 794.5015 null] +1039 0 obj << +/D [1037 0 R /XYZ 85.0394 794.5015 null] >> endobj -1026 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F48 940 0 R /F55 1025 0 R /F21 702 0 R /F41 925 0 R >> +1036 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R /F41 935 0 R /F55 1035 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1034 0 obj << +1044 0 obj << /Length 1676 /Filter /FlateDecode >> @@ -3231,78 +3249,79 @@ x ¹#„@Ë1!ƒìTÛ•mÕLæªÔpßÔ8ÔBZ»Ï\Ðüp—ç6ºàS[êë¥eˆHh" •êƒi¸ 8”5!lK-ñX*+k°¨’ìö~ÀšVU”?$ì!E4 hÔtmuAë" M5À1óG„à°›äéća¦ïl^FƒhÓ C('骉²6Þd|u>ýÅÜÕv?,h×gá¹'ˆë”ZÔuJýº2;šè£{»LãL06ë(nç»ïœ| gu¼ÊnÌ]¹Ü±¶Õ"µú› ºì­‹òN;s'òYu©µùÿÔ¡¢HH!=%so£t9={qõf7FD…œy}ÏÉN倗ÛI Ñ•±å扆½3NoP;²ý,â`€ ñ dàg3»î¸’DPQî¡-€ù†õˆdŠ!róŸú_E0}L3`ՀЯ ˜{ÂÈã<;½xuÂ=•á=7‡!Ü÷óÁŽóÔ1e×HÓ?²æ0Æí¤ÿoŒAŸPRð¯`ŒRÄE@Ʀç³Ãëi|4ˆíy9 ±¾›ÿÄí¤ÿˆH8$„‘ fE±ýrï[%üSEBaðšÂ,Äà'Mì}µý€ºù® íIy€r€d`>b¦¤ui4¹÷y×}iµR=×ÿ„­gÚendstream endobj -1033 0 obj << +1043 0 obj << /Type /Page -/Contents 1034 0 R -/Resources 1032 0 R +/Contents 1044 0 R +/Resources 1042 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 999 0 R +/Parent 1009 0 R >> endobj -1035 0 obj << -/D [1033 0 R /XYZ 56.6929 794.5015 null] +1045 0 obj << +/D [1043 0 R /XYZ 56.6929 794.5015 null] >> endobj 126 0 obj << -/D [1033 0 R /XYZ 56.6929 424.8255 null] +/D [1043 0 R /XYZ 56.6929 424.8255 null] >> endobj -1036 0 obj << -/D [1033 0 R /XYZ 56.6929 397.5211 null] +1046 0 obj << +/D [1043 0 R /XYZ 56.6929 397.5211 null] >> endobj -1037 0 obj << -/D [1033 0 R /XYZ 56.6929 368.0037 null] +1047 0 obj << +/D [1043 0 R /XYZ 56.6929 368.0037 null] >> endobj -1038 0 obj << -/D [1033 0 R /XYZ 56.6929 356.0485 null] ->> endobj -1032 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R /F48 940 0 R /F21 702 0 R >> -/ProcSet [ /PDF /Text ] +1048 0 obj << +/D [1043 0 R /XYZ 56.6929 356.0485 null] >> endobj 1042 0 obj << -/Length 2335 +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F21 710 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1052 0 obj << +/Length 2367 /Filter /FlateDecode >> stream -xÚ¥XKsÛF¾ëWð¶`•9™7€ä”õ#åœZK{ØJr „´#ÿúížžÁƒ„äT¥T%6æÑÓÓϯGl8ü‰MfW¹Þ¤¹f† ³)7|ós?݈°FÅŒV ->VfwFeÌd2ÝìæLþ}wóÝ;)6’3k¥ÙÜídzlš2#­ÜÜ•¿&¯Ýq¨NÛ4<ÑÛßï~¦mš¥Y*p‡#R&r؉~,?»¶¨JÚñæÃ-ï*7œOU?rš)‡xÖ0asã9h&¶;Á9O>tC½ -[Ô&g¹•6ìPœ¥:³~‡?E)›|øåîý»ÿ]÷ø›&Ž>UñèÚº?Ðçðè†0ß4Ý—>,r½¿,Ò}uú\ÂÄÐÑâ–$ -,ª:®mÜçêj[št{Ä£ª ^/†W‚対¿vmõ/X(•IJ78k¹IÞ·4tÚŠ,©úc×ö 7üu£f'5 i™i‡ ï kujÁ¬ViX¶÷‡t‡È×ÿDÍ MWܦ:y…j"ÌüR7 QÅcU|Z -ÛWQzo¤ê!ܵWwá¾ @TÒNؤ×](‹ÎïB­…VÇßqª8ŸHií@øpmù*lÜÓ/X8Ž´õP»!ðq—' '×ö{ÒM™ƒW Š„wzO“CGÐWÝî»ÓÁ ^p÷Ýy yÅŒî,uú-3*8œK–½"–^ÕHx QV}qª“ÞKÊ5'‚H"žÞ>“jt¢nÆ¿nqùÍÛ»)e¥‚A(‘ &ŒÍ1%ÑäéaCÄÇY×ïæ(‡-ùŠ/Êr[“0–IH5b.DÓäü„’éË‚Ä\ªmÎ$å¡àlà:ÚçM±Éh Ck,—Ó:*uÅFpL¦µÊwMßíž5x“ÍUt“kã@ƃ£&¢ð/g\¿›o¸ÖÉ5ß…qðªÁ8é•HV‹…@W¦ k¾%Ä'ÁçØ,¹[u¨tPõßH¡©æ6,;R -º¢kèf>/ ûcUÔ¿q.¡Bú̦ ô¥ -Ù"³Õ!?}|÷š¨¯–]ªeô2ÒàV¸òŸ7¿þÎ7%èççÎTž™ÍøàX¡åæp£…dyntinnoþ3r„–)fHXçEû8ð -dܱdµ‹Òí”æp3µ°ÈxÙý&Çü’A̘’šböÃLÇÆj4gÿ²ÝY‘ÜÁ™¼½Ô ðÔDS¡ ÷Qºùs#×y®hÑŒöwtà¾{›7Üh3»Td¼›sö—,3Oš)ã©2È5†l„Ng¾–ä9VË­„‚´•‹Î|Ý -Èmø*\K+1 iè¾Z°Ë2 aI™ã´rB¼}UPIëUéiÜã’'Ú[Vû­‚bwn†°²¯Ú2 6{ÁȆ"ÆVód -Ž…6 0i“‹`¸CÕ÷. !øó|¥„ -?HZ_;µÔL-¸ªè·é\é/l„Hn1¶öOuû°"¯äY¹¼(cžOP"ha×µ 2|úaå¹b:S&0ðø†"X¥ŸŒZFpá΢¥)›Ho#ø…sžˆBý®ˆ+Ip+ò1Dތå\E”7*¹þ‘N¾ÕQzU‡ß™>/ëuWT à<”ÿYvÀü:ú9TÃcç}'{o$œ+KðYD% *W ûù¸®¬šjGiaAز Çøº1;.šè€Ú=}ÿD"€‡Š¤-‰'|ƒ'¬ô$úúÒåú@ KT·¿hõb|cYÜ—Õq‹FÜCS柱‚ÖWKfKt?¯¢«_ÔK)”]E壥À’s°” -ǪÖÝ7È?PQ~²-š3é ‡Ý<Á4ö(„A_¹;?ç@V±Ô¤0€×7ËDãš8íŽ]Sk°ÎZèÚÓ늆òJ‹ÊQQ^Ÿb!˜ÌØ\x°yÍ\bȨ˜Áû%¡ì§e‘ùÒeÐný5uX¥Gçy~¼}ÿÓ+šÿ[iå»0¤ˆ¼Làk™ws{h‘¼ÅrJHP·‚ö{tãµ`ƇŸ -ÐçÍÓôCÕV'wʼnü.·S:jùµ4¥ná%…Qð¹-ø7B0­g¥Ï ²[»¸Ù©þÞ?æIýÞõÑ/ã”cqÅ´¶¯Z|H¤g°‹Z]½úë>Y·¯tpVx|‰œZ¬êÐIK_"åø9–±?ºó©ekPó >À@p‚?úÇ03{ ”ÕÊŠ†)¢-•Z;¾2™Ñ0XNÀdª\~Óh~ØÐᵩ¤IªŒ6>ˆÙé…ÏîbÃ]°jË®Kf‰ÃYC[5îÜñ„J -%8 ܇ ’F¨É:@y¬Ú‹i<üä|±ô=êw¸O^«@"vÂk`?s!'ʧƒù“ÂM˜¨/b’’/ÂpzÞñXEÃáé&Oª¶ßlôòU:ÛÔÆšÊþh× -¾àæZÅZÖÍÀ -@ׂ!z6šMAb™^‹'ÙâkR>3,OΈÀZøŠlIO°›ó:Ù…Á;°Þ©.¡b_½µ8YÄ{Äl^Þ×­;=½ûÇîÜ”ã+í²¬Ue=ÄìqpíÙË=ÆùÚ£‰2L#¤Y{Kš:‰iÑÊ[‡â™nd… -ù³/‹+'þ¹ö|endstream +xÚ¥ËrãFîî¯Ðm©ªQ§Ÿl29e瑚&µcïa+É&)›ŠTDj&ž¯_ ÑÝ$%Ú“ª”«,°o@l8ü‰MfW¹ÞØ\3Ã…Ù”‡¾y€½Ÿn„?£bF++»;£2f2i7»9’ßÝ|÷NŠä,M¥ÙÜí#­ÔZfd*7wÕ¯ÉëÇâ8Ö§íNžèíïw?Ó5Ílf^ã@Â2‘ÃM¼ðcõ¹èʺ¢o>Üð®.Æó©"¡™ÒHÄaH inÍÄv'8çɇ~löOþŠÚä,Oeêo(άÎRwÃQQ*M>ür÷þÝÿnüµIAŸ‡º|,ºf8ÐçøXŒ~¿mû/ƒ?T î±õés}òcO‡;âÈ£¨›p¶->×W×lÒïiI?Ô¸ +|>E–CòþÚwõ¿à T&©Š±`p–›ä}GK§­È’z8öÝPÓ +bÃß"Jv“)SÂf@q{é\‹S –jeý±½#Ò^÷$ƒ0=qkuò +2”„ß!9 ø¥i[‚ÊǺü´dv¨÷N 5£5J¯éý{A€(¤H-p ¦»ÑëB©„ZÇ߸UžO$´n¤… ?|]õÊ_ÜÓ/h8¬tÍØ£ÇS\ROE7ìI,ª2«ä ïz´n“COÐWÓíûÓ¡¸PÜ÷ç‘@4ä5x³Ôö[jT@œKé½"”NÔ8‰ PÕCyjŽÎJý‰5#O"PïžóItH¨Ÿáo:<~óön +YV0p2Á„Is I´yzØðqÃâùÝüŰ…!_áE^nërb&eB „˜ –b˜œSx!˜¾ÌHˆ¥:Í™ä <äŒ LGoœ *¶"‰ÚÀ5ÔÆâ79­ƒPWtd2­µ~ÑýîYE5¥¹ +fr­ˆ p”D`þeåÄó»ù…k™\ã](Ÿê•c¯XÊ0[,ºR?ó-&.0! .ÆfÉݪùC¦ƒ„¨ÿFµš§þØ‘BèØ—}K/sq T8ë²ùs ÒE6©Ï +Hd‹ÈÖøøôñÝk ¿¦ìR,ÑÊ€IƒWáÉÞüú;ßT ŸŸo8Syf6_àƒc†–›Ã’å¹Ña¥½¹½ùOÄ!,S,õEÂ:.ºÇ—Ã%ª]àn§4‡—©…Fâc÷›ãK> kJjòÙ3›T»JCpfà€—ñ/Û]*’;ø/“·—’œZk*ÅÒ„;/Ýü¹Œëjü '»œ¸zMÍd‹§š‘~Û¾¨œd +!’[tÐýSÓ=¬IŠCÝËåE.tx¼&@»¾káÓ+¯ÈÓ™2+’( ( 5¸å" ”Åy¨×øÀ2#·ßR˜f™ÍBõçÌÂytíA¨ä&­Šï%d,ç*PˆZ@äÑ2’èÓ}5þw¦„ËJ!¹(àoDþY\ÂhrÈÜ;÷GÍe¨ ‘8´X³N'œ“ð*)­ow¤owÞ<&›’þÖžßî}â¥4—ì2üôs¨ÇÇëË“½SîU::+±T¤Û¢Dãwûá\U·õWé`IUmåɸŒ5#Ô°ï|ÿD,€Y‹¤«'|ƒ%¬tC¾èvI³hé«g‚úýE“‚&tÁ]BWŠ1Vüá0´ƒŽü „Ρ^"[öóüí»„‹L-…JWû¨)°†äì5¥|m€kuWÜ·ˆ?PPn³+Û3É —‹µò*¦±; +åt´»ós”*f ¥ +hq­æg™ˆ‘ƒ0íŽ}Û”keš2#m((ËÖ-Ç- +GùZöšJ +Îdb[ãÊÜkä]F…°?ŒÈ …L QЙ/Mæè_sõLA§¡‚Ïcì?ÕO»Ðô±Ù•§º‚Ûhi×|®pxî!t.å–C"M³9îª?M·&5ˆgBd ©¹ú@MÁï3b“LCýºh´†µ† +!ä\rê‚5ÙÚDÆÞQ}B’ +±ÌÐ.‰`—\?ô³æûîàhT¼pªËÇà6ÅHeÃ¥>x]³jßûy«ëoÚ£aÆNèª –¥FÿM‡Œ bÎf^>6eiéã.û –QT±Øƒ—ç0pù0äB›üÆ ÿ:¥Æóà/»YÀíÛ×°/hkßûA~P´SŠsûý»ˆäãÇÛ÷?½¢ýp•P¼óKŠÀ˾y÷¸·‡æÌi,§€yËK Å"> vŠóØã`£y>Ñ>m?Ô]}*®0‘Ýåé” @|-AÅÒtž†o†aln öu›Ö³ÔçÙ­½ ÌìÔ|õ“—yP¿/†`—aËMwŠr:;4Ž0iw‘K‚©×Á&oÖñY{c%†ã tj‚0«C/e˜Ê8iìþ|êBÄÔ>S`ó!8•?º1œ™Í ¥Áq^UÓ2ytJ©6ó-‹ÕT˜L™Ë]Šê‡ Ãèç\mRfLÃ(.f›pxö–Ô¿³¶´ð\RKXöÈüÚØªrç†'TR+Þè`áÞo7Díüå±î.¶‘øÉ(ø @ÅRÒw”Þ(>9©ˆµ>Cæ™×,buN s“<ÁÖo4>IÁË÷íë(´¼ã±e,û¡Q–8ÖݧEz9O„žÚ¦!§²?ºµ„‡³ã<6…ÎL"Ìô,X¢Õl Ë4§žx s¬|¦Xžœ±l¡Öº¨¯H—4ü…²9·ü¢7êA{§¦‚Œ}Yî­ùÉÂßCÍæËËû¦+NO/”ŠÃcn«8^¦µºjÆ=Ewv|G?_×(Ã4–4kS¬©“˜­L±8$ˆt +DäÏÎ4W(þpu˜endstream endobj -1041 0 obj << +1051 0 obj << /Type /Page -/Contents 1042 0 R -/Resources 1040 0 R +/Contents 1052 0 R +/Resources 1050 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1056 0 R -/Annots [ 1046 0 R 1047 0 R ] +/Parent 1066 0 R +/Annots [ 1056 0 R 1057 0 R ] >> endobj -1039 0 obj << +1049 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/usr/local/share/db2latex/xsl/figures/note.pdf) /PTEX.PageNumber 1 -/PTEX.InfoDict 1057 0 R +/PTEX.InfoDict 1067 0 R /Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] /BBox [0.00000000 0.00000000 27.00000000 27.00000000] /Resources << /ProcSet [ /PDF ] /ExtGState << -/R4 1058 0 R +/R4 1068 0 R >>>> -/Length 1059 0 R +/Length 1069 0 R /Filter /FlateDecode >> stream @@ -3315,12 +3334,12 @@ q n*Œ1½÷¨¾x¥Æˆpîâ‹&Xîܧ³±è\íD¤ßä0}#XŒûž˜‹¸À>#^V°¡|2Îi‰9ÊÎr)`˜¢Xh¡Ò& „hb—H°Œe"Ãêʱ„£~Ï“a³tŒºìZDß!#Z¶ÚÂk! e'jÝ=§ _tsÙ¬ûÍ&­Nå@‚i¬ˆ3t%kÐE„\H–YZxÿ/U¥Ç™åë—Φ@±¯iW H þrÓGçX5¾ûû8‡´ÕªOª«t–Ô³$Ây°‰—BÒ›ÀÄ5©/¨vp÷o`kA“ôr ±ñœÓ4N.4Žæ&F°ÑTÆG%V½ Î'ÌØR5¬BÔ‹`qUžv-UÍ=ëÆåQv2ë_ ”¿­qq‚~èr¯Ú5ÌJ¼ð˜°h»P¡õ‹kÜàéÚýªå>Ò¸D °o»Îi¸CrT]¿MJ¥ ÆÖ¹’°;¿ö‹ûóZ¼¬ å[Ç-œÁ¤ŸBx¿ýpü|üÈÂendstream endobj -1057 0 obj +1067 0 obj << /Producer (AFPL Ghostscript 6.50) >> endobj -1058 0 obj +1068 0 obj << /Type /ExtGState /Name /R4 @@ -3330,56 +3349,56 @@ endobj /SA true >> endobj -1059 0 obj +1069 0 obj 1049 endobj -1046 0 obj << +1056 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [470.3398 477.3512 539.579 489.4108] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1047 0 obj << +1057 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [316.7164 465.396 385.3363 477.4557] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1043 0 obj << -/D [1041 0 R /XYZ 85.0394 794.5015 null] +1053 0 obj << +/D [1051 0 R /XYZ 85.0394 794.5015 null] >> endobj 130 0 obj << -/D [1041 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1044 0 obj << -/D [1041 0 R /XYZ 85.0394 580.0302 null] ->> endobj -134 0 obj << -/D [1041 0 R /XYZ 85.0394 580.0302 null] ->> endobj -1045 0 obj << -/D [1041 0 R /XYZ 85.0394 539.9341 null] ->> endobj -138 0 obj << -/D [1041 0 R /XYZ 85.0394 315.9171 null] +/D [1051 0 R /XYZ 85.0394 769.5949 null] >> endobj 1054 0 obj << -/D [1041 0 R /XYZ 85.0394 282.0038 null] +/D [1051 0 R /XYZ 85.0394 580.0302 null] >> endobj -142 0 obj << -/D [1041 0 R /XYZ 85.0394 146.7217 null] +134 0 obj << +/D [1051 0 R /XYZ 85.0394 580.0302 null] >> endobj 1055 0 obj << -/D [1041 0 R /XYZ 85.0394 117.3479 null] +/D [1051 0 R /XYZ 85.0394 539.9341 null] >> endobj -1040 0 obj << -/Font << /F21 702 0 R /F23 726 0 R /F62 1050 0 R /F63 1053 0 R /F41 925 0 R >> -/XObject << /Im2 1039 0 R >> -/ProcSet [ /PDF /Text ] +138 0 obj << +/D [1051 0 R /XYZ 85.0394 315.9171 null] >> endobj 1064 0 obj << +/D [1051 0 R /XYZ 85.0394 282.0038 null] +>> endobj +142 0 obj << +/D [1051 0 R /XYZ 85.0394 146.7217 null] +>> endobj +1065 0 obj << +/D [1051 0 R /XYZ 85.0394 117.3479 null] +>> endobj +1050 0 obj << +/Font << /F21 710 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F41 935 0 R >> +/XObject << /Im2 1049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1074 0 obj << /Length 3348 /Filter /FlateDecode >> @@ -3401,54 +3420,54 @@ A ©mø¯(¡Ÿ¡AAÉM@rgJ'Ï¢«PÅ*s5M¦ õ@¬ðù T$±/ãx¬ÖÊ`¡ð+|*س«ñsröçÇI_I!Oç…DòV»·¹à ;“_q‘©¨´ž9k¢Vó2‹T…Kd'çiÏ(L5Ú&uU¿¥ÖÜdpÄ©)AìÇy‰M‘#¾ÿÈ5H% b“ Ü6è;q* ó§ñº«¾¸Ë8‹W‰=öÃO¿PÚ¾þ-ÿ.ˆî˜ÕšÃ0«QΩ\þzÄwþë§‹@Ç‚ÎWlb?@~Hš²ôO"BúøŸ •¶`´—ÿûHNÿf+_¤i´\²‹TêÇ)ÂD!ߢà‚r÷Ÿ&—¤ÿbÈendstream endobj -1063 0 obj << +1073 0 obj << /Type /Page -/Contents 1064 0 R -/Resources 1062 0 R +/Contents 1074 0 R +/Resources 1072 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1056 0 R -/Annots [ 1067 0 R 1068 0 R ] +/Parent 1066 0 R +/Annots [ 1077 0 R 1078 0 R ] >> endobj -1067 0 obj << +1077 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [464.1993 488.466 511.2325 500.5257] /Subtype /Link /A << /S /GoTo /D (proposed_standards) >> >> endobj -1068 0 obj << +1078 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [55.6967 477.5271 105.4 488.5705] /Subtype /Link /A << /S /GoTo /D (proposed_standards) >> >> endobj -1065 0 obj << -/D [1063 0 R /XYZ 56.6929 794.5015 null] +1075 0 obj << +/D [1073 0 R /XYZ 56.6929 794.5015 null] >> endobj 146 0 obj << -/D [1063 0 R /XYZ 56.6929 556.0057 null] +/D [1073 0 R /XYZ 56.6929 556.0057 null] >> endobj -1066 0 obj << -/D [1063 0 R /XYZ 56.6929 521.4772 null] +1076 0 obj << +/D [1073 0 R /XYZ 56.6929 521.4772 null] >> endobj 150 0 obj << -/D [1063 0 R /XYZ 56.6929 361.9951 null] +/D [1073 0 R /XYZ 56.6929 361.9951 null] >> endobj -1069 0 obj << -/D [1063 0 R /XYZ 56.6929 325.2573 null] +1079 0 obj << +/D [1073 0 R /XYZ 56.6929 325.2573 null] >> endobj 154 0 obj << -/D [1063 0 R /XYZ 56.6929 133.2872 null] +/D [1073 0 R /XYZ 56.6929 133.2872 null] >> endobj -1070 0 obj << -/D [1063 0 R /XYZ 56.6929 104.8892 null] +1080 0 obj << +/D [1073 0 R /XYZ 56.6929 104.8892 null] >> endobj -1062 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F55 1025 0 R /F41 925 0 R /F48 940 0 R /F39 885 0 R >> +1072 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R /F48 950 0 R /F39 895 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1074 0 obj << +1084 0 obj << /Length 3001 /Filter /FlateDecode >> @@ -3468,29 +3487,29 @@ I! “7 `©gŒN¡wbAÎÇü&ePÁ†¬¶ÿL„N|&‚šÒŒ†¸;ô3½ú ¥G=û/mýù©ÏlJ~59ÿÑ0†r_Å (ˆÊZá¢jA¤ãC1×Ξ?µƒ:>v”¹ÃX'Ãc¿…Ì‘.Mi# 'øËQ|¢$Q†™„«Ëe¾J­yBÙ¥ŸY“¼Ñ Ì?%Až2®­½ ÁêŒÔe ž;5’àøØi ÆÇþ/%x¡'(ÒÄ>£‚~J›PfÃ6ãIAJkYzIŽÐi1 ‹R¨ËŒ:wjÄ©ñ±Ó¬Š½éJ£Â1|öë?ãåg†Ç™Æ&÷Q>´ì2ž$£²®ÏOòÿTÆö¤ "•†*Î\ø%J uFF게ÎÉh|ì´Œâcÿÿ‚ ä•Pn»ÎK0‚:#ÁuY‚çN$8>vZ‚ñ±—­ $ZWÅ“¤h$ƒÜ.}’“gÇ“ÿRŠkáÄŒgÙtÒ ©Ù—jêä¤:êäÀ¤+3°–ñß[qú4´SlýµÎ`xðKÿpÂp´.šÕ¾\Ò3à¨eý€¿‚Rdþ¦n‹€*oÃ(žþÇ81E“¥eG£|$þbT† ¾ÇNo2æP`Žê,Z|¬ï÷ýOƒ¢Š£m¿¦(Æ*­AV+;øyXRð¤Íýû ~Œ”»ƒ_Ä/+÷1^dÄ[¬†Â­GÔ$œ ‰9²¯t‰‚1®è±²ØŒMÆõužFµûñ'š‚Zâï)HèùjK; šþË·S€MüÏ?“ú ¿˜á¢e"^ü÷A§B3p€>Õ!zßRX”»fñ¾^lŠ}q¦¢{‡àޏŸ9è_1v:¿7 ½8!2øóÖð»$Ùût E«µrZøŠ'ÌÊ, D!éòHݺ_S“þCHá endstream endobj -1073 0 obj << +1083 0 obj << /Type /Page -/Contents 1074 0 R -/Resources 1072 0 R +/Contents 1084 0 R +/Resources 1082 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1056 0 R -/Annots [ 1076 0 R ] +/Parent 1066 0 R +/Annots [ 1086 0 R ] >> endobj -1076 0 obj << +1086 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [417.8476 181.7231 466.5943 193.7827] /Subtype /Link /A << /S /GoTo /D (sample_configuration) >> >> endobj -1075 0 obj << -/D [1073 0 R /XYZ 85.0394 794.5015 null] +1085 0 obj << +/D [1083 0 R /XYZ 85.0394 794.5015 null] >> endobj -1072 0 obj << -/Font << /F37 791 0 R /F39 885 0 R /F23 726 0 R /F41 925 0 R /F14 729 0 R >> +1082 0 obj << +/Font << /F37 799 0 R /F39 895 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1079 0 obj << +1089 0 obj << /Length 853 /Filter /FlateDecode >> @@ -3498,21 +3517,21 @@ stream xÚÕWMsÚ0½ûWxr‚ƒ…¾üÕœhBÚf:™4¸½$9¸F$Ì›X& íô¿W²°‘ƒ€PÒÎt˜Y^½]½}+VȆâƒl×^ˆCÛ)p!rídjAûN¼û`¡¥S9ºÕûÈêßAèaÏŽÆV` ;]w(  +`gxùùSÔu° ;§îƒê“ýËhp¥ækÓþé·.B¨Ó¿8œjKäàlÐïú´}½ »·Ñ¹5ˆšHõÝ Hd˜Öõ-´GbSç$ \ûI<@€ÂÛS‹º¸”z&µ†Ö—P{[-5²ƒ ÀÄÃz(Òè ð €òÝx“Ѐ܄@r¡ëâjzœOq1ê:„)ì¹ÊHòéÑJjoÈÔTH¦ÎP…%}Ôn[þËŬµÆ,óI |4í­tlÚ¶¡4…zFGy-ÃbZׄpQÄåäQŽ}*j8ÛAiÊÓyÙdV*r…Y¶ê°‘§cÆ<@¦Eo¬9ƒîª°Œ9z•Fð¾áiüÈö“Hµd—Bxo=#=Jpmy äñM6P‹w¨kãð_f³Ié›—rãaÏ:>€é½ÿ£ÖŒÄ"#±Ô\.¯!R›xŨÿoä䟥¤w&z®U;&\ÑÕQÑÂJ›AÓÉ&SžâËÆGMÜ缬Žïv3ªº'5NòìB|÷N9kõ~/œÅIjda-°‡érƒ¢³“@ú¤Yl |s¤´àN ùLšó'ÀŽäÏ[Bì½eK¸]—q¶Ð]»PïØ8ž§Ûš?Óe„¸@Þ WØðxðEeuG£> A€›;HKôØ È2(ÉÆk‘×7šõЫendstream endobj -1078 0 obj << +1088 0 obj << /Type /Page -/Contents 1079 0 R -/Resources 1077 0 R +/Contents 1089 0 R +/Resources 1087 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1056 0 R +/Parent 1066 0 R >> endobj -1080 0 obj << -/D [1078 0 R /XYZ 56.6929 794.5015 null] +1090 0 obj << +/D [1088 0 R /XYZ 56.6929 794.5015 null] >> endobj -1077 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R >> +1087 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1083 0 obj << +1093 0 obj << /Length 1946 /Filter /FlateDecode >> @@ -3527,159 +3546,153 @@ eS ^Ebêf›C“Áš‡Gô¯ÝàÀ7Õ?ú¦ú¦rSª+a~žÄä'¥|«ŽcexÆ ¥j3Œ–nˆîʾí88Í“¡¡=# ½}[}y´b&fqšŒ Æ¢ècç(»î»º„&œ:þ$þý€!BìøYãf2JE8<æ8‹án‰g8iZ¤Š°8pä”!í·§Î £g²z÷óõkç盀Nd3$ÒÒ:Œ‘ÌSoëÛÉÂhõ×ƽنÊC6ˆa Äj70ê*xc§mš_âç^Ýæ M>1:C‰õ¾î¹³S©:nJý5/ûò̃6ðEµ·n憥 R±Ày‡ßˆ*Q$ÔLC-ÈKúüE¦»a´NE\–Ã,Ô ç2,’ðq=c³>å—š–‹c9Èq@ãèôãiP§™¬j¡â8ðâ…>®Më¡Ô©SfC·üé¥b0ú»¿ÝoøÁ(÷žû%Î þ|6ó»™{®×ÿ÷¯t—Ÿ%ýút¬Î?ÀMòËsCjÎ,ÚCyO%?ÿœ÷­èÿ¢ „êendstream endobj -1082 0 obj << -/Type /Page -/Contents 1083 0 R -/Resources 1081 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1056 0 R ->> endobj -1084 0 obj << -/D [1082 0 R /XYZ 85.0394 794.5015 null] ->> endobj -158 0 obj << -/D [1082 0 R /XYZ 85.0394 427.2881 null] ->> endobj -1085 0 obj << -/D [1082 0 R /XYZ 85.0394 390.6298 null] ->> endobj -162 0 obj << -/D [1082 0 R /XYZ 85.0394 229.0656 null] ->> endobj -1086 0 obj << -/D [1082 0 R /XYZ 85.0394 200.0179 null] ->> endobj -166 0 obj << -/D [1082 0 R /XYZ 85.0394 151.3455 null] ->> endobj -1087 0 obj << -/D [1082 0 R /XYZ 85.0394 127.291 null] ->> endobj -1081 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R /F21 702 0 R /F39 885 0 R /F48 940 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1090 0 obj << -/Length 2296 -/Filter /FlateDecode ->> -stream -xÚ¥YK“Û6¾Ï¯PåbªlÁx|Ä•Ãx¿Kÿõ¼iÙç/4㟗×?üàQ›טYùûf>cWÉ O„µØ7ìÉBABH‹¦~l/gßó#fÇ¡ÅRIbÈÛÑD„p4v‡#|¸'ÉLåÝCuûb<.äÑ0ýì”{·öüà3•º‰ÁEø –‚;`»lF¯O\_(ãÉI™¡‰ì=K€7EÝé“Ý>0ŒHiNÆÎáëºøSƒ¤0`#Hf!§Uæ®,Ŭj%Õ6 æ`s31³Kµm¶¶3ŠuVŠuž EWRª›ý _œë¥!ÖKª[«¶Mþ„zƒ¬3¨¨0ê¯éêkLHÂD„¡ýb¯öey8n£œŸ/õ‘—Áùíu{ºŠQSµçD×û´Ú?µL -C9¹‡h?ƒÆÃxÿ¥Í£òE¶‡ M”˜-¶²£ÓÁ­G Îóî!Ïkìt 6^˜Ùú EoCð kŸÄE•jWû¶Ãõçf´kJ³ÃÃÆ.F¤®±¢à×–UPLÍ6^<›Í»Åéã`²Hü¯8l+„¯ÒaDÄ,½Té0"ãÄr™¯8-Ħb&ˆ%Ûã8Žï×XübeMǨºYá­0DÈH$e:„fëUØé_©0˜MžÖ2©O^ýí/ø“‹†÷Çkkœš-y Qš47C[cÕObUÚë/2—Zh¡7`ºòý®5ãÚpð5Á*ÒÈËÀy -mÀ·lr3£n:ä‚€ë2ý Ô¬6Ûký€ ®Í0˜;gñ²{‚gQS£åäPzïÄS_t¥$‰¸\À‹Û‚ìºÔJ#È(8‰bÅæ©†3좰_öyk,¥³y0£—ÚJáÑMƒ=вÄÖÜ ;hÓ£ú[R»ÍG ž 'T~†â‰Ü=_>íªcÄÔÏ• @g"ý2¬pG¤¦Vó}N£øà…NÁn ”ƒûø4ÕïýzÆ\µÝ“„êtPCaÚa1áx_–ýtCBQû.x1ÔªQxñœ ÏÜí»VÎ[ïÍk &ºC[·%ÕÚ{6f°±ü¶“ÛîÛ‹Gõ°…D?@DR¦ìò12·ö¥¶÷º6^á‚H)£a\3ǞĦ$ߤ69÷£ Ü3Ô/-žŸX¨„ÿûã/XaLD’pÿo5ê§ŠP½Š¡”àø2>ÜþòóXôÿL?øñendstream -endobj -1089 0 obj << -/Type /Page -/Contents 1090 0 R -/Resources 1088 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1056 0 R ->> endobj -1091 0 obj << -/D [1089 0 R /XYZ 56.6929 794.5015 null] ->> endobj -170 0 obj << -/D [1089 0 R /XYZ 56.6929 691.7741 null] ->> endobj 1092 0 obj << -/D [1089 0 R /XYZ 56.6929 668.7722 null] ->> endobj -174 0 obj << -/D [1089 0 R /XYZ 56.6929 579.8329 null] ->> endobj -1093 0 obj << -/D [1089 0 R /XYZ 56.6929 549.1878 null] ->> endobj -178 0 obj << -/D [1089 0 R /XYZ 56.6929 502.9124 null] +/Type /Page +/Contents 1093 0 R +/Resources 1091 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1066 0 R >> endobj 1094 0 obj << -/D [1089 0 R /XYZ 56.6929 474.9173 null] +/D [1092 0 R /XYZ 85.0394 794.5015 null] >> endobj -182 0 obj << -/D [1089 0 R /XYZ 56.6929 277.7919 null] +158 0 obj << +/D [1092 0 R /XYZ 85.0394 427.2881 null] >> endobj 1095 0 obj << -/D [1089 0 R /XYZ 56.6929 249.7968 null] +/D [1092 0 R /XYZ 85.0394 390.6298 null] >> endobj -1088 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R /F21 702 0 R /F39 885 0 R >> +162 0 obj << +/D [1092 0 R /XYZ 85.0394 229.0656 null] +>> endobj +1096 0 obj << +/D [1092 0 R /XYZ 85.0394 200.0179 null] +>> endobj +166 0 obj << +/D [1092 0 R /XYZ 85.0394 151.3455 null] +>> endobj +1097 0 obj << +/D [1092 0 R /XYZ 85.0394 127.291 null] +>> endobj +1091 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R /F48 950 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1098 0 obj << -/Length 3185 +1100 0 obj << +/Length 2314 /Filter /FlateDecode >> stream -xÚ¥Ùrã6òÝ_¡·•«" ;O'™“¬GÙ­T&´[ÌH¤"Röx·öß·/ð2=NÕ–«L 4¾!½Pð§© ”É¢E’EUÚ.6û3µ¸ƒ±oδÌYùI«á¬×볯ߚd‘YÆ‹õíW¨4Õ‹uñÛòòÛ‹Ÿ×W×ç«Ðªeœ¯l¬–oþy®µ^^¼¿¼zÃCoÞàÆÛ«‹ó$Z®¹¾BˆÊ`^IJrýýկ翯¿;»Zwô Ï •Aâþ<ûíwµ(à(ß©Àd©]<@G:ËÂÅþ,²&°‘1²;ûpöá`”–ÎñÄš4°i˜Ì0%Ô ­ƒÌÚpÄ›± qVö|¥•‚#}x÷ ý{÷È×yã -n^l6®i¸}YWí±Þáùa3`½Z¬Â(È"ú×ïÞ#[S½Ìw»ú—§áòÝÏ+Šã¹N—€×5ª -nóêÎÉü¶fØãosp›ò£R!ÑÊŠ..àFáp¸*Û²® bfzõ€^é@Ù$‘^¢rÅóàý¼0 ’Dg2ívS$i$ãžÜñqK˜$ô›ý1ƒn#‘áXÐܺã ¸òPgÑð¬"«€b›-VÀÔÓ¡È[7‡$6‰áÝÌÅ&A¬;ÒŠ’ïmÓ–÷®0Ö,×ÛYÛå6§Fæ*n¹Ï­« -º/˜@ -Pb7ƒDøøÉ=6~¸© 9háÖ ì¦¾w¼äI)ÀêÓ®ð;òX᪺uÅ,gtd:ñŒaëðÉKü¶nZ½Âÿa0/ß: 2—ˆË.*^å>çûÃÎq§¾åo.ƒ,TÂz‚ŒøÇ hÞ¸¿óΑžhV¤i’ $Õ#A}ÿÃ: 6F'!È«ÿ¾zFeˆå=ÝÒ.«|_n¸Ã»ÊÝ%|›o,êj'ü,…íVÊ' iZ9y.˜šò®òndyΟîz€ -?åcFs¡FwÊñÂ}Z4™ <QÒ,’T1Žâñ}ÿzž…ËúÄìóG‚ª3ƒ™ ¥ ³§v†}Ís¸w¨Üñö´›9Oˆb¡Y¿:Ô»ró8sž ˆñzÚ´0yï$M. ÀtÓðݗͦ®0"¹;sT$ܨžpë ·Âaá©T72ê>@óË–Ì+ô{¼´w!Èj«*Š—¹Ç¡éí%c`ÐÄw‘—x‚þšƒ-™Ë„ТüéÄÕøaiÁ¡´à€?3¶…å#‹ÁêÄÒ -!Ûè+h^ÅßSõ©ª*^…ž#|ฉRf3Âå® -J–Bè<"Ùf†ce»…YF JhÈñŒD;ïÄš»›ºp<­q­ ¨ùûúâ ¦HoÀâ |s^á·Ð#B·ã ´'4ŠWë¡Ó N"òöÔí¡b8(*ªQɲ¨ 3ÀH¡tŸïJtMÈçPüÂ'|†%Âg»HÇg‚ -a´¡ ‘chÀY•Œ8 ƒÂY•ggÔ™øYä3` ¸C,ŽbbRäQl YõŠ‰í ‹ûÕ=‹¡#'‰,Âʽ A@Д…ïÜò—Ï‹Ó1ò¢CÂ"Ê„­qöÔL…3Õ1Y+Ïd­˜Éº®x”Óþžt'Y*²àCCWX¬½ðj6ø¦®ßýxõ÷ȲŽvÃC dåD|ó„ΉyàkñANÀAÕ’@("„ífOx€vžÐð¸(Dmˆ³È|¸PI$)Ï)Kòê‘dÃiG×ã…t-x¢úíåâÿÖ ¨!f͈!ú½ ¹–Y+Žc5»Ihùþ§5ÚÛ‹_ÖßJ ØØ¯¡>EU[n@ Ä6u"ÉâPÂÁKæ#ßø¢Æ$Åè& â$ãšÁ`–™$·6ò)2»Æˆöl¶yU6{†ÞÖG†½5ø —ïÆî\åÐKR¼„SÄ¡oó3À˜„>>h8Ý„Áö¡f(þ” *QÙ0DÄ+¦‹£(ö÷' $æ{¸¢†ò˜“¡lÌdðQ ”öéÇ3¼2*Ъ+ˆ4Fò¯·ÜÙbnl”2€p â.|…WÄ$èÈ ò†´ý\SÌ\K!æd‚óUL ^""©Üðx‹UŠÕ,•;¼>À<â -©}èM¶Z¾ÄØKʵúÖív{ÒFœâ>£LÜ9ObF‰Þx²úK¸OËNˆ;µ¬Êïeïœó$๔/G{¢¥¤]ù®ÝÖ§;¤Î  .± wæ–ÐåÀ—•ÒÌÑÃD·áh¿1 ƒÃ2Šñ Å?øù7\ k49»õÖÍe¿~EY—>¯ªVi_‡$)¼“„@©â:%°ÖŽÂ'.Úš>¢„øÜ»á6ãľ‹RËÙª;£‘<*Ì&‘õ3šBÊž@²÷âÙ#•Ø‘™’ô$›™tbd2¯©Ðbç‚O?.GßÌ31(‰EŠç9&EòÉØZSlòô|X–(Ž^<^¬Sÿ›¾ÕÔ¾º$Eœ®²ë=KávÎW¨FŒ 7äáË>Ì ôTòÝúr‡ò}YŸ_ê •”Wth‚8½å ó2ª ´6~Ñ¢&ÊFs"m,LúbM˜ &v)uˆ9@†îfW’öa›l)|»°ÏO'XU¬í5dJ~ê¢Ô_¢ßŒ -È„uÒÄÝIv'¬‰6 lOˆô'™ ú´4ô¸/½‹î"ƒ‘¾b¿Ó×W˜™~¦ûœo$Ú~Â~Én|ÀE¤v^)S¬Û¿æX? ãòõÉò_['ÑÀI -cýaÒ±ãIׯª‰ÏñNý)yQhTŒ—ÈKmjäÁ-Fà[Ÿ‰ÿ8aÛG&öRPÎ~©GáôáQàYpb)h ÈHî¬&{@’*âCbÚp̆¡¨}1Þ—$ð}î3eÍAà/A¤¶D‚´Óƹ´9õ±•bâ›÷>\]òÈh¥×­Ü׃qñ°à (èeÇF~0Pʢ뷗 ­± b½Œ…™ÑÁ\v9¦ÇdÝaíÃéfWn¾#pÏÖ`rí™”jà;L´âÝ9ˆx/Å!4j¬k;”~/wDí§ûÎø“6Ù -Î&ßÏ&ü Ù"tíM6t¯%Í+ï‹Ëûrçº(£ |p÷ÐvÏ6G Te÷Ó?ûÒ}÷ˆ1z–™­Š¢®@‚¥ŸH‚±}¤£}íÑHuÕDÃb U|1ÄnyŠTva’ä/FJ¥és{AwË_¦ÞDBý`#)µ•P÷–.}±?öXæÊfä_MøÔÕt­¯ÌÓº¤½mÝþ0Éówõ¦{/j¾öwã m3WÁuÙ[˜0]ÞÚØð,÷_—®F%àõåϲ¦•g­}3®QtࣼÉcéÚÓÚ¿¶u½ógy8xAëca19Ðʦq§)…ˆù3NŠÚ=á3©“I‚0Õ>N«šácùøQ) ”íòŒà¹Ÿào7fž¯T÷îôÿD¤ÿML”&MŸyƒŒ1HÃ,ñD!á¡RÞý–ä)éÿ±I9´endstream +xÚ¥ÛrÛ6öÝ_¡éK¨‰…àB`3}p'uw“ÍÖê¾4} $JbÊ‹"RvÝNÿ}pˆ´¡ØÙgB\Îý± …?6‘ I2žMÒ,&’29YÖgt²½wgÌÂÌÐlõj~öâ­H'ÉžLæë.E¨Rl2_ýÁ2 4š__½›Î8ã^ÿxñq~ù3L%¸xóŸ)c,ºøðúò n½ùpƒ·—Ó4Žæ¿ü|y=ýmþÓÙåÜÓ7äQ¡‰ûröëot²V~:£DdJNnaB Ë2>©Ïb)ˆŒ…p+ÕÙõÙ¿=ÂÁ®9” £„‹„„ÂEH(2#‰€--”ù¶¶@¿w8(;ýeQÙà¼wŸ(åU¡Y~ñ6fÄ™ œÅšñÛ¶ëÙLÿÏÉs&ÓçTÿ#»}y“÷öüˆ0¦$T: ƒX°èCÛoËfƒw¯Êý”©¨Xö•%óÐ#БŒžOg‚Òhqè À¥“O‘ dÀ/$ÓÖ@•AºÌ, +KÍý>_öŽžµ‘A[ã õ"½^Ì8o,,ˆÇŽòÎ~-SÛEé˜,–8ï¿04ciJ˜àqL‘˜‚ùxÆf HùŸù‹Kùúó»ì_ÏÛŽ}þBsþyuñöéÇÜÑ?ó ¹JN¸Nbßp'‹‰Á5õCyyùž–±7Ž%–I’‚ßNf"‡£©>ŒðéŒ/DïóæWˆî]Ñû¼/Û&,3.µ·D&Ò1I"„ûÆ!ôzYïŒÃÀZŽŸ=˜ˆ1!sìË,Þ"m׸º(û|ˆÇCw€uÎ: Ñn&£÷àç¸~qýúêÊ"6*íìÅHNnòª\w¤§ÜP¨ñùOTÒ¼ë5Z l÷NUÑlú-.–Ý€OÕ‡ª/wÕˆ7Yüè&z½Añ(K˜Y\‚tµÛí; =d@ +PĬ„ºvD’ª&ÀåHQ!;¬e¢`¶AÛ(VÄ#xÐEÕµšŒ”¦“4ú½ioz¯‚1Þs |÷SìZ¿Å°rØlæÌ'"É”õ ºF“˜*øhœzm÷ˆÝ†XV¹]Ûá…›}^[Zü:v-±Þ"`â,9x–‚1–í*ïó£GúãDrŸ²^¤]Ñ9âëvwçƒ÷økСóökИӖ¡¾¯ZctR;ò’d¢Ç]ר§JÐN•]ÜµÆ a o†ÅnÙî +\3& _(<n^àØÐÁ[¤>> endobj 1101 0 obj << +/D [1099 0 R /XYZ 56.6929 794.5015 null] +>> endobj +170 0 obj << +/D [1099 0 R /XYZ 56.6929 691.7741 null] +>> endobj +1102 0 obj << +/D [1099 0 R /XYZ 56.6929 668.7722 null] +>> endobj +174 0 obj << +/D [1099 0 R /XYZ 56.6929 579.8329 null] +>> endobj +1103 0 obj << +/D [1099 0 R /XYZ 56.6929 549.1878 null] +>> endobj +178 0 obj << +/D [1099 0 R /XYZ 56.6929 502.9124 null] +>> endobj +1104 0 obj << +/D [1099 0 R /XYZ 56.6929 474.9173 null] +>> endobj +182 0 obj << +/D [1099 0 R /XYZ 56.6929 277.7919 null] +>> endobj +1105 0 obj << +/D [1099 0 R /XYZ 56.6929 249.7968 null] +>> endobj +1098 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F39 895 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1108 0 obj << +/Length 3203 +/Filter /FlateDecode +>> +stream +xÚ¥Ùrã6òÝ_¡·•«" ;OžO29&Y²[©$´[ÌH¤BRöx·öß·/ð©8U[®2€Ðh4ú¦ôBÁŸ^¤6P&‹IVi»Øì/Ôâ澺вfå­Æ«^¯/¾|g’Edq/Öw#\i ÒT/ÖÅ/Ë7__ý¸¾¾¹\…V-£àrecµ¼zûÏK­õòêÛë·<õöÃGî¼»¾ºL¢åú§›k„¨ ÖEA,;×ß^ÿ|ùÛú›‹ëuOßøZ$î‹_~S‹®òÍ… +L–ÚÅ# T ³,\ì/"kã!»‹ÿèŽfiëO¬I›†É SB½Ð:Ȭ '\±Y›ÐW`G`/WZ)¸ÒÇ÷_ñÕ¿uOÜy·®àîÕfãÚ–ûoêªkêÞN1#Ö«Å*Œ‚,Ò¡ýþ²5ÕË|·«q{.ßÿ(°¢h.uº¼®PUp§É«{'뻚a·ŽÛöà6å¯J…D,(+ž¸zów +‡ÓUÙ•u%H3Ó«GôšHÊ&)Žô•+^WÖ…i$:“ew3˜’ I#™ÿãèš§9,Y`’Ðöû xD¦;`A{çš<ðä¡Î¢?Á³Š¬Šm¶Xõ"K‡"ïÜFØ$„÷3›±îI+J~·MW>¸4ÂX³\oKdul—Ûœ:<˜«¸ç>w®*è½`=(@‰Ý áà'÷Ôúé¶&ä …['°ÛúÁñ–O$¥{¬»ÂŸÈs…«êγœÑA’éÄ3†­Ã'/ñÛºíô +ÿ‡Á¼|ë$È <"n»ªx—ûœï;ǃúŽÛ¼š9>EUN’‰¼_erZ©Šô×ùsèÞº¿3†hr[™ T:½Ì‚4M²çç®bPþÿpC|À΄yõßWg~„X„oïúÅS•ïË øT™!I€¶=‚yñ¦¦®vò¥°²ÛÊ…™ _m'ÈS[ÞWÁ­lϹé¨ðK~ ÃhÎdhzÕzA,\P-^Œ(iÈXŠGñTZ~¾ÌÂe}döù“¿AÕM™Á—Ì…Røcw†}Íkxt¨]swÜÍÜ'D!PȬ_ê]¹yš“74?Æ gÛÁâ½óÔ•Õ©¿‹4س(Œ`mÀ}çáÉæ~Á›‘«êׯÆØUÉxŽÉùˆ‚_‹ÂÅA„q=#)¶qBÒ3ŸÙ¯z‰gØ çóÈ»®"¥‚, íb¶4¢´÷¯±ø×릩›öe§É¶N'Ë=r~·¬îFÆEÇÞ^¤|èïaiÎ~F›¼âÅâe»Ž'È_âV÷àš|Ç×ðq ô0K—ïïx"?{Ž`kù”–E $ÈÃΪ®È§’õy#¹CVý1k€0Œ¾¾@@Fˆþï¯onxð«²ê®nöyÇãž~˜Ð z,w;îÝ +f>¥;6pÁ ¼ÝÈ,ë×@À p)Ü9‚+k@=(X‘}“û±SsͺZ 'S¡·¡]ú6“&`zih÷e»©+ŒgîMŽ*€„5n=ávD8l<¶‚êVfÝçh~Ù‘y…ñ€—Î.YíqUňBñÑ3ï86½ƒdŒ šØá>nO0áBØyBÇ㢵m!Î"ó xàA% ¥,<¦lÉ«'î §Ý€’]´à‰Ž—‡ÿ[;¢†˜5#†è÷NȵÌZq|«ù Ø„–~X£½½úiýµÄÁ€ýÚé#PTuåT±@l£P'‚,%\1¼d>Âññ/‰œ„ ݤAœd\q­2'©±|‚Í®1bÇc€=›m^•íž¡wuÃp ·ÿôò›Àܽ«zIŠ—p‰8ôm>òq³‘PÀÇÝ#'«0Ù=Ö ÅÀŸÒ[¥1*‡(£xÅôqÅþþ&ÄÜ`OÔRÞk2”™ü? +”Ò>ý8Ã+£­úbƒH3`$ÿz÷ă-fÖFy!§AÐ!îB+¼"ž A oÈ[ÒöKM1Kr-eX“ Ìv15hy‹dlˆ¤rãë-V)ÖÂ@V&ìðúëˆ+¤ö¡7Ùjù?`/)×êk·ÛíIý%p‰ûŒ2qï<‰5%¾xëÉ à>u,{A îÔ²+³sÌ“€ äQþ<ÚÃ-%íÊwݶ>Þ#ump Œmy0·…ZVJ3G7N݆£ lb8‡m㊰ù7< k49»õÖÍe¿~EYŸžWU‹^4JRø$ ;„c+Ä!tJ`;¬ +„O\(´5CD ñ¹wÃ!mƉ} "¤– ³UG#yT˜DÖg4/„”=dïÅ»G*±3%éIvbdÒ#“yM…;¼xlýu9úfž‰AI,ªP<Ï1)"OÆÞšb“ç÷ËÀ²Dqôâõbú÷g*©–ÓÖ¾Ê$Eœ¾.ì=Káv®“Ù #È yFø²s=•´[_îA~(ëcëË@½¡’òŠMÇ w“|a^¦C„ÖÆ/ZÔDÙhN¤eƒI-V”Ù`âR‡˜dnv%iöÉ–BÛ‡}~9Áª‚üÓhï !§ä' .Jý%úͤüLxQ' MÜåDapšhÓÀÆñ‰§ÊrýCSRuŒš¼–£ #é½áô¢) —«qÈKÕ…!½[Y­Y!G3ÔïC0‹Í '0þp¶ì¤–m¸lH8“Å>\M0¡ír´|LÞl02©@œU }aç3+­RùN¹‡z9åÎb-›ª)ñòê®#+¦0$Ã=ïľà +Ê-;1ØxÈkÊCN.—²ƒÂ9W‰;hYq  c>ú ÒŸe.èÓ +ÐÐf_zÝG}Åq¯¯¯0!3ÃJ÷9ßH´15ü„ý’Ýú8€‹HݼR¦X3¶!̱~Æ äë“å¿¶N¢£ƆˤSÇ-’®1^U'>Ç;õçäEa Q1^"/µ©‘¯o=9$þÓ†Iì™ ØKA!8ûI¤…ËÇDã‘gÁ…¥ - #yp²›ì Iªˆ‰ ThÃ)Æ¢ö§ñ¾”ø£ ‘€ìsÏ”5G?‘&‰1ˆÄ†æÈÝ$¨Ó0‡º¡è o?|üxý†×NŽ"}Ë¥$Œ€IÍ¡eX.¨&_ q¢”M7ïä€Ð+{˜û ÍÍä–af0€{=£Ê _l¹w8ÞîÊÍ—` ،̿¿aš˜IÆÅï×åÿ٧к±ÒíäÙ9”ÄîÁ5h ø~FîgÎ¥üm¾÷_òª"»„n¾BˆþËIûÊûåò¡Ü¹>âèƒÜÃtý'œÆGUÙ•>&û2~ÿAcò‰f¶(Jo¸ VÊ|œè£F˜êF*­&^¨ú‹ávÇK¤Ê ‹$—1R6Èç º;n™z õ£ƒ¤„HÔVB<]ºôÕÄþ4`™{"ò‘¯NøÔ×w­¯ÒÓú¾ëÜþp’óïj–.þ&Y|é߯Ýfž‚kˆ3¯pÂtùîÆFxôés±v )âjR^¿ùQötò‰kßNëýEÀ %ðßÉg×µ§uøRØÕõΟåáàmˆ‹%‡…^vƒúðRˆ˜¿ãI{ |&2I¦ÚÇlU{ö/8eûœ#8÷ƒcüȨ̀,Õƒú¿l2üº&J“¦g¾‰Aö¤a–x¢È$ÚSÊû_¥<'ýôJ„endstream +endobj +1107 0 obj << +/Type /Page +/Contents 1108 0 R +/Resources 1106 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1115 0 R +/Annots [ 1111 0 R ] +>> endobj +1111 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [418.3461 611.3335 487.0181 623.3932] /Subtype /Link /A << /S /GoTo /D (dynamic_update_policies) >> >> endobj -1099 0 obj << -/D [1097 0 R /XYZ 85.0394 794.5015 null] +1109 0 obj << +/D [1107 0 R /XYZ 85.0394 794.5015 null] >> endobj 186 0 obj << -/D [1097 0 R /XYZ 85.0394 769.5949 null] +/D [1107 0 R /XYZ 85.0394 769.5949 null] >> endobj -1100 0 obj << -/D [1097 0 R /XYZ 85.0394 749.4437 null] +1110 0 obj << +/D [1107 0 R /XYZ 85.0394 749.4437 null] >> endobj 190 0 obj << -/D [1097 0 R /XYZ 85.0394 597.4103 null] +/D [1107 0 R /XYZ 85.0394 597.4103 null] >> endobj -1102 0 obj << -/D [1097 0 R /XYZ 85.0394 573.0707 null] +1112 0 obj << +/D [1107 0 R /XYZ 85.0394 573.0707 null] >> endobj 194 0 obj << -/D [1097 0 R /XYZ 85.0394 410.9267 null] +/D [1107 0 R /XYZ 85.0394 410.9267 null] >> endobj -1103 0 obj << -/D [1097 0 R /XYZ 85.0394 378.8211 null] +1113 0 obj << +/D [1107 0 R /XYZ 85.0394 378.8211 null] >> endobj 198 0 obj << -/D [1097 0 R /XYZ 85.0394 204.765 null] +/D [1107 0 R /XYZ 85.0394 204.765 null] >> endobj -1104 0 obj << -/D [1097 0 R /XYZ 85.0394 171.4256 null] +1114 0 obj << +/D [1107 0 R /XYZ 85.0394 171.4256 null] >> endobj -1096 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F14 729 0 R /F41 925 0 R >> +1106 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F14 737 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1109 0 obj << +1119 0 obj << /Length 3252 /Filter /FlateDecode >> @@ -3700,77 +3713,75 @@ R UˆÄuV¼¼Ô)e ç/> –|}Ä[¾¸»¿‡CÔMT4ÃðF‹Ó üIT¸ ;?ðËPñVUè‚èô7 øpiKìOD“"VØØŒ66ð8uRÈ(L0”lÙuÇ]‰¥¶â§s$ôuJAï¡þœ .ºj2˜dàJU>¨¡“Ï•ÝPK'ºÈO1ta  øŠ#~Õ Ä9ÖsåÖåqÛ³ºÊp0ºÈe©ó['‚|ËÅežÿ~(!ˆA§Ò`xË0zDúÜMç8kO&.βºóhB×íÄe¡þ”LGOéßã¬ÎV¸@8¨aÔ8~?{%ÚÕFªµ›ðËþ”sÁ4µÈOJÆÃN//çì„èð’q$Ϙ}¯\èžôv&ÉŒ® hΨY*“Ìæêì]ºmÖŸsewvèëÆ “ +â~Ú;Ä(>õw¥üÎÄŸoDÌvþç¿úœþÝ’QÖ¦§ñŒ“< ÂI˜)Üvš_pþtÉú‡B¬ðendstream endobj -1108 0 obj << +1118 0 obj << /Type /Page -/Contents 1109 0 R -/Resources 1107 0 R +/Contents 1119 0 R +/Resources 1117 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1105 0 R +/Parent 1115 0 R >> endobj -1110 0 obj << -/D [1108 0 R /XYZ 56.6929 794.5015 null] +1120 0 obj << +/D [1118 0 R /XYZ 56.6929 794.5015 null] >> endobj 202 0 obj << -/D [1108 0 R /XYZ 56.6929 769.5949 null] +/D [1118 0 R /XYZ 56.6929 769.5949 null] >> endobj -1111 0 obj << -/D [1108 0 R /XYZ 56.6929 748.4014 null] +1121 0 obj << +/D [1118 0 R /XYZ 56.6929 748.4014 null] >> endobj 206 0 obj << -/D [1108 0 R /XYZ 56.6929 549.4516 null] +/D [1118 0 R /XYZ 56.6929 549.4516 null] >> endobj -1112 0 obj << -/D [1108 0 R /XYZ 56.6929 521.7105 null] +1122 0 obj << +/D [1118 0 R /XYZ 56.6929 521.7105 null] >> endobj 210 0 obj << -/D [1108 0 R /XYZ 56.6929 231.5025 null] +/D [1118 0 R /XYZ 56.6929 231.5025 null] >> endobj -1113 0 obj << -/D [1108 0 R /XYZ 56.6929 201.1114 null] +1123 0 obj << +/D [1118 0 R /XYZ 56.6929 201.1114 null] >> endobj -1107 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F39 885 0 R /F41 925 0 R /F48 940 0 R >> +1117 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F48 950 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1116 0 obj << -/Length 2902 +1126 0 obj << +/Length 2922 /Filter /FlateDecode >> stream -xÚµYI“«F¾÷¯èx«§Ýˆ¢XÃ1mOûÚl @b‘-hbþûÔ´ÔÛá˜Ð¢2++óË­ -WýÀ«,0,TøWIá«῰¯6¢µ_@Æó‘3}‘­Ôš‹7@¥6j´š”ÔÍéà{«ö&ñU›µÐ P¢ur¶±Í[·ßÕÞKK-4|´°«wzùõwöÕDÆô^X*²ðzE/,…{õ_x2a>ã½Ì_¦…À*YZ†ŠeF9©”Á"(Œ9H`1ƒ8¶ŒØµƒ{XØ ´ >,“$F í…ù¯®ç!|d©¢{qHGÇè È•Ð<VF¢ƒ•ÆV’M&È3.æ~cYγâ'©7 tÏKŸ„™ÞåËBä žÕ±â|_¢ˆE7:Ç–‰ÍA°d|À 7rÄ)+qM Oð•ı2J&.H(àC(ºé»'‘ž„QL©W7q( 0òèsex^æ3Qüô[ë¸ožg)‡û7V`èëFt3#Œ¨nñ1 L7°K6¬Èȼï7/Ù -8?r*‰ÆO3F[ƒ|c=¡HBEb  +ÏP~ÂŽÒ†À‡(¬Î„c”Òá1t1¨„=ü² £Ìdº‚×b›Rò - d%šÏ8!ÊK–e+0À!aŸ# 3·¢‹•á‹äpÈnaŒå¨o -WÁJp©¨o=«ØüÁ'AÅd@ºOCë‹d9ãJ2¡ŽÂ\E?f1wŒ\=±Hœ#>ÊÏe¨Xx:[qÓ™]猸Š~ýtz5<Áÿ\b -r!ŸÇa–ÿO–?Úôe…"Ÿ]îŸãÌÛÂÝ_<šZ1ñ#HŒ¢ ºô8”Áÿ\dž—þpž‘d<Ž…^tÏ5°øEu%¾Z$Ié@L -QÐE”gáBæ·ˆP¢ÇrþIäDd³ÄæÉ…Ë[™HFЏÊ$fú£"Xê 2¨ÈÚ´°â™Ð/ƒš¤tI„Yæ.Ý%» 2£pEÁøqS£HDŒÙÆ(ÙÃÒ%1’À‹Nf„]ÙÆ -#¡¾•±2%f| ŽÆÈ>ÛÛó0÷h‘B@‘)G÷&  €ÙÑ9Z´éx6‹é`‡ë3æÂ•+›#“Œžd’–Dxq¬f‹ý|IÆ„Œâ„òynp Ónð…ψÒcÚ‘~t\ƒ–çÜœ§Ð0¯å@ìÀÏ$zÃý1ÁÂJ´t4OP"#ÏŰѱ”À PI”eùO† *!PTz J$üÇNF¦ –´á×Ïâ†^LËòsÝH±AOëæ’Xļ¹è0@¥•౨2s|Ѷh)ZNa,g QvÒyˆnê¾Ç——óKËQ ¥‘„EÆ™õ§æ™×§²gÿjd£L¿F6ÞÄ´b#r·ŸÙIŸ~øÌ”ènf¿‡,Œž™ÇÍ`2Cãì£fÃ!Hö}ÒU <÷€K°RïŽðI¬åŸñS)f`E¡3$‡B4„ BÅÙÝ¥tŸUõ$+1cP>/ÔÍL,9"=¶abæ[4Grôsâ„‘› r{ɸ²4ÆT3¤SX¼“=dV`}‡¢ø-Ãʼnüä"B>+%­ôd2?×–tÍÚŽú€ú¾X±-z6 jDnìXÈÁ™Cã TÒ£kè}\þ£h2 |4òÂð@G¸w Ÿ“ôÄêN4¢q¸’y^xELT]’œbÅÑc:Ðéƒú"ú|ˆBTãŽg¤<²Ê ¯y}3*ùþh@3'$5—Ñ­ÀÍwÂzåãü0@d|ž¦°ç$&w€'©T[Ü{Ž®Á!¥n­g[i])ŠRB…Ú.²«“  ܤ ÏsøÕ¼¿Ý[U^˜÷ÏFÇ®š°·vÃä$Šv?4§û÷R‰nµ¶°¤³¢,ïê¡sònMç¶žN9öûT‘æïƒ¾¦§Æ‰“fRM…Õ…à̦·¹Ñ-³ztºw~¿>mšÜnjÚ·­ÑTžÆ6fuÓu­t0ÝWmøí—âk -uïß rÚ$äH…Ãðœ¢ÏzõS\p¡+®I_ò/U¯Tðw6øWƒ!Ã(=£`Ýtÿˆz¯_¥"dR»¶j5ý63îÆv¶Ó¿´6u1l5Wï;ŠBë¨ûh 6zmæOœÖfCÕ0+~¹»ÁµâîìÖù$]6Õ{{£™­öh™¾÷6÷sÌzÚ1¹ÚûöÕÑæ@äΖïõµí¶,8ƪ1”ו·g[î -†Íï ßóV–¶7œ×°Ã¯†5cö~suŽštµÉů†ér&×—UgiÞÇ— ÌÄyCu¼ÎÞܵg5·I5cuÊ*5öŸy¼:íÿðîý¸ûæÁMÏPÈÝ $ð—ʾ„îZœ$<›É1øë2ÇtGµfs6©1£–úGq>sþT»öX;Ö'=¸ íûո͑~c%0òô´ ¦Óiª«†#ß¡¶XDïîÀi«Á¨}„p9hÝ{?ê-6ðnÛ)\^GªxØ„¢Á–9<‰ïëÓ6¹ŽoOrãÞ÷Ãꈮ8lW-=ô­ÁØÕÇæœ-ss:îŠu{_ß×óî­‡z·×ÞñCÞLÃ~×¹››tÊm×ÓhŸNË”àuÖkHú8ˆ‡éºß鬭مî<¹í»Ó•ožìq¯}z¿ s\›KÖòÜìuÏQ¢Fwø #ݾ &mî²R›ÕY0X½7¡ -µA™R§·îôœÚ¦) eqÙÏ'ñ¦×±š -]®£ËdcÅ›fwvqšÍ²ýnÞ¿lËR{š/¶œÃ=MF#n>RÄéì ï«nWv·EØ—zóß¿ä’i2Ð?è'ûò£Ðãj†aþÛ?&…:„eÿo°E2ýíS>ÿ@BêAYæ>ÿ(yú¬ˆ¿œ£s~®É 髿Åß.?ªþÛúÞendstream +xÚµYI“«8¾×¯¨x—qMua$±FǼ=ï;^»ç€6‹ x˜ÿ>Z€²ë1óº£c„”Je~¹ +ƒWÿÀ«"rŒr¾nÄ3ˆÉÂÀt»à@ÀKœ"ˆÙyÓ‚£€Hâ##a1kò4c|4ÈÖ†$Re‰Šú å'ì8l(|d€Ýêô¸€qŒnlx]*%¿l#(s©¬à5?f‹…ü@"‡x™Å3 E„ã’çùR- ˆKاˆ@AÙL­èlEEøb>ë 1Æ„ö¦Â",¢¾ñ¬üð› 'è>s­/œâ JJ•¤L E&`I?¤>wˆ\=±¨Ÿc:FÓ”o<ž¬8‰ÙÌ–íósB’‚èŠ~ù4~5<ÃÿR  +›PÈü0ÿ'Íuú@ŠÊ!I@Ï&÷OqjÀMnî/½Y1µ#Èœªâ¼ô8RÀÿ\âTA¸ÀÉŠ'LϺçšXòÆã¼_,¤xé@²b§‹ØBœº ßà…™ 1úƒÈIXg™Ï‚‹¤·"–œ$æ~•rLåÇI°Ð2âp +Pþ°=Xb%3¡_5 éÌ’3²Ì’º NN…yÂøñP#DêŒéÁ8ØÃÂ%s²(HFæ0‡mÑÁ*'㺕’rj|àŠÆ)=;ÛÏõx”Y4! ÊX•ƒKjP±ÃlÙKÚl<™Äl°%ù™P‘Ì•ÎÑŒIGO.6\î‚ôÜ'Ygçî c•ªíé´qg­üBžj>ƒJ*[0CÚ≠LØNÎîöÆ&I¯ª'iŠI ÀÑy¡n¦liwŠ—XÛFSÛâ9³d Ÿ'ŒÜ§ÛsJ•†1Y5C6EÄÈ*ÙCdÖWÈ“ïÁ2\È_AÎ=ä3S²LO'³¾¶ jV¶ÌPz¨ûRɶXo a$\ˆÜر(ÐÆâ„ñJ·ƒkè{Üþ£x2u|<òÂpÏF¤v`›Óð$ ÌœxÄ‚$“y^xÁ\TmœRÉÑc6Ðكن "ö|ðBœã',<ÖÊ`¯Y~’RªÙùxÀ"'¤9MPð­ÀÍN"re㬠<>»)"À)‰éà‰+“ÆÖ÷ž!DrpÈV7Ö³®,¯äI‹‚Êt—ò„‚GéÕIT1Ôí$R¯±ë)Aª(1E1%¾$éMãRæLx`”põŒºa}Y*P@¢Þ—0í½8•2»FIŸ)©Àޤabæ!{hÇ%Ö>>=ͧ†¯Pìϸnü¼©CrÞú+–®ïŸèõK`ÑFæŒÐO;iß­Œ0H‰œT˜Ìß³Øå‚$!"H2Sbziq“[¾L“€ƒ_o=×Ãìâs}¹pà7A’~Lܾ¾ü‹ž"Èœy|KÅ}Œ +x—é’Hn„$§r²€ØÂßéB&ÏÃÂ$$9“°íZ¬ü‰ôò ¶§|æË™Â"'B=;ö7îã E™ ÐÓã[u°.Ñ¢‚Ú¶ó^[š|4_ÞV~¸Iä¸ÑØv‘áM6M]»L;ר¹¿váú$µåѽsbG㻺ÌÓúñuCµ¯Â¬îÍJË[v͆p_µG¯vƒ³Qƒ3Õ_;{sv0Á<Ë­Š¹XJÏï{Á}…Šüø~ƒË›°÷ÃJ]ݧgÕÒý2ʨÕÜU{úT¶×ßË»Ív=ëžÝHkEPlöä©6žÝ«q_ Û,ųƒ›6kÅ AKm%:ݵT;~¿ú•ùzy×ÖÜ«”Aψìe¹Ûo4Ír¡Šîéü]8vj7óäZ­Óþ´B-aÙ¯“÷««C¦bОÎ~9¼-&JuQvæ}xŠTœÖ4ÇkmÑÕ]yV}“”C0ÔÆ¼Záÿ‘ùû§Ñþo‘Æ”î̹Y†ÍÍ @*íËø¢eñYMÈ‘OÓk>*õúdTá íg~>Sá”Ûöpv¨Ž:hÚ÷‹qšýÊË ”ñqŒÇã +W¸ÄÂ/içóèÝí9M-4¨.ƽYûÞ:ó5ºÛö -.MÚ¯CÉà‹ žÄ÷Õq“œ Ç·Ç5¥v~y$Wê7Ë–žbÚœ¡ØÕ‡æ”/2ómØ–ªö(¾¼¯ÖæÝ[õõv§¹ú‚y »mçn®oc¸Y£Ým\$„Ыò^MÖ‡AÜ¿­º­ÖÊšœÙÉ£ë®=^úæÑvšÇ÷3n›¼TX°ïàj¯:ŽÕÚÛÀMâéöµ7jÂóR«—'Aoù^GšõŠ”[U«ãTÖu±'ªóón:Š×–U¯Ín‹Ut­­x]oOÎN½^t¾§ÝóƱ,­3󥆳¿ß’ÁNª4žì•]Ùm+î&wûBkþû׌3 öûÞ_Ü +=îæ8î¿ýÝ‚°«#TôçŸÓ_þ+æóß',Røù/ËSûJ>»ãKB& ù«äù6?Šþ¢Ó, endstream endobj -1115 0 obj << +1125 0 obj << /Type /Page -/Contents 1116 0 R -/Resources 1114 0 R +/Contents 1126 0 R +/Resources 1124 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1105 0 R +/Parent 1115 0 R >> endobj -1117 0 obj << -/D [1115 0 R /XYZ 85.0394 794.5015 null] +1127 0 obj << +/D [1125 0 R /XYZ 85.0394 794.5015 null] >> endobj 214 0 obj << -/D [1115 0 R /XYZ 85.0394 717.5894 null] +/D [1125 0 R /XYZ 85.0394 717.5894 null] >> endobj -1118 0 obj << -/D [1115 0 R /XYZ 85.0394 690.1986 null] +1128 0 obj << +/D [1125 0 R /XYZ 85.0394 690.1986 null] >> endobj -1114 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R >> +1124 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1121 0 obj << +1131 0 obj << /Length 2380 /Filter /FlateDecode >> @@ -3787,48 +3798,48 @@ w ¯7^5t\ç.<7SQK„S£Ýš£ˆ^GfˆŠ×/†qˆ€[èò::-vÞ¿÷ºÇo aàÍ>Ô)ø¹) ‰I˜ö 2±/.âF'~QÖN°vt¦yxJ2ŲÇ3àƒœÃ‡þÅyCO‡7ãÆ¤þ#'!þ_BÆ?݃UqzD:QØÙï¨ÍüäIòà@á'*¿'ÒC}¤àùáì1»«¸«Î÷³>_±Ó$ÏDŠ÷ÜI5á¿ö.ª¸vv÷ŠÌ=ô!ļ"xß½t½†rZ¸¯p㺛Í,‚HHDÏØë ƒ±Oº ‹pt8³?ð¾ì¼Eµ«# StìÙ 9µØ¦.Ëú0øâPïK¿fý„¯b*r¹f1“"÷ôÕƒ©1Ľæ_a”²C¾¼@Í™JxèØ[çm`2‹#Õ'›‡o2耵_EQÎNöÀrh…ëIvâÉ)Ä Æßú…ìK` ¡5¯£ïíê=ÀÉHlŠåsÇ!¹õ|ÑÁ8øî/¿ ê˜)¬’f«xÝaõ¢z¥œ³’š÷ÿ‡x©úÿC|upendstream endobj -1120 0 obj << +1130 0 obj << /Type /Page -/Contents 1121 0 R -/Resources 1119 0 R +/Contents 1131 0 R +/Resources 1129 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1105 0 R -/Annots [ 1124 0 R ] +/Parent 1115 0 R +/Annots [ 1134 0 R ] >> endobj -1124 0 obj << +1134 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [349.4919 384.4828 408.4801 395.2672] /Subtype /Link /A << /S /GoTo /D (ipv6addresses) >> >> endobj -1122 0 obj << -/D [1120 0 R /XYZ 56.6929 794.5015 null] +1132 0 obj << +/D [1130 0 R /XYZ 56.6929 794.5015 null] >> endobj 218 0 obj << -/D [1120 0 R /XYZ 56.6929 594.1106 null] +/D [1130 0 R /XYZ 56.6929 594.1106 null] >> endobj -1123 0 obj << -/D [1120 0 R /XYZ 56.6929 562.6395 null] +1133 0 obj << +/D [1130 0 R /XYZ 56.6929 562.6395 null] >> endobj 222 0 obj << -/D [1120 0 R /XYZ 56.6929 370.2937 null] +/D [1130 0 R /XYZ 56.6929 370.2937 null] >> endobj -1125 0 obj << -/D [1120 0 R /XYZ 56.6929 341.714 null] +1135 0 obj << +/D [1130 0 R /XYZ 56.6929 341.714 null] >> endobj 226 0 obj << -/D [1120 0 R /XYZ 56.6929 214.6004 null] +/D [1130 0 R /XYZ 56.6929 214.6004 null] >> endobj -1126 0 obj << -/D [1120 0 R /XYZ 56.6929 186.0207 null] +1136 0 obj << +/D [1130 0 R /XYZ 56.6929 186.0207 null] >> endobj -1119 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R /F62 1050 0 R /F21 702 0 R /F39 885 0 R >> -/XObject << /Im2 1039 0 R >> +1129 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F62 1060 0 R /F21 710 0 R /F39 895 0 R >> +/XObject << /Im2 1049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1130 0 obj << +1140 0 obj << /Length 1913 /Filter /FlateDecode >> @@ -3842,59 +3853,59 @@ M&P ïp,'èñ+)jä‘jåQúk ©ï¯‘ÙYºÝÕ¡Eâ¦Á§âÛð´â·I-§Ñ;ÀÍÍ$b®»Ö¬Ý‰ÜQµ㩺›{JýÐà4;,ÿ‰f`¨º ‡W$‚7€Úù«1[Ë/¥nÆÏX «Eš Q S£»»·ž;šWïP{“øÄDN)ój=u”ö¬ÊùßC;»òÕ]Û Ñ_;Œ`ÝÄF q…7ÉGb†N0bèKNôJ… $ȳÈBÏ"g¥O Øêåýµ G’^—=Ys{}ñJE½Ó6l`‘“TÈ‹«Ã}%­JüŠÆ‹ŸêIÙmS:_Óß Р*çóýÃì(š´ªŠúºWy÷ËÓü-1~!EŠß×¾6F‘íE†>5.NF¸áb¼¹]mþpùv¹ÿÐÆ}endstream endobj -1129 0 obj << +1139 0 obj << /Type /Page -/Contents 1130 0 R -/Resources 1128 0 R +/Contents 1140 0 R +/Resources 1138 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1105 0 R +/Parent 1115 0 R >> endobj -1131 0 obj << -/D [1129 0 R /XYZ 85.0394 794.5015 null] +1141 0 obj << +/D [1139 0 R /XYZ 85.0394 794.5015 null] >> endobj 230 0 obj << -/D [1129 0 R /XYZ 85.0394 769.5949 null] +/D [1139 0 R /XYZ 85.0394 769.5949 null] >> endobj -1132 0 obj << -/D [1129 0 R /XYZ 85.0394 576.7004 null] +1142 0 obj << +/D [1139 0 R /XYZ 85.0394 576.7004 null] >> endobj 234 0 obj << -/D [1129 0 R /XYZ 85.0394 576.7004 null] +/D [1139 0 R /XYZ 85.0394 576.7004 null] >> endobj -1133 0 obj << -/D [1129 0 R /XYZ 85.0394 544.8207 null] +1143 0 obj << +/D [1139 0 R /XYZ 85.0394 544.8207 null] >> endobj 238 0 obj << -/D [1129 0 R /XYZ 85.0394 403.9445 null] +/D [1139 0 R /XYZ 85.0394 403.9445 null] >> endobj -1134 0 obj << -/D [1129 0 R /XYZ 85.0394 368.2811 null] +1144 0 obj << +/D [1139 0 R /XYZ 85.0394 368.2811 null] >> endobj -1128 0 obj << -/Font << /F21 702 0 R /F23 726 0 R /F41 925 0 R >> +1138 0 obj << +/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1137 0 obj << +1147 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj -1136 0 obj << +1146 0 obj << /Type /Page -/Contents 1137 0 R -/Resources 1135 0 R +/Contents 1147 0 R +/Resources 1145 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1105 0 R +/Parent 1115 0 R >> endobj -1138 0 obj << -/D [1136 0 R /XYZ 56.6929 794.5015 null] +1148 0 obj << +/D [1146 0 R /XYZ 56.6929 794.5015 null] >> endobj -1135 0 obj << +1145 0 obj << /ProcSet [ /PDF ] >> endobj -1141 0 obj << +1151 0 obj << /Length 3113 /Filter /FlateDecode >> @@ -3915,47 +3926,47 @@ h4: ²>Ÿ2˜ÄáÎG9ü)¿²ÁrÔ™½ã7àã~€ª;'è¼UðB4²nÃÑ2–'ÁN;ú3Þ*ü?ÚªŠª•YZêð€rõ\¾ÄE^í…ºbYS¦iM5> endobj -1147 0 obj << +1157 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [356.2946 363.7923 412.5133 376.6291] /Subtype /Link /A << /S /GoTo /D (address_match_lists) >> >> endobj -1142 0 obj << -/D [1140 0 R /XYZ 85.0394 794.5015 null] +1152 0 obj << +/D [1150 0 R /XYZ 85.0394 794.5015 null] >> endobj 242 0 obj << -/D [1140 0 R /XYZ 85.0394 769.5949 null] +/D [1150 0 R /XYZ 85.0394 769.5949 null] >> endobj -1143 0 obj << -/D [1140 0 R /XYZ 85.0394 576.7004 null] +1153 0 obj << +/D [1150 0 R /XYZ 85.0394 576.7004 null] >> endobj 246 0 obj << -/D [1140 0 R /XYZ 85.0394 479.565 null] +/D [1150 0 R /XYZ 85.0394 479.565 null] >> endobj -1144 0 obj << -/D [1140 0 R /XYZ 85.0394 441.8891 null] +1154 0 obj << +/D [1150 0 R /XYZ 85.0394 441.8891 null] >> endobj -1145 0 obj << -/D [1140 0 R /XYZ 85.0394 424.9629 null] +1155 0 obj << +/D [1150 0 R /XYZ 85.0394 424.9629 null] >> endobj -1146 0 obj << -/D [1140 0 R /XYZ 85.0394 413.0077 null] +1156 0 obj << +/D [1150 0 R /XYZ 85.0394 413.0077 null] >> endobj -1139 0 obj << -/Font << /F21 702 0 R /F23 726 0 R /F41 925 0 R >> +1149 0 obj << +/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1152 0 obj << +1162 0 obj << /Length 4061 /Filter /FlateDecode >> @@ -3980,102 +3991,106 @@ S žèͶKê-‰?˜^À¡E×°NžÄô;,)ÒJ”¯0¬•;ªå ëÉ3½&„–˺/ÐñÐè›»ç“_A½Îì±ê%”ÔTÚêÏk]ß­ëËAt•Û…e›(Cµ|LÌœÜnè?cX/J•–±È[Mì©ÂëJka5ó\Sî€[²Ä%ØùØê ŸÆkú2|¼uÀ(ƒovY m‰S»f?PÛûŠŒºüQ[·¨>Õ¡Ëãiß×onBË—Z1ycr®ÒíÇ™'¿ö„g 5;_{þgOå,- k€±3Á1kΆ_‰î}-ÊÅüuò<ÎÛ.β¶>¸eR°øý$~pË@œ)¥Ó···ëXîN§ßÆbsh~Ó`.g¿¸ŸâˉTmIeb?U…—þì‹Û•˜™ùC¸ìßþ¹^ÔKˆvÂýß{ŸV9’üOQø}@ Ÿb jLŒ˜æxqºñ¿IýÅã=þ\%öúoõ꾈CþuèÃcUJ‡w7žæU¿ú£äí'ÛÒagÐ;ð-JZœòEð½™3[BóÂÔÿ Æ+h:endstream endobj -1151 0 obj << +1161 0 obj << /Type /Page -/Contents 1152 0 R -/Resources 1150 0 R +/Contents 1162 0 R +/Resources 1160 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1148 0 R +/Parent 1158 0 R >> endobj -1153 0 obj << -/D [1151 0 R /XYZ 56.6929 794.5015 null] +1163 0 obj << +/D [1161 0 R /XYZ 56.6929 794.5015 null] >> endobj 250 0 obj << -/D [1151 0 R /XYZ 56.6929 165.9801 null] ->> endobj -1149 0 obj << -/D [1151 0 R /XYZ 56.6929 136.242 null] ->> endobj -254 0 obj << -/D [1151 0 R /XYZ 56.6929 136.242 null] ->> endobj -1154 0 obj << -/D [1151 0 R /XYZ 56.6929 106.2766 null] ->> endobj -1150 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R /F21 702 0 R /F48 940 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1157 0 obj << -/Length 3064 -/Filter /FlateDecode ->> -stream -xÚ­]sÛ6òÝ¿B{ˆÜX4A€y}J]§u§ur‰3w3M'¥%Øâ˜"U’²ãéÝ¿]ì"%Z¾´7z¸Xì.‹ý$&!üÄ$ƒPfj¢3Ä¡ˆ'óÕQ8¹…±ïãÌÒ¬õíÕÑék©'Y%Q2¹ºéÑJƒ0MÅäjñËôì‡Wo¯ÎßÏ¢8œ&Áñ,NÂé·—ß$£æìÍåë‹ï?¼{u¬ÕôêâÍ%ß¿>w~yvŸ@æ ¦ðÄ„×?Sïü§óŸÏ/¯ÞÿzõãÑù•_LÁ"”¸’ß~ù5œ,`Ý?…ÌÒxòa ²,š¬ŽT,ƒXIé åÑû£x‚½Q;uL±Lƒ8ôˆ•èiP„QéHLtœ‰Œ¤Uáy<ž%aˆOÅ‚úÿ¦&Ÿ—Ÿª|eÀ?xl±hLÛ~ZåÝ|ù©,ÚŽàÿ¡æc ÔÎéë¨/ÃLè “(«u‡:²2 æEÏDS¿3Ã0ªŠ®¨+Rw^-¨ó¡Ío “•=²á†AC±²ô^lÇ"‚|0OË©’º(©…FÓœ¾nŠUÞå#}nZ³ ^WS»0iVEexò|îÉÏ몳´ê’7uC{ Yo˜_kš{ÃõÚ49®°›“:›^-a#`e¸!‚,ŽI7=!iÙÖÔÛ‹)‹M‹ŠÚniFtž¦`Y ˜¥‡ë7Õ T»¯F%ƒ0‹5c¢Ö÷©‰,ˆµŒÓÖMg÷~Ÿ˜TA$SG¬íòάLÕÑzc\/ mJ‚Ó×ò ¨Õ¶+ºMçϫ̇»ñî¢îfN Uêt(üšÉ€æ9›Ôµq¦õHú†ÚnÉ#7uYÖEuû÷§Ny¢b8P:9ìÖúXöP -ÕÓRÝTöh¡¼C¡w™Âª`’Ò‡¹z¬}¶ƒÍ!ôU2dëtsñ–u3Ptluxñö^±Æ‡~Ÿ¸ã>ª¦HZÆé3jêaP“Ãz^M‡¸öÔ´Ëv\M}¶»jZ“’Ði}Þê©`¬ßN_P§ª;{ઠ-ø©LfϨª‡u@UëyUâÚSÕ.ÛqUõÙæ´tc¬Ê¾;aÓb‹Z¯7ì߯·‡pÄõ€ïQJ8ßsGsWŽ |X*wÝÎS3<1°9¨ñ>ÖÓ÷XÏjü ×­Æ÷ØŽj|ÀÖ»/ŠÛ}ÏæìvïX»èÝ­§ÜÙ™‡¢[Ú›(RAªUìbǼÛ›8ˆD”þÏ{£!qu`ozXöÆa=¿7‡¸ööf—íøÞôÙòi¨ DàÅ—ì…©æeݺ9γ\79¤ ÷@ûY˜$ƒH :}çÛÈ*%‡>èØÐ'#ã6'AÈû ½œšÒä ~ôa>ÏË|•sF&1ä6w4„¾î·¯^ Wó-ÎÖ`ˆlQnÓ/)Ý¢ ‡Úµ`=ˆ±±4´…Tue4H‹øxÁ@YÏórY·OT3—™Ø"T¦kñƒÀ>ÂöÜÞÔ!5Ñ ÙÏõ Õ Ùœ[;Îrm¬™¯»VÍØ¹æ±›zãd*üL3–ê-L;oŠõ6ïÝËIðXÙŽ?;'d7ž"åVq‚æåÓè„ÉÅŽ\âür2…ÝÝ´ \å ³ƒç|‰#‘ÀPÑR¯}¬º|ÞsšÃÙÕ+˜ÖŠz“sB]m Y6,¤Ó¶¨æ£ªiÍ|Ó'ç ·Mýµf£îåíÊçí÷yY,rJ"Õ mG›¯7}Жߒ}ìÈ©AS£—Þƒm=Ôö$ iw–15·in*¦—`ĠǘŽÚ±ßZ,.8{ÀÓðŒ_ ƒ¶Þ uQ”lï*º%•%›[^hߘõ|ƒ{eM{ÇŽÈüsiP½)išÛÖvï€6ÂÁ°°êI£ÝÌF -Ƙ׫5ÅA¬®SÎòLj: ¤äDÐbø(ÙyD±hkžßåw†g®Kp”̿ۄ|M’ÖŸ¡ì Ö€2Ó7èÛ„Í×ìwW¬ ÞDÑô‡úÁÜ{Ó•2£³$£°'HKÓh¿o -ïUÖ2ï\A䱇I‘#äÚMkr`k÷?7ì:uó±ccuÆç¯—†9›±®éd§ÆyHÐïɇ•î» -ûµéãi$m©Ú ™†M£s~†ìª±¾ÃF¸ýFȬMµh îЖƊj£ÏJPÑäÚX ˆmŽ çØ+ã1š„‘K‚Àˆv·¥4ÕP ·'ÃÚÈÅêÜéŒÊå]ûµ hÏ—ŠK™9lª™,8WçbNµcNÿz`Ë xá¼—†(<Ûf -è¶'’X!;òž¬rëŠ='æ/LU?6¦c$Š®T@ñ€áCe[¥OgÌUMß–þ õ½P=<ËC½ 3)CŽ€íXf«D&PÐpf‹kžA1WÜŒ•q%Šv·'#ô SÓq< Ö`tk‹Ñ;-ˆ#ÉŸ$H:ëNƒT©h¨ÛQ~€=y€_‰~šøý¾1ͨ6â@×/§5~?¥Ã Jãì9zz„Þ<Ÿ/ÇnSÄq"þŒˆ–丠Y -5p–}UðíU{¶½O/QHÓäËèÑÖ+( ´ñ0âmÖ6%¹µA¬ÄaN¡H£'¢6§ú7 ö–{v…7sZyÊ3ÉžbäÈ%A:‹¾†è}·¬Ë1iUô}^ŒÅ6 ¤Î ‰Rù Â•HËþï‹UQæ ~!„“b -cú+S¨µ" *P;gÉ¥íP¼Pc:g»ýÜ F(ºáð„¥ŒE%{!§qqœdÅ #¶¶PðŠ-Ħˆ!Ö”+¶~C½c’ª I¼»CQšÑ«x‘RFîÌŽó’‘ö²è½¼Àþ¨$ž~k؆­h7NB„a˜í–2Ÿ2–dæO›‚•/óû¢ö3'$8´ÝY©Ü¢¥ôPL3§¦Ý\·†q­¹á˜2e‚»ÔŠÊQ5Ôáô AET.¨)û¨Ý_÷s`í.40§¤¤)_¸çæŠiXÓ°–,}Ái.ž>ÝÃ÷Âõ¹<²u%çxÖ8_×õs¾Z—Ærɸ–ÙqRË KCçÀEò4Rß`ù£¦_A „üfÄVfžÂ@´tù¹ôµMQeÜÄ -¨4TGá7Øë@`:[ªyy[C}¿\Ñ'{Pyç„8ÖÿÁ¬²®ï6kÒKÛž\Ö±Šhß¡‰ZÉ»–+Êlú¡Ý°áóid™¿áüа·ª„¸n $/:H3©z‡õ³õÎB³ÑG`,\‡^ƒD4doÄ¡ÅÓcë8è÷—šB|¬çw6¹î¡³b5Yç÷>¦‚4ÕÙŽ»»Ü]!ÔÛr„¸}MxâŠGÜ»e¼â<}û:+Ô ;÷ÚëÞzÏêÕ¶ÄyWIŸŸÞå§Cå^úáÀd|äÉÁGKäèÇU*÷³ŒÝö/{^˜œ1ÀäzÕ†vþ {R;Ó®éjÁ¾1?îP{÷ ‘¿N´zs| -£ÛMãîX“ÔšH‰2Ó«ã ð Jši¥†– ç¶ÉaMMK@ëopBÉØw”Ñ'ô¼Ú-íu Ó% ÛÒÚ8Ša`ÁâIàì„Û—/OÈ/ÕÍØ!k—¦,Oצñw–¸œý“…ö n¼ý3@6¾M(ñ´MœZ ø1s&­$YÛ×vÀi¿7peÃþWÁµ95´-ØóædGvEíNAˆ0#> endobj -1158 0 obj << -/D [1156 0 R /XYZ 85.0394 794.5015 null] ->> endobj -258 0 obj << -/D [1156 0 R /XYZ 85.0394 731.767 null] +/D [1161 0 R /XYZ 56.6929 165.9801 null] >> endobj 1159 0 obj << -/D [1156 0 R /XYZ 85.0394 703.7216 null] +/D [1161 0 R /XYZ 56.6929 136.242 null] >> endobj -262 0 obj << -/D [1156 0 R /XYZ 85.0394 229.6467 null] +254 0 obj << +/D [1161 0 R /XYZ 56.6929 136.242 null] +>> endobj +1164 0 obj << +/D [1161 0 R /XYZ 56.6929 106.2766 null] >> endobj 1160 0 obj << -/D [1156 0 R /XYZ 85.0394 201.8883 null] ->> endobj -266 0 obj << -/D [1156 0 R /XYZ 85.0394 144.1965 null] ->> endobj -1161 0 obj << -/D [1156 0 R /XYZ 85.0394 118.9605 null] ->> endobj -1155 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F21 702 0 R /F23 726 0 R /F14 729 0 R /F39 885 0 R >> +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1165 0 obj << -/Length 2262 +1167 0 obj << +/Length 3096 /Filter /FlateDecode >> stream -xÚ½koÜ6ò»…€~¸ÝÔ+“"õ`ûÉqlŸ‹KÚs¶8Ú'k¯P­´•´qÝ_3R¢lÙIϹ€ÅÇp8ï— þx'a¢"¤J†1ãqPìŽXp {—GܬÐʇz½>:¹i B•DI°þàáÊB–e'ÀX…‰ˆ„ F ÆØâþ™±¨.û²©‰Õ¼ÞÐàÇ.¿ÕÈ/`V¬"*É¥ÁwÖìvºî;:´Ëï-šý^ç­Cy·Õí’g M+ý6ïit·-{ÝíóB?ƒ t´ÑgÔZÑÔHÿí¡ÍGp¥Ò!’ŽÄò4T"ʈØU×ßWp•v” !]Ÿ·=mÜ•ý–û­…íïZ)¶y›½n;Ú8yEë?³˜uUÞma:Xãe„Š`šþ¯NhÅ`€Shy "D,h®q¶x­‹üÐé3ª8&¿JAp‚¥‹Ü 'Àã¾Ò½®ìæFWå$¾¡©¥‚%x¾sg‘Œ˜_òÅ€¾ÈkÜXp Èbë›áR,MšÚÝÓgß´¤+³ûÁíMxŠ OUY[«h¬!à øƒ±ÊÞª¾ÜWOt4ŸN5M4 ŽÕMO;7ЀB$N,.Ìõ°ªÏQœÇ8‹É8pùCSUÍ]YßÒ´´x¤óªÜ8ü¤A0 ZÊÁ=Fúædd]tGÞ¤GËo;ëY¯N¾!ï•|ê½¾Cœ˜;âP¥i;a*¹õ+³ánö6Ö[ä/Øá¾æzXÂ!ê¿9},Cáœå>FØõeUÑpÿãpÛçÀÔDX_‚;443¯‹¦muaÉÉû^ïöľh5Æ žb]0fq’Íc©ôÖ‰ú•€hŸ )§¬=&´nè[5õ-[K´câ~†šˆ È#韠æA*XEQr™A&ŠT˜e©"_ûúëÁÛ¤ò½ fÖHph-FdÁ8À8kyqç''ôõã¬AçB$M){™KÁ§êƒCÛ<¸G;84«ÉÎ~{ß­æ<¯,ò -ãab¢ Fd‘L\„EEplB#®Y"64Í ãäM×Ñ|Œ]8˧wtßÂ8‘Wam›´°MmUs;žã.LLˆœq·™€yLcÛqÕ…WN(jùÑÆ¨$F-MҚ͸.tÛØùlL¢PxÑV_iV<28´sÍßíÃÜŒ~ݵƒã»ƒwÌÇ4Óuíˆj·[{¶Ÿâ°ê øÌ…Ïĸ}«?–Í¡{ì¼3E™çï·ºª|D·qšØëÖîY*­Ü7 AÉèƒnGÏú”–á;¡ eA…J¿ša&¨i )¯» iææò¶¶T Õªïï3 ,OÁ‚µ«uMðwFgtþ`$ï¦%)Ä:WŠ’|f«?å™Ì_ëÜ¿õ/ó¯^às}˜ˆY˜BAùYB¥b9߈¡Y¦ŠÉ§qÑ9¸ìИ¢Þ( Kê©_C&D¡Hy‘†Îtþå9Hœ€Å‰S°òSM´¸6ÿ¡_MøâjG‹Ë‡¢‚KX -È#%€h‘!-Áo Å¥ÈæG¡˜…“«Þ4Àbàqé¯|̆KhUG;‡n Ò@KÆk"mìQì¯`´°Ès{ŸKœæ€iÐìvô½_F†¶¹Ã‹šC…>–&*`ã–Óô%m®†õ¥¸„ÅCÊÉ/qÇãO—õ<ÚbÚí5`º&X°×Œ]°aÛvWÔ„öz¶˜™u"™¨0ÊTX3ý–>«L|Ïx™_N)–\ù\†B&‘ÿúEä‚8qÏGöåãlîéà¢t…Ñe›ïvyûDªÍÂ$UÂy_nfß$`¤èóøi"¸Ø•I¢b²|š\rMìkáp9e%dºxÿN;8›‚ñ¨Åè Ê?ù¤!˜œ»\OR}<¾'àĦøØ¶õ8Ò•ö íËb1-:"p/90FJ›ƒ@{.ª¦£¾ön fІW¦oM˂˞tfèǼŸ?xº©šâ×ibï7«Ññðöä*ÞÜÊ«ÎU -ºÝ•unÞK¦=·½ÊôLÚ_»rÂ!ˆÙTáoï{|"Ñ›oúg–† R—жIÆ?Ç—„_â «‰/ýo§¼Ì Øî¹óQ|p'8³e Tª ã©lþ!ò‰Èx·€ö9å”2ò¢šñNÎ2èHS›7ô¼i"i¢L¼„Qç;Ó’ÁÊÕ´”o6¤ƒÎ‚îò¾Ø…ávN‹aJ*[‹¬(:5ï=õvÕœ‘oªM¿ÕíÐOu#p -IZòÀ—ÇË$ŒºŒy’Ž}>Jwâ)¥1(SR™|Biʉ„îÚ6U÷š+*ëÝðÖ;Ș¶P&誛> ÞèA¾Vè7÷cqO×údrŰqÅT[oŠâ iQ‰pÄú²*ûû%ç|ñŒ=ñ¼LàÿGª8„*ŸW¡RL ´„˜}ØèOêÏÂu“hé½ÌÏJÌ#æK ì‹Gªjo¦øóCà˜Q#÷«¾ÿ¤´º½.J”ŽXÂÌ!ôæ5œÝPB0Š?¸C2‰mEá›À¡ .†‚ƽ‡ÙÍf5W¶å^tè†,µ~uù´®<9¼L°|+ ,ˆªÐ@$s?y±ÀQüâØÆúQ‚{fYä÷bžÃ§Y(3@"À&•zB>j;Ý/qÊ#ý¿ÚÕ.endstream +xÚ­ZÝsÛ6÷_¡Î=Dn,˜øà×õ)uÖÖÉ%ÎÜÍ4”–`‹cŠTHÊŽçîþ÷ÛÅ.(R¢å~Üèàb±X,v¿%'üä$ E S3‰S#Â@†“ùê(˜ÜBß÷G’yfžiÖçúöêèôµŽ'©H#M®nz²$‰œ\-~™žýðêíÕù»ã™ +ƒi$ŽgaL¿½¸üŽ()=ÎÞ\¾¾øþûWDZ™^]¼¹$ò»ó×çïÎ/ÏÎáDÃxÉžðúâ§sjÿtþóùåÕûã_¯~<:¿êÓ_° 4®äóÑ/¿“¬ûÇ£@è4 'ð™¦j²:2¡¡ÑÚSŠ£÷GÿèözÝÐ1†:a¢â Ù³  ”Hc%'q˜ŠH+íLxggQ`ãS¾ öè‘Í‹Oe¶²⿹o±¨mÓ|Zeí|ù©È›–èÿ¥ÇÇ ”hÓת¯ÃLÆ"Õ¨«s±r: å¥PÇ3ÀÐïìÇ PeÞæUIæÎÊ5>4Ù­e±º'6˜@7X(4NÞ+ÐíX&SÐÆÅzꔤ&jê¨jšÑ×u¾Êê¼x¤×McÔj+z.lkëU^Z<ŸwâçUÙ:YUA„›ª¦Æ=ˆ¬6<_cë{ËÕÚÖ®°ŸÓq:½ZÂFÀÊp-RŠ4 É6=%aÒ¢©¨µ9–SVQMó’žíÒŽØ— JizVJ¡™èž,Ô÷c ãÝIaU0Èćgí¸ö§lŽ  m¢á´Þ6oÙ6C‡.¨ƒ‹·÷†-V{öûȇû¨™T,b&Ϙ©ÇuÀLžëy3šµg¦ÝiÇÍÔŸv×Lk2&­/[;åÌõÛé j”Uëþ ©`>“êôSõ¸˜Ês=oªC³öLµ;í¸©úÓf´twÆ8“}w®Åµ \o9¿_?nƒp$õ@î1FúÜsG sWrX¢wÓÎSS8xB˜æ Åû\O[¼ãzÖâgÝZ|oÚQ‹¦íÒÛýÌæýv/¬ýéÍm¦ÜÙ™‡¼]Ú¥ŒHbú³c^ŒíM(”TÉïÞ›Î#†Qö¦Çu`o<×ó{shÖÞÞìN;¾7ýi9J 'ðâì…-çEÕø1>³\×@:÷ÀúiEx +e$EßùödÕš>h¸£O+Ðã6#E€Èû ­Œ…ÍpøÑ‹ý2/²UƈLã‘[ßQæºß¾zY c[GŒÖ ‹|Qoá—Ö~QÐBmHÚGð8ˆñádÄŽRV¥%ÒqxAGQͳbY5-4Š'שÜ2”¶mð…ÈœÂÎÜ«4‰A³Ÿ«-šМ_;ŽòϦfA¼l:3cãšûnª×)ïFÚ1¨·°Í¼Î×[Ü»‡I0¬\£‹Ñ rO'a«0B÷ê`tÄâB/.òy9šÂîn&®²…Ýáó¹Ä‹ˆ +o¨Õ<–m6oó9a4Ç}Õʧó¢ÞàŒXWySCE–;’i“—óQÓ4v¾©ó–Á9èí Ÿa§ŽÙ©{¸Ýt¸ý>+òEF Ò `;ú|µié…¶ü–ücGDFt5êðð|ë¡r‘€¢},#4w07‘ÓKpb°c“Žúq·µX\0zÀhx&/C»lÐxÈ vŽM—*Ú%•%›[^hß™Õ|ƒ{å\{Ç(üsiѼ Y·9¬íÞÂβ@pæIÔ.2‚žœ9æÕjÍ¡¸ гuÂ(L¨·@BI=†CÉ#‰ySñø6»³íH,ǽøN¬ñë ;OŒ_Ø2·ÝøÙX¸ PÌÛ*<«Lºzõ‘SVôîäŸP»SªÇç&E\¡ƒÔË·ÍŒ6R‘ñ(—<ƒÂ1¿+uÂÊ¡8î¶{_ Â8 Òjol=j¢DÉç„%ûÂÆc6„JÂäÏÈ›góåØ5e¢EFZ⸞iõvšþ1©pŽ”Í ¸ö¾¼È™$PKÚzeHËpxºnÖ~§+sÐÝB‘èáî“°ä^lóЭð0ÞúÐÑ×™*ÄÅxë]R¸[Vض&i¥[m0Q¤S‡›5dˆ`Á€AÓ]:#tÑô}¾Ê‹¬!¥ôÊ=qá‘D"Nõﹺ©…D“ÃÎWPS=@„ÖœÑ>4¹F‹¶—ÓH¬èÉ8 cF_¤ +/^,Ý "áfGä*Cða_ð€ž¼ Û ÍÏ ÙŽ]Ñ?U/¡=FÑÆñb1œ±°H71·eŽç< o¬¼à!«m)#´•,²´ÔèŽOš€žžëÕÙOé|-“Ý æÄ|bÙaã8@ØcŸž0¥:F”éš}Ⱦ%'ÝðA†–c%УK ø™äÔ «@òŠÅ!×KÝ{­Nû!•E]ÖFUêQ¸"S¡µRÌ—û™—<Y(‹Þ!Ø…Óo-û°Sí†OžÀˆ ÒÝ +ËY_¯ÉÌ›H×v™ÝçUäº`×vgá…­uw/Æ23z4›ëÆ2¯s7ìW&€º+-/½TK F­( +µbAm¨$FýþºÍcÏ‚P—àU¶ð_™xV(àM÷èê`¸Xw?Ëä¾ÍU›+w:ç|]yÖ/Ùj]X7KÊ%ÖN&Ó±iÒaX)”ЧÊ|ƒU™™~EUHýÍX~ë$ LAK—ªKo[P+©@"f…¥òßÁØ«Ÿ¥ÜJÍŠÛªC¬è•3¨T]rB—ÿ`TQUw›5éàž^.±JµŸÐäÀ,ÈÔ¥…n:ýÐŒW!2ˆà\ê.^¿"î­)gJ%[Á#0'IªM/X¿¸ì,cvzÎÂåñ5hD]=®¼„v© ¥ÕüÎÁð;6&O‚p>ñŸíŒH’8Ýñse‘ù›j[ÀÐl_Ó ÞÌøš¶cî]~ˆÎp|W¿éHH¶ó¡ý'è³jµ-ŠÞã ×—ç¿:óMãÿ€“ò-U'^GK¾¦z÷͘¹›þ”Á; +›1¸ÜC¯.‰}~©­mÖtãá>}?î +0{× ª»ŸŽb¯>´æøµ*P·›Ú_ýF‰s‘ïAt$§WÇ)?®ÃMPÐH§5<Ùqnë ÖT7DtùÌ}—CuB_}Û¥»¥€nºÛƒnwãÏÅÖ21guÈ¥€pvÂÏ—/O(/UõX5K[§k[wW©¸œÑú^·ÿQPB²ƒô}Âȧ}âÔiÀßXgRÄF“·}í:¼õ{Wî¸Â¿PøgFÚluîäz=wIÏ3œ€Cƒ»s²2=ú)CR¡B±Ôé)ÉýËz½|9vÅø·ÿt쬸ýáòâ_Ôr[íå•üß·óO|qÒ¡À?ÛŒ|ù º½úËÿéÙ~º‚’B'‰ÿ„¤!±'*½Rh-­w5ïþü³¯úÿÊì~Óendstream endobj -1164 0 obj << +1166 0 obj << /Type /Page -/Contents 1165 0 R -/Resources 1163 0 R +/Contents 1167 0 R +/Resources 1165 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1148 0 R +/Parent 1158 0 R >> endobj -1162 0 obj << +1168 0 obj << +/D [1166 0 R /XYZ 85.0394 794.5015 null] +>> endobj +258 0 obj << +/D [1166 0 R /XYZ 85.0394 731.767 null] +>> endobj +1169 0 obj << +/D [1166 0 R /XYZ 85.0394 703.7216 null] +>> endobj +262 0 obj << +/D [1166 0 R /XYZ 85.0394 229.6467 null] +>> endobj +1170 0 obj << +/D [1166 0 R /XYZ 85.0394 201.8883 null] +>> endobj +266 0 obj << +/D [1166 0 R /XYZ 85.0394 144.1965 null] +>> endobj +1171 0 obj << +/D [1166 0 R /XYZ 85.0394 118.9605 null] +>> endobj +1165 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R /F14 737 0 R /F39 895 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1175 0 obj << +/Length 2474 +/Filter /FlateDecode +>> +stream +xÚ½koã6ò{~…~8{»fH‘Ô£ý´»MÒ·Û^6ÅáÐ8ÅæÚBeÉ•äMÓ_3R¢åÑ&Wˆø‡óž±˜qø3³8‹²Y’)¦¹Ð³ÕîˆÏ6°wv$ÌÒ-C¨·—Gǧ2™e,‹£xvù)À•2ž¦bv¹þi³ˆ-Ÿ¿ûþÃéùÙo‰š_žÿa±Œ4ŸŸžÿó„FgoÞ¿s±XŠT‹ù»oßüpyrA[±ÃñöüÃ7´’Ñç¤'§''Þ,~¹üîèä²Kø^Á%>ä·£Ÿ~á³5<û»#Îd–êÙ5L8YÍvGJK¦•”~¥<úxô¯a°kNòOpÉ8š``$¦¨3ËH: +`a\áœÏ¿1?sUEWÔ=5¯Ö4ø±Í7ß Xe€•Ï–‘b™Êâ{Wïv¦êZ:´ËošýÞäGys½5ÍB¤sC+Ý6ïht½-:Óîó•yAái£Ï µU]!ý›C“/À•Ò0$‰ Ëd”±Ë¶»)á*)#8ì)—RÎÛ.o:Ú¸.º--v[Û]×´²ÚæM¾êLÓÒÆñ+Zÿ™kÞ–y»} sMè`M”e*‚„w¼:¦‹N¡æy$ˆ± ºêtþÖ¬òCkú— –iMv”ã$Oæ¹g4NàûÒt¦t›kS;àøš¦Ž +ãù֟韈dDðø…˜÷èWyEƒ+9l]Ý_ŠŒ¥I]ù»súìë†dew?ù½Ñ›"û¦²¨œVÔNðü‚Â8aïeWìK‡'Ú[’OÆ’F’¤ÀUuG;WГ'ç§özX5¿çÈÎ×8Ó¤¸ü©.Ëúº¨64-Þéç¼,Ö?IÐô€–¢7¾)ž€9S#Ù‘5™Aó›ÖYÖ«ã¯Èz•[ohÇöͲ$‰a‡%J’Y¿²þæ`ãr‹ï‹Áwø¯½΄pˆrÅoN÷ 6¥¹w¶]Q–4ÜßÁØß6ÂÙ?jĬ—x*šW«ºiÌÊ‘“wÙíû }Qk¬Ü÷tÉKuœN㨠։ú¥oŸJ¥ÆO»KhUÓ·¬« 8[G´ÄÍ5—G’?AÍ­P°Œ¢„ •B$Š2–¦IF¶öå—½µ©,´6˜9%Á¡Ó`‘ãý¬=øYœÓ7ô³w‘4¥èe/›ªm}ëãáP­F;ûíM»œ²¼b•—ècëeÐ#ËÄ`ý",z/‚cëqͱ¦i¾²F^·-Íß…3¼x|Gû5ŒcE~Ö¶ùg[WnPÖ›áÌàwab]䄹M8Ì×46ùj;¬z÷êÝ y­ÐÛX‘h´ÑÂ-ô–‚;o‰øÈ[>Å “v>Ï·,EdqoŒ¿»ö9¬ð×ö¦î^0¿¦™ùl*OT}ØlÝÙnŒÃ bÞ„ +ù ðjûÆ|.êC{×\'Ò°Àæ>nMY†V‡†â%±7ÛsVS8­¿©‚ÂÏ'Ó ¶ô˜Ýöºšë„°!…`*7Â-¥_L<&Èb )¯»+tböæbS9ªúü4´pò’’³ –Ç ÷ùB¯³Æg·ÖîÃÁü¼8³ÈÛq +ÞÍ'ŸÄŸ¿¢÷‰cÅß«öQxëߦõ_8Z˜†:»ÛÒ÷fYÚ&ÂÄ5^TJŒâZY?€ÅYNÓ?B»x 3ª=q „D]âNð"<]Tk°(}i·ó`T €­Œ`Á]3TºöÙ®‚¢B³3“ ˤ©8cQš¥3§¦Ùó5m ìTèY<Ï.ÇÆ¤x¢Â‡PLª8 +;Q¬€4Ñ·ˆ\wãÝT{à´ðÉÏY“ïvysOpMYœdÒ_Væú0Êès·ýK\l‹Ö†M±q¾VL>œÆ®#@8†(¢’ùÇ[pÆÃ¹ ‹GF¯PáÉ{ÁFqí£§w=ô p₺v¥;ŽLih×½A,¶ G¾[c¤´>XÔçUY·TÃÞd ƾ•gó÷¶,Áå€;ôc¤Ïoõ€®Êzõë8”·‡«å€èuß_òYmv ò²õ¹ivE•۞ȸ®vWŒžh,\ú"ìh>øíÛÛÃÛ fýÕmûLÁ_òd&’Œ ®ã§Ø’ÌÀ–ðjdKíT# ûµ4ïøâ–1»'-…Ö§åt³2“L¦¬;á,‘ÄÛ|UN§à)‰ Œkê`ZGgÖ]B|¨ò­º`åüZÊ×kAë@wy·ÚZyáv 6‹ý®,I6ÙjEЉm5vT¾•S:Ú·Mënkš¾djï:`¬†ª{²ãy FQj'EOGéOÜ'3%Y¤¸xDf*fi'½µ6uÙ>Ar«ÒYEÛ·s{Ó²S¶ãîß•éùë˜~u3dótmH¦È8 >•jªõj‚8¨R²Xzâ]QÝÍB1@†{žÇðÿ§ ¥€¯²Gd(KA©Z^û°6ŠÐÁµ#ôß§™ÐóRL{ygÅÈÓUüÓPiDLY¯ææQ†µ{³*A–g1·‡€kP’Wàvv}ÁÉ áu^bWÂ7?€žCñ»ê³ßør›õr*mŠ?‚4èÐö¡êòãùÙâ +8ñR~ŠÔˉ+…41VÑÃÒÊ bá1ý´Po6øþ?'/™@>as¹î} +ùAóÙº|X¼6óP¾Qa ¿} ç,,!ØAÁßÚļ¥Ÿ+LÄ™v2©÷² +Øð²¢zAËÒ@«–x£D3ži +(åuc&ad#ÊÝ8 2DZo3QŠp-øÁ8‘ȶ^1°é¢M#ð»4Î8Êb³í–×?´á©K«¸²Î]‚¾L¡†‘Ù­žþnøSó ú#ÍRÕØ2ù¨ìStÓÄý +ãyÒUà SÉSûã°ˆx6õË5Ÿ=Üžú;ùP"*pOi…í–€eIÊT +H¤fˆ 9"ÕÎ’ÿAÝA¤ÿC9 endstream +endobj +1174 0 obj << +/Type /Page +/Contents 1175 0 R +/Resources 1173 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1158 0 R +>> endobj +1172 0 obj << /Type /XObject /Subtype /Form /FormType 1 @@ -4095,3034 +4110,3137 @@ x 6\>RgÈbÏWÖ¹j[†› WŒÏ¢®{6;»²þFÃÇñ÷ø]š¨)Õ/Ô¬Mu;pk;Ì©Ëdh<åE–ñ¬AÏw³ð¬±±Nê¦ó¡Ä½t•‹ùD„™Â²]°Ä(‡;„ ·åްЭr²ÂÙÄLûˆ T¥Í¡èª‹ŠŽt’¹w_ =Î]ˆ‹=¦uSä÷—ä"ï±yl±‡µÃ-ËkHsŠöreOÚ³êvg›<7ºt,‡Ýe—;ãÒèЭ/I…B÷&ê(ýê³ö󻉨YÙ¹Ç,çkRÔšÚ'^ m" ^˜h±ÎW9AVªy­Â©/fýÆ"•œãûFy-Sng \Çdª¼˜©Æ¥†Í}B©•µŒÎ$âw1.¶&Øíþ²C¶O–ÃVç X×9g¹E{îÇ< •ãóP)!ÍZÜÅŸLÞª~ÑÔ'¯UâXLµüc“ÅXsЖõÚ¯½˜Ó’~òBL–§èªÆ¹O¦ºNZ_[Èü.øšŠû*]3QôçÇñ!Ö-žendstream endobj -1166 0 obj << -/D [1164 0 R /XYZ 56.6929 794.5015 null] +1176 0 obj << +/D [1174 0 R /XYZ 56.6929 794.5015 null] >> endobj 270 0 obj << -/D [1164 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1167 0 obj << -/D [1164 0 R /XYZ 56.6929 749.9737 null] ->> endobj -274 0 obj << -/D [1164 0 R /XYZ 56.6929 246.2071 null] ->> endobj -1168 0 obj << -/D [1164 0 R /XYZ 56.6929 214.3631 null] ->> endobj -1169 0 obj << -/D [1164 0 R /XYZ 56.6929 155.5938 null] ->> endobj -1170 0 obj << -/D [1164 0 R /XYZ 56.6929 143.6386 null] ->> endobj -1163 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F62 1050 0 R >> -/XObject << /Im3 1162 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1173 0 obj << -/Length 2334 -/Filter /FlateDecode ->> -stream -xÚÍZÝsÛ6÷_¡·“;%Š/â£}r'çNâö÷)Ídh‰–x¡HŸHEuïú¿ß P”MYv­Îdü@`,»‹ÝýAf# -ldRB…•#m%I)KG“ÅÍ`ìÍ s’8)éÏúñêè»×B,±Š«ÑÕM—!Ô6ºš~Ÿþóä—«³Ëã„§t¬Èq’*:þñüâR,~N¾x}þæ×Ë“c-ÇWç?_ ùòìõÙåÙÅéÙqÂLÊ`=v,x}þö [o.OÞ½;¹<þxõÓÑÙUw–þyî ÿ9ú𑎦p쟎(Ö¤£5t(aÖòÑâH¦‚¤RˆH)Þý«cØõK‡ô'¹ œ[1JRJ$c»wÅ(ìš°Ò:9·7MK‰H…3‰”„Zº1 g=“0Έæ6éÔ%¸ð6)ëÙ¬¨fN70_ôçSC˜Ôn7±¹Í'Åo”ò¼­ -=^ϳ[í¾f³IC¤´ûµRÀÈR ×îøpEŠI“LæYUåå“® xz ÜPå(0Õb±ªŠI0”'Ev¾ç"³ûÎòÙd’7~P»Áð)¡œ‹=ñ?éæmçßî\˜µ§¯C™5Êðt–qÅn³ -E¤•û¬*)Ô²T…êÃߢýe^ºòe›!¡=¼xîÎtÏu1ÃÏ-VNIw{v5ÅcÊßœêeŠú{uÏG³/“)jå©Ä"d¹‚œ0M>çwÏKgNkÍØ¯Çþ«‹÷ïÏN±í>¢Ðž¨‡Õ(;¨F07Çöh”)Â4ÅÜò¥È×ÏÖdpM¿Öòñ#ŠëIô5»"¥üloR¦’pJT_§üEʵ(­'Í¡”¶¦û®[cðÚBºmU„YF¤VG¸&To#äHYPE · uª}÷ì"<5ˆQš¦`£½Â¯æù@Âc–€:¼°ú -MDÀàJ A^"í`ÑîÚ ‚°¡LÇtÐÕB±¸½‹á¾Œ­Éd‹¨j’oÂÿPâ d]j¾q.Í ÂàÒ€ )˽˜°ã„Qê@[‰üÞGÂSÉ2[,²×dÿ¼ÔÕÄJ†!Ø3PÈ)q•öþë‹Â˜Ã·ê…l:|Ö|ZdídþÉ£üîMÆkõçC$xŽJMw ¾ç@¯ðæ›,‹-4~uï »wÒÝ®ÄLt%·û@å+aï›Þ=Šjšb擽ôË}š»Åu]ì¡V]Ë•v~Z¾ J¬ ýz5ö:Å1§XàŠšñyØj†5´ŠØØð¾A¤°ØävY€ÜaZJ@Ü3Ül›µ¾ jÝ’É»6Ê”R/Só=Åèø$T¥þ©oTðÖMÜ@þ“Ó·M×=Ô8$8^ñ‹º…#êñ/QB(¯ GÙÆ aܘæŒjpÔŪ <®%Æì)’×E;ª¡µ„ÖúŽ ÀieŒ×¹CIø æ6*ÂÆ“(=J œâ§H"?ïÏ~pÐÙŽ«:Ü Ϊ™yÄÖ ‚·ãÚ›ÀKÌEÝ‹œë”e½Î§ƒú¾š‡I7µ›å"§ï:# °º^e›Õ÷÷c’h­ùHÀ-O|xpHª´~n:Z¡-"¡ÀÇ’ÅŠn¸ˆ`©#ÁBŒænÀk¬õ¤1 ½sÜ­ f^7ƒ°ÚÁ.ˆÿ}a^ZC¢Œÿ-:£nµµûtF!U•"Z.¼QZU?Mg=a¥³>EDq èÎXµGg*2*X|ìŸd¥;þ3§Ex§×||þˉ$L¢HR´‰¹q¡Ï 0 ÝUÞ®ëågìU›/o²‰ó ªíG%,Úyš;€m‹Ý¦ëëä¥Ï ÑtPpNŸ]âŠÝ¦,«”Ùçî\9ÈË6–«ò¶yºå˜•>°@CxŸG’+ƒpGЦ~d‰_4©ëÌåÈ7q|=/\.u¼e -3ô"8w? p&°xa|cv‚‹ïk_ŠÀ dÒà´iĪn±q‹•Âð–bVdøYû*- †uÓ¶YU¾Û£¸ L}¦ÿ)e^“Y;o°ï}ØÑ°|Z[>ï«.6>¯p¬Yùò‡£”@˜dMþíà3œ& -ŠÉ–ì6uÒÍÝ®Á:ð°è¼îÞDÙ¡dß.ØrÿKÐþí« ,Ù>•½Ü¡SnD_ÖERHp*F\ÚÞmxÙ Û\ÚçàÜÃÌÅÜ”§ ‘ jµ'â\f”å[ï=ô¯†àì%ï0È¿ûã›ÿs‘Ôy©–›_<—  ‹uà–×}ÀpÅZlù_évûÉ»—ïüY0A` ‰–÷ú& !ÓÞ€«úquØå¶^¶ïMçc¡®"'ŒS:7qàO,›£mÅÿ Ù¸ÂZ×Tvõ,´&šµG+„­etpþª*~'Íh` ¶ªÕâ:ê¬×Ulöɳe½º}H~Ö‰îEÉ¢Ý;ÊÐ?Sˆ”¸ÿ€ø×:Ú[9>õ-6ÿ…VÆðá—¡îf¡Ü™Dú  CRÃõ€èÿÚÄ6endstream -endobj -1172 0 obj << -/Type /Page -/Contents 1173 0 R -/Resources 1171 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1148 0 R ->> endobj -1174 0 obj << -/D [1172 0 R /XYZ 85.0394 794.5015 null] ->> endobj -278 0 obj << -/D [1172 0 R /XYZ 85.0394 537.224 null] ->> endobj -1175 0 obj << -/D [1172 0 R /XYZ 85.0394 512.8844 null] ->> endobj -282 0 obj << -/D [1172 0 R /XYZ 85.0394 444.1158 null] ->> endobj -1176 0 obj << -/D [1172 0 R /XYZ 85.0394 414.002 null] +/D [1174 0 R /XYZ 56.6929 769.5949 null] >> endobj 1177 0 obj << -/D [1172 0 R /XYZ 85.0394 336.6639 null] +/D [1174 0 R /XYZ 56.6929 749.9737 null] +>> endobj +274 0 obj << +/D [1174 0 R /XYZ 56.6929 282.0726 null] >> endobj 1178 0 obj << -/D [1172 0 R /XYZ 85.0394 324.7088 null] ->> endobj -286 0 obj << -/D [1172 0 R /XYZ 85.0394 175.0326 null] +/D [1174 0 R /XYZ 56.6929 250.2286 null] >> endobj 1179 0 obj << -/D [1172 0 R /XYZ 85.0394 144.8676 null] ->> endobj -1171 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1182 0 obj << -/Length 4254 -/Filter /FlateDecode ->> -stream -xÚ­[Ýsã¶÷_¡·ê:C|ÀÝÓõ¾êLsIv’<ÐmqN"]‘ŠãÎôï.I ²œ¹? `±ØßîÂl–Û©"+,·3me¦r¦fËíE>»ƒ¾ÌY„A‹ñ¨¿]_|÷^è™ÍlÁ‹Ùõíh.“寰Ùõê—y‘ñìÌÏßüøñýÕ‡Ÿ?½~¡åüúêÇ/\åó÷WÿxGo>½þá‡×Ÿ^,˜Qlþæï¯º~÷‰º -?Çß®>¾¥K“~z÷þݧwß¼{ñÛõ÷ï®ã^Æûe¹Àüçâ—ßòÙ -¶ýýEž kÔì>òŒYËgÛ ©D¦¤¡esñùâŸqÂQ¯ûi’,ϸ(x‚’¥¨lV.ÿ÷ -÷ðÝ{ÎfŒeV)ŽCs˜ÕdZæ&rYãò<Ÿ/ۦߵ›Ž8ñ¹/ûj[5=}¾­~ÍsÞÔ}Ý6ÔR6+zù¹+ï*¿–QK‰<Ë Ø.u½®"Aà ÛWZÃ`I8žM+€ï4®ˆ…¯ªå¦Ü½`f^õBû½`C»¡!ËuÙ4ÕÆw÷-µÞTôÜwÕŠzn©¥{ì`j+WÛº©»~Wöí®£þ0Ãt!œš¶9[y’§g‹È} ¼½¯`âa¡çí->û‘khÊmEM]µû½Ú¡tf¸Gþu¾o²(þlØv{VPm ßpka±ãƒ9ÈB.=ƒwÍj™8.2&´ñƒö}½©ûGšBt7~½e»Ý‚x¢ ß±Ep› ÉÌ”/Q˜ˆô~WW¿WÔÒ´ÍâíÇÏãîn¿é½˜Þ¶^&ýOˆ‹ð6æ".2ÉY&½Š¼nŒ`*3@°ßcÝT}‚ ^ ãc±çÁ£´á‡™×5–ôyýæ'úîÚå—ª§÷ ˆWÕÔÍ)}3É4t÷Õ²F „ÃL(‘,À:¨@òý¡ñÒfynĬà*“ÆÏ1_vhLÚx-⌋ñ”Î2M¥JÁ![͆•‘Âûv—b*œLnƒ)p*ò|hø­aâ$ ¤»­At¿ âŒgX •ÎXQè) ÊÕjw‚‚ù]\ÂÆ…˜?¬ëåš”GB¿Êåò,Kä•1Μq’濯~ú]RK»‹-½9œ2u``$W'´ÌãZžd,çè ‡í1phBʯflœq1žò˜± ™aàã°§+2›ËÀY°»nÈÄ‹K ‘ƒ³eàÍö×ÄT&3 -ìúhÔ¯¹ÊKPà]Ý}wFvz¼¯è¹÷†ÍcdGOoÎÊÌêÍjI6|åÏs8«W$œiQA`Á5ÕÝ‹ós -§rnI’§ƒ–r¹¬î{òvÊ)ö–Í£o¸¥§# _Èþ¥£qD¤›g ©B* À¨–Ï[ê'ƒF¿¢UF“’z‡½z=ñ Ã2  ‚qôgð’#þH›i”>)­L˜ŒÂT‡ãÿZa .Æ3Ë*“ Œ€5ÃÂOɪÌrV¨3²ªAgý—/S.ʳ‘† Ž+²[bÞc»Ѳ6H4µÍæ‘ÞÅǬµ:Bó³A*£F6'$!‡Õ6í²ôË­Û®GêßÁÈöþ¦\~ñg=ˆ—…§RBÔóD&˜41Ë•f,A=àhP@¨ß¥o -%#ãSÓ€nZÁ‚ðÀHÝA Â#ÀJ•>·ÎDÃ˶ü£Þî·¿,÷;ÄXŒ1a A2—ÅÉà¹X¢§ó°“EGîóòpŒUb:A#ÂN–;ØNØÊ8úú•s™`ø+@ü`Ɉª“FTeVëb6åftsƒ?kZOÚM5P40*! _F³ÓÈ™å@˜ÂCUøzf\Œ§L@ ïŒóaå' çÂì ´™ ¨ˆŸøu0¦åGáhj{o~ë®Ûûþ†;p˜†®ã€I£ôêfzÁæþ·^œ/£¹yl{"¨Þ£F•›Mû²/( ÆÉ@±ÈópÀ_ªÇ.m9u!ƒªCP¸wÞ‰°`vÅ"NLÆ›±ËäJP£¸·DÐ0÷ØÁ= b-èàn[÷äãáó¦ôBË Íâìé Xƒ:Èpêh켡›Hpa3=Sœƒ ‚˜ù«%8̸O™`®!¾ˆÃÌmÙ,ªFwR|C"ÃŒgˆ”9ÿØyB$”šÉ „Ö¾QÀ!^¯k/ôäÁ&‹yWoï7þ¯~ -Z™£›f'‹7`e´\h}7hD]˜§Èå¾ -Ù”Çú– -šB„¾A¨‹"~³­Œúzôf\Œ§L¡ožÒ²aegxWi$bÀÅø]T—¹ñìi½ãJ+FgÏ-;£F!pÿf<ˆ3žá sìiÅÐy¦ €‚oGd˜ñ‘¢#vcLä)ŀЫˆÐsdÜÜ5-}¯‚_g¯%ì$§’cД<㾩ÿHÙnžiÁŠtJES*…O©hJ©èùϯþE«v[Ö µù=ͯ>¿¢CrAO’ nÄ}Ù¯©+LçǤÆáw.é¦Ázh&˜»]»¿O;|«clý4øh=ÿØöž;Îi:.m}Ëý¦ìÁ(o;bâýÏûæÇÏÔë)Âè, -Ü$:þÜnJ°³p¢ðâüv×y C q ǰ;•›?Ãëa¹A›ðãþ~S»f>w:d@úh¬Ë¾CǪö1CßîýݹM8öGDiƒ÷ºïªÍ-±‹“ÑÓÊ©l@£¼°óû]½-ðQîûu»«ÿ3Þv¾­P‘ënKYaJ€‡,ŸË§;´ê?¢ÎÇÓ?44‘t¡_ÂU€7öR‚nr°G_oÃŒ‹ñ” lÕ0mqس¡ †j€Õ)sÿ`â<3Jz¸¹Ü[ÈLXLò ]”`ø -c˜I€Û«˜¯æQ˜p1žñ˜Eü†oqÔI0á‚ß`¨œÍfþ®${”} Ííi™ÀìÅôÍ7Ûoœñ̆ÑlÛ¼°ÏØ1¡d ˜ 9å ¸É${B €dEû 7f<³aøÜhðˆ“ ŸR ¸OÅLG[æÄ™MdAKÏêj¹wN>FU'ø¢p7ð ^ô²À_•ñ¢ô¹ªNÕ~en2‡†¤¾ÝÝŒ^>¥ªÞãñÄ‘(ÚÆQ¸Õ_>U[òšÏ?RK‹ùÛšj}3¡:+Y:ûÛQ| TfJLh?ª3ÇQgH†#ÉášëæhUÀíŠqö\ŽÅñçÖ?š×ùuŠß‰;"¢ãœ•gøG¡ãx¶‘§×!n„£©D+å@^yÓî{ê9D”w·÷ñ ô†¬Æ >àG&§.¹NVh\æËžÉËæ™Ôâ ­Ä0гÇyD¦0˜0.,@LÓç ²7¶×½àK#åcï -G%fi±ëåK6J36¿jhHï2Ø·,»ê’ðsœ³Üt-{X»RŒ‘§À“²+”yÖ- !£/_ÃÀM„ØÇ¢šærŠ6F籓œßìý˪­\<‡bç›Ö¥+ÿÃ[™yŽaÏ$F*P‘’4eXÉ>+h !y=pàÞSíGÑ(W¾eí·1àZübYé¼´ûÕè*—Ã=ѳÄêA©Ã¡‰E¦Ü°‘9È<8ô?9’`E²Ø!L`àwUŸ´,Å8/‹¿¤¤ã÷*UEQ( QÞ ˆ‘»Å çxþ‚ÃîU¸öèü JÆK:]XµjèÍßù¶Ðy³¯7=ÚéŒ.넊%ö-I>Kò¾y¼ ÝT›.ôAÒïi.Ch""{ðÔ.CÈÌ÷íf,k°†ˆ('_ îpcÀëù¢LU¥1m'ôÔÄ3ÄÕyq\9Hœ5 –µŸ#7Ŭ¾†íc¤ˆÕëÒ—½~ú’7e?,4uÕ¤ø /»²éÂÝ2c),„vJ¯ø Gú]þtáÍ\úRæk.N‚Ñ«Ú/K6ZœMqlш@åF­ê»º§ê$, oÜÚØ\ûj¦ñ¶:׃NcëP4-üò.ü0Žé×{ßä¨Ã&G¾ÅsÓ…Rž/äv0ãÎâ!¬pÕÓäÛò ‘…ûðæZƒ«›}`®Û®«o\žKx¨-4Uß±Á]1ˆ½ÁM’“„n(Ðnè1€œ‚„h0 öó„_jwAö rôŽª•ÂúbÐË9ã CÉUÜÀn¿Ëñ7ÚÝ¿Õ`x~eLš]ï”K·2•²w‘6 g^t-×Åxi§#Ò;àéÙ!½tcýKÔæ2‚0Šâ¾ I9$QŽM ÎðªÌŸ²-€ŸŒíò¶wAÕˆL §æ]¿†ðWä=CY¹n1l6G9$‚ñu³¬(‘Ú'-”„8TIþ, e†+K …³;Ì”óxá¹:T‰w«·ô¤je$ÈDÀ÷àï«ã¶÷ ÖNIpÔÞ]„¥¹oéI Â_jf/ˆUVd“BGn}¬,Ö+ Þ~³óˆÛ§†<ŠÁâ P” <ô¬ë»µ]ÝÑ+êqWرÂúº2Ý<â‹ù¿»Üû‘¡J/ÐÊwµNAI»;¿lÐ¥ü8ñ„Ag¼¨©è‚š -ð^:ˆó}×í¤K⥛Êé&6iÝjÁëv¿YQ#ZGO vblâ9µ ,];wŽ;éýË4ϬB¬…/{ç|ÚÐÒ·‘’MN–ª ©£U#X ìèWXÅïøÄÚ<¸£ç&®˜( æ™åÑm>î‹@7T Ÿù–(Céï8ÿ‡Tó¡²qï†ùÛ8"œºmëê!.çwù3ì[€+ W9pLí¯ 83ä‰óöî·Œ›÷—•™D=Ñ2J™@bÂUaÀšó7ºdÄ÷!»vI—ƒzÛ°ˆ¿P¦çMEé9ןk¤'µüÔZžPC=ÜÀŠR‹7~e¯òËÔB o]6>=E«ò&üÖ¹Ô@ø%€9‘½ñ,®f]ú[J£¤¼ -—ØèÒÒη=¬ýͬÁ4åÁ>cùßQÊ-ÆF­êÎS<^e-ñƒ`èe$ \/ 'ƪ)ÔÂ1‹¤Šg¤vº0Á/Sâ…Y Â&çdòäœþBÀ]2î‡Cáè_¥¤5“˜ŽA‡ÿ³ŠgÚ -Lò$UÄ„Qþaˆlö«*ù0v%p;Óü»KœQÕm½©Ðø¼:•ZÆJ…©¤d‰ÿê9e¦5& ø‰,«6„ "…»ÅåᓎIÿ?hPU‡endstream -endobj -1181 0 obj << -/Type /Page -/Contents 1182 0 R -/Resources 1180 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1148 0 R -/Annots [ 1184 0 R 1185 0 R ] ->> endobj -1184 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [55.6967 404.4849 256.3816 416.5446] -/Subtype /Link -/A << /S /GoTo /D (rndc) >> ->> endobj -1185 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [268.5158 404.4849 332.4306 416.5446] -/Subtype /Link -/A << /S /GoTo /D (admin_tools) >> ->> endobj -1183 0 obj << -/D [1181 0 R /XYZ 56.6929 794.5015 null] ->> endobj -290 0 obj << -/D [1181 0 R /XYZ 56.6929 724.3071 null] ->> endobj -1031 0 obj << -/D [1181 0 R /XYZ 56.6929 689.0661 null] ->> endobj -294 0 obj << -/D [1181 0 R /XYZ 56.6929 117.0915 null] ->> endobj -1186 0 obj << -/D [1181 0 R /XYZ 56.6929 87.6248 null] +/D [1174 0 R /XYZ 56.6929 191.4593 null] >> endobj 1180 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F21 702 0 R /F23 726 0 R /F48 940 0 R /F14 729 0 R >> +/D [1174 0 R /XYZ 56.6929 179.5041 null] +>> endobj +1173 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R >> +/XObject << /Im3 1172 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1190 0 obj << -/Length 2372 +1183 0 obj << +/Length 2134 /Filter /FlateDecode >> stream -xÚµËrã6òî¯ÐQ® -<,Ÿ&ÛëìÆÙxœÓdjŠ&a‹>‘²W»É¿§)R¤,ﺶt`h4ºýB‹-(üØBKBE.TI™\¤å]<ÁÚõó8A‡ ±¾»?ûöJ¨ELâˆG‹ûÇ-M¨ÖlqŸ}^~üÛ‡Þ_Þ\ÒeDÎÑåw7·ßãLŒŸ?Ý^Ý\ÿr÷á\…Ëû›ŸnqúîòêòîòöãåyÀ´d°Ÿ{ -G6\Ýüã¡ë»?þøáîüËýg—÷½,CyVßÏ>¡‹ ÄþáŒk¹x%,Žù¢< ¥ 2¢›)Î>ýܬº­sú“B©¹šQ g ÆH,%iPÆ$\8 Z¡#P¥t™Wi±Í Šø©MZSšªÅá÷æWJy•·y]áLReüÒ$Oƪƒ£ X&Bp¼«ûU‡ÄH,&”Ó-NÇÁ”˜ˆH†^3`NHØÖ˜MÛà ]šµIs˵±ŒŠhiáÂ/&íöºÎ;r/+³9gzip[;Ë85‰ÀïãÜ3mª´ÞV­?7#–Î"!#\3½úk|M‘R¼…E˜ŒÔ ;Z-“4/r;gùÒ‘W¬$Y™WyÓno°X?âZZWVµOÛá"*»AŒ‡~×fSæm›WOäQî$ëWê ª@‚öt,:  )½lr¤!(r!(\w]œiW°ØàìöÅɪnq¦†C7 xz¨Ôò -Îq³æ_I¹.Ì70âùrD÷ú±Dà’Š Wzg±óëMþ ˆ8øÍìÎÙ²éxIüÞÄÛ”‹Žo´“>y(¼÷ÕU±CèÁQUTIé!0úg°ˆQ¤7ˆ¿Ã!`{àØ{OWÞÓ-‹s^~½IÊ2Ù µwfG BJ_ó áÿ8Ù¸ ± ~£KЧ.mU"&Ø\ÑÅœ.“nL;E è"öŸG$•…½äú„äÿ¯øÆ)x?½»ÙÓ§„G*1! æ/3dÌz’&øiVÞœ2?­¹±ßåÄ´À£3p¶A஡ûO7×ýJ%mŒ9Ìg!U$âÀ¤ä Î0v 7O dž0 žÒµ‚2)jßr™l”òt<âf’{¬SÈq;æÐ4$“j*A4„”SÝáà 3®4¡ûF‡– ZmH~êÐÖ).&ÔöaÒ²PnŸA|UÒ%,Ÿ=“ö ~AÀ¡ –8åÇ¢‚<´?ØèHœÃ3(Š\ˆt¾åÆI¬µž…=Å`HÒ)kÌÔa UGæjñl΋¼›¢ßX“fàM WËߪú¥B0ið‹ -´k®„á‘«ÝNŽï‹Œ+Y]&¹ßïëE€¶UþûÖ¸ÂF¦ª6ÜaÉÍ£ñŒ±¥sM¾¼iq]€‡Žžum¬ÒÁããèóš£Â% -I»²È²3^J e|îédãFˆ4éC–@ cÓ=› :ävÆŸŠ³õ0jÁ¾ü©œX0áÞÜ©NENýX,ŒB\–!/Ç/“6]ùà¢G6“cK‘#Ëðr¬h½Þàvü2 <;êÒ¿’ô¡À°¾Jž ®=Sá\/ À^í*I;Ö€c±§ìEÕª·²Xí«ønìË¡™‹QÒ/Ÿtk[(+ѹõþ½pèܸ(NH™-!ùû}Û †g\;„Æjpðq׆ÊG²þ%j„=VÝöƒO„ñVCp1ת€G£ëV48×m0PºäíîÛd  -›ú -ÄíÔ® -UÕòî*óû¶ëum›"Ó·\‡àV”omU&iPfrF"xLiNU¬¦$%Q²¯%x¡°RRkqŠ”> Åy8C,²¸ýÃéÍ|q%&ÿ[bBÏrY3êËRï'ä€*”ô$ãGéu‘Ð?ÜÉ6èJÈ B´Š†C°µqSˆð ¬`³ta£Y¹f}£Â-x3B<á»Ó×k(Ò0ZÀ´Oîbi›Då¶D¤j[>¸ ®¢–û÷ÏWG6wñ Ö×8Œã -ÉÔ`Yû®Hì¼Ê3`ß¶nÀî y"3ÊŽ¡>f‚Zh éŒ¶#Jtµ¡íAn>µ"ÈcQŸ¡°wq²‹H³p•Ë{CVG0Rœ†,a[‚1Óûƒ1‹º4[+©å lYÍâÍÆlÔap µ¿ ¿îëüÁÝø­t˜6°“Õžp1wh«}¿Åm EßkûRÒ/$¾àLD!l5ëQÆ·6Åbß*ê§'oÑÿKc óxGcßc -êUÛž -û1ú†Á`ð ¶¿ïài')"=æ…G_'í -wíÃùs¡¶h $48ÚÓê<ÖÂàg[y™»;𸠡/s©ßÓoò› 9n¸3˜•ËŸÚìPåþê{Ó»¹ÈÐíj3³ÙÌñõG'_Qìå¸òÁæ1¶ kw{E¥¶÷œ&ÅHIpj=VÛK²©zCèN¯a§é¦ìÙ>ÐŒdÉ«Çz´-3[OÈså;¨Ëê®?O‡"5>>n$è<¦ lF_õâîŒ7N¶ª¾8}÷Hi¬¸7SbSJmÞ¹Ã)*óõçxËÝNy"6ýÈ£Ë:ºNy'÷–nÇ6èÏý?)à™*fÛ§´—ñÝÿ]îÿØ…òQhÍç ‚FP\ƪcÊr.Ô!çýŸœSÖÿkɉáendstream +xÚÍYMsã6½ûWè¶òVˆàƒˆääx<§fœÄvN“©)Z¢$f(Ò+RV¼»ùïÛ$ʦ,;ÖTmù  4¯×´pøƒ4a\Ùx`lÌ.’Áh~ÄS{w$üœ(LŠº³~¸>úö­2ˬ–zp=éèJOS1¸žþxòËõÙåq$>Ôì8J4þp~ñ†$–~N¾x{þî·Ë“c¯Ï¾ ñåÙ۳˳‹Ó³ãH¤‰€õÒkرàíùû3j½»<ùðáäòøÓõOGg×ë³tÏ+¸Âƒüëèã'>ñ:âLÙ4¬ Ã™°VæGq¢X+$åÑÕѯk…Q·´¿X*&¥Uƒ(á,b÷®´‡]}VZ´s{ÓHˆ„©D¡Kâ˜qË7.‘¢ã!3Ò&“X¦•TÎ'ó¬ióEƒØÀ|ÕÏS&bƒûàÄqþ;ç²Ê›ãH™d˜áO<¬²y>&IÐä:eÑ´4cR/HTT£rÙuº4޴˯²òšš2»ËÑ"ØŽÇl’Hgÿë*'—®7ÃΨ̖MÞ°‡N¸a©ábÐæu`++Y"´DaÂ!ý'afÊå>ÿ©Â:HêÛ }†ÿFuÕ.ŽE:¬K„ͦÃiYßd%¶í°Éwù‚ä0]=].²Ö¹ '„}Ü ç)l4yÛÐø8Ÿd˲m¶ÝF÷Þ…:ªng¹o6mÖæó¼jŸr[C¹-„ÓóU†»Ý@K¹÷ÖžTíñpïušÇc<_´Þ×yä!wí!ìxaF?·¹s}´v3Èn²¦x +üÍ©^ÔW½2:™Àö€¯­ei¢cBÒS1j¢Ñ,«ª¼|Vúƒ,ã@Ä ˜h N˜Ï—U1ò.p¢ ÎõÚš~§yKl4Ê7hpöìÚ+cÁ¸3hOJ®M‹Öó¶®Ùæ\»½ÚÅëÿøJi#¡e÷Ý)mfcMÇoKxÆÑ—üþeÏ^HéЭ§þ›‹««³Sj£Â'í˜z¨‹ò5Õ@7x¬ö!ªÁÛ–ÓÛrWä«#é3Ž[kåð à:8qPàâ”űÝ÷(ëD›LÒ Où›ÀáÚ'@ëXs(Ð6luýÅ5V€®-úû÷VC„,6r™4Œ›mÚüˆ>+®Y*-X­X#;~Qê5Ð\ÉGÀ¯gyOÒ– Ö;¥¬§Ó¢šöxO¦4xšæ!êÕ¥ò÷nn¦à\˜ðʯ¹P ·÷á/Ck4ZUòÍ«ÞÇØÚ²5yž`HK¦-¼ðG!81,£”TœCŽJÒw òõÓ"›Ï3OWâîy9¾E‚ìhÒáëE½ÿ8RÞ‘-FŸÇ x?ϳv4û쪜=˜Lþ¯ïû6Ä9Úß=<Üs 7tóŠ y"F ßšlÚwwœtw(‰4„îÞ“|­ìC×Ãî1”@MSL‡‹]‰…?Íýü¦.‹õUl!½pÓ*ÿ P?qëõÐaJc,TËŠ§Ãs¿Õ”¨%´ŠÐØèžP¥0ß2ävQ@ÜS +.ò”Š™LeºíÖzâaݲɅ6ÙM´©ùŒ|x♑«ÿ7… + ÞãDjþÎ~rú¾_ÁÖ¥†aVIã6¾¨[8‚RÏ,à +TiJ¶ŒÁo Ž¡1ÿðb‚¥óeãuÜxIÈÙc¯ŠvÖÇãLÊ,_'ú !hãnr¬’Ð:Ú¨ð‚õdFàÇ$¢™¯fÄìóï±t¶Ãªö÷ÇB°ñÀ-°ÅŠH¬vZ;ñ: ±„·(˜â:eY¯òq/ÞxܤI³0sº.:©GÕͲ(Û¨¨¾{øÀ 3cŒ„, ùH‰ç½FPÕkc^úõ­ +vðƒ’/¦HÕÔN!¥àUPÌhésiuß4V}OÂ#ôxí³Òß—YÝôVÕÈ ýwy-…PLkÿ*˜ÅXÂ+µ3H)7ßU?ïz´ª~fc…Ù«á5f«;®öa¦°–žïŒ²OÿÜŒ‚ìŠ7ÚÈáù/w1‰è %‘ö¢MÆ ÝË“(ZAPåíª^|¡NQµùb’Áð êû¤Ô†¼ÓÜCÑ6ÂsH^[ðÏÝH%I Vìôœ4šÅ©Ýí ^a6®«ò¶y¾ë„]b†r1O"dA4D#äT7² _ò)Ž­ý…âI_Í +|Jq‚s ÊÈ5}ßqg:W(â.BnüÎè»âUí˜Ì % M×$¬ê–·Dî \б_‘ÑÏÊ‘hh´0è×sØf^T½—)¤d앺‡þO’”yJ¦í¬¡¾ b”£¨éƒZ[AïH—žW4Ö,û‘d%FY“Óû%È0 \r]•ìvu´ž»uC6µÃ¼›ðÖ'ØMoû6_Ë›oHö‡#AÄØ¾ô±^‰Å©LU×Ö%æô½†fî¾µÝëðº+¶¹µ/)sO,Á<‘ þˆÁ NŸYæJöµ•Ò;ÅOø–H¡ŠN즦S¾rŸýé“ÿ ;v&žŒl´lê¹@·.ÑGšW¬¥2v/»ýìÂËuþK*„b‰‰12«Ä©ø§"¥$ý´Úïr[/ÚµîM瓯A‘ƒ#!9ï«6ià/bÍ!†¶Žä¾'5ø¿{P”ú] +c˜á©Þ¾‹PaŒm-ã½(.«âOÒ ê jA£VµœßäÎzU…fW<]ÔËÛÇâhŸiâ˃´¯tïûï«JXLáýððÁ^ZùÜÿÌnþm .Viºã«ÑúÚy£Ðr•<ÊR*eI*MéÿUÜU?endstream endobj -1189 0 obj << +1182 0 obj << /Type /Page -/Contents 1190 0 R -/Resources 1188 0 R +/Contents 1183 0 R +/Resources 1181 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1199 0 R -/Annots [ 1195 0 R 1196 0 R 1197 0 R ] +/Parent 1158 0 R +>> endobj +1184 0 obj << +/D [1182 0 R /XYZ 85.0394 794.5015 null] +>> endobj +278 0 obj << +/D [1182 0 R /XYZ 85.0394 585.0446 null] +>> endobj +1185 0 obj << +/D [1182 0 R /XYZ 85.0394 560.705 null] +>> endobj +282 0 obj << +/D [1182 0 R /XYZ 85.0394 491.9365 null] +>> endobj +1186 0 obj << +/D [1182 0 R /XYZ 85.0394 461.8226 null] +>> endobj +1187 0 obj << +/D [1182 0 R /XYZ 85.0394 384.4846 null] +>> endobj +1188 0 obj << +/D [1182 0 R /XYZ 85.0394 372.5294 null] +>> endobj +286 0 obj << +/D [1182 0 R /XYZ 85.0394 206.4979 null] +>> endobj +1189 0 obj << +/D [1182 0 R /XYZ 85.0394 171.8379 null] +>> endobj +1181 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1192 0 obj << +/Length 4496 +/Filter /FlateDecode +>> +stream +xÚµ[_sÛ8’ϧÐÛ)W ó”Í$sÙÚÍÌ&žª½š™Z¢-V$Ò'Rñø>ýu£” Û[É•HP£Ñhtÿºæ |¡Ë¢tÂ-ŒS…f\/Öûlq }?½àaÌ*ZMGýõêÅ_ÞK³p…+E¹¸º™Ð²³–/®6¿-ËB/[¾ýùãû?ýúéÍK£–W~þør%4[¾ÿð÷wôöÓ§7ÿøÇ›O/WÜj¾|û_o~¹z÷‰ºÊ@ã¯>þH-Žˆ~z÷þݧwß¾{ùÇÕß^¼»Jk™®—3‰ ùŸ¿ýÁXöß^°B:«÷ðÁ +îœXì_(- ­¤Œ-»Ÿ_ü3œôúŸfåÇY!d)2|Áyá´3 jW”RÈ$ABaŒ-×];º]O«ü¬gL´ÍÐt-µTí†^~í«Ûe3ÊÉ–±ÅJ}&i³®¶qŸ °4m Æ1‰…sjŠ!©0®™“¥[nêõ®:¼ävY÷Ò„µ`C·£!ëmÕ¶õ.tµ^×ô<öõ†z®¨¥èaj«6û¦múáP Ý¡§þHa>’¦e.V%+@«Ìb•öïîj B2,Ͳ»Á§õ?ò mµ¯©©¯_ëj^3 ”_úf“âÏÆÕawuÑÒð —';ßÉp¯Tð¡Ý¬3› dÁ¥±aÐqhvÍð@ÔQ Äwæ[wû=(I` +ú½X¤p…TÜF¹r$e"Ö‡CS­©¥íÚÕ?O»ûãnjzCrØ ?!)ÂÛTŠ8=è$·…qÜøiß´Ip]Xà8,²ië!# ¯–‹©Þ¦ IÝðÃ.›ž+ú¼zû }÷ÝúK=Ðûô«n›ö–ÆT¡™ú»zÝà„ÝÌœ"UÂÑבå»SË$•+³rQ:VaÄsl“€Z›·L«Dq5%ÍÎD­4ì²3|œ9¼ë9¡ +^0m?#ÏßZ./Š@i0Êt÷»‰ Q|BJ›‚—¥™‹ ÚlD yXÅ+X¸”Ëûm³ÞÒéQЯ™²s«²®PVÖz{&,hZøþðËWE-Ý!µ”ôæð§© £„¾pÀŽqaÔEÁ +0òVXž“õäš®&ÏÅ +ºQXî.ŽzLª²pLE±‚ÕõCÔl¼"7Ê £¤òÿ3CÊVƒUŸŒúiVÁé=4ýxç$^èAðM =wÁ¬ySŒ²ïéIº £âFÙå}³Û¬É‚oÂfŽõià´@–s +F¨­×è\¼—ÓHÊ;%E~Zªõº¾È×i°·jBà ==[øB^ð?zGLz:#K5jOi ½tbÙQ?Y3úÍ2!J*×ÍóD¯'ÓÀQ\ 7ƒ†è#o”Õæ¢ªri ر„“kKðߪª‘àjJñ\U¹â`œ'~LWUÁx©ŸÐU6 yý:矂ip ZvCÂ{莠ZÎE ¦®Ý=Њø\´ÎRñ$6pTÜv4wÁÔÍT¸´€ŽÁwh&­¯óÍ*)®¦$3*ì±5„i²¹¯B¥ós†Ñ’ß‘ÉHñ &à¡:ϘD ’;gª¥u£w”°‰WÛ&è=E´ÊrÙ7û»]Øä¿ÄcÉÐQó‹%X°*™.4¿;´¢>ÊÓätˆÙ”‡øVZŒJ¾A©Ë’¼-`.¾Ý®%Š«)ÉüE©gö–w“Ç"|LXE½ó™› ž.x®üÁ(aï…ãO £º7$ŠOÈ@*Ð9~*ƒüÁ0¬Ð`Á÷c2R|ŠI# mÐnL™¼t0 ô*øœ7·mGß›è˜ÀÛ¥åÜ1½Éé1–öñØ6挷(Œ"Ù”Š™¦TÊR1”R1Ë_?~øulº}Õ´Ô:æWÌ<¿R†üЉÉ3K.øwÕ°¥®H.Œ-éÇßù -Ë7^EŒ*a5ê4ýç‹-cÜWŽ,Z"Æò„hð‰»ð«œà…(eÜ3ôAyhnYʽÊÐÑ…)÷rßÖ¹ØDB,Ü£~̇á2޹=tÇ»¼Çw&…'ÉQƒ“6Ëݤ㽦—Ò>´Üíª¬ò¾'‘!äÿ|lþL½# Àä ÂÍäÏÝ® 9; +/Þq÷}@Ð0Æ'z «ÓÌþ;²§~ÜÝí¿Ã<$OG†,hõéwèØ4!lºÃC Ð?µ/¾éˆ¤mðÞ }½»!qq8È ¤hôøég8*J·¼;4ûÊóÕqØv‡æSÊÛ-÷5ä¦ßSZ˜2à1Ëçꮆtæáß045‘u—°_ÆW„?„&˜AˆVªïWS’l×[Töll‚Á€uJ¦ä?˜¸ ŒŠž–‹ ƒ+‰ âR•óÎ œ…uV.„7`²¿YD‘ÞjBð\@܆oqÐE(áƒßh¥¼ÁPvù®"{–z‹ÆÜe…ÀìÃôÍ÷Zl"øøjÑb;Vº§—Ë_hU¦RfG.ùaÁ»?¢þÀ0*¡û~«_­`n xÂéj/é¾¼§S饧õF+â­%®¿£gýg½>z_“j|Q˜…/æPà/ȸ%ú\×—ê¹Êª‚iiq}Ôw¸]Ð˧\%{:žä!3•ì4 +—úÛ§zOnψåG*_¹ü±‚æ–ZßÎø‡NïAÖÞ´þqh]€u’3ÞÏjÇiÔ,ÖƒïÏM{6+àuÍ®ÄÒø§æ?£ëÝ9Åí$ˆù +ÀAç±`^©žCõçÔ&ÞÄx¶¦i¤T#{Õuw¨ôÁÝí1Äг ´õ¹š—&[˜ñ)/÷DF–ÊÈ“|ÇÏÍ+¡>ƒÈ5f3¦E€Hù™GŠô`ÿ zàçUz$í3±E@§ˆá&éTdëÒFþ¥²¦¥œ&d1`"ëÇ@ë@;¾Ö¹ŠFIúÁ3¨Ü 7çôK«×Qãî}¸cØItŒ·sú8kÝÒ[¸È…m±óúØì4ÔÝÒ‰ÅJì[“~Vä~YT¼ßT”.ÍIDù¸”!$‘I<¸k¯bÈ.Qìvªk0‡L‰¯P>·¸0õrUå +Ò˜¯“fnã9"jV깑OW°ÔIÄ®±¤ýÅ)Ç4õ Hì˜BD¬\W¡ä= +4”»)íá ©¯g…ox9Tmo•YGñ ´S^%œè +Û oöU(cn±Já$½i´dT Å/à +¡”›ï⦹mªLÂÄ馅¡‘e&T2m0ÖÌŒ‡[Çr |ìÁâW·ñ‡ḭ=†&Ï6yîð…Lžž-¡˜¢TêéÂs£÷&-ø€ßW_ˆ-\G°×|-í{Ýõ}sí\2€mi¨òŽ þn‰Dô ~’¼$t‡MvKæD$͘9ƒM iüµKh8¶(Ñ[*TJî†ALç­/ ;zVlÃõô-6HDºsxß¾„¥FË ¬àÊž¤ö{‚å +ô­Ê%ë}ˆÍã䧆³ÆL9ÚŸåHð âPA»±t‹Å‡jó©@E¡I_Å쉳'ç¶E€çàÂÿ=ãâù©TÌ®nVMØt°kÁ÷ˆ}µ9A®!Íß´v»³äÙ¥ÏM»®)…:dM”‚@T+ñ,eÇËJ3…Ô=jb"Ývàþz•áýì=©P™ò#ò݇Ë* ¹ýèµ?%8êèïÀíz’„ð—–@Ú+’•“…ÁtÐLT§§Å…Ó‚W_`óæÃö¹å…†€£d4yÒE%)C=ÛævF×·ôãšz¼É•nzbCI™®óåò¿½Ã<†‘±B/ÑÌ÷×NIéºÛ0m?ä8b‘8)ŸÁÉÿ×ã <ásä £ %Æ$*“瓱^}ð.CFó/ó¸]NªèÐY '£ïº&’»G«±ÎÅâ(œ3¢üFÎÓurpóëXh·üÄÔ^¤–ÏaÇàÑ3v¬YÞTkt +ÐÖÏ® ˜é$5±HN‘³É^6 +»§tŸÀÄëjä`¦ä£L=tç’JÖɹ[¾?4C¸Â[ô«CÉ[·P«Ïüac~595_È3fù¡ ¶ÖVxá +]`‚ëYÚ‘aˆéÍ)ö¤Ã‚íw‡æ«w9øø‡n0²Nð-·3õÄCh– ý{ØÌ_üW£\! +’RæJ,…oþ§ÁIÊ`FP\¨©[( DS¸rYžqÿ»ðœõÿK]mendstream +endobj +1191 0 obj << +/Type /Page +/Contents 1192 0 R +/Resources 1190 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1158 0 R +/Annots [ 1194 0 R 1195 0 R ] +>> endobj +1194 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [55.6967 480.2482 256.3816 492.3078] +/Subtype /Link +/A << /S /GoTo /D (rndc) >> >> endobj 1195 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [406.6264 524.1437 456.8481 536.2033] +/Rect [268.5158 480.2482 332.4306 492.3078] +/Subtype /Link +/A << /S /GoTo /D (admin_tools) >> +>> endobj +1193 0 obj << +/D [1191 0 R /XYZ 56.6929 794.5015 null] +>> endobj +290 0 obj << +/D [1191 0 R /XYZ 56.6929 769.5949 null] +>> endobj +1041 0 obj << +/D [1191 0 R /XYZ 56.6929 749.0409 null] +>> endobj +294 0 obj << +/D [1191 0 R /XYZ 56.6929 209.5509 null] +>> endobj +1196 0 obj << +/D [1191 0 R /XYZ 56.6929 183.9497 null] +>> endobj +298 0 obj << +/D [1191 0 R /XYZ 56.6929 147.0778 null] +>> endobj +1197 0 obj << +/D [1191 0 R /XYZ 56.6929 116.7981 null] +>> endobj +1190 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F14 737 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1201 0 obj << +/Length 2349 +/Filter /FlateDecode +>> +stream +xÚµ]sÛ8îÝ¿ÂÊLÅòC¥ÉS·›ô²w›½K½OÝNG‘[³¶äµäd|·ûß$HY²ä:½Î’ €ÀlNáÇæ‰$T¤Ñ\¥‘”Éy¾™ÑùÖ>̘à =RØÇúa1{{+Ô<%iÌãùâ©G+!4IØ|Q| +ÞÿíÝ?7W!—4ˆÉU(cüpwÿ#ΤøyÿËýí݇_Þ]©(XÜýrÓ7·77÷ïo®B–Hû¹£pfÃíÝ?núððîçŸß=\}^ü4»Yt²ôåeTAþ˜}úLçˆýÓŒ‘&rþJXšòùfIAd$„ŸYÏ>ÎþÕì­Ú­Sú“"!2ájBœÍ#©”| A™’Xpa5h„V Jið»> xÛ¬Õ]µNÚ]¶Ùd;#íÛÛˆõ.…ÎCbšXb–@Œ”¾”Âÿ1ûæ\Ô¨$ìül½¬we»Ú fÓîÊjymñ©ÇÄ‹nt¾Óí-œ¤û×5ò:”HJJ¨¢¬“<¹ ùú7JyU¶e]áLVüÚdKíŽS*Qö”ÅJw¼‘8%qÄS@öj©ÌÕ£ŽŒ%2¦føiVpK, táÆ 5;v»¬˜xªwìÀ \B‹wúJÚh}jåU$æÀdÌa +” ö†‹»å‡žvøah_à1]#øG£ö G`ß#n¤$à½é€›‘“tX—xQ3<€"2àõÖ®œÞò\l£P”$ŒË¡5櫬ªôÍæŒNYÄà¶c5iJø%vØá},Ë)Í61`r8IAlóHz¤ÍçëçŸPòš$¨,Æ(Q±0ÊJH"hú Å È|Í_'ŽØ„¿pyV!Pçù~‡`æÖì]r*ƒ¶ÞâÌZ?Ûû2øO$ TWÆõ–û]æ4 “ffíjG¾¬š²psÙ„L‚J"¹òB=—úe* +ÀK¢¨<• +*žÊàïúÐà … ÆŠ€ECÄhaB—0œáä QÔ1wJÁ£rAãiDGo:ª€G_ˆ5$Äÿ5NáI€$N&‹ÖêªÀMc–£3”cJ»\I"˜Šspkí®^7RÀó™˜gæÔn¬6#0Rˆ røsb‘˜I5—qL"•$—ÜØã‡ý Ž4¢ûJW– ZÁ¬O~ìÌë#jÇÐhXØì÷jÚ ‡¯¤Ü‹™¹et%XÀ¡ J˜ q.*ÈSûsÚè@œCBÇsÁÓ©ô5'iÂMæcaG1쓴ʲÆ%‰RO6,–Å”97E)Þ“fàM WÁïUýR!˜5øEš5›¶ð8¨²¶;yP:¤ WŠz“•n¿ÁBh_•ìõú€#SU[> «ÂMƒcuMܵ8® À£§g\Û^Ÿ;dŒ£Ï×.QHêS¡FïžõnÊK!sc|"¸Û8†"ϺЀiÈØ`8’@ù½]enÆŠ³u?jÁ¾rÙNL’poé‚”W‘U?&ƒWÈKãð7Y›¯\pÑcóŠöc˺D–…¬$I¼Áí¸9d ²‚ܯ pN†õUö¬qíQë +ç:avÂ$6{4hMX;ÊNÔDuV–ªcæîÇ.¢Ã‹?& ¤[¾èÖ&9V»õ±F8uî\E)x¬Äªçû|Û û'\;„¦ªwðy×–!v’5F”u›–1ã­FàbÍVçå³¶npÎoк”íám¶Í]b‰z5«BVÜÃ]nß~»­wm3Q¿…P1RFÙðÖV›,7…œ¢Y©ê‚Õ˜¤$5{K ª6A +J[¨åÅ%RÉ )Σ b±ÁÑ·òÅe|–˜üVb"™ä ì=îÒRç''ä€*’'ô$ãgéùHèŠ5F²}Ê/¨É0¬ô-ÆDsNƒÅUJ!n@XÁ<¾Ò„fe K¸jœ!ž8m·¤a´€i÷¸‹BS¹Ùo©Úom€…›QËcˆ.»’Õ’-mü‚õ-·Sq%ט‚–Ôz•ÀþóZ±@“%™Pv +ù1üÔBÄNh[1¢„Ï Ao¼Íg¢V ïXܽPد8 Y‚Å$†„9’ÀCwÄòôÂÁqÀ`^2eIw,>¡6úL¦ÃJ&²³ŒZñZS6h)Ø…Ú]ƒ[wI~ïbÜVÚ3°u©ž°wÐò {´Éñ‘cŒ)ÈVM›®/í'ÄèZ½ÁL×zܾ“ÂNRDz*×}›µ+Ü=Ñycýs!³h 48:Òòþjà?ñ³¯Ö妴—àpBŸ§ÔÑoÊë/\g8)—;µ94 Ê>üå)ËË5<ƒSmB¿«-ôn7Åן^¾õú(ÇuŸ6-ˆ6IX{8**‡!ÄÓõ@Ipj=TÛK¶«:Cð§×°Sû)s¶ 3YÊê©l+ôãÞr\¹>êr€z€ë/ó¾ˆ}º—iCó€³:qÚˆ—­ª¯/ß=R*îՔؘR[zw¸DeÚ¢þzÏC¹ýè’'²~›¯‡|=¸¬³ë„ïäÞPÀ­Ãþ­Îè+Bàÿ±%N…òïŽç`ò}â"emq¡zÍ9¬¹Ì,vÇ…)xL;Î@ÏÙ®ÔÆ&ÍÀä#«ÚNn[Œ‹f€Ýrá +oƒ‹wh¦\é¨"“HejäfªÙ'S9‰O}¼‹é›"R%'ÿhlW» k[óþ5u^‚Ü ö +ê}»Ý·¸¶Ñíª.š7Xkã›Ì­tÙö‚½2Ñkfdã‰Cy1U–»˜\Áºk ÚÕÎÌ·ùlŠà ,Ù±+pb®®òt­  e¥„JŸ1w.9QŒ@¡˜x•v’.)1 €^ëÜÙíª~AÀ\~½w9D¾mj7ÀÌÔ(±1–ìÓŒcŒž¡ rî?!‰ù·n¢ÍF;ßûî?ÿ˜B5&’äLû]ÐjµTy¦Œ’„:å¼û÷pÌúâØ\5endstream +endobj +1200 0 obj << +/Type /Page +/Contents 1201 0 R +/Resources 1199 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1210 0 R +/Annots [ 1205 0 R 1206 0 R 1207 0 R ] +>> endobj +1205 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [406.6264 617.3695 456.8481 629.4292] /Subtype /Link /A << /S /GoTo /D (tsig) >> >> endobj -1196 0 obj << +1206 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.5805 512.856 196.7992 524.2481] +/Rect [140.5805 606.0819 196.7992 617.474] /Subtype /Link /A << /S /GoTo /D (controls_statement_definition_and_usage) >> >> endobj -1197 0 obj << +1207 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [103.6195 470.0794 159.8382 482.1391] +/Rect [103.6195 562.6731 159.8382 574.7328] /Subtype /Link /A << /S /GoTo /D (controls_statement_definition_and_usage) >> >> endobj -1191 0 obj << -/D [1189 0 R /XYZ 85.0394 794.5015 null] ->> endobj -298 0 obj << -/D [1189 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1192 0 obj << -/D [1189 0 R /XYZ 85.0394 749.3189 null] ->> endobj -302 0 obj << -/D [1189 0 R /XYZ 85.0394 679.8163 null] ->> endobj -1193 0 obj << -/D [1189 0 R /XYZ 85.0394 652.1211 null] ->> endobj -306 0 obj << -/D [1189 0 R /XYZ 85.0394 573.4726 null] ->> endobj -1194 0 obj << -/D [1189 0 R /XYZ 85.0394 542.9681 null] ->> endobj -310 0 obj << -/D [1189 0 R /XYZ 85.0394 335.1831 null] ->> endobj -1198 0 obj << -/D [1189 0 R /XYZ 85.0394 307.4879 null] ->> endobj -1188 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F53 1017 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj 1202 0 obj << -/Length 3489 -/Filter /FlateDecode ->> -stream -xÚ­Z_“ã¶ ßO±“'ïÌYÿJê=]’½tÓæ’^6Óé$™ŒlË»êYÒÖ’ooÛéw/@€”ä¥ïÜöÆ"A -@ø²¸Lá'.Ml!‹Ë¬Ð‰I…¹\7éåŒ}{!xÎÒOZNg}u{ñåk•]Ia¥½¼ÝNxåIšçâòvóËÂ&2¹éâëÞ¼¾ùöç·¯®2½¸½ùáÍÕRštñúæÏ×Ôúöí«ï¿õöj)r#_ÿñÕ·×oiÈ2¯nÞ|C”‚'˜¾½~}ýöúÍ××W¿Ý~wq}t™ê+R…Šüãâ—ßÒË ¨ýÝEš¨"7—ÐIQò²¹ÐF%F+å)»‹Ÿ.þNFÝ«Qû‰4‘Êʈ¥¸")Œ‘3 š"±Jª`A‘‚UÒ4]캻»º½#-Ê¡jªv î7Õ¯i*Ûz¨»–(e»¡ÆÏ}yW¡-`E5Ù²ô†“ãò°Ôí½Ÿ$&“dš¤*30çx ž3S9hYž×Â)•-Ö]‹ÒÝöW"_T=RóEIƒõ¦¢Öûr_WÃuº-Í -J;âê×SgÛí©1ÜW4·-fÕWû÷Õý'“‹›¡h§ÀÖ*‹½¾/Û¶ÚEÔ[j‘%&ËÕå2l¼ðp¿/{XR*°wßwëôî±/Ýax8 4ÖTÃ}·é_`O£àMÉ#A#|…¶ ¨}Ò×h -ìí ·ã)õ•…y>“ÚØX¬ËÖ“*n­*:ôÕUD eè´>ÖŽ¯qïÄŒU$©QÞT è]·ŠØJ§‰Í½Iƒ…mGϾÚUköÛûùÝ¡§ÎzÖ¬¸ƒž€Ï¦êÑ“™Z’/Q¤Ú$N+8gI¦Aµ~¢€¹å󆧥Ðó1l†z}Ø•{êSÞ¢ö¶\×;ÄŽBˆÅÑëtvð…ùiƒå¦§ÍM ‡)fáFôMݯ™‹‹}áÍ@ Ñ!"¹’ŽD2na;v= -‡H¿nêˆ$'ÐØÎD¢âœP±ŸN°7÷8h+~©\¯«‡ÁA2_=-0îPMMFNÀ‘ºÂÆ<)„)øDÔí¶‹Åš<ÉEbMjÄ ro­³$SFÌ]ÃÁ?%²Ñß°ã-<ƒ'c§Œ!7a’\ûœ†•Á&v’Ó¤(” !²j+õ¯<Ô ¯nÒ¸äb<G´ƒ=®¹PœvóeÇòŽ[…=Þ*lzÓ×6ÉUnç QŸãCÛ ó7žiWë>¡a“àpc¼ˆ—µkìÔïb³ˆ•¤H2ëóÈ<^vŒšä@å -Ð]’Fâ$F˜ü]¡PÐ^"…<­˜Æ1¤vDtþ ýÙƒ «dê6q(/@¡‹€Îy y˜€£ŽæXq‚á¶! GóÓ¬Èjª²<±µÎ7´L-l¼ßaˆè!ÒØ˜­Uf‚­U†!¡ÖCOƒä˜8Ë‹ŽÓ܉É\ÄĘñ ¬,) VîÕ²¥Ññ€ÕE¤Ò_9aÕa‰Œó¼dX¿:[H4Zê¹­wd@À¬`#CÃc)l;‡'øM÷èâÎì蹪Ö]ã’€Õ\•Šfhpf…·ž·z.ÏžZc¤ãNϾ|ï®Êõ=¿ë¢”'ÅŽFw%›˜{`mªtA‰^;цêâ:·6Ñ©òŽÔ‹\7ˆÄZ;)Þ‰k€«ÖáùÈ4]ˆ<_¯Ôh•üTàԉΔdI\\r(”6þ"Gh‹°µ*×ï4>nŽtÛÑnx<'€vÉ4; -’˜ÈT&ya—~&[a‹Ë7há¶Àtú,[¼vQÈÕïc€©ÀF*í4Ö÷]G§Nòq’‹wUõàסµyB·ÛPc¢’·A*l¨Y˜áöôøè4À(Áý|¾ ¦H²,@QÜXñM—’ùâïùakUm»P®B¿fº+´àIþ«"`§m–†+ úçò@P™÷AÏ<ìK¬@ºÈJІ,²ŽŒ­I‰ ösf (Ôœ™Ïð.Ø~~^q¡4æçš 8…ÒâH¡ô´BPNÈ3-7×̤\œ{Îê!‹b§Ÿv¨s#>³ô駤Gü )åoW¸ýÖ¤¼ ¨#bµ£‚°S€óÎ}Ì!ËZ—‡¢ñ*$­ <² ° © ýqðЬ\m—'àéDà$Ý09 -0sÈèi.AëÆò9¤}kÂé e5ð¬=Lò×å’oŸG\d¹Ø-ÆRˆoÍÒĤG †o¹= -ˆÒ†–/º°µáúØpˆD ;&9^UÌÅúHáÈÕ‡uUmú£ëvS¯Y!˜„–Á{Y™-Þt4ÃglO3ÚqÁ®wP¾ðÕ(WÑ _ìË÷%ê~׬á¦`ÔgDÓ} qŸ_+@³Mu‰àóã´víø¶rJcòš4M;ð•Õ‹HÍa“ ¿é|*’ŠBûIGde2uÖ!‡86wº>úÁMdvAç35C…Ÿ±Êöw. ~ŸÑùKœJ -ü“Ål7·5Ú'}Á¯"´ú‚HcÀÀž¢í¶dÚ¼Œ~?Ú×í°¤jç=U}ô#Í›ª s—QqÏùw2Eš<\{ðõl$a@Z)ĉ+&9¹b’ók$0L’Óë#Ép2 -kî²Úc¯0¹¿C8_Pø;v! ¹(Éï3S|µŒ@x"BÉ_– IJ,Ç÷xc$†âÖ•Æ'Ëý н.ô' &O¾ÐjJæù‹ÛÔ.þÔvLå›p÷ûåôÈ|»4N* wվߦÇÕ×üÎ"‘"ü™vn»é‚£j3y.—¦¬wñ  ƒ¸'™xÿÛ”¨c9\"ós…)ùO s¶J'7Wæ 8Qv.ŸÝCÔ¾*ù¨BK%@¤3‹bñÂBV¤É$Bhï·‡Ãú!ÆE&6×ù§¸xаÞG7 <§æ\Qp¯ ä½ízÈCŸËi;<œ²s*Îe²ëÖå.VBKpA›ÊÿŠøßù˜)ù™äQŸ‰þLz™Ï$ñÁo²á¾ê$Ñ6ÜÝ:VÙ"-¥Ux·]ñ¿$bÿÝT&Á?\Fþi™†¯úÿ÷ÿ:Ç?½ê,Qy.Ç¿lÎäÏòDçÀ„…B-TþLrÿÐç¢ÿ¬@Ùendstream -endobj -1201 0 obj << -/Type /Page -/Contents 1202 0 R -/Resources 1200 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1199 0 R +/D [1200 0 R /XYZ 85.0394 794.5015 null] +>> endobj +302 0 obj << +/D [1200 0 R /XYZ 85.0394 769.5949 null] >> endobj 1203 0 obj << -/D [1201 0 R /XYZ 56.6929 794.5015 null] +/D [1200 0 R /XYZ 85.0394 749.0225 null] >> endobj -314 0 obj << -/D [1201 0 R /XYZ 56.6929 769.5949 null] +306 0 obj << +/D [1200 0 R /XYZ 85.0394 668.2594 null] >> endobj 1204 0 obj << -/D [1201 0 R /XYZ 56.6929 749.2381 null] +/D [1200 0 R /XYZ 85.0394 636.8261 null] >> endobj -318 0 obj << -/D [1201 0 R /XYZ 56.6929 540.3599 null] ->> endobj -1205 0 obj << -/D [1201 0 R /XYZ 56.6929 517.4049 null] ->> endobj -1200 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F39 885 0 R >> -/ProcSet [ /PDF /Text ] +310 0 obj << +/D [1200 0 R /XYZ 85.0394 425.0299 null] >> endobj 1208 0 obj << -/Length 3336 +/D [1200 0 R /XYZ 85.0394 396.4061 null] +>> endobj +314 0 obj << +/D [1200 0 R /XYZ 85.0394 136.3155 null] +>> endobj +1209 0 obj << +/D [1200 0 R /XYZ 85.0394 104.8822 null] +>> endobj +1199 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F41 935 0 R /F23 734 0 R /F53 1027 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1213 0 obj << +/Length 3704 /Filter /FlateDecode >> stream -xÚ¥ZYoãF~÷¯0ò22`1}‘lÎ%A@K”DD"’²â]ä¿oUW5/·í Ã`_ì®ó«ª¦ä¥€?yiãHèÌ\¦™‰b!ãËÕáB\naîë Ék–~Ñr¼ê«»‹/?êô2‹²D%—w›Ñ^6ÖÊË»õO‹ß¼ÿçÝÍíÕRÅb‘DWË8‹¯>}þdôøðÃ矾þ÷íû«Ô,î>ýð™†oo>ÞÜÞ|þpsµ”6–ð¾âžyáã§ïn¨õõíûï¿{õËÝ·7w=/c~¥ÐÈÈï?ý".×Àö·"Ò™/ÏБÌ2uy¸0±Žb£µÙ_üxñ¯~ÃѬ{5$¿XÛ(¶* Péã,J4L¡«ºŽ2¹È÷{jlòU¹/»²hy¢¹’vQP§=uÓkêÖÕäe±¨E“weµååmWZ*ð°ø¦>£À€,9"K¥qC˜A‚à•}½åucòµŒ+ü²sééÝåÕzÏ䊶ͷžò¶¨˜¹®æç®lqëË¥i¤Ò¬NÊ(‹cåveÞQÉzQâ>±Y¬‹vÕ”÷Ži®èÙíŠ;RÆ‘Lc=a'ZÕÕ&Àh7U2嵇œw> 3­ÄâÓ†hx¬O4·Ë -Êi€dLíó®\íhöÔ:1À ¯{(šGšª÷ë~¨-k>´Þ¸YÊÄF6K§bzIG*U†ùévyGîRWûGjy²Ä¢;×Ô Ûž .?ÇSψ8‘Ò©7°¹ -ÈùYÄþe€,ž-¯’Í©ZuÀöuFå[%Ÿ¿Úç@(µýX[î@ÏG¹­jrŒuD2ã D¥tæ» sA:ö6R€"Ðê×–’× TÅ‹sÝüÆæ¹/ ‘ÚÈ€q½æVÊF©íMðMKÛÿ¬”96eÝ8 ÀÞ5M¬ŠcGm¯_ƒ2|¤±Ù0Xç¾­ièžIÚ×4Wnh„ÚŒ0YÃC«-IU&&ÊR«gØ5y¹Ýáé*#k'º‹Ÿ…P`ÀhW4¼lçhƒÖ©åýçj16’6MÿžÌÐS…^|?`á=Éê™âoq”Ÿû"o¹Yoh Z½è ƒW>{jnˇ‚yq@H¢J 0ë!MŽ,öží¹-öÅŠz›º\lÄTûwÔ!*úñ†ž;~Ñøýz"¡çˆäՌѣ³óZw1u„:#3² -lô‚ÃÎé -=¬6°t èþ÷´ölÉÞ„±,Â&ƒ§¾Œæq¤Ó>B îCû“4_Î5 ð¶.º¢9”óxv…-bÕ ¬>Rÿ˜·œ4 ^mLäG&3ÉmÃV¥˜K–M‰ÎyS Ë'Ù0¤Œ'ö¡Ìƒ+Š•6͘ „ˆÞZÉxfV´P#ßÄ ôME“)¾ÉrD¿iYmêŸÈÈêÞäê†)¸ðS®Šj¦l^&ÓHè=“¿&ƒ=ûªmeÚÚ)‚}rŒÅ„PØhKpÎ%.Ø='´HÔÆÌ¦XƒÅkèËnâòàLÆžÑ*?ëÒfm½"88¹“Ç -ˆY1Y^(14Qo¨Ï[(I©Ä+É91ìÊ –í¸Ê¹žùZjzrÉÆBl!þDIjfð¹>í94€U;räÓpPò4É|U@Tòa…t{Ç– ü?Ÿ)ÅYÏN·.š&d³Y$J{¨hAIl"ðú(sÊë’ÉuÉfÒS— ˆJA³a¶-šŒy 7üfÛwP”ZÓ"¤oøŽÎʘ$h LR:™-úgÕÕš,”I›P3€¢mÕ‚xh?SÎ -CDžU=yØv{òæÊ.NA=Žç-?é±á vË‘a_;Rº¾¦²®§€CÉœ -‡ÍÛáz²a¨Ùžš|Ùk|䨍ŸgM+8f -h Ì’kP—†Ã`ñH¯-xý˜è"À5o°œ)Æ)® ¨`¦¬;€½×ëÂU¯Š*1WCΈ#ƒ˜ðÇe_ßçhN6áèÍ´Ïã`”•,¶l&i0õ¹*Lý‡Ð­všˆ}µK&2O¥4q.!Ur —yÁt%σc ƒä ³A -“ÂtQ9k‹Ž µ()¿ÖŽz¤1ðІ1zÏUÉ -J8¼Ž½€Ò}™Dòî!ÝÚïo&)¡€û,dÚët%<úƒ¡êœIÞÔû}}F(³•ÓãXCøq‡=ô^öv@fdäsä† -[A£ÍPáo4ÕzÅÔäÁàjL”€EŒŠ°fá­^³ˆx¬ÙØöšE´Ë)9·¤Ô1ôMRe—â±åÁ2¶<|ñÔT#!DCå5!åý#¾( -ˆü‘1ƒ½¡¢Ö‘HŬ„´ãÑÀrЬDcT¼xO.‘MÇŽCšµ„Öþµ#\ÍüÝ‹µ„pvð®Îœ“Z–Ì÷uR`-¸%ð²(GÎc(b&,C½—{dëSwCh^Q¿7Q5'¥\\ÏjDFÿ·‡›!xJáI(W¿ºs~eÄ™ÿ:^•†M¹ÌžÌ65Ï4´zFF#yõH®<ÜÚq£G8¾vÂ14È'ÇKçt7©Ïx·œ‡ 'Ñ…Þ“ ë³ºGmÍds˜r|€]¥`ƒ]áÌ3©´""õ`´~@/W!ÐÒ‘”z~ï嶦²ÆšÂYÆ…sÑÚ뇽àa´«Yõx”š×z£‚ÛÝPôn2Mlýý£KŸ»¬x*† PJË¡þ¯º¥Ór@6²i_ î\bf$@±‹îF Pjð–ÑhüÏYan 9µtpÎñŒÛ˜žP l¹Üš«0îL_ ý êùãø¼x@ÔÙ$žÕ¡R9 TŠÿÂ7mŸ 0è\sX;u®(ÓNÁÀøB5ðG¾‚smY­ÂWÍ’æ%û«„ø»Ï”ÄØÒ‘\I¤^g±0„‚v!\‡-KeY_àvV°Ï¶nB÷ÆI¥I_úÆ$À˜ÂßOP4¹’S{¶4@¢:Å›]>ÍõÜM`Óì@ô^Ê—¿ð$ã¶³ö ÷=¢Œ†Œó#”k¨u°ˆ ÉAYÙ_)^¸?{K¥Ɉ¯®ûê©bѰ8¼D €¥Tc¨‚ž‡h:è—rXÙË;F uÏ#Þ—&Kž)yb"­ú»1âñ™šWô `}Ä2§e"òÇé±t÷Ž-O¤C«´Ã=Ë× hôÚ}É{©³UHoY¹mæûsþØÒ¨S4Œ9r ^ê²)í­f)µ¦Ü‹2ew Ú¼¥«!tT Tʽ¹y“ÐvšœDtßóM1\¯Ç¤axºÜÎêU$|7Z›¸K@méEP5_:‰_Õ È/SÙ\3ÃǮ ¥RËXã}¶™e—‹û%DZA9ŽŒßŠø-6Ñ4²-ª¢É÷ K|‚¯å|¯™¤ÝúùÔín$¥DNðÆàÔÐð‘?~Ñe²Ó7Œ®†$4Q> n¢ýw hq\xbÿPf"{­6DDì+Hº’Á¤`“Ÿö€ÎF¶†4´þP4Aü& U—û&í†ù¼•Óp˜Š”_¶ûOYÃ×ÁÉ7bw0ûi€L±^SæR¹Fê>ÒÓd³½¤Æíè«~¿~9~áéWý§û"?+û%Ü龜Ԝ$Í‘ÒNHzòó‚~Õ+„<ÝŠ¯€ËHJ”y¡f`=þÊ÷µja¼Œ®êßÝk4ü/¿ä*¤@ÃfwnĽ„–3¼FGàÝ@6«Èý>ý·þ3Yªu ÞB=¡†>OLéâ/F£×BÔ¨ 5¹™KM.{04èö5‰ÐÉ:\¤lW.+<=Š÷¹ÍEšDF+¥J¢\eÊGmZbq 6ï¨f6П7û¢+Ã/u”&qf‘½qîÏ”úÝ¡§ñC[vSf¶M9åò¶e£µ[©|Ì q<Ì v £X»ð÷š?µ>WÁ|Û¼¹c ‡:$gávºÆãÁˆ‘ˆ,„†,hâõoÁ†IG¼4Æ…ÙŠ%ÓÛC×Ó\Õ,ëê$páÖw`bŰ|Y¼i²ß=A»â©#xCY ·7:»¨¬Ëe_‚­¯°ny»ž3Æk2m­ Ÿ=?‘À̰Á¡¹äÉtÎz›¾ZêbOÿ)pÑx],«ºêŸn„³“×Éxð…©¹Ávcs³ HcŠ-£pCþVU·d,Öù%à ïzBˆ–dcàÊPˆ +ÄQwHœÊfuµE/@¢`Ìg‚v%ÈOFËá_í–[q3 €-ø¥b¹,w½MÊ`~ñt²Á €þëØÏøDgª.˜8fQ.tÎ&Q5ë6äl²(¹w6±¯H¿“$R¥ÅT5l¨D:èþ±žž^“ñOÊÝ„Ž²Äµ¦ØÂɦGy¹ ó‘eS‚¯/yç¾Úò &[}¼“àîà?Ü‚ÉiV_¶Lï *üǢ¡c1Yxb¢Le'9éÀxtûì š¶Ÿú¸Á¦Ñ4OÈØÈ+ÜÈaÜ£¿À!v¢Ãì,À&)¢Ô¸H2u¹FŽ©`~!`Ü¥u޲M{$fCž¨™L™]­ 3‚¹ —NáØê82´Ä$%ü±Ÿ#ÓÀ@¡¦È\4€w÷SƒÅâžKúÁ(ÎOŸ?”òBÎMOlRÖÑ=G 5‘A²ã—ÕªÀL‹ÏL}üõ˜CLùûMj =)°ÀJ‰Pý¨Àíä ¼SÝysˆó‡Æ¢ ?‚*)Irg.· | .«Î]ö“‡íÂV20¶žnC<XÒƒƒ9f!=öÓ®úW( CÜ7Ú[/­g奮k—åHß±ÂØ:ÊŒ ¼ùP qç,Žt|’ÖíC +qâ¥ÖœEnváhÅ5²f‰0NÌå`zQ2ã<…——e¹êN^¬šUµäÁ"ä 6ge:{×Ò +p<Žh§at’x=BÃýQ®¤9G~íÓ_î™|¬ºÞ÷Z}·`8ÏPwø}~­ØÁÉVg¢öÙü9óAð¼dFŸjVkª2¦¬ã↟ÔCÇiWö°Û¡î˜RQ½zì7Øu’Ò ‘ºB%â?±á‘“œÝÀ5x„¡Ð eÊ@–‘¦æåô@hh›óU&Ò|L•¶ë[TjåINq+ÀÕ\ð„18ÈÀiL³¦6+‚öŠÎ0‘ò‚D +ìJšS“E´cSUÞT±{ØÛëM¦¼†ÃxäÅÔ¸uP§_ Å8Ùu¬"e29åÑHGä€C A†ÞÖ5©‹ä†¯Äêa¹¯¼h?ð\]K[À£)4€ƒ +B+Áä úÁ\³RÉñ¥ +þ­x§àý‰ÂZ&õåO'®2—bÂðWä0š–vضã}WE_pµ P’Æfê68)³Ç'êUo³¢˜Š +ûÜð,Y M_ñ›]»åÙöÐÏÛõ|A\À¶Ä +«ê¶ô—(Ûw;~aÏø÷7 DWØÛÑÑBÊLkŠà/M·ÅÇj{Ø:FÎUŒº«“ÖÁ¢Ü*ß?>×Hpr\[‡vÚ²ûÒ §¼¥\šÖ¸ou‚#Pu˜(…ëEW*òÄ-òÙÑ©KV:UY98²©ÖuÁ{7‘C’MÏé«l¼Í*š_¹†øuç 9åxK<‘çºB&á¢/øUÌ®¾ Ðà2ðŸ¢ÉG2Þ¾^#í«¦ŸSÅŠëžÊ.xWGë¦7v~í;—œ£Y?Éïs*¦¸Á îÒvbPð ³o–fâ´›7øb¨omu|¶âO!ÁOòäE†Éò'Wkm ƹ‹Ãú66³?6í‘¡Ü·éø¿_…LÅ•@í¤¼=–û&ÜŒO °iÛ"’B8â@rûP· lÕ¤òR,Û¢ªÃ^!ñäžEâôoU€«Èf&2»”˜â±ÿ1é¬pe¥—â©wAþªè“š'øIæ:ïé@Èa‚[HóøS$éHˆÄéíá°Ü…°ÈÈdIö—6,÷AaæäR_J +Ê +\Þ‡ÔsÌ=’K1­ûÝ9>ÇâR$u»,êP-AM,ñ¿ãÑc<ò3Ñ£>žä3K&zL^Íú–ÕÙ|$1*£J/ i.Âþvé?–Hbìõ%êôÓ%ª„»oOo'|½ºÃn×î¹× f\ýËØ Æ+0ªÀp¹ ˜¶¢Ôì[êñŸÞl@¸Òùº}*¾gþ„Ü|‡= b¯j&o|W$ü]_àsã¾ãRq +aÖœ’þÖ2MÅÉn2¾ÜÐ3|ñêP¤ZMŽ-Ûfj¿â7bb‚3‡`¼£²õ ÐÀWû ÓâCI ‚>)ñqSÙk˜å›4ò:¾ñ‡)ÛafPÇŸj(̯Cße˜,Êòtêà?%#™zoÈ÷jöS +×$qdAlÇ·c”6|‚q†Å¿côqJ@Þ‰âõe(UÇXç¯ ×PRq‰È{4näÊŸ,NZ=5èÎQ=4\Rr¿kp¦Î/ìûH¡ü7îš7øÕ”þ«O•žÛý#«g]=³@¤ÂWÅ& +¿ë=~ͯÝ[G€ÿ^ ;j£i/_Ûay"Á’¸/lïžüQ'ÌÑWHÚ)õøsL=ôpèrÛ$Qžfê´á³/ª‡ î.sÒx¢¢«QŸ@àŒèk\¶±´ÁèРߨMS×,Yú“+Û¹Q³ïß#so‰27l\áŒP~ÖeÑñÐV¸ÊUÉ}ªaWÒ§0|¨>”|× }]¬t„Ÿ¾Žý×[ÿ÷—ÇÃgÙI©,“áŠ%êcH˜(äœÊžQî>Q~Nú`UðËendstream endobj -1207 0 obj << +1212 0 obj << /Type /Page -/Contents 1208 0 R -/Resources 1206 0 R +/Contents 1213 0 R +/Resources 1211 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1199 0 R -/Annots [ 1210 0 R ] +/Parent 1210 0 R >> endobj -1210 0 obj << +1214 0 obj << +/D [1212 0 R /XYZ 56.6929 794.5015 null] +>> endobj +318 0 obj << +/D [1212 0 R /XYZ 56.6929 607.7662 null] +>> endobj +1215 0 obj << +/D [1212 0 R /XYZ 56.6929 584.6557 null] +>> endobj +1211 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R /F39 895 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1218 0 obj << +/Length 2891 +/Filter /FlateDecode +>> +stream +xÚ½ZÝoãÆ÷_aäådà´ÙOry÷tIíä‚äÒ:îS4EÉD)R!©SÔ"ÿ{gvv)RZÛ) +‡÷{çó73+‹kÿĵ5Œ«L_§™f† s]l¯øõæ¾¹~Í2,ZNW}õpõåJ¯3–%2¹~XOβŒ[+®V?/¾þöÃ_nïo–ÒðEÂn–&ዯ>~ú dôùúÇOw¿ùûý‡›T/>þø‰†ïoïnïo?}}{³ÖØ/ý Ïl¸ûøý-µ¾¹ÿðÃîo~yøîêöaäeʯà +ùíêç_øõ +ØþîŠ3•Ys}€g"ËäõöJÅŒV*ŒÔW?]ýmDÜÜÇæ~WÕÚWgùd ¡¹ þh “jNö<«=ú¿‹8Ü‚¡4ᄪøÕÝó«·Aœù·ãU*ÈÃø™¬+ 3¸è‹uÛ~ñ>°§z×y.°©ÞûR)vòï#&'c¶j”žæÛ]{ ÆÄlÔ(|šr™|=gØT~¦£Õ5äÍ‘Cµ-}ëÉ7F„ÃÜʯGƒ¼¸^8§C¸ICÆ»ñyÈé¦v ºî2«F„PVχ)ÇØU +6p²+œy&•–œ3ÎÓF«#zUÄ@K1!Ôèc9 GSYÄŒže\8w"Z}ãp<Œ­W=^%Oµž +n÷B1ºÉ<±%ô)ðs—bÈ¥”8ÕÿͰtZŽÈÁ2›‚­ÑÒ'—˜iP좻æ'(…ѶAGÔ*rV˜[AÎ@-œs†…CþÆL_(6¾Ü:W¡±Œë±ú/¨ßæÇé%x €¨%šÙĜձR +ÁD˜×žtÔ³IÀy9®<þ!€sŸáe`_þ=;»Ø#WÁn_5E4MIã"ýstˆ¨Ðûž «ý >k̼Â0RΔ1H™4nVB%,Uv®šÎÙ´Ý1BM’2‘ÚF}·Ô:aZò³ˆBàñÛ*&W/c^ïÍ  …¨NÍb¼ÍõÜ3`jNÓÞ{h“·:~ôÓduÔv¦žbÕ^#Ä(H7ï VCÍ„ƒLLJKfÅøž@r8{î˜É +n1•ß¼K§Æ‹†§Ìà â +‡„œâôÖ@Óá¾§•£°ãc´ýHð¾¥Î’gê]©2¦d¢g<>Sðò1ûkwXãôžˆü8¿uE-LDBK´í£¯”ßzÜL StÏ]ÔÙ*ä¶^¹jæõ!?ö4ê cŽÜÒ/u©” +V³”WSâEi²{íÞÑ»ºªÊäÑÜ‚I(;ÏL=ö|;>ý¸ =5.±…ûNÅ*þ4Y›¸ht¤EQÕv©Ä¼ª_&³s͸ôk¤ˆ&–G-ÂÇl=6Ò.ïÊÇ%„YN Ž0ï¸y•ƒMlʦìòd Qû7¹Ðëf9·z>o{˜H)Q‚|.Øw4L¥Ivú†Ñâ”&2d óC”·Elù paÿPf<{­0ä,ËÆò‘Þc0#Xçûz ÐÙÈÖ†>\Š&Ø£ùh»ø¶=Ð0˜è‘våÓ¦˜´ç/힟£QþÜ]õ87ç?‰‹5©¡21#¤)þ€C“Ýæš÷“_|ÆõËé†Ë_|.ÏE*‹ðôÅÝo^‚3yNÄe¦¸°3’.~zW½BÈåiTyE \ )‘ú…‚ÁëñWo_+¦Ëèþ=ؽBÃÿòK_‚”`ØÂÔθMh9§mt> dgµf8güaÄÿ3[*#E >A]PC¿MÌéò?M¶Å¨‘3jò°Ù×™¾æÁРÎøc, H„úy©OꨨÐÅy}朔Æ|œ +=áŸË˹àÇÕÓ×ùtÄ×vÿt>íè­:0tŸyØú©¬éñ˜nõz'_&: ÊW±2sTÛú‚á—®®ÖgÔ‡zfJ€{,+W/Co]³“Þ,×o> endobj +1220 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [173.6261 273.4719 242.2981 282.8815] +/Rect [173.6261 333.9221 242.2981 343.3317] /Subtype /Link /A << /S /GoTo /D (the_category_phrase) >> >> endobj -1209 0 obj << -/D [1207 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1206 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F41 925 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1214 0 obj << -/Length 2391 -/Filter /FlateDecode ->> -stream -xÚµ]sÛ6òÝ¿BÓ—H3B€ ^žÒÔιsIZŸûpÓv2´IœR¤Ž¤âª7ýïÝÅ.ø!ÓŽï27z °X,ö{œð“3‹8Ué,I#¡©g«ýE0ÛÂÚ» É8K´b}{{ñê*Lf©HcÏn7ZFÆÈÙíúçy,”X…`þö㇫ëw?ݼY$Ñüöúã‡ÅRé`~uýK½»yóþý››ÅR-çoÿþæ‡ÛËZŠ™Æ·×¾#HJŸGˆÞ\^]Þ\~x{¹øõöû‹ËÛN–¡¼2Q_üük0[ƒØß_"LžÝÃ$2MÕléPè( =¤¸øçÅÁÁªÛ:©?ÆjB‘œR`”ˆ8IH«]V–¶X,ã ˜¯í&;í§¦]Ûº&ØPÆ™ -E*ƒh¶”R¤Z+·—Ð^ƒF“0_½¢÷uÞÚ†ÆmE_¦ˆ¤O„hìg N„——› - †j@°* ^nl¹¦Ñ¡Î«ñ6âSjPc8æÓÓÉüæ]¾ÝYâf©ÂMu&ÚŸ¯=¯$yøPYå±(†*’‰HCeÆt åI‡ò´UÓxŽNí./·tm§6'’B&A<ÖXGf—3Ï×zu¥ÂG x©0&IÎíÎ2ÒÐmT "…=äÜï%¸`G³X¢«ä9ޝDjŒ™vû¥'¸Rt.=âMÊP„”Þ¡“wÇ털¡: ¥3f˜Äó]Öà ¥Z‚4»Ê3^>Ô iæÕÁÖèqiwYK;ò– ä¥ìõqe^;¶‡#ãßïléiø³l A°XB’yÑ 1í-¯‚¹T@Ø4D/ÀoY•X:òY(ƒùuëWê}V {8óñ‰cŒOüfôù%Tai¼‚vMjåXœ†õXf{»õ±œÐ8¤eLʘyÉ‡îøˆ±ÜÄ\Uÿæ'ë܉cWmUŸRʹ í„A,¢$Aõ¸¨#»_U@K¥Ð])9àŒhdMU6/¸•M€kÄ - ~Q*šUF¡0©”,Áò8!¤·¡8BŽäªÚï]ÊÁI‘—î$ ^ÔæïLßcc׎7í8šàC§"cý<'*õÛYtpÚŠ5ÒÚ5³„®KŠM”PR%lÓRºÇi¾«ìÐÉØDJ.‘¾P³&èIìM;äÉ9£ ÿ¯8¾ÏÛÝT=ï‚û‘ˆ‚’¦LêSÂrûÜ€Š]äèÀ;CÀÑÝg -Î,- °Æ‚íª¶~"ñùì -ié“‹ql|,WÀ¸%ûú0 -- æAJ%G3„¯·âñ%̹ßf¢Šð‘i‘UF›ãyV´v!ç5Í8}Íc^´K—`q±ÖR¯›‚’è˱ÝÈI::ÖÖõ¾Zç›ÓYîöU£j»í²ö£ª¼l;è -r -›¯<oð:<|—}îêô0†g-)×송ã - /ºÝÙÑáÌØ»:kì#ýP$ÒHF¾òÁ¦ú‰™ï]Bp/Ø< -õ¼©hÁÉ‚¸N‘¡öATúškÄè¯2lqÔV´ÔXƾ÷¹0|°‹ÀЄøžî¶-Yü‚ŽVžSç*Uù¢%Òs.™R¦UFKz4n“œs †˜pÞ0‘j3ŠvÈ Õ鿳9'ŽSPIHÀ&¡ímÓd[Ë<çå”s[¦ÌÀä¡JA%˜xŽÑ‡j¶â´ v²ý•‘†@‡àó:¡EêsÖðp¬6­Í0À58j¡d98—µ‰°N›ÏÖ¨*2žoP„‘PõÙígSEußÅ!¦ÓQìò¤O³¾ŸÄ¦äo<w]½¬ƒ+¤¿¯•§Œùz t5œaϹ¤¼ÁpQ…1¦T<·¿gûCa. Í²í‹†šìD˜¬èØ€Èäš|Ë!w#‚!¼Ê–ÉxÔŒ¦T(ø4—3GGdEÃøþ°xþ›µ>ÖE=€^tîÁãTj!ÂEŸ¸§ÿ×"UP½_pYëão˜œ;›?i?óðR»?}òªø4Z˜| œ²ÁöÊ!}3ÜŽào^O‰8uåç«ëÄ+߯§ÙØëzó}áÉbB¾IÏ]v‚ƒ3þ’½zD·ÎªþÖÓ5{\* ¾é 2 Æi9jaÎSäwLôðR‹$ìosøªñ]èÚÂñ½yʳ@þDHlìa#[ý¾±õËÓ0Eð;IŸÎ 2¦íë) -O§‘«AV ¢¾¶ã„¡Ÿ³¼Èî -h¸2êbõ¡0¸؆†kÛ¬êÜõªŒUmF„¡?ìÙ•9`<Àu[]ÚuâÓ«²ÍòRL)è}Õ‰0Ñmí³“Ï(ì4ëµ]ýhs\ôð5” Ü¡m#¼ý)4`A -•R hôs n‰$HÎ^=ÿ·]žì¡VÇú h_´xèwœ¿?y¡` m¢ÇÞŸð -™Ìd‰ÀÈ/ti$ùHsÍi&}ÉŒÂA/ÄKÔû64miKÜ „VÞÕp‚½Õd_T5¸7–#×Àù}ßåF1†]êÀÓW¼­*q¶=ÖìšÄËüÔ]ÂÚrªyºM¤I¸}üu6Cï€ÖÑôo¶Ï'éw<êF‰8 “§Ý 5Ò©v: Gˆâyn S—ZV»%äz ®œ¿w7 é©ÀÖ ù ‡œ³\óèYÓ8“ad#î_UG|9e©þæ2ºTsÊÖë׎¾¡±Û> endobj -1215 0 obj << -/D [1213 0 R /XYZ 56.6929 794.5015 null] ->> endobj -322 0 obj << -/D [1213 0 R /XYZ 56.6929 496.5566 null] ->> endobj -1211 0 obj << -/D [1213 0 R /XYZ 56.6929 471.7746 null] +1219 0 obj << +/D [1217 0 R /XYZ 85.0394 794.5015 null] >> endobj 1216 0 obj << -/D [1213 0 R /XYZ 56.6929 154.8032 null] ->> endobj -1217 0 obj << -/D [1213 0 R /XYZ 56.6929 142.848 null] ->> endobj -1212 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R /F21 702 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1220 0 obj << -/Length 3046 -/Filter /FlateDecode ->> -stream -xÚÍZÝsÛ6÷_¡™{¨<­pø 2o®-çÜIìœí›¹»¶ŒYœP¤*RvÜ¿þv± D9´X_œ™ØX‹¯Åb÷· ‰‡1Š5ã*‰F6‰˜æBfË#>ºƒ¶·G"ðLZ¦I—ëçÛ£¿Ÿ+;JXb¤ÝÎ;cŌDZÝf¿ŽOÿqòávz}<‘š ;žhÃÇ?_\žQMBÅéÕåùÅÛ]ŸÛh|{quIÕ×Óóéõôòtz<±Ð_†žép~ñnJÔÛë“÷ïO®¿ýåhz»ÝKw¿‚+ÜÈG¿þÎGlû—#ÎTëÑ|p&’DŽ–G‘VLGJµ5ÅÑÍÑ?·vZ}×>ùE\0!µMTÌ"­ãç§¥)8LH!X¢õÓY'BYÉâ™hÃ8Û3‘¢s&"R,VJ¬N˜QRùC©Ýl³Î›G”tP «# ³ ãÉjµ>ñ¸ºO ’kZfDd®ÌÛÊjN¥çul\ÝÔì©è#½5FŽº+þ:)¨(f -T ä^S°QÄxÂõ`#ËŒµ¤í³ªüsy7(ØÓÀ¸Y§M^•$>¬)Ñ«t]çåÝ¡‡Ó˜¹ˆ¸³ö×±T,9xe¾²íñ¼ˆ%pÆ\‰XÁ¶¤H¼äÖ®®Š{·ñÙå Ø -®‚VB¯ Šú'4 v\of lŽÆiMlÍÂQñà ©ó{GmEU}Ú¬jj_9Ï1ÁÀ\A÷HæÕzéÂaµÇúÑ-Òb¾SfEîʦ á˜C[:[l¾L—A#j·Æmƒ½;pî~Ý!}Û«Åc&åàÍ‚qb!Œìçyz^žü«2ȬY§e =ƒ ýwdéé¼î¯™Ëï_­ÝÚ¿cãeð•&‰Dl’„ÅÚDû"®6Í7’qíÊì t»ë~]ñŠWo1%¢!§kbË.Èé–U“χ]îm+¿Ë«Û‹óÿìÙý¦šUÅáuVõ=릕Lédèú«Y™àX½½Þ‡=ÿØgr_Tº }-y ³öE°íñ¼<…d:VƒÊhÀÒ'œ¼è¦\¦Íl®jH¤ïA–éƒ , ·;mмcʨò!­©nS¦ÀxΊê2׸õ2/ÛêE fEZ×û.Tú ñ¼TœŒ+°*áèR©âa‘£ÏÆ:…Ž0´à°¾¬¨Âo5€v·'X^3aw÷¹{è”L(“&ˆ9¬ŒÇ'4>\öDr¬É>(üV¥c·Y.Óõ#}x eZÔR0Å݇ -PÛT¡\¸¾%kXNF‘¾ Ò2«¬nÙÒÆÝU0¿· ÇÜ.r’ùDX°ü±Uû²ßö™(¥üš•ŠÀÔ ÕÔþa®kRúl¡+Vù󂺺ÉÜÚÀ\JGç`Cææé¦CæaÀ¼Wêí•õ"Òωî‰ -[/7EÑ'ÁZŽÙ"-KwÈ–v.Õ×]ÔokK9gFƃ¶”GLŠ ¡¥kªõ§Á›øÈŠêõ¡Ê!{ÙYÌwìtƒPj@f:‘Lê$ØËUWc8æx³˜ÏHdÔ瀼º ùŽÁ޶†YEi:†Ixwä5ùV‰†p/ðåÝM¼š¬eÊÊè%c¶]ž•vĦ"=„ܵUD G°ùuîêA)᪚ 1¨—Û÷âg;áôEµ)²6|¥r민1f}Öúlu„n¢I×Íff?Ša0šÕ2lõ‰­·éqy –­¹~~ƒ - ¿2ð=ä`øýØÞÏ7 (NAĶç¦]€*Ò&8ú±{O _¸Oð±) W×} g+#wø={V'f#øªUH÷ÀØ D-ÒÆ aW¶^™³$Vñ'ˆDë²^±SÈùU‰kñ8Ð¶ŽŽ{U­›0qÓv$HñC¨¾ø@ L³,äNBÞÉž¤ŽNÜXp¼ËnëòC·[üTH„5*c<„ |„=îËãÊn1FŒ/š¾},%ô“A(·Çˆþƒ¶ Ä5euüÀ癫sê™QÈX¥wa„4 U»ÞÉãšÿFs´J°àü ©d<¡ -jÐúm9 Ÿ\m3­šÛó3íôØ%¿+ýúŒösÞl0ã)æ¸z„ðp++©ÜÔ(ý(ò#LÞaNåٕ؃ÞLOéûê2Sßí¨(‘wg4ühÔ‰žµiNÍOnöi¢å5ÞÆŒæòÆ)Ýf šN/d`tÇ¢îm|2Sê ãEåð/þf¤Væ D’“¹{|Ó+¼‡æ>§ËUáØ¬ZÒ(—TžÀQ?ÞLû6ÙúÍšÔšT~1iéšç&Ф½®ë8¾Ò}Ó¤¯‚GJAÖÀdb-‰'Ëë†tÃ,0’j)Iˆʼ„³ µb¼JgŸœ·ÐDÁ— ׈mæ -èe•m -W÷*ʾ…îmw¯ºÚw£~0ç½§Ù•ÒwœÉUV1ðñCXZY¸„Æ–ÎJØúì¯äï½Úƒ·7o¿L‰½ìq¤»æ×‚‚J³Ø¼è´ÚÏ‹(#¢! ¨Œfá[J>€Gú£ÁwþiAé$(|ÎVY„uhØj2~,óz¶ÿlå=6'/ ļ¬(Pú2”÷“ (”oô¬ºw[÷«Aù(éy©„ -¸i%Q€eü%ötE%yÍž Ú,ªz/|J1Iëzö‡(Mç4¾î„¿­Òph3¼2ôj‚qu…»óç9©Êb8V;Ûò#*Tcß©M2l|WÝÕÔ²‹)¬ -©C¤é½#Ê#_Oa–Nbæ¡rW}:tùﳫ÷'þµßŽ #˜öÉÁ¶‡ésKøMᢥ‡5óÅF}ÛŸá!Ã"zéQ¢´üƒ´mr KÏF,ŠxÊäåÞcxªpªðVR7›Dý¹}cÉdºsT´sö¯¥¢€™xÑmgU46Lk3¤¡2QLŜ̚—1ÉH¶k>ôᦣ~Ü´êÇu«~PÔ¨=õCîŠx=pÆŠU‘æ×?,#‘mz yüdÜäKWm0)¶\SîÕ7P ®jÞøù¡ -‡òuÛΤÓ{FÕ3t,Yâ‹ýèB !Ïù)€ "¤ Öªfæ©×;K žøH‹‡ô±&šfn6ë2ŒfÆçWד¾-¿Ÿ^ãO|$%¥Œ lYæ ²Té7•SìZ¨&ïŽCÌuî3Ȧö>æ++BT „XYÞº -j{$jçÅàÃo97erlª*£¨bbÀì\„δ’>ÐGŠ’¡“A£?MWÛ²¡éî\Ca˜Ÿ†ÊÝÑ™¸ÕG¨ž§yºVT;¶ª¼`LüŒ5$i>ÍÝ„÷iV•?„ʰmyo.áí æm‚YU*äXÒ[}ÌÒ’ -Ñúš¼6+Z| ¢$’ w;`]³>éþìÂEDeOT'®'L¢Žò¾¶óKªµAÕ¡ºUõYÿE%ùØN¾ ¢rÔm‹ &«é mÀò–wß´°GH£à5à¶´Ë·!]i·oOçÇEïVˆfœhk& ÌpŠØËÈÐu÷nßuˆ°älót»- -Þ$diö2ªs8E7YUuÞø_½ì°‘ϪÒ•ØZÌ&-Ыj©Û×A$)'§ó‘áÅ:$–pýVÔÖÐdi^í¾@þ÷:˜ôhÍ*}µi2 &Xn(I€Ú€ù&XŒéª ÒŸ×òiÌðàØ]žG9¨vCdûú|„'[mODÐö‰U||ŽR.Ìõ9¯|þØkQéà£Ý½AG"* %m¿m(iÛ@„mãqã% ¨coçÀ•/{g‡I½€cI=c± Ç î>-ò¬E€ð^f‘­ÍƇÄZ$~ æý(k«›Ý¨/ü"§µ¸ýñôÎK -§; ãëpÌí~ð9ô Rìc¹}ò Òÿ¯×v!Z²Hà -8³’~óñô‡§|4ñÿÕŸ¹î~YÀeq¾íeã¹a±L,K‹Î6OE«˜éXîØ:‹ÿ®æ¹÷endstream -endobj -1219 0 obj << -/Type /Page -/Contents 1220 0 R -/Resources 1218 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1199 0 R ->> endobj -1221 0 obj << -/D [1219 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1218 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R >> +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1224 0 obj << -/Length 1962 +/Length 2569 /Filter /FlateDecode >> stream -xÚÍ]sÛ6òÝ¿BôL…üÀõ)Mœœ;W·g»OnÆC‹°Å)?T’²›»Þ¿],@‘•(i:ž1‹Å.°_Ø…ø"„?¾ˆbk¡‰V, -y´XUgáâ æÞŸqG³ôDË1Õw·g¯ÞÉd¡™ŽE¼¸}ñJY˜¦|q›ß1ì8„Á›¯Þ]¾ÿùúõy¢‚Û˯Η" -ƒw—ÿº èýõë~x}}¾äiă7ÿ|ýÓíÅ5MÅŽÇw—Wo £és„éõÅ»‹ë‹«7çn¿?»¸Î2>/%ä·³»á"‡c2©Óhñƒq­Å¢:S‘d‘’Òcʳ›³ G³véœþ„ä,‰äb)KAü˜è8I™J¥mGšÅRÈAÛ‚/8g:ŠÄDÝB±˜GÑ nÎA…aåKk:RÈMŸõ¦2uïTÝfU•µ¨`+GF aŠiÅ•åw».ÿí׆€'ÇÚÇÝ,1å#¦œÃ™"wdJû:”-&ÓÄuÓõž5H&ž}U&g«¦~œ‘ &âØ“þ†¢4ÿ˜á¸)g<£ñ„i)’ÑΗ1(÷¿¸h!$ÓèGËÁ0@uGeÑõ¦^6µ_`?Åæ>Ëó–w›¦í<>Ðè[7ÿkc8ôÿ¾õCÜp8»Õç¼ì {Ôàü*>^Õ™¬]­'§Ë›*+jË`î Ǧ¿fÏuÞôÎõ¶z0ídÍrÖ2À×{ç(’€¿Š™N¸ÞÅøl ½5è=uÑóͬΠø¹ËžÌ)Á5,š¥‰âŸ‹È±à–‡Á"À÷qoOÛöœ§î±6r õKlŸMë¦úfeç¡•ã—9}ÊâiÝ¿üO'¦)³1$eÌÜBB¤Eá1ûùXiÁ”–‹( -Y ›i®}Zp=JŽž|9¦§Ü8VÎWÔÑY-É5”ŒX†|êdG®U1±¿ÏX¦‹H¢Þ“Ù4ïi–#¢Ã½ísBÑ ´I[hŽ>AÚ¤­TÙG,BÕ¶ì‹M9ë8aÊ%Ôç<'f©ˆÕ¾çt$gç:EýD"'æFš©¹Cæîˆþ¥èׄ΋G$}tG÷´úç1$z'Ó¤²±DÍÆ´}a:6D¾M¿é'F€‘!tÝ©‡¤{xr%Y"g"FFA·1«nƒEÆÖÕì7bl"¶çïˆ6²¾mcé0!wdOœë×™cÐÛ«qE Òë•Ùcì%Žƒ æIšsÝŽ ôÔq‡¸ã<È3S¡#Ü­›m™œ­Vfƒ yèþ¶5g›¢&¸|$DÝЗ®„ -GºSTþ †z<¢Ñ‚“O¼íà"žrvZ@N# €™›¦©Š¾·¢0¯NwŽ˜—¢, zpe Ô¸LìS3‡ÚÜ„qlj6m IÁ¿À× 9+;²·æL€)Üÿ\“ÊࡨóŽ@RB;‡À‘­¥à›Ñ§,Îy0ò ÄM#1Þð–q3a@—;Éñ’¨·W7à•Ðùô¨ XãûÑ™­ êN¦^Â:4º¶°NnpûÚ4ugˆ Û/iðàÈ Ét}{žÛYÊ…çêˆ:{K!TeumωqÙ.£OÝ´Uæ¸Óa Ò~ôKûÕÚf2áCp¦¢°ÒÂÞU!w¾ª_US_•Gï¼SJWãtn3HÓDCÚGȯ¨°±£©b°sƒÈ!ýQ<ª=ΠX·q·ƒ¬¦ÓR.mÁ3‡îÛâéÉIË÷B ùtp¥÷¦ð0 - çJ©™(P)5ÊÆrñœ•Þz®ÒÇÚàÇ’ÿ9ÑõLµ½Ôp3¼2ýêUkƒëX¡#+î€×ÈP—=íÝÝcÏEnÜ)3úÐ]‚PóH‘&c`”ˆ½|NE²OpëKl›Ù¼gØÁfcêܧ9«·!A–Y_<;:ØÓ -Ããð†ýŒÉ÷µ&ÕݳݛN5Ÿkߔ룩ÁO>ap¨ø$Éâˆä#öN£ïWYjZkñSW^¬@hçÎD2$Í—U%vó¶<Ûº¨¶0S±ëaN¨$u8ˆAÛ!&£áÔÎDŠNC³®¾W>E#4ÃêŽ Ìùu™b~§ÊP6¶lš_·B?˜ÇÆyãLfÁÀÄI︛¬w)}­yÔ¡Ù‘ jö -Ç]‡&]‡VePñµ'¼sL<9‚è8¶&¶ÚÓ£½¶kw±ò#È1¸§ GÌ_Ò»ßýj>À‡9Ÿ6ÑÐ&ïäYu‚šNleùñVÖsŸIÆPëïJ&T·~Y6/¢3Ž>«¦ªüN:ÓOŸ˜&ñ‰ÏW&ëŠò#ÁxϺY‡š'âÜoöNÛ•™Oœÿij—#÷µ¼ôGr>™î”9e7TåßñíÍïlÆP!ÿúç7¥ÿÚ÷7²H'ñô~{Ú6¥…€sƒ{(=¡"<á}kÝtý.øÑ'׋éûvÅË"ï‹ütyÑšUß´.7`"=õqòÈòË–O_×ЈËß±u?¾vîebŸÃgHÂ!ˆþô«ûî' …oÆé‘w ÷–.ý¦ð|êàm'â!ƒî@Ìlýÿ÷Ür»endstream +xÚµ]sÛ6òÝ¿BÓ—H3B€ žŸÜÄιsIz®ûpÓv24IœP¤Ê»êÍý÷ÛÅüiÙ½äÆ‹Åb¿4ŸyðÇg2da,âYLz\ÎÒÝ™7ÛÀÚû3nq–i9ÄúþöìÍ•Íb‡"œÝ®´ó”â³ÛÕ/ó ¶ +Þüí§W×ï¾¹XDÁüöúÓÇÅRHo~uýK½¿¹øðáâf±äJòùÛ¿_üx{yCK¡¥ñýõÇw‰éç ¢7—W—7—ß^.~»ýáìò¶»Ëð¾Üóñ"¿Ÿýò›7[Áµ8ó˜+9{€‰Çx‹Ùî,>“ï;H~öÓÙ?;‚ƒU³uR~ÜcÂÅ„>%@³Ð¾àÎñ@h)|s/0Ðt›…ÎËÐóæE›ÛÑ¿ .Xì 5[rÎb)Iˆt²à½yCøMY×4JŠC³ÍŠ Íj]4Â3y¡£) ÍŽÌ6³d_¸ŽQÈÁx]èÍܯ¿:^/fJE±Á¹Ýj‹4”ðX#Ï ¬ô:ióæXÁdí‡Á, q)ä9 +¥¦õ»t—CŠFw#Þ8÷™/Aè1y×n&®ë &}/²Wé”éGá|›Ô8ˆ@¨š õ^§Yb—÷Õ‚«y¹×Us H³MÚ‘5)‹ü0Â^µ©®íZÛì[‹ÿ°Õ…£áÎÒÕ½®Kð¦W5iQãcÍÓÅŒ¯åúyÇ!Zþeñ§¦£Áq}îͯ·Rí’ÙÃÙC•5ÚîC3¿ ýüêy"×4Na‡^‘G‹ŒƒÑX9ÉN¯XÕßJÅ3+ì¡[{ÄøÞÄ\Y}1“Uf®£Ó¦¬ Îùœ‘t|/dA¡xŒ×E†þU ´DÝ´…KhF4’º,ê× ÜjU€kÄ + ~"˜¸+|¦bÎí –íÄ%†Å2$Ór·KŠMò¬0'I°¢&+íñFuðÛÖzex“†£ >Lp +åËd‰Ø9l§ÑÁi©•H£W–%4]l$˜àâ(x$ëÔ4S\‰!SSn±Z*'BãiBFÆÿ6†©¬FÎ4Ô¼ÐùùúÝk‘,a ¢&A:P‡!x£ ]ÙÛIt¸,Ÿ +l m¨8úKìg–ûºIªÆªš·{+¾HŠ€‰Ï0F^7æ V ØUDæF*‘5ֲěD>ÐUV§‰YZÞÁP”˜_¯iíP¶4(´¶çiÂošì›–”Mô(eàÉ %«¼žÄ®­›!–œQ +òoýÇY³u9r˜ñ:ç~£ ¥ »°Ü¼Ô¡€bç9°È<ëÝ}¤°‘¥+1‚èŠD[|.ºøL’»à¢ ŸŠÔ:0n‰Ã> Œ\K‚zRa½™’ÂSÀ-íøN˹Ûj ‚’pki‘VF›Ãy’7zÁçÍløšm–7K`q±VR/›œ‚èë)½ÝµVtt¬IVÖ»r•­G±ÛU”Êͦ‹Úwu_fEÓASpÈMYe.ó$vë€×ááÛä¾;¨ÐcöŒ¶8Ô½XöAÅåA]t»Õ£Ã-c?n«¤ÖOÔC‹¸zÈ9Cüé'j¾3AÁýÅ@ç/çuI æ.ˆk‰(ðV¢Ô \M ‹ñ*Á2GMIKµ¶ØŽ#ã†vYÐ5Á¿ÇZ¦P”H#`t´pœS)‹W Áž1ɘ" ¬Z´¨G³e’1”%œÕ–H¹ùŠ5È5åé¿Ó'8ŽPAHÀ&¡ít]'myΊ©ûÙ²L¨Ê}ƒH0ð"½!Tl#ÄH ÍdùË €ôÀÇyB²ØÅ¬áá +X­ ƒKpp”&BIsp®•&Â:i"VG޽.ó¼|èüÃéÈwí¤³®žÄ¢äoÜÆþ®ØŠt¤©1Â>ׇ”y>šna/iR.Ð]Daô)ÎõÉnŸk# (³t󪦅:9¦tè @¤rI¶e»ŠÁà^EcÉ8Ô„¦”(ìi&fŽŽHòÚâ»ÃÂù­÷öXãõXѱC©†8˜»@µ5ý¿±€ìýʦµÞÿ†Á¹ÓùIýE›ÚÝá³ÅçÑõ¸®q¼ÆòÊ }7ÜŽàïΧƒ„/#lÜ”ëòܵ®#òü¨Ò[]¯¾gx¸ßùT6<6Ù Ž xê§[ï¡nV]×Ó{6Uæ¶ÓD@ôÓbT‡†I똨á¹d‘ßwsøªñ˜]¨ÚüqßhÙ¡Ûqüþä.µäaÈ| ËPØCF3ûLÉP=S#Ä‹dà|Í”§õI3ðÕ]¢ê·¦iC[Â>M ´tƆ¬®&+£²Æ½!Îú:7ѹl‚žžÚme³M[YãD ¶óSÝ„ÖÅTù>4œ@F,àÐEüujCêQ¹Hìÿ’nÇÓ–åpøŒ%À­â˜Ó32½Dä/³›ø’n—ðV¹|þÁ´ܼTºkÛwÚÀe*HC OêÚh Ý!Є•ñå”iôí˨³¶qg˜€´[k÷¶M³–sB¹©}&Ž•|SårŤ˜§•ë̳½æ*i’»é>r¬Ü]Öö¥t±\² +:0M‘)](ƒŽ¸Ý„¥8-€6uUÐc.®Ü¦ÝÆp|Ô¿µ?êf”4þ, }di’v ?°tBÍù}+5»½œ¤Ûñ´š½I<£eîÑg*Vmiùœš/ööÝÿ>ɤ¸ÒEæ€&ßw9õ÷V×M}B¬=¿_'‚c©òo)UD(Ô3)2V jMúBãRɳB}{œsŽ¿R쓪îÚ¥NàV)x,>-ÞãßJ¼ÿ‡Øy,âO#ñª‰Ð£´SéºÌï»'û§ÅûîãO‹¥„‚”¬vµ(æ×øÝ7š×mºÅezF4W`_[þ½¦µ¼,¿´ûšÖ÷”&Ó –·®öt*ÅF7_=$Í3jÇŠI—:µ? +r¦[~Jçi~‚( ¨ù°ìJN~†öfÏF±—~ôîÿ# ˆ˜¯Ô WZµHAà +i¡ÈïÑ'y÷uÜb Xÿ/LN+8endstream endobj 1223 0 obj << /Type /Page /Contents 1224 0 R /Resources 1222 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1199 0 R -/Annots [ 1228 0 R 1229 0 R ] ->> endobj -1228 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [491.4967 546.2465 511.2325 558.3062] -/Subtype /Link -/A << /S /GoTo /D (lwresd) >> ->> endobj -1229 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [55.6967 534.2914 89.457 546.351] -/Subtype /Link -/A << /S /GoTo /D (lwresd) >> +/Parent 1210 0 R >> endobj 1225 0 obj << /D [1223 0 R /XYZ 56.6929 794.5015 null] >> endobj -326 0 obj << -/D [1223 0 R /XYZ 56.6929 744.5408 null] +322 0 obj << +/D [1223 0 R /XYZ 56.6929 556.3324 null] +>> endobj +1221 0 obj << +/D [1223 0 R /XYZ 56.6929 531.5504 null] >> endobj 1226 0 obj << -/D [1223 0 R /XYZ 56.6929 717.3918 null] ->> endobj -330 0 obj << -/D [1223 0 R /XYZ 56.6929 594.9189 null] +/D [1223 0 R /XYZ 56.6929 214.5791 null] >> endobj 1227 0 obj << -/D [1223 0 R /XYZ 56.6929 564.805 null] ->> endobj -334 0 obj << -/D [1223 0 R /XYZ 56.6929 340.8686 null] ->> endobj -1230 0 obj << -/D [1223 0 R /XYZ 56.6929 316.529 null] ->> endobj -338 0 obj << -/D [1223 0 R /XYZ 56.6929 259.8095 null] ->> endobj -1231 0 obj << -/D [1223 0 R /XYZ 56.6929 229.6957 null] ->> endobj -342 0 obj << -/D [1223 0 R /XYZ 56.6929 197.042 null] ->> endobj -1232 0 obj << -/D [1223 0 R /XYZ 56.6929 169.8331 null] +/D [1223 0 R /XYZ 56.6929 202.6239 null] >> endobj 1222 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R >> +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R >> /ProcSet [ /PDF /Text ] >> endobj +1230 0 obj << +/Length 2985 +/Filter /FlateDecode +>> +stream +xÚÍZÝsÛ¸÷_¡™>=W±ø"@æÍ±åÔ7;µÝ™¶w÷@‹°Í EêDÊ>ß_ßv!Q +e6M2“x&Xâc,»¿]ˆOüñIšÄLfjb2'Œ'“ùâˆM íݧ>ÓÐiÚïõööèoçÒL²8ÓBOnï{¼Ò˜¥)ŸÜ¿D§?ùp;»>žŠ„E:>ž&šEo/.ϰ&ÃâôêòüâÝ?¯OŽŠn/®.±úzv>»ž]žÎާyÿþäúø·ÛŸŽf·›½ô÷Ë™tùýè—ߨ¤€mÿtÄb™¥Éä>X̳LLG*‘q¢¤ 5ÕÑÍÑ?6 {­~èüã1‰œLe«$IO‹S0˜–HÎã,Iögri€“qg’蘹9Á{g•ŒS)“‰I²XK!ý¡üqoWÇ<¦eícdo ˆÆ$ÊÀD®ïšÚ¢H»U^·0²¥ÏGªoíê øyº¤FÏÞÎmùTÖñþ)(8£µ˜ôÿe‘*%hˆ†:|M+³Œ%c2V&ÖÆð]7ëî ¹µuñºx{ëþžÅ+EÌe"ÇÄ+a[‚g^buÓ•÷/£‚½ ò»¼º½8ÿ7ÒK0M×Ì›êááªÔ÷.<=S&Æ„'¤ÛVê¥2¯J[kå”Óܶ-¨Ê®¹Ç’Xô.ûïkÛví+òì-ôkÉŒš1ŸeOȃòԚŊ)5&OX[ʹö‚Z׋¼›?ÚbT¤ïA–ùƒ… œp·;§ÐŸD;S kÁ!u¾d,ÁtfJP¯çœx®ëü®²Ä¿Á²°]-Ê:TÃ¥~°kg#aÅDíÈ[`&é´} –Gª,º÷T•P^PJÔw]UCâá± ÂyÌëÚ¾b‰ûWòË®ù7µÄ˜+•YbÀ  ZâÚvÏÍêã¨Ý¸¤~hƒ—v•weS¿bmû‹ù޽—+¦²1c«ƒˆ‚‘±]p3F%vö†³œ£ÄpÌkâÚ®ã{–X»D¦é˜¸œí`|¶âš¶v¾^•Ý8b:Y‡'Q‡¥ ÿÇ\ë1Ô¯¹Ž¹aYÁæW%¸÷1)ß,íÜáW/·ç­uŸÝÇf]‘üï¨ÃÆYySÙì°Ô•‚ÝÏWÝz F_¥À gõ`εúèÂ_3àï´Š…æÁXÞ Ä¶Ìð )Áì{ÞÞɒDZ”"Ù]ª%À"Læ¸óÝtæ÷‰À>ÖuØihÂÄB‰´·À9°B81£‚_j–΂"ïÇÜðŠÖÖ ‹³T¦»À ÐùW[ Šà `äW¤[‹'À}†:<îe³êhâ. D<ñU_|ÀæECZjpwr`~ÇP—6àvw68|™i¼Å®ÅOåZ£ÔÚcLêÐtØyYZ‡»4.ö Ê…€Oöv Ü!úÜ&×εxðyfÛGX2–ùqȉUkñɯ,a?BD¥³JÚa£ÎáES¬À†Ä…›0ŽS¯ÐŒëƒæp~:Lµ_ŸNüœ7:š]Þ ­ Ѱ‚•ÕX®['}¥<‡qðî±<»ÂÒµÓ›Ù)~_}tq솫“ȶwvÏuà¸N)ûæF>ÚùÇMxwV¶î68—xá_×å:ÄxÇTÿ6²ýXÃDÍXä.*øñ˜ÿE‹Dê7ÇS.š»—7ƒÂ{~ŽíùbYÙxÞ,ËÅ%–'ð©ofC›ìOýæ Nj>oÒÚv‡&⤃®ï8¾Ð}S8¡T ÎÇò. +Ö`2“mÍëb‰f5îå.j9Z}ò;— óäÖËÁ‡„=EfB4ÜßQkÛ,,ÖÜçeµÆŽ‡aFs_ fg¯f?aF>1>vO!æ4^ªEÙ.]L=©#Þn)´AYÖp¨–GË|þÑzs-)ø•‚,!›Ä#Ћ¦XWèü÷oÛ†ánòêfÉ,·&ò¨Ãg¹Ò—ÉýÛ^'–Å`sÇйââ~輨açóñ“$G°Çoo.Þ}šÐüD°¯fˆûkþZ·D&qª“ϱ~aÄAÑJ#c°£–Šh3 y˜fŠÚ;n©~Î>•‘¾·îHã]K ù6Ë•E‹²7µC‚kŠÅTbèç¡v^4©îßšÄÁr¡Ý…ž7Ov€dÆ}~Æ•øTæ¨ ¸h5R€&ýötƒ%â–·Ö=6íÎSyõ¢ÂàüÉö6ÕÚmè°ÒôOãËNøÛ* Pš«±û(usÎɶÚÊ>øóœ6u5-Ÿmú;\.#?“| ´YôsóÐbËÖßüPù“EÊÇžrYV8‰9&$¥;ܽü×ÙÕû“ ÿò XÝŸ§F¦çHñvã“„Ðo£¾íOz†2?Áüð ¤mBÐ7.=£b¥X&½kw& pT1zéj»õRn^È + ! +Þ¹WT´wö_KE!žŸåýiÄAåBÄàÜFUTdâjŠ—ÁgL Âéã†ÍGŸL÷ôé , úu¤@íèŸëÝ`_»¸Še•—Ô×Å=ž(ÖvÐîxŸE]¹°€ýœ]……474` ¾ê¾óóC•cåë6ƒQ©w¬ªïÐ3e™í”öÎR¢ÎóS$(GA¸ÛÒ/s¯xã(Œá#¯žó—iœ¹[¯j⦣ó«ëéЖßÏ®Ýï„D5 +"ÇE :‹•~SP9Cщ¾i€jtïn0…ÍPgÿÙ´Þɱ4œ{ #Æ;ˆ´hꨒ¶ 2Lç\‚¢½q©3²«RR:Ç |ÊÃy^#™GÝQ“×f)A‹A”H"ä Û6’î[KÑ){&{©TÁLõ„˜¡Ûðµ5Ø_Tu¨%U‡ê êóዊò1½”£Î¨› ¦mñ ayÃú‹ne²XTçÝz³|Cc³y4ÚŸß-z»Bg&À‹3£`f*|')ŠH×>Ù]ß"Éb=D`›VP¢l'©}§h§Ë¦-»òi'¹í[¯éJª .fWÕP>5U.ÐÏÆwybÌN25 ¹NxFo»`»f‰T‡KÌ;zluî…ʼnd{ï»íÚ=ݺ¬U0Êøò\h~5Ù}(Q—€ ]r Cx´î+2ÙOLàuyhQÙî2=h-ábtHúÄt"ãÉpW ïÊÔH»3ª%û¤eyÿ2hQmÔöÖ9ÚqB*§·­P²®ÄmAÛvÊâ®0–C¯r18;Lêœ +™òm4uOyU@Â7=¬»ná9…2£Ä„ÜP÷à m£Ùý ‘~ìõp4¾õq¯ã}Ìòe8h ­¶?žû5žc˜Ùû5Þÿ7*,„ë _¦‰†nøŒ~Å÷ɯù„à±ÉÂQu¿=Ȇ~óÇ&£ †ÿõ†ÛŸ_*Ë4íÁ;ƒé8™q8V¹çw§ Šïc"Ó8IŶ[oñÿÕ¾$§endstream +endobj +1229 0 obj << +/Type /Page +/Contents 1230 0 R +/Resources 1228 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1210 0 R +>> endobj +1231 0 obj << +/D [1229 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1228 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1234 0 obj << +/Length 3540 +/Filter /FlateDecode +>> +stream +xÚÍ[msÛ6þî_¡™ûpòŒ…øæ~r§çNãô·s3i¦CK°Í E*$Õ½¹ÿ~»X€%ÊRr¹»$âeñ²Ï>Ø`1áð_LˆEiNâT±‹p2_žðÉ=”ýp"l™«4ók}sò쥌')K£ šÜÜy²Æ“DLnï¦ Ø)HàÓ篯_^ýðË›‹ÓXMo®^_ŸÎ‚O_^ýtI©Þ\¼zuñæt&’PLŸÿíâç›Ë7TYß_]¿ œ”~ö}sùòòÍåõóËÓ÷7?ž\Þtsñç+¸Ä‰|TuÞfmþÉJhtýI[ÖqPÙ6ÐHÚÎ#Õ(äu +Ùf Ð鲇Ũ^ i¬6¯€áÿ°]ä%Œw C«Ê¡LÓ|]74ê.«©Š5V·ch²vP 𣞢o„÷Ž1t$cám¥K «îm…UõÁ¦òúói‚ÖýN·Èdh¥`Ì`Ó­£g¼5NTö ;?À”Fˆ¿h‡s‘HÇ9m¾„F¸¢Z·Ïšõ|“¥¦ïÕ2ËËsOúY­ï€²â<€dÓ¤Ïã³õcø=OÎP8È9ÏŠl©ÏùY Ó©kHÜf h°:gÙâ–²î`Dڃ䧬 Ôû§Ø)î¼”YÀ#cþuƒ@à±±.ʾõ·BY@C•yUÀA^þ@ãŠ3+"£ŒmvY„”G&Í ÷ú-©÷…•o° Õ@Oè¯øºÓ‚‡ÕQ"½)»^Jì?Œ“ƒ•ÌL1W¦Ì +Êõý,¤ cªÐ®a劬€]sÁj†º±©»^SÛö@CÞ˜2@±CGc>•ã·¡ò1ð£SGã½)Œûžq&“"a2£íû•ÒÚ©Ùº©Š À!D:F”ÊÛ±0»[dü8‰PÕèÄk  +>\cK‡µ%­ +俸~ûöò9åIä ÑÆITnÌ +%ÁòÇlÛ˜£Ød&-¦IcÁæA—”*+*î»±MAörÕÒ‡“·ÌC-ˆ¿®JjG›Z@íËnÄÖ¹Á*C–6’­4ÄÙl 0žóÀÃéŠ|ÛìÖDs«í&‰R3®U ìCY´ë5¶Üñ~,ªMI)ãËÀﺤrp-¡3#ø,t¶ ߪ ¥Iö“øŽ>r+Nr×µ1R6¦©NÓ°d¾ +Ìã6‘ál1§¬¬mÕ„›Ö`/÷)2AÐÈAÊ";QS]Î ˆ¢”o¢øm>®û¸¾oëlþA·-µÖÍô)ðd'ÀßÌÜê‹Â™I"-O&Ò¹Gv,ä ‘HG¯³±•ê8WÅnÖÆ ’>\F³J]øb¶°±øi!p‘*Ú².Ô‹›¬r{‡BoF¯È|!÷Ϫ´Ùvó0)= MQQ*½øsÀC¶‚(¾ó÷’7.®³4~(¥®Mç(zNùA–£|m{:èæÜYçzš³“ëÔ Ý§f½\fuþ§‹•òrK‚ϲ˜ÖÅöÁ¨€³H%Ñ1‡0Ö–#†§0_ØÌÄCàÞ1P;ÂlÒµŠêÉO %UwÆ3@m$`î"`v‹ržÖvÁ­`AÊ¥o§Ær½¼ušrZ´‡FT3÷Píræ<Ÿ…«LÈZß?¢°îÙË’î9fWÛpÈn+”ØÍc;€r¿öÝÁ +6îX +[5mï‚;˜£ke£¡Å°1E¿kzBàQ\(¢‰¯¥ÿLñca˜x¡ãדL#`¹DîrEœÀd ‹@¥ÎuBw}Ìo* ££Ð4œºƒQÖT[çIT¸¬ÚA<Ú¸ý¬µËéA’°€‡êR#wt…dºÁþÔÈÌäàð!¬qdGÌv‡6D‡!_UM“w´Í:¶ËÛ3Ǿ+?¿*Ç»7YtìcŠ«í¡(çbtdü/ºßað1:eIÚð}Îbîµ_Ùn¾& ã©PœHñ´ÝH€›ŒRò¥lp;zr¤ìSé1†ÓŸ(\{”Ep3ÑqJG*Ñ[oY‰qÀ’ N(1Žh($GÉúé# ”býn!ŸT¢•⼞¼œë/ÚQÝùRæ6/ßòŸÒ7ñoysŠ8KbpcFõ‡Œ*˜È¬'Léæ O‹Æ,,†ùò£tSl1áaSó¢ùÃæ¦"–p!¿xºØeiçã ÇáèþVoÏKç½~û8<îÍKDî»éN‡Ýn;¨HÇþZVÕ‡õjèËãkúW×~±°mÝ2ðé³F÷ÛâÅ‹ïqëü7í»m{”5píæ&`zÊ<˜}Ël¥–Š8ÚÃV)ã*‚É„ ¹¢°ŽMGà,‚šÇ؃‹K`¬f[ÝŸãÁér^­ËÖêo+Â8:ƒ=îi{’¥'ŠG_lO¯7îüÒyRóù¸ùo;ŸÃÊ[Ç?[!Äqß íòêù«ŸŸ¾¶Û{†§0ïé[ƼŒP…êÀ­8žíÕÚëÑ‹æ€qž¬KýÇÊ#Óí+zËMÞ˜@9Æ÷Ž q®Ýží)  ®º3¤m—}`½gwûxQO[€LS~]çÏÓÙ·ì\à?ðX Ó aa* [tá4²>",Š•[Ç—Y^¬­.†4gŽÑz¢{ŠL¼­q÷~xÔµødF‰Ï§Â=‡m°ó2J ÉÝ{ëüÐÆ°;çXMWУ‹Êͽ;°~È>uŒú¸Ç‹Øº?{ +¬ +¾e¨.OžùIÑKslïDÇ€§9i¤ö¢uxä‡tòùˆíN†·!‘9jk³b?ßí ê?;?Üoe¿epÁx +U!˜I¡ª½ +¥«„ÅBF0~¹dUû+ÞBoÝ8íªmèŠð+÷[pÇ E¾Ìw‚Ÿ=Wx8ο ó‘[7äF_,ÜI\÷"'[­tSm½à€E"dI†þ]ô {ùj@îþ.P‚@°/(fAÄ„ §Â½Ýy®U"L)&}¨4<¦¶F`¯ÂúWKî¢. +ûWK‘÷jɾ©„@ü§EÙr©wT£È›V—³ªt èíãêwãÔÒ+ÆUU·]>~¼§¯ïlù´aŒQÂfÿë;÷9bÓ¶ƒO¹Þô©ßqhÕè¬vÏCíìÈçø¢­Ý‰ì+>r̃å-UkuAÞ¾ßfìí¸=øG/#íÂ'½ëcÿ¶Æ{ShN‚q¡s+ì p^*عû#œÝ¡ÿgH[Pendstream +endobj +1233 0 obj << +/Type /Page +/Contents 1234 0 R +/Resources 1232 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1210 0 R +>> endobj 1235 0 obj << -/Length 1102 -/Filter /FlateDecode ->> -stream -xÚ½XKs£8¾ûWpŒbyjN™¬“ÍÔNf×ë9eS.„QYHŒ${ÿ}…» Ù§»— çÈ#§+¹-Õ/ÀÛ˜ƒG(ÐéöïUcÎRá8FѰڦ-Ïê¦\³Û ŸÒ°ûT* -¢ð‘ ÈÑRý A9h×JÂØ -¡æù\¿> endobj +326 0 obj << +/D [1233 0 R /XYZ 56.6929 769.5949 null] >> endobj 1236 0 obj << -/D [1234 0 R /XYZ 85.0394 794.5015 null] +/D [1233 0 R /XYZ 56.6929 749.9737 null] >> endobj -1233 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1240 0 obj << -/Length 1162 -/Filter /FlateDecode ->> -stream -xÚ½X]sâ6}çWø:#U–mMž²)I³ÓͶ,ûDƱEâÆX¬-ÈÒîþ÷ -l° Ø&Éð€-ù{t¯t%l ýó Å 7lnB†03¼Yºï¦ƒ³oÀö#Püêðóë5µ ¹E,c8-`996†þ¨kA{u¯>ß]ßÞ|\öl³;¼ý|ׄ¡îõíýôéfpùéÓå °Ãp÷ê÷Ë?‡ýAÚeenï~K[xú÷è Ýôï®ú½ñðc§?ÜùRô#ºvä[g4F†¯ÝþØAr‡ÏúAÌ91f“QÈLJ·-açKç¯`¡wcZ©FP‹Thâ‚€‚ÒP6ãТ„nõ€…P× Cù –HV‘zI¤íÿeݾ‹$™Ì\å=N QiûÏ‹ô¼B³CÎ)B߇®÷ô(Cñjˆ‹D€¥ þÌe¬ÊT×-§ñpÉù¥ üsZ¯‡—1´^Ïçõ×"2J_G9PúÌ'ùËøÕ¦n7¬væ}Gþ¶ñ -$r{Y$þÚ -ææd=Júöcƒ‡m)±™†…¶IÍ ê/iW6N¡CcáMÀ– ©MÌJýs‹ƒ<ÏÆÆ:ÿmÆéØì¥±Y>vQ· #œVÇV*j-%¨ MÇ4›³Ii˜š”[•4Ú Rg2Š‚ä G©á—Bg·ÕÑcjÆmH,Dh–2r¤úíÅz×è±NEOƒ©;=Eï#HÝè9Ø 6´&£o¦í+‘Ld<‰dÝÅkg_Ü¢Åì^Ä5ü=ˆ R"^ºái”‘™û¨Ø’©ˆ -fB !ª¡3%ŒÀÏ¥±¨E£„¡¼9ðÂ@DgC猖_øzUñžDsR6÷q,EýáKözðÀ Ó°±«DCúû@$-TËê °MÍ·“6•±.ö³^FèžÅníɦ;Zeíùb…k¸º.Ù„&m¨&mbkg;×¾FMl§Ò~ÅS£Â).‹ rÛ¶ªWÅÑAÑ6®\íd{JÙ¼z« h$kmÃ+r5Ûrå`ƪ4‡\OJK†ØFÖIKlˆM‡¼¸G¾(o“2’*˜®€/Bwµ]ª<ùI¥êÄÉj¥M^àW -ÆÎK›Bjr~ÌϺI“gà[ä7Ç8Ä>FTIÍÕÝ›ÏÚs↉)Ré<¨Y实b;ja!,€?kÁ÷i Bù’à_Ñ¢0ùGÏk¤7ØÜ|ý4IæÂ«!—'uyqhyLîßUî9öÓ ÜµŒË¥…r½§sF÷BáFAôжÄ}n¬î…«”<ؘM]O´e %Pº> -¼¤-‚’s©ÃoUïöd|ql>tRäß6…*W­q"±¿­Í2´MËá$Žöî§fž¡GnŸ\}ÚP*lqÚˆ<×{¬i|Î'm«î)ƒë‹ßŠ_´;¬ž}¿œ_¾›z/s²»:&´puLlGÝ5HFjíŸi0ß^DRÿv2°endstream -endobj -1239 0 obj << -/Type /Page -/Contents 1240 0 R -/Resources 1238 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1237 0 R ->> endobj -1241 0 obj << -/D [1239 0 R /XYZ 56.6929 794.5015 null] +1237 0 obj << +/D [1233 0 R /XYZ 56.6929 433.0023 null] >> endobj 1238 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R >> +/D [1233 0 R /XYZ 56.6929 421.0471 null] +>> endobj +330 0 obj << +/D [1233 0 R /XYZ 56.6929 173.1316 null] +>> endobj +1239 0 obj << +/D [1233 0 R /XYZ 56.6929 148.792 null] +>> endobj +1232 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1244 0 obj << -/Length 1750 -/Filter /FlateDecode ->> -stream -xÚ­XÝs›F×_¡·Ê3ÞÇÇôÉMíÔÆiuúfÜœ$&(v”6ÿ{wÙƒŒSYi<–»½ýüíÞ">gðÇç¡°™yó òlÁ¸˜Ç»›o`ïÕŒ«c²†\ß/gß^ºÁ<²#ßñçËõ@Vh³0äóeònñòÇó_–7g–#ØÂ·Ï,á³Å÷W×?ÐJD—o®/¯^ývs~x‹åÕ›kZ¾¹¸¼¸¹¸~yqfñPp8ï O¸¼úù‚¨W7ç¯_Ÿßœ½_þ4»Xö¾ ýåÌEGþš½{Ïæ ¸ýÓŒÙnŠù=¼0›G‘3ßÍ<áÚÂsÝn%›½ýÚ ì¶G§â'ÜСLÐãƒrÚ‘ó@D¶ï:nÁwg–ÏØ¢N7ÖÌÒ$Õ{+͵ªà¶òf·RÑßÑã=:Ú-ÎíHçPüÏÓ|cåE¢ê¯–‚O©›êxQü)Qz_ª“ìÙ¥¹U…™pŦVVúqmíU}[T·yq´ñeUܥɤŒ#´Wê¯FÕúÄÓºRR[qeÉÚªK«Shƒ§ÖÀ­¥Ó݉ÿ!­%ºÚ?KlÇsEŒ¬(‹J•–·ørÄ™@i¦E.3k];K6z{j>eÅ2Þ>'¹cŒÉ<‰ºK;„”RoosÙEçÈä¶V@¥~R]Ý~R·u©âg¤FÇ[k'ËR%8 X©»¦ñà—€3UU d“5Æš?˜`DÓãóÿF ×o®/ú#üm*Ék«IÊë_j/ÀxüÑqÞ ›AÖ2µ‘ˆ«È³=ítv}Œ³&1bÿ6Ò!©YZô~î´›fèFÕ>+6§7Ik¹Ê”%³MQ¥z»3ÉÊ4YÚ³|7rêpÙØþù˜ -$€ªM8µZŒ8S²½¦®Ú#ó.O*˜‘5q–ª\×V©*«ÍÍÉùdInÕŽu -)^”óCíiõQÿSÉ{,ª£-S»Æ™"Üñ¬®DÇã"×2ÖÇçÏ*rU%l:à?H¤u¤ž×i?©ª€¹Ìª iiZ‰b޽B,ǵ#œŒG¦AõÁæ·—Ÿ÷ËkT Ó¯ãù¢eÂéœû0ª3V”سjÆßj©ÕàG¯?¨?sòö†£¸¡ˆø­–et¹ƒÑT9í ´ª–[Õ4˜Ÿa|Ž"˜‘§³à±0ׇéÚ†¯纋Zá‰TSÒs“+¬¤Ü‚]àÓ[¬”9P«„¨Õžžø¡c¹Ü¦æØÂ4Ìx+ÊÊèi{=Q±¢Ìfóqf°©º¾¿øP -ÛMSIŠ.îáJ¦À_D‹«5-ê-TŠ¢q¸  ˜¬ÚañÿŽl$ #ûdG²Lºú ¢ÂUVĈ¼OqbB`¥5â%RCÛx\Hum@Ë|;Q8®„D­e“ÐݧYFT›.ÑNþ‰ýè‘ÙLÀ·+"ðœpúƒØ0YC®ö{n¶îc³çjJ+ëúïfp¿¬ºçšÐ=Ìw™¾?VŽuc¹ŽXÜÕ¸ÝèLj‘-”/вvµXÓSwgL—†nüÜŸç†5‡éD®ê"k´áÅ»&Ùñ¥CYq -‹„S“Q±cþì”C×£’s=(AùAå´$kz’/ȽS´Òºeȶ -‘zp=朷^EÜÄ9:ø "@ig)lÁÝGÄ®¨5Q݆ÌE£ËƬ“Su÷"˜²76•Îèãÿ ‹cð»jò‰*ƒ¦D¡kªŒî[ÒÒ6˜ s©I'ÝÐi»2È)¾‘°¼ÐDàÜ’¢7*zvBFÙÄ­M“²` -2г¦…¶sïŸp}׆û¨k"öTÚA×ç¿yAˆñàærñ#Èâ<~h–ë9‹u»Rìˆá~›¶MHsÈ$ö `ÛZ¥±uX"\&ðaÈŒ¼mÑd m®Ì¹¶+Â^_@£–ÓÓ­Šq›‡¾øV5àúB«ê¸Pëµ·žnWdÁaÞ—Õ÷\úGíJ@»b<ðû¶-n|0t¼I-‹E‹d’Æ´Ù”‰lÐm׆ZÅM¿qšÃêÔ(½œ=J,Ý®EÓ³–Í*ëôá´Bc˜¢ð WUzGæ8†ˆ‡6à„0€•á\MŽ…åzÑ"]_ز6&áÄ€¬zÛbÆéÌœó |øD¯ó‚î>ˆ8&8‚2Þž»¦ÖãûTvÃ\àÛ4t Ü\aão§Èaý ùÕ?Ñ>ü~í¶†Î4]œ!œ(èŒB¯=qhyÿ[îcÓÿÖ½ endstream -endobj -1243 0 obj << -/Type /Page -/Contents 1244 0 R -/Resources 1242 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1237 0 R ->> endobj -1245 0 obj << -/D [1243 0 R /XYZ 85.0394 794.5015 null] ->> endobj -346 0 obj << -/D [1243 0 R /XYZ 85.0394 285.8176 null] ->> endobj -1246 0 obj << -/D [1243 0 R /XYZ 85.0394 252.9894 null] ->> endobj 1242 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F21 702 0 R /F23 726 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1249 0 obj << -/Length 3961 +/Length 1976 /Filter /FlateDecode >> stream -xÚ½[_“Û8ŽïOÑo箋٤(ŠdíÓlÒ“ÍþÉÌ%ÞººÚÝÙVw«bKŽ%%éûô$Mɲ{î¦ê*•˜¢ ’·þˆ[U°ÂföVÛœ).ÔífÃoŸàÝûái–h™Rýqusÿ³Ô·–Ù"+nWÉX†qcÄíjûEÁ2v#ðÅÛ_>þüáýß?ýt§óÅêÃ/⋟?üõZï?ýô·¿ýôén)Œ‹·úé×ÕÃ'zUø1þøáã;ê±ôsaÐO??|zøøöáî_«?ß<¬â\Òù -.q"_oþñ/~»…iÿù†3iºýœ k³ÛýM®$S¹”¡gwóùæ?â€É[÷éœþre˜Êòâv)sf€ÿ¼–ÓB‘V–2“QË™˜Ór B-7å¾Ú.u]y¨—›#̺éërwæ -Tlsu]ŽH5#Hº¢È˜ÔÊŒ%Y¡5 -‹êØ G§a|Ú¸5Š‚¹¾ïuÿì[ÏõÆ7ûÓ÷NÔ~n‡Ý–Úå$0ÊÍÈõÀÜ;j“¯CÕõàKnÑ gZ2,áô×]Xb–Á7ï?^®>xOÝÞ úvÓîÀ´3ko‡# Þô;ÿqÛPË,þR×}ÓÑ;E?‰¬)¸ö$å·²Þ•ë— l¶#™ìTe8>¶=2[P üäv*¼8ëfSPáHàÕŒoˆ ô5cç¦lü€›¯CM쉪¦q‡§é÷Ûê±Èi`^@ñ{z«Bÿä<ÛUoè¡iûrŠsN§†=™Ü}Õoî¿׊ÁH}¹žTÅŠ\@…•*2½ø8,¥*@N‡ÌÐJt¡»} „ˆ›J-á{êúg–å^N“Ú½1,×¹ôl·Mw?3›L2+x´Ì¶í¾p?Ÿ‰ÖLsл٘ÅêÎf‹–$ƒA6-bZbˆM:Øð›pÍ +”ØêÐâ¢,gÏÂôöCç·Üu-µÖñú‹Pƒ1£§®B]Juê"ÕŒð#|qðüæ‘j†ûß„eÚ¨ ûÙ‰Yx\»<î`ÃÖEp僯 -±C„‰Žšdqô¹£Žî¹ô®NÏ„gØzªš -Ãå–¾p€y¾¸2 ¶¼ð+¶úËÃÍ,k¦™ÈÌÉWpüÿtò3–…†¨Æž¸ÙÕ€Aˆ°Eаs}9‘H –+n_È2® 퉪›ç²yr8ÁÁ==¿}ùBöHìbGÓz’˜ ák> -À¥®ŽZuô.P#Í#Uœˆ«„ öbñᑺ)TÌþ éGpÉ­ž(ȃaà-\dü¯ÒEÆg‚Gh|¯wžqyw`Eþa]Í€ŠÐS… «¦àÜk¡ÆáñÒ¬~Fç¬Àš€ÿ>Ã°ÍØß†BJ&è+¹]ü>~¯»Ê+Lêœi›ec¨ò)kP&¯Î+dqz5ò - p -ä0lÍëðKò,xÃk»'¥ ßÝA£Èޝë.¡º¢»@å`|Ø.¨NpÁ”È_a©f¸•W°w´FìW!JwöŠóTÉKè’‰RȰ!¬ip*Ýä»m uuÙù'Ú0„üŠŠhÕM×ïÌbØP ’m[Ï"|4_š@*ËŒ-&y˱Ùn¼g‚TÛõ|ö’©"K’Ë$>F£pI¯ÄíÔgGûu7—("¬«Ó Çé*CJ ôBÜæÒ2H¼íïN?âˆËtHg#餀arkOœƒA²Y…å‚™\Ѝ°K®ì…Î_ÙL©®¸J rûÕ¾ëËr¿zÓ]òˆÈâ«RDª1F>S–ÞŽäð!‹'>ƒO®3Á> >“tŠ$ÌA9Ö½ /ІÉaäpí¡+Ÿüw§ ûqZϬ¡_H…{0ÝœSI‰]hº.¨a(U6vŒßgÏ\‚¯ÙÔœ™_•¹RÇ@šd»`0²(pGà•¸”R]6˜Håvíëí31–ÿÈë¬Ñ ëQïΠŠ1ëÕü‰ áª>¨œp59e9ªŽ6âmzŽãw7Uç;>¼ Ç:Xê̾p8æÆ­»,ø‰]\wÊt¾îhþÒØàú÷d_y†–œV@}pš{gô/ƒ…˜«„¥†‚&OËûB{ï‚*6Y=÷ì¢;üúÜZ.w.lz:ãiúç²§Ö÷²ñ-ç:–¢ÿ¾«Ÿšr×%¯5?eÈQ¼QNè‚UÓ¸¬Bj¶t6:œYÚ,>Ó®’ÎdÌJ2X…xÀ”LÖ Û6³7|$òXÖæÅ}Bë ‚ ÄYt”ôø«³hœeXêÀÒ÷$bøh­Ã •OÃÒr´èh¥}媜̧ޮñB»]®`÷5TME ¿/e}š¿”DïÛoX>BøR‹mïß¹59fT9˵ (sAq™Jwœ)Y§üä’ydí|ƒg>üŸ(H'~— pޤÃ×ê|»Ž¦òئõuHPcvQ5›]Köœ”Ûvˆö×Ð]ÄÎÌ&5ϯcgJu;#•³s<[úñR šqà~U‚H5#ÂxÓ”g´Ë@P TháÉZ…±¸#NíJ…€¦’ƒ'’ÓÑû¯C#ë*¾p¨­dWD-6“ƒ9èòÅiˆº\NK¸Èiÿn„“D×Þ6,·O5ýï…DWp(Ÿó"8ÿ)ÃK5¿?¨ôhõÿ%Ée×d‚¸ZÒ¼–àýËÅ+%WJuÅ´•K^M"qG}]„H5#Ãx·È@½ÅÅXJxž&ðä ›{ÅŽˆÆÐŽ1AÊòp€€ÖùIºè¾hé×\@>-¸¢­ÿuW~Ûhn«œ:Ÿá=Ê‚„˜Kóœ)³G ’вVüˆüzœ¨8à¯èÕ)Q)ä[Ì ñ8C½$OIÖ!p¸ƒ¶"(L6Zð]‚^¢¹mœÖ*Þè( >H;Ö—Þ§ÚljǠì0¶U·9Öë$PLL6Ë$(ÂP†Hj¹+hèåñé–ŸãôËôƒsã=åÿ\mümw—,gPˆžIdÔײItæD‘ê59ÎF»Š -H - -u;RªËØ©\žÖÒ¡WÊTÆâÕ¥«LÑ Ó6r–[ÀëSfñ÷w¿Þ¯ÞþJNhA’?ìסˆà&ÁƒaG¤nk »¼ÝVõ7Je¹¿BŸ6ÛØûîãgú4½²ây˸_¼Á|ÍäÑðøa1) ’X¢ã *ȃ±òÈâ>žŽ·ÞN÷¦ô;v/ñâ”?Ç7~·/Ù9ÇSqÚùûÝ +Ï âQ‡oIŸøÎ9Q'¤Ms|?†`ܧ°i0 ;¶§C’è7í~?4þZQŒôcïÚµëÒ ª¿láÂê•› ÑûöD§£Ìå¶úVoÎÃb–3]hq•w$:g>Nø,Ó`/#î§‹]íàŒmãŸÛGúÜ%#<ø;_¨Yü]{Bª ]ÏËüe/*Ï2èx˜Vû+^‡c½/õÎwÓ?jûs}·4ŸÞú|Ï@^f&ßðÄÌØ» -(¼%9FG¿î”ĵÀ‘š®t˜ÚÑ)¨÷E@~<ÀC |[g;ئL»"¶òÄÿ ÅO‡Ž¨l¸DŠ”?° ‡øË¹«^.æ"•AP`Èu–m,wð!BZ=‚žãqŠ{ò·Àð#—\@á ÙàSº>j*¿…Eìk/Hø-ƒþ¢—”ýíã?®Ï.O—" +ƒ˜.£8 ~<¿øLœŒŸ~¹ørþõ×˧‰ +®Ï¹ öåÙ—³Ë³‹Og§KžFÖ §á•_Îÿ~FÔ×Ë?ÿüñòôöú§“³ë1–ýxy(1?NnnÃE aÿt2™¥Ñâ ^BƳL,êI))=§:¹:ùç¨pï«]:—¿H¦,JE2“@Åçe,–BÚþ÷ŒáÃÁœ³,ŠІ‹¥JXËÈ +ab¸€,…aTOî) WC>èZ7½~Ö¿…¡hÌ`Ú†8ySñkŸ¯´³$÷|C"b"ã‰5t½Ö£;;!ž±4Q/Êý—ªÀ"“ÂIõ;פàAÑ6èÛjÛò4@ÿ‘;€9K4ym©0èu÷¨;÷¹¥g^õž*œ¾ÜiÈéQ™ÕzxÒø?1œ™¶rÊFÅ€'ĘÁoa^i}¡H„,Å2ÅiÌT’p,&}ìV ".÷«ïå—û lõ'éy©Ót¥‹%zõ–KËð‘êÈ3@‰ý两¶ª#Fû@œ¼,]ü=ÉFáv Ü¦í†žê‰ß†uî kãäMÖ›B(ö÷[ ¾“5‡ÞBPÙ4qc÷q”¹®ÌH÷ëv[•DçE¡7¨‡Ná[ÝcÑñkÛ@¯*(Ýù1š–ž QƉîUþ>Þ“É' ^xÛëò@³ËjÚ«ð·±Qß¶µk +§ëÔsä<™ª" +ÄŽb©vóØh.0aÜi"§íÖ)øÖäÛ#Ze±ÃУÑOs ¦Ðÿø%ÐD*ƒ{Ó”=‘” +¤v€À7>sz Ny°Ãò¦ˆ_x«¸(°n:;Þ²3õùâŠÜz?!S§…Øä…ÆÜÉ4ÀMBX@#´…¹&Âùµi›^“¼¯èåÞ‰Áé‡î4 ¶UÊ6…×ê„z»W!UçMcãľ쉗ӣi»:wÚ)`@ºg¿t(Öv’ ß‚”‰]!3aw¬;¬ª«jŠUxöR†n—…Ï¥~ÈaL“ e)¿ +»ÂöNFçûm49Žÿ}CÔj_³½væó†dtGƒ´­ÎDïn{4¥vQæô ©öÚLÆ (ülëÆ›nk1ÒXó°°/›nJ?ãlÞÆéXåƒytr¶«‰4nbo|Ûö +%ܧ½)ÛaöP‘°,ÍøLÖ#¾ˆ¢iÁOŽGo> endobj -1251 0 obj << +1245 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [222.5592 220.8351 286.2499 230.2447] +/Rect [519.8432 682.6714 539.579 694.731] /Subtype /Link -/A << /S /GoTo /D (statsfile) >> +/A << /S /GoTo /D (lwresd) >> >> endobj -1250 0 obj << -/D [1248 0 R /XYZ 56.6929 794.5015 null] +1246 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [84.0431 670.7162 117.8035 682.7759] +/Subtype /Link +/A << /S /GoTo /D (lwresd) >> +>> endobj +1243 0 obj << +/D [1241 0 R /XYZ 85.0394 794.5015 null] +>> endobj +334 0 obj << +/D [1241 0 R /XYZ 85.0394 731.9325 null] +>> endobj +1244 0 obj << +/D [1241 0 R /XYZ 85.0394 701.4683 null] +>> endobj +338 0 obj << +/D [1241 0 R /XYZ 85.0394 475.6865 null] >> endobj 1247 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F39 885 0 R /F23 726 0 R /F41 925 0 R /F48 940 0 R >> +/D [1241 0 R /XYZ 85.0394 450.9966 null] +>> endobj +342 0 obj << +/D [1241 0 R /XYZ 85.0394 393.3855 null] +>> endobj +1248 0 obj << +/D [1241 0 R /XYZ 85.0394 362.9213 null] +>> endobj +346 0 obj << +/D [1241 0 R /XYZ 85.0394 329.3761 null] +>> endobj +1249 0 obj << +/D [1241 0 R /XYZ 85.0394 301.8169 null] +>> endobj +1240 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1255 0 obj << -/Length 3390 -/Filter /FlateDecode ->> -stream -xÚ¥]s£Fòݿ•—ÈU a`€¡ò䬽9'YûÎÖ^.•äK#‹ZŠ@v|W÷߯¿„äMÝn•fšéžþî©óþ«sûA”éó4Ó~¨ø|¶: Ο`íû3%0žòúPßMϾù¥ç™Ÿ%ar>]ôö2~`Œ:ŸÎ¼ÿÛåß§×÷^“Ä¿ðâ$˜|ws{Å3?ÞßÝ~¸ùþÓýåEª'Ó›»[ž¾¿þp}}ûþúÂS&Vð}(;ùàÃÍO×<úþþòãÇËû‹ß§?œ]O»³ôÏ«‚òÇÙ¯¿çs8öge&>—ÀWYž¯Îtù±Ž"7Sž=œý£Û°·JŸŽñOÇÆCœ{‘öM{Œr9ðƒ¸æ¥qæ'Qu\Õ—ry½± »Ùع÷Tníþ¡UøY ÌyçüÔQǾ1‘Rp³¾›pÒ¬í¬ø-B;3™š´K‹KѤ,šÖά}][ýÄÁ%Ôžº„0­xö¥(Kž”ìªh»í¾Sf"‹5à“}ˆ4YT‚ÖÑ’Ïç…‡|BéøY”"”ŸÅqHÇi‹ºÊKV¥ÆÎð•_ê?s~ü±µ›W2ͺ® Z©`2%t°6·‹|[¶üR4ü¬j™hk~®y‹Ñ8*ÙZ¸#äÖíÝí5²Ç?PnÑ T%¾6ÙZ¶:¡d„,ÙÔuëÍmiŸrd‡WWå릥 éijN’ÐÒ0Ð3–gj@Äô" &Û #2 z*½šT¢3»²UËó(,„Û§š& ÙdúÓUÃàÈܶ^ótiŸm)Ÿ×«¼¨VIœÈ«9A/¬Iiä'*ÚÓ¤ו¿íÒIV´iÝW4ûç¬ÜÎEÒh-$a`š§2?ŒBfÁmÝ -HS¯dÄg ;[èkØŽ‚—¸àÊúO¢°¿…¡¾ºÆ¿ïd†?]dáäŸ{“Ÿð¯;Í|·ðñÓÃõ§8êtô›º¯\pžHùÊ:³¨O‚`ò:°N}é£êGulãèñÕÜ~õ­ Ëçn¸mºájÛØíʽþ÷[qc¨yqÌÒb“ ‹N›Z긭uPˆr^4ùci½¼|ª7 6«æÐÔߥ'Ip@#$ L-ý|ú†+¦D›hñœIÔwð¼ruûðpýž{äÒZÞÊ“4mY¿¼µc•¯ÈƒBÄÿ^Ó9ê⎺²Y—–UlÀSðJgȆãÌÜã1~ ø“¦Í[r$cf•—p;›¹ël©uî~U7bxÝÙfΔbìn³õº,p³c*¦#?Sɶ:¡`D,©k^Yן󦘦 I['ÑIôÐ!þv%Fi2 àç¥E_”¯í»jpúqÔ‰p„Þ}~‚Yg ¹æg€mè›™<çe1Ï[Ê6àU¼2Œr¡(/[»©rr³I6YÙvYÏe“ºÛC´SôÍÆ©%§½ˆ>‚íãÇë_pœHŽ0ãH5oŸD (8Å/„à†P: ˆÙ×[ëc)ö6Æ“â¼_ï+Žl< ;=C{D%×Îlu1Å®mÓŽˆ.Iü@œ¿Xt*ÉäŒ2:ŸÑÇXÕ›ÅJ˜ä]y,åèp˼á…Ò.Zž’=ô䳕sl«vsa&[ÌI#±Lµöƒ²ùaN(ð^^Í–ÌÓT š¹+¬]¯-å$ÉhF3èãÞç rÅñ–ç† -s %òÖÊêvÝG€y P!ÊTˆVÌ@ÝrfÍfÚ•RÒ?Eé>Nw:ûÕI·osDmSJEšbU”ù†r4ܾÞ3—\VÜ÷Çù4¯-çl#ÚܹjG•›÷à‹†9:(ùÊ·iºóÜ;ý9ê¼uN0Ž“Þ»uÜ}wP=£Z¡:>ZÆÛÍ¡‡hžé0=MF5BÇÀg°îÑñ€Nc&¦“ea7(g0lxòeYÌ–ŠÕ|ŽÊb²ç9Ù>qÄ9*ŽòÙÌ®[WÍ‹Ý4ü‚V‰O؉@“]ªÓ»ãû\M’ÆX…²ª#^pŒxq¬8vŽÇ=ÇJü AtDCÁ Úu¦97*ª'|‹& r“0 åSO踀pdç0ùè‰]”b¥ZqpƒT»cV/sÛl«¹ò‘8µï6d̺ºCÆØúêXçÉ:•o’Xÿ¥”%ÒX>óè熳¶x¶þ*Èì¤ì¬6J}¤, -laî â  ªù®®KëjÍ;)´Ž¸ªHC© Þ¨dz@Ç•"ÝØ¶K¯úSÄtЗÒ~šÀùOá»R™Ÿj¨)ûØGà¢ø¯™z*±–(0.MØÏW! Ô©K?//Çö5~œ(òèq—®•ÝdL‘Õ’ÝþëêîãåÍm?Üq¯©í³K ]¤—¨‰)öæÙn:l’ã(?LM:´eö¿&CÕÛ‚-¿ÊˆK§ I%©¤Cú[°¾ëo#ö¸®À§&N¾ÜK}ë¸M±¸gÎÙ2¯ž,£\p¶¿âi/ÃÈ¡‰t'³Ék½•=v-à b89,ÜèÛyÌŸ ôN{Ñ£.ç]Þàš0‹öE¶“þcÁ:0—ʰ²ûIÄ.ÓØ5G¸† wÓU¥§ÔÕÌÑ\òY?UúJ²uÜÄ;(rtþ b¯WWžý³h«I(ÝÃ8;MC5BÄð¼ÔÔ‡TL—.g㎒ÔÛT -Ä -dì$PÈÒîÂ0jwÍC[IçVgK;ûÌ -oÑH¶vUsëWA‘vÈ+×Ë+Zj(FÄ ¾ƒÁ?ôúÀÈ4M‡üŒ—Bà­Ŭ°=,”jG½;±sÆL1Hþ9 ÛS°øø:âþÃÀø)yàÉv# PigºÔ-dB\jA¡:uDíœ,&TcNÖ‹¢ÈÃ0jظ³Õ¾Ö±Ë·UiQ ¯½UÿFÃU_+£![zš¿Ó¿zµêôµ,*;´?W dÞØ¡7=„Â{ø‚÷QíWYæëмQ™õ¡ŽkÅÍÆ¼„|_íÝ™Ÿuo5‚x(3P61«lpôåñc˜ -ºâ yA—EÐ$ëFNýÑ€Z¢¼à®;p®á)LGðÝ•8ýèàí -9W÷±Àn >XH•„ÙøÆmÍÓÈkŒ9sKŠF>6JüX§{ Bñ¢8FMüŒ)“ -â,vCh@µCœLãöiÙò‚ûaø"Ý]üR¤§¢³§ú`vy }A! -GÂJpS`ä ‰^¸DÍ+Ül^ÐöxˆÌªÚ±n˜ -"RT9‰½20EÅ<™»4C÷‰NÍ'篫àØH‡FIÛmø&ñ-ÄF剦v°Ôk„Q!OR,©&{R©Øò±žL)&™8A4¨>ßñkMqd]‚vPz; ;³_Ú|Ó>‚zzn§1çù&ÖÎ6ÄS…“e½¶‹-§¾ð:ßn$ø»ëc"H38'…yÈ1…vÀ¥ˆ1øÒl×r« Š˼3™wºw‘±»ÌsWÌ#íúž0¡ä²' îGõò­è‘&Bùx+ûf‚®ú¾"4^EtíÙ»¥œŽI‘àUn°ç*÷ðD¡ot抴.ÿÉŒdÔèJb1LQ± Ͻ8m8Ј!%6P7w•àsa_F( c_&îéÈè¡LÔåè$ ‘ ‘O‚ôàzéËÉÑê‚"/AÒò³~f_ 7!„)àïrúa#7}z*ëÇÎú¤C&­S~<¢Ä å!ÒWÊ* -‡Ò§ö°‘„ -âC`D~ÎÄÔÀ…Ç*oZ*Mø¡Uæªíþ]k\‹gù.>WÝv¾½›Þ|ø…Çl‚lm#0äÖí³CSæÏb©{þ [bFÜcôtž;CÿµÅò0JЋ§'¢69à@¸P,-Фq\mW”rvÞŽ|eÿk¢Œ‡HÊ=}ÂÙA‚×_:z -f‹ü¼Æ]fvåM§2‚¬_²÷¹Õ«³ÜÎ꺒©—VUÿ×3.yt­¡êjbçYäM¿@Þ€½,Ò |¥ÒoA8Ǭ†Í5 ³˜º,];šÚ«LùQÚ¥UÝ"F¬$ðU’¼é+¢8uU:1ïè~ *ÖÇ3Y×n‹}üýÙH>t•ÿûgn»ßêÔŒ ÇÓ(H „ÏRG®Ó}ÊãÈø± ÓÒÿ‚+Iendstream -endobj -1254 0 obj << -/Type /Page -/Contents 1255 0 R -/Resources 1253 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1237 0 R ->> endobj -1256 0 obj << -/D [1254 0 R /XYZ 85.0394 794.5015 null] ->> endobj -350 0 obj << -/D [1254 0 R /XYZ 85.0394 396.2024 null] ->> endobj -1060 0 obj << -/D [1254 0 R /XYZ 85.0394 369.4308 null] ->> endobj 1253 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F48 940 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1259 0 obj << -/Length 3376 +/Length 1168 /Filter /FlateDecode >> stream -xÚÍ]sÛ6òÝ¿Bo•gB” ><¦©“sçâ\wnz½>Ðeñ*‘ªHÙñýúÛÅ)Rt.—™ËxÏš¨(H¶ñkz—$Y+¿"ÿ´+<µtNáÏË–Ë¢)ªpzE¿u^.‹òÁ1%V£.$}æo>Ü]¿ý•´˜vÞë¦f­¤RfE’:ä·E‰·&;_Teãð«ÈJîáN„ˆçÙb]äùÒ>Óï¡ö}ÿVš›4Ëê©Ädcµœ&¥Å¡EœôþœÿïówwïBßö}fÛ<¨*NäŸ@uø¼¦§å!'À+Y^<:-Á•¯ßÝ]ݾEžOšªüfËÊ‚A®‹å´Ýj–¤æ¤yš•Ï>húF«{ðmi€žöE“×hâ<Eò£¾Þm•j7]3”·&;y-§Šm;}Ô± -ܳðB¸®OK3­f]¬ójÖb¹F\\l–ÑbSäe3Høx"@ ¸œ& Å¡ Çl‚¹<ä©=ȪEª[çŒðSæ Ъ¼”פƵ–q|»Ûä[ ÚµµqÀ¯$›FC·Œý[‡ö|(«ÖUˆTQK¼·Ö‚ªhcæw—ô’O¦,悟(õÖÍO`[³\澕š·9=ƒãÑ4Ž”m†6r3'ú¥ 8}z<Ñ¢¯ S™8™×»|5zŸäæ© -ß]¶Ï?L—2j;¬<(ovhÖQùiYm³bÌ@98‹í‰ÝŽ“ÄL&"°ÖöwûÇ[ˆ¥i0Ìýj‘ˆØD˜Hñ1aa¦.'MQ‚øUèßòlyÞ"cY£á/XdkÂ"–»÷ªn¢º ­nŠÅÐ"Ñ©`'d’€k„‚¾E‚å‚{ë“à2 Å;ÑÑ%ÁЇ$ J|}€ü#ÏwÞçrŠêðÛáÁ!­Ü›I\úHi/€Èl¿òoV\,†ã· -9Àî…A¶ ‹›L zçéÉ{‘¢Y{Wꤞ¿på 8{Û‰VLj=}Û]¬ó·Ýb!¥h+ üGÅ'j\G÷Y=Le Ž3}ŽkHä†}»UÖœP’+yÌ‘¦1q¬`FrZÃTÛ6„E"áóë†Ö;7Ž€ÏtqK¿u;”Xt†Kláq çì·En‰I'¨Äž2úiöYYƒ@lhIÝTþí*‡ª(':á(‘”ÕeÒ‘Fp].( ~¸¤ÿA¹ƒŒ1ÄsVíð³ú¼Çœ/}¡QÝÅšPã€ÕÏÙ=ÖHȨŒ™>6 ÛK¬°À‰yÿØÑxªÔNŒ„3Å•é¼ì§^Žný -:8ìʘ”tF¨ÎW[º÷u̴ΧjÈ+"¿ìh€Ò „è#×0i›O´”(G®áEsû‡·]—УþˆK9݉úºšH˜dü”(ºéKÑÎÖÃ×Jiš€Á^>ë–ÚP¤@:Wwâ"Nù«Š)߯éfÝNá½Ôô°Ú͵G£ð¬µ˜x©ßùݪÄbà¤(‡JÞJqâÏ\þ´p‰¸2tekü»‹[·eS ;p$ ª"zK?~xMÀ{çyèl–A±1%)ýzÇ<üº¾áñ¸šZæONfÅ'-êlSWÑÙO ÐßH>‚£èÃÎ}§,ÃkQ•xöâ æÏý†ùø·Ä æL …ˆ„/;D -É—fèsýÇÎCÒÿù§3†endstream +xÚ½XÛnã6}÷WèÑ.@V÷ ö)›:iÝlëzŸÒÀ %*&B‰Z’rìnößKYK‰ÝJŽ$J<3çpf8¦¡éêÏкh^`CG7-LFºö Þ]ŒêPÚ_}œ~¾²<-€kºÚŸÎÊWn…ññæö—r$(/G@gÓ«élz{9ÜÏ?¦ó†K›¯¡[‘o£»{]‹íO#ZïhOêA‡F˜Z2² :¶eÕ#tôçè°õv7õ ~†MË5h-}ºº‚òœº–ií¼›W×Ç(—+n"– ’–C[,Œ/Rö¡|¾/È*‹À0`à8f{z„¥,D–¼!ò ‚hžµï,“„¥‡çí¹1zÄ€|Ë1ß7c®ÀÍñ si.Vào–bQ0«\F쩟‚+¤hBJp*ÅpOVLH $’DH¾$hS¾Hód‰y II‚(àXd,ø'’œJ’Q Â%§¤L’øe”Ïåo2JÂ:B«Á ‰¹ZBºíA”ã0çB…æpÿxš–î¹Í°1|z.TœG cŒ±"·¥úds°Dâ„€ßM9K@Dâsœ†õ2ý¥;úaÉKu;C‚¢5V3Œ>•!‡§hIñpÚÕô5¢$Bò¤U« (cH¨r¢]-%ÏUú 4\1Þ~Û<)–ˆ"¸X82 +CœIU3ÂqtBucü ñh¿¼å]‘%ÅŒ ²ùÊèŒy;ßËKdÙEQ¥ã]ƸlÆ‹‡ûò©2!¬íí.?úè“«2¥j]ø¨äæëÆ£¶¾ïÀL ŶÞa´×¥\­EQ¹þîyW£tàúq/d®U( À ¬’m#MWpG%M¸ÂJ•VõÝó;–Æ‘ºø·üì! +†´RˆÐÎyHÇG‚ì%#ã5£dó’Îmêÿ"ß¡QØdΔ+ç«:8‘Ûá©_³-wÐwä,øúým’%%éÃp•Švõ ´›…ª¹‡…X$H5… Jêºö£‡O%h« =/&¨w®Ó`c°!Rbþ/ïßèöpÉQ*âºM]ÝÙÜmpϯDž©ŽŸY‡T[t“^gpºB.s÷Q</RE• 3¥i¬¼Xšøkˆm*WXq6vKªú‰£çË¥¢Û_Û 2Pìý]W‹‘¡ë»fêÇÃ_{螯òÐ=çâk¼O½»=P§¯ê´gXºÆ¬"ó¾–ËÒ+XÎÃW[ñþŽdv«Ï¬úQ/€–é9 +z¶eïPê´ª­Mk ׃–gÚõßSlo1¯{a :žmT¶c¶½í¶nÏ•'¦38ÜÙV¢öRÂò íÛöpoŽZ,Nñßé â› ÷'©¶Zß7›s@Ójšž¯È)Ê©‚‚m¿ò¼>U|íú?ÌÕÌendstream endobj -1258 0 obj << +1252 0 obj << /Type /Page -/Contents 1259 0 R -/Resources 1257 0 R +/Contents 1253 0 R +/Resources 1251 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1237 0 R -/Annots [ 1263 0 R ] +/Parent 1250 0 R >> endobj -1263 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [154.2681 85.4256 203.5396 97.4853] -/Subtype /Link -/A << /S /GoTo /D (notify) >> +1254 0 obj << +/D [1252 0 R /XYZ 56.6929 794.5015 null] >> endobj -1260 0 obj << -/D [1258 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1261 0 obj << -/D [1258 0 R /XYZ 56.6929 679.1143 null] ->> endobj -1262 0 obj << -/D [1258 0 R /XYZ 56.6929 667.1591 null] +1251 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 1257 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F48 940 0 R /F39 885 0 R >> +/Length 1152 +/Filter /FlateDecode +>> +stream +xÚµXÛrÛ6}×WðÑê P\^&OŽ+»Î4N«ªOªFÆ"r¢4ý÷‚I¤EY$DƒÜƒ³g±‹°…̶<õmËõmÈfV¸!ëÞ¼»áê°ûÔ¿z;ý|M]ˇ¾Ck¶ªayy¶fÑüâê×Ëßg“é†.8ÌAooï~)GüòçêÃÝõíÍ_Ó˱k_Ìn?Ü•ÃÓÉõd:¹»šŒö6ö¤B8ap}ûÛ¤|º™^¾9/fïF“ÙÞ—º¿ÑܑϣùY‘qûÝAê{ÌúbþAû>±Ö#›QÈlJw#ñèÏÑ{ÀÚÛ´M?F=È<â¶h㚀˜è9[.ó¡C -œƒÐE*•.ŸþF •O"]†¿ç¾Z>®º6eÄOÕ+è3†­Ú …KëÅ»x³ÏM¶}hSß1O +©Sû¼áj 2¹Q!ÎS–u¾Î2ˆ"Õ ì»8&§“#Â%#JŠÌÛ6FÃIJOÍm·‹õ½bBdħ;&¸Î$w—gY'%¨ mÏfýCw>D?jõ¿z6Å +ÊÉ€Tʸßòl)Õ2‘ ,ÔªrÓäO•äÉfý‘«vò „H4WAÜe|ZI¶â +h±æè<~BnôKhˆ(îFã D' Wt˜‚0<é “3F~™ª~âÌÃÊÄ#ï>}ƒ¸™\q¹, +4ï9Í^ð¾äsÕb‘ižäÞWô]ÐVR­ƒ£¬— æƒ/|_{ªp'ÛjüP¬p¶ÕtY±Ä0éåéÞvÀÚÚÛ¦Æ×¤·È;•Êmë ’HíãÊìú·­23è»®Ó^ç‡òZÕÚEku,w2Ü…gc{í°Ú'¨ÚèD!¡®ß¾ÕÅô’µ†ö +²äC‚k•µ…ëYi Á»Èy%ºÄ…ØöÈÉ=ò¤¼}6ÊDj±Ú‚ˆÇÁvWªB™DY ¥öÄ©:¥ãBêû”`ìeiãRHmß?Ïò|Ò2ð’û’¢ý?- ×àI<;Ç$ˆ3 J¤ràß=«ƒ«çØÎØ@ à ñu¥@,ïA&¾ñýÑ?&®‰Ù`æùÓ2KyØA(M{qlÙYî(ÐAOû†+ïš‚þ“g:?½„}ó É}·ÁþJäÚ#f« äCŒÚôG"̆ú e*ÍòkfKuT[š¦)|XæXµ¨ož#c’âðí‹ ”ʸRE»Þ¬B+FŽƒ<öíÓÔk‘%eïãSÞnä%ºÇ~Ô Ÿ*ù(¢VŒN‡7sìÉô@k­òÒ*d Kƒ£&©³…x|eøPÇEÀ¬îî m7•”Áüz±å^íïd^|‹y¸âµMËæydAIhí‚’"zÄww¤rGmö”ùþºó˜úÿ;HÏÌendstream +endobj +1256 0 obj << +/Type /Page +/Contents 1257 0 R +/Resources 1255 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1250 0 R +>> endobj +1258 0 obj << +/D [1256 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1255 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1261 0 obj << +/Length 2305 +/Filter /FlateDecode +>> +stream +xÚ¥]sÛ¸ñÝ¿Bo¥gB„?1yòåœÔמÓ:¾éC’I)’8¡H…ã(½ûïÝÅ‚)ÓŽâØ\.»‹ýÅüóE±H +¹ˆeÀB‡‹l{æ-Ö°öúŒ[·'rÇT¿Üž=åÇ Éd$¢ÅíjÄ+a^’ðÅmþΉ˜`çÀÁs^¾¹~uõú›‹ó8pn¯Þ\Ÿ»"ôœWWÿ¼$èõÍÅï¿_Üœ»< ¹óòïÿº½¼¡¥ÈòøåêúWÂHz<ÀôæòÕåÍåõËËó·¿]ÞgŸ—{>äóÙ»Þ"‡cÿvæ1_&áâ^<Æ¥‹íYú, |¿Ç”goÏþ=0­š­³öã~$f ð‘E°ŠCÉ"_øÆ€ïÎÝÈóœmQ¹ÒÍÞÕÅV®ê¶KÕü‚ðÀ ÕåœÉ0éןe±«MP±ûˆ/ó{øxOšç….ê*-ÝUSoÝ´ÓZÙ«öcÝ|¬ê“åóÊÒl£žÊ¬I«xäêK‘Y&»To>VioN‡F5Z¸mñÍnCèc»SÙ¸Fgw›îv*wáj[Õìÿ4j¥š˜¬ËÎjóÞ =‚.èñ§}ƒ¿ âúÍõå°…Ÿpv•W­Ûå»ÑÑ)žN Æ'nmêZƒ×JµN1ܺ*÷´Òëõ5+»Ü²ýŸåN-‹ÖFï_½”SÝü¹S;¬×Oµ¼hÓe©Ü´\×M¡7[ë\À´¨&š$/&‡:F[Ýÿ:%k(@U…*üÀ ø “¬TiUTk·¨´j¾¤åüžþ|Âde¡*ݺ;Õ¸Æ7§–³ûÉûTNGÇjÁ«\¼ªHçCîiõUÿÙ¤w˜T'óSÛÞ»-X¸W⇪mÏêJ§™>mÿŒøou¥Ú›ÙÀ?p$ÌF¾Zºv¤œï;­Ò-AÝŽžë²^bú#|8¼èŸ³TvC«r‚–{zâǼÝvÛ‘Àmj‰±)¦•cJ=A™"Ç„!ª-¦ŽÁšêG‘“â#v жë®Iɺ¸†˜RQ(«!õŽ'Ž¢¨¢!&f %,‘’ß²1€^rlÙgÀ[†àe’5.Ë:ûDà]R(ˆUÂ-ÁàZFÃ#¢Ð­Y/bI(å4ŸrµJ»ÒÝ]Q–wÁÝÅîÍ͜ŜG Ÿ,Jbÿ9—ˆÜ1•s'fëgðÊ(U4*Ó5”ß#É2fQ$Kî‰f$ýÀ=±â‰©hÌסsW7Ÿ µÑ (dâê'wP/ƒ­WôÔý[¢áöWˆú‹Ê’V0š¤Ë¶.;miqºÄ’‡.Åè˜×ý($E©õ'‡\÷¢i¨“ý€Î ÓOª"TÚÒ“ÎRß/=QM+Ú$ B‡ãq9çæH’[!E9È´W– ë°­[M1 Ï.ÔÞuv‰Õö/¡§ØšQâLnDG—³¦«fr îapñ6Ǩ٠+p‹)/qN„fÏé'ÂÔ$Hçè&̪Z€CK§Q9d³H<ò&. Ñ4Ë  mcìÙÂÔM ýïŒ!üȇ»¡×q6g&ã8²{F@Ûòã(œ† E\ÀÕòᬠ¦ÞÁݦ0%@»Iô!Oë`‹Z£±p¸aö3#€Mfùmê®Ìiqi÷™škCÍ4tL§ •ðC†Þw +Õ˜êáB5P¡ÔOjï>X¬8YKï‰f¤OŠ•°úSñÿÙ˜Ôæp׃yFM*Xžtò=¤G‘Ñb·ËSSv65 Z•uCoã4‚µÏ¨‘s¹wÏa€ºµD`3îºeÙËÃI…ÎC%GžjŠ/¤Žh@E@$‡ €…¥¥\Õ]…iåÒ)VD—º¬¬J8- ©Þ˜ˆ½zÀa§4£òž*{ º/Ü—ã¸åPª$4ã‰tšó|?9Œ.¾¯‡öQZÍÕ5)™ˆe` Û•¦Tx€M—ˆ2ýžô‘×B˜VOã°ÕÞ"Ÿ¨ïÊSZ=;J‹ dâ0#OMz¤· u—E\ðiÛQ}]7éÛL W&H’áãfâHì%ǩӼ·j—6©žBü€…2”–t¤I1Í ž•R¹Ê_  +ÂÌ’»êªŒ>½z?ÞùÚ4N¢´ÕÙ‡P8½Ï§¹CÇdP¥„™'£ä;)1¢z$%z*Ó±˜¯Û6ÝnÖÀ©+]À•æ8=B0± ÂÇõ¨f™”õH@G† +9ÑÄT.=*ÒÆÂø–Q ê38ºˆš3‚ú°Ÿš³mME¿º"—ÌÔaÄÀÙ[‚HÈçNµÐÁÉiº0LøS§™ë·%VÀž×oߺ·o¯^Ú”®³ºÄÛ”ÎËC .íf{…ä?T³¤2^·´Òc¤+]…¹5\û’%}@4Ý:Éc“Í|O(ìõÇ<è,Gj`}nŠ*+vær Ö̸BR9˜‘ÙPå³Ï]Ñ·J¤ÒâÛ­÷Oî`í ¿¥ÓIÝñ½TøM©,÷Èä£çJgÏ?5Ë'.ç +*\˜ £¤‰Ø¹î%¸~õ—€F¶À×mf +Cˆu3 qþßê½Õ3™|…HX¾›Wíó™Óô_YìMÙX™Ù¤÷OÇ,ö’¾£`sšÄ¹=—©I3hÓ~²ØŽ®O} ?›)®A¢0îk«©êá7¢?ÞaH˶žp_gý.£þ˜4S`¼á ÓOÿfuøA›G’ˆùJ%bðXL¬Rx® º_¤í[÷Uÿ?ž> endobj +1262 0 obj << +/D [1260 0 R /XYZ 56.6929 794.5015 null] +>> endobj +350 0 obj << +/D [1260 0 R /XYZ 56.6929 418.3076 null] +>> endobj +1263 0 obj << +/D [1260 0 R /XYZ 56.6929 386.0953 null] +>> endobj +1259 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F48 950 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1266 0 obj << -/Length 3662 +/Length 3835 /Filter /FlateDecode >> stream -xÚ­ksÛ6ò»…¾=2x’àܧ4qrî\œ;ÇéMÛ4EÙœP¢"RQ}¿þv±Å—¤ôÚñŒ‚Ë}a±/ˆ/üñ…Ñ“©Z$©Š4ãz‘¯¯Øâ Þ}¸â&ô@aꇇ«×ïe²H£4ñâaÕÃe"f _<, ÞþãÍ¿nî¯C¡YGסŽYðÃíÝ;ZIixûéîý퇟îß\'*x¸ýtGË÷7ïoîoîÞÞ\‡Ühß ‡áÄïoÿyC³÷o>~|sýÛÃW7,}y9“(È׫_~c‹%ˆýã‹djôâ,âi*ë+¥e¤•”~¥ºú|õïaï­ýtNZšH‘Ì(PÈž9ƒ¹Š‰N£XÂ+Tàí -exý^™d™$‰;B¬³¦-va½©^t€4ÖQ¢¥r°¯®C)Ó`S·å¯Œ‰¢g!‚lwÍMPà,"»Ü›–ÖVõŽ–ˆ-þ·Þ nˆPólrÔ²ažxñû¶*ó²áR%‘,ù\zÞDÇ/ÚQ/BÉT ¨žó(ÕZX¬M±ûVì²Ï ~ŠÏU r-i¾oÊÍ“c’÷Å‘ t™hÇeV5uˆ<®æô®ÒHhå%-IÎNhIE‰ê 7õ 2ƒÕƒl¤jÂçNMø€jŠH+‚ÅQÂ(%d¬,ª‡çbFPÁ¢XpÕqtBDÉŒy®êm[Ö3ÁJ^h‚:¢ÙcAc³-rbw‰ :(Ý7í,+ìW$ÜëMn†¡#-¥ç¤i³¶Xƒà (%EGáð\æÏ4ͳÆñS¶4Ö`»rimí$7¡P2b*Y‰Žê7éiuÅ ìó˜E0 %âà¶¥õ¾ZÒ”ÌZcUg1yÑ4Ùî…Ûš^·ûÝÆ}²Â_¹×Ï¥ãÈï —îméæÙ¾±vïš*ûV4rk4Äô@Ú|—5ÏÑij²ˆipúq2òD$q@aŠ!Ÿ‰$ÔÑ Ã¶›:Sç°/\3sž|5CpÜ”‰8ú³‡×€zRox/ ½ã¡;×¶ÄMc¥¡Iþ\ä_pšZ›£—Ùº8z+X@ Ʊƒ¸ûLãý}S´ôuö”•›¦~þô†&ïÞ|¼‰Ü×õnU.@1D!†›œ$øÖ»O·ïÿCó5ßSAÖ¶`$9ºX!„$»„â&ÄL,4ý•iÖ­º¿ýp{Kœž3‡¼l‡Äšýv[“¹"þšèå5PæAf•„ôéè‚ÂCï7­ý€R@ÆxLìH Ê$ØWm¹†IË.ÄAb^›éàs½. hÐñB\z®Å7‚p+}iM-Ë€º*5ZàÑJv$;ÝÀÄë¿Ýðs¹\›¡,¢ò*1(>ºÓ§ý.ó^(B›%½¶È´ˆ¬¥Wäûpí¥ÞÓ’w;°vÈì>&Þ†’z`¹OÛn@4mYU´và09Û™cŸ,ÉÅ«Öű̢À…g¼†ç`¥­`}h{&0kÄ3qÒ?éT‚¹Ëø¼êCöO -µ+òý®AG;öM²tgIwP3´¾I -Èm؈ø‰,QŸõM(¥R˜^ÞÅ„³TX³NyðÎjž¿î |`J9,4mCP´âtà0ÁÞlžv). £Od5H©…p¸miÙ,.ÝH†/<’C½ûBÎKcVž˜¡}yæJš 4LZ&A¼æ`9À5ò“ʉÆ9ÇC/R›ÐÚ±=Ûðêná”Æäe')Ì—µµvxí?|PêlùBo¾lêÈ+Ǫs4\”<]›Ó£0Ž[—ÀsÖ_^A†“ ›-8Œ"¢Íz m‚e±ÊàÌÓCÙÌ&öI$uòLËÒyZGÄù#ΣhÛù„Ûp<ŽÒ¡ØõvA˜ùDYC„Ôõ—ý¶qÙç¢ðÁ§©gËHŽŒðiûªhóçð©ÚÏ!4*îí={„‚âtb"2Ê\ -B=¨3AÈCÙ3²Ê…d&l_¶Ÿ&É -?‘œ'ßAÍМop½Rèö‡C²ÄU vVÏ8‘êÞ˜éK¹sjR¯~òsˆÐ–-žJAÆéíÈ´#e#8Æ£óçµ— }šUµgúP¶ÏÄ åh6ü–üqÄU’O™í—ئxÓýæ­Ìúso|>s9:\Ìkf®N¡vï -3MÑ9Üñî»î’ÉÐéwô¾¤±­<3ßû‚ã—ð(f±>‹¾c€ËMýCT¡ç.”&Žt"Ò¾ÑušE!u •,”RðAJ'ÿ®§+NÝ´HËîä~ºc<ÀÜLTH¥Ðf¡‹ wÄ_~TšJ‚êÍ­´G-Ø…×·k±xWƒL‹¾XsØGmåŠÅ`ADÃ$2Ú‘XµKÅ_® -÷P®·•í£ßµUa–Nv_¥Ø‹å¢¯ß?·eÒÊ”ÉExì}þ9ƒ‚Ä+—pÀµðsîÈÇ PL0ÎzÇ -õ >#,—á¶®«‰ ÈÐÊtÑG;õjJû äÁbä¨#g¼ëÈÐy§µÇ¦®Šv.²€Ò”ŽÍ°—8i¢gÕ!{iºZªÎ¡ds>q‡éí;·ÖË!ðP5'£–„íÑüRk§uf_<”ïê…Øƒò®Ì›iÜJ#ÁŒ8Ï@5ÃÁ0naS:ÕCNP1ò;²Ü~ãšùê>Õ½bGwÅŽ‚нª( B/¶Ív`Áey)&…4ºúGSÃp`ÿd¿©(­A4¾­šÛÆŽ]Ã2ÀúÄåj³à@'Žæ {²½[,h€œ ¿mÇÕ®Üþüþ~ø:£a›íÀˆ÷U¶#„àxàJx´7žæx—ÄñÚÑ¡õ]f0E8šÜB¹Ya“ýhju¯]9ã`Ï’ÔŸ°í®þV.6>\@Шxtïæz¢£ý…XU–Àr-‘É…ƒÕÁ‡ý¦f=Å;s¸¸1CÂ/ƒD·~boè\½ôhRÙ˜HcH4có½Zéà/14Á;ÑŠŠä$7Wèøy•x  Lpw7p®™Vê‚»éAq7j΂‡©68)åyêÔ ùá]"G'ß§ßí~{¬±›|WöÎJ½š9‡P%1¡Ìÿs§gÌüÄ;ç¬ÌÃ_yŠ÷{Ï^Œo¯fŸ‡ºÄÆÛY[ãP.&Xµµ>Ôi[ë ¨/l¯!NØš‰¸†€t–z5C~hk2âŠÉÿ5¦6bljJ–ž65† —ÊyÎÔ<ü‰§x¿ÛÔâˆ'â¶wP—ؘ`;oj~žo Å#ÐCs@H®ÝYæTeMØl³¼˜8(­â³NâãvC¿€¥ƒ½Ä Ûº8§GÚ\;µ­\xÓfîÇ’lsÆýèÞ­²¼¬ÊÖÝ–C•UgKw;“Ð ,RM3* i»™È - ?ÝÝþìØ}Rm=wåánÑRt?û‚§§bƒw&d ®“Ë™ïh´¢ÁøîÓgš¬íÝšàÖ{Šƒô5vÉq渄٩ýç&Ssiÿå`ðÓ©ˆ™Dôöß‹³ôò¼v"èSl$ò¡®†½ÈÅnN´Bõ×ÊaÍV HÚ´ýÎjSªr3û«¾A«/Ï‹-ìô+Ű…£¹fcù´©ÝåøI/jÒHH.Ï{ÑÐi/êìÅØrY"?Y®võ:Ìöíó«î®nðÊ^fN -ƒq“‰³ìu@Sþ†EŒ€úkŸAß -JÕñw}Òví6äk¼ƒJÝE?¾y,ž³o¥­Sû«;f7‚€õ]^QÉh€®¶þòûTü= ö‡Jpwed]¾ÀNn‰6AP¶„ÓgûË#ûA§EzƒýD,^ci{; VuUÕ‡û[úÑ]Î9œwîgJ°]àËMú‰µÔþ.zf{Xw¡ó§~}ümºJ"iÌ™4ƈ4ñL¡$*sÞýN{ÊúÿR]òendstream +xÚµZÝsÛ¸÷_á·ÊÓˆ!‚Ó'_ìä|½8i¬›¶sw”HYœH¤"RvÜ¿¾»ØR”|Ó›&“\,±Àb?~ H\†ðW\¦:U]&YèPèËÅæ"¼|„¾‚y¦–iêsý0»xû^%—YÅ2¾œ-½±Ò LSq9+~¼ûñúóìöËÕTêpWS‡“îîoˆ’Ñãݧû÷w~ùr}•D“Ùݧ{"¹}ûåöþÝíÕT¤ZÀ÷’G8ñÁû»Ÿo©õáËõÇ×_®~Ÿýtq;skñ×+B… ùvñëïáeËþé" T–êËgx ‘eòrsièH)KY_<\üà èõšOÇôé4Ð2Š/§* +ÒÆÕr„´6MtÄJ*§e)Æ´l¹PËÝ×òeZ4›¼ª‡+‘ +„—þ¨G²-ÓˆlåÉQ%Âg«òjªt:á ˜v¾Ý^‰IYeA„®á§å®óMÙR³Yâ3™äë5ÚU¾»éÄ~ ËcÖDz.wyGÉä¹êV¸â’””°a «33üûí¿™Ë_ŽL!“Œ™ðÏUi—€ŸÀž¥I„QZA¦µ4Ü‹uUÖØeOhªßöeÛµHÑôé`N‰"¦¯L) Â$¶Lå÷Å*¯Ë7`Óa<©XÞ&¡F³#qŽP7ÌÒnËEµ|¡n£r¤e[9½~ØâYÒXñt~%„@½ÈLLî–DÞÒ-¬þ )H„!˜w÷Dûœ%,[f›áéºzÛœ™m¦ŽçÊX´æ%i)òU)bˆ(¬&»qòÂ+_·ù®Q³=G©Nx€¿ŽÈ€V¦,ÃÀ¿£Ál­¢ƒ%«>Á*wÏU[²–T"ÎŒ„§%ewB)Ö’Š]=-i :XKÐ:¡%J뻼†ZVåwjÕcF;¢¡0‚v¦Ïj\#ûß4¤ãlrWÓä7MÛÑÊy[¶oȳqùÇN4 "CõŒŽ—A¬…]I»jökФL3T<9&!¡-wO%8$•¿´D²A ùPúb–×CR^[c·›^릞–ß«¶3†‰Œí~~*›¬«¯%†^oA¿IEr¡ÁÏÀpâ, RG${É KÓt*ò.Ÿç­ý¬a8EÈZUÝv»«t²_P¡á1ülu¢™BK³xSvu±`·„Yóq°"u,½šÄK„Î Ê5Ѱ:lQ.óýºsf7‚ 1¦ˆÌb[Tn1Ü`¥RÀŽ€éu %ŸÉŸÆnÄ©?¤1‡ÞìT$‰šslÖƒQ…{)ávÊKT@ÙðJŒñ¹Îx‰åB‰›rÓvyP¯Z´§Ü%Ž ŠgÙùY8®‘iô&†â;²?ÎW¡ç0ø†ƒÏÎv[‡ñˆÂËq>vUgr ´aq˜6L{ßæüÝaÁ¥Õ¶Š8Az@¢ƒ„’QÀƒtÂgÈ€k$}D¥õÑÉ-eÙøõ´…¨d”õbÝP=è•E³wõ·=( =B GI¿B=®3!ÔrU.ö;¬OÒHcâó3p\#SèÅ `G ¦@éVk?Ýj¶jxvWbb9œÍjëZ2.´¢öú¿íñø|W•®#ï¨å‚è è^ënýB$®÷HAD2È–b#B¦}{ ]“}»ÙŒ7ùyíŠ +è(¶)øsÝFŸ êÄ?ü¿!Ý´ ÎÍ)d»Sß“†­b¸¬™=a“qˆÆ7È’ 69;S³¸Ú!„òDQ¶‹]5÷òÃÀ\¥†áC‘AI…Ž N¥ÎÝã%5¾x–ëø§þǦ{<.ÎÿV\5µ½hŽ(CªZØ? EoFGä¸^™Çñh烤8K_©@}®3aÃrxÖÐW/T`M¤Óø¼TÇ5"V NQS%VO.G‹tòËÍç·³wŸéÅÌZ€ñ÷›9[C@ã%RÄ‚-±šc1$±í–Õ“I^H2ˆ>­ G½¹ O_wÍ¢Y³¬]îN‹ˆÔ+Zãà‹ñÀò½<’°u§­0#)éÎð’I³µ–N, ¯5(ñb‘Óñ}7öðIŸwnŽ—ßtê÷7x‹…Áow©‘Ø^Ò'ö™+&"¨í<ͺÂ~Ücðê'R{^{¸±I~Ñl6ûºZÐa´Íòýð¸næ9 ª?iäRÇ`)â•Ôès6rÇu¸½œåSµ8NŒ°[B¨ø¼xÇ5"¿÷Ò Ì¢¬?Ý‹#Ú“[ð{³¤'D`2Åí P¿øœ3#Õ††b9ܘ~y&p;¬jé¹ÝU›|W­™\—eaGå+|³A·ïð¥€ÌÒÁ­s³Å[0fsÙ*ä¤Ý/Vè<`-=ÍM‰i;Õmn‚kKwŸì‘ðn/6ðe¿-Œa›±%3ÿŠŸÝQgìT†sË+{y?í´t7&X›&_c °A‡&ˆ O€"èÝ]©˜·çUe $Š:xmƒoþFrþÔ|’Eâ+žˆ}æv +(5ªBOžˆoûjG!l gdÉìÃPý/óŠ[™dbï–¼Sl¯p÷°wŽÅƒe-¿¯ò}Û™ªU%|$—ØÐaìÄ–!À{ˆ Þ¦®÷,iê¨( "<æãØŸ·ü«ƒ¨“Qd‘ïY¬ÐAE$‡ªù 3ÚWeVQÖÿQŠ¡PeTs›–»¢G=„™Í Ã’]b®üj‹;ƒe$a µ-b\†i]þÕÔnÐ,M:Z@¡÷bOF`Ø*Ëð,+އµYÕU6ð.šwéqO–ED¾nÄÈÞõ/âL»ËwÝ~ËѼ²y¤ÌŸ6‡»[ÍG¹8À~ÞâO›jœ˜Pè麞cîpÏ&Ÿëtp\éìÊe¹Û•Åô-ñ( „ˆ Óóò×ÈúY@)Dÿþ è8[]&s—½j²Æ_}ðo÷²å+`´ðkb ŸŽÈÉ5üacª=ͲWËjRnðܪ°Dï´a0]ä•@¤—ÈÃ\ò¢àx +a7ÈÔðh ÍÈZWëh[äö §4×ÎÚ-D¶’‹öÙ©Š¼@,Þ`g]Z¥“8d m™zC‡÷ŸîoQ=§ÍLšK“WNè}®3ff¹ŒÏ7M¿.ŸMÍõìÐØ(›“$=? Ç52ž±¥ +ÂH&úó˜]!jØaÈ—+*…p±½fcX”*ü€nrnŠ›ÐŸ¸!V<Èìç›–ØQÅ]³%òº|*×ü¹ù©NËÙ3åX_P²²÷8 ?B ìÉäø!ˆÌ­Mm}s+¿/Öû‚÷}&°IPÂÖ…‚øñ@å?`Uò‚;×ò;¸âѱÁœ{7yQö{¼XÝ<—‡ØaÏ Ÿ=8Mò9©ZË$jòÀØé0É‘dNReß}p9RxË‘ˆ¶‹Ðа·¥Žœ^Am%gÃÞùxÓeè_Çèâ0Oªà£iR ä'œïÕÅý¿n>}¼¾»?­ïáÍSUØtÂqäÝýõÇÛᡨÚEóTö²Mi®ñÑøOJl¬ƒhü'ð÷åOÿöûðÃx>*Må‰s‚Ê™%vR¨Â(Î\+©LF¦þ_˜ Ìuendstream endobj 1265 0 obj << /Type /Page /Contents 1266 0 R /Resources 1264 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1273 0 R -/Annots [ 1268 0 R 1269 0 R 1270 0 R 1271 0 R 1272 0 R ] +/Parent 1250 0 R +/Annots [ 1268 0 R ] >> endobj 1268 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.9497 292.4924 172.6404 301.7078] +/Rect [250.9056 343.4991 314.5963 352.9087] /Subtype /Link /A << /S /GoTo /D (statsfile) >> >> endobj -1269 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [293.8042 246.568 355.0043 258.6276] -/Subtype /Link -/A << /S /GoTo /D (server_statement_definition_and_usage) >> ->> endobj -1270 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [395.8905 246.568 444.6373 258.6276] -/Subtype /Link -/A << /S /GoTo /D (incremental_zone_transfers) >> ->> endobj -1271 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [309.3157 215.2488 370.5157 227.3084] -/Subtype /Link -/A << /S /GoTo /D (server_statement_definition_and_usage) >> ->> endobj -1272 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [305.9683 183.9296 367.1684 195.9892] -/Subtype /Link -/A << /S /GoTo /D (server_statement_definition_and_usage) >> ->> endobj 1267 0 obj << /D [1265 0 R /XYZ 85.0394 794.5015 null] >> endobj 1264 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F48 940 0 R /F21 702 0 R /F62 1050 0 R /F39 885 0 R /F14 729 0 R >> -/XObject << /Im2 1039 0 R >> +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj +1272 0 obj << +/Length 3458 +/Filter /FlateDecode +>> +stream +xÚ¥]sÛ6òÝ¿Âs/•g" Aœ>¹±“K¯qîlçz¶´YœP¤*Rv|7÷ßo»€@‰R’¹ñŒ ,‹Åb±_<ð'ÏÓ,ÊŠ¸8Ï ¥B¦ç³Õ™8„±·g’q¦ibýxöý›$?/¢"‹³óûE@KGBky~?ÿm’EqtÄäõ‡›7ïÞ~¼½¼ÈÕäþ݇›‹iœŠÉ›w?_Sëííåû÷—·S©S9yý×Ë¿ß_ßÒPÆ4~|wsE‚>GˆÞ^¿¹¾½¾y}}ñÇýOg×÷~/á~¥Hp#žýö‡8ŸÃ¶:QRèôü:"’EŸ¯ÎTšD©J©ÏîÎþá £vê¨ü¤ˆâ$‹G'µŒÒ¢HÏ󴈲†P€ïÓ¶^âGNæ¦6e_µ Û¦~¡Ö¿ÛÆP«3›'³!ü²îÚÚÄÄd¶¬ê9áífW=;iZ”õsùÂÖm×U5Oé[Ç\o6« +(ØaïS)£"Mc»‘ç¥é—ÈVœ[⬘”M÷ì@³v…ì!x±¹zÒ®hfQ#Ü;¢ÑÞq„¸·°M8 ¼G‡!§ÅäîÃ% ßÜ1C #]ÝÜýíú×± X¦Ì¬µß9²šd“’ ØÉ'åÚ|&0³°ñYv5œAýUÙŸÍ#õhJ·n›Ž ÷˲§±YÛôeÕtn%_ÇJð®î¨_¹y„]öf>Ü)]ÚÑÒ„˜‚vp&)ñ,\h:á&ñäööîÝ[‚r…“½Ì°c[æs‰ºÃôz†v†«,ÍË®zôs,‚r9r¢¬ô‚Ô&‘•6¡´žÜ£!¨ÜöËvSõ/„Ù™ß>èØ;‚8t˲ÛÂûÖMbb¸ Ø›@̇tÌS57ÍÌ8$u¼Ó2uøíú 9©ìÜ”lTêL]UW8øB°vAß¼!’5MÖÂâX»fìxJÇ _o»6 ß:6ÚóÈSÒ‘”‚DrW­ªºÜXó¯”c›À±e–¸AȬl¨Qn*‡œôÌjm5\%p2s7ïw‘Ц¥öÁU¶ôzú’žáäre`–$pÕ †UhÂG„ÃVs +HÛ"“?·fÃxýËzOxV¯°qyóë…”r²'s -“‰Ycuuÿ_ñ04¾(âÉ?=P[àÇ;üÏkZ—ÀØï?Þ]|-”%Ó½_Ú=J]uÌ“ƒ “#ׯ|^–ÛÕÒJáû7Jñ '"YJ‘F»Æ½ÁLˆÉ,9•G:ùžlÛ~ºƔ䀓ÌçY½GÁ~þ27ù›õ“on;ß\m;³]¹î°+OG—¦ÁA@'£\Ê ¾E¤e‘ ÀibQü%GX…KΫ®„@gZÖè–«nŸ©âHe"=̓Ça" %l\)©‡\\³(Û$“nmfÕïBÄÖñÁ/wׯi0`ØŽÙ¿VÑáÁÔíó—(â}Fýƒˆüý¶î«)N–FZ߃ÓY׆´l U™ERAÜ,Nˆs?Ö¸o7¥ë!NY™¦ç^†¦,}ûŒÒºÄÞ€xc±j;6~o3¶,ÞÒ?8bëu]±¹S2•çd7ú´’…XÇ•ÌcY©4ÄÓºm?•„*–¨(…>ÍÇaa b ä…”C~!C«bp:ý«‘ƒTiT $޲¼Œ"RqîŽqMþ#œŽÖ¡3‚ÆSYWó²·Ñ*tŸA/¨U2Ge 1HS’Í–“d휉´;¬œR+XXMáœf§‰‹ðm{$>M覤îV o×Ô ¿ŸO|Ì '½ÝX¸ +ù&¾‚HfC_ww³æíª¬˜Ðð.ÂtkGœ¦ÏtæÆ¬Mלä¨Bùûô'—C/³‚' ÇÊÕ.Eò+6ífUÖÔö¦ø<}¢¶´  ÔfÑÈÓød8‡Û6•è ¸+3ç‰N4‘è§äÞÎZ6³¥àEη:¨³²µAÖ±MyîꌖG:ÆwÈ%¡\‘ï&ØPaŽ-‰²5<º]‡Kgœ ˆœsœnøb6âÃY˜f„q +o ]‘T&0ç_â:ót»`³¹W[lcXÓQ&’Êö^òˆ›w\NóÖt66<ªÅ©î€DLÑ0¼%_Žœ)EÜ™ïþµà‰ÎaÍ/«Ù’šÈ.µ¬ ákMŽ”L‚ÂßÃnÍyàØi 'ß1_l8›S k/²Ž£"×ãÕ¥ØT›+ XŠ 3%HØuç‘ÒV1› ƒ£KS͸x×ç#“$ʵ”ŒÅñvE6l•³™Y£@r—‹w4`«Z¸ê„Ô¼„†÷ÂÜÑMÇ"‰À—9.Û±M³à7mõY‹EÖÖ"cBÈ2*’1Ädû’s›Œ#!ë§Sб(%…¡¹é ’»* ¢—ˆÊØ1“M´$­è(T\_AøÐÍïa4 ³mæ»fևǡ´?ú5 S4œ‡rM±0ëåÚnÆYé,Ußÿ¤î'Mà­„áæ,ÈÌKMe^@œAúƒ:)eê‹éN_L¥ú±mkSrvü³·#†/Ö2Šã$;møB¬ã†ÏcY±oûå´ù̇¶oðâ #1yzy5²þ0n•‘` 1y¢Š¯0zw“’XòMBýäØã0†tÛYˆËË1º:J3oDœw¯œŸuUt¦´§Å¨ž˜e®å23hžL3 Øë]ÙŸV£ÀI¤r½—F“M×jàn÷ ÷¸Ò –¢$ÍœBüÎ7Uc€¹(!ÄŽæöÄ.Á¾ç:;ނýà¤m¼¦R¨e†>³eÙ<Z2(AÿAK[F3aÿ¥Ý2 oœ ³íÈ„¡'¬‘| +H™”ØóH­«Í]ÙçÌÛEÿÌä^ˆVÁ ³äœ³1û‘É.|éýÀˆÔðUHëäÔõh€Ž5´øÂ=°NÜs‡eíA70>m›©ù\õ‡I*šÛBæÁc01¬ƒØz‰rÁ50,Á®Ù[a&OÎØ@ÅC»CM(¨Ý-5MÃ5WöeWòqx¶fÕR­QBòR~r‹3uƒ-=HZˆj#ü„Œ‡*Åï•'µ|­÷êá~(„JwOn¶m6ÀÖj•µêƒÔ`± —:­!Öq}ðXÖ™fª®¯f‡%10‚™*ŠÓË{¬‘õª'Q–€D ü‚O¾*ù)òƒ'k ºo¶ïŽ›Kž‚A‡=ÿBíE!0øð2F +é"s1À@S&7ÄÏ+wum°Wˆò7¥ØÈxgd«Q# !A¥q¬‡áÛ¸±U‘R>îÝ6µéX¾›®ÂÇ—©}·÷"2¬Aì4§íjåõµ®ü[†»šœl féžbª]Rw¸=pQnþbÿãÚ¯  Ù¬aˆuBû•1Ëû½eu ™ÈO/ëF– wXÈl‡.;ëÀ%ÂÖ·¥Jô¨‡$ WŒ»_X {#îh̾©áV½¬#Í~„Ë~²s½ž·Ö²ºÉŒ»taaÓ;aFÞ½s¤ Œ‚F‡37VË(} ¢Cf/t"Ó$MQ ?a¼¤c§¥G0hØ*M +)­¸}\ö4àæãû1~Å¢pÑç@|ôX5pçqCˆ<£á 런Ţ7Ž]Ùr›W–ü‚#›~,¯1Œ3ëí#±ÂDŠ/+1 [–/¿µ"Ä>ŒYt[Î’)>´Î` ×|¤{–ÌÃ(¾ÇHÐèZ‡KÑŠêUHØV½ ±´6¦iŸü`µrl/Ä—öîÇ\fié+ê¶vAl¤_XÕõJ¼4å¦õœ:Jc–7‰tªÜÝ`3O–íÚ,¶÷Bw¾Ý°çw5iË7f°Oëã!ÀdÞÝoä¤Û®×ìÏ;ãbîBCÌ'CýäwÆàñØ›PŸ´>'Aå­@ùÁãÞÑØ¹cv5Î “Ìõׇæ\²‰ó’©$> Þ¦G²‡® ÿÖãŒä~%Ž´*\bì#ŸBs,æ€D\Ðï ð»ç¡5¹¶^#¬¤âÇÄ-òT™çNâ4’B§‚ŒnJ'>:·4BBøLäOV¯ø·Ì«s‡À>»CÜHOßö‰ Wib|?É0RõhÃï'¡=Öíƒ×ÿAý(ä*ÿŠóH2=<èØOç’4Âß»¸6áèÿþYÝî7‡*­ãq' ©m¤4a¦}¥£þýÝ!ëÿf ^‚endstream +endobj +1271 0 obj << +/Type /Page +/Contents 1272 0 R +/Resources 1270 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1250 0 R +>> endobj +1273 0 obj << +/D [1271 0 R /XYZ 56.6929 794.5015 null] +>> endobj +354 0 obj << +/D [1271 0 R /XYZ 56.6929 333.8409 null] +>> endobj +1070 0 obj << +/D [1271 0 R /XYZ 56.6929 308.7186 null] +>> endobj +1270 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F48 950 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1276 0 obj << +/Length 3312 +/Filter /FlateDecode +>> +stream +xÚÍ]sã¶ñÝ¿Bo•fŽ ñE—‹}u¦çkg:i’Z¢,6©ˆ”}î¯ï.° A‰’®éÍôÆãá +\»‹ýØ$?6Ñ*N„‘“ÌÈX%LM曫dòïÞ_1‰¼½ŸýöðýÕõCÇKÈ/K2òÇÕ/¿%“°ýýU £Õä~$13†O6WR‰XI!üÈúêÇ«º ƒ·öÓ1ù)¡c¥y6"@.²`™N2eâTÀ+àír ­¦íªpÀ¿ëŠ ²qÏÜ=6yÓ»éÍ,’Ìà‡ÕÁM±{ö˜/åzíG«…ƒê};˜ùîãÃíÍÏÞ͘ž싆pÚšpý<ý2ëü¹hp @c±QŠ[¦~MT²(–ù~ÝÈ`SS™LV–#e¦ÍªÞ¯‘ØêvW>=Yjñ‡’@ÀL™¯\í7u¾*æ¿»éÊêàkK™‘”­eª~.eõä†Ë–0÷Ûm½kG¹pbAœÎê;þ²‹!@‹Ù±Ú=Aúåò`iz<ÇB/«r]Ì2¯«ª˜·e]¹ß(*»(Œ= AÁP‚~Í¢u@½ô¸åMGÆ€gª°ê|åü†‡ zМóœhxìik×ëbAï^q Ðpj¸a±ÈKãŠUÝ¢^h l-M¡å —csÅBeÒ㬛::9Ÿ41W2#ÜØrq«H­A +Yl×½ñ”“à mÈJž9>X·¯0Rïܳi÷ýWoTd€ƒ9½"ì ÐNºæÌ«i>pÃOûuN_ýʹì)Ûo ¿vÏEÞˆA¸ ân‚hL—´æŠ49ͦ`Þ»²hÜ¿êjýê m±[Ö»ûDôBœÚ±‘-ãŒÇ~Ð>¬Š|×>y•x®g°âã­Ó2N¯ ŧmIÔºuJZ/_,J² \½vOôhh´Ý)ú^>TúPÓ×ÖĤݸ)+ë]¸ UžÐ(@£ sUÏhvôÕ=÷ ôÍÔ¡6gYÌSyÙ2 è,|™„&‹»ÍA¹nØ9n€7 UùSѼ]—†Ð®î”s +lD¹Î +, äkV/¨Æ™NÕ%)ì™`€‹*vÎJ¾fA2Ä—ñZ³Ì\ˆê'öYî+ äk¶H•d–^ôÿ‚Ç:¥ª²é?/¶³†ô¥äÖ·²þ 3Y (JÀIZÐS;ê­ üƒë‹¤'¨™>ßZ“¸´Ô¿©Û®ËÒg)}öÖ†‡Y{Ø ¦œx‰HËbÞží‚p(‘  öNyر^ÀÖê,Óa×bÐËñ(Í —ÖÀ›9Ñ»%¤(Ä:Ö\ßí°lc ÿ½ˆJ,9ŽÒ6&tÌR“_¼ÃY}˜ ³Tl¸ú-óQ³XË©ÆÒÃHØ-+ylTn©è‡·E…å½hÊÍ~·n«|O±êǦ^vßaø»»à˜´íë–ÞÞþðÓõý RÙŸgŒ1Ø€=jj¨@1Zâ ^ª +×ßÁ:¦ö5L0Ÿë¨‘uuzo“4fI’^ØÛëÌÞz,»·E;_EOë}q¼µ | +¹ÑÙµ;¬‘Å[+liÈ ®î:½<Õýb3ÇÑaS3N`˜ía@í)µð=Œ€A¨Ž’Y$TøBa÷Þ~3Ï÷Õ XƒZoYЫÓÔXÒÓ¼m‹Í¶ »MÚ­H½¦4‹µ0Cp´p£©`jê½æƒÑymŸØÀAìCãsQ.ª¿¼r}G€¨áм®šv7ÓÓýœ´Þxðí1ëÙp¶¼ÍÔt=eøa›ÅÆLó™[˜ºˆÇ:‡´WøÒµ„›rQ¸)Èæäsú ïó¾™`£“¡QC*Û“#ä&½à C¬ÓÓa¹-ûfaÓµ‰ê*jVûvQ¿T‡”pÍ\rsž”k„–A ³á€8$æîLGj‰ ÈEóMÑëÀ‹âSÙ6îÕb_¸1Ò°¢|vçðîÇÛ÷×÷Þ8bÒ½ªi¦EM+`˜ ±¬ª /Ó|¨yõJa“:°‡»²-šÃC *;éùc—” ÙÕÍgöäÐ=0§F²>Ë)ʉ… W$:–2»à”C¬3:æ±l‡..Ö‹h¾.‹ª=Jú DÆ‚³tX# ˜…"²+6$Î಴óÌ¿ä4XÎØ´EšÔÚž3Žo¶ëbDÛ~7ЗΠÂè-:N°(~Χªîü<Â"¯‡Ÿ<$Ôzú03 šN÷$Tñ Óòî¹¾{ßµ¶<«EAmÖ¢KÔÜop|#ÊÆQ.]š6²9*e¸LöˆŠÙã?'&4 Ÿ6ÛbnÏ$·/µo +oó]ÞÒ°Û—QëØ}e^ó}»ŠªO‹z“—cÁ•A‚}p 2N6ObÉ;»;w çcén9ç Y¦SlLXP!u²:Õ"“Rù^r ñ­È'’CÁJqÁñ‡X§²Ã²û^7mÔ´§5m9?6J f¤Syž€k„‚¡QÂV¤Y6$Áf@ŠÑѦŠùT —þR€ü½(¶äv³iÀƒEZÚSKüôÙ%¿"³Ã’ˆõGÐbh*Ÿlò9‘G’Ç gÙÁ™IÙ®ÈÛßùbià2ì@u”œÞm–Ätçw;À:³Û )E[iá?*?¹†vô˜7Ç92˜ºIåy2<Ò1†A@†¬èð©•ì3d€Ý˜è«˜‘ŒVÇ*KLÃ"ÁÙô¶uß[?Žå¹8%Mí¥e–[ÃÝU•a7¥ ÝSNPˆû‘»G»Ë«TüvG꺦sW¦8R$4ÂR"¨ªÍ£rúÀm5wñµÃ¦¬0øO—<à5‘žŽÁŠK #“–Gˆ+Ä ÷ð[I åîáiu„ÂjL¦)Û„_Û*}°(šýv9veâµÞû4Õk±¿âAÇWt cß>Õ}ßàˆ¿ArÔoþ¤mߌž¥§&‡â»Û^_)œÚŽœËAÞžïžL~Ø¥äË,c’ ~6Ä:my–µ¼²*7ù:ÚQÅqìi3 ‚òy:¬†85æƒ"n—#Â3sêô3ººÊüÅ¥|ÐèØÎ7&T:¨±‡BþV^Ö_ÓÂ/èŒAUç€ãÊðœ"Óå{:Ñ7Â~ÂëT¹]Õ”ãÌê»zL°aá(¸/ó…cãÆ‰Aa£…ŸÄ‘å†ýÝŠ²¯…»™RÄOÖÆÐÓ¬‹'Û±ª/˜þ¶Õ®àCY¹{cg‹ÒMþÚ…ºáux«Š.²äÕ¼Þ—êoo¹M ?s±\({‰’_ æ`P/úó„3f`1;eÍX(!Gs[AG: ÃÕy:¬ +̦i,2¡‡$ÐŽ™ Ÿ°‹&õ± +†JzE® íP¬®ånàè”ýZ,Ê_Œêð}'Eubp˜ïîÞ~¸vÆU’äXM…:vlp\8ê8Ÿ>—µëê¹a«QÜßå‚×täx[ ì,§9¬ t)¼¯CT/ù`¡|ý’¿6~Ž]éÊ0|STËšzJÍÁª=KÉ!/zºï2ÇǺ] Ó1­a(¸y‡Ú5m¯ ÙrNÑj‹—ÏšøÔÍ[¡b¼.;¢EÉäâ×çÞÊí¯,C‰(´>q/B$¸É> endobj 1277 0 obj << -/Length 3827 -/Filter /FlateDecode ->> -stream -xÚ¥]sÛ6òÝ¿Âo'ÏT,ðóÑIž;mšsœéÍ´} %Èâ…"U‘´âþúÛ/€¤D;—9ûAÀb,û ªËþÕeœI®óË4‚8Tñåjw^>ÂØJp–i9Æzsñý;“^æAžèäò~3Z+ Â,S—÷ëßI ƒ+X!\¼ýõý»Û?Ý]_¥Ñâþö×÷WK‡‹w·?ßpëÇ»ë_~¹¾»Zª,V‹·ÿ¼þpsÇC‰¬ñæöý Éùç…EïnÞÝÜݼ{sõçýO7÷þ,ãóªÐàAþºøýÏðr Çþé" LžÅ—Gè„Ês}¹»ˆbÄ‘1R]|¼ø—_p4JSgù§Â@›DÏ0P›3Äy_¦q$†¿mm}µ4J/šnË­fÿÝÖ¶›jÑ컲©[†‡+•-,wZÛ vƒÜøþ]”öT)Ò"­¸Û³miB˜VAhò\pþãvæE×vSôU0%{×ki0aõöðÌRÈ{°eýè°Û£ejeÚ†zÍNÆû%Òs¹T¹ -t -¿*ÈãX!ݶ9”]Ñ•O@ŒŽòźè -¤±`àßMm¸jê?ÂP?ö~C/k` Ó¡ÔÚÓ=à™¾;)Öë]T< ;Òœ0/<¼ã¾zfø±¬dKç §'C2«Š(Ì‘BüÍ}K|Cì À_vÒ@ÑOù“3+Z­eññüLðªXm-h]Njۚam³“ѶìúBާ•­ÐÚNÏÃV ¯×¶-ÅCe£&4‹¶_mq\1Í4‹# :Bè ,À8ÀKk¼¾•=NóÄç4Žd?ð´UÇ”Ué&xMÁƒ ,QÊ¢|ï=BÅ̵UALM¦&ÙbW<3ìAÆ@\èÇp€íšu‰÷k¥ÿðÌ}Ý®ð’;7\% -d…}qèJÛÂ¥˜$Y\WmƒÒ v¯xjÊ5‹Fâ®0A‰d;@Œ†þŽ;s¹»LO…;SNÈ`Dä`íÞyì÷üË\ãáfo^0pÉŽ™(@Ø7m[‚0Ø~ÙÛº•!ºª324YÒÎÊ•Ó\¾¨¶©žDߎ[Ú[M_­E+Q°Žek½êÑïž5à©ä»HYÕ§j/Ê8štD`Õ‘¤w(Tà(àlÅnOò®CЋ B3´Š8(V›Eû¹åÖ†§¢¬0à—ó¯ˆuã¤q6nŸmÓvbØÕØf¤YžŠÑÞ4M +Ðös#ŸÓIL&øB6I-îB¬À}ÏiAÂ{‡'ú¿÷€oŒOìšÖÑ ­Qg*’ñÐI.TÈ¿»¢¬<éµífHW†ØAªgØÀ†eVJ±_!µÜqÎzjx¢œ¹—hИQ4!4HFgkìÝØè[?Ž¿Ñ$z¸aYòáqH¼$úИ}(By¢™†~–Y<•öØsèºëìnßáuÌ&]'¶`kw~è\(T©1¯K… ²Ô˜c‰/«àFeý]•›g‘×™] é¬éÁ®úCËá,2»iœ)\üTqyU³qK¾v€y)1 |¬¯‚ÌQ¤ ™—¦Së1¨O,æ -Uó(ñ†Å¡æH:;0Å£ób_cF”™J\:0ˆürshvK -°0ÌÕ/\†J•(g‹„’Æz¬±‘ÓBh0Ç"-õhd²['Hµ[Žõ2½9fÕäŒ"‰ƒ<ͦ\d}5 r®ùÜïQ…bˆÑP\Êâ‚-Wq19¡0Eä)qú‹é)ÅÄä ¦”ÁP)«÷­p~"EÌ>3B"¼Õ¢Éµ[N§æ´4Š‘†0{ìœÇÑ.£™`!ãד,(æ#±º~ÛÛYkÅy-9ö–Â`:•Ó"Òšù‘`‚1æƼ`DVG…ƒÄxky’0øì/‰…‚hH`°ÍvÚ8sb"E‘ -J[°E܇ßQìÅ€)ÅÑ”b‘á87ªFé Ë¡ýªU5/YÕ¥Ÿ?¹½-ƒq‡ u3B~ŽPL% æ÷skŒ %Gæk.ýh÷ {•LÒ®Ü%ñq9šÌì¶ŒpwóîÓÇ›†³å£‰[—•e¢‡q.ŽqΘÕÏ“L îa'v¦eÂæ„÷CRèyOfilðdc‡øW?˜[еšÃ‰ÉóYf?Tz„¤Êà¬Ø¨‚T©ä2RäB‘~¡8ÈHË1×ÕLqÕcqjÑ­¶Ë]±ßÛõs ‚å1 -ãf“ůÓá±f™¸ï4 $‚SJn7sµE*{¾ZY„X 7z”tšŒr r­œ›8]Ü~xŠäœ<€„‡&©DƒãŒÙ#X(B´â):#qD9k–åSá«Êí@¨ÐرŒ›P‹?A°ÛšlQÂQ)Š”†ƒÇc0ˆ ,²%Ñâ¦ûâ19WAÌfa ËvÌæº+wŽМM_ÍY<Ô”öN–7!ÈÏeÝáfû `×R=)aõè±9|æë gùÔçŸÏöPÛŠÛ¨>‚-¾Z¤Ò­' âÖýÛ2ÜÔ5WRÚÙ"›˜Å)-üºôö8€3ÝHb¤Å")©éÀ„ÕÊî¹=VV%Q‰éÁym³úL‰@]y5Æ;eQ£IÃUYâPÌçäÉ]ÎÂÉG’’,µÜÄèî±&q†çaIê$Zäcp¨(+®ø9-ˆŒõ={ÑT8h°'N!d/â3ÞˆGOûþ°oÜ:ó…\ˆÏWM€¬aý¢¹3: L˜™×ÍÝëesç±póò ûxöˆërƒ >àÜêÅ:ÓȼNŽÇš¡gb§â4ã8™ô›wå»§sôÄúkO*Qî2R~3‰S1 `¦|HÀª)(œˆ©zˆÚ¹aßm,7? í -ÐiY‚õGQÀËN&1‚IEZÏò[—Tï"W½‹bbã?Zþ› WÐqw‚m±ÃQì,û°B´Xm‹úÑÊ«B6xõérve×9 -ÈPÃïR‰¶cú‹ìƒ"ÑòÄ¢]þD$¦µ³±HÌ&Ÿo0 DY¬ õcC½óU½ é‘ µÒmø÷A†Á¯¹Å‘#*HïúòŸrÅ#ôV„>Äø73T(1ÐØn…0ûDi9Ç…c¹¦Ô14 BŒ‹<Ìð¢bBÎ]èVzûᓬP dgw ¥lÐÇÜö;ç7Î÷‰œuá²F”äôHˆôJ…‚ïR¥X~IëЃ’ÖaÃkv¸ä ¹t¥ýõj)2Pò·¯lÇ¥€Ø zÓžâÈè‘3ÖþS5¦=)ƒŸ q!ÒÓcæÕÈÜÌh %¹,óðõoË)['Î/qÄåWBCŽeÍÉ0qXQሕàH0w¼ÞÁ½m“|Ïcú݆"Q>s&-.Oò¯çv·oÅ¡tµ&T®Ù?.6²x§l÷4'Ê@Õ'¾T©,ñÚÕ±º`&‰>Qó¯ 'N9ÏH°½WæÒpžJ4ÙÎlÇA¬ãÄ?õRœ/lL`ò$¹û™3D :u©»Ç™¸! t蟃Èç©{ÝN©Ê>yàOG…aèTöÉVÒ>nK~ƒO]œ~NÔŸužœ„ßÌØ4ÈR¹Ûwï¯CR2κ –»z²ÂGC/ó[¹N܆î‘nÊndI}ÝñøqÁ=õµ€=¦/TŒTJ¡)4*\ÜvÓbhÃì‘S‹ȇ3/FÑ*ÑR*}=Šc½E{,bìZ.ÖM‚f³¼º»ÇšÙ~4ƒ.mÒéþRËã«@‰–/&”X[hÈç ÐznzÆÙÊ7ŠÏ°¯\ÎÒNžâ8GM|Êè Ýð¸w’Ú1ȵ‘[|̉Ôi245Nô­>X¯¶`¬éC<Ÿ/€¥Ñ¡2ßVÑYJÅÔ5ïã>Êp•¬Ì=÷¤¹ã^æªWU}ËÂMèwüÉF(‚|@t‰¶ùÓX˜h=yqV$2S$8ñ_^8RѨ÷Ç#ç¶E+êrïêk¢^yf*J~Ôe¯>ö 1Œò¢~%ÑF}%I!½¬]‰D¢QZIåL»@²Tå¯îí‘Î7ŸêVd±Ñ“Ýoj‰!²lñÃûoÞbë´{pÍP@º Þt¼øT» ÎD³|þ{A߯Jý’›Ž$’—ÜŒ_²H㲜k;H׆û¥Ð¹nŠ·¼|‚32i|Z&r§±ácÜùÉŠ¢ Ê’o©V/}\j⿹ÝÐKçÿýáéðUn”&Ë^(×BDç‚E„($<Ï•B¾P='ý¿L+•endstream -endobj -1276 0 obj << -/Type /Page -/Contents 1277 0 R -/Resources 1275 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1273 0 R +/D [1275 0 R /XYZ 85.0394 794.5015 null] >> endobj 1278 0 obj << -/D [1276 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1275 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F48 940 0 R /F41 925 0 R /F21 702 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1281 0 obj << -/Length 3465 -/Filter /FlateDecode ->> -stream -xÚÅZÝsÛ6÷_áGy&B € ÁG×qrnÇ'»÷1m‰²5–IHÙqÿúÛÅ.(P‚äæÚ™‹g"p±Ä.€ß~§ üÉSkD¢‹ô4/RaiN§O'Éé=ô}<‘Ì3öLãëû»“ï>èü´E¦²Ó»y0–‰µòônöËèâoç7w—“³±2É(gc“%£ï¯®ß¥ Ÿ‹Ï×®>þ<9?ËÓÑÝÕçk"O.?\N.¯/.ÏÆÒ ï+áÀ ®~º¤ÖÇÉù§O瓳ßî~8¹¼ëçÎW&'òŸ“_~KNg0íN¡ kN_à!²(ÔéÓIj´0©Öž²<¹=ù{?`Ðë^­_j¬0*ÍNÇ:6ƒ1¢«œˆÄÀªsSˆL+ݯ²’±Uö\¸Ê³ºm«éø¹\.fe·hêÝyËÌ•åÅi8øž -=WDè óD¨´ÐC%.ëò˲:ƒIÊÑûëÛÛË jZ¹çÿÖåS5Ãý´ztÝtê¼3Y•$"Ë - êÓ¬H±‡ze¹0yV0w¹l–TU³–𓾰¢mÕõnÀÔ޵‚­3°2RÆ(7îkÕFd«D¤J§,Å Q þVó3iGójÚ-ž+˜³–Éèî;gÕ¼Ü,;zX´=¤*À¤üàqd. -P—yÄò^¹Ì„Íù®#ô\Áæ”ÓiµêÆÕ×Õb]ÍöphS‘)£«ÑsEôLÙü’,*rî4€5ÖräÔÀ¥U€ŒÚÅ}]v¢µÄôòPÕÔû\­ó×E}O=Š¡=|a Ém!öö[ˆÑ-ç PN2%Òµnb;É`ó;éÐr[uS AÒ=€ ×jVdXŽÊ ûU©0‚?DXVåsÅ/8«£æófYWk2Úð}šãjY¾ÒsÙuåô±=©,Ggj#*`: (Ï„óþϦZ¿.›û=©L$‰IŠí™öåVZ'¢°Y>|»ª¦€˜{š"6º‡jšT":(vOÛíC³YΨí,xÛ®\wÕ¬¥¦–_~| 9I:±£«yÄýi ë"¥GB¸";I5„ˆ0ÄèÀšŽE­ª39šŽñMpjÅ4ÍvÜÚâ×$QÕìGXU÷-jøÙ# úÙ“Çb7ÖUë§Eíáõåug€OUO™ÒÌwXOË®ºo@fde RYÝ»[TmõŠZ‹Ühõ–WÌ´âô¸Ž€Øs¡ÄéC5}ã®·{@†MËlñ†ðž+"}åÔŠ,OvÄß9G¡Ó¢wšw i›Ö¹E6}¤ðuëÅ´ãçâ kúP®Ëi‡¶€ôÅÀûð†üÊ$™G7/@ÜäÌö{S;'Ÿ{{ʃ¸„T—†¨µÊÉcÌËÅ2‘ŒH iƒˆcÇUW`pEî=Q»„ÈË– $+}¦öWhþR®ë˜ L*ß×Ü )ëö¥Z· ¾ r½³Žpë†àA·´ÏÀu1x8'&‰¨,•‚tÒO{Í0ùsWNx·£ÉiÑœq <¤ÙzHÈ^šut' -¡u‘‡òÍÁ½&¸V@啳3Aᙂ5±£3C•éÑÜ­&—Õ}¹$ÚCÓvlߨãÒŸ_ŽDž€‡`£àðå´Øð,6ðM>\¹0Šß¬™‘»ôÈ*ÉByð§f¶Ǭ’Þ0XÑ0Ѐ°«EdY¿&Qÿ¾[(xë ’ÕjI¾ŠVçqsÍÎÍKí¼мgDêœ~ÏßQ×9ü# -9] }ú©ì‘0±È¬]uÄÅÕ¾¸UC³©SÃm½Wy°RÞm«¢wÛØ$’eTaòž -rüïœH.ÄÃïõí;b¾ýÌ=´uÐÀ àïþR“¹ 8v7×òp²™øGt¸¹› q C÷rW*LÙzPÂ#  Þ&lâJPkQϘ­à„$îiÙq‡ÿåQKú¡‘¡Úhy€eÓàõ¦DOèXXít(¼¦'ÇyUÏ8C[pJwu=>ÿ~"Î'7g…rØrä›l—äL›»®®ïÐÌ¡RH+%„‰ã9TÈu8‡ê¹¶6öôu¿°B¹:.¹çŠˆÖMs› e_ l\”F{GLÖ‡¿C €Z•ë–ßhBÆy?“Kú¹ºáÇÙŒ3W!ÈÂèÐõkN¾u|1Ì’ ”7I¡¾5D‚´Ïnª‹\h›î” «¦m}éø\.7¾ÂôÎ<±!H­y#×È¡$S>n¡“ˆÄQZ&×ÿCl‹Wg0Áü Ün™ŽÀ–™¶¨}Y,gÓr½bR‘§¹9*¼gÚ—>ÌÎ -H›­ˆ§Ì_ét{DmOÛ¸ô}F‚ð;e¬C“bºÆ²SYçB;PxF½ÖIÊØäqIèüØû\ˆ¦ ·Uv¬~l`W p…ñë !¶!‚-Aù—òµåGÏB?l7d"ðìTñÝ©ƒÝ¦wíŠ-~75dP”»°¤¼‰C#œ1QžÊnú@uªS ªÔE÷ðDÐEcqÅ2Ñ)ùP<öÕY‚Ç8XMQe\È‘¶¯ ÓeËýõ¶NdŸJçP"ªã§ˆ©(Rm‡‰'†zVÔ‡[h:¬`ßÎ^C×+>µT"“ÆC0-ºKeÛ û”’~ÐkÁR´^(#D.SsÜ|C®ÃöÛsm xQwÕ=ìîë¾Can¤9®@ÏÑ`hÃOÒíP…›j «ëp• Çuˆ–-”3¢!¨µÕÓ±8å[êrÆ¿DØïA„ûÆ®8¶oIŸÄÕ…8Åe>vÝNÎŒýƒ·™VMÛ” -ÏEƒÈ§5¤Tù†šA´#VDð95©Â—.ó%<âQ”k¯;¶î—›ê€ŒèÕ×E˯®5$XÙttš½kÒ½5ÂQ]i3Z1›óŠÁ¯˜£îç›ÀÑÔËWê^ÔcÞV ‡…Ø;.ès»årNèÁ›{ùͦ7ó~˜<&’ÿnÚX°†8œHéã°;·;‰nÔ}ÏaaÄD™Àst)¯J"GxD£’ÈÞa'Ï?Q}‘àWšeóBÔ®Y1ãœ<9hm%‘Á¢$*X|1X‡ÜŠBêRÇK÷ÇZØ ¹#I¨× U=åz±·hZÇT@®bþÜB¾ýÁhx€$Ejå7xúƒîUR$hßGÝkÈuؽö\aV?žúÂeøÁ26M³ãò{®ˆƒ¹âq±2ÅPƒè™{!ŒJüñU$쌌 mr¼ƒý¹¯ŠÊŒ$L;Þ‘A¸<œì”íÕe°½eöYÜS°c¶°”°Åf _\Ÿº¼å£ 9¡5vçTë ”ü‡ ¤´È³>/ÿƒµÄ!PAÐÐ*}#幎€Êsm7¬]?E•9®@ÏÑ ‚*;Táª4”•ß‚*ØH¢*³Œª¬ð¨’GU®=ª€Hçqvˆ*xm„ sZ™õÐê» Z(±!ò´ŒÜÍßÿßÐJŒ0øÊqh\G å¹hAÍ‹‰ÿÞ·œ KÛì¸øž+"˜ ‚Wüy¨À?ù#b6ZQZÈßóAî—r^о£>>6ƒ–OÙÓÞ…ÑÏÇ‘9ÎÙ¥AþÛ$í(P·; -ÌѸCÙ«ÕEäÁÀ™óÆN†\‡w²çr)[µnÆu3n›rÜuËýÄÌ¿vU çŠh0ÜKp¹–Cx/¥ÏB» 9»j¹é°¦,ñ¾’ðûÂ}ÿ$w?s!ÉÙ(Þp¬@ð_E•œ²=ð€ww?…ýÇ à”ÛQ¨\ËíÃ+8  ¾Øý|ì§Ä‰S‹wavo.üNg®Í·'< -VW™¿&å‘f[èô à\G€ç¹"ÀOËéÃ~ŒÂãGq\ž+¢ÇðŠL - O.‡Šü$ä"¨‚³Y¸¤m‘†O!Òˆ w {˜Ýá é|AimØpÛmŽÂo{ Yí5Òý^;ⵌTÊa½@!2Ùoí¡k5ÐÒoí¾-„ÒRßü€éðÞ{&Wc­fPARÞ?~lcô¬ÌŽ‹ï™öåï^ÏË‹|¨{å?³ÜWx÷‡¯io§Ð=™Ü^}l‰8o–P€ñAWáNd€úó b¹ „ÝwçšÍy˦¸®r{9Ò‡§¿ª¥C_Ã_uÌèÇÛ)yþ5ItyODç> -³åz}ûã忉q2áΆ~ûë)Ô½˜ûw]j­Çꕺúë<@üÂ#ÓU ÅøE -/`µ£‚[>+³ý‰¬ÙÎAg#OÛ&k3î˜SG|ˆ‚Çm±‹ÜLˆ“ ù¥é¨õ² VÆ5-“ "f*Ñ`‘µø@7¸ûàtŒ˜§€Z[ý)ÏëÏߌÀ»´ì'ý­¸?}ew{Ÿ9ÅVÅ­H'P8áí -V -7rWs£­0VåÕÿ ƒ^'endstream -endobj -1280 0 obj << -/Type /Page -/Contents 1281 0 R -/Resources 1279 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1273 0 R ->> endobj -1282 0 obj << -/D [1280 0 R /XYZ 85.0394 794.5015 null] +/D [1275 0 R /XYZ 85.0394 625.316 null] >> endobj 1279 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F48 940 0 R >> +/D [1275 0 R /XYZ 85.0394 613.3608 null] +>> endobj +1274 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R /F39 895 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1285 0 obj << -/Length 3124 +1283 0 obj << +/Length 3798 /Filter /FlateDecode >> stream -xÚ¥ZKsã6¾ûWèªj„‚äq2ãÉ:µ™ÌzœÃV’MQ6k(Ò);Ú_¿ÝèÅ—ì­ÍL• 6@£Ñ¯AÉUÿå*²Â¦*]Å©Q(£U¾¿ -WÐ÷ã•džgÚ ¹~¸»úþ“ŽW©H­²«»Ý`®D„I"WwÛß+”Xà aðá—ÏŸn~üõöý:6ÁÝÍ/Ÿ×…Á§›^SëÇÛ÷?ÿüþv½‘I$ƒÿxÿåîú–º,ÏñÃÍçDIéqaÒÛëO׷ן?\¯ÿ¸ûéêú®ßËp¿2Ô¸‘?¯~û#\maÛ?]…B§I´z—PÈ4U«ý•‰´ˆŒÖžR]}½úW?á × ]ÒŸ‰)cA“J$¡ZV²±”À 2¦g%+¹¤dÏ…Jî§M—?mÅîP´ÓMK%EšÄj5œz&@ϵ H •…vbÇ"Ü­Ó08œÖ g×5ø„÷µLÉ=@.ê|,¨ñŸ¦.ˆïØ–õï>|¡F¹£¾_?2áÏcq(‹–^vYYMX©‚OÍhd8&!BÞ쟲®¼/«²;­¥”Á;舭t„'#´Ö°õ(Rn'Ûb—«Ž ©l‘qrF #­µ!ÿ©ð<#-‘0X˜e“h¡l š×J(cÎþ"áxA†¸¹—ì°EõÌ×W…ËHCGàÚ`ç¡Ò·¤×0…å¤Ç‘g5‘ïyȱ-¶Dqg‡,tjYÇuW4ñSÛ²+6/å¶ Þ<˽ ¯±LÅ (Ïšœ)[Èö˜³ p6‡l‡ÄßÃPåî”Âñù40XMTeý­¥¦“Z§AñWWê¬"jí jñªFâ4¸éˆJj€FVµ µîy+¦ìÏS5/Ô<›"Ž8/ÁòÓQ鼨¨#^%«O/9 -*Ê(6¿%W“çÇhêêD“Âq/œU÷Ø´yR¯3|ÙáêØxy,óGjº½aƒÙûŸ{:ía#;œ‡²¿~fþ¬ÞRcÛSv§ìñôYݾôÓ×üìx 3`1Ë›mh!~Gæõ>äºÀ{.Ôyìvºn -BEÑëëz¦…u‡Á’² -m2^÷î¬S4O]é\6•AO£ÓʾÈj0€Ý±¢œSË09ä@«Ê¶OH>„bÿÔõ†ë(xOôç¬:òŒÍŽ"ž*O[)À9ªîʬ0‹*IÒs‹ô‡>æ‡O w-F}`VÖ€€ÿ£IXÞ#6z»´”áð‰V}šðMu4Œf(,½(S‹L×R¶£I2fBc®¿ë<ÛìpX»ÅC{·Mˆ+‰ÎR'¢CUºkjQ|À^rJ꤆[v-¦ƒ—ÕN 2Np³t>JF"V½ê-œ±±š™œ‹£ OE^¢žŠ-žBªßÚ™'¶ð@ÌÓY|wÒÊ(ab£Æ'=>ž‹¾º £7°Ú€é²§{¦££]LAøe‚¿¶pÏ4_y>`¿&g.ýµ×/*Ü;¯W»ùB„l»e¨Öö< ±ÜôNi[d-©œ  ´m‹àÀ3šâ80Z™â€£Q´ÀÖïaÖ¼.®3oø@cëñy‡‘Rø³im#c‘Bªr¬Ótq“06`Ëm»šõõpd”BÔÆóÓã© ·Í>+¹ë>kKD8J3lèW#­)ïcÐx¨š{Ä+Ü;“sË£š¥,ëäµÚ!£C¹Ý:׆(æÄzFç °S7ô5;"BÂGT„¨ùßk »G¢“Z€±-:¢=9™F »(anß|y6c{Šõ2Ê€Þy®=ÈVÖ—‘±ND¡òõt9亜/{.‡ËúcÜ´ç£%N -©õë"x¦ÆU»þŒeeNm"Ö ^¾z¢+¨à9É¢ÈåìºX‹<àŽ…úûRÏpý%]C½™›Útº3syÎ*I“LÊ® 74 í6µÖ6:N\1õ/Êϵ1:*:‚eéq=ôyä…ýû£Û5P]‘ ” L™(Nê8íý¢zöÌë×ÃuJðWNÂКY¹oÑ”ü|Ìps&ŒÝæÂpQy53KO4$léÀYƒÌ°GÂʯ?±J°~‰âİlÓ\Aè“~×  Ö?ô,8‘å¼—c]áù»2IÍ$²…8÷l8Íðë@?®âe¶û¢¨}âlñ¤¶¼0œÞñ¡©»CS½– ´›£diÏx -„¾¸€6¡è½çN¶çîPæÛ#ÐÝQS’.:Oæ ´AiêpúÌɹ  Îa=åÔvÅá˜õ×9v0 ¡C¤J#!±†};ôü›á€yØ›Ï;Æ ¥óè -¥­ɳþ™ë )|üWx1 -.à!qÑeeÕŽmøoä†>áŠÈÝÉg6v”Ña8#o»Ë• ¡õ©lÀt9“y&çÁXl<¢xÓ&µÊ^]ºgš¯=®ý!•­=.ý”ì¯Ý”r¹€©=$Bº“—j.áÉâ;†ÎÝ!•=ˆ¡2^$G[Aäc’³å/ý±ÀNýà¢ÊIáQ•Îè(Bµ«Ô$ºT“øÌ þŽ­=à3_ÓOŽ$MDÚßKLÏb¢B --µ/"öÙ‰fçKâ„ó<WDpxŽe›Ë !®…Æø‰Ü ·#‘0‘‰™ R „(vÜ5–êWàÄfñˆõ2NeŽA±¥ÕãåÇQèlÀ&ú(„nÖG! Ÿ£PB ÓÛoDhü]Iæ.a¡ëãç¯Ôå/Gƒæ!e{L7ÑË4-A% ­Få£yÔ -i(åØì‚€cÅ$¸PÏå‘(˜Ë¤o„*Yˆ* ûù½vcC‚Gcõ0\–E&¡ˆ•ÑÓH€#^׿yø7¬0-Â(™ÜãÝì&÷+ÿ¯ãò‡ºùG§±oºkd.rç` ‘"ÂoÛ³ub¢ÿå—ha’$Ë¿LKa5—ç¢q!ÌÅM?b<ÕÆK·Tëdz‚1ÅBÅ`æRBõ1 þ<8¯È"Öƒ“E¤!ÑÒyý‚Öƒ;ø«‚Ù/(‹‰Ô¬âH„Š~˰ús%!±¥©&žAÛíô¬Gøþf¯VØÏj¸%žw3˜ØmÉŽ| …Õ`’à'!þ¤ÂûïZBAíì …à´É³| oØN–âo6Ôð”ª5MB/|ÑÍ¥->ÏÐ i_Q È:ã„¿‚Ã\3«26¦ð+\nÏ4œ±MCð¥óPþžž¯Î}c!„½™ýí_М^dbpµäÂ7 P¬0XEjÀGšêºH]¬H˜k ú‡Z+Üendstream +xÚ­]sÛ6òÝ¿Bo•g"Ÿ8÷”&N΋sg»3½iû@S´Í‰,*"×÷ëo Pü’äN;™1A`¹»Xì71ãðOÌLÂ’T¦3›jf¸0³üéŒÏ`íÓ™0‹´èBýx{öö£²³”¥‰Lf·÷\ŽqçÄìvùëÿåêãå§Ÿ¯ß[=¿½üru¾†Ï?^þë‚FŸ®ß}þüîú|!œó÷ÿ|÷ïÛ‹kZJŽ/¯>ÐLJH¯/>^\_\½¿8ÿýö§³‹Ûv/Ýý +®p#ßÎ~ýÏ–°íŸÎ8S©3³gxáL¤©œ=i£˜ÑJÅ™ÕÙÍÙZ„Uÿé”ü´qÌHÌJ3ô§¥,˜€¬IY¢¤j¥,Å””#Jy]5åýËp³N3•87ë"‘@dU‡¬K™‚£ï“½¼G’o?jלIcSÀŽ /EM0=lR0#Œ 0¿qÛÇâ|¡àˆ—Å}¶[50'ÞÀŒ³óW700éüêËíåÇÿØSQ×Ù ÷+Ùö\¸yÀPë†FÏÅ:ÐÄÿªu"z°RÛïÅ–&ˈn×äFrIJÛE>ÒŒêclÈX¬NÜüÖËØè—ƒ¥p`0j*ZnÛ%<š^VeÝK‚(ÃîZH<Úv¯00GDòÊ?—5¤œ¥Z¹þQ¢äÅ9Q:à…ÁSD·4nuÆå¸.ã\z–pf=øôæË;|¾z÷ù‚†þƒÕ2ª·1ól¾÷›‡g¶~é’«é¥Ýü€W×Cð¸3:ˆlUW‹½ƒzmL°ÄjƒzÃHPqi!Àö-›|Êœµ6à -ªõjŠ^b˜5JXJ½ûò‚Á½Ê®vH1÷ˆütИ#éöt`5 Æ@!õÏ„Nß×'âÅ›U™—Í— ÈNrû'¸Œ¼É–_J¾CXô™}…kãUd¿Ä÷xØ8ÞÕåúa★â JEyü˜u +NYG‡ËÐOñBÒpê«x,Èâ6Zé ›ž{)á{+%|A)í’ÆÍã:}Í¢­£ø]zX\‰e­î´,¢Ó–Éü²¡Ÿ«ÝjICÒjéœÇ\äèÒ·/ôŠÞ —›Ýv>¹Ç“¿Ëeà(ž —aµ ólW{½‡µz•}/ê¹WbºçÞòmV?²Qž’©LÏ}<áêη"Ð^Mµ¨«lêÁ‚‡TáíhL¼oi)³ÎØõI³u ˜TOº8ã<‰‰ÙÏ‹;Ü òÇ"ÿŠÃ”"˜_Ì l·Ž +&PyñÙB`¨Åçõu]4ôuö•ëºú`ˆ YøºÚ>e+ + гøIÈÜ$xÕ˜ûá8¤ôâÕ +ž´6JHIÙÎ0 `21ð·ó_®/?]^ap¦÷, /›>±z·ÙT¤©ˆ¿"zy”Å<óB’*Zí> ÓŽP¨ ´ÿ$•Câ[>-ÒtnPÙ Ãæf~S=àM é±z.¾D˜ÉèKo;4ô,êU ¬…¨¯~g{ÒI ¢lðÛ5?–KÈvú{`PÖáöÑ“>ì¶Yt@ÖRzƒË™EÈZ"·‡s/ÕŽÏpINß2”6ª‘íI¦»äý)DÝ”«M*LA}&NcŸ—b€jBË< +ê×z¦0ˆÑ~o]hoXˆ¢YôNFÙ +-Ž»§.ÔaÿÔBᦶE¾ÛÖèf”S¶\Úã”#ÐåžsâšI§û”䇯qsÔ9K•tŒ «|©ôj +ªñýÛ®ðq†”^ÀDÝÔ²~À›¶ X<Q*Ûd?y&•AJ DB,pÚkL.Ó´"’çjû5dËØ°ƒª"2WÒwÃ)Ñ—PždëúÙsÀuô“:lMF/SŸÊú…Þ¶·mXÚGZ®ƒÐbi„3íNa¼¬¼ªÃrpüðÁŠPgËZùº®ž\Vƒ£jNióИ‚¥ ܆dÞ³îô=$7Y°Þ€Ã(Ö-ùk{ôRÖ“)½eÊXñ +ݲä6yU5JpH\GÑ4ÓɶŒó¥m礛N’ …m b—1ÞÂ`C;ÿŽáŠÊ¨å…4j߬J€ðÎÔÌïý7Õ½=vá%™/³&› +žÓ´ZgøCMßäý„T¬!°èÁ¨Ã` ¿.ž»+?†p/ <«§”%óÑÅ€:xí-ò¦MØ9Í}ÛA\(¶¥/ðOæï=ÑHŸàã ú~Ä’ÃÑ,Å:&‚f‡"RX@€Y{e…·jSPp á¶ÞA +?µµ#Ú¬CÊrt=ªúºÛÔ¡»)Šzêj²ô€ìÈɨ‚÷E“?.V»©D;¦Eô¥ÙCÆžHG Ðá¼ÜçRq·h^6…'È–q‘¨£´[ 1ñžiKzj“õ›hŠÛPxøQ5á@(w“± F.’'‡}µ©¤—m‹ˆú'¥!8¢Æ”5¦ü§ÙªŠL?—Íc± Í$ë{Z Ú¦íIŸ»ÔÊ$ó¾<êÝmLYöÎÖðÎÖ@5"Ú*㽑Ú5ijfšKÈõÓô5 xåü}‚›nÀƒåY¨üy’ÆEßqÀ†ô… ZDîJ ¦°¥ÙQºV² ,ƒ¤RΔó1~¯Wiß.ó½p£Z›ýrÕÞüþÊùèfÂy[P2¥ dKÆß$Ì¾Í î€˜uÆ~¯{ø‰·—Orö¡‚ͺ› +ˆ]Ì~S‰ìY’b ìy¦Œd‰Lmª + øË¹äó"¼”O›•ïƒÜ>ÜÏÀ(½NRHoW¸í¼D’rpûÛ—¿¦Mq1çФ&ErÜ1BQŒ)yÜ3¶P(Qp‹r¹ØTÕjä9ä ÜšYíØ3F¨1u•ö,7Ú#K}0ñ¶CæNswuµ*š©˜bÓ&tG÷qÙê9{©ÛªÊ¡T ¯1g‡áå‡0×Éðz hÆ+i©è8z, Ã§b#o]0¨éʼ D—{”z 4&ßX†90³.ùES6ùg‹¦Xѧ¦Sà˜¶ÀÑP¥¯V”ù HܲOp`"$v)æô 5¡ö:áÀžÉn½¢LÑÄ.jî›9~SïW¨O|¬[¶Î%ƒže¸ÎÉèi~±÷u0s—Õe¸º{ wCHõþå@w”A«Dv:µÝö&ħDŒqÝk¦‰Î´c¦‹Ý` Ög‡Vì1ù+²#p¯»bbKÝrðâZšAïÓ·bg9¶b©‘¼0pà:Ö0ëeN_#Ñ)íÒŠéTên›ßÅ®5~t +(.wOš9=…QEk¡%býÍת É}ïĆÞÉ¡·äk¹H;ò#-¾‰Ê ^bºžJµéuÒ¦×SY‰T>q6'.gÛ4¡ ?qe>ÄÚ»š¥Ÿ5hÆÇ׳$/Sk{üŒýM„:ÁÆÛdfÖ:X8Ç,㸇í@q±ª |€Ç¶¤‘;N8 ÷b^šà͋覧ìþêÇíÜá—J¦D7ä%©õíå8µ,ÁºðwG–®@ð¹,ëìU_.ùxÝ_Îè±É¶ Ç»U¶%„àÄ<ðêo8mü}v|µþ§„,ô–!1\÷ýi¹¾ÇÖú^ÕªN‡rÂ5ȉÂ>7Ûê{¹ÜŸÕк,†-3¸f MÐáï  fÕà´ E†òDŸúÑC_tá'~o0Ä:aW’ 7äœKazìŒ4­…:ÁÅ['/ó=>š¿Z,-ü)ŽFxG‚ÑLÒraÀ=èRi¡Nð0ÆvÔÙ@ÏœÔ'Ú]¨ÃΦ…šRâ~ÿRv}”z 5A¾_ð‚6&P öè· +ÐìËë:ß–s©î' 1¿%õŸ2ÅdŸª Í"DBÓÛè1û‹ð'¶<ÆûZ Ô‚ Û=«I ŒP'Øc;®kJ2Ã!ÿ9®k¨#º¡¨ìo¦uC= ÐÇ©·Päûº¦™õÖÕ¥ÿ÷èÚpC]olÖ5ëÀ‰ÞFéZ„?±å1Þ×êšÂßð˜çÞB`cŒí¸®qPM—˜ºÖ:¢k +)6Û"k9UGY½¨7Y>þ±¡L! JÅq6Z¨ >zJ§43’›>#¡ Å>€ñs&ÃÏ8t¸…™Ð*€‘£‡/àù”}-ÂŒ×_Í÷•+N†Ë©†^ól»-éò_‹þ-¼caú›”šXè^¼†àÇyû3¢ ƒÐ,+Œö0õ#欉Nø¥òõ˜m³|nr ZãûÀ†nŽm²¿Ì®é—0õìo0誄®Íé•Î×}3Všì.ÜÞx’ÍþZÎ…Ÿ<ÀÚ}–—+ükøxUeËp5cé‚&©ºÆÕR´?Ld…?_]þØ}ªíiê¾#\¡iØHÑþÞ ÞŠ5^˜.„žLgáyuKO¿5x~ørCƒ'»C÷n~À£ +%óô =ï*ì“ã(p £Cç/,µ_yþë©ßLA–leçüãv–q?oÃÌ!6¬aʶåìkµ°¿“®þMûðj«±l†M†uñ¼*ד?çëuûrüñl±|/–ƒ 4Õo,ÖU¸g‡~ª¯ Íâ¡ ãmOþ/ÿŒÿ´eÊ9y8i§Td +åcø8 +p&±÷4fýÿK€ä?endstream endobj -1284 0 obj << +1282 0 obj << /Type /Page -/Contents 1285 0 R -/Resources 1283 0 R +/Contents 1283 0 R +/Resources 1281 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1273 0 R -/Annots [ 1288 0 R 1291 0 R ] +/Parent 1280 0 R +/Annots [ 1285 0 R 1286 0 R 1287 0 R 1288 0 R 1289 0 R 1290 0 R ] +>> endobj +1285 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [154.2681 743.8714 203.5396 755.9311] +/Subtype /Link +/A << /S /GoTo /D (notify) >> +>> endobj +1286 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [80.6033 237.2629 144.294 246.4782] +/Subtype /Link +/A << /S /GoTo /D (statsfile) >> +>> endobj +1287 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [265.4578 191.3384 326.6578 203.3981] +/Subtype /Link +/A << /S /GoTo /D (server_statement_definition_and_usage) >> >> endobj 1288 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [339.2005 483.6075 400.4005 495.5077] +/Rect [367.5441 191.3384 416.2908 203.3981] /Subtype /Link -/A << /S /GoTo /D (zone_statement_grammar) >> ->> endobj -1291 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [455.0966 291.3684 511.2325 303.428] -/Subtype /Link -/A << /S /GoTo /D (address_match_lists) >> ->> endobj -1286 0 obj << -/D [1284 0 R /XYZ 56.6929 794.5015 null] ->> endobj -354 0 obj << -/D [1284 0 R /XYZ 56.6929 712.783 null] ->> endobj -1287 0 obj << -/D [1284 0 R /XYZ 56.6929 687.8416 null] ->> endobj -358 0 obj << -/D [1284 0 R /XYZ 56.6929 470.2923 null] +/A << /S /GoTo /D (incremental_zone_transfers) >> >> endobj 1289 0 obj << -/D [1284 0 R /XYZ 56.6929 447.8217 null] ->> endobj -362 0 obj << -/D [1284 0 R /XYZ 56.6929 335.2388 null] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [280.9692 160.0192 342.1692 172.0789] +/Subtype /Link +/A << /S /GoTo /D (server_statement_definition_and_usage) >> >> endobj 1290 0 obj << -/D [1284 0 R /XYZ 56.6929 312.9276 null] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [277.6219 128.7 338.8219 140.7596] +/Subtype /Link +/A << /S /GoTo /D (server_statement_definition_and_usage) >> >> endobj -1283 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F63 1053 0 R /F62 1050 0 R >> -/XObject << /Im2 1039 0 R >> +1284 0 obj << +/D [1282 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1281 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F62 1060 0 R /F39 895 0 R /F14 737 0 R >> +/XObject << /Im2 1049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1295 0 obj << -/Length 3121 +1294 0 obj << +/Length 3853 /Filter /FlateDecode >> stream -xÚµZKsã6¾ûWè¹jÈà ²ršd<‰SOÖñž’h‰¶X#‘Ž(ãÝÚÿ¾Ýh"(JždjÇU#°Ñ~|xðƒ?>+tÎd©f¶T¹f\Ï› 6{„ºï/¸çÉS6äúöîâë÷ÒÎʼ4ÂÌî}9+ ->»[þ:ÿ?ß]Ý^fB³¹É/3mØüÛë›wD)éç»7ﯿÿ×íÛK«æw×nˆ|{õþêöêæ»«ËŒšC{á{8Ñàýõ?®¨ôýíÛŸ~z{{ùûÝWwq.Ãùr&q"\üú;›-aÚ?^°\–…ž=ÃËyYŠÙæBi™k%e ¬/~¹øgìpPëšNéOé"×B™Y¦A¶,§µÌr¦Ak™• SÁMÔ²àSZ\¨åj½îž³?öõö%ëÚñ¤¹Ö¹Z̆=¹&¸©2cR ~yªÍoŒ‰º‡ÅüyÕ,VT\w‹jE;¯–Ëí%/æu߯EÕR¡Z,ê§•;ǵlÚjûB”w7¿P0Ë~×tm¦rÌïVïiS} 6¾Ÿ§®ÏP zÚ0XÎóRÃ4Qê¾¹_×o °¢3“ -Ú¶ý®j¾ë\’Ž©ˆŠnp(ü}»ß¦½äó]½m«uöP-šö1ЄÀ¿ßQaÙôƒ>w«z“vXÿé{s`©äa´õ®­û7T|nv«À¶†AûjÛ¬_ˆð±ížc+ -NÀÖ­k´{î¶¿êé3Y°%Ù#ÊUæ–³S–82+rÅ-4CîM…’qÍúŽJ÷5ýöÑ –DhÐL¸tr‹ÁÏ´ÜwüoÐÉÄàBæVxXä]½©ÛªNpß¿Š† ÅEÕ{iœ=Áo÷©Þn›¥33øµX~2µ²+&B{v*•&ºä£ñLà-ÞÚWr‹É¹dâór  %¥ÏM)ÄEqÆGûu9 -tf's"·pû3ÅÕßO.âï%iKVŸ÷Ö!×io\&6•ZòJ£Šó2D® !äh‡+1<%R¤.+bj8R RG©k]jquþ ‰cw6¸+¢>À˜MÑ9 -V§;\0lÐgà³cÆæô¹Ùd$É—î„£9H+¿{=c®3æ¸æ°ZV»ã ‚¡åùÑ#×Äðé¾öDR‰tüÆ8BÆ÷±©1v»»‘É­ûýýƽ@ùÝK[mš1Ði Pi’àR7U¿«}‚z?î‚9@z…#R€z0SúÐä;—µƒ @9 äè±Á€ìf‰”P¾év5Qw«jÃQÐ=BÕ}EÁÐÐI “aå; …¹Pœ*¤£¯|«ëŸ§N v˜yÓöhϮ·½¾>²Á!1Y¥g:ÕÒ¸3ªÜ>ú£‡ÛÕDþlØàØjŽûuVS/𠌤±¹<’ư¼…M¤9²ÜÈõš °!“=g(YË#»ªYŸö]¯°ôÎúîë´ïF®±ïf Îsµ]¢¡Œ•ÁSSœ$rMH’(ƒéœ‹á´ŽÝØÈèÆP n ŃãGtcø ß‘7†òÁñù1>5h¶®>y-A¾BðÔ_gãrù&ZÐé1|“âÜ‚ªˆE¨ C L'¹uÑÁÕ ò‚D—q0²â@a°Ãe\$ÿ… Z[ô&,þw -ûÀ–¾,vxCÝ¢@5ì§¼°)€Øz±}4wµt=â1Üšq¡S×Ó§ £ 7.8©‚””§z =m°d’•ó»ËRÌ;â©Ûê~íùâÐÊ =¿!æpœ7¡§öOZÈN7•yÞd^µ°a šýæ¤jeÜ.e`#d¿/t#ÙüSµÞÓ•ÇþôiUµ¢s ÐÆ -û×–Øâa`–i¢_‘£Fݦ7Õ+(/X åÞ÷{Ðç },º=^ãî:@÷u€`¨#ŠZŽâgàÊîªË ûçS××HÓ=0÷S£ÑÖ/ƒ¿ã4NÀcJ„+°.¬”tí`¹†ðw·«ûÓà@–%¸k¡Ý9“tZ~DþlØà8÷û9à@`-9xë°óã›øÀõŠ JA-“2•!‚ƒM7TùkPA¬¯œÑ ¹NC…Èuˆ¦ŸLÖ¿´`¾=eªt×Çr¡ÊWdˆ\B¤»> Ét*…¿·Ú_tRù¹rDƒ·Ë1&Ñ&_{EBÁ_óèy¿é: ¸…4Ø„®L±õü-üó|§úÅ#·´íü@èB²ãoB¨¶¹§MÖÕ}½î‘JßԷ߇‘seQΔsˆN¢8Rà¼÷s1^6d›êÊÏu4)kè Çñ/ë'¿û„ äÏHÙøp4 ú¸ø  -7øtµî uØ—=0FÛß6lz›ÇÖ›ùòð¶ÀGƒnS‡Q¶mŒJ|mðxfÃË$²Â¼rþ1ä:ã ëà Îpêíñ–·Ì…(Θ&†O7¼îU¦ã'HY P=RVÂ2Ò#RÆ´7üõëS»s$¸‡ Äâgçû:x…«\y®áAåÄ•˜Ö¹Á\C8&ŠtG?‰m T:ŽÓ!W™¼äe07(9˜ ¿éKYÒK Yž|É!aÏ/‘O¿ä(-çSo9#ÄGHexË¡˜T&o9NKƒw'˜Ò·~ªõÁv’[nÿŠúJØ¿è ¯ü?<ÞЈƒ -þÌâÄ‹9<ß‘“÷×,¾øâ×t‡§†ÊÒÍ4D`öø¥ B¡õ$вÈu!ì„èÿ¤â/ -endstream +xÚ¥Ërã6òî¯ðm媈!‚£3ñd'µ™ÌÎ8•­Jr %ÈâE*"ióõÛ/€¤L{vkíFh4ú ©ËþÕen£ØÉeV$‘•½Ü.âË{ûáB ÎÚ#­§XßÝ^|ûÖd—ET¤:½¼ÝMÖÊ£8ÏÕåíö·Õ›¿_¸½ùxµÖ6^¥ÑÕÚ¦ñê»wï¿gHÁŸ7?¿ûî‡_>^_eÉêöÝÏïüñæíÍÇ›÷on®Ö*· +ækYá… oßýã†[?|¼þé§ëWÜþxqsÎ2=¯Š äÏ‹ßþˆ/·pì/âȹ½|„N©¢Ð—‡‹ÄšÈ&ÆxH}ñéâŸaÁÉ(M]â_bóÈê$½\r¢s³Ìå8Š-pm%*Š3£—µZâ²ÇB.—ÛmÕWmSÖëÝ©=¬Ë¡ßÃŒ8Ú”›½;g‹Î³(Ö±¾œîýŒÂ€µ@¢™¨ űJç4Þî]ç®Ö@ûª="Ew6mÓŸ®T¾jk˜U¿´;·/ªö$“vü-ùÂÛSÕ—}õ@º!­F+ÖòÆ;=8X$Ññêqïl)X¦{t§ª¹ç?è¸ÎcU›=7'#yd[ö%ð8Iͪ=[=^íÚºnÃêoÞ_ÿtã÷ݱ±'’õä{ÆÀÛì˪颀Âc Æú•60J¯îÚ~Ï-â |{á¯Rþ¼$æ:ît®ì×ÿöm’O.Neq¤MŒŽ»=?i~» +°œßcó…Á¢[·+‡º˜’½á°Ü`ÂËO ©„¼;G\bl¼¢V¦íX02>¬åž élÎÀ©0¬uRÐý0C‘Æ’µ.·Íïq¬ï‡°!ŽW 0†ÆéPbñÁ3}s62•iÎŒ„@žÞñX?1ü±ªe;7 -,Žu]…Rˆß|5tÄ7ɾù…p”{˜+ "+:mdñéü\0Ù °¼‰µ«w úö £]Õ¥O«:¡µ[:ÏÐl]WÊ»ÚGMlVÝ€êfcUÒL#š„: 0ðÒ¯oãN‚Ó>ð9'ÇOººF6@‚ˆ ÏMûØÌ=É(¸Šáí„"ƒú$Ë3 ¦í¹Q…922* IŒØ3|r}¦‰írf(ˆÑ©ƒ –Wf¡p¦#“s˜M»$ I¤HXe[uèu:Þ@l¬>šãlà¦>¸ŽaÁ¾!… ¹p‚N­«feÄ™­€±¢)¹bCžF©^`Û–1^©Ä„qÔqÇûë%Ûããmc&ñ tÆxÐ ½kHR°GdccèÂ8~çÁ6Ø%·æ³ãøIô¢–½(By¢™a–Y=TîqãNÎ~Ý÷îpìñ„Ú²Q×)®Ø»Cz.*N¢Ì˜×…ÂDyìËc…ò.«—àHeãÛT»'×…] ééÉm†SÇ,²¸)ä€Üû\oyS³qK¾u€!›0 ºoÚ ÌÑ£™—…ãöX±VبÛ{ˆ?,O Ç +Ð9€õ+ïÝbâñé5n$y”«ÔgË 'Dºú…ÛPY¤RåÍc¹h²æØXO56ñZ fY¢%¶žŒÌvë©ñ˱^&¢— ȬšœT¤6*²|ÎFÖW“"ëÚÏÃuÈB˜†ò‚P–lqÄŠƒˆÉ9 €1.B çH©×_,[€QLMzJ© U²úÐ &RÐ’#$bLSSxý%¥ZRCŽ]DÒ(L#íi¼ó<”öIÍ ¿%B–ÄèûÝà–¬g¶ägØñ4åA­âÝ&6|âM¼ý$[}ª ‰;Ãô§E¢5ó#ÅcÊ LyÁ:œ NJ© Öò,s ù_j…‚dLa°ÍvÚxkbEJJ\°E܇ï$ôbÀœâdN±€Èn<·©Fé(/ ýªQ5/Õu˜?»½=Å‚6‡Cº!?Ç)(&“3|È:Ë-†…©’¸#U +Ÿ}tÇ–½J.‰WáÓx€„jÏì÷Œðñæí/Ÿn¾Ά&î}^–‹ÚBã’-kžf¹ÜÃAÌLÇ…ÍïÇ´0ðž¬ÒÔÞÉÆñÏa´¶jµ§3‹òÌa¬õI°“ѳڳx!a²Ø~¥ +<Åz¹ +°8³è7ûõ¡<Ýv) PÁ©ò¬ÖÇQš'Åët¬Bæéˆ…4âš%ïvKÕE,.¦¯Ö!(ŒÎÆœÓä”ZgÍÙØlõîÃC"çä¤<4Ëä lsf`¡ÑŠçèŒÄ¤¬y^Ì…¯®:´±BcÇ2nb-þÁ~h²E‰'Å(RŽ `Á2°Ì–&«›ìKÀäT1!®ã°…» fsÝWOhÎn¨—, jF{§k‡›€äU3|áf÷àÐQE)eõèc{úÌ-ÖNò©ÏŸÏîÔ¸šÛ¨>‚-¾Z¤Ò] áÖí›2Ü6 ×Rë;Þ¼(Îháë³#ØãÎt'y‘‹¤¤ª6wäRôXY•%J¤çuíæ3%õV‹wÊ¢F“Æ«rÄ!ËçäÙ].ÂËGš‘,uÜÄàî¾!q†çaiæ%Zäcp¨¬j€ÖDŸ +öú–i&94Øg^ˆrd‹5Û‹uG½‹ÏVÇátlý:çÕ\åsêM;œ qؾhñ@Š"È¿bñ¦X/[¼€…›W_ØÍ³SÜV;ì€8pÏ Ÿ‚g¯“°è™™* (‰õœž_ƒ3ŸY>] /6_{VI +’(z8±™Ø°T!*`Ý–QX*!"¤qÜÇHŽïÖÊÍH‡ÔZ–`ÕÁÁI 𪗅 Aì`å‰Ö ¯Ž#NúS_5swATmžŒÐ‘˜ðt†*%&Û0fß0­—øðXm)ŒÍŠ#ÿŽð°bbyFÍx¶’ÈDЛ¿È +@îÐRÞmðÎÝpðžãù>‰·/\ÚHÒ‚Þ +ƒ«PôƒJª kÐ/éºQÒ;l½Ã—4ׯt¸`-…ʵë¹`ͨ)ôšÛb£éypòÜiõ¸õ\—i[ÊägH\ $™eD²9 jÈÁI! |&|NýËq*Ä&ŠóLñy–ÐP Â]Õpd2NWDüi…àH%°ðì_ă“¼/`†ÝÆZQ±p&-o>_ +ïèîplOå©ò%'T± A.:²„M§ì[ÿH'ú@E(¾W)0=ãµ/gõÑB2=×õ¯ gž¹È#ȳ}¹X*ÄE&Ae·°Ÿµ‘Õ6 >¤Ï6&2EšN\þB¥Bùçv‘ ÁCé8< +‘E.2ÿÌQ±}öÒŸMêÃЩ݃«¥-¿}Á¦„ëωZãc¢†ÞüòÿgÆfQži!Ú_¾ˆs“iò]²ØÇ†E”©pC/ó[G…Ný†þ©nÎnå©M¾Æn;}cðoþcIàˆY Õ$•Rh ŠWïúyI´eöÈ©Eä4/FÒ*V‘ +_¤§X/GÒ‹˜»Vë‘u³À91Qšçù뻬…íçOry”f±šï/Å 0<¡”jùé„c ù]´žÚqöòã Åg8Ö¾Ggéfrœª¦!s vn|â;ËðjG‚ÚÊ»-¾é$j®綉r_ ¾7{°Õô‹B-WHð‡“6Mþ‹Éø,¿`}"£ÂCV[·Ë¶'³úì9 +Èä*X–ÉSQ–y–gÞždøwªJ?a8Ü_ ÝÎÇŒÛt¿¸0¿!š> endobj -1297 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [213.0783 309.0057 261.825 319.7901] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update_security) >> +1295 0 obj << +/D [1293 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1292 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 1298 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [398.1622 184.6228 446.9089 196.6825] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update_security) >> +/Length 3366 +/Filter /FlateDecode +>> +stream +xÚÅZÝsÛ6÷_áGy&B‰/|t§çN㤶{×™¶ŒDٜȤ*RqÜ¿þv± Š” )¹væâ™\,°‹ÅûJž'ð'Ïm*Ò\åçYn„M¤=Ÿ=%çÐ÷Ùdži`š¹¾¿?ûî­ÎÎs‘§*=¿_ ær"qNžßÏ›¤B‰ ˜!™¼~óöú‡_n//23¹¿~s1U6™¼½þéŠZ?Ü^¾{wy{1•ÎÊÉë]~¸¿º¥®”çøþúæ Qrz˜ôöêíÕíÕÍë«‹?î<»ºï×2\¯L4.äϳßþHÎç°ìÏ¡sgÏŸá%2ÏÕùÓ™±ZX£u ,ÏîÎ~î'ôú¡1ûë„U&=Ÿj#È[YŠLJ`Êl.R­toe%cV\håyݶålZÖÅÇe¹»f©á29ßsEäë|©¬pV«±W$yªœš¼¹¹»»zMív³Z5ëŽ^ªUÛYTF˜l’ø‰ê⩜3ÛP¬NDž܈ à`’tòK½,Û–%•,¥kh¸qƒá©Ö暇¿”mD„ÌD®Uñ*¢«:ËO)ª…K”a®åcñ¹d ~V ~²Æó&pÔM‡SP”ª©”"·Vù¹¶¶„“‘½Ü?–Ô˜—‹b³d–ªB0·KÓ¯°„ë½{ˆ©™L2‰<ç×8®œ?Ëj^tUSïAZ§"WàˆŽªÐsEt-×€•XïH‰i­³ÒØhåßã¨ÑéW€eÕ6““›¦+#S°T–`íø™ÓLØ~âbÙ6¤l]–ó–š“>òýâŽ}Ü"È œSƤ<‚p%Fé * +B<~d–‹ é&‹rÖUŸKX³–߆`•Cx1ÿ€Ó £€;ŽßÓaø¦ÁÖ³Y¹ê¦å—Uµ¦Í!FªÌ¹£:ôLûJŒV›J¡R€íP‹K/wTN¼htÐɤ­ê¢Û­%¦çDz¦ÞÏåºZ¼TõulÁ/w"`!TûÍÃÞ~óð%ºyBˆ4MÒ±g«›Ø2C6'we×yÅÝcÕR«YÑyôT†ÛïJ@>ˆ°,½+ŽV0s–$ú´g7ήϛe]®9ê Ä’iVËâ…Þ‹®+fŸÚÃÔRhÈN€pÀu… üsS®_–Íîà<©uùqÁ)"x´G‰©IÔXòݪœ€`ý&AXuå^tN:4{ zûØl–sêðni]±îÊy?KÌÍ*N1OäéÓ. .ÃOŒØÕB\/b®Ö “¦zCCîL âµíýŒG#(‹Qœ–†˜r@à[ì¸Ïê÷$QåüUÀsY÷-jƒÙ¡ÁÈ3²»ìÊõSU{;¡}Ù™`ÅGµ¬gLi;,£‰gEW>4 3bH¢œîÝ:ªVE½/˜;à ñ„÷µÒbAê(ò‡\‡‘ßs¡ÄÙc9û4E0´{nWBgÔ á=WDú8†¬6z,þÞ»%mòÞ-iÞ1¤mZï„Ùc …w¨[W³Ž{¼C…®Ùc±.f¤SˆzQϩѾÔ]ñ…zqcý rÝ‹7OÔ†²iS3,!¨+cÆîø©hI¤N'Ð%…ˆÅ~×pDj°ú«¦n‘f%Ä÷9QžÔ<Ñ­uÙ=7ëO¾ºs!ޤÃ8’B¾åaF +ÌfŸiÎÑ)ålömt°6mñ€ðÎÀ“6øLMÞÂûØÎ(lSËeD‘ éGH«þjjŸ¸gá0eƒˆÔ*m*ÊØà²EµŒ?+L.‰¡†¹ãª+8myXÛ%¹XJf!#JÝ?¨ùs±®c‚À#ÑÜ )êö¹\· ¾NMnÕ}cð OÚ‚gä·<í›D«K…Ÿ yøšqså¾€N ¦“;⢙éH™[ÿ™R³ŽnE¥]ž Ýã9LšsM°äsP_KÇ®…§ +Œâ&Uª' oN /ˇbI´Ç¦íø€c÷HB€y¹ž‚O÷€''kÃËÀÚÀwûö5‘aŸxd͌ܥ'NIÊ“?5ój:>–ŠÍŠánªhhH ؉˜5ÛdÇ»ïÖ=P7ã->«Õ’œGfÈßfš½šçÚ»9 ׈Ô=/_Q×%ü# +y] ½û• UvI˜R¤NN®;â⪠nÕЬ†ñjø­*,ü¶ÊlP›Ä§ÖNnßÐÕþwI$àáys÷Šwï/¹õîWnÐ&bßí…µ“ÓËþz´³~=~Œ_ÊR\Ï…œÐ’ðÝç¾§µŠøé÷xÃgöDñG†© ÓCƒ7›hjUõ¼Âìe˜‹Ž;“g-†¡Öiy‚eÓ|Ú¬XÂbĽ¡¯ÙÑ%‚uæÇ‚·žsºVq~w}3½|óæV\Þ~¸È•‡š'HwIþ¤s×õÍ=ú¥ƒ •Ñ)ä¹'ò©Óát*0mÏÛÓ—½:"‡3 Åæ1©g_긊0àû@‘¡Ø×(×®%„ÕÁÓ!Äç9D€–źåÍqÑOÄä‚×øu>çŒÆã_æánB#€æ \÷·%ãTÙ&"ß^j~u¨iïýR)>B¦Ýnv¶jÚ¶êËÎÏÅrS2º‚ODnH'Lgr(çÈÀÀ„"O!vÙLÿ!.Xk‘*s¢ör†lϵÅìsµœÏŠõþÝ‹J…¢ñ¨øÀ?2¾H#ùT(m¶7Ð4*”f eÆ`‡&ÅvhÔM=¥â·x ðz¶Î91 Nš”%.ŽçrÔä"sP¸ŽÕÏ ìŠ®0Ž=ûÃ6D²åsñ¾¿å×ÀB>8tFàÝ«ºÇݦw芗ÏM ”å>(©pÆ¡1\1QžŠnöHÕªW jÕª{|"è˜1ˆ™hCÎ?Ç„-Á«#X—iðZô—“¸´<ßCÐéÓæ~†’¶^^¤¡Jg"ÍÔñ;K#r£óq +SE½±ò¼Ç +4=V°og¯¡k„•b*‘J»“hÑ}JÛnØ©ô@·¦>||áˆ@Z¨Oßב㸶Ƿª»òv÷eÿüByžØãòSDþøü&B¹TøP®Á¶U :\gÈxšbN4Dµ¶Zz¯zK]þÜÃ3@û„pרKÇv” ‰ P}„ƒ'Ÿ Ù'kt„H]êÆ0ßK£ð&vø´V|ñ/‡‘ŽÞKjR•/}òKPÄ‘ÑÙ)+ÖAql=,7%Ø“¢üRµ<” ­±&Á⦣û¼Ýܪ?ˆ`ª-]Jær› Ûܨû &p4õò…º«zÊ{ +äa-…ö> úüVyÿ =h±Eßlºi³è§ÉÓD–°icbp"¥ÞgN½D?ë¾ÓpþË•8 ü$˜¶J"'xM£’ÈÞa'¯ºÃrø±\6ÏDíš3.ˆÀ‹ƒÖÖ(‰z¶FÁ£xØæNäRçcØé6Ùú#‘¿“„’RÖ3.ûãíCv4òû÷ yúËÔøI +ãäW8ù“¦ Z™©üë°gí¹†ÉütæË“½ÏªJ˜–pT~ÏQ`ìZ3a²ÜŒ5ˆ^¸çª$¤‹ï¿33Úf£kw8ü îÑ„Ç+:>§sÊçÕg¯ýɶì?Ò¸§`¯ì쨌p\ûùõÍ廫;¾ÍÁϿκø¡> E ¥E–*ýmuÄ!P%VXrT®#  +\Û kן¢ê¸üÀ‘Á”+pSÚ¸oì¢B*u ©4R€T¦¤€H÷qn )¶@й+ 2®únÂJlˆ¼‡++wóöÿ3®dª„KsWC®Ã¸ê¹¸‚bþ½/9NÈD©ãâ{®ˆüñ—-ñb¤Àh×M:YQBH…‡ÉFYŸá¤ }E}|O­ª›Þ1¬Ç“9ÈÙç@”†â¨ÛæhÐÑ)”rÒ}Kmqx'¡˜Ís}j'\Gv2pù|­\7Óº™¶M1íºå~B¯„5VW çŠh0ÞË ÂIšUཔ!í6PÜ@éçw¨Å¦{ÄZ²À_¥ ?0<ôor÷;’üÅ_%¼¿$Bø&ê©ä<í‘'¼¿ÿ‰(>’áãpÊê­ÈU&eõÃßà*Â…zµûñ8,‰³¦q³û+‰¿è†µùölGAŠ¥¬û'pçr¡´> endobj +1299 0 obj << +/D [1297 0 R /XYZ 56.6929 794.5015 null] >> endobj 1296 0 obj << -/D [1294 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1293 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F63 1053 0 R /F62 1050 0 R /F48 940 0 R >> -/XObject << /Im2 1039 0 R >> +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1302 0 obj << -/Length 2626 +/Length 3178 /Filter /FlateDecode >> stream -xÚ­]sÛ6òÝ¿B÷tòMˆà“É“›Ø=w7q}ssÓö–èHc‰tDÙ®çæþûíbIQŽ3éøAàb±X,öV jâR‘º˜d…N*7™­ää3Ìýx¤' HI뇫£×g&›¢Hu:¹ºéÐÊ…Ìs5¹šÿ6M…Ç@ANßýrqvþã¿.OŽ3;½:ÿåâ8ÑNNÏÎ>¥Ñ—'>œ\'*wjúîŸ'¯N/i*e?œ_¼'HA?ˆ^žž^ž^¼;=þãê§£Ó«x–îy•4x/G¿ý!'s8öOGR˜"w“GøB…ž¬¬3ÂYcduôëѧH°3ë—ŽÉϺ\8mÓIb¬Èaÿq)+‘)H™+Dj´‰RÖjLÊ ¥|½*g·‹fU Ï«¤NÁÖ]¢{[G¬‘½Mgo%Sa 7Øü×»j¶ü]J]µÇ‰ÑzZÒÏjÙniÔÜðÄ|¾9Vù´jÛ€»]”Û0ªhÐV›‡jCãÇåjE£ºa¼r6«îxüå¾Ú,©O»YóžLá¾õdÍtÛ€9hVU`„6I4ÜM‘Z†…sÚŸ 7x:VJMA’ÓOaGT³ÝŽøÀ½p88(‚è$8ò'ÁÁ5c3ê]SÏ«9Ójx¿«#Í«›ò~Å+—-òüúÌæÛ1&6“Ü)²^7uEX½;ÔF¨ù„$£«a‰ÉÁjó õµ­V&Z²J…û”RNÏëmµ¹)gU;²‰qf §)-¥CjºÜ-‚o}=§‰»f³miH³Û°,hŽYŽ~qû Qð£s-€¶.ŸìÅ €6ê+o~ß.ëÏaójD"V¡œS,4TìªNšzääIÄíéQs·]6õ˜´M*réò¶F¤¹eÄmyëõÞ(ýÒ%Ú‹‘^¢¯`èI™1Imº (“Ÿ¹f¨º ¶CGbø°\å“4ÍÁôí‹\§EžçãŽ3‰“.Iïtzü Î)“éngds]ng‹=&ÒÒýuLŠ_cÒ9!-ÜzIï¿n‚ h Ù^Rt&(;ŽH1ø¢kºâ&½ë/&tª]_çzÆæD`œH|ç·¼[š§0*^bBZäY0Ûm¹­ÖU½ "ô¤ÅÇ>Ãp‚àêÏr \¼1¤$‡TM™ùÖv’ÜæéljTd"K_ÿ{Oܹ¿ÁJ’Ž”6¶Gío -|³–ÉÁ×k•öhïûgéFjHOù …ªêòz…È «ër͠舊|!Œo þVrÓ0J¤pþ‘fúJ†KH¨ YÁá`”6a˜L ¤¬ФÅ6øò¡X×ål±¬ù–—5kmÅš ² †QÒl–ö¨šû¨›E3Í ûÍzØ·¨h½ñbzFœŽ›ú†™2,;ÿø`ƒx‚ ¡Ã&©Y†¥@WůFƒ&`ÈÔî6yHGŒY­2™"°`Yú¦ðŽ ˜È!Ä‹ãæ‰^Vö½ž :1r ËG‡ßÇÅòXM½»ëÒŠR…U,UÛ‘*@QÕ½`2Ðä,˃ª)öÀ³fM¹óK7ulÁí1@ðé@«HÂÿ^Tc¡{€ÅÞ ¬Ÿ‚í›~W_½xe6HŠd>-y"fD½3Èî¤-žÏTÆ É$Ixþîp)&]’ûáXe…ÈÀìv>˜3h%…VFýuLFŠ_ap„–ªè3y(gp¢ÈÒ&’‡íÞN?§„€hz±éAVœõLÝ‹JÙP;‚!€bÌ›ŠUƒ"€®1µŠ–Ü•ˆ¯\\¥…°«Û®+n›Ù­w¼&g«7^z3„Z¢MÓgßãÖU“M—L‹Y„ ŠˆY&vÃ.˜\sW£d„ðÙ>¸Ö4^”L§ª›ûÏÌ×ÉÇsƼ¿óÞ´dTç‚ ¤ñ!r9ý]:­lÎö‰0WJh)Õ›ùuþæÍk£ßŽïð’jÂH« #¹@ UŠ: -P¯–#Ö‚é)B¼æ!¸ ÛÌ m &ÑÍ>.· F ¦X‘ž_£Y¯çè8ÑÄN âjD Ä£*‹OÖk4Bˆ7 xC$ò,8¹dˆ¡PÓ¯ÎÜÑb´¯?iªw3Ú—D[öst*ÞÇ ¡d¾8òÙP5‹^]׎b³£«ãBO›Ð*¸­ž)Hbá4Vø[ Éï!?‚Mܯ¦¿ ;¡ß ¿>ŒYu°„ˤ{¹HµÎ÷ªEŽÌî•t64=m§éiU§ø YÚ]ChWÆ(–¥²´j+ÁÔ}½âT}˜4* ² y`2vHlÓÂÙnYŠŒvâ€Oö¬JkúVó¸ þ•ñÀw$µ§ eýÐÜz'é\Ž70ROêT˜<–?…Ud·lFÚ½8…›n÷91±Õf:­6Í­¶ÐˆÀ‘wKðÛ0F–±Wò‡Ù• ø áÉË;­þž±qc¬7,G;ð)wà?ù· -»ìùN<ê¶ vj:vŠ}bL›ë¿oiâ¶n¸¡áî ÷–éjÛ– “9ŸkšØŠ`d—4òʱ òÑŽvÈ +ŒŽ6ç)%ms¿™½o$½ŸËô©R®mLêú‚3äýaÀ—8Ô|@E#´÷>û‚I®ëAwS—Q€G„ÝÛbûr±7À8Ÿ5äõCïq–“°x—£íkÈÞsËfÜ%…>…ì=Kø+µ:k…ÌÍ~? ‹OO¹êx†}JP‘[çãc¬a=p†‘­;Ü,Û[‚ „4”Óïw=)DÝõr»%×IâÂÉ~€G4ß~L‡­Bà.cN^¦PÙGGw~qòþýå°qçÚ€à³Lè,UßÝ7ˆ“Åý`›[¡ÁïÆ}}rñŸ±¦Ë·éN¤Š´“@ ºUÏ4ãÇžÐøî=òž,'A'¿ûy}÷¿6Cï¯Ç¦u–ƒþf -ãìçØ˜1©aýÿˆdM3endstream +xÚ¥ZÝsÛ8Ï_á·Ufj­ø¥Çn›ö²½íöœtnvv÷A¶e[YÊZrr¹¿þ¤%YNæî¦Ó’AºbÁ1KM©LÏ’L‡&f¶Ú_E³-Œ}¾Ì3wLó>×O÷W?~RÉ, ³XƳûMo­4ŒÒTÌî׿þöþÛýÍâz.MÄáõÜÄQðÓí×Dɨùðë×O·Ÿ¿/Þ_':¸¿ýõ+‘7Ÿn7_?Ü\ÏEjÌ—¼Â… Ÿnÿ~C½Ï‹÷¿üò~qýçýÏW7÷þ,ýóŠHáAþºúýÏh¶†cÿ|…*KÍì>¢Pd™œí¯´Q¡ÑJ9Juuwõ¿`oÔNÒŸ6ih¤Žgs¥Ã4†5&µ…‘­Í“…±’ÊkYŠ)-;.ÔòñqwÅ|µ+Vó‡öa|l›0±˜õ×>“ÀsMˆ z"ˆ$ +“,ÉðÏ]Qƒîe®EÛ¢.yWÖ[ ª(èv /w·Ÿ["nšªjž‰†r¢~ÿö‘.ö¦¿à_Ç¢íx­fÀß«#ñùßM]¼Ã!X• :fó8 +ÁˆÀŒ…3c¤•š¤ÊLðåî vtðG©|KĦ¦Ös}üz÷åæ7b\,x°¡v]tÅa_Ö —7·l©÷P¼ÐP»kŽÕšˆK^ùØku뱋‘V}¡=R4<Ë=í¤Ìé *­ÜÖ )iÍ€•½òà3?}ÄAÝtDõâbÁK.›nG½ç’zq×ë©9vL%(9¤ÞýŽwX›üXñ. +œkdñÎ(#)á¸xÊ—Â1 lR‡™V)ó„g~ÏΕD:Ô—üôä=®W<ÐqY;:¼Ì»ÕãüPlE»;s@ø ._ÀsMH08¬1¡HpEÁ,LR¢ )€AºË 5  ¢î±ƒ~B|ÇÖú ï?|£ÚŽ}ÿÈpÀC Ú·›¼¬à.c!ƒO`W–F¸ŽsR"¬šý#@À²¬ÊîåZ€[ª$¶"X§Ôp’8ÚñÉ$`¥i“P¡qüßZÄh•yªBƒ¶UšÔŒaŒð„œ(ŠðlÏùaÚ9ßüOÆa)ç¨Í(TÃI¨ó5©52 ¯iÁr¬òšÈKžBî{uÈB—f¿s®há-SÛpÿ¹\4ºÊWNˆ†wÈY¦â™g‡§âÐâE­ë㊅«9ä$†ÈÕf(¤70XuTeýÐR×J­² ø€`WD­ó}A=ÞÃw’·QI ÐÉ«¶¡Þ’'€B®E°î­nÙ ZP÷dŒ8é…vç]xÒ.çmÖ<Ý¢vvùS1… ë’ô±B>™ùjU´-õ­ 2eïÂmG-:Ô¤Žƒå±#†çÒ:šŸ’UÓq&@á¶ _ò:à îŽç]¹ÚQ—‚Œq×å=ж  “aÍCÙg?1?¡¾AUcv«ìáòyÝ>ûåkn;žhmø"‚Cöþg²×¼ÏuÁ=ꉜv}†ÜR„&Ùë{®‰ xa ¤‹ƒ­)p«LÍcWZÇÍDàitÁ@Ùy 6°9V4b:s€„ð­*1kê/Hn„bÿØy[K þ¾'úS^yÅfC¸§ûúS1ž6chÝ”Øáe¦©ç/Ñèø#¨-‡ØÂÐÉ[ É[(€Vó±ãM3¦0‡-öˈo¬ ¤!¦l‰R&Ô#ë)äÑ"93¡=×?tŽÍ¶¿MKáÒÞM;r¥æ$uª ªŠ¨åÌÐ#ˆÀQòËÔœæúma¼¤¨6p]Zèàvêr¤0a"½Þ­õL\N&:ÖÌd]¥|,V%*©Xãdê­mbÔx}x9Én¯YjêD«¡Z†wsÑ×u¦Â4I^wõÓeOwL=GG£û:Ög âkû:žó}~®Àø!•l|çµk gCàe·ßˆ¯×œªµž§!ª„¯J&FéÚ>÷níS6Å0Ø™ ÀÒ(°÷Gd¢š÷ÝPÑ0çë´>=ºÍÞæ0S„îæ!3‚m.2ȲRb3) %Ø¡${ö°8ÔÔ¨¯íñT¸H®Ê¤Íl°y¤òe¾nöyÉC˼-ÛwTæ½Ó°Ö¤s/èl«f‰ žÉG˜Üò¬fÊÍ­¼±²©Ñ¡\¯­W€Yq€žSó”Cøµê†±fCD÷˜aÖüÛ5"î‘è¤`l‹Ž(ù¡+WGÌí7¸%.‚Beó&-m·áâ®îˆoèzh!W<Ðày^D°œsp?[r"5OÂÄDX\PµÓ,~t|I© c¹2oY€0˜!%c‡e½³p^á2”ªzç™bìå*NñÉÜ\¥‚ʾrÐàa;£Î¢çñžÞŸpîóçëZ§‡dÒ†tz“¡4c .¢Î’@ç¯HŽë 1ÎW»Xÿ(çD5Y)®€>ójÞvùêÎpÇ9ö›åP¢R\x`ŒhéÛ?4à×?øþÐö؉×XgAb•Ûd(Œ“Í¡£*@LðÜúë7ÇzM߸·%-«bÏ» ‡bËÅÖj—/]™‹­,ž‹g#¿¯¼V¬7£½­Lƒ»(í#‹íß~{ÒC{Jì4uwhª·£Ÿ¤%iO»,¾¸€>å=0ºäA¶çîP®:{F A~G]AºÔò´˜M¦õ ™¦‹Ñ'NÑÿ]²=å¥íŠ=&d`ÖwçÙƒNu¨U¦fZB%åÙƒçŸ÷'L„í³u‡ÙˆFб<¢¼Ie2ç |=×R¸ 䱯—؆‹./«vhÂ;|뻄­!7/.´±Ÿ îÂÚxÛ].üDš`*¿Ìú\—ƒ™ç²>ŒµÀH”pÆÀGtš¼±»çšØ~øü §£ý‡% þñMJ˜zú èVfª}¸„–`ø&éßF8eÆçDâh+À?&Y/îñG!é©·N ª $ÞXiM1”ãßÎ0à¤.¾@‡O€Þò4WÙî%KÃÌ¿NŒïc¤Ä8 +•P†™÷ù ­Î¯Å)GAh{D°yËv.ƒP2Œ´v? X¹'ÞHL¨g‚€ÀE}É’~¾A쮕X_—I&’a-mì–®L´I|v‰'Å„L(‰3w|_‡âœ7JqœŒEÇT$1ôüžHÎ:ü #ô/Œ ¿1Øý¨±†D]Tš[oC$,ÌìññâLÅrh/£×¥~üÿä3@”GÊÚOAÇ?æÅ@Í·E{*19÷¦IûAœF™h]B&оr†d„ðÆTŸër\'³§WË3›O…~}sÏ5±û…ð÷5ÀýÁöC:Ù0ä…ÐÍ< +ý„B)¥š–Ø>¡qo&9½føƒ1 ¹÷ÑI0™¡Ç¡hJ/£Ã˜4”"–}4 ÈëRÀ–Hˆ‰Ç¸æF ÁB´Ó‘JXKgo@„€òhÖ‡™F~§ÞDDÐîµ xÿ .Ë#R ÜZÑg¼®7бâ Xg +íxô»=µü¯¾Ë¿Øÿú4tOûžÌõîDZàêRäé×øË7þÿžÓwÒ øXz!SRQ¦2KœP¨5£.fgç¢ÿÓÅh|endstream endobj 1301 0 obj << /Type /Page /Contents 1302 0 R /Resources 1300 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1273 0 R ->> endobj -1303 0 obj << -/D [1301 0 R /XYZ 56.6929 794.5015 null] ->> endobj -366 0 obj << -/D [1301 0 R /XYZ 56.6929 725.2846 null] ->> endobj -1304 0 obj << -/D [1301 0 R /XYZ 56.6929 700.2184 null] ->> endobj -370 0 obj << -/D [1301 0 R /XYZ 56.6929 148.5316 null] +/Parent 1280 0 R +/Annots [ 1305 0 R 1308 0 R ] >> endobj 1305 0 obj << -/D [1301 0 R /XYZ 56.6929 118.3446 null] ->> endobj -1300 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F48 940 0 R /F41 925 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1308 0 obj << -/Length 2999 -/Filter /FlateDecode ->> -stream -xÚ­ZÝsÛ¸÷_¡·Òˆ‡Olžr‰“úæ.ISg¦3w÷@I”͉D2"e'íôï.vA‘2e;I'3!´X,‹ýø°œ ø'gÎÆBgf–f&¶BÚÙr{&f×Ð÷æL2Ï<0͇\?_ýôZ§³,Ε̮ÖY.ÎÉÙÕê÷èåß_¼¿ºøp>WVDI|>·‰ˆ~¾|ûŠ(}^¾{ûúòÍÇ/ÎS]]¾{Kä¯/>\¼}yq>—ÎJ¯X‰¯/½ Ö›/~ûíŇó?¯~9»¸ê×2\¯òùì÷?ÅlËþåLÄ:svv?D,³LͶgÆêØ­esöϳô½~è”ý¬v±u*0 ÒS´YœhèB^®q À)œÐo\Ò‘£©wó ¥)§™fž²"E,²$c–¿NÈHaQ©d†z¦ÍÊ‚oÕÛ²ëŠÕ³ó¹–2Ê©s—W«zK ͹ŒP7ÿ£ÚoKXïÎ¥‹l<±˜/ëê!Ôõž~¯ˆ ä^ãù›rù‰º]´oXVÅ„»r³!Ò¢À…ÍæÆÅ™¶Él.eœY«üšöm°¦å¥Q‘/oˆôy_쾞KXxlttuÃ*4¼¬”ôúCXÑÂr¨`u7yG”¶)–%®*ÌVV¥˜Ø•ÚX»Ä°áAÉù­™ïWÍ'n'6ʉØhvõY‡íº|k‚n©7Ðý ð¼Ôêá|ɜͦDì²c³=  -ØY(cUÑJ¢* ©¢•Šê¦+ëªEÿÑYT|Ynö«²º¦N4Œã ÜqdFìD3î 3ZKg‚ƒç·u¹zÌ™€Ð2ÁòÓÖ‹ˆ$KÇb{{ATeJÛ`0ù¸Á ʤR!Êz«`£Àuwåm± ÞH3ñ¸¹Ìbi!ãprQ¹*Öù~Óµô«^ÓwÚPÎÄ©•!νÛÏÛz¿[ê&W„{Ð@ ¶©™všJ3rh26雓þFƒÌp’¹22Ö‰²cŒ´Ÿ'd¬V»¢õ–ŸIS)H‹sX…]ê3ß,ø÷ #dÖ™ÊbçÒlb”³4M†ƒžÓîÈTÇ/P“–¸¯žÑ±IÏcNigÒΜÐδ;2?ØOÆÊ(-¡,ºì¡Êc¥“ß”˜ÀI%dÂ[T¬dš“ÏÓeúlël´¯éáÙT’K†IµÊ·ÅjB¸Ö±ÓIðo.# ~yS,?a3‰Ê5‘|ŽÂFÝ»¼ó¹ ûÛ¯mWl©‹ªZÍÉŒ Hà89Ü–+Ÿá´ÅZ¨µ £®wùvK)úʪ+ ¢îÖ9z6Rºš¾$Ý®„îâ6tÞpë=Û¿ð$œx,äWF¿(UC£hnŠ-Ôk(ì¢øÝððË kx=Û=ÖJ¯xåW(Æ*³¾ -€šßª˜oór“/6ÅÔ6e¡ibߦT93Þ&˜܇æ Íʲޅ,ZWT`°¿ß$`é ‚¾à<ÇÝK£¤ìîʶÀtìDT2ÏÄ|%¹*¬ÂQ “-QßUã¼<•ÒÄ8•Ý /Ÿ/þCDØ”Po©•X«ísjÿ÷ùxGätx}‡Ì£­ã´ñ¶î _nH¢mþ ýJ¤à(´øË±k -w(îÐ^0­Ý¯‘ãxYUEÏÓ7T ®Y"y*òËý®ì@Í™èuAXaHìÐÕ˜¹üwúš¢ZñÜuEßÛ|WÖ{&6ù|ʧ!& ðj_¡Œ{ô 0wè¬ lPm$Óº—õv[xl -%¤Ûå ¡sSä-÷ËD;CMÞ+d@D%™¼(‰šQ‡^0åŽæ+"­—’ø=ái6mM-N'<„G†4†IÒó F + q ßÝKKÜ÷¯Ô¹`Q]]¡Ýæ>r€FU"öyHÍ~×ÔlJ3–—=ŽF9A·6/Ý” Ì­H!+AÚ+¼¦o[o™ œ¢×˜X|É· #lh%ŽpüÇ·—ÿÂWœ#[úÁ¨ZUÝQâ¹¾›Ä¼ÖÞØY%’t´öŠ ŒŸ¯»©÷a&ú!ÂôÍ®¼…<ç} 2*Æ(’ ´`?—hnð â[àòµø -"=âó FÄG8‚Úʱ³³@­ìÁµäWáéžr…åc» !eöÆ9º5@¸ÚÁñ·X…›€EG]¸§H ›Oòà‚ÑùðhXÞÁ>6ŒáŽ -í«€[ŸÑ•˃’Hâ ·dÁ]õfOFrJl‰ð˪Øäð¢(Ó¢8fìB aÅ<€¨r‹KÍ+æöù¾Çùw¸R¶ξf²ãñ¢¹èBzXæ ]œXÚ|]„dtH,eu” ¥ú}ã|3̾»º-É[+€FÝdâù?Üf<éÖÇAS«o¸Óè/}ž,õé×NCÂ;¾Ö˜X!÷c˜¯Né7d?…àÝ(ÝgýM½È"8øÇ1î4cÌÕ~IÈäÔVà}†„Ä *û˜C@­z3}'\ŸïÉléYÂ)&³fúR2ýÄèì´,'@7ȱ¨Ãc=ÔQg…¤Ïû¾Ê¦x‘(^*üƒÜf€%ôHl+sr{0BFWð¿Š.Ž 2ͤLc©éu}öy&ca2ÿ-Fm¿Ôƒ <á§Ë­š½ªaA³Áš‚àùP²_T¢F‡ª4©4œ,úÇÐ~xhz|â0þ„Bß¾Ô$£HÓÊG– j EDuá\JÆ%i¬tÿš¼ÌOÇz~FÊú\ (À 8žSëã«÷Äɰ]]ÂÎ=®ãW/ßã ÝÝ©@uÏ3z”X ’þ°xx¹0XN@: ¢ÓeSK}uå‹•£w¤x]p<}B’¼¹CÆù•'Àb7…]ñBÝŸ¢ü­ˆGn)ž|–IGÚ‘ûÜ‹S“¥q¢q}$¤?[Åÿbb~økŽ|k±ÄMÑGìÿÊ!/à³±s'*ІüèT–δQǖíÿ …¹ªÿ˜5@_endstream -endobj -1307 0 obj << -/Type /Page -/Contents 1308 0 R -/Resources 1306 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1310 0 R ->> endobj -1309 0 obj << -/D [1307 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1306 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F41 925 0 R /F62 1050 0 R /F63 1053 0 R >> -/XObject << /Im2 1039 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1313 0 obj << -/Length 2984 -/Filter /FlateDecode ->> -stream -xÚÝZÝÛ6ß¿Âo•šå‡(‘i²ÉmqÝäwm´¶¼"KKÎvû×ß ‡”%[ò¦— ¬Fä3äü惔Ōߘé„%VÚYjc¦¹Ð³ÕîŠÏî¡ïÍ•ð<‹À´èsý¸¼úáµJg–ÙD&³å¦7—aÜ1[®‰&ÙfàÑË··¯oÞüóý‹yGË›··ó…ÔÒ辬ﲒšÊ¢i‰r†„Þ›wžã\˜’#O=‹‰ªl—ÕäûÏ„"é Oci¤Á°åš¼ò ·o—7¯ÿMô$d÷¹spˆ6ÒÆ:Ö·y•v™ªR\ÄðWoK­«úá‰(‚¤xåî9•Ð…hÍ×ßc¢7Þ‰\)P ¤èü¨7Ëq­ð‚û–¯‰#ŒÈûÎKºý0æ ¤úªvÏ5àr+ÈJ[ÔOZmóòÁ“ÎðÌ«æ¶UZáw{`åEî¹qínÔÖ³¡.¾ï±(K¢>ŠÕGç/nx…[ 3ßç~’ŠÆÂ³²ÝR£_¾Wõf3¶¬¬òQ­ïBõòlj?œ€<Í$Ry^¦„Dí¶6ó¾øœW¾É?³‰%ÒcVsÖ?—%áDb“¥Œ’;Àç÷8-Ô¢-Iô{‚jXý¾Xçô†û;¶TG±ØúI -½¸r™ßp{ª #§PæÕF½â_[·Vn‚J™ÐÊö7ÁñNo>TÝ<‰OU QLE ‰¶‘i$3R«®V‘ *° ò8 U¹àã4 >N·Ö¯ccV€+îVò ä Yà k9˜=8‹Û0o…Ú -¶t€ù»³h¯€ -Á é.¸ù ¶™.kYê4Ñ­óMv(=CÑœ$Ç|÷ÐúTçÕêW®yå_ˆïHãº1¬2Šlað‹élÈ¢1~&ö¸.dÃÀ…{µË~_„dŒæ]´Å._ÕYjÔP³›Ëzxž5pTëD¨¡7ÕT0îh‡ìT¿*2 -‚´‰UEçGè.ëêžNŸˆÂ¬ -[cX]õD#wEuhsßLHBê.ÈÉ÷»bA Jè*Ò!¦*ð½õ¡BHîD4H"·P©7díát`‹bwØÑËç¬<äÙ¥ñb³§Þ¬1W'/"IAYœè©{®€¤>×4’:®Q$ërIqÊ ÔP—5é¸FT¢I²Ô -3Ôåˆ&Ñ¡I Ñ$ I@£§âóÁé^߇XG­®ž²D‡,¡qÓ¡¨÷à‚w.áÁ%NÀ% ÇIù¿‚+™Â–8bëÿ-‘2-éBî´z\ ¸¦ƒT}hÏ£œÒ…—Ué¸Ft`+cqDj_™·‡Öƒ «ŸÅ±*í¦àµªð½øhå¸]´"*ÔR„)Guæí<‚éÊ2͹Ö!™h%ñ:ÄÒmÝ4¤ú\Ó긦£Õ(¤ XŽí3ªt\#º ÕaJñeŽR<@Jq>ˆW\ãÐ.^Ás$^Á@¯xÀuñжæˆ!ßãã'x¹Q~K<À–BF,˜ä¯³$œd?sÍÐ纰Àåªõ|_dåâÓ!ß?-öxás -,…ûyYÏ3"*•0« ¢(ð¡Ì>ãŽ)y<'KÕ…h~ëu±ÊJwð„>§-uuÁ -š{ã%~áéî1ÖÄ€~ã‹ 5ø°H²‹Ì ¬»;Ï›   qpµ%ðVíÞ!,–It­¶ÔÞ”ò@g 2zé}“¿“†®T°Jwœ®ì$Ò*ç‹4޾ó³UyûXï?ÒË]V­‹u»eÃ6…Üå܉8!ừ:$µm@;-°@3/¬/@¤á3ðØÞ”ÍÉœV4»÷¸ÅÆ•Ÿwˆî!¥»ª€—Ædá0e¼¿7¹ØÈ‚S—O°e´áŒ:†ú¸¦)€Tä¸j!"—9Þ$´9fJ°„ïq>ÏýÕ²ƒ¸"Ž ìqí\„“ w˜M«ºZ3:Á.iex·§˜Ñúä@9Ö$Ÿ *xÄ‘)¦ÆîsM•Žëd{ ºžDaXòŒtÏ3"|Q¤bI e ýÍ#m§4‘Aó(5ŒDÃá<œOè~"4‰™Œãx HW Ì-Góãåg0?t8óCwuØäíÝ4>ÑŸß”ägqÈͧ”9ÂH)ˆ$xÛíî¡ÇÝFÂÓeMxB lZphJÑÈÝRe^ ü]öa‹_ôS¾)@¿¥‡ÿŒ -}FvPœØ­—Výõf,$ 4"¯÷p\ ǃÎ}UûRâkFîs ˜Öv×J_bZÁe20­?7ÞiRÜ“tÉ7wáz t9 w1†;ˆutK[8Y¥'žÛ]Ñ—‹Ÿ&ºP8¸%ÊšPÅÐýš^M÷cb7RÃ4lÉŸ‹iœš“ ™'Æ2‰éýb4é1M“ÀÔÿøãJ½M½ße絯Ô0N©‹tLç* ‹Îüh××¾Ä «û¥.¾®0 qçûÉJHys¸A5k¨;`~5+­ªù~,k©”‡¼z,@G˜`äB2ójqúIöÄ#˜áîË(.ª'?ߨ;hH2;øe(sðŽtˆßå8à` ãN¡ Cž"N0˜³èªOh©+?¨%ôxï1ÇbP§]™äjz®sw$­<;¹¥ãöú ÿ[®éÃßé¹@£˜žMüÖpƒ(×Ãð6i/(‡%þ´‰¦¡ÚP¹eaè¥^Ý~ L­®4ÀVkú¸ã¾âv­á [O}ë±5Ið=Ð?þBdX‹îîû![}ôº»ÏÍ Ñã&~Ò¥4ÃßX8)ï~¦ñÕ?÷:~†S¦Œ‘ãî.!&Æ&ñJártrá8ƒDލþ_r›Äÿendstream -endobj -1312 0 obj << -/Type /Page -/Contents 1313 0 R -/Resources 1311 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1310 0 R ->> endobj -1314 0 obj << -/D [1312 0 R /XYZ 56.6929 794.5015 null] ->> endobj -374 0 obj << -/D [1312 0 R /XYZ 56.6929 573.6377 null] ->> endobj -1061 0 obj << -/D [1312 0 R /XYZ 56.6929 551.8981 null] ->> endobj -1311 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F62 1050 0 R /F63 1053 0 R /F21 702 0 R >> -/XObject << /Im2 1039 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1317 0 obj << -/Length 3275 -/Filter /FlateDecode ->> -stream -xÚÅ]sÛ6òÝ¿Bo'ÏD,¾?ÓÄé¹sMs©;7sm(‰²9•HU¤ìº¿¾»X€"%JN&¹¹ñŒ¹Àb±ßŸ0øã§3&½šX¯2͸ž,6Wlrcß]ñˆ3KH³>Ö·wWß¼“vâ3o„™Ü­zk¹Œ9Ç'wË_¦oþùúÃÝÍÇë™Ðlj²ë™6lúííû·ÔãéóæÇ÷ïn¿ûùãëk«¦w·?¾§î7ïn>Þ¼ss=ãNs˜/â -g&¼»ý× Aß}|ýï?^ÿv÷ýÕÍ]w–þy9“x?®~ùM–pìï¯X&½Ó“'h°Œ{/&›+¥e¦•”©g}õÓÕ¿»{£aêÿ´t™vÂŽ0PÈ9X™‰Õ>3†»kî¦ESï°(àxÜÆÞE¾Ë†:óøÝÖMSÎ×µ¬Ú:ŽÓgS4M~_dÈ €÷)ð"ƒ›ƒÓ„½7yõ<Ë«æ©Ø5»O¯{æÒGä2î¾!¢âîÅ -¿2&eQµ¯ WÈé|ßFâ⤺Z?Ôì·Ûz×KÜp2†eÎk1™qžy î5dÉYdÃ:oËÇÌO«â‰›uþXD°Ø=Â`w)l±x ~äÎ!Äptê1—ý‘«%‡1•ùLSg]=åñ6@F•óÓ»‡b„ÅÒûÌiåû,¦£v#ƒ£žg¿ô fZÇ…Võn“#W™ ®Â7_7xõLö¸øbCíÊE誛z»þs­5Èв~jh©*"~ÂA…Wá wY¬òýú@ÄÈéá:­|ñôü¥ÓÛŒYfãBc¬3m=í–Zát³È«ÓE-ÏT7e“?“-™ô­áÌ»r¹,ªØŽßœ>Û¸:1'NÍ›pÆÕöMYÝØŽJˆ&“:QWaØ#cÒõ7mÞ¸ÈìÄ䱌i°ÆÆËL)æÆM|Dšõ±ÈBñßaõYÛÌÊêxs×d·—wï°F¶H%ÀÊáöAúP­7ùŸåf¿¡FµßÌñ®Wô-«y½J ¿ê*ÎëèÍT#„yEÀ 0ª¶H…ê©¢“ -á@P!泯BˆzF…Hs€XkŽ\ÿæá“I-Zâ}Ñ´Mú. â‰÷¿:¾ÿrS¶>•ëõÐàÓš«}S,3òòwiÞÁÕA#jpØtLƒ%‰Ìsñ9*|F -µ7™R\–Â>Öy)ì°†R˜üXÕœ£6™uÞ\¦¢Ã!cpbÃ3k™ÒAæì ŒØHÂ( è -wÈÙÁœcƒd¡ž,†æEEQ±k1Odo0& °8ŽLV(!}žBøÜCZHËnê¶ 6†ME µðñȾ/Tþ TþŒP ¥ ”âÉ/ˆ1›ykMÏ+HöI^¸åO¼ÂP,Ž'NÎÙAä„G Þ!*3ßm¢Ûà3@ãÉgp1â3`4ø ì"z~ðÂFŸeKxä°‡üt ½CoK½"¡wPÓ¿D K ¤ô.ñ”‡lxÊOe"¸XÝ‹‘t'(úpr~b¿9 ‡Ÿa*…Ÿ|&´~b×™ðSAN#<€‚ÁëåæöaGÌEÚV´Ûø3 ©£Uz¨Q_-ÒÕV·Æ¼`#{XldÂ:I"0%_§&R€-S/Ña½@×6óLÇÒ\³ÎE®-‹¶ØmJPÐL0O%&Á¦Hòi¾\ÆzCB#Ÿ(£ÑÄo´¹€ê -hR><*‚îÞ| Ô¸*mY“ ãEƒ3É8Rÿ&d¤ÚÑZð]m  À âq4Ùä@\œr°ÿÚÇìÊ%Çî†VVJ‡[H¡£òd0·_mv< lÓcЫp0vœ­zÌ´Þâáóuð*ÐŽkÛéÏo?Pæã¯¨/±Áb?À7)‰»>P'„9»’È6‡=arªA¤õ–Ï`²Êï·KPÌÚ¥€C­¥ªÛáI’6R±Æ« -1còN µÂ…‰`}ðCÁ3Ápù-yÇõ:}É›˜DA/€öÍ>2KÅ {%$‰…®b·ÊqίB¨Åºnfc÷Q"r¨á¸vÌ> Æxq÷ì)à HB¤Í>­™o·E¾£Þ²Šû<ĵ†kK\û£•n2ÍMòÃÀœúiÖiþH1ÎfЉd‹Iüh”©è‚eæ!—:rNR‚¾3«Ø˜T¥€LöHùP*¤™–+B¤¸KÆ¢t€Ï_”X𣠙©È´0–l7M‹ã~B2È…+á\2{‚u¡6él“)p †X‘Ý!à Éᄎù?7ä¡cà±Çsj&üXR v„FbÑF’gFð™ DYï—ä¡; -•iñ¹áF»Ï$t(w–=•íCY]*R)›Y͛ÉOw -›¨­wcgˆ­NÄþŒ®Ã¬OìÖïïKçÀô èÝïw9)vbϺ8 R¹]1™Iãͧ<HÞ6Üøck2cÅ…µhƒµ"˜f —š%ê@…ÁÛ~Õ]òO•HëIOï{LÔâŒðºaHœþñzføôþ‹éÍ g`Q Žo"•ÉÓ!›ü1AR>Ä{l‡Ã˜:¾¹ÝˆÉÛŽ4éŸ*­<ë/ÎjØ|àˆŽYRÌŸê5šUêdCú©ÈtÆ ¤ê<EÄY—! -†že]D|ôu z8dD ;±§h[Ò=hµÆ^R*Ú,>Y{h¬®!ʉ†õÈ·Pd1ŒX\ 6ýÿ¡¥¢N„Py ™DÛ½kþ2Á4 br2;…äñS5Ⱦ§xˆÐ7ÏclZ!™¶©aé;Ì'±±ƒôŸRh`êlDÒ—çоR|™žýŸ# -ÎA¼µ•—R‡uÁ)E,2ÄþýMNýRD!eà—FdViA¿$,ëû%lö^¯ 5¨8YNÙµM‰e1Ͷ¬óKû%æ2λ ø<ލw*S\‰¡o -„û&0M‡ß_ ¶’Z(0ÊNXuü^{6J8&ŒëjÊ—|SŠZ¬Í„5/D6=¤ó2”NíÏåØïÝÀu_¢¤C:%e CDM93 åçð¢í’}p~ LÎõ…Éùž054\ǰháÉISñF0qoâ’]” ý½"¶TÃq®_Äþz¬¾úb™0úJU={*Ö$E5œo®)½¥¶ƒ·Ö( -£;rÈá­ð©Ôð\Œ=W@ÀÂù•iË­ý_$ºTHØl󶜗ë²}Tžû)¡ÔþþoäÎY„|ñÏ ¿ÁT6ÛzæIÜ.(d‘‘(<§¶Ç”w¿G<%ýo -~_õendstream -endobj -1316 0 obj << -/Type /Page -/Contents 1317 0 R -/Resources 1315 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1310 0 R ->> endobj -1318 0 obj << -/D [1316 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1315 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F41 925 0 R /F62 1050 0 R /F63 1053 0 R >> -/XObject << /Im2 1039 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1321 0 obj << -/Length 3347 -/Filter /FlateDecode ->> -stream -xÚ¥ZÝsÛF÷_¡·Ò3»ß\^žÒÄɹÓ:9Ç}¸éõ–(›ITEʪ{sÿû ,EJ´L’s?@‹Åþ,%'þˉu©ËU>Ér“Z!íd¶:“;˜ûp&™f‰¦}ªŸnÎ~|¯³IžæN¹ÉÍ¢Ç˧Â{9¹™ÿž¸T¥çÀA$o?^½¿üðÛõ›óÌ$7—¯Î§ÊŠäýå/Ôúpýæ×_ß\ŸO¥·2yûÏ7Ÿn.®iÊ1Ÿ.¯ÞÑHN'˜^_¼¿¸¾¸z{qþÇÍÏg7ÝZúë•BãBþ<ûý1™Ã²>©Î½ì¡#R™çj²:3V§ÖhG–gŸÏþÕ1ì͆WÇìg¬O­2,©S-­·²L3)(32•ÞÉÎÊJŽY9R¡•×u[-§M½ÛÎÊã5K™¥÷ùžHD/H—J¦yžéÄÃ[º÷–ƒe[‡²z^¶åvU­Ëæ|ª…Iö÷Õì›6YÖ³bI£Èì\ú†©b>ý²i^Á´ŠõœHëM[Õëb¹|¤þoï>Ñ;›zÛ2ñ¾Z2ãÛ !¬Xè4³:ǵ§¹µ*(·kJäê|ÒÖôlÊ ÇeÉÕÇ›Ë÷ÿ¦ÑèQÜ• 8¦s:¹¹¯šèéÉ”»¦å©Í¦,¶Ô®Öij½/Y̲xˆÍrûP¸ô ›³¿ Úå©Tʰ=WEmFì®Ñï´bº¿ë5/݈,uƺáÒgËV*h0é–žAM­ÁÖ#z€ÆÏ{°½Ÿ’+Œèbó4Ë´eb’NµŒÆqM[´åª\·Ü-[ž@3* Á Eî"Ó¯pCg¼gêE\c<h à\¼dÇ:Ìhé4Cš{a¢ÑÈõÁ›¦*óI ;¶­æórÍýðÌ’‚º›28Å4ìl‡3U¹§Wn‹í“·ô¬Ö³ån^­ï¨[ŒØBe€hÖ¸¯·…ÈE¤îÙùï«ö¾âŒ[¬‘¥Ê€ç \(ºØ‘0eR‘åQ¬|d+eê.Œ1ÊÇ©,n÷- ÅÂû ,<ÃiÂÆ¬^ÿGu·Ûˆ 4ˆ#Kpº#|ô2µyn'ÎAÃå_´1Î0 -0ÖOò¢÷ðâf|cÈjµ›ZoRŸ»ìÌzÒÙ~1ñ°™WððTkŸ]õŒh‘ÁÒ"µº€_pá¯JN¢¥wi‘râ„I•09Šžü9Cgr°S êµÃZ6?^®Ôä] +šôÅŒ§}ÎaQN ¢ œXmôP&•™È‚ÊŸë%¢¨´ anž¨Ô¦’š Q2Ͳ*·42¯K¦‡ÃAf·ÙàA4à:F$žÁ=OçZ°Cã®÷ÏÂÍÛOtššzv®Dòÿ  R'>hK•Ïý¤¿Ëßç8<ÂåãL©É÷¹õTå©÷DL8ˆFiÿ| {cžÏc:ªÔš>¸“TF‹ÔJôYŸ¦2L4¢@L¤¶©×V5ø¥ú2†wöd˜Ò~%¸‚m•ŽÔ¯}BDÁ¤à” #VMOŽ›¡s ê5Ë=ÚËO`buH60Ái  ¦¬†íЗ뺬Ž”‡"„ „ ù}‚„‰Z¿TMÛD·VöŠ_…°=}0ÓÝ|3Åôj,íÈ2È âòOÕUœyIñPWó—x‚3#Í×ò ZºoÒrª4ÁÇÈîCüòæHßç¹{HwzñuSÎh{µ )<–æ…JÛ¤^Ðì«á\ÃYH³¹!JÀ6¥|t•óÎÁéší}ÑR‹’^¤ i -ŒPz‹­À3`!’¦ -fÔOÁ‘¢'c_ïè%ÄZèäsyR‡£1„l¦õ=hn{Çãº_5EòiþôŸp !¢œqØÍØÙOÀÄB$³«¾>#hÆDÏkÑÌdpT´"-ŠÛ:žùûz”¡Eµ,n—ܶÅ:ÒÔ銥9VB½,3å_Åj³,]0e;’°¨1#§¤q$% ->kún' ÓiÆÏDk‘ü—Ûb}WRS«Ìyj:kµ}Míÿ½‹Š#‡§ÏÖ‰×'",³ˆ‰8ÚŠn:¤bPuÖJ†‡CtŽpä¹8N‹ã‹°õj,c…¸ !;BÒºX•ó±Ì`¬™ŠËP'%„ - ú¡0è+GÉêpØGfiþI‹•ÑöHêU˜×9ü{E8¢À{Á%³á ‘å0¤z‰ü/ÀŒ%SÑ…  4¸Í Ú©oÀt¨¦‡^`ê3}#ôöØbý6UB -qNÅpdCîwýTƒ23Ûʼn'·ê)!biÒ¹M3»¯ë†Î!H è -£U8ï0:'ò -r•m؈ 1µ0–ß`ð‡V¨!áʤ°dÃ% >"ÇÐBL õïC!ŒcbŒ'îù³ÜÙš=Ö58.ó™Î,ÀMóšß[ôÏ“?wåöqˆTWï鈎¡7Ž!‡ -z ®ˆ€€ôÄ™nÍ¡óØ{Ë-øU?ÓG¢u³´÷õn9§—¨b€±»²ísu‡7 IÜæª4DoÂûÙÝùh«:¹0|O—B–7<Éb®¸+ª5^@I“\Õm ˜`¥b`~^6iÄÜQ±Ž6ŠeSù-OÑ+|( -ãëõzÉ’ÃVŒƒÀð.íEPÑw‡ë‰ì „˾#³ ·<´5õC5/ç1ÔsRp[̾ì‰Ã<†ýÕNàmµ¬ÚÇ#€¨¾©›¦º]òtSA^Ñ#]:±éjƒÍ¢»ÓÑ~"ŒÔ9×7%&!13ùüØ´åŠoîËXkS²ªF·ø¨(¹¹çüvxuÊ)oqdz!цDvU¬™>І6;|*ü>hÄz‰JQ>†‰î¬XÆÄù¡Xîâk‡,;Á‰*Oö÷%sä² 1Çú ä:UÒ>/5ÒœJí»qî.ÜPêMijćÄéï²C5Ê´b6¸ÒÙ­6 7\$”æ<½œQJâÕ¼{1,¦»|~z;$¤Fºö£Gõ̆Dª YÑOìH†aæYÁ‘hDðÑždÆÊ¡`2f.{› -´ÔÛ’‹ "“–«Ë)l·ñýîø^<ë2½…[ÊQ&T¬— ccô_‚¤¥„Ùœƒ©¦ªyb‰¿Ühù•>ïŠe—ÍÂG³ O'£jÆ3¨Že›È¢.Š ð•»x· ­$VÚÇŸ’à(oœc  ßm¹µ,CU#ûÃ2@çiHPÓ"ÆŠ:ï®>Þªf”yž|ÿ»§/û%§R˜&ê\Ъ1sT£vÛrÝ*mRïÅQÛéps„c=öÓ„Há8@ðÇË7œO@Ÿ4n‹˜“€[ØÚGj>ØLP^ñúª…édK1¨\‚2+©É—DšÍ ÔÛ¢jx2Ò¢¹íEsÏ+´bûÉ­ë’[GÓݺfú]j¡>4LJ0s‡þþÄOÄ´Mñw]#(%ºïîßýó±Ãoë ìÐÞ«q¼S$I˜°R¸Ö?ùAãTõÿ5µùÍendstream -endobj -1320 0 obj << -/Type /Page -/Contents 1321 0 R -/Resources 1319 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1310 0 R -/Annots [ 1324 0 R 1326 0 R ] ->> endobj -1324 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [442.7768 483.7823 511.2325 495.8419] +/Rect [367.5469 435.097 428.747 446.9972] +/Subtype /Link +/A << /S /GoTo /D (zone_statement_grammar) >> +>> endobj +1308 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [483.4431 226.9165 539.579 238.9762] +/Subtype /Link +/A << /S /GoTo /D (address_match_lists) >> +>> endobj +1303 0 obj << +/D [1301 0 R /XYZ 85.0394 794.5015 null] +>> endobj +358 0 obj << +/D [1301 0 R /XYZ 85.0394 671.5763 null] +>> endobj +1304 0 obj << +/D [1301 0 R /XYZ 85.0394 644.6731 null] +>> endobj +362 0 obj << +/D [1301 0 R /XYZ 85.0394 417.7762 null] +>> endobj +1306 0 obj << +/D [1301 0 R /XYZ 85.0394 393.3438 null] +>> endobj +366 0 obj << +/D [1301 0 R /XYZ 85.0394 274.0842 null] +>> endobj +1307 0 obj << +/D [1301 0 R /XYZ 85.0394 249.8112 null] +>> endobj +1300 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1312 0 obj << +/Length 3041 +/Filter /FlateDecode +>> +stream +xÚÕZKsã6¾ûWè¹j„à ¢æ4Éx§6NÖã=%9Ðm³F"QÇ»µÿ}»Ñ_¢d§&[µ›©ŠÁf£Ñh|ý%fþ‰™±ÌzégÎkf¸0³åæŒÏîáÝwg"ò,Ó¢ÏõÍÍÙ×”›yæ­´³›»ž¬Œñ,³›Õ/sË$; |þíOW.¿ûÇõ»s§ç7—?]/¤áó—» Ñw×ï~üñÝõùBdFÌ¿ýþÝÏ7×ôÊFß\^½'Ч?G„^_|¸¸¾¸úöâü·›Î.nÚ½ô÷+¸Âü~öËo|¶‚mÿpÆ™ò™™=ÁgÂ{9Ûœi£˜ÑJ%ÊúìãÙß[½·aê”ý´Ì˜UÖÍ@7¦¸¯YVeÁŠÙô²C0«­>.‹æq‡iÆPÔ"Ìxof ë3ÝáJ5‚yc$žnæ˜t1NÜÒé^¡}§gÆjŒ‚3£¤ÙÈñÓùŠù ü_ÎN#³ÌÃI€b‚eJâʳßg‚qí½"žÞ8l´3@ |}¹‘³÷5lgÖßQ”»è [²ª‡W!‹V°|\Ö…óõº>fþ´ø}_lŒ|þ¼XæËs<´_+{b2q¿etÙ¼"!ô°oŠv5ým‹ey÷LùrY4Íak…, CÅÆÖÓÖ3™ùlÖÛ—AÁ[^±èÀüe0]HϲÌAèšY¡³éø"”: ØGi!(&âKË•Ž‹ŽêyQWc ‰Híú’Öo¹&F;X.†|Ä£ü•sYàªlþôP.h¸®—ù‡nž¯VÛs‘Íá¤ã2¯h€xÜѸ\«²Ê·ÏDyõ‘DÀ.›]YW DCÅíü桌’6ù§$´Œrëfæó¹Yæ%o&ÏmÊÛuñä@ܼƒ5JÃܪÙåÕ2Ñ‹J{²1 ÑÐ%.…`ïð·¬vçb^l«|½¸Ë—eußÒ‹-ÿí~GƒUÙôdÔ7CÅ;’6À“æ2hžVÀ8_WEó††Oåî¡Æð¡*Уòm¹~&§ª~jg‘oÁ (X… +“vOõöÓW =ŒÅ@×Ç#ê…ÝÉ#HÁ@£…‹qb“£fBô¦¦ÑmA›P+"”¡‚Þ‡j)P ÿl2±8Ä:'yb‚cÞ›¢Ú¡ñ¤ˆ+èº0\æMÔ' +þÖŸ‹í¶\ Áãmœ…X%-T?À$]%žçkìæœµcÕ Mogqy´Ž€èÙôÍ«â.߯#_?„aÁ‡-ô xíûch$º˜buLsŸýÚæ %¾PÅæ×¿°00‡k£ÿú /ùD`„Ãu²¿²ø/çýþqýŸg~í8sÐZœÎü-×8n±ÆÉ_s&uoÖdîL `¢ “ + 4Paú•)~âð¡nv‘šSdˆ¨6ÂB) +3H¼/vñmÕ<Û8ï.Ì«7ôƒ°YlˆŒÂ@wƒ¡6` +O™*b@wN qkÄqêÈ fÁvØVFRhÅASÄ(XMh!ì• ”ÙËý¶)§Ã½àx?ZŽ\ Gå]»n¨SÀB°òö©l&óx¿2ÎÚbbi}€áê5Kã@Í÷Õ=øpY(c êp­‡UW·o`0`÷ZX ~Õ¦ê ðÒš0(ÃdÛb H!W*á9Ë’+( ¦7å\û‹á–ѸÖ÷ŒÞ +aù6m"õWnø”ñŒ3•¤‡jª¬æ-ÌòŠžÑO¦å¥ôéÜ`A“ÊXLh¡! +J9Ä0*~0S”3é¥z!õ¸N„¢Ä5ЦZè›…—Ùi-Z® 5ñÈBÔumz [îÚzš…ÔŠðÃVÞR+ïîËÏ‘ÚP„ä.á+JR@N¡HzK5¼¤š ^j.ªÕ2fœ¶Ã#ûÓ…Å©5Yõ|P“½™@§„vÂ6Fçµd™k})¯VS`÷hXGlOIãÌk›ü(\•…Öî4\û\ÇáÚr‰Áæ»Óæ´-ׄæY1nÌH…aæ´mӌÔ9aØeN|h3§¥z ÿbçK#b {úI]·Š3Ãûû‡D(㫦ØBoƒWˆ€ekÍtZE›kÕã ¤¿*¡ñL»Am(¢›¸˜Lr,bœ¹üX¾†ÊW/Fë¥Z”²R(JçN'P(&„âòµ Jí“KSµcÆù¨‰ +¡+wIçx¯v,éè@!;L$œu2鵬$~4:™^‡þHKñ‚¿ö¸Nøk⚀ØTrÑàd"Ó§uh¹&”»ŽyïÝP‹¡ËÊ6¹(Ù&¤Ž’ ¾ É%¼‹÷\H»«tÉ]±´Õ<äd¤BSŽòI¨AâÄ |JÔ1œ^›OFš|i¯ŸNZ‚ãZ¯Íi8ô¹ŽÃ¡åêà°\å»Ãž»X¥ÿÉÕ[®‰åÕèjÉgÎ ×UÝ…'äü»‘ÚÆîðb72…3b³¿Ý„Ë%¿®òM¹$ºñ*m2Õ xM‰ÔMÞìŠ8Æë®&V 7 `!ÂÈcp€ª–BS„<¯ŠP4¥[Ƚ²Ç%9ì’Q}|Uï +¢îò]˘®ÞI„W·9CK·A‡‡(€ nyq«Ž¾Š³.ބƸÐápò²jÏá] {Mqˆ•Ì0‡©E‚½\¦Ãgz¹½×+×}Ô$þEÂjäÔË]™\É15ÖF*Ét‚úÂÛr½ ƒT:\ôœ¾„ Gvy¹>á»/5„Áw{\'|7q}wê<åÛe|4N`~T§i¹&4Q£;Y—õ·uèÆVµn ÃäÆ0ìÜZ7†òÕ¹1Œ;7ƇàÆ0èùToÚ:ÿýÕCÓ“ÉQøžÇ§@ßnÈá™ ¾“eðò¡Ž¬‘' ªé”p!:„7½¼Úɯ?è¬i!QêTËÿ ŠBÎc †ÿžª}sÐìÆ9oH|²)*T@G•¥HÄ*ª£yx{GŸ€â]tžeBš¡qÒö)ÈhHÆeN:##屨‚¤ ,ïýüæÜËyMÿa&:úšÊ@Cµj¬êrø#›Äõ‚ +ZrÆõCÚÊ`S÷íýRy&ÁO— =¦ãUBbêâèg»hž+nC9jØï~¸t'h™5v{–eÐö5ˆ¿,p&~À¥ñSˆ¿›·‘ˆZ{-èLú‚eæÍ¦®C@â’_™DÙAamæïà¿ÈWGŠ¥¿xÕ6œ@ýža2ë.×) +ü*¥®Ê[Jl0eßë©ôL²Ýü6ý¶¢åÁ ™ùù÷PÛt1If]øÎÛ¸u³I·)4~*Z,9K×;U<ÆžBQ¼Åº› +Áà±s:€ÐŠ6uBh_V(u LŒšÞ*µºå}ñ½ê~5c@½)Ò*ÛªEüÅýT››n* ß¿M·ßŽ¿øWvÝOµ£Önºêwt $*…–4úÐy9 "Å¡êÿ6=Žendstream +endobj +1311 0 obj << +/Type /Page +/Contents 1312 0 R +/Resources 1310 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1280 0 R +/Annots [ 1314 0 R 1315 0 R ] +>> endobj +1314 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [184.7318 238.2538 233.4785 249.0382] +/Subtype /Link +/A << /S /GoTo /D (dynamic_update_security) >> +>> endobj +1315 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [369.8158 116.018 418.5625 128.0776] +/Subtype /Link +/A << /S /GoTo /D (dynamic_update_security) >> +>> endobj +1313 0 obj << +/D [1311 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1310 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F63 1063 0 R /F62 1060 0 R /F21 710 0 R /F48 950 0 R >> +/XObject << /Im2 1049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1319 0 obj << +/Length 2727 +/Filter /FlateDecode +>> +stream +xÚ­]sÛ6òÝ¿B÷tòL„@É“›³sî4iâúæÚ>Ði,“Ž(ÛõÝÜ¿]ì")Êq§=\,‹Å~Sj"á§&Î +©½™Þ+•Ìoää ̽?RŒ3‹H³.Ö—G¯Ït1ñÂçY>¹¼îÐrB:§&—‹_§ïþyòéòôâx–Y9ÍÅñÌærúÃùÇÄÓãÝÏÏÎßÿëâä¸0ÓËóŸ?øâôìôâôã»Óã™rVÁúŒ)XpvþÓ)Þ_œ|øprqüûåG§—é,Ýó*©ñ _~ý]Npì¤ÐÞÙÉ#¼H¡¼Ï&·GÆjaÖ²>úåès"Ø™ KÇäg¬63ùdf3ád6.d)¤¡Í +£DîýNÈ™rÄB!—ëuó8Ûnʺ½®6Ã3+ãE–¹I—ðÞöid{ÝÙ^Y#2éuÿ_îªùê7)³ª=ž™ÌN—«ù’†Ë¦Ýh>-7ÇÊM+‚ž«½lz¼Z=0ÖššGñtLë: 6·<¹d¬¶Ú<€@)Ša Þi4Û†FW=Û$œV5=‘é}U¦…2:cÂAû»’/”b¤v[n«ÛªÞ¾ÊF¥øp8/[äÇÈéjKµY-ðÊžá¦p"³.J¬¹Û®šºGíˆ/® UDñ©ˆÏË æ­•œž_“×Í–!¾"H¸r,ªëò~Íx«–gz´S  ‚¢Š=‡Áf™;dXéçm·‹uØvýj]Îo–ͺÚ3Û 5ò;G¤‘{f«p&lÝ3[eÓ’ëU»¥QsÍ‹™fÛFÜí²ÜÆQE6¾0~\¡\qî0™Ï«;½¯6«HjgËaO¦pß²:ܘƒfýPEvƒîep6Ÿ›¾åâOÇJ©)«Ôç¸#ÞõnGV¥–•ipPÑIzÚxÅØŒz×Ô‹`ÜA­x¿ËCúlMÇÀL! 6†ú°ÉcÈ"¤1÷6Ó"¤+ ÐèLh©L@Ũ©ra!ˆJ ¶Uo«Íu9¯Ú‘Md§7¼”áÑ£¤Eð¢¯4q×l¶- I#pv—EÀ1Ë1,n#4)¾t®Ðȧ8ˆ}O +÷íªþ7s_F[BoDBCÅ®êYSœ|–p{zDo4˜à}i£…Ó:bnË› øbMOÚ¤Dƒ16ˆ4Î/"©MÏ7*×yŒf º ¶C7E¡•›ä2…/õ‚œ'Þ97žñÌÅY—dp:=þ´q¢È@­EÊ-Ĥ!“d2×ß‘ÉHñ[L:0·Þc2xÀC&h’ ά/ÈFð’’ûƒ1»?‘bð=×tÃs(lfJÈ<è\ÏØb‹æêiÿ:.‹$á0ÄÍ!µ¤)Y7d>kwÈVbô…à®ÁLЇ(ˆ2:+Âi>€ó[Ý­GÍS +ù—˜$ÎEʶRºËŽ´øØgN\ýQÞ¯F iæ ‡‡ùvv@…äô¿ô€R½¥·ÿ½M'î¤=ƒ•$=AngzÔþ¦À7ka˜¼½Vyöˆ†ˆïˆE¾Èv«º¼Z£ +ÍšÀº¼ePòÃE¶Æ— +p©¹n%Q8ÿD3}Ã%$ÔÂs4¥MGFæ)ë4i±‰®|(ÕÛr¾\Õ|É!ÃE¥­X1AtÑ.ÊCŠÍÂh)‰r—qŽèiÚçÍŸVÓÈÀ3Ékº˜žMEŸã¦>dƒq&e°çŸLOô tØY.»È|ß2/ÇS~.ÉìvöØæ"‡ä²Wp™ÁUú‚l›NAtýÄÀe,KºNOGJ‰©†á£Ã +œc5 Þ®K+Ik ’ªéH ¨êA0hrQ¸¡ž7·”Z€0¿v3ǼNtx Ÿú¾/«±È=Ð=veýMÜò»”ƒxe1ȉ¤›–<‘¢ÞÎE°ñϧ ™„B¢­‘àõ+þR0Žg]Šû±Ø²Ð~·ñÁ„!ÓNXë¿'‘â·˜4JXãtŸÉC ƒ…2=w,nò¯Ý»é'” V/649”â&Šê4Q˜»pãÁ¸UÄëXêà†“…vEÁ&ÚÏGöJˆWÝÎÆÖ¢uª-N“—p¼Ùkŵ+ZÉ„I1:¹+ÈÁb†ï;Õ=g¡ò®£ »‡ëÜ/j^^HøBh£ÈO7ûïüç눴ð¹R"“R½Y\¹7o^ëìíøª‰ÂwÊ -m*'´äbTN (é(@ƒZŒ»Áü!Aó\Ѐm 憶“èiWÛ%#s¬ÈHϯÑlÐstœhb§† q5bÄ#”û,>åMÐh„o8ð†HäYprÅE ¦gÎÜÑb´¯?hªw3Ú—$[st*Þ'¡d¾8 + QõM׎b³£ËcŸM›Ø*¸©ž©HRå4V„[Ùï!?‚MÜoæ¿ ;¡BC3ê` WHûr‘ã×°aY£È‘™½šÎĦ§é4=êT$K%Y¦:F±,M’¥Qƒt ¦îë5çêüQáR÷x6vÒ[Ó­K‘ÑNùž‘@ bM_©SÓ(Þ ß©Ð9,ƾó‘Y[tv¦PøÐÜ×jÆ{Û'Ÿ¡ ÿì¡ Ï¥î7Ð0¼—1ö¡ð+Tá^Ä~l±ÆÅ®«0ö€  q¦¤e19& ìÊ]œHÈ3œPÒeýHÀ߯ÚÐ26ûm·ÙŸs³ÿsø B±xWì=ßôG3ÒÑ%èŽKÐV…$½þû–&njü¸Öý}ÍŸØpMI¯PG·\¦è†´V§¶# ³¸¤¡ì¡víh3Þƒºdɼ¥YÛÜoæcŸRf ½_Øô¾‡å\IéÜög(ÐÀ€/p¨Ñ0 +|0hïC¢“ÜC…ÏmA¹"ì>ƒ!vh- vCâ§ÎšLls"Î*rïÒÁ±?> endobj +1320 0 obj << +/D [1318 0 R /XYZ 85.0394 794.5015 null] +>> endobj +370 0 obj << +/D [1318 0 R /XYZ 85.0394 658.768 null] +>> endobj +1321 0 obj << +/D [1318 0 R /XYZ 85.0394 636.4568 null] +>> endobj +374 0 obj << +/D [1318 0 R /XYZ 85.0394 119.9909 null] +>> endobj +1322 0 obj << +/D [1318 0 R /XYZ 85.0394 92.5589 null] +>> endobj +1317 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1326 0 obj << +/Length 3170 +/Filter /FlateDecode +>> +stream +xÚ­ZßsÛ¸~÷_¡·Ò‡ß›'_⤾é9©ëÌ´sw”DÙœH¤"RvÒNÿ÷îbŠ”)ÅI:™ ©ÅX,v¿ýZL8üc™Íd6I3Í f2_ŸñÉ´½=Ag•¦}­ŸoÏ~z£ÒIÆ2+íävÙË1Ü.~K,“ìFàÉ«w×o®Þ~¸¹8Our{õîú|* OÞ\ýí’ÞÞÞ\üúëÅÍùT8#’W½x{yCM6ŒñóÕõk’dô82èÍå›Ë›ËëW—çÜþrvyÛ­¥¿^Á.äÓÙoðÉ–ýËg*sfò?8Y&'ë3m3Z©(YýãìïÝ€½VßuÔ‚3©¬q c4³J*ïÀO»bûeÚÔ»í¼˜>X\tS½n©a6MÌ…úõ¦-ë +ü¥ÀWˠߟFkØÔóÅb[4ÍȰ*eÚ ôÊfd¤Œ¥Ú˜ ñç1Ó×&Zö;7˜° ËJÉ.Œï&¤Og`š´÷yK’fSÌK\Uœ­¬¢J1–ÊÙ˜`äôAOw‹Í'Ç™VZõ²z·ëêýƒŽ¶¥ÞAO'´†ñÔ¨þ|vÜ&9sÙ¡ÛN˜~æR›CS”hŠ%S””Œ•%Åçùj·(«;jDÇø>ÞÁ nÄFtcÔq£‘ êVDÕ‡º\|͇Ôêü8î,p·Y:¶s$Uèý%¾î/H2!å T SŒÂ²Ûò¡XÅ`¤™B¿Öw§…ž‹b™ïVmC¿ê%=Çý8—Ó¼_ÜF̵€+Üt¤LªGÆ;Z,M‡Ád/•—â/ÔI÷'™23(àfˆ—ë§–ó~5 SÉLA(“Êìoûבu"3æ\šô2,KSÛïô’vG¤Ší£@Žzâ©yZ1œÄ§Y§OY§X§÷Ö¸üÑÉt@θJÓS•Ç'¾ — H{d$Z$“"͆Øóü1=Ø:“ìª:¼Ã8ÛÇÔ*_‹1†¥˜S6Æw¨"0üü¾˜ÄW›”KyˆÂ—zSlóÖC¶7_€P­©‰ŠZÀœÌŒ; ‹‡ráN,…JéØën›¯×„ˆÐVVmu»Ì1²QÒÖô¤$i·%4±ñ>¼xs eý§0I€†Ðà»Ñ/Bjx)6÷ÅÊ5ÔõIünxʯ14¼ÍK¥7¼êÈKöÐä`¯„³€ßª”òr•ÏVÅØ6e¡©5_ߦT:=Ü&˜‡æ ÍɼÞF­+ª/ØÞm¨tÁ_o^âî¥I £l˦@8v<)ƒÎÈ|%…*¬ÒQq ÷¸~¬†¸<iÔïIzy¼ø=ÂWå–Þ¬1ʼ¤÷ÿ¾îˆO¯ïó`+ø6®ëðhƒMÖùGŒ+žB Ðà/B“»}m‡÷Y5»%ªbÏË¢j¡èyùŠjÁ]‘"õ‹ùn[¶{žætrAMV˜[ µ \þ»ˆm›¢Z„¹ëŠžù¶¬wA¸É§c„œ, ª}…Ö"™í0&€¿£1õñ%ð¥ûr†ØŠòçT ½ÁKz6õ:H"£ó@òÑ…Åç|½ ̸AH~@Ø>\_ýS\ŒlèG`ðVÕ-½@>×£œ×ÁÚ»s扔•ܦƒµWDaü|í}½‹3у§ßlËÀ9c€¨˜£(&Ò‚í¡¬ÀëŠ.ëüY:¯è I€¯ Â3>¿`d|Äsà ¨Œ{PI³c%ùUx¸'¬0áÔ®cJ™Ãs½öEŽ. ®¶pü-ñâhgÑRî) +è¢Æ‹¼x¥ Õ~üxÐ-oa7Ãñ±Û:O:€·¾ ‡0”DZËÀ"BS½ÚQ"Äž’Dþ²(Vy¼HBZ.(¶1‡°bîIT¹Æ¥æUÐöø ÏCüí®4xg_’ÑñpÑ¡è<ÌójxWÙäË"‚ÑXÊêRý¾¼éã…o®JŠÖ +¨Q;zùù¸ÍxÖ­ƒW%¿áN£»ôyö¨Ï¿Öp +ïðZcdÄÜÇiþˆ}}õg1x™ußvx–ÀÁŸqä ¸Óc.vsb&Ƕï3„í¾F`Uö9‡YõjüŽ»ïÉmaŽšLiv›pÿ +œd~0/ðÁO:›b[w% ÒìGêN(8k”>ÌO’€>wFp“DYU?†Ædzáù54ÏŠyNð +M´Ë»†›GFjM¾:‚áµ S-Å#£†6ª, ™Qz3à±ÈÏï+œõî(݇ƒL0 Þö¤ÃŸq$X4q?|ö8Ø3„CuGHײٳCTñ[‡ªôËÐ/§Ç&ßóÝ!òÃÞB ´8] +oSŒ|öµ¥Öžºˆšj­!\=}k÷¼ûË—ˆZwüÒZÙà©´9ÀL +ÄQì©5Àhp¼Ñ÷"lƒ¯©‚¥BØ œ™ËŽ|û$•é^çø‡Ï s<û“§Á^âÔìΓéÕ:2fSeúóßRFúj2]e!{„§ÌúÚwÂ'=­^‰Z]„t>Ù׃gŒdZ÷{Žú&j˜1ðŽI™†ÔÚñƒþ©eNhsÚ?}­ãþé´Fü³Û,ò¶ðwƒùÓÊàX`œ;mN§5bÏà+(@´¹ô½ŽŠ‹ƒðÏúKçÿ{ì[4€1”{«Uv|,êÇa¬ð{|Öîþ"Är–‚y}‡tx@(™Jq·¡ä #BÉ±@Hèë°–`í‘ÜÂÿ2yò0&Oe:q)ãXÌ<ù4J¡³L‘Nïݯtï/øéj-'¯kXϤ·¤8î´7°_’•}ÆàXŠÇnÁ-heéž:BŠtßWà‡4´?˜Ð³«0vf +  +|Þ+1pJä •ƒs ä8vëdS&U÷4†˜Ÿ.ØA´%ËsÅýYÌàTNo^¿'ÍÀFdº> )·¯ðo.œŽ¶A¢ô-b†Fú3âþƒ…Æ*£CÝ!9Ý15ÔVW¾F9ú¼€o +çÀ³¡UGl ‘W¨˜ã"¿„ °ÆQV¼G÷‡'â [ŠÞM“N² w+x’¤ÚfLºÌM( Ä'¦°Á¿“˜îÿžè‡ÓNÖ>2n¼K×þK¨=(à×b7…þ¢cÚÁ Ê0 ÷ÃØ§u"üÉTÐê™þ?náÒ1endstream +endobj +1325 0 obj << +/Type /Page +/Contents 1326 0 R +/Resources 1324 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1323 0 R +>> endobj +1327 0 obj << +/D [1325 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1324 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R /F63 1063 0 R >> +/XObject << /Im2 1049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1330 0 obj << +/Length 2839 +/Filter /FlateDecode +>> +stream +xÚÝZÝÛ6ß¿Âo•šå·ÈÇ4Ù䶸îæwm´¶¼bKŽ%goû×ß ‡’%¯ì$H€ŠÑˆÎ ‡¿ù ½bÂ៘8øòz’zÍ f²Ø^ñÉ|{s%"Ϭešõ¹~ž_ýôZ¥ϼ•v2_õd9Æ“ùò·äåß^¼_¿›Î¤á‰eÓ™±<ùùæöxz¼¼»}}óæŸï^LSÌoîniøÝõëëw×·/¯§3ጀù2J83áõÍ߯‰zóîů¿¾x7ýcþËÕõ¼[K½‚+\ÈÇ«ßþà“%,û—+Δwfò/œ ïåd{¥bF+ÕŽl®Þ_ý£Øû¦Žù¯ã™iǤ_¢VHæ½Ñãj9l†e6ÏŸ•Eó8ÈŠd;c(긽Özf¹O»í•j"óÆHÜ_ÏY*`[S¥Ç!ØÞ[tp`ôÌX-Opf”ÃÇÝtfE2‡ÿer}º R£?¬sÌ ‡Š''‚qí½"žVzô@øéf+'¯*XϤ·¤Vî¬'8¬ÈÊ`…LO58†sæœrÁà÷Õ&ÛàLRÔÓ™r<‘Ì0AdV.‰È#ϦÈ÷4²¬òÈ_V õa·«à³æI;’7MQ>ÀKê“fÇÑê°_D:[.÷y%­¦Š'UT0ùý‡{ßí +Ø[W‹©äÉü/oê)ÅNý¬}ʬ²j·Ø};jŸÆ[?™‘ÿ͘–– “~Y©`Ö +õ5+ 3ôÙø0À ¼4Ÿ‰+=sR™ï Œ°Î›ï!}ÉBÄxɬ֔ÔßçV™º$ÛÔ-ЪÞ,-`ÊÆ6û¬¬WSðÜ#Hgw$ò4·¯15LiÛÎÅx{._x¦\Y ÚŠÕÓe¡°ÂaGhÆùðèïð·æû‡G‡øô†b¤ +Ã0§µ+ÆÂ),K!eqΓÿTeNer>B$aƒò}ÝÃj+.¥p¦Ê­¬MÖYMÄ6_¬³²¨·ñ½(é¹Ûd!§ÙTøL“U¶(¦rf“59 ýL Lá•2-2‰ØÛ¢‰_«¨„R(²o«C«UœPeKÒÒ¬³f,wöt¢7¢ÉH¢|HÔOu“o¡ýPäy;ºª6›ê1dô0k×U¥e»Ýæ)J©èùgçøNó30:ÕÒˆ¶ =Ó’E¦YŸë<:®S´3ŠšSÝBi&½þŒòŽkDû L•g25'ê_å¿s.ËP,%¤|¤ÉæºÏ64´)ꆨ°“ðõæmd†â8.ÙÎoYÊl›ÓHï?ŒdÜyšK3ã &®ÀPçed¸½›ß¼þ7Ñ[Ð=ä!"  ßHŒ¼>v×y™ +ÕR\¤ñU4oM£‹j÷DaR´€åð9µð áš/Äbïb…v @LÑROÊq­ð‚~Ë—ÄÑÎèû!jº}? Êêdú¢ +Ï%*’¨ûŒIÖùfÉ`<ó²>tnÅqò6P°ò"ÜaíákdC[â·Çb³!êã¡X|À€¡é%º$?Ä9Áð„%f›f_hùl,¶ïB,f‰9ü*µÁ}’Z'Ж5Dm³'"îszÖ»|Q DÑ•8ðX :¤òl±Ž9²eÚGŸjÕÖ¬a|…záL[ü{€&!S yÕS"Š$«[|&e®jµ>~àvÉiRÈ=’7¬¤Á¨v>_e‡M˺¢A8Á€Ç¹OnVô¦=w„°p¾‘Æ~©#RÉE䥘GÉEM*ŠOy´­(i(Ñ õ*{«2DÕs]RCºì6¨Æò³…¸ÿ‘ÄQ3aG*@Õ¾XæäO% é„ :lÄ)œðxÛ›tõ@iÑsÔÀ1@O¦Œ§Vâ‘×Éä_kt‡Ò|Ô Î3о‚ÎóÞ·àþÌ#4 ‹t4šª/M5¦UCË«ºFlDx ¨–“›U1€Ð×5?Éëät +0 AÒšh%ëÆsÓŒgP§ä—AQ2•ÊQvÌM@щˆû V¶UFºªô1*ñmnÁØ,2ãÆÀvj洞À±.Þð¥¨ë n€ÔÅ ‡fvà†|»kbk¨ßaCËØh´åi\6æ³EF…¤üâl÷¡ R¤—»>×ùî£ãBÓ·Ùgmóƒ[>kŠm>+Êg­H +'wiõeK:®S0t +N©ÚrSÞC×Nôº  ú¨SP]r(K:¶ÃçMU>С_ÇüI]`E)Ÿhæ¶(M‡#šUš0%ßo‹ís +öYá†Û\BT.O[Îc~6Ô;àSHND§²E„$r Ç£šv|(ö£Ø¶ôò)Ûò¡dé¢Úì©'Usu¢ñ2šxÊž/£©ÇuM-×(šŠåfMx³Ç±‹–t\#¦ Ñ$ ¹89´åˆ&Ñ¡I Ñ$I+:=wÁöêáØ +à(åºY¢C–0Áé¤ \¢k£D—8˜ë¥Ö¯/—=‡-qÄÖÿ ZÒÚ‹‹Ðês‡VÇu>QU‡æ¶  +j íÁES:®[†Ø‚º§ƒcîM—„þ=#ñ Ð;ÀÂk?UÉp¤P¶ +ÜÔíªˆSSê¶^b/Ô}«ª(E‰û¿h¶’RÂH÷Hõ¸.@ªå:Ÿ­F!mԃ˦t\#¶ !…W¸é‰1GH)ÞBJq>ÈW\ó”¯à9’¯`bÈW¼ÅÍ ùŠ‹a¾â-¼ +ùŠx—D€Y–B „ü5r–€øIuª/¬Ïu`Wèãó}‘mfùþi¶ÇK¶S`YΤ·æ² ׈ `AŠ’)tU#Þo²Oè5%×Ru)†w`fµ,áp¾‹éã6«›°”èÏ—tÊ…g¸>ZÆN,V4S#é.²¨°ËfÍÆ®mæS/t ýpEŠd¼lÁ±Î + ƒØ$´‰V÷NRŠö§Yàñ=‘õ‰Ì-’Õ=®ñиˆÑCáú'°´7DøRÓV¶' ä¦0¹Â æryæ¨--3Š?ý¼¦p8·F ç¸n!’PAUQ69ÖKØ‹ø%D>wnÈrL¼Eq´æWÏE<)âð®å«óEU.ƒtðô¸bîxÉ@Ím’ŸÏ,Z=g?siÜçºYZ®÷tD¤2Î1­\Òßq0H+:½Ã´Ò·àwHú¡Ò%wH©3ð°¸ s~Æþ¥V3‰?—ô±A +Ãê#ÀÈ0Ú!>Àìïâ°'܇íbb>¢9±Ð üÅé4yJ¹#’”‚t‚?5„û]øn`áÊ'0íሕúçW„!bËÅß…º|ˆ?+>p¸nÛú}dI¯‡ºûuéÜ£c\òuyªµ;qÈ™?•Q†áß®Œ4ï~ýþæ?£9þ¸ 9B¹s‡#Å-sÒ§­Qh¾IO-7 +<âd:búÿæÜ"endstream +endobj +1329 0 obj << +/Type /Page +/Contents 1330 0 R +/Resources 1328 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1323 0 R +>> endobj +1331 0 obj << +/D [1329 0 R /XYZ 85.0394 794.5015 null] +>> endobj +378 0 obj << +/D [1329 0 R /XYZ 85.0394 548.8286 null] +>> endobj +1071 0 obj << +/D [1329 0 R /XYZ 85.0394 526.2567 null] +>> endobj +1328 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F21 710 0 R >> +/XObject << /Im2 1049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1334 0 obj << +/Length 3252 +/Filter /FlateDecode +>> +stream +xÚµZÝsÛ6÷_¡·“g"_üÀcš8½t®i.uçf®í-Q6§©Š’÷¯¿ßbŠ”(Û™äÆ3ÆX‹Å~Cj"ñ§&I*R§Ý$sV$R%“ùúBNn1÷Ã… +8³ˆ4ëc}}ñÝ;“Mœp©N'×ËÞZ¹y®&׋ߦ©Ðâ+È雟?¼{ÿïŸ^_fvzýþç—3Èé»÷ÿºbè‡O¯úéõ§Ë™Ê5}óÏׯ¯>ñTÖøþý‡·<â¸9³è§«wWŸ®>¼¹ºüãúÇ‹«ëî,ýó*iè ]üö‡œ,pì/¤0.O&èH¡œÓ“õ…MŒH¬1qduñËÅ¿»{³þÓ1þÙ$‰¶)8™K3Y‰L)àdÆ4w`²VcLŽXÄäݶ¨Ûe¹½Tùt¶l¶ëbw|p¥|:ûËŸÑaPazT(#EšáD2þÛÔ%nÏ%A-wçEÍÀM˜oËzÇо­êÛðÑCÃÀ¢ZÒIÂ:T>XûŠŽvÄm2‘;Kç B@Ç <`ÆíÓž@†UQ‹z1²žÊE.qQŒ³.êǰ^;²`šˆ<ÈÈ‚0pç:Š®\)á’Dû¹ë»rl3'´í:s—G{fJ$inãy7»ª©IôóiÕR›±å‚GâÌ»{`]´;làÑÚr{Ï0n%¦×UÐîªùczx£Ðâ.­9—Qt)yïNkdN¢žDÞ¨pgîËÀ„ªò28hü±J²éÛ¿ðȺlÛâ6ŒnèT4ÊBÔ6{ÌËþè¼ñí‚?‰¬ç¹ÅØ™4ôôÛJ†V%I@Þó?íEË;Ò÷Ì“j!ÕC9¥]«ìˆö–‹Ðnš¶­nVµªý¥Ò<7GbTµ€Ù~©ÔÃÈ+ãrv_3Qa÷ÒëñïRêy5~…Qm¦7û] .|ÔÔ«G†ÚýfÓlwå‚™¢S JÔ)7@6J6¬Š]u_ÒFºi]>ðd»*îËz‡Ý˜m± 3ûKÀ7ìThÄyœ$Ž`.Ÿr½`à0g… 6õCnžÊæîŒªç`+lÞgq¸žqcJ1Æ~Ø]™w¢Õé¥ÔÌU´Åª¥«—¦ÇU?Aü£6ˆ‘·¯Ôÿ©šû¡¦m–aè?—IZ4-/U æ'ªõõ¸‹rYìW"FNëÌRgŸ?½~îô™™Ìú&÷ØOŠ$s_lS­Sª£î‘c‰›’Û‡ÞV‹EY‡~h n6aùƒAŧEËæX2ÓÑGànTD4ìIdT¬°Ü ޤi€vWìÊ5®RœDøè°úÌmgU}uHø6ºÎ'wï°F¶DÊ +°'îï4{]|®Öû5wêýúÆ{ÀÍ’Ûª¾iö^Ñù›ý ^°â»w¤Iù°…€›€¹½Ì§ûºö7èšz¾ßÆ(6H)5¥PÕèh ÛZ¤ˆ“’Ý銑Éô¾XíK£ÚX5”ËÜØ(ìJŽC\;êÃÌ"~_³>—…—¹Aà"Mz¤$ñÃ&h”ë…DLq»)É®¸ßPk9Π°çžµâ¶¬çaÐ_} 4@º +ožéƒgÅŽÙ‡Èq·ÎŽ #7hQ§§Õá¸åAÁ<°jŠÅPi{SóbÅ`ûˆ°h}V’ Q¼ÒöiêcW kÈøf·C摬ا·ï°FöʉY–dC¼YåD¨AVKi4ƒ +QUˆ ž +:«Mx"à&`öUˆPϨkN.T–yN2üF«î{¼Ä_û²ÝµQ ¸-?Ïô„û_ßµæ@VNªÕjhòyÍ%…Ò‚ýuüîàíÐ ì7Ó`ƒ$Qº.²z‘ +Ÿ“B˜>™9óŒö°žÂˆ5”ÂèÉêö4‰Ì…µF=ME‡5BÆ0‰4Â"óÒÁVò ŒÔ‰Â¨wù;Tò`ΩòHPO}÷Ž£ ‹4t0Odoðý6MÏÖ\'KŽ•ˆ>ÇAš[„¢5ƒ¼ìºÙ•ܧȉ¡àÒa¡ÉPkŽìúBåBåΕ¶ÐùTEó­Çl¶pY–ö¼‚‘/ò +à–;ñ +C±8Ž,œ\žb':ª÷A™¥Hòì(Àõ>Ï>CéŸYï30Ùõêà3t|«ã±w öSz‡Þ–*xB"ï0 ¦‰4Á—èIé]â)åPV^ÊD¸Ø¤鹿è#7ƒ”Æ›Ð<}€úO9õà#£…”†Î iIͱŒlH­‹˜›»-3—h[ònã[ ÛÍEf“!—¾Y¨K5¹,Gzð¤ìc·‘ÖIAYù¼<5‘™Gö Ö3T(íH$^Dű0iY£Æ®¤CVV ÖtÌ!2jZ,¡âÑØ%š`3© &ؾ²@åã½eèúÍG Åu9§¢T¢8_ÁÞø¡FKOËrǵ¦œ5<Ì 3¡þÔ™ÿÄ…ôªWãYc ‡rUŒó!Oßöë-è‡b›ƒ|ò èª«&1 ¹bå +úaílúëÛaƒ‚혎q3$ÓìÒ#£¢‰ðj{`Œ¦~˜/¸ð}ÅEH l!΄šf¢c&ð‘‘¡¬ö vÎ.F…nC)G”:µÇÞ3Êb›ŶÕŸªRÙLd‰Œlö'>ÝN.ÕY¤¶ÙŽÕœZ§I$Îógt¤1޽Ãús˜áuÙL‰Þí~[ÄéëÏ«ò$ZÈ4’‰¡­ÜKÞâÒÓf>þ#“!lÈtz~-þNb­Æ/†KÍ"uävpC껫å$Ï„ÎàWa[„sŠâ>ô˜˜¤ÈˆÓ¿Mg ~¾œ¥jzÿzzòHš§È‡ba‘'™œü5Yç£=9€ýY<ðß½_ëÉÛ'šôžõWö‡‚ö£ĕƚ R(¨áÄð—fEVUù*"H7Õ"ŠA.Ï(Ϊò10FMðÉÕy€ âȇ :a¤ÜíXõÐacM£¬S¼ >{t–—r‚]=r-eEÌ/µœþIÿÈШ´©šÞÈú·üu‚c ©“°ò‡é¯kdr"÷™›†O’ò™Úƒ¦‚g"Ÿy¿î°Î²Ù}zZ›œžÓÒI‡ÓÐ:b2¨> y1.Ò•wZÎÖÿJ4’#§¡ù™a8è<視¯¥©M("ý}RØ +5«¢{RãgzÀ('Ï ˆRÓ³)‘–”ègªÿ}¬'®.bq`²›½$-2ozó}’k„’áÝYa·¤¼&wœeDR¹­ aei¯LH“ƒw`ô)Ž¡–uèì¢1²ªZÿdæ±ê±DYAÓÒ,ÿRoœšøÉ²¨Vm zôw²IeÝîí{FüŽofVäÎØñRóQ’ÉÓ¼%¡/wg½¤J¬0ÖfßÄKæT70î Œ]ü✗Ä2)ógœ¤²J(Ï·t’m.í·÷‘½…Ÿp‘Рiv‘ïýÛŠœ>’ÏiöÜYP)Lªàý$%õ”G^j$« Á4è MB†èÝ»õÎÎëVé\"a4ÜÞ„>å±T’“é‚ö®Ù¯.ÃÓkjÎ×Ë¢ ³0Ø z& +õ'JÓ3b4±HöÍ&D 8e—V³¦ÑÏs@#½h ÁÙóD$“`Ï,妬Ãà~ÓÔ±œ¶¤R·1ˆ ÷ï‹Í¾m‰á~즡ïùT:‹õ‡Œ0±¥l’:[$ÿœø£C‰?ñ‘h3ÏÇ=}ø: û„ôx›ÂݰtüçprûÕ¿Ð;ü|I HÓã>…BR›DÒ‰ÀZ|£I~êP%½AÐzÄÿ.:Xendstream +endobj +1333 0 obj << +/Type /Page +/Contents 1334 0 R +/Resources 1332 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1323 0 R +>> endobj +1335 0 obj << +/D [1333 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1332 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R /F63 1063 0 R >> +/XObject << /Im2 1049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1338 0 obj << +/Length 3258 +/Filter /FlateDecode +>> +stream +xÚ¥Z_sÛ6÷§Ð[噈Å‚—§4urî´NÎQnÚ>ÐesB‘ªHYu:÷Ýo P¤Ùé$™1A`±X,v» ŠOüç«&35I3•hÆõd±¾`“{{Á=Í,͆T?Ì/¾'ÓI–dF˜É|5àef-ŸÌ—¿MßþûÍÇùÕíåLh65ÉåL6ýáúæGêÉèñöÃÍ»ë÷¿Þ¾¹LÕt~ýᆺo¯Þ]Ý^ݼ½ºœq«9̞Ù ﮾¢ÖûÛ7¿üòæöòùOWó~/Ãýr&q#^üö›,aÛ?]°DfVOöðžeb²¾PZ&ZIzª‹OÿéFÝÔ˜þ”¶‰ÊLfZ$™Ui\Ë,a´6KO47¶×²à1-*Ôr^u³n›×íªØ^r;µÍn»(fæXÜòÄdf2\äD”@EDáÖ$&MåX–75œ@ÊP¦b[ç]A¯½xî åCAn”OË•§zðäMíUÙvÅ’ÚeÛ9Rˆ`6ᜠ—?¯†#é­JWaÚ*/«Ö ^/#Ë(–蔥ž|×3$‚ÃeYbE +ÞÁy’i-ž;˜:‘,“žoÙ’ù¶E—œØ®7“e‰ÊXö¼ ©Î[QO6õŒàc3‚£7pôÏ +ÓSE¤Rö¦¬‹ók‹&`­7 +›L +û&ƒ“ji¸ñuºœ)¡§×+y,‹}ëYº9ža»)åïŒ gp0Ú=”žÙ²X廪ó³º&b!3ðš”AÛ[`ÝDúð`K ìo»/ÝnáèËŽžƒá-º" X’ŠL{FO°óÈZi¢¤ +4¿3ÍVN3zˆÃ–‹f½É»ò®¬Êî Hùy#ÔÀÖÀŸ7ÂÕ3F¨H_]¹z:gv +¼Åýüò=Õ ës  ­¤}A€#}™Hm¸×粓\—5djº(ØÔÓªYäõá‡òå’ì®m_A´ti³éʦΫê‰Þýñ#ÍÙ4ÛÎïËÊ3¾+…œ%h™Q¹‹æãžmáÖ1éôæÃüúÝ©w rä÷E nbŒœÎÕãÀ@NO¹k;?´Ùà<® ¸ìx:GuËTùchÛGtQˆÓßµ–&K¸ÊësÜocv,1ˆÊ€×_0@xN<ô‘Û-ª|‡%¥r@€O'¦” ëˆ †2Üxö ÿf?#SˆÈ¢³â^ð)ZËe&<(–k;@ªuQwþµèüª)âÌDYf‚"¾Â 2m_a¹³ h ‚œqi°’—aA[Ÿ  hd/w.ær‰mË岨ýû%ŸúfN_|œöh;AŒÅžtz—·Eaðe½¨v˲¾L#a=ŒÔÊ|½:XÆÂ‰ Tü÷%yMÒÄ• +I¡4+$XÙÑbB%,Í‚h°óÈiòÄÓ)#ÊLj4}€ñÙÇ€Ú£þC€¹Æ¸t¿ÛæÔ‰=UqÑ2’ §SHŒÒìkr\i]Ênã9.ƒD3=ú,/šÇ€—o†cV³ Ü ê¨%ÀÜA¯zÔŸÝ@ª¬‚ 6u*º(8ÁDË?>„Â_1½:Ñ 0•BÛ‰,±\¹ýLþœ€ã©Ìå`lÔv»=hÁu|½“ØÓd¸­Ày6díöeÄ(äpô;@Š$µL9¡?5B)×SÞl*pjRd€Fáiª²ØRϲ)<=¸5ÚÝfƒ®¨Àx|OÑuÎÓðÅ#4eK ßF”÷ŸMW—’y“ƃzÃüíGò§¶Y\ +6ýŒÕ@¨+TÀ²4r2<èo³ie† u(¶¾Í²g’wœ¡Ggò¹lMš&Œ«겞êµbÕÁ¶†¼Oó™@a”é«@éfÇ2ü\~Ž!ž€dµ/¢+¨VÈó¼"øqQ +€MU÷ô±ÓµC~j›ºÓ^Õ«CÂéH¨¹á‰Ð{²1ù%›nHc9cŒ’&ä÷’&jý ud¬ZhPhfûªçQÍvËÍ S¬Xê‘bzh³~û‘êÐÞ†Ü$lÊåK<Á–ÔŸ_ËÓIiþ‘”3!³3Å,š»UGò>ÏÝBÊ“±ó\¥äŽW—À+uléi³¢8Wåó £“,cÇU2B›6€ÈüÉAÉášÝCÞQ‹_¤s© +ôPŠ‹-—€ÀÓA!’†rÏhtëƒ5Vaz/À )–LN?'ÕˆJÁè8äŠÈa™ƒ8ÜÞûˆq;¼ +ô³á„S?>åë‚D±ð¡„óö~(³d+Ò‘H'€ÒS½ HÀ4‰·e&Ú]ÿ¡Ùå)ùc^Vù]å_ƒ‚q¤/´]m뫦%j—³é»P’åëMUxˆÁÄíh…Uƒ©9¥Ž‘ÄÈ®Ú:¸»OÁv£Ž43Óc›×÷5¥H¥¦Ñ€7¯©ý¿×±Èñ ![˜Ä^Ÿ,¡±Û/1  %ŽŽ¢ß%BTŠ^ÃRpçuØE΄=ÜÅ~Â]ì_¹³hÖ±¼b¯°ý}T¯‹e¬ÃHc•¯Ga tK\Á•ZÂ_ã …£e8œ#ö;µ´ÿ‚ÄEó {$s…+ŒË þ½"0ò©ôPñÑ ’ù8®(šDöç°F“ªèÜÇ¢ 3Þ.jõ€ +Ieƒjâø Lm*Í?Ä_`âr3Á8á ìi {6äpxê§dRèCü?wÌPU±ô{³që,š¦%?„ÕÄBoéü:à@—da©ÁtE–Žl„ƊИZP”tø-WIÂÓKnËÊ—•Ðù„] 1ö¿w1ö9ˆQTÂŽ–;åîµ9`í.é¼t˜î,Ü´¯ý¼Õ@ðlúç®Ø>ÅpbO.¨ Dº’\qØ•ÓctW$'Žô{v/OƒYæhï†Ù>ÕíÞ ÐÞ7»jI“¨j€¾û¢r5‡™ÇŠ$nËÕh—¼·&¼xàýåÔ¢_ºèvH{÷†'iÌÑå÷yYãMWÓ›¦+4^"_mIynQ±éÜyÕ6D~ç‡hŠw +„Â0½©+¿²;Š8Œ/Õ^„µkŸ‰IÁÐ%Lú é»îqGÁÏ]k(‘X!Æ8ssØžâ5Ý@¶Ä·ÛøâÕ¾«—¹³cèr@ÏCކ= Û¶xí÷¡xó!× —=º¬¤£iËe± ¡Þ'wùâóž8,#ÕGP}Ó´myWùá¶„¼¢¯HútbÓýå?¹ö™p):2_t|ؘ„„ÌäÓSÛkÿ!³õ6•"ë2zÄG•ÉüÁ'¹ã;TŸ÷æ÷~ÔeÛÍ®óúÉÓ‡¥¡í ~ôqº)€@#$Ò +Eùf»‹¼ +Ùóc^í´C‡/Á‰*›î +ÏÑרˆ˃ë ZSme %ƒ‚IŸ F"(×ýµûò©L*‡!׺ókúÛqh•5è+÷/ ÎØ—‘ÈÕg©L·BÅ.‡ÑéXð&‡pÀ¶¯˜ð%ìš¶êò#\½öÒÝ—÷ùÝSWD‹`ÉTbGÈTûCŒ¥Ò$åýçK:ÝÖ…k(Ùséµu)¸ôeôÇ@cÿU®wkzæûøºnvuY¼í?Cù[ñÌ2³Vp±=Zß+úrßÚ瞬 ÜJ%ÚÈt™QBÆåÙì‚«¹á<ÜXtù¶ëk¬Ç“ $-¶åæp3µ!H´ì¯{ÛòËIE)µ„ÄŠ~.íyúUW\ø›‚³\=ÇÙåéõ•ÔÎ'=,ªüصµHÞˆùOÖõÉ.2ÈÏ KG»x¦.îé#2ŽLã„ï¸.v¿0á'U:Þìs•¤9ýF zA†Sn(Câ\ºt¨ôÆ¥•®ðÚÇYA_‡Bï!ŠÀkåÐ>…NœIÐVØR£ kR.F+xˆ^k!Ðõ†š~jÝA€z“8˜XÈÄšú;„/ËýµsGý­ã…-äðt‘ éÌÙÍÙð§LO?ÔžÁÎ}CÅ­X¤ Ì©Rš +G|¡ÚÓR)„=eÛî²c{°^d;»Ú RŽ.ø Æ;?†‰g>ƒ'P¥¾ô<Ð<÷ ÜѸ8Õl‹6pÁÑijkö4'‹Žâ¢0ø›¥Ñªó€exwIÓ—¢G4ʲBþ5ºÎÙ­7çL$„º<½˜ ,³Ö¼„Õß>'ç~Ó%<þ+¢ÖYúæß{~ UZ+Î@8ÅŠ× …‚ëììmÝ©èÿ½°Ñ½endstream +endobj +1337 0 obj << +/Type /Page +/Contents 1338 0 R +/Resources 1336 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1323 0 R +/Annots [ 1341 0 R 1343 0 R ] +>> endobj +1341 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [471.1233 402.3147 539.579 414.3744] /Subtype /Link /A << /S /GoTo /D (query_address) >> >> endobj -1326 0 obj << +1343 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [361.118 212.4953 409.8647 224.5549] +/Rect [389.4645 133.6118 438.2112 145.6714] /Subtype /Link /A << /S /GoTo /D (configuration_file_elements) >> >> endobj -1322 0 obj << -/D [1320 0 R /XYZ 56.6929 794.5015 null] ->> endobj -378 0 obj << -/D [1320 0 R /XYZ 56.6929 540.8756 null] ->> endobj -1323 0 obj << -/D [1320 0 R /XYZ 56.6929 517.8101 null] +1339 0 obj << +/D [1337 0 R /XYZ 85.0394 794.5015 null] >> endobj 382 0 obj << -/D [1320 0 R /XYZ 56.6929 293.4989 null] +/D [1337 0 R /XYZ 85.0394 458.5915 null] >> endobj -1325 0 obj << -/D [1320 0 R /XYZ 56.6929 267.9627 null] +1340 0 obj << +/D [1337 0 R /XYZ 85.0394 436.0118 null] >> endobj -1319 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F62 1050 0 R /F41 925 0 R >> -/XObject << /Im2 1039 0 R >> +386 0 obj << +/D [1337 0 R /XYZ 85.0394 213.7989 null] +>> endobj +1342 0 obj << +/D [1337 0 R /XYZ 85.0394 188.7485 null] +>> endobj +1336 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F62 1060 0 R /F41 935 0 R >> +/XObject << /Im2 1049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1329 0 obj << -/Length 3260 +1346 0 obj << +/Length 3419 /Filter /FlateDecode >> stream -xÚ¥]sÛ6òÝ¿BoGÏT<|$8÷”䜞;iÚsÜëC¯Ù¼P¤*RqÜ_ß]ì‚"eJnç&ãp±X ì÷Rr!àŸ\X '‹,Ob#¤Y”Û+±x€¹o¯$Ó,ÑrLõöþêïïu¶Èã¯òÛÕ/¿ŠÅŽýÝ•ˆunÍâ "–y®Û«ÄèØ$ZL}õéêߣYÿêÜýmccU6sJ.P -€“t‘™·8‘È£§ª{DÈF}K˜ºÚV=£áŠm{hÙn·uÛvÿL¸CçÖ„]=Ÿ¼Ú¹ý·Ç ý2CÚ# \$°+Gì*8L¦s<&2º-¾.Ë¢|tË®ú=ЗÁj™3yѬgÖ”n ÑL³wåaßU_ÜIKmul¥Ñ‹¥”qnŒòTe]¹¦ïfvÔ*ÖÆ&¼Z»ë«¶éH?ª¦ë]±Ž_(ˆˆ…Ýͤ‰³DËyƒ`¢å˜Šä)ç "P!ÿBÕ®;Ý”1¶‰Í.ox¿s]{Ø—ÌíT›9!K•ÇɎרUmÚºnŸªæ‡öè8p®s=5-J áú°B¸Gp¦ãÉ ºtýàá’iÁ^ºÃÖïV)x‚^¢M\³iùÅ5MWMïöMQƒù1¸tô“bêg…»/½Ò/š=k -þÍgð–Û³Ve2 ð9—­jLuÞªªSª¯êeÝ>,g-,•q¶p™j†‰…¥iœ¡ŠM¹¬PŒ¹fe@XEnÕµµëÝ?®—IšD”ÇÓEYº]ï…†£fÍÓ É3Ì x=@ùÒXB”ívâXUuÕþ4ÏyO‘•BdLÕTòÌëK‹Ò2ÖB#÷ÿÀ\@“ÎÆnˆ'²=z”xÝr(-XGÀê‚UjshJº' -¶ôå}çuIÙX*™¾¢K#ª º¨ÎòT¡’Ë T3,œª¤+vÊÃ'ç=Fâ/ ƒÃÆçÊC¤ 8H¨bÖi@:ÀFtîÅqt–Bì´éä84¹Xp7:Ø@ÿÊÁ^®Kcq#G :æS~ÀÅÇ&‡ôïâõT¯pñr5Ê­ŒÄÁŠèçGÇÜO>sƒ”V*§‰É§ÆSìvÞ:[ÌiQÕ³ Ðí\Yá>›FÈÓf«£®Ý2•ºã×Úzíºž‘û¢éŠ2䤀ñf2&8ÆÁSU3´âéâз[p ¥ÏOyy—mûÅ­ÿz—"‹iò?|é!„óVUw’Hu×´BRHPš‰3ã}þïmÔ«¢«º³^#g W¢/{1Õy¯1PáaÛ®_BÖÔW\t·ƒ}é8rPA­.31PÍp1qV¦PNظÅëImð iYÔ¶L4±#ÒŽÉ`:ÊóS® á‰g£Ùãiòö}E fTnrÅë~†`†2Nuô±íÉ„R`Ú ó[PµÝÕn ky#ù‹q ÃÖØE¸,ÑÕ‰ªiQ9*'ò„ò;SPË_da šáa Jy>eb.c—G!3v˜®û¢qí¡#*²j>Õmûù°ë&Iœœä{ì=È´0x eàmÉTçS÷±rElXIì€_å;ù'Bó1ìØí¼;ÔÝæÒ°“ÀŒ}Æ“(çØ—< ÄÚè­+ êEÀâ݃ÏSîhÞè*hrST{B¬ª~|*j!L¬¼·ÃÅÈë,igRjÁÁ3±Æ[Ö’>¢• ñçªnWϽë`U­Mx/‹¾õ!,±!Ô|“EZ ^X¤/:"ç»Y¹šÊ']ÚÊ;bÜ‹ÊvD¡q#fÅãµ+é^ ß(ò‡â«PÒ¨T›éU 邎õ¬*Æ…&e­g¬]§"6Ö¾’õ©Î[û@å%UîÎÚ¹†ߨìòæÕÌîÓÊ<ƒíOv'ûÈÓ‘™Ã`0s€½ÂóÄÌ3è2À÷ï~ddÛ4nÈAµ"A~¯Q£löQ³(3ìÐN­ý/¤©‚#&#SžÑB uµVÙk  |šçæÁ¨.>P‘¥ø{X/»¶üìf¤r‚{1—9¨fX˜zyƒÁÚNyðW -9Ô ñD’Ärx„!+,÷Õ®o÷!¸YàO@¯ù’§P$ûßаë×U‹°É"×—à2­H9ùò[;·fmŸ+GK®ªöþ&ÖúÔǹ¦=½Ü}¢ÑÆÆ"3r²=õ[;î‚¿`á„Ï€{Õ8ï3–ÄÒ×)¸Yº¯€9í¾Ê³°L{É#Îgf E)XWèäG}H°³Ë“®@hª§Šë(­‹¾ Èë<¹S´-œVq3!•@äU¦|ºä=¡9¾:„q€9Œû),9奨XS‘ûº«BóÇ;Öÿ"hó|Ç`EiŸ$õL"ê ›èÃÝO 4 Ÿ}Ñ»‡gš â> 9‰ ‡ |ª„Y²L-¹¯%Ä(jQ¨$zCdÁ½ 'zŠé¾ò-j¼7ïŠ]õlÜ÷ÓùòÊyl²'pOC{þÁç¿€¢ös»%jV2D‹`Ûø<@O¬Fž®ÚÓ÷÷x«£T|›JGoà|gù@ôÒg÷üÄ|²sµÓã^lÎd˜„`‚×ÔQo™N’Ë‘ù6T&9UGˆÒj¹ -=íCÓU u¬¥ónÏ ¢k_ÉË]þÝ7æ,*ƒ«|‹ÓóñL 5¡­xŸè(/6´öèŠ-Cc'‹ctÄøôð•Ų»|įŽëÂR¿Ñv»vσm;(‡ JÒŠž+úd©^÷oW…Kí ÂN½ éÙ3»¶«úŠª1M— Ê„ƒ!BPUIo†8Pß¿%à ùG·€*ß’“o -°bH${^ª%4¬æ¶!LAÃàuEõb±6©vuà²rOTÑŠÁ[žk°w}ÔšR+ßïÛè2êðá±=ùðæ¨Â?@¸ñ5èÇkÍLÿgƒ©2Ö‰yåsÕ˜ê|8¨B±Iùíʃ›ë,ÉLä—9¨fX8í,I¨ TsN´ &n–ÚßÕ®ôAÏi‡ ôØ `H45_+"5¿{»™ÝÖ¾q5ÁlC½:DT“ÄJ¤zjÎT˜¢Áð/z¯8R*ÁØÊ‘sýŒ𢨉õ”‚Ú¸'W]óÜcûDÀ¶hž ò?S+iZ²`.(Ú"äÍÊZº¿5áªfNáÃé•”dö>E…!H@_âÔA*Øj3øœY¹á½]ÑQÄØ gˆÞ¾}÷ööí‡7ooþ¸ûáêíÝÀË”_)2òçÕïˆë °ýÕˆUnÍõ#4D,ó<¹Þ]i£b£• +=õÕÇ«'£~êÒùicc“èNWM’åS–q&% eiåj8åD.rÀÂSÞ}ÑU¹Svsg)\Ҕ䳅ÒÂÂj²0Üj¦œ/|÷ààÄsíŠ/ÕF±kMOp»Å¯ð[dT·kO÷a~çŸÝ!ÐâÑcçàâµJÆu6n[k¦]uÈð·ïôô€”~òÌsþhx‚Gœ1¤elµ’ŒçR°¿^©<‰3›&×+)ãÜ’kÏ‹‰ŠÃ´Ñ†Zuµ«zÛ†¾#_z¸ÖŠ{Ïœ6Ñû-õñaL'™¨è{·ÛßÀQuŒÕò@]·eÑó”)íŠ×v_J×ñ¬vXƒùŸÄóã·þÍÍJ‰,ì# KTÄL=VuMж¨jm£Ç‡ª| ^¾¸”wFýñÀPíŠÏLu ?²™FǦXס¥ïÞ¶íaGï>|gU%œÝ &þ>Ìó_Ü#Ÿçz¥Ò$j÷Ä¡ï@—èê'jƒØm5Â**§ ÏcÁ8xžøõçV5÷Ôò¬ytÖ€)j¸"^bC ¬ájŸÄÙ3¦HÔø˜ÀÀ7‰Ê£õ…LÁEûo•ECsÒ +ùãìCQu<ð[8â‚¶ÝSÂFC¬¯yÃâǃ|#ч‚!¯/ +å²eü]áÅ÷óDc¬„1JLŠò¾pwOíERÖ¡¸U0¹'†%O¡dÎèE³Y )mœk­çàÊã¡«>»Û«b+šŸPYW®é»…U+c5S#ïÈV Üi±‰ŸyBv7`ùcm…ºì“¦Xç}Ò€…»ø—IíºÓu3!lþâºiaÝ)ÛVÀ Jçë’«PÙÄ%A£9îÖÞÖìža‡¾Ñ‡iƒUò$¼[°óŸyT¦!¨l¸52MÆCJy7ã&Fe•©X£ÿ¥Ë;6^ÚÝfáš z6«uîJD]ùKaÆë•,o‰ú¢ü´gdq +>óòÊiaå)“ Å©f¾4(Èóx«ÐŒÀþVáë7ɸÁÁ÷‹ãá~=1¥HCI1.4ÞjÑr¤!b+ŒýêHã¹9Xi0&M è>ÈršÑ³L!f„ X}œìýÖuíñPònD¡Y2 `e“4†ˆz¢*É£m Îý‘Ù‹,# uÁ"µ=6%ÇÆÞÏÒw’¢ž—%câÔf/øÜ)ÖY +Xç¸<#a^Ø@@ZØÀ© p^ó|tÞ^hdøì56(”DˆäW`ö€oœä›lDçž1£´e’È74x¸¿&àvÂ×€ÿcÏéc|Ù¸#vùt?Z¨89—OwÀzaÏ©QPâq³2VD¿=8Þ Yä3'Hñd"ãT›|n4‹ýÞëf‹Á, +z º½++¤áÃh쀻ÃxÙª¨kwŒåîtZ[o\×sç¡hº¢ Á(ôx%™¢;Ƨ—­y¸8öíŒBéíÿBnD¶e×~v›¯÷ßRdhóÿ!ò⥪î$Ž(ê®%h=8¤Ÿ43S²§LuõWÛ0æºèªî¼Í"6Öæ/ØŒ Ö›°™‡¶ëW4õUÝ­@aŸ™ -â,KíåM X »˜mâÌX9߯{<žÔû™f‘EiË’‰$v„BÒÀ ¦“?儾Ȏ ÒD쇊f”gBçšé~WSNþ¡íI…RƒÇ4s ªvûÚ퀖W’¯ôÊ€øi0´otŠuþF¬y69Éçn|£B·0`-ìaîÒŽJÏ7±°Ëñ’¦; ×}ѸöØi53AHuÛ~:î»Y'gÑ[R-® +žôš¥ÊÎÍÇÚ=5nÃr¡ì*ŸÖæ„b6ìÔœØ3…G©òØæ2dá°/X’DŹzRuIôÚ•!€8yD„&çà£Ôaw4 3:‚ +ÜÕ:ÖU?åj(ºbXå¸F¦ +²ij…Î +œxÊJ’ÁÇîDPûSU·ë§ÞuXiS&ÌË¢ÏE} $¶Ôµ\]‘ƒQ‘>+…œ/wdDjI>+wÐRÞãZ”°c*7ö¬¹½q%kA58dŠ"I!áJÕ‰’£邌õ,ì*¦y&Ŭg´=ɱlþBN>A:¯ëÉ_S¹?«ä@dÂåK+HÏ—žçäc3[û.Ôq'µÿtÔp€©èœžj8ô b ðÝ›_¸³m7„ ùPdkÆÙ¬f<–£)ûˆù3|~š+úWDiNI›Q‹PfqéêK…˜DgÃÁ^._úë­,R›U×–ŸÜ²ÏÍåõgaùSãž+©æëûã„Ði¸m-é¶±/„îC0Xª}ß:êà +ß=Mó™¡HÈð¿¡f×oªa“E®/ÁRZ‘rÌå—vnà ª8~׎H®«{6ú&VêÔ´¹¦=Þ£kMž_còIR…]^T$ƽ$CŸ¯Fl‹Òu‹–,‰ó< v©)v‹±$&é‰ ‰i Q‰óäÛæ›ºD \Ɖʟ¦ 9¸`$³`ºÎkŠVC1®#Î>WGÔnwœ8HІDȹ6ù+óïÇþ¾å烠Èüyt\ù·~‡¨HñdŽ{ñ)Ó„­;tü<ÀµÓtZ;MÏTàD +9èàrLÎ*k6‰ÝÇ-¯ª Uâ48­³µZH¤À}§ZÎ%J&vÉÓ ŸÔä8˜2=5›z\Y›3Á…Ì1~I‚Yú/V¬éñÏ/é‹_´f0¾©õê#g•¸8ç4:Ü*M{"`Í{Ÿä]ÔQ5#wV@pŸd'º·=öGš;¾ßåq¢’|R‚¢âÜXZy(ºàtû¾fCî¶Hf þbž^ývcðtÓ>žÏ¥$h‰™¼l—§Xçíò€µü44³Ê Ä 2ù‹ëX ˜‰u‘Øt¾ªïj;­»Œe8à£1DÏ‘0îc$mé! .Ï„j/ôœV{¡ËsŠq_¦üýcŸA–RбP¡ÈG©ð¥•üÄœ U|~,Å/??â+mC_ÎúZ–@ä¸|‘J~èMÂÃ,†º©§Ñ>åRôà Rì=,9èeR”&‘û²¯B±Û{Ö‚"Èt½X›^S ™þU€Ñôþ +ío%`ÀÑà÷EïîŸh€Ê ÀÂŒ(23>ÈÂ4Rp‹-#áë¿ÛP]$ÑÑ+B vÆðOà+æ|º]àë~b@ó]Ñ Í^¬¹û¾–ÏO ;Ǻ¾†£^î}Ð ]Tñnw„Ír&Ãí"Ø6¾èÐ#K’Ç«DàîîG^j¼_SÑ+8_úÇQfˆ&}rO¼O¶²vþX2Ì‹¡ ô?Ž©£r6q2ýI ö†tˆƒ]*Y­CýØtÕ}CEr飌{w`‚h£Å2w—ÿC;ŽS’…_e¨ðs$Ô„ZFØû<Í¡ŒÉ†z"]±chjm±í_AŸ~YÌõˇ +nºq] UðŒî¸ß·nìÚA8lx›AH%ô]Ó«“¥"Ÿ¬’ÚøûU&Üô¢ÎíÛ®ê+J>”š½"B¼,Œ'?½¦.° °ûš”0ê“7 ©†¶g:í@%¦ž÷L· f°:ØE$öbJTíë°ÅÊ=R-ÎýdPv•Ûš,_aÜh2êðÒÙž> endobj -1332 0 obj << +1349 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [375.4723 524.316 432.5882 536.3756] +/Rect [347.1258 451.8816 404.2417 463.9413] /Subtype /Link /A << /S /GoTo /D (journal) >> >> endobj -1330 0 obj << -/D [1328 0 R /XYZ 85.0394 794.5015 null] ->> endobj -386 0 obj << -/D [1328 0 R /XYZ 85.0394 661.0164 null] ->> endobj -1331 0 obj << -/D [1328 0 R /XYZ 85.0394 635.6995 null] ->> endobj -1327 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F41 925 0 R /F48 940 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1335 0 obj << -/Length 2714 -/Filter /FlateDecode ->> -stream -xÚ­]sÛ6òÝ¿B÷tÔLÄà‹_“'7uzî\œ«{jûKÄ E*"eÇ×¹ÿ~»X€%JéLn2Åb±Xì·ø„Á?>IÒ8-D1É -'Œ'“Åö†MÖ°öÓ w834 ±~˜ß¼ý ³I©H'óU@+YžóÉ|ù[”Æ"ž½ÿøðáþ§?ÞN3Íï?>Lg"aчûÞÑè§ÇÛ_~¹}œÎxžðèý?n?Íïi)u4~¸ø‘ }.}¼ûp÷x÷ðþnúÇüç›»y—ð¾œI¼È—›ßþ`“%\ûçË"O&/0a1/ -1ÙÞ¨DƉ’ÒCª›_oþÕ VíÖQùq ™Š ->&À¤ˆS)d/@žÆœƒ\cÑ'³/›e¹ ‹Î§œóH·Ÿiz_wfÿ¬«öìÞ<Î8O'™à1—B]à“f!Ö6=²¹¨Œ®Ëz=+ §p Oy~…k„ðÀes%ù‰ù¦l§3™‹¨ç‚fjVSžG+³èÊgS½°yj›ÊtSвŒ¥Ñ§=¢™ç²9´€…~3)žDÝÆÐ¦¨›=_šCµ¤!mÜ6ÏÍ|Ý•[¢<@Äj ˆ˜ó¸HaÙ&Œ¶9ØÁ÷&…ƒ.û]¶\ÙY³¥±ƒ…^ø¡¾^ñ°“WãY ¥ -óÅ÷:rÎc¦RîvlËúЙd”ÊÌY"XЧn^h°Õµ^›6dÌ^]€Þˆ‚û«“{Ø‚°ö¯„[ÂÔ4ÔŽ]ÞÞ,ÚfïÛ• Ý™eVmŸ–uí€Ë†Nϧ.”¥}q7õ@|y´ëmÊòìDãɾ™‰íuØð Ý™E¹zµ»Ð;«‰8jv]‰ÔU1o´Ã­úõÔÑ8î§W?pzw{ŸÌFƒÆîÑÆ—Ì?MT,ò,½nþ!Öeóï±ðþ£÷Ý“ÑÝû‡¨ 3y‡k„‰ý+3ž§C.æ(Åò^>ŠeÑKYU…gÁo üŸ¦vÈ[<׺^ZêÀŸ¶´†eaÚÁ}-Á¶zÿ5Áº±9)³XBXp´,uuØÚ pâ,É‹¡R½lLmÈÍd¹S)™¡søÑÇXÛ,.-ÍJªŽ&~wÊhØ3ìy4ºmjýT¹­@þ`Íƺ·BØ vúr/õë˜]üÎ Ü)GŠ,ñGÇè 3bÕ.é¯åö°ÅIJ‡Üš€DNs8ÇA´bR\ F÷+BlMG(È2xsÞÙšÀIp%T…ÁmÈ[Ymp†Ø:Stú€CÒ4k°‹Åáº%&y+%²ë–b]¶Ä y´Ê±Ò sÅ!¤Yr‡k„‰¡%Br£ò|Ƚ+xMo‰"=Ê  ]Ó¨óˆµé^šýgÂì/Ak¸}]ŠnB2¬Eæ,m\çá'ùYt“2·ìÛ %3Èë’l¨Ô½Yñ"µ -Š_4+ü ‰B,Øë7/2¯ßávÔoü’~ã(ÐÓo¤ú+V¿q€úä­~ƒ²µ$® ÜmhQn÷:yá#¥(¼[ :#Ñ“Á`ÑÔ¿3&Ö‡½v1¶ ¤rÖxá[5zi–À¶yt»êÌþ„òLKƘ×<¼çíɬKwj…©gcn‡¢·LÈbqðå1Þ:4©( ÅvÔæ¥rÃeÙ.šgã³6 ëÕ©¥9>ÍŽ2±çrIX -9w4Ž'UÕ¼xJO£#;y޶”8tnÇB†Ç\üäIP[ÞK²éÑÐKµ]³£Ôg/>ßïMnOw>eyvþoMÎOxÑ”,_vz,Óo;½ëŠÓóXxí¶ƒëbjØ^­?Ò¼ø=Ö§õGš±6ô=H@ì¸gç>!Á•'‡]5ëµÕ–_Îß‹*LáýÕ…dð©LÎ|œÊ¥ËØ1K ‡HDvâñ|2›2tœyÿ΂¸ ·QuÜ·áëâvÂq ã6жqÛ&¹NÙ:—³7Ã49ìP³Ÿ$Ø3}±$E‘LTªb OþWÚho,‡87Úÿ“ñ8eir™íc@Ë ýŽ!©™ç²BC=Z„*Ø¿ -—< õ ”&u&Ù]~¥b&Š"ðúVåÝyàéÏÆq§ë‘s0)Ç,žöë%¥K3…ý³$SÃp¹7m;â,YÎp ÉdñWÔ[ÄÅUå¶g!ÅsåÎáæÙñTÀt·Øœv&IûÿÁžâ78äB²€ñ€I«™çɳ8“Â7Ó¨Y%3J±œ2v­ƒu~ ¿©í†Á´Å“­úar̵fIÆ£; ‚±  K³ -’ˆŠö’à‚©¼æ iw”nÛr]ÇŒ;RàK`êtͲ4–¶%ZÕCSÏj³v­8Á=y¤ >zNÁšæž$Ÿtë·ÙT\Ø´¿Üh×´%Õ¸`…P²OA¹*³´5IŸi æQ8åþHÊc‡e;VY땹Ûäå}G0t2rkyÏEÊüM³·µÍ€Jpuéº0S¿îŘšPJwŠÓŠàçm':‰n ~½,ú›Üå– ¥1g¼·è ²8„†o5è8‡;†Œ›Ã¬Íaߤp÷¥œ ç–WœòĨ—K×ÁrØî°ä‰ZÂ2P¤‘˽lJ”C˜~®{Šc®|©}1ôêSÉ@}%äš°¤Ð§å“×­KCbŽ„Ëk?øî‘ùª1uyC^Bña4æx|Ňa–B(ÿÓ^2¤º\³·ù»1™üC> ß -õnLåÿ$€ó–§ïh"‘’ý÷ëÜH‹çɱ/-„[š» L}8[nðØ‚ gôuýmkqØX5¾¦F ¬©ñ»„«A,vd± -Õ-ýt[D’ÄøX‹ŒÕ¥²JF™R \¶ÛÐ2± óua|û0щ Ø3ª¨KEe•4² ˆžM˪/ïñt§û°§t´2‚:Ñ€Êh¯ð«» ¹9þƼf_óõý/*μŠ:»;Wê£þÔNUÛ~ªR+Ï»`÷o9öƒ®Lbüv¤¦g}ÍôÝ?ö WY )¼o@åC…-=S6-gçM÷«ð9ëÿ‹aèendstream -endobj -1334 0 obj << -/Type /Page -/Contents 1335 0 R -/Resources 1333 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1310 0 R ->> endobj -1336 0 obj << -/D [1334 0 R /XYZ 56.6929 794.5015 null] +1347 0 obj << +/D [1345 0 R /XYZ 56.6929 794.5015 null] >> endobj 390 0 obj << -/D [1334 0 R /XYZ 56.6929 769.5949 null] +/D [1345 0 R /XYZ 56.6929 585.2486 null] >> endobj -1337 0 obj << -/D [1334 0 R /XYZ 56.6929 751.9325 null] +1348 0 obj << +/D [1345 0 R /XYZ 56.6929 561.0275 null] >> endobj -394 0 obj << -/D [1334 0 R /XYZ 56.6929 369.5823 null] ->> endobj -1338 0 obj << -/D [1334 0 R /XYZ 56.6929 344.1885 null] ->> endobj -1333 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F62 1050 0 R /F41 925 0 R >> -/XObject << /Im2 1039 0 R >> +1344 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1341 0 obj << -/Length 3169 +1352 0 obj << +/Length 2983 /Filter /FlateDecode >> stream -xÚ½]sÛFîÝ¿BoGÏDÌ~’ËéSš:­;­Ó:¾¹‡¶´DÛœJ¤#Rq2þ÷XjIÑqñŒ îb±X‹/J.üÉ…³©Ð…Yä…I­v±ÚžˆÅ-Ì}"g–1Ö·W'/ßè|Q¤E¦²ÅÕMDË¥Â9¹¸Zÿ–¼þáÕ/Wg—§KeE’¥§K›‰äÛó‹ïh¤ Çë·oοÿçå«ÓÜ$Wço/høòìÍÙåÙÅë³Ó¥tVÂzÅYðæü§3‚¾¿|õóϯ.Oÿ¸úñäìj8K|^)4äýÉoˆÅŽýã‰Huáìâ^D*‹B-¶'ÆêÔ­ÃÈæäÝɯÁhÖ/“߀œ¥ZXùEÛJ•…5óÛ -P†L3Eº˜§EëÐb0¬“:¨7+òÔæ¦Ô«ôBÊ´°V¡~ ‘æÔš[ :ÏH¿(aY¤63¥H­VÀ¹Çx{ºÌdrÿUr6ÕÐ4Ò³&S§î¼x¿©0E¡ '‚ýQ"ð/Ï·jñ] ZDg -t—a¤LE+UžŠÜàö.u…Ôžá«»Š•é@mùL}{ßnÚÛOŒÓ4ö“±½ïë¶“Ì]RwôlÚž¶÷›j[5}µæÆäûP‘N%f@I™Öbm=ÏÐÔl‘‹åÁˆŸgžc›’yf6%g\FfËÙÜË o¹ÌR©áÖ !¼>üîÚ]¿©»žÞÞõeï¥Y`  ×TkŒ”ƒF—J›dw*]Ru÷mÓù 𤙒^¿»xGïï÷ÕîÛòM®`m£í n÷›¾=Ž6h÷XFW­®;Zø»°âò²ƒ‡$¬›v·­›[š-ÿz <òpWáÈ]…|&lSõ¸xOc4Ë&›rËPWí>T;‚ê͆ç¥r³ùDo´m¿ß5ôÞ›ý°²¿«Ç³&ñ»æÊ†Ö§2iÖU_áÉA4ÊçvF#]ây®÷HOäÀuE@îìȼàÀÎZÍwq·>–íŽ OLÆŠTIp»Á¸Ø´«rC`S¢ŒD[W7=›¯ñΉ•ÝÌV ; ùÊíC…ðÅœ‰S€0.)ý= lGC+‡X㦦Îkžjw¼œ–1~»c·Ñûû쇚߅P·ä\ª5²'Šä_w“.‰ò bÃA žA¬Ë ‰?óÆ\  Ç…3‹äò亢ç}µC—胣ËIø.cZ.Ÿì6y]v¹eZ2á½EZA—¨0ÈÔ]Xêåã‚™¾ß׌˔©‘â]¼?õÆÈª7Iˆ\¤_H¿ô!Ä›]:) Ø3ÎKF>12’­!D;8 ¹;ÄØc§!Æ¢WõÎ_®«MûÀq©å•âÙq¦læ8И<SFÙ‚\ý$Á¹ËÐu^¨/É2 ÇpÎ=’c —1Éã$Cƒ¿´Yn;#›Û²_Ý1IÙ›úŠLŠO1iòÔ)!ÇL>¢J™§Ê ðfMÚ©!“ܱoêYcuOJ‡ÓÐȶ nߺûjU£=¯|œ'Ïëà,F»± ƒoÅK•ÉG‚-Z$§³òˆ{ŒqJª™H ´×­¿gP+ IE]]@9`ÀˆT–ežŠº}áÏDÝ)ÕqÔÍäuÕ±U‹ÔIó3s çóLL)Eñl(9+ÁZIúí=Ðé†d5býYEI05] %Êç]†ÔƒoÙî»@¿ïªÍ ‹@M;aèÃu®|¢§! Vï7õªîgØÉLjõóÞC:å”Г¹âÙs ¸ŒI_Léò´PJv~Ô{(4g‹¯Çä@ñ &D™£ÇL>æ=½.\TLÙIWmS‘²0Àþ¡% ¢2c%øQÊýýÆ"B -3V<ÜÕ+&íK(®y%Ù…JÎ!+’VAúm&¹Þ!JCäÔûý2[à2ÿdg‡||œ ¼zýTã äÏÏP‡WVÞÇ©60¬}"  Å«™ (Ÿ¥Î¿B¬`ŠË˜ä\¬0àA…=ìüx@ËA®Ò÷¯Çd ø“¹MUAjÄäc&i 晋Áí±ÆnèYyï‡÷~°÷ó –‘Þ áÓ8|®îªÕŸ¤^`Z˜4¢Œí붬›ÐNè]†¨ØÆ$í`…4à+ÿxEè¸oúšsº’¤ÖLà¦Ý7ëÙï­/%Àˆ81;Ú¨1;ˆàe¯`vù®d¤ëʇ€¤¿42ráH­¡'cÈé-†)Ê‹FHÛº©·ûíÜž5Æ;vo÷VŒ\À\P»€Q¬°žÒ9jÍ9¾lÜ´¨Û=EírH¹Kü¾ðûšz_ˆ…Ñ¡öõüÐáXUµçÚ¡®Ú–Þ†U>ÈÄ›MZhHìç®õA .]" ,2]*_*CSÌ:j™±]byÓSÕ…†'àV57…;4SIÅ$¹7Íèa†7£oý3§h0têù(ŽwwíCCà5У¬C+ä¨cª*´Œåm­N~ ð'† Ø‘aÂ[I¶0Mý[OÝPIs®ÉŽ«ml è`þ[¹NMÞ’qŠ“›ÉúDÆxh§úðD}dµS…P}ä3£ˆƒ´l1•–]ãCÁÃÒ¼º¡f¬v7¼{(–fPì”Aš"t!#<”g,Ì‚…9sšé]F‡Ø ±Þ¸®Gll—F7«±Ä^¾1rüI0δß3!’¿ì1‰¢ñ=@ú6Ð÷4$>培À /š»ˆº8ЋG¢D_ãÔ4Ïâcà,ÃSléy(ªà%ÎT‰‹G~„…:þ*p曑~w÷ì(~Š…Ÿ}œS|~Üú"LùbÉ)çøqÒ:•ϰþorc\endstream +xÚ­]sÛ6òÝ¿B÷tòLÄà‹$8yrS§çNëä\ß½´}€%Èâ„"‘²£ëÜ¿],@¥t¦7”‹Åb±Xì'd>aðŸè4a²P“¼PIÊx:™¯¯Øäæ~¸âžfˆf1ÕwWo?È|R$E&²Éã2⥦5Ÿ<.~¾ÿÇͧÇÛ‡ë™HÙ4K®giƦßÝÝO˜‚>ï?Þ¸ûá_7×¹š>Þ}¼'ôÃí‡Û‡Ûû÷·×3®Së…çpfÁ‡»Ÿn úááæçŸo®üñêö±?K|^Î$äËÕ¯¿³ÉŽýãKd¡ÓÉ+ X‹BLÖW*•Iª¤ ˜êê—«ö £Y·tL*ÕI*T6™±H¹×2KX +Z›åŠã½–Ór B-wóͬ*ÛÎÖ³/;»³ÇÇæi‘𜓘÷‰=Õˆ2g ¼PWöz&U1%A&ifnda7Ý +®/cú@»°K³«:˜zAÀº¬ËõnMëÊ–Ò¯½[Ò¸ <>Ûmm+‚ÛÝfÓl»––" hô®Á2 GäI‘¦Â læs (u>ý1QuvëGB¨…éÌöšë©5‹="hª[9y2UÛ4oêΑ6•Ÿ[5¯¬M½'èñý§žº¶ó®lê6°4^Š×²ªz³iMú[®¬ÝaX8©=œ^p>m7fn |5eWÖÏ4X6[OЬý<![á4”fžl¿ncÚwG¸kèKZƒ»E>ý÷u!@;ÛÒde[Á¡j‚¤È6ô”•­»j?<ÝÍÖ”°s‚SGö?*)XÎ$U’ .=Fž%œC¤`ŒM?ÙmÙ,Ê9ƒÇkŽ’·ŸixWÃM¿ÀýDï‚™”h/Ùe?©ÎûiO…bÎ+kjPï¬ô"œ8j& ÂjyY„žjD†¡£æ‰ÒE6âÑ›°˜öRÐÈcí­a‰6úb«=!›§¶©lwͧî>gÙôÍKÙìZ B ¿¹ž)žzÏ„E-p'ŸÓ×fW-¤…ëæÅ“Ù¯›’p ï®9ÆÔìÈ$EÛì0wQ¥ðØ9Yð¢%ä’¼qM#€¹™Ђ\ûëâyš¥ +ÐóÙû:R²æ S÷+ tí:Ûb¬’¹Ot¸aAŸÚ 0˜gÛÆ‚¹£‹L¹àã¯AYÛ=Ñ–p5ƳêÝW¦\|÷Û•sÓ¹ÀA{Õî`šb,  í®A¦.Ö¥»q@7õ@}zºé}ÊÉìUØî‡Â$c±ê——Ë=ÅŸÑæj6Ö(.ze÷!lz/„åp§¡/'ôÂŒf»ßQJÁ–"Oր䉯œEã”ùJ…‘È3ÚœðÎ%4aAÖŠIq†wæÊ)$lmG$.Ñ‚A4»žLgbSñrª6È[ïŠÞô…:ì|¾û†'2–héeOŒ¨.xb Bq,¡Zºà‰2ɸº,B a˜‡¡(R9”nbfðC‘´ع« BF ¶Ýk³ýL”ýh«n‚Îå6!¤U¨Øœ&7žê“Ü&%Õð.eÉzŸ4+†VÐ{/2gŸøE¯Âï“€Ò)¡ƒys¨-½yÇËѼñKæPdÞ_oÞÈÍgœy#€æìyCxrù´×$Πâ]fñT=º€lƒ‰RÁŒcAtg@¹ÍÅónk|Šƒ%®ÝðÎwá[5f%ïL =½YºfdÀ å¡%c.˜nÞËödŸK¿“ï +ÇÎBÉ[¦ä°@·±-]<“Šò? )µPÛ×ʃ‹²7/6m×ÛSKc¼š b/储Jîyâ%ªªy œž<…oߎӅÖP¢A«MFéØÔ£#ÐLóèJÐZÞPDrÕÑ0Hµ]³!ˆvê‹—PnÄ禨gºP±¼øð÷L±wx5T+ŸyJˆ$Sâ1/¦:óz*êç–Ðþ ÑöËÎTø6’r_!±%ʾ ä|Õ4­õ, }j0qö@IïqˆÃœ½'ÔáÙ£_-|]è]Æñ©ˆ{‹%FÁ§%6D`üߋà "¤€—Óc[/©GöãTYÜß,¨dš)Y@œ=/¶øÐ90f®›É?0xñEëv gÇSëæ\$Šƒ¿*—ÆL7_H¨X’i&þ†ßPA›”| ¡3ÌÓ[äy’Cì ÷àž«dNU–·E÷¼¸.Ìá7sïa0lñ•Éõý08”[³4çÓ[Zq`H³ +ꈊ֒›à„­‚á k¿•iÛò¹¶^¿TÁ6ÁôÖ5˳Š"=´”û¦žÕöÙ?Æ Ø#_ˆÑϤmhXòÉ´a™«Æ…«üË-¡6M[RKN ‚{÷T®¢/K×–ôŶ`„“Ond9,Û±8áœWj¿؃ÈÛŽpcåçt/EÆ"úU³¥ßZb.ÑÑ¥‡‘Xýu¯Öýš$¥ßÅ[E´Œî-.:Þþ zYô'¼//%öJcoÑ}‹~›¨Cl|Wƒ7çxÅP0å¾"ŠÃþ¼T¶áØÉú&þ¥ f±ðoXžÚ¦¼!Ñ£°Œ i¬‰]•¨‡¸]î¶”Æ|S‡~hªÉÈŒC3äŸaÉ ;¨`[çÆÌ< _Ú~ïGö«ÁÒå E ŇɘëDjÁ‡Ya–A&ÿÃZȤÀŸxGçì­~7¦“¿q(ä[¡Þ™ÃÄhÞòì $rrÐßù·û±iò´–ˆÅ;²-}N¦—8×qòð ÎèëŸÄtÝ8Ãw€eÚj¤À¶¿+ ¸È4m& °Ù5ýxKDš&ø(°Ó%Ù€R[%§…R)¶[Ñ4‰ €ýŠ¿)ÒëPbAtTÑcNE•T8ƒ˜NÔÐáãîÞöaMéytÿut¦Êš`ðo½ ¶IÎý}L%åèÏìl,ë/ÿñÁá/3éZ‹ñ>‹c-м—Ê•¿üXöTê$Õ"þÔüendstream endobj -1340 0 obj << +1351 0 obj << /Type /Page -/Contents 1341 0 R -/Resources 1339 0 R +/Contents 1352 0 R +/Resources 1350 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1346 0 R -/Annots [ 1344 0 R 1345 0 R ] +/Parent 1356 0 R >> endobj -1344 0 obj << +1353 0 obj << +/D [1351 0 R /XYZ 85.0394 794.5015 null] +>> endobj +394 0 obj << +/D [1351 0 R /XYZ 85.0394 688.9861 null] +>> endobj +1354 0 obj << +/D [1351 0 R /XYZ 85.0394 663.3646 null] +>> endobj +398 0 obj << +/D [1351 0 R /XYZ 85.0394 285.7302 null] +>> endobj +1355 0 obj << +/D [1351 0 R /XYZ 85.0394 261.2794 null] +>> endobj +1350 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F62 1060 0 R /F41 935 0 R >> +/XObject << /Im2 1049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1359 0 obj << +/Length 3004 +/Filter /FlateDecode +>> +stream +xÚµ]oãFî=¿Âo§k­æK¡OÛm¶MÑfÛl÷ÐöA±åD¨-e-¹é¢è?rÈ‘F²¼É]¶ùâp8$‡_²X$ð'&Ó\æ‹,×±I„Y¬vgÉâÖ¾= ³ô@Ëê뛳×ïT¶Èã<•éâfà²qb­Xܬ‰ÒXÆç€!‰Þ¾¿zwùí¿¯ßœg:º¹|u¾”&‰Þ]þpA½o¯ßüøã›ëó¥°FDo¿{óÓÍÅ5-¥ŒãëË«oh&§æÒë‹w×Wo/λùþì⦿Kx_‘(¼Èdz_~Kk¸ö÷gI¬rk0Hb‘çr±;ÓFÅF+åg¶gÎ~î«në,ÿDK•ÊJ5Ç@“Ç©‚%dàÍ}IwZ—›â°íhÐ5Ͷ¹ûD£ªÅ{¾~§E€Mª8‰^,E'"5Û°/M’è/j¶ÍªØÞ7m÷U0®Ë®åñß_bcšƒ|sý<> +ç¹Ñó|L€9"N%ñfíKwýŽ1ªA_S©ã4“6d·qnŒD¥2V™H©Uq’jÇ +⤓‹I¡â3Jáâ=0ED7ð_FGú(“Lf‹TÙ8wlY|\ˆ8Ñ9ŒHÐwà&^_îäâ›®³näÑ.¼î> SƒÀáÙ œ­Mœ[`Ww£4Ô4P‰\¾P¯¢Ô:¶JxÀæ¡«šT.³¨r®­›Ž'vÛrWÖ]¹æ †ä7 ½<ž²K§y,mn¡¤^&|T3“§ ýáE¾L5Çú$3=ð_Š™çkl+“ä½ýi,˜µÞRÿœÛfßm«–ßó‡®è÷õóxáiÈ4P…Aéh.lT¶Mݺ’¤•‚†ß\} ñÇC¹ÿDÝ]ñ‰W°Ž‡ÙfC“;00Èqt@spÕhvÕ¸vÝÒÆ_“\_·Ð‚Ú4û]UßÑjñ¿àà•ûw +WnK¤3×þ˜²ÃƒÀ'h­˜°X;îµåþrOýÇj»åu ©Øn?шŽíûšÆ¡1à÷;»ûj¼ª#w:uýZQÓÆê\DõºìJ¼9ˆ“fù^@ÎÌÅð>·Ä—d@uIοٱz‰Øã­Ð~t,›=#žzp8BH†m{årèîÉ3”^_š›…Q`:ÀÒ ‚ÓâþŽmÓuàÐzøe¸áØ¡ãEr>”+¶#@Œúˆ&‹[€áG®µ‡zŠ’#lÌ~Ô"™§¬E@Ðj[õœò +»%mÂÕfÍpí}sØ®C¸b¿/ê»@†®ƒê„’_J ¶.ë2Ò€ÂÙQKó°¯@Z¯p6,EGëU릲èÐÒ³Â=õ'î¬×Lj[2>²Ó‚逎sêÔ­K”èèrSR[¯x³'ˆ °ìgŽÞ)ˆ»¾kKät_µœb@òÚF…{ŠÐ ÛÒÔÊ=#è¬ñPå/5{ÞNÛ¾Ù³åèÜ“vSõ¯I"ïȾ”k$/É£ÿÜ—Œº ̽ˆ5û1h=[=”í]¶'î~LSV7μmºÍ¢Û’Ú‡rVÑùG›ómʸl69tò¶h=pøz`ºÃ¿ZRA«(ÑÏT­ßêøc½š~l«UÕÍ“êXèç퇀t2…r, “Û¿Íã2Dyü6a%6™É†“Oa3HÁ~9"=ƧˆÌ“ØJ«ÆDž2 lLï +0n'Y5uIÂÂ'ºÇ†:%åªè-ÓÌPô‡€h:ö¨_1Éã}µbÔ.ÂÎ-ï$½ÑåO¤EÂHˆÁõ$Úü4øNÞßm39ns-Û;¤ãÏ È›·?P‡ì¹{A[`ÉxÙbú}¬‘Rb Ã<áÒ¤Á©RµRªÂ x¹»`ŒË圻0þëáàÓ. Ìm®2ûiôŸ¢Q§q.ÓtLä)Ô±ÊLÎü¦ØÃ lCméŒöœñÃ?×ÅTÒi! 0ŽÃvu_®~'éÑ dVI>±QÅ]QÕ¾¤Ð •† áÆ(mPBšpÙ¸Ã×  {¨»Šƒº‚‹¯;ºvÓêõlŒ÷ÞåJs"‚¥å˜p< +w09|_0Ðméè9zÊ5>–’òñfÉüÕ½sq$Á" !îq|¼‹—q+š™à—Í(9|Wسê˜0( Uµ«ºê’†ƒ! çt8͔ӠÇ3âþA +€‡¶ßÛP > ܼ?æäþz.I#áË|ZV’9¥Ðîš?&3ý¦Ûò®ªkJ $©ùh=DêÒ2]NaB—/Iï±-¨áZYˆü‘©ðÆü”:Ê÷õlöw¬³¡h,sÖF'ô18óÌ„|L/ô +;‘@ŒžéD=•C€“ƒTc¡ÒBàÌ|‚1.C”s9„Šmhz°Ï$,ji¾‘=Æ'ˆD¯ ”Pc"O'FKË ÇxÑIiÎ&`Ÿ¤zVdo ˜Föø-JøøÕi‡31p™2Ð +ƒ,«gMÆœl=!ö,Ú¶º«]¦Ÿ’•…f ·,¨ƒ“õzˆifdÄ[M-Cˆé;†% +ŒF@»ª®v‡ÝÜ™#ÆWïOoN[“ŒŒÀœ[oq‰R³–Ÿt6ÍRw‡QÙ bî¿2¼Â‡¢òB¡¨\Jß9Veå¨vH¨°¶£Q¿Ë¹™ð°I ‘ÁàW2êqÆàúTcÆÞ]ÙÍYœðæ-Õ…‡š×]°’<©ãaù¸/2≠µ}EÚÕ©¶¼ +†­à†%ïŒäþwW‚”ëªü³#¸»‚tPÕŒ†ZÖ˹[‰Ml䋺\ü´‘È1Ñ´±x-5-1EhªEÊz €Å¦£«õ5O€-+®;&v¨§z”’Qry0XQý +F§ý³ÕIš/‚â|{ß<ÖÔ½|w(‰µ Bi…!¿QÑϽbüD1:PLÔ°†)*á:ìNùÈ›3ò诫LæuzÁÅܘ«¹Øª¼!â‡)&£u¡†ñÑLåá:ßj¦¡Åóg†ü[&ŸrËŒžññ0·0²®i† ËûÓ5Ÿî³¥3%–= ­ ‡üŒ™™33gÔjú–Ñ Ö½A¬öüQ¿±±b¼`¬­†›|áOÆßö‡/Šôm‰¢¨1i3Ÿý¥û8ùú5­\¾Ãa$lº{Xê:–¸'î¯ãŸ›¸o¾»¸¢Þ¦Ú{b7wE)—orÊ7ñóMüc|S/ä›z6ßÔsù¦žâ›| ßäËø69@`Ædáu±Þà® 'W2|ç‡=9 ²jE×[¥S¿©R&Æß“ÍTÞ“þÇK/þÙÚð›,[{ê³y ±€„‰r¿h9újÐÿ¾í˜ôÿ]ýЬendstream +endobj +1358 0 obj << +/Type /Page +/Contents 1359 0 R +/Resources 1357 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1356 0 R +/Annots [ 1362 0 R 1363 0 R ] +>> endobj +1362 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [242.0197 602.0286 315.2448 614.0883] +/Rect [213.6732 532.1015 286.8984 544.1612] /Subtype /Link /A << /S /GoTo /D (rrset_ordering) >> >> endobj -1345 0 obj << +1363 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [238.0484 522.6184 311.8142 534.678] +/Rect [209.702 453.3093 283.4678 465.3689] /Subtype /Link /A << /S /GoTo /D (topology) >> >> endobj -1342 0 obj << -/D [1340 0 R /XYZ 85.0394 794.5015 null] +1360 0 obj << +/D [1358 0 R /XYZ 56.6929 794.5015 null] >> endobj -398 0 obj << -/D [1340 0 R /XYZ 85.0394 673.0194 null] +402 0 obj << +/D [1358 0 R /XYZ 56.6929 601.5665 null] >> endobj -1343 0 obj << -/D [1340 0 R /XYZ 85.0394 649.1998 null] +1361 0 obj << +/D [1358 0 R /XYZ 56.6929 578.6548 null] >> endobj -1339 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F62 1050 0 R /F63 1053 0 R /F21 702 0 R /F41 925 0 R >> -/XObject << /Im2 1039 0 R >> +1357 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R /F63 1063 0 R /F21 710 0 R >> +/XObject << /Im2 1049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1349 0 obj << -/Length 2450 +1366 0 obj << +/Length 2639 /Filter /FlateDecode >> stream -xÚÅÛrÛÆõ]_ñØ ×{Çnò¤8’«L"·4;Žãˆ„,N@‚&À(ЧÿÞ³7`q¡$Wét<–‹³gÏý’`øG!‘ÔT'™æH`"’Õö 'ŸàÝÛ3âaæhC}¿<{}ɲD#-©L–·.…°R$Y®?¤Q4 8}óîúòêí?糌§Ë«w׳98½¼úé­Þ.Îþù|1›%Húæ¯ç[^,Ü+éq|uýƒÛÑîqéââòbqqýæböqùãÙŲå%æ—`fù|öá#NÖÀög1­Dr?0"ZÓd{ÆC‚3vʳ÷goFoíÑIùŒ(“tB€”M Ph$¼2¬š»â\)–ÞUuS›%M«ÛÊÝc½9̈J‹US>8€UµÛÁÏbívEs_~u?î7eé öîØm¸!_¯ÝN]µÛr7Ñ´¹Ë·SçÛ¢‡”ñJE½¯víÁ¦2Â Ì AZÚc”ôùX6~xš`µ«·¸)ܳ®À2Ø^_r ÌàÎfTYܰÜÔp\bœ~±×K2Áx ÂåQV«¼4Bý.ú <Õþ÷¿¿›âàË£ÀóÁ…îŒ{ êPÏ£­§‰À€p±¨ /‰w‡5ˆj÷É#a}$”#Í ·HþyW}I‘ne³Ù—F†R¦Þ<*û\×$w»1Ds<ì¬ÍÀëÍνÉ=Æ|Wß[Ý™w{·ÍÜÆGs¬‹ÛcéöÀìlñŒé§c|Ø{ëir˜eZÝúÃw'HŸPɾÌW–j΀j{-çly“¶Æ ¶ÊÀV—ðn¬Â¢B*ÀoРye„?!y‘ÈÀ[lÝäM±-v»r_¶ë¬@HÇÞl¬?„åž-•­Œ¢í¹È”( Z¤¨Îú&n•¦“»Gd ð«'Þë„Dpú¾ððyYWnÕLËMe¹²~8ãS:”Ù7Ã0ͨDàÕ"Î -¦LÀt/Ÿ·XD¶…ŸÇÆvŒ×Ðñ¥Ó‹M5Î Ùˆ& ¡FiÖ£ië[¨§(a3” §RÆÁµä!¼eöåùnJôaÀå%ÚÚjL8Ü$•Ê¡(Ÿç$= -Ä)5òæá<ÆèX쑆1’Y&º‹­Ò÷ÅjÂ0(E‹àMŸÖ…q‘ŒúíÛª,«ûú[qA§‹~.ø°*óºv‰ÞEA%AüE-T,0Bʘ‘˜ä¦’a/–X‹q£´"ëG@5" `†ÈI¸"cHÌ='h>4ûb‚mˆlDÒ`'¨Çµ9b%ÿD®Ƨ¸€Æ_ÀuÜçZÀ’‡xþj]móÍnäØ˜ I˜øóo1>Á8ÃI ì5ŹFàuºÏy—='¸§ˆ?bÃta¢=²ŠŠãͤ&4d橼¯Ø­ÍŒ¤~iüyc¼´X;Êgvs`]Üæwü‘z2z)ðÆ,(èüú_Ó¡AjØ@#Nyâ4X4´/Ú»ìË“´é˜6u‚¶Œ!NÛ¤ömòqÚ¬qF¼!a2Ed¿Œé“Ò­„ž\ó#DÇ_(åS„c†Í#ê/dsàŒ²hB,p^7`&õ¯°&>™èÅ0Ëúæ± ´•ŧÜ×î¿åå±hƒôa‚8¥ƒ`OÛ$¤ÀL·å•/U¿-¬?PA€Ã ‰gø.ã -ePw÷½÷¿;1u¸LDw.¿ '†q305çYœH°D þÍ5…ì"2Á|~‡|9(4&ÖÒœ@½f€ã¨àdØ Àk[Oò`‘—ínÿa„¨ŸÀáÐ Nÿ¨vÅTEoN•ª›‹ qåN,˜— Û¨’”êî>Êpâ´þ@è”iò„þ -**œ[ò¤©¯ÔŸˆÅÞó­þnûºÚwÑ ‹d<}Dê;/Q'užï8û -”áÄi©C¯âOH]H¤2¨mø°*7«ÿ™Ô}æo逫ãn=w«›;ÖÅÐ9®|_è§a¦éµNL‡¶o‰ï7ÍÝ “41þËb—ß”ÅÜG¹íx}>0-é>ô«4Í›>)®š_UÛýƶ• ¼Ú”ÛÂä.fÛïß··RÈË»M³±¹‚áa¿ ¯m¿ÇkçC°¹Í›ÕÝ”XÚdibŠ3ö.¡öõÑ‚þÑÂ>q"£z™¡v¶ßÍ ÿ)‹HXÖ>gß%qC;jli¦Àm5Å CÒm1™(îûÚËÊÏüŠßóí¾ty|<Ì£P…B| _¢y^èñzš÷•©ººvOÛáØÕ¹{¸"̬^™‘ò” °àWn?ºËÅÆÉñ_åÜÙÏý„‘þÜo0²ƒnLgÚÁxË–2]åǺ3·‡xúÕ Vef +7B³<šÕùÉ)ŸlÇx^Hfi„d0ù™.ìÜå¿yT]QÙÓ…ƒe$nCN°©èŸ ŠLÚ'"wúxk¨µÈDŽŒ„É1šB˜Ð¬¯€¼¼Ïêþˆøtä}$ËÙ×y;Gƒé±Ÿéã?É­‘ó.ÇÓ¹q½Ì!©uì“IÉ´N×û}‘[Rºæâa‚·vþj…¤fƒà Õ ".\RnŠúîB¡Ñä”>ïà &[ ~²à6qˆM@¶ ¾ rû}‹P‰²,êÖÐÖô °. H€¸8u)Úxâ:0$ ¦ÿ¢I—𗦣R€g`âD0„t÷può9!s­™ŠÖ–×NvãõÕ–&?TÀQ1ÏcÌ–)Ic/Ufà÷g/´ãé -Œ™3ƒ7……YвÈMp2?Lž6OW˜•“â\wãaÙ›ïpcòR·F<ƒ#ÎgwËa‚£Œ´u4^7÷­«Âf­Õ,êã~o£é.ÜŽ­qLX™AýP¬C`3s)À “˜¦ ‘:½1ä=¸5tàéÂMè€færã1;€‰ó+÷éDû¯#:5å–ÁY†C.þꨎ‚Íf[Œ °ÅÌíƒï–G STйæï½Â.Sî£<+üêŠÇ¢ƒ¶BÝÂÑݸJ‚R‚*­’؃^æ”Æû…£ùŠ*éñˆÑ÷s–i5Ý 0ÍŽ¢÷qNøsËRô¸óÚ˜ -u Ú Æ¦>àäÉV󹟟;ž¸™():]”ùâ¢,KtDyøN=&ý?o>¤Uendstream +xÚÅ]sÛ¸ñÝ¿B“'¹sBðIÉ“/g§¾¹sZÇN'—Z¢mÎQ¢"Êqt™þ÷îb¤¨Ø©¯ÓñØÁÅbw±ß°˜pø“Ì0®¬ž¤V3Ã…™Ì—G|r ßÞ 3 @³êÇ«£—g*Xf™L®n"\ãY&&W‹Ó7=ùÛÕéåñL>MØñÌ$|úãùÅO4céñæÝÅÙùÛ\ž§zzuþ/OÏN/O/ÞœÏDf¬—Ãg翜Òèíåɯ¿ž\¼úùèôªå%æWp…Œ|:úð‘OÀöÏGœ)›™É¼p&¬•“å‘6Š­T˜©ŽÞý½E}uKÇägTÆL&Ój PðŒYmÓIj,K”TN‚ÿ~LLfR1‹$Ï„`Ö}|y°0)³Jfæê®™$Éô¦®ªú¡\ÝÒkñ%_®+ÿí¡¬*Ý–ŸýÜæXdÓ"oêU~஋»üsYoF?؆=ªzž{Dwu³¥Q¾ZtS ë=%m3ßV;š™×«¼ Ç7 “>­ŠíC½ù½=þ¦ç¸ƒI¦%b5é´)—e•ohr[û§#Îôˆ‡·úfð9_,ˆ–¦¡‰¦Þl o¹¢™ ¹ÉT3˾x*.‹f]¯š",+VÛ>Ÿî‹MYxoÜ&õ²Ï§£E)äˆC’#Žè”ʦ7ùgd'óÕŽÈ>[}ÑâL'Z÷ Ó¤IÌ~%6Æšž-øÒ²ÑR1ÂO Ä ¸3Õž}&éìa*§Ç@ ¢<ôâ5 Ö´ì&쟓5LÑNd’oi¦É—E+0¯yÿ á#°<¢}p0Ñ‘ò@ŒVõ–×=Q‡Š#3í™ûÀL°*ñ¨Χ_Ýö‰a©QºOÄW‚p‚B}½O÷~cp _¿ <l8p2ê58ÓT‘—B×,&4¸j//›ÂKâÝf¢¯3ê©$’„äŸw…ó +fº¼¯¶e뜼zÔî¹h$§Ùb{¿Y9Ïå*ø¾jÜÙá7ï—–ùŽ&®=šû¦¸¹¯hÎÙ.áÙRÙÊ ¬ÛÄuÁ2 1¯'r·Ü9xDÚo}<ñ\'$Á§ï ŸWMM£í¸Ü²B¸6AÁ÷…¦4ãReöÃ0ÉPF³$50$&9×íéÛævBƒË(=à³Þeý͇X‘ˆ÷à%éP\zE6¨†i™0¥LÖ£h/Mi¡!dRÂè<•%´‰îû¶“Õ˜ÜÌÅR/ÎVQcÂ…DP +À2IÓ§$l’Ù,ËÆÓµY‹q£$&{ÄI g­»Ý‘¯‹ùˆZHÉ47ÁîJš ù#ÔB?MIXóÊû[¥åi}˜WyÓÐF¦·Q ù~£ª'1-!ùþ4dáJiû|‰Œ³¥“X8áÂî6véFÛ‰ù\–ùH’ù°Ý­‹®Á­‰D= @1Ó‚H‚áñOcºÅøÓR¦,ÑÊ>ƒë¸Ïµ¡úÅ¢^æåjÏÓ€–ZcíŸÇx‹ñÆ•4Ðì1þbŒs˲,µ}λÐ9½d2Ë’Ø7ŒgèêQ=m0!²ÔsÌ… d¸˜¹šÌÛŠ›*ÅÔÑžK´ÒbñÌd>®ã‚Eq“CÔñKšQ÷U]’³?¹ø×¸kH¬ºË—yâ ½ÞIë¢ÝË}Ú‹\ãëÑfEÖìû~£„º\PtÊRÄîî æù}S„žÛ.î~uÕ$® 8:9ØåKÚ6žQHˆÉ÷tñZ!W]ZÙ;i%(‹©ÛP„#lZu]»Àûd͑ӣ¹¿AjBÇ‘ŠÐ9†<9c\ÈAžœWù®é·ˆ;Þo9×ã: mç¨1½/Ƨ;úØÃpä‘’;G·çöSfm¡v×OnI&h{ƒöZà`½.rGKW_ìF˜kðp®”‡p‚éÀy‚Fm6©Ê¢a‡® …ÑLiý¤6”P![£æÜ™¢ÖÁÓ]rX1pÉÝý,&ç=×Öê¨4|¶ˆ0sÐäÛ.¢ƒ0 ñT„1£d8ˆwà.Äô +þÊééP0€S  ÌbOõÃäÓD0®­U§ÜÄËó¥œüT?“ˆ¥€w!v,A(‹›t)¶œ0M3XDÐ-Â9(³؃ǼG›¢*rtNø‚aŸ”~àÈ‚Fim»öpÒïkqÆeb[>†%¤ÇÇ’wý‹e '©hk먽Žû-êÂæ”ÍýzŽ« šq)º•cHŠEpl`pÄࢻÀ‹w¿k§×HÞŽÆPƒ#¬ÃÑu@1sVzÌ0²~NW'ÖߎØ)f[ˆ³ +‹ÈÿÚ(‚—m¹,ö p¹ÌÍÎ×Ëðçs´Ã,â½—×¥]êÁ“,ø©Ë‹[Òå3¼Tà ðìö“$›‚çCìçy‰¶o,èÌw$Iú ¥Y–X9Ö»ç“GË¿§þCCçM4öy2yà6"$TÊ0ÀEǘìÝ<´ÿúÀ"âÿžóN»endstream endobj -1348 0 obj << +1365 0 obj << /Type /Page -/Contents 1349 0 R -/Resources 1347 0 R +/Contents 1366 0 R +/Resources 1364 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1346 0 R -/Annots [ 1351 0 R ] +/Parent 1356 0 R +/Annots [ 1368 0 R ] >> endobj -1351 0 obj << +1368 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [325.3322 596.1482 398.9856 608.2078] +/Rect [353.6787 530.3947 427.332 542.4544] /Subtype /Link /A << /S /GoTo /D (the_sortlist_statement) >> >> endobj -1350 0 obj << -/D [1348 0 R /XYZ 56.6929 794.5015 null] ->> endobj -402 0 obj << -/D [1348 0 R /XYZ 56.6929 666.7383 null] ->> endobj -1010 0 obj << -/D [1348 0 R /XYZ 56.6929 639.147 null] ->> endobj -1352 0 obj << -/D [1348 0 R /XYZ 56.6929 513.4583 null] ->> endobj -1353 0 obj << -/D [1348 0 R /XYZ 56.6929 501.5031 null] +1367 0 obj << +/D [1365 0 R /XYZ 85.0394 794.5015 null] >> endobj 406 0 obj << -/D [1348 0 R /XYZ 56.6929 101.3093 null] +/D [1365 0 R /XYZ 85.0394 600.9849 null] >> endobj -1354 0 obj << -/D [1348 0 R /XYZ 56.6929 74.6262 null] +1020 0 obj << +/D [1365 0 R /XYZ 85.0394 573.3935 null] >> endobj -1347 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R /F21 702 0 R /F53 1017 0 R /F62 1050 0 R /F63 1053 0 R >> -/XObject << /Im2 1039 0 R >> +1369 0 obj << +/D [1365 0 R /XYZ 85.0394 447.7048 null] +>> endobj +1370 0 obj << +/D [1365 0 R /XYZ 85.0394 435.7497 null] +>> endobj +1364 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F53 1027 0 R /F62 1060 0 R /F63 1063 0 R >> +/XObject << /Im2 1049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1357 0 obj << -/Length 3401 +1373 0 obj << +/Length 3269 /Filter /FlateDecode >> stream -xÚ½]sã6î=¿Âoç̬´â—$>¦»Ù^zmö.Ioæ¦íƒb3‰fm)+Éɦ¿¾êÖ“v:sɃH$@Ðb‘À¿Xä&N”Õ‹ÌêØ$Â,VÛ“dqcߟƉR4Æúîæäý'•-llS™.nîFkåq’çbq³þeùáŸgÿ¾9¿:¤I–i|™4Y~wqù‘ –>>_~ºøþ竳ÓL/o.>_øêüÓùÕùå‡óÓHäFÀ|É+™ðéâÇsj}uöÓOgW§¿Ýüpr~Óïe¼_‘(ÜÈד_~KkØö'I¬lnÏÐIba­\lO´Q±ÑJÈæäúä?ý‚£Q?uN~Ú䱑:]DJÇy -kÌJ9‰R‹2cãTIÕKYŠ9),”ò¦Øº¨ë6ûÛ2‰µNÕb¼æåk†´‘ÒÄZfé”öµëZ¹–ËîÁaC-«ÝöÖ5¬ïèÛºU]­[Bèj®Š͑˂Fp'aBó)«u¹*º²®àüU’/‚¯Ë¶¸Ý8^W+«S±¼g¬_“Ü<”Ì|A<{âT9´…Ô ÜÌåçFo<Ò‰‰½[c¤ÇmNE¾„]m·®Z»u ÔÐÉòÆo -´píîŠÝ¦£N ¯Çô¨„Í{úi’ÌÐÇó‘*àà®DBknËj×¹–H# ¨ÖÔèÛâ[¹Ým©óTlvî5v²,–VI&%òy~ÒX'bÄŽ:d'>0=ÖïL¤±•&{ÃFX¯AÀBF`£Qå5jÖ€%-­}~5ÃÀÄ ˆ@5åàæÔ‚ƒ(¤aíXïV(n©—•ëžëæ vMq‡ã¿&‰\Ñ8Œ•ÕŠæ­#È£kîêf[T+÷!–†z#Ú®¦‰-UîLæ‰1‹ª}vMÏØ@¤a3©QSõ>çž Ò‡æn4×Y0¶dÞÚ”ïl c ~xõ¶G͇z× †·o/2¶‰–ó`à«¢ªêލ¸o+çÏÚË«xanP…½€E‚‚(Ôs¹Ù›¸eÔ–8øÍ {¬æ4_ÎVÓ7coÊ”ÀwÝñ®›bô¹g ê¼.¿wÔ%¥noY^wIc¬ã.©Ç -’>î‘4\*Z毓ï±fèO=ŒJ-¦ ðålÒp¤ãûÀ[0Ù4žÊÕÃdÎÈÍà8cÚßÞÐ$ϳ.«¢y!ªæcÝ–] ¦÷ä •Ž(R2÷fçuF×Y¾§2Ãý™kò0ð­+$š›å³s_„Ä2j¢’DZ¨åAý‡ÓïhöïÎó\t[¼PcUìZÆ,üFõëÎ5¥còÏ`ϵk*ê_C” ¢úï' IÏ.~|Gso­ˆ›L¦.9Q*_nê¶Ã–%‰¶¥Q n ´xëÖ%h3\]µþX±;owx`ˆ[0ôòš¾þRÁ{¿}Áßû3j‡†£¢I^ÀK½Ùy?=Ù Õ#IsåÚö¨™\Å©öu;c·³ËÛYYEM]wíalc%Àz^%ÝcÍÐV{Áš´ZL‰óÍ‘#Á²ì:Jü’ˆÈ—Z6ª–†º‡¢£–WsDþuWr$A£l¦9yº˵ݯPÍ÷¨Ö„rËF(5øš}#,V+÷>9þSÁm>–W’ƹÉ,_$ræª1±Í £ „Å `Bâd”MÌŸÉ×TîÓÏ|>_K0²‹'q|-š—ÀZܤûKE;ˆŸ€¤z¬5½A ÂÄ©„{Þ@à¬Ò„Äz9’†IA©¼Àb£úãói” -*£T.ÏD‹*8Ã…†Ë]ÊÔ'•‹¯ 'ÚZEX£¶ßí x±•‹5ìi1ÞVX9/í÷Íñ[ÌäÀÆ‘S»ôŠ–o7R#ºÍPÑ—³hÙƒ×6ƒÌRѱHÿÞ)©–´ëGCŠþ÷t(wƒh.Y¦^ @†Zƹ"u;îÍz,â•÷\Xåºì^"ïþ¡wpþ™‰³<—‹1Cϰfø˜x6`7K!Èœ0rýèV%æ(þîËB@eƒw ÷nYx® Æ ¼ØÁMé}õŸ\E(/¯¯Ï?v^±¥ñb×Õ[Hd"rQYçR™©‹ZÁU÷·N—÷®r ‡Ð-ZþÒ‡W&·¥™wø®_ªb[®¨³{\Ã</Ø}Ù+ -Ÿ€JiÜ€¸P¨4ØÜ³y]N¡ÇÆOáp]ŠáVœ;pp“‚àxÇ‹hBõ«q’/ˆÿ å¾=òÝäË-o†þˆa¼œŠ¾~Ä]<™Ò¾u LÑ ÆgêõnƒñK"BPŠÍv¬”x¨Ÿ©±©«{jݺ»:°‚}Ïê µé¦¥ï«§è÷I‹Ñ—†{ýÂ3UË‹;õ)Rà/š ÷ˆiÜ ´§ ò”¼éÉ&oÈ#òŽÅ{M 5â,_=ÀVp 1Þ&’®oO˜NÀ/3È'0 ƒ ÃÀlàÌÞPV_6zÃLø¡àŨǦiš÷/EEC}†ÅkXµy.û»éRf‰"}}^Œ - -±øMðFC踜Ù؈g›Ïçï:‹¥Èr¾¯Õ\ö.tl¥!ïÖ»/ŸJTWl£…ØŒO8Bm쇦Lxwߌ&ˆ÷’ú¸,ê£Q¼G€ yt|þÔ‹ÞH¡ã ‰°Ô‹+š–Ë#2ÊfSåõ•†4M†L¼¯5x¹åqfS5Ї¥œšÊ -cI.õȾÔ#¹|$1ÿ­,ÉUxŸ>T$—”$§€ÐÀÓ¥ÖØä=jàbµk^uûDÃr@ }H(9Íè×6å¶ì«ŶÞUþÖ\XmêÕ®M|qÏXÜ“‘ìetX¦A÷oT¨» ö4Ì*LüC Ý‚H6ëÖcš’›@ÀÆmǰÖAà ¶` å#UÒû„%ÔpýùŒ ƒÓ§>ñ,¬R -’©W(!$DfY6)'*É2T;áÄo7¡8ËáÞó%£Òýj¯¶ýT4e½ã¢žk³WŽŸ”.õ£¹)Ä£«¨7j@c¬ãÑ\Ž‘M:ªêµ;ÌQSÈ -r•¾ÎB5ÃÃÄß@¬Rm§LøHî!BP&Æ.BŒB:hûóâ—&Õº…³æéîÄL•7@ðן¤/ä뮨º°<|€€Âà`.±¹Ý»'½ïŠy¿“µCë¹ì&C•{¦‘ÿ:ÿß©ìÍCþÂŒ„4ÕŠ¾Þ)f«°"‹­’Ù±LµW#•ÆBgê 5a½¢Fk_‚cÑ¥<Á­g¯óÑcÍ02Ù³±Ì§| š„ -üœñÀ±ËC½áWŒ^› íµ ñûѽŸê}´8°D˜k@¯|¹Ë? •%R0j«Rj¯ö^èºðìÅÊçKÎárý*X¦ ^Õfõ‹ù~C¿x{­“7^ÏÆXÇõ«ÇÚׯîåѾŸYÈ…“ôuz¬&»Mu,29eaP-«)&Òpøåit®>Ò{¿¯°ȳJ-tPÖÐãôù! -Z|úÐâ虣+½üâ˜Ú(æÒûeQ ¬´*ÕFcQäX¡ú˜hØ(øððÎkŒ2s/«XYè fü^Ú£m¦Ä\o:ÈÉë`V¾0‹¦Ø:еE¨xCà L„moë'Z„ChAGŸI -ÃXF¤ûY`Q~åA7Æ"êý"mw3E LOð¸º+²ÊÞ¨±^Q÷€ÕWŒÝ¸Ð‡‡wýcù,ØcwÍË!ndåøÃÞóÕ-ôX3{˜dåÒ¥åt7ô, -ÇÙuK¡;ršøá! èîË€%¢±Bߺ‡â©ô!šRKÊ*¼ÖÞoO£èe>ìH=È|Ýa¨Ð¼0–æˆð(š„Æ -ò½ûþç H¨êúɘåÆ+&´»¦¨Ú;~DJÌòçIb¹†O”×ĹXž¨[;JŠ,ófCÙ ¼h&ëÝÊ;¬„C޽ëž§÷Öœ$Z”Ãôö¥ŸD-Ääp&p$¼îÚe»)ž¯„å׳%|hA:]Ý´!céºTOÔÂg-O!`fÊfÀ‚\©=–ÛùºBªƒh3dP§ÊÂÖ#vx¬¦¯†Ç¡~ÿrâa¾*ОbgOõöP{}!x0È}ù¸Ò{'ÿk¡GrSž3Z´Ö=詤Ô̓ )¥–ËûM}ë“RŽð'F,\°v†³‡ŽÏâ¨Izp°ˆë³üÉS·»%2Õ2ykÙÛÇc¿hS&ÆŸ¡Í8™¤-þö¯Ý†Ÿê ²‘\ñVøî#m˜ò7žÚçr“Øä2›aýß9oendstream +xÚ½Ërã6òî¯Ðm骃'IϬ³‰g×v¶j+É–`‹5é!){œ¯OÝàC¢äì¦jí›@Ýhô›â ÿ|¡Ó$5Â,2£͸^,·glñsŸÎ8áÄ)c}wöî£Ì&1©Hw£½ò„å9_Ü­~‰ÒD$ç°‹Þ¾þxõé盋óLEwWŸ¯Ïc¡YôñêÇK„>Ý\üôÓÅÍyÌsÍ£÷¿øçÝå N¥´Ç÷W×pÄàãȦ7—/o.¯ß_žÿv÷ÃÙå]–ñy9“î _Ï~ù-VpìÎX"M®/ðÂnŒXlÏ”–‰VR†‘ÍÙíÙ¿ú G³~é¬ü8K„LÅŒŸ 6I*…ìÈÓ„k c,º;çÂD»ª¬Ç“Œót‘ ‘ˆLçG˜A¤xŒu‚—€åxÙ[wÝfŸ° 3&?M8 Í–#Â&åá|JøÖv-ܬQ·¶QµÛÞÛë|¶vYW«º—Å׈¨ÀwŒ° y›”Õª\]YW l’åÃñUÙ÷K»ºÝœèyDX¿2ÍîÖ%±OÍž,e0äàsýùŽÆçŽÓ Bjsž­…ÇmÎyÁ©¶[[­ì*jèrÐ(Ðõ•}(v›_}5¦Ï¥JLÔ~ÊØ }Á%¤"w*ÎpÏmYí:Û"i7PT+ºÀöøVnw[|y.6;{Š,K„‘žÏó“&Šñ;ò䘤9+7Ùi c·€Ë1+¯QsvÀ…å•ú4ýk†±¸?šª|ÊÁݹ…QMÚ±Ú-¸…Š*Û½ÔÍœìšâÁÍÿʘXâ<^Ì•Õ×­Å‘'Û<ÔͶ¨–ö;7bèraª7Ø¡íj\Øâ\eÁdž ³¨ÚÛ´ÉŒ Ä +î3ÕrªÞ‡âÜ“Aš')ïµÒ[™Ñ®µ+„¼‘óµò9($Œ!Ç­œqÓºÒ»€àÔ4´¶-Ñ9ð¥¬úù@+È#LªàyüÉݽ"×tVŒ„d°Yo°‡B‚XÂ?ñg„c´àƒpm I®²`ilÞÔ¤H”2ìàDWox®ë]3XÝç¹H Sâã|YTUÝ!ûmiý圑¼ŠWâÆé¯°„ˆÈœ`'ÚôRn6è#îÉÿ´ån}óJîª9Ï!r‚“·ÁÕøÌÈ•%p\´í¦˜>É|:¯Áé÷G\¿R¼áFX'üQÀ +’>îŽ@JƤò4ùk†þÔ¨³,2@‘Y§!¤ã` ƒ¡Á0/ër¹ž¬ù7Oטö¡@t;«²*šWqªùT·eWB0~¶!<¥ƒŠ¥È½ÙyQ¡eùžÊ Á3Wè^àYWŽh®£k¿à#–!è”Í V\F8‚ž[þ€«·žçG·Å+Ëb×fá +¨_w¶)-‘ïh¹­]Sáû-dà ªt¹îÅÕßáÚ{‹;ºC²©ËqœH™G›ºídP¢-Žâ¬Z¼µ«´gnnZ­v'owîÂnA£×·øôÅM<ú㻡 ø{wpH_ðò(…@šˆàÀ PT©7;ï¤'‡Á«zBi.mÛµ3­2ÈtÒ7âþë¸õXÞÎÊ*nêºklŒ1X Ös’t5C{bc•eSâ9rÇE°,3$À¯Ò=QDèK U‹Sݺèòj®ƒÈ¿îJJ#p–Ì4GO7`Ù¶ÛC ã5ªùÕQîÉ…J¤Ú7Âb¹´Oà““?•Ùæy¥I®³œ‰˜ 5"(NÎm ôi¦%±&y« ”¹¯oóù‚´6ƒM3#Žï…ëìE`X1Ý*ÜÅ +Bt®Ót¬5½!úBBåb¡ OÓ +ËŒ‘0t +Y—WŽ;¤SŸÏÁåCB§":¨”sˆ +P®.h"˸r¤_mwö‡‚ +yn$ÁJB…­œ¸±¾öZ–oŸ6Š" ån Â'µ2·­R“ˆjб<ÿÚI}jXöÐøk + “äyf¼±W’tfŠå ½áÌz,Ÿá•1Ä«rUv¯±÷þðvàØàv”âÙbLàб¬>&ŽM W^Nù¸}²ËÒ•'>òe!ȲÁ·Á ÷mYŸÂ°\ã-€äbqÒ{*|YÛ +Q>\ßÞ^¾ÇQ8xUÄç‹]Wo¡†‰ÑAe,JYOÔµ‹Þ*meJ áµhé‰Ú–"Þá¹z­Šm¹Ä—ÝÓ +6 ….¼î‹^`BË|!M +†m¼RádóHæuói¬0„^ÂᾘÁ-©.v@ãö¹‘2ÿö7Þü@z¬7x8Üê{Ž PòýöD‘ÉwZŒ‹ ýÃ|9}ýäNQÐb,b(æhˆ)˜Û$7òz·qÙ ã!%u`;VJ7°®_ØÔÕ#B÷ö¡¬¸wÏê+Âg¢é}µóý9q3|ât¯_.½Letõ€³¾@ +üÅsù2½‚¬Pê,$V‡:/¥Äaöž°öˆ#š?Lòw +Ìa•o8”à=|6ÃÐí©¢ü=ê,Dô£e)ÜLb{£,cÏäz¬pdÑqU¯ìay*!Õ”™8ÍB5ÃÃÔÝÈ„qHg'Lø4îÁ ‚‡ŒŒ=åsûûäÕø¼§µödK•7õÎÖ_£oÁÈ×]QuaoJõÁI‚Ò¸”'Šçfßç>Nšx¿£¥ôRvëÉTe_€ôñ—ÿ9çÜðq#ÿŇå©á¢o¿Îºp(ô¥È¨½ +1™dJ¥o¨Ðë„ +¬} +>uFtæ:¶â4=Ö #“3C0ô§œ zä>%ÐGŒ5%.ëzCß.z]Øë’k¿ï'ö~©÷L"¤;~Ì6 X¾Ïå?z -%Ô°S1Ò%¨Â¥Üû.×…]¤}¾×"ëÿSÃ2ÿ-‰÷*6§aÄ÷ÆÁftž¿QnޱŽkXµ¯aÝë“=ôQP–(%NsÐcͰ09­ÔPÁi=åaÐ-£0#Rpûå3ª¼Ü|ÀŸøÞ*y^rþÉhôOðNߟ¢ëˆrgÊ­TôŵQÆ¥ö¢.­RrèQkWñë=·õ¶€[V< Q:ÕZê¹/ªÔWéÔ»à™ÒÓâÊãÔçÚE:(Ñ«`X +OESl-¦Ú<4»@ν­ŸqÊ 9Þ<&õ;L»"ÆgîúñKÚ1Rï7i;ˆÍ˜€w…Çžñ„ç©~CáGX'>`õÍbûnt»Äá»þ#ùì°Çîš×CÜ0xP’ƒj§,U§ÐcÍœaR’§) +¤P“CÜáçPn•Ö-¾@Ý¡ÛÜà€øßpÀ‚þFÙ¾ÈÝ/öû½÷v]<—>E“2ò·,ÃWÚ‡àïÑd$~Ñ…¹R‰ßb )tßL^ KQÆx˜M°„rï±ÿÙ‚#ÔŒ uýbÈË‹rãà®)ªö¾1ýÜî|êËéUp.‡G²ÆŒŠ!CL™Ð*‡:@£BÉx‡â +wˆ÷»ÇÂ÷è½='Ö.0zÿÚ/B` É8\Üí;”„&j7Å3áõÞÜÖ«x®Tu_ZKW7m¨Tº.dÓ}ðÕÊsÈ”™²° FšI‘É€Àk»_QÍè1ëØ_þ±ÖðK6¨­ežùÒ)²> endobj -1359 0 obj << +1376 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [318.204 427.0782 366.911 439.1379] +/Rect [289.8576 392.4739 338.5646 404.5335] /Subtype /Link /A << /S /GoTo /D (dynamic_update) >> >> endobj -1358 0 obj << -/D [1356 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1355 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F48 940 0 R /F62 1050 0 R >> -/XObject << /Im2 1039 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1362 0 obj << -/Length 3826 -/Filter /FlateDecode ->> -stream -xÚ¥ZQÛ8~Ÿ_‘Ç 0ñZ’mÙ¸ÃÝît·‡Ûv¯=°»žXI|uì4¶gšýõGŠ”b;Î ‡jJ¢%Š"?‘ŒÅ"„b'A’Él¡³(ˆC/Öû›p±…±oó¬ÓjÈõýÃÍwï”^dA–Èdñ°Ì•ašŠÅCñÛ2 dp 3„Ë·?¼{ÿ㯟ÞÜêhùðþã‡Û•ŒÃå»÷ÿ¸'êÇOo~þùͧەHc±|ûÓ›_î?ÑPÂs|ÿþÃÔ“ÑãʤŸîßݺÿðöþö‡¿ßÜ?ø½ ÷+B…ùzóÛᢀmÿý& T–Æ‹gh„È2¹ØßD± -âH)×SÝ|¾ù§Ÿp0j_ÕŸ©9£@© -LEgY¼Ðq$ -†PÝÎО>|CÄñV¤K³¡G»£Î¼.†£ÝñDͮܛ–ɆŸnÆö`Öåïa( ¿û”W½iƒ ¥‰@ ‘,´LÇÙ•MÓjÈE{sFâ¸p¦¨ÛU_Vmù§™®.d¤Zd//ï¹fÖêXÈ8Hc%Ç|6U’vÊI–yñdŽ]Ù’nôòþ‡Ÿiä×~¡®Ç~ƒÊÞ˜#µ­ô–¥¬™ãÔ¡>WJ…ËÝfr™WeA,¤kbËéШ It^z…YBÔïaò{ ¤Å*Š` àƒ+!‚,ŽÉãš¾kË'“¸×Éò˜×[î|.«Š¨GîiËÊÔ]u"Ö¼øOßv¦€å -ªåƒU Œf“÷UG¯YYˆtË °Ówú¶ÏyAÚhÞ65µ7Í‘%0]WÖ[»¯ÐmHÎXÇJ&¬šGͺ©WgÁ’Ä –°`þ•d¹5ÌCLj“Ôí³9NØyÛÒp·³B7ývGCÔþbjj£ѾžóªòoåÝÜf«fý…¼msÌ·{P»ó¾C¾þÂvhýù;« ï°íM˜íbôÚÙ’Â喵ݙ£ç«‰b# …^ñø$A("ñ²Ç¹®{¼çB5ìóo×^¤àµ/®î¹f–;¼ -ÂL%ãõÉáU‘Ã#"•û~O òv¤¬Æí¸iÛ|ËÌdŠHÕùIò+;ljîC$À§C-ä phäÑ"ˆ²hl2ƒ3Uîà"FåÑ!¢ƒ9²@·‚Ø ŒÜ3è Ù©óìoÀèü úÝ2¤°ïŒ\ÎÀÁB(ǰm‚ ,ØÆÈhlUOïm#`¾znSTX)'^2Ìøg]˜X8ÈLÍfYŒ/O”¬MùÄ ã«3´¶‹M°Cê"!À˜p>N˜øzAΘ™Œö -°Åk¥B¿lC®ëÀæ¹ØÀaŽxø•Yïéᛊ©uô²žkFоE\Æ©‹ñÙ‡vh i‚9 H4¢Y>KãâóϦq¶®‡­¹Àj°¦t G{¡ÁãvAħÁ®<ÿ+»ºœ—P{Ý•ˆ(Q¨@_È“B¨ Q·žë5).f;XIDhˆÂxÔÁ£’eKf tËvÚ™oÝŒ-õ•a†BLw|=È$Q2ÆÑç]¹†ÐDEÂz(>é´#ÀÏ„À à!XÎâ.6È/œJ€?ç¨_ÜÜKïJ:}œ·¦g‰$Ûii(“*™JËä•ê@ f9ãŠz:”kÏ5Í·iA¡ç¥2ƒX<…Rš/GÓµí­©Í1çaè>1ÛÎÌ€ŽP*ˆx‰d/øÕºÙ@Ö;.·ÅˆuìöÙ4‚gª–šÎК£ÁªÏ;9B_NärØáœ{Ë1SQzÄD Õ]BìœBÒec]8Ç–Z];›8 -²,Ô¯ (Z©”™,þÃŒU“¦¸›Q] -²«¡æffýjt¦óDÓ6û’5Ô6{Ã}· ÖÊzgÖ_X6|«Ó¦¯nÅ’ÿ‘ß>˜#jÂYFVi" 0ËlìG¨h03`×ö ØŸfTèaè«*Tè²áà`l‚¤—ïyöCw庯ÀøAÊ9½fQ Îˆau°Bí¶s— „¹±Ê†¼-­S4´«ºé¨#?l¨GîLƒó[R±”Î'ŽùóÜVÃ@)=·SCïjØŠÊ&öº7|q̉é|:üyMyµº&d¹}e¯ Åa<’’&ÝC¬K‹?òrCØ€æsÙ툵ló=SVÑDVæÉTĘ·N`·Ê°èBÆh-$žýdyê -D!dÆYòºŸE"ö–ÐÔ¸ì¶?æt‰âô¤\{J©‹ô ®Îì)¾Ã&ešWÅ©ûô8q%º¬v…a20Z!·) híÒØ=K²ÎYðGÃöB˜NnÄ¢ÏcYg•^ÚݪÔÚ<„¡+¶1d8ŽGžJóL#yk•ƒöÖ€®²^W}AY‰tæ|b Ig"ÿ7…„°ƒÐ×ð”¶¶Wò6æa@„‘cCºrcÉ(µ· Æé©BÌ“ÄÎå­JfçI¤¿ù•вžä—ögã~²¿+az·”Æ’è‹aúëz˜î¹¬3T%¨¶]¹ÿÚ›ãéŽdÂ4sv|*¥TY¥‰xYLÏ5#çX“Q%vŒ…³µl‚^ˆDÌ* ±ÌXv%åÐñ9×Ml°¾‡Á}¿Ç`•Æ©B £¾Ðºß?-J8q=Áf{«Ìåpý±¥,ºZ˜§‚Ó4}K=k¸„IuÔ&·"¯ODláíšHRª%ÏùŸù˜t¬…3¯¿Î t”:ùŠPx÷Gø]aî~9i -x›ø åo¯ÍÉ!Ä-å4`ŽO†ÁÃVS” '‹ .žÔqÖks°ÅG¼aP3\ÖvAÕƒÃ`zò¢(ÑOìñ&ÂY,Bu”¸ª2r_é1hÁ…L¬ T¢º¾æÕ¸”œ $øvÍ®wX!jçJ6®`òB,¸ÝšÂ— -¸wP -•îI}R„“ß.D~Yð)$;•Wœ »@¶;ˆù -¢iVIuíšg"ödz@¡½•Víy"‹Tð$["§‡³TAê3“ Qú!^¹Ë¿×‚—¯mª§ÙJ˜‹¨šÈ•¶÷W¹ãƒ]ÕvRÅE ¶æÛÚ¸XÅÕû¸¼xwž¾˜ÖþÀKú½/º8¥ì†õ<¬÷åç Šèö›Ö‘°Ç[>4µÃ‹dy¾péÈ¡‹Å€.çÔ?2åÏÎF* éF±ÊáÝ-(ŠÎNy…ãênÅ •Áapâl0ȳßÍm×€€•%ÂËgÅN{8ØgZ0¸±±Ä§ä Ãþé¥Í±ñÈÃUóÌé]A6ï†R@½ïlR ¸Ã`ÓÊg§ØçeÍ1æ´ðZ“‹³ÎºI@Jß]½/u œ!Ñ5†&ÚPÇŸ4McmÔÞnµ·üaéÛMPó{UI #–ºë‘¯D³¾²ötܨ»„Ðê¯`q<Í‚8I'0>p¹p½q]¨W\W¯€ÐO%‰_@¦å¿0 -¤òA>ê(’)) ´³†Èž#-YÏ–ç¬glº9jûž^ö«,ìzlzÔ’\ -¢÷óšXËý¡±E_Ë|š‹R…ˆ¡eÓƒLG“"³Á`Î4 —ÈBð‚&2¤†î‘Àßí -ƒpù}_VÝÊe>þ²¥V>¹°äŒ!GB-¤ÎÎzUéy2•Š%ÕD›§²°p‹£6`@jgªÃ¦¯ˆ±(ómÝʯip$vŒ~?Æ7rêw…]¶øžâÏ"nsØ"ù-¸Gé¡ -WØ¡5}Ѭºæ°²õ‡UÑà 0W&Q2HbíÐü±¬‹ùª¬ÔÂEÉV$¥¯•#àzð…Ÿ·?½ùøyfBˆ‰³ÔGÕ68ÇB3 ç88¿Û2æÕ¾Œ»ËQVU”Ëcs 1hQÞŽÃW~¯pŽ-€ˆ´zíç -ÿåÓÿÒ_/fýX!Ef­XªKÔˆT:g5˜ë).g¤/ ƒõuxò¢Ñ)*,Ö§É+Ç\©ð…@W‚…i)DÇ”ËF=†.5^ïx´-5ÚÞª ÓXí›»ÛEÊÔ¹[^A”wõ:‡•UèymÁ6K¹` „+ØfîC¥ÌÞÞ-“Ö{À©"flˆ }§¦'bclQ2KÝ«zYSº€]¼RQ¶ùc5šÙWÌ…Ò“:›+Ñ©$]öÖ…#÷A^I -+x¶ß=Xvª¸aÿÎ~¡0zÏ»ôÌùÃ'“¾5X×zX¹¢™O´h©¢¬í}ˆýyMOóíP•kOC˽æ@Ï5³„´9tšM‚šPˆÌAëùã¸5Ö;Ÿ)»ÀÒ'þWâÁW¨—ÃÓõhÇ1Y¥Çšzºh†Õó—×d–Ë%'?˜EJ«Ñ’N¤~mÛè\¯÷?¤]î4ÿ†Ù;~»Ì‰à‡ ðuÊÑÎ`N›×_ÞRCœ¦”ƒB–'¸rSjü¦Óÿ¢À©1®r:˜+¿‘)Æ>üûaÀTñ‹¿ýÊó5:ç(^ñò5,×A"ý•ŒQ]&9âü›vFŸÏà³s£üMIE-dØð‘ ÐÖu2WrBŠÏQG¸ †tÜ~«°9ñ×ÓK)„02Õ“£àuæKÛG»¨x V mì^ß­!ÖåªÆÌg,¾èp%ŠPhų^.Ü)ýß_ŸƒH*M¯ä ø©L”Â$,”£KÐàO‘/Eÿ/²Wendstream -endobj -1361 0 obj << -/Type /Page -/Contents 1362 0 R -/Resources 1360 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1346 0 R -/Annots [ 1364 0 R 1369 0 R ] ->> endobj -1364 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [324.9335 578.0115 381.8296 590.0711] -/Subtype /Link -/A << /S /GoTo /D (zonefile_format) >> ->> endobj -1369 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [55.6967 152.6674 116.59 164.7271] -/Subtype /Link -/A << /S /GoTo /D (view_statement_grammar) >> ->> endobj -1363 0 obj << -/D [1361 0 R /XYZ 56.6929 794.5015 null] +1374 0 obj << +/D [1372 0 R /XYZ 56.6929 794.5015 null] >> endobj 410 0 obj << -/D [1361 0 R /XYZ 56.6929 226.773 null] ->> endobj -1368 0 obj << -/D [1361 0 R /XYZ 56.6929 199.6254 null] ->> endobj -1360 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F41 925 0 R /F11 1367 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1374 0 obj << -/Length 2801 -/Filter /FlateDecode ->> -stream -xÚ½ZÝoã6Ï_aôå Vù!ê£÷”Ý$=]ï^’;×íƒbËkaɵ䤾¿þf8¤D)²œEC`h4ÎÌoHÉQøŒÁŸÅÊg2 fQøŠq5[=]°Ùhûé‚™¹š»Rï.~¸•Ñ,ñ“P„³‡£+öYóÙÃú7ïý?®>=ÜÜ]Î…b^è_ÎUȼw‹å5qz¼ÿ¸¼]üô¯»«Ë(ð—ľ»¹½¹»Y¾¿¹œóXqè/Œ†n¿ÜõÓÝÕ‡Ww—¿?ü|qóÐbqñr&È¿ýÎfk€ýóóe«Ù ¼0Ÿ'‰˜=]Jú*ÒrŠ‹û‹¶ -VÝu,~Š}%‚p6W`5Œ‚ñ(3Ÿ)ˆÚ< -@— xeÁÇ¢l¥0ÊÛªnÊô)Âå"ñ%—3Wå+ÃVhİt sø" –¶< ;ô[cÙu¶Îö†ÞV‡btäí/yìe»jßPÛsža²ý‘Èj3Ði‘þp¸‘1÷ƒ(L•ÿ1/×$ÞÃñ–¡‘}É›­1rÜݽ¨Ïeú0!Jœû‰R‚Ðÿú0¢™)•Qýý%ôUÞªHëzD±d~"`"2»Z>Þh”‘Š82R>©|Øæ5R¡·Î6é¡hjâ7•yb¼°¹dc8få=¥«m^:²yùe b{wã‰ÜT‚™ûAØÈмØT‡‡:ˆ¼GÇ 6ãŒ/Yc]ú̃'‰Í¡\5yU"@–˜¹vûü)ÕÓ_û]UgÔCÏ `Ö‡Õ–88qò¬&vnžlÌ×YÙä£ée›Û^ ¡°þðâ\?¾èÉZvôªmÂ3-«´nè…â‚æXLfQbÕÒ¢8Zùú|Ãàâë±:ì‰2.j‘„Þý.[‹(72]`n‰X¨Á'=eUf™=‘ô#Ì,Ôg×éc‘™±“‰ôYÀÂ>ð!^euMþBFÕ°áIÃDëö0ÇšD†Ü!ãÓÙΕ:íZ)ôÎÌAðpž¯_§<å ‹ió­Ôˆý~Òc¾‰ê;@3޼Å5=ËhÓÒ6ÝŃtãÔËJ·e•åÏi`¥ôXÒÀuïh]è)ü™1a9¸†–÷‹k³Ž€CÉ“sŽÙG$‘Wí­f=è@a†ê¹É¸<áz¨yb†'2.¦PÅíd\\û÷7wÿ¾¹™‚Jùaª^ºEÅ'Òm›jÙ|÷¶,‹êNeYá$[– »,‹*(¬KBÈm“¶P¸¸IBȱIˆ¢ÂÆ$a?AêÜÍekxv© ßLjBRçkx¦ôp’Q¯Õ&#|i“‘Vlž]2"ù6á+%#¤ºd„g’Ñ [ö—%d–ètF -`õ³WI÷æäi”‰YgHt^FJL{)8L¦vïqÒ&Ñ1G˜·"i§mQP—Uz¨3“@c ‰!äýX >\ú‚ÑÞ#¸wÐ{–° '{C{Z×îœ@êšÚã;'vrwNfô4'ƒ±Dq?âq2—ׄðÀçck ‘±]b8ð#Z„€4Äí -9hàS"‚ÈÂrÄŠâÉŸÃ ,‚õÅà»C^4ó¼¤èæi׉ü®G,3\‡~D4>K©¤·ÅÀKxu¥9Àzlµã[FÚQä¿Z»æbüï?^?-²å==MV¯ôsm TeqÄ!ƒA -…¤ÚLIž^6˜­ÖšmÚ/iW9­”ÕþÉœ6àñ˜Ñ“ºV¿&NQ­¬˜"Ï‘kCIè¡çÐtY5}å5ä,¢ô,OÌ‘‹²ÉöeÖüÍè¡Um˜ …YN_8]{€(Eª‡>¸Õ­òVžÒ9gÉ õø«ŠvH‰±ÒqEJ½KW™é@qhû’Ú—¿^üpµXÒµÖ»ª¬©ƒ$XÐÑÑ٥ɀI»tßä«ùظ -^¸¦â^‹VU¤Z§#7 È Äh-| iv ?]¯Ãä-°6ä'z»»}O]`oŠM=Ú]›ò¤„íaŽF¬¨+êš—«â°ÎÆ`‘ÇR <–¼ç1´“ÇÀ_|z‰¥§ 1Ô† «›¢(Á—2[ãÒÁʰÕĽ"/¿NéÌjÓŸÛ÷¢ÚÍÇ&ÞcºúJé¤ï2tÝc°ÑÔ¡üZV/嫞~kïIÜË@B$f_A*mÌ6èžÝ8Èá°’žô _󑥇ÎUÔA§C`aÞ02ù®ÄÈþÌë¦&š†…ÑmEèÛJþl:â Ðì´‰M;Ë7ªý %®õSÛØ$qdÚ‹Ä:ƒcÚ>ÅíÊl`n\M0€¢lÄÊ€hLÄSzd]Ö7ˆ•‰žÔöNël0î)%{²Pš.E^7ýKÏÀ–™ yýã©S–x̃邚+¥/@:;*±tt¡×Ÿl‚Ã;  SM[m¥^›í¬ÐAØ7ËüÅr~u}}ç_Ý}ºL„wu -¹·ãXÊiä®Ôiä­ÔYä“V;ä¯ÌŽ"ï™åpyx3v¸©Xñ3Ø© ìVê<ö)«ö¡Ùqì®Y¡ –ÉÛñã-9“3ø© üVê<þ)«þ¡Ùqü®YácÑW¼¹/Žã3ø© üVê<þ)«þ¡Ùqü®Y¡°LÒýÞ}Ðgá™88Rq°Rçã0eÕ‰ÃÐìx\³Ìÿk‹Oáù˜1éËDœÙ1\©‰˜Y©ó1›²êÄlhvÅ!õ”–¦ÊÝÖ©/}…Ñë̵ NaÊËÍ>­›ýeìVÍ¡°ˆ;õ[x1µLS1$Rp"Þ•I¡Ïî’{XÄÅõIï¾">yìvÚ@tl÷ÔPuºÚçNyèÄKæúWfÙZO ÔQ3[ÆÚÕÑ®Jq!nӲ̊‘Oå¦|TT©é’¾¤†çä4·×©0BS[??u™€£Åx1~f¤þòÿ>9u¬È—q,Æ÷< {],’È:¥¿ç¨¡çJƾŠE4âúÿx``endstream -endobj -1373 0 obj << -/Type /Page -/Contents 1374 0 R -/Resources 1372 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1346 0 R +/D [1372 0 R /XYZ 56.6929 769.5949 null] >> endobj 1375 0 obj << -/D [1373 0 R /XYZ 85.0394 794.5015 null] +/D [1372 0 R /XYZ 56.6929 749.8269 null] >> endobj -414 0 obj << -/D [1373 0 R /XYZ 85.0394 592.2428 null] ->> endobj -1376 0 obj << -/D [1373 0 R /XYZ 85.0394 565.4551 null] ->> endobj -1372 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F14 729 0 R >> +1371 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F62 1060 0 R >> +/XObject << /Im2 1049 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1379 0 obj << -/Length 3229 +/Length 3862 /Filter /FlateDecode >> stream -xÚ¥ZÝsÛ6÷_¡·£f"Ÿ$ñ˜6NëNëÜ9îô¡í-Qç$R);Î_ ì‚%ZI®“™\,‹Ýß~²˜qø'f&e©•v–YÍ f¶Ü]ñÙ#Ìýx%ˆg˜1×÷÷Wß½WÙÌ2›Êtv¿ŽdåŒç¹˜Ý¯þHR&Ù$ð䇷ïo~üíîí<ÓÉý͇ÛùBž¼¿ùåG?Þ½ýõ×·wó…ÈH~øéí¿ï¯ïp*%ßßܾCŠÅÇ+Bï®ß_ß]ßþp=ÿëþç«ëû~/ñ~Wn#_ýñŸ­`Û?_q¦lnfÏð™°VÎvWÚ(f´R²½úxõŸ^`4ë?²_ϳÐ9“d|ͲB2kž^–Ï9ÍôYøY4 _ŒE îMSÉ2Ž î•j&³ÆHç_˜U™Hg™RŒ;¸÷ÖØ3ZfR-ŸàÌ( Š{ŽóE*’{ø_&gî‘<“Ù,ÍsfEîžý=ŒkkòDc¿ÓÁžðÝÍNÎÞ5°ŸY´¥ w ö;JeXÀ)0e³Œg,7wt¿)CYžÊbëF6Ù‡²îÚ–‡ùBñäi.MRZ¤®ç@jÈÞmÊ–d|ž “4uIlí¦9nWȵªÚâa.y²%Þb»ÅA¹Ûw/Ⱦljc½*8„5œ-zò½¦y›gþXìçÆ»pŒ`*SÉû~#9.âd -shšnJ„¼)ËỪE&|f´7 ø«- ©j|†-ë`2¯Õh“‚…&€˜hö]ÕÔ8^5J|ÀÖi‘q&3cÇźn‹WûŠ®Ú9 ±é­ïj©å)xIAîÑÙpúJ&r8ÔpΓ·«Uå4*ZËePÎ2ÅrSÕQG„C$A -Ôù¡EUÚ$E$Ni ŽÄ¹É%ˆ+!'¨Ôõ–mƒ,K€5lí|"‡$#jÛ ÿù„. -V–åÄFò½½B5®RÕ]y µHœè$U»½w`óD[éúµÝ7uKSІ­1‹.ÐqRhÆ9ô-#ÏíŠzYbÛܬ]^í‹@±6O~ÇäsÎvŒ{o©7ŸûbIÞð3޳Å!…òìV£ðê»vÄ‚dfñËmšC·X»©&×·¡2£JƒØ×R摲0éŠ6þðâ[7(Ad.êö¹$êÝÃÁmÓ•a‘¢›€Dƒ1_‚„k ácÏ)LºE›M³ÂÔ®\nŠºjwÔ Á9ÌrטÆ~õÎ4£³?Uº¢^‹aÝPFm‹.D±7gÜ+½»ýˆƒA!WM©Ctãõ±öÎ p\Ô9V8Uf£È‹¡£ÀË«ÆþÙkççaÓ%Ž÷™=ŽÈ€z¿º÷?¹áå§e¹ïN>½»kËŽ¡v£<  îóWŽŒ#\©>‡8+‡²Éå¶y „ŸÈ’‡c‡˜VÕIH»´µ: iGÁ ·.ÂkŸyAb·}™ !ü©”›ä†Öò~n8ævÕò¸-À7ºOÇaö‹]ÞáŸ,šÃ -#8Á¬ÎáLÙ7eîÒ "¸žqDJ¿<9Jø©ÍQè+Ì¥T²ÁÇQB{'ðøê>"Oº¡o EàÒx¿³Á’Ð@ ¾+¶–:#ÝV ˆm„ŒY{›bw}®â:ŽÒLyƒx¬Ð¼ÝªÖ¹eTf`¦¡&_À¯#Ò3’>g*ŠÓÔLõ9(:wwë:1MÄŒKØãö.9r‡K8̸„MæZwLv% +b”"%†ñç‚ c‡M›´a ZÐoZAHØ#ö"aãDRi”¥ b‚­‰Ž +³ç™T \L°5É¢D€VNØø_§×ƒ,4ˆ5j3®wˆ¿»);ß1¢³g~BCÄ©ÒDMÎB“Çí55>Nè_8Õùºä36˜¤GI1îœ-TôyÙª¸8_í¤Xk#c…ÙL¡Ð'C“qjO¢s­Ç2ûµ_Ðeô•˜UÑ+ŽˆUÓBÑã®Ú`XSø…¿tÛ.'!0(y +¶#ØŽ} yàD ì¹@ùâá²xõ®¢ÛÇuúm)Å&éNGÛ89?¨†ðN§Ð~þ¤iâÒ“«DVŸÕÆ¥¬®k¿®I +Ú$Q’©d +c ñ¡iLágj(T‡þÖ6yš†á'&Û-ÅRküt?¬7íþòpÖq~„ÜDrìÚÁ3Ó«moiOÆfØõqç|DêÜÉá€7N­¦De%Ôô>‚Î"“ÇùT%¼a«T_º0°<é W‚Ö€Aâ”ÀŠu[”¶|µ ºØD:3ú¥È W¦*8þ'Z¶ÝW,¡®Ý[»÷‡`©lvvó…ù`Åw2mÌÐøúïøéƒ=¢$¼V`PB.=Qªf‰%Ê´,\AÌ©.›Ó‚E”I™½(A+F÷¹á{^ýP€«Ü 5è>0¹$Ö<Žô 0œÖ(ÜnÉJp^:Óv´OÙÒ©š¶§âp ìÕg±ºpT©$æiÞ$ŽÅãÒQE¤uºtRBé¦pçSÓÝÛÂUž <Å[0Ê› „û€¶»£/1)L”%qþ“±fÂ%-ºÇôÝm~ÇÛQºU¿#Žsôª+öÜr‚¦fmlM„Eçö»Œ+R¤‹NCL<+4T4[F(DL“'/›Y,MЄ¶Ám·Ã± ŠË“pC1°âòxÞî)¼‹]½³{Ž™iÐÏB wè©HFêÂÕDª²Lkˆws²)˜ñ;Ëú¤ Ëf±…àóX•¥ƒY®Üiuæt ~Æ¥S&8Ng\ÕÍÜ•ƒ2r0T5›z(1§áEîǤdOê¯ B]#üu¯6EÝ«øË—°œŽDœÎj)–Š#‘ "\œßªk2ÞäH×ITp|>Aq9Â,%8×?#‚þ]ˆÒc þGèøù(}Lu9JTÎê +DÛ­ý…ÿ>ØãÓ+â ÑÅù9—*ðy6ÕŸÓ(H;àž0ê ô"¡·J_TM@ÆU_¹š )/Žc¬Îï$0V¥y*ŸÃlx/fØßÙàƒ$…Îc5”R¸áØQç + {ˆy‹Æ¶Û˦ɦ¡Q4OÔØÂ£ 5I¢¡Kª%'F„ozÒPÆùû‚ö¥Qgv~G|õ;ðSsþ>[4°MB€òKk¦£’«È„à®åo–‘Ãb‘bð0ÏJ@›=8@bQ2¾D˜¯Jª„)@Q”e…FâîÖ±F‹Øë´%{Ù˜$äÑT6r;õ€2ÄWÊa°³õ=µú¡a&¹,nBv㞦W29x?¬I…¢®€¬IšY–Â{rý~ëv»ÅZ?WxôTY¯k¸¦0.«J1{)$…Å*Ø_ HÈ€ß2 |C³Ûµƒ‹¡M«iÈhh‡/±±'Í…ªkå8‘ lÏ 9”ƒ_RuhôãšM1'&ÂF¦xç¾øb™]w¿®­ìòË3Š,¤ÛÈ S­ÞßÓƒ¯ôf>*ÖÈÑ‘ æVKqŽ WÍâ_ +HÑ6³,àþsH>+±â`›ÃÞúÝ +¾ìŠR1O¥-j6 ‚/A.ðR£ ›ØVYb‡¶ñP•¬N¾ž4†˜òHããÓáê]”h5ß<»¥ØHÓÕëp_¸»ßñžŠÿ093u˜äÕ_-¾ ÂzBž3§±ÓVîvÎ0„c¶=‚`«Ó&#C×ࢸ㹺}䬲¤ —îÄÔg2¸—}8y(1w; rsn‰}Q5ÛÎŽ34墡‚`ŸH å±í¢S>¤FOÚ³û4šQ²nZ¦unß°XpÂÕ8<Ôè°@ÃÏÕå©0Õžž`š`g1Û™ùDCïè]Ãû?ã_ ÓNµ³À:›r#s `4믈WBÈ ¢Uàÿ¬Œ¥ˆ#P葌c•‘Œc•:ãÀHÆqª¼ê©l,cìúš–žNP8t×(lrõ‰ž/"­ö‡ÖÕ™ñÓRd,¥‡¤féèƒè¥`ÂÛ,÷qüÅ8UIˆ÷QÏÆ©cªËqj "8ë«û§uiëâéüÞ^®Ÿß=P-l?¹ÐØD9D„ÓýÉ+§‘ŽürÍ%ãT<ŨûÒ%j^úGkÃTÃi,À9$´¨¤“ðÙhŒ_ëu4CÞ† úAðvõ´|Ì ª p†4ž¹¯ƒKÑä’Q.’KÂ<*ðâ§Q„Ëäf a…X};Tu¿öMû\–Cé\Hh\Öº Hh)¾üLG¯Ð²ÓbøŽ‘ʰíCUZ~3Ju0líl}¸j",«bÛ´ïšœpAoTǯËéÍ=Ž{xÂ!WïÏðMŒ?öˆGf7_4ú^Gƒï:tv(ÛußÖ®æ±.[Dÿ¥ÒŒVQbRäwUS.‚U*½µ9–`— %p :õ¡Å›^ü¼°"*¢y—`q È +¦ÓpfLæCùW{j9YQ»#‘AŠ8}ቷl)u$!»{áIøBpLn°g«N^(™;5Vú6t”ÇBMØY€ ¦z‹óÕFiðàŒ~GùØô¾ È’®¨2ª¾ì ËRl©\–‹u ùXчcížæ8Ü‚.ñxá©K,*‘E1(/ïþþÃ’;ÀHc¯¹ ó‡lœî!Hª„Óa  /òª?LzáþÁGÀÍd/A ÖÝC†Í €+?Ѧ%昪qÇ‹†~í×C]m\0 =ÿœ!Ì‘Kj¹V‰‰Ò,ŸE5Ï ¡”¹ŠOI¸Í.¤Ø>ª–  m¼üM¸öÜüߟŸ0N#eê«b‘€®ç©gÊyp3ç<|7|Îúÿé5£ +endstream endobj 1378 0 obj << /Type /Page /Contents 1379 0 R /Resources 1377 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1346 0 R ->> endobj -1380 0 obj << -/D [1378 0 R /XYZ 56.6929 794.5015 null] ->> endobj -418 0 obj << -/D [1378 0 R /XYZ 56.6929 489.6987 null] ->> endobj -985 0 obj << -/D [1378 0 R /XYZ 56.6929 463.7183 null] ->> endobj -1377 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F62 1050 0 R /F21 702 0 R >> -/XObject << /Im2 1039 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1383 0 obj << -/Length 2832 -/Filter /FlateDecode ->> -stream -xÚµ]sÛ6òÝ¿Bo'ß„(>I }JS'uçšæRwî!õdh -²9•H•¤œøîúßoø!ѱ]÷Fø^ì.ö›b -?¶ÐŠPaä"3’(ÊԢ؞ÐÅ5¬½9aaO7%ã]ß^œ|õZd CLÊÓÅÅzKª5[\¬>,_}ÿòÝÅÙûÓ„+ºLÉi¢Rºüöüíw8c°yõÓÛ×ço~yÿò4“Ë‹óŸÞâôû³×gïÏÞ¾:;M˜V ÎóឯÏÿq†½7ï_þøãË÷§—?œœ]ô´ŒéeT8B~?ùpI+ û‡J„Ñjñ ”0cøb{"• J -g6'?Ÿü³8ZõGçø'•&ŠËt‘(N4MÙ<—)¡ -¸–d’‘Ô(Ùs™³9.Ç]ŽËÛüs’yqc“¶ü·=¤š4Sl1}„@¿k1€¥0MP¸¸±§‰ ÂáRn÷[äÛz_uد×aƒÝÖÍöË -Û«»Î¶Øíjl÷m¸®›°¯hmskaÞþoáRÒ!S³ü×­†#À ༠ŒQaƈQ -…3bÇ•ôعv•w9ön®õ׺Þýæ”é¥uã6î*CoSnËî…ë«álDÙõ?•› öŠÍÃ-À2\u}ö-oíæ.©ã]y7àæè£‘0î ó(¸l‰XñeU‡ û¹°veWÀ+Áäò¼Âé›Oxv78»Ýoºr·±8º-í§öî ²ñ•ùn·)‘/à.oò.ÐÀýóºùþàÀUîa†ÇfÔjwó©áK;E™só+»ÎEÅä«×r¬6 -Î8Àv Yú#nšJvFŒà:ì!aèODfí´,GJA™…"ŒKDÑY&–™¢”.Û.ïʶ+‹6)nòª²›1ûìÖVÑ7M¾ÝæÍ ¶À.‰‘™ðÐg¦pÓ<»ílÊ´¸£¬l‡½_©¢an÷1_­üA00c ÏƒdR(âïa ŽÃÓá–]Ýt=ìap6å›Mý)bœ0­C„ûã6 .,üŽ~Axõe\ 5â !禬Aµÿ㛹—žË  ‘Ëê'¾èwöWJyUve]áL^­°óK›_Û™ëŸz0£¹‘`’i‘ÁœÃæ°N9>ŒƒÂ›¯pßÕδw-Üý|µ-+@²É“ðT­ôÁ vu8‰v.¯màe^ ÓÅò ê8‡m>°­8Ö….«|zÁ²Ï ½‘qÒ‘êÀxo)Y:f•–Ug«UXóˆ°Ì3Áá¹…ý\^mìx`ìw¨n0²ž0:`´›Úù—¨»º¨7m¼5ô„Àë}·Çs–—Ã;ì;\)p>™šNu@Ç÷‡Æ]x‰«Þ -û‰5¶˜|:×裟wÂ>DÒÃP²N€R-—.Y©q-žÂ[F@Q -‚­3ÉÐèšhÖ}¢ìü±¸¦†è,»ß²¢O‘µdššŠgKk1ƒ<–VO@͆›¿,­ -žøiå2‹[¾þzÎKFŽ<—[¢ŒSWx"É*„ž!œÃüÊÁü¾8Ü£ét/ˮ竮Ü;ôb¤r˜ÕFÂѯœËªdn2¥&(©¼WI1Y–.F» †]Ušw6Ù¯vøñÍOUûíUdí#nwðž kòª]Û¦}ìi6w:Árêჺ² lødûoéê.Ì·ý6½ôK8ÿfïúï¾qæÈ…P#î_!„\ýãÉ|Jœ•+ì@i¹“Ç_E2CÏÔql=MEŽ>‡\Îàç>iCڣؗ_ñL\z8 š£j2ÂS¯ ‡pƨª?‡*§‚p‘™Y–‚å+×wc(¤|¢¹ûªžÇÐL!Í#°|˜ÃÛü?^r'®?KDÁ”5Sn†…ú>ü5CìÊ2÷òi_ó.ïù¨7¹l˜¬™óˆòÉ—My"\ñ0UröñÆ<éßîélÆýécNúâ;̾êsØ¢ž|Ù”-.…•F³Y¶@xָ˓]íªíöÓ?=Ÿ¸ÞćŒAÌý“÷÷—™?”ÐþýŸý/›á/H ˆÖ|þŸ)‚¦DC"‘òASvT˜€dV9í;Fý˜°Mendstream -endobj -1382 0 obj << -/Type /Page -/Contents 1383 0 R -/Resources 1381 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1388 0 R ->> endobj -1384 0 obj << -/D [1382 0 R /XYZ 85.0394 794.5015 null] ->> endobj -422 0 obj << -/D [1382 0 R /XYZ 85.0394 690.4757 null] ->> endobj -1385 0 obj << -/D [1382 0 R /XYZ 85.0394 663.4801 null] ->> endobj -426 0 obj << -/D [1382 0 R /XYZ 85.0394 582.7428 null] ->> endobj -1386 0 obj << -/D [1382 0 R /XYZ 85.0394 552.623 null] ->> endobj -430 0 obj << -/D [1382 0 R /XYZ 85.0394 310.6261 null] ->> endobj -1387 0 obj << -/D [1382 0 R /XYZ 85.0394 286.2805 null] +/Parent 1356 0 R +/Annots [ 1381 0 R 1386 0 R ] >> endobj 1381 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R >> +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [353.2799 540.398 410.176 552.4577] +/Subtype /Link +/A << /S /GoTo /D (zonefile_format) >> +>> endobj +1386 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [84.0431 109.336 144.9365 121.3956] +/Subtype /Link +/A << /S /GoTo /D (view_statement_grammar) >> +>> endobj +1380 0 obj << +/D [1378 0 R /XYZ 85.0394 794.5015 null] +>> endobj +414 0 obj << +/D [1378 0 R /XYZ 85.0394 184.8801 null] +>> endobj +1385 0 obj << +/D [1378 0 R /XYZ 85.0394 156.8765 null] +>> endobj +1377 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R /F11 1384 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1391 0 obj << -/Length 3884 +/Length 2882 /Filter /FlateDecode >> stream -xÚ¥Ërã6òî¯ðQ®1x$P9M2ž¬S›IvÆÙG%9P%s‡"‘²G©Úßntƒ/ÓcOR:hF£ß ¼ð“—&‰§ÜeêâÈi.×û q¹ƒ±ï.$ÏY†IËá¬on/¾z«ÓK¹D%—·Û. kååíæ—E©è -0ˆÅ·?¾{{óÝÏï__¥ñâöæÇwWKeÄâíÍ߯©õÝû×?üðúýÕRZ#ßþíõO·×ïi(aßܼ{CGO }ýöúýõ»o¯¯~»ýþâú¶;Ëð¼Rh<Èï¿ü&.7pìï/D¤5—БtN]î/b£#k åŇ‹t£~é,ÿ¤ˆ”NÔ c9` Q"Uj\”h¥=¹Z&B,~?åÇó¡>¶ËC]—Ë¢jóã}VÒ`uÚ¯òã×Ôù Ï|¹T:rRÄ—K)#gŒòÈþ÷5~õVÉ˼"—±‹L*’îÊ”€k€­mò#qõC›µù>¯Zê¾ÉBUE[ÔA²jCŸ›l—óVzpBØI%‘ˆeìwº½Ë;zúIÒF‰Z„ŸÃ<Æ¥€I)ÜOÐ&äbC´å u×wÙ1[ËŠ¦-Ö lkú_åôŸ5M½.͆úE{Ç#ôw¼’v‘ïëÖ/P‹*ÛóR&dU9½¸ÙŽVh)Òô‰Ö–ù•\T;ØÁßVl#mœ ·EºS ¡°òukóÍ+„˜E{—#˵òÀ”cVírjÖ[^åijhZ@µ®‘N¤e”j/~¬Ê3Rjìë¦ì¼&44 ª2;5¼";Ê"ç=ÿ.óÿ›2o˜ Ï*Æ"I»‚ÌÔ4?[QÑ4”Í¥)_9²­ëj;# Bij,OˆËRê(5 -ÙŒ2&“ÏI¡C…ŽŸ“BzŸÊ)LõbUÔ¨×ëÓ‘šѹAbÚú@2¿ÏKž¿MLu…×°;3V7"¤ä 5£/ª¦Ø0ælæXZšHí˜àû"˜Ó­8²óºC¡Ä¤Ždû ôKm]dE%ùémRÇÌ3)¹Íà8س‹ºÊ ì -€=ÉËìÕÅ"²©yÉÝ©X>Ú¾A%3¶ôš{µwuÃÛ£¤hM –`K§¤Yd-4Î<©>,é‚I‰¬tcU¨½½Ò„„Ïæ5´ØUu¯³q*ü øi4á¾[‚[c§gΨê9þ¤)˜NpVÏó'qVÍñG˔Ά›ŒÎ6ÝKÆ‘²±ú³{Íð¬Î†Á qSƒ]ó)ÇìÜäÛìT¶MÔ™¯ôÆzÆfq®OÔØ GßkïPOuœx`hû±,!¶Ñ¸âÿ®¸/ªµë¯_eÞ k3ä\âûìø±›Y´ôŸ1–U½;qó¡(Kj±¹÷Úh·§#ÈÝq΢b¨@ÆÌ( )˜S¯½Rxkç!Ìê@(q -vx;«R62 ×|?Dãì-Ê$ ³Šfxm©ƒiéÄSD&‚–ž˜n@©_bº•ˆâ¸ïñ¾“¸,>mçÏÀÁv N íÜ&oÑW.öé%€îrÏußñz¯S»(ë5Fbë¸êØ QÝ4 ú†ùû¬i“d¸g˜B×Ü`ÛmˆßÔÇ!AEÌH]$‰£k/ª5 )‰§G$‹?¼ÝÄV !B³õ´ ƒ©~Ç@zl$ìÐJKG†àevŸ#H ^²×Ò&$rqš²¹B4-ï9g•4„¿iÓ9Ÿ“/0&.îœï<=8™0°©Rnì‡z& ¯$¶«TQR3//žŒÊïÊCÝ4ŪÌ#ºÈvÓþ`ˆgö`J§ô‹øå2Ðg%‡솻õ(:PãÀÔÓs¼ŸRó!!l­«%çöKúú9AÂKT’ÎjSXÝRt:!+Íš§·óÁUj"#{¡Š‚»2:ès}à°U¿ Q@.Ørœÿ»²^¡6x˜_ÚPgjû‘Ñ0È{Ξ4X27IŸ26ªÙÈ‚Îú—'ƒÊØêà厤.OÛD®—‰.ܶŠ,›%eeo–py!ƒYBØH•ëÍÎó§²”Jà\Vje]«†êM«fµ®5ÎŒ¹F6H¥ÉXŽÍbKÚ¶çA’f ÂÆ‚m&ç`ša^oQQ3mš™°´ú•í«!`,H+ŒÖÛž†Ë«Îi=m61¤°l¾!愘Èé'¡F -ŽuE/Ãëd:A†ÑÁ3ˆ¢#/¥/—Ö›¿ÅJ‹Ž'fÔ€¬ Œ òɘã#Þð0qçX§ Ñ1‹À²S[ï!é¤Ô3^lÉÔAk•ù ö} ("jÞÞqòºå€Ø§Ã^ýûd`QêëÐî¿]T¹g@h ǪS ¼yAÙ/zûb}GÍÁáíð„®;¡ã Æë(¤ÇÖ&l_·_C+憺ëÕv•áê¹P,Ö±8g>ë(—ݬ/š»úT"•„fåCvn¨ýP?¢æ$ LJ;œŽJ{G -’¸§Ì¹UQ¬µy±9S‚DäÚ¬¡4q§DÏk\êÜÈNò¹ -þ÷7íïþ@ÖGÝþ”ìÑ»y=@– :“Ž£H2šjÃíA£³Êäò:™‡VN†ÌjŽ·pÖªöU%€±Ñòm’hxëK3á$Åž7«y´“<èäåb[3–üS¶ÇÐ1ÐX0Ed€­îHäkœªJ/僲:ívçI}o}Ìš»b+µ®Ç+»8ZÀŒ‡Z||h1s&kb”ž©ËØX[œoªæ‰ÂBÜÉcÔûúRï:1‰í#zi9hˆèÖ%zÐæ8sßòÓCËËjúçMÒÅõ›wxÅÙËûý©£ç/ùr*£ÇBÆUGLÝ‚CyA#ÆÕƧsºÙôK&i$”Œ¿ ̘*Oî‹2°¤«Šá%-O›Ã²)þ˜« -I.±nâ1!@¯÷d¹8‰ æ-´~~óy´Äi»%é±l¬j *|u&¸/ˆïÈr‘Ò5ÞÒŸÜZ°nÉXUF)’tã;1øç•ƒð¤,64–¾šF*‚’¹P AVç–ÄÔ-~F QÔ§–ê|8ØÞ æ20YVM ±(!TC7ç‰Øü÷ög˜e46’o–ê¢¿í²¾=•c”«)ÀÓ¢¹£A¬XôÑ<#ðl0c˜ʣð {´óÇš1q$$qWÎ$͘ºŽœa„¼‘Ž¿"Ø66oVËüÕÔ–õaÇÈ ±ÍÃê, ?PtƒCísª]„GXCCŒÁEíÐ+IŠv#D¾ -ÿeÆ4MgÍÛgŸ>«¦`®t—tB!uPS©ƒEçö©ØŸöØQ=Ô¬³8ž7þˆÖ“C+¨¥Ô±Åì¥ò•O7Ñ*´Š´4Ž´5íTM)Eª¦¿ü€T !¬jªuª†ƒ$/.äÐVñS@zUCèXÕ–ZHV.>$Š_ià?(޳¸ô‘$“ž~¬ê‡©È|¹dþyqceés9èÑÓÌSrÖµ¯Qè>¬ñ&r‹‡šÀ\¼²zX¼ÂÀ \v½9_¦Áù!Ø« hÆ¥¢aÞï>ÌV¢ŠLªL_Љ¥¯ €Eb;²Ø ¥:.Ë‚™Õ‘L¥œóM}òµ<ãٚÁ&ºSwÅÿV&ÒÂt -\ù`sn=?ÖÅèg5´µÏa»==VtÄ|žÄÉâaÅЏéqƒæŽ°”_åÌXªŸ? -Äë}Ù'TÝ“ô$‰Øñ—(#ZïòK¬ËãdZ¤Â+@P‘*zêc.™AÿTm€Ž¶®7 ?œ¿Gˆcü=ÄFŸFa3L?díú.”˜ø#ÙÀ蛲{,/b´Žÿ„[—Eä>qñâ?h -½¿…ÿÒˆ ÿb»=S‡Q_sö:CmïNÓ¯BÃ{:ldŒ$è&âàê³}ª8v×Ä*ÜE§©Àû%à…D.=íVÀ¼-DSo}qu&ùÅš˜ø²ÍR Û½2úB8ªW`ð<~]×*~â Öa´þvlD$øXTŠ'öK5hvÜíì›Ki×ñðˆŠ[x×Äqé$|b°Ê'IØ„ˆ‰õî xéˆÁnje‡:™v娔.@Êbï“ï4„Aiø€…æQ-ÓÉj}:öa!ŠjUŸ¼6A'Ô帮8òEÃMFüÇeã<ŠÞU)1㣌„sþ)L—ê¾x†=žØi5wàp'Ÿy ÃÄÀ³áìœÙ:˜äÎY‡G¿yÁRõõ’ŽæåÅyVÊÒ8R±çhQx}•‘pþõõÙ8l- -üú˜ŸŸÈÞHÔ4{!ûØ€(‚Ì}„`u÷´Â&Ó¯À”€{u  RËT½ä;09kíüW`ËãrˆÒâ59?˜p›$ýÎ^Y6sI¸ŠlMღ Û›Žø©z¸«Í„S& ´MÌš@~bòû0ãùÍZä+pk|GðY@Œ9è+~ŠÐžùÅÀNMQ0¾¾ýpóÝ«é­@š_¦¹È&HCÇÝ%5Þ>ª ³—ƒéÄïá)§8‘€y Ú¦àQÍ”©“(M3$äÑ7}ݤÏïÿs@Òî¡ô,Ú¬äOð9«æ -mÓqµÁ&cË•B6ÿ/F”zÞ­à÷Ío\´´j?¿ ¾=· >¸P–WšN‹!¸§q“= VvUÖžºr‡éJh†E þwy•é«;ìžbƒ é<,B &„# -€>ÏÁž´|ãp€œ1LjñD#”®H—‰N¯ç«ñ“—/t»¢ÊÚÎÎŽ“žçêu#óMÏ%¦7/8Ê[ðUWØUaluûdÈ,\Ìf\¯KˆüN;âbÁDbcwÌö{Hê|}nsr„Ø$ÏXm ùè¹±B’Y?4ÔöæûSÙ‡’§ NLµ4~éUÂ}îÓF™L¥ú+eþb»àj€Lâ(}ô…Õ  (™‹œ{rø3÷­°6ø¸1gD÷í_þޏÿÈ:†xÎZ5oOTjñY¢ü÷ºöåáƒãǤÿC_ý¢endstream +xÚ½]sã¶ñÝ¿B“—Ê3B| Ó'ßÙN•i|W[ídšä–è3çdR©sÜ_ß],@‚2Dú&ŽÇ`±Ø/‹Ý¥ø,‚?>‹–d"›éL±8âñlýtÍ>ÁÜgÜâ,ÒÂÇz·:ûîZêYƲD$³ÕƒG+eQšòÙjóËåæ8àà°ßÕMA+ÌÙ`sX?ÄÞB—¶E“àd¹)ª¼AŸK· +è *‘S‚â<‹ Ç'ºý‡ Ohóêe7- È.È.J‰-b¬ÛC¾Ý¾8üæd3þ†/õaO½Îq,D6åààl‰TÄGgœè ‡ûkèÉ‘LÇ©sïg3{'3É"éáîýOü]"4SÑ”¿ó±Nû» ¥³g$\”›WaGÂ2Îõ8w‡à>tyœ¥™r§S™êùò’ÚÖ:_‡}çëÒ#_—â¹+*f]”_ÈÌÊ©¹¡]…ÞGuiÎï¯Q$/ÐÍÝòÒ^"€ç䜣뙞×{GÙ츈˜ÈŽŸ;ënyÆÍ>óÌî3N¸[ôŸ1wtyÉî®nÿ1óëóǰ‰É0äA§Bj3­¿&ä1äNF7OøÛ\lÒ»X$¹"D½Bhçp†ÌÅ­Bˆó@díD1¡²dèXŒã޹jh{¿„#ë—°kœ5´95ž'Ì:O„ƒÎ¶í=áwž‡ä‰°×{"•Lx¢hx€†wÜŠ>펃CËÝ‘YsìxFA¡vÁ¤ö¤Ô±—Rp8LÝÃÒyРw$"ëŽívKKÖù¡9#H1Z©‡âHÇ2®Ü6'!Ss$NÙi«ü×ÀyCPû¾"ßWÙ2ü¾šEýûªUäbwÕÅî÷F ÈÐ24àk$¶2s—¨ ÝFÈL8‹yï€èFœˆÎ…סÒîV†èÁŸ2ù­þ¹ÌŸCĦÏ1¾…ÜýPnÛEYÑËuõ´k_¨ûoàÛÃñ&Ì¥M¼1›¸±œ?š-ˆÕ¼©Í¦è¾£Ž£‚¨#Ê uŸûpAð¼²ÄnAmÚePWÛÜ<Ø®D˜íj,Üðið€þˆ[û˜·VJzˆÑ=˜õþÉF'vÜÔ’o0ä7ÙÖk‡“äuÁS–x!WæùЯêvH¼7G=‘e6ÄDÀ²j‹}U´±tÈ8Ö©¡c‚h n \Gkðu\—˜j +)½¸LªNf€¯kzT¥¹i&œ„.^™f—¯ »€ìÐöÍßü|ùá§‹å h¶ÙÕUC $©%•O³÷V2R &!ìò}[®¡}9ls“ðâóŠŽ”Ž;¡µ³tHÔÑ:p˜Ðé@x¾ÙXIZ=‘Ÿht{ýž–Às–Ú5f·û¹x.%d,” +À.¼X´mSÓÒ²Zo›"¤I,őĒ$†y’àË_™#H@O šÃ‹ÕQÄ€·ãSUlðê  eÒQâómY}£Y4vI{ÎçNb_z·½û|ý™<ÊP@#ú‘³¥½Cõ¹ªŸ«W+YÇ#…hMqß !ík„½¼mÑáÐÀ?h7\¦'“Ôá°ÄÐ]([ +ß]὆%µµešÍ Š?ʳJì›MAZv EùÅ.Ä- ³é܆ gÉc +»úLnk³@Ç:"N—vl +ˆëö9>[6ÆõMjí=ò5ÐY[%Zk윚¢÷ùVcè¹Ü¥Y7EÐø+·yëÞ8TvɶlÚaŠtÄËžƒ²ùþTEX¦œ ®ÔxÜÇ2É +¼z^XÅY"JýkOàS ô8¤ƒ£LÒk¦Ã" +¼åY™Fly³¸¸¼¼e·Ï31¿8©w"¨ü1®·‡5¢·ÃšÔ{Œi¯÷1Ó°Þ>S™Æ›5‡P h‰ Í=¬ÍÖ¤æcL{Í™†5÷™Š¿${»ö"aRB7®½‡5¢½ÃšÔ~Œi¯ý1Ó°ö>SÁðëŒx»öQÊ"™N(ß#èn‘&UáØk~Ä1¬¸ÇQ@bïÿ¿U‘fL«)øX§-ÐaM™`”igƒWLƒF0ØŸû[~L¦-ê*•é ‹yX#sX“cÚ[ì˜iØb>Sþÿ°X,ãdÂbÖˆÅ֤ů˜ö;f¶˜Ïô’]£¶oÓÜ|çúšîchî°&5cÚk~Ì4¬¹Ï4eW_£;äüq¢'â(kDw‡5©ûÓ^÷c¦aÝ}¦ÙWéÎ3ós"–ò±NëÞaMé>Ê´ÓýÓ î¦_§»r:›ˆ'|¬ÝÖ¤îcL{Ý™†u÷™¾;©;#Ų?Öú¹‰«gñ¸Ë7¸ê‹DoжÅ:+L¶ÃmÉ_Êâ™z[ÈÌ·–€É²fò5Z¸ÛQWQ®i—6令o@ËFKªón£Hw‡j;$‚Œ!g{,öek(AžîÕ0`²Þa¢ØÐ”I{¥©•t¦po˜«jnzñêă '@¬4›/–·1£tÅ™83JkFSó‰ç+Ü?˳ä}9V!Á<²Ó"˜^z²º ó[ê¿Ô—ÆVÜ£„W\äÃ. î­B(*dÙP…Ý?ò§Ý¶ø>ðy®“–£Jüþ!ýZÿ˜wAl“(šþ Õß!˪’ª™¿08œó¹ýd™%}qqX“Áêb^}rËaåî¸à§ûH÷œüÒæ°V’ÅóÇüKáU.»úVÖ!Çk _è³ó°R‡U\#vXžX$BšJ"Bv{,Ŭ Ù_Î`y·+ò½˜Ï К* vî ¾ûÄ,|P>Ðaï)¯l!»+ñÒZú6c06…Ï!v:óüWð©€{þôoâzw¯4“iz"´D¬Pæ£AòúS6œ<Èñ¢ÿ7Ú‘endstream endobj 1390 0 obj << /Type /Page /Contents 1391 0 R /Resources 1389 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1388 0 R -/Annots [ 1393 0 R ] ->> endobj -1393 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [87.6538 116.0624 137.7628 128.122] -/Subtype /Link -/A << /S /GoTo /D (tsig) >> +/Parent 1356 0 R >> endobj 1392 0 obj << /D [1390 0 R /XYZ 56.6929 794.5015 null] >> endobj -434 0 obj << -/D [1390 0 R /XYZ 56.6929 718.7806 null] +418 0 obj << +/D [1390 0 R /XYZ 56.6929 551.4149 null] >> endobj -1274 0 obj << -/D [1390 0 R /XYZ 56.6929 687.5668 null] +1393 0 obj << +/D [1390 0 R /XYZ 56.6929 523.4719 null] >> endobj 1389 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F21 702 0 R /F23 726 0 R >> +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1396 0 obj << -/Length 2509 +/Length 3167 /Filter /FlateDecode >> stream -xÚÅY_s㸠ϧð[™µJ‘")Í>ew“m®wÙk’{èäv2²ÍØšµ%Ÿ$ÇM;÷Ý ¤þØò:¹›NÇ")@à@G ~á(–I4ÒIHÊÑl}ÆF x÷ù,t4O4éR}¸?ûë•У$HW£û§¯8`qŽîçã»øùþòö|Â%«à|"¸¾ùD+ =>~¹¹ºþüËíŹޯ÷×_nhùöòêòöòæãåù$Œeû¹ãpdÃÕõ—4ú|{ñÓO·ç_ï8»¼otéê2Šüvöð•æ ög,I,G;˜° L>ZŸER2¯¬ÎîÎþÑ0ì¼µ[‡ì'EȘër1d@™JÀ+4àýÒ @vHÃ$9çÀiê2Í«'Sž‡ñxRÛræ÷tÙk‘'±Û“æóa¾" Õq¾“g5À:k*íYÏVé¶2\D$ÇÕÆÌ²§œ¨q ÊØÕ럟#ZB9ü’r[à$,ÿ»È Žd«š]ßeõÒ­/ -щë¢v*S>9¸Û;X€wN$P¯ÎžÍêå< Ã1¸g¤ÅøŠ” q#}q¥Ï7:ä[äÀëðfx‡’±zÓ•Oš]={ÌP,Îái/éWƸ™(ßeël•–N-‹ìˆô´_û;ƒ•®Z–cW-Ü{D-.#‹Ë7{œíñ -}®Ht=^$*ù‹€ÐL8Ä­³ÖÜÔi¶ªÞ”TÆÐ€¼sSÍÊlSgEN ÅÓP, @ ™·©–ÑÉ •Zü å¡ð¬³|#Ƥk.­TŒ(E/Ëň·Xkè'Ý ‡°vÈϿøñöC`U DR -ØÞé_ªS‚pCAç 181bH”úú†þò¢€;~¥ŠÃašŸÆ]q¾L­Å$;âJ¸ê(âÊW"®!&ôjÄ,’}¨!U€Pq ìÒ…f•ÉkEÄVzb)Clêä(Þ -xGÑ ¬,ÀV§íQ¦˜`ï1¼Õ2à Æk/Y¨{‹GÖ&À‹ˆØ¼LŒì¡TÈPÈuaºhq÷£žrªºÊ!0A]þ¦ù6“¡î.ðT…â ♉¿&ž8€žb™~Ûšòûá”0¦¾NÀPFI2Àð¨vZ4¹µ‰&¡YMB%®:ÐÌçsÍ(šðÝŠÝÒ‰&KÒ&˦ SGЩ_b+¹ª_„²šdV2¡]á²å'úIçm y¼`‘Ên±‹P^A8f˜©/Xäñ‚.*Œ”<}«Rõ:6uy:âQ Yœôéÿ@ñWË×{˜„{UákãÇ׸r ¬)…´ðJtäƒy“‡Ð1åI¹­j3Ÿ|3/q½«ÓÚ¬ g±'*Óõ:-‰ÔU‡ -¡½‰”+)ºœðþ½H› 4=ç¬ê2ËD–o×S¬©¿7îÒ¿·lYŸáÃ!ÝÛùÚÇC_¿’íÉNôûû!cƒ<¬8̲Fæ¯5ò'ƒ×˜gmqCù¿`öðÆú'jލm±zbr„’cUËÜ µÆX½Z m†é§›»»Ë4®Ìl[fõ ÍlpE]aWÃÂeVyfX -Om5€Ë‡U%Â@ÅÐ)GPã$úTUéé'Ý CÅÜ>ß~U ÂDA¼/d`™(é sد;¢ð¢jëâñ…·ç¤Å/Î’ý>Ìú#olšYóÂÓßšW°ñnirzAu 6Ûé*›Ñ¼¡Û¨Á ¥G^ä“t[/ 8/Eô§ej‡‘±?ï[^ìrÛ±Éñt넴ʽ`S·ÕzŠOÂÇ6ˆ)²Š)´PVn(@ZRo»XÒ¸Ò;h½m"ÚÏ0óÒ$ÃäJ+ñ0Í^´&ÙëíaT ³s|6)Éìó'mó*[ä¾’ÙC§/¹Më×øpFÇù2­hejð–piVäx gª¹ÛèèRšÖåy<¶áLsdè²—ÐÎ’®wÕÄ+­ûì€à‰ü†e:÷òœ‡c)?§«lÞÙœ;¢ YóÙäCZ·×íí½ï…]UQ¬0oÞÕ€6›ÚÁc0vg·m³GÈÕª!vvZ§4ÊMµÎ‹5øTÕ´Ü´×'î&˜d‹\í Ú”²Û…= *‡á0ú•IF0 “YQúR©Èç6§à2úI„!MWÝŽ õ[ºýFq -±c N|}í\”¸Ï €·;ɶJð4ÿ‚ãiH¤ Ú2_QËëÖ@ðÜ-SGÙñ|J‰\2Ñ{ùÜêIÝ^•¶]K:Å•}K ƒßç¬Aaà -£Æ:0¶ŽŽÆãW'Žc_ÎÛ’Ì5·Eeönmß§ª¦ƒõþßk-¨üýòŸ¾TPP+¨¤o—ÛÛÊÔûÞßšô/Þß[rî2ïߣºåtÒ£E“2y½ÕB¥Š‘¸ -TÄQˆÔ´ºÞ®êl³24sé$Aõ°íÀ¼’¤³e³·‚‹v!’8—K|r²¬]€–‚—–ótmÞ‘­ñ£æ{ý`¦H¶o‰¤G¦º˜+·”®˜Ê–k;ŠqŸ$`ð!…Ü«"šÐm\Tƒ6ƒðÊÜÛIxΥŠl@ø»M:3^ž:úanv«Ì†‹àÊ÷¢û©p––e†•_/ëmé¬õWD»E^4¹¢ Í·Gº‘þ e±GÔæÚ®Ó—ý¦c•9ÜnüqµãÕq˜Y-ƒ#ÅòAG"\±üœ™ÝŸëDˆƒr¼Ñq¬‰… b%÷Üæ÷ªúÚíXöÒØ:­gËÉl•$MgcØ£t>ZŠÇ•EW\ÿýýЕ¨}Á÷­…ÿ³®P%&° -J³ áÒ¿˜ê±(óât·dÍSØOÒ®ùÁÞgHv·aþ±…ý=“A¿¾]ŠNyÀÿ°Mâ<ñ}¶=þã -Ê2Jªñ™ÒcSìLù´µ®ÇOPwA1µmcÖ%Z ôÿj*úW!%uý§ÿnÿ1t â˜7‚© æPô9¡lô$-«ÿ÷øPôÿLÎ8Èendstream +xÚ¥ZKsÛ8¾ûWè¶TUÄ€$Ž™‰3ã©]g×ñÖfæ@SÍZ‰TDÊŽç×o7ºÁ‡LÙÙM¥*Ä£4úù5d¹ðO.r eõ"³:6BšE¹»‹{˜ûùB2Í*­ÆT?Þ^üðQe Û4I·›Ñ^y,ò\.n׿G?ýòþŸ·—7ËUbD”ÆË•IEôãÕõ±ôùéÓõÇ«Ÿÿ}ó~™éèöêÓ5 ß\~¼¼¹¼þér¹’¹‘°>áÎ,øxõ÷Kjý|óþÿx³üóö׋ËÛþ.ãûJ¡ð"_.~ÿS,Öpí_/D¬lnOб´6Yì.´Q±ÑJ…‘íÅç‹õŽfýÒ9ù•Ç&O²&jN€ÆÆ©‚)`UoEÛ–yt,»ãa)óÈÁ3µîðè-u6Íu±sºªSãà\ÏߨœµÍ Þ¦j1v¥ïóNŒƦv±òÂ÷ÅŽ•Žm.Õ„kGó™ZÄ€³¯Rab•fÙäL¢é©PC^+ +†§’B Ôéb¼ï‹Ó{ª™ãÇyNjgÖØéùŸ÷®¬6`PJÙèɧl1C¾©ç½a«Øï]Áó¨rüz•cƒÂ<ØP¹G>z?ž*ÿåIŸC±Á¦Í¿Ð¬u€]m¼i¯”sˆnS ¯Éc1×´œXðF˜-Ýú]ŸŽê“Ä„ûÿÐý°ÅN­"­[¿LQ¬o“"#IþºQŒ©ÎEO5EÙÔ¢Vaã$yëøžjæü‰U'â”Þ*0‘U`À ùa ³Ø`,˜¶CÀ⨨O̧¼Y SƒYà$A+˜ì#žîÍBKÝ›˜’*ý=fñG’èÿûÿÌ@ÐT™}à FT¯˜A ÌÀßy…Q{ë^ØdbHÄúuzª&&¶Ë8ÏM6åâ’Nörð*AäˆÉ8 AZAQì_ìB¾øñ9ÀÍMqÜvƒôy¼ÃBºçyaëA4^ö˜ê¼°{*¼&_i5ý¥° ä)‘¾ÎCO5ÃÄTØTÚ)zÁ*¬ ÖÕcµ>z0ý _höòšä c#ù*<Æù"°ökU*‰š}5JÕÔÔ-‹šÜpZeÀ.”HS79©o Tû`]µs„ðO4°³"!A‘¦2CQ M™Æ2‡ÂS½_¯«8*ؾ>»²#±x-ʇª¾Aê°9` @ª@3¨J¨m§´†ÇÛád Û¹wêY¶ ‘”`Ûpµ—9T²I®·~ù / ä¬ ‰Èx¹g¨¦Sªºsf‹9¡‰®¡¡j·§úꑯÒ +Rm»oê–§‰m(Ž®Hq RB’Ÿh*ÏÒhn6\û÷±h6~£ s(;0^¹ć+JÖ†ŸAÊ–šìÎ tG'Ð'dnƒï9ˆÅ÷кUyìæp¼G¢Iƹc]C1 “˜ÆöC‡Ò 4p@ÄEÝ>9½¹‰©qÝt.Rt3&Þƒƒ˜·LB‘k™3™w?d˜y]8Ä +S;‡¥yÕî‰ |±éX¯^™fòØÃ·¨×ÓŒXûÒdDÛ¢;} +èáÒ‡ëÏü8Ð3Ô—ðüp¬½„‡2j\¨™;2¤•‘çMG–× Ö~8ì¹óópé{Gm²ûÌžÚ=ìêõŠý?„îkéöÝÉÒ››Öu|w Øpù‹‚‘Ä;±+ÕÇsÑÊ ß¹móH?‘EwÇŽ&8¬ž¸4άթKã¹tðXXÜ¢‡Ý×ô&TÔÝöy)¥ô5©0ÑŸE‘Ý`‘ÛUåq[€nÆy ¸ƒ7x“G ŸcôÆvc–KÓ²kì…bµæþ±­º"ìc éÏ\½r­­ÃKŒ=¼7?ŒÁÐÚmÝ}Bæ©§ª{ )O4£¤ûí‘ít=kWÞöô êúx‹Ãw]Q1 Û ²ôµÚwÔ™¨FúÜ‘ Âàð*†½IþÉ Ù(’ÁG“Ñg»nÈoršßæMrµ94»Õ¹¸#…ŽS­B.¢§ÁÓ´–Ä©´!6ÕÍÜ6&6&‡/eMàwpùµ÷°C[‘|l#P–Ç{!Yï [/³‚cP7›¹«!à¥6{3À*¨‡EHÍQ¬ñ…*Ȉ©HÌÔ †CP—iqBÚ1©joÃÀ™wÐIü ¯¯EWÌç'n)˜ácÕ[ê p[?‚³÷azNHR‰ØêD}CJ”HÆY¶dO„VÅ_ÒÕ—cÅa‰FwGŸ+±Õ èSôŸi†üÝoÊ rô'Þ}ÜïTÙV»êÄÉ{»5'z÷>ªÞbä½wÏáe`^ª‰‘PB«4(­øºbɶÕ_srÍ¥&ë%Bw:ɤV‡S#BÙ~@h0ÃT!³*ʾÐßU5ù§åš¢zDb1ÑØ0y”Áçöøe +‘LàŽÁÉoK!¿{XÍ9Isìf 4Î2•[©•÷¥ÖËŸË4ä¿ò¹ÜVåÜ>ylàL6FÂR €ï fÂ!zÆiBc’ðÅöâ$ïôä¶Ûé­Ç‡v®Cü¤QØ`”õÜïÉu>ÞXyR {Ü„¢OTôKóäñ%Az’ÛÆ†dƆ3ˆ4¿úèo‚aɉ5˜8z+m7ìé¸:4Œ&˜ ¯~ãCÉÕlÑ8·cŽFF¥N@‰UQK•ö…[ŠP«)„Â÷?¾jÀ–·nÜÿX–Îù8,§–¦±{zqYo]Ûò¡› ?ºÇaöM”w8À’UsXÓÏ'6«s¨){P†ïæ`ôð!Ó‰ƒ+™Q#SþÝ GÂm8zÇ«(B±(¥¢‡‰ùàH€w’ÊW\ĚĦÐ2 æ<µ6ìî€TÏ{¶ãp—Éõ1¯n½Éûuhù÷èªn©WЧÝäQYTwwä@|i=“cÈ^•³ð¥ºÃï]´Ž)Ñ”¿å`PèÖ…S¸úoþôPr˜±d<ë1žºVÀ0“Â=`zy+fáämØrÓl¡*í÷ ÏãÚãnW„òb³…×™g‚™ÄáZH•ýoáúì{o–ÅI–¾ñÜ;":ÿÚˆfAÎô–> endobj -1398 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [399.2874 719.9611 467.9594 732.0207] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1401 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [461.1985 450.514 510.2452 462.5737] -/Subtype /Link -/A << /S /GoTo /D (DNSSEC) >> +/Parent 1398 0 R >> endobj 1397 0 obj << /D [1395 0 R /XYZ 85.0394 794.5015 null] >> endobj -438 0 obj << -/D [1395 0 R /XYZ 85.0394 615.421 null] +422 0 obj << +/D [1395 0 R /XYZ 85.0394 453.4423 null] >> endobj -1399 0 obj << -/D [1395 0 R /XYZ 85.0394 585.8633 null] ->> endobj -442 0 obj << -/D [1395 0 R /XYZ 85.0394 502.9736 null] ->> endobj -1400 0 obj << -/D [1395 0 R /XYZ 85.0394 470.6064 null] ->> endobj -446 0 obj << -/D [1395 0 R /XYZ 85.0394 298.1533 null] ->> endobj -1371 0 obj << -/D [1395 0 R /XYZ 85.0394 271.5604 null] ->> endobj -450 0 obj << -/D [1395 0 R /XYZ 85.0394 137.8852 null] ->> endobj -1402 0 obj << -/D [1395 0 R /XYZ 85.0394 105.518 null] +995 0 obj << +/D [1395 0 R /XYZ 85.0394 426.3513 null] >> endobj 1394 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F41 925 0 R >> +/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F21 710 0 R >> +/XObject << /Im2 1049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1405 0 obj << -/Length 2683 +1401 0 obj << +/Length 2863 /Filter /FlateDecode >> stream -xÚ­ZYsÛÈ~ׯ`ù%P• Ï…+~’½²W[±ÖÑ*IUv÷‡Ê$À%@ÉJjÿ{º§{pP EÇ*— =zúøúˆr&àŸœEqg*›%™ #!£Y±>³O°öþDòž¹ß4îzs}òêNfY˜Å*ž]/¼ÒP¤©œ]/~ âP…§ÀAo¾|wñþWg§‰ ®/~¾<«Hï.þvNÔû«³ήNç2dðödz×çW´37—?ÐLFL¯Îß__¾=?ýýú§“óëN—¡¾RhTä“_³¨ýÓ‰u–F³{ˆPf™š­OL¤ÃÈhígV'¿œü½c8Xu¯NÚOŠPéXMPé)FYkXBžçÅ-j{å`¯2p^„G঻ÒÞó¦!C…ÊÈ”75mÞÚµ­ÚÓ¹–*XØß„P•mp(ƒœf'GÕKZho-Müpù ÍTùÚ6›¼àùö6g–÷åjE[nx­±¶"êæatN³»il;>©X• ]¾6Yœ¡B3 Á1€OÊ0‹"åT¡àë4 Öy[Ü¢8Èñ‘‚§2@EpP.i­lySSï¶§2 P_|ä— 7o›†Þ±F;8›‘¢$”J¶1²À×÷`§Áµ°SΓ„qÄÀSa–¦é4ìæÇù¥ÃÔH> XR&îF)^dL³0Ñ2~F=ǧdÌT˜(aÆB®Ê¦ÂtÂŽˆí]/{ç8ñû—f"`ÀI,|,8 ÌaJ…Q”¥Sk&$Ð::ö«|×8´§A^-ˆpPCba›¶¬ò¶¬+š@¬¹­C¬áD‡5ÀšFÝɱ…BÅÉ,јUfÏ€5æ8²œÂ$~ÅýÉ_[ЉP=£žãSBf24ÙXÄCPKB‘dr5ïG„Z,Â8ÕñP#¤@2…7@®ÌR3ÂÖÃ( .P&­ƒªn‰h6¶(1¯ÛÅK˜‰LpS·SõCj B¦r$äaÌÇP.ã,ñÈœO”$pL9>¡Z†¯€Ûa™ïV¬I[ÓÓñ)«Od@ˆ»Ð(­Æ±šcÙQ`ATY¬#ZÇÁEÕ­•‡8Böø„˜+>#{7r•`ŸÏ”ªP~“ú‡#­§C£…úªõdEßb½_Q]"ʽ¢«†•kóÏv⨹ÎÙ^#+~¶S§€ªqd<üîoKˆfðƒ 6ÎDõ]¹À€ˆu€àÂÚ·yU6k.ë-­SäÀŒ/ßH;?ÃbcW¶ðs~£ëF2€+cè Ïh+÷(ÈÈI:#uà"·L9rîµ$Yk‹Ý¶)ïì¼®VSè…œúŠᦒØÛG%ÌW ‘Ô"©DŽ•›#€ñé?vàv~qI6^3G Ž•Ç›[¢Ö«Û48ÖÅ ‹:ò÷À¸ZDÁµ+¡: -jwæÂny¸¤gW“F„^?…Õ'úPš$ÙoCâ[ò³)?UÎaàÔ–¦~S*Aʸ¾&º¾è±h‚MÔniêÕ‚ÀVõÊ8ÆE]µöKÛ©ê¬ ]¨…Ø‹zn(ä¶«£âfÖ]æ?lX%Þd `[ò“;db’ÆR:¤ŠX‘(ÿ®]ß=Sׯ£‚BƒÚ[§¤@£M¤¡ÀZ>)¢Œcóøâ€lÙÎpƒYPÔ¹#‹rfy³²´Ã¥YaXÆ«,t‡UaÀK™Ú6“Ð×±žFPÔ!Ýb®‚œD¦Ü”žïUæâ€'\pˆï-ùéÁ«¤._\Ž·ÁÂnmÌ÷²nùt_äb¾¸Ãª¹ý®z½s JÍH>œd!ïpŽEHr*oÊÞ?”Øޏ¸ô¹›t@.9E½Þ”+»˜{öðåÚÉìíÌá§?ÛYúóÞü°¦¸kð±8"3“Mõ‹À—Dõ &ÀjèÚO4B’‹œ"«©¡Vþ 'qÈy®ÿЇ/Qe’}·‰§úÅ][Ã>2Óon{i¹ S€èî2#±e&½pêâ2$â¬z˜lÕLÀËå  cÁÝ2KÓ c!çQÖÁã늜õQoheeïìŠæ°$6ÉÎÄ»-ÊÂU²4ÑçywS. ßR'aíÝÛ]w˜ -*±ðÜäÛ–(ú®‡(v†O‡ÈLú -õ’¾ÓR±Le ™(È@ÙQµCdÙÄ÷räÍm/P¾äâuð@ÌS‡µT -dQ1ûÚ¦¢l'ï¦.øY–|O à@Df—Øßm—¢&ì5®ú üJ8˜“¦¦` >&¿J‰ÐD™ü– T¢¯Pp ^Þ†…âG;´@éÍÂi[ct9êkÛ‡ FûM.óE.(‹å6z×ð½cÿ^÷fè­þ?=ÿ:ñm´Ö¡HÍžÚ”ìb@Þ ßì¿ ñ±t·Ë(#ìÕ+Úrí‚©æ¶Þ­Dó Iü;Š#sñýk½½|õï.ÏÂ1ÿæo¯þ~õú’–²Hãë‹wßÄÓ碗¯ß¼¾|ýî›×ç×Wß½¾êtê+¸BE~?{Íg+Pû»3Δwfö&œ ïålw¦bF+• Û³ŸÎþѬ†­SöÓÆ1#u6[(Í🶲`V@²Æ³LIÕYYŠ)+',´r¾Ì—·Åb¹-òª¬6‹²j‹Ã]¾=U_d–)cålÈã$Ö„(j а’)Jd¹º-ट7 Bq ñ‡r»¥Ñá\¸y±«ïV›oq¨ø<(AТjeÑ| j~“7ÅŠꊾyü~ù3màäÛM}(ÛÛݨÿlá9³Êÿ +Á¼12ˆY€l÷¸~b_™1ǵKd˜Ý•ŇH'*(†,óý~[’]à>?ämÔARÈ¼ÛØ[Uâ!Lhƒf¦àBÎç^΃ì<æ€÷9& qÈ%ZŒr‰`J +s‰È~˜J8–y%]Äa].ë„Yƒ`ãÕc˜pÖt—²°pÑrÎ6äóŸZÐ}WTQ¶·‡|·Ë‚ÎR3o£k&Ð+÷¿æ«Õáý—ûC±.?n‹êšþ¬%óxóŽlöž0nêͱ¡á}ÑüZ~Ňӯès=eð¸y¨ïÊU±(?®/ !†4ÅïÇ¢i_Jc$G±ªšÏÙ»8®ö”¨:în’iŸ¡&Ö—‰ÐòªY‡æ³v/ î0ìø 7œFuU,áC¢øŸ$tuáM·EŒ™~Jéߊû&ùXø4P=À 8$ðþñÆØuôÑ?_®iSË¢×´ÜëIC$!¬‡x¶x 3«Eá_Ã’(‚°À{ÝßïëCÛEN®'äÃz™)Øô9wÙPÔ졨Þ2™…E‘ô©¨Ùl±¨’+&•õ“ÇI¿\ß?Ï X¢Z©3höyµ + +àIsŽd|Ú˜ýÉü?Äô‚I'í¤ Èc[Æ”.êÓÐŒi{(½”® žM¸Bb8é ×#~½.#f=8šJY¦Ö/f6¶‰r’™ÌèIÚ¤;»—›Jj¸Á¦|/ñœ<ÕÏ1‹y1³±Y4çL{7" v]Ó óž®·'÷×3ÒáxÿG£äW× ‰®ÕzŒÊb²”øó«©B8jË„†`é + ÷tômñ ç²*Û2ôÉ« ~nòM1Q•TFW·ÅD“)ËO­bà!-hp2ëSØ dãªÈ [¨\aº¼…Âu &+›¶\F`(_á{SÐ7ošzY™ÍcÍÌ© †OêÎÛ°êð|·F!C«í©¢ö´ß¹§­(ÓGÚ ¸˜Wà@.è §ú“dê}Ô÷ŲĽÅ*ôü¡A“+ +Üc›‚†¡ûQI¦†Ð©er¢,¡iàzþcÊy•Êxìê¦=á¼$27 ©mú:÷m‚JfÚäá»Ú†¼›§;‚6þÔ4­’³AËö°²†ÖÏÛÌÇ3Gû¯Ø²®Öîa ÿµÆd¬˜5Ð,°?0Æ~Ê =>Zé§ÜPáÛ–nhÕ|ZBÐSBæq—ië=A¶ô‡=BJu…ç°9BFñ@„l#BÉ—U…>QÎ'ÔRz£RgÚ°‰àÒÌ÷@+ô_¡—ŒgŽ[=>æÇùX‡Ö3unó² +ݧÃò˜ÀAStmöÄÙiΠŸ{ÎáI-°§ŽßÓ¨ÕupuÙ£¯'hM èÃŽ´$,J…÷©Þ/è„c}‚.'µ^]¥§“<=!`Œ–›ªî£V[N  Â] ÙYã¤7b@ƒ5ak!y:ó ûdÞÉ)û(aI7zèèvÊKh(Ä´ü_yMØã^3¸‰•Á¢ÔŸ\áñ-¡a]âD}0¡6óûúHƒUÙPz 3z˜Q: 6À0ûã<åBczÅ寮 ŽëcÜ“¯"ƒ¼ÍÑr™‡¦îð[‡Y¶ôÍ#•ØéãÞ—p¯»Hv}<€ß¦r* ñÕ†G'…„Ú~ò©ЉcÊÄëÉrÌ@\Çó!'OQdYÂJï7#Jpo‹.ÿtî9~-ÆgYu’»= à#Í3r·„‚Nwî=zü˜¸)ʼn[ºÖ0Ï­ŠoK|zq  ·E°z˜Ð+¦uóm½ÄZ a})G­ÁÜPwÐIÃb8aÀßåM;@éœmú  ÙÛsH`*‘@ "c@ËÌшãz¡ZF'' òðlþGÈ›8JÍ.Î *REømDïM°‘³ól¬•žÀ·ù] ÉãžðFÔÐjp9mmLWñµ>ðœÊJÊq¸³Ó• ö”k@ù¨U‰œO§” ÖJyòËFo¼,ãó­•T„Â,øË*â€¡Š»´c_7My³-äE¼§ég+§ƒ¦žÎõó}/ Ÿoc=0xx +ÓzTÈqijûgõ¡’**‰ÈÕ"v Ú5™Ùñ5tbOL?–„/UGÁKŸï­ÿzƒÿN ôIÇ_˜C¶QzØQv?\Áò*.“¥︧—\í GWX~lëô1àÔ|êùšRŒnò Ð€ï+ ÁhxuÛ×u,ˆCC¿oNË!j~=ý$¬Ü¼*‚B°«ŽI¸ÍKêñ¶/ÃïUÊ•wC }§¡E?¬öQI£Ub_·_ÁH§ô KÝñ*7¨Êp÷T)¦T,Þ›ñE9õŸ +¢QMþï€>û¿<úÑ–)çäôOÍpŸaêSI¨ðÔäþ²-™Êä„èÿ¬O*endstream endobj -1404 0 obj << +1400 0 obj << /Type /Page -/Contents 1405 0 R -/Resources 1403 0 R +/Contents 1401 0 R +/Resources 1399 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1388 0 R +/Parent 1398 0 R >> endobj -1406 0 obj << -/D [1404 0 R /XYZ 56.6929 794.5015 null] +1402 0 obj << +/D [1400 0 R /XYZ 56.6929 794.5015 null] +>> endobj +426 0 obj << +/D [1400 0 R /XYZ 56.6929 654.5469 null] >> endobj 1403 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F41 925 0 R >> +/D [1400 0 R /XYZ 56.6929 627.5235 null] +>> endobj +430 0 obj << +/D [1400 0 R /XYZ 56.6929 355.4402 null] +>> endobj +1291 0 obj << +/D [1400 0 R /XYZ 56.6929 325.2926 null] +>> endobj +1399 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj +1406 0 obj << +/Length 3514 +/Filter /FlateDecode +>> +stream +xÚÅ]sã¶ñÝ¿Brç„â“ 'O—œïêLsI}N?&Édh‘–Ù£HE¤ìSÚü÷îbФ¨“¥û†ÚOõö#0CEÑüö!'Øf·ÝÔÿ¨ïé¿…^à¬%zk‰X2 Û…¸Êf[?Y¾(>Ýoýè>eÆ2ma48­²)Œ 0„Ûü—]Þ´'f“Ä]–é®Éý¾ +ÿßÖô¿N?º Åó¢õ»¬›¦¸+ón Ÿ-”0 L‚%ÆH‡:+𔆯ÊqÂ5vŽG±$àúŸoo¨•?浞¨%çwuû@°uÚ´ù–ÚÈ×hÊôÑãƒk¿Xí{w›M½mé£h_A#óûÚcÉ?¥ëÍ¥˜ OQ]y@ Ñ‹X6Ø`“oómCJ_øÿ»Ýjµ§&Q å6mr?À­ŽÀz»½Œç»Më;²´M©å·-Ïœ~à_Æ:jfmLÊz;­k ‹µˆ½´ó¬j&4Bjfu§¤ Þ"žg9ð|]TH¼)fl©ÓÉ¡e½LK‚O¨ýT”% HÛ6_oZ?­¦¿ˆ_½yÿÁÏpGز^¯wU±LÛ¢Z‘–i°ßب¡ ž +§ÀÒ0hl/S¾®[ÿíIg…6+¸·Yäx~Ÿîʶcðû"˸Ú³fŸO±Oh–h,Š„N¨Œ¹g…$9Ó²3IÒb—mMñk>±”‹üèzÓ52ÍZØ)ê’²‘íx  ïß|çG!Z×jÒ–:‹† i¬j Ð1ú¾ÛO‘ ’P‘ JU¥ë<› S¡VEÊò¢œàœ¶{”jG)9‘9‘¾0•H†Â4øûe"Á9õ?¦åÎ)«û£ÉÔa„$(©_2×<‰r·oI¿“ùÜð>Šz×6à›©³}(83˜xéò |Ê'c`ÉŒ•a(x 1Â*D€Ø ƒrä;‚ á„íKÅ„C‡N¼oêk,]¬,<‚>üw9ïvL}Ö=‡ápÓyŽjï75ˆD1Ó]V‘.?6´tÚÐr8»OÌçIMîGþb^T”#§³ˆ›ø3µP îÏ ÍâüV Ãð{q*¯Aug5ZÎsw¢¡B, °f<6´†ø»¥Á4 òŒÊÙ9@Ð+:êtçqíª èhë:óð=Á}¶ Äã?@böÉÃ(Їᛴ]>õÌ~ ƒ]c¾îÄE[±Ë/ðŸpb "If@ç£DÏÿ…ÎÔôбtg/4šM¾,î÷ôñôP,¨IöBmwŽÛaCñØH=’`—ˆÃEÐnÚäÙÖ +É¥ ²è¬x¿¼kðKÇâ[t³¦AÎÔ×÷«iÃÉ_¶˜•ŒÇRõ”¥ªnérC5ɳW“éÌ/þÀʽ…ˆÔ¢pZ¯gX¶Öƒs~Ê”e*éøß´)äRÀq~’/J8DåÎ÷î.¥#"FáKØö|¦’qß&-!Æ–?µRkW.°!þ‚Fµ[ß¹äƹ¬Úb\-wÛC<а¢º«wÎšàƒŽ‡º#Ëut‡Ùp‘ÿqÚ0óƒ¤rJú­ XUÕSþ\—ŒõH+N°G)’èþ‰=TÄA|xÖ{@º .¹;í«Í)Å’O*<Í‹WçI-³šIÝ^0Tº Æ“D<3•F~}Ì÷'ê †Gr\oÐöd  +Ä£† 锥*¦´Â"ãR£„`Eii ¡„˜à9¥FÉ’8ާ ‹ßâ€jˆÃ8,Z)Vuf2J É⃀²÷[9§¡½ÓЧj‡p¨ÄÊŒ¶>f/G¯:?«|’—Pº +ÿdÀØ¢S—F•I—>ñÐ⃥‚‚ŠùžT”TBŽŠ1šß~¸~÷j,!"£h¦#Á"¥cd unW3jÜôª¶ÝøEÂqÕö/’ñ!¤ÇNTsDMd˜j@ÌQá8 :GÁ—烠Õ}ÊGó6-)ZG°“þSXk‡e=ð\Vòù?<"ëŽðn†+ôÀ{njÕ~vbXÈözE’A°ÂüašƒM2ZÓ`B¹ªÒv×ÕYLWô3^Áà•Wùt0£Ï]Cl0¡Ž“P áàÀ!QÂ/h¹ÆfYg„ŠYP&‡€t);=Uyl‡J³Åª¨¨ä8ÌšžUa¸o~ÿ²+|”?ôàw]AbU…¾»}X/ Cþ`Åd²äðº„Èo·‚ NsO$6VÛt½†¬Ð}à™z§9@™èŒ×6Œ‹®ž¼6b…,µ~j¨íœ6Ö»²-6¥‚81ÍRÀÎ +kî{„»ô»Q'zC©çõzþb»ðõifc1Н{Eé¹èóΗVͤôS± &MË©² dŸJ&ñ¹{>ë4ÞÅc4bi‘ÝøÊF›C: µ¯ú"ôú»GM Ÿš8Pä§ôÓ>’e>ô8)9Š|rdè„ ¦'kÏ£"\‡\ž›~.pŸb œêVzèð £ï‡ÜU€'iƒ¾ü1/ƒþã<K š¹KŠí!C¼ú¯K§²Ã"G/ù¢›5TÂÔU„<á¿çÕ\}IÎ?@¼W¦Û^!T…‹)Íi¾ 2ÈÀãÈh¸-œ{b[Ò@Fi¤y±Æ)–ØÀŒgìç-‘n):EŽ*†t.6C¿›åmZ”Í«à<ó‘{Íòf¹-BÝÍ8ï5å´ VÃ{ä—©5ú¬‘«~‡‘J¡ê¢G༘Œ•a%Ti+ÏÄ@ÝøEÂqrŒwÑÝ¿ÂìI„O‘’’Ž"¡nÔ9Bްõ …x&UW(Ô缯€ƒÜi‘FÎ.+ÏûÝ.7`œ¦XÄ|¹Ç5ÁãF'=®y¦Çu-ô äz­e1×#S¢­`¶Û•(új|N­}^®†>Ćâ¬3C›œô· +úȺ­&ÇSýnO" Ž æžò·Ö0™tOÎ +Y1Þ•6ÑQîEin¦K#/%ø„×í_?¥áÎäöÙ›d?÷”×…x +øf^¦o¦»Ó]R&·âŸ\DŒ+!Ÿ™“«ˆÏä®_?kN çÑgÍ Ýå¯}„'wgUw¶vÖ¤BÍÆ•3£¼[ÎsëßP`IÅMéY“Ò·&埯`ÇЋ_bG¹™Š_TävRÐÅ© y€>5<„ñû`@˜Ãœ2 yÂ)tƒ… *{iXÌé€%ÂK»ÎKž—ª‰†:.v—‡zÓ<Ukÿ$ÑÿZó| 3 ×H<×~Ür +` Ç›Ó^-à4ÕÄwn&— Á1 i!1lÚbÙ,–iUå¥OÎ>*²îõ›Ï»Ü2zTk•ì±P˜9BÁJÿqBøÌãP£$Š~ E…ÅAlaÉÅÃ6?;Kpÿ%B1c5V3è¢ø“ï"¤½ªZàl¿ +½ò¸?ùA.ë /„ädŠ`†?¯ñäç²ÀÄÚuüæ§~P9BJid2ª"í‘16šçX3z)òÛS’åøC–D%¡DßP®8TÝË®ïÝ¥à±>ŽD}úU@ÜݨNQ3e‚Û·ÚN\ óÒßÓ{ÙFå +b`µ‡­âz #ýãªBøË 9oö ¬Aí4[¹M^ܰØÄj¨¥m^Å…2ǪW̦¨§×yع/¡TtáÒÿ‡ÞQ?î:ñÞT|m9ÚòNSþð[ÔÃC]m™Šã12Þ—Ç2±(§“ɘòîÑê1éÿ—ðl endstream +endobj +1405 0 obj << +/Type /Page +/Contents 1406 0 R +/Resources 1404 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1398 0 R +/Annots [ 1408 0 R 1409 0 R ] +>> endobj +1408 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [116.0003 457.8291 166.1092 469.8888] +/Subtype /Link +/A << /S /GoTo /D (tsig) >> +>> endobj 1409 0 obj << -/Length 1124 -/Filter /FlateDecode ->> -stream -xÚÍXÛnã6}÷Wè1)@®¨»§lê¤Yt³­×}rƒ‘(‡nKÒqœzÿ½”(Ù’/Éq…aHâåðÌpf8C¤éò‡4φºé[šë[ÐÖ‘­É@×f²ïf€ª1 š£>Ž®MWó¡ïŽ6ŽXÔ=iãprvõÛåãáè¶~æÀs`;úÙÇÛ»_U‹¯W_î®ooþ]ž»ÖÙøöËj ¯‡£áÝÕð ÏFr¾Q!˜p}ûûP½ÝŒ.?¾ß? †ãµ,My‘n‚|Lîu-”bèÐô=[[È"ß7´d`Ù&´-Ó¬[âÁ×ÁŸkÀFo9uŸþlÓƒ¶g¸{h !èÛ¶ÑÒ íCÇ4ÌRƒ…І-5 ëúÙk–%àWIH**yNÌ -y?\[¨±-ºLº®«6D!8Ö4ÅIõ9 bÌù½úø·Ò ú…–Àš£˼š‘`.»(‡êõ µÊDÀqœ-À·9aËWµ‡!#œO,‚ÇiL¹Píß/Ôó¾iÀYzbXÁpÊ#ÂÞ»Gó<”»u2® -äYLƒ¶bUÏTõLÙ<®7BxßG<i&hÔ†§ù´à]aæëöâ£Z¡Z`rÄI³f×YÅÁ# ž@aÈ\5ü­Ûú³ta¯è,Í‘m¨µÒÄWˆÉËIá4ÌBÕ¶$|š±išu¦‚ÌË-€Î4BŠãyÞ|Ÿf¹ µu@ˆhmO\0šÎ~4±%ŠÅteLšüF³‚¼ˆË^ý'›³Ç]¹m./ š8}­’oSž“ ƒ4R„Åz# ²4^®"ʸè%E…Co9Ùÿè7­åéKÄÀæÇmi9;bYBɈIÒ ö¿7l{—„HrÐǶ¶öSz†üƒ-y:9Ú¶Œ$Îf ÓHçÉC}"t´¯ú4”&ŸÍÅû‘Mz!µ$k†ò-½¬Ôƒ¼äòÈ ¢Õ¨ÜæÝ™´Z -„$ÆÕ$N‚, y_‘žáþÑ2Ÿ?<‘定½÷4·Š—$ ›@s«á®«9.4]C&κ–i—0¿”]6ô]×Ñí›Èñ–¯+v¹&”sßäž&Mg—¦L;M¹zEÓ:@Ó:’¦ Q&¿{öªHA—™¬LhÀ=Ù8gÓPžŽå9Éžëá§ËHòŸJ‹ùOXG´žîÖD)žXÌYw¨ƒ„6™wO™â£}"C+#‘à± BG‡²÷ƒ”L„Ìûû@ ]}!Z,dp‘G#Èêª&Çⱬ¤:L%¬H­‹Ø„ˆß6y°U…)y¾¯Ë.Õm½·¸C[Åñ3¹x³`ÚS$œ¨¸;q öŒÆ¡‚TâÚ]O  -YÕOü©ÊVzO×þÜàç¬.÷]™6,îvö\êèë{›w_!mî×,™/xž±¹2÷8¦î@ÏðÝšT¡Pm3_ß5íRÿŽ@íendstream -endobj -1408 0 obj << -/Type /Page -/Contents 1409 0 R -/Resources 1407 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1388 0 R ->> endobj -1410 0 obj << -/D [1408 0 R /XYZ 85.0394 794.5015 null] ->> endobj -454 0 obj << -/D [1408 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1292 0 obj << -/D [1408 0 R /XYZ 85.0394 748.6299 null] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [399.2874 346.5415 467.9594 358.6011] +/Subtype /Link +/A << /S /GoTo /D (zone_transfers) >> >> endobj 1407 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F41 925 0 R /F23 726 0 R >> -/ProcSet [ /PDF /Text ] +/D [1405 0 R /XYZ 85.0394 794.5015 null] >> endobj -1413 0 obj << -/Length 1090 -/Filter /FlateDecode ->> -stream -xÚÝX[sâ6~çWø:#Å’ï³OÙ”¤Ùé²-¥O”a[NÔõm%± Yúß+_³1`C2³í0ŒeÉçÓwnÒ‘¦«Ò,Úö4Ç3¡¥#Kó㞮ݫ±›ª¾ë@ý«÷“Þŵáhôllk“°†åBÝu‘6 ¦}b8PzÿêÓèúöæÏñåÀ1û“ÛO£À–Þ¿¾ýuX¶nÆ—?^޹ê_ýrùÛd8.‡ì -ãýíèç²Ç+{@ÇÃëáx8ºf“½ád£K]_¤¹"_zÓ™®Jí=žkiêE‡Èó°÷LË€–i램÷Gï÷ `m´m´Ò!6lÜ`@Õ èêÐÖ”cyÐ6°Qp:¶®÷ýê ‰©(;þÒ-ý‘ðd­Ø}’rªúP9ú®|Ìrý €ô, ×F¢EVoÏÓL²4i²ˆ–-!9Kî ¢º`L„¤<aÊc"·*Iú$Wœ§ B©öcæ‹S«€HÒ¥:ÚÝ^T=ÂiÈ©x(v—“÷¨S@ÐK&’/ÏåqÄ"’ ”{Þ©y¦<I±s)£ã0ÐCŲ[c¤ê§jŽõpÞ›Í6|æù¹«ŠH?"Blj¿bÍi‚•ˬ’xPõè»&[ì+qÄ è=ÉÏhµB¡•åðùgÉ‹‹ò9J«Œ¼³ˆÆ4‘4€?€…\Ü2‰¢ô|YP¾Ü©Üó¥Š -1WÇPÿ¡Vµ·)¬k˜`}p~ØW9ì£×=ì¿Rìý0wÿÝSûÿøÚíxÙt±gX0¿k¸†SÿjÒ³/ý¶7¢¦ª¿\oîó°Q»ÏÃŽ MWT¤reü‚ùúvð%õõ~Lendstream -endobj -1412 0 obj << -/Type /Page -/Contents 1413 0 R -/Resources 1411 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1388 0 R +434 0 obj << +/D [1405 0 R /XYZ 85.0394 240.6473 null] >> endobj -1414 0 obj << -/D [1412 0 R /XYZ 56.6929 794.5015 null] +1410 0 obj << +/D [1405 0 R /XYZ 85.0394 213.5966 null] +>> endobj +438 0 obj << +/D [1405 0 R /XYZ 85.0394 126.6995 null] >> endobj 1411 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R >> +/D [1405 0 R /XYZ 85.0394 93.8745 null] +>> endobj +1404 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1417 0 obj << -/Length 2117 +1414 0 obj << +/Length 2970 /Filter /FlateDecode >> stream -xÚµYÝsÛ6÷_¡Gú&DðÉñ““Ú9w.nÏQ_êf<”Y¼£HAYQ¯ýß»ÀmÓ‰OÇX.‹Åîo ™M(ü±I¦¹œ¤¹$Š25™¯èäæ>1/¡x(õnzôö\¤“œä O&Óå@WFh–±Étq½ÿçéÏÓ³«ã˜+%ä8V Þ]\þ€œ‡÷?]ž_|øåêô8•Ñôâ§Kd_Ÿ]]¾?;ŽY¦¬ç^à Î/þu†Ô‡«ÓO¯Ž?O<:›ögž—Qaò¿£ëÏt²€cÿxD‰È35ÙÁ%,Ïùd}$• J -8Õѧ£÷ -³né˜ÿ”ȈÊx:â@Éd4#¹ÌÓIªr’.œ¯ã„Òh]|‰»¶¨ÍR·qW®u\Ö8So×3Ý"}‚Ãg{nØ[}o£i¶í\#ó7ªh¹‘7ÅbáµþáT°4'‚§ -4‘T -éýÃM)’§i2ðA ÃÅ×›¦í,77öãóˆ}3DÀ¢`'ûŠñ]245yljžždÐTõ„©êûLåT.Ò|Ô¥EÕÅ/rë@ÛßbkN8Sê¹¶~Óµœ3ÂRšü=(à<%Lf|[£ã'Ý»×æ¦ioêæ°ÿ½©ulº¢+MWÎÍÏΞEѳÂèç¦Þ½Ã¬Ë:nõ²Õfå*Äw•[g^¯ÄYÒµû©`íx©ŠûVl«®Œ×…颯$æ‚äÌ%ø@ÕŸ'aƒ0m¹6Ú‡¸ßÔE°ðz^ÆxþÑ=¦¶ÛoüŠeÓîŠvqòWx‘C5uµÿcY¶¦;dÃ3üáõèÖûÐæ>‡‰ù­Ü"„„ýÜðçs°­+} ÒÔ±=ÀË#ÂF#"_ö "ì<ù&:Þžs6éÙKk\à”£bÛ´p¨€Œzã°AùµB¯uÝáçú7Jy]Úm‘SÔ $~1Å­î÷9´ Ö&ûæwúµßizœƒŸ7Úzï9ï#€âo«rPUÔÈ.*ÓŒÝm†±×Ú Ç i7u#ìÚZ2ë#åøv/F@„¢w{ä-ô²€nå F?t£~AÜ.`zÌ%æùÌMY„×7Oy¤rܵ#º Ørå€ |<2¬œyÁùª¨oõ?°:Q¸Bb‡Àw¶ œÃÝrïzY!¥Å¾Êi¡±³Ü™^ö8³sÎ`;1²,çaàX:}C‚E‚ u²5ÊcNÛh·.î ¹’´ßÎ@Ë.p=‚¤‡ý½=-  –§PX9éá—§ƒå‡+æ¡-Îï‚%5G9p1@‡KEËÙ•Ý -©‡¦[ÞôÓŤà…oÍR4.–^-ê²^ymöœvtñq©¿x3šxp. ç°Ä½º&”ð7“šy‘\2]¿° -ܦ@õ†ØÅ°Æc 7Áªj©ÒŒº ‘i#Î^’‚ro[Õ@¦xÎ!9ì—·¨Þ P`,pèýÚ+„×]ÛÙúœ$Г…U˰jľ žS†÷B¯kÞ¬¡Ê,œíœA2–õ<v86Kç<»â£Ù=T-m-ÚnP{àêª\—£´†Zéoy{ýÈ<ªAqFæÎ‚IW9A`jwå¢[Y3]6A"ÔðÐ1€p…•êÖK`V›qÏ(j¿¡"‰4êÚ Ë%/pVÛÚgÙ"Ì,½ìªÙ°Íà è0Åj Jm\ûbg,´%Ö¾j:œÖLãu |sûC2 -üîvM\d+äBùwÕÍN™ùJ¯½´o¦xßø  -w_LÉs‘þ2¶b½©ô›Cw åºo=€6n—…*Ÿù}]ƒp¿ùQŒdðtð-‚þâö Ë‘n"ɈR]Gy»êp—MUÌu¸?tø¹…©øƒ‡’Ïd¨Ëp¹wx¿Ú¯²v…¨‡>#­(Ü1Á#ÖKNhÊUoýÛ¯ K T™Ä‹ïVÚß/5 Š¥<(ÑÆgbp‡u‡WzÿÜÿÙ: AuˆaOØöÜ]ƒDu ‰Ûù†¾]þ —ye¡Cì# siô± Ê€;Ü=‡ðiöÍk3†¨™^!~¤ˆ<¶[’TÍ®Ú#·\â¸o¶Hl¶JÁ!‘C13~¡‹¨¥ -¯ ªü^‹Ò—¿®M>âòwü™1ìß_÷&<ó¿0f”€Qc?ÓÓIðЫÿ)pø 4ÙÐÿñþr¿K§ ÉxžÂû›X]62©xäŒðß/50ý/—$Šendstream +xÚ­ËrÛ8òî¯Ðmè-‹K$LNy8Ïî$YÛsØJR)ˆ¢%V(R!©8Þ­ù÷m )ÑLùÀÐh4ý–Ù,‚?6KÒ0Õ\ϤŽÃ$bÉ,ÛœD³¬½9a„3÷Hó!Ö‹ë“¿¿r¦Còtv}3 ¥ÂH)6»^~Ò‡§@! +^¾{ûúâÍï—ÏOe\_¼{{:çI¼¾øç9Bo.ŸÿöÛóËÓ9S ^þòüýõù%.¥DãÅÅÛW8£ñsÑËó×ç—ço_žŸ~ºþõäüº¿Ëð¾,ö"_O>|ŠfK¸ö¯'Q(´Jf·0ˆB¦5ŸmNâD„I,„Ÿ)O®NþÕ¬º­“òcQÈEÊ'ÈÅ”¦–¬¯×E —biÐv¦Ë7yÕá°¨º¼ZÒZWÛ¯ 9Ž?F‘È¿‹2®Ýv[7Da³+»bëQ²z³ÙUEfº¢®pjÛœ2Ô]ÕeëO%‚ëO¼Ùu;‡–ŸÁçÁb×áJ†ósû ˆ9c¡Nîn…;ª®¼\™uå¡_®¯ß#d²,o[„ úÿùB¨$¸°gÉ”è}Ýv·6B¤8iü8AÁn½-Ê|‰£Û¢[#T‹ï›’?ƒ‘Rî¶p x/6x¯ÞU§"ËÙ;Ù÷)Ú®ÈZ¼ò¼_]=[›ªÊAžHp¨±yÌÙ€žo•¢”„é¢,qÊJhÛ9æa!ÿ–W„zCßWpk +OS”4eoZïˆ4>&Ì­ÓÜ2Æûœ:¡ç„5SÝ!6½ß¶ž çêÆ% €îC÷G@2+5~óõ¬±FzuáQ¨RÜò¼š>KBÅSEÂ*ª¼›(P1NHY]ux”e•kÿv PJ0ipxýò=ŽÛ:û’w—ðÀyUT+Ä14„‰v›g‡G9f™Ç)˜¿×—b{èD¬Ã(Rb&#ê(QOñO€©”šöNóžâ|H]Ï3‘À iÉö'[«8*ga¤%ÝÂùЧ‹@Â^ÅĽ"ˆpÌRª¿N=ÅGD'2di*Ç"0Ëes„7Tk)B·ë"[“âÃzÅêÀòƒ;qÎGéÀ/Þ‹qlÀϤ9œOkÁçÅ<¹ÇR¸=—ñ½‚å<{ár–jðJI”þ°`{Šó!ÉcÁ‚v„ŠAÐëѬÙÇ^²õ ¢Ä£«2ˆŽDSʼ«EüÛ)ª$’³ÖÇ(‰ pS´_f(aôŽÚÔC^NNÄßî#€Ãòo¥¬Ç[fÆá/é=÷oõ â (‚H¡¯“Ù8 Ô…‹;Öy +pV5?tíÂ…G\u>ØMÜà×±eöîµù©Eg¥×µêÅÁË¡‡tÇÖûã<„P!˜¨{ÖÑõ´¢ë² Ä1º°Û¼ÙÞPCídP¹`Å%505÷ó( +%õ 6 > ¸šƒðä` "…lᇮ§8’œ¸Rc ÷h–Íé0=eœ’#žÆ“=ÅG˜ðúð1“6MYDBÒ½E@R'ÐÂ#3œPAÐÀ˜óÇ4P…1Sz¤¨Î€8å-”agSé,€|…TfÓ'½Ãc mãaCÎ.ô(æUƉRÅü@8¨¼Œ=¢^‚­Š}ME…¸» fOÆî¼äÆÝžQÄ÷ŒôÊ +*ÌE y‘â6Ùò(íÛ{òhEð\Í’ƒåüK~G×»ßúMc6ÓL$ ö)´mhGvL)Úÿu/f«ævàóå,ZµÛ,òæaxˆÿlJ?ãýÿtÝçC†Ÿ>Q)0ÅûϦ„¹ž«J¡zé…ÌŸ*äW¹Mÿªbÿ°¦"Kû½5«|B¼ôEŸTL˜2º>q1‘Ö5®’©FV,‘Aפƒá«·WWç/nól×ÝŽÐpëξa­'ÖfM±Àr-²íÉÃŒ¬CÅJÌ„„JÆ.áb³š!p9hÖöøóá†ãfí1]{Õ«Þ3q¨Ž¸Á«Oô˜ë… n®„v k¼ÞnµÆ Ц3„ò®Ò ¼È3LìÀ†2Á°û,|Ó›ö"°™áe,TO“#:[ãû߇ûüI;ˆÅ«Ê¶¹'.öÎ…xa-Û~Hèv¼¶í +;³È]Q!ҾߊDµ¤„gpØ5§*pcKzÀB’(jÙ]ØDÍM7&¹Æ³EðÖféùYbÁ7SËÁæŠ(RÛ6ö„WÞ?÷aIJ1´.¿åTÆ’§dàa¦³{ߨûH4ÝÓZ° kÂiw‹e½jÇY¡ œW²w^“ýlw˜9q€\kÊùiduCwÚÖÕ’J8éÔ¤¥¾•غ¡ÅdOê©eúDŸ­¹oëî % ¾Ìó? 1äßmªî@D]Q{¨ÄŸ`ëP .Ãæ@ñ1&&TèÃ"ÎÝ6ÄiП°AY¨ƒ«bS”¦qé$¬¢_(@½tâôé@îqõdá@É£ûž·çü™«FGïeêXÄô|½ú{ +€âýãüß>WH!YHõX.——mÞ*ÿ^¤?yu'vèNä„ÃŽÊXG#ýp%}%ö©±4H„¦n¸Pƒ*f¿Iˆ¢‰¶×kŠÜõcp$&[÷{[›Š£‰hR9ÿkRpr\´]œ¶©ôÊZJ(ªùÁtö÷S³²ç‰8ýJS¦\ÙH¶Þ¸qLNŒûÀ ¡7q€o4ÈöÉÙ5×ËîDwÎç‚ì/ßÀüÕÖd¹ç§3 VùmY8s±;-#3 T?«‘»ìv÷c{}µÎnUÕ}¨z¿¾ÃG!yæ ´¤}Ø8[,<Ê×nK_.î¶þ8_TFî–á=Ù2–$É>[”-+òÛ?YŠ`2ŒR"õÙê“°°-–$9(²Ò´í§aÅrð® 3ÏÊé+÷¡.Òg‡ñÙõAÜüÏî§É/¨¾¡6ÙŸ 6è ;ZHÌæèÞ,þ]Þ~®›Ï¶ÝápÏ|RÀÈÿÔ?tºý/Œ‰l:êuå‡ÿÙcÿŸ0± …R|:-ç¶+¤€1e9—Ñçþ¿BŽYÿu´Éendstream endobj -1416 0 obj << +1413 0 obj << /Type /Page -/Contents 1417 0 R -/Resources 1415 0 R +/Contents 1414 0 R +/Resources 1412 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1423 0 R +/Parent 1398 0 R +/Annots [ 1418 0 R ] >> endobj 1418 0 obj << -/D [1416 0 R /XYZ 85.0394 794.5015 null] ->> endobj -458 0 obj << -/D [1416 0 R /XYZ 85.0394 421.6574 null] ->> endobj -1419 0 obj << -/D [1416 0 R /XYZ 85.0394 391.5435 null] ->> endobj -462 0 obj << -/D [1416 0 R /XYZ 85.0394 391.5435 null] ->> endobj -1420 0 obj << -/D [1416 0 R /XYZ 85.0394 367.1321 null] ->> endobj -1421 0 obj << -/D [1416 0 R /XYZ 85.0394 367.1321 null] ->> endobj -1422 0 obj << -/D [1416 0 R /XYZ 85.0394 355.1769 null] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [432.8521 368.6685 481.8988 380.7281] +/Subtype /Link +/A << /S /GoTo /D (DNSSEC) >> >> endobj 1415 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F21 702 0 R /F23 726 0 R >> +/D [1413 0 R /XYZ 56.6929 794.5015 null] +>> endobj +442 0 obj << +/D [1413 0 R /XYZ 56.6929 543.7303 null] +>> endobj +1416 0 obj << +/D [1413 0 R /XYZ 56.6929 512.1243 null] +>> endobj +446 0 obj << +/D [1413 0 R /XYZ 56.6929 424.5706 null] +>> endobj +1417 0 obj << +/D [1413 0 R /XYZ 56.6929 390.1552 null] +>> endobj +450 0 obj << +/D [1413 0 R /XYZ 56.6929 210.2494 null] +>> endobj +1388 0 obj << +/D [1413 0 R /XYZ 56.6929 181.6082 null] +>> endobj +1412 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1421 0 obj << +/Length 2930 +/Filter /FlateDecode +>> +stream +xÚ­ZKsÛF¾ëW°rY¨Ê„ç…×ú$Û²£T¬de·j“ ph¢  JÖnå¿o÷td)—hÌ zº{¾~ %þä"B¡3³H2FBF‹b{"aîý‰ä5K¿h9^õúúäå;,²0‹U¼¸^x¥¡HS¹¸^ý¼ùöìÇëó«Ó¥ŠD‡§Ë(Áë‹Ë·4’ÑãÍ—ï.Þÿ|uvš˜àúâ‡K¾:w~u~ùæüt)ÓHÂ÷Š9<òÁ»‹ïωzuöáÃÙÕéo×ßœ_÷ºŒõ•B£"¿Ÿüò›X¬@íïND¨³4ZÜÁ‹e–©ÅöÄD:ŒŒÖ~¤:ùéä=ÃѬûtÎ~‘NÃ(UÉŒ•\HfQ¤&Œ²0ÖJ; ¢ÒÊ€„ÁmiïHÁŸº¼³[[wôúÖþ*„ªË®ljÉë?·ùG‹†€íôè¼Ä¦aï$rû\oü"9Z$³P© UÁ5nû‡œ” ã4MyQ;–,Ê–ž9=vÍݯ¾%ÁÚæÝ© ûS™–Æš5­ô(‰ %qÐmræYÙnʵηüuk÷·vÏ“u{×Óôx{ù¿ìþžÈU¹Æí×ÖI±DK£ÃL&ÙbÙŸ¨JUøQ’+»³õª¬?Ò«³:<ï6 Nmxæí'X°Õ™.ºéä.ßweq¨ò½g{h-èu³çåÛ]å,Úo×y‘F8f»ÃŽߕݦ9tN1Õa“߀F×Ðs +;3n¶‡ª+a?z#s¶aÏ) ceŒãtž›Èt=˜0-g£¥Ó:,Û_%žŽô‘B€àDˆuÎ8‚0hwyÁã¤îʪ¢%7<×Z[us?Ù§=Ü€%§;U Ò–&‹‚3F:i|„Z ¶K“`›wŵÀÄ_š‚wçÃðR®i®ìxQÛ' ø~ñ#¼Z‘‡´-}9aÝyÏ5“cˆ’P*mØÆÈ?? +ˆ:ß:^ÄIÊÔ¤Ï ‰*Ìœ»ÏÄeÏq9fé¢ÝD>&a”)3ìŒb:ÅŽ…¤„"ŒòÕ„ì9>!¤Q21òDȪl»9PÇa’Hüf=œŽ#Àkg¢} ï Î>)FQ–Îa¬‘@kH ±— ¨r'ˆà”²kH¬l ñ$§„6·t 6èÁ†/€ M£~çGÁ¦ChµˆãÓJüÀÆ—c–s`‹C6þÖâ05Iòõdì9>!£\›âéM„| k à·Ï˧RÓDZ HÕàœOcê·JæЕYj&€Ã-Ê‚ ”Ië n:"Ú-JŒìvõF"Ü4Ý\‘Zb=!'B>úJ¹8K<ôè39 Ž*È Ç'TËð™ñ'+»Î!1’&˜6ñéø`2u„£ B,Ž5¯\©“ÝÊb&Ñ:.ê~®¯Ü2ÎÊYNW|â\Q.8æ3§*äß$…Úö™ÖÓ¡ÑB}ÑzLc¢èÏX/ÅOT‰r¯hÕ²r]þi®Þ„2 6±â'{ß>RxFÆÃïnS‚?Ã9˜`çLÔÜ–+tˆX(Nlm±Éë²ÝÒ«+±pž<F|GÚ3L¶¶²…ó ]=’©Ž2†Þ䌖r•‚Œü–¤3R7,ÌÈxÉÜA.½v‡$ëïmqØ·å­]65”Ž3è…¶¡¯È_`Q{û¨D‚ 6&’«êDŽ•#€ñã!¨šÛŽ?\“·ÌÑû‚cåñ榨øê¶u~âNÎ{d\-"×›,•Ž‚Æí¹rE=¾®éÙÍö.Ї¦0ûdù¨m‰oÉ϶üX»ƒCíhèW¥¤Œ«ì` ¯ü€‹Ø@ÝØñ’¶©nn³zPÆ1.šº³Ÿ»^Ug-(éB-Ä‘Ð7P¯£û>cLR ˜Y÷‘ÿ œJ¼É|Ã%‚’Ÿ\ +P;°„d’ÆRN»‚7®rWÂô…<*(´kJœ’6f„‚³ÐO7›2ŽÍL³ lÙΰƒY×¹-‹bfyãZAQǬ +ãUºÇª0ÀK™ê6“2Xå]NL8˜qû!0ðEI9Ï®nÏÌÜ™¦Ô~αÇ}Á †Vö÷u^!}t¡CàGÓÃ1"^ý%w±Ü.ãE ]j—gûÚyín4_Ehï^0°£„ç^ØH–õ°pØ&ed¼ïy&3õ;TŠZ©¹‹퓨&hê®Q½áº9Q"mš¨§Ã@Ô`½îxŒ?§míkŸÊu ÜÝÎ9a–ywênãŒÔ)oÀÞÊ”.|àJЩÔ{%Œƒ‰’à_=³º,û[ð`^,‘%3w‡÷bt‘p¼®žÃé#ç Ÿé}ü Ç uý\àÊ ‹eüIf®& '=¸E½ +Î/(7’»â’œ—Hlò[;aA/NU^;©Gœ4üí¼ºËHC¿3Ü|Èçg”^ëW|É„3×ÃA™½ÚÕŒŽÚq…bW¶.x¬á{?äÚx®>Ìk¢vsF=Ë1…|P&pÔ©ÄJÃø0Bªÿ< ©C¸ÅXyÇ)°XÈ[Tæä€N8DO×–üôàUÒŒ§/.§Ë`â°µ+æ{Ùt¼»Or1w'n³zé?¿„Þ\ƒR@1’Ï;Yˆ;c’ÊÛr8 +|ޏ¸ô±›t@.9E³Ý••]-ýðåÍæo%ù"¼ü³Ã­²™æÀ´3­±†3ψŒÆdsõ"ð%Q}@°íGzC’“œ"«©±Vª¿Þï«r®úð#ÊLr¨6qW?yèX]pª÷„Ì4ÅÎí(,d +Ü]f$¶Ì¤?º¸ ‰8«ïgK5BðÆr1hÆXÐ[fà-&Q·ojšpÖsD³£™ÊÞÚŠÆ0%ÉÞć=ßeá,Yšèþäyu[®+_R'aõí®:L¥XxâU=Qt±‡(v†OÇÈL† õ‚nj)Y¦E ™(ˆ@Ù³r‡È²¹ßX€7—½@ù”›Š^¾€ôbž¸è}œK… ÇA53°Ÿ¡l*Ên¶7ÐàgYòWr;úÈ3ûÀÞújC¸5c7ȹÐzè'hð–,~dcnš +èu}Â@|ÌÞJ‰ÐDÏù)lNUŸ) á׼ŷvlÒ›…ׯ,èzR×v÷;ôö'Š\æëD²\FZî;Žû蛡¶úÿôüûÌå0h­C‘š#µ)ØÅ€¼o|±ÿ ½ÿ×KGÐ]FÑa/_Ò’kç|Hµ›æP­ˆæž Iü%Åž7½Õ¶»köŸF©cäóÓ»2Å=¤ÝßËô üñÊ3PøC¡Ðé~Üóվ쇋'¯Ýß–¿ >r"¦ÍYi™/†<\woÛçË”óF ‚¢ãÁá@fN¼ O1ï{pÀ;ܱP~7HûÕ~uûѶòŸª U[70Tã:¨Œ$y-àÖ#£…­^Í1_—Õó¥—+\Ý|óŠ=wÊŸ>ýc~RŽ'ûã0Ǩ÷=ìóQÿaÀ·«Ü€Å]¶÷ž`Ù-ðÎÉqîöö¶lípîÒ G<Ë®ìÚýõ\?ð&™¨öô×ÍŸ?²Û—Eç­ô5áÏÕrª}é7TýÛøNê/»€ÊÂ4M²¯ãþ$z˜û7+þïËÌ?½ˆþÿZþò¿Ø ÿd’P§©þ{fR èÑT$,ê•ÈcÉûÿÅy(úÿÛ"›ˆendstream +endobj +1420 0 obj << +/Type /Page +/Contents 1421 0 R +/Resources 1419 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1398 0 R +>> endobj +1422 0 obj << +/D [1420 0 R /XYZ 85.0394 794.5015 null] +>> endobj +454 0 obj << +/D [1420 0 R /XYZ 85.0394 769.5949 null] +>> endobj +1423 0 obj << +/D [1420 0 R /XYZ 85.0394 749.1193 null] +>> endobj +1419 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1426 0 obj << -/Length 3415 +/Length 1106 /Filter /FlateDecode >> stream -xÚ¥ÙrÛFò]_Á·@Uâx.\µOŠ#;J­å¬¬­Ýª$ ŠHH€!@ÉÌ×o_‚$'ërÉÓè¹zº{úš‰†f'*Ém>Is¯bmâÉl}¡'OÐ÷þÂȘi4ŽúöáâÍ;—Nr•'6™<,keJg™™<ÌŠeÕ%¬ £·ïÞݾÿ÷ýõe꣇Ûw—SëèÝí?ozýáÃõýåÔd±‰Þ~ýãÃÍ=w%²Æ··wß1&çæ•EïoÞÝÜßܽ½¹üåᇋ›‡þ,Ãóíð ¿_üô‹žÌáØ?\håò,ž¼À‡V&Ïíd}ác§bï\À¬.>]ü«_pÐKSÇøçm¦â$Èf¹Š÷¯ïË{hØW@›8¥ 0úxßifT’¤(íUž„âÍ@(Æj•ÃB“4ÎUâ¬#©´ÝîYóæ ƒ“L¥Þâö8èxéR PýÑÔ%ãªVúªuµ*¶ÜÝ5Œ,¤oU<—‡‰WæQùyVn:Ñ- ªŽn/M•›U5+ºRöhêÕiª¦Æ¨<Ž-‘×-augóèî¶™Lž5ÔÎ[îlÜYðçºh»rË(>b«°ÅüxF¿~Yw¯}˜‡úè“è“ðñ”6‚äkaªÕ:ª›N°üÝvE=çsîØÛŽûĈøîîÓ?zÔžqƒÕûEeÑí†øvSΪŸµ¶³cZù†’ØàÎð>ñð’Uëͪ\Ãù‹®jj5vRâ°Å‡3;G³¢fÜcɈ][΃»!¦\êÔ eA/¨KG‹f˨§ÕN–aIûI‘U!†tÑ™¹JSêŽÑ"zè)ÃP~Þ”—&ª[ù&u€v]TÀ‡ª®ê'™Éx¾ˆ‹¦¸Ïv?Æk6r–ÔÑÆ0¹ìø›„ m]¬Ëе}FM¥Ñó9Óß¶¤V€‚Òý=¾ìI¢2›¥rq±¹š5õb䮃9HÁ&ÈPÐgç\ô°¬dý][< %€Â£L­ã©}rÌiRi÷4e -3'!’…@]¾0ä *>í¶¤T-ØçÌìgíC(ç¦Ým6ͶkGÅŒ{g Û‚HðK'‹#Ô²ŽˆÜK±¿4ÆàaS õV†ÊŽù7ãMd ¸n[Ôí¢Ü¶²Ób°~¯XÓ1a“¶Ù$› ¡™­vÄÄóõ»Ï,v.è«Y󱯀Ÿ-«•¨EÍR"#v5 ¦j„q,h—êh]t+RMóðü`2ˆ€jÔG„fèõj¼Î[™>kv«9ƒO%­vM¨—ª[†qõtŒÑºU6MøTÆtÔ–±,_„0ìdÞ"Xtšî àIó‘ñ‘ÀŽæ°àX!ÀiR”f»¤e³®>ãD°kàÄKÚư?/º`‰{ѾZà'èRO¢{_¡ép´ò²U÷;·U–Z°Æ°µQ…zÀ>±çåÜô,³lf˜ù‡ GŒê%BË¢e€Å4B¢è§ö‡sŃ;OëΑNã¢bµâ~qq¾teËxæpäÐ!4BO±j›1©²g!O'oÉ› }_+öW÷ŠˆH>S¬û3ÅúìLæuÖ{GÙ;@”D~RgÁObŸ .¸á¥ùŽc+"Ÿ±;Ò!\Ñ! j›Õík?k„ºm]=UÏhAœ7èæΈKˆÛ¡'ôìK±Á¥ší(ìÃoòa8I£q»nÙl+ žË0†„9zÛÞ±ŸOÀóo CðqˆÀa -:%ŒaÿˆP¯øAç´l•aÊf[=KhSÊî¥ÙþÆ»v:.àúIÝ¿{kr“ñÇÀíÊ öÜI"ƒöT+†/éãƒ$éU aãtî¾Oˆ2ZUõ‰PÅvSŒøðÜ)ðÚF|8…VIÆsà -þ&9ñØB SnëbÅ£„¥40°4$gR²û›4Dz¦ÛÒ_\øà‹ëà“bS§™™Ï¼Ê—L†ùÌWæH^;Ä@³3¹&ÙßX´ŸòZâåR§|ÆIäHâElrñÄç6™,!~?^Ší|D–iªR £úÜËû<úÙZÏS$E@$êvðúqlñvz1øM×Úýdä`MÒlÄáêÊ£M9Ù°f3aM=m{jÁo]˹†|&9ŽEVúüìÖ©ô0’¢Ž²Þ€¢¯»ý¦[?Å×ÉÜ×ùë2•¤YÈmÉãêÀžN΂æã|}ˆ“íA.bv§§V¥yœžzéQ0zβL‚x÷M0Gû¹X¥ÖgÇçÁû4Â;¡úÛ®$öZV3´A­zZ„ŠÍ†"e4° £~ߕ۪”ߘØdíñ-GkF<ÒiðÀÙA tïB|Üs·ŒK{Ïœ’¥!MI¢Û… š@l bäæ_áQYÚ‹Ÿx„“ÄÊ; g-9 £‹ƒíFl¼t؈ü†'5·åzÓí\U­ ZŒ -Ï$`Àžü­Êmò¯@ 1òª/@Ì%8’ñ`J\~|¤ÓËì|:8ù)®2/‘1¢ØÅzqû˜ô^q·c zXLƇ–vÖµÜsW„,w/©Ë2ö”’Ÿs晲Yâ…+͆Rıۜ¨¼çs¯ù'1ÄÅ»°Ù‚7Û7;^ -NÊØ>Zñ–¬úpóljüi•©WFögj}.Ézù‡ålYÔOG1% ,!Ь‚# “ûóiœoÁÜ Éǧ -5Æ\i«óžo½òʧùé™(.´ÞBökñÌ’>Ìï¬÷çn{Ñ‹lÛŽ=NîîDQi½±‰˜¼a‡,NŒôs5+y† ÅÕ˜&=î:®­°Ü"³e‰rL*7‰Äîõ õ6 e…§rhÒ±a ©R}lÃÆaÔ RYm±?'É2D?ý=äF_BžÔ€Sý;Q”Lx5ÜÑÐïs÷…:3\@±OJ,¯Ñ}±Îü@¬3Xt¨ºŠx\€ý¿eI4`¥PFC¼‰KHÛ—<)çÄŽCx\¨` ª$ÑG_!¨Mãþà -nr3}©á®ÀúÁ» ª¹¹¤.Ù çO’ˆ†[$œ*…&gjOçÐéGîKOf/´T—oêMI´nÚŽ!©8I©*‡“âáÆIÈ¿êSº©‹SöçØßp?VGþ°ûÅöXRÖJÊ=³UÑÊ Û»+ø8-œ`a±eÑâÌf½©Vå|JÎórQìV£Ivd$;2ƒã× 'Ò,*8qFï-RÇùÌå:‚`Nk†nïd•S7Ü>îªU7åî©…Tq:²ã«†cp'¿ê–ÌFæ ‚IìßX1ÌxÍpX“)¸W¨2èôr8Ì/3 -VåÕ‡§áùçÄ„89dUyoCØMÛ(´\JAˆ³Ê:MÈTe‚žÓí‰QÅNc§ ‹×‹mÑvÛKˆfý#ËŸ?¡ÅõD±¯Þ~üpÅ]w7ønyÅÕ¿÷ïÑ%)î»®ÃOݾp‘Ñ„,K…²z¸ÀÕ3lQÊ#ÆëÍ®Í8r+?ã+ÕÏ!k !>ø°¶Ho}f}ö¿g| ¡ Îú4ÅtìùŽ)/¨:orK~Úä.ºûïw?\ßÞ)F³dš7¥ ¡7šÃé ‚(eì#â -²8ªüL¼7¼Ú˜Xrï?Òð(.w©N‹‡«²„|G_«ç˜¿¨ÔpLì‚_¤b«#‚°ñ‚ˆûœQÄí8(‰Œ?èE3ñ°“Ž“Ø°éiûå°ex±¿ÎVÌÏáý‹ïò0'ÎããgùÿkR (P™ê ò³Ê%¨ðšöªoÓ ‚6ç&ø{ˆ}ÒÃÏ"Ž ò“ãS•¦&éaá?PP ·™œÉˆBhÜF´ð}¤drV¹oZ†Ù%#DµI8o—¿eÀ¢Y­š¾pš2ul nÈÝÒ5ÑäÎO»¬Â®|õГ³2úü:@f )¯ õ -p#fݩ̧!ßAÓ9^*5©Êµ ·TÐ,ÇBMå!4œhL=XZŸÛ“ò@Höà;|<Å$@÷ÞE÷ý³f+·¬;+tŠÕx.Zé[¿Š•&€ô v7så]œõb92€:Ü[–mÕ¼– æ.ÔDrøh^IK¯Â öOìá½¾B¹&ô<4“·ù¯·ßÈ’?rǯl–q)a?’p6ºíŽ 8ÿ1@»,®tg*ÏO“Ö#ÒPG‹GtqdÕŸ‹mÕ¯F…Ü·]¹n¹ßâååÒáO!vX£é2‚Þ2©r7>Çn†o¶T+—•9¢†9ølƒ-þ&bê‘0¿•û—ÁÏþÜ!|ÿiì@Æ)ÿ .Dú(µõ}ÝÔûõ‰Ê±.¨×~ëä¨6öË$øõï ?ƒç²ÌŒáQ4M! -Ϙú3ÊVÖ!>'ýÿÞüendstream +xÚÍXÛnã6}÷WèÑ)@®H‰º OÙÔI³èf[¯û”#Ñ»º-IÇqêþ{)QräKÉNÂ0$ ÉÃ3Ù!‡È²õYă^ˆCË]HlD¬(ØÖ\·] PÝ4@»×ÇÉàÃ¥ã[! =ìY“Y +€v kß=ˆá™F°‡_n.¯¯~ŸŸùîprýåæ `b/¯™·«ñùçÏçã3€‚†?Ÿÿ:M“Wc|¼¾ùÉHBóxt<ºG7£³»É§Áh²Ñ¥­/²R‘ïƒÛ;ÛŠµÚŸ6t€XKýaC†ØJ.q q§‘$ƒ¯ƒß6€­ÖjèAû!bÇà 袖C \Ë'!ôìTüûÇR 8!@†„àVã‡KŒ¬x¦'®¯çñÍ`¢ÍjÛöð9Ϙ±ÑWEKY¦jë š¦T¼-Zˆbà ‚WcM3šÖŸ·QB¥¼3U¬±ÃÒÌ5iãjUÔ#R*FA{[³[Óƒ&I¾ßL¬\#cÁ¤œ¦TEÓ„KeäÚ Õó®&ȳS`Ñ>¬4“3&Þ™í¢ˆõj½¨EžðhÛ°¦ejZ¦b‘4‹ !¼ëc ™ƒ,W|¶ Ï‹iÉ»Æ,r¡6òò£ž¡žàöˆ1šfî³5¢}¥#K#øÃ&ö’Šl=£Ü’'qDEld+&§¹˜fyg:¾µ³ž:2ôìèÓ?@JϨ@’|Þrl‘Þ7;BG”f<Ö.Ÿ/TW$ô*’âi/¤-NíT¾c—µy°§Bo\m M؂ҽ{Nb–ÐzdQžÅ²³Ú5‚ÊÌi*÷ߨjßL¯½÷ôûšÔ$b/)€n+\×ò|èøØÕ8Ðw·‚ù¡j"0ô}ÏjÉ_2Ç[±nØä;Ð!ÿfAÃÍ€@GÏ^Ó$¯Ð$GÒ Äö³<‚©O²úøÃ#ylàJ>4á±Þ«}R<6›CÏ+‘ô?Ó¡Ï?q“Ñz†[¥|Rµïõròî©•>Ò£}ªS«`3­ÀC•„ŽNŠÇ€ }&JŸûOäq„N.zË,RySÕT=T•T%ž™(ÖenJ%o»<Ø©ÂÚ¥cUÜÕÍ'wx§¸“ }do×vЄӫ°ÿkÁˆß³`> endobj 1427 0 obj << /D [1425 0 R /XYZ 56.6929 794.5015 null] >> endobj -466 0 obj << -/D [1425 0 R /XYZ 56.6929 167.2075 null] +458 0 obj << +/D [1425 0 R /XYZ 56.6929 720.2271 null] >> endobj -1428 0 obj << -/D [1425 0 R /XYZ 56.6929 139.8789 null] +1309 0 obj << +/D [1425 0 R /XYZ 56.6929 692.8842 null] >> endobj 1424 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R /F21 702 0 R >> +/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1431 0 obj << -/Length 2969 +1430 0 obj << +/Length 1141 /Filter /FlateDecode >> stream -xÚµ[[sÛ6~÷¯Ð£'jYµÕºÚÚ[ë®§ÈÛbã$í-´ÚŽ]¹Y-q±ç„/ÿ[íÝMÞæüP9 KgÏ:ß›ØCV„ -í¼¹/ìð4‡b]þ1í´BÇsÙ>Ú–Ñ O~ÅÉ 6ÂŒˆs¤úðÑ‚‚2Š˜T™C­·y6[ØPÖŠP”ʲŊIÄ” ´!Í®aŒ{/Á ‡¶¬öMD%Œ°–g’ Aù‰©ã@«!ÊŽ<™y2åÛmõ¼‚á/^ÆÊ 'ˆ+9£Ý£&ÔãFx†x¦Fú?ÅqDºÆ¦hÖuÙ…ÃvTáÕaʵ…±#ÕB!Í@³—û±£Œ0”ŽÚ›õ§…mÜ\öø—c¹ÖåõÑ9C‰L‚A¥ZÏÄÞ£æ ‰¤CÐI¶qH4ÉfØ6@%ØÖ£Žãô婨'È8ExZ¹GMhÉ&à.dÃ@ý[’Í;1æšDŠâÓ\ƒé‚GANrÍág<Žå¾žkÒ¼Ke–½GÍIKs kxå)9õ*Áµ5¦U @ -/Œ¤~š0  [®bÈõÿŒn*¦›óc¤\R$e&N34ÕB®¦×ãgœŽå¾šqK¤¥`éè{ÔŒ!±´$ã„!(3Œ¢N3ΣŽ#ÕÖù¾y€ÅT”à4¢T¥Õ÷  õßGkêK¾ ½)Ï2”IÐ}’oFxšâ[Ÿq:–ûú §’ -Ïß£æ ‰¤¥ù %aPÓ| |ëQÇ‘z:À -¹ˆÙ™KPÖîQêC¾A~cœ†úß’oG/Æl£HaÐ|šm\ a˜“lsø—c¹ß°v3´ÀY:ö5gH$-Í6äÄzŽmT‚m=Êh´#´:TÛr=±zSˆPÊÓê=jBH7f6Î24à£ßÎ56þ¹ýóHüXî[GB£'»ß´×¿u†”½vB а¾Â‘ÇcotÂ`Í7´4E«?ãZ,w’Vtê¥ °ôeé{ÔŒ!±´$­¸â¨Ó´¢NÓÊ£ÆÓ;üç¼Þ”ûOc;(†¸Áö1mˆGMX2tžbDºõÿÉg#‡Æ4' ­ÈÉÜÆ6W8 ¡ÇϸË}ýÊ œÍˆâéqð¨9C"iiB^`ŠÍ‘p€J°GÙ1kªSEK-Íg”{Ô„ö`Ȭ朗ÿ°ß¾@Ø©^îŠ|dyxÚÚërŠoàŒ^¿à?Yõ€å’²ßµvµ;˜Ã -lÛÔ Ñ>ö·ÿ®ö…ÉŠ˜-ï¬)ZÛö[+óõc¹/šþáÜÝ.·În›×…W•O”Ûh&—ª·ÿxÓ•Û „CFâ}QÏÖxo>Ü]_ýgª§¾¯Ç튦É?ÆçŸiXÿV¶Ïög6®çé`ÿ7 67ÞØÇb[6] Ó´÷ùÎõ6Eýµ¨‚?°À®˜jÍ÷#!‡ºÜå¶v`VÖú €¹ËAM ’<Á©óVg½ÐuØ>5¶•ï_lãúW×±ÙØqhš¢±Ï%QƒéJ¢1Å(,»¨ÈŽ9-˜Ñ,,ïK¦x®äò™WÕ­mírgÞ}1²åœ,Á,ºD[·5Ñ-€yæÂʈI*^e­ °¥Ïzk1²ÚªÔýÆõØSýL³¬±< RfEÒ°u›"¸c‚Š™ àõò?m{能 ‰aªœ¬ÊÌÉ@0)f<%HrÁ‡ 2;Àm#È5pm³©›·O÷¶ehÖ¸EÒÝñ¥è¬6½TÿÊ,v‡öÅ6Íl9™Ë™äˆc{:r:—Q§s¹GuùÇbýyefg¯RÊ”žQîQÚÃ# ‰ÉSú;›j8¤·n`.L¦ï©é&ž Xe{ûÚº\·îŽä<ÉkH×̰0Q&ïÈ ˜æeßæÙÎŽAæ¹¢nóÒiÞT;Ûæ6e5Π½Ï?’òQ®µù€,[š ºíž‚ Pû}ån˜tÝ5œ‡jßô¸Aúߨž{&´³WÖEhì‹ö¹ª?wnÊRÌt'\|ÍëÒ°^W¤nIeeUSg@û“•öåP8 -_UõÄÔÊ2„a)Ö¿@¬ï“ç>Ò¢ƒu3#Z-†câÍ-‡çd<äåvjYoEMéô´élR¬÷5ÛüëԚŸ1ö†–ÚvªI¢œ-?5õ‰†,ÉÌÔ S¿G§þî¯hÞSØwjIÓš=jBu¸†ƒÝ©9 t¿ÍæaèÁø-+PÆÕé2/…!‚¨ÀÉÄfÁãgÜåžÚ,h ï2I4KÇÝ£f ‰¥%YF gÆgX6Df™GÇÖº›5líâƒo])Òú=j€0hÈÏJ…¼%׆~Ä D+•8X0»mLW“ ?ãt,÷ÕŒãØT5´LGߣf ‰¥¥' ¾˜ÐÆ P Æõ¨ãH•û¶øT—m¼E…‰‘ X4' ð¨ BÊ)óaˆ -MxKÊŽŒ9GÁ4Á9&aäXàkŠs=~ÆëXî7pŽ£ŒJ™¿GÍKKsÎ|eÂÔç¨çzÔq¨šò~;Që¾åàð -Lª÷¨ ý!ãâTëЀ·9¬Ü/0¤´Ö‰ãóé =M/8üŒÏ±Ü׿U5F”Òtì{МcYI² Ü4­I² Q§ÉæQÝš´¨Í>vÕTùªm·q‚Ã0JD¥ ð¨ Bº¯’‘Є·¡Û„#cÂ)Äxâð¶œ*¸šÌo?ãt,÷øfÎ]OGß£æ ‰¤¥)T:G¹*A¹58βùásó9â\,!ÙŒ5aBÀ9‰‘ÔrdÃÛ¼T§<ô ³L&>€3å>94oî´ËágÜŽå¾þ­ -»1-2Ž¿GÍKK³Î|äÉ2iÖ P Öõ(£±­_Víú°ª‹‡ºh§ìÔeÚš°`œè,ø Þ&ÏMø1ÎsÉÄn•1¶ÁBoèB2Ï9üŒÏ±ÜoÈs°Ôð2Lß£æ ‰¤¥‡a᫲™|‡¨ãz”Ñh>Ÿ¾Ï›øÊá-Ûú¤fšPPj¤2X¬º»û®bÎû²&Ó]AÎvÙ‚%>ÚhïW¶÷Þ¡\Í”» -µ4mUÛ Ìq(÷Àî÷5EóÌñ‘‡ÊÒ¦¾à†64,,ã«Â›Í?þ¹xyvµJÐB¥­›¿°ý©í7ò…=M¢j™»›¹ýcJç¶ÕÅÏe[4‡|]¬6ŶܕîQ¹ìµ˜B=,)ÇpÔnë^ÎÈ–M±oË•;osv~ú-´t©Çêºa ¿³‡]=Úôu‡P¦Ñ<Ý7Å—'ûÛ=°ÒáüpqÈ›nŒ»àÓ“ùõAoF•6Çݾ/‚0q)huj«àÃ/Ižó—Ñ/Ö.WVãœyÔìKÌ'~Â2?ݘ˜]ðßüÿBäøón~lpr¹o -£Þ()Æ–ûŸ’Ħÿýì{endstream +xÚÍX[s£6~÷¯à1îŒ$!@³OÙÔÙf§›m]÷ÉÍxˆ„†Û"ygÝÿ^q1/¾@6ӎǃЧs¾óݦ«Òl +u Íb¤:¢ští^µ}¡ê°ù4¿z?_Kc™ØÔf~ˆºm#mæÍÏ.¹øm6™Ž¦ú™ Ç€šúÙû뛟ËV>.?ß\]øsz1¶Œ³Ùõ盲z:¹šL'7—“1@6Eª?®öt¸ºþuR–>L/>}º˜ŽogG“YíKÓ_¤“Ü‘/£ù­®yÊí#fSíI½è1†µhdP©AȦ&ý1ú½l´]»ø£Ä†ÔÆVjˆt2ƒYšE4 &ƒó10uýÌ Ãä ,SÏ‘øIöäd^ߗߪoI]ÀÈ(}´µÏ –êvü©­è©Rq„ñoÛ¸·º5æÃuŸÎy5©Âm Þ–Ñ\¸Çä‘k¼ #Lî"—ÑÏzeŠÌœX¨ð‚ÀSÉħáÃ@ÉR¾IQ“Ða ¡&5”ÍU:àÏi¸A[¥j@>uô +xo’*#¯£4ä%÷à!žQ'ÏÆkyF;< ¹¼;D^y£ñeɳÕ»Åh`‚ÍÁy,úööþã;ƒ®û8Ba~‰Öq{¦þÕØ¯¾«Û^dj•¶m\_ÃaÒ¸†#º m̬Q¹ÏÙµ¼¾ÔûÞôh÷Lendstream endobj -1430 0 obj << +1429 0 obj << /Type /Page -/Contents 1431 0 R -/Resources 1429 0 R +/Contents 1430 0 R +/Resources 1428 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1423 0 R -/Annots [ 1434 0 R 1435 0 R 1436 0 R 1437 0 R 1438 0 R 1439 0 R 1440 0 R 1441 0 R 1442 0 R 1443 0 R 1444 0 R 1445 0 R 1446 0 R 1447 0 R ] +/Parent 1432 0 R >> endobj -1434 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [312.6233 667.7189 381.2953 679.7785] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> +1431 0 obj << +/D [1429 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1428 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 1435 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [310.4119 636.5559 379.0839 648.6156] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> +/Length 2154 +/Filter /FlateDecode +>> +stream +xÚÕËrÛFò®¯àÚ2Ƙ^å“ìHŽRk%+3—UT*ŠH@€ €¢¹ñþûvOÏ€ Z²T9¤t@OOOwO¿‡â£þø(ŒX”Št§Š…GÓåI0º‡½'ÜÒøŽÈïS½Ÿ¼½ñ(ei$¢ÑxÞã•° Iøh<»ñ"&Ø)p¼?_]\~üõúì4VÞøòç«S_„wqùÏs‚>^Ÿ}útv}êó$äÞ‡Ï~Ÿ_ÓVdy¼¿¼ú0)}Ž0½>¿8¿>¿úp~z;þéä|ÜÝ¥_H¼ÈNnnƒÑ ®ýÓIÀdš„£ ,ÆÓTŒ–'*”,TR:Lqòùä_ÃÞ®9:h?0!#1`@Å{LÀ*SI!oNý(¼yUo²zF‹ß‚0¨Êbûuž×M +Nøwô¹Å[ƒhŸs–†¡à£ë†ÖÒÇîæ«»l6«-nUÕm‡ÇÅížƘ“g>ÿ{†øeÖ´ì£þÜ]sïØ]‘7öÀ×ïQøæ½%€ÛŽù¾Õnà>ß¾ ߿ɿ­³²™ëÚÏg…öó’vÊõr¢ëg{dQ›/_Ìhµžt÷ì=7m—÷ßb¿wáNǦZ×S½sQ¾R='|5,xœ2)â8±XÉÐ0ú‡Ù +YÇѨ‡ß¹â©#ý°@0 ‡Íp §ÿõU«šÆL@Þý5ªŠ@BîÇé ªYÑúßeÖ7ÔIÑU½T×” †ƒîÐõIÓ +Áƒè/2­ˆW‰4íºÑþQónusWÕweõŒ¬úoUj¿i³JO>m<;{fY›M²F?7õöKD^úµž×ºY˜ +ñâ:ó&ü±&m½}­¯c±.Úܧ¦ð´C|!YÊM‚÷.5Þ + mÊôöÎïweæ4¼™YÓtýÉD÷Ûv»Ò{öÝÓÍøoØÔ÷c[ú¤*}¼À÷{D zD¾Ö#âÀ#z¾{R—·‚:ôUƒÑ,»ÑV@äUŽfÏÏP+ôR—--п(sK˜¬œðk“ÝëNÎnD (–*.{r·’þÝIŸ¦`ç•n§Ü„³(ŠùHèÇÏs¡µ„i¸?å¾èÓ¢çÈ£òé\¬,èNì³òÝ|‘H¨X OМ£Ý`rð “”œi ZöÈcÅbž& ÉÆ ´+˜´Ñõ„ä”HR/£µ+:O«Õ– jND­cåž ÈMº=*ÈÓD 6yQ4ÑCyžM +ëó¶¢ïª>å‰W=ä3»‘­ÛEUçØ¨ªl6¦&à‚ô oÙa¼¨D±$’ѨoÝ×9 #ƒ§Ì0Qô]1`O‹(fI¨Ž†@ÌRÉùH€w£8IŒ›"{ÐCˆä6ÎÐ+±¥5 sUâå a2úëëU‘O3Ú§èö»0±L ¨*!Lˆ=Îwœ»b´zÐ ×f@[³X8mé-d^éiîÛj¦b¦¢Díj,AÚBìÙò*ׄXVtZ]þB»¦e ºiº“s{À]È(W,A»ÈZY!Θ€›BÝ +î6›¶Ž‰îÈ[¯ 챜6#—n"‘“Ò™XÊÀûä^˜H`mPú±&;VYIè¬hª! } ¦ÅvÓˆBͤÖ&»×,âQVJ€‡¼÷[ÂÍô<ƒYå yßÍ¢ö@æÌ.MÀÌôP‹Sž/Aݘ{Ô¼E,¼PÆ4ø’)°y‡¡"&pOW†“K8]d彞тª™)D@¶s,`'Û!#™¸›oÍ$+•ÂØ—*´J"Âuˆèyg¸gÆ ò¢Œ…ƒ!høõCl(# +ZC[m6¤ØJ›s~WÈCåÁðmL`6oÖF²a¿' +|y…"2ݵpeã´w|×bhì.yD¡f \¢Ã¤"b6y» èPuÄ?_~$Þ÷¨V¤Þåܲ%^˜á…å†÷įñIýÙ›Áă{¥»{uM†Òv&ÜšX’ 4™¶;X9F(@"xhºF_UU„òfH/™èqR“”°ºdŠÅì’WV€:6ߌ>];†ð¶«[¬ÏQ™;5w§\êØ‹€S_èxM«%T™™Ñ]pHƼœ:–¾ÕÜÏ€ô¬!tª£FëÑŒX]äË|°€–P+m—Çö£R¯Æ„0!7œšÊ `»Ég태ÞUå(\ wT©î-eõ çÌhpW‘d uÙÊ$/`ëÒfÙÌíÌ-í¢Z7 [CïŸÝ7QÓÕÊx°+vøÛ/–X|Ó´´qXÜVujÒ&°ÀŸ ‘ѺÝT~![Ê¿©n¸ÕLzi©í0%º±_Ú 0ý‚QJ^‘ôô—A·eËU¡ßì¦K(×ÝèÑ @“¸ÄUùÄÊ5Âþðr–ÀÃÁŽú‹‘Á ,¦‰Fä0nêÈï-IYÙT»þ¡Ý-S¡8x&ÙL†º ͽ¥þŠ«¼4… Œ>]F")ôÈàí•`A,ÂNû·ß¾@3¨2‘%ß,´í/9KŒ•Ú1à&`¼-- 4ƒgW¼H¿¯M Au"€7¬;ì¦" 8…Ämí@k“ýc6€ÂÐaøHL}ª³ +Âz‰CX6[Èæe3<µ,27üCðl jŠjSX8ŸÓw[­í;bm³ß–A@0yËVò¥+.ÈTqÏ‘Yn _[8%™Ì=öÀèî¯{ (‘àO‹à)˜\ ýç%èï¯þ?ÏîŸ`0`Ãì'º×Ç~Å S 0‘!C^è•X=ú/”û‡¥ê©þ&4Cendstream +endobj +1434 0 obj << +/Type /Page +/Contents 1435 0 R +/Resources 1433 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1432 0 R >> endobj 1436 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [340.2996 605.393 408.9716 617.4526] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> +/D [1434 0 R /XYZ 56.6929 794.5015 null] +>> endobj +462 0 obj << +/D [1434 0 R /XYZ 56.6929 373.8367 null] >> endobj 1437 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [328.1051 574.23 396.7771 586.2897] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> +/D [1434 0 R /XYZ 56.6929 343.7228 null] +>> endobj +466 0 obj << +/D [1434 0 R /XYZ 56.6929 343.7228 null] >> endobj 1438 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [320.3548 543.0671 389.0268 555.1267] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> +/D [1434 0 R /XYZ 56.6929 319.3114 null] >> endobj 1439 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [359.1386 511.9042 427.8106 523.9638] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update_policies) >> +/D [1434 0 R /XYZ 56.6929 319.3114 null] >> endobj 1440 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [429.9426 480.7412 498.6146 492.8008] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> +/D [1434 0 R /XYZ 56.6929 307.3563 null] >> endobj -1441 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [286.0435 315.5214 354.7155 327.581] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1442 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [339.144 284.3584 407.816 296.4181] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> +1433 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 1443 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [336.952 253.1955 405.624 265.2551] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1444 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [322.5463 222.0326 391.2183 234.0922] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> +/Length 3493 +/Filter /FlateDecode +>> +stream +xÚ¥ÙrãÆñ]_Á·@U"vN•'y-­åÊj­RI•íˆEØ$@ ´Ì×§¯Aò‘­-í4z®žîž¾†z¢àŸžd>V6w“4w±WÚOfë 5y†¾ZÆLàépÔ7ïnm:Éã<1Éäq1X+‹U–éÉãüÇèýw×?<Þ<\NWQ_N}¢¢oîî¿eLÎÍûO÷·wþõp}™ºèñîÓ=£nnonîßß\Nuæ5Ì7²ÂnïþqÃЇ‡ë¯.~üþâæ±?Ëð¼ZY<Èo?þ¬&s8ö÷*¶yæ'¯ð¡bçf²¾pÞÆÞY0«‹ÏÿìôÒÔ1þ9“Å>É2Y{íÜÛûò +öÐ$6V}¼ïTk…ød2õÊÅy–ê^*N¤¢]›$#ûA³]Ò²ˆYW_ð +"Ø5pâ%ícXȈŸ]°Ä½è_-ðt©'ѽ¯Pt8ZyYªû@­ÂÛ*K-XcØÇš¨B=`Ÿ‡Øs€rnz–63ÌüÄ#FõŽ¡eÑ2Àb!QôS¹Ã¹üàÎÓºs¤SÛ¨X­¸_\œëcdÙ2ž…9yD#tÐS¬ÚfLªìYÈÓ‰Ç[òfCß׊ýU½""’ÏäU&¯ÎÎô{ÞQe½w½#D)Aä'Uü$öÉà‚¾QŠï8¶"ò»# ¶Yíоö³F¨+ÐÖ¥Ñsõ‚Áyƒnጸ„¸zBǾŒPªÙŽÂ>ü&†4·ë–Ͷ ᥠcH˜£·í–ý|ž·Àx‚ó!"‡Q€(è”0†ý#B½~àÓ°U†)›mõ"¡L)»×fû+ìÚéx¸€ë'Iôpû^ç:ãÛ•칓Dí©0V _ÒÇIÒ«@ÂÆéÜ}Ÿ~UO‘ˆ¸ØnŠžÛ¼¶N¡U’±À,ø‚¿I@Vü¶ȔۺXñ(a) ,MDÉ™”ìþÃfÇͱ¬é¶ô>øâz|@¬cñijæµ 4ƒlæ+S$§, €Ôgª­†Ä5Éþ¢ý”7ó.›ÚØeœDŽå]°øÄå2é,!^/^‹í|DŽi§ +Fõy—syô“1ާHz€HÔ!ìà/ôáØâÍtb$ð›®.´'ºÉÈÁš¤ÕˆÃûÓ/”G›r,ªa­ &Âh=m—zjÀg]˹†LYŽEúüìÆÆéa$De¼E4ZwûM9¶~Šá®•¹oó×fq’f!¯%û‹«{:9 šŽóõ!F6¹ˆÉJ4œš8Í}zê¡G ÀÈ9Ë2YbÝwÁíg}œ—ŸïÒHø·Åggl»’¸kYÍÐþ8´Dèe*6Š’Ñ¸6ŒúmWn«Râ{­=° Òÿ£Ž–Œx¤Òà}³ƒ¨Þ} ø´çn—ö^9%+Cš’Dw A5#,€¸ öÈÍ?Ãgi/~âANâcg­?ÎZò?KÛØwé0ù" MjnËõ¦Û3¸ªZ´žN4Ùÿ)ÂMœ›,ä^bäU_| +˜Kp$íÀ”ØüøH§—Ùºt qòQÝ:e3N¢bD±{uâò1á½âànÇ ’󰘌ï,Áë¬k¹ç4¦î^Ò–eì (ý9$>ç ̳Ød`®™+͆ÒñۜÄyÏç^ó1&N<ÄÄ»°Ù‚7Û7;^ NÈØ>ñ”¬úpóLªÝi…©7Fögj\.‰z÷‡ÑälYÔÏGñ$ *!Ȭ‚ “ûpóyœožÀÜ ÉùS…ãG+£òžo½r±KóÓ3QLhœÌË+ñÊ>ÌíŒsçn{Ñ‹lÛŽ=NînEQi½±‰˜¸a‡,NŒôK5+y† +ÅÕ˜&=í:®«°Ü"³¥‰ptª6‰ÄíõA õ6 e…çrhR^3†Ô©< ¶aã0ꩤ¶ØŸ‰“d"Ÿþ¿î ƒˆ¯ŒLáNªÁ¥þ•J&¼ê(àrû%f¸1¤§)qœF÷‡%æGâœÆzCÕUÄ:øàªìþ ¢i+52BM\BÚ¾ÚIé v½ãBcP#‰>ú +1Õh÷oÖo‹”è« w–¦ÞmPËçj6"¸Z7œ;íªU7åêí©…Tñ9²ãvcp#¿ê’¬FÑŸÓeÅ0ãM»aTk•½a6tÛ,O&3ËL¥ÂƒUùL•áixø9± Žžè¼· ì£MZ®¡ ÄžÙDeª%d§ƒ*AÏén„Äb'‹±Ç†ÅëŶh»í% ³þuå÷_~ÐÁâSBüL¯‹ÞúxÅ]÷7øryÅe¿OÐÅÜw]‡·º}åê¢é3Öeõp}«Ø¢”×# Ö›]7˜qØV~Áç5*œCÊÂA|é9`l‘Þú(Ìú´Ïø¢BœõágŠáçØ»S^PY^熜´ÎmtÿŸo?}¼¾»Í’EhÞ”2„hç2¢”±ˆCD¨Äâ¨ò ñ^ójc6`Él¼qü:À“øsÜ¥:­®Êbò }«£ÿ¤Nà ÐÞ¯HUVKq{ˆ½ñ[s¹Ë ‘Á… 8ÆËÏ8é8} ;žf¯GËY9³ ÅQ°kE0Tl̆FÊdŒ\|Kã$wô.ÎÛç ƒò~üt8LÆqH|¶.Rµ‹=áñ" Á0ØKsDÑÙK}?j„Ž£ˆûl5~C·Õ+øu†õ`«¿6øÃŸ/ÀŸûã_/ü_“@AœA²‹–U†œ<ç¨ÂÉ«$i+«ßløa†v´“Cñ÷þƒË¬Àò‘Û¹< ¤OŸä‡˜Rç|=ÿÖ2ÌÁ BTÀE€LLøûI,šÕªye㤨¤mÁ &dR>§] VaW6WjéÍ72úÜt@ +çF‡Â#ÐÆ™KCbˆnf¼ž¬Ó8W&¼ßQÕ· ÊÖÑTzXPsF6uà•@Ïý±= Y1œ`‡/̘-©Þ«¾ÖlÅ(ugÕ`1$/E+}ëâñ(ÃL™^¶T(Í}/æ‘#¨|`Ͳl«æ­”9·!†Éá/ *iééœÁþwáG †ëàAoh3ùÃÀèÂ×ǻǿɒ?pÇ/lÅq¹s¿$±&ºëŽ 8ÿÅD»,aÇÔgqž²{‘Ì4ÔÑâ Ãò€/Ŷj(®A…Ü·]¹n¹,Ÿäy×âïEvX<¤é2‚|©’\>Çn†o¶ô  +sîsðm [üáÈÔY-É`~-÷¯ƒßnüþ+ÈwŸÇnX ç³AôQ öuSï×'*Ǻ¿õ‹0KC=æàOXüÕ?;ü–®œÍ2ó† V3P…§Lý™±Yì3“Žÿ?EØ endstream +endobj +1442 0 obj << +/Type /Page +/Contents 1443 0 R +/Resources 1441 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1432 0 R +/Annots [ 1445 0 R ] >> endobj 1445 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [331.4327 190.8696 400.1047 202.9292] +/Rect [280.2146 205.1117 375.7455 217.8489] /Subtype /Link -/A << /S /GoTo /D (boolean_options) >> +/A << /S /GoTo /D (root_delegation_only) >> >> endobj -1446 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [361.2812 159.7067 429.9532 171.7663] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1447 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [330.3165 128.5437 398.9885 140.6034] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1432 0 obj << -/D [1430 0 R /XYZ 85.0394 794.5015 null] +1444 0 obj << +/D [1442 0 R /XYZ 85.0394 794.5015 null] >> endobj 470 0 obj << -/D [1430 0 R /XYZ 85.0394 726.6924 null] +/D [1442 0 R /XYZ 85.0394 162.5022 null] >> endobj -1433 0 obj << -/D [1430 0 R /XYZ 85.0394 700.1172 null] +1446 0 obj << +/D [1442 0 R /XYZ 85.0394 137.1661 null] >> endobj -1429 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R /F21 702 0 R >> +1441 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1450 0 obj << -/Length 3050 +/Length 2962 /Filter /FlateDecode >> stream -xÚµZ[sÛ¶~÷¯Ðô¥òL…q{LS;ÇÓ¤Çq§iú@‹”Íš"uD*®óëÏâFñ -6§éd2†€Ø]àÛÅâ‚WüÃ+ÆWD­„Š‹0[m÷ÑêÚÞ\`‡ÙxЦ‹úîîâÛk*V -)Nøên×éK¢HJ¼ºK[sDÐ%ô­_¿{{}óæçÛW—"^ßݼ{{¹!,Z_ßüûÊ–ÞܾúñÇW·—,^¿þ׫Ÿî®nmw}|wóö{[£ìŸ™No¯®¯n¯Þ¾¾ºüý«»Ö–®½8¢Úÿ^üö{´JÁì."D•d«gø!¬Yí/bF‹)õ5ÅÅû‹ÿ´vZͧ“ã‡#D('Hhg%FL)¶L!N¡IàÝc6Åxf»äT4öG^k˾½Žeç{NÅ‘¡úïŽ÷ÍWÕ“B’R(‡úF÷GýÀBÏêëK¼®m¹Lšü£Ÿ—›}¶¯Ž/öçñËu–nî‹dû´iìO¯iÒ$÷IÁ¤ÑH€¹é/j¬Ê¼œªÑŠ®6ŠÀK¾Ú`ŒcĨØ$O™ÖĈy8í³²©‘ù$¬³±4ØwÍcv±4^LŠ“@)uf¶áPÕu~_d¶)ßÙÚ$Mó&¯Ê¤°õg]ukz„8ºÞ“®ú>ËJ[WäåS–ÚÚ¼l*[Û<:`á{MRÃd¼~_í³Öc¬õ—:Ù -gn+ôl»kÉËmqJµ<ýë9omÉÈ3ŸæusÌïOÚ"[e[(«2›èÒ`»wß¼¸Þ,õÐÈ›0ó— aíÓì· MeÉ'¢G‹Ò£‘æ0‰‡¡XÉÀó XšÛõ>Ç@‘žØ÷Y6ϬÞóÃy8«s­® J ˆ€KFå2)ø)Ès0ì}èÓ3Ð6V¶pÛ1µÅ/Ø:î×»=›¥Ã5æT‚˜.1‘á1oQKŠŒzÓŠÌÓ b¬<^ W —G™ÊŠì!ÑÖoª²xÊ É‚-jBƒ®Ñ0òˆ:PÁ†wÅ×¢ˆ&ºÌÖFS›EnÂ$üÐQEÿ}„cI™Úªº9ÝÛÒ'poˆ›8ë›kÍz/ L ¡åãKVOp ¤(‘çUCGvpÒ©æÍød£ Èz΋ÂQÔNó{óàc…"%å ÐÛx”4>%.öémþº–û˜h;Ö%ï¦ý µNürp^¬•›g¬Ò–ò–uP–y”6kWŸ“c:”«("„±°\šÛ‹b‘ˆË¾Üwf(eë}–”yù°;nÚÙz·<17kºé1©mUbÿXåõ¼¤ný‹a©¨³ŒÅ†¾ã8cDÄ}&â}kŽ ì@f¹¶2·É©Îœ¬VÅ¢ªž šZ½+Û¸KòŠ@Çô •ì $8¾Àè2vd…Ê¡qºÑº4>dMÓ~RV¶2)ëg»ŽëÄIðõóc^LF\Jê¬ï&Ǻ™“8úQx®N…“ŸEõìt²5euÜëôDWùá0¶U¶Î{p0ïʳt–ýŒ1 &4Ï}êP_î0¶F°>GÀìà4–Ü‹M`f,þ]Ñ?×&Š`a‡渂d꘧™«}tÍf[ªvøPT÷fœ¡®O¤Ã˜²qs÷¡‰GÑy¬©¨Ù6×sîu0 ûÓEÉV¦°AjL# -[A`ë CÉ0§€‘¢„·ñÙV%ˆì¼Ÿa–.dv,³4ïÖ´Í5H…>óÇ2´µ#§3$“-Me¯v˜ n`$&ˆ°X-P²ƒ -pÒ£LÂõçÎh³1éý0*sDUaé4!½ÇË#W¤/þ—KEÌʆa‘<–b†è»Ó%i4}õOé݋ýaF\·–É>³UšI&(!Z%.¹ÓØ¢z°-"ýQްÙ"ö•)\¯fÖueúò­Sö›"c`Ó%(}jYBÀîææ×ë[d‹ngÉí–*òˆc† µ­°ìáž1¶²íj ‚Ä@®OÛfø5^W7:7áµ3Ïâ¼iºÁìi´€Ã!+óáçBb—u  ªòþ‡¼_¹Ú^€ý£,'#ÆúL5ðgŒÝ[̹œµdÖgb;±Æ»¨yŸiQ=Ÿiö‡ÎaD‡±1[P¢EMhÑéIÂj´¾cË"eZmÍ™€Ï«ÎFÍïeÏGGRŸKàh}Ó1ƒªù‘& ²—H.Œti2,rÄîy’:MÊõ  ¹½l1†ý‡Šûr_¹tCz'’¤sä$[úº¶?- ikø,MbþºÕ6ÍJ½‰˜ÛéHÜïÕ¬8úsߪ¹>'ÃtØðy±Pªï€s>Œ`LbïÁÓ^ -¹¨ÒçC/µQB¯R†2î(«»Ñ´mrïÏlü«7Ñ8ˆóØë°Oj—N ¨ób¯CàD_ -Öá5­ }5aƒðL½@·'œ¡2•1)‚F5OåeíüsãX³©óOãˆ;âˆ-(àA -ôw×EÆ¥§Á—9È™²c ^H$³G:&ø%z¶ŽtZü‚Ùã~gt¢‘NÆ³ðø·¨%MF½Ït((dÄ ¤ë ¤ó(?Y&óÙenÅÊ÷Ùf<#ö¨L†õp˜ 5zÔƒ]ã˜öõørÔ›³fÕ!)Õëä,y„0Ã}“CôøóÇýÎQP UÒûI1 ÏB‹ZPdÜ[˜°óŽ÷]T€59gyZL2VX~YX“5¡JŸ… ¥§¡«Ë?ÄÂŽECRÄ#IæYÈbÄ1=£C,ôøóÇý~ 1"Šð<´¨EƽYH¤DB.„Áhžƒ46ªS3Ž‚°2`…ƒz´ ±"=r « 0µ«É?=»n…¹š§ €¢QÏæ=š“䣈Æ*¬G +ÒQõ5ù{äSÁè7M>¥¯RÚì|jf0`¸kqp ¶è°éÃ>?ƒxRí°ñoAa%F}…‰K5añó:¨õ<Ên6úŒl¸yŽõ…« ‹õ  ±½Gzÿ¥Ý¼+öËí¬üp†!Ãâ¶×æ±¶­ÐWXºìnRà+m®©j?ÿ˜Íí69‹4W1€®ó‡2Ù¸³gˆ 1¾]9ï´ˆ½ÍÓ¿ûþýÕk[Ö}‰ÕÃAŸí#bÞ:¼ØÒùº”èk»$õßÙ[˜jo¥yýdY¶×lP©\[åØëVb ܽœ•IÎJO¼Dô. Åî{ûWxÝð`§k–¿B "øBÚ×ͳ׃üñö¦n`Úê&ߎŸÀF\r,‚Ò[ÐX|/Lê+ˆ¦]ñ7»‰GUJ¿õ’ÿד*ÿf˼5åóSª§,;ø_ÎÞÄ5ååN¿qÜ… -Kló8+¯Ï¯³Œ ©®lmí6)ÛçYæozÚ²Ô²¶µ2ŠpŸÝËˉ·/B?Çðéêyb:‡Ã”CATh¿H3 ,‡×r-ÉÚ¡9¿2@s½)C3¯á¿óß¿ýüüB>ˆJ9—à C©WJÛ*øØWÜkñ±êÿ×è"Rendstream +xÚµ[[sÛ6~÷¯Ð£ÿÞ®Qæ³õ€Q„õ·DŽ!¬é°ôsÏ¡Xëð®…rGiEÇh•*Ä!óÆcìPS†Ò¢´âŠ# `§UužV5œþ 8ã?gÕºØG…1‹âP#–x“ ŒBß­ÿO>84rL©:ŸÛ8¦ Âs:BB‡Ÿp?”ûêÜ`8Ô’4>5eH -NBÁt)eŠ„=T„„ÊŒY]ž«‚`û\Xú¢ÊjD»?äÚï÷Ûˆ:Mç»<ÛW6Ç­ù\ŒÑM‰~=ãlÙƒBSÈŽ•mñ$f0ÆßrÓ65h4OÝã¿Ë}®“"fóå“…Õyc@~ce¶z*öyݽœÙçÏÅÖÚmÒï*wª²‘zMâRQkáOwm¹ "1’˜wU=Sä½»_ÞÞüg¬§ ð¤;ÿìòºÎ>çÚëŸnÿV­¦ÏôhgÖ¶çx0µ››ioÌë±-궆©Ûûlg{ë¼ú–WVÁ',°­¦šW³ý@È¡*v™)@¶¶Ö{Ì]j*Dà N­Ð028ëÜ€®ÃöX›V¶1ÛßlÇzmÆ¡®óÚ¼çÕD5¦­‰†£°ë¢"9 ¼é1œÄ0‡ïjºŒ®äüÊšWVií2kÞc>°å’ÌÁƒ úüÓ‡)ÜêèæÀ¼sacÄ$¯²VPÄhÒYÛ‹‘ÑДݠî×¶Ç œêfšaá™÷’Ò’v„ÓXWÁ-TÈ«Ë&;n;èÆ<…Ä0VN†Õ:ÑWÞ¤˜ð"¼Ÿ ±Ü4¼\ŸM6Ð…óæøhZšfµÝ#-Ok¢µZ褺3ßšÓÔ³ål*g’#ŽÍõÈùTÞGOåÕVäŸòÕ—…žu¸I8¡Ü¡F´û›T LbõK“j8¤»m`6LºïX·O¬4=–}MU¬ûÄLò<É*H×-ô°äéÏZfB£~Ù7Ù_æiKýR^5YaÕ®Ëis“¯jkÍÞ%Iù Ñšä@–ÌõìܶoÁPû®´t®nÖüC¹¯;\/÷¯MÏÆÜíÌ'ã4öyó\V_Ú{7eø¥»O³>|˪°Z•­¤v;ed•c7@»k•æå[þÞ”ÕȼJ„aÖ­Æ÷ÑKŸr¢…µÓ"Ø)ú³bdÙÖEÒmö6Y±ÛÂ’˜’^.=o:›ë¾z›};>SØÜ3ÆÞÐrØÏŽÕ!)C”Ó“åçæ=lù&æ}™÷ê4ïw §)R«¸â4¢ØÌuyŸøšß¦ìÖ·¸À +”pu¾ÄK…^÷|Œ•@:ü„»¡ÜsÇœUwL×*¢aw¨ CBiQŽQ¥À(>Á±>ê<Çê4F°Í]¯àP7v©À1‰«ï@#ê‡W +LA—§ÿm¨¡á•B[G?¥1„#ˆçiôJÁâ'œ從oRÁY‚±xðjÊ@ZœoBWQ à[á[‡:T±oòÏUÑ„GS=-°ˆëï@#ú}ÂaDUÂ|Þ’pžCÆDpäÚ6Æ(ÁDy®F¯,~ÂëPîw0ž(ÂâÑw¨)CiqÆéûÈŒë¡"ŒëP§¡ª‹ÇíX N…SWïP#úýý3CX1áð–‹iÏá¥C*MÓÈ¥‚€˜ÏÓ襂ÅOøÊ}=ß‚”cïP†„Ò¢|#)G‰§µ>ê<ßªÝæ•>Á.ê2[4Í6Ìp ب5bÏ8‰„>û{&¼ ãFrNÁ±’‘HŽã0¨ð|æ8‹Ÿð:”û9#™4~‡š2$çLRIb‚s=T„sªw‘erÄ—úK@:ç$°À¡FLðHÇ)âlx›…uÌ“zDzDF.ëC)°²ïDôšËÀ'œ¤¾šrc”دDƒïPv„Òâ”Ó_îÔßi‰S®‡ŠP®CiMõ²hV‡E•oª¼~ +Ó\{½Nã8Ôˆ~šK ­ß„·Is#Ž ÓœD§¯ÇŽe9 +PØgö}ˆf9‹Ÿp:”û++l¹Pñè;Ô”!´8å0l}U2ñÍÞ>*B¹¥5ê/N?fup±&H08ÓGw Å~=D—ë¹ô5·÷ôm¡œwÕL–¶¥8ÓeJ•ød¡y^šÞG‹²¥Rn ÓR7eeJN0ÇÝ]<×ÛëÜUõ;§W6¥¾šõ$Œ}qÚDP¿¤Øæ0Ç0Øîân‚|É_žm•´PiJ¿ú/*óÝøÜ\"Q5ÏìÃÌüÑsÓjc€ç§¢ÉëC¶Êë|[ì +ûªœwZt}^pj=†ºh[ur¶¬ó}S,ì5›µÛóÓ}½"•6Q@ã4Pm7 ä殢­Dë¾öîI7êãc=šß ¤=+-Î}/>²ºãöø|Ô¿:èÌ(ãæØÇ¹_ +&6 ¢NMý»ÿý‘çìeð‹•Í”å0cž4»âò™_0ôO6F&ü·ÿÇ¿ 9ýl†ëßœ=uèr†!Ö(™„Éþ„$4ý—Qëendstream endobj 1449 0 obj << /Type /Page /Contents 1450 0 R /Resources 1448 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1423 0 R -/Annots [ 1452 0 R 1453 0 R 1454 0 R 1455 0 R 1456 0 R 1457 0 R 1458 0 R 1459 0 R 1460 0 R ] ->> endobj -1452 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [231.137 681.3376 299.809 693.3972] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> +/Parent 1432 0 R +/Annots [ 1453 0 R 1454 0 R 1455 0 R 1456 0 R 1457 0 R 1458 0 R 1459 0 R 1460 0 R 1461 0 R 1462 0 R 1463 0 R 1464 0 R 1465 0 R 1466 0 R ] >> endobj 1453 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [324.1075 378.783 397.7608 390.8427] +/Rect [284.2769 667.7189 352.9489 679.7785] /Subtype /Link -/A << /S /GoTo /D (server_resource_limits) >> +/A << /S /GoTo /D (access_control) >> >> endobj 1454 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [359.1555 347.5161 427.8275 359.5757] +/Rect [282.0654 636.5559 350.7374 648.6156] /Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> +/A << /S /GoTo /D (access_control) >> >> endobj 1455 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [353.6164 316.2492 422.2884 328.3088] +/Rect [311.9531 605.393 380.6251 617.4526] /Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> +/A << /S /GoTo /D (access_control) >> >> endobj 1456 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [370.2338 284.9823 438.9058 297.0419] +/Rect [299.7586 574.23 368.4306 586.2897] /Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> +/A << /S /GoTo /D (access_control) >> >> endobj 1457 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [364.6948 253.7154 433.3668 265.775] +/Rect [292.0084 543.0671 360.6804 555.1267] /Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> +/A << /S /GoTo /D (access_control) >> >> endobj 1458 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [226.7331 222.4485 295.4051 234.5081] +/Rect [330.7921 511.9042 399.4641 523.9638] /Subtype /Link -/A << /S /GoTo /D (boolean_options) >> +/A << /S /GoTo /D (dynamic_update_policies) >> >> endobj 1459 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [283.1811 191.1815 356.8344 203.2412] +/Rect [401.5962 480.7412 470.2682 492.8008] /Subtype /Link -/A << /S /GoTo /D (tuning) >> +/A << /S /GoTo /D (access_control) >> >> endobj 1460 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [287.6042 159.9146 356.2762 171.9743] +/Rect [257.6971 315.5214 326.3691 327.581] +/Subtype /Link +/A << /S /GoTo /D (boolean_options) >> +>> endobj +1461 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [310.7975 284.3584 379.4695 296.4181] +/Subtype /Link +/A << /S /GoTo /D (boolean_options) >> +>> endobj +1462 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [308.6055 253.1955 377.2775 265.2551] +/Subtype /Link +/A << /S /GoTo /D (boolean_options) >> +>> endobj +1463 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [294.1999 222.0326 362.8719 234.0922] +/Subtype /Link +/A << /S /GoTo /D (boolean_options) >> +>> endobj +1464 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [303.0862 190.8696 371.7582 202.9292] +/Subtype /Link +/A << /S /GoTo /D (boolean_options) >> +>> endobj +1465 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [332.9347 159.7067 401.6067 171.7663] +/Subtype /Link +/A << /S /GoTo /D (boolean_options) >> +>> endobj +1466 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [301.97 128.5437 370.642 140.6034] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 1451 0 obj << /D [1449 0 R /XYZ 56.6929 794.5015 null] >> endobj +474 0 obj << +/D [1449 0 R /XYZ 56.6929 726.6924 null] +>> endobj +1452 0 obj << +/D [1449 0 R /XYZ 56.6929 700.1172 null] +>> endobj 1448 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F48 940 0 R /F21 702 0 R /F41 925 0 R >> +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1463 0 obj << -/Length 2955 +1469 0 obj << +/Length 3111 /Filter /FlateDecode >> stream -xÚµ[Msã6½ûWè(WEX|¬=MϬS›IÖqjI‰²Y‘H‡¤<Ñþúm D$¨©8•J‰Ÿ¯»€njLVþ#+-f _©„#‰Xm7xõÏ>܇Ùt MõõãÍ?Þ3µJP"©\=î{¶4ÂZ“Õãî—õ7ÿz÷ããÝÃí† -¼–èv#$^}ÿñ[;’Øo~øøþþÃÏïn_?ÞÿðÑ?ܽ¿{¸ûøÍÝí†hAàûÔY˜ùÂûûßÙ«ï¾ÿþÝÃíoßÝÜ=z_úþÌŒ#Üüò^íÀíïn0b‰«ÏpƒIº:ÞpÁàŒu#‡›Ÿnþã öž¶_Š Êåj`"ŸŽ2FX@Ô6ŠÄ\uQ¦d*ÊÊD¹ÎŸ6¯é!ßåÍy“MVÁÝØw¢RZÓU‚€†GMð`=ø*™ˆ!‘Ÿ²ÌÆ¿yv»¬ÞVùK“—…(÷†ØÈ«D!L¹ -QwF†( -ö[y1ö˜iŠ(%jà±}X=­ìÅCÏw_ð=´k}ß^¼4R%1ædáñ,xÔ“Кa‚Ù;m)BÌÒLØCEØ¡ºŒÁÿE^ÞJž Iü5ñ%=ñ®Œæ×uæ¿1!<É'tèmLx~ÁïÐîAâãñ xÔ“ÐZTx.4Kd\x}Ô¼ðj^YÕ.é?÷¶ÒÙWåq³Ë÷檟¬ØNýz§ÐEéxÔŸa_!Çtȧ -“ -…I>Šy2¹³L Šœt;Õ’[ak µ†#l×}—¢­…Ã/Ä ´;P£q·ScØZÀ kÑdxÔ‘КÕãF -¾þ ü±l|fÒÆ¦Æä(Lņ àLÌ&Oì‚^›8™g•VÔeä˜Ö ”äaâ`W†é:XZì&,¨O…ïëCú:U`1 -uŽ/è·Ïenxµ›gÚw'-œšnô5Í駃O›Ñ‘ü¿²pW‡ì5; ˆ"™]ß ÂÏéBµÒGEÖw‡2~üž!Öª¬ÎSÕqB1OïQó«ãC±0 ð6¥JàÆ¸:f<¢"Õ1EÐ7Ò§ÑêØá|íÎÔ)á‰kÞ½0½G-ѬÅO,N–ÄvE´æ@í=š|sY©C¥1$µÖÑ©=(œ{ 3®‘T˜ &›wcÆ*#\LæUF E1{è…~Lc÷vlsöÇPa) Mm,ä´@bl+*/ª’œ-üÔGÍ Ì£.§À¯ÓC¶Ù—ÕöÜàí;hˆBŸ%áQ,†ÝH Ã6 ñ6[ÚŒ3ãwïa%"’ªMHߘæ|ÁïÀê—üÎ åµXJ€G- ­yåUçHnŽ)ŽuŒáI%âPÙcŒ×ßž‹ô˜o­?¿ìÒÆeðÇòoóÉÚI¨TµuŒû7£\¶ÿf>êÓËKY5¦VàP}.ípz€ôi“¿fvà˜5Ïå®¶7 öó©J‹&¿%ëâÉlyV4eUþôܸ±ÒNô’UF5vpçý‚›SëW݇ã™ñ¥_“™Å5ˆÛ²0Z|:ÙZggG?/JŸ*ºMш//óåç}æ öº/Õ†ÛR­û¥ÓšÚ¼˜ÜLžúZ(Ö•le»þœ;Ö‹úÅhНó-!ÄêÆd“ºEbZD÷{öã´‹ RL\é`[„tuæöžjS2cµþ\V¿×öÒö5pQ§Çîiz¶©Ãä¦ôÇrýb½xÍË“{òšU58é̧‘$²—÷ýluå`OÂ^vêjã ‚ ŽÊt¿§¾Žy]ûß - >O½U“ç~¸·eû¹ó{àT´›«¼˜¨•‘WèrV4Jß\!è3“Q^(cë¼¶ŸEöÙ bŒv‹Fûaäj/ŒÜ׎¥o àÎ,Ÿ"Û@äó"shXUM‹)Öp ´>·m”¹º¬Wcß™´âÀ“a†ZÙÎ$œ²õ;@±®³¶ýà.ê2¢×§ƒí`„uFÍ‚È Ñl×. 4`óÉ. ŽXgéöy`à ç­Ê>èÔÕNXÙ绬È37vÑŽØw(×]¾æc8Øžlò`Œ-¬ú4_Êì½ÙÎ ží 5n.*û — Íb“7ÀbÇ _ßï-ÌÊ—mÔOaÖ̧¬nìC V§OîiîHš¶f9‰¶gn;å‰m7¯Ý.•7ÝzØN»®Ý¼Dýxüéþƒ[Uî ˜)pÛUN¬A3þÕh•¹œ‡ëÓ?né;óÛÔ-ÑO¾ÄiLR #¼‰uúà´&U¯[†›žàÌ€´+Lª¹…0„¥¯‘®XÙŠ“îHq 7¿Џ¥;$pq8Ûác–šl¸?ì½Õªy`û€nlÙ0IÖÿ}Î -»>‰Òp¦µ'Éh pÍüŠŽÅõž%Ltèºð’g´%ÞTw>ÔðÀøš+¨"µ·—Ã=u% f•Ý™*{kÝÖs™¡ -wrõAH¤œæn²2ºjCÈ´ù3:\ø=ÇLÌ•š9(û÷µ$*™à¥h§ÅÖÙŸ©ÑymÇíê€a¿: xoÇR{ë6ƒöwóÒSÛÌÂÒÝÎùU[@îæ0¯”¬ž(ƒƒ-¡C=Ù/²×Ô„cæ‰rl²Éƒÿ±¿üGF—¿Àâ -1óÇ9ÓíÔ…š&ª#eœPÁ5PÖ#¡©š þ4A‘endstream +xÚµ[[sÛ6~÷¯Ðô¥òL… ®iêtÝÙ&]ÇÝ™¶´DÙl(R+Rq_¿Wñ +¶Ût2Àœs€ï\ƒW üÃ+ÉP’*ºŠ"–`¶Ú®’Õ#”}w…fãA›.ê›û«¯ß¤b¥â„¯î÷¶$J¤Ä«ûÝÏë×ÿxõãýÍÝõ†°dÍÑõ†ñdýÍíÛom޲?¯ß½}sûÝOw¯®]ßß¾{k³ïnÞÜÜݼ}}s½Á’a¨O\ 3ÞÜþ󯦾»{õïÿþêæ>ØÒµ'©6ä¿W?ÿš¬v`ö÷W J•d«gøHVЬW”¥ˆÑ4õ9åÕû«…;¥¦êTÿ±T"&‰˜è@’v:'¦|%˜B<…"Ý÷O9XDñz—ï³sÙڢі}ý†ÊN}NPŠBuÅ/NíÕ“B’R(‡úJ·—ú–Õ—×xÝØt•µÅG'¾¨6‡üPŸ^ìçéËu¾Û<”Ùö浟^ӬͲ&‡±J¦½$8X{9u«]m>–|µÁ)ƈQ±Í>ävP3#æñ|È«¶A¦JX‰ˆb¶·ÞµOù Ħtý1+ÏZ@š¦®bn ŽuÓen‹Š½ÍÍv»¢-ê*+mþEW]º;AGœ\kOÙG—ýç•Í+‹êC¾³¹EÕÖ6·}rÀ&?A}MVC`¼~_ò`@ÇØ&;Kgnz±Ý•Õ¶<ï´<ýõ\´O6e䙪EÓžŠ‡³¶Èæ@Ú&ªºÊ'šôØæ]ך¥yS‚ŽÎ¥@Xp<=hÓEYòã‰èPº7v âq(cŠ$.7 &÷¼ƒCh×íI~ŸçÃ.Í›í©8^z´Þ;ïêš¡JõÞuÑ 4Wå Ó ¿&ž *”è™h O+›¸ëð ÆŽÛµÆn/fé ‹9ÂC•R5˜Zèõ€ZPdÜšVdžaŒ#E_`Xa˜G™ÊËü1ÓÖoêª|QMc¥ŠË÷  ù=¢qðs‘ °ñ]ñõ/I’f:ÍÖF“›eaâ$|è°¢Ÿ ÂX`VílVÓžlêø7Ç ¥b}»w¥¹ÃC ãyƒ¤ +aйcãKÞL0 ¤R"/Ó†íà•SÍ›ñɆõ\”¥3¢lœæ6èAe…%å ÒÛ€”µ>e.øé m~] +|P´ ë”wÒþpZ~9:ÖÊMÎÁÝ·Û³¶ qpÈ‘BWÉæZޏ`K~ð›n…17Çíj­NuÝnJ8T\ô4Q4 &ôèLJakQ·dŠ#Jè‚[vQónPZâ¾>=g§Ý¨û FL`P’{”ƒµ[Oô;Û4eëCžUEõ¸?—n^ßÛ|7«3Çu]ô”56+³?VÍæ[6P˜a›ÖÌþÔ8ýxîÊ!‘p¿€ó£=¢I,°™UŽ•¹ÍÎMîd˺þ3Õ»¶…û¬(­…N1î»a¶oõ"ŠpÓ ô€Ncçâ94NÚ@…yÛ†*Um3³ªy¶Ë½Þ|ýüT”Ó]€àÖ:ˆ‰äÔ´S½`ÖÛ¾žëséägeY?;lNUŸzU§³|wÛj›çcö-œcR‘ïæ€D8lƒâÐAEÀ£: ûwè)E”‹Šö  Ñ=€È/Sí]Ù?5&þba»ƹ†uè©Øå.÷É%4£mªÞ[àcY?˜¾†¼>Mž”‘ °pM$ˆÞ˜Œæ˜o =î^³Df?Ýüd +ÞÇTJa%'Ž"ˆ2\Š@H 3›!…Ø€)žaaåf›Ži–ë9iÖ×€¬!?]ÖÞÕnPºN/-Í2sjåoû àëZ&.§e¡¥G™•êï{£ÍÆlFÑ™Bü‚]uT|@MÈïGgØC¤ë+ðïkE̲à +ãlˆŠ5$Ñ9v«SÒhëOC«ý‹ý0}®K«ìÛ,M¦N$N´2·.ÖØ²~´%¿$,ù­>Ÿ`«Iì3RºV͸ëÌÝ (¶NÙ#l)]¨-‡H™„]C ØÞþçͲI°¶ãßÚeŠGˆh†Ͱâž663´¶"ÁÂJ®ÏÛvXÁÚ¯³Œ3]ŠðÚYhqÞ:]`6…ZÀñ˜WŽþðù !Ô­-»,¢„ ΔÔÈ{—ËíuÀoU¹¸ð4b¬ãÔrÆØÙœßYKf‡R›AØ4F§‹šwœ€ê9N{8n\w݇ê&² D@MhÑë6(…Uå@à>6¹PRíê­9TñëÍõ‡—C;©vp²¾ DÜÍAÕ|Oc†8å 3géi2,rÄÀrŸÂ/*8 &$÷ƒSŠaª/ú•[{HïG’tŽídpª/ûiyàx XCiiV$æ×M»»¼Òû¹„¹Í¢ÄýVÍÌ£«ûRM÷9æ°È!0A(Õ÷Á97† .ö«24í¨Ð% +Ãövè¨6PèÙʰÆvwqz»Íü¹—ߤöwHT Ωoþ5z‘:y²¢.³¾Ž‚m)Ñ×›Ó”úϩ̖!óRÄI"ÌÝô1ùÅ’(ï:jø°Í?Î9ªï%%õ}ÀDU¶e¬Z`#¨b^5ϸ€šõ¹‘NRD9ãqUjB—>ñz gO™¿‰z]“F×ͰîÃ\Í“O)Äg=³côóø…·ûÇ)«²4´ Æ¨­8 A4U $¼€"t ùP1IAŒ¸âq=h¬HŸ€úl_ô5ù›&Ý®=ÃØ§oÐB‡ Ö59Ê>?jõOp/A‹èxL\‡aKqâPGÊ¥ð×AE¨çQö0³Õ'b£}2ÝX—P‚û—ëB3’÷%®]ôqãÇùüå:ã(LöLŒ]®{ü‚±ãvÿÄå:ô'[êõ€ZPdÜZ”aXÁD;¿(Á: y~yÐexôõeö2uÔ¥R•FEÐXöð K‘„÷„N†]LHf¥z­<ÀÀI:úǘ‡Çíµ:K26^MR åÑn 5†mÅ)Æõ½žXb]T„dÕ¢¶Þ4u6¦ìfX"ãâjB~Ÿh6 ÷ø<ë¶‘Ù0að„àÕ¸~:¨z–F¹æð 6Ûýã! öö\ŸD;? –µç[Šaf]8\î€"ls -îx~øO̘P+ @c©ýseФT²'öV÷´ þXRò+ÊlÎP!'œØCú9s™EÕš“WýÅÜu$d»»0wKOí=9ÕÖ•ú²J§Ý… ÔÒ›¬Pýc~2´Ûì"Òܸº)«lãΗ)P'>ñ9_®®ˆ½·Ó¿ß¾}ÿþæµMë6ŒÎÄêá Ïö­1^lêr5Jô]¶óõìeK}°_»¢ù`£b߇©\YíØ«Ub Ü¿\”É.JO¼Øô~ Åîvû7uÝa‡k–¾B ²øž²š§¯ù#ìMÓ°5m±?,€M9ч1é4ßã1Ó³쩺òo÷ϸu*ÿ¯§gþm›yZkÒ—'gòüè_Æ9ƒ3WTT{ý"Ä‘2,³Í#¶¢¹¼b3‚¤~ª²}²¹Û¬ +ÏØÌïî|8æ;Kw‘L’Áƒî%åÄk¨ä~q™ÎápÉ¡e¡Æ.×ÀjxýXºæò¤Í½ˆOÒÏØ'ÆþÝÿòkùË% ¥RÎÜ]¦ G’(á•Ò¶ŠÑ~,<««þ?çme>endstream endobj -1462 0 obj << -/Type /Page -/Contents 1463 0 R -/Resources 1461 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1423 0 R -/Annots [ 1465 0 R 1466 0 R 1467 0 R 1468 0 R 1469 0 R 1470 0 R 1471 0 R 1472 0 R 1473 0 R 1474 0 R 1475 0 R 1476 0 R 1477 0 R 1478 0 R 1479 0 R 1480 0 R ] ->> endobj -1465 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [381.2254 737.5325 454.8788 749.5921] -/Subtype /Link -/A << /S /GoTo /D (tuning) >> ->> endobj -1466 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [362.4163 707.2832 436.0696 719.3428] -/Subtype /Link -/A << /S /GoTo /D (tuning) >> ->> endobj -1467 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [402.2465 677.0339 475.8998 689.0936] -/Subtype /Link -/A << /S /GoTo /D (tuning) >> ->> endobj 1468 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [348.0303 646.7846 421.6837 658.8443] -/Subtype /Link -/A << /S /GoTo /D (tuning) >> ->> endobj -1469 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [335.4973 616.5353 404.1693 628.595] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1470 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [363.1733 586.2861 431.8453 598.3457] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> +/Type /Page +/Contents 1469 0 R +/Resources 1467 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1432 0 R +/Annots [ 1471 0 R 1472 0 R 1473 0 R 1474 0 R 1475 0 R 1476 0 R 1477 0 R 1478 0 R 1479 0 R 1480 0 R ] >> endobj 1471 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [365.365 556.0368 434.037 568.0964] +/Rect [259.4835 683.3704 328.1555 695.4301] /Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> +/A << /S /GoTo /D (boolean_options) >> >> endobj 1472 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [393.041 525.7875 461.713 537.8471] +/Rect [172.152 623.0288 267.6829 634.8294] /Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> +/A << /S /GoTo /D (root_delegation_only) >> >> endobj 1473 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [402.9837 495.5382 471.6557 507.5979] +/Rect [352.4539 369.6354 426.1073 381.695] /Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> +/A << /S /GoTo /D (server_resource_limits) >> >> endobj 1474 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [320.374 465.2889 389.046 477.3486] +/Rect [387.5019 339.3849 456.1739 351.4445] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 1475 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [348.05 435.0397 416.722 447.0993] +/Rect [381.9629 309.1343 450.6349 321.194] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 1476 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [488.512 404.7904 561.5676 416.85] +/Rect [398.5803 278.8838 467.2523 290.9435] /Subtype /Link -/A << /S /GoTo /D (tuning) >> +/A << /S /GoTo /D (zone_transfers) >> >> endobj 1477 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [397.3443 374.5411 467.1586 386.6007] +/Rect [393.0412 248.6333 461.7132 260.693] /Subtype /Link -/A << /S /GoTo /D (boolean_options) >> +/A << /S /GoTo /D (zone_transfers) >> >> endobj 1478 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [321.49 332.3366 382.69 344.3963] +/Rect [255.0796 218.3828 323.7516 230.4425] /Subtype /Link -/A << /S /GoTo /D (options) >> +/A << /S /GoTo /D (boolean_options) >> >> endobj 1479 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [317.0267 302.0873 385.6987 314.147] +/Rect [311.5276 188.1323 385.1809 200.192] /Subtype /Link -/A << /S /GoTo /D (boolean_options) >> +/A << /S /GoTo /D (tuning) >> >> endobj 1480 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [356.8967 271.8381 430.5501 283.8977] +/Rect [315.9507 157.8818 384.6227 169.9414] /Subtype /Link -/A << /S /GoTo /D (tuning) >> +/A << /S /GoTo /D (boolean_options) >> >> endobj -1464 0 obj << -/D [1462 0 R /XYZ 85.0394 794.5015 null] +1470 0 obj << +/D [1468 0 R /XYZ 85.0394 794.5015 null] >> endobj -474 0 obj << -/D [1462 0 R /XYZ 85.0394 256.8016 null] ->> endobj -1106 0 obj << -/D [1462 0 R /XYZ 85.0394 231.4888 null] ->> endobj -1461 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F48 940 0 R >> +1467 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F48 950 0 R /F21 710 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1483 0 obj << -/Length 3014 +/Length 2952 /Filter /FlateDecode >> stream -xÚÍZ[sÛº~÷¯Ðœ'¹c!¸ìS}'õ¹8©ãN§““Z¢-6©ˆTœÌôÇw R LYJÎt|ä£,û—ÎTêÌè>8i*GËm3Z©¶eqòþäoè×ÔŸàL*+(ÕMʬ‚.Tàͼ¨iQm9¯¨’Q±>uãÍ"§Yþç²,š¢*©eQUŸê?£"^¼Ö"šŽ&2eÎ9?ÏÜðÓ‰å||¿Îʆªÿ¦b–—ߨT‚j46EÚËl™7ßVùö‹j¨À®šªI’ÞÂ[I’Ô‹r‘Mç »µÑÒàÃËUS½Zc™ dEÚVëâK±ÈïóТŒ¿-§ahFÅ2¯ëì>§¡ó,Œ«7Ó)tÜm‹o.k¦ó|ÖD9ƒ¯4œ«U¾Î‚²)ì,$K‘~AÅr™ÏЬÉý.¥¥ø œ£µ@£_ËŒêY*eEåÝf s®iD¥´ëSáÆ9}ä_³eQæ3P–v|N­[=‡ÇpÙ®æyI5ZTê⾄{ë¡CM#‘N½v"°a˜/fgÔ×4 bÒõ']¿kPsQRc6V~¹³Œ6úŠf>À…àq -¢ jöˆÆÂ*Õ¶Þïmõ*Ÿžû,Ñr€˜jAÖͰTÉÄÏ}U!`E«q¨K¿KØF›ûySPeF½w՚Α‰Ï‘†9e€½_Ñt5©óÅÝÀ3‚))’@8ÌK2—˜–Ä6•ÞË,a2MU ë”¡EÒÊ[7 vê,^PÖd™­VEyO½/¨Xêî«WÜDª„)¢÷6oZ•È©³yËMÝD{¸³)P÷nŒ ÆwÛi M `9#¢-’ý‡–Œ>ŠÅlÚé¢=h³(¬—"!ÄøŒÆ5t ýãÒ›än§ëæýå›þüЀVž{#>p¬?å°>ÅÓñ¦ö8ƒZS‘XˆÌÐâ·‰V3°hToAš× 0.ÿðöû2*n~½ø'Õò¯ÓyVÞ‡¡Þ ã·ù©ûAð±#”Sš£›2°­çÙö`  y lÎöžr¥c à*Ë®»ÇVÇlÃð: ™»1~/°–Õ;ìÌFŠ×ݲ±¯ -¬6@c§´ðx”×èÀ[ýzDÙ xLŠ4jœ-êŠZ‘ã2¿¯š¢½Èð4æÍ¼šQ¤ÂÚí7*ß¼?A|Ñçü C&Ç€€ìvQÔÁnJ0·aòèÐ)Ò[ÖÐÇî¥)¶[%R3þ5_ßæ^ûUM-pÓ—Ób•-èõ‰e7bº(`2Žûë}NÍY¼ Û9—€×Å]0_?Áb×™WäYµÌŠò§‹'xÂLj[C Š–© oylQuʼ£H.A«ŽÇÜ.±ZÂÎÖ ãØÖxs¨À¡ÔNï˜C44ÎîG÷"ªX ‘7€jºýW>mˆ®©¨ñÕÕûaVP¶ÊJ´¸žŒC‚ûûnïèÅ‚šÁÊ“d»Y–›ES¬ZÒ ™ݸtß êV¤LXp*×€Ÿ.„ÚUnÿÒ€ë¤ÉÚ»’ -ö·D°äxážr‰½ahq‚„^`e”IÔ1>qoØnBp°Wðfåêá>"¡´c OvÿݨVŒ¼ÃØ+ãÀ+T[ëÐg5é³,‘Jvi޾!JÑ.{&™„Kô ;”p–"RãÅ×lÚL‚G¯gj™¡o„¿u<äJ°§»|ð£‹ãðƒ]•èàHAS;ùîUs›ûxM;9»³~"†®™)º!>¾¨vâ ¼FrJYòúÚîÇ·€„‰¥Õî€]¶LwWE¸ÄàÒi‘‚‚£mxÞÖ"ˆw®E‹ú¡h1j -™@‹ŒN^8}Ì´é3§ÉDÚ‹6÷ÑÆ«X qÔ:ˆbܲͨðM†P´õª»³PYïÐÙ3$œc\KóCmÍB2ÌYc¾ƒe;b?‚„e©Nôið•µV‡üŒ] WW‹C§¢„D§»›²ÈcÙyÝÊ’×ÞëÆJßëÆ–ØëViÒ%³Àä‚Úm²íRœ*#{¨c{¨ekµlKÀ”üØØ?¦i* Ì†B8ðB‹`3;ÁCÙWâ¥>Çh£Ÿž-[äx–툽xTJ1‡î?ŽžH¿ïñ#†Œ(b»Ÿ"µÛýÄž‡…&m8lÃnaSØOlìöÛ{‚yÙµc[[¤¤¦†Ô{l„?p¡%G„clVªvíÑÄ(¹çäÐ!àUOžPÈ[ù‹û² -JÁÒ5sȹáÛ?œzÏ« ^ƒ©*([;雩áºL¤Å½ 8.Ò¡ßËñQ{Ÿýë¼íO!lTÎÉáÞÁ†"€‰2øDKg?q~<Øþޝ%‹„ÿþÍendstream +xÚµ[Msã6½ûWè(WEX|ƒ¨=MϬS›IÖqjI‰²Y‘HG¤<Ñþúm D¨©8•šŸ¯Ñ@7$“†ÿÈBH$5Õ ¥9˜ˆÅzƒOðîà q˜UZ Q_?Þüã=S ´¤rñ¸ØÊÎ2²xÜü²”ˆ¢[°€—ßüðñýý‡ŸÞÝ*¾|¼ÿáãíŠ +¼|ÿï;{÷ááÝ÷ß¿{¸]‘Lå7ÿz÷ãã݃}%¯ï?~k[´½\0úp÷þîáîã7w·¿=~ws÷è}úK03ŽüqóËox±·¿»ÁˆéL,>ÃFDkºØßpÁàŒõ-»›Ÿnþã Þv?.2$(—0’ Éøô(¤â1ã×2%S£Ü£Ì(7åÓê5ß•›²=­Êª-ð4öp…8'j1ì ¢áQ<Ø€qh xüT6í³»ÙÍúP¾´e]Ù†zkxœÒ +aÊ50Hz3¢ ¢Ls÷©²;Ì`¸3%hà°}yxZØ›‡ë?ãzl×ú¾>{idO$"b̉S“éô ‘-CE’wº‚ÿ™i©gÄ7@%Ä×£úpÁ¿ª¬žVU „Ç`A`Ц)xÔ‡@xœ! KDHâ¯)/(/reÔÁg^«ªca)IàmJu=~ÆïØî¨K¤¨ÔéxÔ “ØZRx2Ã0bZ¦…7D]žG£e®y{FÅŒ¨„{”é1ßµ«k–=K!"MÄ£&˜„ +äˆkš…TÞ¦ÂM84Ö @ kšÐ TM„gÏI :üŒ÷±Ý/Ð ‡r–ƒG͉­¥5h¶+Í茨„{T"dS ¡€¥‹k‘æâQdÂs– Š{œ…lþVN¯†Z›1¡D)`؆Dg”Øãg ¶{½äk +Ò´d$Çv¯¯A`«„…Š¥ÇÞ£fˆÄÖÒjƒÌ!ãbæ°eˆJ¨­GEš,@0Ê RLèA¢£oƒà¦÷ZsÔ"ˆJµh¾ÎµüŒÛ±Ýë5—)Ø5K¿G͉¬¥5庘;a€Šs Óݾ¬V‡b{(šçU[ììó?'›;t{8ÅØ¾1N™’Xò$ŠÓ$‰D¦TàA'X¢`ÍM XÓ‹‹C‡D’lÈ*¡-Oó‹¬Ê2L.â H¼¨I’aîAi‘­¤®˜‚̈Ë,-¬!ê²²<ª›Ònmг=ÔûզܚH{Šj=õ EXA ”¤ãQ|‚V#!dH¨S +¤ÚV)LòP)æÍäÒF0aôg$snÅ5™,QSVsxž¬)~f b»·½ãšBA> ²t00yk#cBGösàLÌ×8²%!èµ!ÙìU™¯òöyÓB.Ve讇åÕfÂÜT¨>¸Í.J¯º¢Êgòëçº4¼ºÅ3vM×úš—»üÓεçíhKþ_]¹»]ñZìŒ"¹8¿DØüŠ!=¿¨ÄüîQÆß‹ŒõUNS™±P<Ý{šè=ÌŒ)öÇ û·©É"'Æ™1”ƒŠd‰Ìª4ÙÄÐ…dfìð3>Çv/d)S?a\±ôÈ{Ô ØZz/ÁRê9©A ¥9P7C»¶\çi¨3)OvíAqß¡Î0bÊ aço#³± c•AÞÀ1¹¬²L#©¤z™YOûY½øc,2iÖÆä ÷˜4‡±¥¤¼¨9™€í$­¯!ê²À<ê¼üŠ1Ý«m}ØÃŠU^Q‹U’„GM°Þ1¢Ê†4ÞHkÓÎŒÝ dR‚$Ê/q I–_?ãyl÷K~âCŰ%càQ3Lbk^|QÚÁ9„›„ÃáRÓJÄ!µÇ/¿=Uù¾\[~~Ùä­ âõ®\—“É!’qEm"ã~ûÉe÷ÛO¸4Ç——úКdCzô¹¶Íù"\åmùZ؆}Ñ>×›Æ>€FºëÓ!¯Úò–,«'Û°Þ•EÕ:”ÕÜʧçÖµÕ¶£—â`„c7Þ/x8v~5C8Ð1ž_†I™ÉQ\…¸®+#ǧ£Mv6¶õÓé,ö©¤ qæñwõç•íýÂædœ«…»\­Oã­©Õ‹‰ÍäÆ/ 5ñGbu7;Ö‹æÅh²¯Ó-!ÄêÆD“™ßÁPdˆj÷uöã´‡)&®ô¯KCú¬wÇM_nžG&½<þtÿÁÍ*÷L¸«*'æ iÿj4ËÜœÂùé_wôùuî¦è'Ÿä´&¨•ÞÄ<}pZ“jP-ÃÃ@p¦AÚ&Õ¥ …0„åù˸ù™­8éwWpƒñóN ˆ›º!1Ø«ÝÉ6ï‹ÜüÚp{ÜÙg«UóÂVÜØ6²a’,ÿû\Tv~•Á–&t¼„N¸9­ÂâzÏ4=ºi¼‡àmI§7Õï ¼0¾ja5@äöñ¼·ç.ƒƒÆâ`W¦ƒ}´ng—"C!öÅÏüFH¤œæn'²2ºê†eÃŒ†à˜s¥.ìˆýŽ{Z´Ò¼íõ Ø²ø37:ol»Ðìg‡om[nÝbðÏájb>QÛ\j]XX¾Ù8¿ (]æHÉê‰2ØØ4 õd?´+^s3þjó×?¹6üsÆþòÿ‹+IJìÂ(L žGÊ8¡²¸`„òŠI:AýÿD’‘Fendstream endobj 1482 0 obj << /Type /Page /Contents 1483 0 R /Resources 1481 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1423 0 R ->> endobj -1484 0 obj << -/D [1482 0 R /XYZ 56.6929 794.5015 null] +/Parent 1432 0 R +/Annots [ 1485 0 R 1486 0 R 1487 0 R 1488 0 R 1489 0 R 1490 0 R 1491 0 R 1492 0 R 1493 0 R 1494 0 R 1495 0 R 1496 0 R 1497 0 R 1498 0 R 1499 0 R 1500 0 R ] >> endobj 1485 0 obj << -/D [1482 0 R /XYZ 56.6929 512.9872 null] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [352.879 737.5325 426.5323 749.5921] +/Subtype /Link +/A << /S /GoTo /D (tuning) >> >> endobj 1486 0 obj << -/D [1482 0 R /XYZ 56.6929 501.0321 null] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [334.0699 707.2832 407.7232 719.3428] +/Subtype /Link +/A << /S /GoTo /D (tuning) >> >> endobj -1481 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R /F53 1017 0 R /F48 940 0 R /F62 1050 0 R >> -/XObject << /Im2 1039 0 R >> -/ProcSet [ /PDF /Text ] +1487 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [373.9 677.0339 447.5533 689.0936] +/Subtype /Link +/A << /S /GoTo /D (tuning) >> +>> endobj +1488 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [319.6839 646.7846 393.3372 658.8443] +/Subtype /Link +/A << /S /GoTo /D (tuning) >> >> endobj 1489 0 obj << -/Length 2789 -/Filter /FlateDecode ->> -stream -xÚÍZYsÛ8~÷¯à#U!8ûæq쌧f•¬¬©­ã!‹5©ˆ”ϯßn4@Q‡íÉ$S»•*l4€Fãë Š8üAªWY$YÄ4:X¬/xpcï/„ã{¦ñë»ÙÅÛ•Ëb³å`­”ñ4Á¬ø%¼úþòãìz:KÍØÆ:æáw·“wDɨ¹ú0¹¹}ÿÓôr”DáìöÄÈÓë›ëéõäêz4*ÒPn‰Ÿ?L®‰éæöÇëÑo³.®g½ÈÃc ®PÞO¿üƃN÷Ãg*Kuðœ‰,“Áú"ÒŠéH)O©.î.þÕ/8µSÏ©)â‚ ©U0±f åóûÒöu]¡2&¹ÖGû¹é”Ë”%™V½ò#1P¾ˆK•ÒA¢3+©¬ö㮉ƭ©–¨ ·7@ÝÏH8ˤB!󲪚Çœ! »•¡ΦÞf;ih~å\~vL ¶i8w¼»M‘w®?¢6¯]gvõ‘:‹¦6‹®lj”v Á2­¥ai7iÖ£±ŠR’BE^ -$Õ¦{l¶¿¹Ùñ™Y‹fK2·›¦.ÊúžÆo?>DÄãsBnV 8SZ„³UÙÎâ(¤V…eÝ™º0QQØæ¤?d˜Ü %ÄöÝäòŸ×44¶¦kg‚ä »É Ún±Å³a‡D|0ÛÖ:¢vlRD,Ñq$‚³HÄ韱)#¥€®³–r&1‹#þ%èö3ŽÀÝ‹7Ž•bI=n€j-Ë@J_öã,a"µÕÑd€jƒÀhœi%#‡ê£q wexâ$pQ¡`­Œ›ki­:øÆ£,SÄ5èÛãîÕ` oo×2x×À¡‚á¹üÊãáÒö\àö&(u &-¢ ‡Á5O¬Ð·º8e§(+ÓlMW.cO4´iÚ¶œ$+C ¶÷fyØ°Š…K’’9b§œƒ1¶#¡ÃìD*ei$eàî&ù÷ È⩆û޻ѯC£Là†x+BdJeö <.¸ ¦ ~}‰8'áÉQðøk³¼ "ΘJÜcpüàÐÓaÐ9 >ŠÇ Οä8g¸èÀ’Nc4èŠ ¼! ¸šÜà‹:‹ñfïu¬™éá:1`C <ê|mÎD3ˆ‰Žc‡©œK[ïÚŽzíÆ,Êå“€šå€>þ´Ë«ÒÎr“Šf—NTÜÑ"6gšA“€ö„eJ:ZaÝPÛ=m ú].Üœ%ÑÍçMU.Ê ¿­8´)ž_ÀL -0¶¥á®r×y·X7BŠ;ÜÆ|^˜MGäéôîöýêOî\çîÃeOº¾r ÕÍF’bçìx6Êxè¶I3%b$ NàžhU*Î!„-ªEùlìròl|hþþ¤0B'j·¡?)ÝQ³.ö$õæ\Œ{\•‹0©‡«@JŒkD³'R>µ(@(A™Çá¤éÜX·Ê;â~\·-•†y×™µ ˆö¸Î ?µ!Ja*ã—£ã‘0I¶EëFÛ¶Y”(‹Û²ìVnäÜM9……n‹¡Ö὇"ÝÊ,~÷X_Úä:&·*ÂÞç²íèÎúÀ èv;aÎÁDLE± Ÿ“S HJY!SPsÂϹ,º¬Ì~ê>òrt-,ND?• 7yˆDX¡Yº¤Ý´Ín»0þ d,üyk'é¿é²ÉÍO>—™­ÌúŒ/9 dKkÖ*•¼›‘mN‰àNã°"­Þ´i䘻T°yDí*}3ÂøôæŠÈP)Dn‘´‹m97-PZ©mK`G*ž‰9}ÒÁqå…ãž.9Ю¦S²›ú8tJàépo!°•P H+ÝØ®5ØD”%áµ!*I 6»9x·Ü&ÜvÄJ -:þÈ“°¼¼"zmi ÈX‰²ÊÜòsã* SwÞÙœ9HßåzS™50{|{?ÞÆ»Éëà±p`yÕ6~2º/<¹ìN ]•Ÿ¯=bÏCóU°]¢×Iûøƒ}ñ — uÐÒXîXšÂàݤ*¼¦‹sDê­òCv( hA{GÜ» Hµ¬Á5¬sw)½ÅA ”«Ê°Eÿ÷4ÆØ9<£jI¸Í¡c7ĹÍ#>ܜ؆¿É#Új6ù×Ú¤ývzƒž…0¬¹hÖÍúüþ­™¶ Ä/!–ý ÉÙÊœš³2Œ -ÊLRaæÀ º6²TÁ½®)*`[7ŽÐ–÷µ½LHŽdAl™Œ)ŽØIÏ}}Üšíƒåv-¯C -zª-ÖlöÚ¢^ÃÕ€ÖxùÁ,¶çΉê´ù9é«u$8 Ò÷àé0Š&Qh“˜$l›­ ƒ™ë]Õ•›ÊM·º’N'HؘíºìÈbá“" -·éÊuù‡CåÜmñ -[·YÏi>çh÷gc¿÷ûùŸ‹æûLp›ö™|;w̤NêÏûB¸ô/qÛvŒnãΘãúFEÇ" —à¢3fÜÞ» -o:̰=ÿx8á4Å>]Ï{çÞ=Ü;²@‰xRs Y<”¯Ã-Nš<×+’@ÁÏÀM‹CI\Ð9,õ4ŒsýgUÑó¿&ÀɺϪ":– ªa¦°ÄxQ=×+’œ®†’¸ -Š\&3ÈpJˆ™MÖCÕàå|˜ïx7Ù–A^æÂØ?ŽØ¿íI(õt’Æÿ«Rsàe¾ ~v3ž}°”:a±TÏÜHÿ`)cÁ$9…æ±öMn -‰dÇ õÑWîÓ„>£˜ºGç²õ)õ®.N_9 "NbH“‡Ò~öR±ìÅçç“%ýŒç•Š1hÓ¯(5ʘÔQF¾’ôÑ8Žb^¢ú²84õ¢¡ÆL‡"ÏËŽòjg¨ë¼10ìkÊÖy»4òX«Ñ¥Ð#kªÈó³c³9,i^¸© -¾N­û›Šð¨üKž¸üŒgoJ€¼i&_…¿ÔP§Eô¢9›ý¥3î@Ÿ€>˵C´á¸*Ñ*;ñÊN4€ŽWiÿàdOÌéSIwã@Â÷ì{kvÈW?_»º´.PQŽŠm ×U6ðG¾¼réØ6ÛroKû¸Ÿ»Ö8†¹£$AD²åι„aepR ÅdÓ†º”BÄuúÂÇ^T!v%~®èyž‡Uc¡Øæ¨´ˆ_·¦ÎülŽi·-|¾±l†N§ô¯Y«fW‡9IQ¶‹Üå§/ z—¯ƒàßê ³aY*_ó?"I˜–î½aQA¸˜;” P:p@ÙÞ¥½ÊŽŠ,Ëi€ï¦kME”e¾FÀA±ð¥‚+"Û.¯½ï9ŠéÃe_¸².¾•#ú;®L¥ŒãÎ+W¦‹…"G4}G?ÅâŸK|`ˆ#W-¦ò\qÔ"ïr0FH÷öœT.Rße©p¯nõl-EìáK‰y&x¬ ºFÜ-Äèa¥¯*l÷Âí Ôò­nïÿ惎vø3õ ¿üÑ,‹Ò—2È qŽåaj¼lðgÏþQÒ¿×Ø• ASå~  Çã3?(pB;.o“àÊÂçtíóY4¸œ(K³¿®ý}U!Y„åTr<Öé¹ÊƒÞ©|õÿ-Øÿÿ -pè*Må3u¥¿/(ª`-òfIvR7¬u*÷láÿ êê]endstream -endobj -1488 0 obj << -/Type /Page -/Contents 1489 0 R -/Resources 1487 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1499 0 R -/Annots [ 1493 0 R 1494 0 R ] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [307.1508 616.5353 375.8228 628.595] +/Subtype /Link +/A << /S /GoTo /D (zone_transfers) >> +>> endobj +1490 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [334.8268 586.2861 403.4988 598.3457] +/Subtype /Link +/A << /S /GoTo /D (zone_transfers) >> +>> endobj +1491 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [337.0185 556.0368 405.6905 568.0964] +/Subtype /Link +/A << /S /GoTo /D (zone_transfers) >> +>> endobj +1492 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [364.6945 525.7875 433.3665 537.8471] +/Subtype /Link +/A << /S /GoTo /D (zone_transfers) >> >> endobj 1493 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [341.1654 298.8688 414.8187 310.9284] +/Rect [374.6372 495.5382 443.3092 507.5979] /Subtype /Link -/A << /S /GoTo /D (the_sortlist_statement) >> +/A << /S /GoTo /D (zone_transfers) >> >> endobj 1494 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [434.6742 298.8688 508.3275 310.9284] +/Rect [292.0276 465.2889 360.6996 477.3486] +/Subtype /Link +/A << /S /GoTo /D (zone_transfers) >> +>> endobj +1495 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [319.7036 435.0397 388.3756 447.0993] +/Subtype /Link +/A << /S /GoTo /D (zone_transfers) >> +>> endobj +1496 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [460.1655 404.7904 533.2211 416.85] +/Subtype /Link +/A << /S /GoTo /D (tuning) >> +>> endobj +1497 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [368.9978 374.5411 438.8121 386.6007] +/Subtype /Link +/A << /S /GoTo /D (boolean_options) >> +>> endobj +1498 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [293.1435 332.3366 354.3435 344.3963] +/Subtype /Link +/A << /S /GoTo /D (options) >> +>> endobj +1499 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [288.6803 302.0873 357.3523 314.147] +/Subtype /Link +/A << /S /GoTo /D (boolean_options) >> +>> endobj +1500 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [328.5503 271.8381 402.2036 283.8977] +/Subtype /Link +/A << /S /GoTo /D (tuning) >> +>> endobj +1484 0 obj << +/D [1482 0 R /XYZ 56.6929 794.5015 null] +>> endobj +478 0 obj << +/D [1482 0 R /XYZ 56.6929 256.8016 null] +>> endobj +1116 0 obj << +/D [1482 0 R /XYZ 56.6929 231.4888 null] +>> endobj +1481 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1503 0 obj << +/Length 3016 +/Filter /FlateDecode +>> +stream +xÚÍZ[sÛº~÷¯Ðœ'¹c!¸ìS}'õ¹8©ãN§““Z¢-6©ˆTœÌôÇw R¤LYJÎtP%¥b}êÇ›EF³ìÎe‘×yYPË¢,?UFE¼x­Eg9>šÈ„yïÃ:pÃO'–óñý:-jªþ›ŠYV|£ŒTË¡±ÎëØ^¤Ë¬þ¶Ê¶_Tû@vUTýHœôo8qI`å"Îwk;¢ÁGà«¢z¹ÆÒ!gyÛVëüK¾Èî³ +@¢Œ¿-¦qjJÅ2«ªô>£©ó4Ϋ6Ó)tÜm‹oq\ZOçÙ¬77²r_šGÊå*[§QÙ@öÄC„`‰12”/—Ù,Oë,,à%,à=ÉA–ÕÓ"VŠ’Ê»ÍÖ\ÓŒÈKÇ®O…gô‘}M—y‘Í@ZÚñ9µnõG@e+%4>̳‚j$Tªü¾€{òС¦™HF»8^û"°a˜-fgÔ×"hà€‘¶ßµý¾!@ÍyAétZqg)m.ô=äõ|€ +Á±C)²‚ªØ#šk«TÛrhx¿?¶U«lšê³xD‹ÁT‹L°vmÇ6×¾*°¢Ñ8ÔeØ%l£Íý¼É©2£Þ»rMçÈtÏ‘†ye€|hºšTÙânàÀÁ”.¦%™w¦bëRï%æ˜DÃH#Á:e_HAz@~«ÔN@uå‚‘U²LW«¼¸§ÞT¬hêîkPÜD*Ç”¶¿yÓ²@J­Í[nªº³‡;›ÒêÞñÑø`;éBÓw@±œÒ -’Ç–”>òÅlÚê¢9h³(¬—)"!ÄøŒæÕt ýãÒ[än§ëæýå›þúЀVž#>p¬?e ŸâÉxSœA­.‰-Dfl [ŠƒV3°hTo@šU50.ÿöûR*n~½ø'Õ²¯ÓyZÜÇ©Á ã·Ù©‡Ið±Ã”SZ£]2’­æéö` £YXŸí=åJw1€_¨<,ÛîYÝ%§WqðÜÎ {µ´Ú!w`5R¼nÅÆ¾2’ÚÀ(˜;%Á»³‚Fdlôe£âe4)Ò¨qº¨Jj‰GBŽ‹ì¾¬óæ"ÃÓ˜ÕórFuâ +k·ß¨|óþýñuFŸóœ™ÒÛE^E»)ÁÜÆÅ;‡N‘ÞÒš>v/M±Ý*‘˜ñ¯Ùú6 Ú/+j›¾˜æ«tAŸ¨O,ÛÓE‹!s<\ïsjN«èù®óŽÙ„ûh¾~a×™—äY¹Lóâ§‹'¸c&±¡EËDFÈ7Œ<¶¨:aÁQ$— QÇcê0ÎYÝ lm îÚš`Á]dÚk×Gow §{Õ¤òš‘7€jºýW6­i\]Rã««÷ä, l•hq=˜§D÷¡ë»y¼£ j+O^mWYnu¾j†FÍäèÆ  ûfP·"a‚ûxP¹üt!)·iÀuR§Í]½ìàN>oÒEïÆ'PÌxØ {íàNì]ó{X‡àÀq9j=—a\eã‚“ÅŠT~I`Œ‡¼~¯™”­îÇKIÅ hÐÙŒcTÃ4`'êa@áŠA@x4©´ÙüŽyÉÝÑL {+$šþ* Þ;‚yÝŽ;Š +÷|Á>­oÍ^_ì ¶'ÚI¦¥Ûñ –Õ>’ÇÈ™øöHwOÂ+f½•ÇÒCÆž æsÇ3÷”K Cƒ‹$ìÐ+£ŒSÇøÄ½}`»i^¬6NêB}8ÔG$"”öÌq·“ˆøïf5Œ`äÄ^hZ±ÚX‡>©I+@Ì2'•lÓ}-jQ +˜ H&á}Â9Î$Dz¼øšNëIté•Sp¨–):Gñ[Ïc²{ÚÛ?Ú@?(ÒUNGO +ššÅwïšÛ,$hÛÉÛõ31tÏLÑ F¹hà=’QÎÂÛ×t?¾$,,­ö ³eº½+º‘K]Úð àˆu÷áy{‹(RÜû.ê‡ÂÅ@¬)dr.x0Ú¼rú ih¢›(Ýà^4Ù&bÅJŒ¬ Ö¢@tQ Æ Ù”ŠÀÑdF[¡¼;‹•õ=BÂ{ƵÔ?B½ùQR†ykÌwlf쇰,ÑN‚wYkuÈÕØEÐà~u›CÙ§lœÙuÙ”¥PËÖïV–ünl ~7Vú~7¶týn•¸6FÔnÝn¼K‘ªìDÝ5ˆZ6QË&´”ü82‚[ðwGÄDŒL‡‚8ðCóh4[ÆC9Tº¢>ÇÎF?<[<6Éñ$›{ñ¨”k.Þ€ÿ˜ßãJ Y3ßn¨HìvC±ç!¢®‰ˆmÜ.lŠŠí†b{B´/»†lkŒ”Ô”Æz1‚®4wDD&Àh%j× MŒ’{N b^uðä •<:yÀoùÏï‹2&y(W¢kæ‘r÷›p:!úž—:¾³UP6>vÒ°†²?v_@hÎŒñæ(ÅhÔü®b¬Ñ[Åô}]ˆ‚yïÁÓD‚G/än +u›2«6n¬Æ²¬jjÙT„À}‹wßbQ>D cZcQ‘RÌmÉñj÷-a». 𚌟W–`ÞÀºâRÍóF3" £)ØíŠ;áU‡vwЀ™Š—½²!1URõ66mVÐN +fÔ¸ÝÇ É¸oIOç ÐPÇ€—0Ä(Uû/ ª“»êîwb™ç7’9­È‘þÓà–›„q£Á0 NDzyòK›,GUgë¼úD|ý·ŒÆÝ¦U¶ß2wMÞóÌèÿÔÙTƒ8~ÈÙÁ|‚O&]MÛ{“n“èË|‘®©Ð>°¡†%ÊË pà¶ÉÇìë4[Õ´@SªÉÖ=ŽK—wCá¬ð¨ÿïµtd¦-rb6™ÓÙÆJO@¥³ÿÇq‰~µæöT †O||®"Í3„Å»žÞ”-Vðc+àì£b%aw°h¬`­,ßâ¢Ô„ž!ÔLÄÕ·ãO€µ6ZÌ”îü(¤€[À$7ßC3Ny"Ú2L«> éãNÊEõ‘rŽw,úeÍ›[pÒ|ÜAlž§_2ªÝfäúA\‘±÷KžRåæå;ª„_à |F-ñ«{|¿þ ®Tjû`‹wô@³¤/rêÁËñ—(iÝ»|Ge:›Ñµ^UÔ!{² c¯£éóW¯®Ùùõ»ÓD†Ÿ7  *bŒqùÎv»âiµJ§Í“ýÐ{pêóxÐv½ƒCh•B3gà–àtzcÍ1Ù<)ÃËØ›—s–Y<:Ç£”f<ºN[ö&\J0äºûó£VµpV!¤7BФï«@†Ã÷¼±=oÁ'ãø/Ç”D¸Ã#¨Ö‰ þÁèó(xýÁíç½zw«†Ððâr)G¯JjÔ•«¡<é’rëd,s‰Ð#á% ã:0}Yã/ÉÂã#”Á3,×YÈÅ 9Ä®UYUùí©äc´ÎØ‚ŲZ•dÞ—ñ÷ Òy:mX©äöV§Â<Îkå™×Àzwož¹ß€,0M¶¿I{¥ƒâ PÔøC¶äXN —¦“Í1€És‘ ýtŽšsøìêmÅá£ò^ÿü{:Ì-2.Ùݶö'}Ͱóÿ*HÞendstream +endobj +1502 0 obj << +/Type /Page +/Contents 1503 0 R +/Resources 1501 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1507 0 R +>> endobj +1504 0 obj << +/D [1502 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1505 0 obj << +/D [1502 0 R /XYZ 85.0394 512.9872 null] +>> endobj +1506 0 obj << +/D [1502 0 R /XYZ 85.0394 501.0321 null] +>> endobj +1501 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R /F48 950 0 R /F62 1060 0 R >> +/XObject << /Im2 1049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1510 0 obj << +/Length 2779 +/Filter /FlateDecode +>> +stream +xÚÍZKsã6¾ûWðHU0x ±7ÇcOœÊzfe¥¶6-Â+©ˆ”=ίßn4@Q–lgâ¤vkª†`£6º¿~A‡"J5ÓFš(3 K¹H£Åê„Gw0÷ñDxži`šŽ¹¾™Ÿ¼¿PYd˜ÑRGóÛÑ^9ãy.¢yùS¬™bØÇ?~º:ŸLeÊã‹Ëïa$T’ÊøìÛÓÏóóMhÏúÍåÕ¢zœ}ºº¸üøÃìt’%ñüòÓ‘gçç³ó«³óÉ/óïNÎçƒÈãc ®PÞßN~ú…G%œî»ΔÉÓè^8ÆÈhu’¤Š¥‰RRŸ\ŸükØp4ë–SSÂ2UÑTè”e\Ëç¿Kßàð]?Ê0ÉÓôÉw§‚&à¿hªeÎ2“ªAù‰)_ˆ”%ye©aZIEÊïÛdÚÙúõóþ¨»gF*”9Oëº}˜ÀLÜ/- p5Ö›‰Ècû3çò‹gjñ™Ç7žw».‹ÞoéY4~0?ûLƒEÛØE_µ Ê_ž +ÁLšJ'­ûH»šLU’“* R ©±ýC»ù•È톈ϬZ´’¹[·MY5w4ùù>!†¢œ¢ô«:@¢JE<_V`M'1=U\5½mJ[õ€Ï‚ô‡ W×DB ñùáêôŸç45›u¶ïöW‚÷ä ·)Jú€Ü1âφñÞn:Oè‰bÙS7¹f‰à2ʇÎÿˆ#H™’\GäÌÀ¹þ5à+žb;ˆ7ÕJ±,ÓzÀ6@u0 €ÛHŒ(&Ò&c°*u:º¡:Õ 0rr–*™xTšL5Øþ—ñAŒF€?E<›§Ò¹tô[$OŒQÄ3»Ãî”àï/W2úБ¢ñ©hßéxcw&ˆ;÷“àÍI’FBOyæä½ì1þ)‡µ1²´íÆöÕàõHSë¶ëª›‰äqm‰‚øÀ' ½½=†iØÅ!%ËÉqÐÄÁ»‰HãØ$ˆ“æ‘7KövS#¨xžêhº  o¢ÌÀ<ÜÀŽ“rˆõoµ!˜œ}¸&ãÙ“´ñçV ÈÔ†© p=@,ÏÇéæ í€9AMš¦šs†›Žœè0;ƒ®˜@ 9À5A_4X€Œw»€ã<,ï£s–+òFS¬ì‘ä"Á±¹ð<˜6lí£ÙjÛõ4êÖvQÝ>zèq» OÛuåVùEe»**/*~Ñ!6šš”Aƒð!2f”ô>t |\ÄMKÏþqm1är'‰n¿¬ëjQõèXøîÄ¡âù¬¤Øs›Iok¿pUô‹¥õ3¤¸ýÏØ/ »î‰<›]_~|Gã«k?¸þt:ÎÏüFMI«‘¤Ø1?žO ýgrr ä@ÂŒ„Ñ üÄ#M ÊàƒŠsÈ^‹zKùg~;½ú><bhýî¤0C'j¿a8)ýQ³)w$õîXz{XV‹%0©‡†U %¦4¢¹©PU” ”À|Ìu|Õö~®_=q?,­ß‚¶Êã¢ïíÊ DgD ®Š2,m‰RÚÚ†íèx@$Œ@ý€Ï²ó³]×.*”Ųê—~春¼ÂŸdm‡¡Îã}€":ÝÒ.~ X¿uu láT„£/Uד͆ôô_›0ï‡?¦í2'Dz”A푇j +o@øJ1_WµÝ-Ý%]Xª8Ó™–2á‘;´·¾·]»Ý,lxËpÞÆKúo2Ö¨®ù!”1ó¥]‰% $“ˆ„¼Ày¥Jïv"bWN"¸sפÕ;‹>7¾ +lP»*Ý+a~vqFdè¿Ii»Å¦º±ÍPE™ºÚ•ÀŽT<1 z¥ƒãÎ Ï=9Яf3²_ú8 JéðÛBz`+¡<Vù¹mgKð‰Ädñ58µ%*I ÖÛˆn…«µÝŒ“žtd„#K,ÀóŠšè} - X%ʲ¸÷Ûߨ PUÚ¦ÁæÈA{W«umWÀðâøà®®Ù€€…=ÿ(ê® ‹1|áÉ`÷p劣ÆS ˆ=ÍWÁvŠQ'òŽ]ƃQ6ÖAGs…giK‹¶ÉU|N†óD-‹}vè hCg#BФ€Z5VEÀ»”!Šâ¤KÊ7døÄø÷8ÆØ±<§FIøÃÀ}<Ç>žðñljmñ"¢›¡ÇºØ@áºEŸtï^o0r†=í +ªÙ°Aø~ga¥ë%ñ @ˆw ÉùÒš÷2Ì +:LR¡ñà…™Þö‹TñW…¡¿Ãb*gïm^¶Xª˜ŠÂÐìý´ŠÿⵂN|˜Ëc-!PË¢/À3žî8©I¤±kÅráï$ü¹æ ž”Jp„÷#áNä™Ì±²}bw£ë”¡—pÍÛ Æiå¯2ÞÿÍïmÿgéç~'pzå,5Iþòjf-÷«âÛç®"Ã-»GQf´IŽçÊÿ@WÆG~&P3„ö\Á%! Te¨çºç hˆ8‰ÉÍŸ×þî$@KɸNócMBLyóßìþž¹Êsy܃½ø«RÌr~ð§`L©ôŽm$ü>s †endstream +endobj +1509 0 obj << +/Type /Page +/Contents 1510 0 R +/Resources 1508 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1507 0 R +/Annots [ 1514 0 R 1515 0 R ] +>> endobj +1514 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [312.8189 298.8688 386.4723 310.9284] +/Subtype /Link +/A << /S /GoTo /D (the_sortlist_statement) >> +>> endobj +1515 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [406.3277 298.8688 479.981 310.9284] /Subtype /Link /A << /S /GoTo /D (rrset_ordering) >> >> endobj -1490 0 obj << -/D [1488 0 R /XYZ 85.0394 794.5015 null] ->> endobj -478 0 obj << -/D [1488 0 R /XYZ 85.0394 509.1791 null] ->> endobj -1491 0 obj << -/D [1488 0 R /XYZ 85.0394 477.0735 null] +1511 0 obj << +/D [1509 0 R /XYZ 56.6929 794.5015 null] >> endobj 482 0 obj << -/D [1488 0 R /XYZ 85.0394 477.0735 null] +/D [1509 0 R /XYZ 56.6929 509.1791 null] >> endobj -954 0 obj << -/D [1488 0 R /XYZ 85.0394 447.2177 null] +1512 0 obj << +/D [1509 0 R /XYZ 56.6929 477.0735 null] >> endobj 486 0 obj << -/D [1488 0 R /XYZ 85.0394 390.5598 null] +/D [1509 0 R /XYZ 56.6929 477.0735 null] >> endobj -1492 0 obj << -/D [1488 0 R /XYZ 85.0394 368.2486 null] +964 0 obj << +/D [1509 0 R /XYZ 56.6929 447.2177 null] >> endobj -1495 0 obj << -/D [1488 0 R /XYZ 85.0394 281.9323 null] +490 0 obj << +/D [1509 0 R /XYZ 56.6929 390.5598 null] >> endobj -1496 0 obj << -/D [1488 0 R /XYZ 85.0394 269.9771 null] +1513 0 obj << +/D [1509 0 R /XYZ 56.6929 368.2486 null] >> endobj -1497 0 obj << -/D [1488 0 R /XYZ 85.0394 89.8526 null] +1516 0 obj << +/D [1509 0 R /XYZ 56.6929 281.9323 null] >> endobj -1498 0 obj << -/D [1488 0 R /XYZ 85.0394 77.8974 null] +1517 0 obj << +/D [1509 0 R /XYZ 56.6929 269.9771 null] >> endobj -1487 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R /F62 1050 0 R /F53 1017 0 R /F21 702 0 R /F39 885 0 R >> -/XObject << /Im2 1039 0 R >> +1518 0 obj << +/D [1509 0 R /XYZ 56.6929 89.8526 null] +>> endobj +1519 0 obj << +/D [1509 0 R /XYZ 56.6929 77.8974 null] +>> endobj +1508 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F62 1060 0 R /F53 1027 0 R /F21 710 0 R /F39 895 0 R >> +/XObject << /Im2 1049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1502 0 obj << +1522 0 obj << /Length 2893 /Filter /FlateDecode >> stream -xÚí[]oÛ:}ϯð£4\~‹Â>¥iÒúÞÖÉÚ)°»÷ÞÙV¡Žåµä¤Ù_¿3Ê–]ÛJÈö@9Q4uf8s8TE‡Ã_Ñ1–ÙD&8ÑÌpa:£û#Þ¹…{ŸDèsRw:iöúx}ô· w–Xi;×7±ãΉÎõøÈ2ÅŽaýû²w~|" .º_AJ}9½º>ïÓ º~ìö>‘&¡æì²wÑýü½zëèº{Ù#uÿüâ¼Þ;;?þëú·£óëå”›¯%¸Âùþçè¿xg o÷Ûg*q¦óœ‰$‘û#m3Z©Z39ýc9`ã®tLš &¤Q¥™ƒßÎÏ*íXÌã?Ë;'R±Dp½{,zŽÃXA¤'ÔÆP'‚'LÀ?`FeX,E²4£T 3 -a˜vq'6‚I F3žŸØX[l•TÑ]QV$¥ãñüX¸(+K4žL¢î”îTw ݵ£IZ–@Önæ%i©ÕQJ—Jž ó0v÷jËo€¥;±f‰1ÞI€Sü”•£y>ÌÆäù4øÈÅ ‰a›Ž¢MÌ´Hàm˜¼g´¨ÿ¯g'^0dý>»M?[ëZL'c¦ŒÒd:øs|¢µèƒ%0Öͦo‡Ï9»¾Æ¼^÷®+øÀ"Îó‚!ë'vÂg]Ì.T |ÐÂo[bV‚ëïOD×ÞñÞ( À 3lú5^ÎÒy•§“_ NrÃCÇrqƒ·þä\þµOLÇa¸éîOÇ9;ªò—!ت­_Ž LÓû =ÞeÔ/ŪG˜[EWÅÍÆk³GÎïâÄøÊíqJ3êÙ|€’@ÁƒíM±˜ŽKžDç?gÙ<¿Ï¦U: ª¦oBï<½%Åã]>º#†¸"i4É¡[x" ¼å°$ÆáÁ¼ºÛm†jÉjÐÔÏä‰:†mÐNÛ5A9”í4 (yü‚!ë'vÛNk¦íàvÛÎ@¾s‰ ,ð)¬!>ßÏf“tä×OG¿„@÷©‡ ä°~@*gÙˆ–ܘÞ.^‚%W!MÛxXÝN³!©‚¹G“¢øªDE‹ÙϢ̳ËdˆÙä‰zúõê½É_Mét²%?}¹VtQÏ b†[¸ßò]¹ªgÎzÌRÎÓðjƒLº¦¡ÌgRw$R[øvL÷Ó’îÑ/ÔQ -#d9kÓ!XˆñЋ -d1ï½}FB›wKHG{¼»á6¯sÅ7MFrf¤k‰LFYÆc"Soðûù¿ÀÜ*áÑ *ÍAúx‹A3[ 'ùˆäÙSHΈƒ7‚g¯ž*óÛi 7ü -)ÿ[LWñæd·«·„"®öl š(6ÔXÀv˜®…*!™°<„¢nY¥Y3”H‰‰îÒòŽ$\ئԣ¶!ª¼ ý½µ¬¡ƒ —O™¥ QFn±…„5»¾ÆxMT»›8(ÏÕNƒUz¿ñ´s=@Ÿ¯.Áxð˜ˤPn®ÛI1¬‰î¬(sÜöT‹Yéf¤¡FvVâ×˳=x6&úŽ©­¶œÅ°ÓjÁ3¶L&ÚyD¿t{—©pr“ÛŠ8` -ÂÙÕw¨Ò‹ -"`(y$áNJ—XÅ´‘¬(àŽwfèø -’Û|ÓwLr5$ §eÜbØ•Â^€\¼{58?óÉDÆJGW>B@j˵PtŸUwE*úB¤ˆh¯‘Êl«–ê{ˆTs_kÃ+´EˆK¯(k.÷«Â{N%$%Û¢‘tLÇšpé>õŽO 71’ÚL°bA¥&#©>h°ZO]åZ0Ãm @<7ª^÷ŠÜ¾¿ØÔ|ÓCä ÊÑ*Ž·¶…ˆi®™±ŠÂ™_8Ñ: SÊ/lê Ž²Ïàþ^#ƒã5eðÆSžy¡vzÆšè{YwÏ÷a=ÞæSŸŽhXݧ šžß -Iã#(u£@ƒ7æxD$•‹†‹jÛ®¢¬òIÈ}!2ƒX%Hƒîg,Gs,6·2rYõ1kevP%jÏ.¶i·ÃV”ºÞ•QLÛB•uÌ&ލãïÿê(”ØL•°þ}™ÍÕÌ ûs{¶[¿3¡:B]5pΛxY>Pëå è²Ï³V›.©øc4ÞòSA¥“\´_;ÈØÑR ˆKtá±…€¹LR&À¤Í§7…?)QkðBïëÒ(A!\lC×õ€¼ÝÆ´ßñÁžâ†A¤j‰¤JIæ”$x¿«›Düâê˜À°Q@$ò Iµ¯Ó¹z}Ä,K  ±HªzaéHåBoöä½p&7õU'¢‡t²"F¶Iñ藜㾪‡êaVã Çkp}SL°×8Ü}¢–& Ñá=ªBU$Hâ[bírÇ©Fâ™»¸$Ö^tß4ä¡Bë¬fÈÀhy ï•°KMlL¡µwzuÝÇâ®âQ€ÇŒ³–;Ï«§z;—OÁ–ø™Ë N-ùKD»QmN÷ '2-iAÕÆ…$í N¯ÔØùoS|­:«‹ùpšžÍòQõh´:™C 7 HwÒ͘ïùú!Ìû †ºYƒTÌŒ0-UmØ•1àû]¤ÖE×>¨xé¯)ÖI¢Ht¬L2IåBQuíÛg³æÖê™<`äh¾Ý;>Z ÙD·ù¸†þH YáüÌ…\ÍɵGÌ·KÚL—þshag¼ Dâ‹üþqާ¡¡ß]Z‘Ôï‡Gæ¤}™S4±–uúÐÿp2¨I©ÁÓ×”trÙKD>´=àVAûœF)*²ŸyYmŽ·%+aZ,ÑuïWôn õûÔVO3¿MB»úäÅF-)¼×ÒÐÔúIl;O öÂñ½EͦkêøvÉÖÙ—,Šú‰,¤eœ»–óe LIHäµ+0©ú¿ ¿;ÖréÂàJKSIü¢"ÎKRÜP­îË©I–$ïʃE¼&´av0»rÛ @w²éâ©oJK¨Ã€¼kÄÀȋ嫃vTÜÏTŠJ'ÞGb¤ê³lZbrÚ‚»Œ2,¼ŸH^¥*–¹ e2Ь?‰ƒnõa:)Ó0 "À¨Ccå+ï'ÛÞv OíÉdÍöºEû¦åÁ%ãIË—RBÄÌÂo¬ÂÀÕq"£Óþé7 ÖÖáÀ†p`×à áÛ ë>^òVaƒŒ jiF鳈a xºÿ\èÖzý9Qíbþâv>ép.q.¡òô̈ßb鄯³ŠæœÅÒ:üŒY»õuÞi¥ìÏý~õ_ )çvPJ;pxŽ…¨;þËÇú‚3©¬¬{5¦þ?ʽ+fendstream -endobj -1501 0 obj << -/Type /Page -/Contents 1502 0 R -/Resources 1500 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1499 0 R ->> endobj -1503 0 obj << -/D [1501 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1500 0 obj << -/Font << /F37 791 0 R /F23 726 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1506 0 obj << -/Length 3252 -/Filter /FlateDecode ->> -stream -xÚÍÙrÛFò]_Á·€U"‚9€lžYŠ•8²–b6®Mò#kà dùë·{z†iÊZ®R±Šèé9Ñw÷€õ"ø±žŽÃH¤²§RÆ‹{“ÙIÔ»‡¾ŸN˜3ðƒÝQ?ŽN¾¿ª—†i“Þ讳–#­Yo”ÿœ¿=»] ûGAöq?^]¿!LJó÷×—W?ý6<ë+Œ®Þ_zxqy1¼¸>¿è˜1‡„[âßï¯/hÐåÕ»‹þ_£ŸO.F«#w_‹EÏûß“?þŠz9¼ÝÏ'Q(R÷¡…,Myov"cÆR™žÜžüsµ`§×NÝE&±ñXÁ’«$Þ¿-mÁ¶ŒÓP©Xoí -o­B+$}¤CÎ×”ç¢Cy&E¨…ˆ{ -ÖIô!é¯?Œ€V’‰à·ÆäýÔiPVøÔÁ›ëÛÛ‹sµ5=3Y.úLfúäGçå$kWd-AÃaCÀcÙeò §d˜Æ1žœ!ÀíAêÇÊ,`gA•Íp5Îé$€Éè11‹6#_b0ª5‹‡lJø¼v«Ô-æSÙ´Ûëá9¢Í|®+XPÄ œ3'`ýnØz´ï†ÐpHÏöinUU?§Fc*7á®^ø¥éi5Ø<)CY̦݃Ҿ ²”Üñ‘ø<A½(ïË -߱ĩ¨A{ϧÙÄO?ÑóÚ²Ó-³ƒ´Ì¸l`[Á¢ài&‹rl—%²{£Æ]žr‡Ûj%A¯T’ð^G¿NÀ…Ô¡cÑp¦Uõ‹%ýŒ½:“h -&Õ¥IÒ4Ôq"-nFC40" ΀PRóÚÊ 5PUð™9Ï-AõVòzf…aj„š9ðí0ûìR’—Ã,‚w?À¢îËA·y$_”GIÊHŠcÀ"‡Ës§àiÂý6í¨þ°D`Nç­_–9/«@" e*ñ&æàmA·‘.ÃË\U`gY[ÖHÅÿœ›ESW 5­ç€(ÇSCHkQ¹¤Gˆ!=BÓ¥Tpñ –Àyƒýì)g`Ÿ³é3cú³ÖTxͼb<Œµ8jì¸Æ …ŒÝpx{õ¸!°wÁy]¡¶Ž­Ý6yД÷UÖ.½DTžµ—EQÜ¥/vQÁ-}÷rHFB yçm^Šè`-uÿ§ågì%z¬’P1Í=’!gΨûB#Ô "X/[3h 2dË{ˆ¦¸ˆƒ1F'6X.À@ ¨›¶!b1„0&§‰ì¨ìÁøA¦tS!ÛÏŠ¼$ÆN0”Õå† ù`Œ&£ sZ/>º®MC9Ð^3ת§•^ù·èoy¶ƒúØ%ú×1òÛʆŒ ¬àÇ2Nà 2M,Y¬:Æ:M;ê¨x´ -×ÞÒEDy]D˜âI„¬ -"âU<¹ß™ùS°x+Æ„ÂÆ˜ØãÌ¢lP¨•8…¶`ÁxÙÒ€¦-§S³Äí’k`7¬úgGü±£»Yǧ‘GT*Ø©é°ã¥¤æÄC1K ÐáÇâ¡XðPjI„¼}†‰Ø«t¯ü3Џ ˆ[»Ð¦µaªõÄwôÌh%G˶©iŸúŒ±ÀºÝ #cJçÎùÃ!j÷]_±g•©€øæ˜!%Šx,Ë‘›KÔcÑÕcé í³‚ð­©r›|SOËÉÁ— Hœ…fÙ£aÕlâp_>§2"§)ë(ê1|½Ÿuš¼fÎ%);ì˜ E -“DPLt;ìÇqð/L¹ÅŠòƒqmM\¢ƒGc-@+ô¯\ùHl4fñPNlZhã:Ƶٯ6¿ÿrël!râhª¡4?À© ^q(e !;f÷$$N*Îîݾ½¼ÁÐbÍíT0¶ÖM'ÁcöDmÌݱYæÂžùr<-›‚º3­G¹Y…å6v}4Oß5„EK[HCîÍb¾(«ö¹:Çãæ²K¢—â¤?ìó—ô3ösRˆÇªá$dUZr²—#[ªL €õS˜O-ÄÅ¥µ}æÏ­]ö:Ýó}Ý;[Û¥BV}„Œ\†Z«ÄÛ #fÎv+æ±·[>å¤@0q& ‘΄!¸2a8›°ÓýBÞ,q9йàìö×ÑMŸñ48¥¶ËVpD×Ü,çózÑzæ¾-›b f{YØ¡Í+v?Î QÙ±¢½Œ¢0UŠˆùÇ9Ä*šN©Ù{ -¨ÈÏ!Ehís ±—©(ÝÊËöF _W&é¾íK1e}Ûrìúç¨Hm]ßü³üA¸N¡€i膑ڼöùâúGD`Ðxª0™T@T½‡ïþnJ@BñØ@¦ïêé´~ÄÜèüý¥H;3 §Ô¶Ã)“i†,¦q;ð4äBãlP¿²¥MMnmbvZX§¥+Ï ðƒÔ¬Zë0õMË-!iý @FømY©„@k•J¾-G£oâñãa©cz.˜­#’®]]÷ Þ­8…×  Ê4¬³ÏKy®oPøà -´EË—D$ÃXèÔÝãmX¯ó"« Âé:C… ûÝ^CM±nëI=%ÌÄU¨Zkµ0@o©ã׫!¬„‚$€Y™Xª¢CåýaÖ ™ @¾8 ¨ÒÖâ(V‹Úóåb^7_GTA4-¸c!¼ ÿ®ÙU!/Ëi;X9JpÅfáÕ®[]&ñs·&¼OÉ.€´uh¯€­`QÈ.ÀZ L±Ö¸Ãˆ(*ÁÜØý2Ùaö+®ÅqÉBænäÈ$HG˜(—¾…X*a @o Ð)GÚji/y!áÚb€ZåzÔÈ̓™Ösª•hº¤UV&mæ ËWþƒE×½Rx2[ae/æ:¸Â´/º1ä^$co%Óë›j{#ÞÍ]¡ßç®Ð÷-ÊzéVjžšEÚÖÌœCÀã8kVöeȧYøÞ{WÍž{„Í «`×Ôô!Ü/_픀½–¨B` å3£ -Î õÅBñÁ¨‚¥ e9YGŒûAw õáÆuÞµ¦r¨Ù|ZNÊÖVsu°ÈÜ-7·1¼„Re/'°á‘Èàûš@l¹+q»¸ŸîvC.k·²ù”Á¶Æí9˪§]0йQɺ,ß -V•M)——öpµ¤ †ÆYc Ø"£D2| ƒåÄ—Ò›Õn~á¦vvÆ‹ûSúJÃ]Ë`RP*£cú.qðÖ°ä5ª:·‘¸dÒrdÇËÑ 0'¢[Éìw(\rKʆPë°LúÂ.Xƒød- Œ.Lf‹ŠÔGø X -Š<½Ãsù N/ÝN¼mZû ¶‰(0 ³E{<¿BÚ/ypš– ïrwX’ Ôy<Üð }ï…gî<Ù"¾ZÛl˜•1>Nõ¡íªowŒ;6DU4d>Å WÇÓƒ¸ H_à43“'°ðmEXù¯:Ô#Œ-´OsjXuR¶îdG—37|ZÎÊ–Öó¨]_M»cAŒýþÚ“Ì»e>š¹[¥¬6všd“?'I ~þ´ëYËk[Tî3*¡@‰çsÔÄY_‚(wîãÁP:‚è.èøï׺>·x6mÜRH‰œàN±xí/Š wì7&êzÞ9VŽ ,˜c¼ôgG‰Üå²ì*©´GÃìäräqÄ·Ô± -u¸ÁË4{8÷)>Wkd9Ø9P0ƒÖV¥Î:àÔz,ÌÊý®—žn€r7q-%æ +¿åt§Ah€ø¨šá©‚¬H 06ôtÁ¤f®¸É<ð¬ülü„ Òφ.©·X¤¨ðøLÇ­WÛàbì¢S„ûÅ:Î02Ç)ÈÛÒ¸‘V#áé“™]ï67 ˜T¨4Ëû{ӸȄ´Ÿ Ó¸(B\ÔË© |Æ®›î \:K¾‹;'„ß,<¹UˆÝ)`))„ÇÞ´‡T»rs3z€µ¯îwÚ6RXžºS!½[Ø9¦&èÛ¤ö›¥NøbÑ4_Òå+ v¢³¦.Îë,ãÓéL;€­²Z™r¼_BT¾\8ïM¬ÜÁ!Z÷t+\Ã`Ôg>íj|±hœM>ºa.ª+½åFfû¼å!›.¿¨tlÚpÚ<Ü÷I¯À*“`»¾ÀzG“ûç~ï»þæYªPh½ç^bùS!õ4Û>;ä¹a¬¹ÚuøÿV!Ó•endstream -endobj -1505 0 obj << -/Type /Page -/Contents 1506 0 R -/Resources 1504 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1499 0 R ->> endobj -1507 0 obj << -/D [1505 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1508 0 obj << -/D [1505 0 R /XYZ 85.0394 337.2163 null] ->> endobj -1509 0 obj << -/D [1505 0 R /XYZ 85.0394 325.2611 null] ->> endobj -1504 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F39 885 0 R /F41 925 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1512 0 obj << -/Length 2929 -/Filter /FlateDecode ->> -stream -xÚÍ]sã6î=¿ÂÎL¢?ôÁ{Ûf“6^Ú˦7;×íƒlѱneɵädýï @™väì^»w×ÉL’  ‚“þÄ$I£ÔH3ÉŒŽ’X$“ùê,ž<ÂØ·g‚q.=ÒeˆõÍÃÙ_nT61‘Ie:yX´ò(Îs1y(™¦‘ŠÎB<ýçw×ç—2‰§7·?$”Näôê»7?=\ßÓ@ʨßÜÞ½¥CŸ«ïnn¿ýùþÍy¦§·?ÞQ÷ýõÍõýõÝÕõù¯ߟ]? ,‡Û±B~;ûå×xRÂî¾?‹#eòdò 8ÆÈÉêL'*J´R¾§>{wö÷`0ꦎŠIÄ‘T©‘“TcrJL”*B9=,-ì ö^}APÕàWL{?tÿ–öÿÞPWgç}Õ6ÔhŒwßÑ̪£Žy±ÙT¶¤FÁ¼Ê¼]ͪ¦ðTÄ@{7;^¦ßTÍ£ŸØ0¥²]žÉ¦XÙ.B=€0.…ˆL’È`gI€°C'°Øœ‹|Ê8 jü¶µM_ï¨oÛ9Öf¾¤Ôë¶jz»é¦Þ¾¥o Ûð’$Ì„…‰Hž›·wï» (˜W*"0_I°Ö8ŽAòBˆ©ýÔo‹š¨ØOëí:^Â*HHD\—:2ZhGœôdd h¼¦Orp»7‚¶ƒb^´›A4ê­:ÖÅü£íyÇ|‡QØ>áÓBmßÎÛúâüRÅŠ c|m;Øu½{•IÇÆˆ ,«Ç¥›šš©mæmIÆh<ÿY<}^Ú†úº¾%ºŒSqA4šÒÙÍ“Ó4ô¶üeŽÚGàœ€GQi6½mh -Ÿ%àâS±Z×ΡÅBxªÊãEïo®h&¸}q¸72‘…&ë]m¬VU ²s ´J÷]=B‚íûpü®Š®·Œÿ!Ž¥ã ϘmwÇóHN¥=XJL»eûìe–æ-¨¨é™Z~ÁA>:M|hBÕ)õTô`R&ÓUÛÁV$,M,L`)ðÁõݹ¤;/R[ꪫÆ:‚zZÔý²Ý>.iy­š­wI0 Q;ƒ…@m-½YÍËn‘:0ZèB¿”EFÉ<ô¸ -4WlzÉ÷)o&Ê­Œœ>VOd-Á(l“ìodæý}DÀ-DÇSTÓ™}¬&ù\õË ë¢ùˆâåô|4ÆW®˜DÑuÛXȈ‰zÏ8³GN°£³¸V2ÓЕ È|ÚŸªvÛy/ð rK ×Õ±go½m¼/ž×ÛÒ;õEËΚ°‹²˜UuÕÕÜM[×í³S6žm2rH(pèÑ™túÌýu…öz€úððÃwíÖ–ñßþy Âdš‹£™nÏ\푆‰HŒ 8äGW]µM5ïÆ4TZ<÷Í£gí“;©÷ÆbgN †@ÌaÎö#™êxÑr³â !\ÊÖ%îC r÷÷ÎÄ¡·Ô]<µ•ç -2…Ç-ªæ ?Æ'ÙuËŒxÚ†Ò^¸îEâš{{FYuÿÂdUŽ›Ãâ­w+Û/B»F€v,†­„dˆÔêçbÇ00Ö£PbÍÎðnïB®Oî Ì—ÔÀSQo?wÚUÕ÷à  è³ò)Å™Æò—õPë»Ã“ -. )ã(7)ì%O£,ÉéÒðR"oÞò8-Ž`¥¯*ñUå‘Á]K¤Ÿ5˜LGy¬èâ|h˜«ƒÙ€¯Ê ÊH摉€%yZ2ÁšbKI Ð* -',%•Q®ùî:$¯È  þ'–Î"§êsÖ‘ 0¤!ë$y¡m§ ™K°àŸøÐ¨$R‰Ÿ3 GAeù¡iøó¡N ! ÿ•„°¯¡ý?BÈ`CÚ˜ ¸Š(΋y/ŠzàN"pž(gÑy¦åëE=•›}Çå[J*ç´•Ô”4`Dzxâ!LâÝÐaª…CCª…çe5_*\»Êe8àn(Ò]qP¤—³ª§®f»š¹âÀ wirÀší‚Ij(ÍáÖW^/äeɉXw” ¹[OÿÀÕº))äéö§4¨ÂpXÉÃJ@q”R)IûráÆö/H¾’ý&|»:ÈüöYsÓUŸ†­ù´®èÈÞs{´oϸ-æËãÛ3ñtª:zÁ}G$_KH­}‘LB•*¥'J¦ ´,û²f~×3ÿ£\ÒïéR‰$‚kkrÊùã¨I&JäQ’ -€ïßG?\½‹þvûÀ)¥4Ýè0o‚C–‚_Ã8€Z¿tpàM Öþ£.Ð|åð¸„XgêTБ°2Ä3œ@Ññê»Pbº—öJ-ãÓ2 –ûJ2ùOÂÂ×·Z‘H0,(eF˜/ ¨æIj^ pf£X˜”QÕ½î~ø4»w”ô´px2 ù¬˜þÈSÜÒ<•Œ~qÊ}±Ó-«r±°¾¬:Ø×ºW”!X,@,Iå⥑^Sü[ÊÛª›oG^N0T:ßjçí¦<õŠ’E™âSþÆáä´´Ý|SÍ\„ò—ДÙ{]ì§Gž3<5ÐXÕP¢  ããÃÜÊrÕH)G©wÎ5µÎñ!X¾álŠê#A}®2%œ”«´õÕ|ëÞ\»²®v£øÕN‰Ã-¸©³v‹êR±§âË1áH ÿ®Ї8‰9Ýp$™ ÿ„å¥ ªŽÍˆ4Ln zÚÅh¥ ¶, õi»Vøò`2Α ¿«\Ù S/;êv½L`‰»œð„ô±æ„MäÛ…ÿòÄÝÚÙô¬‹jCDB¹Ú*Gæ}°%‘ £bÊ”( UF¶Jê¯íSᎊvµµí -¥¦.BçÁK´9ÅÀ‘Ö) ðjÓU´òM­T .m‚ïÒÖk&³ëz»ê˜ ÙÒŠžp1zUÐTr1Á{~•÷Î*ÜÔ>mï§25”&ØÀ‘ñSçPTjxÈ©WQªGeКJ[ƒâ;§bóƯåÔø+D±å ª«["Ô­AEv^¹ -7¯à”©¸þ’=Fò\Òg½©ZWJ¥Î¦ô£c¥{o0:ãÜÙEOâúZ: ÷ÙÑxïÃ×\R>Ý€´ÛUí«ØÁú9x&ì}¸[»ç/}ïfö’sFÇùàÃ×mSòCÆðTžë) ñz`°Ük!4‹GŠ„9žÜšqApÇ*æy^Ë_O²±Ÿ˜FMŒ<:LJCÓ¼-âéOƒ áÒSGèe;f“äŽÁ©Ñ=SJF¼£®bÖµõ¶·ÔZÙ¢¡’<à|2£nàÔ£‚’æØ¯I|à­Ñ /­~Q·qÄâŸdèâû@*p8HÅ{·¾S+àññ:ñ•Dø«œ‘ŸãÄ“ÏæØ_úãŸý ° ”ç'JCNÈL¡"òE7þ•aýßû -õendstream -endobj -1511 0 obj << -/Type /Page -/Contents 1512 0 R -/Resources 1510 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1499 0 R ->> endobj -1513 0 obj << -/D [1511 0 R /XYZ 56.6929 794.5015 null] ->> endobj -490 0 obj << -/D [1511 0 R /XYZ 56.6929 729.6823 null] ->> endobj -1514 0 obj << -/D [1511 0 R /XYZ 56.6929 704.98 null] ->> endobj -1515 0 obj << -/D [1511 0 R /XYZ 56.6929 519.4358 null] ->> endobj -1516 0 obj << -/D [1511 0 R /XYZ 56.6929 507.4807 null] ->> endobj -1517 0 obj << -/D [1511 0 R /XYZ 56.6929 339.3113 null] ->> endobj -1518 0 obj << -/D [1511 0 R /XYZ 56.6929 327.3562 null] ->> endobj -494 0 obj << -/D [1511 0 R /XYZ 56.6929 227.5589 null] ->> endobj -1519 0 obj << -/D [1511 0 R /XYZ 56.6929 200.4217 null] ->> endobj -1510 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F41 925 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1522 0 obj << -/Length 2732 -/Filter /FlateDecode ->> -stream -xÚÍZKsÛ8¾ûWè0ºj„Å“çæÉ8YOMœ¬¢­Jm&Z¢-ÖJ¤V¤âdýv£%Kv²Ijb6¯F?¾¤FþÕÈ;!MnGYn…“Êf«39ºƒ¶gŠyÆ‘i<äúuzö·ç&å"Ou:šÞÆòBz¯FÓù»äÙß/^O/'çcíd’Šó±KeòëÕõoDÉ©xöêúùÕ‹N.Î3›L¯^]yrùürryýìò|¬Œu0<Ä¿^]_Óó«?.ÏßO?»œöKnKIƒëýÏÙ»÷r4‡Ýý~&…ɽÝÇ*ÏõhufÎ)˳7gÿè´†®ÇÄäŒÎë순´9&'—‹Ô@Ê©.V%l-Õ:™.Êó±q6™7«¢ª©ŽíT»«>”L¬Z*»ØcUÌUÍ]Cåý¢š-0VKn­–\»‰Ó–K˜bs®|RÎyMWŠ<l6!¤ÍP¸…Õ¶e®½íj`’yÊL‹âOSÔÈ<[êâR›R"wN¾¢m›YUtåœN¹˜ÏiEmKúš5¡d¦?¥“Tz(/àÈŠ´ÎXã®/^²U2T·DÑÓ’é3L -åMÓ-°–Åqâ ú`‹8[ÝW¨|ùö3OÎû4×p)YRñˆå&´cÈ„i£Â)‘u“òè\åÁ²º«›êX'WuÛ•®ÈHÉ+ò9k vy8Èž •»Q ´åY¨¾.gWä[Á^ç*‰‚ò#Š´uSÕÝ`ª½­’BÞ|"å D :Pl ÀR~,VëeùË¡{Ê3!5Œ›fZdÆëÏòO:.SÙ¾úÿzÅu ¶xrÔOÂX\=ö‡Ç=ÓTŠÌ›Þ÷Y5pàŒ…•ÊŒÒÔ -“‚[@±œÄ¬Y¡¿1Ö&WŒ– ¹àû“·ü¡äù8“ì¿Ä^·;Âr½ –óuDQªÌèï"3ëD\h‹1*¥N «¬ Bc åA±C…¥c‚tôgЇfÎpù˜Tø Ìë ùX)¬ËÍ ùè¡|ÄM1û÷v-šÍÝ#ÒÌûKBl®2÷”ÉiÀ'Ò’ç~h@c³gwGJ%ð_–Ñ`öXFJ£DžtK*œçó^FfÁð!éÓBLÿ­„´ƒ¢Eìƒ^Z7‘™ícâØØH0$Ès­wæql xPÀæ)<¼$¨0”†b­"pzP]W®ÖÉá“"ùáY;9Aj#j=0„#”È;,C¡ÃQs‚˃ê'FEóÚkî‚Ø5ÀÜFÍ;dRnÂ"Ó¾‡bc“)áS¥öqJÀ›ˆfË*@NB÷¼4mAîlV–(:9¬“'ä–‚: —ÈmçC‰M ål”3–c”‡>–àΪ×yè PT‰Ô§6ê„‚ Ã`hHÀ’oÊ®«ê;m:ý£=²€8èŸ j†îSBoiÒU«rÜ5cÜ6QHFYxi2™P€årN”,Z‡O£Ç7UÇM!ïHâ)£Ì5ç,%£ËÀElëªk‡3§igM=oÑD¤ßO™&ëMµ*6ÕòЖó“@55¼‚¶Y¹¶Dº_PŠbp“Ì6ƒ”±¤êdÒb°žÅ$*Uæe;ÛT7%´hlÂ@­ˆƒÄqyª›r0Ñ<Òn›]6d’ B(ÛE³]ö<Ç2ŽyÕÎ -¶ -Ì0Œ’ñPerÛ,—Í}¯Ý‚æàÖîÓºl÷í¶‡ºØ¯>f[Ê€àÔ–lAØ”-Ö܃Šÿ6u“O©ÁØC€R ~.³#ëRa³ÏÂú&7"“™ù2}¼×ë[ðcZ~ ˜‰=bP¿§±•^¤NðæJ+fÆ, Lðwdƒo^AØ´àJâÁÙdY´ÁˆÌÐØ ËÚF“4ÔUóͺ8B]ÞÛ2é«AÐaALÓEì†ÖQ–»l© 5õ-u¤l{6ÅZî\ÒD§ê8eãŒîÍõÕºƒ›]ŒãEÒÐÏ_¿ýíÕË‹«ëx1ᢱ®›º-ÛczK«]‘®}j¶â˜í÷–°*>V«-s£¯‹²‰Ña'.9×î:ÄP¹iw×+f‹~ˆ˜Atš‚Æ âë” ÕÙHïÁ˜òK†Œ=Nê­ñVdÞžP[ ˜ÎsVÿSpV{Ã7t‹‰y?ø%¾W ©bcÑQI—nÀÓ5k¢ û „8y¬‘¡f”÷ÐSî ¦@êƒT¼|jyÖÓZŽ{ ÇÂÃöæÁ)ÆŸã0×`éÿ3RºNendstream +xÚí[ÏSÛJ¾óWø(ªâÙù­Qí‰Hü^bX U»ûÞ;ȶUŒåµdû×o÷ôH–lAaª8l8¨Õš¾îéþ¦G=¢ç ã*ѽ8ÑÌpazã»Þ»gŸDhÓ¯õÛ­>^üíTŽ„%VÚÞÕuk,Ǹs¢w5ù#:þrt~urqØ—†G–öåÑÇÁðiºŸ OŸ¿_Æ:ºœ I}qrzrq2<>9ì ¥„TâßgÃjt:øzrø×Õo'W͔ۯ%¸Âùþçà¿xoo÷Ûg*q¦÷7œ‰$‘½»m3Z©Z3=¸<øG3`ë©ïúLš &¤Q½¾ÒÌYã?«´c1·ü,ïõ¥b‰àzûXÔÃXA¤jc(@0fÚÄhFeX,EÒ˜Qª–…VÌ)ez±LZ01Úñè°ocmñª¤Šn‹²")L‡ÂEYY¢id fô¤ºÍH é:ž¦eùd-àa^’–®:JéVÉþ(cΟø 0u/Ö,1_J  ý?eåx‘² ùE> NtzL`bئ§hp•ØZÙkƒò: Ñ¤ +@=;ñ‚!ë÷Ùn;øQ˜¯ë²Œ™2J“íàßa_k!Ñ{Kh¬ÛM ÞŸsv~­‰½îeWøIœ5æCÖ=¶âg]Ì.T~ÂàcdV‚óoGODWÞ¡ñÙ8 È2¼ +ôl¼§‹*O§¿ @þ䆇†åòýɹü jzÌ&a¸Ùö5Ï&9;®ò"DͪW¿ A˜¥wAz¸Í¨9ÞŠU‹0·ŠîŠëÖf +œ=>ʼnñ•ãã”æÔ²ý6%‚ ®×År6A,yüœg‹ü.›Ué4¨ÚÎ ­óЛœé­ÎÙ¶úë¾8½;4ÉCôè­Ñe7ak¿à¾‚ÉÄt“H&MÒÓyÌÓ?}9ÀIóÄE€~)Z–ˆÍu± Uîmtý˜ÏnHñp›oI„!ÎIOshz„Á€‡ãÅ$tÌ«Ûív¨jƒ¶~&[Ô1l‡¶¯Ê¾Œ§AÉã Y÷Øn<­™V´“Ûa<IÏ%‚2Á§°Š xýE6Ÿ¦c¿‚’8ª ÆøEò¤¸K=f ‡R9ÏÆ´è&¤ð†ñ,º +ÉÚFàv[í†Ô +&M‹â¨-çèe K}¹UtŸQÏâ‡O0Àæ]¹ªgÎÌR.ÒðjÃLš¦¡ÌgZ7$j[øë„ž§%=£_¨ã(ÆHuÖ¦C°/â¡!VÈbÞ}/ ]î-!#ípï–ß¼Îß4GÉ™‘®+6eyˆMÃËßOþöV .«"pdá‰7\æËÑ4“ü#{ ºsðApíU¯2¿™Õxïò¿ÅlqúÛ}½#qµcwІa¿™d¯ÖÆÃ¬p]|ÉÉ„å!]âÖUš5K‰$¬‘˜è6-oIÂu×”ZÔFD•7¢¶–8t0bÓË4FDø„Á((¬ö5ÖkòßMÅ^Ù®vh¬ÒÖÓÎAbô}>?ëA?]6y¡Üˆ]7ÓbTÓÝyQæ¸ý °^.縇Xq¨¡…µøõìx ­™¾c‚«-g1l¸º-“‰vÒ/ƒáé`*œÜd¸" ‚p|þª¹À²AK ‚XJJx’Ò-D1u$ë¥ +xâݾ‚ê¶_õS] yÂiwY¶§°% 'œ_žû„"c¥£s¤Š{ ¶åZ4ºËªÛ"Ä•@€!Ø@P ä×ÀHe¶ +Wú‚Õ—ÝðBÓ+*ÉšË]ÖjÁðžÓ ä‰DÉ΀$Ó±&`—Ÿ†‡}ÃMŒÔ6$¬]PÕÉHª¬ÝSS¹V,Ìp;(ÐϺ‡×½"Áï®;µ_u_yƒÚ´ŠcÆ­í¢cškf¬¢ˆæ—`´ÎÅ ™?OKÆQöiÜ?k¥q¼§4Þêåù +aÇg¬‰¾—uó|GVäM>ó)‰Æõýwº¡éùÑ„4>ˆR3Š4x«ë(Ç#©\4ZVOm.Ê*Ÿ†ü‚3H[‚t9øŒµiŽ•çNºQ6õ³VsU¢vìfÛ†Ûoyy¯+^Å„±]RYÇlâˆ@þþO B‰Ít ÀWÜ\MðÁ²?ǰw»ñ9Ê(ÔåX½‰›:‚Z/ A“]®µÚ|IÅwX£õšï˜*-˜ä¢+þ*ØJÆŽ;Ð6XŠÀ^¢S.ÄÌ&J™c¼$m>».üÁ‰ZÚxo—.` +ábš®Çä­ð¶æýŽú7 ðë +¦JI$áû œÝ$âgÇ$†l"Ÿ’T{;Ý‘³×‡ÞØ¡)z€2„#©êa„¥Cn”C½Þ‘ûÂÝÌ×KœˆîÓé2ˆܦŃ_tŽûªGY´'·Áýu1ÅV“ðô‘®4YèFÇù¨ +õ ‘?n›G@¤‰gîæ’XxÑÉ|Û’ûŠ®o°ž!E­å]ìWÂv5±1E×áÑùÕz†„fÍ©Õ3‰ÀîÀÑ~½w|È y|Kwz¹N˜Ð@kÈ 'Ǿ6äjZ®=dþÚ0gºõŸÀ¶ÇKJ$¾Üï;Lr< ínÓŠ¤‹‹Ð5ì @ÚõÑIñ0CkY§ ù'ƒš”.x›’N6­Dä#Û=î´Ï™a”¢"!û™—ÕæxOd%,&â‘‹%ÆŽBëÝàîÞ ¤‹ ºVs¿SB"»úÆF­]-)¼ÛÒÐtõ“ê?u²@Dì…çd;‹›mߨ×Aì”­³/Yu­.,¤eœ»®Ãf LIÈäµ +°©ú¿¿;Ö²ñað¥ÆT¿¯熋’×T±»£»!¤L +M’‡×åÁ(^®a‚÷0Áò©I,€ñd³å]¶Hñ蔾gV¼à½#V^4oÚqq7_RI*z7‰‘®Ï³Y‰ê èýÀ`—Qá]EòúÛUÑ$0”É.²þLšÕgë¤LÃ0£­Õ¯¼«<õ¶M,€dµ#µÙëî›V—Œ']O 3 ?² +燉ŒŽ.޾Á°¶ 6„»l xͰþã%o6( ª;‚LŸIl ÁÛýD·°ÞëŒjó7÷°ýIGÓp‹s ¨g†ýS¯0|Y4ç,–Öá·…ÌÚ'?\ç½NêþÜÏäWÿU²rn ³TÀLbܧáXˆº›hàWXÆÉ¦UkêÿÈ:0çendstream endobj 1521 0 obj << /Type /Page /Contents 1522 0 R /Resources 1520 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1499 0 R +/Parent 1507 0 R >> endobj 1523 0 obj << /D [1521 0 R /XYZ 85.0394 794.5015 null] >> endobj -1524 0 obj << -/D [1521 0 R /XYZ 85.0394 685.0919 null] ->> endobj -1525 0 obj << -/D [1521 0 R /XYZ 85.0394 673.1367 null] ->> endobj -498 0 obj << -/D [1521 0 R /XYZ 85.0394 537.6026 null] ->> endobj -1526 0 obj << -/D [1521 0 R /XYZ 85.0394 510.2982 null] ->> endobj -1527 0 obj << -/D [1521 0 R /XYZ 85.0394 468.8256 null] ->> endobj -1528 0 obj << -/D [1521 0 R /XYZ 85.0394 456.8705 null] ->> endobj -502 0 obj << -/D [1521 0 R /XYZ 85.0394 288.1559 null] ->> endobj -1529 0 obj << -/D [1521 0 R /XYZ 85.0394 258.1665 null] ->> endobj -1530 0 obj << -/D [1521 0 R /XYZ 85.0394 168.8733 null] ->> endobj -1531 0 obj << -/D [1521 0 R /XYZ 85.0394 156.9181 null] ->> endobj 1520 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F39 885 0 R /F41 925 0 R /F21 702 0 R >> +/Font << /F37 799 0 R /F23 734 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1534 0 obj << -/Length 2208 +1526 0 obj << +/Length 3252 /Filter /FlateDecode >> stream -xÚ½ÛnÛ8ö=_¡‡}šÃ»¨ÁbLêt=Èe6õLÓéƒb3µ[J-9içë÷‡”¥DIºÛ΢@uBžû…f …,QšèœçI–K¢(SÉr{D“°÷戜iDšö±~Zýp*²$'¹æ:YÜôhBaÉbõ>ÕD P éɔ+šžÎÏbB*žžüóø—Åì -7t@ýi~ñWrüœ\^œÎßüzu<Édº˜_^àòÕìtv5»8™M>,~>š-:–ûb1*¿ŸŽÞ É -¤ûùˆ‘•ÜÔ°<çÉöH*A”"®lŽÞý«#ØÛõGÇÔÔáoDPžêZÆIž+9~-M¦F£Í3´ðZŒ'†¤VÔØãFtVä"aŒäJqgF͉ȘN2¥À´Íxá4ì1s¢´d‘Q¢Î=ÆådªYº€ÿyúÈ@“f%ŒP™çqz°õ ¿ðÃ|Ë“×5”ôdŠt§=Â^$Í{Ž þHp» DÓÜx~k‹2iÑCåÀ‡bQ¦¿]^Íß̃ì’R£¨x›²²Íd*rš–~[ ï;4ý\lo7¥Ø…­·UïðÛ]=a*½+Weõ—–uÕâñ6­Ÿ#\‚FÀh”'S4(¯®6_ŸÑôÎ3„ NÓ°¾ªñ[ÕmìÒ6M¼Oe<^ÜÞZ·&CAYäÅm.Û}±Axß­ZJê•}¸ À±}cW^Yçžõµu¸<3^v÷-«U¹,Ú¸º.Ú…¥žN‰¿;»)ÚònÂUú€fwvS6-0âá:ÿ±¬ÈC–:'Ü€'õcéÛÂÓ%•kˆÏCŠù¶äÑxI0‡ˆgýˆxZfÑÌt‰[(¥é%(h‡)÷÷º²!‹—›½.wv šE Y"F -õéPgâvSnLz^€ªwR&OOëÝÖ[V*Û²Ø8_q®ì”òÊÛÉïâÑ«Ó\€„¯*ª€³FRyÚì¯ûio«6R»¶¶BÈ~nmµ²+ç³à#ïÖŽ«ŸDo¹;ÚèD¸l»¹ pƒßå¦h¾loÝUÀ!ØM0´¬ýwÕ¡¬ç®ßî›@ì:¬ÔŽï¦ØÚ/¤Ò)˜ðBŽK#chíÀÕr³_…d -Žu0=àê™fcÙtà#.›rh+ïÕ)ð_ÃD$4¿89ûõõl„’‚ Êøê«Zä’a²Hs±8CEL¹†Â–S !IfT/ ±ˆºŒB áå8xû¥j‹Ï?Žð%QL«1¥©Ò2"çoUo‹²šVδ/׆p)£!ÞP@,‹—.ëíÖù䈥 Ì‚¼#ìOY® ® B’/äà2Ú¡±­÷+Ý•ÑÌÓ*¸.‹™ û£†ç¾N¹H˜5~‹ê ûêTªÒeÄá㸪$ Øpo'ÿ Ù…hf©#²kZôœ(Ê ú"éÂ]Ä$Æ0|}FuaÙ‘ƒ‹°]Bù*—e;U JNfò1aƒ˜ÑÀDô¿#‚ì#d$“Æ'ZÏ}” ±…¦>’úÇSRd,0‰TyôŒs¹ß¡ª1I!˜MvˆÐ§=¨/(jRö}À©»îÔŽŠNåÍ&p!7HóÍ­]ö|ä~ÛõX²ƒŽ€e¹~™ÙAØ^üûmWÊX.ÚaÙð­™Ïf×M½Ù·–ŒXÐDæP§Ðë -2õ¹™jH]{#ANÆÊÛ»wïÀû]’;¹8>wƒšøüx~1};»ú fµÑäÖ¿/ò •¶¼+6l`…ÇŠIAšh£»Êè20éwºàТ„8wv°¼Ft *¤Aš°øW×E¸ïvWº!ôáÑ‘|£ɺà®=†|#eô«ºZÚY7…jb`–zTß‘p”òã…­úÃJ±"O=ÃqµKðßãA,„s˜“¿~âŽ'žoÙû…1NšæßóAŒ©œH-Í÷ëS~úIŒ¹× -¤Ÿ e–‡ ZÚK9 na4#dÇEƒ·Ú{5Á…f]ï7+Ätý¹[ÛÙ¦­w6¬7~ÒtE5ò&''Z‚ÊìÛÂÆÀY{¾?†9(¡ü0J©Òk÷,µw¼Kík‚[téÂ}›[×âܯ->†¸ETÀ18tLžXÔÀŦ©Ãý!î"sÃÉ!¨Éõ@B…Wq‘)÷*.2÷\¼†”ŠøÝØÛ†³ _£ÜâÙð'l\ªší¶·+¤]ô?+ÿªvWÓёҩÇ=šÝìê-Bø“ásÌ+‹€ähÙ¢Ýïüá«Ã{›û:9ž~pëÇê·…ÿ_ùàÆ8Lš±þƒÛãJr -ÄdÿyA |‘¨°÷ÀgIÂ{³ +?”B8Lyr{òÏÕ‚^3u™dÀ|ÆCѨÈçqîß–¶`[ †‰Ç¡ÚÚuÀ‚Ägð¤”Ïùšò\t(ÏXèK÷bX&Ð…”¿þ4jJ&¼ßõR%^QáSyï®oo/Î ×Öôlôd¹è3åéòÑΊIÚj;.O[‚†Ã†€‡¢Í J+dA/–~†ÎÀƒÔ•^À0μ*ájœÓI“Òc¢mJ8¾Å`T«÷iIø¬¶«Ô-úKÑ´Ûëá9‚Í|­+XP„œ3#`ýnØz0ï†ÐpHÏöq®c/%ª~NFWvÂ]½pKÓÓj°y Ò…¢š‚Ü&Ò¼ ˆº”Üò‘ø<^½(¦E…ïŒXâÔÔ ½çe:q“Æô¼6ì´Ëì -3.ØV°À{§›É¢›e@‘ÌÞ¨P—瀇þ¶VÉ0ö%K@ÎÖÂømò-¤òØŠÞ€ ?9¨©O–t3öªL¤¤/˜ŒëL”$¾ +#iÈt3¢‰wt’Ò›×F©š‚Ï0wÈyºh ªïì°\Õ3#Ó“L#ÔÌ}hè€×ïô`—Þ¸æ¼úußýÛè¹Í"ù¢,Š_RaQú‰Œˆ*7ŸúƒÄÓ»1ÚPß**W±7KçsÐ1ÛëöAëŠD6çK€À'8A`qYfջѿߢÕ‰¼é¼ôËòæeÕGD¾LäÖ„ÜAT†,ÃÃî]U`gi[ÔH™˜{î9׋¦®jXRÏQŒKMHcNy,H‹CZ„v+޽‹/°ÎìçN1㜖ϴtŒ©C¼Zá-³Šq?T☥ã +ã²tÃáíÕOà‚ÀØyçu…Î×8u¶vØä^SL«´]:ˆ¨,mS . ‚°K^좃òîe „<@òÎ˼ÍÁTª(ü;ËÍØKó0Žü˜)~„æô9³}ر7BQ €õ²Õƒ6'+¶œB ÅEè101q‚°±yÝ´ †!„á>M8dF¥÷Ú Ò… +Ñ×~Ndñu‚Q”À€.ÓÙ Ã3xØÒzñÙvmZÉrz¹V<«•o þ–W;¨]š_W4d!?¢ŽaGId¨b”1TIÒQƘ«@á-MD”ÓD„)’D©C,¼Š$÷;2] +nE—=˜è{¬±@”‰gµ²§ÐÌ/[дEYÒ˜%žh‡X·aÕ?ƒ0à5×Í:2%ˆ<8¢ÁM‡/%4¯ +…,‚ ‡ …BÁá)‰Ž·Ï0ëq•æ7±PÌÖî³iM€j¼ð=SBYÑFDzÍAhÚÇ>cÌ3.wÃÂã˜ÂºòƒþppÚ}Õ7ìUe" ¶9bàCH…¼•aÈÍ%j±èj± ”×ö™‡ü@øVW™I‡¾©ËbòHðå2kd¡YtC(D¥A ÝŸ1L‹{mFCÐT¸ žµWû9×!É[f\gGì/¨‘E‚¡Ûa? ½aòÉÍøUDŒkcß"å=hcÞú\¡o5àÊ?b£Ñ‹ûbbªÐB×±¬Í~¥ùý—[k‘GsŒXñŒêà çR†±#FOB‡½Û÷—7•@”¹†Æ´©È{H©);"6‹[Ø3_ŽË¢É©;%Üz”•fc×gýø]CX4³ÕücªóEQµÏÕ8°•] +½#ÝaŸ¿¤›±Ÿ‘Bø<„ý0#!›R’“±™úd±Ã¨ŸpOi‰6"­Í3{nÁê°ÇéïÛ^ùu @BB6}˜Š\úJÅ‘3@EL˜7ŒVÈCg´|È‹IŽ`dí"­ýBpe¿p„³_§ûE¼Yâr&³aÙí¯£›>ã‰wJm›¦àˆ®"¸YÎçõ¢u¼}_4-„Lör°Cš7ìz„‰ðH^ŸÄ1Ñò1hco¨;Õeç}” Â"ÉV>¶7`ø¶âH÷e_Š'ëû•c68'â­ ›ÿo–;·)bà„¸~o^ô<¹ð ì„p¯ €¨jÛÝm”€L$à¡5&@ßÕeY?`ÎtþþR$™‘„S* Ûá”I™"‹iÜÆ<ñ¹ŽÐ8ί,iS“O›èöÕ*éÊíAœ 5«ÖxK@ݧe±%$­{Hÿ±-#+h¬¢CÙ×ër4xw'÷“ >¢æ‚™â!©ÚÕuáýЊñWx³š|@Á:Û¼”Ûz…zAYä‘DIÒ…J 1ÎßãýØ®ó<­ Áé:3…pûÃ^ðBðLö°nëI]fbëR­±Yš·ÔñëÕˆF>Aò À¬È@ÍàPE˜v¢C&¨t+Hª08ò•»¢ö|¹˜×ÆWàBM îXo·¿kvFÆË¢l+/ ~X/œÒu+ê€Àä½±¾VûSÿ”¬[‡ô1pì YX«é>Vw˜˜ù±`vì~‘ìðú Wà¸d>³7ðûE„Ãb›¾‡8*b ?ï5)CÒ*i.uÁÌoÑ?^%yÔÈô½.ë9•H]ÊÆF$MΠÍTþƒ•Ö½Bx"[a=/äÊ»Â|/¶1äN"c®!Óäë›isÞMZ¡ß%­ÐwŸ.ŠziWj›•ÙVϬ7À²â8mVö4܃Ó,\ïÔ–°ça²èß*Ó55=A÷‹W‡q/%_o%¤èý•|fHÁ$½X>R°„ùJˆhR°Aö‹ í½3V…Ûy×êÊ¢f󲘭©á*o‘Úkmnâw;¥ÊÜH`Ã!‘ÁÓZ@lÙ;p³¸›nw}.k»²þ’¶Úî9K«Ç],йQÉ ÚüÞV•–”ÅKs8‚ZÒM㌭lžRй= PÞrâ +èÍj;?·S;;ãMý)}•a¯‹¥7É)Q!}ƒ8xkXòŽU™0\2i8²ãåè˜ÑUdæ».¹!eC¨uL&]=`õ¡Ï¼/ÆØ@;ש©'â ¬5á‡+xf)(^´ðhô‹K4Φƒ8½°›Mð¶iÍg-Ø&ºÀ€ÔT@Ì ÝZD i>ÞÁ!h]R¼ÁÝaTH4PíñpÃwôþÙól$‹øvm³`VZ»8Õ…¶«¾Ý1îXaÑ–¹Ç_OAb¿& •ÓÌtJÌÀ’·‘âØ}É aL‰½Ì¨a4*6E'3º˜Ùáe1+ZBc ϼ~°}5íB¾1æ“#hOR;vl—ù¬çv•¢ÚØi’Nrü„$‚j”»cЮ;Ä-«M12¶_N‰ôx>GBœq'ˆ²Åð ÷šºÐD°aÇx¸ÖöÙÅÓ²±K!%2B‚ :źµ»!‚Þ±Û˜¨ëxxgY™[60oŽåñÂ%r—×2«$Ò ³_Ë‘ÃßË*TãoÑÌáì×Sø\­‘f`ê@ Às•XS76"è!×+¼^F8ºÊ^Áµ”˜ƒ®üžåN›ÐñQ ÃS7‘@`¬éiÃIÅle“yxàYñU» ¤Ÿ‰^g´HQáñ•Ž[¯¶!ÀFÙy1¦÷É:Ö62Ë)ÈÛBÛ‘F#áé²™]ï6× ›T«4ËéT768!í'H7vŠPcçõ²´±ÏØvSŒÃŸážMgÉ}që‡ðS…G» +ñ±;,%ñØÀvŸê_WvnJ0øÕt§m#…å‰=Ò»cr‚îM*·Yb%€'“ˆ¦Ù’n]á5±¡^g{˜NgÒ‘lÕÊ”ãÕ¢²åÂ:pbåѺ§[Æ£.ÿp‰WãŠEãtòÙ³]á,72Ûe.÷i¹|RéØ´á´¹¿ï#^U&Áv}sôŽ&÷ÏýÂwý•³Œ}¡Ôž;  ‰Õ©zŠ?9;Do\D|×áÿîÐMendstream endobj -1533 0 obj << +1525 0 obj << /Type /Page -/Contents 1534 0 R -/Resources 1532 0 R +/Contents 1526 0 R +/Resources 1524 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1499 0 R +/Parent 1507 0 R >> endobj -1535 0 obj << -/D [1533 0 R /XYZ 56.6929 794.5015 null] +1527 0 obj << +/D [1525 0 R /XYZ 56.6929 794.5015 null] >> endobj -506 0 obj << -/D [1533 0 R /XYZ 56.6929 663.594 null] +1528 0 obj << +/D [1525 0 R /XYZ 56.6929 337.2163 null] >> endobj -1536 0 obj << -/D [1533 0 R /XYZ 56.6929 640.0743 null] +1529 0 obj << +/D [1525 0 R /XYZ 56.6929 325.2611 null] >> endobj -510 0 obj << -/D [1533 0 R /XYZ 56.6929 573.5829 null] ->> endobj -1537 0 obj << -/D [1533 0 R /XYZ 56.6929 548.3076 null] ->> endobj -514 0 obj << -/D [1533 0 R /XYZ 56.6929 357.2459 null] ->> endobj -1538 0 obj << -/D [1533 0 R /XYZ 56.6929 330.4365 null] ->> endobj -518 0 obj << -/D [1533 0 R /XYZ 56.6929 105.6253 null] ->> endobj -1539 0 obj << -/D [1533 0 R /XYZ 56.6929 82.6167 null] +1524 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 1532 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F62 1050 0 R /F63 1053 0 R /F21 702 0 R /F53 1017 0 R /F11 1367 0 R /F41 925 0 R >> -/XObject << /Im2 1039 0 R >> +/Length 2932 +/Filter /FlateDecode +>> +stream +xÚÍ]sã¸í=¿ÂÎL¬Šúê[6›\ss—ÝfsÞÞƒlѱº²ä³äxýï  L;rv{—¶;™‰@AAÐbŸ¥QªL’LQ(¢ÑlyŽ¡ï‡3Á4G4ñ©Þ<œýåF%£,Èbæ¯4ÓTŒŠ_ÇW»|ÿp}>‘Q8ŽƒóI‡ã7·wo “ÑçêÝÝÍí¿Ü_ž'züpûîŽÐ÷×7×÷×wW×ç¡t$bÿ|wwMD7·?]ŸÿöðãÙõC/²¿,*”÷÷³_ G¬îdz0PY¶Ð‘er´<Ó‘ +"­”ÃTgÎþÞ3ôzíÐ!5E* ¢T&z’jHOQÄ +ºPO Ë…y—TÖøãÎuÝ¿%ýà¿KBµfÖ•MMfÎt÷-,[BÌòõº45rFò,³f9-ëÜq=Ä®wé˜iæÔø}cê®ÚnÓZÑ#¾Ÿ¤Ô«¦¬;³n&l×з…­yJRfÄÊD"'ÍÛ»V\0ŽðŒÂ+Áî‹' þ†!h^16_ºM^óeµ6mKʋؙ€˜«CæR™Ú2';eÒS4^ѧ=ØÕg‚–½až7ë%AÔ뼫|öÙt<ƒ• ¾}/,Ÿèi¢¦kfMuq>Q¡bCß\›V]í^ÒŠ1à‹òqa‡ÆÙØÔ³¦ gÌœüI8Þ.LM¸¶kˆ/Ó”ŒÏ郮CCZ³~²–lÃ_–¨©°ö „ 'ãÛš†ð^)¾äËUe}Z¬„§²8žôþæŠFBчk#ÉQi¤ÞU†ÁrYV ;Û@¯´ßEÞ!$ØŸ‡“àw™·aúOa(­\ØØæ ¶Ù#=æ`*1nÍÖMÊ"Í0QÝ17ôü‚‚~t[ýЀ²2 Ú)ïÀ?¤ŒÆË¦…¥H˜š‘·x½°Lò¿‘÷÷·Ü“ÇQ§æ±¬™å¶ìtVyýÕÆéxk Ï\2‹¼m7Kðu‘qjŽ‚`K{É ­ä¦~(ë‰y·?•ͦuQ. à JK ³Õqdoæ©],žU›ÂõyÃÁš¨ó"Ÿ–UÙíl¬´ÜMSUÍÖ÷699¤ØôDzx¼e|U¢¿><ütÁ¨ÝÊ0½{ˆ›U Læ9?i׌ÀÕž¨ˆÌ‚M~4pY›eS—³vÈB…Á}_÷gô´y²›#vÑŽX™ƒþ æcöö#¹ÚxÞôz÷³’ !œÊT®C +xî%o?5¥“ +2…Ç šæ ?͆;ÅµÓ DZ†ÒN¹îUb›{FQ¶ÿÂ#Ùª?DÅKo-U²Ÿ„V­Ú› [é¹UÛ|Ç0Ö¡RBÍÁènï|©O® Ü—ÌÀS^m¾¶šeÙuý ÓgéRŠþdÊ[lÖC‡\×îTq}bã$~ÈÓý)¹±ÀŒ±.õÔ|šêç§ö3NÍQÏ©ÜÓw¿nh`èä.Fø¹n¶•)Í V`¹rfó¬^`/ß Óaø¤:Ò.kP7Ž”U~A­-[BÒ±NÔ®tôE~r홋³NHrÛü±±=¾§% ÷¥Q&pg’ò[n**ƒ8–ÑáMår‚xJ<) ƒnÄ!«I¿¨‰Î¢@€²Ý5Hû™¶PIFQ6Òp_L„Š­Mn?Ü×om«4ÿüñ|’¨DBúHÁÿq}w}ôdG +Õ™­Ò‘7õŸ[ ê <𿣟n‰H‡$uH gžNã ‰Rº4<×ÈåÇ^§ÕáÍôªú¯ªîZ"þªÃ$:HCEçC‡À\ÜbU’¡Žddˆ$OkÆ›ó;ö”|!ö* +'<%–AªùîÚ+&D/èÀãþë@' +cõ5ïˆÂ ÍdFÞáoHò|ßIA-29­oÂïxÓ¨(P‘_s [A%é¡k¸ý¡N+ÁcÿJJØ×ÐþGH`A:ËF*‚09,æ=+êýƒTf èŽè4Ñò增J³}Çæ[J*´•Ô”4 b‘?q&ñ¶ë0Õ®>ÕÂÆvQÎD +ä¶´ÙvØŠ´GìñdZv„ª7Ë©-<·—&[AªéΤúÒva}ååB^^œˆµG¹½õxù\­ë‚rANnߟàA†ÃJVò£”JIZ_Ÿ צ{Æò…ì7âÛÕAæ·ÏòXš¶üÒ/Í¥…tEGñ¶ÍѺà&Ÿ-ŽoÏ$Ó©èà÷\t(!5æy2)ã àˆ’äÛvXö‡vXö¿J&Ý¢&JÀ et*ü+Sþ•À*|FGàÇÁOW‚Ÿo8©„Lw:Ìœ`›ÅÙð$À?­ŸÁ‚'Aî?³×> ÷ +UêäÄ)#‰6 AH‹•Êø}Æ×…ïU…X89ÂÓJñ¦{%¥ü''Ãëû­H2ÈžðdP2H2‘}ãÉ kÅÙË'lÛ Y̱¨l_Ž@}ñšÙÇJz]8܉ „‡¾?ðW‚8“_œŠ`w‹rŽRÌ«¬ö5·ö!¥?/æ –( +RPâDCªâ½§¸×”·e;Û ¼àai£«™5ëâÔ;J$Šwù¥-ÃÉqaÚÙºœÚ3 g\DSÙ>î"žž xLÿØ@}eMç»ÐŸ3]Þ- £¨4¨Š)ØKØWÕZ+‡`õú£é\( òágkSÂZAÙZ[WÎ6öuÁ¶Kc«7Šßí”8\‚:m6h-:.® ` )á^VúF!'–% ក°ÀtAõ±)±†Á TQ»¬•Á’$?MÛÁ ß²„³$À·¥-|aò"ðícGhû¬!ìÛ™e•'¤cˆU'l¢œØÎÝ—îVÖ'³ÊË5!‰…²Õ!4ŽLyï+ÐK*A4 +êcljÒše`©dþÊ<åv§h[]Û,Qk:â¢! Þº ÍIö4ÖA(Ñš¶¦•+ij}dj@ØÄ ¾ S­˜Í®í̲e äKKz€ÀÉè]ASÑmÀïùÝÞÅ*QûÄ‚ŸJT_œPàGÎOȾ&¨Tÿ5¯¢d +¡u¦?Å—NÅî_Æ©ðG‘bÏAR[¹D¨]¡f¥­qó Ö˜ŠKáÏÅc"'%}Vë²±ÅTBÖ…ë*Þ;‡Ñ gÏöð$éçñÒ±¿Î–ú;Gè¿çA“xÆ}ê(»z=õ mK´yæ^u¦@ŸN„sS¼À&pZw_À‚;*pÍõð˜±TƧtóšl0ĶW•O]õ=£÷%ŠšcXº¶‚’‡Ï &PHJÇkÐv³¬\Û›?…(ÃŒ] ·swü¥Oݲ½æ‡‚Q/qÚÇðUSü”Ñ?–§zLJGº„*û^Íü‘ÂwnÅ4óœ ¸eå³Ï<®á¯cY›/Ì£"Amàî^h^¿áø}ïB8„ìÔyÑ ù$…cjtÓ”2'Þ*Ÿ¶Mµé µ–&¯©(4Ÿ¤L ’:ò^Q2;ŽkŸx+&tJÄk«›Ô.©øGÚó½gå ì¤ò½ßšèx{ø‰Šü]ÎÀrÂÑWsìoýùÏþ'PXJÓE€>%d¡Ðé³ÒJÿ;¡ç¢ÿ6³.ùendstream +endobj +1531 0 obj << +/Type /Page +/Contents 1532 0 R +/Resources 1530 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1507 0 R +>> endobj +1533 0 obj << +/D [1531 0 R /XYZ 85.0394 794.5015 null] +>> endobj +494 0 obj << +/D [1531 0 R /XYZ 85.0394 729.6823 null] +>> endobj +1534 0 obj << +/D [1531 0 R /XYZ 85.0394 704.98 null] +>> endobj +1535 0 obj << +/D [1531 0 R /XYZ 85.0394 519.4358 null] +>> endobj +1536 0 obj << +/D [1531 0 R /XYZ 85.0394 507.4807 null] +>> endobj +1537 0 obj << +/D [1531 0 R /XYZ 85.0394 339.3113 null] +>> endobj +1538 0 obj << +/D [1531 0 R /XYZ 85.0394 327.3562 null] +>> endobj +498 0 obj << +/D [1531 0 R /XYZ 85.0394 227.5589 null] +>> endobj +1539 0 obj << +/D [1531 0 R /XYZ 85.0394 200.4217 null] +>> endobj +1530 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1542 0 obj << -/Length 3049 +/Length 2721 /Filter /FlateDecode >> stream -xÚÝÉrÛ8öî¯Ð!¹ÊBc!¸ôÍí(O¥Œ­éêšt”HÛ¬¡HµHÅI¾~ÞøHìžt×T}„åo_@1áð/&±f\%Á$J¦¹Ð“ÕúŒO`îí™°kfnÑl¸ê§ÅÙoT4IXÊp²¸ÀŠc1Yd§W»ü°˜ßžÏ¤æÓÏtȧ?]ß¼¦‘„š«÷7o®ßþóöò< -¦‹ë÷74|;3¿ß\ÍÏgBZeAüëýÍœ½¹~7?ÿ´øûÙ|Ñ]yˆ–à -ïûûÙÇO|’v?ãL%±ž<ÁÎD’ÈÉú,Њé@)7RžÝý£8˜5[}dÒ*f:–‘‡NRùè¤*˜B:Ýå- “ðiû˜S'ËïÓ]iGçZO‹uî~%rZSÿ]ñÙŽþÆ5_,ÞA#hà¾ÞR§Ù-›ü÷]^YhÛsOóUmÚ¬¡Á§¢}¤Þ®Êòß8—UžÙóï { øô<:-‹Á öÄ4% 4\ß÷Èk€>3!X¢µ4ÈnÓê!'îñ™AÄ* "iàbUçÁF œPÁD,Q26`^ÁévÕ¾2dq [pQÑØ!J𳨬ˆ½¹¢ŽT<îÏìn{?™9x3¥™<4`QCK·âüsÚ´ùÖÊeQZç_Ú¼jŠºúñ|¦„c1L¼z;¿™ƒÐIVš_Û|Õ"OôeÀ’@$2_«6ýò£‡NpQ-ÂÀR`|ŠY­‡`CÅ8WÚ®ð¦|l<·Ð’Å\ÚÕ=ðS"ràÚ¶ôÀp\¤5Ÿè8¬„ ©C»nU¦ïF2aqÜ;„¢áƱˆöëÆâ·õâ»e¼ÁU½^£by %Æ÷ñi¦xÂT”8±ŽŽñk7”,Ò¡Ê·ÔÓ]cDz-ZNW¤‘i›ÓxJM“o‹Ün2z --­lêé¬rph&úcÚÚÍUù•zYqKîèÃï{³£^˜<]=Ú ùvÉÒnM+j Л´…£ÀøTæ°’gIæ?Ž+W`9ˆæ÷‰™´¨¹¹£ön~ûËüö›ÿzùó‡wó—2¢î+j®n.¶“¯÷Ø!FÎu ?§%¹Oø L~ÚÇ–íºcP³'ŒØ`%¢C‘R0¥Àó:baƒàP9¢€8D¶tñh´#ŒÉªb­*¶ue:yhŸjê@@ºnÐ`ôÚtÛΚ¶ÞØ][jûñ –Ú04ˆjzí@=ÚC0˜Û6­ONð ?R`hÑÎ_ Ý¯›àAùf¼¬¡T6¯ƒÜ·ùº^ÖeCS˜¶GvéÖ>éHUBYØ~š‹BºH»)²œÀ÷i]èH¸)Ó… †q&>‘r~‹±tÛ˜IõÑù¾t—£Õ’.•Åñ‡¼¥NJÍ+»¹¢¶ƒVïÚÍΨìýZïh´Ê)ÈR6ÈRÀìUºÉûÍþ„rAxƒjÈ]6°C@™˜;B³LWÿn –z¤­š ¶‚¤£ -ÓÞÊ—"°$.’G„€"9{``…F¢K™*2XpBÄF§a%ˆ@»|tÿ™p~ -Öˆ,ëô+Q£Þ`°˜–¥ýmÚ{åúÉðGöBƒ6% ‚½¨v]gZw~‰ O&*­}¤ì‡Ic”1ù0Ö÷Ùné– 3 $u¤ŒÉËÌSdí#uÑ{Œõ2mPl#Lôá’çbÚß3‰zUQIBÛÒ5²Q\€9Î¥öŠ•P8a¹÷’y 'pv¨ |xv(Mߘ¨ˆ’I×›2¿ð\)ÔL(­ŸÃ*x)V3É/ÔEæ3 Sê#@RiY.ã‹Fјå-ˆ &²’Ë©äØªaÞÎ¥µ`xµÛ’h›fŒ’BN7[õfo‡õµT¾„‰Ô.Hi:ËWÅ:-iÌ8¯~î[N—˜yÃ¥4Ë\vÛ)/þ0™æN‰¥S¬£7ÕÏiQ¦KW#B}“R·÷u°½¿£¦Òª×LrÊ®¾ù*ŒÇ‘è•V\Ø+¬Ú´´ü‰À´óXŽùsäÈQí©ö•ç˜V‰ˆ&-¢Øíá#ˆr‡Î9(NX :…ùâµGAÐi3(ŠGá!"ìaüê ; ¼ä]¨g -Öx§ÝfCb°}F$LާŒ·2 ºâ8þè=¡XøŒÏL€ú„(ªÏå‡âܯ­H«N6ŽZœ``q´´‰NpÄ -+E0ýl$§“QyàUuKtÙÔå®5êÛ'TÁHÉ}œFÉ®¨îj=œ"8]F{§§ÀÏ -5—øE½²Ábm«+®:ޱ¼7Ü6VYIµ×MÚË¢,Zqö'ót[F$`KiX'ópE,N’ηùœ›P ±Âš¶ÀÄá»4â¡*¾Q˜£Ñö¨²Ây_pC<Ù¯b®ã}ÑÙÒ»‰V¬õy5.çu"3vkëYIg0bÎ@TçV¹pF?÷RE"\Û¤`ÐiºS3w*¤}göd¤¹Ì‡ómÑ:g³±R€»rr4îK«•{Ù8§»2?úˆ6¾c*ã:qᦈ÷Y‰ŽÔé§ LSrX‚¢ æ&ï*äC)Ï ûX€‚N$Ïû׿¼äèÏ*•üânŒψ»Àçäà$“NÉ»vñ˜Vv¿£Hi07”r÷H¹ˆ\¹–ÛŠ¬\§­yØÑÊ“ÓoXüó˜ìîÀ`ª6sUöÞœ[ñÿ&¶Cyø³ÄV*–œüðá¤Ûq\lÁ5ˆ(ŒŸ[K‰X÷o­Ï‰íeK2¶±YƒI3”p©;ÌÐK#Ùw3ãbaá74Ógß0þaq{AÃæUà‚F_wýxzyá-äÁŸõÕeìÍÝ Î Hò}dÔfíuþ€Ï¶;ŽsNk&¥xο -ã;¹ýDbK¹ãc¯ä ³1Ðtï# ½dõ:u -AQœÉÄ®÷4ž^¯ò¦qjÔkHÔ¶æa™^ÚÜ—'¸0@ïûHÖs¡ÿÌçñ„!Ž€Þ³ `B‘ipß|w¤8~±˜üòÑ8<ýÙQÓçT[Ïýö$;9þùˆ<ü|ÄEÏ™}ï¦oXFì¶ÂÑ-“»ïböTŽB)tÛŽóû.j ÚÉHçí®oôîd+.ÕÇô>¥y2Ó$"HÜ â:I¢AŸØIoÞì]¤{®Çß¶ÚI¿ðc¤1Wï.ïîFÅŠC)v\‹ŽŸ—y¾+ã“gMÂK¿bë¿ä L­Hú%¥({)¤R¬ôÏ}îvxõÿA‹¬Àendstream +xÚÍZKsÛ8¾ûWè0ºj„Ń Á¹y2ά¦&vVÑVMm&Z¢-ÖJ¤V¤âdýv£$%ÓN²qjW`£ñjôãk@j"áOMl"’Lg“4‹…•ÊN–Û39¹ƒ¶_ÏóLÓtÈõóâìo/M:ÉD–èd²¸Œå„tNM«·Q"Œ8‡dô¯ë«Ëó©¶2z9ûjÊÄVG/þ~ñzq9§†„Yž]ýB”ŒŠ×W/g¿þs~qžÆÑbv}EäùåËËùåÕ‹Ëów‹ßÎ.Ý’‡ÛRÒàzÿsööœ¬`w¿Ia2g'÷ð!…Ê2=ÙžÅÖ(›³7gÿè´ú®£bRRh“è9i3&'›‰Ä@ʩʷì>Ñ:Z¬‹ó©±q´ª·yYQÛ©vW¾/˜X6T¶¡Ç6_®ËŠ?ÚšÊûu¹\?`,7ÜZn¸v¦-60Åþ\¹¨Xñšf-Š<lÄÀ6eœjØ>na{h˜ëh»˜d–0Ó:ÏÓä2O¦±u±‰›L•™µÚóåMS/˼-VtÔùjE+j"Ðײö%3ý)­¼ *Ð}yÿ€¬˜Aë”5êêâ«cÉ#VuK•æp‹ƒþ)¥^–EÕ +¿P LEf´ó |égH\”SÁÇ‚U:·á#ÕQyKD=-™>ý¤PÞÔíki', ª¶ˆ³U]…ÊWŒ1óäþ¼ç.%J±ØûVàcó?m‚?%²nRI¯ËéLØT¥ÇîèÿëÖ1ØÔ£+ ~Æâjèq<Ô4ìi +ÿ‹TÙ´óu±jÁ¶c"ÐÂHöu,'±¬·è^LG3ðèFK:(¨¸HÉói*ÙU‰£.'â³T8«² /Å}ýîPŽ*5ú›,IDšÈd\` #ǰ˜+JìT)jŸµ² +Àxzb#PÕ¢ P•1Ïé¨!Œ©?1(äÂiP2bTOpoñH±G¨ŠK»rMMª„K”>†^W"j-J- õÞœR7E³ËeQx@håP®V>"¶´Á€*ÄÖ;Ð1©i¡,è‡BBËh¡{8+ÁU§òÐ §‰ƒc‚¬@(%Ó.o4$JÀŒoж-«;m±ø½Y`H4²Xžû‚€Zµå¶˜¶õ·M’Q°\ÍçTz¹YÑ%„ÊáÓèéMÙr Å;’x€rǹIÁ@Òsчªl›áÌ @×e]­$ÑwS&Ñn_nó}¹ùÈ4Å(öö˜41¼‚¦ÞÀ¹6Dº_S*bp“̶„Ô° ê|Þ`ˆ‹ H Uª¬Šf¹/o +i]ßSeSû€Z ãòT7Å`¢U ÝÖ}Öc"/B(›u}Øt­³Ê ­¬õ‚ýÁ{‰X;ÃWp„‰ft +‰ïH¤Ø˜·TÒ­ð´õŽ(èw¨…=t‘Gƒî o—žuL…Ùi·ùaÓžø¼N!Š>òÏùÆõÀC}h\]w›²<¨)Ú'”b ï¯;Âo©¯û?©x¯i$»… );Þ¦&ºÌñ>UkKÚr„ +]ob-§‚„‡ß •äÍ´e@õÞ#ÂGYpÎç&á&iÛ¡›{ܹQ‡m/'{/'‡^Nò^Øc'÷^å0”ísiÀç§>ß"–ª w +*ò…©ï©Ò>™ú»´&ñtáoá3E®#óW·á‘Dª‡ÄUq®"¶qÏTƒL$Q5™±wDõán}Â¬è¬±× OU|ØmÊeéñÒ7«~¤„¼ 6qÖóãH +q‚TÕÚȱÌÒNçÒh<’0Ïƒä æä`V¡ê²z¾Êw»>ȱÏ^¿?1Ì Çd2¼¶¸¬Gׇ¶¬+jE·Ý®½÷Ž’d öºÏ«f“3´ôñ{Í^õè%ÃðÕ66à¤ìñ3 +ÑžÂ6,mETýHÝ0‘èÀÉF¾ÑœEYMýüi‰|¿ËGäb ˜‚ éj÷åRÊTŒK¢×‹9UޝÓ1«HµŒ.Á!•>\9zU@VŠkžp²ß|4O¡a›¯Šã‘6 IÌé¶5=8M¦aÍGѰ)ï*Šcy…Îé>ÏO ò4Y¾"ŽMqëy ¿8èh_Þ­[|Ëi—@¥2€Sz·«›²-ˆÜOäÃXÌ Zþ‘(¨X´¢à¡û\ÚÍ!ßø,{ïËv:† Û¢ò¯.˜Ù~rÉà ¿ Ò›‹vBýâ§ZȉzjÖ/lPà"…ƤÜÀ 4pÌ˺™@z¬»"{ô2§¯Y뻉FÒ\sâ=Ž8íîï1u‡÷] Ræ.½*¯.¤òŽ”¿ƒi|eYPóÃwÅâ._§%os"²×]p .†rPìóôÈÇ¢û77#Q£Ð•øSWJÕD[pþånÃh3P9±D"ú;¢,¨TüdBÂ|ëœ9·}šîùI+` “ß§c“ð{×0ø…•Õ¨FäðvpKöŽ/£¼ÍÿôX&­0“¶:þ 3ég»î¨J´ˆ³TßN3U˜J;CÍ?\Ïg¿âE´UFFÇÆÐùðQ@6œëë–ß²o +…?! ˆŠ<ÂùÔ¥ +”IþÍÛVnëú釰N0ý”Ï%—ï¨B¦¥ôÄ÷8PÕJ¤Àî)>š,û9‹œ|ò¨?÷Ç3ýˆ`uÆ9=Ž‹;ü PdzvñƒŸö„_Ù0×`éÿ‹³ endstream endobj 1541 0 obj << /Type /Page /Contents 1542 0 R /Resources 1540 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1547 0 R +/Parent 1507 0 R >> endobj 1543 0 obj << -/D [1541 0 R /XYZ 85.0394 794.5015 null] ->> endobj -522 0 obj << -/D [1541 0 R /XYZ 85.0394 713.4234 null] +/D [1541 0 R /XYZ 56.6929 794.5015 null] >> endobj 1544 0 obj << -/D [1541 0 R /XYZ 85.0394 686.2623 null] +/D [1541 0 R /XYZ 56.6929 703.0246 null] >> endobj 1545 0 obj << -/D [1541 0 R /XYZ 85.0394 478.4096 null] +/D [1541 0 R /XYZ 56.6929 691.0694 null] +>> endobj +502 0 obj << +/D [1541 0 R /XYZ 56.6929 555.5354 null] >> endobj 1546 0 obj << -/D [1541 0 R /XYZ 85.0394 466.4545 null] +/D [1541 0 R /XYZ 56.6929 528.2309 null] >> endobj -1540 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F53 1017 0 R /F41 925 0 R /F14 729 0 R >> -/ProcSet [ /PDF /Text ] +1547 0 obj << +/D [1541 0 R /XYZ 56.6929 486.7584 null] +>> endobj +1548 0 obj << +/D [1541 0 R /XYZ 56.6929 474.8032 null] +>> endobj +506 0 obj << +/D [1541 0 R /XYZ 56.6929 306.0886 null] +>> endobj +1549 0 obj << +/D [1541 0 R /XYZ 56.6929 276.0992 null] >> endobj 1550 0 obj << -/Length 3201 +/D [1541 0 R /XYZ 56.6929 186.806 null] +>> endobj +1551 0 obj << +/D [1541 0 R /XYZ 56.6929 174.8508 null] +>> endobj +1540 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F21 710 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1554 0 obj << +/Length 2210 /Filter /FlateDecode >> stream -xÚÝZKsÛ8¾ûWè¶rÕˆ‹ ‚Ç<œYOÕ&3Ž÷²³s %ØbE"5"eGóë· € DÉÉćTÊ%³ñn4¾n4Ðà|’©D¢˜äEšdŒg“ùú‚M ìç îêÌ|¥Y\ëõíÅ?ßÉ|R$…jr{õ¥¦5ŸÜ.~Ÿª$M.¡6}}ýþmq9›~¼½ÌÓé+üw{ýñöúÍÇËYQh1}ó¯W¿Þ^ÝP-5¤×ü͇÷ï®þÏëàÃ{ʾ¹zwusõþÍÕå·¿\\݆ Ä“äL"÷^üþ›,`®¿\°D:›¯Ý˜y…ö­Q–Rɲ„Mm|îD³.[P*Z Y¯¯âÔ"Lû6Í0ÉiÀ§¥©GFR0Ñ,¬ÚH×VŠç½hXݼÈ.á—x2“¶1-ô;°zXg$Êûή^æm²ÕÒmY·÷>¿q_Ë75ÚlVû Ó ª¾ÊnfÆ´žÓV+$a‚¥~4–öº ´Õݾ’·ŽH-º6fÑ H%BºYØ¥—(q—27̶u‰õÎSV_Y†byDÞ’ÊBB©!Ò±Óë«ãÇu±Û½Nà €\e_§›…æòX7A^­¬uÏA sÓ¶$+HAyí²Ù­D?à¼2EF ÒÎXçv†DѪØM@ÃÒWóå RN˜¯Ìr}4q‡“;‡'”­lÆÜ¨Ñ–9c^¬˜»ï«)¦7ˆ‰¯”$—ÙP’ÑeUlgBëDgààûjÕÁÌ–(x~boQ"Ñ…äÏ9`úä¡ã}îZÓö½[¢6ÝS³ýD‰»}ç²òä¬SI; K<6ÕÂõAÞÞ|Yu&ìô³…Ù˜zÚOuÈ'°µWÕC=£ùkp¦…<ØqÖ¶‘HÅ´mèÛ-K—Sù/ªd*­_„éõ΂(ôÉo”/ß4m[ÝÈÒô ïTÖÇHíŽë·ÛÔm·©Ûná Âs%UÝV ãy4ÄR ðpìƒÝr›ë¶{°íkÐ,¥9ÖJD­ -ò_!˜)Q^IYÎ¥… oÐ0×ú°Øp0`[’Œóg£Xz„èÔú×0Ⱥüd¼ôòÆÌ»rþi·qó¹ïù±AÏáÀc—K«Ö©‚ÈγtÌ EýA0(µÓõ 6~Lý‡§[ mp8#§×µ$Øž‚»£„;¥p:SRû3ª;jÅgTlß‚“qêx¥•tZs^µâö„ªÒ`&:øµ”»jì> -(WÌiûÞm~UÓ‚‘VNY±$xÌ ãzk HÎÎÚ6„ù¾œûBò©”EúÖåYI*ô5;×ù·Ê„»ø^EĨõó”=LA‰ŽO9Ê”®êùj·ðuí4RkÞìjØ?;âUÞ\õd¹ãx4ëÀ×I*hÊ ¹!áZLnmÊÔû~·ò' £Ã‘;ÕÃïΖT;^* ÐÒá¸j¸Ñ¸®XpÔå¹ÞKgl¨0¸OͶúË÷08T—ûfµjž‚ûþ8öCN×àv$W‘«I*³D@|ÑõOr¦†·#«‘ç5 -vê³×3ÔŽAWŽô-†]ÍüŒf)¬zŠNQ¸y‰•XAkÃÄÁz1!¹»)ƒ„vcþÜ™–nXb™I–'™ƒðmL‡.ŸáZrthx6d› ”Óz·¾³HÍɈc^ÕÏ Roߤb‚§› -Bã1¢/¦$¯ŽM?üúæÃÛ«c1 s*ø ŠÁ"É&³þŽíA¥Ô°[æ"{•L$9OÅ*Û™meNƒ2à¥@yžé”1×”2—”H[Ͼ=(1õ§›’MØ= ¼ í7ÛoÌi0¾œ¾0‚‰Ö*ûšù'Á˜±¤`ú0Ê\')Ëè2ùî{h¾ŒÑ߯sƳL0¸¶`L`DÁh¿aJàŒXdÁˆÄ1Ec&”#Q­=e"®ól¥¡ìþʳÇÚ¬Üåe2ù;Òoø ž0 ÉX¾˜¾3X¦/ KØO(ï3°„Ó„–˜òÿo¸Ÿµ6ÃÔe=7_ŽÍhÀÃæÙIôØŒg1À¦`Sy>¸ËB¦ÊÃÝŠ¢¸™á3’G³ÁøžŠÜiçݲ=uÙÝžAô‹Éîv8„RplQÏ Z2É„¤óñß¿Äñ/åsœç;€xÀx âT¥ˆS•y‹µÝJ038;{êñ³x+`ãR9§›ÃÜÝaR†w.0uì\Ì|Ð4ŒjÇßô1^Nâß ôS°F‚}Íöä[œ„>8–«g õEV‚Þ€Óé ÐÛ×îNâ¦5gn$âA¾ïûgï±sNþ6€/øÛ<'òÜ,½¡Bmi¬DŽ4æ`ÄvÓ´£@­ºê«eON3 ÷=”˜K1T,±÷w¶ìøgPEë™c j\;¦^mׄ{;©)Ôˆ_Ò/ æ´$Hb`ä®lá :˹ˆ}ô1¿è+´éÅÖðûÐ&%rž?i¢Šbðbêèå”Àc›–ø¦%ÐiqwþáOAlL’”_a¬UÀN~×ÚÛnæîÜáçüuÈ þ:Òñ+sa%øÎ›ÕÊ’˜¿Çž—ÍSMäÆ÷áƒÔÂ]¿áC¡Ì…élÓhØeéÆ ¥å®[6[|*5ž0î’§>T‰lÌÚsq °ÒJù·t™Œñ„.D\(ö¤cíÎ’þ¹ÁÞŒõêèPŒ€2€þ·Æ pp­ÝoƒXZöÏ‹x.¾#¨º%e‚ˆªƒÇ~A€°êd ­N»è,…¼8xuíúnt›—6œ:¸9?èÑy„ñ+(8 u!N}ïŸ5„æ¾Ü­ºuw§ÍT¸•ðýJɇ/ËŒðÔPFwˆŠ@Ò{°ª öÈ(ØÓúÈñ …ŽA*¦jWRµ¾7´o²Y•”ÇÝ3Ia'ÿ&í¹øöÄJJiˆrQE¢ŠD^Ü`-ØÇVã}Pÿœ‡'ýDfý»¨Cƒ,‹>°_c͇Ý6„Ý´{„ƒV™»TǪ‹þ` ¶¥¯{ÞÖtÆž1¦jåŒjÅ7™Jã±Â7"šžvi1T Èž/˺6+*t/i4?%‚4ÃÇŠc¸nÆ”UgIž µ1.h¯iÑ-[ƒµÐ„, •CF¤§£çuP÷îÖ˜SoqU–H¬ƒe§¢íĈ›±—ÇQõÓ¯d]o -wù—Äìä!+œ[ñ¥1/G›Q¨tž…£¾¬%´ŽÈ €]ÅÄ#c²ð:ø›*÷Ds¨µç>츎)d^«#Îý‹æcÖÿQ(Tendstream +xÚ½koÛÈñ»…>ôƒD{û$—EQÀçÈ©~\]S\.hiHG¤ìä~}gvv)Ò¦í´IŠáhwvvÞµqø'FÖ0®2=J3Í f´ÜñÑGØ{s$Î4"M»X?/Ž~:Ué(cY"“Ñâ¦CË2n­-VïÇ'ÿ8þu1»šL¥áã„M¦&áãŸç¯i%£ÏÉåÅéüÍoWÇ“TóË Z¾šÎ®f'³ÉT(m$PÄï—3B:ŸÍ&¿Í-Ë]±WÈï§£÷øhÒýręʬÝÃÎD–ÉÑöHÅŒV*®lŽÞý³%ØÙõG‡ÔÔâ[Lq#¾êZ!Y–=|-å+fû -:ÇVã‰>©ƒ€”´ªµ¢T#!XfŒD3fœ¥Ž§Æ€i2ãjØcfÌ$Z ¢àÌ( œ{ŒËÉ4ãü/Çì4µÖR¸Ç*‰7>ã:Ëát`/êA~á§ùVŽ^W Ш#S¤;íö"%²ã˜B¦Œ§®Wœ%<³žáÅÚ‘P‰êàJ`Ĉ(Ô_.¯æoæAøM­™5< x›¢tõdª2>.Jú6@Þn¢øøs¾½ÝD”|¶np«ÚÑÛ]5f|W¬Šò#--«²¡ãM Z=G¸ë‚Õ8h„,JÖ«ÊÍÀ|ü‡”)AHBòqX_Uô-«&néê:Þ€§"Ïoo®)!HPyÁÍe³Ï7ïëü£Cq \µæ^Ù‡ÛHÛ×nåà‘uéY_;Ä•©õ²ã·(WÅ2oâê:o"–:: 'júîÜ&oŠ»‰4ã4Û³›¢n€WAøEÉ:´ÎR–(ðœn0}[|b&0Y’¦‡ómÙ£òše¿ yÑ ùˆ—èBZP|`®5 Îùø´£tû{Uºx‹M€^;·Í’†4#…û|˜¤êvSiíø<Uï¤l6>­v[oQX½ÏkвhŠ|ƒ¾‚?WîÎeéíäwéèÕé -@Æ7åeÀY©l\ï¯k÷iïÊ&R»v®$È}n\¹r+ôYð‘wkäjÀ'É[@îV„ž6Z.šÚmn\Ów¹Éë‚/»[¼³ ø $»‰†–•ÿ®Zô€õÜõÛ}ˆ]‡•*0Ðò]ç[×á…µBZ¦•P^Èaâ`ibŒ¬¸Znö«LÁ±:‰W«§‰ʦ=Ál*¡¯ ¼W¤À­P‘Ðüâäì·×³J‚(•J¤¯r5@Rj¦”M#ÍÅâŒ1• T¶ŒC)ÍRk:ñÀDˆˆEÔeª/ÇÁÛ/e“þë_Ê0#’ÁdzJK™R¼UµÍ‹rZ¢i_žX&µŽ†x?@M±4êmYm·è“–‚: >ð> °?Y¤Â>ˆüI¿d|Cêh‡Ú5Þ¯DtWDCXŽËàº"f~€î Š<^ú:…‘0+úæåöå'¨Tf‘ãaUR\¸7§“†ì'B4‹1ÙÕ yN¥W}‰tŽ M1 _ŸQq#,#9¸1Û”¯bY4CQ% ä¤6rÑ‹™˜ˆþñ7BÐ]„”¥ÚÚ€€¢uܧG :[èê#©¿0Õ#ņ“i“E¿¡è1—ûi¡’‚Ù¦‡}Úƒº‚’&u×PÝU«vRtp*o6¥€€HL?Í×·nÙñ‘CúmÖCÉ.ɘH³äef{a›{ñ?î·m (b¹húe÷f>›]×Õfß86`Q a:ƒ>…^WY©ËÍ4Ôå¨7bäl¨¼½{÷¼“ÜÉÅñ9Î^àóãùÅôíìê_0Ì &·î}‘g¨´Å]¾ie+<æùÁY¸žÍþ}|þëÙŒ\ž3b:°’ô9é#>¶ ßHµèdpù(ƒÇjòÃRx¯\õ².ÌX‘À hH´ðÅ^í°m œ¢M›¿½ÌCäÀ›¥Iÿ—zJR8ÎÉ´ßQ\QT±-S)Ì<èýŽ´Cá ÆÝÆ x‹W5ZÛ¯R™°möÈà >¼àj^ðûþ†q—z™À^Qú´1À—ßΛ¸Yâ·ÁÚÁ“ñüf¨çŠq+Õ‹fâ @•uSïf$ª7ÇÐ,}¢?m™í¤‘ŽÊc^»/šõ`+ª6S}mFƒÞ{H—±†T°w¡'«°Þµ{Л>_D +ÖÇQþ¿ã) +SfhòTšB—ÂmßG))h-ãarW½@g=&ýNÛ¢Z€çÎí–×ÈŽ%…ÔD¿Ðê:÷Ýî +BÈ7‰`iüϵÇo´Ž~U•K×#‹ShÂ,Ì’}ê:R~¼pewXÉWì©w8)¡£Æÿ=^Ä2Ť„9ùë'îxâ©ñˆÌÞ/¼ˆIŽh‰üž/bÂdL'Ú~ÿ'±.ågÞÄ>GèP!ý­Ó,ŒÐÚòNΩi‹Â™ G8>pµólB õºÚoV„‰ :®í\ÝT;Vó?jâF^<Ê)%YbQõ?6na£ç­çïÉ ÓÔPq˜ µ6ãk|—Ú#ï:ñE1_à·.¨wA¸* ç~íè5IT?b6@tÊžXÔÀù¦®Âý!ð"sýÑ!¨ › e»¹J ¾›«TÇýš¯!§„?~½m8»ðE +—Ć?áâRY7d·½[í< çôYùgµ»"Ÿ>‰¨|5»ÙU[‚è=&¥÷˜Wæ i¹¼Ùïü#á«Ãƒ~Qާ_ܺÁúmñÿ#_Ü„„‘"¢ûâöøO%¬Y¦»ï êQwºXœý¸Î‰?îý€w«³öeÁÝäûM3mšÍÿùea¨”€ø7–?Àð6góŸ{vÄ>ÂZÙ­ Ý. %¡ý +L!ãÖ<äÜ( ÅO¦¬ÿ…ŸžÊendstream endobj -1549 0 obj << +1553 0 obj << /Type /Page -/Contents 1550 0 R -/Resources 1548 0 R +/Contents 1554 0 R +/Resources 1552 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1547 0 R -/Annots [ 1555 0 R ] +/Parent 1560 0 R >> endobj 1555 0 obj << +/D [1553 0 R /XYZ 85.0394 794.5015 null] +>> endobj +510 0 obj << +/D [1553 0 R /XYZ 85.0394 663.594 null] +>> endobj +1556 0 obj << +/D [1553 0 R /XYZ 85.0394 640.0743 null] +>> endobj +514 0 obj << +/D [1553 0 R /XYZ 85.0394 573.5829 null] +>> endobj +1557 0 obj << +/D [1553 0 R /XYZ 85.0394 548.3076 null] +>> endobj +518 0 obj << +/D [1553 0 R /XYZ 85.0394 357.2459 null] +>> endobj +1558 0 obj << +/D [1553 0 R /XYZ 85.0394 330.4365 null] +>> endobj +522 0 obj << +/D [1553 0 R /XYZ 85.0394 105.6253 null] +>> endobj +1559 0 obj << +/D [1553 0 R /XYZ 85.0394 82.6167 null] +>> endobj +1552 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F21 710 0 R /F53 1027 0 R /F11 1384 0 R /F41 935 0 R >> +/XObject << /Im2 1049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1563 0 obj << +/Length 3050 +/Filter /FlateDecode +>> +stream +xÚÝÉrÛ8öî¯ð!ºÊbAöÍí(O¥Œ­éêšt”HÛ¬¡HµHÅq¾~ÞøÈ➤jªÆ>Âò€·/ ;àŸª8ŒSžžêT†*bêtµ>‰Nïaîí ³kfnÑl¼ê—ÅÉOo„>MÃ4æñéân+ £$a§‹üc‡"<Qð¯÷×ó³WQðæêô˜Š—»ø°˜ßÐDl—þruýšFRj.ß_¿¹zûÏ›‹3-ƒÅÕûk¾™¿™ß̯/çgŸ?™/ú+Ñb‘ÀûþyòñStšv?‰B‘&êô~D!KS~º>‘J„J +áFª“Û“ôG³f«—L, +¹ˆ¹‡N\øè¤Ò00…tº-:À)‚î¡ N^Üe»ÊŽ.Δ +Êuá~¥3ÆÂT)nÝfõ}A,ŒfœI-KM#-\¬Îá<Ø”c#Ê!¦‚'Ì+8ݮӗÇa"ƒ‘YT¶vŒü,k+Bo.©ÃE” gö·½;9x3¡BÆ¢¸—ë„8ŠÆâúkÖvÅÖJyYYç_º¢n˦þùl&˜c1L¼z;¿žƒPIV7^—ÛbÕ!OŸ#ès¦’I™§ºË¾üì¡\T±XY +LO1«Õl,Â(Ò®ñ¦zh=·PþB üe@ å0ô#ÀõKQ°+œ7ˆÆX”‚ÕÃHÅ/ E*Bé½Pñ¿Ûå®™ð"‰•:|Ú,Ûu;¦ f% Ø`a4ŠCÇ ”I ¡­ãDË‘÷®ZÈŽ.ŒfÄ YTì EŶ©MG“gD£ëƒ×eÛnÖvÍÆîÚR;ŒÿÔ&Dc(‚+êÁ‚‘ܶí|2‚§`ì™’òB‹6þmCxÝ*6Óe-à)yOhF¼*.ªŠ(¨Mé’¢E fuî¦èõ®µ0—…OÌ7M[b¨÷L&¥ʳx3bà÷ÉJD¸ Ü Örpù`ö[ çœ0HùŽ +‡xˆ³Ôàî-}b†ÎÊùµ¶ç#75Æ8Vgk7x··êypƒÓÏ6‹È=C»´‹†*÷š¤‹c&ƒ¶¬ï«Â·(B~»X܃t)jâbaLâò¦ª²­ƒ{_SFg~=­—MÕÒLØÐÃcß&Z{g3e…îéé§9‹ͶÝ0! }J‡?¨¿©²D&$áøÊ$› +µ‰ë´SV­‡ÀÎ ƒÝ¨×©ÒX¿7êŒv½¢_&‚CkvÝf‡ÚÇ<5;š® òÀ|gáÀd&Ì·›ýÉä8xðr†Ç‘‹³w-†§xGl–Ùêß-„Q´Ò²ÑVõ8v”¯}Ù(sÀÑœÈ4(ÂûÐ 2PÍút©ö c€É#B69 Ë,Rƒ~ùè®3"yT`,nÁ:{"j4Œ³ª²¿ +A{ÒÜ<šøGŸHxФ¤Rî´ë&/ѸCÜKy|(1wôö2S&Õ–Æ&cÞaŒ7þÜÒ/'Hj-Œ)ªÜSæÝuÑŽ{lõ2kQl5&ùpÉ3 ÷LõHUÒ„¶£k仕Á Zà\æa/Ó©ÄÌ Ë—ä©`ñÈFTÅ]G—[PIk"࠲ѼƒUÙþ3Ks `RžLiÌ1‚Í%? )2 SÇ$ÜühAÖúLWÁÅÆ„ + ½;$ãnÁÀøç†{Ï‘EŸ>y §pvÜWî_ "ÒÁc²€(Å—l½©ŠsÏ•b2ÑÛ΃XÉ—b5ãѹ8Ï}& …8‚Á„OZ–spÑ©dzÊòDsXñ€GØŠqÊqkoaxµÛ’h›ÜfŒGûËx°_áàô;¬·¥Ò%LdvAFÓy±*×YEcƼs_ ºÄÌ-eyîÛ^yñ‡‰ËT䔘+`Íݸ) |ÎÊ*[ºb9ê›”ºCù¶wTTVõšÉ(Œy_ZÈ}Ň0J4”–Û+¬º¬²üÑ`Ú±45áÏ#'e§ÆWš •è ŸÖ$€7¡)ÚÃå7œ9pP’†Rô +óÅk¤ìµÅ£ð0~÷]Ân ºáv› ‰Á +ô‘0é0ÞÊ,è ãøcð„bé3>3êkPTŸËÿ+G~m…Zô²qÐâÈ‘ÅQÜæ9‡‚9Á°þ¥¾ËI•N*ƒ¯n:êd˶©vQß!Ÿ’%÷qÅS‡+óxpÒp:×{§gÀÏ:ïƒFà§Öƒ"Ý6Q›UÆ1š÷ÜÆ* ®°ìºÉºrYVeg"i_0p²È¶UiD†±Š†%2ŸgZ‡Išö¾Íçܘ1°Âڮļá»Dâ¾.¿R˜£ŒÑö¬óÒy_pCQº_À\Æû¢ ²ew­XëójZÉë Dfìpæ8ÎȾ3ËRÇ_¡à³M¹’`nRuäAaš8ÞnÀÈ«€2(m*h:庘uͬ¢W31ÞCFÃWõÍéç^šhƒ£ª0Kª¶?2wG’)ÚwcFn…ËÂñö¡Ø–óm6Ϙª8*'øè5Þ—Õ+÷œq–»ª8øt6»CO)2ŒTꌌ…÷uB¥åñ|\w£ †¦èËâcù.JûB€"N$/†'¿¤DèGÕH~¼ íÇhਠ³$T‰<Ê¡c’®\¦„ÝoÆ(@ÍEÆ="δ+òÁr[Ç‚•ë¬3O90ØA +äà}ŪŸÇX÷wÛ ­´¡—+­ôæ¨Ø²ÿ7± Ä[.ö±Ïžt;Š-ø¦ã䍨²„‡š%jx]ý–Ø^t$c›,˜ìB0—±Ã ½-â})3ž&~K3£ú”>,nÎiؼœÓè뾟çÞ +üY÷[[®^ßaÛˆ ßGãQEÖ^ç/¸j»ã Û” +9gÇÝ*S =‹›Â?Ä“f'‡ÅAZ èÞG6bÉ›uæT"7“}]íé:q»Ymë¨-לmÍ;2=¬¹/ް`„Ü÷Ñk`ÁðYÏÿâñmA‚‘×LÊ 2 +îû¢gßq ÙW"L 9hÿÌ(Iðóe+ê…ß2‚X§‡?á‡?Éíó6}³2a·Žáë˜Â}³§oD¡€dÛnšÓ÷P qNN +ow}¥§&[ pé=¦ôÅÅ t’53Nœh0Ü'qÒ[´{é_ç§1·­pîÅa=—ï.no'ŠçR츶?'ó|G~Ó¼ô«µáË=iêCÜ/)½@ÙK!•’øÙÍÝçmϯþ<õª÷endstream +endobj +1562 0 obj << +/Type /Page +/Contents 1563 0 R +/Resources 1561 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1560 0 R +>> endobj +1564 0 obj << +/D [1562 0 R /XYZ 56.6929 794.5015 null] +>> endobj +526 0 obj << +/D [1562 0 R /XYZ 56.6929 713.4234 null] +>> endobj +1565 0 obj << +/D [1562 0 R /XYZ 56.6929 686.2623 null] +>> endobj +1566 0 obj << +/D [1562 0 R /XYZ 56.6929 478.4096 null] +>> endobj +1567 0 obj << +/D [1562 0 R /XYZ 56.6929 466.4545 null] +>> endobj +1561 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F53 1027 0 R /F41 935 0 R /F14 737 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1570 0 obj << +/Length 3287 +/Filter /FlateDecode +>> +stream +xÚÝZÝsÛ6÷_¡·“g*_ÁÇ4qz¾™‹[Ç÷r½>Ðls"‘ªHÙuÿúÛÅ(QrÒø!“Ñhˆo,¿],°Ë' ~|bòŒÉRMŠRe9ãùd¾:c“{¨ûùŒû6³Ðh–¶úéæìÇ÷²˜”Y©…žÜÜ%c™ŒÃ'7‹ß¦oÿùæ—›‹ëó™ÈÙTgç³\³éO—ÞQIIŸ·WÞ_þüŸë7ç…šÞ\^} âë‹÷×Þ^œÏÊÒ诒|ß7ØÉ÷üxsùöãùï7ÿ:»¸‰ HÉ™Dêÿ8ûíw6YÀZÿuÆ2Yš|ò–ñ²“Õ™Êe–+)CÉòìãÙ¯qÀ¤ÖucZ.M–QŒpMð çY™çbÀ¶¼Ì´Ò±Mg2+Îgœ16}³XÔ}Ý6Õ’ü¾^ZŸj7«ªïp½0ªLö‚MfBe¥âÊ wٜϤdÓÊE¹¾õßK‰®¯šEµ9çfºðUöÏ~‹cæÎM÷dò°‡X\úÎÛõºÝ5Ã1«ÛzY÷ÏÃݶò“´ú.¶«õ°Ý_mã‡ùcbiÝRqq‘°¸—#òi sn(I”v™Oo€Ç"Åo3¦´€áp”Mõ4ÂGÁ3^pß„F¥ꎾóí†ÓôËg*ª«zYÝâ&¹¬oYy2«d;w´zR/÷†¯ès[7Õæ9mï1ã@Ÿà… !™#‚Öô進º¹'À$‚÷ŽuÓÛMÄÖ¢ê+JuýæÜL·ó~Kãøúšrs\-ç|ú•;ÖcÅí3PnUm>'|Y½"šÚÇHƒ &–mµØ•Ö+›Å­.²R +ãVö¡"J|ÁÏzS¯cDɧÝ< ¢,6"aŠ@DiD ~ûqp2SЧÁÁ2#K½‡7xG_ûçÚžóé¼· ?[Kß[OŽm즊ÕwÄŸ-ÈÓept1„P1Âp9 ·€˜¸D‘.Q”™Tyî©oª•]Ìæíj ÚÅMr¸^˜Dk¡|h»u‘¯ig„rDÜ·¨KžCÖíK·þ{·×eñ DÔsÊ ˆ-ýº§"ÇTl¾í[àt=¯–€,/*c¬(‡r0Wj ËY}GévåÁ d¢\C:”uk;¯‘Å¡72Sjy„™pH ŽxYUHíÐl'°{ü4"Ì„>íµÉi§ی̤a¥¹Òé¶ -a«xa|+T¬~]¤—!öx2“Ž16l_ªÃk‰ê®wÛ—ìÄtS5Ý](oý×ÑMÖëåsjÕÐd»=c»=/訂Œ@ÁT˜©ðBÚ ï®QP˜ŽbéÆÚEGI€*ɦۅÛÚy…G”qI(óÓl:ŸYmCÊ ,Ë‘-€»!™…„RKIOÎN`==~ˆç±ÓëžÀ(ô +g‰à@8A‚Þ,z/€!sÛuÄ+ÈAeÝC»].(}ëÊ5i-È{m]¸RŠvŶ¾ž? †!é„õʼ0 ÷8¹õxBÞÆæÌÏšœq›sØŠ¥Ï»fc‚)Á bâ 9Ée>ä¤Gô}U7Û™0&39XÀø¾Yö°òûdÙ-;~cám5ÿ´]ûõÜíèqQÎáÂã¶kë΋‚(2Îs5f†¢ü ˜ö„ÚËúž„G?&þÃÛ‰«ŠŠ6Zœ‰Õë”ZuW`ïháoGŠeBKã/[Ê_µÒk%öïÀÊ8v½2™.Jº­y³ZswŸÕiP=ü;*]¶î… +ä+–t»Ñ]yÝІ‘Ö^X±&šÌ ëGë,pέÚu„ƒù®š‡J2ª´CúÆ—9Nj46{?ø*„Ê#§_eB¨3ô´»LAI¯9Æ”¯›ùr»mÝ4ÒjÞn8?{¢U–A]@êÉÆ‹Çál΀¯ç<40T@|Äï=²¸•­ï»í2\nGþZ¿¿[Rët«@+㺋àFåBø`?`ÂQ“ç&AøŽ;cSÅ À|ºo7õ_at€Á¾¸ÜµËeûÍ/0Èq2ºö^GÊÜL”Ì3Yrýy¯#<+˜>Žü­N(8¨O¾ÎP?Cùdè1jæ4S°ç +M¢øî28åE&%hYº‹ Éý; ¨«È²kûÇÖvô¾’rL«JÎËI:Ã×ч|j©àÎ`ÌjÂOQN›íêÖÁ´ ŽeõnI{÷á#U6ýú\jŽa±™tlzõËÛ«wøTi®_‘É +=™íؾLJ'e!ò0ÉDVp%F0ùëÖnj{’é¯ÉÓDGH¦D;HÊBFHbÚðÝAsø¹Œ;¾0á`7€#aýÚ?%÷Ïk{Š¯Ç…oаFç_²¢Ðãs–•̼EY˜L±œž‘¯¶ý}ûùPL&ø:’(ž$:@q@´ƒ¢b2€ƒn– GCÁ»ôcwmx>˜WΕ?ðÚìè/&i\Éû#qBjâ {Wm—ýÈÉãöÕd¥R:Øa\©^`f?¬Qà O-Õ¡g‘R©óQzG#6uŽF™8w•!jaàE U‰éUãkê.Œï§]ÖˊʸA‘äò ‘{ºãž§´ñNPïÑÑ£MéA´¶rA%Øk<¨$×YÁcxÎn!³]PÞN]po¹ *i°åýv]¾Æ€!„uî}:è¼÷žG èèëc+ÛÞº ôç;>c„wÈcü(ó7kŒO2WhÄP4 xþP5]R¥â2ü lŒ•‡,ðÃŒ +hÍ¢:éc}Àˆ¡Mwd ö +°‚v =àžIb;¡š‘µÇâÀužIá;Õlî'”¸ zßµ>~ ø6îÐ&?kxp&íÓ‡†PºL98ˆb›“óïät ³†,4*Æ­ÌÈbLúW‡Çïx‡ŠÐqÄæ g­' +‰7Å¡aâãèIÿ?äßGendstream +endobj +1569 0 obj << +/Type /Page +/Contents 1570 0 R +/Resources 1568 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1560 0 R +/Annots [ 1575 0 R ] +>> endobj +1575 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [55.6967 62.1828 116.8967 73.5749] +/Rect [84.0431 62.1828 145.2431 73.5749] /Subtype /Link /A << /S /GoTo /D (statschannels) >> >> endobj -1551 0 obj << -/D [1549 0 R /XYZ 56.6929 794.5015 null] ->> endobj -526 0 obj << -/D [1549 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1370 0 obj << -/D [1549 0 R /XYZ 56.6929 752.4085 null] +1571 0 obj << +/D [1569 0 R /XYZ 85.0394 794.5015 null] >> endobj 530 0 obj << -/D [1549 0 R /XYZ 56.6929 542.1781 null] +/D [1569 0 R /XYZ 85.0394 769.5949 null] >> endobj -1552 0 obj << -/D [1549 0 R /XYZ 56.6929 510.0725 null] ->> endobj -1553 0 obj << -/D [1549 0 R /XYZ 56.6929 447.7453 null] ->> endobj -1554 0 obj << -/D [1549 0 R /XYZ 56.6929 435.7902 null] ->> endobj -1548 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F48 940 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1558 0 obj << -/Length 2647 -/Filter /FlateDecode ->> -stream -xÚÍZÍwÛ8¿ç¯ðQ~­¹üDqöÔ¦I'=¤­ãîÎÛéd[‰5+KKvšýë (YvìÊù˜÷ü|‚ ð¢EÃOô¢€qeüž6> ¸z“ùïÝAßÇ3áx5Ó Íõ~töK¥{†™P†½ÑmKVÄx‰Þhú»wþë»/£‹a î…¬?Bºþ@CóÏ×—W¿ ßõµï®>_yxqy1¼¸>¿èŒ‰$Œ÷[ÜØ›r#oFWç7ý?FŸÎ.Fm#W¨ý_g¿ÿÁ{S°õÓgÊDAï^8ÆÈÞüÌ |¥jJvvsöµØêµC÷¨ˆ‘Ô{P“bja¡’Ê¢††ÂÌýàœ{£YâL­â*-«tRÒûeš%h,ˆT-‘¼7>3¾ð­°fx•ü¨¨u[,ç±k—;B§«ù‚Zãä.Íõ>­fÔŠé‘¥yò¶nþ7ùÅé!¶õš%#«Ç›7oö›ñ¡™±aùÎn´‚P2¾±ßL¯7f*®½|5'Kj§9>#o/û"ò’¼š%eRºN÷Œé@äSâ›Ò¨oyúcPV™“\¥ó¸æ 0\IáÍ“¸\‘`7"v"ËdRäÓú%Í'N§8_ÅËboÑ*k‡`&¤µCÍ2„Þe‘eÅ}šß(>øof}¦ŒŸZh>cb)ÇQÜÒsË»Àæ·E_xèþ´ÈѾôîgéd¶-oWÉ]±Lÿ‡–áÀØuL“r²LÇ–ŒóŽ‹uÂȸ‹¤lYD9ÀÀÉþ¦ "öëx^/’d¹F÷ï‹4àîŒ#kÅ@ -ÝÒ[„ø³Q%uYxበ-—¨±T^Ò Þ*Nsr¼Wv -½í +t•WVYè\ÇÙÊñÝZÇ[Œkü@Ô´žò*Îè…²ì‹%T",(;i ˆÆ&N³$Z¼ŽÓ,gŽÅ©Uº¡—5Û˜b}V}!„‡†kѰ“P¥À>‹× Ñb"Ô†@ qÇ@’‰–QËYqŸ-ÍkéÉ>Cw“ØwÎeqY³>Ê2Ú.ñaOBKh¡H«h˜vkI÷³¤V{‹£I@@L t -¹' Ó,oAäªVfk ,Ð|KfDËÆFÔëQ¥6™ÉÈSÙÏ—ò]JÝ•˜7<‡2³è5ÙTÀ„àº)gu1Û㼞ãê˜RW TgF¤T»ˆ´^¹šÏcL\ÔµåeÕV;Ð+ÒiO‚4C„…õm±ÏáB‚€²ÐRG.bº'25«ZSÒëí¾¤H<]r[͋ը^¶šçÔccGðšU@²mV ¤gÀ`Jôòa>.2bÎm"Ä–ÕFˆÚF Ôé¶J`‘obZ:vRº™šÀÆZ†V¥¼–yÄ24¶Ú¸RƒËòüd’”¥MlÐ fP#vÝ¿ŽF_ˆ²% z&³8Ï“ 3’Šê-ñ–éÝÌ¡g¹ldXñõ.]'NJÁ@ëJ—”ÒlzÒÒ Ûä8„Îf=ÝMè´E¸ã¬,ˆRg.ìÌwDm™ˆ W×xUÙ)ÂÖÐÔñN‹Éj™Äé°(Ê2gÔéÊ) (3Äe_ØÍ‹iŠNœST (g`cœT¶a› žÆã4ƒ|+À…ñÞM§)¶¹ 8!]ÛµÍyü@ B‚dÒ³µœ¦DIÝôd¶(øqɽÏÇïóÕYh9^8G]û®™P>í¾-¦q•P¤†Rº@éF÷ÃCÏÓ‰ÛèZ/„·¥ú©Â+Œ`Qgia&´ÑnIã‡@ü i@y7ïòò˜<@ƒ€e’W‡sJô.à`aWÝ‘bRúaÁÈžÀ–«/™ˆÉQß`´E^=¢~Ot£ìÉâjF² P-˜ ߊçOþäðûéÇ‚([zž,–AÀ´ÔÕ]†)áËMpy48åæ(Ð iwÒeZËŽ‚.|ÍT`DƒË±ÇÕ>>¯v ÙÒòµ“¢§}©¯GìG*‡ DײVó¹¢ò »Ì›•½,í†òk½ŸTÆÔiq•ÙDéswgkì_„ðQ’ØÛUæÈyyßÜ ã‡Û}¸…‘ó$¦²ö袔î_Õæk­jîCét€ƒ.ýÑGÑß{”wýùb8ü<¤—vþv\ ÿÞ»Ë,‰í5y =»ĆÓÚ¡72"ŽÜâîµ#Ú?_ÍIvÜ!yĸ¤·<è…Aù…ÍæJ0 ;x|.ê{ûbUn}),·ùZÿŒ<ñ­hzYtþ}©J¾1aGî4 "%ëxÇÃéQÛ¨¯ÏOu¼Óçwwúø°ÛŽõCè¶T?ÕÏ^Z‰Ttäe°Pº›a@÷ºˆ¾ ýÞÍuüš`7Ÿž‰zˤ—¢1Á¡ TÈBùûþË{.9ö¿À›GcŒ¢Ö·È6ªŠ‡°áð€I^ÑD¤Ãáþ4ì¸ZªÿHIÝSendstream -endobj -1557 0 obj << -/Type /Page -/Contents 1558 0 R -/Resources 1556 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1547 0 R ->> endobj -1559 0 obj << -/D [1557 0 R /XYZ 85.0394 794.5015 null] +1387 0 obj << +/D [1569 0 R /XYZ 85.0394 752.4085 null] >> endobj 534 0 obj << -/D [1557 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1252 0 obj << -/D [1557 0 R /XYZ 85.0394 752.4444 null] ->> endobj -538 0 obj << -/D [1557 0 R /XYZ 85.0394 549.5629 null] ->> endobj -1560 0 obj << -/D [1557 0 R /XYZ 85.0394 524.9842 null] ->> endobj -542 0 obj << -/D [1557 0 R /XYZ 85.0394 417.5407 null] ->> endobj -1561 0 obj << -/D [1557 0 R /XYZ 85.0394 395.2295 null] ->> endobj -1562 0 obj << -/D [1557 0 R /XYZ 85.0394 395.2295 null] ->> endobj -1563 0 obj << -/D [1557 0 R /XYZ 85.0394 383.2743 null] ->> endobj -1556 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F39 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1566 0 obj << -/Length 2456 -/Filter /FlateDecode ->> -stream -xÚÍ[[sâ8~ϯàÑ©´º_Ó¹Ì25tf«kfç`gâ©Û$ýõ{dÉF€ÁÐSTWµ…Ðåè;ß¹è8†¤'$’†šž2 LDoòt‚{Áw?Ÿ?¦_ꇣ>NþuÅTÏ #©ì4ÂZ“Þ(þ#’ˆ£SXGŸ×æ´OŽnG§ŠGgö¿Ñàv48¿=í£itþï³/£Ë¡%ƒ‰®ÇO?¿¹¾üüÛÐ/psíº‡—W—ÃËëóËÓ?G¿œ\Žš„‡$˜YéŸOþø÷b8ë/'1£Eï>`DŒ¡½§.œ±ºçñäöäk³`ðm5µ 4Î5`ÈôFœÍ»º0ìê›”!cå\Þ´/ RŒÁ‚Šs„ ^¨’@ RÃ!ê)ad”Ujøš¿ “û$Ïǘ‚)DÕpاκϒõŒœÁQÚEXEQbjÊ\Ïó")÷` ¥j…1¶Ç2Æ>¯o.‡Ã›áÒ0 CQÏ|MËךfîË1j#‹c1ë̪:-—ªg+—{ÄìJNúéÆc2†¸d•KveËû\æ’í.Ù®~%vŸ5e{ñ[|7Ùjü1\«QÝ}ÉzÆ&®I&(ÞN6i ÒBòšl·à÷ÁsüçêTˆèlð+`¡±Œn¯Æé>>˸Â@è©h#lËÃ&6 ~ÝŒtxˆá² -59$Ôš#F¸ê€Z+d0iBÁÕÍð3X¢…D*@ø,èPûµ·ˆ|(`C匱RBÔÆœu«2\’Æa~»¸ù|6€„„TÈÂç}Â-a«á–øp ßÔk#÷чVh­9@; `[ˆmw‡1¬eã ãìi »® ) §šüc¡5TÂñ†VI!+fºËÝ Š0j‘ŽMæ0V_”EÃ«×øëždy}H'žãyáÃ*-W"Ém0r™{Î’ü>ËŸB¶Õ‚,Æqº"3QVŒ«Å8v‹A÷1¦ÓØ÷U»Ö.%Ä+)¡Ò5oaÜ:oÝÊïämžc•¸”€ù?GÜ€‡ŠÓÎ+%öY²ž±‰¸|‘’].P& -7±ãb>{L'ãÒ*›2 ¡cÞBL­yk›kl£æªmË2yš¹ÐbÇdî¹`«Ÿs7/]#N‹~o&™OÆìR²‰ñÔ=“ïiQ¦Ó¿Ü§ç¹½¹O. µ­J8Û(ÆO¾5øâŠcOÞâ§¶gY^þÂ1^­þfÓY .ª>MaAÿuù6KÜ·ckJöÛÉã¸(|ߣÛf¿¹ïî’JlÛt”Íúm†;Á’lNUÛœj³9åð­žíV^_J©¼"ãFÿ-f©äÚÕË® æãÒa#¶Wçe´i|­?f(?Ôö@Z£Ýn|B¢†79òEžÍfÀåÝÍM(¿w ow¶YQÛ6j»³m0£%‹±}Öbì3ù”j5²"}±žMçOw• C»R™Ñ¥ÙÞ àÔ“žÏ`¼¨¶áü̯L¯…àµiY[ª-ÈòÜ[PÓ§qôê溋ù]‘ÀÞÓòñÍõ8ƒ®Þråd²Íм—br£ môoT$§c½fC²²¡ê¹d-Ϊ ¹€{*]ø#6ÐóPFtø$k‚°’™‡›œ$'Ô·¸PÎó¤Ûˆn@•ô¢öáLÊ辚îÔoý« 3D3¤g†ØTØf(Éßô~£týfäJŒûÑÙLó¡ÒðÃW¸4ˆP";È ÀR°vÐ}»Ï‡ÉóE6Ý Cë,Šæºû?;É•+sÈqï]÷q’=Í“Òûv<¤ê𥅃â)"Rv” 9\Ñ”`Î'ÿ6‹!1¤à.Ó¨Ö*„=Ž ^ÇþÖ± Ë@Ê#Æ. ”ŽTÛ¾2€C™%,‹Ù;Á\TV÷@3óˆÑd Q!Iš¶ðÊ© -à$w«&^¼Az‘NvóÚGßëmE4õxˈqÀUº P¸Ôj­dèn®³Í=œåB´#f$6ˆqÑ•ˆŠ £ %5‡ê3L‘”zaJÌ,ÝB¨Bõ¶/Éýâöíé.{„› 74ºHŠIžÎJ_G ‘³©'ÆÎ^ìñ1¹-B k}À˜¶€‚HMÉ&¶ÕPÀDÀ.½ÎÊôþíf^¾ð#•àu!lðUT›Â,[ô®J‘LK´½P¬Ã¢wP"Y«…ë<ë@OSˆ/ܬ 'wAO¾ ½@¬cFOBò‰é@OÁÚ¨½ÁôCÔóõµ$}iÉ - Ò³ H8¹îÀP@ta\.cøîˆáB¸cæ!§HÚ…!‡0« 0&wC8…üÝ•v7ÂèÒª-03Ž rO¦d޹8‘ «7gû˜âÏáßZt8Ä@²c¶e¢‘Ñ´+SŠ„4$pS~€dÇÌ@¬¦ª+Œ$a.Ÿ}»“ç½(h笕ä¶p ×ÃW½wT´# £‘Z-Á·÷†/”ë˜áÓ ZÒtÀ§á^ˆ!µ­@yû{ÃÈuÄÞ(WZÒ†‰X¸æKðíþýá ä:fö ƒ(–Ñ—HŠ”aÍ«ÛùÄþD'~¿¯½ÊÙôN¢°+&ñVDQQ®„w *0ÒL×€n(V¾Í µË”NƃæÝ«f?¢äŽ -1àÙº™ TíR7«^ê+¸ec¶½n¦9¢2øÙ A̗͆I‘=¾ÔšØµRÖÔ〠Ì]WeĽNnîú›šÅ¯Œ@íL‡…¶ô3_L¬¥²§ÕzMvȃ(“´Møÿml ºendstream -endobj -1565 0 obj << -/Type /Page -/Contents 1566 0 R -/Resources 1564 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1547 0 R ->> endobj -1567 0 obj << -/D [1565 0 R /XYZ 56.6929 794.5015 null] ->> endobj -546 0 obj << -/D [1565 0 R /XYZ 56.6929 352.0981 null] ->> endobj -1568 0 obj << -/D [1565 0 R /XYZ 56.6929 326.9775 null] ->> endobj -1569 0 obj << -/D [1565 0 R /XYZ 56.6929 326.9775 null] ->> endobj -1570 0 obj << -/D [1565 0 R /XYZ 56.6929 315.0223 null] ->> endobj -550 0 obj << -/D [1565 0 R /XYZ 56.6929 102.2008 null] ->> endobj -1571 0 obj << -/D [1565 0 R /XYZ 56.6929 77.0802 null] +/D [1569 0 R /XYZ 85.0394 542.1781 null] >> endobj 1572 0 obj << -/D [1565 0 R /XYZ 56.6929 77.0802 null] ->> endobj -1564 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F39 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1575 0 obj << -/Length 2081 -/Filter /FlateDecode ->> -stream -xÚÍšÝoâHÀßóWðÒÒ×ßÙfYí$àV+íµ€lå¿¿j·mÚl¸äNh¤ 6U]å_WWUÓ& ÿHG „™áe8˜ˆÎly…;ßá»/W¤é—BýPêçéÕ¿†Lu 2’ÊÎô)K#¬5éLçvo~¹þ6Œ{}*pW¢^_HÜýytwëïÿçæþn8úòïñuOñîttçoÃÁxpw3èõÑôy0B¡;™:¥Bs2ÝLzO½L«’`æ¼ÿqõç߸3‡gýõ -#f´è¼ÂFÄÚY^qÁàŒ•wW“«‡jÀàÛ\õ4Î5°¢ªÓgi cœb–3Ä%­[ý¯”J?p§O2B4Ø÷z†*>–õ¡úüBp…¤Rd&ˆ“$$é(A• . -&oËÇdÑëKnh>wº˜»â>£œvom:ÛÄë,NVû3(C„3Ñ mìa5,aÈÏçÃR”˜Š%‡ø0ƒŽÏÃÖnÞ^8Ͳ;¾ÎPe*ÑB -çJ£oNÃaüê±MýEjW:0pîs’ÏHRRê€T!&ʳÊóÎ]lÂךÙg€æ,Æ6]'«ÔºâXªîx|NnzDw‹!ÒðÖÌÆ/vÞ€3põRqJc’·àĆ9«Ó”çÑ”¤zz©«[j… &¬™¦4q­LNæîÛû¯×#è -ã¢;†ëvœ;¥3ø¾]l4* —¤…ŸŒå0h~ö„è^~ƒ šwÇÃ(^´ƒtÚ Ú®ÏrÚg œ½X ’!cpK½–R!¡”¯×Ãûñ׬é>Ïãq8ØlÚ9VJgà \»X|‚B{-T >!¤Ô§ÇûìÙn€Y²q‘H4ú§ÌÕ<>»É&›óÒcàêŦGîþâ–Ú-Á>D¤¯ÝƒÛ» >m-;Ñ¿°Àþ#»ÞçÍ|‚1¶Eñi xx±AI5"T´”lÉRÄCü§Ë(›=CDûv»>¡fï´>V·w/)‘ˆ(L[ƒ”€öØÑ™ö,îÍv5‹2;o§9íGLwKRõ_v5ÇQ"Úª9VHcâ«ùoÑÒöú -»¼™nåê5¸¹]Øï‘ÛbŸG2ðòRI -C¦¥Œ #æRmzæR_Žr þ„=ãÃ.[ztÙn㸶›§d³l:y± 5¨bÞRÐ…fHâ ú—ÅÖ-äA·dŠñîdò–žõÆÝÄÿæóbÁTŸÜ¸%âxõ’üÓØ;ÑÛsHˆqÓRâ…‚A˜¤{€åÙ€å眿XÀB‚*o©þBÀ½âgê €Ok¤N Ü]cÕ5pøb¡rŽ83-õ_p0z?jO¦*?‘jàñ¥¶û°GG\ó–ú/˜DXa_ÿÏ»ªhqev¹ÎÚ©BÏ?Üxf/Ñ"žç @Á×Òˆ1pñbƒ“b$¨n+þ”#B„¨a¼ÿçcÓílfí¼‘`àÝg¤ rVo[j&)I¢ÛŠ¡ˆHÌjïì÷s *nj@ÌÿÂýUÞ¾X7^¹~*Ö}ghw¬åÓwÛ„÷1Zÿ»†%[zÖR´¸ÖÐ@ÖðŸ–Z›B¸-‘†®}VüîŽNÿÿ‡¢6†m -VìV±Vá \†%ÒÔIsÁ”ê#%°Áwo’å¸?Æ‹8+v¯qöìg6%ÁìQ…\tûÉËÌý‡©F° e!Tœ©Þ$ÛUf7éèè3¿„çÈpâϾ&iæÎ`i7ÍÀ»4‹g©»&ÝY9Vþmör¯Öe/½@üD 뿌W‡\…,“ðˆï(tÁTRº{7\T3µH“ÂÕízlò Ž%0sô £¦0ZHŸ“×Ue¡ ï¸!.´‚é]*pDÉK±ÙΓÁÝ_*dyÙ /VIV¶ß ½ÍüÇd÷kçnòaóiÈwóI5@¡¾^ÛhSvò¥¸M÷Ú?tl ¢[B§qø/Ó…Ž/J*ße_çãŸÜ™ìxß2Ôb„Ýn¼Ñv%uÀz-ãIp’*]7?õÏϸ îvÅ…Gèî†q—vmS{(¸`+/dµúŽ—K»à‚1ç‰-\(¬ -hs“uဋ¯òËšÇó#G: Ú M°h9—€©†˜+¥ò˜»þcø>Úˆ„y³ÙJê€ÝZ´A -eœ¨ºáésœÖm±Ëõ ½bšÆy®Ü[¤þÃh5K–n–ò«‡ú{ 3GaRM‘¡T6à ¥ŽÃ¬¤r˜£‡w(1ä>,e³ÑJê€ÕJ ÈÝaoÍìç¢Û[›f§²Ч0®ZXR ,K©œåý:Kß&„’pMg“ÙJê€ÝMÀ€½n¸…fUB‚üç.òŸ„þRuNJ0eݲûfgµŠ”ÁÑ·¢®ƒ_­ßÍõ_ÓMZ¨¬ÑÌŸZêºZÿOÃÔR S[Jùsrˆ¹¿NŒä¼Ùj%uÀìþ:1\¨ºÝ#3 ‹j lËõÂ.-ÈÌ*¾)1¿‹ƒ7»èØ{•L ÷2ä'ÃÖ]Ò©ï\îÞBåÐIjM#ªšõ©¼™÷;èœ5U\ÿðçœendstream -endobj -1574 0 obj << -/Type /Page -/Contents 1575 0 R -/Resources 1573 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1547 0 R ->> endobj -1576 0 obj << -/D [1574 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1577 0 obj << -/D [1574 0 R /XYZ 85.0394 769.5949 null] ->> endobj -554 0 obj << -/D [1574 0 R /XYZ 85.0394 439.3709 null] ->> endobj -1581 0 obj << -/D [1574 0 R /XYZ 85.0394 411.7795 null] +/D [1569 0 R /XYZ 85.0394 510.0725 null] >> endobj 1573 0 obj << -/Font << /F37 791 0 R /F39 885 0 R /F21 702 0 R /F23 726 0 R /F65 1580 0 R >> +/D [1569 0 R /XYZ 85.0394 447.7453 null] +>> endobj +1574 0 obj << +/D [1569 0 R /XYZ 85.0394 435.7902 null] +>> endobj +1568 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1584 0 obj << -/Length 69 +1578 0 obj << +/Length 2644 /Filter /FlateDecode >> stream -xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream +xÚÍZKsÛH¾ûWèHU¢Þ~ðÕ³§Ä±3ÎÁIdewj's $Úâ,EjDJŽ÷×/Ðè¦(Y +åÇT©\e5A4ø€úAÑãð'zAÈB-u/Ò> ¸z“ùïÝÁ»gÂò Ó Íõ~töKõ4Ó¡ {£Û–¬˜ñ8½Ñôw/d>ëƒºþ ûpïfÔ|ïþ]ÝŒ®Îoú­céÿúîËèbH\a«#Ql÷óÏ×—W¿ ­€Ï×D^\^ /®Ï/úŒ>]ŒÚF +®Pû¿Î~ÿƒ÷¦`ë§3Î”ŽƒÞ=ÔÍB%UƒŒÜι7š¥·:©³ªÎ&=_fyŠÆ‚HÕÉ{é3í ßkº×éšZ·åržØvµ#tºš/¨5Nï²ÂRï³zF­„~ò¬HߺæÓ_¬b[1­dlôxóæÍ~3>4#6,ßyÀu¤ ”´¯áAì7“ÄG3¼b5§KjgþÆÞ"YöEì¥E=K«´²/íoB?D1%¾)õúVd?Uý[Éu6Ok¾Ã•Þ%Å*Y>³x‹V;ÓA BGœ!Cè]–y^ÞgÅ€âƒÿfÆgJð©…6àoB,Uj9Ê[úÝò.0dø¾ª¹,оôîgÙd¶-o’Ôé]¹Ìþ‡–aÇľ˜¦Õd™ Ç—딑q HÙ²ˆr€ƒýMAEì×ÉÜM’t¹F÷ï‹4àîŒ#cÅ@Ѝ¥·=ðg¢*zeà…_T¸B¥òÒ¦#ðÖIVãà¹63PDÛÞ0BWEm”…—ë$_Y¾[ãxƒ1pˆš¹Ñq"¯’œÈ!‹Á¾XBõÑ9!‚²C–‚hlâ0K¢%ë$Ë“qnY¬Z•íz騯ëë¬~è !<4< ; µQ +ì³d-!‚³0´‰[’L´¢¬‰ZÍÊû‚hYᤧû ÝMbß9—9Ä¥c}”'d¼Õ^ÚćoRšº@£EZMÝ";÷t?KÚ[MbfeSÈ=ÙfxK"×N™­>0?‹-™1MQ{¬G•þÙdvj¤? Oå?ŸBÈw)£®Ä¼á9”™E¯ÑÈŒ &šræŠÙîç.xŽ«cJIœ€ËŒH©1v+jW+Loós—¥´­ÚñjúšxE:-4¦‰°0î-×à<œ AÐ\@šíÈEL÷DƸFbí”%ÕÞîË‹Ä# ×¥·õ¼¬P êå«yAoLøîXäÛfB†K§D¯æã2'æÂäBlm„p6ÅeX9E¾keÙIHeGjbßÐL4*Næ3QSÁ¡jƒ3Rýd’V•ÉmðÌ Fb_ÿ:}!Ê–$x3™%E‘昔TìV5Ú[fw3‹žá2ÁaÄÇ»lZM( ­+cRV3*’¶Û&Í!t&ñEMÝ„—¦nw’W%Q\ò—Ŏ¨-Óà™Ò1á¯j3DØêšYÞi9YÍ!™XeUeãü^ÚŠ +ªqÙvóršá€ë(Jاµ)HئH¦É8Ë!åãdðC¡½wÓi†M:NÈØfúAsž>gÓû)H¶t:îZCðˆ åÓâÛbšÔ)Ek(à ”n|?<É<›Ø…¯‘ñB€[ªŸ.ÀB hÕ±Ã:`¬² ñ¸’ònÞÕ1Ù€:Y«´¨Cg•:ñ® +&bŤôđٕ-WÞC—£¾Æˆ‹=×£‚Ot£ì #F,Œe¤‘`2Ô~)îJù“Cð§‡`¶ô> endobj -1585 0 obj << -/D [1583 0 R /XYZ 56.6929 794.5015 null] +1579 0 obj << +/D [1577 0 R /XYZ 56.6929 794.5015 null] +>> endobj +538 0 obj << +/D [1577 0 R /XYZ 56.6929 769.5949 null] +>> endobj +1269 0 obj << +/D [1577 0 R /XYZ 56.6929 752.4444 null] +>> endobj +542 0 obj << +/D [1577 0 R /XYZ 56.6929 549.5629 null] +>> endobj +1580 0 obj << +/D [1577 0 R /XYZ 56.6929 524.9842 null] +>> endobj +546 0 obj << +/D [1577 0 R /XYZ 56.6929 417.5407 null] +>> endobj +1581 0 obj << +/D [1577 0 R /XYZ 56.6929 395.2295 null] >> endobj 1582 0 obj << -/ProcSet [ /PDF ] +/D [1577 0 R /XYZ 56.6929 395.2295 null] >> endobj -1588 0 obj << -/Length 1324 +1583 0 obj << +/D [1577 0 R /XYZ 56.6929 383.2743 null] +>> endobj +1576 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1586 0 obj << +/Length 2860 /Filter /FlateDecode >> stream -xÚ•WKoã6¾çW99@D‹¤DIÍi7ÛmS,Š¢ëžº=Ð2m ‘EUdÝbÿ{9R¶lÁÛÀ08¿΋…æGgiLBžE³$‹HÒx–ïoÂÙÖ¬ýtCLsGœ›ÉÄjó”Ä)KfÁ)ÈûåÍâ#£3!X<[n]"Iå,-×Îw²îTs°8œ'w-ÁmI҄¶ШHHœ±Ìnxÿôë”Îpø¬ò¾)ºÎuÕkÕÈ®0Ô€G#Â#ÁžˆI,¸…3¦Ü4 Ãù»&Œpu CkÙt…¦ÄB•.ˆ5ºûEU2ÚZk›z.šöÌ@¬UUÈr6°©È•{~Пá>p[»ÎT®Ó-·²¨ÚîA¸wúvܼ@‚ aÌõ~¯+ð‚=Oë·•ß®õÆf¦Õ†‘$c‹°eÊÜŸÅŸ§ÿZá(1 :LƇ‰ý-Ò¥gsv¾žÇü,ò"¦}£˜ò½Ð‘0S+–EÙ .)2Ń»Æã!¿ J' £7æEnš¾w±ÉýÜD\ÜU]B°]ŽøaãDÞ`é\ íÒ¦[¿_©æ;qñú|Xìð•ØßÑ¡ƒ:Æ·I¿ê¤'!öË#9B&º`³‹Ò©•Þô«&?aÞpÕ¨ã»ãqÈò«6yÈàÌ9ײé]9U·®±S¥·W\íÞ,‡ÚíÛËÖ\Û“m -ŽÛýâþá-ñÕa|ìkç›üÌYˆ2K›éœòá=4v{Ix ¬°7L ÉsaMc¸ ½ÁF¿ÇÙ 2܇0é«ïر2H`í¤[[)U¡*Cæ©Fç-´L`¯‹6˜,»•)tü›—Ã×¥ÿf„W¢ùúþô"ÁQ?>GÐP˜î”%4fô\Ûð){©î?‰Bá_endstream +xÚÍ[[SÛH~çWøÑTŽ}¿ì[`ÖS3f+µ3ó l4k[F’C˜_¿§/’Û¶Œ0xS.Ôêë鯿sk ÒÃðGzZ Ì ï)ÑÀDôƳÜû +m?ÐgPwĽ>Üœüã‚©žAFRÙ»¹‹æÒkMz7“ßûÿõþÓÍùèt@îKt:÷? /Ï|ñW—ß~½?U¼3¼ºôÕ£ó‹óÑùåÇóÓ1šÂxÍÆ^ߨAaäõÍðãõéŸ7?Ÿœß4ˆ7I0³Ò?œüþ'îM`¯?Ÿ`ÄŒ½GxÁˆC{³.œ±ºfzr}ò¹™0juCÛ@ã\VTõ#NÈîUý +V Eʱr®/:0`…CàaƒW‡@It0’ô”0H2ÊÜ!|.žFé]ZÉÔbCX4„h’>Øw^¦E––§Æy¿8%ºŸ–Ëi•N|M6[¤®&™—iaÏÁ’aý›û,L3΋0Ó"ŸOJ+¬6 !¨[¶ÊýqV÷i1ÞUˆk)‚ˆÅîÍ0‰¨`2tçËy2¹™ó;ÿ\xQ¾eù²ô5ßÒ¢Ìòy¹Þ/b)Ú¤”` ÎD/>·/ç a S˜@°×}¦¬Gì` ÖˆÒ.ÂÀŠSæò{Q”iµ_(U|±5–/öyyu>]ÖºÊzäcVÝûÒ<÷ÏIR%¨*žWÄlóÊUZ&¹g+“yÄìL^úùÎm s%È&“ìÌ–!ö¹Î$[L²U'ö€5ƒ£â{“øjª­Žñm´X1­FõåSÖ#Ú™&MTý<Õ¤1H Ékª]ƒ«ñï‹S!úËþõE’íc¯,|üƒÇ?ë&`˜±ÞbøËnœãM¼ •M Éá€Ö1ÂUÐZ!ƒIã.®F¿‚Z@¤|ÏA{…o˜ûX#‘«7¥ü`¾UJðÕ˜³X•@†KÒ˜Ê/gW¿¾BÐB®ð¾›%lÓÍ’àf¡¥žù×àR¡´eúì(0}m®µÝJİ–œä³VÝN5ùa.5>„cu©’B$Ìt—¡"O¡VAØxé`±§EYtñ8ù¼'Uï³ñ} @²,=_˜;cW(ÓÂ:!_™ûç"-îòbs­d.žÑŽzÌôs×sâ&ãØOÕ`Lç“PçV­+} ˆ7A¥kÖB¿mÖú™_ÉÚ"ÞÇ&mû˜ÿ8ÚF”8”† ^)±Ï”õˆvÚ‚ÓEJv™7À˜(Üx³åbš“Ê5e¢?‚Š}X ¾´f­-:ÎØBÍT[Nª*-¼S±}rÿ\q5Œ¹]V¾0ÉÊAkÆyÁìT¢ˆdîŸé÷¬¬²ùWÿö°´½úOþÍÇž¶ä„³…2™…ÒðS˜h2 Ô-ßµ­¼È‹êǸ›ýɱ¦?[¨wnËvçöÍ`+V;mr²´–@°pýAƒuµ›NÊ|îÒï‹)Äg>ìfuº,èN? i®¤¦ÖÌi;.‹Ÿz µM«A3n ‹eË¥ Aš’Úϒ.1;2ÔÔIx¾¨¼æs0]`ËÔ_£ƒ=†ÚIZŽ‹lQ'ÖT"%¬^­E .²¢0,¹Í—Õ¦¹`ŒCFrpÈD¤d.mðÅמ/Œ¢¼¦ÿ °­¼Ûó>‹x,'ÂH5㶯ë^-‚¬ã­Ù¬ %¢àÈ -¯`+èÛ§í@g`!7õe—‰âA¸ðãò†ØÄ¾Ífoº~07ÀC\㎌C¤kL{²,Òn7pGg ©u ¤ìß¹áþ¸m| d@¿íøF¸øw\ÆOòÚ¶Üí”nÐô܈Ñ8cîˆ9þu*Ø–l»ïÇl Pa …î_æUúOØ–²òfe{TØ&¤ï#£zÅü[6©M€§O¾µñš·Éø¿‰Ï…|Ó8Ÿ-’*»Í¦­XV=ùlÜÛh——ûìlóÆÐ¦cõ.mª„)l¦˜%Ói˜!ñY^{0ûær­´5úýZÔ.B©zÓ¥+—.‡RR¶ù °@½šHï—Õ½KXÿj9Vž(ÖuÐ×îˆA’*± +OvÎ"uRr3ýKl¨/Dÿ1_N×<¦eî+ï$_—Í«PWyó&Dll`P žm‰ý»«7°yŒv%†ëYmiÅ"ÜHe‹ó¼ò…ÛÔ?] ϙÜAòA²áÆ:M«BåÜw[ɸõ8«lœî¶w±-9”½;ô…0“ ê/>wÛ;05ˆâïI¾Ü£ôá,Ÿ§/ {ÁÌ•Í]äßvÿ©Hæå'?¼Z¦• év¢Iz¬·¾ŒÃî;R&`CBJ‡Ïo‹ äm€ÒÅã ’ß;¾èuè Á ÖfðY‹â9ÉK×qwÇlø‚ _ñ\¼ÈÕO]{ Éy´XR°(ÂÈ,)x .iàø²ŸwΞ ãËÆ¹el„b¨€ùžÅ3’õh5œ0¤0ïø­–…¨!$Âóeö²Ì=,d$ÛÑò¤¸éˆ¯Áé"Æ„‰ùøZ2–/$_$ر‚Ga³ÊðgM CLc÷!™|*Ò"}x ‚ÞPþ•Žw.GpómHˆžkß”•Yc V)Îî3ˆ÷w¨3X}ÔùIŒ±6pí‹¢W ªÅ DZN)89ؘýU$º=غE€ˆiêzÛoƒôŽ8¢þXŠB¶/¤ÖîÔì‡WàOcÜÿOfý +éF•Γù8T\W•·†CýXç gBÀ·q¡`¬¦êEe1®a›Šíaû¨Z|@5j6åï¼]i3k÷ë i°?$iðHÚ«ÒõÓì6‡œÒeÚ?ó×]UøikíÎNHIàD¼ÈÛ·1¬õÿ êG¤i§Û + dÆP°X@JŸÝ=]-«o¼Å¤Ž”àuþ9üÙ Ëlr\[”2Wh7|‘\‡…>E‘DwÁ§®ù|ò%ðÉWÁÉuÌìs—RvÁ')¸F#ø†ó7‘/üâ‘fßZ‚Š‘xÇŒ"‡€SÞ…¢ÀPÐë ¾…‚/ÑK'ŽD& jßõëû +D¦‘G¡Ø~q¶âBxÿCñN }põ ‘„Ç $…4|RýÁª‚w½z¿¯;!¾ð×a#ÑŽAèÁ´èôÉ„#£¨ˆÜG_… íØ ¢1ˆÃä]øaHÀ3û+õ/£Qú°혭û¸ç48’ëˆÑÓÊ~ZÝå“ ‹Ò5ðöaßÞàEb1xJ Aq—+V‘£_A¼á¾ØERq0-ä´¢ËK…ˆÿ 1|ñö/ë÷#E¥»ËAÄþûOË÷¸×ÉÊ—þ#Ôê_à cµ´˜Ð\=@|aç²pi³}O£‘дé‰þ?¥w¤‹endstream endobj -1587 0 obj << +1585 0 obj << /Type /Page -/Contents 1588 0 R -/Resources 1586 0 R +/Contents 1586 0 R +/Resources 1584 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1592 0 R +/Parent 1560 0 R +/Annots [ 1588 0 R ] +>> endobj +1588 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [333.4761 480.8577 413.3061 492.9174] +/Subtype /Link +/A << /S /GoTo /D (clients-per-query) >> +>> endobj +1587 0 obj << +/D [1585 0 R /XYZ 85.0394 794.5015 null] +>> endobj +550 0 obj << +/D [1585 0 R /XYZ 85.0394 244.5016 null] >> endobj 1589 0 obj << -/D [1587 0 R /XYZ 85.0394 794.5015 null] ->> endobj -558 0 obj << -/D [1587 0 R /XYZ 85.0394 769.5949 null] +/D [1585 0 R /XYZ 85.0394 219.381 null] >> endobj 1590 0 obj << -/D [1587 0 R /XYZ 85.0394 573.0962 null] ->> endobj -562 0 obj << -/D [1587 0 R /XYZ 85.0394 573.0962 null] +/D [1585 0 R /XYZ 85.0394 219.381 null] >> endobj 1591 0 obj << -/D [1587 0 R /XYZ 85.0394 542.127 null] +/D [1585 0 R /XYZ 85.0394 207.4258 null] >> endobj -1586 0 obj << -/Font << /F21 702 0 R /F23 726 0 R /F39 885 0 R /F41 925 0 R >> +1584 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1595 0 obj << -/Length 3437 +/Length 3080 /Filter /FlateDecode >> stream -xÚ¥Zm£Fþ>¿ÂßÎ#1ý4Ñé¤É¾\&íæv=º‹’|ÀÀØÜbpãüú«êªÆ`3™•¢ÕMÑTWw½=UXÌ|ø'fAè…±ŒgQ¬½ÀÁ,ÝÝø³ <ûçà9 7i1œõíêfù^E³Ø‹CÎVO^Æó³Uöó<ò¤wûëêûåû0Ì•¾HìqΛï>}ü¸¢Y#ŽÚxZÉÓî?¼âzR Ís>¿[=>¼`%¥UØ/yÿãêݧۅ |ñöèÏ¿}€,%¦Ëçwo?=¬~¢»7?|~xûîÓým¤ç«¸ÃunÞ­ú“ž¦ðÓo7?ÿêÏ28Ôïo|OÅ&˜áÆ÷DËÙîFÊ ´RŽRÞ|¾ùwÏpðÔ¾:©áà „rB=pÂê b/TðÏá}ÝÐæv0fžÓ]Q=ÕÍ.銺"‚»në# ºš®‡–_¹óC;~´·ë.O;"œê¯ÖæÍsÞà9Þ9³é¶9ko¨d%…™ØiïþñóP^ÌÙjFÕ‘gb_ðÜ${.Úº9û¤û†ÞbðÆB…p&QÍ`&"ˆûêß/õjOkÍ"-<éˆôAO¿ÌÜè_gݸÃ7¬jôpý+¾¸úS·ÿf¹„¿^rhӼ鼺ÙÀx¹?¬—LZºÝ-ïX€ûs0¢Øó}íeU{)¾V`d‘/Gò¿f Ò‹1Óæ¹è9¾²A0a8Öx¼Á¬¾–0ž_ð…Å÷³®W©õš.û61ÚSÇZølÞwxI¡‹^· áûàüÛ¦®ÙŽ“*ãøw‡"›0A¶¨†˜ é#z æþ‹£ Eëõ¼èˆZ´4o_·m±.s¢Zjsk懊hª€Z0ïdÂm¤ˆ<ÔyBº%‡œ’Y…^Gnr^=4½ÚåUGküâþ¡-ª æ|UO]ø¡gtÜS{pø&üSëO†~ÌÓŸUŠaÇN¶‹®Oøj(ö´/5ø¨ðâ  üÒîó´x:Y™”RV&Èù/RjZmd‰‘ï¹@²è&rìiŠåcY×{ sE`æ«-* J“ŠžoórO£bDZï9'B{j»|GóÛ<=4Ew¢'k¾îË$åMHÖ®åļ“ó¦Z0¿uý;ïèdŒ„à(#w0ÒÊ}Üé–ÌôX”%ÊbWtç@kY²K6n\W.<±­6=â8ŸÖn›»¢Í3›æÑò‡!ô¾ªa!|QÛ\ñt@I´˜?åIwèSŽöÉŽáÉv áÊbÞR2‚ûú‰f°ÅŠ¤Ý¦€¬‹Òž±¥Ötíh¸L–ä;Ç8a6 ߪ}S<e¾!±»œ1lˆÏí{ÂÚ$GÁÖv )ÁÈÚ0öÎü-Çk“£ûŒ†®V¨„?ÿÏm,]În›MÞ²vi«¹*ª±u¡‹Óöpg.‘ó^ŽÛÜÍj{Ó¾.£Òƒ0#_ŸòqáÉH:6нǾ |”2áØx¾Ë([ãÕº\óߓݾä‡`‹;–ñ¦,*&£æ-¥Nø»°-˜O2µ/x Öê+ö±Ó/{æÝC­<_úŽßò9i–U²›ŒÃ \i"7õ?œ÷{s;b[¾^ `^`Œ{½_òš”€%ã‹0Ѿ” ³G>¤Lâ3€{l%Ò— ¥´A)~o¤Éå¡m–e&år]T¼õEy|Â^:º^‘˜õrÛ«Ï„`S®Êœ©W.°¥ƒ”ýÓ§²ét€… -Êú`ZFs‚ÄîXËpþT7DŸ²˜@§âUƒ;P}n¼J²È—;ÖÍ¢p”ÝçMy¢gEå$¡ IÓé¡LXÒŒ¸ð¶À§`€ê7À®s7±X‰é!ƒU‚3å…Ap‘~_2b@?ÆDñ b¡!GkhÃI GUŽÆ€#kÜp£¤ÁªŽÈçáþêÀì[Û„GE•–‡,oy2äS·¥¬ -÷ìúÀWlÇK’?yh{zþžÓíÜíeä7ÈìoTãàZae㳩 HÏE~ÄØ];OÛ”¡;°^¶Ü‰ÚNA¶ ]ÀŨ8@cOm_d :ˆ)w ¼Ð„1.IÓúPqàxr2RËÙJD¢ÅE²z¬x›€ŽE·%$‘'MYþ±8¦åSÑl*@EKº£¡u‹XNû‚eyrü@Qð^ƒø±pòW“GÀœ¨O'¬h@ ŠÅå Z d`.3ÉuDSqßÛ.醒Wuãà<¢]`¹ ÛáE*Ú&¶PÂÓøºIšÂœAÈb#1>! 7h·G¢8O@\›ùwõ14LQ|ŸWÁ˜oŸé[Hð -²Smã3b¿£B‡ôÔ]r¢Ù|ŽÆ‚Ë2.­rÂÜ÷æSmÚK/—&B„K¸Ë,^þ‘7õBP^÷m±©£•é!«|…Úeˆ Ä(ý35dVÖ›ú.ÒÎÀÅÕʸXÜcžy—:èŠÝ”›…nê6ìM°)å‰(4=0p%üãÍr]cá¿çÒóÏqý±)êfèFr ¸¹¾¸v©Ø÷ †_ãR±s<*Pl„PÜnƒõ¦ùGPLHyh('’3(*ô]=t}©$,Lp[J·IµÉÝFPK‡ø˜·-WL¶Ä]8)uMC<Ðfëª~8A8ÂHéËLÑüi¶åé¶>NiGI/–¡ºÚ×e.®÷>ÙkÿŒf À~–N¢ çÁEÆ=‰A;”3ì¸ï9¨¼)p -q åÜdîç7EG…ÐT/YÁ©éX_ÕLp1`´Én1„˜ ×yÑ{>ðâ¡{ã¢ñ×¶Û -õë çŽýÁdsn—+p»É»¼ÛÖ‹Á4(Ð8ûàèPÊçgí춦)îÁX¸¢+I#p¿*—‘)0Ó-ŽßâéØBI¿>0½XyÒ¶ñ5ƒ6Ö`±#_¶5ŸxÝõ¢&ŽÅÓHøˆ´8:çeìùRÖ)¼¨+Oʾ¢™E?}¢6‡el#ÉvL膄…Áød`­Ð¥-“gžÚÀŽìH½å ~Dn‰Ã#•w\„ ¸ö!oh7ö˘g‘v ÔcÍ”á§ÔÓ¦0#pZìls -ä¤ëP·=\3µí«ÁÀ¹y ¦¡ž9—‚Ýõ{Œ§ú¯+z¸GzDßZ&Xñnø}Û,ð3`;Ãô€9€Ï6å_:ÔôÉa¢Ö9/zÆžÉ~ð¥Ê¢ÜÎ}37=ð Å0tæ‰O<ö'Ê·æÓZ qèKZˆÝâ0íç4 ³¾íßmlèçb?·Mnˉ To t³fîisÚwõ¦Iö[×kÀÇÉ$¨°ýÐåÌhÍkìò¤š>[4A™ÔÇm’²c„øµiSõ_)Zš„ÅÄêóÃ?ù N[‘ÇÃÚl¨_Š©qèiÝ—f¯ÇÔXônÞ;,,ãò*.Žé‚¨6ý‘@ Ѿä'Tà‹à¸b¾C§$1×-ÂÂ6†hyù]u¶\ãê£A¦q?öÈmŽÉ[þ^ù»ÕˆÙaüÇ:΋ܷäH1žÇsòs`ŽH扖շ‰/¤% €¨:Q) uTõ * ÑÆ°Ñ«(YÎ{ ·Ë€ÉcaÙªpŸMàCÍ ›øÿFÕŒ0íˆ0Þ˜;èfMhK¯lŠ0%+8LÄY!º§«6xm)±¤¯=#b“NÁYÄy¶xª§bRDE’ɬšˆólñ*9š#„h¸Ã2{¹)ˆÔü0Ô:Õ\Ð#Z@-ÑXK˜ mßîDµÏ `"o“¯ËOÙb„Cyé¥m…fÕ.¸äË8Ÿ­’Ç"ÉÒW~™‚8°¦ðÝoq£Z¨¿!f¸Mç„$%þ•}\Ç«¯Oâ˜Òz8¹zžìpÌ:«NVþâúŽ@ Á7¬’¸öµqZíÌBvL9øQey„à ¨”6€P ¡>€¹ÖBð|Šö)!3‚9]‚®î1KóµJRm†ww‡(¡SžD6Íâä©#Zµx¶œž0œ¦A¨¶=xRE˜rO}žú­x¬ž®‰+”Ûq³PåaÆùÔôæ—‹Û÷ï®!BªáÜ÷ÚÚÁ·ÓUIe ÉFõ há\V‘j&¨…~¾)5|wý#(¦²rx·%?}%ކq0«2}¤³' ©VD[Þã5$£\[º¯nïÞ_‚ee©“W—«U?’Í  X;a«†Š×pÓ¸*‚ ¸o‹‡x¨e+ÔFÆ >ßÂr˜0^•f«ƒÜdÈê k¤„«^<¥"BYÆ//n&t?ƒÆ®¿QE)üamôµ­2×UÚcËà £™¢eº'z+Å>z¿OòeTÌ@)‚Ø}±~Ü#|·£ÞÂC~OØØ!{´Bö Ê$݇ð鈅¯Öé,*ây?žÓ‘CÌì°ñF\ŽOX[!‹tT÷vêˆtÂö£e<Šî³¼îEÖ@èæñ"þaá}–—§‹% XOD—Î%Œ«òö]` æÌ~:òcë5=xE[L>Æ«ûlµÜeÈäéš»„LÒ=PZE 8ŠòwŸ²U±† hŽ©Í}¾®×E³:HeEä/gYZøè¿ØoÀù±ð +— ÑþzÄV|¥†â‘ö¸SiÑÜèßI6û²_¼¿ +":ÀGÙ0Iýoö§IúoÚÚs þÇÜÉám¹@ ͳl¹Ìª¡ž^”ûu»pÑ_yis·ðŠoäþY’û'‘¿ :øöìÞ?h¸ :§ñ³¿÷¬úFÔ˜fjý©tg‘,“¢t|þ¾þýR¾hœ£_–„är‡~3÷6eø[]¡PK«ž°"…!FsÖê׋¾dgëâ OXø1»p 8:áÂ9TÐ}Ki’ÃŒRíCÈ÷‹u|Cˆ‹cÂ9œL¾æ­éÞL*]Ï+[©7ní'“ô)û²3´ÌŸ0ÄŒBEí£Õˆ™ R¸ëƒ!ÖÇ…Ø3â% „š»`ʈuZ¿Ôáý¢Ë¾º»s³Aµå÷„1µênÙSV +€ÉI&_ªíÞ¨ê#¢p|¸ ƒîÁÕâ¬ö¡ýç²°ŒïŠ"^>î¨.n&“ËsÚS´HæA"y";ô,žx%)4‡Ú[ö„|¡5¡‚± o¿¼ ÃíG>Z !‡JŠîê[1jCÙSö€Qj”ÛÀð&þ|ŒFº M•“b{Z–èO±oMR,)ƒn€ö¸+ãí‚@¸·áõ·ª1×DAu¾{PÓJoÌÀ~>v—÷zÔ–·£ùjˆr‡­¬ÔC¶AÈ™gÉû<ôâŒúPõqõµÜï™NÓtÚ²9¦”ΰ€*¬ˆ>•eVn©¯ }©¾NçU(­ª+(r‰+Òw#aàŸú—W‹ÓHåÞS©6ëI—Æ_F =·¡„\â9Q1Û-"BBòã»äñ,ÁJÙ\†ÅCŒŠßU»9/ëQ|~¿ªžKdjxúqH†T *ëÚ5šò}~$¾C”ôµ xBŽ1µ!C¨“¨Š’B_ÀˆJÙ>ÇŽ8¨…µÝˆÆ ÅqHòµþî€4¤8M7äu€,áu¬ž†o:„„JÚJ¹]F%¼QÆšbŸŒ?Ì󦈼_DÈf@é–&Hj·K‹ ƒ †OÚšbŸ´NG©ÛwÙ!®…šL›Mq½­HÞt½K¥5€råNhw<Š=H óȕ٠é@chí6’ÜÛ8˜€d› PÞ‡ðaº^~ÂíKȺJ¯†mÍ$¼y~ÈòØ?}¡Õ‹cxó).žã8íòyÕiÔíà*b[²\ŸtG·¢8Iv ZJÓôBÑï'ã>F¸4n>V†‚ÏMñ¸F=%t¶Xç/UÁC@RŸÎ»Ð eïv ”–@ܳ7€†uæíXS‡$»ü #š¡7¯»mS@ý¤ÿ|%ý2Y,’<žAÄÂÕ\Aåð +—fñY˜œ#šJ³ z}AMÓÔ+ª.×ÜŸâ4©¢4T ‹(/<®–bvÆ6ÓrŸIX1̲õbŽ×ÒÓƒ6oãUªãªC”wâ+ oÃN¾ ¥Kˆéò¶·ã[Q‡$»ðÓÀZÓ­ %ÿè2dIl“QB,¡à \Ý@H–q”Vþ•Aý n¼Ë¿Â46þ¸Ï¡-8âijÿŠí›þ6þC^-|»ß?À“&Õ/ =t3³{=¥E;(¸9ç RîíQ­¡8I¾ž n Ù±í{·uàbv­M›Îc[%–o,[ÚZhÿÏŽ~ž3íï!˜|ŒnFõ|tÀ”"F™ð£Y}t0©¶²°þ¼þö¶ÿÛƒ³GÑ$Û5ÇI³3V‘Ë< ‡÷³š\yµÛo­[ŸûÛÇxU‘è_ãüÜäµÅ†t:’aÐè:òþtñAvH‚'¼¡” +btüWš1´u¥Ôàõpª%«!«·‘Wå¡0vÓáLÏ»Ù6PvÐ‡Ž»Ù6„«:†Cg}U½ÕŸÒäÏ.ª )Ú†P`?Hàäð"[FIꉗxwå1¶‹WÏ娎ºH@¢ldð¦jwÙ¿ 7w˼^y2ýM[7 Èóµ/ +çÆXÔp™Í׋2ëÁ‡ë²öæJ×A ï³Å"{ö[ÝØ^.Q”¼²pŠþT5yá¿:¤†É¶Æmúß—dðK-k7úïîÔ•ã!ßãUÌÏ=בç6 ®ò&+üóh±ð[c.G·á ú> endobj -1600 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[0 1 1] -/Rect [63.4454 738.9144 452.088 749.0762] -/Subtype/Link/A<> +/Parent 1560 0 R >> endobj 1596 0 obj << /D [1594 0 R /XYZ 56.6929 794.5015 null] >> endobj -566 0 obj << -/D [1594 0 R /XYZ 56.6929 723.0302 null] +554 0 obj << +/D [1594 0 R /XYZ 56.6929 698.798 null] +>> endobj +1597 0 obj << +/D [1594 0 R /XYZ 56.6929 673.6774 null] +>> endobj +1598 0 obj << +/D [1594 0 R /XYZ 56.6929 673.6774 null] +>> endobj +1599 0 obj << +/D [1594 0 R /XYZ 56.6929 661.7222 null] +>> endobj +558 0 obj << +/D [1594 0 R /XYZ 56.6929 173.6899 null] +>> endobj +1600 0 obj << +/D [1594 0 R /XYZ 56.6929 148.5693 null] >> endobj 1601 0 obj << -/D [1594 0 R /XYZ 56.6929 689.3491 null] ->> endobj -570 0 obj << -/D [1594 0 R /XYZ 56.6929 552.677 null] +/D [1594 0 R /XYZ 56.6929 92.1409 null] >> endobj 1602 0 obj << -/D [1594 0 R /XYZ 56.6929 525.9649 null] ->> endobj -574 0 obj << -/D [1594 0 R /XYZ 56.6929 411.5673 null] ->> endobj -1603 0 obj << -/D [1594 0 R /XYZ 56.6929 383.9327 null] ->> endobj -578 0 obj << -/D [1594 0 R /XYZ 56.6929 225.6356 null] ->> endobj -1299 0 obj << -/D [1594 0 R /XYZ 56.6929 193.4614 null] +/D [1594 0 R /XYZ 56.6929 80.1857 null] >> endobj 1593 0 obj << -/Font << /F37 791 0 R /F69 1599 0 R /F23 726 0 R /F39 885 0 R /F11 1367 0 R /F41 925 0 R /F21 702 0 R /F53 1017 0 R /F48 940 0 R /F62 1050 0 R /F63 1053 0 R >> -/XObject << /Im2 1039 0 R >> +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F11 1384 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1606 0 obj << -/Length 533 +1605 0 obj << +/Length 2016 /Filter /FlateDecode >> stream -xÚ¥TM›0½ó+|©¸6Æ`³IÚ²RÓ4a«ÕxT‚Ó@6Úýõµ3·¶ôTEóÆoÞ|x€"b~ Ž “1JeŒ9¡•[ µ9ûêQÇ Ï¤ð–u—{Ÿ¿°I,“(AùË–ÀDŠòêÉÍóé"#Nü!Oˆ—Í&à‘ðXNÇ‹,4þ1[f“éb¤±Ÿga,ˆ0ñÌ)Lg£ïÙøó P§Ôžó{oš_¹m–f»øí==T™žï=‚™ ˜J¡­s†yÌØÙÓxKïçEðæô:4<Îæ"J¦±¡éq‰fŽìô–z«lO‰ßÕ½êÀ,7ZwÎÝkûäþ/¥và)šŒê­-¶uið[xØUE¯*8˜ØyžE_€U· ã`wXUz[€×H¶.²RZ!—{Sô7üÐŽÛôRŠ%çÑ©'ÂTÊä)…Ú{2è]·ÊÜ,#‰Ÿoê˜Çâ- ”úŸ Œ‰I§Àßë]بWÕ\cÁ*uÛ›|u»vx_÷v溵¹å¬Â¥rÚÂÏæî ªö¾ê:å8úe¨ÁÝaÕÔ%ìÝQ­Àp#¶ý¬Ní_Õ¾Ð*å­î]HÓè#˜îâÀÍ9Ε‹ÿµÛŒc»›hþ®îÿÞûë!6¯¤ÑðJ›ëÄ"’é¹(;/É>V~yAþ.ýÐîÌendstream +xÚÍZ[oÛ¸~÷¯Ð£ ±¼_€ÅÚ4ÙÍÛKâv±gYm„ãH^KnпC‘’)[¶šÆ1Š‘H gÈ™o†3¤I„áDZ Ì ”áH`"¢ôa‚£Ïðíç ñ4qK‡Toæ“WWLEIe4ÿðÒkM¢ùâ¯éÅ/¯?Ì/of1x*Ñ,Oß\¿{ëzŒ{\¼wuýóï7¯gŠOç×ïß¹î›Ë«Ë›Ëw—³ØMa<8ø±·s;ȼ__ÜÎþžÿ:¹œw I0³³ÿgò×ß8ZÀZ`ÄŒÑ#40"ÆÐèaÂC‚3Öö,'·“Ãàk3tHiD¨`QÌ8Òx|ƒXÆ5RX‹£˜d„8ÂËÃÀË¿¶#ú¬bÂâBY£r…¤RdkT•p†4c"R‚ *ÁàÖª·_îÊå,–ÜÐéÛ¬J×ùªÎËbWóT¯¤¤Q(äy·*b¯(¦ ™£æÜcÙŽ8¬  €ùêN„ ê‚;Ñèâ'»èWW4¤THq­€»%˜ÿùáÒÑô¸Q¸äÌý÷í Þ¯²ÂÓ°€¨ 5žè¶LÿŸÕ8†&ÓFd ûާÕ&M³ªú´Y.¿Î!Sð#ŽÙt~ŸWŽ"-7E­ÝÐܳ(ÊÚ½$«Õ2­ü…VdšÜ-3ç‰uéŸ÷ÙÀjEBRâgzõö1©Óû’9“íŠê¯« †U`¯ça`Vü”°’Æ -$ƒV=7¬®’|9 +-K´Yψžf†Í´üO‚œåÅg×Y9Zxiíáe‰:xY¢Üshàe¿þ ð +ív*x¹Å‘SFp©2˜°xICÀÇœ^˲ʞ¶À¼©²8b”`µ§ÚJ^`[•J Ã%3Š2H0ªÎi”7y±øŸ·Æ±>oŸwÀ¢ñyÛè|þ É]üÈ&“༛1“I…„RgÝý/Ê¢x¦ÉR`‘¥õ¬¨ãG¶D~Ì„³šHRÐÜ™­6j± o—²ð˪6½¼ºo’71˜¼´Y ŒSÙŒ ¨_„xËvÄa›‰ˆÂtÌfðÞvÖ„è5èzU‡¯ Æ_ŒM“†Iãj¶;/Òò¡k¥Á]ÛqøgvwÞ¸›ù$ð&‹š‘©ËÓ¡Ýö»<0—Hµ9|hr&èΙˆàá߸õüþöÃÀš)·u_«ž¤X 1ÒÀ‡'_1ÅQ(û ´Yر@ åy|QP £1 DX!‰Çq}ðroP°®“×Z©q[¦Â§m™ªl´ul³xÐÕª,UWšî¯„ÃZic‹f)Ãë q"Z­ma\â6ÀT!°A—ÉÛƒÔ¦IÜ™BAh`úS¸/Y)F‚ê±Ä\À0úœ½ÉÒ/OE(šӡ¶Ï-Íò/™ûØ*5¼Íšñér³È|+Ûr@ª«”÷*dÀØ}±©ˆ}&îá#æ©m|u ÚÉÂ;„îüÓl1”²Ü}uN +÷¼¾øíƒÏnÛ©ºæl(Éç#g0¡íOD·Çößw ÿ¼c|" b +°S…°êßìÝ#0,‘¦FE17 aA¶^ÐCe{ÉÁô1æœÀ^˜$`kÆC¥ñ°«ßå˼ööyÌk¿ßIºÌÌ¢g/ÊôC¸ŸK¶ISÁåÝJà¦~£îJ@Ûú¸ÉÖy*W V&TSœè1¨Ž(³¥j”yýqO•¢Ÿ­îŽ +í¨¤öT‰Aåöf¤'ö´ª¼ñ'<ߦKj`Ûfîò°.CªÃºì¨]¾_ÕÕ>0JÂ&÷ÇÄvTr{Ú´µ÷h³ÛD‚ø×\4ŽFÔSB‚iw®lWlÚÛƒðÚç­å*8¢Ý³µÍ„ו²Z&é~F»Èþtd@Ã8=ÿÖ_¨l³c F­Ä.¹ô“jtDvgYhšª©ÿ aKendstream endobj -1605 0 obj << -/Type /Page -/Contents 1606 0 R -/Resources 1604 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1592 0 R ->> endobj -1607 0 obj << -/D [1605 0 R /XYZ 85.0394 794.5015 null] ->> endobj 1604 0 obj << -/Font << /F37 791 0 R /F23 726 0 R >> -/ProcSet [ /PDF /Text ] +/Type /Page +/Contents 1605 0 R +/Resources 1603 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1611 0 R +>> endobj +1606 0 obj << +/D [1604 0 R /XYZ 85.0394 794.5015 null] +>> endobj +562 0 obj << +/D [1604 0 R /XYZ 85.0394 477.8665 null] >> endobj 1610 0 obj << +/D [1604 0 R /XYZ 85.0394 450.2752 null] +>> endobj +1603 0 obj << +/Font << /F37 799 0 R /F39 895 0 R /F11 1384 0 R /F21 710 0 R /F23 734 0 R /F65 1609 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1614 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj -1609 0 obj << +1613 0 obj << /Type /Page -/Contents 1610 0 R -/Resources 1608 0 R +/Contents 1614 0 R +/Resources 1612 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1592 0 R +/Parent 1611 0 R >> endobj -1611 0 obj << -/D [1609 0 R /XYZ 56.6929 794.5015 null] +1615 0 obj << +/D [1613 0 R /XYZ 56.6929 794.5015 null] >> endobj -1608 0 obj << +1612 0 obj << /ProcSet [ /PDF ] >> endobj -1614 0 obj << +1618 0 obj << +/Length 1321 +/Filter /FlateDecode +>> +stream +xÚ•WKÛ6¾ï¯0öä"ZEJêž’MÓnEãžšh™¶…•EUlÜ"ÿ½)[¶àÔ0 ‡Ão†ó"Eg¡ùÑYÊIȲx–d1á!å³|ζfí§;êdbÎ3“‰Õ€³”ð4JfÁ)È»åÝâCDgQH„ˆøl¹t‰$!”Eél¹þsþ´“u§š‡ âá}lÍHqQZQå&ë5N=Ö^vùÉòˆÒíd‡Ìƒî‘Èe…D«ÜR_£°¬ÖȨŠü¥’{§j£Gô]jCß*8/œR’qÙÕàÏ£Œ@ÈhddAD–¥~ *ݛÄ˸ qœ$NøÍ\LR.F`÷ª™Äâ&¤ÑíP®&Ð’D)Ͼ7 ^©×Ó€&5R*n²oÀ›¶1&Ûxü?!W¥Ì_vºTH±Œèmq°ÄP™‰©q—ÔJt¬Ú)ãKUŒ“˜Š£*[RªË âùå€f$a1ÖømQm¤0Ui*)k…£mÎÑiwò‹BêsF•m(‚ÎsãG:?–"ðô\ ç¯;·ÛVŽÕá{êprX1@µªÝIl"ØüµèvºïLÙw¦—íÕÅgw¸†2Öµ[œY*×€©]¿UH¹êRop|þ Ç“¦¡Z2h·.Å>û -³yÑâ(1T,; U”‘hˆÔVëµÛ²Vr*‡(I³„:qCë°Î8‰%™k?<„òQ{k|ï44 +ÅÎOÀ9z<‚f¦›î‹Î¦^nf—›-½:`Ò™Ú¤"¦ãø˜0ÂÍ­eÓ>˜ Uº Öèî/ªêÑÖZÛÔsÑ´gb­ªB–ã°ME®|Üyø^ÂëÀní:S¹N·ÜÊ¢j»óÔ9uÉ(ÚX@?+ßÎA¸ðXîê«Ü×¥Û´Ó¯HØ’ލkÕ”în•uíIˆî˜1½¸Z±X˜p…pCwH@ À†ÀhP€ +[#y¿ÒÛ¾­T×Þ#o: ^‹²DjUêüÉß?<ÑŒ¦8ik™O^]Þ+©¡¦j”uæúáÓ·+àæ\c®÷{]ìyZ¿­¨üv­763­6Œ$[„-Sæþ,þ¼8ý× +ljiÐa2>DHìo‘>¢(=›GçëpÌÅ^Ä´obS~¢:’ÈÔŠeÑè—Š™âÑ] c‹ñß%# ãó"7Mß»Øä~n".îª.!Ø.G|€°q"o°t®†viӭ߯Tó¸x}>,vøJìïèÐAãÛ¤_uïÑ“ûå‘!“F]°£‹Ò©•Þô«&?an¸jÔñÝqŠ8dùU›@§>?½Hp”ÁoÏÑ#4¦;e‰;×6|É^ªûaáŸendstream +endobj +1617 0 obj << +/Type /Page +/Contents 1618 0 R +/Resources 1616 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1611 0 R +>> endobj +1619 0 obj << +/D [1617 0 R /XYZ 85.0394 794.5015 null] +>> endobj +566 0 obj << +/D [1617 0 R /XYZ 85.0394 769.5949 null] +>> endobj +1620 0 obj << +/D [1617 0 R /XYZ 85.0394 573.0962 null] +>> endobj +570 0 obj << +/D [1617 0 R /XYZ 85.0394 573.0962 null] +>> endobj +1621 0 obj << +/D [1617 0 R /XYZ 85.0394 542.127 null] +>> endobj +1616 0 obj << +/Font << /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1624 0 obj << +/Length 3449 +/Filter /FlateDecode +>> +stream +xÚ¥ZmoÛFþî_¡o'Å}á[q8ÀMœÖm‘ôwEÛIK¼P¤BRvÕ_3;³+R¢ëEÑh9»œÝ×g†3þ³ ôÂD&³(Ñ^à‹`–í®üÙæ¾»¼fa-†«¾]]-ß©h–xI(ÃÙêqÀ+öü8³Uþë<ò¤wýûê‡å»0¬•¾HìqÍ›ï?~ø°¢U#Ž:ö´ˆ%/»}ÿvŠSèI%4¯ùt·z¸;ÁJ8”V¡ÛòöçÕÝÇë… |8ã5ÜÑŸ{;JB?ŸîÞ<|¼_ýBOo>¼ÿtÿöîãíu¤ç«{xÂ}®îVNRCi +_¡˜¾\ýú»?ËA¨?\ùžJâ`ö ¾'’DÎvW:P^ •²”êêÓÕ¿ÃÁ¬yuR; „rB= á õ‰*˜B9¼kZºÜ"žôTÖM»Kû²©‰`·Í3 ú†~¿rûæ§n<µ7›¾Èz"›ïÖíSÑ¢o,ÙôÛ‚µ7T²’‹âÄjïöáÓP^ÌÙjFÕ‘'¾àµiþTvM{$öiÿ ½!Äà… +A&QÍ`&"ˆóê?ÏõjOkÍ"-<éˆôA³ŸgvôãI7ö…Åð £=Üÿ‚/îþØï¿Y.á_/=tYÑö^Ón`¼ÜÖK&-íí–·?-Àˆý9Qâù¾öòº;?¾V`d‘/GçÍ@¥—Äq*¼$(¿tû"+æLJGæL0ˆç¿I©i·‘%FÂÒ‡E?q boaøÖÍžâ!r‡ð8qu±qÅüfî¦í{Iâ2äžÐ—óÕ•¬³´¦ý¶Eµ§Q¹ãXúÄ—ëŽ]_ìh²+²C[öGzZižJ3'²Éϟ’LÁw=8Jde*Ý•;0òuó9D?oËlËòªhT•»²?En3ÈÓ]º±ã¦¶)å‘g”hŠGÖØ{îÊ®È n@WÆäÛºðEm’ÏãO¢Åü±HûƒËaÚ'Ç€ :Øû€„;‹yGÙ ž›GZÁ^s$m/„t]VFȆÚЯóÈá6yZì,ã”Ù¤ü|¨÷mùTVņ,ÃÜn y¸ËfÂ|%D$¢`ó=Ð’`d¾˜LëO†ã¥ jÒÎ Ð×À •ðçÿ¹N¤Ýa³):Ö.]µ&ßG5v62ÞÌ"ƒÖZNaWuŽÁtðQùFÄ£à1åC“‘´¨o {ƒðQ*ÇÆó}a D‰Äè¿ÁoñGºÛW< ¶¸3qª²f2jÞPš”çØ·€mÉ|Ò©{)‰V_q¯$H¬~Ù o&jåùÒ·ü–Oi»|)Þ€reÙ¥àÍJ…sw7{#¶åÉ ı:j(¥pšœa/ò!Ÿ~d+‘¾dl¦ã6ã÷Fš\ºvY5YZ-»uYóÝ!’úèæø1¡§ß ! ê)e«Â7•­[çþ•lÙÜa‚ää8 0QA8âLCKH!Æþr¼²–¡É"†>e2!ÀX)Ä«† \¶½HÛÈeÛ=7íg¢p˜Ýmu¤¹²¶'¡iÛ—Ù¡Jù¤9q(o 4.Áå.À¾s3²˜Iì@ˆQ‚µå…Ap–Ð_²bÀSq%ƒ…–I¬*(§QVÂQ] 1àÈX7&Ì¢§ÁSjʉðB`æ­mÊ£²ÎªC^pj. qû-çÕxWqÇn¼%9”IïzþŽóÝÜÞeä8ÈìU“`iÎÆgržÊâƒó”ˆAu$¾&„Ò‹‚ÈÎ’÷#Ôäc˜'„Hd»7å6üæû²*}ÀÍtÏÁC¡ +pžUŒHæå†~Óü‡®?Ûï)­Eçv#Pb\ ƒ±x}uv|.£Kç‰àš2´ëe˨¤ËÐF\ ‹6ñÔIhû2_ ¦Ü1ðÂ8< ri–5‡šÇ£-¹Á:Ïâ0ˆÑâ,[=Ô|MÏe¿%(Q¤mU2@¦c©h6 ¢%ÝÐÐ8‡,Ç} Ѳ:Z~ ¨‰‚AÃñaÏ_OFk"—OXш€!Œ+«´ÈàU|¬ sA×§ýðäuÓZ|St ,à!`ÇAx–‹¶)…-õ¦;÷‚q±)DØŒ»Ì‹§åŸEÛLAåE‰k´M…°LYµà+ÐÎCL!Féט©!³ªÙ¼ÐÉ‘~tB.¶úžÆšðó,úŒàA_î¦Ü4Vè¦ÒÕ`€lJy" +c  lSàa g¹°1øÇŒßq1ûW¸þÜ–M;t#9FÜ\`\ºTâ{ +ïq©Ä:U(&B(nàÁ~Óü#¨&¤<´Ô€Éú6ˆzW+ 앲mZo +K7ÔÐ!>]Ç%“i®q×ä%.ÊleÚìl$"Œ”>Ïí_Va](϶Íó”v”ôª‹ûpafãºóI§ýœµ6÷YÚm(¨X.sîr ¬œaÇÔAéMi©M(§¶µ[ß–=UBSÝiRÓ‰ ¾ª=-@ `´Éþ1„˜ ×yÑ{>ðâ¡}㬕è>2HÓ¿…vП%€…°ZÁÉd(Iåï: B ¦åÊ•ˆ‡‰ù +þ•󻋾®ôüHFPƒqHˆƒ°õìËLx¾NE‹csד ay¿“³· Üh6¸”e¼r6—‚Ø3pâÐJûǰM,cºSÓ¤-…6QˆÂ¦ŽoL’½ˆ£Í ˜ lù csïè¬U.ö %53ŠP3w¢F}ê0¸uh¬ÏþÑÓ€púÖó÷¼sìRP¨ë“KšßvôÑHÅyNq–{{S*3 +-û<í ÛþæÎã« ð[ðJ(n8(®„œç–?RÌÇiÆŸºms¨r¯ùUÐ8(»â¦‰ÚZ€«šš©0ã 'ÀŒS˜ñ—óàT0WWÇ©ݳl‰âºFÏ󆟷TM½›æÖiGU¢øžh[J©ùýÏDHóœ0jÇ/QÑ¥ìJ=ß6T6)¤Å¨˜V—‘änØ¿øUé–jêÕ½°õ⤬…^ÖSç@P™^ <Tü×”Ãÿ ºé¶ñ‹ßÀ£Äâ-€íÍó‚U=Y£Æ±‹cr 9æ¹ +¸aŽä]Ño›œÁ4(Ð8Ý'Mpt(å‹ÓÍꮡ%vb¬ ÜññÔ'W!T.#S`>±3Z?¼EéØBÉ>>ˆÝ±Š´+M!Ð'Økc Bàü¶ê–xÓ»£¦–Åãèðiq|è‚·1ò¥>lL¦ð¢fT¢<)4|E3 ·|¢6‡mL#ÉtLè ƒ±d`¬'è§«Ò'^ê¾ `ÇŠv¤ÀÞŠ?KwD€á3•w\„ ¸º‚tó­M‰Ó‘v)Ôcí”ágÔÔ¦0#pZlms +ä´ïQ·9M®™Ú¹j0°n¨ih†gÖe`n}Cc‡ñ”û¼¢‡w¤)úØ2ÁŠoÃï›fA€»©† —ìÈ|¶)ÿÜ ¦OµÎiÓöL÷ƒoUåöö£¸é(†¡3O|ã1” |c>Á@‡¾´ƒØ!Ó~A‹0ë›þÝÆä·;ø…érN¡œ5ÐÚ¹gíqß7›6Ýom¯§Óœ ÆöC_0£5ï±+ÒzZ¶h‚2{¨»4cÇñsÓ¦vŸ):Z„ÅÄêÓýwü—­Èãa²4&ê—bjzZ»Òìõ˜šçæÎaa›WqsLD5éç#ÚçâHƒ|WÌwè”tÌÀv‹°°M Zž©°-[çØúhiìŸ&ÇŸº­Àà@ŒåSçBØ®€³IlàLT}ÐH¨lCÄ´Ø7U™§[Aä>Ñ:iGàÁúTñå/—ZPi)5õG ¾«iþö pÀ<ŠŒ³=öt LøPx³D_œÜþ5ÑåÑÿk$§/endstream +endobj +1623 0 obj << +/Type /Page +/Contents 1624 0 R +/Resources 1622 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1611 0 R +/Annots [ 1629 0 R ] +>> endobj +1629 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [63.4454 738.9144 452.088 749.0762] +/Subtype/Link/A<> +>> endobj +1625 0 obj << +/D [1623 0 R /XYZ 56.6929 794.5015 null] +>> endobj +574 0 obj << +/D [1623 0 R /XYZ 56.6929 723.0302 null] +>> endobj +1630 0 obj << +/D [1623 0 R /XYZ 56.6929 689.3491 null] +>> endobj +578 0 obj << +/D [1623 0 R /XYZ 56.6929 552.677 null] +>> endobj +1631 0 obj << +/D [1623 0 R /XYZ 56.6929 525.9649 null] +>> endobj +582 0 obj << +/D [1623 0 R /XYZ 56.6929 411.5673 null] +>> endobj +1632 0 obj << +/D [1623 0 R /XYZ 56.6929 383.9327 null] +>> endobj +586 0 obj << +/D [1623 0 R /XYZ 56.6929 225.6356 null] +>> endobj +1316 0 obj << +/D [1623 0 R /XYZ 56.6929 193.4614 null] +>> endobj +1622 0 obj << +/Font << /F37 799 0 R /F69 1628 0 R /F23 734 0 R /F39 895 0 R /F11 1384 0 R /F41 935 0 R /F21 710 0 R /F53 1027 0 R /F48 950 0 R /F62 1060 0 R /F63 1063 0 R >> +/XObject << /Im2 1049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1635 0 obj << +/Length 533 +/Filter /FlateDecode +>> +stream +xÚ¥TM›0½ó+|©¸6Æ`³IÚ²RÓ4a«ÕxT‚Ó@6Úýõµ3·¶ôTEóÆoÞ|x€"b~ Ž “1JeŒ9¡•[ µ9ûêQÇ Ï¤ð–u—{Ÿ¿°I,“(AùË–ÀDŠòêÉÍóé"#Nü!Oˆ—Í&à‘ðXNÇ‹,4þ1[f“éb¤±Ÿga,ˆ0ñÌ)Lg£ïÙøó P§Ôžó{oš_¹m–f»øí==T™žï=‚™ ˜J¡­s†yÌØÙÓxKïçEðæô:4<Îæ"J¦±¡éq‰fŽìô–z«lO‰ßÕ½êÀ,7ZwÎÝkûäþ/¥và)šŒê­-¶uið[xØUE¯*8˜ØyžE_€U· ã`wXUz[€×H¶.²RZ!—{Sô7üÐŽÛôRŠ%çÑ©'ÂTÊä)…Ú{2è]·ÊÜ,#‰Ÿoê˜Çâ- ”úŸ Œ‰I§Àßë]بWÕ\cÁ*uÛ›|u»vx_÷v溵¹å¬Â¥rÚÂÏæî ªö¾ê:å8úe¨ÁÝaÕÔ%ìÝQ­Àp#¶ý¬Ní_Õ¾Ð*å­î]HÓè#˜îâÀÍ9Ε‹ÿµÛŒc»›hþ®îÿÞûë!6¯¤ÑðJ›ëÄ"’é¹(;/É?V~yAþ.ýÑFÎendstream +endobj +1634 0 obj << +/Type /Page +/Contents 1635 0 R +/Resources 1633 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1611 0 R +>> endobj +1636 0 obj << +/D [1634 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1633 0 obj << +/Font << /F37 799 0 R /F23 734 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1639 0 obj << +/Length 69 +/Filter /FlateDecode +>> +stream +xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream +endobj +1638 0 obj << +/Type /Page +/Contents 1639 0 R +/Resources 1637 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1611 0 R +>> endobj +1640 0 obj << +/D [1638 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1637 0 obj << +/ProcSet [ /PDF ] +>> endobj +1643 0 obj << /Length 1964 /Filter /FlateDecode >> @@ -7135,86 +7253,86 @@ i ­èרÚ:‰óÎÐÃBYn?z·XdÌqâd¾©Üä¤ÚNí:ørðï»QÕaáƒL·CÕMucVìâªV.Wª4 Û8Hü»Uoy)”@»Zìo+B)ˆ×­©ôD9ƒ©;B.ÊõTyåvÂ)Î6™îZds§¡ÁÓÏMí­µ°r=¶öä&vÓž®é^/yr€¡¶¯ÓP;«y Â1{9B€FãŸà{ËוÂM>p\×-ž‘7>å èWˆÌ¨WKÐÆ 5m"û¿À¥–€ã6WUŸÔž9ZØ×•å,¶VHbžþ‹'¯´=Í\¦pÀŸ'8TÃ[WyÌ#‰6Éyè5µÒÇî:4 ßál 3,•ßbÏ[œ+ªë/WF".ƒ›ËÊ?@”€/jŒu“1Ô¢+l',{_¼2ãâ•sä®ÏñÛªÊ ¿&–Bú–åç !G˜ ¥Ìrcø-мûãËü “¤%œ¡i±Iæ² —â~ÚøÑŸ/¯6³Âv¡ámÒ¥ß;»è½‡CÀê/aïoãã<,EQ^Çsór4 ÝÅpµö;[ÃïVÎy7G)JΑOü©5­¿|hW°hpk·IQ„"é5¶ÏÍŽûª‡]Ù)C™‹_Ú‘Âõ%KÄQXDñ¯oʬ±]ªÜïʽe×SX{üâññ|>‡¼+¾,}w¸ÉÀUßÄx³Q³Ô}\Wù¸·öß¶ -ߣ«ª]qöü´Þíâ³äZÄ^d{‘¡Éep …E\æÞ†RÊ[oóûæ½»ÿ¡êŒêendstream +ߣ«ª]qöü´Þíâ³äZÄ^d{‘¡Éep …E\æÞ†Ræ·Þæ÷Í{wÿ¢BŒìendstream endobj -1613 0 obj << +1642 0 obj << /Type /Page -/Contents 1614 0 R -/Resources 1612 0 R +/Contents 1643 0 R +/Resources 1641 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1592 0 R -/Annots [ 1621 0 R 1622 0 R ] +/Parent 1652 0 R +/Annots [ 1650 0 R 1651 0 R ] >> endobj -1621 0 obj << +1650 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [348.3486 128.9523 463.9152 141.0119] /Subtype/Link/A<> >> endobj -1622 0 obj << +1651 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [147.3629 116.9971 364.5484 129.0567] /Subtype/Link/A<> >> endobj -1615 0 obj << -/D [1613 0 R /XYZ 85.0394 794.5015 null] ->> endobj -582 0 obj << -/D [1613 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1616 0 obj << -/D [1613 0 R /XYZ 85.0394 576.7004 null] ->> endobj -586 0 obj << -/D [1613 0 R /XYZ 85.0394 576.7004 null] ->> endobj -1617 0 obj << -/D [1613 0 R /XYZ 85.0394 548.3785 null] +1644 0 obj << +/D [1642 0 R /XYZ 85.0394 794.5015 null] >> endobj 590 0 obj << -/D [1613 0 R /XYZ 85.0394 548.3785 null] +/D [1642 0 R /XYZ 85.0394 769.5949 null] >> endobj -1618 0 obj << -/D [1613 0 R /XYZ 85.0394 518.5228 null] +1645 0 obj << +/D [1642 0 R /XYZ 85.0394 576.7004 null] >> endobj 594 0 obj << -/D [1613 0 R /XYZ 85.0394 460.6968 null] +/D [1642 0 R /XYZ 85.0394 576.7004 null] >> endobj -1619 0 obj << -/D [1613 0 R /XYZ 85.0394 425.0333 null] +1646 0 obj << +/D [1642 0 R /XYZ 85.0394 548.3785 null] >> endobj 598 0 obj << -/D [1613 0 R /XYZ 85.0394 260.2468 null] +/D [1642 0 R /XYZ 85.0394 548.3785 null] >> endobj -1620 0 obj << -/D [1613 0 R /XYZ 85.0394 224.698 null] +1647 0 obj << +/D [1642 0 R /XYZ 85.0394 518.5228 null] >> endobj -1612 0 obj << -/Font << /F21 702 0 R /F23 726 0 R /F11 1367 0 R /F41 925 0 R >> +602 0 obj << +/D [1642 0 R /XYZ 85.0394 460.6968 null] +>> endobj +1648 0 obj << +/D [1642 0 R /XYZ 85.0394 425.0333 null] +>> endobj +606 0 obj << +/D [1642 0 R /XYZ 85.0394 260.2468 null] +>> endobj +1649 0 obj << +/D [1642 0 R /XYZ 85.0394 224.698 null] +>> endobj +1641 0 obj << +/Font << /F21 710 0 R /F23 734 0 R /F11 1384 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1625 0 obj << +1655 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj -1624 0 obj << +1654 0 obj << /Type /Page -/Contents 1625 0 R -/Resources 1623 0 R +/Contents 1655 0 R +/Resources 1653 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1592 0 R +/Parent 1652 0 R >> endobj -1626 0 obj << -/D [1624 0 R /XYZ 56.6929 794.5015 null] +1656 0 obj << +/D [1654 0 R /XYZ 56.6929 794.5015 null] >> endobj -1623 0 obj << +1653 0 obj << /ProcSet [ /PDF ] >> endobj -1629 0 obj << +1659 0 obj << /Length 2543 /Filter /FlateDecode >> @@ -7227,116 +7345,113 @@ R ’ r”OœBç=Á 1j"«¢ºÑpQɧUäzý"GöÄÙ G,ØÝfS6ä ÐBdz˜€z²Ó„Q™DÏ B0q¶Ah3>£Œ7«®sÙØ£FfÁ'‘«RuJãÆÕùö‘]ôçÛ/¨N‡ÝVM)gQø|$¶Ì­} 8Épat*ÌÒ¹Ã^‰©€ck ˜Ö…/ ‘úf8ùtTù‘w)Ë¥áZ½RÜ0†Oå:»^•˜Ã&Ù:v3*LO„Y‰ÅèÖt4™\a¼°[`\ÃÈÈö®ž„Ž—ÌÉAM´Ěû«„Ä„ €É,Ö£ÄvFø[vAé÷Aô´QêÜéüY4²³Álˆ†±ˆC¶ýB=ù¸!‚nÌÊw‰P‰ü¨jiˆ¯ÔàbºHêØìІ Â÷ZÁµêμûž¶ºž–Ï܈RvµïY×ÛæÕ¨äjµ¤½¬s«I˜ŒéT×wìDDåïÛÍêv{K‹<õ0Ø>Þá0(î9±Þs@ܘe·ž«„D±é Ønu»ÁƒÖÄqE?cÔq,¦…îÀ³ÆúE£ÁĘŽAÄ)ôkÙ>ËRži6”šQÑÇÑ í%"Û2R¡q¼µ2$Q†£5ÄÞÞ3Xßñ±bɾ¾Ûºù~­(z‚Hׇ î †FX³Á¿,0x,ã&þ,<^ NÖÀY_Ö# ÆÃkfÝOUÿÕ‰[¸‘{Y›åj_¼ˆ1î𥑈6Hy ÿ/óŽ#çª€Š ã”U#7Cã@Q²€.ÿ¾ô™Ñ„K ÷yIJ­¥¥tG6µí a)\§ë€Ö&tÅŒ‚þ[år Òéú@Øèªé)ŽL½"Ÿûæ¢@ù<ópBµÙ>~æÜpËBtG‰ãÉYxEìÅbè á¥…9`°8#Û–8Ϲ6aù/3!(¬ÝˆUÐâ£:J¼TœpŠq«ëÄLM³ÿ@ÏM •($Ñì]€B‰±c€2i ?P‡nþmD4“Ç v;)*¼Q¾Ý3,$¶×`(‡æJý× éz`ê„Þw§Y1J†|%\‹B¡kùüEÙi¸U³“eÉJ}“/Ë…ü¦¯KÑX%=›4øªQÕ‘¢®óñg¯,•IJáŽg k ¥TŸ%#.Q=( ‚ש©ö¦7F ŸgàÑ[¦Ã–è@±¸ˆ$ŸægH@Ä%²ZI(Ž":ž( 6SaUŸiQc¢õFêÆ†EiX*×5ÔÏ]OÕ-ãÖXXE p³Í‚¥¢o¹‡›MÔºõÁùˆ4òK®øbðج–S€¼V(Ø&ˆ0ð[P£ ÄNg[iÝÑÒF´åêNuЧ—%KÞ©gI«w}o }U¯K­yHÝ2Ž"ÛüÁ×ý ÆŠýô3À‹¬ÉC–Påú‘?{°GÉÏæ#Sð¹c"ˆ£oë¥yó–þ®‚¸åé·žøqsˆ™Ìy™Àfá:ã¤m,ßû¶¿š°f¬…´íº¥®ÙÀoçÁâgþe5ñÐ7þùçìÀשŸ%ÃF¨g–¼=mü‹Áßû j=¢Xendstream +®o¬ƒñ+ñ'E\2}8Ç’;i %Ò‡ï&ª°Wõ\~jÀaÛÍ{³˜¢GË!zeoA_^†NmÞxš^Xð”Ð;’ù‚Ïr{z8Ø'"Hóȃ…×UØNÑô©|hÑçò+Å™X‡¬Yzœï_wEî”b8Iù‹Oï×WHÎÄšæÝǧñ#þði>ÀoçÁâgþe5ñÐ7þùçìÀשŸ%ÃF¨g–½=mü‹Áßû j•¢Zendstream endobj -1628 0 obj << +1658 0 obj << /Type /Page -/Contents 1629 0 R -/Resources 1627 0 R +/Contents 1659 0 R +/Resources 1657 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1634 0 R +/Parent 1652 0 R >> endobj -1630 0 obj << -/D [1628 0 R /XYZ 85.0394 794.5015 null] ->> endobj -602 0 obj << -/D [1628 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1631 0 obj << -/D [1628 0 R /XYZ 85.0394 573.5449 null] ->> endobj -606 0 obj << -/D [1628 0 R /XYZ 85.0394 573.5449 null] ->> endobj -1632 0 obj << -/D [1628 0 R /XYZ 85.0394 539.0037 null] +1660 0 obj << +/D [1658 0 R /XYZ 85.0394 794.5015 null] >> endobj 610 0 obj << -/D [1628 0 R /XYZ 85.0394 539.0037 null] +/D [1658 0 R /XYZ 85.0394 769.5949 null] >> endobj -1633 0 obj << -/D [1628 0 R /XYZ 85.0394 510.2426 null] +1661 0 obj << +/D [1658 0 R /XYZ 85.0394 573.5449 null] >> endobj -1627 0 obj << -/Font << /F21 702 0 R /F23 726 0 R >> +614 0 obj << +/D [1658 0 R /XYZ 85.0394 573.5449 null] +>> endobj +1662 0 obj << +/D [1658 0 R /XYZ 85.0394 539.0037 null] +>> endobj +618 0 obj << +/D [1658 0 R /XYZ 85.0394 539.0037 null] +>> endobj +1663 0 obj << +/D [1658 0 R /XYZ 85.0394 510.2426 null] +>> endobj +1657 0 obj << +/Font << /F21 710 0 R /F23 734 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1637 0 obj << -/Length 2893 +1666 0 obj << +/Length 2810 /Filter /FlateDecode >> stream -xÚ­ksã¸í{~…¿Õ™‰IÔ3ÛéL.›ls×Ë¥‰;íÌíÍ”–h[]Yò‰r²¹__€õ°•½›i“&Ê›¹ðïÍÂȉR?Åià„®βݙ;ÛîÓ™Ç4 K´R}·<»¼ñ,uÒÈfËõ€Wâ¸IâÍ–ùÏókÇw΃;ÿtûpûtý·ó…ºóÏ4xº½»}º}¸¹¥éýÃÝOO?^ŸÇÁ|yÿÓÃù"‰Óp~ýøxûðñþ_Ds ]×BonŸÏY~v»ì$žÊsŠûëÙÏ¿¸³÷ý™ëˆ4 g¯0q/MýÙî,…BXHyö|ö÷Žák–NjÉs_Dþ„š|1¥¦0u"(TÓw÷át~2Q.ê -'é<%Ø«Ô4hνd®J%µÊ‰¢¨ó¬ö­Ú­TCSßu]"UN ‚yH‚ïäêfÈõµ)ZE¸zMˆJɦ|ãeeÉ õ^e-3³”í–—ª\~ 4 -hfáyN†¾9fùVT²"ŸFÒÐg[Ø>k$ŒÓ­%ya4P’~¯$œø#Ìùp -"‡Ï®ëgýFÐ\í‰s&[ÔÂŒjp`‹1ãÄ.}Qe½ß©ª%€Ý)«+]ðq‰§µU«*YejRueêd9ø]ËcmzÂê ½7À$Ç÷ÓdþPÓ\æyÑV–4 j¶ÐŒ¨+Eœ-«wvXŽæ=ª‰%dÅ\ ¡a»•Ö5ƒ´Êà_o ö`2bö²Í¶JÃà>¨u|4Ì_ëæ ¡Ì!æsE¸}­u±*ÁÛ:—o4\½y+ôLX7z[ì c,€د1z…IV7ûº‘¨j} ˜oÕË‘r(üµ…½²ZÓyYp)㨠¢–Qfsø­;rªúÀ˜¢Ê‹—"?È’!Å›y#ˆ7S`× t’Tؘ{¾ð Ì?©Š1йj­Ê1·væx=ok`Ã[Ç DÚtÙß?¾D|‡ó¼#*–÷³º×ð¿ó†@`éÇNà‰Ð°d6IlØ}1«$áè ïùÉbU´„«WµÅ¹gî:ø'AÉå€ïa³–YÇȘ Z…ÃÈ(9Hãùë¶È¶o~]½½'¤º` ¤ˆ„w ‰ã:¸¹•Í€TßH(ýæÀù„x^:bÞ÷ÇCÙ¾«ÆÔ bOü?$$õ®Æ^<öÁ^nð¢ -æíœH¸>ø8þzduÖ+ž™ ‰èMY¯0† Ð:„™ ¼‰(5Dòâ=@¶«‡›}´ÁãBnÑŠw|º»!&ñÅÔeúìûÁ'ãL'Ž© ‡â àÎläࢩìÒG¯ÃÍq Iôo£´œ²<Ô‰PÓlÏÍ@ÔÁUæÄG» y¿Nxø¸ë=ãÝ=}ÊSK¨+Š˜5†þsºC:¡'¼£ªÜ¦ÂCìDPÚó’έþÐv±püPص”ï8AâÇcË,)?§½Er¤@@Žh T -$Œ©!cš JÓ©ÍüÉü°×Ê•Ü Ù™E AL&ÚûçÇsjÛ sîOM–c©6ÛòÍ$;³ -v!¨/rÍ[×½® ÞLh܇l›„´¦5õÃD œ$ŒlH„r«å&Âçݳ5º?¾·hdµÁk+ §/-UçI0> -è¾ÏÝG$”uf,Õ­DC¡Æüx¾;˜t -(–"—ÜYi4¹B™º¦qfèY'ÉíŽÑ–\z ¬nÌ\³&ÊKŸ ‰•v(Äð1“‘㣓Æ|ÒØŠž«Ëˆp}µ6eè£[SWöj›ŸMñ¢Âú`K@®Ö j]¼©VP%Ûc4ºãê#‘œ*Õ-õNB'V½S“ÖÂxl˜gr/WXÖà= #’qcYaç 8êò®• õ•Ëö0î$3£–F®ÁØÑ‚𪕲€¦)¨Ùˆ1|L7eX¥s*-qPC+a©÷Ö> XúØö±°ž  WÓgÀÀ´ëð{SJ­¹ô‡©©í>ÖØ"à© g0Áhrsÿñ ÃÈó1‘¦ß,°Õd0\>M„4Ê‘Qƒ+KŽ\”c.¬ŠhÙdEÛ¤Ašäèe<à‹uÝ«²ä~ɰ?Òì¿A{É ”Ôøø¾ÿˆ8"UÐ%1t\éÁî`ªŒ˜ ‰HÒ¿˜Þtè£}VÕÐ_àrÉhÓ±#}à'nLsD¯€“‡¶Æº$ë) kL蘌‘¦Ö¹aTìö¥ÚYu›ºÊ£²Ýbf`’–5ýv¢àdб¦œ)à·7En¡vÛ\­%””4é-„¼×ô[)¸ìZ6oçÈõX˜Ì¯'ûÓ·}‘ÙeÜÎJ©]±ÙrUQÖ57°eñE]u-ã "‰„“aë_ßu½«|•\ùð›^I×…õ¾Wk•xWþJø)mÑñ™*ÛÒã@ ;L/ʨY'²zÝššbb™Û—¢ÏÞ’9” Cfb‚ ã\sÂ]¨ ÏvHÆïV¼×V¾("+ª¬ÛÀ8«KsÕaˆWýßWW¢K =ÉIøô¥;^4@%(SÚÂdà†¸¿ÑʸSî”bÙH^šÉÉÇ!4F{\Zf6ç¬8€´} âç13êêʪ«Hó›!¾}°ü\ñœ­¨7Üoßú؉õ|Ø *¬(OJæpþÁÆä³H`7é^EžÄ)Û-t/`7õÄàÚýÇHžÇ~ , KÌëì`9B»EœLçsyÛÖà&Ñð\´Md½•ÌÙ|4o.hÔ¿4~^Wè­QâX†½lx7ã/Ñ»ÏbŠ„rS ƒ^E8©È@´ÂŒLcÓ’Ã/ܽmE! §UÝš&7!'\×JÌæ(ÎËñ.iU¾XvÝép’›ž¢2‰¦Ø;ðšÉ½W3ÜðÛjÕ“jº˜¼ý¿ÉY2„endstream +xÚ­koã¸ñ{~…¿ÕbEõ̲»É6w½\š¸hÛ*K´­®,ùD9Ùܯï g¨‡­ì-Ð&L‡Ãyq”˜¹ð/fA脉—Ì¢ÄwW³lwæÎ6°öéL0ÎÂ"-†Xï—g—·2š%Nzál¹Њ7ŽÅl™ÿ2¿v<ç(¸óO7÷7×;_x;ÿxÿDƒÇ›Û›Ç›û74½»¿ýùñ§ëóÈŸ/ï~¾?_ÄQ̯nî?Þý‹p®‘ ëZ臛§ó_—?œÝ,;އR W"»¿ýò«;ËA¸Î\G&q0{‰ëˆ$ñf»3?NàKi!åÙÓÙß;‚ƒU³uRKÂu<zjò䔚‚Ä %,¡šÞßÝé¼xþ¬]ÔN’yB°—TÓ 9ñ\•*Õ*'Œ¢¢•'µoÕn¥šz®ëBZå*˜FJð]úŸºR}iŠVÑZ½¦…J¥MùÊÛÊ’ ê½ÊZ&f1Û-o=T¹2ôhÐÌB' ψY¾Õ†¬ÈÃ(5øÙŽÏÚ1ãØÝžë¸Q4Ôì`išùðã[AaÉ*šŸ0ùìº^V€$¯´%W{BÊÒVåàVR¸óûš÷çyÑÂ)iIó\=«²ÞïTÕÀ(©Ô•=¥:–­·¦atB%Æo¡ )˜’þü¥n¾Ð’a~wi®hm_k]¬JEð¶ÎÓW®^ ¬½íÖÞ{Z1vÆ8¯1IV7ûºIQIúAáˆä„Ôma]Y³™q)c«uÝ´º3žù­;ò­úÀ+E•ÏE~HKmôWMÌ„ïHî!Ü58Õo%£ó…€«1ÿ¤*–cŒÔZ5ªÊØœw0±3òõÄ­†¸”N쉸‹t‚Éß=<‡5 £b†?»{ ð+˜æ06 ™!x&‚¢“‰#CÆ(ŒIÅñÀ¿a]xñbU´´RäàŹ0þÎDеñ4À-ªV5ë4ë›Á‚VFã02GJ#Ôhþ²-²-U¾A$Ëä‡LåöZ;qÊ ¤õ(G¤_8§(‹65Qæ:KË”ÜfwÈJ¥Zš±´NðÚ&Ñ|¹í„t8i·4³Ó×½(âH‡èCý^‘ed2°Œ?Ë 2ÿªÈRÝN˜P +'’^‹8Ó1d2 VAå,dÃF1¾&«¥/æÄD=HßíMòn‚ËØsd,=>üºz}‹I xþ€IJÃ$ž6f!ÆuðpËš¨¾SúŒÀù{")½ˆÏýéP¶oª1qü®ÁÿCR¯ï:A$¢±~{¾Á‹üПÿµs"ézàãø+ Êê¬)V<3Q—7e½Â‚@ëf2ð&ÂÔÙVíŸqkx´]=<¬è£ Š+|‚O|¼ý@82ˆ£‹©ËôÙóüOÌÆ™ŽS0 ÙAÀ­9ÈÁMÙ¥^‡!•ã  a×m”N§ õÔ:>›s3àtp“ À)­ûuÂ1ÀÅ]oèožé9P¶YD}XQðÀ¬1tŸÓÂÀ „G'Øê"­¦¢Cä„Pòò–Ϋ¾ë¸H:^ í^J÷ ßó?†›24Ì’ÒsÒëOÆGúƒÅ‘þ „*˜WjH˜&Dà +eéÄ&þx~Øk +ä*Ý É™M ALÜ»§‡s%ß9õ'&Ç1W›mùjRÙõ{”¹æ£ëž…‰BœÑŸP¸¹6) ,kʇ‰0â;qÚ€¨¡ÀäÚÚãÒUØÒÕßZ4iµÁK+!£/-VçH0> +çÑD”’-Ê:3–êv¢¡Pc^4ßL2…%æâVº³Ühò„ò4c­ô¤ˆRÊ]€Ñ–\ŠV7fžYæ¥ÇˆDJ;`XÌxäøñHÒˆ%,ëñ±ú¸ˆ0×kSìèÒØú7¥ŸMñ¬Â½³ ×j´.Þ T+(’m|ik»sPÛ` JÛ­âb¼Ý¦Õ{—BƒR)=UŽ“Ò‚hl˜gé>]aMƒ×,9DF]„e-+à¨îû–+8©¾rÑDcfÔÒh@Õ¿3zr‚ÞµRÐ4…‰HàÐNv&¦hñçTWâ †î.…}¦ÚYù°ÀÜG¶ƒˆ¤ud½˜.¦‰…ßeª5þ05…ÝÇz—Zj]4ƒ “w1Š\0húÃ|[Júó‡åã”$¤QŒ<9m» ÀDX+вI‰Nɘƒ—q€/ÖSt¯ZÈ‘ûAÃîH³ÿm!o€~½×ßt…¤ º2{Ž«@ØL…‘ú·ã£D£ú{VÕPŸïr¹Ëè{††>PKŒÀiŒZ•ÓZzhk¬I²rÆTCgl‘$Ö·aTìö¥ÚYm›šJ£²Ýb^`”–5ýv¬àdЮ&œ'à·7En¡öØ\­S('iÒi¯é·RpÕuÚ¼ž àk± ž_O…"èŠÌÖ'ãVnTFíŠÍ–Kв®¹{-‹/êªkåH½¢”¶öõ\W\å«øÊƒßä*u]Qã{µV±¸òVÒ›Hh‹ŽÎDÉ–Gaè‹ðµÆ8QF:¡ÕëÖÄÓ³2XÈܽ]†ÔÏ¡2bø;÷ßú‚ÞJtMël†xü–ÃgmÓgEhE••*>zˆÂƒ¶ÐéO¾m»Î´ë]4k~EŠÍÁ;4%¤NŠÂËëy Œ³º4†xÑÿ}uõ'ºÒÐþ˜„„/?º£ET‚2e-L^ˆç­Œ›äN)–LÊ[3ªÅBc´ÇeefΊÃÇžøL*47ÂŒºš²êªÑcßü¾‡É/ïA¶¢Þ4é~ûÚÄŽ­§ÃUaYyTiò^/¾ý""»‘Gqʶ +kûèõ¡Þa€<Ž@«£¿ïqäiìØ@:ļΖ"´ZtÀɶ¡?|F0·m ~B}×Eã„Ö]ÉÞ¡M7€éæ‚Fý+¬ïÁí +½5ºÂ5æaŸ6|šq˜ÐëA¤S‘ônhaЫg#ˆV˜ilÚqø…Ë·­(„á´ª[Óà2àdƒûÚ“9òŸóv¼LZ•Ï–\'NrÓQT&1À;Þ3Y¶÷j†+~Sm vRM“—ç V¸_hvK%OÆ1e¼»YÞrîMlk‘ă,ómúOm?‹çŸ¸ÙÓ"Ñú„ôÂ@•ÒâwÖÞÊz…±rp3 ûöû\p©z»|à;Ù^Mdûu»¿º¼|yyA8….•.‹ja¬t‰­¾qý`èúÂOàZ…¶þ +Ä“N"\‹ä´_ùaEŒóŠÈ¶Å>þtâ¾%AlZv&>}ë å/3;ú±ÿîÑíX ·˜ïþðàSÊ#u UßwÈk/ùó‘ÿ8ŽŽø;úÓaò4RÆ)5äé/SyW01bŒ‰®ôÒ=<žÚ ¢¡'ñf ßµ8…¶ˆê½W¶-±O,Ý"x‹õbšé‰oi©í'ç´°OªC—íèýR­Fþ{¤²~¶¡éáÄBßñ}zÒqEðÇ^d7,†;Nè„®©ÚÞ‰T»vêfsÙ¬³ßñÜÈI\yÌÕ‘ïtX§¬ŒqJí-߉œÈ£áÏqz7!Ø$MÓ’3Ðo}ᔃŸ%'äp»Äü?ýì?s2޽é›^À 13…@î?aÝ~'=åý¿xÇðBendstream endobj -1636 0 obj << +1665 0 obj << /Type /Page -/Contents 1637 0 R -/Resources 1635 0 R +/Contents 1666 0 R +/Resources 1664 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1634 0 R -/Annots [ 1641 0 R 1642 0 R ] +/Parent 1652 0 R +/Annots [ 1670 0 R 1671 0 R ] >> endobj -1641 0 obj << +1670 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] -/Rect [253.7995 146.8976 417.685 158.9572] +/Rect [253.7995 149.3637 417.685 161.4234] /Subtype/Link/A<> >> endobj -1642 0 obj << +1671 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] -/Rect [63.4454 108.9117 208.8999 119.0735] +/Rect [63.4454 110.455 208.8999 120.6168] /Subtype/Link/A<> >> endobj -1638 0 obj << -/D [1636 0 R /XYZ 56.6929 794.5015 null] ->> endobj -614 0 obj << -/D [1636 0 R /XYZ 56.6929 652.1213 null] ->> endobj -1639 0 obj << -/D [1636 0 R /XYZ 56.6929 614.8935 null] ->> endobj -618 0 obj << -/D [1636 0 R /XYZ 56.6929 614.8935 null] ->> endobj -1127 0 obj << -/D [1636 0 R /XYZ 56.6929 584.5024 null] +1667 0 obj << +/D [1665 0 R /XYZ 56.6929 794.5015 null] >> endobj 622 0 obj << -/D [1636 0 R /XYZ 56.6929 289.5256 null] +/D [1665 0 R /XYZ 56.6929 662.0717 null] >> endobj -1640 0 obj << -/D [1636 0 R /XYZ 56.6929 251.3901 null] +1668 0 obj << +/D [1665 0 R /XYZ 56.6929 624.1661 null] >> endobj 626 0 obj << -/D [1636 0 R /XYZ 56.6929 251.3901 null] +/D [1665 0 R /XYZ 56.6929 624.1661 null] >> endobj -955 0 obj << -/D [1636 0 R /XYZ 56.6929 222.7156 null] +1137 0 obj << +/D [1665 0 R /XYZ 56.6929 593.0972 null] >> endobj -1643 0 obj << -/D [1636 0 R /XYZ 56.6929 53.7852 null] +630 0 obj << +/D [1665 0 R /XYZ 56.6929 294.2701 null] >> endobj -1644 0 obj << -/D [1636 0 R /XYZ 56.6929 53.7852 null] +1669 0 obj << +/D [1665 0 R /XYZ 56.6929 255.4568 null] >> endobj -1635 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F39 885 0 R /F53 1017 0 R /F11 1367 0 R /F41 925 0 R >> +634 0 obj << +/D [1665 0 R /XYZ 56.6929 255.4568 null] +>> endobj +965 0 obj << +/D [1665 0 R /XYZ 56.6929 226.1045 null] +>> endobj +1672 0 obj << +/D [1665 0 R /XYZ 56.6929 53.5688 null] +>> endobj +1673 0 obj << +/D [1665 0 R /XYZ 56.6929 53.5688 null] +>> endobj +1664 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R /F53 1027 0 R /F11 1384 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1647 0 obj << -/Length 2824 +1676 0 obj << +/Length 2825 /Filter /FlateDecode >> stream @@ -7350,374 +7465,381 @@ xÚµZ]{ ´ ¸ ¤ƒùÈ ’Tï*ÓªA<—Ǻ·ÃÐû"Âa‡˜%(ŒÏ´’–Û µ9Te>#ôá¶6Ø6Ay2¾b$´ÌHÜ)³|Þ‰zA 4lY3ª#Óò`ï§6c¿ŒI0‚¶Æ¾[g;µú,{Ù•oúùFÿÍ+”Ÿë¯’ù Ø.…‚1¦‘•ß‹WñÈÌvìï&}•/\ u˜sê 8˜$Ðk“3©-å¡ZKY\{h½ÐÙ}lÛ6ø´Üïå®+Ö›­ßÁä\²Z*)#ý&ÇÍ:±¦‚ñwù·á£s£˜cû‰†Íçƒb‘÷Ç}ªO]žkÓçÁj%¬¼SƒS5ø´‰3zÝÏÞs–äWœ¹Ïw;sâû}&ÁDÂ(ò[„%ä6-Ô~P‘xN|¸­9ô‡­ÁF^d‡\•<ÛkÒlIdu¾ª2!³ðôtÖÅ:Úsq\û½I$Ø‚?Sÿ[Bn…k¡6ãû>ûòá¶ -ï+ÜF6Þuþ}^=gÛô5Õ Œ@õµ®­Ñ LKç„ }RÛˆÈBFo_#y5Y«YȰƒŽAóañEXûDó*å!¯¶yJIŒ/…—(™»¼Øg¹vB½fgÉ>ÜprªÅ'¸ª LnÿË_úZ;‡1¢Iâ8L£A„ÂcýRâWpÞsóIðé«ÿ+Ab«endstream +ï+ÜF6Þuþ}^=gÛô5Õ Œ@õµ®­Ñ LKç„ }RÛˆÈBFo_#y5Y«YȰƒŽAóañEXûDó*å!¯¶yJIŒ/…—(™»¼Øg¹vB½fgÉ>ÜprªÅ'¸ª LnÿË_úZ;‡1¢Iâ8L£Ð|Rʱ~)ñ+ppò!²ù&øôÝÿ ‡ÿb¿endstream endobj -1646 0 obj << -/Type /Page -/Contents 1647 0 R -/Resources 1645 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1634 0 R ->> endobj -1648 0 obj << -/D [1646 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1649 0 obj << -/D [1646 0 R /XYZ 85.0394 752.3015 null] ->> endobj -1650 0 obj << -/D [1646 0 R /XYZ 85.0394 752.3015 null] ->> endobj -1651 0 obj << -/D [1646 0 R /XYZ 85.0394 752.3015 null] ->> endobj -1652 0 obj << -/D [1646 0 R /XYZ 85.0394 746.3107 null] ->> endobj -1653 0 obj << -/D [1646 0 R /XYZ 85.0394 731.5461 null] ->> endobj -1654 0 obj << -/D [1646 0 R /XYZ 85.0394 728.1497 null] ->> endobj -1655 0 obj << -/D [1646 0 R /XYZ 85.0394 713.3851 null] ->> endobj -1656 0 obj << -/D [1646 0 R /XYZ 85.0394 709.9887 null] ->> endobj -1657 0 obj << -/D [1646 0 R /XYZ 85.0394 651.9592 null] ->> endobj -1071 0 obj << -/D [1646 0 R /XYZ 85.0394 651.9592 null] ->> endobj -1658 0 obj << -/D [1646 0 R /XYZ 85.0394 651.9592 null] ->> endobj -1659 0 obj << -/D [1646 0 R /XYZ 85.0394 648.8377 null] ->> endobj -1660 0 obj << -/D [1646 0 R /XYZ 85.0394 634.0731 null] ->> endobj -1661 0 obj << -/D [1646 0 R /XYZ 85.0394 630.6767 null] ->> endobj -1662 0 obj << -/D [1646 0 R /XYZ 85.0394 615.9121 null] ->> endobj -1663 0 obj << -/D [1646 0 R /XYZ 85.0394 612.5156 null] ->> endobj -1664 0 obj << -/D [1646 0 R /XYZ 85.0394 585.7959 null] ->> endobj -1665 0 obj << -/D [1646 0 R /XYZ 85.0394 582.3994 null] ->> endobj -1666 0 obj << -/D [1646 0 R /XYZ 85.0394 567.6349 null] ->> endobj -1667 0 obj << -/D [1646 0 R /XYZ 85.0394 564.2384 null] ->> endobj -1668 0 obj << -/D [1646 0 R /XYZ 85.0394 549.5337 null] ->> endobj -1669 0 obj << -/D [1646 0 R /XYZ 85.0394 546.0774 null] ->> endobj -1670 0 obj << -/D [1646 0 R /XYZ 85.0394 531.3128 null] ->> endobj -1671 0 obj << -/D [1646 0 R /XYZ 85.0394 527.9163 null] ->> endobj -1672 0 obj << -/D [1646 0 R /XYZ 85.0394 513.1518 null] ->> endobj -1673 0 obj << -/D [1646 0 R /XYZ 85.0394 509.7553 null] ->> endobj -1674 0 obj << -/D [1646 0 R /XYZ 85.0394 483.0356 null] ->> endobj 1675 0 obj << -/D [1646 0 R /XYZ 85.0394 479.6391 null] ->> endobj -1676 0 obj << -/D [1646 0 R /XYZ 85.0394 464.8745 null] +/Type /Page +/Contents 1676 0 R +/Resources 1674 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1652 0 R >> endobj 1677 0 obj << -/D [1646 0 R /XYZ 85.0394 461.4781 null] +/D [1675 0 R /XYZ 85.0394 794.5015 null] >> endobj 1678 0 obj << -/D [1646 0 R /XYZ 85.0394 446.7135 null] +/D [1675 0 R /XYZ 85.0394 752.3015 null] >> endobj 1679 0 obj << -/D [1646 0 R /XYZ 85.0394 443.3171 null] +/D [1675 0 R /XYZ 85.0394 752.3015 null] >> endobj 1680 0 obj << -/D [1646 0 R /XYZ 85.0394 428.5525 null] +/D [1675 0 R /XYZ 85.0394 752.3015 null] >> endobj 1681 0 obj << -/D [1646 0 R /XYZ 85.0394 425.156 null] +/D [1675 0 R /XYZ 85.0394 746.3107 null] >> endobj 1682 0 obj << -/D [1646 0 R /XYZ 85.0394 355.0758 null] +/D [1675 0 R /XYZ 85.0394 731.5461 null] >> endobj 1683 0 obj << -/D [1646 0 R /XYZ 85.0394 355.0758 null] +/D [1675 0 R /XYZ 85.0394 728.1497 null] >> endobj 1684 0 obj << -/D [1646 0 R /XYZ 85.0394 355.0758 null] +/D [1675 0 R /XYZ 85.0394 713.3851 null] >> endobj 1685 0 obj << -/D [1646 0 R /XYZ 85.0394 352.0499 null] +/D [1675 0 R /XYZ 85.0394 709.9887 null] >> endobj 1686 0 obj << -/D [1646 0 R /XYZ 85.0394 337.3452 null] +/D [1675 0 R /XYZ 85.0394 651.9592 null] +>> endobj +1081 0 obj << +/D [1675 0 R /XYZ 85.0394 651.9592 null] >> endobj 1687 0 obj << -/D [1646 0 R /XYZ 85.0394 333.8889 null] +/D [1675 0 R /XYZ 85.0394 651.9592 null] >> endobj 1688 0 obj << -/D [1646 0 R /XYZ 85.0394 309.8192 null] +/D [1675 0 R /XYZ 85.0394 648.8377 null] >> endobj 1689 0 obj << -/D [1646 0 R /XYZ 85.0394 303.7727 null] +/D [1675 0 R /XYZ 85.0394 634.0731 null] >> endobj 1690 0 obj << -/D [1646 0 R /XYZ 85.0394 278.3282 null] +/D [1675 0 R /XYZ 85.0394 630.6767 null] >> endobj 1691 0 obj << -/D [1646 0 R /XYZ 85.0394 273.6565 null] +/D [1675 0 R /XYZ 85.0394 615.9121 null] >> endobj 1692 0 obj << -/D [1646 0 R /XYZ 85.0394 246.9367 null] +/D [1675 0 R /XYZ 85.0394 612.5156 null] >> endobj 1693 0 obj << -/D [1646 0 R /XYZ 85.0394 243.5403 null] +/D [1675 0 R /XYZ 85.0394 585.7959 null] >> endobj 1694 0 obj << -/D [1646 0 R /XYZ 85.0394 173.5556 null] +/D [1675 0 R /XYZ 85.0394 582.3994 null] >> endobj 1695 0 obj << -/D [1646 0 R /XYZ 85.0394 173.5556 null] +/D [1675 0 R /XYZ 85.0394 567.6349 null] >> endobj 1696 0 obj << -/D [1646 0 R /XYZ 85.0394 173.5556 null] +/D [1675 0 R /XYZ 85.0394 564.2384 null] >> endobj 1697 0 obj << -/D [1646 0 R /XYZ 85.0394 170.4341 null] +/D [1675 0 R /XYZ 85.0394 549.5337 null] >> endobj 1698 0 obj << -/D [1646 0 R /XYZ 85.0394 144.9896 null] +/D [1675 0 R /XYZ 85.0394 546.0774 null] >> endobj 1699 0 obj << -/D [1646 0 R /XYZ 85.0394 140.3179 null] +/D [1675 0 R /XYZ 85.0394 531.3128 null] >> endobj 1700 0 obj << -/D [1646 0 R /XYZ 85.0394 113.5982 null] +/D [1675 0 R /XYZ 85.0394 527.9163 null] >> endobj 1701 0 obj << -/D [1646 0 R /XYZ 85.0394 110.2017 null] +/D [1675 0 R /XYZ 85.0394 513.1518 null] >> endobj 1702 0 obj << -/D [1646 0 R /XYZ 85.0394 95.4372 null] +/D [1675 0 R /XYZ 85.0394 509.7553 null] >> endobj 1703 0 obj << -/D [1646 0 R /XYZ 85.0394 92.0407 null] +/D [1675 0 R /XYZ 85.0394 483.0356 null] >> endobj -1645 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F39 885 0 R >> -/ProcSet [ /PDF /Text ] +1704 0 obj << +/D [1675 0 R /XYZ 85.0394 479.6391 null] +>> endobj +1705 0 obj << +/D [1675 0 R /XYZ 85.0394 464.8745 null] >> endobj 1706 0 obj << +/D [1675 0 R /XYZ 85.0394 461.4781 null] +>> endobj +1707 0 obj << +/D [1675 0 R /XYZ 85.0394 446.7135 null] +>> endobj +1708 0 obj << +/D [1675 0 R /XYZ 85.0394 443.3171 null] +>> endobj +1709 0 obj << +/D [1675 0 R /XYZ 85.0394 428.5525 null] +>> endobj +1710 0 obj << +/D [1675 0 R /XYZ 85.0394 425.156 null] +>> endobj +1711 0 obj << +/D [1675 0 R /XYZ 85.0394 355.0758 null] +>> endobj +1712 0 obj << +/D [1675 0 R /XYZ 85.0394 355.0758 null] +>> endobj +1713 0 obj << +/D [1675 0 R /XYZ 85.0394 355.0758 null] +>> endobj +1714 0 obj << +/D [1675 0 R /XYZ 85.0394 352.0499 null] +>> endobj +1715 0 obj << +/D [1675 0 R /XYZ 85.0394 337.3452 null] +>> endobj +1716 0 obj << +/D [1675 0 R /XYZ 85.0394 333.8889 null] +>> endobj +1717 0 obj << +/D [1675 0 R /XYZ 85.0394 309.8192 null] +>> endobj +1718 0 obj << +/D [1675 0 R /XYZ 85.0394 303.7727 null] +>> endobj +1719 0 obj << +/D [1675 0 R /XYZ 85.0394 278.3282 null] +>> endobj +1720 0 obj << +/D [1675 0 R /XYZ 85.0394 273.6565 null] +>> endobj +1721 0 obj << +/D [1675 0 R /XYZ 85.0394 246.9367 null] +>> endobj +1722 0 obj << +/D [1675 0 R /XYZ 85.0394 243.5403 null] +>> endobj +1723 0 obj << +/D [1675 0 R /XYZ 85.0394 173.5556 null] +>> endobj +1724 0 obj << +/D [1675 0 R /XYZ 85.0394 173.5556 null] +>> endobj +1725 0 obj << +/D [1675 0 R /XYZ 85.0394 173.5556 null] +>> endobj +1726 0 obj << +/D [1675 0 R /XYZ 85.0394 170.4341 null] +>> endobj +1727 0 obj << +/D [1675 0 R /XYZ 85.0394 144.9896 null] +>> endobj +1728 0 obj << +/D [1675 0 R /XYZ 85.0394 140.3179 null] +>> endobj +1729 0 obj << +/D [1675 0 R /XYZ 85.0394 113.5982 null] +>> endobj +1730 0 obj << +/D [1675 0 R /XYZ 85.0394 110.2017 null] +>> endobj +1731 0 obj << +/D [1675 0 R /XYZ 85.0394 95.4372 null] +>> endobj +1732 0 obj << +/D [1675 0 R /XYZ 85.0394 92.0407 null] +>> endobj +1674 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1735 0 obj << /Length 2889 /Filter /FlateDecode >> stream -xÚµšKsÛ8Çïþ:JU1>´¥ØJlÅ+ÙÙ™Êä@KtÌ2E:"•Äß~ă E‚™ÝÚòÁÐÄ_ÂÝ@7I&þÈÄõÒpâ‡r1q'Ûýž|ƒ¾«3"mΕѹiuqöÇ{æOBzÔ›Ü?c™Üï¾L#ÄÐ FÀÓ‹åÅÍòÓÕ:º»þkvN]<ý»8ZÍŇÍÃÕÕbs¿׋h¾\] ™û^ˆ§ÑÝÝb5_þ)ú#>*Ö­—‹Íìëý‡³Å½þÚæO#˜ñïüýìËW<ÙÁ/üp† wò>`DÂNögŽËë0¦Z²³ÍÙ¿ô€Fo}kïTŒ(óhÏ\Q2!…®K[“å†Èc”Õ“µNÊâxØ&r -’mq؉ëûÌÀÛkRþJFï;@ÃJ|)ÖPYñïôeýþ’€}í*Ja:\ß.­­NµYhhê#—úmíUò~>aÓùj#.ÖkÙü1ÍÓ*-òzN:?…`¦•yð%ø@ïà.Ч—èý,¤S$ÆXüH3LŸãCUéìŠêÿtzïã—¢”½kÙûeû8Ïå q¾Íw3BC5øm±}‰_“êÂÝðý`&ÔW:Ë@øÇ§mU<Â÷¨)âÃhˆ°†(ðœ¦Õ0am¥ ûØ&l•nŸh÷ni °ðÓW›èN-{îLÛz1ƒ¶ú¡ì/ø Òü›ø 0ñÑdïe‘%YË{ºœa>è3âp0¬,”•æø66iƒCW»Ÿƒ©ñµìOo“Ü .½éSqm‹_¯5¤,ÅdBçM±¹ë ‹eÆ{ÝàMSÙQ='âb^ìãTv®â½lݼ•U²ïÁÊ0A.¢ VFÀ{å`ñ´”mÏAÇç™ëNÓ_i"=Ns®/Œv?ó)z×YK¹*æéö%ÍË"—âüÞôºð†×…ÛžÃÆüÓ°²¬ e¥ÖÅ.µ¬ ›´±.ºÚýëÂÔ†uÁˆ+Ü”§Ž¿¼¡^übóšlÓ§·zeðÏ5rnÙ,Þ\ÊüéCžrP¢±³ÍBËr—äUÊÏUÉ¡MGò™ŠåЦc9Ó±œYc9C~à23–‡bæƒÅyšdb‹¡ñ©ø-om¡†=*Ëàk)ÖÇ<Ñ ýaÐ.EÌÙhÃÊZYiДa h›´º«ÝÚÔþ˜È5¾øµ}Žóor"æI–|SÛq'‘Û:\žÜzµé;Y.$2¬}°RG§¨jí‘ݳ“…£Èq¼1 -†•…‚²Ò`¯·P°IºÚýLíù&?ýã⯲s¬Ø,¯dSšwç]ù?ý -?â7?Òù1Щsàží’9(ô½6¡¹$´ˆË*‹_ÙÌjGß½Sçbá÷ÏšX8LŒÀÌ6 + 1eeó-ÄlÒ±®v?1S{½‰þ¸»°³øŠó‰,ú. çøÀ ǨVªÊª¡êXÎ1ViƒjW»Ÿª©=Oªxûœìþ›QdïF¢Ì.cŽûÞ*¤‘!ñFИVÃh´•Fã–€UºAs¢Ý‹¦¥]m|U§ Dä92˜–F€wH'óyJ¦Ï ÊWýi) ¢U‚]›5¯Ì|ò9ÇG$ð&D_ja £:Д„\£$t# eªb­°•]<?f„µHÞ'‡Y0m²IŠñp‰–y.Â4 #+À°²¬e¥W@H\Ë -°I+ «Ý¿Lí{Ôqî‹5eÇaÓèX=ö[½‰®»"ååÑÇ¡®¢»ûµðOÞ_3æ}í¬“wÉä¤?Èz®Óð†hÁSÃú.•®‘Wä‘ÊïlEÕMò -ñC§)vŽ ¶á‘#occa(lAFˆ%¼ZD ~mÕ~z*?èn®£s"`Èl„Ê£.¥”[ˆ™¼À•(ÔU½¥Fõ–èê-i2\l—ðÀŒ˜cˆˆ¿´uæåE\#þò‚tü&™ª1ZP"¦}Ô Ç‘…£4j@RKÝΦkì÷£4„£&]ÉøZ?¤üÑ`'¿¿IËJ¦ž"öâv1Ž7܉üðô+)‡²w7JcðìLÚ[ªz!¯*¶Ï'5+0ˆ8ˆ‘ÐÌ0¦Œ407´”lº °®p/0SXÔP8þª’¼¬ŸTÂŒEMþ—Ç××âP £åhü‘JQ6‡F¯¯2ã„½ÐØêN7HÜqÿ\ìE¾À[/eëõ1_eëg]0‡®ešÇy%»D - ͪ§ÕÚÁ´8¦e™öÕ€0&Ì‹· !6¬,Œ••ÙRM°J”»Úý˜Mík˜´L?gTÎö¿äÅϼë´7ß“.×rí²·üC㇌¤ó]Ë*~*›ÌñtûcêL뽈KV0£ü LHû9­®lé:–~p0ÀòYÈqðH6­†™k«æÍL†™[¥æ'Ú½Ì[Úz>ù¶ØÀ_%ÕÏâðÒä0ݺà'˜¾Ão@Æ¢Ø ,aö³ù¡õÖX¯‡4SÉK0œ¼7D«˜VJʪ¡dÛ/­Ò¥®v?%S{|?¦bÛ'¹ÚõÙ<ò⟮ ½až«¹{ÍÒ­QHoʺ2r÷¹¥É“Ó)œ_â]2P.·Aaðcg¤^gZY (+ Å m®c“6 tµû¡˜Úãéý¦:·•“Igæg=[cè"ÏgN{ò?Hç¸À“þϯíUq± 8¼P2ڮ嗪+ñŸ|uõ‚ïéwÿ–¡OYendstream +xÚµšMsÛ8†ïþ:JU1†øy¤-ÅVb+^ÉÎÎT&Z‚c–)Ò©$þ÷Û >R$˜Ù­-LM¼tÝ$ž8ð‡'žüˆD“ r‘ç`o²ÝŸ9“oÐwu†¥Í¹2:7­.îÏþxOƒI„"Ÿø“û'c¬9aˆ'÷»/ÓQ4ƒœéÅòâfùéjß]ÿ5;'ž3ýÛñœx56WW‹ÍýB~\/âùru&xvø‘3ïî«ùòOÑóQÝz¹ØÌ¾Þ8[Üë¯mþ4ìPþ¿Ÿ}ùêLvð ?œ9ˆF¡7ù „£ˆLög®G‘çRªZ²³ÍÙ¿ô€Fo}kïTaꓞ¹"x‚1Š<´&Ë‹O ­'kÍÊâxØ29l[vâú~3ðöÊÊÁ_I1 +<ahX‰/Eû*+þ¾¬ß_bÒ¯]eLL‡Ø¥µÕ©6 mLä‘ ­½b?áçc:¯6âb½– ìoÇ!yZ¥E^ÏIç§`Ç…i¥>| >Ð;¸‹8ÓKô~‘)c,~°Ã ‡ÓçäPÕxz#»âú?™Þ&ûä¥(eïZö>dÙ>És9h’ïDóÝ “H ~[l_’WVR¸¾Ì„úJçbÿø´­ŠGø5eXt"ìG +}w„°i5LX[iÂã¶J7„O´{ ·´Xøé«M|§–=w¦í½˜A;ˆ‚ÈÀ öHü¿HiþM|˜øh²÷²ÈX–%òž.w˜Cú# + e¥9„ƒMÚàÐÕîç`jÇ|-Ó[–€;Á¥?}*¢mñ뵦ÁÊRL&tÞÛ„»ž°Xæ`¼× þ4•Õ3óbŸ¤²s•ìeëæ­¬Ø¾+u0òxm°R Þ+K~¤¥lk|:>ÏX’§,CˆX ·HÅoyk 5ìQY_K±>æLƒ†A{Ñ ¢#  + he¥AêX@Û¤ Ð]í~ЦöG&×øâ×ö9ɿɉ˜³Œ}SÛq'‘Û:\žÜzµé;Y…$2´}°RG§¸jí‘ݳ“…%Èuý1 +†•…‚²Ò`¯·P°IºÚýLíù&?ýã⯲s¬Ø,¯dSšwç]ù?ý +?â7?Òù1Щsàží’º( +ü6¡¹$´HÊ*K^˜l¦µ£ïÞ©s±ðûgM,&†af0 †•…˜²2ˆb6iƒXW»Ÿ˜©½ÞÄÜÎ=ØYEXž(E_q@ü¿Ø&ÁFQã‚Z}ƒ¤Æ¯G¨ù +\'4v¹@`ã£Ø\ÇÄÆ?5ØÄaFÔÊ'­0ÝÐA>Lº¦i5 S[0-»Uºy¢Ý ³¥½©ŠC½KáˆN/ÙAlapød%osk†¼¯fÈCÞ(ò+Å[Œ0$aH;†ü~Îßkºžã)†Â¦^aüâ“4¾:îöG8ÔÊùŴ‰´ÿÄs]8Ç4 #° + leeÀŽ,°mÒì®v?lS›ÃNÄ>ŠsÁÙô©>µœ_³º2#zas,E*[dè ÐéС7[‹8K¡7”¡7jñ÷[¡×Ç'>,ú. çøÐƨVªÊª¡êZÎ1ViƒjW»Ÿª©=gU²}f»ÿfcÙ»QèÁ³K©ëýŸ·J +id„ý4¦Õ0m¥Ñ¡¥`•nМh÷¢ii×G›@ÕéBQ€…yŽ §¥QàÒÉž’é3¨òÕ`ZÊ€h• E×fÍ+3Ÿ‡|Î ¼ 1…ZȨ4%!Ï( ÝHÃE™ªX«leÅÆX-’÷ìñ0 §M6Ig¸DK}9$Ä#+À°²¬e¥W@„=Ë +°I+ «Ý¿Lí{Ôu]î‹5e×¥ÓøX=ö[½‰®»"ååÑÇ¡®â»ûµðOÞ_3æ}í¬“wÉä¤?ÈúžÛð†hÁSÃú.•®‘Wä‘ÊïlEÕ {…ø¡Ó;G +ÛðÈ‘·±±06Š ÅØ^-¢¿¶j?½F•t7×ñ90d6BäQ—Â-D‹L^àJj±ªÞ£z‹uõ7®G¶Ëx8›c°ˆ¿¤uæåE\#þò‚tò&™ª1ZP"¦}Ä Ç‘…£4j@KÝΦkì÷£4„ã&]ÉøZ?$üÑ`'¿¿IËJ¦ž"ö:íbo¸ùáé+‡²w7Jcðì··T#ôB^UlŸOj4V`qÅ‘˜a4 Li`^d) Øt`]á^`¦°¨¡†p"üU±¼¬ŸTÂ숚*ü/¯¯Å¡FË;ÑøƒJQ6‡F¿¯2`äø‘±ºÄ›n¸ãþ¹Ø‹|·^ÊÖëc +¾šÈÖϺ`]Ë4OòJv‰šU N«µƒiqLË2í«ÿa:L˜o©3†Ø°²0VVdK5Á*mPîj÷c6µ¯aÒ2ýœQ9ÛCþ’?ó®Ó<Ül|Oº\˵ËÞòFnu<0–Îwu,«ä©l2ÇÓíªg0­÷ .XÁ”ðƒ< +ŒÛÏiueK×±ôƒƒæÏBŽãŒÄaÓj˜¹¶jÞLpð0s«tÃüD»—yK[ÏÇ"ß»ø+Vý,/MÓ­ ~‚é;üd'DÄñCK˜ýl~h½u Äë!ÍTò'/Ø‹PˆÇª¦•…’²j(ÙöK«´A©«ÝOÉÔ^³ïÇTìq{–«íPo‘Í#/þéºÐ湚»×,Ý…ô¦¬+#wŸ[<¹ÂùÅ!Ù±r¹ +…º#õ:ÓÊEYi(^ds›´¥«ÝÅÔOï7ÕḭD˜d™7žmôl‘‡ü€ºíÉÿ ãóa ±~ãcðÆÓÊ‚AYé´ŽbË®e•60tµû1˜Ú—YR–™> +.Wçñ|¾FñZD—øw¦~TЙìkUUIw9SAèJ6î$Í«z꾅щlÍ£ü~dÃÏu1dwGÛ›VdÊJ# ‰å4i•6uµû‘™ÚËøBm¼DÁ¶Ï9„§L½Î´ç1NîC݇MyúýȺ‡ лéz~ÐÛ–±DÇÊŽ§^I§‚ö;•“~f8ö–…a4LK5eb©TÛtV]á^T¦°Žqn¨bœñ7ƒ´ºsnÔ©b‚å2^Åâêr…tÇÉÐû¼¤é“ÖÓ?±N©áv3¥†f#¥æÒè¢.lå¹x òüßµ·eYšìÕ‹Z¤uö×ÎÚyÍnð i©³xˆ¿OÛ3ùŽ>“þϯíUñÑ08¼2ڮ嗪+ñ9ùêêßÓïþ–ùO[endstream endobj -1705 0 obj << -/Type /Page -/Contents 1706 0 R -/Resources 1704 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1634 0 R ->> endobj -1707 0 obj << -/D [1705 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1708 0 obj << -/D [1705 0 R /XYZ 56.6929 748.5056 null] ->> endobj -1709 0 obj << -/D [1705 0 R /XYZ 56.6929 748.5056 null] ->> endobj -1710 0 obj << -/D [1705 0 R /XYZ 56.6929 748.5056 null] ->> endobj -1711 0 obj << -/D [1705 0 R /XYZ 56.6929 743.7078 null] ->> endobj -1712 0 obj << -/D [1705 0 R /XYZ 56.6929 719.6381 null] ->> endobj -1713 0 obj << -/D [1705 0 R /XYZ 56.6929 711.8197 null] ->> endobj -1714 0 obj << -/D [1705 0 R /XYZ 56.6929 697.0552 null] ->> endobj -1715 0 obj << -/D [1705 0 R /XYZ 56.6929 691.8868 null] ->> endobj -1716 0 obj << -/D [1705 0 R /XYZ 56.6929 665.1671 null] ->> endobj -1717 0 obj << -/D [1705 0 R /XYZ 56.6929 659.9987 null] ->> endobj -1718 0 obj << -/D [1705 0 R /XYZ 56.6929 635.929 null] ->> endobj -1719 0 obj << -/D [1705 0 R /XYZ 56.6929 628.1106 null] ->> endobj -1720 0 obj << -/D [1705 0 R /XYZ 56.6929 601.3909 null] ->> endobj -1721 0 obj << -/D [1705 0 R /XYZ 56.6929 596.2225 null] ->> endobj -1722 0 obj << -/D [1705 0 R /XYZ 56.6929 569.5028 null] ->> endobj -1723 0 obj << -/D [1705 0 R /XYZ 56.6929 564.3344 null] ->> endobj -1724 0 obj << -/D [1705 0 R /XYZ 56.6929 549.6297 null] ->> endobj -1725 0 obj << -/D [1705 0 R /XYZ 56.6929 544.4015 null] ->> endobj -1726 0 obj << -/D [1705 0 R /XYZ 56.6929 529.6968 null] ->> endobj -1727 0 obj << -/D [1705 0 R /XYZ 56.6929 524.4686 null] ->> endobj -1728 0 obj << -/D [1705 0 R /XYZ 56.6929 500.3989 null] ->> endobj -1729 0 obj << -/D [1705 0 R /XYZ 56.6929 492.5805 null] ->> endobj -1730 0 obj << -/D [1705 0 R /XYZ 56.6929 467.136 null] ->> endobj -1731 0 obj << -/D [1705 0 R /XYZ 56.6929 460.6924 null] ->> endobj -1732 0 obj << -/D [1705 0 R /XYZ 56.6929 436.6227 null] ->> endobj -1733 0 obj << -/D [1705 0 R /XYZ 56.6929 428.8043 null] ->> endobj 1734 0 obj << -/D [1705 0 R /XYZ 56.6929 414.0996 null] ->> endobj -1735 0 obj << -/D [1705 0 R /XYZ 56.6929 408.8714 null] +/Type /Page +/Contents 1735 0 R +/Resources 1733 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1652 0 R >> endobj 1736 0 obj << -/D [1705 0 R /XYZ 56.6929 382.1516 null] +/D [1734 0 R /XYZ 56.6929 794.5015 null] >> endobj 1737 0 obj << -/D [1705 0 R /XYZ 56.6929 376.9833 null] +/D [1734 0 R /XYZ 56.6929 748.5056 null] >> endobj 1738 0 obj << -/D [1705 0 R /XYZ 56.6929 350.2636 null] +/D [1734 0 R /XYZ 56.6929 748.5056 null] >> endobj 1739 0 obj << -/D [1705 0 R /XYZ 56.6929 345.0952 null] +/D [1734 0 R /XYZ 56.6929 748.5056 null] >> endobj 1740 0 obj << -/D [1705 0 R /XYZ 56.6929 321.0255 null] +/D [1734 0 R /XYZ 56.6929 743.7078 null] >> endobj 1741 0 obj << -/D [1705 0 R /XYZ 56.6929 313.2071 null] +/D [1734 0 R /XYZ 56.6929 719.6381 null] >> endobj 1742 0 obj << -/D [1705 0 R /XYZ 56.6929 298.5024 null] +/D [1734 0 R /XYZ 56.6929 711.8197 null] >> endobj 1743 0 obj << -/D [1705 0 R /XYZ 56.6929 293.2742 null] +/D [1734 0 R /XYZ 56.6929 697.0552 null] >> endobj 1744 0 obj << -/D [1705 0 R /XYZ 56.6929 267.8297 null] +/D [1734 0 R /XYZ 56.6929 691.8868 null] >> endobj 1745 0 obj << -/D [1705 0 R /XYZ 56.6929 261.3861 null] +/D [1734 0 R /XYZ 56.6929 665.1671 null] >> endobj 1746 0 obj << -/D [1705 0 R /XYZ 56.6929 199.468 null] +/D [1734 0 R /XYZ 56.6929 659.9987 null] >> endobj 1747 0 obj << -/D [1705 0 R /XYZ 56.6929 199.468 null] +/D [1734 0 R /XYZ 56.6929 635.929 null] >> endobj 1748 0 obj << -/D [1705 0 R /XYZ 56.6929 199.468 null] +/D [1734 0 R /XYZ 56.6929 628.1106 null] >> endobj 1749 0 obj << -/D [1705 0 R /XYZ 56.6929 191.7053 null] +/D [1734 0 R /XYZ 56.6929 601.3909 null] >> endobj 1750 0 obj << -/D [1705 0 R /XYZ 56.6929 176.9408 null] +/D [1734 0 R /XYZ 56.6929 596.2225 null] >> endobj 1751 0 obj << -/D [1705 0 R /XYZ 56.6929 171.7724 null] +/D [1734 0 R /XYZ 56.6929 569.5028 null] >> endobj 1752 0 obj << -/D [1705 0 R /XYZ 56.6929 157.0677 null] +/D [1734 0 R /XYZ 56.6929 564.3344 null] >> endobj 1753 0 obj << -/D [1705 0 R /XYZ 56.6929 151.8395 null] +/D [1734 0 R /XYZ 56.6929 549.6297 null] >> endobj 1754 0 obj << -/D [1705 0 R /XYZ 56.6929 137.1348 null] +/D [1734 0 R /XYZ 56.6929 544.4015 null] >> endobj 1755 0 obj << -/D [1705 0 R /XYZ 56.6929 131.9066 null] +/D [1734 0 R /XYZ 56.6929 529.6968 null] >> endobj 1756 0 obj << -/D [1705 0 R /XYZ 56.6929 117.2018 null] +/D [1734 0 R /XYZ 56.6929 524.4686 null] >> endobj 1757 0 obj << -/D [1705 0 R /XYZ 56.6929 111.9736 null] +/D [1734 0 R /XYZ 56.6929 500.3989 null] >> endobj 1758 0 obj << -/D [1705 0 R /XYZ 56.6929 97.2091 null] +/D [1734 0 R /XYZ 56.6929 492.5805 null] >> endobj 1759 0 obj << -/D [1705 0 R /XYZ 56.6929 92.0407 null] +/D [1734 0 R /XYZ 56.6929 467.136 null] >> endobj -1704 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F39 885 0 R >> -/ProcSet [ /PDF /Text ] +1760 0 obj << +/D [1734 0 R /XYZ 56.6929 460.6924 null] +>> endobj +1761 0 obj << +/D [1734 0 R /XYZ 56.6929 436.6227 null] >> endobj 1762 0 obj << +/D [1734 0 R /XYZ 56.6929 428.8043 null] +>> endobj +1763 0 obj << +/D [1734 0 R /XYZ 56.6929 414.0996 null] +>> endobj +1764 0 obj << +/D [1734 0 R /XYZ 56.6929 408.8714 null] +>> endobj +1765 0 obj << +/D [1734 0 R /XYZ 56.6929 382.1516 null] +>> endobj +1766 0 obj << +/D [1734 0 R /XYZ 56.6929 376.9833 null] +>> endobj +1767 0 obj << +/D [1734 0 R /XYZ 56.6929 350.2636 null] +>> endobj +1768 0 obj << +/D [1734 0 R /XYZ 56.6929 345.0952 null] +>> endobj +1769 0 obj << +/D [1734 0 R /XYZ 56.6929 321.0255 null] +>> endobj +1770 0 obj << +/D [1734 0 R /XYZ 56.6929 313.2071 null] +>> endobj +1771 0 obj << +/D [1734 0 R /XYZ 56.6929 298.5024 null] +>> endobj +1772 0 obj << +/D [1734 0 R /XYZ 56.6929 293.2742 null] +>> endobj +1773 0 obj << +/D [1734 0 R /XYZ 56.6929 267.8297 null] +>> endobj +1774 0 obj << +/D [1734 0 R /XYZ 56.6929 261.3861 null] +>> endobj +1775 0 obj << +/D [1734 0 R /XYZ 56.6929 199.468 null] +>> endobj +1776 0 obj << +/D [1734 0 R /XYZ 56.6929 199.468 null] +>> endobj +1777 0 obj << +/D [1734 0 R /XYZ 56.6929 199.468 null] +>> endobj +1778 0 obj << +/D [1734 0 R /XYZ 56.6929 191.7053 null] +>> endobj +1779 0 obj << +/D [1734 0 R /XYZ 56.6929 176.9408 null] +>> endobj +1780 0 obj << +/D [1734 0 R /XYZ 56.6929 171.7724 null] +>> endobj +1781 0 obj << +/D [1734 0 R /XYZ 56.6929 157.0677 null] +>> endobj +1782 0 obj << +/D [1734 0 R /XYZ 56.6929 151.8395 null] +>> endobj +1783 0 obj << +/D [1734 0 R /XYZ 56.6929 137.1348 null] +>> endobj +1784 0 obj << +/D [1734 0 R /XYZ 56.6929 131.9066 null] +>> endobj +1785 0 obj << +/D [1734 0 R /XYZ 56.6929 117.2018 null] +>> endobj +1786 0 obj << +/D [1734 0 R /XYZ 56.6929 111.9736 null] +>> endobj +1787 0 obj << +/D [1734 0 R /XYZ 56.6929 97.2091 null] +>> endobj +1788 0 obj << +/D [1734 0 R /XYZ 56.6929 92.0407 null] +>> endobj +1733 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1791 0 obj << /Length 2542 /Filter /FlateDecode >> @@ -7727,173 +7849,173 @@ xÚ¥Z[w ÇÄ¡V"l·Jäë‘¢š7&vᨒ׷„°FœEÄmÊm™E]â'B‰™`µ¸÷ÕHëÖ&&s-?¦! }™fðŠÊ S“}„Õ×iya] ½r°.…é$HÙ…kp>¶Pn ü@ÄHB;I ¡]Ktº8ól«ËGXáÝÄjù°P-Ã0MÀL(6ƒ‹º 'wiÞ@‰Úh¢¾ÀG°5Ø|=¤E»KžùóHž5Ì\‡€¶¨–ç¥fºÙ¾i¾íU…ôN‰!¸›RÆ•”A9vPî‚68b[H7Á9£ÂÅØ|šÒ„»>»i*°µÇ×€%Á /ŒxéÊÅÚØÏ÷Fâ(ßWæÃEtšDœ@Æ6}8@aÇ8¿Á¸¸WK8ßù¢W7é~§Åö5‚ð &ÐA]Êæ¦”p-eî(ƒÐágØã„÷ÀŸNÅm¹c<€Ó¨ó™^C‰U·„óó`Ê ‘gDDvXýZdüR±(’>¬Ž%PØ×q#êâ,«%7æ-y¨^ôB0WD¡õˈ…§JøŸrö³:û ¸ÊY'ˆŒ¨2”¨‚æËÓF @¨µ> ‡ÐÈ¿P˜R3RRº›‚ÐaF.hÃŒ†Ø32Á¿Ö­uˆ]Vçê(•:_ÝübU”¥ÜàÓ\ÄÞ¢zÉšªí‡Än¥ œ¼œKðˆ zløÓô´Eé˜éÛ EðÂñ…v”r¡¤4$pt‘Nhƒˆ!¶…\g„P×üPÔnppSŽiñ£Gkñž½y#$¾Äæt‡$dúÉWþ-gd¦vÕ×îÁw~áì”ù«¼@?½Ü„þ¯~ùÑEy¹Ns˜-b+Ÿ~D½(¼”.L);ŸZªã“:ŠG'tÇçö8Ÿ=ð…ž¾³¢‹Þ)—’UÁÀùTõÇg9µcºrÖ(£úÿ¬·é¶ÝM ¼ƒ ¼tBZ¤.éQäèá\¸)` 'òšA7FØÖ¨™-b¸"2ú]¨JÑ޼¡ Ý—àyõ`è×’5J%^ƒúû“¤¨sÆÑ‰7àØN¡^€‚ ¥€)å JIi¦ 7;˜rAT ±-\™àKþåW²­›$œ.Nͨ¼ŒóÎÄ’ˆƒüH¹ùI4}çsñvõM42¼ùàç¼+KëFÞo·›u=êTt„) ºC(ù>Š»ïÚñ7ßµ„ž©«{ˆôíDB—-Ô…/{¦”ƒH%¥‰LËå\БCl ‘&¸®éVOÅxê¨Ò¢îм³/÷üÓjžlü›òž:Gkêå©Òžª”«­ÞëÊÙ6ìØ¥0Xfâ{1Oý™øãK]æ¬a4°´Ã1gˆýªó½ý^1ã+êyˆ±Ø&GÁXܶ`JÙmAK]”#):¡;[8÷…¸°?œÞvC8k£'ü¿gå¾JoहXùì(0Cß‹)MÌá(žÞxâ»T|dy.wÚ/&>tËÛ·Sþ“«)ÿ”³¬)˜þîH°äö–RšŽ]Ydd¥£ð{ó˜ÿ¡…×РînJ9(VRºî #G£ì„6(b[(6Á¯³B§­Ïé S=sv–iG{ -9±ôIŒ»©Òï¯bF²SÁà´?Õæ!±ò¡‘n !; J¨û$9úhnÇÁxœY8YŒ!à4¼ªÅœ7%ÿo6×°(£2ùP.ì÷ba¯¾ëÇÊ+à.kVœ¸¥7álE‘9ôˆAWܧ«»­Ì›òž[Ý¨Ï§ÌøÆ§Sþ3ŸŸxYAFméÿÿ ˘OF‰m3Ù…«‡j»#tö{1ýÓ­ógÿ/’#÷ðendstream +9±ôIŒ»©Òï¯bF²SÁà´?Õæ!±ò¡‘n !; J¨û$9úhnÇÁxœY8YŒ!à4¼ªÅœ7%ÿo6×°(£2ùP.ì÷ba¯¾ëÇÊ+à.kVœ¸¥7álE‘9ôˆAWܧ«»­Ì›òž[Ý¨Ï§ÌøÆ§Sþ3ŸŸxYAFméÿÿ ˘OF‰m3Ù…«‡j»#D†®ºuþìÿ’{÷òendstream endobj -1761 0 obj << -/Type /Page -/Contents 1762 0 R -/Resources 1760 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1634 0 R ->> endobj -1763 0 obj << -/D [1761 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1764 0 obj << -/D [1761 0 R /XYZ 85.0394 748.4854 null] ->> endobj -1765 0 obj << -/D [1761 0 R /XYZ 85.0394 748.4854 null] ->> endobj -1766 0 obj << -/D [1761 0 R /XYZ 85.0394 748.4854 null] ->> endobj -1767 0 obj << -/D [1761 0 R /XYZ 85.0394 743.3452 null] ->> endobj -1768 0 obj << -/D [1761 0 R /XYZ 85.0394 728.6405 null] ->> endobj -1769 0 obj << -/D [1761 0 R /XYZ 85.0394 723.1655 null] ->> endobj -1770 0 obj << -/D [1761 0 R /XYZ 85.0394 708.4607 null] ->> endobj -1771 0 obj << -/D [1761 0 R /XYZ 85.0394 702.9857 null] ->> endobj -1772 0 obj << -/D [1761 0 R /XYZ 85.0394 688.2211 null] ->> endobj -1773 0 obj << -/D [1761 0 R /XYZ 85.0394 682.8059 null] ->> endobj -1774 0 obj << -/D [1761 0 R /XYZ 85.0394 668.0414 null] ->> endobj -1775 0 obj << -/D [1761 0 R /XYZ 85.0394 662.6262 null] ->> endobj -1776 0 obj << -/D [1761 0 R /XYZ 85.0394 599.7666 null] ->> endobj -1777 0 obj << -/D [1761 0 R /XYZ 85.0394 599.7666 null] ->> endobj -1778 0 obj << -/D [1761 0 R /XYZ 85.0394 599.7666 null] ->> endobj -1779 0 obj << -/D [1761 0 R /XYZ 85.0394 591.7571 null] ->> endobj -1780 0 obj << -/D [1761 0 R /XYZ 85.0394 565.0374 null] ->> endobj -1781 0 obj << -/D [1761 0 R /XYZ 85.0394 559.6222 null] ->> endobj -1782 0 obj << -/D [1761 0 R /XYZ 85.0394 534.1777 null] ->> endobj -1783 0 obj << -/D [1761 0 R /XYZ 85.0394 527.4872 null] ->> endobj -1784 0 obj << -/D [1761 0 R /XYZ 85.0394 502.0427 null] ->> endobj -1785 0 obj << -/D [1761 0 R /XYZ 85.0394 495.3523 null] ->> endobj -1786 0 obj << -/D [1761 0 R /XYZ 85.0394 420.5376 null] ->> endobj -1787 0 obj << -/D [1761 0 R /XYZ 85.0394 420.5376 null] ->> endobj -1788 0 obj << -/D [1761 0 R /XYZ 85.0394 420.5376 null] ->> endobj -1789 0 obj << -/D [1761 0 R /XYZ 85.0394 412.5281 null] ->> endobj 1790 0 obj << -/D [1761 0 R /XYZ 85.0394 388.4584 null] ->> endobj -1791 0 obj << -/D [1761 0 R /XYZ 85.0394 380.3932 null] +/Type /Page +/Contents 1791 0 R +/Resources 1789 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1843 0 R >> endobj 1792 0 obj << -/D [1761 0 R /XYZ 85.0394 365.6884 null] +/D [1790 0 R /XYZ 85.0394 794.5015 null] >> endobj 1793 0 obj << -/D [1761 0 R /XYZ 85.0394 360.2134 null] +/D [1790 0 R /XYZ 85.0394 748.4854 null] >> endobj 1794 0 obj << -/D [1761 0 R /XYZ 85.0394 345.4488 null] +/D [1790 0 R /XYZ 85.0394 748.4854 null] >> endobj 1795 0 obj << -/D [1761 0 R /XYZ 85.0394 340.0336 null] +/D [1790 0 R /XYZ 85.0394 748.4854 null] >> endobj 1796 0 obj << -/D [1761 0 R /XYZ 85.0394 325.269 null] +/D [1790 0 R /XYZ 85.0394 743.3452 null] >> endobj 1797 0 obj << -/D [1761 0 R /XYZ 85.0394 319.8539 null] +/D [1790 0 R /XYZ 85.0394 728.6405 null] >> endobj 1798 0 obj << -/D [1761 0 R /XYZ 85.0394 295.7842 null] +/D [1790 0 R /XYZ 85.0394 723.1655 null] >> endobj 1799 0 obj << -/D [1761 0 R /XYZ 85.0394 287.7189 null] +/D [1790 0 R /XYZ 85.0394 708.4607 null] >> endobj 1800 0 obj << -/D [1761 0 R /XYZ 85.0394 272.9543 null] +/D [1790 0 R /XYZ 85.0394 702.9857 null] >> endobj 1801 0 obj << -/D [1761 0 R /XYZ 85.0394 267.5392 null] +/D [1790 0 R /XYZ 85.0394 688.2211 null] >> endobj 1802 0 obj << -/D [1761 0 R /XYZ 85.0394 252.7746 null] +/D [1790 0 R /XYZ 85.0394 682.8059 null] >> endobj 1803 0 obj << -/D [1761 0 R /XYZ 85.0394 247.3594 null] +/D [1790 0 R /XYZ 85.0394 668.0414 null] >> endobj 1804 0 obj << -/D [1761 0 R /XYZ 85.0394 223.2897 null] +/D [1790 0 R /XYZ 85.0394 662.6262 null] >> endobj 1805 0 obj << -/D [1761 0 R /XYZ 85.0394 215.2245 null] +/D [1790 0 R /XYZ 85.0394 599.7666 null] >> endobj 1806 0 obj << -/D [1761 0 R /XYZ 85.0394 149.4956 null] +/D [1790 0 R /XYZ 85.0394 599.7666 null] >> endobj 1807 0 obj << -/D [1761 0 R /XYZ 85.0394 149.4956 null] +/D [1790 0 R /XYZ 85.0394 599.7666 null] >> endobj 1808 0 obj << -/D [1761 0 R /XYZ 85.0394 149.4956 null] +/D [1790 0 R /XYZ 85.0394 591.7571 null] >> endobj 1809 0 obj << -/D [1761 0 R /XYZ 85.0394 144.3554 null] +/D [1790 0 R /XYZ 85.0394 565.0374 null] >> endobj 1810 0 obj << -/D [1761 0 R /XYZ 85.0394 120.2857 null] +/D [1790 0 R /XYZ 85.0394 559.6222 null] >> endobj 1811 0 obj << -/D [1761 0 R /XYZ 85.0394 112.2205 null] +/D [1790 0 R /XYZ 85.0394 534.1777 null] >> endobj 1812 0 obj << -/D [1761 0 R /XYZ 85.0394 97.4559 null] +/D [1790 0 R /XYZ 85.0394 527.4872 null] >> endobj 1813 0 obj << -/D [1761 0 R /XYZ 85.0394 92.0407 null] +/D [1790 0 R /XYZ 85.0394 502.0427 null] >> endobj -1760 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F39 885 0 R >> -/ProcSet [ /PDF /Text ] +1814 0 obj << +/D [1790 0 R /XYZ 85.0394 495.3523 null] +>> endobj +1815 0 obj << +/D [1790 0 R /XYZ 85.0394 420.5376 null] >> endobj 1816 0 obj << +/D [1790 0 R /XYZ 85.0394 420.5376 null] +>> endobj +1817 0 obj << +/D [1790 0 R /XYZ 85.0394 420.5376 null] +>> endobj +1818 0 obj << +/D [1790 0 R /XYZ 85.0394 412.5281 null] +>> endobj +1819 0 obj << +/D [1790 0 R /XYZ 85.0394 388.4584 null] +>> endobj +1820 0 obj << +/D [1790 0 R /XYZ 85.0394 380.3932 null] +>> endobj +1821 0 obj << +/D [1790 0 R /XYZ 85.0394 365.6884 null] +>> endobj +1822 0 obj << +/D [1790 0 R /XYZ 85.0394 360.2134 null] +>> endobj +1823 0 obj << +/D [1790 0 R /XYZ 85.0394 345.4488 null] +>> endobj +1824 0 obj << +/D [1790 0 R /XYZ 85.0394 340.0336 null] +>> endobj +1825 0 obj << +/D [1790 0 R /XYZ 85.0394 325.269 null] +>> endobj +1826 0 obj << +/D [1790 0 R /XYZ 85.0394 319.8539 null] +>> endobj +1827 0 obj << +/D [1790 0 R /XYZ 85.0394 295.7842 null] +>> endobj +1828 0 obj << +/D [1790 0 R /XYZ 85.0394 287.7189 null] +>> endobj +1829 0 obj << +/D [1790 0 R /XYZ 85.0394 272.9543 null] +>> endobj +1830 0 obj << +/D [1790 0 R /XYZ 85.0394 267.5392 null] +>> endobj +1831 0 obj << +/D [1790 0 R /XYZ 85.0394 252.7746 null] +>> endobj +1832 0 obj << +/D [1790 0 R /XYZ 85.0394 247.3594 null] +>> endobj +1833 0 obj << +/D [1790 0 R /XYZ 85.0394 223.2897 null] +>> endobj +1834 0 obj << +/D [1790 0 R /XYZ 85.0394 215.2245 null] +>> endobj +1835 0 obj << +/D [1790 0 R /XYZ 85.0394 149.4956 null] +>> endobj +1836 0 obj << +/D [1790 0 R /XYZ 85.0394 149.4956 null] +>> endobj +1837 0 obj << +/D [1790 0 R /XYZ 85.0394 149.4956 null] +>> endobj +1838 0 obj << +/D [1790 0 R /XYZ 85.0394 144.3554 null] +>> endobj +1839 0 obj << +/D [1790 0 R /XYZ 85.0394 120.2857 null] +>> endobj +1840 0 obj << +/D [1790 0 R /XYZ 85.0394 112.2205 null] +>> endobj +1841 0 obj << +/D [1790 0 R /XYZ 85.0394 97.4559 null] +>> endobj +1842 0 obj << +/D [1790 0 R /XYZ 85.0394 92.0407 null] +>> endobj +1789 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1846 0 obj << /Length 2121 /Filter /FlateDecode >> @@ -7906,119 +8028,119 @@ Z9 aÜo汆ÆÙ3¨¢sõd¥Ë*^ÉÛXxùÎR~ȬتýÁŠüˆ9w›m&U¿Øé½cïU¢Àâ,pò¢2ª‹ö6°L@ÎU\¿²q8.€6býN}×I?âL¥°Ž ®üHU®‹}fFµVÕx•øý}_à»*ê¬cIj†\m­17ÂÞÔ©ÏpÐÆºû<3ú$)6“.|¶qžjéŒ:¯ü≀Æ2-“,N7:‡ê‰¸jH ññBçç®:s%võrá‹(+$-K¢èp uüa„ÄøÉÒ7YÂò°§O+|Ëô'66E^­ /œ÷z‰?Ö)\6;6jVìÙ+†ÎRZ/ÙÉT[?뙉Wà BRSOÄú1£ì ô<(AD]­Xx©°óZìM¬¸¾{˜åºP¬ú\J"VßCÞäN¹Qï3;¡Ô»pý²©Î“ ì‚™8 -ÓÙ„õç‘A­Ç> endobj -1817 0 obj << -/D [1815 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1818 0 obj << -/D [1815 0 R /XYZ 56.6929 749.4437 null] ->> endobj -1819 0 obj << -/D [1815 0 R /XYZ 56.6929 749.4437 null] ->> endobj -1820 0 obj << -/D [1815 0 R /XYZ 56.6929 749.4437 null] ->> endobj -1821 0 obj << -/D [1815 0 R /XYZ 56.6929 746.6461 null] ->> endobj -1822 0 obj << -/D [1815 0 R /XYZ 56.6929 722.5763 null] ->> endobj -1823 0 obj << -/D [1815 0 R /XYZ 56.6929 716.7581 null] ->> endobj -1824 0 obj << -/D [1815 0 R /XYZ 56.6929 701.9936 null] ->> endobj -1825 0 obj << -/D [1815 0 R /XYZ 56.6929 698.8254 null] ->> endobj -1826 0 obj << -/D [1815 0 R /XYZ 56.6929 684.1207 null] ->> endobj -1827 0 obj << -/D [1815 0 R /XYZ 56.6929 680.8926 null] ->> endobj -1828 0 obj << -/D [1815 0 R /XYZ 56.6929 656.8229 null] ->> endobj -1829 0 obj << -/D [1815 0 R /XYZ 56.6929 651.0047 null] ->> endobj -1830 0 obj << -/D [1815 0 R /XYZ 56.6929 636.3 null] ->> endobj -1831 0 obj << -/D [1815 0 R /XYZ 56.6929 633.072 null] ->> endobj -1832 0 obj << -/D [1815 0 R /XYZ 56.6929 609.0023 null] ->> endobj -1833 0 obj << -/D [1815 0 R /XYZ 56.6929 603.184 null] ->> endobj -1834 0 obj << -/D [1815 0 R /XYZ 56.6929 579.1143 null] ->> endobj -1835 0 obj << -/D [1815 0 R /XYZ 56.6929 573.2961 null] ->> endobj -1836 0 obj << -/D [1815 0 R /XYZ 56.6929 558.5914 null] ->> endobj -1837 0 obj << -/D [1815 0 R /XYZ 56.6929 555.3634 null] ->> endobj -1838 0 obj << -/D [1815 0 R /XYZ 56.6929 540.5988 null] ->> endobj -1839 0 obj << -/D [1815 0 R /XYZ 56.6929 537.4306 null] ->> endobj -1840 0 obj << -/D [1815 0 R /XYZ 56.6929 510.7109 null] ->> endobj -1841 0 obj << -/D [1815 0 R /XYZ 56.6929 507.5427 null] ->> endobj -630 0 obj << -/D [1815 0 R /XYZ 56.6929 477.5928 null] ->> endobj -1842 0 obj << -/D [1815 0 R /XYZ 56.6929 453.2532 null] ->> endobj -634 0 obj << -/D [1815 0 R /XYZ 56.6929 369.7201 null] ->> endobj -1843 0 obj << -/D [1815 0 R /XYZ 56.6929 345.3805 null] ->> endobj -1844 0 obj << -/D [1815 0 R /XYZ 56.6929 310.6805 null] ->> endobj 1845 0 obj << -/D [1815 0 R /XYZ 56.6929 310.6805 null] ->> endobj -1846 0 obj << -/D [1815 0 R /XYZ 56.6929 310.6805 null] +/Type /Page +/Contents 1846 0 R +/Resources 1844 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1843 0 R >> endobj 1847 0 obj << -/D [1815 0 R /XYZ 56.6929 310.6805 null] +/D [1845 0 R /XYZ 56.6929 794.5015 null] >> endobj -1814 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F39 885 0 R /F14 729 0 R >> -/ProcSet [ /PDF /Text ] +1848 0 obj << +/D [1845 0 R /XYZ 56.6929 749.4437 null] +>> endobj +1849 0 obj << +/D [1845 0 R /XYZ 56.6929 749.4437 null] >> endobj 1850 0 obj << +/D [1845 0 R /XYZ 56.6929 749.4437 null] +>> endobj +1851 0 obj << +/D [1845 0 R /XYZ 56.6929 746.6461 null] +>> endobj +1852 0 obj << +/D [1845 0 R /XYZ 56.6929 722.5763 null] +>> endobj +1853 0 obj << +/D [1845 0 R /XYZ 56.6929 716.7581 null] +>> endobj +1854 0 obj << +/D [1845 0 R /XYZ 56.6929 701.9936 null] +>> endobj +1855 0 obj << +/D [1845 0 R /XYZ 56.6929 698.8254 null] +>> endobj +1856 0 obj << +/D [1845 0 R /XYZ 56.6929 684.1207 null] +>> endobj +1857 0 obj << +/D [1845 0 R /XYZ 56.6929 680.8926 null] +>> endobj +1858 0 obj << +/D [1845 0 R /XYZ 56.6929 656.8229 null] +>> endobj +1859 0 obj << +/D [1845 0 R /XYZ 56.6929 651.0047 null] +>> endobj +1860 0 obj << +/D [1845 0 R /XYZ 56.6929 636.3 null] +>> endobj +1861 0 obj << +/D [1845 0 R /XYZ 56.6929 633.072 null] +>> endobj +1862 0 obj << +/D [1845 0 R /XYZ 56.6929 609.0023 null] +>> endobj +1863 0 obj << +/D [1845 0 R /XYZ 56.6929 603.184 null] +>> endobj +1864 0 obj << +/D [1845 0 R /XYZ 56.6929 579.1143 null] +>> endobj +1865 0 obj << +/D [1845 0 R /XYZ 56.6929 573.2961 null] +>> endobj +1866 0 obj << +/D [1845 0 R /XYZ 56.6929 558.5914 null] +>> endobj +1867 0 obj << +/D [1845 0 R /XYZ 56.6929 555.3634 null] +>> endobj +1868 0 obj << +/D [1845 0 R /XYZ 56.6929 540.5988 null] +>> endobj +1869 0 obj << +/D [1845 0 R /XYZ 56.6929 537.4306 null] +>> endobj +1870 0 obj << +/D [1845 0 R /XYZ 56.6929 510.7109 null] +>> endobj +1871 0 obj << +/D [1845 0 R /XYZ 56.6929 507.5427 null] +>> endobj +638 0 obj << +/D [1845 0 R /XYZ 56.6929 477.5928 null] +>> endobj +1872 0 obj << +/D [1845 0 R /XYZ 56.6929 453.2532 null] +>> endobj +642 0 obj << +/D [1845 0 R /XYZ 56.6929 369.7201 null] +>> endobj +1873 0 obj << +/D [1845 0 R /XYZ 56.6929 345.3805 null] +>> endobj +1874 0 obj << +/D [1845 0 R /XYZ 56.6929 310.6805 null] +>> endobj +1875 0 obj << +/D [1845 0 R /XYZ 56.6929 310.6805 null] +>> endobj +1876 0 obj << +/D [1845 0 R /XYZ 56.6929 310.6805 null] +>> endobj +1877 0 obj << +/D [1845 0 R /XYZ 56.6929 310.6805 null] +>> endobj +1844 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F14 737 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1880 0 obj << /Length 1945 /Filter /FlateDecode >> @@ -8029,45 +8151,45 @@ O3i_ ! ˆ(ñ7|Ùl‹²†B ù¼¬WÍn[ôeƒ•Ï×»‘Í›Öí€U¦ŽÖ š~ã\¹ŸåcåˆÜ7ME+€a{·#¤5€×kâ¤Zë>¦=‰ÒwÇnÅÓùmOT8åꈷy‡ŽºŒü™ê°*"ÖKH,£][‡@î7ŽÈEÝ=Ãq‘Zôa›—5ðиßïj·¤å©²=#-DZ q;2.ááȈ3t€Ò-Ae³OM×Ç‚ª–·•²ò˶¬Ë1ïú]Ñ7^x ï;7á l>Tœ .ݲ1Û÷ ö¤äîµÛ4 ŠnùQŒ––auÛÑÒ£[(…_nVô-û°½„ kþ ,d`…â|Oáþöè¢gZ¥h«ìÁ| ƒ›ýwß·ûýGðùg¸›ÝËv=´ C‡BDúnŠ'¶`WàG«}½À˜(ªá<¸ÍzÂà ³‰1éï\³\«XûXÌΚeyn@Çœ¥iJÿ¦ê7Í~½™8Jè8•ºvµ2eàÁÀUJÎkŒñª:àÌ›{Iôç²ßmÑl·`ý¤*kGkëýÖÕ}‡Wg$\.qU×צè‰æE¿Ûf ü=ãšR7€ÕB¹»ýB(bŠ%%}r¡h©ëCŽ8†(ÎŽ™JVÎç;C´Gˆ½ »=(½;Ф DïÀxÆØ$õÔ$ä½ ··¨X7$̉ˆnw˜‘ßêùóÆÕ4Âtò²È§9Âêp‘ÉfÚ«Lfc@¤OØð]—O®Fõšÿ³®ÊïŽè®ØU¥˜`úEÑÁiJÙMZ3{{÷ž8ò€ºm!øA÷âxR³šŒ x‰¡¾X—Lj¢7ƒw6ÏdµDãÓ*züÛ}Õ—måN£»GòcX,»nïB”Ÿø…âÀ.7€Á ³áÆN‚lF)A‘ïK¥B1”phµ$Š?(¾°© J׺E‰N¸ y,{*Œ›TCV|i@ÉsïyÍ€^5繬ª XŠ2 —Ô«‚QÕ%jUvä–¨e=á‹Â&¤ˆêk×/^à ª©žb*Ëàá$@º‘¿/šz5!÷¸Ñ‘82ÿ¿(Fd ¿éɵ1&ŒÎH>ÀŽc\|a“ŽIëë ³É®Z_Èll}@ ^ñ}Ûßè!0\E᥮þ#:ötM0!ßmzì)¢¡,<ƒyfÇ–ò}“ÍBà§ðëºÐ Õ;(P;ØZêG¨;ZZºUÖÑ: -7Ñ[¤ʘÐ×ìbyíòTSþ*¤Ñ›þüïŸ?}øÏkx»Åb¦˜Í¬ü:5¿ßDU)ÇŸªŸ µƒ8Èa€\Ô¢7…r$sÍ´gõȇ½á'®ƒ“¶…ü¹ŒYÍu\¼œcN‘‚³N¦{ß`Bɺ½£/uµ0x÷‘¾ô{ƒo™1§tDm ¦«¢¥I¨í0ê¯ÂõMK`•{rÑè•ý!`zfó%5YH§Î-œ1ñ³¼eL–ÅBç£ëMÓÙ+5´‚çžy1W±»M—ª¢T£ªÊ!Å¢´¼:Ë/ ðw¿F“™C]ôª^®×"‡¤aÉ~\”,†Ïpî‰4êHi0Fë)šP´ƒ4ʧۻ˜@`eè¡¡„*œžõÐÈøîcäw H¨©Ômá/„íàÍ]tì¦}²÷/açïðãó˜áϲ“íÀ’yèÙÑo#\Ó/U€:q~ÜðïËóþ Ðažƒendstream +7Ñ[¤ʘÐ×ìbyíòTSþ*¤Ñ›þüïŸ?}øÏkx»Åb¦˜Í¬ü:5¿ßDU)ÇŸªŸ µƒ8Èa€\Ô¢7…r$sÍ´gõȇ½á'®ƒ“¶…ü¹ŒYÍu\¼œcN‘‚³N¦{ß`Bɺ½£/uµ0x÷‘¾ô{ƒo™1§tDm ¦«¢¥I¨í0ê¯ÂõMK`•{rÑè•ý!`zfó%5YH§Î-œ1ñ³¼eL–ÅBç£ëMÓÙ+5´‚çžy1W±»M—ª¢T£ªÊ!Å¢´¼:Ë/ ðw¿F“™C]ôª^®×"‡¤aÉ~\”,†Ïpî‰4êHi0Fë)šP´ƒ4ʧۻ˜@`eè¡¡„*œžõÐÈøîcäw H¨©Ômá/„íàÍ]tì¦}²÷/açïðãó˜áϲ“íÀ’yèÙÑo#\Ó/UÜœ7üÀûò¼ÿйž…endstream endobj -1849 0 obj << +1879 0 obj << /Type /Page -/Contents 1850 0 R -/Resources 1848 0 R +/Contents 1880 0 R +/Resources 1878 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1857 0 R +/Parent 1843 0 R >> endobj -1851 0 obj << -/D [1849 0 R /XYZ 85.0394 794.5015 null] +1881 0 obj << +/D [1879 0 R /XYZ 85.0394 794.5015 null] >> endobj -638 0 obj << -/D [1849 0 R /XYZ 85.0394 769.5949 null] +646 0 obj << +/D [1879 0 R /XYZ 85.0394 769.5949 null] >> endobj -1852 0 obj << -/D [1849 0 R /XYZ 85.0394 573.0107 null] +1882 0 obj << +/D [1879 0 R /XYZ 85.0394 573.0107 null] >> endobj -642 0 obj << -/D [1849 0 R /XYZ 85.0394 573.0107 null] +650 0 obj << +/D [1879 0 R /XYZ 85.0394 573.0107 null] >> endobj -1853 0 obj << -/D [1849 0 R /XYZ 85.0394 538.4209 null] +1883 0 obj << +/D [1879 0 R /XYZ 85.0394 538.4209 null] >> endobj -1854 0 obj << -/D [1849 0 R /XYZ 85.0394 504.6118 null] +1884 0 obj << +/D [1879 0 R /XYZ 85.0394 504.6118 null] >> endobj -1855 0 obj << -/D [1849 0 R /XYZ 85.0394 432.7569 null] +1885 0 obj << +/D [1879 0 R /XYZ 85.0394 432.7569 null] >> endobj -1856 0 obj << -/D [1849 0 R /XYZ 85.0394 303.3232 null] +1886 0 obj << +/D [1879 0 R /XYZ 85.0394 303.3232 null] >> endobj -1848 0 obj << -/Font << /F21 702 0 R /F23 726 0 R /F41 925 0 R /F53 1017 0 R >> +1878 0 obj << +/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1860 0 obj << -/Length 3824 +1889 0 obj << +/Length 3825 /Filter /FlateDecode >> stream @@ -8086,124 +8208,138 @@ h £L¨¸Â›2ޤŠà˜ÊjŽŠåû]>ê|“(ÑÆô®³av½Ò»^q¬$C“¡Ç|qYðw)Ð÷þæ Wr–ÇëçbÙ–Ÿ‹ÿx…f&@Ã2Ô \ÙZ6Ýmž _•˜¡ áÁKa¸t…'z ù²ªr±ØðPý–‰¿¬>åý¿È¦endstream +/ÉpÚQœÀ¬*VË9pcÐ-Zq4õM´ÂRˆû2G„/%þçï¥_ƒk)k'¾ñ‰ $†´™)‡:Dzú-Y}ÊûXȨendstream endobj -1859 0 obj << +1888 0 obj << /Type /Page -/Contents 1860 0 R -/Resources 1858 0 R +/Contents 1889 0 R +/Resources 1887 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1857 0 R +/Parent 1843 0 R >> endobj -1861 0 obj << -/D [1859 0 R /XYZ 56.6929 794.5015 null] +1890 0 obj << +/D [1888 0 R /XYZ 56.6929 794.5015 null] >> endobj -1862 0 obj << -/D [1859 0 R /XYZ 56.6929 752.1413 null] +1891 0 obj << +/D [1888 0 R /XYZ 56.6929 752.1413 null] >> endobj -1863 0 obj << -/D [1859 0 R /XYZ 56.6929 501.191 null] +1892 0 obj << +/D [1888 0 R /XYZ 56.6929 501.191 null] >> endobj -1858 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F48 940 0 R /F53 1017 0 R /F11 1367 0 R >> +1887 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F53 1027 0 R /F11 1384 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1866 0 obj << -/Length 2981 +1895 0 obj << +/Length 3111 /Filter /FlateDecode >> stream -xÚ­Zmsã¶þî_¡o•' ’èL>øÎ—Œ;éʼn}Ót.þ@‹”űD:"eWÿ¾»X|IwÚÎÍœ@`‰]’-k¯?Ë›ü°/Jûèð€—j€ÏìíL\Pž®´¬ßÈy°å“1p¬Ê&Ͼ·§¼[V0ÇÁRº«­ï€F±Ï«c3x“€h̲à±np@žŠ¼¼M:Û¥±ésJ[·¬I|0Ânã: ˜N·qp0òh¥Sz„sÿVåvû‰³ù:Ï&ÞxÙíäuñdÕal9ÀÀ‡ ‰絿;¸Žcç0:B­xÒµ°&mDnYÄû,BCm°< É>a &£F-ï-7™„£€ëdÊ`ì #'¡½„Ø&t¹#©$5Z$Δ՘¯àÞBçÞL´¹Ëü ¶™ÞêÛò´$ß½†¯Æ -c §‘]×/HDëágp YÆqÞÇ%­i?µåkº;¢Ë\ðÏ;%ìÜÏ9uS&ƒ ÇkÇÓq€YÀ©c„ùDÛôuøâ¦:ìÇÈã N´K ¾£ud?ÛFàLD%QèC€SLzéœØûW²Ì[Ÿ‹Ç’¶þ¯g©2 ˜‚4\É8C%£¹½Zu¥Lf+“‘ÌÖK™U~+«‡fý2TÌP9bïhöRçªÌ‹á`ðî¯x¬þ[†[.!ªêŒåZ÷ŸniÌæÕÐe ¥ÔßÁTÌôS*l1mw²|“BL!™ÇQà9Æ'ôZ(b(Gj©ñõúÖR ×jp¢å.¯ÝΕô{õû¿YŸl}÷ïq>ÓjlÝ/ Ô­W/ìT.p@sÖÖ‹§ôcà0#UYRTéOL¹Þ˜„²ŽEïШ#5C#'åiôº>c&0I¨æ{©sÍq`ää=ÕÄ"éYÄ,‹¤g‘ô,bŽE’÷XÄ‹d—E -ªŽû-q6`¦4®ÒˆÊ&ýµëmU/ÿ” >í´aHâAÈ´+ñ -ë4eÈÅ…êS¯“áÙ@¾q|{L×Ïoi¸ Iö/P=»¢9]rÎÑM Îèp Äa(_×ø¿Ë C¨3¡âÐÓ·0jÖÇ¢Á±I¾ĮE¨çùÖ•šæ›—òhBô¨ùç b&óʽԹöAù­ Ñ—¼¯þ5»¬–—Pe•®ö„¢™3#Ob:lÎð>ß$ç <œþ4£qвÄÌÆ_Fe¬‘AóPã.âÀÇu[‡n„;Ñ™ ’:K)$a2 Ã~!˜f挎3.DBR'Ãæ·´#5³¥NÊliVíÓ¢üóiW^÷ö&Ï[à¥ÎMèï+ØAðî™p‡ ˆ\ª:'xЋÓÚ‰Tô ~¸Iq³ûïÁæíl›Ö5â!Bɨ–®ˆì.|`-DÍ$dq{!4£«˜¿ØmõK¾ö™·°V¥#ÅåJ@Mª åé'%][ûÕtÈHGþÊĦªMa²«ˆÔJ‚ ®Tÿ7뇼®v¯Seµ†]Á<¡]hb+E\ÀCT ¯¿3¼³3ÖE®!D“{‡Ñ>V¼½SýÛ‡$€ZÀÙûêXoG̳ W<»óñ¼{®ž§ròLe@Ú0œ?S]©é3奼›lW1ê&g•·nòLû¸›ì©7¡]’ Íã(4c…flÙšC÷vhGq$Ë‘Ö%Õ‡ÌÖ‡£oÚw¸ÍÂà×2šæéÓ‡Gi 1ÚÊÝËZÊÚo°ótn&è ‰d¼-6ò²Æ“­={ѸòtÒ;Ðæy6îŸ\ýo¢À4Ë8žx©ÞaYGj†eNªeÙ¶z›`Z,ƒ˜‰w ðRç .¼4 F{&ÜRÜ" ˆm]°lX{è¥ÒC°qþ>ÓÔ“ ª}Ænn§&!Èù$'ßéJMCì¥<İÁ£Q#c&çµ{©sõ}|#ÄŠÇ}ý×¹»œHÛz¥¡.ì±ÀÖ}€OeUžöm29âq#HýÃPw“äqyˆUp©Å;w¤f vR^wšVåî4é+g•·¾òLû¸¯ì©‡Ü£\Üaj¦mnî/+;µ¢¦“Rü)èBÈ7T”¼]Gj:'Õn³KŸ¦¡›SÞn¨}º®ú«ÿ˜n‘†Eú þÁŽtE J Õ½á/ÞâH¾»»RÓ z©ÖºlÔYå-¨gÚÇAí©§\X)[V+é.g^‡>På»ÐuuMãü—8ÊÒ&¥¯€(ðXØILrª”›Bö¼ŠBi/p`„&Wî] uç\OÙìN4¶54Ò™RÇ·©»|Bµ÷œø`ˆ`¾’ã §W³a6ª" ƒP^ˆ>çÑp¼|<ÚaZ4R[~SoEÌÝqOŒVירë#cX=ÿ=îìRovy“— Osj(âïøÔ®Ô ‡”çðúÏ)ïpx¨}‚Ã]õ†ÃÀ›@ƒ2‚„[c‹<(4>]Ó/rx½Í×Ï” @OVÔXxdöc6ô˜Í†ñÃÝYz4–LØ$êÜù™ž°}Ë0Æ©ª -Sz¸þrw÷ùµ_Ó]‘¥m!Rmzù qy’ -:¢K§Y&t„¦‰à„Zì&¯ç´¶·ƒCµã—ƒ]½×ô­p*-´Ÿ¡ôÓÏWwwî*6/;à|zèemVä?†LÀ -ÁD„ïÜ™´2Ó Z™öB±Í>ƒUÊ á@˜­^f¨vðGŽ_¤ºzÿ;Lïïþ?!ê*à_üŒ¬ùðÿóµ6%ñ¯<’‰*˜ „ÐÜ…0q¦†¦û?A:·ýßh @endstream +xÚ­ZmoÛ8þž_áoç k•õÆöCÚtYì¶Ù‹ÛC›Š¥ÄBlÉkÉÉùßß gH½Xrw‡5E9ÃáÃg†däLÀ?9KBO(Ìbx¡álµ½³'hûùB²Ì +-ºR–ïRñL{:ò£Ùò±3Vâ‰$‘³eöm~u{ûéóõÍŸ— ?óÞå"bþÛÕç¯W¿RÝí¥öçW?ºƒÏ(>I‹ÄüúæçËûå/Ÿ–Θ®ÁR(´ä¯‹o÷b–Ý¿\Oé$œ½Â‡ð¤Öþl{„Ê ¥lÍæâîâw7`§Õts@¨/Lüxľó@¨½HAzàczhŠª¼\(ÏëuuØdT~Èé·IŸsn~]ÛÒ¡.Ê'n_çè…÷?²£K&—$" QËâH2={$Ø#•d‘j×Úa·‡MS,u¾gûŽu“okúHëÖSxÎXˆæ«´ìÏᥨ‹‡ %Ú2[€·½D«JÒÓaè3Ìh~¬æÕ¡Ù,óÇý¥LæÕ–Zvõw^†ÿ$‹îI F6ßnŒzo6«éc]ÔMµ?’èw!üM@R‰˜ÿÃøeدX\Þ¼Œ,¬4Å*%aëkѬ٥]·+í{J|öiV<ù=ð4±Ì8 nm.ÓmN +DìáX=ÿÀZ¼àrø!öIÑAa2/jªùëï‹<£2ϳšÚ›ŠªžËêÕöͩɬÖ¤%÷K7OÕæ·å¾¬E;-9y zQEó›’Z?Ü|¾þÁ*)ê¾YUæ<ˆ$8§G„°£•~)2V!æéŽ+wû"mò¯K!Š ]z¾›eÿúéË0œÿ“ ùr»¼ùòùndžàt@¨å9”ÆžôeÌf´ë’ã4% ’yyØ>¥´´q‹šÄÅ"¬6Ìu€<à`ämÃoÐòÀÒ)}¶­Œr^~Âl¾Ê³‰»Í¯‹'V‡¡edÿ¼$J,i¿Û·žŽcK +œF¾ÖF2éZX“6‚‹dÉ>ŠÐPŽ•Jú^DA=ÉMFM8_26E[ç)B±bà l9R ­%TÀ2!ãŽdÓh•X"(«1®P@&¾e7l`ì2B¾6ó°-OK¢v¨5x5V˜5ñ¼¾ I¬ç?ã_$`œ”ý ’Ö´žàµùKº9 e)©ŒaXçH +7ÅsNÕ”È`ÁâÛqwìa0'Ð1ºùH ëôeØñ±ÚoÇÀ##/N´Í +ÞÑ<²m#îL”%‘ï"€ULziŸp† ¼ GaÁ{—9òï'™²ðDYx†(Ba4µg¡EWÊ$¶A2’Ø:)3Ëoeu߬vCÅR”#ñ†f'uªz€¼6†èþŠ;AÁì¿e¸ääBUC5°ÜSiùñ–Ú8­†*ãZʬ±fb¦ž2 °E$4¯dùc +1…drDû¿µPÄ@ŽÔRáëõ-C ×Ã¥;”›¼¶+WÒïÕŸ?ýÁœÌÜ}ãj,g²Æ–~¡¡nY½à¡là€â*­™ÅSú1î0-UYRTéL©ÞŒ ©RúoÀ¨#uFVÊÁèeu‚"ø8ñÃóŠÔ©æŠ$  RòžjBQàP$ECQàP$,ŠÙC‘°( +º( +áб\F`6À0¥¡J#v,›ô_Tn˜mÃ^ú$p.pùgw£ C’ô|¡í ¯`Ò |é…R…S™wÎüÑâí!]=¿¦mà2 Ùîà8ôPlŠæx)¥DšRRÐæ@‰ï¾¼¬ð›@†PF6Bž9¤·0jV‡¢Á¶I¼±ïIçñ֕𯛓rÞ„èQíó̅‹µŸœWî¤NµNß!äùì«¿AÍ6«€ý%²J{ô„33mfALb*8gØç›ä\à†‡ÝŸfÔNQ¶“˜qütŠ52cék\Eløp¤jf8¤i)¢3$u ) _?‘ƒtÓMÓÌ|Ññ …p¬òÃ8|cI;Rg–ÔJ™%ͪmZ”?b>mO×½u…Á£DÄç-pR§&ô×lˆ x÷L¸Ã„NE6U€B“{U„iHmE*únR\ì~?X¼ —i^# áKHFu`Ï݉¬ +ù"nï"”t³ãd[½ËW.ó6 lU:r¶\(¥½Rž>½tmí¦/ˆtänL8Um +“]Erü<@ÊžÔßçÍêý>¯«ÍËÔ©Zê`žÐN4á“"NÜC÷S ¯¿2²³2L‘+ÑDïÐÚ÷•l¯ãÂþåCâÁYÀÚûu¬Ö#f‚Y+žÜйñ¼»¯žÀOåäžRqä~øÆžêJMï)'åh²Å(MžUÞÒä‰öqšì©7¡)É„fˆqš±†B3–øÌ¡{+Š ´¢Ø’åë’·‚χ£=¹ä, ~Ñ4N¶Ø< +[ˆéPíµ,C–Ïx£+?gHl!Ûæ@üQÖxä³g/÷\:tÒ;r çy÷öüo¢À4ÊTà…A½²ŽÔ”Y©eëêuiqàÅB½a€“:µ`pá¥àƒ°oÂ-Å-r¡­ë,k÷½Tzèlœ»Î4çIˆƒ]Ænn§¦],/òã7<Ü +q0 9ÿÂêŽFÅà‹à¬j't¢»ïÚHzq(ãžòëÜ^K¤íI¥¡*¬a—Ö}×˪±™Êª+Þöå™Ïë:çËJ?†S=i}¾”÷ùÔ´ØkxSÎH +gˆ¯nGªïÜëÃ]51ŸVÍ›%”^ÒM‘1aúô,‹’0ÂÁ%ŠX¿ZñÝ)…"´¨"Ñ“çÉï_0[”ÌwÕæ’ñÕ±;«¤{-ÌM€P°~?Jj*Ê OóÚv1·½]q è\Ž÷f=1Ù¤;Y0®3ߤõì[!ZR¿Ö¡ÐypÖ{ òËí_×_¾.©bŸ–Oø†(3[Áƒñlé‹'«ÝsÔíÒ=ë1^Ô’½…®U¯imGì,æÈTìmŠËJœ—&)ïM%û<Åt¥¦)ÆI9ŠY§˜³Ê[Š9Ñ>N1=õ†b`crª–Ø5M$S –ÈÛPøxM¿H1«u¾z¦­5YQã‰0ã?2€Ã2X0a²;Je@>± 6õYÆOü¶—{ÈÇ¡ª3¬2Ì5éãúóÝݧ½åv'Äê±—XÒÅÐ$àdìo¥–¡i X¡›É{ÛsZÛkÛ¡Úñ[Û®ÞkzÄÊ×ù÷~é|üõêîÎÞ‘çeçeÔåíN¶ÏU“n…X¯ü7žUZ™i§²L{ÓÛÀbŸ¸r—D`Îhu2Cµƒ?NѰý¢°«÷¿óérùëÿÉ£öäzø—X#sî#þç?øjÿœ-À¿¾I&^ ð £”–Ö(t“ñÐt÷§a§¶ÿR+¯^endstream endobj -1865 0 obj << +1894 0 obj << /Type /Page -/Contents 1866 0 R -/Resources 1864 0 R +/Contents 1895 0 R +/Resources 1893 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1857 0 R +/Parent 1843 0 R >> endobj -1867 0 obj << -/D [1865 0 R /XYZ 85.0394 794.5015 null] +1896 0 obj << +/D [1894 0 R /XYZ 85.0394 794.5015 null] >> endobj -1868 0 obj << -/D [1865 0 R /XYZ 85.0394 674.4719 null] +1897 0 obj << +/D [1894 0 R /XYZ 85.0394 679.319 null] >> endobj -1864 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R /F21 702 0 R /F48 940 0 R /F53 1017 0 R >> +1893 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F48 950 0 R /F53 1027 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1871 0 obj << -/Length 2837 +1900 0 obj << +/Length 2838 /Filter /FlateDecode >> stream -xÚ¥Z[oܺ~÷¯ØGITÞ%èC‚¤9hOÝ-øA^Ѷ­´Yic8¿¾Ã«HÝö´Å>ˆ"GœáÌ7’‹w~xÇE* -R첂¥a¾Û®ÐîÆ~¹Â–æ#zR½»½úÓ_i¶+ÒB±»}æÊS”çxw[}IÞ¥8½†Pòþã/×oˆàˆ$oon>üöþã¿á# „’¿¿ýíóÛ¿™¾›ëÈ~ùðéúîö׫·^˜P`Œ¨’äûÕ—;´«@î_¯PJ‹œïžá¥¸(ÈîpÅ8M9£Ôõ4WŸ®þé' Fõ§K -`6òú Íq2<éIz9 ×8©ÛGóÞ=D8ùý½y~E®qžèEÔ]kè+Ùצ» -lhïëÁ4êvÂîûYž^®1Æ €"C,¹}ªûéG¶D3Ý¿(•iäˆg  œ–¨VVɇòÜ ¯“äù©Þ?ÄŠ"9ȲíÕ‡  (Ð+2Î@«úóúÑÒDJÌÒ‚ˆÂÒ´ÝéP6Í‹™·—m¥$Dúø!ͨZ`-{X€*ù=PЫ•)¢ò€ýëØbT¤˜d|·9MgŒräá8Øi‡Î<¿"DÚÊ "MùÔê0ùÃvµåA:N?äÉNó`ñ߬æýã­¶îØégå¨ÊÁŒÊRG†ˆ±Yš*u´åE Ñ 円ZÚ:~)Ió<£ðPmà×Qyüz/ŒÀ Á‚‰<ßæí©æÌcœ2(bîQþ(Àú ˆÉ…09£pp‚F%ùXZhÁ±žÌȃ¶Mwˆ>Ær]7˜n ½"„^á ÔžÏHh¤ñΗsÄc+:X)䞪 ÁT- -@ãâ]0ƒ±î½±½&Óè‰wç<ÐE0…lõ KžLQ– ¹ìÉ>ÊoÒ:`=È“wÓÜå»t¡Fà8^»ö|B­{ô]£¿%ÌêF¬¡e=Qz•A·QEÉÇÁ >×P44yy蚦{™<ÈÓ©lz;<Ú<ÓÀæ@d-­Ò8ƒÔÿÔ={A\¤ñŽi*OÈîÏÎwG§C+ôï1<—ý˜‰ì`†«£Èë•:”Vüž ‘f$Û~R­û½§ò~¿?T3¯GP«cz³§š³ŽáÙ…lÂ{ôz¥0aCMާºLІn‚au_=(„”yßw‡ƒl78™¬;dz¬€®~xñs{*Q,ÇÇÙ)R¥þviÇ3ìhTjÑ®ÃZÙ¤´ô¶_+kFH=•0÷ÒiåñØÔªÔGE¶ÐUý£2¸- á©êÐxo™ùˆ³:IŽ.$›jtŽÊƒœð4¬&›MÞc²™1_N6÷ãÍ? V“VÝRížLqþŒ%^½2ÒY¬]çÞZËÇãHÝF r÷c éç°j ¦¶«y†·-R­[ÂSyK8§X-[7ÙeëŒÿrÙ ðéI‡vpÀ/:ÿ‚óUéhuð†®ïLŸ ïÐøxcÆÊª²Aµ7ºšS#G/3Ñùp/On‚ÒÍz6MÌœ½ÌŽ0K³œ.n“(gkÛ$žr&üÎÆÃ|º³m»=’«ÔaZãáis< Pœ||0½f>ÝT1-#´ýÎï†Ô‹iC„éU.À†×b“r:‚9dkÔ®–×-ä,-hÆãôØk»EHﻳæ¶wÈMc\Á cÕr¦Ñ±ïa:ábz=Žî[-ûšvÛ5O½9½HCª OrTc"5±·_÷¤-ö'Mù¯xR(@XCGZ·5’£,ÑÔ­ìãå¿6Ùó ƒN!ëö€Ê@ˆ_°G@µaG5æØrö«9f“÷˜cfÌ—sLÄݦcšûäMçäª=øºG½hµB#¨{ýƒyªUÔýPïû?«Ó¦BT?íä〓)A¡q(+ùZmFñH××?¥g°¾§ñ0N|l^&^Ü[swí&:î%T/µÛæþ‘”ÔCãÒWDE–2F.äÆjAžÊ#èûiÊ·ÈSN/°µ4s®“ª˜Bõ [àˆíͨ‘/•Õ’ŽÉ^]wëúr[zâš=8¡µÒ»¸ú{½>™û8æ¾qºFi–b¨ò·-1mÂvPLyÏZdÝâ=Ö)óå¸rwæPŠ6‡«Lü>E™Cq'áEÕo½Ü/f'Cuh(µ®¡i_ažÒÒúÂÚÚÂm‡ó©5…?+´Ó­+ÿu¹¯a³_¶Ê(´¯‚@™W t!Ó†TëpðTc™ßup$A·™{ª9÷Ih·$°m‹Ø¿ÓéÜCm¶½ÛØDZu ¹œ[{‹ñÇÓn”çë Ö -”]H¹!Õ†aÕh{Ö;ßM0”Ò¬ÀÛü=Õ\€Ø6PfSX,ÁhælÜmXdæOŠQ2Ь_GóИ‡ó°%ó Ìš‡…æaÖ<Ìš‡E§ËÛæ`E1»°ë©6Ìã¨FóTU­VW6sûu×’m à©æÄöI)Íc ógáÌ#"ódÎ<" DÖï£}˜°öÆ>bÉ>…³í#¬}„µOæí£ƒ©(Ҍ擊hÃh¸ )b]@´n2G4Z¬iVç¶ØŽgsS¾ËGs!ãOÒÆW¶íYÚ¦’go¾"DËÇõ* uF.\¼…T*rTæê°>ȿܮTi›l]•6ãº\¥ElAC?.ï«ey§ÏáÝ\í@£4—íi·t% -®’ñÌÜß.äPŸøÛPðƒ®­ú8‘äF&+¶ˆ' 7øû·­Ö\ëy9-é° 0(Žd0‰ÝdYpØK¹SQ—°2»{›±=C¯Êì˜õâ3´ \פUìSnçö-Áu ?C]C-.Ô?7.¤ÊjµŽÊ^xײŸÃvôì-ÎkOY¯øvÈÛB×Ýt©†?†±×mzÔéè:ûÔª†Æç÷7¦áî‡"2ncúæÀ!œ¦Æ|éá¹%¨Û~e5‘Ï üEpLÕ#X®ÎË\ 6ë9¿È×Ý‹Õöâ ¶f^ßÁ¥ß|]¼”ßÏe—g?¥9¸šn¸À¬RÃ\Ý@µí6áfªsëÏÀôevÀ ¯b:ËR’‰ Ûå€hã/H–Hú$€Þb;âyÊwÎ!c‹fê8ð¨Qh›3ìѬšyÚÍ”93ÁÓÐ1{L›¾%LCš±b[$+f…t+öæ”'$5Ç>ŸÕ¡OS[:uO@iÎ -Óš8³tüÌÕÿoœ'xL:´Uœnþëvßœ«éᢾŠsPÿ~µòÇ;à«þ-·€´sÎõÿ)oüË!Ë cædO$ã)|,œPJ‰¹ã ”PH»sÙÿn þ¥endstream +xÚ¥Z[oܺ~÷¯ØGITÞDQú éAÚS÷ÄA $~W´-D+mVÚίïð*R·=m±¢Èg8óÍ…äâ‚Þe<å)vyÁÒ ál·?\¡Ý#Œýr…-ÍGô&¤zw{õ§¿Ò|W¤'|wûÌ%R$ÞÝV_’w)N¯a”¼ÿøËõÂ3D’·77~{ÿñßðž! „’¿¿ýíóÛ¿™¾›ëÈ~ùðéúîö׫·^˜P`Œ¨’äûÕ—;´«@î_¯PJ ‘ížá¥¸(ÈîpÅ2šfŒR×Ó\}ºú§Ÿ0ÕŸ.)€e"Íã  +š”“e5á4Ljr†SR0êÕÄÄ’š•RÓ«/mww’ûó©—Ó%c"RFhðÅwO5gOhÀSš2”‘˜ÿ­Òw÷øØÈë7TàdxÒ ’ôr®qR·æ½{ˆpòû{óüŠ2tºÆ"Ñ‹¨»ÖÐW²¯MwØÐÞ׃iÔí„Ý÷³<½\cŒEŽXrûT÷Ólˆf>ºQ*Ó(ËA8-2X¢ZY%Ês3¼RL’ç§zÿ+Šä ˶W‚‚p  @/Ï3Z՟ז&Rbž„–¦íN‡²i^̼½l+%! :ÐÇiFÕkÙÃêTÉï²€^­L•ç¡;”C½7³ª¡ªîËûFVf¥³”#)Zêó“lû(}j©³Pj–Ïyf¥~Õö½,O Žùú£D·¾î´00Ü«éÕp*÷ra&*RšqbÉŒyµˆÝq€u÷æ¥4š2/ç^VéÌï­sq‘§¨@bÛCªuôTÞC•D.H8 ¾MöžjÎâ‚E +¸±ÿÒÖ£8ëiˆCË(É´]Àþõl1*RLòl·‚¦3F9 òpì´Cgž_"m呦€|êNõ˜üa»Úò @§òd§y°øo VE–"ˆN1Vv­27+’}×eÝêã°« Õº—~´éºoàºû|4ÏRÉ«ÁIŽMùbzý<ŸþñÖ [wìô³rTå`Fe©#CÄØ,ÍŒ?•:Z€ò¢…èrCC-m¿”¤Bäô~ª ü:*_ï…x!X0.Ä6oO5gCˆà”AsòGÖALÎ(¸É…ƒ4*ÙÈÇÒBŽåðdF´mºCô7–ëºÁt[è!ô += ö|FBƒ Gp>‘¡,¶¢ƒ•Bîù¨ +LÕ¢4n!ÞÅŒuïý‹í5™FL¼;‹@Á²Õ3,y2Ey +$ä²'û t(¿Ië€õ OÞM…Ë7vé$ƒ!ÃñÚµçjÝ£ïý-aV0bõ-ë‰jÔ« ºÊ(J>f𹆢¡iÌËC×4ÝsÈäAžNeÓÛáÑæ@à™6"ki•Ƥþ§îÙ â"wLSyBvv¾;²<Z¡‘à¹ìÇLd»0„XE^¯Ô¡Ô°â÷çiNßöûjÝï=•÷ûý¡šy=‚ZÓ œ=Õœu 7È.¬`Þ£×+…q‹Âir<Õí`‚6t« 3¨ûêA!¤lÌû¾;d;¸ÁÉdÝy8žÝ`tõËŸÛS)xèˆb9.8ÈN‘*õ·K»,ÇŽF¥í:  •OJKoûµ²f„ÔSés/]‘VM­JpTd ]Õ?*#³%!<µBï-3qÖ@G  èB² ©6@ç¨<èÀ OÃj²Ùä=&›óådq¿1Þü°`5iÕ-ÕîÉôçÏYâÕ+#ÅÚuî­µð¤)ÿO +kèH+ã¶&Pr”%šº•}¢ü×&{þ¯aÐ)dÝPðeìPmØÃQ9¶œýjŽÙä=æ˜óåq·é˜ +ŸÜ¡éœ\µ_÷¨­Vhu¢0OµŠºê}ÿgušÃT‚ê§|p2%(4e%_«Í(éúú§ô Ö÷4ƉÍËÄ‹{kî®ÝDǽ„ê¥vÛÜ?’2ƒzh\ú*‚(ÏSÆÈ…ÜR­#ÈSy}?Mù"Íè¶–fÎuRS¨ža ±½5ò¥²ZÒ1Ù«ën]_nëQO\³'´VzW¯×'sÇÜ7N×(ÍS Uþ¶%F¢ CX¢Ñ*ƒ)ïY‹¬[¼ÇÀ:e¾WCîΪBÑæp•‰ß§(sp2î$¼¨ú­—ûñÅìd¨. ¥Ö54íá+ÌSZZ_8B[[‚»íïp>µ¦ðg…vºõbå¿.Wá5löã‹ÃV…öU0(ó +„.dÚjžÊãa,Ó⻎Äé6sO5ç> íà–¶mû÷a:{¨Í¶wÛ€H«.!—Ó`ko1þxÚò|½aÎRŽò )7¤Ú0Œ£ cÏzç» †Ršx›¿§š ÛÊlÊ‹%mÜm˜³ ‹lÃüI1JF‘õëhZó0c¶d”[ó°Ð<Ìš‡Yó°ètyÛ<¬(fvÝ!Õ†yÕhžªªÕêÊfn®îZòm<Õ\‚Ø> )¥"– 0wæáÎ<<2OîÌÓ@dý>Ú‡qknì×ìS8ûðÐ>ÜÚ‡[ûäÞ>:˜ò"Í©˜TDFÃI¿ë¢u“9¢ÑbM³z8·Åv<››ò]>š ’6Ƹ²mßÈÒ6•<óxó!Z>®Wi˜«0ráâ-¤ÚP‘£2W‡õAþåv¥JÛd몴×å*-b Òøqy_5@(Ë;}Öïæj¥y¸l¯H»¥+Qp•<ËÝÁýí¡€úÄ߆‚tmÕÇAˆ„ 72Y°EI@Ç ·ØŽxžò]†sÈØ¢™úæN(¥ ŒÄÜqPJ(¤Ý¹ìÿnøþ§endstream endobj -1870 0 obj << +1899 0 obj << /Type /Page -/Contents 1871 0 R -/Resources 1869 0 R +/Contents 1900 0 R +/Resources 1898 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1857 0 R +/Parent 1843 0 R >> endobj -1872 0 obj << -/D [1870 0 R /XYZ 56.6929 794.5015 null] +1901 0 obj << +/D [1899 0 R /XYZ 56.6929 794.5015 null] >> endobj -1869 0 obj << -/Font << /F37 791 0 R /F48 940 0 R /F23 726 0 R /F21 702 0 R /F53 1017 0 R >> +1898 0 obj << +/Font << /F37 799 0 R /F48 950 0 R /F23 734 0 R /F21 710 0 R /F53 1027 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1875 0 obj << -/Length 3266 +1904 0 obj << +/Length 3265 /Filter /FlateDecode >> stream -xÚ­ZÝsÛ6÷_¡™¾ÐÓŠÁ'?òàÔnÎmš¤µÓ»›¶”HÙœR¤*’NÝ¿þv±DŠ”Üi/™„¸À.¿]ì.Å þòE¢C&SµˆSjÆõb½½`‹x÷ö‚[š¥#Z©ÞÜ_¼úFÆ‹4L#-î7ƒµ’% _Üç?W?Þ¼¿¾ýÏåRh¼ /—š±àû«÷Ÿ®ÞÑØÇËTWooî i&€ˆ#YÄ‚ëÛ·—¿Þ{qsï… -Ì™DI~¿øùW¶ÈAîo/X(ÓD/>C‡…ýqà z#ƦÝôu^äsn ß‘a8ÛÏ›Ï֦᣹»} z gc¹p:`aï|AfWø“nœ†zÖ!Akõ­µÇŒxêÔú½/öÏv!;qeiÉ­ž²5ŽWb¤_°µÕ[sTÆÖмn_114…C}ž±§šr> -_пÉdÌú QnŒ6gl‰×U€µeSÛ÷ =½sãè+w^engú£Kh/&´¶ €ÑwÖHÏÊBÁ œÿiÿ¿ó?¾tjºàà˺Á#›q àõ¤%ݺ‚û¨=ºéHÛÂD‰6Z h7zˆ:Ž@šHžâê4=•Ù×Ïuóë‚°²*ëb‚Ç( cð­çù{ª©c<Æ °(Kðq_bÜ£Dbõ´nÌ3oi°*+¨eô‰»W؈ç'`ø€ÏŒ ÚUÓÚ™f§K³UÓ‡èd›YîJaë±ßfõ’PÌ;rßÄ7˳U… 1Áðã7¼âHÓ¥€ã>ÄÅ:Vbû;»u*²õ# Ž÷DchŽH•Q/6b,Ü ¢J¦~ÙM¶†ÓĘH¶°¶=ÜcG½°Zdtù ã.14P„â˺(èaÆx*© \+»þ´sÕ`Ð $7/`z@uÓŽÊcz“•Õ4;„ÐQÆÑyÖžjÊû(Ž‘ï¤cÞט$)HEšŽ:©,zÍ«âû®-öO&oT6m€çsÓ½ÅAa¢L|“ÑãîæÇK­ƒŸ¾¹ŒUpuû.¤á{·ü!©‚EL&¥lî6#–Kž€ÔˆE! ì+–Ç=‰jîÜÇÁj"ßyW‡î¬ƒªFK³®ºíúÕ£b·øª€,¹ôÃîNBGANÅ‹ÏCgHu:žÊCgU@.²×ÐMkÌä xª©GÖb{=᪃Äu‡ÁpDžBDàFÊvWeÏvÐ(HtètˆÆhFm¸ÜRÏVÄw2Re:¿"7ø± _xü`§l­„]&zŒ w•P™0ÏK ÏÀÞÉu ùi{úHeŠˆ½j ©Î©£òG -Ww[¬'Ç©d""9ÏÜSM¹š8V|ÌþÇ‚ψCÖ þÝÍ×Ôž\^œÒjólM1ÀŒ<»+aÇ@àxÁßÙ¥ú ÓìúüÏ©7#O£Ãìïçd¡3WÜZrT»™dñYž—„.Þ¶1áhêé2Ä(ä?™ÂE“0qCªÓ@ðTmù°~ÌÚ™HG„1¬q–»#šr²ÉX¤rÌþkÃv) ¾p‡&æ¯uÖõÞ4O°.‚v —7âÇVZzW¯i˜V`!n»++ch>ŒÁÖòz¦ ¬ªTªÑN_* ‹0M’d¾ ¼ô+¾ §´b¬–»Û·_ÿëêîæ4@éÂï<Tgðਠº}E§åoÅóë/àÏIÔ‰Èo'£GÆçÊÎì[GcP1S•*Ô©/¦}94#ù±”Ÿ&‡òÔRÀ²7&lE€éïnþëJžp,I*ç‚æC`k. ØÆ8s®£ì\À•0Ò } 1Z”&fá[ô2© nø·Ö+5Ÿ dS¬IË—Y—ù¹’gTMó1ØÌ–u i¹ÏMÅo±þÍq"Ô,v³ÀSΖª(Næ—WMbÜ'¯Æi§®´ò¯ÉߨG‚ÇpIÌWí¯vWõl†üp©¿íÞÊL|ðÀ[iæ¼´f½•ˆÑ•ªt!ÊøO½•_q9\rj®\KÌe|àü—¼•èó„½ðÅkHuÚ[y*{uÍΔÒ&qL‘Sç¹{ª)û£ë‹‡±æñ˜ÿ¿˜Kajû™Íyz¸ÊàÅñUÆÝUFí]±Ç€:M‡ -mq›R™g)„NÓc8Ák®›AÒÅt<ÆìßÃÇJœ´Ð x•þsŒ¹—Ã%g0†f­„>pþk1H”¾8©Î`ÌQyŒáG½“‰óYÖ‡ÄyÂ{6qñ¾­×UŸ» ²>.™¯ž6ÀÔ›û‹Wߨd–±,–ñì~ÝÕ2ž¦bv¿ú9ºúøñæýõí.çÒðè »œΣï¯ÞºzGk/3]½½¹ƒil¸ `1®oß^þzÿíÅÍ}`¦Ï°à +9ùýâç_ùl|{Á™ÊR3û ÎD–ÉÙæBÅŒVʯTw?„½·vë”´I™‘:žÍ8Q™˜gÜÀ±ç‰æ,‰¥bÒ锘<ŠéËzÕtíëëãã +%Ys1ëãQPcÒRõH •°T‹#ÚwEw9W*‰ºÇ‚õ~³(v8Ž£fMkÈŸË݆ÇüÉíèzæÛmq)¢|GӲƽúÆô¹NÜ•J\ƒ·àb•7`<&âç$&oZ«’Dµt’"†ÇÈd"VñßU.6òäÎ]Ɖf<ÙyŸÚ‡:íS”õ©‹ýº-ÿ,^¿yU­AäpÅgi¨1ñ¡WÕK²Ø ©[¯*½5ãàÓõG€¶ùƒ[&Qük«ëhèÀ1Žâ(_=»®lI¬“@Ûë÷wÜ¡ŸòŒ2N0{ey3q;ÑTâÏ]Ñ2ty‚¼™e3ÿ£Üì74A‹!ó†éÄdC;Ù”µƒM2{„–†=ðÙ=–nep^˜,&±1ʸuk¢0àô °vKzZ=_ +!"d9K¢Ÿ0…@wë©î;ôäÒ)v9ÈOXZ0¶ãf_¯ŠÕ”ØoÉ0¼í¯šÏΦ!àÑÞí®ÝãKð!_¸taç}Aî0üI§¡™sH0ZæûÖÙcN¼uý¾/vϑ۸p°äVOÙšÀ›l­uÆÖ<”µµbU·¯¿šŒ¨¡9O8@)¥/èßT:$}*Q®­4RoliUµeS»÷ =ƒSq¬êk_åÊí W—ö´&|ˆLã€ÑwÎHÏòBÉ(8ÿ¡¦ýÿîÿ86˜Œ“ùäà˺Á+›p àõ”!ܲ‚xÔE:’Ŧ°Y¢Ë–† ºƒžTD“ÄÀM¬Î+bê´"({®Ÿëæ× $aeUÖÅHã”%à[ÏÓPc†ú˜@5ÀãlÈÁÇ]‰y–©“Ó²±ÏUK‹Uù[A#+OÜ}¸ÂA2½Ó|æôÑ.šÖí´'Û£Ú9d'›ÜQ§T +GûM^ÏIëbà9æGî›èæ«|Q!". Þ`þ†A!‰ \).Nбj¨ØPq¾uG‡¥"_>ÒâðL´†æˆP9M1°aáY Õ* h×ùn`Ùnw¹ÇŽz Êê Sðéç]²o - –õYÐÄ-ˆ„i¥= „•íþ´s5`Ð)7/ètêŒN{¨ Ó뼬ÆÕ!¤Ž*‰Ï“PcÚGyŒ‚|'Ò¾Æ"IC)Òt4èÐñ(í´×¾*þpïÚb÷dëFíÊx>7{‚wzPØ,ßäô¸»ùñÒ˜è§o.]ݾc´|ïÑŠ*@b+)íj· ¶|ñ –-JYà\‰:Nì‰UsKTV›ùN»:tgÅP©j´4çªÛn¿èƒcVì‘/ +¨’KÐ~8ÝIÕÑPSqÍ“óªÓ‡:­:*¨Î¢€Zd ®¡)d¬ W/0 ÆY‹-ìÍ…« +×-&Ã1y +ƒ)Ûm•?»E+l@!Ñ¡Ó!+iXuérK3Y±èÅd„Ê+t~ÅÊêóXø"èNÊÖyAHÙUj†:áC©U*›æ.a¸˜\·PŸ¶§¯TÅLÆü…T«uæJ=T¸RÝm±]§áP‰Èô<ñ5¦>¼NHk’D‹!ù H>Z¼#U3ü»›¯i< +^‚Êjûlm3À®<û—+áĪÀ1Âß¹¥Ûú 7üúü/hŽ‘Qdña÷‡÷S¼Ðkn-=êÝŒªø|µ*;H]‚mcÁÑÔãˆÒKÄ(å?¡*ƒ@“ry^úP§!@EhˇåcÞNd:’%€ã,u4¦>T¨&™©!ù¯-Ù¹„üÂ_š”X¿>Ôy·¦)±y‚}´KÞ¨?®ãÐÒk ½v`SX‰¸Í¶¬¬¡…4Gó뉆°N%Ó™Òƒ“¾Ô–,KÓtº!<_‹†[X9ËÝíÛ¯ÿuuwsZ@è1ªßy}èAÑeõ¡Ûí±é4ÿ­x~ýüéDtªÎ³ Æ< µ",VYp©*hŒn4Â?XÓî2öÔ/Ã9ðï6£GÆçÂíÜ·ÆjÅD Tif²ÐLû²oGüc+?Kí©¹´76mE ÓßÝü×·<áZÒLM%͇ÄÖ 8ưó®£ì|À·0Óe!‰…-ÎR‹øÖ6MŒ‹CIµA¨«¯&2ÙD0¡âø¥L6NC¿ÇU™@£jšßˆÈz²¥h&uh)Ú®_OÍü›"&%“™O›ÁYNv«%Sæô"Ò ¬R +~pÛ‰‹Èý’<Ž+rTª@$=qauî¾ïÙô]øá2²ïzþÊn|^qÏ_îýŒ&ý•LЙêl¦¸`BÙ?öWã¼rl°œK"Tr ü—ü•å)á›Wê´¿ +P!~uÍÖ6ÓF™L ¹×穨1ù£&XbD2¤ÿoÔ˹´ÝýÜU";3xqÌ„f4Þ;L i’Óv8Ðܵ…m!•«¼³­p0Ù±:Ág¯PAÙÅÍ‘Îþ=Øë›–&eUãë˜Ç8Ð1°j£¥9Pþk:&à({¡tîCÑ1t ?ë,Ï’>”Î#Ú“¥ó€öm½¬ö+ŸVÖÇ-2ûÝÓ¥˜‡Zôöº_HÚTÛ©E:|«ÐãÈ'óP ‚­A·R0ˆÕàÑŸS§êûOï°*½¿ýøî†ÐüðéæÇÛ›» ï ^QÆL‰ôðÅSB‘ýæö=2¬³(£…r³­ì—¿ÜeÍÚ~-­‰¥x±ÿ"2µÚýv ElK”Zêû’$€Šm…m+Ç +¤´&† Ô´HѰ»EtQ÷ GX_”Ži¬\4ÁB(KÅQø§ó)®¨ÁµçÏrd×§¿÷¡÷5܇ÔùÔ§3¡Y–d^6‹¼Ã¬I`p)"<%N›-r~IM„Ë_¸ýn Ý£mâR ®/sÇý¢8p_•ö‹4¬’‡Áu›¸XŒŸki0@4H@"fþ@@À«ÊÚ¯\ÚcYm½5¬Fl0á¥(å¿åÀh IbV1µÇßÀà ÷IÑ™ø +‰ +O½ ©¡ð°w_® ™¡ûÆÜ†åÜñS‚%>•«½-• DZ¯<Ë…ã˜tÎ5kq¥}3ùƒÆ«¢]îÊ…ûü4bºÐGÅj¾hž +üm „ wÓ’ÓïlEŽ3{￟=÷¤«YqÐvÀFî³V„ wƒ¯íÝààp‡‡Hï·,Ɔ¶/ÜsÉÂmÞoÝ>«fÒ_o^MumûŸ3ž·Å‘Ž,«¼=Ö{ºi +ßלãl›}µfl¹Wõþ”Ö#oz¬W¤wU³ ‹OÈ$¤û¹ >ƒ&Äž/«­Yè_á&Ï™û +>œ¹_¨ØE›­;¬`ÁÕ’Ôß· íðh¼1Û¢Û6Ãl­ŽëÓ· °?Ûí¶¦Q¶¿ïz¸«‚^‘RÀôK;ƒÕý¶rëä…¤UT¡é:ÝoÛMOJø¢§{0#•äò$‹pÜù©_Š)¨ÒÕä‡Bä?þÙá7r2üò>™'€÷d +?æ˜B± ž³n06¦2™àýÌMÀxendstream endobj -1874 0 obj << +1903 0 obj << /Type /Page -/Contents 1875 0 R -/Resources 1873 0 R +/Contents 1904 0 R +/Resources 1902 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1857 0 R +/Parent 1907 0 R >> endobj -1876 0 obj << -/D [1874 0 R /XYZ 85.0394 794.5015 null] +1905 0 obj << +/D [1903 0 R /XYZ 85.0394 794.5015 null] >> endobj -1877 0 obj << -/D [1874 0 R /XYZ 85.0394 179.5067 null] +1906 0 obj << +/D [1903 0 R /XYZ 85.0394 179.5067 null] >> endobj -1873 0 obj << -/Font << /F37 791 0 R /F48 940 0 R /F23 726 0 R /F53 1017 0 R /F41 925 0 R /F21 702 0 R >> +1902 0 obj << +/Font << /F37 799 0 R /F48 950 0 R /F23 734 0 R /F53 1027 0 R /F41 935 0 R /F21 710 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1880 0 obj << +1910 0 obj << /Length 1912 /Filter /FlateDecode >> @@ -8215,83 +8351,87 @@ xÚ¥X[sÛº~ׯ  aWš½ Ná¸Æ~<ö¹$ø¥?'q•è`á?í4Nû*mUx‡S`ÎH†o;¯ïæ³÷Ÿn†ÈÇ'TÊ–¤TùšcØÊµ2üj@xM sŸ Sîû¼½<‹¹ÅÓanö†YÈó§ÌI—(u€B`b*©#¶mwB^Ëë£BÛòøÀ}5ãùK ÙF¬šDÞ¶¬ÏP- HeˆTËã8¶¹½û„ï»Óº½G¯WªI¯*Uëâ•À _¶iÇ0ˆìŠ¿üû·ÏÜü犀U:d=Üx~sƒÞÏ>Í?_ä÷•®ôÌpè;ü£áŠÌ£ž0+ëZ¥Óïjÿ¢ÊÞ¤Ý@Ä}è¨Ád‡Ý—Ûð”õ‡J‚ˆ„~·n\*Á³·kìý×ó‹nAεgßeý£×gH÷új´ÆÎÚ¾‘νÍ:ûÀtØÇ^ÙÝ ä¼› ®m0ÁOx8ûvŽáásϩɸ‹ -nþó{×mEÑÖý¦¿mò"oöçÓ1›ïK½©á|ÑŽ`$Œà1FPQ@å1ðy€‘Ü7—Óð·0šÁ©ìi8å˜îË[ôæ¢yb>N“YQVõb÷úÔŠÒ¡BS˜'l/Ó´HêzðUB,-ÚEÂû…Â'Qà· Xfº9«/Œ~¹¬p»~VƒÏÅ€p.Ù±Ææ¢Æf¿üú!H̨<Ö÷÷‹úvIÞœÕ':}ø ‹‡à­ Â0>N×»´,’—¡]$‘at‚‚ìzëaíbeX <ûnÞ™]™J»£ñS{ûd(M‘ñáÏe<ô ü9h2N2˜Þ~};µý¿p"5endstream +nþó{×mEÑÖý¦¿mò"oöçÓ1›ïK½©á|ÑŽ`$Œà1FPQ@å1ðy€‘Ü7—Óð·0šÁ©ìi8å˜îË[ôæ¢yb>N“YQVõb÷úÔŠÒ¡BS˜'l/Ó´HêzðUB,-ÚEÂû…Â'Qà· Xfº9«/Œ~¹¬p»~VƒÏÅ€p.Ù±Ææ¢Æf¿üú!H̨<Ö÷÷‹úvIÞœÕ':}ø ‹‡à­ Â0>N×»´,’—¡]$‘at‚‚ìzëaíbeX <ûnÞ™]™J»£ñS{ûd(M‘ñáÏe<ô ü9h2N2FOLo¿¾Úþ_nê".endstream endobj -1879 0 obj << +1909 0 obj << /Type /Page -/Contents 1880 0 R -/Resources 1878 0 R +/Contents 1910 0 R +/Resources 1908 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1857 0 R +/Parent 1907 0 R >> endobj -1881 0 obj << -/D [1879 0 R /XYZ 56.6929 794.5015 null] +1911 0 obj << +/D [1909 0 R /XYZ 56.6929 794.5015 null] >> endobj -1882 0 obj << -/D [1879 0 R /XYZ 56.6929 581.7741 null] +1912 0 obj << +/D [1909 0 R /XYZ 56.6929 581.7741 null] >> endobj -1883 0 obj << -/D [1879 0 R /XYZ 56.6929 460.6765 null] +1913 0 obj << +/D [1909 0 R /XYZ 56.6929 460.6765 null] >> endobj -1884 0 obj << -/D [1879 0 R /XYZ 56.6929 366.7195 null] +1914 0 obj << +/D [1909 0 R /XYZ 56.6929 366.7195 null] >> endobj -1885 0 obj << -/D [1879 0 R /XYZ 56.6929 293.4426 null] +1915 0 obj << +/D [1909 0 R /XYZ 56.6929 293.4426 null] >> endobj -646 0 obj << -/D [1879 0 R /XYZ 56.6929 247.3727 null] +654 0 obj << +/D [1909 0 R /XYZ 56.6929 247.3727 null] >> endobj -1886 0 obj << -/D [1879 0 R /XYZ 56.6929 211.2315 null] +1916 0 obj << +/D [1909 0 R /XYZ 56.6929 211.2315 null] >> endobj -1887 0 obj << -/D [1879 0 R /XYZ 56.6929 172.539 null] +1917 0 obj << +/D [1909 0 R /XYZ 56.6929 172.539 null] >> endobj -1888 0 obj << -/D [1879 0 R /XYZ 56.6929 96.3402 null] +1918 0 obj << +/D [1909 0 R /XYZ 56.6929 96.3402 null] >> endobj -1878 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R /F21 702 0 R /F53 1017 0 R /F39 885 0 R >> +1908 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F53 1027 0 R /F39 895 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1891 0 obj << -/Length 4197 +1921 0 obj << +/Length 4192 /Filter /FlateDecode >> stream -xÚÍ[[s㸱~÷¯ðÛ‘«F\\xOU¼3³'Yïdìœl*›Z¢,ÖJ¤F¤ìx}ú¢¨ÕlååÌ<j‚@£Ñýõ°¾Vð__»$R6¯³<Ž¥“ëÅöJ]?ûﯴô™ûNóa¯o¯¾ùÎf×y”§&½~\ Ær‘rN_?.ÿ9»ýôéãý‡»Ÿnæ&Q³o£›y¢Ôì‡Ûû¿Ýþ…iŸnr3»ýþãþL v2Ø-U³?þøðxó¯Ç?]}| Ü 9ÖÊ"+_®þù/u½Æÿt¥"›»äú~¨Hç¹¹Þ^ʼn’ØZOÙ\=\ý5 8xKŸNI ±.JœÉ&D`ôµÖQž$æHI¥ÖX’Á‡ï?ß}z¼ûñWCßôbS×s“EF©Œ:¯›¶“^vÐËèÈÆ:cŸª½™ÃJf?Új»Û”Øv³CWmªî_¬š=7våÚÛª~æßiš_»ämr;»ëx?~ ß›ŒvhË%·º†Ÿ‹¦~)÷òQ]lËöøýÝ'ás¹Üßh7+ÛºÀâ`ɼžy,«¨a|“ºÙKµ(¥UîÛ¸³©ý}]ÖL­~4êóa[Ö]Ë$\1=w]ÕÔí° ™Íž«—²~7± }‘Š“X„|n# ìpâwb·¯ÂÔ?Úuƒ"¡æa»-öo*›F™GÆ<Sv‹oöeÛl^"@äÕÿ°Æ4ÖV>ˆØ,¬5‘udŽ^>®Ë‰)¡‡N3/¥y11‡Ž£8Àø³J¸xè!Hɪd¥å—CõRlH9HFGב¯ò‚›`(«Â’æ/92 ³hÁ‰NÕ™H[m.˜²Ž\’ù <÷ÛâÚ'ª´ám'}nïÿq£Ðü¦À˜iœ»cÜf×gµ=#8…„ðD„ñ~J æ™ŽGÂÀ!Éá‰þ}Ê/‚¤•±æ"ªÅ.Ö#T³³@|»ë„ùŸf¶¬ÚݦxëWD‡o¹Áæ½hè¹îØììצ.'`Ì€à@Ž Îyº Ö’ùµ¬h†f+¬zžEÆ`õ -Æ„µ#£·OkâYqèÀÝW]ÑATÁ$>IoÕHfþ¡!À -\ Fºàc×ò5Î_3¬õãÅÇã1z¢»øY)S{†È‹Ð,òFzØo,T\ :†3qé!Ú ]5o.+XÍx ~°¯Á‘<øŽùbZOMœÕÔjBÕý D¸ €¬e¸À7lpH)˜@á-6Ðònôì‘Dá¹Øm;¥BZEn7O>èv¬Cyä\ÀBÜÀÄÀr+áŠ"œæ©ä'ÇÍC†ƒÃÚ˶j–ÂàÞƒIä´ƒï×EÓÖ¥lsGMq‡Í‹rH ŽA4ÄE~ãB˜1ÌcóÝ=?Èïê®ÜÃ̈æ£Íf|ú?‚°rÿÔ´4<ćnwè¸ÍCBä]Öå¾ß–¡ªN„P^$IP‘óÀ›Іƒ$;‡Ž6JÁ_x­[N»ŠD§^ëöSš SÚ$½ào`}âoz  *D¼×²Àók#" ) üX`6ð“â% ¾JóQþC¢›‰³Ùº@42±%$ÙmÇ`÷R-i€ÂÖŒŠÅ/¯E€[|ÉÉ@퉳IvPs« §;®|©šCË£ 6U`m°†wL™Þ›Äà­R{a?b"œ J˜·}­ºÅš—Ë©Åm¦.‚Pæ$È: —ô†UM1 -ûgÕ8ZÇÊR»+F9¡¾D -¾:Ê…‘ -þŸëP˜Ý#å¸Å£K'%.&Ò.cãîSÝÝ?ò_ ¡š–|ÞÇ_¿G‰³Ù±vU’v|þî½v`L¿åнÿõÙÄÁ -rrû™«¥¿CòFE*f9¿Ÿ¹l–œÄ\±ÅD £šØÇ“@ªÛ'J©HЖMß‚[ ± "ún>É >­EðI‡<ã|oCŽ©q¼N¦jø÷“L ép þŽ·|ÉïŠ'È”EÞ¹öRŸ -*o@ïÇ.Äï È|ðw>£m’ÄÌÐâØáÐ2vPŸ’5 -›-¤ %—Eh¸Éh)8ùììž Áø’p‹Z«ò•áÞ‰¶`«rp@ 2e4q|leø’ÉI³R÷³0îÒtoÆ1RÁ³-y‰‘fïçã)|¶7J†ØÖ§K2ゎŸã¸¨ê¦Ø®pegK;`þËÒ&ñ9Űƒ&|ƒéÉž²›Ùß>`…-ö¾¡ÛWe˱3Cù<6hÑ’ÂÀOÎx ÁfÎk]ÔÏloFtÉÓÑ‹É!â×}%çó„JN¢—S±Y¤MˆÀª&K˜& éCU/«(¾,vݼŠs ÝÆÙÿ¶¨ßø´¤«¶“Ñ„·Î9{±^bœMê%8(Ë~WzT)˜ìKH8­ Ân)†[7Bz.¥!Ï«Ç=°ËØ:ñ7øÝÓ<žã ªN&DàÑNËPw«©BrÒÏô1Îo‚Ã=Ö‘Ñ*êò¹èměү¼”æÝÈôóƒÒÚ1ó@Ꭽw°ÚÛŒðsd3÷M=Ë=@vó"þëËáÓ]1ë-À;Z²”®/•Í™Ø=O£,s^µçû3Úº'ÎÍ|¡”'¨„Þ…ƒqnž„Þyøü ?CÔÍ”Á"}Ne iÑqzâÛ*øS£´Œa”š=¡F¡žòû¤tP_hòÀDâA~æ.\m’/JWè\)öI LŠò0Ù¶,+…0'L)–¤P’W!0.«öß§ËàŒ.M@8™;vR÷T[$6ú(ü øž¾b³y™Ìw`™&¶ñ×ä;=ðÏc§ÏÅ€Y¤t@¤s:¦úêiP à•SÜ) K3ºøòyi Ì FŽƒn«mµ™RBã©„˜±"W£ø¸”ä'òä*¨ÊSX(ƒ)OF*J5Ð,Gý`ãÈð(ûÔŒ;ÊV ?(ްNÍÊïÐSûo‰ixöªQúdÛã^Ýšj'£KhìÕU$Ú±… ¼î™ë¾ØŒ²‚†ÌYûS¤Éäà[”‰rOw3Î#•¦—7ÓjÙÊ¡pT`s¸G;ì…¯E¤£ö\†˜)P•ÇsJêâ %åÊMF¹<)q -îï½ðTÛËß:æ™Õ)I!Mããm «çµøcq,„‰Fêp¢—Ål…¹Ÿ*ç ŠPŠCaaÝ«àÏ}©;È9‡(O8mÇ÷¬_UP"<‚ïÞÉÁ¨EÎøô5•“b_‚‘*ïíOß}îÏëü©íegR{mT¤mª/ßÎHÃôd-V$QÖ&óÙ4ä&A֟Αd²kö”ÉdæÜé@,”Ãæéÿã5¦>¶1xY*PìPõ+ÿ=[Ä.:vÓbp&=9u’>:'‡#Æ1~"…ÍÛìy ¬"ímWNÅþ:K#•…*(°N^uÉœö(÷Pœä‹SÉ7æÆ×ÇžëêWæð„‰ÿE4ÏfïïoøøŽÉXd$Lâ¢Q,üðã-u4³‡»ï¥õç|þK?õ PÞ@î‡x¢óÉNÚáX1þ(ÙIM(}½lò<Trwêuû˜a[4 íSËSÂ_±“c†Ý¾‚”J„‘Û(NM>­}¸õ´¥ó²òo…4ÈQA:±¸×r“ÓxxÇÍgXG•&× ñÃOÜgTìÄny>{:ȰTqù¹ã -GV÷æþþŒžŸO8ä+0€¹uF{d—[y¤“Þç’6•SÄÔgÖ_ñ˜Ûdb}6‘²ö«V“æ¢ð #¹Xn3}âÍGœ| ãZHc\¥NG÷t€KÏ6_Í^À²é«tžñ)ìñÝÀᵬ©[w`ÐÜ"éÁs"ž¬ -Ķ+öq*º9PÂ_Ÿ@_ÏS™þXØ 0,Q¡:?0y! ÆYÖËpæ¿'_lüùþfÓ¼Ž¿ë+]I 7+ÿá0ÇX¢Œž¥Ê=—tåðmlœ¤™;{Ì5 -SqEZ ?_ ‚+W)°QðCj&Lð“b¹ÚL„¦î•6|Vg1fÊáy-ÓLgN‰‰²4ä8ó¿Ÿ9aqý ËäÁ"ޟʳpPózn˜ôCèÐT`Úÿ&Y”¤yòõ¬`‚åž;êK5øÇ`ð_{Ž5‘w¯L®üz2ªødy ÄÞÓˆcB®Ú‚íÕdwI’O— ÑX8ûªQÇìl#ØDEµš[.~zÛR¿.ªQ¿0ÖÙ0L[Êk¾ßAcø7Ⱦp/—¸¬=[M"[÷[J2c%x¹þÈ]ô.'•( ;ËE:M/c¥1#°ÄÁËZÍŠëØ dÞ2]êƒÛ’«)B >ÿîMU®Ä:£‡NbôЃÁñÐÔ(øxƒX‰|ã¹Ì$šKic7sA¨6NŸKÿf5Q?ƒk¹?!÷(ÊÿiýmÀWÛÃVnÈÒð*•‡aÔ­g?=@rÝõ7/Îü „Å3;õ *üQÂý÷ýŸÄHÑ™þOŽŒ[A˜dsí™B k•YIqÊû'Á endstream +xÚÍ;]sã6’ïþ~;¹jÄàƒ$À«ºgf’õîÆ™{osµÙZ‚,V$R#Rö:¿þºÑ ¢¨Ñ¤öåì4› Ðhô7 y-à_^Û,ºH¯M‘&™Ùõb{%®ŸáÝW’ûÌC§ù°×÷Wßý Íu‘¹Ê¯Wƒ±l"¬•×ËÌn?}úxÿáî—›¹ÊÄìûäfž 1ûéöþo·%ܧ›BÍnüø€¹ÂN +»åbö§Ÿoþùøç«‘š!ÅRh$åËÕ?þ)®—@øŸ¯D¢ ›]¿ÂƒHdQ¨ëíUšé$Kµ˜ÍÕÃÕÇoý§SÈ´M2«Ì ”¼–2)²Lñ +’\+íyðáãÃûÏwŸï~¾ÇÕøoz¶‰ë¹2‰ÂøÎë¦í¸—ôR2Ñ©…ÎØ§joæ°’YIM[mw‡°ºjSuoôbÕì Ø¹=ÀÛª~¦ç÷lšæ·Ã®~«BÏî:$Œ_Ã7åfãZ·$¨k¨]4õ‹ÛóGu¹uíñû»OLçr¹¿‘væÚºÀâ`É´žyä,«¬a|•ÛÙKµp ¹}[u:׳¿¯]Mغ¡¶ô£>¶®îZBáŠ}»ëª¦n‡ýüfö\½¸úÝÄF€ô%"ÍRfò¹P°ÃY؉ݾŠS—Ô´ëYâÁÃv[îßhÞfEÈ*ô_4ð–Lü0¨4RŽölªÚ‘–Œ—Š(Ï.x­ Q›écá’E’.Ü£©5ÁÂE6.%Ŭ[;–Ͷ¬óRÒüºìŠ4Ôç‰{ l¡Ä |Øy3^ı(kÊM;ú® Óv[ΗnQîîÓKJ"E¯üÆ÷_/šMSÏ™·´¼#Y[ºMµ­:¤OËÎʆ¿ŒÖ3\;¾y]W‹5u_”­› iT’ªâ¢eRn¿V› ùôFÓ,ݪƒYb¥ƒï×eÓÖŽ·ˆ¨ó »Ãæà…bã†c qÑcظfŒ ¶ùîžZ4äwuçö03ZóÑf“}úoÂÜþ©iýðºÝ¡#˜†„ÈÛÕn_²o3(ª!„YEä¼á-”Ö†ƒÌœ³Ž:ÉÁ_©[N»ŠLæAêöS’ Sê,¿ào`yâoz ($´×¼@ókÃ,‹) < 4Ð ü${ _äÅ(‚!Ñͤf¶.ѩԂzÞnGÆî¥Zú i3v*¿½–ÑÜâ;HNv`Ôž(›$5×rº£áÜKÕZmSÚkxG˜éíÐY +Þ*×ö#•1‰¬„yÛת[¬i °œšÝfneN‚ü§ÃósIìË…$O§¤$%ðßT¸º|Ú„`í¥WÁ +Àû%%d™5ÇZóWoëĦÛféò’më6nAª¢¼ªøöL,Ît;¤óÍ4ÙJæÇ±ßÑ`º<`HÛ©`(‡à·H/êd®là]L\pÜ’ï¹iû²nW> +VAC‡S»,Q•È/¸vR¤½Yök»)ÀòdäÓA@lžçÇ’Bþ Ô’iȧö$;hš½1 ö¼@) þéñ3a(ªÔãä' "ѲÞ~w dW=ònE-èßSå½:>̯§4É 0ªüBX®²˜ßøç,E>l#}²6ɱväžX¶=kÐ’M¸‚3~†ËzŪ¦…ýÓb­ce©Ý¹E…QN¬/ù@_åˆà‚= Ã§:f÷ˆ9®DÑèœÄq‰‹~—¸û”'w÷ô*!¾¦ÅŸ÷ñÇïIfµ9–®ŠÓŽÏ?¼—”ék®8øßM‚AAJn?Sµôp^‰DQ-ç÷Ó!—6ÙIÌ•jLÄ0ªIC< ¨ú°}ò)5 }@¸eÓwóÁ-àÈyúŸxÖŽ"ø,Icžq>€×±ÅÔ8^ÇS5ôüÄSC:Ü‚¿£-_Ò»ò 2åCç#ïB®O‘W ÷cöø>ø€»ŸùmÇÌ qìphÉvø>Ž€š…` )ƒ£²ˆn2ÏÏ ìn,ýá<ÿÙ@o]aJIMµ¢)}u‚(.šéL'¢±cv0Åʲ£²!h}póéÙ=‚ñ¥·[Z¹W2÷–¥¡>ÈÁ1ÈäÑØñ‘–áKBo8ÍBLÝÏBv×OçÍ›²d© mÍÁÒìÃ|4EÈöFÉéútIf\Ð subÝአ./àlitÀâQÀ¿YÚÁd8U§ö4@¡ +ß`z²§GÒb5ûÛ¬°¥Á7tûʵ„`=S>¿‚fƒÍ) Tõ²Z€àób×Í+3±ÐmœýoËúNKºj;-Axk­Õë%Êêü¨^‚ƒïw.X•’С„„Ó²ÅA³ëXqë†QÏŽy^ƒÝ½Lµeƒß mZ°çøÂW§",ˆÖNòPw«©B²î9²ç7ÁâžëȨµ{.{ ªô;-¥y7R½Hü ´vL< ˜¹cG¬ :ÃôéÌ}SÏYsݼ°ÿúr¸Át—D ŽG”,¹ëKÅJs&v/òÄD{¾?#ý§¡{fíì!Ji‚ŠÉé]8(çÌã»`> įuf°ÈS)HZdšŸ8ĶŠþT Éc(!fOè†å­žû$d_é`"ñ‡ ߨËWÇä˧+þ\) I L‹ò0ÙÖ•‘”’‰c¢D8ËT,É‹»ê…ü÷é2(£Ë3`ޱÇNƒëžÂF"Ð@áÁÇ'ІŠÍæe2ßeªT§ß’ïô†žZy.4‰Ñ"“1ÑWO£­”âNºÜ€¡K/Ÿ—¦È jä8è¶ÚV æ‰JžÄŒ•w5‚ŽK=ÿ˜ŸTfp0……2ˆŠl$¢¾j +”RƒGÙ§Š hÜQÒbxðq„¶bæþµCO¾õDCÛ‹†  ‘m{uk_8Cc;¨®"úÐüûQBë n¹îËÍ(+hèÈÌÛ@ãþi29øþô„MàTrP](yÙo±ÎhÉC¤< ÀÅ8pýˆeN ”¦ç¤t´êëBÓÙ¬µr,¦8Õ.ÅìÀ'b >ñ¼ß“X|9TQŒð¾{LJ:¤>vÆ6TUNÊý}†ë¼·¿üð¹?± ó¸¶kÿHª»hbŠ6O§w1ÏäIuÏP¤ékØ“öF$Rç—Täqz¯/k’ÈkeB> (¾K`úó9@zžìš½ÏeŒúФ + bóüÿñóÝ(¼.•Ov,ކ•ÿ‘­ÎR»3 +«ò“3XË $´t<¢,YPÄ:L¾€@*âÞvn*ú—&O„‰uPÆ:yÙÅXªtÅrÆh1™|#jB…ì¹®~' +OˆøO´çföþþö§ïUA²$‹@d4І~¾õÕìáîG†þò‘N€ý£œ¡òÈþОˆ,Ü}²ŠÒvh#)*&[®J¦¯˜Mžè‚h@öaó‹R&MÌñÈlùYü>µ4uÉô•;>hØí+Hª˜…NÒ\ÓÒg o)¤\Š<•±½§‚aÙ¦CG¬ïµÔ2yÀy–b ïè•÷Ó/ÔŽê<ꓯêB_1ç +ì`WAŠ3õÕóõ41ÒžþÀ˜¯%Ì7ÏüÌÁ¶óMŒ‚® N“:ç“ÄÄÅU@¶]¹ç¸SøûUÉôõiôõ<‡LŒB²c™ˆ5ú àlèAA]½Œ‡bá;pôå&œòo6Íëø»¾Þ‰ä ³ +ÓqŒ'\ò̵î9'Ýȇÿ’J§YnìÙãdªTèÔ—Xj¨}-½%Ð|¡’®œxãÄM5ghêŽ,Ó†Nì4&Ä„9<¯yšéü)S‰ÉÓxÀö÷3ç,¶?g™<^Ä[T…‰Ã¼žft†ìÏîA¦0D¬Y^|m'NX§gOür N2ÿÆ[q#Q¤-›“«p’ž +?B£ ‚Ø{Úè€äN-(_í/ËŠéêS¦!$ë¯U~˨dÊôlÃæÉ×Öj‚ fö&4(' úuùRõ ™;‡i¿¦k~ŒðÉgêù.—Ögë¡Y¢Sm¿&%˜E%™µ£"}x•s(`Îß겉Ìss9ÛSâø®*îV¨6+*gS8`‚jÚ> endobj -1892 0 obj << -/D [1890 0 R /XYZ 85.0394 794.5015 null] +1922 0 obj << +/D [1920 0 R /XYZ 85.0394 794.5015 null] >> endobj -1893 0 obj << -/D [1890 0 R /XYZ 85.0394 751.6872 null] +1923 0 obj << +/D [1920 0 R /XYZ 85.0394 751.6872 null] >> endobj -1889 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F53 1017 0 R /F41 925 0 R >> +1919 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F53 1027 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1897 0 obj << +1926 0 obj << /Length 1971 /Filter /FlateDecode >> @@ -8304,50 +8444,50 @@ xÚ½XKs ]uI7¢Ý(ñ¬¢û-ìxM’o}À&à £áàý&ËÕ«ñÅ.XšˆoÏÄ•ø:­×ã —•kqÒÝðaÿ÷( ÖsC¶ºÎ“ºþþÊHß4˜Ø{ý£’„9ßE!´à°! Å †0JHvëÍ|ùáqñ°ZÜßyüé<ÐtA‚#(0ÇJËcs8¶œŠrË h4¹Q¹Ú:`‰e¶-ZVc š7KË8A×ÝšŽí`­Œ–‘® ÏJO_>>:†O»®£V¯el0ýxûÁXÄ…ÙkÃ8p»Ðóaȱ´@ßR˜Á½i›=+ ˜!íT}v¼Šœ÷m.ÿǰmI˜]!¯÷n_ËüíàëÝN«½B’ó%#(IÄõ%’gÉ~ED0Œ!–ƒ%?»;óò³€˜ar~Á†ƒÕPa=™oË n1{wïäø¤§6É1oήéew×µ—ß²Ù]®Y¤'åQ—*o€Êgáo$ §u%N«M}5×–<%àbIoúKÿ_Rðj€b ºqD®Ç§§ôzxœR‡ë|póƒÓNò®Ûê8óŒÍ¤¨ã5×:¥K߆´ BúŸ™¾oK€²µŽ\ŸLÐb~ -{AÈf†¬ë‰ç$?Úa¹ñ‚>dICß/ÿKÝåð|T‹ý¸kàeXoЕV»E[QIw%†—uâT²®ÇuÖh¢×þ¿…#RÿéêÉîÀô‡ÿÛ=ýƈ Aý5‚žƒ±uJÇ„|Ùö_àKßÿ üî¡Uendstream +{AÈf†¬ë‰ç$?Úa¹ñ‚>dICß/ÿKÝåð|T‹ý¸kàeXoЕV»E[QIw%†—uâT²®ÇuÖh¢×þ¿…#RÿéêÉîÀô‡ÿÛ=ýƈ Aý5‚žƒ±uJÇ„zÙö_àKßÿ ýF¡Wendstream endobj -1896 0 obj << +1925 0 obj << /Type /Page -/Contents 1897 0 R -/Resources 1895 0 R +/Contents 1926 0 R +/Resources 1924 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1894 0 R +/Parent 1907 0 R >> endobj -1898 0 obj << -/D [1896 0 R /XYZ 56.6929 794.5015 null] +1927 0 obj << +/D [1925 0 R /XYZ 56.6929 794.5015 null] >> endobj -1899 0 obj << -/D [1896 0 R /XYZ 56.6929 684.0716 null] +1928 0 obj << +/D [1925 0 R /XYZ 56.6929 684.0716 null] >> endobj -1900 0 obj << -/D [1896 0 R /XYZ 56.6929 572.8605 null] +1929 0 obj << +/D [1925 0 R /XYZ 56.6929 572.8605 null] >> endobj -1901 0 obj << -/D [1896 0 R /XYZ 56.6929 509.4701 null] +1930 0 obj << +/D [1925 0 R /XYZ 56.6929 509.4701 null] >> endobj -650 0 obj << -/D [1896 0 R /XYZ 56.6929 470.2699 null] +658 0 obj << +/D [1925 0 R /XYZ 56.6929 470.2699 null] >> endobj -1902 0 obj << -/D [1896 0 R /XYZ 56.6929 433.5878 null] +1931 0 obj << +/D [1925 0 R /XYZ 56.6929 433.5878 null] >> endobj -1903 0 obj << -/D [1896 0 R /XYZ 56.6929 401.47 null] +1932 0 obj << +/D [1925 0 R /XYZ 56.6929 401.47 null] >> endobj -1904 0 obj << -/D [1896 0 R /XYZ 56.6929 335.1577 null] +1933 0 obj << +/D [1925 0 R /XYZ 56.6929 335.1577 null] >> endobj -1905 0 obj << -/D [1896 0 R /XYZ 56.6929 244.1508 null] +1934 0 obj << +/D [1925 0 R /XYZ 56.6929 244.1508 null] >> endobj -1906 0 obj << -/D [1896 0 R /XYZ 56.6929 168.8052 null] +1935 0 obj << +/D [1925 0 R /XYZ 56.6929 168.8052 null] >> endobj -1895 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R /F21 702 0 R /F39 885 0 R /F53 1017 0 R /F55 1025 0 R >> +1924 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F39 895 0 R /F53 1027 0 R /F55 1035 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1909 0 obj << +1938 0 obj << /Length 1658 /Filter /FlateDecode >> @@ -8363,47 +8503,47 @@ a ¦×ã)]»Ž‘VÊÀí,1ͨ1)À«»h·uB¶q¸»+°#Ii«€Îâ!©÷ÏqlXz¼”âmŒš¡Ñ+ëþ•c¨ÄÍ>‹ìÑI$.ž”òVLK¿rS¤æ­Sø¨Šl¾çý–Ý_Yµ®Ðq¢˜ŒÇvG|5ùtü”ÝÙ{ÚJmÃÿ”…n¼®õÂèÑH¹fÞ(òE3º¼9·J"']fœ*È;ïNϵŠ™;æuRl’¼«#B+¥»ôèB£€">1î.άF&…êÎ"ÊùÏê¸ÀÑQuÝYÉ'1‰Úiž¾ÿtw> endobj -1910 0 obj << -/D [1908 0 R /XYZ 85.0394 794.5015 null] +1939 0 obj << +/D [1937 0 R /XYZ 85.0394 794.5015 null] >> endobj -1911 0 obj << -/D [1908 0 R /XYZ 85.0394 575.4191 null] +1940 0 obj << +/D [1937 0 R /XYZ 85.0394 575.4191 null] >> endobj -1912 0 obj << -/D [1908 0 R /XYZ 85.0394 427.1073 null] +1941 0 obj << +/D [1937 0 R /XYZ 85.0394 427.1073 null] >> endobj -1913 0 obj << -/D [1908 0 R /XYZ 85.0394 329.3834 null] +1942 0 obj << +/D [1937 0 R /XYZ 85.0394 329.3834 null] >> endobj -1914 0 obj << -/D [1908 0 R /XYZ 85.0394 262.8864 null] +1943 0 obj << +/D [1937 0 R /XYZ 85.0394 262.8864 null] >> endobj -1915 0 obj << -/D [1908 0 R /XYZ 85.0394 196.3893 null] +1944 0 obj << +/D [1937 0 R /XYZ 85.0394 196.3893 null] >> endobj -654 0 obj << -/D [1908 0 R /XYZ 85.0394 155.0304 null] +662 0 obj << +/D [1937 0 R /XYZ 85.0394 155.0304 null] >> endobj -1916 0 obj << -/D [1908 0 R /XYZ 85.0394 117.4002 null] +1945 0 obj << +/D [1937 0 R /XYZ 85.0394 117.4002 null] >> endobj -1917 0 obj << -/D [1908 0 R /XYZ 85.0394 84.3344 null] +1946 0 obj << +/D [1937 0 R /XYZ 85.0394 84.3344 null] >> endobj -1907 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F55 1025 0 R /F23 726 0 R /F41 925 0 R /F48 940 0 R /F39 885 0 R >> +1936 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F55 1035 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F39 895 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1920 0 obj << +1949 0 obj << /Length 2406 /Filter /FlateDecode >> @@ -8417,32 +8557,32 @@ H :ÍS½--ú){É=6]´põ9ØíncUm…2hÔ¬N±,˜o±HÉÖæx¤¦{7¶±ß~ƒEΚø ‰ ðœ6ƒ>ê¸t(c‹`&U‰P{wjÏÀN•œËbyW5 õsÂ|±&¹)†ìåLw|­ÄÌÖºÏ1öÑ»I¼hå¥]eb{¹‹yHÊ7)­õXØp¯—W¦*‚žÃ-«â¯ HX†Ž˜€<”(ßé¿L¾ì²ø—ÜZ“biÍ>`Ô%¼ài13‘H‘8–g’{uÂDʘÈÓ>Ke¼õ K °ì«?f„­Ígù°)*Wtf¶ }ª7­ínW«lóæS]éT¯Û¢®š½›-ÆååV—Ù®4«¯ ª›S,wº9`ÔMŸåçJ¦ÌÝÐo$Ýó{Ä€ÃÚÅ((«9š}ßïØÕú¡¥h°TÔ’TØâ[tì;gÝ÷J¸ÂE”f;›åPynNØ1HAV=ÖW?¦·ïÇŸôXïph|0Èì E¸[¦QØy&1¾wkí*gõªoõÊZ½ò$ »!Ý“6D.ò›wÝ:’ÙcQí›?›ma¾jÍá[ÎY›iá…}™Öc†iÀ¤»lº£-탴yeÞ'ì»=jî*!LÐ3@=Ðqcw cë/á˜-¢8Úÿ»Â+[c’ò„Ÿ”Êa¥òo.œ¤4•žX“Dzyþ¸].»¢ÎHEŽýG*$Ñl¤¢Ýüÿýÿéîßâ(_JŽd#K‹•Jï1~¨gûOë¡ìÉŒI2endstream +ÝPWrAÁêJ.˜»·ÆÝuÝ4Åci)u˜;=Ø>9š}ßïØÕú¡¥h°TÔ’TØâ[tì;gÝ÷J¸ÂE”f;›åPynNØ1HAV=ÖW?¦·ïÇŸôXïph|0Èì E¸[¦QØy&1¾wkí*gõªoõÊZ½ò$ »!Ý“6D.ò›wÝ:’ÙcQí›?›ma¾jÍá[ÎY›iá…}™Öc†iÀ¤»lº£-탴yeÞ'ì»=jî*!LÐ3@=Ðqcw cë/á˜-¢8Úÿ»Â+[c’ò„Ÿ”Êa¥òo.œ¤4•žX“Dzyþ¸].»¢ÎHEŽýG*$Ñl¤¢Ýüÿýÿéîßâ(_JŽd#K‹•Jï±èPÏöŸÖCÙÿÉäI4endstream endobj -1919 0 obj << +1948 0 obj << /Type /Page -/Contents 1920 0 R -/Resources 1918 0 R +/Contents 1949 0 R +/Resources 1947 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1894 0 R +/Parent 1907 0 R >> endobj -1921 0 obj << -/D [1919 0 R /XYZ 56.6929 794.5015 null] +1950 0 obj << +/D [1948 0 R /XYZ 56.6929 794.5015 null] >> endobj -1922 0 obj << -/D [1919 0 R /XYZ 56.6929 748.122 null] +1951 0 obj << +/D [1948 0 R /XYZ 56.6929 748.122 null] >> endobj -1923 0 obj << -/D [1919 0 R /XYZ 56.6929 665.5133 null] +1952 0 obj << +/D [1948 0 R /XYZ 56.6929 665.5133 null] >> endobj -1924 0 obj << -/D [1919 0 R /XYZ 56.6929 579.9397 null] +1953 0 obj << +/D [1948 0 R /XYZ 56.6929 579.9397 null] >> endobj -1918 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F41 925 0 R /F53 1017 0 R /F23 726 0 R /F55 1025 0 R >> +1947 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F41 935 0 R /F53 1027 0 R /F23 734 0 R /F55 1035 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1927 0 obj << +1956 0 obj << /Length 2100 /Filter /FlateDecode >> @@ -8452,50 +8592,50 @@ xÚ­Y_ çíŠËK¾—9IC.I ʾ‚=Ò—GÉ qìúžkx(–µª_ÔtZu «^^!êòêPÛurq6of• èº*UìÒ˜ÂÁäõ‘£eYI;[V1\r' =Ãm²WÙ-9Šn‚Èl=´“ûm^×"ŽpÕ©_Á¼4ôk޳‰=ˆÑÇÙç›EêÕ`åB›ŠT¥„ùXçëR9Qç³fKÓnd$p~©C…wSU4Ó$HÍc´Üæe0•5‡aêI®¤Ñ³\H3õ)+™VI ¸Ê#wè>‰pû?½¿7#NS?F!1ûûìãÿv&–(C a¤ï Sê³ A >OM×!F_矟nzÂ#d“})m%<{«!Š-ŒÞƒ·Wû&?l›2DU3`ذñÔ’ÐBwˆ1îû–Ê>"®I§ì.È8‹ù¹‡ÚlE‰™®ó$ýÛâ½­¨šª*~ nÞÊjWC,ŸÔ;14 òKSu†ÄWãõV`†]ç¥+ÔZ*ö1˜5´Õ'ï9&(&Â%#ö-׺>.|ñqƒ¾¶96¯ó?}˜Í$"ìèÂò"+aITyÓ¼í|¼ £ORáÄzf…»XY]û2IŠ„p;~3F{e;Zy8Cù™ð¶¨YÙÚÇšu0޳‰aHm„“\×7å·~ xè±Tm{Oˆ\sw ±‡2®Ú.å«_ø·Ö2­o2…ü Ë5”·\­åÙxx†T©o*ºîŃßïúgÒ2~½)l!_eñƒîW‘î°Hy‚YŠÆ“ÙýÓã—ùãç©§=¹’À=`§ˆGiÔw9ÓbÙfdoJDQ…®gªüÑYºýî*xËìò¥TÅOiÚ5¨yš¼ ÈIÜ®(—'ß Ý1u×Cyðؘ)UâêàrÒ÷2+êªMÓ&€úäÞçPÛo®ÃÂÁ|öøáØ·)V¾\g‹c˜AÁ“5VíºUîz¨§.¶êb§Öe”jŸõÏÎÚz›/DŠ"JèõœÒ!rW›ç)Åi”véƒ÷ÒJDÊ}Ù£×û³ÅQr]´–è\¶^bÐ(!xO¸™, QVfÌvo0XìßvMµÞg»î)aªs)ý‰Ð=|àÁ+Ô$8Ø·jå P@ì”ÆÄŸ+û½F ²µ¨³=ÔÙþÅJ¦[+=X™ Ÿf£Ocn›j( D”Ò¾÷*¯*åUæžVûªÐKg#íj) Ƴ‘¾ÇeÁâ‘ö?ê)GÁƒñƒy*Öã|¥ÜVw7föAÅ6+Ãr·ãçÑ}â»4-'q]š °éÁ]•fG0€†+s$ª-ë¼É_/ß|ª+{Ïà6Fþç_Ž÷]1¨è\ìõ¯’0°4%N(¥1!ôTôö7„sÙÿ(l7wendstream +QƈSg·¯šjá‚Às‚ñé>{Oˆ\sw ±‡2®Ú.å«_ø·Ö2­o2…ü Ë5”·\­åÙxx†T©o*ºîŃßïúgÒ2~½)l!_eñƒîW‘î°Hy‚YŠÆ“ÙýÓã—ùãç©§=¹’À=`§ˆGiÔw9ÓbÙfdoJDQ…®gªüÑYºýî*xËìò¥TÅOiÚ5¨yš¼ ÈIÜ®(—'ß Ý1u×Cyðؘ)UâêàrÒ÷2+êªMÓ&€úäÞçPÛo®ÃÂÁ|öøáØ·)V¾\g‹c˜AÁ“5VíºUîz¨§.¶êb§Öe”jŸõÏÎÚz›/DŠ"JèõœÒ!rW›ç)Åi”véƒ÷ÒJDÊ}Ù£×û³ÅQr]´–è\¶^bÐ(!xO¸™, QVfÌvo0XìßvMµÞg»î)aªs)ý‰Ð=|àÁ+Ô$8Ø·jå P@ì”ÆÄŸ+û½F ²µ¨³=ÔÙþÅJ¦[+=X™ Ÿf£Ocn›j( D”Ò¾÷*¯*åUæžVûªÐKg#íj) Ƴ‘¾ÇeÁâ‘ö?ê)GÁƒñƒy*Öã|¥ÜVw7föAÅ6+Ãr·ãçÑ}â»4-'q]š °éÁ]•fG0€†+s$ª-ë¼É_/ß|ª+{Ïà6Fþç_Ž÷]1¨è\ìõ¯’0°4%N(¥1!üTôö7„sÙÿ(Ä7yendstream endobj -1926 0 obj << +1955 0 obj << /Type /Page -/Contents 1927 0 R -/Resources 1925 0 R +/Contents 1956 0 R +/Resources 1954 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1894 0 R +/Parent 1966 0 R >> endobj -1928 0 obj << -/D [1926 0 R /XYZ 85.0394 794.5015 null] +1957 0 obj << +/D [1955 0 R /XYZ 85.0394 794.5015 null] >> endobj -1929 0 obj << -/D [1926 0 R /XYZ 85.0394 752.0811 null] +1958 0 obj << +/D [1955 0 R /XYZ 85.0394 752.0811 null] >> endobj -1930 0 obj << -/D [1926 0 R /XYZ 85.0394 529.0618 null] +1959 0 obj << +/D [1955 0 R /XYZ 85.0394 529.0618 null] >> endobj -1931 0 obj << -/D [1926 0 R /XYZ 85.0394 453.6936 null] +1960 0 obj << +/D [1955 0 R /XYZ 85.0394 453.6936 null] >> endobj -658 0 obj << -/D [1926 0 R /XYZ 85.0394 414.4777 null] +666 0 obj << +/D [1955 0 R /XYZ 85.0394 414.4777 null] >> endobj -1932 0 obj << -/D [1926 0 R /XYZ 85.0394 377.7886 null] +1961 0 obj << +/D [1955 0 R /XYZ 85.0394 377.7886 null] >> endobj -1933 0 obj << -/D [1926 0 R /XYZ 85.0394 345.6639 null] +1962 0 obj << +/D [1955 0 R /XYZ 85.0394 345.6639 null] >> endobj -1934 0 obj << -/D [1926 0 R /XYZ 85.0394 279.329 null] +1963 0 obj << +/D [1955 0 R /XYZ 85.0394 279.329 null] >> endobj -1935 0 obj << -/D [1926 0 R /XYZ 85.0394 194.9705 null] +1964 0 obj << +/D [1955 0 R /XYZ 85.0394 194.9705 null] >> endobj -1936 0 obj << -/D [1926 0 R /XYZ 85.0394 119.6023 null] +1965 0 obj << +/D [1955 0 R /XYZ 85.0394 119.6023 null] >> endobj -1925 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F14 729 0 R /F39 885 0 R /F53 1017 0 R /F55 1025 0 R >> +1954 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R /F39 895 0 R /F53 1027 0 R /F55 1035 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1939 0 obj << +1969 0 obj << /Length 2835 /Filter /FlateDecode >> @@ -8510,24 +8650,24 @@ xÚ¥Z_s LJ$ä—«ªiòå l¬i €M*™ÚÜéüÙè?ަœ ÌÁ|;{0#üús9æ7x,¿/èP¤ç.›õ>)pX™£±½›-;«;¡T^(€{ÌyÍÆ(nw±øÝíë¶^ÖåÙâwD¬¾ô=–k°ðuƒ[Û¼)z+:™øƒÂ˜)*`õ¤©.<8=€¸rŸ±$Yœ§Šáƒ!|v/fÂyÇÐŒ`àXXº*ÈçYâ‡`!¥ÉžéáLîD3ø0Ñ ÚP7Ì–kPìÚr æžÈ€ kÃ'~uÅ›U€ÄÛF÷\OwGhuy­Ùc™©%©°5]w °KZF[<*ÿ ?šÃr™CÕº±ÝŠä’õ:¨ûµ(cÁûKYçį·«üõ4£€š%‰’qá:Ô€t¾Ë€ËؗΈeöå“A¥UÌa˜'T†Ù¤nQÚ*7UWKÌIú•€Üõ¹‰&ôg¸Å©Umù˜MO“}¿+Zž ¼ô„`¥\ ëò7 ¬kÔiDiêŸ< 9p €°0±wú$Ü_‡lÕ˜¡ö _,ss„Ò¾«Þ/ôO=<¥få¨Ç‹¦sïç:³µ°™©v¬‚Ž7BÆÇX:dGÛ%¢tÒ{÷ðO5²gš72ÂóÄÔšåK¶Ï–­ $€C r­&XÒ˜[Èk<)ÜÌ­²–ˆêGÝ>wJ·`¤¨À(²•/ÊxvEÏ8 ›=˜Mf%~`¤=Õ¥þùAòî‰Na5üDrn-¬pÞ9ð^l»b×9G“ïésì2|¼pž–GŸx"Çœs>âÆÄ›æâÃQÓîójÓ¾œÞ˜øh}D¬s"—ÿ«Ü5"Ž\ÁŽBýÍ: ûF&3b/NF?ݸh÷÷žØþÞ3H¥ F6ÝEÉÜ‹>ÁLí.µëóй:Ó -2å{Ùò°'Ž­ýð%#ƒ©èyq•ëW9Åî°‡2·†Ó¥ZpŸž·¨Y,.S>{ýîIJØ×ùžÀæ±[·–dö\”EûîÏf˜¯Z£|â ‘\ r*Ï`Ì0H¶ºª®§í<³çÕrÿ¾£0©Éžÿ \-¼Ðȯh2¶þzña§Ì_ó“"BA©+ ¨“ÊbN¥òŸÓTÍJzbaáÅ«üù°ÙtocFªàÜßž@¦ ÿ`d@*6±‡óÿ]Jÿ÷7Q¾t®‰ `ql…ÒûƒÛâôœé/XNeÿïN¥Qendstream +2å{Ùò°'Ž­ýð%#ƒ©èyq•ëW9Åî°‡2·†Ó¥ZpŸž·¨Y,.S>{ýîIJØ×ùžÀæ±[·–dö\”EûîÏf˜¯Z£|â ‘\ r*Ï`Ì0H¶ºª®§í<³çÕrÿ¾£0©Éžÿ \-¼Ðȯh2¶þzña§Ì_ó“"BA©+ ¨“ÊbN¥òŸÓTÍJzbaáÅ«üù°ÙtocFªàÜßž@¦ ÿ`d@*6±‡óÿ]Jÿ÷7Q¾t®‰ `ql…ÒûƒÃ:=gú –SÙÿ殮Sendstream endobj -1938 0 obj << +1968 0 obj << /Type /Page -/Contents 1939 0 R -/Resources 1937 0 R +/Contents 1969 0 R +/Resources 1967 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1894 0 R +/Parent 1966 0 R >> endobj -1940 0 obj << -/D [1938 0 R /XYZ 56.6929 794.5015 null] +1970 0 obj << +/D [1968 0 R /XYZ 56.6929 794.5015 null] >> endobj -1937 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F55 1025 0 R /F41 925 0 R >> +1967 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1943 0 obj << -/Length 2184 +1973 0 obj << +/Length 2183 /Filter /FlateDecode >> stream @@ -8541,47 +8681,47 @@ Zì¬ ¶Äm-n˜\A¥9îh„Ÿi=(ä=Ì]%ò~ÐÙ`{>µÕròiþy8XCTÙc¡«¹®ÝB—WkB*»l’9¥®nfö‹„´ÓuVdà‘IízÞ¯êAÛKë”·I±ƒšäsÎyð§ @'Ú:þõݵáÓ¼ôð‹ 8j üev"bÿ;»è˜8=dç70• ‰ˆÄ~òmñáó×aÃÞ@»¾-”Mó— Z'Û»^C«Qnël·Þ‹…ÊqWP"h[¥Я‡²€!—¹Šë(œÞmˆg0Lô¨&à\±×ç쨆±Y™¯xf½®©ÛTW—e>\ ç/E¹©²êx”„Ð#’ SǘžIRGwÈ´5½Ã-t”L4ѽgq:eº¸¥òž^׉ïArçVKs2v8‹HÑý˜—'•/é… »œÔrL='Á™ËЯC¯^n_¹¬ú o¼@WˆÑv#–yƒ3ôIí¯³1=qŽ_uþ5«Ai -…asœ r¬Ê$€q5Kò~m t œˆ“)¹ÃœðøW¬öÙ‹0£Ž'6çʽÇ=ĉ§mÚÕÖ#ë0¶ÐÔëT=õÄ7f'€WÀ×ɶî‹p PÜ6 -׺]=õ*íøç0Qå¯ÏrÞÙÞKH(fòhNûPÀ"I°C©JòÚû„&¢Çò> Çe­‡R˜6«×4±+]šäfö!!„îú>Å‚\ý;”§Vá¶>þß?wí¿éBV¡Bì¿ó~.m¾ïCb•ÒÇ#„«Þþ0vªû<¥ø¾endstream +…asœ r¬Ê$€q5Kò~m t œˆ“)¹ÃœðøW¬öÙ‹0£Ž'6çʽÇ=ĉ§mÚÕÖ#ë0¶ÐÔëT=õÄ7f'€WÀ×ɶî‹p PÜ6 -׺]=õ*íøç0Qå¯ÏrÞÙÞKH(fòhNûPÀ"I°C©JòÚû„&¢Çò> Çe­‡R˜6«×4±+]šäfö!!„îú>Å‚\ý;”§Vá¶>þß?wí¿éBV¡Bì¿ó~.m¾ïCb•ÒÇ#§tÛÆNuÿ/<ýøÀendstream endobj -1942 0 obj << +1972 0 obj << /Type /Page -/Contents 1943 0 R -/Resources 1941 0 R +/Contents 1973 0 R +/Resources 1971 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1952 0 R +/Parent 1966 0 R >> endobj -1944 0 obj << -/D [1942 0 R /XYZ 85.0394 794.5015 null] +1974 0 obj << +/D [1972 0 R /XYZ 85.0394 794.5015 null] >> endobj -1945 0 obj << -/D [1942 0 R /XYZ 85.0394 752.3199 null] +1975 0 obj << +/D [1972 0 R /XYZ 85.0394 752.3199 null] >> endobj -1946 0 obj << -/D [1942 0 R /XYZ 85.0394 504.8188 null] +1976 0 obj << +/D [1972 0 R /XYZ 85.0394 504.8188 null] >> endobj -1947 0 obj << -/D [1942 0 R /XYZ 85.0394 359.3246 null] +1977 0 obj << +/D [1972 0 R /XYZ 85.0394 359.3246 null] >> endobj -1948 0 obj << -/D [1942 0 R /XYZ 85.0394 298.3625 null] +1978 0 obj << +/D [1972 0 R /XYZ 85.0394 298.3625 null] >> endobj -662 0 obj << -/D [1942 0 R /XYZ 85.0394 260.8495 null] +670 0 obj << +/D [1972 0 R /XYZ 85.0394 260.8495 null] >> endobj -1949 0 obj << -/D [1942 0 R /XYZ 85.0394 224.9084 null] +1979 0 obj << +/D [1972 0 R /XYZ 85.0394 224.9084 null] >> endobj -1950 0 obj << -/D [1942 0 R /XYZ 85.0394 193.5316 null] +1980 0 obj << +/D [1972 0 R /XYZ 85.0394 193.5316 null] >> endobj -1951 0 obj << -/D [1942 0 R /XYZ 85.0394 129.6476 null] +1981 0 obj << +/D [1972 0 R /XYZ 85.0394 129.6476 null] >> endobj -1941 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F14 729 0 R /F48 940 0 R /F39 885 0 R /F53 1017 0 R >> +1971 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R /F48 950 0 R /F39 895 0 R /F53 1027 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1955 0 obj << +1984 0 obj << /Length 3093 /Filter /FlateDecode >> @@ -8597,29 +8737,29 @@ ZDh ˜}ˆ|gW­ï³PÁ 6“ÝaQyœ½e0¯¦­0Œ{5èyÞcçûR6Å‘%pš¦\´rÉ”kz>0UÏ%]«À[SוßÌùÐ0U±´§ïXž×ù‚[¿4‹mb÷ LBuÔeéTÂ÷Úöo !°Õëè”(@|Á°†³m·iIÖÀ§õ_"þP´/9Y{ð}‹@5*t]eˆÃýEþXw5}h.Wt\ñ}Ä¡ûX»LšÏ(ÐDlŒ •Üäm(rà²ÏmhͼûŒŸÌG-í(˜&ÀDjäçÇyüÀ®C¾|ó‰» ÷÷yË­´jÔJï™Õ)]á0á^`XŸ"ëS´Y#BsÀœp‚{¤K`§E€BOÜÅ;½ÿöÏ´¥§†C&Pò2ÿI —û[I‡ø Ó‰;/N~¦çÂwWti—¾mw᣻¿öÏuÑt·Ï9ÃèxͲ „Ï%ÀK½ ÷®G}u*'ƒJU å×É”ÜC:ž‘’OÈ7ç mŸÂæ ù YȰÒÎb) ®<Å\‡tȵL"˲{÷¡–fú06\hÛ}¡Í¥'ÎQZF ¡¾~6чºiÊ*À oÖpѼ·‚ƒê*Áï£Ý÷ èÓÚâÏŸ.§@jÝý -æ1¬t+ä)…Ú|èÚØUhÓ#²Í_ŽÑÀV$Sã2>â~ä¯|oëì>Í;Øó¶„š´\¿2œÑ]óoÔ?'dðN=#ŽÈÙa°|…â¾\ÐËþg4vÿ#×¼ÿ–Ɔ†–ï6Ï´"‰B›úa—¶1þk¨D÷K’ÿûG_ûŸ·šYväû©J!a83S(dp¹Co埇òþ_0¥Åendstream +æ1¬t+ä)…Ú|èÚØUhÓ#²Í_ŽÑÀV$Sã2>â~ä¯|oëì>Í;Øó¶„š´\¿2œÑ]óoÔ?'dðN=#ŽÈÙa°|…â¾\ÐËþg4vÿ#×¼ÿ–Ɔ†–ï6Ï´"‰B›úa—¶1þk¨D÷K’ÿûG_ûŸ·šYväû©J!a83S(dÐÅ¡·òÏÃyÿ/0w¥Çendstream endobj -1954 0 obj << +1983 0 obj << /Type /Page -/Contents 1955 0 R -/Resources 1953 0 R +/Contents 1984 0 R +/Resources 1982 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1952 0 R +/Parent 1966 0 R >> endobj -1956 0 obj << -/D [1954 0 R /XYZ 56.6929 794.5015 null] +1985 0 obj << +/D [1983 0 R /XYZ 56.6929 794.5015 null] >> endobj -1957 0 obj << -/D [1954 0 R /XYZ 56.6929 752.112 null] +1986 0 obj << +/D [1983 0 R /XYZ 56.6929 752.112 null] >> endobj -1958 0 obj << -/D [1954 0 R /XYZ 56.6929 665.106 null] +1987 0 obj << +/D [1983 0 R /XYZ 56.6929 665.106 null] >> endobj -1953 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F55 1025 0 R >> +1982 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F55 1035 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1961 0 obj << +1990 0 obj << /Length 2978 /Filter /FlateDecode >> @@ -8633,718 +8773,739 @@ xÚ¥ZK 5‚']R‚ðy¸/þ¶L]ÒèwÖ72žÜåÉ`B[êõv2RE\„Qþ{6RõQÓ‘ªC™HUç 2êY},Ë겺!$bžµ5›Ÿ„$PÔKå3÷ài Y£aÆäÃŒ Þ¾÷8—NùwC]tÉžÓD{9{wå¤lÉŒg*úý0Ñtyl7‡ãkB2å üDÎ믚Ö_‡2úûx-Ó€Šêí‰,ƒ'$ÂØYþh„?O‡Ð çHú Ê„u)„L8%މ«¶¡ALRÛ)ö:ï–Æ]!©ãÒlÛ´#†þsÚq^µ¡¡3iG‚i7¤^¯'·Р7>žuXÛÍ”†x“³ç©5’óTL¥}Áù‰#q%“í£fìË¡Œ}†Kê(Œ¢èÊ’4²dwêw¡Kþ‚7¡ÀHphŠS^/éÆIïgmFÏææiÝu’É:€êÑH‚ šrBÛ²P›¬i»k¦Hò`eŒT˜"µ½L°ªL±ËOÄÛ²…Š]ÎB%ι+‘c_$°¾+I,S"‘çËcì³jPAmN`þ;z¥]# wI(¼ @™‹bê1—Éðt]¥$Ȩ®?Ø5›š6¼¶Ó”ÍØýĮܗPqMš¢HÁåkyÅÕõQӦءŒ)Gï¡ãÂë‰:/ž.SÙ4ÃÅué•Ùdv¾e;Ýks®BÅ• EV ùxY+9wVVy¹¶ßàè~Ï&k¾éŽØ$†¥m}Úå~²…{žv;ôètâ;äÙíôP3nÇ¡ŒÛ¹Hš4ã$Šæ—t ‘%½‡±R‰¿ä§cé*º¦…óß`!æ_h®ëýaW`à˜”Oñ­ó飦%Ò¡ŒDž®Ö »â©ØÝ[ŠнYÎ:ÔkÃ{K¡bŸ5¨ÚšAfž«ÓãcWíΦe¦¤ÎúJÕGÍÈÌ¡ŒÌ¾]X‘ ¥„ÌnvIYÒ³¢NœVþ’«ºÿeå§ûŸº*GfVîÚ#5l¢`>lï¾¥›.g}® Â$dZ–‚Á`WjÖ>jF–ed)Çì…Iª]&Ðd»ËZ‡CÞ-ÁPfëP#œyæ'¢0Lù¬½·o—  \ÇÁÝý»7’(ð¯ H¥OÒH4¦Š¤Çò©¨ˆ¶-¾R£¨Öu޾¸-pÞÿBÝyÖØY°±rñ ˆ4†¤&M‚–xóÁ¢s-Ã-¿™åve·Dq)hHqþÝ&B…ªùÁGÓÎr*g9ȇWgKkZÉ7I÷YÐYdwÈ­ˆgDOÿK"çó+’8ƒfþ#aAÆ"ÿy­ -‡”™>ê]~ÍQi¨…³¬u KÞü«,Ð#“±Çܯ“âËÆ…×Éß Ù©hŸU/.Rwû&]n×W.g,œúGähÑxFÎΈþï+ÿ—%¡LÓ‰ ¹8\ÍS(?Γ!ëÝÿš.yÿgH,endstream +‡”™>ê]~ÍQi¨…³¬u KÞü«,Ð#“±Çܯ“âËÆ…×Éß Ù©hŸU/.Rwû&]n×W.g,œúGähÑxFÎΈþï+ÿ—%¡LÓ‰ ¹8\ÍS(?ðCÖ»ÿ5]òþ?gvH.endstream endobj -1960 0 obj << -/Type /Page -/Contents 1961 0 R -/Resources 1959 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1952 0 R ->> endobj -1962 0 obj << -/D [1960 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1959 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F21 702 0 R /F55 1025 0 R /F41 925 0 R /F53 1017 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1965 0 obj << -/Length 1813 -/Filter /FlateDecode ->> -stream -xÚ¥XKsÛ6¾ëWðÒ©4 Q¼ˆÇQ±•ÄMb»‘2M'É–(‹Dº&åDùõ]EŠˆ“iG.ÁÅ>>ì "†‰„¦:’š£“$ZîF8º…o/FÄñÄž)îr=[Œ~{Îd¤‘TD‹uG–BX)-VÆÏD€Ç—Ó7³óøìåììÕÙÕåóIL¤`|<½¾ž]ž_¼ŸÄ4ÁÀÌßL/ßM_۵뉦ãé‹Ù|òiñûh¶h ëO03Vý3úð G+ðá÷FL«$ú/­i´ñ„¡„3æW¶£ùèV`çk³5OJ(QÌ8R ? A’`’‰F‚QÖBFI2Ïe ‹§§Ž -‰¤ ,ê -¨ôL•¬£RR$9=•n²b3ªÇ·Y‘ݧu^ÜÚ÷Ô>.ç³3fÉå&Ís•Õ–¨7™%®®¢ÆWïöý#Æ,u¢J·+ÝnBïÍ®lY6ÏUå‹•%V¥}eݳ23@E -©DF1!H' müq’Mô $›Å5¼6D^TÙroyìÊ*Ûf·@YThpîT%ˆb¢pô®GŽÞs»¿•EÑmvªZS$„Ô«öLÕÝÐ ÛS½Ø8œþ†^–E §ÝDƒy¯=“1Ô-•öyãÞ«ü¶ÈVß…N(Ž$êqèº\߇®å2öΧ:%C ãèôL½´Qˆ*r¢s~—-óõbüe“/7–[*KU›r¿]YºAžû*s+ v† 0s+Çd†ZÈ5¾XÛ¥¢<•ž¶k„cÌáe«§°"›ÓjÄʾXgnnÒÐÙeÒp ò$²¯é./s™ÏH¿óËù«Ù_vq˜_&skûÑêem¼˜OwÙWãæÖ1[=*ÇwôÖ×å¾pªSOo—åÈßvi½ÜØX…·»ûüÁ—ÜwË øÔ€“Ȇj`eµ+¹s±.ïBÈøi»å¸¹rÛ¬„pÇÝ­:æ¼ÁÎ&IšØn[G1åHcÁ1âФ‹gï§o®_Ï܆n`‚kT"*Y'‹]ÛmùÅ‚!HäÝÎbߌúÊ’ÆíF&W™ú ÅÐqwÛ €B!¦„çõƉzc•×Þ¨óùÔ&YÂò•å¼9´t¬€ˆ ¬†UQAÍŽAl؃5(Q\÷Ïü#Nð«Ž'è ´¦'DR.á”D[ü@@ãǯ¦) ÖNÈøà^vûª¶,7޵é†Ê%™YØ¥U QÚоšc‚C»ëc:˜òîÝ ÇñV %¨cïÙžWM´Çœ˜c@I¼x(—Mgsx2Þ–åçÊ’&2‡†icUâq7Iý~hÓPA¹l 2›ôbB[l¸ CôÒ‹qN/³µ*ýÖ´¶ÔùÜ>‡Ã‚œ:Uͱ€àNh5.6ÜQÀ…QH.Ü–;;¬‚•;ßýQõB‘*Ä)#ÎÕø6t}ïÿ7– ó§YÜÿ¿ÿ›;þ É¡ß(EÃ÷t*›…7Ê8ãÃðïŒ(ƒpÚþ/?×>3endstream -endobj -1964 0 obj << -/Type /Page -/Contents 1965 0 R -/Resources 1963 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1952 0 R ->> endobj -1966 0 obj << -/D [1964 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1967 0 obj << -/D [1964 0 R /XYZ 56.6929 612.518 null] ->> endobj -1968 0 obj << -/D [1964 0 R /XYZ 56.6929 335.1485 null] ->> endobj -1969 0 obj << -/D [1964 0 R /XYZ 56.6929 267.4555 null] ->> endobj -666 0 obj << -/D [1964 0 R /XYZ 56.6929 225.2657 null] ->> endobj -1970 0 obj << -/D [1964 0 R /XYZ 56.6929 190.8284 null] ->> endobj -1971 0 obj << -/D [1964 0 R /XYZ 56.6929 153.8399 null] ->> endobj -1972 0 obj << -/D [1964 0 R /XYZ 56.6929 83.2251 null] ->> endobj -1963 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F48 940 0 R /F41 925 0 R /F39 885 0 R /F53 1017 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1975 0 obj << -/Length 1710 -/Filter /FlateDecode ->> -stream -xÚíYßsÛ6 ~÷_áGû®bùC”ÈG7qÛt“Åκ[ÚÕ–µ–”JrÒô¯(’²$Ëö’f»ín—»„¢!ü|cÒÇðCú‚#̤Û÷¥‹8&¼?{¸ Ÿ½é#ãX!§.õjÖ{ùšù}‰¤G½þlYÓ%‚ôg‹«Áèü|<9>ù}èPޝÐÐáNG“ËÑ{½w>”t0z3žâ{”€PbLF§ãcçèíøè—?Î&ãá§Ù»ÞxV9Vwž`¦¼úÖ»ú„û 8ûFL -Þ¿‡Œˆ”´÷\Îw³;«Þ´÷k¥°öiùjœ Äõ;Р¤O’œÓ\"QVÂq<ž]œœÏNÎ&ê4å;qß¡.’¾ï•ÂI‡ g~οÎÓdi^`uÈ)ò)—ò¥d®Q-nB½È’"øþB?|^z‘¤E[.Œƒ¤ˆæ¹M—úo`^P¾è%øòcz½Î‚"J½©vV!ªU±^:ŒêL'ÆY Ât+¦a¹ãyq*dwB!§.eC°•”²ëÜ´MB]×=`Ò -u˜¬DJäRÞ2yžEIîu\[ä×qdîÄ ~ -´F‘GÐ<Ìs¨/pQAÄ‘ë)¬l s©ëÈ”e6ƒµ©½ÏRÍ£8ZÙÊìÎ+Ìl—µ¼3·¸ÄÈw…·?·êR»s«’*sën«òÒ;`Ò -u˜lTž€Xú-“]•wfyE[–åÔ§Û| Mª{&AËÇ&¶×Y?¦¸¡ó!Áá¿Ú¿*ÑÿÑ>c‚îµge¶íµ°gDò†½ó0[¦YÜÈÌ"ÌM4Vi°hõ™ÕJ/â /ÂL¯¤Ih™®-zQÒQõªsà‰Z¬ÐŽ0AGö¡-ÑÝ`IÊøHÔ¤ö„ÂJ•±ø² ‚<ßu÷›´B&ÑðÇÕ&?Ü„Éú(¹nFál)J³‹b(¢ªt¾¤ë, VM&ŠŠ*§ó"ß &†ø| ¡×¥ö€i¥ÔÉ´ß*Þ[ †)‰¹ßv%Õa¼Ñ‘¨„,g´i}VbÃü2áÔJ茆 llLði7@+÷>ÛÅ(ІÁ'K½«g6ËoÃy¤ÞjXsM @d.ƒõªÈ]Ý‘¹0ã˜ä󗛆3L.B¨]o?; -‰2$ vë…´5ý¹@ÌÄ·Ã_)x1ž]^LtÚü6`£÷—ãéóOÄ: ÈÚÜ2ð†€M·,‚b7¹ˆ43<Ì4‘gFì>´\=-ÂfÛ[+ŠÇF%dAvå§ã±~yô~zÖqÆ.P>bŽü"/j=^#¥‹»ú¸ÔÇd=³]ÅòĆñÕÉäX+‘ÆE%Pܾ©!æ‹pi@Hæ‡Ó Y7l»K<¨çy{³„Á—¢‘&£ËÙÛ³‹Ãœ$Ð0’Ðtúý#6¡:J“<ÍŠho¬B¹»5z\lžÔÁ‘€;(Æ[è••ÂÌEž ÒÄN‡kù„óvÂ*EÍà¤ñm´ -KúE©¿áãú½ÊL.Á*ZDE5×ÒŠÈm` ,`À)ªý"MW]€ãVÊ=$émåm -…†”çhpt":gz§Ww¼ŸÚë*Jvu»¨½’ê@oèx›+gñÉ®nªÕ—jõ­ZÝU«¹¹Õ4¸ ÒRJb†ù*Èó®¹BúvV¨4.;4 :¯UÓOPt1pC¬Òøúù4–Dî¹ÛM"¿r¢.,J·PÄé"ìB¢Aö•ß_ú½Wkë‹Nß–§Ïì_òÌúÒÃq6óMû®ë#A±ßÖ™wèt˜¡´0m&D^<¬Â¿ž÷ÓgŽNqP_ëßPÊ,('m¥÷‡Òãjõ¡C½Ç‘Ï™û ³Ùèªñ ‰le@=«;¯ -~:;×4ì&g+Tãæzk³ó8™«KœàOãä£gÎ͆ã&|Ä]ÏoÖåcUGÏ|ø;­ÿwi˜ u?' añ?kîdÍòi?Zâ‚c¨¯u:WCñO{´ùž Ò A»ÿÀ°úƒ$Ö)u(BdÛõê{¦mßÿÅl”–endstream -endobj -1974 0 obj << -/Type /Page -/Contents 1975 0 R -/Resources 1973 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1952 0 R ->> endobj -1976 0 obj << -/D [1974 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1977 0 obj << -/D [1974 0 R /XYZ 85.0394 752.397 null] ->> endobj -1978 0 obj << -/D [1974 0 R /XYZ 85.0394 692.2263 null] ->> endobj -1979 0 obj << -/D [1974 0 R /XYZ 85.0394 446.6274 null] ->> endobj -1980 0 obj << -/D [1974 0 R /XYZ 85.0394 386.4567 null] ->> endobj -1981 0 obj << -/D [1974 0 R /XYZ 85.0394 326.2861 null] ->> endobj -670 0 obj << -/D [1974 0 R /XYZ 85.0394 289.3231 null] ->> endobj -1982 0 obj << -/D [1974 0 R /XYZ 85.0394 257.1813 null] ->> endobj -1983 0 obj << -/D [1974 0 R /XYZ 85.0394 222.4882 null] ->> endobj -1984 0 obj << -/D [1974 0 R /XYZ 85.0394 159.3957 null] ->> endobj -1973 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F55 1025 0 R /F41 925 0 R /F39 885 0 R /F53 1017 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1987 0 obj << -/Length 2836 -/Filter /FlateDecode ->> -stream -xÚÍZ[wÛ¸~÷¯Ð£|N„Å•½‰³Í¶q¼·ÝÓÍ>ÐmsC‘ŽHÅq}gpáE¼HÞí9m|NDC`ðÍ7ÀÌlAá-TD"ÃÍ"6’(ÊÔb½=£‹{èûáŒy™UZu¥¾¿9ûî­ˆ†˜ˆG‹›»ÎXšP­Ùâfóëò{¢É9Œ@—Wï/߬^ÿåòõ_ÿõáêò|Å∳åÅõõåÕ›w¿œ¯¸¢ ”.ß_\ýýâo®íúÜðåÅ—Ï»ùñìò¦Q¬«<£µúröëot±5üxF‰0Z-žà†f _lϤDI!BK~öñì§fÀN¯}t F Aƒ³cÄ(Å{p(C"Á……ãÍåÇ×?¿»¾y÷á -WcŸi¤ X0‰©PV¸H¶éfµ~Hןÿ]©@tÐ’HKxå­d… ‰eýâ…\VÏE|sI±qYQ§÷»¬~víåïw½v2Ûð‰Rž§`–zW»ÆÇtwW‰@[×Ôê!—I5²N!4aVBÛuެn%9{˜x±r¸:JmÊ×rùôî*/“MVÜã[†vËÕ%ãË›‡¬r}Ûäs:¦‹xÆtW¥cÐÇÜ/¿¯Ò»}îæpÜ…}¼ÑÊ£ -íU¿†Ûå™^úÎuY`ÿý -ç>D”Hɸ›nç†ïü·î -ŒZº«ÄýÞ"tY¥»¯éî<–K2N;¦‰T¬G»rû˜åéÄê"œEÌ¯Þ ÓdÛ,OìêÙ”N¥$Ñ\šÓQ†ES®¼ü+Y/o÷µ›/«ÝTIþ”<{6ûí£¿tÔ„þ=Etë´¨ƒ@éŸ÷ê?¦ë»€‰%øaö -T] ª¼ñ:è][ânq ž,úKR#ãxy±ÙduVIž?Ÿ3ÆpY‚»;Èãcž!=ìPõ.[×`;Ûe¡ryú5Í+×|ûì~7é]²Ïk£5Šuê:,ø¢cWHû>UîëGDU0ðª,ÏÝÕmê~Ýw•Tþ·ð¿ëzŸxi‡2^5Ð0ç™áiÐsH .€KJª#› Ä8oœ”=&øòŸvÀ¡·I±·€Ú»¾ ¡vOY•"6ÂQÃûWD¸Ô¼oh3ºNÀ¯·ûªöV‡Þ$4Ýz_K¼°³\¿­~(«à’]û6=†Rd…óJ‚H-ÃÆö’ý.A¹ñÞæèY@ŽGõ""Z*c‡ù`Ï«áñËpÇŒ -œ”Á&=~Z:™UG(œ•ÃÈ!ᤫÍá|`)jâùù‚Ìp¾.J1#4Öýù.‹ä6÷¶Ù¤·ûû{ØbÉäš%±q1ÇÌ¢;R3«RvÙ“Ëž›²]÷`ÊÑ…w§¼†Ã¤n¹g/öUrˆºßn“ݳ'ráÙš~Ëêit8PZDGÐéHÍ ¤,:_&Ñ™›²Eg0å(:Ý)Úg©Gg[n<&«wµnºÊÂïê“èH SÆGü¥#4M²Ð|@£0xšŸ/È çëC‰´?ßk ƨš}Æ•SûÄë×Ðè%ñ–0"D6d*ïwÉö%Ä„¨ø˜Ûv¥fÀRýßè "xlæ§ B#Sv×ið‹þ”î쳇Püv¢xÚÇxíBÍds ü{¹ßxÛ“È[. ­êjTn‹Žy{WjÔ eA];(Õ#¤_,D ë<©ªCÅ œ]ŒËyłЈb¢7,㎞fñð¾{>Ñ)3 c Ì£]¾ó}EYO„Ÿ8—ï®ðoˆ*„°§›IK@ÒJb™yKt¥¦-ÑHYKd#–<¸ -™ÝÔ‚Ý"æÚÌ«„FÔê%naŽßSëÚe¢«„´´¬êº‚»õѨì%»Øá²S µY^—U•Ùs%q•“J|N6‰ÅD¢&$Ýh%Hýrk­á¶ÅqÇ4®Ÿ¨¢>H‡Köjdx) ÕFŒ¾B-ÁÇ'f‰ †‹bÖ¤IÃaæa2êǹ8\^®“)í! R’©™q%1šuµµÃS×)LP·î‘¡âîÈXtJON"ÕÔAˆ 홊û(êg·ï=Q­ -lV1?ݨæ°ê"$æY˜ •ÞÿâZÖ.ÅßTÝÆ;›Õ,¦¡Ø|ánË¿…cƒ8)¤Ò-¤5N"+VðÊ…v¤}½*ïVáD…=WÉx?÷ƒœ¤Æó·BJú=j%{s}hî)«•˜ÚÀÈí“M}ˆZœÚs©ƒ6>=dë‡n¿…Ìî«eHšVí9×,$íÎÕiöט^²“í¯Å¡ù¹懫?Ÿ+µü‡»r€›ðÑÒý^¸ŸÒ7{ qct8-àÆqGp@ 'h#øŸr ëÿ„<ŠôÉD€C)Ô_ÃNÀUÉdžÞ7ù·ZB"mGªú«‹üêì΀?¥ov¬âÚZVà]˜(DÉʲÂÓ!&"¦…®@àpCakÁØ—äUé®?€kïpuŸïý(Éfã”­¼ÐÐ+ ÑÒìö1¾lÕØ&5rÀõÚ2Š’Ž:«\5ä°¬u;Ѳ|s„ߊÄ2f/â7›å·³ø™Ú>Î ²¡"U•Û4°B«Ø”¶Ü$_ö™»ð§³Sì¿:6kÔM‹L­:®ÀÜ ­¤}7ö:É'©¤ñ c"I¸–òXÁ´d/_xÔD¾›¬ò•#!–þA¼áTÑy#­®z-ÚÓ¶6J×çÀÅ] $FߤzŒ,Í0®›ß¶`Ð'Ä_òmóÞÑ!­©³¯i·ñ>Ǽ_ž¼3yb¨ ¼Õ¬o”jàþ.öŸÈŸ˜åh¤æó§®ÔtþÔHÙüén4аÈävoc”.ù¼bAhD±~&”êk6žÉzm¦SÙ~)Ùn§m*ÕŽòÖéd -ÒI›2Ú¶N¿Õs¼eã¹T[yë¡Q]7ß%OSsÄÂÞM%F©‚)—1úU:R3T R–*oÇŠŒÙ8ãW1TéyÕ©Ýúl0QÃ1ØS®a‹ÐÒŸÑZ4lÁFd ¶ùNÙ¾YÒ¢}/¤{¯h€@W7o­œð4 F B0}v™™bj”A+ˆ‘¥éöâ‹—QɺÉ[8²Gü€C-¢?ñ^Ôzh8zý+òn‘iì매ðþžÞ!¬w°M{é}‘§¡„ªá…êø^¨N; -ÃÏŽùI+4ã&^ÈzÉçq/ÑF‰™Šî|FÏ+d†JõêQ1‘±é+ÊQ#U kÌ…t±Æ]¹°zœ=1èÁØa–©Ùò)³ŸæÁÉØÁûNh¸K²|â l@4ÐϨìùkj^0Ü\ÍKëîp† ÍW6 ¾8JZwkΈ±Íb‰¾+ÌŒHñ6#(¬A,atwŸxJvÅt0™h¸M¼Xï“]øØÆ!¼‰T×Ù}Qî&£!ˆÞhóͤsÆÄ›wΎдs!ëœÛ1ç”$Šš/?FSAX ÜœRAf¨Tÿð¢ÙÓª=»(Ã4n¼á®VGÇ2Rh¬Ê}¾q×ö{xÀš5õ¶rƒ‚©ïÅ×'¶ã!õ³5‘¾½ia,P¬dÔsIÀ¹¤Ëá4ÐLÿÔ™öSæ¡À&©šÏNªëþoyyXv§å$§Ã‹ X›}ÝF›oþô—‚í7‘2†Bóq"òXAð×^)Tœq:tGÿMáP÷ÿ–-–endstream -endobj -1986 0 obj << -/Type /Page -/Contents 1987 0 R -/Resources 1985 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1952 0 R ->> endobj -1988 0 obj << -/D [1986 0 R /XYZ 56.6929 794.5015 null] ->> endobj 1989 0 obj << -/D [1986 0 R /XYZ 56.6929 752.1653 null] ->> endobj -1990 0 obj << -/D [1986 0 R /XYZ 56.6929 611.3886 null] ->> endobj -1985 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F55 1025 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1993 0 obj << -/Length 2490 -/Filter /FlateDecode ->> -stream -xÚµZ[wÛ6~÷¯ÐÃ>PçT(®$ðèØJënìdm§íé周ˆ§éåe]ï¯ßÁ…)”ÛdOކÀ`ðÍÌ7ˆÉ Ã?2“a¦ø,Q LÄlµ¿À³ÏðÛwÄé,:¥E_ëÍãÅ·oY2SHÅ4ž=nzsI„¥$³Çõ¯Ñå‡˻뛟ç *pôÍãèöòîãå;+û0W4ºünù0_$¦”¤V‹qtwy»¼^\}¿¼úç/ïï–ó߸X>zÃúÆÌ´Uÿ¾øõw<[Ã~¸Àˆ))fÏð‚QŠÎö\0$8cdwñpñ/?aïWóiÈ\H$(g Á‘"J†]†à‚E‚Aâ]FIÈe–vÙâVoôÛ·Bô4‰@I‚%Ì®Uöå:;ö¡%‹YÉüVÀ2Ö_*”`¢†¦]m³Õóã,Ê7ö™ên¶¯ÕœÈ([•æ¹îË6YUÛ÷¦ì}Ê¢+}ÌÈNó¡¬ëüÓ.³¿èmºoR;‰õÌÀ‡TRÄ™Œk~£”oÒ|§ŸN»¿/*‡#vÊßæ‹a‰èÍöœVÅÈl,F€ØN ¼Î6i»k`HœÝÅ:°Æ‚%qœ08‚”Ô¯–.Ê*!†ig=: ‡ºX ° Ÿf_kš^Ë@³A“ ©›„&F’‹i»:¥€]C` -$i|dØÃS¶Ê7/Q‹ž·Y3'Ñ6«ìû݃}±Yk!êmÙîÖVáSfe+ óÌ 5Zb–YF¾4ÛÌ-ØÓˆÓõÚ¾ÖuVkXcуµÖp°î€D¼”˜Ÿ"d -Ý R\œâÑfÚ ìüt!ASŒºŠtŸ­«rÿ”ï²ÿ–EXEAÀQ*ËPID•T¯Œ#8J%ÔW0\ŸÜˆÙüˆiÏ;ÄÎQ€‰E?|•ÈÅB©3‘ÙÓšˆÌNËDfŽLƓΨ œ¨öÒItrŽ(Nø´q^+`Ý >¹BDÊdhÞOó„GUÞèÄÎHdNF8*Ûæ©m¬´q{àýݪÉ„ÒÀŽæ äœøX@ÌD7›À”¢D€ÏN ; Dtù=¯CsA'¾\,BÑ‚hB:hCÎ(ìfŸ;o`[AT7ÅÔWN€wÜF·ymµ­³M(ñ×S4eõ29qŒ¸Ää/‡¼: oœh›Î û 4n§d¼Z‡°e¤s|ݼìebXH9i–W:µkkŒ‘c20ìPu¤ÒG …-FVnŽ~[·û'SX@hƒ@~Øî28iN•­P¾l¹èæ«­æ Jt¸‰¤OƒÚÝh¡Pˆ{tB\ÌJÁ¬c$ÕçZU¶K›ü?cyQg„Å}à‡¦@²4…î#÷qkÂAFÚl7*«}ÚØ±…¿„âY;IÝæMj¹¢Õµƒ'ã¢rõ7/>[YÚ6%Ì”¯ÒÝîÅŠ>¹gê&ËžÒ*mÜdõªÊŸLè%"z_XaÓX6šZèàn ¶ÙÙ‚Ó¾A:eìH‡õ‘•vE¢.¨÷eG!´tÛB/¬$]w{´•jðY³mk—;Z€ÌÁ¤ó޲uÞ8G·kl,u™åm0Eàáá¼¢ºrKL}žÓ&ÒDEë2s£¢Ôå<‘Ñ*mëÌÊÒâŲÞí&[5N»-ônœ»uô8‘¨ÄGŒVeÑdEc8—Š£›Æ-±«Ëž)€±Ã=–ŽnlS}T–¸<ºÏÒÂ8Q¿(°³AŠ˜Ë¸ætbmŸ~æ&û³MžØ”ºx:{öµÆÓ§×2ùóá‹Xû¤]žµŸÚdíúvPhÚIx¦öñp?"úѾœô”⨧SCßûžR zJáÉ·Ñè)c„ ýŠ=%ìõ=eèhS© o*áâÿÓTrÉ"#× -ž}­qxz-Ï&O ‘Ô³u^AbФ愺•‹›6Îk¬€: -Å¡. Ì»ÚÚ‚¢c˜af©\ !㠽ǜRóY¿3šÌ¤ÛÔMŸ«]»Îì Ld±¯«Gí ÑÝWNRŸæŸ[(ayé~µ¬ÂŽ}‡ª_z2[Û„¨A<&Cä¤õ0ßUs iÙŽ?¹Ä˜ÚGïó]Zíœtå}fÈŽNº€Œc 0¨Ä¹ ‹¾Ö¶:-ƒ­çPêÓ×…ç±åÑ0eœ× -X7Ä`ÆCëV[}À@‡øª€ãJúPI„)§=P™9 ¨ôhHB´Ä‚CŸJ­pgاu“U}%;þÇÍÝÕ»×KûvL‡!Hs2>ªªÏeõ‡NÄ»¦_l\q,ÊêaßϬvŽ;èIŠ€Ë(†Ã¥¾ß²°ƒðØ„¼¦P’ˆ³M S)y®«ékƒÓkp^/ Í®áð“KvJ%ˆÃаd¸ä50(ë=Ç›`Ô²ó©õsZ”…¦Ë}R3zŒéî9}qcÀÔÚõTû T1ÆØß¾r?ª·@LUOkâ¨:-sT?}Ùü¤a‡;ùSË‚wòÓ|ªI¯¾ú4÷žúÅp"x®ÍR‰ë -@Ç»€8ßç…>cói¾[¯ÜíƒæÐ —ÑÝ´–j ,îLƒf˜+ ¾†E¥Ã -§.ÒyÇðj{áï¦oæ†Í釿^­¿cå–íég[¬6¦/LØ7ÓJ¿«­¥ðzâÝç²Ê›íÞ¾j–uÿöʾ̸æZæîVèc áënru Œ’I}1E0ÿ 7¡ñhc>z]©s™òWU¯ä|ül=ixe –®Úìì¦Ôú9¯GÜÓ™;pÏÃri?¾|÷ð>°ÇStöögÜzJ¢ÞÏf>¦™üßØÜ¨Ý€™ÝòD¹Ï>¡ 9,ÒUü77w×v>åvµ†“×M¥¯®­è^7÷ƧÅʹõ6-Z¨C§Ë“X"ǃ[Æ¿2! kø÷{ùññû÷÷ç=zS@,2‡‡ É{wöWeQ—U“·û±?P€¤®ÿª ”Ø›øÅ¼pø3 (8LJŽn†uP¤3Joó±é‚Ièhi°ýî“;!endstream -endobj -1992 0 obj << /Type /Page -/Contents 1993 0 R -/Resources 1991 0 R +/Contents 1990 0 R +/Resources 1988 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1998 0 R ->> endobj -1994 0 obj << -/D [1992 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1995 0 obj << -/D [1992 0 R /XYZ 85.0394 225.6507 null] ->> endobj -1996 0 obj << -/D [1992 0 R /XYZ 85.0394 155.4035 null] ->> endobj -1997 0 obj << -/D [1992 0 R /XYZ 85.0394 85.1564 null] +/Parent 1966 0 R >> endobj 1991 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F55 1025 0 R /F23 726 0 R /F41 925 0 R /F39 885 0 R >> +/D [1989 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1988 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R /F53 1027 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2001 0 obj << -/Length 2597 +1994 0 obj << +/Length 2340 /Filter /FlateDecode >> stream -xÚÝËnÛHòî¯0‡‘«Ã~²X,ØN ÁÄ㉒h‰’ˆH¤F$g¿~«_M)ÀÎ^69°Ô,VUW×»'üÇ.PDMbÅ0Ÿ,vÑd ïÞ]`‡3óH³6֛NjWoi\~yüåâö±§-2ލ–寋O_¢É$ÿå"BTI>ù?"„•"“ÝãqF©_Ù^<\üÞl½5ŸU€#D¨ <Á Q/ÛJà -¯„ËŽ`‡y²K—zG@vF9Šá;ƒr/ô:У-Q(æ±Õ¦ýÜèç3!±…æy•ò´²¿–Å.Ér kt •éá9=8 0FŠsâ8ÐqÁ¤áðð=/öeVöµN1Š¥ AA‹–0ÈM8èqD…(ÖÎÚ$ŒXQƒÕÚ· ~š±/ ´°[ãmÝa‡s{McQä«l=[e[§è[gÁ)s¸ Ýe€.›œ;ÔeúT¯gÛô9Ýþ8ÙU­h`¥8 ûÏWÛdàAb±Ä}y€ÞŒJ‚0àË À7?-öu¢¬”±êSÞŸUʾ8T!z) ´Q6ÐC€rW…?í’—YY,¾†äŸ‹c.ûô«ó‡˜ÒEU¾‡ˆ2$¨·>K´.½Çõ‹ˆNŸ¿˜¨0£°]‰á4ÝY¿ÿ4ûWƒù`  ¢.ñ–ž,6阡[ùB S‰˜Œânh¸¹}¸þ0¿œÿv×|ÕTEXµ#Õ0 Q0VyŸ„83ƒ8MìãÆÅ. ›€h ‡ïe•î,ü9âÑÍÝ<°]p-fÓ+Xˆ£é>Ó3¯Š•}VGèÍüîÆBÊ>–YY²§ºÊ -Çuu¸ÄrZ8nó‡kd¡·ÅÁ»Â`¤î´Ün:Þ”å«â°K,Q|ýÓ¢ØÁ•ËnéÃÛëÒBÓèU2&ù²YãÈg,‘‚¶lRÃGÏÅW›'äô[VmŠº²o#üºÞ¥yU^NóQ w>£§3޼}˶[Kßê&q¬Ý~ÄÈURo ‡?GYׇFErªW‚æŠã1ÚÄŒWiµxe¤B:žD“ -TB} ¸²çÄ ùDœôª-­Öðw dyVeÉÖ¥Ó¤JúG°³IÝ™®´ahà¯:=di‰~ Çþf|hXظÉ BˆÑZÌgÑ6–¯C†Y´ÁÒ|g¬ÏR0¤–§Yz¤ËNœ0¦¸Ëòcéì{~ÿ̼7l¢!g:-f«ž‡lŠÒÕ3;fYî–3ç#‹dŸr•PÎm]%ò”úÒÄ=ŸÊb[WnuŸTmv£Ñ…( $’ÓÑ¥5],]–¡è‚‘Tœ†ûæntÑóhÜOÊ×`ìFˆØ°ÒðÁŒK”;H ,“tWä?—΂VÄ…æ Œ-0f`Q…ÇÆd¼—_f<žÞèOÖÆêD‡d¡N3lÚ‘@¥Ž¡“W‚ž¯Ô!ûxù”Î\AŒ9Š`¹g…~\Ôt9æxôSáSxRö’´W•.Œ­ªl½påuéŠâ BsM;Sê¶±N Ç2¸9B.äö“,=R€eÏ!¥€R¢ÃòCÝoó|0´úè½\9¯í×¾¹Ðn†RÝwb=Ís“¼Â÷Œ™fÿNu <®W¹"&gŠÇ6Ö ½z,£×õ@¯q¦Î°ôH–m½B¯ÇiÔcù7éµéÞÂÂÛóÖYì¶ðNÈžÞ+!¡‹<ÎwÊj™!ŸëŒF C‰ ‡x¦¶kcRƒeiŠ¾Ð• ¦z£Ä¶\Š#"$>-—G -ÈÕ Š”’L±®`PµDÓú`f-tjg.lº‹6ùÖê2Y§\âƂœJ“u©o -€È½ÏóÕ½³?’〦_;BA¢ˆf>§y -®ÎÔ3”Ŭ!câõù£T )˳Æt–N ¡a´ˆd½©ÑŸŠnhºžn’ët=»Eõò#•ªŽ`›Ô§Ø¡=›r_xo¬Šžÿήû†©Ã¬€VKð?µÓ\ùhö´öC>3OpÖ¦84bu ±<2Öûzû~  ¤ˆüwJè)žQ -DpwE¼¹}óñÝŸðϧç6]—‹Cö䯑²<Ôã2ª…ó6õ¬\¼/E›ŽÖ4磋ϥú6Ö‰hç±L´ËÏÖšÍýF'ÜI !ÈiÁŠ)8Œ_긇™í„ô‹äkjW’ås’W6 Â ÓÁÂs]k¶ß:¤ëû¥»~;Slèwå>]dº™I—¡a1Å:6Ò• Ð-ƒ1ÚëyÜÔ"v¥£¿ -s? 6 -åÎÎ{ôòÆy½{2‰ŸÙÝh\-¿]Ù»à’æ•]°)€Åñ Ì7Å‘rk¬Ixê@YÜùÊ®dŽhæ¸Õ¹›=1æª3ou¸í]´#\³‹ÖÔJï™]‘™Ï϶ü¹[2ݱµ¾›Áãn—£Þi\Aø?íŒ-¤q_ôHÆ÷g]Ñß v<‘ ¦äi¡<ÎP¨Î}i Þ§ºBýzbZß½Ÿ9ÞZöî‘™Ž±dp·y"úä7_õÊ÷ŽGõû¨æ’ä8â4Ì ÄéèaB¦Ÿ¹topÆÒᘓ,CbF¡c<ÁÌ£ ˜õ†rÐ|â6³?ôõÝ!óc _jØÕƒFuURÁQf‹òD‰®›qÁȱB×W_°*¡œÍŸú’UhìÏM Ó#ØwÔ\õü׊rüS¦ïáäÈHƒÄ`ß -`'”Þ&dhîV†²ÿŠfendstream +xÚ¥]sÛ6òÝ¿B/RÓ%>J¬¦nÛ9ÓÞ5} %ÊâD"U“râûõ·‹(’¢Ïuôp±Ø/ì >‰àÇ'±f:éĤŠÅ'ËÝY4¹ƒµ·gÜá„)ìb½¾9ûùi&)KµÐ“›u‡V¢$á“›ÕŸÁk¦Ù(DÁùåb1..Þ^þçêr> yb¸ f××óËó‹?¦¡ˆ#@ä( +>Ì.?ÍÞìzšŠ`öv¾˜þuóÛÙü¦¬+<$Jõ÷ÙŸE“èðÛYÄdšÄ“¯ð1ž¦b²;S±d±’ÒC¶g‹³µ;«vë˜1Tœ°X(= ¥b ð7g†s@2qÊ´²5™àc&óXh²p6TTf4—“.±–i„¥ì°4‚ÓËß7y9 ¥Hƒ»¼Ìﳦ(ïè;£áŽNÒt¹É +‡\ç MšMN“«ë›)O‚«O7ôý9ŠdæHUnW¶Ýž½Ç]ù²²ãªvˆåŠ&«ŠÆ²jzRæh¨IÂ’ØLBÎYÇÂêã(£÷œPFà>í¤(ë|y ‚¬òm~¨Êš8œ;UÃ5SI¤¾sô¬gŽÞc¡Üÿ­ÊL&¶ùu*˜Ö&}žµGaÝuÔ0­Àq{¬o6ÎŽ¿/«²Ó¶Þ€ßGBA¨¢ñÖ}×Å]™¯ž4Nb&ÈÏš®‹õ´éZ,”ÿKþ8äi$“Qôži„g/lXäž‹}¾,Ö ¸ÖÁ×M±ÜÐd©iVoªÃvEsk!uî Övˆ6sCBC.”q\¬ TVCêYë¸H…ÁÃËW¯bìiY²¦OÖ‰[`:¹0ŒÀÜ â(ÿ–íŠÒŠ+}Ô@øA*7ÿ7Oã #·¡Eâ+[Á¥}þ ‹)FÙ£vxG¾®¥cù àvQŽø°¶Ëšå†|¾ö÷ŃOQ_-´à+Ÿž Ù€h–K…S±©î§œóàU»å¸¹vÛY;Ꮋ›uð¼AN$Ö·[áÖ“P(–FB¦P…Pâù³×ïçnC×1A5¡¡u£X+àµÝV_É:†@ÞíȆ°†ìkš¢Ú–¦J:49ÔAë¨õ‚ý6g@dD0™hëL%š 1o¼Pç‹M0XíÄ'òaÞ>¶&éH£Á"Iš:«²†œ Ø<"OÒ°8Q©?sjD>Gqô®£ û JÓOÜe`‰ƒKž’ý€€ÕãG¬C‰i§eBq +ò¦¡†Þ×98F)E]¡]}¿±°Ï\ª±ü÷DŒ¡öÉ2ªî}Dî„ÍM¤Ÿ¶(ý\˃ì¶z€Ðr_ŽÏ«»§)ãÙ +nEÝ@)…‚k”-ÏQìšY@mÓ¶íé½XÎ|–âˆ9ú¦ eÃDÝ¡…À­p謰ÁÏíýZ±êÁí c] NÈãi…­ÞÀJ cF à`•m”Ôg‡ýóˆ£;M1+¸ØÏî2Ÿ |¢j³tKæ¨g›†¹`fÛ™$8”`éæPÚì%•~«<ÌרèÒ a¡WábcO!øò’+n‹mÑ<Ò¢_²~?ÒÜ;ç/¯² ãZ´U¹Ê}z¦†ËM¾üâxVÚe_r‚Ôí³ ~à¤Í®•PÃ8p·&Ììî]Ê%ÈÒv©|¤Eì-[˜+R4Y¼ÆÛ-¾:‚,Öæ€“5P?÷nÙJ#³]&@ŸwuhìœèRh÷û<»§u <æN‡å2§+¼Ž:ÑíÞ` 9œ¯Šgó2A‰@ç }؇=kœÙm‰”Kä±&Ul¿Ç@ +½÷Ï?¸X¨wûm:2?ÒhÆbßf¦“Ç¢a³HùIrÑZOPk#´þ¾ºÚö@ö¢ÁÍѽ¸ï9¶yVÛü—ÛŒâ +ÝL`²Ë³²)v6‘ X_¼énÅ t^®œHô.✱¥!p‚=ùÀ­g½îúe¬‹0ß…@Áîë~盬yòyηžÎ‘ ×÷mïúËüã…o‘°åYWÝ÷Q_çl¾Á ™{•~1ŸÓžÙûÅÕw_1zW|¼Š%x‘r™vo[œ©Hz½¾¸<'6©ãÖ+^ô±ÛIèCV²íX?¯lyµ#?&>Mpßðüå Q™ä=ÅÁ¿cÞ^FŸÒ˜%©Øoöéæ×«ß5ÜE Ío™;wX<ÖÇÜ9¾©Ê +IqØ=õ7ŠŒþ÷1òHµþã¿XŽ&)¸2$‰n&f°Y{¡P9.¢ÓWåˆ ©ÅˆìÿÅhØ^endstream endobj -2000 0 obj << +1993 0 obj << /Type /Page -/Contents 2001 0 R -/Resources 1999 0 R +/Contents 1994 0 R +/Resources 1992 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1998 0 R +/Parent 1966 0 R >> endobj -2002 0 obj << -/D [2000 0 R /XYZ 56.6929 794.5015 null] +1995 0 obj << +/D [1993 0 R /XYZ 56.6929 794.5015 null] >> endobj -674 0 obj << -/D [2000 0 R /XYZ 56.6929 769.5949 null] +1996 0 obj << +/D [1993 0 R /XYZ 56.6929 614.1369 null] >> endobj -2003 0 obj << -/D [2000 0 R /XYZ 56.6929 747.9385 null] +1997 0 obj << +/D [1993 0 R /XYZ 56.6929 339.2217 null] >> endobj -2004 0 obj << -/D [2000 0 R /XYZ 56.6929 712.2038 null] ->> endobj -2005 0 obj << -/D [2000 0 R /XYZ 56.6929 645.6981 null] ->> endobj -2006 0 obj << -/D [2000 0 R /XYZ 56.6929 561.1687 null] ->> endobj -2007 0 obj << -/D [2000 0 R /XYZ 56.6929 455.008 null] +1998 0 obj << +/D [1993 0 R /XYZ 56.6929 150.6999 null] >> endobj 1999 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F41 925 0 R /F53 1017 0 R /F55 1025 0 R >> +/D [1993 0 R /XYZ 56.6929 84.3474 null] +>> endobj +1992 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F41 935 0 R /F39 895 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2010 0 obj << -/Length 2569 +2002 0 obj << +/Length 1439 /Filter /FlateDecode >> stream -xÚÅZ_oÜ6÷§p•®Êÿ"qOÎ%¸hÝ\ãÞÐöAÞ¥m%Zi»’âäÛß ‡Òjwåu{N°Èáp8ÎüfÈ Oüã‰Õ“N%¹S™f\'ËõKî`ìõ<‹i1åzq}öÝ?ež¸Ìa’ëÛ‰,›1kyr½ú5½xóæÕÕËËÿž/„fé‹ì|¡K¼¸úå⢽9w"½xýê-t•’˜²–^]üøêåùï×ߟ½ºÕ™ªÌ™D]þ8ûõw–¬@óïÏX&ÕÉtXÆÉúLi™i%å@©ÎÞžýk8 SçL „ÍŒ49´l&8ÈøËJ aç—e`Ï<3ÆœØÍc +6‡û¢œÁ1(“,Œ=¹HÈ„óÌi-ð„8×™*Or)3†48¡+4pàt™6ŠF–i)GŽŸÎ†§×ðW¤¯eJ¡mb`·Ž[\:ù#áSÎIbš´ÃVw&„ï.×"yÙÀ†’éžÁ‹‰ä°)#&^Ç5ìÏ2›ä  -”F•¯ïËÝ+O›MW65µ‰fÒuQÖÕ§8~ÇêÎo}ÛQ¯kèûâòê%ÍqDXùsÉÒçB§¾j6~—)ê5Ö2|¢I7žˆ[¿nιŽóVhC<ÿñh@ãf ¬¹M—÷E}çWÔ)kúô¹í»~멽õ•/ZR³Ã3Q.Go•ÉÄžç`ÒÝA´-vAò<÷_—á ØÜC‰yäaà¦èJfœvç×|xF.´çâ-ùµÖSgá™uZF¿þÛºø¸h›åûöÈ©µÉrÎL2]øH»‘kF?9]Õp0wû -^TUócoº°Knsu¬‹5ùËL`eÕ°rW–ö­ }a€¬0«U&%ØeÎ -Ë‘ cVäò]{äoüÀ\J~päÒe*‡xþóÎ;Ny UÎ3f{5ÔtNÿ™ÃGžé,Df¹Èøsø{°òrl‹ôõ£ˆ©…ÉÀD„L §Áä´ýdÊS9}3u®ÀNN1ÓÙfB»½oújEígðíëÚ/}Û€Yì€z‹À` :Ý}ä W\…Þºx‡Ze¦EF¡-‚i€³…b -ÔñãÀ,`Â<)%¬„jK)Fµ‘º$­±9Aìšq8rúú¶¯ˆrã—E"d {@j»ñËò7Æ„"iSUÇGÌÇYa¹‹}•©Zz x­¸L«r]vé¸+¤G¶^y²Xõ©¬ïh´ýÔv~M o.3¢^žó´£&š$®³õñ`⊭ïâR˜g ûpvRÌD% ±"E_uDX65Úã®ßžs GýqÍ×R›,q”ÝxØÓ)ήFéí2:Ŧk¶q6fÔíèP Æ0ùŽ‹x~l ¹€Ã.·M½öuGœÁ?`ð}’ðCMdM$·ýfƒN©X'Œkì<ðÖ¸b¿¾Á# JÜÎ3à$ªñÿ^F§ÎÿªéÂ1@ÁPµ ¶0TŠŽhñÐapÙõ¸%l<—kZ–S°Og ô&zsQaqäЧ*»®š ¢p¬õ|@©(RõÐòÔØ3…S 1Nç‰2OÀK³—sH|2Ï“Ú.Iù”G&(Æ<á ÅnõhÖQ£Á…°=u! -½…`yf•ÍÜ'øW(¦F¸ÂB«k‡Š«ódÆàSH꟪²¦Yå™™ê+×YJi°Ùôþ0Wg\¡Îêfê,—q({ãA®Ê­_‚Ý?%B•à (‡¦ËWY׌v{>¦$yÈò{êýã@2Zƒ H˜ù‚Ê2'场k@ÁÇZ:p·ä+ vC«`R – -¡#,×kº@§*ë@†Ø sîzªö[ IžÞôQÏÛ„ñ(ƒÚÅ -¥÷æJ`W3舅ß ‹áþÃbÄ1¾ïºð ûˆ×ë¥ßtÔ·V—ît@j3“›à.– ©†ätSÖ«S© -j½ËåtoÒøÙ×mE*ì]¨-½Žc#<>Ь&ÞÓ¸EÜÑæð©Óþ÷À¦ßböV2§÷’áF H”þR9\¯¯‹ÎÃõ—3–Ð(Hoô@„“×¾¨£Ôxé–æ±Ç@T0{ºÄe‚ï•8$s|ZÁ< nÊn¡á²ÂÞãq -GÏ.Ç^ eâN=íµÒ -;)PäP(aÏR•Ô¦A‘‰Œ[b@ÅVˆî:œe¤Ïp .Qn±ÙzI;wŸ ªÓ£_9°ÜÍònM¡>c˜8èÁ®lú–˜Ö‹Ô&3œP‡šëÊ¡8¢îqаøèÃâ ô·¾+ÊP^ !Ÿ{ÃáûNH¥'‹9™åÎ ÿñBi -âÏL _¹Tr •öt¥40…úph¨­3<™ˆ:Znà9^o4Îf6Ï÷×ûÙcÂ?‹ ×ä~ÛŽ×ã:>ªa;þž~÷±ìŽÎ6̓I‹Ÿ° 4v<'~¹"ž`–™Åd ù©Å–£ÅöÊBȘ̺ébÿ§Mnú²ŠMB½ð|ñ´Õân¬””³;aÉgÏþY÷ßTcżU$Ã_õB»p!•×Pj+ò9íÿ Ï'endstream +xÚ­X[sÚ8~çWð3EÕÝò#Mh›nK²ìîL›Dp×—®mÒ¦¿~,ÉØ`Èdv§3Yþ¬sôï\bøG†J ÌB> BŽ&b¸JxøïÞ ˆÃLuRµŒÓ8‰ŠäÉ÷Ï™Oà:—Oj‹©1 fÏj«:­­Ukëñ(ó D†ò“Ôc²“y +b˜ì˼G]”MÙòUμ=®Ç0@ÖcéòÒzìbûPDéK’› ˆ<1¹ìÐB €GÕøÕÆ=oÒƒzL€‘PtMÞèb“iGŸ•.]L’DM}ËwE%ÝzW²ËªÇ<\\Œ#J9“áäææbv>ýÞb Ä8ü8™ÝM®ÝÜÍXÓpru1]|],Zµºª̬N>ÅA -'ø0ˆi%‚gxÁˆhMƒÍˆ †g¬™Yæ£ß[†Õzë\($(— -CŒ*6 A1!@s‚HÌh %C€5T°è»=èÙ¥JÀ0VZwK²L–&Zeksˆ ¡1¢´ê -î©×R èǺRE”i¹¯àu‘¤Î4iR%n´Úމ -‹W½Ë$ÆHÆØêò$ˆ“²9e–W…ã^=7¨w»a±:XKÍ*Ù­+÷ò”™gë7è EÐdŒ5b’ÿ”×0Uû³ö (ÆH1}œ•Û†•ú ûŒ¢F·H2QÁºV!i!¨…IõbE©@‡eÖ<…䤶°‰iìñœŒ#IÃÛúÿ$œ¶c^õ’HChœYѸV&ø0Єn–¨;®ÿŠI=q6ݰༀ3ÝczÆQ—s}LI»ÎG’ ¸KÉ‘$®±xÈÊqÄDUVän¼îÊʽå…|3î¹+Mj3‹‚#û¥–K¾~ñ£•_É+³5Ž— ­ ÚÙ·ÓÙ¹i÷H͘Ÿ©ͺx4ÛÒh½¡µ¨›ä6TbnKþâ^¬^ö¹5›bL„çâ)‹­{.’ü¾™Ìr÷LÜcµ«vÛ–ÉÚ$¥±|zÞÎ¥FTit=ê—|”óI Ù6zM’¿?ûnO¨TÝdÙqû&[ -ͬ?°àùôj6¹ž$°†¹¨ §A*C—¨vU–7am—XWzevŸ'ëÒ-–Ånmm@½[ÙÉo~§u+7ª<—E^9k·Çe'XÉ“)ÍöÉlóºv ƒ„SÅ}¤nót9p"JH6™ôUµ¾FÖ‹ËÊ$iÏ#šÊ$˜•|O–¯.ÕñòÕRyƒ¼¿»9«c„5!§Å6Db÷ª¦Ç”ï˽,jà—¾øºTÏA|6«W5œMlOr*#†ô¯Pu¨N@ÕPy¨¦³…-Soœ20±¸¸ýØ+êò¼ŠùiMZªUöà¶%Dã¾.;_:Óâ9? XŠCÐ…¸ÐħfÓ½l‹qziò4Ëï½ò¿ -b¶ž  =+½Ö¢gžh—§æ Æ47ÎÕs$&‘Іï>Í.§Ww·‹ùbúiöã´aÕW¢ÁœV]$ÚØNX1Ž0‘´é|ŠÜjz¿sÙªf¡YÛ*…¹+I0W…,‹ÍãÚ|w«•ŸLM¹Üfßš=y3[%ÙÚ-œÖPñxŒmÙ·”ŽYeº\_qÂyøèÒWäì =nl»[Òž²ÔøhÊ:ŽRêEÇçâ’0|W@-µvIºÉò¬¬ŽÂ[õÖ¬¼îyÇ“|—¬À%RÙf±É†ƒÖ‡L ±Þó‚ËéõÀeÂÇ1cÅ®õQ_\ „zCdEž™jyV» 7Xõ\"h6â“Ò[¢žøƒð&ˆ1µ'~1Ø#÷ÒN:‡<š ™m›û>ª5T5BOÉöl»ËJ«Ç,=T„bh"×§5i©úªìWT,a’íë2 —Œ¥)Ë(K{hõ|pÈœñ=ß›_\x￞ˆ™ƒìs{ùnC¸ß² àp·â²ÉCoÚû:#ž ËŽÿ·ìÄO°³P—,#¸Æ-ÿ²¡ð ¬àô—ÿ)rs¸l;£Ã¹õ³/8é 3Ôˆn¥¨ˆ0(‰\$ºÿ%cµD]¯™Ü-Þºý™®.¹ñ;pã å»"/‹m•í6¯b9b\6e’CSE9m¿Ù€e1Æa^îášošË ƒ¤î:ï€{D% Môgumlö»xÖÔÎ_À8ÙÒ¿Ìæ¾œwh¡E_gÕ˱¯>µ"ƒ__p è/zýòÅ¡WRêÈwè…l–Röà„ò~ň2@¼¯û¿C¤•endstream -endobj -2013 0 obj << -/Type /Page -/Contents 2014 0 R -/Resources 2012 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1998 0 R +2009 0 obj << +/D [2001 0 R /XYZ 85.0394 227.6801 null] +>> endobj +2010 0 obj << +/D [2001 0 R /XYZ 85.0394 156.5137 null] +>> endobj +2011 0 obj << +/D [2001 0 R /XYZ 85.0394 85.3474 null] +>> endobj +2000 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R /F55 1035 0 R /F39 895 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2015 0 obj << -/D [2013 0 R /XYZ 56.6929 794.5015 null] +/Length 2415 +/Filter /FlateDecode +>> +stream +xÚíZ[wÛÆ~ׯà#tޱÁÞw[I•V²©O?@(Á™­°¿¾³7ARŽÕ6µÎ1»ÃÙ™ofç²$ž%ð‡g\ ¡‰žIÍO0ŸÍ—'ÉìÖ~<Áž&DqŸêûÛ“ï~ r¦‘DÌn=^ +%JáÙmö>ú)t +’èêìòüMüú/ç¯ÿúÏ·Wç§1–‚àèìúúüêÍŻӘðÈ8I¢Ë³«¿ŸýÍÍ]Ÿjýx~súáö§“óÛN°¾ð8¡FªÏ'ï?$³ tøé$AT+>{‚—a­ÉlyÂ8EœQfÊ“›“Ÿ;†½UûÑI0p‚d ‚g˜!Ê`±׈(I xVé2ÏâùC>ÿô¯ºÊn°AL’B1K|$f8ÓÎ@E’:Ñ–jÄè•ÍÏÖËÇ¢Ìívú7B¤õæ’„”~ü%-‹¬h7îÍ2-ª{÷V¯ül]}ÉWm7ßÖuéÅ0Òœ/'åˆ +&­œ7›ª~lŠflEŠ‘T‚΄!öf£ŽA{ÂÁ.{L‚$Æb÷YX‹0<áŸÕz§±Û¼³aôÐ>v£ÏÝèK7š;xßRD(¤56r›½æeÚ4Žl ÑH)©=UÇq1ÁDW‚sOº¨WË´à8$ë8þðr»Æ KÄÀßgqgvX|SXP¤qÂ<ƒeåSHX":–ûÓQ¹¿ŽßòÛø±1¿Ë–¯zaùêãv‡(QuáfÀ“I¤H"Æ<› ž1• 8!Á!\hÚM™?ßïo^Xûö(¿¬Xåó¶^m&˜r†áxÌôé?ÁôM7úu‚½àHrÊþ&²ë‚‘¤7HÐÃSÛ÷€©ð̆³.ð7„ç>‹ýá¹£ê…ç~è?–A¢„+þœ°¬Æ6zýÂgý¿åcª$”6BŽŒþ•¬‹>šöÀ^½°|/ˆåó1WÈ0ý–8üÿ¸ÙÅMû64ͰÖ)áµ´Ö¼oÎo^ÿrq}{ñöªûÔ°ç‰Èd!?Qù+†‘]9i(SƒÓ¨}°<‹šMÕ¦¿»É´ÊÜdQµùýÊ—õ4ª~Ý­†N€úNZ0 +ÙEë&ó• ;Y\ÌÔV¥Í„ž”*„ àZ='´‹!£ô(Feun˜+==ä••uš¹þC95”SDg˜D·EãÖ–é§|J$,¹IJª/Ò1è%Ñጬ›|±.ݾ ÛÁ ×-ÁÎU˜w¨zîrCUä¡™2ë÷±ËÍr3ƒ²zÁzµm¶ò¥Qk7J·-Ÿ5ù +:´SÉ"4ív:ôDÉ=)vW{ÍÁ"œ;.lS,‹2µÚcè'¶‚óªÓÏG”NHˆ¦•U*º[·n¿¢u[¥åSºñ2dëå£:ׄõ½mUÛ¼jAí?ïÅÌçv¨r4££xYË€«Æ4á]—Lл¹Ô½FZ—V3JeÐPu•–åæclÔ¢X[m,“ÇDz0îaYµ«bÞ‚íì’…Ê-”ù—¼lÜôÝÆ=³|‘®ËÖð#ÆÕ\ë÷©ÂåØn­ßQ™}ãl¼%+ÑòÈ–hbË>Tj~©F[žWé]¸úÊò»õý=Z´Ws …¨yXñ-ѽ=‘Uûa¯ÚöÛj=ÞoRéÞ~×LÚ­ïÙÁºI®—Ëtå/}‘DùïE»½EB(9 LŸj?2•…æó>hnÙa³»å8ƒ-^¹GÇVŠvoAW a©®|Tßö\Ó#èô¨ ¨,:_vÐá¦~:²e šØr€N‚8MF[NùTMm\i¹/ªAGÕM"¾¦ê¢š†ºãÑNõý*]~•{Ð@svÄ=ªTÖw @%RÞ2Ml9h[üépK—m*êJà¾1¦oõ]Á™f#âõzU™tnó‘·\pq€´i›½ b-†°rÔ>Õ~P;* j¸±áÇAP¢í\ØôÓ) =ÆAÁÑ„`t°( ©JvcRøb3Ñ ³ãü5L7…“è¯Uu»S¼ê¾›aWæo‰&T“ól¿))䑼ԧ:`Š@eMQL˜BC+Ç娙4tJJ+Mˆ5è; ë2×(±®]C +¸2èNë¦ÍYp¯¾(eƒž×,¸&ÕÔ‘JG×uÓ6ñJ£Dã¨RßšMd2¨Ö¡‡5V‚°´ÖÚ[†Rý-ቯÕaˆ_M°g %JÓ÷ØH ‡|Ï.J9!q×-í²…–Z <þ‚ư+ëyºOzh†8Ãü_ÕîKkÙW›’ ®‰ÝB#ÊeŸsÝ''A‚KÖõ¶Âǯ ù‹a“{ÙÝúÑÍГçµs€péA™i·L`\éò›qn4w~Öô'¶¹ZÓšé3÷Z¯ü+ü›b⨌+ÝAwã(Š*Ï]2´œÖm\/âî[å˜-ñèKhMZ“€ã’>HíAÉfa¢ÆæÞgpeJ¦¶>Ú~™ìCÚå»~bêád&ŸŠùCÝBæ¾i½S¼Mt"ÁÀîŒðçÙß|?ÛÕÇí¯Æwo”¨`~ÝürÊyô÷²ëD|À|´vÏ3÷¨ý´÷&ŽGÏ€bëðâ|ÀpÚñ…¤Ða øŸú@֟ĈêÙŽIIî\ÆH@¸€n²Ìï»6œGÐOÛç„¢|¨ðÚÙÈ`µŸv^±ËÄÍm½Â¼õ€¡LæÖ+¼;HDeÂG·B‹àJÐÏŒ}ƒij¯„ÍZZ6µuçÆþÀè¾\{.i–9aO´{*`ÒÞ§Yöc$ÚŠ±L[ãnÕÞ¦8¶ö(MžíûM5×ñ“ PÒ]|óï…¶¿Œb€§R{M"9„{¡ Ö˜ÝzÎÿ²hWöÉ #ùendstream +endobj +2014 0 obj << +/Type /Page +/Contents 2015 0 R +/Resources 2013 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2012 0 R >> endobj 2016 0 obj << -/D [2013 0 R /XYZ 56.6929 586.3808 null] ->> endobj -2017 0 obj << -/D [2013 0 R /XYZ 56.6929 444.5078 null] ->> endobj -2018 0 obj << -/D [2013 0 R /XYZ 56.6929 369.9671 null] ->> endobj -2019 0 obj << -/D [2013 0 R /XYZ 56.6929 265.0122 null] ->> endobj -2020 0 obj << -/D [2013 0 R /XYZ 56.6929 190.4715 null] +/D [2014 0 R /XYZ 56.6929 794.5015 null] >> endobj 678 0 obj << -/D [2013 0 R /XYZ 56.6929 151.8306 null] +/D [2014 0 R /XYZ 56.6929 769.5949 null] +>> endobj +2017 0 obj << +/D [2014 0 R /XYZ 56.6929 748.2469 null] +>> endobj +2018 0 obj << +/D [2014 0 R /XYZ 56.6929 713.4785 null] +>> endobj +2019 0 obj << +/D [2014 0 R /XYZ 56.6929 650.1391 null] +>> endobj +2020 0 obj << +/D [2014 0 R /XYZ 56.6929 514.9018 null] >> endobj 2021 0 obj << -/D [2013 0 R /XYZ 56.6929 115.5088 null] +/D [2014 0 R /XYZ 56.6929 376.6996 null] >> endobj -2022 0 obj << -/D [2013 0 R /XYZ 56.6929 83.5219 null] ->> endobj -2012 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F55 1025 0 R /F23 726 0 R /F53 1017 0 R /F62 1050 0 R /F39 885 0 R /F48 940 0 R >> -/XObject << /Im3 1162 0 R >> +2013 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R /F55 1035 0 R >> /ProcSet [ /PDF /Text ] >> endobj +2024 0 obj << +/Length 3046 +/Filter /FlateDecode +>> +stream +xÚÝZK—Û¶ÞϯТ Í9Š',ñ8uOÜxÒä4É‚#QO(r"Rž¸¿¾O‚IkoÚ™…@ð¸¸øî ÿd¡ÂLó…Ô LÄb½¿Â‹÷ðî›+âiVh•R}}õ×WL.4ÒÍ÷Ûd,…°Rdq¿ùeùâíÛÛ»—¯¾^Q—_£ë•ÀxùæÅÝ/¾s}o¯5]¾øæöÝõŠÈŒ R†,ÃË»on_®nþv{ó÷}w{ýÛý·W·÷‘±”y‚™áê«_~Ë ¬áÛ+Œ˜Vbñ­ébÅC‚3zª«wWÿˆ&oí§cÂL!¡¨‘e‰4†6ÏRh”1xe¤ñðÑ­¹Û®±Þ•ÕVË¥Ùf‰0ŠUriæ7#üJ)¯šu^™†§N§edBuSWÃDÅú÷ÖµïÞ¹ßÃ5QËbÝØßù´+×»ôý¶8x¦÷[Ö«7µ_À®i»:ßþë&ÐîòεÚfoWµX¢‘” th!-µ,ºIþ8–®±q_½¯Ž~‚âϲíÚ¯N‡-#»E}"SËNqøø¤¥'ÌÑ»¦Y²Lb`N!F¥°ÌMl €s,“-Ù«jÕ–UY¿ŸØ™Œ#ª8÷åõfd`Qül¯/¬ÍD`gS¶ùCedÁØÒhh*tG4@ïñs¹Û×Û€8Oeë?pÂ5‚pEÞŽ,¤‡a“¹›L"šXÕ ¬.‰† É?I ¨§v k‹uW~(@%!K·á+Eç˜?wß)IY¨8SD¸"ÃMiÏÔßì:3läßf™BÒ`fÔ*{¢UJåì±Ê‘ʰ³Ú:Ž…H(ÁN)&<ÃÛæ°];aŒ0 ÆOñyÎ"Õk 2™–CÞÞÁ6•ÛSCéùqFf{ò²7G¿bL«ÂÔ·Mkð?Áï@ÀúÈsŽ8(wWüÙÍ"WbhoŠm~¬:h?Õ(œÁ+H-h2Ë!ššD"B"”¦Ñb<&êZª´*‹–W#hõf\² p¡ˆ +PÃYÖ"ÕoC¸H&H ™‹paŠ;D0Å"\L§‹éó/¡ãØ=;×éãú(MGa\²Ñ#¨´uÄÓb„"ƈ~‚@W˜"“²S"hÅ$ì)&lèOŸ%¡dõäxíE H+–yRãT7+k¯¬¶­€ LƒuŒ;xßM¬_Ýx=^çǶJâ¾Ø±nÁR{êc f3xpÿáæ¸l'mÀº©»¢î¦ÍªÐ8Ì V5!šV“@dµä÷q-QZ-Ù{·2Њ‘âb–©@sÎÔ@?¨@ʼM¹z[ lGö—ÃJ M½™ÝÝ• Ÿ&à#ÁY’`ˆBð]>•ÝδhÐ2’j“ëØæeu 1†é0â0Іù@ÑÜ‹Ö 7c¨%GJ*‘Fa0Ãç+ŽÄVôT[z}‹^bÌZƒFC<1Ô…fÿXVÅ„6h¥ªWkòÕXl¨V*YÁS~¨§ŠLgçvâ“ù¾¨Ã"áz·ÞH&Ò (ß×Ía2"‚SvÉ ±ÍèõL¨fô3PYÝ)(GYÆÕ¬‚2”Èäf‹T#œ •|—zÈZïÄ01) ¾Í]¾ùÙužåj¦³Ý5G“ØöCá>°Û[øN“²Y¿-·þÅ®ð³Å¨ß>l6>Vn °Ÿ+ž Tpªéò9…2®õP¡¦õ•¤áïyê +Ðâ‚÷ÎdÄ|w"ìóTçyAù4€ó‹yIÏ<¡šx ²3pùž8G’b1ÏX¤álp†€fÀÚA% ˆ3AøÍÍ8<žöm‹Cëž-œÃ§lycêCÈ “ ÞÂÙœ1©SÙ§ ’Í 2C¡Šg"2CY¬Òœ}†ïé cÉÎóë/a{y¦‘8›‡fJ5 ÍHe¡YVp4ËWŒŽÎù ŒõÙ&cÖò^“¥5¾æÙÊ)”1¯!xð5‘h|mͤñ„…¯ä›g|ÏJ.§Æ—a‘¦°,ßÁ—c%X§²Ó +Ì º%Ò\|àâKEú,»ÐÿÿQ‡‚ÄòBrŸRÍhf ²šÙ\NîaG”δ“sD±äóÌEªîúÉMñSÉ!{?]K¾<”1ìŒø,1Ü'ñ̆9v <]-$AJÆ`º†“‰¹» >æèAÐåëíÈ´Dh~yHA ÍŽCÙŽvœDw±ÓDe, t¶Îmû¤á*ò¦«íŠyôœÐÒñ ¹·¸¡.}ÜF!‹Ë´C±7CtÍáãœædâ +“OVy} ÞÌ`S+³ðN©¦á©¬`Û1xcD ²o»Õˆç5›Ír©FX–®0"“!o½ïQÚ24öìØ>[èLߙ‡u/Ðé ЊEONµóàÄœÓ㵎r.›&¬Ö陯tÙ“ÇXè< 63ÚÆ #!uqŠ*7Eù‰‰Œí±åKöœB¨eR­4ñ¸·u¦–†mß +E@h;%PàB[ßÓËΔxZ×x´"jÖà…íÁ‰éË]#•ë¼2çi¦ëÁÿæ~°â1?ä¬]ÊG«€R,¿¯]g´G+ñ´)Y„öЈÜ“‘ëéWE–Aµ÷MÌâ wwe^¹ž|ÖèüÕà³nwl½9dzy ¼,6eçAüª±åÔÛ—ñâ!—gøXÈæÑÚÙ²¡Ô¡l-W6”*– ¥öeCh ˆÐˆÐ.ý‡¡l(ƒFɨEÐêˆ+¦³åëÎOQµMŠ;3òÌv/–5wù‡Óªæ¾Èkw gª˜§ÇÁ•žs”§SSFž6¡8CZ^*ÿ§T3&4PYúî³b÷Y¾bì~Î×hì>`,$•Â×5à7w?ï~¸bùO÷p–YŠ“Ìh¬'í¿™¥d–"†à–v&³ÌLmõ f–T°çg–òÐÉÔÒ0>Z2ÂÅùy—`a÷dŠ Ñ48‘Åf7z xéÃ`L\s½B4—16ËY$:gm€OH)4—”òv³s®Äh/Ãz5‡ßýå}iæø1¨~ì%k©¤X컪¤VßÒ³Û¯¶uOí3”ÏzÍ/o/¨ñžUÛ»™-ªß÷U×3Ä‚Ÿeõ›ªqà놞ï^½PR›pÏ‚HF¢ÚÝU;4f`ÝTž..oÈ/Ý9X€H/‹Í¦½Çf”ºvoëjÜ»ní³´ScÚW<©(K‹/4a¢Bë¶í¸²=í–WÐã϶©hþ}Ýß ÛîmÑìµz«Êº¯›kzéox[ªH¯MÖ`êOíiE¨',ßTä œ!Âöˆ Ô±.n´M_ÔÍ£iõXÀN {l?Mï["¿õ7>!ïT÷½Žê‘?xCâý+@d´²P{jn3|Ù7%ˆ‚m–NñF¼ØPÇ]]ÌhˆÌÀ«HcXð?§!I¤bá´·å= zœýøâœZ,›Ô^oJj7-c¿bÄ‘ß®è „c2,•Ž£,1YÈâ7Vdˆz s|´û0KARt½f^£ÄQË“g^»:ÁçÙE_„R°â‘MÛõs¼ºD™ÕI>Ãì¡w¤bØÉL…ÖÀTxaTI9´NõpÌRÞÃcÕÃ{ÒÇÖ‹ÌÄOâ°Q¹s%7ÅcƒÀçŠßQayîèÐ2Y®nFJš‰C%FÅéâÝ `±­b ’ÓôÔm)ŽÏBßðšmÑõ(`Ø !‚·†ÐÑS.êÀÖh<¬‰‚6aèjñæíé›—Ô´ó¬(Á„ö*@C94ÓCöâçÓ§ª4ŠÉL,ƒMíÔpYΰG¢Jçh[ˆ Zd„óS|r^<`½Ñ‘ÉÓìIœ×:@W;k<vÍ{”ÕjÍÛµ%²3‰s¦7vÞ’±¹zsO¿+ÖÖ ˜«v·-gò¾²~ÀN¼aéÏ…GŒ'áϼ)ï¼±eM/Æ6x[”ÕD¹‰Èí¦vúÏL«jrcÐ3rcã•ì‚“Ð¥ñAèòlŽÇqÇ>îr<¦ూœåIÚ f V4Ó ÝõÞÅÕ¸™3®–Ý×ä“ ûØ(ÎPC¬+>/ÅÌYšÂÆ^dzŽ4$âI.0žìŠ5‹MF¢¾nŠ~Ï&–ú¬;dž5P𤰠[ÖtÁ³ØÁ¬I®sÖ~lø(ξ`gA1‡ ùÙ °'./^ÿ0ŽÌ¹31Ô×?Üò((ÏzW¯* KklX˜Å ½0Îüšìÿ›€dþäáMƒÖ‰¶ SÒ·aéÕœ­³ç]J89mCz$s w¨¿ GwÃ*YÒ0&rö½§qR]šIœ€ Ó“ÌN|~jÚû†Ø* ¥"}J £áNöìa¥ã$B'õ¶…¶X¼Øï÷¦ô¤”‹g0 ô`¼´‘Ir -;†ÌáÕˆán³Þ=°~ã{±¹nwàÁ·ø/®ËØï¨­­GÃçoN_,ßœ%dqS¯o£äÂvóÀTj@ÛsÉÅÏͺ¢[8ÉnNŽ=fh-Ó±ÓNƒ­pÌ¢ýˆö3ž ¦vmmGGƒ÷õfCcME+5ù|è©€}ã «éªMe£ºÔåœLõí®&/‘Ži9#¾˜ic÷"¡Mê{H¡ ãSõÀsÀhPkd@ȧÁ´ª@Âã(ÑŽ¤d`ñÊê(L©›®/€ÄÏÐT$ u_¬6­âmœÚAž¡öÕöìæ˜rϯ&5Á§KÏ´š·ÎYå:sÒÿ¼ê×ÏQàËBæ«eÉa;“òô®¥MØÝj>Áfìµ×Û¦ Ñêºvͼ–ÉÎi˜œ„$¢Ð 5QŽÅƒP4­oùX{0Aæ _pŒŠ×çœL—%æŽl”çgÂŒ54‰"ÜAvݬ¢w{X!Sµ€ü%t‘ÖZ#ÁiÎ׋=#£àd;˜ÛýjcsÐP+/Øi-G{½+noÈXHúÑcªEKs(‘U½‡N{2 v„Îl™¸-ãÅvo“gèZñ´®o½uÇ6†~Þï§—ÿ¡þ©/ÂÁaîŒhÿé³f+O‘Ù¨ýI±Ø4ÃÅ’Hö$ïDHeëÂC›ºqbQÎ(„aà²'+¦ÝF§ã0h‚7E"ŠS‘AÑ—ôØ—÷º¡p0Œê<Ší.T{˜O8dì ×îæ">˜¥®¸éJ¯ŸƒâÒE‰µVrœ: Û‘qAÅ…Á<à8º7FÐÄâºj\ú¢¤«O>bÇ£ÐF¯èl@h•F‰N'éëÔöCŽ<ªýá‹­ýAç*y¤*¨b ieuUì7=SЇ-çÐQ‹“Ì›8BÔêèeð»ð²Ý÷T;›±Õë Ø¢;›s§rñËI*g-bzH28¸ùgG&ö¼&ÔžÍâH ¥ÔÏë[Ç2ÈH -[|Lž§"•ÊÐE¤Aª6^Få¹Ë¼#Q*ž» Ñ -÷6˜Áh«íx6@€’+¾‚wr9ñQè_´RN¨mŒ´«ŽC²žå΂üô‚ÿ;úV&iôí_TVÿ;_y7OL™æ‘ ½EY&Êp ›BžöKJôÎÔî@ºP8c1à7¦\¨ì±Š2™Æs(2Ò$Êtœ†Ðgw>µ…xJG`ÉÓè twƒQ•»ÌYŠ -+E˜™‰xñ Eh™< ×2‘‘^Ù¹4ÑÓ¤aÚâì %)–ÖâH‡Ž'Ko€JZëå“Êš±µåI¨±æîU"-=;íØ êö^k¸¦ù”ðFc‹6€«OçÝ¥Jrt!ac()‡j[(™Û8mF%ämJ9 ßóxè›ê«¢«LLUµËÀ{t‚uO±Þx{‚:ü{o3|®ÿ9͘±˜ ëÞ­’+=5˜ÑŠ -ìPÖݺÝïŠk+,1Ö˜¹­]{7‡&p SL^–Mkb*ÑÃàºÝn)Ñ€¾MÝpÚšg`6ÀÊ…Ï‚¿Þo)V)Elð\oª#|•-úêÞ–]•+»Âø¶x ÑÕ‰´¾ -šwuWÛ¤g ˆØvßßÚ!˜9²å0rÛaÄ*9bÅ©»1ŒÌ†šðJ¶í^Øz12µ½ß±ï+ÆÍåì£nØÂÈo8ðën GüªúžH¼?äCµN]ØGÄÒ9[:lQ2—»›Ç˜¯ §»­Öõ•[@IP=°tî„50=1Ú1zÄè0ˆ±¼6‹× k˜–Èz˜Ä)ˆúÓâ5‰£ðû³sjX‚ÚhÔ¦ŸjtÛ¨•¨ý|g•F·eH³¡¤”"`>ÎõYH¼õ†5´ -1B’ö¬×àTÍÄÔ‘Þ°ôøå“ R•û‰\[ÂÉÈOê¼|ÁË8VNjé¾ÜЉ> " -\J*¹›×==­Ã6kà22¹ÖOâ¬ÖF¬ èá9[S­)_çk-åY–N -¡^ØI‘Gw„¨\A °rWÒTL²ÂÍ“‹~Íw“Ö¾¶îB-Á˯3KÊ×}–ý³$ÌÔS³@@íæÚ¸ÂÝÿ¨·û-÷Ö[î.xÅ`>ÌD° cífõÀJj­ª«áöÞkžj«¼(ª)[ŸK‡ÅKù¹f¡…Œ“ž~Gn³mJkÇ Tøµ"g3ù$ÀqíçèþœõÀLoÓøËœ¯`G†AH÷óìBÄSvˆÄ±C8v@i148$°ŽP`¥ãRl"*µáĘp8©£§và…T–þŠzÿdJÙ`.vv;\Wã -D_xîÉ}þ{6÷¹ß=ùmÆ×yÍ~»ªv¡ú-¼îد›¾JQTª|H·›çL’ˆi1Cá8cœ™7# ß%‡¡‘!†6@#™q™À°ÎC§æY–)ð>f -~ÓÐw4’¿91#[âwsŠh|õÒØò±S™LéIòúÕ–Ff¾†0÷±˜„P¿OœýX, 4ä”änBÕ(x訣àþàëÅB¡x—|«Õü”H˜¸{}œi/¼ù²=t}µ¥¶«*š¨ \E®Vf&× 3ôI!®p²óŽýœP›9½É"!39úØãW` ¤ÿÊ3”»ÚÞ- …uÛëÄ–DÁúŠ& D᚟a­ÚÂ×ja&Äx³…›UÅÍϱs©ó> endobj -2026 0 obj << -/D [2024 0 R /XYZ 85.0394 794.5015 null] ->> endobj -2027 0 obj << -/D [2024 0 R /XYZ 85.0394 749.1471 null] +2022 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2028 0 obj << -/D [2024 0 R /XYZ 85.0394 677.0612 null] ->> endobj -2023 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F41 925 0 R /F53 1017 0 R /F23 726 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2031 0 obj << -/Length 3132 +/Length 2003 /Filter /FlateDecode >> stream -xÚÅ]sã¶ñÝ¿Bo•gÎ >I oÎÄÉ\§ç\Ͼig’{ $êÌž$*"uç×w € EÉ—¤ÓŽgLp±X,ö{Añƒ?>Óy–[ag…U™f\Ï–Û+6ûs?\qsnR¬o¯¾ù^3›Ù\ä³ÇuBËdÌ>{\ý4ÿ6ã,»l~ÿðþíw·×…š?Þ]ß¡d>¿}ûöîþ»×ÿ‚wÍ0›¿¹½ûw‚½½¶b~ûÃÝÃõ‡Ç¿]Ý=F¶RÖ9“ÈÓ/W?}`³œàoW,“ÖèÙxa·V̶WJËL+)dsõpõH0™uK'E§2²rJÚf¹„)”ÅãSgbjÞî«e]nðEÏ?—›c…‡ûæ{ÅE‘‰V2·öSõ¼hÊÊ{)›](XïVõ²ìª–¶êžÊŽöñ®¹™¯h®Þí~²}jŽ^x.mµ…«óº%ÄfßÕÍŽ¶å3é¹~fLTŽÏÙ Eƹ-`Ä3«µp,n›®Þo*RpWo«6óçⳈ¸†ÝH8¦•Æ-{}ÿöý#­ùþÇwonÑ0ãº^° ¶eF[·l×÷+È”äT&„.¼äœhªr…'…Q ×nªÙ ’(t¦-÷Öõ¦Ú•ÛjZIÖª Íæ@„ۮܭz„]AêÜà®\>tÙl·€éQ<ƒp®ý¦®<Ô)ðk¹ì6¨nXtSï*¯’Ì…ó òÒf ; -w×BÏ8ˆƒúÝ[z#vÝŸ¯ñ$ºÚÖ»ºíeWöëöÇþiQ¹Ž 3„7ÝSuh‰@BMÌ«ghì•æÙÂ×f~\¢ñµî lhSŽÎç{¢Gÿ9Ömíˆp6_>UËO-a¡°ðÙ=…Éf×U».L¯GÓ¿ á --î©j+šN)¶U)­jbÓÓ(;Bg#´Ó¡_>u*`DäÒ›fÛÝ`‰JÍ•‡.²Ÿ–Pfš½{ô`À ÄêÆ¿‚’ZZßxXí—–‹d@sÑäÝŒ¼ $ø BÓ3ãûöØz2 ±­:¿×š&âàÀdˆ°,BX­ÇA§•#n=ßðìz¶Çå²r1KI;ï–z”/õfC£Å€Ú¿«eç<ÈzÖl8,* &§ giL¨t]Ö›,NXH5 `âîsu·•EÞÛ~Q O“@¾%â´3UxþV]sÄ¡9Ë‚‰m=  S\{J.¾ Îo4Ýø MéžCôìÜXŸ‘ͦù2yîè¨îÊÅÆ,îò•cÂZBv1>;i'è j›õš¼áFI.Jˆ¥>„ N|Qû ÷ªÈ5p àNXî¶nÛz÷LÀ˜Ô{àl!Œ@0¼%ÈbSî>Ñ0ä㣵¡7;ÓódN³"“*Ï}f6§j¡2¥l¨|@÷H/KHöíˆÛr¹Šr™DQ®‚ÀpXîhAå_&V4 “Fœå4¹;‚.ž æ;GØêÖv*¹Ë=. Î‡#bÈÒ1Çs®Ïãx&È¢¢'z(¥BV~òs§iwIE3Ìõu«£OèíKzG1äÖíš~ÊC¼Ÿã¸£;Äà¸" IŽÆ>/¸º«­?îb)y6L@iüÜ…f)Öù0±B&¤íq"ù 4¼¹3—YH, 8ŒP µQj®áŽYúj -¹î-_úÒ‘›´7×`«ÁLÈ5€â;-$‡òD„ž#ÄØ (Y‘„ íSPîRÐm›Á›žv­BuÔccŒÆI;44—[ U})²€Î¹ˆÝÔå»C+cÙé 6(;`fßÑ˪‚jeë»9Z+;¨ºÀ[â4ôŒ±Æ‹²¥ÌÒ5_Jʇ'OÇ¥T?MIñŒéQN÷×|ç\‡ËŒ©^pë‚ë,¸6eHªnxÖyDa/s±&Ø8qfÅç>®´<[¹8þ2º­{íË”IsåRfÖê`¯tÄSkÁ¼W˜|PO~}•®n'™€V\ë`Œ¯ï'8úžxFùÂ@‚—:¿¬üë¼ò#–»è6¡YÅ ²öDñ r5ã—H ÏÊ ‘Ѐƒ^í¡ÅÄA/h„Ö[vnÏ»ÍÆÔbľ5½vMð~=äæäëIuò©góŒêÓûîLÈÓ ?1 7@r¹©ÊÙ#ù’ËBŸ>®êAçM@B1*Å vŠuÁ–ÿ†uzm³<ÐÕ÷0ØŒ[ö+k‚—¡w(¨ùˆ™a5,äPŠmÃ’jÒëão¢Œ¿ç‚çãÃën°2¡8Ý߆õ÷vCk ÈÆKVÀK/˜ñi   ÁB¾/ëäÖëF1 –ÏFUÖãäÍ!ñå…é˜Ú ÈY#‡÷†¾ú‚Föi4^ŸyåF-n`©^¹=é £Ïu9ñ=}Y«ØIßL²‹×œñ‚§9L¹˜<†Ê›O5Fœ‹¬-½:éûäSé_âÓ‘šC2k;¹‚˜[9iPãï6¯|ƒ©Yf¬(&>¢¦ -í ¿}œ×¾/),Aý Öý¬SÏ>Úª;Õ?Ý:¹šïCÏð‰Y`^gyq™Ùˆ5Áíø]3ävhÐô…)ýEäS_¦#4¹ÛXüò,é;Ñó F¿9é7-^…ˆÄ1>Tâœ×~5u墠qä*çCùº¢½ÜM±†™ PþŽØ£“f˜º‹ ª*+”ÊÿPSÑlkhACC½€{¢ÛÕ;èFwñ—É+Ð?n/\ºâo‘ŠüHλC@: ‡Ò ÈÖ9H§¬}A‚ôœÒnÅúo’½_(üçË-u‹Ú».EWÀ9ç -8xÁú¾øï¹ÿߺ‚É ä„"Öÿ^DûÄÉ30YýÿwŒp¿¡3üÅà„µ±XFþé&ö?ÀTømölr/ EÄÞž)<;ù©OûŸ0žòþ -¦ˆæendstream +xÚÝYßoÛ8~÷_a`Î"–¿E>¦Mº—E›æbgw¶Š-ÛBmÉkII»ýER–dÚ)p¸—C€h$ g†Ã3e2ÆðGÆB"©©Çš#‰Ï·#<^Á»_GÄéD^)êj½Þ¼gñX#-©Ï–[ +a¥Èx¶ø<Ú™5ã9ÄcPB±¼˜'ÛtÍ×éüÛßEžº¬3@qš™8þþ‚¨IZÕû¼´Þ’Ü^ÓïYe¥²JªÚ½-–öJì%s·é¾±SìÚKjíÚ»EZ¥ó*]xNÀÎdµN÷/Y™¢vvìD>܈I˜‚›åôæÆ¾ú0ý˜c()_°À +þ‘K;´“©y‘/;¯{LwìN#J»¤=¼çÒ€™¸mÊ…OqÈ GZæÞÞÞ][{ÚÍj±Íò¬¬öIUìí£‡téršÏ]Z?&ylî‰TˆJ)ùp^™H¢}bE£{õ8û÷§‡sµø¼Í«tŸ§!Óe•nÝÚ¿+ò²ØWY½=ø…5ä’:;œ"ðûÍ~ŒÝr˜F… ÄcˆÍ¨ÜÁ‹iÄ5g‡%¶|¡4¶R?ÊE±M²ü°øÝéþ2H`îG^ìʬVFP¬ -œ)$)‘¡j@ n*Ìz‡KŠ Œº&šJÁI Z¶ZyKÈàçˆõ’l¥¹šèâ‚Ä þÙ*Zf—èž[i–q§ÛÚ]ì²))„S]¤Oõ*Ú¤ÏéæçÍ.[iÕJÛ€+-äÄ_n’UÀå#E†>ò€½ˆ)€%“°ZÀ˜_滺 YÖH©X-ï^MʶFÈCšà£l”­4 Xî§ð—mò=*‹ù·P¼Ð[âX¨¡ýêõEÌöP»‹ýQ8Gé­_5Z—~Ç —‹Ê£œ>mªìES°`5ÝY¶ð9ú½Õüp ØõHO ÞŸºÍÑÁ¨jØ{\á¸_5¯o¦ïnïg·Ÿî~²C +°rì÷$Ô™jæ$±—kW»ŒÜÄF²u×ʦ]ßMM³\a‹94 ˆÅx²KzÍ+ÓÅÍ:¯l2’¶—…é>ÙS]e…óº´Þy»¾CVzo:”¶…ëùvµÜlz‹•åËb¿M¬Ñ¦÷»kˆ`—¾.»GÐl˶۲ËVä—>aš1ò„˜uŠmüc6~4ð\|³}BM^²j]Ô•}“4Á¯êmšWåe`‰ˆ3ñùUfc¢—l³±ömnçÚÍWC\&õÆÅuø ÆtUïÛ©‰y„+‰1⬭oÒjþ¦‰ +™z"~À/%S]V-š4î—½n´&Ã?Ý˳*K6®&U2\‚ À&ukºôÔå¯:Ýgi‰~¢Ç~jöÐ1w ’ª4¡â|íjy¾}ÜE[-ã7âC—Þj¢Î»ôJ—½: b ¶çò±tø¾½æ~7l\¢¡gæ}†ÝîuQ:>³…b–åîqæöÈ<Ù%O›´ÏÖÁ…D¡‚ P«ØWp›…!™4¹íf¥PÔˆ‰ØÓÙHž4ã÷EÒ=lë +xl;õïóM]fÏö8D[R«WPÐÑ:ƒ¯u<ˆ‚s.(8rDA×eòþÿƒs„)D}]­Ó(hµšÀ=cÝÀÍažˆ0aî†GE2ŽõùøZ­@€½|±I¡i?Bšc¦C1˜Tê§bQ*áYQb¸†Žh~܈Ì[׈9ˡΛö`´6ÑîšÚekD"€ªS+˜pº×Ä^vEYfOA&AFc¦ü½” "qË㋃‡ Ô]- +X€Í˜‡6—¡U +áX’ã¥?ƒc…(ç¾r•@ç6މ<¥ýÏYÉSYlêÊ=Ý%ÕÚÀîtuÁ1J¿R]:Zgª‹×jªË"T]RZ°ð¹¹_]Ì—8¸Ÿ¯Õ +د.P±áI/Àió¹D»…4Â"I·Eþ¯ÒÝ™è¬hCŒ¾lÏ \ ¦É©ÏôôYö2ñäÚ Y5¨o"Ú's³éŒÃö8`êNòZ²×™:ôc_/ŸÒÈb"†ÇúÏEí)§¹ƒýTøž”ƒ&íSeˆ±M•%ÑsG¯KGŠC„|0úJs;蜟Ói ·<¢7 Š-tõ3μʑ³Á6TšSÇÙC=<Úùhs0x¹ti]Ùe­ýœj3”š³&1_ðÜ×»ÂÒk ™ýšc/:õÝß|Md,4=ÜžEþëß¿ypsPT4œ*ÙÒ » L®åÇ0p¿Çþ\¹$-endstream endobj -2030 0 obj << +2027 0 obj << /Type /Page -/Contents 2031 0 R -/Resources 2029 0 R +/Contents 2028 0 R +/Resources 2026 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1998 0 R ->> endobj -2032 0 obj << -/D [2030 0 R /XYZ 56.6929 794.5015 null] ->> endobj -2033 0 obj << -/D [2030 0 R /XYZ 56.6929 699.775 null] +/Parent 2012 0 R >> endobj 2029 0 obj << -/Font << /F37 791 0 R /F23 726 0 R /F41 925 0 R /F21 702 0 R /F53 1017 0 R >> -/ProcSet [ /PDF /Text ] +/D [2027 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2030 0 obj << +/D [2027 0 R /XYZ 56.6929 752.1483 null] +>> endobj +2031 0 obj << +/D [2027 0 R /XYZ 56.6929 689.4255 null] +>> endobj +2032 0 obj << +/D [2027 0 R /XYZ 56.6929 626.7027 null] +>> endobj +682 0 obj << +/D [2027 0 R /XYZ 56.6929 587.9664 null] +>> endobj +2033 0 obj << +/D [2027 0 R /XYZ 56.6929 555.0457 null] +>> endobj +2034 0 obj << +/D [2027 0 R /XYZ 56.6929 519.5738 null] +>> endobj +2035 0 obj << +/D [2027 0 R /XYZ 56.6929 453.9292 null] >> endobj 2036 0 obj << -/Length 2472 +/D [2027 0 R /XYZ 56.6929 370.2609 null] +>> endobj +2037 0 obj << +/D [2027 0 R /XYZ 56.6929 265.1402 null] +>> endobj +2026 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F53 1027 0 R /F55 1035 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2040 0 obj << +/Length 2882 /Filter /FlateDecode >> stream -xÚ­YQoã8~ï¯p—­dI¶ür@v¦3˜½™¢×f=ÌöÁMÔÆÇÎÄNÓÞ¯?J”Ûq’ÝÛCZ¦h’"©”ÂFþØHIBy*FI*ˆ¤LŽë+:z†¹OWÌñL=Ó´Íõóüê§<¥$£x4jÉR„*ÅFóå·ñìööúæÃçß&ÓHÒñÏd2•”Ž¿În~}AÚí$ƳO×÷𠣆/¦ã›û_o?Ì&‰ϯ'ó_®®çÁ¬¶éŒrcÓ«ot´„ürE O•íá…–¦Ñh}%$'Rpî)ÅÕýÕ¿‚ÀÖ¬ýtÈB*"#¦R’XñtØa”P ˜&\Å’88,bCó\Æa›­Þêèš·×í¶Ö ¾,«u–—Ó2[k$|[Y]?àKó¶qäeÖd„¾»¢4&‚K6jÛtdyà0·Lç”Áâžíó•6jú(Û¼x›¥ (0<ÆXëa²”Bʾáà8@ªûƬu(Ñ™Õ"Ѷ^†ÛÈ ØÂ,Q7òŸŸ†Ð²^]Øê1‰÷[}xs²”°øb鳂¼­¦XEœ¹ÊV½äK½|gH²¥C3iÁáf?gÇÎx4ÞçEÓ¶uõ¢—Ä@¡°@`§ò²ÑÛÒb,¼¬²™.!ºˆn ‡ô®‰ }ɇœ+aH…º€]< ÖK/+×ջͦÈÑhFO WJIDi(ÒM1ä~JDÔu¿1ü¹DÏ¡÷ͺJ¿&ÇâÂa¦Š¢Úû%C‘ÄÔÐ €Öc^äÍÛ„‚ŸÆh§¤H.ÀÊé ª8¦>¨dËå D1^ùûÉ8ò¬í騸~7'Ru¬Ÿ-MÒò› x”zor ßÍt7ß‘¶Ï›Žl©0ƒz£ùï”Fƒ 1hÈ?Ÿ1,!)½ê»Á¢ ›š™cBiÎgz| I¸Lø$é´›'³Mʘ¨(:Ÿm-¦ÓÙæ™°{®ö}Œš™s*ӱΎ˜ <†S[[釼ÞÙ›Ù‘Iìú,v[L‡²AÂZ×uö¬ÍVVv&´y‰ -³™ÅÏ A'Îö#‹0Àmæ¨íôBB^.ôA*"ƒ8½2¹á‘M—ËÓ±c¦è^@ŠÓ™Ø9&ìÆ1麱ƒ½Ë”8«20ëìÆöu -³m¥÷ ÔA)úÛ`f'p@p (ðÙ=MP^²"𛣊¥›Ú…6è‡Ç"+¿ã°€ÓÍI'‹22J.ì6×i7.ÜÛõ’©ïi”XÅÉy½k@qÇ×QDâXu·öIÛÝ΀ÅÓ¾€¦IBµ¿à‹×_x.‹aúq÷|ì -{›ñój×€ÞnÚ)¢( uGñ|]æn[ú*î»n0ç2Æ5‹œ“$†ön -ý2Pn>ýYã|ø¨¹ †•¦•kµ^狪ðâ§"ì Ö u¯±èð´â Þ¸ÇÆ8M.t7Ʋëßf_o¿\ßTjê0áî/i, -Âñz½)ìzTë',’[¢ƒô^8™ˆLÿç `Y»FãX5X:½jW,Q…í>AÁ®ÖŽb7.Pò²ÖÛiè„#0 õø@· ¬‡k$«ÁÃ/S œ#Ùí_;ÈÂòC›a. î¨x|S59¢¸¹OÊ?r¤¼Üì\¡±g\ á•¡\|q•§Æ·ÌÉÙfÐ#úbäA -& HᨮúÊ3ä~Æ%î6vi´[Sl9sù–°í¤Y3 m­oüÞ IÌøÒî%}5Ôut®¬¡˜i×:Mì‹§†.¹åv—ç‚u“Ú£$N•]Ñß&ÐIÒNÊõýdñ›±O3®ŠåªªÒ ·™˜u…±SÂl'mÐûaI*”z¡öÁ’‚„vÆb_„·oÛ³Ò^ˆq#Ú<ŽŸÓ½kfWk&·}Ôo/s”± KÇS¶4EÇ 6LEƒÎ0ýù6LÜŽvù×òU§Òc紇ɥ÷ÅÛÔNµsó`¤¡­|j;hfþ`ãŽoó¹û)âw*© æ+l×e TöMMÅoÙ_ñ@æÞòÅw³_:nü³i9$£Ÿ—ïof_¯]ÚUk}º¿š¥ós t€Âeîîô é¦ßÅ;ä0ðç‘ÃLW®Ç_éÅwÿE ’º™½ýRº -H8T¶ Hë<`ﱬ&wÔwŽƒ35è}“´\˜‹&`I;6ÂÎFs4‰„ªàª>àªñŒÚŠ•N¬r¿sXâÂ:*íi•ûÔÞŒ;e„É0f¸*{Ð]ÊZ ê°e¾'W¦ç®wιHpqÑ~¥»—¿!ÄÚ3š -*Y‰¶›qUÂÑŠç /›.E7ÁÐp=Oí½²)¨‘ÚNÀ·…½€T¶Z³4ß}|Ï(HD« 9CúÓð· K«õ'Ò²Ú}†·žP–m¨-­KV‘½c1³ù“³§-´îIÅWë6‚cƒWv§¡†Ö ä ,þQÛ0pæÒË$÷Ũnîï¯ßûÛ?œßD’K$ÚÍÇÝ’¬Auwz•½¸;Ä»»ûÏŸÞéÿ¼þ·`[; Þ…½H îžúÑ—Kb~©8ÐÐ$ÿå„?|‹„p¥¢S·W‚pž2o”q4‹’¾é’+"FŽmÿ/Ö°Ö·endstream +xÚÅZmÛ6þ¾¿ÂÀ}8-P+|§„;°I¶ÁÍ^®Ùâ +´ý •µ»jdɵ¤lr¿þf8¤,Ù²Ý"-š+ЇóòÌ2_0øÏ‰Ž™LÕ¦*ÖŒëE¾¾`‹G{sÁ=Í2-ÇT/ï.^|-í"S#ÌâîaÄ+‰Y’ðÅÝêÇèêÝ»ëÛ×7?\.…fÑËør©‹Þ^Ý~õ-õ½»LEtõæú=¼*% ¥HfXt{õöúõåÏwß\\ß âŒEæL¢,¿^üø3[¬@òo.X,ÓD/žá…ÅÔ“­>fuG  +Í=×}Õ•›Ê½z÷}뫞OP7µ›"/Á}D±òà3±z)3ƒtu¶.æPl)S%÷°æ¹tùP»Ã ૱ÀI»b».ëÂw?ùFݯï]úW´¤Eù©gãñ¥¨;ê Ä|g7§ÙqJô,wàíÍõ”žiéWëëÌå ¤¡šÔ0Ùàxcvm· xâ.¾òe‰/u ûU~F°;±‰Œce(cîÒ»]G–Æ ró™pQÇ@åÂqs67Ͷ;ŒF'JŸ–+ÍÈ5­? m +³'Ø·eÛõ®t_ûb[?äÛÏ‚€µb‹;ªóiðÆ[Ù–3î8°¦Þ±*2PÏíH$ׂ³À1›jkc©RqÚ¦cªã6¨œMÀ3±M@'— D3KNJ[ÃÍtÉÿ^ZmËÎ+%”‰Øöe¢Sc—u`Ö2oOÔî\i@±+Ý›~Îp2"ÇpO|¡øTv +çàW)ÔÁZGØ4ý-é^&îÐy$árÀî1'Ž‹4/ß 3öj‡ ÝRõº4cµø„þ z4¤"¦Rã6~;R6 H¤d±–"¤ø_. ‡r~iDt} `*…N +Ч”k·øâ×…[!•D5j»Ýî´à:^ܬÅâu{ZŒ·8/ǬݾŒ›ŽjiÂ@‚õ@g' +$5›®$ÛZ\&Zge]}öã~¬ì.ÚŽÞ¨NµÑË›Û×4'¥ŽUq)YôñR訨È~ä´À >Ó$h õþº¹äÚÏ[ÍåPΪOYýèŠ5xq'^xfôxè»~[P{[TE¥6p=pW…éW‚£ŒâË|L&ПÌ-ww_KdçSe"8€‡äf'!l röþ|•¸Î>-Û&ÿpX*jµ3‹ñ‡Ù)PÍÈ7É#†Ãy:𪪚ç™ ÔbwÒc%”‰*Qa'áXÕ‡³W¿™âã$¯iK92§ZدõE,ŒnA€ªèڣ𨘕J’?¹Lce…ú¾;L9ÂØ8µFHð&<0rŸ™fNkV„óÒ•ƒÆïÜß[–7C[DoŽB¦„Úsk=d29¥&Çí#)OAæ˜õ È”Jø4ÓdšÐnŸš¾ZQÛá<ûº.ò¢m3<šÚAï"ŸÃ1x¡òó2¬ð¶Î~A +@­²sÓ<#ÓÑÔáÙR1…W ÃÀ,bâáEbIbK)±±7'©±9‚ìšq8ò”¹²0Z?ôõÜyæ¢ÉܰwT½Qmªêýøú8Ë-÷i9™\)/âžµ‚£WU®K,jPnÀ]).]¯ +ÒXõÙÝáhûjÛ5\½»‰©÷æ’G5Q%~má ãWl‹Î/…IpF±ÏO¨'ÅŒ+âAu*väMúxìáèý^~@õµÔ&M`Ž–o<5q¢þCÊ·Ô¨éï‰0ãXñÆ™Œ¥ågO·<FZ$rñÆ¥†b>åBñ6f}¢xã†ÅÊ$ɤxxS3*Þ¬/Þ,™ï)=8Ë/}‡i6z.»'j¡CÍ|*é Âe?ƒå\x¸C ¡¾B8çP óüi 9¸´L;ö¨è†z³uÁE/ôP„Ò÷BèÉÂHC7Ù"Z5E[ÿ½£î¢†|–û[ñ¶ÈûQ ê.ÊkQÞ´~Xí?°¤cA ûiþÓ‚/ýf” Êl¸†¢½þÄ4ð‡Ï( ÀE+²Ÿ³¦ÕØ0jkºÀ|[Q ã† Ý èzðÅ[Z¤" ,«â±ð“ݱÑbjͳ íŠÂÊ#ÐÝD`˜D¿deu<#ŽcõËÂÿ¯MˆÖÆ ¨3÷h +'®ðœsì6|´ÞñËð¡fïÂÇR½/º¾tA/Žd@[0Þž„û7ÝxºŸý€%$¸MUt”ùà}³õ~æ—ÄJÝ¥¡ÖVÜù  l –_ÃS TíÄNºk,2;OKõ2ήÂ?.R“ƒU”JÓi¤N$ò×ë‡÷Á ¿øë›#°!ã|ñ|v?b‚<öØ_†·5 ¼P¸°ñ¾èZ&±N„‘ýÿ$Áendstream endobj -2035 0 obj << +2039 0 obj << /Type /Page -/Contents 2036 0 R -/Resources 2034 0 R +/Contents 2040 0 R +/Resources 2038 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 2039 0 R +/Parent 2012 0 R >> endobj -2037 0 obj << -/D [2035 0 R /XYZ 85.0394 794.5015 null] +2041 0 obj << +/D [2039 0 R /XYZ 85.0394 794.5015 null] >> endobj 2038 0 obj << -/D [2035 0 R /XYZ 85.0394 372.4169 null] ->> endobj -2034 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F23 726 0 R /F53 1017 0 R /F41 925 0 R >> +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F55 1035 0 R /F53 1027 0 R /F62 1060 0 R /F63 1063 0 R >> +/XObject << /Im2 1049 0 R /Im3 1172 0 R >> /ProcSet [ /PDF /Text ] >> endobj +2044 0 obj << +/Length 2113 +/Filter /FlateDecode +>> +stream +xÚµÛrÛ¸õÝ_Á·R3Œbúä4Ž«GI¥íÌî>Ð"dsV"µ"i;¿ç LJ”ÜmÚñŒœû 4‹(ü±(QDn"m$I(K¢åæ‚F°wsÁδCšö±Þ/..? +bWÑbÕ£•š¦,Zä?Çï‰! @ãùÕ§ë“)—R¨øêË—ëù‡Ù¿á=¡€(”ÆŸ®æß®n=ìËÄðøêæúëä×ÅO׋½8}‘(Ëï?ÿJ£$ÿé‚aÒ$z†J˜1<Ú\ÈDD +ÑAÖ_/þ±'ØÛuGÇL yJ”PV)á hülEê ‘Ž³¥Ñ”1EDš°ÓÄüA +ÄÂrdHlš2’“DSÅ Iæ{q‡ˆIŽNJ5á:å‘‚Pæhb‡hH¢$Cœ@9ó¡l¹a[TÒ8ˆ–•¹_Ô¶éNUS¯0µLÔP㥭AM¬;[WíniñMÇëbS4õBI™‰¿•+´Cǯ-³Æ®¿CÐø€tv)jxc³2Pm³¦[Ù q9AStž¶#fÁ줜”jÛUéiV%ˆà´ã¢ŽQÝiç å3Fiå ÷º“›øùÑ–#Q P2#ߎZ‘ò.¶‹@Ò3h19xW¥‡°ßä„–z ak0åÃû)ßÃG ˆ1ÓíÎ +¯¹a$¥œÝêHP6$Mu\%zÌ ‘áû©¨ÚÚ#ð мÈý²j<²©ÂÈxö¯ÇI@¼pèÞú÷m²¢ta‹V(Öq4СÅmq6c Ë@gÁä°ŠJeOMõ ø6Õ^è‘Ó×ÖöcMkŠÂ¥fAHÑ n*<±}3b#ÃË¥ÕÓ¡e”iTÔ'vIJCaÙOm°¼³P›?v¸Š‰‹'»«]òâKÙnî}´Q_¸pa_ŠæÈê pÒ”‰óöéc¶ÏËÙçŸGöÑD+Ø=˲Ca9°^®†,ÿKûÜ·Å:,}!¬ßý) Š”&Þˆ°>Ö vX΂/>;“¤_¸Aßæ'ŸËlùh§+¨‡Ò1m24>+ÞkD>1hºPd…QCo«,(Ϛ̯V» ƒz½ ¢Ä´ÒRŠ~ÀO;¥:-‹KßÀ«îtðÙê`/·«¬]‡8x*ì3NèGîëÑ„Â]A0ý?”µ†9Íü‰Šœ’!Ä10ôC²„†Å¸/ÿ’žæÝ`xåÆã;÷;wól¿æñÍ©±YÂjŒÔal¦Ä0¸"9¤þúÄØ,ÎŒÍ}ÊgÆf s eÆ! 7‰Dï‡\oÜ]7þÍwWX¸Ž O‰s¼Â¥ rØÚSÁ±Ç¯Va§„†j=-å›/@ßÏæüÊøGî[þ¼]W[¨6n†8h»¾”è4ÞdˆþÝ¿ \øÜÙëþžJÀÄyŸ8‡?tÀ¢ôÏÌ?VmÓîöDÖ6«­Ÿ/O5í~@ýPˆþZö 깑¼_+{QßK˜a¾L½¿ÎnæW·_Gj x/ÅPÂâ -Èa6wuªm`‚òô]†¡„Õ_0˜ëÊ '6ܬ«Ö5  +÷á$†•_¹:ÏeU6žÁÚŸñÅ vp +®íºÒ_ƒ¬ý>  kžv#ó®Ì—#qh~PÒ«hÇa×Íò“ÝKpFÔÉùîÕÇ:ݽöXÁ!ÿöå­Ñ„ÆÎ³íFØšå„j¸ûø~¬œá—¡„¶ä`Ÿ]Ã:jÞ'-㓦‚"ôAéç´™N0Òl¾ÀþF,®ï>us¸ÆšTËs2ìqŽ„-b­ ûR<¶¡[æÕsyÞ0à M'ÁÉš)¸åØö ]ïûogèÚ–yQ>tƒÕ÷° lÂ8öšnȽ—­‹€Ô–¹ý…R^ZÞ‡u_ +"5øEüÛçùÇÙÍ·»+4÷böyþv­Xt÷ë™?š‘1RBB³RÝg +((êCëK ^ÙDŒµ»ÌI߇ÖT•_,«Ívm_ün€¹­—»â¾;SvP¸®ýí‰ øb¯GLO¬±}*ÛWA.OÖA°=ƒhyãFýŠtÚD’³ÐS¶»Üµ¥·R°Õ¶È¥à ƒ+ôY1öHGr )M`W‰ ㆠ+©ßö¦E~ÞN];„£µšîãô‡ÿ)ðúO© Xü„¦šƒu +e\»˜Â=ªÖ±ìÂkè±endstream +endobj +2043 0 obj << +/Type /Page +/Contents 2044 0 R +/Resources 2042 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2012 0 R +>> endobj +2045 0 obj << +/D [2043 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2046 0 obj << +/D [2043 0 R /XYZ 56.6929 374.0222 null] +>> endobj +2047 0 obj << +/D [2043 0 R /XYZ 56.6929 216.7302 null] +>> endobj +2048 0 obj << +/D [2043 0 R /XYZ 56.6929 132.6902 null] +>> endobj 2042 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F41 935 0 R /F21 710 0 R /F55 1035 0 R /F53 1027 0 R /F39 895 0 R /F48 950 0 R >> +/XObject << /Im2 1049 0 R /Im3 1172 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2051 0 obj << +/Length 3048 +/Filter /FlateDecode +>> +stream +xÚ­ZÝsÛ6÷_¡·“§K|ûæÆnê¦q|‘3½»4”H[œH¤*Röùzýßo»à—áÄ7wãsñµX,v»$f!ü‰™‰‚P¥z–¤:ˆBÍÖ»“pvm¯O÷Y¸N‹a¯nN¾ûQ%³4HcÏnn¼L#f7ùÇùÙõõÅÕùåßN2 +ç?§‹( çoÏ®>œýBu×§©œŸ½¾XBQjC'b¿8œ_-?\ŸŸ&z~sqúéæç“‹›N¬¡è"T(Óï'?…³VðóI¨ÔD³(„HS9ÛèH‘VÊÕlO–'íZíPŸ*"e‚ÈÈÄ£ )fBiÉ‘2¢4ˆ•TVË‹ ZóÙ/Ëw¸Ð`:Ð`8ƒVXL(m÷÷?¾:]ˆ4œÃòuF}w±Ž ÃÞßz¢ˆJp‡!;ýÿe½€ÝB†r^e»"_¬7Åúóº®n £ÐÀ?ñ´ù_uUL›U¾žÖm§ÂÌ‹&÷2 Ü4µ<]ÔB¨0Huåöþáòêœ6+å=ËweU6í!këU½/n š½ZTõ6«ŽÙÖ£›@Æ0 é#à.#£Yt* +tÂfsöáæ§wï=<'örYµÅ¡*Z’dùØ´Å®¡Â«ºjêC[wý¼:P:–ÌwKF-XÂÖ†à¨UsÜçY[à(ì¦t`D”ØnW ßg„2Q†„ê8X9~“2!êüö§\sájIİï±-·eûèST8VÐò±ª÷MÙL!"?Wà¬:MIísi’ËHí…¾0#€²Å…uw-<Ð×õ¯<M~\äŸuÞQwDü›>‹z\äµG#;‚)d xGvôq³ËÖßú\ :‹ï›b}°ÃF +%Ày;wt3|öÌ ÓÀ˜$åžÀù¶Ü–ZFwpÐ-©õ°\¨$ +¢Ð’}Œ‚C[îŠúؾœ÷Ñà ÁÄ`¹Ôõ˜ïŸç +Xœ$‘™r=¼„+¨õPͳ\Ó)×÷_åzȪ¼Þ厩âŒ}ÂôÞQ¸'¸ãŸ¼8¢´!¨¹ÉùÅòÕûËë›ËwWݨgÁdèùSd‡€«µfÙJ„îÚ9QmMßæ¸Ú•-ѽ» çî@|pî4éïÇ¢i™cÆßA(+Ǿ¬è H +çÌ胪a!ŠÃ=€4¤SÈ4™ßl(À§y#Ü϶Ûú'Ž‹ÔÔGKXˆïj×µýæ¶«¦ù¡qŲ<·òi£t¡q»úÞ5ÜÚšzÇ#èƒqú?”ííØVïl\Ù>R©È˶¬î¨Ðnx€ªæ¨¯m V¸x—ÙÀðmñt»@ë¬b¢®Ú¬¬žtãc_X8.Hö˦òŽÇ¥vãø“ðÝ€‘Ö»Z§õ [äš:Líšþ,@%-Û–¨Ì͆…c•ƒ-X2w‰\mÆ–*îËÌã"Â@2'ºþ%‰©Cç¾5Ï™Ñçü§W×D±q ›½Í‰®j–~Å‚ã†ܸz¤/hŽõ°—#@÷¼r.bÕ‡ ·‘vÞS0U®y³ÑäˆÊ‡á™–ÉÃaVgàòÜ;k³±¬¸e[7­w³nÐjU”z¶»¯8Vò®Õï*XVr‡Îù°Íª¾ãÇ·v©O·X…äšX¿h‹c™:Øßd÷, j¿+.£Ëð\ÑpÞ„àRÄjìšèÆèºa fçbZö‹–Z€éT-U[•ãwÃMÈà/,HA Z¶0w9{uöö‚HÛÏÚt¨oGbH'Æ|È0—ïÎ^ìÔh'žtIåq‘ûntAábm iA;¡²Ï.ö>VAœ&æE[¯”éY‹ŸÈ»ä9òbu¼ãéê÷3Ò)++÷7÷ p®ƒÅÚb:±¹­»Œe–`ð+ +lÇ ›/\â$€=ƒæM‡·ìëÙ†wY^LÜ›ö±c²ß–x׊’"Ô "Ùp$Gáh…ÿ›Mq—ˆ.Î}›¬­»ŒÎm2­è™M–ã¼È¿´t¬Y p†êÂ\‰“9|µû}G19šìã¢o +ÒÜðËfÌ[;86b~ã¹$qZ4¤ÅS8CRÙdk6œp¢¼«²öÈ(Ku6¦#a1 +¾”»!eÑ ¾Ùv `M–2 Ñ¥r¶€©œeA1 =Q +7´éyOÜ,/_ûrO$Hô#¨®}Üs+¸ÏúP® +n°î—(›Q¥8jÃ`~¼ñJàùI¼¬5²V‘bÖÖ[¸V¦Jø–e§‡¤ìõr¹°K·%LnU,G³@µ%¶ P1à ¤ûˆ!„½EÒºL‚ÛÁÇ=:gÁì‹j}xthål{W âï¨x[sH$ÅbE@5ÿéíÙ«Ew>°¢vóíyd¥0ó‡M¹Æl ö‡›ÑIŠ6[†¯½*C$Ú..¿£+#¨¬a9";1™ß â?aÎk0v ß’Ù`z} +î‹Ko¨ò¡Ün©gU¹ÏBmaRÐZsìf4õüH-M±-l’h8‘A"ÛÃLÈö‡’¢Ö”ņ¾…•øºšŽÓgšuZT<ª BU”/³ +7Ngd*Z&óëƒ/Ñ(«¦Í@Ñ R6DzÍVxì4&E‚œ8Œút*a`[ì@‚†Êì.ÐmÅ \šj?¼K±îŠïŠvý])éñ•TBÒ]45ó&Ÿ…‰ À ªêSÈ$ ^ZOw¼‘j{$²¦©×´KX´Ì ¡ÑŒ÷[‡Àe«,Ë•e‰~—±HG‡ãËkî™ç í U`ª8è 2 U<Ù0…NŸ­’6DÌv”ÝøJ €dÄjhHue Ì4رRÚW[Þ€&ÂÂI}wÈö‚"ftƒ¯uÇ‚§¤ÏÓIã˜RªËä&Vë@8"Ïbwl8ß_1ø5mÝa½E0‡uôysñwê?mž¾|sà@˜;­ŸÁj5Í禇(âÙ(zQ’¥áîùòº`¶`$Hø,÷¸äøòN.î¿îfxŠ•éR*Øšp퉷qÉî›â°¢KþÚŸYëhTÙ¶ñ)`á¦e¹_»/Ð.d[”]®?Y¹J 0àÒÆGÿéGè$î/ <Ù§ ¢8qºwWÁ_ââÎP’ÎùJŠá9¦—ضŒR{×1HE ƒ‘k#náü®¨ÜY +zðu »2T<ÉÒ õ–‘!dDû}éIIÓÁ]$ì]$ݹ)MGç&;DßÛì¸m©òO¤lº9ơȸ¼[H[ ú@…ݱ¥»<¼ÿ\oÆîí @"濞FÑœne’çÌÁÀÂE˜~q#5F"1ÚÈo½ž æª_v:J´£ÓQf/CwL‘ ÈDŒlÛçÆá0º¾ô=~à‹Ž”Ú÷61oô~€ÙQArQ7<#ˆä.ƒ•‘A*ä$u¿E#“Ψ%ZÛÎw[¯‚ؤQÞüìÿ ¾Q|ó]óÿ@x½÷+S` {DŠdls;é¦D¨Ç .*³¶°.4Nöò 57vv-#íÑeQ`”NÆþÓ‹‘ȃ¥ø¬”¸×( +RÊ€ïnmúb(\aÍžsðF<$Bó«Mö°Ío×"ÀÜ×p.‰ÔôyÚ›˜϶ &-´39;‹€rÛÙ'ݲ⫠+>ߌlä£ï'P¢ÛNûBçݾ³õQ_á2~áã· ®ôéEÅ kwµàiÈÅÎú{o'ÜT ’)R›ðy> endobj +2052 0 obj << +/D [2050 0 R /XYZ 85.0394 794.5015 null] +>> endobj +2053 0 obj << +/D [2050 0 R /XYZ 85.0394 752.3578 null] +>> endobj +2054 0 obj << +/D [2050 0 R /XYZ 85.0394 679.8301 null] +>> endobj +686 0 obj << +/D [2050 0 R /XYZ 85.0394 642.5879 null] +>> endobj +2055 0 obj << +/D [2050 0 R /XYZ 85.0394 606.8804 null] +>> endobj +2056 0 obj << +/D [2050 0 R /XYZ 85.0394 575.5077 null] +>> endobj +2057 0 obj << +/D [2050 0 R /XYZ 85.0394 512.0134 null] +>> endobj +2058 0 obj << +/D [2050 0 R /XYZ 85.0394 442.4505 null] +>> endobj +2049 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F39 895 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2062 0 obj << +/Length 3460 +/Filter /FlateDecode +>> +stream +xÚ¥ZYsÜ6~ׯÐÛRUMIì›+^§ÖŽ×’+[›äCr,®‡ädȱ-ÿúíF7Àc8²][)‡`£G_”¸Œà?q©“01Ò\¦&u$ôeÑ\D—ïaîÅ…`žkÇt=åúñþâÙÏ*½4¡Idry¿¬•…Q–‰Ëûò÷àÇPDá,¯ïÞ½y~s•ÆÁýíÕµ”±J‚›7on_?ùox×0g¯n^¿»ù'ÑÞ\ܼ¸½»úóþ—‹Û{¬éÑE¤ðL]üþgtY ~¹ˆBe2}ù ^¢P#/›‹X«PÇJ9Êîâîâ_~Áɬýéª(à6R%rER­ÉB›0Q0…²è«âp%² ðž™ÞõÕÕµŠEÐmñÃC…×|ös,&‹e24iÀE®‰c¶Ð¡ŠSÁ,Ý~¨»–V¬{Ú¡¬û¢;ò÷UI›ªÈnÜ×Rû‡œŽXÒÄxäùrýq¿ßÕn­¼ç'M]Óä-ÏíêÖÞéòÌ$B"4ZK{VÚîý±©Ú" ꖞŮ‚IfÁP}F‘©H÷xœoòGšÝ\‰ ¢áǺ¯7»j¾½ºã°?ŵûv Íìû?"P&üO0ëaºF†7ÃWØ|èôòGI·W“×íÿP"ø¾á³±BA1³[ƒàað„¿õdåýCµÛ…žÕ€¢fõ~Õ$€#Ò&s6ñaÍ&âP©4e’–2A¾ë;m*zÂaðÔh~<Óï«¢ÞºÐãîå ”QÄ2ʇêq¶ŒÜù.Þu‘-ýü±Í›º éç¯ïø—û’8`Lvö×±ê‡Þ*; ^¶d9Jt221s>XéÂ|zK‚ñÂ’&×äeõAEfÒÉ|8T¢d™h€¶ÀDíîÊÙ/ šüsÝ¦Ö “sþÅþɲ€P8®tI£Mµí¼•Ã{ͬö¶Jù¦; lW‰½¢f_Ÿò&´ð¡gnÿõtmi£ˆ‚ÿT„I.Ø´srôÓ>á ¹Ö¨M‘P|>²0…4Ùé㸮¾x©H;}Œx¢2i–ö`™qt|É!ÿ¸–F³ä¢©ä©§§rË;IzKÔ/,*ŒÆ"wv;кŒ@ßð'?¬«Fë(Yª&‰œjλ‘ä˜P1€4:"fG´6©¦F%ìö@TÌeµïS­$.&ÛZÞÞ»¢ß͹"L²º`jSy§Éä2$?؈Ì8¾%=`%]{uvMY­E†B$f)j-'Ù_O„œéP á=‹ŠÞÉ,$ïÒB€µÎŸ’ a‚ 8÷€ÕCݾç…û¡jh\vnÎ-%ã{÷±.]„A+KEЊ|ÒPÆÎxžÁµŸÑÑVnŸ@¹-|Âè*Ð` ®ÀeU–ò±.lš¬œÝYª³øÉL(Xm‰i +Eü„yÓQ†Q'ä"Ø3È-.¤dÆþ˜O©óZ¦±s˜ëR¹ÂNùDIetd äô( œÍ‹Áz–r2 )+'5©â½³E)W¹‹Ó8/JENÊÉLæË¬Ár~qGáSzY‡k!cnL—ÌAÇ5ßIÁ8Ÿ’³ʵ<Æ„™N]x€|ÙVd=mE¥î³P$ÌÕ-UʈôœÎ#yçäü¢…‹ cô‰9ÑñÏÊ0ëB¢Óšt"  z¿›€{úDÎ3nQ| +®iTjöòõ›w÷ô›Ÿ}ûê{F÷+ `„õDeÚ|C(¥öàc11/ñ¦"óÒ“>Â)~¥:ÔÆÙû¶WD3]U’1±šú/,Ù`|£NÜ®6»‰‚ÛÜf„謮ÙbYø€c{߬RðŸÁ,ö ÃØÔ±AfbÑ ±­))ýîZêà®CC*ïÞÓ›/B”&kD-ð©~@ØüÈ¿Ûû®·ñ ´æô¼åÐÓ“ÕdPÕ8Cc­èX°ð8¡MÃû¹o /Q•<çÚ.¾Õ}m ¯x¨Š=qÙÆ™p-1œPuÓÛÅô$Ü"F‹{¨lC ¦§+ö¶yF+•5“×°µ:²@‡ Ìît¾‚”%(6Ít'1S Ê—­Ù+öoÞ¾…õ¸‡$'V;þ\S¿ï˜VóOóMO‘æ&™X¢\ +£œ ø ©Ó;ã{sìy™ s4ÕÀ{miâLÏ ûI>ý7jÌYŒZä,†Ïm¨ÝÏþX•ŬX™àý)³pz£ÍlµÿBeg=ÈðÑŒ»,¸Ø‚¡µóÙ亡áÌD+†ºÍëõà-ÿØFIÇ¢I¥éüÖ8 Ë÷¤Cœ¶¦ +Ï/ÕguOèÙør +¼vj^‰š¹Àó¥:]'™­ãšèÙIf8<ØEv;ìÖ¬hÛÆ)¤RÇz€ºÉ^TÍZˆ%1Œw—Ë»sc+õj›õ–ØÇR9o Ž‹M}pâCÈ:‚’ß«"×ÀŸt‡5½6ußSN‘ÍÏYÆ6#†7DÙìòö ]¼É­í½Ùš^–ß fÑNJª8qY¤íC†LËbßFa@g„€¥íW‚~qÚ¼(ŽªI5–ËÅêÙÅI˜²35»òØÎŒ(š¾Øâ¬å©±[Œ/¶[|¾é1/¾}eÈI¡ï⇧³õ •ö>” ¸u“»†Š§Âê5W’M•s¦ˆ ™&×ÙvÖäÿ~òåJ„)Ô+—Ré0ê̇&⹞0Ñg&±ò™É1‘š¹Wèo>Jâ÷}wþ\žG$i5Iúä<Ó鉿EØ\’ÍNtWQ†é`ŽX‹ƒÒi_¼cûÞ„ëf)ÌS;š¡ Ž‘¶ aïzš{IÈßt,|Kz”ÃJõÅFª]«0ÕÁoØ„£b×h̉j‹‡‚ŠÇIÛŽ¸}ÈÂW |ðœÔ€åZÇYÄYGþ»ÁSI©•ŒÜI)pÑ!,@Ãèè"¾ |F š¼üa'§ÏŒŒzŒ~Ü&Ø'Ư3`s »v›I‚W¯o^ÝRi`!Ö–@·ùŠÑ®ê +þÚ~ÿêݯ7Dœƒ.Mº B öË”Ñ.à&þ^HôætÍËMÃY„$ô“5¬L+]9eÝÜöG0Š'' åévø-4ê[Ì3‡±³ŽOÕ5“½Ë1ã Pê“î°ÞÛ„Kk À˜±É˜ÛÚšµ¿ +i>ƒ‚)‰³…ùOZj®Û< «Ë¯qc›aŠçN^ë:­æËSÍyJ…FÍÄÉÓX:å:¦ž /ºë +ßO,Ëõ@Î#i¬B$ñÓçñ\+R `ÐqšÎOÄh*ÓˆÐT¦b¢ýt&S±Ô>Îr*’º.Ðè’+(*ñ þ‹€À +0‰0‹•!TÁò¿Ñw Y«òûX’ÅÊk×N×ËP ¤"& ê«@šÉ0æ›`Tø㌢° £¨P±ó–æQ”ùõn¢¤™4òPß¶DÅ¿@1w ×pÈöE´I¾ŽÆÄÍ.²‡³%Ç#Qì§×Èz8Y†gc?®àè4ì”/Ãܘ²Úõéá½½ w<"Æ‚ÄX0ARÛSLa?Çqí’E{‰3¾$û­¾1m3®¾~ßú$ò,Ld&”êkׄé> endobj +2063 0 obj << +/D [2061 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2064 0 obj << +/D [2061 0 R /XYZ 56.6929 420.5648 null] +>> endobj +2060 0 obj << +/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F53 1027 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2067 0 obj << +/Length 2757 +/Filter /FlateDecode +>> +stream +xÚ½Z[oÛ¸~ϯðÛq€†Ë«H>fÑlÑE·èi¼ÀÝ<(¶’•%×’“fý^­»“ö`Q ¢¨19œËÇoȆd¡ÂLó…Ô LÄb½=Ë{øöîŒx™‹ tÑ–úuuöËoL.4Ò M«»ÖX +a¥Èbµù²¼üôéêãÛ÷_P—¿¢ó ñòË^~p}ŸÎ5]^¾»º†WÊYB¹/?^ÿùéíå¹äËÕÕùÍê÷³«UT«­:ÁÌèôíìË ^l`¿ŸaÄ´‹'xÁˆhMÛ3.œ±ÐSœ]Ÿý7Øúj:f +.”'‹ ÁãtÂ`a¸f:Ú‹’1{y!c®u‘Öµ³‹m–é6ë/œ„älÑ} BêÀZ:#!DÒQâz—­ó»g§Fó¹Æ&»KEÓRœÄ^¾¿s}ee4ýå7Ñ™€1¤uJ—g¥:j0Š˜“;©Ü[ 6zü1Í6oN*ãšy=ªC‚$¬Òÿþ㈄ -õ"hlÞ£+$NN¸½%5ã÷ eflšÂ/:[Wå¦8ìȹäóD©ºQˆS¥º:ýŽ…754ަ6½ùÖw7•{ù£íáË»jïºöçD-aö¹©»ò·þ÷éf“m ‚¨ËU˜ë1-Ùˆ©âHS­½{ʪÌF|Hø/ô”…u]dé~bU0Êâ‚1XÂЇwÉd$‰€ô—óaÐšŽ‚ dfüšù¤³iÂaŸ5CHøÎ©d†jt€"ATWë˜xÆyÊä]Ú¸Vj +Ãn“6á{ê\î…+÷¼õï«ë÷ï.êü¾Ì6þ§u^Þ‡GÝ àE•TÞ“`oø¼mÒ_ &ˆR"`—æ{³w çeŽ5ìK°Sx/» j4èx‡hD© +ŒÍÃiÅ´UÛmZnœ×ªÇl¿Ï7™G¥´ô~nA›ÿEÙC¸ÎxE^úîǿƱLc5«S*Õw+“”v´ê{•9¯ -4’J½ÐÎ%ÜŽîdË¿±À©‰OD| ›Xݸ.³ýÙÆX@±^@½qè–DJSÙE¿ê®‡P&Î@ 2í}%ȉÌnKÍø?H 3{¿¯³fèÛñž›£Âƒ°0ŒÎ+¥F´í†¤²\tÕíFe$l’Ð2ùnžC÷{ùnúB˜¶õ‰Ïÿ ½YŒ¤8Ð,@r°Ç º‘6U’z32Χ "¦´iÈMÚåe“íˬ1±K —u}ت:•˜!i¸Â|B´¤f"H ñ§‚`ضg•R#ÚöQ誻z0ã8lhíôà8¤‡ùž¶ÅÚÙqì=f‡ù©ÉóÍf„iœÈ¨e±/Êþ‚Œ ݺà_K …(çÌnµw¿Åй 1{‘/Jä_Hž`Ägó Ò–šN(õ³ âäÒ&Eh 8Õ âLœÐ¿ë¬lÒ&¯üÖÝíF8©êsÒÿøp$D!ØD7?ûyóßå$ê3EœšGý¶Ô4êG)3½;x +ÇÀEÛÐošâfÿ¿7€/~¸¹é/ƒQS8ãëˆR# édì¶X“ÞJÞZíë^¥ÿ’C‚úXô² ÔÆƒœ×E¸;+ƒ&”Ó®çGÙl±˜JõQÂØ)fD’“[Ÿˆ·I ÔG.ò«Ç|㘠- š ¼½°"³£Òp~ Ÿo;bÛêÑ\3ÌýÁ53ùêØ‘{‹Xe#]@¹Ò…œsòtj‚ÊiÌÕ;eåéP}ØíŠÜ) œq½4Fã¸I7Řù1â´k~£ø}é,yc<·Œ´Ò¹CØóãê),ÙݸÃ΀Öm^äÍó9ŸÆ€Y©“ÇOm©\ R}\I7› P‰÷4¯§”‰æb^ý(5¢ŸR&R¨î.7&t™t”eödb$êÍç~¥eúÜ¢iÙ Ã4NÔZh™bóqC$Ò,2Ö—>üß+­ <éÎɘ£Š…§'Jü¶ÔtÌE)G£«§ÁÝ6\Íì¬QjdÚîy=G,Ñ´;ïÛ¼Þé³ÉN™xnõaï‚¢l\Ç6«ëô>3i­d)P‹¼t` +_Ý]tõCg ‰ZÃþÈb4ŽHðÒ½1y¹ÎŽ£ºMÉ OoK*ÒPñ™®AÍ!¦úD Ú–šñ`räÜE_×ƒÆæNmvÖ(52m׃x0ìŒy¯³rS÷¯Œ:îƒネûyÝ…eãšÇ´ˆòöæÎô›Ý̹YØãó¸-Òòëñ:jÚÔX¢ãSÉÒ’š1ury^?eû±\•Èùy£ÔÈÄcSŠ’Du'neKÛÜ^ŸpÁ8f "MÁqê¯DÚRÓ¶ˆRϲÛÃýÐ )àGóÓF©‘y»q§Â€Ú‰WçÀ;û²{kiÕ¹‡ˆAáBÉ„™)4â’¹ýQãmx›p#Ìí:­X«³m¾®Š0ü±Nò£ ujtdZ”ÅÛÝw`¨ãMü-ÏÕ_—|úpu=²C€$p|Š9Ç6 ¡àÞî +wÿMa=ÀjÜ é¶Óc{ÿf™SÃÃfXÖžw §æ©ã=Ѻ:7…»X§ËCùwåN†ÖÙ¾q}Î2ЈEŒUl„ÿ‚èñ`ÉÎ@˜( 5!íÕ„Þhmår˜cƒ;*Y~¬šÜa¹w$2ü%4òrwðÛ­z¡ËbÙ–×½øý§vo©gŸk [R))Â9´êª?yê¤ïÝ;»4<~5æ/âë‘0«#r¦‘èhþd!_»—6µ {bV÷@7âʶ´l?üCýcè¼¹ev4õ÷qL óGm#P€cJüôßÎÿFKà%jªÆÀF˜&A)cgà$}ÕSH(€ž¡îÿbÚÏendstream +endobj +2066 0 obj << +/Type /Page +/Contents 2067 0 R +/Resources 2065 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2059 0 R +>> endobj +2068 0 obj << +/D [2066 0 R /XYZ 85.0394 794.5015 null] +>> endobj +2069 0 obj << +/D [2066 0 R /XYZ 85.0394 108.4894 null] +>> endobj +2065 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F53 1027 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2072 0 obj << +/Length 1863 +/Filter /FlateDecode +>> +stream +xÚíXK“Û6¾ëW¨*©2„ñà¼l•<3v&±g½–²•-Ç I,S¤,Pëß§)RâHÉæšR•4ýBlLáÇÆAH˜Çã(öI@Y0N7#:^ÁØÛs<^Ãäu¹^/F¯Þˆh“8äáx±ì`IB¥dãEöiòš0F¦A'ïn§÷eìOf>Ü?Þ=üý€pP:y?{üuöi¦1ŸÌÞÞϧŸ?î­8]‘F–¯£OŸé8ÉQ"bŒŸ¡C ‹c>ÞŒü@À¢¡£ùè?-`gÔNT£„‹èÀgC:ð#Fêà‡©ÂîJ½ßfI­Ì†ÕÅÄAÀ-Ë¿Å1Øv¦ +Õ´«"[Wº&ê{²ÙФÕf}0öX’eNõ<Œ$CŸÒÔ~XÄ #ì‚ÄZ•™~õ†‹Ž€YPÐ*¨Ó0ÏÊÃÂ@›ÏnÊäD¥•ýfÚùd ];:¸[3à<ì ~2p?”°BæxÊÎJüd%jT†xÎëõf> s‚:Xk$tteû¹n­ˆ‚ÑÉb­ËÏ!áTHC[' „[?YrÀÆbáåwPg<ÓÕ€Sf¨wÖ0==1ÌŸwÍíNíÔWÇþ=«6I^º^ž~)“ê©ñ¯ºåÆ©_Þ>ÎÞß;·«6êÌtÿ¿—ú– …°WküÿºÏu^Û‘`bt›×yU"ãJÕ[u3×ìyµÚ} ®ð›®Uú¥™‘ÔÈsÇ6I·Sº‰Îݪ½m¤n‰³82¬ÕÒᘠ³+¶ƒ–µqÀ9¨}ã´ÂŸ<° îÉ3œŒ7Ѓ̎›rc[Ón´§t„e’ÚÂVÂLŒÙè ZY¥Z妪﹮Ýb +„Îðâ®$Ä`í¾¿M,ú”©ªßwÊE‚³ ´ž×ÊØY2·Aٺ଑MÊvÉ4)QvÓ®Êß)yÚ šÜâVR_TåÊÓu¾U®†Bg7ÝÀÍbX¤4ßhòñÍ-œ>QjCN€ú4„Í^׎V9«O¤™4c§o1„ÊšÚÒNó’]È8“Í—Nž.¨>AÅ®UÁ¶ÉW6Òp…ÎÆLÊ0蓲f̹—I‚:;õîq>¿¿Åv^â è†"@¢ > &EQ=#É +¤ûÃëä›BÊÇó‡·7-ú/÷ÿse†ÄÇvÁ“$&ïºLÃÆí.0ÕDDpŠ}óðn ²a$b,û~L„ˆâ*dòº\XˆÈB¤å2«¾RuújY¤ø!^.O`f_\– å:¡—]YfAØ—a¯›SÏêÝœ•™*ë|éεL-“}Q»“Ò%Ú$Ó—4Æ$‰ ®¼¢±×5\FÚ_ЖÌï2’8ŠBÀ¶ÙƱ]$ŸÄ’ Ç`·p‰õÓê +ùÑhóÇ Ÿé ögÅÙãQy‚#"à ¸&P#1ù¢§ÖàTÆ!e]4GËunžûp& ¾ý¾Až­¼ÐG§PeZÙ”i{ö܃ïOïg·Þû»{FNÛH1T]ÂSãq¥†¢ÉÆ•*m5ÕOC¾&¤$jª‹®ÖazÙӦ풣mwù7WšöœMpBEà_´GËtf¾«Aj¦,”=‹´žÆâ®§™^µÄïÑÓLÏzšiô<ÍžÜÀO;=/<&á:ÊEÜ?7æ÷÷è´³wóW´܆±È²›c‰ðç@OP{£Ó“~pì™Ò¢3‡i§ vsÌÐY»•›«uå\|ýëÛùõma¡óÉÎiÓb.Ì¡a˲¸¹øeû2Kʺpƒº®™l¹ßzÊ&϶µÚ&;¬b¡¥‡ú¦šÊ*WW9šÉAìªM¹[Úâè6Á@{¹²Ô½Æ„eV]–åwóª±ÈŸvÉÎe)W¬›²V7 í°­«Õ.Ù®óÔ¥À­Ñáz¢%°bƦ¹7¦ë¤\¹CÕnß`ïëý±ºo‚ЫùDøac5Ÿ?¢}ä§pÓÚ•YÚl +"=änê±ÍNg†IèÇ!& 3oµœG/Ô¸ª¬­˜U„}y}¸èc(ÊüPV[ëÓŒ" yËPŒ# ‰x +É! }1ûw.<9¦ã¾ÍMõ“÷„[ºj +‰bÙ¤Vs L•y@Ø™ˆóK¾$”`)dÿÜ §ÈýllŠÂ|å-óB À†‰áŸÂ~¹ + Áù¦ÉitŠ©¯b ÂDnrø âvÑ!t"ôp[íê`> endobj +2073 0 obj << +/D [2071 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2074 0 obj << +/D [2071 0 R /XYZ 56.6929 479.6712 null] +>> endobj +2075 0 obj << +/D [2071 0 R /XYZ 56.6929 343.3873 null] +>> endobj +2076 0 obj << +/D [2071 0 R /XYZ 56.6929 280.1555 null] +>> endobj +690 0 obj << +/D [2071 0 R /XYZ 56.6929 229.1103 null] +>> endobj +2077 0 obj << +/D [2071 0 R /XYZ 56.6929 196.0344 null] +>> endobj +2078 0 obj << +/D [2071 0 R /XYZ 56.6929 160.4072 null] +>> endobj +2079 0 obj << +/D [2071 0 R /XYZ 56.6929 94.2535 null] +>> endobj +2070 0 obj << +/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R /F14 737 0 R /F53 1027 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2082 0 obj << +/Length 3151 +/Filter /FlateDecode +>> +stream +xÚ­]sÛ6òÝ¿Bo•g"ßÓ$í¹Ó¤¹Ú½¹™^h‰²8¡HW¤ìó¿¿]| EÉéµã\,Åb¿WlAá-Œ"TX¹È¬$Š2µXï¯èâæ~¸bg‘V)ÖwwWß~/²…%Vs½¸Û&kBa‹»ÍoË·Ÿ?øôþæß×+®èò;r½R”.?¾ýôëÛŸ<ìóµåË·?|¸…Wi¬$ÆOÓå/ŸÞ¿»þýîÇ«w=9)ÉŒ +¤å«ß~§‹ Pþã%µx†J˜µ|±¿’J%…ˆêêöêŸý‚ɬûtŽJ¢ ÏfxÀÙèµJñ”%Zpá˜ðþÃí»_n>ßÝüü Oã¾øF+nˆÌwȇz³X"Áâœ(& `#Òº©»Ã53˦joT-»]áÍcqÈ»²©ÃëÖ?sÿ¨ó}Àk‹ÃSq¸ÎԘͭZÞtaâ+´Å¦HV>¥šK ìÒžyš™3<α+«²{‰‹æa»ç<ìóèôTnЇ”ñ U|wóé=î³”(EùbÕ3y‡+U‘·E §’Â,o¶3Ä+JŒä‘øsD˜Èð‰´Hzj¾8ú@jŸËnçÁuã!ëf¿ÏëVe]xpóˆ–hþ™;jŽû¢îÚ7×+AaùÎðx(ðü£Ý5‡0Ûa—ÃKXnë9’IÂÕ‘!^ý¼T€–Á¥>Â÷Žrx t¶þÍS ƒ=ÊË*¿¯Âë@ÿ»<XzrFÈA¿À`\â81ÑËø~¬ËuÞ¡$ +TÏo9BE¦ƒ<#(ȳ7ý(÷»wŸ=>(N]¬»òš-›˜.i_Ö›²~ð˜gÜçGØ©î› yÈ‘àEIËMùPvyåUª-ê¼;z±t)Åò¦ö˜žÙ€µ>¾W¸£eËç]¹Þù™c[œÜ?ÚAÜÛ½kÿÞùw4‡ø,ò¸DQ;Té,$¼LÁ ÊHSÃii—w»HQb£Zw :Ö·»Û›Vm÷R¹¥Ì”¶E t74ƒÕÀOöÇ¢íÂq¦ÇB¯³^è3¹ü¦M¿oA~ +¤Nø¶ªFMH÷wÐzñCmwKŽìÁz—O*ÿ²?¶ó>ZóhZî_‚Ið/ÅËÔƒs“Ë4[€s Ô2ö5>œkÐÏyðU¿â*]Ò»ç‘>€×°TÚaggÛå_êæ¹o& ˆÞR.ç¬:'b´R_eåð(–EÍuו{Sì½B?Rÿ‡Rþpì]9Ì!Ä[dËMч½w4Þ5ÏîçÝB]¾îpÐB D/@ †]ƒ€ûñ³wÔ8Ý+©×äpŒ±"G߀×îep_Ç*LQ2#“à $R +Â7n±Ÿ]Ät{RB„— +¬g™™YÒ*ÅŠñÚiÌÚcᾫ{O\gb&1VESÚ6ÇúXå›Í¡hÛ)… vלÚË$öX34Ž£(E4å|Lä¯mˆÊÔH¶(‘R«³TN–µFeÑ?8§Ç¢såî{Ïuá'p!o]¦7e€>a‰í k5„‰"!ÀI#Ç‚ôñXuåcŒ?ʺíòz]´i´æQþ»>²‰š›W•×ÔÝ®sþÝ·m0SóØ©Žß|~’“@:,’ð¡ ¼(|Ä3'£23ÄfT^–Ñ뼌öXNF×s2J!djȶåÃj[Vʼn€jF(—â2}=Ö #ÕšP +b4¢p^@1%Ð ó³$NÖÕàf2‘Nfƒ$1;c#m$ŽQjÀ²ú¼wfÅðù¦Øæ doüÆr\Q¸™ŒE*¿-ºõ·hÌ Ò;§F‚h£y@?/ RñŠ0$X„!b9aøòªÁ{ïÖ»"|”Ÿ¢‚7ïŠ}Èw­¯ó¤Ë‚¬¬üµk`?Sv|ëc³/Ì`ö…ñAÉiˆn¤W²ed¢t9£ +ËGnQ,ðàF}•`.)D¤½Ué2Oxó$Å(Ê$5!„bMË,Ö0¶k\ªgxHÀÓ(ÕPN˜œÈ°d«!Œ‡\­ÊAácà4‰qF•œô’ÐèLÁO@f#Å+,„¤@‹lPùiC“,†FS•d’hªÎ볌Ê+4ź ÏËéóã« 'ÚÌ±Ž¨.Ó‘fèé2‡ ’ë a·E=[±‹Q®«k¹(87µÜ‘õ¥›k|kšHíôà:‘p…W7²ß‚èEêúzôLÁ·}>¯wöz)C?Æ^¹ÞëÂõF,w½ÿšniÁpR4œ—¶ŒH3[Žx ³ÔØñ–ê¡z +šyßD¬š‡HFÎ2k Á$,w‘ )Öy&ôXŽ /ó2.›7S«aL‚cÎøˆ®¿T«éW<=Ä„4 ¨¢Üœê %F3~™q=Ö çÆUbg@wýÕ]žŽMôqØHÛ”nRuž›œB¼È„úû¸Ù¯8ÃÍ‘ŠCt’Q8ë ;O‚x¢¬ŽñöÖ«õ~€SÓ@oÚɬâD0›g€$Òù÷±¦_ñÖ˜eÂüyÖ„:(ü>ŠE¨ "C­£KGPhh58u ‘3cù¸ŠÜ†òœJ ãîÕ{5*o»÷î*¡k¦$Fq€±ñaòµLlµZî!¾ËÂŽOyUnzw­‚§Á®àz] o^ îÃ"„BXtzÙÂ*Â4çç/+YZ˜lÁˆ¯æ/_v¿â*]òô²ø:Í35ì|ö²!H\ý(ärQ…àé±X—(ñÅæÍ\‹­ÜW´å.ùhׯe.(¤è1š/>±ôå6êjëøpù%bȇc¼~|úð’²!d¥£ˆ_]ëcÀ¥#ÜûÂ7Å` ŒÊÞ„6£€bÚ¿ñ ƒôù U¡*“˜_c~ÒØõ-Ú~ÂË©í[ÄÂyè:Ûg}6¿òÙ6öÓblCîoUÒ­Z±¦Õ\# u}q½üÔ¸™Ú¾imb·ÝÎØA˜íC\Ðå¥ÛfÒ6ÎzbsC•à!…G"š°” ñ¤I9iíœFg³Ádì +D1À†¥`Ôÿ0`R‡=yÛ&-Æbºî»ü)€Šº8äaãØíÑeÈXžÁÄŲ*X™¶%}«"=jª|ï>’± !]åâ±*ÜË»›@rV€¦-J˜¼™Ët˜ÂzæŸH߼‹ m!nõ€·›}Y—`®ó.ä—bxY¯Ãgóú,óL +v23 +çø ¢QÏœ’5ÊúÚËWekèžšc7ÓЋ‰?¥kí„™]Q=†Ö w%³Ý°Ñ`Á©‰MŸ?Ý|¼¹s?Â}ÃçÿýLržPDJ¥ò¥èF?‡è[ÓvçH?Ò¼x’ ™ÙDYËûß™ŸÆXü”˜ü4†1Û"ké˜M¤ÂµËŠÖÛPx&? p­x9 Ïç<ºH:؈¦ fF¶‰ÛqŒïÞ0s,è̔̕…øRéKž€¼B|lg)ó7„wa½Õ° ó÷#º0„¬ZÄ]/…v¼Ï“U€ã[Zq;ðêÔì0 ñ‡ ¶ØéHïï¶xlaá/-ªrP6J`ojcid]ႆöÙÜãÐ^Ì×"h¯ŽùGsÃ%ö ŸÏ§…”H€.¢ L°“x0þ¼î”öÿ…Á ‰endstream +endobj +2081 0 obj << +/Type /Page +/Contents 2082 0 R +/Resources 2080 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2059 0 R +>> endobj +2083 0 obj << +/D [2081 0 R /XYZ 85.0394 794.5015 null] +>> endobj +2084 0 obj << +/D [2081 0 R /XYZ 85.0394 751.281 null] +>> endobj +2085 0 obj << +/D [2081 0 R /XYZ 85.0394 555.2948 null] +>> endobj +2086 0 obj << +/D [2081 0 R /XYZ 85.0394 126.1169 null] +>> endobj +2080 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F55 1035 0 R /F53 1027 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2089 0 obj << +/Length 2725 +/Filter /FlateDecode +>> +stream +xÚ¥Y_sÛF÷§ÐÌ=Tn£Íþç2÷ä8NëNãäbeæfš>Ðms*‘®HÚõ·?`±K‘§sãk‰±X?»3bf,³©LgIª™áÂÌVÛ>»ƒ¹ŸODàYD¦EŸëíòäõ{•ÌR–ZigËÛž,Ǹsb¶\ÿ>Ë„d§,}ýÞ¨³fÁ%,€\Ÿ¯Þ³óWï‰s V& K„JëÙ§OWï.ÿ{º†ƒøÓ…á|þáìêËÙoDûtšÊùÙÏ×(ìäbÙm¤¿YÁî⯓ßÿà³5ìù×ÎTêÌì 8i*gÛm3Z©HÙœ\Ÿü§Ø›õ¯NOp&••Ö“b&K‘ó™”Y%•ßíõÅmêì·ëdÙ7#ŸÁ,,n¬gß•ë[UåíWn¸â½Ž œ¸ËKœs½¹2ÛæëIâ¤(Ôc&¥}9É8ó’¿Þ^^½£Ó°“õ¶(‹ºÙeMµ#Òçü6ß +7ÏËUN¤YÙf›‰ 똴Öñ!¶†¦\hÑ BVY&´v:_–¿|üü²/Ë&ß•yCš\?×M¾­éá¼*ëj×ív¿®fJ[ähÁdêºÐ'.X¿Ç,N'IØ@ç²)‹È»P† Aº×¹b´‰” ¥Ì¤\5Dªt."ê«”É>Jh/~å\޵ॢ*‰ˆ”M>ið(1Ø;¥à}.«‡º¨Ç8T‚%ΪÄ$¥§p#@[i0ˆ¦A)AXôDxL L!Õq1ø~#|1ï.®Ï?_~Z^~¼:bñ)ðMY<°àÑâ`p¨˜7÷9&̳ÁÜžá ÕíaAB¨(n{¡4±¶äL'Žb•ØýÊO\.%Ÿu¾{XFÐjC“mSlŠæù‚0¸°BΗ÷´/ÞÓ\Ìï³@ÌP5°‡ôj3[tfµêb[l2\Lš9ä†S7oWMKI¨Y¹ÓÏe“ýM㦚ð‹ÐPcuØò>•M9&eIb\—MF™ùu“äó²©ÃÒ}= Gmª:÷ÊèyQõf—­òz¤)¤Èu +¨ÞÐëYI|Õf¨zÄõŠ&#Æ!´²b!ŸõËô˜E‹gôógþ<âcS¡[š€?ì^Ùh¨¨ï¡•´f)—"ðõ4R<ñ /+pŸø„&{Ìà AãÄ1¬fÜXd¯óÛ¬Ý4‹`CUœe‰6±¦hµ"hp[m6Õ“O$ðtóL¿”ÆaP†žÊ—0Lk>²}åS+¤ƒõšÜ\×DÀ÷ô²¿Ä$t*æ^ÝDû¼(UÌð0{_Õ žŠÍ†F7áÍ6$G˜»ÏË ·Â_>ª Œ£Ô»â1¾RŸ½ÚwmðPbê—cHöê÷TDÜ›6G)æéF~Äð<”jSÆ¥±c'Jö—öTïD™'!' ^qäGp@úÓ})£/³XƒE + бÜlj?©`"éºçéHèa¹NûÀXPpiè0ƒGÁ~p>ДÏ/QqëÐ߇‹C„3”Ú¯]¬'VWp¦2©é·J6?P÷ñX@T®ýNè;%-ËR‹$,\T‡ŒùŸÔ…Ú “JgMn’—Ìc¹Vc?ƒLRÖŸÛ¸Œï,y·Y³ºÆ1g…³(ï¦ +©eç‘ciDÁÉѸƒŒ[×B•¼~NÄ8¦ +.Ç#’]@²ëì¨4"%kÁÖo+M²=°D@Cºø!¬œžÈôÀI(X:cë1Ämý)›rl’¦xLÖ#hbç1a™DcE<À&·!ÁšA‚µ!Áš˜`íÜËõ£"°¢!‰2_EzE¯ø ä±Åmw[5AT€9Œ‚É|‚õÆpøÐ|Sü¦à±Ô‘ÝK^bÒAE$™±¼tð"lÁLäèJLÀöØâ{lI9ïhG4U E—v¿KÕ½£\¯¶q"è˜ÑŒ×4~°b€àqæú’Œá“Hâ<")á=$aŽ¢I:(ÁÈC ~”’¥„‡à`ò¹G*Äy +©q+Qµ»U¾Àz޵|âžo Rñ¾™0 tiÌb=Àoz‘Å£ZÇH&¬¦Cl!ªC¹‚Îw¾òý#ÐÐ H ƒ Å·Ý@©ý |§ +ƒËOšæ¨A$’ ìW¹×Úäu€SÔmàôÀõÈ…~cϰýåÙm³oʧœ£ñ&#/æeÇt§÷Uå©òJ¬_ÅÞ;vݱEî÷ÖôXÀ±³]ç¡ñι¡Ùa¼{R4¶vÝ£“‹í¥߇Í Â-Ãlá8ÒŒÎè¡ëP׆™Ã“(ãè&0…|…òʺɳðà-›x¿J„0ŒÑ1þô­æ™wÛp5r9œ„æ#°Q¾”`ÊìÏœFD1X¿¡j@ ÷—4@@»ûe„ïï”1-4ÿ2v·/–gX*:“ÆÈ¡Hì…»øþ®zÁs¦;TAá¾s|(»¹ÉO$*ò,G}ÒMøt<Õ»Ðñ!{®ÈS†T]úסºà+ýê‚,£1üÔ‘#•ÃYJËoŸ5ð[Jêï(4Çмó78öW‹Ðæs&H¡ƒáí³/H b-L,9H¥ä#t +è¦P¥p¿›8Gy ÔðÙÍS‰,±zÐñÚäÐØl9Ã2ÛÜU;ØÍvú]ÕÝ£í¾X_THEJI¼¤Ý=Ç>&öBýã‘ëôZ&ןŽ]@Jß3ùnNùvæßØ×éùªÝ…oYÍæ™&«’Frþˇ³óŇw&Ü“¥º/5º¦êm÷÷¨ÝÍ$ÇþÌ‚T<³ 5£Ç:_‘ ‘»”ã®Wè_táDè@XVç «‰ +Ö¬Ö¡ÑH²}Þθ?ÔS÷Á}_Ä˽VxùºŒxÜ/é/þBg㢎÷²ñæÝSƒ¸uÕúǵpÊ¢›úð -1~­ø¢Ä»@ÿ÷Gáýçr0åœÜïöoClT +-%”>Ôý€Û-Òendstream +endobj +2088 0 obj << +/Type /Page +/Contents 2089 0 R +/Resources 2087 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2059 0 R +>> endobj +2090 0 obj << +/D [2088 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2091 0 obj << +/D [2088 0 R /XYZ 56.6929 752.2635 null] +>> endobj +2092 0 obj << +/D [2088 0 R /XYZ 56.6929 690.7232 null] +>> endobj +694 0 obj << +/D [2088 0 R /XYZ 56.6929 652.8084 null] +>> endobj +2093 0 obj << +/D [2088 0 R /XYZ 56.6929 620.2916 null] +>> endobj +2094 0 obj << +/D [2088 0 R /XYZ 56.6929 585.1376 null] +>> endobj +2095 0 obj << +/D [2088 0 R /XYZ 56.6929 520.6753 null] +>> endobj +2096 0 obj << +/D [2088 0 R /XYZ 56.6929 462.0998 null] +>> endobj +2087 0 obj << +/Font << /F37 799 0 R /F53 1027 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F48 950 0 R /F41 935 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2099 0 obj << +/Length 1782 +/Filter /FlateDecode +>> +stream +xÚ¥XKsÔ8¾Ï¯˜ÊeZ,ô´¥¥8’@€„Ù-ŠÇÁ{2^ücCØå¿oK-{<ÁÙ„¢æ`©Õê—Ô­¯‡M)üØT+B…‘ÓØH¢(SÓY9¡Ó X{2až'ì˜Â!×£³ÉýCO 1¦gó,M¨Ölz–¾öNONöÞî†\ÑàÙ ¥ÁñÞÉŸ{/vºkx°÷äà L¹Œ#`bœì~<{vÿP‰|a ‰¥²fYɯOö“Ç/O-ëäଷwè£Âûyòþ#¦àÚ³ %Âh5]Äf Ÿ–©QRˆŽRLÞL^õ«nëXŒ”ÐDi‰‹± )C"KÖ•³E¶Üe:ÈvCAul&qЮk¤Î견+$®“«©m”‹¬Ê–Ië%´ ¿ûpév$»-6³ 8ÐÎ_˜#8ªé{/L*ÈOíôFCµ·ZíTÇúvÕ쎪۬i‡óÛtsé7õšé6W’¦Ë¬i²þÆ<¼¬—~¤„pøýç=q&EÃhÜêER\ÔKH&Ègi|Q&³°LÕ¨3ö¡ÈÐRìD‡Çó¿¥xÙ|“ÅÕ9—/2ž?9øfŠ9+Šg//¾íü‚>ª?ãAtWܱí¼OôiôèùÚ¼[¿]Ÿˆ¿Þ=_½zøðV_«\aŸzB!(²¹rß• a‚ä¼þ’!-ûêŽèÞH½„·'fLÑœ­ŒòLë¼(PîùªòɉD¨ùHEK$íï¼³Ês .¥% €exL(üLra ÊÂD +l/ð]v7Ð?ýŒ3¢bj¶OÂ_Oû"W=‚ÇX mYä'ûuZ8۲轰ä½*::Ü6ÈK¢hj‘ϸR®P4ëžl {!iöÀHå|r^m”ŒÔÅδX¿YoâØ+ábï,>±,ŽÀà߳أ2» –ûŪaðãkMÙ, ºjYZxÓá±m‘žWi>JÓ©qÇŽz|„Ffå*—ZxÜ:xz¼÷8<ÞW¾ÙeAŸ€ŽRyh–·~ëÆXœÏŠÊŽëªMòªÙ 1z=ü€‰ @,r›ßdÐ ß«¶l5+jD@0ËýƒÖ«|^Õ$Ò ƒË+b©1Ÿç#Ùª‰Ü?LVÈ„Ö#Á‡ÊIk¢e20  w¿ªJB3$n¯q_« â]Vñ +j$nªC $¶ó Xñ‰² ö‰ê,ÅC]¾ÍÖ—oÌp¬…í¦|T ¶@¶ ¬1ø(ªŠÂ§Gñˆ³¶ÎÓåÍ––Ù¨ï\#rs³AwNxæ?<²ÒÃúΩ!LCзL¿E.ÝæÞƒL‚om6à”"‘ܪüÄJƒÊ1ÔÔ¾!ÆJ5MB°s¸â+L«»<íÃÉZWHè‚"ã 4Z1xeì‚­‚ö»†$o³Ê‹­‡âcÛ#€|ì_Óîù„Ùogd½j]ŸàPµ­ùP¡²4¬µ_ c”ĦË_£®ßtJ$ïÓÁVŸ9†w<¶æ,뢋+\°Û3ö%t€ÕIb´êRÍëô¦c‹ [Œ¢ŽµïöÝeÇWF—ÐlAH|Ò®¡Ù‹Ùv)º5i6ôg²&"JëøöNM¢Yßçf 3‘öÏ­Èf‹qÚŽoþ-ëòW‚]Kd‰G³µíàä_ü û ™­4#ØÐFþòßC›ÿÇdL„Ö|üŸhÕÖeÁ„¸nzÿGÒ¶ÿ n 8endstream +endobj +2098 0 obj << +/Type /Page +/Contents 2099 0 R +/Resources 2097 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2102 0 R +>> endobj +2100 0 obj << +/D [2098 0 R /XYZ 85.0394 794.5015 null] +>> endobj +2101 0 obj << +/D [2098 0 R /XYZ 85.0394 668.3939 null] +>> endobj +2097 0 obj << +/Font << /F37 799 0 R /F53 1027 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R /F48 950 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2105 0 obj << +/Length 2487 +/Filter /FlateDecode +>> +stream +xÚ¥Y[oÛÆ~÷¯Ð£DÛ½_pžÜØÍqÑØ9¶sp€$2E[D%R)»î¯?³W‘ÒÊrQ×ËÑììÌì7ß,ÉÃ?2ICÍHŽ&bT¬Îðè Þ}:#Af…¦}©ŸïÏ~ú…©‘AFR9ºìéÒkMF÷óoãŸah*ðøöúâãôãÍõ/Ÿ.¯'Sb¸âãó/_.¯/®þ7™RA$1>¿þzþ›Ÿû21t|þéònòãþ׳ËûdVßt‚™µé³o?ðh;øõ #f´½ÀcèhuÆC‚3g–gwgÿI +{oÝO³® Q&iÆ”ŒAF:p†0H2Êœ3®Ï?_ú]Ý]ÞN`ûÿ…‡ûÛºåêÓ×Ûs»Ûû«›k»[ÐÉzþÅ#E˜3í”Ý/ÊÉ”9®g+7ã¶Ü<—?»Ú¶=„·ESǘ>m7¢ÇåÜ¿íÿœE¹î¼ä¦ž~~S—EW5uÄê¹—‰¿óÊŠæ©®þ +u‹°âï嫟i×eQÙÅãªUm7h·ä}æ“ÅþÐ훓޾‰D†IÂVÆÚ†À¬ÇŒ‡Àé†($ízËò,HÍxÛVõ“]›Eó˜Ý\çÌo–­Ÿi»YW®Êºóz+Ìü:,b??jAJ%QHnnÌø®,÷ìh{fã¦Þ½Î¬þRŒGn ÖüÃŧ ¤(UÑÇÔý¢·E›x°E÷tƸ3xu}áGÆ?Î竪®Ún3뚟º-K÷º?û<«·³¥?F¹yÙͪe‹‚uƒ¡g1bͺ» 'ãü·»›ÓÉo³à;XÃäƒÿ¥›ÚH<•õþ»ì¸hæ¥'~Þ­ÁLß·J!¡`ì}ûÏß”mû~t'U‹MÓtój“³èHé’”nO*Ý]ȹ•JíÔeAŠP`Jzxø..ï>Þ^}é‘’ª ¢‡dˆbS* Ai‘L›‰“¾Ø [€M œ!… í‰ÌÒ`P±^ɦj|Õ…•ga5K©ì\8÷£YXz–l|.ëÊ—Y;½´À ö>‡_ZúdŸ/›ª›:\ "¦¹樣-ÔÈ#|€Á!pœõ=äHqªäÈkvœŽH€±´oã«Z»nê¹5!ãNðÆœf"Ì .UL{»ZF›Ašº‘\5¼õ$"Óz›³dM‰3𾇬I +l)ÁÉë׺s‘·õÒp3ŒÏù.²Ë× Ð³±¥챡ç<$ >i`b3Ñãm˜{©º…ŸMáºEhD4WÁªé,ç ŒPDÛu8Üst«»uŒ&¶k?1˸Jid0!ýLʇAظï±l¯Þ'’ÕÿÜTó`Ã"l».Ë0åùá3À„Pj`Gð?> ö G¢I%â˜ìÛTÂÛhwB`p÷»RF÷S1h^vÍS ߨ/ÏóÖˆ3P0Ô³…Ÿ‡­n à3`)àú79J_*v¦‡$%Iíòª¿¤„·†è·—ŒB™%' † +ÊÞ`É €>Û®YÁñ)2á€#©—'›!Fi¯!ê à€c÷‹ªõË×b5‘°eL‘L>rKæ${×¹ +ÇêšïÚ¥ÃüSÙùÌUÀ/ 0û9[´¬h&"·¯­=‰/ ûB}ˆ–XqìÅV0E`Ыۉøâea)¬ùÎÈÍÅ—ÛjÙÙÆÊÿÙ©îŽg\à÷ Ó«{6€‡§8¥¤äDä)â$ß‘º{ÅÚô @î8SdvîkÂ6áXoºíÙJ@Ý}K¦À€~*å!Z1í×zˆVG t^f­0ÛŽÓÚ%+.YÝìãl»ìüE³ZyPêU].ý›4 glBÆ>8f‘3áp=ã—Ëæ%_åÎÈ8 M —+;Á²mm—,ƒO š1ªÄ^æUù€zÌ9?9†8pê^ä·˦ˆ·‹¦ øŠ.Œê&ÜXl7®ÝâlÜ”±—)aËMíz·ÛºÎû ¨>´iÕoU¾’+ ¨LÅdrQi½x¼‹þ.BÉv FîþqÀÄ ë~°@¡c' ?PZ»DX{îïÈÖÓ*Øîòz9+ÿ‚†[Ÿ­j¬#±åk¹8Gy ‰ç7@$FEýp,¨ö,<•m¼AØËŒòϪí<¹Üzél+°J%¿ž¢‘€bp–C +Q{¿döRèêÑ®ë‰Ç«Æ{×O–ËÙCc[ÿça瓵»QçµÄŽiî_<¼æÎ‡× Z‡~Ššã)ªULWUAÔÛüǶ +WË6&’Æ”€}ü9[­— ý½>çÑ^Ôêx÷ #«Ü>ÝM3<Ý=6Ò…ÆÆÁ(k8aü0WÃÇÞCÛÿk™·*endstream +endobj +2104 0 obj << +/Type /Page +/Contents 2105 0 R +/Resources 2103 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2102 0 R +>> endobj +2106 0 obj << +/D [2104 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2107 0 obj << +/D [2104 0 R /XYZ 56.6929 752.3759 null] +>> endobj +2108 0 obj << +/D [2104 0 R /XYZ 56.6929 668.0781 null] +>> endobj +2109 0 obj << +/D [2104 0 R /XYZ 56.6929 607.6906 null] +>> endobj +698 0 obj << +/D [2104 0 R /XYZ 56.6929 570.577 null] +>> endobj +2110 0 obj << +/D [2104 0 R /XYZ 56.6929 534.8112 null] +>> endobj +2111 0 obj << +/D [2104 0 R /XYZ 56.6929 503.6098 null] +>> endobj +2112 0 obj << +/D [2104 0 R /XYZ 56.6929 440.3004 null] +>> endobj +2113 0 obj << +/D [2104 0 R /XYZ 56.6929 370.9227 null] +>> endobj +2114 0 obj << +/D [2104 0 R /XYZ 56.6929 274.6697 null] +>> endobj +2103 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F39 895 0 R /F53 1027 0 R /F55 1035 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2117 0 obj << /Length 2188 /Filter /FlateDecode >> stream -xÚíY[oÛ:~ϯðÛ:85Ë»¨Ç´I»>Û¦Ù&],ÐöA±e[¨,ùXR‚üûrHY’e§Ày]o£ápøÍf -l¢4Ñ1'Q,‰¢LMÛ :YÃÚÇ æifhÖ¥z÷pñöƒˆ&1‰5ד‡U‡—!Ô6yX~Ÿ¾#Œ‘K`A§_o¯ß_θ4±œ^ÝÝÝÜ^Ïÿ cE((~¾ºývõ çî.c>½úxsùóáÏ‹›‡Vœ®ÈŒ -+Ë_ßÒÉ$ÿó‚5y†%,Žùd{!• J -fò‹û‹· ;«îÓQ0J¸Ð|DœMàˆ±R¼§-¸pJø0ÿ4rF"Æô$âŒhÅ͉}‘hÖ¥rÛJ3¦ú@ew}›Ö‹·û´*ó'²(‹ÕP¦8BŠó´TÇ"Àé"0Á”îËÐTéï³.±Í–iQg«-ÓUÒä5Šd›b¯J÷Oéþ”ÆtÌåQt^c]ªÓk©¬´ÿ²;¾ýÀd—ÄQ¤·%X!A“$±a¸#3á‚ÄŒJO´~ ùÃjóF’#û]qöI±,·#|„"F+õš@Abò+}Þ§†0®Øùëh©Žï£ÎX³–ý yLªt¦%‚"-å2+Ö8*WØþóóÕûÙçk…#+§ë,ö—ÌLÓ¤ø{ ˆ+ª*]Ì€p?¨¢þ‹:…5M‰y^ÁZ‡ê ÖÕÿ±vk»}ö÷v„7Á Jž¿’–êøNúx¡L›þ¥´xcqovdñfÛÞìÈáÍvzx³~á Þ†±cÆ „ . Ò‚t*k°BÝßÜ t¯>ÝñßuBáÔlFb°ùúá=“~ƒßÀHPF°Ñ©#§Ý5%:k<ìÍÁO/Û£¼yÕ®†ç¤ýó½ûöñþõc=lll€œàá~þÑö˜7vèd.á,›b™uôóH”ØÖ—lú\b¿JwÉÞbÎ~PÊó–+ÈK¤P°wØ[6MpaµJÿj))Î;¯ EÕì–ž!ƒ(ˆnËîºqÀ¶§k5§»¾@5æÙã>Ù{_µÉ1hÖUpk/»º\ï“Ý&[xG¸KAô $ñ7vˆmœá&)Ö>´ºã[ÞMÝ ^pŒý< ¨:·&‰:Üšä$â±j;@8…´m_,áP`ìdQŽä¶uPG“Hs<ºûÚ‰ðƒóèD&€Ç(‹Ú‰Yæ8ÑÔYžÕ/g1†ÒÞ¿宂Û8Üh12&’åø¢ƒ-@ÿl è²ÀÀFb@Ku8º~Ÿ=â)TWS˜B2lU6ûE:K–KHê*ïF»{A´ËBòŸób„sß'Ûì0[ÏVYžŽ°Õp¥JÈ!Û_¯²û<ÅSFÄp yV¯ò;<ÐHKœÉÂr?ñn~{í-L‰R”÷Ü÷áºÌt¾^QÈìxþ”Æ&(ãž‘žÊ_!’>gõ§‹2ÄCĆ›Ì³ÂÔrçâN»˜mâ¤]7[¨mèØ×ø¤€Eíélª5OŒÖ ìâb¤e·BD -tªƒBðõQaÃH³³æŠ/g5˜-yò”dyò˜§!ÄùÔ™L½³q[4è8>«r8kj+dSd H#`k)¯pÛs’ŠH{@Û©)m¿l{ 6ïï,§HuÙMY€Ö%àËó\KyPû¼ ^_¸Ä¡ç…ì!/@AN—Ù:« c)[IÈ3$¥˜Î ¤DmÕ¢Ù#EQã -H_À(ÃCû‡À–¯bXRÚõZ]HL§¢Zް”ÄqëVu_‚1Õ”=”Å=åYä Wi3Žžú’|]îA…[`­…³6Û†ZÃîiä3ä|\iªÔÓ$ØT›¤ÍrÝ8õIcëm›&EZ8Ré\¤@LA'`¤,àÆ´Œ}þk—:Nªêç±hp69ŸUõKîX™¡ -ÜœËj…ŽÂ†æà6ìņ¤ºª=°ÒÒ{Ðë¨=¸ñTÝï«MÍ­üp«<ïmT¥àÂÏš{›q¶ÁfÐEêÓÎmSyÊÇà^çdžäð"1¬dUL”Ž#€O±¿û[޳.Ë‘ªWCUÀº%ó±E-Êç¢ÿZwp pylC6:Ù,Mÿž›³g‰Cžê gtÆèî•«¬l¶nÚ`k¾0s(¡˜.Ó:Ýo1ÔÀô¦|Æy\wŒêdQûÉ' †è<¸vËtÇþ3†j»ÜZ)š²?Fß’Cth_¢2`Mî Í×+ã/.g:ýriöÊÃñ(z2},]°îš÷üîIÒ˜ÒžIGŽä  ÿV0öû Ôm¶¹|ÚBþoÿvsømJÚû4ü„ß‹Dp[ó PVÍŒ›cÃò¿òËþ?ƒü¨Jendstream +xÚ¥Y[oÛ¸~ϯð£¬YÞE>¦m¶'‹6ÍiR`Ý}P,9*K^Inýõgx“%™¶ÏÁA€ˆ¢Fäpæ›ofd²ÀðGJ Ì4_¤š#‰X¬¶WxñÏ>]/³ B˱Ôû§«w¿²t¡‘–T.žÖ£µÂJ‘ÅSþGróðp{ÿñî÷ë%8y®—ãäËÍý÷›ÏnîáZÓäæÓíãõ’hžr"ÌÈIœ|»ÿøaùáëý¯Ÿnï¯ÿzúíêöiPk¬:ÁÌèô÷ÕáE'øí +#¦•X¼Â FDkºØ^qÁàŒ…™êêñêߣ§öÕ˜)¸PHP.KA‘Â4n/Œ°€ó/SNÔú`/Jbö +RÆ^ËÍüœp<Î9YŒ;Ú2E¶d£-µFœŠÙ–mY÷sFæ.ݦi{?Üo·Yûænšµ»ö›ÂOìú²©ÃËuîí5QÉË~[ ÷9×Ì”kD)Má F‘¶ÎWËUS¯_ŠÚK•—àʨFGxðVO AŠyÁ5#©3® RÖ5?œRBŒ$€Ì+õ£x«³m1W0…Ò4Uçu¤"Êí@8C©ÐdªÝã®X•bL kq|$Rn`U³#çÇ‘Œ1½e{˜¬ûr•ÏV „€Í—ŒªäiSú=¶û®w£g¿Pæ.?³ªÌÝ0o¶YY4°Ž[,Ý™96AZjñp•ël_yÂnÖð|ì"I‘P\Œ¡cÔ<† O‘¢X^‚”æ•a?Àf,u6ƒ”…Íî"lv&Úæ˜¡™óÕ+Eôš † +°œ)6A Ó f°j æM03-’Õ&«ë¢rO¬¦vôº)l”±¸ÆÁ0Ïx=x†q¤Y¤ª²ë‹Ú«²nÚ  +l¾ò$cÔYÛ]›md[€×1ç#LDv“ñaS@tÊ•ÅE%ÇaJø–s4Ú+¸ï4˜¨BÄíy0¤Î€)HY0µ0i$"×l×euÌB’„Vê¼vƒTD½ ¦ä…ÉT¿)¦7|À„Hºfoý¶*Ü´! suÚ:™<ë37ë¼HE DT¿8‡P³,°TÓ–ÿX’'JÊ’;¿¦œÂËη ÆgŒÓ½ê@*)0•åNI’ºéÝÔΡíg™n"‹P! +*íð./~¾óçŠ$1•88˜ӬZü½/2wÝþ°D¹*~17þÐV¿† 2¶¨yh)®nçºè:wj¢¤É"Û•eÀ2Ÿ—®=]—õnߣÈ)•©Ž(™À ôŒœQHÄxìÑLLÇùÈg œ6[õ…±Ž†µ†—lÝÕ,Xù9àˆRŒE‰MfƒñMRÕÀ´³p¶@3F„ª®Øe/¸ßwEîfÊp‘ånÚÙ6”=Ö?Ö&rê³<·GÍ*'þÜ;R®<‡’Áx ƘŠHåË:7I9@´ßd½ÛuæCxf}èÎO¡—©b3Ôoš}勵gŸrÍÙOšºœ%´±ÔiB¤,¡u±ìˆeƒ…²v­»lìJ~*ví[älì‚•)ÑóØ Ä“®èඃ浶å”®gûO‹YF¡^Äú¿C>@ß ìàËv© °•ùñASúòÀ½ÓÏUðbÐK²ª §òsî @˜Ïʽ¦®Þf9èP=šJoöð ã¯Y…ÿ4¶É|¢*ç­`ZáRñ‹/£ìq=ÖPŠA»‹¥4jBM‚Ýg›Ûßo¾<|¾}Œœ»W8q­Õ“ùNÚx•ªªyØ”CÞdš\HèÔ$¡Ê}s\º‘G*Œj/5ÇÞ©°…†±â˾µ=Ø/nÖS¶ƒ•mº”PÖ`jØr £éñ¿¥Ä8xÞRK0,¡A+MÓd†™»tÙvWE) Æ&¸6;ÇûÅ縶;Øo"Øt­¯Zv ”å®Ãœ'?l¿pÞ1MJÛT]Œ5µ) ¹ØlY †DŽš†/h$EÖézˆ@ÿÖèÜ{‹=ûÃ8gšÐ0we’(%¦´“³†¡hû€ 0x1/´×óq‚8i_m(.xâ"r†Ä•j}:‘pÃÓ8{¼½uûÜ|~üz9ØÌêb(¿à ȘbôÀv$mW¤Mû ¢DÀÔû»ûþ#’W*ßBÿÚõK§’oÅÚVõʇæ~ÇKÓRÊIÞ=¢iƒ €ÙÄ.7ߟþõõÛeƒÜÕЎׅ§ÄGûÕÄóßè5š¶/÷ÛS?ÑÀ†æw•HVŃŠÿ÷Ï7‡Ÿ© ÊfJÑx~f˜ A)s8ÂÄ\uÁ òV€µcÝÿ* +zendstream endobj -2041 0 obj << +2116 0 obj << /Type /Page -/Contents 2042 0 R -/Resources 2040 0 R +/Contents 2117 0 R +/Resources 2115 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 2039 0 R +/Parent 2102 0 R >> endobj -2043 0 obj << -/D [2041 0 R /XYZ 56.6929 794.5015 null] +2118 0 obj << +/D [2116 0 R /XYZ 85.0394 794.5015 null] >> endobj -2044 0 obj << -/D [2041 0 R /XYZ 56.6929 752.0628 null] +2119 0 obj << +/D [2116 0 R /XYZ 85.0394 400.4859 null] >> endobj -2045 0 obj << -/D [2041 0 R /XYZ 56.6929 615.2568 null] +2120 0 obj << +/D [2116 0 R /XYZ 85.0394 274.6805 null] >> endobj -2046 0 obj << -/D [2041 0 R /XYZ 56.6929 551.6561 null] +2121 0 obj << +/D [2116 0 R /XYZ 85.0394 214.6285 null] >> endobj -682 0 obj << -/D [2041 0 R /XYZ 56.6929 500.3546 null] ->> endobj -2047 0 obj << -/D [2041 0 R /XYZ 56.6929 467.1661 null] ->> endobj -2048 0 obj << -/D [2041 0 R /XYZ 56.6929 431.4263 null] ->> endobj -2049 0 obj << -/D [2041 0 R /XYZ 56.6929 364.9038 null] ->> endobj -2050 0 obj << -/D [2041 0 R /XYZ 56.6929 292.3128 null] ->> endobj -2051 0 obj << -/D [2041 0 R /XYZ 56.6929 107.6861 null] ->> endobj -2040 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F48 940 0 R /F23 726 0 R /F14 729 0 R /F41 925 0 R /F53 1017 0 R /F55 1025 0 R >> +2115 0 obj << +/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F55 1035 0 R /F41 935 0 R /F48 950 0 R /F39 895 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2054 0 obj << -/Length 2477 -/Filter /FlateDecode ->> -stream -xÚ­Y[oÛ:~ϯðÛ:@Äò.ò1mÓ³9hÓnã.8=Š-ÇBm)kÉÉæßïŒHên»§SÃ9œë7›Qøc3£VÎb+‰¢LÍ–» :{„¹ß.˜ç‰SÔåz»¸xóAÄ3K¬æz¶XwÖ2„Ãf‹Õóë/_nîÞßþç2âŠÎß’ËHQ:ÿt}÷íú££}¹´|~ýÛÍ=´@”&þï3YÔ( Ôr›@À»q­Yøuš…Añ„J+ÝC× 8·n™Ç -ägTÈa(â6äû¦ÂÕ›4 cŸª`ôà)˜ªŽÇ34eµ9Ï®ñ¸êx~:[@ŸŠ}5ŠfðIë¤\iB®^,s…G»OÑqj«¶ùMT¸ßÅ»/nÄfn‰€Š<8ÄÐjšHòt[:;.ñööî½Ùx¼ëéòªN…·çr“äyºm…»ò¯CÕ;f^ƒ÷p+N›·Ëuܼ WmÞ·´8)$Γ[¦‰-{:¦“íoy“'ÁË!2Š‘Ûâñ1Ë+ArkvÆÇ»\'”¸j%¼Nû¸hsžG=g -sÌ{rk @àËdû5+Ž1 ÕýCd«q Zb4ã§×pMh®_Q%+Wý]¿ÕÆÓ>eã Áa½hS´IÕqmr -x‘ õë´Ù¬8¡Í^ˆ:‰)œuB#O”Õo¯]Xï -§v ºÔN&ó'‚Ùø¸j4‘Ð>È_§šfÅ3ªÚÚ2]5»Öm<øCp‹¼xñºÀú͵%I/YµiÕXu„ȱÙ{ø¦tHL©y²},öðÚÎ?ºj †,2«üsµ‡¤âÆ®æKDqÀ±r°@Õ°¨ rµšïß%~Ççd›­šr­|¥Ëeе9ÜÁ"¤,šºšQ„iÎ蘅ü  ÂP­ÿ¶±›£î’cc+¨ušÇªÝù¨±¤¯Dß3Nú(€§§t™¡Ç§«« ¸¤0Ëq}. èi¸äЮËîkPH±b?\cY›I‰û©ûKȇc4?þ:x o5•ö>byïðÒïCZ».¨ìÊyllPè u ƒtý ­Ý¢~n1¿êc~éÛ5òF3áüÔb$ž„ù -%Ñ(iYhºùÈuÛðb€­ïý­j¹[drí[%ȤçwEÝ#S$¢Æ/GíD„Ùâ:†*Éê a¦Ü$î¼+7ÛÆ±gMÌyNG÷-< -Qø¥4DÆN3¿š:ÌM‚Iߪà%;£ó[òÊMqØ®šÁ‰·.1q‰Âón’gOzLótŸøoƒ.}Çò)Îs'eÊ’øì(h8Œ!œq‡¬>ÔoÉp#!ë«‹§mZ¯ ñ~¢räÚô@è¨Ø¬­µ “¯S­Sx¡ùºÅ«°w:Íg YG¸^í²<ƒ|Tá _ÓµWf¾ô¯}JòèÌiA(ØipT·¿ßÈ'Î鲿òå§Ú5¬OÅÁÐyßãaà'î”Ø]†™Mº}r#_KH#Q#ô“4¤pj°4*•+´o?Ý.ê[ü·¸ý|w?qðhh„âìçÏão‘ºnùš_vnàϺЦMîH·1´Cf²SÖØÝO‹Ê,~ þs¨²mV½^2ÆæÁù!ÓZÃXßû!îðbѺ, -¿ËÃÞ{Pµ}u¤:ÃïKâ •'¸Œ[ñÒ«fБHaü@<¿bÔ]²®ú=Ù -Bo-ÚOA<ÞôËmDÀ¡¥ƒXܶ§ v`ð Ë Ôxjƒ¥ïëŸÛ¤˜:Û…ö!TOlrn¸#YnSo§ýe,瓱FûAvsãÞ½þxÿyâÔáUìøNUðùö'"œ€¬Žs¦3W#ÝIâäR°R‡¹IØ®?I˜†éÜ@ø“ )†‰Hm"}´sh­»mF K*ŠL¶¯Ìëo‹~þz^‹·y•îóqî_KÀ?Þªï‚@úÉ»v_lu0žd$|HÃ/ >ÞL— XŒŒ»wšÝïS½£ÀA-¡:v¨÷ëý8ñœìä²=, AeL膾s·NÒ\ ½œ,~Å¾ï¾æÅS™•Ãt¢!'Ž—ßDJ5ùá -’¬…VÆg¾4+ŒsGûÀ1´2õµK¶˜¼U¢Íÿö—èöS¼Œ‰0ä׿ö§àÊ‘ -À¸õdÂe@ŸcÙÿ9Īendstream +1592 0 obj +[702 0 R /Fit] endobj -2053 0 obj << -/Type /Page -/Contents 2054 0 R -/Resources 2052 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 2039 0 R ->> endobj -2055 0 obj << -/D [2053 0 R /XYZ 85.0394 794.5015 null] ->> endobj -2056 0 obj << -/D [2053 0 R /XYZ 85.0394 409.4177 null] ->> endobj -2057 0 obj << -/D [2053 0 R /XYZ 85.0394 311.5951 null] ->> endobj -2058 0 obj << -/D [2053 0 R /XYZ 85.0394 250.1972 null] ->> endobj -686 0 obj << -/D [2053 0 R /XYZ 85.0394 212.3815 null] ->> endobj -2059 0 obj << -/D [2053 0 R /XYZ 85.0394 179.9082 null] ->> endobj -2060 0 obj << -/D [2053 0 R /XYZ 85.0394 144.7976 null] ->> endobj -2061 0 obj << -/D [2053 0 R /XYZ 85.0394 80.4778 null] ->> endobj -2052 0 obj << -/Font << /F37 791 0 R /F53 1017 0 R /F21 702 0 R /F55 1025 0 R /F23 726 0 R /F41 925 0 R /F39 885 0 R /F48 940 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2064 0 obj << -/Length 2904 -/Filter /FlateDecode ->> -stream -xÚ¥]oÜFîÝ¿b{¨Üf'ó¡’''qz.š4׸@^ä]Ùª•ܕ֮q¸ÿ~䣕vå8ÅÁqF$‡ßäZ-$ü©…uÂå:_dy*¬Tv±ÚœÈÅ ì}¢øÌ2ZŽO½¹› g´ ·}wþùíÏŸ./~úH¢IÕH4r¹Oéð¶Y¯Äªm®é¨ËÛfBç2 -±êN—ƪ¤¿-q!øêßRê›Ý¶è«¶¡]„Ô|àºÝ2Ö1J§Âé-20C[K‘f†Ï¼|™ÛS~sññ‘Ë Ð›’]¹½/·ƒýöTù¤­is×WuÕ?ž*¥0§tryK÷’#ÎUr[0°@Ö@bR ™§v±„luÕ¦ª $¦mÒ)ŸìVý., Z4kÞ~lúâ/Z÷íŒ^T*…O]ÊWÆ­ŸTL.²Ìz>Šællò¹/úrS6}ǤÇ|”ͪn»20“&UCЫm±*»Nûr»©ÀÅïU¥ …ÓZG)·àA9 -~S-WmÝ6ÀOjÒäm]ì:Ä®Áµ"ž -*D@7â7nÃKݵ|lÀÊßÌ1•ˈp×튚­Ú bf¾úÇ:r‰àmä.wwwíð¾v½p)ÊvßR”¸^X”L^~K°o_N?Èèƒï¾›ùä%Áú–ž%Ší5=ëª)ç°ýÒT£ûÇWb;ã«}18¡'D?Ñ©O6»Õ-®r´ÿ» ÁýmÑÌPË­0~Àñ÷¬ÚÈœõ Ä¢{"-¶+€ö·¤RÞØ[Õ+ú¼hè\{‡!ª;8õ‚6£“ƒ=¤Æ©Ãà€BÒç鵈/èñGùxpNÌi¯4ãÿp{㢠"¿ÇRJS‘K­øÜˆ##³ñŠ -ï‰o(²û’wÈÑk¼zŠ— -ieÜëòºØÕý’%pÌŠw"KmÌÇD¨UÌÁu[×íCˆ$ðvõHOŠã°a;ÈÞ(+ÒTªihiCl…x°^“š»Žhâaƒþ5F¡S•v³4Fmbˆ‡ÝÛ¶ëiõPÕ5­®øËGGØ»-ÆÛâSNðszuÄzSÝÇ -ñ=°}³c $Æ~}è’#“ûš”ˆwKíŠÔ™ð™özDó<Æêr!µu‡JÔžï—•РD³…“³V¹*s‘Éù‹h%´Ló±c,ɸR ¾e±K™üséœK.qçQßÇÄ!Bgö´«õ uUÍí¸VryrGåÇ}V¹7`(•\” ú Ì\”ˆŒñ+ŸÜsr†³jÕ®´Ùsâq25‡zœÄ¬=ï"™P 8Ò$¼nŠ~uË zjÕÜÌ(êõ ‘§ÂˆÚÕú£ˆWO•)þ¼ŠvL/d\^FOöìÉ~ðdO©!Åd ö¶Ô!ÙÑèÐ.¾a:¬~#ÑÃIŠ@,(ÏSÅ„lбYö„k:……zzàšXzÌH&K1#ù¦t`í$À:°6X—¼aÕƒ¶´„$Ñ”«oé“`”2ÖØ ënÚžQ±›ÃŠEl†2N¤ÒO…|J>áSЀ-ÆõÄí¡ÝË¡±™dDÂÓËà^ä[°O )†} @{ß’{ßÒ:`Opj€‹!ì~«{EùQ&ÜE:óXÐNp®yÿÁŒˆ÷‘K=ëIºÅ9O‚~—=)“#OÂE6’ ®«àJðdWÊØ•2ÉÆÆb'žÈ@`ç9tR‡¥D»Û®Ê%æsÌåÇ7PÆBÓ¬¢ nfÄUšp˜&7OdyïæèX-”³Ópˆå!X5§+¨|“U¨†A !¡ìHWö •*,.>ݧ´G"o©?\ñáQiSvìN‘·iQ@§îÀs¡Þ¨c;Ó¬œ]÷û¢|N9©¯çⲇ>ݧû¬òÐ&Ö/bí«îX"kkz­ ïÜ­K.¼ îú-Ú{Ea§~h0¼X®QØ %¡!,FM¾Þµ]W]Õü›Î«9'À,‘%É|^†Ü›¡V{1W€ï•}&epu¥¿è6P?JH'ñ ¹G9ç…Öˆ,÷zTjê,ŠIǺNËw¯…•‡­Óf‡å¶v†b-I».e (4¬ð,èAm”›è?3„=Ã-¡ IÍe„R<ÃU³Û\»D\à8TovXâyvi€ 2œk™ÀÅõtnÀÓ¹¦W!Ý08û¢¤è$?ÌðZSU†OLÔUˆ:TuÇÓÈ@ÀquŇ8^!¾¦ëË‚_‚Äc¨D†5*&tß&9/‚Ú¦ÔHåÐ7¨T8ÅK ¢,þ(iE‹ù²¤ð0¥Ê=Q¡Và³sÂtPüëXÝ>›B¼¹DGS”X öýUùBáíдÌðX9!4ÊÔdI'ä$&ƒô¬ꤠ)Síx LöšG -¤)4CÊ.ãñgüdœ]ðÈXù7òÈ™]B/•ê/÷ZH™ûãE*Ñ4o„×a¶e¾ f‚j ¯C‚@% ,abÊA(\¡*Á°…,ñ€7óžâ!š°¢;.ú‡6¶‰"séADZɱ °Øò&šeQß´[¸Íf~Ž®”æhûÖó‹áPdŒÆ)íö1Ö¹°±G^Ÿ˜§gP2ù¡zjx!}(Ts&”3¯±®K“ÕnK–Ñôõ#m¶ ­tòÏgo—ÞYž“åª/£§’¢ìíöƒÔa€G;Ùpbß³ {„ôÚ•+â£'ða=Ô -ãAnpÅÈŠ®\º”  ÍvÍ…FF.;>;÷›n.°u‡{lV8|½Œþ¸'\ÙÀºêâ\6ŽÞ”Ñ­Û](!pý纬î©Yá0ÆÇ–aÿ’Ã:j|²ä¡xì¸j rS6å–ßqc4ðÐÈ7®¯ÃÔm?¦ó#„ñ¡æRvø‡8œ€;²›m±™1UÄø‘©NG4±ÅÀþ|§#åðS ¥(¯X·LS’>÷Rº'àBh»¡uÔï z¥j3ÛWÐSŸË½Ðrè -ñç°µrÎ÷µÐ^Æ"z$¦Ã?u MûÐ0{ÝMéEjÒˆjS}¨Ê D_°ˆ­ -¹©™“èW Cˇ*‡ò±è2šuãñÁìݨ ‡ýkºâ†vâ¥ÂLén׋™‹ig…ö—e™Â:ö”-•r8ë‰vw[݈ ®ÈDq7gÎw}œ9{!s=Ç0uÞU] >ÃÀ¦hâÿ -ªMÇñàsY$êó_Ï>|úñœcº8‚‡h? ÐzOÄŸnºƒÃ%Ôb{ñ~†•Eê-ý¢éÎd,è$öG{Ž<üÒ°tR&ÿ ’‰¸ç»k®•†óu»*jlÓ^Ï…ÐñࢃŒ†÷×ÜêÎQúï€ 2²å[E²nLõY¦åÌ?OY}eÓýøý9Ò:å"á¹-µàÿÌü#€Pÿßÿv°ÿ‡Œ4Æ{½ÿ‚iiqÚí"Sx%G¬ÇP8æý§vÝ7endstream +1447 0 obj +[702 0 R /Fit] endobj -2063 0 obj << -/Type /Page -/Contents 2064 0 R -/Resources 2062 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 2039 0 R ->> endobj -2065 0 obj << -/D [2063 0 R /XYZ 56.6929 794.5015 null] ->> endobj -2066 0 obj << -/D [2063 0 R /XYZ 56.6929 752.0756 null] ->> endobj -2067 0 obj << -/D [2063 0 R /XYZ 56.6929 252.6303 null] ->> endobj -2062 0 obj << -/Font << /F37 791 0 R /F53 1017 0 R /F21 702 0 R /F41 925 0 R /F23 726 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2070 0 obj << -/Length 1788 -/Filter /FlateDecode ->> -stream -xÚ¥XKsÓH¾ûW¸rY¹ š‡4ÒRLp‚8ŠâqP¤q¢E–‚%c»ÿ}{¦G²ìˆM(ÊÍô´zúùuËtèÁCŸx<C â{Ô&Ë7¼„³ãµWø<$~Èd/íø‚rFÂÀ£CéG$àŒgÄiºRU¥ª‘€~à#/“8¿*«·×åÊ®|îóG¸ü÷‘6èRJ"ßgÛ…k½¡+hÇCý¬nðÝ*^^çªÝþ0̽‚âü²\eõÕr’€õj'î2õ[ù]æJ%+…šzÎApt²ø[ðÓê»Èo.˜8*–O¾Gù‚æùóÓ?óïý6ÐûØP«ªþE ‚ûÀ„6àŒ?›†¯‚'/6Ñûͻ͌¿}ÿbýúñã{hýð⻽Ë}ˆ½ïÃÂ#ƒLÒ¬ÓÂÜäÔW -z+Œm@Ίí%;IFm’¡j€khk¤t’²Ð.׫¸ÎJýº MÉ2l q…šÃ1hn‹v…ÎׇÈ#:ªÖÞ4_Y4U³Ôq­–ª¨‘ži–¥j®1aÇ{¬‡z -fm‹‰° wè<;º'O}ÜÅùˆ:mŠÑYm_Ý*‹û$1Pz]uœ†Sn/¹ˆ+å7ªHÊ4+.qW.~¦ÐO -¾½:ˆÊËÊv&ðLËõ…‰¬¿¬Kpi……$…M=Õ’úB·X¡¨ãj‹83(fâvË„‚Ûw³ -ß\£zÜäWÑs£/ˆün|RîáH*©í%·h@“|·Þ€[”>Ð-ªÑƒÂ›zšÚÂ7V8"Aà®»­õ*vȹJtþ¥*”ˆ EŒdT¹Äõ~Ð(¨Ÿ(ò E±eW<,nŠ46ÁI›öÉ ƒ˜ïVd¹®¯×µ(b> ”J] ÷8„RȨ©‹Qû™îÁÚrÐèÓ#'"Ü— ÆœU™W}~…T½-c ¡fÛ¢\õÙ±)5 ÖéÏÂ0‚ aEo5ÉŽ]V׫L»Ä g! Ç’îBÑE³Ð_©šæ°PZõthxU""!eáÿU "ô°¼S*¹*qN;ø\”›Âοy¬Mþf‡`íf³ˆí4k¦¶Üüƒ=åh;bÝq¨PJsçl|2A»Ï'g#èÊoáaöú3czüæl¬½9ŸžÎú‹˜Äc‘u¼Éwئ̩ߢ§¦â¡WötÛúMR<5åÏ8IÔuœØ<4Õ‚4L -•e+RäiÞCaIyYdß­BX‰Àc XSªk•dúòæÖ¬èë‘vŒÙ/™€D<ˆîƒEÀIå-,â,j:§¼QcõiõuJgRÑÛ¬èU*ÓïSdðù¯ÑFD‘s®ÔžUÇÃÜ´½æ¸‡(‘\ȻĞO$ƒÍîÒÆ:ƒ¶Mý•<=ÅU„qºÌЬª¡°u5hÒ™Z(Œ{‘Ø×Nâbç[pÂiFÁD•ãsGiœOleŒ_žŸÞü: ôgA¨?ØîÜéûgM‘šO ¤›;xÔõ­Ô½Œ5 ø{ž¸m B¹A›=^q¹€ï7£w½3~3vzv·[¦€]«¢×ó› -Bm;Æ!$LNÙz¹½WÀ4Ñ€O_)àãȘ@?r©þ¸ÞŸ,Là ±„°˜¦Ñ§_1Èþ@²Ûó‰Ñç#|õlã†+Ù¶?Ptv–eþ³¿`@=Éõüaⵞýí¿g¶C Ix²öŸ—«¹.åm”Ò¦SN÷Uoÿȹ­û`&ã±endstream +1198 0 obj +[702 0 R /Fit] endobj -2069 0 obj << -/Type /Page -/Contents 2070 0 R -/Resources 2068 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 2039 0 R ->> endobj -2071 0 obj << -/D [2069 0 R /XYZ 85.0394 794.5015 null] ->> endobj -2072 0 obj << -/D [2069 0 R /XYZ 85.0394 343.1761 null] ->> endobj -2073 0 obj << -/D [2069 0 R /XYZ 85.0394 255.6488 null] ->> endobj -2074 0 obj << -/D [2069 0 R /XYZ 85.0394 192.0319 null] ->> endobj -690 0 obj << -/D [2069 0 R /XYZ 85.0394 152.6743 null] ->> endobj -2075 0 obj << -/D [2069 0 R /XYZ 85.0394 115.923 null] ->> endobj -2076 0 obj << -/D [2069 0 R /XYZ 85.0394 83.7361 null] ->> endobj -2068 0 obj << -/Font << /F37 791 0 R /F41 925 0 R /F23 726 0 R /F21 702 0 R /F48 940 0 R /F39 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2079 0 obj << -/Length 3192 -/Filter /FlateDecode ->> -stream -xÚ¥ZYoãF~÷¯Ð£ D=}اIf8Øxf3°@6´HÛÄH¢"Rvœ_¿Õ'5%?°Ý,U«¾:I²ÀðGB"i¨Y(ÑÀD,ÖÛ+¼x„{?]‘@³ŠD«!Õ÷wWï~dja‘T.î¼4ÂZ“Å]ùûò{Dºxùëí‡V?|ºýñ§·×+b¸âË÷Ÿ?¼ýpóßëˆãå/ïo{ÿo¿÷ùÚÐåûŸ>~¹þãîç«wI¬¡è3+ÓŸW¿ÿ%<ÁÏW1£ÅâþÁˆCÛ+.œ±¸³¹úrõŸÄpp×ý4« -‚e’ftAÉ‚d„ #eƒ$£Ì)ãËë®Ù·u;}FÒ’-c+ªsGP4 ÜŒ\H"A¬ ''9E*+ÕaW®Wëf÷ðXí®Wôÿûªø#®î­°ï~„“{6X8Û2øZ½¶õß•'Ç Òœ‘@—x®3<™@Z -ѳ|¨7ßÀò)­¾f˜K”`¼g¾+¶ßÀ|QÞ}sè2ü(CÆbsÂïá·bàG9@+ÁȧؕÍvF€-¥„ž²o/Š[”å¡jÛ·k »Èrýthš®¬99ÁCE‚Kbz¼ÈôØV9~”#:`çÆî·b„‚3kXh¤ŒðÁèÃÇ/?üzóùîæÓmúQÏ/VT"!Œ8u O=‚CÓ) ©EWµ´´YÂÏþ‡1}<Â^Ýìü¦ÝÙDЇæp††È„“™£)F\EPAÈäT-oºprN»¯üTXúUŽ.’ŒÏÕ®®vá—Ŧ«;÷9ü²küõåPw++è‡*Ä4—cŒÖ»G 4rÙ=åP -±Æ¸°šž Yµf “â4âÙëËs/° áŽp;ëæp¸&zYµûfWZ2êMQa"RàÔîÐlÚÌÉÌ .U„½=-ÃÍ MíƒH†ЀV"Ÿ¶HlAí—¹ÞeÔ#Á㌎lm`*çô#)R4…“ûWÏõ ÄEÞ>œpÈ]ÜŒíó¾·ìæõš²ü~ÉAkzÎh¸ð Ãµ^ÃÞKÝ=ùÝdÞ±Z„FDs¤Z9µ`¤˜ˆ‚7ûàÀÝ x·Uç7Ž{¿QdT¥42˜!’òfÖîŠNì=,ÿç¦.ƒ Oá±wU¶¬{ΊA¨@B©‘Aÿð!zñ¨q—³&ŽÉTF(y¼Œv‘Q7D ê~¤1at -ÅÀyÓ5<øáª0” ¡kÄ0 1Ôƒé“ Ÿ§ÕX(@‡¸«•<_¥ ©bñtZ¥$ªWÃ#%GÆ}þÈH”9räY°TöFG~p‚ϱk¶à>ëŒ9À%µ‚€x>`3ÄhŠk“ä`8ı»§ºõÇ­}\‹ÙDú€-#D2xä‚doò ©pÌ®ÙpÉ™ßUÝ:\%qï^;w_ž@ìçlÒ†bE3cqûÚZ·Hõ×BRC€õØ^l#Ú}µ®­:¬»ÚxãåÉ–°võýÍ퇰oÞëMÂÿo¢º6dY‚ ÷ÀÓ†Wwm þž -¨)%%,O')ðÍäxV¬Í0äÜ™"Ó«¯ n}èŽ{d3 åàauI¥vM–`>p³X3Á¶Æn6ÍK>Ë35#7â¢%6Ñ\.íÉŽ;{dtÙŒQ%Æ:q90ƒÈÇœóK–cˆCM=°œÀ>éÀbÓ¬‹_>5mˆÏ!éÂj×øëÃñàµûç$„8Ù!nB”Q :„~ƽè¿w»¼Þ ÔÇ‚šÚú.²g>“+(P™Š`rVi=¹÷8*äÒø<Ú5Ùøó3¬‡Æ†®:þ¡¤µG„³KçºÍ~UÙ½+ï7Å:Õ_ðCŸÕ²ª¥Ž…-GXˉ+ÌÖL¤ú;ÿ £býnΨÖçXD4dTÕmç‹k; 2c/ó4l+J%½^*#!ˆ‘/Q¥¬àB~lqó`ÏõƒÄËmãµë7«MqߨÖÇÿ{ÚùÀ&„Ú~Õy.±c*ýûלqhpͨuBÔÌCT«—UÔËüç±ö‹ÒÚDÒ xŽ¿Ší~£P@±?Î?5èQíAëV–¹½ZÓÙ«E¨½B!š•ܸmºAõ͸^¾6GOÐ>5ÇM"v•wFvòÔ§’ËÝ©0©¸´Àk ÀzY³U² E# Î;/[¢Ê7¶2T’„ª±t_R¹eáΩPvá$r«æar ú(›Û=—Íí¢÷u×Ú™/TŽ¿mîs›U¼v/U(IàêÀ A¨]0Çâ_°Ô Ù€1:›@¬¯HÀÜu0;¡zÖÚ¶Ð`vÖÚCªyk'*gíuÎÚv°L2óÏ‘µ¡%Sª“³²%ªŒpck3[ÿM¤û-d×a¾ÊÇ è­˜Jv¶ñש4Kÿ Û¹Zþá5v¾©=u‹A‰Ôÿ2ÎÆ@C“õ†ˆ+¨†±JÓ³9ãS “üB;¤:cüHåÔôtÒÇJ„ºpd$Ê9Ê}PÓ)=9òó¡%v9ÜjýɬýòÅù! y˜Ô Þdít0á‚åã1ÕVΞùN)UoLZJoÆ.™† =7xõYÓ ©æM“¨œi¾¾% -ÇWÙ(|V¶> -Ÿ -—Â#éFQØV³ÁF24I°p¢¹•·ã€Æ×,v5 Ì‘ƒ­LOÜa7¶Gß‘ÈT|þò\lÜø –e³-ê]/:„ï"®¦Ñ8Ó¶ÚILj®tþ‘GSÁ ƒÆÌl»¹Ö>ûl(#Œ"0:ˆTóÁ,Q¹hÖ^ìrŸ!d»œ³²õ]ΩpÙ.g$ݸš¢”,o>û +œÁ(ÎeD¹s¢.‚‰Örš-w?ˆ‚óûa9Ńa9Åã\é~3Ÿ+)–ˆöm¹2¼Ã„$1}Å?[·MgÙÍþ¾X ]ÂHƒ®ÛVÙE£6ì<DóXŒDŠ]6±šZ£¯WÆ•=$`"ÍYÉÑ©h#$RŽ„}Õ?”-´ÛÆÄvÛ˜¹v[ Í´¸0¥£Jòi»mÂÇpíÛmãºFf_Í!Ü9‹uaß,srëF¥Ï%^êÍÆ³NßÀÔîܸ©ÛŠCˆneøæ­ïô-UYÛgó™gì_‡É’Í|Š¢!djEßô¢”³ä¨Ax`ëÓ sßÄ\C¨vƒhøß+k¿ž±4Qç%6ÉOÔ 7ÛDäC>óŸdØê ðŸœúÐ]`°[¯}OÞ”&‡*87õUöæÅ¨U I5(šû“A×ʲ‚Ówÿø#ÍþcTn?EÒ3-4Ud¦2 -e‡øvÂ眧²ÿ¯îŒ—endstream -endobj -2078 0 obj << -/Type /Page -/Contents 2079 0 R -/Resources 2077 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 2039 0 R ->> endobj -2080 0 obj << -/D [2078 0 R /XYZ 56.6929 794.5015 null] ->> endobj -2081 0 obj << -/D [2078 0 R /XYZ 56.6929 748.9271 null] ->> endobj -2082 0 obj << -/D [2078 0 R /XYZ 56.6929 674.5821 null] ->> endobj -2083 0 obj << -/D [2078 0 R /XYZ 56.6929 573.362 null] ->> endobj -2077 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F41 925 0 R /F53 1017 0 R /F23 726 0 R /F55 1025 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2086 0 obj << -/Length 965 -/Filter /FlateDecode ->> -stream -xÚ¥VMoÛ8½ûWè(+–ß"NâdS$N6v€mª-;ÂÊ”×’äßïP$]Ùa›CÀJ3o†oF$ †?’(0Ó<É5G‘,·#œlàÝ͈xL@Ùu±}ºfy¢‘–T&‹õÀ—BX)’,V_ÓÉããtvuûeœQÓ 4ÎÆéýdö<¹sÏÇš¦“›é|œÍs Â,Nâôivu™]>Ì®o¦³ñ÷ÅçÑtq¤5¤N0³œþ}ýŽ“dðy„ÓJ$¯°ÀˆhM“íˆ †g,<©GóÑ?G‡ƒ·ýÖX)¸PHP.“LP¤0× #, ÿ,çI­Ö‹’X½ÊÖ+;Ø{ì¶pÂ{äÂvzã)Õuó©)‡Ödš Î.â—R0aö8Pç]þðÙœRÁòJËx̶0‡¢ö©6ÆVqs€ƒýýåžîÇ*=/+5šIs†*8šiFó#à <­A1ãLÂl‹ -‡]ê¤ Ët·¯LçÌÂýk‹í®Ž)[ÄØ‰®m䘰%4ú¹®ûfåŒe³w¢hwYUf9 ˜ªHæÄêöMÝFâ1PmN¹Ú o`)<&Þ€‘"~Ú:p[+S˹óûá“q‡i[î*“ù¢ne:ì!š]쉔—kÄqnŠ-´Á¯ê«íˆ 'ñ¡rÖˆäZÿF:‘vç}6ŸN]œÉÝüáãf³Þ¿aüÀ0Hƾƒ}²tï”68NQ"hêâvvå¶jOjµ­LÕvÐK%Oåºt3Kßš÷®ý"/¢R†Y? >¾¾§u™> endobj -2087 0 obj << -/D [2085 0 R /XYZ 85.0394 794.5015 null] ->> endobj -2088 0 obj << -/D [2085 0 R /XYZ 85.0394 687.41 null] ->> endobj -2089 0 obj << -/D [2085 0 R /XYZ 85.0394 561.6045 null] ->> endobj -2090 0 obj << -/D [2085 0 R /XYZ 85.0394 501.5525 null] ->> endobj -2084 0 obj << -/Font << /F37 791 0 R /F21 702 0 R /F55 1025 0 R /F23 726 0 R /F41 925 0 R /F48 940 0 R /F39 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1187 0 obj -[694 0 R /Fit] -endobj -2092 0 obj << +2122 0 obj << /Type /Encoding /Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity/lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal 144/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis] >> endobj -1598 0 obj << +1627 0 obj << /Length1 1628 /Length2 8040 /Length3 532 @@ -9354,7 +9515,7 @@ endobj stream xÚíte\Ôí¶6Ò ˆtÃÐÝÝÝÝ¡Ä0 00Ì ÝÝÝÝ’‚R"‚´t ÒÈ‹>ïÞûüž³?³?½¿w¾Ìÿ^×Z׺î7¶‡Œ5Ü ¬‡¹rðpr‹ t´P(ÐWç…C­fL9g0ЇÉ]Á¢#°5@ ðòxDDD0rp'/gˆ­+€ù‘ƒ…ý_–ß.+¯ ‘.[€ññà …;9‚a®ÿã@=0àjØ@ `€œ–¶‰Š¦€YIÓ †P€¶›¨C@`˜ ˜`w@ÿ:@p˜5ä÷Õ\8¹d\@€‹y {‚ÀN¿!v€ØÙââòø €¸l0×ǸÂêfý[À£ÝþG“3üÑÃñ{$Ó†»¸º€œ!N®€Ç¬ÚòŠétµºþÎíy„p›GOk8Èí÷•þ`4¨+s¸‚=]粬!.NP ×cîG2'gÈn.˜í¿°œÁ¶@gk(ØÅ呿‘ûwuþuOÀ¹=ÐÉ êõ'þÇëŸ ®.`¨ '&ïcNëcn[ “ë÷¨¨Àlàî¿ìÖnNÿÀÜÁÎ -Äü{fXE­á0¨ÀlƒÉ¥ w}L `þŸu™ó?×äÿ@‹ÿ# þ´÷×Ü¿÷è¿,ñÿvŸÿN­è…jÁ‚ÿxcê€ßÌs:B ^ÿÎýïžFà¿4þ;Wàc!d`¶Íàáäæù €¸(B<ÁÖÚWÀ}¬Ô»Ìì …ÀÀýSL7÷ß0};Èö»ôA`˜õßå?6éx.SEM#¶ÿöªrèA§Ë‚GPè¯íÇ9pÕ÷rþo:# ¸õ?¿ùdeáž^7Ïãú=*áðû7¹ÿñüë¬tu†x^psr?Fr~ÿsÿÎýOÀìo4 +Äü{fXE­á0¨ÀlƒÉ¥ w}L `þŸu™ó?×äÿ@‹ÿ# þ´÷×Ü¿÷è¿,ñÿvŸÿN­è…jÁ‚ÿxcê€ßÌs:B ^ÿÎýïžFà¿4þ;Wàc!d`¶Íàáäæù €¸(B<ÁÖÚWÀ}¬Ô»Ìì …ÀÀýSL7÷ß0};Èö»ôA`˜õßå?6éx.SU}9=¶ÿöªrèA§Ë‚GPè¯íÇ9pÕ÷rþo:# ¸õ?¿ùdeáž^7Ïãú=*áðû7¹ÿñüë¬tu†x^psr?Fr~ÿsÿÎýOÀìo4 0Üú÷äè¹aÖÃöOÃoäæìüØã?ûÿxýœÿŒ=ì a.ÌÁAb¡ö™9Y® Ä£ò/z{xœ*Þè—ÖÁ»2#×Dj,ïêÃ8›ÇEµyÍî;Ýoª²n öA™ºÓÁß‹(üèX>ã.3v±ms™W`gÅúϨ¯"› rn­êèš—ß¡RŽwð9£_²Ò¹Ð_8=óe4%v>oFÀk(Ù?`LÙ½¼`êú4ð±ûåÃ&9[~ƒ˜;26cLà«|r)Sƒj…×Íl(ßÛ b¬Å7ÎßÊçÏVð™h9Žù,¢I‚°RÊ• e®äß·RÆ%=²ìÙ êt›œ(†Ì%³LÇî)®Ž>1Ù¥‘„µ…^Ñ2¼éˆO£Ý %õ‰>•pjÕr{2–ÂwÍ<–g¬™-j—!3cäáakIè,AŒ$ÁLˆÇÆ‹J¯³nöùU»Ïm›Þ‰D3 @@ -9377,146 +9538,144 @@ $O t‡Í=žÝbóÆÃwî6ß"£“˵?”JËOP2RÐ oQo+†â1)©w†¦ÜèådîI½ÈZ¿VÍ­(e÷åû È"QÔüFØs(úF$'‘qL ®/¶!õÔ ¤HvkÖ‰Œh¼È‰¬ê؉á¶o?Ùa:Šÿ±qêcŒ° gã!_QÇ~ÏWê¡1üaœ¯UÝGmã§Yñmn%ìRãr9÷¬ß0qˆ5†/‚E…(êÚ“†,W‚˜$Ù½ï¶åçLxËÎÔ|ú奕£w†Z|ÂV€ãž÷,éOd ÞyŠGÝ ŽÎ¨Ý3lÍ4©¿Î\×T2Zª½Ag—.7Ù#ÏPæï™v¼eŦQLÞ»±Oþ¼Ô\’ ¬ÿĵJÅñ¾(š3Ç].Å*,MÎ>ÛBx(ÃSÃó|D³uû‚Þ¡ï†{:Ò‘Á¨2G9¡Cê{É•<|?ÒK áéá@F)Ø,êw÷ó?È ¸¢Ëa„Çh%Ù±o^Œñ{‹6™Ý @¥-«ä%Å~jÉwXjz1îi´·î¬%uÕ3^¿±g¸`d+ÎK[ŽDe—„]âò†YèÖýÇ?Ï>£³HjË,èkѸÍhÔ8Š” ™v_Å [ªJÖ®²9m=·âú?\‹k>¼à¬‡¤*³Ñ³ž,Y ê<‹ý¹uÓ Z/ZV$S·é#ƒmNOš¨5M@¿§rãÝ0Hõ7¬&7[àçŽAØñêOõƧÈêÚ5±pE6~d»Ž^.x¨T1¬µ¤$£Í7¿ÿ4òÆêüj§‹G1¬èípoóÌ3³QýÐZ:œNÍÆéç,0½‹ЇZg‹ðâ£à)‹Q©¯³‹X""œÛÆ0ÏÁ¾äBvFA‚)Y9(ÎYÖý…ì¬S…|¸Ôü¾“qbæÇN.LÔX§…_ï‚¿œ%%½¥åŒìé|°D>W²7}C–Í#—ZR¸­$º`bÛGο…a¿9gÝS%\”Á/œîñhC|?s§ Ø…šg¯ÎÙÈ)ª¬m}ÐvÖËk†Ÿ.bÉ&O üõí+uqfº`Îa‡„°£â,I§ã¯½/‘˜÷ÇÝ›Á¤'P6ߢH‚Ú?÷›½šÙ¹˜Žà9¦ŠmHr7:pMRYŸ#£ 'æW¥¿ðKCß|-¡mWÝ躖ná²¶Ë0–«ÞÐ3äÛÙ=j’¸Ë-,n–³e±€¢üb½iÙ;‘˜Hâ°l<)žL.ßÐYÖÿ°Ú·)wL=(‚Œ£± L|)=å'ÀÆ-Å@²öò¾µ<ÃNrä³6îµEôʃ3±d¶kÓ»¬ÿ‹%ôµøü·(kD~ô(¬_yñ‡Í; ¯åä²fùOî{&*‰äyÒ¯9ÛB±T¨d>è.òY[a-³ZyÏ•px9ÝØÜ>穾„»*|,4°ç Žð=Ï añŽ©{ZwLVqžCÅo, H;ç_7Gg[åGx d½DŽ…*~ÂJSÛ/ *ûÎÔF‹µëújQ‹jw Ý]_-Òq;Œ,1t³õ2ߥÆíËòê{:Ö§Ùo$<×ð¬žôôJ©Àëóüλì„b›F=ÍçåcT”u;ÐuË›÷#³»Z1q“ÒYÖgHŠ^fiyv|‰¢,PkŠA±¢FH£s^…EËRôƇnQWEÛt%Ú·y3™{æÈŒõFbKã<%Æ)â"-L+{墒zS'“#é²ÊòZÃ+•÷U­Á׎#Ç©ÃCcæHŸ,êä;÷=íÏô .óYäg:¯jÔn¹¶Æô×êS:c¤¬UºW¹Þ/Ëf¹ŠšcO¥ÛøŒM¯lD‰Á¦9²ú:­ÈùÈßÛ˜ìÑËr6½õx§ç±2ú]úS¹‘ p7O¼,j1îöÐËÚ{ž$ªS7O–xYŽróæs÷â»ì(è˜Ýš‹ÏD‚@§­Y#žC²L%¯íáž›1A•ø©3¾~M+ÖAîDí>¤¶¯cãµã-Nˆ¥”ûÚÔß ÄÖtzâ"¹tãØ'>(˜“”hSðÕœM]ˆÎÛ…0ìŽ ñâSPÓKD³—dOj nÌó®|KHtÞ‘Ñ+㢟S'÷@6„iõ“¨C,÷ág3B½žpÖáΡÄêφÖÑn‰Ü;ɦc“ _7T,Q1çTiHøBÕWL8­¡¾  ,œ²£.±ß u2†)¶=–Oš ¹ÿêÚ´­Ùê², Aq¨¿râ^T!1í¢ëç2)áN\§‹¬‚)æÄËR…Ëbž÷ž6Cb5ü´çêÞ›Ô;ð¶¹mH“üÅL¸^Ȭü¤Ý¸Ê {>«m@Ë›ðzéN‹›´×»ÔÌÃBÿ]¬—š@)õp[jÊâá…6ë¶¡²BSHQø×¨.öØ«N÷Ž`ðG¿§zŽ^n)?ìû±«892ÉÿxÈÌÄ÷Ù%¼­Ø3ÕÎZJðô]\ÿ^¸Äé„SXA㣅¸r}[(â0Ò@¥elöÉmi¶ö­EWÕ9úQѲ´ˆC¶Û¯µAñ=°g>MF{Q’= †*Ëk¨+™×Øõµk¤i@ïħÕW:x<›ó"Í}<=<²šC½Q¤4Æð÷i©UµSöA-ÒiMÛk×qnñÔÆèO“¦R<)D¾€÷/ÇT#î¡ÍM© Æ$ÖžåÔ3³Ð¿Á¢\ç{Uª÷Þ<UW=ˆ$®&<ƒªZ€0óØÒgÒR*¹ÉÒO¦1‘'£ùŽŠj*5wË-·‰ûùT j4ÝióÍu``òh߯µ“K…ݻʔÑk‡‡A›”ôÈÔDôìtk¯ö2ÅÛö÷ú—¨§$ÌöZ¥ï@Î^ùÝêõ^E~§”Üúí¨u4߉<*ôޱ§¸KJßùy/žn•C*}…ÃåLgI£J·8jŽ[“Þ³ ”ØT7%JÈOïä,Á!ØžÈ+ÌÁ¯f—ÉȘs‡h`Úq¢O”1£<ƒ3(©dØOfBOŸ º'"p=Q£B¿âäpJ}ÝØü™ŸZ®¤!p{òëÈa}÷qÑ¥³äƒ£DKXôžòxÇ(žÏÑã ©¨“{ÏçÉšj¿dqX·ã·ŸP¦Üv£ä£Ï€³i¬¾AÕ;³@øyŠ*œoLœOœÕøë…ú¾›ºxOÛÝËc -@YšUʳªø;žBiäMÖð.•\rž;ùU´¾Rø'î…ç)眄š˜ …@ƒi/_ A®ÉéÙêr«0áFx<×Er;¾zÇ´UÏšøSÂö²Ù„.¥mô÷Œhâæ¨É2Ø’ç/{I;õŠjÑm÷¬ -*s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€޶Xo³êÙ}U¹ôZø: hÁ‚)8f÷EµÔëÛDäµsüð¢ qTMŠ:ù‘ɸX!±l®ûÔ”Ëû ΄,ñº17ýbŸgûŸ&fܽ×Y'jeAt ]ôÛïwV^þ%ÑåµÛR¼”tμ‡Ël¥¿é˜¦j¹„‚øÏ¸3èm>YjŸÖCƒÕ¸ÄžÄÈÊjbÆn“ªŒUý©?ô‹ïðu«ÈÃWøìý#ë,M€¾ߥJBQlމâXè-ebtxÃ]€s<—ÿ¢:XÝQ…¸w¶²-N;N¾?Vl¤‘vG‰…,Å%ë9êçöË'bìη9|1.…±!]¹¶DšÏó=RԌݬ¤Iˆg‰=Åh_ìŸ5rÿ/˜ÿŸàÿ  tv…;0ÿÐ$õ»endstream +*s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€޶Xo³êÙ}U¹ôZø: hÁ‚)8f÷EµÔëÛDäµsüð¢ qTMŠ:ù‘ɸX!±l®ûÔ”Ëû ΄,ñº17ýbŸgûŸ&fܽ×Y'jeAt ]ôÛïwV^þ%ÑåµÛR¼”tμ‡Ël¥¿é˜¦j¹„‚øÏ¸3èm>YjŸÖCƒÕ¸ÄžÄÈÊjbÆn“ªŒUý©?ô‹ïðu«ÈÃWøìý#ë,M€¾ߥJBQlމâXè-ebtxÃ]€s<—ÿ¢:XÝQ…¸w¶²-N;N¾?Vl¤‘vG‰…,Å%ë9êçöË'bìη9|1.…±!]¹¶DšÏó=RԌݬ¤Iˆg‰=Åh_ìŸ5rÿ/˜ÿŸàÿ  tv…;0ÿFsõ·endstream endobj -1599 0 obj << +1628 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 67 /LastChar 85 -/Widths 2093 0 R -/BaseFont /ZIFUNW+URWPalladioL-Bold-Slant_167 -/FontDescriptor 1597 0 R +/Widths 2123 0 R +/BaseFont /ZJTCSQ+URWPalladioL-Bold-Slant_167 +/FontDescriptor 1626 0 R >> endobj -1597 0 obj << +1626 0 obj << /Ascent 708 /CapHeight 672 /Descent -266 -/FontName /ZIFUNW+URWPalladioL-Bold-Slant_167 +/FontName /ZJTCSQ+URWPalladioL-Bold-Slant_167 /ItalicAngle -9 /StemV 123 /XHeight 471 /FontBBox [-152 -301 1000 935] /Flags 4 /CharSet (/C/D/E/H/I/O/R/S/T/U) -/FontFile 1598 0 R +/FontFile 1627 0 R >> endobj -2093 0 obj +2123 0 obj [722 833 611 0 0 833 389 0 0 0 0 0 833 0 0 722 611 667 778 ] endobj -1579 0 obj << +1608 0 obj << /Length1 1630 /Length2 6133 /Length3 532 -/Length 6981 +/Length 6982 /Filter /FlateDecode >> stream -xÚíVuTÔí¶VA!¤†”ºQº¤»{€!f€J¤SJº !¤‘RBpé–NI%‰‹~÷;ßYß=ÝsþºëÎZ3ë÷îgïg?;~ïFZu-Ik¸%DCrpsr‰€t4õÔ--¬¡pe)¸£µ"ÒÂtñ¥]!H(&c„ˆ€ô Ö ˆˆ‡Ä-,, `Iý\¡¶vHó  û_–_. K¯?‘›HÔbºyp‡8 0ä Åÿ:P !í ¨#$­¦n ¨*b–WÕÉC`×›"ÔÝ,¡V e¨†€°€là® Ç? +8Ìú«4ç —$dB8C¬ 7aO+ˆó/ˆä qu‚"7Ï (dëjCÞô AaVŽnÖ¿ÜØmà¿9»Âo<œn°2u8‰°r…:#A7YÕeäþЉ´³@þÊ€ÞÀ ¸Í§5ÜÊíWI¿±ši…!@Hˆ'òW.KÈŠpv´ðºÉ}Cæì -ý-à …Ùþ¥€ä -±µpµv„ 747Ü¿ºóW ªÞÂÙÙÑëw4ü·×?4@‘ˆ£ '€›ç&§ò&·-ÿZE˜ ÄÍõ‡ÝÚÍùOÌâú»AÌ¿v†åF„…5æè²†ØÀªpäMJóÿnÊœÿ¹!ÿFüðd¼ÿÞpÿ>£z‰ÿÝ÷ùïÔrnŽŽªNßA ?ï2è×EúuÓ@­þGŒ…ÔÑë_EýÝSò‡Ô_dÇþà–„ÙÞÌ„C˜Sø+!õ„X«C‘Vv  Ç›ný¶ëÀ¬!®ŽPäfª¿ -âàæâú¦mµr€ýj?ÿfýwí7ƒú­¬£©¡¨,Éö¯o×ß¾ê7[€Ôör†€þ;‘ž -Üú‡_LRRpO7· ˆƒ÷F7— /H˜—ßç_dýMÄý×YÅé -õqqrqqƒn~ÿüþu2ù,Ì -nýko´0ë›Uû‡álåæêz3áßoÿMáž/=â ±LOÀ­DƒíS3ÒUä9=ý2F:¸1zBœ‹k´_çûWÀÛýRÃ…ËÌ/*C8kE®š¼Æ·/W•X×z;È·'Cöò¨|èYÞçÍ3½d[ ›ã§}Õ‹òÞS^À4àÒ][ê×Ð4-º¸|Ç늽ÊâOïžïOÊpâLàk•òöÕƒÂÚ[ÄUÛ_™6OOwõ}ìén?¼û~•’-û£¨;&>S¤¿K6åSCRÙò·ª·ãòŽXXðð+yÏ—×ro1XçFèÅR61žêDžeâ§Á ×^‰mùkT³ïT ¥ØÜ KCvá)µKö±éû¬l´¾úï.ú¹üA¢IὬ}‹xp—ÆÌ:…x÷dlt×VEæ¹®ëºB4ߢé:°h`M$z¯=Ä*óù ?7l &?QäÔ…ÚvÆ<=yÊÙûÃ㎣²=÷'ºçä ÄAŸßÊ}gw‡U¸'b%6—=\5Æ„¶O€X)Ô| 6*˜Ö}ØŒôDVs§Up ˆíbëÞ­×…+Ïo_MX`êÁWÉC.Âß6¼|í½ÏÊ)¥2ÉP0–b®G+kGõýZŠÿåÆ~+`çÑáËé#™~KˆjîβÍ5—‚ ÿ3zë5½ó-o'‰ŸžoJ| öñ Õê…k¯Hî÷’ô¿/üž“â«7Rîõî°F˧€NÚ´…”QOÆYÃÃöLN߯e‡··Q&8LëÀ…cÙ Õˆ€éëèqo£F‚®ºqG’*¦²óà‚‹¥"ýbmÍHàv{(Ž?ªÍü-ë&wU¼m_A±FÀͼX[ÝuÞ80+l8]ò)áß½WMœ½RY.þä© Èóqº:Âo£ù¶ãí•MÑJôßY$‡‡Œ’`$íŠN î÷Þ×ó¨‡caíó )¹ óSçãa¼&ßi·õã¬P2ó§Ð„]¬ûãð#l3oñ{´„îªÌ ÁºqÙhiµGH‡:!F[ ŠcÙX±¯Á,þÙñ°“ŠÊP)½±×3 gwµy—Þ)¥åB¸*!œˆ—ÕëLwÑÔëe5íÕÄÆú¦d„’ÅÙ5jY®yr!Þ8RÖwòd€éî¨h:³ìç” Œ”´¹©¦úa!ǼÆêëÝSY·ÊhHçú—J§=\½ WšbN,8‘T‚Y³0©ÝZH;V$Ìëü›HÙñÙÞ¦eÊgTr>R‡>Ó£*X¿l WTh‚ˆsÝÍötº·)tÊ`D"ŒN€d÷¶kÅŸ×Ë)~>;ûHé¬\ýÉò%Œæuj Û²!>2M¤ |N¸»OŒÀ¸Å~Hª´+ˆ#Å"QÒ µl’9’kСA}S÷†né^W©]+žSüÁèû³,>VsIì)Í’©^ cFièr}Ú]ÜAƒŒ±9“"³ºÓÜö1x«ßiëÍ‚5ÃèÕp:¯©+Œ*‚_øˆ'û´”eÞW1qáÊã»NÞ`Ðß 'é »Îk+ñKÚ+ŸQÉ8¤¿'u l(-V;K!ªÆ¹áK‰IúäUW‹ÇtΜ%6QK(ŒžJAÿÝëáæ…\™F{3dk*ƒA¸Äg5’òœA±ë¥ÙgwA•,Ï\÷3jT¢÷Åɪ™œüRÅy÷wF#«(Ùá²Zá”Y„FÞì¼\>LÉÈäAÝ ŸËi6ô¸ý•dèEͤ„ o€8qørŒ0m+êñûƒkŠ a6u÷} ÓÁÙ&Qûó©„rìî:?†:è -ù£ÜÛõŒÚGa¾Tµ ˵µ;¥¬W~òn+–lO­4 o¥ø!=ËMS¸âØ(kb¡,D ZÆ8T'p—.ø;2S•cf‘¦>dÇvË%·*­7 }Åçj£&ã—6Y”«Dd¥×VÑà›lh`2爙0#·êZ=4í%牵7h%Å Y$Zü¬ˆv±?‘©‡É=áមð;Ïcc„—÷:IêÖá°5ž’”ö×yÇUµD2>ÃÙ}ÐŽvk2š>2òQ× ›yôASLPkQ¡âZõ>×_À -ZŒvR¸pdÎ& QºÒàî¯E¦âx|E&ù'Ar0Ëèh" ’çÏvÙý½Ï»ÓçêßV¤0²iRÂyO„jßÌé&šH¹£(Âμ4™ -V1-S8`_3D ÝËúÅ7BëbØ r¨Ãt©aÊÓêØº0‰¼•5ï´ñïâ¨Î)9É@[gbL¦')Ä?Ê„ãÐ÷*éT“꟱Eê+ãIõ_â‚R§—«·>noߢiŒ!L½<©35¢$2MIÝs™ôäu¢¨bâ8 ûVÇÌšDT£ä¶"Q TFÉ…Cóuø9dcÝI¥Z’f@A -»<¶ÚL9’00#†ô}à…ê¬ëè¾>€à)†fbˆù†7sÑ¿×ÀÅ}ä׊³ÒgÍ¿?FІæNP˜ké÷2è´à2|Ö§™¥£[¶WDMåtè3?èù:28¢È;Xf1S§³EŠ$´×å0Ä0d—5ŤÐ4|ybæ)OÄ|˜léË@Èu±}µ\"üSÀd5ŒÃkùp ü3ʇ×Î -+˜^p€&9I‘òÝÂcJ-Ù.Eâ.ÂÄSL”„Ä`4œÚÁ¤7\N>frÖi¼ÝÏPüTì,1êÈ@^'èMuèï\ ékJj§^ æü12Ït¦ˆLVéøŠ>iÜ猆ž=ZƒÎÈVO(Îʾu™÷ѶÏÐÔfh=}̹öm{âý”2¶£ÆI±»põ-¾¹+ýZC—±­ËôKo¹‰nÞ”×|ßòË?mztÖ9ÖåçÄe/°¦Õ•äÂúö*~”2è½ÞQšKþ´$Ï*§ú·æøšÿ]íùu¢@ñÁâ°ÆÈzúçîߥnK~£ÒwRdˆµU -”kx±saóÝÒ÷ÁÜ÷Kk ]ö¾ô3 ·/*ÉmÌKgƒwõÇ–ˆýIô‰ù¤ŽòŒ¿Ù=a£ïe€üvû# }Llb9_ÚEƒˆÓFHRòæ›=ë­GýTùH:ñ9ˆe¬ù6PÃ%BÒ§4ž£Ò.n+¿ƒª°ÿ9ÌèÙïc‚4Ã_gÇÓ¶ú‰s+>傹»˜‡¬9,Épª½è!׉·ïhuF ÒiU2Æâ-A6L;iY­"Û ±+hô3…RÝOïi¦¹Í —Š‹ä©ˆÏHžn5÷ò”JDýÉ›³¯pôÝÞó4ÇÃøJ~t‰•|§›19äÚ¸N±)¸}> ˜5.¶5Œ¥¿þ“ <ö¨õëGš±×1{!•Ųê3‚A-üMÉcÂ[ ×%Üû/¾¶°½9oØPO;fiv±}½•@ÜJ#(G9j>2š?¤Æ ñ?~ªÑWåïBç¡ÛµO±B¥™Ÿ†ñúÃ&e“v”3†­ÉÞ&™<)ïÈxbý'.¼Ï\Ì_³Ÿ±‡Ý'0þààõªckêUPe¤cne„žÁVó“pÜ Ê½ö>ÄÐ -½c–î3Ó5¬´0ÏÚEdÊŒƒH(‘©,ðÉôä‚Nnád¥,_½ù°/ä -ecŽ¡ñ³b2•ßÃÄœ¯ît¸âËA".0mÕjÛ;÷$èÓ#Ó“]Q;Ò­vü‘‡¦ýO ¢Â{'ˆÈ‚1N ;$F_Õ~@Ü©Jw“+gfCš§¸Aëßå~üv»s=í,€–ƒÔÊ‚ü À† -ÈÃñôß[Ƥ7œàÀfIŸŠ¿iÍPŽêb FDt¨%Sc<ØCÞ±‰¤_¥}#툎~áß\°ÕÃjC¾35𮾌ŠãÖEf˜ä÷q}ÔUp¬$Ú¿•×çyD*û*ݷ÷î@òQŒÞ7¬â¢¾yçã,£êìª%É0®š¹î³È6¸½}ˆŸ^½÷s®Ã´ÔøÛܪ{‚€79»#¼¸ùߣf²sË©W½ørÄ(€Db^Ð*A|üÙÀøä¹ª“ÐzÜÙ™N>uêתͲ, ¤Õè/‡üî¥IM€©*õO ÀgÆC”kìþ‡•—•ß×±GJ«€ŸVp+;çÔñG—ó±Ð¶"u¢»}e/—¤ÜbÎò7žÖ®Œ•0ð¥ëŠ[Fv7íXëÕ5Ì›ì¬É„Ac_ü¯ƒò{LEÊgL®ç'õÇlÒé'‹½6I Þž {Ÿ¯¬iëdºOIi옂-i©Š“b«U«B굦 HìK¹cÈŒƒ´úúipÏÈêµE[ªOâáÏx’"‹V)úÌZWïŸÖ‡ƒéüL¯Pã}<ÇY:{ˆÚ%~Ëõ( cΧçƒþCN…ˆ§tO&Žç„V™(7íuq›]©&Ä=5Þ¬£éÖZìržOÔ¯énuÏ)§†£9‚¨¢ß–Eä@Šz?»a`Yû äÄ Vnœþ˜`~i·R‘öÁc\Æ—ïî§%DJ^Ÿ£h˜Ö„ýΨڦ·.Jú«ùt…F^ÈòcXþ3OQ¡d϶0§,÷”Še&uùÙ¾ˆï‡OÄY˼zõ¹Wô,i9d•0nçvKîhQ"K•Q¾Zø@0M¨âÒ¤xÑRõ†‚›ÇŽ$J­´çwR0ˆ+Û6UÕ¾/שM”B®±XÆçÅÚ«'ªM]D›„]ÊQÈî]Ä-ucIg|ÇZÙdŽg>ÂŽï|ê™5È(ü…ëù®êè –ÄмÂNЕë4P“÷ÞÏîèÖ ‡8—‰$—ØBt¹úÑBCšÛöç™yxWûãz×±ÛýD0ϛȘÅñÅ„oJXOWi öì»×.çä_MàSgDd]ÞíR–}Áõ÷ã¶ÂŠ”È[¤«Ý†\~‘_ZÞ}ÕRë\à=cÆmï¢æŸH4Òn˜ ®/™Ë[ßlÏ¢œ\mÓŒ]Ë; 1ÐBVû \±–·´åµ‚µ¯ÊN*I"/ïm?áIÂÙNr©ä —ë?>}7›ùâžàÙZ˜æñ`kËG.¯–*O˃åé]®$£lì©VÌú‚§«/]´~è µW,=ÖÞDÞýQ C96­DñtÏeŘ'”V[ĶtûPðôÝûîú@ò$Æ.ƯúÅœï}ù½Ï *[7›#lUÊ[“|öÄcÃÅšgêDE2_¡ÃMÕ^}üÆkOÛŒäCã±åSPΟZc¯\ð̸™ð '-ÖÄ®1švÆeÐË“=û’Òk÷Óc½æÁ×í%ƒ‰á½: °C¹Ø\Ð`]“˘ˤ¦¸Xºr©·! îη¯Œ_‰_Tó¾ -Ÿó/°Kê¼-œ [—¿çÃq-øz~Ii‡³®>ëGGÈF¶Üšqˆ‹¢À¤^Ý µºÜzœòŽLy*Ø!$ëȯ²È¿Äøý9Àõ—x»Ë+Jé.Õ­”÷yKr¬àKñnD$ïÇÇûùSޏ+¹ºfS4æHõ¿ÞzyàÂ*/ç%Šâ×»Í ÏØõæãmº'7]ìå±ÅöK)ØÑÁ@£b…î\çÑÄÝÊ‚×[g“©»U©«ÅÖ¡’v'¯ÔíÌ¥ºiMD?3AqÑgœ‡ ÊŸ¼ίªóÑÓ3NoTšv [YAóOL®·´MHËJ°ý‡ãĬí«å Ä\]NG”¤;F¸<D†ŽR›æ.MÃ>ÂW5ßÏI“1øi^{Ñz·ö´·‰¾¯½bÅ=YV6S$øqr,påÑr·¦s<Ýþº•l+¢dÙôú~«ÉR1xøà`äÛÔ€²K[å.Nµ;ãUûŒ2ó¾jÂÓ’D€Ì»«™Ï5o~"Çý'…|¤0i"í.>_0'BT¦ž¹{Ñ`IíJÓ(`ÌW¾­ÇaKPÓŒSÃ$(L÷8k•·ýAcc·òd3–âm¸L>b@”©k?OÙ#ün*3oÄHóÉÐàCíúd“GW;¯y‡™¬.÷Ì¡@Ðñ}“à¤Ô-´ý^½R¸'EæòÑ¡wuº>ó<5{Ž´€KÃ7®Ì[NŠpÓèªÉš•Q•Ýk|}kÑçc(?72•­ã»9 -Òí¸FúïšyË«mn£°MWÑl‡ög2w™SçäSCþ¹A¡‰&вÈkª|3Ø`ê‡ÄcïÑ+Ó\ºŽ’3®óø‚ÿVŽ W$ÜÉÂÕð_0y§endstream +xÚíVuTÔí¶VA!¤†n†n”.IéΆ˜f(‘N)én$†FJ Á!¤[:%•$.úÝï|g}÷üuÏùë®;kͬ߻Ÿ½Ÿýìø½ki5´8¥¬á–y8 ÉÉÃÅ- +Òy¦§aáèha …«pJ핎 HÀÈ(ã +±@Bá0Y $D¤±ÉB¬@¼¼ #Hîìå +µµC‚XnxXÙÙ9þ²ürYzý‰ÜD" ¶0Ó̓;Äîì!o(þ×ZiÙ@! u %5‹‚šHƒ¸Þ¡áf鵩@­ 0„dw9þqYÁaÖÐ_¥!¸n¸¤ Âb½ ƒxZAœA gˆ«¸yA [W ò¦H8 +³rt³þ%àÆnÿ-ÈÙ~ãátƒÝiÀH„•+Ô ºÉª!+ÿ‡N¤òWnôÁmn<­áVn¿JúÝÐÜ H ( BB<‘¿rYB@ÖP„³£…×Mî2gWèon(Ìö/ Wˆ­…«µ#¸¡¹áþÕ¿êýSõÎÎŽ^¿£á¿½þ¡ŠD@m¸<¼79­7¹m¡0ø×º(Álà î?ìÖnÎbî×ß bùµ3¬7",¬á0G/5ÄVƒ#oR‚XþwSæúÏ ù?0âÿÈ€ÿ#ãý÷†û÷ýÓKüï¾Ï§–wstT³p‚üýyÏ€T@¿.Я›jõ?b,œ Ž^ÿ*êïžz?¤þ"û;ö·Ìöf&œ"\"X¡y¨'ÄZŠ´²ÙX8Þtë·]f qu„ 7SýÝP'7÷ß0m;¨•ìWûþ€ 0ë¿k¿Ôoå`Y=ͧ +ìÿúvýí«q³Hm/gè¿é©Â­ÿqøÅ$- ÷ysòqƒ8ùnäðp ñDø|þEÖßD<U-®PO777èæ÷Ïï_'“¿ÑÈÁ¬àÖ¿öF i³¾Yµ~ÁVn®®7þýößþçù÷ÒC ž+ÀôÜJ,Ø>5# YEžÓÓ/kô¡ƒ£'ŸFûu¾¼Ý/5|Q¤Ìü¢2„«vPôªÉk|ÛùrU™m­·ƒÌ‘¹=²—GåCÏú>ŸhžéûZ Ø´?í«^”÷þ˜Ê¦¡ ·îÚR¿æ3Ó¢‹{ÀÁw|®Øû§¬þôîùþ¤ 'ξV)o_=h!¬½E\U°ý•)aóô„¹«ïcOwûáÝ÷«”ìÙ¯pÅÜ1ñ™"ý]²)Ÿê”Ê•¿U»—w„ÄêÄ‚‡_)x¾¼–‹ À:7ÒD/–²‹óP'òÆ€,? N¸vðIn+\£š}§Z(Åç^XrˆL©GXrŒMß—ìdc§ õÕwÑÏíK +ïeë[ă»4fÖ)Æ»'c£»¶*2‡Ìu•ÙÖ£™øM×E;k"±{åè!6ÙÏgø¹a1ù‰¢§.Ô¶3àéÉS®Þ?pUì!¸?Ñ='g€$NúüVž;»;l"=+±¹ájy4&ôøë´}‚ÄÊ¡æ °Q™Ä´îÃf¤'²š‹8­‚{@|[÷n½.\ex~ûjÂâSÿ ¾jrþ¶áåkï}6KiÕI†ú€±s=Z9;ªîÕÒ/7ö[;_NÉö[BÔrw–mF¨¹]žÒ[¯éÇhy;Iþô|“Pâ±_®Ô(\{Er¿—¤ÿ}á÷,˜4½‘JÿШw‡5Z!tÒ¦(¤Œ2x<κ¶grú>0.;¼½2qøÀaZ.Ë©EL_GHx5tÕ;’T1•\,ék?‹n·‡âø£ÚÌßÒ¸nòTÀÛö• +atÜÌ‹•±Õ]ç°ÊÁ†Ó%¿2þÝ{ÕÄÙ )•埉>§«#lð6šo;Þ^Ùû¡LÿUjIpÈ(F²Ó®èê~ï}=z8Ö>ß’»0?u>Ægòv[?Îú 3MØĺ??Â6ó–¸GK让ÆÂ¬—–Q„tÈ¡f´µ 8™ûÌ⟠é?;©ª•Ò {=ÕtvWŸuéR^.„«È‹zY½Ît+@½^V×^Ml¬oJfE([œ]£–å›'â#å|'OF˜îˆŠÖ¡3ûÀ~.IZÀH)L›‡jªrÌg¬±Þ=•u«Œ†t®q©,xÚ3À-ØËpõL܉'òA€ªC0[&µ{C iÇŠ¤y)>û›çeLcÑ%/³FTU§€ÙÕô¨5« ð +½’•sJÜkŒ "êC 3ó®cUÉÙ4eHÎH~0+¾÷ìEÑOÁY^€ÝˆF›ÍŽTU§h§D´çéíçǽ8IÉ{éBDWžñ»ïÝR±FêÏVë®fûÆÊ¦îíqßÇ´L…ŒJ®GЧzTÅ‚ë—âƒáJM î;£2þñN÷6…OŒHâÑ ìÞv­øózy¥Ïgg)Õ‚«?Y¾„ѼN-áf_6ÄG¦ ‘”Ï w÷‰·8I•w…p¤Y%K:¡–-@2GrMú 4¨oêÞPÀ-Ýë*õk¥sj€#}–ÕǪq.‰ã!Åp£Y2Õ tÌ( ]¡ÀC»ëƒ;hbЀ16gRtVwšÇ>oõ;#m½YÐá³0zuœÎkê +£Šà> ä>-e™÷CL\¸³Äù¯“7ôwÂI:HÁ®óÚÊüÄRö*gTréïI(J‹ÕÏÀÒˆª1!øRb’>¹`ÕÕâ13W@‰MÔïÒ335,Gƒ÷î Ã'V? 9ZŽfjW]èUªŠÛ¬[ßÑY@ÞCLAíŸjÙÙ*+òæÅõÁÉÏ5~šj}‰Ûy]ç¼cñvË‹ Bxi9]'±|¤“²w/±2X®‹‚8w^+ÐKºDœ~$ìl‚Ý‚I®J5`žV¯ipw/¢6’ +}ˆçã õF´£ögºts£ng]á„Ö|Õ`ˆksÕ8;¾Ï»´²?…&@È™!*¦54[«*/„“¶sÈo?87Æ…ÑS)ê¿{=ܼP‚+»Ñho†lMe$—ü¬NRž3(Þc½4ûô.¨’õ©ë~FZBô¾Y5““_ªßþÎhd%\N+œ2‹ÐèÛ—ˇ)™¼¢{ás9͆·ß¡’ ½¨™”qá 'N_Φíc%}#0~?3¸¦fSwß2œ]aµo1ŸJ(Ïá®óc¨ƒ~ P ʽ]HϨ}æKU«Ù0¼Q[»SÊvåg à¶"hÉþÄêYá­ÿ/¤g¹iŠWœeM¬”…¨AˇêžÒGªrÌ,ÒÔ‡Øn¹äV¥õ†¡¯ø]mÔÅbüÒ&‹’j´¥‚LsNù£97œ{xØ4()Ûó’:ÍÕJ QɉÓ4âQxŸ6êw´êú|©:T™$·Ü½Ê·ƒµ +Õý‘–”øÑ†1öã9ã^Ìæ‰ÍDqfÍEK–º¨ÖÆ¢ñ—Šˆ™b+oŒÝ-.4‡u˱A—†„‡ÖŽñŽ\ß·ì$&ªH=ˆð~„v^f-ÔpžYÆSD“Ÿó=²AŠ5bµXî òàGzŸV·å|ñ¯¬ ôùÜäµqFÿ‚Ox·Fšk†dMÎV{žPzÛ`%õÅl˜m—eYqªÆXÿ»t›y_o‚*…»”ëü`8™dÈWLUeÛ|êæl UltŸÙ|¹»Dl3Ö£=ÍÒshí.‘È/œxK÷,,AãaÓ¬)ŠWtíB²J*=Ý{†!f»Rq„mÃoœ5¤pìhrßµïdé0æÀ&øyž•Š÷Ïï[P-qµÎ“ `ýB!aþa`Wf +pR°‚šL\(hG»µM™ŒüÔuÃf}ÐÔZE¨„V½Ïõ°"„£.™³ÉJ”®<¸{çk‘©‘IþIü€dLÔ2:šH“äùÓ]ïóîô¹…z¡·)ŒìÏ)á|'µoætM¤ˆÜQáŠg^Ï™ +V1-S¸`_3ÄÝËú%6BëbØ r¨Ãt©a*Óغ0ɼ•uï´ñï¨Î)y©@[gbL¦Ç)Ä?ÊDâÐ÷*éԒꟲGê«àI÷_â‚R§—«·>noߢiŒ!L½<©35¢$2MIÝw™ôäs¢¨bâ< ûVÇ–DT£ì¶"Y \FÉ…Cóuø9TcÝI¥zÒ³€‚*lõ™s$a`F éúÀ µ (X×Ñ | |ÁS +5ÌÄ÷ o榯‰‹ûȯg¥Ï.š%~2Œþ  Í“ 60×Ò3îeÐiÁeø¬O3KG·l¯„šÊé:ÐgyÐóud6pD‰+v°Ìb¦N f‹Mh¯Ëaˆ>.`È.kŠI¡iøòØ"ÌSˆå0ÙÒ—ûbûj¹Dä§ Éj§×òáøg”ŸV0½ÐMr’å»fJ-¹.%â.ÂÄSL”2 „Ä`4œÚÁ¤7\N>frÖi¼ÝÏPúTì,9êÈ@^'äMuèï\ ékJj§^ æú12Ït¦„LVéøŠ>iÜ猆ž#Z“ƒÎÈVO8Îʾu™ïѶÏÐÔfh=}̹öm{âý”²¶£ÆI±»põ-þ¹+ýZC—±­ËôKoù‰n¾”×üßòË?mztÖ9ÖåçÄe/°¥Õ•äÂúö*}”6è½ÞQžKþ´¤À&¯ö·æøZà]íùu¢`ñÁâ°æÈzúçÃîߥoË~£ÒwRbˆµU”ox±saóÝÒ÷ÁÜ÷Kk ]ö¾Ì3I·/ªÉm,KgƒwõÇ–ˆýIô‰ù¥òŒ¿Ù=f£ïe€üv™ý‘‰>&6±\/í¢AÄé#$?)ùòÍžöÇÖ£~ª~$øÄ:Ö|¨é!åSš‚@ÏQi7KÜAUØÿœ fôì÷1Ašá¯s`„i[ýĹŸÎzÁÒ]ÌKÖ–d8Õ^ôûÄÛw´:£é´* cõ‰ ¦´¬V•ë…ŠÚ4ú™B©î'Œ÷4Ó\fKÇEòVÄg$O·Æš{yÊ %¢€þäÍÙW8únïy›ãaü%?:‰ÄK¾Ó͘ro\§Ø‰Ü>ÊßÇÆÒ_ÿÉ ž {Ôúõ£ ÍØƒk ‚˜½Êb9™¡ ¦ä1‘-kˆ2n„ý—_ÛÇØßœ7lh¤³6»Ø¾ÞJ aI¥’§5ÍRçƒø?Ñì«òw¡óÐíÚ§X¡‰z–Ÿ†ñúÃ&e“v”3†­ÉÞ&™)ƒÿÈxbý'.¼Ï\ ,P³Ÿ±‡Ý'8þààõªckêUPe¤cne„&žÁVóãpÜ Ê½ö>ÄÐ +½c–$îSÓ5¬´0ÏÚEdÊŒ0ƒh(‘©ðñôä‚Iµ±¾»Ú» :—2´Ä!<|^Þ‚X2›/¾5obÿd¬ë¥KºÃwƒø‰Õ˜ÞMG0C&ÊØjãž;áÔ+=ÃÜãÍEXr#à]Cg "}Yá¾.¶aýìY³ÆIˆ/^Y»}$oί8 lU†ø„=O'aFX²Åï9hRÔ¤[ÞÞ[ù~ˆ[ró—M~“j…<·ÑVG½‹Xî//¨šá‹ÉVà²hÑi·¢·æÉå6I?,·%F\œÖô™–@êõ~ø†Yý E>eUλGwü^‚}« 2ë$¶Íð‚ +ïcñ•ñZ×™b”[DÌÛ³>Â&Õ—ÂaY Kê{@”¹¸’QeUSæX6»ð¯CvòàªÇ£hœ½a¢ª§é›ßôóƒòêªÎ1‡(‡(-Ô±ßV”ÓyCC..& +®Æã +7/ƒ[\ÉcçtFqóÍÍhF4®¾¡õz»Bö¯ ÐØóÜE™Œ® #ôÃëÅš[È +ŽM®Aµì)ÅŽ¡ArjgWLØ;'·p +²RV¨Þ ˆ|Ør…²1ÇP‹øY1™ÊïabÉWw:ÜNñå$‘œ¶jµí{ôé‘éÉ®˜ ,éV;þÈCÓþÇQá½DdÁ'†RG£/º÷ê‚*8VŠí_ŠÀÊëó<"•{•îÛá[w õ(FïVqQß¼óq–Qõ vÕ’Tw͇\÷Yd›fÜÞ>ÄO¯Þû9÷aZjümµ=!À›œÝ>ÜüïQ3Ù¹åÔ«^ ü9â@"ñF/h•>þl`|ò\ÕIh=n‚ÜL'¿õkµf9VÒjt‹ƒS~÷Ò¤&ÀŒTú'§$à3ã!Ê5vÿÃJáËÊïëØ# ¥UÀO+8‹•sø€£ËùXh[‘Ñݾ²—KÒn1gy‡OjWÆJøÓu%,#»vlõꀖÍF¶d À±/þˆ×Aù=¦¢å3&×ó“úc6 éô“Å^›$oφ½ÏWÖ´u²Ý§¤Æ4vLA‹–´TÅI±ÕªBU! õZÓ¤ö¥<1dÆAZ}ý48Ì3r:AmÑ–“xø3ž¤È¢U +ƃ>³ÖÕ;À'uãá`:?Ó+Ôx`ïq–΢vIÀr= +ȘóiÀù ÿK1â Ýc‡É…ã9áU¦ÊM{]\¥fWª OÍ7ëhºµ»œçõkú‡[Ýs*©á(DŽêƒØ·eQyУ¢ÞÏnXÖ>9ñB•§?&X^`Ú­T¤}ðØ—ñ组ûÆi “R§×ç(¦5ác¿3ª¶é­‹’ùj>]¡ƒ‘²Ì ËÊë)&œìÙæ”åžR±Ì¤¡0Ûâýð±[ùW¯>óÑ{EO“–C6Q ãvn·äO0€%rTå«…„Ò„û(.MŠý!UoH!¸yH¢ÔJ{'Eƒ¸RñmS5íûòÚD)ä*‹eü^l½zbÚÔE$±IØ¥œ…ÞE¬ÑÂP7L¶Áw¬•M–x–#ìøÞÈ'žYƒŒ"_¸?‘ïªjy@ Í+ì”]¹N5yßéýÜèŽn rJp›Hñz‰/DW‘k-4¤¹m^‘‡gq·3ÿл¾ˆýØî((ŠyÞ|@n Àœ(–Œ/&|SÂvºJK°gß½v9§ðjŸ:#"ëòn—ŠÜ &¨¿>P´DÁ"]ý6¬àò‹Â‚ôòî«î”Zçï3~h{5?øt@ú¤‘vÃu}ÎRÞúf{åäj›fìZÞ‰²ÙOàŠ'°¾¥-¯ª…|U¹ÐüpRIyyoû1oBÎv’K ¹\ÇÌ|ún6óÅ=¡³µ°gǃ­-¹½Zª/¨lÝ4nlްU-oMôÙ“ˆ o:œ©Í|y„7MT{õ ¯=i3RÇVHA9jQ¾rÁ3ãaÂ3œ´X_¿ÆdhÚ—E/Oö\ìKɬÝOõš_·— &†÷ê$ÀuæbsAƒytN.`.šâb™Ê¥܆€ð6é瘯l¾}êÈg|ëwRŠžhXŠs×L84ØGê} 1Y³mgzÑìÅÓŒ$»9ñNh‹Í”ŸâÕ÷ºXsm{Ôg"'H±¨ª®RU\O¹<Š>ÊlSñ" + ‰ôt.CB±|…—(z?п)|Æö…›‡8csa4«ªy=~U»+jð*Ì8Ó“«&ÐÐåÇw?´,IpöÛ7oå¡#½Ëõqw¾}eüJü¢šïUølœ]Rçm‘LغÂ=Îk¡·ÐóKJ;œuY8:B.²åžðŒC\„0&õê®X¨ÕåsÊ;2•©`‡¬#¿Ê"ÿÿátökä÷g\âiì.¯(å»T·RÞç-ɳ/%º‘|™÷ó§qWru?̦hΑê¼7ôòÀ…U^ÎK:%į v›AŸ7pè1ÌÇÛtOn4 +¹Ø+`‹ï—Rp 36‚FŊݹÎ%:b‰»•¯·0Î&SwjÒ V‹­C%#N^©Û™KuÓÏy,ÅEŸq&¨ãò8¿ªÊ{D LGÌ8½UTmÚ5leUÍ?6¹6ÞÒ6!-+ÁöŽ·¶¯T(wu9eQ–éáö:Jmš»4 û_}ö~N†ŒÁOkôÚ‹Ö»µ§½Mìð}íîɲư™qÀ“ë`Á+–»5ãéö×­d[%˦×÷[M–ŠÁÃ#ߦT\Ú*wqªÝ¯¢Øg”‰˜÷Õžà$²dß]Í|®yó9¾è?)ì#IiwñùŠ€%z :õÔÝ3°ˆKzW†Fc¾òm={‚ú³8uL‚ÂôwÌY«|í»U&›±”n{ÀeóbL=Xûy*áwSYø"FžN†j×'›<ºÚyÍ7Ì4`u¹§h‚Žï›Ô'¥o¡í×ðê•Ã=)2—½«ÓõYæ©9rd…Y¾qÏà`ÞrR‚›FWM†Ð¬Œz¬ì^ãë[‹=Cù¹‘©nßíÈQ”iÇ5ÒoÔôÈ[A}s…mºŠf?´?“½Ë’: Ÿ’òÏ +M0 V”µ@¦ØRšÁSÇ8${^™æÒu”œqÿ›ÀÿüŸ °r„X¸"áN®€ÿ'yžendstream endobj -1580 0 obj << +1609 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 66 /LastChar 78 -/Widths 2094 0 R -/BaseFont /URQILA+URWPalladioL-BoldItal -/FontDescriptor 1578 0 R +/Widths 2124 0 R +/BaseFont /DGWQKG+URWPalladioL-BoldItal +/FontDescriptor 1607 0 R >> endobj -1578 0 obj << +1607 0 obj << /Ascent 728 /CapHeight 669 /Descent -256 -/FontName /URQILA+URWPalladioL-BoldItal +/FontName /DGWQKG+URWPalladioL-BoldItal /ItalicAngle -9.9 /StemV 114 /XHeight 469 /FontBBox [-170 -300 1073 935] /Flags 4 /CharSet (/B/D/I/N) -/FontFile 1579 0 R +/FontFile 1608 0 R >> endobj -2094 0 obj +2124 0 obj [667 0 778 0 0 0 0 389 0 0 0 0 778 ] endobj -1366 0 obj << +1383 0 obj << /Length1 771 /Length2 1151 /Length3 532 -/Length 1711 +/Length 1713 /Filter /FlateDecode >> stream -xÚíRiTSבª¡¬2©¤j=,ŒiF !¡€D ¢a”Abî ¹%¹—^n )ƒˆ•TeYÄF—Œ¢¢TXUê€RK¬B 8‘VJXÖ"U«"àÔ ÖÕUúó½_o½sþœýíïìýïlš[„Œ!‚° p0† “#R©„Ãä™Í¦Ðh8,' ’°p/°R«Üe€Íò– y| - bizIQÀ#>Aâ‘Æ…R9¡‚5d …\ d˜ =ˆÔj°vâF:X §Ãx 1)€6À)JaMh’ J ðßÀ6ím*ÆÓIQÀcR&"! Uë+)¬pŒì“Zþ²¦ÖªÕárÍDùI§þ•—kµþ/¦IÓ0¤ãèTj üFœ†­fjVBÈÕˆB„¦¨aÀà,g²—¿Á‘ô`DC¡P¥\Oâ0 -MUBú7©ƒµZíù××N&#äJDêÓ`Àþ›=sþŽI“pDâÙL6›CÉýö”8¥™U`‚¦.Ï Èq\®§CDF<Å -Á:ëHÅ,&Šä@:“”N™øW/6`©áôô ô À¬”‰Ù#Ý›Àþý´€L—ÅXÆ .lÅ^î ø¤Aoc%Bz -Ã:XA1ßÀ>[>Þ{j[M®¸ªó¨-=}¾ñð–ös[O}˜C½>N×ðÆ#áþpÜêø1rÌ¡d8ì+¤äõQO‰²MY2ÖÖG“½ ½bŸlÆÅPBÒ´Kem­ïil¿k^hIkô|ð“ûÓ;çlëVÝãð+©Ã…ÓknÞxù87ucGŸÙîKÈ}°„’XvzÕ8ú×;EWÆï‡`U˜¹úÒÜ„}O_™©­·»SoÙ†2©Íu£ï‹YlºNÙßAáìO]hŽ-¬” gÎ÷º]nVïûºcýš›Â¤¿Ïè¢ ÜŒïvKòsJBc$Q#óŽV8)jæ©}Cª©Öp}ëºz¡ÀR¿&ß)µ¾“ë[ÌIkÜC[›<ö’öÇ¢ÓŸ$>ÞûìµÚò@‘åfåz|ZŒ§÷~ÿ Ï!z;›j{õ3“[œ\õÅ]BäÚk·ÂЦùÁ¿?»yT -b×ó\nùÌÝ̥܎iö–(]çùu“iw‚Xg%ˆ»ˆ~Ô_ùð·‹-†ýܤàÀøÞä3‘7=/Õ6œ¯ -r®-˜žhj -®ZÔ4ë˜ëæç<ßg¶ƒ(Á T;ͺuE÷Ug³xãc Ž ½t¿ðü±$ÊÔ8|ØkA®íàæy©;™÷#—fyÿns.¬6Yßé]{Âôýœ%{¡ÈlÆš½©ÇjÂj¶iô³öÔ?䨔gŸ}"júNY†:°O—ÒÛhë/×>"Š"žW&3ñ8ÿ3-­(ŽZŽeepϬ^ÏóIHyÕíwxíÁê¬]<º¹|Áöõ¡]Ï€€š&þ´$÷õ–‘ž­£¸©=ÞŒÞ=j¼ý}"Ø|ö £ÖÝ7ö«Å~-Ժ󿌮XÃà:*#³Øê8ÏBëþqÔ\©©u¡A.–Kò³«Iêü­ä‰+jjN3l &h‡^ž¨*‰fåZzVœôr#VV -QÙbÉ)õR«i·§>.qµ<Å7¸Êo(ß ùߪˆX7R1î{§k\›ç|y¸°ãçÓˤJéëxÙžä¹ÊL½®sNfSWé<‡r] ÃcËéÕYŸs¿8ehÜd5—D@ßX«Ú·]s¾m¯álŽè¸ÏŽÄväÛ¼›S¸’Jý5,®Õí« -µôÙq13êýÓh×RqÉ+ë¸èºÁv버C\¡S£¢±Þ°ûBe±ýGÑê@¼42_Ñv+ióÊ!i]Ãñ]vÛ9UÙÅ]³ šgÌß±é'—GK2d_®ó;ÇÏψ>ÌëóŸõ­ûÂ"%åœ,WH¹+î Í~æÿÝ{Ð;¶A#‹Çœ1<·¨zO{—K†.wŠn¶î¦Õv©›ªK vKg×8­'ÄáPûeáUß]íÅí¼OÚÆ¨Kˆ¯âO.uùZŸ\Ä ê6< iY• ¡‡[° ûðÞF§6f^ž¨4 ëúÎaURCǵ²¼ŸÑ(Yu¼­jß,NT˯m¾P`3ãÞWâ>ý&¹š?0z^Ü’xµçó‘5;ø/̉,zbCN¬èæÍ1ox’q(¿ŠZÛÏþåÿþ' -(Ô°'0O¥ü ÛGŒŸendstream +xÚíRkTSW‘ª¡¬òRIÕzX%2yj   `, ‰¹7ä–ä^z¹¤D|PIU–EltÉST” +«Š@} Ô«0|‘VXŽƒT­Š€¯¹`]]¥?g~ÍšsþœýíïìýïlšG”Œ!‚°p(† “#ÁR©„Ãä™Í¦ÐhÁ8¬  Q°p¡Óî +Àæ y+„<>…‚±tޤª àLŸ$ñH ãˆR©‚PÃZ²†R¡2L‰À„ D X7y#¬ƒ3`<†˜@ˆ’áT¥°&5IPøoaH—þ.• ã¤(à5%“H‘†j ‚UÖŒì“Zþ²¦Õi4kÚÉòSNý%¯Ð"Ãï L›®#`H1ÆÑéÔXø­8) !:íô¬„Ph¥MÕÀ€ÁYÉd¯|‹#¡ˆ†¢B©*…&žÂaš®„ôoJ+V'yÿþµSÉ(‚цt°ÿ`OÅœ?bÒ$у6“ÍæDr¿;%Mk&F•„ ©€Ëó +W(ä‘9A!X`=©˜ÅD1‚¼Hgr€ +Ã)“ÿêÃ, œ‘1‰¾¸€•:9{¤{“Ø_Ÿ„éŒ\ÀàòÈV앾€Ïcçü‰¨Ôá8ŒSãCô.V!¤§0¬‡•ëMLé·õÓ}§·×䊫:ÙÓ3šlm?¿í”Ù9Üëçroü)þè7çmΟ"ÇJF"¿aA*^õ´(Ûb”±¶õ8[Ýèûe³*‡“g\.kký@{pÇ=ëâÁôFï‡?{>»›yÞ¾nõ}¿’:R8³æÖÍWOrÓ6uôY¾†<‡J(IegVï…åÿ¼[tuâAV…Y«/ÏOÜÿÌõµ•Úz§;í¶£Y`*“ÚÝ0û¿œÃ¦ëUýδÅÖ¸RA„L8{¡Ïuy¹Ø|èïaŽ hnŠ”þ:{ ‹.ð0¿ß-ÉÏ) •ÄŒ.8V᢬Y ñ«¦ÚÂõ­ë[´èÅ‚Áúµù.iõ\ÿbNzã^Úº”ñW´ß–ìœù4éÅ‹ÞçoLÔ–‡J£‡û‰±Þ¾3½¼‡éílªýµ/,ñ +õW÷Q`x¯Ã*S›öïýÙÍcR'¸‘çvóèžV.å¾p\»¯üoÒõÞß6Yö$Šõ6‚øKèÇý•þu©Åt€›œÐ›r6ú–÷åÚ† U!®µ3“,M¡¡UKšfc=Aó=\úÍu%Fõ.ëÅn}Ñõ¹lÞÄø¢ãBŸƒÝ/ý†~*‰±4ŽñY”k?´eAÚ.æƒèåFß_íÎGÖ¦:}kOZ~œ·lÍX»/íxMdÍv­á±`ÎÞc‚úG»òìsOEM?¨Êð"Pç¹éÙrzmÕÚÇ„SQÔ‹Ê&x¶¥ÅÑÁãÆLîÙO6ðüS_wYw¨Ú¸{ÓÃÇ·V.Ú±"tèïPÓÅŸ—ä¾Ù:Ú¦sp7µ'XÑ{ÇÌw~ìC[ÎrÖyúÇ}³4 …Zwác«Ö2¸Îªh#[ï]hÛ?Aƒš+µµn4Èmðr"ÕËên‘º~/yêŽZšÓMÛC ÚáW'«Jä¬ÜÁžU§|<ˆÕc•BT¶TrZ³ÜfÆ™cOJÜŸá›^ ç7”ï‚oWD­­˜ð¿Û5¡Ës½2RØñË™R•ôM‚loÊ|U–Aß9/«©«tS¹>˜áµõÌ'Æ/¹_65n¶™‡¯‘DAßÙªÛ·_w½.wÔr¶Ä +ôÜçGã:òíÞÏ)Œ R?CMKëÆôûëÂKûŽî¼”óa宗ܽT\òÚ6^^7Ôn[–x˜+tiT6Ö›ö\¬,vüX® ÆK£ó•m·“·D KëNìvØÁ9¤Î.îš[Ð> endobj -1365 0 obj << +1382 0 obj << /Ascent 694 /CapHeight 683 /Descent -194 -/FontName /OICPNV+CMMI10 +/FontName /WVJXVA+CMMI10 /ItalicAngle -14.04 /StemV 72 /XHeight 431 /FontBBox [-32 -250 1048 750] /Flags 4 /CharSet (/less/greater) -/FontFile 1366 0 R +/FontFile 1383 0 R >> endobj -2096 0 obj +2126 0 obj [778 0 778 ] endobj -2095 0 obj << +2125 0 obj << /Type /Encoding /Differences [ 0 /.notdef 60/less 61/.notdef 62/greater 63/.notdef] >> endobj -1052 0 obj << +1062 0 obj << /Length1 1608 /Length2 7939 /Length3 532 @@ -9527,7 +9686,7 @@ stream xÚívgPTݶ-HPPÉ™&çÐÉ™–œƒº–††î&K(HÎQÉH ’sÎ 9#$ˆ€øÐïžsn}ïüº÷üzõvÕ®ÚkιÆs޹VmVF-]^Yª„p@óùž4`ö–Î(]°ƒ¯ÜEXYå‘P0†pP£¡O†P@jÅÄÄXòGw$ÌÆ àÐ×1ääææù—åwÀÒýžÛ(˜€íöà G8ÚCзÿãºP(m XÃàP€¼¦–1HCÀ¡¬¡P†:@‘`8@ËÙ³¨Á¬ (('ÀÀÿZ¬ØïÒP|·X²(€r„ZÁn·Aݬ Ž¿]<G(Ò†BÝ~`(€ 쀾í€9XÁ!¿ ÜÚ­9"·ö·¾[0- ²BÂÑ€Û¬Z -JñDÛ‚Ñ¿s£`·nÂú6‚°rþ]Òß-Ì­ †9 h¨úw.K(C9ÂÁî·¹oÁ‘°?4œQ0›1à ¡6`$E¡nan±wç_uþ[õ`GG¸ûŸÝˆ?QÿäC£ pk> àmN+ômn˜ÿïA9X#@¿ìgÇø\ È? âø=3œ·$À„ÜZðk з)ÿ3•ùþs"ÿ$þü‘÷'îß5úo‡ø{žÿ­ä ‡k€ío௠p{àj€ßwÌÿ ¶‡ÁÝÿMôß ¡1üw 4ø¶ ²6·Rð üe„¡”`nPˆ me °Ão{ôÇ®ï"á0è­–ÚàŠˆüͧg ³²søÝôÇb\PÈß™ßÊó‡7¿‰ªš–¡÷ßoÓ?QZ·ª£õÜo‰ýWêÈ?¿1äänO^ ¨€WH@ôö° ĄżþM¾?@À­ÕÁh$Ì ðü¶hàŸÒÿëý×Êìo0ŠVÈï9ÑEƒ ·£õOÃo·•3y«èŸÓ~[ò?Ö† +JñDÛ‚Ñ¿s£`·nÂú6‚°rþ]Òß-Ì­ †9 h¨úw.K(C9ÂÁî·¹oÁ‘°?4œQ0›1à ¡6`$E¡nan±wç_uþ[õ`GG¸ûŸÝˆ?QÿäC£ pk> àmN+ômn˜ÿïA9X#@¿ìgÇø\ È? âø=3œ·$À„ÜZðk з)ÿ3•ùþs"ÿ$þü‘÷'îß5úo‡ø{žÿ­ä ‡k€ío௠p{àj€ßwÌÿ ¶‡ÁÝÿMôß ¡1üw 4ø¶ ²6·Rð üe„¡”`nPˆ me °Ão{ôÇ®ï"á0è­–ÚàŠˆüͧg ³²søÝôÇb\PÈß™ßÊó‡7¿ž†‘’‚÷ßoÓ?QZ·ª£õÜo‰ýWêÈ?¿1äänO^ ¨€WH@ôö° ĄżþM¾?@À­ÕÁh$Ì ðü¶hàŸÒÿëý×Êìo0ŠVÈï9ÑEƒ ·£õOÃo·•3y«èŸÓ~[ò?Ö† uƒZ|™BX‰¼LLIB—Qdt ( Ã?V1ñŸx£+w¿³^õ9’e‡Ð†ŠÚ¥ÍäÊu””7œœ¸äN­Ñ÷ˆ¨/ùŠõ.‹ú…'Ð)á0äPùÝÚ…ke ¸éÛR§ö ]8sô&sß±­|*åŸî#>cÕ¯‡‹úœ‚ œEëÑymeê÷AÆ€>8m„ 1œ4¬jõõr¦XÜâd8„²³¤¿V>M¼çÀ7ÁÜ&N\€*ÄJÒÜOµøï8•^Ýçôáö¼J%qõ‡ ‘®.µ&у;ìXBÒ0ÊÚcVKŸ0-SÛ·ߌG?óí·Eƒòñ(€(§¸Ëš’=´øô•ú+y\J6.æê”‹‚œÞ»ó^eúÞ‚·V„(õb*$Ã=AÁžéÌmEéïa9žoñ€Rý3™ÙÑS×!÷8ÎãÒ9‹ÅÕçÜrƒÅ£‘C™Äù\‹-ÕÕ²k±ò¡øáÃÍ8 @@ -9559,35 +9718,35 @@ QH; ‡á{__bçâ.°ßþºæó}<¯½kb¶Þý9\¥™àpDË\TL[\a·¿«NüÆW¨œµ>¿¥t®tÉQÀRD‚!$Dr£G¢1¸AÌý¾ ¥Y í–.ç#_©ØÉ#¬w¥Å¹ò«|Sþ?Z:è:”—fÆ×’¸ʵhúÏÈ×XaÛfÚœ¯Ú3™B¶“—£Ìü¤‡uቇôä·ÏÔϾʉltãp)’&ÿT+p•°e –íZ­M31I¡ÒÏL«êÈcýªG’«ô"Hx¾çS•ö$Û_Œ*[£n~OYgÚC¢ã® ø LóÃI8GU–¿Bã¡\‚–Ÿˆ{éõ´Sû›7M‹Š–…;ûÛ䃵h¹0GQœ&÷ <‹"œ_ý¼ÈAze‰ÀN2ÿPÜJ"u]©¶ÕLòs.}æQùü‰iõHö5¨ñ‹‚‘öqLðëƒýUj[’ =Á®…1Ñè²YÆHOŠåoq ’„!¿‡RÒ¯¸ð%ê«~u¯ ³¿0Š×·6î;>nE=m½aÔ\{\ÄcïQq”&T/bµ^þü‹}m“¹ò A’ü陈×O/ÍI>c×b%ÒÌ&ìýºªú· ¶mJ;û7žb{ª6eC‰Æô_è<@ÀbW’+Q'‘šäçÚU›‚ݧ/ˆ+ƒË°a*¦Ûåõú/5 JÔ†½ó'lï 0Kf›/Ð^‰ˆÖ½žO¼¡M [If§€ãC `æÔbï1}ÚU*÷i g#™HÓÄ+¸"î2X|F#êLq¶ÀØÙªþr#g <¤þdÑ _IÒõ.˜ê¢Ï\9¾§é-xÚÖ-9?›ìÐv_ wóý}¾éH`…Ñ'>Êß4¬>äŽT‹¬ÌÛúGäµGÔà…$Í ï‚7LI›u`žUJ2ì„΃79ç¯~f´lá­ÊΚìïW 5?|¸':U—.ûrJo ÇÓlÔË5áAÜçxE ³º×ا‰3Ç•ÚTñ#åKþtâ•.iKW@ö/É›ÔÑ÷ ûj&Q ¦Œ²È˜¥t°Èð§Äh-ؤ1íý b?e¾™F Š– ÉXrÙ/&Šjz©¨rAÁM°re.2Òe%ÉÍ£™6"5[¹(H4 :\mdb“™[i:ýP½2“¿Ýä÷ö0JÑ»pÕh¯QšQ¨ý±Qó_»Ã7;mþã«÷Aú^ÁÐ; Ó èvñ¡Õñ¥ã«*’Hóß¹,QëtT½}…ÁbWý€g”ùxÔ$Ó¬GÞ×™®'}¡uÞói õ´’D§ùõ; ¼xðÞԡư~. °öâ%ÅÅ4O”˜»ª¡ Þ»Bï­\ÿÆÈæ  -†ìvm…$t§³ÎLd?莑ˆ+í–«I&VñZ"-¿35MGöÊìä§7À Ñ4‰>ÅauA×W¯½r‚…`Hã×W{Ûw1Û®­¹E¥^["W¬%BŽ… >«íÜMÑ#nNCuy‹¼Hû %Tž,TÜþ0]4.ïdîžk0œPañœ„5ðY ÓëF–?ªU'?Õ‹«žäfü¸Š·Ö¤qCr®až1j,†º¿÷2Ó“=²õáÿ¶D4ÏØeÊÀ¿I Üóv¼vþ´b„dîÿ¼ø)xý)\+"oÜ´¦ÜD1å[|)h$úØûeGUeŸ?õ¾†Ó<åízznKB†Éd–¬ö…Àÿò!øÿÿOXÁ¡`$aFÚüì|*endstream +†ìvm…$t§³ÎLd?莑ˆ+í–«I&VñZ"-¿35MGöÊìä§7À Ñ4‰>ÅauA×W¯½r‚…`Hã×W{Ûw1Û®­¹E¥^["W¬%BŽ… >«íÜMÑ#nNCuy‹¼Hû %Tž,TÜþ0]4.ïdîžk0œPañœ„5ðY ÓëF–?ªU'?Õ‹«žäfü¸Š·Ö¤qCr®až1j,†º¿÷2Ó“=²õáÿ¶D4ÏØeÊÀ¿I Üóv¼vþ´b„dîÿ¼ø)xý)\+"oÜ´¦ÜD1å[|)h$úØûeGUeŸ?õ¾†Ó<åízznKB†Éd–¬ö…Àÿò!øÿÿOXÁ¡`$aFÚüðI)æendstream endobj -1053 0 obj << +1063 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 36 /LastChar 121 -/Widths 2097 0 R -/BaseFont /ZKLPWP+NimbusSanL-Bold -/FontDescriptor 1051 0 R +/Widths 2127 0 R +/BaseFont /TNXFDF+NimbusSanL-Bold +/FontDescriptor 1061 0 R >> endobj -1051 0 obj << +1061 0 obj << /Ascent 722 /CapHeight 722 /Descent -217 -/FontName /ZKLPWP+NimbusSanL-Bold +/FontName /TNXFDF+NimbusSanL-Bold /ItalicAngle 0 /StemV 141 /XHeight 532 /FontBBox [-173 -307 1003 949] /Flags 4 /CharSet (/dollar/hyphen/semicolon/C/D/E/F/G/I/L/N/O/R/T/U/Y/a/c/d/e/f/g/h/i/l/m/n/o/p/q/r/s/t/u/w/y) -/FontFile 1052 0 R +/FontFile 1062 0 R >> endobj -2097 0 obj +2127 0 obj [556 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 722 722 667 611 778 0 278 0 0 611 0 722 778 0 0 722 0 611 722 0 0 0 667 0 0 0 0 0 0 0 556 0 556 611 556 333 611 611 278 0 0 278 889 611 611 611 611 389 556 333 611 0 778 0 556 ] endobj -1049 0 obj << +1059 0 obj << /Length1 1166 /Length2 8309 /Length3 544 @@ -9600,7 +9759,7 @@ x r¶Cž! s{¦îâèhY¨ .Îæ (ÐòyeÿY(îàèá ¶²†é4Õ´é™þaçååšyü…%@P°øöyà ²spü£Ò3…4r~^´Å¹*–¦’`Øíé¬a0G>VVGKSÐsŒjÉÁXéŸ* ±w°ÿƒ øC3 °3Èü¹)Ö¿ëf qpƒxýGØ ±ø³% GVMØÉ$+ñ?ÉÏ!À¿bV ›ƒ—r‚ÜÍ­Yÿ(©ááúdÿ#l -±ðörtpZšÚAAÞ`KÐóà5uaÎ. o¯ÿø÷€h6‡Í@VÏÛð/öç0ÈòsES˜3Ø¨ÏÆÂÆÆdûãÿÏ‘áó†Z8@ì<þ•®dj²Š*ȨÈ)2þ½÷f‰‰98–D2ê›-¯X 2n‚LñK€ú +±ðörtpZšÚAAÞ`KÐóà5uaÎ. o¯ÿø÷€h6‡Í@VÏÛð/öç0ÈòsES˜3Ø¨ÏÆÂÆÆdûãÿÏ‘áó†Z8@ì<þ•®dj²ªi©+*Ê3þ½÷f‰‰98–D2ê›-¯X 2n‚LñK€ú ÝØ)[7q\ä딬Ÿâ}2Ç”¥Wº4BâÃ8êÁø¾d7z»{NÊ/IÈKsËQ•÷fèy eì|Tù^N ~“`³ IA“k¯¿¥•ÓC«?¸Æ-oÃ1™žéÃàö –ÀªOÌHt‹ßñ}n縳.i±¼«tÌå–ã4t\dêÍFÔÏZïÖEη2Úú`¿Lè-вFsŽ]Ä!JÞlø*@çìwÓ>ׇ&ª©æˆy²¥@¥]kU>=­rEÞ-çŠÇ™°V£¨ÙaQmL1!h²R%^×àj¸Öl;ÓÛì^R‹×5{/¶ ¸»ßËwU°s:NXµ‘÷ 8ÆßÆûOvj(øÏñTÔ¤\¥+Ö#2\…¿n5;ÿH¯i}¤ß®£Ñå~º9$m`Ƶ'4É)ù6b›•½.†eC[•+ÚËG}*”µ>A¼­dÏGæjøf¬%€Ê4ìªÉ$›Š ÛwÃPoÄd‰÷ú´ÊÈÓƒ8~Gžõ‘÷Èe¦_h‘Q¤Ç‹×g\<©‡3Ѿ¯òJ­’ûÁ«‘e‚gìº N¦bŽO+ÞÀ“îS­™c­Hœ4ÞCØKH÷²m:§dÔ’ÆC»t½€!…Âæ©.—IóÉ^!Øæ¾ÔD’ZÐZ¢˜ÝËMïQ•¦ùÜȇ®CÄTÄZÅ‚zŽz­‹Ä#EÄ7ÏLm}.éF?:ÃÓ¬v­Ä3*ŸH“¾˜sLfZžÓ$Vf‹B4®»%DÚ”6òÛì!Ó7ôRI¿S{ŽØ¸Õü ØKÒG;ë¢Od€V@Sp¾¿–_Û«°ÅníË5n̈XÛØ~ô¡ ½ÖRb…LKúÄ6!T²ªNËg¡å‹Åí„\æ |7AÏâO“fgYPg~ø¡õ´ÆÏ³è­‘!†Øç]äÆÀ @@ -9628,106 +9787,103 @@ s Ëȯúô$ šü=Z¤ïs£öjïM ­È"±óBc!¤d³£©Ëb”ű‰„g²@›€³y‹u[ñBQÊüñ‡2+QÉnÎÕ…lÍ É¬Ë½p¤+M)zÙ>û!Ÿ>ÅÏ ¢ï,Ý™Š£°ƒûüµ±ÒI‡c&”ü¼ün®'ñ°~ÅH¿ßýø ‡é+RúŸRû#Ì»’ŒŒ[È1Z‚«„äî<úüEþ„þ'¢DEPˆ¨½|”‘s¼j#U(»1é·–½,ÝÓ4Ešç×Ü WŸuÓ‚S{:D¦àæ }ª¯ÏB%Ö^‰$—Y –Œ8Ǹ %³šc&h˜!ç¹ÙG£ÀŽ–+([;3ˆý¡ŸA`´ž°ç£G°øªlV˜SÞRÿS”W~V'¦—,É*ZÊÿëH™­ >FþrRZ§³¹™ª$@!È¿Æf'%N¯Íqg'á4¤ÄÛeù+¡D‚A¿x0J1»ôÖ©Cøp:©¡Ý69‡Ñr;âš>ã|º‹Úˆ²;h“Ùé gÖÐŒíõÒ½Ó’iH)è¿iŸö&Iû RKÈÜ-‹Åx°VÅ Ec°ÖH·1ÁïX™hF¸íµnQtCç¬``*s¬Räxƃ<¬ˆI·$¿Ã“,Wp¨þ>VDI`×Ï!JØÁÁH¡aÆJC××J\ë(üÕ7“íÿòøÿÿO˜ÛLaö¦Î¶/gæàüÇgR€ÿ®äendstream +Å2ÑÈùðîì”í êzTóM¥ŸýØc¶ªáq_Ø™­¯cr¤&®tƒ9ëàWüéâõŒK(ÅðX02†å_-x¿ ¹”.?Ý7ÒpÒtÔÑ\»d»9›5Ð~錪ò$õjü2r‰7NNï²Ú°ŸD%DPüyýôG]4йˆñ%3¾j)þäÖ NŒ`¸ÝÅÁT„wÁ_¡@Ò€îz¡yæNVÈë9=-á9rEÔ”#Ï3p|JÉ–2ÿGõ¸E¯§sÞL]G˜¿c‰Š³ˆìš¹äf¡8RâDÊž Òy—gìn›01-ík*l)o ùˆÐÜ/Þ³¶U&¨1à#ö-©r\+çUIufÁ“$Ž¿?ãÉãÞ¢I}gu?rYREÝikoiï}ý"Öˆo’H†ã÷ÊÁ©ã𔩡bD˜2¾pòV…;YfÑÿà×C®ƒñÕ{Š)BøÝîO|ßÃŽý}àãFU'~Çq-m%ÄÖ´½è$iÑü’¹9¢È`—k˜Ë£öeƾ-kØ‚.ñ>s¬Räxƃ<¬ˆI·$¿Ã“,Wp¨þ>VDI`×Ï!JØÁÁH¡aÆJC××J\ë(üÕ7“íÿòøÿÿO˜ÛLaö¦Î¶/gæàüÇgR€ÿDlendstream endobj -1050 0 obj << +1060 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 2 /LastChar 151 -/Widths 2098 0 R -/BaseFont /ALHPJM+NimbusSanL-Regu -/FontDescriptor 1048 0 R +/Widths 2128 0 R +/BaseFont /RVSMMK+NimbusSanL-Regu +/FontDescriptor 1058 0 R >> endobj -1048 0 obj << +1058 0 obj << /Ascent 712 /CapHeight 712 /Descent -213 -/FontName /ALHPJM+NimbusSanL-Regu +/FontName /RVSMMK+NimbusSanL-Regu /ItalicAngle 0 /StemV 85 /XHeight 523 /FontBBox [-174 -285 1001 953] /Flags 4 /CharSet (/fi/quoteright/parenleft/parenright/comma/hyphen/period/zero/one/two/three/five/eight/nine/semicolon/A/B/C/D/F/I/L/N/O/P/R/S/T/U/Y/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/endash/emdash) -/FontFile 1049 0 R +/FontFile 1059 0 R >> endobj -2098 0 obj +2128 0 obj [500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 222 333 333 0 0 278 333 278 0 556 556 556 556 0 556 0 0 556 556 0 278 0 0 0 0 0 667 667 722 722 0 611 0 0 278 0 0 556 0 722 778 667 0 722 667 611 722 0 0 0 667 0 0 0 0 0 0 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 556 1000 ] endobj -1024 0 obj << +1034 0 obj << /Length1 1624 /Length2 8579 /Length3 532 -/Length 9445 +/Length 9443 /Filter /FlateDecode >> stream -xÚíwePœë–.Npwkîî îNpo Fº¡iÜ‚ \Ü!Á îî4¸CȽï™3uîüš9¿nÝ®ê®ï]ÏZÏÒw}ÕLôÚ¯¸dl¡Ö E(ÎÅÇÍ+лX{¸k@!ê\²Pg[-kg0à Âdb’ƒ€p0"„ƒÄ† [€<ÈÀÏàÃdÈA]}``{8€U_׃ƒóŸ’?*kŸ O–î`{€ùéÁä uuAàOÿcÃW îØA9-mcM%«’¦>@ Á€Îm§Tlê`Ä݃ÂÎ6Pˆ-øOjîÜO\2î ÀÝd~2yÛ€\ÿ@œWÌìîþô »ìa@ü©p( ±qö°ýÀ“ÜúW@®0蓆ËöD¦ u‡»ÛÀÀ®pÀ“WmyÅ¿ã„;á|»ƒŸ`ÔîIÓjãñ'¥¿°'š'CÜp7ü/kÀìîê ôyòýDæ -ÿ†‡;bÿÏ80=fë rw¢yâþSæ ø/Ù]]}þ²†þ¥õŸ1€áî g;nL>þ'Ÿ6ð'ßö`&ÏŸaQØA|¼Ëm=\ÿy‚`ˆõḬ̈=´…Bœ}¶ ;LM(üÉ%€õÖeî_“ÿ -þ·4øßÒÞÿ]sÿµGÿåÿoïó¿R+z8;k]žàï%xÚ2P€:àÏžüY4n ÿËèvöùo¬þUÑôw¤ÈþSŸÊ!±j ?7ïßb°»"Ød« †Û8ì€ÎOÕúK®±ÁœÁÐSWÿ*è“/ï¿`z`'ÈŸò ý ¶ÿûS£þŠœGAAOÍØ˜ã¿Û­ij?Í\ÏÇø?n 5 ¶ÿyøÃ#+ õøq ó¸øED¢‚¼Q¾€ÿÆã_4|ÿ³ß]¶UÙwºHY:Ó@'ÔÏÙ¾¬2·‰pì„òX”àdÆùΨ¯£˜óìlŽèèZ|ø…F3Ö&{vzËüܳ0˜˜ñÆ7Ð&½þ I;~#amÑ÷Cæ”ýÛ–ÞÁ¯ý}ç¨_¶©8rß`0Ix¢à0Ç»åRI™èWøÅ0¾T&À2K‘cXöà ŒñC¤[ÔÉ¿&˜,£u®NKz½A„þßlH‹µc@™ê -qh<ë/=íq|ÜÞ>“f¾WV “Ž]m(;Íe J[<ÃaÃlœùb\¾¡ æúžè×}#-#ÈÉq©¾çeÏ[9Já¼ù¢_¸ØWaøáÖß -ié”ç-ÚX'ÕE1xãÕ^r%LSõ)çœ+眛 Ë -õÞÇÂ[&Zêy#ƒ0Xæ]&òCO#ÅÛ¤ø²¹2Eí úIlºgÌéÝ·akÃÎÇáòû¥Næ ´ÃöÚ™5ÍËÓV¾“/M,-±çDÇZÛ>Wk˜DCÏ7rRIÝŸ’¬ð1È‹diøÚ¿Sü€Ar%çÎ{*“AèÊôŽÙ.… ®mϫ͖ÐW®ýkD -ca¥ˆ:ÚŒás#ñ€îÀpolí›ò¾°ÍDŠNsíò2¸‚Ö#Œe -·&üÖ!Bë}àBA¨ÛÀΡXÐm|¢]æpvKºXKõ‹•‚Eí3MâɤáÝìdtÉa~´K_\ â4HÎý**iœ·É\Ìe:ŸHÄ6]«W•}]¿­ÑêS%S´w< Ü‹åîOìkkQ^¸ù‹Kû`ïJí¦¼W&MÕ½%)–›D6Bc<\ë¿ï’+8H„ -uŸ1Í‹K -|TúÁ.øó-x{dœñØZWäû¬eÙ—n¶R^v&ëgD& Ê&>2P&õ£±•_aG*Þëýï°`eNNAU{yßÅi\îÓÇê#‹0xðØï†×c¥•¾\ûõL$ü•ü¦ð·ÒæªØ,ªl'<]ÔLI½à†ž­Ñ¦°¥ú_Ûµtk2aÁާØÚC~4¶âµm1²¯I+ðí^a ¤Ft(†VP É Ç[è>C×ÿ:_!yà»uµ ÎVfVúôz–ÙÀOX¨{ëµW°{מQcVõª)ÝŠ…?÷dɱ8~EÎHo)3'ï÷*Ò]_™¾ÓÄÔ~Ÿ®vx¥ÞòÊ¡ÀØÕ&˜žØHHyÛbœ6ÅFÝM ÆèD,y5¨˜ ß~2‘{Yî ”±¥¥r¢­ãÉÕ>»8Ÿz“ –R…•RÒõÐò˜ç·ÇoÐÁÀTÊ]ÈÂD9îæìðêàkÎdߨ².pÔáò[ ¥`«Ë„‰ä9“2Cƒ‘i‡“žÆáWö.—6Æ™ÖE(}Ruã̱«˜10Ë _S0-ÏkH“¢JéG³ÂÌV³ßz/gѺÇ;Öö#ejö¨0Øt5¤^yE½mqÝ(X q(Ú2”*n#œ³tWtV¡èžã`Yõ±Á±º l/W¢Ù©kü:e·´\úö†K+=à7éë¥ý7§B´ÌYUÄØŒbTáœü"¡ o–ãú£ùwh rU ‡¾á%y›?qp©V«?e4¯Ue iPŽ—YFüF$Má…­s¥E>œŸ²G»ˆÏIÝ®6‰"t:Jí¿Sy“]Åá·IߠȼhåiÖ'«šÜÝ_Û¯Abí±šŒbuQç“:)õµÕÃR)Xß–j“rJ=Úð†6þÒË+ï«‹ jvð©´OÞ'”¥‰änÑ ›éí’Lp¤Xk²W:=KO$ÛÝó#VÅ­Ý Gèwua[¿ÍL5DIÊiÜ·Bj «½x[$K@"šà­ ’ìeÀ¸„^Y·5o`f^œñ2é…ÎXÐï•rN}þix—PÕÊ WõÀÍê݉ aä{âÕÃÄ¢%F'SÛI-ºàLÉž@«ò­Vê–¹Ö‹y+ƒM"º%ãÁÞ÷d¨Oª<ïË5F¸½‡·¨t'ù :rÕØª}O¥nÌåðêsú|I5cd ô<™Çë,©ŽO¡ÏtûgM]O ááÓ÷ƒ™YÌzt/xßõk?ÖH¬¾·ç±SÅånÍT3‹št:°#ž'º -ýL?ë´êpUn¿TöùVnEÁê?Ø×_¾´pãúâ`(ý”b z@¾‡ínüºSw©õÙ,"ÃeçÝ4b‹x™-R†ÁÊÚî™â “”„üKKëšÄ¶´Ÿ­äü”Fõ.Ÿ1´c~¯U¹¯M]p¤)ûIoΰ2$Z`8+B5®Óµ³ÎJ}ô²?ä\ –³[¢›.ü ¤Æ°Yd¶SêZDh»¹áYºœü€~IÒG>\ {áxÊ/õÉ®[ávÅË/¡‡')Ù®oº«;ùqÄuj 4Ö„bùàgÈ•ÝçOñsÆJŠwí^ùÏõ £†þè©ÿj/(xý¬Úñõôó//]ÈÝÅüæOë~Ó×ʶ•àt`e/ûïè ãûcOû) …WU/“Ñ‚¯Í–Þ´Gù­ÙïÜwTîÏW.¼)ð—«{žÿE4%ŽxôÕ×ñO‰Ö¡ìѱüBú®^?² Ò7Ú‡6i–”“´šü»;Èœ{Ô¯6-®dó7 -DŽãlÀŸ_¶—s@“Mú§„ây¬ödæº/ŠP‡}øe(x¿ÔR^¾ŠÎæ -5ËéZôO±N>%¨ˆ¹aâôOZ3)€å}íÖN¤§fQrÍ›d²~©d›Ã«°]µmä_—–õo‡öé´6𷧝t`0ˆ'¬bXšz˜g­âA;ÌÆº‡:ÄŽ/0´ ³’YÍ“Ó^O¬œ.~èÿé“1 m«ð(¦Ìÿ#~+ÿÄ@è…†–1‡¬üþÖZš‡ÑÏMŽc…#ë,…põ «—½ ãQ›q„~ݶDwRÉ­±­ðç}ˆãêЀlqâÂmƒéN¡òºât»ÉÒy•qÝGŽó©6ƒïXd,7DýiF}/JáP*Z°ýƒ[ïÊñåx´NÞl¾d¯÷ÝêèïM‹Í¼:,ýdÅx#µÅøÇ—ÄæÂч7jèÜÛÓáöâ¡Ï˲¬¸x›·wê¾Â'_=Sz<Ï,NîË!É.öš«çY¢¬-j=-¨¦a”%m].'Û¦œ|ó+êçÞ Û!)Žoh\ð(~r£hc*o±q× q+fõ³ïóäÒå62†™·«ª vVij^×Lb‰—'ä¦ÜÌÖR8ˆ -à–¨ÞÏÙCãr±`Í1º'Þ3©$.GæEHÇçʚʗrhüúŸ·Òb¥éuž!&¨qΉ6öQnªÒ$:ZC}˜i%¹Ê­»ßàÅË]¡;J¤ü¥íÄáÈ¡¥æê?^0ß-±9,ƒÖ?¾oН*4ë™XÏ¢ÔVúåœó5Ë%`*fÝÓ áõ €¹Jx¬ŸÁ«|ÉÜ-MW¸Æ1–Máù*ȼRé¹!;vúŽËE”¨Km+F´ˆ´zç*ëØ¦‰å›«ŠÍ5¥êi¼Áa}4ÞU•Õü<4·ˆp2IÝb“I{Ù·¥ÙGL‡<‡¨)L™¼§6<{OÚ‰õJëù‡)=Ž`W Ti+Ô/ëy§Oul3`C¡Zª¬8Íçë)ƒz5f(mNnLe[C~‡HèÝ:«é3oî=vc"¾53b/Ba•Pâž‘Á©gtgºeغîõ`Έê;¶Õ$´T¨z‡Ró™Ú$F2æz__híÜže .#‡9Öžc蛫w¿YøIoÇÑÛ>;V;Íúå¥~$»Ï¨AÒIK(¢Û³@Õ0¦Ô£20¸Ê )$çÔ*í> Lª×5z(Ro,ÙõÝ#ÿ}àQàÉçÙÛy\1°Èöºc.FÚËcuÉÎÎý D­P”0Çj XS;ióé,¶hqPÞQ×I®y² Y%Ó&tÅú­;ôþþ ¹„ÙsQdÐ+-\yª×¹L&¯Ÿc݇)ùÈ69ëzTê|øÚÞo–ÖÕwÙY\9C -¹oú•ÿ™„WÀ ßóÇÓNV]UÅw¥Uf]F}å'Æ ~’Ò›Xœ#Ëçž¾cvB¯W/¤™iÐÂò:Èû°?¥Zï³ÚÜt!r¨±w(P¶¨^á ô Û}3e/¹N \J¡ñ¢ufý\˜‘ãLT(1 „™YÍdãºIé;o¤äú9oÒ>ÒçMªá8rCŒuÁÀ߉DL6¦ëÕŸ¦D¹í[v¿ 8½£ÉICxY'ž%¸)4ãl¤Ã!þ"2J)/E¼4²%º㉜Ɵ1gr P -×¢<Ð;’A m&%`»‹ý,]@QwÚÛ²R×jArÝ;Â9†¤q›~ c<Ÿ;–º¬#v·K÷ñI2`=Ìáä4 H™óÔ~÷ïAÀ–fZrëÆ)8UFžRÓT*¥¸¼ý  -b&c,±í™Ðò´6@ýMãÇlå‚¢Ý+§¤õþŠ´JX)Ò~Ú ®~_òŒ`|µ*ÊOw`à™]ÃtíÓ?³Ý…‰ÎZÖz¾xï¥ÝQøP&_DFáî?¸jÂÎóï¨Ùšø•À„¯çäHËlÅוäÀŸ/¢p«·ýj/ -¿¼I-*-]‚×X![0O²h¾µuí©±°njî¼Ùõˇix6·ÇüvàÁ~ó©O‘Àù‚˜lMT(Ûf™)Ea¡ -«f\‡Ð¦¡$ƒ±È=Ñ3{UvŽyo{VîÏë ù P`üñŒT¶Ve¤âZ­²<§EnÚâ)ÚQû´%¾ ¦¸7ïI¸tƒæ¹H)w)I¿¯r8Ú'‰uŠ‘VäaÊ^äZ¬Øy·ºÉ’ðô`ù³d^z¸)Æ6Â:F´lÙGNŒî;T“Aß<68açÛœ\Í„˜P&-‰*Tù–†‚û9n‰ƒMŠ.Ö _®¾˜ì»[tTç5u|e±ô(z¿‘1­ÄE¤m½9FGyü…Çݲýu %b«º&Ü“k®[“Jf—õvbè,úS0ëò£KvæOìÂT€l,Jc§wyÛezŠJ{ÍG¿+Ö¤²)¹¶Ú¯ã5ßõzÕ~^Ñ™,UËÜíj4¤fÒØÜÔ–Ÿ"^£Î|ÏvDÿpï2®ÀžDrng/ÿ¨F1}ël†±ùÝ/àíÀÈ/þ€%À!yjå—rG?v’ŠÁ÷ão¿1ÎÞVlJq§FÅã®|‰ú^òñ{¾°ì¤&>M†J|)§C'[¸@wÑ„¾»üë’N¨€‘ÇA,‰MÒ[PÊqu RÏëgì N™*>rˆÞÌþs“°Š¶ì×,¹v¸5½âz*¬Çsu€yÂ<·@t%'ºÎ)>þ÷k[1ÞyãçM–i‚Óµ»ùêÛ9ûÙhYéTŠDá]ô-$@auS¡s™ -wñÈ6úà ”mÕé²ÂþYTñ0¶ŠŠn˜ÄVûÄ*ª¾“z<ÓËåoœÈ-ÜÌ€9ð®Éü̸˭ojÊÁª&ÁU/ðޭ목;íNˆ"ç}%éÁ´ä}£‹>òΰLžž4^ùÂí°Ä`üÃ\½[s!ªÝÎLð.ó¦ŠÜlµ ò"±Úu -Ú匓$S¢’ 6CSûT ßé3çDIЩ49VTÑÞê_Eb:ÚÃæšúa,M[a¥1a=“Ûÿ³6]<·1Š\KŒŒjì…¹¯ònð /u Än锊ê&½7Sl x±*#Á ÆxpC‚yC[ >F=ÂT@Dæ©F ¨j`ŒT-Fbj ×t0ÿJ"Ã.c0@mY{PJ 5¤Ì'¶WŠô(æ -w:©ÿrŠ®­|¢©Â¸¦z$:S÷5ýe!Óné³úÇÈ‚®¥kîciqç`“&"Œ»ñ¯[’¿ +Þ^aæ’W~Þ¸‡ï¼¾L¥ [þ¼RB ¶¸¦ÓP?¸O/Kch™iÆìɶ69eý«Æñ0C¯zÚV»\€3ÓF6F’×PK(Â}<….õñG¢7uª–íöx?Q:¢/³«¡ÝUf7ù0ýÖgß´—-hyŽéT¤ÂpÕ äX´Ùð!Gf“$~°Úù‡A—ñÃ0¦é!Áy[—¬Ê™kØtó̸Ã[x-¬Vgûi æ_£,îiH0Ÿ9´>fDâ´¼µ¾éþ…¯P$ÞÏa$ùÁÌ È«×ÅØ¥p*7'ZtÐg;9N{9*Z—ê^‹Ã@jò£ -É]g¤ÌÒìÃ<¥)7‚Ñì¦aìnd0² ã‹ï»¡.{tm)«ÿÚ;ðÅû¥™¢ËÀOû&*‘8$nÎ ¢7ï A -/TÍ®vi6Ð9¸Í>4â|ßï½@G_C )$œôÀÁ¡S霿<+sK…¦–s5KÃóøêÄ寶Pþ}JýHgëeC÷ÁUf2‹ïU ¦(^9g­5Þ’‡®?¯¸ËÎïPrtAFžÕŸþzo…‡“Œ:¾æ$žýf¾ ÙéÝ›S”¦]¾‘õÉŒ·‡¶3­×žÂBR­Ì]þ -诮ñqÂmdàÔ`7nƒ¨RWºÓE[œ–™Ù6‘9¶?`ƒ=p®ç3Lã,oئDLß÷˜¯ÙTýŽ§Ý¯eW‘öîònQÆ—a)ähF%ö¤5ÙÍqXÒÜâDÍPá±S)ô|ÒÞôÔŽUYïÃÛ›ær¬f~0?rén#º«mH¼Ÿú„Âl#¦u¬…85ˆ#FìEeU§ ¼¹Ô_ k<ÿk¦°ÙbA%R7@"ÿÔ÷»Â2aë}ñó± Í„½![/©¬‡DpÙn/Éo ´=ý!"o×Ï¢ðœoâ}Nó’Ïúýk'´$ó ’;ŠTÅã8æWÌuTš+Èó1pT>×v€n -^õ,mÝ>µsªÇÍóQ™“™:…&ÚÞ0Å(ÛHj…`ÌðSòèí$¬=Ý3UÊõú”ûµ̒yæMŸ"¦*lÊKÓã)¯ý¼ð^lØb$vÖˆH 0癥l{< -ø_Ê'Œ.ÌGöª‹é–Q}é•.t(f2‰ûjéŲ¼[Õ -§m#dì^Àz#ÎHc3ŒÕA›Þ@4ýÆaù ÃM¸gGs´+l®ºhXÉ¿N5ÙbHË5toï<Ÿ¶¤UxÑ£(½¶§b^j -Ûó–ÊŠEVÛ*l‘(¯;Ä¢føqOóÊE½WÇçT(ÝkEfAó¼žýÂdù’†¸æ¦n®»Æ8ô¸©%ê XVŸP®Hè¥SûzëÈÑT5JÊ»khOiÅ©Sá[$#þÀ~yÖÓ àŠuq~»ty5ÈßZäë¸îE¡Í ƒ£ç<–õ?ž|¡ÿk7Iä¬óX‚Ö†¯¨Ãw¨JÀÆ!¶vŸ]@ŒÆ „˜ì¦{SL+SªÕT5ìÊnÂI’8˜$ØÛwk:P—zŸm”ñ¢7dTyïÍšVìL~åò0„­(ÕC‘¥H›â{*SniNƒ;о ¸î -rW²tˆjêÏéIœmyhžrñšxÓÍΔ{.2û˜Ö=2£&Gl þhÕuµÈ}«ƒË±GgYúô‚á1*ëlänȹ¹YEÒºOúʼÓ\/QÐ4Çê§ JLn%!ê‡-ÛêÑ–tzŒüâ!rÈ~¶Ç*¥ì”o‘‰šo6õÖÆe›DÈ7äð+÷&³áøÚsŽNvÊ0± -¼õ¥¦Ø[?°qI„Kõ⬟5~•)ž¢7StûŒ•_ÑባûŒÒOLû-ˆè•ÕóåÉú¹@¡dÉE’]_VJDù»ýõW……¿].²dt~ˆ˜ˆ ëM„í[z:ð1¼meãðÎW &If° ânË5èŒqJ ùHçq$?HÒàºN÷œ³ÄtÉÕ¶øhÎ=øi2Ó1\‡>ÆQºO€Iep3ó¡5_€lª§~—å6í×ðnþ4à ;h·M±VH½r4­ÊvV & ¯Ž¼ ml߇K€#×?xÇ”³îL3sÆ™¸Ö‹ô¥{Îcj+;ó÷ˆ™¢à#ÃZIü7£aÛG+ˆñøÝÔ›QEíÀ’¢#­ƒ™)­ìÕ¼`¤øÍíø´) ’J±4ŽL_$/Ö.,ÇÑYéácòwjÖlžvÉ[ÓáþhÉðþð‘æó|[×L.6y¾WLMèJÕ€¯ŒþØ;©>âÏ  ‘Y‰è4‚ïÓ+Å·®‚›m=Ø”°YXÓIp}å°ñ YÙ߉ŽqûN<Ëúæ=´ûÔg·>ÚܼŽq9ºT†¸ÃèGSyçm÷p0ðÞû[  ‡s‰³3 Éî%ø¥/ÝðúµnAi•wÖ,[é5SõˆcÜÕ°Öº×èÏÕÇFÍ,Œ;nòAï-´´€Ä߬ug¬À!ˆ <*’Ïã´ñ—Ü›£D•îÔO/ý-?*¹Ww×%sUc‚ö6a u¤´ƒ·¶ªVq«ù|4F;2¤¬«šßh1Î2éj˜ô÷8æºÚÀ¤¨Ä•½š:q‘— 8roBÎJìÞÉK<<æÓ?6tð4)=Oö¹nÝ úy33ç4ç«"s_ʯrXZœ´¿":¿y€Ø`eóúþèÇi™f*õÀdP[S Ú^D$24³ªSpÙçr«u +¯X£ð\½àá)™—Úùìû.¹ò‰¬vY·S‹È¸w´þÓÄœŸ£ãì/âìœb†Î#aÂ]ôG1ë-ñÒ8;iµ¡ø LÃ,c¥&]#¨£V¥¨wʈտ™f_ŒWi—²]Šã—â¬3—ÄGBßèòQB]Pö½!FUßs³Ó¨ú­™¼‘JÂÀFGí -†Þ[ÕñºòŽABjÙhaLMô\¸©·UÇ2lucJQ¹ô@!5@ç;*>ƒìïâ _\Hñà‹Ea{¢ê’7ÎV[ˆso'Ƈ.–¼{èãrœÇ<˜Ê¢©5û&/gý©~ò†…p´F7Û,‹™éÞ& ƒ–PvZœÆé<ÙX<Ç~ÚñDRx›±Î°mé¿,œÏxIÀBµüïgE/Hý£öÓçVB[1úüû¼×+,(ëÈj‘õ8¶DšÈ1éV%á*>ºÑÌÏ-ÉbW®V§…* ßcoÃÉ«Šx›B¶>GžÀ>­š-QFÜHÑÃâ•°8ð8—ÿTO¼VJ›Jfo!ŠËKÌ4,pB@<ɵŒhÛ*ô¬W¤ˆ¿™Ù³[¯6€œÚ§óªE:§…¼L¤åê•B¼¦aíe®7·víÀe™4U8Žm]èÝÜA±ÁYažr}‰Í#1ã™Ûµ*j”ÿ ÑŒáè+àu–L _#Ƶö»Ìñ˜S}­—qmm(›1öÑà kªuÊ}$ìL„_hH÷,½ÔtÚšw½álœADöâ‹Ctkôq¶ÁîV1)Òö" Ô»gFbØ_ p(xÿ—ÌÿOðÿ3ƒC]€0'Ìÿ_‚*-endstream +xÚíwePœë–.îîNCpwOpw‚{ 4ÖÐ4îî \Ü!h€`ÁÝ,÷$À½ï™3uîüš9¿nÝ®ê®ï]ÏZÏÒw}ÕŒtZ¯9¥m V ˆ Œ“—‹G  v¶òpW‡¸¨qÊ@œl4­œÀ€g@ƒ‘Q +ÂÀ9 $0Ùä@Ö>>¯¨¨(#@âêÛÙÃ,z:¬ììÿ”üQXùüy¶tÛ¹˜ž-·öìÀò?ë2׿¯Éÿ†ÿ[üoiïÿ®¹ÿÚ£ÿr‰ÿ·÷ù_©<œœ4€ÎÏð÷’Äþ|WØ^[ø +Y`Šù½'‡•”ò7;)uƒÉ5ð{yi¯ôlVÇtùаap™$=Ú¼| ¿Ã2¥ÔD$mCG75vܾU‘'Ÿ·^¨%Qëê>±Œ­v¤i¢œÆœ\DÅæ$Uyœrï…¹Š]îI“°pS{ÕZXÕkÝJ´ÎÈw\xTû ni¨ õà=7¶Yˆ}Mäo“ÊÊôA6'¨'qž1§?õýµuÞ†mŒ:‡Ë]”9š5ÒŒÚieÕ¶®ÎZúN¿‚ 4¶°ÀZ™hïøT£n q8ßÊM#ù}J¼ÆK/'œ­îküNáNñu”¬;Ïa¨t&+ã;&ÛTüøŽ}¯_ÙÎ/åP”Ì¥µbªhSúOMDC:C£ýquo*¶“Ȼʹ*ÊÕã Û ¯ò“»í6ãµXp— +C݆î°|Dƒn’l³Fs*™3DÛj^®.kmiM' +ýœêe#¥M ó£Yùìì"Fà4¨¬œÎq›Â邱Jë ß¡cùºj çÉ +¥!M"Uk×ӠѽDöþÄ®v¸é5¾›¿˜”ÖžÐvÆ{mÚDÍ[‚‚µYxë04ÆÃµáû™¼ã¡x¨`ï㢘ÿGÅŸl¿Þ‚¿M2[韷(ÿ<Æ%ÏúSÒKÜÖxóŒÐTÕÌK +Ê¢z4²ô+êŠBÆ=ø ÖYäæVwv \,‘Äçí0~¬94¤6ƒ M<5îº+® äÙmf!à­4‡¿•2SÁbVa=áî¡bLïW7ÖrïŒ7‡­4üþVG»!\èpÊŽ¥5ÒäG­o#V×#KR‰gû³p(-¢K餒|D5Á\ UïËb¥Ä¡ïÎÕ*8G‰mT±%vžIßOH°w“3Ö+ؽgß°)»œjÝ„¯~ÍÜŸkºôØœ°&k¨;™¯—Öì$‚Å— £ + +ûäаQoâIÒîGžaWŸ¨•h‰ˆx=}«Ïí“|ûؼ‡Ðé6ÙF£¹VàjÁÓllyÛÃüù5N†¹á±£LtÝ“¡‰>åìÉ÷¾ƒŽ´OT ôNó˜yûõ²ëáô—p£KTóÓ+±Áz’ÈÜ™ ªÌ@¼Îâü/Œœê}í“Xñ$R¨ÅኾÝë;toK’Ö~ÕŠç7~g¨ nX,ÿ\¡Žˆ/νtD¨scÓÐý#íã‹™%¦”ƒ~¥@Úë+“wZï34ÃŽ®ÔÚ^Ûz:d3 +Žš(nÛ¬³&XÈ{‰TXíþ¯FeS¡Ûï#Ʋ¯*ì3w4•O£µ=9;ç—SCoES«1SK{^âÚó½q÷yô»è˸j’˜ƒè"'Ýœì_~ÉW²„凒¿yZÙŒ|^©ìÂ=¯ù•PIÞk^z¯ ~½±NoT2Ž^ªt‡}‹8”›Ô"bÇ +oaguÊ!ÛçÜ…ÒŒ9dëÉ’¿Õš[»Ó7õ§aNLÉH•.‹ð·ä“q#t|%öuþÄRÓ¹+Ænvê–‘¦žh}í½B׫üsóø‚Õ9*«¼ª¡M‹E“½h|íøiG½¡^¨!¥®_œÍeÜŠáâuç±ýïQÎ`Ÿñ‘Eôï þ©¦%³u£:GPb²Ü"â ž$•Ç…t“3=òáüŒ€-ÚYlAòv½YŽ¿ÛAòàò›œjv¿mºF­$ÎàeKOÓÞ|±•”.ÔèÁºAu–>Ëé(gEp‰ÃˆbP3P-,œYàm™Y‡ä£5OhÓoÝüŠú˜ V{Ÿ*»” +ð„pÞõ¨©îñ{ª•[•#ZòPxéÞ¾‘ +NÝ^8Ü «3ëæmVšRrnÓ%B#mÝÅÛ + i"á4O%qD?=ú%äʪ£u #ë⌇)H7tΜno¤Œ]`æ«Ð/ƒ»Äêv.˜ŠNvÿn1W@XlˆW#³¦4õt N7•Èœkx"ò×:É[¦:/¦LVñè¶Ì;ß“ƒ‘ÉŠüÏ×èávÞ"RÝds¨ˆÕ?ãª<](t¡ÎGWŸ2Kk"Û ç)Ü^o|dH´}Š|f;?8ièxŠäÊ Žž¾ÎÊfÒ¥}ÉónPë±V|ý½˜(Ÿ2¾`¨hg®†IĸÛiˆ þ<ÑÀUðI ã¬Û²ÊU©óRÉçcXC¸%9‹ÿðÀ`IøÊÒFŒëËÑŒSòÈ!Ù>–»Ql†ÎJû-¢iD¦óî»Yø6±r„Lýµ½3…aFIq¹WVµIé¿ÚÉø( œ=>¡kÅä^ W°Y š,ý¤ B·ÞfIJUìY†ë¸¹á^¹œþ€zî’¬‡8z´$NúÒá”Væ“S¿ÆåŠ[PJK R´ÙÜ*rWsôcï"P‡kª ÅôÁË”-¿/˜á㈓ëÙ»ò_èCDýÙWþÝYXø ­Æ!vöÅçWÎdî¢~‹§õO´Fu2¥Ø]˜9úB«þ»:@ƒ„ÁøÓú$Š"¡uå£Ë”àkÓ•7Q~v£·ä” ”Šn +ýeë_|I'ýe²%É*”-:ŽOPÏÕë—|6DêFëÈ:Ý‚bšFãƒoi˜SŸÚÕ¶ù•LÁV¡ðáx{kð§WìãAøÁnË}é…Þ‹bäQ>irîåÏu×㯣 ‚9CMs{–=&SíFSNñ+cnç9ü“7Œ ¡ù_zµ’èh€Y?(8³X>× +°.àVجÛ4ñmJÉŒûwB´Û›Ì:3ÖºÐéÅ’ñ×Ñ-ÌŽ<̲×q!]¦½M#Ýò¢ÇèšEÙ),f)é±³Gk§ËùdIÙ(<Š*ñýLØ)8Ñ|©®iÄ.#w°³‘.Ìnøk›ýXþ‡¿U6ÿR¸Z¦å«~úɨíx>$Ž$w‰íqí°ð“j.¡9bDE߬õg»oÈêK2´ï¦Ë¡”’¤DõÙÏO$;ô¿c’2ßVª¦¼z(ƒA(iÀvnýkÇ—“ƒÑÚùó‰Ü<ÞwëãOÛæÛùõ˜z) + †ª¥ + cÎI­7ã*oTQ¹¾Í†Û‰…¾(϶jääiý¶[ÿ6ýMññ<«$e —8§Äk¡ág©’–ˆÕ¬€ªºa¶”U…¬L‡RÊÍï¨_û7¬G$Øö<¡ñÁãx)M"Mi<ÅDF='Dí¹ThßÉô=¤Ì]”:H闤߮«4~ØM\§®­˜Æ«HÌK½™¯#·áÇ)U%¸_°ƒÄçaB[ctN½çÒˆõ˜#dŸÛ+i(]Ê¢ðé}ÚI“¢ÓFƒOTåXi Ø9U¡Nr°4‚ø0ÑHpVXõ¾ÁMV¸Bv]ª +V¾%Fެ´~Tûù’én…ÕÞðd´ùñ}sBu‘ißÔf6…–âo§Ü/ÙÎ3Ô›n¼¦p±s¦J¡‰Az¯Š3sx”t¡Z‡8Vùë ³*ÅlX¨»ÎQ"Îõ4,èÑÂRj[È´,ÛÆwn®ÊÖ×*§ úG ѸWÕ–‹‹¼b‚éd5óyPL~bÞ@LøÀ†ú>Ãå¬PU~Æø­•ÁÙ{’nÌך/>Ìè²»¢#KY"÷yY-:¶ÔW²ÎU‚ h(³ã5^l¦vëÖš¢#©w8º1–ïŒø! öj¯g̽¹÷Ø‹‰øÚÊ€µ VAˆúƆgÐhÏtʱtÜÀÔ5w¬ëÉÊ(iµ.A„Ö%RÕiôŒÍz¿Ðº…}‹ZZv9úüT§¨Dã…,ïß ÅØg£ÙÍ…pBõ:—"aâ»7,ôdUÇÀ(®¸C·0`UÍüuƒÒ Îy”ìj–Å)”Ã8ÿ8õ–”3›FTÜ·Üü]ãúžc‚HTLã[?˜àä:AõUéC5¥´·$kl†2f-õ'»/`3_iªÞ‚Óe]ë¬G¢J“$áˆE㜦5¦q*=I³ý1„lï}¿èè×(ãËñ>¹Vž…¨ÛëwONÌ|$·“¨Ÿjçýr‹Ó¾ÞgÖ"h§'Óî›#«QèRêë_å…‘qh–õ&7è>«5•îùL=ݰã…p¸Èspïï>®é™çxÝ1• ìg‰²8çää}¤’/N\`ÑW¨­›¶n9‹+^–sÐq”m²(GTβŽ]±‡~í½¿=H¬`ô]ÛtËŠÖF´/SÈXÀaŠ>ú2ÍN:UÚ†¾tš¦÷ \bD–Ô»œ!„ÜŠ5ÿ.øDÌï_àùsŒñg7‹ŽŠ³Â;þ²jÓÃîŠÂv#z? ©mÌGޱՇsOß [Á®Øõ )¦cj”°ü.²¬–4«ë›xvU¶.yŠ6•+\þ!Û¯&l¥×‰+©T ”îì_«ü³!²IJü1PS˹7I={¢­ÂÔGÂÂ'‚‚˜HJmú¦4=­ô‘Ÿ¨ý˜,‘´úe5ß_‘T )FÚÍšÂÔîKÑð'׫£üt††Ðlgëžÿ™í-Mu×±|Ôõ}À}/é‰4¶OÛvGâEš~…sð¨ïª=/¸£bmæSÄ.È’”Ûˆm)Ê‚?^FáÔ|ó«»(úü&­¸¬lVkùîØœišYã­kïX­¹Us»P÷Íž_TÝ› µ3æÉžëMË€¾Ó醈`Žõ*cªüR5fí¤6uci&C±{’g>׺ÞüÓî·yÙܱ]ârA¡À„ ¢9ÉÍ|ŠH…:%9]ò¼ôåS”³xb¶Þ<'áRçÂe\¹$ă¾Já(-â›äc툣ôýˆu˜q‹nõÓ¥áÁrg)Æ<ôÄt0ôoôp›èÑ2å9Ð{ïÇ|óYaÝosó4cBù5Å«‘åÚBèoðï¸Ä·É{X. ¼yz¢2ïnQ‘6Ôð”D3¢èüÆ&4“ƾévÉ28àËá-=î•l)àÛÕ4xažœ ½”Ò{,·S#`áÐ_Ù—s²~a¥d⚺½+:.3R•;k?ú]±$—ÏÈÖ²Ö}™¬ý®Û—¤úëŠÖxùGôÝA zcZm€õM]Å)ü5òÜ÷Ô÷ΓòlÉÄç¶vr_ kbPwÎæZßýÞýæ X\¥U}®pðc#®~?ùö+Ãümå¶$WZTÎÚç¨_᥿ÉLËbàQg*'”qØw³†óq•Nyá¹ËM°¬h‡òzÆ['¿¥×"ôÅ¢±-9f)ûÈÂy1ù»œ‡U†°–b}¼fγũíÓUf9^¨,ສg(+:ÒvÏÐóò½ß؉ñΟicÑ&p!ÉÖ3ÇH«Ä]˜ù" î¿ôR3§†_ã’J­¬iÖ}3ÃJ§<œh„ 3À_4°çeÐ%HD fª‚ª‡&HTcÄgvpL†£ñ®Ä3m3‡TWµ†%ùÓBÊ}âú%I~Ä\áÌ&^ÎÐvTL• "TÕÖ GgpèÄ2Ò]á;þÀ)C‹ {Œ,ìY¹¦7è9–s +ö7n&„B¹š.p{%ø*\¸ %ßÖ˜8e•^4íã9m®RÊgAW?­•â«.oh76 ÐÉPXd™2{²nLÏXý®u8ÊÔ­ÙB¡2‡Ö­bÏuNç7ÖsÏ J~ü™äM•¦ióíF¬‡0Þ—ÉÕ¿ÈöÎ2«—l”nç“oú«6”|‡Ç Jr!˜ÊbÊ|øˆ¶“q2XõüðóäQã콿À¢ ®ÉáÁcl×Ï—Ý~ΔêJ¢1¯ª"…‘Ê Z¸ÆÐÃü¹\ÌKðÀ$5wÅ¡¦á‡ZJ4‘¥*4› +IÅD³H?4“ÂÜœJ“ƒ•›¿$%èY}e‰ŠÕÉ$L(¯ÝyI 2Uü$4ðUðú3ÿpXé%DmßþAלÊ Cšv&¢J%­ ZŸ¬Úõ8…b¤CÁÜ„±÷'Ë*šÓ‚®Õéxô¨w |D$Ø•8Ò->IÝ3?Z‰ŽÉu;–ò(Ð]'üMÇUàJ"ôUøúÕAƒÆy¡¼¿1>ÝèPx,õ)òat{³Ü׆(ÿ¶f­()è­ßš§W²P<ðIˆþ^òÉÓØNiÉÇ«ß$x abzî¸8j_, Ùböa’è¨Ï`KÔ«Âu+«Û·kc·­¹| +IÌÐI íßòÓÇi€39!5ÄäáÃ^,$)¿Û˜p©P]¾ÃRÛéòfû&Ú_Àå„ÿ"r¥–VkDqO½`D’Õ3 ÷üà‡x|ÚR¶¸òÝ/0Å4oÈ@ݤýûÀçp»¶ ĉS켘=ÛY¸ÛÄkánšqt¢úþPoBÉ6rÊ.Ô«‹´òÕÇÂÛ^*6I7õ4·áJøÐDë¶©»ö¨m~Íb½®G¥!$ @ž¨KÌU*Y±ÂA§lnw1P‚™ÿ$­cV¡¿Û;ûŒ—lׯN„Ho6ÐÄ¥‰QDÕâsÉ¢”µE»È„Ó=ºƒKÞÆb9…~vÞhö%Êüžæ;ý¡(3»í ´ýMïo<ùb±AvC‰ö¤úÅ^ýÎFÎE3y¹Ñ"Ã>ßRâµV£¢u(ï5ÙÐõ%§?*ßuGJ¯ ÌÑ/R˜pÁéÎoÄí…¸ Gf~ö}7Òc‡ª%)o9çqâ_wǾ|¿ò2ëBdØ2ºg¬‰MÜíáÔ(rñ$ÿRÅôja«•ËôCîÉ÷ƒþûTÔ÷µT.EÓØØ´ÊÝ‹—gon)QTsï¯æ©¹¡_9ýuÁæJO§T´6^Ö´<‘¥§³ù6x_Ç`X‹àVpÔYá®xèøãûŠ9Ÿa?…’¡ +0s¯ÿò×}+4šlØõ%7éì‰é.d·AAŠfõ>DÆc,+ÁÒɸYw + I³4sýõ;`°¦Öǧ‰žCͨÃE…ªÊÕˆ@ Òöà¸ÊĺÈþíØûz1Ó$Þâ†uFØä}ŸÙ†uõSÍA›²”ww›ž4s{+2‘'¡ð^®ý2ú;ú3tŽ—R¾¯EstÛS+NyswJ,˜Ó¡j”môÁì‡soá]¥LcÒýL “µ¨æ]°&üÌ0”¾™E"ðJøÐp-¤þâ'´•Üz‡™PM¬eà©Ò"qç}É‹‰-.¸ý/Éì‡$íp™^/‰¯‰4}ƒ!Âo7Ï¢pn|NŽòSÎýë¦4%ò]$w(K&›°Í>®™i+·>V’åb`ȼ®TÜšyšú*§41êCãÒ‰Æsõò7Œ4ýa +Q6‘TòÁØá§dÑß’1÷uÎT(6R_m]Ô1Iä›5·DÌTÚ[W”e$']ûyá¾Ü²AOê®5 +)“âgÊ7Mýæñ(xâ)—8¾°Ù¯&ªSNù¹_ªÈ¾„Ñ8þ‹†óê^u;Œ\¤ƒ€¡w óµUXÌ(fMF#ÂìûÕÃL7¡¾]ñž°…šâQEÿz•óM×ÐQÜýóšÒv¡eôâ Ôº¾ÊEÉ,Ï[J[&i]»y’œÎ3³ªÁÇ}+gµ~mŸSÁ ¯-$é%ó¶ }Å+j¢Ú›ú…ÞZ£Ðãæ¶¨Ã`=ÙbÁWŽ›íc?fº¨RßEXAúÊ*O‹Þ"bóʱœf׬J +:¥*j@þVÂ_&u.Ьçè<1­–øpåŠücÝ$<†³ÏãðÛ¿t!Þ!+·šFX;µ±÷Ñ›‚àbršïM0,M(×ÓT±ªzÙ ¦é‰ã¡`oßYÌÙ@qªÖq†‹þq¥mÜ7šqsU«£|6"”̈́ +?í(M<¸¤8ôCî@Æàú+—»Ò•#d“P{—¤ù¶‡Ög¯ù©7½lŒyçÂóé½c!sª²DFà–=÷WË\·Ú8ìû´eÏ/nÃBÙî&¡ô˜››uÍûä/L»}Á â…Í ,~ ¤”vbÂAèªÐeE»ÏÐ/ÁEÑÏæX¹Œâ-¢aëÍ¶îÆ¤´C³0Ù–,^Õþ”C,OkáÑßÑV *º[‰»¹Ò÷sç'¶±P™n¼ZÓ§€qé’:S·Ÿˆ˜QI •]žØ:h~ª¤Zoá@„¯-_¬N7,¬Š$J/’5i²S#*Þl¾.*zr¾È–Öþ)l,Œª;v`áiÏ-Dÿ¶•Ý»@%˜8…ÞB$ˆ«#O¿;Æ1‘ú#­Ç Ùa²:çu†ç‚†sž–ÿG3®áOpŒÓYáÚt1r¨Tü¼ÊÃÛYíÁ „BDùxµ»lûôY¿øÆw‹§™n¬XA{ +u‚jUãá(Õ6óü1ùõd…醨œ‚(øìyþÁ»&õgzYsNDu^$¯lÝsÓÚÙ¸¾GJÿ0¨“À{3†þíÇ|^/Õvyaq'°´¸ËPópnF3g=?!a;D+!}Æœ¸J[4=ËÁ‹¥Óa|_j´Ëˆìª«§mÊÎl¸?Êhl0|¬õ¼À†Ú5‹“UŽ÷5c3ê…b à ƒÖnœØ }Hdv*õ–ÀûŒ*±«àVVE,f–á b_Y,\þ#¶w"\¾ShÙ_½Gö¾’øì5D›™Õ3¬F·‚Êáwü¨«î¼mކÞ{ ôq¬pt‡!øÂ¼„?dؾ@¾ ×/)®óÌ›æ(Æ2S9Ä_jnzÿZylØÊŒÎ°ë&ôÞ\SËHôÕJgþ‡%>8”OIüi’&á’k{œ°Êêù% ·ã'L)ûúîºt¡zBÀκ),1³ž„føáÖFÅ2~½ ’—ÚpWš$€e]ã+ úYm-£Þ>ûBO˜™¨*³_C;>ò²[öMÈY©í;9ñ‡Ç\!ºÇÆ.îfÅ)>·À{?o&¦ÜV£D£K¹uŽB ó“Η’„ç7.Ö˜9<þ?Àñš&YŠ}PiäöTýŽ—)Ãô­,jäœvy\ª=B +ÁkVHÜW/¹¹Kefv?ù~‚I¬µÖ­êtKcuâŒ7´L-ø9è2Ìÿ&ÊÉ-¡ïþ!D°‡ú(jµ#Vo+¥ú1/±q”y¢Ì¸g yܲ ùN ¾æ‰ñpþÀhf%ǹD!a%Þ*kEty,ô/ÄéÀÛŰú{^N:•ã Õ#£BiØðÇT§¼÷NM‚N“œC jJc38'NZ÷mõ±4ký„bWTÞ?PPÐ}ȈŒG/óTô›!|±,dGXSú&ÓÉr~áíÔäÈÅŠw]|Þ’Ó„cÅR4•ÆÀôå¼ÿo•oh{{t«õª¨©Îm²á1hi·Íq’Ö“•Ùsâ—-!w$¹·)ËëŽÎè«¢ÅÌWøÌ$Q« ~–tTÐëZ>µØèkOÐÜç©Ç®1#m"v©F6`Ûj ÆdXzˆ—Ї+ûèD‹3½° [»Z{œ¬tùwNV]ÌÓ²ó,òÚ´nºBq#IMMPÄdÇûéTñK- «˜>“ÂÖFŸŸ”ePè’gÑq T6ìÙ @9y3·o»Y£ïrj—Á£è”ò*‰†³_þšš¥Ÿ©ÁÌÊ}¼ ‡yÚDþ8®}©{É+dQhÆõ·ø¶gN\Ïv¨ˆa¼)7Ü‘%8@l¶toúµÖ»¬É3í—ñHÛ]1vÑ£K•*õJÄlŒŸ©›€÷ÌýT´Zwýá¬A„vbCËø#´tñ6Áî–1©RvÂð!T{g†¢X_ô±íÉyþ—ŒÿOðÿµ…AœPGŒÿ_º*-endstream endobj -1025 0 obj << +1035 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 35 /LastChar 122 -/Widths 2099 0 R -/BaseFont /EETKYY+NimbusMonL-BoldObli -/FontDescriptor 1023 0 R +/Widths 2129 0 R +/BaseFont /JWHHZP+NimbusMonL-BoldObli +/FontDescriptor 1033 0 R >> endobj -1023 0 obj << +1033 0 obj << /Ascent 624 /CapHeight 552 /Descent -126 -/FontName /EETKYY+NimbusMonL-BoldObli +/FontName /JWHHZP+NimbusMonL-BoldObli /ItalicAngle -12 /StemV 103 /XHeight 439 /FontBBox [-61 -278 840 871] /Flags 4 /CharSet (/numbersign/hyphen/period/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/r/s/t/u/v/w/x/y/z) -/FontFile 1024 0 R +/FontFile 1034 0 R >> endobj -2099 0 obj +2129 0 obj [600 0 0 0 0 0 0 0 0 0 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 ] endobj -1016 0 obj << +1026 0 obj << /Length1 1630 /Length2 10814 /Length3 532 @@ -9735,68 +9891,72 @@ endobj /Filter /FlateDecode >> stream -xÚíteT\ë–-w‚-Ü ®ÁÝ]A (\ -ww‡à…;AÁÝ!¸÷à—Ç9·»oûúWwÿzãÕ»ÆþÖ\k.™kÔä*êÌ¢fö&@){;03 +?@ dkââ¬ho§À¬´pQ6±Þ.djjq' 1do'a ò´f  )€ÀÆÇLJL ·wðpYX‚tšjÚôŒŒLÿ´üå0ñøwä-Òda y{qÚØ;ØíÀoÿí@u ¶ÌA6@€¸²Š®¬’4€NZI ´:ÛT\ÞZ1(€LvÎ@z€¹½À怩½è¯ÖœYÞ¸DÆg )è- èn -tø b8lAÎÎoï3ÀÂÉØü6°=dgjãböWovsû¿ rp²ó°}ÃÞÈTìÁΦN 0à-«Š„Ô?ê[ƒÿÊí zƒöæožfö¦.µô7öFó†‚AvÎ0ÐüW. À äì`cìñ–ûÌÁ ôw.Î ;‹VÀpZ;™ÙßhÞ¸ÿšÎ?ûü§îl<þ޶ÿÛë?j6æ,Èlìo9MÁo¹-@vÈÿZY;s{ë?ìf.ÿ޹þÝ_;CÿV„±™½À hŽüQÉü–@÷ßS™åOäÿ‰ÿWþ_‘÷&î¿jôŸ>âÿé÷ü¯ÔR.66Jƶo ðKðvËØÝ36ÆN€¿îGàÿfl ²ñø/ÿÕQøbÿï_aY°ñÛPDí,Þ„afcgaý‡ä,rš©€À¦–sc›·™ým×´3:Ù€ì€oÚþ=Ö· VÖÁ4,A¦Öv‰Àõhgö¯å¿Éõwñ5%Tµdÿ«öoO•·Mkx8ÿ–F[ÑÞì?ñˆ‰Ù»¼˜¹ÙÌì<N/›Ï‘ño¶žÁN wÀgVVV6ÀÛÿ¿?ÿ<ü ¤©½Ù_›£6¶3{[¶ÿ0ü›º89½iü÷÷ÿÖô¿Ÿÿ^{ Ðhм4oo*l•–™®ÅÏ“øÜÓÅ3âPÒ QTà_mßé—¾ÁWaôTÂÒ8ÁÿÒê1wäð¼#ǰ;Ô…gCÛùxšOìCIß]ð~¦‡q7ðã—´ôcíh¯³Y…uX=nV­ÝÍ1Uµ/'x’‰6'ij[zJתt_ÓÔú8ÜvÌF(¬Ú£cš¤ƒÛÚ¾áÁþÎ ¸î"Æœ8$jWX4š(Ç"a=Í -¯Æíwu»d±Ý‰¹ÜÆXæ§R÷)Áxãi³åyª¶š—ܾí9ÞYò<0”jûˆ/²­pÛ2 D¯"k<û¶¨ó¼ˆ­pΛlxEv'Ê%Ëž…¹`|R_•·–ñÿd{÷ç9óÙ¢Üß¶e@°-Q–äÿˆO$¯ê2Á³|ÀnåäÉ4¸Ø¢¶œ£íG>ÐK´®‹²üE{ÝsÔGµ÷Î~ï—¶Gí'Ä”›’V¬Éà‡$¾}¿6?dÊ—|ñÔ'Hr;ùMŒ]IJd÷d“ÂUu?¥¾q¬Àe¢zœUú… ~Æ¡dë/O *‘¶²læ ³,D/L§­„Ÿ5)¹;+În3†Ô¼Á¼ô× ÃXؘA¢(¦! rµšT ®çjm¿‚ˆ"ê:=8„é‰ÓvÅÒýÒ´ÉoèwÌ»ã¿ÛŽû«h»‚¬Î.zµŒ4Í$‚Ÿ!‹8s»wè«© }ÌT8-TCšP×í±¿Ò‡š…ß¾*hÔ>_˜A‚»êEžä>A£%»Y÷¾¼Ó‡— -bEh;m&¶2q@¤}Ï7 ëX£ÇuénÉ=µLiØ®Z#‹ ÒÃxLçÜȾÓ>•ƒàÑYô…Í ¤qk#è3‡ãMà¸ò“üLvq|ìD\0D¿Åv „|uw•­ K³KòÉôﺸ씪ÊÌ=½Ðz ¢˜A‘'¨÷GêîéÃä}-.ÍÒ!˜ 1†Akµ§„öŒÜ̆(;¿+ñ‘7ÕÖÊ(C²I|ÒAÿG÷CŒuŒrQÑV…=3åŠè’>·uŠ?œ5Trh¯©ŽòÒ^¢HNåç4 ’/Sîˆë‘~_Ë.ÿôa÷rû»õPã ôdìo0gùš²þ›D"îbHèœé–𔢑:æ]jx6Ϥ0õ!5½‹%CDAçK*Ë3W'Á¤='€.I5p4¬›#CF¢NóÕ`Âv'F.ÛB|Ê]ÞOŠá€íú #&ãøÆ6“¦P~…‡mŒo7±™›1Ϩ)b´S«ü²h*^‹ÅÇâçü¸ð1~çŠæÆß_ÒEàj¦cþسի9ôžÆP±&*Y £ xkâÇ¡r_u¦Ó«8¦Ca1è³M/FìÝHHºq˜ÜÂb¿Ïá[l×êkû¬úËÆ¦¡¶¯F$¹äÆÇ´vyW -†üdË‘È)ÜÑ˹ʱ„ƒ¡¼(«BuV•ÚèHbNÒnAÂé¨X^‰$2a€ÕóEч(¤hÉãcTsë5V»´"ËŒV÷o¿=ÍÊ~€íçÙ7¡èûÉ;ÊÝ/ÁP®}€ ƒ·õMDK°+Ãä²4'ø«<£¥sâáÙ9,ìú)t aúBD.ÈÊ?ÃîƒÑ $ÜjIàsT¦9õ¸zNÓõ% (ªÎ»é}ìsZ^N Û÷FÎ9PJ‡¦4k[«ç f4e«’ùN·C Ì«üj}B¨ª–^xÄ€(4ì—ß«qe Ë:m“®Æ ö¤¼êͶW=§µjØÊo„’Œ 3²8yj‰ê`nûÁâ'YÚTKM”‹ùÂÔì %Ù³¹Â]¢þãEš ®ßHœÑ"P/V,N~οPóÙ3ãþ™Ç ­ù¡cÈeü¤S¯ƒ´ -ýÏTa%ª£3»Ùª]`ÁQ êó}³x:HX¿U;úŒ hHØõKጬ‰•Y)f.¤«â£Þ„ÇG8îàôº¯a»p7åsÚBc£µÎ¥7apx X&_­ð¬)wMÔY„«9y™ÁŸe!Ë×÷*$“ §E¿jéŒ)f?ÂwJ×ÓŽRIßU±($ {û‹xÜ©ÎMYÈÅäJõÅc?—Þ^Ì:yðý¡_nA7üÕ©Ô–?Ài¤kðÉPHRòÎzçiÞY­Ýû+Öäˆ2…tzW3¦Ž­à:]q¨¢–½¾:µ;›ôšÿL±î\ì{¯1üÛüë]¥ôî•ÀJªÏªœûÄøø¾z$A)ŽöNÏÊþû>ϾЇÑu—ßR±Â ö’ºÛua{ذ¨ï•›)wËÜ%ÒUùœ×“ǘy‰–wè–š7ô¹ÇÑöˆøoµÃî:5Nö˜~ø§•ûß¾ËPéä—b@3¢€iÓ,m ¥däg àø¤'®/}"Lø¡-”ÉP&kB;…}ü§D7×±0œ^þ +ú)[¾ž¤.ª×VYzd,Ò#áx]RÁÜõ]òe&`”2Ÿé3WÀâ•ZްX…Eµ®ÙßWÌ¿vAJ|,„$={Kýë§Ò/Ð0Ñ4ͨÙEiÜ.äîOîþŸmÏ)¶9ÜÂOq?¸ ííë[ï]ÄtŽþF™]ðL7 -—ÑÅW%HkÂE©(ˆö6i°¶&b°Þ¨ïnwÓ÷߀MÙð#îVbjXèÿÞ«[k‹ÄA³±8Õ 7j/I$Êý¥í¼ž;‘zJFžÀÊÓÔµFÑÌ®mÆ"F̶ƒ°‰¢2­`Ÿ¨3pCQŽf©:ÇvlÔÁþZ[zCºåçš8ÓîŠu¤ì5í¶rÅŸßÛ¾25ùŠ †ÒVÔgó°Õ_Γæ@ÒïÅ™…Á)DWÐ6+Þ­ë ‡ñß¼©MüâÆaªƒi>_ªóCËLD CP]ÐúÂL½\=ö›ŠLE Ñ:Ç¡õ>_ç¾”ÕÓDÀ`h{#oÜ1§ÌT«®X²é¦ nh¿,ÿá2ž’ ‰ˆFÙ`TMN>ÜïO?èdÚg>|Y×ð²,"ë•ÊWBJ° ‰ëÊw ª7¹·DþAG—/Øi¬\¤C§õœ.óbƒAÆ.Iµ +ËÁúŸõ#¤½ü?PÝuØ¡™BŽTÜksmuçÛÇ¢,3ÔZ’ÌQ|7û³Û;eOŒF<¸7ƒWÜRgò Ó· pVÖÿÐÄ÷èæjnr–+zóX܆;$¾Ô%€ë›<«×³!ãq/:˜µõϼ¾†<…ö  ÝðáÌ´w4`›x©¢†1ÖñÉê^ah¤K¸$J^¿ö†[ÖÓ¯õîs ¼ëÿz†¢Ä?÷å~.õŽÇá[„P¬€Ûð»-kë‹ý‰ÕL°§™ªï 4ÁÚ‡þ Ir¾ëýéÝ´g3ì=jï©l¾\þd×Gpá"V‘tÏÀ¶5Øq\ Ýv¿r›âÝß {?ƒ™1¿"‰IRœ<-²*Þ]²=¹E7œA©B±:Ž#¼²ôäÃSPÇ­^1¦?˜"PPŽuáùíWý˜òiÕÒ‰¸’§‰_D³-ZV4áÐ%TLo bæñÛR_—žãö“øì«úá”ýcuW Ÿ¡Ï9 GÓZ¨Œh2Ù×’Þµ¨,©û)õ悃Lµâ·õ $Wjþ%ÚZ¯Ôfß¾«¦W¹êdî-î ±íynæÂÄ(è1ö2|N¥ô]kÃÅ%200*«›ºR„1¬/ÊðN÷ìóùû‹¨HfÅ¥KÂe«]ú,fY…b!Ã)ã¾ íÜà…F˜´ïú¾rùª‘œ4å*Ù÷îÝ`ÿ6[ítïhwýÞ¿}ù´¨Å0VÅ‹IE™B;§5 ÁÁ"MLýÝI'òÛlo©?œ¸Q Mù%K²Ñú—¦Ÿн¤†Â…¬–ŽŠ6tÙÌ ª‰ÃjºyUqjRì™IP?þ3i^p…úÊ*÷a]mVºúÔ†‰lHÑ!_ €è&c[Ï“â)¬;²ü´®ÅêüôÕÒ¤’ÞúÞž¢ùI1c¥3N¨œ£´ ’©JçâçESNÝ“Qˆ8jn'Z, €"¬ õϧwßÊ[…—~Œ»÷‡zÖíO‘ -rÍå…Œ†ê# Rßò,"lêþ¨¨T"‚è:‰¹'\â­CrÞ×z,Õ¸ §A:æ‹Ïg<¬>Ú'dPîÐÿ¡1ŸibT,­L”¡ïéd¢º6[*1½[)R«¢x úJ6ްÉÊlÅß ùЇº¾“¾%ß6%€ÌZ€ÿ@ ×/Û:œŒœPœLö'½<Òpk\yOO6ÒÐÆÈÔ©B"ÑitÚ>€Bµ8o)vçùêµFÕ¬$¾üESúÀŸüY=ÁÂýŠŽëWÝÏ¿6nhϽ±ý;]¢f%(ÞŸèA¸Ž‡yÛ$o/Aûv sÙzOÖÆ’±È^d¡›_Û"Õ3ôܱS+­¸Œâz»ö­‡?5Šž:¡ô´Ä)lI_%Ѝ ªÂý»6}ê™;Ç]CË‹/—øMÊ›md>&ö3¾OÝÑzÙ¢²ÛbÒ¿'•?OäºÈ"`ùÌθrÌJâ˜ô튓yðYtè»;íAýºû);†1åO¯º2¶€ér´¥Ró˜”LÓ Á©^šv¤öŸ‡G/„ß_ú±Ø«'.‰ªÔM“k—K26é÷ÿôWSºÛ§¯÷ŸšN×V¦KÃã|³DZ£…C3¿åB”‰…³[ÏY *J“›Ûä—añüïM–͇»‡[R»³Ÿ"ýŽ‚fç¹8¬™^} µö:›QòbSpìØcø±gÊX?KÀð~íó‡6ÞOX¸:âZôÍ  -+Ë,¶öyL,Z&1ÝÍz*ÐßeÑIå²ONçÓ‡õ™Í#ùÝ1Éq…•-eÀh‡ÛQ$ßn:pEä®Àì]05‰°=5˜®‡¶­2P‰5eÃí+–an„UÐŒºÎ’x Ù?ò­ëue¢¯ÓÒ )Ý7º:n:<\6¶c¬ÅÎjt(âHe¸¹Tس`8œâß?0­•ÇÌщZžôOöŠ¿^üŠõ·="æ>ÖÝJ+u@ãW•DÞ,똒7•|›ðÝ쨾ýµ€€@Ò¾g[^VÙMÅÎÁ/kÍô)$œ4Â}ekñ{3ç~ÖOøA)D*v"ŸX{Rwª*S -aÉÁ_¹5wCs̲ÕûÖþŸjÆàùØ÷–¯ž™‘ÌJþ¯swQ⢃³F‘1b˜üÒ|ë FžøßIµç+x-Jï)#ÌÙªëÃn¾(ýpð»*tYÜÇÎ}Å›Ço¸Æ³jÞÒ±ko{!dhÖ- \˜`[Kþ)pLžXlø ÈÖQø~‚¸×Çl7¬S¹þ›¥*¼”>§Â.öÝìþñÃdi‘;`‰‚j#–•µß¯XB`ZdHnh“¿èI¤Ž$Ì‚Õvz!Œ^ !+NypÛÈŸVͧÁ`f–fU®äi l'Nªw!]ÅúŸÑ|È'Žb&‘$US —ŸÞF`'CЇr(¾Kª‰;Æf+eZ´X‹+öÿ说oÃ™ËøX9—í¸*¬^™FRЙÿ£ÑFï…ÅAUÂ͸)¡Q#>£0Æ*Ú¹:R…€à”%áee¨±¸ì¤|üi3bNdoÊåo3Ç\³RŒ†ø9`S? — ®ó·´ƒQEûõï©3ë-1F]ÚKé"Np÷#Ò~ ‰JIa†ôTA}Zê˜ ÷V¸ ƒnq7; v›™QC'C÷"¸®_o†™»NIÆgŸìø‘Y¿_µi´ÿgD>Øæ° âe©!EG² 'f«µÙ_—ï~r›þÊÂIöÉéS·y_!ºn×®æHQ–r5¡XÓh€šé©)Ñjw(üÜ}ÌðÏ4|Dp_CSàë€ÚÏ!œñ)— -Á?§†Ï9?³7mhÓÑzô±Tk¤Mˆ»’jÕ´¤Ò«ÑÞ™aä­"5šÑ´ïGZ‰CFp)6õçV{d0¥álƒ%8ç= -R §Ïò‘”-ý©¿+ÛU4¢.^1Q0¼[ç>ÙÙg¼9!‹/JÂ@¸N´eiÁ—23Âoæ+Ãçu#•!O°éÔ ìâY@—!WùAŽ…ó¢fÂŒpV[¾Á)?E ‰/Tc¹Þ]¬É0×aH¥RÜóªq¼¯)XßúdᎪC…Ð鑼gˆˆzéže¯¶-…¼ÏΩ?iž¡}Q'ÓÁfü Þ÷ž¬c6_|5µMZ@·1úf ñ9êês ª]ÜÔæBZ -®0QU?Åt v¤T1_¼Yp¯ÏÑn1×’äê'ŒWÔZB¾y¶¦}Âw’ ë°È‹G¤Î -f‡dúë‘|3ÝÖ¬9»pï°h1ûó¸í•½ÈW©”qn‘9¤pÙ²Q@ýDîã6Ó>ëo\,«m÷º·óSP¼ÕÆé‹cŠ˜/»f€¾-Ïxˆ®;SëP´JáŒU'â#VúÝ](ëeQb}–¡˜hïá\¢°»­ŸÓ¢aKY3Ê´R°ÝĦŽTWòã?É ç4ÙÚ¼~pÕôÉs;.“=@K?ò°ÞŸmG¢«Óg‘n1»€˜ótÆ[;ËæW{¼«ó¼¶¤êqáãï876} ÎÆEòY‚i›XëzPD}ÕÓq>ÌÖ=¨[ÓeÚÚÛ-DuoãáTç+ÄGQ½Ma.Ù¹êÜ×,r„U16W Ý¡UPÎQâ sªÞûÛT—ž´Þ>UtB%®Q?™†o\?‡c ©ãàò DíDÞÌÁ<¨‘‘å±cW'}¿ü%)yõ(¶Lz,£›Ú÷=Á‹º“Ûˆƒ„ªk_mÖø'\ÿg:óÈm§j³.”ŽÑ}½³‘šÞJAàȶ¨â>ÓÇBt^¿æt8Lyäån¨ðª~ÛÓœ„×RD"Ÿ"nN4U¨·áìDz./)6dÏXã¼;Îi8D• ÊV7yüöX¨å! v”kÝÛÓ¬ÙÛ’Æ9G -#ª5¶ãƒýŠŒ[ônjŸÛ\vù$/ãRÖyÕ\-¨üKŽà|B8x“AíÁ.O_JŸqD×=®_ž~:? ³7—2⊦Ý|jèÚ~e“hŒ¬Ò`2Æ`PzwL˜,Á”‚Ó­à¸=] {¸â>uD-‡UÙð›Ãí÷Qri|& -Ô>ÏíFŒòóGL2Õ×i#yûyNÕÓSáÄ.ì(¢ ê—´®u߃]bùž¹Tè²ÕV YŸ(uAyFìT½ª7?‰ã[×4¯#ã:ªÞš|1¥·cÿÂÄ=SŸ¶Q,hÛñðh]©¤ßûàzÑ÷ùÝQywÚë\ç£V}—À&}nJÎ_#2ž½+¢û%̰Ë=NIW™H9ถÃM”†òó?¹>HÛÀh[ÃdýÀ#þñøV¸°ÏjTÌ†Š½Úß'9Q£•ðD -ƒ¥=Ûe!sdê)‚.l4lóþE¿‹'@ÑN“Œ -žKXø4¼]íywbZâü™rœ¤ÂQ-<µÏ¬À¯´)"‡£]·ˆçÚ\¹çyy/Àbý‚ .G¢×.èßY÷®! É>a'c6CU¢y{nÞ#‹MÝ¢UüišB|!# V­}'­5®Ð±äNÆ ]túPÑ:/­ò¦X˜f9Žó¦žWv·Ô•©:N"õ³g²N î‡íæV¾–HYÈ.J°M¼FWÁqAéoÑxJ!&Wðˆâ­Tþ“$(®m Xïe{Ì××Ð8]/^¾g«Äo‰M·9}SO‹ý‹³n£zbÏ<3³ºÍö½9dÏDy6ÔDPM:Žð˜S“ wh…µ„cK´Äã‹{:Qö¦Ò-‘þh[N½œ;M7 !ìX¶lç -ûÆnÅOøÙ/šåvýÑ;Á¿Š(æÀêzÑÊ–>ì9¬Ç”°n÷ùv®Û·Y^+ùå+ÔÅKl—‰æÀ+gbïç6Å”E”vÕ8÷¸Ü¯¸.ÔF,ÜcjÇqx"3¦Ò™L•*×5FžÅVÝMçï©Év%¿ã´Þ'£N·ò6iM¯È-ËÅ8ò̉Xµ3<³ƒE´p“®Rºçègk,¹,1MwðM»¥&©v#(&aWgXñïs’ÓCˆoRlãB& ¬Wb_ÎíîŽNGW 6Øgåëg5ˆ¦:”'réÑü_³Ž§ËoÈtö¤¶egSÌUlåÓuD%ÝÐ=Ü~¯à0Úò•K èñ”ê ƒ\¼Úˆ½ À'&Ñ>—Ä÷VåTËïuXg2YèfôŽ ¿™€!m†×<^¢¼™=¹†\„¤žºŸ3>hÙà …ìwÈc>Ûºa/AØÛŒk1M,ø}GΨ|ÐÕ¿ÕSÞ=t@†šÆZ‰œà¾‡_ö}ô€–d0£¹¯”xP× òóvSF¢Mv˜Hv¶y@¼ ½„uØ1åÐØ,*Á×ÍE -® v'ö½Îln;mÿFN• +/Ÿ3Áô1êˆõí‰~4HFz>5#Ε{}mBl+ï Èà+S>îϵ ³3™ýžYZÍ?º°ü|(ø«8EÛN¼-Zr^’3©ÒÓ8 3ÅX£n Õ¤îc„Ô#gAGŒT3$kÿu‰mßêÃ0¦ô%BV¾®”ÍXKƒ²ÿ )¦|¶¼,–…WTгOð Dt&’vm‚¿[ñ²âñ‰hÿOr£æ§E·úÔ‘”˜l LkO$&¿Tƒc¶“Ùå€ýfSœªÝËX¿aП‘$ŽÒ(HÆ[®²—|þ§¸™¬b 5Q*ëkbC™%x=ÒqYŠ€¢y•#HÏGNJq¥RÚ‡o•C¡ -«÷îõç‡k¥¨9îx]R Éé !lŸàk<“™HÏÕ2Ú3'Ð_}Á±nwYíÖP¤z™$z¸ˆå¬uBZö˜ò,ïД‰ˆ6”E׋8'<óٔ᭦ó'îôÇÇ)§Óˆ%£‰[LgPÌùÃ[VëÁçµü÷=iˆçv¸#¨<¼‚¿ÏûN¶Ë9·©\qwqVb§E9¤»çóÆØ';†0€z!1q*L»_E³%)dª8„qb" Béãkë}™`_ölz?d(d𠺢¼ùŠú·nöM|Îëv N–È1@´é}Þ…gðvÉ–ßoµµRj¸Mk5"YŸ~bÐW¯ÔÛǦ¤}wQ1øA³x/ÆP/3Þ‘,¼#[¹3'Ì™^4ªýJw“çM›vŠ%Y37ÚZ-í!ÚZ„¯Nêý÷ÆA@U/#ÀJG4½øˆ®Lš„(Ûq¤—ZDÉŒf%)1[1$EβU?ç]ùÅÏ÷àº|/»çº86е"¿(8°™NWÎÿJÙf[ÙÉ(áåÊ=L 1û•œãBJ9 q•Cqƒì.¤Cj]ÃðÎ/b J:Hüäë0=—›g»W†0¡N¸ 4Òa,‰FˆÐtoÕ¬’«]G=ç#þ*½QÇÅ[àr4XÅ,[‹LŒÑÆÀ%D줫v‚SËBYtD\éLrg¡ÒsX?ìbW,%´ŸOZM3 Ý$Ë ÓÑïÜ„u“={Êãe†pæëaú<ž¬,®O1·—ŸbÍIÞÐÅPE¿p’·^¼à|ˆüÔµC?Ìçm£ù kòúšQ ½ U*<\£›Œj¶sP‘>N¯Ý(Ó ñjùz£¼uRX,Ã"É"˜z2Â[°À´3Žœ}ØÏ"/³Ö@~Ž!¶Q'–Mªý.¤äøx®9Í“xNKÚ¸ìì -ÏÆ^é(t{äg^Ì)¾^Äyoߊ“8E˜‰YjÚ é]ÁØ¥ÙDf’ø iÌÌR¥®Û·‘•¿#ëÊቛ¯½ð“_“9>~"iú -M)Ã9Âp:Ä'°ÂyFJv5„yfù¾ZF|šÿ˜Œû;àcêØBüß›©î¬ÃŽNÌtèÔd/O7ðŠëË–“Õ7ÑyD¿‹31ÓóÏ÷ÈJ¶b@=­Ö“4Õ -G‘áR웸5™UP®ÇǰH„×5Åã>½,TGè±8ñª4ô~È®š††,h»®ß z¿š l–,hËÐ%ˆÁC}ìÜbÒŽy’Ÿ&þÕöZïtï|çil¸#é¹–8!}BÌ’ñé{‘ˤFX.K·¿ìܦ|ºgÀM¤ûÆ¢•Ü=ÿ=²X_S`ìÿ<ì)ú¸Ô#»oøý–‹¿ˆ‰´ƒAF;ûû -Ûwôd¡Üw÷xgXøÉ\›ôi3“ŒIDί¹N%àŒ±éï\á>ذtmÖ$¼ãÅ,ñá…uÛæþCU˜Å6é*xsÈé4矾½–çëOf%,RKÁÖñ¦¤EÎL_2¾›Š‰iŸ¯œ±zÇÍÃÁs}~± à)Ë~ת0üÈ»€ñ¹R.Ä•!/`9ºz\h­õx–jÖ‘þ:9OñÉÉjð‰¬”Ô̰–˜Þè.h1ýdftX*ÿ7=™q FB1w)ÝúiC$ü9œsðàÒŽžQÔÄÚÂdÝ@BN~CªÝ©.ÉÊ¢^r’¹º¨JªÂ˜ †C4|¡" ‰j&m¤cYõ"¡ -#‡O/$v$R®cià¤Çâ÷Û¹6AçU‘©®¼n„ ¥Ä£Ïš‘mÛ«ðáäwãëuÃ&µ!¿®êÐ0š{©Ld"Ö½þ¤´4¡æmTu{5v÷­õýT_ekp¤¹¾r§Ð~ Q4ËÍRK2'¿ÊÀRŽõ‹l9Ù‚<£G{{©ÅVØeÞ=þ½ãøkæÈr by&?Ý!`@Ê‘Ъu iBškÿSéɾûmE@Ï4Y×^Y´ ~MÅǨp¸ägÃýö¥fÜtUAJgi/MüañD…+×»v­ø‚|ø¨.‡£0å÷]°k{r|xœ4Cäcüá5üº)µb2sàŠyÄjÌð%Ç)œ¯¹©ß81-?­ ‘#™ÄJ›áå#“DtC=ýHn¥?n^p ǧaÎ’òÆClÍOä˰¡·¯?xæÇñô, $Í 0ôfD ~xa*îD«­†S˜Å8×ü¼Ž/ÐÞQ]‘E „7d+À©'8Ôô«÷Õ™X²ü¾†IÓ:Ùÿ=Õ-¼°îŠ1tgþFHHÙ´.ʦ¤œGºßFúÄÇÜ=f¯h®N½]Ï©6»‘Cò°xVÍgŽÓ´¯*ʯÃÛ2†Ÿln»`Oêçl~’»×&PÑàoÇAóa|TtžòP—7ÿÂÖ›xS4ð‘Ìâ»[kSø˜¬O¡Ås§EÏSa$(’§œ¹¼m1¾>¨AAç¥ü‹#’ëµñاw“t“Í•…EYOU)-&5[ÍÕ” ÐYÙ>uï¯tH¸KJrãGÛà´ç«š4¥`Ê,c%ò¤üš½›õêó­‰îÖ­æda WÓæ'öj¹·„x!o“E¬{Ÿ×I„¨€>×ô¯R.ÁŸ_fnÇŽÜgJúvájï JPnÑ‚ûÇO⮊²]À¼^Aî^‡H_¾ö•ÑJr(•³¡ I[ Pȇy°ôQëG»ÉöQ  Ø}ê˜;AÊýì:ìº#=É“(þÊ|>ä®ö’ÚJ³òW³§‹„²ý:wR­äL -5«€ßbÑdûClC‚eÑ3›i“É_É>`"cGKó‚+îœÂ”SË%ëŽX½úð±Å­¾ç2]p ×9¢øõÛu“°WÙ8å{‘+cc"]•Á½[ˆ‹uÔ§Š®åëÜe\¾"Õ?M!©Ø‘5Yñ>>ƒg™. faSçõ"VY %¨öôÒPâÀ}ç_~[Š3šXh¬Xâ&4ã‡4ó ZòU‚õ(c˜äœMÈ>õ”D{Ê=ëÚ -B4½0üÂåZ8CÆzh¹Äõ ë­ÍÙ”™\ÛÑíÎ¥+ò—áE¢ì¹:BZ -ï!ÖdÙÌ>‡·‰—´ß•D¿l,¸Y‡þl½P ºñé:®DÁUÃñî+k#/™P¼|±ÔTa=Õ*¥­T^훳ø®Q¶t°HKZ®Åœ~`LgÊ`ømq%['=§!Y§ù“%–±y»¾nrI Kvß3g&r–÷é¹ÄÈ<j<~o™4iu¶ßL‚Ó´äÛðrœ..½¥×hÀ³È*ÂKÐh©Oañø.[ždZÏáƒçÆ"òŒ\#`"*äªFí¾a„tßÓÅ*YõaJFÏ*‹÷öýä(ŸÇ%hmdfRñ›„Æn[C ñŒSÄoÖÿáùÿü?A`j4vÛÛ;Y#ÿch»Žendstream +xÚíteT\ë–-w‚-Ü ®ÁÝ-h h…KáîîÜ¡p'H ¸;—àÜýqÎíîÛã¾þÕÝ¿Þx5Æ®±¿5ךKæÚ5¹Š:³¨©1PÊÎÌÌÆÂÊPÙ;;)ÚÙ*0«Í•­A€7€ ™šZÜhÙÙJü- )@h`g°ñññ!SÄíìÝAæ`†š=##Ó?-¹ŒÝÿy‹t™ÛhÞ^\€Övö6@[ðÅ;P€-€35 ®¬¢#«$  “VÒHmŽFÖç·VL +  ­`fç°þÇ`bgk +ú«5'–7.Q'€ÀÉhz º™íÿ‚˜ö@G“ÓÛ;ä0w4²¿ÍlÙšX;›þUÀ›ÝÌîï‚ìíÞÿ©{#{{k÷¿£íþöú@`' µ 2û[Nð[ns-òÇ¿–EÖÖÌÀÆú»©³ý¿c.@Ç¿D÷×Îпadjgkí0š!T²¿¥Ðý÷TfùßùAâÿÿWäýŸ‰û¯ý§øú=ÿ+µ”³µµ’‘ÍÛüã’¼Ý2vÀ_÷Œµ‘#௻ÆÁø…Ù€¬Ýÿ‹ÀuÔþ£ØãûWXlô6Q[ó7a˜ÙØYXÿa9IÜ€¦* °‰ÀÌÈúmfÛ5lMŽÖ [à›¶õ-ˆ•õ_°Ï +Û¿Dàú´5ý×òßäú»øêš +š’JŒÿÕ û·§ÊÛ&€?»Ûÿ–FKÑÎô?ñˆ‰Ù¹<™¹ÙÌì<N/›÷‘ño¶žÀŽ 7ÀVVV6ÀÛÿ¿?ÿ<éÿ ¤­‰é_›£6²5}[¶ÿ0ü›8;:¾iü÷÷ÿÖô¿Ÿÿ^{ Ð h‚¼8gg"d™š‘®ÁÏ镸ÒÝÉÓl_\ÿ¹0߯ʮÃ75l¯Üð©:˜¥aœÿ¥Å}öÐþy[Žag°Ïš¶ãð$Ø›’¾+ÿý*M+ãNÀǯÅhiGZQž§3 +k°ºÜ¬š;£ªj_!Oð$ã­Žˆ§·ô~”.ù~8T7öè>&)u±¸m˜ PX5‡G4‰û·7´½Cý}çp]ÛDŒÙ±HÔ.°h4‘~ÙDºåžáŒ[ïjwÈbºr¸°ÌN¤î“ƒðÆüSgÊrUm4>_pû´e{eÊóÀ@’ªí!B¾^gYâ¶fˆ^FT{ônRçz[âœ5Zóì3ŠìŒ—*J–># +sÁx§¼*o.á_g}wýœñl^îkÝŠÔ'Ø’(Mô{Ä'’WuçÙ>`·pòdèŸoR[ÌÒö! íë&XôÕFZü¦½ê>ì%Ü}g·û[˽æb6J¸uq ÖDP»}"ßžo«/2åKžxÊ$©ü&Ú6|I²k¢QᲪÖÒß(Fà"A=PÎ2íܘ??ý@²å·‡•Hki–óº‚i¦¢'¦ãfü¯êäœíe'×ijÞ ^ú«úò!,lÌ@Q“àx¹ ªy—3µ€ÖßDáµîÂôÄ©;bi¾©õZä7ôÛf]q?Žlcß?‹}…U´YFVg½\BšÃfÁOAœ¾Ý=ðÑP†>b*˜ª¦ ‰¯írß[îEÍÀo]æ7hÍO#Á]ö aOp£Ñ’ݬyÝGÜéÁK² ´dÝŽ½6[ +Û#Ò¾ç‚u¨Öåºp³àž\¢4hS ©–Eéf< ¢sj`ß®›ÌFpï(üÊæú|k-è=‹ãEâï°ü‹üTvalÝ´X\0X¿Ù¦?˜|ew…­K£KòÉäÃïÚØ¬äÊŠíŒ]Ý: %¢˜~¡¨ç7GÊÎÉÃÄ} .Íâº$ÉvŽÏÊ~{ÞÏ>ÐQµßS°Ââ¡v»Út`{æÙ°¨ï•›( wJÝ$ÒTùœÖ’F™yˆç·é›Öõ¸ÇÐv‰øoµBï:>ï2ýôK-ó»}—®ÒÁ//Ä€fHÓªQÒBÉÈÏâÏñIW]1NúX˜ðCk“L2 Ö¸V2ûØ/‰.®#G`1¼6ü~fÔ R–|Imd¬²ôðh„{üÑš¤‚™Ë»äË´ÿeÓ.ÿ…Kµla°. +‹jm“Ÿ˜=~ͼ”øh0IzÖ¦ú·O%_Ã% óa:¢hšP³ +S¹ÏÉÝÌŸÜü¾ØœQlq¸†=žà~pFÛÝÓ³0Ú=î,ùƒ272ï‘,n&£#:$НJÚ0ˆ/ŠRžåe\ßoeEÄ`µ^×!Üæª-î¶ÿš¼îKÜ¥8ÈT?ß÷£G§Ö‰ƒf}a² nÄN’H”ûkëYwõ¤.<¥‡‰Kµ¢©mëŒy´˜M/a#EEjþ >Q fÀº¢Í.RU¶Í舽ݕ–ôºtó¯Uq¦SÜe«Ù+Ú-åòëhŸÛÞR5ùò` †’Ôg³Ð•ßNf@ÒEAÉD—ÐÖËå^-ùkõqß½¨}cÇ`ª‚h¾_¨óAËŒ‡ŽAPÐúBM<]Ü÷ MD Ñ:F¡u¿\å¼”ÖÑ„Ã`hy!¯ß1'O—©.[°é$¬k½,]sMʇG¡¬3ª&%ìõ¥íw0í1¼¬}ö´($ë‘ÊSBŠ· Žë̳§ª3¾·†DþIG—'Øa¤T¨M§ùƒœ.ã|AÆ6Q5¿3ËÞêŸÕ#¤­ì?@ÝeȾ‰BŽTÜscueûû%Ç‚,3Ôª?’ÌQ\û³ë;eŒŸ†<¸7ç—Ü×)Óyi›ú8Ëk×4$qEÝ:9œeŠîG<æ÷_àˆ/tàz'Nët­ÉxÜ +÷glü2®® O!ÝèCÖ½93ìôÙÆ_*©a …õD¼3»–èâ/ˆ’Ö®¼à–tõÊC¼z]îú¾¢(ñÏ~½ŸM¹ã±ÿ.#à:ônÓJÆê|ošAb%¬Äiªê3 M°úá]@’œïjoj'õÙ{˜D—ÚëF*‹/‡?Éå'Å!\˜ˆeÄ£Ýó5ئ;– ¤ÓÌî[f=O¼ótï«?=ê[("1AŠ“K£IÖOÅ»C¶+·àŠ3 U VkÍqˆWš–tpêþÌ1N«[„©Ë¦”cþpëY7ª|Rù³d<¶øiü7ÑL³¦%Mt1ÓÛ‚˜†ºĶÐÓ!E§ç¸ý$>ó*€€~0i÷ÄXÕÀÃg`ÈsFÃѸZ *%šHò± w),M,Ä~J¹9ç S-ÿc5 É•’w¶Ú#µÑ»ç¢áY¦:‘s‹{hh}ž>76 |Œ¹›U)y×R~L H€Ê좮!DG íM†2¸Ó9ýröþ<2‚Yqñ‚pÉr‡>Ÿ‹YV¡HHààCò˜O}÷x¡æŸm;>¯\>j$Ç9Jv=»7ØŒBW:ÜÚÛ\~ôm]<-h2ŒVòbÒGR&ÓÎjÎ@p°HRþtЉü1Á[ì #®W@S~õÇ’l°ú­á«b'ùÙáÜVS[E ºtz“ÕØ~%Mˆ¼²(51f–L›$°ÿ™Î¤/¨Ü}ù•{°¶&3M€}rÝX6¸ð€/@@t“±µûIñZ +ëŽ,/µs¡*/m¥$±¸§Þ˜¾§Û›§pnBÌHé”S*û0uœd²Â©èyÁ„Sçx"ŽšÓð§ÍïB½þôÁü{Y‹ð"ÂÏ1·¾Ú½IRA®ÙÜà‘=$Aê[ž„ÍŸþ媓D¸“§B1·ø ¼•"Höû÷Åj·Â¡Tˆû\ÑiÀ´G¿åG»xÿtÊí|ú?Ã4fÓmƒŒŠ% 2ôÝLTW¦‹Å&wË…j•¯?CÈÆ6X™-ù» "zQ×¶Ó6å[g#Yóñäúd[†’°‘ã‹’È®óÐË" 6Ç”wue# ¬ MË%òG¦ìü) T sbw^˜¯ž«TMZ‰âK_5¤÷ýÈ¿“ÕÌß/ëâ¸|cÐùò{ý†VðÌSÛ¯Ã9rFòâý±6„ëhˆ·u^òö´g?›õ¡çxu) ìEºéµ5B=]× ;¥Â’Ë0¶§s7ÁjèSƒè‰#Jws¬Á¦ôE`"¨€:¾2̯sû6Œ¹cÌy!¤¬èb‘߸¬ÉZæc¼`ãû”mÍ—áM*ÛM&½{Rù³®óL–/ìœËG¬¤Á‰ß/é0™'_D¸ÑîWÛ­¹ð°cQþò¬-a ˜,EY(5JÉ4Nœè¦jEh]?L;x"üùÚ‡5Ï^Å8~AT©n2T³Tœ±¿A¿wÝWINîjK˜z¼Ú{jÈj9c¨(Mll‘_Œ‡Äñ›¿7^2êjNéÊzŠðë? œ™ãâ°bòY- 3cjåaŠ|Œ8í•»è‹p¹•2N¥€¨Z(Ó÷:c½JÈúMÈî¾vN›êè¥û}pÕ¿À kCn-,xŒ‰á¯Y®UÛ” ãç‘O(¥ÙýÎø'ó–CEƒºªëØeŠ ÿ€O¡•ÎýáÜ!ÄÕ³0ŽÿÙ™2"s¬o£w²;ÜëA¦{J(…5 ¡YlYÏšÈÚíi®Óâœûhå5ÄÊótZÉ“MÁ¡}—ágøN¬ cÝ ‘?ÃûÕ/Zy?aáj‹‡kÒ7}€*¨(5ߊßã1¶PhžÀt3íù¥@—I'•ÃB>1•GÚk:[„Pè{Ç$ÇZºô£ n[ý‘|¸aÏž³ ³{ÎÔ(ÂöTo°|кÂ@@%Ö˜·§X „¹=VA3ìB8Mä%dÿÀ·¦Û™~´FK3¨t_èl¿i'pw^ߊ¶÷?­Ö¦ˆ%•áæRaÏ„ápŒ{ÿÀ@´Z=GD'jqÜ7NØ#þjpþ;JxvVÔïÝô°˜ÛHhW ­Ô>oqd"y“¬CrîdÒm‚ÿÓú¶sÔ|I»î5lExYeW[{ßÌU“3¤à0Òp·åÍ…Mœ{áX¿à¤©Ø‰¼ƒaíHݨ*M(„%~çTßõÎ60CÈVî³Yû~©­ƒ?>æaßCX¾ydD`0+ù½ÎÞEŠ‹ÌFD‹ còKó­1zØãÿ Õš+çµP(¹§ 7c«¨ ½õÿž¯ôÓÞ÷²Àya];ço¿©ÿ +ϲiSÛz´­õ…¡I§ `~œm5é—ÀyyB‘Áƒ"[{ÁûqâoÓÐåºïªðRBøœ +;Øw3øGæüõù¤…Þì€E +ªõVÖ>ß"‰Ï“Br{´5ë¼â@u´@a¬Ö“saô| y\qÊýÛþÔ*¾Ï|ffi&Qå +žzÊ6âÄ:gÒ¬?yéM|â(¦‰RÕùr ði­æp2¤ˆp(â 1¤¸£œ¡æ1Rᨅ 59©ðÏ~J{ÖÜñÙôu³Y+ÂJàå)$Müà¹kMˆz,ª.hÚU ñ…1FÑÖÅ*§, /+CÅe+ÅàãïG›},{S&›1ê’™l8ÈÏ›òIø°°€¸¤•·©x€*Ú§wH™^kŽ6ìÔZ$Hq¼Æ!Ü Oý#$*%UˆÜGP õi±}&ÌKá6ºÙÍ(ô@€ØuzZ Ý^ˆà>ªR|­ fö*9 Ÿ}&R°ýgFÝ^å†áÞõ°(|õA~øo,"ÊŠöjes>@vôfK=²ŸßýÄý¥¹£ì“ã§.WòÞNBtÎáÂLå*B±Æ5“¢MÔ®øÙûè¡Cž)øð nßúB¦€×~µ_ƒ8c“Îãš(‚×'ÏÙ¿²6¬iÓкõ°T«¥‰;kÔ4¥ÒªÐÞ™bä® 5˜Ò´íEXŠC†q)6ôfWº‘d0¥àl‚$8ç< +Ì“ ¦Nó”-ü¨(Û–7 .\2Q0¼[ã>ÞÞc¼9&‹+LÄ@¸J°aiÆ—23Äoâ+Åçu%•!·îÐ èä™G—!WùIމó¢fÌŒp V[ºÁ);A Ž+Pc¹ÚY¨N7ÓfH¡RÜõªv¸¯Î_ÛüdE…Ð鼦‰ˆzèže.7-„ê½NϨ?iœ¢}U'ÓÁ¦çÿ +Úóž¨e6[x5±IœG·6ünñ>ìlu ¬YØÐâBZ *7VU?Átr T1[¸™w¯ËÖj6Ó”äê#ŒSÔ\D¾y¶¢yÂw” k7ÏC¤Î‹ b‡døé’|7ÝÖè¯:9so³h2ûñ¸î–¾ÈUªû—rl’9å'sÙ°Q@ýBîå6Õ:íkX‹(­ió¼·õUðW¼ÕÂîcŠ˜-¹¤ƒ¾-Nyˆ®:RjQ4KàŒTÇc—ûÜœï¥&)ëdQb¼‘– ˜hïáœ#±»¬žS£`KXÓK5S°]Ħ~ WUðã?É g7ÚX¿~p™ÑðÎu=*•ÝGK;t·Ú›iC¢­Õc‘n6=‡˜ñtÄY9ÉæU¹¿«õ¸² êvæão?32y ÊÂEò^‚iYk»QD}ÔÓp>ÌÔ>¨[ÑeØØÙÎGuncáTçÊÅGP½L`.عjÝVͳ…U16–!]!•PN‘âñ³ª^{[T´^Þ•tBÅ.‘¿˜ç‡n\¾„a ªáàïëðõGn‡ ÜÌÂí?¨‘‘å²cýP'}¿ô51iå0¦Tz4½‹Úç=Á‹º£ë°½„ª&koMæ!ø\ß"g*ãÐu»r £6„ŽÑm­³šÞRAàÐ,H¶ëUõ@=ÒØà³žTÄ2–‰ÆŽ÷ã3él~ éÅ»{ º;j•ÜvÓœ:Ý×I“ª]:³Í~ÿòYŒ“o4|l‘E½&$è0¼¾Mi4p˜òÈK]Pào½Ö§Y[5¯…ˆDEì¬h.«POýéµû’%.71&x—Ïèó+xgŒÓ`*”¥n*04üøý±@Ó]ì ײ»«Q½»;(s†'FTkhÃ…û53èÞT?>·:ïðI^Ä&¯ñª¹˜SùÂysð&Ú‚œŸÊ¿–<㈮¹_½<ýrz@go*aÄM½ù Uß¹õÊ&ÑQù™ÉS€AéÝa’S2N—‚ÃÖT¾ÎÁ²Ûä!µVEýn×?ÃDI%q(P{<·ëÑÊÏ1ÉT_§ åíæ8UON„·:°#‰©_R;×|öwˆåoxr¡9ÂÃ8smª¾F¶¦%ÄM‡(è99ÄòîúÄc˜†Å‘¼öJj¬ªÅ2¦<¤®nt [.K©Ã`-›]ì†ý0HýÍþ©.l7ƤSÄBîÆ\+õ;ŽÑ®Bs…ÈþöÕ¦ÙG•..vè»6ˆ_RÙ]¿Åâž¹AÿNh¼ãšc A4Ì×Ùrí¼Ülwƒ ]ÇL`©xNªe–eé;ø»¯çnðœB622ݧ1‡n7ú½+n¶ôHàû:/øå%5†}ΜÐüÇ*cK[\µ)/0Zõ:Tx ×WÇ`G,96\=k°ß¼0 ô¸z{—Už I[ë‹p†¨`ûq … T¶dp½”z2¶º£H5³SÿæGPýŽÌ.\Œ¸p3àzW‘‡~Qh¥ÞNLè¾\‘YŸnÕ­^o…Œ)Èó”å~vûL·Îò‡*´Ž¦9u#ü=]KÝÅ7:l1ãž(oìÅc'ç1tB¨® ií<‹½n°ÖÚGT¼8 Z-á{#Ý_H7©2!j·´$PˆïBë*ÇÛ¿˜øÀ3¹ø Ûꦶ §Al(,8(ëC=»Òt(Ø‹®=8û~b¶ˆ†Ð¡~á§=\õvÉ' AG+‘¤¯Ûœ’Æ—߆%{R ;Òæ¯²íS~0²L…r”èã«3qû¹$¸^Ï„Ò4VÔRJ»Ã×¶J™~rë/×a«)G²:Vê„ ò ÛªzVm|Ç·ªnZCÆuP½5þjBoËþ•‰{º.u½HÐ8¦ýáÑ»BI¯ïöÁå¼9ö˻ò®ÔŸV9N‡-z(~ÎzÜ”œ¿‡eÌ?‹÷¯¸™Ø?ÎÝS“íHþÀi¹OB*jám<ÕœZ–[’‹và™±lcxf‹hâ&^2$w +ÎÒOVYrX¢ïàwJŒSôm‡¯)&`WfXñï³’Ò‚‰oRâ­‘cƒ'ò­–c^ÎlïŽOF–õ×Ùgäëf>MÅ·+(çÑ£ø½fM•ÝiïJÍ+lÉÎ$›©ØÈ§i‹ Kº¢»»þYÆa´á+“Ðã)ÕÕ;{¶ +{郎£¼Ã/ô‰ï-˨–ÞëijNg°ÐMë"@þ0ƒ[ ®xžd/mý€p @{ m·bÊ3ö£±™W€¯>š‰øç_ìŒïyž"ÿÜßXvܺ†FŽ• -+›5Æô™6ì{ˆñéŽzÔOBz>1%Α}}mBl*î Èà+’?îÍ6 ±3™þ™^\É;<·ør ø»(YËV¼5,{n½@Ø`2Ÿ<Þ#‡æé6~p/Ø t+—¢44bOT§UŸPʲÁ%Ï™Ý×êmŠ¿¶kš¹ÒÍ»¿^Q6R|Vœ=¡ÒÝ03ÉX­®/Õ¨îmˆÔ-gNGŒT=(k÷m‘mÏòæôB"VžŽ”õhs>ƒ²ß€ ¦|–¼,–¹g,Tà³wÐ Dt:‚vmœ¿[ñ²ìþ‰hï:©AãÓ>ȼK}êPJL¶¦¥;“_ªÞ!Ëѯô¢ßn³1VÕöe¬W¿FèÇHKi(ã%WQŒK>÷K ÜDV¾ˆšƒ(•‡õ-¡•¡¯Ô¼a†¸$E@Q‡¼Â(‹gÏ#'%‹¸\¡íͷ¡P‰Õs÷úëC¶•Rä,wœ©¹äÔº1¶wЕ@®ñút„À—ª|­écho>àW{ÿ»Ì6+(RÝÇ ]\Ä2ÖZ!M; Ly–whÊDDëÊ¿£êDœâŸ€ylÊð–Syûwzcc”S©Ä’QÄÍ&Ó(füaÍ+uà³þ{ýîTÄ3[ÜaÔ +^Á?g½Ç[eœ[T.¸;8Ëñ1S¢ÒŠs¹£ìãíÃ.õy‡¸MnÕ\v¡.Tü©Ä%ñõdaÑÉ•%úh¡æÍ".‰„%{O÷0+íøHæ¢D!‹fäYvç׺X¿R+b-ݰM&ã\ †Úç¾5 +7³”rÁ©£håIËC3L—ÏÝ| á`õ|,bÂd¨VŸŠFsbðdQãØ*Y„ÒË×Úó2ξäÑø~Ð@HÿtyYÓ%ô@웸xœ×­j)œL‘S b(€hãûÜs ­âMß?j«%ÔpVjÖD²Þ}Ä ož)?·ŽLH{ï"£ñgð>ž¢^¤?¼#™G¶|gF˜5¹ÒoPûæ*Ï›:åC²fn°±\ÜEÞ'µ1[™Ðý-î…ƒ€ª^J€•†h$>rþ]™4Q¶â@/;¸€’ÅJRlºl,HŠœi¢~Æ»ü›ŸïÁeé^v×eatÀ cI~ž¿o=•¦œ÷²U?¦¢)‚QÃ-Ò…{ˆbú'2)Û™”²ÿóe6Å ²›6©U5Ã;ßðþ4(é@ñ㬃´nž­ÂøZáNÐp»‘$!¢ã½e“JŽV-õ¬·xØ«ôz-o¾óá@%³hL 21F+—t"±£ŽÚ1N eá!q…cÉM¬¹J÷AÝ}²m‘”Ðn.~,r%UŸtg€|d4N[¯]rÖUöì!—q4Ì™§M†éýx¼¼°z4ÉÜVzv‚5+=rCMõÂ}@Þrþ‚ó!bàS_ä6ýŸ—µÆw¬‰«+FE€ô¼f‰ðPµNªéö~yÚ½VƒL½Ä«ÅcÈòæqA‘ ‹$‹@BÊñ0oþ<ÓörÖq@‹¼Ìj=ù†Øz­X©Ö»à⣣ÙVæTâYMi£ÒÓK¨×l´—í‹§¡{¥»¬ëe˜R™ÏJñ­j}Ú§ÝoìU¿ë à{™ä–\©†õ6Ü:ƒ·¬ct5I/« €,¸Eð=÷ Â8i¢+~[‰2ðL~¿%˽ΨEdµÄ3C}®éX…VÇÝ?àëV!CŽä‚à`D2Òé4Û%‘çÖ9¿×õH„)¥ð„ÁúO”P7tt1iU~½&=I¾òèÏF}=шû\XUêÅá[&¹î3=ûІž2¦8мá"GĘ›À[pClC½ÆXÊÉÍÿQi¶Qk bºmj‹df$Àw =õ´åƒ‡”]·¨¼þÑØŸKƒ©ÄøÄ[¨žúÝðq*ø!y›%Å…øØLÏ?×-+Ù‚õ´RGÒX I†ÿI±`dìÚhZN¹Í"VÛ‡ûô2_®ËâÈ«Rßó!«r +2¯å²vƒêõj:¨¿Q<¯%C/õ±c“I+úI~ŠøwØc`µÝµýƒ§¡þޤûJâ˜ô ]8 SÆ/¸÷E.ƒa©4Íî¢gb‹òéž7î;‹f"pçìÏðB]u±¿‘ßó‡èãb·4îžiÀ[.þB&Òva­¬7*l?TГ„ræÝÜnàœ`á'r¬Ó¦Ló1&9¿å8ƒÓG§~p…QxcÃÒ=´Z‘ðޱÄ5䇨×n™ù VbY§©àùÏ"§Ñœ}úþZ–§75’¿@-[Ë›œ1=u˜Oÿa"&¦u¶|Êê;ÏõåÅÆŸ'?Hl4ëE\³Üà#ï<Æ— +¹`†\ÿ¥¨ª1¡Õ–£ªø«¤\Å'GË'²RSƒbzûÀ…´ãé‘!©¼?ôdFÕ±EÜ%üÝtk'õð‹äpNA‹Ûº†‘ã«óµýñÙyõ)¶'Þ¸$—( ºI‰fÞê¢*) +£ÖöQðŠ,$ªõ@˜Ôáö%Õóø*(lŒl>9h¼à˜áxJ¹öÅþãn ˆï§šxíWE¦º²Úa2”b÷^+BBF¶-c¬>À‡ ïç ›Ô„üR¸²ý³áìKE±®èÕ'¥Åq5/ÃÊÛËÑ»ï-ï'{+Z‚"Ìô”{9…Öñ›‰ò¥YnY’8ùUú³­^dËÈæõqàÝÝÚJÌ7C)[yðîñïÆ^3>@–cÉã1ùéóRŒ€Í}hH˸À ÒlÛu…ûÎ÷e]“$;eÑFøUo¡â_õ÷[±S}•ùÉ%=4qEãå.\ïÚ4ãòoðá#;íC•ßw®îÊñáq–Ó ’òS„Uóë$׈ÉÌ‚Ëç«0Ã&q¾å¤üPàÄ´ø´€D g+m„• OÑ v÷ù#¹r”üœ¿yÁ(›‚9MÌ ¶1;–/ņ޺úàËÓ=’8s(ÀÐgŽúá„©¨­¦ +NaãLïñ˾œ[{Uy<-Þ€-§Žà@÷ÎG{|Ñâ'ú*&MËDß×°‚ÚKÆí¹W!¡ÏN¤µ‘ÖÅe<Ò}øÖÐÇÞfnÑ»…³µêmºŽ5Y ’8&€ù³js¬†]ea^å(Þ¦14üŒ`pË{B/{ã“ÜŘÊgþ6<ÔÆGE§Iwuy³¯<¡= 7…ýÉ̸¶ä3…}€ÉüR4{Ò^ø<zN‚‚!y™ÃÛíÃáxVRο0,¹V‡}’Op7A7!ÐTÑQP˜ùT™ÜÞl,P½ÙTE™>>™åݰ^ûþR›„»¸8'n¤-ìJk®²QC + ¦Ô"ZñwOòï™»ÏöP÷ê¨.ÐJî~&Ö>zm^B¦[s°'òYøš×Y­D˜¾ +¨ÿKuß!å"|ÐÙEÆVÌð}†ô¡¿ O'®ÖÎþ€å&-¸ùhì8ö²0ËüÀëèæy€ôõ«`o­$‡Rš´y?…|¨ç>K/µ^¸°«l/J¿í§öÙÄ¿Ñ׶ݶëÒ“<‰âïŒçî*O©ÍTK?5;º(›o³ÇUJN¤P3 +øÍæ6?ÅÖ%X<²˜6˜ü” èýÇÓ·55ιbÏ(L853ïáˆÕë¡›íÐêº/ÂÐ7q‹^¿_5 +r•ŽQ¾¹42"ÒQyܽ…8[E~*ï\ºÊYòÃå«&R½n<NÁŽ¨ÎŒóöÀ8mÈpf0 <«±Ìœ/Fµ{ —·î9ýöÝ„PœÒÄ@cÅÿ4¦; ™«×”¯ü¨K­ À$çdLÎð©»$?ÊCîYÇF¢á‰á&Ø,ØÏ<Ú#@Ë%® ]g‰hƦÌäÒ†F`{&(]ž·/iÇÕÜ\p±"Ëbö>¸M¸  ý¡$úu}ÞÕ*äW˹ÑwçQ +®ŽW_hi+yñ¸âÅ‹…† +ë‰f m…ÚÐJï¬ùÏ¥‹û ´¤ešÌiûFt& ß–³´Ó²ë“´›>Y`™å³{ëéÄ2 û“°dõ>sf gz s‘žI Ï¡¡Æá÷”êK“VeùÞÉÄ;NIN² -ÅêàÒ[xŽø?‹¬ !¼Ž”xí°åJ¦v> endobj -1015 0 obj << +1025 0 obj << /Ascent 625 /CapHeight 557 /Descent -147 -/FontName /TMDQVH+NimbusMonL-ReguObli +/FontName /SVLVEN+NimbusMonL-ReguObli /ItalicAngle -12 /StemV 43 /XHeight 426 /FontBBox [-61 -237 774 811] /Flags 4 /CharSet (/quotedbl/numbersign/parenleft/parenright/plus/hyphen/period/four/six/colon/B/C/D/F/I/N/O/R/T/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z) -/FontFile 1016 0 R +/FontFile 1026 0 R >> endobj -2100 0 obj +2130 0 obj [600 600 0 0 0 0 600 600 0 600 0 600 600 0 0 0 0 0 600 0 600 0 0 0 600 0 0 0 0 0 0 0 600 600 600 0 600 0 0 600 0 0 0 0 600 600 0 0 600 0 600 0 0 0 0 0 0 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] endobj -939 0 obj << +949 0 obj << /Length1 1606 /Length2 17112 /Length3 532 @@ -9808,104 +9968,107 @@ xÚ¬ .†ÖF #['*€©#ÀúßÀÈÎÖØâŸÒœèÿb 9 Nö&F™¸™Øÿc¢Ø›8ÚX89ýýX8Ì lÿöÀÙ`akdíbüOõ¦vÿJÈÞÑÍ_Û_0;'g'#G {gÀߨ ¢bÿÎÓÙÜÀùŸØNÍ;Ó¿žÆvF.ÿ”ô/Û_˜¿Vg ['€³‰»ó?± MÆNöÖcÿ³w´øW.N¶fÿ•-ÀÑÄÌÀÑØÚÄÉé/Ì_ìºó_uþ·ê ìí­=þuÚî_^ÿ+ g'kSz&æ¿1œÿÆ6³°…aøgP$mMíLŒÿÖ»ØÿO›«‰ã¿DùÏÌPýMÂÀØÎÖÚ`lb à gçü7$€òÿŽeúÿ>’ÿ(þo!ø¿…Þÿ7rÿ“£ÿíÿ¿Þçÿ„s±¶–3°ù;ÿ^0€¿Æ øgÇüÿ| l,¬=þÞÿé¨fòï ÿO ’ÎÛ dkö— -FzÆ+-œÄ,ÜMŒ,œÌ¦Ö{ô/½Š­±‰£µ…­É_.ÿÕF#ãØ”Í-Œ¬lÿi:Û¿M&¶Æÿ™ù_zþ•7ƒªšœœˆ<ÍnÓy)üeÝYÙÃþobÿ£Y;ãÿ%üƒ!,lçð¢ceÐ1spØ9™œL>ÿ‡hÿ‚aú/YÖÀÙÑ õ·dF¦þ?¾ÿ’tþ懭‘ñ?S¢äl`küw°þ—ⳑ‹£ã_>ÿu×ÿü?帉‰»‰ÌÚ²O°eú¯ ç:ÌÜ‘IQ­>&БûÒFå¢ÿ»^¿ôð]®JýÏÚú¦iîïv¥sû¯C)꣱> kŠÞT“ë|<ªþä-òNš£@ÝRøŒ µh¯›E™0MvFÕ£½IÅŸº%ŸøÓ,ŽP7/Tþ$®þh¤Ïö¾Fi qè]HM@(u…çäI§/ÏC¿GG†{ïÀûqirâ Éx\ÁàÉ£ürp4U*½"¨—Ž3Ç'­1/ÍzG$91Ø7™Ây¶*GÜ|®1ïOåñ•`GíGˆ\.­=û“æúüq†;÷šLÉ»‰î«;¿ÐÄ“n\¤ÎõðÖYNùÜóÒ1àL—ëFb$]#b²ûób€aOžcxwK÷ ‘„%&B™‚ºo"ä¾²’UÏìU(­Ñdù?ç ‘îj\I‘näQÒ÷í9~5\ýYsÈ 4Õ;¯>ꪅª®c`r *§Ž¾í1I>T -Ð÷ª-KCºæì¢]•ß@e›‡á±Í R©e7ãÝ8æ¥X¼Ý ú^¯bª¿fiWã¦Ç6hé("ôæ?ü…$ØVS̓÷â¹-Àõæ}DJš2½œœ$~T’D™ˆ‡…:Nq®ó#5ßì" 󧈼ˆÎQჶL–­Èµðc“ÊçØ‰/WöýîŸX2ŸÈÈðxª©-“[¿F7žsWÆ{4B -pÇ€úâLV›‰¨ÛE°¼õ`K«Vá½Öž\ºÍªk:K?>1ÁÆy9ãd™5 @P2ƒ÷Ͱ]öþ6Í(9Ð`®¦ ~ Ì¢ß +¹9y´Æ¢]’ˆåþJ¿*ú¨ gÒöK“]?e’CÌ(m -D\ïN¤Ô´|˜Ǧ¡‹Uf¥—øŒÉïÀúÒáè -ûÙ £)¨Ž&‹"º–Qª86Æ…‡â9xV6jƒxlˆÊù†º’2–^ù -|Ò Ä;c g¯lt_´û•jP°– ¼ãT³mê=-ŽÙ - ËÖ /¨é?&§ Ã­¤oø -%Ñ]µÃ³V‹Éµ‡†#hižrX£2¾K±²Å?²©Ç‹t3V<«×üHl'}µ“œ7ÂnhJê¶ŒbuKÉ)O^Œ Z5‰OßöÚÖ?ý<ÿs88z™l­; %ÔVæ ËŒõ”ððßEôÌH«íjÚ ~öÖ´Öb}ë­MùñÍê+GÝq’Yµ£[N¢+C1¸Ë¯öýµgî;ƒBµÖcæ4vP“"d×sžåxñ^ÚÁ9O^jŒŸ»e: £$‰µåf~)Z–Tz=a“2¨ÕæSÐÞ»V›áçp"êcýK¹Wåã»/Íx=‹ -RÚ8Ýw>SÓ¯S®A˜Ç©ó-×;%¾À˜úeiH—faP$÷Då€ãCã&¢A†C ѾB&eQ/MN¯µÊQg¿NÊèÑ8o©­?²ËˆR(iæŽO¿Œz‹~€èßöذŸŸÊ€ù#!Î4uðÏU¤ KqŸV!rÉœt„Èä´n"/«åâPH<8±Ìà%!*áÂÇbhO‰†o‹›Cd¨· †Q>ÎN{©’ÑòíÀkÕÍ=ý.8}"Æî™Ux§ñ~Ê©jG¤SY¹Ÿc[kÑ‘pœr)h‹xŽ7ó—Š›Æ]BöTx¿0¬ÝcàÏ}0p²¢A17y,óUø‚‚¢·…ø¿K,ZS¥VÇìóK—Àd=ˆúÓ‡j €Ÿ;¢’Ÿ×¡ôã+J‘RPl3ï˜ùÆïy4¬Ôx_½´oõƒŠHÅÔ·vS_ü AåÒg˜Î_Ý„õ’~w?@’4ýQîï(á"[Eq¬ã si5׳¬ÄÈ—D|ÌŸ|çå¸K¬m@e½)ÿø’– -ß$TAÂrü—ÇDUËx,¬mCFË„vh”V¬èæÝod%·Ýͼc‹ò¡R´©kð97Aa¸ö<ër Ñ¿5{ßîRÖÀª—Öì6 °¿ÒÅŽð.Îe“ž¿|€³ÉŒÎ¤Àa;ó›c ø1憀^Ñå݈2ð#"ÎúÎøYkK?¤ãž4rIt\IIÛaë°†;ÒD™øÃW=ü÷œ÷YÅ+˜©rM‘!ˆÑ'ëâ§λ‡Þl è‡ÕŽ¿MZaÆ©wO/ˆ¤ÿä‘¿<y±Ç-û"å{a«Øçé¹WÑs<¨ðÀ%ìÝH(*ævØÃíý¢_õ¦fŽÏZ5X¥¥6­›Þj<ßó±/¹ç*£ÅJÏ“o“¾™ˆÒ¼¬¡µ6"£Í·@¼çÂKtÛF3c‰¬#«;¾HõOR¹éGA½qW/}gTHLЇÖ-'¾ŸÔkí2„}ÆÅ6ðû {î56Ë!l<À-€èÇUq;=t}ÃY)¬8Ýø3yìáœ9oÙìF€s#MSþ‘»Ží®@§$Ùýû(§îºÑ¶±ý¯ë È>loD‚K{à[ì1_s©–¤ ÑLâ”Z|µÙÿ‡L§/:OMz}ÈÔïKHï~-ð_Åt¦¶Ÿ ë­‹­åÁüW“Ý$ýAƘ¹ß3¯œl×âr,ëâ€y¥&0•²jmÚqý[„ìÑL6Qb~´+¹PÄ-sÙø¿µ$ÈÑ*ªï ¥ ðÈOÓ…¦JûèY[éýSækŒ¹©[üm}ÿ˜Ð6L÷èO³[²ò½¼ƒëÆÐNOp:„ùHïä7CĬ“ü]½yî´¶ïïÃ>Õ“·aý'×M½®qê äîbà_w– ž]4ðÚÀˆ²öÒøÞó¬n +: § Ìô 8û›cÑJR[2£mXÅw‹}y7ˆ×ÅLeD$ç,?Yh{³ÛÆBÅΙki¿ŽøÐš¿ Ø1ò°ºŸ;eó‚T›n|˜)94µ9uæÐ¥x´ ƒã½R ->ç³]æoM%„£¬ÎG)³‘4°ký‡ïbZ~ø ¼`_[hã»8ë<¾4²}$.îÁ³ÖÄ‚(¥ªæu†&ÿaÜÀ™y£Û2¤³‹Ô»¹T+ªJÀҙçÍÁØØJJ,šëò¾v\TP‚Êü´iÚõ pÃsùâäFáã!ÌnT)^”"²À±R'ºƒÀ q)J‡4`¿s]¼ÉZGâï”œÒ Òœƒ(BÖqˆú(““v&ø­3UÏ‚Bþñè› ™Œb‹Zˆüù Ir2Ÿվ ¾îÄ›7ïX)c¼5&•‚OϺ÷•—2nµÏÄGýÓ¯?74¥Ü׳ ޲ŭTj(–Eãs‹ &‰Rð³ÐѵL‘ˆÁ3²pæuy6©Ì7k‰¨‘}¤TêÄoÊ"´wÂñls ò­Eâë2¦'jQ®,ßéàHˆ]í„äÛct? ÁÕÑÊ,Ga³ýý¥­Ý2^¤d0•NUx¤$"e`à%~7*ýþ¬ØæŒ­©Ÿˆ{cÃl³?hZFCH7U£*´Ü‹Ç‚Ìy|±°8ô.šÎXAÐufóË ".Ä-_Z “MÄâë뙤—¡¹Â‡Ý÷í[áÉ\DZQR÷¡ x“à¼K)Ý)‚pÊåDÃ’«¼m“­HÁ• <¨üˆ´Ÿ_Ä1ÉðkH/·)(_|ýû2ª,B³i‡Ðñ4V®ÌCøY¹5õB2Ey»…yö47£h¬Bù\=m‡r94ÚOäjùãwiºð_w ÎvMíð¬òüò[°4ê©—Tÿ³š™\Ó¯r»N1†c-8!âΤұtzžK,בZÅ5…ÍCÅg€„ »öˆÍÐJÎÑ=–|üËÊ,u‘,Yƒغù‹ÑîÇôBÞ¬ƒé\¦SM„ L¿ÐÛºp`i5U])ÖìUæt™PÚŸhlA¨6`¦ãqµ"~g2è2êþ6d`{#Cn³W!Ïw¦I¼Lwdk J)ýK‡"™¬ô&¶ºV0ÀfÓ¡?þr83)J‚$È4?$ àE•´Åì²›¯:Ÿ -Œ(iýŽà-º 7~õSLcüýkÅ!.0Yü:7— `hPêoˆÜä¦ójÂlƒG¥v‚j»8Ç«Á¨›ÕäÅÆ6nÂN'éú3ÑX®ÐH¨Ïü%›zl½ ýƒ©´T~Ú}ÂwlzŒ(D:ooV¯Ãúe@Xrݪ#ç‡ d4C:«G‚nxŠôÒ¤Xç©þƒê¢dÑ^øÎg’´k½›Ú}Áîí{åÅÄõW·F°;ª¬ë§Â×òh`7d H—”µNº’7G«5–-™¥Ïà 1‹†d ®\É(¸¬®&Á€%þg› R¤q[â’ÖÀ.Ê¡\ÔýÔG&ùƒÔä1Gô!ríØŽHÀÊÏôØD¾!eeÈ2¯ª ­òûôÅ![é@8Í1J©áRJËÁE·¤]wú³{D1Â_¤ Ó¿’²\ýz¯ö §D‚ßìñ¯Ìd$!ÉÝ–#/û$ÅVrþlAŒÕ„ž­·:@¬RÏhV‡ƒTW÷ði¼&ßVQžb‘¦°$Í?^ªøŠJj ¹vQÕ±:³´FRƒK«}ÏGL©ôÐ÷±ûûAÜ8€)dä±”Z®N¨æîuQÕw_ ºLã®páý±•¯ŽÄ—¢9Qök¼`EËih[úª•³Á5?M”õÝãõû ØÃ)’'¸Q·*ó4yΊìðüC[I&«Ýrx”/Ø`x0…oÝûsËÙsïsìêƒø—弫Œ诗´% \˜Ò„-qBÏÐá¹ †^ n u^CE ’¡ù‰ÝĶAµXþ¤@á¼ömÿÒ’JÀf)Ë‹MÞÈRÁëVSi•#w6VBÐù£®QŒßk¨£1#ð9‚ïq?ô¥VAØAÿו° ¶ì.Ü5.óQøw¿­'zÁ7°…#|ÝX#c½r"ëòUt™îÖÔRìáϳ—åd—ã0Â{)ÒuŒÉô˜t’’•û6°Aêõvƒz»§ö»`~LÑ%óÌ·«š™,"QW½^CDDûa.˜ª¨ƒµ ÜöBŒvUÛaÀvæƒ~ç÷%ƒ#™D@¬Êž±H •e—„7tà›¹¬6–O_pãÊÑŸÀ)ÏÐ÷#lžtñôË.jLt•¤ÍÊv)nè>¡á˜T‚nü%´öª•K]^sõ'lÙ²k2]¿÷þ5#Ä®j@o^'Å|³ÂÎp?èÅyIß»7ç ¶ÞJ\pA·F¾#Û÷jYó\a@D‚Y>›‘Sa? -)‡¿ ÕÖÏéÛNÄD]*¾ÔŸæ›õ· ­‡.kÙõ£a ü:ræ\e·ûá&ÈÉDŽ¿Œ™%_$$3}9šü• Š8$½¬€È¢þàÎg×™„¿ZuÎÚ8רË=~³a#›L]gŽyiðÎ+.ÐÇå‹6{™jšSksÀ›ø¥qéD¾ ~Èͯõ{Ó·Æm'¤v;?«A%qÐ7ú"úpM°!(ïx[„Ô]Ä,…u‹0~‘—Ý›°ùot…ÿ‘vm¸oŸÓÔ/˜àyÝSÝñ}Ó"‡ÍÿImñ@üñ¥Çýawú™¿9Zôèý öI„÷,`¯ImJ /¿!UÕ†[ƒÒni$%µÖwjÂíÏ÷•y†’Úª? ü¸Ôî¿¥8«?—ÇÍá4êµq5‡g7¶}E¹l“lRŒg{ ©Ò2±°Ÿ. nÇL^ªJéˆYç¹¾‡(Š©?fÔ2ciÛŒ<¦É¥¼""—@ƒ Èí•Ú!kŽ 5+V=ÑÅQA+žß͸ÒË;vƒô% ÎFº+s*)¼Xs9NÛß™üÑ¥˜L¦ºÿ[YÛyt¼ÿ²ô„ xÚ:tés®` [Öx³(³û¥šrvrÓ vÝW+—ºù.myÙï=Ÿ†Ì†Q54ÕxÑîÊa•Ÿ‚T`ò—`È „^3¥>5¥UºaÝH‚c™'x‚.löÓ°g™~»uFˆÄÈ8ˆò€ b ÿ.¸%Û »ðPâ*¡L;.w_÷<Ê/¸‚óŸ‡o£ ov£~8ù8‘ïV¶qãf -åÚ`qÈoa’:Üà}ÒË’àóI¡ Å¡H±`í ¾‹¢R¯u²Í3}›’«˜Œ(-ž ŒßDÇîwëôêé‚t­»Ìt«Ã¯W¹4#UâRwXPƯY“4ìg·FRß vßû<ÔxP>†uÂËe&+W-\O+NcÓÈ«¦ˆdÉÊç°Ÿuµ‚^¸Îö%oH¦£¾]ü¨G,ïjçís”'Ù#~3’âø‘JÝ’J¯E«N²A»‘_l ØÙ1U¶c3  ˆ¾G»m+–¦VÙû©|¬-íÛ`»õ¿lf³$Ú«ôŒóÌžÕÅ›±Ëšûvy7ÅtU¯Z¥lÂÙñÏ,¿ Nªä@Ëäþ‡¼%NRs¦P†[¼‰P?ß”ÛI¤eo Õ wö¹¥@´!è&/Ä8Ù×öÐŒëÝñ‡þî…l<œ%š.Ò™{A•£@lŸA µÆ? wR,»SQ,H›ÀuQÚå¯>¡UAﻵÔ/£²­™Ï&/Ö…JVíù9@(üˆõ›œÏt\ F;éœt­Ha|þ­ZÇ)Ýb®4¶H„¸îbtÜ©. -Dì2Çüߢ¿¢‚IÔnèEYÒÒÇe)ü²:V ùUš>иɚúq:…mɲ¶þUñNžY±B§Ýêƒ&³Ã¼]Rý*ÃŽûý=*n…ѽKv„hf0ó;!ØÅ .&f«RÚ„ Ï‹ë&e¤ãe}|“x$Ó½ââ;£kgž=çyÅg©Þ+a…¶’û.Î)†Ú`NËiߜʼnW«Uäç*i¼/W 6æø>±§“ t6ó –p2/ÉõÚzî„øÑ=h>±` -n5TÁšëÑ”’ÐX"GEÉ.4–ú&µ¼ ØØ…'Àú|€PÜLêar ¾0N1fo÷í¼Á¶Uå" ‹*0âù$]s¨>ÓΆ”'â¾ÞÑØèÝf6qì©)¡}mZ€šÍûIÄN§ -Îþ@PD # V{¿Ö%þVõ|3ùÈ”JE3)&Níð{_’ Ê m3™Î1 oåñ S“•/bì~O«¸8/*™Œ²éëíZφä(.Pÿ§žÏdÔö¤¾X<é§îrî9YJÛ)Eæаz6Ø/v0 ¡ ªD °¾T㹋˜€7ýP“Ú¡ûµ¿^¶û°iDØF…ṳ̈9Ô\ðØDˆ“Ï%Ë;¥Ø—qëŒà2ß œNý.¶8bWÉI0Uy®ƒÎÈfPw³‘ Õ8ŒÌ" Çsäs -ZmØFÐÃʶÞïPhzI÷™ð€*qaBrÒ·Ø^ðƒMâÝàí-Õ¨ô¡À˜å®™ÂÞžÑÉö>u¼ ‰ŠÏãonŒ{óæâ<ŠéU¿˜f);›Íp±OË,¾†ª™ŸÔL~‡(ÂJšWQû¨ -`þ* ÎŒÔÀh0±ì$(]J+?!uR[LGÓOÁ ->DGÓyØ}—(l ø &‰åSß}fÄ †ù©»7«ôÖÞ •ŸÑ;!)îüP_©cEìì_Ï“Á’TYj¥àê§ïS({ çÑd -± éÇ¥µ¨ÿ‹0Ò±«ö¡`¢/³I Ph¦€ZhtDįcÅxBkô¹õ¾z힢Uˆ1áû-C^­î@\’ž¶Ê#f„†µ]òOÍÕ5 Ñôh‚˜CGÚc(hƼ<@žðŒe/ºˆ¾]úyèŸãgT —–B„W‹:ƒÅ‹"p+EŒŒûE|ë7p<*6~¾R—”{N f.]Æ&‡•è…MÀNsr'=d/UMzW¿¨8ûÎ=ªŽ´n¸ÚvDôÓM=×ArY8sœ‹ªf(ú²"’å®êvj×;¥ôŠË7/“æÖö¹]Ë\Ù”7Ùë•azgòá¶gÌ)RàÞ%H}!³¡i°Re<Ñ 7¡%ý¿¹a¢d:£gteµIˆ­¨*’ -‡–oü‘éO' °xd"뙂T¯·3z ^‡ø~LËÿ¡IÖBcP/giй.^ÿâ×úÔ¡/jƒX©ÛQÕ ­€ÒÆ-Ô¦4Ê{Ù·hïgZ¼'ªF§ó.²$2ÈÙB Æúž07êÅÌJFØ “|Àmv®å·Ìù´"Ëæn0jª8xB¯QÎïïˆþ”âÞþÐßÙ«À|˜­jiu›¡lQæ5ý%ßzÅŒãÎv¥ú…>GïÀ•Nv.óY‹=Šð ðô"¦k ¿E)û›™,$i{;vÓSë œ†œSW¿BPPúËj…+ýá{ÛÏáûg¬ššLœ/ -¹,6:üâƒ^ÔX'€å9U¿œ‹fkM6¼¿tî˜è^‚(Ò2g¡I›yÕ²˜RôÓ(.ãcÃÿBM¶SaÓv¨‚/uø¹!&jìdR¥ *ÿ!´BSJ‡ã !DË¢FT=B–žýÏm+›ä’…0Ñ¢­½ãmëIÆ}ÈATZS¾Ø ûú=óÀrèƒ!÷v§} ‚ü |8âìñ,¼ - ’¦ž~o8LÃć4»DÜ϶ÒlÊô‰'´:Y'ϵ:X–¹ȃKKÖr97…ü dé2 -{¡„Fuœ·3žÍÇoÕ‹Ü2C7§jy¸-Í@Šæ,dL//¢„Kàô̰FYîÊ„³Ýþ9Å™êVþ©\ªGôZמL6ú3‹:—g›:‹¡RB£–†‘ž/Îç»v­KH©—Ôï[¾­mÁò¥®S%{ D4ÌuBÞ…ø,&ñ~‰‚F?Âì–\WöÉ¡r€ägµUê—ÚqqÜ6Mgy0#Ï•`¯Ô&Â~Œ[¢é°ŒnÒ#u"%`£–ŠžÏr­çgäeùÝy£ç#HZ@#‰F•Xý”ÚèíTÃl’Ä’2”XÇQ[ľN1’ÔD͸©ØÎbÜÙ{òdEÿÍžó¦˜ßTŸß¯£Y4v̪ߔcƒ>´ã¦´ŸÆ½;åø³U>.Y'²–¹.NŸöLM-©Í•åÂ߈¾x6·w\uÂTõ *ÁtÛ©X„ø6‡{AFi íDñËèŒ}âýì¬pK?N2%-MK2{%¾,æ)ÝPÍh5WtK¼˜/ä%‹(ü¦„¶â VÝ?Èþ¾uôÎEšwž]“¨Jb $Ùd+¦_wZ+MVÇ3”Fíh¹ÝG{>ôº0 ¬{ðÀ“ [^Ž O0~öãÊô`1õYû -*–÷oz ×PýÚúŽÇä–G”30¢ ò ¡€?Žê)^¿)’£Êw8:B-sìFDò±û¹Õ.¯ýaËmwñ¶ÀBUôz8sš3&¥JÎ|ñ$¡9ê -¿’ƒ½[žBš´¾™Kåd H*ž±yÈ"ýƒß ýzêXê>ªµÌWÕŽ“Ѥi$&N“yu°BIsŒŒÓoLª¸IòD·»ñŸ’ÆãÇ•ÑlèE)÷—¡OŠÌ:˜¶O-h/_cÂ:u* ý ‚(ÖÛõî9ç}y}F)ß×]>9]¾¬šæù%†­Ž8[pµŠ Úˆììˆ4eAäÙoÀÄÜ# Ò¹äY¼I©[ˆˆu÷Ìp•)ÁæDÚøõ l¡ù})¼ºjoÌa %h1•l­õíP”Eöd¡‹#ò!Œí±Y‡q4NaB¢#@÷3ÁÜ´*ìåFÖ‡ù–[>¼üózëþ2‰ØMÌDn…Þ ÜwKØ¢Y(i£X‹ßüƒd¤ú9ò ¯L,ÿì“^^ñëàö­ÂóY%)µ4ÙZ\ÔötôÕW¯ù­i ¢7,qK“ñâ”-Ç?ÑúE@•àë#¼‰&+ƒÄ0¸Ø¡¸04ºœ5Ö–›ÿë“WåÔ/¶fLƉèß‹›¥0³Å¡u±yذÐu:¯Û{®[’ĸ2Ï}’ cu¶Þ÷²' )¦Z`‡`\… c¬—ÖÙ±{OÑØD°Çré ám;€¸LÐl} JÜ„Ž6 ‘nþ‹‚>°§nºxŽPc=‰6pÊè)L[‡+»†%ª}'¿P°aŽ‘45¨lG½>(ÅûE&-#Èkií·jEüÅ×Ö "ŸûmUó˜SvL „„§=ªA2Ÿ¶_5J¶Ôø¿ÒU‹‡_O·V°mîl= -æ7ÒÁÒq3‚`¦ t.Ó„c‰Nä•×wíÝZKGº¦Ô›.(ðÔà^æÕ—w[.,ÕZåŒ -cGM}!;4šÍCnœ®2'ÖÊïìù®? Œå¯@9ÖË'Ñ®æp]CÖ-C¼Dû]QPÓ-}yhÎëzqã©Ýcô‚®ËÚ+›ß™A;tocšn’Éæ¤-O‹ÛÃWÓ•ºžÛóÛž:]‚é#Â_fbȰg‘øÌÇ õPŠ€Ú†ÑPÅŽO£ªõdU “ï6dÍpŒ‹bçÆ©\¦©Þ÷Œ­;£&{"ÿÚé,–ŒO_»ÔÇÐ9V¼47M=ÍaÍ]:mÎïGAã›P.4”ªþ3€ãd—&•É–è*HfÅ„÷‚¼M:ÞÌk(g -4–·öÈZýjH sóG··»èV üY).üjcPÌ¥’»nÞÝtïw¼RÓTÔBÇA4MÚgw†çsI2½¾C®æÀɳ/™CŸÈ<€µƒòðð½·J'“8.}äjðg$Y[ì3úØ“ü=¸ ŒdÇäRŸ\4˜Y^ ßZóÖãD`LŒ³8äûX‡¸xã-·òú:Õ]PUˆo3‚¡©q¢ÎÈí¯¸âçü%­F~Ÿd¡Ü17br'ÓP¯Ú.~ÈFôêg´ªš’í2\x%ÃE…§é[#ùÍ[8‘çðÞÞª'Õª{±ôV2ZâvWùS×ve?sL¾d5׬¨sôßaJý.–óÌê0Í›øñ(#­FÎv}MD"]˜2?µfÕ_kÜ͇±MÞí'–‘nÇ[ gÞi×ê¨SÖ—¬€ðp:ªÌð/šEù3/ùkÑÍ Û1Æ•U -ŠéÑ:kÅÖ ›r}’õéŽVbbérªïHÎ7Õã³ßêí¥‹_©¼“×2[ëAõ°çô­JCRz!»‘<ùq3mÔ¢W[M0hÒ VÊíaL¦3zb¥ÿÐCNãú?O“lVŠšßÍÒ4Øë>Rj•·•ÛéD[÷87ž9(ÎÔ ëR„Ç?Jáf±;V¬32Ýy‚¢ÈÚ«òßü2ž°é: ;QU–8Ííx„µt¾n -vÚÑKâåÅíÍÓ¿½Í~¬?×§S§ÎªôÉžµè6.¤K±“H?R‡yþnv8Âax9™:¯¼&ýµêo<çßb%ðórÿDí;Ú%§1M–UΗUÈÁXÒ6G«NJ"€Ùíì£â%Àì”w¶ðtý—_7×¾`!—ø§‰×o>v²|îÁÈç™±ÈBu:ºXXv9’nn*Ç÷ÝŽ#*%)½—-“u¸3ôž¶ú¯?N ` -;ÜÆŠF¸*Cb&Znf]C¡ÈN‹×6Á.þÂÑ, èW91£ðà«iK;m+úbTèSpïGsÊuÊkÏ&ALH^Ö™FV{ð$ ÝkúÝMbxáñå6ÿa˜ƒØÅYå›a¹5°þ¦J0Ëšëö“©¾é™ý¡ -Ó†©"S—Ïz_¥¬Sþ@Î lÀ£ì†D/®¨÷þ¹B­c0ˆb( º -ƒËsˆŸ.ÍÏxP£þþ\ næèJµõN*·ƒ7A—^…¯f£èïnò˜Øc#ï|<ÐŒ¹a=íÂèœL¹Çt}N9@œí2ò“º¬ð;ŒÔ’`Ÿš瘓gÛ–» “(kw“Hˆ«fz# ü«TU5aQW.;ì§øtÁTK!bñ6Û¨Ú±A2®Èü„è-£þ|âáŒMÍU5j2~áúˆ^]i‘åe-·¨^žÿWeoÙ~äèžÞÊ„×Cô®ïw= ý² {ì}Åï÷šNå)àÒ„½\Š*‹Jò|±WŽMí¡±Òøòo- kÈ“èZ±Õ6"Ù™þ\W7ϧGÂ}VÁc§Úª4ØXoM7ùwÂá›P«cþÕ’Ûl{lY B‰©Ù/šÌÝÖíü¾ì–­˜T¡ÁÜ?ï°êšš+‰¾Å’Ñs­êŠGô†äv5¶ÈÍÌ?ÈÖ§éBÄ<wsÕÆØµŸ×ŒD¦¤9 ߥKòã_Ý»›’«á`Ž]} ‰µñnÃáhDÜÀÂ\É&*NNk…¤û0œ†»™¥ ›ýÔº˜Å9}­Q}lêœDª0ŸœÛj2wü“¯µJ÷‹¡œéÃvµvz¬,Æ}úè"öìijƒŠyñý›·î ’±¼cæOˆq¸Ìpãd:3ö¬Õ¹$c¿_W#ò4ºÑ1¬ç¥†Á z,8ÚÈÕD-æ h•’ö5Cº ͧáƒ_%wÒªu¿ â#¤Ç”g!]7¾ô/BŒ]eh©IKôŠ2¦WTŸuÊÊŒk84æÍ¥0Ç‚AÞÈ;b•1b°mÍH;í>nôÏ¢ÖR /#NìqHºà0gÚ…>tí°§Vûa¶ ˜/æöŸñü |¥sçYà¨q³Ý,ÙŽÆ™(®” ¿œ^õÏ‚~¢­Ö>ʧÐÃwHv«;ø´þâÎMÌÿ$ìe ™´´_ÚژтX–KµÆZåÀËÎ)\uñ–Ã2îvKËý XåEÛÒ7ÉG’”¡":1£ëV G½°â”ÀÑ&–Ê(è1ó›Û9‡?³3˜FÛRâåGcM-,‘kÖ!í¯±òÎuÈþ7æ;r…½VÌ+r“l«á¢ü” ³˜¿4{k{#í"øKMaëb³y÷ý©ÐØ l/W^ïo<9[<˜W(§H‚I§,âkíŒ{·)G<«ªfÉÝqIbÙÈKá«J-p_¶×&,xÖú~Ã!C‘FŠ‘Aã”Vh0–à¼ùMeœ·È¾„B‰?MÓQNqXA÷žŒ#´wøÏ4æm¼ðS"u^5^á1vÛv"®3P£ÂîƒÃ Âù^Ú&5ÄùïzFƒ@PD‹oŽ+'.ë²Üãa9…@4uÝlXÃÇ1ߟ¡X3Žª‡µ?c(µNn¢--0žà1ò†´Ñžácó—W¬¼ˆÉâL¦â™w ·9 -Ú…W¨•fI•M@ï±–KÉ­7‹û)Cc¢ïS`…,8'Îl[stÂ<¡\nc«¡T&8Ñew‹¹ƒã'}'ÅrW÷ ŸMì7#X1nfœ÷ ~¸ŒÓ2Û*¡U§ %›ˆÁÇ:èDMÂ|Ò.Ž«ªˆàc:š®)IËü*ŠÎ¿žê³Â:rê2:Ò©iWLÁÎ=¢wßÎÙàì­J5 d'XZ;UïÑ[ˆÉô+j£"dgO5!nYÙÚõmÒ/‡`ÈÛZ¦  Ã9LcZp)©Ê›ÓQ$7ÐâänX튌X,ðO“˜£Òâ'ؾe6\0˜`À2ÊâL— ÁøÁbÂrQu -ºâreA5n!Ñ…êì]Œ¨ÁºØ»‚õOWìõHƒ:Ô…—‡uÀÏk2Q:ú†Édf¬š¢ µ‡$EÏÐï8f±æ™€âNØÔ@Gœ¹}\=ñõ°¨öˆ¨‹¼_W/nÀÄbÛíÿ¸¯ß0^8U¤>¾û=O?°g›¾U̧[aý;óþÓSX¦ä”gÚLÁ´·¹‹.võ@/Ò&ÿ”i:dÏk0G£u¨ð“rÏBž7gO‚w üúàü•–”À‰KY&j øœ7¼r 2–á°WNÎxëh“õÒ¿Í7§LŽ„×VC@]ÒÖóºÁ*óë-Å ÃA;}üvñïiCU…—.úZl¬ õå?²ŠcHÕ¸´Ôu½ö!» »†ó±œW‚Ñ/ðó\Hvq•bf€úOÕy3¹;¾Ð¤ ² ÜŒ°š'ÿˆêIܯE|Ÿ¹ š­p:ÔC9èc!¦²VûCÕ7òÿ2]„2ø²âª³ç½ã,}Êø%(ê’r‡ɆfQþÏÈéª{ÃÅ3’u7õ(;†>Dî`…°éö'xN°?1jaóXDOÄOTÕYe¸S;&bïæ„Ÿ"=_ƒÕL+Æe)ëõP -gŽ}“ú£qÍòÛ¨ù›ÂN•¥•îÉ/­„¼Ÿ¿¨ÎwýéN­ъ”⃞êöÉ(ú˜i.ŽJÓY{Ê…ë߃ˆêo&ãX -Ë|åT¬N!{¶ L•„«a` K=ETBÔSEÐATMb§œ -Q‡Æ~ËJlQ‹Rü¶×ZB§©{g¯ ^x™‡¾m€ï¨LŽ1p%õïø×ké\¤~}ôO½Ü8Ûu·×çqÏÜV»ì*æGj¸ÙÛ9ýèOâ÷Žû’VuûtñCv.¯ÉÞ¯²”ì U=Ú·rèöI3 Í¢¹ØO7( S~ãÈ”‡ «ÒÛšt”š®`½öÈl/ÅY¦37›„Û¦š ;ŠôÑ à<‹ÆN–T‘Z.!`ßêã…”´I¼M%0,(`Y³¡mm¡ §&ymr¦-åɽ.§æo·œ¢ŒEŸ¼B91Œâƒ!ÈD4B\\ò.½ Ÿ†‡b.ô¾=ƒq™“s,|Ö?¼´~8£»»³­ -Ñÿž¶l ÷ö" •äjÓ`Zo…hbµÌ}åÏ0—ŸùoÎ*˯µŸÞµöñæ/~ úÕ'Kü@Tƒ¯k5{<‹i»ö—ROBz@-+µyÚª«1èûŒÂ·–µZë¿ÊnòEp7âPi«ú€pV¢;g.Oã­pÈTA3V.ÀÙòV…I’]UAÍÊ&¯æwú{¥,¿f -ý’OP\h{†!Ë/:9*ÁþNª‘À„y†Ý¢›¼~¸®<rÍ¥Ø.k¹áR\ÄKÀõ=™Ê³ô¤µéšàš)É  -Ìó¬¤^©êzX-Ta’•éÔUÚjLØ–‡ÁPϲ ‘ Ú €,j%‚‹Bè_|³yŒß]¶to7ɹ¿"Á¡ÒW¾7ÉÔ9NÙbdÌ÷Î2s—O‹D"—MêÓ†l›Ñc,Å=Æ/¿ÎWDk¿þ-ţø¬‰tF%ÿÐjwÕïS;ù^É£ ñšo?ñ -ÆQ'?ßœ†*×3;ùQhþà“R¿«A±FÌb<\gÜÝ@ƒ×oìfg,ÙS¿´íw*0=a{ æŽ!Ù5"OBŃð4ûbü[ïR«r‰2Ó'VìÖĵv\PjÐÝh «»Œd ­ªÌ'3çÜŸ¬ô£uªü”.ø¡×cšÎO -DSmÝ÷dU«TòȨr7)z¡mYÅÀX˜Ä5ê¦[Ø÷ËÅŸ"f ‰@êéqD„ç™Õ'~ñHA[€‹Vû¤“õ^C -ݓ׀-xú€°šNceŸ[å˥ߺŽ1½é˜Ê®aYÝ«ÀF5PYåaÉ|3ãä¡ïbøM@©Nyav.åh­nî×ņ®ô²¡RŠÅ—ȬŒWyŸ¦Þtƒ7×ÔÀOkB¬œC@ƒž©êo´dÏ “I¿ü“Z©þä}\žÅ’gÎBT…bM+5êõHzJžìfy®âq -C¸ÎÞ•¡‡›û/ìë aLãdU±Å,[g¯úWСÖX·V7~æQÈ¢%+ð?éצµ!ùUè³Êk5ãø&Z£Q‚É [äxŽ-b÷uP…#Ïñ¾†E@qIÀ$ä;®ŽVçæ$#ÜíkôëtJ€\¶p5žr„º‘¢€$|H{U¡øæòƒK]N}¬ò†Ÿ€E×D° -FÏ-¶ 6© †Â ߸ŒçânVä^… ]šMg\ÔKÇ·ä 9·/£‡õü7o¼¾¾Ð¼­ÎÉSö'ž”Q®¬þ´òB†‡Òe|°ià”¸[‹_Ý‘†6ùŒë.'¸cä½M½åÕr\S>‚K䃔t§C稶h5uREæ‹LU§­Òƒ˜Oôz VÇ‹;¬¤'áS™ÇOXñË€¿®›¦™;µWEƒeÔ #:0츜BøUª,ØÞèb -Òó…2pÈ^Ù†:0|&e¦Õ,?‚HFkJæU'ý!qÆYµwß³HžÿÔ«œ;…ª»ž–3ª[œé@—hžÏuãrnL‘;®ˆ=bªy7¥E>°áíîä=HøŠõzŒ³šâs|Óß¶ª`KA -Œõ_P-ç'„HS -Л¨'ÁÚæãy¿ˆ Re†êi[‘¯²2Ê2ýQ%™ÒZâû®žm-c¢‰LPe³o“=ÒÜi:èÑ'Ðr^ùÑ­ßÔ{?z$É&aM%*Æð®iÞ ïÚ‹š%4Üôí#6¼± -´!;h¾þGáÁj2Á|O¸D ‡?ûµ“îw¹´`ªÓ¢¿¸‚’cçÅò¢†‰‡Î·¤ÌaŸŒÄÆíˆ—62A»wÆÕ(†“Øs/A'viÙ.Ü]Á‰µ‚7*‹4¥'O ¢ °vŒ÷øF34§¡Æág¢O¿u¬.t¼“®rõ–s}/¸šä”ôÛºö˜#=ÕdrõÔVL­WVŒªÙÄKã‰éS.“ (Õ;ãh"’€}R>•lÏs¯ì³²Ô!¶‹lAËE:ßy&ôœh»Æ2©×Äë2+Ù®HѳÁŸ¨0An´ë‡Lš@°ƒy‡ß[q8^:ZËÄc hjð-¦B _¦–¨ñº€ÛJT§ûš5j9È«>Ú)¢Û»nSÑj=³ÕXër÷Hl_—rß:¯0)]F: ”Ùtë,,pQ£î÷s²•õÒœúåx.Þ!ª±…» šMdÙŽ%󌥢À>­×בtÍýh;ÑN}ÅO™~ìx[ôÒ[ ô)Ò`Ç™[z€Ð¥Ç;ÿµbä¸ ý· ZÛ±ýW=mVùD×®9, «Ÿ³e,ëKj}Ü üï J¼,®bðýÂò3Þ2¼ ­h=Á‰U,jï% -ìé×¾ Ä92¯kƒG`µÕÂKþ{|*Œ”)ÎêÒˆÁÄRéAîCêD´Ó®ïÒ‰svѬµ>cj -6müÍpHr£\Ik[xi×$¼šÉH$S<ÂÐ]­H;"þÏ] …h!ÎK Ùç wœÙƒaƒ!Wo§têQ‘21¸¦e}œDó—ýªM¢Ê&ëÅ"þçÍÜ1IpÅQè—{ØAÛ»kJ‡³÷4°6ŒíîO«Ö*“YŒÝ*³A"Õ±«Ì Õ r¤eKãùŒ©$a^Hœ›Œ×ý‰ÞFïNûé)•7µ»‹i?¦: ¤®ý§"×ñ—á -¦y¼5âéx Î?8€†,ÄÙ%š¼ø*%q$GÐ]È%\íðÀ¸¯±ÆLÆø¤z*­Ë"7›U0ž$¥¨ ×”€ïøq*櫸×\~ghL[ü ¢rñY{âkây9‘ä¹_­-¡„­“ߣ|ÒœZ¿€ë˜û.†zžÜbé>1aNÓßøÂ–à—ÒK!5hI¾?K3²< áŸ,ÞÅÁ¸²Ü$j:=úzåmÈ_N4ƒ˜Fäûq -°’胱«T«þÃ5jíaƒ"¯‹¬Î×Эô'7kˆ]ú†A§òuSà‰epÀƒZ˜%ÆÅ…¹­Â¬¾=úð¤´~¸Pù*€üÕÝ+àŒVd˜¥ódqɈÎEX—dÓJHÁ+°:ƒÊ}Ð)#ôø@ײ!R»ÿ©€£ì–ù -;\ùˆ¹¥e7ÍHÖx³¡l½ [sÉHù[êƒáëXôËUNÑõ¢i X–Ø«c4ë7û\Aº0«<{ Evg]8xp[lZщ5õè¹r÷ûGâÈm*Nêê:Q+|‡gµ}ÁÞ\d„äO¾>hžDä¡GXnöº +b¸¬óÇ;½tÛÓÆŒ£6lÄ”Å>4ÌÑÑ0a=‡ˆ …˜ØÃ zb¸»6û€x{³IÝ)KÞí­[×î÷7ÑÙ€ ï²jP8b*æñÛGŒŠw4£V³ü2ÎŒfu3^üL9OOW3èPq½*z5la:ÏÆ> ?Òæ3zîÔL¢Ãùïú÷~¾­ÔŠŸ+qqj²„îÌoƒ¤ 2^›6Mäck~·H‡Ogi$q5|©/̾®¿îÁÛë3úï.7ÿ”,—síÃ[|EØ9 ®+Á -ÐQk|/Û9¾ÑxÜÜúÙP7˜ªl©¼å© 敱<ý6œÍ¶Â=Ÿù …3ñTI‡@TƒÌ07ƒI`5¼áô‡lcoƒ|áþü]¤ãÏ(^¡¥µºÈÕ6ÿCÞŒ Ú롾—lšÒÚ´ë÷aµ1Óþÿ×Μÿ3¡¹—çÈÊ–#Ɔå‘yLî£æhm+÷U¹bó±'ñ˜#GÒ,Ga<ç,÷s¤„9a§¥|I@µ>¬Ó ‘ŸÂînÞñ ±mŒ¼?Áá¼ÃñqJ˜.áC{¸Ús oÐþƒ–B•(­dfá¹È|ÄÕñÂï„Ó84šÁç2ˆ¥(phëž7ÓŽd5ÈìDÀµ€ÛæIl]Bå'IÑ¥ôFÛ܊ꨤ!šFó…L`0\ÁàÛ˜‰¾Q¹u3!skA$TˆBØó“ɰ`¬ âŒéúŠƒŠ–%¹Î× Aä÷öoŽûŸ»­w‡¾ÙºïÁ° bCL?í<:Ú _Þi 8eT)ŠD¨á~ÑH½ØÏ7ceÐès6µ™Â$ï|ûŘ‘ùË âæIPÈkfåöVÔBÓ(ü -šþˆ/KnèEKØ(xÆÈìƒww¦\3¥kÔ!›ùÑÆlð›Qe8‚nÛh’8¯tãær|BUw•Q“)€gÏ£ŽWºè¥@Pñ„¥¾‡LZð7×(fÐlç9¬Œ bf r·Ñá·šPæ}p -øš*›íßyýá“ãûB/1;Aì2ÕÙ3ÕSs±‘woÃñÕ“VÝÝíßv¼¯å¹ÜÆ{¯’XcÇú9'*:ÞÒˆVÂ)BSzŠ)Xý_ƒÓŠÖpm{§z¼¸—±u±)ôc¹ÿÕ)€+H2Qi·'Âڱ׉×b@akÊE¿¢vÉÃBakR‡å:›ñ†‡Fˆ~¨êÈ’Ìm®g4šv~\œI©¸ -^ýì¶<[7Û-ú%çq´Å5mââËÊž¶t“Bdc;|WÝÚú7–xSyåÈ4ØÇÖv´¦×Åõ Q«´˜„2ã¹Rwr\Œ¨ÇÂCÀVD -­`Ú5øy÷»é@k"¢™5)Ï1·ØRù-DÒH Ö»¼ÍDdM†o3w»5Gv`LÐ2îä¯uÈoêb—r›[ˆv^Ð^P€ó]üQ¨‹ÔS^?¨Ïóè_û³£ 'C2T5ÍyÅ [<;ËÛÜ}‹hLé4mMmÖéҎ/À}"ÑçB0%’éVE~µb(e’ ”峕UòïiN“ýië€ëÜ„{X#Œ=dÓ[娽 ÿÆOƒHð”£Vê ªëvGJMGÚêåÄLX^9ymiZPpù˜B5«¬Âø#…sW+* ¨)¨OñD¾Ë_*Ïøy81¢ÎsY×/NI„8wÖ¦.¶v.rþ÷¥äïûˆÍžá¹ˆ“¤;éë7¤{®ÈEÕîÄìø‘VYƒÉïÌ|ÝWN`ÄþÅW‡Ù¾—›º‚ÔÂâsh™ËúÊIÆ(ˆxó^m¸ƒž²Ê+»O':QGrçÉ׿[XFRž;j¸±·ùI•šà5A0 {Ab8A²T†’QmO@ i©Vél³¤Ó¸£CX;䆔¢$ŸaP÷ga†kq*Õ{²…nøglƒ’¼2GÞ Y•.ß“­õSlôŽß-%-½¯·e—ppÔW³8©×‘fÅ¡Ú=ΆþKbÿÿ‰À/$À'ê,öžä÷³endstream +FzÆ+-œÄ,ÜMŒ,œÌ¦Ö{ô/½Š­±‰£µ…­É_.ÿÕF#ãØ”Í-Œ¬lÿi:Û¿M&¶Æÿ™ù_zþ•7ÃQ9õ4ÿ¹Mÿå¥ð—ugeû¿‰ý:díŒÿ—ð†°°;À‹Ž•@ÇÌÁ `çdpr0ùü¢ý †é¿dYgG w€Öß’™þUøÿøþKÒù˜¶FvÆÿL‰’³­ñßÁú_ŠÌF.ŽŽùü×]ÿ[ðÿ”ÿ5â&&î&F0kËvF<Á–é¿2œë0sG&Eµú˜@GBìK•‹ +ükìzýÒÃw¹*õ?kC蛦¹¿Û=–Îí¿¥¨Æú0¬)zSM®óñ|H¨ú ·È;9hŽtKá3.Ô¢½nevÀ4ÙUö&ê–|BàOw²8BݼPù“¸ø£‘>Û#ø¥5Ä¡w!5¡Ôž_'¾}Û kZÿôóüwÎá\àèe"°µî€”PX™/,3"@<ÔSÂ{4ÂÑ3#­¶«i7.øÙ[ÓZ‹ ô­·6åÇ7«¯uÇeHfÕŽvl9‰® Åà.¿ÚCpôמ¹ï +ÕZŒ™ÓØANvŠ]Ïy–ãÅ{iGçý2ê-úA¢ÿ}ÛcÃ~~*æcd@Œ„8ÓÔÁ?W‘2,Åi|Z…È%sÒJ CÓº‰¼¬–‹C!ýñà Ä~0w‚—„L¨„ ‹¡=%¾,jl‘¡Þ‚Fø8;í¤JN DË·¯U7÷ôw¸àô‰¸gVáÆû)§ª!‘Neå~Žm­EGÂýqÊ¥ -â9þÝÌ_*nÿAv ÙSáýÀ°v€<÷ÁÀÉŠÅÜä±ÌWá ŠÞâÿ.±hMe”:X³Ï/=\“õ 8èOª~îTˆJ~^‡Ò¯(E>JA±Y|̼cæ¿çѰ>Pã}õÒ¾Õ*"SßRØM}ñ7•KŸa:uÖKúÝý HÒô D¹¿£„‹lű"ŒƒÎ¥Õ\ÏR°#_ñ1ò—ã.±¶•õ¦üã7JZ*|“P9 {Èñ\U-ã±°¶ -Ú¡QZ±¢›w¿‘•Üv7óŽ-ʇJѦ®!ÀçÜ…áÚó¬Ë9€FÿýÖì=|»KYg¨^BX³Ø€ÀþJk8»8—MzþòÎ&38S‡uìTÌoŽ $àǘ^zE—w#ÊÀˆd8ë;ãg]¬M,ýt’Ž{ÒÈ%Ñq%%mw„­Ãî@Jeâ_õðßsÞg¯`¦RÈ5EB† nDŸ¬‹Ÿ"8ïnx³E4 V;þ6Qh\„§Þ=½X ’þ“Gþòüåŷ싔셭bŸ§ç\EÏñ Â—°w#¡<ª˜Ûa·÷‹~uÔ›š9>kÕ`•–ÚX´nz«að|ÏǾävœ«Œ+=L6¾Møf"Hó²†ÖÚü‰Œ6ßñž? + ,ÐmÍŒ%²Ž¬î|ø"Õ?YHå¦õÆ]½ô!P!1):X·œø~R¯µËöÛÀï/ìº×Ø,‡°ñ·¢WÅýí`ôÐõ g¥°âtãÏ䱇sæ¼e³Î4MùGî>8¶»’d÷ºëFÛÆö¿®3 û°½i.ío±Ç|Í¥Z’2D3yˆPPjñÕfGüf0¾è<5éõ!S¾/!u¾ûµÀÓš +Ø:|‚¬·.¶–ó_Mv“ôacæ~ϼr²]‹Ë±¬ˆóÄa©Öbß:g× ¯ïëb¥-±÷#ƒP!»‚ŒCîîœbL ÓÞ˘]÷]¯* dÏÕ §„n˜"}x3< `C X‰ì4áJrÛBHõ“ÁÊ„edÔI¿Ì | `Zþ©Å 9;LgÇp™or¬øæ•šÀTʪµiÇõo²G3iØD‰ùÑ®äB·ÌeãÿBÖ’ G«¨¾7”2À#?Mš*í£gm¥côG=èÞ[|T^Êh¸Õ>w~õO¿þÜДr_Ï68È·R©¡XVÏ-‚˜$JÁÏBG×2E"ÏÈš×å=Ú¤2߬ '¢Fö‘bP©¿)‹ÐÞ Ç³Í~Èo´‰¯Ëd˜ž¨D¹²|§ƒ#!vµ’oÑý$WG+³…Íö÷—¶vËx‘’ÁT:UYà‘’ˆ”y€—øÞ¨ôû³b›3¶¦~"î ³Íþ i !ÝT=ŒªÐr/ 2çñÅÂâлHh:cA×ušÍ/[L€ˆ¸?´4~i-pL6‹¯¯g’^†æ +vß¶o…'siEI݇‚>TàM‚ ó.¥t§>À)— 7J®ò¶M¶"Wv,ð ò{ Ò~|oÄ$ï!½Ü¦ |ñõï˨²ͦBÇÓX¹2á{dåÖÔ ÈåuîæÙÓÜŒ¢± +åsõ´ÊåÐh?‘«åŒß¥éÂExÜ%8Û5µÃ³ÊóËoÁÒ¨§^RýÏjfrM¿Êí8Å޵xà„ˆ;“JÇÒéy.±\Gj×tP6;L` Ÿ6ìRØ#6C+9G÷`Xòñ/+?þ±ÔE²d n`ëæ/F»Ó y³¦s™N520üBoëÂ¥ÕTu¥X³W™ÓeBi¢±¡Ú€™nŒÆÕŠøÉ t¢Ë¨ûCØí ¹Í^„<ß™&ñ2Ý5’­*}¤ô/Šd²FЛØêZÁ?˜M‡þøËá̤( ’ Óü€þUÒ³Ën¾ê|*0¢¤ô;‚·èb€ÜøÕO1ñ÷¯‡¸ÀdñëxÜ\6€¡A©¼!r“›ÎWL¨ ³ •Ú ªí⯣nT“Û¸ ;¤ëÏDc¹B#e >ó—lê±õ2ô¦ÒPùi÷ ß±é1¢é¼½Y½ë—aÉu«Žœ.@’Ñ é¬ ºá)ÒK“b§úb¨‹’E{xaüá;ŸýIÒ®õnjgôO¸·ï•×_ÝÁ¬Ÿ +_Ë£Ý% }\RÖ:èJÞd­ÖX¶d–> /Ä,n’5¸r%£à²ºš–øŸmV$H‘Æql=ˆKZ»(‡ruP÷S™äR“Çчȵc;"+?Ócù†”•!kȼª6´ÊïÓ‡l¥ýá4Ç(A¦†K)-Ý’vÝéÏîÅ‘‚LÿJÊr ÷è½Úƒž ~g°Ç¿2c‘„$St[޼ì“[É]ø³1Vz¶ÞZè±J=£YR]5Þç9ðš|[EyŠEšÂ:4ÿx©â+*©æ>ØyDUÇêhÌÒ>I .­ö=ý1ý¥Òc@ßÇîìq㦒ÇRj¹z8¡v˜»7ÖEUß}-Hè2¸Â…÷ÇvV:¼:_ŠæDÙ¯ñ‚-§¡mé«VÎ#PÔü4QÖw×ï7`§¸o¢JžàFݪ<^ÌÓä9+²Ãóm%™¬vËYàQ¾`ƒáÁ¾uïÏi,gϽϱ«â_–ó®2 ¿^Ò–L€pi`J¶Ä =C‡ç&zM,¸M,<Ôy 1H†æ'vÛÕbù“nx…óÚ·ýKK*›¥,/6y#?H¯[M¥UŽÜÙX AçºF1~¯¡ŽÆŒÀç¾ÇýЗZ]aý\WÂ2ز»p׸ÌGáÜý¶žèuvßÀŽðucŒõʉ¬ËWÑeºwXSH±‡?Ï^–“\ŽÃï¥H×y0&ÓcÒIJVîÛÀ©×Û ê ïžÚï‚ù1E—Ì3ß®jf²ˆD]õz I퇹`ª¢Ö6pÛ 1ÚaTm‡Û™úß— Žd±*{Æ",T–]BÞÐoæ²V4ÚX>}Á+G C¦2ží-L¤JËÄÂ~º0¸3y©*¥#fç^ø¢(¦þ˜QËŒ¥m0ò˜&C–òŠˆ\ ‚ ·sTj‡¬A:&Ô¬XõDGi¬x~7ãJ/oìØ Ò—48é®Ì¨¤ðbÍå8m{|gòG—b2m˜êVüoidmçÑñþËÒ6ài;è<ҤϹ‚%lYãÍ¢xÌî—jzÈÙÉuLƒÚu_­\êæ»´åe¿÷|2Du\Ô`ÐTãE»+‡U>| +RÉ_‚!'zÍ”FøÔ”Vé†u# Žežà º°ÙOLSÀžeúíÖEx!#ãp Ê^0ˆ1üS¸à–lƒîÂC‰«„2í¸Ü}Ýóx(¿à +ξ.¼ÙúáäãD¾[ÙvÄ›)LH”k€Å!C¼…eHêtrƒ÷I/K‚ Ì'…&‡"Å‚u´ƒø.BˆJ½ÖÉ6Ï<ômJ®b2¢´Û}ArL®'îz“$ær,ýíæ%¾Ù£ÔYª„ G…&ûÖÙ9s_CÆKàöÐÊÝQ"K+‚M=2èy_*ê‘®VrÇbæ“–©|.()$Yám¥¥ÎWîw‚45…[ +Ý÷B#?ƒôúT×ϧxß :ÉÜápø»ß­Ó«§ Òµî2Ó­óƒ׌Èð“- „Z°è–¿ + cHì›R¤»°C\qbl +pïswóH +kç„¡ºØ-y*ÄmkYÙ>â2š¸’Ë»§ +À§i°~†Ò°ŸÝI}ƒÚi|ïóPãAùÖ /—™¬\µpe<­8M#¯š"’%+ŸÃ~ÖÕ +zAâ:Û—p¼!™^ŒúvAò£b<±¼«·ÏQždWŒøÍHŠãD*uK*½­:ÉíF~±1`gÇTÙŽÍ€2 úí¶­XšZeï§òA°´´oƒíÖü²™Í’h¯Ò3Î3{VslÆ.kîÛåÝÓU½jh•² gÇ?³ü‚:©’-“ûò–8HMÌ™Bnñ&Bý@|Sn'‘–½%T7ÜÙç–ÑN„ ›¼ãd_ÛC3®wÇú»²ñp–tjºHgîUŽUP°}Ö7þ€ÜI±ìrLEm° m×Ei—¿ú„V½ïÖR¿ŒÊ¶fn<›¼X*Yµçç¡4ò; Öor>Óqí¤sÒµ"…ñù·j§t‹¹ÒØ"⺋Ñq§º(±ËóˆþŠ +& SºY e H;Hÿ—q¤ðËêXæWiú@ã&kêoÄé"´%ËÚúWÅ;yfÅ +v«šÌóvI]ô« ;î÷÷¨¸F÷.Ù¢™ÁTÌï„`/ ¸˜˜­Ji‚>S,®#˜”‘Ž—õñMâ‘lL÷Š‹ïŒ®zöœçŸ¥z¯„Ú^Hì»8§jƒ9Ux,§}s'^­V‘Ÿ«¤ñ¾`<@\-ؘãûÄvžN‚ðüìAåqy|ª“™Ç>$’ïÒÍÇH¬ðù·ÆHÄUÇMXá –&£‰.BÍÓTøÐÙ̃DXÂ5ʼ$×Chë¹âG÷ MøÄ‚)¸ÕPk®GSJBc‰%»ÐXê›XÔò‚bcžëóBq3©‡É%øÂ8Ř½Ý·óÛV•‹,,n¨Àˆç“tQÌ¡úL;Ržˆ?úzGc£Wt›qØÄ±7¦¦„öµij6Cì';*8ûAŒ,XíüZ—ø[]ÔóÍä#S*Mͤ˜8µÃï}I‚(/´Íd:Ç€¾•[ăLMbT¾ˆý±û9<­þá⼨d2ʦ¯·Cj=’£¸@ýŸzv<“QÛ;úbñ¤ŸºË¹çd)m§™_h(ÂêÙ`¿ØÁ4t„0¨ ,ÀúR æ.bÞXôCMj‡î×ZüzÙîæaò3“æPgpÁc!Nn<—,ï”b^ÆM¬3‚Ëpü}ƒp:}|ô»DØâˆ]%'ÁTå¹:#›AÝÍF‚Vã0b0‹4pÏ‘Ï)hµaA+Ûz¿C¡è%mÜgªą ÉIßb{Á6‰wƒ´·T£Ò‡c–wºf +{{~D'ÛûÔ ð.$*>>¿¹1îmÌ›ÿ‰ó(¦Wýbš¥ìl6ÃÅ>-³øªd~R3ù +|hD +i^Dí£.(€ù«483R£ÁIJ“@¢t)­ü„ÔIm1iM?!+øM{äa÷]¢°A4àƒš$–O}÷™'ä§îÞ¬Ò[{/T|F¸óC}¥Œ±°sH|=OKRe©y”‚«Ÿ>¼O¡ì%œG“)Ä6<¦—rÔ¢þS,ÂHǮڇ‚‰¾Ì&%@¡™~j5¢ÐW¼Žã ­ÑçÖû:èµ{"ˆvfT!Æ„ï· yµºqIzÚ*˜mÖvÉ?5{T×0DÓ£ b9h¡ óòyÂ3–½è" +øvé硎ŸQ-\~X^Y<.ê /ŠÀ­1F0îñ­ßÀñ¨<ØøùJ]Rî9˜¹t›V¢6[8ýÍÉô½T5é]ý¢âì;÷¨:ÒB¸ájÛÑO7õ\CÉeáÌq.ªš¡èËŠH–»ªÛ©]ïd”Ò+>,ܼ`LšoXGØçv-seSÞd¯W†éɇ۞ 0§H[x— ô…Ì>„^¤ÁvJ• ð@FƒÞ„–ôÿ憉’étŒBžÑ ”ýÕ&!¶¢ªH*Z"¼ñG¦?€Ââ‘Ьg +R}¼nÜÎè-xâû1-ÿ;„&Y A½œ¥AçºxýˆK\ëS‡¾¨ b¥nGU/0´J·P›Ò(ïeߢ½œiñž¨Î»È’È g 1ë{"ÀÜ|¨G3+a/Lò·Ù¹–ß2çÓŠ,›»Á¨©âà ½F9¿¿#úSŠoxûCw|g¯óu`¶ªu¤MÔm†² D™×ô—|ë3Ž;Û•êú½W:Ùe¸Ìg-ö(ƒÀkЋ˜®5ü¥ìTlf²¤íiìØMO­3prN]ý +AAé/«®|ô‡ïm?‡ïŸý±jj2q¾4(æ²Øèð‹zQcaœ–çTýr.š­5Ùðþ~йc¢{ ¢HËœ…"$mæUËbJÑO£¸Œ ÿ 5ÙN…MÛ¡ +¾Ôáç†8˜¨±“EH•.¨ü‡ÐFM)ŽC‚†-‹QõYzö?·­l’KÂDжöŽ·­'÷!QiMùbƒìè÷ÌË¡k †ÜÛö +ò7ðሳÇW°tò>*4HN˜zú½á0 Ð\ìiüp?ØJ³)Ó'žÐêd<×ê`YæV .-Y#ÈåÜò/¥Ë(ì…ÕqÞÎx6¿ATK,rOÈ Ýœn¨åá¶4)š³m0½¼ˆ.Ó3Ãe¹+Îvûçg¨[ù§r©Ñk]x2ÙèÏ,Rè\žmê,†J ZFFx¾8ŸïÚu¶.!¥^R¿o}ø¶¶Ê—ºNy”ì1€XÑ0× yⳘÄû% +ý³[r]Ù'‡Ê’œÕV©_jÇÅqÛ4åÁŒ¢ð›ÚŠC.Xuÿ ûûÖÑ;exhhÞyvM¢*Š%`d#­˜~Ýi­4Y}ÏtRµ£åvíùÐèÂ0°îÁO.,ly9.<ÁøÙ+ÓƒÅÔgí+¨XÞ¿é^Côkë;“[QÎÀˆ2È7ü= „þ8ª§xuü¦HŽ(ßáèµÌ±mÈÇîçV»¼ös„-·ÝÅØ UÑ7êIàÌiΘ”*9óÅ“ „Rä¨+üJ^ôny +QhNÐúf.•“"©xÆbä!‹4ö|/8ôë©c©û¨Ö2_Uÿ9NF“¦‘˜8MæÕÁ +E$Í] 02vL¿1ý©â&ÉwxÝîÆ;|JWF³¡¥Ü_†>)27ê`Ú>µ ½| ëÔ©$@ôƒ +¢Xo× ¸çœ÷åõ¥|_wùät ø²jšç—¶:âlÁÕ*‚h#²°#Ò”‘g¿s$Hç’gñ&¥n!"ÖÝ3à T¦x›iã×/°…æ÷¥hüiXðꪽ1[„n” ÅT²µÖ·@Q Û’….nŒÈ‡0¶ÇfÆÑ8… ‰ŽÝÏsÓª°—yXæ[vlùðNðÏë­ûË$b71¹þy/pß-aÿEˆf¡¤b-~Kð’‘êçȃ¾>0°hü³OzyůƒÛ{´ +Ïg•¤ÔÒdkqQÛÓÑW_½æ·¦5ˆÞ°Ä-IL>Ä‹S¶?üD#èU‚¯ð&š¬\ Ãàb‡âÂÐèrÖX[nþ¯L^•S¿Øš1'¢/n–ÂÌò$µën/&glÑiø‡ÖÅæaCÀ^@×é4¾nï¹nIãÊ<÷I‚ŒÕÙzßËž€¤˜Zh‚q‚rŒ±^ZgÇî=D`ÁË¥ƒ†·ílâ2A³õ5(q:Ú0D~¸ø/ +úÀžºéâ9Bõ$ÚÀ +¢§0mA®ìR–¨öüBQÀ†9FJÐÔ ²õú ï™´Œ ¯¥µßªñ_['ˆ|zì·UÍcNiØ11žö¨É|Ú~iÔ(ÙRãÿJ T-~=ÝZÁBd´¹³õ(˜ßHK?ÄÍ‚™&Ð=¸LszŒ%:‘W^ßµwk-iéšRoº ÀSKd€{™W_Þm¹°Tk•3*TŒ5õ…ìÐh6¹qºÊœX+¿C²ç¸:ü€2–¿ýåX/ŸD»šÃu Y· ñíwEAM·ôå¡9ÿ®ëŧv[ŒÑ º.h¯l~gfíмiŒiºI&›“~l<´<},n_MWêznÏo{êt ¦™‰!ÞEâ37ÔC)jFC ;> ªÖ“UL¾Û5Ã1.Чr™v¦zß3¶îŒš8 î‰ük§{°pX2>}íRCçXñÒ@Þ4õT4_d„5wé´9¿ 5ŽoB¹ÐPªúÏŽ“=^šT&[¢« ™ +Ü ò6éx3¯¡œ)ÐlXÞ:Ø#kõ«!1ÌÍÝÞîv¢[m4ðg¥¸ð«AA07–JîºywÓ½ßñzHM_PQ =#Ñ4hŸÝžÏ%Éôúz ¹F˜'Ͼd|"óÖÊÃÃ?öÞ*Là¸4vô‘«ÁŸ‘dm±Ï@êcOò÷à&Tp0’“K}rÑ`fUx~kÍ[q€11Îâïc +àà·ÜÊèëTwAU!¾Í†¦vÆIˆ:#·¿âŠŸ?ò—´ù}’A„rÇ܈ÉL{@½j»<ø!Ñ«ŸÑªjH¶Ëpá• ž¦oHä7oáDžGÀ{{«žT«îÅÒ[Éh‰{Ø]åO]Ø•ýÌ1ù"Õ\³¢Î}Ї)õ»XÎ3«Â4oâ#Ä£Œ´9Ûõ4‰taÊüÔšU­q7Æ6y·ŸXDºoœy§]C¨£zLyX_°ÂÃé¨2ÿhfåϼäo¬E7ƒnÇWvV)(¦Gè¬[ƒHlÊõIÖ§;Z‰‰¥Ë©¾7"M8ßTÏ~«·—.~¥òN^Ël­ÕÞӷ* Iée„ìFòäoÄÍ´]P‹^m5YÀ IƒZ)·O„1™Î艕þC9ëü(+3®áИ7—Âgry#ïˆUƈYÀ¶5 DP í´û¸Ñ?‹ZK '¼Œ8±Ç!é‚ÜiúдÞZí‡Ù€b¾4šÛÆó3ð•Îg£ÆÍNt³d#8g¢¸R&ürzmÔ? ú‰¶ZûX(ŸBßv"Ù­~ìD ãÒú‹;71ÿw°—1dÒÒ~ikcFbY.Õh•/;§pÔÅ[˸ÛAp,-÷ƒ@b!4–mKß$iHR +„ŠèÄŒ®[1õŠSG›X*£ Ç|ÌonçþÌÎ`mKý‰—5µ°D®Y‡`´W¼ÆÊ;×!søß˜ïÈöZ1¯È O²­†‹òS6ÌbþÒìu¬í´‹à[,5a„y¬‹ÍæÝ÷§Bc/°½\ix½¿ñälñ`^¡œ" Z$6²ˆ¯µ3îMܦLñ¬ªš%KtÇ$]ˆe#/…¯*µÀ}ÙB\g˜°àYëû ‡ E)F^SZ¡ÁXRP€óæ7•q>Þ"û +%þ4MG9uÄbÝ{2ŽÐÞá?Ó˜·ñÂO‰t8ÔyÕx…ÇØmÛ‰¸Î@ +»3ç{i›TÔç¿ë bA!-¾9®œ¸ ¬Ër‡åÐÔu³a Ç|†bÍ8R¨ÖþŒ¡Ô:¹‰¶´Àx‚kÄÈÒF{†Í_^±ò"&‹3y˜fˆgÞÜæ(h^¡V˜%U +4½ÇZj,%·Þ,î§ ˆ¾O²àœ8[°mÍÑ ó„r¹yðUýF]O“/ñúó°6;^dï¾ ê'7zSí2¯N ,Ó$œ’*ÆÐru>‹ÔJ#*»"¦;ˆwá1Ô2nœ@f'=/M`AÕ÷ 9£ fqLwËÛ”Û.„­¶gReЛJZ^§í'~êúºÃÓ(ømawÇÃ2•ƒà.„¦n‡@¢.÷DVäý»±–dgÑõþ.ëßH±²9•P´G‘è&D1ÊnÕb"£B³¦˜ë*c°#•l'xýù¬†R™àD—Ý-掟TôË]]܃|6±ÿÝHŒ`Ÿ™qÞ7ø5â2NËl«„V.”l"Së [5 óI»8®ª"‚éhþ¹v¦$-?ò«<*:ÿzªÏ +ëÈ©ËèH§¦]1;ÿõˆVÜ}8gƒ³·*Õ€’`iíT¾Go!&Ó¯¨Š=Õ„¸eeWh×·I?¼‚!okuš‚6@ç0IhÁ¥¤*oNG‘Ü@‹“»aµ+2bü±À?MbŽJ‹Ÿ`û8”ÙpÁ`‚Ë(‹3]6ã‹]ËEÕ)pèŠ_ȕո…DGª³w1¢ëbï:ÖS<]±×# êP^Ö}?¯ÉDéè&wv™±jŠ2Ô’=C¿ã˜Åš{dŠ;aWPqæöqQôÄ×âÚ#¢.ò~]½¸]‹m·ÿãnP¼~gÀxáT‘úøî÷<ýÀžmúV1Ÿn…õïÌûOOa™’Sži3ÓÞæ.ºØÕ½\H›üS¦é=¯ÁFÔ ÂOÊu< yÞœ= Þ ðëƒóWZRw&.e™¨1àsÜðÊ1ÈX†Ã^99kà­£MÖKÿND4ßœ29V^[ uI[ÏèN«Ì¯·ƒíôñÛÅ¿§ U^~¸Lèk±±‚Ô—ÿÈ*Ž!UãÒR×õÚ‡ì‚îÎÇr^ D¿ÀÏs!ÙÅUŠ™ê€jlp0Âjžü#ª7&q¿ñ}æ6h´Â9èPå „˜ÊZíUß ËþËtÊà ÈvŠ«Îž÷޳ô)ã” ¨HÊPJ$šEù?#§«î ;ÌXHÖÝÔ£ìú¹ƒ¦Ûœà9QÀþĨ…Íc=?QUg•áN혈½›~Šô| V3­—E¤¬×C)œ9öMêÆ5Ëo£æ;l +;U–Vº'¿P@´ò~þ¢:Üi<8ô_¤;µ^D+ +SŠzªÛ'_P èc¦¹8*Mgí)ÿ®O "z¨¿™Œc),ó•S±:…ìÙ‚0U®f„,õMP QOAQ5‰r*Dû-+±E-JñÛ^k z¤î¼.xáeú¶¾£29ÆÀ•hÔ¿ãC\¯¥s‘úõÑ?õrãl×Ý^ŸÇ=s[í²«˜©áfoçô£?=Šß;ò4]·ÓóUµkÁ”^ÚÖfÊÜúìKZ=lÔíÓÅÙ¹¼f${¿ÊvR²ƒVõPhÜÊ¡Û'Í$4‹æb?Ý 0dLù#S&¬JokÒQjº‚õÚ#³½g™ÎÜlZtn›j‚zì(nÐG7€#ð,;YREj¹†D€}«ÿ9RÒ&ñJ4•À° €e͆¶µ…‚œò„ K +\=c¹²E®¾98wyÖP—Vg••ÄÌÀ÷ æy©é“ÜŠÎf´ÜÄ0pѼ!€Ÿ„üú†z·®Jn%ËAÈÐ=Ð +âÚ?ÆCÏz| þ±rèou¤¥J¡ð9`º · 5àñ û˜ä9X´É™¶”'÷ºœš¿=ÞrŠ2}òzåÄ0Š„ Ñq9pÉ»ô2|йÐûö ÆeNαðYÿð6ÒúátŒîîF̶*Dÿ{ÚF°€ÜÛ‹,T’«Mƒi½¢‰UÔ2÷•?Ã\~æ¿9«,¿>Ö~z×ÚÇ›?¼ø1èW?œ,ñQ ¾®Õìñ,¦íÚ_J= 鵬Ôvæi«®Æ ï3 +ßZbÔj­ÿ*»5ÊÁÝtŠc@u¤A®èÂY‰îLœ@º<·Â!SÍX¹gË[&IvU5+{˜¼šßéüš)ôK>Aq¡í†,¿èä¨û;©Fæjt‹nòúá¸ZðpÈ5—b»¬=æ„7Jq/kÔ÷d*ÏÒ“Ö¦k‚k¦$ƒ*@2ϳ’z¥ªëaµP…IV¦SWi«1a[C=Ë.D‚j/²¨•. +¡ñÍæ1V|wØÒ½Ý$çþЇJ_ùÞ$Sç8e‹‘1wÜ;ËÌ]>-‰D\6©O²mF±÷[¼ü:_­ýúc´ã²&Ò•üC«Ý W +¼Oíäwx%2Äk¾ýÄS(GQœü|sª\ÏìTäG¡ùƒOJý®Å1‹ñpqw ^¿±›±DdOuüÒ¶?Ü©Àô„í˜;†d×xˆ< ÂÓì‹ño½K­Ê%ÊLœX±[×ÚqA©Aw£-¬î2’5´ª2ŸÌœs°ÒvÔ©BòSº ã†^i:?)Mµuß“U@t®~PÉ#£ÊݤHè…¶eCcacÔ¨›l=bßS,Š˜&©§ÇžgVŸøÅ#m.fXí“NÖ{ )tO^¶|àéÂj8”ñ@‘eX€IÑa.²~SfÈá ay_èŸNWú-¬Þ7ºÒu<õÃà”µ}™î¸I ÁTðg Ãg´œä¥~%>Ðoë÷°"« q96.9 ÓNüÿcSd÷¾d&"µ7‰GâxœÝ´EþïñDµÔÝÒ–Ó~í4íLÅ…oÅßìx2b ÊS:_…´Ý·¿‚] £Âih£uÄØ¨‘³XKbâf¨üÚ½¼‚• X®O”­…ÿ5ÿ0¡Y8÷PÚ-ö¥¶÷ãtR× +DãäÈ¥1™ÈO¬=1ô'¦9ö‚ã²½m.6Ëš '{`ê¡8à^†ÎD(|s÷éz¡¹¯Gœ1nßNqø‰f*O‘[Ö\Lbî,‡–Íáó±up¹÷ž!º«hÆ8j"cÔóΨڢë¸Sô²—59Ø™ +*Ÿgj.[‹šœ²¶'iº`Ǿ‚+¤ª$›ì¨éƒ?Îy¤*ÓÌmx¾'˜|g'%ï\Äu,áºn–¿öÓfñQ‚[P0¶ãW~Ø0N(GC¦û|n•/—~ë:Æô¦c*»†eu¬:Õ@md•‡%óÍŒ“‡¾‹á7¥:å…Ù¹”£µº¹_ºÒˆJ)_"³ +3b\å}šzÓ JÜ\P?­ ±r jx¦ª¿Ñ’=‚N&ýòOj¥ú“÷qxKž9 iPŠ5­Ô¨×#é)y²k˜åñÀ…Ôi¾ ëk'ƒØ™{Ξ`Î숉 {é5züñ-à@¶–bo˜zP«uxÿâ/ëSôê„¢ k¸ÎCSx¤`ŠÇ]ÒdÛÎ’E[”kÏîéÉç[DÁ†8ºÒ’èû¸ŠÇ) á:{W†nî¿°¯ƒ†1eŒ“UÅw°l½ê{\A‡ZcÝZÝø™G!‹–¬Àü¤_›Ö†äW¡Ï*¯ÕŒã›hF &6l‘Gà}8¶ˆÝ×}@Ž<Ç_øÅ%“ï¸:Z›“Œp·¬Ñ¯Ó)rÙÂÕxÊ=BF@èFŠ’|ð!íQT…â›Ë.u9õ±Ê~r]Á*=o´Ø.ؤ‚jP +'|ã2žˆ»Y‘{‚vi6 pQó 9$¦û,ß’ƒäܾpŒnÔóß¼ñúføBó¶:'OÙŸxRF¹²úSÐÊ fH—ñÁjx¤Sân-~uGÚä3®»œàŽ‘?ö6õ–WËqMù.‘RÒ£Ú¢ÔÔI™/2U¶JC~ b>ÑëZ/î°’ž„OAf?aÅ H,Oþj¸nšfîÔ^ –QƒŽL èÀ°ãFp6 +áW©²`{£‹)H ÌÊÀ!{eêHÀð™”™V³ü"­)A˜Wô‡ÄgÕÞ}Ï"yþS¯rîªîzZΨnq¦]¢5z>×˹1Eî¸"öˆ=ªæÝ”>ùÀ†·»“÷ á+Öë1ÎjŠÏñLC~Û>ª‚-)0Ö?~AµœŸ"M)@o¢NœCh›çý>^ 6H•ªW¤mE¾ÊÊ(ËôG•LdbHk‰ï»z¶µŒ‰&2Ay”;!LöHs§é GŸ@ËyåG·~Sïýè‘$›„5•¨ÃG¸¦y'¼k/j–Ð@pÓ·Ø ðÆ*Іì ùú…«Éó=à1þì×nLº?ÜåÒ‚©N‹:üâ +JŽË‹&:ß’nd0‡}2·#^ÚÈíÞAW£Nb_̽Ø¥e»pw'Ö +Þ¨H,Ò”ž<1ˆ2,ÀÚ1BÞãÍМ†‡S\œ‰>ý~Ô±BºÐñNºÊÕ[Îõ½àBh’SÒoëÚcŽôT“ÉÕS?^X1µ^Y1ªfg/'¦gL¹L‚¢TïhŒ£‰HöIùT²=Ï ¼²ÏÊR‡Ø.²-é|ç™LÐs¢íˤ^¯Ë¬d»"EÏ¢Â4¹Ñ®2iÁæþ}oMÄáxéh-¢©Á·˜ +- |™Z¢Æënw(QîkÔ¨å ¯øh§HˆnïBºM}D«õÌVK`­ËÝ ±}]Ê}ë¼Â¤té\40PfÓ­³8<²ÀE ŒºßÏÉV>ÔKsê—ã¹x‡¨Æ^ì‚j6‘e;–Ì3–Šû´^_GÒ5÷£íD;õ?eú5²ãmÑKklÒ§Hƒgn]èB—ïü׊‘ã6ôß.hun?Æö_õ´Yå]»æ°0¬|Îr”±X¬g,©õq€ð¿/(ñ²¸ŠÁ÷ ËÏ~TxËò‚¶¢õ'V±¨½—(°§_û6çȼ® ÕV /ùïñ©0R¦8«K#K¥¹©ÑN»b¼ H'ÎÙE³ÖúŽ=¨)Ø´=ð7Ã!eÈr%­mái¤]“ðj&#‘LñCwµ"íˆø?w-¢…8/ ,d?œ3Ü9TpfR„ †\½Ò©GEÊÄàšz”õqMÌ_ö«6‰*›¬‹øŸ7sÇ$ÁG¡_îamï~¬)ÎÞÓÀÚ0¶»?­Z«Lf1v«|̉TÇ®27T 0$È‘–-ç3¦’„y!=lpn2^÷'z½;í§§LTÞÔî,¦ý˜ê4ºöŸŠ\Ç_†+˜æñÖDˆ§ã58ÿàZT²<g—hòâ«”ÄMHAw!—pµÃã¾Æ3ã“ê©´.‹|ÜllRTÁx’”¢,\S:¼ãÇe¨˜¯â^sù¡1mñ'ˆÊIÄg퉯‰çåD’ç~µ¶„R¶N~òIsjýB®cî[¸êyr‹¥g@øðhÝéGÔz.Ó]8ß½¨DN¨÷9ÔPÙ;ÐLtl=«ä‡Ûä…^íH”K)cÞ˜ôª)骙Sg qWY¹›òÁ—n«ëlte¯Ë•K~Ǿֶ«uVÔél“µûÄ„:MW`à [‚_J/9„Ô Q$ùþ,ÍÈò0„²xã^È6>r“¨Eèôèë•·!9Ñ b=’ïÇ)À^H¢Æ®R­úרµ‡ м.²:_C·ÒŸÜ¬!véÊ×M'–Ája–k>ä¶ +³úöèÓÒúáBå«òWw¯€3Z‘a–ΓÅ%#8ae\’M+!¯<Àê *÷A§ŒÐã]ËF„Híþ§޲[æ+ìpå#æ"”–Ý4#Yã͆²5~ô‚lÍ%K åo©†¯c=Ð/W9E׋f¤1`Yb¯ŽÑ¬ßìwré¬òîÙqxœuáHàÁm!°q8hE'ÖÔ£çÊÝï‰#·5z¨8©«ëD­ðžÕô{s’?ùú y‘s„aq¸Ùë6¬ˆá²Îïôò¸Õ3ëÛÊ¥=áØÕOx#U®Ù÷…ÅÉÊP|×ð1;Ò…\j1+‰zùkakÛŒ“|£Ã öËa?ªåå]íÉ ?çúåûÐlO3Ž6bذSøÐ0GGÄõB €bbƒèMˆáîÚì_âíÍ&u§,y´·n!\»ßßDg2¼ËªAሩ˜Ço1v(ÞÑŒZÍòË83šÕÍxAð3å<=]Í C}ÄõªPèÕ°…é<û,üH›Ïè¹S3‰ç¿ëßûù¶ZP+~®ÄQĩɺ3¿ ’2ÈxmÚ4‘­ùÝ">¥‘xÄÕð¥b¼0ûºþºo¯Ïè¿»ÜüS²\εoñ a瀸®+@G­ñ½8lçøFãqsëgCÝ`ª² §ò–§&˜WÆòôÛp6Û +cô|æ'`ÎÄS%Q 2ÃÜ &aÔð†Ó²YŒ½ ò…ûów‘Ž?£x…–Öê"WÛüy36h?¬‡jø^²iJkӮ߇կLgøÿ_;sþÏ„\ä^ž#g([Ž–Gæ1¹š£µ­ÜWåŠÍÇžÄcŽI³…ñœ³ÜÏ‘æX„ñœ†ž³ /rMåýï·÷yß?à»sÿâY#é» NØ3íY¶À:U ®[‰‚‘¶BàkÝz™=iïÒA• áÓ>8â„ÒXò¨Dƒv–ŸxÃSê^c6GÑÃeï©z¬.£Yÿ¸O£Ø0^¬7“Seã¬ô ˆˆMî«>Ý…¸4g䯓Z}:ͬÈòjùÚqynýKs*)oŠ .¬Èøœ–ò%Õú°: L/D~ +»»yÇ&Ķ1òþ‡ókÄCÆ)aº„íájÏ1¼AøZ +U¢´’™…ç"óWÇ ¿NãÐhŸgÈ –6¢À¡yX¬{fÜL:’Õ ³kÔ6n›'±u •Ÿ$E—Ò9ls+ª; ’†hNÍ2Ápƒoc&úFåÖ̭̈́‘P! +aÏOB&Ã~€Y°R0ˆ3¦ë+*Z–ä:_7‘ßÛ¿ 8ò~Bî¶Þúfë¾Ã2ˆ 1ý´óèhc4|yC¤1à”eP¥(¡†ûuF#õ`?wÜ<Œ•Ag ÏÙÔf +“ü½óMìcFæ/.ˆ›'A!¯™•Û[Q M£ð+hú#¾,¹¡.a£à#_°FÜÝ™rÍ”®Q‡læ tD³ÁoF•}àº}l£Iâ¼Ò›Ëñ UÝU>DM¦ž=:^颗fTAÅ–ú2iÁWÜ\£˜!@³ç°2‚ˆ™1ÈÝF‡ßjB™÷Ám(Dàkªl¶çõ‡OŽï ½Æì±ËTgÏTOmÌÆ~DÞ½ ÇWÿM>Xuw·Ûuò¾–çrï½JbYëçœd¨è8lxK#Z §Mé)>¦`eô_| N+Zõíêñâ^ÆÖŦÐåþW§® ÉD¥ÝžkÇ^'Z\‹…­)ýþ‰Ú% …­I–ëlÆ!ú¡ª#K27¶¹žÑphÚùqq&¥â*xõ³ÛòÏ£|yìÏŽ‚œx ÉPÔ4ç7lUðì,W`üm_p÷-¢1u¦Ó´5µY§J;¾÷QˆDŸ Á”H¦[uúÕŠ¡”I‚R–ÏVVÉ?¾§9Mö§­®sîa@0ö]Lo•£ör$ü? "ÁPŽZ©7t>ªn¬Ú½CPŠM( 4 Xi«—3ayýåäµ¥iu@Áåc +Õ¬²ãÎ]­¨€¢¦ b<Åwù.©D<ãçáĈ:Ïe]¿8%âÜY›>¸ØÚ¹8Èùß—’¿ï#6{†ç"L’îX¤¯ßî¹"V»³ãGZe &¿3óu_9û_fû^nlê +R ‹Ï¡ev,;è+c$?  âÍ{µázÊ*¯ì>èD5É'_›oa9Iyî¨áÆFÜæk$Uj‚×À$ì‰áÉRJDµ=%¤¥Z¥³Í’fLãŽaíORŠ>’|„AÝŸ…®Å©Tï Ⱥ៱ JòÊx €dUº|O¶ÖO±Ñ;~·”´ô¾Þ–]ÂÁQs\Íâ¤^Gš‡Rh÷8ú/‰ýü'¿ŸH|x¨Od°Ø?µo÷¡endstream endobj -940 0 obj << +950 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 34 /LastChar 125 -/Widths 2101 0 R -/BaseFont /VWNNCO+NimbusMonL-Bold -/FontDescriptor 938 0 R +/Widths 2131 0 R +/BaseFont /EUDNXE+NimbusMonL-Bold +/FontDescriptor 948 0 R >> endobj -938 0 obj << +948 0 obj << /Ascent 624 /CapHeight 552 /Descent -126 -/FontName /VWNNCO+NimbusMonL-Bold +/FontName /EUDNXE+NimbusMonL-Bold /ItalicAngle 0 /StemV 101 /XHeight 439 /FontBBox [-43 -278 681 871] /Flags 4 /CharSet (/quotedbl/numbersign/plus/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/semicolon/equal/at/A/B/C/D/E/F/G/H/I/K/M/N/O/R/S/T/W/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright) -/FontFile 939 0 R +/FontFile 949 0 R >> endobj -2101 0 obj +2131 0 obj [600 600 0 0 0 0 0 0 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 0 0 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 0 0 600 600 600 0 0 600 0 0 600 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] endobj -924 0 obj << +934 0 obj << /Length1 1612 /Length2 18760 /Length3 532 @@ -9914,239 +10077,226 @@ endobj >> stream xÚ¬·ctåßÖ&›£’Û¶mWœT²cÛ¶m§bÛ¶]±*¶­[ÿsºûíqnß/}ß{Œßšxæ3ç3×c“)ªÐ ÛþŠÛÚ8Ñ1Ñ3räÍ­:;ÊÙÚÈÒ)Mlpdd"@C's[QC' 7@h ˜™L\\\pd[;wsS3'¥š² íYþ ütÿŸž¿™Žæ¦6ò¿.@+[;k Ó_ˆÿëD àd˜˜[" -ŠšRòJ y5€Ðè`hPtþien57Ú8©&¶«F¶6Ææÿ´æHÿKÈ`p´™ÿMºíþqÑì€Ö掎¿æŽSC§¿3p²˜ÛY9ÿCà¯ÝÄö_„ìlÿFXÿõýS´utr4r0·sü­ª(*þožNf†NÿÔv4ÿëØšü4¶5rþ§¥ùþÂüõ:šÛ8œ€nNÿÔú ›;ÚYºÿ­ýÌÎÁü_4œÍmLÿ‹-Àhjè`lttü óûŸéüWŸ€ÿ­{C;;+÷eÛþ+êq0wrZ™ÐÃ11ÿ­iäô·¶©¹ Ã?‹"ecb `bü·ÝØÙîú\€ÿå?;Cõ—„¡±­•;ÀhÇ oëô·$€òÿNeúÿ>‘ÿ$þoø¿EÞÿâþ§FÿÛ%þÿ{ŸÿZÜÙÊJÞÐúïüûü}al²€Þ+C‡ÿW¸¡µ¹•ûÿ!á?5€ÿ&ùÿ#ådøwB6¦a¤gü·ÑÜQÜÜ h¬hîdd01´ú;©ÙÕlŒVæ6À¿Šþk˜:&FÆÿ𩚙YÚü3z¶»€6ÆÿIþ¯Hÿ¢ÎðC\S^X™æ?ßÔE)þÕÞIÕÝî/±ÿÑŠœ­ñÿ:üƒ!,lëð¤û{é˜Y8ì r21yÿªý †é¿Îr†Næní¿-32ý«ñÿñû¯“îÀˆÙÙÿ³+*N†6Æ×ëþq9;8üUõ_7þoÃÿóü¯EÝ€Fp«¿mx‚,Ò2Ój±r‡'Eµû{™À‡ƒíJTøUÛöø¦…ípU¼×Ó7Ns¶¹/Ú}ìKSŒöbZQô¤/óñ½I¨ú -P7É;8hôJÓÏ4¢<¯e·!´ØÕv'•”õŠß¡¾Ow°8À\=Qù‘¸ø¡“>Ú!ù¥ÖÇbt¢4‚|«-<=#O<~z¤ê¹ìÛǣɉ…%ãq@$ô³ÏÁÐR«ð §‚JoBÀ»i¿ú$ÔèöÔË##Å%°–}U4Í_³i—}O‚LoàM”slݯüy=?É+”8Í5—ûµîL&æˆÅÛ„?Ø;kI8“ ]O0üvMÙïæYk]MýÚ‡”»02£ÔYRïÚµOÆH7î\‰$ÒjçH桳,,c|/ͳ‰M|\ÔøÉ×Ñ;gYs&kœ«ëP›‰­HÚz‚qÒÄ^hØx#:0%;Øt­%?!IRt¦äÞáséÒG_æóÈùC¾*íž¡±D­³EvAõ)i´»¨ ¹Í o)([ŒÔ‡+!Œ4Ž óçBÖx¨ö×éÀQ†Û–Í·´Š“çALb¸Ù…B ß%5Vy>©•õ_C äåwÍO?Xjb¸ËRˆ¢kŠìßFÆW‘¦³Âxýùb1£ôB:^‘átlØèöÇóžˆ}† -ß´Ç-_†‘À=DMá¢y;3pîÜÇ£àí •"¢œÍ‰pGÄ/çk~ú’DÎv}û Î|è8|ÔpVx{DžØæÁù¬(™è“‹¿ònc‚"©jȦފòJøˆÚfœ ƒ¡J÷ôy¼5Œ³4©aÆGD‰–îQHA²;§Oý|ÍJÑs{+ø}Ÿ£ù-0  <¦L¾F{@ºK4@Ê84;/  y¥)ߢ•èöp9ãÁuaÔqLä z?‚Dô°°Tÿ ½ÒHt<êƒÑ`4×Úú -'ëZ;/€Ü –^dŸ”¹\ ô 0:ŸæëFVEò‘¥0\^ƒŽ å³Ý1wé¡•>Rh’`ÛêüÁT~Ø QaZ­d®ý:<_µ\Lä…5®£¿ºyÃRxy^Ù@I?ÂÄ0ï–~ÿà·à -U~-UÙ1`¿ôB}èÿ[à|ýÛ¢˜‘èþà éz]n¡·†ätœÍOîø -é+¦ÞâwªÉ"=ÖšTÂb.Ê;9§D¿KBr•ZDIé°É¬/$h-5…œë¼_àï_æE݈P`„‰ÆA/Xâ\¥$jœPSj9ìùîåIt·¹özîk^Çqô„êò´GËhžÖ=ëxõ\Se”ãÒx!÷©8aYf«qy·BýÞHÜö˜ãfM¯ocþÊù -eŸCN[hÀÌ"¯5sß¡¶s«ÒVÛBfžáœD(˜Ü¤胢&BˆóáÛ§Œ—=Ü9bª©s ß¨nZîÉÄõn^’¡ïg^í*ªüdïfº×D°>M*|™vži­}ç`1;s~ŸNÀê~m©Ó±‡„æ\£"éc ã9D^ŸÍ1ÿ˜,F»9ÿÙªø¥só=Ê>çR³¿N§EUÝ£¾ÊPäý60|õ‘³9& x¿«é:d=ˆ“ºª¯’!êö9šu96¯¬|öu½nX—n/:s€fHë¸ã~_±›PªƒÍ®Hò£}&Eåæ«ëO¸éT\“Ö¤ÍoMç9œÇ!©Góò eLOÉuA¬¡#_Ôáhr/Щ6ßïÜ:´ëÕͩϮ$V‘ILJÓ]Mèž µÎⲇ  @¾áÓË9äøÇZ›¨6ŠŽ¯7Ï©"Öħ1Ê™‚b½ZôL’ADe2EV ]¼¤X*Aþ8€?¸AÝÈ‚ªºØHüéuyHã”Âs *þ¶¤ÐÏW8=IŠ0Å - œÉò;Fª¥)Ò—³ö­nEä ûÆÀ%g5HF¢´`Æ÷‘1ÌBTï7íVcUðíÏsÔ5#LðÆ}Ì Ó]Ô^žNkHp<¨‹7äÛ!”a¿Ö9âì-OhGô¢µÍæ<¶ªKt VèLUjŽÒ:Ø€ íÚ²"A9ƒýL§@•­ÕÜjF×/áóæX±a¤“á…sy鞆v_Íï[3‰Ó ‰°^¡Ê-à¬ßŒ!œÙl7¨¦ ÍÌÊdnS;Ó>„|d¹—.Ú¬fnßY“ã|ø5ýòbõ"éM¬¢øBÍØ-P_éÀ'´ -S4DB~Öõ‚iJìÞóex1tk/•m›ÙƒlÐÈÍ#ÿ}7©ñ´¸jL¤NB¬O+ϸ WEõ{ç$3W¨† ·°‰ñ6Szuß²]wTé‰2åº -r€Ð5™'­§øÌ·¶YPNøÌHý ú†C¦ÝÖïLS]Ý(…3¹p¬Ï–z«ôtNzTD¨7KŒ:®žh[µg¥Ñ¤ë­‰ ¿ø˜¹Ô¹¶âÂõA?Â}û Ž>uÝ'9*Ë25 ÄÜ£ýR¹'«3Ir¿'ãƒz‡&ù#uf9¯*¡ì@ Œ÷OÑĬyáw‚ÀÙÚÞœ«‚ó—o -s%Ú¸üf„ŸËcÉ£ç ©œ>V† x*sžlKÍ?–‰N£“í³Þ;TÙ6qoam~gfÞÃá¹b:èÅ `Âî ƒ3öæùfÛVÓT”75"úzEÒ²4Yj©sÊNõ Ñ?±Šèqu""¸RϹ·ÖÏð­f†¼ÀA'bϧð!KI4 @·Ã‡u&“w]!&$ià}ßн£ƒimói×Y +RÀCÔÂÙ—ð¤ü‡Ö†8ó1…œ)ÛC0H Éª­ÀP[¹@SÝ~w0æOÍ‘àÝÔ´#Þ%ì8MÖ™E -t.Û½«½DŒ/vÄ”õf&|aªŠ«-÷­c†ƒY¨}ÇEWùn¾ß¬úvtÿtšúgÓ±ÇFé…ÁI{>2›Ðø‡¨ÏÂØ#7nPe…cÄ\k¾Boq_„t˜V/|å|ªeE2óFm<Þƒòc):¥¢@y'¿v4œ¸}!™RkÃKnpÁÿ"}ÏHj/Æ*.@¶B™¡áì8³h¨ûÂò0:z$X(q»®%ù9ÞÃX*´ŒEŸ|ÆB¬-$MXÜ/ƒ°I,Ø iÀ~™3Ó &"sÐöb“–ZÁéÃÝog„F#º¡séc¡Êöïpð{އLã³EÔ]¥™PÙu`Jvqíªi‘0ñ}ÅóEëg2!­Œ:¾~¤ÛS¶ïgãÞ¨e}èGóíÜ+¶býÂW¦âEñ%,ðÑ„ U |έR †÷Ó¸ ‚“7|Y0¦¡ÐŒ`c”h"ï¥]$¯ÙDøy–¢U”÷³*Ëö;•»°žˆž½X€Vºi<„#ÑÅÒ8ù³‰·5òNéK#Û”îËÏNï‘r®[nXôf$AO"Ý–¸SVµ¼7ê^Y´]VsBe÷ ´g¬KI^¹A5Çr &&# zK½q*Ø" ¥¸ÅS äVOlMš­åV:ìH™/*go¾ |¿Û^B´÷£sä™Í/‚¬¨+“`‡™Dì žº,Âe…9:Cf!3M¯ˆNïxnÀ>9ë·ÞxCaSB$È7{Od¤Ôt †ðˆÍŠcÅø»,Y™B‹áºoÛâUûà¸Í —¢§²Â‡W½`¢ñ"•oû›‹¶»í‹èoœSªÛ>¢UÍAÃo+«îÅ —6/¿es^“Y ?±Py2C™‹ -ÆŒEöÏ´óŸ{.Ô&fÓAÄVUþDØ×™ -´ÂØ÷þÞŒ4à…÷r Å› ‚$Œ¾£Q`ƒ-`¬×ðÇŽMéˆüyÀœJØ ò`’…hQý)*¡ $ˆY -5Ëñò­Àóv3.]”T'‘™×_ìÎ"ÀT'8±ìƒJÕ2,ί„q;§oék9ãñÙ^¼è½þ#±ª‘l VgÈDÝ/tHõÿ¨ÀQ—Œï±<=fYM[=€7 µ¡éPŰ¯qdt³a³´Ÿ¸®‰ViÉ}Í~‰r¨È ºC`%ÐÔÖòü¤‘ ¨ä=ìíÈ€°ø‚x.«å_dÃñð,öͲ ôpù‚­NŸÛ®}§ˆTÎÒ¶iÒà_/á z¡±íRÒ*Ø Æ 3ýrI›½Z }z+§ðEU-8¬¿¢u6ìú xõ+ðsFúÐÎ3à"Áw}EýlMÚv…U=Iö1ä³Ò±çŠ:lú¡‰àâåŸm•ôònG&±O4 ŽÇ³rŽÏõ¬ß’Š@Î%R¿~W Ø)Ø×\„Ý=VÎáܨVbkcà6æŒ#°ÅóŽùI4MœÑb¸ï=pû{níÒË%ˆfcY¨¬×¿þécaöyqÌÝ1¯Æ ì—n7 -4?äÀYÜéV“yö2RS¨àÆ`{š,#JiHÂâ-ý»€ëbú@ùðsºÄÙÙÇ5NJ;Îið’s7?†™YJÂ’F4TïËý´äb„RêK,k"z’t&¼pwÛkßò1^šDFO²ÌÂ>1Ñk3V¾îÈNŽD{¶æDJ™¼oæà”1•±ææ¯\ÒeÖ/žôG};;’%Ú¨A{½Eì–6¿nn† ê¢Î,%*îp5¤=¾š£Íi -Yت^éιAÈ•Ë5í -Ñaµ+Ë“º±\‹0ïdÅ C´Ð²(Ó©Öצpy§’éÛ …oû x#z–ÓŽú­iÅ6„_´'Æõœ¦?óØ&¢6ºT&V@t½E ­B:3ç|¡7›Ãù)èq‘ y#釪sfWZâH«abzTÆcóY!ë>=ä€Ë„—ö†ÅŒÎF1-Ùòò}\Ò|3GŠXi -TpndØtº7ù)åç«sç/4ƒ8ôÃNE#.VØjÑ6sÇþ·Šª,o¿¢N(Þ-Ú›:ŽoLªḻ9ö8èš?&f¾>©¾*æËäIâ~‹zÅ}HôäX|]ˆ…–5Ö‰¤õö3›‰ø/(‰[ï ˜Vîb6ðÀ—ˆ¨ÔÆ¿<—ªîïáõÑc{R‡vº±£¹ôRåpõ«ý—T6xÍtd=úÈKgû% º`I)„ê6…xVdLñK±¯“þO{e§Ré÷ù+Poõ šZyßÝb*óë6§ï½$¬ôG u\>Ì~ó²=]ÞkÃOáGùÀâ¼’þ4SËÅuÖ¦Ç5´ŒšÈN›Q;|8x -ï‹i’6RNbl¨°› (¾/`Á%àÁ¶åæõ‹¹ÙpbO$s™Ø¶€ŒÑ¾ÖÛw@‘ÖD“Õ˜‚ÍN"­K  &.MæÊj©úŶžÔì¿(`\5ÛZ µ2kyD„ ¬Î[ï*¦à"þFp›aÿ Xf˜¸ÎTb»}-» ÎáÎB%½ 8ê  U‘6J‡(ê¢ØÀµ–…Fíªãʜ؂¯ÀX-ô£-Ýñø>‚q'«o"ty’ЄP.Hòöf;¦—囦 -èýJÇF@´ø¢umŒ¯Æ8|‚…$³(ßUH§k‹ÖÐÓà ÷¹eeÕmÖGJ•#𠜶k%ââ];$ÖJt ‡Ÿû?`ö„i¶Iq~?•°©Âá/üªÄÕÎk‰ÎX¬Êù˜³SÜÛ¶‚ÜHvòÅ¿¯ö—Slöèeî‹*bN¿ÿe¾¢\h¦µð®ŽRöã -oçë÷¤¸Ñ^u¯LÇåô¼ë‘¡—–‰È/º¸ïr£ìu_ -¹ÊGÜ.×÷ÂÌ?áw…_«DP×vÀÊîúðMEi‰Í;èÌjêL¾ÓÍç¸×l£ÖJáðœ4ݘ$í$©QøRdàdzFaÆ -±aưö¤ûÐq#Ê õ;–>u ßЂÑȲ¨ûÜ î(x­Ô>|»zsÇöMïÜÚ ¡<£²€*¬R¶nè«jt¤g6ö!;¢nÖDJ®Jí¯/i·2»K’HŽc1äÄ¢):ÙØ^Ãô¢šù…Íí>ŒôkÏ\@¡fË yñ6“é‘úGÔPÐ艋ª£5nôXþ8…ZvOç kŠV7ûüÒ6'wÊÅrÒVrô‘àÔóµOoü@ ”Ç}žìÃ3_k¥Wn~— q°ê€Â¡NmHN¢ö.U¿_¤dNß9h‰¼¤‹8 @Qpù7Y^©Æž7RØ‘{ǵºÒ´±Î—ÄA¦WM¹ ³xûû’×*îÞ¡Þxö\(ž§/2Ÿ@\ꩉãù>#ÞÐFÕ³« iøMŒ”™?E¥´bC3%ê5îæ{ÓeR„Z )o UE4´oÆ :[qt ˜O¹èðuÙÎJ’ÔàW-º¤–yÃ*¸Ü,ºq ï7ô/fÁC¬F¤œslÂïJc–R‰¬È3†›…ˆ¸î*\ª‘nu”Íooˆ[í)0"Ï„äÜòR‚zƒi"ÖbhÖ“ ÀI8ŠeC’µ¦ ½`ò6¬¬ÙÈØ—Éýüv¼ÏvB¡¹†5ÃÌé—|5˜,óë··'{Ÿ$ÿ0Ø vYR~=2·NDá…Ü… ´²ðAC£´ïK‰ t¾ú¤ÅÊ´Uäfsä)_©ËŸ÷º1Ó—ÃU»»bî¯41Ê„ kÄßF(Ä -AQé}lß§‚>œ'Øoy=Û“õÀ!»šp£v SO`MÚ -ÂEdqðÏVŽ<[^/à•‚³mQB(ÉJ4åïPÓ%›ù5`¦—¼<áN]´ÍrªuÓD…8#¯U…ÑxšŒŸžþØë$@Ñrˆ ¥åpT_ç6þ3$$mýñmmòk ŠÊƒ!7gN?¥÷Ó -4“R¥VU»4¦^¡ËþõúB–üLJ#£·nγsl€tŸh‹P¢ÀB¯B¡1ÔÏ’‡’ÀmA8onTƒ¯üàŸœŸ™@©5Ý£ m>è|Ìãé$Œè8L¢äë×RõC™u´„î0a\*;­A° 0‰ì…ÀÏ?'ê=¤†CcÕ×ÇógEw{ñ§X<¬Ö«Î§¢¯‘Ö/¬+±]éÐf¾ë{Î"²Â.`W_‡—ú¸R2´  ¬ ÑßèûnȨ÷„W:È%¯Qý#?‡uÓÌá†8p¶ÄÖKê"“`t@ º^õÛ“TºXÔ+©eÝy,NÄ™‰âJcì³¾ýóiówh²i©1K½à#<í‹6uƵ(E -¬Ç¿Ñ¦‚¤E(#ÍËŽâ~qõ¥]ïãDí -zúÎ}™‹KŠcw|¤ªïhu•ëôSˆÆ¡ÐãË­„[ö:Ò-DqnFå†üô’êP>Âz^ʧÁÒÀ”¬Ì»›~–[T¸4عâXïîif%ŽE„óN˜¸þÒ:Í“dõ¡#d©ðº+†ðŠÊoFš{ÈY_5¡»$ž…Sr25Õ¼îà>Ó ë°+a“^r8Æz5³w ³„­JÚ%uàÏŠŒ²¥oŸP,ã¦8(+{(š\‚J)æ}kŒné?op¡Œ®_@U<º°4Êßo‰ÔYÞ<ìaÁ ŸMˆ§õcDÏSÆ)ÃêNiñZMEèG5­:—ÜüÂ.Ì{á¥Åu[R½Q0È›®iÔú#ÅU·@„ñ`lˆ-gb”Ŭ\ÏŽXIP'°(Gý³»`š˜º„€B@BÖ&íOrÒKn°Éއ{ûgÕ.V­„Ó á™ÔëuVO¹©’›¦ic{b¨þÈí‹5D«Í÷‘(L˜žkVADõ½mÕTŸÃb|kÊ"¯=^sfÉ̇ ø.Íþ¦úzƒ D?¼fd¥òCRØÇ”½²c+‡ò¼}ÌÉ? ޲69>jí™e›W"àùï -.^7=º6Š2#0 Ÿ“8uGzƒ)?&¯~Ó&Î^ma€ÐÎÝØ”ÉUk‚Ï]ûl ’4Já–‘—ªÖã¾ß‚•苈zN“Uæ§z¡Ø„ðcÃÀ4¼âeºsÂiŽ˜›ÈÈu"ÂXÐ MòÂàwB²Iê­Ã>¬qø´d†É¼•§Ç. m"£ûˆëDÊ!‘‰oRêS´½)™FÚêaÜ.¹½<ÙBý 2ƶðÞ+ôBƒÐ­¡+-Õ›3ãò¡5ŠÚR" :zïEñ>©-Óæ° Îg‰lL8y$º›³Þ%µÙJÏX9?ænµ‡äFóà–®Œæ4GÕ'‡“ç@µ-–ýp5i~Ìoãø†Ž…·r–½Ý¢_« -)׆þ®ì¸}Ÿð‘„¨ÍŽà”ÿâMµ3ëîDþþF·X#›Vx„¥Šš9—ÅÁ¨¢S@§¾Õ§+Öf.;™•óÛtÆçÕÍ&…¸eýÁˆQ³ý Qi†•hOr{jY%ÙJw¯ÂT„—lFt{¸ö81÷(Â¥…ô¶äÃÊòûb2ÒJ8cá”ˈÒbÁÀm¼J&­Z‚A -Õ!R3|´î|ܽ$uà×­GY‚œ æ{Âx¡  ~.œú&[qæfôð†hZ³O D_‰Ã`z™7ÊMìòMA•WsÕ [ž„væsÅÜ!ƒØ^ZÉ»‘wïFÞVeGò‚\l¹ÑS\Ÿeæ"þÌDnÚ‘15Nôz{ƒ¸Yów0[° ukz?¡Þì%¥ -Ü0†Ç/OLj[É|Z«×Ûž<Òí°4ûº ·Dɇvk5A´oã ÌtAÔ” -çHBžO+Ú‚ÄîóÎ"«g,Ç}õS?3Ù³”“´§+Ôö·V¥+ÂÜÖ/'Ên³÷^ö/€Õ…Óÿ곕µ°€ùÙ?"0ÁAÉÃ\(à-ŸÍ¹À/¾7mù±y}ýÔm“ýmùkìµ4#±$ß” -¢0ÓžœÇ‹·z´RÒCfwMÎ-‡Ý ’օʹºwvE:…n6OAÆR . ½Ã Kæÿ>©´‹™Ü¾hiÓn#Ç*ëÈÎ^ª ‹{n„œƒ|Q‹évÝ 5¼ã›ènB uv%ò9{d|ÞQP>CöŽŠß$qˆÒÊšÙ8”Ç­š¥«­u#Õ¸)«Û×¼¡ëSœiQ¡zJõÏA*tµÓ¦¤§ 3;Ûtès-|b~0~B-Z)ñBšª©*·?ƒæ–+[L’0o!ìÆ»UÕ‹B"Œ¾ªÏ5jdÝi·©dVéc]Ð[æa÷Ú(i³ ¿=ב;†L íu߆+YÙÔ¯jÒðoAs-á÷!Þ;ýÈž8íöêš«Î~à 0 À„ -Œè†²}­°[^­ÄÊ"+4´Ÿê°»Ç[èë+SˆR·sQª‰’ŠYHX¿™ïC6ñé|W$­µÈ¹ê1±£×Kì¸ËG4ÄÓ:£å9d8—f‘%¬-Uo—@~<Í‚¿<ÀÂ/OY„рƈŸ²7 9ÿFL!Ë·$À#Í‘»%#“ÂÏ®À!¼d^ûÉßì#r8ç7Ôs¹ùáÃ@óî¤D((§vL¼ñgà³wKKf8Õ–u±M„ ,GìÀ±„#†áÎ7n $\*Âä2Þ Ví/@3*Û¯¦"üÔHÏ Ä»Tm’k7ìècƒÀ¶oÝ…æpxVåÓ{'ŸÀVÏQ@Lv¥ày«§ ç-{†Õ#c¾Ùy·Gö=…lL˜ÀL[×nЩ2oY4êðÌûÖË•÷>BX^M4UÓvŒ„l0gz -ó½ýÙ ÍËF£jkN°3½WäfÜÁ)8+í':º/¨%²+žG%$Åw·í=¾tÀÜ~ÆéÁúäi*¨ÐuÙ>lû2{†X’GVM"¹ï§¿äØÞóŠ-I¦./q*#Ú-ÍÌûS­n®Þ~¿5f58O&Ó=ƒSµ@·ŒVÓÃܧçOPkÓÿ hÙ)&ÒªîÏWfzv,Þ6ì,Ïp¸êÉã7­ ‡ixÔÆ­SÆ;Øc¹}¤ÛUŸV¼ðœxç.»wQ~ßÓJ3CÙNcYB»Ñƒ¤3Æ›õ?­ÔæuÅXŽÝʇÌ®þÈ}‹b×"¼ô)ÿÆ;Ñ€¤ˆÍ -Ú‚+m.'ª®ãæáLVò ÊacL-À³…KË+@±ù~àI mªÎw3$‰/pKx÷ÛNìv þB ͽ2ÛÏA‹É]`Kmâd¹êuW‡¶oŠ\ˆ©/QÙî„„!'Ìqzî¿æÞ`rŒjéÒÍd‹ß”¥ -¹•úÑÅ0v ñ>R0Þ{W8ý34®H‘ó£îH±±­ -—0oj+tóH*ßj<šÊ¡ÁYzdÍ¿f1hJãg<+ïa??Â…VMQ·IŠ´Ö`ÁÖK)²jâ‚·8óK×… -t‚i]ÕܹQ7•¬¶">ø'2cq’ÅuE}sÀ£e9L&„MrÐ`yOCÀ´ó'{›HPO˜ÒoÅø8ì»n·Šš¹Î1è˜(]zš¦ÊÜ÷ŒDÈQ–Í’>¸iŒYñvÃ×LT%ù+0&—¢1BµUkæÞê«–Ì«l -¶Û2g§yö$®ö*Îæøe"'WèÖ£“C N1.-ÖsÛòQí5rJ÷ÛYAQ&¢V1R7Œ¾'NI,Ÿ*˜å~Ƶ”›~÷Úrò9!ˆcV†aCPµO;;PÝÌå³(t>ƒ ¯ì~0Óâ&ý¥tdW)T?&ÔzISÆ—µ Ñéô9óóŒl|—T¶·ô¤+NÓÄn“4üÑ«#éÜ‘ñÑÄüÁÉ֕aã_.›+A¯@™øêSÈ3•'üp‡IøÐÌySzùO ‡´æìÍ®¼Ck;ë2O3Ô‰áy/sT²—»ŸŸhŸúĈäomg…Zˆ­‰fº9ðþÒnjĹ.&i&ß7AŸÀ’\aö(±V­J¸ãnÔœm> ØŸ) þêy…ñålkMO¸éX8VEdàŸs][» NÆoñ3F_ 4å`}†v,ïˆnd ‚ì’ØªLÚB+;1‹h²QÀú·î´¢f)²kß8OÒ# õ:‰ɰ*NøG0Úðž{Ï·¸Gâ3]ÒB]ÝãŸeõÊUút–Zä¡ÛQ*He'3u}š&ºaVÙ0nÂ_å · Ø5Jæ³§Þ;R~&ôc5Æ¥:3…/ïì&Ó¢.AðáÁÎÆ¸ÃÄžR¿nÈ€¦ã~E2Kâèš”¾³klÌM"÷mkòù¶Bˆ)™öøï¿¿ÓIF{/õð·לuù[Š“‹ÜhV¥<õ!1QÏG)9ì(Å¥ ÒtM ËëqÌõþ¸]%tƒP]¦ûtàÆ&Ks:!lg‡€†)®7ì,èøÔ:Åaäæá·ãäQùÔò=•ÃýnÙ,×À­¼kZ^IºgàÁô.uQ³÷ },Œz“¸»•dA@{â^@±ÝƒžÅ&ýþ°Æ¹rVL*ç‹jïRf§ž¦|ú¦ØhwFjPÜ{tnã𠞸Â1LM‰ðg6þ>¬€ä¨è!³ßO’N·3PsÞvz¤' W›Bb×÷d•ª;ì;Ъ"j7Ž”‹98ô©å,³ÑÕ4ÛÕ-뀌éÂçË+[ã®fΠ´=5"ëO_Z§ÝQýJå÷# ;~Æ×:¦ùOuP2Ãþû9¿™Úã†ß°q¸D’!ˆñÛü"Np G“ó TI¹Düˆmu áê°q¤boówH/Xâ¼¹vbh™‚79}Øži• 0!5mù'p¸ªŒÍ-ÖЗXéçQdrîá•fè÷ëåÞ1ŸdŞΣã…ê(?ÞOCüUd;â±ñ.&- ÆÍ á©UÃ&ÄlÈQ¶œFWü ÊîG˜ç;!:XV†à Ž«¦g.šÆÌ" ƒâÝ`”Âp¼](G¦•|ªf?„ËÄŒjݬ~h2w|¶A™¿îÇ숚ˆ‘u #S0g0XÌŠo æ< ~°fC1å¹TËI€I¯v8ì{0®BôÂPœŽì>@;QÐÃ'‡³ †êÉ2$¢b(ŸÜ~¦r Ž}žjÈê 6G\æ«ëVáÃðšOD©h#Œir ~7úsaóÊÀ?Ô³©§²ÆÍ9Õܯ» -%*RŠ 8$ ²Bí¦®ä[D¥ªÝ«ÔGÆ;üÑh<®^‰¨´ÑE—@$|ûÈ89O\2¾ãw3ÆRæò…iŠR)ÇäN(˜$ âBd ±ÈÔ: ¤cCœšÒÅãE…É<¬)2@5ø.½’ë"¼ë'óMÂÛçœÌ„8 -БQöw>}N·>¢Z[@ß HÀ—ÞäN—÷“$wŽp»X0õ•ă<±´Áí¼sÎ*`<Ñú¶øAF‹/©=J^®üݯ‰TÿýŠCX k¯”¢vÈ´ªøƒßnÔ«Ó¨ ÉŽ:ÁCò®E~$œ-b™¶ëþto©ýB5÷ªF¶¬ïϾ¦´]çnÿ¾ãçz£û-&úiý½®€Q“²sxGûÑû¦I`¾|R$I‘õ\‹àX.áçëÑMdù ØGË7DÐÁ`lÈÒák‡)*¢mÁˆŠ‰£ä¾цëmhQ8ð™’¦;¦eP‰Ñ£EçòÎïZ¶úAI -¦£Ò턳`à*ùê™>÷)›td¾ñlË•]“î×=í -9l¿»YªjËŠÍa™°Tt÷W.™”Õ>/žú„ VݪdspÏ#¸îú§+^üƺ§h¥ÔS-b©\LÔåg› llª¦¢,#Un¥`ÙD2ïÑw^´îWƒ…jžÚòHƒ,ߣ4i´Ø$ƒšš4œ¤c„\œÐ9˜n³žK=F™•S'a&È6cS4 EV×#ž°Nšy’ QN¦]ˆ‚{4)gáŠÈZó±ñëÛ¢¸$¶§”tÖ©ç< K·fÐ2o„mê„‘iª:Ï”)Ðö¬ ×ø,m/@=ÉFËi‚tÖ²$Q."]å+&•²jjÄD™Þ}Û­n38e(Ö²õ²·™s,ÒõáÙĽëÃîñ¦Öà#” -, kÉ÷´éhÏ·.rLgâ×hž„—pZ??ÎË;@·aQÞ¦fÍ‘Á£˜ÁüÒ,_g+õÇDê–[ÖË`lƒÿmjC“½ µ‰¹ñ•«ßyÁÙUe°M ©P21=ÑAC6R²ãxÖ¢Ó»ÌiI˜µnþ¡twÙW|$Ø©Ýv;Œ4âcƒäy.,üôFÖm@Ë1›ÚÜÒS½V%¥ òN)®#ò÷~H}ç†/œ¶CDÞË>K†·Õ04 y\·ç¤Í¨ƒÎ¬VD©?qúÉ´K¿¸!˜Ù6t’m3ã˜B. -ÂJY†Z†ûš|ý4-¼©‡ôÄÖ/äNø&vL‰¸y)û÷oæéÆ¡s¨Fâ²JJ–à!`²K-TîÍ$\ \8fÇ®Ÿ™ºˆ¤]z‹9L9‘Ïÿö4ÆðÞ/Tþ&š¥ëÕŽÛîäHŒ7ýø1ô°’ë{ÇnŽrbÍ¤à„©7ëã!ÀÎ|#^ìñ›C§.Öçì1Ê"‰ >B÷‹=^Õäìb—bu/ÙÒXÄ‚™Oå§kY‚O)™:&Bç|i¿ôÚ¸rŽ:7q.8VJG±Ú–= -¼œggÍMÛR9éà½Ù»T¿Ø6žft»@ã.‡±v¸g8ËÃ7ÖÇËñˆùƒs‡@JE¢ ÌL‡²¾ì§£é-ø?ÝÉ8݇uÊ I·ï*"3 Ò÷ËVA¬¢Õ- ¡Z"ÞÆmU{/)tŽÎ›ð?KŸä~_†ÜÙš Ö¶lâ’¡n˲aþq+—ôú¨¤ë1æo/+žQTËq&ÕHdn„Ô¾u ˜Ñ­-ëMåÇ‘sÿÉÅ™[tœ¼¨øµŸÀÄíÞ®ßPx|òúËüá‘æ/¨-epsƒÛ;ʽQÊeŽÍYszgÏLf²Ê%—â -‡3¾•þ4¡´°Ç4s©Ó(œ#qp6ß ïȈLÞè¹xÌ9ÿ*Ͻ-+\NÆ"ìÊלý 4±ëè“B»5ýû/VQO‰Aüp ÈÄ@ˆtö·­ã*EÕV0µ¬7Vn¸¨bÍ[u?¹CöuJ4,Òk|_Ë­|Ïë2•`k”äÅhÅEdÔ<üÉgÁÛ{Ôrä5ø‹›o{Ÿ¬cy¯£ÓJ¥Ò/âðÉÞ28Ê8®9!úzÕP“¤¨x÷6`1©ÖÝ`¯îOzó€Xú8jvƒXq¢™°£»kÌí²¶¡‰2D¾ß•‰”uaôBAwõúà ‰¿ -€ÞŸ|æ`xFÎärãiwÍBÄt·Ñ9”kE‡-ñL¡•´]^`ƒ|ðv?B@ÕÚ,eç¼oì.9‚¿‡ú‚8ÛƒïûÝ -2h°Ø‹­ˆÓçBJ6 rD÷ öy@hÓ©A˜orÉbo»­]hdçb;é^ûxw^c»{$¯öw÷ª(:©]Bæ?0B¨Zt=qsŽ»_ý¾$UÎö×ÐíT! vMIöM»ªéKk¦øy"Óî“hŸQ¨¿tHg½Å#v³ Ë¢¹(^Ë×"F¸Cáß Úï~µÍO[ŸåÇ•ÖZ²Æ~!íg‚dö¯hÙ¿¿«ðÉ×_j¼ºÞÑñ¯EAåƒß€MŽ›_ô?¸M¼½Ñ¹t~ŒÜ+ì SVáu¤T…r©¡l®¥Uƒ0P;Þ‡™OØ~uLáÑwöÞ5gL›É+Êj/1ˆwv_›Æª¥µ[þ±žœh…{eóåa"ë‡u ™rÔc§®–ã¶­=üdxí†ã%û¡AUì÷È+×¼ Ô4ÞΔEÞ°•ÏØ„ç“ø¡´ûèâPz?¢†Ú mê"ìvbîdU‘Ö¾”ñzñj3¹¢¸j&ÁÄ~¶§‹»‘LͱZ -É5w½‚'☺²¡tg‚ÉGѺÐäQ`Æ9vÉlpúÿÖ§ÿ¢^ʆÁ.¸7%Ò` ã±¬Fœ}a<õŽÞµªž2Ȇ´h¶”RÒ`k‰ÉÓUúÞê¤/˜÷¢ú¹«É«¿ð\”)$q‘1)Ûÿ~3w¿,ᶉ:—ŠùÒ¬®ÊÊ€W6 Ù ƒé‡~ÕiЩ`’××»žÉ v ˜rGK/ÊBˆTJRÌZ[¡}ÙAöˆóÛ¡Ýå熫"ø`™Þ[þö‘±U1²ѵÀÈyþ¸ëhBØ…ÏÃÌQ)¼é‰e‹@Ÿª"´±³ÿ2ŸJÙÒe5> 9UV„ jTÔ׳4ašG}„Çá§œ5ÅHgQz>ÜØÕ"oÍ£i:,®Zƒ…[ªŸo[¿¢!cÝÛ)èu3oÁÜKÄÏ6W Þ¯"Ó  ”ÚðUAtE© ¿#Ibz£±'»PæÜä - !˜s¥8cs;ªÄj­ÌÜfºô#·Ãÿg:‘s2$Œ©ˆ×6'?^1„4=Wk¯^éßÈsê&Ù¸e;ìðìÐégªA¬½Ù¢vXþ]ïz¿Y¬ÍrôÞ= - Þ?”XÉÙTVà†Q¢›‚3=A(ÊŒ®?Ît??xnkà1›Ô›ÔÚ äŸA`ã×0滬²tôŠ¡Œ»*!ÂFë¾ÈÕÁ(»L lô-eFf×Å -§,Éù¾Nª„8’sޱ©U WSi—³¶,keõ%ï"‚×cQ:Á`c„†3p› Ò£ïט vv„_Y†)„A(@n`'7)$P²tJíòkÓp? ¨OÝï°¸>ózäö o"DXÓº3Êlª‘ûÁ†êÙKß±6ÎÀš9ŒÌ9‘ 寧«Ÿ#Áâw©üljœ]rlXÀfñêjéÙÖ ˆ¹œqwLLCÖŽ¯ËAŒÍƒ•è­0|¦·Ý¢fZ/Ç -qH {ÃŽÆ¡I<Ü“QvÏÍ ‚TD†¶ßûu|s˜ÙöoÜœ¼ •ÁáÊË—1™­.·óüe|î÷œzzEÝ³Ý U1d•1°Æ½™Ä<‚Ǩ‹Ç/œapbÑþ?íÌ÷?à3ÎÙdds_ël_ûÎÞ;33gwÈæì’³ÇÙ„ì2Î(ópvÄÙ+ -eËè2R¼ÄûÛûyŸ?à ·Cžtж‰ä€¢rªØt°W¨ÂÃ^Ã>\\hŠþ…¸­£éÝ ÓùÞ©e‚ & -ŒÙí?ÄSËÜ·7 ¦Mwv½ r#aCp ÑÁ¤»Ê«Z²â™×?åYó›j‚foM¤Ž¾ïhWò÷%Ñq.4ƒ5ÍÞóŒ®:žªFï€uI|Òxóstóår}¤‘(º…íOëËD›ïö0C³Xò™Ï­mtý#¿#/OÙÉU5ƒ|¦ðžË%åOŸ8+‡!ðÕÈïÆÄ»Þpi¯ÏÊ*ÓK(’èÛ¾½ÙR„n9 ½i3Í“~i/]L‰ÙA•+®ƒ¬-ãÐúˆ¿”X£Ôëë"M3µ°hónf;ñˆYþÒ$qW½ÒG_¹jcR2š×»‹7¨Š}r ¼áègJ?%Lë9bBú<–ŽÌ&f·´È’Mµ½>ºç|lÙQs- -Ï7û1'»öoσAü¬¸²a«Í¡K-é¢äþ{." xÊDï ùÐæI~˹G=Ö±?‚§>Èyüñ°“NÐ%îIß×µ¿è4É^)Oïä¥ç¾®ÁÉ’F°³¥1ŽžzÓ€SÚóJîi¸g_ ~`ñ›1E!ûޱÖ]Óhcotí¿AàçUpö„ß*&"-š{~gò&ú{ …rO]ÉOœ…È”[‰„î£-•;J×VAЊü$JJX&Ê×"é 5 -¼ØñÆV¼_±  ’™c€AÆ -€~g´¦™L#ZeöܬðrFVU -¨ì¿öžÓpÇ£†äH¶Õ2Señϵt(å¶õOÖt†Ò[ \„¢73}ñƒça-ø{û9…Ô8‚Ãõa8K<ªä-™£UÍZˆjzìɲ¦Omuã–‹ -|BÖÝB|kæZÄ@ºÛt7B5úÿü¥/Òµ׃1šòò‚Æû±®¸—ÜQZÖ¿S^©Àþz?§â7*¬UÌ‘Ž´Á9a¸|ø2DyúQZg‰?D[á4m|‚B–*õ¹÷kîìDRºÚ0„¾ýç–É­wó~ýØÒPÇü>? -»ë~÷aœ¿nïOÝp}ê#Æ)f’’¦„?BË`„ú ~R(hà'Ùç¾óì ØÉ»žOÛšù.»ûe<™“1êÌÇÒïÒÂfÔÕóÏ“¤òÞ!°(íTLÈÃÖ¥råúDÌ|–ÐÅ8Gä|}¥|è+ÏTPDpƒˆíJN5ª,»sa}èàÝ!/ÿhEî:±‰–ÂÖuL¥èmzÍŒÈ%áØß+pJ^‚…®Ù†V§óÕ7ƒ° 3¡‘ áâ9zU¯Ì…‰ò;é–Ÿ·(Nâ°­|&=×ÝÉEr4GîÇ4ê˽/Vñùén :,'劘ʕc(x^µ@$ÛL‰†¸æVìP¤ýÄJÍÏD{¤>pV$QJ¬©ô=˜Ð9 Úp€Õâ«ùD¤å0ù_‡b>éRêVtÃÖ ÄMd~„Ýl{‚òsÉÞ! 5õµPÓÎ!ÓêÕ±·ÍˆoÅï$ø4÷µ£e!Ó†R©û,ÞΦbކlŠ\›»ÆÈì\Ùú$Rk=›‹Tö° -Úð­,6äX€qÐ-}nJ®k^¨£ô@l€¼ÜI>Œ˜×TqÅOшتxín°úâ…õµ4JÌäÅV kw¨Š‘þI’€¥¤\°^0Vò˘íep«%"h* ê mQôB±Ýë“ÙÏXšEÿ¶Éµú0üöA•ÚªÏPbÑËöê6EL7‹:Æ6ÒpÑÁå»ý%Tñ4w bBY6Kn8¢slG›‡œ .ôˆdŸ*‹îí¡ï8‚ìu)+¸"xJmKM Û /û’oË3ÌkŒÐ‘ÜãƒÛ’ÍËïÌk‡;/°¿‚ë’àU¿n¦NÔí]…6sÍ£¹ÛÉi<9s„pÓ4ìЛ•E÷³¡{¨Î¸›Ñ(@£ìª–8¥C©·g{foU>Ñ™vù¨µ«IÈÜÞPœU›K)ʶZQýmk ·çƒe~cs3˨Œ°2è£ßÕ ¾ÄùNs´Añ,ù¡H¾…¼ÀÅt••å;: -œ•F“þ/Eň¢M—íîÒX =r‡K—+hö¦­y¢–éx>39+¥¸®¯k"½…Çl÷ÀJí„MÚÜ8ÁYËÜ&F¶”´Ñnýó'¶±_t¯…´²ÅÕÛ¥ ¼”žŸö8Gojü=ã6ÀçÞ}IP†C?äy¹l÷×MÜ 8ºSJ§Y´%$<-ãw¼S9ðJU&t ŽÞ[™#ÅÀ½5‘µc§O&QNðoMÂM/ …Ìþæ2¼`ÕE”n¼]QàѨPØÅA9TM;x¸á•3O‰­X»ãÞä»ÎúF_s„"oêoì9‘ö-Z%×/ÌÓÀ¨LÒ¬ŽÇçDrU‡¿ ¶Ï­š6ÞxÓÂï¯Å÷†½®w~¿Î~ÁX0nïýe´Ý&¤„’Wm»Š)Ôšë2ÒÄ`ÇŸ­B¢ž}dMÞ xì)㟂ñU‘dIÂçÍ Ê>`O‹5ö7ÕKõ 5ñŽ£ÓÔ‹Á}äIZ-™óDZ´[ŠkA,è3úI—ãq­«E2·:±AÚJÇ‚p9lrEèp¢V —2JÙçï£)m×·ÇѾ&\!H !Wuy§|õ ¸ýkI±3ÓËôì ünŠÐе¼J§UÇ‘º;Ë÷Û\»#QÆ>‰E¼ßå îÜôÕ7;w“«)½VM.òHfÜ7$fÒzVÒþ ®:ëÍ©Û"Ä%yF#u»¶b1:î£Î¦Ð¦ºwI§âtß±.bïö:Áô|š·!/ä‘×…lEŒ];\PâéƒÀJ-†ùfï\gX?ÚÝbÊâ¼q#°È™JZcvr›”)\MUŠÿ½žØ«R#óÞ*{OÙ¥òó£SØÊ3«uS¥Ò+¦Ë?:ô$±ó4£º‹Õ±™o °Î³d q‰ÿ|¡âWV¬I¾ßxo¦Ì=ˆ4Šž%,²——Tí–]x-«GU}¡:¼@šëäãÕô´:+VfÀiIÆx†‡Ë2Ë–„\ü_¢øð?¸ùº»Áý\}(þGªßendstream +ŠšRòJ y5€Ðè`hPtþien57Ú8©&¶«F¶6Ææÿ´æHÿKÈ`p´™ÿMºíþqÑì€Ö掎¿æŽSC§¿3p²˜ÛY9ÿCà¯ÝÄö_„ìlÿFXÿõýS´utr4r0·sü­ª(*þožNf†NÿÔv4ÿëØšü4¶5rþ§¥ùþÂüõ:šÛ8œ€nNÿÔú ›;ÚYºÿ­ýÌÎÁü_4œÍmLÿ‹-Àhjè`lttü óûŸéüWŸ€ÿ­{C;;+÷eÛþ+êq0wrZ™ÐÃ11ÿ­iäô·¶©¹ Ã?‹"ecb `bü·ÝØÙîú\€ÿå?;Cõ—„¡±­•;ÀhÇ oëô·$€òÿNeúÿ>‘ÿ$þoø¿EÞÿâþ§FÿÛ%þÿ{ŸÿZÜÙÊJÞÐúïüûü}al²€Þ+C‡ÿW¸¡µ¹•ûÿ!á?5€ÿ&ùÿ#ådøwB6¦a¤gü·ÑÜQÜÜ h¬hîdd01´ú;©ÙÕlŒVæ6À¿Šþk˜:&FÆÿ𩚙YÚü3z¶»€6ÆÿIþ¯Hÿ¢Î §©%£®IóŸoê¿¢ÿjï¤ên÷—ØÿhEÎÖøþÁ¶uxÒý½tÌ,ö¿9™˜¼ÿÕþÃô_g9C's7€öß–™þÕøÿøý×I÷?`ÄlŒlÿÙ'Cã¿ëõ¿ ÿ¸œþªú¯ÿ·áÿyþ×¢n@#¸Õß¶Fö¥©F{1­(zR€—ùøÞ$T}¨›ä4 z%ˆégQžW‹²ÛZìŒê»“JÊzÅïPß§;X`®ž¨üH\ +üÐIí|ŒRëc1:QA¾Õžž‘'?=R Ž õÜ@öíãÑäÄÂ’ñ¸@ ’GúÙçà h©Ux†SA¥7!àÝ´_}jt{êå‘‘â’FX˾*šæ¯Ù´Ë¾'A¦· ð&Ê9H¶îWþÀ¼žŸŽäJœæšËýZw&sÄâmŸ +쿵$ œÉ„®'~»¦ìw 󬵮¦~íCÊ]™Qê,©wmÚ'c¤ w®Diµs$óÐY–1¾—f‡ÙÄ&>.jüäë賬9“5ÎÕu¨ÍÄV¤?m=Á8ib/4l¼˜’lºÖ’Ÿ$):Srïð¹ŒtéÇ#/sƒydŠü¡ _•vÏÐX¢ÖÙ"» ú”4Ú]Ô†Üf†·”-FêÕˆFG‚„ùs!kt> +j8+¼="HOló‰à|V”LôIŽÅ_y·1A‘T5dSoEy%|Dm3N†Á‡P¥{ú¼ÞÆÙˆ +šÔ0ã#¢DËFwˆ(¤ ÙÓ§~¾f%ž©Y·˜"<Ø™Él¶‹Ç¹ÿúä2Ý©²HˆîKöÿ¢Õê’2|Cu˜Äï4‡ÙbIYY`AýÝ«!ðc* w¡)óÊ~#†!åÌDйp¼šÖ™(bðÆ%łߪÇ4òsœ.劎^Ëú0ª†'> +dÇ$[ß4˜h3iï*#§†]Y·6_¡$l¥—\5Š´ +ÖƒGÒgÏt7êz \ÄØSÂèÑÝá Kz¬Å~»šF£¦s>y{­)ÕCóaÑýû²Ú7× Ý#ÓF¾o¯Q2v3äòÔן¼xÒ¾#x9s¬(ÃÇÊÒ÷öUX7Žqb‘ŠŒHö;QºÙö³ˆÊëí:²5p,sÍŠ˜VÚÜýXQý3j .jWô…¼¬[Ç2#oîä2’«²6¢£yé0O ÙÓËø8³)Kz¡l„ïzä^骟|‚gOH)àY îó¸¢e¾,Ùê›Ì,ðŒ‚þ²Êsźy&Ê⥄ñϤì*“@bKiyäúk@WÁ»¾/ÿë÷îÆ5 Ï##êáù@¹‡ŽRƒ;ÇË6ÈV|¶å9{<)¼ç QU+󨉬@"9ãå·¾9Ì-–†Æ¬»î³ØŽÈ³¼…„e†t Y.ž±áWËÔÀ;žš¹„PfÙWÐBNûŠX÷a|nÓd5ÕR©¡Ûo÷¿]fǧ_$¿å0[^ž‚IpƒVzrEÄsÜó^Á¤ÑÏJó„½Ë®Ïô—qŠž€3«Çþt¿ipôøÉ¼ïÆ/ÑøµÑ7d™§©M’°{<1†/ß{€"Ãg'”Dnnë«J0 VkÜ„},j6ä²6”ª ’nå'Ž`gâ[ö +õ Ò””d³3þˆA*ú<ì;»ãçëȈÏÞr‘U¦Ξƒ ¸R64yEIÝ#ب[@“4ÂS»Ð¯«±÷è(pÖg/ä/ÄX»ÐÖ@­Å»b¾äcŠÅIî n¿¿„îçç3Ã"çU=^ó»\XºwV¯”¡ûB:Ï‘ +[—ÒØ$ ´zEø}:µ`s(éHô‚Å+X—³÷¶*5Â^ÁmøÆÊ$¶ïÉéGH +>êò:Û†ç-àñwN‰ +3“7º]Ç }"}xt¿-i7Ÿè¹½‚• +üƉ¾ÏÑüІž@S&_#‰= ]Œ% ešPІ¼RŽ”oQÈJt{¸œñàº0ê8&ò½A"zXXª‰„^i$º@õÁh0škm}…“u­@îK/²OÊ\®zOóu#«"ùÈR.¯AÇ„ŠòÙôÐJ©4I°muþ`*?섨0­V2×~„/ŽZ.&òÂ×Ñ_ݼÇa)¼<¯l ‹¤ab˜wK¿ð[p…*¿–ªì˜F°_z¡>ôÿ-p¾þmQÌHtðFЇt½® ·Ð[Cr:Îæ'w|…ôSoñ;ÕdȇkM*a1eˆƒS¢ß%!¹J-¢¤tXäÖ’´–šBÎuÞ/ +p‡÷/ó¢nD(0ÂDã ,q®R5Î@¨)µŠ ö|÷ò¤ºÛ\{=÷5¯ãƒ8zB uyÚ£e4O랊u¼z.©2Êqi¼ûTœ°,³Õ¸¼[¡~o$n{Ìq³¦×·1åŠ|…²Ï!§-4`f‘ך¹ïPÛ¹Ui«í!3ÏpN"LnR‰ôAQ“!ÄùðíSÆŽËî1ÕÔ9PƒoHT7-÷dâz7/ÉÐ÷3¯vU~2‰áW3Ýk"XŸ&¾L;Ï´Ö¾s°˜9¿O'`u?‹¶Ôi„ØCBs®Q‘ô±…ñ"¯Ïæ˜L#ÈÝœÿì UüÒ¹ùeŸáS©Ù_§Ó¢ªîÑ _e(ò~ ¾áÚÈÙ¼ßÕt2ƒÄI]Õ× Éuûͺ›WV>{€º^7¬K·ƒ9@3¤uÜq¿¯ØŒM(ÕAfW$ùÑ>Ž¢róÕõ'Üt*®IkÒæ·&„óÎãÔ£yù„2¦§äº VБÇ/êÀp4¹‡èT›ïwnÚuŠêæÔgW«È$&¥é®&tÏ„ZgqÙÇCȇŒ† ßðéårüc­ŽMÔEÇ×çÔkâÓåLÁG1‹^­?z&É ¢2™"«….^R,• ÀÜ ndAU]l$þôº<¤q Já9 [Rèç+œ„$E˜b…†F΂dù#ÕÒéËYûV·"r†Š}cà’³$#QZ0 ãû‡H„f¡ª÷›v«±*øöç9êž§Ç)$¥!€4%J)Æ«B¡(kèè^«£ Œ¢K"ôŒÖIQ§.¾É°UDBó€â¼HÛHzõV¢’éç5柑&xã>fé.j/O§Î5$8žÔÎÅ òíʰ¿_ëqv–'´#zÑÚfs +[Õ%:P+t¦*5Gil@ÐvmY‘ ‚œÁ‰~¦S JÖjn5£ë—ðys¬Ø0ÒÉð¹¼tOC»¯‰æ÷­™ÄiÐDX¯ÐåpÖïÆÎl¶TS†ffe2·©iB>²ˆÜKmV3 ·ï¬I‰Àq>ü€~y ±z‘ô&VQ|!æ 쨯tàZ…)"¡ ?ëzÁ4%vïù2<€ºµ—ÊŠ¶ÍìA 6häæŒ‘ÿ>„ŒÔxZÜ5&R'!Ö§•gÜ…«¢ú½s’+ÔCÐ[ØÄx›)½ºo +Ù¿®;ªôŠD™r]9@èšÌˆ“ÖS|æ[Û, ('|f¤~}Ã!Ónëw¦©®n”Š\8ÖgK½Uz:'=*"Ô›%FWHO´­Ú³ÒèÒõÖDÐ_|ÌÎ\ê\Û +qá‚ú a¾ýGŸºî“•e +™âîÑ~)Ü“U‚™$¹ß“ñA=‡C“ü‘:³œW•Pv Æû§hbÖ¼ð»AàlmoÎUÁùË7…¹í \~3È +ÂÏå±äÑs‰TNŸ +Ã<ˆ•9O¶¥fÈËDˆF§‹ÑÉöY廙l›¸·°6¿33ïáð\1ôb° a÷ Á{ó|³m«é*Ê›}½"é?Yš,µÔ¹‹ e§úPh‹ŽŸXEô¸º\©çÜ[ëgøV3C^à ±çSø¥$š ƒÛáÃ:“É»®’´ ð¾ˆïÅ^ƒÑÁ´‹¶ù´ë¬†)à!jáìKøGR~ŽCkCœùŒBΔí!$ÐdÕˆV`¨­\ ©n¿»Gó§æHðnê Úïvœ&ëÌŠ":—íÞÕ^"Æ;bÊz³N¾0UÅÕ–ûÖ1ÃÁ,Ծ㢫|7ßoV};º:Mý³éØc£ôÂà¤=™MhüCÔgaì‘7¨²Âˆ±b®5_¡·¸/ H:L« >r>Õ²"™y£6o„Aù±RQ ¼“_;N\¾L©µá%7¸àÀ‘¾g$µc [ž Ü80›=~Øü.¥T¿†ñ¥™^šW`/ž$8¢%S>ô”æý XÞ$'ñ.ά¡¥„2Éÿoƒã;At«!Äò‚´žÖ&\Åžã™dn£˜kjÓ¥³< -YRç˜oiæUìÚÆ‘ÌY Kî%?ê5TXrz¶ë[È/¨£=gU0‰Ü„€UShW´1ûºzcw™>ÔXê1§†S\»²3Š‘ÎBaʉ@,ŒëÂ?/ßu3u¤ð;…®MXÛ;Í0¾z“ƒE9–T¨ÕÖ[x,ÐÏsô1Æ÷Ìó–Q£×©VNcÌ…ËrÖs,¨ ³“eeµ‚l€N0j—;î~÷–ê2›ZoºäÆ JR¸¬ Ý.nìÿ¦ÏR(šF½qqIéì{7¸–lƒ%Jåíi6.’±ñNJ„µ­~d¢Jă÷^Oß«Ñ É s!¨kgw%¼¤ó_†©ë +??zÜ…¤Ÿ'PìE¶e6¹-Vƒú£ò>áÂPe†–½Í•Gèf5©{AuÔ¦JÑø^V¡ÌP +:Ù‰4GÌCe*Z­:?ß"íÖŠS$`ë¾*~=QîFf†£¾d5 ?Užaú9v¢÷"“T!KÈ õð;[ùÛCµÛ²Ñä$|É•ÿ#]±·,ÄgåÂc>t- ƒôÏ/c!Ö’&,î—AØ$l‹ˆ4`¿Ì™é„G ‘9h{±I K­àôáî·3ÂF£Ýйô±Peûw + 8ø=ÇC¦ñÙ"ê®ÒL¨ì:0%»¸vÕ´HƒŒ?˜ø¾âù¢õ3™VF _?Òí)Û÷³qoTŒ²>ô£‚ùvî[±~á+Ó ñ¢øøhÂ…ª>çV©Ã{‰iÜÁɾ,ÓPhF°1J4‘÷Ò.’×l"üˆæ ¿D9TäÝ!°hjky~ÒHTòövd@X|A¼ —Õò/²áxxûfÙ z¸|ÁV§Om×¾SD*gi[‹4i p¯—ðƒ½ÐØv )ilPcΙŒ€~9¤Í^-P>½•Sø¢ªÖ_Ñ:v}¼ú‰ ø9#}hçp‘à;‡¾¢~¶&í@»Âªž$ûòYéØsE6ýPÈ¿Dpñˆò϶J úy·#“Ø'PG ‡ãŒY9ÇçzÖïIE ç©_¿+Pììk.Âî+çpnT+ ±µÇ1*#Xd4-.¹.f(܌̠n{Sš©|ãPtw90¿Ì§­ã=tÜr•xÿ’Yñ©Õa…@.i¾™?#E¬4*872lºGÝ›ü”òóÕƒ¹óšAúa§¢+lµh ›¹cÿ[ÅU‚·_Q'ï–íMÇ7&U6æØ‹{tÍ3_ŸÔ_óerˆ$q¿E½â>$zr,¾.ÄBËëDÒ‰ú@û‡ÍDü”Ä­wPL+w1xàKDTjã_žKU÷‡Š¿÷ðN€úè±=©C; ]‹‰ØÑ\z©r¸úÕ~ÈK*¼Æf:²}䥳ý]°¤Bu›B<+2¦ø¥Ø×Iÿ§½²¿S©ôûü¨·zM­<ƒïˆn1•ùu›Ó÷^Vú#:.æ?¿yÙž®ïµá§ðƒ£|`q^ Iš©åâ:kÓãZFMd§Í‡ˆ¨><…÷Å4I)'16TØÍ†Nß°`‹ð` [€r óz‡ÅÜl8±§ ’¹Ll[@Æh_ëí; Hk¢ÉjLÁf'‘Ö%З&så@µTýb[Ojöß 0®šm-Z‡µ<"ÂVç­wSp#H¸Í°ÿ,3L\g*±Ý¾–Ýçpg¡’^uІªH%a€ÃuQlàÎZK‡B£vHÕqe·lAW`¬úÑ–îxüFÁޏ“Õ7º¼Î IhB($y{³ÓËòMSô~¥ã # Z|Ѻ6Æ×c>ÁB’Y”ï‚*¤ÓµEkèið„ûܲ²ê6ë#¥ÊxNÛµqqŠ®k%:ЂÃÏý0{Â4Û¤8¿ŸJØTá‡ð~UâjçµDg,Vå|ÌÙ)îmÛ ÁÎ n$;ùâßÎWûË)6{ô2÷Å1§ßÿ2_Q.4ÓZxWG)ûqŠ·óGŠõ{RÜh¯ºÎW¦ãrzÞõÈÐKËDä]Üw¹Qöº¯G…\å# n—ë{aæÆŸð»Â¯U"¨k;`aEw}øŽ¦¢´Äætf µŒu &ßéæsÜk¶Qk¥pxNšnL’v’Ô(|)²FðcˆÇY£0c…‚Ø0cX{Ò}hƒ¸eÐúƒKŸ:†ohÁhdYÔ}îw¼Vj¾]½¹cû¦wní†PžQY@V)[7ôU5:Ò³ûÑ 7k"%W¥v3<ú[j¬ån–E¿kƒœm»ŠìŸ×—´[™Ý%I¤@DZrbÑll¯azQ?ÍüŽÂævFúµg. P³e†¼x€ÉôHý‚€#j(hôÄEÕÑ7z,œB-»§óÎ…5E«›}~i›“;e€b9i«À9úHðêùÚ§7~ Êã>OöᙯµÒ+7¿Ë„8Xu@HáÐG§6¤'Q{—ªß/R2§o´D^ÒEœ (¸ü,¯TcÏ©ÆìȽã‚Z]iÚXçKâ Ó«¦ŒÜ„Y¼ý}ÉkwïPï <{.ÏÓ™O .õÔ‚Äñ|Ÿoh£‹êÙÕ†4ü&Æ ÊÌŸ¢RÚ±¡™Hõš‰ wó½é2)B­…‹·†ª"Ú7cHЭŽ8º̧\tøºlg%Ijð«]R˼a\nÝ8†÷¿ú³à!V#RÎ96áw¥1K©DŠŒ?VäÃÍBD\w.UȇH·:Êæ·7Ä­‰ö‘gBrny)A½Á4k1H´?ëÉà$œNŲ!ÉZS†^0yVÖldlƒËä~~;Þ¿g;¡Ð\ÚaæôK¾L‚ùõÛÛ“½O’l»,© ¿™[§ +¢ðBîBZYø ¡QÚ÷¥Ä:_}ÒbeÚ*r³9ò”¯Ô¿åÏ{ݘéËáªÝ]1÷WšeÂ…5âo#”‰Nb… ¨ô>¶ïÓAÎì·¼žíÉzàá]M¸Q»„)ˆ'°&má"²‡8øg+Gž‹-¯ðJÁÙ¶(!‚d%šò÷F¨é’‹Íü0ÓK^žŒð §.Úf9Õºi"‚Bœ‘תÂh‚0æ£Þ·/Dž¿V™¹6j©Û̇‡o— +_0ß9ø™Ü®Á³@3&i ¯)BBD‚Òr8ª¯sÿ’¶þø¶6ù5EåÇÁ‡›3§ŸÒûišI©R«‹ª]S¯Ðeÿzý!KþãÑÑÛ7çÙ96@:áO´ˆE(Q`¡W¡ÐêgÉCIà¶ œ7·@ªÁ×N~ðOÎÏL ÔšîÑ„6t>æ€ñtFt&QòŒõk©ú¡Ì: ZBw˜0.•Ö +X˜DöBà矉uƒRá±êëŒãù³"‹‡»½øS,VëUgÈÓÑ×Hë‡ Ö•Ø®ôh3ßõ½@gYa°«¯ÃK}\)ÚÖ„èoô}7dÔ{Â+ä’רþ‘ǟúiæpC8[bk%u‘I0: ]¯úíŽI*]¬NꌕԲî<'âÌ€Dq¥1öYßþù4ˆù;4Ù´Ô˜¥^ðžöE›:ãZ”¢‡ÖãßhSÁÒ"”‘æeGq ¿¸ú‚Ò®ˆ÷ñ"‰v=}ç¾ÌÅ%ű;>RÕw´ºÊuú)DãPèñåVÂ-{ i¢87£rC ~zIu(a=/åÓ`éÇ +`JVæ€ÝM?Ë-*\šFì\q¬w÷4³Ç"Ây'LÜi æI²úвTxÝCxEåÇ7#Í=䬯šÐ]ÏÂ)9™šj^wpŸiuØ•°I/9c½šÙ;ˆ†YÂV%íÇ’:ðgEFÙÒ·O(–qS”•=ŽM.A¥ó¾5Æ·ôŸ·¸PF×/ *ÝXåï·Dê,oö°`ÐO„&ÄÓú1¢ç)ã”au§4‚x­¦"ô£šVKnþ?af¿½ðÒâº-©Þ(äM×4jý€‘âª[ Âx06Ä–3± ÊbV®gG¬$¨ˆX”£þÙ]0ML]B@! !k“ö'9iH„%7ØdÇýý³ê«VÂiH€ð‹Lêõº «§ÜTÉMÓ´1=1TäöÅ¢ÕæûH&LÏ5« "ŒúÞ¶jªÏa1¾5e‘ׯŠ9³dfƒC|—fS}½Á¢^3²Ry€!©ìcÊ^Ù±•CyÞ>æäŸGY›µöLˆ²Í+ðüw…¯‰‡›]E™†ÏIœº#½Á”“W¿ig/€¶0@hçnlÊäª5Áç®ýF6PI¥pKˆÈKUëqßoÁÎJôƒED=§É*óS½PlBø±a` +^ñ2Ý9á4GÌMdHä:a,h&y að;!Ù$õÖaÖ8|Z2ÃdÞ‹J‰Óc—…6‘Ñ}Äu"åÈÄ7)õ)ÚÞ”L#mõ0n—Ü^žÇl¡~c[øïz¡AèÖЕ–êÍ™qùÐEm)PF½÷¢xŠÔ–ŒisØ€ç³D6 &œ<ÝÍYï’Úl¥ç¬œs·ÚCò£ypKWFsš£jƒ“ÃÉs ÈÚË~ +¸š4?æ·q|CÇÂ[9ËÞnÑŽ¯U…”kCWvܾOøHB ÔfGpÊñ¦Ú™uw"£Û¬‘M+<ÂREÍœËâ`Ôщ) SßêÓk3—ÌŒÊy‰m:ãs‚êf“Bܲþà ĨÙþ†¨4ÃJ´§ ¹=µ¬l%Ž»Wa*ÂÎK6#º=\{œ˜{áÒBz[òaey}1i%œ1ˆpÊeDNi±`à6^¥ +“V-Á …ê©>Zw>î^’:ðëÖ£,AÎó=a¼PP?N}“­8s3zxC4-áÙ'Ð@¢¯Äa0½ÌåŠ&vù& Ê«¹jÐ-OB;ó¹bîAl/­äÝÈ»÷ #o«²#yÁ?.¶Üè© ®Ï² +sf"7íȘ'z½½Aܬù;˜-Ø„º5½ŸPoö’RnÃã—§cÄ­d>­Õ‚ëmOévXš}Ý…["äC»Îµš Ú·ñfº ?jÊ…Šs$!ϧmAb÷yg‘Õ3–ã¾ú©Ÿ™ì‰YÊIÚÓjû[«Òaî ë—e·Ù{/ûÀjÂé‰õÙÊZXÀüì˜à äa.ð–Ïæ\àß›¶üؼ¾~ ê¶Éþ¶ü5öZ š‘X’oJQ˜iOÎãÅ[=Z)é!³»&ç–ÃîIëBå\Ý;»"B7›§ c)Œ—†Þa%ó‡ŸTÚÅLn_´´i·‘c•udg/U†Å=7 +BÎA>ȨÅt»î„ÞñMt7¡Š:»ùœ=2>ï((Ÿ!{GÅo’8DiåGÍlœ ÊãVÍÒUŒÖº‘jÜ”Õíë +ÞÐõ)δ¨ŠP=¥ŠúçÇ ºÚiÓNRŠÓ€„™m:ô¹¾@1??¡– ­”x!MÕT•ÛŸAsË•-&I˜·ö@ãݪƒêE!F_Õç5²î´ÛT² «ô±.è-ó°{m”´YÐßžëÈC&ÐöºoÕ¬ìêW5iø·Š ¹Ž–ðûï~dÏFœöN{uÍUg¿a`BFtCÙ¾VØ-¯Vâe*ï@ì @uòQµ ä8L°4§2Ir©¶Ð“†¤o§¿Ù §¥ëÁIÆtPÕ'ÆiÎâsëŽÉÇTЃF`Þ™0Úu­5hJ»½ Ù‡,KíÜкÔP¡f|éO7§Hf|dÑr^kç Žß¼¥'@>¢íð@‘…„—Ä”ÄÄJÄÞ¿Ý>3„Œµ¬èZˆ›Ù¡R^XÚ9ÈÍjÕy0”Nš¯s„gA‚îWˆ™[Uú £™2õÞzבl‡KØ6`ñ +î†Å×°æËùß'™+¹O?àªH‡q@…ÑQœÙ–l.vk -3Ô+¸Gç Q@CX <¢â*î>Ö‰?7ëÝSY±ƒ°±÷a~ü¨=j ºíd„¾‚þÔ‘"Ød±ÊUU;•ÞÆrÝJéŒ$AøZ©uëÎñ³‰W´Bšgûû±wæp'Øbû5莵Ë#—½ë ¿É¥M!¹q¼V@«ßÂ=¼8жœÃñ!r1†À`^6]ÈÊü«o†c\'7 V;:šb˜€™Sì +…eȤ½øÛ ]Ûq};—¼¿ý%W[J¨÷¡¼–Þè aÁþ[Ò-@^ŸFðGH¿ ìÏÈܰ<·eÕ@wô¨‰Îy«(‘«xd;{”«‰U¸otÁªDÕL +˜ªˆÍ|Îóp—aÜ^§9Lî÷‹¥¨`=1OþLˆq‡p–*ÃsqÇwŸÚOuØÝã-ôõ•)D©Û¹(ÕDIÅ,$¬ßÌ÷!›xŠt¾+’V‚Zä\õ‰ØÑk‡¥ vÜå# âiÑò2œK³ÈÖ–ª·K ?žfÁ_ ž`á—À§,‡h@cÄÏÙ›‰„œ#¦å[àŒ‘æÈÝŒ‘IágWà^2/Œýäoö9œóê¹ÜüŒða yƒ?wR"”S;¦ÇG^ˆø3ðÙ»¥%3œj˺Ø&B–#vàXÂÃÇpçŽ7†.arï«ö •íWÓ~ j¤gb‹]ª6ɵvô±A` Û·ŽîB s8<«ò齓O`«ç( &»Rð¼ÕSÐó–=Ãê‘1ßì¼Û#ûžB6&L`¦­k7èT™7„,uxæ}ëåÊ{!,¯&šª‚i»FB6˜3=…ÎÀùÞþì…æe£Qµ5'ØŒ™Þ+ò@3îàœ•öÝÔÙÏ£’â»Ûö_:`n?ãô`}ò4 T躉l¶}™=aC,I‚#«&‘Ü÷Ó_rlïyÅ–$S—‡—8•í–æ æý©ŠV7Wo¿ßγœ'“éžÁ©Z [ÆN«éaîÓó'¨5ˆé´ìiU÷ç+3=;– ov –ç 8\ õäñ›V†Ã4¼@jãÖ)ãì±Ü>ÒíªO+^xN¼s—]Ž»(¿ïi¥™¡ì §±,¡ÝèAÒãÍúŸŽVjóºb,ÇnåCæWä¾E ±k‘ +^ú”ãh@RÄfíÁ•6—U +×qóp&+yPå°1¦àÙÂ¥å Xˆ|¿ð$6Uç»’ÄŽ¸%¼ûm'v»!†æ^™íç Åä.°¥6q2Œ\õº«CÛ7E.ÄÔ—¨lwBÂæ8=÷_so09Fµtéf²ÅoÊRaáÜJýèb;†xŸ)ォG œþW¤ÈùQw¤ØØV„K˜7µºy$•o5MåÐà,=²æ_³4¥ñ3ž•÷°Ÿ +áB«¦¨Û$EZk°`ë¥Y 5qÁ[œù¥ëÂF… :ÁƒN„´®jîܨ€›JV[‘ +ü™±8Ébº¢¾9àѲœ&Â&9 h°¼§!`Z„ù“½M$¨'Ì é·Ç ˆ‰b|ö]·[EÍ\çtHL”.=MSeî{F"ä(ËfIÜ +ˆ4ƬÆx»ák&ªˆü• “KѡڪƎ5soõUKæU6Û‹m™³Ó<{WûFgsü2‘“+tëÑɇ¡ˆ§Ç—–Fë¹mù¨ö9¥ûŒí¬ ( Q«¿˜?©Fß§$‹OÌr?ãZJŠM¿{m9ùœÄ1+ɰ‡!¨Ú‚§¨næòY:ŸAÈ‹Wv¿ ˜iq“~ˆRŠ:²«ª j½¤©Gc„ËZÐètúœùyF6¾K*Û[HzÒ§ib·I þhŠÕ‘¿tîÈøhbþàáDëÊ0Žñ/—Í• W L|õ)ä™Ê~¸Ã$|hæ¼)½ü'CZHsöfW^È¡µ „u™§™êÄð‰¼—9*ÙËŒÝÏO´Oý bDòÎ7޶³B ­DÖD3]‰xécFb\“4“ï› O`É@®0{”X«V%Üq7j·6Ç„ŒìÏõ¼Âør¶µ¦§@Üt,«"2ðÏǹ.Š­Ý§ã7‹ø£¯šr°>C;–wD72Ð AvIlU&m¡•˜E4Ù(`ý[wZQ3‡Ùµoœ'é†zDŒdØ'ü#mø Ͻç[Ü#ñ™‰.i¡®îñϲzåª}:K-òÐm(¤²“™º>ÍÝ0«l7á¯r†Ûì%óÙSï)?ú±ãR™Â—wv“iQ— øð`gcÜabO©_7d@ Óq¿" ™%qtÍGJ߃Ù56榑û¶5ù|[!Ä”L{ü÷ß_é$£½—zø[HŠëNκü-ÅÉEn4«Ržú˜‹¨ç£”v”bRŒiº& åõ8æz Ü®ºˆA¨.Ó}:pc“%„9¶³C@Ã×vt|jâ0òFóðÛqò¨|jùŠƒÊá~·l–‡kàVÞ5-¯$Ý3ð`z—º¨Ùû…>F½IÜÝJ² ? =q/ ØîAÏb“~Xc„\9+&•óEµ‡w)³SOS>}Sl´;#5(î=:·qøO\ᦦDø3ÖF@rTôÙoÈ'É@'áÛ¨9o;=Ò«M!±ë{2‡JÕöhU5ŒGÊÇÅúÔr–Ùèjšíê–uÀ@Ætáóå•­qW3gPÚž‘õ§/-‰Óî¨~%ŒŽòû‘„¿Fãk Óü§:(™aÿýœßL +íqÃoØ8\"ÉÄø‰m~'8 £Éùª¤\"~Ķº…puX‚8R±·ù;¤‡,qÞ\;1´L AÈ›œ>lϴʘƒš¶ü¸\UÆækèK¬ôó(29÷ðJ3ôûõrï˜O²âåMçÑñBu”ï§‚!þ*²‰ñØx“–ãfðÔƒªáFb6ä([N£+þe÷#Ìó,+CðÇUÓ3Mcf‘ÐAñn0Ja¸Þ.H”#ÓJ>U³ÂåbFµîV?4™;> +Û Ì_÷cvDMÄȺ„‘)˜3,fÅ·„@sž?X³¡˜ò\ªå$@Š$ÈW;ö=W!za(NGv È(èᇓÃY†CõdQ1”On?S9Ç>Oµ +dõ›#. +óÕu«ðaxÍ'¢T´Æ49¿} +„¹ƒ°yeàêÙÔSYãæœjî×]…)Å’ÀY¡vSWòÀ­¢ÒGÕîUê£ ãþh4× ¯DTÚè¢Ë ¾ŠŒ}dœœ'.ßñ»c)sùÂ4E©”€cr'L’q!2XdêFÒ±!NMi€âñ¢ÂdÖ |H—^ÉuÞõ“ù¦?aÈísNfBèÈ(û;Ÿ>§[Q-„- ï$àKor§ËûI’;G¸],˜úJâAžXÚ€àvÞ9g•0žh}[ü £Å‹—T€%/WHþî×Dªÿ~Å!¬„ŒµWJQ;dZUüÁˆo 7êU ‰iT†dGà!y×"?αLÛuº·Ô~¡šŒ{U#[Ö÷g_SÚ®s·ßñs=„Ñý}Ž´þ^W@ƒ¨IÙ9¼£ýè@‡}Ó$0_>)’¤Èz®Ep,—ðóõ覲üˆì£å"è`06déðµÃ•GѶ`DÅÄÑrß‹èGÃõ¶F´(øLIÓÓ2¨ÄhŒÑ¢syçw-[ý $SŠQévÂÙG0p•|õL ŸûŒM:2ßx¶åÊ®I÷ëžvH…¶ß]„,U5‰eÅæ°LX*º{Œ+—LÊjŸO}«nU²9¸ç\wýÓ/~cÝS4ƒRꩱT.&êò³Í66USQ–‘*·R°l"È÷è;/Z÷«ÁB5OmùǤA– +ÈïQš4Zl’€AÍMNÒ1B.NèL·YÏ¥£ÌÊ©“0d›±)š„¢«ëOØF'Í<I('Ó.DÁ=Œ”³‡pEd­ùØøõmQÜÛÓJ:ëÔs††¥[H3h™7Â6uaÂÈ4UgÊh {V†k|–¶ žd£å4A:kY’(‰®rŒ“JY55b¢L ï¾íV·œ2kÙzÙÛÌ9éúŒðlâÞõa÷xSkðJ–†µä{Út´çŽ[9¦3ñÇk4OÂK8­Ÿçå Û°¨oS3æÈàQÌà~i–¯³•úc"uË-ëe0¶Áÿ6µ¡ÉÞ†ÚÄÜøÊUƒÆï¼à쌪2ئ„T(™˜ž‚è ¡)ÙqìÔn»Fñ±Aò¼Œ +~z#ë6 å˜Mmné©^«ŠÒކy§×ù{?¤¾ó ÃN[„!H-Èâ–‘Ôyúê³Ból«nsªYòU4Mö¤ ©0lÕÜ´~µÇê½æ`¾ü™ñd™ÿÍ%ºŒ(„ïñÃpY0çh^zÑl™dɄ˱½ú¸çðG0Q'[9R3…m4cA¸Ôá÷¹öîY+x‡}Ê)¹ÕV¹„çþìm‚›sÞi +chô„, 3 ‹ ï‘“#•ÃùG ÖÑŠ9$5à »l|ëQλM}ž¥’>‚ÈÔ!¦}™n¿°B=…_½' qŠ=ò¼²D½JQ:|4ù "V&71¢‡»Ê´XGŽÌ˜Û6¸XÉLjðD^«Pìˆ,0ª°>«ÇŒzK „Uê• Á;ð# zJí™ÛG ÃLtåk ­' , 2ýòô™ÏªÍÑk|Õ[~>'}A–ž­h¦M$™O¤{É™™aý|Fo¾á¦›\basmç­‚‹ÝjM߃½€—RÚ·ޤ`W 5YC¶]Þœ}ËA… IñFÝi„—¤>4Å1 <ÏÜïQ»ÔäJ!¼@ïµ/g”ÆL…˦Xx2¹Z‰—L¤xó¨jZ‹¿•…< ËÍ(癵uèKvÝ%' ¹ä†¡&$XôÕÝevþŒÂ…--kZ"»À¤Kõ.C!5—ÔÖ² NɆ ÅŸ;DrR,çÖ‚ŒQŸ¥Hâ-A(wYœÐ% + ±(ø'E5 Í0Á{'­WÈÐÐlûù 4·Oÿæþk¨ÕÏÙ€œ“æ¬)Tlý¼SM¢ÌºtÙö:ʇOI[|¹,™á +¸} ³i¼<nU·ƒÊ'D†7Òz;%s}S°l<•’y°46Ê–TZ¹eÛ]DÕ\Y¹ñ}˜en|(xèn)<¸ËŒ¢G/Çê‚«þf$'„ƒ":èuë ìðx/’<€Â?‰CòSÁ064qcZŒz¸ÙÝü\! ;‰^ ¼·'PZÖ‰EvdŒ¢bòjGYþ=Ñh/«¹È´®ŸË $8éÈ'kê¼²à +%gsðùB§*÷Ä•TÝþô¶VÔ½~Þgÿ°s-Ãê¾ù¤‡I3ôÀâʨbŠÅ4ZŨǾdzçÏ—à Áç‰÷ø×³ŠX]"ïe‰¥?ÂÛjš…<®ÛsÒfÔAgV+¢ÔŸ8ýdÚ¥_ÜÌl:ɶ™q +L! … a¥,C-CŒ}M¾~šÞƒÔCzâë—ò '|;¦DÜ‹ Ž‹¼”ýû·NsŠŠô c‹Ð9T#qY%%ËGð 0Ù¥*÷f’® +.³ã׋ÏLH]DÒ.½Å¦œÈçûNcxï*ÿÍRŒõjHGmwr$Æ›~üzXÉõ½c7G9±fRpÂÔ›õñ`ç¾/ŽFöøÍ¡Sësöe‘Ä¡ûůjrv±K ±‚º‹—li¬@b Á̧òÓµ¬FÁ§”L¡s¾´_úm\9G›8+¥£XmK‰^γ³æ&„m©œtðÞì]ª_l„Š@O3º] q—ÃX;Ü3œåá› +kƒãåxÄüÁ‡¹C ¥"QPf¦CY_vŠÓÑô|‚ŸŽîdœîÃ: eФÛw‘éûe« VÑê–†P-o‰ ã¶*‚½—€:GçMøŸ¥ÀOr¿/CîlMk[6qÉŠP·eÙ0ÿ¸•Ëzý?TRÈõó·—Ï(ªå8“j$27BjߺÌèÖ–õ¦òãȹÿäâÌ-:N ^TüÚO`bŒvï ×o(<>yýeþðHó‚Tƒƒ2¸¹ÁíåÞ(å2Çæ¬9½³g¦F³Ù å’Ë?q…ÃNßJšPZØcš¹ÔiΑ88›ï…wäD&oô\<朕çÞ‡.'cve‰kÎþšØuôI¡]Èš‡þý+‡¨§Ä ~¸db D:{‹ÛÖq •¢j+˜ZÖ+·?ÜT±æ­ºŸÀÜÀ! +û:%é5¾¯åV¾çu™J°5Jòb´â"2jþä³àí=j¹ òüÅÍ·½OÖ±¼×Ñi¥Réqødoeל}½j(áIaRFT¼‡{°˜Të‰n°‹W÷'½y@,}H5»A¬8ÑLØÑ]ƒ5ævYÛÐD"ßïŽÊDʺ°z¡Ž »z}ð…ˆÇÄ_@ïO>s0<#gr¹ñ´»f!bºÛèÊ5ƒ¢Ã–x¦ÐJÚ./°A>x»! jm–²sÞ7vÁßC}AœíÁ÷}Žn4XìÅVÄés¡%›†¹¢{Pû< ´éÔ Ì7¹d±·ÝÖ.´?²s1‹t¯}¼;¯±Ý½’×Gû»{UÔ.!ó!T-ºž¸9Çݯ~_’*gûkèŽvª»¦$û¦ÝU‰ô¥5Sü¼‘i÷I´Ï(Ô_:$³^‹â»Ù…eÑ\ ¯eÈk#Ü¡ðï…Š íw¿ÆÚæ'È­ÏòãJk-Yc¿ö3A2ûW´ìßßUøäë/5^]ïèø×¢ òÁoÀ&ÇÀÍ/úŸNÜ&ÞÞè\:?Fîö…)«pÈ:RªB¹TŠP¶×ÒªA +¨ïÃÌ'l¿:¦ðè;{3¦Íäeµ—Ä;»¯McÕÒÚ-ÿXON´Â½²ùr0‘õC€ƒºÆ…L9ꉱSWËñÛÖþN2¼‹ÆvÃñ’ýÐ È*ö{ä•k^‡jogÊ"oØÊglÂóIüPÚ}tq(½Ÿ +QCm6õv;1w²ª‡Hk_Êx½xµ™\Q\5“`b?ÛÓE„ÝH¦æX­Ž…äš»^ÁqL]ÙPºÀ³A‚ä£h]hò(0ã»d68ýÀëÓQ/eÃ`Ü›i0ÐñXV£ξ0žzGïZUOdCZ4[J)é?°µDäé*}ï uÒÌ{QýÜÕ‚äÕ_x® +Ê’¸È˜”m€¿™»_–pÛD‹KÅ|iVWeeÀÀ«‰ „lÐÁôÿê4èT0Éëë]Ïd‹;PL¹£¥e!D*%)f­­Ð¾ì {ÄùíÐîòsÃÕ|0ŠLï-ûÈØÀªY‚èZ`ä<Üu´N!ìÆÂçaæ¨ÞôIJE OÕFÚØÙ‚™O¥ì鲟‹„œ*+aB5*êëˆYš0MŽŒ£>ÂãðSΚb¤³(=nìj‘·æÑ4W­ÁÂ-ÕÏ·­_ѱîíô‡Çº™·` î%âg›«ïW‘iІJmøª º¢Ô††ß‘$1½ÑØ“](snr…„L¹Rœ±¹UbµVfn3]ú‘ÛÀáˆÿ3È9ÆTÄk›“¯Bšž«µW¯ôoäˆ9u“lܲ‡vxvèô3Õ ÖÞlQ;, ÿ®w½ß,Öf9z ïï‹?ŽJ¬äl* +pË(ÑMÁ™ž eF×gº‡@‰<·5ð˜MêÍ jmòÏ °ñksŒ]VY:zÅPÆ]•a£¿u_d„‰ê`”]&6ú‚–2#³ëb…S–ä|_'UBÉ9ÇØÔ*+‹©´ËY[–µ²zŽ’w +Áë±(`°1BøÍéÑ÷kL»;B„/ˆ,à  G70“›(Y:¥ö +ùµi¸ŸÔ§îwX\Ÿy=rû„7"¬ˆiÝe6ÕÈý`Cõì¥oØ?g`ÍF朌‹ÀH‹†ò×ÓÕÏ‘`ñ» ‚ƒT~65Î.96,`³xõµôlë Ä\θ;&¦!kÇ×å ÆæÁJôV>ÓÛnQ3­‹c…8¤„½aGãÐ$îÉ(»çf†A*"CÛï}„:¾¹ Ìl{‹7nN^ÐÊ`„påƒå˘ÌV—Ûyþ2>÷{Ή =½"ž;ôl`¦GS=)ÅhhR:ê bÞ°ã}µ;íYÏHey~aN'¡¦o¦NQ»ð%`\ô?G°2™9×Á>ìSЬ7…¾»Ù6ò_qÛ§ÍȒΊŽ¤¦vغä.Ù#*Íõ¹²G-–à°Ã~3º½øÕNôdàÐH¬|ò€Ò>I6]ñs˜öüåÛ{ñ7cÌ a8d?‡ÉNV¦æWíûê^ÙŸ\W’é†;ˆwÒ`–v0zA…füA©‰õ§$=›Ò¥˜ÖÒGVöašMŒs*(±Ó8üì¹äô¶^d•àŒ1÷·»s®ÛCºDdq +I¢BŸîÙ¿¿²ÊXãÞLbÁcÔÅã‡Î0¸±hÿŸvæû +‡ðgl2²¹¯u¶¯}gï™™³;dsvÉÙãlBvg”y8;âì…²et)Þ?âýíý¼Ïð„Û!O:hÛDr@Q9Ul:Ø«Táa¯a ..4EÿBÜÖÑôŽŒn†éü +ïÔ2AÆìöâ©eîÛ›Ó¦;»ŠÞ¹‘°!¸„è`Ò]åU-YñÌëŸò¬ùM5ÁF³·&RGßw´+ùûè8šŒÁÈfïyFW OU£wÀº$¾¿@i¼ù9ºùr¹>ÒHÝÂö§õÆe¢Íw{˜¡Ù +,ùÌçÖ6ºþ‘ß‘—§ìä*ƒšA>SxÏå’ò§Oœ•Ãøjäwcâ]o¸‡´×ç?e•é%Iôm ßÞl)·œ?Þ4‹™æI¿´—.¦Äì Ê×AÖŒqh}Ä_J¬Qêõu‘¦ZX´y7³xÄ,i’¸«^飯\µ1) Ík„ÝÅ TÅ>¹Þðô3¥Ÿ¦õ1!}KGf³[ZdɦÚ^Ýs>¶ì¨¹…ç›ý˜“]û·çÁ ~V\Yƒ°ÕæÆÐ¥–tQrÿ=!ën¡¾5ó -b Ýmº¡ýŽþÒéÚŽëÁMyùAãýX W ÜKî(-ëß)¯Tà‰aß½ŸSñÖ*æHGÚàœ° \>|¢<ý(­³Ä¢­pš6>AÈ?!K•úÜû5wv")]mBßþsËäÖ»y¿ˆ~li¨c~Ÿ…Ýu¿û0Î_·÷§n¸>õã³@IIS¡å 0B}?)4ð“ìó ßùöìä]ϧmÍ|—Ýý2žÌÉuf ‹cHéwia3êêùçIRyïX”v*&äaëR¹r}"f>Kèbœ#òF¾¾R>ô•g*("¸AÄv%§U–ݹ°¾ tðî—´"wXÈD Kaë:¦Rô6½fFä’pìï8%/ÁB×lC«ÓùꉛAØ„‹ƒ™ÐȆpñ½ªWfÂDùtËÏÛƒ'qØV>“žÇëîä"9š#÷cõeŠÞ«øüt7–À“rELåÊ1<¯Z  ¡“gÌ^™7…fÖ¶†Î;xzÍ.—½°õ<µ@|˜¾÷º`ÜG¶ÁàÇ¡ÝQ‘ôÁö¥¿XmQ žh?ÝŠd„Zêภw–_ã÷ëÛ“ÌWsƒÚH ãØ´ðÕHPÎ#razoºÚ·¼§,ýÎ{=M¤LÅ;uD«&RVdz»Qò¿£Ài:ü:a‘Ѽr.<Ó!OÍÁãÏcL­ó*ó@ dbzâ2YÌóŒûäð<îº|¯t$âckÖvzÎÌfPW´ DSÄwÞqŸm¦DC\s+v¨ Ò~b¥æg¢=R8+’(%ÖTúL茜m8ÀjñÕ|"Òr˜ü¯C1Ÿt)u+ ºakPâ&2?Ân6ˆ=Aù¹ä?úZ¨içiõêØÛfÄ·âw|šûÚѲiC©ÔŒ€} +ogÓƒ1GC6E®Í]cdv®l}©µžÆÍE*û‚Xí øVr,À8è–>7%×5/ÔQz 6@^î$Æ +Ìkª¸â§hDlU¼v7X}ñÂúZ%fòb+†Î5ƒ;TÅHÿ$IÀÒR.X/+ùeÌö2¸Õ4•õ…6È(z¡ØîõÉìg,Í¢ÛäZ}~û JmÕg(±èe{u›"&Œ›Å?ci¸èàòÝþªxš» P1¡,›%7Ñ9¶£ÍCN„zD²O•EwŒöÐwAöº”\¼ ¥¶¥&†m—}É·åæ5FèHîñÁmÉæåwæµÃØ_ÁÆuIð*Š_7S§êö®B›¹æÑÜíä4žœ¹?B¸ivèÍÊ¢ûÙ‰Ð=ŠTgÜÍÎh QvUKœRŠ¡ÔÛ³=³·*ŸèÌ »ü ÔÚÕ$dno(Î*ˆÍ¥e[­¨þ¶5ÐÛóÁ2¿±¹™eTFXôÑïŽj_â|§Ç9Ú ÆxŽüP$ßB^àâG:ƒÊÊòÎJ£Iÿ—¢baDѦËvwi¬†¹Ã¥Ë•4{ÓÖÓ/mJûW2S‡êrÚS–V¸&•ˆàúZ(^S'2×ä‹’L3:5¨V}JC9ÜÖË”2Jî(>9c·aïj<Ü(ÎQC…6Ç­ X)sSl„öϲژÑ߬n +i¿5xÑ@>,Ïu> w?tiÓ¶0ûôIÏä#%(ù‰ö +©«ˆ|LO†D¨Å÷¦gîÑå¼Þ8vÉC÷I~®O–ÙÍ>mŒáõÞ¢‰‘}‚ +^hâŒð·¹ œ£“hZ™Í/øÅ_à7œÀ+P¸¸&&êåî$+Nȶp®Ô ~I(–»c¹ÚŸYªÓÅg¶%ø¥p%ö>­’H¾iL¿\ÚõÐß(¦µâ_«8Cƒ—R{‹ +޵rð¦ëØíû‹0Ê{‡˜ÊQê¸2‰«Zœa‰ƒ†*7Äc¹äJî„I›ÏüìÒ]©æÁ 1=Š¡å©òñS€MX¡¥GMøªéþP¢‹:*½ÙOT9†ÜD¨*ÀzÞÃ*Úž“¬ÿ°Ë_hg +‚œ«ê9ŸjˆŠ"J7Þ®(ðhT(ìâ ª¦¼ÜðÊ™§Ä‹V¬áÝq +oò]ç }£¯9B‘7õ· öœH{È­’ëæi`T&éVÇãs"¹‡‡ªÃßÛçVMo¼iá÷׈â{C„^×;¿_g¿`,·÷þ2 Ún“ R ɫǶ]ÅjÍuib°ƒãÏV!QÏÆ>²¦aO<ö”ñOÁxƒªH²$áófe°§Åû›ê¥úКxÇÑiêÅà>ò$­–Ìy"-Ú-ŵ ôý‰¤Ëq ¸ŠÖˆÕ"™[Ø m¥cA¸¶¹"t8Q+PK¥ìó÷Ñ”¶ëÛãh_“ ®$+ƒº‡¼S¾ÎúÜþµ$áØ™éezv~7EhÅZÞ‚¥ÓªãHÝåûm®Ý‘(ãŸÄ"Þïòwnúê›»ÉÕ”^«¦y$3î3i=+iÿWuÈæÔmâ’<£Ⱥ][±÷QgShSÝ»¤SñºïX±wû@`z>ÍÛòÈëB¶"Æ®.(ñôAàN¥Ã|³w®3¬ín1eqÞ¸XäL%­1;¹MÊ®¦*Åÿ^OìU©‘yo•½§ìRùùÑ© lå™Õº©RéÓåú’ØyšQÝÅêØÌ·XçY2‹†¸Ä¾ŒPñ+«Ö$ßo¼7SæDEÏ–GÙËËGªvË.¼–Õ£ª¾PH^ ÍuòñjzZ+3àÆ´¤Nc<ÃÃe™åGKB.þ/Qü?øŸÜ|Ý]ƒà~.>ÿèß2endstream endobj -925 0 obj << +935 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 33 /LastChar 125 -/Widths 2102 0 R -/BaseFont /XFYNBR+NimbusMonL-Regu -/FontDescriptor 923 0 R +/Widths 2132 0 R +/BaseFont /MYZKVY+NimbusMonL-Regu +/FontDescriptor 933 0 R >> endobj -923 0 obj << +933 0 obj << /Ascent 625 /CapHeight 557 /Descent -147 -/FontName /XFYNBR+NimbusMonL-Regu +/FontName /MYZKVY+NimbusMonL-Regu /ItalicAngle 0 /StemV 41 /XHeight 426 /FontBBox [-12 -237 650 811] /Flags 4 /CharSet (/exclam/quotedbl/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright) -/FontFile 924 0 R +/FontFile 934 0 R >> endobj -2102 0 obj +2132 0 obj [600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] endobj -884 0 obj << +894 0 obj << /Length1 1620 /Length2 20127 /Length3 532 -/Length 21036 +/Length 21035 /Filter /FlateDecode >> stream -xÚ¬ºct¤]·.Ûv*I§cul'[£b§bÛ¶mÛ¶­Ží¤cwý¼ï·÷>cŸóëœý£jÜk^s^×Zë5FQ’)ª0›Ø%ìlA ,ŒÌ<5e ECkkC ;Y)¡5௙’RÔh²°³3y@€Ðð퀅›› jgïîhafPÿå ¡££ÿ/Ë?.#÷ÿ@þF:Y˜Ù¾þ}pZÛÙÛmA)þ¯U€@È0µ°Dµ¤ä%Ô’òjI -ÐñoŠÎFÖÆY c ­`jç°þ÷`lgkbñOkNŒ¹„†'{ ±Åß0 ›1Ðþˆ`t´±prúû °p˜9Ú‚þÎd°°5¶v6ù§€¿vS»dïh÷×Ãæ/ö—LÑÎ ädìhaüͪ(&ñï:A憠r;Yü…v¦=MìŒÿié_Ø_š¿(ÈÐÂÖ ºþÉe˜X8Ù[ºÿÍý—ÌÞÑâ_e8;YØšýWôG ™¡£‰5ÐÉé/Í_î¦ó_}þ—î íí­Ýÿm÷/¯ÿ¬Áä´6eD`ùö7§1èon3 [¦¶Š”­©€…ùßvgûÿÀ\€Žÿõ?{†æo†&v¶Öî )“¼èoJõÿÊŒÿs"ÿHü?"ðÿˆ¼ÿoâþwþ—Cüÿzžÿ;µ„³µµ¼¡ ð_A€ÿ¸c²€. ãÿÍÝÐÆÂÚýÿðß=5€ÿ®RhælmèøßáÓ ÛšýU„›‘ýßV ' 7 ‰¢ÈØ`jhýwVÿ²«Ùš­-l5ý×8 ,ÌÌÿ S5·0¶²ýgøìÿ†€¶&ÿ½ü¿2ý«x&ùïòbšŠtÿû½ú/?Å¿úƒTÝí€ÿ?‰†œÉ.þa±sx2°p2X™Ùÿ»¿›Åûÿñ_D,ÿµ–39Z¸´™™™Y¿ÿãó_+ÝÿF#nklgòÏŽQÚšüÝdÿiø6vvtü«í¿Îýߦÿcý¯íºÖWìŒyƒ,Ó2ÓAu¸¹#SbÚ},#Áö¥ªE~5v½¾ia»Ü•µÁŒM3<¿ÛÝ—Ïí?¥iÆúp¬©zS€×ùDÞ4ýè[_;9鎘ôJ‘Ó/4¢:2Ü{ ÝHH— OÉë…ü5ÒÏ!‡Pð‡Z…xUó«Óö”ê&BÏØ>ŸŸÙ‡PvE‘Ŧ—µ‚ÏÕàO͘ƒá†€l¬„ÔÈW"æþx²À £ŽïIx%Q¼Kâ¦No¿­ùWcwúŸò‚ßÄÎ׊ü;L§V‘;fT° £Ö.ãG¶íúÌÓÎõ=®>ÕÎ7èX¬JÌ[ÃZUýùbªÜîA+_®›xF»Íc¨À( ¥ã©ƒv¸\Å$L Ò…õ)_,Ò ¡Ã4ŒR4r-Ø“©¾ˆ3ø‚2މŒ€$¿ d-ô~“„}¼Dä9&G9?á¬;Ô6®£ÛB‘œ´Xsÿó/w†ßöèWŸ.S?649ú0|‘ßãš@΀ƒëì˜ç3¾>9È%æú!.à—¼Áô/mH‚Þ¹U'g7¬«T¨y㨒Cº4œÖ)7%Š_0iôGàìáä}²›„ ƒåÔ›xêÙÄ6\/ÓÁ¹Ô¢ÑCnoãÐ5-Ûu. ê24|jþb'U//g7~u®›œ÷äkƒÓ—8•†n¤3€j}_R:âàÎ>)[kÛAP++Ïú;iw9¶»¼ª½ ·c¸A{÷¿Y‰ü j¿3à aÉ»ðSr°Ñœ¨t2ýV å -o(:¨Ñ_‚ä¤ñOFuØI)Q’¬¥®‰Í:T\+kÀ2ñ´Ò(ÏË2+­Ô»Ð]é¾çAM¾×Q­?A"tto¯$ÏÊAœÇÛwÎB¼ã¢ü1lþUxq¨eÝÒäöt¼d"$ÀÇŒ‡™M ,tEÃ2g§ö“0ACª•ƒÇ“IyàbLżê|cÔd€&ó­Ðƒ}7ÆÐJVóJfŒ!`/—ö©Ä~iCB2l´–¼â¸¡Å·Û‘ÜÁøÈÆ - )/úh½0HéZ=`|K›@?ôî3Ob¨cËLádÍíìÉQûcz‹þú7¾cèü¹$ Æ>2Í%—¹ß°%F ->@í£dJî'¾T¨WÝ– ’ÆÑë«úþ®@Zl—,P* ï™7o6x©bäÀ×ZëíùOרc ‰^à°HY¹ê¶]¼„qGÝx- $v·úyüJŠÑ‹lüwÝ„ze|5lÇ¢‰Û&^^Y†¯d¤å¸=眫Ø'ZðþžQ.,°#p¯ü°Éøù¨~j‡|i¯ÖÍ_)¢é<-ëqHb_Ò»S3‚4~«Ò/²Jú -ó»kœAUyÑ® D‰ˆ„’"µpVk_í+t·—$ïÒBhtçß’¼`ª-‘C†Èù}îÒôƒ¡OQN¢¾hÉlÙ‚¦X©ÍÉÃÚ-ðÝ󜚮Ӳå‰f]D–„]fp`ÝLWý£ÄÄEäÑOT¢ÿ«0ûž†zܾòïþ׬M -‘ו‡ošDƒŒ ¾”¹yÙÚ<1Þö÷Š3 -9à Ù÷:Å„Ÿ\ÉFlý¹ŽNÁçµ±½F¥1¢{1I#ù#gÐM!Å&Ð!ùf¸¸<:â‘[Ç‚êÞ—dx²UÃü9‰Åm³{¦¨F®Aº/b›ƒÞŸ&ŽiÊù0ÆÊ<É{ –3Á—)t;¾ -I…ÆÄ8á J’«2ðÚÁF–û†t÷+àK‘D:rtËSα£³ÒFX°Y¿ƒw0¢ºãÎo‰Õ"Ú-P¼L>Vš˜ñפ2 Ynîë|CVÞZsZú Ó†x9„ĶU&bNž\@š'üýlNÔÞû1ãWÎèjöE¡¬¨ÿI1©~´Ç)¨¥P#çP&¦B5ãrEò¬é&ÜìPÿgÖ©‘ŽrÏ3ä5ë(h“‹£66q¨ JÄ·­ ï|à·Ë Ç#·û:[‘úìƒîi0žì­ÎÚoœ*3ö8¡|SgrJ_ˆ·¬»TáZ‡%{ÍbË„pøTþÃiK¢`È$Ñò-ž— r38‘nü9jNÒúzzç÷˜ °î¸×ÃÈm‚t ßk–ßnŒ.ƒjÅâGr Ÿ¶~Ýòz^o -g}%ž¿<ÿ𦢧y>ÕdsŸZˆ—ŸäØt‘ùB<*Cuù­ Xò4RWJY¾?Ôse4¿¦öÁGGøË=1nI6ö>â¶dxøÛzÀÛö§úø÷^`K­™u ÒZ¹$gMÍÍE®Ý§R‰³› |~Π;âIךÚCXFçÔ[ "9Û\(:Ô/œê4Ùè´G÷b^LG9DyÈ‚6ú+ìÖ?óÍv_æÜ@Úz¬ºy4r ²ÕEëæfNfS\ý(„w!Ð+`'èìõö½Ãºk0Ê1pI?ص€ÝK?lÜT›åœ¼lîSè’›šæC`-ëJœª{K'éͺ¯ÊÕ Çƒ„¶õÄ&]_\ãN*޲ýÈ˜Í ¶q™â?tâ‹>Ú»ª¿[h]ØÎDi‹Ø?•ƒ] q‚ŒêH¿(OßM Þýa›kP …Ìùj†§lL_Iª3e#9_zÇ…q»¢«¾I¤DKi‹KÂ|Áô-ïì¾æãEP+ëÂû; KOã%; EýkêÂJþþ‰ò{¢M; -%Všy¯Žç½wd`õ\¥Sd˜4¬Å¥øïhj-Ó)¢1Ù¯tê…hE‘¼Æ’§@c]ŒQº,ÃÙPJ±Zõjæ¨u¯žYuÉÔÅ›òÊqzú‘Ÿc¸×µ#Gr<’çâØP|Â~Rq‚a?–Ôà?ÌÕ…¢ò-›ðå&•ZëCnŽ‹¨H鬄™NN~g’±ÜLwgz̹{Q\CÂàkîËãMN®-Ø\ÝmbdDÀ!pŒ,*-eG¾v²M×<Ÿ»)¦Õî°ÚQ ¬Ìô²Åc¬ÇáÓ7/ZÓÀ¥¢–ôæ!ùOInWþþXÞ€8ä„áU„4ƒÜ42ôgYzY,lsûtˈSòî’üZQ”²8 !Êó@¨`úžnLnï¬?'@‰R§³ÓÔcz’jýzçÑGD”ÖlþhkUé.ÁôÅ0…{)ÿûŒ<Ë) ÔCçÆŒ¿v—f6„øzÒ˜êïUì³^¯È€žžs<Œ¨+ (œ× -?>Lîw\_¼__º‚+úˆ—Ï*×5²,Üâ~‡ -ËGBÐ×4$<]q…x\6_ÌI_ϱȸtÓ<< ±ã[ôV(“K—ê£hAÑLÿžƒ«±î«k”“Á™-H¼~„ÈëRtàÆ;ê¬ԧОSŸ«,Ä>x›ºQmMΠà¸ÀöH|’MÇD-2:s»ÁK¾jÍ)yu$–©Ó:ž•([mq!+GŒ™SÞz‚PùÒ†ÞjLñpö«Ys%²Ý¶p¬z.M[›t]Þ§ÀŽKxÀKPų½×ÕêL•ªçLý=à'd{ì-¥?Ö­#†‚­¢E^+#6#– ñ/–“õ­ñ¼ÍTñÖ<ínÀZ‰/”Ú8Y2ÓØ/gÓAÓ›øæ±,dx -v]šÑØ}a(ôÉ:eÝX!±«AÏ[–Ž×ÊÜ’ÀæÆ¹Æ£Þ3a‘^£ãxR°šË\ì2ª<2€ÿŒÍmxÕîQžæ‘QáE‚žÈ¿¼=±HF,ÃØðªÊжÌ>Èü]¼¾Ø¨ÍqZ\Q0³“×-|/SS´æ;ª? [B«˜jÜë&BØ’ÆIRòu“$€„ƒƒj°i&ÝY³$——½å£-B’ -ç¨÷i ¼%0¸)xëõdïIG•&Ž¿œÃtɳ6†ž7|¸.&õ - -ΈŸçf™ÕÈPMC°3p§î¸eÚìq²áBÞæh‡~ò¨,þ¶¢Æ®¹ÿã -¥;Kƒ{jPÌCÛf¯¨“Ø£_:©Ãb*¬Ž–Ôº°AïhµûÞÈq‚F΃a¹¦Ô9›X´Öò€)t‘ÚQPAng©§âÏíÿ4»š†ü˜©>¹I¡Îúîá”JO¼A̰#­úEñÛÅŽÉ<æT»;×ý.Fíô«déÝj¸bÙ«k“ú§V«,þ|D—æ‘,4‡Ûj·vÝ–²ºyAñ—‘ùþP´›ç€8îf3A|æž{a­ --5ù\;³½2>V®±*T# +sê«®0V—0p ÒÀPô4¹7®“Þ¾Ê܃#›}Là®Ižß˜ä•¾9h_ê3ú 76¤Z&!‡Ÿ†‰Y‚Aý±Â;¥§!ûÅóë\š[S±eG»tö™€JË ¾qWp‡þ¬ÎˆN7ÝId¸1c[9H©èMu„hžä?ø³Ùo°‡T2­„Œåm¬ÔæZ5·}Oîͺ!bîÛÉ$<~éø::¥½½ž„2Ž €O1W© -@0‡cz´ëðcL"¸¶©ˆ1tQ mhž7OyÙK/=mŽ1Ü´iüŒÇŠ··ôŒÄŒ%¥”v= \lB­×9Ɔ½‰ü‘“WŽÄõÝ©s;Ú¾†øðýa_ 7,Z±jg[À6¾bV¤ÊY—qá=›TLÀTæù4¸©ŒZä¹xæÇ©D S7Aof„ûoަ¹¶†d¬Å(?# Í”¡4÷Ú7©¯;˜Ác%$P„P|¹Ú“k½T˜dpR(áæÓþ; @UÂŽåo.P -·?å?«ì:º;rº¶;(œåÒHBÐUQ%Wy¯ÇûcEàÝÚóÌãÁÏbמgo@¦ð­q´ÔDÖèÈ' )øóÁ«ÄhåHø*²ï›#™·ZÏYHá( %Òïg!›µ ß¿ûW{|êõhñGÆq¡ÄL»»o–DTèd·ºãú±‚e6D²]}~Ç¢jé‰fÙ1HD,zÉDx¤[®'tC,ôC“2ßíÓ[+'aæ%¬vâ×òAµƒŒc;ÎC:e›sÓ’/ŠVÿ¸lÞ+ã,¬zïpÂ%¿ìg.#C‰ž4¥ì#,þà¦ÉÃý\¬Á—¤&‹öðcç[5—&b†ì~wcÖͳQy•†øÀWœ±k´Ô¨ÿ ³6QÃÁ»kÓÞW´ÌvŽËËf³í®Ào×>¥‹;ùk/E'’r×i'4hözUZj -S(xÚ#oÓÜõç ç‚͘©ØÔäs½6º~ï6?\$Ý“ Ûp¿øæ ´wÅ@¸º·ÑG´=/á1^ØûûWM€Õ}ýÐé§‹–Ê{ÅóZˆÔ(sï[6ìÂO ‘züñÉ'ý1(¸MáCªš˜ãôº)–æD8ŸåÏ=’´ŽMæ2_Úû+ࢊ.hmËÞycÀ‹0w¯ƒ&¬í9r7µqB´!KRëhlo:®SZrEýñž:™%ÓF¤ûX¬ö@fÔ3™Ö`¶ÉbcгûË€yŠ|{¸ ¡ïì¹Fn§È…çA™kÙYÔëÚ½ |â­±ôÈìÓDáw E)³*j³sý«‹Û–]vŠSl|œ¦ÆEÔô5L‘–Ñ – :Z™ÜŠ2Mù…%–Ð`ß¿1¹¤²¿‡T@@jL¨Ph˘Ԩs*ô½§ Ëâå®è‚ -I³ÙêéÇ–T©-˜R§5߇›‡þÚ@ÂÇŒçoT§÷uf‘‚‚Ÿ£;?®IÖB,$ÊqªG¶vÚâ¯PIJ •£Æ»¨(¡àœ•SÕ`RHáRp·É/i¼™É6rƳ¬È»ÚôÊvökU;]äW¸é­ysV†$Z k›oÀëãõK„ö Î£ æe*|LÞ¹*p¼§}¸ò× }an²éÜ¥ºÏ¡öÚò´Ú7dîyˆg9ÏÅõð¤éFOdtã’ý‰,5FYrè¼c}í¤Ná§à:†KÐe fŸvE#Ÿ?Íю˪̘ í‘0S(Ó¿£ME J+dL©¬¼I­ð^>|$½g'IàŠ´?"týy0ïù4=:9W8ùÉÝ1ÕØ”D…—ÒšòÒ»³/Ã1ðý¥C¬£ù#öŽi÷é1Dr‘ ?ÇBì6R6VdÒkšÙâ” \šž¯ÀßgÐ>ç¼u]'6ªû©$c6!Çác¢Ä£Ü¢Ãvƒ -6AdQ›¹Í,>N)¥Ò©ðOã’ÛÍ·o}ŠÓ3U¢ªõ3“ÏŠC…}àp)Æó¿a™FK›ó+ •W1{‘¨íœiNŒZ?¿~Ô<îZÛ×Áˆô~ô}“IU?û -^ºö*ÕÊ;â˜<\éæjB† :æ‹ãk‡o™ùžËýtaA=« ÓÔ'ŸÔÐH•ÄN!z^“«ÿw¢ëKËÌ´«vߪý'ZÎØS³_-Ÿ!¡ÑÐ9†˜­yƒ±<`–ìÜkÚìƒ8˹‚®UF¡èýÒ¿äâôëO‹¦3xª©‡ì†°b$pãÀfN2rI[ ÷Ð`-IêѸ\\AIëÇz£AÅ ;²;»¬·Ó@sûÑ’Ðë"ø ,méG(;vø™Ùd×"|‘"¦ŠÄ`྅Óé‘«¬óõlýÖ!|t]Œjø0Š–¬¿Ö¾ª0Z )ˆM&çEî+É÷Éœ GÌ7kʱ—Ed`X]ŒÚE•ÀQd¸À'D5õüDU°p¯)+7sZz Ce´– -Ý)k=g< -ýÀ”å•LâàÛìàwD#XY«yû¸é ‰zp£^àž¡°óRÈÒˆþ‰B˜D²¼¾Ý_v|˜÷ÕìÆ”¡v’S|*B‰ã˜D#ÑŒ¹N7uˆ'ôx’ÎvïNEy-‡UI 9̽Ç|iýB[}¥­ Ó¨ÜE>T ”;pf4_·Ñ%ÙøN} T…—Äï÷uĘ¿”õ‰¦ûñ,Ri.ï -„y„ÑŠ<¦ªòÐYtÍþz`Õ4ŠMÇ>f·ÅH3¯ð(±…¼]¨!9‡çߤ–šà›cà -è°ƒXC#Ä1ž7róѧƒ†1÷‹þØ*:½Ý -¾¬üš"¨ùá¶“°P ¾¢®tþkºô¡ßs˜8ÁºÌÈ8õc°ã9­•Qæ3EåŠü±¹ÙΆq«¿tÔöÙËCCY^"fDzJ -ÛnÂ÷Ù'Î{ü®ÒÿŒŒ®AiD–Xg‰¸N8T£lõß Ý¼ùõšâq’Þ¸+U‹í7›™Z¨ Á©Þ¼{U ìôtœ&ñ6»=¹3gT’>Ë€ijév¦r‚Kºr‚ÞDƒœR7$ál^é•4mtn$êEÒÙeÜã8½¹ƒVã=R¶W…C8.Œ.'~Všë[²­:fÉHn‚™MÂû¯®2P8¼Ï`@¹G´=qHw¾•Ø[_û7*²C™r³ŸºkÞ²¬Ã1‚¤Á7ú>< -Ã2k}„‡Œ°±hd7,=½åÒp3{9 uN4Òœ°T—£b ؆F–i$ïó‹'p‘}¾Ÿt¥™´ð^ɨ"3±Ut¢¡zx²ØÆx4D K¬ZógÜ–z‘xC6‹]äÂØý9&yóï³t6?ðÌ"% -‘¼FøCAÌÑð}>€¶6‡¢ÓVÛþ\ý di B´«ÙQ¯è.Ç~Þ‚´ÈÌ=ìäm’6yS$ý-Ñ¥ª¶™)P‚´)keÅÃvM¡Gã¶Ëe·5%¬_ØYûMŠKÒ}ƒ†Œ8 îÕŸÃl5wìóµ Ô<öÅ·£„²3dz’œVÉ ÷ - žóø.Ѱ\éd¥(š˜>¯–LãPÊ  Ôš3,¿Ô16še¤³Û²˜BG»OåÔÏæ¦_ƵW‚®e oÎP×½'”@ç×Ò KLýº-/ÞJ[ýŒxw]öG8förˆVƒÉcvÄþh;Ìšé£è‡µŸõ!qîL¾Â mÕBÇïã@håR}ºûür†¢'rû⣖í5qq!Š¥¥¾Üt¿°wô¯µžQ8É@Œ‹«}Hë%‚Õ›E1TâìGäìï¢vF9Õ´½Öœþó«õ‚y¦¹ØÍYG$RXs³ ¢ÖÌÄxŒÕ}èÔ²®å†ˆ¶DR¢$GG0!°Ýº˜ÇêQàQv‡{ÎúlÀf×rh`>-¸O×HÿËtÈG¾è¤Â³8˜RG#zÛƒ–´N–˜0NGéìl%¡§¢Ë.læ¦äyð»R×|~e@!ŽŽÔGê`ª0棋«å=,–v_æyN¸À(:¶óÌ¥kÔ/˜´@ÚщÝ2Ï$4;ô™d1Sží±B;·šjü“ < Iiß\ÿ ê™™Î9£<È;ôÈypckÜl"ºÇdcß]ªPí’›öĪ®Ê™x³}YÚð²UöWÓÖ°Å÷ê êy´NpY¨Jý°ÐKöd¢_Ì|¶jUM‰Üßíùº=B78b5í9S]âh?7 ØD) ƒšƧ̗ÌÛgäX‚ǵx–!6YßÃÛ.R8WÐ^õØ!žÃüJ½:±³tñÀ{›lnZú|£€xÎÈ›Éú¾¹[ÄÇÍ U7NÑoÁ/¼\€ZëôJ(šøºa™Ùi¤•?€üa/J£ˆEÿýý"«€ev×!€Ã?ü‡¦1áå©Qá<>ÝZ¬|¥“hà]12fʸ™§ž(Cj‘ÃS¦™úêûW%W%N_ììÉÕÈiü‡Ÿg='tÖ¾Íö¤â„6ùWÊÕfKd2žÊ]'Á±†[–àÎGÂÑ%Zu$o[fìÀ(ÿ÷KŸml>H×ýá<ňe~Òußɯ,gVi®ÔŒ¼³¶FUjé‚YKò–eŸ¨?ŽD‡.^– åª$y6àj)¼¹è 'Ç"äMï{fÅ´cäì²Üz+¢1 -°YN0ÛæxôÞù¾•·Z1#‘pÐG)œïò±ž{+¿ÝªjwÒ±E©áš=P´Þ7±ÙÑ[7û¦“¸NYYÇU¸ydyÀ3yzdC|`×¾„CBݤ0âF½Æ&nœÐ~,‰ÄÖº ô"µðóo›Á·¶±zÚŠ7¡t<=›¯z`é†Fx¿¯!­„OL¥ó¼‰cä¹àåOsLÊ…©V-Ľaw^ß -¢ˆÉd)$± ¶Š¸[a# :‘ÁÜ.‹ÍÉü7LÓ„(èòGÚyö é안øžwbMŽÓüÇÞNËe?ZÎÂfRc¯PÌeš²ªéQÚ"äI8 -4Æg÷ÎüôL¬¾¾Ò?Âlœá6_±Â؈u‡ëî$àÝÌ;ÇDpBÝu¢Cbî›#13º;Ï -*‡Kò·¶‡;¼-’"+ܦ˳-ý<ÎÈt_üöYëÎ’áBÁ‚¡$üé©Ò.&>Ùe¸R¸¡3›Áÿ]u7üaÌõñ.R8‹zAµÓãvnXLûçpYTÓôª['ÒøUÒà=|¹üº*ÚÜOAŒ/–*CØ ¿?CÞêh67÷ Wáïx,V½ªŽ_RÆò^/H–}èÈ;‡¨=+mä káÕÊuS®ÉẇNbnN’²‹Y)êctž-yá¬JHw‡d`‹£Mó®úí}KÕ4¬«–!øWù…sYÚá•MS |•ЧD Nß"æµdYDéÖáÄúÑ¥õÇ*1öEÒ.úMµü–r±ÀÒüØ -Á4õ5’KÄó}†#‘.§­¤‹R‹« -õS—¸­oïV‚•¦x{ì—?]Ž{øjA}øé{¶$õ†BÇÃh>/o†"U¹»ý´P‡SkwUçn0þ€8âàB¶ü¾F;u¶pL)#–àa–é†EI!ù+hâJXÓP%*;fÑðáCyê¬ã}ÝoÒ¼¿¡ɧR,çÇ?’˜Sl9Ò«W¶ä'j˜¸¬UÆ)šµæ•Ïˆ°gí®œÙ­cø•XÞ|‚qbÈ£!1{¼ùelÇgÅ™0Ù—^už…ÒÊç„D_ºö¡l*·ðd¾Flú`‹Í,¨X KTŒŠf­—;û²#q~hŸ7¡¤Y'ÕynÚsëÙ¤…Ϭâ¾Ü{äcÍ2–ô-ÙþŒÜ×’QîPt®ÄóðZs‡’„¼Å·Q·œêŬÇàâr´iÔhKEF<ýçn|Ñ ;ÃÎ*½½Æ¢¨O~TÍËiƒ„½• ñÑrQ˜šÂ\QxöórÅs]‰‡ÉK‰×Öt©RŒ{±þÄTq>°/í¯ èÀYˆ8~'}j+U¤5]¦tj7ѳø6²ÉOŒô%òœíüØe¡ ÿýkFÁÍÄI÷-IƒZÚ[fãçŠ´Šˆï;£À»¹{ý£›¨æÜ 6pÂédʬ ÊL -}c6!„L¹âP’{ƒá;D¾dçqí¨ˆz`Ë2«f§µ­])ÊFDŠÜ›/˜[öÃð"§Ê^wHZÁ‘³"¯oD{¼_7züä5àb«;ýS@$ú¡W °²ZðDò¢òuÙÙ‡W{fMÞ2ó ¥I*,~…Ä©¹#xÖÖŠìz‰KkVßL™E›)¹‚¢ÞIXbÄSóùÈ»´[N[lº3íLX¬˜üçw^@dqór®©aœ€ÿˆÈ«^œ©úQÔëèŽ0¼KÔÎs?Å$#ÅEA‰i×&ɇݻÁ‘$Ò©ü¥Sy‡1;HèWuP)½N® ‚’¯W¹s×![PÛwÚä” ïÜiCéW.䦄NMb‹Õžçáâ—¢ VTOþNÂ^K_çÛ.€ m†uÅÎåÏ0úvaiÞAœ,g5YaØ‘â×Ái¡Þø\¥œÑÖž-©* -G%vA)ÁÃG¬³¤f‹o¥¿ñ`Ý­LF™óVõ‹ÔK‰óÔÝwø`ø?qŸàÁ¨Í tj@®ÈÎê3cçÈEÑØK×O»Õò:;?I ¡ ýÅ!˜t¿£dæ[)¹¨øLIÃ-…Í6mïÄ;ðëjoà'ø|Q¸>ElЧÔþ"$+Ä/ÊÑótb/w6ŠäƒôÝ~pióÁ …§Î`ÕÊgвg²:¡;÷Y2&Ô%ó -ž(—NÑÄåi¾%¦Še¿€Ù?ó‡ Ÿ›o†`ƒbîª0Ø– õÚ MR¾Ýmc,ÛtóÓÇ@6UÓ -Xá…<§õ0ØC"ôñŸjè(–ŸÚŠeÂÑ_{Ú#‹p7ƒLìÙ5`:ì¥~Áì4«¼„?ãL®Ý8Qó\‡,OÇ™ÒÀ;ŒmhT Î§µVÄ! ¿h¥¦ž;t*ê¿ôŸçq !·Ë,·*¤Z…ΟÐWŸ¼T‘*”„6C‰:(ç›ø9ÖɵQçQÈÔGæÇ¦ß‘_<Â9ç×YÛ­ÐÚºMîƒ3u"JL üüÒ¦Q#ÆV_©©…vYTóVKYðçæÄÞU™gÔ»ð¼ òù‘Ïz‘Z(ßC?¢1Ý=žâD®jŠR8€‘%öøg×Èži2v»n›„¸MM¢t QdÂ*l%–¿‡RS7ÌÖgj¿¤‚<ÿWßÊ}#ó9¼ˆ¯†eç^™êgÞÀ Ïõ#²z:Ý¢ -Ha\»¤ÿEH Ü„Ôçì¾f• %bA¯üIÃvÊ¥lPsw‰8º8Ö­æŽÚz1IÝûQgÜûØÍMw­©•—#ŠC$=ꤡ ºí=ŒjâwÔŸD*/ÜÒdêÅÎVÇ ,M¹·KÎ?ß´—GM‹-ø’S,‡rYŠãÙ§¢](?*¢/GØRèÌõݲOR毙(š:4 ú™æÒøxÝ`£BÎ ´;á0dˆåÍvøÈnç”j¶ÐŸôwoå*ra|&£p8`ƒ1ÕªJs‡!ùåækz‡Fíãeo—É1.ƒ&xªMC1b¤‚Ïæ·x±Z8~"xOkËÄ¢¯×¼lT²”XQ  Mo¸cRt¡Þ aY7_.äNéT±JëñM2AJéŸÃ=k§Í"Ž‘Zíë%a]¶•æsð¡|jËNèNÙ Ùcš|GXŽÈc|G¸[«‰5G¶,€/œR\n‹l_`m>üTO‰+©b0é³lG¾u8ÂfÓºÞC#ÏzÆ?/Ùel\‘´ˆW°‡Ý×ôøüº±Bì¯7z%ÀÀ·Ú(»w)ûV§â‚›î»vM†›»ó¨7Õ5K#;ù -ž‘õ÷¦ÝÔÆ.3±õƒ¤9ù]v\_17OnS{‡71¼ôtÝêÅËCgû!Ìõ’+Ì\\j·Äž¸,1Èßß62–e€Æ§¥ì¶£þ&kL¿ÜêWÎc½aàJÚQà&AY¸Úãt¼Å+«8•õàZõг…V|Òœ½ÅÆú¡/½99tsDõbÛ_ÇÜÛWp vµe>‡ÿö²fßé(!‡°~i0bkzì¾ÕIä­ÖÙ²¥©@ œæ‰R&ï…Ãi$|i ×¶Î ³ùòR¥ñ-f —ºŸ æžæœby,I꾟pXðØ©»›¦Æ)bF°¡K·b¬H‰ÌçubØJŽ%Yô¶yX}<¹ƒùÂ3éîe›i0Û~4f$­z6n/¾˜z¤ðvÀÓx$×ÂìÀˆæÑnmeõaàtçTŠEð­*>÷ËMÉCJÁ0Ýg¿WæWk¡0[(ÃL(”ÂÁÒ/;í:1J ÛÙÞ¯£ùþŽŠ'sÙìYœÑ$l“E! ÿŠ’úë}ÈѸ/áK#¨ÅA­Ž^Uë“Ø~L¿ Â Š‚±XYC§»¬þÄÜ¥¹¾a.áM\…ætrQ×üÀjq"Üm £ÏÖ¶î½-‡Tâ‚Û%JÅX›M³z¦¹7SÖ¨úf ï0´ô³V˜q7´2AÚ€úË»X®Õ’t•Ö3çfÚÌ3C’{Äc6 b€¸Pek8ÆÉ@G•«EWf¶rˆO»iuw‚xÜÒqÌÿ8ihø©à¬j›—UCÅH»Ê¹b?,£LrE =ƒ¹ôñ5Ý&*~ê%ÐÕc¾îÏòX¿,Û qBN)óYþÁµe¤*±~å`r|"ýç4[ØŒ¢¤¤€í·Ã|­íü·‚PžéÉ+Qu|¸ÃH:^R8MÿÅ›ª¾â,FU-°ràQ„³sœð §gVì5qï¢< êÎŽ -d9ÊÉ„™Ö´š1ìÏ¢ì¶1CZVXÉbןJÐA¹ÒKMöS–GõºwÑ×í‚cþ` È1aeÿñG©n¼õ÷Ñ™7çïŸÊœFŸînŸT‡êO÷6ήpMëgW7a=_ëŽ1T^¶Õo&Œ¦ßÓÔ‡\œ"ÚË •×)-E.eÃîi¨¨Ý·ŸsÿS„/ ü†š(Aæø+ÇŠI*ÎÓüúÆjÚˆšµmiäXý…EŸç¤9q/¥%p¯ëç As=ÜÙ}Ú•;Qlir®©ù“ ÿw-db&Ñ = ¡.b¸ÝÀ¹P¿¤àÅЭÑ#m„ɲ]¶ÇeÕù-÷uÆÇ9—ydrwÙxm£ ]Ô(IÇéÓÂQ„V‹I/öVxÞж[óVmyc~|´‹ÎññF-]£ÇõF$ô{Ç•þò"‡‹Èu*'¥æ/Tw)þñ/ ‰_bbèø†èh³H‚y5(Ô23^K~xɱVÊ+˜H©·1›)¿h¤GP~,”é;¸0ÇPÝîDÀ³Ø2y(ï³³RTkÂì¢þ•KÒíÛ/ Ôkz2,ƒÄUHH,[¤÷žÆ—ù­gÜBþîÕLM*g,ØG‰³Vî«LµÎ¸NÆ›þÜþ$î¯Di$uôìØ‚´)# 1%}>Ò-2¸ßL1­ø¿²s5ûvTëð$‡.2XPPù8ú¹ãsµïõîrRÎÁõ„¡Ï¸¨›â•þI=¹“ NOCÕ4rʷ鯲›lYõéjÀ‹¯>T1w=/&6‹ü9ìæ·äŽui]¹%3ÁÐ.{~Sé…*5s›3:Ô„Ù“ü*·ÂÖ5pFÍšm*sÚ»°©’aÅ:kïÃõb–^4M"s2Ë®EÑ8Õh¿]œ·R´Ɇ¥ŠÚh6lXq¦!JpAW©!lx’YŒ¡›=’ÍÓtúñPJ—ép —Ý@ÿÁ$]C2R7qlnOÊ—*k”(Ú…V¯{­²ÏRw#XLÀ#btJ—Ç-N‰zØÞ)VMÐS“Æ£<^É™¯ŒuK ¥¤‘îdçÖMø³[×ÐÁ÷ÛÞóÞkSÙèðËÄÚÎÍÞÕßßLØUÄ Ô:L}× ¤å°6a@/æ{н6X6ÿ]„Ë1_µ8.·$ñúëý2h¤ñ³O:þÉããhIU½”²·–2 Ÿð3”1®.øºò"îf/’’u.3éªZšœ˜­9µÀµ˜…”Û±†mùlË—‡Ï³'´8/Éu×µF±‹gKŽ‚Ç;`†øç:í·úGj¹ÃÊH‡õi¤ö@É÷²ÇÖiFèÅžo:Ë… õXWzŒ†˜g =çÇ$¥6¸i\üh¸Ôè¢ë9ÃËñüwÑ¿nÊm#p¯=7Ö8wK -†‚˜!Y5ª¬h›Âø IŸsëâÏç ùÕu8᱇¶QøFt“M$Ž×Óå“y'ž‘q޲ñÐEW fáx:„˜û;W7·H þ”ãWŽª—g=p.Ä"®¯·4š©øZKGœòÍ£¾O‡¯ wŽù¦Ú&þ¼­ÓØb½êÇý3ËÌ@1"†r=qoÃEó”ä×™v0™ºpݳ³Ë„ƒ"´Å¡‚’¶Éà#’¨¡Ü‹BÕÝkñ:FñHí ç絬¦æÐì âyPÞÛúóÐn#Z\›É72L‹Šã°-*CÌÚº§´á—µ'摃ì“Ùðú”ø>mã fË©¤7i0?˜ûû/‘ªªÚÜAñ‡®¸»¤ß3¶îew´°éÜÐ fL9QqØ]P ×·²¿èýöФ¤5BéÂKÖÔ( ÿRÂM«bd¦ñbÏJ®¿Ü>å#cãv“¯Š1‰«¹Ñrjºé×M —U;hKË’ºDÐWRIÔ®@$š@ì<‘ÍA´¨ÄDú&„IU©¦"ŸöÐ9~D”eùÖÔ ôTê¬ãœé(¤Çn.”.kðÿ´ ¥®ogï=ƒþ½»þsuFÝÏåþ¢‹·cËáäÖ„þ²÷‡ôŒÃ¢§gÖ™EBdeìºf|íö˜ Œ³Zw4Vçvž&Ê=®ÝÂ¥H‡,d|LÀâ3N‹'¹²7,šsL„Ô]øm³ n-@ܤ¬N&…¬$ÿÈûÃõKÐt|]Øl‡¢óJ>h– -’9„©²Íºi=ÿ¨nuþò©­'h¾N«˜4Õ 7<±–¹ûIíÓö†÷Õ=Î)iÇN{À$dQñãTË0¿‡h¹KÝçµÙÚÒ9äóÌèÍï@¢ËG¢ $éðfKvHÀÑ:ÓÝ&îûAoà `žŽ“DGO?Ìd¨ö3ìŒ Â̪i¢ì'Y"-°ö-¸™¸O-õÂ5¾4¡Ã­š6rMŸ4Éì’‰üË¢¸U9F4Ò±SÑU-ÚÆ -¡à£"Ð,‘gÏKîD~^ººÓÜÉ/Zn\Æ$ÿM­Œù–1ÄŒ)Á×BoÅ£E[âcQóh¨X*úêÊÒO>0”ëw+ÇœðaÚ¨F~¶zñyþþ{ ‡gS(êá9‡&IdÑX2)Fžb¡8ÚËp¤‹PX,Gæ(xõš2œS`º faje‰ªh.,w¤á«7 -cLÇý2 Ža®_š²HÎh2+ƒZj@¥üAnÆÝܧúœt`;æßgŒõµzê×îòx¤áï¹Ñ%–ž{æVp¨XU‘Ãí`ß Üv«%¸‰ø×îDß=pNÞßà`å7—Ò‡Rtó ž5•C{ -L­ysŽ>!qÓ±ôm«¢É‰Èåîãéoª#ÙÎÐ^?ï8–y_å¨õOÇ€«j;‚U㌠-¸Kþ­Óp’¹«³>ú±ägWüD³É÷?æKåÖôm#|žZ¡£ ¢Ieí "b0G`½t¢n¢J¯q¨ÜÜPé¢G08mÜ8Ùªç µÝ¯Ýã¤ßRf§2e±;$D/Æ&.mÈ—(Ân¹\çU"S#Ð!=7±æ -’бà÷+ÐáËú­qJ®lHsIw¹eòª zDëÞªÔ• NÚšO%ÒçÕñr‰½¯=W¸Ë„TF%:uÀ䀙2º,~u‘\ıáýú”oC}xù‘Žq"4{‰ -@ûÅ#\t£¼ó¿º™/K®Ÿ±UgR¯H€d~È -a«Ç|…Á|e¿g½¯ }ð”uT©ûa3s+³Ì¥•¿½ã1KÇ×1¼tþ~¸O`Ë’tyQ[ýÈ—M!›ªo®J¿¦½Á'‚K›ð⊿Sî|ÿ˜û\WAƒ#‰Å9Žê2]2Z³lp‰Fûû–†ÜûO¯†O &¤ ÜDpªV¦8ï…ñ™÷óìº è™zgØùÝg¢‚5¹’-É}P«†öž/£y+¢rC*î‹#&ï]:x"v˜rNµ4¥‹|ÓWíJû`føZ1mü-msFYîÐ:8[Ž–?[¯+v~ôðá²› ó&pÀs–K‘v£y¨¤}Üšÿˆ÷[â01%¸.cœY‰]j˜ª:Ç¿ùö:Qqæ!åµ¾©ÏÁÈégƒ¡¾{£6jÊÑõ({ö;¯`ôô«î½A$äÆä¥=ÿ7<‰†ÐZLLSXëFŠ}Db62×,èÿv;=›#˜‡Ãc(íˆFrEƒÎUA7Á¾ºñ°¤‘ïμ Ÿ³ËØ 0 - ·‘—Vh/†¸MƒD:•ÄÇNñü°†•:#Þþ>PLÇÒwïÿQ5GbÄñ Òû¦ªð@` Ìz(iVþÉOëµ6 ‘–`.¿ô#°Ý;Uº-AnGûnxf³lTÆíØHºcÍõ7<²q3)‘‘Ç~*Ún¥ ÑB«R‹Ï+K¥È›!®)w™øÄ•™þîêñþœCåaIyƒÎ³<–äxŸs²)¬•¢×®8zÅJäó £n©ÌsÌ™æEHœX-z/è=!s_å™B?Êóíwö;µŒ›ô7M»Õö“˜:¨’PGKÐ'¨MÖí éżAJN{QbÆu:V7^Ð(*mké«s櫬é)7,"[›CÓXåºñªÌq…»¡„GÂmb(GXT€,ùÅbo©ðp²‰Ï÷ÖnròΡÕ`‡ü'íÌI êÁ¤Ë­,,ÿ7üëlþ\K -³ãÆ Y§u ïèœÙ+èï°9¤- ˆíRUöMxöOþúíú¡ÅsC¨3‚Džú›„àyEà·£¸q ›—Rôd}ŽO± æé[ÞÄ™G`c·§;[‰^L–çÎ(Ön^v轈î½—’‚IA?‡Zdߦx¶ë‡0Þê5/„·ï0iñUE°—,¿"7ZE"Y÷­à ŒçÂëáÂBG¾8˜¯§µ#êÂ^ êa¹bÙø´­b÷Vîæ×œuHmzæî -P̪è¥Ôqõ D·Š@ÞDzˆ‹òuçöÿäüfN?ag>-šŒÊM©a7šµjª)Ð¥0c1å˜Åêž&¶Á0®ï¸‚«n9¯ÀMæW )õêP&°C˜Ù‹÷¥J@eôOqðȾÿçx˜¡ù3ÜÏú\åušà$å·=„þ’»:0¥äí ¬ {]Û7°PPÎþm1ˆ’=pËvÑ18Zµ±ˆÀºrG»%±6.«ßÌ¢8Î8П«woZKÉ9'çêí#úG—ïj²X+§ÃšP8†»Œݸ¼0J…®D“-ýf¸=_U0óA­ú¤‰Lÿé-àK‘ú¥Ïã&zŽ^Lqêm²ù›_º´~æ9ö$ |òÔ«*9k+ôûÒ—eL€<•Ëu¼É]ý v¨Œº_rœ!¬ß§Ìèèn"X[,#ѬR;Ry\³¥»VXÀƒ±AA+w -©õŠÊ»üyž+¾û™%’I†2£mÞá­¥\÷¤uçó:µš¥WbÕ‘¹éˆ×h'¢IµCŒºÛ ¯uJ*ÓÉ<¸S!ÙÖdNPÂD)­çcÅkø2æòò›9b«Ë#¸ö••v² û›T“Z#¿FýŒcÄ̦ë»Éz,³ý‹ù¦Š{ªÖœÿV¦(Z‰šavQÖK>T«:œcn -JÎtŒa½µ~öB¿çn 8b¦”W»VŽn$èÍñ)4Üê¤÷VûËÌŒ;µ•èN ‰R£ËÐŪ§ýÿ×>Y¶5( QD‰!%ÝHîfà¨Ñ9º‘n i’"]Ò-Ý1ºKÝݵ÷þ‡÷Û}îùçÃyžã•”4|œ"ïñ`Ûý]_€ßÿ¼Ý²í\£$«:ê¯{¶F†Æ»lìÏ3¢?ÑL$G@Öóå×vmôãŠ#Žª×°tή4ËFIñê\é±¹†òã–ÊcLÏBÙðn¶²e™i¤ÿs;<¶ ¼ÿñÏ7JŸ¨ie/þ5÷“FàEZUuç!í¯îðœJMþ•³ŽôÓ }Ëß–~¸ -Âòé€z{JE‰FªM Û„u–æG0i ž³ÍÀ†^µYkúzþ'ôÍòH¬n“È([ÒKFR}ÿ^÷ôdk -±5b$ßì}Cd%#vﱓ*š°ßÉ ‘ú°»­¥8hñÀÜ_Œ»Ð7¥U½2f -b›oÒm÷ãÅY…½jãnQŒ˜fýÊm½­ªm&*þ8”Èç1|ñ˜a¬~– F‘«•¢ûÎòXQ;( _ÆSI0ü+p˜ý&á¸$BF -ý1ì_v#ZâÍ,µgªìVØ -*‹š@i‰úû¿ž8ëäCî3luRŽn£ÒsbX‰É ýÚNã0Lb£?yrK—Søƒ=ÕˆáÜá@Æ žÀlþ ¦Ã<˜'•AÅ87gñU˜ -Üx丛ЕXGŠyº'üá9vµ,Õ½OÓà¬KÏýØIC`­” ¿¸9Âò§é¸ˆ ßcZ”Âh.RÕŒI8¬_$òfIKmÌXró–€àÇêŸ%Ŭg”ÆÂüˆßY'ºVR, ¨B~ ÐÔAQäϲ¯u£s¢€Ý_˜Œ\@øt-ò©Ÿ’>ö‡Q÷FÉÎUŽ«l$Ô.ËW(¦8*³Ÿ{>B7@ -7쑘ôy™Ù7º!„³¶ QèÌL}*Ÿ$‚WVÉÉ®š±Èñ×´//2ZA$¼§¥ªb;>~T6EÕ<Õ¿¿Vj3ps[‡Ú[ë #.JìñåY¯ª0ûì©'™„±ŸµQÖ8}Q¥ÞÒš½.HÒý¤ñ‘õ$=¨â¯oñöaZ]‹#6ž/¿¦Ðô¹e¸ÞZ‹ÇM{ªh= Hp¿œ¦-Õôš£åežÂúz‚€ÛÆ«ì(Onû÷söQY²æ‰Ï&¡I(Ja]U›-fø´Û[ˆÿÞóݦ6vº%š.[Íá§KpyJÖˆàêh2nösjJ,©VŽ&EͯU¨•x9øW+0éOžÜX‰3„\´å‚]:aFïz”* ^Ô¿Žààˆ¥A -‚¾¡ÉzŒ:s[­+ž:[´‚r 7À«_ó熈ÑFÂ2Õ:¨Ù˜-Aè -œÆâO­Œ,Eß÷;XM«âU†æüìeçÎ&¾¸cë2“.D£T«h8&Ëe7nV"ÎCøpÁ¨Ö# }&_ot-ç2ÃæXL¦ºŠðï"’‚Áf&ѭ탔w¤éʼŽE9Ãê¶Y|t\dà=_©Ÿiµª¯9ÅÝU5½<}âoCʬe±É·mQJ_”–õx-ºDïä»3¦Ÿëï"‚_ -{8þFÑÇæ–éì é–sEcø ôc/ ¥Xne­£ß Ip’XÌ,X§x©oÞC§C7}yñ8㟑KÓ•F<Ø—¶cÚùc§>É÷"ÊåæÔYxVì#³í³9y«bTjýé‰NÜáù„…ªjŽ\«WÍX!Ì[Ê뺧b'ÞŒÆ)<$1ôÊÚ[,à§ ƒ@ŽWÃc3/—°WnY"¬Æ4áé[_Šüå–#xÎöf3I¹[V¦;ñ²è2f’a_ÏãX;q)ö&Öö4FØ…È÷Ÿ ˆMóK¶Ñõ‡ºé€‚œ»&nˆ°¤ý‹ëžÜ[}·R½™Ú¾Nò -=X¤9ƒ:Ø•ñÒ¤áiÁáß”×ëù pj2ã¬#C÷€ù=  Ë#; .§Yº°xB±}!ÝA®í×›< ûFÔ9OµX¥|½D;-^Èê-Èñ(õ8¶ºÞsžj‘ÿû_„1Ìo^}$å©ZR‚„ÒE! -†*Nñ(ßc“À“ -ÎQÓp/6è~E”ª:Ý?ªúÚ Oæ˜%3=/4X ýÄÐuƒä–ŠžØ¨ûáá]°ÄDóÏí¼ G‹Æ˜; sL‘yø‹laÚTKcøþÙÒ5Ìg+Ÿû{Dü±Í9­M9îŒu.ÍÁGBLK¬O%¹ŒÔLM…•“–`Ov’T EíûÐÖ[ï21Êsd©Jéšp•˜éø#ÃYÝEö‰¨õrnâ芻‰…ë°¬&âè݃é3N^Árÿœð•ó+fd-9¸U0Ód‘ ´U¥A}ù®º"äöÔÝ© -ê™ã2ú»‚îY$óµÉ•­ßª2^IÑPYm3ïÜÚ×Juý¼=ÕùÌ~9Äÿ 2©”pmPkDÉ Ç¥)DcX¨Ù콘ûk*+ÇMCÆ{Ù´~­Íµ)²è5¿¯ÅL|yÿ1ª5u‡Êëñ÷Òc9„ÍrU ¶óBDøò3TyÈ嘙 SzH1ß+`Îð¶+§`½°W5Ó㎎²ÁÑÃiÁ™,÷ò}cýö3!§ïÒƒŒ‘Pu aÛ›”Ë tòÍ|T\ÅL,pÈBHðì9çÑô)8H-úäjj*ê=êOŽ<™â:õY9­ªÓ=iƒ‚h¾!‡¶ïh­ðç¼×îöÎWc?|8na|qží+¬A}~é{âV+gê7L7,ðt>ÓSÉr¢$˜@ZýaQ»²L=4›Eb ”¶¼ú¨•ËÅ›å/Dj {h>UVÇêúÓ·×!JÞ£ëp‚FL¦DE8"¸FKËyŠRŠàïQ¶ÖÿcFö,nc$õCèÛn^ºËø}ÃÞ‰ÔÕÃìm{ebèÅß5|:¼ê6ÙÑÑçd®‡ÄŽæùƆ ^Ý+÷/Ø:!\ذmeCkn+? äm –ùK'S| j&¹qýÉÆJ²¤µúže•xz2ÙÌBwÛÝ:‘C¤·¸:¥½`RÛˆë1ïN^‹r+Ú©:/cm1+Wã¤àûðó·ê÷$â{‘™à‰¾m©¡¯ÈlXCšyÆïÓ»,P°&Ä•–¤–6Aí³è¼XË4ì¢Ljn¢ ér:S#7v°£˜¬dd÷—“dZ«¼rQK¨ý>¯õ®lH}™‰Óüzôßa­ªëµjÈî`ê†÷Vš¬ŠÖôžÕŽopõÄh€— âc—mNá»’E…¡/—¯ñ­(À»¾£ÐgñKÂ¥K_}dÀç²çšøWNy´bJºœñýÎ^y{D¹¿ áöø ȯ×Íó WV?S¢6y‚ D\ë †µÆ†ûÿ -Œ†<\a/r¼ˆvÈxµfíÉCvP€ÕóuóföÈy§Åm4ÍÛÆajùlW¤JÕ4pñûZ¢Aÿ6Ñ®–B][¢µš×´B©®¦Ö{?q£Q4¢«]*ê f1 ¬Œ*w5#Ò”HðŠ¼ª¡–©ÖËCšŒñÌ®¾”ëÓj¯¼Ã'gE¸FŽ:í·²ˆ¯%u0Aü¼$°aXÂ/ ÷ߵƪÂú¬(ß™uklê..Úá¨etV‡rÓ*$ß;>wYp®Ûr¡£îdʈ†éñÇVéÃhKñ«¸óWCÞ.ïò$.¢oÂÞQ#»Å¹* q¦ûÀ6¸JÔ àÇæOŒù[ôÏQ7óeø^ðÏa:iÄçºb¢&ÙgAÑV£ç\tj†yçר™<£È„ì3tçV(ôßÌh©×OѬEf›½ éÝK•X?`Ãþ7ØokÓÈh_y,Ü÷í½?á¬{®Mpóßù‚z¯–ž§ûëeò eÌtÞøa‚s{ú(5J<iKfÙý6ZilX'Å¢ã6ÉñÃëÓÛ)'´Y¬¼ó4a ³Ô4ǸÔ;ÁñUÁÑu]h‡ÎlŽÑJqz$KЪ@ÊÛ3§Üo%ù˜CS÷.õ„ŠuáDâ°YkÊ5N-¸àî )¦uóñ×RÒŽ»—,â,Öò‘ù;²eõ'h=ö:©aCDcjÏç¾µg"ÁÌû'…@ä¡e;éL7FK@»,ƒýëdE’¹¿eÊu]þ¦&ãñ*çXê R\×|ç>¤}Ð8ûÅò´†ïZúI–-ÄŽwp­íô |Mª›…ÞTõèË¥{E-5uyЪ(Cˆ­ÞF‡ÒogçüÚ3‚Æ?Sh`Õæ²2­£=‚II¥ñ“ÆñÎhÆz[ùP.ÍgN#w£é_á£ãäbJýè ¦3eçø1Î?­úw–û’ ë zT4{… BfA]qpeóD=>ö$”z‹Ñ”H"s›eª+è–Æ޵z lSvöñ©…ï–YöWñǘÛFÆÉð& ëB¼´söÓn>³•ƨ»VjÔŒw¥¿·x¬ I’ERH· |MÄãzÅsz{o ß–ž›ŒD3e'lÁb=âßç95K7ÁœÃ'ç k+'ÂæxAS5#]¡~ Ú§¾wÅäoV¬1¿AÃÍÝ4šïOFG,j‹`Ý8ðE¡4™üøìi–¢L-C^+ÔÜF«Uݱǭ„ŽŠ(û89Aû[¡÷Ó­f)­Æa|é]l©ì™ùÀ`§ª¶p«B8Lúño@}þÐ’F³’Ùa8 -åUÔwUMõ»gÕ"&ÛQ=Q¿Á²p,æŽ ðrÎfœÝ‡Qã³éîtÜt6.§>ôÙêð97›“¡ÞnW‡•‚ø«Ñ¿}‹!®N‡éi…@lã -C•Á&ûA×"4ÂÌ]iÅ Î|,›ž(mÍ…pêÖ.‰ý³oRŽÕ] ¸kެ¢PÖ¡ZÛZŒŽT2Ê©‚pC¯–dô.Rn®f™7£žØærðk®–-!OõŽž1t¿9~‚󖉿·q¼mxYæó”9gK’}ÃÜÕè×å HéÏAf™\pCÊˬM‚._óBâÚjq À¶]qL÷‡ Âa¯¡n—ˆ›´¢('â¥&Cv­pñf–¿‡OFÙ2ö -# ð:øF(‰¥YäsäLèÆùxÂJßÓ%ÌgæÂîˆñe:‡¯#0®ÿëÊ»3¯‡óíLM¤\“wŒgßRkHäŽÅ_KØwÓªÂìni–ŠØ± ¨wŠlNþj sßÑ8vcŸóëœý£jÜk^s^×Zë5FQ’)ª0›Ø%ìlA ,ŒÌ<5e ECkkC ;Y)¡5௙’RÔh²°³3y@€Ðð퀅›› jgïîhafPÿå ¡££ÿ/Ë?.#÷ÿ@þF:Y˜Ù¾þ}pZÛÙÛmA)þ¯U€@È0µ°Dµ¤ä%Ô’òjI -ÐñoŠÎFÖÆY c ­`jç°þ÷`lgkbñOkNŒ¹„†'{ ±Åß0 ›1Ðþˆ`t´±prúû °p˜9Ú‚þÎd°°5¶v6ù§€¿vS»dïh÷×Ãæ/ö—LÑÎ ädìhaüͪ(&ñï:A憠r;Yü…v¦=MìŒÿié_Ø_š¿(ÈÐÂÖ ºþÉe˜X8Ù[ºÿÍý—ÌÞÑâ_e8;YØšýWôG ™¡£‰5ÐÉé/Í_î¦ó_}þ—î íí­Ýÿm÷/¯ÿ¬Áä´6eD`ùö7§1èon3 [¦¶Š”­©€…ùßvgûÿÀ\€Žÿõ?{†æo†&v¶Öî )“¼èoJõÿÊŒÿs"ÿHü?"ðÿˆ¼ÿoâþwþ—Cüÿzžÿ;µ„³µµ¼¡ ð_A€ÿ¸c²€. ãÿÍÝÐÆÂÚýÿðß=5€ÿ®RhælmèøßáÓ ÛšýU„›‘ýßV ' 7 ‰¢ÈØ`jhýwVÿ²«Ùš­-l5ý×8 ,ÌÌÿ S5·0¶²ýgøìÿ†€¶&ÿ½ü¿2ý«x&q5 UUIºÿý^ý—Ÿâ_ýAªîö@ÀÿŸDCÎÎä?ÿ°ˆˆØ¹<X8™ ¬ÌìÝ߃ÇÍÆâýÈø/"–ÿZË‚-ÜÚÌŒÌÌ,€¿ßÿñù¯•5¶3ùgǨ€ mMþn²ÿ4ü;;:þÕö_çþoÓÿ±þ×vÝ€Æë+vƼA–i™é :ÜÜ‘)1í>È‘`ûÒFÕ¢¿»^ß´°]îJƒÚ`ƦžßíîËçöŸ‡Ò´Gc}8ÖT½)Àë|"o +šþô­¯œtGLz¥ÈéQž7K²;P?8˜Õö¦””õJ>`ˆg:Yánžiü(\ +ü°¾<Ù£ø§6Äbw¡5aÔž_|M<}~¢î½…î?$¤Ë‰…§äuBþéçC(øC­B¼ªùÕi{Ju ¡glŸÏÏìC(»ƒ¢ÈbÓËZÁçjð§fÌÁpC@¶VBjä+s^"ò“£œŸpÖj×Ñm¡HNZ¬¹Šù—;Ão{ô«OŠ—©š}¾ŽÈïqM gÀÁõ@‰Î +vÌó_ŸäsýðKÞ`zŒ—6$Aïܪ“³ÖUª Ô¼qTÉŒ!ÝNë”›Å/˜4ú#pöpò>ÙMBˆÁrêM<õlb®‚‡é‹à\jÑhŽ!··qèš–í:—… u>5±“ª——‡³›G¿:×MÎ{òεÁéKœJC·Ò@µ¾/)qpgŸ”­µí‚ ¨•Šgý´»Û]^ÕÞƒÛ1Ü ½û߬Dþµß™á…°ä]xŠ©9ØhNT:™~«„r…7Ôè¯Ar Òx‹'£º줔(IÖR×Äf*®•5`™xZi”çe™•Vê]è®tßó ¦@ßë¨ÖŸ :º·WH’gå Îãí;g¡ÎÞqQþ6ÿ*<È8Ô²nir{:^2‘@àcÆÃLˆ&º¢a™³SûI˜ ¡NÕÊÁãɤðÛeã‘[‹}­H}öA÷4OöÖgí +„7N•{œP¾©3¹¥Œ/Ä[Ö]ªp­Cƒ’½f±eB8|* ÿá´%Q0d’hyŽÏË9€œH7þ5'i}=½ó{LXwÜëaä6Aº„ï5Ëo7F—Aµbñ#¹‰…O[?ˆny= ¯7…³¾ÏÆ_žMSÑÓ<Ÿj²¹O-ÄËOrlºÈ|!•¡ÀºüV„, y©+¥, ßê¹2š_Sûà£#üåž ·${qÛF2<üm=àmûS}ü{/°¥ÖÌ:i­‚ƒ‹\’³¦ææŒ"×îS©ÄÙM>?gЀñ¤kMí!,£sê-Ð@‘œm.êÎ@ušltÚŽ£{±/¦£¢a?©8AްKjðæêBQù–‹Mør“J­õ¡F7ÇET¤tVÂÌ''¿3ÉØn¦»3=æÜ½‰(®!að5÷åñŠ&'×ì ®n612"à8F•–²£ _;Ù¦kžO„ÝÓjwX í¨FVfzÙâ1ÖãðÆé›­iàRQKzó€ü§$·+ ,o@rÂð*šAnú³,½,¶¹}ºeÄ)ywÉG~­(JYœ…Gåy T0}O7&·wŠÖŸ D©ÓÙé@ê±=Iµ~½sŽè#"Jk6ÿ´µªt‰`úb˜B½”ÿ}FžÎå”ê¡scÆ_»K3B|=iLõ÷*öY/È× d@OÏ9FÔ•Îk…&÷;®/Þ¯/]ÁH}ÄËg•ëYnq¿C…å#!èkšž®¸B<.›/æÇ¤¯çXd\ºiÐØñ-z+ŠÉ¥KHõQ´ h¦ÿFÏÀÁÕØ wˆÇÕµÊÉàŽÌ– $^?Bäu):pã uÖêShÏ©ÏUbŸ¼ƒMÝ(¶&gPð \`{$¾ɦc¢¹Ýà%_ µæ”¼:ËÔiÏ¿J”­¶¸•#HÆÌ)o=A¨|iÃHo5¦x8ûÕ¬¹Ùî?[8V=—¦­Mº.ïS`Ç¿%¼à%¨âÙÞëju¦JÕs¦þð²=ö–ÒkŒVH‹CÁVÑ"¯•›ˆøKŒÉúÖxÞfªxkžv7`­ÄJmœ,™iì‹—³é éM|ó‚X2<».Íhì¾0úd²n¬ØÕ ŽgÈ-KÇkenI`sã\ãQ +ï™°H¯Ñq<)XÍe.vUÀŒ‹Ææ6¼j÷(OóÈЍð"AÏ@ ä_ÞžX$#–alxUeh[fdþ.Þ_lÔæ8-®(˜ÙÉë¾—©)ZóÕŸÐ-Ž¡ÀULµ îu!lIã$)ùºI@ÂÁA5ØÀ4“î¬Y’ËËŒÞòQ€!I…ó +Ôû´Þܼõz2‹÷¤#‚JÇ_N‚aºäYCÏ>\z…„–gĈÏs³Ìjd¨¦!X¸ˆÓ wÜ2mö8Ùp!os´C?yTÿ@[Qc×Üÿq…ÒŽ¥Á=5(æÎ¡m³× ÔIìÑ/Ôa1VGKj]Ø w´Ú}oä¿8A#çÁ°\SêœM,ZkyÀºHí(¨ ·³ÔŠSñçöš]MC~ÌTŸÜ¤Pg}÷p€‡€ J¥'Þ fØ‘Vý"‡øíbÇdsªÝë~£vz-t±~ŸU²ôn5\±ìÕµIýS«Uÿ >¢KóHšÃmµ[»nKYݼ øËÈ|(ÚÍs@w³™ >sϽ°V…–šü ®ÙÞÇ+×Xª‰‘†€9õUW«K8†?é `(zšŒÜ›×Io_eîÁ‘Í>&p×$ÏoLòŠJß´/õý…›R-“ÃOÃÄ,Á‰ þØFáÒÓýâùu.Í­Ž©X€²£ÝF:ûL@¥å߸‰+¸CVçD§›î$2ܘ±­¤‚Tô¦:‡4Oòü?ŒÙì7ØC *™VBÆò6Vjó­šÛ¾§ ÷fÝÆ1÷ídž ¿ô |ÒÞÞ@OBG À§˜«T ˜Ã1=Úuø1&\ÛTĉº(Ð64Ï›§¼ì¥—¿ž6ÇnÚ4~ÆcÅÛ[zFbÆ’RJ»žƒ.¶¡ÖkŽãÃÞDþÈÉ+GâzƒîÔ¹m_C|øþ0/–­Xµ³-`_1+Rå¬Ë¸ƒðžM*&`*ó|ÜTF-ò\<óãT¢Щ› 7³ Âý7GÓ\[C2Öb”Ÿ‘„fÊPš{í›ÔW‹Ìà±(B(¾\íɵ^*L²€N8)”póiÿ *aG„ò7(…ÛŸòŽUvÝ9ÝÛ” NŽri$!誨’«¼Ž×ãý±"ðníyæñàg±ë?ϳ· ÓøÖ8Zj"kô 䓆üùàÆUb´r¤ |Ù÷̓ÌÛ­ç,¤p†é÷ƒ³ÍÚ…ïßý«½ >õz´ø#㉸Pb¦ÝÝ7K"*t²[ÝqýXÁ2¢?Ù®Î>¿cQµôÄ +³ì$"½ƒd" <Ò-ד º!ú!áŒI™o‚öé­•“0óV;q„¿kù ÚAƱç!²‡Í¹iÉ—?E«\6ï•qV½w8á’Ž_ö3—‘¡DÏ RöpÓd‡á~.ÖàËR“Eû?ø¿±ó­šK1à +v¿»1 ëæƒÙ(ˆ¼JCü +à+N‰Ø5ÚNjÔÐY›€¨áàݵiï+Zf;ˆ?Çåe³ÙvWà·kŸÒÅüµ—¢I¹ë´“F4{½*-5 …)2x¤iÎ#§·5ž.‰©sV ñº^ñ¼ëÓýªÀ›`õVÙÅ¢UR¸¼ûpœ“åæ41$ûFÐ8ªŸ8 lV{v”ƒîÞw©³î~¯ìýý«&À꾃~èôÓEKå½ây­ Dj”¹÷-vá'†H=~€Œøä“þܦð!UMÌÆ‚qzÝKs"œÏòçžNIZÇ&s™/í}‡•‚ðQE´¶åï¼1àE˜»×AÖö¹›€Ú8!ZŒ%©u4¶7×)-¹¢þxÏ ÌŠi#Ò},V{ 3ê™Lk0Ûd±À1èÙýåÇN@ˆñ€ÖXzdöi¢ð»†¢”YµÇÙ¹þÕ‚ÅmË.»ÎÅ)6>NSã"jú¦HËèË­LnE™ƒ¦üÂKh°ï_ŽÆˆ\RÙßC* 5¦ T(´eLjÔ9úÞÓ…eñrWtA…¤ÙlõtŽcKª¿ÔL©ÓšïÃÍCm á‚cÆó7ªÓû:³HAÁÏÑ×$k!å8Õ#[;mñW¨$¥„ÊQã]T”PpÎÊ©j0)¤p)8H‹Ûä—4ÞÌd9ãYVä]mze;ûµª.ò+ÜôÖÆ¼9+C­…ŒµÍ7ÈÀaÀõñú%B{PçÑó²ŒG>¦ï\8ÞÓ>\ùë +¾07ÙtîRÝçP{myZí2÷<ijœçâzxÒô £'2ºñÉþD–£,9tÞ±¾vR§ðSpCŠ%è²³O»¢‘χæhÇeUfL†öH)”éßѦ"¥2¦TVÞ¤Vx/>’^޳Š$pEÚŸ ºþ<˜÷|š‡+œüäî˜jlJ¢ÂKiMù éÝÙ—áø~‰Ò!ÖQ‡ü{Ç´ûô"¹HПc!v©+2é5ÍlqJ®‚MÏWàï3hŸsÞ:®ÕýT‡1›ãð1QâÑ?nÑa»A› ²¨ÍÜf§”RéTø§qÉíæÛ·>Åé™*QÕŠú™Égš¾p¸ãù€ß°L£¥ÍùŒ„Ê«˜½HÔvN„4'F ­Ÿ_?jw­í€ë`Dz?ú¾É¤‡ªŸ}¯? ]{•jåqL®tsµN!CPóÅñ5ˆÃ·Ì|Ïå~º0È žÕ iê“Ojh¤Jb§ =¯ÉŒÕÿ;Ñõ¥efÚU»oÕŠþ-gì©Ù¯–Ï‚ƒ‡ÐhèCÌÖ¼Á‹Xž 0Kvî5möAœáÅ\AW*£PôŒ~é_rqúõ§EÓ<ÕÔCvCX± ¸q`3'¹¤­„{èF°–$õh\..‡ ¤õc½ÑŒ â†Ù]ÖÛi ¹ýhIèu ü–¶ô#”;üÌÎl²k¾HSEb0pßÂéôÈUÖùz¶ˆ~ë> +º.F5|EKÖ_kßU­†Ä&“ó"÷•€äûdÎ…#æ›5åØK"20¬.Fí¢Jà(2\࢚z~"‚*X¸×”•›¹-=‰Œ!‹2 ZK …‹3…~`ÊòJ&qðmvpˆ;¢¬¬Õ¼}ÜtЈD½N¸Q/pÏÐ@Øy)diDÿD¡L"Y ^ßî/;>Ìûjö‚cÊP;É)>¡ˆD‚qL¢‘hF‡\§›:ÄzPªÂK b÷{Ž:bÌ_ÊúDÓýx©4—wB<ÂhESUÈyè,ºf=°jŦc³Ûb¤€™×Nx”ØBÞ.Ô¿œÃóoRKŽNMðͱŒNpt ØA¬¡â ϹùèÓAØûE lÞn_V~M TÈüð +ÛIX¨_QW:ÿµ ]úÐÀï9Lœ`]fd„ú1ØñœÖʨó™¢r +EþØÜlgøÕ_:jûìe ‚¡¡¬¯ 3"=%…m7áûìç‚=~WéFF× 4"K¬³DÜ'ªÑ?¶úï…nÞüú +M q‚8IoÜ•ªÅö›ÍL-Ô…`€ToÞ½*Pvz:N“x ›ÝžÜ™3*IŸeÀ4µô +;S9Á%]9Ao¢ÁN©‡’p6/€ôJš6:7õ"élÈ2îqœÞ܃A«ñ)Û«Â!F—?+Íõ­ÙV³d$7ÁÌ&áýWW(Þg0 ÎÜ#Úž8¤;ßJì­¯ý‰Ù¡L¹ŒÙOÝ5 oYÖᘠ+AÒà}…a™5‚>ÂÃNFØX4²–€žÞri¸™½‹…:'é‹NÎXªËQ±lC#Ë4’w‰ùŸÈ>ßOºÒLZx¯dTH‘™‡Ø*:ÑP=@[›CQƒi«m®þ²´! +ÚÕìΨWtŠã ?oAZdævò6I›¼)’þ‰èRUÛÌ(Á@Ú”µ²âa»¦Ð£ñ Ûå²ÛšÖ/ì¬ý&Å%é¾ACF÷êÏa¶šƒ;öùZjûâÛQBÙ„ãljÎYIN«ä…{Ïy|—hX®t²RML‡WK&q¨aEPjÍ–_ê›Í2ÒÙmYL¡£Ý§ÎŒrêgsÓ¯NãÚ‹+A׃²„7g¨ëÞÊN óké…%¦~aÝ–o¥­~F¼».û#3{9D«Áä1;â´æ ÍôQôÃZÏú8w&_a†¶j¡ã÷q ´r©>Ý}~9ÃQ‡“¹ýñQËöš‚¸¸ÅÒRß +nº_Ø;úáW„ZÏ(œd ÆÅÕ>¤õ„‹ÁêÍ¢*qöŒ‚#röwQ;£œjÚÆ^kNÿyŠÕzÁ tjY×rCD[")Q’£#˜Øn]Ìcõ(ð(»CÈ=g}¶F`³k940Œܧk¤ÿe:ä#_tRáY L©£½N‡íAKZ' KLH§£tvH¶ÐSÑe6óSò<ø]©k>¿2 GÇNê#u0UóQŽÅÕòK»/ó<'\`ÛyæÒ5êLZ íèÄn™çšz‹ˆÆL²˜)ÏvŒX¡[M5þÉž„¤´‚o®HõÌLg‡œQäzä<¸±5î6Ýc²±ï.U¨vÉM{bUWåL¼Ù¾Î,mxÙ*û+‚ikX‚â{uõ<„NZ'8ƒ,T¥~ Xè%{2Ñ/f>[µª¦Dîïö|Ý¡±šöœ©.q´Ÿ›l¢”„AMãSæKæí3r,ÁãZ<Ë›¬ïám)œ+h¯zìÏa~¥^Ø‹Yºxà½M67­ +}¾Q@°ë_Â! ¡nÒ q£^c7Nh?–Dbk]z‘Zøù·Íà[ÛX=mÅ›P :žž‰ÍW½G°tC#<áß×V Â'¦ŠÒyÞÄ1ò\ðÎòˆ¿ƒˆ§9&åŒÂT«âÞ°;¯oQ +Äd²’Ø[EÜ­°¿ÈÇ`n—ÅædþǦiBŠFtù£¿ mŽ<{ töJD|Ï;±Æ&G‚iþco§Àå²-çaA3©±W(æ‚2MYÕô(mò¤ œFã³{gþz&V__éa6ÎÇp›¯ØalĺÃuwðnæc"8¡n‡:Ñ!1w‡Í‘˜Ý¿g•à ˆ%ù[ÛÃÞI‘nÓåÙ–~gdº/~û¬ugÉp¡`ÁPþôTiHŸì2\)ÜЙÍàÿ®ºþ0æ‡zx)œE½ Úéq;7,¦ýs¸ƒ,ª‡izÕ­éü*ið¾\~]•mî§Æ Æ K•!ì†ß!ou4›¿›û‹†«ðw<«^UG‰/)cy¯$Ë‹> täCÔž•6rеð‚jåº)×ä; æC'17'IÙŬõ1:Ï–¼pV%¤»Ã +2°ÅѦyWýö¾¥jÖÎŒUËü«üÂ@¹,íðÊ&©¾JèS"§oóZ²,¢tëpbýèÒúc•û"i}„¦Z~K¹ŠX`i~l…`šúI‹%âù>ÑH—ÓVÒE©ÆÅU …ú©KÜÖ·w+ÁJS¼=öËŸ.Ç=|µ >üô=ÛŒ +’ú C¡ãa4Ÿ—7C‘ªÜ݃~Z¨‹ˆÃ©µ»*‡‚s· @qp![~_£Œ¿:[8&‹”ŽËNp€0ËtÃ"¤ü4q%¬i¨•F³høð¡HÁ81äј=Þü2¶ã³âL˜lƒK¯:ÏÂiåsB¢/]ûP6•[x² _#6}°Åf T¬…%*FųÖËÇ}Ù‘8?´Ï›P Ò¬“ê<7í¹õìÒÂgVq_î½ò±fKú–lFîkÉ(w(:Wâyx­¹CIBÞâ‚Û¨[NõbÖcpq¹Ú4j´¥"#žþs7¾hÐag•Þ^c QÔ'?ªæå´AÂÞÊ…øh¹(LMa.‰(<ûù ¹â¹®ÄÃä%ÄkëºT)ƽØGbª8Ø—ö×tà,D¿“¿¾µ•*Òš.S:µ›èY|Ùä'Fz„yÎv~lˆ²Ð…ÿþ5£àfâ¤û–¤A-í-³ñsEZEÄ÷QàÝÜ=‹þ‹ÑMTsî›?8á‡t2eVe&…¾1›B¦\q(ɽAˆð"_²ó8ŽvTD=°e™U³ÓÚÖ®e#"EîÍÌ-ûax‘Se¯;ŠF$­àÈY‘×Ç7¢=HÞ¯½~òp±Õ¿þ) ’ýÐ+PXY-x"yQùºì€ìCˆ«=³&o™ù…ŠÒ¿$¿Bb‰ÔÜ“Q80ƒÁ˜jU¥9Ãüró5½C£öñ²·Ëä—A<Õ¦¡1RÁgó[¼X- ?¼§µebÑ×k^6*Ù J ¬(І¦7Ü1)ºPïNଛ/r§t ªX¥õø&™ ¥ƒÆôÏážµÓfÇH­öõŒ’°.ÛJó9øP>µe't§l†ƒì1M¾#,Çä1¾#Ü­ÕÄš#[ÀN).·E¶/°6~ª§ˆÄ•T1˜ôY¶#ß:a³áI]ï¡‘g=㟗ì26®HZÄ+ØÃîk +z|~ÝX!ö×½’F`à[m”Ý»”}«SqÁM÷]»&ÃÍÝùԛꚥ‘ü…@ÏHÈúû Ónê +c—™XúAÒœü.; ®¯˜›'·Œ©½C›ˆ^zºnõâ塳ýæzI‡•f®.µ[bO\–äïoË2@c„ÓRvÛQ“5¦_nuˆ+ç±Þ0p%í(p“ ,\íqºGÞâ•ÕœJÈzpˆF­zè€ÙB+>„ iÎÞbcýЗޜ:È3\0/¡4ÜcàˆýÚTÑýŒ§m q¢Òß\cÇ úb{OhD~éì#­Hýð&Åû˜éì¿Íäj…¾d›ÐTC ÿcä¢Be({fŸ9¢z±í¯ãîí+¸ƒ»ˆÚ2HŸÃ{Y³ït”CX¿4±5=vßê „$òVëlY„ÒT PNóD© “¿÷Âá4¾4k[ç†ÙÎ|y©RøŒ³„‚KÝOsOsN±< –$õ ßO8,xìÔÝMSc1#ØÐ¥[±V¤Dæó:1lž ÔzÔ,•é$âλ›¼ôá·µ©¤C}cç +RÐ%åØWÔ糖Î;ÇOÏØŒI“ëöL%Ç’,úÛ¼F¬>žÜÁ|á™ôaײÍ4˜m?3’V=·_L=Rx;`‚i<’kav`Ä óè·¶²ú0 +pºs*Å"øVŸûå¦ä!¥`˜nƒ³ß+ó+ŽµÐ˜-”a¦¿FJá`éˆöF%†m„lï×Ñ|GÅ“ˆ9€lö,Îh¶IŽ¢‡…ÿNEI ýõ>ähÜ—ð¥‡Ôâ VG¯ªuIl?¦_a‡EÁX¬¬¡Ó]VbîÒ\ß0—ð&®Bs:¹¨k~`µ8î¶ÈÑgk[÷Þ–C*qÁí%b,ˆÍ¦Y=S„Ü›)kT}3ÐwZúY+Ì¿¸‰Z™ m@}‹å],×jIºJëÇ™Œs³mæ™!É=â1P1@\¨²5ãd £ÊÕ¢+ 3[9DŒ§Ý´º;A‘þsš-lFQRÒÀöÛa¾Övþ[A(Ïô䕨:>Üa$/)œ¦ÿâMU_q£ªÀX9ð(ÂÙ9Nø†Ó3+öš¸wQžugGвeŽd‹@ÂLkZÍöç@QvÛ˜Š!-+¬d±ëO%è \é¥&û)Ë£zÝ»èëvÁ10 䘰²ÿø£T7ÞúûèÌ›ó÷Ï eN£Ow·OªCõ§{gW¸¦u‡3Ž«›°ž¯uÇ*/[ê7,›¸Gܰ”¿¤Z·R ®²¡Ï”ÊÇ‚À“É*ì5tõŠQ,öO^ÇHO‡^!VçnõYç†ã2?K0eXËk¦·zy*’"\ü®æj‰¸gFÓïiêC.Níe†Êë”–"—²a÷4TÔîÛϹÿ)ÂP~CMH” sü•cň$çi~}c5mDÍÚ64òÀG¬þ¢ÏsÒœ¸—Ò¸×õs† ¹žGîì¾íʨ ¶49×ÔüɆÿ»–21“膞„P1Ün`‡\¨_RðbèÖ‡èΑ6ÂdÙ.ÛNã²êü–û:ããœÀË<2¹»ì¼‹¶Q†.j”¤ãôiaŠ(«Ť{+ÚE +çøx£ƒ®Ñãz#ú€½ãJÿy‘ÃEäºF•“Róª»ÿø†D¯11tü@Ct´Y$Á¼šGj™¯%?¼äX+å•?L¤ÔÛ˜‡Í”_´Ò#(?Êô\˜ã@¨nw"àYl™À<”w„ÙY)ª5avQÿÊ%éömŒ—êÆ5=–AâŒ*$$–-Ò{OcŒËüŒÖ3n¡÷j¦&•3ì£Ç€ÄY+÷U&‡Zg\'ãMnÿ@÷W¢4’: zvlAÚ”‘…‡’>é„Üo¦˜Vü_Ù¹šÇ};*ˆux’ÆC,(¨ƒ|ýÜñ¹Ú÷zw¹)ç`‚‚zÂÐg\ÔMñJÿ¤žÜɆ'ާ¡j9åÛôWÙM¶¬út5àÅWª˜»ž›Eþvó[rǺ4®€Ü’™`h—=¿©ÆôB•š¹ÍjÂìI~ •[ak‰¸‹ +£fÍ6•9í]ØTɰbµ÷áú1K/š&‘9€‡e×¢hœj4Šß.Î[)Z +dCŽREm46¬8Ó¥N¸ «Ô6<É,ÆÐÍÉÎæi:ýx(¥Ët8ÐËn ÿ`’®! ©›86·§FåK•5JíB«×½VYg©»,&à1:¥ËãŒ'„D=lï«&è©IãQ ¯€äÌWƺ¥„RÒŠHw²ˆsë&üÙ­kèàûmïyoµ©ltxebmHçfïêïo&Hì*âj¦Î¾kÒrX›0 — ó=è^›,›.Âå˜/Z—[’áXýõ~™?4ÒxÈÙ'€äñq ´¤ª^JÙ[K™†OøHÊW|Ý@yw³IÉ:—ˆ™ô U-MÎL áÖœZàZÌBÊíXÃ6‚|6å˃ÃçÙÚœ—äºëZ£ÇØÅ³%GÁc‡0Cüs‰ö[}‹#µ\ˆae¤Ãú4R{ ä{ÙãaË4#ôbÏ7áÅÂ…z¬«@½‰ FC̳„…žóc’ÒNÜ4.~4\jtÑõœáåxþ;²![EâOB ÆwkäL•1Ó-M‰Ë㤶@fõ$²&©U"Ë*u A½ +¼ë0å ®ÏØ¿îZïܪc~[Q7µê4è©Hšñq‡Ôø°7ò=­³ž‰’ §™òÆú˜“duˆ?ÎÕ+r^9kæÖqæ§œa^NžbÁ:ÐÞ“ªC=>JÅЕd›dg‡¼]ÕúˆËz@øeaªCšs5z Q/FÐé­Dú÷8È«âX²D›íŽO@Ñ% U÷Méd>kZ|èdü%ÎÐ?,cYÎMw5ÊÃÃP|øTëZBŒåæxM~`Ô•ä×P +Ïoé†-Ë»ç² ¹ Y¶ñ­Î±‹èÞÛ°ëÙC¼aŸèß7嶸מ +뜻%CAÌ‚¬UV´‰Maü€¤Ï¹uñçó„áÜêÀ:œð؃CÛ(|#ºÉ& ÇëéòɼÏÈ8GÙx被 гp<BÌýÀ«›[¤Êñ+ÇÕ˳ž8b׈×[ÍT|­¥#NùæQß§CW;Gˆ|SmÿFÞÖil±^õãþ™ef C¹‡¸·á¢y JòëL;˜L]¸îÙÙeÂAÚbˆPAIÛdðIÔPîÅ¡êîµx£x¤ÀvóóZVSshö†ñ<(ïmýyh·-®Í䦊ŽEʼnqØ•!fmÝSÚ‡ðËZŒóÈAöÉlxýJ|Ÿ¶q³åT ÒŽ4˜Ìýý—HUUmnˆ øCWÜ]Òï[÷²;ZØtnh3¦œ¨8 ì.(Ðë[Ù_ô~{hRÒ¡tá%kj†)á¦U12Óx±g¥×_nŸò‘±q»ÉWŘÄÕÜh95Ýô릆‚˪¿´¥eI]"è+©$jW M vžÈæ ZTb"}¤ªTS ‘O{hŠ?"ʲ|kêz*uÖqÎtR‡c7J—‚5ø Z‚†R +×·³÷ŒAÿÞ]ÿ¹:#¥µI丙û@òñœPœ p9EñxŒ9"úˆçFëÒ1“ä2cÈÝVâârÌàOÜ>KÖ>uÒ»jì¡ír¡Ž#ú$ÝQoë <µ ƒº²#×_›Êÿ~†L²¸Q“Îxêœ-ñ9t­@i_Àš9™’»ÂuŸîçrÿ +ÑÅÛ±åprkBÙûCzÆaÑÓ3ëÌ"!²2ö]3¾v{ÌÆY­»G «Œs» Oå×náR¤C2¾&`ñNƒ§Eƒ“\ÙÍ9È&Bê.üŒ¶Ù· nRV'“BV’äýáú%h:¾.l¶CÑy%4KÉÂTÙfÝ4„T·:ùÔÖ4_'áULšj€žXËÜý¤öiû ÃÆûêç”´c§=`²¨øqªe˜ßC´Ü¥îóÚlméòùfôæw Ñå#ÑÇ’tx³%;$àh én÷ý ‰7pP0OÇI¢£§f2TûvÆafÕ4Qö“ ˆ,‘XûÜLܧ–zá_ÐáVM¹‡¦OšdvÉDþeQܪ#騩èªmc…PðQh–ȳç%w"?/]]‡iîä-7.ã ’ÿ¦VÆ|K‰bÆ”`ˆëF¡·bÈÑ¢-ñ1Œ¨y4T,}ueé'ÊÇõ»•ã Nø0mT#?[½ø<ÿ=†C³)õðœC“$²h,™#O±Píe8ÒE(,–# s¼zMÎ)0Ý‚³0µÀ²DU4–;ÒðÕ…1¦ãŠ~Ç0W€/MY$g´™•A-5 Òþ 7ãnîS}Ž@N:°óï3ÆúZ½Fõkwy<Òð‹÷ÜhŠKÏ=s+8T¬ªÈáö@°on»ÕÜDük w¢ïž@8'ïop°ò›KéC©ºyϚʡ½ +H¦Ö¼9Gž¸M‡ôº„þP¼¡ïÒ4Š›µ.¾êJøiˆG•Ä$ …hÎX÷lÕ-DÞßÍ›á/c;§Ü?‚Ë¥9‡l®Ñ{Ä­Æ»òni†n½$›B×:õÒ©~’Xvy x’9c…Y + w/¼ÞU·O§”~EÁÏAç8Q•|ðŒGÇ=gý9,?YÁ2Ë2L"ôÄEñK‡æPüÚ÷AÍí"I1„'{†§³ úº¿¯c¼NøŒß_lbéøûö— m„nĜɫí÷Zäo£‚³|t0ó>ú>S‹Â™ÔRú—°zaI¿ î%ÕA˜">© •N~ú‚×-† ®2-QVçh-‰úó ýÞpܹâÛ/–¹"5vÎf—GWnT66þ8éô^úÞu¾4+k‹O5Q]¬NÙ  ¡-ël_M¸k˜ÚûAú=é&;4³áhgVå°CºìÞÃ5ÉÕMå×\Æ»8Ô\¬è”&fO³úÇ;^‘RÒ.æ,S–¼÷ƒ`÷‰†¹¼3y°f?s&†ñÊ; WÙ,¼K#«©Ù¯®øbj[¸_VM2ë*BWMЬ3@¿1(Ÿ¸éŽ÷ÏÉXúŒ¶UÑäDär ÷ñÇtƒ7Õ‘l g h/‚Ÿw˼¯rÔú'‡cÀUµÁªqFÜŠ%ÿÖi8ÉÜÕYýXò³+~¢‹Ùäûó¥rkHú¶>O­ÐÑѤ²v†1˜#°^:á?Q7Q¥×8Tnn¨tÑ#œ6nœlÕó Úî×îŽq + Òo)³S™2áØ¢c—¶FäKa·\®ó*‡©‘@èž›XsIÅXðûh‰ðeýÖ8%W6¤¹¤‹»Ü²yÕŠ½¢uoUêJP'mͧésŠêø?¹ÄÆŽÞמ+Ü¿eB*£HH:`rÀL]¿ºH.âØð~}Êη¡>¼üHÇ8š½D ýâ.ºQÞùÎ_]Ì—%×ÏØª3©W$@2?d…°Õã¾Â`¾²ß³Þ׆>xÊ:ªÔý°™9•YæÒÊßÞñ˜¥ãë^:?Ü'°‡eIº¼¨-„~ä˦MÕ7W¥_ÓÞàÁ¥MxqÅß)w¾€Ì}®+È Á‘ÄâGu™.­Y6¸D£‰ý}KCîý§WçRPn"8U+Sœ÷ÂøÌûyvÝôL½3ìüî3QÁš\É–ä>¨UHC{ϊѼ•€Q¹!÷Å“÷.¼?;L9§ZšÒE¾é«v¥Ž}03|­˜6þ–ˆ¶9£,whœ-ÇËŸ­×;?zøpÙÍ„y8àŽ9Ë¥H»ÑHîÍÄû-q˜˜\—1άÄ.5HLUcß|{¨8óŒòZßÔç`äô³ÁPß½Q5åŽèz”=ûŒW0zúU÷Þ r còRˆžÿžDCh-&¦)¬u#Å>"1™k–ôÿ »žÍÌÃá±N”vD#¹¢A窠›`_ÝxXÒÈwgÞ„ÏÙå 솋ÛÈK+´CܦA"Ê +âc§x~XÃJo(¦cé;‚÷ÿ¨š#1âŽøé}SUx °f=”4+ÿ䎧õZ›…HK0 +—€_úØî*Ý– ·£ý7<³Y6ªãvl¤ÎݱæŒú‹Ù¸™‡ÈÈc?m·Ò†h¡ˆÕ©Åç•¥RäÍ×”»L|âÊLwõø Ρò°¤¼AçYKr¼Ï¹ÙÖJÑkW½b%òyQ·ŠTæ9æ‹Ló"$N¬½ôž‡9ȯòL¡åùö;û¿ZÆMú›¦Ýj{wAÆILTI¨£%èÔ&ëö…ôâÞ %§½(1ã:«/h•¶µôÕ9óUÖô”‘­Í¡i¬rÝxUæ¸ÂÝPÂ#á61”#,*@Š –üb±·Tx8ÙÄç{ëG79yçÐê°ÀCþ“væ$Põ`Ò匀V–ƒÿþu6®%…Ùqc†¬Ó:†wtÎì•NôwØÒPÄv©*û&<û'ývýЊâ¹!ÔA"OýMBð¼"ðÛQܸ…ÍK) z²>Ç'áØóô-oâŠÌ#°±ÛÓ­ÀD/&Ësg k7/;ô^D÷‡ÞKÉÁ¤ ŸCH-²oS<ÛõCoõšÂÛw˜´øŒª"ØK–_Š­"H‘¬ûVpÆsáõpa¡£_Ì×SÈÚua¯õ°Ü±l|ÚV±{+ wókÎ:¤6= s÷(HfUôRê¸zP¢[E  ïcYÄEùºŽsûr~3§Ÿ°3ŸMÆ?å¦T‚°ÍZ5ÕèR˜±˜rL‰buO[ˆ`×w\ÁU·?‚‹œWà&ó+Дzu(“ Ø!ÌìÅûR% 2ú§8xdßÿó <ÌЃ|Šˆîç }®rw‚RÕ:Mp’òÛBÿÉ]˜RòöÖ„½®íX((gÿ¶Ä?ɸ‹e»¿è­ÚXÄ`]¹#ƒÝ’X—ÕofQg è¿ÏU„»7­‰¥äœ“sõö‘ ý£Ëw5Y¬•ÓaM(Ã]Fƒn\^¥BW¢É–Œ~3 +ܯ*ù V}ÒD¦ÿôð¥ÎÈ +}ˆÒçq=G/¦8õ6ÙüÍ/]Z?ó{P>yêU•œµú}éË2&@žÊå:Þä®þ;TÆ +݂Ư9ÎÖïSftt7,-–‘hV©©< ®ÙÒ]+,àŒA‡Ø  •;…ÔzEå]þ<Ïßý‹Ìɤ C™Ñ6ïðÖR®{ÒºsŽyZÍÒ+±êÈÜôÄk´ѤFÈZ‰!FÝmP€×:%•éd +Ü)„lk2'¨ á"€”Öó±âµ|syùͱÕe€\ûÊJ;YýMªI­‘_£ƒ~Æ1bfÓõÝd=–ÙþÅ|SÅ=UkΫ +S­‚DÍ0 »(ë%ªUÎ17%g:F‡°ÞZ?{¡ßs·1SÊ« „]« +G7ôæøÆnuÒ{«ýef‚‰@ÆÚJt'D©Ñeèb ÕÓþÿkŸ,ÛšŠ( ¢Ä’n¤Gw3pÔèÝH·„4 I‘.é–îÝ%HŒîîÚ{ÿÃûí>÷ü€óá<ÏñÊ@J>N‘÷x°íþ®/Àï^ÈnÙv®Q’U õ×=[#Cã]6öçÑŠŸ‚h& ’Œ# ëyƒòk»6úq +ÅGÕkX:gׂ še£¤xu®ôØ\CùqKå1¦g ¡lø 7[Ù²Ì4Òÿ¹[PÞÿøç¥ÏFÔ´²ÿšûI#pŒ"­ªºóöWwxN¥&ÿÊYGú鯄¾åoK?\aùt@½=¥¢D#UŠ&ÐmÂ΃:Kó#˜´ÏÙf`ÃN¯Ú¬5}=ÿúfy$V·‹Id”-é%#©¾¯{z²5…رF’oö¾!²’»÷ØIáMØïä†H}ØÝÖR´x`î/Æ]è›Òª^3±Í7é¶ûñâ¬Â^µñŠ +·(FLH³~å¶ÞÖ@Õ6Jäó¾xÌ0V?K£ÈÕJÑ}gy,‹¨†/ã©$þ¸Ì~“Æp\!#…þö/»-ñæ –Ú3Uv+l•EM ´Dýý_O‰uò!÷¶:) G‚·Ñ é91¬ÄdÐ~í@§q&±ÑŸ<¹¥ËŠ)üÁžjÄÆpîp ãO`6ÿÓaÌ€“Ê ‰bœ›³ƒø*Ln•OA‚+«ä¿dWÍXäøkÚ—­ ÞÎÓÒU±?*›¢jžêß_ ++µ¸¹­Cí­u†Æ…¥v‹øò¬WU˜}öÔ“LÂØÏÚ(kœ¾¨RoiÍ^$Hé~ÒøÈz’T ñ׿·xû0­®Åψ_ShúÜ2\o­EŠã¦=U´ž$¸_N Ó–jz͉Q +Žò2Oa}=AÀmãUv”'·ýÆû9û¨,Yó‹Äg“ˆÐ‰$¥°®ÇªÍ3|Zí-Ä +ïùnS;ÝŠM‚­fˆðÓ%¸<%kDpu47û95%–T +G“¢æ×*T‹J<Èü«˜t‡'On¬ÄÂ.ÚrÁ.0£€w=J/ê_GppÄÒ A߃Ðd=F¹­ÖO-ZÁ 9†àU‹¯ùsÃÄh #a™jÔì‚NÌ– tNcñ§VF¢ïÎ{Ȭ¦ˆUŠñŽ*Cs~ö²sg_ܱu™É¢QªÀU4“å²7+ç!|¸`Të‘…>“¯7º–s™as¬G&S]EHøáWIÁ`³ “èÖöAÊ;ÒteÞÇ¢œauÛ,>:.² +ðž¯ÔÏ´ZÕ׈‚œâ^ž>ñ·!eÖ²ØäÛ¶(¥/J‹@Ëz ¼–F]¢wò¿ÝÓÏõwÁ/…=£ÆhŒcsËtö„t˹¢Æ1|Pú1—ŠR,·²ÖÑï„$8É +,f¬S¼‚Ô·Nï¡Ó¡›¾¼xœñςȥéJ#ìKÛ1íü±SŸä{årsê,<+ö‰ÙöÙœ¼U1*µþôD'î¿ð|ÂBÕF5Ç .‰Õ+‹f¬æ-åuÝÓ±oFã”’zeí­ðÓ„A ǫ᱙—KØ+·,V cšðôŽ­/EþrË‹î ×öëMƒ}#j€œ§Z¬R‰¾^¢/dõäx”z[]ï9OµÈŒý/Âæ7¯>’òT-)AB鈢C• §x”ï±IàI稂i¸t¿@€"JUîU}mÐ'sÌ’™ž,Ð~bèºAòFKEOlÔýðp€.Xb¢ùçöÞ†£EcÌ9¦È<üE¶0mª¥±|ÿléæ3‰•Ïý="þØæœÖ¦wÆ:—æˆà#!¦%Ö§’\Fj¦¦Â‡ÊIK°';Iª…¢ö}hë­w™å9²T¥tM¸JÌtü‘á,H‡î"ûDHÔz 97qtÅÝÄŒ‰ÂuØ VqtîÁô™?'¯`¹NøÊù3²–œGÜ*˜é²HÚªÒ ¾|W]ò {êîTõÌqý]A÷,’ùÚäÊÖoU¯¤h¨,Œ¶‰wnmƒk¥ºþ Þžê|f¿â‰™TJ8‡6¨Š5¢äÇ„ãÒ¢1,Ôlvˆ^Ìýµ•Žã¦!ã½ì Z¿ÖæÚYôšÎß×b&¾¼ÿÕ‰šºCåu‹Îø{é±Âf¹ªÛy¡ "|ùª<ärÌÌ„)=¤˜ï0gxÛS°^Ø«šéqGGÙàèá´àL–{ù¾±~û™ÓwéAÆH¨º…°íMÊe:ùf> *®b&¸Fd!$xöœóhú¤ýGr55õž?õ'GžLq ú¬ÀœÖÕéž´AA´F߃ƒCÛw ´VøsÞkw{竱>·0¾8ÏöÖ >¿ô=Hq«•3õ¦x:ˆé©d9QL ­þ°¨]Y¦šÍ"±J[^}ÔÊåâÍò"5=4Ÿ*«cuýiÛë‹%ïQˆu8aA#&S¢"\£¥å^u›ìèès² ×CbGó|cïî•ûl.lض²¡5·•Ÿò6Ëü¥“)>5“ܸþäc%Y ÒZ}ϲJ¼G=™ì f¡»ínÈ!Ò[\ŠÒ^H0©mÄõ˜Àw'¯E¹íTŠÀ—±¶À˜•«qRð}øù[õ{ñ½ÈLðƒDß¶ÔÐWd6¬!Í<ã÷é](XâJKR +K› ÀöYt^¬evQ&57Ñ„t9Æ©‘;ØQLV2²ûËI2­U^¹¨%Ô~ŸŒ×ˆzW¶ ¤¾ÌÄi~=úï°VÕõZ5dw0uÃ{+M VÅkzÏjG‰7¸zb4@ˆKPñ±Ë6§ð]É"‡ÇÂЗË×øVà]ßQè³ø%áRˆ¥¯>2àsÙsÍ@ü+§hœýbyZÃ÷-ý$ËbÇ;¨´²* #Œ6^ÿ´Œ‹Ä*jj¾}5™üÊ­tÿg ›­ûá=)ìGõ™;RVÛÚ½wV*îM\ˆšhßn`ÇPÙºzÇ'I~©VŽ;&븙i—w âc3:™S‹åa¥40ÏZ: Moè¥Ø~ƒÐ#YcÑV„³IF^¸Övú¾&ÕÍBoªzôåÒ½¢šºˆ<è@Õ Ž!ÄVo£Cé·³s~íAãŸ)4°jsY™ÖÑÁ¤¤ÒøÉ‰ cxg4Hc=‰‚­|(—æ3§‘»Ñô¯ðÑqr1¥~tÓ™²süçŸVý;Ë}I†õ„=*š½Â!³ ®8¸²ù ¢Ÿ{J½ÅhJ$‘¹Í2ÕtKcÇZ=P¶)»ûøÔÂwË,û«øƒˆcÌm#ãdxÐu!^ Ú9ûi7ŸÙJcÔŒ]+µ jÆ»Ò_€[hI£YÉì0…òÇ*껪¦úݳj€í¨ž¨ß`Ù?8sGx9g3ÎîèñÙt÷:n:—SúluHx‹œ›ÍÉPo·«ÃJAüÕh€ß¾ÅW'ˆÃô´B ¶q…¡Jˆ`“ý kaæ®´bg>–MO”¶æB8uk—ÄþÙ7)Çê®Ü¿5GVQ(ë¿P­m-FG*åTA¸¡WK2z)· Ž×?3Ì›QOl +s¹xŽ5WË–§zGϺß?ÁyËÇDóÛ8Þ6<,óyÊœ³%ɾŠaîjôër¤ôç ³L.¸!åeÖ&A—¯y!qíµ¸`Û®8 &ƒûCá°ˆ×P·KÄMZQƒñˆR“!»V¸x3ËßÀÃ'£l{…x|#”ÄÒ,ò9r&tã|¼ a¥ïéæ3sawÄø² Ã××ÿuåÝ™×Ãùv¦&R®É;Ƴo©5$rÇâ¯%ì»iÕav·4Ë EìØÔ;E6'µ…¹ïh;ž7\oqkÙñ*¯u¾+ÍNcýàÿOÃõÿû‚ÿ +¹ƒ%ÔÕÝÙêjýákáüendstream endobj -885 0 obj << +895 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 2 /LastChar 151 -/Widths 2103 0 R -/BaseFont /NHNDXP+URWPalladioL-Ital -/FontDescriptor 883 0 R +/Widths 2133 0 R +/BaseFont /EUFTTG+URWPalladioL-Ital +/FontDescriptor 893 0 R >> endobj -883 0 obj << +893 0 obj << /Ascent 722 /CapHeight 693 /Descent -261 -/FontName /NHNDXP+URWPalladioL-Ital +/FontName /EUFTTG+URWPalladioL-Ital /ItalicAngle -9.5 /StemV 78 /XHeight 482 /FontBBox [-170 -305 1010 941] /Flags 4 /CharSet (/fi/fl/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/emdash) -/FontFile 884 0 R +/FontFile 894 0 R >> endobj -2103 0 obj +2133 0 obj [528 545 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 333 0 0 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 0 0 0 0 0 0 722 611 667 778 611 556 722 778 333 0 667 556 944 778 778 611 778 667 556 611 778 722 944 722 667 667 0 0 0 0 0 0 444 463 407 500 389 278 500 500 278 0 444 278 778 556 444 500 463 389 389 333 556 500 722 500 500 444 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1000 ] endobj -790 0 obj << +798 0 obj << /Length1 1630 /Length2 15892 /Length3 532 @@ -10157,7 +10307,7 @@ stream xÚ¬¹cx¥]³-Ûv¯ØfǶm¯$+6:ìØ¶“Žm;éØè°culãëç}ÏÞû\ûœ_çÛ¿Ö=kTªY£æ¼îûZ”¤ÊjŒ"æ¦@I{WFV&^€†ª–²‰­­‰9ÈAžQÕÁÎð×̉@I)æ 4q9Ø‹›¸yZ@s€8Ð ÀÆ`ýúõ+%@ÌÁÑËdiå  ùËAKOÏð_–\¦^ÿütYÚ¨þ>¸mí€ö®)þŸÕ€@€«`²Ä””ud¥4RŠ) =ÐÙÄ ìfj 2ȃ̀ö.@Z€…ƒ3Àöß €™ƒ½9蟭¹0ýåq˜\f ¿a@O3 ã?Àèlrqùû ¹,Mì]ÿöÀÕ²7³u3ÿ§€¿v ‡äèìð×Ãî/ö—LÙÁÅÕÅÌäè ø›UY\òßuºZ™¸þ“Ûô8Xüõ4w0sûgKÿÂþÒüE]M@ö.W §ë?¹Ls‹£­‰×ßÜÉAÿ*ÃÍdoù_0œ–&Îæ¶@—¿4¹ÿéÎíð¿íÞÄÑÑÖë_ÑÿòúÏ@®.@[ &V¶¿9Í\ÿæ¶Ù#0ÿ3*2öV–ÛÍÝÿs:ÿ«A4ÿÌ íß"LÌìm½æ@ fE׿)4ÿo*3ýωü? ñÿˆÀÿ#òþÿ÷¿kô¿âÿ¿çù¿SKºÙÚ*šØÿø; øç’±ÿ?¼Mì@¶^ÿ7ÿÿî©üw‘ÿWW“¿­±·ü+ãW&–¯ÿ@.’ O ¹2ÈÕÌ -`abû·Wÿ²kØ›mAöÀ¿šþ«FV–ÿ†©[Ìlìÿi>ç¿! ½ù¯ÿ¯LÿªžYSWMSG•þÿ¸WÕlÿΗ+÷¿#”ÿN‚«º—#ð¿Òi)8˜ÿçâ>QQO€7#+€‘‡ýïdc|å`÷ý¿äþë­L\Až=&Ö¿¤ÿü²ü“û? ƒÿF#aoæ`þÏ쨹šØ›ÿ·ÿ4ü›¹9;ÿUù_7ÀßíÿÇú_ƒzÍV9˜ñ[§ge¸Öáæ OŠë ô±B‡8–6ªÔ8ôú§‡o­4~« ajšæýh÷Z:q|ß—¥;íñ¥îM^ù’Óö¢ÿ¦êä¦?d6,EÎ8ÕŠö¾\”ß‚ÒåbÑ<Ø™TQ5,yƒ!žîdw†»|¤ w/ À¢xpDñ3KkˆÃîBkèûqrJ•tüø@=462ü³÷ºŸ>7ž’Ï +`abû·Wÿ²kØ›mAöÀ¿šþ«FV–ÿ†©[Ìlìÿi>ç¿! ½ù¯ÿ¯LÿªžYI\F[R”þÿ¸WÕlÿΗ+÷¿#”ÿN‚«º—#ð¿Òi)8˜ÿçâ>QQO€7#+€‘‡ýïdc|å`÷ý¿äþë­L\Až=&Ö¿¤ÿü²ü“û? ƒÿF#aoæ`þÏ쨹šØ›ÿ·ÿ4ü›¹9;ÿUù_7ÀßíÿÇú_ƒzÍV9˜ñ[§ge¸Öáæ OŠë ô±B‡8–6ªÔ8ôú§‡o­4~« ajšæýh÷Z:q|ß—¥;íñ¥îM^ù’Óö¢ÿ¦êä¦?d6,EÎ8ÕŠö¾\”ß‚ÒåbÑ<Ø™TQ5,yƒ!žîdw†»|¤ w/ À¢xpDñ3KkˆÃîBkèûqrJ•tüø@=462ü³÷ºŸ>7ž’Ï ™**À)—PHW£B¢ªU³m·WÛÔOrí]VÉ• $«ùqyĤ"õÂzŒf<0ëûë£Îðf}/Ÿí¤>bêFè,VØUd‹ÕƒæÔJlNÍo’©+¬OXÏ1Ï-¼§c-NÂ1ipÝ›í\AÖµ?ªª…¹{G.ž'Þ½µ$5õü^oDÌÒ’j8Á¬R/ë‰yÝ࣑<Ì`½^ úêì`uvdé,RHžê$žkK‚>&Y ¤ºÛ”OØ&â„o™kâÆœm§Ù WëÙÉ ¨œ/û«Ð[BÒó´`Ûtä¯äÍN¿GfáĈHªýmVéDÇÏ“Ÿ”Ä÷¦Y_kÉóÍ+èü1pÇÒ¨åÁ³ñÂjD•jÊ @@ -10219,35 +10369,35 @@ MI ¿n$rÝ XðD˜t ÎõÓ…”2§—n„sÞmOÆ„ ˆ;²ÃßshuåU9ñÖ&;y-sõP~K*ªÅz4rnp´}ª÷œõ)RB—+«å—>¢cI£Ž¹w× éhz€Ì\mm £MúHþ×<×|Ìï­&‰ Ÿw³s£Üë+\?VË´<=yò‹ØH»M'²ñÑ67Cøoí+A5x5½·x¯'_Ë c!vÜ~óÓ4¶bIpµP]ãH^ŒúÀnkLßYßÙ„æÀ,•‰)tCœrÀ‘ Çi†Ï±m$hýÈn.ÿ¶»öO¿ªWÂ[–{OFChÓ'žWùÆ*6L‡1±’g^H]u Ââa3ð¸g@—TÕL_1@d7¾ùÁ“†µ‹Œ:…‘XF.ÿ§Òfb1\ÄñSÙ£Ö®TÁIS ÒŽã{9.´ v´ôPš_$ ƒºÃ™.T€Áj”¤RÚ.zàÂiXÎ^;-”ûkwå0HMKyÃûSc-‘tkâôk'a.*bí Û¶4ŠdÇ&ž*qÉŸX‡ÒÝÓä"c°4 *+9‚3£ cáE¢Lg%ãŸïÁó§KíÚï©=ëg‡~Q)œu‘Še7@ô`­¥¡c˜„s2¬ìe/ï´Ã÷5ØI*·[ÔrHîD4;"«hntRÉ´c¬¥ŸýÝ„u å{ÿÁØ }hë …x;³°çlqf—š “d79˜R€2õ¨)iµ†–Gö»€ê&‚—ÜÞ¨CšùŸeVò]ÏÓ~„ð¡T}îY¸dë`XÕìéÎ<òe JË»1ÒXê¤QáÀ#÷gX¹;«ÜÉà{}¤* ½lÈ»€~.ž©kÜõVÅÇ®þÒ€§ú‘7ã$o—#€àkص <Éâ{ -¯41¶{ºQµÚâl·Pãg;‹($@QQ~:ú4¥ /麞e„¼æª't“Ê>~œÍÆTÂ={š÷ÈcW ä­ë6Å͆ÇIjË‚¶{Al ¸¸ ²œís è¹”Lª £ÈàýÞùqœöÇ=*Y€þKTØ&§Ð9æ2ös³Ìü±×îªÊ›õäõ§=ìÌÉIx=ãç7åv[¿Céhw›«Ó(îl*ø®Ÿq ‰Ëb“ÛfÜèY àûYÚÿßRŸåÆ |)¶U-*ª[rᇻ……øw8me-PÍsóQîñúW™N‡vé¸î²”š{e³ã=öEëe>*­xQÿuò_­Rñ„çÒ˜ ¢þ«Iïç?d¯Y¹Æa½/Kz†Âc™›gZ6qæåØöì—3 p0, HÎIM,*ÉÏM,ÊæüfÔendstream +¯41¶{ºQµÚâl·Pãg;‹($@QQ~:ú4¥ /麞e„¼æª't“Ê>~œÍÆTÂ={š÷ÈcW ä­ë6Å͆ÇIjË‚¶{Al ¸¸ ²œís è¹”Lª £ÈàýÞùqœöÇ=*Y€þKTØ&§Ð9æ2ös³Ìü±×îªÊ›õäõ§=ìÌÉIx=ãç7åv[¿Céhw›«Ó(îl*ø®Ÿq ‰Ëb“ÛfÜèY àûYÚÿßRŸåÆ |)¶U-*ª[rᇻ……øw8me-PÍsóQîñúW™N‡vé¸î²”š{e³ã=öEëe>*­xQÿuò_­Rñ„çÒ˜ ¢þ«Iïç?d¯Y¹Æa½/Kz†Âc™›gZ6qæåØöì—3 p0, HÎIM,*ÉÏM,ÊæªlfŒendstream endobj -791 0 obj << +799 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 40 /LastChar 90 -/Widths 2104 0 R -/BaseFont /VZSVYR+URWPalladioL-Roma-Slant_167 -/FontDescriptor 789 0 R +/Widths 2134 0 R +/BaseFont /ODIXFB+URWPalladioL-Roma-Slant_167 +/FontDescriptor 797 0 R >> endobj -789 0 obj << +797 0 obj << /Ascent 715 /CapHeight 680 /Descent -282 -/FontName /VZSVYR+URWPalladioL-Roma-Slant_167 +/FontName /ODIXFB+URWPalladioL-Roma-Slant_167 /ItalicAngle -9 /StemV 84 /XHeight 469 /FontBBox [-166 -283 1021 943] /Flags 4 /CharSet (/parenleft/parenright/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/X/Y/Z) -/FontFile 790 0 R +/FontFile 798 0 R >> endobj -2104 0 obj +2134 0 obj [333 333 0 0 0 333 250 0 500 500 500 500 500 500 500 500 500 500 0 0 0 0 0 0 0 778 611 709 774 611 556 763 832 337 0 726 611 946 831 786 604 786 668 525 613 778 722 0 667 667 667 ] endobj -728 0 obj << +736 0 obj << /Length1 862 /Length2 1251 /Length3 532 @@ -10256,48 +10406,46 @@ endobj >> stream xÚíUkTgnõJÀ+Å€€¸ -æ2%X4-wDP¤2$H20I0@¹,P ‚A…ÊE ÒJi½ ”‹ÁŠ‚§F„‚Ü4 +æ2%X$-wTP¤2$H20I0@¹,P ‚A…ÊE ÒJi½ ”‹ÁŠ‚§F„‚Ü4 & X¹ê -ºè±KîþÚ³3æ}žç{¿gž÷;ç33ñð&8²‘ ØŠ ¤N®ÞA2É833'†ÄA2É833'†ÄràqçÖÉÚ¸¼ë;Y·î¹0=ð"ç4sÇA;hš}„ àD(Vž#Ž-wUÊ£úìùõîéMþÒ'Æ©¦)fÏZ½Ë¥3i±†Ñ¿ß ÓÄßIË(žùÊ] ×d̸6p[žt]IÊŒßÛhìbÔöКûrs›•›ì£`ò õª‹#µí!|~®S^«47—Å>/‡B jr÷<‰ -ÿ®~çœ>#†øEõ©ƒOKëåÚÝõz î®»½N™/ -µÜ:4Ò(®’+³²Zîñ1~xܦ£ûöÞÒ‡ñ‚÷t ¾ýÊ3 —á9¿ÒÈhcÍ~eV”žÂDV)äqNkÏf¦gx¸yú}¡w¸9/)À=à™ZÝ÷¼âirfÇØ–„1_u2óxë‹Á «)Ѹ·6ýbW©_Š¡y$|±ÁÁf¦@Ó±üÌzSä´ß`ø]ØßÅ-LÎæFM¥žýÍôEÜà“ßm, -!üm94¡ÜÜ—=7âjp¢ŒûLé^g_]flBìµ§%õ„DàPYR»rÍü ëÀÎCûîSŒÃ㲎„™xh躗Ë.Ûk'$Ô\—-”…ÌîЉМV*¦…­FÔ=2À5½[wì™üPûR×ÈÉ?ª)–’Öokö³ïOWûlzyàYC?÷£ÐèÎú©_†çÍVS¹Ëúä—pïç7J¿üñ·¡ÒÉðõùWoʯʉ΄։Öþ›E¶TÅÑ“Êk•×Ç$ 7ìÍe$å-ŠOÂé,¶ižï…ÔË*‹GUM=uó)ƒ¢…0订êcú<Êyê<^a?YYêOÿÔ{߯qT1ç„ãó_N’^'v?רk••ù2ªR¦¦K´Z_oõÈjrÔ“ÍYY2(Õk$ûš @šÝî~Ã{8sç—Úµ¬÷U$FÛéx7:á,?ÔyòÓæÝ¯¸ùOiD§È‡‹øÄuþ÷T«TêSFaô{ò€Š1b]aÚù_Ýv*S’ç#¶ä]k¬Øu ÙìÝò€vlÃlÓËD Õ7™U¦«‹ûJ*ƶábuÁÀ$ñö²×p}Â(5ñiQBCG¸ÇÀ\—$§!7!ÇM~9Šœù¸)ökµÑ)Ç÷D_uo€£ŒÚjnÿ=Õáh׺™;wáÔúBÙ˜‹jU´fŸîNç²QÝÖ…Zöî–[£!CŽWµ$Aü6ÍŸd‡š@Â!ß¼tÍ› ‰ˆINzÀxwÁv}ÃuÙF{I¾?>¬iÿ˜ú`v«ç íøT6Ý1¿é0S x}Î䇯£Ž¨Fü׆þÜ×¢¯ª«;rª³+Ù7ÖÅt®]šrZ9µqg{7áø®l÷GÌ}Ÿ3\NkôÏɵV'•Dz;Bêmиƒ’ž˜l/^·`m`onç=òøàþßà¢vuC¨@h(î_<þuendstream +Z$eñaÖâÔÄ‹ì2AHAXæðŸ 2ÃPˆóaΟaë7ðòÐßá¶¡ï, `…Šøˆ»ÿ58‘F(vÁÎû´h4jÌ¿ Y……⥳‰Åÿ¶æð°‘Á°fáz»–}RH^urEìgçnÿIëE[¥ºW³Ù¯66ŸÇŽñ¡žõ2 —Ž+¯—ãCúŸ³ìOꢗ 2ÜÓ¿œ.ѽp%­¨Ü/+žÚDìñÁG&¦ÉÖ¼²2eÊÜ*øZiHoBžùfÛöÞémqm:gÙ*Æ¡ssƒÝÚ-½OXšn¦õž×x>ràqçÖÉÚ¸¼ë;Y·î¹2=ñ"ç4sÇA;hš}„ àD(V^#Ž-wUÊ£úìùõéMþÒ'Æ©¦)fÏZ}Ê¥3i±†Ñ¿ß ÓÄßIË(žùÊC ×d̸6p[žt]IÊŒßÛhìjÔöКûrs›•»ì£`ò õª‹#µí!öÿ\¦¼Vin.‹}^…Ôäïyþ]ýιýøŒâÕ§>-­—kw×뺻îö:e¾(ÔrïÐH£¸I®ÌÊj¹ÇÇHøáq›ŽîÛ{KÆ ÞÓ1øö+¯€\†äüJ#£exðص0Š–©¬‹fdþå—ÌÕåkE%›D%ãÇéýGÁª]à}ÕxÆáœXæ$3M/7øjŒ#ÇÛUY6o”ÕéõÔœ‘ÉûtŒ5û•YQz +Y¥8Ç9­=›™žáàîå÷…FÜáæ¼¤€gjußóЧeÈ™c[Æ|ÕÉÌã­/'¬¦Dã>Úô‹]¥~)†æ‘ðÅ›™MÇò3ëUL’Ó~ƒáwa_·09›5•zö7ÓqƒL~·±(„ðc´åЄrÓ%{&nÄÍàD÷™Ò£Î¾ºÌØ„Øk7NKê ‰À9 ²¤våš'øÖ‡\îSŒÃ㲎„™xjèz”Ë.Ûk'$Ô\×-”…ÌîЉМV*¦…­FÔ=3À5½[wì™üPûR÷ÈÉ?ª)–’Öokö±ïOWïßô:óÀ³†~îG¡ÿÐõS¿ Ï›?2¬>¦òõÉ/áÞÏo”~/øãoC¥“áëó¯Þ”_• ­­ý7‹l©Š£&•×*¯InØ›ËHÊ[”ý §³Øþ¥y¾~P{D².«,U55öÔͧŠ »Šªéó(ç©óx…ýde©?ýS—_ã¨bÎ Ç翜$½Nì~®Q×*5*óeT¥LM—hµ¾Þê™Õ>ä1¨'›³²dPª×H\š @šÝî~Ã{8sç—Úµ¬÷U$FÛéx7:á,?ÔyòÓæÝ¯¸ùOiD§È‡‹øÄuþ÷T«TêSFaô{ò€Š1b]aÚù_Ýw*S’ç#¶ä]k¬Øu ÙìÓò€vlÃlÓËD Õ7™Už¦«‹ûJ*ƶábuÁÀ$ñö²·p}Â(5ñiQBCG¸çÀ\—$§!7!Ç]~9Šœù¸)ökµÑ)Ç÷D_uo€£ŒÚjnÿ=Õáh׺™;wáÔúBÙ˜«jU´fŸîNç²QÝÖ…Zöî–[£!CŽWµ$Aü6ÍŸd‡š@Â!ß¼tÍ› ‰ˆINzÀxwÁv}ÃuÙF{I¾?>¬iÿ˜ú`v«× íøT6Ý1¿é0S x}Î䇯£Ž¨Fü׆þÜ×¢¯ª«;rª³+Ù7ÖÕt®]šrZ9µqg{7áø®lGÌ}Ÿ3\OkôÏɵV'•Dz;Bêmиƒ’ž˜lo^·`m`onç=òøàþßà¢vuC¨@h(î_EÍþ}endstream endobj -729 0 obj << +737 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2105 0 R +/Encoding 2135 0 R /FirstChar 13 /LastChar 110 -/Widths 2106 0 R -/BaseFont /CWTQLU+CMSY10 -/FontDescriptor 727 0 R +/Widths 2136 0 R +/BaseFont /QQRSYH+CMSY10 +/FontDescriptor 735 0 R >> endobj -727 0 obj << +735 0 obj << /Ascent 750 /CapHeight 683 /Descent -194 -/FontName /CWTQLU+CMSY10 +/FontName /QQRSYH+CMSY10 /ItalicAngle -14.035 /StemV 85 /XHeight 431 /FontBBox [-29 -960 1116 775] /Flags 4 /CharSet (/circlecopyrt/bullet/braceleft/braceright/bar/backslash) -/FontFile 728 0 R +/FontFile 736 0 R >> endobj -2106 0 obj +2136 0 obj [1000 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 0 0 278 0 0 0 500 ] endobj -2105 0 obj << +2135 0 obj << /Type /Encoding /Differences [ 0 /.notdef 13/circlecopyrt 14/.notdef 15/bullet 16/.notdef 102/braceleft/braceright 104/.notdef 106/bar 107/.notdef 110/backslash 111/.notdef] >> endobj -725 0 obj << +733 0 obj << /Length1 1616 /Length2 25334 /Length3 532 @@ -10305,7 +10453,7 @@ endobj /Filter /FlateDecode >> stream -xÚ¬ºc”¤]°%\]î²,Û¶mÛvuÙ¶mÛ¶m£ËU]¶í¯ß÷Î;ëÎüšo~äZωˆ³cGìsb­'3Iä•hŒí MDílhhé9*ŠjòÖÖÆvÒ4Šv6€¿f(!' ;[a'N€š‰1@ØÄÀÈ`ààà€"ÙÙ»;X˜™;ÈÿbPPQQÿ—埀¡ûzþît´0³þ}p1±¶³·1±uú ñ½QÉÄàdn0µ°6ÉÉkHÈŠÈÅdUb&¶&ÖygCk #€´…‘‰­£ ÀÔÎ`ý €‘­±Å?¥9ÒþÅpíMŒ,þn3q32±ÿÇE °7q°±ptüû °p˜9Ø:ýí“ÀÂÖÈÚÙøí¦vÿ²w°ûaó×÷LÞÎÑÉÑÈÁÂÞ ð7«¼°èðt27pú'·£Å_7ÀÎôo¤±‘ó?%ýëû ó×ëd`aëp2qsú'—¡ ÀØÂÑÞÚÀýoî¿`öÿÒpv´°5û/Ô3ckGÇ¿0±ÿéÎÕ ø_ª7°··vÿw·Ý¿Qÿ“ƒ…“£‰µ)-ãßœFNs›YØBÑýsT$lMí ôÿa7v¶ÿOŸ‹‰Ã¿ "ÿçÌPü%a`lgkí061…¢“µsú›@þ§2íÿ;‘ÿHüÿDàÿ'òþÿ÷¿kô¿\âÿ¿÷ù¿C‹:[[Ëؘü» ðŸ3 øgÈØþoÑ6Öîÿ§øÿ©fò$ÿ0N[!`köWzZúÿ0Z8ŠZ¸™Ë[8™L ¬ÿöé_»Š­±‰ƒµ…­É_=ÿm%€†žþ¿ù”Í-Œ¬lÿi<˸Llÿ;÷¿ýËœNMMB^TŠêŸ©ÿÆÉÿÕÞIÙÝþ/µÿQŠŒñÿ\üƒ"(hçð¤a`eÐ0²3ý½rŒ f&ïÿCÆþk-càä`áÐú[6=ÿÅÿÏ­tþŒˆ­‘ñ?§EÉÉÀÖøïûŸ†ÜFÎuý÷Îÿ-ú?×ÿu7#¨µßvF\A–i™éNuè¹#SÂZ} #Áö¥ÊE~5v½¾ia8*õ?jƒi›f8¿ÚÝ—Ïì?$)ÇúЬÉzSL®òq¼‰(ú ·H;Ù¨ètKaÓÏÕ¢<¯—¤w@5YéUw§uK>Àqg:™ ¯Ÿ)üˆ\ +xÚ¬ºc”¤]°%\]î²,Û¶mÛvuÙ¶mÛ¶m£ËU]¶í¯ß÷Î;ëÎüšo~äZωˆ³cGìsb­'3Iä•hŒí MDílhhé9*ŠjòÖÖÆvÒ4Šv6€¿f(!' ;[a'N€š‰1@ØÄÀÈ`ààà€"ÙÙ»;X˜™;ÈÿbPPQQÿ—埀¡ûzþît´0³þ}p1±¶³·1±uú ñ½QÉÄàdn0µ°6ÉÉkHÈŠÈÅdUb&¶&ÖygCk #€´…‘‰­£ ÀÔÎ`ý €‘­±Å?¥9ÒþÅpíMŒ,þn3q32±ÿÇE °7q°±ptüû °p˜9Ø:ýí“ÀÂÖÈÚÙøí¦vÿ²w°ûaó×÷LÞÎÑÉÑÈÁÂÞ ð7«¼°èðt27pú'·£Å_7ÀÎôo¤±‘ó?%ýëû ó×ëd`aëp2qsú'—¡ ÀØÂÑÞÚÀýoî¿`öÿÒpv´°5û/Ô3ckGÇ¿0±ÿéÎÕ ø_ª7°··vÿw·Ý¿Qÿ“ƒ…“£‰µ)-ãßœFNs›YØBÑýsT$lMí ôÿa7v¶ÿOŸ‹‰Ã¿ "ÿçÌPü%a`lgkí061…¢“µsú›@þ§2íÿ;‘ÿHüÿDàÿ'òþÿ÷¿kô¿\âÿ¿÷ù¿C‹:[[Ëؘü» ðŸ3 øgÈØþoÑ6Öîÿ§øÿ©fò$ÿ0N[!`köWzZúÿ0Z8ŠZ¸™Ë[8™L ¬ÿöé_»Š­±‰ƒµ…­É_=ÿm%€†žþ¿ù”Í-Œ¬lÿi<˸Llÿ;÷¿ýËœNLITBYŒêŸ©ÿÆÉÿÕÞIÙÝþ/µÿQŠŒñÿ\üƒ"(hçð¤a`eÐ0²3ý½rŒ f&ïÿCÆþk-càä`áÐú[6=ÿÅÿÏ­tþŒˆ­‘ñ?§EÉÉÀÖøïûŸ†ÜFÎuý÷Îÿ-ú?×ÿu7#¨µßvF\A–i™éNuè¹#SÂZ} #Áö¥ÊE~5v½¾ia8*õ?jƒi›f8¿ÚÝ—Ïì?$)ÇúЬÉzSL®òq¼‰(ú ·H;Ù¨ètKaÓÏÕ¢<¯—¤w@5YéUw§uK>Àqg:™ ¯Ÿ)üˆ\ üPˆŸìá|ŒRbQ»š€ê ÏÎIOžŸÈ†ÆGG†{oÁú°©rb’p¹€Â’FúýÊÁæÓT©©jUmÛëÕb3ô]ÿ””s Îl~^õ­H¹²çŸÈôÿbاÑÙ®ïå²žÒæNHÙ ™C ½‰h1R^iC«ÙÂ{»AùÖˆqwÛÁxyÒWcÁ·ÿ¡y÷'‡—ÁOéTñ´šŸ­wôêuòÓsPMTUËçýNÀ(5±†ÅÄ ö¶‘ÛMüc,‚¨×]EI[™Y… ¸îˆ0^ ÆMÏm}™× Ë 3ž@óÉ ª0öGƺ°>KÛyE‡“åÜTh6þÁØŸøÐJ¢w¢§æ_[c ³öB8xÕ¾Vk”Ô‚—I¯¿ä„÷gÞk‰òŒ+(}‘²Å+åýdä„P9Œ,U•äD¡&w("Z·´U¾D£|yÛ)Õ‚þ0ŽÖ)¹` Á6l¬NÒµ½žŒÍ&²˜ W WâãÆ[.¸N5ÈõëZS† @@ -10399,35 +10547,35 @@ A ­u|Ðí8t^ˆš/€‹MÝp­_’<{*ñ>Jn ÐÅ—6¹s²R¯aÆ‹úr×€]9ä¯:²(`\‰áÉlA7¾ĦK”ž·†9z8nb64Ë¢jE¢$µ1V|·ZBËÐöX#Y»ͪföWßqYûlf/ö»­8Fj…›ë_X1¡ÁèínÕ (N1©þ¢CÑð´ýÆ9(AÄEêÞ–«ôáÃÉ€ÖÜÑf}_¢£J¾:¤ íéJ$<ÂBÿˆSUÅöìMø›Yr¤˜¾ÃÈ×`Qíå?›Ù±VƒÝŽˆ½¸ÂˆÚÖñhÃÙƒXÔ‡7Ó¶,Í!Á•FÿÁEè^F ¸¯xÀÁ¦ÿàB*·ÛvªR&¤N<•ê`¢µ+çN¼é¬ g¤£Ê¾2f~mû„m}…i¶xÄãæužÙÆœ»‚ÙüÂx\Ôt{™C Àåò ›ËøýÈ·'5' ªzqvipd×kµ»¶j©@ƒæ…:Íw¾?bøàôVs,%ãIP¡ÍSÃ…„A³ô‰ìDª`Ïûñ,{r˜¦fY—AÀ˜EÏ¡+LNä^õ,¸¬Y¼B™¡9ÛœÐç†dbTC4è¿JLWl©0Âkž ^¸ùT›Úò«¾¦ét«§^Þí§/‡3SÄ蚇dQœv(CÜ쇵È%#¾j0Æ7›5pEZ‡ì—,í¼éÀOÇéÃõ¤¯(CæýéZb4üÁP”™Γ{5Þ…k`åùÃJÙãpÔféAvs,µp̈Õ.¨±g¸Ño¡µ°±P9:Ý,'c|Ì1eÁh†M~‘fQÞúûdú9’LÈúôÖN0–"/Ó|8׃ҿ]‰/ óûÚûس˜z$©Ôü³[<~q÷é#ƒä2 'óP4I×¥ŸÐ?`b¬FH. ÷R}ÿÀ#] «iÀAñ7FÌÐ5øùq6O‰ Ç/êúWbõÑFåq-¢´ð §]xžök%˜Ã–td˜¯‘ŒÎ¼r¿?qEµÀ¡Glq_åOÎ1ŠL$HülÓ‚|²ëÅ›:vÐ Ø›¨†À<¬è2ëg8„7ë%j ÅL/ARWˆŠmõƒÑ ±)Cðî&œ£Ò(q14ŒED;ÌjdW åqêÒÚ8ß'‡õt˜{r›`üz$¸~ЗV-ðr#QcªžÉ¹=H­EÍëCóIîÁÕŒ–aYÅuz8UG²þºÝ¡HJP+dGR]¤IؘNd'×DóN'é[ºqÆIÒĵF,·;Å—d•”©7•‘W­_ˆF®kô­é¢á£tΘ ~­ yTjænUÀNöÂߥ6”éŸì¶\e>:3‚t{ù^÷p*kõ!1ñÖ3«/¥tŒëÖÈ|æeWç¯ÛQ#`IbýÍÃ$ŒPÍXÉSKUŽž¡’` ËAÅžþ›m­%N©ò’÷Y ¥Ê¡K_º`ÕsYGõ¾ìŸö¨,4ƒ“³›¯HC'Ÿû89cá[ã Û2?ÆN¼ ü±ù#°¥ª0ägã¶,Š¢œ¡. éj”¿ê?ÉxG# Ò+“Å.ă-†cå-Yo¢UÄVõñÈö15Ò»æ¾Ýc@@íéíAŸ LüUÜêÏÉ…ÜÔ¿©ÿÌZÏ‚ñåÎSUn9“mbµf[‘€Š±ÑT8D1¿4г#hqÙך½E9É{Ь¶uîœb…M'­?/ÖGÐÿéε%¨˜Gš±Ñ3 ?hßó¤¸þa¶„çŽØyžÓ€’^`´ý×Þz\‹÷¶v«áP{ÑÑ•Ih~×`5»æ0ïfM…ÂÛ -ä&oH[œ¯A•9fÜË•ÿ+J†'¡1ê’ëyC \<†æ›îyʇfäiX.²¢¦ ËÅoöøA…°•#ó3ÆÎÑ—ï;¦ûÁ_;râw‚›ìĽÅzi“Ã+Yxh­ÀêÐÃz5xu¾5)sþ³py}Mµ~à óÿ¸ÿüŸ˜Øš9ÿv°3r¶û?s¹Kendstream +ä&oH[œ¯A•9fÜË•ÿ+J†'¡1ê’ëyC \<†æ›îyʇfäiX.²¢¦ ËÅoöøA…°•#ó3ÆÎÑ—ï;¦ûÁ_;râw‚›ìĽÅzi“Ã+Yxh­ÀêÐÃz5xu¾5)sþ³py}Mµ~à óÿ¸ÿüŸ˜Øš9ÿv°3r¶ûG‚¹7endstream endobj -726 0 obj << +734 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2092 0 R +/Encoding 2122 0 R /FirstChar 2 /LastChar 216 -/Widths 2107 0 R -/BaseFont /WWIPFK+URWPalladioL-Roma -/FontDescriptor 724 0 R +/Widths 2137 0 R +/BaseFont /GSFITG+URWPalladioL-Roma +/FontDescriptor 732 0 R >> endobj -724 0 obj << +732 0 obj << /Ascent 715 /CapHeight 680 /Descent -282 -/FontName /WWIPFK+URWPalladioL-Roma +/FontName /GSFITG+URWPalladioL-Roma /ItalicAngle 0 /StemV 84 /XHeight 469 /FontBBox [-166 -283 1021 943] /Flags 4 /CharSet (/fi/fl/exclam/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/circumflex/quotedblright/endash/emdash/Oslash) -/FontFile 725 0 R +/FontFile 733 0 R >> endobj -2107 0 obj +2137 0 obj [605 608 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 500 500 840 0 278 333 333 389 606 250 333 250 606 500 500 500 500 500 500 500 500 500 500 250 250 0 606 0 444 747 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 1000 667 667 667 333 0 333 0 0 278 500 553 444 611 479 333 556 582 291 234 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 500 0 500 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 833 ] endobj -701 0 obj << +709 0 obj << /Length1 1614 /Length2 24766 /Length3 532 @@ -10435,7 +10583,7 @@ endobj /Filter /FlateDecode >> stream -xÚ¬zSm]³eÙ¶]uʶmÛ¶mÛö)Û¶mÛæ)ó”«ëû¯:n÷S÷}Xkfæ92GÎ{G,RBy%c;CQ;[gZzNE5ykkc ;iA;kc‚3 )©£‰³…­°³ 'š‰1°‰##)½‡£…™¹3ùõYþ !0ôøÏÏN' 3[²ŸWk;{[çˆÿçJ&&Îæ&¦Ö&Brò²bäb²*b&¶&ŽÖò.†ÖFÒF&¶N&¦vŽÖÿ¶ 0²³5¶ø§4'Ú,''{#‹Ÿm&îF&öÿ¸¨ ìMm,œœ~Þ ,œÌ lzàlG`akdíbü»©Ý¿Ù;ÚýDØüø~Àä휜Œ-ì ~²Ê ‹þOgsçr;Yü¸ ìL"íŒ\þ)é_¾˜¯³…­³‰»ó?¹ MŒ-œì­ <~rÿ€Ù;Zü‹†‹“…­Ù1 &p413p4¶6qrúùÁþ§;ÿU'ÁÿV½½½µÇ¿vÛý+ê?9X8;™X›ÒB10þä4rþÉmfa E÷ϨHØšÚ0Ðÿ›ÝØÅþ?|®&Žÿjù?3CñCÂÀØÎÖÚƒÀØÄŠNÖÎù'%ùÿ›Ê´ÿs"ÿHü?"ðÿˆ¼ÿâþwþ·Cüÿ{žÿ;´¨‹µµ¬É¿6üÇC MðÏ%óØXX{üßÂÿ{¤šÉ¿qü¿¡H8ü4BÀÖìG zZú3Z8‰Z¸›Ë[8™˜Xÿté_v[cGk [“5ÿÕHzúÿæS6·0²²ý§í,ÿæ2±5þïÔúq:MAaQiªÿóFýWœüòÎÊö?Ôþ½;ãÿ\üƒ"(hçNàEÃÀÂH@ÃDÏðsà~øp0±øü_2þ ˆá¿Ö2ÎŽîZ?eÿìü§øþk¥óß`DlìŒÿ™%g[ãŸñúOÃ?n#GÇUÿuâŠþõ¿ÝÄÄÝÄj}ÅΈ+Ø2ýw†szîÈ”°Ö@ðHˆ}i£rQ]¯_zøG¥þGmmÓ çW»ÇòûÏ#IÊã±>4ë_½©&×ù8>ÄýˆÛdlTÇtº¥°jÑ^7KÒ» š¬ôªÇûS +xÚ¬zSm]³eÙ¶]uʶmÛ¶mÛö)Û¶mÛæ)ó”«ëû¯:n÷S÷}Xkfæ92GÎ{G,RBy%c;CQ;[gZzNE5ykkc ;iA;kc‚3 )©£‰³…­°³ 'š‰1°‰##)½‡£…™¹3ùõYþ !0ôøÏÏN' 3[²ŸWk;{[çˆÿçJ&&Îæ&¦Ö&Brò²bäb²*b&¶&ŽÖò.†ÖFÒF&¶N&¦vŽÖÿ¶ 0²³5¶ø§4'Ú,''{#‹Ÿm&îF&öÿ¸¨ ìMm,œœ~Þ ,œÌ lzàlG`akdíbü»©Ý¿Ù;ÚýDØüø~Àä휜Œ-ì ~²Ê ‹þOgsçr;Yü¸ ìL"íŒ\þ)é_¾˜¯³…­³‰»ó?¹ MŒ-œì­ <~rÿ€Ù;Zü‹†‹“…­Ù1 &p413p4¶6qrúùÁþ§;ÿU'ÁÿV½½½µÇ¿vÛý+ê?9X8;™X›ÒB10þä4rþÉmfa E÷ϨHØšÚ0Ðÿ›ÝØÅþ?|®&Žÿjù?3CñCÂÀØÎÖÚƒÀØÄŠNÖÎù'%ùÿ›Ê´ÿs"ÿHü?"ðÿˆ¼ÿâþwþ·Cüÿ{žÿ;´¨‹µµ¬É¿6üÇC MðÏ%óØXX{üßÂÿ{¤šÉ¿qü¿¡H8ü4BÀÖìG zZú3Z8‰Z¸›Ë[8™˜Xÿté_v[cGk [“5ÿÕHzúÿæS6·0²²ý§í,ÿæ2±5þïÔúq:Me YuªÿóFýWœüòÎÊö?Ôþ½;ãÿ\üƒ"(hçNàEÃÀÂH@ÃDÏðsà~øp0±øü_2þ ˆá¿Ö2ÎŽîZ?eÿìü§øþk¥óß`DlìŒÿ™%g[ãŸñúOÃ?n#GÇUÿuâŠþõ¿ÝÄÄÝÄj}ÅΈ+Ø2ýw†szîÈ”°Ö@ðHˆ}i£rQ]¯_zøG¥þGmmÓ çW»ÇòûÏ#IÊã±>4ë_½©&×ù8>ÄýˆÛdlTÇtº¥°jÑ^7KÒ» š¬ôªÇûS Šº%`¸3LŽ7)ü‰] üQHžíá|ÒâP»šê ÿ\%ý}þ54>:2Ü{Ú„M•IÊå KåïƒÍ§©R!RÕDzÝžeÌ}øØ"œ³\ʤ!g?5íµ Îk“T $f}QìŒ}}œ7Ãë–aI­zQ£Ø`{1®ËÊ›¡9sõ‰ór5úË<#¤=ø…ˆ´±36…è4Ó+òŽÇ¾a‘Ïp:‰é"“|:[5P6“Ó#\2®˜Æíß»OÍß 6.â'¢ÿp$iÊíù2ŸÒ;LÛ–Oòá ±Fóyº)‘ùµ©ãà~ ¥ŸC¡ë­„aø ÅÑ«¨ÙûGæhg [&óâ<1—Xû²Âø{iª_“¸bf)¦Œ²§T˜ ÜÓ»GAe!ógF玦àUa!*ÚZ0Ÿðç/è a0¼€ž~£œ†äwÝo âïfŸJ³xÛw® ÞaÇL¿õ0 è^š `8¿Ú Ù4Ùç÷ Ï©4†V×"”]BÝ3pþà·½_) èIÞ\H$séåXŒ{Òb^Z,ÃÛ6ö©ÉÁ ¬–R2µCÇŠ‰t(£ˆOܲÓ7‚9òó`e€² ä@y%0júAÈëRÿ˜à˜~xƒ4wÖ5çíÂàÖ±åmÝÓ×â}=Ð’tRX[>͔ҞÐRÔ "çH³l/é•_r> endobj -700 0 obj << +708 0 obj << /Ascent 708 /CapHeight 672 /Descent -266 -/FontName /ZBDFML+URWPalladioL-Bold +/FontName /ZTEYNX+URWPalladioL-Bold /ItalicAngle 0 /StemV 123 /XHeight 471 /FontBBox [-152 -301 1000 935] /Flags 4 /CharSet (/fi/fl/exclam/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/question/at/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/emdash) -/FontFile 701 0 R +/FontFile 709 0 R >> endobj -2108 0 obj +2138 0 obj [611 611 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 0 500 889 0 278 333 333 444 606 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 250 0 0 0 444 747 778 667 722 833 611 556 833 833 389 0 778 611 1000 833 833 611 833 722 611 667 778 778 1000 667 667 667 333 0 333 0 0 0 500 611 444 611 500 389 556 611 333 333 611 333 889 611 556 611 611 389 444 333 611 556 833 500 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 1000 ] endobj -703 0 obj << +711 0 obj << /Type /Pages /Count 6 -/Parent 2109 0 R -/Kids [694 0 R 721 0 R 731 0 R 786 0 R 850 0 R 912 0 R] +/Parent 2139 0 R +/Kids [702 0 R 729 0 R 739 0 R 794 0 R 858 0 R 920 0 R] >> endobj -941 0 obj << +951 0 obj << /Type /Pages /Count 6 -/Parent 2109 0 R -/Kids [929 0 R 943 0 R 957 0 R 968 0 R 975 0 R 987 0 R] +/Parent 2139 0 R +/Kids [939 0 R 953 0 R 967 0 R 978 0 R 985 0 R 997 0 R] >> endobj -999 0 obj << +1009 0 obj << /Type /Pages /Count 6 -/Parent 2109 0 R -/Kids [992 0 R 1001 0 R 1012 0 R 1020 0 R 1027 0 R 1033 0 R] +/Parent 2139 0 R +/Kids [1002 0 R 1011 0 R 1022 0 R 1030 0 R 1037 0 R 1043 0 R] >> endobj -1056 0 obj << +1066 0 obj << /Type /Pages /Count 6 -/Parent 2109 0 R -/Kids [1041 0 R 1063 0 R 1073 0 R 1078 0 R 1082 0 R 1089 0 R] +/Parent 2139 0 R +/Kids [1051 0 R 1073 0 R 1083 0 R 1088 0 R 1092 0 R 1099 0 R] >> endobj -1105 0 obj << +1115 0 obj << /Type /Pages /Count 6 -/Parent 2109 0 R -/Kids [1097 0 R 1108 0 R 1115 0 R 1120 0 R 1129 0 R 1136 0 R] +/Parent 2139 0 R +/Kids [1107 0 R 1118 0 R 1125 0 R 1130 0 R 1139 0 R 1146 0 R] >> endobj -1148 0 obj << +1158 0 obj << /Type /Pages /Count 6 -/Parent 2109 0 R -/Kids [1140 0 R 1151 0 R 1156 0 R 1164 0 R 1172 0 R 1181 0 R] +/Parent 2139 0 R +/Kids [1150 0 R 1161 0 R 1166 0 R 1174 0 R 1182 0 R 1191 0 R] >> endobj -1199 0 obj << +1210 0 obj << /Type /Pages /Count 6 -/Parent 2110 0 R -/Kids [1189 0 R 1201 0 R 1207 0 R 1213 0 R 1219 0 R 1223 0 R] +/Parent 2140 0 R +/Kids [1200 0 R 1212 0 R 1217 0 R 1223 0 R 1229 0 R 1233 0 R] >> endobj -1237 0 obj << +1250 0 obj << /Type /Pages /Count 6 -/Parent 2110 0 R -/Kids [1234 0 R 1239 0 R 1243 0 R 1248 0 R 1254 0 R 1258 0 R] +/Parent 2140 0 R +/Kids [1241 0 R 1252 0 R 1256 0 R 1260 0 R 1265 0 R 1271 0 R] >> endobj -1273 0 obj << +1280 0 obj << /Type /Pages /Count 6 -/Parent 2110 0 R -/Kids [1265 0 R 1276 0 R 1280 0 R 1284 0 R 1294 0 R 1301 0 R] +/Parent 2140 0 R +/Kids [1275 0 R 1282 0 R 1293 0 R 1297 0 R 1301 0 R 1311 0 R] >> endobj -1310 0 obj << +1323 0 obj << /Type /Pages /Count 6 -/Parent 2110 0 R -/Kids [1307 0 R 1312 0 R 1316 0 R 1320 0 R 1328 0 R 1334 0 R] +/Parent 2140 0 R +/Kids [1318 0 R 1325 0 R 1329 0 R 1333 0 R 1337 0 R 1345 0 R] >> endobj -1346 0 obj << +1356 0 obj << /Type /Pages /Count 6 -/Parent 2110 0 R -/Kids [1340 0 R 1348 0 R 1356 0 R 1361 0 R 1373 0 R 1378 0 R] +/Parent 2140 0 R +/Kids [1351 0 R 1358 0 R 1365 0 R 1372 0 R 1378 0 R 1390 0 R] >> endobj -1388 0 obj << +1398 0 obj << /Type /Pages /Count 6 -/Parent 2110 0 R -/Kids [1382 0 R 1390 0 R 1395 0 R 1404 0 R 1408 0 R 1412 0 R] +/Parent 2140 0 R +/Kids [1395 0 R 1400 0 R 1405 0 R 1413 0 R 1420 0 R 1425 0 R] >> endobj -1423 0 obj << +1432 0 obj << /Type /Pages /Count 6 -/Parent 2111 0 R -/Kids [1416 0 R 1425 0 R 1430 0 R 1449 0 R 1462 0 R 1482 0 R] +/Parent 2141 0 R +/Kids [1429 0 R 1434 0 R 1442 0 R 1449 0 R 1468 0 R 1482 0 R] >> endobj -1499 0 obj << +1507 0 obj << /Type /Pages /Count 6 -/Parent 2111 0 R -/Kids [1488 0 R 1501 0 R 1505 0 R 1511 0 R 1521 0 R 1533 0 R] +/Parent 2141 0 R +/Kids [1502 0 R 1509 0 R 1521 0 R 1525 0 R 1531 0 R 1541 0 R] >> endobj -1547 0 obj << +1560 0 obj << /Type /Pages /Count 6 -/Parent 2111 0 R -/Kids [1541 0 R 1549 0 R 1557 0 R 1565 0 R 1574 0 R 1583 0 R] +/Parent 2141 0 R +/Kids [1553 0 R 1562 0 R 1569 0 R 1577 0 R 1585 0 R 1594 0 R] >> endobj -1592 0 obj << +1611 0 obj << /Type /Pages /Count 6 -/Parent 2111 0 R -/Kids [1587 0 R 1594 0 R 1605 0 R 1609 0 R 1613 0 R 1624 0 R] +/Parent 2141 0 R +/Kids [1604 0 R 1613 0 R 1617 0 R 1623 0 R 1634 0 R 1638 0 R] >> endobj -1634 0 obj << +1652 0 obj << /Type /Pages /Count 6 -/Parent 2111 0 R -/Kids [1628 0 R 1636 0 R 1646 0 R 1705 0 R 1761 0 R 1815 0 R] +/Parent 2141 0 R +/Kids [1642 0 R 1654 0 R 1658 0 R 1665 0 R 1675 0 R 1734 0 R] >> endobj -1857 0 obj << +1843 0 obj << /Type /Pages /Count 6 -/Parent 2111 0 R -/Kids [1849 0 R 1859 0 R 1865 0 R 1870 0 R 1874 0 R 1879 0 R] +/Parent 2141 0 R +/Kids [1790 0 R 1845 0 R 1879 0 R 1888 0 R 1894 0 R 1899 0 R] >> endobj -1894 0 obj << +1907 0 obj << /Type /Pages /Count 6 -/Parent 2112 0 R -/Kids [1890 0 R 1896 0 R 1908 0 R 1919 0 R 1926 0 R 1938 0 R] +/Parent 2142 0 R +/Kids [1903 0 R 1909 0 R 1920 0 R 1925 0 R 1937 0 R 1948 0 R] >> endobj -1952 0 obj << +1966 0 obj << /Type /Pages /Count 6 -/Parent 2112 0 R -/Kids [1942 0 R 1954 0 R 1960 0 R 1964 0 R 1974 0 R 1986 0 R] +/Parent 2142 0 R +/Kids [1955 0 R 1968 0 R 1972 0 R 1983 0 R 1989 0 R 1993 0 R] >> endobj -1998 0 obj << +2012 0 obj << /Type /Pages /Count 6 -/Parent 2112 0 R -/Kids [1992 0 R 2000 0 R 2009 0 R 2013 0 R 2024 0 R 2030 0 R] +/Parent 2142 0 R +/Kids [2001 0 R 2014 0 R 2023 0 R 2027 0 R 2039 0 R 2043 0 R] >> endobj -2039 0 obj << +2059 0 obj << /Type /Pages /Count 6 -/Parent 2112 0 R -/Kids [2035 0 R 2041 0 R 2053 0 R 2063 0 R 2069 0 R 2078 0 R] +/Parent 2142 0 R +/Kids [2050 0 R 2061 0 R 2066 0 R 2071 0 R 2081 0 R 2088 0 R] >> endobj -2091 0 obj << +2102 0 obj << /Type /Pages -/Count 1 -/Parent 2112 0 R -/Kids [2085 0 R] +/Count 3 +/Parent 2142 0 R +/Kids [2098 0 R 2104 0 R 2116 0 R] >> endobj -2109 0 obj << +2139 0 obj << /Type /Pages /Count 36 -/Parent 2113 0 R -/Kids [703 0 R 941 0 R 999 0 R 1056 0 R 1105 0 R 1148 0 R] +/Parent 2143 0 R +/Kids [711 0 R 951 0 R 1009 0 R 1066 0 R 1115 0 R 1158 0 R] >> endobj -2110 0 obj << +2140 0 obj << /Type /Pages /Count 36 -/Parent 2113 0 R -/Kids [1199 0 R 1237 0 R 1273 0 R 1310 0 R 1346 0 R 1388 0 R] +/Parent 2143 0 R +/Kids [1210 0 R 1250 0 R 1280 0 R 1323 0 R 1356 0 R 1398 0 R] >> endobj -2111 0 obj << +2141 0 obj << /Type /Pages /Count 36 -/Parent 2113 0 R -/Kids [1423 0 R 1499 0 R 1547 0 R 1592 0 R 1634 0 R 1857 0 R] +/Parent 2143 0 R +/Kids [1432 0 R 1507 0 R 1560 0 R 1611 0 R 1652 0 R 1843 0 R] >> endobj -2112 0 obj << +2142 0 obj << /Type /Pages -/Count 25 -/Parent 2113 0 R -/Kids [1894 0 R 1952 0 R 1998 0 R 2039 0 R 2091 0 R] +/Count 27 +/Parent 2143 0 R +/Kids [1907 0 R 1966 0 R 2012 0 R 2059 0 R 2102 0 R] >> endobj -2113 0 obj << +2143 0 obj << /Type /Pages -/Count 133 -/Kids [2109 0 R 2110 0 R 2111 0 R 2112 0 R] +/Count 135 +/Kids [2139 0 R 2140 0 R 2141 0 R 2142 0 R] >> endobj -2114 0 obj << +2144 0 obj << /Type /Outlines /First 7 0 R -/Last 639 0 R +/Last 647 0 R /Count 10 >> endobj +699 0 obj << +/Title 700 0 R +/A 697 0 R +/Parent 647 0 R +/Prev 695 0 R +>> endobj +695 0 obj << +/Title 696 0 R +/A 693 0 R +/Parent 647 0 R +/Prev 691 0 R +/Next 699 0 R +>> endobj 691 0 obj << /Title 692 0 R /A 689 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 687 0 R +/Next 695 0 R >> endobj 687 0 obj << /Title 688 0 R /A 685 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 683 0 R /Next 691 0 R >> endobj 683 0 obj << /Title 684 0 R /A 681 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 679 0 R /Next 687 0 R >> endobj 679 0 obj << /Title 680 0 R /A 677 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 675 0 R /Next 683 0 R >> endobj 675 0 obj << /Title 676 0 R /A 673 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 671 0 R /Next 679 0 R >> endobj 671 0 obj << /Title 672 0 R /A 669 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 667 0 R /Next 675 0 R >> endobj 667 0 obj << /Title 668 0 R /A 665 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 663 0 R /Next 671 0 R >> endobj 663 0 obj << /Title 664 0 R /A 661 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 659 0 R /Next 667 0 R >> endobj 659 0 obj << /Title 660 0 R /A 657 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 655 0 R /Next 663 0 R >> endobj 655 0 obj << /Title 656 0 R /A 653 0 R -/Parent 639 0 R +/Parent 647 0 R /Prev 651 0 R /Next 659 0 R >> endobj 651 0 obj << /Title 652 0 R /A 649 0 R -/Parent 639 0 R -/Prev 647 0 R +/Parent 647 0 R /Next 655 0 R >> endobj 647 0 obj << /Title 648 0 R /A 645 0 R -/Parent 639 0 R -/Prev 643 0 R -/Next 651 0 R +/Parent 2144 0 R +/Prev 611 0 R +/First 651 0 R +/Last 699 0 R +/Count -13 >> endobj 643 0 obj << /Title 644 0 R /A 641 0 R -/Parent 639 0 R -/Next 647 0 R +/Parent 631 0 R +/Prev 639 0 R >> endobj 639 0 obj << /Title 640 0 R /A 637 0 R -/Parent 2114 0 R -/Prev 603 0 R -/First 643 0 R -/Last 691 0 R -/Count -13 +/Parent 631 0 R +/Prev 635 0 R +/Next 643 0 R >> endobj 635 0 obj << /Title 636 0 R /A 633 0 R -/Parent 623 0 R -/Prev 631 0 R +/Parent 631 0 R +/Next 639 0 R >> endobj 631 0 obj << /Title 632 0 R /A 629 0 R -/Parent 623 0 R -/Prev 627 0 R -/Next 635 0 R +/Parent 611 0 R +/Prev 623 0 R +/First 635 0 R +/Last 643 0 R +/Count -3 >> endobj 627 0 obj << /Title 628 0 R /A 625 0 R /Parent 623 0 R -/Next 631 0 R >> endobj 623 0 obj << /Title 624 0 R /A 621 0 R -/Parent 603 0 R +/Parent 611 0 R /Prev 615 0 R +/Next 631 0 R /First 627 0 R -/Last 635 0 R -/Count -3 +/Last 627 0 R +/Count -1 >> endobj 619 0 obj << /Title 620 0 R @@ -10869,8 +11032,7 @@ endobj 615 0 obj << /Title 616 0 R /A 613 0 R -/Parent 603 0 R -/Prev 607 0 R +/Parent 611 0 R /Next 623 0 R /First 619 0 R /Last 619 0 R @@ -10879,75 +11041,77 @@ endobj 611 0 obj << /Title 612 0 R /A 609 0 R -/Parent 607 0 R +/Parent 2144 0 R +/Prev 591 0 R +/Next 647 0 R +/First 615 0 R +/Last 631 0 R +/Count -3 >> endobj 607 0 obj << /Title 608 0 R /A 605 0 R -/Parent 603 0 R -/Next 615 0 R -/First 611 0 R -/Last 611 0 R -/Count -1 +/Parent 591 0 R +/Prev 603 0 R >> endobj 603 0 obj << /Title 604 0 R /A 601 0 R -/Parent 2114 0 R -/Prev 583 0 R -/Next 639 0 R -/First 607 0 R -/Last 623 0 R -/Count -3 +/Parent 591 0 R +/Prev 595 0 R +/Next 607 0 R >> endobj 599 0 obj << /Title 600 0 R /A 597 0 R -/Parent 583 0 R -/Prev 595 0 R +/Parent 595 0 R >> endobj 595 0 obj << /Title 596 0 R /A 593 0 R -/Parent 583 0 R -/Prev 587 0 R -/Next 599 0 R +/Parent 591 0 R +/Next 603 0 R +/First 599 0 R +/Last 599 0 R +/Count -1 >> endobj 591 0 obj << /Title 592 0 R /A 589 0 R -/Parent 587 0 R +/Parent 2144 0 R +/Prev 567 0 R +/Next 611 0 R +/First 595 0 R +/Last 607 0 R +/Count -3 >> endobj 587 0 obj << /Title 588 0 R /A 585 0 R -/Parent 583 0 R -/Next 595 0 R -/First 591 0 R -/Last 591 0 R -/Count -1 +/Parent 567 0 R +/Prev 575 0 R >> endobj 583 0 obj << /Title 584 0 R /A 581 0 R -/Parent 2114 0 R -/Prev 559 0 R -/Next 603 0 R -/First 587 0 R -/Last 599 0 R -/Count -3 +/Parent 575 0 R +/Prev 579 0 R >> endobj 579 0 obj << /Title 580 0 R /A 577 0 R -/Parent 559 0 R -/Prev 567 0 R +/Parent 575 0 R +/Next 583 0 R >> endobj 575 0 obj << /Title 576 0 R /A 573 0 R /Parent 567 0 R /Prev 571 0 R +/Next 587 0 R +/First 579 0 R +/Last 583 0 R +/Count -2 >> endobj 571 0 obj << /Title 572 0 R @@ -10958,207 +11122,205 @@ endobj 567 0 obj << /Title 568 0 R /A 565 0 R -/Parent 559 0 R -/Prev 563 0 R -/Next 579 0 R +/Parent 2144 0 R +/Prev 243 0 R +/Next 591 0 R /First 571 0 R -/Last 575 0 R -/Count -2 +/Last 587 0 R +/Count -3 >> endobj 563 0 obj << /Title 564 0 R /A 561 0 R -/Parent 559 0 R -/Next 567 0 R +/Parent 543 0 R +/Prev 559 0 R >> endobj 559 0 obj << /Title 560 0 R /A 557 0 R -/Parent 2114 0 R -/Prev 243 0 R -/Next 583 0 R -/First 563 0 R -/Last 579 0 R -/Count -3 +/Parent 543 0 R +/Prev 555 0 R +/Next 563 0 R >> endobj 555 0 obj << /Title 556 0 R /A 553 0 R -/Parent 539 0 R +/Parent 543 0 R /Prev 551 0 R +/Next 559 0 R >> endobj 551 0 obj << /Title 552 0 R /A 549 0 R -/Parent 539 0 R +/Parent 543 0 R /Prev 547 0 R /Next 555 0 R >> endobj 547 0 obj << /Title 548 0 R /A 545 0 R -/Parent 539 0 R -/Prev 543 0 R +/Parent 543 0 R /Next 551 0 R >> endobj 543 0 obj << /Title 544 0 R /A 541 0 R -/Parent 539 0 R -/Next 547 0 R +/Parent 535 0 R +/Prev 539 0 R +/First 547 0 R +/Last 563 0 R +/Count -5 >> endobj 539 0 obj << /Title 540 0 R /A 537 0 R -/Parent 531 0 R -/Prev 535 0 R -/First 543 0 R -/Last 555 0 R -/Count -4 +/Parent 535 0 R +/Next 543 0 R >> endobj 535 0 obj << /Title 536 0 R /A 533 0 R -/Parent 531 0 R -/Next 539 0 R +/Parent 243 0 R +/Prev 483 0 R +/First 539 0 R +/Last 543 0 R +/Count -2 >> endobj 531 0 obj << /Title 532 0 R /A 529 0 R -/Parent 243 0 R -/Prev 479 0 R -/First 535 0 R -/Last 539 0 R -/Count -2 +/Parent 483 0 R +/Prev 527 0 R >> endobj 527 0 obj << /Title 528 0 R /A 525 0 R -/Parent 479 0 R -/Prev 523 0 R +/Parent 483 0 R +/Prev 511 0 R +/Next 531 0 R >> endobj 523 0 obj << /Title 524 0 R /A 521 0 R -/Parent 479 0 R -/Prev 507 0 R -/Next 527 0 R +/Parent 511 0 R +/Prev 519 0 R >> endobj 519 0 obj << /Title 520 0 R /A 517 0 R -/Parent 507 0 R +/Parent 511 0 R /Prev 515 0 R +/Next 523 0 R >> endobj 515 0 obj << /Title 516 0 R /A 513 0 R -/Parent 507 0 R -/Prev 511 0 R +/Parent 511 0 R /Next 519 0 R >> endobj 511 0 obj << /Title 512 0 R /A 509 0 R -/Parent 507 0 R -/Next 515 0 R +/Parent 483 0 R +/Prev 507 0 R +/Next 527 0 R +/First 515 0 R +/Last 523 0 R +/Count -3 >> endobj 507 0 obj << /Title 508 0 R /A 505 0 R -/Parent 479 0 R +/Parent 483 0 R /Prev 503 0 R -/Next 523 0 R -/First 511 0 R -/Last 519 0 R -/Count -3 +/Next 511 0 R >> endobj 503 0 obj << /Title 504 0 R /A 501 0 R -/Parent 479 0 R +/Parent 483 0 R /Prev 499 0 R /Next 507 0 R >> endobj 499 0 obj << /Title 500 0 R /A 497 0 R -/Parent 479 0 R -/Prev 495 0 R +/Parent 483 0 R +/Prev 487 0 R /Next 503 0 R >> endobj 495 0 obj << /Title 496 0 R /A 493 0 R -/Parent 479 0 R -/Prev 483 0 R -/Next 499 0 R +/Parent 487 0 R +/Prev 491 0 R >> endobj 491 0 obj << /Title 492 0 R /A 489 0 R -/Parent 483 0 R -/Prev 487 0 R +/Parent 487 0 R +/Next 495 0 R >> endobj 487 0 obj << /Title 488 0 R /A 485 0 R /Parent 483 0 R -/Next 491 0 R +/Next 499 0 R +/First 491 0 R +/Last 495 0 R +/Count -2 >> endobj 483 0 obj << /Title 484 0 R /A 481 0 R -/Parent 479 0 R -/Next 495 0 R +/Parent 243 0 R +/Prev 275 0 R +/Next 535 0 R /First 487 0 R -/Last 491 0 R -/Count -2 +/Last 531 0 R +/Count -7 >> endobj 479 0 obj << /Title 480 0 R /A 477 0 R -/Parent 243 0 R -/Prev 275 0 R -/Next 531 0 R -/First 483 0 R -/Last 527 0 R -/Count -7 +/Parent 463 0 R +/Prev 475 0 R >> endobj 475 0 obj << /Title 476 0 R /A 473 0 R -/Parent 459 0 R +/Parent 463 0 R /Prev 471 0 R +/Next 479 0 R >> endobj 471 0 obj << /Title 472 0 R /A 469 0 R -/Parent 459 0 R +/Parent 463 0 R /Prev 467 0 R /Next 475 0 R >> endobj 467 0 obj << /Title 468 0 R /A 465 0 R -/Parent 459 0 R -/Prev 463 0 R +/Parent 463 0 R /Next 471 0 R >> endobj 463 0 obj << /Title 464 0 R /A 461 0 R -/Parent 459 0 R -/Next 467 0 R +/Parent 275 0 R +/Prev 459 0 R +/First 467 0 R +/Last 479 0 R +/Count -4 >> endobj 459 0 obj << /Title 460 0 R /A 457 0 R /Parent 275 0 R /Prev 455 0 R -/First 463 0 R -/Last 475 0 R -/Count -4 +/Next 463 0 R >> endobj 455 0 obj << /Title 456 0 R @@ -11213,149 +11375,149 @@ endobj /Title 428 0 R /A 425 0 R /Parent 275 0 R -/Prev 423 0 R +/Prev 351 0 R /Next 431 0 R >> endobj 423 0 obj << /Title 424 0 R /A 421 0 R -/Parent 275 0 R -/Prev 347 0 R -/Next 427 0 R +/Parent 351 0 R +/Prev 419 0 R >> endobj 419 0 obj << /Title 420 0 R /A 417 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 415 0 R +/Next 423 0 R >> endobj 415 0 obj << /Title 416 0 R /A 413 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 411 0 R /Next 419 0 R >> endobj 411 0 obj << /Title 412 0 R /A 409 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 407 0 R /Next 415 0 R >> endobj 407 0 obj << /Title 408 0 R /A 405 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 403 0 R /Next 411 0 R >> endobj 403 0 obj << /Title 404 0 R /A 401 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 399 0 R /Next 407 0 R >> endobj 399 0 obj << /Title 400 0 R /A 397 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 395 0 R /Next 403 0 R >> endobj 395 0 obj << /Title 396 0 R /A 393 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 391 0 R /Next 399 0 R >> endobj 391 0 obj << /Title 392 0 R /A 389 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 387 0 R /Next 395 0 R >> endobj 387 0 obj << /Title 388 0 R /A 385 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 383 0 R /Next 391 0 R >> endobj 383 0 obj << /Title 384 0 R /A 381 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 379 0 R /Next 387 0 R >> endobj 379 0 obj << /Title 380 0 R /A 377 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 375 0 R /Next 383 0 R >> endobj 375 0 obj << /Title 376 0 R /A 373 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 371 0 R /Next 379 0 R >> endobj 371 0 obj << /Title 372 0 R /A 369 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 367 0 R /Next 375 0 R >> endobj 367 0 obj << /Title 368 0 R /A 365 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 363 0 R /Next 371 0 R >> endobj 363 0 obj << /Title 364 0 R /A 361 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 359 0 R /Next 367 0 R >> endobj 359 0 obj << /Title 360 0 R /A 357 0 R -/Parent 347 0 R +/Parent 351 0 R /Prev 355 0 R /Next 363 0 R >> endobj 355 0 obj << /Title 356 0 R /A 353 0 R -/Parent 347 0 R -/Prev 351 0 R +/Parent 351 0 R /Next 359 0 R >> endobj 351 0 obj << /Title 352 0 R /A 349 0 R -/Parent 347 0 R -/Next 355 0 R +/Parent 275 0 R +/Prev 347 0 R +/Next 427 0 R +/First 355 0 R +/Last 423 0 R +/Count -18 >> endobj 347 0 obj << /Title 348 0 R /A 345 0 R /Parent 275 0 R /Prev 343 0 R -/Next 423 0 R -/First 351 0 R -/Last 419 0 R -/Count -18 +/Next 351 0 R >> endobj 343 0 obj << /Title 344 0 R @@ -11382,21 +11544,21 @@ endobj /Title 332 0 R /A 329 0 R /Parent 275 0 R -/Prev 327 0 R +/Prev 315 0 R /Next 335 0 R >> endobj 327 0 obj << /Title 328 0 R /A 325 0 R -/Parent 275 0 R -/Prev 315 0 R -/Next 331 0 R +/Parent 315 0 R +/Prev 323 0 R >> endobj 323 0 obj << /Title 324 0 R /A 321 0 R /Parent 315 0 R /Prev 319 0 R +/Next 327 0 R >> endobj 319 0 obj << /Title 320 0 R @@ -11409,10 +11571,10 @@ endobj /A 313 0 R /Parent 275 0 R /Prev 311 0 R -/Next 327 0 R +/Next 331 0 R /First 319 0 R -/Last 323 0 R -/Count -2 +/Last 327 0 R +/Count -3 >> endobj 311 0 obj << /Title 312 0 R @@ -11481,9 +11643,9 @@ endobj /A 273 0 R /Parent 243 0 R /Prev 247 0 R -/Next 479 0 R +/Next 483 0 R /First 279 0 R -/Last 459 0 R +/Last 463 0 R /Count -26 >> endobj 271 0 obj << @@ -11540,11 +11702,11 @@ endobj 243 0 obj << /Title 244 0 R /A 241 0 R -/Parent 2114 0 R +/Parent 2144 0 R /Prev 231 0 R -/Next 559 0 R +/Next 567 0 R /First 247 0 R -/Last 531 0 R +/Last 535 0 R /Count -4 >> endobj 239 0 obj << @@ -11562,7 +11724,7 @@ endobj 231 0 obj << /Title 232 0 R /A 229 0 R -/Parent 2114 0 R +/Parent 2144 0 R /Prev 131 0 R /Next 243 0 R /First 235 0 R @@ -11744,7 +11906,7 @@ endobj 131 0 obj << /Title 132 0 R /A 129 0 R -/Parent 2114 0 R +/Parent 2144 0 R /Prev 91 0 R /Next 231 0 R /First 135 0 R @@ -11818,7 +11980,7 @@ endobj 91 0 obj << /Title 92 0 R /A 89 0 R -/Parent 2114 0 R +/Parent 2144 0 R /Prev 67 0 R /Next 131 0 R /First 95 0 R @@ -11861,7 +12023,7 @@ endobj 67 0 obj << /Title 68 0 R /A 65 0 R -/Parent 2114 0 R +/Parent 2144 0 R /Prev 7 0 R /Next 91 0 R /First 71 0 R @@ -11970,2164 +12132,2194 @@ endobj 7 0 obj << /Title 8 0 R /A 5 0 R -/Parent 2114 0 R +/Parent 2144 0 R /Next 67 0 R /First 11 0 R /Last 23 0 R /Count -4 >> endobj -2115 0 obj << -/Names [(Access_Control_Lists) 1591 0 R (Bv9ARM.ch01) 932 0 R (Bv9ARM.ch02) 978 0 R (Bv9ARM.ch03) 995 0 R (Bv9ARM.ch04) 1044 0 R (Bv9ARM.ch05) 1132 0 R (Bv9ARM.ch06) 1143 0 R (Bv9ARM.ch07) 1590 0 R (Bv9ARM.ch08) 1616 0 R (Bv9ARM.ch09) 1631 0 R (Bv9ARM.ch10) 1852 0 R (Configuration_File_Grammar) 1168 0 R (DNSSEC) 1111 0 R (Doc-Start) 699 0 R (Setting_TTLs) 1526 0 R (acache) 985 0 R (access_control) 1290 0 R (acl) 1176 0 R (address_match_lists) 1149 0 R (admin_tools) 1018 0 R (appendix.A) 602 0 R (appendix.B) 638 0 R (bibliography) 1640 0 R (boolean_options) 1060 0 R (builtin) 1368 0 R (chapter*.1) 734 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 230 0 R (chapter.6) 242 0 R (chapter.7) 558 0 R (chapter.8) 582 0 R (cite.RFC1033) 1767 0 R (cite.RFC1034) 1652 0 R (cite.RFC1035) 1654 0 R (cite.RFC1101) 1749 0 R (cite.RFC1123) 1751 0 R (cite.RFC1183) 1711 0 R (cite.RFC1464) 1789 0 R (cite.RFC1535) 1697 0 R (cite.RFC1536) 1699 0 R (cite.RFC1537) 1769 0 R (cite.RFC1591) 1753 0 R (cite.RFC1706) 1713 0 R (cite.RFC1712) 1809 0 R (cite.RFC1713) 1791 0 R (cite.RFC1794) 1793 0 R (cite.RFC1876) 1715 0 R (cite.RFC1912) 1771 0 R (cite.RFC1982) 1701 0 R (cite.RFC1995) 1659 0 R (cite.RFC1996) 1661 0 R (cite.RFC2010) 1773 0 R (cite.RFC2052) 1717 0 R (cite.RFC2065) 1821 0 R (cite.RFC2136) 1663 0 R (cite.RFC2137) 1823 0 R (cite.RFC2163) 1719 0 R (cite.RFC2168) 1721 0 R (cite.RFC2181) 1665 0 R (cite.RFC2219) 1775 0 R (cite.RFC2230) 1723 0 R (cite.RFC2240) 1795 0 R (cite.RFC2308) 1667 0 R (cite.RFC2317) 1755 0 R (cite.RFC2345) 1797 0 R (cite.RFC2352) 1799 0 R (cite.RFC2535) 1825 0 R (cite.RFC2536) 1725 0 R (cite.RFC2537) 1727 0 R (cite.RFC2538) 1729 0 R (cite.RFC2539) 1731 0 R (cite.RFC2540) 1733 0 R (cite.RFC2671) 1669 0 R (cite.RFC2672) 1671 0 R (cite.RFC2673) 1811 0 R (cite.RFC2782) 1735 0 R (cite.RFC2825) 1779 0 R (cite.RFC2826) 1757 0 R (cite.RFC2845) 1673 0 R (cite.RFC2874) 1813 0 R (cite.RFC2915) 1737 0 R (cite.RFC2929) 1759 0 R (cite.RFC2930) 1675 0 R (cite.RFC2931) 1677 0 R (cite.RFC3007) 1679 0 R (cite.RFC3008) 1827 0 R (cite.RFC3071) 1801 0 R (cite.RFC3090) 1829 0 R (cite.RFC3110) 1739 0 R (cite.RFC3123) 1741 0 R (cite.RFC3225) 1685 0 R (cite.RFC3258) 1803 0 R (cite.RFC3445) 1831 0 R (cite.RFC3490) 1781 0 R (cite.RFC3491) 1783 0 R (cite.RFC3492) 1785 0 R (cite.RFC3596) 1743 0 R (cite.RFC3597) 1745 0 R (cite.RFC3645) 1681 0 R (cite.RFC3655) 1833 0 R (cite.RFC3658) 1835 0 R (cite.RFC3755) 1837 0 R (cite.RFC3757) 1839 0 R (cite.RFC3833) 1687 0 R (cite.RFC3845) 1841 0 R (cite.RFC3901) 1805 0 R (cite.RFC4033) 1689 0 R (cite.RFC4034) 1691 0 R (cite.RFC4035) 1693 0 R (cite.RFC4074) 1703 0 R (cite.RFC974) 1656 0 R (cite.id2504427) 1846 0 R (configuration_file_elements) 1144 0 R (controls_statement_definition_and_usage) 1031 0 R (diagnostic_tools) 966 0 R (dynamic_update) 1054 0 R (dynamic_update_policies) 1106 0 R (dynamic_update_security) 1299 0 R (empty) 1376 0 R (historical_dns_information) 1633 0 R (id2464966) 933 0 R (id2466572) 934 0 R (id2467531) 935 0 R (id2467541) 936 0 R (id2467713) 948 0 R (id2467734) 949 0 R (id2467768) 950 0 R (id2467852) 953 0 R (id2467945) 946 0 R (id2470250) 960 0 R (id2470274) 963 0 R (id2470372) 964 0 R (id2470393) 965 0 R (id2470423) 971 0 R (id2470526) 972 0 R (id2470553) 973 0 R (id2470587) 979 0 R (id2470614) 980 0 R (id2470627) 981 0 R (id2470721) 984 0 R (id2470731) 990 0 R (id2470763) 997 0 R (id2470779) 998 0 R (id2470802) 1004 0 R (id2470819) 1005 0 R (id2471224) 1008 0 R (id2471229) 1009 0 R (id2473110) 1036 0 R (id2473122) 1037 0 R (id2473515) 1069 0 R (id2473533) 1070 0 R (id2473969) 1086 0 R (id2473986) 1087 0 R (id2474024) 1092 0 R (id2474042) 1093 0 R (id2474121) 1094 0 R (id2474161) 1095 0 R (id2474286) 1100 0 R (id2474331) 1102 0 R (id2474345) 1103 0 R (id2474462) 1104 0 R (id2474599) 1112 0 R (id2474678) 1113 0 R (id2474759) 1118 0 R (id2474902) 1123 0 R (id2475169) 1125 0 R (id2475190) 1126 0 R (id2475291) 1133 0 R (id2475438) 1145 0 R (id2476300) 1154 0 R (id2476328) 1159 0 R (id2476522) 1160 0 R (id2476537) 1161 0 R (id2476567) 1167 0 R (id2476718) 1169 0 R (id2477161) 1175 0 R (id2477272) 1177 0 R (id2477419) 1179 0 R (id2477780) 1186 0 R (id2477797) 1192 0 R (id2477889) 1193 0 R (id2477912) 1194 0 R (id2478003) 1198 0 R (id2478197) 1204 0 R (id2478249) 1205 0 R (id2478942) 1216 0 R (id2479645) 1226 0 R (id2479719) 1227 0 R (id2479783) 1230 0 R (id2479827) 1231 0 R (id2479842) 1232 0 R (id2482169) 1261 0 R (id2484043) 1287 0 R (id2484102) 1289 0 R (id2484598) 1304 0 R (id2485793) 1323 0 R (id2485852) 1325 0 R (id2486200) 1337 0 R (id2486839) 1352 0 R (id2488339) 1386 0 R (id2489091) 1399 0 R (id2489142) 1400 0 R (id2489292) 1402 0 R (id2490761) 1419 0 R (id2490769) 1420 0 R (id2490774) 1421 0 R (id2491188) 1428 0 R (id2491221) 1433 0 R (id2492840) 1485 0 R (id2493223) 1491 0 R (id2493309) 1492 0 R (id2493330) 1495 0 R (id2493498) 1497 0 R (id2494737) 1508 0 R (id2494865) 1514 0 R (id2495022) 1515 0 R (id2495385) 1517 0 R (id2495522) 1519 0 R (id2495544) 1524 0 R (id2496017) 1527 0 R (id2496141) 1529 0 R (id2496156) 1530 0 R (id2496268) 1536 0 R (id2496291) 1537 0 R (id2496420) 1538 0 R (id2496489) 1539 0 R (id2496525) 1544 0 R (id2496587) 1545 0 R (id2497018) 1553 0 R (id2497363) 1561 0 R (id2497368) 1562 0 R (id2499022) 1568 0 R (id2499029) 1569 0 R (id2499405) 1571 0 R (id2499411) 1572 0 R (id2500259) 1581 0 R (id2500446) 1601 0 R (id2500592) 1602 0 R (id2500651) 1603 0 R (id2500731) 1617 0 R (id2500737) 1618 0 R (id2500748) 1619 0 R (id2500765) 1620 0 R (id2500964) 1632 0 R (id2501136) 1639 0 R (id2501255) 1644 0 R (id2501257) 1650 0 R (id2501266) 1655 0 R (id2501289) 1651 0 R (id2501381) 1653 0 R (id2501417) 1664 0 R (id2501444) 1666 0 R (id2501469) 1658 0 R (id2501494) 1660 0 R (id2501517) 1662 0 R (id2501573) 1668 0 R (id2501600) 1670 0 R (id2501626) 1672 0 R (id2501688) 1674 0 R (id2501718) 1676 0 R (id2501748) 1678 0 R (id2501843) 1680 0 R (id2501917) 1683 0 R (id2501925) 1684 0 R (id2501952) 1686 0 R (id2501988) 1688 0 R (id2502053) 1690 0 R (id2502118) 1692 0 R (id2502183) 1695 0 R (id2502192) 1696 0 R (id2502217) 1698 0 R (id2502285) 1700 0 R (id2502321) 1702 0 R (id2502361) 1709 0 R (id2502366) 1710 0 R (id2502424) 1712 0 R (id2502461) 1720 0 R (id2502497) 1714 0 R (id2502551) 1716 0 R (id2502589) 1718 0 R (id2502615) 1722 0 R (id2502641) 1724 0 R (id2502667) 1726 0 R (id2502694) 1728 0 R (id2502733) 1730 0 R (id2502763) 1732 0 R (id2502793) 1734 0 R (id2502836) 1736 0 R (id2502869) 1738 0 R (id2502896) 1740 0 R (id2502919) 1742 0 R (id2502977) 1744 0 R (id2503001) 1747 0 R (id2503009) 1748 0 R (id2503034) 1750 0 R (id2503057) 1752 0 R (id2503080) 1754 0 R (id2503126) 1756 0 R (id2503149) 1758 0 R (id2503200) 1765 0 R (id2503207) 1766 0 R (id2503230) 1768 0 R (id2503257) 1770 0 R (id2503352) 1772 0 R (id2503388) 1774 0 R (id2503429) 1777 0 R (id2503434) 1778 0 R (id2503466) 1780 0 R (id2503512) 1782 0 R (id2503547) 1784 0 R (id2503574) 1787 0 R (id2503592) 1788 0 R (id2503614) 1790 0 R (id2503640) 1792 0 R (id2503666) 1794 0 R (id2503689) 1796 0 R (id2503735) 1798 0 R (id2503758) 1800 0 R (id2503785) 1802 0 R (id2503811) 1804 0 R (id2503848) 1807 0 R (id2503854) 1808 0 R (id2503912) 1810 0 R (id2503939) 1812 0 R (id2503975) 1819 0 R (id2503987) 1820 0 R (id2504026) 1822 0 R (id2504053) 1824 0 R (id2504083) 1826 0 R (id2504108) 1828 0 R (id2504135) 1830 0 R (id2504240) 1832 0 R (id2504276) 1834 0 R (id2504302) 1836 0 R (id2504329) 1838 0 R (id2504374) 1840 0 R (id2504416) 1843 0 R (id2504425) 1845 0 R (id2504427) 1847 0 R (incremental_zone_transfers) 1066 0 R (internet_drafts) 1842 0 R (ipv6addresses) 1127 0 R (journal) 1055 0 R (lwresd) 1134 0 R (man.dig) 1853 0 R (man.dnssec-dsfromkey) 1902 0 R (man.dnssec-keyfromlabel) 1916 0 R (man.dnssec-keygen) 1932 0 R (man.dnssec-signzone) 1949 0 R (man.host) 1886 0 R (man.named) 2003 0 R (man.named-checkconf) 1970 0 R (man.named-checkzone) 1982 0 R (man.nsupdate) 2021 0 R (man.rndc) 2047 0 R (man.rndc-confgen) 2075 0 R (man.rndc.conf) 2059 0 R (notify) 1045 0 R (options) 1246 0 R (page.1) 698 0 R (page.10) 970 0 R (page.100) 1707 0 R (page.101) 1763 0 R (page.102) 1817 0 R (page.103) 1851 0 R (page.104) 1861 0 R (page.105) 1867 0 R (page.106) 1872 0 R (page.107) 1876 0 R (page.108) 1881 0 R (page.109) 1892 0 R (page.11) 977 0 R (page.110) 1898 0 R (page.111) 1910 0 R (page.112) 1921 0 R (page.113) 1928 0 R (page.114) 1940 0 R (page.115) 1944 0 R (page.116) 1956 0 R (page.117) 1962 0 R (page.118) 1966 0 R (page.119) 1976 0 R (page.12) 989 0 R (page.120) 1988 0 R (page.121) 1994 0 R (page.122) 2002 0 R (page.123) 2011 0 R (page.124) 2015 0 R (page.125) 2026 0 R (page.126) 2032 0 R (page.127) 2037 0 R (page.128) 2043 0 R (page.129) 2055 0 R (page.13) 994 0 R (page.130) 2065 0 R (page.131) 2071 0 R (page.132) 2080 0 R (page.133) 2087 0 R (page.14) 1003 0 R (page.15) 1014 0 R (page.16) 1022 0 R (page.17) 1029 0 R (page.18) 1035 0 R (page.19) 1043 0 R (page.2) 723 0 R (page.20) 1065 0 R (page.21) 1075 0 R (page.22) 1080 0 R (page.23) 1084 0 R (page.24) 1091 0 R (page.25) 1099 0 R (page.26) 1110 0 R (page.27) 1117 0 R (page.28) 1122 0 R (page.29) 1131 0 R (page.3) 733 0 R (page.30) 1138 0 R (page.31) 1142 0 R (page.32) 1153 0 R (page.33) 1158 0 R (page.34) 1166 0 R (page.35) 1174 0 R (page.36) 1183 0 R (page.37) 1191 0 R (page.38) 1203 0 R (page.39) 1209 0 R (page.4) 788 0 R (page.40) 1215 0 R (page.41) 1221 0 R (page.42) 1225 0 R (page.43) 1236 0 R (page.44) 1241 0 R (page.45) 1245 0 R (page.46) 1250 0 R (page.47) 1256 0 R (page.48) 1260 0 R (page.49) 1267 0 R (page.5) 852 0 R (page.50) 1278 0 R (page.51) 1282 0 R (page.52) 1286 0 R (page.53) 1296 0 R (page.54) 1303 0 R (page.55) 1309 0 R (page.56) 1314 0 R (page.57) 1318 0 R (page.58) 1322 0 R (page.59) 1330 0 R (page.6) 914 0 R (page.60) 1336 0 R (page.61) 1342 0 R (page.62) 1350 0 R (page.63) 1358 0 R (page.64) 1363 0 R (page.65) 1375 0 R (page.66) 1380 0 R (page.67) 1384 0 R (page.68) 1392 0 R (page.69) 1397 0 R (page.7) 931 0 R (page.70) 1406 0 R (page.71) 1410 0 R (page.72) 1414 0 R (page.73) 1418 0 R (page.74) 1427 0 R (page.75) 1432 0 R (page.76) 1451 0 R (page.77) 1464 0 R (page.78) 1484 0 R (page.79) 1490 0 R (page.8) 945 0 R (page.80) 1503 0 R (page.81) 1507 0 R (page.82) 1513 0 R (page.83) 1523 0 R (page.84) 1535 0 R (page.85) 1543 0 R (page.86) 1551 0 R (page.87) 1559 0 R (page.88) 1567 0 R (page.89) 1576 0 R (page.9) 959 0 R (page.90) 1585 0 R (page.91) 1589 0 R (page.92) 1596 0 R (page.93) 1607 0 R (page.94) 1611 0 R (page.95) 1615 0 R (page.96) 1626 0 R (page.97) 1630 0 R (page.98) 1638 0 R (page.99) 1648 0 R (proposed_standards) 1071 0 R (query_address) 1305 0 R (rfcs) 955 0 R (rndc) 1187 0 R (rrset_ordering) 1010 0 R (sample_configuration) 996 0 R (section*.10) 1776 0 R (section*.100) 2058 0 R (section*.101) 2060 0 R (section*.102) 2061 0 R (section*.103) 2066 0 R (section*.104) 2067 0 R (section*.105) 2072 0 R (section*.106) 2073 0 R (section*.107) 2074 0 R (section*.108) 2076 0 R (section*.109) 2081 0 R (section*.11) 1786 0 R (section*.110) 2082 0 R (section*.111) 2083 0 R (section*.112) 2088 0 R (section*.113) 2089 0 R (section*.114) 2090 0 R (section*.12) 1806 0 R (section*.13) 1818 0 R (section*.14) 1844 0 R (section*.15) 1854 0 R (section*.16) 1855 0 R (section*.17) 1856 0 R (section*.18) 1862 0 R (section*.19) 1863 0 R (section*.2) 1643 0 R (section*.20) 1868 0 R (section*.21) 1877 0 R (section*.22) 1882 0 R (section*.23) 1883 0 R (section*.24) 1884 0 R (section*.25) 1885 0 R (section*.26) 1887 0 R (section*.27) 1888 0 R (section*.28) 1893 0 R (section*.29) 1899 0 R (section*.3) 1649 0 R (section*.30) 1900 0 R (section*.31) 1901 0 R (section*.32) 1903 0 R (section*.33) 1904 0 R (section*.34) 1905 0 R (section*.35) 1906 0 R (section*.36) 1911 0 R (section*.37) 1912 0 R (section*.38) 1913 0 R (section*.39) 1914 0 R (section*.4) 1657 0 R (section*.40) 1915 0 R (section*.41) 1917 0 R (section*.42) 1922 0 R (section*.43) 1923 0 R (section*.44) 1924 0 R (section*.45) 1929 0 R (section*.46) 1930 0 R (section*.47) 1931 0 R (section*.48) 1933 0 R (section*.49) 1934 0 R (section*.5) 1682 0 R (section*.50) 1935 0 R (section*.51) 1936 0 R (section*.52) 1945 0 R (section*.53) 1946 0 R (section*.54) 1947 0 R (section*.55) 1948 0 R (section*.56) 1950 0 R (section*.57) 1951 0 R (section*.58) 1957 0 R (section*.59) 1958 0 R (section*.6) 1694 0 R (section*.60) 1967 0 R (section*.61) 1968 0 R (section*.62) 1969 0 R (section*.63) 1971 0 R (section*.64) 1972 0 R (section*.65) 1977 0 R (section*.66) 1978 0 R (section*.67) 1979 0 R (section*.68) 1980 0 R (section*.69) 1981 0 R (section*.7) 1708 0 R (section*.70) 1983 0 R (section*.71) 1984 0 R (section*.72) 1989 0 R (section*.73) 1990 0 R (section*.74) 1995 0 R (section*.75) 1996 0 R (section*.76) 1997 0 R (section*.77) 2004 0 R (section*.78) 2005 0 R (section*.79) 2006 0 R (section*.8) 1746 0 R (section*.80) 2007 0 R (section*.81) 2016 0 R (section*.82) 2017 0 R (section*.83) 2018 0 R (section*.84) 2019 0 R (section*.85) 2020 0 R (section*.86) 2022 0 R (section*.87) 2027 0 R (section*.88) 2028 0 R (section*.89) 2033 0 R (section*.9) 1764 0 R (section*.90) 2038 0 R (section*.91) 2044 0 R (section*.92) 2045 0 R (section*.93) 2046 0 R (section*.94) 2048 0 R (section*.95) 2049 0 R (section*.96) 2050 0 R (section*.97) 2051 0 R (section*.98) 2056 0 R (section*.99) 2057 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 234 0 R (section.5.2) 238 0 R (section.6.1) 246 0 R (section.6.2) 274 0 R (section.6.3) 478 0 R (section.6.4) 530 0 R (section.7.1) 562 0 R (section.7.2) 566 0 R (section.7.3) 578 0 R (section.8.1) 586 0 R (section.8.2) 594 0 R (section.8.3) 598 0 R (section.A.1) 606 0 R (section.A.2) 614 0 R (section.A.3) 622 0 R (section.B.1) 642 0 R (section.B.10) 678 0 R (section.B.11) 682 0 R (section.B.12) 686 0 R (section.B.13) 690 0 R (section.B.2) 646 0 R (section.B.3) 650 0 R (section.B.4) 654 0 R (section.B.5) 658 0 R (section.B.6) 662 0 R (section.B.7) 666 0 R (section.B.8) 670 0 R (section.B.9) 674 0 R (server_resource_limits) 1331 0 R (server_statement_definition_and_usage) 1274 0 R (server_statement_grammar) 1387 0 R (statistics) 1552 0 R (statistics_counters) 1560 0 R (statschannels) 1385 0 R (statsfile) 1252 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.2) 226 0 R (subsection.6.1.1) 250 0 R (subsection.6.1.2) 262 0 R (subsection.6.2.1) 278 0 R (subsection.6.2.10) 314 0 R (subsection.6.2.11) 326 0 R (subsection.6.2.12) 330 0 R (subsection.6.2.13) 334 0 R (subsection.6.2.14) 338 0 R (subsection.6.2.15) 342 0 R (subsection.6.2.16) 346 0 R (subsection.6.2.17) 422 0 R (subsection.6.2.18) 426 0 R (subsection.6.2.19) 430 0 R (subsection.6.2.2) 282 0 R (subsection.6.2.20) 434 0 R (subsection.6.2.21) 438 0 R (subsection.6.2.22) 442 0 R (subsection.6.2.23) 446 0 R (subsection.6.2.24) 450 0 R (subsection.6.2.25) 454 0 R (subsection.6.2.26) 458 0 R (subsection.6.2.3) 286 0 R (subsection.6.2.4) 290 0 R (subsection.6.2.5) 294 0 R (subsection.6.2.6) 298 0 R (subsection.6.2.7) 302 0 R (subsection.6.2.8) 306 0 R (subsection.6.2.9) 310 0 R (subsection.6.3.1) 482 0 R (subsection.6.3.2) 494 0 R (subsection.6.3.3) 498 0 R (subsection.6.3.4) 502 0 R (subsection.6.3.5) 506 0 R (subsection.6.3.6) 522 0 R (subsection.6.3.7) 526 0 R (subsection.6.4.1) 538 0 R (subsection.7.2.1) 570 0 R (subsection.7.2.2) 574 0 R (subsection.8.1.1) 590 0 R (subsection.A.1.1) 610 0 R (subsection.A.2.1) 618 0 R (subsection.A.3.1) 626 0 R (subsection.A.3.2) 630 0 R (subsection.A.3.3) 634 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 254 0 R (subsubsection.6.1.1.2) 258 0 R (subsubsection.6.1.2.1) 266 0 R (subsubsection.6.1.2.2) 270 0 R (subsubsection.6.2.10.1) 318 0 R (subsubsection.6.2.10.2) 322 0 R (subsubsection.6.2.16.1) 350 0 R (subsubsection.6.2.16.10) 386 0 R (subsubsection.6.2.16.11) 390 0 R (subsubsection.6.2.16.12) 394 0 R (subsubsection.6.2.16.13) 398 0 R (subsubsection.6.2.16.14) 402 0 R (subsubsection.6.2.16.15) 406 0 R (subsubsection.6.2.16.16) 410 0 R (subsubsection.6.2.16.17) 414 0 R (subsubsection.6.2.16.18) 418 0 R (subsubsection.6.2.16.2) 354 0 R (subsubsection.6.2.16.3) 358 0 R (subsubsection.6.2.16.4) 362 0 R (subsubsection.6.2.16.5) 366 0 R (subsubsection.6.2.16.6) 370 0 R (subsubsection.6.2.16.7) 374 0 R (subsubsection.6.2.16.8) 378 0 R (subsubsection.6.2.16.9) 382 0 R (subsubsection.6.2.26.1) 462 0 R (subsubsection.6.2.26.2) 466 0 R (subsubsection.6.2.26.3) 470 0 R (subsubsection.6.2.26.4) 474 0 R (subsubsection.6.3.1.1) 486 0 R (subsubsection.6.3.1.2) 490 0 R (subsubsection.6.3.5.1) 510 0 R (subsubsection.6.3.5.2) 514 0 R (subsubsection.6.3.5.3) 518 0 R (subsubsection.6.4.0.1) 534 0 R (subsubsection.6.4.1.1) 542 0 R (subsubsection.6.4.1.2) 546 0 R (subsubsection.6.4.1.3) 550 0 R (subsubsection.6.4.1.4) 554 0 R (table.1.1) 937 0 R (table.1.2) 947 0 R (table.3.1) 1006 0 R (table.3.2) 1038 0 R (table.6.1) 1146 0 R (table.6.10) 1498 0 R (table.6.11) 1509 0 R (table.6.12) 1516 0 R (table.6.13) 1518 0 R (table.6.14) 1525 0 R (table.6.15) 1528 0 R (table.6.16) 1531 0 R (table.6.17) 1546 0 R (table.6.18) 1554 0 R (table.6.19) 1563 0 R (table.6.2) 1170 0 R (table.6.20) 1570 0 R (table.6.21) 1577 0 R (table.6.3) 1178 0 R (table.6.4) 1217 0 R (table.6.5) 1262 0 R (table.6.6) 1353 0 R (table.6.7) 1422 0 R (table.6.8) 1486 0 R (table.6.9) 1496 0 R (the_category_phrase) 1211 0 R (the_sortlist_statement) 1343 0 R (topology) 1338 0 R (tsig) 1085 0 R (tuning) 1354 0 R (types_of_resource_records_and_when_to_use_them) 954 0 R (view_statement_grammar) 1371 0 R (zone_statement_grammar) 1292 0 R (zone_transfers) 1061 0 R (zonefile_format) 1370 0 R] +2145 0 obj << +/Names [(Access_Control_Lists) 1621 0 R (Bv9ARM.ch01) 942 0 R (Bv9ARM.ch02) 988 0 R (Bv9ARM.ch03) 1005 0 R (Bv9ARM.ch04) 1054 0 R (Bv9ARM.ch05) 1142 0 R (Bv9ARM.ch06) 1153 0 R (Bv9ARM.ch07) 1620 0 R (Bv9ARM.ch08) 1645 0 R (Bv9ARM.ch09) 1661 0 R (Bv9ARM.ch10) 1882 0 R (Configuration_File_Grammar) 1178 0 R (DNSSEC) 1121 0 R (Doc-Start) 707 0 R (Setting_TTLs) 1546 0 R (acache) 995 0 R (access_control) 1307 0 R (acl) 1186 0 R (address_match_lists) 1159 0 R (admin_tools) 1028 0 R (appendix.A) 610 0 R (appendix.B) 646 0 R (bibliography) 1669 0 R (boolean_options) 1070 0 R (builtin) 1385 0 R (chapter*.1) 742 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 230 0 R (chapter.6) 242 0 R (chapter.7) 566 0 R (chapter.8) 590 0 R (cite.RFC1033) 1796 0 R (cite.RFC1034) 1681 0 R (cite.RFC1035) 1683 0 R (cite.RFC1101) 1778 0 R (cite.RFC1123) 1780 0 R (cite.RFC1183) 1740 0 R (cite.RFC1464) 1818 0 R (cite.RFC1535) 1726 0 R (cite.RFC1536) 1728 0 R (cite.RFC1537) 1798 0 R (cite.RFC1591) 1782 0 R (cite.RFC1706) 1742 0 R (cite.RFC1712) 1838 0 R (cite.RFC1713) 1820 0 R (cite.RFC1794) 1822 0 R (cite.RFC1876) 1744 0 R (cite.RFC1912) 1800 0 R (cite.RFC1982) 1730 0 R (cite.RFC1995) 1688 0 R (cite.RFC1996) 1690 0 R (cite.RFC2010) 1802 0 R (cite.RFC2052) 1746 0 R (cite.RFC2065) 1851 0 R (cite.RFC2136) 1692 0 R (cite.RFC2137) 1853 0 R (cite.RFC2163) 1748 0 R (cite.RFC2168) 1750 0 R (cite.RFC2181) 1694 0 R (cite.RFC2219) 1804 0 R (cite.RFC2230) 1752 0 R (cite.RFC2240) 1824 0 R (cite.RFC2308) 1696 0 R (cite.RFC2317) 1784 0 R (cite.RFC2345) 1826 0 R (cite.RFC2352) 1828 0 R (cite.RFC2535) 1855 0 R (cite.RFC2536) 1754 0 R (cite.RFC2537) 1756 0 R (cite.RFC2538) 1758 0 R (cite.RFC2539) 1760 0 R (cite.RFC2540) 1762 0 R (cite.RFC2671) 1698 0 R (cite.RFC2672) 1700 0 R (cite.RFC2673) 1840 0 R (cite.RFC2782) 1764 0 R (cite.RFC2825) 1808 0 R (cite.RFC2826) 1786 0 R (cite.RFC2845) 1702 0 R (cite.RFC2874) 1842 0 R (cite.RFC2915) 1766 0 R (cite.RFC2929) 1788 0 R (cite.RFC2930) 1704 0 R (cite.RFC2931) 1706 0 R (cite.RFC3007) 1708 0 R (cite.RFC3008) 1857 0 R (cite.RFC3071) 1830 0 R (cite.RFC3090) 1859 0 R (cite.RFC3110) 1768 0 R (cite.RFC3123) 1770 0 R (cite.RFC3225) 1714 0 R (cite.RFC3258) 1832 0 R (cite.RFC3445) 1861 0 R (cite.RFC3490) 1810 0 R (cite.RFC3491) 1812 0 R (cite.RFC3492) 1814 0 R (cite.RFC3596) 1772 0 R (cite.RFC3597) 1774 0 R (cite.RFC3645) 1710 0 R (cite.RFC3655) 1863 0 R (cite.RFC3658) 1865 0 R (cite.RFC3755) 1867 0 R (cite.RFC3757) 1869 0 R (cite.RFC3833) 1716 0 R (cite.RFC3845) 1871 0 R (cite.RFC3901) 1834 0 R (cite.RFC4033) 1718 0 R (cite.RFC4034) 1720 0 R (cite.RFC4035) 1722 0 R (cite.RFC4074) 1732 0 R (cite.RFC974) 1685 0 R (cite.id2505777) 1876 0 R (clients-per-query) 1592 0 R (configuration_file_elements) 1154 0 R (controls_statement_definition_and_usage) 1041 0 R (diagnostic_tools) 976 0 R (dynamic_update) 1064 0 R (dynamic_update_policies) 1116 0 R (dynamic_update_security) 1316 0 R (empty) 1393 0 R (historical_dns_information) 1663 0 R (id2466552) 943 0 R (id2466576) 944 0 R (id2467534) 945 0 R (id2467544) 946 0 R (id2467716) 958 0 R (id2467737) 959 0 R (id2467771) 960 0 R (id2467856) 963 0 R (id2467948) 956 0 R (id2470253) 970 0 R (id2470277) 973 0 R (id2470375) 974 0 R (id2470396) 975 0 R (id2470426) 981 0 R (id2470530) 982 0 R (id2470556) 983 0 R (id2470590) 989 0 R (id2470617) 990 0 R (id2470630) 991 0 R (id2470724) 994 0 R (id2470734) 1000 0 R (id2470766) 1007 0 R (id2470782) 1008 0 R (id2470805) 1014 0 R (id2470822) 1015 0 R (id2471227) 1018 0 R (id2471233) 1019 0 R (id2473009) 1046 0 R (id2473020) 1047 0 R (id2473420) 1079 0 R (id2473438) 1080 0 R (id2473942) 1096 0 R (id2473959) 1097 0 R (id2473997) 1102 0 R (id2474016) 1103 0 R (id2474026) 1104 0 R (id2474069) 1105 0 R (id2474263) 1110 0 R (id2474311) 1112 0 R (id2474325) 1113 0 R (id2474374) 1114 0 R (id2474510) 1122 0 R (id2474589) 1123 0 R (id2474670) 1128 0 R (id2474953) 1133 0 R (id2475083) 1135 0 R (id2475105) 1136 0 R (id2475138) 1143 0 R (id2475285) 1155 0 R (id2476147) 1164 0 R (id2476174) 1169 0 R (id2476380) 1170 0 R (id2476395) 1171 0 R (id2476425) 1177 0 R (id2476500) 1179 0 R (id2477079) 1185 0 R (id2477122) 1187 0 R (id2477269) 1189 0 R (id2477629) 1196 0 R (id2477646) 1197 0 R (id2477806) 1203 0 R (id2477830) 1204 0 R (id2477921) 1208 0 R (id2478115) 1209 0 R (id2478167) 1215 0 R (id2478997) 1226 0 R (id2479731) 1236 0 R (id2479859) 1237 0 R (id2480244) 1239 0 R (id2480317) 1244 0 R (id2480381) 1247 0 R (id2480425) 1248 0 R (id2480440) 1249 0 R (id2482851) 1278 0 R (id2484684) 1304 0 R (id2484743) 1306 0 R (id2485249) 1321 0 R (id2486520) 1340 0 R (id2486580) 1342 0 R (id2486934) 1354 0 R (id2487436) 1369 0 R (id2489703) 1411 0 R (id2489789) 1416 0 R (id2489841) 1417 0 R (id2489923) 1423 0 R (id2491460) 1437 0 R (id2491467) 1438 0 R (id2491473) 1439 0 R (id2491963) 1446 0 R (id2491996) 1452 0 R (id2493692) 1505 0 R (id2494007) 1512 0 R (id2494025) 1513 0 R (id2494045) 1516 0 R (id2494282) 1518 0 R (id2495452) 1528 0 R (id2495580) 1534 0 R (id2495602) 1535 0 R (id2495964) 1537 0 R (id2496101) 1539 0 R (id2496119) 1544 0 R (id2496660) 1547 0 R (id2496785) 1549 0 R (id2496800) 1550 0 R (id2496980) 1556 0 R (id2497002) 1557 0 R (id2497063) 1558 0 R (id2497132) 1559 0 R (id2497169) 1565 0 R (id2497299) 1566 0 R (id2497798) 1573 0 R (id2498301) 1581 0 R (id2498307) 1582 0 R (id2499706) 1589 0 R (id2499713) 1590 0 R (id2500089) 1597 0 R (id2500094) 1598 0 R (id2501108) 1600 0 R (id2501140) 1601 0 R (id2501549) 1610 0 R (id2501792) 1630 0 R (id2501941) 1631 0 R (id2502069) 1632 0 R (id2502149) 1646 0 R (id2502154) 1647 0 R (id2502166) 1648 0 R (id2502251) 1649 0 R (id2502313) 1662 0 R (id2502485) 1668 0 R (id2502741) 1673 0 R (id2502743) 1679 0 R (id2502752) 1684 0 R (id2502775) 1680 0 R (id2502798) 1682 0 R (id2502835) 1693 0 R (id2502861) 1695 0 R (id2502887) 1687 0 R (id2502912) 1689 0 R (id2502935) 1691 0 R (id2502990) 1697 0 R (id2503017) 1699 0 R (id2503044) 1701 0 R (id2503106) 1703 0 R (id2503136) 1705 0 R (id2503165) 1707 0 R (id2503192) 1709 0 R (id2503267) 1712 0 R (id2503274) 1713 0 R (id2503301) 1715 0 R (id2503337) 1717 0 R (id2503402) 1719 0 R (id2503467) 1721 0 R (id2503532) 1724 0 R (id2503541) 1725 0 R (id2503635) 1727 0 R (id2503703) 1729 0 R (id2503738) 1731 0 R (id2503779) 1738 0 R (id2503784) 1739 0 R (id2503842) 1741 0 R (id2503879) 1749 0 R (id2503914) 1743 0 R (id2503969) 1745 0 R (id2504007) 1747 0 R (id2504033) 1751 0 R (id2504058) 1753 0 R (id2504085) 1755 0 R (id2504112) 1757 0 R (id2504151) 1759 0 R (id2504181) 1761 0 R (id2504211) 1763 0 R (id2504253) 1765 0 R (id2504286) 1767 0 R (id2504313) 1769 0 R (id2504337) 1771 0 R (id2504394) 1773 0 R (id2504419) 1776 0 R (id2504426) 1777 0 R (id2504452) 1779 0 R (id2504474) 1781 0 R (id2504498) 1783 0 R (id2504612) 1785 0 R (id2504635) 1787 0 R (id2504685) 1794 0 R (id2504693) 1795 0 R (id2504716) 1797 0 R (id2504743) 1799 0 R (id2504770) 1801 0 R (id2504806) 1803 0 R (id2504846) 1806 0 R (id2504852) 1807 0 R (id2504884) 1809 0 R (id2504930) 1811 0 R (id2504965) 1813 0 R (id2504992) 1816 0 R (id2505010) 1817 0 R (id2505032) 1819 0 R (id2505058) 1821 0 R (id2505083) 1823 0 R (id2505107) 1825 0 R (id2505153) 1827 0 R (id2505176) 1829 0 R (id2505203) 1831 0 R (id2505228) 1833 0 R (id2505266) 1836 0 R (id2505272) 1837 0 R (id2505330) 1839 0 R (id2505356) 1841 0 R (id2505393) 1849 0 R (id2505404) 1850 0 R (id2505444) 1852 0 R (id2505470) 1854 0 R (id2505500) 1856 0 R (id2505526) 1858 0 R (id2505553) 1860 0 R (id2505589) 1862 0 R (id2505625) 1864 0 R (id2505652) 1866 0 R (id2505678) 1868 0 R (id2505723) 1870 0 R (id2505765) 1873 0 R (id2505774) 1875 0 R (id2505777) 1877 0 R (incremental_zone_transfers) 1076 0 R (internet_drafts) 1872 0 R (ipv6addresses) 1137 0 R (journal) 1065 0 R (lwresd) 1144 0 R (man.dig) 1883 0 R (man.dnssec-dsfromkey) 1931 0 R (man.dnssec-keyfromlabel) 1945 0 R (man.dnssec-keygen) 1961 0 R (man.dnssec-signzone) 1979 0 R (man.host) 1916 0 R (man.named) 2033 0 R (man.named-checkconf) 2004 0 R (man.named-checkzone) 2017 0 R (man.nsupdate) 2055 0 R (man.rndc) 2077 0 R (man.rndc-confgen) 2110 0 R (man.rndc.conf) 2093 0 R (notify) 1055 0 R (options) 1263 0 R (page.1) 706 0 R (page.10) 980 0 R (page.100) 1667 0 R (page.101) 1677 0 R (page.102) 1736 0 R (page.103) 1792 0 R (page.104) 1847 0 R (page.105) 1881 0 R (page.106) 1890 0 R (page.107) 1896 0 R (page.108) 1901 0 R (page.109) 1905 0 R (page.11) 987 0 R (page.110) 1911 0 R (page.111) 1922 0 R (page.112) 1927 0 R (page.113) 1939 0 R (page.114) 1950 0 R (page.115) 1957 0 R (page.116) 1970 0 R (page.117) 1974 0 R (page.118) 1985 0 R (page.119) 1991 0 R (page.12) 999 0 R (page.120) 1995 0 R (page.121) 2003 0 R (page.122) 2016 0 R (page.123) 2025 0 R (page.124) 2029 0 R (page.125) 2041 0 R (page.126) 2045 0 R (page.127) 2052 0 R (page.128) 2063 0 R (page.129) 2068 0 R (page.13) 1004 0 R (page.130) 2073 0 R (page.131) 2083 0 R (page.132) 2090 0 R (page.133) 2100 0 R (page.134) 2106 0 R (page.135) 2118 0 R (page.14) 1013 0 R (page.15) 1024 0 R (page.16) 1032 0 R (page.17) 1039 0 R (page.18) 1045 0 R (page.19) 1053 0 R (page.2) 731 0 R (page.20) 1075 0 R (page.21) 1085 0 R (page.22) 1090 0 R (page.23) 1094 0 R (page.24) 1101 0 R (page.25) 1109 0 R (page.26) 1120 0 R (page.27) 1127 0 R (page.28) 1132 0 R (page.29) 1141 0 R (page.3) 741 0 R (page.30) 1148 0 R (page.31) 1152 0 R (page.32) 1163 0 R (page.33) 1168 0 R (page.34) 1176 0 R (page.35) 1184 0 R (page.36) 1193 0 R (page.37) 1202 0 R (page.38) 1214 0 R (page.39) 1219 0 R (page.4) 796 0 R (page.40) 1225 0 R (page.41) 1231 0 R (page.42) 1235 0 R (page.43) 1243 0 R (page.44) 1254 0 R (page.45) 1258 0 R (page.46) 1262 0 R (page.47) 1267 0 R (page.48) 1273 0 R (page.49) 1277 0 R (page.5) 860 0 R (page.50) 1284 0 R (page.51) 1295 0 R (page.52) 1299 0 R (page.53) 1303 0 R (page.54) 1313 0 R (page.55) 1320 0 R (page.56) 1327 0 R (page.57) 1331 0 R (page.58) 1335 0 R (page.59) 1339 0 R (page.6) 922 0 R (page.60) 1347 0 R (page.61) 1353 0 R (page.62) 1360 0 R (page.63) 1367 0 R (page.64) 1374 0 R (page.65) 1380 0 R (page.66) 1392 0 R (page.67) 1397 0 R (page.68) 1402 0 R (page.69) 1407 0 R (page.7) 941 0 R (page.70) 1415 0 R (page.71) 1422 0 R (page.72) 1427 0 R (page.73) 1431 0 R (page.74) 1436 0 R (page.75) 1444 0 R (page.76) 1451 0 R (page.77) 1470 0 R (page.78) 1484 0 R (page.79) 1504 0 R (page.8) 955 0 R (page.80) 1511 0 R (page.81) 1523 0 R (page.82) 1527 0 R (page.83) 1533 0 R (page.84) 1543 0 R (page.85) 1555 0 R (page.86) 1564 0 R (page.87) 1571 0 R (page.88) 1579 0 R (page.89) 1587 0 R (page.9) 969 0 R (page.90) 1596 0 R (page.91) 1606 0 R (page.92) 1615 0 R (page.93) 1619 0 R (page.94) 1625 0 R (page.95) 1636 0 R (page.96) 1640 0 R (page.97) 1644 0 R (page.98) 1656 0 R (page.99) 1660 0 R (proposed_standards) 1081 0 R (query_address) 1322 0 R (rfcs) 965 0 R (rndc) 1198 0 R (root_delegation_only) 1447 0 R (rrset_ordering) 1020 0 R (sample_configuration) 1006 0 R (section*.10) 1805 0 R (section*.100) 2091 0 R (section*.101) 2092 0 R (section*.102) 2094 0 R (section*.103) 2095 0 R (section*.104) 2096 0 R (section*.105) 2101 0 R (section*.106) 2107 0 R (section*.107) 2108 0 R (section*.108) 2109 0 R (section*.109) 2111 0 R (section*.11) 1815 0 R (section*.110) 2112 0 R (section*.111) 2113 0 R (section*.112) 2114 0 R (section*.113) 2119 0 R (section*.114) 2120 0 R (section*.115) 2121 0 R (section*.12) 1835 0 R (section*.13) 1848 0 R (section*.14) 1874 0 R (section*.15) 1884 0 R (section*.16) 1885 0 R (section*.17) 1886 0 R (section*.18) 1891 0 R (section*.19) 1892 0 R (section*.2) 1672 0 R (section*.20) 1897 0 R (section*.21) 1906 0 R (section*.22) 1912 0 R (section*.23) 1913 0 R (section*.24) 1914 0 R (section*.25) 1915 0 R (section*.26) 1917 0 R (section*.27) 1918 0 R (section*.28) 1923 0 R (section*.29) 1928 0 R (section*.3) 1678 0 R (section*.30) 1929 0 R (section*.31) 1930 0 R (section*.32) 1932 0 R (section*.33) 1933 0 R (section*.34) 1934 0 R (section*.35) 1935 0 R (section*.36) 1940 0 R (section*.37) 1941 0 R (section*.38) 1942 0 R (section*.39) 1943 0 R (section*.4) 1686 0 R (section*.40) 1944 0 R (section*.41) 1946 0 R (section*.42) 1951 0 R (section*.43) 1952 0 R (section*.44) 1953 0 R (section*.45) 1958 0 R (section*.46) 1959 0 R (section*.47) 1960 0 R (section*.48) 1962 0 R (section*.49) 1963 0 R (section*.5) 1711 0 R (section*.50) 1964 0 R (section*.51) 1965 0 R (section*.52) 1975 0 R (section*.53) 1976 0 R (section*.54) 1977 0 R (section*.55) 1978 0 R (section*.56) 1980 0 R (section*.57) 1981 0 R (section*.58) 1986 0 R (section*.59) 1987 0 R (section*.6) 1723 0 R (section*.60) 1996 0 R (section*.61) 1997 0 R (section*.62) 1998 0 R (section*.63) 1999 0 R (section*.64) 2005 0 R (section*.65) 2006 0 R (section*.66) 2007 0 R (section*.67) 2008 0 R (section*.68) 2009 0 R (section*.69) 2010 0 R (section*.7) 1737 0 R (section*.70) 2011 0 R (section*.71) 2018 0 R (section*.72) 2019 0 R (section*.73) 2020 0 R (section*.74) 2021 0 R (section*.75) 2030 0 R (section*.76) 2031 0 R (section*.77) 2032 0 R (section*.78) 2034 0 R (section*.79) 2035 0 R (section*.8) 1775 0 R (section*.80) 2036 0 R (section*.81) 2037 0 R (section*.82) 2046 0 R (section*.83) 2047 0 R (section*.84) 2048 0 R (section*.85) 2053 0 R (section*.86) 2054 0 R (section*.87) 2056 0 R (section*.88) 2057 0 R (section*.89) 2058 0 R (section*.9) 1793 0 R (section*.90) 2064 0 R (section*.91) 2069 0 R (section*.92) 2074 0 R (section*.93) 2075 0 R (section*.94) 2076 0 R (section*.95) 2078 0 R (section*.96) 2079 0 R (section*.97) 2084 0 R (section*.98) 2085 0 R (section*.99) 2086 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 234 0 R (section.5.2) 238 0 R (section.6.1) 246 0 R (section.6.2) 274 0 R (section.6.3) 482 0 R (section.6.4) 534 0 R (section.7.1) 570 0 R (section.7.2) 574 0 R (section.7.3) 586 0 R (section.8.1) 594 0 R (section.8.2) 602 0 R (section.8.3) 606 0 R (section.A.1) 614 0 R (section.A.2) 622 0 R (section.A.3) 630 0 R (section.B.1) 650 0 R (section.B.10) 686 0 R (section.B.11) 690 0 R (section.B.12) 694 0 R (section.B.13) 698 0 R (section.B.2) 654 0 R (section.B.3) 658 0 R (section.B.4) 662 0 R (section.B.5) 666 0 R (section.B.6) 670 0 R (section.B.7) 674 0 R (section.B.8) 678 0 R (section.B.9) 682 0 R (server_resource_limits) 1348 0 R (server_statement_definition_and_usage) 1291 0 R (server_statement_grammar) 1403 0 R (statistics) 1572 0 R (statistics_counters) 1580 0 R (statschannels) 1410 0 R (statsfile) 1269 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.2) 226 0 R (subsection.6.1.1) 250 0 R (subsection.6.1.2) 262 0 R (subsection.6.2.1) 278 0 R (subsection.6.2.10) 314 0 R (subsection.6.2.11) 330 0 R (subsection.6.2.12) 334 0 R (subsection.6.2.13) 338 0 R (subsection.6.2.14) 342 0 R (subsection.6.2.15) 346 0 R (subsection.6.2.16) 350 0 R (subsection.6.2.17) 426 0 R (subsection.6.2.18) 430 0 R (subsection.6.2.19) 434 0 R (subsection.6.2.2) 282 0 R (subsection.6.2.20) 438 0 R (subsection.6.2.21) 442 0 R (subsection.6.2.22) 446 0 R (subsection.6.2.23) 450 0 R (subsection.6.2.24) 454 0 R (subsection.6.2.25) 458 0 R (subsection.6.2.26) 462 0 R (subsection.6.2.3) 286 0 R (subsection.6.2.4) 290 0 R (subsection.6.2.5) 294 0 R (subsection.6.2.6) 298 0 R (subsection.6.2.7) 302 0 R (subsection.6.2.8) 306 0 R (subsection.6.2.9) 310 0 R (subsection.6.3.1) 486 0 R (subsection.6.3.2) 498 0 R (subsection.6.3.3) 502 0 R (subsection.6.3.4) 506 0 R (subsection.6.3.5) 510 0 R (subsection.6.3.6) 526 0 R (subsection.6.3.7) 530 0 R (subsection.6.4.1) 542 0 R (subsection.7.2.1) 578 0 R (subsection.7.2.2) 582 0 R (subsection.8.1.1) 598 0 R (subsection.A.1.1) 618 0 R (subsection.A.2.1) 626 0 R (subsection.A.3.1) 634 0 R (subsection.A.3.2) 638 0 R (subsection.A.3.3) 642 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 254 0 R (subsubsection.6.1.1.2) 258 0 R (subsubsection.6.1.2.1) 266 0 R (subsubsection.6.1.2.2) 270 0 R (subsubsection.6.2.10.1) 318 0 R (subsubsection.6.2.10.2) 322 0 R (subsubsection.6.2.10.3) 326 0 R (subsubsection.6.2.16.1) 354 0 R (subsubsection.6.2.16.10) 390 0 R (subsubsection.6.2.16.11) 394 0 R (subsubsection.6.2.16.12) 398 0 R (subsubsection.6.2.16.13) 402 0 R (subsubsection.6.2.16.14) 406 0 R (subsubsection.6.2.16.15) 410 0 R (subsubsection.6.2.16.16) 414 0 R (subsubsection.6.2.16.17) 418 0 R (subsubsection.6.2.16.18) 422 0 R (subsubsection.6.2.16.2) 358 0 R (subsubsection.6.2.16.3) 362 0 R (subsubsection.6.2.16.4) 366 0 R (subsubsection.6.2.16.5) 370 0 R (subsubsection.6.2.16.6) 374 0 R (subsubsection.6.2.16.7) 378 0 R (subsubsection.6.2.16.8) 382 0 R (subsubsection.6.2.16.9) 386 0 R (subsubsection.6.2.26.1) 466 0 R (subsubsection.6.2.26.2) 470 0 R (subsubsection.6.2.26.3) 474 0 R (subsubsection.6.2.26.4) 478 0 R (subsubsection.6.3.1.1) 490 0 R (subsubsection.6.3.1.2) 494 0 R (subsubsection.6.3.5.1) 514 0 R (subsubsection.6.3.5.2) 518 0 R (subsubsection.6.3.5.3) 522 0 R (subsubsection.6.4.0.1) 538 0 R (subsubsection.6.4.1.1) 546 0 R (subsubsection.6.4.1.2) 550 0 R (subsubsection.6.4.1.3) 554 0 R (subsubsection.6.4.1.4) 558 0 R (subsubsection.6.4.1.5) 562 0 R (table.1.1) 947 0 R (table.1.2) 957 0 R (table.3.1) 1016 0 R (table.3.2) 1048 0 R (table.6.1) 1156 0 R (table.6.10) 1517 0 R (table.6.11) 1519 0 R (table.6.12) 1529 0 R (table.6.13) 1536 0 R (table.6.14) 1538 0 R (table.6.15) 1545 0 R (table.6.16) 1548 0 R (table.6.17) 1551 0 R (table.6.18) 1567 0 R (table.6.19) 1574 0 R (table.6.2) 1180 0 R (table.6.20) 1583 0 R (table.6.21) 1591 0 R (table.6.22) 1599 0 R (table.6.23) 1602 0 R (table.6.3) 1188 0 R (table.6.4) 1227 0 R (table.6.5) 1238 0 R (table.6.6) 1279 0 R (table.6.7) 1370 0 R (table.6.8) 1440 0 R (table.6.9) 1506 0 R (the_category_phrase) 1221 0 R (the_sortlist_statement) 1361 0 R (topology) 1355 0 R (tsig) 1095 0 R (tuning) 1375 0 R (types_of_resource_records_and_when_to_use_them) 964 0 R (view_statement_grammar) 1388 0 R (zone_statement_grammar) 1309 0 R (zone_transfers) 1071 0 R (zonefile_format) 1387 0 R] /Limits [(Access_Control_Lists) (zonefile_format)] >> endobj -2116 0 obj << -/Kids [2115 0 R] +2146 0 obj << +/Kids [2145 0 R] >> endobj -2117 0 obj << -/Dests 2116 0 R +2147 0 obj << +/Dests 2146 0 R >> endobj -2118 0 obj << +2148 0 obj << /Type /Catalog -/Pages 2113 0 R -/Outlines 2114 0 R -/Names 2117 0 R +/Pages 2143 0 R +/Outlines 2144 0 R +/Names 2147 0 R /PageMode /UseOutlines -/OpenAction 693 0 R +/OpenAction 701 0 R >> endobj -2119 0 obj << +2149 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords() -/CreationDate (D:20081116011130Z) +/CreationDate (D:20091231231729Z) /PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4) >> endobj xref -0 2120 +0 2150 0000000001 65535 f 0000000002 00000 f 0000000003 00000 f 0000000004 00000 f 0000000000 00000 f 0000000009 00000 n -0000070820 00000 n -0000731720 00000 n +0000071459 00000 n +0000744619 00000 n 0000000054 00000 n 0000000086 00000 n -0000070944 00000 n -0000731648 00000 n +0000071583 00000 n +0000744547 00000 n 0000000133 00000 n 0000000173 00000 n -0000071069 00000 n -0000731562 00000 n +0000071708 00000 n +0000744461 00000 n 0000000221 00000 n 0000000273 00000 n -0000071194 00000 n -0000731476 00000 n +0000071833 00000 n +0000744375 00000 n 0000000321 00000 n 0000000377 00000 n -0000075519 00000 n -0000731366 00000 n +0000076158 00000 n +0000744265 00000 n 0000000425 00000 n 0000000478 00000 n -0000075643 00000 n -0000731292 00000 n +0000076282 00000 n +0000744191 00000 n 0000000531 00000 n 0000000572 00000 n -0000075768 00000 n -0000731205 00000 n +0000076407 00000 n +0000744104 00000 n 0000000625 00000 n 0000000674 00000 n -0000075892 00000 n -0000731118 00000 n +0000076531 00000 n +0000744017 00000 n 0000000727 00000 n 0000000757 00000 n -0000080171 00000 n -0000730994 00000 n +0000080810 00000 n +0000743893 00000 n 0000000810 00000 n 0000000861 00000 n -0000080296 00000 n -0000730920 00000 n +0000080935 00000 n +0000743819 00000 n 0000000919 00000 n 0000000964 00000 n -0000080421 00000 n -0000730833 00000 n +0000081060 00000 n +0000743732 00000 n 0000001022 00000 n 0000001062 00000 n -0000080546 00000 n -0000730759 00000 n +0000081185 00000 n +0000743658 00000 n 0000001120 00000 n 0000001162 00000 n -0000083518 00000 n -0000730635 00000 n +0000084157 00000 n +0000743534 00000 n 0000001215 00000 n 0000001260 00000 n -0000083643 00000 n -0000730574 00000 n +0000084282 00000 n +0000743473 00000 n 0000001318 00000 n 0000001355 00000 n -0000083768 00000 n -0000730500 00000 n +0000084407 00000 n +0000743399 00000 n 0000001408 00000 n 0000001463 00000 n -0000086696 00000 n -0000730375 00000 n +0000087335 00000 n +0000743274 00000 n 0000001509 00000 n 0000001556 00000 n -0000086821 00000 n -0000730301 00000 n +0000087460 00000 n +0000743200 00000 n 0000001604 00000 n 0000001648 00000 n -0000086946 00000 n -0000730214 00000 n +0000087585 00000 n +0000743113 00000 n 0000001696 00000 n 0000001735 00000 n -0000087071 00000 n -0000730127 00000 n +0000087710 00000 n +0000743026 00000 n 0000001783 00000 n 0000001825 00000 n -0000087195 00000 n -0000730040 00000 n +0000087834 00000 n +0000742939 00000 n 0000001873 00000 n 0000001936 00000 n -0000088275 00000 n -0000729966 00000 n +0000088914 00000 n +0000742865 00000 n 0000001984 00000 n 0000002034 00000 n -0000089985 00000 n -0000729838 00000 n +0000090625 00000 n +0000742737 00000 n 0000002080 00000 n 0000002126 00000 n -0000090109 00000 n -0000729725 00000 n +0000090752 00000 n +0000742624 00000 n 0000002174 00000 n 0000002218 00000 n -0000090234 00000 n -0000729649 00000 n +0000090880 00000 n +0000742548 00000 n 0000002271 00000 n 0000002323 00000 n -0000090359 00000 n -0000729572 00000 n +0000091008 00000 n +0000742471 00000 n 0000002377 00000 n 0000002436 00000 n -0000092896 00000 n -0000729481 00000 n +0000093550 00000 n +0000742380 00000 n 0000002485 00000 n 0000002523 00000 n -0000093155 00000 n -0000729364 00000 n +0000093809 00000 n +0000742263 00000 n 0000002572 00000 n 0000002618 00000 n -0000093284 00000 n -0000729246 00000 n +0000093938 00000 n +0000742145 00000 n 0000002672 00000 n 0000002739 00000 n -0000096500 00000 n -0000729167 00000 n +0000097170 00000 n +0000742066 00000 n 0000002798 00000 n 0000002842 00000 n -0000096628 00000 n -0000729088 00000 n +0000097298 00000 n +0000741987 00000 n 0000002901 00000 n 0000002949 00000 n -0000107160 00000 n -0000729009 00000 n +0000107947 00000 n +0000741908 00000 n 0000003003 00000 n 0000003036 00000 n -0000112147 00000 n -0000728877 00000 n +0000112966 00000 n +0000741776 00000 n 0000003083 00000 n 0000003126 00000 n -0000112276 00000 n -0000728798 00000 n +0000113095 00000 n +0000741697 00000 n 0000003175 00000 n 0000003205 00000 n -0000112405 00000 n -0000728666 00000 n +0000113224 00000 n +0000741565 00000 n 0000003254 00000 n 0000003292 00000 n -0000112534 00000 n -0000728601 00000 n +0000113353 00000 n +0000741500 00000 n 0000003346 00000 n 0000003388 00000 n -0000116796 00000 n -0000728508 00000 n +0000117615 00000 n +0000741407 00000 n 0000003437 00000 n 0000003496 00000 n -0000116925 00000 n -0000728376 00000 n +0000117744 00000 n +0000741275 00000 n 0000003545 00000 n 0000003578 00000 n -0000117054 00000 n -0000728311 00000 n +0000117873 00000 n +0000741210 00000 n 0000003632 00000 n 0000003681 00000 n -0000124364 00000 n -0000728179 00000 n +0000125183 00000 n +0000741078 00000 n 0000003730 00000 n 0000003758 00000 n -0000124493 00000 n -0000728061 00000 n +0000125312 00000 n +0000740960 00000 n 0000003812 00000 n 0000003881 00000 n -0000124622 00000 n -0000727982 00000 n +0000125441 00000 n +0000740881 00000 n 0000003940 00000 n 0000003988 00000 n -0000127456 00000 n -0000727903 00000 n +0000128293 00000 n +0000740802 00000 n 0000004047 00000 n 0000004092 00000 n -0000127585 00000 n -0000727810 00000 n +0000128422 00000 n +0000740709 00000 n 0000004146 00000 n 0000004214 00000 n -0000127714 00000 n -0000727717 00000 n +0000128551 00000 n +0000740616 00000 n 0000004268 00000 n 0000004338 00000 n -0000127843 00000 n -0000727624 00000 n +0000128680 00000 n +0000740523 00000 n 0000004392 00000 n 0000004455 00000 n -0000131746 00000 n -0000727531 00000 n +0000132601 00000 n +0000740430 00000 n 0000004509 00000 n 0000004564 00000 n -0000131875 00000 n -0000727452 00000 n +0000132730 00000 n +0000740351 00000 n 0000004618 00000 n 0000004650 00000 n -0000132004 00000 n -0000727359 00000 n +0000132859 00000 n +0000740258 00000 n 0000004699 00000 n 0000004727 00000 n -0000132133 00000 n -0000727266 00000 n +0000132988 00000 n +0000740165 00000 n 0000004776 00000 n 0000004808 00000 n -0000135910 00000 n -0000727134 00000 n +0000136765 00000 n +0000740033 00000 n 0000004857 00000 n 0000004887 00000 n -0000136039 00000 n -0000727055 00000 n +0000136894 00000 n +0000739954 00000 n 0000004941 00000 n 0000004982 00000 n -0000136168 00000 n -0000726962 00000 n +0000137023 00000 n +0000739861 00000 n 0000005036 00000 n 0000005078 00000 n -0000139609 00000 n -0000726883 00000 n +0000140484 00000 n +0000739782 00000 n 0000005132 00000 n 0000005177 00000 n -0000142684 00000 n -0000726765 00000 n +0000143559 00000 n +0000739664 00000 n 0000005226 00000 n 0000005272 00000 n -0000142813 00000 n -0000726686 00000 n +0000143688 00000 n +0000739585 00000 n 0000005326 00000 n 0000005386 00000 n -0000142941 00000 n -0000726607 00000 n +0000143816 00000 n +0000739506 00000 n 0000005440 00000 n 0000005509 00000 n -0000145423 00000 n -0000726474 00000 n +0000146298 00000 n +0000739373 00000 n 0000005556 00000 n 0000005609 00000 n -0000145552 00000 n -0000726395 00000 n +0000146427 00000 n +0000739294 00000 n 0000005658 00000 n 0000005714 00000 n -0000145681 00000 n -0000726316 00000 n +0000146556 00000 n +0000739215 00000 n 0000005763 00000 n 0000005812 00000 n -0000149865 00000 n -0000726183 00000 n +0000150740 00000 n +0000739082 00000 n 0000005859 00000 n 0000005911 00000 n -0000149994 00000 n -0000726065 00000 n +0000150869 00000 n +0000738964 00000 n 0000005960 00000 n 0000006011 00000 n -0000154684 00000 n -0000725947 00000 n +0000155559 00000 n +0000738846 00000 n 0000006065 00000 n 0000006110 00000 n -0000154812 00000 n -0000725868 00000 n +0000155687 00000 n +0000738767 00000 n 0000006169 00000 n 0000006203 00000 n -0000158401 00000 n -0000725789 00000 n +0000159308 00000 n +0000738688 00000 n 0000006262 00000 n 0000006310 00000 n -0000158529 00000 n -0000725671 00000 n +0000159436 00000 n +0000738570 00000 n 0000006364 00000 n 0000006404 00000 n -0000158658 00000 n -0000725592 00000 n +0000159565 00000 n +0000738491 00000 n 0000006463 00000 n 0000006497 00000 n -0000162385 00000 n -0000725513 00000 n +0000163504 00000 n +0000738412 00000 n 0000006556 00000 n 0000006604 00000 n -0000162514 00000 n -0000725380 00000 n +0000163633 00000 n +0000738279 00000 n 0000006653 00000 n 0000006703 00000 n -0000165534 00000 n -0000725301 00000 n +0000166453 00000 n +0000738200 00000 n 0000006757 00000 n 0000006804 00000 n -0000165662 00000 n -0000725208 00000 n +0000166581 00000 n +0000738107 00000 n 0000006858 00000 n 0000006918 00000 n -0000165920 00000 n -0000725115 00000 n +0000166840 00000 n +0000738014 00000 n 0000006972 00000 n 0000007024 00000 n -0000171027 00000 n -0000725022 00000 n +0000172189 00000 n +0000737921 00000 n 0000007078 00000 n 0000007143 00000 n -0000171156 00000 n -0000724929 00000 n +0000172318 00000 n +0000737828 00000 n 0000007197 00000 n 0000007248 00000 n -0000174630 00000 n -0000724836 00000 n +0000172447 00000 n +0000737735 00000 n 0000007302 00000 n 0000007366 00000 n -0000174759 00000 n -0000724743 00000 n +0000175899 00000 n +0000737642 00000 n 0000007420 00000 n 0000007467 00000 n -0000174888 00000 n -0000724650 00000 n +0000176028 00000 n +0000737549 00000 n 0000007521 00000 n 0000007581 00000 n -0000175017 00000 n -0000724557 00000 n +0000176157 00000 n +0000737456 00000 n 0000007635 00000 n 0000007686 00000 n -0000179033 00000 n -0000724425 00000 n +0000176286 00000 n +0000737324 00000 n 0000007741 00000 n 0000007806 00000 n -0000179162 00000 n -0000724346 00000 n +0000180517 00000 n +0000737245 00000 n 0000007866 00000 n 0000007913 00000 n -0000185987 00000 n -0000724267 00000 n +0000187075 00000 n +0000737152 00000 n 0000007973 00000 n 0000008021 00000 n -0000192355 00000 n -0000724174 00000 n -0000008076 00000 n -0000008126 00000 n -0000192484 00000 n -0000724081 00000 n -0000008181 00000 n -0000008244 00000 n -0000192612 00000 n -0000723988 00000 n -0000008299 00000 n -0000008351 00000 n -0000192740 00000 n -0000723895 00000 n -0000008406 00000 n -0000008471 00000 n -0000192869 00000 n -0000723802 00000 n -0000008526 00000 n -0000008578 00000 n -0000198137 00000 n -0000723669 00000 n -0000008633 00000 n -0000008698 00000 n -0000206589 00000 n -0000723590 00000 n -0000008758 00000 n -0000008802 00000 n -0000227810 00000 n -0000723497 00000 n -0000008862 00000 n -0000008901 00000 n -0000227938 00000 n -0000723404 00000 n -0000008961 00000 n -0000009008 00000 n -0000228067 00000 n -0000723311 00000 n -0000009068 00000 n -0000009111 00000 n -0000235196 00000 n -0000723218 00000 n -0000009171 00000 n -0000009210 00000 n -0000235325 00000 n -0000723125 00000 n -0000009270 00000 n -0000009312 00000 n -0000242275 00000 n -0000723032 00000 n -0000009372 00000 n -0000009415 00000 n -0000250260 00000 n -0000722939 00000 n -0000009475 00000 n -0000009518 00000 n -0000250389 00000 n -0000722846 00000 n -0000009578 00000 n -0000009639 00000 n -0000254380 00000 n -0000722753 00000 n -0000009700 00000 n -0000009752 00000 n -0000257620 00000 n -0000722660 00000 n -0000009813 00000 n +0000194627 00000 n +0000737073 00000 n +0000008081 00000 n +0000008135 00000 n +0000194886 00000 n +0000736980 00000 n +0000008190 00000 n +0000008240 00000 n +0000197709 00000 n +0000736887 00000 n +0000008295 00000 n +0000008358 00000 n +0000197838 00000 n +0000736794 00000 n +0000008413 00000 n +0000008465 00000 n +0000197967 00000 n +0000736701 00000 n +0000008520 00000 n +0000008585 00000 n +0000198096 00000 n +0000736608 00000 n +0000008640 00000 n +0000008692 00000 n +0000203976 00000 n +0000736475 00000 n +0000008747 00000 n +0000008812 00000 n +0000212370 00000 n +0000736396 00000 n +0000008872 00000 n +0000008916 00000 n +0000233628 00000 n +0000736303 00000 n +0000008976 00000 n +0000009015 00000 n +0000233757 00000 n +0000736210 00000 n +0000009075 00000 n +0000009122 00000 n +0000233886 00000 n +0000736117 00000 n +0000009182 00000 n +0000009225 00000 n +0000240979 00000 n +0000736024 00000 n +0000009285 00000 n +0000009324 00000 n +0000241107 00000 n +0000735931 00000 n +0000009384 00000 n +0000009426 00000 n +0000248082 00000 n +0000735838 00000 n +0000009486 00000 n +0000009529 00000 n +0000255955 00000 n +0000735745 00000 n +0000009589 00000 n +0000009632 00000 n +0000256084 00000 n +0000735652 00000 n +0000009692 00000 n +0000009753 00000 n +0000260235 00000 n +0000735559 00000 n +0000009814 00000 n 0000009866 00000 n -0000257749 00000 n -0000722567 00000 n +0000263744 00000 n +0000735466 00000 n 0000009927 00000 n -0000009965 00000 n -0000261821 00000 n -0000722474 00000 n -0000010026 00000 n -0000010078 00000 n -0000265032 00000 n -0000722381 00000 n -0000010139 00000 n -0000010183 00000 n -0000265290 00000 n -0000722288 00000 n -0000010244 00000 n -0000010280 00000 n -0000274081 00000 n -0000722195 00000 n -0000010341 00000 n -0000010404 00000 n -0000277408 00000 n -0000722102 00000 n -0000010465 00000 n -0000010515 00000 n -0000281163 00000 n -0000722023 00000 n -0000010576 00000 n -0000010632 00000 n -0000284537 00000 n -0000721930 00000 n -0000010687 00000 n -0000010751 00000 n -0000284666 00000 n -0000721837 00000 n -0000010806 00000 n -0000010883 00000 n -0000284794 00000 n -0000721744 00000 n -0000010938 00000 n -0000010989 00000 n -0000289362 00000 n -0000721651 00000 n -0000011044 00000 n -0000011108 00000 n -0000292729 00000 n -0000721558 00000 n -0000011163 00000 n -0000011220 00000 n -0000292857 00000 n -0000721465 00000 n -0000011275 00000 n -0000011345 00000 n -0000292986 00000 n -0000721372 00000 n -0000011400 00000 n -0000011449 00000 n -0000293115 00000 n -0000721279 00000 n -0000011504 00000 n -0000011566 00000 n -0000297818 00000 n -0000721186 00000 n -0000011621 00000 n -0000011670 00000 n -0000301909 00000 n -0000721068 00000 n -0000011725 00000 n -0000011787 00000 n -0000302038 00000 n -0000720989 00000 n -0000011847 00000 n -0000011886 00000 n -0000306096 00000 n -0000720896 00000 n -0000011946 00000 n -0000011980 00000 n -0000311992 00000 n -0000720803 00000 n -0000012040 00000 n -0000012081 00000 n -0000323134 00000 n -0000720724 00000 n -0000012141 00000 n -0000012193 00000 n -0000330383 00000 n -0000720592 00000 n -0000012242 00000 n -0000012275 00000 n -0000330512 00000 n -0000720474 00000 n -0000012329 00000 n -0000012401 00000 n -0000330640 00000 n -0000720395 00000 n -0000012460 00000 n -0000012504 00000 n -0000341427 00000 n -0000720316 00000 n -0000012563 00000 n -0000012616 00000 n -0000341814 00000 n -0000720223 00000 n -0000012670 00000 n -0000012720 00000 n -0000345189 00000 n -0000720130 00000 n -0000012774 00000 n -0000012812 00000 n -0000345448 00000 n -0000720037 00000 n -0000012866 00000 n -0000012915 00000 n -0000348312 00000 n -0000719905 00000 n -0000012969 00000 n -0000013021 00000 n -0000348440 00000 n -0000719826 00000 n -0000013080 00000 n -0000013132 00000 n -0000348569 00000 n -0000719733 00000 n -0000013191 00000 n -0000013244 00000 n -0000348698 00000 n -0000719654 00000 n -0000013303 00000 n -0000013352 00000 n -0000352344 00000 n -0000719561 00000 n -0000013406 00000 n -0000013486 00000 n -0000356394 00000 n -0000719482 00000 n -0000013540 00000 n -0000013589 00000 n -0000356523 00000 n -0000719364 00000 n -0000013638 00000 n -0000013678 00000 n -0000359826 00000 n -0000719285 00000 n -0000013737 00000 n -0000013784 00000 n -0000359955 00000 n -0000719167 00000 n -0000013838 00000 n -0000013883 00000 n -0000360084 00000 n -0000719088 00000 n -0000013942 00000 n -0000014001 00000 n -0000363183 00000 n -0000718995 00000 n -0000014060 00000 n -0000014124 00000 n -0000363442 00000 n -0000718902 00000 n -0000014183 00000 n -0000014239 00000 n -0000366164 00000 n -0000718823 00000 n -0000014298 00000 n -0000014360 00000 n -0000368398 00000 n -0000718690 00000 n -0000014407 00000 n -0000014459 00000 n -0000368527 00000 n -0000718611 00000 n -0000014508 00000 n -0000014552 00000 n -0000372713 00000 n -0000718479 00000 n -0000014601 00000 n -0000014642 00000 n -0000372842 00000 n -0000718400 00000 n -0000014696 00000 n -0000014744 00000 n -0000372970 00000 n -0000718321 00000 n -0000014798 00000 n -0000014849 00000 n -0000373099 00000 n -0000718242 00000 n -0000014898 00000 n -0000014945 00000 n -0000377366 00000 n -0000718109 00000 n -0000014992 00000 n +0000009980 00000 n +0000263873 00000 n +0000735373 00000 n +0000010041 00000 n +0000010079 00000 n +0000267780 00000 n +0000735280 00000 n +0000010140 00000 n +0000010192 00000 n +0000271179 00000 n +0000735187 00000 n +0000010253 00000 n +0000010297 00000 n +0000275345 00000 n +0000735094 00000 n +0000010358 00000 n +0000010394 00000 n +0000280135 00000 n +0000735001 00000 n +0000010455 00000 n +0000010518 00000 n +0000283544 00000 n +0000734908 00000 n +0000010579 00000 n +0000010629 00000 n +0000287237 00000 n +0000734829 00000 n +0000010690 00000 n +0000010746 00000 n +0000290642 00000 n +0000734736 00000 n +0000010801 00000 n +0000010852 00000 n +0000290771 00000 n +0000734643 00000 n +0000010907 00000 n +0000010971 00000 n +0000295142 00000 n +0000734550 00000 n +0000011026 00000 n +0000011090 00000 n +0000295271 00000 n +0000734457 00000 n +0000011145 00000 n +0000011222 00000 n +0000298928 00000 n +0000734364 00000 n +0000011277 00000 n +0000011334 00000 n +0000299057 00000 n +0000734271 00000 n +0000011389 00000 n +0000011459 00000 n +0000299186 00000 n +0000734178 00000 n +0000011514 00000 n +0000011563 00000 n +0000302629 00000 n +0000734085 00000 n +0000011618 00000 n +0000011680 00000 n +0000304248 00000 n +0000733992 00000 n +0000011735 00000 n +0000011784 00000 n +0000308427 00000 n +0000733874 00000 n +0000011839 00000 n +0000011901 00000 n +0000308556 00000 n +0000733795 00000 n +0000011961 00000 n +0000012000 00000 n +0000312881 00000 n +0000733702 00000 n +0000012060 00000 n +0000012094 00000 n +0000318771 00000 n +0000733609 00000 n +0000012154 00000 n +0000012195 00000 n +0000330157 00000 n +0000733530 00000 n +0000012255 00000 n +0000012307 00000 n +0000337397 00000 n +0000733398 00000 n +0000012356 00000 n +0000012389 00000 n +0000337526 00000 n +0000733280 00000 n +0000012443 00000 n +0000012515 00000 n +0000337654 00000 n +0000733201 00000 n +0000012574 00000 n +0000012618 00000 n +0000348444 00000 n +0000733122 00000 n +0000012677 00000 n +0000012730 00000 n +0000348831 00000 n +0000733029 00000 n +0000012784 00000 n +0000012834 00000 n +0000352195 00000 n +0000732936 00000 n +0000012888 00000 n +0000012926 00000 n +0000352454 00000 n +0000732843 00000 n +0000012980 00000 n +0000013029 00000 n +0000355319 00000 n +0000732711 00000 n +0000013083 00000 n +0000013135 00000 n +0000355447 00000 n +0000732632 00000 n +0000013194 00000 n +0000013246 00000 n +0000355576 00000 n +0000732539 00000 n +0000013305 00000 n +0000013358 00000 n +0000355705 00000 n +0000732460 00000 n +0000013417 00000 n +0000013466 00000 n +0000359352 00000 n +0000732367 00000 n +0000013520 00000 n +0000013600 00000 n +0000363488 00000 n +0000732288 00000 n +0000013654 00000 n +0000013703 00000 n +0000363617 00000 n +0000732170 00000 n +0000013752 00000 n +0000013792 00000 n +0000366917 00000 n +0000732091 00000 n +0000013851 00000 n +0000013898 00000 n +0000367046 00000 n +0000731973 00000 n +0000013952 00000 n +0000013997 00000 n +0000367175 00000 n +0000731894 00000 n +0000014056 00000 n +0000014115 00000 n +0000370864 00000 n +0000731801 00000 n +0000014174 00000 n +0000014238 00000 n +0000374585 00000 n +0000731708 00000 n +0000014297 00000 n +0000014353 00000 n +0000374843 00000 n +0000731615 00000 n +0000014412 00000 n +0000014470 00000 n +0000377514 00000 n +0000731536 00000 n +0000014529 00000 n +0000014591 00000 n +0000379759 00000 n +0000731403 00000 n +0000014638 00000 n +0000014690 00000 n +0000379888 00000 n +0000731324 00000 n +0000014739 00000 n +0000014783 00000 n +0000384086 00000 n +0000731192 00000 n +0000014832 00000 n +0000014873 00000 n +0000384215 00000 n +0000731113 00000 n +0000014927 00000 n +0000014975 00000 n +0000384343 00000 n +0000731034 00000 n 0000015029 00000 n -0000377495 00000 n -0000717991 00000 n -0000015078 00000 n -0000015117 00000 n -0000377624 00000 n -0000717926 00000 n -0000015171 00000 n -0000015249 00000 n -0000377753 00000 n -0000717833 00000 n -0000015298 00000 n -0000015365 00000 n -0000377882 00000 n -0000717754 00000 n -0000015414 00000 n -0000015459 00000 n -0000381321 00000 n -0000717621 00000 n -0000015507 00000 n -0000015539 00000 n -0000381450 00000 n -0000717503 00000 n -0000015588 00000 n -0000015627 00000 n -0000381579 00000 n -0000717438 00000 n -0000015681 00000 n -0000015742 00000 n -0000385344 00000 n -0000717306 00000 n -0000015791 00000 n -0000015848 00000 n -0000385473 00000 n -0000717241 00000 n -0000015902 00000 n -0000015951 00000 n -0000385602 00000 n -0000717123 00000 n -0000016000 00000 n -0000016062 00000 n -0000385731 00000 n -0000717044 00000 n -0000016116 00000 n -0000016171 00000 n -0000409752 00000 n -0000716951 00000 n -0000016225 00000 n -0000016266 00000 n -0000409881 00000 n -0000716872 00000 n -0000016320 00000 n -0000016372 00000 n -0000412612 00000 n -0000716752 00000 n -0000016420 00000 n -0000016454 00000 n -0000412741 00000 n -0000716673 00000 n -0000016503 00000 n -0000016530 00000 n -0000430434 00000 n -0000716580 00000 n -0000016579 00000 n -0000016607 00000 n -0000437928 00000 n -0000716487 00000 n -0000016656 00000 n -0000016696 00000 n -0000440723 00000 n -0000716394 00000 n -0000016745 00000 n -0000016788 00000 n -0000446647 00000 n -0000716301 00000 n -0000016837 00000 n -0000016874 00000 n -0000453150 00000 n -0000716208 00000 n -0000016923 00000 n -0000016962 00000 n -0000462862 00000 n -0000716115 00000 n -0000017011 00000 n -0000017050 00000 n -0000465578 00000 n -0000716022 00000 n -0000017099 00000 n -0000017138 00000 n -0000475305 00000 n -0000715929 00000 n -0000017187 00000 n -0000017216 00000 n -0000481121 00000 n -0000715836 00000 n -0000017266 00000 n -0000017299 00000 n -0000495077 00000 n -0000715743 00000 n -0000017349 00000 n -0000017378 00000 n -0000498576 00000 n -0000715650 00000 n -0000017428 00000 n -0000017462 00000 n -0000504687 00000 n -0000715571 00000 n -0000017512 00000 n -0000017549 00000 n -0000017918 00000 n -0000018040 00000 n -0000025869 00000 n -0000017602 00000 n -0000025743 00000 n -0000025806 00000 n -0000711071 00000 n -0000685128 00000 n -0000710897 00000 n -0000712096 00000 n -0000020903 00000 n -0000021120 00000 n -0000021189 00000 n -0000021258 00000 n -0000021326 00000 n -0000021394 00000 n -0000021443 00000 n -0000021490 00000 n -0000021823 00000 n -0000021845 00000 n -0000022013 00000 n -0000022178 00000 n -0000022347 00000 n -0000022526 00000 n -0000022835 00000 n -0000022995 00000 n -0000027233 00000 n -0000027048 00000 n -0000025969 00000 n -0000027170 00000 n -0000683907 00000 n -0000657386 00000 n -0000683733 00000 n -0000656701 00000 n -0000654557 00000 n -0000656537 00000 n -0000038940 00000 n -0000030289 00000 n -0000027318 00000 n -0000038814 00000 n -0000038877 00000 n -0000030823 00000 n -0000030977 00000 n -0000031134 00000 n -0000031291 00000 n -0000031447 00000 n -0000031604 00000 n -0000031766 00000 n -0000031927 00000 n -0000032088 00000 n -0000032250 00000 n -0000032417 00000 n -0000032584 00000 n -0000032749 00000 n -0000032911 00000 n -0000033077 00000 n -0000033238 00000 n -0000033393 00000 n -0000033550 00000 n -0000033706 00000 n -0000033863 00000 n -0000034020 00000 n -0000034177 00000 n -0000034331 00000 n -0000034487 00000 n -0000034649 00000 n -0000034811 00000 n -0000034967 00000 n -0000035124 00000 n -0000035286 00000 n -0000035453 00000 n -0000035619 00000 n -0000035780 00000 n -0000035935 00000 n -0000036092 00000 n -0000036249 00000 n -0000036411 00000 n -0000036568 00000 n -0000036725 00000 n -0000036887 00000 n -0000037044 00000 n -0000037206 00000 n -0000037373 00000 n -0000037539 00000 n -0000037701 00000 n -0000037863 00000 n -0000038025 00000 n -0000038187 00000 n -0000038349 00000 n -0000038504 00000 n -0000038659 00000 n -0000052318 00000 n -0000042272 00000 n -0000039025 00000 n -0000052255 00000 n -0000654006 00000 n -0000636925 00000 n -0000653822 00000 n -0000042862 00000 n -0000043025 00000 n -0000043187 00000 n -0000043350 00000 n -0000043508 00000 n -0000043671 00000 n -0000043834 00000 n -0000043989 00000 n -0000044147 00000 n -0000044305 00000 n -0000044461 00000 n -0000044619 00000 n -0000044782 00000 n -0000044950 00000 n -0000045118 00000 n -0000045281 00000 n -0000045449 00000 n -0000045617 00000 n -0000045775 00000 n -0000045938 00000 n -0000046101 00000 n -0000046263 00000 n -0000046425 00000 n -0000046588 00000 n -0000046750 00000 n -0000046912 00000 n -0000047075 00000 n -0000047238 00000 n -0000047401 00000 n -0000047570 00000 n -0000047739 00000 n -0000047903 00000 n -0000048066 00000 n -0000048230 00000 n -0000048394 00000 n -0000048557 00000 n -0000048721 00000 n -0000048890 00000 n -0000049059 00000 n -0000049228 00000 n -0000049397 00000 n -0000049566 00000 n -0000049735 00000 n -0000049904 00000 n -0000050073 00000 n -0000050242 00000 n -0000050412 00000 n -0000050582 00000 n -0000050752 00000 n -0000050922 00000 n -0000051092 00000 n -0000051262 00000 n -0000051432 00000 n -0000051601 00000 n -0000051771 00000 n -0000051932 00000 n -0000052093 00000 n -0000065459 00000 n -0000055941 00000 n -0000052416 00000 n -0000065396 00000 n -0000056515 00000 n -0000056678 00000 n -0000056841 00000 n -0000057004 00000 n -0000057167 00000 n -0000057330 00000 n -0000057493 00000 n -0000057656 00000 n -0000057824 00000 n -0000057991 00000 n -0000058159 00000 n -0000058327 00000 n -0000058484 00000 n -0000058646 00000 n -0000058811 00000 n -0000058977 00000 n -0000059139 00000 n -0000059301 00000 n -0000059463 00000 n -0000059625 00000 n -0000059792 00000 n -0000059959 00000 n -0000060126 00000 n -0000060288 00000 n -0000060450 00000 n -0000060607 00000 n -0000060774 00000 n -0000060936 00000 n -0000061103 00000 n -0000061270 00000 n -0000636036 00000 n -0000614704 00000 n -0000635862 00000 n -0000061437 00000 n -0000061604 00000 n -0000061759 00000 n -0000061916 00000 n -0000062073 00000 n -0000062235 00000 n -0000062396 00000 n -0000062552 00000 n -0000062707 00000 n -0000062864 00000 n -0000063026 00000 n -0000063183 00000 n -0000063340 00000 n -0000063496 00000 n -0000063652 00000 n -0000063813 00000 n -0000063970 00000 n -0000064132 00000 n -0000064289 00000 n -0000064451 00000 n -0000064613 00000 n -0000064775 00000 n -0000064931 00000 n -0000065086 00000 n -0000065241 00000 n -0000068260 00000 n -0000066412 00000 n -0000065570 00000 n -0000068197 00000 n -0000066626 00000 n -0000066783 00000 n -0000066940 00000 n -0000067096 00000 n -0000067253 00000 n -0000067409 00000 n -0000067566 00000 n -0000067724 00000 n -0000613738 00000 n -0000593771 00000 n -0000613565 00000 n -0000067882 00000 n -0000068039 00000 n -0000071445 00000 n -0000070635 00000 n -0000068358 00000 n -0000070757 00000 n -0000070881 00000 n -0000071006 00000 n -0000071131 00000 n -0000071256 00000 n -0000071319 00000 n -0000071382 00000 n -0000592977 00000 n -0000574660 00000 n -0000592804 00000 n -0000712214 00000 n -0000076016 00000 n -0000074836 00000 n -0000071569 00000 n -0000075330 00000 n -0000075393 00000 n -0000075456 00000 n -0000075580 00000 n -0000075705 00000 n -0000075830 00000 n -0000074986 00000 n -0000075179 00000 n -0000075953 00000 n -0000330576 00000 n -0000385795 00000 n -0000080671 00000 n -0000079635 00000 n -0000076140 00000 n -0000080108 00000 n -0000080233 00000 n -0000079785 00000 n -0000079947 00000 n -0000080358 00000 n -0000080483 00000 n -0000080608 00000 n -0000096564 00000 n -0000083893 00000 n -0000083333 00000 n -0000080795 00000 n -0000083455 00000 n -0000083580 00000 n -0000083705 00000 n -0000083830 00000 n -0000087320 00000 n -0000086179 00000 n -0000084004 00000 n -0000086633 00000 n -0000086758 00000 n -0000086883 00000 n -0000087008 00000 n -0000087133 00000 n -0000086329 00000 n -0000086481 00000 n -0000087257 00000 n -0000281227 00000 n -0000088400 00000 n -0000088090 00000 n -0000087405 00000 n -0000088212 00000 n -0000088337 00000 n -0000090485 00000 n -0000089800 00000 n -0000088498 00000 n -0000089922 00000 n -0000090047 00000 n -0000090171 00000 n -0000090296 00000 n -0000090422 00000 n -0000712332 00000 n -0000093412 00000 n -0000092524 00000 n -0000090583 00000 n -0000092831 00000 n -0000092960 00000 n -0000093025 00000 n -0000093090 00000 n -0000092670 00000 n -0000093219 00000 n -0000093348 00000 n -0000265096 00000 n -0000096757 00000 n -0000096310 00000 n -0000093524 00000 n -0000096435 00000 n -0000573985 00000 n -0000561996 00000 n -0000573806 00000 n -0000096692 00000 n -0000100548 00000 n -0000100358 00000 n -0000096883 00000 n -0000100483 00000 n -0000561455 00000 n -0000551709 00000 n -0000561276 00000 n -0000105074 00000 n -0000104676 00000 n -0000100714 00000 n -0000105009 00000 n -0000104822 00000 n -0000171091 00000 n -0000107419 00000 n -0000106970 00000 n -0000105213 00000 n -0000107095 00000 n -0000107224 00000 n -0000107289 00000 n -0000107354 00000 n -0000110116 00000 n -0000112663 00000 n -0000109960 00000 n -0000107544 00000 n -0000112082 00000 n -0000112211 00000 n -0000112340 00000 n -0000111759 00000 n -0000111921 00000 n -0000550839 00000 n -0000541419 00000 n -0000550665 00000 n -0000540855 00000 n -0000531769 00000 n -0000540680 00000 n -0000112469 00000 n -0000112598 00000 n -0000712455 00000 n -0000111588 00000 n -0000111646 00000 n -0000111736 00000 n -0000206653 00000 n -0000242339 00000 n -0000117183 00000 n -0000116248 00000 n -0000112819 00000 n -0000116731 00000 n -0000116860 00000 n -0000116404 00000 n -0000116569 00000 n -0000116989 00000 n -0000117118 00000 n -0000389821 00000 n -0000120797 00000 n -0000120417 00000 n -0000117335 00000 n -0000120732 00000 n -0000120564 00000 n -0000122047 00000 n -0000121856 00000 n -0000120922 00000 n -0000121982 00000 n -0000124750 00000 n -0000124173 00000 n -0000122146 00000 n -0000124299 00000 n -0000124428 00000 n -0000124557 00000 n -0000124686 00000 n -0000127972 00000 n -0000127265 00000 n -0000124888 00000 n -0000127391 00000 n -0000127520 00000 n -0000127649 00000 n -0000127778 00000 n -0000127907 00000 n -0000132261 00000 n -0000131363 00000 n -0000128097 00000 n -0000131681 00000 n -0000131810 00000 n -0000131510 00000 n -0000131939 00000 n -0000132068 00000 n -0000132196 00000 n -0000712580 00000 n -0000323198 00000 n -0000136297 00000 n -0000135719 00000 n -0000132386 00000 n -0000135845 00000 n -0000135974 00000 n -0000136103 00000 n -0000136232 00000 n -0000139738 00000 n -0000139418 00000 n -0000136435 00000 n -0000139544 00000 n -0000139673 00000 n -0000143070 00000 n -0000142311 00000 n -0000139850 00000 n -0000142619 00000 n -0000142748 00000 n -0000142458 00000 n -0000142877 00000 n -0000143005 00000 n -0000385537 00000 n -0000145810 00000 n -0000145232 00000 n -0000143238 00000 n -0000145358 00000 n -0000145487 00000 n -0000145616 00000 n -0000145745 00000 n -0000146250 00000 n -0000146059 00000 n -0000145909 00000 n -0000146185 00000 n -0000150252 00000 n -0000149486 00000 n -0000146292 00000 n -0000149800 00000 n -0000149929 00000 n -0000150057 00000 n -0000150122 00000 n -0000150187 00000 n -0000149633 00000 n -0000712705 00000 n -0000154748 00000 n -0000154940 00000 n -0000154493 00000 n -0000150351 00000 n -0000154619 00000 n -0000154875 00000 n -0000158787 00000 n -0000158210 00000 n -0000155065 00000 n -0000158336 00000 n -0000158464 00000 n -0000158593 00000 n -0000158722 00000 n -0000161394 00000 n -0000162773 00000 n -0000161268 00000 n -0000158925 00000 n -0000162320 00000 n -0000162449 00000 n -0000162578 00000 n -0000162643 00000 n -0000162708 00000 n -0000166049 00000 n -0000165343 00000 n -0000162928 00000 n -0000165469 00000 n -0000165597 00000 n -0000165726 00000 n -0000165790 00000 n -0000165855 00000 n -0000165984 00000 n -0000171284 00000 n -0000170496 00000 n -0000166161 00000 n -0000170962 00000 n -0000170652 00000 n -0000170803 00000 n -0000171220 00000 n -0000510397 00000 n -0000175146 00000 n -0000173875 00000 n -0000171422 00000 n -0000174565 00000 n -0000174694 00000 n -0000174823 00000 n -0000174952 00000 n -0000174040 00000 n -0000174192 00000 n -0000174378 00000 n -0000175081 00000 n -0000712830 00000 n -0000179291 00000 n -0000178842 00000 n -0000175272 00000 n -0000178968 00000 n -0000179097 00000 n -0000179226 00000 n -0000183212 00000 n -0000182833 00000 n -0000179416 00000 n -0000183147 00000 n -0000182980 00000 n -0000186051 00000 n -0000186245 00000 n -0000185796 00000 n -0000183324 00000 n -0000185922 00000 n -0000186116 00000 n -0000186181 00000 n -0000189675 00000 n -0000189484 00000 n -0000186357 00000 n -0000189610 00000 n -0000192997 00000 n -0000191830 00000 n -0000189787 00000 n -0000192290 00000 n -0000192419 00000 n -0000192548 00000 n -0000191986 00000 n -0000192140 00000 n -0000192676 00000 n -0000192804 00000 n -0000192932 00000 n -0000194483 00000 n -0000194292 00000 n -0000193109 00000 n -0000194418 00000 n -0000712955 00000 n -0000196016 00000 n -0000195825 00000 n -0000194582 00000 n -0000195951 00000 n -0000198266 00000 n -0000197946 00000 n -0000196115 00000 n -0000198072 00000 n -0000198201 00000 n -0000202789 00000 n -0000202420 00000 n -0000198378 00000 n -0000202724 00000 n -0000202567 00000 n -0000359890 00000 n -0000206718 00000 n -0000206398 00000 n -0000202927 00000 n -0000206524 00000 n -0000210794 00000 n -0000210300 00000 n -0000206843 00000 n -0000210599 00000 n -0000210664 00000 n -0000210729 00000 n -0000210447 00000 n -0000215794 00000 n -0000214662 00000 n -0000210919 00000 n -0000215729 00000 n -0000214845 00000 n -0000215002 00000 n -0000215186 00000 n -0000215359 00000 n -0000215544 00000 n -0000713080 00000 n -0000289426 00000 n -0000220074 00000 n -0000219883 00000 n -0000215975 00000 n -0000220009 00000 n -0000223936 00000 n -0000223745 00000 n -0000220199 00000 n -0000223871 00000 n -0000228196 00000 n -0000227253 00000 n -0000224048 00000 n -0000227745 00000 n -0000227873 00000 n -0000227409 00000 n -0000228002 00000 n -0000228131 00000 n -0000227579 00000 n -0000297882 00000 n -0000232129 00000 n -0000231567 00000 n -0000228365 00000 n -0000232064 00000 n -0000231723 00000 n -0000231893 00000 n -0000373163 00000 n -0000235454 00000 n -0000235005 00000 n -0000232298 00000 n -0000235131 00000 n -0000235260 00000 n -0000235389 00000 n -0000238850 00000 n -0000238659 00000 n -0000235579 00000 n -0000238785 00000 n -0000713205 00000 n -0000242404 00000 n -0000242084 00000 n -0000239019 00000 n -0000242210 00000 n -0000246107 00000 n -0000245916 00000 n -0000242560 00000 n -0000246042 00000 n -0000250518 00000 n -0000249704 00000 n -0000246276 00000 n -0000250195 00000 n -0000250324 00000 n -0000249860 00000 n -0000250453 00000 n -0000250021 00000 n -0000254509 00000 n -0000254014 00000 n -0000250673 00000 n -0000254315 00000 n -0000254444 00000 n -0000254161 00000 n -0000257878 00000 n -0000257429 00000 n -0000254634 00000 n -0000257555 00000 n -0000257684 00000 n -0000257813 00000 n -0000261950 00000 n -0000261283 00000 n -0000258033 00000 n -0000261756 00000 n -0000261885 00000 n -0000261439 00000 n -0000261601 00000 n -0000713330 00000 n -0000265418 00000 n -0000264650 00000 n -0000262119 00000 n -0000264967 00000 n -0000264797 00000 n -0000265160 00000 n -0000265225 00000 n -0000265354 00000 n -0000269455 00000 n -0000269083 00000 n -0000265601 00000 n -0000269390 00000 n -0000269230 00000 n -0000274209 00000 n -0000273530 00000 n -0000269623 00000 n -0000274016 00000 n -0000273686 00000 n -0000531414 00000 n -0000529417 00000 n -0000531249 00000 n -0000274144 00000 n -0000273849 00000 n -0000356458 00000 n -0000293050 00000 n -0000277537 00000 n -0000277217 00000 n -0000274335 00000 n -0000277343 00000 n -0000277472 00000 n -0000281291 00000 n -0000280972 00000 n -0000277662 00000 n -0000281098 00000 n -0000284923 00000 n -0000284346 00000 n -0000281433 00000 n -0000284472 00000 n -0000284601 00000 n -0000284730 00000 n -0000284858 00000 n -0000713455 00000 n -0000289491 00000 n -0000289000 00000 n -0000285035 00000 n -0000289297 00000 n -0000289147 00000 n -0000293243 00000 n -0000292193 00000 n -0000289603 00000 n -0000292664 00000 n -0000292349 00000 n -0000292792 00000 n -0000292921 00000 n -0000292511 00000 n -0000293179 00000 n -0000296310 00000 n -0000296119 00000 n -0000293355 00000 n -0000296245 00000 n -0000297947 00000 n -0000297627 00000 n -0000296422 00000 n -0000297753 00000 n -0000299421 00000 n -0000299230 00000 n -0000298059 00000 n -0000299356 00000 n -0000302297 00000 n -0000301718 00000 n -0000299520 00000 n -0000301844 00000 n -0000301973 00000 n -0000302102 00000 n -0000302167 00000 n -0000302232 00000 n -0000713580 00000 n -0000306225 00000 n -0000305905 00000 n -0000302409 00000 n -0000306031 00000 n -0000306160 00000 n -0000312121 00000 n -0000309387 00000 n -0000306337 00000 n -0000311927 00000 n -0000312056 00000 n -0000309651 00000 n -0000309813 00000 n -0000309975 00000 n -0000310136 00000 n -0000310296 00000 n -0000310458 00000 n -0000310629 00000 n -0000310791 00000 n -0000310953 00000 n -0000311114 00000 n -0000311275 00000 n -0000311438 00000 n -0000311601 00000 n -0000311764 00000 n -0000317105 00000 n -0000315364 00000 n -0000312233 00000 n -0000317040 00000 n -0000315583 00000 n -0000315744 00000 n -0000315913 00000 n -0000316075 00000 n -0000316237 00000 n -0000316399 00000 n -0000316560 00000 n -0000316723 00000 n -0000316877 00000 n -0000323263 00000 n -0000320266 00000 n -0000317230 00000 n -0000323069 00000 n -0000320548 00000 n -0000320702 00000 n -0000320856 00000 n -0000321010 00000 n -0000321164 00000 n -0000321325 00000 n -0000321487 00000 n -0000321647 00000 n -0000321807 00000 n -0000321969 00000 n -0000322129 00000 n -0000322288 00000 n -0000322439 00000 n -0000322602 00000 n -0000322753 00000 n -0000322915 00000 n -0000326791 00000 n -0000326470 00000 n -0000323375 00000 n -0000326596 00000 n -0000326661 00000 n -0000326726 00000 n -0000331027 00000 n -0000329830 00000 n -0000326960 00000 n -0000330318 00000 n -0000330447 00000 n -0000330704 00000 n -0000329986 00000 n -0000330156 00000 n -0000330769 00000 n -0000330834 00000 n -0000330899 00000 n -0000330963 00000 n -0000713705 00000 n -0000334374 00000 n -0000334183 00000 n -0000331209 00000 n -0000334309 00000 n -0000338114 00000 n -0000337793 00000 n -0000334460 00000 n -0000337919 00000 n -0000337984 00000 n -0000338049 00000 n -0000341943 00000 n -0000341236 00000 n -0000338226 00000 n -0000341362 00000 n -0000341491 00000 n -0000341554 00000 n -0000341619 00000 n -0000341684 00000 n -0000341749 00000 n -0000341878 00000 n -0000345707 00000 n -0000344868 00000 n -0000342055 00000 n -0000344994 00000 n -0000345059 00000 n -0000345124 00000 n -0000345253 00000 n -0000345318 00000 n -0000345383 00000 n -0000345512 00000 n -0000345577 00000 n -0000345642 00000 n -0000348826 00000 n -0000348121 00000 n -0000345832 00000 n -0000348247 00000 n -0000348375 00000 n -0000348504 00000 n -0000348633 00000 n -0000348762 00000 n -0000352603 00000 n -0000352153 00000 n -0000349023 00000 n -0000352279 00000 n -0000352408 00000 n -0000352473 00000 n -0000352538 00000 n -0000713830 00000 n -0000356782 00000 n -0000356024 00000 n -0000352742 00000 n -0000356329 00000 n -0000356587 00000 n -0000356652 00000 n -0000356717 00000 n -0000356171 00000 n -0000360343 00000 n -0000359635 00000 n -0000356907 00000 n -0000359761 00000 n -0000360019 00000 n -0000360148 00000 n -0000360213 00000 n -0000360278 00000 n -0000363634 00000 n -0000362992 00000 n -0000360455 00000 n +0000015080 00000 n +0000384472 00000 n +0000730955 00000 n +0000015129 00000 n +0000015176 00000 n +0000388739 00000 n +0000730822 00000 n +0000015223 00000 n +0000015260 00000 n +0000388868 00000 n +0000730704 00000 n +0000015309 00000 n +0000015348 00000 n +0000388997 00000 n +0000730639 00000 n +0000015402 00000 n +0000015480 00000 n +0000389126 00000 n +0000730546 00000 n +0000015529 00000 n +0000015596 00000 n +0000389255 00000 n +0000730467 00000 n +0000015645 00000 n +0000015690 00000 n +0000392694 00000 n +0000730334 00000 n +0000015738 00000 n +0000015770 00000 n +0000392823 00000 n +0000730216 00000 n +0000015819 00000 n +0000015858 00000 n +0000392952 00000 n +0000730151 00000 n +0000015912 00000 n +0000015973 00000 n +0000396633 00000 n +0000730019 00000 n +0000016022 00000 n +0000016079 00000 n +0000396762 00000 n +0000729954 00000 n +0000016133 00000 n +0000016182 00000 n +0000396891 00000 n +0000729836 00000 n +0000016231 00000 n +0000016293 00000 n +0000397020 00000 n +0000729757 00000 n +0000016347 00000 n +0000016402 00000 n +0000421042 00000 n +0000729664 00000 n +0000016456 00000 n +0000016497 00000 n +0000421171 00000 n +0000729585 00000 n +0000016551 00000 n +0000016603 00000 n +0000423902 00000 n +0000729465 00000 n +0000016651 00000 n +0000016685 00000 n +0000424031 00000 n +0000729386 00000 n +0000016734 00000 n +0000016761 00000 n +0000441854 00000 n +0000729293 00000 n +0000016810 00000 n +0000016838 00000 n +0000449343 00000 n +0000729200 00000 n +0000016887 00000 n +0000016927 00000 n +0000452138 00000 n +0000729107 00000 n +0000016976 00000 n +0000017019 00000 n +0000458062 00000 n +0000729014 00000 n +0000017068 00000 n +0000017105 00000 n +0000464564 00000 n +0000728921 00000 n +0000017154 00000 n +0000017193 00000 n +0000476717 00000 n +0000728828 00000 n +0000017242 00000 n +0000017281 00000 n +0000480140 00000 n +0000728735 00000 n +0000017330 00000 n +0000017369 00000 n +0000486583 00000 n +0000728642 00000 n +0000017418 00000 n +0000017447 00000 n +0000496757 00000 n +0000728549 00000 n +0000017497 00000 n +0000017530 00000 n +0000506693 00000 n +0000728456 00000 n +0000017580 00000 n +0000017609 00000 n +0000513987 00000 n +0000728363 00000 n +0000017659 00000 n +0000017693 00000 n +0000519675 00000 n +0000728284 00000 n +0000017743 00000 n +0000017780 00000 n +0000018149 00000 n +0000018271 00000 n +0000026100 00000 n +0000017833 00000 n +0000025974 00000 n +0000026037 00000 n +0000723763 00000 n +0000697820 00000 n +0000723589 00000 n +0000724788 00000 n +0000021134 00000 n +0000021351 00000 n +0000021420 00000 n +0000021489 00000 n +0000021557 00000 n +0000021625 00000 n +0000021674 00000 n +0000021721 00000 n +0000022054 00000 n +0000022076 00000 n +0000022244 00000 n +0000022409 00000 n +0000022578 00000 n +0000022757 00000 n +0000023066 00000 n +0000023226 00000 n +0000027466 00000 n +0000027281 00000 n +0000026200 00000 n +0000027403 00000 n +0000696599 00000 n +0000670078 00000 n +0000696425 00000 n +0000669393 00000 n +0000667249 00000 n +0000669229 00000 n +0000039173 00000 n +0000030522 00000 n +0000027551 00000 n +0000039047 00000 n +0000039110 00000 n +0000031056 00000 n +0000031210 00000 n +0000031367 00000 n +0000031524 00000 n +0000031680 00000 n +0000031837 00000 n +0000031999 00000 n +0000032160 00000 n +0000032321 00000 n +0000032483 00000 n +0000032650 00000 n +0000032817 00000 n +0000032982 00000 n +0000033144 00000 n +0000033310 00000 n +0000033471 00000 n +0000033626 00000 n +0000033783 00000 n +0000033939 00000 n +0000034096 00000 n +0000034253 00000 n +0000034410 00000 n +0000034564 00000 n +0000034720 00000 n +0000034882 00000 n +0000035044 00000 n +0000035200 00000 n +0000035357 00000 n +0000035519 00000 n +0000035686 00000 n +0000035852 00000 n +0000036013 00000 n +0000036168 00000 n +0000036325 00000 n +0000036482 00000 n +0000036644 00000 n +0000036801 00000 n +0000036958 00000 n +0000037120 00000 n +0000037277 00000 n +0000037439 00000 n +0000037606 00000 n +0000037772 00000 n +0000037934 00000 n +0000038096 00000 n +0000038258 00000 n +0000038420 00000 n +0000038582 00000 n +0000038737 00000 n +0000038892 00000 n +0000052547 00000 n +0000042497 00000 n +0000039258 00000 n +0000052484 00000 n +0000666698 00000 n +0000649617 00000 n +0000666514 00000 n +0000043087 00000 n +0000043250 00000 n +0000043412 00000 n +0000043575 00000 n +0000043733 00000 n +0000043896 00000 n +0000044059 00000 n +0000044214 00000 n +0000044372 00000 n +0000044530 00000 n +0000044686 00000 n +0000044844 00000 n +0000045007 00000 n +0000045175 00000 n +0000045343 00000 n +0000045506 00000 n +0000045674 00000 n +0000045842 00000 n +0000046000 00000 n +0000046163 00000 n +0000046326 00000 n +0000046488 00000 n +0000046650 00000 n +0000046813 00000 n +0000046975 00000 n +0000047137 00000 n +0000047300 00000 n +0000047463 00000 n +0000047626 00000 n +0000047795 00000 n +0000047964 00000 n +0000048133 00000 n +0000048296 00000 n +0000048460 00000 n +0000048624 00000 n +0000048787 00000 n +0000048951 00000 n +0000049115 00000 n +0000049283 00000 n +0000049452 00000 n +0000049621 00000 n +0000049790 00000 n +0000049959 00000 n +0000050128 00000 n +0000050297 00000 n +0000050466 00000 n +0000050635 00000 n +0000050805 00000 n +0000050975 00000 n +0000051145 00000 n +0000051315 00000 n +0000051485 00000 n +0000051655 00000 n +0000051824 00000 n +0000051994 00000 n +0000052161 00000 n +0000052322 00000 n +0000065709 00000 n +0000056176 00000 n +0000052645 00000 n +0000065646 00000 n +0000056750 00000 n +0000056913 00000 n +0000057076 00000 n +0000057239 00000 n +0000057402 00000 n +0000057565 00000 n +0000057728 00000 n +0000057890 00000 n +0000058051 00000 n +0000058218 00000 n +0000058386 00000 n +0000058554 00000 n +0000058722 00000 n +0000058879 00000 n +0000059039 00000 n +0000059205 00000 n +0000059372 00000 n +0000059534 00000 n +0000059696 00000 n +0000059858 00000 n +0000060019 00000 n +0000060185 00000 n +0000060352 00000 n +0000060519 00000 n +0000060681 00000 n +0000060843 00000 n +0000061000 00000 n +0000061167 00000 n +0000061329 00000 n +0000061496 00000 n +0000061663 00000 n +0000061830 00000 n +0000648728 00000 n +0000627397 00000 n +0000648554 00000 n +0000061997 00000 n +0000062164 00000 n +0000062318 00000 n +0000062475 00000 n +0000062632 00000 n +0000062794 00000 n +0000062956 00000 n +0000063113 00000 n +0000063268 00000 n +0000063425 00000 n +0000063587 00000 n +0000063744 00000 n +0000063901 00000 n +0000064057 00000 n +0000064214 00000 n +0000064376 00000 n +0000064533 00000 n +0000064695 00000 n +0000064852 00000 n +0000065014 00000 n +0000065176 00000 n +0000065337 00000 n +0000065491 00000 n +0000068921 00000 n +0000066744 00000 n +0000065820 00000 n +0000068858 00000 n +0000066974 00000 n +0000067131 00000 n +0000067288 00000 n +0000067444 00000 n +0000067601 00000 n +0000067758 00000 n +0000067915 00000 n +0000068072 00000 n +0000068229 00000 n +0000068385 00000 n +0000626431 00000 n +0000606464 00000 n +0000626258 00000 n +0000068543 00000 n +0000068700 00000 n +0000072084 00000 n +0000071274 00000 n +0000069019 00000 n +0000071396 00000 n +0000071520 00000 n +0000071645 00000 n +0000071770 00000 n +0000071895 00000 n +0000071958 00000 n +0000072021 00000 n +0000605670 00000 n +0000587353 00000 n +0000605497 00000 n +0000724906 00000 n +0000076655 00000 n +0000075475 00000 n +0000072208 00000 n +0000075969 00000 n +0000076032 00000 n +0000076095 00000 n +0000076219 00000 n +0000076344 00000 n +0000076469 00000 n +0000075625 00000 n +0000075818 00000 n +0000076592 00000 n +0000337590 00000 n +0000397084 00000 n +0000081310 00000 n +0000080274 00000 n +0000076779 00000 n +0000080747 00000 n +0000080872 00000 n +0000080424 00000 n +0000080586 00000 n +0000080997 00000 n +0000081122 00000 n +0000081247 00000 n +0000097234 00000 n +0000084532 00000 n +0000083972 00000 n +0000081434 00000 n +0000084094 00000 n +0000084219 00000 n +0000084344 00000 n +0000084469 00000 n +0000087959 00000 n +0000086818 00000 n +0000084643 00000 n +0000087272 00000 n +0000087397 00000 n +0000087522 00000 n +0000087647 00000 n +0000087772 00000 n +0000086968 00000 n +0000087120 00000 n +0000087896 00000 n +0000287301 00000 n +0000089040 00000 n +0000088729 00000 n +0000088044 00000 n +0000088851 00000 n +0000088976 00000 n +0000091137 00000 n +0000090434 00000 n +0000089138 00000 n +0000090560 00000 n +0000090688 00000 n +0000090815 00000 n +0000090943 00000 n +0000091072 00000 n +0000725024 00000 n +0000094066 00000 n +0000093177 00000 n +0000091236 00000 n +0000093485 00000 n +0000093614 00000 n +0000093679 00000 n +0000093744 00000 n +0000093324 00000 n +0000093873 00000 n +0000094002 00000 n +0000271243 00000 n +0000097427 00000 n +0000096979 00000 n +0000094178 00000 n +0000097105 00000 n +0000586678 00000 n +0000574689 00000 n +0000586499 00000 n +0000097362 00000 n +0000101249 00000 n +0000101058 00000 n +0000097553 00000 n +0000101184 00000 n +0000574148 00000 n +0000564404 00000 n +0000573969 00000 n +0000105860 00000 n +0000105461 00000 n +0000101415 00000 n +0000105795 00000 n +0000105608 00000 n +0000172253 00000 n +0000108206 00000 n +0000107756 00000 n +0000105999 00000 n +0000107882 00000 n +0000108011 00000 n +0000108076 00000 n +0000108141 00000 n +0000110935 00000 n +0000113482 00000 n +0000110779 00000 n +0000108331 00000 n +0000112901 00000 n +0000113030 00000 n +0000113159 00000 n +0000112578 00000 n +0000112740 00000 n +0000563534 00000 n +0000554114 00000 n +0000563360 00000 n +0000553550 00000 n +0000544464 00000 n +0000553375 00000 n +0000113288 00000 n +0000113417 00000 n +0000725149 00000 n +0000112407 00000 n +0000112465 00000 n +0000112555 00000 n +0000212434 00000 n +0000248146 00000 n +0000118002 00000 n +0000117067 00000 n +0000113638 00000 n +0000117550 00000 n +0000117679 00000 n +0000117223 00000 n +0000117388 00000 n +0000117808 00000 n +0000117937 00000 n +0000401111 00000 n +0000121616 00000 n +0000121236 00000 n +0000118154 00000 n +0000121551 00000 n +0000121383 00000 n +0000122866 00000 n +0000122675 00000 n +0000121741 00000 n +0000122801 00000 n +0000125569 00000 n +0000124992 00000 n +0000122965 00000 n +0000125118 00000 n +0000125247 00000 n +0000125376 00000 n +0000125505 00000 n +0000128809 00000 n +0000128102 00000 n +0000125707 00000 n +0000128228 00000 n +0000128357 00000 n +0000128486 00000 n +0000128615 00000 n +0000128744 00000 n +0000133116 00000 n +0000132218 00000 n +0000128934 00000 n +0000132536 00000 n +0000132665 00000 n +0000132365 00000 n +0000132794 00000 n +0000132923 00000 n +0000133051 00000 n +0000725274 00000 n +0000330221 00000 n +0000137152 00000 n +0000136574 00000 n +0000133241 00000 n +0000136700 00000 n +0000136829 00000 n +0000136958 00000 n +0000137087 00000 n +0000140613 00000 n +0000140293 00000 n +0000137290 00000 n +0000140419 00000 n +0000140548 00000 n +0000143945 00000 n +0000143186 00000 n +0000140725 00000 n +0000143494 00000 n +0000143623 00000 n +0000143333 00000 n +0000143752 00000 n +0000143880 00000 n +0000396826 00000 n +0000146685 00000 n +0000146107 00000 n +0000144113 00000 n +0000146233 00000 n +0000146362 00000 n +0000146491 00000 n +0000146620 00000 n +0000147125 00000 n +0000146934 00000 n +0000146784 00000 n +0000147060 00000 n +0000151127 00000 n +0000150361 00000 n +0000147167 00000 n +0000150675 00000 n +0000150804 00000 n +0000150932 00000 n +0000150997 00000 n +0000151062 00000 n +0000150508 00000 n +0000725399 00000 n +0000155623 00000 n +0000155815 00000 n +0000155368 00000 n +0000151226 00000 n +0000155494 00000 n +0000155750 00000 n +0000159694 00000 n +0000159117 00000 n +0000155940 00000 n +0000159243 00000 n +0000159371 00000 n +0000159500 00000 n +0000159629 00000 n +0000162513 00000 n +0000163892 00000 n +0000162387 00000 n +0000159832 00000 n +0000163439 00000 n +0000163568 00000 n +0000163697 00000 n +0000163762 00000 n +0000163827 00000 n +0000166969 00000 n +0000166262 00000 n +0000164047 00000 n +0000166388 00000 n +0000166517 00000 n +0000166645 00000 n +0000166710 00000 n +0000166775 00000 n +0000166904 00000 n +0000172576 00000 n +0000171658 00000 n +0000167081 00000 n +0000172124 00000 n +0000171814 00000 n +0000171965 00000 n +0000172382 00000 n +0000172511 00000 n +0000523089 00000 n +0000176415 00000 n +0000175144 00000 n +0000172714 00000 n +0000175834 00000 n +0000175963 00000 n +0000176092 00000 n +0000175309 00000 n +0000175461 00000 n +0000175647 00000 n +0000176221 00000 n +0000176350 00000 n +0000725524 00000 n +0000180646 00000 n +0000180326 00000 n +0000176541 00000 n +0000180452 00000 n +0000180581 00000 n +0000184122 00000 n +0000183743 00000 n +0000180771 00000 n +0000184057 00000 n +0000183890 00000 n +0000187139 00000 n +0000187334 00000 n +0000186884 00000 n +0000184234 00000 n +0000187010 00000 n +0000187204 00000 n +0000187269 00000 n +0000190703 00000 n +0000190512 00000 n +0000187446 00000 n +0000190638 00000 n +0000195014 00000 n +0000194436 00000 n +0000190815 00000 n +0000194562 00000 n +0000194691 00000 n +0000194756 00000 n +0000194821 00000 n +0000194950 00000 n +0000198225 00000 n +0000197183 00000 n +0000195126 00000 n +0000197644 00000 n +0000197773 00000 n +0000197339 00000 n +0000197491 00000 n +0000197902 00000 n +0000198031 00000 n +0000198160 00000 n +0000725649 00000 n +0000199777 00000 n +0000199586 00000 n +0000198337 00000 n +0000199712 00000 n +0000201300 00000 n +0000201109 00000 n +0000199876 00000 n +0000201235 00000 n +0000204105 00000 n +0000203785 00000 n +0000201399 00000 n +0000203911 00000 n +0000204040 00000 n +0000208528 00000 n +0000208159 00000 n +0000204243 00000 n +0000208463 00000 n +0000208306 00000 n +0000366981 00000 n +0000212499 00000 n +0000212179 00000 n +0000208640 00000 n +0000212305 00000 n +0000216337 00000 n +0000216017 00000 n +0000212624 00000 n +0000216143 00000 n +0000216208 00000 n +0000216272 00000 n +0000725774 00000 n +0000221633 00000 n +0000220341 00000 n +0000216462 00000 n +0000221568 00000 n +0000220533 00000 n +0000220687 00000 n +0000220842 00000 n +0000221027 00000 n +0000221201 00000 n +0000221386 00000 n +0000290835 00000 n +0000225939 00000 n +0000225748 00000 n +0000221814 00000 n +0000225874 00000 n +0000229702 00000 n +0000229511 00000 n +0000226064 00000 n +0000229637 00000 n +0000234015 00000 n +0000233073 00000 n +0000229814 00000 n +0000233563 00000 n +0000233692 00000 n +0000233229 00000 n +0000233821 00000 n +0000233950 00000 n +0000233397 00000 n +0000304312 00000 n +0000237811 00000 n +0000237249 00000 n +0000234127 00000 n +0000237746 00000 n +0000237405 00000 n +0000237576 00000 n +0000384536 00000 n +0000241235 00000 n +0000240788 00000 n +0000237980 00000 n +0000240914 00000 n +0000241042 00000 n +0000241171 00000 n +0000725899 00000 n +0000244802 00000 n +0000244611 00000 n +0000241360 00000 n +0000244737 00000 n +0000248211 00000 n +0000247891 00000 n +0000244971 00000 n +0000248017 00000 n +0000251891 00000 n +0000251700 00000 n +0000248367 00000 n +0000251826 00000 n +0000256213 00000 n +0000255399 00000 n +0000252060 00000 n +0000255890 00000 n +0000256019 00000 n +0000255555 00000 n +0000256148 00000 n +0000255715 00000 n +0000260364 00000 n +0000259868 00000 n +0000256368 00000 n +0000260170 00000 n +0000260299 00000 n +0000260015 00000 n +0000264002 00000 n +0000263553 00000 n +0000260489 00000 n +0000263679 00000 n +0000263808 00000 n +0000263937 00000 n +0000726024 00000 n +0000267909 00000 n +0000267242 00000 n +0000264157 00000 n +0000267715 00000 n +0000267844 00000 n +0000267398 00000 n +0000267560 00000 n +0000271438 00000 n +0000270798 00000 n +0000268078 00000 n +0000271114 00000 n +0000270945 00000 n +0000271308 00000 n +0000271373 00000 n +0000275474 00000 n +0000274971 00000 n +0000271621 00000 n +0000275280 00000 n +0000275409 00000 n +0000275118 00000 n +0000280264 00000 n +0000279585 00000 n +0000275642 00000 n +0000280070 00000 n +0000279741 00000 n +0000544109 00000 n +0000542110 00000 n +0000543944 00000 n +0000280199 00000 n +0000279902 00000 n +0000363552 00000 n +0000299250 00000 n +0000283673 00000 n +0000283353 00000 n +0000280390 00000 n +0000283479 00000 n +0000283608 00000 n +0000287365 00000 n +0000287046 00000 n +0000283798 00000 n +0000287172 00000 n +0000726149 00000 n +0000290900 00000 n +0000290451 00000 n +0000287507 00000 n +0000290577 00000 n +0000290706 00000 n +0000295399 00000 n +0000294607 00000 n +0000291012 00000 n +0000295077 00000 n +0000294763 00000 n +0000294915 00000 n +0000295206 00000 n +0000295335 00000 n +0000299315 00000 n +0000298562 00000 n +0000295511 00000 n +0000298863 00000 n +0000298992 00000 n +0000299121 00000 n +0000298709 00000 n +0000302758 00000 n +0000302438 00000 n +0000299427 00000 n +0000302564 00000 n +0000302693 00000 n +0000304377 00000 n +0000304057 00000 n +0000302870 00000 n +0000304183 00000 n +0000305902 00000 n +0000305711 00000 n +0000304489 00000 n +0000305837 00000 n +0000726274 00000 n +0000308815 00000 n +0000308236 00000 n +0000306001 00000 n +0000308362 00000 n +0000308491 00000 n +0000308620 00000 n +0000308685 00000 n +0000308750 00000 n +0000313010 00000 n +0000312501 00000 n +0000308927 00000 n +0000312816 00000 n +0000312648 00000 n +0000312945 00000 n +0000523056 00000 n +0000318900 00000 n +0000316165 00000 n +0000313122 00000 n +0000318706 00000 n +0000318835 00000 n +0000316429 00000 n +0000316591 00000 n +0000316753 00000 n +0000316914 00000 n +0000317074 00000 n +0000317236 00000 n +0000317407 00000 n +0000317569 00000 n +0000317731 00000 n +0000317894 00000 n +0000318057 00000 n +0000318220 00000 n +0000318383 00000 n +0000318546 00000 n +0000324121 00000 n +0000322204 00000 n +0000319012 00000 n +0000324056 00000 n +0000322432 00000 n +0000322595 00000 n +0000322762 00000 n +0000322931 00000 n +0000323093 00000 n +0000323254 00000 n +0000323416 00000 n +0000323577 00000 n +0000323740 00000 n +0000323893 00000 n +0000330286 00000 n +0000327279 00000 n +0000324246 00000 n +0000330092 00000 n +0000327561 00000 n +0000327714 00000 n +0000327868 00000 n +0000328019 00000 n +0000328173 00000 n +0000328334 00000 n +0000328496 00000 n +0000328658 00000 n +0000328820 00000 n +0000328982 00000 n +0000329144 00000 n +0000329306 00000 n +0000329458 00000 n +0000329621 00000 n +0000329776 00000 n +0000329938 00000 n +0000333816 00000 n +0000333495 00000 n +0000330398 00000 n +0000333621 00000 n +0000333686 00000 n +0000333751 00000 n +0000726399 00000 n +0000338041 00000 n +0000336845 00000 n +0000333985 00000 n +0000337332 00000 n +0000337461 00000 n +0000337718 00000 n +0000337001 00000 n +0000337171 00000 n +0000337783 00000 n +0000337848 00000 n +0000337913 00000 n +0000337977 00000 n +0000341388 00000 n +0000341197 00000 n +0000338223 00000 n +0000341323 00000 n +0000345128 00000 n +0000344807 00000 n +0000341474 00000 n +0000344933 00000 n +0000344998 00000 n +0000345063 00000 n +0000348960 00000 n +0000348253 00000 n +0000345240 00000 n +0000348379 00000 n +0000348508 00000 n +0000348571 00000 n +0000348636 00000 n +0000348701 00000 n +0000348766 00000 n +0000348895 00000 n +0000352712 00000 n +0000351874 00000 n +0000349072 00000 n +0000352000 00000 n +0000352065 00000 n +0000352130 00000 n +0000352259 00000 n +0000352324 00000 n +0000352389 00000 n +0000352518 00000 n +0000352583 00000 n +0000352647 00000 n +0000355833 00000 n +0000355128 00000 n +0000352837 00000 n +0000355254 00000 n +0000355382 00000 n +0000355511 00000 n +0000355640 00000 n +0000355769 00000 n +0000726524 00000 n +0000359611 00000 n +0000359161 00000 n +0000356030 00000 n +0000359287 00000 n +0000359416 00000 n +0000359481 00000 n +0000359546 00000 n +0000363876 00000 n 0000363118 00000 n -0000363247 00000 n -0000363312 00000 n -0000363377 00000 n -0000363506 00000 n -0000363570 00000 n -0000366293 00000 n -0000365908 00000 n +0000359750 00000 n +0000363423 00000 n +0000363681 00000 n 0000363746 00000 n -0000366034 00000 n -0000366099 00000 n -0000529136 00000 n -0000521853 00000 n -0000528956 00000 n -0000366228 00000 n -0000366760 00000 n -0000366569 00000 n -0000366419 00000 n -0000366695 00000 n -0000368655 00000 n -0000368207 00000 n -0000366802 00000 n -0000368333 00000 n -0000368462 00000 n -0000368591 00000 n -0000713955 00000 n -0000373228 00000 n -0000372285 00000 n -0000368767 00000 n -0000372648 00000 n -0000521532 00000 n -0000512319 00000 n -0000521346 00000 n -0000372432 00000 n -0000372777 00000 n -0000372905 00000 n -0000373034 00000 n -0000374270 00000 n -0000374079 00000 n -0000373465 00000 n -0000374205 00000 n -0000374697 00000 n -0000374506 00000 n -0000374356 00000 n -0000374632 00000 n -0000378010 00000 n -0000376784 00000 n -0000374739 00000 n -0000377301 00000 n -0000377430 00000 n -0000377559 00000 n -0000377688 00000 n -0000377817 00000 n -0000377946 00000 n -0000376940 00000 n -0000377112 00000 n -0000378464 00000 n -0000378273 00000 n -0000378123 00000 n -0000378399 00000 n -0000381708 00000 n -0000381130 00000 n -0000378506 00000 n -0000381256 00000 n -0000381385 00000 n -0000381514 00000 n -0000381643 00000 n -0000714080 00000 n -0000385987 00000 n -0000384768 00000 n -0000381794 00000 n -0000385279 00000 n -0000385408 00000 n -0000385666 00000 n -0000384924 00000 n -0000385103 00000 n -0000385859 00000 n -0000385923 00000 n -0000392873 00000 n -0000389045 00000 n -0000386140 00000 n -0000389171 00000 n -0000389236 00000 n -0000389301 00000 n -0000389366 00000 n -0000389431 00000 n +0000363811 00000 n +0000363265 00000 n +0000367434 00000 n +0000366726 00000 n +0000364001 00000 n +0000366852 00000 n +0000367110 00000 n +0000367239 00000 n +0000367304 00000 n +0000367369 00000 n +0000371121 00000 n +0000370487 00000 n +0000367546 00000 n +0000370799 00000 n +0000370634 00000 n +0000370928 00000 n +0000370992 00000 n +0000371056 00000 n +0000523023 00000 n +0000375100 00000 n +0000374394 00000 n +0000371233 00000 n +0000374520 00000 n +0000374648 00000 n +0000374713 00000 n +0000374778 00000 n +0000374907 00000 n +0000374972 00000 n +0000375036 00000 n +0000377643 00000 n +0000377323 00000 n +0000375226 00000 n +0000377449 00000 n +0000541829 00000 n +0000534545 00000 n +0000541649 00000 n +0000377578 00000 n +0000726649 00000 n +0000378124 00000 n +0000377933 00000 n +0000377783 00000 n +0000378059 00000 n +0000380016 00000 n +0000379568 00000 n +0000378166 00000 n +0000379694 00000 n +0000379823 00000 n +0000379952 00000 n +0000384601 00000 n +0000383658 00000 n +0000380128 00000 n +0000384021 00000 n +0000534224 00000 n +0000525011 00000 n +0000534038 00000 n +0000383805 00000 n +0000384150 00000 n +0000384278 00000 n +0000384407 00000 n +0000385643 00000 n +0000385452 00000 n +0000384838 00000 n +0000385578 00000 n +0000386070 00000 n +0000385879 00000 n +0000385729 00000 n +0000386005 00000 n +0000389383 00000 n +0000388157 00000 n +0000386112 00000 n +0000388674 00000 n +0000388803 00000 n +0000388932 00000 n +0000389061 00000 n +0000389190 00000 n +0000389319 00000 n +0000388313 00000 n +0000388485 00000 n +0000726774 00000 n +0000389837 00000 n +0000389646 00000 n 0000389496 00000 n -0000389561 00000 n -0000389626 00000 n -0000389691 00000 n -0000389756 00000 n -0000389886 00000 n -0000389951 00000 n -0000390016 00000 n -0000390081 00000 n -0000390146 00000 n -0000390211 00000 n -0000390276 00000 n -0000390341 00000 n -0000390406 00000 n -0000390471 00000 n -0000390536 00000 n -0000390601 00000 n -0000390666 00000 n -0000390731 00000 n -0000390796 00000 n -0000390861 00000 n -0000390926 00000 n -0000390991 00000 n -0000391056 00000 n -0000391121 00000 n -0000391186 00000 n -0000391251 00000 n -0000391316 00000 n -0000391381 00000 n -0000391445 00000 n -0000391510 00000 n -0000391575 00000 n -0000391640 00000 n -0000391705 00000 n -0000391770 00000 n -0000391835 00000 n -0000391900 00000 n -0000391965 00000 n -0000392030 00000 n -0000392095 00000 n -0000392160 00000 n -0000392225 00000 n -0000392290 00000 n -0000392355 00000 n -0000392420 00000 n -0000392485 00000 n -0000392550 00000 n -0000392615 00000 n -0000392680 00000 n -0000392745 00000 n -0000392809 00000 n -0000399519 00000 n -0000395955 00000 n -0000392985 00000 n -0000396081 00000 n -0000396146 00000 n -0000396211 00000 n -0000396276 00000 n -0000396341 00000 n -0000396406 00000 n -0000396471 00000 n -0000396536 00000 n -0000396601 00000 n -0000396666 00000 n -0000396731 00000 n -0000396796 00000 n -0000396860 00000 n -0000396925 00000 n -0000396990 00000 n -0000397055 00000 n -0000397120 00000 n -0000397185 00000 n -0000397250 00000 n -0000397315 00000 n -0000397380 00000 n -0000397445 00000 n -0000397510 00000 n -0000397575 00000 n -0000397639 00000 n -0000397704 00000 n -0000397769 00000 n -0000397834 00000 n -0000397899 00000 n -0000397964 00000 n -0000398029 00000 n -0000398094 00000 n -0000398159 00000 n -0000398224 00000 n -0000398289 00000 n -0000398354 00000 n -0000398419 00000 n -0000398484 00000 n -0000398549 00000 n -0000398614 00000 n -0000398678 00000 n -0000398742 00000 n -0000398806 00000 n -0000398871 00000 n -0000398936 00000 n -0000399001 00000 n -0000399066 00000 n -0000399131 00000 n -0000399196 00000 n -0000399261 00000 n -0000399326 00000 n -0000399391 00000 n -0000399455 00000 n -0000405692 00000 n -0000402254 00000 n -0000399631 00000 n -0000402380 00000 n -0000402445 00000 n -0000402510 00000 n -0000402575 00000 n -0000402640 00000 n -0000402705 00000 n -0000402770 00000 n -0000402835 00000 n -0000402900 00000 n -0000402965 00000 n -0000403030 00000 n -0000403095 00000 n -0000403160 00000 n -0000403225 00000 n -0000403290 00000 n -0000403355 00000 n -0000403420 00000 n -0000403485 00000 n -0000403550 00000 n -0000403615 00000 n -0000403680 00000 n -0000403745 00000 n -0000403810 00000 n -0000403875 00000 n -0000403940 00000 n -0000404005 00000 n -0000404070 00000 n -0000404135 00000 n -0000404200 00000 n -0000404265 00000 n -0000404330 00000 n -0000404395 00000 n -0000404460 00000 n -0000404525 00000 n -0000404589 00000 n -0000404654 00000 n -0000404719 00000 n -0000404784 00000 n -0000404849 00000 n -0000404914 00000 n -0000404979 00000 n -0000405044 00000 n -0000405109 00000 n -0000405174 00000 n -0000405239 00000 n -0000405304 00000 n -0000405369 00000 n -0000405434 00000 n -0000405499 00000 n -0000405564 00000 n -0000405628 00000 n -0000410270 00000 n -0000408006 00000 n -0000405804 00000 n -0000408132 00000 n -0000408197 00000 n -0000408262 00000 n -0000408327 00000 n -0000408392 00000 n -0000408457 00000 n -0000408522 00000 n -0000408587 00000 n -0000408652 00000 n -0000408717 00000 n -0000408782 00000 n -0000408847 00000 n -0000408912 00000 n -0000408977 00000 n -0000409039 00000 n -0000409103 00000 n -0000409168 00000 n -0000409232 00000 n -0000409297 00000 n -0000409362 00000 n -0000409427 00000 n -0000409492 00000 n -0000409557 00000 n -0000409622 00000 n -0000409687 00000 n -0000409816 00000 n -0000409945 00000 n -0000410010 00000 n -0000410075 00000 n -0000410140 00000 n -0000410205 00000 n -0000413065 00000 n -0000412421 00000 n -0000410395 00000 n -0000412547 00000 n -0000412676 00000 n -0000412805 00000 n -0000412870 00000 n -0000412935 00000 n -0000413000 00000 n -0000714205 00000 n -0000417403 00000 n -0000417083 00000 n -0000413178 00000 n -0000417209 00000 n -0000417274 00000 n -0000417339 00000 n -0000420874 00000 n -0000420618 00000 n -0000417556 00000 n -0000420744 00000 n -0000420809 00000 n -0000424122 00000 n -0000423931 00000 n -0000421013 00000 n -0000424057 00000 n -0000427851 00000 n -0000427595 00000 n -0000424248 00000 n -0000427721 00000 n -0000427786 00000 n -0000430691 00000 n -0000429983 00000 n -0000427990 00000 n -0000430109 00000 n -0000430174 00000 n -0000430239 00000 n -0000430304 00000 n -0000430369 00000 n -0000430498 00000 n -0000430563 00000 n -0000430627 00000 n -0000435364 00000 n -0000435108 00000 n -0000430830 00000 n -0000435234 00000 n -0000435299 00000 n -0000714330 00000 n -0000438315 00000 n -0000437542 00000 n -0000435490 00000 n -0000437668 00000 n -0000437733 00000 n -0000437798 00000 n -0000437863 00000 n -0000437992 00000 n -0000438057 00000 n -0000438120 00000 n -0000438185 00000 n -0000438250 00000 n -0000440916 00000 n -0000440207 00000 n -0000438468 00000 n -0000440333 00000 n -0000440398 00000 n -0000440463 00000 n -0000440528 00000 n -0000440593 00000 n -0000440658 00000 n -0000440787 00000 n -0000440852 00000 n -0000443940 00000 n -0000443555 00000 n -0000441068 00000 n -0000443681 00000 n -0000443746 00000 n -0000443810 00000 n -0000443875 00000 n -0000447035 00000 n -0000446261 00000 n -0000444080 00000 n -0000446387 00000 n -0000446452 00000 n -0000446517 00000 n -0000446582 00000 n -0000446711 00000 n -0000446776 00000 n -0000446841 00000 n +0000389772 00000 n +0000393081 00000 n +0000392503 00000 n +0000389879 00000 n +0000392629 00000 n +0000392758 00000 n +0000392887 00000 n +0000393016 00000 n +0000397276 00000 n +0000396058 00000 n +0000393167 00000 n +0000396568 00000 n +0000396697 00000 n +0000396955 00000 n +0000396214 00000 n +0000396393 00000 n +0000397148 00000 n +0000397212 00000 n +0000404163 00000 n +0000400335 00000 n +0000397429 00000 n +0000400461 00000 n +0000400526 00000 n +0000400591 00000 n +0000400656 00000 n +0000400721 00000 n +0000400786 00000 n +0000400851 00000 n +0000400916 00000 n +0000400981 00000 n +0000401046 00000 n +0000401176 00000 n +0000401241 00000 n +0000401306 00000 n +0000401371 00000 n +0000401436 00000 n +0000401501 00000 n +0000401566 00000 n +0000401631 00000 n +0000401696 00000 n +0000401761 00000 n +0000401826 00000 n +0000401891 00000 n +0000401956 00000 n +0000402021 00000 n +0000402086 00000 n +0000402151 00000 n +0000402216 00000 n +0000402281 00000 n +0000402346 00000 n +0000402411 00000 n +0000402476 00000 n +0000402541 00000 n +0000402606 00000 n +0000402671 00000 n +0000402735 00000 n +0000402800 00000 n +0000402865 00000 n +0000402930 00000 n +0000402995 00000 n +0000403060 00000 n +0000403125 00000 n +0000403190 00000 n +0000403255 00000 n +0000403320 00000 n +0000403385 00000 n +0000403450 00000 n +0000403515 00000 n +0000403580 00000 n +0000403645 00000 n +0000403710 00000 n +0000403775 00000 n +0000403840 00000 n +0000403905 00000 n +0000403970 00000 n +0000404035 00000 n +0000404099 00000 n +0000410809 00000 n +0000407245 00000 n +0000404275 00000 n +0000407371 00000 n +0000407436 00000 n +0000407501 00000 n +0000407566 00000 n +0000407631 00000 n +0000407696 00000 n +0000407761 00000 n +0000407826 00000 n +0000407891 00000 n +0000407956 00000 n +0000408021 00000 n +0000408086 00000 n +0000408150 00000 n +0000408215 00000 n +0000408280 00000 n +0000408345 00000 n +0000408410 00000 n +0000408475 00000 n +0000408540 00000 n +0000408605 00000 n +0000408670 00000 n +0000408735 00000 n +0000408800 00000 n +0000408865 00000 n +0000408929 00000 n +0000408994 00000 n +0000409059 00000 n +0000409124 00000 n +0000409189 00000 n +0000409254 00000 n +0000409319 00000 n +0000409384 00000 n +0000409449 00000 n +0000409514 00000 n +0000409579 00000 n +0000409644 00000 n +0000409709 00000 n +0000409774 00000 n +0000409839 00000 n +0000409904 00000 n +0000409968 00000 n +0000410032 00000 n +0000410096 00000 n +0000410161 00000 n +0000410226 00000 n +0000410291 00000 n +0000410356 00000 n +0000410421 00000 n +0000410486 00000 n +0000410551 00000 n +0000410616 00000 n +0000410681 00000 n +0000410745 00000 n +0000416982 00000 n +0000413544 00000 n +0000410921 00000 n +0000413670 00000 n +0000413735 00000 n +0000413800 00000 n +0000413865 00000 n +0000413930 00000 n +0000413995 00000 n +0000414060 00000 n +0000414125 00000 n +0000414190 00000 n +0000414255 00000 n +0000414320 00000 n +0000414385 00000 n +0000414450 00000 n +0000414515 00000 n +0000414580 00000 n +0000414645 00000 n +0000414710 00000 n +0000414775 00000 n +0000414840 00000 n +0000414905 00000 n +0000414970 00000 n +0000415035 00000 n +0000415100 00000 n +0000415165 00000 n +0000415230 00000 n +0000415295 00000 n +0000415360 00000 n +0000415425 00000 n +0000415490 00000 n +0000415555 00000 n +0000415620 00000 n +0000415685 00000 n +0000415750 00000 n +0000415815 00000 n +0000415879 00000 n +0000415944 00000 n +0000416009 00000 n +0000416074 00000 n +0000416139 00000 n +0000416204 00000 n +0000416269 00000 n +0000416334 00000 n +0000416399 00000 n +0000416464 00000 n +0000416529 00000 n +0000416594 00000 n +0000416659 00000 n +0000416724 00000 n +0000416789 00000 n +0000416854 00000 n +0000416918 00000 n +0000726899 00000 n +0000421560 00000 n +0000419296 00000 n +0000417094 00000 n +0000419422 00000 n +0000419487 00000 n +0000419552 00000 n +0000419617 00000 n +0000419682 00000 n +0000419747 00000 n +0000419812 00000 n +0000419877 00000 n +0000419942 00000 n +0000420007 00000 n +0000420072 00000 n +0000420137 00000 n +0000420202 00000 n +0000420267 00000 n +0000420329 00000 n +0000420393 00000 n +0000420458 00000 n +0000420522 00000 n +0000420587 00000 n +0000420652 00000 n +0000420717 00000 n +0000420782 00000 n +0000420847 00000 n +0000420912 00000 n +0000420977 00000 n +0000421106 00000 n +0000421235 00000 n +0000421300 00000 n +0000421365 00000 n +0000421430 00000 n +0000421495 00000 n +0000424355 00000 n +0000423711 00000 n +0000421685 00000 n +0000423837 00000 n +0000423966 00000 n +0000424095 00000 n +0000424160 00000 n +0000424225 00000 n +0000424290 00000 n +0000428694 00000 n +0000428374 00000 n +0000424468 00000 n +0000428500 00000 n +0000428565 00000 n +0000428630 00000 n +0000432294 00000 n +0000432039 00000 n +0000428847 00000 n +0000432165 00000 n +0000432230 00000 n +0000435543 00000 n +0000435352 00000 n +0000432433 00000 n +0000435478 00000 n +0000439271 00000 n +0000439015 00000 n +0000435669 00000 n +0000439141 00000 n +0000439206 00000 n +0000727024 00000 n +0000442111 00000 n +0000441403 00000 n +0000439410 00000 n +0000441529 00000 n +0000441594 00000 n +0000441659 00000 n +0000441724 00000 n +0000441789 00000 n +0000441918 00000 n +0000441983 00000 n +0000442047 00000 n +0000446779 00000 n +0000446523 00000 n +0000442250 00000 n +0000446649 00000 n +0000446714 00000 n +0000449730 00000 n +0000448957 00000 n 0000446905 00000 n -0000446970 00000 n -0000450308 00000 n -0000450117 00000 n -0000447201 00000 n -0000450243 00000 n -0000453409 00000 n -0000452699 00000 n -0000450434 00000 n -0000452825 00000 n -0000452890 00000 n -0000452955 00000 n -0000453020 00000 n -0000453085 00000 n -0000453214 00000 n -0000453279 00000 n -0000453344 00000 n -0000714455 00000 n -0000457067 00000 n -0000456748 00000 n -0000453574 00000 n -0000456874 00000 n -0000456939 00000 n -0000457003 00000 n -0000460443 00000 n -0000460252 00000 n -0000457193 00000 n -0000460378 00000 n -0000463120 00000 n -0000462477 00000 n -0000460583 00000 n -0000462603 00000 n -0000462668 00000 n -0000462732 00000 n -0000462797 00000 n -0000462926 00000 n -0000462991 00000 n -0000463056 00000 n -0000465837 00000 n -0000465063 00000 n -0000463272 00000 n -0000465189 00000 n -0000465254 00000 n -0000465318 00000 n -0000465383 00000 n -0000465448 00000 n -0000465513 00000 n -0000465642 00000 n -0000465707 00000 n -0000465772 00000 n -0000469228 00000 n -0000468907 00000 n -0000465990 00000 n -0000469033 00000 n -0000469098 00000 n -0000469163 00000 n -0000472297 00000 n -0000471912 00000 n -0000469341 00000 n -0000472038 00000 n -0000472103 00000 n -0000472168 00000 n -0000472233 00000 n -0000714580 00000 n -0000475693 00000 n -0000475114 00000 n -0000472436 00000 n -0000475240 00000 n -0000475369 00000 n -0000475434 00000 n -0000475499 00000 n -0000475564 00000 n -0000475629 00000 n -0000478674 00000 n -0000478483 00000 n -0000475833 00000 n -0000478609 00000 n -0000481314 00000 n -0000480605 00000 n -0000478885 00000 n -0000480731 00000 n -0000480796 00000 n -0000480861 00000 n -0000480926 00000 n -0000480991 00000 n -0000481056 00000 n -0000481185 00000 n -0000481250 00000 n -0000485767 00000 n -0000485446 00000 n -0000481510 00000 n -0000485572 00000 n -0000485637 00000 n -0000485702 00000 n -0000489361 00000 n -0000489106 00000 n -0000485893 00000 n -0000489232 00000 n -0000489297 00000 n -0000492296 00000 n -0000492040 00000 n -0000489487 00000 n -0000492166 00000 n -0000492231 00000 n -0000714705 00000 n -0000495466 00000 n -0000494691 00000 n -0000492422 00000 n -0000494817 00000 n -0000494882 00000 n -0000494947 00000 n -0000495012 00000 n -0000495141 00000 n -0000495206 00000 n -0000495271 00000 n -0000495336 00000 n -0000495401 00000 n -0000498834 00000 n -0000498190 00000 n -0000495632 00000 n -0000498316 00000 n -0000498381 00000 n -0000498446 00000 n -0000498511 00000 n -0000498640 00000 n -0000498705 00000 n -0000498770 00000 n -0000502306 00000 n -0000501985 00000 n -0000499000 00000 n -0000502111 00000 n -0000502176 00000 n -0000502241 00000 n -0000504879 00000 n -0000504301 00000 n -0000502432 00000 n -0000504427 00000 n -0000504492 00000 n -0000504557 00000 n -0000504622 00000 n -0000504751 00000 n -0000504815 00000 n -0000508675 00000 n -0000508290 00000 n -0000505017 00000 n -0000508416 00000 n -0000508481 00000 n -0000508546 00000 n -0000508611 00000 n -0000510245 00000 n -0000509861 00000 n -0000508815 00000 n -0000509987 00000 n -0000510052 00000 n -0000510115 00000 n -0000510180 00000 n -0000714830 00000 n -0000510430 00000 n -0000521774 00000 n -0000529362 00000 n -0000531661 00000 n -0000531630 00000 n -0000541154 00000 n -0000551267 00000 n -0000561743 00000 n -0000574367 00000 n -0000593432 00000 n -0000614319 00000 n -0000636463 00000 n -0000654358 00000 n -0000657188 00000 n -0000656958 00000 n -0000684495 00000 n -0000711606 00000 n -0000714910 00000 n -0000715033 00000 n -0000715159 00000 n -0000715285 00000 n -0000715402 00000 n -0000715494 00000 n -0000731830 00000 n -0000750703 00000 n -0000750744 00000 n -0000750784 00000 n -0000750918 00000 n +0000449083 00000 n +0000449148 00000 n +0000449213 00000 n +0000449278 00000 n +0000449407 00000 n +0000449472 00000 n +0000449535 00000 n +0000449600 00000 n +0000449665 00000 n +0000452331 00000 n +0000451622 00000 n +0000449883 00000 n +0000451748 00000 n +0000451813 00000 n +0000451878 00000 n +0000451943 00000 n +0000452008 00000 n +0000452073 00000 n +0000452202 00000 n +0000452267 00000 n +0000455355 00000 n +0000454970 00000 n +0000452483 00000 n +0000455096 00000 n +0000455161 00000 n +0000455225 00000 n +0000455290 00000 n +0000458450 00000 n +0000457676 00000 n +0000455495 00000 n +0000457802 00000 n +0000457867 00000 n +0000457932 00000 n +0000457997 00000 n +0000458126 00000 n +0000458191 00000 n +0000458256 00000 n +0000458320 00000 n +0000458385 00000 n +0000727149 00000 n +0000461723 00000 n +0000461532 00000 n +0000458616 00000 n +0000461658 00000 n +0000464823 00000 n +0000464113 00000 n +0000461849 00000 n +0000464239 00000 n +0000464304 00000 n +0000464369 00000 n +0000464434 00000 n +0000464499 00000 n +0000464628 00000 n +0000464693 00000 n +0000464758 00000 n +0000468481 00000 n +0000468162 00000 n +0000464988 00000 n +0000468288 00000 n +0000468353 00000 n +0000468417 00000 n +0000471857 00000 n +0000471666 00000 n +0000468607 00000 n +0000471792 00000 n +0000474868 00000 n +0000474418 00000 n +0000471997 00000 n +0000474544 00000 n +0000474609 00000 n +0000474674 00000 n +0000474739 00000 n +0000474804 00000 n +0000477300 00000 n +0000476526 00000 n +0000475006 00000 n +0000476652 00000 n +0000476781 00000 n +0000476846 00000 n +0000476911 00000 n +0000476976 00000 n +0000477041 00000 n +0000477106 00000 n +0000477171 00000 n +0000477236 00000 n +0000727274 00000 n +0000480529 00000 n +0000479949 00000 n +0000477453 00000 n +0000480075 00000 n +0000480204 00000 n +0000480269 00000 n +0000480334 00000 n +0000480399 00000 n +0000480464 00000 n +0000483987 00000 n +0000483796 00000 n +0000480669 00000 n +0000483922 00000 n +0000486972 00000 n +0000486197 00000 n +0000484113 00000 n +0000486323 00000 n +0000486388 00000 n +0000486453 00000 n +0000486518 00000 n +0000486647 00000 n +0000486712 00000 n +0000486777 00000 n +0000486842 00000 n +0000486907 00000 n +0000490279 00000 n +0000490088 00000 n +0000487125 00000 n +0000490214 00000 n +0000493070 00000 n +0000492684 00000 n +0000490490 00000 n +0000492810 00000 n +0000492875 00000 n +0000492940 00000 n +0000493005 00000 n +0000497081 00000 n +0000496436 00000 n +0000493307 00000 n +0000496562 00000 n +0000496627 00000 n +0000496692 00000 n +0000496821 00000 n +0000496886 00000 n +0000496951 00000 n +0000497016 00000 n +0000727399 00000 n +0000501017 00000 n +0000500761 00000 n +0000497220 00000 n +0000500887 00000 n +0000500952 00000 n +0000504237 00000 n +0000503981 00000 n +0000501143 00000 n +0000504107 00000 n +0000504172 00000 n +0000506951 00000 n +0000506307 00000 n +0000504363 00000 n +0000506433 00000 n +0000506498 00000 n +0000506563 00000 n +0000506628 00000 n +0000506757 00000 n +0000506822 00000 n +0000506887 00000 n +0000510720 00000 n +0000510335 00000 n +0000507103 00000 n +0000510461 00000 n +0000510526 00000 n +0000510590 00000 n +0000510655 00000 n +0000514311 00000 n +0000513666 00000 n +0000510860 00000 n +0000513792 00000 n +0000513857 00000 n +0000513922 00000 n +0000514051 00000 n +0000514116 00000 n +0000514181 00000 n +0000514246 00000 n +0000516582 00000 n +0000516326 00000 n +0000514463 00000 n +0000516452 00000 n +0000516517 00000 n +0000727524 00000 n +0000520063 00000 n +0000519289 00000 n +0000516721 00000 n +0000519415 00000 n +0000519480 00000 n +0000519545 00000 n +0000519610 00000 n +0000519738 00000 n +0000519803 00000 n +0000519868 00000 n +0000519933 00000 n +0000519998 00000 n +0000522871 00000 n +0000522485 00000 n +0000520216 00000 n +0000522611 00000 n +0000522676 00000 n +0000522741 00000 n +0000522806 00000 n +0000523122 00000 n +0000534466 00000 n +0000542055 00000 n +0000544356 00000 n +0000544325 00000 n +0000553849 00000 n +0000563962 00000 n +0000574436 00000 n +0000587060 00000 n +0000606125 00000 n +0000627012 00000 n +0000649155 00000 n +0000667050 00000 n +0000669880 00000 n +0000669650 00000 n +0000697187 00000 n +0000724298 00000 n +0000727622 00000 n +0000727746 00000 n +0000727872 00000 n +0000727998 00000 n +0000728115 00000 n +0000728207 00000 n +0000744729 00000 n +0000763926 00000 n +0000763967 00000 n +0000764007 00000 n +0000764141 00000 n trailer << -/Size 2120 -/Root 2118 0 R -/Info 2119 0 R -/ID [ ] +/Size 2150 +/Root 2148 0 R +/Info 2149 0 R +/ID [ ] >> startxref -751176 +764399 %%EOF diff --git a/contrib/bind9/doc/arm/man.dnssec-signzone.html b/contrib/bind9/doc/arm/man.dnssec-signzone.html index 9e4b00f563d..40c09764bd1 100644 --- a/contrib/bind9/doc/arm/man.dnssec-signzone.html +++ b/contrib/bind9/doc/arm/man.dnssec-signzone.html @@ -14,12 +14,12 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + dnssec-signzone - + @@ -50,7 +50,7 @@

    -

    DESCRIPTION

    +

    DESCRIPTION

    dnssec-signzone signs a zone. It generates NSEC and RRSIG records and produces a signed version of the @@ -61,7 +61,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -a

    @@ -276,7 +276,7 @@

    -

    EXAMPLE

    +

    EXAMPLE

    The following command signs the example.com zone with the DSA key generated by dnssec-keygen @@ -305,7 +305,7 @@ db.example.com.signed %

    -

    KNOWN BUGS

    +

    KNOWN BUGS

    dnssec-signzone was designed so that it could sign a zone partially, using only a subset of the DNSSEC keys @@ -330,14 +330,14 @@ db.example.com.signed

    -

    SEE ALSO

    +

    SEE ALSO

    dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 4033.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.named-checkconf.html b/contrib/bind9/doc/arm/man.named-checkconf.html index c6aeb32bc3a..94c22f69c4f 100644 --- a/contrib/bind9/doc/arm/man.named-checkconf.html +++ b/contrib/bind9/doc/arm/man.named-checkconf.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -50,14 +50,14 @@

    named-checkconf [-h] [-v] [-j] [-t directory] {filename} [-z]

    -

    DESCRIPTION

    +

    DESCRIPTION

    named-checkconf checks the syntax, but not the semantics, of a named configuration file.

    -

    OPTIONS

    +

    OPTIONS

    -h

    @@ -92,21 +92,21 @@

    -

    RETURN VALUES

    +

    RETURN VALUES

    named-checkconf returns an exit status of 1 if errors were detected and 0 otherwise.

    -

    SEE ALSO

    +

    SEE ALSO

    named(8), named-checkzone(8), BIND 9 Administrator Reference Manual.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.named-checkzone.html b/contrib/bind9/doc/arm/man.named-checkzone.html index 4cee97f3c6b..b187a1a7112 100644 --- a/contrib/bind9/doc/arm/man.named-checkzone.html +++ b/contrib/bind9/doc/arm/man.named-checkzone.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -51,7 +51,7 @@

    named-compilezone [-d] [-j] [-q] [-v] [-c class] [-C mode] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-n mode] [-o filename] [-s style] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

    -

    DESCRIPTION

    +

    DESCRIPTION

    named-checkzone checks the syntax and integrity of a zone file. It performs the same checks as named does when loading a @@ -71,7 +71,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -d

    @@ -257,14 +257,14 @@

    -

    RETURN VALUES

    +

    RETURN VALUES

    named-checkzone returns an exit status of 1 if errors were detected and 0 otherwise.

    -

    SEE ALSO

    +

    SEE ALSO

    named(8), named-checkconf(8), RFC 1035, @@ -272,7 +272,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.named.html b/contrib/bind9/doc/arm/man.named.html index 3e338877670..2a440ce4b10 100644 --- a/contrib/bind9/doc/arm/man.named.html +++ b/contrib/bind9/doc/arm/man.named.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -50,7 +50,7 @@

    named [-4] [-6] [-c config-file] [-d debug-level] [-f] [-g] [-m flag] [-n #cpus] [-p port] [-s] [-S #max-socks] [-t directory] [-u user] [-v] [-V] [-x cache-file]

    -

    DESCRIPTION

    +

    DESCRIPTION

    named is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC. For more @@ -65,7 +65,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -4

    @@ -238,7 +238,7 @@

    -

    SIGNALS

    +

    SIGNALS

    In routine operation, signals should not be used to control the nameserver; rndc should be used @@ -259,7 +259,7 @@

    -

    CONFIGURATION

    +

    CONFIGURATION

    The named configuration file is too complex to describe in detail here. A complete description is provided @@ -268,7 +268,7 @@

    -

    FILES

    +

    FILES

    /etc/named.conf

    @@ -281,7 +281,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    RFC 1033, RFC 1034, RFC 1035, @@ -294,7 +294,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.nsupdate.html b/contrib/bind9/doc/arm/man.nsupdate.html index a0ce8661aa5..eb3b7bec285 100644 --- a/contrib/bind9/doc/arm/man.nsupdate.html +++ b/contrib/bind9/doc/arm/man.nsupdate.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -50,7 +50,7 @@

    nsupdate [-d] [-D] [[-g] | [-o] | [-y [hmac:]keyname:secret] | [-k keyfile]] [-t timeout] [-u udptimeout] [-r udpretries] [-R randomdev] [-v] [filename]

    -

    DESCRIPTION

    +

    DESCRIPTION

    nsupdate is used to submit Dynamic DNS Update requests as defined in RFC2136 to a name server. @@ -187,7 +187,7 @@

    -

    INPUT FORMAT

    +

    INPUT FORMAT

    nsupdate reads input from filename @@ -451,7 +451,7 @@

    -

    EXAMPLES

    +

    EXAMPLES

    The examples below show how nsupdate @@ -505,7 +505,7 @@

    -

    FILES

    +

    FILES

    /etc/resolv.conf

    @@ -524,7 +524,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    RFC2136, RFC3007, RFC2104, @@ -537,7 +537,7 @@

    -

    BUGS

    +

    BUGS

    The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library diff --git a/contrib/bind9/doc/arm/man.rndc-confgen.html b/contrib/bind9/doc/arm/man.rndc-confgen.html index 485e6f4b5b5..cb59c2ed722 100644 --- a/contrib/bind9/doc/arm/man.rndc-confgen.html +++ b/contrib/bind9/doc/arm/man.rndc-confgen.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -48,7 +48,7 @@

    rndc-confgen [-a] [-b keysize] [-c keyfile] [-h] [-k keyname] [-p port] [-r randomfile] [-s address] [-t chrootdir] [-u user]

    -

    DESCRIPTION

    +

    DESCRIPTION

    rndc-confgen generates configuration files for rndc. It can be used as a @@ -64,7 +64,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -a
    @@ -171,7 +171,7 @@
    -

    EXAMPLES

    +

    EXAMPLES

    To allow rndc to be used with no manual configuration, run @@ -188,7 +188,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    rndc(8), rndc.conf(5), named(8), @@ -196,7 +196,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.rndc.conf.html b/contrib/bind9/doc/arm/man.rndc.conf.html index b4c080126fa..e8e86ba6b13 100644 --- a/contrib/bind9/doc/arm/man.rndc.conf.html +++ b/contrib/bind9/doc/arm/man.rndc.conf.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -50,7 +50,7 @@

    rndc.conf

    -

    DESCRIPTION

    +

    DESCRIPTION

    rndc.conf is the configuration file for rndc, the BIND 9 name server control utility. This file has a similar structure and syntax to @@ -135,7 +135,7 @@

    -

    EXAMPLE

    +

    EXAMPLE

           options {
             default-server  localhost;
    @@ -209,7 +209,7 @@
         

    -

    NAME SERVER CONFIGURATION

    +

    NAME SERVER CONFIGURATION

    The name server must be configured to accept rndc connections and to recognize the key specified in the rndc.conf @@ -219,7 +219,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    rndc(8), rndc-confgen(8), mmencode(1), @@ -227,7 +227,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.rndc.html b/contrib/bind9/doc/arm/man.rndc.html index ae38ad16d1d..36843bc145b 100644 --- a/contrib/bind9/doc/arm/man.rndc.html +++ b/contrib/bind9/doc/arm/man.rndc.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -50,7 +50,7 @@

    rndc [-b source-address] [-c config-file] [-k key-file] [-s server] [-p port] [-V] [-y key_id] {command}

    -

    DESCRIPTION

    +

    DESCRIPTION

    rndc controls the operation of a name server. It supersedes the ndc utility @@ -79,7 +79,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -b source-address

    @@ -151,7 +151,7 @@

    -

    LIMITATIONS

    +

    LIMITATIONS

    rndc does not yet support all the commands of the BIND 8 ndc utility. @@ -165,7 +165,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    rndc.conf(5), rndc-confgen(8), named(8), @@ -175,7 +175,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/lib/dns/include/dns/db.h b/contrib/bind9/lib/dns/include/dns/db.h index 3b78208943b..c75c774143f 100644 --- a/contrib/bind9/lib/dns/include/dns/db.h +++ b/contrib/bind9/lib/dns/include/dns/db.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.h,v 1.93.50.3 2009/01/18 23:25:17 marka Exp $ */ +/* $Id: db.h,v 1.93.50.3.12.1 2009/12/31 21:44:37 each Exp $ */ #ifndef DNS_DB_H #define DNS_DB_H 1 @@ -205,14 +205,15 @@ struct dns_db { /*% * Options that can be specified for dns_db_find(). */ -#define DNS_DBFIND_GLUEOK 0x01 -#define DNS_DBFIND_VALIDATEGLUE 0x02 -#define DNS_DBFIND_NOWILD 0x04 -#define DNS_DBFIND_PENDINGOK 0x08 -#define DNS_DBFIND_NOEXACT 0x10 -#define DNS_DBFIND_FORCENSEC 0x20 -#define DNS_DBFIND_COVERINGNSEC 0x40 -#define DNS_DBFIND_FORCENSEC3 0x80 +#define DNS_DBFIND_GLUEOK 0x0001 +#define DNS_DBFIND_VALIDATEGLUE 0x0002 +#define DNS_DBFIND_NOWILD 0x0004 +#define DNS_DBFIND_PENDINGOK 0x0008 +#define DNS_DBFIND_NOEXACT 0x0010 +#define DNS_DBFIND_FORCENSEC 0x0020 +#define DNS_DBFIND_COVERINGNSEC 0x0040 +#define DNS_DBFIND_FORCENSEC3 0x0080 +#define DNS_DBFIND_ADDITIONALOK 0x0100 /*@}*/ /*@{*/ diff --git a/contrib/bind9/lib/dns/include/dns/ncache.h b/contrib/bind9/lib/dns/include/dns/ncache.h index a818fe63cce..d61684df88c 100644 --- a/contrib/bind9/lib/dns/include/dns/ncache.h +++ b/contrib/bind9/lib/dns/include/dns/ncache.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ncache.h,v 1.25 2008/09/25 04:02:39 tbox Exp $ */ +/* $Id: ncache.h,v 1.25.142.1 2009/12/31 20:29:21 each Exp $ */ #ifndef DNS_NCACHE_H #define DNS_NCACHE_H 1 @@ -76,7 +76,7 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, * The 'covers' argument is the RR type whose nonexistence we are caching, * or dns_rdatatype_any when caching a NXDOMAIN response. * - * 'optout' indicates a DNS_RATASETATTR_OPTOUT should be set. + * 'optout' indicates a DNS_RDATASETATTR_OPTOUT should be set. * * Note: *\li If 'addedrdataset' is not NULL, then it will be attached to the added diff --git a/contrib/bind9/lib/dns/include/dns/types.h b/contrib/bind9/lib/dns/include/dns/types.h index 8c7773c3160..525dd8d4892 100644 --- a/contrib/bind9/lib/dns/include/dns/types.h +++ b/contrib/bind9/lib/dns/include/dns/types.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.130.50.3.12.1 2009/11/18 23:58:04 marka Exp $ */ +/* $Id: types.h,v 1.130.50.3.12.2 2009/12/31 20:29:21 each Exp $ */ #ifndef DNS_TYPES_H #define DNS_TYPES_H 1 @@ -301,6 +301,8 @@ enum { #define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \ (x) == dns_trust_pending_additional) +#define DNS_TRUST_ADDITIONAL(x) ((x) == dns_trust_additional || \ + (x) == dns_trust_pending_additional) #define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue) diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c index b163441d43b..d5b5b5c8194 100644 --- a/contrib/bind9/lib/dns/rbtdb.c +++ b/contrib/bind9/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.270.12.6.10.1 2009/11/18 23:58:04 marka Exp $ */ +/* $Id: rbtdb.c,v 1.270.12.6.10.2 2009/12/31 21:44:36 each Exp $ */ /*! \file */ @@ -4546,6 +4546,8 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * If we didn't find what we were looking for... */ if (found == NULL || + (DNS_TRUST_ADDITIONAL(found->trust) && + ((options & DNS_DBFIND_ADDITIONALOK) == 0)) || (found->trust == dns_trust_glue && ((options & DNS_DBFIND_GLUEOK) == 0)) || (DNS_TRUST_PENDING(found->trust) && diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c index 3b90af4400c..1b4f407c87f 100644 --- a/contrib/bind9/lib/dns/resolver.c +++ b/contrib/bind9/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.384.14.14.8.1 2009/11/18 23:58:04 marka Exp $ */ +/* $Id: resolver.c,v 1.384.14.14.8.2 2010/01/07 17:17:19 each Exp $ */ /*! \file */ @@ -4289,11 +4289,19 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, rdataset->ttl = res->view->maxcachettl; /* - * If this rrset is in a secure domain, do DNSSEC validation - * for it, unless it is glue. + * If this RRset is in a secure domain, is in bailiwick, + * and is not glue, attempt DNSSEC validation. (We do not + * attempt to validate glue or out-of-bailiwick data--even + * though there might be some performance benefit to doing + * so--because it makes it simpler and safer to ensure that + * records from a secure domain are only cached if validated + * within the context of a query to the domain that owns + * them.) */ - if (secure_domain && rdataset->trust != dns_trust_glue) { + if (secure_domain && rdataset->trust != dns_trust_glue && + !EXTERNAL(rdataset)) { dns_trust_t trust; + /* * RRSIGs are validated as part of validating the * type they cover. @@ -4330,22 +4338,6 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, } /* - * Reject out of bailiwick additional records - * without RRSIGs as they can't possibly validate - * as "secure" and as we will never never want to - * store these as "answers" after validation. - */ - if (rdataset->trust == dns_trust_additional && - sigrdataset == NULL && EXTERNAL(rdataset)) - continue; - - /* - * XXXMPA: If we store as "answer" after validating - * then we need to do bailiwick processing and - * also need to track whether RRsets are in or - * out of bailiwick. This will require a another - * pending trust level. - * * Cache this rdataset/sigrdataset pair as * pending data. Track whether it was additional * or not. @@ -5463,9 +5455,7 @@ answer_response(fetchctx_t *fctx) { /* * This data is outside of * our query domain, and - * may only be cached if it - * comes from a secure zone - * and validates. + * may not be cached. */ rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL; diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c index 46a74919c82..ce49daf2eb1 100644 --- a/contrib/bind9/lib/dns/validator.c +++ b/contrib/bind9/lib/dns/validator.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.164.12.9.8.1 2009/11/18 23:58:04 marka Exp $ */ +/* $Id: validator.c,v 1.164.12.9.8.2 2009/12/31 20:29:21 each Exp $ */ #include @@ -3242,20 +3242,20 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume) if (val->havedlvsep) dns_name_copy(dns_fixedname_name(&val->dlvsep), secroot, NULL); else { + unsigned int labels; dns_name_copy(val->event->name, secroot, NULL); /* * If this is a response to a DS query, we need to look in * the parent zone for the trust anchor. */ - if (val->event->type == dns_rdatatype_ds && - dns_name_countlabels(secroot) > 1U) - dns_name_split(secroot, 1, NULL, secroot); + + labels = dns_name_countlabels(secroot); + if (val->event->type == dns_rdatatype_ds && labels > 1U) + dns_name_getlabelsequence(secroot, 1, labels - 1, + secroot); result = dns_keytable_finddeepestmatch(val->keytable, secroot, secroot); - if (result == ISC_R_NOTFOUND) { - validator_log(val, ISC_LOG_DEBUG(3), - "not beneath secure root"); if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure"); diff --git a/contrib/bind9/lib/lwres/man/lwres.html b/contrib/bind9/lib/lwres/man/lwres.html index 70d7856f372..986918a8cf7 100644 --- a/contrib/bind9/lib/lwres/man/lwres.html +++ b/contrib/bind9/lib/lwres/man/lwres.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@
    -
    +

    Name

    lwres — introduction to the lightweight resolver library

    @@ -32,7 +32,7 @@
    #include <lwres/lwres.h>
    -

    DESCRIPTION

    +

    DESCRIPTION

    The BIND 9 lightweight resolver library is a simple, name service independent stub resolver library. It provides hostname-to-address @@ -47,7 +47,7 @@

    -

    OVERVIEW

    +

    OVERVIEW

    The lwresd library implements multiple name service APIs. The standard @@ -101,7 +101,7 @@

    -

    CLIENT-SIDE LOW-LEVEL API CALL FLOW

    +

    CLIENT-SIDE LOW-LEVEL API CALL FLOW

    When a client program wishes to make an lwres request using the native low-level API, it typically performs the following @@ -149,7 +149,7 @@

    -

    SERVER-SIDE LOW-LEVEL API CALL FLOW

    +

    SERVER-SIDE LOW-LEVEL API CALL FLOW

    When implementing the server side of the lightweight resolver protocol using the lwres library, a sequence of actions like the @@ -191,7 +191,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    lwres_gethostent(3), lwres_getipnode(3), diff --git a/contrib/bind9/lib/lwres/man/lwres_buffer.html b/contrib/bind9/lib/lwres/man/lwres_buffer.html index deb52624899..7ed5407c53a 100644 --- a/contrib/bind9/lib/lwres/man/lwres_buffer.html +++ b/contrib/bind9/lib/lwres/man/lwres_buffer.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_buffer_init, lwres_buffer_invalidate, lwres_buffer_add, lwres_buffer_subtract, lwres_buffer_clear, lwres_buffer_first, lwres_buffer_forward, lwres_buffer_back, lwres_buffer_getuint8, lwres_buffer_putuint8, lwres_buffer_getuint16, lwres_buffer_putuint16, lwres_buffer_getuint32, lwres_buffer_putuint32, lwres_buffer_putmem, lwres_buffer_getmem — lightweight resolver buffer management

    @@ -262,7 +262,7 @@ void
    -

    DESCRIPTION

    +

    DESCRIPTION

    These functions provide bounds checked access to a region of memory where data is being read or written. diff --git a/contrib/bind9/lib/lwres/man/lwres_config.html b/contrib/bind9/lib/lwres/man/lwres_config.html index e27892b2020..050fd5de361 100644 --- a/contrib/bind9/lib/lwres/man/lwres_config.html +++ b/contrib/bind9/lib/lwres/man/lwres_config.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_conf_init, lwres_conf_clear, lwres_conf_parse, lwres_conf_print, lwres_conf_get — lightweight resolver configuration

    @@ -90,7 +90,7 @@ lwres_conf_t *
    -

    DESCRIPTION

    +

    DESCRIPTION

    lwres_conf_init() creates an empty lwres_conf_t @@ -123,7 +123,7 @@ lwres_conf_t *

    -

    RETURN VALUES

    +

    RETURN VALUES

    lwres_conf_parse() returns LWRES_R_SUCCESS if it successfully read and parsed @@ -142,13 +142,13 @@ lwres_conf_t *

    -

    SEE ALSO

    +

    SEE ALSO

    stdio(3), resolver(5).

    -

    FILES

    +

    FILES

    /etc/resolv.conf

    diff --git a/contrib/bind9/lib/lwres/man/lwres_context.html b/contrib/bind9/lib/lwres/man/lwres_context.html index 18c3d38fb72..d6fada9b918 100644 --- a/contrib/bind9/lib/lwres/man/lwres_context.html +++ b/contrib/bind9/lib/lwres/man/lwres_context.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@
    -
    +

    Name

    lwres_context_create, lwres_context_destroy, lwres_context_nextserial, lwres_context_initserial, lwres_context_freemem, lwres_context_allocmem, lwres_context_sendrecv — lightweight resolver context management

    @@ -172,7 +172,7 @@ void *
    -

    DESCRIPTION

    +

    DESCRIPTION

    lwres_context_create() creates a lwres_context_t structure for use in lightweight resolver operations. It holds a socket and other @@ -258,7 +258,7 @@ void *

    -

    RETURN VALUES

    +

    RETURN VALUES

    lwres_context_create() returns LWRES_R_NOMEMORY if memory for the struct lwres_context could not be allocated, @@ -283,7 +283,7 @@ void *

    -

    SEE ALSO

    +

    SEE ALSO

    lwres_conf_init(3), malloc(3), diff --git a/contrib/bind9/lib/lwres/man/lwres_gabn.html b/contrib/bind9/lib/lwres/man/lwres_gabn.html index a51d2520e7a..efb152a381d 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gabn.html +++ b/contrib/bind9/lib/lwres/man/lwres_gabn.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_gabnrequest_render, lwres_gabnresponse_render, lwres_gabnrequest_parse, lwres_gabnresponse_parse, lwres_gabnresponse_free, lwres_gabnrequest_free — lightweight resolver getaddrbyname message handling

    @@ -178,7 +178,7 @@ void
    -

    DESCRIPTION

    +

    DESCRIPTION

    These are low-level routines for creating and parsing lightweight resolver name-to-address lookup request and @@ -278,7 +278,7 @@ typedef struct {

    -

    RETURN VALUES

    +

    RETURN VALUES

    The getaddrbyname opcode functions lwres_gabnrequest_render(), @@ -316,7 +316,7 @@ typedef struct {

    -

    SEE ALSO

    +

    SEE ALSO

    lwres_packet(3)

    diff --git a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html index c64beb13b23..aeb0967e3e0 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html +++ b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@
    -
    +

    Name

    lwres_gai_strerror — print suitable error string

    @@ -42,7 +42,7 @@ char *
    -

    DESCRIPTION

    +

    DESCRIPTION

    lwres_gai_strerror() returns an error message corresponding to an error code returned by getaddrinfo(). @@ -110,7 +110,7 @@ char *

    -

    SEE ALSO

    +

    SEE ALSO

    strerror(3), lwres_getaddrinfo(3), diff --git a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html index d4dd956aa36..ec0083952a2 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html +++ b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_getaddrinfo, lwres_freeaddrinfo — socket address structure to host and service name

    @@ -89,7 +89,7 @@ struct addrinfo {

    -

    DESCRIPTION

    +

    DESCRIPTION

    lwres_getaddrinfo() is used to get a list of IP addresses and port numbers for host hostname and service @@ -283,7 +283,7 @@ struct addrinfo {

    -

    RETURN VALUES

    +

    RETURN VALUES

    lwres_getaddrinfo() returns zero on success or one of the error codes listed in gai_strerror(3) @@ -294,7 +294,7 @@ struct addrinfo {

    -

    SEE ALSO

    +

    SEE ALSO

    lwres(3), lwres_getaddrinfo(3), diff --git a/contrib/bind9/lib/lwres/man/lwres_gethostent.html b/contrib/bind9/lib/lwres/man/lwres_gethostent.html index efeeaa238a5..9465440bd51 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gethostent.html +++ b/contrib/bind9/lib/lwres/man/lwres_gethostent.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_gethostbyname, lwres_gethostbyname2, lwres_gethostbyaddr, lwres_gethostent, lwres_sethostent, lwres_endhostent, lwres_gethostbyname_r, lwres_gethostbyaddr_r, lwres_gethostent_r, lwres_sethostent_r, lwres_endhostent_r — lightweight resolver get network host entry

    @@ -228,7 +228,7 @@ void
    -

    DESCRIPTION

    +

    DESCRIPTION

    These functions provide hostname-to-address and address-to-hostname lookups by means of the lightweight resolver. @@ -366,7 +366,7 @@ struct hostent {

    -

    RETURN VALUES

    +

    RETURN VALUES

    The functions lwres_gethostbyname(), @@ -430,7 +430,7 @@ struct hostent {

    -

    SEE ALSO

    +

    SEE ALSO

    gethostent(3), lwres_getipnode(3), @@ -439,7 +439,7 @@ struct hostent {

    -

    BUGS

    +

    BUGS

    lwres_gethostbyname(), lwres_gethostbyname2(), lwres_gethostbyaddr() diff --git a/contrib/bind9/lib/lwres/man/lwres_getipnode.html b/contrib/bind9/lib/lwres/man/lwres_getipnode.html index 23fe50fdf5f..c92c51cb280 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getipnode.html +++ b/contrib/bind9/lib/lwres/man/lwres_getipnode.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_getipnodebyname, lwres_getipnodebyaddr, lwres_freehostent — lightweight resolver nodename / address translation API

    @@ -98,7 +98,7 @@ void
    -

    DESCRIPTION

    +

    DESCRIPTION

    These functions perform thread safe, protocol independent nodename-to-address and address-to-nodename @@ -217,7 +217,7 @@ struct hostent {

    -

    RETURN VALUES

    +

    RETURN VALUES

    If an error occurs, lwres_getipnodebyname() @@ -261,7 +261,7 @@ struct hostent {

    -

    SEE ALSO

    +

    SEE ALSO

    RFC2553, lwres(3), diff --git a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html index 53a70d96279..7730131cfda 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html +++ b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_getnameinfo — lightweight resolver socket address structure to hostname and @@ -82,7 +82,7 @@ int

    -

    DESCRIPTION

    +

    DESCRIPTION

    This function is equivalent to the getnameinfo(3) function defined in RFC2133. @@ -149,13 +149,13 @@ int

    -

    RETURN VALUES

    +

    RETURN VALUES

    lwres_getnameinfo() returns 0 on success or a non-zero error code if an error occurs.

    -

    SEE ALSO

    +

    SEE ALSO

    RFC2133, getservbyport(3), lwres(3), @@ -165,7 +165,7 @@ int

    -

    BUGS

    +

    BUGS

    RFC2133 fails to define what the nonzero return values of getnameinfo(3) diff --git a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html index 8dc36a146e1..15bfb82dc64 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html +++ b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_getrrsetbyname, lwres_freerrset — retrieve DNS records

    @@ -102,7 +102,7 @@ struct rrsetinfo {

    -

    DESCRIPTION

    +

    DESCRIPTION

    lwres_getrrsetbyname() gets a set of resource records associated with a hostname, class, @@ -150,7 +150,7 @@ struct rrsetinfo {

    -

    RETURN VALUES

    +

    RETURN VALUES

    lwres_getrrsetbyname() returns zero on success, and one of the following error codes if an error occurred: @@ -184,7 +184,7 @@ struct rrsetinfo {

    -

    SEE ALSO

    +

    SEE ALSO

    lwres(3).

    diff --git a/contrib/bind9/lib/lwres/man/lwres_gnba.html b/contrib/bind9/lib/lwres/man/lwres_gnba.html index 88b18a8630e..80c909ec212 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gnba.html +++ b/contrib/bind9/lib/lwres/man/lwres_gnba.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@
    -
    +

    Name

    lwres_gnbarequest_render, lwres_gnbaresponse_render, lwres_gnbarequest_parse, lwres_gnbaresponse_parse, lwres_gnbaresponse_free, lwres_gnbarequest_free — lightweight resolver getnamebyaddress message handling

    @@ -183,7 +183,7 @@ void
    -

    DESCRIPTION

    +

    DESCRIPTION

    These are low-level routines for creating and parsing lightweight resolver address-to-name lookup request and @@ -270,7 +270,7 @@ typedef struct {

    -

    RETURN VALUES

    +

    RETURN VALUES

    The getnamebyaddr opcode functions lwres_gnbarequest_render(), @@ -308,7 +308,7 @@ typedef struct {

    -

    SEE ALSO

    +

    SEE ALSO

    lwres_packet(3).

    diff --git a/contrib/bind9/lib/lwres/man/lwres_hstrerror.html b/contrib/bind9/lib/lwres/man/lwres_hstrerror.html index ef67d486f99..b166e3d7780 100644 --- a/contrib/bind9/lib/lwres/man/lwres_hstrerror.html +++ b/contrib/bind9/lib/lwres/man/lwres_hstrerror.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@
    -
    +

    Name

    lwres_herror, lwres_hstrerror — lightweight resolver error message generation

    @@ -50,7 +50,7 @@ const char *
    -

    DESCRIPTION

    +

    DESCRIPTION

    lwres_herror() prints the string s on stderr followed by the string generated by @@ -84,7 +84,7 @@ const char *

    -

    RETURN VALUES

    +

    RETURN VALUES

    The string Unknown resolver error is returned by lwres_hstrerror() @@ -94,7 +94,7 @@ const char *

    -

    SEE ALSO

    +

    SEE ALSO

    herror(3), lwres_hstrerror(3). diff --git a/contrib/bind9/lib/lwres/man/lwres_inetntop.html b/contrib/bind9/lib/lwres/man/lwres_inetntop.html index 1a911103e85..3522a1dc191 100644 --- a/contrib/bind9/lib/lwres/man/lwres_inetntop.html +++ b/contrib/bind9/lib/lwres/man/lwres_inetntop.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_net_ntop — lightweight resolver IP address presentation

    @@ -62,7 +62,7 @@ const char *
    -

    DESCRIPTION

    +

    DESCRIPTION

    lwres_net_ntop() converts an IP address of protocol family af — IPv4 or IPv6 — at @@ -80,7 +80,7 @@ const char *

    -

    RETURN VALUES

    +

    RETURN VALUES

    If successful, the function returns dst: a pointer to a string containing the presentation format of the @@ -93,7 +93,7 @@ const char *

    -

    SEE ALSO

    +

    SEE ALSO

    RFC1884, inet_ntop(3), errno(3). diff --git a/contrib/bind9/lib/lwres/man/lwres_noop.html b/contrib/bind9/lib/lwres/man/lwres_noop.html index aab581a5fe3..18a41fa0a54 100644 --- a/contrib/bind9/lib/lwres/man/lwres_noop.html +++ b/contrib/bind9/lib/lwres/man/lwres_noop.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_nooprequest_render, lwres_noopresponse_render, lwres_nooprequest_parse, lwres_noopresponse_parse, lwres_noopresponse_free, lwres_nooprequest_free — lightweight resolver no-op message handling

    @@ -179,7 +179,7 @@ void
    -

    DESCRIPTION

    +

    DESCRIPTION

    These are low-level routines for creating and parsing lightweight resolver no-op request and response messages. @@ -270,7 +270,7 @@ typedef struct {

    -

    RETURN VALUES

    +

    RETURN VALUES

    The no-op opcode functions lwres_nooprequest_render(), @@ -309,7 +309,7 @@ typedef struct {

    -

    SEE ALSO

    +

    SEE ALSO

    lwres_packet(3)

    diff --git a/contrib/bind9/lib/lwres/man/lwres_packet.html b/contrib/bind9/lib/lwres/man/lwres_packet.html index b4cc1df5949..11601e86b12 100644 --- a/contrib/bind9/lib/lwres/man/lwres_packet.html +++ b/contrib/bind9/lib/lwres/man/lwres_packet.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@
    -
    +

    Name

    lwres_lwpacket_renderheader, lwres_lwpacket_parseheader — lightweight resolver packet handling functions

    @@ -66,7 +66,7 @@ lwres_result_t
    -

    DESCRIPTION

    +

    DESCRIPTION

    These functions rely on a struct lwres_lwpacket @@ -219,7 +219,7 @@ struct lwres_lwpacket {

    -

    RETURN VALUES

    +

    RETURN VALUES

    Successful calls to lwres_lwpacket_renderheader() and diff --git a/contrib/bind9/lib/lwres/man/lwres_resutil.html b/contrib/bind9/lib/lwres/man/lwres_resutil.html index 7bc3e6e3ef0..e67ac0aa796 100644 --- a/contrib/bind9/lib/lwres/man/lwres_resutil.html +++ b/contrib/bind9/lib/lwres/man/lwres_resutil.html @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -22,7 +22,7 @@

    -
    +

    Name

    lwres_string_parse, lwres_addr_parse, lwres_getaddrsbyname, lwres_getnamebyaddr — lightweight resolver utility functions

    @@ -134,7 +134,7 @@ lwres_result_t
    -

    DESCRIPTION

    +

    DESCRIPTION

    lwres_string_parse() retrieves a DNS-encoded string starting the current pointer of lightweight resolver buffer b: i.e. @@ -210,7 +210,7 @@ typedef struct {

    -

    RETURN VALUES

    +

    RETURN VALUES

    Successful calls to lwres_string_parse() @@ -248,7 +248,7 @@ typedef struct {

    -

    SEE ALSO

    +

    SEE ALSO

    lwres_buffer(3), lwres_gabn(3). diff --git a/contrib/bind9/version b/contrib/bind9/version index ccb7b87efb2..c6fcc3fdeb6 100644 --- a/contrib/bind9/version +++ b/contrib/bind9/version @@ -1,4 +1,4 @@ -# $Id: version,v 1.43.12.5.8.2 2009/11/18 23:58:04 marka Exp $ +# $Id: version,v 1.43.12.5.8.3 2009/12/31 20:29:20 each Exp $ # # This file must follow /bin/sh rules. It is imported directly via # configure. @@ -7,4 +7,4 @@ MAJORVER=9 MINORVER=6 PATCHVER=1 RELEASETYPE=-P -RELEASEVER=2 +RELEASEVER=3 From 7c2545fb17b656ff05eec84ac0dbb43fca8d8615 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Sun, 7 Feb 2010 21:04:26 +0000 Subject: [PATCH 1396/2592] Merge r202115 from head: Our standard "xterm" termcap entry supports colour, so this tip is redundant. As it happens, "xterm-color" has just been an alias for "xterm" since src/share/termcap/termcap.src 1.131 in September 2002. PR: docs/132959 --- games/fortune/datfiles/freebsd-tips | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/games/fortune/datfiles/freebsd-tips b/games/fortune/datfiles/freebsd-tips index c9a2ed6bbac..1b0844384b0 100644 --- a/games/fortune/datfiles/freebsd-tips +++ b/games/fortune/datfiles/freebsd-tips @@ -50,18 +50,6 @@ If you are in the C shell and have just installed a new program, you won't be able to run it unless you first type "rehash". -- Dru % -If you are running xterm, the default TERM variable will be 'xterm'. If you -set this environment variable to 'xterm-color' instead, a lot of programs will -use colors. You can do this by - - TERM=xterm-color; export TERM - -in Bourne-derived shells, and - - setenv TERM xterm-color - -in csh-derived shells. -% If you do not want to get beeps in X11 (X Windows), you can turn them off with xset b off From d430c009c7e29a8a3c2d2f9074c84ce220a3e0fc Mon Sep 17 00:00:00 2001 From: David Xu Date: Mon, 8 Feb 2010 03:11:55 +0000 Subject: [PATCH 1397/2592] MFC r203414: After busied the lock, re-read state word before checking waiters flag, otherwise, the waiters bit may not be set and a wakeup is lost. --- sys/kern/kern_umtx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 2ab099d758f..a57dc3d903b 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -2463,6 +2463,12 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, int timo) umtxq_busy(&uq->uq_key); umtxq_unlock(&uq->uq_key); + /* + * re-read the state, in case it changed between the try-lock above + * and the check below + */ + state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); + /* set read contention bit */ while ((state & wrflags) && !(state & URWLOCK_READ_WAITERS)) { oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_READ_WAITERS); @@ -2595,6 +2601,12 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo) umtxq_busy(&uq->uq_key); umtxq_unlock(&uq->uq_key); + /* + * re-read the state, in case it changed between the try-lock above + * and the check below + */ + state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); + while (((state & URWLOCK_WRITE_OWNER) || URWLOCK_READER_COUNT(state) != 0) && (state & URWLOCK_WRITE_WAITERS) == 0) { oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_WRITE_WAITERS); From 95e1c1fa001b5574fb34d9bb64db2eaa529affe6 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Mon, 8 Feb 2010 14:08:52 +0000 Subject: [PATCH 1398/2592] MC r202889, r202940: - Fix a race in sched_switch() of sched_4bsd. Block the td_lock when acquiring explicitly sched_lock in order to prevent races with other td_lock contenders. - Merge the ULE's internal function thread_block_switch() into the global thread_lock_block() and make the former semantic as the default for thread_lock_block(). - Split out an invariant in order to have better checks. --- sys/kern/kern_mutex.c | 2 -- sys/kern/sched_4bsd.c | 13 +++++++++---- sys/kern/sched_ule.c | 27 ++++++--------------------- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index 85ca646370d..f9c3377ce88 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -616,7 +616,6 @@ thread_lock_block(struct thread *td) { struct mtx *lock; - spinlock_enter(); THREAD_LOCK_ASSERT(td, MA_OWNED); lock = td->td_lock; td->td_lock = &blocked_lock; @@ -631,7 +630,6 @@ thread_lock_unblock(struct thread *td, struct mtx *new) mtx_assert(new, MA_OWNED); MPASS(td->td_lock == &blocked_lock); atomic_store_rel_ptr((volatile void *)&td->td_lock, (uintptr_t)new); - spinlock_exit(); } void diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index 456f853702d..b7ba029f725 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -920,9 +920,11 @@ sched_sleep(struct thread *td, int pri) void sched_switch(struct thread *td, struct thread *newtd, int flags) { + struct mtx *tmtx; struct td_sched *ts; struct proc *p; + tmtx = NULL; ts = td->td_sched; p = td->td_proc; @@ -931,17 +933,20 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) /* * Switch to the sched lock to fix things up and pick * a new thread. + * Block the td_lock in order to avoid breaking the critical path. */ if (td->td_lock != &sched_lock) { mtx_lock_spin(&sched_lock); - thread_unlock(td); + tmtx = thread_lock_block(td); } if ((p->p_flag & P_NOLOAD) == 0) sched_load_rem(); - if (newtd) + if (newtd) { + MPASS(newtd->td_lock == &sched_lock); newtd->td_flags |= (td->td_flags & TDF_NEEDRESCHED); + } td->td_lastcpu = td->td_oncpu; td->td_flags &= ~TDF_NEEDRESCHED; @@ -984,8 +989,8 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) sched_load_add(); } else { newtd = choosethread(); + MPASS(newtd->td_lock == &sched_lock); } - MPASS(newtd->td_lock == &sched_lock); if (td != newtd) { #ifdef HWPMC_HOOKS @@ -1004,7 +1009,7 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) (*dtrace_vtime_switch_func)(newtd); #endif - cpu_switch(td, newtd, td->td_lock); + cpu_switch(td, newtd, tmtx != NULL ? tmtx : td->td_lock); lock_profile_obtain_lock_success(&sched_lock.lock_object, 0, 0, __FILE__, __LINE__); /* diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index 3bd5b71fad8..d065c9a04f5 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -301,7 +301,6 @@ static int sched_pickcpu(struct thread *, int); static void sched_balance(void); static int sched_balance_pair(struct tdq *, struct tdq *); static inline struct tdq *sched_setcpu(struct thread *, int, int); -static inline struct mtx *thread_block_switch(struct thread *); static inline void thread_unblock_switch(struct thread *, struct mtx *); static struct mtx *sched_switch_migrate(struct tdq *, struct thread *, int); static int sysctl_kern_sched_topology_spec(SYSCTL_HANDLER_ARGS); @@ -1106,9 +1105,11 @@ sched_setcpu(struct thread *td, int cpu, int flags) * The hard case, migration, we need to block the thread first to * prevent order reversals with other cpus locks. */ + spinlock_enter(); thread_lock_block(td); TDQ_LOCK(tdq); thread_lock_unblock(td, TDQ_LOCKPTR(tdq)); + spinlock_exit(); return (tdq); } @@ -1714,23 +1715,6 @@ sched_unlend_user_prio(struct thread *td, u_char prio) } } -/* - * Block a thread for switching. Similar to thread_block() but does not - * bump the spin count. - */ -static inline struct mtx * -thread_block_switch(struct thread *td) -{ - struct mtx *lock; - - THREAD_LOCK_ASSERT(td, MA_OWNED); - lock = td->td_lock; - td->td_lock = &blocked_lock; - mtx_unlock_spin(lock); - - return (lock); -} - /* * Handle migration from sched_switch(). This happens only for * cpu binding. @@ -1749,7 +1733,7 @@ sched_switch_migrate(struct tdq *tdq, struct thread *td, int flags) * not holding either run-queue lock. */ spinlock_enter(); - thread_block_switch(td); /* This releases the lock on tdq. */ + thread_lock_block(td); /* This releases the lock on tdq. */ /* * Acquire both run-queue locks before placing the thread on the new @@ -1769,7 +1753,8 @@ sched_switch_migrate(struct tdq *tdq, struct thread *td, int flags) } /* - * Release a thread that was blocked with thread_block_switch(). + * Variadic version of thread_lock_unblock() that does not assume td_lock + * is blocked. */ static inline void thread_unblock_switch(struct thread *td, struct mtx *mtx) @@ -1825,7 +1810,7 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) } else { /* This thread must be going to sleep. */ TDQ_LOCK(tdq); - mtx = thread_block_switch(td); + mtx = thread_lock_block(td); tdq_load_rem(tdq, td); } /* From 33e6da3c3a90d014f37606acd6b34f47f22a4a22 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Mon, 8 Feb 2010 15:48:18 +0000 Subject: [PATCH 1399/2592] MFC r200751: Add fork(2), getegid(2), geteuid(2), getgid(2), getpid(2), getpgid(2), getpgrp(2), getppid(2), getsid(2) and getuid(2) to syscall table to decode their arguments correctly. --- usr.bin/truss/syscalls.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index ccceed04ff1..f514649d846 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -92,6 +92,18 @@ static const char rcsid[] = struct syscall syscalls[] = { { .name = "fcntl", .ret_type = 1, .nargs = 3, .args = { { Int, 0 } , { Fcntl, 1 }, { Fcntlflag | OUT, 2 } } }, + { .name = "fork", .ret_type = 1, .nargs = 0 }, + { .name = "getegid", .ret_type = 1, .nargs = 0 }, + { .name = "geteuid", .ret_type = 1, .nargs = 0 }, + { .name = "getgid", .ret_type = 1, .nargs = 0 }, + { .name = "getpid", .ret_type = 1, .nargs = 0 }, + { .name = "getpgid", .ret_type = 1, .nargs = 1, + .args = { { Int, 0 } } }, + { .name = "getpgrp", .ret_type = 1, .nargs = 0 }, + { .name = "getppid", .ret_type = 1, .nargs = 0 }, + { .name = "getsid", .ret_type = 1, .nargs = 1, + .args = { { Int, 0 } } }, + { .name = "getuid", .ret_type = 1, .nargs = 0 }, { .name = "readlink", .ret_type = 1, .nargs = 3, .args = { { Name, 0 } , { Readlinkres | OUT, 1 }, { Int, 2 } } }, { .name = "lseek", .ret_type = 2, .nargs = 3, From 3ede63a7e391cf89805dd0cbafec82532720d893 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Mon, 8 Feb 2010 15:50:51 +0000 Subject: [PATCH 1400/2592] MFC r200752: Avoid sharing the file descriptor of the output file with traced processes by setting the FD_CLOEXEC flag for the output file. PR: bin/140493 --- usr.bin/truss/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c index d0dd073e632..586fcd64299 100644 --- a/usr.bin/truss/main.c +++ b/usr.bin/truss/main.c @@ -239,6 +239,12 @@ main(int ac, char **av) if ((trussinfo->outfile = fopen(fname, "w")) == NULL) errx(1, "cannot open %s", fname); } + /* + * Set FD_CLOEXEC, so that the output file is not shared with + * the traced process. + */ + if (fcntl(fileno(trussinfo->outfile), F_SETFD, FD_CLOEXEC) == -1) + warn("fcntl()"); /* * If truss starts the process itself, it will ignore some signals -- From 46e7e3ebbce5877e610f64d675b7a154f26481d9 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Mon, 8 Feb 2010 15:53:28 +0000 Subject: [PATCH 1401/2592] MFC r200780: Remove non-working special case for pipe(2) from amd64-fbsd32.c and i386-fbsd.c. Add pipe(2) to syscall table to decode it's pointer argument properly and re-add special handling for pipe(2) return value to print_syscall_ret(). PR: bin/120870 --- usr.bin/truss/amd64-fbsd32.c | 13 ------------- usr.bin/truss/i386-fbsd.c | 13 ------------- usr.bin/truss/syscalls.c | 8 ++++++++ 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/usr.bin/truss/amd64-fbsd32.c b/usr.bin/truss/amd64-fbsd32.c index eab841c96e8..3b1b88220b1 100644 --- a/usr.bin/truss/amd64-fbsd32.c +++ b/usr.bin/truss/amd64-fbsd32.c @@ -315,19 +315,6 @@ amd64_fbsd32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) } } - /* - * The pipe syscall returns its fds in two registers and has assembly glue - * to provide the libc API, so it cannot be handled like regular syscalls. - * The nargs check is so we don't have to do yet another strcmp on every - * syscall. - */ - if (!errorp && fsc.nargs == 0 && fsc.name && strcmp(fsc.name, "pipe") == 0) { - fsc.nargs = 1; - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - asprintf(&fsc.s_args[0], "[%d,%d]", (int)retval, (int)regs.r_rdx); - retval = 0; - } - if (fsc.name != NULL && (!strcmp(fsc.name, "freebsd32_execve") || !strcmp(fsc.name, "exit"))) { trussinfo->curthread->in_syscall = 1; diff --git a/usr.bin/truss/i386-fbsd.c b/usr.bin/truss/i386-fbsd.c index 8500f32bf48..3a81392b15f 100644 --- a/usr.bin/truss/i386-fbsd.c +++ b/usr.bin/truss/i386-fbsd.c @@ -305,19 +305,6 @@ i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) } } - /* - * The pipe syscall returns its fds in two registers and has assembly glue - * to provide the libc API, so it cannot be handled like regular syscalls. - * The nargs check is so we don't have to do yet another strcmp on every - * syscall. - */ - if (!errorp && fsc.nargs == 0 && fsc.name && strcmp(fsc.name, "pipe") == 0) { - fsc.nargs = 1; - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - asprintf(&fsc.s_args[0], "[%d,%d]", (int)retval, regs.r_edx); - retval = 0; - } - if (fsc.name != NULL && (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { trussinfo->curthread->in_syscall = 1; diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index f514649d846..6541d9a6906 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -242,6 +242,8 @@ struct syscall syscalls[] = { .args = { { Name | IN, 0 }, { Hex, 1 } } }, { .name = "pathconf", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Pathconf, 1 } } }, + { .name = "pipe", .ret_type = 1, .nargs = 1, + .args = { { Ptr, 0 } } }, { .name = "truncate", .ret_type = 1, .nargs = 3, .args = { { Name | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 } } }, { .name = "ftruncate", .ret_type = 1, .nargs = 3, @@ -1137,6 +1139,12 @@ print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs, if (errorp) { fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval, strerror(retval)); } else { + /* + * Because pipe(2) has a special assembly glue to provide the + * libc API, we have to adjust retval. + */ + if (name != NULL && !strcmp(name, "pipe")) + retval = 0; fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval, retval); } } From 5e4fd6c7986b5575c24b9e7315d65503a0ef29ad Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Mon, 8 Feb 2010 15:55:01 +0000 Subject: [PATCH 1402/2592] MFC r200781: Cast time_t values to intmax_t and use %jd with printf. --- usr.bin/truss/syscalls.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 6541d9a6906..8aec4a85da7 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -1161,15 +1161,15 @@ print_summary(struct trussinfo *trussinfo) ncall = nerror = 0; for (sc = syscalls; sc->name != NULL; sc++) if (sc->ncalls) { - fprintf(trussinfo->outfile, "%-20s%5d.%09ld%8d%8d\n", - sc->name, sc->time.tv_sec, sc->time.tv_nsec, - sc->ncalls, sc->nerror); + fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n", + sc->name, (intmax_t)sc->time.tv_sec, + sc->time.tv_nsec, sc->ncalls, sc->nerror); timespecadd(&total, &sc->time, &total); ncall += sc->ncalls; nerror += sc->nerror; } fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n", "", "-------------", "-------", "-------"); - fprintf(trussinfo->outfile, "%-20s%5d.%09ld%8d%8d\n", - "", total.tv_sec, total.tv_nsec, ncall, nerror); + fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n", + "", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror); } From 256aec2de49fe4936ac114c15184f6e5d155adac Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 9 Feb 2010 12:20:48 +0000 Subject: [PATCH 1403/2592] MFC: r198231: 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 6b17f232cda..56463598883 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 3268298eeffda104a70e35ec81600a7e0f595469 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 9 Feb 2010 13:07:32 +0000 Subject: [PATCH 1404/2592] MFC r203077: Add missing return, in a rare case where we can't allocate memory in deallocate. Submitted by: Ryan Stone (rysto32 at gmail dot com) Approved by: jasone --- lib/libc/stdlib/malloc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c index 80e26e66ec6..8bc2c85bc06 100644 --- a/lib/libc/stdlib/malloc.c +++ b/lib/libc/stdlib/malloc.c @@ -3861,6 +3861,7 @@ arena_dalloc(arena_t *arena, arena_chunk_t *chunk, void *ptr) arena_dalloc_small(arena, chunk, ptr, mapelm); malloc_spin_unlock(&arena->lock); + return; } mag_rack = rack; } From 1bb0287cb9ea1573aa976cdace336cdf1b3d103d Mon Sep 17 00:00:00 2001 From: Bruce M Simpson Date: Tue, 9 Feb 2010 18:43:50 +0000 Subject: [PATCH 1405/2592] MFC Revision: 203574 Add sane-port (Scanner Access Now Easy) as port 6566. Obtained from: http://www.iana.org/assignments/port-numbers --- etc/services | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/services b/etc/services index 318562cd31f..5859d46fd83 100644 --- a/etc/services +++ b/etc/services @@ -2338,6 +2338,8 @@ sge_execd 6445/tcp #Grid Engine Execution Service sge_execd 6445/udp #Grid Engine Execution Service xdsxdm 6558/tcp xdsxdm 6558/udp +sane-port 6566/tcp #Scanner Access Now Easy (SANE) Control Port +sane-port 6566/udp #Scanner Access Now Easy (SANE) Control Port ircd 6667/tcp #Internet Relay Chat (unoffical) acmsoda 6969/tcp acmsoda 6969/udp From 613e96b8c69b02360dbb78ee03c20f8aca209288 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Tue, 9 Feb 2010 19:27:54 +0000 Subject: [PATCH 1406/2592] MFC r203401 Some of the existing ppp and vpn related scripts create and set the IP addresses of the tunnel end points to the same value. In these cases the loopback route is not installed for the local end. --- sys/netinet/in.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index ed34b249c48..91de6332ab4 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -921,6 +921,12 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, if (ia->ia_addr.sin_addr.s_addr == INADDR_ANY) return (0); + if (ifp->if_flags & IFF_POINTOPOINT) { + if (ia->ia_dstaddr.sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr) + return (0); + } + + /* * add a loopback route to self */ From 207a2ae06c6082beed1ae41695f2319da4b34764 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 9 Feb 2010 22:05:30 +0000 Subject: [PATCH 1407/2592] MFC r198593: 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 b8aed26871e..76f50e2a3d8 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 cf0971f0de9..3f9714d07c6 100644 --- a/sys/dev/aac/aacvar.h +++ b/sys/dev/aac/aacvar.h @@ -441,7 +441,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 0985bbeaab1d423c0838534b27e55af90abe35ae Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 10 Feb 2010 00:34:13 +0000 Subject: [PATCH 1408/2592] MFC r202060: Add a new option, -q howmany, which when used in conjuction with -w, exits netstat after _howmany_ outputs. Requested by: thomasa Reviewed by: freebsd-net (bms, old version in early 2007) --- usr.bin/netstat/if.c | 2 ++ usr.bin/netstat/main.c | 10 ++++++++-- usr.bin/netstat/netstat.1 | 8 +++++++- usr.bin/netstat/netstat.h | 1 + 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c index e9e77b9a9d8..99a820aa7f4 100644 --- a/usr.bin/netstat/if.c +++ b/usr.bin/netstat/if.c @@ -685,6 +685,8 @@ loop: if (!first) putchar('\n'); fflush(stdout); + if ((noutputs != 0) && (--noutputs == 0)) + exit(0); oldmask = sigblock(sigmask(SIGALRM)); while (!signalled) sigpause(0); diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index ebbe1d24fbf..7a6dc731166 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -332,6 +332,7 @@ int hflag; /* show counters in human readable format */ int iflag; /* show interfaces */ int Lflag; /* show size of listen queues */ int mflag; /* show memory stats */ +int noutputs = 0; /* how much outputs before we exit */ int numeric_addr; /* show addresses numerically */ int numeric_port; /* show ports numerically */ static int pflag; /* show given protocol */ @@ -358,7 +359,7 @@ main(int argc, char *argv[]) af = AF_UNSPEC; - while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:rSstuWw:xz")) != -1) + while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:q:rSstuWw:xz")) != -1) switch(ch) { case 'A': Aflag = 1; @@ -444,6 +445,11 @@ main(int argc, char *argv[]) } pflag = 1; break; + case 'q': + noutputs = atoi(optarg); + if (noutputs != 0) + noutputs++; + break; case 'r': rflag = 1; break; @@ -780,7 +786,7 @@ usage(void) " [-M core] [-N system]", " netstat -i | -I interface [-abdhntW] [-f address_family]\n" " [-M core] [-N system]", -" netstat -w wait [-I interface] [-d] [-M core] [-N system]", +" netstat -w wait [-I interface] [-d] [-M core] [-N system] [-q howmany]", " netstat -s [-s] [-z] [-f protocol_family | -p protocol]\n" " [-M core] [-N system]", " netstat -i | -I interface -s [-f protocol_family | -p protocol]\n" diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1 index 41e15c11b15..872ff954db4 100644 --- a/usr.bin/netstat/netstat.1 +++ b/usr.bin/netstat/netstat.1 @@ -32,7 +32,7 @@ .\" @(#)netstat.1 8.8 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd July 9, 2009 +.Dd January 10, 2010 .Dt NETSTAT 1 .Os .Sh NAME @@ -136,6 +136,7 @@ is also present, print interface names using a wider field size. .Op Fl d .Op Fl M Ar core .Op Fl N Ar system +.Op Fl q Ar howmany .Ek .Xc At intervals of @@ -146,6 +147,11 @@ traffic on all configured network interfaces or a single .Ar interface . If +.Fl q +is also present, exit after +.Ar howmany +outputs. +If .Fl d is also present, show the number of dropped packets. .It Xo diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index f834495e32b..7594464547f 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -45,6 +45,7 @@ extern int hflag; /* show counters in human readable format */ extern int iflag; /* show interfaces */ extern int Lflag; /* show size of listen queues */ extern int mflag; /* show memory stats */ +extern int noutputs; /* how much outputs before we exit */ extern int numeric_addr; /* show addresses numerically */ extern int numeric_port; /* show ports numerically */ extern int rflag; /* show routing tables (or routing stats) */ From 7526c9dfc7419663d0267a52a41743fef4b6c4cd Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Wed, 10 Feb 2010 08:50:06 +0000 Subject: [PATCH 1409/2592] MFC r203483: Instead of spamming the console on each curvnet recursion event, print out each such call graph only once, along with a stack backtrace. This should make kernels built with VNET_DEBUG reasonably usable again in busy / production environments. Introduce a new DDB command "show vnetrcrs" which dumps the whole log of distinctive curvnet recursion events. This might be useful when recursion reports get burried / lost too deep in the message buffer. In the later case stack backtraces are not available. Reviewed by: bz --- sys/net/vnet.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ sys/net/vnet.h | 6 ++--- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/sys/net/vnet.c b/sys/net/vnet.c index 298ffb28457..26635db0cae 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -37,8 +37,10 @@ __FBSDID("$FreeBSD$"); #include "opt_ddb.h" +#include "opt_kdb.h" #include +#include #include #include #include @@ -616,6 +618,65 @@ vnet_sysuninit(void) VNET_SYSINIT_RUNLOCK(); } +#ifdef VNET_DEBUG +struct vnet_recursion { + SLIST_ENTRY(vnet_recursion) vnr_le; + const char *prev_fn; + const char *where_fn; + int where_line; + struct vnet *old_vnet; + struct vnet *new_vnet; +}; + +static SLIST_HEAD(, vnet_recursion) vnet_recursions = + SLIST_HEAD_INITIALIZER(vnet_recursions); + +static void +vnet_print_recursion(struct vnet_recursion *vnr, int brief) +{ + + if (!brief) + printf("CURVNET_SET() recursion in "); + printf("%s() line %d, prev in %s()", vnr->where_fn, vnr->where_line, + vnr->prev_fn); + if (brief) + printf(", "); + else + printf("\n "); + printf("%p -> %p\n", vnr->old_vnet, vnr->new_vnet); +} + +void +vnet_log_recursion(struct vnet *old_vnet, const char *old_fn, int line) +{ + struct vnet_recursion *vnr; + + /* Skip already logged recursion events. */ + SLIST_FOREACH(vnr, &vnet_recursions, vnr_le) + if (vnr->prev_fn == old_fn && + vnr->where_fn == curthread->td_vnet_lpush && + vnr->where_line == line && + (vnr->old_vnet == vnr->new_vnet) == (curvnet == old_vnet)) + return; + + vnr = malloc(sizeof(*vnr), M_VNET, M_NOWAIT | M_ZERO); + if (vnr == NULL) + panic("%s: malloc failed", __func__); + vnr->prev_fn = old_fn; + vnr->where_fn = curthread->td_vnet_lpush; + vnr->where_line = line; + vnr->old_vnet = old_vnet; + vnr->new_vnet = curvnet; + + SLIST_INSERT_HEAD(&vnet_recursions, vnr, vnr_le); + + vnet_print_recursion(vnr, 0); +#ifdef KDB + kdb_backtrace(); +#endif +} +#endif /* VNET_DEBUG */ + #ifdef DDB DB_SHOW_COMMAND(vnets, db_show_vnets) { @@ -637,4 +698,14 @@ DB_SHOW_COMMAND(vnets, db_show_vnets) break; } } + +#ifdef VNET_DEBUG +DB_SHOW_COMMAND(vnetrcrs, db_show_vnetrcrs) +{ + struct vnet_recursion *vnr; + + SLIST_FOREACH(vnr, &vnet_recursions, vnr_le) + vnet_print_recursion(vnr, 1); +} #endif +#endif /* DDB */ diff --git a/sys/net/vnet.h b/sys/net/vnet.h index 116d7af3288..d9a1ee0b679 100644 --- a/sys/net/vnet.h +++ b/sys/net/vnet.h @@ -108,6 +108,8 @@ void vnet_destroy(struct vnet *vnet); * assertions. */ #ifdef VNET_DEBUG +void vnet_log_recursion(struct vnet *, const char *, int); + #define VNET_ASSERT(condition) \ if (!(condition)) { \ printf("VNET_ASSERT @ %s:%d %s():\n", \ @@ -125,9 +127,7 @@ void vnet_destroy(struct vnet *vnet); #define CURVNET_SET_VERBOSE(arg) \ CURVNET_SET_QUIET(arg) \ if (saved_vnet) \ - printf("CURVNET_SET(%p) in %s() on cpu %d, prev %p in %s()\n", \ - curvnet, curthread->td_vnet_lpush, curcpu, \ - saved_vnet, saved_vnet_lpush); + vnet_log_recursion(saved_vnet, saved_vnet_lpush, __LINE__); #define CURVNET_SET(arg) CURVNET_SET_VERBOSE(arg) From d5f8ba9274febcf52035945e5c5f34ad357d9454 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 10 Feb 2010 09:46:31 +0000 Subject: [PATCH 1410/2592] MFC r203062: acpi_hpet: correctly get number of timers in a timer block --- sys/dev/acpica/acpi_hpet.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/sys/dev/acpica/acpi_hpet.c b/sys/dev/acpica/acpi_hpet.c index ee346b7ddff..a98a8260f95 100644 --- a/sys/dev/acpica/acpi_hpet.c +++ b/sys/dev/acpica/acpi_hpet.c @@ -42,6 +42,9 @@ __FBSDID("$FreeBSD$"); #include #include +#define HPET_VENDID_AMD 0x4353 +#define HPET_VENDID_INTEL 0x8086 + ACPI_SERIAL_DECL(hpet, "ACPI HPET support"); static devclass_t acpi_hpet_devclass; @@ -155,9 +158,10 @@ static int acpi_hpet_attach(device_t dev) { struct acpi_hpet_softc *sc; - int rid; + int rid, num_timers; uint32_t val, val2; uintmax_t freq; + uint16_t vendor; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); @@ -194,10 +198,21 @@ acpi_hpet_attach(device_t dev) freq = (1000000000000000LL + val / 2) / val; if (bootverbose) { val = bus_read_4(sc->mem_res, HPET_CAPABILITIES); + + /* + * ATI/AMD violates IA-PC HPET (High Precision Event Timers) + * Specification and provides an off by one number + * of timers/comparators. + * Additionally, they use unregistered value in VENDOR_ID field. + */ + num_timers = 1 + ((val & HPET_CAP_NUM_TIM) >> 8); + vendor = val >> 16; + if (vendor == HPET_VENDID_AMD && num_timers > 0) + num_timers--; device_printf(dev, "vend: 0x%x rev: 0x%x num: %d hz: %jd opts:%s%s\n", - val >> 16, val & HPET_CAP_REV_ID, - (val & HPET_CAP_NUM_TIM) >> 8, freq, + vendor, val & HPET_CAP_REV_ID, + num_timers, freq, (val & HPET_CAP_LEG_RT) ? " legacy_route" : "", (val & HPET_CAP_COUNT_SIZE) ? " 64-bit" : ""); } From 88cf3d348f8774c69e65f522a10f65d94d85f45f Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 10 Feb 2010 16:16:50 +0000 Subject: [PATCH 1411/2592] MFC: r203072 Fix a race that can occur when nfs nfsiod threads are being created. Without this patch it was possible for a different thread that calls nfs_asyncio() to snitch a newly created nfsiod thread that was intended for another caller of nfs_asyncio(), because the nfs_iod_mtx mutex was unlocked while the new nfsiod thread was created. This patch labels the newly created nfsiod, so that it is not taken by another caller of nfs_asyncio(). This is believed to fix the problem reported on the freebsd-stable email list under the subject: FreeBSD NFS client/Linux NFS server issue. Tested by: to DOT my DOT trociny AT gmail DOT com Reviewed by: jhb --- sys/nfsclient/nfs.h | 2 +- sys/nfsclient/nfs_bio.c | 6 +++--- sys/nfsclient/nfs_nfsiod.c | 20 +++++++++++++------- sys/nfsclient/nfs_subs.c | 4 ++-- sys/nfsclient/nfs_vnops.c | 2 +- sys/nfsclient/nfsnode.h | 15 ++++++++++++++- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h index 18eae3bae74..6f6e0d33ad5 100644 --- a/sys/nfsclient/nfs.h +++ b/sys/nfsclient/nfs.h @@ -252,7 +252,7 @@ int nfs_writerpc(struct vnode *, struct uio *, struct ucred *, int *, int nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred, struct thread *td); int nfs_readdirrpc(struct vnode *, struct uio *, struct ucred *); -int nfs_nfsiodnew(void); +int nfs_nfsiodnew(int); int nfs_asyncio(struct nfsmount *, struct buf *, struct ucred *, struct thread *); int nfs_doio(struct vnode *, struct buf *, struct ucred *, struct thread *); void nfs_doio_directwrite (struct buf *); diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 945bc51597d..cec0220b7f1 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -1377,7 +1377,7 @@ again: * Find a free iod to process this request. */ for (iod = 0; iod < nfs_numasync; iod++) - if (nfs_iodwant[iod]) { + if (nfs_iodwant[iod] == NFSIOD_AVAILABLE) { gotiod = TRUE; break; } @@ -1386,7 +1386,7 @@ again: * Try to create one if none are free. */ if (!gotiod) { - iod = nfs_nfsiodnew(); + iod = nfs_nfsiodnew(1); if (iod != -1) gotiod = TRUE; } @@ -1398,7 +1398,7 @@ again: */ NFS_DPF(ASYNCIO, ("nfs_asyncio: waking iod %d for mount %p\n", iod, nmp)); - nfs_iodwant[iod] = NULL; + nfs_iodwant[iod] = NFSIOD_NOT_AVAILABLE; nfs_iodmount[iod] = nmp; nmp->nm_bufqiods++; wakeup(&nfs_iodwant[iod]); diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c index 3fafa1e2d94..5302c5695a2 100644 --- a/sys/nfsclient/nfs_nfsiod.c +++ b/sys/nfsclient/nfs_nfsiod.c @@ -113,7 +113,7 @@ sysctl_iodmin(SYSCTL_HANDLER_ARGS) * than the new minimum, create some more. */ for (i = nfs_iodmin - nfs_numasync; i > 0; i--) - nfs_nfsiodnew(); + nfs_nfsiodnew(0); out: mtx_unlock(&nfs_iod_mtx); return (0); @@ -147,7 +147,7 @@ sysctl_iodmax(SYSCTL_HANDLER_ARGS) */ iod = nfs_numasync - 1; for (i = 0; i < nfs_numasync - nfs_iodmax; i++) { - if (nfs_iodwant[iod]) + if (nfs_iodwant[iod] == NFSIOD_AVAILABLE) wakeup(&nfs_iodwant[iod]); iod--; } @@ -160,7 +160,7 @@ SYSCTL_PROC(_vfs_nfs, OID_AUTO, iodmax, CTLTYPE_UINT | CTLFLAG_RW, 0, "Max number of nfsiod kthreads"); int -nfs_nfsiodnew(void) +nfs_nfsiodnew(int set_iodwant) { int error, i; int newiod; @@ -176,12 +176,17 @@ nfs_nfsiodnew(void) } if (newiod == -1) return (-1); + if (set_iodwant > 0) + nfs_iodwant[i] = NFSIOD_CREATED_FOR_NFS_ASYNCIO; mtx_unlock(&nfs_iod_mtx); error = kproc_create(nfssvc_iod, nfs_asyncdaemon + i, NULL, RFHIGHPID, 0, "nfsiod %d", newiod); mtx_lock(&nfs_iod_mtx); - if (error) + if (error) { + if (set_iodwant > 0) + nfs_iodwant[i] = NFSIOD_NOT_AVAILABLE; return (-1); + } nfs_numasync++; return (newiod); } @@ -199,7 +204,7 @@ nfsiod_setup(void *dummy) nfs_iodmin = NFS_MAXASYNCDAEMON; for (i = 0; i < nfs_iodmin; i++) { - error = nfs_nfsiodnew(); + error = nfs_nfsiodnew(0); if (error == -1) panic("nfsiod_setup: nfs_nfsiodnew failed"); } @@ -236,7 +241,8 @@ nfssvc_iod(void *instance) goto finish; if (nmp) nmp->nm_bufqiods--; - nfs_iodwant[myiod] = curthread->td_proc; + if (nfs_iodwant[myiod] == NFSIOD_NOT_AVAILABLE) + nfs_iodwant[myiod] = NFSIOD_AVAILABLE; nfs_iodmount[myiod] = NULL; /* * Always keep at least nfs_iodmin kthreads. @@ -303,7 +309,7 @@ finish: nfs_asyncdaemon[myiod] = 0; if (nmp) nmp->nm_bufqiods--; - nfs_iodwant[myiod] = NULL; + nfs_iodwant[myiod] = NFSIOD_NOT_AVAILABLE; nfs_iodmount[myiod] = NULL; /* Someone may be waiting for the last nfsiod to terminate. */ if (--nfs_numasync == 0) diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index 329294bae30..94cbe8448d4 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -347,7 +347,7 @@ nfs_init(struct vfsconf *vfsp) nfs_ticks = 1; /* Ensure async daemons disabled */ for (i = 0; i < NFS_MAXASYNCDAEMON; i++) { - nfs_iodwant[i] = NULL; + nfs_iodwant[i] = NFSIOD_NOT_AVAILABLE; nfs_iodmount[i] = NULL; } nfs_nhinit(); /* Init the nfsnode table */ @@ -375,7 +375,7 @@ nfs_uninit(struct vfsconf *vfsp) mtx_lock(&nfs_iod_mtx); nfs_iodmax = 0; for (i = 0; i < nfs_numasync; i++) - if (nfs_iodwant[i]) + if (nfs_iodwant[i] == NFSIOD_AVAILABLE) wakeup(&nfs_iodwant[i]); /* The last nfsiod to exit will wake us up when nfs_numasync hits 0 */ while (nfs_numasync) diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 6b13bb4573c..64953fe19cd 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -212,7 +212,7 @@ static int nfs_renameit(struct vnode *sdvp, struct componentname *scnp, * Global variables */ struct mtx nfs_iod_mtx; -struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; +enum nfsiod_state nfs_iodwant[NFS_MAXASYNCDAEMON]; struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON]; int nfs_numasync = 0; vop_advlock_t *nfs_advlock_p = nfs_dolock; diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index 402fc796023..46d1bd6cf6c 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -176,11 +176,24 @@ struct nfsnode { #define NFS_TIMESPEC_COMPARE(T1, T2) (((T1)->tv_sec != (T2)->tv_sec) || ((T1)->tv_nsec != (T2)->tv_nsec)) +/* + * NFS iod threads can be in one of these three states once spawned. + * NFSIOD_NOT_AVAILABLE - Cannot be assigned an I/O operation at this time. + * NFSIOD_AVAILABLE - Available to be assigned an I/O operation. + * NFSIOD_CREATED_FOR_NFS_ASYNCIO - Newly created for nfs_asyncio() and + * will be used by the thread that called nfs_asyncio(). + */ +enum nfsiod_state { + NFSIOD_NOT_AVAILABLE = 0, + NFSIOD_AVAILABLE = 1, + NFSIOD_CREATED_FOR_NFS_ASYNCIO = 2, +}; + /* * Queue head for nfsiod's */ extern TAILQ_HEAD(nfs_bufq, buf) nfs_bufq; -extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; +extern enum nfsiod_state nfs_iodwant[NFS_MAXASYNCDAEMON]; extern struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON]; #if defined(_KERNEL) From 1d0daf9e447a792a8e43377426858a02b734b9a3 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Wed, 10 Feb 2010 20:35:20 +0000 Subject: [PATCH 1412/2592] MFC of r201700 | mckusick | 2010-01-06 This corrects a bug that manifested itself as identifying the last cylinder group of a UFS1 filesystem as bad. The error was in the check and not in the cylinder group itself. So even though fsck fixed the cylinder group correctly, it was still endlessly reported as bad. This bug first appeared in 8.0 so does not apply to earlier releases. PR: 141992 Reported by: Dan Strick --- sbin/fsck_ffs/fsutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c index 4ce2ef20dac..68d113a3f61 100644 --- a/sbin/fsck_ffs/fsutil.c +++ b/sbin/fsck_ffs/fsutil.c @@ -436,7 +436,7 @@ check_cgmagic(int cg, struct cg *cgp) ((sblock.fs_magic == FS_UFS1_MAGIC && cgp->cg_old_niblk == sblock.fs_ipg && cgp->cg_ndblk <= sblock.fs_fpg && - cgp->cg_old_ncyl == sblock.fs_old_cpg) || + cgp->cg_old_ncyl <= sblock.fs_old_cpg) || (sblock.fs_magic == FS_UFS2_MAGIC && cgp->cg_niblk == sblock.fs_ipg && cgp->cg_ndblk <= sblock.fs_fpg && From 7733cf8fffadd4b286f7ed03e7748ee70e36433d Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Thu, 11 Feb 2010 18:34:06 +0000 Subject: [PATCH 1413/2592] MFC a number of changes from head for ISP (203478,203463,203444,202418,201758, 201408,201325,200089,198822,197373,197372,197214,196162). Since one of those changes was a semicolon cleanup from somebody else, this touches a lot more. --- sys/cam/scsi/scsi_ses.c | 4 +- sys/cam/scsi/scsi_targ_bh.c | 2 +- sys/compat/linux/linux_futex.c | 2 +- sys/dev/aac/aac.c | 2 +- sys/dev/agp/agp.c | 2 +- sys/dev/amd/amd.c | 2 +- sys/dev/amr/amr.c | 2 +- sys/dev/arcmsr/arcmsr.c | 2 +- sys/dev/ata/ata-raid.c | 2 +- sys/dev/ata/chipsets/ata-ahci.c | 6 +- sys/dev/ata/chipsets/ata-siliconimage.c | 6 +- sys/dev/ath/ath_hal/ar5211/ar5211_reset.c | 2 +- .../ath/ath_hal/ar5212/ar5212_interrupts.c | 2 +- .../ath/ath_hal/ar5416/ar5416_interrupts.c | 2 +- sys/dev/bktr/bktr_i2c.c | 2 +- sys/dev/cs/if_cs.c | 2 +- sys/dev/cxgb/cxgb_sge.c | 2 +- sys/dev/de/if_de.c | 2 +- sys/dev/e1000/if_em.c | 2 +- sys/dev/fatm/if_fatm.c | 2 +- sys/dev/firewire/sbp.c | 6 +- sys/dev/hatm/if_hatm.c | 4 +- sys/dev/hptmv/entry.c | 2 +- sys/dev/if_ndis/if_ndis_usb.c | 2 +- sys/dev/iscsi/initiator/isc_sm.c | 2 +- sys/dev/isp/isp.c | 105 ++--- sys/dev/isp/isp_freebsd.c | 160 +++++-- sys/dev/isp/isp_freebsd.h | 4 +- sys/dev/isp/isp_library.c | 151 +++--- sys/dev/isp/isp_library.h | 8 +- sys/dev/isp/isp_pci.c | 16 +- sys/dev/isp/isp_sbus.c | 8 +- sys/dev/isp/isp_stds.h | 4 +- sys/dev/isp/isp_tpublic.h | 428 ------------------ sys/dev/isp/ispmbox.h | 32 +- sys/dev/isp/ispvar.h | 58 ++- sys/dev/ixgbe/ixgbe.c | 22 +- sys/dev/malo/if_malo.c | 2 +- sys/dev/mge/if_mge.c | 2 +- sys/dev/mxge/if_mxge.c | 30 +- sys/dev/patm/if_patm_intr.c | 2 +- sys/dev/pdq/if_fea.c | 2 +- sys/dev/safe/safe.c | 2 +- sys/dev/sound/pci/maestro3.c | 2 +- sys/dev/ste/if_ste.c | 2 +- sys/dev/trm/trm.c | 2 +- sys/dev/usb/controller/musb_otg.c | 2 +- sys/dev/usb/storage/umass.c | 4 +- sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c | 2 +- sys/isa/pnp.c | 2 +- sys/kern/kern_fail.c | 4 +- sys/kern/subr_firmware.c | 2 +- sys/mips/adm5120/if_admsw.c | 2 +- sys/mips/mips/elf_machdep.c | 2 +- sys/net/flowtable.c | 2 +- sys/net80211/ieee80211_node.c | 2 +- sys/netinet/libalias/alias_db.c | 2 +- sys/netinet/libalias/alias_mod.c | 2 +- sys/netinet/sctp_asconf.c | 2 +- sys/netinet/sctputil.c | 2 +- sys/nfsclient/bootp_subr.c | 2 +- sys/pci/ncr.c | 2 +- sys/powerpc/aim/mmu_oea.c | 6 +- sys/powerpc/aim/mmu_oea64.c | 6 +- sys/powerpc/booke/pmap.c | 4 +- sys/rpc/clnt_dg.c | 2 +- sys/ufs/ffs/ffs_snapshot.c | 2 +- sys/xen/xenbus/xenbus_probe.c | 2 +- 68 files changed, 441 insertions(+), 725 deletions(-) delete mode 100644 sys/dev/isp/isp_tpublic.h diff --git a/sys/cam/scsi/scsi_ses.c b/sys/cam/scsi/scsi_ses.c index 825b883c17c..2275654c141 100644 --- a/sys/cam/scsi/scsi_ses.c +++ b/sys/cam/scsi/scsi_ses.c @@ -1555,7 +1555,7 @@ ses_encode(char *b, int amt, uint8_t *ep, int elt, int elm, SesComStat *sp) */ static int safte_getconfig(ses_softc_t *); -static int safte_rdstat(ses_softc_t *, int);; +static int safte_rdstat(ses_softc_t *, int); static int set_objstat_sel(ses_softc_t *, ses_objstat *, int); static int wrbuf16(ses_softc_t *, uint8_t, uint8_t, uint8_t, uint8_t, int); static void wrslot_stat(ses_softc_t *, int); @@ -2257,7 +2257,7 @@ safte_rdstat(ses_softc_t *ssc, int slpflg) ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_NOTAVAIL; ssc->ses_objmap[oid].encstat[1] = 0; ssc->ses_objmap[oid].encstat[2] = sdata[r]; - ssc->ses_objmap[oid].encstat[3] = 0;; + ssc->ses_objmap[oid].encstat[3] = 0; ssc->ses_objmap[oid++].svalid = 1; r++; } diff --git a/sys/cam/scsi/scsi_targ_bh.c b/sys/cam/scsi/scsi_targ_bh.c index 47b6e2b5957..b8c2379ff91 100644 --- a/sys/cam/scsi/scsi_targ_bh.c +++ b/sys/cam/scsi/scsi_targ_bh.c @@ -429,7 +429,7 @@ targbhdtor(struct cam_periph *periph) switch (softc->init_level) { case 0: - panic("targdtor - impossible init level");; + panic("targdtor - impossible init level"); case 1: /* FALLTHROUGH */ default: diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c index b9f570ba7b1..48422605599 100644 --- a/sys/compat/linux/linux_futex.c +++ b/sys/compat/linux/linux_futex.c @@ -493,7 +493,7 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) return (error); if (f == NULL) { td->td_retval[0] = 0; - return (error);; + return (error); } td->td_retval[0] = futex_wake(f, args->val); futex_put(f, NULL); diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 76f50e2a3d8..ea58895a2a6 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -553,7 +553,7 @@ aac_alloc(struct aac_softc *sc) 0, /* flags */ NULL, NULL, /* No locking needed */ &sc->aac_fib_dmat)) { - device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");; + device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n"); return (ENOMEM); } diff --git a/sys/dev/agp/agp.c b/sys/dev/agp/agp.c index db7856127f5..8d9369219e9 100644 --- a/sys/dev/agp/agp.c +++ b/sys/dev/agp/agp.c @@ -763,7 +763,7 @@ agp_allocate_user(device_t dev, agp_allocate *alloc) static int agp_deallocate_user(device_t dev, int id) { - struct agp_memory *mem = agp_find_memory(dev, id);; + struct agp_memory *mem = agp_find_memory(dev, id); if (mem) { AGP_FREE_MEMORY(dev, mem); diff --git a/sys/dev/amd/amd.c b/sys/dev/amd/amd.c index 53753994ec8..f4b3d80f5f2 100644 --- a/sys/dev/amd/amd.c +++ b/sys/dev/amd/amd.c @@ -1657,7 +1657,7 @@ amdhandlemsgreject(struct amd_softc *amd) tinfo_sync_period[pDCB->SyncPeriod - 4]; pDCB->tinfo.goal.offset = pDCB->SyncOffset; pDCB->tinfo.current.period = - tinfo_sync_period[pDCB->SyncPeriod - 4];; + tinfo_sync_period[pDCB->SyncPeriod - 4]; pDCB->tinfo.current.offset = pDCB->SyncOffset; /* diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c index 955c87947fe..5ccf9b8a1a5 100644 --- a/sys/dev/amr/amr.c +++ b/sys/dev/amr/amr.c @@ -221,7 +221,7 @@ amr_attach(struct amr_softc *sc) sc->amr_submit_command = amr_std_submit_command; sc->amr_get_work = amr_std_get_work; sc->amr_poll_command = amr_std_poll_command; - amr_std_attach_mailbox(sc);; + amr_std_attach_mailbox(sc); } #ifdef AMR_BOARD_INIT diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c index 0e6acbf190b..93466eb4a86 100644 --- a/sys/dev/arcmsr/arcmsr.c +++ b/sys/dev/arcmsr/arcmsr.c @@ -1940,7 +1940,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, switch (pccb->csio.cdb_io.cdb_bytes[0]) { case INQUIRY: { unsigned char inqdata[36]; - char *buffer=pccb->csio.data_ptr;; + char *buffer=pccb->csio.data_ptr; if (pccb->ccb_h.target_lun) { pccb->ccb_h.status |= CAM_SEL_TIMEOUT; diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index 7bc88b51e5f..1e976078f61 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -407,7 +407,7 @@ ata_raid_strategy(struct bio *bp) if (rdp->status & AR_S_REBUILDING) blk = ((lba / rdp->interleave) * rdp->width) * rdp->interleave + (rdp->interleave * (drv % rdp->width)) + - lba % rdp->interleave;; + lba % rdp->interleave; if (bp->bio_cmd == BIO_READ) { int src_online = diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c index 39c51523e76..6811c795c85 100644 --- a/sys/dev/ata/chipsets/ata-ahci.c +++ b/sys/dev/ata/chipsets/ata-ahci.c @@ -656,9 +656,9 @@ ata_ahci_pm_write(device_t dev, int port, int reg, u_int32_t value) ctp->cfis[3] = reg; ctp->cfis[7] = port | ATA_D_LBA; ctp->cfis[12] = value & 0xff; - ctp->cfis[4] = (value >> 8) & 0xff;; - ctp->cfis[5] = (value >> 16) & 0xff;; - ctp->cfis[6] = (value >> 24) & 0xff;; + ctp->cfis[4] = (value >> 8) & 0xff; + ctp->cfis[5] = (value >> 16) & 0xff; + ctp->cfis[6] = (value >> 24) & 0xff; ctp->cfis[15] = ATA_A_4BIT; if (ata_ahci_issue_cmd(dev, 0, 100)) { diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c index 066e9280e5d..85b0830c02c 100644 --- a/sys/dev/ata/chipsets/ata-siliconimage.c +++ b/sys/dev/ata/chipsets/ata-siliconimage.c @@ -716,9 +716,9 @@ ata_siiprb_pm_write(device_t dev, int port, int reg, u_int32_t value) prb->fis[3] = reg; prb->fis[7] = port; prb->fis[12] = value & 0xff; - prb->fis[4] = (value >> 8) & 0xff;; - prb->fis[5] = (value >> 16) & 0xff;; - prb->fis[6] = (value >> 24) & 0xff;; + prb->fis[4] = (value >> 8) & 0xff; + prb->fis[5] = (value >> 16) & 0xff; + prb->fis[6] = (value >> 24) & 0xff; if (ata_siiprb_issue_cmd(dev)) { device_printf(dev, "error writing PM port\n"); return ATA_E_ABORT; diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_reset.c b/sys/dev/ath/ath_hal/ar5211/ar5211_reset.c index 1ed6214bf29..438bf5c8d76 100644 --- a/sys/dev/ath/ath_hal/ar5211/ar5211_reset.c +++ b/sys/dev/ath/ath_hal/ar5211/ar5211_reset.c @@ -136,7 +136,7 @@ static void ar5211GetLowerUpperPcdacs(uint16_t pcdac, uint16_t channel, const PCDACS_EEPROM *pSrcStruct, uint16_t *pLowerPcdac, uint16_t *pUpperPcdac); -static void ar5211SetRfgain(struct ath_hal *, const GAIN_VALUES *);; +static void ar5211SetRfgain(struct ath_hal *, const GAIN_VALUES *); static void ar5211RequestRfgain(struct ath_hal *); static HAL_BOOL ar5211InvalidGainReadback(struct ath_hal *, GAIN_VALUES *); static HAL_BOOL ar5211IsGainAdjustNeeded(struct ath_hal *, const GAIN_VALUES *); diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c index b9cee9ab23b..47f9e7400f9 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c @@ -76,7 +76,7 @@ ar5212GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) isr = OS_REG_READ(ah, AR_ISR_RAC); if (isr == 0xffffffff) { *masked = 0; - return AH_FALSE;; + return AH_FALSE; } *masked = isr & HAL_INT_COMMON; diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c b/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c index 7b6f951175f..4b66d04fefa 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c @@ -104,7 +104,7 @@ ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) isr = OS_REG_READ(ah, AR_ISR_RAC); if (isr == 0xffffffff) { *masked = 0; - return AH_FALSE;; + return AH_FALSE; } *masked = isr & HAL_INT_COMMON; diff --git a/sys/dev/bktr/bktr_i2c.c b/sys/dev/bktr/bktr_i2c.c index 403225818ea..06a65473084 100644 --- a/sys/dev/bktr/bktr_i2c.c +++ b/sys/dev/bktr/bktr_i2c.c @@ -331,7 +331,7 @@ bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte) /* clear status bits */ OUTL(sc,BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE)); - OUTL(sc,BKTR_I2C_DATA_CTL, ((slave & 0xff) << 24) | (u_char)cmd);; + OUTL(sc,BKTR_I2C_DATA_CTL, ((slave & 0xff) << 24) | (u_char)cmd); BTI2C_DEBUG(printf("r%lx/", (u_long)(((slave & 0xff) << 24) | (u_char)cmd))); diff --git a/sys/dev/cs/if_cs.c b/sys/dev/cs/if_cs.c index 826f4adb3c6..8baaafd3bae 100644 --- a/sys/dev/cs/if_cs.c +++ b/sys/dev/cs/if_cs.c @@ -475,7 +475,7 @@ int cs_attach(device_t dev) { int error, media=0; - struct cs_softc *sc = device_get_softc(dev);; + struct cs_softc *sc = device_get_softc(dev); struct ifnet *ifp; sc->dev = dev; diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index d993df7dc32..88478b261a3 100644 --- a/sys/dev/cxgb/cxgb_sge.c +++ b/sys/dev/cxgb/cxgb_sge.c @@ -152,7 +152,7 @@ struct rx_desc { uint32_t len_gen; uint32_t gen2; uint32_t addr_hi; -} __packed;; +} __packed; struct rsp_desc { /* response queue descriptor */ struct rss_header rss_hdr; diff --git a/sys/dev/de/if_de.c b/sys/dev/de/if_de.c index c3d283988ae..56219574a20 100644 --- a/sys/dev/de/if_de.c +++ b/sys/dev/de/if_de.c @@ -2289,7 +2289,7 @@ tulip_identify_asante_nic(tulip_softc_t * const sc) mi->mi_gpr_length = 0; mi->mi_gpr_offset = 0; mi->mi_reset_length = 0; - mi->mi_reset_offset = 0;; + mi->mi_reset_offset = 0; mi->mi_phyaddr = TULIP_MII_NOPHY; for (idx = 20; idx > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx--) { diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 7a2dbad33de..eec23d0c5b7 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -4446,7 +4446,7 @@ em_free_receive_structures(struct adapter *adapter) static int em_rxeof(struct adapter *adapter, int count) { - struct ifnet *ifp = adapter->ifp;; + struct ifnet *ifp = adapter->ifp; struct mbuf *mp; u8 status, accept_frame = 0, eop = 0; u16 len, desc_len, prev_len_adj; diff --git a/sys/dev/fatm/if_fatm.c b/sys/dev/fatm/if_fatm.c index 47a6443801b..2138db25b85 100644 --- a/sys/dev/fatm/if_fatm.c +++ b/sys/dev/fatm/if_fatm.c @@ -860,7 +860,7 @@ fatm_getprom(struct fatm_softc *sc) NEXT_QUEUE_ENTRY(sc->cmdqueue.head, FATM_CMD_QLEN); q->error = 0; - q->cb = NULL;; + q->cb = NULL; H_SETSTAT(q->q.statp, FATM_STAT_PENDING); H_SYNCSTAT_PREWRITE(sc, q->q.statp); diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c index 02ceb784e98..0b9d1fa96e0 100644 --- a/sys/dev/firewire/sbp.c +++ b/sys/dev/firewire/sbp.c @@ -1573,7 +1573,7 @@ END_DEBUG bcopy(&sbp_cmd_status->s_keydep[0], &sense->sense_key_spec[0], 3); - ocb->ccb->csio.scsi_status = sbp_cmd_status->status;; + ocb->ccb->csio.scsi_status = sbp_cmd_status->status; ocb->ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; /* @@ -2148,7 +2148,7 @@ sbp_free_target(struct sbp_target *target) } STAILQ_INIT(&target->xferlist); free(target->luns, M_SBP); - target->num_lun = 0;; + target->num_lun = 0; target->luns = NULL; target->fwdev = NULL; } @@ -2318,7 +2318,7 @@ sbp_timeout(void *arg) sbp_cam_detach_target(target); if (target->luns != NULL) free(target->luns, M_SBP); - target->num_lun = 0;; + target->num_lun = 0; target->luns = NULL; target->fwdev = NULL; #endif diff --git a/sys/dev/hatm/if_hatm.c b/sys/dev/hatm/if_hatm.c index 85327643ba3..3f90063929a 100644 --- a/sys/dev/hatm/if_hatm.c +++ b/sys/dev/hatm/if_hatm.c @@ -836,7 +836,7 @@ hatm_init_rx_buffer_pool(struct hatm_softc *sc, uint32_t lbuf_addr; /* address of current buffer */ u_int i; - row_size = sc->bytes_per_row;; + row_size = sc->bytes_per_row; row_addr = start * row_size; lbuf_size = sc->cells_per_lbuf * 48; lbufs_per_row = sc->cells_per_row / sc->cells_per_lbuf; @@ -889,7 +889,7 @@ hatm_init_tx_buffer_pool(struct hatm_softc *sc, uint32_t lbuf_addr; /* address of current buffer */ u_int i; - row_size = sc->bytes_per_row;; + row_size = sc->bytes_per_row; row_addr = start * row_size; lbuf_size = sc->cells_per_lbuf * 48; lbufs_per_row = sc->cells_per_row / sc->cells_per_lbuf; diff --git a/sys/dev/hptmv/entry.c b/sys/dev/hptmv/entry.c index 843281a6bd5..bce7458130a 100644 --- a/sys/dev/hptmv/entry.c +++ b/sys/dev/hptmv/entry.c @@ -1341,7 +1341,7 @@ init_adapter(IAL_ADAPTER_T *pAdapter) #endif &pAdapter->io_dma_parent /* tag */)) { - return ENXIO;; + return ENXIO; } diff --git a/sys/dev/if_ndis/if_ndis_usb.c b/sys/dev/if_ndis/if_ndis_usb.c index be03919cc8a..e4152bd268b 100644 --- a/sys/dev/if_ndis/if_ndis_usb.c +++ b/sys/dev/if_ndis/if_ndis_usb.c @@ -204,7 +204,7 @@ ndisusb_detach(device_t self) { int i; struct ndis_softc *sc = device_get_softc(self); - struct ndisusb_ep *ne;; + struct ndisusb_ep *ne; sc->ndisusb_status |= NDISUSB_STATUS_DETACH; diff --git a/sys/dev/iscsi/initiator/isc_sm.c b/sys/dev/iscsi/initiator/isc_sm.c index 3f4f377b95a..ec9d34695af 100644 --- a/sys/dev/iscsi/initiator/isc_sm.c +++ b/sys/dev/iscsi/initiator/isc_sm.c @@ -399,7 +399,7 @@ ism_recv(isc_session_t *sp, pduq_t *pq) if(sp->flags & ISC_STALLED) { sdebug(4, "window opened: max=0x%x exp=0x%x opcode=0x%x cmd=0x%x cws=%d.", sn->maxCmd, sn->expCmd, bhs->opcode, sn->cmd, sp->cws); - sp->flags &= ~ISC_STALLED;; + sp->flags &= ~ISC_STALLED; } } } diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index a4a40a87acc..15983a3ed99 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -63,7 +63,6 @@ __FBSDID("$FreeBSD$"); /* * General defines */ - #define MBOX_DELAY_COUNT 1000000 / 100 #define ISP_MARK_PORTDB(a, b, c) \ isp_prt(isp, ISP_LOGSANCFG, \ @@ -695,7 +694,7 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults) mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - isp_prt(isp, ISP_LOGERR, "NOP ommand failed (%x)", mbs.param[0]); + isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]); ISP_RESET0(isp); return; } @@ -1547,24 +1546,18 @@ isp_fibre_init(ispsoftc_t *isp) } icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp); - if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || - icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) { - isp_prt(isp, ISP_LOGERR, - "bad frame length (%d) from NVRAM- using %d", - DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN); + if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) { + isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN); icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN; } icbp->icb_maxalloc = fcp->isp_maxalloc; if (icbp->icb_maxalloc < 1) { - isp_prt(isp, ISP_LOGERR, - "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc); + isp_prt(isp, ISP_LOGERR, "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc); icbp->icb_maxalloc = 16; } icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp); if (icbp->icb_execthrottle < 1) { - isp_prt(isp, ISP_LOGERR, - "bad execution throttle of %d- using %d", - DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE); + isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE); icbp->icb_execthrottle = ICB_DFLT_THROTTLE; } icbp->icb_retry_delay = fcp->isp_retry_delay; @@ -1658,18 +1651,18 @@ isp_fibre_init(ispsoftc_t *isp) /* * For 22XX > 2.1.26 && 23XX, set some options. - * XXX: Probably okay for newer 2100 f/w too. */ if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) { - /* - * Turn on LIP F8 async event (1) - * Turn on generate AE 8013 on all LIP Resets (2) - * Disable LIP F7 switching (8) - */ MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0); - mbs.param[1] = 0xb; + mbs.param[1] = IFCOPT1_DISF7SWTCH|IFCOPT1_LIPASYNC|IFCOPT1_LIPF8; mbs.param[2] = 0; mbs.param[3] = 0; + if (ISP_FW_NEWER_THAN(isp, 3, 16, 0)) { + mbs.param[1] |= IFCOPT1_EQFQASYNC|IFCOPT1_CTIO_RETRY; + if (fcp->role & ISP_ROLE_TARGET) { + mbs.param[3] = IFCOPT3_NOPRLI; + } + } isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; @@ -2093,8 +2086,7 @@ isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition) * or via FABRIC LOGIN/FABRIC LOGOUT for other cards. */ static int -isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, - int flags, int gs) +isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags, int gs) { mbreg_t mbs; uint8_t q[QENTRY_LEN]; @@ -2771,21 +2763,15 @@ isp_pdb_sync(ispsoftc_t *isp, int chan) /* * Make sure we're okay for doing this right now. */ - if (fcp->isp_loopstate != LOOP_PDB_RCVD && - fcp->isp_loopstate != LOOP_FSCAN_DONE && - fcp->isp_loopstate != LOOP_LSCAN_DONE) { - isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d", - fcp->isp_loopstate); + if (fcp->isp_loopstate != LOOP_PDB_RCVD && fcp->isp_loopstate != LOOP_FSCAN_DONE && fcp->isp_loopstate != LOOP_LSCAN_DONE) { + isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d", fcp->isp_loopstate); return (-1); } - if (fcp->isp_topo == TOPO_FL_PORT || - fcp->isp_topo == TOPO_NL_PORT || - fcp->isp_topo == TOPO_N_PORT) { + if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT || fcp->isp_topo == TOPO_N_PORT) { if (fcp->isp_loopstate < LOOP_LSCAN_DONE) { if (isp_scan_loop(isp, chan) != 0) { - isp_prt(isp, ISP_LOGWARN, - "isp_pdb_sync: isp_scan_loop failed"); + isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: isp_scan_loop failed"); return (-1); } } @@ -2794,15 +2780,13 @@ isp_pdb_sync(ispsoftc_t *isp, int chan) if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) { if (fcp->isp_loopstate < LOOP_FSCAN_DONE) { if (isp_scan_fabric(isp, chan) != 0) { - isp_prt(isp, ISP_LOGWARN, - "isp_pdb_sync: isp_scan_fabric failed"); + isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: isp_scan_fabric failed"); return (-1); } } } - isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, - "Chan %d Synchronizing PDBs", chan); + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d Synchronizing PDBs", chan); fcp->isp_loopstate = LOOP_SYNCING_PDB; @@ -2831,11 +2815,7 @@ isp_pdb_sync(ispsoftc_t *isp, int chan) lp->state = FC_PORTDB_STATE_NIL; isp_async(isp, ISPASYNC_DEV_GONE, chan, lp); if (lp->autologin == 0) { - (void) isp_plogx(isp, chan, lp->handle, - lp->portid, - PLOGX_FLG_CMD_LOGO | - PLOGX_FLG_IMPLICIT | - PLOGX_FLG_FREE_NPHDL, 0); + (void) isp_plogx(isp, chan, lp->handle, lp->portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 0); } else { lp->autologin = 0; } @@ -3081,8 +3061,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan) for (i = 0; i < MAX_FC_TARG; i++) { lp = &fcp->portdb[i]; - if (lp->state == FC_PORTDB_STATE_NIL || - lp->target_mode) { + if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) { continue; } if (lp->node_wwn != tmp.node_wwn) { @@ -3600,8 +3579,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { lp = &fcp->portdb[dbidx]; - if (lp->state != FC_PORTDB_STATE_PROBATIONAL || - lp->target_mode) { + if (lp->state != FC_PORTDB_STATE_PROBATIONAL || lp->target_mode) { continue; } if (lp->portid == portid) { @@ -3838,8 +3816,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) if (fcp->portdb[dbidx].target_mode) { continue; } - if (fcp->portdb[dbidx].node_wwn == wwnn && - fcp->portdb[dbidx].port_wwn == wwpn) { + if (fcp->portdb[dbidx].node_wwn == wwnn && fcp->portdb[dbidx].port_wwn == wwpn) { break; } } @@ -4425,7 +4402,7 @@ isp_start(XS_T *xs) *tptr = 0x1999; } - if (isp_save_xs(isp, xs, &handle)) { + if (isp_allocate_xs(isp, xs, &handle)) { isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers"); XS_SETERR(xs, HBA_BOTCH); return (CMD_EAGAIN); @@ -5171,8 +5148,8 @@ again: } } - if ((sp->req_handle != ISP_SPCL_HANDLE) && (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1)) { - isp_prt(isp, ISP_LOGERR, "bad request handle %d (type 0x%x)", sp->req_handle, etype); + if (!ISP_VALID_HANDLE(isp, sp->req_handle)) { + isp_prt(isp, ISP_LOGERR, "bad request handle 0x%x (iocb type 0x%x)", sp->req_handle, etype); ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ ISP_WRITE(isp, isp->isp_respoutrp, optr); continue; @@ -5186,14 +5163,13 @@ again: */ if (etype != RQSTYPE_RESPONSE) { isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype); - } else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED && sp->req_handle != ISP_SPCL_HANDLE) { + } else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED) { isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts); } ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ ISP_WRITE(isp, isp->isp_respoutrp, optr); continue; } - isp_destroy_handle(isp, sp->req_handle); if (req_status_flags & RQSTF_BUS_RESET) { XS_SETERR(xs, HBA_BUSRESET); ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1); @@ -5329,6 +5305,7 @@ again: if (XS_XFRLEN(xs)) { ISP_DMAFREE(isp, xs, sp->req_handle); } + isp_destroy_handle(isp, sp->req_handle); if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) || ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) || @@ -5689,16 +5666,19 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) * commands that complete (with no apparent error) after * we receive a LIP. This has been observed mostly on * Local Loop topologies. To be safe, let's just mark - * all active commands as dead. + * all active initiator commands as dead. */ if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) { int i, j; for (i = j = 0; i < isp->isp_maxcmds; i++) { XS_T *xs; - xs = isp->isp_xflist[i]; - if (xs == NULL) { + isp_hdl_t *hdp; + + hdp = &isp->isp_xflist[i]; + if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) { continue; } + xs = hdp->cmd; if (XS_CHANNEL(xs) != chan) { continue; } @@ -6666,8 +6646,8 @@ isp_mbox_continue(ispsoftc_t *isp) ptr = isp->isp_mbxworkp; switch (isp->isp_lastmbxcmd) { case MBOX_WRITE_RAM_WORD: - mbs.param[1] = isp->isp_mbxwrk1++;; - mbs.param[2] = *ptr++;; + mbs.param[1] = isp->isp_mbxwrk1++; + mbs.param[2] = *ptr++; break; case MBOX_READ_RAM_WORD: *ptr++ = isp->isp_mboxtmp[2]; @@ -6677,7 +6657,7 @@ isp_mbox_continue(ispsoftc_t *isp) offset = isp->isp_mbxwrk1; offset |= isp->isp_mbxwrk8 << 16; - mbs.param[2] = *ptr++;; + mbs.param[2] = *ptr++; mbs.param[1] = offset; mbs.param[8] = offset >> 16; isp->isp_mbxwrk1 = ++offset; @@ -8293,6 +8273,8 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data) if ((wwn >> 60) == 0) { wwn |= (((uint64_t) 2)<< 60); } + } else { + wwn = fcp->isp_wwpn_nvram & ~((uint64_t) 0xfff << 48); } } else { wwn &= ~((uint64_t) 0xfff << 48); @@ -8358,11 +8340,6 @@ isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data) ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data)); wwn = ISP2400_NVRAM_PORT_NAME(nvram_data); - if (wwn) { - if ((wwn >> 60) != 2 && (wwn >> 60) != 5) { - wwn = 0; - } - } fcp->isp_wwpn_nvram = wwn; wwn = ISP2400_NVRAM_NODE_NAME(nvram_data); @@ -8371,6 +8348,10 @@ isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data) wwn = 0; } } + if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) { + wwn = fcp->isp_wwpn_nvram; + wwn &= ~((uint64_t) 0xfff << 48); + } fcp->isp_wwnn_nvram = wwn; if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) { diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 3d20b097e58..cd6ec099816 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -133,33 +133,37 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan) } #endif } else { + fcparam *fcp = FCPARAM(isp, chan); struct isp_fc *fc = ISP_FC_PC(isp, chan); + ISP_LOCK(isp); fc->sim = sim; fc->path = path; fc->isp = isp; + fc->ready = 1; callout_init_mtx(&fc->ldt, &isp->isp_osinfo.lock, 0); callout_init_mtx(&fc->gdt, &isp->isp_osinfo.lock, 0); - - if (THREAD_CREATE(isp_kthread, fc, &fc->kproc, 0, 0, "%s: fc_thrd%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) { - xpt_free_path(fc->path); - ISP_LOCK(isp); - xpt_bus_deregister(cam_sim_path(fc->sim)); - ISP_UNLOCK(isp); - cam_sim_free(fc->sim, FALSE); - } /* * We start by being "loop down" if we have an initiator role */ - ISP_LOCK(isp); - if ((FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR) && fc->ldt_running == 0) { + if (fcp->role & ISP_ROLE_INITIATOR) { isp_freeze_loopdown(isp, chan, "isp_attach"); - fc->ldt_running = 1; callout_reset(&fc->ldt, isp_quickboot_time * hz, isp_ldt, fc); isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Starting Initial Loop Down Timer @ %lu", (unsigned long) time_uptime); } ISP_UNLOCK(isp); + if (THREAD_CREATE(isp_kthread, fc, &fc->kproc, 0, 0, "%s: fc_thrd%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) { + xpt_free_path(fc->path); + ISP_LOCK(isp); + if (callout_active(&fc->ldt)) { + callout_stop(&fc->ldt); + } + xpt_bus_deregister(cam_sim_path(fc->sim)); + ISP_UNLOCK(isp); + cam_sim_free(fc->sim, FALSE); + return (ENOMEM); + } #ifdef ISP_INTERNAL_TARGET ISP_SET_PC(isp, chan, proc_active, 1); if (THREAD_CREATE(isp_target_thread_fc, fc, &fc->target_proc, 0, 0, "%s: isp_test_tgt%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) { @@ -343,6 +347,17 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td) break; } if (IS_FC(isp)) { + /* + * We don't really support dual role at present on FC cards. + * + * We should, but a bunch of things are currently broken, + * so don't allow it. + */ + if (nr == ISP_ROLE_BOTH) { + isp_prt(isp, ISP_LOGERR, "cannot support dual role at present"); + retval = EINVAL; + break; + } *(int *)addr = FCPARAM(isp, chan)->role; #ifdef ISP_INTERNAL_TARGET ISP_LOCK(isp); @@ -1638,7 +1653,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb) cto->ct_timeout = 10; } - if (isp_save_xs_tgt(isp, ccb, &handle)) { + if (isp_allocate_xs_tgt(isp, ccb, &handle)) { xpt_print(ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__); ccb->ccb_h.status = CAM_REQUEUE_REQ; goto out; @@ -2943,8 +2958,8 @@ isp_target_mark_aborted_early(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id) #ifdef ISP_INTERNAL_TARGET // #define ISP_FORCE_TIMEOUT 1 -#define ISP_TEST_WWNS 1 -#define ISP_TEST_SEPARATE_STATUS 1 +// #define ISP_TEST_WWNS 1 +// #define ISP_TEST_SEPARATE_STATUS 1 #define ccb_data_offset ppriv_field0 #define ccb_atio ppriv_ptr1 @@ -3819,21 +3834,41 @@ isp_watchdog(void *arg) isp = XS_ISP(xs); handle = isp_find_handle(isp, xs); - if (handle) { + if (handle != ISP_HANDLE_FREE) { /* - * Make sure the command is *really* dead before we - * release the handle (and DMA resources) for reuse. + * Try and make sure the command is really dead before + * we release the handle (and DMA resources) for reuse. + * + * If we are successful in aborting the command then + * we're done here because we'll get the command returned + * back separately. */ - (void) isp_control(isp, ISPCTL_ABORT_CMD, xs); + if (isp_control(isp, ISPCTL_ABORT_CMD, xs) == 0) { + return; + } /* - * After this point, the comamnd is really dead. + * Note that after calling the above, the command may in + * fact have been completed. + */ + xs = isp_find_xs(isp, handle); + + /* + * If the command no longer exists, then we won't + * be able to find the xs again with this handle. + */ + if (xs == NULL) { + return; + } + + /* + * After this point, the command is really dead. */ if (XS_XFRLEN(xs)) { ISP_DMAFREE(isp, xs, handle); } isp_destroy_handle(isp, handle); - xpt_print(xs->ccb_h.path, "watchdog timeout for handle 0x%x\n", handle); + isp_prt(isp, ISP_LOGERR, "%s: timeout for handle 0x%x", __func__, handle); XS_SETERR(xs, CAM_CMD_TIMEOUT); isp_done(xs); } @@ -3924,12 +3959,12 @@ isp_gdt(void *arg) isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, tgt, "Gone Device Timeout"); isp_make_gone(isp, chan, tgt); } - if (more_to_do) { - fc->gdt_running = 1; - callout_reset(&fc->gdt, hz, isp_gdt, fc); - } else { - isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d stopping Gone Device Timer", chan); - fc->gdt_running = 0; + if (fc->ready) { + if (more_to_do) { + callout_reset(&fc->gdt, hz, isp_gdt, fc); + } else { + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d stopping Gone Device Timer", chan); + } } } @@ -4006,6 +4041,7 @@ isp_kthread(void *arg) ispsoftc_t *isp = fc->isp; int chan = fc - isp->isp_osinfo.pc.fc; int slp = 0; + mtx_lock(&isp->isp_osinfo.lock); for (;;) { @@ -4238,6 +4274,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb) isp_disable_lun(isp, ccb); } break; + case XPT_IMMED_NOTIFY: case XPT_IMMEDIATE_NOTIFY: /* Add Immediate Notify Resource */ case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */ { @@ -4287,11 +4324,19 @@ isp_action(struct cam_sim *sim, union ccb *ccb) SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle); ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n", ((struct ccb_immediate_notify *)ccb)->seq_id, tptr->inot_count); + } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) { + tptr->inot_count++; + SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle); + ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n", + ((struct ccb_immediate_notify *)ccb)->seq_id, tptr->inot_count); } rls_lun_statep(isp, tptr); ccb->ccb_h.status = CAM_REQ_INPROG; break; } + case XPT_NOTIFY_ACK: + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + break; case XPT_NOTIFY_ACKNOWLEDGE: /* notify ack */ { tstate_t *tptr; @@ -4601,10 +4646,21 @@ isp_prt(isp, ISP_LOGALL, "Setting Channel %d wwns to 0x%jx 0x%jx", bus, fcp->isp } break; case KNOB_ROLE_BOTH: +#if 0 if (fcp->role != ISP_ROLE_BOTH) { rchange = 1; newrole = ISP_ROLE_BOTH; } +#else + /* + * We don't really support dual role at present on FC cards. + * + * We should, but a bunch of things are currently broken, + * so don't allow it. + */ + isp_prt(isp, ISP_LOGERR, "cannot support dual role at present"); + ccb->ccb_h.status = CAM_REQ_INVALID; +#endif break; } if (rchange) { @@ -4771,6 +4827,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) char *msg = NULL; target_id_t tgt; fcportdb_t *lp; + struct isp_fc *fc; struct cam_path *tmppath; va_list ap; @@ -4855,7 +4912,6 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) /* FALLTHROUGH */ case ISPASYNC_LOOP_DOWN: { - struct isp_fc *fc; if (msg == NULL) { msg = "LOOP Down"; } @@ -4863,20 +4919,21 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) bus = va_arg(ap, int); va_end(ap); - FCPARAM(isp, bus)->link_active = 1; + FCPARAM(isp, bus)->link_active = 0; fc = ISP_FC_PC(isp, bus); - /* - * We don't do any simq freezing if we are only in target mode - */ - if (fc->role & ISP_ROLE_INITIATOR) { - if (fc->path) { - isp_freeze_loopdown(isp, bus, msg); - } - if (fc->ldt_running == 0) { - fc->ldt_running = 1; - callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc); - isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "starting Loop Down Timer @ %lu", (unsigned long) time_uptime); + if (cmd == ISPASYNC_LOOP_DOWN && fc->ready) { + /* + * We don't do any simq freezing if we are only in target mode + */ + if (fc->role & ISP_ROLE_INITIATOR) { + if (fc->path) { + isp_freeze_loopdown(isp, bus, msg); + } + if (!callout_active(&fc->ldt)) { + callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc); + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "starting Loop Down Timer @ %lu", (unsigned long) time_uptime); + } } } isp_prt(isp, ISP_LOGINFO, "Chan %d: %s", bus, msg); @@ -4886,6 +4943,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) va_start(ap, cmd); bus = va_arg(ap, int); va_end(ap); + fc = ISP_FC_PC(isp, bus); /* * Now we just note that Loop has come up. We don't * actually do anything because we're waiting for a @@ -4893,8 +4951,8 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) * thread to look at the state of the loop again. */ FCPARAM(isp, bus)->link_active = 1; - ISP_FC_PC(isp, bus)->loop_dead = 0; - ISP_FC_PC(isp, bus)->loop_down_time = 0; + fc->loop_dead = 0; + fc->loop_down_time = 0; isp_prt(isp, ISP_LOGINFO, "Chan %d Loop UP", bus); break; case ISPASYNC_DEV_ARRIVED: @@ -4902,8 +4960,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) bus = va_arg(ap, int); lp = va_arg(ap, fcportdb_t *); va_end(ap); + fc = ISP_FC_PC(isp, bus); lp->reserved = 0; - if ((ISP_FC_PC(isp, bus)->role & ISP_ROLE_INITIATOR) && (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) { + if ((fc->role & ISP_ROLE_INITIATOR) && (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) { int dbidx = lp - FCPARAM(isp, bus)->portdb; int i; @@ -4936,6 +4995,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) bus = va_arg(ap, int); lp = va_arg(ap, fcportdb_t *); va_end(ap); + fc = ISP_FC_PC(isp, bus); lp->reserved = 0; if (isp_change_is_bad) { lp->state = FC_PORTDB_STATE_NIL; @@ -4982,6 +5042,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) bus = va_arg(ap, int); lp = va_arg(ap, fcportdb_t *); va_end(ap); + fc = ISP_FC_PC(isp, bus); /* * If this has a virtual target and we haven't marked it * that we're going to have isp_gdt tell the OS it's gone, @@ -4994,10 +5055,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) lp->reserved = 1; lp->new_reserved = ISP_FC_PC(isp, bus)->gone_device_time; lp->state = FC_PORTDB_STATE_ZOMBIE; - if (ISP_FC_PC(isp, bus)->gdt_running == 0) { + if (fc->ready && !callout_active(&fc->gdt)) { isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d starting Gone Device Timer", bus); - ISP_FC_PC(isp, bus)->gdt_running = 1; - callout_reset(&ISP_FC_PC(isp, bus)->gdt, hz, isp_gdt, ISP_FC_PC(isp, bus)); + callout_reset(&fc->gdt, hz, isp_gdt, fc); } tgt = lp->dev_map_idx - 1; isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, roles[lp->roles], "gone zombie at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); @@ -5022,6 +5082,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) nlstate = reason = 0; } va_end(ap); + fc = ISP_FC_PC(isp, bus); if (evt == ISPASYNC_CHANGE_PDB) { msg = "Chan %d Port Database Changed"; @@ -5034,16 +5095,15 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) /* * If the loop down timer is running, cancel it. */ - if (ISP_FC_PC(isp, bus)->ldt_running) { + if (fc->ready && callout_active(&fc->ldt)) { isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Stopping Loop Down Timer @ %lu", (unsigned long) time_uptime); - ISP_FC_PC(isp, bus)->ldt_running = 0; - callout_stop(&ISP_FC_PC(isp, bus)->ldt); + callout_stop(&fc->ldt); } isp_prt(isp, ISP_LOGINFO, msg, bus); - if (ISP_FC_PC(isp, bus)->role & ISP_ROLE_INITIATOR) { + if (fc->role & ISP_ROLE_INITIATOR) { isp_freeze_loopdown(isp, bus, msg); } - wakeup(ISP_FC_PC(isp, bus)); + wakeup(fc); break; } #ifdef ISP_TARGET_MODE diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h index 2988e3095ee..29425940c05 100644 --- a/sys/dev/isp/isp_freebsd.h +++ b/sys/dev/isp/isp_freebsd.h @@ -177,9 +177,9 @@ struct isp_fc { hysteresis : 8, role : 2, gdt_running : 1, - ldt_running : 1, loop_dead : 1, - fcbsy : 1; + fcbsy : 1, + ready : 1; struct callout ldt; /* loop down timer */ struct callout gdt; /* gone device timer */ #ifdef ISP_TARGET_MODE diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c index 5e6430905bf..efe30c0a3d4 100644 --- a/sys/dev/isp/isp_library.c +++ b/sys/dev/isp/isp_library.c @@ -246,65 +246,70 @@ copy_and_sync: } int -isp_save_xs(ispsoftc_t *isp, XS_T *xs, uint32_t *handlep) +isp_allocate_xs(ispsoftc_t *isp, XS_T *xs, uint32_t *handlep) { - uint16_t i, j; + isp_hdl_t *hdp; - for (j = isp->isp_lasthdls, i = 0; i < isp->isp_maxcmds; i++) { - if (isp->isp_xflist[j] == NULL) { - break; - } - if (++j == isp->isp_maxcmds) { - j = 0; - } - } - if (i == isp->isp_maxcmds) { + hdp = isp->isp_xffree; + if (hdp == NULL) { return (-1); } - isp->isp_xflist[j] = xs; - *handlep = j+1; - if (++j == isp->isp_maxcmds) { - j = 0; - } - isp->isp_lasthdls = (uint32_t)j; + isp->isp_xffree = hdp->cmd; + hdp->cmd = xs; + hdp->handle = (hdp - isp->isp_xflist); + hdp->handle |= (ISP_HANDLE_INITIATOR << ISP_HANDLE_USAGE_SHIFT); + hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT); + *handlep = hdp->handle; return (0); } XS_T * isp_find_xs(ispsoftc_t *isp, uint32_t handle) { - if (handle < 1 || handle > (uint32_t) isp->isp_maxcmds) { + if (!ISP_VALID_INI_HANDLE(isp, handle)) { + isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle); return (NULL); - } else { - return (isp->isp_xflist[handle - 1]); } + return (isp->isp_xflist[(handle & ISP_HANDLE_CMD_MASK)].cmd); } uint32_t isp_find_handle(ispsoftc_t *isp, XS_T *xs) { - uint16_t i; + uint32_t i, foundhdl = ISP_HANDLE_FREE; + if (xs != NULL) { for (i = 0; i < isp->isp_maxcmds; i++) { - if (isp->isp_xflist[i] == xs) { - return ((uint32_t) (i+1)); + if (isp->isp_xflist[i].cmd != xs) { + continue; } + foundhdl = isp->isp_xflist[i].handle; + break; } } - return (0); + return (foundhdl); } uint32_t -isp_handle_index(uint32_t handle) +isp_handle_index(ispsoftc_t *isp, uint32_t handle) { - return (handle - 1); + if (!ISP_VALID_HANDLE(isp, handle)) { + return (handle & ISP_HANDLE_CMD_MASK); + } else { + isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle); + return (ISP_BAD_HANDLE_INDEX); + } } void isp_destroy_handle(ispsoftc_t *isp, uint32_t handle) { - if (handle > 0 && handle <= (uint32_t) isp->isp_maxcmds) { - isp->isp_xflist[handle - 1] = NULL; + if (!ISP_VALID_INI_HANDLE(isp, handle)) { + isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle); + } else { + isp->isp_xflist[(handle & ISP_HANDLE_CMD_MASK)].handle = ISP_HANDLE_FREE; + isp->isp_xflist[(handle & ISP_HANDLE_CMD_MASK)].cmd = isp->isp_xffree; + isp->isp_xffree = &isp->isp_xflist[(handle & ISP_HANDLE_CMD_MASK)]; } } @@ -617,60 +622,54 @@ isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role) void isp_clear_commands(ispsoftc_t *isp) { - XS_T *xs; - uint32_t tmp, handle; + uint32_t tmp; + isp_hdl_t *hdp; #ifdef ISP_TARGET_MODE isp_notify_t notify; #endif for (tmp = 0; isp->isp_xflist && tmp < isp->isp_maxcmds; tmp++) { - xs = isp->isp_xflist[tmp]; - if (xs == NULL) { - continue; - } - handle = isp_find_handle(isp, xs); - if (handle == 0) { + XS_T *xs; + + hdp = &isp->isp_xflist[tmp]; + if (hdp->handle == ISP_HANDLE_FREE) { continue; } + xs = hdp->cmd; if (XS_XFRLEN(xs)) { - ISP_DMAFREE(isp, xs, handle); + ISP_DMAFREE(isp, xs, hdp->handle); XS_SET_RESID(xs, XS_XFRLEN(xs)); } else { XS_SET_RESID(xs, 0); } - isp_destroy_handle(isp, handle); + hdp->handle = 0; + hdp->cmd = NULL; XS_SETERR(xs, HBA_BUSRESET); isp_done(xs); } #ifdef ISP_TARGET_MODE for (tmp = 0; isp->isp_tgtlist && tmp < isp->isp_maxcmds; tmp++) { uint8_t local[QENTRY_LEN]; - - xs = isp->isp_tgtlist[tmp]; - if (xs == NULL) { + hdp = &isp->isp_tgt_xflist[tmp]; + if (hdp->handle == ISP_HANDLE_FREE) { continue; } - handle = isp_find_tgt_handle(isp, xs); - if (handle == 0) { - continue; - } - ISP_DMAFREE(isp, xs, handle); - + ISP_DMAFREE(isp, hdp->cmd, hdp->handle); ISP_MEMZERO(local, QENTRY_LEN); if (IS_24XX(isp)) { ct7_entry_t *ctio = (ct7_entry_t *) local; - ctio->ct_syshandle = handle; + ctio->ct_syshandle = hdp->handle; ctio->ct_nphdl = CT_HBA_RESET; ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO7; } else if (IS_FC(isp)) { ct2_entry_t *ctio = (ct2_entry_t *) local; - ctio->ct_syshandle = handle; + ctio->ct_syshandle = hdp->handle; ctio->ct_status = CT_HBA_RESET; ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO2; } else { ct_entry_t *ctio = (ct_entry_t *) local; - ctio->ct_syshandle = handle & 0xffff; - ctio->ct_status = CT_HBA_RESET & 0xff;; + ctio->ct_syshandle = hdp->handle & 0xffff; + ctio->ct_status = CT_HBA_RESET & 0xff; ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO; } isp_async(isp, ISPASYNC_TARGET_ACTION, local); @@ -2229,59 +2228,59 @@ isp_send_tgt_cmd(ispsoftc_t *isp, void *fqe, void *segp, uint32_t nsegs, uint32_ } int -isp_save_xs_tgt(ispsoftc_t *isp, void *xs, uint32_t *handlep) +isp_allocate_xs_tgt(ispsoftc_t *isp, void *xs, uint32_t *handlep) { - int i; + isp_hdl_t *hdp; - for (i = 0; i < (int) isp->isp_maxcmds; i++) { - if (isp->isp_tgtlist[i] == NULL) { - break; - } - } - if (i == isp->isp_maxcmds) { + hdp = isp->isp_tgtfree; + if (hdp == NULL) { return (-1); } - isp->isp_tgtlist[i] = xs; - *handlep = (i+1) | 0x8000; + isp->isp_tgtfree = hdp->cmd; + hdp->cmd = xs; + hdp->handle = (hdp - isp->isp_tgtlist); + hdp->handle |= (ISP_HANDLE_TARGET << ISP_HANDLE_USAGE_SHIFT); + hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT); + *handlep = hdp->handle; return (0); } void * isp_find_xs_tgt(ispsoftc_t *isp, uint32_t handle) { - if (handle == 0 || IS_TARGET_HANDLE(handle) == 0 || (handle & ISP_HANDLE_MASK) > isp->isp_maxcmds) { - isp_prt(isp, ISP_LOGERR, "bad handle %u in isp_find_xs_tgt", handle); + if (!ISP_VALID_TGT_HANDLE(isp, handle)) { + isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle); return (NULL); - } else { - return (isp->isp_tgtlist[(handle & ISP_HANDLE_MASK) - 1]); } + return (isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].cmd); } uint32_t isp_find_tgt_handle(ispsoftc_t *isp, void *xs) { - int i; + uint32_t i, foundhdl = ISP_HANDLE_FREE; + if (xs != NULL) { for (i = 0; i < isp->isp_maxcmds; i++) { - if (isp->isp_tgtlist[i] == xs) { - uint32_t handle = i; - handle += 1; - handle &= ISP_HANDLE_MASK; - handle |= 0x8000; - return (handle); + if (isp->isp_tgtlist[i].cmd != xs) { + continue; } + foundhdl = isp->isp_tgtlist[i].handle; + break; } } - return (0); + return (foundhdl); } void isp_destroy_tgt_handle(ispsoftc_t *isp, uint32_t handle) { - if (handle == 0 || IS_TARGET_HANDLE(handle) == 0 || (handle & ISP_HANDLE_MASK) > isp->isp_maxcmds) { - isp_prt(isp, ISP_LOGERR, "bad handle in isp_destroy_tgt_handle"); + if (!ISP_VALID_TGT_HANDLE(handle)) { + isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle); } else { - isp->isp_tgtlist[(handle & ISP_HANDLE_MASK) - 1] = NULL; + isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].handle = ISP_HANDLE_FREE; + isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].cmd = isp->isp_tgtfree; + isp->isp_tgtfree = &isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)]; } } diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h index 9a9e39721cd..b055dd827c7 100644 --- a/sys/dev/isp/isp_library.h +++ b/sys/dev/isp/isp_library.h @@ -43,10 +43,10 @@ int isp_send_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_t); * * These handles are associate with a command. */ -int isp_save_xs(ispsoftc_t *, XS_T *, uint32_t *); +int isp_allocate_xs(ispsoftc_t *, XS_T *, uint32_t *); XS_T * isp_find_xs(ispsoftc_t *, uint32_t); uint32_t isp_find_handle(ispsoftc_t *, XS_T *); -uint32_t isp_handle_index(uint32_t); +uint32_t isp_handle_index(ispsoftc_t *, uint32_t); void isp_destroy_handle(ispsoftc_t *, uint32_t); /* @@ -156,9 +156,7 @@ void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *); int isp_send_tgt_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_t, void *, uint32_t); -#define IS_TARGET_HANDLE(x) ((x) & 0x8000) - -int isp_save_xs_tgt(ispsoftc_t *, void *, uint32_t *); +int isp_allocate_xs_tgt(ispsoftc_t *, void *, uint32_t *); void *isp_find_xs_tgt(ispsoftc_t *, uint32_t); uint32_t isp_find_tgt_handle(ispsoftc_t *, void *); void isp_destroy_tgt_handle(ispsoftc_t *, uint32_t); diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 47dd350887e..4eb2e0c9094 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -1516,17 +1516,21 @@ isp_pci_mbxdma(ispsoftc_t *isp) return (1); } - len = sizeof (XS_T **) * isp->isp_maxcmds; - isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + len = sizeof (isp_hdl_t) * isp->isp_maxcmds; + isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); if (isp->isp_xflist == NULL) { free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); ISP_LOCK(isp); isp_prt(isp, ISP_LOGERR, "cannot alloc xflist array"); return (1); } + for (len = 0; len < isp->isp_maxcmds - 1; len++) { + isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1]; + } + isp->isp_xffree = isp->isp_xflist; #ifdef ISP_TARGET_MODE - len = sizeof (void **) * isp->isp_maxcmds; - isp->isp_tgtlist = (void **) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + len = sizeof (isp_hdl_t *) * isp->isp_maxcmds; + isp->isp_tgtlist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); if (isp->isp_tgtlist == NULL) { free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); free(isp->isp_xflist, M_DEVBUF); @@ -1534,6 +1538,10 @@ isp_pci_mbxdma(ispsoftc_t *isp) isp_prt(isp, ISP_LOGERR, "cannot alloc tgtlist array"); return (1); } + for (len = 0; len < isp->isp_maxcmds - 1; len++) { + isp->isp_tgtlist[len].cmd = &isp->isp_tgtlist[len+1]; + } + isp->isp_tgtfree = isp->isp_tgtlist; #endif /* diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c index a50d0f20ed8..e2dd78fed96 100644 --- a/sys/dev/isp/isp_sbus.c +++ b/sys/dev/isp/isp_sbus.c @@ -455,13 +455,17 @@ isp_sbus_mbxdma(ispsoftc_t *isp) return (1); } - len = sizeof (XS_T **) * isp->isp_maxcmds; - isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + len = sizeof (isp_hdl_t *) * isp->isp_maxcmds; + isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); if (isp->isp_xflist == NULL) { isp_prt(isp, ISP_LOGERR, "cannot alloc xflist array"); ISP_LOCK(isp); return (1); } + for (len = 0; len < isp->isp_maxcmds - 1; len++) { + isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1]; + } + isp->isp_xffree = isp->isp_xflist; len = sizeof (bus_dmamap_t) * isp->isp_maxcmds; if (isp_dma_tag_create(BUS_DMA_ROOTARG(ISP_SBD(isp)), 1, diff --git a/sys/dev/isp/isp_stds.h b/sys/dev/isp/isp_stds.h index d0a98121a37..2ed66cb5f37 100644 --- a/sys/dev/isp/isp_stds.h +++ b/sys/dev/isp/isp_stds.h @@ -31,7 +31,6 @@ */ #ifndef _ISP_STDS_H #define _ISP_STDS_H - /* * FC Frame Header * @@ -147,6 +146,7 @@ typedef struct { #define FCP_SNSLEN_VALID 0x02 #define FCP_RSPLEN_VALID 0x01 +#define FCP_MAX_RSPLEN 0x08 /* * FCP Response Code Definitions * Source: NCITS T10, Project 1144D, Revision 08 (aka FCP2r08) @@ -159,6 +159,8 @@ typedef struct { #define FCP_RSPNS_EROFS 3 #define FCP_RSPNS_TMF_REJECT 4 #define FCP_RSPNS_TMF_FAILED 5 +#define FCP_RSPNS_TMF_SUCCEEDED 8 +#define FCP_RSPNS_TMF_INCORRECT_LUN 9 /* unconverted miscellany */ diff --git a/sys/dev/isp/isp_tpublic.h b/sys/dev/isp/isp_tpublic.h deleted file mode 100644 index b16440b0748..00000000000 --- a/sys/dev/isp/isp_tpublic.h +++ /dev/null @@ -1,428 +0,0 @@ -/* $FreeBSD$ */ -/*- - * Copyright (c) 1997-2007 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. - * 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 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 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. - */ -/* - * Host Adapter Public Target Interface Structures && Routines - */ - -#ifndef _ISP_TPUBLIC_H -#define _ISP_TPUBLIC_H 1 - -/* - * Action codes set by the MD target driver for - * the external layer to figure out what to do with. - */ -typedef enum { - QOUT_HBA_REG=0, /* the argument is a pointer to a hba_register_t */ - QOUT_ENABLE, /* the argument is a pointer to a enadis_t */ - QOUT_DISABLE, /* the argument is a pointer to a enadis_t */ - QOUT_TMD_START, /* the argument is a pointer to a tmd_cmd_t */ - QOUT_TMD_DONE, /* the argument is a pointer to a tmd_cmd_t */ - QOUT_NOTIFY, /* the argument is a pointer to a tmd_notify_t */ - QOUT_HBA_UNREG /* the argument is a pointer to a hba_register_t */ -} tact_e; - -/* - * Action codes set by the external layer for the - * MD driver to figure out what to do with. - */ -typedef enum { - QIN_HBA_REG=99, /* the argument is a pointer to a hba_register_t */ - QIN_GETINFO, /* the argument is a pointer to a info_t */ - QIN_SETINFO, /* the argument is a pointer to a info_t */ - QIN_GETDLIST, /* the argument is a pointer to a fc_dlist_t */ - QIN_ENABLE, /* the argument is a pointer to a enadis_t */ - QIN_DISABLE, /* the argument is a pointer to a enadis_t */ - QIN_TMD_CONT, /* the argument is a pointer to a tmd_cmd_t */ - QIN_TMD_FIN, /* the argument is a pointer to a tmd_cmd_t */ - QIN_NOTIFY_ACK, /* the argument is a pointer to a tmd_notify_t */ - QIN_HBA_UNREG, /* the argument is a pointer to a hba_register_t */ -} qact_e; - -/* - * This structure is used to register to other software modules the - * binding of an HBA identifier, driver name and instance and the - * lun width capapbilities of this target driver. It's up to each - * platform to figure out how it wants to do this, but a typical - * sequence would be for the MD layer to find some external module's - * entry point and start by sending a QOUT_HBA_REG with info filled - * in, and the external module to call back with a QIN_HBA_REG that - * passes back the corresponding information. - */ -#define QR_VERSION 16 -typedef struct { - /* NB: tags from here to r_version must never change */ - void * r_identity; - void (*r_action)(qact_e, void *); - char r_name[8]; - int r_inst; - int r_version; - uint32_t r_locator; - uint32_t r_nchannels; - enum { R_FC, R_SPI } r_type; - void * r_private; -} hba_register_t; - -/* - * An information structure that is used to get or set per-channel transport layer parameters. - */ -typedef struct { - void * i_identity; - enum { I_FC, I_SPI } i_type; - int i_channel; - int i_error; - union { - struct { - uint64_t wwnn_nvram; - uint64_t wwpn_nvram; - uint64_t wwnn; - uint64_t wwpn; - } fc; - struct { - int iid; - } spi; - } i_id; -} info_t; - -/* - * An information structure to return a list of logged in WWPNs. FC specific. - */ -typedef struct { - void * d_identity; - int d_channel; - int d_error; - int d_count; - uint64_t * d_wwpns; -} fc_dlist_t; -/* - * Notify structure - */ -typedef enum { - NT_ABORT_TASK=0x1000, - NT_ABORT_TASK_SET, - NT_CLEAR_ACA, - NT_CLEAR_TASK_SET, - NT_LUN_RESET, - NT_TARGET_RESET, - NT_BUS_RESET, - NT_LIP_RESET, - NT_LINK_UP, - NT_LINK_DOWN, - NT_LOGOUT, - NT_HBA_RESET -} tmd_ncode_t; - -typedef struct tmd_notify { - void * nt_hba; /* HBA tag */ - uint64_t nt_iid; /* inititator id */ - uint64_t nt_tgt; /* target id */ - uint16_t nt_lun; /* logical unit */ - uint16_t : 15, - nt_need_ack : 1; /* this notify needs an ACK */ - uint64_t nt_tagval; /* tag value */ - uint32_t nt_channel; /* channel id */ - tmd_ncode_t nt_ncode; /* action */ - void * nt_lreserved; - void * nt_hreserved; -} tmd_notify_t; -#define LUN_ANY 0xffff -#define TGT_ANY ((uint64_t) -1) -#define INI_ANY ((uint64_t) -1) -#define TAG_ANY ((uint64_t) 0) -#define MATCH_TMD(tmd, iid, lun, tag) \ - ( \ - (tmd) && \ - (iid == INI_ANY || iid == tmd->cd_iid) && \ - (lun == LUN_ANY || lun == tmd->cd_lun) && \ - (tag == TAG_ANY || tag == tmd->cd_tagval) \ - ) - -/* - * A word about ENABLE/DISABLE: the argument is a pointer to a enadis_t - * with en_hba, en_iid, en_chan, en_tgt and en_lun filled out. - * - * If an error occurs in either enabling or disabling the described lun - * cd_error is set with an appropriate non-zero value. - */ -typedef struct { - void * en_private; /* for outer layer usage */ - void * en_hba; /* HBA tag */ - uint64_t en_iid; /* initiator ID */ - uint64_t en_tgt; /* target id */ - uint16_t en_lun; /* logical unit */ - uint16_t en_chan; /* channel on card */ - int en_error; -} enadis_t; - -/* - * Suggested Software Target Mode Command Handling structure. - * - * A note about terminology: - * - * MD stands for "Machine Dependent". - * - * This driver is structured in three layers: Outer MD, core, and inner MD. - * The latter also is bus dependent (i.e., is cognizant of PCI bus issues - * as well as platform issues). - * - * - * "Outer Layer" means "Other Module" - * - * Some additional module that actually implements SCSI target command - * policy is the recipient of incoming commands and the source of the - * disposition for them. - * - * The command structure below is one suggested possible MD command structure, - * but since the handling of thbis is entirely in the MD layer, there is - * no explicit or implicit requirement that it be used. - * - * The cd_private tag should be used by the MD layer to keep a free list - * of these structures. Code outside of this driver can then use this - * to identify it's own unit structures. That is, when not on the MD - * layer's freelist, the MD layer should shove into it the identifier - * that the outer layer has for it- passed in on an initial QIN_HBA_REG - * call (see below). - * - * The cd_hba tag is a tag that uniquely identifies the HBA this target - * mode command is coming from. The outer layer has to pass this back - * unchanged to avoid chaos. - * - * The cd_iid, cd_tgt, cd_lun and cd_port tags are used to identify the - * id of the initiator who sent us a command, the target claim to be, the - * lun on the target we claim to be, and the port instance (for multiple - * port host adapters) that this applies to (consider it an extra port - * parameter). The iid, tgt and lun values are deliberately chosen to be - * fat so that, for example, World Wide Names can be used instead of - * the units that the firmware uses (in the case where the MD - * layer maintains a port database, for example). - * - * The cd_tagtype field specifies what kind of command tag type, if - * any, has been sent with the command. Note that the Outer Layer - * still needs to pass the tag handle through unchanged even - * if the tag type is CD_UNTAGGED. - * - * The cd_cdb contains storage for the passed in command descriptor block. - * There is no need to define length as the callee should be able to - * figure this out. - * - * The tag cd_lflags are the flags set by the MD driver when it gets - * command incoming or when it needs to inform any outside entities - * that the last requested action failed. - * - * The tag cd_hflags should be set by any outside software to indicate - * the validity of sense and status fields (defined below) and to indicate - * the direction data is expected to move. It is an error to have both - * CDFH_DATA_IN and CDFH_DATA_OUT set. - * - * If the CDFH_STSVALID flag is set, the command should be completed (after - * sending any data and/or status). If CDFH_SNSVALID is set and the MD layer - * can also handle sending the associated sense data (either back with an - * FCP RESPONSE IU for Fibre Channel or otherwise automatically handling a - * REQUEST SENSE from the initator for this target/lun), the MD layer will - * set the CDFL_SENTSENSE flag on successful transmission of the sense data. - * It is an error for the CDFH_SNSVALID bit to be set and CDFH_STSVALID not - * to be set. It is an error for the CDFH_SNSVALID be set and the associated - * SCSI status (cd_scsi_status) not be set to CHECK CONDITON. - * - * The tag cd_data points to a data segment to either be filled or - * read from depending on the direction of data movement. The tag - * is undefined if no data direction is set. The MD layer and outer - * layers must agree on the meaning of cd_data and it is specifically - * not defined here. - * - * The tag cd_totlen is the total data amount expected to be moved - * over the life of the command. It may be set by the MD layer, possibly - * from the datalen field of an FCP CMND IU unit. If it shows up in the outer - * layers set to zero and the CDB indicates data should be moved, the outer - * layer should set it to the amount expected to be moved. - * - * The tag cd_resid should be the total residual of data not transferred. - * The outer layers need to set this at the begining of command processing - * to equal cd_totlen. As data is successfully moved, this value is decreased. - * At the end of a command, any nonzero residual indicates the number of bytes - * requested by the command but not moved. - * - * The tag cd_xfrlen is the length of the currently active data transfer. - * This allows several interations between any outside software and the - * MD layer to move data. - * - * The reason that total length and total residual have to be tracked - * is to keep track of relative offset. - * - * The tags cd_sense and cd_scsi_status are pretty obvious. - * - * The tag cd_error is to communicate between the MD layer and outer software - * the current error conditions. - * - * The tag cd_lreserved, cd_hreserved are scratch areas for use for the MD - * and outer layers respectively. - * - */ - -#ifndef TMD_CDBLEN -#define TMD_CDBLEN 16 -#endif -#ifndef TMD_SENSELEN -#define TMD_SENSELEN 18 -#endif -#ifndef QCDS -#define QCDS (sizeof (void *)) -#endif - -typedef struct tmd_cmd { - void * cd_private; /* private data pointer */ - void * cd_hba; /* HBA tag */ - void * cd_data; /* 'pointer' to data */ - uint64_t cd_iid; /* initiator ID */ - uint64_t cd_tgt; /* target id */ - uint8_t cd_lun[8]; /* logical unit */ - uint64_t cd_tagval; /* tag value */ - uint32_t cd_channel; /* channel index */ - uint32_t cd_lflags; /* flags lower level sets */ - uint32_t cd_hflags; /* flags higher level sets */ - uint32_t cd_totlen; /* total data load */ - uint32_t cd_resid; /* total data residual */ - uint32_t cd_xfrlen; /* current data load */ - int32_t cd_error; /* current error */ - uint8_t cd_tagtype; /* tag type */ - uint8_t cd_scsi_status; - uint8_t cd_sense[TMD_SENSELEN]; - uint8_t cd_cdb[TMD_CDBLEN]; - union { - void * ptrs[QCDS / sizeof (void *)]; - uint64_t llongs[QCDS / sizeof (uint64_t)]; - uint32_t longs[QCDS / sizeof (uint32_t)]; - uint16_t shorts[QCDS / sizeof (uint16_t)]; - uint8_t bytes[QCDS]; - } cd_lreserved[4], cd_hreserved[4]; -} tmd_cmd_t; - -/* defined tags */ -#define CD_UNTAGGED 0 -#define CD_SIMPLE_TAG 1 -#define CD_ORDERED_TAG 2 -#define CD_HEAD_TAG 3 -#define CD_ACA_TAG 4 - -#ifndef TMD_SIZE -#define TMD_SIZE (sizeof (tmd_cmd_t)) -#endif - -#define L0LUN_TO_FLATLUN(lptr) ((((lptr)[0] & 0x3f) << 8) | ((lptr)[1])) -#define FLATLUN_TO_L0LUN(lptr, lun) \ - (lptr)[1] = lun & 0xff; \ - if (sizeof (lun) == 1) { \ - (lptr)[0] = 0; \ - } else { \ - uint16_t nl = lun; \ - if (nl == LUN_ANY) { \ - (lptr)[0] = (nl >> 8) & 0xff; \ - } else if (nl < 256) { \ - (lptr)[0] = 0; \ - } else { \ - (lptr)[0] = 0x40 | ((nl >> 8) & 0x3f); \ - } \ - } \ - memset(&(lptr)[2], 0, 6) - -/* - * Note that NODISC (obviously) doesn't apply to non-SPI transport. - * - * Note that knowing the data direction and lengh at the time of receipt of - * a command from the initiator is a feature only of Fibre Channel. - * - * The CDFL_BIDIR is in anticipation of the adoption of some newer - * features required by OSD. - * - * The principle selector for MD layer to know whether data is to - * be transferred in any QOUT_TMD_CONT call is cd_xfrlen- the - * flags CDFH_DATA_IN and CDFH_DATA_OUT define which direction. - */ -#define CDFL_SNSVALID 0x01 /* sense data (from f/w) good */ -#define CDFL_SENTSTATUS 0x02 /* last action sent status */ -#define CDFL_DATA_IN 0x04 /* target (us) -> initiator (them) */ -#define CDFL_DATA_OUT 0x08 /* initiator (them) -> target (us) */ -#define CDFL_BIDIR 0x0C /* bidirectional data */ -#define CDFL_ERROR 0x10 /* last action ended in error */ -#define CDFL_NODISC 0x20 /* disconnects disabled */ -#define CDFL_SENTSENSE 0x40 /* last action sent sense data */ -#define CDFL_BUSY 0x80 /* this command is not on a free list */ -#define CDFL_PRIVATE 0xFF000000 /* private layer flags */ - -#define CDFH_SNSVALID 0x01 /* sense data (from outer layer) good */ -#define CDFH_STSVALID 0x02 /* status valid */ -#define CDFH_DATA_IN 0x04 /* target (us) -> initiator (them) */ -#define CDFH_DATA_OUT 0x08 /* initiator (them) -> target (us) */ -#define CDFH_DATA_MASK 0x0C /* mask to cover data direction */ -#define CDFH_PRIVATE 0xFF000000 /* private layer flags */ - - -/* - * A word about the START/CONT/DONE/FIN dance: - * - * When the HBA is enabled for receiving commands, one may show up - * without notice. When that happens, the MD target mode driver - * gets a tmd_cmd_t, fills it with the info that just arrived, and - * calls the outer layer with a QOUT_TMD_START code and pointer to - * the tmd_cmd_t. - * - * The outer layer decodes the command, fetches data, prepares stuff, - * whatever, and starts by passing back the pointer with a QIN_TMD_CONT - * code which causes the MD target mode driver to generate CTIOs to - * satisfy whatever action needs to be taken. When those CTIOs complete, - * the MD target driver sends the pointer to the cmd_tmd_t back with - * a QOUT_TMD_DONE code. This repeats for as long as necessary. These - * may not be done in parallel- they are sequential operations. - * - * The outer layer signals it wants to end the command by settings within - * the tmd_cmd_t itself. When the final QIN_TMD_CONT is reported completed, - * the outer layer frees the tmd_cmd_t by sending the pointer to it - * back with a QIN_TMD_FIN code. - * - * The graph looks like: - * - * QOUT_TMD_START -> [ QIN_TMD_CONT -> QOUT_TMD_DONE ] * -> QIN_TMD_FIN. - * - */ - -/* - * Target handler functions. - * - * The MD target handler function (the outer layer calls this) - * should be be prototyped like: - * - * void target_action(qact_e, void *arg) - * - * The outer layer target handler function (the MD layer calls this) - * should be be prototyped like: - * - * void scsi_target_handler(tact_e, void *arg) - */ -#endif /* _ISP_TPUBLIC_H */ -/* - * vim:ts=4:sw=4:expandtab - */ diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h index 8f689379afa..eb3ab6381a1 100644 --- a/sys/dev/isp/ispmbox.h +++ b/sys/dev/isp/ispmbox.h @@ -26,6 +26,7 @@ * SUCH DAMAGE. * */ + /* * Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters. */ @@ -244,12 +245,38 @@ #define ASYNC_RIO_COMP 0x8042 #define ASYNC_RCV_ERR 0x8048 +/* + * Firmware Options. There are a lot of them. + * + * IFCOPTN - ISP Fibre Channel Option Word N + */ +#define IFCOPT1_EQFQASYNC (1 << 13) /* enable QFULL notification */ +#define IFCOPT1_EAABSRCVD (1 << 12) +#define IFCOPT1_RJTASYNC (1 << 11) /* enable 8018 notification */ +#define IFCOPT1_ENAPURE (1 << 10) +#define IFCOPT1_ENA8017 (1 << 7) +#define IFCOPT1_DISGPIO67 (1 << 6) +#define IFCOPT1_LIPLOSSIMM (1 << 5) +#define IFCOPT1_DISF7SWTCH (1 << 4) +#define IFCOPT1_CTIO_RETRY (1 << 3) +#define IFCOPT1_LIPASYNC (1 << 1) +#define IFCOPT1_LIPF8 (1 << 0) + +#define IFCOPT2_LOOPBACK (1 << 1) +#define IFCOPT2_ATIO3_ONLY (1 << 0) + +#define IFCOPT3_NOPRLI (1 << 4) /* disable automatic sending of PRLI on local loops */ +#define IFCOPT3_RNDASYNC (1 << 1) /* * 2.01.31 2200 Only. Need Bit 13 in Mailbox 1 for Set Firmware Options * mailbox command to enable this. */ #define ASYNC_QFULL_SENT 0x8049 +/* + * Needs to be enabled + */ +#define ASYNC_AUTO_PLOGI_RJT 0x8018 /* * 24XX only */ @@ -260,11 +287,6 @@ */ #define QENTRY_LEN 64 -/* - * Special Internal Handle for IOCBs - */ -#define ISP_SPCL_HANDLE 0xa5dead5a - /* * Command Structure Definitions */ diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index e568a1c9b76..5c8508c87c4 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -50,7 +50,7 @@ #include "ispmbox.h" #endif -#define ISP_CORE_VERSION_MAJOR 6 +#define ISP_CORE_VERSION_MAJOR 7 #define ISP_CORE_VERSION_MINOR 0 /* @@ -288,6 +288,53 @@ typedef struct { #define DOMAIN_CONTROLLER_BASE 0xFFFC00 #define DOMAIN_CONTROLLER_END 0xFFFCFF +/* + * Command Handles + * + * Most QLogic initiator or target have 32 bit handles associated with them. + * We want to have a quick way to index back and forth between a local SCSI + * command context and what the firmware is passing back to us. We also + * want to avoid working on stale information. This structure handles both + * at the expense of some local memory. + * + * The handle is architected thusly: + * + * 0 means "free handle" + * bits 0..12 index commands + * bits 13..15 bits index usage + * bits 16..31 contain a rolling sequence + * + * + */ +typedef struct { + void * cmd; /* associated command context */ + uint32_t handle; /* handle associated with this command */ +} isp_hdl_t; +#define ISP_HANDLE_FREE 0x00000000 +#define ISP_HANDLE_CMD_MASK 0x00001fff +#define ISP_HANDLE_USAGE_MASK 0x0000e000 +#define ISP_HANDLE_USAGE_SHIFT 13 +#define ISP_H2HT(hdl) ((hdl & ISP_HANDLE_USAGE_MASK) >> ISP_HANDLE_USAGE_SHIFT) +# define ISP_HANDLE_NONE 0 +# define ISP_HANDLE_INITIATOR 1 +# define ISP_HANDLE_TARGET 2 +#define ISP_HANDLE_SEQ_MASK 0xffff0000 +#define ISP_HANDLE_SEQ_SHIFT 16 +#define ISP_H2SEQ(hdl) ((hdl & ISP_HANDLE_SEQ_MASK) >> ISP_HANDLE_SEQ_SHIFT) +#define ISP_VALID_INI_HANDLE(c, hdl) \ + (ISP_H2HT(hdl) == ISP_HANDLE_INITIATOR && (hdl & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \ + ISP_H2SEQ(hdl) == ISP_H2SEQ((c)->isp_xflist[hdl & ISP_HANDLE_CMD_MASK].handle)) +#ifdef ISP_TARGET_MODE +#define ISP_VALID_TGT_HANDLE(c, hdl) \ + (ISP_H2HT(hdl) == ISP_HANDLE_TARGET && (hdl & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \ + ISP_H2SEQ(hdl) == ISP_H2SEQ((c)->isp_tgtlist[hdl & ISP_HANDLE_CMD_MASK].handle)) +#define ISP_VALID_HANDLE(c, hdl) \ + (ISP_VALID_INI_HANDLE((c), hdl) || ISP_VALID_TGT_HANDLE((c), hdl)) +#else +#define ISP_VALID_HANDLE ISP_VALID_INI_HANDLE +#endif +#define ISP_BAD_HANDLE_INDEX 0xffffffff + /* * FC Port Database entry. @@ -562,11 +609,11 @@ struct ispsoftc { isp_mboxbsy : 1, /* mailbox command active */ isp_state : 3, isp_nactive : 16; /* how many commands active */ + volatile mbreg_t isp_curmbx; /* currently active mailbox command */ volatile uint32_t isp_reqodx; /* index of last ISP pickup */ volatile uint32_t isp_reqidx; /* index of next request */ volatile uint32_t isp_residx; /* index of next result */ volatile uint32_t isp_resodx; /* index of next result */ - volatile uint32_t isp_lasthdls; /* last handle seed */ volatile uint32_t isp_obits; /* mailbox command output */ volatile uint32_t isp_serno; /* rolling serial number */ volatile uint16_t isp_mboxtmp[MAILBOX_STORAGE]; @@ -575,18 +622,21 @@ struct ispsoftc { volatile uint16_t isp_mbxwrk1; volatile uint16_t isp_mbxwrk2; volatile uint16_t isp_mbxwrk8; + volatile uint16_t isp_seqno; /* running sequence number */ void * isp_mbxworkp; /* * Active commands are stored here, indexed by handle functions. */ - XS_T **isp_xflist; + isp_hdl_t *isp_xflist; + isp_hdl_t *isp_xffree; #ifdef ISP_TARGET_MODE /* * Active target commands are stored here, indexed by handle functions. */ - void **isp_tgtlist; + isp_hdl_t *isp_tgtlist; + isp_hdl_t *isp_tgtfree; #endif /* diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index 23b185722b2..5284134ead2 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -4463,6 +4463,26 @@ ixgbe_handle_msf(void *context, int pending) return; } +#ifdef IXGBE_FDIR +/* +** Tasklet for reinitializing the Flow Director filter table +*/ +static void +ixgbe_reinit_fdir(void *context, int pending) +{ + struct adapter *adapter = context; + struct ifnet *ifp = adapter->ifp; + + if (adapter->fdir_reinit != 1) /* Shouldn't happen */ + return; + ixgbe_reinit_fdir_tables_82599(&adapter->hw); + adapter->fdir_reinit = 0; + /* Restart the interface */ + ifp->if_drv_flags |= IFF_DRV_RUNNING; + return; +} +#endif + /********************************************************************** * * Update the board statistics counters. @@ -4471,7 +4491,7 @@ ixgbe_handle_msf(void *context, int pending) static void ixgbe_update_stats_counters(struct adapter *adapter) { - struct ifnet *ifp = adapter->ifp;; + struct ifnet *ifp = adapter->ifp; struct ixgbe_hw *hw = &adapter->hw; u32 missed_rx = 0, bprc, lxon, lxoff, total; u64 total_missed_rx = 0; diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c index d77718b0d1e..4ccba30e3c7 100644 --- a/sys/dev/malo/if_malo.c +++ b/sys/dev/malo/if_malo.c @@ -2099,7 +2099,7 @@ malo_rx_proc(void *arg, int npending) * payload prior to constructing the header. */ m = bf->bf_m; - data = mtod(m, uint8_t *);; + data = mtod(m, uint8_t *); hdrlen = ieee80211_anyhdrsize(data + sizeof(uint16_t)); off = sizeof(uint16_t) + sizeof(struct ieee80211_frame_addr4); diff --git a/sys/dev/mge/if_mge.c b/sys/dev/mge/if_mge.c index 0188ae3b79f..30366ce8a4b 100644 --- a/sys/dev/mge/if_mge.c +++ b/sys/dev/mge/if_mge.c @@ -1144,7 +1144,7 @@ mge_intr_tx_locked(struct mge_softc *sc) break; sc->tx_desc_used_idx = - (++sc->tx_desc_used_idx) % MGE_TX_DESC_NUM;; + (++sc->tx_desc_used_idx) % MGE_TX_DESC_NUM; sc->tx_desc_used_count--; /* Update collision statistics */ diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c index fc8d0ae8996..19647b29a6f 100644 --- a/sys/dev/mxge/if_mxge.c +++ b/sys/dev/mxge/if_mxge.c @@ -3174,23 +3174,23 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, bytes = rx_ring_entries * sizeof (*ss->rx_small.shadow); ss->rx_small.shadow = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK); if (ss->rx_small.shadow == NULL) - return err;; + return err; bytes = rx_ring_entries * sizeof (*ss->rx_big.shadow); ss->rx_big.shadow = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK); if (ss->rx_big.shadow == NULL) - return err;; + return err; /* allocate the rx host info rings */ bytes = rx_ring_entries * sizeof (*ss->rx_small.info); ss->rx_small.info = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK); if (ss->rx_small.info == NULL) - return err;; + return err; bytes = rx_ring_entries * sizeof (*ss->rx_big.info); ss->rx_big.info = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK); if (ss->rx_big.info == NULL) - return err;; + return err; /* allocate the rx busdma resources */ err = bus_dma_tag_create(sc->parent_dmat, /* parent */ @@ -3208,7 +3208,7 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, if (err != 0) { device_printf(sc->dev, "Err %d allocating rx_small dmat\n", err); - return err;; + return err; } err = bus_dma_tag_create(sc->parent_dmat, /* parent */ @@ -3235,7 +3235,7 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, if (err != 0) { device_printf(sc->dev, "Err %d allocating rx_big dmat\n", err); - return err;; + return err; } for (i = 0; i <= ss->rx_small.mask; i++) { err = bus_dmamap_create(ss->rx_small.dmat, 0, @@ -3243,7 +3243,7 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, if (err != 0) { device_printf(sc->dev, "Err %d rx_small dmamap\n", err); - return err;; + return err; } } err = bus_dmamap_create(ss->rx_small.dmat, 0, @@ -3251,7 +3251,7 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, if (err != 0) { device_printf(sc->dev, "Err %d extra rx_small dmamap\n", err); - return err;; + return err; } for (i = 0; i <= ss->rx_big.mask; i++) { @@ -3260,7 +3260,7 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, if (err != 0) { device_printf(sc->dev, "Err %d rx_big dmamap\n", err); - return err;; + return err; } } err = bus_dmamap_create(ss->rx_big.dmat, 0, @@ -3268,7 +3268,7 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, if (err != 0) { device_printf(sc->dev, "Err %d extra rx_big dmamap\n", err); - return err;; + return err; } /* now allocate TX resouces */ @@ -3288,7 +3288,7 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, sizeof (*ss->tx.req_list) * (ss->tx.max_desc + 4); ss->tx.req_bytes = malloc(bytes, M_DEVBUF, M_WAITOK); if (ss->tx.req_bytes == NULL) - return err;; + return err; /* ensure req_list entries are aligned to 8 bytes */ ss->tx.req_list = (mcp_kreq_ether_send_t *) ((unsigned long)(ss->tx.req_bytes + 7) & ~7UL); @@ -3298,13 +3298,13 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, ss->tx.seg_list = (bus_dma_segment_t *) malloc(bytes, M_DEVBUF, M_WAITOK); if (ss->tx.seg_list == NULL) - return err;; + return err; /* allocate the tx host info ring */ bytes = tx_ring_entries * sizeof (*ss->tx.info); ss->tx.info = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK); if (ss->tx.info == NULL) - return err;; + return err; /* allocate the tx busdma resources */ err = bus_dma_tag_create(sc->parent_dmat, /* parent */ @@ -3323,7 +3323,7 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, if (err != 0) { device_printf(sc->dev, "Err %d allocating tx dmat\n", err); - return err;; + return err; } /* now use these tags to setup dmamaps for each slot @@ -3334,7 +3334,7 @@ mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries, if (err != 0) { device_printf(sc->dev, "Err %d tx dmamap\n", err); - return err;; + return err; } } return 0; diff --git a/sys/dev/patm/if_patm_intr.c b/sys/dev/patm/if_patm_intr.c index a13125ae54c..79cb248966b 100644 --- a/sys/dev/patm/if_patm_intr.c +++ b/sys/dev/patm/if_patm_intr.c @@ -381,7 +381,7 @@ patm_feed_lbufs(struct patm_softc *sc) static void patm_intr_tsif(struct patm_softc *sc) { - struct idt_tsqe *tsqe = sc->tsq_next;; + struct idt_tsqe *tsqe = sc->tsq_next; struct idt_tsqe *prev = NULL; uint32_t stamp; diff --git a/sys/dev/pdq/if_fea.c b/sys/dev/pdq/if_fea.c index a2cb27fe7aa..ee49db7d4d3 100644 --- a/sys/dev/pdq/if_fea.c +++ b/sys/dev/pdq/if_fea.c @@ -140,7 +140,7 @@ pdq_eisa_probe (dev) u_int32_t maddr; u_int32_t msize; - u_int32_t eisa_id = eisa_get_id(dev);; + u_int32_t eisa_id = eisa_get_id(dev); desc = pdq_eisa_match(eisa_id); if (!desc) { diff --git a/sys/dev/safe/safe.c b/sys/dev/safe/safe.c index 736b329e8c2..ac970980449 100644 --- a/sys/dev/safe/safe.c +++ b/sys/dev/safe/safe.c @@ -1902,7 +1902,7 @@ safe_init_board(struct safe_softc *sc) { u_int32_t v, dwords; - v = READ_REG(sc, SAFE_PE_DMACFG);; + v = READ_REG(sc, SAFE_PE_DMACFG); v &=~ SAFE_PE_DMACFG_PEMODE; v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */ | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */ diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c index 8a57c8ccf85..51f9ee083cc 100644 --- a/sys/dev/sound/pci/maestro3.c +++ b/sys/dev/sound/pci/maestro3.c @@ -353,7 +353,7 @@ m3_wrcd(kobj_t kobj, void *devinfo, int regno, u_int32_t data) struct sc_info *sc = (struct sc_info *)devinfo; if (m3_wait(sc)) { device_printf(sc->dev, "m3_wrcd timed out.\n"); - return -1;; + return -1; } m3_wr_2(sc, CODEC_DATA, data); m3_wr_1(sc, CODEC_COMMAND, regno & 0x7f); diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c index 3fd43187c7c..78c0290b70a 100644 --- a/sys/dev/ste/if_ste.c +++ b/sys/dev/ste/if_ste.c @@ -1119,7 +1119,7 @@ ste_attach(device_t dev) */ if (ste_read_eeprom(sc, eaddr, STE_EEADDR_NODE0, ETHER_ADDR_LEN / 2)) { device_printf(dev, "failed to read station address\n"); - error = ENXIO;; + error = ENXIO; goto fail; } ste_sysctl_node(sc); diff --git a/sys/dev/trm/trm.c b/sys/dev/trm/trm.c index 222857fb7c3..26ab35239e7 100644 --- a/sys/dev/trm/trm.c +++ b/sys/dev/trm/trm.c @@ -2770,7 +2770,7 @@ trm_DoingSRB_Done(PACB pACB) xpt_done(pccb); psrb = psrb2; } - pdcb->GoingSRBCnt = 0;; + pdcb->GoingSRBCnt = 0; pdcb->pGoingSRB = NULL; pdcb = pdcb->pNextDCB; } diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index 987d3f65462..e4db7bf6857 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -1799,7 +1799,7 @@ musbotg_init(struct musbotg_softc *sc) MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, temp); fsize = MUSB2_READ_1(sc, MUSB2_REG_FSIZE); - frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16;; + frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16; ftx = (fsize & MUSB2_MASK_TX_FSIZE); DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u, DYN=%d\n", diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index 0b6ceffa536..4e57d82a1fd 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -3036,7 +3036,7 @@ umass_atapi_transform(struct umass_softc *sc, uint8_t *cmd_ptr, case 0xad: /* READ_DVD_STRUCTURE */ case 0xbb: /* SET_CD_SPEED */ case 0xe5: /* READ_TRACK_INFO_PHILIPS */ - break;; + break; case READ_12: case WRITE_12: @@ -3044,7 +3044,7 @@ umass_atapi_transform(struct umass_softc *sc, uint8_t *cmd_ptr, DPRINTF(sc, UDMASS_SCSI, "Unsupported ATAPI " "command 0x%02x - trying anyway\n", cmd_ptr[0]); - break;; + break; } bcopy(cmd_ptr, sc->sc_transfer.cmd_data, cmd_len); diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c index 80c95181ccc..20be557d771 100644 --- a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c +++ b/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c @@ -1117,7 +1117,7 @@ _xfs_strategy( } */ *ap) { daddr_t blkno; - struct buf *bp;; + struct buf *bp; struct bufobj *bo; struct vnode *vp; struct xfs_mount *xmp; diff --git a/sys/isa/pnp.c b/sys/isa/pnp.c index 6712f421acd..83ae10d2d69 100644 --- a/sys/isa/pnp.c +++ b/sys/isa/pnp.c @@ -480,7 +480,7 @@ pnp_create_devices(device_t parent, pnp_id *p, int csn, } resinfo = resp; resp += PNP_SRES_LEN(tag); - scanning -= PNP_SRES_LEN(tag);; + scanning -= PNP_SRES_LEN(tag); switch (PNP_SRES_NUM(tag)) { case PNP_TAG_LOGICAL_DEVICE: diff --git a/sys/kern/kern_fail.c b/sys/kern/kern_fail.c index 06dfc38c91c..d7601a90a44 100644 --- a/sys/kern/kern_fail.c +++ b/sys/kern/kern_fail.c @@ -452,7 +452,7 @@ parse_term(struct fail_point_entries *ents, char *p) } else if (*p == '*') { if (!units || decimal) return 0; - ent->fe_count = units;; + ent->fe_count = units; } else { return 0; @@ -497,7 +497,7 @@ parse_number(int *out_units, int *out_decimal, char *p) /* whole part */ old_p = p; - *out_units = strtol(p, &p, 10);; + *out_units = strtol(p, &p, 10); if (p == old_p && *p != '.') return 0; diff --git a/sys/kern/subr_firmware.c b/sys/kern/subr_firmware.c index 6a36c24e5f6..3f5e52b8d37 100644 --- a/sys/kern/subr_firmware.c +++ b/sys/kern/subr_firmware.c @@ -500,7 +500,7 @@ firmware_modevent(module_t mod, int type, void *unused) mtx_lock(&firmware_mtx); for (i = 0; i < FIRMWARE_MAX; i++) { fp = &firmware_table[i]; - fp->flags |= FW_UNLOAD;; + fp->flags |= FW_UNLOAD; } mtx_unlock(&firmware_mtx); taskqueue_enqueue(firmware_tq, &firmware_unload_task); diff --git a/sys/mips/adm5120/if_admsw.c b/sys/mips/adm5120/if_admsw.c index fff8930c2c5..623e92d1d80 100644 --- a/sys/mips/adm5120/if_admsw.c +++ b/sys/mips/adm5120/if_admsw.c @@ -527,7 +527,7 @@ admsw_attach(device_t dev) ifmedia_add(&sc->sc_ifmedia[i], IFM_ETHER|IFM_AUTO, 0, NULL); ifmedia_set(&sc->sc_ifmedia[i], IFM_ETHER|IFM_AUTO); - ifp = sc->sc_ifnet[i] = if_alloc(IFT_ETHER);; + ifp = sc->sc_ifnet[i] = if_alloc(IFT_ETHER); /* Setup interface parameters */ ifp->if_softc = sc; diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c index d276b8f7eb0..f9b363f4da7 100644 --- a/sys/mips/mips/elf_machdep.c +++ b/sys/mips/mips/elf_machdep.c @@ -105,7 +105,7 @@ static int elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, int local, elf_lookup_fn lookup) { - Elf_Addr *where = (Elf_Addr *)NULL;; + Elf_Addr *where = (Elf_Addr *)NULL; Elf_Addr addr; Elf_Addr addend = (Elf_Addr)0; Elf_Word rtype = (Elf_Word)0, symidx; diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index 3ed0528dd28..ab42e685d5f 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -404,7 +404,7 @@ ipv4_flow_lookup_hash_internal(struct mbuf *m, struct route *ro, if (*flags & FL_HASH_PORTS) goto noop; /* no port - hence not a protocol we care about */ - break;; + break; } *protop = proto; diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 30508d963e7..bccb6d5bdd9 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1739,7 +1739,7 @@ ieee80211_node_delucastkey(struct ieee80211_node *ni) status = ieee80211_crypto_delkey(ni->ni_vap, &ni->ni_ucastkey); if (nt->nt_keyixmap != NULL && keyix < nt->nt_keyixmax) { nikey = nt->nt_keyixmap[keyix]; - nt->nt_keyixmap[keyix] = NULL;; + nt->nt_keyixmap[keyix] = NULL; } } if (!isowned) diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c index 489933f6385..a42803ef44b 100644 --- a/sys/netinet/libalias/alias_db.c +++ b/sys/netinet/libalias/alias_db.c @@ -2136,7 +2136,7 @@ void SetProtocolFlags(struct alias_link *lnk, int pflags) { - lnk->pflags = pflags;; + lnk->pflags = pflags; } int diff --git a/sys/netinet/libalias/alias_mod.c b/sys/netinet/libalias/alias_mod.c index b2576da6be6..b6d903091c9 100644 --- a/sys/netinet/libalias/alias_mod.c +++ b/sys/netinet/libalias/alias_mod.c @@ -158,7 +158,7 @@ _attach_handler(struct proto_handler *p) static int _detach_handler(struct proto_handler *p) { - struct proto_handler *b, *b_tmp;; + struct proto_handler *b, *b_tmp; LIBALIAS_WLOCK_ASSERT(); LIST_FOREACH_SAFE(b, &handler_chain, entries, b_tmp) { diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index 9c46e7992ea..9513ded3361 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -2224,7 +2224,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, } if (stcb->asoc.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { - continue;; + continue; } if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && SCTP_IPV6_V6ONLY(inp6)) { diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 65de46229e4..8681acd03b2 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -4382,7 +4382,7 @@ sctp_add_to_readq(struct sctp_inpcb *inp, m = SCTP_BUF_NEXT(prev); } if (m == NULL) { - control->tail_mbuf = prev;; + control->tail_mbuf = prev; } continue; } diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index 4377f74367b..cff72c7f2bc 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -1332,7 +1332,7 @@ bootpc_compose_query(struct bootpc_ifcontext *ifctx, *vendp++ = TAG_VENDOR_INDENTIFIER; *vendp++ = vendor_client_len; memcpy(vendp, vendor_client, vendor_client_len); - vendp += vendor_client_len;; + vendp += vendor_client_len; ifctx->dhcpquerytype = DHCP_NOMSG; switch (ifctx->state) { case IF_DHCP_UNRESOLVED: diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c index c344a1e85fd..793ae80154d 100644 --- a/sys/pci/ncr.c +++ b/sys/pci/ncr.c @@ -3992,7 +3992,7 @@ ncr_action (struct cam_sim *sim, union ccb *ccb) msgptr[msglen++] = MSG_EXT_SDTR_LEN; msgptr[msglen++] = MSG_EXT_SDTR; msgptr[msglen++] = tp->tinfo.goal.period; - msgptr[msglen++] = tp->tinfo.goal.offset;; + msgptr[msglen++] = tp->tinfo.goal.offset; if (DEBUG_FLAGS & DEBUG_NEGO) { PRINT_ADDR(ccb); printf ("sync msgout: "); diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c index bbf2e04daae..597f9258076 100644 --- a/sys/powerpc/aim/mmu_oea.c +++ b/sys/powerpc/aim/mmu_oea.c @@ -922,7 +922,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend) thread0.td_kstack = va; thread0.td_kstack_pages = KSTACK_PAGES; for (i = 0; i < KSTACK_PAGES; i++) { - moea_kenter(mmup, va, pa);; + moea_kenter(mmup, va, pa); pa += PAGE_SIZE; va += PAGE_SIZE; } @@ -935,7 +935,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend) va = virtual_avail; virtual_avail += round_page(MSGBUF_SIZE); while (va < virtual_avail) { - moea_kenter(mmup, va, pa);; + moea_kenter(mmup, va, pa); pa += PAGE_SIZE; va += PAGE_SIZE; } @@ -948,7 +948,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend) va = virtual_avail; virtual_avail += DPCPU_SIZE; while (va < virtual_avail) { - moea_kenter(mmup, va, pa);; + moea_kenter(mmup, va, pa); pa += PAGE_SIZE; va += PAGE_SIZE; } diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 7a212b05034..f83cd1436a0 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -1019,7 +1019,7 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele thread0.td_kstack = va; thread0.td_kstack_pages = KSTACK_PAGES; for (i = 0; i < KSTACK_PAGES; i++) { - moea64_kenter(mmup, va, pa);; + moea64_kenter(mmup, va, pa); pa += PAGE_SIZE; va += PAGE_SIZE; } @@ -1032,7 +1032,7 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele va = virtual_avail; virtual_avail += round_page(MSGBUF_SIZE); while (va < virtual_avail) { - moea64_kenter(mmup, va, pa);; + moea64_kenter(mmup, va, pa); pa += PAGE_SIZE; va += PAGE_SIZE; } @@ -1045,7 +1045,7 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele va = virtual_avail; virtual_avail += DPCPU_SIZE; while (va < virtual_avail) { - moea64_kenter(mmup, va, pa);; + moea64_kenter(mmup, va, pa); pa += PAGE_SIZE; va += PAGE_SIZE; } diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 78a72507fa4..ab47292666e 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -2299,7 +2299,7 @@ make_sure_to_unlock: static void mmu_booke_change_wiring(mmu_t mmu, pmap_t pmap, vm_offset_t va, boolean_t wired) { - pte_t *pte;; + pte_t *pte; PMAP_LOCK(pmap); if ((pte = pte_find(mmu, pmap, va)) != NULL) { @@ -2783,7 +2783,7 @@ tlb1_write_entry(unsigned int idx) mtspr(SPR_MAS7, mas7); __asm __volatile("isync; tlbwe; isync; msync"); - //debugf("tlb1_write_entry: e\n");; + //debugf("tlb1_write_entry: e\n"); } /* diff --git a/sys/rpc/clnt_dg.c b/sys/rpc/clnt_dg.c index 78f4a9a2128..e3fa02c91bf 100644 --- a/sys/rpc/clnt_dg.c +++ b/sys/rpc/clnt_dg.c @@ -258,7 +258,7 @@ clnt_dg_create( rpc_createerr.cf_error.re_errno = 0; goto err2; } - cu->cu_mcalllen = XDR_GETPOS(&xdrs);; + cu->cu_mcalllen = XDR_GETPOS(&xdrs); /* * By default, closeit is always FALSE. It is users responsibility diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index a6e73f53c5f..b36cb58808b 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -739,7 +739,7 @@ out1: auio.uio_iovcnt = 1; aiov.iov_base = (void *)snapblklist; aiov.iov_len = snaplistsize * sizeof(daddr_t); - auio.uio_resid = aiov.iov_len;; + auio.uio_resid = aiov.iov_len; auio.uio_offset = ip->i_size; auio.uio_segflg = UIO_SYSSPACE; auio.uio_rw = UIO_WRITE; diff --git a/sys/xen/xenbus/xenbus_probe.c b/sys/xen/xenbus/xenbus_probe.c index f04f8eca463..b1e9a2108aa 100644 --- a/sys/xen/xenbus/xenbus_probe.c +++ b/sys/xen/xenbus/xenbus_probe.c @@ -330,7 +330,7 @@ xenbus_devices_changed(struct xenbus_watch *watch, device_t dev = sc->xs_dev; char *node, *bus, *type, *id, *p; - node = strdup(vec[XS_WATCH_PATH], M_DEVBUF);; + node = strdup(vec[XS_WATCH_PATH], M_DEVBUF); p = strchr(node, '/'); if (!p) goto out; From 066850734605ec5780eb32618ade0bf3cdcf7d9f Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 11 Feb 2010 21:25:48 +0000 Subject: [PATCH 1414/2592] MFC: r203119 Patch the experimental NFS client in a manner analogous to r203072 for the regular NFS client. Also, delete two fields of struct nfsmount that are not used by the FreeBSD port of the client. --- sys/fs/nfsclient/nfs.h | 15 ++++++++++++++- sys/fs/nfsclient/nfs_clbio.c | 8 ++++---- sys/fs/nfsclient/nfs_clnfsiod.c | 22 ++++++++++++++-------- sys/fs/nfsclient/nfs_clsubs.c | 6 +++--- sys/fs/nfsclient/nfsmount.h | 2 -- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/sys/fs/nfsclient/nfs.h b/sys/fs/nfsclient/nfs.h index a72ec6da75d..4b542869d62 100644 --- a/sys/fs/nfsclient/nfs.h +++ b/sys/fs/nfsclient/nfs.h @@ -55,6 +55,19 @@ #define NFS_ISV34(v) \ (VFSTONFS((v)->v_mount)->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) +/* + * NFS iod threads can be in one of these three states once spawned. + * NFSIOD_NOT_AVAILABLE - Cannot be assigned an I/O operation at this time. + * NFSIOD_AVAILABLE - Available to be assigned an I/O operation. + * NFSIOD_CREATED_FOR_NFS_ASYNCIO - Newly created for nfs_asyncio() and + * will be used by the thread that called nfs_asyncio(). + */ +enum nfsiod_state { + NFSIOD_NOT_AVAILABLE = 0, + NFSIOD_AVAILABLE = 1, + NFSIOD_CREATED_FOR_NFS_ASYNCIO = 2, +}; + /* * Function prototypes. */ @@ -87,7 +100,7 @@ int ncl_fsinfo(struct nfsmount *, struct vnode *, struct ucred *, int ncl_init(struct vfsconf *); int ncl_uninit(struct vfsconf *); int ncl_mountroot(struct mount *); -int ncl_nfsiodnew(void); +int ncl_nfsiodnew(int); #endif /* _KERNEL */ diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c index 3193822f47e..d0dd2cc2e9f 100644 --- a/sys/fs/nfsclient/nfs_clbio.c +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -63,7 +63,7 @@ extern int newnfs_directio_allow_mmap; extern struct nfsstats newnfsstats; extern struct mtx ncl_iod_mutex; extern int ncl_numasync; -extern struct proc *ncl_iodwant[NFS_MAXRAHEAD]; +extern enum nfsiod_state ncl_iodwant[NFS_MAXRAHEAD]; extern struct nfsmount *ncl_iodmount[NFS_MAXRAHEAD]; extern int newnfs_directio_enable; @@ -1396,7 +1396,7 @@ again: * Find a free iod to process this request. */ for (iod = 0; iod < ncl_numasync; iod++) - if (ncl_iodwant[iod]) { + if (ncl_iodwant[iod] == NFSIOD_AVAILABLE) { gotiod = TRUE; break; } @@ -1405,7 +1405,7 @@ again: * Try to create one if none are free. */ if (!gotiod) { - iod = ncl_nfsiodnew(); + iod = ncl_nfsiodnew(1); if (iod != -1) gotiod = TRUE; } @@ -1417,7 +1417,7 @@ again: */ NFS_DPF(ASYNCIO, ("ncl_asyncio: waking iod %d for mount %p\n", iod, nmp)); - ncl_iodwant[iod] = NULL; + ncl_iodwant[iod] = NFSIOD_NOT_AVAILABLE; ncl_iodmount[iod] = nmp; nmp->nm_bufqiods++; wakeup(&ncl_iodwant[iod]); diff --git a/sys/fs/nfsclient/nfs_clnfsiod.c b/sys/fs/nfsclient/nfs_clnfsiod.c index f38aed85305..6649fc032a3 100644 --- a/sys/fs/nfsclient/nfs_clnfsiod.c +++ b/sys/fs/nfsclient/nfs_clnfsiod.c @@ -72,7 +72,7 @@ __FBSDID("$FreeBSD$"); extern struct mtx ncl_iod_mutex; int ncl_numasync; -struct proc *ncl_iodwant[NFS_MAXRAHEAD]; +enum nfsiod_state ncl_iodwant[NFS_MAXRAHEAD]; struct nfsmount *ncl_iodmount[NFS_MAXRAHEAD]; static void nfssvc_iod(void *); @@ -114,7 +114,7 @@ sysctl_iodmin(SYSCTL_HANDLER_ARGS) * than the new minimum, create some more. */ for (i = nfs_iodmin - ncl_numasync; i > 0; i--) - ncl_nfsiodnew(); + ncl_nfsiodnew(0); out: mtx_unlock(&ncl_iod_mutex); return (0); @@ -147,7 +147,7 @@ sysctl_iodmax(SYSCTL_HANDLER_ARGS) */ iod = ncl_numasync - 1; for (i = 0; i < ncl_numasync - ncl_iodmax; i++) { - if (ncl_iodwant[iod]) + if (ncl_iodwant[iod] == NFSIOD_AVAILABLE) wakeup(&ncl_iodwant[iod]); iod--; } @@ -159,7 +159,7 @@ SYSCTL_PROC(_vfs_newnfs, OID_AUTO, iodmax, CTLTYPE_UINT | CTLFLAG_RW, 0, sizeof (ncl_iodmax), sysctl_iodmax, "IU", ""); int -ncl_nfsiodnew(void) +ncl_nfsiodnew(int set_iodwant) { int error, i; int newiod; @@ -175,12 +175,17 @@ ncl_nfsiodnew(void) } if (newiod == -1) return (-1); + if (set_iodwant > 0) + ncl_iodwant[i] = NFSIOD_CREATED_FOR_NFS_ASYNCIO; mtx_unlock(&ncl_iod_mutex); error = kproc_create(nfssvc_iod, nfs_asyncdaemon + i, NULL, RFHIGHPID, 0, "nfsiod %d", newiod); mtx_lock(&ncl_iod_mutex); - if (error) + if (error) { + if (set_iodwant > 0) + ncl_iodwant[i] = NFSIOD_NOT_AVAILABLE; return (-1); + } ncl_numasync++; return (newiod); } @@ -199,7 +204,7 @@ nfsiod_setup(void *dummy) nfs_iodmin = NFS_MAXRAHEAD; for (i = 0; i < nfs_iodmin; i++) { - error = ncl_nfsiodnew(); + error = ncl_nfsiodnew(0); if (error == -1) panic("newnfsiod_setup: ncl_nfsiodnew failed"); } @@ -235,7 +240,8 @@ nfssvc_iod(void *instance) goto finish; if (nmp) nmp->nm_bufqiods--; - ncl_iodwant[myiod] = curthread->td_proc; + if (ncl_iodwant[myiod] == NFSIOD_NOT_AVAILABLE) + ncl_iodwant[myiod] = NFSIOD_AVAILABLE; ncl_iodmount[myiod] = NULL; /* * Always keep at least nfs_iodmin kthreads. @@ -295,7 +301,7 @@ finish: nfs_asyncdaemon[myiod] = 0; if (nmp) nmp->nm_bufqiods--; - ncl_iodwant[myiod] = NULL; + ncl_iodwant[myiod] = NFSIOD_NOT_AVAILABLE; ncl_iodmount[myiod] = NULL; /* Someone may be waiting for the last nfsiod to terminate. */ if (--ncl_numasync == 0) diff --git a/sys/fs/nfsclient/nfs_clsubs.c b/sys/fs/nfsclient/nfs_clsubs.c index 3cd7e5c8685..15535098707 100644 --- a/sys/fs/nfsclient/nfs_clsubs.c +++ b/sys/fs/nfsclient/nfs_clsubs.c @@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$"); #include extern struct mtx ncl_iod_mutex; -extern struct proc *ncl_iodwant[NFS_MAXRAHEAD]; +extern enum nfsiod_state ncl_iodwant[NFS_MAXRAHEAD]; extern struct nfsmount *ncl_iodmount[NFS_MAXRAHEAD]; extern int ncl_numasync; extern unsigned int ncl_iodmax; @@ -100,7 +100,7 @@ ncl_uninit(struct vfsconf *vfsp) mtx_lock(&ncl_iod_mutex); ncl_iodmax = 0; for (i = 0; i < ncl_numasync; i++) - if (ncl_iodwant[i]) + if (ncl_iodwant[i] == NFSIOD_AVAILABLE) wakeup(&ncl_iodwant[i]); /* The last nfsiod to exit will wake us up when ncl_numasync hits 0 */ while (ncl_numasync) @@ -396,7 +396,7 @@ ncl_init(struct vfsconf *vfsp) /* Ensure async daemons disabled */ for (i = 0; i < NFS_MAXRAHEAD; i++) { - ncl_iodwant[i] = NULL; + ncl_iodwant[i] = NFSIOD_NOT_AVAILABLE; ncl_iodmount[i] = NULL; } ncl_nhinit(); /* Init the nfsnode table */ diff --git a/sys/fs/nfsclient/nfsmount.h b/sys/fs/nfsclient/nfsmount.h index acf438e1c22..2f0ada61dc7 100644 --- a/sys/fs/nfsclient/nfsmount.h +++ b/sys/fs/nfsclient/nfsmount.h @@ -71,8 +71,6 @@ struct nfsmount { int nm_tprintf_delay; /* interval for messages */ /* Newnfs additions */ - int nm_iothreadcnt; - struct proc *nm_iodwant[NFS_MAXRAHEAD]; struct nfsclclient *nm_clp; uid_t nm_uid; /* Uid for SetClientID etc. */ u_int64_t nm_clval; /* identifies which clientid */ From 9090fd5bfa8b2d142e204fdcaec4da8f3e0c5472 Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Fri, 12 Feb 2010 00:47:23 +0000 Subject: [PATCH 1415/2592] Pick up some changes the the MFC missed. --- sys/dev/isp/isp.c | 35 +++++++++++++++++++++++++---------- sys/dev/isp/isp_library.c | 4 ++-- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 15983a3ed99..1945e4fbced 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -2763,15 +2763,21 @@ isp_pdb_sync(ispsoftc_t *isp, int chan) /* * Make sure we're okay for doing this right now. */ - if (fcp->isp_loopstate != LOOP_PDB_RCVD && fcp->isp_loopstate != LOOP_FSCAN_DONE && fcp->isp_loopstate != LOOP_LSCAN_DONE) { - isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d", fcp->isp_loopstate); + if (fcp->isp_loopstate != LOOP_PDB_RCVD && + fcp->isp_loopstate != LOOP_FSCAN_DONE && + fcp->isp_loopstate != LOOP_LSCAN_DONE) { + isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d", + fcp->isp_loopstate); return (-1); } - if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT || fcp->isp_topo == TOPO_N_PORT) { + if (fcp->isp_topo == TOPO_FL_PORT || + fcp->isp_topo == TOPO_NL_PORT || + fcp->isp_topo == TOPO_N_PORT) { if (fcp->isp_loopstate < LOOP_LSCAN_DONE) { if (isp_scan_loop(isp, chan) != 0) { - isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: isp_scan_loop failed"); + isp_prt(isp, ISP_LOGWARN, + "isp_pdb_sync: isp_scan_loop failed"); return (-1); } } @@ -2780,13 +2786,15 @@ isp_pdb_sync(ispsoftc_t *isp, int chan) if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) { if (fcp->isp_loopstate < LOOP_FSCAN_DONE) { if (isp_scan_fabric(isp, chan) != 0) { - isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: isp_scan_fabric failed"); + isp_prt(isp, ISP_LOGWARN, + "isp_pdb_sync: isp_scan_fabric failed"); return (-1); } } } - isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d Synchronizing PDBs", chan); + isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, + "Chan %d Synchronizing PDBs", chan); fcp->isp_loopstate = LOOP_SYNCING_PDB; @@ -2815,7 +2823,11 @@ isp_pdb_sync(ispsoftc_t *isp, int chan) lp->state = FC_PORTDB_STATE_NIL; isp_async(isp, ISPASYNC_DEV_GONE, chan, lp); if (lp->autologin == 0) { - (void) isp_plogx(isp, chan, lp->handle, lp->portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 0); + (void) isp_plogx(isp, chan, lp->handle, + lp->portid, + PLOGX_FLG_CMD_LOGO | + PLOGX_FLG_IMPLICIT | + PLOGX_FLG_FREE_NPHDL, 0); } else { lp->autologin = 0; } @@ -3061,7 +3073,8 @@ isp_scan_loop(ispsoftc_t *isp, int chan) for (i = 0; i < MAX_FC_TARG; i++) { lp = &fcp->portdb[i]; - if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) { + if (lp->state == FC_PORTDB_STATE_NIL || + lp->target_mode) { continue; } if (lp->node_wwn != tmp.node_wwn) { @@ -3579,7 +3592,8 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { lp = &fcp->portdb[dbidx]; - if (lp->state != FC_PORTDB_STATE_PROBATIONAL || lp->target_mode) { + if (lp->state != FC_PORTDB_STATE_PROBATIONAL || + lp->target_mode) { continue; } if (lp->portid == portid) { @@ -3816,7 +3830,8 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) if (fcp->portdb[dbidx].target_mode) { continue; } - if (fcp->portdb[dbidx].node_wwn == wwnn && fcp->portdb[dbidx].port_wwn == wwpn) { + if (fcp->portdb[dbidx].node_wwn == wwnn && + fcp->portdb[dbidx].port_wwn == wwpn) { break; } } diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c index efe30c0a3d4..57b84002ec9 100644 --- a/sys/dev/isp/isp_library.c +++ b/sys/dev/isp/isp_library.c @@ -650,7 +650,7 @@ isp_clear_commands(ispsoftc_t *isp) #ifdef ISP_TARGET_MODE for (tmp = 0; isp->isp_tgtlist && tmp < isp->isp_maxcmds; tmp++) { uint8_t local[QENTRY_LEN]; - hdp = &isp->isp_tgt_xflist[tmp]; + hdp = &isp->isp_tgtlist[tmp]; if (hdp->handle == ISP_HANDLE_FREE) { continue; } @@ -2275,7 +2275,7 @@ isp_find_tgt_handle(ispsoftc_t *isp, void *xs) void isp_destroy_tgt_handle(ispsoftc_t *isp, uint32_t handle) { - if (!ISP_VALID_TGT_HANDLE(handle)) { + if (!ISP_VALID_TGT_HANDLE(isp, handle)) { isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle); } else { isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].handle = ISP_HANDLE_FREE; From e6c7573970c78e353b0d8f1299a89017323bfe3b Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sat, 13 Feb 2010 00:29:01 +0000 Subject: [PATCH 1416/2592] MFC r203534: Correct two typos. Reported by: Brandon Falk --- sbin/newfs/newfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbin/newfs/newfs.c b/sbin/newfs/newfs.c index 776b45df4f3..b70ce1b3774 100644 --- a/sbin/newfs/newfs.c +++ b/sbin/newfs/newfs.c @@ -499,13 +499,13 @@ usage() getprogname(), " [device-type]"); fprintf(stderr, "where fsoptions are:\n"); - fprintf(stderr, "\t-E Erase previuos disk content\n"); + fprintf(stderr, "\t-E Erase previous disk content\n"); fprintf(stderr, "\t-J Enable journaling via gjournal\n"); fprintf(stderr, "\t-L volume label to add to superblock\n"); fprintf(stderr, "\t-N do not create file system, just print out parameters\n"); fprintf(stderr, "\t-O file system format: 1 => UFS1, 2 => UFS2\n"); - fprintf(stderr, "\t-R regression test, supress random factors\n"); + fprintf(stderr, "\t-R regression test, suppress random factors\n"); fprintf(stderr, "\t-S sector size\n"); fprintf(stderr, "\t-T disktype\n"); fprintf(stderr, "\t-U enable soft updates\n"); From 992955ae5e17af0a748eb5503037aad5b866570d Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sat, 13 Feb 2010 00:30:50 +0000 Subject: [PATCH 1417/2592] MFC r203053: Add a manual page for nvram(4). --- share/man/man4/Makefile | 2 + share/man/man4/nvram.4 | 93 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 share/man/man4/nvram.4 diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 1dec7814d7f..4e34eb0d87e 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -290,6 +290,7 @@ MAN= aac.4 \ nsp.4 \ null.4 \ ${_nve.4} \ + ${_nvram.4} \ ${_nxge.4} \ ohci.4 \ orm.4 \ @@ -638,6 +639,7 @@ _ndis.4= ndis.4 _nfe.4= nfe.4 _nfsmb.4= nfsmb.4 _nve.4= nve.4 +_nvram.4= nvram.4 _nxge.4= nxge.4 _rr232x.4= rr232x.4 _speaker.4= speaker.4 diff --git a/share/man/man4/nvram.4 b/share/man/man4/nvram.4 new file mode 100644 index 00000000000..a3a361e1d69 --- /dev/null +++ b/share/man/man4/nvram.4 @@ -0,0 +1,93 @@ +.\" +.\"Copyright (c) 2010 iXsystems, Inc. +.\"All rights reserved. +.\" written by: Xin LI +.\" +.\"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 January 27, 2010 +.Dt NVRAM 4 i386 +.Os +.Sh NAME +.Nm nvram +.Nd "non-volatile RAM" +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following line in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device nvram" +.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 +nvram_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides access to BIOS configuration NVRAM on i386 and amd64 +systems. +.Pp +PC motherboard uses a small non-volatile memory to store BIOS settings +which is usually part of its clock chip and sometimes referred as +.Dq CMOS SRAM . +This driver exposes bytes 14 through 128 of the NVRAM, or a total of +114 bytes, at offset zero of the device file +.Pa /dev/nvram . +.Pp +This driver is useful for cloning machines that shares the same hardware +configuration and need same BIOS setting tweaks. +.Sh IMPLEMENTATION NOTES +The BIOS NVRAM's bytes 16 through 31 are checksummed at byte 32. +This driver +.Em does not +take care for these checksums. +.Sh EXAMPLES +Backup existing BIOS NVRAM to +.Pa nvram.bin : +.Pp +.Dl dd if=/dev/nvram of=nvram.bin +.Pp +Restore BIOS NVRAM from +.Pa nvram.bin : +.Pp +.Dl dd if=nvram.bin of=/dev/nvram +.Sh SEE ALSO +.Xr dd 1 +.Sh HISTORY +The +.Nm +device driver first appeared in +.Fx 6.4 . +.Sh AUTHORS +.An -nosplit +The +.Nm +device driver was written by +.An Peter Wemm . +This manual page was written by +.An Xin LI . From f2176d8ce1602e3876b21a0947c2ff039be7b556 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sat, 13 Feb 2010 00:39:46 +0000 Subject: [PATCH 1419/2592] MFC r202130: Set svn:executable to *. --- etc/rc.d/static_arp | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 etc/rc.d/static_arp diff --git a/etc/rc.d/static_arp b/etc/rc.d/static_arp old mode 100644 new mode 100755 From d69d02b9a46af5fbd5e5c0c556ebcc446bf5bd9a Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Sat, 13 Feb 2010 10:26:00 +0000 Subject: [PATCH 1420/2592] Merge r203393,r203395 from head: The multiplicand a = 0x5deece66d = 25214903917, not 0xfdeece66d. This bug in the man page has gone unnoticed for over 15 years! PR: docs/143461 Submitted by: Jeremy Huddleston jeremyhu apple.com --- lib/libc/gen/rand48.3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/gen/rand48.3 b/lib/libc/gen/rand48.3 index a703ba08813..8d325a1bff1 100644 --- a/lib/libc/gen/rand48.3 +++ b/lib/libc/gen/rand48.3 @@ -12,7 +12,7 @@ .\" @(#)rand48.3 V1.0 MB 8 Oct 1993 .\" $FreeBSD$ .\" -.Dd October 8, 1993 +.Dd February 2, 2010 .Dt RAND48 3 .Os .Sh NAME @@ -57,7 +57,7 @@ The particular formula employed is r(n+1) = (a * r(n) + c) mod m where the default values are -for the multiplicand a = 0xfdeece66d = 25214903917 and +for the multiplicand a = 0x5deece66d = 25214903917 and the addend c = 0xb = 11. The modulo is always fixed at m = 2 ** 48. r(n) is called the seed of the random number generator. From 6c204d20ba69bcf7cff67e054d851c52e0b410bf Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sat, 13 Feb 2010 16:25:33 +0000 Subject: [PATCH 1421/2592] MFC r203378: Make -a option actually work. --- usr.sbin/rtsold/rtsold.c | 1 - 1 file changed, 1 deletion(-) diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c index f0493fbd68f..fd089549915 100644 --- a/usr.sbin/rtsold/rtsold.c +++ b/usr.sbin/rtsold/rtsold.c @@ -841,7 +841,6 @@ autoifprobe(void) if (!argv[n]) err(1, "malloc"); n++; - argv[n] = NULL; } if (n) { From 93bc06c3206447eacf943beb2deae2cc559e0e93 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sat, 13 Feb 2010 16:28:25 +0000 Subject: [PATCH 1422/2592] MFC r203387: Exclude the interfaces which IPv6 and/or accepting RA is disabled from the auto probed interface list. --- usr.sbin/rtsold/rtsold.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c index fd089549915..b2031c801f7 100644 --- a/usr.sbin/rtsold/rtsold.c +++ b/usr.sbin/rtsold/rtsold.c @@ -32,15 +32,20 @@ */ #include +#include #include #include #include #include #include +#include #include #include +#include + +#include #include #include @@ -789,8 +794,9 @@ autoifprobe(void) static char **argv = NULL; static int n = 0; char **a; - int i, found; + int s, i, found; struct ifaddrs *ifap, *ifa, *target; + struct in6_ndireq nd; /* initialize */ while (n--) @@ -804,6 +810,11 @@ autoifprobe(void) if (getifaddrs(&ifap) != 0) return NULL; + if (!Fflag && (s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + err(1, "socket"); + /* NOTREACHED */ + } + target = NULL; /* find an ethernet */ for (ifa = ifap; ifa; ifa = ifa->ifa_next) { @@ -829,6 +840,23 @@ autoifprobe(void) if (found) continue; + /* + * Skip the interfaces which IPv6 and/or accepting RA + * is disabled. + */ + if (!Fflag) { + memset(&nd, 0, sizeof(nd)); + strlcpy(nd.ifname, ifa->ifa_name, sizeof(nd.ifname)); + if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) { + err(1, "ioctl(SIOCGIFINFO_IN6)"); + /* NOTREACHED */ + } + if ((nd.ndi.flags & ND6_IFF_IFDISABLED)) + continue; + if (!(nd.ndi.flags & ND6_IFF_ACCEPT_RTADV)) + continue; + } + /* if we find multiple candidates, just warn. */ if (n != 0 && dflag > 1) warnx("multiple interfaces found"); @@ -855,6 +883,8 @@ autoifprobe(void) warnx("probing %s", argv[i]); } } + if (!Fflag) + close(s); freeifaddrs(ifap); return argv; } From 4508cb3ff7a74f740a87c56f1228ccf4d53c0377 Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sat, 13 Feb 2010 17:35:29 +0000 Subject: [PATCH 1423/2592] Merge r201918 to stable/8: Fix a typo. --- kerberos5/usr.bin/kdestroy/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kerberos5/usr.bin/kdestroy/Makefile b/kerberos5/usr.bin/kdestroy/Makefile index 8ebb201cee4..592f5e69a57 100644 --- a/kerberos5/usr.bin/kdestroy/Makefile +++ b/kerberos5/usr.bin/kdestroy/Makefile @@ -2,7 +2,7 @@ PROG= kdestroy CFLAGS+=-I${KRB5DIR}/lib/roken -DPADD= ${LIBKAFS5} ${LIBKRB5} ${LIBHX509) ${LIBROKEN} ${LIBVERS} \ +DPADD= ${LIBKAFS5} ${LIBKRB5} ${LIBHX509} ${LIBROKEN} ${LIBVERS} \ ${LIBASN1} ${LIBCRYPTO} ${LIBCRYPT} ${LIBCOM_ERR} LDADD= -lkafs5 -lkrb5 -lhx509 -lroken ${LIBVERS} \ -lasn1 -lcrypto -lcrypt -lcom_err From 43cd061a2741e9357c4e07242b692b875adc5f93 Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sat, 13 Feb 2010 17:41:22 +0000 Subject: [PATCH 1424/2592] Merge r201919 to stable/8: Fix a typo. --- kerberos5/usr.bin/kpasswd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kerberos5/usr.bin/kpasswd/Makefile b/kerberos5/usr.bin/kpasswd/Makefile index e4da7695574..a9ab1c99ec8 100644 --- a/kerberos5/usr.bin/kpasswd/Makefile +++ b/kerberos5/usr.bin/kpasswd/Makefile @@ -2,7 +2,7 @@ PROG= kpasswd CFLAGS+=-I${KRB5DIR}/lib/roken -DPADD= ${LIBKRB5} ${LIBHX509 ${LIBROKEN} ${LIBVERS} \ +DPADD= ${LIBKRB5} ${LIBHX509} ${LIBROKEN} ${LIBVERS} \ ${LIBASN1} ${LIBCRYPTO} ${LIBCRYPT} ${LIBCOM_ERR} LDADD= -lkrb5 -lhx509 -lroken ${LIBVERS} \ -lasn1 -lcrypto -lcrypt -lcom_err From 2265536f119989b3514deff47830470b87674a98 Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sat, 13 Feb 2010 17:48:52 +0000 Subject: [PATCH 1425/2592] Merge r201920 to stable/8: libusb20 was renamed libusb several months ago. --- share/mk/bsd.libnames.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index 3a3fd864625..8a37a768655 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -150,7 +150,7 @@ LIBUFS?= ${DESTDIR}${LIBDIR}/libufs.a LIBUGIDFW?= ${DESTDIR}${LIBDIR}/libugidfw.a LIBUMEM?= ${DESTDIR}${LIBDIR}/libumem.a LIBUSBHID?= ${DESTDIR}${LIBDIR}/libusbhid.a -LIBUSB20?= ${DESTDIR}${LIBDIR}/libusb20.a +LIBUSB?= ${DESTDIR}${LIBDIR}/libusb.a LIBUTIL?= ${DESTDIR}${LIBDIR}/libutil.a LIBUUTIL?= ${DESTDIR}${LIBDIR}/libuutil.a LIBVGL?= ${DESTDIR}${LIBDIR}/libvgl.a From 16a11310f08cdf60f91943413626d60657e19cb5 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 14 Feb 2010 00:43:42 +0000 Subject: [PATCH 1426/2592] MFC: r203303 Patch the experimental NFS client so that there is a timeout for negative name cache entries in a manner analogous to r202767 for the regular NFS client. Also, make the code in nfs_lookup() compatible with that of the regular client and replace the sysctl variable that enabled negative name caching with the mount point option. --- sys/fs/nfsclient/nfs_clvfsops.c | 22 ++++- sys/fs/nfsclient/nfs_clvnops.c | 170 +++++++++++++++++++++----------- sys/fs/nfsclient/nfsmount.h | 5 + sys/fs/nfsclient/nfsnode.h | 1 + 4 files changed, 139 insertions(+), 59 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 1f7d20868b3..0bf2bf4b4e5 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -99,7 +99,7 @@ static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp, struct ucred *, struct thread *); static int mountnfs(struct nfs_args *, struct mount *, struct sockaddr *, char *, u_char *, u_char *, u_char *, - struct vnode **, struct ucred *, struct thread *); + struct vnode **, struct ucred *, struct thread *, int); static vfs_mount_t nfs_mount; static vfs_cmount_t nfs_cmount; static vfs_unmount_t nfs_unmount; @@ -498,7 +498,7 @@ nfs_mountdiskless(char *path, nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK); if ((error = mountnfs(args, mp, nam, path, NULL, NULL, NULL, vpp, - td->td_ucred, td)) != 0) { + td->td_ucred, td, NFS_DEFAULT_NEGNAMETIMEO)) != 0) { printf("nfs_mountroot: mount %s on /: %d\n", path, error); return (error); } @@ -669,6 +669,7 @@ static const char *nfs_opts[] = { "from", "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "resvport", "readahead", "hostname", "timeout", "addr", "fh", "nfsv3", "sec", "principal", "nfsv4", "gssname", "allgssname", "dirpath", + "negnametimeo", NULL }; /* @@ -717,6 +718,7 @@ nfs_mount(struct mount *mp) char hst[MNAMELEN]; u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100]; char *opt, *name, *secname; + int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO; if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { error = EINVAL; @@ -891,6 +893,16 @@ nfs_mount(struct mount *mp) } args.flags |= NFSMNT_TIMEO; } + if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL) + == 0) { + ret = sscanf(opt, "%d", &negnametimeo); + if (ret != 1 || negnametimeo < 0) { + vfs_mount_error(mp, "illegal negnametimeo: %s", + opt); + error = EINVAL; + goto out; + } + } if (vfs_getopt(mp->mnt_optnew, "sec", (void **) &secname, NULL) == 0) nfs_sec_name(secname, &args.flags); @@ -990,7 +1002,7 @@ nfs_mount(struct mount *mp) args.fh = nfh; error = mountnfs(&args, mp, nam, hst, krbname, dirpath, srvkrbname, - &vp, td->td_ucred, td); + &vp, td->td_ucred, td, negnametimeo); out: if (!error) { MNT_ILOCK(mp); @@ -1033,7 +1045,8 @@ nfs_cmount(struct mntarg *ma, void *data, int flags) static int mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, char *hst, u_char *krbname, u_char *dirpath, u_char *srvkrbname, - struct vnode **vpp, struct ucred *cred, struct thread *td) + struct vnode **vpp, struct ucred *cred, struct thread *td, + int negnametimeo) { struct nfsmount *nmp; struct nfsnode *np; @@ -1101,6 +1114,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, vfs_getnewfsid(mp); nmp->nm_mountp = mp; mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK); + nmp->nm_negnametimeo = negnametimeo; nfs_decode_args(mp, nmp, argp, cred, td); diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 147c1641392..2114ba9078b 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -224,10 +224,6 @@ int newnfs_directio_enable = 0; SYSCTL_INT(_vfs_newnfs, OID_AUTO, directio_enable, CTLFLAG_RW, &newnfs_directio_enable, 0, "Enable NFS directio"); -static int newnfs_neglookup_enable = 1; -SYSCTL_INT(_vfs_newnfs, OID_AUTO, neglookup_enable, CTLFLAG_RW, - &newnfs_neglookup_enable, 0, "Enable NFS negative lookup caching"); - /* * This sysctl allows other processes to mmap a file that has been opened * O_DIRECT by a process. In general, having processes mmap the file while @@ -713,11 +709,11 @@ nfs_close(struct vop_close_args *ap) * enabled. (What does this have to do with negative lookup * caching? Well nothing, except it was reported by the * same user that needed negative lookup caching and I wanted - * there to be a way to disable it via sysctl to see if it + * there to be a way to disable it to see if it * is the cause of some caching/coherency issue that might * crop up.) */ - if (newnfs_neglookup_enable == 0) + if (VFSTONFS(vp->v_mount)->nm_negnametimeo == 0) np->n_attrstamp = 0; if (np->n_flag & NWRITEERR) { np->n_flag &= ~NWRITEERR; @@ -1007,6 +1003,8 @@ nfs_lookup(struct vop_lookup_args *ap) struct thread *td = cnp->cn_thread; struct nfsfh *nfhp; struct nfsvattr dnfsva, nfsva; + struct vattr vattr; + time_t dmtime; *vpp = NULLVP; if ((flags & ISLASTCN) && (mp->mnt_flag & MNT_RDONLY) && @@ -1027,37 +1025,68 @@ nfs_lookup(struct vop_lookup_args *ap) if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td)) != 0) return (error); - if ((error = cache_lookup(dvp, vpp, cnp)) && - (error != ENOENT || newnfs_neglookup_enable != 0)) { - struct vattr vattr; - - if (error == ENOENT) { - if (!VOP_GETATTR(dvp, &vattr, cnp->cn_cred) && - vattr.va_mtime.tv_sec == np->n_dmtime) { - NFSINCRGLOBAL(newnfsstats.lookupcache_hits); - return (ENOENT); - } - cache_purge_negative(dvp); - np->n_dmtime = 0; - } else { - newvp = *vpp; - if (nfscl_nodeleg(newvp, 0) == 0 || - (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred) && - vattr.va_ctime.tv_sec==VTONFS(newvp)->n_ctime)) { - NFSINCRGLOBAL(newnfsstats.lookupcache_hits); - if (cnp->cn_nameiop != LOOKUP && - (flags & ISLASTCN)) - cnp->cn_flags |= SAVENAME; - return (0); - } - cache_purge(newvp); - if (dvp != newvp) - vput(newvp); - else - vrele(newvp); - *vpp = NULLVP; + error = cache_lookup(dvp, vpp, cnp); + if (error > 0 && error != ENOENT) + return (error); + if (error == -1) { + /* + * We only accept a positive hit in the cache if the + * change time of the file matches our cached copy. + * Otherwise, we discard the cache entry and fallback + * to doing a lookup RPC. + */ + newvp = *vpp; + if (nfscl_nodeleg(newvp, 0) == 0 || + (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred) + && vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime)) { + NFSINCRGLOBAL(newnfsstats.lookupcache_hits); + if (cnp->cn_nameiop != LOOKUP && + (flags & ISLASTCN)) + cnp->cn_flags |= SAVENAME; + return (0); } + cache_purge(newvp); + if (dvp != newvp) + vput(newvp); + else + vrele(newvp); + *vpp = NULLVP; + } else if (error == ENOENT) { + if (dvp->v_iflag & VI_DOOMED) + return (ENOENT); + /* + * We only accept a negative hit in the cache if the + * modification time of the parent directory matches + * our cached copy. Otherwise, we discard all of the + * negative cache entries for this directory. We also + * only trust -ve cache entries for less than + * nm_negative_namecache_timeout seconds. + */ + if ((u_int)(ticks - np->n_dmtime_ticks) < + (nmp->nm_negnametimeo * hz) && + VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 && + vattr.va_mtime.tv_sec == np->n_dmtime) { + NFSINCRGLOBAL(newnfsstats.lookupcache_hits); + return (ENOENT); + } + cache_purge_negative(dvp); + mtx_lock(&np->n_mtx); + 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.na_mtime.tv_sec; error = 0; newvp = NULLVP; NFSINCRGLOBAL(newnfsstats.lookupcache_misses); @@ -1067,29 +1096,60 @@ nfs_lookup(struct vop_lookup_args *ap) if (dattrflag) (void) nfscl_loadattrcache(&dvp, &dnfsva, NULL, NULL, 0, 1); if (error) { - if (newnfs_neglookup_enable != 0 && - error == ENOENT && (cnp->cn_flags & MAKEENTRY) && - cnp->cn_nameiop != CREATE) { - if (np->n_dmtime == 0) - np->n_dmtime = np->n_vattr.na_mtime.tv_sec; - cache_enter(dvp, NULL, cnp); - } if (newvp != NULLVP) { vput(newvp); *vpp = NULLVP; } - if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && - (flags & ISLASTCN) && error == ENOENT) { - if (mp->mnt_flag & MNT_RDONLY) - error = EROFS; - else - error = EJUSTRETURN; + + if (error != ENOENT) { + if (NFS_ISV4(dvp)) + error = nfscl_maperr(td, error, (uid_t)0, + (gid_t)0); + return (error); } - if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) + + /* The requested file was not found. */ + if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && + (flags & ISLASTCN)) { + /* + * XXX: UFS does a full VOP_ACCESS(dvp, + * VWRITE) here instead of just checking + * MNT_RDONLY. + */ + if (mp->mnt_flag & MNT_RDONLY) + return (EROFS); cnp->cn_flags |= SAVENAME; - if (NFS_ISV4(dvp)) - error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0); - return (error); + return (EJUSTRETURN); + } + + if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE) { + /* + * Maintain n_dmtime as the modification time + * of the parent directory when the oldest -ve + * name cache entry for this directory was + * 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 <= dmtime) { + if (np->n_dmtime == 0) { + np->n_dmtime = dmtime; + np->n_dmtime_ticks = ticks; + } + mtx_unlock(&np->n_mtx); + cache_enter(dvp, NULL, cnp); + } else + mtx_unlock(&np->n_mtx); + } + return (ENOENT); } /* @@ -1829,7 +1889,7 @@ nfs_link(struct vop_link_args *ap) * but if negative caching is enabled, then the system * must care about lookup caching hit rate, so... */ - if (newnfs_neglookup_enable != 0 && + if (VFSTONFS(vp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY)) cache_enter(tdvp, vp, cnp); if (error && NFS_ISV4(vp)) @@ -1893,7 +1953,7 @@ nfs_symlink(struct vop_symlink_args *ap) * but if negative caching is enabled, then the system * must care about lookup caching hit rate, so... */ - if (newnfs_neglookup_enable != 0 && + if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY)) cache_enter(dvp, newvp, cnp); *ap->a_vpp = newvp; @@ -1973,7 +2033,7 @@ nfs_mkdir(struct vop_mkdir_args *ap) * but if negative caching is enabled, then the system * must care about lookup caching hit rate, so... */ - if (newnfs_neglookup_enable != 0 && + if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY)) cache_enter(dvp, newvp, cnp); *ap->a_vpp = newvp; diff --git a/sys/fs/nfsclient/nfsmount.h b/sys/fs/nfsclient/nfsmount.h index 2f0ada61dc7..9fd93311e68 100644 --- a/sys/fs/nfsclient/nfsmount.h +++ b/sys/fs/nfsclient/nfsmount.h @@ -69,6 +69,7 @@ struct nfsmount { u_int64_t nm_maxfilesize; /* maximum file size */ int nm_tprintf_initial_delay; /* initial delay */ int nm_tprintf_delay; /* interval for messages */ + int nm_negnametimeo; /* timeout for -ve entries (sec) */ /* Newnfs additions */ struct nfsclclient *nm_clp; @@ -99,6 +100,10 @@ struct nfsmount { */ #define VFSTONFS(mp) ((struct nfsmount *)((mp)->mnt_data)) +#ifndef NFS_DEFAULT_NEGNAMETIMEO +#define NFS_DEFAULT_NEGNAMETIMEO 60 +#endif + #endif /* _KERNEL */ #endif /* _NFSCLIENT_NFSMOUNT_H_ */ diff --git a/sys/fs/nfsclient/nfsnode.h b/sys/fs/nfsclient/nfsnode.h index c0610c96cff..3a5731a3bf1 100644 --- a/sys/fs/nfsclient/nfsnode.h +++ b/sys/fs/nfsclient/nfsnode.h @@ -108,6 +108,7 @@ struct nfsnode { struct timespec n_mtime; /* Prev modify time. */ time_t n_ctime; /* Prev create time. */ time_t n_dmtime; /* Prev dir modify time. */ + int n_dmtime_ticks; /* Tick of -ve cache entry */ time_t n_expiry; /* Lease expiry time */ struct nfsfh *n_fhp; /* NFS File Handle */ struct vnode *n_vnode; /* associated vnode */ From 3390bcf4cfe57fd04d63a7f892bb2a236a658321 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Sun, 14 Feb 2010 09:34:27 +0000 Subject: [PATCH 1427/2592] Merge r200530 from head: Don't panic on failure to attach if we fail before or during the if_alloc() of ifp. This fixes the panic reported in the PRs, but not the attach failure. PR: kern/139079, kern/143874 Tested by: Steven Noonan Reviewed by: thompsa --- sys/dev/wpi/if_wpi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index af51f60269c..0517e6b22ba 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -713,13 +713,14 @@ wpi_detach(device_t dev) { struct wpi_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic; int ac; - ieee80211_draintask(ic, &sc->sc_restarttask); - ieee80211_draintask(ic, &sc->sc_radiotask); - if (ifp != NULL) { + ic = ifp->if_l2com; + + ieee80211_draintask(ic, &sc->sc_restarttask); + ieee80211_draintask(ic, &sc->sc_radiotask); wpi_stop(sc); callout_drain(&sc->watchdog_to); callout_drain(&sc->calib_to); From d53236783dc53a7bfc42b014826680853f5de63f Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Sun, 14 Feb 2010 09:37:13 +0000 Subject: [PATCH 1428/2592] Merge r203636 from head: Correct arguments to free_unr(), "item" was missing. --- share/man/man9/alloc_unr.9 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man9/alloc_unr.9 b/share/man/man9/alloc_unr.9 index ee805a3bda5..2ba93e6f984 100644 --- a/share/man/man9/alloc_unr.9 +++ b/share/man/man9/alloc_unr.9 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 23, 2005 +.Dd February 7, 2010 .Dt ALLOC_UNR 9 .Os .Sh NAME @@ -81,7 +81,7 @@ is returned. Same as .Fn alloc_unr except that mutex is assumed to be already locked and thus is not used. -.It Fn free_unr uh +.It Fn free_unr uh item Free a previously allocated unit number. This function may require allocating memory, and thus it can sleep. There is no pre-locked variant. From b6e226e6aae7d623ee4941bcc13b1f22be58e0b5 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Sun, 14 Feb 2010 09:40:58 +0000 Subject: [PATCH 1429/2592] Merge r203620,203621 from head: Document support for the D-Link DFE520-TX card (supported with the vr(4) driver) PR: kern/135989 Submitted by: "Rashid N. Achilov" citycat4 ngs.ru --- share/man/man4/vr.4 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/share/man/man4/vr.4 b/share/man/man4/vr.4 index c1ec7d1e81f..0774a53bd34 100644 --- a/share/man/man4/vr.4 +++ b/share/man/man4/vr.4 @@ -30,7 +30,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 11, 2008 +.Dd February 7, 2010 .Dt VR 4 .Os .Sh NAME @@ -130,6 +130,8 @@ Fast Ethernet adapters including: .It AOpen/Acer ALN-320 .It +D-Link DFE520-TX +.It D-Link DFE530-TX .It Hawking Technologies PN102TX From a83e66390839874d7c5c1b52499f0a040088e3f2 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Sun, 14 Feb 2010 09:48:53 +0000 Subject: [PATCH 1430/2592] Merge r203310,203547,203717 from head: Implement the "-i" option to sysctl(8), to ignore failures while retrieving individual OIDs. This allows the same list of OIDs to be passed to sysctl(8) across different systems where particular OIDs may not exist, and still get as much information as possible from them. PR: bin/123644 Submitted by: dhw --- sbin/sysctl/sysctl.8 | 10 ++++++++-- sbin/sysctl/sysctl.c | 13 +++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8 index 4084290284e..1f5c8e6af77 100644 --- a/sbin/sysctl/sysctl.8 +++ b/sbin/sysctl/sysctl.8 @@ -28,7 +28,7 @@ .\" From: @(#)sysctl.8 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd November 28, 2007 +.Dd February 6, 2010 .Dt SYSCTL 8 .Os .Sh NAME @@ -36,7 +36,7 @@ .Nd get or set kernel state .Sh SYNOPSIS .Nm -.Op Fl bdehNnoqx +.Op Fl bdehiNnoqx .Ar name Ns Op = Ns Ar value .Ar ... .Nm @@ -82,6 +82,12 @@ or is specified, or a variable is being set. .It Fl h Format output for human, rather than machine, readability. +.It Fl i +Ignore unknown OIDs. +The purpose is to make use of +.Nm +for collecting data from a variety of machines (not all of which +are necessarily running exactly the same software) easier. .It Fl N Show only variable names, not their values. This is particularly useful with shells that offer programmable diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c index 4140fb3a586..3c1f3648ed7 100644 --- a/sbin/sysctl/sysctl.c +++ b/sbin/sysctl/sysctl.c @@ -58,8 +58,8 @@ static const char rcsid[] = #include #include -static int aflag, bflag, dflag, eflag, hflag, Nflag, nflag, oflag; -static int qflag, xflag, warncount; +static int aflag, bflag, dflag, eflag, hflag, iflag; +static int Nflag, nflag, oflag, qflag, xflag, warncount; static int oidfmt(int *, int, char *, u_int *); static void parse(char *); @@ -75,7 +75,7 @@ usage(void) { (void)fprintf(stderr, "%s\n%s\n", - "usage: sysctl [-bdehNnoqx] name[=value] ...", + "usage: sysctl [-bdehiNnoqx] name[=value] ...", " sysctl [-bdehNnoqx] -a"); exit(1); } @@ -89,7 +89,7 @@ main(int argc, char **argv) setbuf(stdout,0); setbuf(stderr,0); - while ((ch = getopt(argc, argv, "AabdehNnoqwxX")) != -1) { + while ((ch = getopt(argc, argv, "AabdehiNnoqwxX")) != -1) { switch (ch) { case 'A': /* compatibility */ @@ -110,6 +110,9 @@ main(int argc, char **argv) case 'h': hflag = 1; break; + case 'i': + iflag = 1; + break; case 'N': Nflag = 1; break; @@ -187,6 +190,8 @@ parse(char *string) len = name2oid(bufp, mib); if (len < 0) { + if (iflag) + return; if (qflag) exit(1); else From 1ea944617193c01bffcf8b5a011ea9bd6d5438ef Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 11:53:51 +0000 Subject: [PATCH 1431/2592] MFC r202150, r202170: Make OSS_GETVERSION ioctl really work. It has 'M' group, not 'P', as different nearby ones, and was grabbed by MIXER_xxx() handler. While there, replace '(cmd & MIXER_xxx(0)) == MIXER_xxx(0)' expressions with more correct '(cmd & ~0xff) == MIXER_xxx(0)'. Use of bit operations to compare numeric fields doesn't looks sane. --- sys/dev/sound/pcm/dsp.c | 12 ++++--- sys/dev/sound/pcm/mixer.c | 66 +++++++++++++++++---------------------- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 66faef13c15..54c165fa67a 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -1003,7 +1003,7 @@ dsp_ioctl_channel(struct cdev *dev, struct pcm_channel *volch, u_long cmd, if (volch != NULL && ((j == SOUND_MIXER_PCM && volch->direction == PCMDIR_PLAY) || (j == SOUND_MIXER_RECLEV && volch->direction == PCMDIR_REC))) { - if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) { + if ((cmd & ~0xff) == MIXER_WRITE(0)) { int left, right, center; left = *(int *)arg & 0x7f; @@ -1011,7 +1011,7 @@ dsp_ioctl_channel(struct cdev *dev, struct pcm_channel *volch, u_long cmd, center = (left + right) >> 1; chn_setvolume_multi(volch, SND_VOL_C_PCM, left, right, center); - } else if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) { + } else if ((cmd & ~0xff) == MIXER_READ(0)) { *(int *)arg = CHN_GETVOLUME(volch, SND_VOL_C_PCM, SND_CHN_T_FL); *(int *)arg |= CHN_GETVOLUME(volch, @@ -1023,7 +1023,7 @@ dsp_ioctl_channel(struct cdev *dev, struct pcm_channel *volch, u_long cmd, case SOUND_MIXER_DEVMASK: case SOUND_MIXER_CAPS: case SOUND_MIXER_STEREODEVS: - if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) { + if ((cmd & ~0xff) == MIXER_READ(0)) { *(int *)arg = 0; if (rdch != NULL) *(int *)arg |= SOUND_MASK_RECLEV; @@ -1034,7 +1034,7 @@ dsp_ioctl_channel(struct cdev *dev, struct pcm_channel *volch, u_long cmd, break; case SOUND_MIXER_RECMASK: case SOUND_MIXER_RECSRC: - if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) + if ((cmd & ~0xff) == MIXER_READ(0)) *(int *)arg = 0; ret = 0; break; @@ -1069,6 +1069,10 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, chn = NULL; if (IOCGROUP(cmd) == 'M') { + if (cmd == OSS_GETVERSION) { + *arg_i = SOUND_VERSION; + return (0); + } ret = dsp_ioctl_channel(i_dev, PCM_VOLCH(i_dev), cmd, arg); if (ret != -1) { PCM_GIANT_EXIT(d); diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c index fdef0d5b372..4c60c50d5c5 100644 --- a/sys/dev/sound/pcm/mixer.c +++ b/sys/dev/sound/pcm/mixer.c @@ -1136,7 +1136,7 @@ mixer_ioctl_channel(struct cdev *dev, u_long cmd, caddr_t arg, int mode, if ((j == SOUND_MIXER_DEVMASK || j == SOUND_MIXER_CAPS || j == SOUND_MIXER_STEREODEVS) && - (cmd & MIXER_READ(0)) == MIXER_READ(0)) { + (cmd & ~0xff) == MIXER_READ(0)) { snd_mtxlock(m->lock); *(int *)arg = mix_getdevs(m); snd_mtxunlock(m->lock); @@ -1154,14 +1154,14 @@ mixer_ioctl_channel_proc: KASSERT(c != NULL, ("%s(): NULL channel", __func__)); CHN_LOCKASSERT(c); - if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) { + if ((cmd & ~0xff) == MIXER_WRITE(0)) { int left, right, center; left = *(int *)arg & 0x7f; right = (*(int *)arg >> 8) & 0x7f; center = (left + right) >> 1; chn_setvolume_multi(c, SND_VOL_C_PCM, left, right, center); - } else if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) { + } else if ((cmd & ~0xff) == MIXER_READ(0)) { *(int *)arg = CHN_GETVOLUME(c, SND_VOL_C_PCM, SND_CHN_T_FL); *(int *)arg |= CHN_GETVOLUME(c, SND_VOL_C_PCM, SND_CHN_T_FR) << 8; @@ -1214,7 +1214,7 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td, int from) { struct snd_mixer *m; - int ret, *arg_i = (int *)arg; + int ret = EINVAL, *arg_i = (int *)arg; int v = -1, j = cmd & 0xff; /* @@ -1248,8 +1248,23 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, snd_mtxunlock(m->lock); return (EBADF); } - - if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) { + switch (cmd) { + case SNDCTL_DSP_GET_RECSRC_NAMES: + bcopy((void *)&m->enuminfo, arg, sizeof(oss_mixer_enuminfo)); + ret = 0; + goto done; + case SNDCTL_DSP_GET_RECSRC: + ret = mixer_get_recroute(m, arg_i); + goto done; + case SNDCTL_DSP_SET_RECSRC: + ret = mixer_set_recroute(m, *arg_i); + goto done; + case OSS_GETVERSION: + *arg_i = SOUND_VERSION; + ret = 0; + goto done; + } + if ((cmd & ~0xff) == MIXER_WRITE(0)) { if (j == SOUND_MIXER_RECSRC) ret = mixer_setrecsrc(m, *arg_i); else @@ -1257,23 +1272,19 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, snd_mtxunlock(m->lock); return ((ret == 0) ? 0 : ENXIO); } - - if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) { + if ((cmd & ~0xff) == MIXER_READ(0)) { switch (j) { - case SOUND_MIXER_DEVMASK: - case SOUND_MIXER_CAPS: - case SOUND_MIXER_STEREODEVS: + case SOUND_MIXER_DEVMASK: + case SOUND_MIXER_CAPS: + case SOUND_MIXER_STEREODEVS: v = mix_getdevs(m); break; - - case SOUND_MIXER_RECMASK: + case SOUND_MIXER_RECMASK: v = mix_getrecdevs(m); break; - - case SOUND_MIXER_RECSRC: + case SOUND_MIXER_RECSRC: v = mixer_getrecsrc(m); break; - default: v = mixer_get(m, j); } @@ -1281,29 +1292,8 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, snd_mtxunlock(m->lock); return ((v != -1) ? 0 : ENXIO); } - - ret = 0; - - switch (cmd) { - case SNDCTL_DSP_GET_RECSRC_NAMES: - bcopy((void *)&m->enuminfo, arg, sizeof(oss_mixer_enuminfo)); - break; - case SNDCTL_DSP_GET_RECSRC: - ret = mixer_get_recroute(m, arg_i); - break; - case SNDCTL_DSP_SET_RECSRC: - ret = mixer_set_recroute(m, *arg_i); - break; - case OSS_GETVERSION: - *arg_i = SOUND_VERSION; - break; - default: - ret = EINVAL; - break; - } - +done: snd_mtxunlock(m->lock); - return (ret); } From 66a894f383fb41d1d1f7d8bc1d238141def258f9 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 12:00:23 +0000 Subject: [PATCH 1432/2592] MFC r203484: Do not release device, when changing number of openings. --- sys/dev/mpt/mpt_cam.c | 1 + sys/dev/mpt/mpt_raid.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index cd3048de664..6ae6bbedf09 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -2553,6 +2553,7 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req, } xpt_setup_ccb(&crs.ccb_h, tmppath, 5); crs.ccb_h.func_code = XPT_REL_SIMQ; + crs.ccb_h.flags = CAM_DEV_QFREEZE; crs.release_flags = RELSIM_ADJUST_OPENINGS; crs.openings = pqf->CurrentDepth - 1; xpt_action((union ccb *)&crs); diff --git a/sys/dev/mpt/mpt_raid.c b/sys/dev/mpt/mpt_raid.c index 6b7eb7b46c4..c576a9eab9a 100644 --- a/sys/dev/mpt/mpt_raid.c +++ b/sys/dev/mpt/mpt_raid.c @@ -1062,6 +1062,7 @@ mpt_adjust_queue_depth(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol, xpt_setup_ccb(&crs.ccb_h, path, /*priority*/5); crs.ccb_h.func_code = XPT_REL_SIMQ; + crs.ccb_h.flags = CAM_DEV_QFREEZE; crs.release_flags = RELSIM_ADJUST_OPENINGS; crs.openings = mpt->raid_queue_depth; xpt_action((union ccb *)&crs); From 9a1be4e8d1e6dd22851ec79b8255f0fa0feec372 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 12:03:04 +0000 Subject: [PATCH 1433/2592] MFC r203489: Return CAM_RELEASE_SIMQ flag only when it is needed, when SIM really was frozen before and should be released. --- sys/dev/ciss/ciss.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index c5ad417e70c..2a5b145b8d0 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -3101,6 +3101,7 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio) */ if ((error = ciss_get_request(sc, &cr)) != 0) { xpt_freeze_simq(sim, 1); + csio->ccb_h.status |= CAM_RELEASE_SIMQ; csio->ccb_h.status |= CAM_REQUEUE_REQ; return(error); } @@ -3152,8 +3153,8 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio) */ if ((error = ciss_start(cr)) != 0) { xpt_freeze_simq(sim, 1); + csio->ccb_h.status |= CAM_RELEASE_SIMQ; if (error == EINPROGRESS) { - csio->ccb_h.status |= CAM_RELEASE_SIMQ; error = 0; } else { csio->ccb_h.status |= CAM_REQUEUE_REQ; @@ -3181,7 +3182,7 @@ ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio) if (CISS_IS_PHYSICAL(bus)) { if (sc->ciss_physical[CISS_CAM_TO_PBUS(bus)][target].cp_online != 1) { - csio->ccb_h.status = CAM_SEL_TIMEOUT; + csio->ccb_h.status |= CAM_SEL_TIMEOUT; xpt_done((union ccb *)csio); return(1); } else @@ -3194,7 +3195,7 @@ ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio) * Other errors might be better. */ if (sc->ciss_logical[bus][target].cl_status != CISS_LD_ONLINE) { - csio->ccb_h.status = CAM_SEL_TIMEOUT; + csio->ccb_h.status |= CAM_SEL_TIMEOUT; xpt_done((union ccb *)csio); return(1); } @@ -3208,7 +3209,7 @@ ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio) if (((csio->ccb_h.flags & CAM_CDB_POINTER) ? *(u_int8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes[0]) == SYNCHRONIZE_CACHE) { ciss_flush_adapter(sc); - csio->ccb_h.status = CAM_REQ_CMP; + csio->ccb_h.status |= CAM_REQ_CMP; xpt_done((union ccb *)csio); return(1); } @@ -3269,13 +3270,13 @@ ciss_cam_complete(struct ciss_request *cr) /* no status due to adapter error */ case -1: debug(0, "adapter error"); - csio->ccb_h.status = CAM_REQ_CMP_ERR; + csio->ccb_h.status |= CAM_REQ_CMP_ERR; break; /* no status due to command completed OK */ case SCSI_STATUS_OK: /* CISS_SCSI_STATUS_GOOD */ debug(2, "SCSI_STATUS_OK"); - csio->ccb_h.status = CAM_REQ_CMP; + csio->ccb_h.status |= CAM_REQ_CMP; break; /* check condition, sense data included */ @@ -3286,7 +3287,7 @@ ciss_cam_complete(struct ciss_request *cr) bcopy(&ce->sense_info[0], &csio->sense_data, ce->sense_length); csio->sense_len = ce->sense_length; csio->resid = ce->residual_count; - csio->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; + csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; #ifdef CISS_DEBUG { struct scsi_sense_data *sns = (struct scsi_sense_data *)&ce->sense_info[0]; @@ -3297,21 +3298,18 @@ ciss_cam_complete(struct ciss_request *cr) case SCSI_STATUS_BUSY: /* CISS_SCSI_STATUS_BUSY */ debug(0, "SCSI_STATUS_BUSY"); - csio->ccb_h.status = CAM_SCSI_BUSY; + csio->ccb_h.status |= CAM_SCSI_BUSY; break; default: debug(0, "unknown status 0x%x", csio->scsi_status); - csio->ccb_h.status = CAM_REQ_CMP_ERR; + csio->ccb_h.status |= CAM_REQ_CMP_ERR; break; } /* handle post-command fixup */ ciss_cam_complete_fixup(sc, csio); - /* tell CAM we're ready for more commands */ - csio->ccb_h.status |= CAM_RELEASE_SIMQ; - ciss_release_request(cr); xpt_done((union ccb *)csio); } From 6228bcd1ee400d43a1f470d91bb8f9f13ec5d410 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 12:04:25 +0000 Subject: [PATCH 1434/2592] MFC r203524: When hacking INQUIRY result, make sure that it is right INQUIRY and there is enough of result to hack. --- sys/dev/ciss/ciss.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index 2a5b145b8d0..2455004230e 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -3322,10 +3322,15 @@ ciss_cam_complete_fixup(struct ciss_softc *sc, struct ccb_scsiio *csio) { struct scsi_inquiry_data *inq; struct ciss_ldrive *cl; + uint8_t *cdb; int bus, target; - if (((csio->ccb_h.flags & CAM_CDB_POINTER) ? - *(u_int8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes[0]) == INQUIRY) { + cdb = (csio->ccb_h.flags & CAM_CDB_POINTER) ? + (uint8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes; + if (cdb[0] == INQUIRY && + (cdb[1] & SI_EVPD) == 0 && + (csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN && + csio->dxfer_len >= SHORT_INQUIRY_LENGTH) { inq = (struct scsi_inquiry_data *)csio->data_ptr; target = csio->ccb_h.target_id; From 20bbf2de820809c383f3affabf39e76f31406f5d Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 12:24:12 +0000 Subject: [PATCH 1435/2592] MFp4: After last running command completed, give commands in timeout state second time. --- sys/dev/siis/siis.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 1c6a2bb17e1..b8820d2af2b 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -1056,6 +1056,28 @@ siis_process_timeout(device_t dev) } } +/* Must be called with channel locked. */ +static void +siis_rearm_timeout(device_t dev) +{ + struct siis_channel *ch = device_get_softc(dev); + int i; + + mtx_assert(&ch->mtx, MA_OWNED); + for (i = 0; i < SIIS_MAX_SLOTS; i++) { + struct siis_slot *slot = &ch->slot[i]; + + /* Do we have a running request on slot? */ + if (slot->state < SIIS_SLOT_RUNNING) + continue; + if ((ch->toslots & (1 << i)) == 0) + continue; + callout_reset(&slot->timeout, + (int)slot->ccb->ccb_h.timeout * hz / 1000, + (timeout_t*)siis_timeout, slot); + } +} + /* Locked by callout mechanism. */ static void siis_timeout(struct siis_slot *slot) @@ -1216,8 +1238,9 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) 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); + } else if ((ch->rslots & ~ch->toslots) == 0 && + et != SIIS_ERR_TIMEOUT) + siis_rearm_timeout(dev); } static void From 82368eed5151086a96b2d1316c37d926cbc8a70f Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:23:05 +0000 Subject: [PATCH 1436/2592] MFC r202699: Make ata_getrev() an optional method by implementing ata_null_getrev(). This fixes a bogus '???' boot message on Cambria boards with a CompactFlash card. --- sys/dev/ata/ata_if.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/dev/ata/ata_if.m b/sys/dev/ata/ata_if.m index a1775ac6ee7..4b9fea37d3f 100644 --- a/sys/dev/ata/ata_if.m +++ b/sys/dev/ata/ata_if.m @@ -71,10 +71,17 @@ METHOD int setmode { int mode; } DEFAULT ata_null_setmode; +CODE { + static int ata_null_getrev(device_t dev, int target) + { + return (0); + } +}; + METHOD int getrev { device_t dev; int target; -}; +} DEFAULT ata_null_getrev; METHOD void reset { device_t channel; From 9290c85988e864de698cfb7947c9a351f4cb9e96 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:28:45 +0000 Subject: [PATCH 1437/2592] MFC r203030: Add support for SATA part of Marvell 88SE912x controllers to ahci(4). Limit early revisions from 6Gb/s to 3Gb/s by default, or they negotiate only 1.5Gb/s, when 3Gb/s devices connected. Add dummy driver for PATA part of these controllers, preventing generic driver attach them. It causes system freeze when SATA controller used after PATA was touched. --- sys/dev/ahci/ahci.c | 273 +++++++++++++++-------------- sys/dev/ata/ata-pci.c | 1 + sys/dev/ata/ata-pci.h | 1 + sys/dev/ata/chipsets/ata-marvell.c | 19 +- 4 files changed, 162 insertions(+), 132 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index bdb49a66800..bf6ab22eca2 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -98,6 +98,7 @@ MALLOC_DEFINE(M_AHCI, "AHCI driver", "AHCI driver data buffers"); static struct { uint32_t id; + uint8_t rev; const char *name; int quirks; #define AHCI_Q_NOFORCE 1 @@ -107,135 +108,138 @@ static struct { #define AHCI_Q_2CH 16 #define AHCI_Q_4CH 32 #define AHCI_Q_EDGEIS 64 +#define AHCI_Q_SATA2 128 } 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", AHCI_Q_NOFORCE}, - {0x26538086, "Intel ICH6M", AHCI_Q_NOFORCE}, - {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}, - {0x2361197b, "JMicron JMB361", AHCI_Q_NOFORCE}, - {0x2363197b, "JMicron JMB363", AHCI_Q_NOFORCE}, - {0x2365197b, "JMicron JMB365", AHCI_Q_NOFORCE}, - {0x2366197b, "JMicron JMB366", AHCI_Q_NOFORCE}, - {0x2368197b, "JMicron JMB368", AHCI_Q_NOFORCE}, - {0x611111ab, "Marvell 88SX6111", AHCI_Q_NOFORCE|AHCI_Q_1CH|AHCI_Q_EDGEIS}, - {0x612111ab, "Marvell 88SX6121", AHCI_Q_NOFORCE|AHCI_Q_2CH|AHCI_Q_EDGEIS}, - {0x614111ab, "Marvell 88SX6141", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS}, - {0x614511ab, "Marvell 88SX6145", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS}, - {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} + {0x43801002, 0x00, "ATI IXP600", 0}, + {0x43901002, 0x00, "ATI IXP700", 0}, + {0x43911002, 0x00, "ATI IXP700", 0}, + {0x43921002, 0x00, "ATI IXP700", 0}, + {0x43931002, 0x00, "ATI IXP700", 0}, + {0x43941002, 0x00, "ATI IXP800", 0}, + {0x43951002, 0x00, "ATI IXP800", 0}, + {0x26528086, 0x00, "Intel ICH6", AHCI_Q_NOFORCE}, + {0x26538086, 0x00, "Intel ICH6M", AHCI_Q_NOFORCE}, + {0x26818086, 0x00, "Intel ESB2", 0}, + {0x26828086, 0x00, "Intel ESB2", 0}, + {0x26838086, 0x00, "Intel ESB2", 0}, + {0x27c18086, 0x00, "Intel ICH7", 0}, + {0x27c38086, 0x00, "Intel ICH7", 0}, + {0x27c58086, 0x00, "Intel ICH7M", 0}, + {0x27c68086, 0x00, "Intel ICH7M", 0}, + {0x28218086, 0x00, "Intel ICH8", 0}, + {0x28228086, 0x00, "Intel ICH8", 0}, + {0x28248086, 0x00, "Intel ICH8", 0}, + {0x28298086, 0x00, "Intel ICH8M", 0}, + {0x282a8086, 0x00, "Intel ICH8M", 0}, + {0x29228086, 0x00, "Intel ICH9", 0}, + {0x29238086, 0x00, "Intel ICH9", 0}, + {0x29248086, 0x00, "Intel ICH9", 0}, + {0x29258086, 0x00, "Intel ICH9", 0}, + {0x29278086, 0x00, "Intel ICH9", 0}, + {0x29298086, 0x00, "Intel ICH9M", 0}, + {0x292a8086, 0x00, "Intel ICH9M", 0}, + {0x292b8086, 0x00, "Intel ICH9M", 0}, + {0x292c8086, 0x00, "Intel ICH9M", 0}, + {0x292f8086, 0x00, "Intel ICH9M", 0}, + {0x294d8086, 0x00, "Intel ICH9", 0}, + {0x294e8086, 0x00, "Intel ICH9M", 0}, + {0x3a058086, 0x00, "Intel ICH10", 0}, + {0x3a228086, 0x00, "Intel ICH10", 0}, + {0x3a258086, 0x00, "Intel ICH10", 0}, + {0x3b228086, 0x00, "Intel PCH", 0}, + {0x3b238086, 0x00, "Intel PCH", 0}, + {0x3b248086, 0x00, "Intel PCH", 0}, + {0x3b258086, 0x00, "Intel PCH", 0}, + {0x3b298086, 0x00, "Intel PCH", 0}, + {0x3b2b8086, 0x00, "Intel PCH", 0}, + {0x3b2c8086, 0x00, "Intel PCH", 0}, + {0x3b2f8086, 0x00, "Intel PCH", 0}, + {0x2361197b, 0x00, "JMicron JMB361", AHCI_Q_NOFORCE}, + {0x2363197b, 0x00, "JMicron JMB363", AHCI_Q_NOFORCE}, + {0x2365197b, 0x00, "JMicron JMB365", AHCI_Q_NOFORCE}, + {0x2366197b, 0x00, "JMicron JMB366", AHCI_Q_NOFORCE}, + {0x2368197b, 0x00, "JMicron JMB368", AHCI_Q_NOFORCE}, + {0x611111ab, 0x00, "Marvell 88SX6111", AHCI_Q_NOFORCE|AHCI_Q_1CH|AHCI_Q_EDGEIS}, + {0x612111ab, 0x00, "Marvell 88SX6121", AHCI_Q_NOFORCE|AHCI_Q_2CH|AHCI_Q_EDGEIS}, + {0x614111ab, 0x00, "Marvell 88SX6141", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS}, + {0x614511ab, 0x00, "Marvell 88SX6145", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS}, + {0x91231b4b, 0x11, "Marvell 88SE912x", 0}, + {0x91231b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_SATA2}, + {0x044c10de, 0x00, "NVIDIA MCP65", 0}, + {0x044d10de, 0x00, "NVIDIA MCP65", 0}, + {0x044e10de, 0x00, "NVIDIA MCP65", 0}, + {0x044f10de, 0x00, "NVIDIA MCP65", 0}, + {0x045c10de, 0x00, "NVIDIA MCP65", 0}, + {0x045d10de, 0x00, "NVIDIA MCP65", 0}, + {0x045e10de, 0x00, "NVIDIA MCP65", 0}, + {0x045f10de, 0x00, "NVIDIA MCP65", 0}, + {0x055010de, 0x00, "NVIDIA MCP67", 0}, + {0x055110de, 0x00, "NVIDIA MCP67", 0}, + {0x055210de, 0x00, "NVIDIA MCP67", 0}, + {0x055310de, 0x00, "NVIDIA MCP67", 0}, + {0x055410de, 0x00, "NVIDIA MCP67", 0}, + {0x055510de, 0x00, "NVIDIA MCP67", 0}, + {0x055610de, 0x00, "NVIDIA MCP67", 0}, + {0x055710de, 0x00, "NVIDIA MCP67", 0}, + {0x055810de, 0x00, "NVIDIA MCP67", 0}, + {0x055910de, 0x00, "NVIDIA MCP67", 0}, + {0x055A10de, 0x00, "NVIDIA MCP67", 0}, + {0x055B10de, 0x00, "NVIDIA MCP67", 0}, + {0x058410de, 0x00, "NVIDIA MCP67", 0}, + {0x07f010de, 0x00, "NVIDIA MCP73", 0}, + {0x07f110de, 0x00, "NVIDIA MCP73", 0}, + {0x07f210de, 0x00, "NVIDIA MCP73", 0}, + {0x07f310de, 0x00, "NVIDIA MCP73", 0}, + {0x07f410de, 0x00, "NVIDIA MCP73", 0}, + {0x07f510de, 0x00, "NVIDIA MCP73", 0}, + {0x07f610de, 0x00, "NVIDIA MCP73", 0}, + {0x07f710de, 0x00, "NVIDIA MCP73", 0}, + {0x07f810de, 0x00, "NVIDIA MCP73", 0}, + {0x07f910de, 0x00, "NVIDIA MCP73", 0}, + {0x07fa10de, 0x00, "NVIDIA MCP73", 0}, + {0x07fb10de, 0x00, "NVIDIA MCP73", 0}, + {0x0ad010de, 0x00, "NVIDIA MCP77", 0}, + {0x0ad110de, 0x00, "NVIDIA MCP77", 0}, + {0x0ad210de, 0x00, "NVIDIA MCP77", 0}, + {0x0ad310de, 0x00, "NVIDIA MCP77", 0}, + {0x0ad410de, 0x00, "NVIDIA MCP77", 0}, + {0x0ad510de, 0x00, "NVIDIA MCP77", 0}, + {0x0ad610de, 0x00, "NVIDIA MCP77", 0}, + {0x0ad710de, 0x00, "NVIDIA MCP77", 0}, + {0x0ad810de, 0x00, "NVIDIA MCP77", 0}, + {0x0ad910de, 0x00, "NVIDIA MCP77", 0}, + {0x0ada10de, 0x00, "NVIDIA MCP77", 0}, + {0x0adb10de, 0x00, "NVIDIA MCP77", 0}, + {0x0ab410de, 0x00, "NVIDIA MCP79", 0}, + {0x0ab510de, 0x00, "NVIDIA MCP79", 0}, + {0x0ab610de, 0x00, "NVIDIA MCP79", 0}, + {0x0ab710de, 0x00, "NVIDIA MCP79", 0}, + {0x0ab810de, 0x00, "NVIDIA MCP79", 0}, + {0x0ab910de, 0x00, "NVIDIA MCP79", 0}, + {0x0aba10de, 0x00, "NVIDIA MCP79", 0}, + {0x0abb10de, 0x00, "NVIDIA MCP79", 0}, + {0x0abc10de, 0x00, "NVIDIA MCP79", 0}, + {0x0abd10de, 0x00, "NVIDIA MCP79", 0}, + {0x0abe10de, 0x00, "NVIDIA MCP79", 0}, + {0x0abf10de, 0x00, "NVIDIA MCP79", 0}, + {0x0d8410de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8510de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8610de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8710de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8810de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8910de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8a10de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8b10de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8c10de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8d10de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8e10de, 0x00, "NVIDIA MCP89", 0}, + {0x0d8f10de, 0x00, "NVIDIA MCP89", 0}, + {0x33491106, 0x00, "VIA VT8251", 0}, + {0x62871106, 0x00, "VIA VT8251", 0}, + {0x11841039, 0x00, "SiS 966", 0}, + {0x11851039, 0x00, "SiS 968", 0}, + {0x01861039, 0x00, "SiS 968", 0}, + {0x00000000, 0x00, NULL, 0} }; static int @@ -244,6 +248,7 @@ ahci_probe(device_t dev) char buf[64]; int i, valid = 0; uint32_t devid = pci_get_devid(dev); + uint8_t revid = pci_get_revid(dev); /* Is this a possible AHCI candidate? */ if (pci_get_class(dev) == PCIC_STORAGE && @@ -253,6 +258,7 @@ ahci_probe(device_t dev) /* Is this a known AHCI chip? */ for (i = 0; ahci_ids[i].id != 0; i++) { if (ahci_ids[i].id == devid && + ahci_ids[i].rev <= revid && (valid || !(ahci_ids[i].quirks & AHCI_Q_NOFORCE))) { /* Do not attach JMicrons with single PCI function. */ if (pci_get_vendor(dev) == 0x197b && @@ -276,12 +282,14 @@ ahci_ata_probe(device_t dev) char buf[64]; int i; uint32_t devid = pci_get_devid(dev); + uint8_t revid = pci_get_revid(dev); if ((intptr_t)device_get_ivars(dev) >= 0) return (ENXIO); /* Is this a known AHCI chip? */ for (i = 0; ahci_ids[i].id != 0; i++) { - if (ahci_ids[i].id == devid) { + if (ahci_ids[i].id == devid && + ahci_ids[i].rev <= revid) { snprintf(buf, sizeof(buf), "%s AHCI SATA controller", ahci_ids[i].name); device_set_desc_copy(dev, buf); @@ -299,11 +307,14 @@ ahci_attach(device_t dev) device_t child; int error, unit, speed, i; uint32_t devid = pci_get_devid(dev); + uint8_t revid = pci_get_revid(dev); u_int32_t version; ctlr->dev = dev; i = 0; - while (ahci_ids[i].id != 0 && ahci_ids[i].id != devid) + while (ahci_ids[i].id != 0 && + (ahci_ids[i].id != devid || + ahci_ids[i].rev > revid)) i++; ctlr->quirks = ahci_ids[i].quirks; resource_int_value(device_get_name(dev), @@ -800,6 +811,8 @@ ahci_ch_attach(device_t dev) pci_get_subdevice(ctlr->dev) == 0x81e4 && ch->unit == 0) sata_rev = 1; + if (ch->quirks & AHCI_Q_SATA2) + sata_rev = 2; resource_int_value(device_get_name(dev), device_get_unit(dev), "sata_rev", &sata_rev); for (i = 0; i < 16; i++) { diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index cd877284085..8c4c01fa85e 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -877,6 +877,7 @@ ata_pcivendor2str(device_t dev) case ATA_ITE_ID: return "ITE"; case ATA_JMICRON_ID: return "JMicron"; case ATA_MARVELL_ID: return "Marvell"; + case ATA_MARVELL2_ID: return "Marvell"; case ATA_NATIONAL_ID: return "National"; case ATA_NETCELL_ID: return "Netcell"; case ATA_NVIDIA_ID: return "nVidia"; diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index 6f696a69eb4..b9c535c6ec2 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -234,6 +234,7 @@ struct ata_pci_controller { #define ATA_M88SX6121 0x612111ab #define ATA_M88SX6141 0x614111ab #define ATA_M88SX6145 0x614511ab +#define ATA_MARVELL2_ID 0x1b4b #define ATA_MICRON_ID 0x1042 #define ATA_MICRON_RZ1000 0x10001042 diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c index 0d11266aa2b..8b8c0041b10 100644 --- a/sys/dev/ata/chipsets/ata-marvell.c +++ b/sys/dev/ata/chipsets/ata-marvell.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); static int ata_marvell_chipinit(device_t dev); static int ata_marvell_ch_attach(device_t dev); static int ata_marvell_setmode(device_t dev, int target, int mode); +static int ata_marvell_dummy_chipinit(device_t dev); static int ata_marvell_edma_ch_attach(device_t dev); static int ata_marvell_edma_ch_detach(device_t dev); static int ata_marvell_edma_status(device_t dev); @@ -70,7 +71,7 @@ static void ata_marvell_edma_dmainit(device_t dev); #define MV_6042 62 #define MV_7042 72 #define MV_61XX 61 - +#define MV_91XX 91 /* * Marvell chipset support functions @@ -113,9 +114,11 @@ ata_marvell_probe(device_t dev) { ATA_M88SX6121, 0, 2, MV_61XX, ATA_UDMA6, "88SX6121" }, { ATA_M88SX6141, 0, 4, MV_61XX, ATA_UDMA6, "88SX6141" }, { ATA_M88SX6145, 0, 4, MV_61XX, ATA_UDMA6, "88SX6145" }, + { 0x91a41b4b, 0, 0, MV_91XX, ATA_UDMA6, "88SE912x" }, { 0, 0, 0, 0, 0, 0}}; - if (pci_get_vendor(dev) != ATA_MARVELL_ID) + if (pci_get_vendor(dev) != ATA_MARVELL_ID && + pci_get_vendor(dev) != ATA_MARVELL2_ID) return ENXIO; if (!(ctlr->chip = ata_match_chip(dev, ids))) @@ -133,6 +136,9 @@ ata_marvell_probe(device_t dev) case MV_61XX: ctlr->chipinit = ata_marvell_chipinit; break; + case MV_91XX: + ctlr->chipinit = ata_marvell_dummy_chipinit; + break; } return (BUS_PROBE_DEFAULT); } @@ -190,6 +196,15 @@ ata_marvell_setmode(device_t dev, int target, int mode) return (mode); } +static int +ata_marvell_dummy_chipinit(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + + ctlr->channels = 0; + return (0); +} + int ata_marvell_edma_chipinit(device_t dev) { From 50ae5fde8d275e57e290c224f774b1be55d24deb Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:38:27 +0000 Subject: [PATCH 1438/2592] MFC r203108: Large set of CAM improvements: - Unify bus reset/probe sequence. Whenever bus attached at boot or later, CAM will automatically reset and scan it. It allows to remove duplicate code from many drivers. - Any bus, attached before CAM completed it's boot-time initialization, will equally join to the process, delaying boot if needed. - New kern.cam.boot_delay loader tunable should help controllers that are still unable to register their buses in time (such as slow USB/ PCCard/ CardBus devices), by adding one more event to wait on boot. - To allow synchronization between different CAM levels, concept of requests priorities was extended. Priorities now split between several "run levels". Device can be freezed at specified level, allowing higher priority requests to pass. For example, no payload requests allowed, until PMP driver enable port. ATA XPT negotiate transfer parameters, periph driver configure caching and so on. - Frozen requests are no more counted by request allocation scheduler. It fixes deadlocks, when frozen low priority payload requests occupying slots, required by higher levels to manage theit execution. - Two last changes were holding proper ATA reinitialization and error recovery implementation. Now it is done: SATA controllers and Port Multipliers now implement automatic hot-plug and should correctly recover from timeouts and bus resets. - Improve SCSI error recovery for devices on buses without automatic sense reporting, such as ATAPI or USB. For example, it allows CAM to wait, while CD drive loads disk, instead of immediately return error status. - Decapitalize diagnostic messages and make them more readable and sensible. - Teach PMP driver to limit maximum speed on fan-out ports. - Make boot wait for PMP scan completes, and make rescan more reliable. - Fix pass driver, to return CCB to user level in case of error. - Increase number of retries in cd driver, as device may return several UAs. --- sys/cam/ata/ata_all.c | 6 +- sys/cam/ata/ata_da.c | 2 +- sys/cam/ata/ata_pmp.c | 150 ++++---- sys/cam/ata/ata_xpt.c | 121 ++++--- sys/cam/cam.c | 6 +- sys/cam/cam.h | 25 +- sys/cam/cam_ccb.h | 7 +- sys/cam/cam_periph.c | 393 ++++++++++---------- sys/cam/cam_periph.h | 6 +- sys/cam/cam_queue.h | 105 +++++- sys/cam/cam_sim.c | 3 +- sys/cam/cam_xpt.c | 662 +++++++++++++++------------------- sys/cam/cam_xpt.h | 5 + sys/cam/cam_xpt_internal.h | 1 - sys/cam/cam_xpt_periph.h | 3 - sys/cam/cam_xpt_sim.h | 8 +- sys/cam/scsi/scsi_all.c | 59 +-- sys/cam/scsi/scsi_cd.c | 48 +-- sys/cam/scsi/scsi_ch.c | 2 +- sys/cam/scsi/scsi_da.c | 2 +- sys/cam/scsi/scsi_low.c | 36 -- sys/cam/scsi/scsi_pass.c | 12 +- sys/cam/scsi/scsi_xpt.c | 65 +++- sys/dev/ahci/ahci.c | 55 ++- sys/dev/ahci/ahci.h | 15 + sys/dev/asr/asr.c | 1 - sys/dev/ata/ata-all.c | 27 +- sys/dev/ata/atapi-cam.c | 32 +- sys/dev/ciss/ciss.c | 48 +-- sys/dev/hptiop/hptiop.c | 31 +- sys/dev/hptrr/hptrr_osm_bsd.c | 32 +- sys/dev/hptrr/os_bsd.h | 1 - sys/dev/mly/mly.c | 22 +- sys/dev/mpt/mpt_cam.h | 1 - sys/dev/mpt/mpt_raid.c | 17 +- sys/dev/ppbus/vpo.c | 37 -- sys/dev/siis/siis.c | 35 +- sys/dev/trm/trm.c | 18 - sys/dev/twa/tw_osl_cam.c | 59 +-- sys/dev/usb/storage/umass.c | 77 ---- 40 files changed, 1051 insertions(+), 1184 deletions(-) diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index 25daea4eb7f..b2db7a03ce1 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -198,7 +198,7 @@ ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) { char cmd_str[(12 * 3) + 1]; - sbuf_printf(sb, "CMD: %s: %s", + sbuf_printf(sb, "%s. ACB: %s", ata_op_string(&ataio->cmd), ata_cmd_string(&ataio->cmd, cmd_str, sizeof(cmd_str))); @@ -212,7 +212,7 @@ 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)", + 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 " : "", @@ -223,7 +223,7 @@ ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) (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)", + 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 " : "", diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 8d493096bff..3408b4fa3bb 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -689,7 +689,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); if (cpi.ccb_h.status != CAM_REQ_CMP || diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c index 8c2e1bff3a2..1b8d9d5129f 100644 --- a/sys/cam/ata/ata_pmp.c +++ b/sys/cam/ata/ata_pmp.c @@ -98,6 +98,9 @@ struct pmp_softc { int reset; int frozen; int restart; + int events; +#define PMP_EV_RESET 1 +#define PMP_EV_RESCAN 2 union ccb saved_ccb; struct task sysctl_task; struct sysctl_ctx_list sysctl_ctx; @@ -179,7 +182,8 @@ pmpfreeze(struct cam_periph *periph, int mask) i, 0) == CAM_REQ_CMP) { softc->frozen |= (1 << i); xpt_acquire_device(dpath->device); - cam_freeze_devq(dpath); + cam_freeze_devq_arg(dpath, + RELSIM_RELEASE_RUNLEVEL, CAM_RL_BUS + 1); xpt_free_path(dpath); } } @@ -200,7 +204,8 @@ pmprelease(struct cam_periph *periph, int mask) xpt_path_path_id(periph->path), i, 0) == CAM_REQ_CMP) { softc->frozen &= ~(1 << i); - cam_release_devq(dpath, 0, 0, 0, FALSE); + cam_release_devq(dpath, + RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_BUS + 1, FALSE); xpt_release_device(dpath->device); xpt_free_path(dpath); } @@ -298,19 +303,20 @@ 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 (code == AC_SCSI_AEN && softc->state != PMP_STATE_NORMAL && - softc->state != PMP_STATE_SCAN) - break; - if (softc->state != PMP_STATE_SCAN) - pmpfreeze(periph, softc->found); + if (code == AC_SCSI_AEN) + softc->events |= PMP_EV_RESCAN; else - pmpfreeze(periph, softc->found & ~(1 << softc->pm_step)); + softc->events |= PMP_EV_RESET; + if (code == AC_SCSI_AEN && softc->state != PMP_STATE_NORMAL) + break; + xpt_hold_boot(); + pmpfreeze(periph, softc->found); if (code == AC_SENT_BDR || code == AC_BUS_RESET) softc->found = 0; /* We have to reset everything. */ if (softc->state == PMP_STATE_NORMAL) { - softc->state = PMP_STATE_PORTS; + softc->state = PMP_STATE_PRECONFIG; cam_periph_acquire(periph); - xpt_schedule(periph, CAM_PRIORITY_BUS); + xpt_schedule(periph, CAM_PRIORITY_DEV); } else softc->restart = 1; break; @@ -353,7 +359,6 @@ 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; @@ -377,16 +382,8 @@ pmpregister(struct cam_periph *periph, void *arg) } 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); @@ -408,7 +405,10 @@ pmpregister(struct cam_periph *periph, void *arg) * the end of probe. */ (void)cam_periph_acquire(periph); - xpt_schedule(periph, CAM_PRIORITY_BUS); + xpt_hold_boot(); + softc->state = PMP_STATE_PORTS; + softc->events = PMP_EV_RESCAN; + xpt_schedule(periph, CAM_PRIORITY_DEV); return(CAM_REQ_CMP); } @@ -416,17 +416,35 @@ pmpregister(struct cam_periph *periph, void *arg) static void pmpstart(struct cam_periph *periph, union ccb *start_ccb) { + struct ccb_trans_settings cts; struct ccb_ataio *ataio; struct pmp_softc *softc; + struct cam_path *dpath; + int revision = 0; softc = (struct pmp_softc *)periph->softc; ataio = &start_ccb->ataio; if (softc->restart) { softc->restart = 0; - softc->state = PMP_STATE_PORTS; + softc->state = min(softc->state, PMP_STATE_PRECONFIG); + } + /* Fetch user wanted device speed. */ + if (softc->state == PMP_STATE_RESET || + softc->state == PMP_STATE_CONNECT) { + if (xpt_create_path(&dpath, periph, + xpt_path_path_id(periph->path), + softc->pm_step, 0) == CAM_REQ_CMP) { + bzero(&cts, sizeof(cts)); + xpt_setup_ccb(&cts.ccb_h, dpath, CAM_PRIORITY_NONE); + cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; + cts.type = CTS_TYPE_USER_SETTINGS; + xpt_action((union ccb *)&cts); + if (cts.xport_specific.sata.valid & CTS_SATA_VALID_REVISION) + revision = cts.xport_specific.sata.revision; + xpt_free_path(dpath); + } } - switch (softc->state) { case PMP_STATE_PORTS: cam_fill_ataio(ataio, @@ -460,7 +478,8 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb) /*dxfer_len*/0, pmp_default_timeout * 1000); ata_pm_write_cmd(ataio, 2, softc->pm_step, - (softc->found & (1 << softc->pm_step)) ? 0 : 1); + (revision << 4) | + ((softc->found & (1 << softc->pm_step)) ? 0 : 1)); break; case PMP_STATE_CONNECT: cam_fill_ataio(ataio, @@ -471,7 +490,8 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb) /*data_ptr*/NULL, /*dxfer_len*/0, pmp_default_timeout * 1000); - ata_pm_write_cmd(ataio, 2, softc->pm_step, 0); + ata_pm_write_cmd(ataio, 2, softc->pm_step, + (revision << 4)); break; case PMP_STATE_CHECK: cam_fill_ataio(ataio, @@ -519,9 +539,9 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) struct ccb_trans_settings cts; struct pmp_softc *softc; struct ccb_ataio *ataio; - union ccb *work_ccb; struct cam_path *path, *dpath; u_int32_t priority, res; + int i; softc = (struct pmp_softc *)periph->softc; ataio = &done_ccb->ataio; @@ -547,16 +567,8 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) 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; + softc->state = min(softc->state, PMP_STATE_PRECONFIG); xpt_schedule(periph, priority); return; } @@ -645,7 +657,7 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) xpt_path_path_id(periph->path), softc->pm_step, 0) == CAM_REQ_CMP) { bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, dpath, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, dpath, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.xport_specific.sata.revision = (res & 0x0f0) >> 4; @@ -705,53 +717,43 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) xpt_schedule(periph, priority); return; case PMP_STATE_CONFIG: - 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); + for (i = 0; i < softc->pm_ports; i++) { + union ccb *ccb; + + if ((softc->found & (1 << i)) == 0) + continue; + if (xpt_create_path(&dpath, periph, + xpt_path_path_id(periph->path), + i, 0) != CAM_REQ_CMP) { + printf("pmpdone: xpt_create_path failed" + ", bus scan halted\n"); + xpt_free_ccb(done_ccb); + goto done; + } + /* If we did hard reset to this device, inform XPT. */ + if ((softc->reset & softc->found & (1 << i)) != 0) + xpt_async(AC_SENT_BDR, dpath, NULL); + /* If rescan requested, scan this device. */ + if (softc->events & PMP_EV_RESCAN) { + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + xpt_free_path(dpath); + goto done; + } + xpt_setup_ccb(&ccb->ccb_h, dpath, CAM_PRIORITY_XPT); + xpt_rescan(ccb); + } else + xpt_free_path(dpath); } 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); - 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); - 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; } done: xpt_release_ccb(done_ccb); softc->state = PMP_STATE_NORMAL; + softc->events = 0; + xpt_release_boot(); 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 99cf3141083..bff0340b671 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -130,6 +130,7 @@ typedef struct { u_int8_t digest[16]; uint32_t pm_pid; uint32_t pm_prv; + int restart; struct cam_periph *periph; } probe_softc; @@ -231,15 +232,11 @@ proberegister(struct cam_periph *periph, void *arg) if (status != CAM_REQ_CMP) { return (status); } - - /* - * Ensure we've waited at least a bus settle - * delay before attempting to probe the device. - * For HBAs that don't do bus resets, this won't make a difference. + * Ensure nobody slip in until probe finish. */ - cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset, - scsi_delay); + cam_freeze_devq_arg(periph->path, + RELSIM_RELEASE_RUNLEVEL, CAM_RL_XPT + 1); probeschedule(periph); return(CAM_REQ_CMP); } @@ -247,17 +244,12 @@ proberegister(struct cam_periph *periph, void *arg) static void probeschedule(struct cam_periph *periph) { - struct ccb_pathinq cpi; union ccb *ccb; probe_softc *softc; softc = (probe_softc *)periph->softc; ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs); - 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 ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) || periph->path->device->protocol == PROTO_SATAPM) PROBE_SET_ACTION(softc, PROBE_RESET); @@ -269,7 +261,7 @@ probeschedule(struct cam_periph *periph) else softc->flags &= ~PROBE_NO_ANNOUNCE; - xpt_schedule(periph, ccb->ccb_h.pinfo.priority); + xpt_schedule(periph, CAM_PRIORITY_XPT); } static void @@ -290,6 +282,14 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) csio = &start_ccb->csio; ident_buf = &periph->path->device->ident_data; + if (softc->restart) { + softc->restart = 0; + if ((path->device->flags & CAM_DEV_UNCONFIGURED) || + path->device->protocol == PROTO_SATAPM) + softc->action = PROBE_RESET; + else + softc->action = PROBE_IDENTIFY; + } switch (softc->action) { case PROBE_RESET: cam_fill_ataio(ataio, @@ -299,7 +299,7 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) 0, /*data_ptr*/NULL, /*dxfer_len*/0, - (start_ccb->ccb_h.target_id == 15 ? 3 : 15) * 1000); + 15 * 1000); ata_reset_cmd(ataio); break; case PROBE_IDENTIFY: @@ -339,7 +339,7 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) mode = 0; /* Fetch user modes from SIM. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); @@ -355,7 +355,7 @@ negotiate: wantmode = mode = ata_max_mode(ident_buf, mode); /* Report modes to SIM. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; if (path->device->transport == XPORT_ATA) { @@ -368,7 +368,7 @@ negotiate: xpt_action((union ccb *)&cts); /* Fetch current modes from SIM. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); @@ -400,7 +400,7 @@ negotiate: bytecount = 8192; /* SATA maximum */ /* Fetch user bytecount from SIM. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); @@ -416,7 +416,7 @@ negotiate: bytecount / ata_logical_sector_size(ident_buf))); /* Report bytecount to SIM. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; if (path->device->transport == XPORT_ATA) { @@ -431,7 +431,7 @@ negotiate: xpt_action((union ccb *)&cts); /* Fetch current bytecount from SIM. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); @@ -462,7 +462,7 @@ negotiate: bytecount = 8192; /* SATA maximum */ /* Fetch user bytecount from SIM. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); @@ -482,7 +482,7 @@ negotiate: } /* Report bytecount to SIM. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; if (path->device->transport == XPORT_ATA) { @@ -560,7 +560,7 @@ proberequestdefaultnegotiation(struct cam_periph *periph) { struct ccb_trans_settings cts; - xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); @@ -582,7 +582,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); @@ -739,7 +739,7 @@ noerror: done_ccb->ccb_h.target_id == 15) { /* Report SIM that PM is present. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.xport_specific.sata.pm_present = 1; @@ -836,7 +836,7 @@ noerror: path->bus->sim->max_tagged_dev_openings != 0) { /* Report SIM which tags are allowed. */ bzero(&cts, sizeof(cts)); - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.xport_specific.sata.tags = path->device->maxtags; @@ -957,18 +957,23 @@ noerror: 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; - done_ccb->ccb_h.ppriv_field1 = found; - xpt_done(done_ccb); - if (TAILQ_FIRST(&softc->request_ccbs) == NULL) { - cam_periph_invalidate(periph); - cam_periph_release_locked(periph); - } else { + if (softc->restart) { + softc->restart = 0; + xpt_release_ccb(done_ccb); probeschedule(periph); + return; } + xpt_release_ccb(done_ccb); + while ((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 = found ? CAM_REQ_CMP : CAM_REQ_CMP_ERR; + xpt_done(done_ccb); + } + cam_release_devq(periph->path, + RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE); + cam_periph_invalidate(periph); + cam_periph_release_locked(periph); } static void @@ -1013,7 +1018,7 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb) { struct cam_path *path; ata_scan_bus_info *scan_info; - union ccb *work_ccb; + union ccb *work_ccb, *reset_ccb; cam_status status; CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, @@ -1038,6 +1043,26 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb) return; } + /* We may need to reset bus first, if we haven't done it yet. */ + if ((work_ccb->cpi.hba_inquiry & + (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) && + !(work_ccb->cpi.hba_misc & PIM_NOBUSRESET) && + !timevalisset(&request_ccb->ccb_h.path->bus->last_reset)) { + reset_ccb = xpt_alloc_ccb_nowait(); + xpt_setup_ccb(&reset_ccb->ccb_h, request_ccb->ccb_h.path, + CAM_PRIORITY_NONE); + reset_ccb->ccb_h.func_code = XPT_RESET_BUS; + xpt_action(reset_ccb); + if (reset_ccb->ccb_h.status != CAM_REQ_CMP) { + request_ccb->ccb_h.status = reset_ccb->ccb_h.status; + xpt_free_ccb(reset_ccb); + xpt_free_ccb(work_ccb); + xpt_done(request_ccb); + return; + } + xpt_free_ccb(reset_ccb); + } + /* Save some state for use while we probe for devices */ scan_info = (ata_scan_bus_info *) malloc(sizeof(ata_scan_bus_info), M_CAMXPT, M_NOWAIT); @@ -1071,7 +1096,7 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb) /* If there is PMP... */ if ((scan_info->cpi->hba_inquiry & PI_SATAPM) && (scan_info->counter == scan_info->cpi->max_target)) { - if (work_ccb->ccb_h.ppriv_field1 != 0) { + if (work_ccb->ccb_h.status == CAM_REQ_CMP) { /* everything else willbe probed by it */ goto done; } else { @@ -1141,10 +1166,9 @@ ata_scan_lun(struct cam_periph *periph, struct cam_path *path, struct cam_path *new_path; struct cam_periph *old_periph; - CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("xpt_scan_lun\n")); + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_scan_lun\n")); - xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); @@ -1182,7 +1206,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&request_ccb->ccb_h, new_path, CAM_PRIORITY_XPT); request_ccb->ccb_h.cbfcnp = xptscandone; request_ccb->ccb_h.func_code = XPT_SCAN_LUN; request_ccb->crcn.flags = flags; @@ -1194,6 +1218,7 @@ ata_scan_lun(struct cam_periph *periph, struct cam_path *path, softc = (probe_softc *)old_periph->softc; TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h, periph_links.tqe); + softc->restart = 1; } else { status = cam_periph_alloc(proberegister, NULL, probecleanup, probestart, "aprobe", @@ -1281,7 +1306,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); @@ -1301,7 +1326,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.transport = path->device->transport; @@ -1429,7 +1454,7 @@ ata_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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); @@ -1450,7 +1475,7 @@ ata_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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE); cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cur_cts.type = cts->type; xpt_action((union ccb *)&cur_cts); @@ -1550,6 +1575,10 @@ ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, */ ata_scan_lun(newpath.periph, &newpath, CAM_EXPECT_INQ_CHANGE, NULL); + } else { + /* We need to reinitialize device after reset. */ + ata_scan_lun(newpath.periph, &newpath, + 0, NULL); } xpt_release_path(&newpath); } else if (async_code == AC_LOST_DEVICE && diff --git a/sys/cam/cam.c b/sys/cam/cam.c index 85b02fb9cfa..88271b0684b 100644 --- a/sys/cam/cam.c +++ b/sys/cam/cam.c @@ -305,10 +305,10 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str, entry = cam_fetch_status_entry(status); if (entry == NULL) - sbuf_printf(&sb, "CAM Status: Unknown (%#x)\n", + sbuf_printf(&sb, "CAM status: Unknown (%#x)\n", ccb->ccb_h.status); else - sbuf_printf(&sb, "CAM Status: %s\n", + sbuf_printf(&sb, "CAM status: %s\n", entry->status_text); } @@ -338,7 +338,7 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str, if (proto_flags & CAM_ESF_PRINT_STATUS) { sbuf_cat(&sb, path_str); - sbuf_printf(&sb, "SCSI Status: %s\n", + 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 3d85264f4c5..2b3b98cba60 100644 --- a/sys/cam/cam.h +++ b/sys/cam/cam.h @@ -60,16 +60,29 @@ typedef u_int lun_id_t; struct cam_periph; /* - * Priority information for a CAM structure. The generation number is - * incremented everytime a new entry is entered into the queue giving round - * robin per priority level scheduling. + * Priority information for a CAM structure. + */ +typedef enum { + CAM_RL_HOST, + CAM_RL_BUS, + CAM_RL_XPT, + CAM_RL_DEV, + CAM_RL_NORMAL, + CAM_RL_VALUES +} cam_rl; +/* + * The generation number is incremented everytime a new entry is entered into + * the queue giving round robin per priority level scheduling. */ typedef struct { u_int32_t priority; -#define CAM_PRIORITY_BUS 0 -#define CAM_PRIORITY_DEV 0 -#define CAM_PRIORITY_NORMAL 1 +#define CAM_PRIORITY_HOST ((CAM_RL_HOST << 8) + 0x80) +#define CAM_PRIORITY_BUS ((CAM_RL_BUS << 8) + 0x80) +#define CAM_PRIORITY_XPT ((CAM_RL_XPT << 8) + 0x80) +#define CAM_PRIORITY_DEV ((CAM_RL_DEV << 8) + 0x80) +#define CAM_PRIORITY_NORMAL ((CAM_RL_NORMAL << 8) + 0x80) #define CAM_PRIORITY_NONE (u_int32_t)-1 +#define CAM_PRIORITY_TO_RL(x) ((x) >> 8) u_int32_t generation; int index; #define CAM_UNQUEUED_INDEX -1 diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 72de5646725..4c5adba5418 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -126,7 +126,7 @@ typedef enum { XPT_PATH_INQ = 0x04, /* Path routing inquiry */ XPT_REL_SIMQ = 0x05, - /* Release a frozen SIM queue */ + /* Release a frozen device queue */ XPT_SASYNC_CB = 0x06, /* Set Asynchronous Callback Parameters */ XPT_SDEV_TYPE = 0x07, @@ -142,6 +142,8 @@ typedef enum { /* Path statistics (error counts, etc.) */ XPT_GDEV_STATS = 0x0c, /* Device statistics (error counts, etc.) */ + XPT_FREEZE_QUEUE = 0x0d, + /* Freeze device queue */ /* SCSI Control Functions: 0x10->0x1F */ XPT_ABORT = 0x10, /* Abort the specified CCB */ @@ -685,8 +687,9 @@ struct ccb_relsim { #define RELSIM_RELEASE_AFTER_TIMEOUT 0x02 #define RELSIM_RELEASE_AFTER_CMDCMPLT 0x04 #define RELSIM_RELEASE_AFTER_QEMPTY 0x08 +#define RELSIM_RELEASE_RUNLEVEL 0x10 u_int32_t openings; - u_int32_t release_timeout; + u_int32_t release_timeout; /* Abstract argument. */ u_int32_t qfrozen_cnt; }; diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 9bac0f5a82e..4c7502ae877 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -71,19 +71,20 @@ static void camperiphfree(struct cam_periph *periph); static int camperiphscsistatuserror(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags, - union ccb *save_ccb, int *openings, u_int32_t *relsim_flags, - u_int32_t *timeout); + u_int32_t *timeout, + const char **action_string); static int camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags, - union ccb *save_ccb, int *openings, u_int32_t *relsim_flags, - u_int32_t *timeout); + u_int32_t *timeout, + const char **action_string); static int nperiph_drivers; +static int initialized = 0; struct periph_driver **periph_drivers; MALLOC_DEFINE(M_CAMPERIPH, "CAM periph", "CAM peripheral buffers"); @@ -99,6 +100,7 @@ TUNABLE_INT("kern.cam.periph_busy_delay", &periph_busy_delay); void periphdriver_register(void *data) { + struct periph_driver *drv = (struct periph_driver *)data; struct periph_driver **newdrivers, **old; int ndrivers; @@ -108,13 +110,30 @@ periphdriver_register(void *data) if (periph_drivers) bcopy(periph_drivers, newdrivers, sizeof(*newdrivers) * nperiph_drivers); - newdrivers[nperiph_drivers] = (struct periph_driver *)data; + newdrivers[nperiph_drivers] = drv; newdrivers[nperiph_drivers + 1] = NULL; old = periph_drivers; periph_drivers = newdrivers; if (old) free(old, M_CAMPERIPH); nperiph_drivers++; + /* If driver marked as early or it is late now, initialize it. */ + if (((drv->flags & CAM_PERIPH_DRV_EARLY) != 0 && initialized > 0) || + initialized > 1) + (*drv->init)(); +} + +void +periphdriver_init(int level) +{ + int i, early; + + initialized = max(initialized, level); + for (i = 0; periph_drivers[i] != NULL; i++) { + early = (periph_drivers[i]->flags & CAM_PERIPH_DRV_EARLY) ? 1 : 2; + if (early == initialized) + (*periph_drivers[i]->init)(); + } } cam_status @@ -915,12 +934,14 @@ cam_periph_runccb(union ccb *ccb, } while (error == ERESTART); - if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) + if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { cam_release_devq(ccb->ccb_h.path, /* relsim_flags */0, /* openings */0, /* timeout */0, /* getcount_only */ FALSE); + ccb->ccb_h.status &= ~CAM_DEV_QFRZN; + } if (ds != NULL) { if (ccb->ccb_h.func_code == XPT_SCSI_IO) { @@ -950,17 +971,26 @@ cam_periph_runccb(union ccb *ccb, void cam_freeze_devq(struct cam_path *path) { - struct ccb_hdr ccb_h; - 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); + cam_freeze_devq_arg(path, 0, 0); +} + +void +cam_freeze_devq_arg(struct cam_path *path, uint32_t flags, uint32_t arg) +{ + struct ccb_relsim crs; + + xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NONE); + crs.ccb_h.func_code = XPT_FREEZE_QUEUE; + crs.release_flags = flags; + crs.openings = arg; + crs.release_timeout = arg; + xpt_action((union ccb *)&crs); } u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, - u_int32_t openings, u_int32_t timeout, + u_int32_t openings, u_int32_t arg, int getcount_only) { struct ccb_relsim crs; @@ -970,22 +1000,21 @@ cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, crs.ccb_h.flags = getcount_only ? CAM_DEV_QFREEZE : 0; crs.release_flags = relsim_flags; crs.openings = openings; - crs.release_timeout = timeout; + crs.release_timeout = arg; xpt_action((union ccb *)&crs); return (crs.qfrozen_cnt); } #define saved_ccb_ptr ppriv_ptr0 +#define recovery_depth ppriv_field1 static void -camperiphdone(struct cam_periph *periph, union ccb *done_ccb) +camperiphsensedone(struct cam_periph *periph, union ccb *done_ccb) { - union ccb *saved_ccb; + union ccb *saved_ccb = (union ccb *)done_ccb->ccb_h.saved_ccb_ptr; cam_status status; int frozen = 0; - int sense; - struct scsi_start_stop_unit *scsi_cmd; - u_int32_t relsim_flags, timeout; - int xpt_done_ccb = FALSE; + u_int sense_key; + int depth = done_ccb->ccb_h.recovery_depth; status = done_ccb->ccb_h.status; if (status & CAM_DEV_QFRZN) { @@ -996,14 +1025,83 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) */ done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN; } - sense = (status & CAM_AUTOSNS_VALID) != 0; status &= CAM_STATUS_MASK; + switch (status) { + case CAM_REQ_CMP: + { + /* + * If we manually retrieved sense into a CCB and got + * something other than "NO SENSE" send the updated CCB + * back to the client via xpt_done() to be processed via + * the error recovery code again. + */ + sense_key = saved_ccb->csio.sense_data.flags; + sense_key &= SSD_KEY; + if (sense_key != SSD_KEY_NO_SENSE) { + saved_ccb->ccb_h.status |= + CAM_AUTOSNS_VALID; + } else { + saved_ccb->ccb_h.status &= + ~CAM_STATUS_MASK; + saved_ccb->ccb_h.status |= + CAM_AUTOSENSE_FAIL; + } + bcopy(saved_ccb, done_ccb, sizeof(union ccb)); + xpt_free_ccb(saved_ccb); + break; + } + default: + bcopy(saved_ccb, done_ccb, sizeof(union ccb)); + xpt_free_ccb(saved_ccb); + done_ccb->ccb_h.status &= ~CAM_STATUS_MASK; + done_ccb->ccb_h.status |= CAM_AUTOSENSE_FAIL; + break; + } + periph->flags &= ~CAM_PERIPH_SENSE_INPROG; + /* + * If it is the end of recovery, drop freeze, taken due to + * CAM_DEV_QFREEZE flag, set on recovery request. + */ + if (depth == 0) { + cam_release_devq(done_ccb->ccb_h.path, + /*relsim_flags*/0, + /*openings*/0, + /*timeout*/0, + /*getcount_only*/0); + } + /* + * Copy frozen flag from recovery request if it is set there + * for some reason. + */ + if (frozen != 0) + done_ccb->ccb_h.status |= CAM_DEV_QFRZN; + (*done_ccb->ccb_h.cbfcnp)(periph, done_ccb); +} + +static void +camperiphdone(struct cam_periph *periph, union ccb *done_ccb) +{ + union ccb *saved_ccb, *save_ccb; + cam_status status; + int frozen = 0; + struct scsi_start_stop_unit *scsi_cmd; + u_int32_t relsim_flags, timeout; + + status = done_ccb->ccb_h.status; + if (status & CAM_DEV_QFRZN) { + frozen = 1; + /* + * Clear freeze flag now for case of retry, + * freeze will be dropped later. + */ + done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN; + } timeout = 0; relsim_flags = 0; saved_ccb = (union ccb *)done_ccb->ccb_h.saved_ccb_ptr; - switch (status) { + switch (status & CAM_STATUS_MASK) { case CAM_REQ_CMP: { /* @@ -1012,57 +1110,19 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) * the inquiry information. Many devices (mostly disks) * don't properly report their inquiry information unless * they are spun up. - * - * If we manually retrieved sense into a CCB and got - * something other than "NO SENSE" send the updated CCB - * back to the client via xpt_done() to be processed via - * the error recovery code again. */ - if (done_ccb->ccb_h.func_code == XPT_SCSI_IO) { - scsi_cmd = (struct scsi_start_stop_unit *) - &done_ccb->csio.cdb_io.cdb_bytes; + scsi_cmd = (struct scsi_start_stop_unit *) + &done_ccb->csio.cdb_io.cdb_bytes; - if (scsi_cmd->opcode == START_STOP_UNIT) - xpt_async(AC_INQ_CHANGED, - done_ccb->ccb_h.path, NULL); - if (scsi_cmd->opcode == REQUEST_SENSE) { - u_int sense_key; - - sense_key = saved_ccb->csio.sense_data.flags; - sense_key &= SSD_KEY; - if (sense_key != SSD_KEY_NO_SENSE) { - saved_ccb->ccb_h.status |= - CAM_AUTOSNS_VALID; -#if 0 - xpt_print(saved_ccb->ccb_h.path, - "Recovered Sense\n"); - scsi_sense_print(&saved_ccb->csio); - cam_error_print(saved_ccb, CAM_ESF_ALL, - CAM_EPF_ALL); -#endif - } else { - saved_ccb->ccb_h.status &= - ~CAM_STATUS_MASK; - saved_ccb->ccb_h.status |= - CAM_AUTOSENSE_FAIL; - } - xpt_done_ccb = TRUE; - } - } - bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb, - sizeof(union ccb)); - - periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG; - - if (xpt_done_ccb == FALSE) - xpt_action(done_ccb); - - break; + if (scsi_cmd->opcode == START_STOP_UNIT) + xpt_async(AC_INQ_CHANGED, + done_ccb->ccb_h.path, NULL); + goto final; } case CAM_SCSI_STATUS_ERROR: scsi_cmd = (struct scsi_start_stop_unit *) &done_ccb->csio.cdb_io.cdb_bytes; - if (sense != 0) { + if (status & CAM_AUTOSNS_VALID) { struct ccb_getdev cgd; struct scsi_sense_data *sense; int error_code, sense_key, asc, ascq; @@ -1071,7 +1131,6 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) sense = &done_ccb->csio.sense_data; scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq); - /* * Grab the inquiry data for this device. */ @@ -1081,7 +1140,6 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) xpt_action((union ccb *)&cgd); err_action = scsi_error_action(&done_ccb->csio, &cgd.inq_data, 0); - /* * If the error is "invalid field in CDB", * and the load/eject flag is set, turn the @@ -1091,7 +1149,6 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) * the load/eject flag by default for * removable media. */ - /* XXX KDM * Should we check to see what the specific * scsi status is?? Or does it not matter @@ -1106,9 +1163,7 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) (done_ccb->ccb_h.retry_count > 0)) { scsi_cmd->how &= ~SSS_LOEJ; - xpt_action(done_ccb); - } else if ((done_ccb->ccb_h.retry_count > 1) && ((err_action & SS_MASK) != SS_FAIL)) { @@ -1119,53 +1174,51 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) * it another try unless this is an * unretryable error. */ - /* set the timeout to .5 sec */ relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT; timeout = 500; - xpt_action(done_ccb); - break; - } else { /* * Perform the final retry with the original * CCB so that final error processing is * performed by the owner of the CCB. */ - bcopy(done_ccb->ccb_h.saved_ccb_ptr, - done_ccb, sizeof(union ccb)); - - periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG; - - xpt_action(done_ccb); + goto final; } } else { + save_ccb = xpt_alloc_ccb_nowait(); + if (save_ccb == NULL) + goto final; + bcopy(done_ccb, save_ccb, sizeof(*save_ccb)); + periph->flags |= CAM_PERIPH_SENSE_INPROG; /* - * Eh?? The command failed, but we don't - * have any sense. What's up with that? - * Fire the CCB again to return it to the - * caller. + * Send a Request Sense to the device. We + * assume that we are in a contingent allegiance + * condition so we do not tag this request. */ - bcopy(done_ccb->ccb_h.saved_ccb_ptr, - done_ccb, sizeof(union ccb)); - - periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG; - + scsi_request_sense(&done_ccb->csio, /*retries*/1, + camperiphsensedone, + &save_ccb->csio.sense_data, + sizeof(save_ccb->csio.sense_data), + CAM_TAG_ACTION_NONE, + /*sense_len*/SSD_FULL_SIZE, + /*timeout*/5000); + done_ccb->ccb_h.pinfo.priority--; + done_ccb->ccb_h.flags |= CAM_DEV_QFREEZE; + done_ccb->ccb_h.saved_ccb_ptr = save_ccb; + done_ccb->ccb_h.recovery_depth++; xpt_action(done_ccb); - } break; default: - bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb, - sizeof(union ccb)); - +final: + bcopy(saved_ccb, done_ccb, sizeof(*done_ccb)); + xpt_free_ccb(saved_ccb); periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG; - xpt_action(done_ccb); - break; } @@ -1188,23 +1241,13 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) /*openings*/0, /*timeout*/timeout, /*getcount_only*/0); - if (xpt_done_ccb == TRUE) { - /* - * Copy frozen flag from recovery request if it is set there - * for some reason. - */ - if (frozen != 0) - done_ccb->ccb_h.status |= CAM_DEV_QFRZN; - (*done_ccb->ccb_h.cbfcnp)(periph, done_ccb); - } else { - /* Drop freeze taken, if this recovery request got error. */ - if (frozen != 0) { - cam_release_devq(done_ccb->ccb_h.path, - /*relsim_flags*/0, - /*openings*/0, - /*timeout*/0, - /*getcount_only*/0); - } + /* Drop freeze taken, if this recovery request got error. */ + if (frozen != 0) { + cam_release_devq(done_ccb->ccb_h.path, + /*relsim_flags*/0, + /*openings*/0, + /*timeout*/0, + /*getcount_only*/0); } } @@ -1221,12 +1264,6 @@ cam_periph_async(struct cam_periph *periph, u_int32_t code, case AC_LOST_DEVICE: cam_periph_invalidate(periph); break; - case AC_SENT_BDR: - case AC_BUS_RESET: - { - cam_periph_bus_settle(periph, scsi_delay); - break; - } default: break; } @@ -1271,9 +1308,9 @@ cam_periph_freeze_after_event(struct cam_periph *periph, static int camperiphscsistatuserror(union ccb *ccb, cam_flags camflags, - u_int32_t sense_flags, union ccb *save_ccb, + u_int32_t sense_flags, int *openings, u_int32_t *relsim_flags, - u_int32_t *timeout) + u_int32_t *timeout, const char **action_string) { int error; @@ -1286,13 +1323,15 @@ camperiphscsistatuserror(union ccb *ccb, cam_flags camflags, break; case SCSI_STATUS_CMD_TERMINATED: case SCSI_STATUS_CHECK_COND: + if (bootverbose) + xpt_print(ccb->ccb_h.path, "SCSI status error\n"); error = camperiphscsisenseerror(ccb, camflags, sense_flags, - save_ccb, openings, relsim_flags, - timeout); + timeout, + action_string); break; case SCSI_STATUS_QUEUE_FULL: { @@ -1347,7 +1386,7 @@ camperiphscsistatuserror(union ccb *ccb, cam_flags camflags, *timeout = 0; error = ERESTART; if (bootverbose) { - xpt_print(ccb->ccb_h.path, "Queue Full\n"); + xpt_print(ccb->ccb_h.path, "Queue full\n"); } break; } @@ -1359,7 +1398,7 @@ camperiphscsistatuserror(union ccb *ccb, cam_flags camflags, * command completes or a 1 second timeout. */ if (bootverbose) { - xpt_print(ccb->ccb_h.path, "Device Busy\n"); + xpt_print(ccb->ccb_h.path, "Device busy\n"); } if (ccb->ccb_h.retry_count > 0) { ccb->ccb_h.retry_count--; @@ -1372,11 +1411,11 @@ camperiphscsistatuserror(union ccb *ccb, cam_flags camflags, } break; case SCSI_STATUS_RESERV_CONFLICT: - xpt_print(ccb->ccb_h.path, "Reservation Conflict\n"); + xpt_print(ccb->ccb_h.path, "Reservation conflict\n"); error = EIO; break; default: - xpt_print(ccb->ccb_h.path, "SCSI Status 0x%x\n", + xpt_print(ccb->ccb_h.path, "SCSI status 0x%x\n", ccb->csio.scsi_status); error = EIO; break; @@ -1386,16 +1425,17 @@ camperiphscsistatuserror(union ccb *ccb, cam_flags camflags, static int camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, - u_int32_t sense_flags, union ccb *save_ccb, + u_int32_t sense_flags, int *openings, u_int32_t *relsim_flags, - u_int32_t *timeout) + u_int32_t *timeout, const char **action_string) { struct cam_periph *periph; + union ccb *orig_ccb = ccb; int error; periph = xpt_path_periph(ccb->ccb_h.path); - if (periph->flags & CAM_PERIPH_RECOVERY_INPROG) { - + if (periph->flags & + (CAM_PERIPH_RECOVERY_INPROG | CAM_PERIPH_SENSE_INPROG)) { /* * If error recovery is already in progress, don't attempt * to process this error, but requeue it unconditionally @@ -1413,17 +1453,6 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, } else { scsi_sense_action err_action; struct ccb_getdev cgd; - const char *action_string; - union ccb* print_ccb; - - /* A description of the error recovery action performed */ - action_string = NULL; - - /* - * The location of the orignal ccb - * for sense printing purposes. - */ - print_ccb = ccb; /* * Grab the inquiry data for this device. @@ -1451,7 +1480,7 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, if (ccb->ccb_h.retry_count > 0) ccb->ccb_h.retry_count--; else { - action_string = "Retries Exhausted"; + *action_string = "Retries exhausted"; goto sense_error_done; } } @@ -1461,8 +1490,9 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, * Do common portions of commands that * use recovery CCBs. */ - if (save_ccb == NULL) { - action_string = "No recovery CCB supplied"; + orig_ccb = xpt_alloc_ccb_nowait(); + if (orig_ccb == NULL) { + *action_string = "Can't allocate recovery CCB"; goto sense_error_done; } /* @@ -1470,22 +1500,20 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, * this freeze will be dropped as part of ERESTART. */ ccb->ccb_h.status &= ~CAM_DEV_QFRZN; - bcopy(ccb, save_ccb, sizeof(*save_ccb)); - print_ccb = save_ccb; - periph->flags |= CAM_PERIPH_RECOVERY_INPROG; + bcopy(ccb, orig_ccb, sizeof(*orig_ccb)); } switch (err_action & SS_MASK) { case SS_NOP: - action_string = "No Recovery Action Needed"; + *action_string = "No recovery action needed"; error = 0; break; case SS_RETRY: - action_string = "Retrying Command (per Sense Data)"; + *action_string = "Retrying command (per sense data)"; error = ERESTART; break; case SS_FAIL: - action_string = "Unretryable error"; + *action_string = "Unretryable error"; break; case SS_START: { @@ -1495,7 +1523,8 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, * Send a start unit command to the device, and * then retry the command. */ - action_string = "Attempting to Start Unit"; + *action_string = "Attempting to start unit"; + periph->flags |= CAM_PERIPH_RECOVERY_INPROG; /* * Check for removable media and set @@ -1530,12 +1559,13 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, int retries; if ((err_action & SSQ_MANY) != 0) { - action_string = "Polling device for readiness"; + *action_string = "Polling device for readiness"; retries = 120; } else { - action_string = "Testing device for readiness"; + *action_string = "Testing device for readiness"; retries = 1; } + periph->flags |= CAM_PERIPH_RECOVERY_INPROG; scsi_test_unit_ready(&ccb->csio, retries, camperiphdone, @@ -1553,15 +1583,17 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, } case SS_REQSENSE: { + *action_string = "Requesting SCSI sense data"; + periph->flags |= CAM_PERIPH_SENSE_INPROG; /* * Send a Request Sense to the device. We * assume that we are in a contingent allegiance * condition so we do not tag this request. */ scsi_request_sense(&ccb->csio, /*retries*/1, - camperiphdone, - &save_ccb->csio.sense_data, - sizeof(save_ccb->csio.sense_data), + camperiphsensedone, + &orig_ccb->csio.sense_data, + sizeof(orig_ccb->csio.sense_data), CAM_TAG_ACTION_NONE, /*sense_len*/SSD_FULL_SIZE, /*timeout*/5000); @@ -1580,21 +1612,17 @@ camperiphscsisenseerror(union ccb *ccb, cam_flags camflags, * the proper order before we release normal * transactions to the device. */ - ccb->ccb_h.pinfo.priority = CAM_PRIORITY_DEV; + ccb->ccb_h.pinfo.priority--; ccb->ccb_h.flags |= CAM_DEV_QFREEZE; - ccb->ccb_h.saved_ccb_ptr = save_ccb; + ccb->ccb_h.saved_ccb_ptr = orig_ccb; + ccb->ccb_h.recovery_depth = 0; error = ERESTART; } sense_error_done: if ((err_action & SSQ_PRINT_SENSE) != 0 - && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0) { - cam_error_print(print_ccb, CAM_ESF_ALL, CAM_EPF_ALL); - xpt_print_path(ccb->ccb_h.path); - if (bootverbose) - scsi_sense_print(&print_ccb->csio); - printf("%s\n", action_string); - } + && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0) + cam_error_print(orig_ccb, CAM_ESF_ALL, CAM_EPF_ALL); } return (error); } @@ -1630,19 +1658,18 @@ cam_periph_error(union ccb *ccb, cam_flags camflags, error = camperiphscsistatuserror(ccb, camflags, sense_flags, - save_ccb, &openings, &relsim_flags, - &timeout); + &timeout, + &action_string); break; case CAM_AUTOSENSE_FAIL: - xpt_print(ccb->ccb_h.path, "AutoSense Failed\n"); + xpt_print(ccb->ccb_h.path, "AutoSense failed\n"); error = EIO; /* we have to kill the command */ break; case CAM_ATA_STATUS_ERROR: if (bootverbose && printed == 0) { - xpt_print(ccb->ccb_h.path, - "Request completed with CAM_ATA_STATUS_ERROR\n"); + xpt_print(ccb->ccb_h.path, "ATA status error\n"); cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL); printed++; } @@ -1669,13 +1696,13 @@ cam_periph_error(union ccb *ccb, cam_flags camflags, case CAM_UNCOR_PARITY: if (bootverbose && printed == 0) { xpt_print(ccb->ccb_h.path, - "Uncorrected Parity Error\n"); + "Uncorrected parity error\n"); printed++; } /* FALLTHROUGH */ case CAM_DATA_RUN_ERR: if (bootverbose && printed == 0) { - xpt_print(ccb->ccb_h.path, "Data Overrun\n"); + xpt_print(ccb->ccb_h.path, "Data overrun\n"); printed++; } error = EIO; /* we have to kill the command */ @@ -1684,7 +1711,7 @@ cam_periph_error(union ccb *ccb, cam_flags camflags, ccb->ccb_h.retry_count--; error = ERESTART; } else { - action_string = "Retries Exhausted"; + action_string = "Retries exhausted"; error = EIO; } break; @@ -1705,7 +1732,7 @@ cam_periph_error(union ccb *ccb, cam_flags camflags, error = ERESTART; if (bootverbose && printed == 0) { xpt_print(ccb->ccb_h.path, - "Selection Timeout\n"); + "Selection timeout\n"); printed++; } @@ -1767,7 +1794,7 @@ cam_periph_error(union ccb *ccb, cam_flags camflags, /* Unconditional requeue */ error = ERESTART; if (bootverbose && printed == 0) { - xpt_print(ccb->ccb_h.path, "Request Requeued\n"); + xpt_print(ccb->ccb_h.path, "Request requeued\n"); printed++; } break; @@ -1788,13 +1815,13 @@ cam_periph_error(union ccb *ccb, cam_flags camflags, ccb->ccb_h.retry_count--; error = ERESTART; if (bootverbose && printed == 0) { - xpt_print(ccb->ccb_h.path, "CAM Status 0x%x\n", + xpt_print(ccb->ccb_h.path, "CAM status 0x%x\n", status); printed++; } } else { error = EIO; - action_string = "Retries Exhausted"; + action_string = "Retries exhausted"; } break; } @@ -1807,11 +1834,13 @@ cam_periph_error(union ccb *ccb, cam_flags camflags, !(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); + action_string = "Unretryable error"; + xpt_print(ccb->ccb_h.path, "Error %d, %s\n", + error, action_string); + } else if (action_string != NULL) xpt_print(ccb->ccb_h.path, "%s\n", action_string); - } else - xpt_print(ccb->ccb_h.path, "Retrying Command\n"); + else + xpt_print(ccb->ccb_h.path, "Retrying command\n"); } /* Attempt a retry */ diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h index e207b1925ab..33e9f758435 100644 --- a/sys/cam/cam_periph.h +++ b/sys/cam/cam_periph.h @@ -42,6 +42,7 @@ extern struct cam_periph *xpt_periph; extern struct periph_driver **periph_drivers; void periphdriver_register(void *); +void periphdriver_init(int level); #include #define PERIPHDRIVER_DECLARE(name, driver) \ @@ -117,6 +118,7 @@ struct cam_periph { #define CAM_PERIPH_INVALID 0x08 #define CAM_PERIPH_NEW_DEV_FOUND 0x10 #define CAM_PERIPH_RECOVERY_INPROG 0x20 +#define CAM_PERIPH_SENSE_INPROG 0x40 u_int32_t immediate_priority; u_int32_t refcount; SLIST_HEAD(, ccb_hdr) ccb_list; /* For "immediate" requests */ @@ -165,8 +167,10 @@ int cam_periph_ioctl(struct cam_periph *periph, u_long cmd, cam_flags camflags, u_int32_t sense_flags)); void cam_freeze_devq(struct cam_path *path); +void cam_freeze_devq_arg(struct cam_path *path, u_int32_t flags, + uint32_t arg); u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, - u_int32_t opening_reduction, u_int32_t timeout, + u_int32_t opening_reduction, u_int32_t arg, int getcount_only); void cam_periph_async(struct cam_periph *periph, u_int32_t code, struct cam_path *path, void *arg); diff --git a/sys/cam/cam_queue.h b/sys/cam/cam_queue.h index 31f9bc238bf..dd9f9a7306e 100644 --- a/sys/cam/cam_queue.h +++ b/sys/cam/cam_queue.h @@ -34,6 +34,7 @@ #ifdef _KERNEL #include +#include /* * This structure implements a heap based priority queue. The queue @@ -47,7 +48,7 @@ struct camq { int array_size; int entries; u_int32_t generation; - u_int32_t qfrozen_cnt; + u_int32_t qfrozen_cnt[CAM_RL_VALUES]; }; TAILQ_HEAD(ccb_hdr_tailq, ccb_hdr); @@ -140,6 +141,10 @@ cam_pinfo *camq_remove(struct camq *queue, int index); /* Index the first element in the heap */ #define CAMQ_GET_HEAD(camq) ((camq)->queue_array[CAMQ_HEAD]) +/* Get the first element priority. */ +#define CAMQ_GET_PRIO(camq) (((camq)->entries > 0) ? \ + ((camq)->queue_array[CAMQ_HEAD]->priority) : 0) + /* * camq_change_priority: Raise or lower the priority of an entry * maintaining queue order. @@ -153,10 +158,10 @@ cam_ccbq_pending_ccb_count(struct cam_ccbq *ccbq); static __inline void cam_ccbq_take_opening(struct cam_ccbq *ccbq); -static __inline void +static __inline int cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb); -static __inline void +static __inline int cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb); static __inline union ccb * @@ -185,17 +190,31 @@ cam_ccbq_take_opening(struct cam_ccbq *ccbq) ccbq->held++; } -static __inline void +static __inline int cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb) { ccbq->held--; camq_insert(&ccbq->queue, &new_ccb->ccb_h.pinfo); + if (ccbq->queue.qfrozen_cnt[CAM_PRIORITY_TO_RL( + new_ccb->ccb_h.pinfo.priority)] > 0) { + ccbq->devq_openings++; + ccbq->held++; + return (1); + } else + return (0); } -static __inline void +static __inline int cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb) { camq_remove(&ccbq->queue, ccb->ccb_h.pinfo.index); + if (ccbq->queue.qfrozen_cnt[CAM_PRIORITY_TO_RL( + ccb->ccb_h.pinfo.priority)] > 0) { + ccbq->devq_openings--; + ccbq->held--; + return (1); + } else + return (0); } static __inline union ccb * @@ -229,5 +248,81 @@ cam_ccbq_release_opening(struct cam_ccbq *ccbq) ccbq->devq_openings++; } +static __inline int +cam_ccbq_freeze(struct cam_ccbq *ccbq, cam_rl rl, u_int32_t cnt) +{ + int i, frozen = 0; + cam_rl p, n; + + /* Find pevious run level. */ + for (p = 0; p < CAM_RL_VALUES && ccbq->queue.qfrozen_cnt[p] == 0; p++); + /* Find new run level. */ + n = min(rl, p); + /* Apply new run level. */ + for (i = rl; i < CAM_RL_VALUES; i++) + ccbq->queue.qfrozen_cnt[i] += cnt; + /* Update ccbq statistics. */ + if (n == p) + return (0); + for (i = CAMQ_HEAD; i <= ccbq->queue.entries; i++) { + cam_rl rrl = + CAM_PRIORITY_TO_RL(ccbq->queue.queue_array[i]->priority); + if (rrl < n) + continue; + if (rrl >= p) + break; + ccbq->devq_openings++; + ccbq->held++; + frozen++; + } + return (frozen); +} + +static __inline int +cam_ccbq_release(struct cam_ccbq *ccbq, cam_rl rl, u_int32_t cnt) +{ + int i, released = 0; + cam_rl p, n; + + /* Apply new run level. */ + for (i = rl; i < CAM_RL_VALUES; i++) + ccbq->queue.qfrozen_cnt[i] -= cnt; + /* Find new run level. */ + for (n = 0; n < CAM_RL_VALUES && ccbq->queue.qfrozen_cnt[n] == 0; n++); + /* Find previous run level. */ + p = min(rl, n); + /* Update ccbq statistics. */ + if (n == p) + return (0); + for (i = CAMQ_HEAD; i <= ccbq->queue.entries; i++) { + cam_rl rrl = + CAM_PRIORITY_TO_RL(ccbq->queue.queue_array[i]->priority); + if (rrl < p) + continue; + if (rrl >= n) + break; + ccbq->devq_openings--; + ccbq->held--; + released++; + } + return (released); +} + +static __inline u_int32_t +cam_ccbq_frozen(struct cam_ccbq *ccbq, cam_rl rl) +{ + + return (ccbq->queue.qfrozen_cnt[rl]); +} + +static __inline u_int32_t +cam_ccbq_frozen_top(struct cam_ccbq *ccbq) +{ + cam_rl rl; + + rl = CAM_PRIORITY_TO_RL(CAMQ_GET_PRIO(&ccbq->queue)); + return (ccbq->queue.qfrozen_cnt[rl]); +} + #endif /* _KERNEL */ #endif /* _CAM_CAM_QUEUE_H */ diff --git a/sys/cam/cam_sim.c b/sys/cam/cam_sim.c index adccfa8593e..59148a9a426 100644 --- a/sys/cam/cam_sim.c +++ b/sys/cam/cam_sim.c @@ -69,7 +69,7 @@ cam_sim_alloc(sim_action_func sim_action, sim_poll_func sim_poll, return (NULL); sim = (struct cam_sim *)malloc(sizeof(struct cam_sim), - M_CAMSIM, M_NOWAIT); + M_CAMSIM, M_ZERO | M_NOWAIT); if (sim == NULL) return (NULL); @@ -86,6 +86,7 @@ cam_sim_alloc(sim_action_func sim_action, sim_poll_func sim_poll, sim->flags = 0; sim->refcount = 1; sim->devq = queue; + sim->max_ccbs = 8; /* Reserve for management purposes. */ sim->mtx = mtx; if (mtx == &Giant) { sim->flags |= 0; diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 88ee3091675..d966a9fb5bd 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -102,6 +102,8 @@ struct xpt_softc { /* queue for handling async rescan requests. */ TAILQ_HEAD(, ccb_hdr) ccb_scanq; + int buses_to_config; + int buses_config_done; /* Registered busses */ TAILQ_HEAD(,cam_eb) xpt_busses; @@ -109,6 +111,9 @@ struct xpt_softc { struct intr_config_hook *xpt_config_hook; + int boot_delay; + struct callout boot_callout; + struct mtx xpt_topo_lock; struct mtx xpt_lock; }; @@ -145,6 +150,10 @@ typedef int xpt_pdrvfunc_t (struct periph_driver **pdrv, void *arg); /* Transport layer configuration information */ static struct xpt_softc xsoftc; +TUNABLE_INT("kern.cam.boot_delay", &xsoftc.boot_delay); +SYSCTL_INT(_kern_cam, OID_AUTO, boot_delay, CTLFLAG_RDTUN, + &xsoftc.boot_delay, 0, "Bus registration wait time"); + /* Queues for our software interrupt handler */ typedef TAILQ_HEAD(cam_isrq, ccb_hdr) cam_isrq_t; typedef TAILQ_HEAD(cam_simq, cam_sim) cam_simq_t; @@ -210,11 +219,12 @@ static path_id_t xptnextfreepathid(void); static path_id_t xptpathid(const char *sim_name, int sim_unit, int sim_bus); static union ccb *xpt_get_ccb(struct cam_ed *device); static void xpt_run_dev_allocq(struct cam_eb *bus); +static void xpt_run_dev_sendq(struct cam_eb *bus); static timeout_t xpt_release_devq_timeout; static void xpt_release_simq_timeout(void *arg) __unused; static void xpt_release_bus(struct cam_eb *bus); -static void xpt_release_devq_device(struct cam_ed *dev, u_int count, - int run_queue); +static void xpt_release_devq_device(struct cam_ed *dev, cam_rl rl, + 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_et *target); @@ -224,11 +234,8 @@ static struct cam_et* xpt_find_target(struct cam_eb *bus, target_id_t target_id); static struct cam_ed* xpt_find_device(struct cam_et *target, lun_id_t lun_id); -static xpt_busfunc_t xptconfigbuscountfunc; -static xpt_busfunc_t xptconfigfunc; static void xpt_config(void *arg); static xpt_devicefunc_t xptpassannouncefunc; -static void xpt_finishconfig(struct cam_periph *periph, union ccb *ccb); static void xptaction(struct cam_sim *sim, union ccb *work_ccb); static void xptpoll(struct cam_sim *sim); static void camisr(void *); @@ -270,6 +277,7 @@ static xpt_busfunc_t xptdefbusfunc; static xpt_targetfunc_t xptdeftargetfunc; static xpt_devicefunc_t xptdefdevicefunc; static xpt_periphfunc_t xptdefperiphfunc; +static void xpt_finishconfig_task(void *context, int pending); static int xpt_for_all_busses(xpt_busfunc_t *tr_func, void *arg); static int xpt_for_all_devices(xpt_devicefunc_t *tr_func, void *arg); @@ -285,19 +293,19 @@ static xpt_devicefunc_t xptsetasyncfunc; static xpt_busfunc_t xptsetasyncbusfunc; static cam_status xptregister(struct cam_periph *periph, void *arg); -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); static __inline int device_is_alloc_queued(struct cam_ed *device); static __inline int device_is_send_queued(struct cam_ed *device); -static __inline int dev_allocq_is_runnable(struct cam_devq *devq); static __inline int xpt_schedule_dev_allocq(struct cam_eb *bus, struct cam_ed *dev) { int retval; - if (dev->ccbq.devq_openings > 0) { + if ((dev->drvq.entries > 0) && + (dev->ccbq.devq_openings > 0) && + (cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL( + CAMQ_GET_PRIO(&dev->drvq))) == 0)) { /* * The priority of a device waiting for CCB resources * is that of the the highest priority peripheral driver @@ -305,7 +313,7 @@ xpt_schedule_dev_allocq(struct cam_eb *bus, struct cam_ed *dev) */ retval = xpt_schedule_dev(&bus->sim->devq->alloc_queue, &dev->alloc_ccb_entry.pinfo, - CAMQ_GET_HEAD(&dev->drvq)->priority); + CAMQ_GET_PRIO(&dev->drvq)); } else { retval = 0; } @@ -318,7 +326,9 @@ xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev) { int retval; - if (dev->ccbq.dev_openings > 0) { + if ((dev->ccbq.queue.entries > 0) && + (dev->ccbq.dev_openings > 0) && + (cam_ccbq_frozen_top(&dev->ccbq) == 0)) { /* * The priority of a device waiting for controller * resources is that of the the highest priority CCB @@ -327,7 +337,7 @@ xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev) retval = xpt_schedule_dev(&bus->sim->devq->send_queue, &dev->send_ccb_entry.pinfo, - CAMQ_GET_HEAD(&dev->ccbq.queue)->priority); + CAMQ_GET_PRIO(&dev->ccbq.queue)); } else { retval = 0; } @@ -352,19 +362,6 @@ device_is_send_queued(struct cam_ed *device) return (device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX); } -static __inline int -dev_allocq_is_runnable(struct cam_devq *devq) -{ - /* - * Have work to do. - * Have space to do more work. - * Allowed to do work. - */ - return ((devq->alloc_queue.qfrozen_cnt == 0) - && (devq->alloc_queue.entries > 0) - && (devq->alloc_openings > 0)); -} - static void xpt_periph_init() { @@ -818,45 +815,42 @@ cam_module_event_handler(module_t mod, int what, void *arg) return 0; } +static void +xpt_rescan_done(struct cam_periph *periph, union ccb *done_ccb) +{ + + if (done_ccb->ccb_h.ppriv_ptr1 == NULL) { + xpt_free_path(done_ccb->ccb_h.path); + xpt_free_ccb(done_ccb); + } else { + done_ccb->ccb_h.cbfcnp = done_ccb->ccb_h.ppriv_ptr1; + (*done_ccb->ccb_h.cbfcnp)(periph, done_ccb); + } + xpt_release_boot(); +} + /* thread to handle bus rescans */ static void xpt_scanner_thread(void *dummy) { - cam_isrq_t queue; union ccb *ccb; struct cam_sim *sim; + xpt_lock_buses(); for (;;) { - /* - * Wait for a rescan request to come in. When it does, splice - * it onto a queue from local storage so that the xpt lock - * doesn't need to be held while the requests are being - * processed. - */ - xpt_lock_buses(); if (TAILQ_EMPTY(&xsoftc.ccb_scanq)) msleep(&xsoftc.ccb_scanq, &xsoftc.xpt_topo_lock, PRIBIO, "ccb_scanq", 0); - TAILQ_INIT(&queue); - TAILQ_CONCAT(&queue, &xsoftc.ccb_scanq, sim_links.tqe); - xpt_unlock_buses(); - - while ((ccb = (union ccb *)TAILQ_FIRST(&queue)) != NULL) { - TAILQ_REMOVE(&queue, &ccb->ccb_h, sim_links.tqe); + if ((ccb = (union ccb *)TAILQ_FIRST(&xsoftc.ccb_scanq)) != NULL) { + TAILQ_REMOVE(&xsoftc.ccb_scanq, &ccb->ccb_h, sim_links.tqe); + xpt_unlock_buses(); sim = ccb->ccb_h.path->bus->sim; CAM_SIM_LOCK(sim); - - if( ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD ) - ccb->ccb_h.func_code = XPT_SCAN_BUS; - 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_NORMAL); - cam_periph_runccb(ccb, NULL, 0, 0, NULL); - xpt_free_path(ccb->ccb_h.path); - xpt_free_ccb(ccb); + xpt_action(ccb); CAM_SIM_UNLOCK(sim); + + xpt_lock_buses(); } } } @@ -866,21 +860,30 @@ xpt_rescan(union ccb *ccb) { struct ccb_hdr *hdr; - /* - * Don't make duplicate entries for the same paths. - */ + /* Prepare request */ + if(ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD) + ccb->ccb_h.func_code = XPT_SCAN_BUS; + else + ccb->ccb_h.func_code = XPT_SCAN_LUN; + ccb->ccb_h.ppriv_ptr1 = ccb->ccb_h.cbfcnp; + ccb->ccb_h.cbfcnp = xpt_rescan_done; + xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, CAM_PRIORITY_XPT); + /* Don't make duplicate entries for the same paths. */ xpt_lock_buses(); - TAILQ_FOREACH(hdr, &xsoftc.ccb_scanq, sim_links.tqe) { - if (xpt_path_comp(hdr->path, ccb->ccb_h.path) == 0) { - wakeup(&xsoftc.ccb_scanq); - xpt_unlock_buses(); - xpt_print(ccb->ccb_h.path, "rescan already queued\n"); - xpt_free_path(ccb->ccb_h.path); - xpt_free_ccb(ccb); - return; + if (ccb->ccb_h.ppriv_ptr1 == NULL) { + TAILQ_FOREACH(hdr, &xsoftc.ccb_scanq, sim_links.tqe) { + if (xpt_path_comp(hdr->path, ccb->ccb_h.path) == 0) { + wakeup(&xsoftc.ccb_scanq); + xpt_unlock_buses(); + xpt_print(ccb->ccb_h.path, "rescan already queued\n"); + xpt_free_path(ccb->ccb_h.path); + xpt_free_ccb(ccb); + return; + } } } TAILQ_INSERT_TAIL(&xsoftc.ccb_scanq, &ccb->ccb_h, sim_links.tqe); + xsoftc.buses_to_config++; wakeup(&xsoftc.ccb_scanq); xpt_unlock_buses(); } @@ -923,10 +926,9 @@ xpt_init(void *dummy) if (xpt_sim == NULL) return (ENOMEM); - xpt_sim->max_ccbs = 16; - mtx_lock(&xsoftc.xpt_lock); if ((status = xpt_bus_register(xpt_sim, NULL, 0)) != CAM_SUCCESS) { + mtx_unlock(&xsoftc.xpt_lock); printf("xpt_init: xpt_bus_register failed with status %#x," " failing attach\n", status); return (EINVAL); @@ -940,6 +942,7 @@ xpt_init(void *dummy) if ((status = xpt_create_path(&path, NULL, CAM_XPT_PATH_ID, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)) != CAM_REQ_CMP) { + mtx_unlock(&xsoftc.xpt_lock); printf("xpt_init: xpt_create_path failed with status %#x," " failing attach\n", status); return (EINVAL); @@ -949,7 +952,8 @@ xpt_init(void *dummy) path, NULL, 0, xpt_sim); xpt_free_path(path); mtx_unlock(&xsoftc.xpt_lock); - + /* Install our software interrupt handlers */ + swi_add(NULL, "cambio", camisr, NULL, SWI_CAMBIO, INTR_MPSAFE, &cambio_ih); /* * Register a callback for when interrupts are enabled. */ @@ -961,7 +965,6 @@ xpt_init(void *dummy) "- failing attach\n"); return (ENOMEM); } - xsoftc.xpt_config_hook->ich_func = xpt_config; if (config_intrhook_establish(xsoftc.xpt_config_hook) != 0) { free (xsoftc.xpt_config_hook, M_CAMXPT); @@ -969,13 +972,6 @@ xpt_init(void *dummy) "- failing attach\n"); } - /* fire up rescan thread */ - if (kproc_create(xpt_scanner_thread, NULL, NULL, 0, 0, "xpt_thrd")) { - printf("xpt_init: failed to create rescan thread\n"); - } - /* Install our software interrupt handlers */ - swi_add(NULL, "cambio", camisr, NULL, SWI_CAMBIO, INTR_MPSAFE, &cambio_ih); - return (0); } @@ -2481,6 +2477,9 @@ xpt_action(union ccb *start_ccb) CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_action\n")); start_ccb->ccb_h.status = CAM_REQ_INPROG; + /* Compatibility for RL-unaware code. */ + if (CAM_PRIORITY_TO_RL(start_ccb->ccb_h.pinfo.priority) == 0) + start_ccb->ccb_h.pinfo.priority += CAM_PRIORITY_NORMAL - 1; (*(start_ccb->ccb_h.path->bus->xport->action))(start_ccb); } @@ -2546,17 +2545,14 @@ xpt_action_default(union ccb *start_ccb) case XPT_RESET_DEV: case XPT_ENG_EXEC: { - struct cam_path *path; - int runq; + struct cam_path *path = start_ccb->ccb_h.path; + int frozen; - path = start_ccb->ccb_h.path; - - cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb); - if (path->device->ccbq.queue.qfrozen_cnt == 0) - runq = xpt_schedule_dev_sendq(path->bus, path->device); - else - runq = 0; - if (runq != 0) + frozen = cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb); + path->device->sim->devq->alloc_openings += frozen; + if (frozen > 0) + xpt_run_dev_allocq(path->bus); + if (xpt_schedule_dev_sendq(path->bus, path->device)) xpt_run_dev_sendq(path->bus); break; } @@ -2601,9 +2597,12 @@ xpt_action_default(union ccb *start_ccb) if (abort_ccb->ccb_h.pinfo.index >= 0) { struct cam_ccbq *ccbq; + struct cam_ed *device; - ccbq = &abort_ccb->ccb_h.path->device->ccbq; - cam_ccbq_remove_ccb(ccbq, abort_ccb); + device = abort_ccb->ccb_h.path->device; + ccbq = &device->ccbq; + device->sim->devq->alloc_openings -= + cam_ccbq_remove_ccb(ccbq, abort_ccb); abort_ccb->ccb_h.status = CAM_REQ_ABORTED|CAM_DEV_QFRZN; xpt_freeze_devq(abort_ccb->ccb_h.path, 1); @@ -3008,11 +3007,12 @@ xpt_action_default(union ccb *start_ccb) } if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) == 0) { - - xpt_release_devq(crs->ccb_h.path, /*count*/1, - /*run_queue*/TRUE); + xpt_release_devq_rl(crs->ccb_h.path, /*runlevel*/ + (crs->release_flags & RELSIM_RELEASE_RUNLEVEL) ? + crs->release_timeout : 0, + /*count*/1, /*run_queue*/TRUE); } - start_ccb->crs.qfrozen_cnt = dev->ccbq.queue.qfrozen_cnt; + start_ccb->crs.qfrozen_cnt = dev->ccbq.queue.qfrozen_cnt[0]; start_ccb->ccb_h.status = CAM_REQ_CMP; break; } @@ -3049,6 +3049,16 @@ xpt_action_default(union ccb *start_ccb) #endif /* CAMDEBUG */ break; } + case XPT_FREEZE_QUEUE: + { + struct ccb_relsim *crs = &start_ccb->crs; + + xpt_freeze_devq_rl(crs->ccb_h.path, /*runlevel*/ + (crs->release_flags & RELSIM_RELEASE_RUNLEVEL) ? + crs->release_timeout : 0, /*count*/1); + start_ccb->ccb_h.status = CAM_REQ_CMP; + break; + } case XPT_NOOP: if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0) xpt_freeze_devq(start_ccb->ccb_h.path, 1); @@ -3129,7 +3139,7 @@ void xpt_schedule(struct cam_periph *perph, u_int32_t new_priority) { struct cam_ed *device; - int runq; + int runq = 0; mtx_assert(perph->sim->mtx, MA_OWNED); @@ -3143,8 +3153,8 @@ xpt_schedule(struct cam_periph *perph, u_int32_t new_priority) camq_change_priority(&device->drvq, perph->pinfo.index, new_priority); + runq = xpt_schedule_dev_allocq(perph->path->bus, device); } - runq = 0; } else { /* New entry on the queue */ CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE, @@ -3192,8 +3202,9 @@ xpt_schedule_dev(struct camq *queue, cam_pinfo *pinfo, CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("changed priority to %d\n", new_priority)); - } - retval = 0; + retval = 1; + } else + retval = 0; } else { /* New entry on the queue */ if (new_priority < old_priority) @@ -3219,15 +3230,15 @@ xpt_run_dev_allocq(struct cam_eb *bus) CAM_DEBUG_PRINT(CAM_DEBUG_XPT, (" qfrozen_cnt == 0x%x, entries == %d, " "openings == %d, active == %d\n", - devq->alloc_queue.qfrozen_cnt, + devq->alloc_queue.qfrozen_cnt[0], devq->alloc_queue.entries, devq->alloc_openings, devq->alloc_active)); - devq->alloc_queue.qfrozen_cnt++; + devq->alloc_queue.qfrozen_cnt[0]++; while ((devq->alloc_queue.entries > 0) && (devq->alloc_openings > 0) - && (devq->alloc_queue.qfrozen_cnt <= 1)) { + && (devq->alloc_queue.qfrozen_cnt[0] <= 1)) { struct cam_ed_qinfo *qinfo; struct cam_ed *device; union ccb *work_ccb; @@ -3237,7 +3248,6 @@ xpt_run_dev_allocq(struct cam_eb *bus) qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->alloc_queue, CAMQ_HEAD); device = qinfo->device; - CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("running device %p\n", device)); @@ -3271,15 +3281,13 @@ xpt_run_dev_allocq(struct cam_eb *bus) break; } - if (drvq->entries > 0) { - /* We have more work. Attempt to reschedule */ - xpt_schedule_dev_allocq(bus, device); - } + /* We may have more work. Attempt to reschedule. */ + xpt_schedule_dev_allocq(bus, device); } - devq->alloc_queue.qfrozen_cnt--; + devq->alloc_queue.qfrozen_cnt[0]--; } -void +static void xpt_run_dev_sendq(struct cam_eb *bus) { struct cam_devq *devq; @@ -3288,10 +3296,10 @@ xpt_run_dev_sendq(struct cam_eb *bus) devq = bus->sim->devq; - devq->send_queue.qfrozen_cnt++; + devq->send_queue.qfrozen_cnt[0]++; while ((devq->send_queue.entries > 0) && (devq->send_openings > 0) - && (devq->send_queue.qfrozen_cnt <= 1)) { + && (devq->send_queue.qfrozen_cnt[0] <= 1)) { struct cam_ed_qinfo *qinfo; struct cam_ed *device; union ccb *work_ccb; @@ -3300,15 +3308,6 @@ xpt_run_dev_sendq(struct cam_eb *bus) qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->send_queue, CAMQ_HEAD); device = qinfo->device; - - /* - * If the device has been "frozen", don't attempt - * to run it. - */ - if (device->ccbq.queue.qfrozen_cnt > 0) { - continue; - } - CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("running device %p\n", device)); @@ -3328,7 +3327,7 @@ xpt_run_dev_sendq(struct cam_eb *bus) * the device queue until we have a slot * available. */ - device->ccbq.queue.qfrozen_cnt++; + xpt_freeze_devq(work_ccb->ccb_h.path, 1); STAILQ_INSERT_TAIL(&xsoftc.highpowerq, &work_ccb->ccb_h, xpt_links.stqe); @@ -3350,15 +3349,14 @@ xpt_run_dev_sendq(struct cam_eb *bus) devq->send_openings--; devq->send_active++; - if (device->ccbq.queue.entries > 0) - xpt_schedule_dev_sendq(bus, device); + xpt_schedule_dev_sendq(bus, device); if (work_ccb && (work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0){ /* * The client wants to freeze the queue * after this CCB is sent. */ - device->ccbq.queue.qfrozen_cnt++; + xpt_freeze_devq(work_ccb->ccb_h.path, 1); } /* In Target mode, the peripheral driver knows best... */ @@ -3383,7 +3381,7 @@ xpt_run_dev_sendq(struct cam_eb *bus) sim = work_ccb->ccb_h.path->bus->sim; (*(sim->sim_action))(sim, work_ccb); } - devq->send_queue.qfrozen_cnt--; + devq->send_queue.qfrozen_cnt[0]--; } /* @@ -3789,13 +3787,9 @@ xpt_release_ccb(union ccb *free_ccb) } sim->devq->alloc_openings++; sim->devq->alloc_active--; - /* XXX Turn this into an inline function - xpt_run_device?? */ - if ((device_is_alloc_queued(device) == 0) - && (device->drvq.entries > 0)) { + if (device_is_alloc_queued(device) == 0) xpt_schedule_dev_allocq(bus, device); - } - if (dev_allocq_is_runnable(sim->devq)) - xpt_run_dev_allocq(bus); + xpt_run_dev_allocq(bus); } /* Functions accessed by SIM drivers */ @@ -3821,7 +3815,7 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus) struct cam_eb *new_bus; struct cam_eb *old_bus; struct ccb_pathinq cpi; - struct cam_path path; + struct cam_path *path; cam_status status; mtx_assert(sim->mtx, MA_OWNED); @@ -3833,6 +3827,11 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus) /* Couldn't satisfy request */ return (CAM_RESRC_UNAVAIL); } + path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, M_NOWAIT); + if (path == NULL) { + free(new_bus, M_CAMXPT); + return (CAM_RESRC_UNAVAIL); + } if (strcmp(sim->sim_name, "xpt") != 0) { sim->path_id = @@ -3867,13 +3866,12 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus) */ new_bus->xport = &xport_default; - bzero(&path, sizeof(path)); - status = xpt_compile_path(&path, /*periph*/NULL, sim->path_id, + status = xpt_compile_path(path, /*periph*/NULL, sim->path_id, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); if (status != CAM_REQ_CMP) printf("xpt_compile_path returned %d\n", status); - xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); @@ -3899,9 +3897,17 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus) /* Notify interested parties */ if (sim->path_id != CAM_XPT_PATH_ID) { - xpt_async(AC_PATH_REGISTERED, &path, &cpi); - } - xpt_release_path(&path); + union ccb *scan_ccb; + + xpt_async(AC_PATH_REGISTERED, path, &cpi); + /* Initiate bus rescan. */ + scan_ccb = xpt_alloc_ccb_nowait(); + scan_ccb->ccb_h.path = path; + scan_ccb->ccb_h.func_code = XPT_SCAN_BUS; + scan_ccb->crcn.flags = 0; + xpt_rescan(scan_ccb); + } else + xpt_free_path(path); return (CAM_SUCCESS); } @@ -4109,13 +4115,35 @@ xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus, printf("xpt_dev_async called\n"); } +u_int32_t +xpt_freeze_devq_rl(struct cam_path *path, cam_rl rl, u_int count) +{ + struct cam_ed *dev = path->device; + + mtx_assert(path->bus->sim->mtx, MA_OWNED); + dev->sim->devq->alloc_openings += + cam_ccbq_freeze(&dev->ccbq, rl, count); + /* Remove frozen device from allocq. */ + if (device_is_alloc_queued(dev) && + cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL( + CAMQ_GET_PRIO(&dev->drvq)))) { + camq_remove(&dev->sim->devq->alloc_queue, + dev->alloc_ccb_entry.pinfo.index); + } + /* Remove frozen device from sendq. */ + if (device_is_send_queued(dev) && + cam_ccbq_frozen_top(&dev->ccbq)) { + camq_remove(&dev->sim->devq->send_queue, + dev->send_ccb_entry.pinfo.index); + } + return (dev->ccbq.queue.qfrozen_cnt[rl]); +} + u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count) { - mtx_assert(path->bus->sim->mtx, MA_OWNED); - path->device->ccbq.queue.qfrozen_cnt += count; - return (path->device->ccbq.queue.qfrozen_cnt); + return (xpt_freeze_devq_rl(path, 0, count)); } u_int32_t @@ -4123,8 +4151,8 @@ xpt_freeze_simq(struct cam_sim *sim, u_int count) { mtx_assert(sim->mtx, MA_OWNED); - sim->devq->send_queue.qfrozen_cnt += count; - return (sim->devq->send_queue.qfrozen_cnt); + sim->devq->send_queue.qfrozen_cnt[0] += count; + return (sim->devq->send_queue.qfrozen_cnt[0]); } static void @@ -4134,7 +4162,7 @@ xpt_release_devq_timeout(void *arg) device = (struct cam_ed *)arg; - xpt_release_devq_device(device, /*count*/1, /*run_queue*/TRUE); + xpt_release_devq_device(device, /*rl*/0, /*count*/1, /*run_queue*/TRUE); } void @@ -4142,51 +4170,59 @@ xpt_release_devq(struct cam_path *path, u_int count, int run_queue) { mtx_assert(path->bus->sim->mtx, MA_OWNED); - xpt_release_devq_device(path->device, count, run_queue); + xpt_release_devq_device(path->device, /*rl*/0, count, run_queue); +} + +void +xpt_release_devq_rl(struct cam_path *path, cam_rl rl, u_int count, int run_queue) +{ + mtx_assert(path->bus->sim->mtx, MA_OWNED); + + xpt_release_devq_device(path->device, rl, count, run_queue); } static void -xpt_release_devq_device(struct cam_ed *dev, u_int count, int run_queue) +xpt_release_devq_device(struct cam_ed *dev, cam_rl rl, u_int count, int run_queue) { - int rundevq; - rundevq = 0; - if (dev->ccbq.queue.qfrozen_cnt > 0) { - - count = (count > dev->ccbq.queue.qfrozen_cnt) ? - dev->ccbq.queue.qfrozen_cnt : count; - dev->ccbq.queue.qfrozen_cnt -= count; - if (dev->ccbq.queue.qfrozen_cnt == 0) { - - /* - * No longer need to wait for a successful - * command completion. - */ - dev->flags &= ~CAM_DEV_REL_ON_COMPLETE; - - /* - * Remove any timeouts that might be scheduled - * to release this queue. - */ - if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) { - callout_stop(&dev->callout); - dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING; - } - - /* - * Now that we are unfrozen schedule the - * device so any pending transactions are - * run. - */ - if ((dev->ccbq.queue.entries > 0) - && (xpt_schedule_dev_sendq(dev->target->bus, dev)) - && (run_queue != 0)) { - rundevq = 1; - } - } + if (count > dev->ccbq.queue.qfrozen_cnt[rl]) { +#ifdef INVARIANTS + printf("xpt_release_devq(%d): requested %u > present %u\n", + rl, count, dev->ccbq.queue.qfrozen_cnt[rl]); +#endif + count = dev->ccbq.queue.qfrozen_cnt[rl]; + } + dev->sim->devq->alloc_openings -= + cam_ccbq_release(&dev->ccbq, rl, count); + if (cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL( + CAMQ_GET_PRIO(&dev->drvq))) == 0) { + if (xpt_schedule_dev_allocq(dev->target->bus, dev)) + xpt_run_dev_allocq(dev->target->bus); + } + if (cam_ccbq_frozen_top(&dev->ccbq) == 0) { + /* + * No longer need to wait for a successful + * command completion. + */ + dev->flags &= ~CAM_DEV_REL_ON_COMPLETE; + /* + * Remove any timeouts that might be scheduled + * to release this queue. + */ + if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) { + callout_stop(&dev->callout); + dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING; + } + if (run_queue == 0) + return; + /* + * Now that we are unfrozen schedule the + * device so any pending transactions are + * run. + */ + if (xpt_schedule_dev_sendq(dev->target->bus, dev)) + xpt_run_dev_sendq(dev->target->bus); } - if (rundevq != 0) - xpt_run_dev_sendq(dev->target->bus); } void @@ -4195,32 +4231,33 @@ xpt_release_simq(struct cam_sim *sim, int run_queue) struct camq *sendq; mtx_assert(sim->mtx, MA_OWNED); - sendq = &(sim->devq->send_queue); - if (sendq->qfrozen_cnt > 0) { + if (sendq->qfrozen_cnt[0] <= 0) { +#ifdef INVARIANTS + printf("xpt_release_simq: requested 1 > present %u\n", + sendq->qfrozen_cnt[0]); +#endif + } else + sendq->qfrozen_cnt[0]--; + if (sendq->qfrozen_cnt[0] == 0) { + /* + * If there is a timeout scheduled to release this + * sim queue, remove it. The queue frozen count is + * already at 0. + */ + if ((sim->flags & CAM_SIM_REL_TIMEOUT_PENDING) != 0){ + callout_stop(&sim->callout); + sim->flags &= ~CAM_SIM_REL_TIMEOUT_PENDING; + } + if (run_queue) { + struct cam_eb *bus; - sendq->qfrozen_cnt--; - if (sendq->qfrozen_cnt == 0) { /* - * If there is a timeout scheduled to release this - * sim queue, remove it. The queue frozen count is - * already at 0. + * Now that we are unfrozen run the send queue. */ - if ((sim->flags & CAM_SIM_REL_TIMEOUT_PENDING) != 0){ - callout_stop(&sim->callout); - sim->flags &= ~CAM_SIM_REL_TIMEOUT_PENDING; - } - - 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); - } + bus = xpt_find_bus(sim->path_id); + xpt_run_dev_sendq(bus); + xpt_release_bus(bus); } } } @@ -4399,7 +4436,7 @@ xpt_alloc_device_default(struct cam_eb *bus, struct cam_et *target, device->mintags = 1; device->maxtags = 1; - bus->sim->max_ccbs = device->ccbq.devq_openings; + bus->sim->max_ccbs += device->ccbq.devq_openings; cur_device = TAILQ_FIRST(&target->ed_entries); while (cur_device != NULL && cur_device->lun_id < lun_id) cur_device = TAILQ_NEXT(cur_device, links); @@ -4629,104 +4666,16 @@ xpt_stop_tags(struct cam_path *path) xpt_action((union ccb *)&crs); } -static int busses_to_config; -static int busses_to_reset; - -static int -xptconfigbuscountfunc(struct cam_eb *bus, void *arg) +static void +xpt_boot_delay(void *arg) { - mtx_assert(bus->sim->mtx, MA_OWNED); - - if (bus->path_id != CAM_XPT_PATH_ID) { - struct cam_path path; - struct ccb_pathinq cpi; - int can_negotiate; - - busses_to_config++; - xpt_compile_path(&path, NULL, bus->path_id, - CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); - 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; - can_negotiate &= (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE); - if ((cpi.hba_misc & PIM_NOBUSRESET) == 0 - && can_negotiate) - busses_to_reset++; - xpt_release_path(&path); - } - - return(1); -} - -static int -xptconfigfunc(struct cam_eb *bus, void *arg) -{ - struct cam_path *path; - union ccb *work_ccb; - - mtx_assert(bus->sim->mtx, MA_OWNED); - - if (bus->path_id != CAM_XPT_PATH_ID) { - cam_status status; - int can_negotiate; - - work_ccb = xpt_alloc_ccb_nowait(); - if (work_ccb == NULL) { - busses_to_config--; - xpt_finishconfig(xpt_periph, NULL); - return(0); - } - if ((status = xpt_create_path(&path, xpt_periph, bus->path_id, - CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD)) !=CAM_REQ_CMP){ - printf("xptconfigfunc: xpt_create_path failed with " - "status %#x for scbus%d\n", status, bus->path_id); - printf("xptconfigfunc: halting bus configuration\n"); - xpt_free_ccb(work_ccb); - busses_to_config--; - xpt_finishconfig(xpt_periph, NULL); - return(0); - } - 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) { - printf("xptconfigfunc: CPI failed on scbus%d " - "with status %d\n", bus->path_id, - work_ccb->ccb_h.status); - xpt_finishconfig(xpt_periph, work_ccb); - return(1); - } - - can_negotiate = work_ccb->cpi.hba_inquiry; - 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, CAM_PRIORITY_NORMAL); - work_ccb->ccb_h.func_code = XPT_RESET_BUS; - work_ccb->ccb_h.cbfcnp = NULL; - CAM_DEBUG(path, CAM_DEBUG_SUBTRACE, - ("Resetting Bus\n")); - xpt_action(work_ccb); - xpt_finishconfig(xpt_periph, work_ccb); - } else { - /* Act as though we performed a successful BUS RESET */ - work_ccb->ccb_h.func_code = XPT_RESET_BUS; - xpt_finishconfig(xpt_periph, work_ccb); - } - } - - return(1); + xpt_release_boot(); } static void xpt_config(void *arg) { - struct periph_driver **p_drv; - int i; - /* * Now that interrupts are enabled, go find our devices */ @@ -4760,28 +4709,43 @@ 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)(); + periphdriver_init(1); + xpt_hold_boot(); + callout_init(&xsoftc.boot_callout, 1); + callout_reset(&xsoftc.boot_callout, hz * xsoftc.boot_delay / 1000, + xpt_boot_delay, NULL); + /* Fire up rescan thread. */ + if (kproc_create(xpt_scanner_thread, NULL, NULL, 0, 0, "xpt_thrd")) { + printf("xpt_init: failed to create rescan thread\n"); } - /* - * Scan all installed busses. - */ - xpt_for_all_busses(xptconfigbuscountfunc, NULL); +} - if (busses_to_config == 0) { +void +xpt_hold_boot(void) +{ + xpt_lock_buses(); + xsoftc.buses_to_config++; + xpt_unlock_buses(); +} + +void +xpt_release_boot(void) +{ + xpt_lock_buses(); + xsoftc.buses_to_config--; + if (xsoftc.buses_to_config == 0 && xsoftc.buses_config_done == 0) { + struct xpt_task *task; + + xsoftc.buses_config_done = 1; + xpt_unlock_buses(); /* Call manually because we don't have any busses */ - xpt_finishconfig(xpt_periph, NULL); - } else { - if (busses_to_reset > 0 && scsi_delay >= 2000) { - printf("Waiting %d seconds for SCSI " - "devices to settle\n", scsi_delay/1000); + task = malloc(sizeof(struct xpt_task), M_CAMXPT, M_NOWAIT); + if (task != NULL) { + TASK_INIT(&task->task, 0, xpt_finishconfig_task, task); + taskqueue_enqueue(taskqueue_thread, &task->task); } - xpt_for_all_busses(xptconfigfunc, NULL); - } + } else + xpt_unlock_buses(); } /* @@ -4809,72 +4773,23 @@ xptpassannouncefunc(struct cam_ed *device, void *arg) static void xpt_finishconfig_task(void *context, int pending) { - struct periph_driver **p_drv; - int i; - if (busses_to_config == 0) { - /* Register all the 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)(); - } + periphdriver_init(2); + /* + * Check for devices with no "standard" peripheral driver + * attached. For any devices like that, announce the + * passthrough driver so the user will see something. + */ + xpt_for_all_devices(xptpassannouncefunc, NULL); - /* - * Check for devices with no "standard" peripheral driver - * attached. For any devices like that, announce the - * passthrough driver so the user will see something. - */ - xpt_for_all_devices(xptpassannouncefunc, NULL); - - /* Release our hook so that the boot can continue. */ - config_intrhook_disestablish(xsoftc.xpt_config_hook); - free(xsoftc.xpt_config_hook, M_CAMXPT); - xsoftc.xpt_config_hook = NULL; - } + /* Release our hook so that the boot can continue. */ + config_intrhook_disestablish(xsoftc.xpt_config_hook); + free(xsoftc.xpt_config_hook, M_CAMXPT); + xsoftc.xpt_config_hook = NULL; free(context, M_CAMXPT); } -static void -xpt_finishconfig(struct cam_periph *periph, union ccb *done_ccb) -{ - struct xpt_task *task; - - if (done_ccb != NULL) { - CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("xpt_finishconfig\n")); - switch(done_ccb->ccb_h.func_code) { - case XPT_RESET_BUS: - if (done_ccb->ccb_h.status == CAM_REQ_CMP) { - done_ccb->ccb_h.func_code = XPT_SCAN_BUS; - done_ccb->ccb_h.cbfcnp = xpt_finishconfig; - done_ccb->crcn.flags = 0; - xpt_action(done_ccb); - return; - } - /* FALLTHROUGH */ - case XPT_SCAN_BUS: - default: - xpt_free_path(done_ccb->ccb_h.path); - busses_to_config--; - break; - } - } - - if (busses_to_config == 0) { - task = malloc(sizeof(struct xpt_task), M_CAMXPT, M_NOWAIT); - if (task != NULL) { - TASK_INIT(&task->task, 0, xpt_finishconfig_task, task); - taskqueue_enqueue(taskqueue_thread, &task->task); - } - } - - if (done_ccb != NULL) - xpt_free_ccb(done_ccb); -} - cam_status xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg, struct cam_path *path) @@ -4894,7 +4809,7 @@ xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg, xptpath = 1; } - xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5); + xpt_setup_ccb(&csa.ccb_h, path, CAM_PRIORITY_NORMAL); csa.ccb_h.func_code = XPT_SASYNC_CB; csa.event_enable = event; csa.callback = cbfunc; @@ -5047,26 +4962,19 @@ camisr_runqueue(void *V_queue) cam_ccbq_ccb_done(&dev->ccbq, (union ccb *)ccb_h); ccb_h->path->bus->sim->devq->send_active--; ccb_h->path->bus->sim->devq->send_openings++; + runq = TRUE; if (((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0 && (ccb_h->status&CAM_STATUS_MASK) != CAM_REQUEUE_REQ) || ((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0 && (dev->ccbq.dev_active == 0))) { - xpt_release_devq(ccb_h->path, /*count*/1, - /*run_queue*/TRUE); + /*run_queue*/FALSE); } if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 && (--dev->tag_delay_count == 0)) xpt_start_tags(ccb_h->path); - - if ((dev->ccbq.queue.entries > 0) - && (dev->ccbq.queue.qfrozen_cnt == 0) - && (device_is_send_queued(dev) == 0)) { - runq = xpt_schedule_dev_sendq(ccb_h->path->bus, - dev); - } } if (ccb_h->status & CAM_RELEASE_SIMQ) { diff --git a/sys/cam/cam_xpt.h b/sys/cam/cam_xpt.h index 283cad1c34e..61a7f3f02d2 100644 --- a/sys/cam/cam_xpt.h +++ b/sys/cam/cam_xpt.h @@ -87,6 +87,9 @@ SLIST_HEAD(periph_list, cam_periph); void xpt_action(union ccb *new_ccb); void xpt_action_default(union ccb *new_ccb); +union ccb *xpt_alloc_ccb(void); +union ccb *xpt_alloc_ccb_nowait(void); +void xpt_free_ccb(union ccb *free_ccb); void xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority); @@ -115,6 +118,8 @@ struct cam_periph *xpt_path_periph(struct cam_path *path); void xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg); void xpt_rescan(union ccb *ccb); +void xpt_hold_boot(void); +void xpt_release_boot(void); void xpt_lock_buses(void); void xpt_unlock_buses(void); cam_status xpt_register_async(int event, ac_callback_t *cbfunc, diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h index 146764ef763..b1fbaafb221 100644 --- a/sys/cam/cam_xpt_internal.h +++ b/sys/cam/cam_xpt_internal.h @@ -172,7 +172,6 @@ struct cam_ed * xpt_alloc_device(struct cam_eb *bus, 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); u_int32_t xpt_dev_ccbq_resize(struct cam_path *path, int newopenings); diff --git a/sys/cam/cam_xpt_periph.h b/sys/cam/cam_xpt_periph.h index dbfb55eb757..867b1c1d381 100644 --- a/sys/cam/cam_xpt_periph.h +++ b/sys/cam/cam_xpt_periph.h @@ -39,9 +39,6 @@ /* Functions accessed by the peripheral drivers */ #ifdef _KERNEL void xpt_polled_action(union ccb *ccb); -union ccb *xpt_alloc_ccb(void); -union ccb *xpt_alloc_ccb_nowait(void); -void xpt_free_ccb(union ccb *free_ccb); void xpt_release_ccb(union ccb *released_ccb); void xpt_schedule(struct cam_periph *perph, u_int32_t new_priority); int32_t xpt_add_periph(struct cam_periph *periph); diff --git a/sys/cam/cam_xpt_sim.h b/sys/cam/cam_xpt_sim.h index e64c67c16fa..323f786c813 100644 --- a/sys/cam/cam_xpt_sim.h +++ b/sys/cam/cam_xpt_sim.h @@ -43,8 +43,12 @@ int32_t xpt_bus_deregister(path_id_t path_id); u_int32_t xpt_freeze_simq(struct cam_sim *sim, u_int count); void xpt_release_simq(struct cam_sim *sim, int run_queue); u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count); -void xpt_release_devq(struct cam_path *path, u_int count, - int run_queue); +u_int32_t xpt_freeze_devq_rl(struct cam_path *path, cam_rl rl, + u_int count); +void xpt_release_devq(struct cam_path *path, + u_int count, int run_queue); +void xpt_release_devq_rl(struct cam_path *path, cam_rl rl, + u_int count, int run_queue); int xpt_sim_opened(struct cam_sim *sim); void xpt_done(union ccb *done_ccb); #endif diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c index e6f3a7c1005..d40a53659ec 100644 --- a/sys/cam/scsi/scsi_all.c +++ b/sys/cam/scsi/scsi_all.c @@ -2880,7 +2880,7 @@ scsi_error_action(struct ccb_scsiio *csio, struct scsi_inquiry_data *inq_data, } } } -#ifdef KERNEL +#ifdef _KERNEL if (bootverbose) sense_flags |= SF_PRINT_ALWAYS; #endif @@ -2995,27 +2995,29 @@ scsi_command_string(struct cam_device *device, struct ccb_scsiio *csio, struct scsi_inquiry_data *inq_data; char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1]; #ifdef _KERNEL - struct ccb_getdev cgd; + struct ccb_getdev *cgd; #endif /* _KERNEL */ #ifdef _KERNEL + if ((cgd = (struct ccb_getdev*)xpt_alloc_ccb_nowait()) == NULL) + return(-1); /* * Get the device information. */ - xpt_setup_ccb(&cgd.ccb_h, + xpt_setup_ccb(&cgd->ccb_h, csio->ccb_h.path, CAM_PRIORITY_NORMAL); - cgd.ccb_h.func_code = XPT_GDEV_TYPE; - xpt_action((union ccb *)&cgd); + cgd->ccb_h.func_code = XPT_GDEV_TYPE; + xpt_action((union ccb *)cgd); /* * If the device is unconfigured, just pretend that it is a hard * drive. scsi_op_desc() needs this. */ - if (cgd.ccb_h.status == CAM_DEV_NOT_THERE) - cgd.inq_data.device = T_DIRECT; + if (cgd->ccb_h.status == CAM_DEV_NOT_THERE) + cgd->inq_data.device = T_DIRECT; - inq_data = &cgd.inq_data; + inq_data = &cgd->inq_data; #else /* !_KERNEL */ @@ -3055,7 +3057,7 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, struct scsi_sense_data *sense; struct scsi_inquiry_data *inq_data; #ifdef _KERNEL - struct ccb_getdev cgd; + struct ccb_getdev *cgd; #endif /* _KERNEL */ u_int32_t info; int error_code; @@ -3083,23 +3085,25 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, #endif /* _KERNEL/!_KERNEL */ #ifdef _KERNEL + if ((cgd = (struct ccb_getdev*)xpt_alloc_ccb_nowait()) == NULL) + return(-1); /* * Get the device information. */ - xpt_setup_ccb(&cgd.ccb_h, + xpt_setup_ccb(&cgd->ccb_h, csio->ccb_h.path, CAM_PRIORITY_NORMAL); - cgd.ccb_h.func_code = XPT_GDEV_TYPE; - xpt_action((union ccb *)&cgd); + cgd->ccb_h.func_code = XPT_GDEV_TYPE; + xpt_action((union ccb *)cgd); /* * If the device is unconfigured, just pretend that it is a hard * drive. scsi_op_desc() needs this. */ - if (cgd.ccb_h.status == CAM_DEV_NOT_THERE) - cgd.inq_data.device = T_DIRECT; + if (cgd->ccb_h.status == CAM_DEV_NOT_THERE) + cgd->inq_data.device = T_DIRECT; - inq_data = &cgd.inq_data; + inq_data = &cgd->inq_data; #else /* !_KERNEL */ @@ -3125,9 +3129,12 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, * If the sense data is a physical pointer, forget it. */ if (csio->ccb_h.flags & CAM_SENSE_PTR) { - if (csio->ccb_h.flags & CAM_SENSE_PHYS) + if (csio->ccb_h.flags & CAM_SENSE_PHYS) { +#ifdef _KERNEL + xpt_free_ccb((union ccb*)cgd); +#endif /* _KERNEL/!_KERNEL */ return(-1); - else { + } else { /* * bcopy the pointer to avoid unaligned access * errors on finicky architectures. We don't @@ -3145,9 +3152,12 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, * dumped on one of the bogus pointer deferences above * already.) */ - if (csio->ccb_h.flags & CAM_SENSE_PHYS) + if (csio->ccb_h.flags & CAM_SENSE_PHYS) { +#ifdef _KERNEL + xpt_free_ccb((union ccb*)cgd); +#endif /* _KERNEL/!_KERNEL */ return(-1); - else + } else sense = &csio->sense_data; } @@ -3157,9 +3167,10 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, error_code = sense->error_code & SSD_ERRCODE; sense_key = sense->flags & SSD_KEY; + sbuf_printf(sb, "SCSI sense: "); switch (error_code) { case SSD_DEFERRED_ERROR: - sbuf_printf(sb, "Deferred Error: "); + sbuf_printf(sb, "Deferred error: "); /* FALLTHROUGH */ case SSD_CURRENT_ERROR: @@ -3212,8 +3223,7 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, } } - sbuf_printf(sb, " asc:%x,%x\n%s%s", asc, ascq, - path_str, asc_desc); + sbuf_printf(sb, " asc:%x,%x (%s)", asc, ascq, asc_desc); if (sense->extra_len >= 7 && sense->fru) { sbuf_printf(sb, " field replaceable unit: %x", @@ -3265,7 +3275,7 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, } default: - sbuf_printf(sb, "Sense Error Code 0x%x", sense->error_code); + sbuf_printf(sb, "Error code 0x%x", sense->error_code); if (sense->error_code & SSD_ERRCODE_VALID) { sbuf_printf(sb, " at block no. %d (decimal)", info = scsi_4btoul(sense->info)); @@ -3274,6 +3284,9 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, sbuf_printf(sb, "\n"); +#ifdef _KERNEL + xpt_free_ccb((union ccb*)cgd); +#endif /* _KERNEL/!_KERNEL */ return(0); } diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index 4a501f109f8..72454e2ea4c 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -433,7 +433,7 @@ cdcleanup(struct cam_periph *periph) callout_stop(&softc->changer->short_handle); softc->changer->flags &= ~CHANGER_SHORT_TMOUT_SCHED; } - softc->changer->devq.qfrozen_cnt--; + softc->changer->devq.qfrozen_cnt[0]--; softc->changer->flags |= CHANGER_MANUAL_CALL; cdrunchangerqueue(softc->changer); } @@ -972,9 +972,9 @@ cdregisterexit: (void)cam_periph_hold(periph, PRIBIO); if ((softc->flags & CD_FLAG_CHANGER) == 0) - xpt_schedule(periph, /*priority*/5); + xpt_schedule(periph, CAM_PRIORITY_DEV); else - cdschedule(periph, /*priority*/ 5); + cdschedule(periph, CAM_PRIORITY_DEV); return(CAM_REQ_CMP); } @@ -1167,13 +1167,13 @@ cdrunchangerqueue(void *arg) * If the changer queue is frozen, that means we have an active * device. */ - if (changer->devq.qfrozen_cnt > 0) { + if (changer->devq.qfrozen_cnt[0] > 0) { /* * We always need to reset the frozen count and clear the * active flag. */ - changer->devq.qfrozen_cnt--; + changer->devq.qfrozen_cnt[0]--; changer->cur_device->flags &= ~CD_FLAG_ACTIVE; changer->cur_device->flags &= ~CD_FLAG_SCHED_ON_COMP; @@ -1208,7 +1208,7 @@ cdrunchangerqueue(void *arg) changer->cur_device = softc; - changer->devq.qfrozen_cnt++; + changer->devq.qfrozen_cnt[0]++; softc->flags |= CD_FLAG_ACTIVE; /* Just in case this device is waiting */ @@ -1465,7 +1465,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) bioq_remove(&softc->bio_queue, bp); scsi_read_write(&start_ccb->csio, - /*retries*/cd_retry_count, + /*retries*/ cd_retry_count, /* cbfcnp */ cddone, MSG_SIMPLE_Q_TAG, /* read */bp->bio_cmd == BIO_READ, @@ -1516,7 +1516,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) } csio = &start_ccb->csio; scsi_read_capacity(csio, - /*retries*/1, + /*retries*/ cd_retry_count, cddone, MSG_SIMPLE_Q_TAG, rcap, @@ -2737,7 +2737,7 @@ cdprevent(struct cam_periph *periph, int action) ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL); scsi_prevent(&ccb->csio, - /*retries*/ 1, + /*retries*/ cd_retry_count, cddone, MSG_SIMPLE_Q_TAG, action, @@ -2915,7 +2915,7 @@ cdsize(struct cam_periph *periph, u_int32_t *size) return (ENOMEM); scsi_read_capacity(&ccb->csio, - /*retries*/ 1, + /*retries*/ cd_retry_count, cddone, MSG_SIMPLE_Q_TAG, rcap_buf, @@ -3163,7 +3163,7 @@ cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start, csio = &ccb->csio; cam_fill_csio(csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* flags */ CAM_DIR_IN, /* tag_action */ MSG_SIMPLE_Q_TAG, @@ -3210,7 +3210,7 @@ cdreadsubchannel(struct cam_periph *periph, u_int32_t mode, csio = &ccb->csio; cam_fill_csio(csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* flags */ CAM_DIR_IN, /* tag_action */ MSG_SIMPLE_Q_TAG, @@ -3271,7 +3271,7 @@ cdgetmode(struct cam_periph *periph, struct cd_mode_params *data, param_len = min(param_len, data->alloc_len); scsi_mode_sense_len(csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ 0, @@ -3414,7 +3414,7 @@ cdsetmode(struct cam_periph *periph, struct cd_mode_params *data) param_len = min(param_len, data->alloc_len); scsi_mode_select_len(csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* scsi_page_fmt */ 1, @@ -3476,7 +3476,7 @@ cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len) cdb_len = sizeof(*scsi_cmd); } cam_fill_csio(csio, - /*retries*/2, + /*retries*/ cd_retry_count, cddone, /*flags*/CAM_DIR_NONE, MSG_SIMPLE_Q_TAG, @@ -3510,7 +3510,7 @@ cdplaymsf(struct cam_periph *periph, u_int32_t startm, u_int32_t starts, csio = &ccb->csio; cam_fill_csio(csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* flags */ CAM_DIR_NONE, /* tag_action */ MSG_SIMPLE_Q_TAG, @@ -3556,7 +3556,7 @@ cdplaytracks(struct cam_periph *periph, u_int32_t strack, u_int32_t sindex, csio = &ccb->csio; cam_fill_csio(csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* flags */ CAM_DIR_NONE, /* tag_action */ MSG_SIMPLE_Q_TAG, @@ -3598,7 +3598,7 @@ cdpause(struct cam_periph *periph, u_int32_t go) csio = &ccb->csio; cam_fill_csio(csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* flags */ CAM_DIR_NONE, /* tag_action */ MSG_SIMPLE_Q_TAG, @@ -3633,7 +3633,7 @@ cdstartunit(struct cam_periph *periph, int load) ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL); scsi_start_stop(&ccb->csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* start */ TRUE, @@ -3661,7 +3661,7 @@ cdstopunit(struct cam_periph *periph, u_int32_t eject) ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL); scsi_start_stop(&ccb->csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* start */ FALSE, @@ -3697,7 +3697,7 @@ cdsetspeed(struct cam_periph *periph, u_int32_t rdspeed, u_int32_t wrspeed) wrspeed *= 177; cam_fill_csio(csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* flags */ CAM_DIR_NONE, /* tag_action */ MSG_SIMPLE_Q_TAG, @@ -3774,7 +3774,7 @@ cdreportkey(struct cam_periph *periph, struct dvd_authinfo *authinfo) scsi_report_key(&ccb->csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* lba */ lba, @@ -3951,7 +3951,7 @@ cdsendkey(struct cam_periph *periph, struct dvd_authinfo *authinfo) } scsi_send_key(&ccb->csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* agid */ authinfo->agid, @@ -4081,7 +4081,7 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct) databuf = NULL; scsi_read_dvd_structure(&ccb->csio, - /* retries */ 1, + /* retries */ cd_retry_count, /* cbfcnp */ cddone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* lba */ address, diff --git a/sys/cam/scsi/scsi_ch.c b/sys/cam/scsi/scsi_ch.c index 2829a155d9a..107f22b2ed9 100644 --- a/sys/cam/scsi/scsi_ch.c +++ b/sys/cam/scsi/scsi_ch.c @@ -376,7 +376,7 @@ chregister(struct cam_periph *periph, void *arg) * This first call can't block */ (void)cam_periph_hold(periph, PRIBIO); - xpt_schedule(periph, /*priority*/5); + xpt_schedule(periph, CAM_PRIORITY_DEV); return(CAM_REQ_CMP); } diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index d05376ee295..77652b2dc94 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -1272,7 +1272,7 @@ daregister(struct cam_periph *periph, void *arg) * the end of probe. */ (void)cam_periph_hold(periph, PRIBIO); - xpt_schedule(periph, /*priority*/5); + xpt_schedule(periph, CAM_PRIORITY_DEV); /* * Schedule a periodic event to occasionally send an diff --git a/sys/cam/scsi/scsi_low.c b/sys/cam/scsi/scsi_low.c index 1cee43dca29..1b2f4f601ed 100644 --- a/sys/cam/scsi/scsi_low.c +++ b/sys/cam/scsi/scsi_low.c @@ -895,8 +895,6 @@ scsi_low_target_open(link, cf) #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb() static void scsi_low_poll_cam(struct cam_sim *); -static void scsi_low_cam_rescan_callback(struct cam_periph *, union ccb *); -static void scsi_low_rescan_bus_cam(struct scsi_low_softc *); void scsi_low_scsi_action_cam(struct cam_sim *, union ccb *); static int scsi_low_attach_cam(struct scsi_low_softc *); @@ -954,38 +952,6 @@ scsi_low_poll_cam(sim) } } -static void -scsi_low_cam_rescan_callback(periph, ccb) - struct cam_periph *periph; - union ccb *ccb; -{ - - xpt_free_path(ccb->ccb_h.path); - xpt_free_ccb(ccb); -} - -static void -scsi_low_rescan_bus_cam(slp) - struct scsi_low_softc *slp; -{ - struct cam_path *path; - union ccb *ccb; - cam_status status; - - status = xpt_create_path(&path, xpt_periph, - cam_sim_path(slp->sl_si.sim), -1, 0); - if (status != CAM_REQ_CMP) - return; - - ccb = xpt_alloc_ccb(); - bzero(ccb, sizeof(union ccb)); - xpt_setup_ccb(&ccb->ccb_h, path, 5); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback; - ccb->crcn.flags = CAM_FLAG_NONE; - xpt_action(ccb); -} - void scsi_low_scsi_action_cam(sim, ccb) struct cam_sim *sim; @@ -1376,8 +1342,6 @@ scsi_low_world_start_cam(slp) struct scsi_low_softc *slp; { - if (!cold) - scsi_low_rescan_bus_cam(slp); return 0; } diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index 75518918375..9464ca21ce3 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -563,12 +563,10 @@ passsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb) * that request. Otherwise, it's up to the user to perform any * error recovery. */ - error = cam_periph_runccb(ccb, - (ccb->ccb_h.flags & CAM_PASS_ERR_RECOVER) ? - passerror : NULL, - /* cam_flags */ CAM_RETRY_SELTO, - /* sense_flags */SF_RETRY_UA, - softc->device_stats); + cam_periph_runccb(ccb, + (ccb->ccb_h.flags & CAM_PASS_ERR_RECOVER) ? passerror : NULL, + /* cam_flags */ CAM_RETRY_SELTO, /* sense_flags */SF_RETRY_UA, + softc->device_stats); if (need_unmap != 0) cam_periph_unmapmem(ccb, &mapinfo); @@ -577,7 +575,7 @@ passsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb) ccb->ccb_h.periph_priv = inccb->ccb_h.periph_priv; bcopy(ccb, inccb, sizeof(union ccb)); - return(error); + return(0); } static int diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c index cae7be61ac9..7639377052b 100644 --- a/sys/cam/scsi/scsi_xpt.c +++ b/sys/cam/scsi/scsi_xpt.c @@ -616,6 +616,11 @@ proberegister(struct cam_periph *periph, void *arg) */ cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset, scsi_delay); + /* + * Ensure nobody slip in until probe finish. + */ + cam_freeze_devq_arg(periph->path, + RELSIM_RELEASE_RUNLEVEL, CAM_RL_XPT + 1); probeschedule(periph); return(CAM_REQ_CMP); } @@ -630,7 +635,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); @@ -668,7 +673,7 @@ probeschedule(struct cam_periph *periph) else softc->flags &= ~PROBE_NO_ANNOUNCE; - xpt_schedule(periph, ccb->ccb_h.pinfo.priority); + xpt_schedule(periph, CAM_PRIORITY_XPT); } static void @@ -881,7 +886,7 @@ proberequestdefaultnegotiation(struct cam_periph *periph) { struct ccb_trans_settings cts; - xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); @@ -903,7 +908,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); @@ -1420,6 +1425,8 @@ probedone(struct cam_periph *periph, union ccb *done_ccb) done_ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(done_ccb); if (TAILQ_FIRST(&softc->request_ccbs) == NULL) { + cam_release_devq(periph->path, + RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE); cam_periph_invalidate(periph); cam_periph_release_locked(periph); } else { @@ -1491,7 +1498,7 @@ scsi_scan_bus(struct cam_periph *periph, union ccb *request_ccb) case XPT_SCAN_BUS: { scsi_scan_bus_info *scan_info; - union ccb *work_ccb; + union ccb *work_ccb, *reset_ccb; struct cam_path *path; u_int i; u_int max_target; @@ -1526,6 +1533,26 @@ scsi_scan_bus(struct cam_periph *periph, union ccb *request_ccb) return; } + /* We may need to reset bus first, if we haven't done it yet. */ + if ((work_ccb->cpi.hba_inquiry & + (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) && + !(work_ccb->cpi.hba_misc & PIM_NOBUSRESET) && + !timevalisset(&request_ccb->ccb_h.path->bus->last_reset)) { + reset_ccb = xpt_alloc_ccb_nowait(); + xpt_setup_ccb(&reset_ccb->ccb_h, request_ccb->ccb_h.path, + CAM_PRIORITY_NONE); + reset_ccb->ccb_h.func_code = XPT_RESET_BUS; + xpt_action(reset_ccb); + if (reset_ccb->ccb_h.status != CAM_REQ_CMP) { + request_ccb->ccb_h.status = reset_ccb->ccb_h.status; + xpt_free_ccb(reset_ccb); + xpt_free_ccb(work_ccb); + xpt_done(request_ccb); + return; + } + xpt_free_ccb(reset_ccb); + } + /* Save some state for use while we probe for devices */ scan_info = (scsi_scan_bus_info *) malloc(sizeof(scsi_scan_bus_info), M_CAMXPT, M_NOWAIT); @@ -1756,10 +1783,9 @@ scsi_scan_lun(struct cam_periph *periph, struct cam_path *path, struct cam_path *new_path; struct cam_periph *old_periph; - CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("scsi_scan_lun\n")); + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("scsi_scan_lun\n")); - xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); @@ -1809,7 +1835,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&request_ccb->ccb_h, new_path, CAM_PRIORITY_XPT); request_ccb->ccb_h.cbfcnp = xptscandone; request_ccb->ccb_h.func_code = XPT_SCAN_LUN; request_ccb->crcn.flags = flags; @@ -1907,7 +1933,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); @@ -1967,7 +1993,7 @@ scsi_devise_transport(struct cam_path *path) */ /* Tell the controller what we think */ - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.transport = path->device->transport; @@ -2095,7 +2121,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); @@ -2116,7 +2142,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE); cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cur_cts.type = cts->type; xpt_action((union ccb *)&cur_cts); @@ -2300,7 +2326,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, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.protocol = PROTO_SCSI; cts.protocol_version = PROTO_VERSION_UNSPECIFIED; cts.transport = XPORT_UNSPECIFIED; @@ -2350,11 +2376,18 @@ scsi_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, /* * Allow transfer negotiation to occur in a - * tag free environment. + * tag free environment and after settle delay. */ if (async_code == AC_SENT_BDR - || async_code == AC_BUS_RESET) + || async_code == AC_BUS_RESET) { + cam_freeze_devq(&newpath); + cam_release_devq(&newpath, + RELSIM_RELEASE_AFTER_TIMEOUT, + /*reduction*/0, + /*timeout*/scsi_delay, + /*getcount_only*/0); scsi_toggle_tags(&newpath); + } if (async_code == AC_INQ_CHANGED) { /* diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index bf6ab22eca2..bb661ee20bb 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include /* local prototypes */ @@ -86,7 +85,7 @@ static void ahci_start_fr(device_t dev); static void ahci_stop_fr(device_t dev); static int ahci_sata_connect(struct ahci_channel *ch); -static int ahci_sata_phy_reset(device_t dev, int quick); +static int ahci_sata_phy_reset(device_t dev); static void ahci_issue_read_log(device_t dev); static void ahci_process_read_log(device_t dev, union ccb *ccb); @@ -348,6 +347,8 @@ ahci_attach(device_t dev) ctlr->caps = ATA_INL(ctlr->r_mem, AHCI_CAP); if (version >= 0x00010020) ctlr->caps2 = ATA_INL(ctlr->r_mem, AHCI_CAP2); + if (ctlr->caps & AHCI_CAP_EMS) + ctlr->capsem = ATA_INL(ctlr->r_mem, AHCI_EM_CTL); ctlr->ichannels = ATA_INL(ctlr->r_mem, AHCI_PI); if (ctlr->quirks & AHCI_Q_1CH) { ctlr->caps &= ~AHCI_CAP_NPMASK; @@ -417,6 +418,17 @@ ahci_attach(device_t dev) (ctlr->caps2 & AHCI_CAP2_NVMP) ? " NVMP":"", (ctlr->caps2 & AHCI_CAP2_BOH) ? " BOH":""); } + if (bootverbose && (ctlr->caps & AHCI_CAP_EMS)) { + device_printf(dev, "EM Caps: %s%s%s%s%s%s%s%s\n", + (ctlr->capsem & AHCI_EM_PM) ? " PM":"", + (ctlr->capsem & AHCI_EM_ALHD) ? " ALHD":"", + (ctlr->capsem & AHCI_EM_XMT) ? " XMT":"", + (ctlr->capsem & AHCI_EM_SMB) ? " SMB":"", + (ctlr->capsem & AHCI_EM_SGPIO) ? " SGPIO":"", + (ctlr->capsem & AHCI_EM_SES2) ? " SES-2":"", + (ctlr->capsem & AHCI_EM_SAFTE) ? " SAF-TE":"", + (ctlr->capsem & AHCI_EM_LED) ? " LED":""); + } /* Attach all channels on this controller */ for (unit = 0; unit < ctlr->channels; unit++) { if ((ctlr->ichannels & (1 << unit)) == 0) @@ -1125,6 +1137,8 @@ ahci_phy_check_events(device_t dev, u_int32_t serr) if ((serr & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) { u_int32_t status = ATA_INL(ch->r_mem, AHCI_P_SSTS); + union ccb *ccb; + if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) { @@ -1136,6 +1150,15 @@ ahci_phy_check_events(device_t dev, u_int32_t serr) device_printf(dev, "DISCONNECT requested\n"); ch->devices = 0; } + if ((ccb = xpt_alloc_ccb_nowait()) == NULL) + return; + if (xpt_create_path(&ccb->ccb_h.path, NULL, + cam_sim_path(ch->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xpt_free_ccb(ccb); + return; + } + xpt_rescan(ccb); } } @@ -1505,6 +1528,13 @@ ahci_execute_transaction(struct ahci_slot *slot) if (timeout && (count >= timeout)) { device_printf(ch->dev, "Poll 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)); et = AHCI_ERR_TIMEOUT; } if (et != AHCI_ERR_NONE) { @@ -1929,7 +1959,7 @@ ahci_wait_ready(device_t dev, int t) (ATA_S_BUSY | ATA_S_DRQ)) { DELAY(1000); if (timeout++ > t) { - device_printf(dev, "port is not ready (timeout %dms) " + device_printf(dev, "device is not ready (timeout %dms) " "tfd = %08x\n", t, val); return (EBUSY); } @@ -1946,6 +1976,7 @@ ahci_reset(device_t dev) struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev)); int i; + xpt_freeze_simq(ch->sim, 1); if (bootverbose) device_printf(dev, "AHCI reset...\n"); /* Requeue freezed command. */ @@ -1980,7 +2011,7 @@ ahci_reset(device_t dev) /* Disable port interrupts */ ATA_OUTL(ch->r_mem, AHCI_P_IE, 0); /* Reset and reconnect PHY, */ - if (!ahci_sata_phy_reset(dev, 0)) { + if (!ahci_sata_phy_reset(dev)) { if (bootverbose) device_printf(dev, "AHCI reset done: phy reset found no device\n"); @@ -1988,13 +2019,12 @@ ahci_reset(device_t dev) /* Enable wanted port interrupts */ ATA_OUTL(ch->r_mem, AHCI_P_IE, (AHCI_P_IX_CPD | AHCI_P_IX_PRC | AHCI_P_IX_PC)); + xpt_release_simq(ch->sim, TRUE); return; } /* Wait for clearing busy status. */ - if (ahci_wait_ready(dev, 10000)) { - device_printf(dev, "device ready timeout\n"); + if (ahci_wait_ready(dev, 15000)) ahci_clo(dev); - } ahci_start(dev); ch->devices = 1; /* Enable wanted port interrupts */ @@ -2006,6 +2036,7 @@ 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"); + xpt_release_simq(ch->sim, TRUE); } static int @@ -2098,20 +2129,12 @@ ahci_sata_connect(struct ahci_channel *ch) } static int -ahci_sata_phy_reset(device_t dev, int quick) +ahci_sata_phy_reset(device_t dev) { struct ahci_channel *ch = device_get_softc(dev); int sata_rev; uint32_t val; - if (quick) { - val = ATA_INL(ch->r_mem, AHCI_P_SCTL); - if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE) - return (ahci_sata_connect(ch)); - } - - if (bootverbose) - device_printf(dev, "hardware reset ...\n"); sata_rev = ch->user[ch->pm_present ? 15 : 0].revision; if (sata_rev == 1) val = ATA_SC_SPD_SPEED_GEN1; diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index e11f84f489d..d136d82b326 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -186,6 +186,20 @@ #define AHCI_CCCC_EN 0x00000001 #define AHCI_CCCP 0x18 +#define AHCI_EM_LOC 0x1C +#define AHCI_EM_CTL 0x20 +#define AHCI_EM_MR 0x00000001 +#define AHCI_EM_TM 0x00000100 +#define AHCI_EM_RST 0x00000200 +#define AHCI_EM_LED 0x00010000 +#define AHCI_EM_SAFTE 0x00020000 +#define AHCI_EM_SES2 0x00040000 +#define AHCI_EM_SGPIO 0x00080000 +#define AHCI_EM_SMB 0x01000000 +#define AHCI_EM_XMT 0x02000000 +#define AHCI_EM_ALHD 0x04000000 +#define AHCI_EM_PM 0x08000000 + #define AHCI_CAP2 0x24 #define AHCI_CAP2_BOH 0x00000001 #define AHCI_CAP2_NVMP 0x00000002 @@ -402,6 +416,7 @@ struct ahci_controller { } irqs[16]; uint32_t caps; /* Controller capabilities */ uint32_t caps2; /* Controller capabilities */ + uint32_t capsem; /* Controller capabilities */ int quirks; int numirqs; int channels; diff --git a/sys/dev/asr/asr.c b/sys/dev/asr/asr.c index 2bc5e227724..ae363d0045d 100644 --- a/sys/dev/asr/asr.c +++ b/sys/dev/asr/asr.c @@ -130,7 +130,6 @@ #include #include #include -#include #include #include diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index f342c819ef1..1ad3c5117c1 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #endif @@ -289,12 +288,26 @@ ata_detach(device_t dev) static void ata_conn_event(void *context, int dummy) { - device_t dev = (device_t)context; - struct ata_channel *ch = device_get_softc(dev); + device_t dev = (device_t)context; + struct ata_channel *ch = device_get_softc(dev); +#ifdef ATA_CAM + union ccb *ccb; +#endif - mtx_lock(&ch->state_mtx); - ata_reinit(dev); - mtx_unlock(&ch->state_mtx); + mtx_lock(&ch->state_mtx); + ata_reinit(dev); + mtx_unlock(&ch->state_mtx); +#ifdef ATA_CAM + if ((ccb = xpt_alloc_ccb()) == NULL) + return; + if (xpt_create_path(&ccb->ccb_h.path, NULL, + cam_sim_path(ch->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xpt_free_ccb(ccb); + return; + } + xpt_rescan(ccb); +#endif } int @@ -390,6 +403,7 @@ ata_reinit(device_t dev) /* kick off requests on the queue */ ata_start(dev); #else + xpt_freeze_simq(ch->sim, 1); if ((request = ch->running)) { ch->running = NULL; if (ch->state == ATA_ACTIVE) @@ -404,6 +418,7 @@ ata_reinit(device_t dev) ATA_RESET(dev); /* Tell the XPT about the event */ xpt_async(AC_BUS_RESET, ch->path, NULL); + xpt_release_simq(ch->sim, TRUE); #endif return(0); } diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c index 84b44c56399..3f8e650708c 100644 --- a/sys/dev/ata/atapi-cam.c +++ b/sys/dev/ata/atapi-cam.c @@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -109,7 +108,6 @@ static int atapi_cam_event_handler(module_t mod, int what, void *arg); /* internal functions */ static void reinit_bus(struct atapi_xpt_softc *scp, enum reinit_reason reason); static void setup_async_cb(struct atapi_xpt_softc *, uint32_t); -static void cam_rescan_callback(struct cam_periph *, union ccb *); static void cam_rescan(struct cam_sim *); static void free_hcb_and_ccb_done(struct atapi_hcb *, u_int32_t); static struct atapi_hcb *allocate_hcb(struct atapi_xpt_softc *, int, int, union ccb *); @@ -315,6 +313,7 @@ reinit_bus(struct atapi_xpt_softc *scp, enum reinit_reason reason) { switch (reason) { case BOOT_ATTACH: + case ATTACH: break; case RESET: xpt_async(AC_BUS_RESET, scp->path, NULL); @@ -322,8 +321,6 @@ reinit_bus(struct atapi_xpt_softc *scp, enum reinit_reason reason) { if (!dev_changed) break; - /*FALLTHROUGH*/ - case ATTACH: cam_rescan(scp->sim); break; } @@ -821,42 +818,21 @@ atapi_async(void *callback_arg, u_int32_t code, } } -static void -cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) -{ - if (ccb->ccb_h.status != CAM_REQ_CMP) { - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("Rescan failed, 0x%04x\n", ccb->ccb_h.status)); - } else { - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("Rescan succeeded\n")); - } - xpt_free_path(ccb->ccb_h.path); - xpt_free_ccb(ccb); -} - static void cam_rescan(struct cam_sim *sim) { - struct cam_path *path; union ccb *ccb; ccb = xpt_alloc_ccb_nowait(); if (ccb == NULL) return; - - if (xpt_create_path(&path, xpt_periph, cam_sim_path(sim), + if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_free_ccb(ccb); return; } - - CAM_DEBUG(path, CAM_DEBUG_TRACE, ("Rescanning ATAPI bus.\n")); - xpt_setup_ccb(&ccb->ccb_h, path, 5/*priority (low)*/); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = cam_rescan_callback; - ccb->crcn.flags = CAM_FLAG_NONE; - xpt_action(ccb); + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("Rescanning ATAPI bus.\n")); + xpt_rescan(ccb); /* scan is in progress now */ } diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index 2455004230e..66a046d8105 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -173,8 +173,6 @@ static void ciss_unmap_request(struct ciss_request *cr); static int ciss_cam_init(struct ciss_softc *sc); static void ciss_cam_rescan_target(struct ciss_softc *sc, int bus, int target); -static void ciss_cam_rescan_all(struct ciss_softc *sc); -static void ciss_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb); static void ciss_cam_action(struct cam_sim *sim, union ccb *ccb); static int ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio); static int ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio); @@ -2863,13 +2861,6 @@ ciss_cam_init(struct ciss_softc *sc) mtx_unlock(&sc->ciss_mtx); } - /* - * Initiate a rescan of the bus. - */ - mtx_lock(&sc->ciss_mtx); - ciss_cam_rescan_all(sc); - mtx_unlock(&sc->ciss_mtx); - return(0); } @@ -2879,53 +2870,26 @@ ciss_cam_init(struct ciss_softc *sc) static void ciss_cam_rescan_target(struct ciss_softc *sc, int bus, int target) { - struct cam_path *path; union ccb *ccb; debug_called(1); - if ((ccb = malloc(sizeof(union ccb), CISS_MALLOC_CLASS, M_NOWAIT | M_ZERO)) == NULL) { + if ((ccb = xpt_alloc_ccb_nowait()) == NULL) { ciss_printf(sc, "rescan failed (can't allocate CCB)\n"); return; } - if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->ciss_cam_sim[bus]), - target, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, + cam_sim_path(sc->ciss_cam_sim[bus]), + target, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { ciss_printf(sc, "rescan failed (can't create path)\n"); - free(ccb, CISS_MALLOC_CLASS); + xpt_free_ccb(ccb); return; } - - xpt_setup_ccb(&ccb->ccb_h, path, 5/*priority (low)*/); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = ciss_cam_rescan_callback; - ccb->crcn.flags = CAM_FLAG_NONE; - xpt_action(ccb); - + xpt_rescan(ccb); /* scan is now in progress */ } -static void -ciss_cam_rescan_all(struct ciss_softc *sc) -{ - int i; - - /* Rescan the logical buses */ - for (i = 0; i < sc->ciss_max_logical_bus; i++) - ciss_cam_rescan_target(sc, i, CAM_TARGET_WILDCARD); - /* Rescan the physical buses */ - for (i = CISS_PHYSICAL_BASE; i < sc->ciss_max_physical_bus + - CISS_PHYSICAL_BASE; i++) - ciss_cam_rescan_target(sc, i, CAM_TARGET_WILDCARD); -} - -static void -ciss_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) -{ - xpt_free_path(ccb->ccb_h.path); - free(ccb, CISS_MALLOC_CLASS); -} - /************************************************************************ * Handle requests coming from CAM */ diff --git a/sys/dev/hptiop/hptiop.c b/sys/dev/hptiop/hptiop.c index 7218bc50442..1ea257becc3 100644 --- a/sys/dev/hptiop/hptiop.c +++ b/sys/dev/hptiop/hptiop.c @@ -79,7 +79,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -105,7 +104,6 @@ static int hptiop_do_ioctl_itl(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams); static int hptiop_do_ioctl_mv(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param *pParams); -static void hptiop_bus_scan_cb(struct cam_periph *periph, union ccb *ccb); static int hptiop_rescan_bus(struct hpt_iop_hba *hba); static int hptiop_alloc_pci_res_itl(struct hpt_iop_hba *hba); static int hptiop_alloc_pci_res_mv(struct hpt_iop_hba *hba); @@ -1035,26 +1033,17 @@ invalid: static int hptiop_rescan_bus(struct hpt_iop_hba * hba) { - struct cam_path *path; union ccb *ccb; - if (xpt_create_path(&path, xpt_periph, cam_sim_path(hba->sim), - CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) - return(EIO); - if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK)) == NULL) - return(ENOMEM); - bzero(ccb, sizeof(union ccb)); - xpt_setup_ccb(&ccb->ccb_h, path, 5); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = hptiop_bus_scan_cb; - ccb->crcn.flags = CAM_FLAG_NONE; - xpt_action(ccb); - return(0); -} -static void hptiop_bus_scan_cb(struct cam_periph *periph, union ccb *ccb) -{ - xpt_free_path(ccb->ccb_h.path); - free(ccb, M_TEMP); + if ((ccb = xpt_alloc_ccb()) == NULL) + return(ENOMEM); + if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(hba->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xpt_free_ccb(ccb); + return(EIO); + } + xpt_rescan(ccb); + return(0); } static bus_dmamap_callback_t hptiop_map_srb; @@ -1539,8 +1528,6 @@ static int hptiop_attach(device_t dev) hba->ioctl_dev->si_drv1 = hba; #endif - hptiop_rescan_bus(hba); - return 0; diff --git a/sys/dev/hptrr/hptrr_osm_bsd.c b/sys/dev/hptrr/hptrr_osm_bsd.c index 78c8b60fe2e..6bc30c22b36 100644 --- a/sys/dev/hptrr/hptrr_osm_bsd.c +++ b/sys/dev/hptrr/hptrr_osm_bsd.c @@ -989,7 +989,6 @@ static void hpt_stop_tasks(PVBUS_EXT vbus_ext) static d_open_t hpt_open; static d_close_t hpt_close; static d_ioctl_t hpt_ioctl; -static void hpt_bus_scan_cb(struct cam_periph *periph, union ccb *ccb); static int hpt_rescan_bus(void); static struct cdevsw hpt_cdevsw = { @@ -1381,7 +1380,6 @@ invalid: static int hpt_rescan_bus(void) { - struct cam_path *path; union ccb *ccb; PVBUS vbus; PVBUS_EXT vbus_ext; @@ -1391,17 +1389,15 @@ static int hpt_rescan_bus(void) #endif ldm_for_each_vbus(vbus, vbus_ext) { - if (xpt_create_path(&path, xpt_periph, cam_sim_path(vbus_ext->sim), - CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) - return(EIO); - if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK)) == NULL) + if ((ccb = xpt_alloc_ccb()) == NULL) return(ENOMEM); - bzero(ccb, sizeof(union ccb)); - xpt_setup_ccb(&ccb->ccb_h, path, 5); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = hpt_bus_scan_cb; - ccb->crcn.flags = CAM_FLAG_NONE; - xpt_action(ccb); + if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, + cam_sim_path(vbus_ext->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xpt_free_ccb(ccb); + return(EIO); + } + xpt_rescan(ccb); } #if (__FreeBSD_version >= 500000) @@ -1410,15 +1406,3 @@ static int hpt_rescan_bus(void) return(0); } - -static void hpt_bus_scan_cb(struct cam_periph *periph, union ccb *ccb) -{ - if (ccb->ccb_h.status != CAM_REQ_CMP) - KdPrint(("cam_scan_callback: failure status = %x",ccb->ccb_h.status)); - else - KdPrint(("Scan bus successfully!")); - - xpt_free_path(ccb->ccb_h.path); - free(ccb, M_TEMP); - return; -} diff --git a/sys/dev/hptrr/os_bsd.h b/sys/dev/hptrr/os_bsd.h index fb487e820b6..ec221f39b90 100644 --- a/sys/dev/hptrr/os_bsd.h +++ b/sys/dev/hptrr/os_bsd.h @@ -91,7 +91,6 @@ #include #include #include -#include #include #include #include diff --git a/sys/dev/mly/mly.c b/sys/dev/mly/mly.c index 0c013bce5d5..fc8402fec56 100644 --- a/sys/dev/mly/mly.c +++ b/sys/dev/mly/mly.c @@ -101,7 +101,6 @@ static void mly_unmap_command(struct mly_command *mc); static int mly_cam_attach(struct mly_softc *sc); static void mly_cam_detach(struct mly_softc *sc); static void mly_cam_rescan_btl(struct mly_softc *sc, int bus, int target); -static void mly_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb); static void mly_cam_action(struct cam_sim *sim, union ccb *ccb); static int mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio); static void mly_cam_poll(struct cam_sim *sim); @@ -2017,29 +2016,18 @@ mly_cam_rescan_btl(struct mly_softc *sc, int bus, int target) debug_called(1); - if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO)) == NULL) { + if ((ccb = xpt_alloc_ccb()) == NULL) { mly_printf(sc, "rescan failed (can't allocate CCB)\n"); return; } - - if (xpt_create_path(&sc->mly_cam_path, xpt_periph, - cam_sim_path(sc->mly_cam_sim[bus]), target, 0) != CAM_REQ_CMP) { + if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, + cam_sim_path(sc->mly_cam_sim[bus]), target, 0) != CAM_REQ_CMP) { mly_printf(sc, "rescan failed (can't create path)\n"); - free(ccb, M_TEMP); + xpt_free_ccb(ccb); return; } - xpt_setup_ccb(&ccb->ccb_h, sc->mly_cam_path, 5/*priority (low)*/); - ccb->ccb_h.func_code = XPT_SCAN_LUN; - ccb->ccb_h.cbfcnp = mly_cam_rescan_callback; - ccb->crcn.flags = CAM_FLAG_NONE; debug(1, "rescan target %d:%d", bus, target); - xpt_action(ccb); -} - -static void -mly_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) -{ - free(ccb, M_TEMP); + xpt_rescan(ccb); } /******************************************************************************** diff --git a/sys/dev/mpt/mpt_cam.h b/sys/dev/mpt/mpt_cam.h index f2faa4abdff..8a18934d648 100644 --- a/sys/dev/mpt/mpt_cam.h +++ b/sys/dev/mpt/mpt_cam.h @@ -102,7 +102,6 @@ #include #include #include -#include #include #include #include diff --git a/sys/dev/mpt/mpt_raid.c b/sys/dev/mpt/mpt_raid.c index c576a9eab9a..78c4c4927aa 100644 --- a/sys/dev/mpt/mpt_raid.c +++ b/sys/dev/mpt/mpt_raid.c @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #if __FreeBSD_version < 500000 @@ -655,14 +654,6 @@ mpt_terminate_raid_thread(struct mpt_softc *mpt) mpt_sleep(mpt, &mpt->raid_thread, PUSER, "thtrm", 0); } -static void -mpt_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) -{ - - xpt_free_path(ccb->ccb_h.path); - xpt_free_ccb(ccb); -} - static void mpt_raid_thread(void *arg) { @@ -715,13 +706,7 @@ mpt_raid_thread(void *arg) xpt_free_ccb(ccb); mpt_prt(mpt, "Unable to rescan RAID Bus!\n"); } else { - xpt_setup_ccb(&ccb->ccb_h, path, 5); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = mpt_cam_rescan_callback; - ccb->crcn.flags = CAM_FLAG_NONE; - MPTLOCK_2_CAMLOCK(mpt); - xpt_action(ccb); - CAMLOCK_2_MPTLOCK(mpt); + xpt_rescan(ccb); } } } diff --git a/sys/dev/ppbus/vpo.c b/sys/dev/ppbus/vpo.c index 673a7858d4d..02bc9b397b2 100644 --- a/sys/dev/ppbus/vpo.c +++ b/sys/dev/ppbus/vpo.c @@ -83,9 +83,6 @@ struct vpo_data { /* cam related functions */ static void vpo_action(struct cam_sim *sim, union ccb *ccb); static void vpo_poll(struct cam_sim *sim); -static void vpo_cam_rescan_callback(struct cam_periph *periph, - union ccb *ccb); -static void vpo_cam_rescan(struct vpo_data *vpo); static void vpo_identify(driver_t *driver, device_t parent) @@ -176,44 +173,10 @@ vpo_attach(device_t dev) return (ENXIO); } ppb_unlock(ppbus); - vpo_cam_rescan(vpo); /* have CAM rescan the bus */ return (0); } -static void -vpo_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) -{ - - free(ccb, M_TEMP); -} - -static void -vpo_cam_rescan(struct vpo_data *vpo) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - struct cam_path *path; - union ccb *ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO); - - ppb_lock(ppbus); - if (xpt_create_path(&path, xpt_periph, cam_sim_path(vpo->sim), 0, 0) - != CAM_REQ_CMP) { - /* A failure is benign as the user can do a manual rescan */ - ppb_unlock(ppbus); - free(ccb, M_TEMP); - return; - } - - xpt_setup_ccb(&ccb->ccb_h, path, 5/*priority (low)*/); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = vpo_cam_rescan_callback; - ccb->crcn.flags = CAM_FLAG_NONE; - xpt_action(ccb); - ppb_unlock(ppbus); - - /* The scan is in progress now. */ -} - /* * vpo_intr() */ diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index b8820d2af2b..91414ec60ba 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include /* local prototypes */ @@ -727,6 +726,8 @@ siis_phy_check_events(device_t dev) /* If we have a connection event, deal with it */ if (ch->pm_level == 0) { u_int32_t status = ATA_INL(ch->r_mem, SIIS_P_SSTS); + union ccb *ccb; + if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) { @@ -738,6 +739,15 @@ siis_phy_check_events(device_t dev) device_printf(dev, "DISCONNECT requested\n"); ch->devices = 0; } + if ((ccb = xpt_alloc_ccb_nowait()) == NULL) + return; + if (xpt_create_path(&ccb->ccb_h.path, NULL, + cam_sim_path(ch->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xpt_free_ccb(ccb); + return; + } + xpt_rescan(ccb); } } @@ -1012,6 +1022,13 @@ siis_execute_transaction(struct siis_slot *slot) if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) ctp->control |= htole16(SIIS_PRB_PACKET_WRITE); } + /* Special handling for Soft Reset command. */ + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && + (ccb->ataio.cmd.control & ATA_A_RESET)) { + /* Kick controller into sane state */ + siis_portinit(dev); + } /* Setup the FIS for this request */ if (!siis_setup_fis(dev, ctp, ccb, slot->slot)) { device_printf(ch->dev, "Setting up SATA FIS failed\n"); @@ -1090,10 +1107,11 @@ siis_timeout(struct siis_slot *slot) 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, - ATA_INL(ch->r_mem, SIIS_P_CMDERR), ATA_INL(ch->r_mem, SIIS_P_STS), - ATA_INL(ch->r_mem, SIIS_P_SERR)); + 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)); if (ch->toslots == 0) xpt_freeze_simq(ch->sim, 1); @@ -1378,8 +1396,6 @@ siis_devreset(device_t dev) return (EBUSY); } } - if (bootverbose) - device_printf(dev, "device reset time=%dms\n", timeout); return (0); } @@ -1399,8 +1415,6 @@ siis_wait_ready(device_t dev, int t) return (EBUSY); } } - if (bootverbose) - device_printf(dev, "ready wait time=%dms\n", timeout); return (0); } @@ -1411,6 +1425,7 @@ siis_reset(device_t dev) int i, retry = 0, sata_rev; uint32_t val; + xpt_freeze_simq(ch->sim, 1); if (bootverbose) device_printf(dev, "SIIS reset...\n"); if (!ch->readlog && !ch->recovery) @@ -1476,6 +1491,7 @@ retry: "SIIS reset done: phy reset found no device\n"); /* Tell the XPT about the event */ xpt_async(AC_BUS_RESET, ch->path, NULL); + xpt_release_simq(ch->sim, TRUE); return; } /* Wait for clearing busy status. */ @@ -1506,6 +1522,7 @@ retry: device_printf(dev, "SIIS reset done: devices=%08x\n", ch->devices); /* Tell the XPT about the event */ xpt_async(AC_BUS_RESET, ch->path, NULL); + xpt_release_simq(ch->sim, TRUE); } static int diff --git a/sys/dev/trm/trm.c b/sys/dev/trm/trm.c index 26ab35239e7..e7d5aad6d77 100644 --- a/sys/dev/trm/trm.c +++ b/sys/dev/trm/trm.c @@ -746,15 +746,6 @@ trm_action(struct cam_sim *psim, union ccb *pccb) pccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(pccb); break; - /* - * (Re)Scan the SCSI Bus - * Rescan the given bus, or bus/target/lun - */ - case XPT_SCAN_BUS: - TRM_DPRINTF(" XPT_SCAN_BUS \n"); - pccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(pccb); - break; /* * Get EDT entries matching the given pattern */ @@ -818,15 +809,6 @@ trm_action(struct cam_sim *psim, union ccb *pccb) pccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(pccb); break; - /* - * Scan Logical Unit - */ - case XPT_SCAN_LUN: - TRM_DPRINTF(" XPT_SCAN_LUN \n"); - pccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(pccb); - break; - /* * Get/Set transfer rate/width/disconnection/tag queueing * settings diff --git a/sys/dev/twa/tw_osl_cam.c b/sys/dev/twa/tw_osl_cam.c index b7a085f1978..1d22920f291 100644 --- a/sys/dev/twa/tw_osl_cam.c +++ b/sys/dev/twa/tw_osl_cam.c @@ -56,7 +56,6 @@ static TW_VOID twa_action(struct cam_sim *sim, union ccb *ccb); static TW_VOID twa_poll(struct cam_sim *sim); static TW_VOID twa_timeout(TW_VOID *arg); -static TW_VOID twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb); static TW_INT32 tw_osli_execute_scsi(struct tw_osli_req_context *req, union ccb *ccb); @@ -76,7 +75,6 @@ TW_INT32 tw_osli_cam_attach(struct twa_softc *sc) { struct cam_devq *devq; - TW_INT32 error; tw_osli_dbg_dprintf(3, sc, "entered"); @@ -149,23 +147,8 @@ tw_osli_cam_attach(struct twa_softc *sc) mtx_unlock(sc->sim_lock); return(ENXIO); } - - tw_osli_dbg_dprintf(3, sc, "Calling xpt_setup_ccb"); mtx_unlock(sc->sim_lock); - tw_osli_dbg_dprintf(3, sc, "Calling tw_osli_request_bus_scan"); - /* - * Request a bus scan, so that CAM gets to know of - * the logical units that we control. - */ - if ((error = tw_osli_request_bus_scan(sc))) - tw_osli_printf(sc, "error = %d", - TW_CL_SEVERITY_ERROR_STRING, - TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, - 0x2104, - "Bus scan request to CAM failed", - error); - tw_osli_dbg_dprintf(3, sc, "exiting"); return(0); } @@ -561,7 +544,6 @@ twa_timeout(TW_VOID *arg) TW_INT32 tw_osli_request_bus_scan(struct twa_softc *sc) { - struct cam_path *path; union ccb *ccb; tw_osli_dbg_dprintf(3, sc, "entering"); @@ -569,13 +551,12 @@ tw_osli_request_bus_scan(struct twa_softc *sc) /* If we get here before sc->sim is initialized, return an error. */ if (!(sc->sim)) return(ENXIO); - if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK)) == NULL) + if ((ccb = xpt_alloc_ccb()) == NULL) return(ENOMEM); - bzero(ccb, sizeof(union ccb)); mtx_lock(sc->sim_lock); - if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->sim), - CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - free(ccb, M_TEMP); + if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(sc->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xpt_free_ccb(ccb); mtx_unlock(sc->sim_lock); return(EIO); } @@ -586,43 +567,13 @@ tw_osli_request_bus_scan(struct twa_softc *sc) sc->state &= ~TW_OSLI_CTLR_STATE_SIMQ_FROZEN; } - xpt_setup_ccb(&ccb->ccb_h, path, 5); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = twa_bus_scan_cb; - ccb->crcn.flags = CAM_FLAG_NONE; - xpt_action(ccb); + xpt_rescan(ccb); mtx_unlock(sc->sim_lock); return(0); } -/* - * Function name: twa_bus_scan_cb - * Description: Callback from CAM on a bus scan request. - * - * Input: periph -- we don't use this - * ccb -- bus scan request ccb that we sent to CAM - * Output: None - * Return value: None - */ -static TW_VOID -twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb) -{ - tw_osli_dbg_printf(3, "entering"); - - if (ccb->ccb_h.status != CAM_REQ_CMP) - printf("cam_scan_callback: failure status = %x\n", - ccb->ccb_h.status); - else - tw_osli_dbg_printf(3, "success"); - - xpt_free_path(ccb->ccb_h.path); - free(ccb, M_TEMP); -} - - - /* * Function name: tw_osli_allow_new_requests * Description: Sets the appropriate status bits in a ccb such that, diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index 4e57d82a1fd..e41e55b7f90 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -469,8 +469,6 @@ static void umass_cbi_start_status(struct umass_softc *); static void umass_t_cbi_data_clear_stall_callback(struct usb_xfer *, uint8_t, uint8_t, usb_error_t); static int umass_cam_attach_sim(struct umass_softc *); -static void umass_cam_rescan_callback(struct cam_periph *, union ccb *); -static void umass_cam_rescan(struct umass_softc *); static void umass_cam_attach(struct umass_softc *); static void umass_cam_detach_sim(struct umass_softc *); static void umass_cam_action(struct cam_sim *, union ccb *); @@ -2144,68 +2142,6 @@ umass_cam_attach_sim(struct umass_softc *sc) return (0); } -static void -umass_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) -{ -#if USB_DEBUG - struct umass_softc *sc = NULL; - - if (ccb->ccb_h.status != CAM_REQ_CMP) { - DPRINTF(sc, UDMASS_SCSI, "%s:%d Rescan failed, 0x%04x\n", - periph->periph_name, periph->unit_number, - ccb->ccb_h.status); - } else { - DPRINTF(sc, UDMASS_SCSI, "%s%d: Rescan succeeded\n", - periph->periph_name, periph->unit_number); - } -#endif - - xpt_free_path(ccb->ccb_h.path); - free(ccb, M_USBDEV); -} - -static void -umass_cam_rescan(struct umass_softc *sc) -{ - struct cam_path *path; - union ccb *ccb; - - DPRINTF(sc, UDMASS_SCSI, "scbus%d: scanning for %d:%d:%d\n", - cam_sim_path(sc->sc_sim), - cam_sim_path(sc->sc_sim), - sc->sc_unit, CAM_LUN_WILDCARD); - - ccb = malloc(sizeof(*ccb), M_USBDEV, M_WAITOK | M_ZERO); - - if (ccb == NULL) { - return; - } -#if (__FreeBSD_version >= 700037) - mtx_lock(&sc->sc_mtx); -#endif - - if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->sc_sim), - CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) - != CAM_REQ_CMP) { -#if (__FreeBSD_version >= 700037) - mtx_unlock(&sc->sc_mtx); -#endif - free(ccb, M_USBDEV); - return; - } - xpt_setup_ccb(&ccb->ccb_h, path, 5 /* priority (low) */ ); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = &umass_cam_rescan_callback; - ccb->crcn.flags = CAM_FLAG_NONE; - xpt_action(ccb); - -#if (__FreeBSD_version >= 700037) - mtx_unlock(&sc->sc_mtx); -#endif - - /* The scan is in progress now. */ -} - static void umass_cam_attach(struct umass_softc *sc) { @@ -2216,19 +2152,6 @@ umass_cam_attach(struct umass_softc *sc) sc->sc_name, cam_sim_path(sc->sc_sim), sc->sc_unit, CAM_LUN_WILDCARD, cam_sim_path(sc->sc_sim)); - - if (!cold) { - /* - * Notify CAM of the new device after a short delay. Any - * failure is benign, as the user can still do it by hand - * (camcontrol rescan ). Only do this if we are not - * booting, because CAM does a scan after booting has - * completed, when interrupts have been enabled. - */ - - /* scan the new sim */ - umass_cam_rescan(sc); - } } /* umass_cam_detach From 929100472e98ebd8dd087e589443968eec0ec9db Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:44:48 +0000 Subject: [PATCH 1439/2592] MFC r203376, r203384: - Give ATA/SATA SIMs info about ATAPI packet size, supported by device. - Make ATA XPT to reject longer SCSI CDBs then supported by device, or any SCSI CDBs, if device doesn't support ATAPI. --- sbin/camcontrol/camcontrol.c | 16 ++++++++++++++-- sys/cam/ata/ata_xpt.c | 36 +++++++++++++++++++++++++++++++++++- sys/cam/cam_ccb.h | 4 ++++ sys/cam/cam_xpt.c | 8 ++++++-- sys/dev/ahci/ahci.c | 4 ++++ sys/dev/ahci/ahci.h | 1 + sys/dev/ata/ata-all.c | 15 ++++++++++++--- sys/dev/ata/ata-all.h | 1 + sys/dev/siis/siis.c | 4 ++++ sys/dev/siis/siis.h | 1 + 10 files changed, 82 insertions(+), 8 deletions(-) diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index c98d5c9428b..8a00f759f56 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -1010,8 +1010,10 @@ camxferrate(struct cam_device *device) printf(" ("); if (ata->valid & CTS_ATA_VALID_MODE) printf("%s, ", ata_mode2string(ata->mode)); + if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0) + printf("ATAPI %dbytes, ", ata->atapi); if (ata->valid & CTS_ATA_VALID_BYTECOUNT) - printf("PIO size %dbytes", ata->bytecount); + printf("PIO %dbytes", ata->bytecount); printf(")"); } else if (ccb->cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = @@ -1022,8 +1024,10 @@ camxferrate(struct cam_device *device) printf("SATA %d.x, ", sata->revision); if (sata->valid & CTS_SATA_VALID_MODE) printf("%s, ", ata_mode2string(sata->mode)); + if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0) + printf("ATAPI %dbytes, ", sata->atapi); if (sata->valid & CTS_SATA_VALID_BYTECOUNT) - printf("PIO size %dbytes", sata->bytecount); + printf("PIO %dbytes", sata->bytecount); printf(")"); } @@ -2800,6 +2804,10 @@ cts_print(struct cam_device *device, struct ccb_trans_settings *cts) fprintf(stdout, "%sATA mode: %s\n", pathstr, ata_mode2string(ata->mode)); } + if ((ata->valid & CTS_ATA_VALID_ATAPI) != 0) { + fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, + ata->atapi); + } if ((ata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) { fprintf(stdout, "%sPIO transaction length: %d\n", pathstr, ata->bytecount); @@ -2817,6 +2825,10 @@ cts_print(struct cam_device *device, struct ccb_trans_settings *cts) fprintf(stdout, "%sATA mode: %s\n", pathstr, ata_mode2string(sata->mode)); } + if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) { + fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, + sata->atapi); + } if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) { fprintf(stdout, "%sPIO transaction length: %d\n", pathstr, sata->bytecount); diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index bff0340b671..a9d0a87d31f 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -1334,7 +1334,20 @@ ata_device_transport(struct cam_path *path) cts.protocol = path->device->protocol; cts.protocol_version = path->device->protocol_version; cts.proto_specific.valid = 0; - cts.xport_specific.valid = 0; + if (ident_buf) { + if (path->device->transport == XPORT_ATA) { + cts.xport_specific.ata.atapi = + ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 : + ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0; + cts.xport_specific.ata.valid = CTS_ATA_VALID_ATAPI; + } else { + cts.xport_specific.sata.atapi = + ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 : + ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0; + cts.xport_specific.sata.valid = CTS_SATA_VALID_ATAPI; + } + } else + cts.xport_specific.valid = 0; xpt_action((union ccb *)&cts); } @@ -1366,6 +1379,27 @@ ata_action(union ccb *start_ccb) (*(sim->sim_action))(sim, start_ccb); break; } + case XPT_SCSI_IO: + { + struct cam_ed *device; + u_int maxlen = 0; + + device = start_ccb->ccb_h.path->device; + if (device->protocol == PROTO_SCSI && + (device->flags & CAM_DEV_IDENTIFY_DATA_VALID)) { + uint16_t p = + device->ident_data.config & ATA_PROTO_MASK; + + maxlen = (p == ATA_PROTO_ATAPI_16) ? 16 : + (p == ATA_PROTO_ATAPI_12) ? 12 : 0; + } + if (start_ccb->csio.cdb_len > maxlen) { + start_ccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(start_ccb); + break; + } + /* FALLTHROUGH */ + } default: xpt_action_default(start_ccb); break; diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 4c5adba5418..2810c545f71 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -823,8 +823,10 @@ struct ccb_trans_settings_ata { u_int valid; /* Which fields to honor */ #define CTS_ATA_VALID_MODE 0x01 #define CTS_ATA_VALID_BYTECOUNT 0x02 +#define CTS_ATA_VALID_ATAPI 0x20 int mode; /* Mode */ u_int bytecount; /* Length of PIO transaction */ + u_int atapi; /* Length of ATAPI CDB */ }; struct ccb_trans_settings_sata { @@ -834,11 +836,13 @@ struct ccb_trans_settings_sata { #define CTS_SATA_VALID_REVISION 0x04 #define CTS_SATA_VALID_PM 0x08 #define CTS_SATA_VALID_TAGS 0x10 +#define CTS_SATA_VALID_ATAPI 0x20 int mode; /* Legacy PATA mode */ u_int bytecount; /* Length of PIO transaction */ int revision; /* SATA revision */ u_int pm_present; /* PM is present (XPT->SIM) */ u_int tags; /* Number of allowed tags */ + u_int atapi; /* Length of ATAPI CDB */ }; /* Get/Set transfer rate/width/disconnection/tag queueing settings */ diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index d966a9fb5bd..3423df97376 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -1201,8 +1201,10 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string) printf(" ("); if (ata->valid & CTS_ATA_VALID_MODE) printf("%s, ", ata_mode2string(ata->mode)); + if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0) + printf("ATAPI %dbytes, ", ata->atapi); if (ata->valid & CTS_ATA_VALID_BYTECOUNT) - printf("PIO size %dbytes", ata->bytecount); + printf("PIO %dbytes", ata->bytecount); printf(")"); } if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) { @@ -1214,8 +1216,10 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string) printf("SATA %d.x, ", sata->revision); if (sata->valid & CTS_SATA_VALID_MODE) printf("%s, ", ata_mode2string(sata->mode)); + if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0) + printf("ATAPI %dbytes, ", sata->atapi); if (sata->valid & CTS_SATA_VALID_BYTECOUNT) - printf("PIO size %dbytes", sata->bytecount); + printf("PIO %dbytes", sata->bytecount); printf(")"); } if (path->device->inq_flags & SID_CmdQue diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index bb661ee20bb..2df516fe5bf 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -2213,6 +2213,8 @@ ahciaction(struct cam_sim *sim, union ccb *ccb) d->tags = min(ch->numslots, cts->xport_specific.sata.tags); if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) ch->pm_present = cts->xport_specific.sata.pm_present; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_ATAPI) + d->atapi = cts->xport_specific.sata.atapi; ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -2256,6 +2258,8 @@ ahciaction(struct cam_sim *sim, union ccb *ccb) cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; cts->xport_specific.sata.tags = d->tags; cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS; + cts->xport_specific.sata.atapi = d->atapi; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI; ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index d136d82b326..a436490d5c7 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -358,6 +358,7 @@ struct ahci_device { int revision; int mode; u_int bytecount; + u_int atapi; u_int tags; }; diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 1ad3c5117c1..6de8fda4e58 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -1348,6 +1348,8 @@ ata_cam_begin_transaction(device_t dev, union ccb *ccb) ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes, request->u.atapi.ccb, ccb->csio.cdb_len); request->flags |= ATA_R_ATAPI; + if (ch->curr[ccb->ccb_h.target_id].atapi == 16) + request->flags |= ATA_R_ATAPI16; if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) request->flags |= ATA_R_DMA; @@ -1358,7 +1360,6 @@ ata_cam_begin_transaction(device_t dev, union ccb *ccb) } request->transfersize = min(request->bytecount, ch->curr[ccb->ccb_h.target_id].bytecount); -// request->callback = ad_done; request->retries = 0; request->timeout = (ccb->ccb_h.timeout + 999) / 1000; callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED); @@ -1491,7 +1492,7 @@ ataaction(struct cam_sim *sim, union ccb *ccb) if (ch->flags & ATA_SATA) { if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION) d->revision = cts->xport_specific.sata.revision; - if (cts->xport_specific.ata.valid & CTS_SATA_VALID_MODE) { + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE) { if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { d->mode = ATA_SETMODE(ch->dev, ccb->ccb_h.target_id, @@ -1499,8 +1500,10 @@ ataaction(struct cam_sim *sim, union ccb *ccb) } else d->mode = cts->xport_specific.sata.mode; } - if (cts->xport_specific.ata.valid & CTS_SATA_VALID_BYTECOUNT) + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) d->bytecount = min(8192, cts->xport_specific.sata.bytecount); + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_ATAPI) + d->atapi = cts->xport_specific.sata.atapi; } else { if (cts->xport_specific.ata.valid & CTS_ATA_VALID_MODE) { if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { @@ -1512,6 +1515,8 @@ ataaction(struct cam_sim *sim, union ccb *ccb) } if (cts->xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) d->bytecount = cts->xport_specific.ata.bytecount; + if (cts->xport_specific.ata.valid & CTS_ATA_VALID_ATAPI) + d->atapi = cts->xport_specific.ata.atapi; } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); @@ -1541,6 +1546,8 @@ ataaction(struct cam_sim *sim, union ccb *ccb) } else cts->xport_specific.sata.revision = d->revision; cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; + cts->xport_specific.sata.atapi = d->atapi; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI; } else { cts->transport = XPORT_ATA; cts->transport_version = XPORT_VERSION_UNSPECIFIED; @@ -1548,6 +1555,8 @@ ataaction(struct cam_sim *sim, union ccb *ccb) cts->xport_specific.ata.valid |= CTS_ATA_VALID_MODE; cts->xport_specific.ata.bytecount = d->bytecount; cts->xport_specific.ata.valid |= CTS_ATA_VALID_BYTECOUNT; + cts->xport_specific.ata.atapi = d->atapi; + cts->xport_specific.ata.valid |= CTS_ATA_VALID_ATAPI; } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 23dc458c697..3d5d36e59f1 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -539,6 +539,7 @@ struct ata_cam_device { u_int revision; int mode; u_int bytecount; + u_int atapi; }; #endif diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 91414ec60ba..f6d83ec78b0 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -1671,6 +1671,8 @@ siisaction(struct cam_sim *sim, union ccb *ccb) else ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); } + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS) + d->atapi = cts->xport_specific.sata.atapi; ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -1714,6 +1716,8 @@ siisaction(struct cam_sim *sim, union ccb *ccb) cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; cts->xport_specific.sata.tags = d->tags; cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS; + cts->xport_specific.sata.atapi = d->atapi; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI; ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; diff --git a/sys/dev/siis/siis.h b/sys/dev/siis/siis.h index f98d204384b..92b4e26d13a 100644 --- a/sys/dev/siis/siis.h +++ b/sys/dev/siis/siis.h @@ -356,6 +356,7 @@ struct siis_device { int revision; int mode; u_int bytecount; + u_int atapi; u_int tags; }; From 31d3ea037e0b6faa2a790d0f8801bd38360ad211 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:46:54 +0000 Subject: [PATCH 1440/2592] MFC r203385: - Use separate buffer for identify data fetching. We can't use main buffer here if device already running, as data need to be formatted before use. - Remove some saved_ccb variables. They are unused now. --- sys/cam/ata/ata_da.c | 4 +--- sys/cam/ata/ata_pmp.c | 4 +--- sys/cam/ata/ata_xpt.c | 56 +++++++++++++------------------------------ 3 files changed, 19 insertions(+), 45 deletions(-) diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 3408b4fa3bb..6cb4f2e5509 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -123,7 +123,6 @@ struct ada_softc { int trim_running; struct disk_params params; struct disk *disk; - union ccb saved_ccb; struct task sysctl_task; struct sysctl_ctx_list sysctl_ctx; struct sysctl_oid *sysctl_tree; @@ -1098,8 +1097,7 @@ adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) periph = xpt_path_periph(ccb->ccb_h.path); softc = (struct ada_softc *)periph->softc; - return(cam_periph_error(ccb, cam_flags, sense_flags, - &softc->saved_ccb)); + return(cam_periph_error(ccb, cam_flags, sense_flags, NULL)); } static void diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c index 1b8d9d5129f..b60a4a7596b 100644 --- a/sys/cam/ata/ata_pmp.c +++ b/sys/cam/ata/ata_pmp.c @@ -101,7 +101,6 @@ struct pmp_softc { int events; #define PMP_EV_RESET 1 #define PMP_EV_RESCAN 2 - union ccb saved_ccb; struct task sysctl_task; struct sysctl_ctx_list sysctl_ctx; struct sysctl_oid *sysctl_tree; @@ -552,8 +551,7 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) 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) { + if (cam_periph_error(done_ccb, 0, 0, NULL) == ERESTART) { return; } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { cam_release_devq(done_ccb->ccb_h.path, diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index a9d0a87d31f..26fd85806dc 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -124,10 +123,9 @@ typedef enum { typedef struct { TAILQ_HEAD(, ccb_hdr) request_ccbs; + struct ata_params ident_data; probe_action action; - union ccb saved_ccb; probe_flags flags; - u_int8_t digest[16]; uint32_t pm_pid; uint32_t pm_prv; int restart; @@ -303,29 +301,13 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) ata_reset_cmd(ataio); break; case PROBE_IDENTIFY: - if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { - /* Prepare check that it is the same device. */ - MD5_CTX context; - - 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(softc->digest, &context); - } cam_fill_ataio(ataio, 1, probedone, /*flags*/CAM_DIR_IN, 0, - /*data_ptr*/(u_int8_t *)ident_buf, - /*dxfer_len*/sizeof(struct ata_params), + /*data_ptr*/(u_int8_t *)&softc->ident_data, + /*dxfer_len*/sizeof(softc->ident_data), 30 * 1000); if (periph->path->device->protocol == PROTO_ATA) ata_28bit_cmd(ataio, ATA_ATA_IDENTIFY, 0, 0, 0); @@ -695,8 +677,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb) ident_buf = &path->device->ident_data; 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) { +device_fail: if (cam_periph_error(done_ccb, 0, 0, NULL) == ERESTART) { return; } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge the queue */ @@ -724,6 +705,8 @@ device_fail: if (cam_periph_error(done_ccb, 0, 0, goto done; } noerror: + if (softc->restart) + goto done; switch (softc->action) { case PROBE_RESET: { @@ -766,6 +749,7 @@ noerror: { int16_t *ptr; + ident_buf = &softc->ident_data; for (ptr = (int16_t *)ident_buf; ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) { *ptr = le16toh(*ptr); @@ -784,28 +768,22 @@ noerror: 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)); + ident_buf = &path->device->ident_data; 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))) { + if (bcmp(softc->ident_data.model, ident_buf->model, + sizeof(ident_buf->model)) || + bcmp(softc->ident_data.revision, ident_buf->revision, + sizeof(ident_buf->revision)) || + bcmp(softc->ident_data.serial, ident_buf->serial, + sizeof(ident_buf->serial))) { /* Device changed. */ xpt_async(AC_LOST_DEVICE, path, NULL); - } + } else + bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); } else { + bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); /* Clean up from previous instance of this device */ if (path->device->serial_num != NULL) { free(path->device->serial_num, M_CAMXPT); From ea35d583e84fe3e972ce087854d6b5465d6b9b21 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:48:53 +0000 Subject: [PATCH 1441/2592] MFC r203386: Change the way in which fake async events generated. Do not use taskqueue for lock decoupling, as it causes unwanted races. --- sys/cam/cam_xpt.c | 84 ++++++++++++++--------------------------------- 1 file changed, 24 insertions(+), 60 deletions(-) diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 3423df97376..9e79d02e4e3 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -2392,9 +2392,7 @@ xptsetasyncfunc(struct cam_ed *device, void *arg) { struct cam_path path; struct ccb_getdev cgd; - struct async_node *cur_entry; - - cur_entry = (struct async_node *)arg; + struct ccb_setasync *csa = (struct ccb_setasync *)arg; /* * Don't report unconfigured devices (Wildcard devs, @@ -2413,7 +2411,7 @@ xptsetasyncfunc(struct cam_ed *device, void *arg) 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, + csa->callback(csa->callback_arg, AC_FOUND_DEVICE, &path, &cgd); xpt_release_path(&path); @@ -2426,9 +2424,7 @@ xptsetasyncbusfunc(struct cam_eb *bus, void *arg) { struct cam_path path; struct ccb_pathinq cpi; - struct async_node *cur_entry; - - cur_entry = (struct async_node *)arg; + struct ccb_setasync *csa = (struct ccb_setasync *)arg; xpt_compile_path(&path, /*periph*/NULL, bus->sim->path_id, @@ -2437,7 +2433,7 @@ xptsetasyncbusfunc(struct cam_eb *bus, void *arg) 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, + csa->callback(csa->callback_arg, AC_PATH_REGISTERED, &path, &cpi); xpt_release_path(&path); @@ -2445,35 +2441,6 @@ xptsetasyncbusfunc(struct cam_eb *bus, void *arg) return(1); } -static void -xpt_action_sasync_cb(void *context, int pending) -{ - struct async_node *cur_entry; - struct xpt_task *task; - uint32_t added; - - task = (struct xpt_task *)context; - cur_entry = (struct async_node *)task->data1; - added = task->data2; - - if ((added & AC_FOUND_DEVICE) != 0) { - /* - * Get this peripheral up to date with all - * the currently existing devices. - */ - xpt_for_all_devices(xptsetasyncfunc, cur_entry); - } - if ((added & AC_PATH_REGISTERED) != 0) { - /* - * Get this peripheral up to date with all - * the currently existing busses. - */ - xpt_for_all_busses(xptsetasyncbusfunc, cur_entry); - } - - free(task, M_CAMXPT); -} - void xpt_action(union ccb *start_ccb) { @@ -2885,11 +2852,12 @@ xpt_action_default(union ccb *start_ccb) if (csa->event_enable == 0) { SLIST_REMOVE(async_head, cur_entry, async_node, links); - csa->ccb_h.path->device->refcount--; + xpt_release_device(csa->ccb_h.path->device); free(cur_entry, M_CAMXPT); } else { cur_entry->event_enable = csa->event_enable; } + csa->event_enable = added; } else { cur_entry = malloc(sizeof(*cur_entry), M_CAMXPT, M_NOWAIT); @@ -2901,29 +2869,8 @@ xpt_action_default(union ccb *start_ccb) cur_entry->callback_arg = csa->callback_arg; cur_entry->callback = csa->callback; SLIST_INSERT_HEAD(async_head, cur_entry, links); - csa->ccb_h.path->device->refcount++; + xpt_acquire_device(csa->ccb_h.path->device); } - - /* - * Need to decouple this operation via a taqskqueue so that - * the locking doesn't become a mess. - */ - if ((added & (AC_FOUND_DEVICE | AC_PATH_REGISTERED)) != 0) { - struct xpt_task *task; - - task = malloc(sizeof(struct xpt_task), M_CAMXPT, - M_NOWAIT); - if (task == NULL) { - csa->ccb_h.status = CAM_RESRC_UNAVAIL; - break; - } - - TASK_INIT(&task->task, 0, xpt_action_sasync_cb, task); - task->data1 = cur_entry; - task->data2 = added; - taskqueue_enqueue(taskqueue_thread, &task->task); - } - start_ccb->ccb_h.status = CAM_REQ_CMP; break; } @@ -4823,6 +4770,23 @@ xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg, if (xptpath) { xpt_free_path(path); mtx_unlock(&xsoftc.xpt_lock); + + if ((status == CAM_REQ_CMP) && + (csa.event_enable & AC_FOUND_DEVICE)) { + /* + * Get this peripheral up to date with all + * the currently existing devices. + */ + xpt_for_all_devices(xptsetasyncfunc, &csa); + } + if ((status == CAM_REQ_CMP) && + (csa.event_enable & AC_PATH_REGISTERED)) { + /* + * Get this peripheral up to date with all + * the currently existing busses. + */ + xpt_for_all_busses(xptsetasyncbusfunc, &csa); + } } return (status); } From 902a54900a24542224d87ddb3e5d849f68633bd5 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:50:33 +0000 Subject: [PATCH 1442/2592] MFC r203421: Add Power Up In Stand-by feature support. Device with PUIS enabled require explicit command to do initial spin-up. Mark that command with CAM_HIGH_POWER flag, to allow CAM manage staggered spin-up. --- sys/cam/ata/ata_all.c | 3 +++ sys/cam/ata/ata_xpt.c | 38 ++++++++++++++++++++++++++++++++++++-- sys/sys/ata.h | 4 ++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index b2db7a03ce1..2271747dda0 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -146,6 +146,9 @@ ata_op_string(struct ata_cmd *cmd) case 0x03: return ("SETFEATURES SET TRANSFER MODE"); case 0x02: return ("SETFEATURES ENABLE WCACHE"); case 0x82: return ("SETFEATURES DISABLE WCACHE"); + case 0x06: return ("SETFEATURES ENABLE PUIS"); + case 0x86: return ("SETFEATURES DISABLE PUIS"); + case 0x07: return ("SETFEATURES SPIN-UP"); case 0xaa: return ("SETFEATURES ENABLE RCACHE"); case 0x55: return ("SETFEATURES DISABLE RCACHE"); } diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 26fd85806dc..bbd34bd9c95 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -86,6 +86,7 @@ PERIPHDRIVER_DECLARE(aprobe, probe_driver); typedef enum { PROBE_RESET, PROBE_IDENTIFY, + PROBE_SPINUP, PROBE_SETMODE, PROBE_SET_MULTI, PROBE_INQUIRY, @@ -98,6 +99,7 @@ typedef enum { static char *probe_action_text[] = { "PROBE_RESET", "PROBE_IDENTIFY", + "PROBE_SPINUP", "PROBE_SETMODE", "PROBE_SET_MULTI", "PROBE_INQUIRY", @@ -129,6 +131,7 @@ typedef struct { uint32_t pm_pid; uint32_t pm_prv; int restart; + int spinup; struct cam_periph *periph; } probe_softc; @@ -212,7 +215,7 @@ proberegister(struct cam_periph *periph, void *arg) return(CAM_REQ_CMP_ERR); } - softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_NOWAIT); + softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_ZERO | M_NOWAIT); if (softc == NULL) { printf("proberegister: Unable to probe new device. " @@ -314,6 +317,19 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) else ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0); break; + case PROBE_SPINUP: + if (bootverbose) + xpt_print(path, "Spinning up device\n"); + cam_fill_ataio(ataio, + 1, + probedone, + /*flags*/CAM_DIR_NONE | CAM_HIGH_POWER, + 0, + /*data_ptr*/NULL, + /*dxfer_len*/0, + 30 * 1000); + ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_PUIS_SPINUP, 0, 0); + break; case PROBE_SETMODE: { int mode, wantmode; @@ -768,8 +784,18 @@ noerror: 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)); + /* Device may need spin-up before IDENTIFY become valid. */ + if ((ident_buf->config & ATA_RESP_INCOMPLETE) || + ((ident_buf->support.command2 & ATA_SUPPORT_STANDBY) && + (ident_buf->enabled.command2 & ATA_SUPPORT_STANDBY) && + (ident_buf->support.command2 & ATA_SUPPORT_SPINUP) && + softc->spinup == 0)) { + PROBE_SET_ACTION(softc, PROBE_SPINUP); + xpt_release_ccb(done_ccb); + xpt_schedule(periph, priority); + return; + } ident_buf = &path->device->ident_data; - if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { /* Check that it is the same device. */ if (bcmp(softc->ident_data.model, ident_buf->model, @@ -829,6 +855,14 @@ noerror: xpt_schedule(periph, priority); return; } + case PROBE_SPINUP: + if (bootverbose) + xpt_print(path, "Spin-up done\n"); + softc->spinup = 1; + PROBE_SET_ACTION(softc, PROBE_IDENTIFY); + xpt_release_ccb(done_ccb); + xpt_schedule(periph, priority); + return; case PROBE_SETMODE: if (path->device->protocol == PROTO_ATA) { PROBE_SET_ACTION(softc, PROBE_SET_MULTI); diff --git a/sys/sys/ata.h b/sys/sys/ata.h index fab5e387ab2..e8a04dbbbfd 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -48,6 +48,7 @@ struct ata_params { #define ATA_DRQ_SLOW 0x0000 /* cpu 3 ms delay */ #define ATA_DRQ_INTR 0x0020 /* interrupt 10 ms delay */ #define ATA_DRQ_FAST 0x0040 /* accel 50 us delay */ +#define ATA_RESP_INCOMPLETE 0x0004 /*001*/ u_int16_t cylinders; /* # of cylinders */ u_int16_t reserved2; @@ -345,6 +346,9 @@ struct ata_params { #define ATA_SF_SETXFER 0x03 /* set transfer mode */ #define ATA_SF_ENAB_WCACHE 0x02 /* enable write cache */ #define ATA_SF_DIS_WCACHE 0x82 /* disable write cache */ +#define ATA_SF_ENAB_PUIS 0x06 /* enable PUIS */ +#define ATA_SF_DIS_PUIS 0x86 /* disable PUIS */ +#define ATA_SF_PUIS_SPINUP 0x07 /* PUIS spin-up */ #define ATA_SF_ENAB_RCACHE 0xaa /* enable readahead cache */ #define ATA_SF_DIS_RCACHE 0x55 /* disable readahead cache */ #define ATA_SF_ENAB_RELIRQ 0x5d /* enable release interrupt */ From cf8a9069cde47173351113d8513500817580d514 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:51:39 +0000 Subject: [PATCH 1443/2592] MFC r203499: On probe error, if restart requested, skip any retries and recovery. Just restart probe from the beginning immediately. --- sys/cam/ata/ata_xpt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index bbd34bd9c95..92ba0271c87 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -693,7 +693,8 @@ probedone(struct cam_periph *periph, union ccb *done_ccb) ident_buf = &path->device->ident_data; if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { -device_fail: if (cam_periph_error(done_ccb, 0, 0, NULL) == ERESTART) { +device_fail: if ((!softc->restart) && + cam_periph_error(done_ccb, 0, 0, NULL) == ERESTART) { return; } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge the queue */ From d2846ca8004dc34ddb68f8332b9f90cff2fb2e99 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:53:09 +0000 Subject: [PATCH 1444/2592] MFC r203445: Report to CAM unit number of underlying ataX bus device, instead of this atapicamX. It is more apropriate and useful together with "ata" name. --- sys/dev/ata/atapi-cam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c index 3f8e650708c..2ed54e71b51 100644 --- a/sys/dev/ata/atapi-cam.c +++ b/sys/dev/ata/atapi-cam.c @@ -201,7 +201,7 @@ atapi_cam_attach(device_t dev) scp->parent = device_get_parent(dev); scp->ata_ch = device_get_softc(scp->parent); TAILQ_INIT(&scp->pending_hcbs); - unit = device_get_unit(dev); + unit = device_get_unit(device_get_parent(dev)); if ((devq = cam_simq_alloc(16)) == NULL) { error = ENOMEM; From dd96528dec8a03f4e139d3a6b796c8cde9614e28 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:54:16 +0000 Subject: [PATCH 1445/2592] MFC r203525: Report SATA300 chips also as SATA. --- sys/dev/ata/chipsets/ata-siliconimage.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c index 85b0830c02c..081bee5b9a3 100644 --- a/sys/dev/ata/chipsets/ata-siliconimage.c +++ b/sys/dev/ata/chipsets/ata-siliconimage.c @@ -471,7 +471,8 @@ ata_siiprb_ch_attach(device_t dev) ch->hw.softreset = ata_siiprb_softreset; ch->hw.pm_read = ata_siiprb_pm_read; ch->hw.pm_write = ata_siiprb_pm_write; - + ch->flags |= ATA_NO_SLAVE; + ch->flags |= ATA_SATA; return 0; } From 34cbb135e7af9e4d29e3ef7f852c773fa7600db3 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:55:41 +0000 Subject: [PATCH 1446/2592] MFC r203347: NetCell is a PCI hardware RAID without cable and mode setting. --- sys/dev/ata/chipsets/ata-netcell.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/dev/ata/chipsets/ata-netcell.c b/sys/dev/ata/chipsets/ata-netcell.c index f6a75451cea..8e5a9cbe8d2 100644 --- a/sys/dev/ata/chipsets/ata-netcell.c +++ b/sys/dev/ata/chipsets/ata-netcell.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); /* local prototypes */ static int ata_netcell_chipinit(device_t dev); static int ata_netcell_ch_attach(device_t dev); +static int ata_netcell_setmode(device_t dev, int target, int mode); /* * NetCell chipset support functions @@ -80,7 +81,7 @@ ata_netcell_chipinit(device_t dev) return ENXIO; ctlr->ch_attach = ata_netcell_ch_attach; - ctlr->setmode = ata_generic_setmode; + ctlr->setmode = ata_netcell_setmode; return 0; } @@ -95,7 +96,16 @@ ata_netcell_ch_attach(device_t dev) /* the NetCell only supports 16 bit PIO transfers */ ch->flags |= ATA_USE_16BIT; + /* It is a hardware RAID without cable. */ + ch->flags |= ATA_CHECKS_CABLE; return 0; } +static int +ata_netcell_setmode(device_t dev, int target, int mode) +{ + + return (min(mode, ATA_UDMA6)); +} + ATA_DECLARE_DRIVER(ata_netcell); From ee22e37df515e67db786dd26a1a00c26acbcafed Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:56:42 +0000 Subject: [PATCH 1447/2592] MFC r203449: Implement poll method for atapicam. It is not perfect, but better then nothing. --- sys/dev/ata/atapi-cam.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c index 2ed54e71b51..e5b002a89ac 100644 --- a/sys/dev/ata/atapi-cam.c +++ b/sys/dev/ata/atapi-cam.c @@ -682,8 +682,12 @@ action_invalid: static void atapi_poll(struct cam_sim *sim) { - /* do nothing - we do not actually service any interrupts */ - printf("atapi_poll called!\n"); + struct atapi_xpt_softc *softc = + (struct atapi_xpt_softc*)cam_sim_softc(sim); + + mtx_unlock(&softc->state_lock); + ata_interrupt(softc->ata_ch); + mtx_lock(&softc->state_lock); } static void From 0129e5cf7af66624474e69a38ef42c3454c5c788 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:57:54 +0000 Subject: [PATCH 1448/2592] MFC r203123: Add FIS-based switching support. If controller supports FBS, it allows several devices beyond Port Multiplier to work simultaneously, substantially increasing performance. --- sys/dev/ahci/ahci.c | 245 ++++++++++++++++++++++++++++++++++---------- sys/dev/ahci/ahci.h | 20 +++- 2 files changed, 212 insertions(+), 53 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 2df516fe5bf..6ca0c663a42 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -78,7 +78,7 @@ static void ahci_dmafini(device_t dev); static void ahci_slotsalloc(device_t dev); static void ahci_slotsfree(device_t dev); static void ahci_reset(device_t dev); -static void ahci_start(device_t dev); +static void ahci_start(device_t dev, int fbs); static void ahci_stop(device_t dev); static void ahci_clo(device_t dev); static void ahci_start_fr(device_t dev); @@ -86,6 +86,7 @@ static void ahci_stop_fr(device_t dev); static int ahci_sata_connect(struct ahci_channel *ch); static int ahci_sata_phy_reset(device_t dev); +static int ahci_wait_ready(device_t dev, int t); static void ahci_issue_read_log(device_t dev); static void ahci_process_read_log(device_t dev, union ccb *ccb); @@ -108,6 +109,7 @@ static struct { #define AHCI_Q_4CH 32 #define AHCI_Q_EDGEIS 64 #define AHCI_Q_SATA2 128 +#define AHCI_Q_NOBSYRES 256 } ahci_ids[] = { {0x43801002, 0x00, "ATI IXP600", 0}, {0x43901002, 0x00, "ATI IXP700", 0}, @@ -162,8 +164,8 @@ static struct { {0x612111ab, 0x00, "Marvell 88SX6121", AHCI_Q_NOFORCE|AHCI_Q_2CH|AHCI_Q_EDGEIS}, {0x614111ab, 0x00, "Marvell 88SX6141", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS}, {0x614511ab, 0x00, "Marvell 88SX6145", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS}, - {0x91231b4b, 0x11, "Marvell 88SE912x", 0}, - {0x91231b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_SATA2}, + {0x91231b4b, 0x11, "Marvell 88SE912x", AHCI_Q_NOBSYRES}, + {0x91231b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_SATA2|AHCI_Q_NOBSYRES}, {0x044c10de, 0x00, "NVIDIA MCP65", 0}, {0x044d10de, 0x00, "NVIDIA MCP65", 0}, {0x044e10de, 0x00, "NVIDIA MCP65", 0}, @@ -379,14 +381,16 @@ ahci_attach(device_t dev) /* Announce HW capabilities. */ speed = (ctlr->caps & AHCI_CAP_ISS) >> AHCI_CAP_ISS_SHIFT; device_printf(dev, - "AHCI v%x.%02x with %d %sGbps ports, Port Multiplier %s\n", + "AHCI v%x.%02x with %d %sGbps ports, Port Multiplier %s%s\n", ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f), ((version >> 4) & 0xf0) + (version & 0x0f), (ctlr->caps & AHCI_CAP_NPMASK) + 1, ((speed == 1) ? "1.5":((speed == 2) ? "3": ((speed == 3) ? "6":"?"))), (ctlr->caps & AHCI_CAP_SPM) ? - "supported" : "not supported"); + "supported" : "not supported", + (ctlr->caps & AHCI_CAP_FBSS) ? + " with FBS" : ""); if (bootverbose) { device_printf(dev, "Caps:%s%s%s%s%s%s%s%s %sGbps", (ctlr->caps & AHCI_CAP_64BIT) ? " 64bit":"", @@ -419,7 +423,7 @@ ahci_attach(device_t dev) (ctlr->caps2 & AHCI_CAP2_BOH) ? " BOH":""); } if (bootverbose && (ctlr->caps & AHCI_CAP_EMS)) { - device_printf(dev, "EM Caps: %s%s%s%s%s%s%s%s\n", + device_printf(dev, "EM Caps:%s%s%s%s%s%s%s%s\n", (ctlr->capsem & AHCI_EM_PM) ? " PM":"", (ctlr->capsem & AHCI_EM_ALHD) ? " ALHD":"", (ctlr->capsem & AHCI_EM_XMT) ? " XMT":"", @@ -804,6 +808,7 @@ ahci_ch_attach(device_t dev) struct ahci_channel *ch = device_get_softc(dev); struct cam_devq *devq; int rid, error, i, sata_rev = 0; + u_int32_t version; ch->dev = dev; ch->unit = (intptr_t)device_get_ivars(dev); @@ -855,6 +860,18 @@ ahci_ch_attach(device_t dev) error = ENXIO; goto err1; } + ch->chcaps = ATA_INL(ch->r_mem, AHCI_P_CMD); + version = ATA_INL(ctlr->r_mem, AHCI_VS); + if (version < 0x00010020 && (ctlr->caps & AHCI_CAP_FBSS)) + ch->chcaps |= AHCI_P_CMD_FBSCP; + if (bootverbose) { + device_printf(dev, "Caps:%s%s%s%s%s\n", + (ch->chcaps & AHCI_P_CMD_HPCP) ? " HPCP":"", + (ch->chcaps & AHCI_P_CMD_MPSP) ? " MPSP":"", + (ch->chcaps & AHCI_P_CMD_CPD) ? " CPD":"", + (ch->chcaps & AHCI_P_CMD_ESP) ? " ESP":"", + (ch->chcaps & AHCI_P_CMD_FBSCP) ? " FBSCP":""); + } /* Create the device queue for our SIM. */ devq = cam_simq_alloc(ch->numslots); if (devq == NULL) { @@ -971,7 +988,7 @@ ahci_ch_resume(device_t dev) ((ch->pm_level == 2 || ch->pm_level == 3) ? AHCI_P_CMD_ALPE : 0) | ((ch->pm_level > 2) ? AHCI_P_CMD_ASP : 0 ))); ahci_start_fr(dev); - ahci_start(dev); + ahci_start(dev, 1); return (0); } @@ -1001,6 +1018,7 @@ ahci_dmainit(device_t dev) { struct ahci_channel *ch = device_get_softc(dev); struct ahci_dc_cb_args dcba; + size_t rfsize; if (ch->caps & AHCI_CAP_64BIT) ch->dma.max_address = BUS_SPACE_MAXADDR; @@ -1022,16 +1040,20 @@ ahci_dmainit(device_t dev) } ch->dma.work_bus = dcba.maddr; /* FIS receive area. */ - if (bus_dma_tag_create(bus_get_dma_tag(dev), 4096, 0, + if (ch->chcaps & AHCI_P_CMD_FBSCP) + rfsize = 4096; + else + rfsize = 256; + if (bus_dma_tag_create(bus_get_dma_tag(dev), rfsize, 0, ch->dma.max_address, BUS_SPACE_MAXADDR, - NULL, NULL, 4096, 1, 4096, + NULL, NULL, rfsize, 1, rfsize, 0, NULL, NULL, &ch->dma.rfis_tag)) goto error; if (bus_dmamem_alloc(ch->dma.rfis_tag, (void **)&ch->dma.rfis, 0, &ch->dma.rfis_map)) goto error; if (bus_dmamap_load(ch->dma.rfis_tag, ch->dma.rfis_map, ch->dma.rfis, - 4096, ahci_dmasetupc_cb, &dcba, 0) || dcba.error) { + rfsize, ahci_dmasetupc_cb, &dcba, 0) || dcba.error) { bus_dmamem_free(ch->dma.rfis_tag, ch->dma.rfis, ch->dma.rfis_map); goto error; } @@ -1219,7 +1241,7 @@ ahci_ch_intr(void *data) struct ahci_channel *ch = device_get_softc(dev); uint32_t istatus, sstatus, cstatus, serr = 0, sntf = 0, ok, err; enum ahci_err_type et; - int i, ccs, ncq_err = 0; + int i, ccs, port; /* Read and clear interrupt statuses. */ istatus = ATA_INL(ch->r_mem, AHCI_P_IS); @@ -1232,7 +1254,17 @@ ahci_ch_intr(void *data) if (istatus & AHCI_P_IX_SDB) { if (ch->caps & AHCI_CAP_SSNTF) sntf = ATA_INL(ch->r_mem, AHCI_P_SNTF); - else { + else if (ch->fbs_enabled) { + u_int8_t *fis = ch->dma.rfis + 0x58; + + for (i = 0; i < 16; i++) { + if (fis[1] & 0x80) { + fis[1] &= 0x7f; + sntf |= 1 << i; + } + fis += 256; + } + } else { u_int8_t *fis = ch->dma.rfis + 0x58; if (fis[1] & 0x80) @@ -1251,18 +1283,35 @@ ahci_ch_intr(void *data) /* Process command errors */ 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), -// serr); ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT; +//device_printf(dev, "%s ERROR is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x fbs %08x ccs %d\n", +// __func__, istatus, cstatus, sstatus, ch->rslots, ATA_INL(ch->r_mem, AHCI_P_TFD), +// serr, ATA_INL(ch->r_mem, AHCI_P_FBS), ccs); + port = -1; + if (ch->fbs_enabled) { + uint32_t fbs = ATA_INL(ch->r_mem, AHCI_P_FBS); + if (fbs & AHCI_P_FBS_SDE) { + port = (fbs & AHCI_P_FBS_DWE) + >> AHCI_P_FBS_DWE_SHIFT; + } else { + for (i = 0; i < 16; i++) { + if (ch->numrslotspd[i] == 0) + continue; + if (port == -1) + port = i; + else if (port != i) { + port = -2; + break; + } + } + } + } err = ch->rslots & (cstatus | sstatus); - /* Kick controller into sane state */ - ahci_stop(dev); - ahci_start(dev); } else { ccs = 0; err = 0; + port = -1; } /* Complete all successfull commands. */ ok = ch->rslots & ~(cstatus | sstatus); @@ -1286,9 +1335,14 @@ ahci_ch_intr(void *data) /* XXX: reqests in loading state. */ if (((err >> i) & 1) == 0) continue; + if (port >= 0 && + ch->slot[i].ccb->ccb_h.target_id != port) + continue; if (istatus & AHCI_P_IX_TFE) { + if (port != -2) { /* Task File Error */ - if (ch->numtslots == 0) { + if (ch->numtslotspd[ + ch->slot[i].ccb->ccb_h.target_id] == 0) { /* Untagged operation. */ if (i == ccs) et = AHCI_ERR_TFE; @@ -1297,10 +1351,13 @@ ahci_ch_intr(void *data) } else { /* Tagged operation. */ et = AHCI_ERR_NCQ; - ncq_err = 1; } + } else { + et = AHCI_ERR_TFE; + ch->fatalerr = 1; + } } else if (istatus & AHCI_P_IX_IF) { - if (ch->numtslots == 0 && i != ccs) + if (ch->numtslots == 0 && i != ccs && port != -2) et = AHCI_ERR_INNOCENT; else et = AHCI_ERR_SATA; @@ -1308,8 +1365,12 @@ ahci_ch_intr(void *data) et = AHCI_ERR_INVALID; ahci_end_transaction(&ch->slot[i], et); } - if (ncq_err) - ahci_issue_read_log(dev); + /* + * We can't reinit port if there are some other + * commands active, use resume to complete them. + */ + if (ch->rslots != 0) + ATA_OUTL(ch->r_mem, AHCI_P_FBS, AHCI_P_FBS_EN | AHCI_P_FBS_DEC); } /* Process NOTIFY events */ if (sntf) @@ -1321,24 +1382,39 @@ static int ahci_check_collision(device_t dev, union ccb *ccb) { struct ahci_channel *ch = device_get_softc(dev); + int t = ccb->ccb_h.target_id; if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { - /* Tagged command while untagged are active. */ - if (ch->numrslots != 0 && ch->numtslots == 0) - return (1); - /* Tagged command while tagged to other target is active. */ - if (ch->numtslots != 0 && - ch->taggedtarget != ccb->ccb_h.target_id) - return (1); /* Tagged command while we have no supported tag free. */ if (((~ch->oslots) & (0xffffffff >> (32 - - ch->curr[ccb->ccb_h.target_id].tags))) == 0) + ch->curr[t].tags))) == 0) return (1); + /* If we have FBS */ + if (ch->fbs_enabled) { + /* Tagged command while untagged are active. */ + if (ch->numrslotspd[t] != 0 && ch->numtslotspd[t] == 0) + return (1); + } else { + /* Tagged command while untagged are active. */ + if (ch->numrslots != 0 && ch->numtslots == 0) + return (1); + /* Tagged command while tagged to other target is active. */ + if (ch->numtslots != 0 && + ch->taggedtarget != ccb->ccb_h.target_id) + return (1); + } } else { - /* Untagged command while tagged are active. */ - if (ch->numrslots != 0 && ch->numtslots != 0) - return (1); + /* If we have FBS */ + if (ch->fbs_enabled) { + /* Untagged command while tagged are active. */ + if (ch->numrslotspd[t] != 0 && ch->numtslotspd[t] != 0) + return (1); + } else { + /* Untagged command while tagged are active. */ + if (ch->numrslots != 0 && ch->numtslots != 0) + return (1); + } } if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) { @@ -1383,9 +1459,11 @@ ahci_begin_transaction(device_t dev, union ccb *ccb) /* Update channel stats. */ ch->oslots |= (1 << slot->slot); ch->numrslots++; + ch->numrslotspd[ccb->ccb_h.target_id]++; if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { ch->numtslots++; + ch->numtslotspd[ccb->ccb_h.target_id]++; ch->taggedtarget = ccb->ccb_h.target_id; } if ((ccb->ccb_h.func_code == XPT_ATA_IO) && @@ -1453,7 +1531,9 @@ ahci_execute_transaction(struct ahci_slot *slot) struct ahci_cmd_list *clp; union ccb *ccb = slot->ccb; int port = ccb->ccb_h.target_id & 0x0f; - int fis_size; + int fis_size, i; + uint8_t *fis = ch->dma.rfis + 0x40; + uint8_t val; /* Get a piece of the workspace for this request */ ctp = (struct ahci_cmd_tab *) @@ -1475,13 +1555,18 @@ ahci_execute_transaction(struct ahci_slot *slot) (port << 12); /* Special handling for Soft Reset command. */ if ((ccb->ccb_h.func_code == XPT_ATA_IO) && - (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && - (ccb->ataio.cmd.control & ATA_A_RESET)) { - /* Kick controller into sane state */ - ahci_stop(dev); - ahci_clo(dev); - ahci_start(dev); - clp->cmd_flags |= AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY; + (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) { + if (ccb->ataio.cmd.control & ATA_A_RESET) { + /* Kick controller into sane state */ + ahci_stop(dev); + ahci_clo(dev); + ahci_start(dev, 0); + clp->cmd_flags |= AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY; + } else { + /* Prepare FIS receive area for check. */ + for (i = 0; i < 20; i++) + fis[i] = 0xff; + } } clp->bytecount = 0; clp->cmd_table_phys = htole64(ch->dma.work_bus + AHCI_CT_OFFSET + @@ -1495,6 +1580,11 @@ ahci_execute_transaction(struct ahci_slot *slot) (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { ATA_OUTL(ch->r_mem, AHCI_P_SACT, 1 << slot->slot); } + /* If FBS is enabled, set PMP port. */ + if (ch->fbs_enabled) { + ATA_OUTL(ch->r_mem, AHCI_P_FBS, AHCI_P_FBS_EN | + (port << AHCI_P_FBS_DEV_SHIFT)); + } /* Issue command to the controller. */ slot->state = AHCI_SLOT_RUNNING; ch->rslots |= (1 << slot->slot); @@ -1537,12 +1627,30 @@ ahci_execute_transaction(struct ahci_slot *slot) ATA_INL(ch->r_mem, AHCI_P_SERR)); et = AHCI_ERR_TIMEOUT; } - if (et != AHCI_ERR_NONE) { - /* Kick controller into sane state */ - ahci_stop(ch->dev); - ahci_start(ch->dev); + /* Marvell controllers do not wait for readyness. */ + if ((ch->quirks & AHCI_Q_NOBSYRES) && + (ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && + (ccb->ataio.cmd.control & ATA_A_RESET) == 0) { + while ((val = fis[2]) & (ATA_S_BUSY | ATA_S_DRQ)) { + DELAY(1000); + if (count++ >= timeout) { + device_printf(dev, "device is not " + "ready after soft-reset: " + "tfd = %08x\n", val); + et = AHCI_ERR_TIMEOUT; + break; + } + } } ahci_end_transaction(slot, et); + /* Kick controller into sane state and enable FBS. */ + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && + (ccb->ataio.cmd.control & ATA_A_RESET) == 0) { + ahci_stop(ch->dev); + ahci_start(ch->dev, 1); + } return; } /* Start command execution timeout */ @@ -1571,7 +1679,8 @@ ahci_timeout(struct ahci_slot *slot) 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) + if ((sstatus & (1 << slot->slot)) != 0 || ccs == slot->slot || + ch->fbs_enabled) slot->state = AHCI_SLOT_EXECUTING; callout_reset(&slot->timeout, @@ -1629,12 +1738,19 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) if ((et == AHCI_ERR_TFE) || (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)) { u_int8_t *fis = ch->dma.rfis + 0x40; - uint16_t tfd = ATA_INL(ch->r_mem, AHCI_P_TFD); bus_dmamap_sync(ch->dma.rfis_tag, ch->dma.rfis_map, BUS_DMASYNC_POSTREAD); - res->status = tfd; - res->error = tfd >> 8; + if (ch->fbs_enabled) { + fis += ccb->ccb_h.target_id * 256; + res->status = fis[2]; + res->error = fis[3]; + } else { + uint16_t tfd = ATA_INL(ch->r_mem, AHCI_P_TFD); + + res->status = tfd; + res->error = tfd >> 8; + } res->lba_low = fis[4]; res->lba_mid = fis[5]; res->lba_high = fis[6]; @@ -1653,6 +1769,8 @@ 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); } + if (et != AHCI_ERR_NONE) + ch->eslots |= (1 << slot->slot); /* In case of error, freeze device for proper recovery. */ if ((et != AHCI_ERR_NONE) && (!ch->readlog) && !(ccb->ccb_h.status & CAM_DEV_QFRZN)) { @@ -1716,9 +1834,11 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) slot->ccb = NULL; /* Update channel stats. */ ch->numrslots--; + ch->numrslotspd[ccb->ccb_h.target_id]--; if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { ch->numtslots--; + ch->numtslotspd[ccb->ccb_h.target_id]--; } /* If it was first request of reset sequence and there is no error, * proceed to second request. */ @@ -1736,6 +1856,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) /* If it was NCQ command error, put result on hold. */ } else if (et == AHCI_ERR_NCQ) { ch->hold[slot->slot] = ccb; + ch->numhslots++; } else xpt_done(ccb); /* Unfreeze frozen command. */ @@ -1750,6 +1871,15 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) /* if there was fatal error - reset port. */ if (ch->fatalerr) { ahci_reset(dev); + } else { + /* if we have slots in error, we can reinit port. */ + if (ch->eslots != 0) { + ahci_stop(dev); + ahci_start(dev, 1); + } + /* if there commands on hold, we can do READ LOG. */ + if (!ch->readlog && ch->numhslots) + ahci_issue_read_log(dev); } } /* Start PM timer. */ @@ -1837,6 +1967,7 @@ ahci_process_read_log(device_t dev, union ccb *ccb) } xpt_done(ch->hold[i]); ch->hold[i] = NULL; + ch->numhslots--; } } else { if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) @@ -1849,6 +1980,7 @@ ahci_process_read_log(device_t dev, union ccb *ccb) continue; xpt_done(ch->hold[i]); ch->hold[i] = NULL; + ch->numhslots--; } } free(ccb->ataio.data_ptr, M_AHCI); @@ -1857,7 +1989,7 @@ ahci_process_read_log(device_t dev, union ccb *ccb) } static void -ahci_start(device_t dev) +ahci_start(device_t dev, int fbs) { struct ahci_channel *ch = device_get_softc(dev); u_int32_t cmd; @@ -1866,6 +1998,12 @@ ahci_start(device_t dev) ATA_OUTL(ch->r_mem, AHCI_P_SERR, 0xFFFFFFFF); /* Clear any interrupts pending on this channel */ ATA_OUTL(ch->r_mem, AHCI_P_IS, 0xFFFFFFFF); + /* Configure FIS-based switching if supported. */ + if (ch->chcaps & AHCI_P_CMD_FBSCP) { + ch->fbs_enabled = (fbs && ch->pm_present) ? 1 : 0; + ATA_OUTL(ch->r_mem, AHCI_P_FBS, + ch->fbs_enabled ? AHCI_P_FBS_EN : 0); + } /* Start operations on this channel */ cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_ST | @@ -1891,6 +2029,7 @@ ahci_stop(device_t dev) break; } } while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CR); + ch->eslots = 0; } static void @@ -2004,7 +2143,9 @@ ahci_reset(device_t dev) continue; xpt_done(ch->hold[i]); ch->hold[i] = NULL; + ch->numhslots--; } + ch->eslots = 0; ch->fatalerr = 0; /* Tell the XPT about the event */ xpt_async(AC_BUS_RESET, ch->path, NULL); @@ -2025,7 +2166,7 @@ ahci_reset(device_t dev) /* Wait for clearing busy status. */ if (ahci_wait_ready(dev, 15000)) ahci_clo(dev); - ahci_start(dev); + ahci_start(dev, 1); ch->devices = 1; /* Enable wanted port interrupts */ ATA_OUTL(ch->r_mem, AHCI_P_IE, diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index a436490d5c7..a2cc5a00f75 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -247,8 +247,11 @@ #define AHCI_P_CMD_CPS 0x00010000 #define AHCI_P_CMD_PMA 0x00020000 #define AHCI_P_CMD_HPCP 0x00040000 -#define AHCI_P_CMD_ISP 0x00080000 +#define AHCI_P_CMD_MPSP 0x00080000 #define AHCI_P_CMD_CPD 0x00100000 +#define AHCI_P_CMD_ESP 0x00200000 +#define AHCI_P_CMD_FBSCP 0x00400000 +#define AHCI_P_CMD_APSTE 0x00800000 #define AHCI_P_CMD_ATAPI 0x01000000 #define AHCI_P_CMD_DLAE 0x02000000 #define AHCI_P_CMD_ALPE 0x04000000 @@ -268,6 +271,15 @@ #define AHCI_P_CI 0x38 #define AHCI_P_SNTF 0x3C #define AHCI_P_FBS 0x40 +#define AHCI_P_FBS_EN 0x00000001 +#define AHCI_P_FBS_DEC 0x00000002 +#define AHCI_P_FBS_SDE 0x00000004 +#define AHCI_P_FBS_DEV 0x00000f00 +#define AHCI_P_FBS_DEV_SHIFT 8 +#define AHCI_P_FBS_ADO 0x0000f000 +#define AHCI_P_FBS_ADO_SHIFT 12 +#define AHCI_P_FBS_DWE 0x000f0000 +#define AHCI_P_FBS_DWE_SHIFT 16 /* Just to be sure, if building as module. */ #if MAXPHYS < 512 * 1024 @@ -374,6 +386,7 @@ struct ahci_channel { struct cam_path *path; uint32_t caps; /* Controller capabilities */ uint32_t caps2; /* Controller capabilities */ + uint32_t chcaps; /* Channel capabilities */ int quirks; int numslots; /* Number of present slots */ int pm_level; /* power management level */ @@ -383,11 +396,16 @@ struct ahci_channel { struct mtx mtx; /* state lock */ int devices; /* What is present */ int pm_present; /* PM presence reported */ + int fbs_enabled; /* FIS-based switching enabled */ uint32_t oslots; /* Occupied slots */ uint32_t rslots; /* Running slots */ uint32_t aslots; /* Slots with atomic commands */ + uint32_t eslots; /* Slots in error */ int numrslots; /* Number of running slots */ + int numrslotspd[16];/* Number of running slots per dev */ int numtslots; /* Number of tagged slots */ + int numtslotspd[16];/* Number of tagged slots per dev */ + int numhslots; /* Number of holden slots */ int readlog; /* Our READ LOG active */ int fatalerr; /* Fatal error happend */ int lastslot; /* Last used slot */ From 3e2fbfe5e66d3e51728192b66486fbe7398f2dfe Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 19:59:06 +0000 Subject: [PATCH 1449/2592] MFC r203165: Reset port on disconnect event, to abort any running requests. --- sys/dev/ahci/ahci.c | 14 ++++++-------- sys/dev/siis/siis.c | 14 ++++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 6ca0c663a42..cf7171086cb 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1161,17 +1161,15 @@ ahci_phy_check_events(device_t dev, u_int32_t serr) u_int32_t status = ATA_INL(ch->r_mem, AHCI_P_SSTS); union ccb *ccb; - if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && - ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && - ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) { - if (bootverbose) + if (bootverbose) { + if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && + ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && + ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) { device_printf(dev, "CONNECT requested\n"); - ahci_reset(dev); - } else { - if (bootverbose) + } else device_printf(dev, "DISCONNECT requested\n"); - ch->devices = 0; } + ahci_reset(dev); if ((ccb = xpt_alloc_ccb_nowait()) == NULL) return; if (xpt_create_path(&ccb->ccb_h.path, NULL, diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index f6d83ec78b0..74806fd7bc8 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -728,17 +728,15 @@ siis_phy_check_events(device_t dev) u_int32_t status = ATA_INL(ch->r_mem, SIIS_P_SSTS); union ccb *ccb; - if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && - ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && - ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) { - if (bootverbose) + if (bootverbose) { + if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && + ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && + ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) { device_printf(dev, "CONNECT requested\n"); - siis_reset(dev); - } else { - if (bootverbose) + } else device_printf(dev, "DISCONNECT requested\n"); - ch->devices = 0; } + siis_reset(dev); if ((ccb = xpt_alloc_ccb_nowait()) == NULL) return; if (xpt_create_path(&ccb->ccb_h.path, NULL, From 877380223f9825a6bf77585ac38c2f0028a348be Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 14 Feb 2010 20:00:21 +0000 Subject: [PATCH 1450/2592] MFC r203426: Disable PHY of unconnected ports when interface power management enabled. It allows to save a bit more power (about 0.5W on 2 unused ports of ICH8M). --- sys/dev/ahci/ahci.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index cf7171086cb..5e2315b16aa 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -2291,7 +2291,12 @@ ahci_sata_phy_reset(device_t dev) ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 : (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER))); DELAY(5000); - return (ahci_sata_connect(ch)); + if (!ahci_sata_connect(ch)) { + if (ch->pm_level > 0) + ATA_OUTL(ch->r_mem, AHCI_P_SCTL, ATA_SC_DET_DISABLE); + return (0); + } + return (1); } static void From 60d2ff2cd9b32a94711dad9f86a4f9ce8f6f89f2 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Mon, 15 Feb 2010 11:29:27 +0000 Subject: [PATCH 1451/2592] MFC: r202969: Actualize. --- tools/make_libdeps.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/make_libdeps.sh b/tools/make_libdeps.sh index f03f01edcca..b0b3f186b1a 100644 --- a/tools/make_libdeps.sh +++ b/tools/make_libdeps.sh @@ -47,9 +47,12 @@ sed -E -e's; ;! ;g' -e's;$;!;' -e's;-lbsdxml!;lib/libexpat;g' + -e's;-lpthread!;lib/libthr;g' -e's;-lm!;lib/msun;g' - -e's;-l(supc\+\+)!;gnu/lib/lib\1;g' - -e's;-l(asn1|krb5|roken)!;kerberos5/lib/lib\1;g' + -e's;-l(ncurses|termcap)!;lib/ncurses/ncurses;g' + -e's;-l(gcc)!;gnu/lib/lib\1;g' + -e's;-lssp_nonshared!;gnu/lib/libssp/libssp_nonshared;g' + -e's;-l(asn1|heimntlm|hx509|krb5|roken)!;kerberos5/lib/lib\1;g' -e's;-l(crypto|ssh|ssl)!;secure/lib/lib\1;g' -e's;-l([^!]+)!;lib/lib\1;g' " From a911d19dfeb910dc5e2e174c6ef3652b48fe9665 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Mon, 15 Feb 2010 15:00:40 +0000 Subject: [PATCH 1452/2592] MFC r203637: Improve checking whether an ARM VA has a valid mapping before performing cache sync. VIPT/PIPT caches need valid VA-PA mapping in PTE for a cache operation to succeed (unlike VIVT). Prior to this fix pmap was using l2pte_valid() for that check, but this is not sufficient as the function merely checks if a PTE exists (there can be existing but _invalid_ entries in the table). A new pmap_has_valid_mapping() routine is introduced to do this job right by checking proper PTE flags. Among other potential problems this cures coherency issues with L2 caches on MV-78100. Submitted by: Grzegorz Bernacki, Piotr Ziecik Reviewed, tested by: marcel Obtained from: Semihalf --- sys/arm/arm/pmap.c | 116 ++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 74 deletions(-) diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c index 1b9bf81f174..9df07d9a352 100644 --- a/sys/arm/arm/pmap.c +++ b/sys/arm/arm/pmap.c @@ -1199,79 +1199,38 @@ pmap_tlb_flushD(pmap_t pm) cpu_tlb_flushD(); } -static PMAP_INLINE void -pmap_l2cache_wbinv_range(pmap_t pm, vm_offset_t va, vm_size_t len) +static int +pmap_has_valid_mapping(pmap_t pm, vm_offset_t va) { - vm_size_t rest; pd_entry_t *pde; pt_entry_t *ptep; - rest = MIN(PAGE_SIZE - (va & PAGE_MASK), len); + if (pmap_get_pde_pte(pm, va, &pde, &ptep) && + ptep && ((*ptep & L2_TYPE_MASK) != L2_TYPE_INV)) + return (1); - while (len > 0) { - CTR4(KTR_PMAP, "pmap_l2cache_wbinv_range: pmap %p is_kernel %d " - "va 0x%08x len 0x%x ", pm, pm == pmap_kernel(), va, rest); - if (pmap_get_pde_pte(pm, va, &pde, &ptep) && l2pte_valid(*ptep)) - cpu_l2cache_wbinv_range(va, rest); - - len -= rest; - va += rest; - - rest = MIN(PAGE_SIZE, len); - } + return (0); } static PMAP_INLINE void pmap_idcache_wbinv_range(pmap_t pm, vm_offset_t va, vm_size_t len) -{ - - if (pmap_is_current(pm)) { - cpu_idcache_wbinv_range(va, len); - pmap_l2cache_wbinv_range(pm, va, len); - } -} - -static PMAP_INLINE void -pmap_l2cache_wb_range(pmap_t pm, vm_offset_t va, vm_size_t len) { vm_size_t rest; - pd_entry_t *pde; - pt_entry_t *ptep; - rest = MIN(PAGE_SIZE - (va & PAGE_MASK), len); + CTR4(KTR_PMAP, "pmap_dcache_wbinv_range: pmap %p is_kernel %d va 0x%08x" + " len 0x%x ", pm, pm == pmap_kernel(), va, len); - while (len > 0) { - CTR4(KTR_PMAP, "pmap_l2cache_wb_range: pmap %p is_kernel %d " - "va 0x%08x len 0x%x ", pm, pm == pmap_kernel(), va, rest); - if (pmap_get_pde_pte(pm, va, &pde, &ptep) && l2pte_valid(*ptep)) - cpu_l2cache_wb_range(va, rest); - - len -= rest; - va += rest; - - rest = MIN(PAGE_SIZE, len); - } -} - -static PMAP_INLINE void -pmap_l2cache_inv_range(pmap_t pm, vm_offset_t va, vm_size_t len) -{ - vm_size_t rest; - pd_entry_t *pde; - pt_entry_t *ptep; - - rest = MIN(PAGE_SIZE - (va & PAGE_MASK), len); - - while (len > 0) { - CTR4(KTR_PMAP, "pmap_l2cache_wb_range: pmap %p is_kernel %d " - "va 0x%08x len 0x%x ", pm, pm == pmap_kernel(), va, rest); - if (pmap_get_pde_pte(pm, va, &pde, &ptep) && l2pte_valid(*ptep)) - cpu_l2cache_inv_range(va, rest); - - len -= rest; - va += rest; - - rest = MIN(PAGE_SIZE, len); + if (pmap_is_current(pm) || pm == pmap_kernel()) { + rest = MIN(PAGE_SIZE - (va & PAGE_MASK), len); + while (len > 0) { + if (pmap_has_valid_mapping(pm, va)) { + cpu_idcache_wbinv_range(va, rest); + cpu_l2cache_wbinv_range(va, rest); + } + len -= rest; + va += rest; + rest = MIN(PAGE_SIZE, len); + } } } @@ -1279,24 +1238,31 @@ static PMAP_INLINE void pmap_dcache_wb_range(pmap_t pm, vm_offset_t va, vm_size_t len, boolean_t do_inv, boolean_t rd_only) { + vm_size_t rest; CTR4(KTR_PMAP, "pmap_dcache_wb_range: pmap %p is_kernel %d va 0x%08x " "len 0x%x ", pm, pm == pmap_kernel(), va, len); CTR2(KTR_PMAP, " do_inv %d rd_only %d", do_inv, rd_only); if (pmap_is_current(pm)) { - if (do_inv) { - if (rd_only) { - cpu_dcache_inv_range(va, len); - pmap_l2cache_inv_range(pm, va, len); + rest = MIN(PAGE_SIZE - (va & PAGE_MASK), len); + while (len > 0) { + if (pmap_has_valid_mapping(pm, va)) { + if (do_inv && rd_only) { + cpu_dcache_inv_range(va, rest); + cpu_l2cache_inv_range(va, rest); + } else if (do_inv) { + cpu_dcache_wbinv_range(va, rest); + cpu_l2cache_wbinv_range(va, rest); + } else if (!rd_only) { + cpu_dcache_wb_range(va, rest); + cpu_l2cache_wb_range(va, rest); + } } - else { - cpu_dcache_wbinv_range(va, len); - pmap_l2cache_wbinv_range(pm, va, len); - } - } else if (!rd_only) { - cpu_dcache_wb_range(va, len); - pmap_l2cache_wb_range(pm, va, len); + len -= rest; + va += rest; + + rest = MIN(PAGE_SIZE, len); } } } @@ -3225,7 +3191,8 @@ pmap_remove_all(vm_page_t m) */ if (pmap_is_current(pv->pv_pmap)) { cpu_dcache_inv_range(pv->pv_va, PAGE_SIZE); - cpu_l2cache_inv_range(pv->pv_va, PAGE_SIZE); + if (pmap_has_valid_mapping(pv->pv_pmap, pv->pv_va)) + cpu_l2cache_inv_range(pv->pv_va, PAGE_SIZE); } if (pv->pv_flags & PVF_UNMAN) { @@ -3512,9 +3479,10 @@ do_l2b_alloc: if (pmap_is_current(pmap) && (oflags & PVF_NC) == 0 && (opte & L2_S_PROT_W) != 0 && - (prot & VM_PROT_WRITE) == 0) { + (prot & VM_PROT_WRITE) == 0 && + (opte & L2_TYPE_MASK) != L2_TYPE_INV) { cpu_dcache_wb_range(va, PAGE_SIZE); - pmap_l2cache_wb_range(pmap, va, PAGE_SIZE); + cpu_l2cache_wb_range(va, PAGE_SIZE); } } else { /* From be4274118a7636dfeabb6f8e0aaab68566788abc Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 15 Feb 2010 16:41:30 +0000 Subject: [PATCH 1453/2592] MFC r203124: Note added FIS-based switching support. --- share/man/man4/ahci.4 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/share/man/man4/ahci.4 b/share/man/man4/ahci.4 index 46660d3a273..b3d2e23bdaa 100644 --- a/share/man/man4/ahci.4 +++ b/share/man/man4/ahci.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 24, 2009 +.Dd January 28, 2010 .Dt AHCI 4 .Os .Sh NAME @@ -114,14 +114,11 @@ ATAPI devices are handled by the SCSI protocol peripheral drivers etc. .Pp Driver features include support for Serial ATA and ATAPI devices, -Port Multipliers, hardware command queues (up to 32 commands per port), +Port Multipliers (including FIS-based switching, when supported), +hardware command queues (up to 32 commands per port), Native Command Queuing, SATA interface Power Management, device hot-plug and Message Signaled Interrupts. .Pp -The Port Multiplier FIS Based Switching feature added in the AHCI 1.2 -specification, which is required for effective parallel operation of devices -behind Port Multipliers, is not yet supported. -.Pp AHCI hardware is also supported by ataahci driver from .Xr ata 4 subsystem. If both drivers are loaded at the same time, this one will be @@ -131,6 +128,10 @@ The .Nm driver supports AHCI compatible controllers having PCI class 1 (mass storage), subclass 6 (SATA) and programming interface 1 (AHCI). +.Pp +Also, in cooperation with atamarvell and atajmicron drivers of ata(4), +it supports AHCI part of legacy-PATA + AHCI-SATA combined controllers, +such as JMicron JMB36x and Marvell 88SX61xx. .Sh SEE ALSO .Xr ada 4 , .Xr cd 4 , From d1b9afd28a8de901a0b38bba3d292d627d0d1663 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 16 Feb 2010 06:34:44 +0000 Subject: [PATCH 1454/2592] MFC r203408: Prevent NULL deference by checking return value of gctl_get_asciiparam. --- sys/geom/virstor/g_virstor.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/geom/virstor/g_virstor.c b/sys/geom/virstor/g_virstor.c index 1de3d5ae28e..974c5946d64 100644 --- a/sys/geom/virstor/g_virstor.c +++ b/sys/geom/virstor/g_virstor.c @@ -311,6 +311,11 @@ virstor_ctl_add(struct gctl_req *req, struct g_class *cp) snprintf(aname, sizeof aname, "arg%d", i); prov_name = gctl_get_asciiparam(req, aname); + if (prov_name == NULL) { + gctl_error(req, "Error fetching argument '%s'", aname); + g_topology_unlock(); + return; + } if (strncmp(prov_name, _PATH_DEV, strlen(_PATH_DEV)) == 0) prov_name += strlen(_PATH_DEV); @@ -565,6 +570,10 @@ virstor_ctl_remove(struct gctl_req *req, struct g_class *cp) sprintf(param, "arg%d", i); prov_name = gctl_get_asciiparam(req, param); + if (prov_name == NULL) { + gctl_error(req, "Error fetching argument '%s'", param); + return; + } if (strncmp(prov_name, _PATH_DEV, strlen(_PATH_DEV)) == 0) prov_name += strlen(_PATH_DEV); From da9808aa2955560b919ce2a91f9dfe08bdae1a98 Mon Sep 17 00:00:00 2001 From: Maksim Yevmenkin Date: Tue, 16 Feb 2010 19:00:47 +0000 Subject: [PATCH 1455/2592] MFC: r203676 Introduce new rc.conf variable firewall_coscripts. It can be used to specify list of executables and/or rc scripts that should be executed after firewall starts/stops. Submitted by: Yuri Kurenkov Reviewed by: rhodes, rc@ --- etc/defaults/rc.conf | 2 ++ etc/rc.d/ipfw | 32 ++++++++++++++++++++++++++------ share/man/man5/rc.conf.5 | 4 ++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 6e7c37d8c68..24a03fd5cc8 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -118,6 +118,8 @@ firewall_type="UNKNOWN" # Firewall type (see /etc/rc.firewall) firewall_quiet="NO" # Set to YES to suppress rule display firewall_logging="NO" # Set to YES to enable events logging firewall_flags="" # Flags passed to ipfw when type is a file +firewall_coscripts="" # List of executables/scripts to run after + # firewall starts/stops firewall_client_net="192.0.2.0/24" # Network address for "client" firewall. firewall_simple_iif="ed1" # Inside network interface for "simple" # firewall. diff --git a/etc/rc.d/ipfw b/etc/rc.d/ipfw index 872f2787ab3..28e59d8cf11 100755 --- a/etc/rc.d/ipfw +++ b/etc/rc.d/ipfw @@ -14,6 +14,7 @@ name="ipfw" rcvar="firewall_enable" start_cmd="ipfw_start" start_precmd="ipfw_prestart" +start_postcmd="ipfw_poststart" stop_cmd="ipfw_stop" required_modules="ipfw" @@ -40,9 +41,6 @@ ipfw_start() [ -z "${firewall_script}" ] && firewall_script=/etc/rc.firewall if [ -r "${firewall_script}" ]; then - if [ -f /etc/rc.d/natd ] ; then - /etc/rc.d/natd quietstart - fi /bin/sh "${firewall_script}" "${_firewall_type}" echo 'Firewall rules loaded.' elif [ "`ipfw list 65535`" = "65535 deny ip from any to any" ]; then @@ -57,6 +55,19 @@ ipfw_start() echo 'Firewall logging enabled.' sysctl net.inet.ip.fw.verbose=1 >/dev/null fi +} + +ipfw_poststart() +{ + local _coscript + + # Start firewall coscripts + # + for _coscript in ${firewall_coscripts} ; do + if [ -f "${_coscript}" ]; then + ${_coscript} quietstart + fi + done # Enable the firewall # @@ -67,13 +78,22 @@ ipfw_start() ipfw_stop() { + local _coscript + # Disable the firewall # ${SYSCTL_W} net.inet.ip.fw.enable=0 - if [ -f /etc/rc.d/natd ] ; then - /etc/rc.d/natd quietstop - fi + + # Stop firewall coscripts + # + for _coscript in `reverse_list ${firewall_coscripts}` ; do + if [ -f "${_coscript}" ]; then + ${_coscript} quietstop + fi + done } load_rc_config $name +firewall_coscripts="/etc/rc.d/natd ${firewall_coscripts}" + run_rc_command $* diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index 0f377b2e679..6bb3a7188f7 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -512,6 +512,10 @@ specifies a filename. .Pq Vt str The IPv6 equivalent of .Va firewall_flags . +.It Va firewall_coscripts +.Pq Vt str +List of executables and/or rc scripts to run after firewall starts/stops. +Default is empty. .\" ----- firewall_nat_enable setting -------------------------------- .It Va firewall_nat_enable .Pq Vt bool From 3d4d4693f0cbdf3f86ff4870d986046e6f3b0956 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Tue, 16 Feb 2010 22:19:55 +0000 Subject: [PATCH 1456/2592] Merge r202461 from head: Implement an "-x" option to cp(1), for compatibility with Linux and feature parity with du(1) and similar: When set, cp(1) will not traverse mount points. PR: bin/88056 Initial patch by: Graham J Lee leeg teaching.physics.ox.ac.uk --- bin/cp/cp.1 | 8 +++++--- bin/cp/cp.c | 7 +++++-- bin/cp/utils.c | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/bin/cp/cp.1 b/bin/cp/cp.1 index 7329b64aca5..fc5a9f73ad6 100644 --- a/bin/cp/cp.1 +++ b/bin/cp/cp.1 @@ -32,7 +32,7 @@ .\" @(#)cp.1 8.3 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd October 27, 2006 +.Dd January 17, 2010 .Dt CP 1 .Os .Sh NAME @@ -45,7 +45,7 @@ .Op Fl H | Fl L | Fl P .Oc .Op Fl f | i | n -.Op Fl alpv +.Op Fl alpvx .Ar source_file target_file .Nm .Oo @@ -53,7 +53,7 @@ .Op Fl H | Fl L | Fl P .Oc .Op Fl f | i | n -.Op Fl alpv +.Op Fl alpvx .Ar source_file ... target_directory .Sh DESCRIPTION In the first synopsis form, the @@ -183,6 +183,8 @@ permissions. Cause .Nm to be verbose, showing files as they are copied. +.It Fl x +File system mount points are not traversed. .El .Pp For each destination file that already exists, its contents are diff --git a/bin/cp/cp.c b/bin/cp/cp.c index feba50faae9..0ae57eba590 100644 --- a/bin/cp/cp.c +++ b/bin/cp/cp.c @@ -101,8 +101,9 @@ main(int argc, char *argv[]) int Hflag, Lflag, Pflag, ch, fts_options, r, have_trailing_slash; char *target; + fts_options = FTS_NOCHDIR | FTS_PHYSICAL; Hflag = Lflag = Pflag = 0; - while ((ch = getopt(argc, argv, "HLPRafilnprv")) != -1) + while ((ch = getopt(argc, argv, "HLPRafilnprvx")) != -1) switch (ch) { case 'H': Hflag = 1; @@ -150,6 +151,9 @@ main(int argc, char *argv[]) case 'v': vflag = 1; break; + case 'x': + fts_options |= FTS_XDEV; + break; default: usage(); break; @@ -160,7 +164,6 @@ main(int argc, char *argv[]) if (argc < 2) usage(); - fts_options = FTS_NOCHDIR | FTS_PHYSICAL; if (Rflag && rflag) errx(1, "the -R and -r options may not be specified together"); if (rflag) diff --git a/bin/cp/utils.c b/bin/cp/utils.c index 63eba422f3d..b075eac46d0 100644 --- a/bin/cp/utils.c +++ b/bin/cp/utils.c @@ -518,8 +518,8 @@ usage(void) { (void)fprintf(stderr, "%s\n%s\n", -"usage: cp [-R [-H | -L | -P]] [-f | -i | -n] [-alpv] source_file target_file", -" cp [-R [-H | -L | -P]] [-f | -i | -n] [-alpv] source_file ... " +"usage: cp [-R [-H | -L | -P]] [-f | -i | -n] [-alpvx] source_file target_file", +" cp [-R [-H | -L | -P]] [-f | -i | -n] [-alpvx] source_file ... " "target_directory"); exit(EX_USAGE); } From da7f88513ec268e085e60a1fc33b14d5abd3af9c Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Tue, 16 Feb 2010 22:23:33 +0000 Subject: [PATCH 1457/2592] Merge 203689 from head: Install the padlock(4) man page on amd64 as well as i386, to match the platforms where the driver itself is compiled and installed. PR: docs/130895 Reported by: George Hartzell --- share/man/man4/Makefile | 2 ++ share/man/man4/man4.i386/Makefile | 1 - share/man/man4/{man4.i386 => }/padlock.4 | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) rename share/man/man4/{man4.i386 => }/padlock.4 (98%) diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 4e34eb0d87e..812a450ff4b 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -294,6 +294,7 @@ MAN= aac.4 \ ${_nxge.4} \ ohci.4 \ orm.4 \ + ${_padlock.4} \ pass.4 \ patm.4 \ pccard.4 \ @@ -641,6 +642,7 @@ _nfsmb.4= nfsmb.4 _nve.4= nve.4 _nvram.4= nvram.4 _nxge.4= nxge.4 +_padlock.4= padlock.4 _rr232x.4= rr232x.4 _speaker.4= speaker.4 _spkr.4= spkr.4 diff --git a/share/man/man4/man4.i386/Makefile b/share/man/man4/man4.i386/Makefile index 677d77eb385..9608ddf2c23 100644 --- a/share/man/man4/man4.i386/Makefile +++ b/share/man/man4/man4.i386/Makefile @@ -21,7 +21,6 @@ MAN= aic.4 \ mcd.4 \ mse.4 \ npx.4 \ - padlock.4 \ pae.4 \ pbio.4 \ pcf.4 \ diff --git a/share/man/man4/man4.i386/padlock.4 b/share/man/man4/padlock.4 similarity index 98% rename from share/man/man4/man4.i386/padlock.4 rename to share/man/man4/padlock.4 index e93d3d9fe21..2a74f63939c 100644 --- a/share/man/man4/man4.i386/padlock.4 +++ b/share/man/man4/padlock.4 @@ -24,8 +24,8 @@ .\" .\" $FreeBSD$ .\" -.Dd August 1, 2007 -.Dt PADLOCK 4 i386 +.Dd February 8, 2010 +.Dt PADLOCK 4 .Os .Sh NAME .Nm padlock From f723d876b5bf6b75c7af922e72d565924c12ac87 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 17 Feb 2010 09:03:38 +0000 Subject: [PATCH 1458/2592] MFC r203875: Do not leak process lock when current thread is not allowed to see target. --- sys/kern/kern_event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index ad0acd83410..9109e0e087d 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -334,8 +334,10 @@ filt_procattach(struct knote *kn) if (p == NULL) return (ESRCH); - if ((error = p_cansee(curthread, p))) + if ((error = p_cansee(curthread, p))) { + PROC_UNLOCK(p); return (error); + } kn->kn_ptr.p_proc = p; kn->kn_flags |= EV_CLEAR; /* automatically set */ From a5d3f6af70182b7542f2644e1ce3daf9f1b0f515 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 17 Feb 2010 09:09:12 +0000 Subject: [PATCH 1459/2592] MFC r203441: Placate new binutils, by using 16-bit %ax instead of 32-bit %eax as an argument for fnstsw. Explicitely specify sizes for the XMM control and status word and X87 control and status words. --- lib/msun/amd64/fenv.c | 11 +++++++---- lib/msun/amd64/fenv.h | 13 ++++++++----- lib/msun/i387/fenv.c | 15 +++++++++------ lib/msun/i387/fenv.h | 17 ++++++++++------- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/lib/msun/amd64/fenv.c b/lib/msun/amd64/fenv.c index cf07c8ba1f8..e12607078f3 100644 --- a/lib/msun/amd64/fenv.c +++ b/lib/msun/amd64/fenv.c @@ -86,7 +86,7 @@ fegetenv(fenv_t *envp) int feholdexcept(fenv_t *envp) { - int mxcsr; + __uint32_t mxcsr; __stmxcsr(&mxcsr); __fnstenv(&envp->__x87); @@ -101,7 +101,8 @@ feholdexcept(fenv_t *envp) int feupdateenv(const fenv_t *envp) { - int mxcsr, status; + __uint32_t mxcsr; + __uint16_t status; __fnstsw(&status); __stmxcsr(&mxcsr); @@ -113,7 +114,8 @@ feupdateenv(const fenv_t *envp) int __feenableexcept(int mask) { - int mxcsr, control, omask; + __uint32_t mxcsr, omask; + __uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); @@ -129,7 +131,8 @@ __feenableexcept(int mask) int __fedisableexcept(int mask) { - int mxcsr, control, omask; + __uint32_t mxcsr, omask; + __uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); diff --git a/lib/msun/amd64/fenv.h b/lib/msun/amd64/fenv.h index b4d7379e8ff..875664affd2 100644 --- a/lib/msun/amd64/fenv.h +++ b/lib/msun/amd64/fenv.h @@ -110,7 +110,8 @@ feclearexcept(int __excepts) static __inline int fegetexceptflag(fexcept_t *__flagp, int __excepts) { - int __mxcsr, __status; + __uint32_t __mxcsr; + __uint16_t __status; __stmxcsr(&__mxcsr); __fnstsw(&__status); @@ -124,7 +125,8 @@ int feraiseexcept(int __excepts); static __inline int fetestexcept(int __excepts) { - int __mxcsr, __status; + __uint32_t __mxcsr; + __uint16_t __status; __stmxcsr(&__mxcsr); __fnstsw(&__status); @@ -134,7 +136,7 @@ fetestexcept(int __excepts) static __inline int fegetround(void) { - int __control; + __uint16_t __control; /* * We assume that the x87 and the SSE unit agree on the @@ -149,7 +151,8 @@ fegetround(void) static __inline int fesetround(int __round) { - int __mxcsr, __control; + __uint32_t __mxcsr; + __uint16_t __control; if (__round & ~_ROUND_MASK) return (-1); @@ -197,7 +200,7 @@ int fedisableexcept(int __mask); static __inline int fegetexcept(void) { - int __control; + __uint16_t __control; /* * We assume that the masks for the x87 and the SSE unit are diff --git a/lib/msun/i387/fenv.c b/lib/msun/i387/fenv.c index ace2d323d05..5c996b36bf6 100644 --- a/lib/msun/i387/fenv.c +++ b/lib/msun/i387/fenv.c @@ -87,7 +87,7 @@ int fesetexceptflag(const fexcept_t *flagp, int excepts) { fenv_t env; - int mxcsr; + __uint32_t mxcsr; __fnstenv(&env); env.__status &= ~excepts; @@ -117,7 +117,7 @@ feraiseexcept(int excepts) int fegetenv(fenv_t *envp) { - int mxcsr; + __uint32_t mxcsr; __fnstenv(envp); /* @@ -135,7 +135,7 @@ fegetenv(fenv_t *envp) int feholdexcept(fenv_t *envp) { - int mxcsr; + __uint32_t mxcsr; __fnstenv(envp); __fnclex(); @@ -152,7 +152,8 @@ feholdexcept(fenv_t *envp) int feupdateenv(const fenv_t *envp) { - int mxcsr, status; + __uint32_t mxcsr; + __uint16_t status; __fnstsw(&status); if (__HAS_SSE()) @@ -167,7 +168,8 @@ feupdateenv(const fenv_t *envp) int __feenableexcept(int mask) { - int mxcsr, control, omask; + __uint32_t mxcsr, omask; + __uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); @@ -188,7 +190,8 @@ __feenableexcept(int mask) int __fedisableexcept(int mask) { - int mxcsr, control, omask; + __uint32_t mxcsr, omask; + __uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); diff --git a/lib/msun/i387/fenv.h b/lib/msun/i387/fenv.h index c4eab02d9df..cc58a92afad 100644 --- a/lib/msun/i387/fenv.h +++ b/lib/msun/i387/fenv.h @@ -114,7 +114,7 @@ static __inline int feclearexcept(int __excepts) { fenv_t __env; - int __mxcsr; + __uint32_t __mxcsr; if (__excepts == FE_ALL_EXCEPT) { __fnclex(); @@ -134,7 +134,8 @@ feclearexcept(int __excepts) static __inline int fegetexceptflag(fexcept_t *__flagp, int __excepts) { - int __mxcsr, __status; + __uint32_t __mxcsr; + __uint16_t __status; __fnstsw(&__status); if (__HAS_SSE()) @@ -151,7 +152,8 @@ int feraiseexcept(int __excepts); static __inline int fetestexcept(int __excepts) { - int __mxcsr, __status; + __uint32_t __mxcsr; + __uint16_t __status; __fnstsw(&__status); if (__HAS_SSE()) @@ -164,7 +166,7 @@ fetestexcept(int __excepts) static __inline int fegetround(void) { - int __control; + __uint16_t __control; /* * We assume that the x87 and the SSE unit agree on the @@ -179,7 +181,8 @@ fegetround(void) static __inline int fesetround(int __round) { - int __mxcsr, __control; + __uint32_t __mxcsr; + __uint16_t __control; if (__round & ~_ROUND_MASK) return (-1); @@ -206,7 +209,7 @@ static __inline int fesetenv(const fenv_t *__envp) { fenv_t __env = *__envp; - int __mxcsr; + __uint32_t __mxcsr; __mxcsr = __get_mxcsr(__env); __set_mxcsr(__env, 0xffffffff); @@ -234,7 +237,7 @@ int fedisableexcept(int __mask); static __inline int fegetexcept(void) { - int __control; + __uint16_t __control; /* * We assume that the masks for the x87 and the SSE unit are From 21eee1133a4b1cb21ede7140a8dadbb923370a22 Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Thu, 18 Feb 2010 01:15:58 +0000 Subject: [PATCH 1460/2592] Add the long missing "destroy" option [mfc of 203505] --- sbin/geom/class/multipath/geom_multipath.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sbin/geom/class/multipath/geom_multipath.c b/sbin/geom/class/multipath/geom_multipath.c index 1bb3f32239a..4319d0421c2 100644 --- a/sbin/geom/class/multipath/geom_multipath.c +++ b/sbin/geom/class/multipath/geom_multipath.c @@ -54,6 +54,10 @@ struct g_command class_commands[] = { "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, mp_main, G_NULL_OPTS, NULL, "[-v] name prov ..." }, + { + "destroy", G_FLAG_VERBOSE, NULL, G_NULL_OPTS, + NULL, "[-v] prov ..." + }, { "clear", G_FLAG_VERBOSE, mp_main, G_NULL_OPTS, NULL, "[-v] prov ..." From 0ed9d88bcaa5b03690c69212acdc304070423157 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Thu, 18 Feb 2010 10:39:53 +0000 Subject: [PATCH 1461/2592] MFC r203681: Fix typo and remove extra spaces. Approved by: rrs (mentor) --- share/man/man4/sctp.4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/share/man/man4/sctp.4 b/share/man/man4/sctp.4 index 226fc3cefc7..975192c44ad 100644 --- a/share/man/man4/sctp.4 +++ b/share/man/man4/sctp.4 @@ -154,8 +154,8 @@ also supports the following extensions: This extension allows one to have message be skipped and not delivered based on some user specified parameters. .It "sctp dynamic addressing" - This extension allows addresses to be added and deleted -dynammically from an existing association. +This extension allows addresses to be added and deleted +dynamically from an existing association. .It "sctp authentication" This extension allows the user to authenticate specific peer chunks (including data) to validate that the peer @@ -164,7 +164,7 @@ association. A shared key option is also provided for so that two stacks can pre-share keys. .It "packet drop" - Some routers support a special satellite protocol that +Some routers support a special satellite protocol that will report losses due to corruption. This allows retransmissions without subsequent loss in bandwidth utilization. From b9d3fd67b9a4ccfd7f16cc16cb2b9ccaa25b0f43 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Thu, 18 Feb 2010 10:46:25 +0000 Subject: [PATCH 1462/2592] MFC r203688: Initialize the execfile argument to NULL instead of _PATH_DEVNULL. This allows the -M option to be used without specifying -N. PR: bin/138146 Approved by: rrs (mentor) --- bin/pkill/pkill.c | 3 ++- bin/ps/ps.c | 3 ++- usr.bin/w/w.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/bin/pkill/pkill.c b/bin/pkill/pkill.c index 69349c3c589..ae0fd89e4ee 100644 --- a/bin/pkill/pkill.c +++ b/bin/pkill/pkill.c @@ -180,7 +180,8 @@ main(int argc, char **argv) debug_opt = 0; pidfile = NULL; pidfilelock = 0; - execf = coref = _PATH_DEVNULL; + execf = NULL; + coref = _PATH_DEVNULL; while ((ch = getopt(argc, argv, "DF:G:ILM:N:P:SU:ad:fg:ij:lnos:t:u:vx")) != -1) switch (ch) { diff --git a/bin/ps/ps.c b/bin/ps/ps.c index 904a430c1af..0667db9b5c4 100644 --- a/bin/ps/ps.c +++ b/bin/ps/ps.c @@ -212,7 +212,8 @@ main(int argc, char *argv[]) init_list(&sesslist, addelem_pid, sizeof(pid_t), "session id"); init_list(&ttylist, addelem_tty, sizeof(dev_t), "tty"); init_list(&uidlist, addelem_uid, sizeof(uid_t), "user"); - memf = nlistf = _PATH_DEVNULL; + memf = _PATH_DEVNULL; + nlistf = NULL; while ((ch = getopt(argc, argv, PS_ARGS)) != -1) switch (ch) { case 'A': diff --git a/usr.bin/w/w.c b/usr.bin/w/w.c index 10ec7b04bd2..dbd41ff60b1 100644 --- a/usr.bin/w/w.c +++ b/usr.bin/w/w.c @@ -158,7 +158,8 @@ main(int argc, char *argv[]) } dropgid = 0; - memf = nlistf = _PATH_DEVNULL; + memf = _PATH_DEVNULL; + nlistf = NULL; while ((ch = getopt(argc, argv, p)) != -1) switch (ch) { case 'd': From 6d812e4f3851212ace9a2c91485302c0b6a64d46 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Thu, 18 Feb 2010 10:48:37 +0000 Subject: [PATCH 1463/2592] MFC r203690: Xorg isn't treated as a distribution, so /usr/X11R6/lib shouldn't be configured when running ldconfig. PR: bin/138945 Approved by: rrs (mentor) --- usr.sbin/sysinstall/package.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/sysinstall/package.c b/usr.sbin/sysinstall/package.c index 212b654b460..9aa4589c0e5 100644 --- a/usr.sbin/sysinstall/package.c +++ b/usr.sbin/sysinstall/package.c @@ -139,7 +139,7 @@ package_extract(Device *dev, char *name, Boolean depended) /* If necessary, initialize the ldconfig hints */ if (!file_readable("/var/run/ld-elf.so.hints")) - vsystem("ldconfig /usr/lib /usr/lib/compat /usr/local/lib /usr/X11R6/lib"); + vsystem("ldconfig /usr/lib /usr/lib/compat /usr/local/lib"); /* Be initially optimistic */ ret = DITEM_SUCCESS; From 73ab91c2d6a89d739965dad67e6439d38d5202ea Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Thu, 18 Feb 2010 10:51:31 +0000 Subject: [PATCH 1464/2592] MFC r203322: Fix typo of ENOTCONN. Add missing RETURN VALUES section in sctp_opt_info(3). Approved by: rrs (mentor) --- lib/libc/net/sctp_opt_info.3 | 2 ++ lib/libc/net/sctp_recvmsg.3 | 2 +- lib/libc/net/sctp_send.3 | 2 +- lib/libc/net/sctp_sendmsg.3 | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/libc/net/sctp_opt_info.3 b/lib/libc/net/sctp_opt_info.3 index 581a220fd62..f0106133677 100644 --- a/lib/libc/net/sctp_opt_info.3 +++ b/lib/libc/net/sctp_opt_info.3 @@ -87,6 +87,8 @@ socket options. .Dv SCTP_PEER_AUTH_CHUNKS .Pp .Dv SCTP_LOCAL_AUTH_CHUNKS +.Sh RETURN VALUES +The call returns 0 on success and -1 upon error. .Sh ERRORS The .Fn sctp_opt_info diff --git a/lib/libc/net/sctp_recvmsg.3 b/lib/libc/net/sctp_recvmsg.3 index f874880f6c8..a5926bfe09a 100644 --- a/lib/libc/net/sctp_recvmsg.3 +++ b/lib/libc/net/sctp_recvmsg.3 @@ -269,7 +269,7 @@ This generally indicates that the interface has stopped sending, but may be caused by transient congestion. .It Bq Er EHOSTUNREACH The remote host was unreachable. -.It Bq Er ENOTCON +.It Bq Er ENOTCONN On a one-to-one style socket no association exists. .It Bq Er ECONNRESET An abort was received by the stack while the user was diff --git a/lib/libc/net/sctp_send.3 b/lib/libc/net/sctp_send.3 index f6f0c958dc8..010430a0e77 100644 --- a/lib/libc/net/sctp_send.3 +++ b/lib/libc/net/sctp_send.3 @@ -319,7 +319,7 @@ This generally indicates that the interface has stopped sending, but may be caused by transient congestion. .It Bq Er EHOSTUNREACH The remote host was unreachable. -.It Bq Er ENOTCON +.It Bq Er ENOTCONN On a one-to-one style socket no association exists. .It Bq Er ECONNRESET An abort was received by the stack while the user was diff --git a/lib/libc/net/sctp_sendmsg.3 b/lib/libc/net/sctp_sendmsg.3 index 0c5fa024157..52faa3168c0 100644 --- a/lib/libc/net/sctp_sendmsg.3 +++ b/lib/libc/net/sctp_sendmsg.3 @@ -296,7 +296,7 @@ This generally indicates that the interface has stopped sending, but may be caused by transient congestion. .It Bq Er EHOSTUNREACH The remote host was unreachable. -.It Bq Er ENOTCON +.It Bq Er ENOTCONN On a one-to-one style socket no association exists. .It Bq Er ECONNRESET An abort was received by the stack while the user was From ee7ee75497f3883553b425290db64c7bb05b77fc Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Thu, 18 Feb 2010 10:55:42 +0000 Subject: [PATCH 1465/2592] MFC r203323: Remove extra semicolon. Approved by: rrs (mentor) --- lib/libc/net/sctp_sys_calls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c index 715fcbd797f..d876293146a 100644 --- a/lib/libc/net/sctp_sys_calls.c +++ b/lib/libc/net/sctp_sys_calls.c @@ -784,7 +784,7 @@ sctp_sendx(int sd, const void *msg, size_t msg_len, free(buf); if (ret != 0) { if (errno == EALREADY) { - no_end_cx = 1;; + no_end_cx = 1; goto continue_send; } return (ret); From 82521c15098cf6555da13a29e20bbdda52cce088 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Thu, 18 Feb 2010 10:59:32 +0000 Subject: [PATCH 1466/2592] MFC r203678: Rename usb2_ structures and variables to usb_. Approved by: rrs (mentor) --- sys/dev/sound/usb/uaudio.c | 114 +++++++++++++++++----------------- sys/dev/sound/usb/uaudioreg.h | 42 ++++++------- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index dfbeb02c36e..069a8c04887 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -155,16 +155,16 @@ struct uaudio_chan { struct pcmchan_caps pcm_cap; /* capabilities */ struct snd_dbuf *pcm_buf; - const struct usb_config *usb2_cfg; + const struct usb_config *usb_cfg; struct mtx *pcm_mtx; /* lock protecting this structure */ struct uaudio_softc *priv_sc; struct pcm_channel *pcm_ch; struct usb_xfer *xfer[UAUDIO_NCHANBUFS]; - const struct usb2_audio_streaming_interface_descriptor *p_asid; - const struct usb2_audio_streaming_type1_descriptor *p_asf1d; - const struct usb2_audio_streaming_endpoint_descriptor *p_sed; - const usb2_endpoint_descriptor_audio_t *p_ed1; - const usb2_endpoint_descriptor_audio_t *p_ed2; + const struct usb_audio_streaming_interface_descriptor *p_asid; + const struct usb_audio_streaming_type1_descriptor *p_asf1d; + const struct usb_audio_streaming_endpoint_descriptor *p_sed; + const usb_endpoint_descriptor_audio_t *p_ed1; + const usb_endpoint_descriptor_audio_t *p_ed2; const struct uaudio_format *p_fmt; uint8_t *buf; /* pointer to buffer */ @@ -278,13 +278,13 @@ struct uaudio_search_result { struct uaudio_terminal_node { union { const struct usb_descriptor *desc; - const struct usb2_audio_input_terminal *it; - const struct usb2_audio_output_terminal *ot; - const struct usb2_audio_mixer_unit_0 *mu; - const struct usb2_audio_selector_unit *su; - const struct usb2_audio_feature_unit *fu; - const struct usb2_audio_processing_unit_0 *pu; - const struct usb2_audio_extension_unit_0 *eu; + const struct usb_audio_input_terminal *it; + const struct usb_audio_output_terminal *ot; + const struct usb_audio_mixer_unit_0 *mu; + const struct usb_audio_selector_unit *su; + const struct usb_audio_feature_unit *fu; + const struct usb_audio_processing_unit_0 *pu; + const struct usb_audio_extension_unit_0 *eu; } u; struct uaudio_search_result usr; struct uaudio_terminal_node *root; @@ -359,7 +359,7 @@ static void uaudio_mixer_add_mixer(struct uaudio_softc *, static void uaudio_mixer_add_selector(struct uaudio_softc *, const struct uaudio_terminal_node *, int); static uint32_t uaudio_mixer_feature_get_bmaControls( - const struct usb2_audio_feature_unit *, uint8_t); + const struct usb_audio_feature_unit *, uint8_t); static void uaudio_mixer_add_feature(struct uaudio_softc *, const struct uaudio_terminal_node *, int); static void uaudio_mixer_add_processing_updown(struct uaudio_softc *, @@ -368,7 +368,7 @@ static void uaudio_mixer_add_processing(struct uaudio_softc *, const struct uaudio_terminal_node *, int); static void uaudio_mixer_add_extension(struct uaudio_softc *, const struct uaudio_terminal_node *, int); -static struct usb2_audio_cluster uaudio_mixer_get_cluster(uint8_t, +static struct usb_audio_cluster uaudio_mixer_get_cluster(uint8_t, const struct uaudio_terminal_node *); static uint16_t uaudio_mixer_determine_class(const struct uaudio_terminal_node *, struct uaudio_mixer_node *); @@ -408,7 +408,7 @@ static int32_t umidi_detach(device_t dev); #if USB_DEBUG static void uaudio_chan_dump_ep_desc( - const usb2_endpoint_descriptor_audio_t *); + const usb_endpoint_descriptor_audio_t *); static void uaudio_mixer_dump_cluster(uint8_t, const struct uaudio_terminal_node *); static const char *uaudio_mixer_get_terminal_name(uint16_t); @@ -782,7 +782,7 @@ uaudio_detach(device_t dev) #if USB_DEBUG static void -uaudio_chan_dump_ep_desc(const usb2_endpoint_descriptor_audio_t *ed) +uaudio_chan_dump_ep_desc(const usb_endpoint_descriptor_audio_t *ed) { if (ed) { DPRINTF("endpoint=%p bLength=%d bDescriptorType=%d \n" @@ -803,11 +803,11 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev, uint32_t rate, uint8_t channels, uint8_t bit_resolution) { struct usb_descriptor *desc = NULL; - const struct usb2_audio_streaming_interface_descriptor *asid = NULL; - const struct usb2_audio_streaming_type1_descriptor *asf1d = NULL; - const struct usb2_audio_streaming_endpoint_descriptor *sed = NULL; - const usb2_endpoint_descriptor_audio_t *ed1 = NULL; - const usb2_endpoint_descriptor_audio_t *ed2 = NULL; + const struct usb_audio_streaming_interface_descriptor *asid = NULL; + const struct usb_audio_streaming_type1_descriptor *asf1d = NULL; + const struct usb_audio_streaming_endpoint_descriptor *sed = NULL; + const usb_endpoint_descriptor_audio_t *ed1 = NULL; + const usb_endpoint_descriptor_audio_t *ed2 = NULL; struct usb_config_descriptor *cd = usbd_get_config_descriptor(udev); struct usb_interface_descriptor *id; const struct uaudio_format *p_fmt; @@ -1045,10 +1045,10 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev, chan->iface_alt_index = alt_index; if (ep_dir == UE_DIR_IN) - chan->usb2_cfg = + chan->usb_cfg = uaudio_cfg_record; else - chan->usb2_cfg = + chan->usb_cfg = uaudio_cfg_play; chan->sample_size = (( @@ -1429,7 +1429,7 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b, } } if (usbd_transfer_setup(sc->sc_udev, &iface_index, ch->xfer, - ch->usb2_cfg, UAUDIO_NCHANBUFS, ch, ch->pcm_mtx)) { + ch->usb_cfg, UAUDIO_NCHANBUFS, ch, ch->pcm_mtx)) { DPRINTF("could not allocate USB transfers!\n"); goto error; } @@ -1709,7 +1709,7 @@ uaudio_mixer_add_input(struct uaudio_softc *sc, const struct uaudio_terminal_node *iot, int id) { #if USB_DEBUG - const struct usb2_audio_input_terminal *d = iot[id].u.it; + const struct usb_audio_input_terminal *d = iot[id].u.it; DPRINTFN(3, "bTerminalId=%d wTerminalType=0x%04x " "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d " @@ -1725,7 +1725,7 @@ uaudio_mixer_add_output(struct uaudio_softc *sc, const struct uaudio_terminal_node *iot, int id) { #if USB_DEBUG - const struct usb2_audio_output_terminal *d = iot[id].u.ot; + const struct usb_audio_output_terminal *d = iot[id].u.ot; DPRINTFN(3, "bTerminalId=%d wTerminalType=0x%04x " "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n", @@ -1740,8 +1740,8 @@ uaudio_mixer_add_mixer(struct uaudio_softc *sc, { struct uaudio_mixer_node mix; - const struct usb2_audio_mixer_unit_0 *d0 = iot[id].u.mu; - const struct usb2_audio_mixer_unit_1 *d1; + const struct usb_audio_mixer_unit_0 *d0 = iot[id].u.mu; + const struct usb_audio_mixer_unit_1 *d1; uint32_t bno; /* bit number */ uint32_t p; /* bit number accumulator */ @@ -1823,7 +1823,7 @@ static void uaudio_mixer_add_selector(struct uaudio_softc *sc, const struct uaudio_terminal_node *iot, int id) { - const struct usb2_audio_selector_unit *d = iot[id].u.su; + const struct usb_audio_selector_unit *d = iot[id].u.su; struct uaudio_mixer_node mix; uint16_t i; @@ -1864,7 +1864,7 @@ uaudio_mixer_add_selector(struct uaudio_softc *sc, } static uint32_t -uaudio_mixer_feature_get_bmaControls(const struct usb2_audio_feature_unit *d, +uaudio_mixer_feature_get_bmaControls(const struct usb_audio_feature_unit *d, uint8_t index) { uint32_t temp = 0; @@ -1889,7 +1889,7 @@ static void uaudio_mixer_add_feature(struct uaudio_softc *sc, const struct uaudio_terminal_node *iot, int id) { - const struct usb2_audio_feature_unit *d = iot[id].u.fu; + const struct usb_audio_feature_unit *d = iot[id].u.fu; struct uaudio_mixer_node mix; uint32_t fumask; uint32_t mmask; @@ -2015,10 +2015,10 @@ static void uaudio_mixer_add_processing_updown(struct uaudio_softc *sc, const struct uaudio_terminal_node *iot, int id) { - const struct usb2_audio_processing_unit_0 *d0 = iot[id].u.pu; - const struct usb2_audio_processing_unit_1 *d1 = + const struct usb_audio_processing_unit_0 *d0 = iot[id].u.pu; + const struct usb_audio_processing_unit_1 *d1 = (const void *)(d0->baSourceId + d0->bNrInPins); - const struct usb2_audio_processing_unit_updown *ud = + const struct usb_audio_processing_unit_updown *ud = (const void *)(d1->bmControls + d1->bControlSize); struct uaudio_mixer_node mix; uint8_t i; @@ -2057,8 +2057,8 @@ static void uaudio_mixer_add_processing(struct uaudio_softc *sc, const struct uaudio_terminal_node *iot, int id) { - const struct usb2_audio_processing_unit_0 *d0 = iot[id].u.pu; - const struct usb2_audio_processing_unit_1 *d1 = + const struct usb_audio_processing_unit_0 *d0 = iot[id].u.pu; + const struct usb_audio_processing_unit_1 *d1 = (const void *)(d0->baSourceId + d0->bNrInPins); struct uaudio_mixer_node mix; uint16_t ptype; @@ -2102,8 +2102,8 @@ static void uaudio_mixer_add_extension(struct uaudio_softc *sc, const struct uaudio_terminal_node *iot, int id) { - const struct usb2_audio_extension_unit_0 *d0 = iot[id].u.eu; - const struct usb2_audio_extension_unit_1 *d1 = + const struct usb_audio_extension_unit_0 *d0 = iot[id].u.eu; + const struct usb_audio_extension_unit_1 *d1 = (const void *)(d0->baSourceId + d0->bNrInPins); struct uaudio_mixer_node mix; @@ -2133,19 +2133,19 @@ uaudio_mixer_add_extension(struct uaudio_softc *sc, static const void * uaudio_mixer_verify_desc(const void *arg, uint32_t len) { - const struct usb2_audio_mixer_unit_1 *d1; - const struct usb2_audio_extension_unit_1 *e1; - const struct usb2_audio_processing_unit_1 *u1; + const struct usb_audio_mixer_unit_1 *d1; + const struct usb_audio_extension_unit_1 *e1; + const struct usb_audio_processing_unit_1 *u1; union { const struct usb_descriptor *desc; - const struct usb2_audio_input_terminal *it; - const struct usb2_audio_output_terminal *ot; - const struct usb2_audio_mixer_unit_0 *mu; - const struct usb2_audio_selector_unit *su; - const struct usb2_audio_feature_unit *fu; - const struct usb2_audio_processing_unit_0 *pu; - const struct usb2_audio_extension_unit_0 *eu; + const struct usb_audio_input_terminal *it; + const struct usb_audio_output_terminal *ot; + const struct usb_audio_mixer_unit_0 *mu; + const struct usb_audio_selector_unit *su; + const struct usb_audio_feature_unit *fu; + const struct usb_audio_processing_unit_0 *pu; + const struct usb_audio_extension_unit_0 *eu; } u; u.desc = arg; @@ -2269,7 +2269,7 @@ uaudio_mixer_dump_cluster(uint8_t id, const struct uaudio_terminal_node *iot) }; uint16_t cc; uint8_t i; - const struct usb2_audio_cluster cl = uaudio_mixer_get_cluster(id, iot); + const struct usb_audio_cluster cl = uaudio_mixer_get_cluster(id, iot); cc = UGETW(cl.wChannelConfig); @@ -2286,10 +2286,10 @@ uaudio_mixer_dump_cluster(uint8_t id, const struct uaudio_terminal_node *iot) #endif -static struct usb2_audio_cluster +static struct usb_audio_cluster uaudio_mixer_get_cluster(uint8_t id, const struct uaudio_terminal_node *iot) { - struct usb2_audio_cluster r; + struct usb_audio_cluster r; const struct usb_descriptor *dp; uint8_t i; @@ -2311,7 +2311,7 @@ uaudio_mixer_get_cluster(uint8_t id, const struct uaudio_terminal_node *iot) break; case UDESCSUB_AC_MIXER: - r = *(const struct usb2_audio_cluster *) + r = *(const struct usb_audio_cluster *) &iot[id].u.mu->baSourceId[iot[id].u.mu-> bNrInPins]; goto done; @@ -2328,13 +2328,13 @@ uaudio_mixer_get_cluster(uint8_t id, const struct uaudio_terminal_node *iot) break; case UDESCSUB_AC_PROCESSING: - r = *((const struct usb2_audio_cluster *) + r = *((const struct usb_audio_cluster *) &iot[id].u.pu->baSourceId[iot[id].u.pu-> bNrInPins]); goto done; case UDESCSUB_AC_EXTENSION: - r = *((const struct usb2_audio_cluster *) + r = *((const struct usb_audio_cluster *) &iot[id].u.eu->baSourceId[iot[id].u.eu-> bNrInPins]); goto done; @@ -2760,10 +2760,10 @@ static void uaudio_mixer_fill_info(struct uaudio_softc *sc, struct usb_device *udev, void *desc) { - const struct usb2_audio_control_descriptor *acdp; + const struct usb_audio_control_descriptor *acdp; struct usb_config_descriptor *cd = usbd_get_config_descriptor(udev); const struct usb_descriptor *dp; - const struct usb2_audio_unit *au; + const struct usb_audio_unit *au; struct uaudio_terminal_node *iot = NULL; uint16_t wTotalLen; uint8_t ID_max = 0; /* inclusive */ diff --git a/sys/dev/sound/usb/uaudioreg.h b/sys/dev/sound/usb/uaudioreg.h index 495f94a8b96..0df4ea525f0 100644 --- a/sys/dev/sound/usb/uaudioreg.h +++ b/sys/dev/sound/usb/uaudioreg.h @@ -64,9 +64,9 @@ typedef struct { */ uByte bRefresh; uByte bSynchAddress; -} __packed usb2_endpoint_descriptor_audio_t; +} __packed usb_endpoint_descriptor_audio_t; -struct usb2_audio_control_descriptor { +struct usb_audio_control_descriptor { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -76,7 +76,7 @@ struct usb2_audio_control_descriptor { uByte baInterfaceNr[1]; } __packed; -struct usb2_audio_streaming_interface_descriptor { +struct usb_audio_streaming_interface_descriptor { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -85,7 +85,7 @@ struct usb2_audio_streaming_interface_descriptor { uWord wFormatTag; } __packed; -struct usb2_audio_streaming_endpoint_descriptor { +struct usb_audio_streaming_endpoint_descriptor { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -97,7 +97,7 @@ struct usb2_audio_streaming_endpoint_descriptor { uWord wLockDelay; } __packed; -struct usb2_audio_streaming_type1_descriptor { +struct usb_audio_streaming_type1_descriptor { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -115,7 +115,7 @@ struct usb2_audio_streaming_type1_descriptor { #define UA_SAMP_HI(p) UA_GETSAMP(p, 1) } __packed; -struct usb2_audio_cluster { +struct usb_audio_cluster { uByte bNrChannels; uWord wChannelConfig; #define UA_CHANNEL_LEFT 0x0001 @@ -134,7 +134,7 @@ struct usb2_audio_cluster { } __packed; /* Shared by all units and terminals */ -struct usb2_audio_unit { +struct usb_audio_unit { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -142,7 +142,7 @@ struct usb2_audio_unit { }; /* UDESCSUB_AC_INPUT */ -struct usb2_audio_input_terminal { +struct usb_audio_input_terminal { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -156,7 +156,7 @@ struct usb2_audio_input_terminal { } __packed; /* UDESCSUB_AC_OUTPUT */ -struct usb2_audio_output_terminal { +struct usb_audio_output_terminal { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -168,16 +168,16 @@ struct usb2_audio_output_terminal { } __packed; /* UDESCSUB_AC_MIXER */ -struct usb2_audio_mixer_unit_0 { +struct usb_audio_mixer_unit_0 { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; uByte bUnitId; uByte bNrInPins; uByte baSourceId[0]; /* [bNrInPins] */ - /* struct usb2_audio_mixer_unit_1 */ + /* struct usb_audio_mixer_unit_1 */ } __packed; -struct usb2_audio_mixer_unit_1 { +struct usb_audio_mixer_unit_1 { uByte bNrChannels; uWord wChannelConfig; uByte iChannelNames; @@ -186,7 +186,7 @@ struct usb2_audio_mixer_unit_1 { } __packed; /* UDESCSUB_AC_SELECTOR */ -struct usb2_audio_selector_unit { +struct usb_audio_selector_unit { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -197,7 +197,7 @@ struct usb2_audio_selector_unit { } __packed; /* UDESCSUB_AC_FEATURE */ -struct usb2_audio_feature_unit { +struct usb_audio_feature_unit { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -209,7 +209,7 @@ struct usb2_audio_feature_unit { } __packed; /* UDESCSUB_AC_PROCESSING */ -struct usb2_audio_processing_unit_0 { +struct usb_audio_processing_unit_0 { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -217,9 +217,9 @@ struct usb2_audio_processing_unit_0 { uWord wProcessType; uByte bNrInPins; uByte baSourceId[0]; /* [bNrInPins] */ - /* struct usb2_audio_processing_unit_1 */ + /* struct usb_audio_processing_unit_1 */ } __packed; -struct usb2_audio_processing_unit_1 { +struct usb_audio_processing_unit_1 { uByte bNrChannels; uWord wChannelConfig; uByte iChannelNames; @@ -228,14 +228,14 @@ struct usb2_audio_processing_unit_1 { #define UA_PROC_ENABLE_MASK 1 } __packed; -struct usb2_audio_processing_unit_updown { +struct usb_audio_processing_unit_updown { uByte iProcessing; uByte bNrModes; uWord waModes[0]; /* [bNrModes] */ } __packed; /* UDESCSUB_AC_EXTENSION */ -struct usb2_audio_extension_unit_0 { +struct usb_audio_extension_unit_0 { uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype; @@ -243,9 +243,9 @@ struct usb2_audio_extension_unit_0 { uWord wExtensionCode; uByte bNrInPins; uByte baSourceId[0]; /* [bNrInPins] */ - /* struct usb2_audio_extension_unit_1 */ + /* struct usb_audio_extension_unit_1 */ } __packed; -struct usb2_audio_extension_unit_1 { +struct usb_audio_extension_unit_1 { uByte bNrChannels; uWord wChannelConfig; uByte iChannelNames; From 646b39536dcf0751285fd53792c09815e2a23e83 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Thu, 18 Feb 2010 11:03:35 +0000 Subject: [PATCH 1467/2592] MFC r203679: Remove the usb2_input_kbd directive that was missed during the renaming of the drivers in the usb2 stack. Approved by: rrs (mentor) --- sys/conf/files.amd64 | 2 +- sys/conf/files.i386 | 2 +- sys/conf/files.ia64 | 2 +- sys/conf/files.pc98 | 2 +- sys/conf/files.sparc64 | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 15b4a98e2eb..d7b57651518 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -205,7 +205,7 @@ dev/hwpmc/hwpmc_core.c optional hwpmc dev/hwpmc/hwpmc_piv.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc -dev/kbd/kbd.c optional atkbd | sc | ukbd | usb2_input_kbd +dev/kbd/kbd.c optional atkbd | sc | ukbd dev/lindev/full.c optional lindev dev/lindev/lindev.c optional lindev dev/mem/memutil.c optional mem diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 9ac3951a3ad..b1e60d67147 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -197,7 +197,7 @@ dev/ipmi/ipmi_smbios.c optional ipmi dev/ipmi/ipmi_ssif.c optional ipmi smbus dev/ipmi/ipmi_pci.c optional ipmi pci dev/ipmi/ipmi_linux.c optional ipmi compat_linux -dev/kbd/kbd.c optional atkbd | sc | ukbd | usb2_input_kbd +dev/kbd/kbd.c optional atkbd | sc | ukbd dev/le/if_le_isa.c optional le isa dev/lindev/full.c optional lindev dev/lindev/lindev.c optional lindev diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64 index 4ad5aa76884..d3fb6100faa 100644 --- a/sys/conf/files.ia64 +++ b/sys/conf/files.ia64 @@ -57,7 +57,7 @@ dev/fb/fb.c optional fb | vga dev/fb/vga.c optional vga dev/hwpmc/hwpmc_ia64.c optional hwpmc dev/io/iodev.c optional io -dev/kbd/kbd.c optional atkbd | sc | ukbd | usb2_input_kbd +dev/kbd/kbd.c optional atkbd | sc | ukbd dev/syscons/scterm-teken.c optional sc dev/syscons/scvgarndr.c optional sc vga dev/syscons/scvtb.c optional sc diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 7f2afc5059c..002cf86d39a 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -105,7 +105,7 @@ dev/hwpmc/hwpmc_ppro.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc dev/io/iodev.c optional io -dev/kbd/kbd.c optional pckbd | sc | ukbd | usb2_input_kbd +dev/kbd/kbd.c optional pckbd | sc | ukbd dev/le/if_le_cbus.c optional le isa dev/lindev/full.c optional lindev dev/lindev/lindev.c optional lindev diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index e5d5f7181f0..734989c2cfa 100644 --- a/sys/conf/files.sparc64 +++ b/sys/conf/files.sparc64 @@ -38,7 +38,7 @@ dev/fb/fb.c optional sc dev/fb/gallant12x22.c optional sc dev/fb/machfb.c optional machfb sc dev/hwpmc/hwpmc_sparc64.c optional hwpmc -dev/kbd/kbd.c optional atkbd | sc | ukbd | usb2_input_kbd +dev/kbd/kbd.c optional atkbd | sc | ukbd dev/le/if_le_lebuffer.c optional le sbus dev/le/if_le_ledma.c optional le sbus dev/le/lebuffer_sbus.c optional le sbus From dfbcd9079096c8c380bd980e868aed36a52d37fa Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Thu, 18 Feb 2010 11:07:36 +0000 Subject: [PATCH 1468/2592] MFC r203685: Document the usfs driver and the NO_SYSCTL_DESCR option, and update the comment for umass. Don't include the sysctl description variables in aic7xxx when NO_SYSCTL_DESCR is used. Approved by: rrs (mentor) --- sys/conf/NOTES | 9 ++++++++- sys/dev/aic7xxx/aic79xx_osm.c | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 3d737246a9a..f3058d2dc0f 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -376,6 +376,11 @@ options KDTRACE_HOOKS # options SYSCTL_DEBUG +# +# NO_SYSCTL_DESCR omits the sysctl node descriptions to save space in the +# resulting kernel. +options NO_SYSCTL_DESCR + # # DEBUG_MEMGUARD builds and enables memguard(9), a replacement allocator # for the kernel used to detect modify-after-free scenarios. See the @@ -2529,8 +2534,10 @@ device uhid device ukbd # USB printer device ulpt -# USB Iomega Zip 100 Drive (Requires scbus and da) +# USB mass storage driver (Requires scbus and da) device umass +# USB mass storage driver for device-side mode +device usfs # USB support for Belkin F5U109 and Magic Control Technology serial adapters device umct # USB modem support diff --git a/sys/dev/aic7xxx/aic79xx_osm.c b/sys/dev/aic7xxx/aic79xx_osm.c index 81eade6d4f7..375de63ae82 100644 --- a/sys/dev/aic7xxx/aic79xx_osm.c +++ b/sys/dev/aic7xxx/aic79xx_osm.c @@ -83,11 +83,13 @@ static const char *ahd_sysctl_node_elements[] = { "debug" }; +#ifndef NO_SYSCTL_DESCR static const char *ahd_sysctl_node_descriptions[] = { "root error collection for aic79xx controllers", "summary collection for aic79xx controllers", "debug collection for aic79xx controllers" }; +#endif static const char *ahd_sysctl_errors_elements[] = { "Cerrors", @@ -95,11 +97,13 @@ static const char *ahd_sysctl_errors_elements[] = { "Ferrors" }; +#ifndef NO_SYSCTL_DESCR static const char *ahd_sysctl_errors_descriptions[] = { "Correctable errors", "Uncorrectable errors", "Fatal errors" }; +#endif static int ahd_set_debugcounters(SYSCTL_HANDLER_ARGS) From 3322939bbb27db717cda2f2dc9911d39fce284ca Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 18 Feb 2010 16:23:13 +0000 Subject: [PATCH 1469/2592] MFC: r203848 This fixes the experimental NFS server so that it won't crash in the caching code for IPv6 by fixing a typo that used the incorrect variable. It also fixes the indentation of the statement above it. Reported by: simon AT comsys.ntu-kpi.kiev.ua --- sys/fs/nfsserver/nfs_nfsdcache.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdcache.c b/sys/fs/nfsserver/nfs_nfsdcache.c index 2598fb83b3a..b91229f3677 100644 --- a/sys/fs/nfsserver/nfs_nfsdcache.c +++ b/sys/fs/nfsserver/nfs_nfsdcache.c @@ -386,9 +386,9 @@ loop: newrp->rc_inet = saddr->sin_addr.s_addr; else if (saddr->sin_family == AF_INET6) { saddr6 = (struct sockaddr_in6 *)saddr; - NFSBCOPY((caddr_t)&saddr6->sin6_addr,(caddr_t)&newrp->rc_inet6, - sizeof (struct in6_addr)); - rp->rc_flag |= RC_INETIPV6; + NFSBCOPY((caddr_t)&saddr6->sin6_addr, (caddr_t)&newrp->rc_inet6, + sizeof (struct in6_addr)); + newrp->rc_flag |= RC_INETIPV6; } LIST_INSERT_HEAD(hp, newrp, rc_hash); TAILQ_INSERT_TAIL(&nfsrvudplru, newrp, rc_lru); From 3343356549a49cbfdf281e254f6095e15768fc76 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Thu, 18 Feb 2010 16:52:49 +0000 Subject: [PATCH 1470/2592] MFC: r203918: Unbreak makefiles by removing mentions of DEFAULT_THREAD_LIB. --- lib/libc_r/Makefile | 16 ---------------- lib/libkse/Makefile | 20 -------------------- 2 files changed, 36 deletions(-) diff --git a/lib/libc_r/Makefile b/lib/libc_r/Makefile index 0b286f2161d..a4248764545 100644 --- a/lib/libc_r/Makefile +++ b/lib/libc_r/Makefile @@ -10,10 +10,6 @@ .include -.if ${DEFAULT_THREAD_LIB} == "libc_r" && ${SHLIBDIR} == "/usr/lib" -SHLIBDIR= /lib -.endif - LIB=c_r SHLIB_MAJOR= 7 CFLAGS+=-DPTHREAD_KERNEL @@ -32,16 +28,4 @@ PRECIOUSLIB= .include "${.CURDIR}/uthread/Makefile.inc" .include "${.CURDIR}/sys/Makefile.inc" -.if ${DEFAULT_THREAD_LIB} == "libc_r" -.if ${MK_INSTALLLIB} != "no" -SYMLINKS+=lib${LIB}.a ${LIBDIR}/libpthread.a -.endif -.if !defined(NO_PIC) -SYMLINKS+=lib${LIB}.so ${LIBDIR}/libpthread.so -.endif -.if ${MK_PROFILE} != "no" -SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libpthread_p.a -.endif -.endif - .include diff --git a/lib/libkse/Makefile b/lib/libkse/Makefile index 9fe09c564bd..c4e2b5abc21 100644 --- a/lib/libkse/Makefile +++ b/lib/libkse/Makefile @@ -10,15 +10,7 @@ .include -.if ${DEFAULT_THREAD_LIB} == "libkse" || ${MK_LIBTHR} == "no" -LIB=kse -.if ${SHLIBDIR} == "/usr/lib" -SHLIBDIR= /lib -.endif -.else SHLIB=kse -.endif - SHLIB_MAJOR= 4 CFLAGS+=-DPTHREAD_KERNEL CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR}/thread \ @@ -51,16 +43,4 @@ PRECIOUSLIB= .include "${.CURDIR}/sys/Makefile.inc" .include "${.CURDIR}/thread/Makefile.inc" -.if ${DEFAULT_THREAD_LIB} == "libkse" || ${MK_LIBTHR} == "no" -.if ${MK_INSTALLLIB} != "no" -SYMLINKS+=lib${LIB}.a ${LIBDIR}/libpthread.a -.endif -.if !defined(NO_PIC) -SYMLINKS+=lib${LIB}.so ${LIBDIR}/libpthread.so -.endif -.if ${MK_PROFILE} != "no" -SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libpthread_p.a -.endif -.endif - .include From 3ed680d8daed05c8c69eb8bf03ea9c30e7947aaf Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 19 Feb 2010 16:36:08 +0000 Subject: [PATCH 1471/2592] MFC: r203849 Change the default value for vfs.newnfs.enable_locallocks to 0 for the experimental NFS server, since local locking is known to be broken and the patch to fix it is still a work in progress. --- sys/fs/nfsserver/nfs_nfsdstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index ba97c545e52..3e38cf48e1f 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$"); struct nfsrv_stablefirst nfsrv_stablefirst; int nfsrv_issuedelegs = 0; -int nfsrv_dolocallocks = 1; +int nfsrv_dolocallocks = 0; struct nfsv4lock nfsv4rootfs_lock; extern int newnfs_numnfsd; From 04c9f4b6d07bf9ede73eb88f1908736d17980fe6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 19 Feb 2010 17:45:47 +0000 Subject: [PATCH 1472/2592] MFC r203931: Make CD driver a bit more robust and predictable to unreported errors. --- sys/cam/scsi/scsi_cd.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index 72454e2ea4c..db916fd70f5 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -638,15 +638,14 @@ cdregister(struct cam_periph *periph, void *arg) return(CAM_REQ_CMP_ERR); } - softc = (struct cd_softc *)malloc(sizeof(*softc),M_DEVBUF,M_NOWAIT); - + softc = (struct cd_softc *)malloc(sizeof(*softc),M_DEVBUF, + M_NOWAIT | M_ZERO); if (softc == NULL) { printf("cdregister: Unable to probe new device. " "Unable to allocate softc\n"); return(CAM_REQ_CMP_ERR); } - bzero(softc, sizeof(*softc)); LIST_INIT(&softc->pending_ccbs); STAILQ_INIT(&softc->mode_queue); softc->state = CD_STATE_PROBE; @@ -861,8 +860,7 @@ cdregister(struct cam_periph *periph, void *arg) */ else { nchanger = malloc(sizeof(struct cdchanger), - M_DEVBUF, M_NOWAIT); - + M_DEVBUF, M_NOWAIT | M_ZERO); if (nchanger == NULL) { softc->flags &= ~CD_FLAG_CHANGER; printf("cdregister: unable to malloc " @@ -875,10 +873,6 @@ cdregister(struct cam_periph *periph, void *arg) */ goto cdregisterexit; } - - /* zero the structure */ - bzero(nchanger, sizeof(struct cdchanger)); - if (camq_init(&nchanger->devq, 1) != 0) { softc->flags &= ~CD_FLAG_CHANGER; printf("cdregister: changer support " @@ -1506,8 +1500,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) { rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcap), - M_SCSICD, - M_NOWAIT); + M_SCSICD, M_NOWAIT | M_ZERO); if (rcap == NULL) { xpt_print(periph->path, "cdstart: Couldn't malloc read_capacity data\n"); @@ -2073,7 +2066,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) u_int32_t len = args->data_len; data = malloc(sizeof(struct cd_sub_channel_info), - M_SCSICD, M_WAITOK); + M_SCSICD, M_WAITOK | M_ZERO); cam_periph_lock(periph); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, @@ -2125,7 +2118,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) struct ioc_toc_header *th; th = malloc(sizeof(struct ioc_toc_header), M_SCSICD, - M_WAITOK); + M_WAITOK | M_ZERO); cam_periph_lock(periph); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, @@ -2162,8 +2155,8 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) u_int32_t len, readlen, idx, num; u_int32_t starting_track = te->starting_track; - data = malloc(sizeof(*data), M_SCSICD, M_WAITOK); - lead = malloc(sizeof(*lead), M_SCSICD, M_WAITOK); + data = malloc(sizeof(*data), M_SCSICD, M_WAITOK | M_ZERO); + lead = malloc(sizeof(*lead), M_SCSICD, M_WAITOK | M_ZERO); cam_periph_lock(periph); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, @@ -2291,7 +2284,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) struct ioc_toc_header *th; u_int32_t track; - data = malloc(sizeof(*data), M_SCSICD, M_WAITOK); + data = malloc(sizeof(*data), M_SCSICD, M_WAITOK | M_ZERO); cam_periph_lock(periph); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, @@ -2910,7 +2903,7 @@ cdsize(struct cam_periph *periph, u_int32_t *size) /* XXX Should be M_WAITOK */ rcap_buf = malloc(sizeof(struct scsi_read_capacity_data), - M_SCSICD, M_NOWAIT); + M_SCSICD, M_NOWAIT | M_ZERO); if (rcap_buf == NULL) return (ENOMEM); @@ -2929,6 +2922,9 @@ cdsize(struct cam_periph *periph, u_int32_t *size) softc->params.disksize = scsi_4btoul(rcap_buf->addr) + 1; softc->params.blksize = scsi_4btoul(rcap_buf->length); + /* Make sure we got at least some block size. */ + if (error == 0 && softc->params.blksize == 0) + error = EIO; /* * SCSI-3 mandates that the reported blocksize shall be 2048. * Older drives sometimes report funny values, trim it down to From c48c2a2389744dbc0db797db5a044b9725e7f869 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 19 Feb 2010 17:54:03 +0000 Subject: [PATCH 1473/2592] MFC r203873: With FBS enabled, we have no idea what command caused timeout. Implement same logic as in siis(4) - wait for other commands complete or timeout and then give some more time. --- sys/dev/ahci/ahci.c | 89 +++++++++++++++++++++++++++++++++++++-------- sys/dev/ahci/ahci.h | 1 + 2 files changed, 75 insertions(+), 15 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 5e2315b16aa..4e1797edf77 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1657,6 +1657,45 @@ ahci_execute_transaction(struct ahci_slot *slot) return; } +/* Must be called with channel locked. */ +static void +ahci_process_timeout(device_t dev) +{ + struct ahci_channel *ch = device_get_softc(dev); + int i; + + mtx_assert(&ch->mtx, MA_OWNED); + /* 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) + continue; + ahci_end_transaction(&ch->slot[i], AHCI_ERR_TIMEOUT); + } +} + +/* Must be called with channel locked. */ +static void +ahci_rearm_timeout(device_t dev) +{ + struct ahci_channel *ch = device_get_softc(dev); + int i; + + mtx_assert(&ch->mtx, MA_OWNED); + for (i = 0; i < ch->numslots; i++) { + struct ahci_slot *slot = &ch->slot[i]; + + /* Do we have a running request on slot? */ + if (slot->state < AHCI_SLOT_RUNNING) + continue; + if ((ch->toslots & (1 << i)) == 0) + continue; + callout_reset(&slot->timeout, + (int)slot->ccb->ccb_h.timeout * hz / 2000, + (timeout_t*)ahci_timeout, slot); + } +} + /* Locked by callout mechanism. */ static void ahci_timeout(struct ahci_slot *slot) @@ -1693,7 +1732,6 @@ ahci_timeout(struct ahci_slot *slot) 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)); - ch->fatalerr = 1; /* Handle frozen command. */ if (ch->frozen) { union ccb *fccb = ch->frozen; @@ -1705,14 +1743,28 @@ ahci_timeout(struct ahci_slot *slot) } 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) - continue; - ahci_end_transaction(&ch->slot[i], AHCI_ERR_INNOCENT); + if (!ch->fbs_enabled) { + /* Without FBS we know real timeout source. */ + ch->fatalerr = 1; + /* 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) + continue; + ahci_end_transaction(&ch->slot[i], AHCI_ERR_INNOCENT); + } + } else { + /* With FBS we wait for other commands timeout and pray. */ + if (ch->toslots == 0) + xpt_freeze_simq(ch->sim, 1); + ch->toslots |= (1 << slot->slot); + if ((ch->rslots & ~ch->toslots) == 0) + ahci_process_timeout(dev); + else + device_printf(dev, " ... waiting for slots %08x\n", + ch->rslots & ~ch->toslots); } } @@ -1809,10 +1861,6 @@ 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; @@ -1828,6 +1876,11 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) ch->oslots &= ~(1 << slot->slot); ch->rslots &= ~(1 << slot->slot); ch->aslots &= ~(1 << slot->slot); + if (et != AHCI_ERR_TIMEOUT) { + if (ch->toslots == (1 << slot->slot)) + xpt_release_simq(ch->sim, TRUE); + ch->toslots &= ~(1 << slot->slot); + } slot->state = AHCI_SLOT_EMPTY; slot->ccb = NULL; /* Update channel stats. */ @@ -1867,7 +1920,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) /* If we have no other active commands, ... */ if (ch->rslots == 0) { /* if there was fatal error - reset port. */ - if (ch->fatalerr) { + if (ch->toslots != 0 || ch->fatalerr) { ahci_reset(dev); } else { /* if we have slots in error, we can reinit port. */ @@ -1879,7 +1932,10 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) if (!ch->readlog && ch->numhslots) ahci_issue_read_log(dev); } - } + /* If all the rest of commands are in timeout - give them chance. */ + } else if ((ch->rslots & ~ch->toslots) == 0 && + et != AHCI_ERR_TIMEOUT) + ahci_rearm_timeout(dev); /* Start PM timer. */ if (ch->numrslots == 0 && ch->pm_level > 3) { callout_schedule(&ch->pm_timer, @@ -2143,7 +2199,10 @@ ahci_reset(device_t dev) ch->hold[i] = NULL; ch->numhslots--; } + if (ch->toslots != 0) + xpt_release_simq(ch->sim, TRUE); ch->eslots = 0; + ch->toslots = 0; ch->fatalerr = 0; /* Tell the XPT about the event */ xpt_async(AC_BUS_RESET, ch->path, NULL); diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index a2cc5a00f75..d4c73c9cfe5 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -401,6 +401,7 @@ struct ahci_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 numrslotspd[16];/* Number of running slots per dev */ int numtslots; /* Number of tagged slots */ From 210a19d01411b66aac312de8ddc7d39280106c56 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 19 Feb 2010 18:07:51 +0000 Subject: [PATCH 1474/2592] MFC r203528: Add pci_get|set_max_read_req() helper functions to control maximum PCIe read request size. --- sys/dev/pci/pci.c | 34 ++++++++++++++++++++++++++++++++++ sys/dev/pci/pcivar.h | 3 +++ 2 files changed, 37 insertions(+) diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index b76e2e7103b..650e2141b70 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1592,6 +1592,40 @@ pci_ht_map_msi(device_t dev, uint64_t addr) } } +int +pci_get_max_read_req(device_t dev) +{ + int cap; + uint16_t val; + + if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) != 0) + return (0); + val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2); + val &= PCIM_EXP_CTL_MAX_READ_REQUEST; + val >>= 12; + return (1 << (val + 7)); +} + +int +pci_set_max_read_req(device_t dev, int size) +{ + int cap; + uint16_t val; + + if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) != 0) + return (0); + if (size < 128) + size = 128; + if (size > 4096) + size = 4096; + size = (1 << (fls(size) - 1)); + val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2); + val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST; + val |= (fls(size) - 8) << 12; + pci_write_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, val, 2); + return (size); +} + /* * Support for MSI message signalled interrupts. */ diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index d7de96e6562..948370813e2 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -458,6 +458,9 @@ int pci_msi_device_blacklisted(device_t dev); void pci_ht_map_msi(device_t dev, uint64_t addr); +int pci_get_max_read_req(device_t dev); +int pci_set_max_read_req(device_t dev, int size); + #endif /* _SYS_BUS_H_ */ /* From a510b78b19774747f20eb973e6486d117a7059d6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 19 Feb 2010 18:15:45 +0000 Subject: [PATCH 1475/2592] MFC r200291, r203529: Increase Max Read Request Size for PCIe chips from 512 to 1024 bytes. It gives those beasts additional 10% of write bandwidth. Use new helper functions to do it. --- sys/dev/siis/siis.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 74806fd7bc8..29afa2a4052 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -231,6 +231,9 @@ siis_resume(device_t dev) { struct siis_controller *ctlr = device_get_softc(dev); + /* Set PCIe max read request size to at least 1024 bytes */ + if (pci_get_max_read_req(dev) < 1024) + pci_set_max_read_req(dev, 1024); /* Put controller into reset state. */ ctlr->gctl |= SIIS_GCTL_GRESET; ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl); From c84124c0d4e471ec5d1b19b12e14a710e2b1020a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 20 Feb 2010 11:50:50 +0000 Subject: [PATCH 1476/2592] MFC r203818: Clear the bp pointer when buffer is already brelse()d. --- sys/ufs/ffs/ffs_alloc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index b4f001e6c67..b758f2c5adf 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -425,8 +425,10 @@ nospace: reclaimed = 1; softdep_request_cleanup(fs, vp); UFS_UNLOCK(ump); - if (bp) + if (bp) { brelse(bp); + bp = NULL; + } UFS_LOCK(ump); goto retry; } From bc6c9c912cd3e521af10428e6c3e1046cb1ce873 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 20 Feb 2010 11:54:18 +0000 Subject: [PATCH 1477/2592] MFC r203822: Remove unused macros. --- sys/fs/msdosfs/denode.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/fs/msdosfs/denode.h b/sys/fs/msdosfs/denode.h index 5d68d6fabb4..4fd306cf620 100644 --- a/sys/fs/msdosfs/denode.h +++ b/sys/fs/msdosfs/denode.h @@ -207,9 +207,6 @@ struct denode { ((dep)->de_Attributes & ATTR_DIRECTORY) ? 0 : (dep)->de_FileSize), \ putushort((dp)->deHighClust, (dep)->de_StartCluster >> 16)) -#define de_forw de_chain[0] -#define de_back de_chain[1] - #ifdef _KERNEL #define VTODE(vp) ((struct denode *)(vp)->v_data) From fe5e7466179f9fc9b37d8183e6848f55442714e0 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 20 Feb 2010 11:58:19 +0000 Subject: [PATCH 1478/2592] MFC r203826: Use M_ZERO instead of calling bzero(). Fix function name in the comment. MFC r203828: Fix function name in the comment in the second location too. --- sys/fs/msdosfs/msdosfs_denode.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c index d4614847d14..b689b5d3ae0 100644 --- a/sys/fs/msdosfs/msdosfs_denode.c +++ b/sys/fs/msdosfs/msdosfs_denode.c @@ -144,11 +144,11 @@ deget(pmp, dirclust, diroffset, depp) } /* - * Do the MALLOC before the getnewvnode since doing so afterward + * Do the malloc before the getnewvnode since doing so afterward * might cause a bogus v_data pointer to get dereferenced - * elsewhere if MALLOC should block. + * elsewhere if malloc should block. */ - ldep = malloc(sizeof(struct denode), M_MSDOSFSNODE, M_WAITOK); + ldep = malloc(sizeof(struct denode), M_MSDOSFSNODE, M_WAITOK | M_ZERO); /* * Directory entry was not in cache, have to create a vnode and @@ -161,7 +161,6 @@ deget(pmp, dirclust, diroffset, depp) free(ldep, M_MSDOSFSNODE); return error; } - bzero((caddr_t)ldep, sizeof *ldep); nvp->v_data = ldep; ldep->de_vnode = nvp; ldep->de_flag = 0; From 6335f05c513d155d2b87bca5570a39f9d302920f Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sat, 20 Feb 2010 12:48:44 +0000 Subject: [PATCH 1479/2592] MFC from head to stable/8: r202896: Unbreak world: - WITHOUT_OPENSSH (and WITH_KERBEROS) - WITHOUT_KERBEROS and WITH_GSSAPI PR: 137483 Submitted by: bf r203016 by ru@: Regen the list of prebuild libraries using tools/make_libdeps.sh. Reviewed by: ru@ --- Makefile.inc1 | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index ad237dd0f18..2866c00da63 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1087,19 +1087,19 @@ _startup_libs+= lib/libc gnu/lib/libgcc__L: lib/libc__L -_prebuild_libs= ${_kerberos5_lib_libasn1} ${_kerberos5_lib_libkrb5} \ - ${_kerberos5_lib_libhx509} ${_kerberos5_lib_libroken} \ - ${_kerberos5_lib_libheimntlm} ${_kerberos5_lib_libgssapi_krb5} \ - lib/libbz2 lib/libcom_err lib/libcrypt lib/libelf \ +_prebuild_libs= ${_kerberos5_lib_libasn1} ${_kerberos5_lib_libheimntlm} \ + ${_kerberos5_lib_libhx509} ${_kerberos5_lib_libkrb5} \ + ${_kerberos5_lib_libroken} \ + lib/libbz2 lib/libcom_err lib/libcrypt \ lib/libexpat \ - ${_lib_cddl} ${_lib_libgssapi} ${_lib_libipx} \ + ${_lib_libgssapi} ${_lib_libipx} \ lib/libkiconv lib/libkvm lib/libmd \ lib/ncurses/ncurses lib/ncurses/ncursesw \ lib/libopie lib/libpam ${_lib_libthr} \ lib/libradius lib/libsbuf lib/libtacplus lib/libutil \ ${_lib_libypclnt} lib/libz lib/msun \ ${_secure_lib_libcrypto} ${_secure_lib_libssh} \ - ${_secure_lib_libssl} lib/libdwarf lib/libproc + ${_secure_lib_libssl} .if ${MK_LIBTHR} != "no" _lib_libthr= lib/libthr @@ -1121,18 +1121,20 @@ lib/libradius__L secure/lib/libssl__L: secure/lib/libcrypto__L .if ${MK_OPENSSH} != "no" _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: lib/libgssapi__L kerberos5/lib/libkrb5__L \ +.if ${MK_KERBEROS_SUPPORT} != "no" +secure/lib/libssh__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 -secure/lib/libssh__L: lib/libgssapi__L kerberos5/lib/libgssapi_krb5__L + lib/libmd__L kerberos5/lib/libroken__L .endif .endif .endif _secure_lib= secure/lib .endif +.if ${MK_GSSAPI} != "no" +_lib_libgssapi= lib/libgssapi +.endif + .if ${MK_IPX} != "no" _lib_libipx= lib/libipx .endif @@ -1144,8 +1146,6 @@ _kerberos5_lib_libkrb5= kerberos5/lib/libkrb5 _kerberos5_lib_libhx509= kerberos5/lib/libhx509 _kerberos5_lib_libroken= kerberos5/lib/libroken _kerberos5_lib_libheimntlm= kerberos5/lib/libheimntlm -_kerberos5_lib_libgssapi_krb5= kerberos5/lib/libgssapi_krb5 -_lib_libgssapi= lib/libgssapi .endif .if ${MK_NIS} != "no" From 1eb55c853788d13c922428317d4142ed61333db7 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Sat, 20 Feb 2010 13:35:05 +0000 Subject: [PATCH 1480/2592] MFC r203157, r203816: Handle short reads when the -P option is used and remove some dead code. PR: bin/121502 --- sbin/restore/tape.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sbin/restore/tape.c b/sbin/restore/tape.c index debed5ff411..c884dee2228 100644 --- a/sbin/restore/tape.c +++ b/sbin/restore/tape.c @@ -227,7 +227,7 @@ setup(void) volno = 1; setdumpnum(); FLUSHTAPEBUF(); - if (!pipein && !bflag) + if (!pipein && !pipecmdin && !bflag) findtapeblksize(); if (gethead(&spcl) == FAIL) { fprintf(stderr, "Tape is not a dump tape\n"); @@ -333,10 +333,6 @@ getvol(long nextvol) } if (volno == 1) return; - if (pipecmdin) { - closemt(); - goto getpipecmdhdr; - } goto gethdr; } again: @@ -400,7 +396,6 @@ again: if (pipecmdin) { char volno[sizeof("2147483647")]; -getpipecmdhdr: (void)sprintf(volno, "%d", newvol); if (setenv("RESTORE_VOLUME", volno, 1) == -1) { fprintf(stderr, "Cannot set $RESTORE_VOLUME: %s\n", @@ -1204,17 +1199,17 @@ getmore: * Check for mid-tape short read error. * If found, skip rest of buffer and start with the next. */ - if (!pipein && numtrec < ntrec && i > 0) { + if (!pipein && !pipecmdin && numtrec < ntrec && i > 0) { dprintf(stdout, "mid-media short read error.\n"); numtrec = ntrec; } /* * Handle partial block read. */ - if (pipein && i == 0 && rd > 0) + if ((pipein || pipecmdin) && i == 0 && rd > 0) i = rd; else if (i > 0 && i != ntrec * TP_BSIZE) { - if (pipein) { + if (pipein || pipecmdin) { rd += i; cnt -= i; if (cnt > 0) From 69b0137459dbfcb836368d22d1fb1af534f524bb Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 20 Feb 2010 22:43:12 +0000 Subject: [PATCH 1481/2592] MFC rev 203883: o Eliminate IA64_PHYS_TO_RR6 by calling bus_space_map() or pmap_mapdev(). o Implement bus_space_map() in terms of pmap_mapdev(). o Have ia64_pib hold the uncached virtual address of the PIB. --- sys/ia64/acpica/madt.c | 6 ++---- sys/ia64/ia64/bus_machdep.c | 21 +++++++++++++++++++++ sys/ia64/ia64/efi.c | 6 ++++-- sys/ia64/ia64/interrupt.c | 3 +-- sys/ia64/ia64/machdep.c | 10 +++++++++- sys/ia64/ia64/mp_machdep.c | 26 ++++++++++++++------------ sys/ia64/ia64/pmap.c | 8 +++++--- sys/ia64/ia64/sapic.c | 7 ++++--- sys/ia64/include/bus.h | 26 ++++++-------------------- sys/ia64/include/intr.h | 24 +++++++++++------------- sys/ia64/include/md_var.h | 16 ++++++++-------- sys/ia64/include/pmap.h | 2 +- sys/ia64/include/vmparam.h | 1 - 13 files changed, 86 insertions(+), 70 deletions(-) diff --git a/sys/ia64/acpica/madt.c b/sys/ia64/acpica/madt.c index 254308846b1..51193fffcc8 100644 --- a/sys/ia64/acpica/madt.c +++ b/sys/ia64/acpica/madt.c @@ -31,8 +31,6 @@ #include -extern u_int64_t ia64_lapic_address; - struct sapic *sapic_create(int, int, u_int64_t); static void @@ -150,7 +148,7 @@ ia64_probe_sapics(void) /* Save the address of the processor interrupt block. */ if (bootverbose) printf("\tLocal APIC address=0x%x\n", table->Address); - ia64_lapic_address = table->Address; + ia64_lapic_addr = table->Address; end = (char *)table + table->Header.Length; p = (char *)(table + 1); @@ -172,7 +170,7 @@ ia64_probe_sapics(void) case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: { ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)entry; - ia64_lapic_address = lapic->Address; + ia64_lapic_addr = lapic->Address; break; } diff --git a/sys/ia64/ia64/bus_machdep.c b/sys/ia64/ia64/bus_machdep.c index f9e019bfc64..cd9ebc8ce46 100644 --- a/sys/ia64/ia64/bus_machdep.c +++ b/sys/ia64/ia64/bus_machdep.c @@ -29,12 +29,33 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include extern u_long ia64_port_base; #define __PIO_ADDR(port) \ (void *)(ia64_port_base | (((port) & 0xfffc) << 10) | ((port) & 0xFFF)) +int +bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, + int flags __unused, bus_space_handle_t *bshp) +{ + + *bshp = (__predict_false(bst == IA64_BUS_SPACE_IO)) + ? addr : (uintptr_t)pmap_mapdev(addr, size); + return (0); +} + + +void +bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh, + bus_size_t size) +{ + + pmap_unmapdev(bsh, size); +} + uint8_t bus_space_read_io_1(u_long port) { diff --git a/sys/ia64/ia64/efi.c b/sys/ia64/ia64/efi.c index 7e6fdaa9ef8..d193f60c055 100644 --- a/sys/ia64/ia64/efi.c +++ b/sys/ia64/ia64/efi.c @@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include extern uint64_t ia64_call_efi_physical(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); @@ -123,8 +125,8 @@ efi_boot_minimal(uint64_t systbl) md->md_virt = (void *)IA64_PHYS_TO_RR7(md->md_phys); else if (md->md_attr & EFI_MD_ATTR_UC) - md->md_virt = - (void *)IA64_PHYS_TO_RR6(md->md_phys); + md->md_virt = pmap_mapdev(md->md_phys, + md->md_pages * EFI_PAGE_SIZE); } md = efi_md_next(md); } diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index 1b5344d54cc..64b04ebca41 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -106,7 +106,6 @@ void interrupt(struct trapframe *tf) { struct thread *td; - volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK; uint64_t adj, clk, itc; int64_t delta; u_int vector; @@ -130,7 +129,7 @@ interrupt(struct trapframe *tf) */ if (vector == 0) { PCPU_INC(md.stats.pcs_nextints); - inta = ib->ib_inta; + inta = ia64_ld1(&ia64_pib->ib_inta); if (inta == 15) { PCPU_INC(md.stats.pcs_nstrays); __asm __volatile("mov cr.eoi = r0;; srlz.d"); diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 95b604f6c9f..c3e7654589e 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -85,6 +85,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -134,6 +135,10 @@ struct fpswa_iface *fpswa_iface; u_int64_t ia64_pal_base; u_int64_t ia64_port_base; +u_int64_t ia64_lapic_addr = PAL_PIB_DEFAULT_ADDR; + +struct ia64_pib *ia64_pib; + static int ia64_sync_icache_needed; char machine[] = MACHINE; @@ -308,6 +313,8 @@ cpu_startup(void *dummy) * information. */ ia64_probe_sapics(); + ia64_pib = pmap_mapdev(ia64_lapic_addr, sizeof(*ia64_pib)); + ia64_mca_init(); /* @@ -684,7 +691,8 @@ ia64_init(void) for (md = efi_md_first(); md != NULL; md = efi_md_next(md)) { switch (md->md_type) { case EFI_MD_TYPE_IOPORT: - ia64_port_base = IA64_PHYS_TO_RR6(md->md_phys); + ia64_port_base = (uintptr_t)pmap_mapdev(md->md_phys, + md->md_pages * EFI_PAGE_SIZE); break; case EFI_MD_TYPE_PALCODE: ia64_pal_base = md->md_phys; diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index 9cbf7705df9..c5ed48f501d 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -68,8 +68,9 @@ MALLOC_DEFINE(M_SMP, "SMP", "SMP related allocations"); void ia64_ap_startup(void); -#define LID_SAPIC_ID(x) ((int)((x) >> 24) & 0xff) -#define LID_SAPIC_EID(x) ((int)((x) >> 16) & 0xff) +#define LID_SAPIC(x) ((u_int)((x) >> 16)) +#define LID_SAPIC_ID(x) ((u_int)((x) >> 24) & 0xff) +#define LID_SAPIC_EID(x) ((u_int)((x) >> 16) & 0xff) #define LID_SAPIC_SET(id,eid) (((id & 0xff) << 8 | (eid & 0xff)) << 16); #define LID_SAPIC_MASK 0xffff0000UL @@ -114,7 +115,6 @@ ia64_store_mca_state(void* arg) void ia64_ap_startup(void) { - volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK; uint64_t vhpt; int vector; @@ -153,7 +153,7 @@ ia64_ap_startup(void) while (vector != 15) { ia64_srlz_d(); if (vector == 0) - vector = (int)ib->ib_inta; + vector = (int)ia64_ld1(&ia64_pib->ib_inta); ia64_set_eoi(0); ia64_srlz_d(); vector = ia64_get_ivr(); @@ -363,16 +363,18 @@ ipi_all_but_self(int ipi) void ipi_send(struct pcpu *cpu, int ipi) { - volatile uint64_t *pipi; - uint64_t vector; + u_int lid; + uint8_t vector; - pipi = (void *)IA64_PHYS_TO_RR6(ia64_lapic_address | - ((cpu->pc_md.lid & LID_SAPIC_MASK) >> 12)); - vector = (uint64_t)(ipi_vector[ipi] & 0xff); + lid = LID_SAPIC(cpu->pc_md.lid); + vector = ipi_vector[ipi]; KASSERT(vector != 0, ("IPI %d is not assigned a vector", ipi)); - *pipi = vector; - CTR3(KTR_SMP, "ipi_send(%p, %ld), cpuid=%d", pipi, vector, - PCPU_GET(cpuid)); + + ia64_mf(); + ia64_st8(&(ia64_pib->ib_ipi[lid][0]), vector); + ia64_mf_a(); + CTR4(KTR_SMP, "ipi_send(%p, %ld): cpuid=%d, vector=%u", cpu, ipi, + PCPU_GET(cpuid), vector); } SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, cpu_mp_unleash, NULL); diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index c738ea3e5fb..32bcb14340a 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -2145,9 +2145,12 @@ pmap_remove_write(vm_page_t m) * NOT real memory. */ void * -pmap_mapdev(vm_offset_t pa, vm_size_t size) +pmap_mapdev(vm_paddr_t pa, vm_size_t size) { - return (void*) IA64_PHYS_TO_RR6(pa); + vm_offset_t va; + + va = pa | IA64_RR_BASE(6); + return ((void *)va); } /* @@ -2156,7 +2159,6 @@ pmap_mapdev(vm_offset_t pa, vm_size_t size) void pmap_unmapdev(vm_offset_t va, vm_size_t size) { - return; } /* diff --git a/sys/ia64/ia64/sapic.c b/sys/ia64/ia64/sapic.c index 00ef23490fc..88bd0139872 100644 --- a/sys/ia64/ia64/sapic.c +++ b/sys/ia64/ia64/sapic.c @@ -42,6 +42,9 @@ #include #include +#include +#include + static MALLOC_DEFINE(M_SAPIC, "sapic", "I/O SAPIC devices"); static int sysctl_machdep_apic(SYSCTL_HANDLER_ARGS); @@ -52,8 +55,6 @@ SYSCTL_OID(_machdep, OID_AUTO, apic, CTLTYPE_STRING|CTLFLAG_RD, struct sapic *ia64_sapics[16]; /* XXX make this resizable */ int ia64_sapic_count; -u_int64_t ia64_lapic_address = PAL_PIB_DEFAULT_ADDR; - struct sapic_rte { u_int64_t rte_vector :8; u_int64_t rte_delivery_mode :3; @@ -165,7 +166,7 @@ sapic_create(u_int id, u_int base, u_int64_t address) sa->sa_id = id; sa->sa_base = base; - sa->sa_registers = IA64_PHYS_TO_RR6(address); + sa->sa_registers = (uintptr_t)pmap_mapdev(address, 1048576); mtx_init(&sa->sa_mtx, "I/O SAPIC lock", NULL, MTX_SPIN); diff --git a/sys/ia64/include/bus.h b/sys/ia64/include/bus.h index a2a02a09f5a..bad4f85ac15 100644 --- a/sys/ia64/include/bus.h +++ b/sys/ia64/include/bus.h @@ -132,28 +132,14 @@ /* - * Map a region of device bus space into CPU virtual address space. + * Map and unmap a region of device bus space into CPU virtual address space. */ -static __inline int -bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size __unused, - int flags __unused, bus_space_handle_t *bshp) -{ - - *bshp = (__predict_false(bst == IA64_BUS_SPACE_IO)) - ? addr : IA64_PHYS_TO_RR6(addr); - return (0); -} - - -/* - * Unmap a region of device bus space. - */ -static __inline void -bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh __unused, - bus_size_t size __unused) -{ -} +int +bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, + bus_space_handle_t *); +void +bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t size); /* * Get a new handle for a subregion of an already-mapped area of bus space. diff --git a/sys/ia64/include/intr.h b/sys/ia64/include/intr.h index 7d59ef217d6..8651fdad110 100644 --- a/sys/ia64/include/intr.h +++ b/sys/ia64/include/intr.h @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2007-2010 Marcel Moolenaar * Copyright (c) 1998 Doug Rabson * All rights reserved. * @@ -27,26 +28,23 @@ */ #ifndef _MACHINE_INTR_H_ -#define _MACHINE_INTR_H_ +#define _MACHINE_INTR_H_ /* * Layout of the Processor Interrupt Block. */ -struct ia64_interrupt_block +struct ia64_pib { - u_int64_t ib_ipi[0x20000]; /* 1Mb of IPI interrupts */ - u_int8_t ib_reserved1[0xe0000]; - u_int8_t ib_inta; /* Generate INTA cycle */ - u_int8_t ib_reserved2[7]; - u_int8_t ib_xtp; /* XTP cycle */ - u_int8_t ib_reserved3[7]; - u_int8_t ib_reserved4[0x1fff0]; + uint64_t ib_ipi[65536][2]; /* 64K-way IPIs (1MB area). */ + uint8_t _rsvd1[0xe0000]; + uint8_t ib_inta; /* Generate INTA cycle. */ + uint8_t _rsvd2[7]; + uint8_t ib_xtp; /* External Task Priority. */ + uint8_t _rsvd3[7]; + uint8_t _rsvd4[0x1fff0]; }; -extern u_int64_t ia64_lapic_address; - -#define IA64_INTERRUPT_BLOCK \ - (struct ia64_interrupt_block *)IA64_PHYS_TO_RR6(ia64_lapic_address) +extern struct ia64_pib *ia64_pib; int ia64_setup_intr(const char *name, int irq, driver_filter_t filter, driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep); diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h index 7fdcb2de539..9a2f92a53b2 100644 --- a/sys/ia64/include/md_var.h +++ b/sys/ia64/include/md_var.h @@ -49,7 +49,7 @@ struct ia64_fdesc { #define IA64_CFM_RRB_FR(x) (((x) >> 25) & 0x7f) #define IA64_CFM_RRB_PR(x) (((x) >> 32) & 0x3f) -/* Concenience function (inline) to adjust backingstore pointers. */ +/* Convenience function (inline) to adjust backingstore pointers. */ static __inline uint64_t ia64_bsp_adjust(uint64_t bsp, int nslots) { @@ -60,22 +60,22 @@ ia64_bsp_adjust(uint64_t bsp, int nslots) #ifdef _KERNEL -extern char sigcode[]; -extern char esigcode[]; -extern int szsigcode; -extern long Maxmem; - struct _special; -struct fpreg; -struct reg; struct thread; struct trapframe; +/* + * Return value from ia64_init. Describes stack to switch to. + */ struct ia64_init_return { uint64_t bspstore; uint64_t sp; }; +extern uint64_t ia64_lapic_addr; + +extern long Maxmem; + void busdma_swi(void); int copyout_regstack(struct thread *, uint64_t *, uint64_t *); void cpu_mp_add(u_int, u_int, u_int); diff --git a/sys/ia64/include/pmap.h b/sys/ia64/include/pmap.h index f878d279c5f..e40d64766d1 100644 --- a/sys/ia64/include/pmap.h +++ b/sys/ia64/include/pmap.h @@ -132,7 +132,7 @@ vm_paddr_t pmap_kextract(vm_offset_t va); void pmap_kremove(vm_offset_t); void pmap_setdevram(unsigned long long basea, vm_offset_t sizea); int pmap_uses_prom_console(void); -void *pmap_mapdev(vm_offset_t, vm_size_t); +void *pmap_mapdev(vm_paddr_t, vm_size_t); void pmap_unmapdev(vm_offset_t, vm_size_t); unsigned *pmap_pte(pmap_t, vm_offset_t) __pure2; void pmap_set_opt (unsigned *); diff --git a/sys/ia64/include/vmparam.h b/sys/ia64/include/vmparam.h index 9e65ea8fa2f..e040e9af8d7 100644 --- a/sys/ia64/include/vmparam.h +++ b/sys/ia64/include/vmparam.h @@ -132,7 +132,6 @@ #define IA64_RR_BASE(n) (((u_int64_t) (n)) << 61) #define IA64_RR_MASK(x) ((x) & ((1L << 61) - 1)) -#define IA64_PHYS_TO_RR6(x) ((x) | IA64_RR_BASE(6)) #define IA64_PHYS_TO_RR7(x) ((x) | IA64_RR_BASE(7)) /* From 454947a618195573fa75b613a5f5d7d7c57b1d56 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 21 Feb 2010 04:10:25 +0000 Subject: [PATCH 1482/2592] MFC r203085 Optimize pmap_demote_pde() by using the new KPTmap to access a kernel page table page instead of creating a temporary mapping to it. Set the PG_G bit on the page table entries that implement the KPTmap. Locore initializes the unused portions of the NKPT kernel page table pages that it allocates to zero. So, pmap_bootstrap() needn't zero the page table entries referenced by CMAP1 and CMAP3. Simplify pmap_set_pg(). --- sys/i386/i386/pmap.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 3ef2a5da261..85e6ffb284a 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -423,7 +423,6 @@ pmap_bootstrap(vm_paddr_t firstaddr) } SYSMAP(caddr_t, CMAP1, CADDR1, 1) SYSMAP(caddr_t, CMAP3, CADDR3, 1) - *CMAP3 = 0; /* * Crashdump maps. @@ -446,7 +445,7 @@ pmap_bootstrap(vm_paddr_t firstaddr) SYSMAP(pt_entry_t *, KPTD, KPTmap, KVA_PAGES) for (i = 0; i < NKPT; i++) - KPTD[i] = (KPTphys + (i << PAGE_SHIFT)) | PG_RW | PG_V; + KPTD[i] = (KPTphys + (i << PAGE_SHIFT)) | pgeflag | PG_RW | PG_V; /* * Adjust the start of the KPTD and KPTmap so that the implementation @@ -458,15 +457,13 @@ pmap_bootstrap(vm_paddr_t firstaddr) /* * ptemap is used for pmap_pte_quick */ - SYSMAP(pt_entry_t *, PMAP1, PADDR1, 1); - SYSMAP(pt_entry_t *, PMAP2, PADDR2, 1); + SYSMAP(pt_entry_t *, PMAP1, PADDR1, 1) + SYSMAP(pt_entry_t *, PMAP2, PADDR2, 1) mtx_init(&PMAP2mutex, "PMAP2", NULL, MTX_DEF); virtual_avail = va; - *CMAP1 = 0; - /* * Leave in place an identity mapping (virt == phys) for the low 1 MB * physical memory region that is used by the ACPI wakeup code. This @@ -539,25 +536,19 @@ pmap_init_pat(void) void pmap_set_pg(void) { - pd_entry_t pdir; pt_entry_t *pte; vm_offset_t va, endva; - int i; if (pgeflag == 0) return; - i = KERNLOAD/NBPDR; endva = KERNBASE + KERNend; if (pseflag) { va = KERNBASE + KERNLOAD; while (va < endva) { - pdir = kernel_pmap->pm_pdir[KPTDI+i]; - pdir |= pgeflag; - kernel_pmap->pm_pdir[KPTDI+i] = PTD[KPTDI+i] = pdir; + pdir_pde(PTD, va) |= pgeflag; invltlb(); /* Play it safe, invltlb() every time */ - i++; va += NBPDR; } } else { @@ -1885,7 +1876,7 @@ pmap_growkernel(vm_offset_t addr) pmap_zero_page(nkpg); ptppaddr = VM_PAGE_TO_PHYS(nkpg); newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M); - pdir_pde(KPTD, kernel_vm_end) = newpdir; + pdir_pde(KPTD, kernel_vm_end) = pgeflag | newpdir; updated_PTD = FALSE; mtx_lock_spin(&allpmaps_lock); @@ -2381,10 +2372,14 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) mptepa = VM_PAGE_TO_PHYS(mpte); /* - * Temporarily map the page table page (mpte) into the kernel's - * address space at either PADDR1 or PADDR2. + * If the page mapping is in the kernel's address space, then the + * KPTmap can provide access to the page table page. Otherwise, + * temporarily map the page table page (mpte) into the kernel's + * address space at either PADDR1 or PADDR2. */ - if (curthread->td_pinned > 0 && mtx_owned(&vm_page_queue_mtx)) { + if (va >= KERNBASE) + firstpte = &KPTmap[i386_btop(trunc_4mpage(va))]; + else if (curthread->td_pinned > 0 && mtx_owned(&vm_page_queue_mtx)) { if ((*PMAP1 & PG_FRAME) != mptepa) { *PMAP1 = mptepa | PG_RW | PG_V | PG_A | PG_M; #ifdef SMP @@ -2448,10 +2443,9 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) /* * A harmless race exists between this loop and the bcopy() * in pmap_pinit() that initializes the kernel segment of - * the new page table. Specifically, that bcopy() may copy - * the new PDE from the PTD, which is first in allpmaps, to - * the new page table before this loop updates that new - * page table. + * the new page table directory. Specifically, that bcopy() + * may copy the new PDE from the PTD to the new page table + * before this loop updates that new page table. */ mtx_lock_spin(&allpmaps_lock); LIST_FOREACH(allpmaps_entry, &allpmaps, pm_list) { From 3588e7da23c707ae9c5f8ab76b3b0e31fff18599 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 21 Feb 2010 11:13:15 +0000 Subject: [PATCH 1483/2592] MFC r203866: Invalid filesystem might cause the bp to be never read. --- sys/fs/msdosfs/msdosfs_fat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index 7fae9c0ec10..76d1527c5a4 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -944,7 +944,8 @@ fillinusemap(pmp) if (readcn == 0) usemap_free(pmp, cn); } - brelse(bp); + if (bp != NULL) + brelse(bp); return (0); } From 4ed35fdd3d887640c92740653f5940ed2435fbb3 Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sun, 21 Feb 2010 11:22:01 +0000 Subject: [PATCH 1484/2592] Merge r200413 and r202755 from head to stable/8: reduces white space diff between head and stable/8 Suggested by: ru@ --- Makefile.inc1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 2866c00da63..a6a99b20eec 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1096,8 +1096,8 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} ${_kerberos5_lib_libheimntlm} \ lib/libkiconv lib/libkvm lib/libmd \ lib/ncurses/ncurses lib/ncurses/ncursesw \ lib/libopie lib/libpam ${_lib_libthr} \ - lib/libradius lib/libsbuf lib/libtacplus lib/libutil \ - ${_lib_libypclnt} lib/libz lib/msun \ + lib/libradius lib/libsbuf lib/libtacplus \ + lib/libutil ${_lib_libypclnt} lib/libz lib/msun \ ${_secure_lib_libcrypto} ${_secure_lib_libssh} \ ${_secure_lib_libssl} From 27a5b388f3096df51f40e1029bd1c92a1fcb1125 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Sun, 21 Feb 2010 13:17:35 +0000 Subject: [PATCH 1485/2592] MFC r203551: - Cast intptr_t, pid_t and time_t values to intmax_t and use %jd with printf. - Cast the system call return value to long and use %ld in a printf in ktrsysret(). PR: bin/123774 --- usr.bin/kdump/kdump.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 60ce05f4f2d..82f7c098316 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -182,14 +182,16 @@ main(int argc, char *argv[]) if (ktr_header.ktr_type & KTR_DROP) { ktr_header.ktr_type &= ~KTR_DROP; if (!drop_logged && threads) { - (void)printf("%6d %6d %-8.*s Events dropped.\n", - ktr_header.ktr_pid, ktr_header.ktr_tid > - 0 ? ktr_header.ktr_tid : 0, MAXCOMLEN, - ktr_header.ktr_comm); + (void)printf( + "%6jd %6jd %-8.*s Events dropped.\n", + (intmax_t)ktr_header.ktr_pid, + ktr_header.ktr_tid > 0 ? + (intmax_t)ktr_header.ktr_tid : 0, + MAXCOMLEN, ktr_header.ktr_comm); drop_logged = 1; } else if (!drop_logged) { - (void)printf("%6d %-8.*s Events dropped.\n", - ktr_header.ktr_pid, MAXCOMLEN, + (void)printf("%6jd %-8.*s Events dropped.\n", + (intmax_t)ktr_header.ktr_pid, MAXCOMLEN, ktr_header.ktr_comm); drop_logged = 1; } @@ -309,10 +311,11 @@ dumpheader(struct ktr_header *kth) * negative tid's as 0. */ if (threads) - (void)printf("%6d %6d %-8.*s ", kth->ktr_pid, kth->ktr_tid > - 0 ? kth->ktr_tid : 0, MAXCOMLEN, kth->ktr_comm); + (void)printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid, + kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0, + MAXCOMLEN, kth->ktr_comm); else - (void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, + (void)printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN, kth->ktr_comm); if (timestamp) { if (timestamp == 3) { @@ -325,8 +328,8 @@ dumpheader(struct ktr_header *kth) timevalsub(&kth->ktr_time, &prevtime); prevtime = temp; } - (void)printf("%ld.%06ld ", - kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); + (void)printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, + kth->ktr_time.tv_usec); } (void)printf("%s ", type); } @@ -821,7 +824,7 @@ ktrsysret(struct ktr_sysret *ktr) if (error == 0) { if (fancy) { - (void)printf("%d", ret); + (void)printf("%ld", (long)ret); if (ret < 0 || ret > 9) (void)printf("/%#lx", (long)ret); } else { @@ -1270,7 +1273,7 @@ ktrstat(struct stat *statp) printf("rdev=%ju, ", (uintmax_t)statp->st_rdev); printf("atime="); if (resolv == 0) - printf("%ld", statp->st_atimespec.tv_sec); + printf("%jd", (intmax_t)statp->st_atimespec.tv_sec); else { tm = localtime(&statp->st_atimespec.tv_sec); (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); @@ -1282,7 +1285,7 @@ ktrstat(struct stat *statp) printf(", "); printf("stime="); if (resolv == 0) - printf("%ld", statp->st_mtimespec.tv_sec); + printf("%jd", (intmax_t)statp->st_mtimespec.tv_sec); else { tm = localtime(&statp->st_mtimespec.tv_sec); (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); @@ -1294,7 +1297,7 @@ ktrstat(struct stat *statp) printf(", "); printf("ctime="); if (resolv == 0) - printf("%ld", statp->st_ctimespec.tv_sec); + printf("%jd", (intmax_t)statp->st_ctimespec.tv_sec); else { tm = localtime(&statp->st_ctimespec.tv_sec); (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); @@ -1306,7 +1309,7 @@ ktrstat(struct stat *statp) printf(", "); printf("birthtime="); if (resolv == 0) - printf("%ld", statp->st_birthtimespec.tv_sec); + printf("%jd", (intmax_t)statp->st_birthtimespec.tv_sec); else { tm = localtime(&statp->st_birthtimespec.tv_sec); (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); From 8d0a84b1d41607046fe4146227684cec62673d77 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Mon, 22 Feb 2010 15:58:10 +0000 Subject: [PATCH 1486/2592] MFC: r204008: realloc() with a proper amount of memory. --- lib/libjail/jail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libjail/jail.c b/lib/libjail/jail.c index 39c88d098ed..c82cb114641 100644 --- a/lib/libjail/jail.c +++ b/lib/libjail/jail.c @@ -191,7 +191,7 @@ jailparam_all(struct jailparam **jpp) /* Add the parameter to the list */ if (njp >= nlist) { nlist *= 2; - jp = realloc(jp, nlist * sizeof(jp)); + jp = realloc(jp, nlist * sizeof(*jp)); if (jp == NULL) { jailparam_free(jp, njp); return (-1); From 9cdec2ba0ee24bbac82d0cef8617803df6509001 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Mon, 22 Feb 2010 16:00:55 +0000 Subject: [PATCH 1487/2592] MFC: r203919: Show when an ARP entry expires (now that this info cannot be obtained with netstat(1)). --- usr.sbin/arp/arp.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c index 61427d34c81..a0e228ce365 100644 --- a/usr.sbin/arp/arp.c +++ b/usr.sbin/arp/arp.c @@ -101,7 +101,8 @@ static int valid_type(int type); static int nflag; /* no reverse dns lookups */ static char *rifname; -static int expire_time, flags, doing_proxy, proxy_only; +static time_t expire_time; +static int flags, doing_proxy, proxy_only; /* which function we're supposed to do */ #define F_GET 1 @@ -594,6 +595,15 @@ print_entry(struct sockaddr_dl *sdl, printf(" on %s", ifname); if (rtm->rtm_rmx.rmx_expire == 0) printf(" permanent"); + else { + static struct timeval tv; + if (tv.tv_sec == 0) + gettimeofday(&tv, 0); + if ((expire_time = rtm->rtm_rmx.rmx_expire - tv.tv_sec) > 0) + printf(" expires in %d seconds", (int)expire_time); + else + printf(" expired"); + } if (addr->sin_other & SIN_PROXY) printf(" published (proxy only)"); if (rtm->rtm_flags & RTF_ANNOUNCE) From 7eb2cc363dba02539ed0a586e7f021f810684888 Mon Sep 17 00:00:00 2001 From: Bernhard Schmidt Date: Mon, 22 Feb 2010 17:10:47 +0000 Subject: [PATCH 1488/2592] MFC r203673: Ensure that tkip_mixing_phase1() is called after a rekeying event when using plain s/w crypto. PR: bin/142547 Approved by: rpaulo (mentor) --- sys/net80211/ieee80211_crypto_tkip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/net80211/ieee80211_crypto_tkip.c b/sys/net80211/ieee80211_crypto_tkip.c index f949255b9c6..6e1fda1fc9d 100644 --- a/sys/net80211/ieee80211_crypto_tkip.c +++ b/sys/net80211/ieee80211_crypto_tkip.c @@ -144,6 +144,7 @@ tkip_setkey(struct ieee80211_key *k) return 0; } k->wk_keytsc = 1; /* TSC starts at 1 */ + ctx->rx_phase1_done = 0; return 1; } From c6bf5f18c04e033a967879c0daff9538a856df0b Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Mon, 22 Feb 2010 21:45:20 +0000 Subject: [PATCH 1489/2592] - Factor out the code shared between NFS client and server into its own module so it's not present twice. - Move nfs_realign() from the NFS client to the shared NFS code and remove the NFS server version in order to reduce code duplication. The shared version now uses a second parameter how, which is passed on to m_get(9) and m_getcl(9) as the server used M_WAIT while the client requires M_DONTWAIT, and replaces the the previously unused parameter hsiz. - Change nfs_realign() to use nfsm_aligned() so as with other NFS code the alignment check isn't actually performed on platforms without strict alignment requirements for performance reasons because as the comment suggests unaligned data only occasionally occurs with TCP. - Change fha_extract_info() to use nfs_realign() with M_DONTWAIT rather than M_WAIT because it's called with the RPC sp_lock held. --- sys/modules/Makefile | 1 + sys/modules/nfs_common/Makefile | 8 ++++ sys/modules/nfsclient/Makefile | 4 +- sys/modules/nfsserver/Makefile | 4 +- sys/nfs/nfs_common.c | 77 +++++++++++++++++++++++++++++++++ sys/nfs/nfs_common.h | 1 + sys/nfsclient/nfs_krpc.c | 67 +--------------------------- sys/nfsclient/nfs_vfsops.c | 1 + sys/nfsserver/nfs.h | 1 - sys/nfsserver/nfs_fha.c | 4 +- sys/nfsserver/nfs_srvkrpc.c | 59 +------------------------ sys/nfsserver/nfs_srvsubs.c | 1 + 12 files changed, 98 insertions(+), 130 deletions(-) create mode 100644 sys/modules/nfs_common/Makefile diff --git a/sys/modules/Makefile b/sys/modules/Makefile index e76d63ad39a..07e4bfbacd1 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -193,6 +193,7 @@ SUBDIR= ${_3dfx} \ ${_ndis} \ ${_netgraph} \ ${_nfe} \ + nfs_common \ nfscl \ nfsclient \ nfscommon \ diff --git a/sys/modules/nfs_common/Makefile b/sys/modules/nfs_common/Makefile new file mode 100644 index 00000000000..8f51f185d8d --- /dev/null +++ b/sys/modules/nfs_common/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../nfs + +KMOD= nfs_common +SRCS= nfs_common.c opt_nfs.h vnode_if.h + +.include diff --git a/sys/modules/nfsclient/Makefile b/sys/modules/nfsclient/Makefile index c53e3d5f98a..5cd3556821f 100644 --- a/sys/modules/nfsclient/Makefile +++ b/sys/modules/nfsclient/Makefile @@ -1,11 +1,11 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../nfs ${.CURDIR}/../../rpc +.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../rpc KMOD= nfsclient SRCS= vnode_if.h \ nfs_bio.c nfs_lock.c nfs_node.c nfs_subs.c nfs_nfsiod.c \ - nfs_vfsops.c nfs_vnops.c nfs_common.c nfs_krpc.c \ + nfs_vfsops.c nfs_vnops.c nfs_krpc.c \ opt_inet.h opt_nfs.h opt_bootp.h opt_nfsroot.h SRCS+= opt_inet6.h opt_kdtrace.h opt_kgssapi.h diff --git a/sys/modules/nfsserver/Makefile b/sys/modules/nfsserver/Makefile index 692179b916c..58ab2bc8fbb 100644 --- a/sys/modules/nfsserver/Makefile +++ b/sys/modules/nfsserver/Makefile @@ -1,9 +1,9 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../nfsserver ${.CURDIR}/../../nfs +.PATH: ${.CURDIR}/../../nfsserver KMOD= nfsserver SRCS= vnode_if.h \ - nfs_fha.c nfs_serv.c nfs_srvkrpc.c nfs_srvsubs.c nfs_common.c \ + nfs_fha.c nfs_serv.c nfs_srvkrpc.c nfs_srvsubs.c \ opt_mac.h \ opt_kgssapi.h \ opt_nfs.h diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c index b2c231fc61e..fc767c16f6a 100644 --- a/sys/nfs/nfs_common.c +++ b/sys/nfs/nfs_common.c @@ -54,8 +54,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include #include #include @@ -77,6 +79,16 @@ nfstype nfsv3_type[9] = { static void *nfsm_dissect_xx_sub(int s, struct mbuf **md, caddr_t *dpos, int how); +SYSCTL_NODE(_vfs, OID_AUTO, nfs_common, CTLFLAG_RD, 0, "NFS common support"); + +static int nfs_realign_test; +SYSCTL_INT(_vfs_nfs_common, OID_AUTO, realign_test, CTLFLAG_RD, + &nfs_realign_test, 0, "Number of realign tests done"); + +static int nfs_realign_count; +SYSCTL_INT(_vfs_nfs_common, OID_AUTO, realign_count, CTLFLAG_RD, + &nfs_realign_count, 0, "Number of mbuf realignments done"); + u_quad_t nfs_curusec(void) { @@ -334,3 +346,68 @@ nfsm_adv_xx(int s, struct mbuf **md, caddr_t *dpos) return t1; return 0; } + +/* + * Check for badly aligned mbuf data and realign by copying the unaligned + * portion of the data into a new mbuf chain and freeing the portions of the + * old chain that were replaced. + * + * We cannot simply realign the data within the existing mbuf chain because + * the underlying buffers may contain other rpc commands and we cannot afford + * to overwrite them. + * + * We would prefer to avoid this situation entirely. The situation does not + * occur with NFS/UDP and is supposed to only occassionally occur with TCP. + * Use vfs.nfs.realign_count and realign_test to check this. + */ +int +nfs_realign(struct mbuf **pm, int how) +{ + struct mbuf *m, *n; + int off; + + ++nfs_realign_test; + while ((m = *pm) != NULL) { + if (!nfsm_aligned(m->m_len, u_int32_t) || + !nfsm_aligned(mtod(m, intptr_t), u_int32_t)) { + /* + * NB: we can't depend on m_pkthdr.len to help us + * decide what to do here. May not be worth doing + * the m_length calculation as m_copyback will + * expand the mbuf chain below as needed. + */ + if (m_length(m, NULL) >= MINCLSIZE) { + /* NB: m_copyback handles space > MCLBYTES */ + n = m_getcl(how, MT_DATA, 0); + } else + n = m_get(how, MT_DATA); + if (n == NULL) + return (ENOMEM); + /* + * Align the remainder of the mbuf chain. + */ + n->m_len = 0; + off = 0; + while (m != NULL) { + m_copyback(n, off, m->m_len, mtod(m, caddr_t)); + off += m->m_len; + m = m->m_next; + } + m_freem(*pm); + *pm = n; + ++nfs_realign_count; + break; + } + pm = &m->m_next; + } + return (0); +} + +static moduledata_t nfs_common_mod = { + "nfs_common", + NULL, + NULL +}; + +DECLARE_MODULE(nfs_common, nfs_common_mod, SI_SUB_VFS, SI_ORDER_ANY); +MODULE_VERSION(nfs_common, 1); diff --git a/sys/nfs/nfs_common.h b/sys/nfs/nfs_common.h index 7c061309593..97b8c5ffea3 100644 --- a/sys/nfs/nfs_common.h +++ b/sys/nfs/nfs_common.h @@ -49,6 +49,7 @@ extern nfstype nfsv3_type[]; int nfs_adv(struct mbuf **, caddr_t *, int, int); u_quad_t nfs_curusec(void); void *nfsm_disct(struct mbuf **, caddr_t *, int, int, int); +int nfs_realign(struct mbuf **, int); /* ****************************** */ /* Build request/reply phase macros */ diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c index 098c46b06a9..43bfe640945 100644 --- a/sys/nfsclient/nfs_krpc.c +++ b/sys/nfsclient/nfs_krpc.c @@ -87,8 +87,6 @@ uint32_t nfsclient_nfs3_start_probes[NFS_NPROCS]; uint32_t nfsclient_nfs3_done_probes[NFS_NPROCS]; #endif -static int nfs_realign_test; -static int nfs_realign_count; static int nfs_bufpackets = 4; static int nfs_reconnects; static int nfs3_jukebox_delay = 10; @@ -97,10 +95,6 @@ static int fake_wchan; SYSCTL_DECL(_vfs_nfs); -SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_test, CTLFLAG_RW, &nfs_realign_test, 0, - "Number of realign tests done"); -SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_count, CTLFLAG_RW, &nfs_realign_count, 0, - "Number of mbuf realignments done"); SYSCTL_INT(_vfs_nfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0, "Buffer reservation size 2 < x < 64"); SYSCTL_INT(_vfs_nfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0, @@ -403,65 +397,6 @@ nfs_feedback(int type, int proc, void *arg) } } -/* - * nfs_realign: - * - * Check for badly aligned mbuf data and realign by copying the unaligned - * portion of the data into a new mbuf chain and freeing the portions - * of the old chain that were replaced. - * - * We cannot simply realign the data within the existing mbuf chain - * because the underlying buffers may contain other rpc commands and - * we cannot afford to overwrite them. - * - * We would prefer to avoid this situation entirely. The situation does - * not occur with NFS/UDP and is supposed to only occassionally occur - * with TCP. Use vfs.nfs.realign_count and realign_test to check this. - * - */ -static int -nfs_realign(struct mbuf **pm, int hsiz) -{ - struct mbuf *m, *n; - int off, space; - - ++nfs_realign_test; - while ((m = *pm) != NULL) { - if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { - /* - * NB: we can't depend on m_pkthdr.len to help us - * decide what to do here. May not be worth doing - * the m_length calculation as m_copyback will - * expand the mbuf chain below as needed. - */ - space = m_length(m, NULL); - if (space >= MINCLSIZE) { - /* NB: m_copyback handles space > MCLBYTES */ - n = m_getcl(M_DONTWAIT, MT_DATA, 0); - } else - n = m_get(M_DONTWAIT, MT_DATA); - if (n == NULL) - return (ENOMEM); - /* - * Align the remainder of the mbuf chain. - */ - n->m_len = 0; - off = 0; - while (m != NULL) { - m_copyback(n, off, m->m_len, mtod(m, caddr_t)); - off += m->m_len; - m = m->m_next; - } - m_freem(*pm); - *pm = n; - ++nfs_realign_count; - break; - } - pm = &m->m_next; - } - return (0); -} - /* * nfs_request - goes something like this * - fill in request struct @@ -592,7 +527,7 @@ tryagain: * These could cause pointer alignment problems, so copy them to * well aligned mbufs. */ - error = nfs_realign(&mrep, 2 * NFSX_UNSIGNED); + error = nfs_realign(&mrep, M_DONTWAIT); if (error == ENOMEM) { m_freem(mrep); AUTH_DESTROY(auth); diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index 72ca2ce3fe3..a8f32da0188 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -147,6 +147,7 @@ MODULE_DEPEND(nfs, krpc, 1, 1, 1); #ifdef KGSSAPI MODULE_DEPEND(nfs, kgssapi, 1, 1, 1); #endif +MODULE_DEPEND(nfs, nfs_common, 1, 1, 1); static struct nfs_rpcops nfs_rpcops = { nfs_readrpc, diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h index 00dbe5bcf5a..bb1893e18c0 100644 --- a/sys/nfsserver/nfs.h +++ b/sys/nfsserver/nfs.h @@ -239,7 +239,6 @@ extern int nfs_debug; #endif -void nfs_realign(struct mbuf **); struct mbuf *nfs_rephead(int, struct nfsrv_descript *, int, struct mbuf **, caddr_t *); void nfsm_srvfattr(struct nfsrv_descript *, struct vattr *, diff --git a/sys/nfsserver/nfs_fha.c b/sys/nfsserver/nfs_fha.c index 25e930fe413..76537d7ef94 100644 --- a/sys/nfsserver/nfs_fha.c +++ b/sys/nfsserver/nfs_fha.c @@ -202,7 +202,9 @@ fha_extract_info(struct svc_req *req, struct fha_info *i) procnum == NFSPROC_NULL) goto out; - nfs_realign(&req->rq_args); + error = nfs_realign(&req->rq_args, M_DONTWAIT); + if (error) + goto out; md = req->rq_args; dpos = mtod(md, caddr_t); diff --git a/sys/nfsserver/nfs_srvkrpc.c b/sys/nfsserver/nfs_srvkrpc.c index bdfe4245b06..512373b30e2 100644 --- a/sys/nfsserver/nfs_srvkrpc.c +++ b/sys/nfsserver/nfs_srvkrpc.c @@ -96,8 +96,6 @@ SYSCTL_DECL(_vfs_nfsrv); SVCPOOL *nfsrv_pool; int nfsd_waiting = 0; int nfsrv_numnfsd = 0; -static int nfs_realign_test; -static int nfs_realign_count; struct callout nfsrv_callout; static eventhandler_tag nfsrv_nmbclusters_tag; @@ -111,10 +109,6 @@ SYSCTL_INT(_vfs_nfsrv, OID_AUTO, gatherdelay, CTLFLAG_RW, SYSCTL_INT(_vfs_nfsrv, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, &nfsrvw_procrastinate_v3, 0, "Delay in seconds for NFSv3 write gathering"); -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, realign_test, CTLFLAG_RW, - &nfs_realign_test, 0, ""); -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, realign_count, CTLFLAG_RW, - &nfs_realign_count, 0, ""); static int nfssvc_addsock(struct file *, struct thread *); static int nfssvc_nfsd(struct thread *, struct nfsd_nfsd_args *); @@ -250,57 +244,6 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, int err, return (mreq); } -/* - * nfs_realign: - * - * Check for badly aligned mbuf data and realign by copying the unaligned - * portion of the data into a new mbuf chain and freeing the portions - * of the old chain that were replaced. - * - * We cannot simply realign the data within the existing mbuf chain - * because the underlying buffers may contain other rpc commands and - * we cannot afford to overwrite them. - * - * We would prefer to avoid this situation entirely. The situation does - * not occur with NFS/UDP and is supposed to only occassionally occur - * with TCP. Use vfs.nfs.realign_count and realign_test to check this. - */ -void -nfs_realign(struct mbuf **pm) /* XXX COMMON */ -{ - struct mbuf *m; - struct mbuf *n = NULL; - int off = 0; - - ++nfs_realign_test; - while ((m = *pm) != NULL) { - if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { - MGET(n, M_WAIT, MT_DATA); - if (m->m_len >= MINCLSIZE) { - MCLGET(n, M_WAIT); - } - n->m_len = 0; - break; - } - pm = &m->m_next; - } - - /* - * If n is non-NULL, loop on m copying data, then replace the - * portion of the chain that had to be realigned. - */ - if (n != NULL) { - ++nfs_realign_count; - while (m) { - m_copyback(n, off, m->m_len, mtod(m, caddr_t)); - off += m->m_len; - m = m->m_next; - } - m_freem(*pm); - *pm = n; - } -} - static void nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) { @@ -334,7 +277,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) mreq = mrep = NULL; mreq = rqst->rq_args; rqst->rq_args = NULL; - nfs_realign(&mreq); + (void)nfs_realign(&mreq, M_WAIT); /* * Note: we want rq_addr, not svc_getrpccaller for nd_nam2 - diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c index ee0614b4dc9..d84261e8249 100644 --- a/sys/nfsserver/nfs_srvsubs.c +++ b/sys/nfsserver/nfs_srvsubs.c @@ -560,6 +560,7 @@ DECLARE_MODULE(nfsserver, nfsserver_mod, SI_SUB_VFS, SI_ORDER_ANY); MODULE_VERSION(nfsserver, 1); MODULE_DEPEND(nfsserver, nfssvc, 1, 1, 1); MODULE_DEPEND(nfsserver, krpc, 1, 1, 1); +MODULE_DEPEND(nfsserver, nfs_common, 1, 1, 1); /* * Set up nameidata for a lookup() call and do it. From 18148841f8a3486c27195573141080a565ee326e Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 22 Feb 2010 22:27:26 +0000 Subject: [PATCH 1490/2592] MFC r203533: Remove two files that are not needed by FreeBSD. Approved by: pjd --- .../contrib/opensolaris/uts/common/sys/dkio.h | 497 ------------------ .../opensolaris/uts/common/sys/dklabel.h | 277 ---------- 2 files changed, 774 deletions(-) delete mode 100644 sys/cddl/contrib/opensolaris/uts/common/sys/dkio.h delete mode 100644 sys/cddl/contrib/opensolaris/uts/common/sys/dklabel.h diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dkio.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dkio.h deleted file mode 100644 index 18f49e513af..00000000000 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dkio.h +++ /dev/null @@ -1,497 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DKIO_H -#define _SYS_DKIO_H - -#include /* Needed for NDKMAP define */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Structures and definitions for disk io control commands - */ - -/* - * Structures used as data by ioctl calls. - */ - -#define DK_DEVLEN 16 /* device name max length, including */ - /* unit # & NULL (ie - "xyc1") */ - -/* - * Used for controller info - */ -struct dk_cinfo { - char dki_cname[DK_DEVLEN]; /* controller name (no unit #) */ - ushort_t dki_ctype; /* controller type */ - ushort_t dki_flags; /* flags */ - ushort_t dki_cnum; /* controller number */ - uint_t dki_addr; /* controller address */ - uint_t dki_space; /* controller bus type */ - uint_t dki_prio; /* interrupt priority */ - uint_t dki_vec; /* interrupt vector */ - char dki_dname[DK_DEVLEN]; /* drive name (no unit #) */ - uint_t dki_unit; /* unit number */ - uint_t dki_slave; /* slave number */ - ushort_t dki_partition; /* partition number */ - ushort_t dki_maxtransfer; /* max. transfer size in DEV_BSIZE */ -}; - -/* - * Controller types - */ -#define DKC_UNKNOWN 0 -#define DKC_CDROM 1 /* CD-ROM, SCSI or otherwise */ -#define DKC_WDC2880 2 -#define DKC_XXX_0 3 /* unassigned */ -#define DKC_XXX_1 4 /* unassigned */ -#define DKC_DSD5215 5 -#define DKC_ACB4000 7 -#define DKC_MD21 8 -#define DKC_XXX_2 9 /* unassigned */ -#define DKC_NCRFLOPPY 10 -#define DKC_SMSFLOPPY 12 -#define DKC_SCSI_CCS 13 /* SCSI CCS compatible */ -#define DKC_INTEL82072 14 /* native floppy chip */ -#define DKC_MD 16 /* meta-disk (virtual-disk) driver */ -#define DKC_INTEL82077 19 /* 82077 floppy disk controller */ -#define DKC_DIRECT 20 /* Intel direct attached device i.e. IDE */ -#define DKC_PCMCIA_MEM 21 /* PCMCIA memory disk-like type */ -#define DKC_PCMCIA_ATA 22 /* PCMCIA AT Attached type */ -#define DKC_VBD 23 /* virtual block device */ - -/* - * Sun reserves up through 1023 - */ - -#define DKC_CUSTOMER_BASE 1024 - -/* - * Flags - */ -#define DKI_BAD144 0x01 /* use DEC std 144 bad sector fwding */ -#define DKI_MAPTRK 0x02 /* controller does track mapping */ -#define DKI_FMTTRK 0x04 /* formats only full track at a time */ -#define DKI_FMTVOL 0x08 /* formats only full volume at a time */ -#define DKI_FMTCYL 0x10 /* formats only full cylinders at a time */ -#define DKI_HEXUNIT 0x20 /* unit number is printed as 3 hex digits */ -#define DKI_PCMCIA_PFD 0x40 /* PCMCIA pseudo-floppy memory card */ - -/* - * Used for all partitions - */ -struct dk_allmap { - struct dk_map dka_map[NDKMAP]; -}; - -#if defined(_SYSCALL32) -struct dk_allmap32 { - struct dk_map32 dka_map[NDKMAP]; -}; -#endif /* _SYSCALL32 */ - -/* - * Definition of a disk's geometry - */ -struct dk_geom { - unsigned short dkg_ncyl; /* # of data cylinders */ - unsigned short dkg_acyl; /* # of alternate cylinders */ - unsigned short dkg_bcyl; /* cyl offset (for fixed head area) */ - unsigned short dkg_nhead; /* # of heads */ - unsigned short dkg_obs1; /* obsolete */ - unsigned short dkg_nsect; /* # of data sectors per track */ - unsigned short dkg_intrlv; /* interleave factor */ - unsigned short dkg_obs2; /* obsolete */ - unsigned short dkg_obs3; /* obsolete */ - unsigned short dkg_apc; /* alternates per cyl (SCSI only) */ - unsigned short dkg_rpm; /* revolutions per minute */ - unsigned short dkg_pcyl; /* # of physical cylinders */ - unsigned short dkg_write_reinstruct; /* # sectors to skip, writes */ - unsigned short dkg_read_reinstruct; /* # sectors to skip, reads */ - unsigned short dkg_extra[7]; /* for compatible expansion */ -}; - -/* - * These defines are for historic compatibility with old drivers. - */ -#define dkg_bhead dkg_obs1 /* used to be head offset */ -#define dkg_gap1 dkg_obs2 /* used to be gap1 */ -#define dkg_gap2 dkg_obs3 /* used to be gap2 */ - -/* - * Disk io control commands - * Warning: some other ioctls with the DIOC prefix exist elsewhere. - * The Generic DKIOC numbers are from 0 - 50. - * The Floppy Driver uses 51 - 100. - * The Hard Disk (except SCSI) 101 - 106. (these are obsolete) - * The CDROM Driver 151 - 200. - * The USCSI ioctl 201 - 250. - */ -#define DKIOC (0x04 << 8) - -/* - * The following ioctls are generic in nature and need to be - * suported as appropriate by all disk drivers - */ -#define DKIOCGGEOM (DKIOC|1) /* Get geometry */ -#define DKIOCINFO (DKIOC|3) /* Get info */ -#define DKIOCEJECT (DKIOC|6) /* Generic 'eject' */ -#define DKIOCGVTOC (DKIOC|11) /* Get VTOC */ -#define DKIOCSVTOC (DKIOC|12) /* Set VTOC & Write to Disk */ - -#define DKIOCGEXTVTOC (DKIOC|23) /* Get extended VTOC */ -#define DKIOCSEXTVTOC (DKIOC|24) /* Set extended VTOC, Write to Disk */ - -/* - * Disk Cache Controls. These ioctls should be supported by - * all disk drivers. - * - * DKIOCFLUSHWRITECACHE when used from user-mode ignores the ioctl - * argument, but it should be passed as NULL to allow for future - * reinterpretation. From user-mode, this ioctl request is synchronous. - * - * When invoked from within the kernel, the arg can be NULL to indicate - * a synchronous request or can be the address of a struct dk_callback - * to request an asynchronous callback when the flush request is complete. - * In this case, the flag to the ioctl must include FKIOCTL and the - * dkc_callback field of the pointed to struct must be non-null or the - * request is made synchronously. - * - * In the callback case: if the ioctl returns 0, a callback WILL be performed. - * If the ioctl returns non-zero, a callback will NOT be performed. - * NOTE: In some cases, the callback may be done BEFORE the ioctl call - * returns. The caller's locking strategy should be prepared for this case. - */ -#define DKIOCFLUSHWRITECACHE (DKIOC|34) /* flush cache to phys medium */ - -struct dk_callback { - void (*dkc_callback)(void *dkc_cookie, int error); - void *dkc_cookie; - int dkc_flag; -}; - -/* bit flag definitions for dkc_flag */ -#define FLUSH_VOLATILE 0x1 /* Bit 0: if set, only flush */ - /* volatile cache; otherwise, flush */ - /* volatile and non-volatile cache */ - -#define DKIOCGETWCE (DKIOC|36) /* Get current write cache */ - /* enablement status */ -#define DKIOCSETWCE (DKIOC|37) /* Enable/Disable write cache */ - -/* - * The following ioctls are used by Sun drivers to communicate - * with their associated format routines. Support of these ioctls - * is not required of foreign drivers - */ -#define DKIOCSGEOM (DKIOC|2) /* Set geometry */ -#define DKIOCSAPART (DKIOC|4) /* Set all partitions */ -#define DKIOCGAPART (DKIOC|5) /* Get all partitions */ -#define DKIOCG_PHYGEOM (DKIOC|32) /* get physical geometry */ -#define DKIOCG_VIRTGEOM (DKIOC|33) /* get virtual geometry */ - -/* - * The following ioctl's are removable media support - */ -#define DKIOCLOCK (DKIOC|7) /* Generic 'lock' */ -#define DKIOCUNLOCK (DKIOC|8) /* Generic 'unlock' */ -#define DKIOCSTATE (DKIOC|13) /* Inquire insert/eject state */ -#define DKIOCREMOVABLE (DKIOC|16) /* is media removable */ - - -/* - * ioctl for hotpluggable devices - */ -#define DKIOCHOTPLUGGABLE (DKIOC|35) /* is hotpluggable */ - -/* - * Ioctl to force driver to re-read the alternate partition and rebuild - * the internal defect map. - */ -#define DKIOCADDBAD (DKIOC|20) /* Re-read the alternate map (IDE) */ -#define DKIOCGETDEF (DKIOC|21) /* read defect list (IDE) */ - -/* - * Used by applications to get disk defect information from IDE - * drives. - */ -#ifdef _SYSCALL32 -struct defect_header32 { - int head; - caddr32_t buffer; -}; -#endif /* _SYSCALL32 */ - -struct defect_header { - int head; - caddr_t buffer; -}; - -#define DKIOCPARTINFO (DKIOC|22) /* Get partition or slice parameters */ -#define DKIOCEXTPARTINFO (DKIOC|19) /* Get extended partition or slice */ - /* parameters */ - - -/* - * Used by applications to get partition or slice information - */ -#ifdef _SYSCALL32 -struct part_info32 { - daddr32_t p_start; - int p_length; -}; -#endif /* _SYSCALL32 */ - -struct part_info { - daddr_t p_start; - int p_length; -}; - -struct extpart_info { - diskaddr_t p_start; - diskaddr_t p_length; -}; - -/* The following ioctls are for Optical Memory Device */ -#define DKIOC_EBP_ENABLE (DKIOC|40) /* enable by pass erase on write */ -#define DKIOC_EBP_DISABLE (DKIOC|41) /* disable by pass erase on write */ - -/* - * This state enum is the argument passed to the DKIOCSTATE ioctl. - */ -enum dkio_state { DKIO_NONE, DKIO_EJECTED, DKIO_INSERTED, DKIO_DEV_GONE }; - -#define DKIOCGMEDIAINFO (DKIOC|42) /* get information about the media */ - -/* - * ioctls to read/write mboot info. - */ -#define DKIOCGMBOOT (DKIOC|43) /* get mboot info */ -#define DKIOCSMBOOT (DKIOC|44) /* set mboot info */ - -/* - * ioctl to get the device temperature. - */ -#define DKIOCGTEMPERATURE (DKIOC|45) /* get temperature */ - -/* - * Used for providing the temperature. - */ - -struct dk_temperature { - uint_t dkt_flags; /* Flags */ - short dkt_cur_temp; /* Current disk temperature */ - short dkt_ref_temp; /* reference disk temperature */ -}; - -#define DKT_BYPASS_PM 0x1 -#define DKT_INVALID_TEMP 0xFFFF - - -/* - * Used for Media info or the current profile info - */ -struct dk_minfo { - uint_t dki_media_type; /* Media type or profile info */ - uint_t dki_lbsize; /* Logical blocksize of media */ - diskaddr_t dki_capacity; /* Capacity as # of dki_lbsize blks */ -}; - -/* - * Media types or profiles known - */ -#define DK_UNKNOWN 0x00 /* Media inserted - type unknown */ - - -/* - * SFF 8090 Specification Version 3, media types 0x01 - 0xfffe are retained to - * maintain compatibility with SFF8090. The following define the - * optical media type. - */ -#define DK_REMOVABLE_DISK 0x02 /* Removable Disk */ -#define DK_MO_ERASABLE 0x03 /* MO Erasable */ -#define DK_MO_WRITEONCE 0x04 /* MO Write once */ -#define DK_AS_MO 0x05 /* AS MO */ -#define DK_CDROM 0x08 /* CDROM */ -#define DK_CDR 0x09 /* CD-R */ -#define DK_CDRW 0x0A /* CD-RW */ -#define DK_DVDROM 0x10 /* DVD-ROM */ -#define DK_DVDR 0x11 /* DVD-R */ -#define DK_DVDRAM 0x12 /* DVD_RAM or DVD-RW */ - -/* - * Media types for other rewritable magnetic media - */ -#define DK_FIXED_DISK 0x10001 /* Fixed disk SCSI or otherwise */ -#define DK_FLOPPY 0x10002 /* Floppy media */ -#define DK_ZIP 0x10003 /* IOMEGA ZIP media */ -#define DK_JAZ 0x10004 /* IOMEGA JAZ media */ - -#define DKIOCSETEFI (DKIOC|17) /* Set EFI info */ -#define DKIOCGETEFI (DKIOC|18) /* Get EFI info */ - -#define DKIOCPARTITION (DKIOC|9) /* Get partition info */ - -/* - * Ioctls to get/set volume capabilities related to Logical Volume Managers. - * They include the ability to get/set capabilities and to issue a read to a - * specific underlying device of a replicated device. - */ - -#define DKIOCGETVOLCAP (DKIOC | 25) /* Get volume capabilities */ -#define DKIOCSETVOLCAP (DKIOC | 26) /* Set volume capabilities */ -#define DKIOCDMR (DKIOC | 27) /* Issue a directed read */ - -#define DKIOCDUMPINIT (DKIOC | 28) /* Dumpify a zvol */ -#define DKIOCDUMPFINI (DKIOC | 29) /* Un-Dumpify a zvol */ - -typedef uint_t volcapinfo_t; - -typedef uint_t volcapset_t; - -#define DKV_ABR_CAP 0x00000001 /* Support Appl.Based Recovery */ -#define DKV_DMR_CAP 0x00000002 /* Support Directed Mirror Read */ - -typedef struct volcap { - volcapinfo_t vc_info; /* Capabilities available */ - volcapset_t vc_set; /* Capabilities set */ -} volcap_t; - -#define VOL_SIDENAME 256 - -typedef struct vol_directed_rd { - int vdr_flags; - offset_t vdr_offset; - size_t vdr_nbytes; - size_t vdr_bytesread; - void *vdr_data; - int vdr_side; - char vdr_side_name[VOL_SIDENAME]; -} vol_directed_rd_t; - -#define DKV_SIDE_INIT (-1) -#define DKV_DMR_NEXT_SIDE 0x00000001 -#define DKV_DMR_DONE 0x00000002 -#define DKV_DMR_ERROR 0x00000004 -#define DKV_DMR_SUCCESS 0x00000008 -#define DKV_DMR_SHORT 0x00000010 - -#ifdef _MULTI_DATAMODEL -#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 -#pragma pack(4) -#endif -typedef struct vol_directed_rd32 { - int32_t vdr_flags; - offset_t vdr_offset; /* 64-bit element on 32-bit alignment */ - size32_t vdr_nbytes; - size32_t vdr_bytesread; - caddr32_t vdr_data; - int32_t vdr_side; - char vdr_side_name[VOL_SIDENAME]; -} vol_directed_rd32_t; -#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 -#pragma pack() -#endif -#endif /* _MULTI_DATAMODEL */ - -/* - * The ioctl is used to fetch disk's device type, vendor ID, - * model number/product ID, firmware revision and serial number together. - * - * Currently there are two device types - DKD_ATA_TYPE which means the - * disk is driven by cmdk/ata or dad/uata driver, and DKD_SCSI_TYPE - * which means the disk is driven by sd/scsi hba driver. - */ -#define DKIOC_GETDISKID (DKIOC|46) - -/* These two labels are for dkd_dtype of dk_disk_id_t */ -#define DKD_ATA_TYPE 0x01 /* ATA disk or legacy mode SATA disk */ -#define DKD_SCSI_TYPE 0x02 /* SCSI disk or native mode SATA disk */ - -#define DKD_ATA_MODEL 40 /* model number length */ -#define DKD_ATA_FWVER 8 /* firmware revision length */ -#define DKD_ATA_SERIAL 20 /* serial number length */ - -#define DKD_SCSI_VENDOR 8 /* vendor ID length */ -#define DKD_SCSI_PRODUCT 16 /* product ID length */ -#define DKD_SCSI_REVLEVEL 4 /* revision level length */ -#define DKD_SCSI_SERIAL 12 /* serial number length */ - -/* - * The argument type for DKIOC_GETDISKID ioctl. - */ -typedef struct dk_disk_id { - uint_t dkd_dtype; - union { - struct { - char dkd_amodel[DKD_ATA_MODEL]; /* 40 bytes */ - char dkd_afwver[DKD_ATA_FWVER]; /* 8 bytes */ - char dkd_aserial[DKD_ATA_SERIAL]; /* 20 bytes */ - } ata_disk_id; - struct { - char dkd_svendor[DKD_SCSI_VENDOR]; /* 8 bytes */ - char dkd_sproduct[DKD_SCSI_PRODUCT]; /* 16 bytes */ - char dkd_sfwver[DKD_SCSI_REVLEVEL]; /* 4 bytes */ - char dkd_sserial[DKD_SCSI_SERIAL]; /* 12 bytes */ - } scsi_disk_id; - } disk_id; -} dk_disk_id_t; - -/* - * The ioctl is used to update the firmware of device. - */ -#define DKIOC_UPDATEFW (DKIOC|47) - -/* The argument type for DKIOC_UPDATEFW ioctl */ -typedef struct dk_updatefw { - caddr_t dku_ptrbuf; /* pointer to firmware buf */ - uint_t dku_size; /* firmware buf length */ - uint8_t dku_type; /* firmware update type */ -} dk_updatefw_t; - -#ifdef _SYSCALL32 -typedef struct dk_updatefw_32 { - caddr32_t dku_ptrbuf; /* pointer to firmware buf */ - uint_t dku_size; /* firmware buf length */ - uint8_t dku_type; /* firmware update type */ -} dk_updatefw_32_t; -#endif /* _SYSCALL32 */ - -/* - * firmware update type - temporary or permanent use - */ -#define FW_TYPE_TEMP 0x0 /* temporary use */ -#define FW_TYPE_PERM 0x1 /* permanent use */ - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_DKIO_H */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dklabel.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dklabel.h deleted file mode 100644 index 01baa7157ca..00000000000 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dklabel.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DKLABEL_H -#define _SYS_DKLABEL_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Miscellaneous defines - */ -#define DKL_MAGIC 0xDABE /* magic number */ -#define FKL_MAGIC 0xff /* magic number for DOS floppies */ - -#if defined(_SUNOS_VTOC_16) -#define NDKMAP 16 /* # of logical partitions */ -#define DK_LABEL_LOC 1 /* location of disk label */ -#elif defined(_SUNOS_VTOC_8) -#define NDKMAP 8 /* # of logical partitions */ -#define DK_LABEL_LOC 0 /* location of disk label */ -#else -#error "No VTOC format defined." -#endif - -#define LEN_DKL_ASCII 128 /* length of dkl_asciilabel */ -#define LEN_DKL_VVOL 8 /* length of v_volume */ -#define DK_LABEL_SIZE 512 /* size of disk label */ -#define DK_MAX_BLOCKS 0x7fffffff /* max # of blocks handled */ - -/* - * Reserve two cylinders on SCSI disks. - * One is for the backup disk label and the other is for the deviceid. - * - * IPI disks only reserve one cylinder, but they will go away soon. - * CDROMs do not reserve any cylinders. - */ -#define DK_ACYL 2 - -/* - * Format of a Sun disk label. - * Resides in cylinder 0, head 0, sector 0. - * - * sizeof (struct dk_label) should be 512 (the current sector size), - * but should the sector size increase, this structure should remain - * at the beginning of the sector. - */ - -#if !defined(BLKADDR_TYPE) -#define BLKADDR_TYPE -#if defined(_EXTVTOC) -typedef unsigned long blkaddr_t; -typedef unsigned int blkaddr32_t; -#else -typedef daddr_t blkaddr_t; -typedef daddr32_t blkaddr32_t; -#endif -#endif - -/* - * partition headers: section 1 - * Returned in struct dk_allmap by ioctl DKIOC[SG]APART (dkio(7I)) - */ -struct dk_map { - blkaddr_t dkl_cylno; /* starting cylinder */ - blkaddr_t dkl_nblk; /* number of blocks; if == 0, */ - /* partition is undefined */ -}; - -/* - * partition headers: section 1 - * Fixed size for on-disk dk_label - */ -struct dk_map32 { - blkaddr32_t dkl_cylno; /* starting cylinder */ - blkaddr32_t dkl_nblk; /* number of blocks; if == 0, */ - /* partition is undefined */ -}; - -/* - * partition headers: section 2, - * brought over from AT&T SVr4 vtoc structure. - */ -struct dk_map2 { - uint16_t p_tag; /* ID tag of partition */ - uint16_t p_flag; /* permission flag */ -}; - -struct dkl_partition { - uint16_t p_tag; /* ID tag of partition */ - uint16_t p_flag; /* permision flags */ - blkaddr32_t p_start; /* start sector no of partition */ - blkaddr32_t p_size; /* # of blocks in partition */ -}; - - -/* - * VTOC inclusions from AT&T SVr4 - * Fixed sized types for on-disk VTOC - */ - -struct dk_vtoc { -#if defined(_SUNOS_VTOC_16) - uint32_t v_bootinfo[3]; /* info for mboot (unsupported) */ - uint32_t v_sanity; /* to verify vtoc sanity */ - uint32_t v_version; /* layout version */ - char v_volume[LEN_DKL_VVOL]; /* volume name */ - uint16_t v_sectorsz; /* sector size in bytes */ - uint16_t v_nparts; /* number of partitions */ - uint32_t v_reserved[10]; /* free space */ - struct dkl_partition v_part[NDKMAP]; /* partition headers */ - time32_t timestamp[NDKMAP]; /* partition timestamp (unsupported) */ - char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ -#elif defined(_SUNOS_VTOC_8) - uint32_t v_version; /* layout version */ - char v_volume[LEN_DKL_VVOL]; /* volume name */ - uint16_t v_nparts; /* number of partitions */ - struct dk_map2 v_part[NDKMAP]; /* partition hdrs, sec 2 */ - uint32_t v_bootinfo[3]; /* info needed by mboot */ - uint32_t v_sanity; /* to verify vtoc sanity */ - uint32_t v_reserved[10]; /* free space */ - time32_t v_timestamp[NDKMAP]; /* partition timestamp */ -#else -#error "No VTOC format defined." -#endif -}; - -/* - * define the amount of disk label padding needed to make - * the entire structure occupy 512 bytes. - */ -#if defined(_SUNOS_VTOC_16) -#define LEN_DKL_PAD (DK_LABEL_SIZE - \ - ((sizeof (struct dk_vtoc) + \ - (4 * sizeof (uint32_t)) + \ - (12 * sizeof (uint16_t)) + \ - (2 * (sizeof (uint16_t)))))) -#elif defined(_SUNOS_VTOC_8) -#define LEN_DKL_PAD (DK_LABEL_SIZE \ - - ((LEN_DKL_ASCII) + \ - (sizeof (struct dk_vtoc)) + \ - (sizeof (struct dk_map32) * NDKMAP) + \ - (14 * (sizeof (uint16_t))) + \ - (2 * (sizeof (uint16_t))))) -#else -#error "No VTOC format defined." -#endif - - -struct dk_label { -#if defined(_SUNOS_VTOC_16) - struct dk_vtoc dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */ - uint32_t dkl_pcyl; /* # of physical cylinders */ - uint32_t dkl_ncyl; /* # of data cylinders */ - uint16_t dkl_acyl; /* # of alternate cylinders */ - uint16_t dkl_bcyl; /* cyl offset (for fixed head area) */ - uint32_t dkl_nhead; /* # of heads */ - uint32_t dkl_nsect; /* # of data sectors per track */ - uint16_t dkl_intrlv; /* interleave factor */ - uint16_t dkl_skew; /* skew factor */ - uint16_t dkl_apc; /* alternates per cyl (SCSI only) */ - uint16_t dkl_rpm; /* revolutions per minute */ - uint16_t dkl_write_reinstruct; /* # sectors to skip, writes */ - uint16_t dkl_read_reinstruct; /* # sectors to skip, reads */ - uint16_t dkl_extra[4]; /* for compatible expansion */ - char dkl_pad[LEN_DKL_PAD]; /* unused part of 512 bytes */ -#elif defined(_SUNOS_VTOC_8) - char dkl_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ - struct dk_vtoc dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */ - uint16_t dkl_write_reinstruct; /* # sectors to skip, writes */ - uint16_t dkl_read_reinstruct; /* # sectors to skip, reads */ - char dkl_pad[LEN_DKL_PAD]; /* unused part of 512 bytes */ - uint16_t dkl_rpm; /* rotations per minute */ - uint16_t dkl_pcyl; /* # physical cylinders */ - uint16_t dkl_apc; /* alternates per cylinder */ - uint16_t dkl_obs1; /* obsolete */ - uint16_t dkl_obs2; /* obsolete */ - uint16_t dkl_intrlv; /* interleave factor */ - uint16_t dkl_ncyl; /* # of data cylinders */ - uint16_t dkl_acyl; /* # of alternate cylinders */ - uint16_t dkl_nhead; /* # of heads in this partition */ - uint16_t dkl_nsect; /* # of 512 byte sectors per track */ - uint16_t dkl_obs3; /* obsolete */ - uint16_t dkl_obs4; /* obsolete */ - struct dk_map32 dkl_map[NDKMAP]; /* logical partition headers */ -#else -#error "No VTOC format defined." -#endif - uint16_t dkl_magic; /* identifies this label format */ - uint16_t dkl_cksum; /* xor checksum of sector */ -}; - -#if defined(_SUNOS_VTOC_16) -#define dkl_asciilabel dkl_vtoc.v_asciilabel -#define v_timestamp timestamp - -#elif defined(_SUNOS_VTOC_8) - -/* - * These defines are for historic compatibility with old drivers. - */ -#define dkl_gap1 dkl_obs1 /* used to be gap1 */ -#define dkl_gap2 dkl_obs2 /* used to be gap2 */ -#define dkl_bhead dkl_obs3 /* used to be label head offset */ -#define dkl_ppart dkl_obs4 /* used to by physical partition */ -#else -#error "No VTOC format defined." -#endif - -struct fk_label { /* DOS floppy label */ - uchar_t fkl_type; - uchar_t fkl_magich; - uchar_t fkl_magicl; - uchar_t filler; -}; - -/* - * Layout of stored fabricated device id (on-disk) - */ -#define DK_DEVID_BLKSIZE (512) -#define DK_DEVID_SIZE (DK_DEVID_BLKSIZE - ((sizeof (uchar_t) * 7))) -#define DK_DEVID_REV_MSB (0) -#define DK_DEVID_REV_LSB (1) - -struct dk_devid { - uchar_t dkd_rev_hi; /* revision (MSB) */ - uchar_t dkd_rev_lo; /* revision (LSB) */ - uchar_t dkd_flags; /* flags (not used yet) */ - uchar_t dkd_devid[DK_DEVID_SIZE]; /* devid stored here */ - uchar_t dkd_checksum3; /* checksum (MSB) */ - uchar_t dkd_checksum2; - uchar_t dkd_checksum1; - uchar_t dkd_checksum0; /* checksum (LSB) */ -}; - -#define DKD_GETCHKSUM(dkd) ((dkd)->dkd_checksum3 << 24) + \ - ((dkd)->dkd_checksum2 << 16) + \ - ((dkd)->dkd_checksum1 << 8) + \ - ((dkd)->dkd_checksum0) - -#define DKD_FORMCHKSUM(c, dkd) (dkd)->dkd_checksum3 = hibyte(hiword((c))); \ - (dkd)->dkd_checksum2 = lobyte(hiword((c))); \ - (dkd)->dkd_checksum1 = hibyte(loword((c))); \ - (dkd)->dkd_checksum0 = lobyte(loword((c))); -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_DKLABEL_H */ From d21288b029644a924bd561bad34f0e0548a29a7e Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 23 Feb 2010 00:40:02 +0000 Subject: [PATCH 1491/2592] MFC r203728: - Return EAFNOSUPPORT instead of EINVAL for unsupported address family, this matches the Linux behavior. - Check if we have sufficient space allocated for socket structure, which fixes a buffer overflow when wrong length is being passed into the emulation layer. [1] PR: kern/138860 Submitted by: Mateusz Guzik Reported by: Alexander Best [1] --- sys/compat/linux/linux_socket.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 396a71e8495..d94d9263f8e 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -128,7 +128,7 @@ do_sa_get(struct sockaddr **sap, const struct osockaddr *osa, int *osalen, bdom = linux_to_bsd_domain(kosa->sa_family); if (bdom == -1) { - error = EINVAL; + error = EAFNOSUPPORT; goto out; } @@ -157,8 +157,13 @@ do_sa_get(struct sockaddr **sap, const struct osockaddr *osa, int *osalen, } } else #endif - if (bdom == AF_INET) + if (bdom == AF_INET) { alloclen = sizeof(struct sockaddr_in); + if (*osalen < alloclen) { + error = EINVAL; + goto out; + } + } sa = (struct sockaddr *) kosa; sa->sa_family = bdom; From 624e666b5db05c0353b94b213b93c463d4c00a8d Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 23 Feb 2010 01:00:15 +0000 Subject: [PATCH 1492/2592] MFC r202812: Add H55 ID from Mike Tancsa, with minor rewording from avg@. PR: kern/143068 Submitted by: Mike Tancsa (Sentex) --- sys/dev/ichwd/ichwd.c | 1 + sys/dev/ichwd/ichwd.h | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/dev/ichwd/ichwd.c b/sys/dev/ichwd/ichwd.c index a47eccd3d39..33a64db0936 100644 --- a/sys/dev/ichwd/ichwd.c +++ b/sys/dev/ichwd/ichwd.c @@ -109,6 +109,7 @@ static struct ichwd_device ichwd_devices[] = { { DEVICEID_ICH10D, "Intel ICH10D watchdog timer", 10 }, { DEVICEID_ICH10DO, "Intel ICH10DO watchdog timer", 10 }, { DEVICEID_ICH10R, "Intel ICH10R watchdog timer", 10 }, + { DEVICEID_H55, "Intel H55 watchdog timer", 10 }, { 0, NULL, 0 }, }; diff --git a/sys/dev/ichwd/ichwd.h b/sys/dev/ichwd/ichwd.h index 51ed26ddfd9..549c4c615db 100644 --- a/sys/dev/ichwd/ichwd.h +++ b/sys/dev/ichwd/ichwd.h @@ -99,6 +99,7 @@ struct ichwd_softc { #define DEVICEID_ICH10D 0x3a1a #define DEVICEID_ICH10DO 0x3a14 #define DEVICEID_ICH10R 0x3a16 +#define DEVICEID_H55 0x3b06 /* ICH LPC Interface Bridge Registers (ICH5 and older) */ #define ICH_GEN_STA 0xd4 From 1b4509372f3d474dd7b05789ab5eb225f85fd27c Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Tue, 23 Feb 2010 16:46:34 +0000 Subject: [PATCH 1493/2592] MFC r201684. Teach the (gpt)zfsboot and zfsloader raidz code to use its buffers more efficiently. Before this patch, in the worst case memory use would increase exponentially on the number of drives in the raidz vdev. Submitted by: Matt Reimer Sponsored by: VPOP Technologies, Inc. Silence from: dfr --- sys/cddl/boot/zfs/zfssubr.c | 50 +++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/sys/cddl/boot/zfs/zfssubr.c b/sys/cddl/boot/zfs/zfssubr.c index 4013986c18c..25d349b1ce4 100644 --- a/sys/cddl/boot/zfs/zfssubr.c +++ b/sys/cddl/boot/zfs/zfssubr.c @@ -454,7 +454,7 @@ vdev_raidz_reconstruct_q(raidz_col_t *cols, int nparity, int acols, int x) static void vdev_raidz_reconstruct_pq(raidz_col_t *cols, int nparity, int acols, - int x, int y) + int x, int y, void *temp_p, void *temp_q) { uint8_t *p, *q, *pxy, *qxy, *xd, *yd, tmp, a, b, aexp, bexp; void *pdata, *qdata; @@ -478,10 +478,8 @@ vdev_raidz_reconstruct_pq(raidz_col_t *cols, int nparity, int acols, xsize = cols[x].rc_size; ysize = cols[y].rc_size; - cols[VDEV_RAIDZ_P].rc_data = - zfs_alloc_temp(cols[VDEV_RAIDZ_P].rc_size); - cols[VDEV_RAIDZ_Q].rc_data = - zfs_alloc_temp(cols[VDEV_RAIDZ_Q].rc_size); + cols[VDEV_RAIDZ_P].rc_data = temp_p; + cols[VDEV_RAIDZ_Q].rc_data = temp_q; cols[x].rc_size = 0; cols[y].rc_size = 0; @@ -551,9 +549,12 @@ vdev_raidz_read(vdev_t *vdev, const blkptr_t *bp, void *buf, uint64_t f = b % dcols; uint64_t o = (b / dcols) << unit_shift; uint64_t q, r, coff; - int c, c1, bc, col, acols, devidx, asize, n; + int c, c1, bc, col, acols, devidx, asize, n, max_rc_size; static raidz_col_t cols[16]; raidz_col_t *rc, *rc1; + void *orig, *orig1, *temp_p, *temp_q; + + orig = orig1 = temp_p = temp_q = NULL; q = s / (dcols - nparity); r = s - q * (dcols - nparity); @@ -561,6 +562,7 @@ vdev_raidz_read(vdev_t *vdev, const blkptr_t *bp, void *buf, acols = (q == 0 ? bc : dcols); asize = 0; + max_rc_size = 0; for (c = 0; c < acols; c++) { col = f + c; @@ -577,6 +579,8 @@ vdev_raidz_read(vdev_t *vdev, const blkptr_t *bp, void *buf, cols[c].rc_tried = 0; cols[c].rc_skipped = 0; asize += cols[c].rc_size; + if (cols[c].rc_size > max_rc_size) + max_rc_size = cols[c].rc_size; } asize = roundup(asize, (nparity + 1) << unit_shift); @@ -777,8 +781,13 @@ reconstruct: //ASSERT(c != acols); //ASSERT(!rc->rc_skipped || rc->rc_error == ENXIO || rc->rc_error == ESTALE); + if (temp_p == NULL) + temp_p = zfs_alloc_temp(max_rc_size); + if (temp_q == NULL) + temp_q = zfs_alloc_temp(max_rc_size); + vdev_raidz_reconstruct_pq(cols, nparity, acols, - c1, c); + c1, c, temp_p, temp_q); if (zio_checksum_error(bp, buf) == 0) return (0); @@ -845,18 +854,12 @@ reconstruct: return (EIO); } - asize = 0; - for (c = 0; c < acols; c++) { - rc = &cols[c]; - if (rc->rc_size > asize) - asize = rc->rc_size; - } if (cols[VDEV_RAIDZ_P].rc_error == 0) { /* * Attempt to reconstruct the data from parity P. */ - void *orig; - orig = zfs_alloc_temp(asize); + if (orig == NULL) + orig = zfs_alloc_temp(max_rc_size); for (c = nparity; c < acols; c++) { rc = &cols[c]; @@ -874,8 +877,8 @@ reconstruct: /* * Attempt to reconstruct the data from parity Q. */ - void *orig; - orig = zfs_alloc_temp(asize); + if (orig == NULL) + orig = zfs_alloc_temp(max_rc_size); for (c = nparity; c < acols; c++) { rc = &cols[c]; @@ -895,9 +898,14 @@ reconstruct: /* * Attempt to reconstruct the data from both P and Q. */ - void *orig, *orig1; - orig = zfs_alloc_temp(asize); - orig1 = zfs_alloc_temp(asize); + if (orig == NULL) + orig = zfs_alloc_temp(max_rc_size); + if (orig1 == NULL) + orig1 = zfs_alloc_temp(max_rc_size); + if (temp_p == NULL) + temp_p = zfs_alloc_temp(max_rc_size); + if (temp_q == NULL) + temp_q = zfs_alloc_temp(max_rc_size); for (c = nparity; c < acols - 1; c++) { rc = &cols[c]; @@ -909,7 +917,7 @@ reconstruct: memcpy(orig1, rc1->rc_data, rc1->rc_size); vdev_raidz_reconstruct_pq(cols, nparity, - acols, c, c1); + acols, c, c1, temp_p, temp_q); if (zio_checksum_error(bp, buf) == 0) return (0); From bb2f41f9a41b1e64212a7f9fcb16f5c8216acf69 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Wed, 24 Feb 2010 15:27:31 +0000 Subject: [PATCH 1494/2592] MFC r202945: Fixes for ls(1) long format (-l) output: - Allow -h option to work if the listing contains at least one device file. - Align major and minor device numbers correctly to the size field. PR: bin/125678 --- bin/ls/ls.c | 28 ++++++++++++++++++++-------- bin/ls/ls.h | 5 ++++- bin/ls/print.c | 38 ++++++++++++++++++++++++++------------ 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 4ad01f4d4a9..e884555b077 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -559,7 +559,8 @@ display(const FTSENT *p, FTSENT *list, int options) long maxblock; u_long btotal, labelstrlen, maxinode, maxlen, maxnlink; u_long maxlabelstr; - int bcfile, maxflags; + u_int devstrlen; + int maxflags; gid_t maxgroup; uid_t maxuser; size_t flen, ulen, glen; @@ -651,7 +652,7 @@ display(const FTSENT *p, FTSENT *list, int options) MAKENINES(maxsize); free(jinitmax); } - bcfile = 0; + devstrlen = 0; flags = NULL; for (cur = list, entries = 0; cur; cur = cur->fts_link) { if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) { @@ -791,9 +792,15 @@ label_out: np->group = &np->data[ulen + 1]; (void)strcpy(np->group, group); - if (S_ISCHR(sp->st_mode) || - S_ISBLK(sp->st_mode)) - bcfile = 1; + if ((S_ISCHR(sp->st_mode) || + S_ISBLK(sp->st_mode)) && + devstrlen < DEVSTR_HEX_LEN) { + if (minor(sp->st_rdev) > 255 || + minor(sp->st_rdev) < 0) + devstrlen = DEVSTR_HEX_LEN; + else + devstrlen = DEVSTR_LEN; + } if (f_flags) { np->flags = &np->data[ulen + glen + 2]; @@ -825,7 +832,6 @@ label_out: d.entries = entries; d.maxlen = maxlen; if (needstats) { - d.bcfile = bcfile; d.btotal = btotal; (void)snprintf(buf, sizeof(buf), "%lu", maxblock); d.s_block = strlen(buf); @@ -836,8 +842,14 @@ label_out: d.s_inode = strlen(buf); (void)snprintf(buf, sizeof(buf), "%lu", maxnlink); d.s_nlink = strlen(buf); - (void)snprintf(buf, sizeof(buf), "%ju", maxsize); - d.s_size = strlen(buf); + if (f_humanval) + d.s_size = HUMANVALSTR_LEN; + else { + (void)snprintf(buf, sizeof(buf), "%ju", maxsize); + d.s_size = strlen(buf); + } + if (d.s_size < devstrlen) + d.s_size = devstrlen; d.s_user = maxuser; } printfcn(&d); diff --git a/bin/ls/ls.h b/bin/ls/ls.h index f01e3519be1..a74abf0c9e5 100644 --- a/bin/ls/ls.h +++ b/bin/ls/ls.h @@ -35,6 +35,10 @@ #define NO_PRINT 1 +#define HUMANVALSTR_LEN 5 +#define DEVSTR_LEN 8 +#define DEVSTR_HEX_LEN 15 + extern long blocksize; /* block size units */ extern int f_accesstime; /* use time of last access */ @@ -62,7 +66,6 @@ extern int f_color; /* add type in color for non-regular files */ typedef struct { FTSENT *list; u_long btotal; - int bcfile; int entries; int maxlen; u_int s_block; diff --git a/bin/ls/print.c b/bin/ls/print.c index 3b80d93aefe..3f2033c404d 100644 --- a/bin/ls/print.c +++ b/bin/ls/print.c @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include "extern.h" static int printaname(const FTSENT *, u_long, u_long); +static void printdev(size_t, dev_t); static void printlink(const FTSENT *); static void printtime(time_t); static int printtype(u_int); @@ -165,16 +166,7 @@ printlong(const DISPLAY *dp) if (f_label) (void)printf("%-*s ", dp->s_label, np->label); if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) - if (minor(sp->st_rdev) > 255 || minor(sp->st_rdev) < 0) - (void)printf("%3d, 0x%08x ", - major(sp->st_rdev), - (u_int)minor(sp->st_rdev)); - else - (void)printf("%3d, %3d ", - major(sp->st_rdev), minor(sp->st_rdev)); - else if (dp->bcfile) - (void)printf("%*s%*jd ", - 8 - dp->s_size, "", dp->s_size, sp->st_size); + printdev(dp->s_size, sp->st_rdev); else printsize(dp->s_size, sp->st_size); if (f_accesstime) @@ -353,6 +345,24 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield) return (chcnt); } +/* + * Print device special file major and minor numbers. + */ +static void +printdev(size_t width, dev_t dev) +{ + char buf[DEVSTR_HEX_LEN + 1]; + + if (minor(dev) > 255 || minor(dev) < 0) + (void)snprintf(buf, sizeof(buf), "%3d, 0x%08x", + major(dev), (u_int)minor(dev)); + else + (void)snprintf(buf, sizeof(buf), "%3d, %3d", + major(dev), minor(dev)); + + (void)printf("%*s ", (u_int)width, buf); +} + static void printtime(time_t ftime) { @@ -592,11 +602,15 @@ printsize(size_t width, off_t bytes) { if (f_humanval) { - char buf[5]; + /* + * Reserve one space before the size and allocate room for + * the trailing '\0'. + */ + char buf[HUMANVALSTR_LEN - 1 + 1]; humanize_number(buf, sizeof(buf), (int64_t)bytes, "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); - (void)printf("%5s ", buf); + (void)printf("%*s ", (u_int)width, buf); } else (void)printf("%*jd ", (u_int)width, bytes); } From 0bd1aed098c7cd76582bb40c36c1b0fb22dceb43 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Wed, 24 Feb 2010 20:20:02 +0000 Subject: [PATCH 1495/2592] MFC r203924: Call the proper linkup routine in PowerPC Book-E machdep. Submitted by: attilio --- sys/powerpc/booke/machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index 9f5960b6daa..d2e25e79ded 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -384,7 +384,7 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) init_param1(); /* Start initializing proc0 and thread0. */ - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); thread0.td_frame = &frame0; /* Set up per-cpu data and store the pointer in SPR general 0. */ From daeeeefea04ba7b0e821cc17b472f0c43452dcb0 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 24 Feb 2010 21:20:25 +0000 Subject: [PATCH 1496/2592] MFC 204086: - Don't emit a warning in 'show adapter' if the IOC2 or IOC6 pages are not present. mpt(4) controllers that do not support RAID do not have an IOC6 page, for example. - Correct a check for a missing page error in a debug function. --- usr.sbin/mptutil/mpt_show.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/usr.sbin/mptutil/mpt_show.c b/usr.sbin/mptutil/mpt_show.c index e0b6b74d136..5a2a9463c81 100644 --- a/usr.sbin/mptutil/mpt_show.c +++ b/usr.sbin/mptutil/mpt_show.c @@ -78,6 +78,7 @@ show_adapter(int ac, char **av) CONFIG_PAGE_MANUFACTURING_0 *man0; CONFIG_PAGE_IOC_2 *ioc2; CONFIG_PAGE_IOC_6 *ioc6; + U16 IOCStatus; int fd, comma; if (ac != 1) { @@ -108,7 +109,7 @@ show_adapter(int ac, char **av) free(man0); - ioc2 = mpt_read_ioc_page(fd, 2, NULL); + ioc2 = mpt_read_ioc_page(fd, 2, &IOCStatus); if (ioc2 != NULL) { printf(" RAID Levels:"); comma = 0; @@ -151,9 +152,11 @@ show_adapter(int ac, char **av) printf(" none"); printf("\n"); free(ioc2); - } + } else if ((IOCStatus & MPI_IOCSTATUS_MASK) != + MPI_IOCSTATUS_CONFIG_INVALID_PAGE) + warnx("mpt_read_ioc_page(2): %s", mpt_ioc_status(IOCStatus)); - ioc6 = mpt_read_ioc_page(fd, 6, NULL); + ioc6 = mpt_read_ioc_page(fd, 6, &IOCStatus); if (ioc6 != NULL) { display_stripe_map(" RAID0 Stripes", ioc6->SupportedStripeSizeMapIS); @@ -172,7 +175,9 @@ show_adapter(int ac, char **av) printf("-%u", ioc6->MaxDrivesIME); printf("\n"); free(ioc6); - } + } else if ((IOCStatus & MPI_IOCSTATUS_MASK) != + MPI_IOCSTATUS_CONFIG_INVALID_PAGE) + warnx("mpt_read_ioc_page(6): %s", mpt_ioc_status(IOCStatus)); /* TODO: Add an ioctl to fetch IOC_FACTS and print firmware version. */ @@ -541,7 +546,8 @@ show_physdisks(int ac, char **av) for (i = 0; i <= 0xff; i++) { pinfo = mpt_pd_info(fd, i, &IOCStatus); if (pinfo == NULL) { - if (IOCStatus != MPI_IOCSTATUS_CONFIG_INVALID_PAGE) + if ((IOCStatus & MPI_IOCSTATUS_MASK) != + MPI_IOCSTATUS_CONFIG_INVALID_PAGE) warnx("mpt_pd_info(%d): %s", i, mpt_ioc_status(IOCStatus)); continue; From 8224141fb79bdd7d3368a77e315ac1ccb64e148e Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 24 Feb 2010 21:29:18 +0000 Subject: [PATCH 1497/2592] MFC 204090: Fix mptutil's method for locating disk devices attached to a specific mpt(4) controller. Previously, the code assumed that multiple match patterns provided to an XPT_DEV_MATCH request were ANDed together. Instead, they are ORed. Instead, to match peripherals for a specific bus, one query needs to be performed to lookup the path ID of the bus. A second query can then be performed matching peripherals attached to that path. This approach also makes the code a bit cleaner as the returned match results do not mix buses and perphierals. --- usr.sbin/mptutil/mpt_cam.c | 222 ++++++++++++++++++------------------- 1 file changed, 109 insertions(+), 113 deletions(-) diff --git a/usr.sbin/mptutil/mpt_cam.c b/usr.sbin/mptutil/mpt_cam.c index 0d20c7db601..b14451a6178 100644 --- a/usr.sbin/mptutil/mpt_cam.c +++ b/usr.sbin/mptutil/mpt_cam.c @@ -56,15 +56,75 @@ xpt_open(void) return (xptfd); } +/* Fetch the path id of bus 0 for the opened mpt controller. */ +static int +fetch_path_id(path_id_t *path_id) +{ + struct bus_match_pattern *b; + union ccb ccb; + size_t bufsize; + + if (xpt_open() < 0) + return (ENXIO); + + /* First, find the path id of bus 0 for this mpt controller. */ + bzero(&ccb, sizeof(ccb)); + + ccb.ccb_h.func_code = XPT_DEV_MATCH; + + bufsize = sizeof(struct dev_match_result) * 1; + ccb.cdm.num_matches = 0; + ccb.cdm.match_buf_len = bufsize; + ccb.cdm.matches = calloc(1, bufsize); + + bufsize = sizeof(struct dev_match_pattern) * 1; + ccb.cdm.num_patterns = 1; + ccb.cdm.pattern_buf_len = bufsize; + ccb.cdm.patterns = calloc(1, bufsize); + + /* Match mptX bus 0. */ + ccb.cdm.patterns[0].type = DEV_MATCH_BUS; + b = &ccb.cdm.patterns[0].pattern.bus_pattern; + snprintf(b->dev_name, sizeof(b->dev_name), "mpt"); + b->unit_number = mpt_unit; + b->bus_id = 0; + b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID; + + if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { + free(ccb.cdm.matches); + free(ccb.cdm.patterns); + return (errno); + } + free(ccb.cdm.patterns); + + if (((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) || + (ccb.cdm.status != CAM_DEV_MATCH_LAST)) { + warnx("fetch_path_id got CAM error %#x, CDM error %d\n", + ccb.ccb_h.status, ccb.cdm.status); + free(ccb.cdm.matches); + return (EIO); + } + + /* We should have exactly 1 match for the bus. */ + if (ccb.cdm.num_matches != 1 || + ccb.cdm.matches[0].type != DEV_MATCH_BUS) { + free(ccb.cdm.matches); + return (ENOENT); + } + *path_id = ccb.cdm.matches[0].result.bus_result.path_id; + free(ccb.cdm.matches); + return (0); +} + int mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd) { - struct bus_match_pattern *b; struct periph_match_pattern *p; struct periph_match_result *r; union ccb ccb; + path_id_t path_id; size_t bufsize; - int i; + int error, i; /* mpt(4) only handles devices on bus 0. */ if (VolumeBus != 0) @@ -73,6 +133,11 @@ mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd) if (xpt_open() < 0) return (ENXIO); + /* Find the path ID of bus 0. */ + error = fetch_path_id(&path_id); + if (error) + return (error); + bzero(&ccb, sizeof(ccb)); ccb.ccb_h.func_code = XPT_DEV_MATCH; @@ -85,25 +150,18 @@ mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd) ccb.cdm.match_buf_len = bufsize; ccb.cdm.matches = calloc(1, bufsize); - bufsize = sizeof(struct dev_match_pattern) * 2; - ccb.cdm.num_patterns = 2; + bufsize = sizeof(struct dev_match_pattern) * 1; + ccb.cdm.num_patterns = 1; ccb.cdm.pattern_buf_len = bufsize; ccb.cdm.patterns = calloc(1, bufsize); - /* Match mptX bus 0. */ - ccb.cdm.patterns[0].type = DEV_MATCH_BUS; - b = &ccb.cdm.patterns[0].pattern.bus_pattern; - snprintf(b->dev_name, sizeof(b->dev_name), "mpt"); - b->unit_number = mpt_unit; - b->bus_id = 0; - b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID; - /* Look for a "da" device at the specified target and lun. */ - ccb.cdm.patterns[1].type = DEV_MATCH_PERIPH; - p = &ccb.cdm.patterns[1].pattern.periph_pattern; + ccb.cdm.patterns[0].type = DEV_MATCH_PERIPH; + p = &ccb.cdm.patterns[0].pattern.periph_pattern; + p->path_id = path_id; snprintf(p->periph_name, sizeof(p->periph_name), "da"); p->target_id = VolumeID; - p->flags = PERIPH_MATCH_NAME | PERIPH_MATCH_TARGET; + p->flags = PERIPH_MATCH_PATH | PERIPH_MATCH_NAME | PERIPH_MATCH_TARGET; if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { i = errno; @@ -122,25 +180,22 @@ mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd) } /* - * We should have exactly 2 matches, 1 for the bus and 1 for - * the peripheral. However, if we only have 1 match and it is - * for the bus, don't print an error message and return - * ENOENT. + * We should have exactly 1 match for the peripheral. + * However, if we don't get a match, don't print an error + * message and return ENOENT. */ - if (ccb.cdm.num_matches == 1 && - ccb.cdm.matches[0].type == DEV_MATCH_BUS) { + if (ccb.cdm.num_matches == 0) { free(ccb.cdm.matches); return (ENOENT); } - if (ccb.cdm.num_matches != 2) { - warnx("mpt_query_disk got %d matches, expected 2", + if (ccb.cdm.num_matches != 1) { + warnx("mpt_query_disk got %d matches, expected 1", ccb.cdm.num_matches); free(ccb.cdm.matches); return (EIO); } - if (ccb.cdm.matches[0].type != DEV_MATCH_BUS || - ccb.cdm.matches[1].type != DEV_MATCH_PERIPH) { - warnx("mpt_query_disk got wrong CAM matches"); + if (ccb.cdm.matches[0].type != DEV_MATCH_PERIPH) { + warnx("mpt_query_disk got wrong CAM match"); free(ccb.cdm.matches); return (EIO); } @@ -336,47 +391,44 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp) { CONFIG_PAGE_IOC_2 *ioc2; struct mpt_standalone_disk *disks; - struct bus_match_pattern *b; struct periph_match_pattern *p; struct periph_match_result *r; struct cam_device *dev; union ccb ccb; + path_id_t path_id; size_t bufsize; u_int i; - int count; + int count, error; if (xpt_open() < 0) return (ENXIO); + error = fetch_path_id(&path_id); + if (error) + return (error); + for (count = 100;; count+= 100) { /* Try to fetch 'count' disks in one go. */ bzero(&ccb, sizeof(ccb)); ccb.ccb_h.func_code = XPT_DEV_MATCH; - bufsize = sizeof(struct dev_match_result) * (count + 2); + bufsize = sizeof(struct dev_match_result) * (count + 1); ccb.cdm.num_matches = 0; ccb.cdm.match_buf_len = bufsize; ccb.cdm.matches = calloc(1, bufsize); - bufsize = sizeof(struct dev_match_pattern) * 2; - ccb.cdm.num_patterns = 2; + bufsize = sizeof(struct dev_match_pattern) * 1; + ccb.cdm.num_patterns = 1; ccb.cdm.pattern_buf_len = bufsize; ccb.cdm.patterns = calloc(1, bufsize); - /* Match mptX bus 0. */ - ccb.cdm.patterns[0].type = DEV_MATCH_BUS; - b = &ccb.cdm.patterns[0].pattern.bus_pattern; - snprintf(b->dev_name, sizeof(b->dev_name), "mpt"); - b->unit_number = mpt_unit; - b->bus_id = 0; - b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID; - /* Match any "da" peripherals. */ - ccb.cdm.patterns[1].type = DEV_MATCH_PERIPH; - p = &ccb.cdm.patterns[1].pattern.periph_pattern; + ccb.cdm.patterns[0].type = DEV_MATCH_PERIPH; + p = &ccb.cdm.patterns[0].pattern.periph_pattern; + p->path_id = path_id; snprintf(p->periph_name, sizeof(p->periph_name), "da"); - p->flags = PERIPH_MATCH_NAME; + p->flags = PERIPH_MATCH_PATH | PERIPH_MATCH_NAME; if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { i = errno; @@ -406,21 +458,16 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp) break; } - /* - * We should have N + 1 matches, 1 for the bus and 1 for each - * "da" device. - */ - if (ccb.cdm.num_matches < 1) { - warnx("mpt_fetch_disks didn't get any matches"); + /* Shortcut if we don't have any "da" devices. */ + if (ccb.cdm.num_matches == 0) { free(ccb.cdm.matches); - return (EIO); + *ndisks = 0; + *disksp = NULL; + return (0); } - if (ccb.cdm.matches[0].type != DEV_MATCH_BUS) { - warnx("mpt_fetch_disks got wrong CAM matches"); - free(ccb.cdm.matches); - return (EIO); - } - for (i = 1; i < ccb.cdm.num_matches; i++) { + + /* We should have N matches, 1 for each "da" device. */ + for (i = 0; i < ccb.cdm.num_matches; i++) { if (ccb.cdm.matches[i].type != DEV_MATCH_PERIPH) { warnx("mpt_fetch_disks got wrong CAM matches"); free(ccb.cdm.matches); @@ -428,14 +475,6 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp) } } - /* Shortcut if we don't have any "da" devices. */ - if (ccb.cdm.num_matches == 1) { - free(ccb.cdm.matches); - *ndisks = 0; - *disksp = NULL; - return (0); - } - /* * Some of the "da" peripherals may be for RAID volumes, so * fetch the IOC 2 page (list of RAID volumes) so we can @@ -444,7 +483,7 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp) ioc2 = mpt_read_ioc_page(fd, 2, NULL); disks = calloc(ccb.cdm.num_matches, sizeof(*disks)); count = 0; - for (i = 1; i < ccb.cdm.num_matches; i++) { + for (i = 0; i < ccb.cdm.num_matches; i++) { r = &ccb.cdm.matches[i].result.periph_result; if (periph_is_volume(ioc2, r)) continue; @@ -480,10 +519,9 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp) int mpt_rescan_bus(int bus, int id) { - struct bus_match_pattern *b; union ccb ccb; path_id_t path_id; - size_t bufsize; + int error; /* mpt(4) only handles devices on bus 0. */ if (bus != -1 && bus != 0) @@ -492,54 +530,12 @@ mpt_rescan_bus(int bus, int id) if (xpt_open() < 0) return (ENXIO); - /* First, find the path id of bus 0 for this mpt controller. */ + error = fetch_path_id(&path_id); + if (error) + return (error); + + /* Perform the actual rescan. */ bzero(&ccb, sizeof(ccb)); - - ccb.ccb_h.func_code = XPT_DEV_MATCH; - - bufsize = sizeof(struct dev_match_result) * 1; - ccb.cdm.num_matches = 0; - ccb.cdm.match_buf_len = bufsize; - ccb.cdm.matches = calloc(1, bufsize); - - bufsize = sizeof(struct dev_match_pattern) * 1; - ccb.cdm.num_patterns = 1; - ccb.cdm.pattern_buf_len = bufsize; - ccb.cdm.patterns = calloc(1, bufsize); - - /* Match mptX bus 0. */ - ccb.cdm.patterns[0].type = DEV_MATCH_BUS; - b = &ccb.cdm.patterns[0].pattern.bus_pattern; - snprintf(b->dev_name, sizeof(b->dev_name), "mpt"); - b->unit_number = mpt_unit; - b->bus_id = 0; - b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID; - - if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { - free(ccb.cdm.matches); - free(ccb.cdm.patterns); - return (errno); - } - free(ccb.cdm.patterns); - - if (((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) || - (ccb.cdm.status != CAM_DEV_MATCH_LAST)) { - warnx("mpt_rescan_bus got CAM error %#x, CDM error %d\n", - ccb.ccb_h.status, ccb.cdm.status); - free(ccb.cdm.matches); - return (EIO); - } - - /* We should have exactly 1 match for the bus. */ - if (ccb.cdm.num_matches != 1 || - ccb.cdm.matches[0].type != DEV_MATCH_BUS) { - free(ccb.cdm.matches); - return (ENOENT); - } - path_id = ccb.cdm.matches[0].result.bus_result.path_id; - free(ccb.cdm.matches); - - /* Now perform the actual rescan. */ ccb.ccb_h.path_id = path_id; if (id == -1) { ccb.ccb_h.func_code = XPT_SCAN_BUS; From 3c48c0897f5c2e2ecf73afaea87d2b0f7752cde9 Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Wed, 24 Feb 2010 22:16:16 +0000 Subject: [PATCH 1498/2592] MFC r202143,202163,202341,202342,204278 Replace the static NGROUPS=NGROUPS_MAX+1=1024 with a dynamic kern.ngroups+1. kern.ngroups can range from NGROUPS_MAX=1023 to somewhere in the neighborhood of INT_MAX/4 one a system with sufficent RAM and memory bandwidth. Given that the Windows group limit is 1024, this range should be sufficient for most applications r202342: Only allocate the space we need before calling kern_getgroups instead of allocating what ever the user asks for up to "ngroups_max + 1". On systems with large values of kern.ngroups this will be more efficient. The now redundant check that the array is large enough in kern_getgroups() is deliberate to allow this change to be merged to stable/8 without breaking potential third party consumers of the API. --- sys/boot/forth/loader.conf | 1 + sys/compat/linux/linux_misc.c | 2 +- sys/compat/linux/linux_uid16.c | 2 +- sys/compat/svr4/svr4_misc.c | 2 +- sys/i386/ibcs2/ibcs2_misc.c | 12 ++++++++---- sys/kern/kern_mib.c | 4 ++-- sys/kern/kern_prot.c | 18 ++++++++++++------ sys/kern/subr_param.c | 12 ++++++++++++ sys/rpc/authunix_prot.c | 6 +++--- sys/security/audit/audit_arg.c | 4 ++-- sys/sys/systm.h | 1 + 11 files changed, 44 insertions(+), 20 deletions(-) diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index 44eef5fb9b1..523a2f7ce3e 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -101,6 +101,7 @@ module_path="/boot/modules" # Set the module search path #kern.maxusers="32" # Set size of various static tables #kern.nbuf="" # Set the number of buffer headers #kern.ncallout="" # Set the maximum # of timer events +#kern.ngroups="1023" # Set the maximum # of supplemental groups #kern.sgrowsiz="" # Set the amount to grow stack #kern.cam.scsi_delay="2000" # Delay (in ms) before probing SCSI #kern.ipc.maxsockets="" # Set the maximum number of sockets avaliable diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 1d5eaf832ea..d2cf6b6abf1 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1138,7 +1138,7 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args) struct proc *p; ngrp = args->gidsetsize; - if (ngrp < 0 || ngrp >= NGROUPS) + if (ngrp < 0 || ngrp >= ngroups_max + 1) return (EINVAL); linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK); error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t)); diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c index b49bf785fd9..6ad674be77f 100644 --- a/sys/compat/linux/linux_uid16.c +++ b/sys/compat/linux/linux_uid16.c @@ -109,7 +109,7 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args) #endif ngrp = args->gidsetsize; - if (ngrp < 0 || ngrp >= NGROUPS) + if (ngrp < 0 || ngrp >= ngroups_max + 1) return (EINVAL); linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK); error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t)); diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 62bd010bd6d..6f80fe64e66 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -708,7 +708,7 @@ svr4_sys_sysconfig(td, uap) switch (uap->name) { case SVR4_CONFIG_NGROUPS: - *retval = NGROUPS_MAX; + *retval = ngroups_max; break; case SVR4_CONFIG_CHILD_MAX: *retval = maxproc; diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c index 23c617de6e7..c537100ba17 100644 --- a/sys/i386/ibcs2/ibcs2_misc.c +++ b/sys/i386/ibcs2/ibcs2_misc.c @@ -663,9 +663,13 @@ ibcs2_getgroups(td, uap) u_int i, ngrp; int error; - if (uap->gidsetsize < 0) - return (EINVAL); - ngrp = MIN(uap->gidsetsize, NGROUPS); + if (uap->gidsetsize < td->td_ucred->cr_ngroups) { + if (uap->gidsetsize == 0) + ngrp = 0; + else + return (EINVAL); + } else + ngrp = td->td_ucred->cr_ngroups; gp = malloc(ngrp * sizeof(*gp), M_TEMP, M_WAITOK); error = kern_getgroups(td, &ngrp, gp); if (error) @@ -693,7 +697,7 @@ ibcs2_setgroups(td, uap) gid_t *gp; int error, i; - if (uap->gidsetsize < 0 || uap->gidsetsize > NGROUPS) + if (uap->gidsetsize < 0 || uap->gidsetsize > ngroups_max + 1) return (EINVAL); if (uap->gidsetsize && uap->gidset == NULL) return (EINVAL); diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c index 78382c7c5c4..7ef580f5ac2 100644 --- a/sys/kern/kern_mib.c +++ b/sys/kern/kern_mib.c @@ -124,8 +124,8 @@ SYSCTL_INT(_kern, KERN_ARGMAX, argmax, CTLFLAG_RD, SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD, 0, _POSIX_VERSION, "Version of POSIX attempting to comply to"); -SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RD, - 0, NGROUPS_MAX, +SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RDTUN, + &ngroups_max, 0, "Maximum number of supplemental groups a user can belong to"); SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, CTLFLAG_RD, diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 709bcb09723..16b0f37ae91 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -283,7 +283,13 @@ getgroups(struct thread *td, register struct getgroups_args *uap) u_int ngrp; int error; - ngrp = MIN(uap->gidsetsize, NGROUPS); + if (uap->gidsetsize < td->td_ucred->cr_ngroups) { + if (uap->gidsetsize == 0) + ngrp = 0; + else + return (EINVAL); + } else + ngrp = td->td_ucred->cr_ngroups; groups = malloc(ngrp * sizeof(*groups), M_TEMP, M_WAITOK); error = kern_getgroups(td, &ngrp, groups); if (error) @@ -796,7 +802,7 @@ setgroups(struct thread *td, struct setgroups_args *uap) gid_t *groups = NULL; int error; - if (uap->gidsetsize > NGROUPS) + if (uap->gidsetsize > ngroups_max + 1) return (EINVAL); groups = malloc(uap->gidsetsize * sizeof(gid_t), M_TEMP, M_WAITOK); error = copyin(uap->gidset, groups, uap->gidsetsize * sizeof(gid_t)); @@ -815,7 +821,7 @@ kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups) struct ucred *newcred, *oldcred; int error; - if (ngrp > NGROUPS) + if (ngrp > ngroups_max + 1) return (EINVAL); AUDIT_ARG_GROUPSET(groups, ngrp); newcred = crget(); @@ -2022,14 +2028,14 @@ crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups) /* * Copy groups in to a credential after expanding it if required. - * Truncate the list to NGROUPS if it is too large. + * Truncate the list to (ngroups_max + 1) if it is too large. */ void crsetgroups(struct ucred *cr, int ngrp, gid_t *groups) { - if (ngrp > NGROUPS) - ngrp = NGROUPS; + if (ngrp > ngroups_max + 1) + ngrp = ngroups_max + 1; crextend(cr, ngrp); crsetgroups_locked(cr, ngrp, groups); diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c index 6113b639732..1504a784c77 100644 --- a/sys/kern/subr_param.c +++ b/sys/kern/subr_param.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include "opt_param.h" #include "opt_maxusers.h" +#include #include #include #include @@ -88,6 +89,7 @@ int maxfiles; /* sys. wide open files limit */ int maxfilesperproc; /* per-proc open files limit */ int ncallout; /* maximum # of timer events */ int nbuf; +int ngroups_max; /* max # groups per process */ int nswbuf; long maxswzone; /* max swmeta KVA storage */ long maxbcache; /* max buffer cache KVA storage */ @@ -228,6 +230,16 @@ init_param1(void) TUNABLE_ULONG_FETCH("kern.maxssiz", &maxssiz); sgrowsiz = SGROWSIZ; TUNABLE_ULONG_FETCH("kern.sgrowsiz", &sgrowsiz); + + /* + * Let the administrator set {NGROUPS_MAX}, but disallow values + * less than NGROUPS_MAX which would violate POSIX.1-2008 or + * greater than INT_MAX-1 which would result in overflow. + */ + ngroups_max = NGROUPS_MAX; + TUNABLE_INT_FETCH("kern.ngroups", &ngroups_max); + if (ngroups_max < NGROUPS_MAX) + ngroups_max = NGROUPS_MAX; } /* diff --git a/sys/rpc/authunix_prot.c b/sys/rpc/authunix_prot.c index fc03dff3ab9..b1b70a59673 100644 --- a/sys/rpc/authunix_prot.c +++ b/sys/rpc/authunix_prot.c @@ -110,7 +110,7 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred *cred) if (!xdr_uint32_t(xdrs, &ngroups)) return (FALSE); for (i = 0; i < ngroups; i++) { - if (i + 1 < NGROUPS) { + if (i + 1 < ngroups_max + 1) { if (!xdr_uint32_t(xdrs, &cred->cr_groups[i + 1])) return (FALSE); } else { @@ -120,8 +120,8 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred *cred) } if (xdrs->x_op == XDR_DECODE) { - if (ngroups + 1 > NGROUPS) - cred->cr_ngroups = NGROUPS; + if (ngroups + 1 > ngroups_max + 1) + cred->cr_ngroups = ngroups_max + 1; else cred->cr_ngroups = ngroups + 1; } diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c index 6d99666ddf2..562b799cc21 100644 --- a/sys/security/audit/audit_arg.c +++ b/sys/security/audit/audit_arg.c @@ -262,8 +262,8 @@ audit_arg_groupset(gid_t *gidset, u_int gidset_size) u_int i; struct kaudit_record *ar; - KASSERT(gidset_size <= NGROUPS, - ("audit_arg_groupset: gidset_size > NGROUPS")); + KASSERT(gidset_size <= ngroups_max + 1, + ("audit_arg_groupset: gidset_size > (kern.ngroups + 1)")); ar = currecord(); if (ar == NULL) diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 397976fd564..a95ca0e986f 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -64,6 +64,7 @@ extern int boothowto; /* reboot flags, from console subsystem */ extern int bootverbose; /* nonzero to print verbose messages */ extern int maxusers; /* system tune hint */ +extern int ngroups_max; /* max # of supplemental groups */ #ifdef INVARIANTS /* The option is always available */ #define KASSERT(exp,msg) do { \ From a498e71df3169789ebd5827a51ab7c68ae1fc087 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 25 Feb 2010 00:46:51 +0000 Subject: [PATCH 1499/2592] MFC r202964: On FreeBSD, time_t is 64-bit for all platforms except i386 and powerpc, where the type is 32-bit. ZFS can handle 64-bit timestamp internally but zfs_setattr() would check if the time value can fit, we change the checking macros to match 64-bit timestamp if the platform supports it. This change has some downsides like, while you can import zfs on 32-bit platforms, the timestamp would overflow if they are out of the range. This fixes the Y2.038K issue on platforms using 64-bit timestamps. Reviewed by: pjd --- sys/cddl/compat/opensolaris/sys/time.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/cddl/compat/opensolaris/sys/time.h b/sys/cddl/compat/opensolaris/sys/time.h index 0bf1e9bf6b8..4275790bebe 100644 --- a/sys/cddl/compat/opensolaris/sys/time.h +++ b/sys/cddl/compat/opensolaris/sys/time.h @@ -40,8 +40,13 @@ typedef longlong_t hrtime_t; #define LBOLT ((gethrtime() * hz) / NANOSEC) +#if defined(__i386__) || defined(__powerpc__) #define TIMESPEC_OVERFLOW(ts) \ ((ts)->tv_sec < INT32_MIN || (ts)->tv_sec > INT32_MAX) +#else +#define TIMESPEC_OVERFLOW(ts) \ + ((ts)->tv_sec < INT64_MIN || (ts)->tv_sec > INT64_MAX) +#endif #ifdef _KERNEL #define lbolt64 (int64_t)(LBOLT) From f407eeb3b4d290ff5cb296310c3aab8b19e38571 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 25 Feb 2010 10:40:52 +0000 Subject: [PATCH 1500/2592] MFC r204205: Remove write-only variable. --- sys/vm/vnode_pager.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 179afbf9a1e..aedc794c519 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -1016,7 +1016,6 @@ vnode_pager_putpages(object, m, count, sync, rtvals) { int rtval; struct vnode *vp; - struct mount *mp; int bytes = count * PAGE_SIZE; /* @@ -1039,8 +1038,6 @@ vnode_pager_putpages(object, m, count, sync, rtvals) */ vp = object->handle; VM_OBJECT_UNLOCK(object); - if (vp->v_type != VREG) - mp = NULL; rtval = VOP_PUTPAGES(vp, m, bytes, sync, rtvals, 0); KASSERT(rtval != EOPNOTSUPP, ("vnode_pager: stale FS putpages\n")); From bca23f69fd6220e4e566b3aedb8d47e3309c7ba9 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 25 Feb 2010 13:28:05 +0000 Subject: [PATCH 1501/2592] MFC r204009 Assorted fixes for mge(4). - Use proper map for the busdma sync on mge descriptor. - Remove unnecesary busdma sync. - Eliminate redundant locking in mge_reinit_rx() (just assert). - Kill unused variable. Submitted by: Grzegorz Bernacki Obtained from: Semihalf --- sys/dev/mge/if_mge.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/sys/dev/mge/if_mge.c b/sys/dev/mge/if_mge.c index 30366ce8a4b..d36ce099ae6 100644 --- a/sys/dev/mge/if_mge.c +++ b/sys/dev/mge/if_mge.c @@ -457,10 +457,7 @@ mge_allocate_dma(struct mge_softc *sc) { int error; struct mge_desc_wrapper *dw; - int num, i; - - - num = MGE_TX_DESC_NUM + MGE_RX_DESC_NUM; + int i; /* Allocate a busdma tag and DMA safe memory for TX/RX descriptors. */ error = bus_dma_tag_create(NULL, /* parent */ @@ -543,7 +540,7 @@ mge_reinit_rx(struct mge_softc *sc) struct mge_desc_wrapper *dw; int i; - MGE_RECEIVE_LOCK(sc); + MGE_RECEIVE_LOCK_ASSERT(sc); mge_free_desc(sc, sc->mge_rx_desc, MGE_RX_DESC_NUM, sc->mge_rx_dtag, 1); @@ -564,8 +561,6 @@ mge_reinit_rx(struct mge_softc *sc) /* Enable RX queue */ MGE_WRITE(sc, MGE_RX_QUEUE_CMD, MGE_ENABLE_RXQ(MGE_RX_DEFAULT_QUEUE)); - - MGE_RECEIVE_UNLOCK(sc); } #ifdef DEVICE_POLLING @@ -1369,9 +1364,6 @@ mge_encap(struct mge_softc *sc, struct mbuf *m0) dw = &sc->mge_tx_desc[desc_no]; mapp = dw->buffer_dmap; - bus_dmamap_sync(sc->mge_desc_dtag, mapp, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - /* Create mapping in DMA memory */ error = bus_dmamap_load_mbuf_sg(sc->mge_tx_dtag, mapp, m0, segs, &nsegs, BUS_DMA_NOWAIT); @@ -1395,7 +1387,7 @@ mge_encap(struct mge_softc *sc, struct mbuf *m0) mge_offload_setup_descriptor(sc, dw); } - bus_dmamap_sync(sc->mge_desc_dtag, mapp, + bus_dmamap_sync(sc->mge_desc_dtag, dw->desc_dmap, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); sc->tx_desc_curr = (++sc->tx_desc_curr) % MGE_TX_DESC_NUM; From 7cfd788d1acad9814f69fd83cfe3bd497eb16d82 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Fri, 26 Feb 2010 00:11:17 +0000 Subject: [PATCH 1502/2592] MFC: r204105 Return partially filled buffer for non-blocking read(2) in non-immediate mode. PR: kern/143855 Submitted by: Guy Harris (guy at alum dot mit dot edu) --- sys/net/bpf.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index e0265ec1415..60f8924d580 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -661,8 +661,9 @@ static int bpfread(struct cdev *dev, struct uio *uio, int ioflag) { struct bpf_d *d; - int timed_out; int error; + int non_block; + int timed_out; error = devfs_get_cdevpriv((void **)&d); if (error != 0) @@ -675,6 +676,8 @@ bpfread(struct cdev *dev, struct uio *uio, int ioflag) if (uio->uio_resid != d->bd_bufsize) return (EINVAL); + non_block = ((ioflag & O_NONBLOCK) != 0); + BPFD_LOCK(d); d->bd_pid = curthread->td_proc->p_pid; if (d->bd_bufmode != BPF_BUFMODE_BUFFER) { @@ -691,14 +694,20 @@ bpfread(struct cdev *dev, struct uio *uio, int ioflag) * have arrived to fill the store buffer. */ while (d->bd_hbuf == NULL) { - if ((d->bd_immediate || timed_out) && d->bd_slen != 0) { + if (d->bd_slen != 0) { /* * A packet(s) either arrived since the previous * read or arrived while we were asleep. - * Rotate the buffers and return what's here. */ - ROTATE_BUFFERS(d); - break; + if (d->bd_immediate || non_block || timed_out) { + /* + * Rotate the buffers and return what's here + * if we are in immediate mode, non-blocking + * flag is set, or this descriptor timed out. + */ + ROTATE_BUFFERS(d); + break; + } } /* @@ -712,7 +721,7 @@ bpfread(struct cdev *dev, struct uio *uio, int ioflag) return (ENXIO); } - if (ioflag & O_NONBLOCK) { + if (non_block) { BPFD_UNLOCK(d); return (EWOULDBLOCK); } From a5a931b33f15b5da551c8c3b0a79fc001d296219 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 26 Feb 2010 00:54:47 +0000 Subject: [PATCH 1503/2592] MFC 203052: Add interface description capability as inspired by OpenBSD. Thanks for rwatson@, jhb@, brooks@ and others for feedback to the old implementation! Sponsored by: iXsystems, Inc. --- contrib/libpcap/inet.c | 16 +++++++-- sbin/ifconfig/ifconfig.8 | 12 ++++++- sbin/ifconfig/ifconfig.c | 60 ++++++++++++++++++++++++++++++++- share/man/man4/netintro.4 | 38 ++++++++++++++++++++- sys/kern/kern_jail.c | 1 + sys/net/if.c | 70 +++++++++++++++++++++++++++++++++++++++ sys/net/if.h | 10 ++++++ sys/net/if_var.h | 3 +- sys/sys/param.h | 2 +- sys/sys/priv.h | 1 + sys/sys/sockio.h | 2 ++ 11 files changed, 207 insertions(+), 8 deletions(-) diff --git a/contrib/libpcap/inet.c b/contrib/libpcap/inet.c index aad87963e78..5f081a6b8c0 100644 --- a/contrib/libpcap/inet.c +++ b/contrib/libpcap/inet.c @@ -401,10 +401,15 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags, pcap_if_t *curdev; char *description = NULL; pcap_addr_t *curaddr, *prevaddr, *nextaddr; + int s; #ifdef SIOCGIFDESCR struct ifreq ifrdesc; +#ifndef IFDESCRSIZE +#define _IFDESCRSIZE 64 + char ifdescr[_IFDESCRSIZE]; +#else char ifdescr[IFDESCRSIZE]; - int s; +#endif #endif #ifdef SIOCGIFDESCR @@ -413,12 +418,17 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags, */ 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 = sizeof(ifdescr); +#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 c372a08ddd5..32e8fa3993e 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 December 7, 2009 +.Dd January 26, 2010 .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 , Cm descr 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 , Cm -descr +Clear the interface description. .It Cm down Mark an interface .Dq down . @@ -2493,6 +2499,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..ec5e4032f1d 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -44,7 +44,6 @@ static const char rcsid[] = #include #include #include -#include #include #include #include @@ -83,6 +82,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 +823,40 @@ 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; + + ifr.ifr_buffer.length = strlen(val) + 1; + if (ifr.ifr_buffer.length == 1) { + ifr.ifr_buffer.buffer = newdescr = NULL; + ifr.ifr_buffer.length = 0; + } else { + newdescr = strdup(val); + ifr.ifr_buffer.buffer = newdescr; + if (newdescr == NULL) { + warn("no memory to set ifdescr"); + return; + } + } + + if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) + warn("ioctl (set descr)"); + + 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 +901,25 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, printf(" mtu %d", ifr.ifr_mtu); putchar('\n'); + for (;;) { + if ((descr = reallocf(descr, descrlen)) != NULL) { + 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; + } else if (errno == ENAMETOOLONG) + descrlen = ifr.ifr_buffer.length; + else + break; + } else { + warn("unable to allocate memory for interface" + "description"); + break; + } + }; + if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) { if (ifr.ifr_curcap != 0) { printb("\toptions", ifr.ifr_curcap, IFCAPBITS); @@ -1035,6 +1089,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..348a13e68fd 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 January 26, 2010 .Dt NETINTRO 4 .Os .Sh NAME @@ -204,6 +204,7 @@ struct ifreq { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; + struct ifreq_buffer ifru_buffer; short ifru_flags[2]; short ifru_index; int ifru_metric; @@ -216,6 +217,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_metric ifr_ifru.ifru_metric /* metric */ @@ -277,6 +279,33 @@ 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 be defined in the +.Va length +field of +.Va ifru_buffer +struct passed in as parameter, and the length would include +the terminating nul character. +If there is not enough space to hold the interface length, +no copy would be done and an +error would be returned. +The kernel will store the buffer length in the +.Va length +field upon return, regardless whether the buffer itself is +sufficient to hold the data. +.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 (counting the terminating nul). .It Dv SIOCSIFFLAGS Set interface flags field. If the interface is marked down, @@ -404,6 +433,13 @@ struct if_clonereq { char *ifcr_buffer; /* buffer for cloner names */ }; .Ed +.Bd -literal +/* Structure used in SIOCGIFDESCR and SIOCSIFDESCR requests */ +struct ifreq_buffer { + size_t length; /* length of the buffer */ + void *buffer; /* pointer to userland space buffer */ +}; +.Ed .Sh SEE ALSO .Xr ioctl 2 , .Xr socket 2 , diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 7dcf479c5d0..f10522e2e28 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3592,6 +3592,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 17240611f36..64135ac81e1 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -108,6 +108,18 @@ SYSCTL_INT(_net_link, OID_AUTO, log_link_state_change, CTLFLAG_RW, &log_link_state_change, 0, "log interface link state change events"); +/* Interface description */ +static unsigned int ifdescr_maxlen = 1024; +SYSCTL_UINT(_net, OID_AUTO, ifdescr_maxlen, CTLFLAG_RW, + &ifdescr_maxlen, 0, + "administrative maximum length for interface description"); + +MALLOC_DEFINE(M_IFDESCR, "ifdescr", "ifnet descriptions"); + +/* global sx for non-critical path ifdescr */ +static struct sx ifdescr_sx; +SX_SYSINIT(ifdescr_sx, &ifdescr_sx, "ifnet descr"); + void (*bstp_linkstate_p)(struct ifnet *ifp, int state); void (*ng_ether_link_state_p)(struct ifnet *ifp, int state); void (*lagg_linkstate_p)(struct ifnet *ifp, int state); @@ -463,6 +475,8 @@ if_free_internal(struct ifnet *ifp) #ifdef MAC mac_ifnet_destroy(ifp); #endif /* MAC */ + if (ifp->if_description != NULL) + free(ifp->if_description, M_IFDESCR); IF_AFDATA_DESTROY(ifp); IF_ADDR_LOCK_DESTROY(ifp); ifq_delete(&ifp->if_snd); @@ -2045,6 +2059,8 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) int error = 0; int new_flags, temp_flags; size_t namelen, onamelen; + size_t descrlen; + char *descrbuf, *odescrbuf; char new_name[IFNAMSIZ]; struct ifaddr *ifa; struct sockaddr_dl *sdl; @@ -2084,6 +2100,60 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) ifr->ifr_phys = ifp->if_physical; break; + case SIOCGIFDESCR: + error = 0; + sx_slock(&ifdescr_sx); + if (ifp->if_description == NULL) { + ifr->ifr_buffer.length = 0; + error = ENOMSG; + } else { + /* space for terminating nul */ + descrlen = strlen(ifp->if_description) + 1; + if (ifr->ifr_buffer.length < descrlen) + error = ENAMETOOLONG; + else + error = copyout(ifp->if_description, + ifr->ifr_buffer.buffer, descrlen); + ifr->ifr_buffer.length = descrlen; + } + sx_sunlock(&ifdescr_sx); + break; + + case SIOCSIFDESCR: + error = priv_check(td, PRIV_NET_SETIFDESCR); + if (error) + return (error); + + /* + * Copy only (length-1) bytes to make sure that + * if_description is always nul terminated. The + * length parameter is supposed to count the + * terminating nul in. + */ + if (ifr->ifr_buffer.length > ifdescr_maxlen) + return (ENAMETOOLONG); + else if (ifr->ifr_buffer.length == 0) + descrbuf = NULL; + else { + descrbuf = malloc(ifr->ifr_buffer.length, M_IFDESCR, + M_WAITOK | M_ZERO); + error = copyin(ifr->ifr_buffer.buffer, descrbuf, + ifr->ifr_buffer.length - 1); + if (error) { + free(descrbuf, M_IFDESCR); + break; + } + } + + sx_xlock(&ifdescr_sx); + odescrbuf = ifp->if_description; + ifp->if_description = descrbuf; + sx_xunlock(&ifdescr_sx); + + getmicrotime(&ifp->if_lastchange); + free(odescrbuf, M_IFDESCR); + 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 f94b54a1b62..aff0d76da71 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -283,6 +283,14 @@ struct if_announcemsghdr { #define IFAN_ARRIVAL 0 /* interface arrival */ #define IFAN_DEPARTURE 1 /* interface departure */ +/* + * Buffer with length to be used in SIOCGIFDESCR/SIOCSIFDESCR requests + */ +struct ifreq_buffer { + size_t length; + void *buffer; +}; + /* * Interface request structure used for socket * ioctl's. All interface ioctl's must have parameter @@ -295,6 +303,7 @@ struct ifreq { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; + struct ifreq_buffer ifru_buffer; short ifru_flags[2]; short ifru_index; int ifru_jid; @@ -308,6 +317,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 eac7dbf9783..5f9064b5847 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -205,7 +205,8 @@ struct ifnet { * be used with care where binary compatibility is required. */ char if_cspare[3]; - void *if_pspare[8]; + char *if_description; /* interface description */ + void *if_pspare[7]; int if_ispare[4]; }; diff --git a/sys/sys/param.h b/sys/sys/param.h index 2776d063f28..6da5e607b1e 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 800502 /* Master, propagated to newvers */ +#define __FreeBSD_version 800503 /* 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 */ From f5e8283aa902a17e38e902f753c974dae6cc477f Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Fri, 26 Feb 2010 18:46:16 +0000 Subject: [PATCH 1504/2592] MFC r203683: Add multicast key search support. This fixes corrupted mcast packets when we have more than one hostap vap. --- sys/dev/ath/if_ath.c | 37 +++++++++++++++++++++++++++++-------- sys/dev/ath/if_athvar.h | 6 ++---- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index c1e43eb54de..42e50eb604e 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -621,6 +621,13 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) sc->sc_wmetkipmic = 1; } sc->sc_hasclrkey = ath_hal_ciphersupported(ah, HAL_CIPHER_CLR); + /* + * Check for multicast key sarch support. + */ + if (ath_hal_hasmcastkeysearch(sc->sc_ah) && + !ath_hal_getmcastkeysearch(sc->sc_ah)) { + ath_hal_setmcastkeysearch(sc->sc_ah, 1); + } sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah); /* * Mark key cache slots associated with global keys @@ -2039,7 +2046,7 @@ ath_keyset(struct ath_softc *sc, const struct ieee80211_key *k, if ((k->wk_flags & IEEE80211_KEY_GROUP) && sc->sc_mcastkey) { /* * Group keys on hardware that supports multicast frame - * key search use a mac that is the sender's address with + * key search use a MAC that is the sender's address with * the high bit set instead of the app-specified address. */ IEEE80211_ADDR_COPY(gmac, bss->ni_macaddr); @@ -2219,8 +2226,10 @@ ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, * it permits us to support multiple users for adhoc and/or * multi-station operation. */ - if (k->wk_keyix != IEEE80211_KEYIX_NONE || /* global key */ - ((k->wk_flags & IEEE80211_KEY_GROUP) && !sc->sc_mcastkey)) { + if (k->wk_keyix != IEEE80211_KEYIX_NONE) { + /* + * Only global keys should have key index assigned. + */ if (!(&vap->iv_nw_keys[0] <= k && k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) { /* should not happen */ @@ -2228,12 +2237,22 @@ ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, "%s: bogus group key\n", __func__); return 0; } - /* - * XXX we pre-allocate the global keys so - * have no way to check if they've already been allocated. */ - *keyix = *rxkeyix = k - vap->iv_nw_keys; - return 1; + if (vap->iv_opmode != IEEE80211_M_HOSTAP || + !(k->wk_flags & IEEE80211_KEY_GROUP) || + !sc->sc_mcastkey) { + /* + * XXX we pre-allocate the global keys so + * have no way to check if they've already + * been allocated. + */ + *keyix = *rxkeyix = k - vap->iv_nw_keys; + return 1; + } + /* + * Group key and device supports multicast key search. + */ + k->wk_keyix = IEEE80211_KEYIX_NONE; } /* @@ -6945,6 +6964,8 @@ ath_announce(struct ath_softc *sc) if_printf(ifp, "using %u rx buffers\n", ath_rxbuf); if (ath_txbuf != ATH_TXBUF) if_printf(ifp, "using %u tx buffers\n", ath_txbuf); + if (sc->sc_mcastkey && bootverbose) + if_printf(ifp, "using multicast key search\n"); } #ifdef IEEE80211_SUPPORT_TDMA diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 29efc4c88cb..31b1d4c00d5 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -580,14 +580,12 @@ void ath_intr(void *); ath_hal_setcapability(_ah, HAL_CAP_TPC, 1, _v, NULL) #define ath_hal_hasbursting(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_BURST, 0, NULL) == HAL_OK) -#ifdef notyet +#define ath_hal_setmcastkeysearch(_ah, _v) \ + ath_hal_setcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, _v, NULL) #define ath_hal_hasmcastkeysearch(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, NULL) == HAL_OK) #define ath_hal_getmcastkeysearch(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 1, NULL) == HAL_OK) -#else -#define ath_hal_getmcastkeysearch(_ah) 0 -#endif #define ath_hal_hasfastframes(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_FASTFRAME, 0, NULL) == HAL_OK) #define ath_hal_hasbssidmask(_ah) \ From 9d8ea0c702adfcae2df484182afddd4c426be7d3 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Fri, 26 Feb 2010 20:25:30 +0000 Subject: [PATCH 1505/2592] MFC r203695, r203751 Fix spelling mistake and compile error. --- sys/dev/ath/if_ath.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 42e50eb604e..4d330d28a3d 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -622,7 +622,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) } sc->sc_hasclrkey = ath_hal_ciphersupported(ah, HAL_CIPHER_CLR); /* - * Check for multicast key sarch support. + * Check for multicast key search support. */ if (ath_hal_hasmcastkeysearch(sc->sc_ah) && !ath_hal_getmcastkeysearch(sc->sc_ah)) { @@ -2237,7 +2237,6 @@ ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, "%s: bogus group key\n", __func__); return 0; } - */ if (vap->iv_opmode != IEEE80211_M_HOSTAP || !(k->wk_flags & IEEE80211_KEY_GROUP) || !sc->sc_mcastkey) { From 4179ce18a26f5c5417359a11f822b2084cf79fe9 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Fri, 26 Feb 2010 21:49:11 +0000 Subject: [PATCH 1506/2592] MFC of 203763, 203764, 203768, 203769, 203770, 203782, and 203784. These fixes correct a problem in the file system that treats large inode numbers as negative rather than unsigned. For a default (16K block) file system, this bug began to show up at a file system size above about 16Tb. These fixes also update newfs to ensure that it will never create a filesystem with more than 2^32 inodes. They also update libufs, tunefs, and growfs so that they properly handle inode numbers as unsigned. Reported by: Scott Burns, John Kilburg, and Bruce Evans Followup by: Jeff Roberson PR: 133980 --- lib/libufs/cgroup.c | 2 +- lib/libufs/sblock.c | 2 +- sbin/growfs/growfs.c | 16 +++++----- sbin/newfs/mkfs.c | 59 +++++++++++++++++++++++++++------- sbin/newfs/newfs.c | 46 --------------------------- sbin/newfs/newfs.h | 32 +++++++++++++++++++ sbin/tunefs/tunefs.c | 4 +-- sys/ufs/ffs/ffs_alloc.c | 70 ++++++++++++++++++++++------------------- sys/ufs/ffs/fs.h | 52 +++++++++++++++--------------- 9 files changed, 156 insertions(+), 127 deletions(-) diff --git a/lib/libufs/cgroup.c b/lib/libufs/cgroup.c index 2185682e098..28e5ea87a43 100644 --- a/lib/libufs/cgroup.c +++ b/lib/libufs/cgroup.c @@ -59,7 +59,7 @@ cgread1(struct uufsd *disk, int c) fs = &disk->d_fs; - if (c >= fs->fs_ncg) { + if ((unsigned)c >= fs->fs_ncg) { return (0); } ccg = fsbtodb(fs, cgtod(fs, c)) * disk->d_bsize; diff --git a/lib/libufs/sblock.c b/lib/libufs/sblock.c index c9125f28ad3..8986290039f 100644 --- a/lib/libufs/sblock.c +++ b/lib/libufs/sblock.c @@ -93,7 +93,7 @@ int sbwrite(struct uufsd *disk, int all) { struct fs *fs; - int i; + unsigned i; ERROR(disk, NULL); diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c index cc58fc6267d..bf803acd8d9 100644 --- a/sbin/growfs/growfs.c +++ b/sbin/growfs/growfs.c @@ -174,10 +174,9 @@ static void growfs(int fsi, int fso, unsigned int Nflag) { DBG_FUNC("growfs") - int i; - int cylno, j; time_t utime; - int width; + uint cylno; + int i, j, width; char tmpbuf[100]; #ifdef FSIRAND static int randinit=0; @@ -373,10 +372,11 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag) { DBG_FUNC("initcg") static void *iobuf; - long d, dlower, dupper, blkno, start; + long blkno, start; ufs2_daddr_t i, cbase, dmax; struct ufs1_dinode *dp1; struct csum *cs; + uint d, dupper, dlower; if (iobuf == NULL && (iobuf = malloc(sblock.fs_bsize)) == NULL) { errx(37, "panic: cannot allocate I/O buffer"); @@ -431,7 +431,7 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag) acg.cg_nextfreeoff = acg.cg_clusteroff + howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT); } - if (acg.cg_nextfreeoff > sblock.fs_cgsize) { + if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) { /* * This should never happen as we would have had that panic * already on file system creation @@ -746,7 +746,7 @@ updjcg(int cylno, time_t utime, int fsi, int fso, unsigned int Nflag) * needed, update the free space in the superblock. */ acg.cg_time = utime; - if (cylno == sblock.fs_ncg - 1) { + if ((unsigned)cylno == sblock.fs_ncg - 1) { /* * This is still the last cylinder group. */ @@ -940,8 +940,8 @@ updcsloc(time_t utime, int fsi, int fso, unsigned int Nflag) int ocscg, ncscg; int blocks; ufs2_daddr_t cbase, dupper, odupper, d, f, g; - int ind; - int cylno, inc; + int ind, inc; + uint cylno; struct gfs_bpp *bp; int i, l; int lcs=0; diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c index f99cb14c5d3..b7a6b521765 100644 --- a/sbin/newfs/mkfs.c +++ b/sbin/newfs/mkfs.c @@ -114,10 +114,13 @@ void mkfs(struct partition *pp, char *fsys) { int fragsperinode, optimalfpg, origdensity, minfpg, lastminfpg; - long i, j, cylno, csfrags; + long i, j, csfrags; + uint cg; time_t utime; quad_t sizepb; int width; + ino_t maxinum; + int minfragsperinode; /* minimum ratio of frags to inodes */ char tmpbuf[100]; /* XXX this will break in about 2,500 years */ union { struct fs fdummy; @@ -170,6 +173,8 @@ mkfs(struct partition *pp, char *fsys) if (sblock.fs_avgfpdir <= 0) printf("illegal expected number of files per directory %d\n", sblock.fs_avgfpdir), exit(15); + +restart: /* * collect and verify the block and fragment sizes */ @@ -216,6 +221,8 @@ mkfs(struct partition *pp, char *fsys) sblock.fs_fsize, MAXFRAG, sblock.fs_bsize / MAXFRAG); sblock.fs_fsize = sblock.fs_bsize / MAXFRAG; } + if (maxbsize == 0) + maxbsize = bsize; if (maxbsize < bsize || !POWEROF2(maxbsize)) { sblock.fs_maxbsize = sblock.fs_bsize; printf("Extent size set to %d\n", sblock.fs_maxbsize); @@ -225,6 +232,14 @@ mkfs(struct partition *pp, char *fsys) } else { sblock.fs_maxbsize = maxbsize; } + /* + * Maxcontig sets the default for the maximum number of blocks + * that may be allocated sequentially. With file system clustering + * it is possible to allocate contiguous blocks up to the maximum + * transfer size permitted by the controller or buffering. + */ + if (maxcontig == 0) + maxcontig = MAX(1, MAXPHYS / bsize); sblock.fs_maxcontig = maxcontig; if (sblock.fs_maxcontig < sblock.fs_maxbsize / sblock.fs_bsize) { sblock.fs_maxcontig = sblock.fs_maxbsize / sblock.fs_bsize; @@ -315,9 +330,26 @@ mkfs(struct partition *pp, char *fsys) * can put into each cylinder group. If this is too big, we reduce * the density until it fits. */ + maxinum = (((int64_t)(1)) << 32) - INOPB(&sblock); + minfragsperinode = 1 + fssize / maxinum; + if (density == 0) { + density = MAX(NFPI, minfragsperinode) * fsize; + } else if (density < minfragsperinode * fsize) { + origdensity = density; + density = minfragsperinode * fsize; + fprintf(stderr, "density increased from %d to %d\n", + origdensity, density); + } origdensity = density; for (;;) { fragsperinode = MAX(numfrags(&sblock, density), 1); + if (fragsperinode < minfragsperinode) { + bsize <<= 1; + fsize <<= 1; + printf("Block size too small for a file system %s %d\n", + "of this size. Increasing blocksize to", bsize); + goto restart; + } minfpg = fragsperinode * INOPB(&sblock); if (minfpg > sblock.fs_size) minfpg = sblock.fs_size; @@ -406,7 +438,10 @@ mkfs(struct partition *pp, char *fsys) if (sblock.fs_sbsize > SBLOCKSIZE) sblock.fs_sbsize = SBLOCKSIZE; sblock.fs_minfree = minfree; - sblock.fs_maxbpg = maxbpg; + if (maxbpg == 0) + sblock.fs_maxbpg = MAXBLKPG(sblock.fs_bsize); + else + sblock.fs_maxbpg = maxbpg; sblock.fs_optim = opt; sblock.fs_cgrotor = 0; sblock.fs_pendingblocks = 0; @@ -476,9 +511,9 @@ mkfs(struct partition *pp, char *fsys) fsdummy.fs_magic = 0; bwrite(&disk, part_ofs + SBLOCK_UFS1 / disk.d_bsize, chdummy, SBLOCKSIZE); - for (i = 0; i < fsdummy.fs_ncg; i++) + for (cg = 0; cg < fsdummy.fs_ncg; cg++) bwrite(&disk, part_ofs + fsbtodb(&fsdummy, - cgsblock(&fsdummy, i)), chdummy, SBLOCKSIZE); + cgsblock(&fsdummy, cg)), chdummy, SBLOCKSIZE); } } if (!Nflag) @@ -516,11 +551,11 @@ mkfs(struct partition *pp, char *fsys) * writing out in each cylinder group. */ bcopy((char *)&sblock, iobuf, SBLOCKSIZE); - for (cylno = 0; cylno < sblock.fs_ncg; cylno++) { - initcg(cylno, utime); + for (cg = 0; cg < sblock.fs_ncg; cg++) { + initcg(cg, utime); j = snprintf(tmpbuf, sizeof(tmpbuf), " %jd%s", - (intmax_t)fsbtodb(&sblock, cgsblock(&sblock, cylno)), - cylno < (sblock.fs_ncg-1) ? "," : ""); + (intmax_t)fsbtodb(&sblock, cgsblock(&sblock, cg)), + cg < (sblock.fs_ncg-1) ? "," : ""); if (j < 0) tmpbuf[j = 0] = '\0'; if (i + j >= width) { @@ -574,7 +609,8 @@ mkfs(struct partition *pp, char *fsys) void initcg(int cylno, time_t utime) { - long i, j, d, dlower, dupper, blkno, start; + long blkno, start; + uint i, j, d, dlower, dupper; ufs2_daddr_t cbase, dmax; struct ufs1_dinode *dp1; struct ufs2_dinode *dp2; @@ -631,7 +667,7 @@ initcg(int cylno, time_t utime) acg.cg_nextfreeoff = acg.cg_clusteroff + howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT); } - if (acg.cg_nextfreeoff > sblock.fs_cgsize) { + if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) { printf("Panic: cylinder group too big\n"); exit(37); } @@ -880,7 +916,8 @@ makedir(struct direct *protodir, int entries) ufs2_daddr_t alloc(int size, int mode) { - int i, d, blkno, frag; + int i, blkno, frag; + uint d; bread(&disk, part_ofs + fsbtodb(&sblock, cgtod(&sblock, 0)), (char *)&acg, sblock.fs_cgsize); diff --git a/sbin/newfs/newfs.c b/sbin/newfs/newfs.c index b70ce1b3774..886730679d2 100644 --- a/sbin/newfs/newfs.c +++ b/sbin/newfs/newfs.c @@ -79,38 +79,6 @@ __FBSDID("$FreeBSD$"); #include "newfs.h" -/* - * The following two constants set the default block and fragment sizes. - * Both constants must be a power of 2 and meet the following constraints: - * MINBSIZE <= DESBLKSIZE <= MAXBSIZE - * sectorsize <= DESFRAGSIZE <= DESBLKSIZE - * DESBLKSIZE / DESFRAGSIZE <= 8 - */ -#define DFL_FRAGSIZE 2048 -#define DFL_BLKSIZE 16384 - -/* - * Cylinder groups may have up to MAXBLKSPERCG blocks. The actual - * number used depends upon how much information can be stored - * in a cylinder group map which must fit in a single file system - * block. The default is to use as many as possible blocks per group. - */ -#define MAXBLKSPERCG 0x7fffffff /* desired fs_fpg ("infinity") */ - -/* - * MAXBLKPG determines the maximum number of data blocks which are - * placed in a single cylinder group. The default is one indirect - * block worth of data blocks. - */ -#define MAXBLKPG(bsize) ((bsize) / sizeof(ufs2_daddr_t)) - -/* - * Each file system has a number of inodes statically allocated. - * We allocate one inode slot per NFPI fragments, expecting this - * to be far more than we will ever need. - */ -#define NFPI 4 - int Eflag; /* Erase previous disk contents */ int Lflag; /* add a volume label */ int Nflag; /* run without writing file system */ @@ -387,25 +355,11 @@ main(int argc, char *argv[]) fsize = MAX(DFL_FRAGSIZE, sectorsize); if (bsize <= 0) bsize = MIN(DFL_BLKSIZE, 8 * fsize); - if (maxbsize == 0) - maxbsize = bsize; - /* - * Maxcontig sets the default for the maximum number of blocks - * that may be allocated sequentially. With file system clustering - * it is possible to allocate contiguous blocks up to the maximum - * transfer size permitted by the controller or buffering. - */ - if (maxcontig == 0) - maxcontig = MAX(1, MAXPHYS / bsize); - if (density == 0) - density = NFPI * fsize; if (minfree < MINFREE && opt != FS_OPTSPACE) { fprintf(stderr, "Warning: changing optimization to space "); fprintf(stderr, "because minfree is less than %d%%\n", MINFREE); opt = FS_OPTSPACE; } - if (maxbpg == 0) - maxbpg = MAXBLKPG(bsize); realsectorsize = sectorsize; if (sectorsize != DEV_BSIZE) { /* XXX */ int secperblk = sectorsize / DEV_BSIZE; diff --git a/sbin/newfs/newfs.h b/sbin/newfs/newfs.h index 0d7cb62379d..9da3226a775 100644 --- a/sbin/newfs/newfs.h +++ b/sbin/newfs/newfs.h @@ -40,6 +40,38 @@ #include +/* + * The following two constants set the default block and fragment sizes. + * Both constants must be a power of 2 and meet the following constraints: + * MINBSIZE <= DESBLKSIZE <= MAXBSIZE + * sectorsize <= DESFRAGSIZE <= DESBLKSIZE + * DESBLKSIZE / DESFRAGSIZE <= 8 + */ +#define DFL_FRAGSIZE 2048 +#define DFL_BLKSIZE 16384 + +/* + * Cylinder groups may have up to MAXBLKSPERCG blocks. The actual + * number used depends upon how much information can be stored + * in a cylinder group map which must fit in a single file system + * block. The default is to use as many as possible blocks per group. + */ +#define MAXBLKSPERCG 0x7fffffff /* desired fs_fpg ("infinity") */ + +/* + * MAXBLKPG determines the maximum number of data blocks which are + * placed in a single cylinder group. The default is one indirect + * block worth of data blocks. + */ +#define MAXBLKPG(bsize) ((bsize) / sizeof(ufs2_daddr_t)) + +/* + * Each file system has a number of inodes statically allocated. + * We allocate one inode slot per NFPI fragments, expecting this + * to be far more than we will ever need. + */ +#define NFPI 4 + /* * variables set up by front end. */ diff --git a/sbin/tunefs/tunefs.c b/sbin/tunefs/tunefs.c index 2b263bb343c..57dfbcb7ce0 100644 --- a/sbin/tunefs/tunefs.c +++ b/sbin/tunefs/tunefs.c @@ -286,7 +286,7 @@ main(int argc, char *argv[]) } if (fflag) { name = "average file size"; - if (sblock.fs_avgfilesize == fvalue) { + if (sblock.fs_avgfilesize == (unsigned)fvalue) { warnx("%s remains unchanged as %d", name, fvalue); } else { @@ -389,7 +389,7 @@ main(int argc, char *argv[]) } if (sflag) { name = "expected number of files per directory"; - if (sblock.fs_avgfpdir == svalue) { + if (sblock.fs_avgfpdir == (unsigned)svalue) { warnx("%s remains unchanged as %d", name, svalue); } else { diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index b758f2c5adf..2b67dd87fd0 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -88,24 +88,25 @@ __FBSDID("$FreeBSD$"); #include #include -typedef ufs2_daddr_t allocfcn_t(struct inode *ip, int cg, ufs2_daddr_t bpref, +typedef ufs2_daddr_t allocfcn_t(struct inode *ip, u_int cg, ufs2_daddr_t bpref, int size); -static ufs2_daddr_t ffs_alloccg(struct inode *, int, ufs2_daddr_t, int); +static ufs2_daddr_t ffs_alloccg(struct inode *, u_int, ufs2_daddr_t, int); static ufs2_daddr_t ffs_alloccgblk(struct inode *, struct buf *, ufs2_daddr_t); #ifdef INVARIANTS static int ffs_checkblk(struct inode *, ufs2_daddr_t, long); #endif -static ufs2_daddr_t ffs_clusteralloc(struct inode *, int, ufs2_daddr_t, int); +static ufs2_daddr_t ffs_clusteralloc(struct inode *, u_int, ufs2_daddr_t, int); static void ffs_clusteracct(struct ufsmount *, struct fs *, struct cg *, ufs1_daddr_t, int); static ino_t ffs_dirpref(struct inode *); -static ufs2_daddr_t ffs_fragextend(struct inode *, int, ufs2_daddr_t, int, int); +static ufs2_daddr_t ffs_fragextend(struct inode *, u_int, ufs2_daddr_t, + int, int); static void ffs_fserr(struct fs *, ino_t, char *); static ufs2_daddr_t ffs_hashalloc - (struct inode *, int, ufs2_daddr_t, int, allocfcn_t *); -static ufs2_daddr_t ffs_nodealloccg(struct inode *, int, ufs2_daddr_t, int); + (struct inode *, u_int, ufs2_daddr_t, int, allocfcn_t *); +static ufs2_daddr_t ffs_nodealloccg(struct inode *, u_int, ufs2_daddr_t, int); static ufs1_daddr_t ffs_mapsearch(struct fs *, struct cg *, ufs2_daddr_t, int); static int ffs_reallocblks_ufs1(struct vop_reallocblks_args *); static int ffs_reallocblks_ufs2(struct vop_reallocblks_args *); @@ -140,7 +141,7 @@ ffs_alloc(ip, lbn, bpref, size, flags, cred, bnp) struct fs *fs; struct ufsmount *ump; ufs2_daddr_t bno; - int cg, reclaimed; + u_int cg, reclaimed; static struct timeval lastfail; static int curfail; int64_t delta; @@ -243,7 +244,8 @@ ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp) struct fs *fs; struct buf *bp; struct ufsmount *ump; - int cg, request, error, reclaimed; + u_int cg, request, reclaimed; + int error; ufs2_daddr_t bno; static struct timeval lastfail; static int curfail; @@ -930,7 +932,8 @@ ffs_valloc(pvp, mode, cred, vpp) struct timespec ts; struct ufsmount *ump; ino_t ino, ipref; - int cg, error, error1; + u_int cg; + int error, error1; static struct timeval lastfail; static int curfail; @@ -1040,11 +1043,11 @@ ffs_dirpref(pip) struct inode *pip; { struct fs *fs; - int cg, prefcg, dirsize, cgsize; - int avgifree, avgbfree, avgndir, curdirsize; - int minifree, minbfree, maxndir; - int mincg, minndir; - int maxcontigdirs; + u_int cg, prefcg, dirsize, cgsize; + u_int avgifree, avgbfree, avgndir, curdirsize; + u_int minifree, minbfree, maxndir; + u_int mincg, minndir; + u_int maxcontigdirs; mtx_assert(UFS_MTX(pip->i_ump), MA_OWNED); fs = pip->i_fs; @@ -1168,8 +1171,8 @@ ffs_blkpref_ufs1(ip, lbn, indx, bap) ufs1_daddr_t *bap; { struct fs *fs; - int cg; - int avgbfree, startcg; + u_int cg; + u_int avgbfree, startcg; mtx_assert(UFS_MTX(ip->i_ump), MA_OWNED); fs = ip->i_fs; @@ -1218,8 +1221,8 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap) ufs2_daddr_t *bap; { struct fs *fs; - int cg; - int avgbfree, startcg; + u_int cg; + u_int avgbfree, startcg; mtx_assert(UFS_MTX(ip->i_ump), MA_OWNED); fs = ip->i_fs; @@ -1272,14 +1275,14 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap) static ufs2_daddr_t ffs_hashalloc(ip, cg, pref, size, allocator) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t pref; int size; /* size for data blocks, mode for inodes */ allocfcn_t *allocator; { struct fs *fs; ufs2_daddr_t result; - int i, icg = cg; + u_int i, icg = cg; mtx_assert(UFS_MTX(ip->i_ump), MA_OWNED); #ifdef INVARIANTS @@ -1330,7 +1333,7 @@ ffs_hashalloc(ip, cg, pref, size, allocator) static ufs2_daddr_t ffs_fragextend(ip, cg, bprev, osize, nsize) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t bprev; int osize, nsize; { @@ -1413,7 +1416,7 @@ fail: static ufs2_daddr_t ffs_alloccg(ip, cg, bpref, size) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t bpref; int size; { @@ -1583,7 +1586,7 @@ gotit: static ufs2_daddr_t ffs_clusteralloc(ip, cg, bpref, len) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t bpref; int len; { @@ -1707,7 +1710,7 @@ fail: static ufs2_daddr_t ffs_nodealloccg(ip, cg, ipref, mode) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t ipref; int mode; { @@ -1808,7 +1811,7 @@ gotit: bdwrite(bp); if (ibp != NULL) bawrite(ibp); - return (cg * fs->fs_ipg + ipref); + return ((ino_t)(cg * fs->fs_ipg + ipref)); } /* @@ -1853,7 +1856,8 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum) struct buf *bp; ufs1_daddr_t fragno, cgbno; ufs2_daddr_t cgblkno; - int i, cg, blk, frags, bbase; + int i, blk, frags, bbase; + u_int cg; u_int8_t *blksfree; struct cdev *dev; @@ -2051,7 +2055,8 @@ ffs_freefile(ump, fs, devvp, ino, mode) struct cg *cgp; struct buf *bp; ufs2_daddr_t cgbno; - int error, cg; + int error; + u_int cg; u_int8_t *inosused; struct cdev *dev; @@ -2065,7 +2070,7 @@ ffs_freefile(ump, fs, devvp, ino, mode) dev = devvp->v_rdev; cgbno = fsbtodb(fs, cgtod(fs, cg)); } - if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) + if (ino >= fs->fs_ipg * fs->fs_ncg) panic("ffs_freefile: range: dev = %s, ino = %lu, fs = %s", devtoname(dev), (u_long)ino, fs->fs_fsmnt); if ((error = bread(devvp, cgbno, (int)fs->fs_cgsize, NOCRED, &bp))) { @@ -2082,8 +2087,8 @@ ffs_freefile(ump, fs, devvp, ino, mode) inosused = cg_inosused(cgp); ino %= fs->fs_ipg; if (isclr(inosused, ino)) { - printf("dev = %s, ino = %lu, fs = %s\n", devtoname(dev), - (u_long)ino + cg * fs->fs_ipg, fs->fs_fsmnt); + printf("dev = %s, ino = %u, fs = %s\n", devtoname(dev), + ino + cg * fs->fs_ipg, fs->fs_fsmnt); if (fs->fs_ronly == 0) panic("ffs_freefile: freeing free inode"); } @@ -2118,7 +2123,8 @@ ffs_checkfreefile(fs, devvp, ino) struct cg *cgp; struct buf *bp; ufs2_daddr_t cgbno; - int ret, cg; + int ret; + u_int cg; u_int8_t *inosused; cg = ino_to_cg(fs, ino); @@ -2129,7 +2135,7 @@ ffs_checkfreefile(fs, devvp, ino) /* devvp is a normal disk device */ cgbno = fsbtodb(fs, cgtod(fs, cg)); } - if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) + if (ino >= fs->fs_ipg * fs->fs_ncg) return (1); if (bread(devvp, cgbno, (int)fs->fs_cgsize, NOCRED, &bp)) { brelse(bp); diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h index 7da18ea6c09..5be5e4b5bc8 100644 --- a/sys/ufs/ffs/fs.h +++ b/sys/ufs/ffs/fs.h @@ -261,7 +261,7 @@ struct fs { int32_t fs_old_time; /* last time written */ int32_t fs_old_size; /* number of blocks in fs */ int32_t fs_old_dsize; /* number of data blocks in fs */ - int32_t fs_ncg; /* number of cylinder groups */ + u_int32_t fs_ncg; /* number of cylinder groups */ int32_t fs_bsize; /* size of basic blocks in fs */ int32_t fs_fsize; /* size of frag blocks in fs */ int32_t fs_frag; /* number of frags in a block in fs */ @@ -301,7 +301,7 @@ struct fs { int32_t fs_old_spc; /* sectors per cylinder */ int32_t fs_old_ncyl; /* cylinders in filesystem */ int32_t fs_old_cpg; /* cylinders per group */ - int32_t fs_ipg; /* inodes per group */ + u_int32_t fs_ipg; /* inodes per group */ int32_t fs_fpg; /* blocks per group * fs_frag */ /* this data must be re-computed after crashes */ struct csum fs_old_cstotal; /* cylinder summary information */ @@ -332,10 +332,10 @@ struct fs { int64_t fs_dsize; /* number of data blocks in fs */ ufs2_daddr_t fs_csaddr; /* blk addr of cyl grp summary area */ int64_t fs_pendingblocks; /* (u) blocks being freed */ - int32_t fs_pendinginodes; /* (u) inodes being freed */ - int32_t fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */ - int32_t fs_avgfilesize; /* expected average file size */ - int32_t fs_avgfpdir; /* expected # of files per directory */ + u_int32_t fs_pendinginodes; /* (u) inodes being freed */ + ino_t fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */ + u_int32_t fs_avgfilesize; /* expected average file size */ + u_int32_t fs_avgfpdir; /* expected # of files per directory */ int32_t fs_save_cgsize; /* save real cg size to use fs_bsize */ int32_t fs_sparecon32[26]; /* reserved for future constants */ int32_t fs_flags; /* see FS_ flags below */ @@ -458,26 +458,26 @@ struct cg { int32_t cg_firstfield; /* historic cyl groups linked list */ int32_t cg_magic; /* magic number */ int32_t cg_old_time; /* time last written */ - int32_t cg_cgx; /* we are the cgx'th cylinder group */ + u_int32_t cg_cgx; /* we are the cgx'th cylinder group */ int16_t cg_old_ncyl; /* number of cyl's this cg */ int16_t cg_old_niblk; /* number of inode blocks this cg */ - int32_t cg_ndblk; /* number of data blocks this cg */ - struct csum cg_cs; /* cylinder summary information */ - int32_t cg_rotor; /* position of last used block */ - int32_t cg_frotor; /* position of last used frag */ - int32_t cg_irotor; /* position of last used inode */ - int32_t cg_frsum[MAXFRAG]; /* counts of available frags */ + u_int32_t cg_ndblk; /* number of data blocks this cg */ + struct csum cg_cs; /* cylinder summary information */ + u_int32_t cg_rotor; /* position of last used block */ + u_int32_t cg_frotor; /* position of last used frag */ + u_int32_t cg_irotor; /* position of last used inode */ + u_int32_t cg_frsum[MAXFRAG]; /* counts of available frags */ int32_t cg_old_btotoff; /* (int32) block totals per cylinder */ int32_t cg_old_boff; /* (u_int16) free block positions */ - int32_t cg_iusedoff; /* (u_int8) used inode map */ - int32_t cg_freeoff; /* (u_int8) free block map */ - int32_t cg_nextfreeoff; /* (u_int8) next available space */ - int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */ - int32_t cg_clusteroff; /* (u_int8) free cluster map */ - int32_t cg_nclusterblks; /* number of clusters this cg */ - int32_t cg_niblk; /* number of inode blocks this cg */ - int32_t cg_initediblk; /* last initialized inode */ - int32_t cg_unrefs; /* number of unreferenced inodes */ + u_int32_t cg_iusedoff; /* (u_int8) used inode map */ + u_int32_t cg_freeoff; /* (u_int8) free block map */ + u_int32_t cg_nextfreeoff; /* (u_int8) next available space */ + u_int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */ + u_int32_t cg_clusteroff; /* (u_int8) free cluster map */ + u_int32_t cg_nclusterblks; /* number of clusters this cg */ + u_int32_t cg_niblk; /* number of inode blocks this cg */ + u_int32_t cg_initediblk; /* last initialized inode */ + u_int32_t cg_unrefs; /* number of unreferenced inodes */ int32_t cg_sparecon32[2]; /* reserved for future use */ ufs_time_t cg_time; /* time last written */ int64_t cg_sparecon64[3]; /* reserved for future use */ @@ -524,11 +524,11 @@ struct cg { * inode number to cylinder group number. * inode number to filesystem block address. */ -#define ino_to_cg(fs, x) ((x) / (fs)->fs_ipg) +#define ino_to_cg(fs, x) (((ino_t)(x)) / (fs)->fs_ipg) #define ino_to_fsba(fs, x) \ - ((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, x)) + \ - (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs)))))) -#define ino_to_fsbo(fs, x) ((x) % INOPB(fs)) + ((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, (ino_t)(x))) + \ + (blkstofrags((fs), ((((ino_t)(x)) % (fs)->fs_ipg) / INOPB(fs)))))) +#define ino_to_fsbo(fs, x) (((ino_t)(x)) % INOPB(fs)) /* * Give cylinder group number for a filesystem block. From 6101f245fc54c64479a2ce31d9a0ccaa4decf76c Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Sat, 27 Feb 2010 03:47:22 +0000 Subject: [PATCH 1507/2592] MFC r204106: Avoid corrupting the list or queue if _REMOVE is invoked with a reference to the head. PR: kern/119307 --- sys/sys/queue.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sys/sys/queue.h b/sys/sys/queue.h index f1f35c8ce35..257679bc058 100644 --- a/sys/sys/queue.h +++ b/sys/sys/queue.h @@ -112,6 +112,7 @@ struct qm_trace { #define TRACEBUF struct qm_trace trace; #define TRASHIT(x) do {(x) = (void *)-1;} while (0) +#define QMD_SAVELINK(name, link) void **name = (void *)&(link) #define QMD_TRACE_HEAD(head) do { \ (head)->trace.prevline = (head)->trace.lastline; \ @@ -130,6 +131,7 @@ struct qm_trace { #else #define QMD_TRACE_ELEM(elem) #define QMD_TRACE_HEAD(head) +#define QMD_SAVELINK(name, link) #define TRACEBUF #define TRASHIT(x) #endif /* QUEUE_MACRO_DEBUG */ @@ -189,6 +191,7 @@ struct { \ #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) #define SLIST_REMOVE(head, elm, type, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ if (SLIST_FIRST((head)) == (elm)) { \ SLIST_REMOVE_HEAD((head), field); \ } \ @@ -198,7 +201,7 @@ struct { \ curelm = SLIST_NEXT(curelm, field); \ SLIST_REMOVE_AFTER(curelm, field); \ } \ - TRASHIT((elm)->field.sle_next); \ + TRASHIT(*oldnext); \ } while (0) #define SLIST_REMOVE_AFTER(elm, field) do { \ @@ -285,6 +288,7 @@ struct { \ #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) #define STAILQ_REMOVE(head, elm, type, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ if (STAILQ_FIRST((head)) == (elm)) { \ STAILQ_REMOVE_HEAD((head), field); \ } \ @@ -294,7 +298,7 @@ struct { \ curelm = STAILQ_NEXT(curelm, field); \ STAILQ_REMOVE_AFTER(head, curelm, field); \ } \ - TRASHIT((elm)->field.stqe_next); \ + TRASHIT(*oldnext); \ } while (0) #define STAILQ_REMOVE_HEAD(head, field) do { \ @@ -415,14 +419,16 @@ struct { \ #define LIST_NEXT(elm, field) ((elm)->field.le_next) #define LIST_REMOVE(elm, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.le_next); \ + QMD_SAVELINK(oldprev, (elm)->field.le_prev); \ QMD_LIST_CHECK_NEXT(elm, field); \ QMD_LIST_CHECK_PREV(elm, field); \ if (LIST_NEXT((elm), field) != NULL) \ LIST_NEXT((elm), field)->field.le_prev = \ (elm)->field.le_prev; \ *(elm)->field.le_prev = LIST_NEXT((elm), field); \ - TRASHIT((elm)->field.le_next); \ - TRASHIT((elm)->field.le_prev); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ } while (0) #define LIST_SWAP(head1, head2, type, field) do { \ @@ -587,6 +593,8 @@ struct { \ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) #define TAILQ_REMOVE(head, elm, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ + QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ QMD_TAILQ_CHECK_NEXT(elm, field); \ QMD_TAILQ_CHECK_PREV(elm, field); \ if ((TAILQ_NEXT((elm), field)) != NULL) \ @@ -597,8 +605,8 @@ struct { \ QMD_TRACE_HEAD(head); \ } \ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ - TRASHIT((elm)->field.tqe_next); \ - TRASHIT((elm)->field.tqe_prev); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ QMD_TRACE_ELEM(&(elm)->field); \ } while (0) From e623216f383d14596f1bd606215fc1389d6ac230 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 27 Feb 2010 16:51:23 +0000 Subject: [PATCH 1508/2592] MFC r203827: - Add idempotency guards so the structures can be used in other utilities. - Update bpb structs with reserved fields. - In direntry struct join deName with deExtension. Although a fix was attempted in the past, these fields were being overflowed, Now this is consistent with the spec, and we can now share the WinChksum code with NetBSD. --- sys/fs/msdosfs/bootsect.h | 4 ++++ sys/fs/msdosfs/bpb.h | 8 ++++++-- sys/fs/msdosfs/direntry.h | 8 +++++--- sys/fs/msdosfs/msdosfs_conv.c | 17 ++++------------- sys/fs/msdosfs/msdosfs_lookup.c | 4 ++-- sys/fs/msdosfs/msdosfs_vnops.c | 6 +++--- 6 files changed, 24 insertions(+), 23 deletions(-) diff --git a/sys/fs/msdosfs/bootsect.h b/sys/fs/msdosfs/bootsect.h index 9e8aa9767b9..ebd60a06416 100644 --- a/sys/fs/msdosfs/bootsect.h +++ b/sys/fs/msdosfs/bootsect.h @@ -16,6 +16,8 @@ * * October 1992 */ +#ifndef _FS_MSDOSFS_BOOTSECT_H_ +#define _FS_MSDOSFS_BOOTSECT_H_ /* * Format of a boot sector. This is the first sector on a DOS floppy disk @@ -91,3 +93,5 @@ union bootsector { #define bsHiddenSecs bsBPB.bpbHiddenSecs #define bsHugeSectors bsBPB.bpbHugeSectors #endif + +#endif /* !_FS_MSDOSFS_BOOTSECT_H_ */ diff --git a/sys/fs/msdosfs/bpb.h b/sys/fs/msdosfs/bpb.h index addacd22fa1..ce20f53d411 100644 --- a/sys/fs/msdosfs/bpb.h +++ b/sys/fs/msdosfs/bpb.h @@ -17,6 +17,9 @@ * October 1992 */ +#ifndef _FS_MSDOSFS_BPB_H_ +#define _FS_MSDOSFS_BPB_H_ + /* * BIOS Parameter Block (BPB) for DOS 3.3 */ @@ -78,7 +81,7 @@ struct bpb710 { u_int32_t bpbRootClust; /* start cluster for root directory */ u_int16_t bpbFSInfo; /* filesystem info structure sector */ u_int16_t bpbBackup; /* backup boot sector */ - /* There is a 12 byte filler here, but we ignore it */ + u_int8_t bpbReserved[12]; /* reserved for future expansion */ }; /* @@ -153,7 +156,7 @@ struct byte_bpb710 { u_int8_t bpbRootClust[4]; /* start cluster for root directory */ u_int8_t bpbFSInfo[2]; /* filesystem info structure sector */ u_int8_t bpbBackup[2]; /* backup boot sector */ - /* There is a 12 byte filler here, but we ignore it */ + u_int8_t bpbReserved[12]; /* reserved for future expansion */ }; /* @@ -168,3 +171,4 @@ struct fsinfo { u_int8_t fsifill2[12]; u_int8_t fsisig3[4]; }; +#endif /* !_FS_MSDOSFS_BPB_H_ */ diff --git a/sys/fs/msdosfs/direntry.h b/sys/fs/msdosfs/direntry.h index a55b0af219a..86b6fbb099f 100644 --- a/sys/fs/msdosfs/direntry.h +++ b/sys/fs/msdosfs/direntry.h @@ -47,16 +47,17 @@ * * October 1992 */ +#ifndef _FS_MSDOSFS_DIRENTRY_H_ +#define _FS_MSDOSFS_DIRENTRY_H_ /* * Structure of a dos directory entry. */ struct direntry { - u_int8_t deName[8]; /* filename, blank filled */ + u_int8_t deName[11]; /* filename, blank filled */ #define SLOT_EMPTY 0x00 /* slot has never been used */ #define SLOT_E5 0x05 /* the real value is 0xe5 */ #define SLOT_DELETED 0xe5 /* file in this slot deleted */ - u_int8_t deExtension[3]; /* extension, blank filled */ u_int8_t deAttributes; /* file attributes */ #define ATTR_NORMAL 0x00 /* normal file */ #define ATTR_READONLY 0x01 /* file is readonly */ @@ -155,7 +156,8 @@ int winChkName(struct mbnambuf *nbp, const u_char *un, size_t unlen, int chksum, struct msdosfsmount *pmp); int win2unixfn(struct mbnambuf *nbp, struct winentry *wep, int chksum, struct msdosfsmount *pmp); -u_int8_t winChksum(struct direntry *dep); +u_int8_t winChksum(u_int8_t *name); int winSlotCnt(const u_char *un, size_t unlen, struct msdosfsmount *pmp); size_t winLenFixup(const u_char *un, size_t unlen); #endif /* _KERNEL */ +#endif /* !_FS_MSDOSFS_DIRENTRY_H_ */ diff --git a/sys/fs/msdosfs/msdosfs_conv.c b/sys/fs/msdosfs/msdosfs_conv.c index 50dc1a06cc9..8dc1d07ea9c 100644 --- a/sys/fs/msdosfs/msdosfs_conv.c +++ b/sys/fs/msdosfs/msdosfs_conv.c @@ -741,22 +741,13 @@ win2unixfn(nbp, wep, chksum, pmp) * Compute the unrolled checksum of a DOS filename for Win95 LFN use. */ u_int8_t -winChksum(struct direntry *dep) +winChksum(u_int8_t *name) { + int i; u_int8_t s; - s = dep->deName[0]; - s = ((s << 7) | (s >> 1)) + dep->deName[1]; - s = ((s << 7) | (s >> 1)) + dep->deName[2]; - s = ((s << 7) | (s >> 1)) + dep->deName[3]; - s = ((s << 7) | (s >> 1)) + dep->deName[4]; - s = ((s << 7) | (s >> 1)) + dep->deName[5]; - s = ((s << 7) | (s >> 1)) + dep->deName[6]; - s = ((s << 7) | (s >> 1)) + dep->deName[7]; - s = ((s << 7) | (s >> 1)) + dep->deExtension[0]; - s = ((s << 7) | (s >> 1)) + dep->deExtension[1]; - s = ((s << 7) | (s >> 1)) + dep->deExtension[2]; - + for (s = 0, i = 11; --i >= 0; s += *name++) + s = (s << 7)|(s >> 1); return (s); } diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c index 1344f628ec2..8e0c3d5950b 100644 --- a/sys/fs/msdosfs/msdosfs_lookup.c +++ b/sys/fs/msdosfs/msdosfs_lookup.c @@ -276,7 +276,7 @@ msdosfs_lookup(ap) /* * Check for a checksum or name match */ - chksum_ok = (chksum == winChksum(dep)); + chksum_ok = (chksum == winChksum(dep->deName)); if (!chksum_ok && (!olddos || bcmp(dosfilename, dep->deName, 11))) { chksum = -1; @@ -617,7 +617,7 @@ createde(dep, ddep, depp, cnp) * Now write the Win95 long name */ if (ddep->de_fndcnt > 0) { - u_int8_t chksum = winChksum(ndep); + u_int8_t chksum = winChksum(ndep->deName); const u_char *un = (const u_char *)cnp->cn_nameptr; int unlen = cnp->cn_namelen; int cnt = 1; diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index e62af02364b..e232f49b4c0 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -1287,7 +1287,7 @@ static struct { struct direntry dot; struct direntry dotdot; } dosdirtemplate = { - { ". ", " ", /* the . entry */ + { ". ", /* the . entry */ ATTR_DIRECTORY, /* file attribute */ 0, /* reserved */ 0, { 0, 0 }, { 0, 0 }, /* create time & date */ @@ -1297,7 +1297,7 @@ static struct { { 0, 0 }, /* startcluster */ { 0, 0, 0, 0 } /* filesize */ }, - { ".. ", " ", /* the .. entry */ + { ".. ", /* the .. entry */ ATTR_DIRECTORY, /* file attribute */ 0, /* reserved */ 0, { 0, 0 }, { 0, 0 }, /* create time & date */ @@ -1729,7 +1729,7 @@ msdosfs_readdir(ap) } else dirbuf.d_fileno = (uint32_t)fileno; - if (chksum != winChksum(dentp)) { + if (chksum != winChksum(dentp->deName)) { dirbuf.d_namlen = dos2unixfn(dentp->deName, (u_char *)dirbuf.d_name, dentp->deLowerCase | From 8ff070d563533c9c8ee42c6a7597c7b792e2fd0e Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sat, 27 Feb 2010 18:19:13 +0000 Subject: [PATCH 1509/2592] MFC r203433: Add rc.d script for the rtsold(8) daemon. The rtsol(8) handles just one RA then exit. So, the OtherConfig flag may not be handled well by rtsol(8) in the environment where there are multiple RA servers on the segment. In such case, rtsold(8) will be your friend. --- etc/defaults/rc.conf | 4 ++++ etc/network.subr | 4 +++- etc/rc.d/Makefile | 2 +- etc/rc.d/rtsold | 26 ++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100755 etc/rc.d/rtsold diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 24a03fd5cc8..1cd4904f1b9 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -450,6 +450,10 @@ ipv6_default_interface="NO" # Default output interface for scoped addrs. # Now this works only for IPv6 link local # multicast addrs. rtsol_flags="" # Flags to IPv6 router solicitation. +rtsold_enable="NO" # Set to YES to enable an IPv6 router + # solicitation daemon. +rtsold_flags="-a" # Flags to an IPv6 router solicitation + # daemon. rtadvd_enable="NO" # Set to YES to enable an IPv6 router # advertisement daemon. If set to YES, # this router becomes a possible candidate diff --git a/etc/network.subr b/etc/network.subr index 497cc5b7520..c36ddbadcb4 100644 --- a/etc/network.subr +++ b/etc/network.subr @@ -985,7 +985,9 @@ network6_interface_setup() sysctl net.inet6.ip6.accept_rtadv=1 set ${rtsol_interfaces} ifconfig $1 up - rtsol ${rtsol_flags} $1 + if ! checkyesno rtsold_enable; then + rtsol ${rtsol_flags} $1 + fi fi for i in $interfaces; do diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 110f3d783a2..49010e5e2c9 100755 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -30,7 +30,7 @@ FILES= DAEMON FILESYSTEMS LOGIN NETWORKING SERVERS \ powerd power_profile ppp pppoed pwcheck \ quota \ random rarpd resolv rfcomm_pppd_server root \ - route6d routed routing rpcbind rtadvd rwho \ + route6d routed routing rpcbind rtadvd rtsold rwho \ savecore sdpd securelevel sendmail \ serial sppp statd static_arp swap1 \ syscons sysctl syslogd \ diff --git a/etc/rc.d/rtsold b/etc/rc.d/rtsold new file mode 100755 index 00000000000..bbecebb4d3a --- /dev/null +++ b/etc/rc.d/rtsold @@ -0,0 +1,26 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: rtsold +# REQUIRE: netif +# BEFORE: NETWORKING +# KEYWORD: nojail + +. /etc/rc.subr + +name="rtsold" +rcvar=`set_rcvar` +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" +start_postcmd="rtsold_poststart" + +rtsold_poststart() +{ + # wait for DAD + sleep $(($(${SYSCTL_N} net.inet6.ip6.dad_count) + 1)) +} + +load_rc_config $name +run_rc_command "$1" From de482c79d6011863d0265da2a8d4e906d9cb8fd8 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sat, 27 Feb 2010 18:27:32 +0000 Subject: [PATCH 1510/2592] MFC r203490: Introduce '[ipaddr]:path' notation. Since the existing implementation searches ':' backward, a path which includes ':' could not be mounted. You can now mount such path by enclosing an IP address by '[]'. Though we should change to search ':' forward, it will break 'ipv6addr:path' which is currently working. So, it still searches ':' backward, at least for now. --- sbin/mount_nfs/mount_nfs.c | 22 ++++++++++++++++------ sbin/umount/umount.c | 13 ++++++++++--- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c index 229da147255..5f6d2887e02 100644 --- a/sbin/mount_nfs/mount_nfs.c +++ b/sbin/mount_nfs/mount_nfs.c @@ -698,12 +698,17 @@ getnfsargs(char *spec, struct iovec **iov, int *iovlen) { struct addrinfo hints, *ai_nfs, *ai; enum tryret ret; - int ecode, speclen, remoteerr; + int ecode, speclen, remoteerr, offset, have_bracket = 0; char *hostp, *delimp, *errstr; size_t len; static char nam[MNAMELEN + 1], pname[MAXHOSTNAMELEN + 5]; - if ((delimp = strrchr(spec, ':')) != NULL) { + if (*spec == '[' && (delimp = strchr(spec + 1, ']')) != NULL && + *(delimp + 1) == ':') { + hostp = spec + 1; + spec = delimp + 2; + have_bracket = 1; + } else if ((delimp = strrchr(spec, ':')) != NULL) { hostp = spec; spec = delimp + 1; } else if ((delimp = strrchr(spec, '@')) != NULL) { @@ -731,10 +736,15 @@ getnfsargs(char *spec, struct iovec **iov, int *iovlen) /* Make both '@' and ':' notations equal */ if (*hostp != '\0') { len = strlen(hostp); - memmove(nam, hostp, len); - nam[len] = ':'; - memmove(nam + len + 1, spec, speclen); - nam[len + speclen + 1] = '\0'; + offset = 0; + if (have_bracket) + nam[offset++] = '['; + memmove(nam + offset, hostp, len); + if (have_bracket) + nam[len + offset++] = ']'; + nam[len + offset++] = ':'; + memmove(nam + len + offset, spec, speclen); + nam[len + speclen + offset] = '\0'; } /* diff --git a/sbin/umount/umount.c b/sbin/umount/umount.c index 32ffbb32701..e5c5ba95e08 100644 --- a/sbin/umount/umount.c +++ b/sbin/umount/umount.c @@ -325,14 +325,21 @@ umountfs(struct statfs *sfs) if ((nfsdirname = strdup(sfs->f_mntfromname)) == NULL) err(1, "strdup"); orignfsdirname = nfsdirname; - if ((delimp = strrchr(nfsdirname, ':')) != NULL) { - *delimp = '\0'; + if (*nfsdirname == '[' && + (delimp = strchr(nfsdirname + 1, ']')) != NULL && + *(delimp + 1) == ':') { + hostp = nfsdirname + 1; + nfsdirname = delimp + 2; + } else if ((delimp = strrchr(nfsdirname, ':')) != NULL) { hostp = nfsdirname; + nfsdirname = delimp + 1; + } + if (hostp != NULL) { + *delimp = '\0'; getaddrinfo(hostp, NULL, &hints, &ai); if (ai == NULL) { warnx("can't get net id for host"); } - nfsdirname = delimp + 1; } /* From 84a85a06622afcaf0a92bf49911d76c4f5c712d7 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 28 Feb 2010 01:25:12 +0000 Subject: [PATCH 1511/2592] MFC rev 204182: Remove pm_active from struct pmap as it serves no purpose. --- sys/ia64/ia64/pmap.c | 5 ----- sys/ia64/include/pmap.h | 1 - 2 files changed, 6 deletions(-) diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index 32bcb14340a..06aad4a1674 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -453,7 +453,6 @@ pmap_bootstrap() PMAP_LOCK_INIT(kernel_pmap); for (i = 0; i < 5; i++) kernel_pmap->pm_rid[i] = 0; - kernel_pmap->pm_active = 1; TAILQ_INIT(&kernel_pmap->pm_pvlist); PCPU_SET(md.current_pmap, kernel_pmap); @@ -662,7 +661,6 @@ pmap_pinit(struct pmap *pmap) PMAP_LOCK_INIT(pmap); for (i = 0; i < 5; i++) pmap->pm_rid[i] = pmap_allocate_rid(); - pmap->pm_active = 0; TAILQ_INIT(&pmap->pm_pvlist); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); return (1); @@ -2246,8 +2244,6 @@ pmap_switch(pmap_t pm) prevpm = PCPU_GET(md.current_pmap); if (prevpm == pm) goto out; - if (prevpm != NULL) - atomic_clear_32(&prevpm->pm_active, PCPU_GET(cpumask)); if (pm == NULL) { for (i = 0; i < 5; i++) { ia64_set_rr(IA64_RR_BASE(i), @@ -2258,7 +2254,6 @@ pmap_switch(pmap_t pm) ia64_set_rr(IA64_RR_BASE(i), (pm->pm_rid[i] << 8)|(PAGE_SHIFT << 2)|1); } - atomic_set_32(&pm->pm_active, PCPU_GET(cpumask)); } PCPU_SET(md.current_pmap, pm); ia64_srlz_d(); diff --git a/sys/ia64/include/pmap.h b/sys/ia64/include/pmap.h index e40d64766d1..44079c88129 100644 --- a/sys/ia64/include/pmap.h +++ b/sys/ia64/include/pmap.h @@ -76,7 +76,6 @@ struct pmap { struct mtx pm_mtx; TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */ u_int32_t pm_rid[5]; /* base RID for pmap */ - int pm_active; /* active flag */ struct pmap_statistics pm_stats; /* pmap statistics */ }; From c5fc7d96445dbe6ac091e3568da4377c447eebd8 Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Sun, 28 Feb 2010 06:07:53 +0000 Subject: [PATCH 1512/2592] MFC of 204384: Fix misallocation error in target mode --- sys/dev/isp/isp_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 4eb2e0c9094..257dd2c0a60 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -1529,7 +1529,7 @@ isp_pci_mbxdma(ispsoftc_t *isp) } isp->isp_xffree = isp->isp_xflist; #ifdef ISP_TARGET_MODE - len = sizeof (isp_hdl_t *) * isp->isp_maxcmds; + len = sizeof (isp_hdl_t) * isp->isp_maxcmds; isp->isp_tgtlist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); if (isp->isp_tgtlist == NULL) { free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); From d180e5eb6cd7a6f59c2e6514b4f6375461f62c91 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Sun, 28 Feb 2010 11:14:29 +0000 Subject: [PATCH 1513/2592] Merge r204166 from head: Document the interaction between /etc/devfs.conf and /etc/defaults/devfs.conf PR: docs/117308 Submitted by: Mel (partially) --- sbin/devfs/devfs.8 | 9 +++++++-- share/man/man5/devfs.rules.5 | 12 ++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/sbin/devfs/devfs.8 b/sbin/devfs/devfs.8 index 62e10d94255..7a744d437e0 100644 --- a/sbin/devfs/devfs.8 +++ b/sbin/devfs/devfs.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 27, 2008 +.Dd February 21, 2010 .Dt DEVFS 8 .Os .Sh NAME @@ -196,6 +196,9 @@ Apply all the rules in ruleset number to the node. This does not necessarily result in any changes to the node (e.g., if none of the rules in the included ruleset match). +Include commands in the referenced +.Ar ruleset +are not resolved. .It Cm mode Ar filemode Set the file mode to .Ar filemode , @@ -243,7 +246,9 @@ configuration file. .It Pa /etc/devfs.rules Local .Nm -configuration file. +configuration file. Rulesets in here override those in +.Pa /etc/defaults/devfs.rules +with the same ruleset number, otherwise the two files are effectively merged. .It Pa /etc/devfs.conf Boot-time .Nm diff --git a/share/man/man5/devfs.rules.5 b/share/man/man5/devfs.rules.5 index cc641ec6e66..24f78244a89 100644 --- a/share/man/man5/devfs.rules.5 +++ b/share/man/man5/devfs.rules.5 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 30, 2006 +.Dd February 21, 2010 .Dt DEVFS.RULES 5 .Os .Sh NAME @@ -83,8 +83,16 @@ devfs_system_ruleset="localrules" .Ed .Sh FILES .Bl -tag -compact -.It Pa /etc/devfs.rules .It Pa /etc/defaults/devfs.rules +Default +.Nm +configuration file. +.It Pa /etc/devfs.rules +Local +.Nm +configuration file. Rulesets in here override those in +.Pa /etc/defaults/devfs.rules +with the same ruleset number, otherwise the two files are effectively merged. .El .Sh EXAMPLES To make all the partitions of From e0d5ebc30f6aad52413fbe604afbeca7e42b0ef2 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Sun, 28 Feb 2010 14:04:20 +0000 Subject: [PATCH 1514/2592] MFC r203665: Make sure that FTS_COMFOLLOW is not set when the -P option is in effect. Otherwise the -i option will show the inode number of the referenced file for symbolic links given on the command line. Similarly, the file color was printed according to the link target in colorized output. PR: bin/102394 --- bin/ls/ls.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bin/ls/ls.c b/bin/ls/ls.c index e884555b077..d625f67cf7c 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -113,6 +113,7 @@ static int f_listdir; /* list actual directory, not contents */ static int f_listdot; /* list files beginning with . */ static int f_noautodot; /* do not automatically enable -A for root */ int f_longform; /* long listing format */ +static int f_nofollow; /* don't follow symbolic link arguments */ int f_nonprint; /* show unprintables as ? */ static int f_nosort; /* don't sort output */ int f_notabs; /* don't use tab-separated multi-col output */ @@ -234,6 +235,7 @@ main(int argc, char *argv[]) break; case 'H': fts_options |= FTS_COMFOLLOW; + f_nofollow = 0; break; case 'G': setenv("CLICOLOR", "", 1); @@ -241,11 +243,13 @@ main(int argc, char *argv[]) case 'L': fts_options &= ~FTS_PHYSICAL; fts_options |= FTS_LOGICAL; + f_nofollow = 0; break; case 'P': fts_options &= ~FTS_COMFOLLOW; fts_options &= ~FTS_LOGICAL; fts_options |= FTS_PHYSICAL; + f_nofollow = 1; break; case 'R': f_recursive = 1; @@ -396,10 +400,10 @@ main(int argc, char *argv[]) fts_options |= FTS_NOSTAT; /* - * If not -F, -d or -l options, follow any symbolic links listed on + * If not -F, -P, -d or -l options, follow any symbolic links listed on * the command line. */ - if (!f_longform && !f_listdir && !f_type) + if (!f_nofollow && !f_longform && !f_listdir && !f_type) fts_options |= FTS_COMFOLLOW; /* From 932a288f19fa790fe2b54a3f306b1b613b229e82 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sun, 28 Feb 2010 21:28:24 +0000 Subject: [PATCH 1515/2592] MFC r203061: KASSERT contract of return value of interrupt filter X-MFCto7 after: 1 week --- sys/kern/kern_intr.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index d22bfeaa311..f59373fbf43 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -1378,6 +1378,12 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame) ret = ih->ih_filter(frame); else ret = ih->ih_filter(ih->ih_argument); + KASSERT(ret == FILTER_STRAY || + ((ret & (FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) != 0 && + (ret & ~(FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) == 0), + ("%s: incorrect return value %#x from %s", __func__, ret, + ih->ih_name)); + /* * Wrapper handler special handling: * @@ -1546,7 +1552,11 @@ intr_filter_loop(struct intr_event *ie, struct trapframe *frame, thread_only = 1; continue; } - + KASSERT(ret == FILTER_STRAY || + ((ret & (FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) != 0 && + (ret & ~(FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) == 0), + ("%s: incorrect return value %#x from %s", __func__, ret, + ih->ih_name)); if (ret & FILTER_STRAY) continue; else { From 9478f3990b0446db869ea8bbb26d688d01d747b8 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sun, 28 Feb 2010 21:30:46 +0000 Subject: [PATCH 1516/2592] MFC r203430: acpi_cpu: correct capabilities arguments for Processor _OSC --- sys/dev/acpica/acpi_cpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index c16dcb17416..cff22a23277 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -378,7 +378,8 @@ acpi_cpu_attach(device_t dev) arg[3].Type = ACPI_TYPE_BUFFER; arg[3].Buffer.Length = sizeof(cap_set); /* Capabilities buffer */ arg[3].Buffer.Pointer = (uint8_t *)cap_set; - cap_set[0] = 0; + cap_set[0] = 0; /* status */ + cap_set[1] = sc->cpu_features; AcpiEvaluateObject(sc->cpu_handle, "_OSC", &arglist, NULL); } From 0445c84e45d746469cb46fb643c93abc94f9f8bb Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sun, 28 Feb 2010 21:43:47 +0000 Subject: [PATCH 1517/2592] MFC r203546: acpi_cpu: prefer _OSC over _PDC --- sys/dev/acpica/acpi_cpu.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index cff22a23277..bbbd23926c2 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -345,28 +345,11 @@ acpi_cpu_attach(device_t dev) } /* - * CPU capabilities are specified as a buffer of 32-bit integers: - * revision, count, and one or more capabilities. The revision of - * "1" is not specified anywhere but seems to match Linux. + * CPU capabilities are specified in + * Intel Processor Vendor-Specific ACPI Interface Specification. */ if (sc->cpu_features) { arglist.Pointer = arg; - arglist.Count = 1; - arg[0].Type = ACPI_TYPE_BUFFER; - arg[0].Buffer.Length = sizeof(cap_set); - arg[0].Buffer.Pointer = (uint8_t *)cap_set; - cap_set[0] = 1; /* revision */ - cap_set[1] = 1; /* number of capabilities integers */ - cap_set[2] = sc->cpu_features; - AcpiEvaluateObject(sc->cpu_handle, "_PDC", &arglist, NULL); - - /* - * On some systems we need to evaluate _OSC so that the ASL - * loads the _PSS and/or _PDC methods at runtime. - * - * TODO: evaluate failure of _OSC. - */ - arglist.Pointer = arg; arglist.Count = 4; arg[0].Type = ACPI_TYPE_BUFFER; arg[0].Buffer.Length = sizeof(cpu_oscuuid); @@ -380,7 +363,22 @@ acpi_cpu_attach(device_t dev) arg[3].Buffer.Pointer = (uint8_t *)cap_set; cap_set[0] = 0; /* status */ cap_set[1] = sc->cpu_features; - AcpiEvaluateObject(sc->cpu_handle, "_OSC", &arglist, NULL); + status = AcpiEvaluateObject(sc->cpu_handle, "_OSC", &arglist, NULL); + if (ACPI_SUCCESS(status)) { + if (cap_set[0] != 0) + device_printf(dev, "_OSC returned status %#x\n", cap_set[0]); + } + else { + arglist.Pointer = arg; + arglist.Count = 1; + arg[0].Type = ACPI_TYPE_BUFFER; + arg[0].Buffer.Length = sizeof(cap_set); + arg[0].Buffer.Pointer = (uint8_t *)cap_set; + cap_set[0] = 1; /* revision */ + cap_set[1] = 1; /* number of capabilities integers */ + cap_set[2] = sc->cpu_features; + AcpiEvaluateObject(sc->cpu_handle, "_PDC", &arglist, NULL); + } } /* Probe for Cx state support. */ From 27a98ec5296120d3bc1748370210b8c8bd38c2bb Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Sun, 28 Feb 2010 22:25:39 +0000 Subject: [PATCH 1518/2592] MFC r203360 GPIB overhaul, part #2: make the tnt4882 driver work with the newer TNT5004 IC. This involved a major rewrite of a number of things, as this chip no longer supports the NAT7210 legacy mode but requires the host to use the (more modern) FIFO mode. In theory, this also ought to work on the older TNT4882C chip. I'll probably add this as optional support (perhaps by a device.hints flag) later on. By now, FIFO mode is *only* activates iff a TNT5004 chip has been detected (where the old code didn't work at all), while everything else is supposed to use the old code. --- sys/dev/ieee488/ibfoo.c | 144 +++++++++++++++++++++++++++++++++++--- sys/dev/ieee488/pcii.c | 5 +- sys/dev/ieee488/tnt4882.c | 71 ++++++------------- sys/dev/ieee488/tnt4882.h | 77 ++++++++++++++++++++ sys/dev/ieee488/upd7210.c | 85 +++++++++++++++++----- sys/dev/ieee488/upd7210.h | 1 + 6 files changed, 303 insertions(+), 80 deletions(-) create mode 100644 sys/dev/ieee488/tnt4882.h diff --git a/sys/dev/ieee488/ibfoo.c b/sys/dev/ieee488/ibfoo.c index f199920f5f3..a002f8ea2f1 100644 --- a/sys/dev/ieee488/ibfoo.c +++ b/sys/dev/ieee488/ibfoo.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 2010 Joerg Wunsch * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -53,6 +55,7 @@ __FBSDID("$FreeBSD$"); #define UPD7210_SW_DRIVER #include +#include static MALLOC_DEFINE(M_IBFOO, "IBFOO", "IBFOO"); @@ -94,7 +97,10 @@ struct ibfoo { PIO_IDATA, PIO_ODATA, PIO_CMD, - DMA_IDATA + DMA_IDATA, + FIFO_IDATA, + FIFO_ODATA, + FIFO_CMD } mode; struct timeval deadline; @@ -170,7 +176,7 @@ ib_set_errno(struct ibarg *ap, int errno) } static int -gpib_ib_irq(struct upd7210 *u, int intr __unused) +gpib_ib_irq(struct upd7210 *u, int isr_3) { struct ibfoo *ib; @@ -211,11 +217,53 @@ gpib_ib_irq(struct upd7210 *u, int intr __unused) if (!(u->rreg[ISR1] & IXR1_ENDRX)) return (0); break; + case FIFO_IDATA: + if (!(isr_3 & 0x15)) + return (0); + while (ib->buflen != 0 && (isr_3 & 0x04 /* NEF */) != 0) { + *ib->buf = bus_read_1(u->reg_res[0], fifob); + ib->buf++; + ib->buflen--; + isr_3 = bus_read_1(u->reg_res[0], isr3); + } + if ((isr_3 & 0x01) != 0 /* xfr done */ || + (u->rreg[ISR1] & IXR1_ENDRX) != 0 || + ib->buflen == 0) + break; + if (isr_3 & 0x10) + /* xfr stopped */ + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + upd7210_wr(u, AUXMR, AUXMR_RFD); + return (1); + case FIFO_CMD: + case FIFO_ODATA: + if (!(isr_3 & 0x19)) + return (0); + if (ib->buflen == 0) + /* xfr DONE */ + break; + while (ib->buflen != 0 && (isr_3 & 0x08 /* NFF */) != 0) { + bus_write_1(u->reg_res[0], fifob, *ib->buf); + ib->buf++; + ib->buflen--; + isr_3 = bus_read_1(u->reg_res[0], isr3); + } + if (isr_3 & 0x10) + /* xfr stopped */ + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + if (ib->buflen == 0) + /* no more NFF interrupts wanted */ + bus_write_1(u->reg_res[0], imr3, 0x11); /* STOP IE, DONE IE */ + return (1); default: return (0); } upd7210_wr(u, IMR1, 0); upd7210_wr(u, IMR2, 0); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x00); + bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */ + } ib->mode = BUSY; wakeup(&ib->buflen); return (1); @@ -227,6 +275,7 @@ gpib_ib_timeout(void *arg) struct upd7210 *u; struct ibfoo *ib; struct timeval tv; + u_int isr_3; u = arg; ib = u->ibfoo; @@ -241,7 +290,11 @@ gpib_ib_timeout(void *arg) if (ib->mode > BUSY) { upd7210_rd(u, ISR1); upd7210_rd(u, ISR2); - gpib_ib_irq(u, 2); + if (u->use_fifo) + isr_3 = bus_read_1(u->reg_res[0], isr3); + else + isr_3 = 0; + gpib_ib_irq(u, isr_3); } if (ib->mode != IDLE && timevalisset(&ib->deadline)) { getmicrouptime(&tv); @@ -249,6 +302,10 @@ gpib_ib_timeout(void *arg) ib_had_timeout(ib->ap); upd7210_wr(u, IMR1, 0); upd7210_wr(u, IMR2, 0); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x00); + bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */ + } ib->mode = BUSY; wakeup(&ib->buflen); } @@ -280,6 +337,8 @@ gpib_ib_wait_xfer(struct upd7210 *u, struct ibfoo *ib) ib->buf = NULL; upd7210_wr(u, IMR1, 0); upd7210_wr(u, IMR2, 0); + if (u->use_fifo) + bus_write_1(u->reg_res[0], imr3, 0x00); } static void @@ -335,15 +394,31 @@ pio_cmd(struct upd7210 *u, u_char *cmd, int len) ib->wrh = NULL; } mtx_lock(&u->mutex); - ib->mode = PIO_CMD; ib->buf = cmd; ib->buflen = len; - upd7210_wr(u, IMR2, IXR2_CO); - - gpib_ib_irq(u, 1); + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + ib->mode = FIFO_CMD; + upd7210_wr(u, AUXMR, 0x51); /* holdoff immediately */ + bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ + bus_write_1(u->reg_res[0], cfg, 0x80); /* CMD, xfer OUT, 8-bit FIFO */ + bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */ + bus_write_1(u->reg_res[0], cnt0, -len); + bus_write_1(u->reg_res[0], cnt1, (-len) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-len) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-len) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + } else { + ib->mode = PIO_CMD; + upd7210_wr(u, IMR2, IXR2_CO); + gpib_ib_irq(u, 0); + } gpib_ib_wait_xfer(u, ib); + if (u->use_fifo) + bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */ + mtx_unlock(&u->mutex); return (len - ib->buflen); } @@ -358,13 +433,32 @@ pio_odata(struct upd7210 *u, u_char *data, int len) if (len == 0) return (0); mtx_lock(&u->mutex); - ib->mode = PIO_ODATA; ib->buf = data; ib->buflen = len; - upd7210_wr(u, IMR1, IXR1_DO); + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + ib->mode = FIFO_ODATA; + bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ + if (ib->doeoi) + bus_write_1(u->reg_res[0], cfg, 0x08); /* CCEN */ + else + bus_write_1(u->reg_res[0], cfg, 0x00); /* xfer OUT, 8-bit FIFO */ + bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */ + bus_write_1(u->reg_res[0], cnt0, -len); + bus_write_1(u->reg_res[0], cnt1, (-len) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-len) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-len) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + } else { + ib->mode = PIO_ODATA; + upd7210_wr(u, IMR1, IXR1_DO); + } gpib_ib_wait_xfer(u, ib); + if (u->use_fifo) + bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */ + mtx_unlock(&u->mutex); return (len - ib->buflen); } @@ -377,13 +471,30 @@ pio_idata(struct upd7210 *u, u_char *data, int len) ib = u->ibfoo; mtx_lock(&u->mutex); - ib->mode = PIO_IDATA; ib->buf = data; ib->buflen = len; - upd7210_wr(u, IMR1, IXR1_DI); + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + ib->mode = FIFO_IDATA; + bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ + bus_write_1(u->reg_res[0], cfg, 0x20); /* xfer IN, 8-bit FIFO */ + bus_write_1(u->reg_res[0], cnt0, -len); + bus_write_1(u->reg_res[0], cnt1, (-len) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-len) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-len) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + upd7210_wr(u, AUXMR, AUXMR_RFD); + bus_write_1(u->reg_res[0], imr3, 0x15); /* STOP IE, NEF IE, DONE IE */ + } else { + ib->mode = PIO_IDATA; + upd7210_wr(u, IMR1, IXR1_DI); + } gpib_ib_wait_xfer(u, ib); + if (u->use_fifo) + bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */ + mtx_unlock(&u->mutex); return (len - ib->buflen); } @@ -832,6 +943,12 @@ gpib_ib_open(struct cdev *dev, int oflags, int devtype, struct thread *td) upd7210_wr(u, AUXMR, C_AUXB + 3); upd7210_wr(u, AUXMR, C_AUXE + 0); upd7210_wr(u, AUXMR, AUXMR_PON); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x00); + bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft reset */ + bus_write_1(u->reg_res[0], cmdr, 0x03); /* set system + * controller bit */ + } upd7210_wr(u, AUXMR, AUXMR_CIFC); DELAY(100); upd7210_wr(u, AUXMR, AUXMR_SIFC); @@ -864,6 +981,11 @@ gpib_ib_close(struct cdev *dev, int oflags, int devtype, struct thread *td) ibdebug = 0; upd7210_wr(u, IMR1, 0x00); upd7210_wr(u, IMR2, 0x00); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x00); + bus_write_1(u->reg_res[0], cmdr, 0x02); /* clear system + * controller bit */ + } upd7210_wr(u, AUXMR, AUXMR_CRST); DELAY(10000); mtx_unlock(&u->mutex); diff --git a/sys/dev/ieee488/pcii.c b/sys/dev/ieee488/pcii.c index 7e924328ba6..3c5699e0cfd 100644 --- a/sys/dev/ieee488/pcii.c +++ b/sys/dev/ieee488/pcii.c @@ -238,6 +238,7 @@ pcii_attach(device_t dev) sc->upd7210.reg_offset[rid] = 0; } sc->upd7210.irq_clear_res = sc->res[10]; + sc->upd7210.use_fifo = 0; if (sc->res[1] == NULL) sc->upd7210.dmachan = -1; @@ -245,7 +246,9 @@ pcii_attach(device_t dev) sc->upd7210.dmachan = rman_get_start(sc->res[1]); upd7210attach(&sc->upd7210); - return (error); + device_printf(dev, "attached gpib%d\n", sc->upd7210.unit); + + return (0); } DRIVER_MODULE(pcii, isa, pcii_driver, pcii_devclass, 0, 0); diff --git a/sys/dev/ieee488/tnt4882.c b/sys/dev/ieee488/tnt4882.c index a4222a671eb..4b69d0dbd00 100644 --- a/sys/dev/ieee488/tnt4882.c +++ b/sys/dev/ieee488/tnt4882.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 2010 Joerg Wunsch * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,6 +47,7 @@ #define UPD7210_HW_DRIVER 1 #include +#include struct tnt_softc { int foo; @@ -62,55 +64,6 @@ static struct resource_spec tnt_res_spec[] = { { -1, 0 } }; -enum tnt4882reg { - dir = 0x00, - cdor = 0x00, - isr1 = 0x02, - imr1 = 0x02, - isr2 = 0x04, - imr2 = 0x04, - accwr = 0x05, - spsr = 0x06, - spmr = 0x06, - intr = 0x07, - adsr = 0x08, - admr = 0x08, - cnt2 = 0x09, - cptr = 0x0a, - auxmr = 0x0a, - tauxcr = 0x0a, /* 9914 mode register */ - cnt3 = 0x0b, - adr0 = 0x0c, - adr = 0x0c, - hssel = 0x0d, - adr1 = 0x0e, - eosr = 0x0e, - sts1 = 0x10, - cfg = 0x10, - dsr = 0x11, - sh_cnt = 0x11, - imr3 = 0x12, - hier = 0x13, - cnt0 = 0x14, - misc = 0x15, - cnt1 = 0x16, - csr = 0x17, - keyreg = 0x17, - fifob = 0x18, - fifoa = 0x19, - isr3 = 0x1a, - ccr = 0x1a, - sasr = 0x1b, - dcr = 0x1b, - sts2 = 0x1c, - cmdr = 0x1c, - isr0 = 0x1d, - imr0 = 0x1d, - timer = 0x1e, - bsr = 0x1f, - bcr = 0x1f -}; - struct tst { enum {RD, WT, xDELAY, END} action; @@ -276,6 +229,7 @@ tnt_attach(device_t dev) { struct tnt_softc *sc; int error, i; + uint8_t version; sc = device_get_softc(dev); @@ -286,7 +240,7 @@ tnt_attach(device_t dev) error = bus_setup_intr(dev, sc->res[2], INTR_TYPE_MISC | INTR_MPSAFE, NULL, upd7210intr, &sc->upd7210, &sc->intr_handler); - /* Necessary magic for MITE */ + /* IO Device Window Base Size Register (IODWBSR) */ bus_write_4(sc->res[0], 0xc0, rman_get_start(sc->res[1]) | 0x80); tst_exec(sc, tst_reset, "Reset"); @@ -298,6 +252,18 @@ tnt_attach(device_t dev) tst_exec(sc, tst_count0_1, "COUNT0:1"); tst_exec(sc, tst_reset, "Reset"); + version = bus_read_1(sc->res[1], csr); + version = (version >> 4) & 0x0f; + device_printf(dev, "Chip version 0x%02x (TNT%s)\n", + version, + version >= 4? "5004 or above": "4882"); + if (version >= 4) { + device_printf(dev, "Forcing FIFO mode\n"); + sc->upd7210.use_fifo = 1; + } else { + sc->upd7210.use_fifo = 0; + } + /* pass 7210 interrupts through */ bus_write_1(sc->res[1], imr3, 0x02); @@ -313,6 +279,11 @@ tnt_attach(device_t dev) sc->upd7210.irq_clear_res = NULL; upd7210attach(&sc->upd7210); + device_printf(dev, "attached gpib%d\n", sc->upd7210.unit); + + if (sc->upd7210.use_fifo) + bus_write_1(sc->res[0], hssel, 0x01); /* one-chip mode */ + return (0); } diff --git a/sys/dev/ieee488/tnt4882.h b/sys/dev/ieee488/tnt4882.h new file mode 100644 index 00000000000..221cfd943cc --- /dev/null +++ b/sys/dev/ieee488/tnt4882.h @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 2010 Joerg Wunsch + * 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$ + */ + +enum tnt4882reg { + dir = 0x00, + cdor = 0x00, + isr1 = 0x02, + imr1 = 0x02, + isr2 = 0x04, + imr2 = 0x04, + accwr = 0x05, + spsr = 0x06, + spmr = 0x06, + intr = 0x07, + adsr = 0x08, + admr = 0x08, + cnt2 = 0x09, + cptr = 0x0a, + auxmr = 0x0a, + tauxcr = 0x0a, /* 9914 mode register */ + cnt3 = 0x0b, + adr0 = 0x0c, + adr = 0x0c, + hssel = 0x0d, + adr1 = 0x0e, + eosr = 0x0e, + sts1 = 0x10, + cfg = 0x10, + dsr = 0x11, + sh_cnt = 0x11, + imr3 = 0x12, + hier = 0x13, + cnt0 = 0x14, + misc = 0x15, + cnt1 = 0x16, + csr = 0x17, + keyreg = 0x17, + fifob = 0x18, + fifoa = 0x19, + isr3 = 0x1a, + ccr = 0x1a, + sasr = 0x1b, + dcr = 0x1b, + sts2 = 0x1c, + cmdr = 0x1c, + isr0 = 0x1d, + imr0 = 0x1d, + timer = 0x1e, + bsr = 0x1f, + bcr = 0x1f +}; + diff --git a/sys/dev/ieee488/upd7210.c b/sys/dev/ieee488/upd7210.c index b245a650a91..ed6c64eed20 100644 --- a/sys/dev/ieee488/upd7210.c +++ b/sys/dev/ieee488/upd7210.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #define UPD7210_HW_DRIVER #define UPD7210_SW_DRIVER #include +#include static MALLOC_DEFINE(M_GPIB, "GPIB", "GPIB"); @@ -90,15 +91,20 @@ upd7210_wr(struct upd7210 *u, enum upd7210_wreg reg, u_int val) void upd7210intr(void *arg) { - u_int isr1, isr2; + u_int isr_1, isr_2, isr_3; struct upd7210 *u; u = arg; mtx_lock(&u->mutex); - isr1 = upd7210_rd(u, ISR1); - isr2 = upd7210_rd(u, ISR2); - if (isr1 != 0 || isr2 != 0) { - if (u->busy == 0 || u->irq == NULL || !u->irq(u, 1)) { + isr_1 = upd7210_rd(u, ISR1); + isr_2 = upd7210_rd(u, ISR2); + if (u->use_fifo) { + isr_3 = bus_read_1(u->reg_res[0], isr3); + } else { + isr_3 = 0; + } + if (isr_1 != 0 || isr_2 != 0 || isr_3 != 0) { + if (u->busy == 0 || u->irq == NULL || !u->irq(u, isr_3)) { #if 0 printf("upd7210intr [%02x %02x %02x", upd7210_rd(u, DIR), isr1, isr2); @@ -168,17 +174,38 @@ upd7210_goto_standby(struct upd7210 *u) /* Unaddressed Listen Only mode */ static int -gpib_l_irq(struct upd7210 *u, int intr __unused) +gpib_l_irq(struct upd7210 *u, int isr_3) { int i; + int have_data = 0; - if (u->rreg[ISR1] & 1) { + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + if (isr_3 & 0x04) { + /* FIFO not empty */ + i = bus_read_1(u->reg_res[0], fifob); + have_data = 1; + bus_write_1(u->reg_res[0], cnt0, -1); + bus_write_1(u->reg_res[0], cnt1, (-1) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-1) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-1) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + } + } else if (u->rreg[ISR1] & 1) { i = upd7210_rd(u, DIR); + have_data = 1; + } + + if (have_data) { u->buf[u->buf_wp++] = i; u->buf_wp &= (u->bufsize - 1); i = (u->buf_rp + u->bufsize - u->buf_wp) & (u->bufsize - 1); - if (i < 8) - upd7210_wr(u, IMR1, 0); + if (i < 8) { + if (u->use_fifo) + bus_write_1(u->reg_res[0], imr3, 0x00); + else + upd7210_wr(u, IMR1, 0); + } wakeup(u->buf); return (1); } @@ -206,15 +233,28 @@ gpib_l_open(struct cdev *dev, int oflags, int devtype, struct thread *td) u->buf_wp = 0; u->buf_rp = 0; - upd7210_wr(u, AUXMR, AUXMR_CRST); + upd7210_wr(u, AUXMR, AUXMR_CRST); /* chip reset */ DELAY(10000); - upd7210_wr(u, AUXMR, C_ICR | 8); + upd7210_wr(u, AUXMR, C_ICR | 8); /* 8 MHz clock */ DELAY(1000); - upd7210_wr(u, ADR, 0x60); - upd7210_wr(u, ADR, 0xe0); - upd7210_wr(u, ADMR, 0x70); - upd7210_wr(u, AUXMR, AUXMR_PON); - upd7210_wr(u, IMR1, 0x01); + upd7210_wr(u, ADR, 0x60); /* ADR0: disable listener and talker 0 */ + upd7210_wr(u, ADR, 0xe0); /* ADR1: disable listener and talker 1 */ + upd7210_wr(u, ADMR, 0x70); /* listen-only (lon) */ + upd7210_wr(u, AUXMR, AUXMR_PON); /* immediate execute power-on (pon) */ + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ + bus_write_1(u->reg_res[0], cfg, 0x20); /* xfer IN, 8-bit FIFO */ + bus_write_1(u->reg_res[0], cnt0, -1); + bus_write_1(u->reg_res[0], cnt1, (-1) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-1) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-1) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + bus_write_1(u->reg_res[0], imr3, 0x04); /* NEF IE */ + } else { + /* µPD7210/NAT7210, or TNT4882 in non-FIFO mode */ + upd7210_wr(u, IMR1, 0x01); /* data in interrupt enable */ + } return (0); } @@ -227,6 +267,11 @@ gpib_l_close(struct cdev *dev, int oflags, int devtype, struct thread *td) mtx_lock(&u->mutex); u->busy = 0; + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */ + bus_write_1(u->reg_res[0], imr3, 0x00); + } upd7210_wr(u, AUXMR, AUXMR_CRST); DELAY(10000); upd7210_wr(u, IMR1, 0x00); @@ -271,8 +316,12 @@ gpib_l_read(struct cdev *dev, struct uio *uio, int ioflag) u->buf_rp += z; u->buf_rp &= (u->bufsize - 1); } - if (u->wreg[IMR1] == 0) - upd7210_wr(u, IMR1, 0x01); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x04); /* NFF IE */ + } else { + if (u->wreg[IMR1] == 0) + upd7210_wr(u, IMR1, 0x01); + } mtx_unlock(&u->mutex); return (error); } diff --git a/sys/dev/ieee488/upd7210.h b/sys/dev/ieee488/upd7210.h index 9d619b78931..88235ddbebc 100644 --- a/sys/dev/ieee488/upd7210.h +++ b/sys/dev/ieee488/upd7210.h @@ -53,6 +53,7 @@ struct upd7210 { u_int reg_offset[8]; int dmachan; int unit; + int use_fifo; /* private stuff */ struct mtx mutex; From a0b72790e44acba2828a829945bcc8b60997a3d8 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Mon, 1 Mar 2010 00:35:30 +0000 Subject: [PATCH 1519/2592] MFC r204129: Enable NETIF_OPEN_CLOSE_ONCE on PowerPC OFW. This fixes netbooting on PowerPC Book-S hardware, which had been broken for a very long time. Submitted by: Andreas Tobler --- sys/boot/powerpc/ofw/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/boot/powerpc/ofw/Makefile b/sys/boot/powerpc/ofw/Makefile index dfc80db0475..d42fa927ce5 100644 --- a/sys/boot/powerpc/ofw/Makefile +++ b/sys/boot/powerpc/ofw/Makefile @@ -56,6 +56,11 @@ CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/powerpc LIBFICL= ${.OBJDIR}/../../ficl/libficl.a .endif +# Avoid the open-close-dance for every file access as some firmwares perform +# an auto-negotiation on every open of the network interface and thus causes +# netbooting to take horribly long. +CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE + # Always add MI sources .PATH: ${.CURDIR}/../../common .include "${.CURDIR}/../../common/Makefile.inc" From 7eb87cc8c790082ae61a28441422ede4f94eee3e Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Mon, 1 Mar 2010 00:38:20 +0000 Subject: [PATCH 1520/2592] MFC r204197: Allow user programs to execute mfpvr instructions. Linux allows this, and some math-related software like GMP expects to be able to use it to pick a target appropriately. Reported by: Jakob van Santen --- sys/powerpc/aim/trap.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c index 532f7476ab5..1ceffa129ad 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -82,6 +82,7 @@ static void printtrap(u_int vector, struct trapframe *frame, int isfatal, int user); static int trap_pfault(struct trapframe *frame, int user); static int fix_unaligned(struct thread *td, struct trapframe *frame); +static int ppc_instr_emulate(struct trapframe *frame); static int handle_onfault(struct trapframe *frame); static void syscall(struct trapframe *frame); @@ -211,7 +212,9 @@ trap(struct trapframe *frame) /* Identify the trap reason */ if (frame->srr1 & EXC_PGM_TRAP) sig = SIGTRAP; - else + else if (ppc_instr_emulate(frame) == 0) + frame->srr0 += 4; + else sig = SIGILL; break; @@ -632,3 +635,21 @@ fix_unaligned(struct thread *td, struct trapframe *frame) return -1; } + +static int +ppc_instr_emulate(struct trapframe *frame) +{ + uint32_t instr; + int reg; + + instr = fuword32((void *)frame->srr0); + + if ((instr & 0xfc1fffff) == 0x7c1f42a6) { /* mfpvr */ + reg = (instr & ~0xfc1fffff) >> 21; + frame->fixreg[reg] = mfpvr(); + return (0); + } + + return (-1); +} + From db9e470d5419ce3ddcca28994d9e5f8673450d12 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 1 Mar 2010 11:33:09 +0000 Subject: [PATCH 1521/2592] MFC r204356: Store path for rescan to the right place. This should fix panic on boot, introduced by r203108. --- sys/dev/mpt/mpt_raid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/dev/mpt/mpt_raid.c b/sys/dev/mpt/mpt_raid.c index 78c4c4927aa..ec4033b5736 100644 --- a/sys/dev/mpt/mpt_raid.c +++ b/sys/dev/mpt/mpt_raid.c @@ -690,7 +690,6 @@ mpt_raid_thread(void *arg) if (mpt->raid_rescan != 0) { union ccb *ccb; - struct cam_path *path; int error; mpt->raid_rescan = 0; @@ -699,7 +698,7 @@ mpt_raid_thread(void *arg) ccb = xpt_alloc_ccb(); MPT_LOCK(mpt); - error = xpt_create_path(&path, xpt_periph, + error = xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(mpt->phydisk_sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); if (error != CAM_REQ_CMP) { From 87aa09332e4796f94b1bd3df0723fb1227f0869a Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Mon, 1 Mar 2010 17:36:45 +0000 Subject: [PATCH 1522/2592] MFC of 204397: fix problems with fast posting handles --- sys/dev/isp/isp.c | 418 +++++++++++++++++--------------------- sys/dev/isp/isp_freebsd.c | 3 +- sys/dev/isp/isp_library.c | 35 +++- sys/dev/isp/isp_library.h | 1 + sys/dev/isp/isp_pci.c | 18 +- sys/dev/isp/isp_target.c | 4 +- sys/dev/isp/ispmbox.h | 18 +- sys/dev/isp/ispreg.h | 4 +- 8 files changed, 245 insertions(+), 256 deletions(-) diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 1945e4fbced..b05496ca797 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -108,10 +108,11 @@ static const uint8_t alpa_map[] = { * Local function prototypes. */ static int isp_parse_async(ispsoftc_t *, uint16_t); +static int isp_parse_async_fc(ispsoftc_t *, uint16_t); static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *); static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *); -static void isp_fastpost_complete(ispsoftc_t *, uint16_t); +static void isp_fastpost_complete(ispsoftc_t *, uint32_t); static int isp_mbox_continue(ispsoftc_t *); static void isp_scsi_init(ispsoftc_t *); static void isp_scsi_channel_init(ispsoftc_t *, int); @@ -1334,23 +1335,24 @@ isp_scsi_init(ispsoftc_t *isp) } /* - * Turn on Fast Posting, LVD transitions + * Turn on LVD transitions for ULTRA2 or better and other features * - * Ultra2 F/W always has had fast posting (and LVD transitions) - * - * Ultra and older (i.e., SBus) cards may not. It's just safer - * to assume not for them. + * Now that we have 32 bit handles, don't do any fast posting + * any more. For Ultra2/Ultra3 cards, we can turn on 32 bit RIO + * operation or use fast posting. To be conservative, we'll only + * do this for Ultra3 cards now because the other cards are so + * rare for this author to find and test with. */ MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0); if (IS_ULTRA2(isp)) mbs.param[1] |= FW_FEATURE_LVD_NOTIFY; -#ifndef ISP_NO_RIO - if (IS_ULTRA2(isp) || IS_1240(isp)) - mbs.param[1] |= FW_FEATURE_RIO_16BIT; -#else - if (IS_ULTRA2(isp) || IS_1240(isp)) +#ifdef ISP_NO_RIO + if (IS_ULTRA3(isp)) mbs.param[1] |= FW_FEATURE_FAST_POST; +#else + if (IS_ULTRA3(isp)) + mbs.param[1] |= FW_FEATURE_RIO_32BIT; #endif if (mbs.param[1] != 0) { uint16_t sfeat = mbs.param[1]; @@ -1604,25 +1606,15 @@ isp_fibre_init(ispsoftc_t *isp) } if (IS_2200(isp)) { /* - * There seems to just be too much breakage here - * with RIO and Fast Posting- it probably actually - * works okay but this driver is messing it up. - * This card is really ancient by now, so let's - * just opt for safety and not use the feature. + * We can't have Fast Posting any more- we now + * have 32 bit handles. + * + * RIO seemed to have to much breakage. + * + * Just opt for safety. */ -#if 0 - if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) { - icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT; - icbp->icb_fwoptions &= ~ICBOPT_FAST_POST; - icbp->icb_racctimer = 4; - icbp->icb_idelaytimer = 8; - } else { - icbp->icb_fwoptions |= ICBOPT_FAST_POST; - } -#else icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT; icbp->icb_fwoptions &= ~ICBOPT_FAST_POST; -#endif } else { /* * QLogic recommends that FAST Posting be turned @@ -4860,7 +4852,7 @@ again: */ if (sema) { fmbox: - if (mbox & 0x4000) { + if (mbox & MBOX_COMMAND_COMPLETE) { isp->isp_intmboxc++; if (isp->isp_mboxbsy) { int obits = isp->isp_obits; @@ -4880,10 +4872,13 @@ again: } else { isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox); } - } else if (isp_parse_async(isp, mbox) < 0) { - return; + } else { + i = IS_FC(isp)? isp_parse_async_fc(isp, mbox) : isp_parse_async(isp, mbox); + if (i < 0) { + return; + } } - if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || isp->isp_state != ISP_RUNSTATE) { + if ((IS_FC(isp) && mbox != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) { goto out; } } @@ -5065,9 +5060,9 @@ again: req_status_flags = sp->req_status_flags; req_state_flags = sp->req_state_flags; resid = sp->req_resid; - } else if (etype == RQSTYPE_RIO2) { - isp_rio2_t *rio = (isp_rio2_t *)qe; - isp_get_rio2(isp, (isp_rio2_t *) hp, rio); + } else if (etype == RQSTYPE_RIO1) { + isp_rio1_t *rio = (isp_rio1_t *) qe; + isp_get_rio1(isp, (isp_rio1_t *) hp, rio); if (isp->isp_dblev & ISP_LOGDEBUG1) { isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio); } @@ -5079,6 +5074,10 @@ again: } ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ continue; + } else if (etype == RQSTYPE_RIO2) { + isp_prt(isp, ISP_LOGERR, "dropping RIO2 response\n"); + ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ + continue; } else { /* * Somebody reachable via isp_handle_other_response @@ -5391,40 +5390,35 @@ out: * Support routines. */ -#define GET_24XX_BUS(isp, chan, msg) \ - if (IS_24XX(isp)) { \ - chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; \ - if (chan >= isp->isp_nchan) { \ - isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d", chan, msg, __LINE__); \ - break; \ - } \ - } - +/* + * Parse an ASYNC mailbox complete + * + * Return non-zero if the event has been acknowledged. + */ static int isp_parse_async(ispsoftc_t *isp, uint16_t mbox) { - int rval = 0; - int pattern = 0; - uint16_t chan; + int acked = 0; + uint32_t h1 = 0, h2 = 0; + uint16_t chan = 0; - if (IS_DUALBUS(isp)) { - chan = ISP_READ(isp, OUTMAILBOX6); - } else { - chan = 0; + /* + * Pick up the channel, but not if this is a ASYNC_RIO32_2, + * where Mailboxes 6/7 have the second handle. + */ + if (mbox != ASYNC_RIO32_2) { + if (IS_DUALBUS(isp)) { + chan = ISP_READ(isp, OUTMAILBOX6); + } } isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox); switch (mbox) { case ASYNC_BUS_RESET: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_BUS_RESET for FC card"); - break; - } ISP_SET_SENDMARKER(isp, chan, 1); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif isp_async(isp, ISPASYNC_BUS_RESET, chan); @@ -5432,10 +5426,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) case ASYNC_SYSTEM_ERROR: isp->isp_dead = 1; isp->isp_state = ISP_CRASHED; - if (IS_FC(isp)) { - FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL; - FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT; - } /* * Were we waiting for a mailbox command to complete? * If so, it's dead, so wake up the waiter. @@ -5450,7 +5440,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) * restart the firmware */ isp_async(isp, ISPASYNC_FW_CRASH); - rval = -1; + acked = 1; break; case ASYNC_RQS_XFER_ERR: @@ -5462,17 +5452,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) break; case ASYNC_QWAKEUP: -#ifdef ISP_TARGET_MODE - if (IS_24XX(isp)) { - isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error"); - break; - } -#endif - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_QWAKEUP for FC card"); - break; - } /* * We've just been notified that the Queue has woken up. * We don't need to be chatty about this- just unlatch things @@ -5482,82 +5461,45 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) break; case ASYNC_TIMEOUT_RESET: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_TIMEOUT_RESET for FC card"); - break; - } - isp_prt(isp, ISP_LOGWARN, - "timeout initiated SCSI bus reset of chan %d", chan); + isp_prt(isp, ISP_LOGWARN, "timeout initiated SCSI bus reset of chan %d", chan); ISP_SET_SENDMARKER(isp, chan, 1); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif break; case ASYNC_DEVICE_RESET: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL DEVICE_RESET for FC card"); - break; - } isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan); ISP_SET_SENDMARKER(isp, chan, 1); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif break; case ASYNC_EXTMSG_UNDERRUN: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_EXTMSG_UNDERRUN for FC card"); - break; - } isp_prt(isp, ISP_LOGWARN, "extended message underrun"); break; case ASYNC_SCAM_INT: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_SCAM_INT for FC card"); - break; - } isp_prt(isp, ISP_LOGINFO, "SCAM interrupt"); break; case ASYNC_HUNG_SCSI: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_HUNG_SCSI for FC card"); - break; - } - isp_prt(isp, ISP_LOGERR, - "stalled SCSI Bus after DATA Overrun"); + isp_prt(isp, ISP_LOGERR, "stalled SCSI Bus after DATA Overrun"); /* XXX: Need to issue SCSI reset at this point */ break; case ASYNC_KILLED_BUS: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_KILLED_BUS for FC card"); - break; - } isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun"); break; case ASYNC_BUS_TRANSIT: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_BUS_TRANSIT for FC card"); - break; - } mbox = ISP_READ(isp, OUTMAILBOX2); - switch (mbox & 0x1c00) { + switch (mbox & SXP_PINS_MODE_MASK) { case SXP_PINS_LVD_MODE: isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode"); SDPARAM(isp, chan)->isp_diffmode = 0; @@ -5590,70 +5532,142 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) ISP_SET_SENDMARKER(isp, chan, 1); break; - case ASYNC_RIO5: - pattern = 0xce; /* outgoing mailbox regs 1-3, 6-7 */ - break; - - case ASYNC_RIO4: - pattern = 0x4e; /* outgoing mailbox regs 1-3, 6 */ - break; - - case ASYNC_RIO3: - pattern = 0x0e; /* outgoing mailbox regs 1-3 */ - break; - - case ASYNC_RIO2: - pattern = 0x06; /* outgoing mailbox regs 1-2 */ - break; - - case ASYNC_RIO1: case ASYNC_CMD_CMPLT: - pattern = 0x02; /* outgoing mailbox regs 1 */ - break; - - case ASYNC_RIO_RESP: - return (rval); - - case ASYNC_CTIO_DONE: - { -#ifdef ISP_TARGET_MODE - int handle; - if (IS_SCSI(isp) || IS_24XX(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad ASYNC_CTIO_DONE for %s cards", - IS_SCSI(isp)? "SCSI" : "24XX"); + case ASYNC_RIO32_1: + if (!IS_ULTRA3(isp)) { + isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion"); break; } - handle = - (ISP_READ(isp, OUTMAILBOX2) << 16) | - (ISP_READ(isp, OUTMAILBOX1)); - if (isp_target_async(isp, handle, mbox)) { - rval = -1; + /* FALLTHROUGH */ + h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1); + break; + + case ASYNC_RIO32_2: + h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1); + h2 = (ISP_READ(isp, OUTMAILBOX7) << 16) | ISP_READ(isp, OUTMAILBOX6); + break; + + case ASYNC_RIO16_5: + case ASYNC_RIO16_4: + case ASYNC_RIO16_3: + case ASYNC_RIO16_2: + case ASYNC_RIO16_1: + isp_prt(isp, ISP_LOGERR, "unexpected 16 bit RIO handle"); + break; + default: + isp_prt(isp, ISP_LOGWARN, "%s: unhandled async code 0x%x", __func__, mbox); + break; + } + + if (h1 || h2) { + isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h1); + isp_fastpost_complete(isp, h1); + if (h2) { + isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2); + isp_fastpost_complete(isp, h2); + if (isp->isp_fpcchiwater < 2) { + isp->isp_fpcchiwater = 2; + } + } else { + if (isp->isp_fpcchiwater < 1) { + isp->isp_fpcchiwater = 1; + } + } + } else { + isp->isp_intoasync++; + } + return (acked); +} + +#define GET_24XX_BUS(isp, chan, msg) \ + if (IS_24XX(isp)) { \ + chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; \ + if (chan >= isp->isp_nchan) { \ + isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d", chan, msg, __LINE__); \ + break; \ + } \ + } + + +static int +isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox) +{ + int acked = 0; + uint16_t chan; + + if (IS_DUALBUS(isp)) { + chan = ISP_READ(isp, OUTMAILBOX6); + } else { + chan = 0; + } + isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox); + + switch (mbox) { + case ASYNC_SYSTEM_ERROR: + isp->isp_dead = 1; + isp->isp_state = ISP_CRASHED; + FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL; + FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT; + /* + * Were we waiting for a mailbox command to complete? + * If so, it's dead, so wake up the waiter. + */ + if (isp->isp_mboxbsy) { + isp->isp_obits = 1; + isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR; + MBOX_NOTIFY_COMPLETE(isp); + } + /* + * It's up to the handler for isp_async to reinit stuff and + * restart the firmware + */ + isp_async(isp, ISPASYNC_FW_CRASH); + acked = 1; + break; + + case ASYNC_RQS_XFER_ERR: + isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error"); + break; + + case ASYNC_RSP_XFER_ERR: + isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error"); + break; + + case ASYNC_QWAKEUP: +#ifdef ISP_TARGET_MODE + if (IS_24XX(isp)) { + isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error"); + break; + } +#endif + isp_prt(isp, ISP_LOGERR, "%s: unexpected ASYNC_QWAKEUP code", __func__); + break; + + case ASYNC_CMD_CMPLT: + isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1)); + if (isp->isp_fpcchiwater < 1) { + isp->isp_fpcchiwater = 1; + } + break; + + case ASYNC_RIOZIO_STALL: + break; + + case ASYNC_CTIO_DONE: +#ifdef ISP_TARGET_MODE + if (isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1), mbox)) { + acked = 1; } else { - /* count it as a fast posting intr */ isp->isp_fphccmplt++; } #else - if (IS_SCSI(isp) || IS_24XX(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad ASYNC_CTIO_DONE for %s cards", - IS_SCSI(isp)? "SCSI" : "24XX"); - break; - } - isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done"); - isp->isp_fphccmplt++; /* count it as a fast posting intr */ + isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done"); #endif break; - } case ASYNC_LIP_ERROR: case ASYNC_LIP_F8: case ASYNC_LIP_OCCURRED: case ASYNC_PTPMODE: - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad LIP event for SCSI cards"); - break; - } /* * These are broadcast events that have to be sent across * all active channels. @@ -5673,7 +5687,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) isp_async(isp, ISPASYNC_LIP, chan); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif /* @@ -5708,11 +5722,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) break; case ASYNC_LOOP_UP: - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad LOOP UP event for SCSI cards"); - break; - } /* * This is a broadcast event that has to be sent across * all active channels. @@ -5732,18 +5741,13 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) isp_async(isp, ISPASYNC_LOOP_UP, chan); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif } break; case ASYNC_LOOP_DOWN: - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad LOOP DOWN event for SCSI cards"); - break; - } /* * This is a broadcast event that has to be sent across * all active channels. @@ -5762,18 +5766,13 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) isp_async(isp, ISPASYNC_LOOP_DOWN, chan); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif } break; case ASYNC_LOOP_RESET: - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad LIP RESET event for SCSI cards"); - break; - } /* * This is a broadcast event that has to be sent across * all active channels. @@ -5792,7 +5791,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) isp_async(isp, ISPASYNC_LOOP_RESET, chan); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif } @@ -5801,11 +5800,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) case ASYNC_PDB_CHANGED: { int nphdl, nlstate, reason; - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad PDB CHANGED event for SCSI cards"); - break; - } /* * We *should* get a channel out of the 24XX, but we don't seem * to get more than a PDB CHANGED on channel 0, so turn it into @@ -5828,8 +5822,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) ISP_SET_SENDMARKER(isp, chan, 1); fcp->isp_loopstate = LOOP_PDB_RCVD; ISP_MARK_PORTDB(isp, chan, 1); - isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, - ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason); + isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason); } break; } @@ -5837,11 +5830,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) { int lochan, hichan; - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad CHANGE NOTIFY event for SCSI cards"); - break; - } if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) { GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY"); lochan = chan; @@ -5863,8 +5851,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) fcp->isp_loopstate = LOOP_PDB_RCVD; } ISP_MARK_PORTDB(isp, chan, 1); - isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, - ISPASYNC_CHANGE_SNS); + isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_SNS); } break; } @@ -5874,8 +5861,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) * This only applies to 2100 amd 2200 cards */ if (!IS_2200(isp) && !IS_2100(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad card for ASYNC_CONNMODE event"); + isp_prt(isp, ISP_LOGWARN, "bad card for ASYNC_CONNMODE event"); break; } chan = 0; @@ -5909,8 +5895,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) "Unknown connection mode (0x%x)", mbox); break; } - isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, - ISPASYNC_CHANGE_OTHER); + isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_OTHER); FCPARAM(isp, chan)->sendmarker = 1; FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT; FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD; @@ -5920,8 +5905,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) if (IS_24XX(isp)) { isp_prt(isp, ISP_LOGWARN, "Receive Error"); } else { - isp_prt(isp, ISP_LOGWARN, - "Unknown Async Code 0x%x", mbox); + isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC_RCV_ERR"); } break; case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */ @@ -5937,29 +5921,10 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox); break; } - - if (pattern) { - int i, nh; - uint16_t handles[16]; - - for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) { - if ((pattern & (1 << i)) == 0) { - continue; - } - handles[nh++] = ISP_READ(isp, MBOX_OFF(i)); - } - for (i = 0; i < nh; i++) { - isp_fastpost_complete(isp, handles[i]); - isp_prt(isp, ISP_LOGDEBUG3, - "fast post completion of %u", handles[i]); - } - if (isp->isp_fpcchiwater < nh) { - isp->isp_fpcchiwater = nh; - } - } else { + if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) { isp->isp_intoasync++; } - return (rval); + return (acked); } /* @@ -6591,7 +6556,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, } static void -isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph) +isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph) { XS_T *xs; @@ -7679,7 +7644,6 @@ isp_setdfltfcparm(ispsoftc_t *isp, int chan) fcp->isp_fwoptions |= ICBOPT_FAIRNESS; fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE; fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS; - fcp->isp_fwoptions |= ICBOPT_FAST_POST; if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) { fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX; } diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index cd6ec099816..da03aea9652 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -2304,7 +2304,8 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) uint32_t tval, handle; /* - * CTIO, CTIO2 and CTIO7 are close enough.... + * CTIO handles are 16 bits. + * CTIO2 and CTIO7 are 32 bits. */ if (IS_SCSI(isp)) { diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c index 57b84002ec9..43c161d2782 100644 --- a/sys/dev/isp/isp_library.c +++ b/sys/dev/isp/isp_library.c @@ -668,7 +668,7 @@ isp_clear_commands(ispsoftc_t *isp) ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO2; } else { ct_entry_t *ctio = (ct_entry_t *) local; - ctio->ct_syshandle = hdp->handle & 0xffff; + ctio->ct_syshandle = hdp->handle; ctio->ct_status = CT_HBA_RESET & 0xff; ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO; } @@ -1131,18 +1131,37 @@ isp_get_24xx_abrt(ispsoftc_t *isp, isp24xx_abrt_t *src, isp24xx_abrt_t *dst) } +void +isp_get_rio1(ispsoftc_t *isp, isp_rio1_t *r1src, isp_rio1_t *r1dst) +{ + const int lim = sizeof (r1dst->req_handles) / sizeof (r1dst->req_handles[0]); + int i; + isp_get_hdr(isp, &r1src->req_header, &r1dst->req_header); + if (r1dst->req_header.rqs_seqno > lim) { + r1dst->req_header.rqs_seqno = lim; + } + for (i = 0; i < r1dst->req_header.rqs_seqno; i++) { + ISP_IOXGET_32(isp, &r1src->req_handles[i], r1dst->req_handles[i]); + } + while (i < lim) { + r1dst->req_handles[i++] = 0; + } +} + void isp_get_rio2(ispsoftc_t *isp, isp_rio2_t *r2src, isp_rio2_t *r2dst) { + const int lim = sizeof (r2dst->req_handles) / sizeof (r2dst->req_handles[0]); int i; + isp_get_hdr(isp, &r2src->req_header, &r2dst->req_header); - if (r2dst->req_header.rqs_seqno > 30) { - r2dst->req_header.rqs_seqno = 30; + if (r2dst->req_header.rqs_seqno > lim) { + r2dst->req_header.rqs_seqno = lim; } for (i = 0; i < r2dst->req_header.rqs_seqno; i++) { ISP_IOXGET_16(isp, &r2src->req_handles[i], r2dst->req_handles[i]); } - while (i < 30) { + while (i < lim) { r2dst->req_handles[i++] = 0; } } @@ -2240,7 +2259,13 @@ isp_allocate_xs_tgt(ispsoftc_t *isp, void *xs, uint32_t *handlep) hdp->cmd = xs; hdp->handle = (hdp - isp->isp_tgtlist); hdp->handle |= (ISP_HANDLE_TARGET << ISP_HANDLE_USAGE_SHIFT); - hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT); + /* + * Target handles for SCSI cards are only 16 bits, so + * sequence number protection will be ommitted. + */ + if (IS_FC(isp)) { + hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT); + } *handlep = hdp->handle; return (0); } diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h index b055dd827c7..4e0c7f8e67b 100644 --- a/sys/dev/isp/isp_library.h +++ b/sys/dev/isp/isp_library.h @@ -108,6 +108,7 @@ void isp_put_cont64_req(ispsoftc_t *, ispcontreq64_t *, ispcontreq64_t *); void isp_get_response(ispsoftc_t *, ispstatusreq_t *, ispstatusreq_t *); void isp_get_24xx_response(ispsoftc_t *, isp24xx_statusreq_t *, isp24xx_statusreq_t *); void isp_get_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *); +void isp_get_rio1(ispsoftc_t *, isp_rio1_t *, isp_rio1_t *); void isp_get_rio2(ispsoftc_t *, isp_rio2_t *, isp_rio2_t *); void isp_put_icb(ispsoftc_t *, isp_icb_t *, isp_icb_t *); void isp_put_icb_2400(ispsoftc_t *, isp_icb_2400_t *, isp_icb_2400_t *); diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 257dd2c0a60..547f48ef2ff 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -1068,8 +1068,7 @@ isp_pci_rd_isr(ispsoftc_t *isp, uint32_t *isrp, uint16_t *semap, uint16_t *mbp) } static int -isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp, - uint16_t *semap, uint16_t *mbox0p) +isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp, uint16_t *semap, uint16_t *mbox0p) { uint32_t hccr; uint32_t r2hisr; @@ -1096,7 +1095,7 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp, return (1); case ISPR2HST_RIO_16: *isrp = r2hisr & 0xffff; - *mbox0p = ASYNC_RIO1; + *mbox0p = ASYNC_RIO16_1; *semap = 1; return (1); case ISPR2HST_FPOST: @@ -1118,21 +1117,17 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp, hccr = ISP_READ(isp, HCCR); if (hccr & HCCR_PAUSE) { ISP_WRITE(isp, HCCR, HCCR_RESET); - isp_prt(isp, ISP_LOGERR, - "RISC paused at interrupt (%x->%x)", hccr, - ISP_READ(isp, HCCR)); + isp_prt(isp, ISP_LOGERR, "RISC paused at interrupt (%x->%x)", hccr, ISP_READ(isp, HCCR)); ISP_WRITE(isp, BIU_ICR, 0); } else { - isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", - r2hisr); + isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr); } return (0); } } static int -isp_pci_rd_isr_2400(ispsoftc_t *isp, uint32_t *isrp, - uint16_t *semap, uint16_t *mbox0p) +isp_pci_rd_isr_2400(ispsoftc_t *isp, uint32_t *isrp, uint16_t *semap, uint16_t *mbox0p) { uint32_t r2hisr; @@ -1177,8 +1172,7 @@ isp_pci_rd_reg(ispsoftc_t *isp, int regoff) * We will assume that someone has paused the RISC processor. */ oldconf = BXR2(isp, IspVirt2Off(isp, BIU_CONF1)); - BXW2(isp, IspVirt2Off(isp, BIU_CONF1), - oldconf | BIU_PCI_CONF1_SXP); + BXW2(isp, IspVirt2Off(isp, BIU_CONF1), oldconf | BIU_PCI_CONF1_SXP); MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2); } rv = BXR2(isp, IspVirt2Off(isp, regoff)); diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c index 68c42b4558a..8707961c24f 100644 --- a/sys/dev/isp/isp_target.c +++ b/sys/dev/isp/isp_target.c @@ -826,7 +826,9 @@ isp_target_async(ispsoftc_t *isp, int bus, int event) ct_entry_t *ct = (ct_entry_t *) storage; ct->ct_header.rqs_entry_type = RQSTYPE_CTIO; ct->ct_status = CT_OK; - ct->ct_fwhandle = bus; + ct->ct_syshandle = bus; + /* we skip fwhandle here */ + ct->ct_fwhandle = 0; ct->ct_flags = CT_SENDSTATUS; } isp_async(isp, ISPASYNC_TARGET_ACTION, storage); diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h index eb3ab6381a1..36a73913ac8 100644 --- a/sys/dev/isp/ispmbox.h +++ b/sys/dev/isp/ispmbox.h @@ -223,6 +223,8 @@ #define ASYNC_SECURITY_UPDATE 0x801B #define ASYNC_CMD_CMPLT 0x8020 #define ASYNC_CTIO_DONE 0x8021 +#define ASYNC_RIO32_1 0x8021 +#define ASYNC_RIO32_2 0x8022 #define ASYNC_IP_XMIT_DONE 0x8022 #define ASYNC_IP_RECV_DONE 0x8023 #define ASYNC_IP_BROADCAST 0x8024 @@ -230,19 +232,19 @@ #define ASYNC_IP_RCVQ_EMPTY 0x8026 #define ASYNC_IP_RECV_DONE_ALIGNED 0x8027 #define ASYNC_PTPMODE 0x8030 -#define ASYNC_RIO1 0x8031 -#define ASYNC_RIO2 0x8032 -#define ASYNC_RIO3 0x8033 -#define ASYNC_RIO4 0x8034 -#define ASYNC_RIO5 0x8035 +#define ASYNC_RIO16_1 0x8031 +#define ASYNC_RIO16_2 0x8032 +#define ASYNC_RIO16_3 0x8033 +#define ASYNC_RIO16_4 0x8034 +#define ASYNC_RIO16_5 0x8035 #define ASYNC_CONNMODE 0x8036 #define ISP_CONN_LOOP 1 #define ISP_CONN_PTP 2 #define ISP_CONN_BADLIP 3 #define ISP_CONN_FATAL 4 #define ISP_CONN_LOOPBACK 5 -#define ASYNC_RIO_RESP 0x8040 -#define ASYNC_RIO_COMP 0x8042 +#define ASYNC_RIOZIO_STALL 0x8040 /* there's a RIO/ZIO entry that hasn't been serviced */ +#define ASYNC_RIO32_2_2200 0x8042 /* same as ASYNC_RIO32_2, but for 2100/2200 */ #define ASYNC_RCV_ERR 0x8048 /* @@ -860,7 +862,7 @@ typedef struct { (ISP_CAP_MULTI_ID(isp) ? tag : 0) /* - * Reduced Interrupt Operation Response Queue Entreis + * Reduced Interrupt Operation Response Queue Entries */ typedef struct { diff --git a/sys/dev/isp/ispreg.h b/sys/dev/isp/ispreg.h index 08df337b88b..2d616aeb180 100644 --- a/sys/dev/isp/ispreg.h +++ b/sys/dev/isp/ispreg.h @@ -677,13 +677,13 @@ typedef struct { #define SXP_PINS_LVD_MODE 0x1000 #define SXP_PINS_HVD_MODE 0x0800 #define SXP_PINS_SE_MODE 0x0400 +#define SXP_PINS_MODE_MASK (SXP_PINS_LVD_MODE|SXP_PINS_HVD_MODE|SXP_PINS_SE_MODE) /* The above have to be put together with the DIFFM pin to make sense */ #define ISP1080_LVD_MODE (SXP_PINS_LVD_MODE) #define ISP1080_HVD_MODE (SXP_PINS_HVD_MODE|SXP_PINS_DIFF_MODE) #define ISP1080_SE_MODE (SXP_PINS_SE_MODE) -#define ISP1080_MODE_MASK \ - (SXP_PINS_LVD_MODE|SXP_PINS_HVD_MODE|SXP_PINS_SE_MODE|SXP_PINS_DIFF_MODE) +#define ISP1080_MODE_MASK (SXP_PINS_MODE_MASK|SXP_PINS_DIFF_MODE) /* * RISC and Host Command and Control Block Register Offsets From 02d2ad57705951ad023d53023e0cdf7fd8ae5b75 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 1 Mar 2010 19:16:34 +0000 Subject: [PATCH 1523/2592] MFC r204195: Improve output for controllers that doesn't report SATA speed. --- sbin/atacontrol/atacontrol.c | 1 + sbin/camcontrol/camcontrol.c | 2 ++ sys/cam/cam_xpt.c | 2 ++ sys/dev/ata/ata-all.c | 12 ++++++++++-- sys/dev/ata/ata-pci.c | 10 +++++++--- sys/dev/ata/ata-sata.c | 2 +- 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/sbin/atacontrol/atacontrol.c b/sbin/atacontrol/atacontrol.c index 29599eb3dc4..4354ddfb763 100644 --- a/sbin/atacontrol/atacontrol.c +++ b/sbin/atacontrol/atacontrol.c @@ -72,6 +72,7 @@ satarev2str(int mode) case 1: return "SATA 1.5Gb/s"; case 2: return "SATA 3Gb/s"; case 3: return "SATA 6Gb/s"; + case 0xff: return "SATA"; default: return "???"; } } diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 8a00f759f56..8e0605f6de2 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -1022,6 +1022,8 @@ camxferrate(struct cam_device *device) printf(" ("); if (sata->valid & CTS_SATA_VALID_REVISION) printf("SATA %d.x, ", sata->revision); + else + printf("SATA, "); if (sata->valid & CTS_SATA_VALID_MODE) printf("%s, ", ata_mode2string(sata->mode)); if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0) diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 9e79d02e4e3..ceaec99cb62 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -1214,6 +1214,8 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string) printf(" ("); if (sata->valid & CTS_SATA_VALID_REVISION) printf("SATA %d.x, ", sata->revision); + else + printf("SATA, "); if (sata->valid & CTS_SATA_VALID_MODE) printf("%s, ", ata_mode2string(sata->mode)); if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0) diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 6de8fda4e58..0195781cd29 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -1160,6 +1160,7 @@ ata_satarev2str(int rev) case 1: return "SATA 1.5Gb/s"; case 2: return "SATA 3Gb/s"; case 3: return "SATA 6Gb/s"; + case 0xff: return "SATA"; default: return "???"; } } @@ -1536,6 +1537,7 @@ ataaction(struct cam_sim *sim, union ccb *ccb) if (ch->flags & ATA_SATA) { cts->transport = XPORT_SATA; cts->transport_version = XPORT_VERSION_UNSPECIFIED; + cts->xport_specific.sata.valid = 0; cts->xport_specific.sata.mode = d->mode; cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE; cts->xport_specific.sata.bytecount = d->bytecount; @@ -1543,14 +1545,20 @@ ataaction(struct cam_sim *sim, union ccb *ccb) if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { cts->xport_specific.sata.revision = ATA_GETREV(dev, ccb->ccb_h.target_id); - } else + if (cts->xport_specific.sata.revision != 0xff) { + cts->xport_specific.sata.valid |= + CTS_SATA_VALID_REVISION; + } + } else { cts->xport_specific.sata.revision = d->revision; - cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; + } cts->xport_specific.sata.atapi = d->atapi; cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI; } else { cts->transport = XPORT_ATA; cts->transport_version = XPORT_VERSION_UNSPECIFIED; + cts->xport_specific.ata.valid = 0; cts->xport_specific.ata.mode = d->mode; cts->xport_specific.ata.valid |= CTS_ATA_VALID_MODE; cts->xport_specific.ata.bytecount = d->bytecount; diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index 8c4c01fa85e..527107363fe 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -714,10 +714,14 @@ static int ata_pcichannel_getrev(device_t dev, int target) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + struct ata_channel *ch = device_get_softc(dev); - if (ctlr->getrev) - return (ctlr->getrev(dev, target)); - else + if (ch->flags & ATA_SATA) { + if (ctlr->getrev) + return (ctlr->getrev(dev, target)); + else + return (0xff); + } else return (0); } diff --git a/sys/dev/ata/ata-sata.c b/sys/dev/ata/ata-sata.c index 9e3f7e8de06..d4c52fd475b 100644 --- a/sys/dev/ata/ata-sata.c +++ b/sys/dev/ata/ata-sata.c @@ -223,7 +223,7 @@ ata_sata_getrev(device_t dev, int target) if (ch->r_io[ATA_SSTATUS].res) return ((ATA_IDX_INL(ch, ATA_SSTATUS) & 0x0f0) >> 4); - return (0); + return (0xff); } int From d4301de786bdac70aaddf45e2e0ac48dfa309223 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 1 Mar 2010 19:19:30 +0000 Subject: [PATCH 1524/2592] MFC r204220, r204353: Virtualize transport part of periph announcement. --- sys/cam/ata/ata_xpt.c | 81 +++++++++++++++++++ sys/cam/cam_xpt.c | 157 ++----------------------------------- sys/cam/cam_xpt_internal.h | 3 +- sys/cam/scsi/scsi_xpt.c | 99 +++++++++++++++++++++++ 4 files changed, 189 insertions(+), 151 deletions(-) diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 92ba0271c87..0c2bf32f8a0 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -178,11 +178,13 @@ static void ata_dev_async(u_int32_t async_code, struct cam_ed *device, void *async_arg); static void ata_action(union ccb *start_ccb); +static void ata_announce_periph(struct cam_periph *periph); static struct xpt_xport ata_xport = { .alloc_device = ata_alloc_device, .action = ata_action, .async = ata_dev_async, + .announce = ata_announce_periph, }; struct xpt_xport * @@ -1641,3 +1643,82 @@ ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, } } +static void +ata_announce_periph(struct cam_periph *periph) +{ + struct ccb_pathinq cpi; + struct ccb_trans_settings cts; + struct cam_path *path = periph->path; + u_int speed; + u_int mb; + + mtx_assert(periph->sim->mtx, MA_OWNED); + + 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); + if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) + return; + /* Ask the SIM for its base transfer speed */ + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL); + cpi.ccb_h.func_code = XPT_PATH_INQ; + xpt_action((union ccb *)&cpi); + /* Report connection speed */ + speed = cpi.base_transfer_speed; + 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_MODE) + speed = ata_mode2speed(ata->mode); + } + 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_REVISION) + speed = ata_revision2speed(sata->revision); + } + mb = speed / 1000; + if (mb > 0) + printf("%s%d: %d.%03dMB/s transfers", + periph->periph_name, periph->unit_number, + mb, speed % 1000); + else + printf("%s%d: %dKB/s transfers", periph->periph_name, + periph->unit_number, speed); + /* Report additional information about connection */ + if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) { + struct ccb_trans_settings_ata *ata = + &cts.xport_specific.ata; + + printf(" ("); + if (ata->valid & CTS_ATA_VALID_MODE) + printf("%s, ", ata_mode2string(ata->mode)); + if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0) + printf("ATAPI %dbytes, ", ata->atapi); + if (ata->valid & CTS_ATA_VALID_BYTECOUNT) + printf("PIO %dbytes", ata->bytecount); + printf(")"); + } + if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) { + struct ccb_trans_settings_sata *sata = + &cts.xport_specific.sata; + + printf(" ("); + if (sata->valid & CTS_SATA_VALID_REVISION) + printf("SATA %d.x, ", sata->revision); + else + printf("SATA, "); + if (sata->valid & CTS_SATA_VALID_MODE) + printf("%s, ", ata_mode2string(sata->mode)); + if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0) + printf("ATAPI %dbytes, ", sata->atapi); + if (sata->valid & CTS_SATA_VALID_BYTECOUNT) + printf("PIO %dbytes", sata->bytecount); + printf(")"); + } + printf("\n"); +} + diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index ceaec99cb62..dea6e5e901e 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -1060,20 +1060,10 @@ xpt_remove_periph(struct cam_periph *periph) void xpt_announce_periph(struct cam_periph *periph, char *announce_string) { - struct ccb_pathinq cpi; - struct ccb_trans_settings cts; - struct cam_path *path; - u_int speed; - u_int freq; - u_int mb; + struct cam_path *path = periph->path; mtx_assert(periph->sim->mtx, MA_OWNED); - path = periph->path; - /* - * To ensure that this is printed in one piece, - * mask out CAM interrupts. - */ printf("%s%d at %s%d bus %d scbus%d target %d lun %d\n", periph->periph_name, periph->unit_number, path->bus->sim->sim_name, @@ -1084,157 +1074,26 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string) path->device->lun_id); printf("%s%d: ", periph->periph_name, periph->unit_number); if (path->device->protocol == PROTO_SCSI) - scsi_print_inquiry(&path->device->inq_data); + scsi_print_inquiry(&path->device->inq_data); else if (path->device->protocol == PROTO_ATA || path->device->protocol == PROTO_SATAPM) ata_print_ident(&path->device->ident_data); else - printf("Unknown protocol device\n"); + printf("Unknown protocol device\n"); if (bootverbose && path->device->serial_num_len > 0) { /* Don't wrap the screen - print only the first 60 chars */ printf("%s%d: Serial Number %.60s\n", periph->periph_name, periph->unit_number, path->device->serial_num); } - 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); - if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { - return; - } - - /* Ask the SIM for its base transfer speed */ - xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL); - cpi.ccb_h.func_code = XPT_PATH_INQ; - xpt_action((union ccb *)&cpi); - - 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 = - &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; - - 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; - - if (sas->valid & CTS_SAS_VALID_SPEED) - speed = sas->bitrate; - } - 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_MODE) - speed = ata_mode2speed(ata->mode); - } - 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_REVISION) - speed = ata_revision2speed(sata->revision); - } - - mb = speed / 1000; - if (mb > 0) - printf("%s%d: %d.%03dMB/s transfers", - periph->periph_name, periph->unit_number, - mb, speed % 1000); - else - printf("%s%d: %dKB/s transfers", periph->periph_name, - periph->unit_number, speed); - /* Report additional information about SPI connections */ - if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) { - struct ccb_trans_settings_spi *spi; - - spi = &cts.xport_specific.spi; - if (freq != 0) { - printf(" (%d.%03dMHz%s, offset %d", freq / 1000, - freq % 1000, - (spi->ppr_options & MSG_EXT_PPR_DT_REQ) != 0 - ? " DT" : "", - spi->sync_offset); - } - if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0 - && spi->bus_width > 0) { - if (freq != 0) { - printf(", "); - } else { - printf(" ("); - } - printf("%dbit)", 8 * (0x01 << spi->bus_width)); - } else if (freq != 0) { - printf(")"); - } - } - if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) { - struct ccb_trans_settings_fc *fc; - - fc = &cts.xport_specific.fc; - if (fc->valid & CTS_FC_VALID_WWNN) - printf(" WWNN 0x%llx", (long long) fc->wwnn); - if (fc->valid & CTS_FC_VALID_WWPN) - printf(" WWPN 0x%llx", (long long) fc->wwpn); - 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; - - printf(" ("); - if (ata->valid & CTS_ATA_VALID_MODE) - printf("%s, ", ata_mode2string(ata->mode)); - if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0) - printf("ATAPI %dbytes, ", ata->atapi); - if (ata->valid & CTS_ATA_VALID_BYTECOUNT) - printf("PIO %dbytes", ata->bytecount); - printf(")"); - } - if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) { - struct ccb_trans_settings_sata *sata = - &cts.xport_specific.sata; - - printf(" ("); - if (sata->valid & CTS_SATA_VALID_REVISION) - printf("SATA %d.x, ", sata->revision); - else - printf("SATA, "); - if (sata->valid & CTS_SATA_VALID_MODE) - printf("%s, ", ata_mode2string(sata->mode)); - if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0) - printf("ATAPI %dbytes, ", sata->atapi); - if (sata->valid & CTS_SATA_VALID_BYTECOUNT) - printf("PIO %dbytes", sata->bytecount); - printf(")"); - } + /* Announce transport details. */ + (*(path->bus->xport->announce))(periph); + /* Announce command queueing. */ if (path->device->inq_flags & SID_CmdQue || path->device->flags & CAM_DEV_TAG_AFTER_COUNT) { - printf("\n%s%d: Command Queueing enabled", + printf("%s%d: Command Queueing enabled\n", periph->periph_name, periph->unit_number); } - printf("\n"); - - /* - * We only want to print the caller's announce string if they've - * passed one in.. - */ + /* Announce caller's details if they've passed in. */ if (announce_string != NULL) printf("%s%d: %s\n", periph->periph_name, periph->unit_number, announce_string); diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h index b1fbaafb221..5fa4b5e6e68 100644 --- a/sys/cam/cam_xpt_internal.h +++ b/sys/cam/cam_xpt_internal.h @@ -44,8 +44,7 @@ typedef void (*xpt_dev_async_func)(u_int32_t async_code, struct cam_et *target, struct cam_ed *device, void *async_arg); -typedef void (*xpt_announce_periph_func)(struct cam_periph *periph, - char *announce_string); +typedef void (*xpt_announce_periph_func)(struct cam_periph *periph); struct xpt_xport { xpt_alloc_device_func alloc_device; diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c index 7639377052b..b907965a062 100644 --- a/sys/cam/scsi/scsi_xpt.c +++ b/sys/cam/scsi/scsi_xpt.c @@ -552,11 +552,13 @@ static void scsi_dev_async(u_int32_t async_code, struct cam_ed *device, void *async_arg); static void scsi_action(union ccb *start_ccb); +static void scsi_announce_periph(struct cam_periph *periph); static struct xpt_xport scsi_xport = { .alloc_device = scsi_alloc_device, .action = scsi_action, .async = scsi_dev_async, + .announce = scsi_announce_periph, }; struct xpt_xport * @@ -2414,3 +2416,100 @@ scsi_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, } } +static void +scsi_announce_periph(struct cam_periph *periph) +{ + struct ccb_pathinq cpi; + struct ccb_trans_settings cts; + struct cam_path *path = periph->path; + u_int speed; + u_int freq; + u_int mb; + + mtx_assert(periph->sim->mtx, MA_OWNED); + + 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); + if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) + return; + /* Ask the SIM for its base transfer speed */ + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL); + cpi.ccb_h.func_code = XPT_PATH_INQ; + xpt_action((union ccb *)&cpi); + /* Report connection speed */ + 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 = + &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; + + 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; + + if (sas->valid & CTS_SAS_VALID_SPEED) + speed = sas->bitrate; + } + mb = speed / 1000; + if (mb > 0) + printf("%s%d: %d.%03dMB/s transfers", + periph->periph_name, periph->unit_number, + mb, speed % 1000); + else + printf("%s%d: %dKB/s transfers", periph->periph_name, + periph->unit_number, speed); + /* Report additional information about SPI connections */ + if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) { + struct ccb_trans_settings_spi *spi; + + spi = &cts.xport_specific.spi; + if (freq != 0) { + printf(" (%d.%03dMHz%s, offset %d", freq / 1000, + freq % 1000, + (spi->ppr_options & MSG_EXT_PPR_DT_REQ) != 0 + ? " DT" : "", + spi->sync_offset); + } + if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0 + && spi->bus_width > 0) { + if (freq != 0) { + printf(", "); + } else { + printf(" ("); + } + printf("%dbit)", 8 * (0x01 << spi->bus_width)); + } else if (freq != 0) { + printf(")"); + } + } + if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) { + struct ccb_trans_settings_fc *fc; + + fc = &cts.xport_specific.fc; + if (fc->valid & CTS_FC_VALID_WWNN) + printf(" WWNN 0x%llx", (long long) fc->wwnn); + if (fc->valid & CTS_FC_VALID_WWPN) + printf(" WWPN 0x%llx", (long long) fc->wwpn); + if (fc->valid & CTS_FC_VALID_PORT) + printf(" PortID 0x%x", fc->port); + } + printf("\n"); +} + From df7d3f0a1f3aa49307520ae5233da67b123307a0 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 1 Mar 2010 19:32:34 +0000 Subject: [PATCH 1525/2592] MFC r204253: Make xpt_rescan() more correct, as it was before r197208: do not use XPT_SCAN_LUN for wildcard LUN, fall back to XPT_SCAN_BUS. --- sys/cam/cam_xpt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index dea6e5e901e..560ccfd480b 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -861,7 +861,8 @@ xpt_rescan(union ccb *ccb) struct ccb_hdr *hdr; /* Prepare request */ - if(ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD) + if (ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD || + ccb->ccb_h.path->device->lun_id == CAM_LUN_WILDCARD) ccb->ccb_h.func_code = XPT_SCAN_BUS; else ccb->ccb_h.func_code = XPT_SCAN_LUN; From aeb7e9f945740c55f0ec2d690bbf556584577681 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 1 Mar 2010 19:36:19 +0000 Subject: [PATCH 1526/2592] MFC r204354: Make PUIS detection more strict. Previous implementation caused false positives on VMWare's virtual CD-ROMs. --- sys/cam/ata/ata_xpt.c | 9 ++++----- sys/sys/ata.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 0c2bf32f8a0..d5e0b32a49b 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -788,11 +788,10 @@ noerror: ata_btrim(ident_buf->serial, sizeof(ident_buf->serial)); ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial)); /* Device may need spin-up before IDENTIFY become valid. */ - if ((ident_buf->config & ATA_RESP_INCOMPLETE) || - ((ident_buf->support.command2 & ATA_SUPPORT_STANDBY) && - (ident_buf->enabled.command2 & ATA_SUPPORT_STANDBY) && - (ident_buf->support.command2 & ATA_SUPPORT_SPINUP) && - softc->spinup == 0)) { + if ((ident_buf->specconf == 0x37c8 || + ident_buf->specconf == 0x738c) && + ((ident_buf->config & ATA_RESP_INCOMPLETE) || + softc->spinup == 0)) { PROBE_SET_ACTION(softc, PROBE_SPINUP); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); diff --git a/sys/sys/ata.h b/sys/sys/ata.h index e8a04dbbbfd..cacb1ea0277 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -51,7 +51,7 @@ struct ata_params { #define ATA_RESP_INCOMPLETE 0x0004 /*001*/ u_int16_t cylinders; /* # of cylinders */ - u_int16_t reserved2; +/*002*/ u_int16_t specconf; /* specific configuration */ /*003*/ u_int16_t heads; /* # heads */ u_int16_t obsolete4; u_int16_t obsolete5; From 8b1670d00cf9eb281390f8e1074f9db75b5b47c6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 1 Mar 2010 19:43:26 +0000 Subject: [PATCH 1527/2592] MFC r204351: Fix bug in headphones audio redirection using separate DAC. It was exposed by removing channel duplication during multichannel audio implementation. --- sys/dev/sound/pci/hda/hdac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 84fc32283a6..06815686660 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -86,7 +86,7 @@ #include "mixer_if.h" -#define HDA_DRV_TEST_REV "20100122_0141" +#define HDA_DRV_TEST_REV "20100226_0142" SND_DECLARE_FILE("$FreeBSD$"); @@ -3503,7 +3503,7 @@ hdac_stream_setup(struct hdac_chan *ch) /* If HP redirection is enabled, but failed to use same DAC, make last DAC to duplicate first one. */ - if (as->hpredir >= 0 && i == as->pincnt) { + if (as->fakeredir && i == (as->pincnt - 1)) { c = (ch->sid << 4); } else { if (map >= 0) /* Map known speaker setups. */ From 4dcf8bb3e27cb46f60afb73c7d1fb61ca6a322ab Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 1 Mar 2010 21:04:01 +0000 Subject: [PATCH 1528/2592] MFC: Fix spelling of EACCES. --- share/man/man9/namei.9 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man9/namei.9 b/share/man/man9/namei.9 index 1ffabfffa07..0325c36fa58 100644 --- a/share/man/man9/namei.9 +++ b/share/man/man9/namei.9 @@ -333,7 +333,7 @@ or an entire pathname exceeded 1023 characters. .It Bq Er ENOENT A component of the specified pathname does not exist, or the pathname is an empty string. -.It Bq Er ACCES +.It Bq Er EACCES An attempt is made to access a file in a way forbidden by its file access permissions. .It Bq Er ELOOP From aa3d547d095ff07fdc39ffc5ae4c371844b504ab Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 2 Mar 2010 01:56:55 +0000 Subject: [PATCH 1529/2592] MFC x86emu/x86bios emulator and make previously i386 only dpms and vesa framebuffer driver, etc. work on FreeBSD/amd64. A significant amount of improvements were done by jkim@ during the recent months to make vesa(4) work better, over the initial code import. This work is based on OpenBSD's x86emu implementation and contributed by paradox and swell.k at gmail com. Hopefully I have stolen all their work to 8-STABLE :) All bugs in this commit are mine, as usual. --- ObsoleteFiles.inc | 3 + lib/Makefile | 1 + share/man/man4/Makefile | 2 + share/man/man4/{man4.i386 => }/dpms.4 | 0 share/man/man4/syscons.4 | 14 +- sys/amd64/conf/NOTES | 14 + sys/compat/x86bios/x86bios.c | 546 ++ sys/compat/x86bios/x86bios.h | 156 + sys/compat/x86bios/x86bios_alloc.c | 81 + sys/conf/NOTES | 1 + sys/conf/files | 1 - sys/conf/files.amd64 | 9 + sys/conf/files.i386 | 10 +- sys/conf/options | 2 + sys/conf/options.amd64 | 3 + sys/contrib/x86emu/x86emu.c | 8335 ++++++++++++++++++++++++ sys/contrib/x86emu/x86emu.h | 184 + sys/contrib/x86emu/x86emu_regs.h | 170 + sys/contrib/x86emu/x86emu_util.c | 208 + sys/dev/atkbdc/atkbd.c | 63 +- sys/{i386/isa => dev/dpms}/dpms.c | 48 +- sys/dev/fb/s3_pci.c | 3 +- sys/{i386/isa => dev/fb}/vesa.c | 1346 ++-- sys/{i386/include/pc => dev/fb}/vesa.h | 24 +- sys/dev/fb/vga.c | 2 +- sys/dev/fb/vgareg.h | 1 + sys/dev/pci/vga_pci.c | 21 + sys/dev/syscons/scvesactl.c | 2 +- sys/dev/syscons/scvgarndr.c | 20 +- sys/dev/syscons/scvidctl.c | 77 +- sys/dev/syscons/syscons.c | 138 +- sys/dev/syscons/syscons.h | 8 +- sys/i386/conf/NOTES | 6 + sys/isa/vga_isa.c | 205 +- sys/modules/Makefile | 7 + sys/modules/dpms/Makefile | 8 +- sys/modules/vesa/Makefile | 11 +- sys/modules/x86bios/Makefile | 11 + sys/modules/x86emu/Makefile | 8 + sys/sys/fbio.h | 2 + sys/sys/param.h | 2 +- 41 files changed, 10992 insertions(+), 761 deletions(-) rename share/man/man4/{man4.i386 => }/dpms.4 (100%) create mode 100644 sys/compat/x86bios/x86bios.c create mode 100644 sys/compat/x86bios/x86bios.h create mode 100644 sys/compat/x86bios/x86bios_alloc.c create mode 100644 sys/contrib/x86emu/x86emu.c create mode 100644 sys/contrib/x86emu/x86emu.h create mode 100644 sys/contrib/x86emu/x86emu_regs.h create mode 100644 sys/contrib/x86emu/x86emu_util.c rename sys/{i386/isa => dev/dpms}/dpms.c (88%) rename sys/{i386/isa => dev/fb}/vesa.c (56%) rename sys/{i386/include/pc => dev/fb}/vesa.h (86%) create mode 100644 sys/modules/x86bios/Makefile create mode 100644 sys/modules/x86emu/Makefile diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 6a1d0cf1248..25e43bab28c 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. # +# 20100301: 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 # 20091218: removal of rc.early(8) link OLD_FILES+=usr/share/man/man8/rc.early.8.gz # 20091027: pselect.3 implemented as syscall diff --git a/lib/Makefile b/lib/Makefile index 7cacb704f6a..00b1c6089b3 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -112,6 +112,7 @@ _libsmb= libsmb _libncp= libncp .endif _libsmb= libsmb +_libvgl= libvgl .endif .if ${MACHINE_ARCH} == "powerpc" diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 812a450ff4b..f8af593a09b 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -86,6 +86,7 @@ MAN= aac.4 \ digi.4 \ disc.4 \ divert.4 \ + ${_dpms.4} \ dpt.4 \ dummynet.4 \ ed.4 \ @@ -622,6 +623,7 @@ _amdtemp.4= amdtemp.4 _asmc.4= asmc.4 _coretemp.4= coretemp.4 _cpuctl.4= cpuctl.4 +_dpms.4= dpms.4 _hptiop.4= hptiop.4 _hptmv.4= hptmv.4 _hptrr.4= hptrr.4 diff --git a/share/man/man4/man4.i386/dpms.4 b/share/man/man4/dpms.4 similarity index 100% rename from share/man/man4/man4.i386/dpms.4 rename to share/man/man4/dpms.4 diff --git a/share/man/man4/syscons.4 b/share/man/man4/syscons.4 index 3f6e9caceb3..2c9d21d9056 100644 --- a/share/man/man4/syscons.4 +++ b/share/man/man4/syscons.4 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 22, 2006 +.Dd September 10, 2009 .Dt SYSCONS 4 .Os .Sh NAME @@ -325,7 +325,7 @@ This mode is useful on some laptop computers, but less so on most other systems, and it adds substantial amount of code to syscons. If this option is NOT defined, you can reduce the kernel size a lot. See the -.Dv VESA800X600 +.Dv VESAMODE flag below. .It Dv SC_TWOBUTTON_MOUSE If you have a two button mouse, you may want to add this option @@ -426,15 +426,15 @@ or else at the loader prompt (see .\".It bit 6 (QUIET_BELL) .\"This option suppresses the bell, whether audible or visual, .\"if it is rung in a background virtual terminal. -.It 0x0080 (VESA800X600) -This option puts the video card in the VESA 800x600 pixel, 16 color -mode. -It may be useful for laptop computers for which the 800x600 mode -is otherwise unsupported by the X server. +.It 0x0080 (VESAMODE) +This option puts the video card in the VESA mode specified by higher +16 bits of the flags during kernel initialization. Note that in order for this flag to work, the kernel must be compiled with the .Dv SC_PIXEL_MODE option explained above. +A list of the available mode can be obtained via +.Xr vidcontrol 1 . .\"Note also that the ``copy-and-paste'' function is not currently supported .\"in this mode and the mouse pointer will not be displayed. .It 0x0100 (AUTODETECT_KBD) diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index a231d333bac..159f12e809d 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -154,6 +154,17 @@ options AGP_DEBUG ##################################################################### # HARDWARE DEVICE CONFIGURATION +# To include support for VGA VESA video modes +options VESA + +# Turn on extra debugging checks and output for VESA support. +options VESA_DEBUG + +device dpms # DPMS suspend & resume via VESA BIOS + +# x86 real mode BIOS emulator, required by atkbdc/dpms/vesa +options X86BIOS + # # Optional devices: # @@ -213,6 +224,9 @@ options VGA_WIDTH90 # support 90 column modes # Debugging. options VGA_DEBUG +# Linear framebuffer driver for S3 VESA 1.2 cards. Works on top of VESA. +device s3pci + # 3Dfx Voodoo Graphics, Voodoo II /dev/3dfx CDEV support. This will create # the /dev/3dfx0 device to work with glide implementations. This should get # linked to /dev/3dfx and /dev/voodoo. Note that this is not the same as diff --git a/sys/compat/x86bios/x86bios.c b/sys/compat/x86bios/x86bios.c new file mode 100644 index 00000000000..34da07c3d40 --- /dev/null +++ b/sys/compat/x86bios/x86bios.c @@ -0,0 +1,546 @@ +/*- + * 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 + * 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 "opt_x86bios.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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; + +SYSCTL_NODE(_debug, OID_AUTO, x86bios, CTLFLAG_RD, NULL, "x86bios debugging"); +static int x86bios_trace_call; +TUNABLE_INT("debug.x86bios.call", &x86bios_trace_call); +SYSCTL_INT(_debug_x86bios, OID_AUTO, call, CTLFLAG_RW, &x86bios_trace_call, 0, + "Trace far function calls"); +static int x86bios_trace_int; +TUNABLE_INT("debug.x86bios.int", &x86bios_trace_int); +SYSCTL_INT(_debug_x86bios, OID_AUTO, int, CTLFLAG_RW, &x86bios_trace_int, 0, + "Trace software interrupt handlers"); + +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) +{ + + if (port == 0xb2) /* APM scratch register */ + return (0); + if (port >= 0x80 && port < 0x88) /* POST status register */ + return (0); + + return (inb(port)); +} + +static uint16_t +x86bios_emu_inw(struct x86emu *emu, uint16_t port) +{ + + if (port >= 0x80 && port < 0x88) /* POST status register */ + return (0); + + return (inw(port)); +} + +static uint32_t +x86bios_emu_inl(struct x86emu *emu, uint16_t port) +{ + + if (port >= 0x80 && port < 0x88) /* POST status register */ + return (0); + + return (inl(port)); +} + +static void +x86bios_emu_outb(struct x86emu *emu, uint16_t port, uint8_t val) +{ + + if (port == 0xb2) /* APM scratch register */ + return; + if (port >= 0x80 && port < 0x88) /* POST status register */ + return; + + outb(port, val); +} + +static void +x86bios_emu_outw(struct x86emu *emu, uint16_t port, uint16_t val) +{ + + if (port >= 0x80 && port < 0x88) /* POST status register */ + return; + + outw(port, val); +} + +static void +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 (x86bios_trace_call) + 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 (x86bios_trace_call) + 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) +{ + + if (intno < 0 || intno > 255) + return; + + if (x86bios_map == NULL) + return; + + if (x86bios_trace_int) + printf("Calling int 0x%x (ax=0x%04x bx=0x%04x " + "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n", + intno, 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_intr(&x86bios_emu, intno); + memcpy(regs, &x86bios_emu.x86, sizeof(*regs)); + mtx_unlock_spin(&x86bios_lock); + + if (x86bios_trace_int) + printf("Exiting int 0x%x (ax=0x%04x bx=0x%04x " + "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n", + intno, regs->R_AX, regs->R_BX, regs->R_CX, + regs->R_DX, regs->R_ES, regs->R_DI); +} + +void * +x86bios_offset(uint32_t offset) +{ + + 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_mapbios(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 i; + + mtx_init(&x86bios_lock, "x86bios lock", NULL, MTX_SPIN); + + if (x86bios_map_mem() != 0) + return; + + 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; + x86bios_emu.emu_inl = x86bios_emu_inl; + x86bios_emu.emu_outb = x86bios_emu_outb; + x86bios_emu.emu_outw = x86bios_emu_outw; + x86bios_emu.emu_outl = x86bios_emu_outl; + + 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; + + mtx_lock_spin(&x86bios_lock); + if (x86bios_map != NULL) { + free(x86bios_map, M_DEVBUF); + x86bios_map = NULL; + } + mtx_unlock_spin(&x86bios_lock); + + if (map != NULL) + x86bios_unmap_mem(); + + mtx_destroy(&x86bios_lock); +} + +static int +x86bios_modevent(module_t mod __unused, int type, void *data __unused) +{ + + switch (type) { + case MOD_LOAD: + x86bios_init(NULL); + break; + case MOD_UNLOAD: + x86bios_uninit(NULL); + break; + default: + return (ENOTSUP); + } + + return (0); +} + +static moduledata_t x86bios_mod = { + "x86bios", + x86bios_modevent, + NULL, +}; + +DECLARE_MODULE(x86bios, x86bios_mod, SI_SUB_CPU, SI_ORDER_ANY); +MODULE_VERSION(x86bios, 1); diff --git a/sys/compat/x86bios/x86bios.h b/sys/compat/x86bios/x86bios.h new file mode 100644 index 00000000000..4ed15e07527 --- /dev/null +++ b/sys/compat/x86bios/x86bios.h @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2009 Alex Keda + * 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$ + */ +/* + * x86 registers were borrowed from x86emu.h x86emu_regs.h + * for compatability. + */ + +#ifndef _X86BIOS_H_ +#define _X86BIOS_H_ + +#include +#include +#include + +#ifdef __BIG_ENDIAN__ + +struct x86_register32 { + uint32_t e_reg; +}; + +struct x86_register16 { + uint16_t filler0; + uint16_t x_reg; +}; + +struct x86_register8 { + uint8_t filler0; + uint8_t filler1; + uint8_t h_reg; + uint8_t l_reg; +}; + +#else /* !__BIG_ENDIAN__ */ + +struct x86_register32 { + uint32_t e_reg; +}; + +struct x86_register16 { + uint16_t x_reg; +}; + +struct x86_register8 { + uint8_t l_reg; + uint8_t h_reg; +}; + +#endif /* __BIG_ENDIAN__ */ + +union x86_register { + struct x86_register32 I32_reg; + struct x86_register16 I16_reg; + struct x86_register8 I8_reg; +}; + +struct x86regs { + uint16_t _pad0; /* CS */ + uint16_t _pad1; /* DS */ + uint16_t register_es; + uint16_t register_fs; + uint16_t register_gs; + 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 _pad3; /* SP */ + union x86_register register_bp; + union x86_register register_si; + union x86_register register_di; +}; + +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 + +/* 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 + +/* 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 + +/* special registers */ +#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_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_ES register_es +#define R_FS register_fs +#define R_GS register_gs + +#define X86BIOS_PHYSTOSEG(x) (((x) >> 4) & 0xffff) +#define X86BIOS_PHYSTOOFF(x) ((x) & 0x000f) + +__BEGIN_DECLS +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 new file mode 100644 index 00000000000..624a75ce008 --- /dev/null +++ b/sys/compat/x86bios/x86bios_alloc.c @@ -0,0 +1,81 @@ +/*- + * 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 * +x86biosAlloc(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 +x86biosFree(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/NOTES b/sys/conf/NOTES index f3058d2dc0f..768c23af099 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2821,3 +2821,4 @@ options AAC_DEBUG # Debugging levels: ##options BKTR_ALLOC_PAGES=(217*4+1) options BROOKTREE_ALLOC_PAGES=(217*4+1) options MAXFILES=999 + diff --git a/sys/conf/files b/sys/conf/files index d14c1ee886f..588e7d737c0 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2893,4 +2893,3 @@ dev/xen/netfront/netfront.c optional xen | xenhvm dev/xen/xenpci/xenpci.c optional xenpci dev/xen/xenpci/evtchn.c optional xenpci dev/xen/xenpci/machine_reboot.c optional xenpci - diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index d7b57651518..2b33ea60b1e 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -163,6 +163,7 @@ dev/atkbdc/atkbdc_subr.c optional atkbdc dev/atkbdc/psm.c optional psm atkbdc dev/coretemp/coretemp.c optional coretemp dev/cpuctl/cpuctl.c optional cpuctl +dev/dpms/dpms.c optional dpms # There are no systems with isa slots, so all ed isa entries should go.. dev/ed/if_ed_3c503.c optional ed isa ed_3c503 dev/ed/if_ed_isa.c optional ed isa @@ -170,6 +171,8 @@ dev/ed/if_ed_wd80x3.c optional ed isa dev/ed/if_ed_hpp.c optional ed isa ed_hpp dev/ed/if_ed_sic.c optional ed isa ed_sic dev/fb/fb.c optional fb | vga +dev/fb/s3_pci.c optional s3pci +dev/fb/vesa.c optional vga vesa dev/fb/vga.c optional vga dev/ichwd/ichwd.c optional ichwd dev/if_ndis/if_ndis.c optional ndis @@ -220,6 +223,7 @@ dev/sio/sio_puc.c optional sio puc dev/speaker/spkr.c optional speaker dev/syscons/apm/apm_saver.c optional apm_saver apm dev/syscons/scterm-teken.c optional sc +dev/syscons/scvesactl.c optional sc vga vesa dev/syscons/scvgarndr.c optional sc vga dev/syscons/scvtb.c optional sc dev/syscons/teken/teken.c optional sc @@ -294,3 +298,8 @@ i386/cpufreq/p4tcc.c optional cpufreq # libkern/memmove.c standard libkern/memset.c standard +# +# x86 real mode BIOS emulator, required by atkbdc/dpms/vesa +# +compat/x86bios/x86bios.c optional x86bios | atkbd | dpms | vesa +contrib/x86emu/x86emu.c optional x86bios | atkbd | dpms | vesa diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index b1e60d67147..4df00d767e7 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -151,12 +151,15 @@ dev/ctau/if_ct.c optional ctau dev/cx/csigma.c optional cx dev/cx/cxddk.c optional cx dev/cx/if_cx.c optional cx +dev/dpms/dpms.c optional dpms dev/ed/if_ed_3c503.c optional ed isa ed_3c503 dev/ed/if_ed_isa.c optional ed isa dev/ed/if_ed_wd80x3.c optional ed isa dev/ed/if_ed_hpp.c optional ed isa ed_hpp dev/ed/if_ed_sic.c optional ed isa ed_sic dev/fb/fb.c optional fb | vga +dev/fb/s3_pci.c optional s3pci +dev/fb/vesa.c optional vga vesa dev/fb/vga.c optional vga dev/fdc/fdc.c optional fdc dev/fdc/fdc_acpi.c optional fdc @@ -333,7 +336,6 @@ i386/isa/clock.c optional native i386/xen/clock.c optional xen i386/xen/xen_clock_util.c optional xen i386/xen/xen_rtc.c optional xen -i386/isa/dpms.c optional dpms i386/isa/elcr.c standard i386/isa/elink.c optional ep | ie i386/isa/isa.c optional isa @@ -343,7 +345,6 @@ i386/isa/npx.c optional npx i386/isa/pmtimer.c optional pmtimer i386/isa/prof_machdep.c optional profiling-routine i386/isa/spic.c optional spic -i386/isa/vesa.c optional vga vesa i386/linux/imgact_linux.c optional compat_linux i386/linux/linux_dummy.c optional compat_linux i386/linux/linux_locore.s optional compat_linux \ @@ -381,3 +382,8 @@ i386/xbox/xbox.c optional xbox i386/xbox/xboxfb.c optional xboxfb dev/fb/boot_font.c optional xboxfb 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 +contrib/x86emu/x86emu.c optional x86bios | atkbd | dpms | vesa diff --git a/sys/conf/options b/sys/conf/options index e336fdc84a0..7f5fd051b2c 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -841,3 +841,5 @@ SND_FEEDER_FULL_MULTIFORMAT opt_snd.h SND_FEEDER_RATE_HP opt_snd.h SND_PCM_64 opt_snd.h SND_OLDSTEREO opt_snd.h + +X86BIOS diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64 index beb97ed7d1e..5617da4e181 100644 --- a/sys/conf/options.amd64 +++ b/sys/conf/options.amd64 @@ -37,6 +37,9 @@ VGA_NO_MODE_CHANGE opt_vga.h VGA_SLOW_IOACCESS opt_vga.h VGA_WIDTH90 opt_vga.h +VESA +VESA_DEBUG opt_vesa.h + # AGP debugging support AGP_DEBUG opt_agp.h diff --git a/sys/contrib/x86emu/x86emu.c b/sys/contrib/x86emu/x86emu.c new file mode 100644 index 00000000000..3e5a06ad98e --- /dev/null +++ b/sys/contrib/x86emu/x86emu.c @@ -0,0 +1,8335 @@ +/* $OpenBSD: x86emu.c,v 1.4 2009/06/18 14:19:21 pirofti Exp $ */ +/* $NetBSD: x86emu.c,v 1.7 2009/02/03 19:26:29 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 + +static void x86emu_intr_raise (struct x86emu *, uint8_t type); + +static void x86emu_exec_one_byte(struct x86emu *); +static void x86emu_exec_two_byte(struct x86emu *); + +static void fetch_decode_modrm (struct x86emu *); +static uint8_t fetch_byte_imm (struct x86emu *); +static uint16_t fetch_word_imm (struct x86emu *); +static uint32_t fetch_long_imm (struct x86emu *); +static uint8_t fetch_data_byte (struct x86emu *, uint32_t offset); +static uint8_t fetch_byte (struct x86emu *, u_int segment, uint32_t offset); +static uint16_t fetch_data_word (struct x86emu *, uint32_t offset); +static uint16_t fetch_word (struct x86emu *, uint32_t segment, uint32_t offset); +static uint32_t fetch_data_long (struct x86emu *, uint32_t offset); +static uint32_t fetch_long (struct x86emu *, uint32_t segment, uint32_t offset); +static void store_data_byte (struct x86emu *, uint32_t offset, uint8_t val); +static void store_byte (struct x86emu *, uint32_t segment, uint32_t offset, uint8_t val); +static void store_data_word (struct x86emu *, uint32_t offset, uint16_t val); +static void store_word (struct x86emu *, uint32_t segment, uint32_t offset, uint16_t val); +static void store_data_long (struct x86emu *, uint32_t offset, uint32_t val); +static void store_long (struct x86emu *, uint32_t segment, uint32_t offset, uint32_t val); +static uint8_t* decode_rl_byte_register(struct x86emu *); +static uint16_t* decode_rl_word_register(struct x86emu *); +static uint32_t* decode_rl_long_register(struct x86emu *); +static uint8_t* decode_rh_byte_register(struct x86emu *); +static uint16_t* decode_rh_word_register(struct x86emu *); +static uint32_t* decode_rh_long_register(struct x86emu *); +static uint16_t* decode_rh_seg_register(struct x86emu *); +static uint32_t decode_rl_address(struct x86emu *); + +static uint8_t decode_and_fetch_byte(struct x86emu *); +static uint16_t decode_and_fetch_word(struct x86emu *); +static uint32_t decode_and_fetch_long(struct x86emu *); + +static uint8_t decode_and_fetch_byte_imm8(struct x86emu *, uint8_t *); +static uint16_t decode_and_fetch_word_imm8(struct x86emu *, uint8_t *); +static uint32_t decode_and_fetch_long_imm8(struct x86emu *, uint8_t *); + +static uint16_t decode_and_fetch_word_disp(struct x86emu *, int16_t); +static uint32_t decode_and_fetch_long_disp(struct x86emu *, int16_t); + +static void write_back_byte(struct x86emu *, uint8_t); +static void write_back_word(struct x86emu *, uint16_t); +static void write_back_long(struct x86emu *, uint32_t); + +static uint16_t aaa_word (struct x86emu *, uint16_t d); +static uint16_t aas_word (struct x86emu *, uint16_t d); +static uint16_t aad_word (struct x86emu *, uint16_t d); +static uint16_t aam_word (struct x86emu *, uint8_t d); +static uint8_t adc_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t adc_word (struct x86emu *, uint16_t d, uint16_t s); +static uint32_t adc_long (struct x86emu *, uint32_t d, uint32_t s); +static uint8_t add_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t add_word (struct x86emu *, uint16_t d, uint16_t s); +static uint32_t add_long (struct x86emu *, uint32_t d, uint32_t s); +static uint8_t and_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t and_word (struct x86emu *, uint16_t d, uint16_t s); +static uint32_t and_long (struct x86emu *, uint32_t d, uint32_t s); +static uint8_t cmp_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t cmp_word (struct x86emu *, uint16_t d, uint16_t s); +static uint32_t cmp_long (struct x86emu *, uint32_t d, uint32_t s); +static void cmp_byte_no_return (struct x86emu *, uint8_t d, uint8_t s); +static void cmp_word_no_return (struct x86emu *, uint16_t d, uint16_t s); +static void cmp_long_no_return (struct x86emu *, uint32_t d, uint32_t s); +static uint8_t daa_byte (struct x86emu *, uint8_t d); +static uint8_t das_byte (struct x86emu *, uint8_t d); +static uint8_t dec_byte (struct x86emu *, uint8_t d); +static uint16_t dec_word (struct x86emu *, uint16_t d); +static uint32_t dec_long (struct x86emu *, uint32_t d); +static uint8_t inc_byte (struct x86emu *, uint8_t d); +static uint16_t inc_word (struct x86emu *, uint16_t d); +static uint32_t inc_long (struct x86emu *, uint32_t d); +static uint8_t or_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t or_word (struct x86emu *, uint16_t d, uint16_t s); +static uint32_t or_long (struct x86emu *, uint32_t d, uint32_t s); +static uint8_t neg_byte (struct x86emu *, uint8_t s); +static uint16_t neg_word (struct x86emu *, uint16_t s); +static uint32_t neg_long (struct x86emu *, uint32_t s); +static uint8_t rcl_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t rcl_word (struct x86emu *, uint16_t d, uint8_t s); +static uint32_t rcl_long (struct x86emu *, uint32_t d, uint8_t s); +static uint8_t rcr_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t rcr_word (struct x86emu *, uint16_t d, uint8_t s); +static uint32_t rcr_long (struct x86emu *, uint32_t d, uint8_t s); +static uint8_t rol_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t rol_word (struct x86emu *, uint16_t d, uint8_t s); +static uint32_t rol_long (struct x86emu *, uint32_t d, uint8_t s); +static uint8_t ror_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t ror_word (struct x86emu *, uint16_t d, uint8_t s); +static uint32_t ror_long (struct x86emu *, uint32_t d, uint8_t s); +static uint8_t shl_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t shl_word (struct x86emu *, uint16_t d, uint8_t s); +static uint32_t shl_long (struct x86emu *, uint32_t d, uint8_t s); +static uint8_t shr_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t shr_word (struct x86emu *, uint16_t d, uint8_t s); +static uint32_t shr_long (struct x86emu *, uint32_t d, uint8_t s); +static uint8_t sar_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t sar_word (struct x86emu *, uint16_t d, uint8_t s); +static uint32_t sar_long (struct x86emu *, uint32_t d, uint8_t s); +static uint16_t shld_word (struct x86emu *, uint16_t d, uint16_t fill, uint8_t s); +static uint32_t shld_long (struct x86emu *, uint32_t d, uint32_t fill, uint8_t s); +static uint16_t shrd_word (struct x86emu *, uint16_t d, uint16_t fill, uint8_t s); +static uint32_t shrd_long (struct x86emu *, uint32_t d, uint32_t fill, uint8_t s); +static uint8_t sbb_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t sbb_word (struct x86emu *, uint16_t d, uint16_t s); +static uint32_t sbb_long (struct x86emu *, uint32_t d, uint32_t s); +static uint8_t sub_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t sub_word (struct x86emu *, uint16_t d, uint16_t s); +static uint32_t sub_long (struct x86emu *, uint32_t d, uint32_t s); +static void test_byte (struct x86emu *, uint8_t d, uint8_t s); +static void test_word (struct x86emu *, uint16_t d, uint16_t s); +static void test_long (struct x86emu *, uint32_t d, uint32_t s); +static uint8_t xor_byte (struct x86emu *, uint8_t d, uint8_t s); +static uint16_t xor_word (struct x86emu *, uint16_t d, uint16_t s); +static uint32_t xor_long (struct x86emu *, uint32_t d, uint32_t s); +static void imul_byte (struct x86emu *, uint8_t s); +static void imul_word (struct x86emu *, uint16_t s); +static void imul_long (struct x86emu *, uint32_t s); +static void mul_byte (struct x86emu *, uint8_t s); +static void mul_word (struct x86emu *, uint16_t s); +static void mul_long (struct x86emu *, uint32_t s); +static void idiv_byte (struct x86emu *, uint8_t s); +static void idiv_word (struct x86emu *, uint16_t s); +static void idiv_long (struct x86emu *, uint32_t s); +static void div_byte (struct x86emu *, uint8_t s); +static void div_word (struct x86emu *, uint16_t s); +static void div_long (struct x86emu *, uint32_t s); +static void ins (struct x86emu *, int size); +static void outs (struct x86emu *, int size); +static void push_word (struct x86emu *, uint16_t w); +static void push_long (struct x86emu *, uint32_t w); +static uint16_t pop_word (struct x86emu *); +static uint32_t pop_long (struct x86emu *); + +/* + * REMARKS: + * Handles any pending asychronous interrupts. + */ +static void +x86emu_intr_dispatch(struct x86emu *emu, uint8_t intno) +{ + if (emu->_x86emu_intrTab[intno]) { + (*emu->_x86emu_intrTab[intno]) (emu, intno); + } else { + push_word(emu, (uint16_t) emu->x86.R_FLG); + CLEAR_FLAG(F_IF); + CLEAR_FLAG(F_TF); + push_word(emu, emu->x86.R_CS); + emu->x86.R_CS = fetch_word(emu, 0, intno * 4 + 2); + push_word(emu, emu->x86.R_IP); + emu->x86.R_IP = fetch_word(emu, 0, intno * 4); + } +} + +static void +x86emu_intr_handle(struct x86emu *emu) +{ + uint8_t intno; + + if (emu->x86.intr & INTR_SYNCH) { + intno = emu->x86.intno; + emu->x86.intr = 0; + x86emu_intr_dispatch(emu, intno); + } +} + +/* + * PARAMETERS: + * intrnum - Interrupt number to raise + * + * REMARKS: + * Raise the specified interrupt to be handled before the execution of the + * next instruction. + */ +void +x86emu_intr_raise(struct x86emu *emu, uint8_t intrnum) +{ + emu->x86.intno = intrnum; + emu->x86.intr |= INTR_SYNCH; +} + +/* + * REMARKS: + * Main execution loop for the emulator. We return from here when the system + * halts, which is normally caused by a stack fault when we return from the + * original real mode call. + */ +void +x86emu_exec(struct x86emu *emu) +{ + emu->x86.intr = 0; + + if (setjmp(emu->exec_state)) + return; + + for (;;) { + if (emu->x86.intr) { + if (((emu->x86.intr & INTR_SYNCH) && (emu->x86.intno == 0 || emu->x86.intno == 2)) || + !ACCESS_FLAG(F_IF)) { + x86emu_intr_handle(emu); + } + } + if (emu->x86.R_CS == 0 && emu->x86.R_IP == 0) + return; + x86emu_exec_one_byte(emu); + ++emu->cur_cycles; + } +} + +void +x86emu_exec_call(struct x86emu *emu, uint16_t seg, uint16_t off) +{ + push_word(emu, 0); + push_word(emu, 0); + emu->x86.R_CS = seg; + emu->x86.R_IP = off; + + x86emu_exec(emu); +} + +void +x86emu_exec_intr(struct x86emu *emu, uint8_t intr) +{ + push_word(emu, emu->x86.R_FLG); + CLEAR_FLAG(F_IF); + CLEAR_FLAG(F_TF); + push_word(emu, 0); + push_word(emu, 0); + emu->x86.R_CS = (*emu->emu_rdw)(emu, intr * 4 + 2); + emu->x86.R_IP = (*emu->emu_rdw)(emu, intr * 4); + emu->x86.intr = 0; + + x86emu_exec(emu); +} + +/* + * REMARKS: + * Halts the system by setting the halted system flag. + */ +void +x86emu_halt_sys(struct x86emu *emu) +{ + longjmp(emu->exec_state, 1); +} + +/* + * PARAMETERS: + * mod - Mod value from decoded byte + * regh - Reg h value from decoded byte + * regl - Reg l value from decoded byte + * + * REMARKS: + * Raise the specified interrupt to be handled before the execution of the + * next instruction. + * + * NOTE: Do not inline this function, as (*emu->emu_rdb) is already inline! + */ +static void +fetch_decode_modrm(struct x86emu *emu) +{ + int fetched; + + fetched = fetch_byte_imm(emu); + emu->cur_mod = (fetched >> 6) & 0x03; + emu->cur_rh = (fetched >> 3) & 0x07; + emu->cur_rl = (fetched >> 0) & 0x07; +} + +/* + * RETURNS: + * Immediate byte value read from instruction queue + * + * REMARKS: + * This function returns the immediate byte from the instruction queue, and + * moves the instruction pointer to the next value. + * + * NOTE: Do not inline this function, as (*emu->emu_rdb) is already inline! + */ +static uint8_t +fetch_byte_imm(struct x86emu *emu) +{ + uint8_t fetched; + + fetched = fetch_byte(emu, emu->x86.R_CS, emu->x86.R_IP); + emu->x86.R_IP++; + return fetched; +} + +/* + * RETURNS: + * Immediate word value read from instruction queue + * + * REMARKS: + * This function returns the immediate byte from the instruction queue, and + * moves the instruction pointer to the next value. + * + * NOTE: Do not inline this function, as (*emu->emu_rdw) is already inline! + */ +static uint16_t +fetch_word_imm(struct x86emu *emu) +{ + uint16_t fetched; + + fetched = fetch_word(emu, emu->x86.R_CS, emu->x86.R_IP); + emu->x86.R_IP += 2; + return fetched; +} + +/* + * RETURNS: + * Immediate lone value read from instruction queue + * + * REMARKS: + * This function returns the immediate byte from the instruction queue, and + * moves the instruction pointer to the next value. + * + * NOTE: Do not inline this function, as (*emu->emu_rdw) is already inline! + */ +static uint32_t +fetch_long_imm(struct x86emu *emu) +{ + uint32_t fetched; + + fetched = fetch_long(emu, emu->x86.R_CS, emu->x86.R_IP); + emu->x86.R_IP += 4; + return fetched; +} + +/* + * RETURNS: + * Value of the default data segment + * + * REMARKS: + * Inline function that returns the default data segment for the current + * instruction. + * + * On the x86 processor, the default segment is not always DS if there is + * no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to + * addresses relative to SS (ie: on the stack). So, at the minimum, all + * decodings of addressing modes would have to set/clear a bit describing + * whether the access is relative to DS or SS. That is the function of the + * cpu-state-varible emu->x86.mode. There are several potential states: + * + * repe prefix seen (handled elsewhere) + * repne prefix seen (ditto) + * + * cs segment override + * ds segment override + * es segment override + * fs segment override + * gs segment override + * ss segment override + * + * ds/ss select (in absense of override) + * + * Each of the above 7 items are handled with a bit in the mode field. + */ +static uint32_t +get_data_segment(struct x86emu *emu) +{ + switch (emu->x86.mode & SYSMODE_SEGMASK) { + case 0: /* default case: use ds register */ + case SYSMODE_SEGOVR_DS: + case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS: + return emu->x86.R_DS; + case SYSMODE_SEG_DS_SS:/* non-overridden, use ss register */ + return emu->x86.R_SS; + case SYSMODE_SEGOVR_CS: + case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS: + return emu->x86.R_CS; + case SYSMODE_SEGOVR_ES: + case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS: + return emu->x86.R_ES; + case SYSMODE_SEGOVR_FS: + case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS: + return emu->x86.R_FS; + case SYSMODE_SEGOVR_GS: + case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS: + return emu->x86.R_GS; + case SYSMODE_SEGOVR_SS: + case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS: + return emu->x86.R_SS; + } + x86emu_halt_sys(emu); +} + +/* + * PARAMETERS: + * offset - Offset to load data from + * + * RETURNS: + * Byte value read from the absolute memory location. + * + * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline! + */ +static uint8_t +fetch_data_byte(struct x86emu *emu, uint32_t offset) +{ + return fetch_byte(emu, get_data_segment(emu), offset); +} + +/* + * PARAMETERS: + * offset - Offset to load data from + * + * RETURNS: + * Word value read from the absolute memory location. + * + * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline! + */ +static uint16_t +fetch_data_word(struct x86emu *emu, uint32_t offset) +{ + return fetch_word(emu, get_data_segment(emu), offset); +} + +/* + * PARAMETERS: + * offset - Offset to load data from + * + * RETURNS: + * Long value read from the absolute memory location. + * + * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline! + */ +static uint32_t +fetch_data_long(struct x86emu *emu, uint32_t offset) +{ + return fetch_long(emu, get_data_segment(emu), offset); +} + +/* + * PARAMETERS: + * segment - Segment to load data from + * offset - Offset to load data from + * + * RETURNS: + * Byte value read from the absolute memory location. + * + * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline! + */ +static uint8_t +fetch_byte(struct x86emu *emu, uint32_t segment, uint32_t offset) +{ + return (*emu->emu_rdb) (emu, ((uint32_t) segment << 4) + offset); +} + +/* + * PARAMETERS: + * segment - Segment to load data from + * offset - Offset to load data from + * + * RETURNS: + * Word value read from the absolute memory location. + * + * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline! + */ +static uint16_t +fetch_word(struct x86emu *emu, uint32_t segment, uint32_t offset) +{ + return (*emu->emu_rdw) (emu, ((uint32_t) segment << 4) + offset); +} + +/* + * PARAMETERS: + * segment - Segment to load data from + * offset - Offset to load data from + * + * RETURNS: + * Long value read from the absolute memory location. + * + * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline! + */ +static uint32_t +fetch_long(struct x86emu *emu, uint32_t segment, uint32_t offset) +{ + return (*emu->emu_rdl) (emu, ((uint32_t) segment << 4) + offset); +} + +/* + * PARAMETERS: + * offset - Offset to store data at + * val - Value to store + * + * REMARKS: + * Writes a word value to an segmented memory location. The segment used is + * the current 'default' segment, which may have been overridden. + * + * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline! + */ +static void +store_data_byte(struct x86emu *emu, uint32_t offset, uint8_t val) +{ + store_byte(emu, get_data_segment(emu), offset, val); +} + +/* + * PARAMETERS: + * offset - Offset to store data at + * val - Value to store + * + * REMARKS: + * Writes a word value to an segmented memory location. The segment used is + * the current 'default' segment, which may have been overridden. + * + * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline! + */ +static void +store_data_word(struct x86emu *emu, uint32_t offset, uint16_t val) +{ + store_word(emu, get_data_segment(emu), offset, val); +} + +/* + * PARAMETERS: + * offset - Offset to store data at + * val - Value to store + * + * REMARKS: + * Writes a long value to an segmented memory location. The segment used is + * the current 'default' segment, which may have been overridden. + * + * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline! + */ +static void +store_data_long(struct x86emu *emu, uint32_t offset, uint32_t val) +{ + store_long(emu, get_data_segment(emu), offset, val); +} + +/* + * PARAMETERS: + * segment - Segment to store data at + * offset - Offset to store data at + * val - Value to store + * + * REMARKS: + * Writes a byte value to an absolute memory location. + * + * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline! + */ +static void +store_byte(struct x86emu *emu, uint32_t segment, uint32_t offset, uint8_t val) +{ + (*emu->emu_wrb) (emu, ((uint32_t) segment << 4) + offset, val); +} + +/* + * PARAMETERS: + * segment - Segment to store data at + * offset - Offset to store data at + * val - Value to store + * + * REMARKS: + * Writes a word value to an absolute memory location. + * + * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline! + */ +static void +store_word(struct x86emu *emu, uint32_t segment, uint32_t offset, uint16_t val) +{ + (*emu->emu_wrw) (emu, ((uint32_t) segment << 4) + offset, val); +} + +/* + * PARAMETERS: + * segment - Segment to store data at + * offset - Offset to store data at + * val - Value to store + * + * REMARKS: + * Writes a long value to an absolute memory location. + * + * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline! + */ +static void +store_long(struct x86emu *emu, uint32_t segment, uint32_t offset, uint32_t val) +{ + (*emu->emu_wrl) (emu, ((uint32_t) segment << 4) + offset, val); +} + +/* + * PARAMETERS: + * reg - Register to decode + * + * RETURNS: + * Pointer to the appropriate register + * + * REMARKS: + * Return a pointer to the register given by the R/RM field of the + * modrm byte, for byte operands. Also enables the decoding of instructions. + */ +static uint8_t * +decode_rm_byte_register(struct x86emu *emu, int reg) +{ + switch (reg) { + case 0: + return &emu->x86.R_AL; + case 1: + return &emu->x86.R_CL; + case 2: + return &emu->x86.R_DL; + case 3: + return &emu->x86.R_BL; + case 4: + return &emu->x86.R_AH; + case 5: + return &emu->x86.R_CH; + case 6: + return &emu->x86.R_DH; + case 7: + return &emu->x86.R_BH; + default: + x86emu_halt_sys(emu); + } +} + +static uint8_t * +decode_rl_byte_register(struct x86emu *emu) +{ + return decode_rm_byte_register(emu, emu->cur_rl); +} + +static uint8_t * +decode_rh_byte_register(struct x86emu *emu) +{ + return decode_rm_byte_register(emu, emu->cur_rh); +} + +/* + * PARAMETERS: + * reg - Register to decode + * + * RETURNS: + * Pointer to the appropriate register + * + * REMARKS: + * Return a pointer to the register given by the R/RM field of the + * modrm byte, for word operands. Also enables the decoding of instructions. + */ +static uint16_t * +decode_rm_word_register(struct x86emu *emu, int reg) +{ + switch (reg) { + case 0: + return &emu->x86.R_AX; + case 1: + return &emu->x86.R_CX; + case 2: + return &emu->x86.R_DX; + case 3: + return &emu->x86.R_BX; + case 4: + return &emu->x86.R_SP; + case 5: + return &emu->x86.R_BP; + case 6: + return &emu->x86.R_SI; + case 7: + return &emu->x86.R_DI; + default: + x86emu_halt_sys(emu); + } +} + +static uint16_t * +decode_rl_word_register(struct x86emu *emu) +{ + return decode_rm_word_register(emu, emu->cur_rl); +} + +static uint16_t * +decode_rh_word_register(struct x86emu *emu) +{ + return decode_rm_word_register(emu, emu->cur_rh); +} + +/* + * PARAMETERS: + * reg - Register to decode + * + * RETURNS: + * Pointer to the appropriate register + * + * REMARKS: + * Return a pointer to the register given by the R/RM field of the + * modrm byte, for dword operands. Also enables the decoding of instructions. + */ +static uint32_t * +decode_rm_long_register(struct x86emu *emu, int reg) +{ + switch (reg) { + case 0: + return &emu->x86.R_EAX; + case 1: + return &emu->x86.R_ECX; + case 2: + return &emu->x86.R_EDX; + case 3: + return &emu->x86.R_EBX; + case 4: + return &emu->x86.R_ESP; + case 5: + return &emu->x86.R_EBP; + case 6: + return &emu->x86.R_ESI; + case 7: + return &emu->x86.R_EDI; + default: + x86emu_halt_sys(emu); + } +} + +static uint32_t * +decode_rl_long_register(struct x86emu *emu) +{ + return decode_rm_long_register(emu, emu->cur_rl); +} + +static uint32_t * +decode_rh_long_register(struct x86emu *emu) +{ + return decode_rm_long_register(emu, emu->cur_rh); +} + + +/* + * PARAMETERS: + * reg - Register to decode + * + * RETURNS: + * Pointer to the appropriate register + * + * REMARKS: + * Return a pointer to the register given by the R/RM field of the + * modrm byte, for word operands, modified from above for the weirdo + * special case of segreg operands. Also enables the decoding of instructions. + */ +static uint16_t * +decode_rh_seg_register(struct x86emu *emu) +{ + switch (emu->cur_rh) { + case 0: + return &emu->x86.R_ES; + case 1: + return &emu->x86.R_CS; + case 2: + return &emu->x86.R_SS; + case 3: + return &emu->x86.R_DS; + case 4: + return &emu->x86.R_FS; + case 5: + return &emu->x86.R_GS; + default: + x86emu_halt_sys(emu); + } +} +/* + * + * return offset from the SIB Byte + */ +static uint32_t +decode_sib_address(struct x86emu *emu, int sib, int mod) +{ + uint32_t base = 0, i = 0, scale = 1; + + switch (sib & 0x07) { + case 0: + base = emu->x86.R_EAX; + break; + case 1: + base = emu->x86.R_ECX; + + break; + case 2: + base = emu->x86.R_EDX; + break; + case 3: + base = emu->x86.R_EBX; + break; + case 4: + base = emu->x86.R_ESP; + emu->x86.mode |= SYSMODE_SEG_DS_SS; + break; + case 5: + if (mod == 0) { + base = fetch_long_imm(emu); + } else { + base = emu->x86.R_EBP; + emu->x86.mode |= SYSMODE_SEG_DS_SS; + } + break; + case 6: + base = emu->x86.R_ESI; + break; + case 7: + base = emu->x86.R_EDI; + break; + } + switch ((sib >> 3) & 0x07) { + case 0: + i = emu->x86.R_EAX; + break; + case 1: + i = emu->x86.R_ECX; + break; + case 2: + i = emu->x86.R_EDX; + break; + case 3: + i = emu->x86.R_EBX; + break; + case 4: + i = 0; + break; + case 5: + i = emu->x86.R_EBP; + break; + case 6: + i = emu->x86.R_ESI; + break; + case 7: + i = emu->x86.R_EDI; + break; + } + scale = 1 << ((sib >> 6) & 0x03); + return base + (i * scale); +} + +/* + * PARAMETERS: + * rm - RM value to decode + * + * RETURNS: + * Offset in memory for the address decoding + * + * REMARKS: + * Return the offset given by mod=00, mod=01 or mod=10 addressing. + * Also enables the decoding of instructions. + */ +static uint32_t +decode_rl_address(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_ADDR) { + uint32_t offset, sib; + /* 32-bit addressing */ + switch (emu->cur_rl) { + case 0: + offset = emu->x86.R_EAX; + break; + case 1: + offset = emu->x86.R_ECX; + break; + case 2: + offset = emu->x86.R_EDX; + break; + case 3: + offset = emu->x86.R_EBX; + break; + case 4: + sib = fetch_byte_imm(emu); + offset = decode_sib_address(emu, sib, 0); + break; + case 5: + if (emu->cur_mod == 0) { + offset = fetch_long_imm(emu); + } else { + emu->x86.mode |= SYSMODE_SEG_DS_SS; + offset = emu->x86.R_EBP; + } + break; + case 6: + offset = emu->x86.R_ESI; + break; + case 7: + offset = emu->x86.R_EDI; + break; + default: + x86emu_halt_sys(emu); + } + if (emu->cur_mod == 1) + offset += (int8_t)fetch_byte_imm(emu); + else if (emu->cur_mod == 2) + offset += fetch_long_imm(emu); + return offset; + } else { + uint16_t offset; + + /* 16-bit addressing */ + switch (emu->cur_rl) { + case 0: + offset = emu->x86.R_BX + emu->x86.R_SI; + break; + case 1: + offset = emu->x86.R_BX + emu->x86.R_DI; + break; + case 2: + emu->x86.mode |= SYSMODE_SEG_DS_SS; + offset = emu->x86.R_BP + emu->x86.R_SI; + break; + case 3: + emu->x86.mode |= SYSMODE_SEG_DS_SS; + offset = emu->x86.R_BP + emu->x86.R_DI; + break; + case 4: + offset = emu->x86.R_SI; + break; + case 5: + offset = emu->x86.R_DI; + break; + case 6: + if (emu->cur_mod == 0) { + offset = fetch_word_imm(emu); + } else { + emu->x86.mode |= SYSMODE_SEG_DS_SS; + offset = emu->x86.R_BP; + } + break; + case 7: + offset = emu->x86.R_BX; + break; + default: + x86emu_halt_sys(emu); + } + if (emu->cur_mod == 1) + offset += (int8_t)fetch_byte_imm(emu); + else if (emu->cur_mod == 2) + offset += fetch_word_imm(emu); + return offset; + } +} + +static uint8_t +decode_and_fetch_byte(struct x86emu *emu) +{ + if (emu->cur_mod != 3) { + emu->cur_offset = decode_rl_address(emu); + return fetch_data_byte(emu, emu->cur_offset); + } else { + return *decode_rl_byte_register(emu); + } +} + +static uint16_t +decode_and_fetch_word_disp(struct x86emu *emu, int16_t disp) +{ + if (emu->cur_mod != 3) { + /* TODO: A20 gate emulation */ + emu->cur_offset = decode_rl_address(emu) + disp; + if ((emu->x86.mode & SYSMODE_PREFIX_ADDR) == 0) + emu->cur_offset &= 0xffff; + return fetch_data_word(emu, emu->cur_offset); + } else { + return *decode_rl_word_register(emu); + } +} + +static uint32_t +decode_and_fetch_long_disp(struct x86emu *emu, int16_t disp) +{ + if (emu->cur_mod != 3) { + /* TODO: A20 gate emulation */ + emu->cur_offset = decode_rl_address(emu) + disp; + if ((emu->x86.mode & SYSMODE_PREFIX_ADDR) == 0) + emu->cur_offset &= 0xffff; + return fetch_data_long(emu, emu->cur_offset); + } else { + return *decode_rl_long_register(emu); + } +} + +uint16_t +decode_and_fetch_word(struct x86emu *emu) +{ + return decode_and_fetch_word_disp(emu, 0); +} + +uint32_t +decode_and_fetch_long(struct x86emu *emu) +{ + return decode_and_fetch_long_disp(emu, 0); +} + +uint8_t +decode_and_fetch_byte_imm8(struct x86emu *emu, uint8_t *imm) +{ + if (emu->cur_mod != 3) { + emu->cur_offset = decode_rl_address(emu); + *imm = fetch_byte_imm(emu); + return fetch_data_byte(emu, emu->cur_offset); + } else { + *imm = fetch_byte_imm(emu); + return *decode_rl_byte_register(emu); + } +} + +static uint16_t +decode_and_fetch_word_imm8(struct x86emu *emu, uint8_t *imm) +{ + if (emu->cur_mod != 3) { + emu->cur_offset = decode_rl_address(emu); + *imm = fetch_byte_imm(emu); + return fetch_data_word(emu, emu->cur_offset); + } else { + *imm = fetch_byte_imm(emu); + return *decode_rl_word_register(emu); + } +} + +static uint32_t +decode_and_fetch_long_imm8(struct x86emu *emu, uint8_t *imm) +{ + if (emu->cur_mod != 3) { + emu->cur_offset = decode_rl_address(emu); + *imm = fetch_byte_imm(emu); + return fetch_data_long(emu, emu->cur_offset); + } else { + *imm = fetch_byte_imm(emu); + return *decode_rl_long_register(emu); + } +} + +static void +write_back_byte(struct x86emu *emu, uint8_t val) +{ + if (emu->cur_mod != 3) + store_data_byte(emu, emu->cur_offset, val); + else + *decode_rl_byte_register(emu) = val; +} + +static void +write_back_word(struct x86emu *emu, uint16_t val) +{ + if (emu->cur_mod != 3) + store_data_word(emu, emu->cur_offset, val); + else + *decode_rl_word_register(emu) = val; +} + +static void +write_back_long(struct x86emu *emu, uint32_t val) +{ + if (emu->cur_mod != 3) + store_data_long(emu, emu->cur_offset, val); + else + *decode_rl_long_register(emu) = val; +} + +static void +common_inc_word_long(struct x86emu *emu, union x86emu_register *reg) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + reg->I32_reg.e_reg = inc_long(emu, reg->I32_reg.e_reg); + else + reg->I16_reg.x_reg = inc_word(emu, reg->I16_reg.x_reg); +} + +static void +common_dec_word_long(struct x86emu *emu, union x86emu_register *reg) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + reg->I32_reg.e_reg = dec_long(emu, reg->I32_reg.e_reg); + else + reg->I16_reg.x_reg = dec_word(emu, reg->I16_reg.x_reg); +} + +static void +common_binop_byte_rm_r(struct x86emu *emu, uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t)) +{ + uint32_t destoffset; + uint8_t *destreg, srcval; + uint8_t destval; + + fetch_decode_modrm(emu); + srcval = *decode_rh_byte_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = fetch_data_byte(emu, destoffset); + destval = (*binop)(emu, destval, srcval); + store_data_byte(emu, destoffset, destval); + } else { + destreg = decode_rl_byte_register(emu); + *destreg = (*binop)(emu, *destreg, srcval); + } +} + +static void +common_binop_ns_byte_rm_r(struct x86emu *emu, void (*binop)(struct x86emu *, uint8_t, uint8_t)) +{ + uint32_t destoffset; + uint8_t destval, srcval; + + fetch_decode_modrm(emu); + srcval = *decode_rh_byte_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = fetch_data_byte(emu, destoffset); + } else { + destval = *decode_rl_byte_register(emu); + } + (*binop)(emu, destval, srcval); +} + +static void +common_binop_word_rm_r(struct x86emu *emu, uint16_t (*binop)(struct x86emu *, uint16_t, uint16_t)) +{ + uint32_t destoffset; + uint16_t destval, *destreg, srcval; + + fetch_decode_modrm(emu); + srcval = *decode_rh_word_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = fetch_data_word(emu, destoffset); + destval = (*binop)(emu, destval, srcval); + store_data_word(emu, destoffset, destval); + } else { + destreg = decode_rl_word_register(emu); + *destreg = (*binop)(emu, *destreg, srcval); + } +} + +static void +common_binop_byte_r_rm(struct x86emu *emu, uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t)) +{ + uint8_t *destreg, srcval; + uint32_t srcoffset; + + fetch_decode_modrm(emu); + destreg = decode_rh_byte_register(emu); + if (emu->cur_mod != 3) { + srcoffset = decode_rl_address(emu); + srcval = fetch_data_byte(emu, srcoffset); + } else { + srcval = *decode_rl_byte_register(emu); + } + *destreg = (*binop)(emu, *destreg, srcval); +} + +static void +common_binop_long_rm_r(struct x86emu *emu, uint32_t (*binop)(struct x86emu *, uint32_t, uint32_t)) +{ + uint32_t destoffset; + uint32_t destval, *destreg, srcval; + + fetch_decode_modrm(emu); + srcval = *decode_rh_long_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = fetch_data_long(emu, destoffset); + destval = (*binop)(emu, destval, srcval); + store_data_long(emu, destoffset, destval); + } else { + destreg = decode_rl_long_register(emu); + *destreg = (*binop)(emu, *destreg, srcval); + } +} + +static void +common_binop_word_long_rm_r(struct x86emu *emu, + uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t), uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t)) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + common_binop_long_rm_r(emu, binop32); + else + common_binop_word_rm_r(emu, binop16); +} + +static void +common_binop_ns_word_rm_r(struct x86emu *emu, void (*binop)(struct x86emu *, uint16_t, uint16_t)) +{ + uint32_t destoffset; + uint16_t destval, srcval; + + fetch_decode_modrm(emu); + srcval = *decode_rh_word_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = fetch_data_word(emu, destoffset); + } else { + destval = *decode_rl_word_register(emu); + } + (*binop)(emu, destval, srcval); +} + + +static void +common_binop_ns_long_rm_r(struct x86emu *emu, void (*binop)(struct x86emu *, uint32_t, uint32_t)) +{ + uint32_t destoffset; + uint32_t destval, srcval; + + fetch_decode_modrm(emu); + srcval = *decode_rh_long_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = fetch_data_long(emu, destoffset); + } else { + destval = *decode_rl_long_register(emu); + } + (*binop)(emu, destval, srcval); +} + +static void +common_binop_ns_word_long_rm_r(struct x86emu *emu, + void (*binop16)(struct x86emu *, uint16_t, uint16_t), void (*binop32)(struct x86emu *, uint32_t, uint32_t)) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + common_binop_ns_long_rm_r(emu, binop32); + else + common_binop_ns_word_rm_r(emu, binop16); +} + +static void +common_binop_long_r_rm(struct x86emu *emu, uint32_t (*binop)(struct x86emu *, uint32_t, uint32_t)) +{ + uint32_t srcoffset; + uint32_t *destreg, srcval; + + fetch_decode_modrm(emu); + destreg = decode_rh_long_register(emu); + if (emu->cur_mod != 3) { + srcoffset = decode_rl_address(emu); + srcval = fetch_data_long(emu, srcoffset); + } else { + srcval = *decode_rl_long_register(emu); + } + *destreg = (*binop)(emu, *destreg, srcval); +} + +static void +common_binop_word_r_rm(struct x86emu *emu, uint16_t (*binop)(struct x86emu *, uint16_t, uint16_t)) +{ + uint32_t srcoffset; + uint16_t *destreg, srcval; + + fetch_decode_modrm(emu); + destreg = decode_rh_word_register(emu); + if (emu->cur_mod != 3) { + srcoffset = decode_rl_address(emu); + srcval = fetch_data_word(emu, srcoffset); + } else { + srcval = *decode_rl_word_register(emu); + } + *destreg = (*binop)(emu, *destreg, srcval); +} + +static void +common_binop_word_long_r_rm(struct x86emu *emu, + uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t), uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t)) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + common_binop_long_r_rm(emu, binop32); + else + common_binop_word_r_rm(emu, binop16); +} + +static void +common_binop_byte_imm(struct x86emu *emu, uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t)) +{ + uint8_t srcval; + + srcval = fetch_byte_imm(emu); + emu->x86.R_AL = (*binop)(emu, emu->x86.R_AL, srcval); +} + +static void +common_binop_word_long_imm(struct x86emu *emu, + uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t), uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t)) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + uint32_t srcval; + + srcval = fetch_long_imm(emu); + emu->x86.R_EAX = (*binop32)(emu, emu->x86.R_EAX, srcval); + } else { + uint16_t srcval; + + srcval = fetch_word_imm(emu); + emu->x86.R_AX = (*binop16)(emu, emu->x86.R_AX, srcval); + } +} + +static void +common_push_word_long(struct x86emu *emu, union x86emu_register *reg) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + push_long(emu, reg->I32_reg.e_reg); + else + push_word(emu, reg->I16_reg.x_reg); +} + +static void +common_pop_word_long(struct x86emu *emu, union x86emu_register *reg) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + reg->I32_reg.e_reg = pop_long(emu); + else + reg->I16_reg.x_reg = pop_word(emu); +} + +static void +common_imul_long_IMM(struct x86emu *emu, int byte_imm) +{ + uint32_t srcoffset; + uint32_t *destreg, srcval; + int32_t imm; + uint64_t res; + + fetch_decode_modrm(emu); + destreg = decode_rh_long_register(emu); + if (emu->cur_mod != 3) { + srcoffset = decode_rl_address(emu); + srcval = fetch_data_long(emu, srcoffset); + } else { + srcval = *decode_rl_long_register(emu); + } + + if (byte_imm) + imm = (int8_t)fetch_byte_imm(emu); + else + imm = fetch_long_imm(emu); + res = (int32_t)srcval * imm; + + if (res > 0xffffffff) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (uint32_t)res; +} + +static void +common_imul_word_IMM(struct x86emu *emu, int byte_imm) +{ + uint32_t srcoffset; + uint16_t *destreg, srcval; + int16_t imm; + uint32_t res; + + fetch_decode_modrm(emu); + destreg = decode_rh_word_register(emu); + if (emu->cur_mod != 3) { + srcoffset = decode_rl_address(emu); + srcval = fetch_data_word(emu, srcoffset); + } else { + srcval = *decode_rl_word_register(emu); + } + + if (byte_imm) + imm = (int8_t)fetch_byte_imm(emu); + else + imm = fetch_word_imm(emu); + res = (int16_t)srcval * imm; + + if (res > 0xffff) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (uint16_t) res; +} + +static void +common_imul_imm(struct x86emu *emu, int byte_imm) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + common_imul_long_IMM(emu, byte_imm); + else + common_imul_word_IMM(emu, byte_imm); +} + +static void +common_jmp_near(struct x86emu *emu, int cond) +{ + int8_t offset; + uint16_t target; + + offset = (int8_t) fetch_byte_imm(emu); + target = (uint16_t) (emu->x86.R_IP + (int16_t) offset); + if (cond) + emu->x86.R_IP = target; +} + +static void +common_load_far_pointer(struct x86emu *emu, uint16_t *seg) +{ + uint16_t *dstreg; + uint32_t srcoffset; + + fetch_decode_modrm(emu); + if (emu->cur_mod == 3) + x86emu_halt_sys(emu); + + dstreg = decode_rh_word_register(emu); + srcoffset = decode_rl_address(emu); + *dstreg = fetch_data_word(emu, srcoffset); + *seg = fetch_data_word(emu, srcoffset + 2); +} + +/* Implementation */ + +/* + * REMARKS: + * Handles opcode 0x3a + */ +static void +x86emuOp_cmp_byte_R_RM(struct x86emu *emu) +{ + uint8_t *destreg, srcval; + + fetch_decode_modrm(emu); + destreg = decode_rh_byte_register(emu); + srcval = decode_and_fetch_byte(emu); + cmp_byte(emu, *destreg, srcval); +} + +/* + * REMARKS: + * + * Handles opcode 0x3b + */ +static void +x86emuOp32_cmp_word_R_RM(struct x86emu *emu) +{ + uint32_t srcval, *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_long_register(emu); + srcval = decode_and_fetch_long(emu); + cmp_long(emu, *destreg, srcval); +} + +static void +x86emuOp16_cmp_word_R_RM(struct x86emu *emu) +{ + uint16_t srcval, *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_word_register(emu); + srcval = decode_and_fetch_word(emu); + cmp_word(emu, *destreg, srcval); +} + +static void +x86emuOp_cmp_word_R_RM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_cmp_word_R_RM(emu); + else + x86emuOp16_cmp_word_R_RM(emu); +} + +/* + * REMARKS: + * Handles opcode 0x3c + */ +static void +x86emuOp_cmp_byte_AL_IMM(struct x86emu *emu) +{ + uint8_t srcval; + + srcval = fetch_byte_imm(emu); + cmp_byte(emu, emu->x86.R_AL, srcval); +} + +/* + * REMARKS: + * Handles opcode 0x3d + */ +static void +x86emuOp32_cmp_word_AX_IMM(struct x86emu *emu) +{ + uint32_t srcval; + + srcval = fetch_long_imm(emu); + cmp_long(emu, emu->x86.R_EAX, srcval); +} + +static void +x86emuOp16_cmp_word_AX_IMM(struct x86emu *emu) +{ + uint16_t srcval; + + srcval = fetch_word_imm(emu); + cmp_word(emu, emu->x86.R_AX, srcval); +} + +static void +x86emuOp_cmp_word_AX_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_cmp_word_AX_IMM(emu); + else + x86emuOp16_cmp_word_AX_IMM(emu); +} + +/* + * REMARKS: + * Handles opcode 0x60 + */ +static void +x86emuOp_push_all(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + uint32_t old_sp = emu->x86.R_ESP; + + push_long(emu, emu->x86.R_EAX); + push_long(emu, emu->x86.R_ECX); + push_long(emu, emu->x86.R_EDX); + push_long(emu, emu->x86.R_EBX); + push_long(emu, old_sp); + push_long(emu, emu->x86.R_EBP); + push_long(emu, emu->x86.R_ESI); + push_long(emu, emu->x86.R_EDI); + } else { + uint16_t old_sp = emu->x86.R_SP; + + push_word(emu, emu->x86.R_AX); + push_word(emu, emu->x86.R_CX); + push_word(emu, emu->x86.R_DX); + push_word(emu, emu->x86.R_BX); + push_word(emu, old_sp); + push_word(emu, emu->x86.R_BP); + push_word(emu, emu->x86.R_SI); + push_word(emu, emu->x86.R_DI); + } +} + +/* + * REMARKS: + * Handles opcode 0x61 + */ +static void +x86emuOp_pop_all(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + emu->x86.R_EDI = pop_long(emu); + emu->x86.R_ESI = pop_long(emu); + emu->x86.R_EBP = pop_long(emu); + emu->x86.R_ESP += 4; /* skip ESP */ + emu->x86.R_EBX = pop_long(emu); + emu->x86.R_EDX = pop_long(emu); + emu->x86.R_ECX = pop_long(emu); + emu->x86.R_EAX = pop_long(emu); + } else { + emu->x86.R_DI = pop_word(emu); + emu->x86.R_SI = pop_word(emu); + emu->x86.R_BP = pop_word(emu); + emu->x86.R_SP += 2;/* skip SP */ + emu->x86.R_BX = pop_word(emu); + emu->x86.R_DX = pop_word(emu); + emu->x86.R_CX = pop_word(emu); + emu->x86.R_AX = pop_word(emu); + } +} +/*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */ +/*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */ + + +/* + * REMARKS: + * Handles opcode 0x68 + */ +static void +x86emuOp_push_word_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + uint32_t imm; + + imm = fetch_long_imm(emu); + push_long(emu, imm); + } else { + uint16_t imm; + + imm = fetch_word_imm(emu); + push_word(emu, imm); + } +} + +/* + * REMARKS: + * Handles opcode 0x6a + */ +static void +x86emuOp_push_byte_IMM(struct x86emu *emu) +{ + int16_t imm; + + imm = (int8_t) fetch_byte_imm(emu); + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + push_long(emu, (int32_t) imm); + } else { + push_word(emu, imm); + } +} + +/* + * REMARKS: + * Handles opcode 0x6c and 0x6d + */ +static void +x86emuOp_ins_word(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + ins(emu, 4); + } else { + ins(emu, 2); + } +} + +/* + * REMARKS: + * Handles opcode 0x6f + */ +static void +x86emuOp_outs_word(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + outs(emu, 4); + } else { + outs(emu, 2); + } +} + +/* + * REMARKS: + * Handles opcode 0x7c + */ +static void +x86emuOp_jump_near_L(struct x86emu *emu) +{ + int sf, of; + + sf = ACCESS_FLAG(F_SF) != 0; + of = ACCESS_FLAG(F_OF) != 0; + + common_jmp_near(emu, sf != of); +} + +/* + * REMARKS: + * Handles opcode 0x7d + */ +static void +x86emuOp_jump_near_NL(struct x86emu *emu) +{ + int sf, of; + + sf = ACCESS_FLAG(F_SF) != 0; + of = ACCESS_FLAG(F_OF) != 0; + + common_jmp_near(emu, sf == of); +} + +/* + * REMARKS: + * Handles opcode 0x7e + */ +static void +x86emuOp_jump_near_LE(struct x86emu *emu) +{ + int sf, of; + + sf = ACCESS_FLAG(F_SF) != 0; + of = ACCESS_FLAG(F_OF) != 0; + + common_jmp_near(emu, sf != of || ACCESS_FLAG(F_ZF)); +} + +/* + * REMARKS: + * Handles opcode 0x7f + */ +static void +x86emuOp_jump_near_NLE(struct x86emu *emu) +{ + int sf, of; + + sf = ACCESS_FLAG(F_SF) != 0; + of = ACCESS_FLAG(F_OF) != 0; + + common_jmp_near(emu, sf == of && !ACCESS_FLAG(F_ZF)); +} + +static +uint8_t(*const opc80_byte_operation[]) (struct x86emu *, uint8_t d, uint8_t s) = +{ + add_byte, /* 00 */ + or_byte, /* 01 */ + adc_byte, /* 02 */ + sbb_byte, /* 03 */ + and_byte, /* 04 */ + sub_byte, /* 05 */ + xor_byte, /* 06 */ + cmp_byte, /* 07 */ +}; + +/* + * REMARKS: + * Handles opcode 0x80 + */ +static void +x86emuOp_opc80_byte_RM_IMM(struct x86emu *emu) +{ + uint8_t imm, destval; + + /* + * Weirdo special case instruction format. Part of the opcode + * held below in "RH". Doubly nested case would result, except + * that the decoded instruction + */ + fetch_decode_modrm(emu); + destval = decode_and_fetch_byte(emu); + imm = fetch_byte_imm(emu); + destval = (*opc80_byte_operation[emu->cur_rh]) (emu, destval, imm); + if (emu->cur_rh != 7) + write_back_byte(emu, destval); +} + +static +uint16_t(* const opc81_word_operation[]) (struct x86emu *, uint16_t d, uint16_t s) = +{ + add_word, /* 00 */ + or_word, /* 01 */ + adc_word, /* 02 */ + sbb_word, /* 03 */ + and_word, /* 04 */ + sub_word, /* 05 */ + xor_word, /* 06 */ + cmp_word, /* 07 */ +}; + +static +uint32_t(* const opc81_long_operation[]) (struct x86emu *, uint32_t d, uint32_t s) = +{ + add_long, /* 00 */ + or_long, /* 01 */ + adc_long, /* 02 */ + sbb_long, /* 03 */ + and_long, /* 04 */ + sub_long, /* 05 */ + xor_long, /* 06 */ + cmp_long, /* 07 */ +}; + +/* + * REMARKS: + * Handles opcode 0x81 + */ +static void +x86emuOp32_opc81_word_RM_IMM(struct x86emu *emu) +{ + uint32_t destval, imm; + + /* + * Weirdo special case instruction format. Part of the opcode + * held below in "RH". Doubly nested case would result, except + * that the decoded instruction + */ + fetch_decode_modrm(emu); + destval = decode_and_fetch_long(emu); + imm = fetch_long_imm(emu); + destval = (*opc81_long_operation[emu->cur_rh]) (emu, destval, imm); + if (emu->cur_rh != 7) + write_back_long(emu, destval); +} + +static void +x86emuOp16_opc81_word_RM_IMM(struct x86emu *emu) +{ + uint16_t destval, imm; + + /* + * Weirdo special case instruction format. Part of the opcode + * held below in "RH". Doubly nested case would result, except + * that the decoded instruction + */ + fetch_decode_modrm(emu); + destval = decode_and_fetch_word(emu); + imm = fetch_word_imm(emu); + destval = (*opc81_word_operation[emu->cur_rh]) (emu, destval, imm); + if (emu->cur_rh != 7) + write_back_word(emu, destval); +} + +static void +x86emuOp_opc81_word_RM_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_opc81_word_RM_IMM(emu); + else + x86emuOp16_opc81_word_RM_IMM(emu); +} + +static +uint8_t(* const opc82_byte_operation[]) (struct x86emu *, uint8_t s, uint8_t d) = +{ + add_byte, /* 00 */ + or_byte, /* 01 *//* YYY UNUSED ???? */ + adc_byte, /* 02 */ + sbb_byte, /* 03 */ + and_byte, /* 04 *//* YYY UNUSED ???? */ + sub_byte, /* 05 */ + xor_byte, /* 06 *//* YYY UNUSED ???? */ + cmp_byte, /* 07 */ +}; + +/* + * REMARKS: + * Handles opcode 0x82 + */ +static void +x86emuOp_opc82_byte_RM_IMM(struct x86emu *emu) +{ + uint8_t imm, destval; + + /* + * Weirdo special case instruction format. Part of the opcode + * held below in "RH". Doubly nested case would result, except + * that the decoded instruction Similar to opcode 81, except that + * the immediate byte is sign extended to a word length. + */ + fetch_decode_modrm(emu); + destval = decode_and_fetch_byte(emu); + imm = fetch_byte_imm(emu); + destval = (*opc82_byte_operation[emu->cur_rh]) (emu, destval, imm); + if (emu->cur_rh != 7) + write_back_byte(emu, destval); +} + +static +uint16_t(* const opc83_word_operation[]) (struct x86emu *, uint16_t s, uint16_t d) = +{ + add_word, /* 00 */ + or_word, /* 01 *//* YYY UNUSED ???? */ + adc_word, /* 02 */ + sbb_word, /* 03 */ + and_word, /* 04 *//* YYY UNUSED ???? */ + sub_word, /* 05 */ + xor_word, /* 06 *//* YYY UNUSED ???? */ + cmp_word, /* 07 */ +}; + +static +uint32_t(* const opc83_long_operation[]) (struct x86emu *, uint32_t s, uint32_t d) = +{ + add_long, /* 00 */ + or_long, /* 01 *//* YYY UNUSED ???? */ + adc_long, /* 02 */ + sbb_long, /* 03 */ + and_long, /* 04 *//* YYY UNUSED ???? */ + sub_long, /* 05 */ + xor_long, /* 06 *//* YYY UNUSED ???? */ + cmp_long, /* 07 */ +}; + +/* + * REMARKS: + * Handles opcode 0x83 + */ +static void +x86emuOp32_opc83_word_RM_IMM(struct x86emu *emu) +{ + uint32_t destval, imm; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_long(emu); + imm = (int8_t) fetch_byte_imm(emu); + destval = (*opc83_long_operation[emu->cur_rh]) (emu, destval, imm); + if (emu->cur_rh != 7) + write_back_long(emu, destval); +} + +static void +x86emuOp16_opc83_word_RM_IMM(struct x86emu *emu) +{ + uint16_t destval, imm; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_word(emu); + imm = (int8_t) fetch_byte_imm(emu); + destval = (*opc83_word_operation[emu->cur_rh]) (emu, destval, imm); + if (emu->cur_rh != 7) + write_back_word(emu, destval); +} + +static void +x86emuOp_opc83_word_RM_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_opc83_word_RM_IMM(emu); + else + x86emuOp16_opc83_word_RM_IMM(emu); +} + +/* + * REMARKS: + * Handles opcode 0x86 + */ +static void +x86emuOp_xchg_byte_RM_R(struct x86emu *emu) +{ + uint8_t *srcreg, destval, tmp; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_byte(emu); + srcreg = decode_rh_byte_register(emu); + tmp = destval; + destval = *srcreg; + *srcreg = tmp; + write_back_byte(emu, destval); +} + +/* + * REMARKS: + * Handles opcode 0x87 + */ +static void +x86emuOp32_xchg_word_RM_R(struct x86emu *emu) +{ + uint32_t *srcreg, destval, tmp; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_long(emu); + srcreg = decode_rh_long_register(emu); + tmp = destval; + destval = *srcreg; + *srcreg = tmp; + write_back_long(emu, destval); +} + +static void +x86emuOp16_xchg_word_RM_R(struct x86emu *emu) +{ + uint16_t *srcreg, destval, tmp; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_word(emu); + srcreg = decode_rh_word_register(emu); + tmp = destval; + destval = *srcreg; + *srcreg = tmp; + write_back_word(emu, destval); +} + +static void +x86emuOp_xchg_word_RM_R(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_xchg_word_RM_R(emu); + else + x86emuOp16_xchg_word_RM_R(emu); +} + +/* + * REMARKS: + * Handles opcode 0x88 + */ +static void +x86emuOp_mov_byte_RM_R(struct x86emu *emu) +{ + uint8_t *destreg, *srcreg; + uint32_t destoffset; + + fetch_decode_modrm(emu); + srcreg = decode_rh_byte_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + store_data_byte(emu, destoffset, *srcreg); + } else { + destreg = decode_rl_byte_register(emu); + *destreg = *srcreg; + } +} + +/* + * REMARKS: + * Handles opcode 0x89 + */ +static void +x86emuOp32_mov_word_RM_R(struct x86emu *emu) +{ + uint32_t destoffset; + uint32_t *destreg, srcval; + + fetch_decode_modrm(emu); + srcval = *decode_rh_long_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + store_data_long(emu, destoffset, srcval); + } else { + destreg = decode_rl_long_register(emu); + *destreg = srcval; + } +} + +static void +x86emuOp16_mov_word_RM_R(struct x86emu *emu) +{ + uint32_t destoffset; + uint16_t *destreg, srcval; + + fetch_decode_modrm(emu); + srcval = *decode_rh_word_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + store_data_word(emu, destoffset, srcval); + } else { + destreg = decode_rl_word_register(emu); + *destreg = srcval; + } +} + +static void +x86emuOp_mov_word_RM_R(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_mov_word_RM_R(emu); + else + x86emuOp16_mov_word_RM_R(emu); +} + +/* + * REMARKS: + * Handles opcode 0x8a + */ +static void +x86emuOp_mov_byte_R_RM(struct x86emu *emu) +{ + uint8_t *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_byte_register(emu); + *destreg = decode_and_fetch_byte(emu); +} + +/* + * REMARKS: + * Handles opcode 0x8b + */ +static void +x86emuOp_mov_word_R_RM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + uint32_t *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_long_register(emu); + *destreg = decode_and_fetch_long(emu); + } else { + uint16_t *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_word_register(emu); + *destreg = decode_and_fetch_word(emu); + } +} + +/* + * REMARKS: + * Handles opcode 0x8c + */ +static void +x86emuOp_mov_word_RM_SR(struct x86emu *emu) +{ + uint16_t *destreg, srcval; + uint32_t destoffset; + + fetch_decode_modrm(emu); + srcval = *decode_rh_seg_register(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + store_data_word(emu, destoffset, srcval); + } else { + destreg = decode_rl_word_register(emu); + *destreg = srcval; + } +} + +/* + * REMARKS: + * Handles opcode 0x8d + */ +static void +x86emuOp_lea_word_R_M(struct x86emu *emu) +{ + uint16_t *srcreg; + uint32_t destoffset; + +/* + * TODO: Need to handle address size prefix! + * + * lea eax,[eax+ebx*2] ?? + */ + fetch_decode_modrm(emu); + if (emu->cur_mod == 3) + x86emu_halt_sys(emu); + + srcreg = decode_rh_word_register(emu); + destoffset = decode_rl_address(emu); + *srcreg = (uint16_t) destoffset; +} + +/* + * REMARKS: + * Handles opcode 0x8e + */ +static void +x86emuOp_mov_word_SR_RM(struct x86emu *emu) +{ + uint16_t *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_seg_register(emu); + *destreg = decode_and_fetch_word(emu); + /* + * Clean up, and reset all the R_xSP pointers to the correct + * locations. This is about 3x too much overhead (doing all the + * segreg ptrs when only one is needed, but this instruction + * *cannot* be that common, and this isn't too much work anyway. + */ +} + +/* + * REMARKS: + * Handles opcode 0x8f + */ +static void +x86emuOp32_pop_RM(struct x86emu *emu) +{ + uint32_t destoffset; + uint32_t destval, *destreg; + + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = pop_long(emu); + store_data_long(emu, destoffset, destval); + } else { + destreg = decode_rl_long_register(emu); + *destreg = pop_long(emu); + } +} + +static void +x86emuOp16_pop_RM(struct x86emu *emu) +{ + uint32_t destoffset; + uint16_t destval, *destreg; + + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = pop_word(emu); + store_data_word(emu, destoffset, destval); + } else { + destreg = decode_rl_word_register(emu); + *destreg = pop_word(emu); + } +} + +static void +x86emuOp_pop_RM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_pop_RM(emu); + else + x86emuOp16_pop_RM(emu); +} + +/* + * REMARKS: + * Handles opcode 0x91 + */ +static void +x86emuOp_xchg_word_AX_CX(struct x86emu *emu) +{ + uint32_t tmp; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + tmp = emu->x86.R_EAX; + emu->x86.R_EAX = emu->x86.R_ECX; + emu->x86.R_ECX = tmp; + } else { + tmp = emu->x86.R_AX; + emu->x86.R_AX = emu->x86.R_CX; + emu->x86.R_CX = (uint16_t) tmp; + } +} + +/* + * REMARKS: + * Handles opcode 0x92 + */ +static void +x86emuOp_xchg_word_AX_DX(struct x86emu *emu) +{ + uint32_t tmp; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + tmp = emu->x86.R_EAX; + emu->x86.R_EAX = emu->x86.R_EDX; + emu->x86.R_EDX = tmp; + } else { + tmp = emu->x86.R_AX; + emu->x86.R_AX = emu->x86.R_DX; + emu->x86.R_DX = (uint16_t) tmp; + } +} + +/* + * REMARKS: + * Handles opcode 0x93 + */ +static void +x86emuOp_xchg_word_AX_BX(struct x86emu *emu) +{ + uint32_t tmp; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + tmp = emu->x86.R_EAX; + emu->x86.R_EAX = emu->x86.R_EBX; + emu->x86.R_EBX = tmp; + } else { + tmp = emu->x86.R_AX; + emu->x86.R_AX = emu->x86.R_BX; + emu->x86.R_BX = (uint16_t) tmp; + } +} + +/* + * REMARKS: + * Handles opcode 0x94 + */ +static void +x86emuOp_xchg_word_AX_SP(struct x86emu *emu) +{ + uint32_t tmp; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + tmp = emu->x86.R_EAX; + emu->x86.R_EAX = emu->x86.R_ESP; + emu->x86.R_ESP = tmp; + } else { + tmp = emu->x86.R_AX; + emu->x86.R_AX = emu->x86.R_SP; + emu->x86.R_SP = (uint16_t) tmp; + } +} + +/* + * REMARKS: + * Handles opcode 0x95 + */ +static void +x86emuOp_xchg_word_AX_BP(struct x86emu *emu) +{ + uint32_t tmp; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + tmp = emu->x86.R_EAX; + emu->x86.R_EAX = emu->x86.R_EBP; + emu->x86.R_EBP = tmp; + } else { + tmp = emu->x86.R_AX; + emu->x86.R_AX = emu->x86.R_BP; + emu->x86.R_BP = (uint16_t) tmp; + } +} + +/* + * REMARKS: + * Handles opcode 0x96 + */ +static void +x86emuOp_xchg_word_AX_SI(struct x86emu *emu) +{ + uint32_t tmp; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + tmp = emu->x86.R_EAX; + emu->x86.R_EAX = emu->x86.R_ESI; + emu->x86.R_ESI = tmp; + } else { + tmp = emu->x86.R_AX; + emu->x86.R_AX = emu->x86.R_SI; + emu->x86.R_SI = (uint16_t) tmp; + } +} + +/* + * REMARKS: + * Handles opcode 0x97 + */ +static void +x86emuOp_xchg_word_AX_DI(struct x86emu *emu) +{ + uint32_t tmp; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + tmp = emu->x86.R_EAX; + emu->x86.R_EAX = emu->x86.R_EDI; + emu->x86.R_EDI = tmp; + } else { + tmp = emu->x86.R_AX; + emu->x86.R_AX = emu->x86.R_DI; + emu->x86.R_DI = (uint16_t) tmp; + } +} + +/* + * REMARKS: + * Handles opcode 0x98 + */ +static void +x86emuOp_cbw(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + if (emu->x86.R_AX & 0x8000) { + emu->x86.R_EAX |= 0xffff0000; + } else { + emu->x86.R_EAX &= 0x0000ffff; + } + } else { + if (emu->x86.R_AL & 0x80) { + emu->x86.R_AH = 0xff; + } else { + emu->x86.R_AH = 0x0; + } + } +} + +/* + * REMARKS: + * Handles opcode 0x99 + */ +static void +x86emuOp_cwd(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + if (emu->x86.R_EAX & 0x80000000) { + emu->x86.R_EDX = 0xffffffff; + } else { + emu->x86.R_EDX = 0x0; + } + } else { + if (emu->x86.R_AX & 0x8000) { + emu->x86.R_DX = 0xffff; + } else { + emu->x86.R_DX = 0x0; + } + } +} + +/* + * REMARKS: + * Handles opcode 0x9a + */ +static void +x86emuOp_call_far_IMM(struct x86emu *emu) +{ + uint16_t farseg, faroff; + + faroff = fetch_word_imm(emu); + farseg = fetch_word_imm(emu); + /* XXX + * + * Hooked interrupt vectors calling into our "BIOS" will cause problems + * unless all intersegment stuff is checked for BIOS access. Check + * needed here. For moment, let it alone. */ + push_word(emu, emu->x86.R_CS); + emu->x86.R_CS = farseg; + push_word(emu, emu->x86.R_IP); + emu->x86.R_IP = faroff; +} + +/* + * REMARKS: + * Handles opcode 0x9c + */ +static void +x86emuOp_pushf_word(struct x86emu *emu) +{ + uint32_t flags; + + /* clear out *all* bits not representing flags, and turn on real bits */ + flags = (emu->x86.R_EFLG & F_MSK) | F_ALWAYS_ON; + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + push_long(emu, flags); + } else { + push_word(emu, (uint16_t) flags); + } +} + +/* + * REMARKS: + * Handles opcode 0x9d + */ +static void +x86emuOp_popf_word(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + emu->x86.R_EFLG = pop_long(emu); + } else { + emu->x86.R_FLG = pop_word(emu); + } +} + +/* + * REMARKS: + * Handles opcode 0x9e + */ +static void +x86emuOp_sahf(struct x86emu *emu) +{ + /* clear the lower bits of the flag register */ + emu->x86.R_FLG &= 0xffffff00; + /* or in the AH register into the flags register */ + emu->x86.R_FLG |= emu->x86.R_AH; +} + +/* + * REMARKS: + * Handles opcode 0x9f + */ +static void +x86emuOp_lahf(struct x86emu *emu) +{ + emu->x86.R_AH = (uint8_t) (emu->x86.R_FLG & 0xff); + /* undocumented TC++ behavior??? Nope. It's documented, but you have + * too look real hard to notice it. */ + emu->x86.R_AH |= 0x2; +} + +/* + * REMARKS: + * Handles opcode 0xa0 + */ +static void +x86emuOp_mov_AL_M_IMM(struct x86emu *emu) +{ + uint16_t offset; + + offset = fetch_word_imm(emu); + emu->x86.R_AL = fetch_data_byte(emu, offset); +} + +/* + * REMARKS: + * Handles opcode 0xa1 + */ +static void +x86emuOp_mov_AX_M_IMM(struct x86emu *emu) +{ + uint16_t offset; + + offset = fetch_word_imm(emu); + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + emu->x86.R_EAX = fetch_data_long(emu, offset); + } else { + emu->x86.R_AX = fetch_data_word(emu, offset); + } +} + +/* + * REMARKS: + * Handles opcode 0xa2 + */ +static void +x86emuOp_mov_M_AL_IMM(struct x86emu *emu) +{ + uint16_t offset; + + offset = fetch_word_imm(emu); + store_data_byte(emu, offset, emu->x86.R_AL); +} + +/* + * REMARKS: + * Handles opcode 0xa3 + */ +static void +x86emuOp_mov_M_AX_IMM(struct x86emu *emu) +{ + uint16_t offset; + + offset = fetch_word_imm(emu); + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + store_data_long(emu, offset, emu->x86.R_EAX); + } else { + store_data_word(emu, offset, emu->x86.R_AX); + } +} + +/* + * REMARKS: + * Handles opcode 0xa4 + */ +static void +x86emuOp_movs_byte(struct x86emu *emu) +{ + uint8_t val; + uint32_t count; + int inc; + + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + count = 1; + if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + count = emu->x86.R_CX; + emu->x86.R_CX = 0; + emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { + val = fetch_data_byte(emu, emu->x86.R_SI); + store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, val); + emu->x86.R_SI += inc; + emu->x86.R_DI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xa5 + */ +static void +x86emuOp_movs_word(struct x86emu *emu) +{ + uint32_t val; + int inc; + uint32_t count; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + inc = 4; + else + inc = 2; + + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -inc; + + count = 1; + if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + count = emu->x86.R_CX; + emu->x86.R_CX = 0; + emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_data_long(emu, emu->x86.R_SI); + store_long(emu, emu->x86.R_ES, emu->x86.R_DI, val); + } else { + val = fetch_data_word(emu, emu->x86.R_SI); + store_word(emu, emu->x86.R_ES, emu->x86.R_DI, (uint16_t) val); + } + emu->x86.R_SI += inc; + emu->x86.R_DI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xa6 + */ +static void +x86emuOp_cmps_byte(struct x86emu *emu) +{ + int8_t val1, val2; + int inc; + + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + + if (emu->x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + val1 = fetch_data_byte(emu, emu->x86.R_SI); + val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_byte(emu, val1, val2); + emu->x86.R_CX -= 1; + emu->x86.R_SI += inc; + emu->x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF) == 0) + break; + } + emu->x86.mode &= ~SYSMODE_PREFIX_REPE; + } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) { + /* REPNE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + val1 = fetch_data_byte(emu, emu->x86.R_SI); + val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_byte(emu, val1, val2); + emu->x86.R_CX -= 1; + emu->x86.R_SI += inc; + emu->x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF)) + break; /* zero flag set means equal */ + } + emu->x86.mode &= ~SYSMODE_PREFIX_REPNE; + } else { + val1 = fetch_data_byte(emu, emu->x86.R_SI); + val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_byte(emu, val1, val2); + emu->x86.R_SI += inc; + emu->x86.R_DI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xa7 + */ +static void +x86emuOp_cmps_word(struct x86emu *emu) +{ + uint32_t val1, val2; + int inc; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -4; + else + inc = 4; + } else { + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -2; + else + inc = 2; + } + if (emu->x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + val1 = fetch_data_long(emu, emu->x86.R_SI); + val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_long(emu, val1, val2); + } else { + val1 = fetch_data_word(emu, emu->x86.R_SI); + val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_word(emu, (uint16_t) val1, (uint16_t) val2); + } + emu->x86.R_CX -= 1; + emu->x86.R_SI += inc; + emu->x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF) == 0) + break; + } + emu->x86.mode &= ~SYSMODE_PREFIX_REPE; + } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) { + /* REPNE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + val1 = fetch_data_long(emu, emu->x86.R_SI); + val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_long(emu, val1, val2); + } else { + val1 = fetch_data_word(emu, emu->x86.R_SI); + val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_word(emu, (uint16_t) val1, (uint16_t) val2); + } + emu->x86.R_CX -= 1; + emu->x86.R_SI += inc; + emu->x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF)) + break; /* zero flag set means equal */ + } + emu->x86.mode &= ~SYSMODE_PREFIX_REPNE; + } else { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + val1 = fetch_data_long(emu, emu->x86.R_SI); + val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_long(emu, val1, val2); + } else { + val1 = fetch_data_word(emu, emu->x86.R_SI); + val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_word(emu, (uint16_t) val1, (uint16_t) val2); + } + emu->x86.R_SI += inc; + emu->x86.R_DI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xa9 + */ +static void +x86emuOp_test_AX_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + test_long(emu, emu->x86.R_EAX, fetch_long_imm(emu)); + } else { + test_word(emu, emu->x86.R_AX, fetch_word_imm(emu)); + } +} + +/* + * REMARKS: + * Handles opcode 0xaa + */ +static void +x86emuOp_stos_byte(struct x86emu *emu) +{ + int inc; + + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AL); + emu->x86.R_CX -= 1; + emu->x86.R_DI += inc; + } + emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } else { + store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AL); + emu->x86.R_DI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xab + */ +static void +x86emuOp_stos_word(struct x86emu *emu) +{ + int inc; + uint32_t count; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + inc = 4; + else + inc = 2; + + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -inc; + + count = 1; + if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + count = emu->x86.R_CX; + emu->x86.R_CX = 0; + emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + store_long(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_EAX); + } else { + store_word(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AX); + } + emu->x86.R_DI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xac + */ +static void +x86emuOp_lods_byte(struct x86emu *emu) +{ + int inc; + + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + emu->x86.R_AL = fetch_data_byte(emu, emu->x86.R_SI); + emu->x86.R_CX -= 1; + emu->x86.R_SI += inc; + } + emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } else { + emu->x86.R_AL = fetch_data_byte(emu, emu->x86.R_SI); + emu->x86.R_SI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xad + */ +static void +x86emuOp_lods_word(struct x86emu *emu) +{ + int inc; + uint32_t count; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + inc = 4; + else + inc = 2; + + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -inc; + + count = 1; + if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + count = emu->x86.R_CX; + emu->x86.R_CX = 0; + emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + emu->x86.R_EAX = fetch_data_long(emu, emu->x86.R_SI); + } else { + emu->x86.R_AX = fetch_data_word(emu, emu->x86.R_SI); + } + emu->x86.R_SI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xae + */ +static void +x86emuOp_scas_byte(struct x86emu *emu) +{ + int8_t val2; + int inc; + + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + if (emu->x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_byte(emu, emu->x86.R_AL, val2); + emu->x86.R_CX -= 1; + emu->x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF) == 0) + break; + } + emu->x86.mode &= ~SYSMODE_PREFIX_REPE; + } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) { + /* REPNE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_byte(emu, emu->x86.R_AL, val2); + emu->x86.R_CX -= 1; + emu->x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF)) + break; /* zero flag set means equal */ + } + emu->x86.mode &= ~SYSMODE_PREFIX_REPNE; + } else { + val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_byte(emu, emu->x86.R_AL, val2); + emu->x86.R_DI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xaf + */ +static void +x86emuOp_scas_word(struct x86emu *emu) +{ + int inc; + uint32_t val; + + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + inc = 4; + else + inc = 2; + + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -inc; + + if (emu->x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_long(emu, emu->x86.R_EAX, val); + } else { + val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_word(emu, emu->x86.R_AX, (uint16_t) val); + } + emu->x86.R_CX -= 1; + emu->x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF) == 0) + break; + } + emu->x86.mode &= ~SYSMODE_PREFIX_REPE; + } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) { + /* REPNE */ + /* move them until CX is ZERO. */ + while (emu->x86.R_CX != 0) { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_long(emu, emu->x86.R_EAX, val); + } else { + val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_word(emu, emu->x86.R_AX, (uint16_t) val); + } + emu->x86.R_CX -= 1; + emu->x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF)) + break; /* zero flag set means equal */ + } + emu->x86.mode &= ~SYSMODE_PREFIX_REPNE; + } else { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_long(emu, emu->x86.R_EAX, val); + } else { + val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI); + cmp_word(emu, emu->x86.R_AX, (uint16_t) val); + } + emu->x86.R_DI += inc; + } +} + +/* + * REMARKS: + * Handles opcode 0xb8 + */ +static void +x86emuOp_mov_word_AX_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + emu->x86.R_EAX = fetch_long_imm(emu); + else + emu->x86.R_AX = fetch_word_imm(emu); +} + +/* + * REMARKS: + * Handles opcode 0xb9 + */ +static void +x86emuOp_mov_word_CX_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + emu->x86.R_ECX = fetch_long_imm(emu); + else + emu->x86.R_CX = fetch_word_imm(emu); +} + +/* + * REMARKS: + * Handles opcode 0xba + */ +static void +x86emuOp_mov_word_DX_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + emu->x86.R_EDX = fetch_long_imm(emu); + else + emu->x86.R_DX = fetch_word_imm(emu); +} + +/* + * REMARKS: + * Handles opcode 0xbb + */ +static void +x86emuOp_mov_word_BX_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + emu->x86.R_EBX = fetch_long_imm(emu); + else + emu->x86.R_BX = fetch_word_imm(emu); +} + +/* + * REMARKS: + * Handles opcode 0xbc + */ +static void +x86emuOp_mov_word_SP_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + emu->x86.R_ESP = fetch_long_imm(emu); + else + emu->x86.R_SP = fetch_word_imm(emu); +} + +/* + * REMARKS: + * Handles opcode 0xbd + */ +static void +x86emuOp_mov_word_BP_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + emu->x86.R_EBP = fetch_long_imm(emu); + else + emu->x86.R_BP = fetch_word_imm(emu); +} + +/* + * REMARKS: + * Handles opcode 0xbe + */ +static void +x86emuOp_mov_word_SI_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + emu->x86.R_ESI = fetch_long_imm(emu); + else + emu->x86.R_SI = fetch_word_imm(emu); +} + +/* + * REMARKS: + * Handles opcode 0xbf + */ +static void +x86emuOp_mov_word_DI_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + emu->x86.R_EDI = fetch_long_imm(emu); + else + emu->x86.R_DI = fetch_word_imm(emu); +} +/* used by opcodes c0, d0, and d2. */ +static +uint8_t(* const opcD0_byte_operation[]) (struct x86emu *, uint8_t d, uint8_t s) = +{ + rol_byte, + ror_byte, + rcl_byte, + rcr_byte, + shl_byte, + shr_byte, + shl_byte, /* sal_byte === shl_byte by definition */ + sar_byte, +}; + +/* + * REMARKS: + * Handles opcode 0xc0 + */ +static void +x86emuOp_opcC0_byte_RM_MEM(struct x86emu *emu) +{ + uint8_t destval, amt; + + /* + * Yet another weirdo special case instruction format. Part of + * the opcode held below in "RH". Doubly nested case would + * result, except that the decoded instruction + */ + fetch_decode_modrm(emu); + /* know operation, decode the mod byte to find the addressing mode. */ + destval = decode_and_fetch_byte_imm8(emu, &amt); + destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, amt); + write_back_byte(emu, destval); +} +/* used by opcodes c1, d1, and d3. */ +static +uint16_t(* const opcD1_word_operation[]) (struct x86emu *, uint16_t s, uint8_t d) = +{ + rol_word, + ror_word, + rcl_word, + rcr_word, + shl_word, + shr_word, + shl_word, /* sal_byte === shl_byte by definition */ + sar_word, +}; +/* used by opcodes c1, d1, and d3. */ +static +uint32_t(* const opcD1_long_operation[]) (struct x86emu *, uint32_t s, uint8_t d) = +{ + rol_long, + ror_long, + rcl_long, + rcr_long, + shl_long, + shr_long, + shl_long, /* sal_byte === shl_byte by definition */ + sar_long, +}; + +/* + * REMARKS: + * Handles opcode 0xc1 + */ +static void +x86emuOp_opcC1_word_RM_MEM(struct x86emu *emu) +{ + uint8_t amt; + + /* + * Yet another weirdo special case instruction format. Part of + * the opcode held below in "RH". Doubly nested case would + * result, except that the decoded instruction + */ + fetch_decode_modrm(emu); + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + uint32_t destval; + + destval = decode_and_fetch_long_imm8(emu, &amt); + destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, amt); + write_back_long(emu, destval); + } else { + uint16_t destval; + + destval = decode_and_fetch_word_imm8(emu, &amt); + destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, amt); + write_back_word(emu, destval); + } +} + +/* + * REMARKS: + * Handles opcode 0xc2 + */ +static void +x86emuOp_ret_near_IMM(struct x86emu *emu) +{ + uint16_t imm; + + imm = fetch_word_imm(emu); + emu->x86.R_IP = pop_word(emu); + emu->x86.R_SP += imm; +} + +/* + * REMARKS: + * Handles opcode 0xc6 + */ +static void +x86emuOp_mov_byte_RM_IMM(struct x86emu *emu) +{ + uint8_t *destreg; + uint32_t destoffset; + uint8_t imm; + + fetch_decode_modrm(emu); + if (emu->cur_rh != 0) + x86emu_halt_sys(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + imm = fetch_byte_imm(emu); + store_data_byte(emu, destoffset, imm); + } else { + destreg = decode_rl_byte_register(emu); + imm = fetch_byte_imm(emu); + *destreg = imm; + } +} + +/* + * REMARKS: + * Handles opcode 0xc7 + */ +static void +x86emuOp32_mov_word_RM_IMM(struct x86emu *emu) +{ + uint32_t destoffset; + uint32_t imm, *destreg; + + fetch_decode_modrm(emu); + if (emu->cur_rh != 0) + x86emu_halt_sys(emu); + + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + imm = fetch_long_imm(emu); + store_data_long(emu, destoffset, imm); + } else { + destreg = decode_rl_long_register(emu); + imm = fetch_long_imm(emu); + *destreg = imm; + } +} + +static void +x86emuOp16_mov_word_RM_IMM(struct x86emu *emu) +{ + uint32_t destoffset; + uint16_t imm, *destreg; + + fetch_decode_modrm(emu); + if (emu->cur_rh != 0) + x86emu_halt_sys(emu); + + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + imm = fetch_word_imm(emu); + store_data_word(emu, destoffset, imm); + } else { + destreg = decode_rl_word_register(emu); + imm = fetch_word_imm(emu); + *destreg = imm; + } +} + +static void +x86emuOp_mov_word_RM_IMM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_mov_word_RM_IMM(emu); + else + x86emuOp16_mov_word_RM_IMM(emu); +} + +/* + * REMARKS: + * Handles opcode 0xc8 + */ +static void +x86emuOp_enter(struct x86emu *emu) +{ + uint16_t local, frame_pointer; + uint8_t nesting; + int i; + + local = fetch_word_imm(emu); + nesting = fetch_byte_imm(emu); + push_word(emu, emu->x86.R_BP); + frame_pointer = emu->x86.R_SP; + if (nesting > 0) { + for (i = 1; i < nesting; i++) { + emu->x86.R_BP -= 2; + push_word(emu, fetch_word(emu, emu->x86.R_SS, emu->x86.R_BP)); + } + push_word(emu, frame_pointer); + } + emu->x86.R_BP = frame_pointer; + emu->x86.R_SP = (uint16_t) (emu->x86.R_SP - local); +} + +/* + * REMARKS: + * Handles opcode 0xc9 + */ +static void +x86emuOp_leave(struct x86emu *emu) +{ + emu->x86.R_SP = emu->x86.R_BP; + emu->x86.R_BP = pop_word(emu); +} + +/* + * REMARKS: + * Handles opcode 0xca + */ +static void +x86emuOp_ret_far_IMM(struct x86emu *emu) +{ + uint16_t imm; + + imm = fetch_word_imm(emu); + emu->x86.R_IP = pop_word(emu); + emu->x86.R_CS = pop_word(emu); + emu->x86.R_SP += imm; +} + +/* + * REMARKS: + * Handles opcode 0xcb + */ +static void +x86emuOp_ret_far(struct x86emu *emu) +{ + emu->x86.R_IP = pop_word(emu); + emu->x86.R_CS = pop_word(emu); +} + +/* + * REMARKS: + * Handles opcode 0xcc + */ +static void +x86emuOp_int3(struct x86emu *emu) +{ + x86emu_intr_dispatch(emu, 3); +} + +/* + * REMARKS: + * Handles opcode 0xcd + */ +static void +x86emuOp_int_IMM(struct x86emu *emu) +{ + uint8_t intnum; + + intnum = fetch_byte_imm(emu); + x86emu_intr_dispatch(emu, intnum); +} + +/* + * REMARKS: + * Handles opcode 0xce + */ +static void +x86emuOp_into(struct x86emu *emu) +{ + if (ACCESS_FLAG(F_OF)) + x86emu_intr_dispatch(emu, 4); +} + +/* + * REMARKS: + * Handles opcode 0xcf + */ +static void +x86emuOp_iret(struct x86emu *emu) +{ + emu->x86.R_IP = pop_word(emu); + emu->x86.R_CS = pop_word(emu); + emu->x86.R_FLG = pop_word(emu); +} + +/* + * REMARKS: + * Handles opcode 0xd0 + */ +static void +x86emuOp_opcD0_byte_RM_1(struct x86emu *emu) +{ + uint8_t destval; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_byte(emu); + destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, 1); + write_back_byte(emu, destval); +} + +/* + * REMARKS: + * Handles opcode 0xd1 + */ +static void +x86emuOp_opcD1_word_RM_1(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + uint32_t destval; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_long(emu); + destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, 1); + write_back_long(emu, destval); + } else { + uint16_t destval; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_word(emu); + destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, 1); + write_back_word(emu, destval); + } +} + +/* + * REMARKS: + * Handles opcode 0xd2 + */ +static void +x86emuOp_opcD2_byte_RM_CL(struct x86emu *emu) +{ + uint8_t destval; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_byte(emu); + destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL); + write_back_byte(emu, destval); +} + +/* + * REMARKS: + * Handles opcode 0xd3 + */ +static void +x86emuOp_opcD3_word_RM_CL(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + uint32_t destval; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_long(emu); + destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL); + write_back_long(emu, destval); + } else { + uint16_t destval; + + fetch_decode_modrm(emu); + destval = decode_and_fetch_word(emu); + destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL); + write_back_word(emu, destval); + } +} + +/* + * REMARKS: + * Handles opcode 0xd4 + */ +static void +x86emuOp_aam(struct x86emu *emu) +{ + uint8_t a; + + a = fetch_byte_imm(emu); /* this is a stupid encoding. */ + if (a != 10) { + /* fix: add base decoding aam_word(uint8_t val, int base a) */ + x86emu_halt_sys(emu); + } + /* note the type change here --- returning AL and AH in AX. */ + emu->x86.R_AX = aam_word(emu, emu->x86.R_AL); +} + +/* + * REMARKS: + * Handles opcode 0xd5 + */ +static void +x86emuOp_aad(struct x86emu *emu) +{ + uint8_t a; + + a = fetch_byte_imm(emu); + if (a != 10) { + /* fix: add base decoding aad_word(uint16_t val, int base a) */ + x86emu_halt_sys(emu); + } + emu->x86.R_AX = aad_word(emu, emu->x86.R_AX); +} +/* opcode 0xd6 ILLEGAL OPCODE */ + + +/* + * REMARKS: + * Handles opcode 0xd7 + */ +static void +x86emuOp_xlat(struct x86emu *emu) +{ + uint16_t addr; + + addr = (uint16_t) (emu->x86.R_BX + (uint8_t) emu->x86.R_AL); + emu->x86.R_AL = fetch_data_byte(emu, addr); +} + +/* opcode=0xd8 */ +static void +x86emuOp_esc_coprocess_d8(struct x86emu *emu) +{ +} +/* opcode=0xd9 */ +static void +x86emuOp_esc_coprocess_d9(struct x86emu *emu) +{ + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) + decode_rl_address(emu); +} +/* opcode=0xda */ +static void +x86emuOp_esc_coprocess_da(struct x86emu *emu) +{ + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) + decode_rl_address(emu); +} +/* opcode=0xdb */ +static void +x86emuOp_esc_coprocess_db(struct x86emu *emu) +{ + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) + decode_rl_address(emu); +} +/* opcode=0xdc */ +static void +x86emuOp_esc_coprocess_dc(struct x86emu *emu) +{ + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) + decode_rl_address(emu); +} +/* opcode=0xdd */ +static void +x86emuOp_esc_coprocess_dd(struct x86emu *emu) +{ + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) + decode_rl_address(emu); +} +/* opcode=0xde */ +static void +x86emuOp_esc_coprocess_de(struct x86emu *emu) +{ + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) + decode_rl_address(emu); +} +/* opcode=0xdf */ +static void +x86emuOp_esc_coprocess_df(struct x86emu *emu) +{ + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) + decode_rl_address(emu); +} + + +/* + * REMARKS: + * Handles opcode 0xe0 + */ +static void +x86emuOp_loopne(struct x86emu *emu) +{ + int16_t ip; + + ip = (int8_t) fetch_byte_imm(emu); + ip += (int16_t) emu->x86.R_IP; + emu->x86.R_CX -= 1; + if (emu->x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ + emu->x86.R_IP = ip; +} + +/* + * REMARKS: + * Handles opcode 0xe1 + */ +static void +x86emuOp_loope(struct x86emu *emu) +{ + int16_t ip; + + ip = (int8_t) fetch_byte_imm(emu); + ip += (int16_t) emu->x86.R_IP; + emu->x86.R_CX -= 1; + if (emu->x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ + emu->x86.R_IP = ip; +} + +/* + * REMARKS: + * Handles opcode 0xe2 + */ +static void +x86emuOp_loop(struct x86emu *emu) +{ + int16_t ip; + + ip = (int8_t) fetch_byte_imm(emu); + ip += (int16_t) emu->x86.R_IP; + emu->x86.R_CX -= 1; + if (emu->x86.R_CX != 0) + emu->x86.R_IP = ip; +} + +/* + * REMARKS: + * Handles opcode 0xe3 + */ +static void +x86emuOp_jcxz(struct x86emu *emu) +{ + uint16_t target; + int8_t offset; + + /* jump to byte offset if overflow flag is set */ + offset = (int8_t) fetch_byte_imm(emu); + target = (uint16_t) (emu->x86.R_IP + offset); + if (emu->x86.R_CX == 0) + emu->x86.R_IP = target; +} + +/* + * REMARKS: + * Handles opcode 0xe4 + */ +static void +x86emuOp_in_byte_AL_IMM(struct x86emu *emu) +{ + uint8_t port; + + port = (uint8_t) fetch_byte_imm(emu); + emu->x86.R_AL = (*emu->emu_inb) (emu, port); +} + +/* + * REMARKS: + * Handles opcode 0xe5 + */ +static void +x86emuOp_in_word_AX_IMM(struct x86emu *emu) +{ + uint8_t port; + + port = (uint8_t) fetch_byte_imm(emu); + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + emu->x86.R_EAX = (*emu->emu_inl) (emu, port); + } else { + emu->x86.R_AX = (*emu->emu_inw) (emu, port); + } +} + +/* + * REMARKS: + * Handles opcode 0xe6 + */ +static void +x86emuOp_out_byte_IMM_AL(struct x86emu *emu) +{ + uint8_t port; + + port = (uint8_t) fetch_byte_imm(emu); + (*emu->emu_outb) (emu, port, emu->x86.R_AL); +} + +/* + * REMARKS: + * Handles opcode 0xe7 + */ +static void +x86emuOp_out_word_IMM_AX(struct x86emu *emu) +{ + uint8_t port; + + port = (uint8_t) fetch_byte_imm(emu); + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + (*emu->emu_outl) (emu, port, emu->x86.R_EAX); + } else { + (*emu->emu_outw) (emu, port, emu->x86.R_AX); + } +} + +/* + * REMARKS: + * Handles opcode 0xe8 + */ +static void +x86emuOp_call_near_IMM(struct x86emu *emu) +{ + int16_t ip; + + ip = (int16_t) fetch_word_imm(emu); + ip += (int16_t) emu->x86.R_IP; /* CHECK SIGN */ + push_word(emu, emu->x86.R_IP); + emu->x86.R_IP = ip; +} + +/* + * REMARKS: + * Handles opcode 0xe9 + */ +static void +x86emuOp_jump_near_IMM(struct x86emu *emu) +{ + int ip; + + ip = (int16_t) fetch_word_imm(emu); + ip += (int16_t) emu->x86.R_IP; + emu->x86.R_IP = (uint16_t) ip; +} + +/* + * REMARKS: + * Handles opcode 0xea + */ +static void +x86emuOp_jump_far_IMM(struct x86emu *emu) +{ + uint16_t cs, ip; + + ip = fetch_word_imm(emu); + cs = fetch_word_imm(emu); + emu->x86.R_IP = ip; + emu->x86.R_CS = cs; +} + +/* + * REMARKS: + * Handles opcode 0xeb + */ +static void +x86emuOp_jump_byte_IMM(struct x86emu *emu) +{ + uint16_t target; + int8_t offset; + + offset = (int8_t) fetch_byte_imm(emu); + target = (uint16_t) (emu->x86.R_IP + offset); + emu->x86.R_IP = target; +} + +/* + * REMARKS: + * Handles opcode 0xec + */ +static void +x86emuOp_in_byte_AL_DX(struct x86emu *emu) +{ + emu->x86.R_AL = (*emu->emu_inb) (emu, emu->x86.R_DX); +} + +/* + * REMARKS: + * Handles opcode 0xed + */ +static void +x86emuOp_in_word_AX_DX(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + emu->x86.R_EAX = (*emu->emu_inl) (emu, emu->x86.R_DX); + } else { + emu->x86.R_AX = (*emu->emu_inw) (emu, emu->x86.R_DX); + } +} + +/* + * REMARKS: + * Handles opcode 0xee + */ +static void +x86emuOp_out_byte_DX_AL(struct x86emu *emu) +{ + (*emu->emu_outb) (emu, emu->x86.R_DX, emu->x86.R_AL); +} + +/* + * REMARKS: + * Handles opcode 0xef + */ +static void +x86emuOp_out_word_DX_AX(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + (*emu->emu_outl) (emu, emu->x86.R_DX, emu->x86.R_EAX); + } else { + (*emu->emu_outw) (emu, emu->x86.R_DX, emu->x86.R_AX); + } +} + +/* + * REMARKS: + * Handles opcode 0xf0 + */ +static void +x86emuOp_lock(struct x86emu *emu) +{ +} +/*opcode 0xf1 ILLEGAL OPERATION */ + + +/* + * REMARKS: + * Handles opcode 0xf5 + */ +static void +x86emuOp_cmc(struct x86emu *emu) +{ + if (ACCESS_FLAG(F_CF)) + CLEAR_FLAG(F_CF); + else + SET_FLAG(F_CF); +} + +/* + * REMARKS: + * Handles opcode 0xf6 + */ +static void +x86emuOp_opcF6_byte_RM(struct x86emu *emu) +{ + uint8_t destval, srcval; + + /* long, drawn out code follows. Double switch for a total of 32 + * cases. */ + fetch_decode_modrm(emu); + if (emu->cur_rh == 1) + x86emu_halt_sys(emu); + + if (emu->cur_rh == 0) { + destval = decode_and_fetch_byte_imm8(emu, &srcval); + test_byte(emu, destval, srcval); + return; + } + destval = decode_and_fetch_byte(emu); + switch (emu->cur_rh) { + case 2: + destval = ~destval; + write_back_byte(emu, destval); + break; + case 3: + destval = neg_byte(emu, destval); + write_back_byte(emu, destval); + break; + case 4: + mul_byte(emu, destval); + break; + case 5: + imul_byte(emu, destval); + break; + case 6: + div_byte(emu, destval); + break; + case 7: + idiv_byte(emu, destval); + break; + } +} + +/* + * REMARKS: + * Handles opcode 0xf7 + */ +static void +x86emuOp32_opcF7_word_RM(struct x86emu *emu) +{ + uint32_t destval, srcval; + + /* long, drawn out code follows. Double switch for a total of 32 + * cases. */ + fetch_decode_modrm(emu); + if (emu->cur_rh == 1) + x86emu_halt_sys(emu); + + if (emu->cur_rh == 0) { + if (emu->cur_mod != 3) { + uint32_t destoffset; + + destoffset = decode_rl_address(emu); + srcval = fetch_long_imm(emu); + destval = fetch_data_long(emu, destoffset); + } else { + srcval = fetch_long_imm(emu); + destval = *decode_rl_long_register(emu); + } + test_long(emu, destval, srcval); + return; + } + destval = decode_and_fetch_long(emu); + switch (emu->cur_rh) { + case 2: + destval = ~destval; + write_back_long(emu, destval); + break; + case 3: + destval = neg_long(emu, destval); + write_back_long(emu, destval); + break; + case 4: + mul_long(emu, destval); + break; + case 5: + imul_long(emu, destval); + break; + case 6: + div_long(emu, destval); + break; + case 7: + idiv_long(emu, destval); + break; + } +} +static void +x86emuOp16_opcF7_word_RM(struct x86emu *emu) +{ + uint16_t destval, srcval; + + /* long, drawn out code follows. Double switch for a total of 32 + * cases. */ + fetch_decode_modrm(emu); + if (emu->cur_rh == 1) + x86emu_halt_sys(emu); + + if (emu->cur_rh == 0) { + if (emu->cur_mod != 3) { + uint32_t destoffset; + + destoffset = decode_rl_address(emu); + srcval = fetch_word_imm(emu); + destval = fetch_data_word(emu, destoffset); + } else { + srcval = fetch_word_imm(emu); + destval = *decode_rl_word_register(emu); + } + test_word(emu, destval, srcval); + return; + } + destval = decode_and_fetch_word(emu); + switch (emu->cur_rh) { + case 2: + destval = ~destval; + write_back_word(emu, destval); + break; + case 3: + destval = neg_word(emu, destval); + write_back_word(emu, destval); + break; + case 4: + mul_word(emu, destval); + break; + case 5: + imul_word(emu, destval); + break; + case 6: + div_word(emu, destval); + break; + case 7: + idiv_word(emu, destval); + break; + } +} +static void +x86emuOp_opcF7_word_RM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_opcF7_word_RM(emu); + else + x86emuOp16_opcF7_word_RM(emu); +} + +/* + * REMARKS: + * Handles opcode 0xfe + */ +static void +x86emuOp_opcFE_byte_RM(struct x86emu *emu) +{ + uint8_t destval; + uint32_t destoffset; + uint8_t *destreg; + + /* Yet another special case instruction. */ + fetch_decode_modrm(emu); + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + switch (emu->cur_rh) { + case 0: /* inc word ptr ... */ + destval = fetch_data_byte(emu, destoffset); + destval = inc_byte(emu, destval); + store_data_byte(emu, destoffset, destval); + break; + case 1: /* dec word ptr ... */ + destval = fetch_data_byte(emu, destoffset); + destval = dec_byte(emu, destval); + store_data_byte(emu, destoffset, destval); + break; + } + } else { + destreg = decode_rl_byte_register(emu); + switch (emu->cur_rh) { + case 0: + *destreg = inc_byte(emu, *destreg); + break; + case 1: + *destreg = dec_byte(emu, *destreg); + break; + } + } +} + +/* + * REMARKS: + * Handles opcode 0xff + */ +static void +x86emuOp32_opcFF_word_RM(struct x86emu *emu) +{ + uint32_t destoffset = 0; + uint32_t destval, *destreg; + + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = fetch_data_long(emu, destoffset); + switch (emu->cur_rh) { + case 0: /* inc word ptr ... */ + destval = inc_long(emu, destval); + store_data_long(emu, destoffset, destval); + break; + case 1: /* dec word ptr ... */ + destval = dec_long(emu, destval); + store_data_long(emu, destoffset, destval); + break; + case 6: /* push word ptr ... */ + push_long(emu, destval); + break; + } + } else { + destreg = decode_rl_long_register(emu); + switch (emu->cur_rh) { + case 0: + *destreg = inc_long(emu, *destreg); + break; + case 1: + *destreg = dec_long(emu, *destreg); + break; + case 6: + push_long(emu, *destreg); + break; + } + } +} + +static void +x86emuOp16_opcFF_word_RM(struct x86emu *emu) +{ + uint32_t destoffset = 0; + uint16_t *destreg; + uint16_t destval; + + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = fetch_data_word(emu, destoffset); + switch (emu->cur_rh) { + case 0: + destval = inc_word(emu, destval); + store_data_word(emu, destoffset, destval); + break; + case 1: /* dec word ptr ... */ + destval = dec_word(emu, destval); + store_data_word(emu, destoffset, destval); + break; + case 6: /* push word ptr ... */ + push_word(emu, destval); + break; + } + } else { + destreg = decode_rl_word_register(emu); + switch (emu->cur_rh) { + case 0: + *destreg = inc_word(emu, *destreg); + break; + case 1: + *destreg = dec_word(emu, *destreg); + break; + case 6: + push_word(emu, *destreg); + break; + } + } +} + +static void +x86emuOp_opcFF_word_RM(struct x86emu *emu) +{ + uint32_t destoffset = 0; + uint16_t destval, destval2; + + /* Yet another special case instruction. */ + fetch_decode_modrm(emu); + if ((emu->cur_mod == 3 && (emu->cur_rh == 3 || emu->cur_rh == 5)) || emu->cur_rh == 7) + x86emu_halt_sys(emu); + if (emu->cur_rh == 0 || emu->cur_rh == 1 || emu->cur_rh == 6) { + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp32_opcFF_word_RM(emu); + else + x86emuOp16_opcFF_word_RM(emu); + return; + } + + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + destval = fetch_data_word(emu, destoffset); + switch (emu->cur_rh) { + case 3: /* call far ptr ... */ + destval2 = fetch_data_word(emu, destoffset + 2); + push_word(emu, emu->x86.R_CS); + emu->x86.R_CS = destval2; + push_word(emu, emu->x86.R_IP); + emu->x86.R_IP = destval; + break; + case 5: /* jmp far ptr ... */ + destval2 = fetch_data_word(emu, destoffset + 2); + emu->x86.R_IP = destval; + emu->x86.R_CS = destval2; + break; + } + } else { + destval = *decode_rl_word_register(emu); + } + + switch (emu->cur_rh) { + case 2: /* call word ptr */ + push_word(emu, emu->x86.R_IP); + emu->x86.R_IP = destval; + break; + case 4: /* jmp */ + emu->x86.R_IP = destval; + break; + } +} + +/* + * * Single byte operation code table: + */ +static void +x86emu_exec_one_byte(struct x86emu * emu) +{ + uint8_t op1; + + op1 = fetch_byte_imm(emu); + + switch (op1) { + case 0x00: + common_binop_byte_rm_r(emu, add_byte); + break; + case 0x01: + common_binop_word_long_rm_r(emu, add_word, add_long); + break; + case 0x02: + common_binop_byte_r_rm(emu, add_byte); + break; + case 0x03: + common_binop_word_long_r_rm(emu, add_word, add_long); + break; + case 0x04: + common_binop_byte_imm(emu, add_byte); + break; + case 0x05: + common_binop_word_long_imm(emu, add_word, add_long); + break; + case 0x06: + push_word(emu, emu->x86.R_ES); + break; + case 0x07: + emu->x86.R_ES = pop_word(emu); + break; + + case 0x08: + common_binop_byte_rm_r(emu, or_byte); + break; + case 0x09: + common_binop_word_long_rm_r(emu, or_word, or_long); + break; + case 0x0a: + common_binop_byte_r_rm(emu, or_byte); + break; + case 0x0b: + common_binop_word_long_r_rm(emu, or_word, or_long); + break; + case 0x0c: + common_binop_byte_imm(emu, or_byte); + break; + case 0x0d: + common_binop_word_long_imm(emu, or_word, or_long); + break; + case 0x0e: + push_word(emu, emu->x86.R_CS); + break; + case 0x0f: + x86emu_exec_two_byte(emu); + break; + + case 0x10: + common_binop_byte_rm_r(emu, adc_byte); + break; + case 0x11: + common_binop_word_long_rm_r(emu, adc_word, adc_long); + break; + case 0x12: + common_binop_byte_r_rm(emu, adc_byte); + break; + case 0x13: + common_binop_word_long_r_rm(emu, adc_word, adc_long); + break; + case 0x14: + common_binop_byte_imm(emu, adc_byte); + break; + case 0x15: + common_binop_word_long_imm(emu, adc_word, adc_long); + break; + case 0x16: + push_word(emu, emu->x86.R_SS); + break; + case 0x17: + emu->x86.R_SS = pop_word(emu); + break; + + case 0x18: + common_binop_byte_rm_r(emu, sbb_byte); + break; + case 0x19: + common_binop_word_long_rm_r(emu, sbb_word, sbb_long); + break; + case 0x1a: + common_binop_byte_r_rm(emu, sbb_byte); + break; + case 0x1b: + common_binop_word_long_r_rm(emu, sbb_word, sbb_long); + break; + case 0x1c: + common_binop_byte_imm(emu, sbb_byte); + break; + case 0x1d: + common_binop_word_long_imm(emu, sbb_word, sbb_long); + break; + case 0x1e: + push_word(emu, emu->x86.R_DS); + break; + case 0x1f: + emu->x86.R_DS = pop_word(emu); + break; + + case 0x20: + common_binop_byte_rm_r(emu, and_byte); + break; + case 0x21: + common_binop_word_long_rm_r(emu, and_word, and_long); + break; + case 0x22: + common_binop_byte_r_rm(emu, and_byte); + break; + case 0x23: + common_binop_word_long_r_rm(emu, and_word, and_long); + break; + case 0x24: + common_binop_byte_imm(emu, and_byte); + break; + case 0x25: + common_binop_word_long_imm(emu, and_word, and_long); + break; + case 0x26: + emu->x86.mode |= SYSMODE_SEGOVR_ES; + break; + case 0x27: + emu->x86.R_AL = daa_byte(emu, emu->x86.R_AL); + break; + + case 0x28: + common_binop_byte_rm_r(emu, sub_byte); + break; + case 0x29: + common_binop_word_long_rm_r(emu, sub_word, sub_long); + break; + case 0x2a: + common_binop_byte_r_rm(emu, sub_byte); + break; + case 0x2b: + common_binop_word_long_r_rm(emu, sub_word, sub_long); + break; + case 0x2c: + common_binop_byte_imm(emu, sub_byte); + break; + case 0x2d: + common_binop_word_long_imm(emu, sub_word, sub_long); + break; + case 0x2e: + emu->x86.mode |= SYSMODE_SEGOVR_CS; + break; + case 0x2f: + emu->x86.R_AL = das_byte(emu, emu->x86.R_AL); + break; + + case 0x30: + common_binop_byte_rm_r(emu, xor_byte); + break; + case 0x31: + common_binop_word_long_rm_r(emu, xor_word, xor_long); + break; + case 0x32: + common_binop_byte_r_rm(emu, xor_byte); + break; + case 0x33: + common_binop_word_long_r_rm(emu, xor_word, xor_long); + break; + case 0x34: + common_binop_byte_imm(emu, xor_byte); + break; + case 0x35: + common_binop_word_long_imm(emu, xor_word, xor_long); + break; + case 0x36: + emu->x86.mode |= SYSMODE_SEGOVR_SS; + break; + case 0x37: + emu->x86.R_AX = aaa_word(emu, emu->x86.R_AX); + break; + + case 0x38: + common_binop_ns_byte_rm_r(emu, cmp_byte_no_return); + break; + case 0x39: + common_binop_ns_word_long_rm_r(emu, cmp_word_no_return, + cmp_long_no_return); + break; + case 0x3a: + x86emuOp_cmp_byte_R_RM(emu); + break; + case 0x3b: + x86emuOp_cmp_word_R_RM(emu); + break; + case 0x3c: + x86emuOp_cmp_byte_AL_IMM(emu); + break; + case 0x3d: + x86emuOp_cmp_word_AX_IMM(emu); + break; + case 0x3e: + emu->x86.mode |= SYSMODE_SEGOVR_DS; + break; + case 0x3f: + emu->x86.R_AX = aas_word(emu, emu->x86.R_AX); + break; + + case 0x40: + common_inc_word_long(emu, &emu->x86.register_a); + break; + case 0x41: + common_inc_word_long(emu, &emu->x86.register_c); + break; + case 0x42: + common_inc_word_long(emu, &emu->x86.register_d); + break; + case 0x43: + common_inc_word_long(emu, &emu->x86.register_b); + break; + case 0x44: + common_inc_word_long(emu, &emu->x86.register_sp); + break; + case 0x45: + common_inc_word_long(emu, &emu->x86.register_bp); + break; + case 0x46: + common_inc_word_long(emu, &emu->x86.register_si); + break; + case 0x47: + common_inc_word_long(emu, &emu->x86.register_di); + break; + + case 0x48: + common_dec_word_long(emu, &emu->x86.register_a); + break; + case 0x49: + common_dec_word_long(emu, &emu->x86.register_c); + break; + case 0x4a: + common_dec_word_long(emu, &emu->x86.register_d); + break; + case 0x4b: + common_dec_word_long(emu, &emu->x86.register_b); + break; + case 0x4c: + common_dec_word_long(emu, &emu->x86.register_sp); + break; + case 0x4d: + common_dec_word_long(emu, &emu->x86.register_bp); + break; + case 0x4e: + common_dec_word_long(emu, &emu->x86.register_si); + break; + case 0x4f: + common_dec_word_long(emu, &emu->x86.register_di); + break; + + case 0x50: + common_push_word_long(emu, &emu->x86.register_a); + break; + case 0x51: + common_push_word_long(emu, &emu->x86.register_c); + break; + case 0x52: + common_push_word_long(emu, &emu->x86.register_d); + break; + case 0x53: + common_push_word_long(emu, &emu->x86.register_b); + break; + case 0x54: + common_push_word_long(emu, &emu->x86.register_sp); + break; + case 0x55: + common_push_word_long(emu, &emu->x86.register_bp); + break; + case 0x56: + common_push_word_long(emu, &emu->x86.register_si); + break; + case 0x57: + common_push_word_long(emu, &emu->x86.register_di); + break; + + case 0x58: + common_pop_word_long(emu, &emu->x86.register_a); + break; + case 0x59: + common_pop_word_long(emu, &emu->x86.register_c); + break; + case 0x5a: + common_pop_word_long(emu, &emu->x86.register_d); + break; + case 0x5b: + common_pop_word_long(emu, &emu->x86.register_b); + break; + case 0x5c: + common_pop_word_long(emu, &emu->x86.register_sp); + break; + case 0x5d: + common_pop_word_long(emu, &emu->x86.register_bp); + break; + case 0x5e: + common_pop_word_long(emu, &emu->x86.register_si); + break; + case 0x5f: + common_pop_word_long(emu, &emu->x86.register_di); + break; + + case 0x60: + x86emuOp_push_all(emu); + break; + case 0x61: + x86emuOp_pop_all(emu); + break; + /* 0x62 bound */ + /* 0x63 arpl */ + case 0x64: + emu->x86.mode |= SYSMODE_SEGOVR_FS; + break; + case 0x65: + emu->x86.mode |= SYSMODE_SEGOVR_GS; + break; + case 0x66: + emu->x86.mode |= SYSMODE_PREFIX_DATA; + break; + case 0x67: + emu->x86.mode |= SYSMODE_PREFIX_ADDR; + break; + + case 0x68: + x86emuOp_push_word_IMM(emu); + break; + case 0x69: + common_imul_imm(emu, 0); + break; + case 0x6a: + x86emuOp_push_byte_IMM(emu); + break; + case 0x6b: + common_imul_imm(emu, 1); + break; + case 0x6c: + ins(emu, 1); + break; + case 0x6d: + x86emuOp_ins_word(emu); + break; + case 0x6e: + outs(emu, 1); + break; + case 0x6f: + x86emuOp_outs_word(emu); + break; + + case 0x70: + common_jmp_near(emu, ACCESS_FLAG(F_OF)); + break; + case 0x71: + common_jmp_near(emu, !ACCESS_FLAG(F_OF)); + break; + case 0x72: + common_jmp_near(emu, ACCESS_FLAG(F_CF)); + break; + case 0x73: + common_jmp_near(emu, !ACCESS_FLAG(F_CF)); + break; + case 0x74: + common_jmp_near(emu, ACCESS_FLAG(F_ZF)); + break; + case 0x75: + common_jmp_near(emu, !ACCESS_FLAG(F_ZF)); + break; + case 0x76: + common_jmp_near(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); + break; + case 0x77: + common_jmp_near(emu, !ACCESS_FLAG(F_CF) && !ACCESS_FLAG(F_ZF)); + break; + + case 0x78: + common_jmp_near(emu, ACCESS_FLAG(F_SF)); + break; + case 0x79: + common_jmp_near(emu, !ACCESS_FLAG(F_SF)); + break; + case 0x7a: + common_jmp_near(emu, ACCESS_FLAG(F_PF)); + break; + case 0x7b: + common_jmp_near(emu, !ACCESS_FLAG(F_PF)); + break; + case 0x7c: + x86emuOp_jump_near_L(emu); + break; + case 0x7d: + x86emuOp_jump_near_NL(emu); + break; + case 0x7e: + x86emuOp_jump_near_LE(emu); + break; + case 0x7f: + x86emuOp_jump_near_NLE(emu); + break; + + case 0x80: + x86emuOp_opc80_byte_RM_IMM(emu); + break; + case 0x81: + x86emuOp_opc81_word_RM_IMM(emu); + break; + case 0x82: + x86emuOp_opc82_byte_RM_IMM(emu); + break; + case 0x83: + x86emuOp_opc83_word_RM_IMM(emu); + break; + case 0x84: + common_binop_ns_byte_rm_r(emu, test_byte); + break; + case 0x85: + common_binop_ns_word_long_rm_r(emu, test_word, test_long); + break; + case 0x86: + x86emuOp_xchg_byte_RM_R(emu); + break; + case 0x87: + x86emuOp_xchg_word_RM_R(emu); + break; + + case 0x88: + x86emuOp_mov_byte_RM_R(emu); + break; + case 0x89: + x86emuOp_mov_word_RM_R(emu); + break; + case 0x8a: + x86emuOp_mov_byte_R_RM(emu); + break; + case 0x8b: + x86emuOp_mov_word_R_RM(emu); + break; + case 0x8c: + x86emuOp_mov_word_RM_SR(emu); + break; + case 0x8d: + x86emuOp_lea_word_R_M(emu); + break; + case 0x8e: + x86emuOp_mov_word_SR_RM(emu); + break; + case 0x8f: + x86emuOp_pop_RM(emu); + break; + + case 0x90: + /* nop */ + break; + case 0x91: + x86emuOp_xchg_word_AX_CX(emu); + break; + case 0x92: + x86emuOp_xchg_word_AX_DX(emu); + break; + case 0x93: + x86emuOp_xchg_word_AX_BX(emu); + break; + case 0x94: + x86emuOp_xchg_word_AX_SP(emu); + break; + case 0x95: + x86emuOp_xchg_word_AX_BP(emu); + break; + case 0x96: + x86emuOp_xchg_word_AX_SI(emu); + break; + case 0x97: + x86emuOp_xchg_word_AX_DI(emu); + break; + + case 0x98: + x86emuOp_cbw(emu); + break; + case 0x99: + x86emuOp_cwd(emu); + break; + case 0x9a: + x86emuOp_call_far_IMM(emu); + break; + case 0x9b: + /* wait */ + break; + case 0x9c: + x86emuOp_pushf_word(emu); + break; + case 0x9d: + x86emuOp_popf_word(emu); + break; + case 0x9e: + x86emuOp_sahf(emu); + break; + case 0x9f: + x86emuOp_lahf(emu); + break; + + case 0xa0: + x86emuOp_mov_AL_M_IMM(emu); + break; + case 0xa1: + x86emuOp_mov_AX_M_IMM(emu); + break; + case 0xa2: + x86emuOp_mov_M_AL_IMM(emu); + break; + case 0xa3: + x86emuOp_mov_M_AX_IMM(emu); + break; + case 0xa4: + x86emuOp_movs_byte(emu); + break; + case 0xa5: + x86emuOp_movs_word(emu); + break; + case 0xa6: + x86emuOp_cmps_byte(emu); + break; + case 0xa7: + x86emuOp_cmps_word(emu); + break; + + case 0xa8: + test_byte(emu, emu->x86.R_AL, fetch_byte_imm(emu)); + break; + case 0xa9: + x86emuOp_test_AX_IMM(emu); + break; + case 0xaa: + x86emuOp_stos_byte(emu); + break; + case 0xab: + x86emuOp_stos_word(emu); + break; + case 0xac: + x86emuOp_lods_byte(emu); + break; + case 0xad: + x86emuOp_lods_word(emu); + break; + case 0xae: + x86emuOp_scas_byte(emu); + break; + case 0xaf: + x86emuOp_scas_word(emu); + break; + + case 0xb0: + emu->x86.R_AL = fetch_byte_imm(emu); + break; + case 0xb1: + emu->x86.R_CL = fetch_byte_imm(emu); + break; + case 0xb2: + emu->x86.R_DL = fetch_byte_imm(emu); + break; + case 0xb3: + emu->x86.R_BL = fetch_byte_imm(emu); + break; + case 0xb4: + emu->x86.R_AH = fetch_byte_imm(emu); + break; + case 0xb5: + emu->x86.R_CH = fetch_byte_imm(emu); + break; + case 0xb6: + emu->x86.R_DH = fetch_byte_imm(emu); + break; + case 0xb7: + emu->x86.R_BH = fetch_byte_imm(emu); + break; + + case 0xb8: + x86emuOp_mov_word_AX_IMM(emu); + break; + case 0xb9: + x86emuOp_mov_word_CX_IMM(emu); + break; + case 0xba: + x86emuOp_mov_word_DX_IMM(emu); + break; + case 0xbb: + x86emuOp_mov_word_BX_IMM(emu); + break; + case 0xbc: + + x86emuOp_mov_word_SP_IMM(emu); + break; + case 0xbd: + x86emuOp_mov_word_BP_IMM(emu); + break; + case 0xbe: + x86emuOp_mov_word_SI_IMM(emu); + break; + case 0xbf: + x86emuOp_mov_word_DI_IMM(emu); + break; + + case 0xc0: + x86emuOp_opcC0_byte_RM_MEM(emu); + break; + case 0xc1: + x86emuOp_opcC1_word_RM_MEM(emu); + break; + case 0xc2: + x86emuOp_ret_near_IMM(emu); + break; + case 0xc3: + emu->x86.R_IP = pop_word(emu); + break; + case 0xc4: + common_load_far_pointer(emu, &emu->x86.R_ES); + break; + case 0xc5: + common_load_far_pointer(emu, &emu->x86.R_DS); + break; + case 0xc6: + x86emuOp_mov_byte_RM_IMM(emu); + break; + case 0xc7: + x86emuOp_mov_word_RM_IMM(emu); + break; + case 0xc8: + x86emuOp_enter(emu); + break; + case 0xc9: + x86emuOp_leave(emu); + break; + case 0xca: + x86emuOp_ret_far_IMM(emu); + break; + case 0xcb: + x86emuOp_ret_far(emu); + break; + case 0xcc: + x86emuOp_int3(emu); + break; + case 0xcd: + x86emuOp_int_IMM(emu); + break; + case 0xce: + x86emuOp_into(emu); + break; + case 0xcf: + x86emuOp_iret(emu); + break; + + case 0xd0: + x86emuOp_opcD0_byte_RM_1(emu); + break; + case 0xd1: + x86emuOp_opcD1_word_RM_1(emu); + break; + case 0xd2: + x86emuOp_opcD2_byte_RM_CL(emu); + break; + case 0xd3: + x86emuOp_opcD3_word_RM_CL(emu); + break; + case 0xd4: + x86emuOp_aam(emu); + break; + case 0xd5: + x86emuOp_aad(emu); + break; + /* 0xd6 Undocumented SETALC instruction */ + case 0xd7: + x86emuOp_xlat(emu); + break; + case 0xd8: + x86emuOp_esc_coprocess_d8(emu); + break; + case 0xd9: + x86emuOp_esc_coprocess_d9(emu); + break; + case 0xda: + x86emuOp_esc_coprocess_da(emu); + break; + case 0xdb: + x86emuOp_esc_coprocess_db(emu); + break; + case 0xdc: + x86emuOp_esc_coprocess_dc(emu); + break; + case 0xdd: + x86emuOp_esc_coprocess_dd(emu); + break; + case 0xde: + x86emuOp_esc_coprocess_de(emu); + break; + case 0xdf: + x86emuOp_esc_coprocess_df(emu); + break; + + case 0xe0: + x86emuOp_loopne(emu); + break; + case 0xe1: + x86emuOp_loope(emu); + break; + case 0xe2: + x86emuOp_loop(emu); + break; + case 0xe3: + x86emuOp_jcxz(emu); + break; + case 0xe4: + x86emuOp_in_byte_AL_IMM(emu); + break; + case 0xe5: + x86emuOp_in_word_AX_IMM(emu); + break; + case 0xe6: + x86emuOp_out_byte_IMM_AL(emu); + break; + case 0xe7: + x86emuOp_out_word_IMM_AX(emu); + break; + + case 0xe8: + x86emuOp_call_near_IMM(emu); + break; + case 0xe9: + x86emuOp_jump_near_IMM(emu); + break; + case 0xea: + x86emuOp_jump_far_IMM(emu); + break; + case 0xeb: + x86emuOp_jump_byte_IMM(emu); + break; + case 0xec: + x86emuOp_in_byte_AL_DX(emu); + break; + case 0xed: + x86emuOp_in_word_AX_DX(emu); + break; + case 0xee: + x86emuOp_out_byte_DX_AL(emu); + break; + case 0xef: + x86emuOp_out_word_DX_AX(emu); + break; + + case 0xf0: + x86emuOp_lock(emu); + break; + case 0xf2: + emu->x86.mode |= SYSMODE_PREFIX_REPNE; + break; + case 0xf3: + emu->x86.mode |= SYSMODE_PREFIX_REPE; + break; + case 0xf4: + x86emu_halt_sys(emu); + break; + case 0xf5: + x86emuOp_cmc(emu); + break; + case 0xf6: + x86emuOp_opcF6_byte_RM(emu); + break; + case 0xf7: + x86emuOp_opcF7_word_RM(emu); + break; + + case 0xf8: + CLEAR_FLAG(F_CF); + break; + case 0xf9: + SET_FLAG(F_CF); + break; + case 0xfa: + CLEAR_FLAG(F_IF); + break; + case 0xfb: + SET_FLAG(F_IF); + break; + case 0xfc: + CLEAR_FLAG(F_DF); + break; + case 0xfd: + SET_FLAG(F_DF); + break; + case 0xfe: + x86emuOp_opcFE_byte_RM(emu); + break; + case 0xff: + x86emuOp_opcFF_word_RM(emu); + break; + default: + x86emu_halt_sys(emu); + break; + } + if (op1 != 0x26 && op1 != 0x2e && op1 != 0x36 && op1 != 0x3e && + (op1 | 3) != 0x67) + emu->x86.mode &= ~SYSMODE_CLRMASK; +} + +static void +common_jmp_long(struct x86emu *emu, int cond) +{ + int16_t target; + + target = (int16_t) fetch_word_imm(emu); + target += (int16_t) emu->x86.R_IP; + if (cond) + emu->x86.R_IP = (uint16_t) target; +} + +static void +common_set_byte(struct x86emu *emu, int cond) +{ + uint32_t destoffset; + uint8_t *destreg, destval; + + fetch_decode_modrm(emu); + destval = cond ? 0x01 : 0x00; + if (emu->cur_mod != 3) { + destoffset = decode_rl_address(emu); + store_data_byte(emu, destoffset, destval); + } else { + destreg = decode_rl_byte_register(emu); + *destreg = destval; + } +} + +static void +common_bitstring32(struct x86emu *emu, int op) +{ + int bit; + uint32_t srcval, *shiftreg, mask; + + fetch_decode_modrm(emu); + shiftreg = decode_rh_long_register(emu); + srcval = decode_and_fetch_long_disp(emu, (int16_t) *shiftreg >> 5); + bit = *shiftreg & 0x1F; + mask = 0x1 << bit; + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + + switch (op) { + case 0: + break; + case 1: + write_back_long(emu, srcval | mask); + break; + case 2: + write_back_long(emu, srcval & ~mask); + break; + case 3: + write_back_long(emu, srcval ^ mask); + break; + } +} + +static void +common_bitstring16(struct x86emu *emu, int op) +{ + int bit; + uint16_t srcval, *shiftreg, mask; + + fetch_decode_modrm(emu); + shiftreg = decode_rh_word_register(emu); + srcval = decode_and_fetch_word_disp(emu, (int16_t) *shiftreg >> 4); + bit = *shiftreg & 0xF; + mask = 0x1 << bit; + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + + switch (op) { + case 0: + break; + case 1: + write_back_word(emu, srcval | mask); + break; + case 2: + write_back_word(emu, srcval & ~mask); + break; + case 3: + write_back_word(emu, srcval ^ mask); + break; + } +} + +static void +common_bitstring(struct x86emu *emu, int op) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + common_bitstring32(emu, op); + else + common_bitstring16(emu, op); +} + +static void +common_bitsearch32(struct x86emu *emu, int diff) +{ + uint32_t srcval, *dstreg; + + fetch_decode_modrm(emu); + dstreg = decode_rh_long_register(emu); + srcval = decode_and_fetch_long(emu); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 32; *dstreg += diff) { + if ((srcval >> *dstreg) & 1) + break; + } +} + +static void +common_bitsearch16(struct x86emu *emu, int diff) +{ + uint16_t srcval, *dstreg; + + fetch_decode_modrm(emu); + dstreg = decode_rh_word_register(emu); + srcval = decode_and_fetch_word(emu); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 16; *dstreg += diff) { + if ((srcval >> *dstreg) & 1) + break; + } +} + +static void +common_bitsearch(struct x86emu *emu, int diff) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + common_bitsearch32(emu, diff); + else + common_bitsearch16(emu, diff); +} + +static void +common_shift32(struct x86emu *emu, int shift_left, int use_cl) +{ + uint8_t shift; + uint32_t destval, *shiftreg; + + fetch_decode_modrm(emu); + shiftreg = decode_rh_long_register(emu); + if (use_cl) { + destval = decode_and_fetch_long(emu); + shift = emu->x86.R_CL; + } else { + destval = decode_and_fetch_long_imm8(emu, &shift); + } + if (shift_left) + destval = shld_long(emu, destval, *shiftreg, shift); + else + destval = shrd_long(emu, destval, *shiftreg, shift); + write_back_long(emu, destval); +} + +static void +common_shift16(struct x86emu *emu, int shift_left, int use_cl) +{ + uint8_t shift; + uint16_t destval, *shiftreg; + + fetch_decode_modrm(emu); + shiftreg = decode_rh_word_register(emu); + if (use_cl) { + destval = decode_and_fetch_word(emu); + shift = emu->x86.R_CL; + } else { + destval = decode_and_fetch_word_imm8(emu, &shift); + } + if (shift_left) + destval = shld_word(emu, destval, *shiftreg, shift); + else + destval = shrd_word(emu, destval, *shiftreg, shift); + write_back_word(emu, destval); +} + +static void +common_shift(struct x86emu *emu, int shift_left, int use_cl) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + common_shift32(emu, shift_left, use_cl); + else + common_shift16(emu, shift_left, use_cl); +} + +/*----------------------------- Implementation ----------------------------*/ +#define xorl(a,b) ((a) && !(b)) || (!(a) && (b)) + + +/* + * REMARKS: + * Handles opcode 0x0f,0x31 + */ +static void +x86emuOp2_rdtsc(struct x86emu *emu) +{ + emu->x86.R_EAX = emu->cur_cycles & 0xffffffff; + emu->x86.R_EDX = emu->cur_cycles >> 32; +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xa0 + */ +static void +x86emuOp2_push_FS(struct x86emu *emu) +{ + push_word(emu, emu->x86.R_FS); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xa1 + */ +static void +x86emuOp2_pop_FS(struct x86emu *emu) +{ + emu->x86.R_FS = pop_word(emu); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xa1 + */ +#if defined(__i386__) || defined(__amd64__) +static void +hw_cpuid(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) +{ + __asm__ __volatile__("cpuid" + : "=a" (*a), "=b" (*b), + "=c" (*c), "=d" (*d) + : "a" (*a), "c" (*c) + : "cc"); +} +#endif +static void +x86emuOp2_cpuid(struct x86emu *emu) +{ +#if defined(__i386__) || defined(__amd64__) + hw_cpuid(&emu->x86.R_EAX, &emu->x86.R_EBX, &emu->x86.R_ECX, + &emu->x86.R_EDX); +#endif + switch (emu->x86.R_EAX) { + case 0: + emu->x86.R_EAX = 1; +#if !defined(__i386__) && !defined(__amd64__) + /* "GenuineIntel" */ + emu->x86.R_EBX = 0x756e6547; + emu->x86.R_EDX = 0x49656e69; + emu->x86.R_ECX = 0x6c65746e; +#endif + break; + case 1: +#if !defined(__i386__) && !defined(__amd64__) + emu->x86.R_EAX = 0x00000480; + emu->x86.R_EBX = emu->x86.R_ECX = 0; + emu->x86.R_EDX = 0x00000002; +#else + emu->x86.R_EDX &= 0x00000012; +#endif + break; + default: + emu->x86.R_EAX = emu->x86.R_EBX = emu->x86.R_ECX = + emu->x86.R_EDX = 0; + break; + } +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xa3 + */ +static void +x86emuOp2_bt_R(struct x86emu *emu) +{ + common_bitstring(emu, 0); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xa4 + */ +static void +x86emuOp2_shld_IMM(struct x86emu *emu) +{ + common_shift(emu, 1, 0); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xa5 + */ +static void +x86emuOp2_shld_CL(struct x86emu *emu) +{ + common_shift(emu, 1, 1); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xa8 + */ +static void +x86emuOp2_push_GS(struct x86emu *emu) +{ + push_word(emu, emu->x86.R_GS); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xa9 + */ +static void +x86emuOp2_pop_GS(struct x86emu *emu) +{ + emu->x86.R_GS = pop_word(emu); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xab + */ +static void +x86emuOp2_bts_R(struct x86emu *emu) +{ + common_bitstring(emu, 1); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xac + */ +static void +x86emuOp2_shrd_IMM(struct x86emu *emu) +{ + common_shift(emu, 0, 0); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xad + */ +static void +x86emuOp2_shrd_CL(struct x86emu *emu) +{ + common_shift(emu, 0, 1); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xaf + */ +static void +x86emuOp2_32_imul_R_RM(struct x86emu *emu) +{ + uint32_t *destreg, srcval; + uint64_t res; + + fetch_decode_modrm(emu); + destreg = decode_rh_long_register(emu); + srcval = decode_and_fetch_long(emu); + res = (int32_t) *destreg * (int32_t)srcval; + if (res > 0xffffffff) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (uint32_t) res; +} + +static void +x86emuOp2_16_imul_R_RM(struct x86emu *emu) +{ + uint16_t *destreg, srcval; + uint32_t res; + + fetch_decode_modrm(emu); + destreg = decode_rh_word_register(emu); + srcval = decode_and_fetch_word(emu); + res = (int16_t) * destreg * (int16_t)srcval; + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (uint16_t) res; +} + +static void +x86emuOp2_imul_R_RM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp2_32_imul_R_RM(emu); + else + x86emuOp2_16_imul_R_RM(emu); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xb2 + */ +static void +x86emuOp2_lss_R_IMM(struct x86emu *emu) +{ + common_load_far_pointer(emu, &emu->x86.R_SS); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xb3 + */ +static void +x86emuOp2_btr_R(struct x86emu *emu) +{ + common_bitstring(emu, 2); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xb4 + */ +static void +x86emuOp2_lfs_R_IMM(struct x86emu *emu) +{ + common_load_far_pointer(emu, &emu->x86.R_FS); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xb5 + */ +static void +x86emuOp2_lgs_R_IMM(struct x86emu *emu) +{ + common_load_far_pointer(emu, &emu->x86.R_GS); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xb6 + */ +static void +x86emuOp2_32_movzx_byte_R_RM(struct x86emu *emu) +{ + uint32_t *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_long_register(emu); + *destreg = decode_and_fetch_byte(emu); +} + +static void +x86emuOp2_16_movzx_byte_R_RM(struct x86emu *emu) +{ + uint16_t *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_word_register(emu); + *destreg = decode_and_fetch_byte(emu); +} + +static void +x86emuOp2_movzx_byte_R_RM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp2_32_movzx_byte_R_RM(emu); + else + x86emuOp2_16_movzx_byte_R_RM(emu); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xb7 + */ +static void +x86emuOp2_movzx_word_R_RM(struct x86emu *emu) +{ + uint32_t *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_long_register(emu); + *destreg = decode_and_fetch_word(emu); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xba + */ +static void +x86emuOp2_32_btX_I(struct x86emu *emu) +{ + int bit; + uint32_t srcval, mask; + uint8_t shift; + + fetch_decode_modrm(emu); + if (emu->cur_rh < 4) + x86emu_halt_sys(emu); + + srcval = decode_and_fetch_long_imm8(emu, &shift); + bit = shift & 0x1F; + mask = (0x1 << bit); + + switch (emu->cur_rh) { + case 5: + write_back_long(emu, srcval | mask); + break; + case 6: + write_back_long(emu, srcval & ~mask); + break; + case 7: + write_back_long(emu, srcval ^ mask); + break; + } + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); +} + +static void +x86emuOp2_16_btX_I(struct x86emu *emu) +{ + int bit; + + uint16_t srcval, mask; + uint8_t shift; + + fetch_decode_modrm(emu); + if (emu->cur_rh < 4) + x86emu_halt_sys(emu); + + srcval = decode_and_fetch_word_imm8(emu, &shift); + bit = shift & 0xF; + mask = (0x1 << bit); + switch (emu->cur_rh) { + case 5: + write_back_word(emu, srcval | mask); + break; + case 6: + write_back_word(emu, srcval & ~mask); + break; + case 7: + write_back_word(emu, srcval ^ mask); + break; + } + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); +} + +static void +x86emuOp2_btX_I(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp2_32_btX_I(emu); + else + x86emuOp2_16_btX_I(emu); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xbb + */ +static void +x86emuOp2_btc_R(struct x86emu *emu) +{ + common_bitstring(emu, 3); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xbc + */ +static void +x86emuOp2_bsf(struct x86emu *emu) +{ + common_bitsearch(emu, +1); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xbd + */ +static void +x86emuOp2_bsr(struct x86emu *emu) +{ + common_bitsearch(emu, -1); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xbe + */ +static void +x86emuOp2_32_movsx_byte_R_RM(struct x86emu *emu) +{ + uint32_t *destreg; + + destreg = decode_rh_long_register(emu); + *destreg = (int32_t)(int8_t)decode_and_fetch_byte(emu); +} + +static void +x86emuOp2_16_movsx_byte_R_RM(struct x86emu *emu) +{ + uint16_t *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_word_register(emu); + *destreg = (int16_t)(int8_t)decode_and_fetch_byte(emu); +} + +static void +x86emuOp2_movsx_byte_R_RM(struct x86emu *emu) +{ + if (emu->x86.mode & SYSMODE_PREFIX_DATA) + x86emuOp2_32_movsx_byte_R_RM(emu); + else + x86emuOp2_16_movsx_byte_R_RM(emu); +} + +/* + * REMARKS: + * Handles opcode 0x0f,0xbf + */ +static void +x86emuOp2_movsx_word_R_RM(struct x86emu *emu) +{ + uint32_t *destreg; + + fetch_decode_modrm(emu); + destreg = decode_rh_long_register(emu); + *destreg = (int32_t)(int16_t)decode_and_fetch_word(emu); +} + +static void +x86emu_exec_two_byte(struct x86emu * emu) +{ + uint8_t op2; + + op2 = fetch_byte_imm(emu); + + switch (op2) { + /* 0x00 Group F (ring 0 PM) */ + /* 0x01 Group G (ring 0 PM) */ + /* 0x02 lar (ring 0 PM) */ + /* 0x03 lsl (ring 0 PM) */ + /* 0x05 loadall (undocumented) */ + /* 0x06 clts (ring 0 PM) */ + /* 0x07 loadall (undocumented) */ + /* 0x08 invd (ring 0 PM) */ + /* 0x09 wbinvd (ring 0 PM) */ + + /* 0x20 mov reg32(op2); break;creg (ring 0 PM) */ + /* 0x21 mov reg32(op2); break;dreg (ring 0 PM) */ + /* 0x22 mov creg(op2); break;reg32 (ring 0 PM) */ + /* 0x23 mov dreg(op2); break;reg32 (ring 0 PM) */ + /* 0x24 mov reg32(op2); break;treg (ring 0 PM) */ + /* 0x26 mov treg(op2); break;reg32 (ring 0 PM) */ + + case 0x31: + x86emuOp2_rdtsc(emu); + break; + + case 0x80: + common_jmp_long(emu, ACCESS_FLAG(F_OF)); + break; + case 0x81: + common_jmp_long(emu, !ACCESS_FLAG(F_OF)); + break; + case 0x82: + common_jmp_long(emu, ACCESS_FLAG(F_CF)); + break; + case 0x83: + common_jmp_long(emu, !ACCESS_FLAG(F_CF)); + break; + case 0x84: + common_jmp_long(emu, ACCESS_FLAG(F_ZF)); + break; + case 0x85: + common_jmp_long(emu, !ACCESS_FLAG(F_ZF)); + break; + case 0x86: + common_jmp_long(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); + break; + case 0x87: + common_jmp_long(emu, !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))); + break; + case 0x88: + common_jmp_long(emu, ACCESS_FLAG(F_SF)); + break; + case 0x89: + common_jmp_long(emu, !ACCESS_FLAG(F_SF)); + break; + case 0x8a: + common_jmp_long(emu, ACCESS_FLAG(F_PF)); + break; + case 0x8b: + common_jmp_long(emu, !ACCESS_FLAG(F_PF)); + break; + case 0x8c: + common_jmp_long(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))); + break; + case 0x8d: + common_jmp_long(emu, !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)))); + break; + case 0x8e: + common_jmp_long(emu, + (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF))); + break; + case 0x8f: + common_jmp_long(emu, + !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF))); + break; + + case 0x90: + common_set_byte(emu, ACCESS_FLAG(F_OF)); + break; + case 0x91: + common_set_byte(emu, !ACCESS_FLAG(F_OF)); + break; + case 0x92: + common_set_byte(emu, ACCESS_FLAG(F_CF)); + break; + case 0x93: + common_set_byte(emu, !ACCESS_FLAG(F_CF)); + break; + case 0x94: + common_set_byte(emu, ACCESS_FLAG(F_ZF)); + break; + case 0x95: + common_set_byte(emu, !ACCESS_FLAG(F_ZF)); + break; + case 0x96: + common_set_byte(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); + break; + case 0x97: + common_set_byte(emu, !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))); + break; + case 0x98: + common_set_byte(emu, ACCESS_FLAG(F_SF)); + break; + case 0x99: + common_set_byte(emu, !ACCESS_FLAG(F_SF)); + break; + case 0x9a: + common_set_byte(emu, ACCESS_FLAG(F_PF)); + break; + case 0x9b: + common_set_byte(emu, !ACCESS_FLAG(F_PF)); + break; + case 0x9c: + common_set_byte(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))); + break; + case 0x9d: + common_set_byte(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))); + break; + case 0x9e: + common_set_byte(emu, + (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || + ACCESS_FLAG(F_ZF))); + break; + case 0x9f: + common_set_byte(emu, + !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || + ACCESS_FLAG(F_ZF))); + break; + + case 0xa0: + x86emuOp2_push_FS(emu); + break; + case 0xa1: + x86emuOp2_pop_FS(emu); + break; + case 0xa2: + x86emuOp2_cpuid(emu); + break; + case 0xa3: + x86emuOp2_bt_R(emu); + break; + case 0xa4: + x86emuOp2_shld_IMM(emu); + break; + case 0xa5: + x86emuOp2_shld_CL(emu); + break; + case 0xa8: + x86emuOp2_push_GS(emu); + break; + case 0xa9: + x86emuOp2_pop_GS(emu); + break; + case 0xab: + x86emuOp2_bts_R(emu); + break; + case 0xac: + x86emuOp2_shrd_IMM(emu); + break; + case 0xad: + x86emuOp2_shrd_CL(emu); + break; + case 0xaf: + x86emuOp2_imul_R_RM(emu); + break; + + /* 0xb0 TODO: cmpxchg */ + /* 0xb1 TODO: cmpxchg */ + case 0xb2: + x86emuOp2_lss_R_IMM(emu); + break; + case 0xb3: + x86emuOp2_btr_R(emu); + break; + case 0xb4: + x86emuOp2_lfs_R_IMM(emu); + break; + case 0xb5: + x86emuOp2_lgs_R_IMM(emu); + break; + case 0xb6: + x86emuOp2_movzx_byte_R_RM(emu); + break; + case 0xb7: + x86emuOp2_movzx_word_R_RM(emu); + break; + case 0xba: + x86emuOp2_btX_I(emu); + break; + case 0xbb: + x86emuOp2_btc_R(emu); + break; + case 0xbc: + x86emuOp2_bsf(emu); + break; + case 0xbd: + x86emuOp2_bsr(emu); + break; + case 0xbe: + x86emuOp2_movsx_byte_R_RM(emu); + break; + case 0xbf: + x86emuOp2_movsx_word_R_RM(emu); + break; + + /* 0xc0 TODO: xadd */ + /* 0xc1 TODO: xadd */ + /* 0xc8 TODO: bswap */ + /* 0xc9 TODO: bswap */ + /* 0xca TODO: bswap */ + /* 0xcb TODO: bswap */ + /* 0xcc TODO: bswap */ + /* 0xcd TODO: bswap */ + /* 0xce TODO: bswap */ + /* 0xcf TODO: bswap */ + + default: + x86emu_halt_sys(emu); + break; + } +} + +/* +* Carry Chain Calculation +* +* This represents a somewhat expensive calculation which is +* apparently required to emulate the setting of the OF and AF flag. +* The latter is not so important, but the former is. The overflow +* flag is the XOR of the top two bits of the carry chain for an +* addition (similar for subtraction). Since we do not want to +* simulate the addition in a bitwise manner, we try to calculate the +* carry chain given the two operands and the result. +* +* So, given the following table, which represents the addition of two +* bits, we can derive a formula for the carry chain. +* +* a b cin r cout +* 0 0 0 0 0 +* 0 0 1 1 0 +* 0 1 0 1 0 +* 0 1 1 0 1 +* 1 0 0 1 0 +* 1 0 1 0 1 +* 1 1 0 0 1 +* 1 1 1 1 1 +* +* Construction of table for cout: +* +* ab +* r \ 00 01 11 10 +* |------------------ +* 0 | 0 1 1 1 +* 1 | 0 0 1 0 +* +* By inspection, one gets: cc = ab + r'(a + b) +* +* That represents alot of operations, but NO CHOICE.... +* +* Borrow Chain Calculation. +* +* The following table represents the subtraction of two bits, from +* which we can derive a formula for the borrow chain. +* +* a b bin r bout +* 0 0 0 0 0 +* 0 0 1 1 1 +* 0 1 0 1 1 +* 0 1 1 0 1 +* 1 0 0 1 0 +* 1 0 1 0 0 +* 1 1 0 0 0 +* 1 1 1 1 1 +* +* Construction of table for cout: +* +* ab +* r \ 00 01 11 10 +* |------------------ +* 0 | 0 1 0 0 +* 1 | 1 1 1 0 +* +* By inspection, one gets: bc = a'b + r(a' + b) +* + */ + +/*------------------------- Global Variables ------------------------------*/ + +static uint32_t x86emu_parity_tab[8] = +{ + 0x96696996, + 0x69969669, + 0x69969669, + 0x96696996, + 0x69969669, + 0x96696996, + 0x96696996, + 0x69969669, +}; +#define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0) +#define XOR2(x) (((x) ^ ((x)>>1)) & 0x1) + + +/* + * REMARKS: + * Implements the AAA instruction and side effects. + */ +static uint16_t +aaa_word(struct x86emu *emu, uint16_t d) +{ + uint16_t res; + if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) { + d += 0x6; + d += 0x100; + SET_FLAG(F_AF); + SET_FLAG(F_CF); + } else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + } + res = (uint16_t) (d & 0xFF0F); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/* + * REMARKS: + * Implements the AAA instruction and side effects. + */ +static uint16_t +aas_word(struct x86emu *emu, uint16_t d) +{ + uint16_t res; + if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) { + d -= 0x6; + d -= 0x100; + SET_FLAG(F_AF); + SET_FLAG(F_CF); + } else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + } + res = (uint16_t) (d & 0xFF0F); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/* + * REMARKS: + * Implements the AAD instruction and side effects. + */ +static uint16_t +aad_word(struct x86emu *emu, uint16_t d) +{ + uint16_t l; + uint8_t hb, lb; + + hb = (uint8_t) ((d >> 8) & 0xff); + lb = (uint8_t) ((d & 0xff)); + l = (uint16_t) ((lb + 10 * hb) & 0xFF); + + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(l & 0x80, F_SF); + CONDITIONAL_SET_FLAG(l == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF); + return l; +} + +/* + * REMARKS: + * Implements the AAM instruction and side effects. + */ +static uint16_t +aam_word(struct x86emu *emu, uint8_t d) +{ + uint16_t h, l; + + h = (uint16_t) (d / 10); + l = (uint16_t) (d % 10); + l |= (uint16_t) (h << 8); + + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(l & 0x80, F_SF); + CONDITIONAL_SET_FLAG(l == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF); + return l; +} + +/* + * REMARKS: + * Implements the ADC instruction and side effects. + */ +static uint8_t +adc_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t cc; + + if (ACCESS_FLAG(F_CF)) + res = 1 + d + s; + else + res = d + s; + + CONDITIONAL_SET_FLAG(res & 0x100, F_CF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the ADC instruction and side effects. + */ +static uint16_t +adc_word(struct x86emu *emu, uint16_t d, uint16_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t cc; + + if (ACCESS_FLAG(F_CF)) + res = 1 + d + s; + else + res = d + s; + + CONDITIONAL_SET_FLAG(res & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the ADC instruction and side effects. + */ +static uint32_t +adc_long(struct x86emu *emu, uint32_t d, uint32_t s) +{ + uint32_t lo; /* all operands in native machine order */ + uint32_t hi; + uint32_t res; + uint32_t cc; + + if (ACCESS_FLAG(F_CF)) { + lo = 1 + (d & 0xFFFF) + (s & 0xFFFF); + res = 1 + d + s; + } else { + lo = (d & 0xFFFF) + (s & 0xFFFF); + res = d + s; + } + hi = (lo >> 16) + (d >> 16) + (s >> 16); + + CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return res; +} + +/* + * REMARKS: + * Implements the ADD instruction and side effects. + */ +static uint8_t +add_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t cc; + + res = d + s; + CONDITIONAL_SET_FLAG(res & 0x100, F_CF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the ADD instruction and side effects. + */ +static uint16_t +add_word(struct x86emu *emu, uint16_t d, uint16_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t cc; + + res = d + s; + CONDITIONAL_SET_FLAG(res & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the ADD instruction and side effects. + */ +static uint32_t +add_long(struct x86emu *emu, uint32_t d, uint32_t s) +{ + uint32_t lo; /* all operands in native machine order */ + uint32_t hi; + uint32_t res; + uint32_t cc; + + lo = (d & 0xFFFF) + (s & 0xFFFF); + res = d + s; + hi = (lo >> 16) + (d >> 16) + (s >> 16); + + CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + + return res; +} + +/* + * REMARKS: + * Implements the AND instruction and side effects. + */ +static uint8_t +and_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint8_t res; /* all operands in native machine order */ + + res = d & s; + + /* set the flags */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res), F_PF); + return res; +} + +/* + * REMARKS: + * Implements the AND instruction and side effects. + */ +static uint16_t +and_word(struct x86emu *emu, uint16_t d, uint16_t s) +{ + uint16_t res; /* all operands in native machine order */ + + res = d & s; + + /* set the flags */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/* + * REMARKS: + * Implements the AND instruction and side effects. + */ +static uint32_t +and_long(struct x86emu *emu, uint32_t d, uint32_t s) +{ + uint32_t res; /* all operands in native machine order */ + + res = d & s; + + /* set the flags */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/* + * REMARKS: + * Implements the CMP instruction and side effects. + */ +static uint8_t +cmp_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + res = d - s; + CLEAR_FLAG(F_CF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return d; +} + +static void +cmp_byte_no_return(struct x86emu *emu, uint8_t d, uint8_t s) +{ + cmp_byte(emu, d, s); +} + +/* + * REMARKS: + * Implements the CMP instruction and side effects. + */ +static uint16_t +cmp_word(struct x86emu *emu, uint16_t d, uint16_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return d; +} + +static void +cmp_word_no_return(struct x86emu *emu, uint16_t d, uint16_t s) +{ + cmp_word(emu, d, s); +} + +/* + * REMARKS: + * Implements the CMP instruction and side effects. + */ +static uint32_t +cmp_long(struct x86emu *emu, uint32_t d, uint32_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return d; +} + +static void +cmp_long_no_return(struct x86emu *emu, uint32_t d, uint32_t s) +{ + cmp_long(emu, d, s); +} + +/* + * REMARKS: + * Implements the DAA instruction and side effects. + */ +static uint8_t +daa_byte(struct x86emu *emu, uint8_t d) +{ + uint32_t res = d; + if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) { + res += 6; + SET_FLAG(F_AF); + } + if (res > 0x9F || ACCESS_FLAG(F_CF)) { + res += 0x60; + SET_FLAG(F_CF); + } + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the DAS instruction and side effects. + */ +static uint8_t +das_byte(struct x86emu *emu, uint8_t d) +{ + if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) { + d -= 6; + SET_FLAG(F_AF); + } + if (d > 0x9F || ACCESS_FLAG(F_CF)) { + d -= 0x60; + SET_FLAG(F_CF); + } + CONDITIONAL_SET_FLAG(d & 0x80, F_SF); + CONDITIONAL_SET_FLAG(d == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF); + return d; +} + +/* + * REMARKS: + * Implements the DEC instruction and side effects. + */ +static uint8_t +dec_byte(struct x86emu *emu, uint8_t d) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + res = d - 1; + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + /* based on sub_byte, uses s==1. */ + bc = (res & (~d | 1)) | (~d & 1); + /* carry flag unchanged */ + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the DEC instruction and side effects. + */ +static uint16_t +dec_word(struct x86emu *emu, uint16_t d) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + res = d - 1; + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + /* based on the sub_byte routine, with s==1 */ + bc = (res & (~d | 1)) | (~d & 1); + /* carry flag unchanged */ + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the DEC instruction and side effects. + */ +static uint32_t +dec_long(struct x86emu *emu, uint32_t d) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + res = d - 1; + + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | 1)) | (~d & 1); + /* carry flag unchanged */ + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/* + * REMARKS: + * Implements the INC instruction and side effects. + */ +static uint8_t +inc_byte(struct x86emu *emu, uint8_t d) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t cc; + + res = d + 1; + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = ((1 & d) | (~res)) & (1 | d); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the INC instruction and side effects. + */ +static uint16_t +inc_word(struct x86emu *emu, uint16_t d) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t cc; + + res = d + 1; + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (1 & d) | ((~res) & (1 | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the INC instruction and side effects. + */ +static uint32_t +inc_long(struct x86emu *emu, uint32_t d) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t cc; + + res = d + 1; + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (1 & d) | ((~res) & (1 | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return res; +} + +/* + * REMARKS: + * Implements the OR instruction and side effects. + */ +static uint8_t +or_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint8_t res; /* all operands in native machine order */ + + res = d | s; + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res), F_PF); + return res; +} + +/* + * REMARKS: + * Implements the OR instruction and side effects. + */ +static uint16_t +or_word(struct x86emu *emu, uint16_t d, uint16_t s) +{ + uint16_t res; /* all operands in native machine order */ + + res = d | s; + /* set the carry flag to be bit 8 */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/* + * REMARKS: + * Implements the OR instruction and side effects. + */ +static uint32_t +or_long(struct x86emu *emu, uint32_t d, uint32_t s) +{ + uint32_t res; /* all operands in native machine order */ + + res = d | s; + + /* set the carry flag to be bit 8 */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/* + * REMARKS: + * Implements the OR instruction and side effects. + */ +static uint8_t +neg_byte(struct x86emu *emu, uint8_t s) +{ + uint8_t res; + uint8_t bc; + + CONDITIONAL_SET_FLAG(s != 0, F_CF); + res = (uint8_t) - s; + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res), F_PF); + /* calculate the borrow chain --- modified such that d=0. + * substitutiing d=0 into bc= res&(~d|s)|(~d&s); (the one used for + * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and + * res&0xfff... == res. Similarly ~d&s == s. So the simplified + * result is: */ + bc = res | s; + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/* + * REMARKS: + * Implements the OR instruction and side effects. + */ +static uint16_t +neg_word(struct x86emu *emu, uint16_t s) +{ + uint16_t res; + uint16_t bc; + + CONDITIONAL_SET_FLAG(s != 0, F_CF); + res = (uint16_t) - s; + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain --- modified such that d=0. + * substitutiing d=0 into bc= res&(~d|s)|(~d&s); (the one used for + * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and + * res&0xfff... == res. Similarly ~d&s == s. So the simplified + * result is: */ + bc = res | s; + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/* + * REMARKS: + * Implements the OR instruction and side effects. + */ +static uint32_t +neg_long(struct x86emu *emu, uint32_t s) +{ + uint32_t res; + uint32_t bc; + + CONDITIONAL_SET_FLAG(s != 0, F_CF); + res = (uint32_t) - s; + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain --- modified such that d=0. + * substitutiing d=0 into bc= res&(~d|s)|(~d&s); (the one used for + * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and + * res&0xfff... == res. Similarly ~d&s == s. So the simplified + * result is: */ + bc = res | s; + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/* + * REMARKS: + * Implements the RCL instruction and side effects. + */ +static uint8_t +rcl_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + unsigned int res, cnt, mask, cf; + + /* s is the rotate distance. It varies from 0 - 8. */ + /* have + * + * CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 + * + * want to rotate through the carry by "s" bits. We could loop, but + * that's inefficient. So the width is 9, and we split into three + * parts: + * + * The new carry flag (was B_n) the stuff in B_n-1 .. B_0 the stuff in + * B_7 .. B_n+1 + * + * The new rotate is done mod 9, and given this, for a rotation of n bits + * (mod 9) the new carry flag is then located n bits from the MSB. + * The low part is then shifted up cnt bits, and the high part is or'd + * in. Using CAPS for new values, and lowercase for the original + * values, this can be expressed as: + * + * IF n > 0 1) CF <- b_(8-n) 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 + * 3) B_(n-1) <- cf 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */ + res = d; + if ((cnt = s % 9) != 0) { + /* extract the new CARRY FLAG. */ + /* CF <- b_(8-n) */ + cf = (d >> (8 - cnt)) & 0x1; + + /* get the low stuff which rotated into the range B_7 .. B_cnt */ + /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */ + /* note that the right hand side done by the mask */ + res = (d << cnt) & 0xff; + + /* now the high stuff which rotated around into the positions + * B_cnt-2 .. B_0 */ + /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */ + /* shift it downward, 7-(n-2) = 9-n positions. and mask off + * the result before or'ing in. */ + mask = (1 << (cnt - 1)) - 1; + res |= (d >> (9 - cnt)) & mask; + + /* if the carry flag was set, or it in. */ + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + /* B_(n-1) <- cf */ + res |= 1 << (cnt - 1); + } + /* set the new carry flag, based on the variable "cf" */ + CONDITIONAL_SET_FLAG(cf, F_CF); + /* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and + * the most significant bit. Blecck. */ + /* parenthesized this expression since it appears to be + * causing OF to be misset */ + CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)), + F_OF); + + } + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the RCL instruction and side effects. + */ +static uint16_t +rcl_word(struct x86emu *emu, uint16_t d, uint8_t s) +{ + unsigned int res, cnt, mask, cf; + + res = d; + if ((cnt = s % 17) != 0) { + cf = (d >> (16 - cnt)) & 0x1; + res = (d << cnt) & 0xffff; + mask = (1 << (cnt - 1)) - 1; + res |= (d >> (17 - cnt)) & mask; + if (ACCESS_FLAG(F_CF)) { + res |= 1 << (cnt - 1); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)), + F_OF); + } + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the RCL instruction and side effects. + */ +static uint32_t +rcl_long(struct x86emu *emu, uint32_t d, uint8_t s) +{ + uint32_t res, cnt, mask, cf; + + res = d; + if ((cnt = s % 33) != 0) { + cf = (d >> (32 - cnt)) & 0x1; + res = (d << cnt) & 0xffffffff; + mask = (1 << (cnt - 1)) - 1; + res |= (d >> (33 - cnt)) & mask; + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + res |= 1 << (cnt - 1); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), + F_OF); + } + return res; +} + +/* + * REMARKS: + * Implements the RCR instruction and side effects. + */ +static uint8_t +rcr_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint32_t res, cnt; + uint32_t mask, cf, ocf = 0; + + /* rotate right through carry */ + /* s is the rotate distance. It varies from 0 - 8. d is the byte + * object rotated. + * + * have + * + * CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 + * + * The new rotate is done mod 9, and given this, for a rotation of n bits + * (mod 9) the new carry flag is then located n bits from the LSB. + * The low part is then shifted up cnt bits, and the high part is or'd + * in. Using CAPS for new values, and lowercase for the original + * values, this can be expressed as: + * + * IF n > 0 1) CF <- b_(n-1) 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) + * 3) B_(8-n) <- cf 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */ + res = d; + if ((cnt = s % 9) != 0) { + /* extract the new CARRY FLAG. */ + /* CF <- b_(n-1) */ + if (cnt == 1) { + cf = d & 0x1; + /* note hackery here. Access_flag(..) evaluates to + * either 0 if flag not set non-zero if flag is set. + * doing access_flag(..) != 0 casts that into either + * 0..1 in any representation of the flags register + * (i.e. packed bit array or unpacked.) */ + ocf = ACCESS_FLAG(F_CF) != 0; + } else + cf = (d >> (cnt - 1)) & 0x1; + + /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */ + /* note that the right hand side done by the mask This is + * effectively done by shifting the object to the right. The + * result must be masked, in case the object came in and was + * treated as a negative number. Needed??? */ + + mask = (1 << (8 - cnt)) - 1; + res = (d >> cnt) & mask; + + /* now the high stuff which rotated around into the positions + * B_cnt-2 .. B_0 */ + /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */ + /* shift it downward, 7-(n-2) = 9-n positions. and mask off + * the result before or'ing in. */ + res |= (d << (9 - cnt)); + + /* if the carry flag was set, or it in. */ + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + /* B_(8-n) <- cf */ + res |= 1 << (8 - cnt); + } + /* set the new carry flag, based on the variable "cf" */ + CONDITIONAL_SET_FLAG(cf, F_CF); + /* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and + * the most significant bit. Blecck. */ + /* parenthesized... */ + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), + F_OF); + } + } + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the RCR instruction and side effects. + */ +static uint16_t +rcr_word(struct x86emu *emu, uint16_t d, uint8_t s) +{ + uint32_t res, cnt; + uint32_t mask, cf, ocf = 0; + + /* rotate right through carry */ + res = d; + if ((cnt = s % 17) != 0) { + if (cnt == 1) { + cf = d & 0x1; + ocf = ACCESS_FLAG(F_CF) != 0; + } else + cf = (d >> (cnt - 1)) & 0x1; + mask = (1 << (16 - cnt)) - 1; + res = (d >> cnt) & mask; + res |= (d << (17 - cnt)); + if (ACCESS_FLAG(F_CF)) { + res |= 1 << (16 - cnt); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), + F_OF); + } + } + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the RCR instruction and side effects. + */ +static uint32_t +rcr_long(struct x86emu *emu, uint32_t d, uint8_t s) +{ + uint32_t res, cnt; + uint32_t mask, cf, ocf = 0; + + /* rotate right through carry */ + res = d; + if ((cnt = s % 33) != 0) { + if (cnt == 1) { + cf = d & 0x1; + ocf = ACCESS_FLAG(F_CF) != 0; + } else + cf = (d >> (cnt - 1)) & 0x1; + mask = (1 << (32 - cnt)) - 1; + res = (d >> cnt) & mask; + if (cnt != 1) + res |= (d << (33 - cnt)); + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + res |= 1 << (32 - cnt); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), + F_OF); + } + } + return res; +} + +/* + * REMARKS: + * Implements the ROL instruction and side effects. + */ +static uint8_t +rol_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + unsigned int res, cnt, mask; + + /* rotate left */ + /* s is the rotate distance. It varies from 0 - 8. d is the byte + * object rotated. + * + * have + * + * CF B_7 ... B_0 + * + * The new rotate is done mod 8. Much simpler than the "rcl" or "rcr" + * operations. + * + * IF n > 0 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) 2) B_(n-1) .. + * B_(0) <- b_(7) .. b_(8-n) */ + res = d; + if ((cnt = s % 8) != 0) { + /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */ + res = (d << cnt); + + /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */ + mask = (1 << cnt) - 1; + res |= (d >> (8 - cnt)) & mask; + + /* set the new carry flag, Note that it is the low order bit + * of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + /* OVERFLOW is set *IFF* s==1, then it is the xor of CF and + * the most significant bit. Blecck. */ + CONDITIONAL_SET_FLAG(s == 1 && + XOR2((res & 0x1) + ((res >> 6) & 0x2)), + F_OF); + } if (s != 0) { + /* set the new carry flag, Note that it is the low order bit + * of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + } + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the ROL instruction and side effects. + */ +static uint16_t +rol_word(struct x86emu *emu, uint16_t d, uint8_t s) +{ + unsigned int res, cnt, mask; + + res = d; + if ((cnt = s % 16) != 0) { + res = (d << cnt); + mask = (1 << cnt) - 1; + res |= (d >> (16 - cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && + XOR2((res & 0x1) + ((res >> 14) & 0x2)), + F_OF); + } if (s != 0) { + /* set the new carry flag, Note that it is the low order bit + * of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + } + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the ROL instruction and side effects. + */ +static uint32_t +rol_long(struct x86emu *emu, uint32_t d, uint8_t s) +{ + uint32_t res, cnt, mask; + + res = d; + if ((cnt = s % 32) != 0) { + res = (d << cnt); + mask = (1 << cnt) - 1; + res |= (d >> (32 - cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && + XOR2((res & 0x1) + ((res >> 30) & 0x2)), + F_OF); + } if (s != 0) { + /* set the new carry flag, Note that it is the low order bit + * of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + } + return res; +} + +/* + * REMARKS: + * Implements the ROR instruction and side effects. + */ +static uint8_t +ror_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + unsigned int res, cnt, mask; + + /* rotate right */ + /* s is the rotate distance. It varies from 0 - 8. d is the byte + * object rotated. + * + * have + * + * B_7 ... B_0 + * + * The rotate is done mod 8. + * + * IF n > 0 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) 2) B_(7) .. + * B_(8-n) <- b_(n-1) .. b_(0) */ + res = d; + if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */ + /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */ + res = (d << (8 - cnt)); + + /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */ + mask = (1 << (8 - cnt)) - 1; + res |= (d >> (cnt)) & mask; + + /* set the new carry flag, Note that it is the low order bit + * of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x80, F_CF); + /* OVERFLOW is set *IFF* s==1, then it is the xor of the two + * most significant bits. Blecck. */ + CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF); + } else if (s != 0) { + /* set the new carry flag, Note that it is the low order bit + * of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x80, F_CF); + } + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the ROR instruction and side effects. + */ +static uint16_t +ror_word(struct x86emu *emu, uint16_t d, uint8_t s) +{ + unsigned int res, cnt, mask; + + res = d; + if ((cnt = s % 16) != 0) { + res = (d << (16 - cnt)); + mask = (1 << (16 - cnt)) - 1; + res |= (d >> (cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF); + } else if (s != 0) { + /* set the new carry flag, Note that it is the low order bit + * of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); + } + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the ROR instruction and side effects. + */ +static uint32_t +ror_long(struct x86emu *emu, uint32_t d, uint8_t s) +{ + uint32_t res, cnt, mask; + + res = d; + if ((cnt = s % 32) != 0) { + res = (d << (32 - cnt)); + mask = (1 << (32 - cnt)) - 1; + res |= (d >> (cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF); + } else if (s != 0) { + /* set the new carry flag, Note that it is the low order bit + * of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); + } + return res; +} + +/* + * REMARKS: + * Implements the SHL instruction and side effects. + */ +static uint8_t +shl_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 8) { + cnt = s % 8; + + /* last bit shifted out goes into carry flag */ + if (cnt > 0) { + res = d << cnt; + cf = d & (1 << (8 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = (uint8_t) d; + } + + if (cnt == 1) { + /* Needs simplification. */ + CONDITIONAL_SET_FLAG( + (((res & 0x80) == 0x80) ^ + (ACCESS_FLAG(F_CF) != 0)), + /* was (emu->x86.R_FLG&F_CF)==F_CF)), */ + F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the SHL instruction and side effects. + */ +static uint16_t +shl_word(struct x86emu *emu, uint16_t d, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + res = d << cnt; + cf = d & (1 << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = (uint16_t) d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG( + (((res & 0x8000) == 0x8000) ^ + (ACCESS_FLAG(F_CF) != 0)), + F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the SHL instruction and side effects. + */ +static uint32_t +shl_long(struct x86emu *emu, uint32_t d, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + res = d << cnt; + cf = d & (1 << (32 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return res; +} + +/* + * REMARKS: + * Implements the SHR instruction and side effects. + */ +static uint8_t +shr_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 8) { + cnt = s % 8; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = d >> cnt; + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = (uint8_t) d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the SHR instruction and side effects. + */ +static uint16_t +shr_word(struct x86emu *emu, uint16_t d, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = d >> cnt; + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the SHR instruction and side effects. + */ +static uint32_t +shr_long(struct x86emu *emu, uint32_t d, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = d >> cnt; + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return res; +} + +/* + * REMARKS: + * Implements the SAR instruction and side effects. + */ +static uint8_t +sar_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + unsigned int cnt, res, cf, mask, sf; + + res = d; + sf = d & 0x80; + cnt = s % 8; + if (cnt > 0 && cnt < 8) { + mask = (1 << (8 - cnt)) - 1; + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) & mask; + CONDITIONAL_SET_FLAG(cf, F_CF); + if (sf) { + res |= ~mask; + } + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + } else if (cnt >= 8) { + if (sf) { + res = 0xff; + SET_FLAG(F_CF); + CLEAR_FLAG(F_ZF); + SET_FLAG(F_SF); + SET_FLAG(F_PF); + } else { + res = 0; + CLEAR_FLAG(F_CF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + } + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the SAR instruction and side effects. + */ +static uint16_t +sar_word(struct x86emu *emu, uint16_t d, uint8_t s) +{ + unsigned int cnt, res, cf, mask, sf; + + sf = d & 0x8000; + cnt = s % 16; + res = d; + if (cnt > 0 && cnt < 16) { + mask = (1 << (16 - cnt)) - 1; + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) & mask; + CONDITIONAL_SET_FLAG(cf, F_CF); + if (sf) { + res |= ~mask; + } + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else if (cnt >= 16) { + if (sf) { + res = 0xffff; + SET_FLAG(F_CF); + CLEAR_FLAG(F_ZF); + SET_FLAG(F_SF); + SET_FLAG(F_PF); + } else { + res = 0; + CLEAR_FLAG(F_CF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + } + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the SAR instruction and side effects. + */ +static uint32_t +sar_long(struct x86emu *emu, uint32_t d, uint8_t s) +{ + uint32_t cnt, res, cf, mask, sf; + + sf = d & 0x80000000; + cnt = s % 32; + res = d; + if (cnt > 0 && cnt < 32) { + mask = (1 << (32 - cnt)) - 1; + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) & mask; + CONDITIONAL_SET_FLAG(cf, F_CF); + if (sf) { + res |= ~mask; + } + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else if (cnt >= 32) { + if (sf) { + res = 0xffffffff; + SET_FLAG(F_CF); + CLEAR_FLAG(F_ZF); + SET_FLAG(F_SF); + SET_FLAG(F_PF); + } else { + res = 0; + CLEAR_FLAG(F_CF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + } + return res; +} + +/* + * REMARKS: + * Implements the SHLD instruction and side effects. + */ +static uint16_t +shld_word(struct x86emu *emu, uint16_t d, uint16_t fill, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + res = (d << cnt) | (fill >> (16 - cnt)); + cf = d & (1 << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the SHLD instruction and side effects. + */ +static uint32_t +shld_long(struct x86emu *emu, uint32_t d, uint32_t fill, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + res = (d << cnt) | (fill >> (32 - cnt)); + cf = d & (1 << (32 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return res; +} + +/* + * REMARKS: + * Implements the SHRD instruction and side effects. + */ +static uint16_t +shrd_word(struct x86emu *emu, uint16_t d, uint16_t fill, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) | (fill << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the SHRD instruction and side effects. + */ +static uint32_t +shrd_long(struct x86emu *emu, uint32_t d, uint32_t fill, uint8_t s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) | (fill << (32 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF); + } else { + CLEAR_FLAG(F_OF); + } + } else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return res; +} + +/* + * REMARKS: + * Implements the SBB instruction and side effects. + */ +static uint8_t +sbb_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + if (ACCESS_FLAG(F_CF)) + res = d - s - 1; + else + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the SBB instruction and side effects. + */ +static uint16_t +sbb_word(struct x86emu *emu, uint16_t d, uint16_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + if (ACCESS_FLAG(F_CF)) + res = d - s - 1; + else + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the SBB instruction and side effects. + */ +static uint32_t +sbb_long(struct x86emu *emu, uint32_t d, uint32_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + if (ACCESS_FLAG(F_CF)) + res = d - s - 1; + else + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/* + * REMARKS: + * Implements the SUB instruction and side effects. + */ +static uint8_t +sub_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (uint8_t) res; +} + +/* + * REMARKS: + * Implements the SUB instruction and side effects. + */ +static uint16_t +sub_word(struct x86emu *emu, uint16_t d, uint16_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (uint16_t) res; +} + +/* + * REMARKS: + * Implements the SUB instruction and side effects. + */ +static uint32_t +sub_long(struct x86emu *emu, uint32_t d, uint32_t s) +{ + uint32_t res; /* all operands in native machine order */ + uint32_t bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/* + * REMARKS: + * Implements the TEST instruction and side effects. + */ +static void +test_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint32_t res; /* all operands in native machine order */ + + res = d & s; + + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + /* AF == dont care */ + CLEAR_FLAG(F_CF); +} + +/* + * REMARKS: + * Implements the TEST instruction and side effects. + */ +static void +test_word(struct x86emu *emu, uint16_t d, uint16_t s) +{ + uint32_t res; /* all operands in native machine order */ + + res = d & s; + + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + /* AF == dont care */ + CLEAR_FLAG(F_CF); +} + +/* + * REMARKS: + * Implements the TEST instruction and side effects. + */ +static void +test_long(struct x86emu *emu, uint32_t d, uint32_t s) +{ + uint32_t res; /* all operands in native machine order */ + + res = d & s; + + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + /* AF == dont care */ + CLEAR_FLAG(F_CF); +} + +/* + * REMARKS: + * Implements the XOR instruction and side effects. + */ +static uint8_t +xor_byte(struct x86emu *emu, uint8_t d, uint8_t s) +{ + uint8_t res; /* all operands in native machine order */ + + res = d ^ s; + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + return res; +} + +/* + * REMARKS: + * Implements the XOR instruction and side effects. + */ +static uint16_t +xor_word(struct x86emu *emu, uint16_t d, uint16_t s) +{ + uint16_t res; /* all operands in native machine order */ + + res = d ^ s; + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + return res; +} + +/* + * REMARKS: + * Implements the XOR instruction and side effects. + */ +static uint32_t +xor_long(struct x86emu *emu, uint32_t d, uint32_t s) +{ + uint32_t res; /* all operands in native machine order */ + + res = d ^ s; + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + return res; +} + +/* + * REMARKS: + * Implements the IMUL instruction and side effects. + */ +static void +imul_byte(struct x86emu *emu, uint8_t s) +{ + int16_t res = (int16_t) ((int8_t) emu->x86.R_AL * (int8_t) s); + + emu->x86.R_AX = res; + if (((emu->x86.R_AL & 0x80) == 0 && emu->x86.R_AH == 0x00) || + ((emu->x86.R_AL & 0x80) != 0 && emu->x86.R_AH == 0xFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/* + * REMARKS: + * Implements the IMUL instruction and side effects. + */ +static void +imul_word(struct x86emu *emu, uint16_t s) +{ + int32_t res = (int16_t) emu->x86.R_AX * (int16_t) s; + + emu->x86.R_AX = (uint16_t) res; + emu->x86.R_DX = (uint16_t) (res >> 16); + if (((emu->x86.R_AX & 0x8000) == 0 && emu->x86.R_DX == 0x00) || + ((emu->x86.R_AX & 0x8000) != 0 && emu->x86.R_DX == 0xFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/* + * REMARKS: + * Implements the IMUL instruction and side effects. + */ +static void +imul_long(struct x86emu *emu, uint32_t s) +{ + int64_t res; + + res = (int64_t)(int32_t)emu->x86.R_EAX * (int32_t)s; + emu->x86.R_EAX = (uint32_t)res; + emu->x86.R_EDX = ((uint64_t)res) >> 32; + if (((emu->x86.R_EAX & 0x80000000) == 0 && emu->x86.R_EDX == 0x00) || + ((emu->x86.R_EAX & 0x80000000) != 0 && emu->x86.R_EDX == 0xFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/* + * REMARKS: + * Implements the MUL instruction and side effects. + */ +static void +mul_byte(struct x86emu *emu, uint8_t s) +{ + uint16_t res = (uint16_t) (emu->x86.R_AL * s); + + emu->x86.R_AX = res; + if (emu->x86.R_AH == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/* + * REMARKS: + * Implements the MUL instruction and side effects. + */ +static void +mul_word(struct x86emu *emu, uint16_t s) +{ + uint32_t res = emu->x86.R_AX * s; + + emu->x86.R_AX = (uint16_t) res; + emu->x86.R_DX = (uint16_t) (res >> 16); + if (emu->x86.R_DX == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/* + * REMARKS: + * Implements the MUL instruction and side effects. + */ +static void +mul_long(struct x86emu *emu, uint32_t s) +{ + uint64_t res = (uint64_t) emu->x86.R_EAX * s; + + emu->x86.R_EAX = (uint32_t) res; + emu->x86.R_EDX = (uint32_t) (res >> 32); + + if (emu->x86.R_EDX == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/* + * REMARKS: + * Implements the IDIV instruction and side effects. + */ +static void +idiv_byte(struct x86emu *emu, uint8_t s) +{ + int32_t dvd, div, mod; + + dvd = (int16_t) emu->x86.R_AX; + if (s == 0) { + x86emu_intr_raise(emu, 8); + return; + } + div = dvd / (int8_t) s; + mod = dvd % (int8_t) s; + if (div > 0x7f || div < -0x7f) { + x86emu_intr_raise(emu, 8); + return; + } + emu->x86.R_AL = (int8_t) div; + emu->x86.R_AH = (int8_t) mod; +} + +/* + * REMARKS: + * Implements the IDIV instruction and side effects. + */ +static void +idiv_word(struct x86emu *emu, uint16_t s) +{ + int32_t dvd, div, mod; + + dvd = (((int32_t) emu->x86.R_DX) << 16) | emu->x86.R_AX; + if (s == 0) { + x86emu_intr_raise(emu, 8); + return; + } + div = dvd / (int16_t) s; + mod = dvd % (int16_t) s; + if (div > 0x7fff || div < -0x7fff) { + x86emu_intr_raise(emu, 8); + return; + } + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(div == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + + emu->x86.R_AX = (uint16_t) div; + emu->x86.R_DX = (uint16_t) mod; +} + +/* + * REMARKS: + * Implements the IDIV instruction and side effects. + */ +static void +idiv_long(struct x86emu *emu, uint32_t s) +{ + int64_t dvd, div, mod; + + dvd = (((int64_t) emu->x86.R_EDX) << 32) | emu->x86.R_EAX; + if (s == 0) { + x86emu_intr_raise(emu, 8); + return; + } + div = dvd / (int32_t) s; + mod = dvd % (int32_t) s; + if (div > 0x7fffffff || div < -0x7fffffff) { + x86emu_intr_raise(emu, 8); + return; + } + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_ZF); + CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + + emu->x86.R_EAX = (uint32_t) div; + emu->x86.R_EDX = (uint32_t) mod; +} + +/* + * REMARKS: + * Implements the DIV instruction and side effects. + */ +static void +div_byte(struct x86emu *emu, uint8_t s) +{ + uint32_t dvd, div, mod; + + dvd = emu->x86.R_AX; + if (s == 0) { + x86emu_intr_raise(emu, 8); + return; + } + div = dvd / (uint8_t) s; + mod = dvd % (uint8_t) s; + if (div > 0xff) { + x86emu_intr_raise(emu, 8); + return; + } + emu->x86.R_AL = (uint8_t) div; + emu->x86.R_AH = (uint8_t) mod; +} + +/* + * REMARKS: + * Implements the DIV instruction and side effects. + */ +static void +div_word(struct x86emu *emu, uint16_t s) +{ + uint32_t dvd, div, mod; + + dvd = (((uint32_t) emu->x86.R_DX) << 16) | emu->x86.R_AX; + if (s == 0) { + x86emu_intr_raise(emu, 8); + return; + } + div = dvd / (uint16_t) s; + mod = dvd % (uint16_t) s; + if (div > 0xffff) { + x86emu_intr_raise(emu, 8); + return; + } + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(div == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + + emu->x86.R_AX = (uint16_t) div; + emu->x86.R_DX = (uint16_t) mod; +} + +/* + * REMARKS: + * Implements the DIV instruction and side effects. + */ +static void +div_long(struct x86emu *emu, uint32_t s) +{ + uint64_t dvd, div, mod; + + dvd = (((uint64_t) emu->x86.R_EDX) << 32) | emu->x86.R_EAX; + if (s == 0) { + x86emu_intr_raise(emu, 8); + return; + } + div = dvd / (uint32_t) s; + mod = dvd % (uint32_t) s; + if (div > 0xffffffff) { + x86emu_intr_raise(emu, 8); + return; + } + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_ZF); + CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + + emu->x86.R_EAX = (uint32_t) div; + emu->x86.R_EDX = (uint32_t) mod; +} + +/* + * REMARKS: + * Implements the IN string instruction and side effects. + */ +static void +ins(struct x86emu *emu, int size) +{ + int inc = size; + + if (ACCESS_FLAG(F_DF)) { + inc = -size; + } + if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* in until CX is ZERO. */ + uint32_t count = ((emu->x86.mode & SYSMODE_PREFIX_DATA) ? + emu->x86.R_ECX : emu->x86.R_CX); + switch (size) { + case 1: + while (count--) { + store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, + (*emu->emu_inb) (emu, emu->x86.R_DX)); + emu->x86.R_DI += inc; + } + break; + + case 2: + while (count--) { + store_word(emu, emu->x86.R_ES, emu->x86.R_DI, + (*emu->emu_inw) (emu, emu->x86.R_DX)); + emu->x86.R_DI += inc; + } + break; + case 4: + while (count--) { + store_long(emu, emu->x86.R_ES, emu->x86.R_DI, + (*emu->emu_inl) (emu, emu->x86.R_DX)); + emu->x86.R_DI += inc; + break; + } + } + emu->x86.R_CX = 0; + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + emu->x86.R_ECX = 0; + } + emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } else { + switch (size) { + case 1: + store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, + (*emu->emu_inb) (emu, emu->x86.R_DX)); + break; + case 2: + store_word(emu, emu->x86.R_ES, emu->x86.R_DI, + (*emu->emu_inw) (emu, emu->x86.R_DX)); + break; + case 4: + store_long(emu, emu->x86.R_ES, emu->x86.R_DI, + (*emu->emu_inl) (emu, emu->x86.R_DX)); + break; + } + emu->x86.R_DI += inc; + } +} + +/* + * REMARKS: + * Implements the OUT string instruction and side effects. + */ +static void +outs(struct x86emu *emu, int size) +{ + int inc = size; + + if (ACCESS_FLAG(F_DF)) { + inc = -size; + } + if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* out until CX is ZERO. */ + uint32_t count = ((emu->x86.mode & SYSMODE_PREFIX_DATA) ? + emu->x86.R_ECX : emu->x86.R_CX); + switch (size) { + case 1: + while (count--) { + (*emu->emu_outb) (emu, emu->x86.R_DX, + fetch_byte(emu, emu->x86.R_ES, emu->x86.R_SI)); + emu->x86.R_SI += inc; + } + break; + + case 2: + while (count--) { + (*emu->emu_outw) (emu, emu->x86.R_DX, + fetch_word(emu, emu->x86.R_ES, emu->x86.R_SI)); + emu->x86.R_SI += inc; + } + break; + case 4: + while (count--) { + (*emu->emu_outl) (emu, emu->x86.R_DX, + fetch_long(emu, emu->x86.R_ES, emu->x86.R_SI)); + emu->x86.R_SI += inc; + break; + } + } + emu->x86.R_CX = 0; + if (emu->x86.mode & SYSMODE_PREFIX_DATA) { + emu->x86.R_ECX = 0; + } + emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } else { + switch (size) { + case 1: + (*emu->emu_outb) (emu, emu->x86.R_DX, + fetch_byte(emu, emu->x86.R_ES, emu->x86.R_SI)); + break; + case 2: + (*emu->emu_outw) (emu, emu->x86.R_DX, + fetch_word(emu, emu->x86.R_ES, emu->x86.R_SI)); + break; + case 4: + (*emu->emu_outl) (emu, emu->x86.R_DX, + fetch_long(emu, emu->x86.R_ES, emu->x86.R_SI)); + break; + } + emu->x86.R_SI += inc; + } +} + +/* + * REMARKS: + * Pushes a word onto the stack. + * + * NOTE: Do not inline this, as (*emu->emu_wrX) is already inline! + */ +static void +push_word(struct x86emu *emu, uint16_t w) +{ + emu->x86.R_SP -= 2; + store_word(emu, emu->x86.R_SS, emu->x86.R_SP, w); +} + +/* + * REMARKS: + * Pushes a long onto the stack. + * + * NOTE: Do not inline this, as (*emu->emu_wrX) is already inline! + */ +static void +push_long(struct x86emu *emu, uint32_t w) +{ + emu->x86.R_SP -= 4; + store_long(emu, emu->x86.R_SS, emu->x86.R_SP, w); +} + +/* + * REMARKS: + * Pops a word from the stack. + * + * NOTE: Do not inline this, as (*emu->emu_rdX) is already inline! + */ +static uint16_t +pop_word(struct x86emu *emu) +{ + uint16_t res; + + res = fetch_word(emu, emu->x86.R_SS, emu->x86.R_SP); + emu->x86.R_SP += 2; + return res; +} + +/* + * REMARKS: + * Pops a long from the stack. + * + * NOTE: Do not inline this, as (*emu->emu_rdX) is already inline! + */ +static uint32_t +pop_long(struct x86emu *emu) +{ + uint32_t res; + + res = fetch_long(emu, emu->x86.R_SS, emu->x86.R_SP); + emu->x86.R_SP += 4; + return res; +} diff --git a/sys/contrib/x86emu/x86emu.h b/sys/contrib/x86emu/x86emu.h new file mode 100644 index 00000000000..f25a95ba6c7 --- /dev/null +++ b/sys/contrib/x86emu/x86emu.h @@ -0,0 +1,184 @@ +/* $NetBSD: x86emu.h,v 1.1 2007/12/01 20:14:10 joerg Exp $ */ +/* $OpenBSD: x86emu.h,v 1.3 2009/06/06 03:45:05 matthieu Exp $ */ +/* $FreeBSD$ */ + +/**************************************************************************** +* +* 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. +* +****************************************************************************/ + +#ifndef __X86EMU_X86EMU_H +#define __X86EMU_X86EMU_H + +#include +#include + +#ifdef _KERNEL +#include +#include +#else +#include +#endif + +/* + * General EAX, EBX, ECX, EDX type registers. Note that for + * portability, and speed, the issue of byte swapping is not addressed + * in the registers. All registers are stored in the default format + * available on the host machine. The only critical issue is that the + * registers should line up EXACTLY in the same manner as they do in + * the 386. That is: + * + * EAX & 0xff === AL + * EAX & 0xffff == AX + * + * etc. The result is that alot of the calculations can then be + * done using the native instruction set fully. + */ + +#ifdef __BIG_ENDIAN__ + +struct x86emu_register32 { + uint32_t e_reg; +}; + +struct x86emu_register16 { + uint16_t filler0; + uint16_t x_reg; +}; + +struct x86emu_register8 { + uint8_t filler0, filler1; + uint8_t h_reg, l_reg; +}; + +#else /* !__BIG_ENDIAN__ */ + +struct x86emu_register32 { + uint32_t e_reg; +}; + +struct x86emu_register16 { + uint16_t x_reg; +}; + +struct x86emu_register8 { + uint8_t l_reg, h_reg; +}; + +#endif /* BIG_ENDIAN */ + +union x86emu_register { + struct x86emu_register32 I32_reg; + struct x86emu_register16 I16_reg; + struct x86emu_register8 I8_reg; +}; + +struct x86emu_regs { + uint16_t register_cs; + uint16_t register_ds; + uint16_t register_es; + uint16_t register_fs; + uint16_t register_gs; + uint16_t register_ss; + uint32_t register_flags; + union x86emu_register register_a; + union x86emu_register register_b; + union x86emu_register register_c; + union x86emu_register register_d; + + union x86emu_register register_sp; + union x86emu_register register_bp; + union x86emu_register register_si; + union x86emu_register register_di; + union x86emu_register register_ip; + + /* + * MODE contains information on: + * REPE prefix 2 bits repe,repne + * SEGMENT overrides 5 bits normal,DS,SS,CS,ES + * Delayed flag set 3 bits (zero, signed, parity) + * reserved 6 bits + * interrupt # 8 bits instruction raised interrupt + * BIOS video segregs 4 bits + * Interrupt Pending 1 bits + * Extern interrupt 1 bits + * Halted 1 bits + */ + uint32_t mode; + volatile int intr; /* mask of pending interrupts */ + uint8_t intno; + uint8_t __pad[3]; +}; + +struct x86emu { + char *mem_base; + size_t mem_size; + void *sys_private; + struct x86emu_regs x86; + + jmp_buf exec_state; + + uint64_t cur_cycles; + + unsigned int cur_mod:2; + unsigned int cur_rl:3; + unsigned int cur_rh:3; + uint32_t cur_offset; + + uint8_t (*emu_rdb)(struct x86emu *, uint32_t addr); + uint16_t (*emu_rdw)(struct x86emu *, uint32_t addr); + uint32_t (*emu_rdl)(struct x86emu *, uint32_t addr); + void (*emu_wrb)(struct x86emu *, uint32_t addr,uint8_t val); + void (*emu_wrw)(struct x86emu *, uint32_t addr, uint16_t val); + void (*emu_wrl)(struct x86emu *, uint32_t addr, uint32_t val); + + uint8_t (*emu_inb)(struct x86emu *, uint16_t addr); + uint16_t (*emu_inw)(struct x86emu *, uint16_t addr); + uint32_t (*emu_inl)(struct x86emu *, uint16_t addr); + void (*emu_outb)(struct x86emu *, uint16_t addr, uint8_t val); + void (*emu_outw)(struct x86emu *, uint16_t addr, uint16_t val); + void (*emu_outl)(struct x86emu *, uint16_t addr, uint32_t val); + + void (*_x86emu_intrTab[256])(struct x86emu *, int); +}; + +__BEGIN_DECLS + +void x86emu_init_default(struct x86emu *); + +/* decode.c */ + +void x86emu_exec(struct x86emu *); +void x86emu_exec_call(struct x86emu *, uint16_t, uint16_t); +void x86emu_exec_intr(struct x86emu *, uint8_t); +void x86emu_halt_sys(struct x86emu *) __dead2; + +__END_DECLS + +#endif /* __X86EMU_X86EMU_H */ diff --git a/sys/contrib/x86emu/x86emu_regs.h b/sys/contrib/x86emu/x86emu_regs.h new file mode 100644 index 00000000000..fda2d47aab6 --- /dev/null +++ b/sys/contrib/x86emu/x86emu_regs.h @@ -0,0 +1,170 @@ +/* $NetBSD: x86emu_regs.h,v 1.1 2007/12/01 20:14:10 joerg Exp $ */ +/* $OpenBSD: x86emu_regs.h,v 1.2 2009/06/06 03:45:05 matthieu 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. +* +****************************************************************************/ + +#ifndef __X86EMU_REGS_H +#define __X86EMU_REGS_H + +/*---------------------- Macros and type definitions ----------------------*/ + +/* 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 + +/* 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 + +/* 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 + +/* 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_IP register_ip.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_EIP register_ip.I32_reg.e_reg +#define R_EFLG register_flags + +/* segment registers */ +#define R_CS register_cs +#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 + +/* flag conditions */ +#define FB_CF 0x0001 /* CARRY flag */ +#define FB_PF 0x0004 /* PARITY flag */ +#define FB_AF 0x0010 /* AUX flag */ +#define FB_ZF 0x0040 /* ZERO flag */ +#define FB_SF 0x0080 /* SIGN flag */ +#define FB_TF 0x0100 /* TRAP flag */ +#define FB_IF 0x0200 /* INTERRUPT ENABLE flag */ +#define FB_DF 0x0400 /* DIR flag */ +#define FB_OF 0x0800 /* OVERFLOW flag */ + +/* 80286 and above always have bit#1 set */ +#define F_ALWAYS_ON (0x0002) /* flag bits always on */ + +/* + * Define a mask for only those flag bits we will ever pass back + * (via PUSHF) + */ +#define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF) + +/* following bits masked in to a 16bit quantity */ + +#define F_CF 0x0001 /* CARRY flag */ +#define F_PF 0x0004 /* PARITY flag */ +#define F_AF 0x0010 /* AUX flag */ +#define F_ZF 0x0040 /* ZERO flag */ +#define F_SF 0x0080 /* SIGN flag */ +#define F_TF 0x0100 /* TRAP flag */ +#define F_IF 0x0200 /* INTERRUPT ENABLE flag */ +#define F_DF 0x0400 /* DIR flag */ +#define F_OF 0x0800 /* OVERFLOW flag */ + +#define SET_FLAG(flag) (emu->x86.R_FLG |= (flag)) +#define CLEAR_FLAG(flag) (emu->x86.R_FLG &= ~(flag)) +#define ACCESS_FLAG(flag) (emu->x86.R_FLG & (flag)) +#define CLEARALL_FLAG(m) (emu->x86.R_FLG = 0) + +#define CONDITIONAL_SET_FLAG(COND,FLAG) \ + if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG) + +#define F_PF_CALC 0x010000 /* PARITY flag has been calced */ +#define F_ZF_CALC 0x020000 /* ZERO flag has been calced */ +#define F_SF_CALC 0x040000 /* SIGN flag has been calced */ + +#define F_ALL_CALC 0xff0000 /* All have been calced */ + +/* + * Emulator machine state. + * Segment usage control. + */ +#define SYSMODE_SEG_DS_SS 0x00000001 +#define SYSMODE_SEGOVR_CS 0x00000002 +#define SYSMODE_SEGOVR_DS 0x00000004 +#define SYSMODE_SEGOVR_ES 0x00000008 +#define SYSMODE_SEGOVR_FS 0x00000010 +#define SYSMODE_SEGOVR_GS 0x00000020 +#define SYSMODE_SEGOVR_SS 0x00000040 +#define SYSMODE_PREFIX_REPE 0x00000080 +#define SYSMODE_PREFIX_REPNE 0x00000100 +#define SYSMODE_PREFIX_DATA 0x00000200 +#define SYSMODE_PREFIX_ADDR 0x00000400 +#define SYSMODE_INTR_PENDING 0x10000000 +#define SYSMODE_EXTRN_INTR 0x20000000 +#define SYSMODE_HALTED 0x40000000 + +#define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS | \ + SYSMODE_SEGOVR_CS | \ + SYSMODE_SEGOVR_DS | \ + SYSMODE_SEGOVR_ES | \ + SYSMODE_SEGOVR_FS | \ + SYSMODE_SEGOVR_GS | \ + SYSMODE_SEGOVR_SS) +#define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS | \ + SYSMODE_SEGOVR_CS | \ + SYSMODE_SEGOVR_DS | \ + SYSMODE_SEGOVR_ES | \ + SYSMODE_SEGOVR_FS | \ + SYSMODE_SEGOVR_GS | \ + SYSMODE_SEGOVR_SS | \ + SYSMODE_PREFIX_DATA | \ + SYSMODE_PREFIX_ADDR) + +#define INTR_SYNCH 0x1 + +#endif /* __X86EMU_REGS_H */ diff --git a/sys/contrib/x86emu/x86emu_util.c b/sys/contrib/x86emu/x86emu_util.c new file mode 100644 index 00000000000..e96efc24a42 --- /dev/null +++ b/sys/contrib/x86emu/x86emu_util.c @@ -0,0 +1,208 @@ +/* $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 +#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 letoh32(*(u_int32_t *)(emu->mem_base + addr)); +#else + return letoh16(*(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 letoh32(*(u_int32_t *)(emu->mem_base + addr)); +#else + return letoh32(*(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 0aae1531b13..600020fae6d 100644 --- a/sys/dev/atkbdc/atkbd.c +++ b/sys/dev/atkbdc/atkbd.c @@ -44,10 +44,10 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef __i386__ +#if defined(__i386__) || defined(__amd64__) #include #include -#include +#include #include #include @@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include -#endif /* __i386__ */ +#endif /* __i386__ || __amd64__ */ #include #include @@ -1089,34 +1089,45 @@ atkbd_shutdown_final(void *v) static int get_typematic(keyboard_t *kbd) { -#ifdef __i386__ +#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... */ - struct vm86frame vmf; - u_int32_t p; + x86regs_t regs; + uint8_t *p; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_ax = 0xc000; - vm86_intcall(0x15, &vmf); - if ((vmf.vmf_eflags & PSL_C) || vmf.vmf_ah) - return ENODEV; - p = BIOS_PADDRTOVADDR(((u_int32_t)vmf.vmf_es << 4) + vmf.vmf_bx); - if ((readb(p + 6) & 0x40) == 0) /* int 16, function 0x09 supported? */ - return ENODEV; - vmf.vmf_ax = 0x0900; - vm86_intcall(0x16, &vmf); - if ((vmf.vmf_al & 0x08) == 0) /* int 16, function 0x0306 supported? */ - return ENODEV; - vmf.vmf_ax = 0x0306; - vm86_intcall(0x16, &vmf); - kbd->kb_delay1 = typematic_delay(vmf.vmf_bh << 5); - kbd->kb_delay2 = typematic_rate(vmf.vmf_bl); - return 0; + if (x86bios_get_intr(0x15) == 0 || x86bios_get_intr(0x16) == 0) + return (ENODEV); + + /* Is BIOS system configuration table supported? */ + 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 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 0x16, function 0x0306 supported? */ + x86bios_init_regs(®s); + regs.R_AH = 0x09; + x86bios_intr(®s, 0x16); + if ((regs.R_AL & 0x08) == 0) + return (ENODEV); + + x86bios_init_regs(®s); + regs.R_AX = 0x0306; + x86bios_intr(®s, 0x16); + kbd->kb_delay1 = typematic_delay(regs.R_BH << 5); + kbd->kb_delay2 = typematic_rate(regs.R_BL); + return (0); #else - return ENODEV; -#endif /* __i386__ */ + return (ENODEV); +#endif /* __i386__ || __amd64__ */ } static int diff --git a/sys/i386/isa/dpms.c b/sys/dev/dpms/dpms.c similarity index 88% rename from sys/i386/isa/dpms.c rename to sys/dev/dpms/dpms.c index 723a6c05a3a..fdfed2f6ced 100644 --- a/sys/i386/isa/dpms.c +++ b/sys/dev/dpms/dpms.c @@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include /* * VESA DPMS States @@ -118,19 +118,14 @@ static driver_t dpms_driver = { static devclass_t dpms_devclass; -DRIVER_MODULE(dpms, vgapci, dpms_driver, dpms_devclass, NULL, NULL); +DRIVER_MODULE(dpms, vgapm, dpms_driver, dpms_devclass, NULL, NULL); +MODULE_DEPEND(dpms, x86bios, 1, 1, 1); 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) + if (x86bios_match_device(0xc0000, device_get_parent(parent))) device_add_child(parent, "dpms", 0); } @@ -171,8 +166,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); } @@ -189,21 +187,23 @@ dpms_resume(device_t dev) static int dpms_call_bios(int subfunction, int *bh) { - struct vm86frame vmf; - int error; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_ax = VBE_DPMS_FUNCTION; - vmf.vmf_bl = subfunction; - vmf.vmf_bh = *bh; - vmf.vmf_es = 0; - vmf.vmf_di = 0; - error = vm86_intcall(0x10, &vmf); - if (error == 0 && (vmf.vmf_eax & 0xffff) != 0x004f) - error = ENXIO; - if (error == 0) - *bh = vmf.vmf_bh; - return (error); + 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; + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) + return (ENXIO); + + *bh = regs.R_BH; + + return (0); } static int diff --git a/sys/dev/fb/s3_pci.c b/sys/dev/fb/s3_pci.c index 558329ba887..cfddf3041f0 100644 --- a/sys/dev/fb/s3_pci.c +++ b/sys/dev/fb/s3_pci.c @@ -54,9 +54,8 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include -#include +#include #include #include diff --git a/sys/i386/isa/vesa.c b/sys/dev/fb/vesa.c similarity index 56% rename from sys/i386/isa/vesa.c rename to sys/dev/fb/vesa.c index 736daffbabe..df0dc1e65be 100644 --- a/sys/i386/isa/vesa.c +++ b/sys/dev/fb/vesa.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #ifndef VGA_NO_MODE_CHANGE #include +#include #include #include #include @@ -45,19 +46,17 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include #include -#include +#include #include #include -#ifndef __i386__ +#include + #include -#else -#include -#endif + +#include #define VESA_VIA_CLE266 "VIA CLE266\r\n" @@ -75,9 +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_VM86_BUFSIZE (3 * PAGE_SIZE) -static void *vesa_vm86_buf; +static ssize_t vesa_state_buf_size = -1; /* VESA functions */ #if 0 @@ -109,7 +106,6 @@ static vi_fill_rect_t vesa_fill_rect; static vi_bitblt_t vesa_bitblt; static vi_diag_t vesa_diag; static int vesa_bios_info(int level); -static struct vm86context vesa_vmcontext; static video_switch_t vesavidsw = { vesa_probe, @@ -166,9 +162,12 @@ 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_set_mode(int mode); +#if 0 static int vesa_bios_get_dac(void); +#endif static int vesa_bios_set_dac(int bits); static int vesa_bios_save_palette(int start, int colors, u_char *palette, int bits); @@ -176,10 +175,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 @@ -189,9 +186,11 @@ 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); +#if 0 static int vesa_bios_get_line_length(void); +#endif static int vesa_bios_set_line_length(int pixel, int *bytes, int *lines); #if 0 static int vesa_bios_get_start(int *x, int *y); @@ -200,332 +199,446 @@ static int vesa_bios_set_start(int x, int y); static int vesa_map_gen_mode_num(int type, int color, int mode); static int vesa_translate_flags(u_int16_t vflags); static int vesa_translate_mmodel(u_int8_t vmodel); -static void *vesa_fix_ptr(u_int32_t p, u_int16_t seg, u_int16_t off, - u_char *buf); static int vesa_bios_init(void); static void vesa_clear_modes(video_info_t *info, int color); -static vm_offset_t vesa_map_buffer(u_int paddr, size_t size); -static void vesa_unmap_buffer(vm_offset_t vaddr, size_t size); #if 0 static int vesa_get_origin(video_adapter_t *adp, off_t *offset); #endif -static void -dump_buffer(u_char *buf, size_t len) -{ - int i; - - for(i = 0; i < len;) { - printf("%02x ", buf[i]); - if ((++i % 16) == 0) - printf("\n"); - } -} - /* INT 10 BIOS calls */ static int int10_set_mode(int mode) { - struct vm86frame vmf; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x0000 | mode; - vm86_intcall(0x10, &vmf); - return 0; + x86bios_init_regs(®s); + regs.R_AL = mode; + + x86bios_intr(®s, 0x10); + + 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 (device_get_flags(*devs) != 0 && + x86bios_match_device(0xc0000, *devs)) { + 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); + + if (x86bios_get_intr(0x10) == 0) + return (1); + + return (0); } /* VESA BIOS calls */ static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode) { - struct vm86frame vmf; - u_char *buf; - int err; + x86regs_t regs; + uint32_t offs; + void *buf; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f01; - vmf.vmf_ecx = mode; - buf = vesa_vm86_buf; - vm86_getptr(&vesa_vmcontext, (vm_offset_t)buf, &vmf.vmf_es, &vmf.vmf_di); + buf = x86bios_alloc(&offs, sizeof(*vmode)); + if (buf == NULL) + return (1); + + x86bios_init_regs(®s); + regs.R_AX = 0x4f01; + regs.R_CX = mode; + + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_DI = X86BIOS_PHYSTOOFF(offs); + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) { + x86bios_free(buf, sizeof(*vmode)); + return (1); + } - err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 1; bcopy(buf, vmode, sizeof(*vmode)); - return 0; + x86bios_free(buf, sizeof(*vmode)); + + return (0); } static int vesa_bios_set_mode(int mode) { - struct vm86frame vmf; - int err; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f02; - vmf.vmf_ebx = mode; - err = vm86_intcall(0x10, &vmf); - return ((err != 0) || (vmf.vmf_ax != 0x4f)); + x86bios_init_regs(®s); + regs.R_AX = 0x4f02; + regs.R_BX = mode; + + x86bios_intr(®s, 0x10); + + return (regs.R_AX != 0x004f); } +#if 0 static int vesa_bios_get_dac(void) { - struct vm86frame vmf; - int err; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f08; - vmf.vmf_ebx = 1; /* get DAC width */ - err = vm86_intcall(0x10, &vmf); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 6; /* XXX */ - return ((vmf.vmf_ebx >> 8) & 0x00ff); + x86bios_init_regs(®s); + regs.R_AX = 0x4f08; + regs.R_BL = 1; + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) + return (6); + + return (regs.R_BH); } +#endif static int vesa_bios_set_dac(int bits) { - struct vm86frame vmf; - int err; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f08; - vmf.vmf_ebx = (bits << 8); - err = vm86_intcall(0x10, &vmf); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 6; /* XXX */ - return ((vmf.vmf_ebx >> 8) & 0x00ff); + x86bios_init_regs(®s); + regs.R_AX = 0x4f08; + /* regs.R_BL = 0; */ + regs.R_BH = bits; + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) + return (6); + + return (regs.R_BH); } static int vesa_bios_save_palette(int start, int colors, u_char *palette, int bits) { - struct vm86frame vmf; + x86regs_t regs; + uint32_t offs; u_char *p; - int err; int i; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f09; - vmf.vmf_ebx = 1; /* get primary palette data */ - vmf.vmf_ecx = colors; - vmf.vmf_edx = start; - p = vesa_vm86_buf; - vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di); + p = (u_char *)x86bios_alloc(&offs, colors * 4); + if (p == NULL) + return (1); - err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 1; + x86bios_init_regs(®s); + regs.R_AX = 0x4f09; + regs.R_BL = 1; + regs.R_CX = colors; + regs.R_DX = start; + + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_DI = X86BIOS_PHYSTOOFF(offs); + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) { + x86bios_free(p, colors * 4); + return (1); + } 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; } - return 0; + x86bios_free(p, colors * 4); + + return (0); } static int vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, int bits) { - struct vm86frame vmf; + x86regs_t regs; + uint32_t offs; u_char *p; - int err; int i; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f09; - vmf.vmf_ebx = 1; /* get primary palette data */ - vmf.vmf_ecx = colors; - vmf.vmf_edx = start; - p = vesa_vm86_buf; - vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di); + p = (u_char *)x86bios_alloc(&offs, colors * 4); + if (p == NULL) + return (1); - err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 1; + x86bios_init_regs(®s); + regs.R_AX = 0x4f09; + regs.R_BL = 1; + regs.R_CX = colors; + regs.R_DX = start; + + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_DI = X86BIOS_PHYSTOOFF(offs); + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) { + x86bios_free(p, colors * 4); + return (1); + } 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; } - return 0; + x86bios_free(p, colors * 4); + + return (0); } static int vesa_bios_load_palette(int start, int colors, u_char *palette, int bits) { - struct vm86frame vmf; + x86regs_t regs; + uint32_t offs; u_char *p; - int err; int i; - p = vesa_vm86_buf; + 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) { - 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); - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f09; - vmf.vmf_ebx = 0; /* set primary palette data */ - vmf.vmf_ecx = colors; - vmf.vmf_edx = start; - vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di); - - err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); - return ((err != 0) || (vmf.vmf_ax != 0x4f)); + 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) { - struct vm86frame vmf; + x86regs_t regs; + uint32_t offs; u_char *p; - int err; int i; - p = vesa_vm86_buf; + 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) { - 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); - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f09; - vmf.vmf_ebx = 0; /* set primary palette data */ - vmf.vmf_ecx = colors; - vmf.vmf_edx = start; - vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di); - - err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); - return ((err != 0) || (vmf.vmf_ax != 0x4f)); + return (regs.R_AX != 0x004f); } -#endif -static int +static ssize_t vesa_bios_state_buf_size(void) { - struct vm86frame vmf; - int err; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f04; - vmf.vmf_ecx = STATE_ALL; - vmf.vmf_edx = STATE_SIZE; - err = vm86_intcall(0x10, &vmf); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 0; - return vmf.vmf_bx*64; + 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 != 0x004f) + return (0); + + return (regs.R_BX * 64); } static int vesa_bios_save_restore(int code, void *p, size_t size) { - struct vm86frame vmf; - u_char *buf; - int err; + x86regs_t regs; + uint32_t offs; + void *buf; - if (size > VESA_VM86_BUFSIZE) + if (code != STATE_SAVE && code != STATE_LOAD) return (1); - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f04; - vmf.vmf_ecx = STATE_ALL; - vmf.vmf_edx = code; /* STATE_SAVE/STATE_LOAD */ - buf = vesa_vm86_buf; - vm86_getptr(&vesa_vmcontext, (vm_offset_t)buf, &vmf.vmf_es, &vmf.vmf_bx); - bcopy(p, buf, size); + buf = x86bios_alloc(&offs, size); - err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); - bcopy(buf, p, size); - return ((err != 0) || (vmf.vmf_ax != 0x4f)); + x86bios_init_regs(®s); + regs.R_AX = 0x4f04; + regs.R_DL = code; + regs.R_CX = STATE_ALL; + + regs.R_ES = X86BIOS_PHYSTOSEG(offs); + regs.R_BX = X86BIOS_PHYSTOOFF(offs); + + 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); + + return (regs.R_AX != 0x004f); } +#if 0 static int vesa_bios_get_line_length(void) { - struct vm86frame vmf; - int err; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f06; - vmf.vmf_ebx = 1; /* get scan line length */ - err = vm86_intcall(0x10, &vmf); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return -1; - return vmf.vmf_bx; /* line length in bytes */ + x86bios_init_regs(®s); + regs.R_AX = 0x4f06; + regs.R_BL = 1; + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) + return (-1); + + return (regs.R_BX); } +#endif static int vesa_bios_set_line_length(int pixel, int *bytes, int *lines) { - struct vm86frame vmf; - int err; + x86regs_t regs; + + x86bios_init_regs(®s); + regs.R_AX = 0x4f06; + /* regs.R_BL = 0; */ + regs.R_CX = pixel; + + x86bios_intr(®s, 0x10); - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f06; - vmf.vmf_ebx = 0; /* set scan line length in pixel */ - vmf.vmf_ecx = pixel; - err = vm86_intcall(0x10, &vmf); #if VESA_DEBUG > 1 - printf("bx:%d, cx:%d, dx:%d\n", vmf.vmf_bx, vmf.vmf_cx, vmf.vmf_dx); + printf("bx:%d, cx:%d, dx:%d\n", regs.R_BX, regs.R_CX, regs.R_DX); #endif - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 1; - if (bytes) - *bytes = vmf.vmf_bx; - if (lines) - *lines = vmf.vmf_dx; - return 0; + if (regs.R_AX != 0x004f) + return (-1); + + if (bytes != NULL) + *bytes = regs.R_BX; + if (lines != NULL) + *lines = regs.R_DX; + + return (0); } #if 0 static int vesa_bios_get_start(int *x, int *y) { - struct vm86frame vmf; - int err; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f07; - vmf.vmf_ebx = 1; /* get display start */ - err = vm86_intcall(0x10, &vmf); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 1; - *x = vmf.vmf_cx; - *y = vmf.vmf_dx; - return 0; + x86bios_init_regs(®s); + regs.R_AX = 0x4f07; + regs.R_BL = 1; + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) + return (-1); + + *x = regs.R_CX; + *y = regs.R_DX; + + return (0); } #endif static int vesa_bios_set_start(int x, int y) { - struct vm86frame vmf; - int err; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f07; - vmf.vmf_ebx = 0x80; /* set display start */ - vmf.vmf_edx = y; - vmf.vmf_ecx = x; - err = vm86_intcall(0x10, &vmf); - return ((err != 0) || (vmf.vmf_ax != 0x4f)); + 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 != 0x004f); } /* map a generic video mode to a known mode */ @@ -545,9 +658,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 @@ -561,6 +674,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; @@ -569,7 +683,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 @@ -590,118 +704,153 @@ 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 void -*vesa_fix_ptr(u_int32_t p, u_int16_t seg, u_int16_t off, u_char *buf) -{ - if (p == 0) - return NULL; - if (((p >> 16) == seg) && ((p & 0xffff) >= off)) - return (void *)(buf + ((p & 0xffff) - off)); - else { - p = BIOS_SADDRTOLADDR(p); - return (void *)BIOS_PADDRTOVADDR(p); - } -} +#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) { - static u_char buf[512]; - struct vm86frame vmf; + static struct vesa_info buf; struct vesa_mode vmode; video_info_t *p; - u_char *vmbuf; + x86regs_t regs; + size_t bsize; + size_t msize; + void *vmbuf; + uint32_t offs; + uint16_t vers; + int bpsl; int is_via_cle266; int modes; - int err; 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; - /* Allocate a buffer and add each page to the vm86 context. */ - vesa_vm86_buf = malloc(VESA_VM86_BUFSIZE, M_DEVBUF, M_WAITOK | M_ZERO); - KASSERT(((vm_offset_t)vesa_vm86_buf & PAGE_MASK) == 0, - ("bad vesa_vm86_buf alignment")); - for (i = 0; i < howmany(VESA_VM86_BUFSIZE, PAGE_SIZE); i++) - vm86_addpage(&vesa_vmcontext, i + 1, - (vm_offset_t)vesa_vm86_buf + PAGE_SIZE * i); + /* + * 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); + if (bootverbose) { + offs = x86bios_get_intr(0x10); + 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); - vmbuf = vesa_vm86_buf; - bzero(&vmf, sizeof(vmf)); /* paranoia */ bcopy("VBE2", vmbuf, 4); /* try for VBE2 data */ - vmf.vmf_eax = 0x4f00; - vm86_getptr(&vesa_vmcontext, (vm_offset_t)vmbuf, &vmf.vmf_es, &vmf.vmf_di); + x86bios_intr(®s, 0x10); - err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); - if ((err != 0) || (vmf.vmf_ax != 0x4f) || bcmp("VESA", vmbuf, 4)) - return 1; - bcopy(vmbuf, buf, sizeof(buf)); - vesa_adp_info = (struct vesa_info *)buf; + if (regs.R_AX != 0x004f || bcmp("VESA", vmbuf, 4) != 0) + goto fail; + + bcopy(vmbuf, &buf, sizeof(buf)); + + vesa_adp_info = &buf; if (bootverbose) { printf("VESA: information block\n"); - dump_buffer(buf, 64); + hexdump(&buf, sizeof(buf), NULL, HD_OMIT_CHARS); } - 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; + "version 1.2 or later is required.\n", + ((vers & 0xf000) >> 12) * 10 + ((vers & 0x0f00) >> 8), + ((vers & 0x00f0) >> 4) * 10 + (vers & 0x000f)); + return (1); } - /* fix string ptrs */ - vesa_oemstr = (char *)vesa_fix_ptr(vesa_adp_info->v_oemstr, - vmf.vmf_es, vmf.vmf_di, buf); - is_via_cle266 = strcmp(vesa_oemstr, VESA_VIA_CLE266) == 0; - - if (vesa_adp_info->v_version >= 0x0200) { - vesa_venderstr = - (char *)vesa_fix_ptr(vesa_adp_info->v_venderstr, - vmf.vmf_es, vmf.vmf_di, buf); - vesa_prodstr = - (char *)vesa_fix_ptr(vesa_adp_info->v_prodstr, - vmf.vmf_es, vmf.vmf_di, buf); - vesa_revstr = - (char *)vesa_fix_ptr(vesa_adp_info->v_revstr, - vmf.vmf_es, vmf.vmf_di, buf); + 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; - /* obtain video mode information */ - vesa_vmodetab = (u_int16_t *)vesa_fix_ptr(vesa_adp_info->v_modetable, - vmf.vmf_es, vmf.vmf_di, buf); - if (vesa_vmodetab == NULL) - return 1; - for (i = 0, modes = 0; - (i < (M_VESA_MODE_MAX - M_VESA_BASE + 1)) - && (vesa_vmodetab[i] != 0xffff); ++i) { + if (buf.v_modetable == 0) + goto fail; + + msize = (size_t)buf.v_memsize * 64 * 1024; + + 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; + 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_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 - | V_MODENONVGA)) - != (V_MODESUPP | V_MODEOPTINFO)) + if ((vmode.v_modeattr & + (V_MODESUPP | V_MODEOPTINFO | V_MODENONVGA)) != + (V_MODESUPP | V_MODEOPTINFO)) continue; #else if ((vmode.v_modeattr & V_MODEOPTINFO) == 0) { #if VESA_DEBUG > 1 - printf( - "Rejecting VESA %s mode: %d x %d x %d bpp attr = %x\n", - vmode.v_modeattr & V_MODEGRAPHICS ? "graphics" : "text", + printf("Rejecting VESA %s mode: %d x %d x %d bpp " + " attr = %x\n", + vmode.v_modeattr & V_MODEGRAPHICS ? + "graphics" : "text", vmode.v_width, vmode.v_height, vmode.v_bpp, vmode.v_modeattr); #endif @@ -709,14 +858,33 @@ vesa_bios_init(void) } #endif + bpsl = (vmode.v_modeattr & V_MODELFB) != 0 && vers >= 0x0300 ? + vmode.v_linbpscanline : vmode.v_bpscanline; + bsize = bpsl * vmode.v_height; + if ((vmode.v_modeattr & V_MODEGRAPHICS) != 0) + bsize *= vmode.v_planes; + + /* Does it have enough memory to support this mode? */ + if (msize < bsize) { +#if VESA_DEBUG > 1 + printf("Rejecting VESA %s mode: %d x %d x %d bpp " + " attr = %x, not enough memory\n", + vmode.v_modeattr & V_MODEGRAPHICS ? + "graphics" : "text", + vmode.v_width, vmode.v_height, vmode.v_bpp, + vmode.v_modeattr); +#endif + continue; + } + /* expand the array if necessary */ if (modes >= vesa_vmode_max) { vesa_vmode_max += MODE_TABLE_DELTA; - p = malloc(sizeof(*vesa_vmode)*(vesa_vmode_max + 1), - M_DEVBUF, M_WAITOK); + p = malloc(sizeof(*vesa_vmode) * (vesa_vmode_max + 1), + M_DEVBUF, M_WAITOK); #if VESA_DEBUG > 1 printf("vesa_bios_init(): modes:%d, vesa_mode_max:%d\n", - modes, vesa_vmode_max); + modes, vesa_vmode_max); #endif if (modes > 0) { bcopy(vesa_vmode, p, sizeof(*vesa_vmode)*modes); @@ -746,73 +914,95 @@ vesa_bios_init(void) vesa_vmode[modes].vi_planes = vmode.v_planes; vesa_vmode[modes].vi_cwidth = vmode.v_cwidth; vesa_vmode[modes].vi_cheight = vmode.v_cheight; - vesa_vmode[modes].vi_window = (u_int)vmode.v_waseg << 4; + vesa_vmode[modes].vi_window = (vm_offset_t)vmode.v_waseg << 4; /* XXX window B */ - vesa_vmode[modes].vi_window_size = vmode.v_wsize*1024; - vesa_vmode[modes].vi_window_gran = vmode.v_wgran*1024; + vesa_vmode[modes].vi_window_size = vmode.v_wsize * 1024; + vesa_vmode[modes].vi_window_gran = vmode.v_wgran * 1024; if (vmode.v_modeattr & V_MODELFB) vesa_vmode[modes].vi_buffer = vmode.v_lfb; - else - vesa_vmode[modes].vi_buffer = 0; - /* XXX */ - vesa_vmode[modes].vi_buffer_size - = vesa_adp_info->v_memsize*64*1024; -#if 0 - if (vmode.v_offscreen > vmode.v_lfb) - vesa_vmode[modes].vi_buffer_size - = vmode.v_offscreen + vmode.v_offscreensize*1024 - - vmode.v_lfb; - else - vesa_vmode[modes].vi_buffer_size - = vmode.v_offscreen + vmode.v_offscreensize*1024 -#endif - vesa_vmode[modes].vi_mem_model - = vesa_translate_mmodel(vmode.v_memmodel); - vesa_vmode[modes].vi_pixel_fields[0] = 0; - vesa_vmode[modes].vi_pixel_fields[1] = 0; - vesa_vmode[modes].vi_pixel_fields[2] = 0; - vesa_vmode[modes].vi_pixel_fields[3] = 0; - vesa_vmode[modes].vi_pixel_fsizes[0] = 0; - vesa_vmode[modes].vi_pixel_fsizes[1] = 0; - vesa_vmode[modes].vi_pixel_fsizes[2] = 0; - vesa_vmode[modes].vi_pixel_fsizes[3] = 0; - if (vesa_vmode[modes].vi_mem_model == V_INFO_MM_PACKED) { - vesa_vmode[modes].vi_pixel_size = (vmode.v_bpp + 7)/8; - } else if (vesa_vmode[modes].vi_mem_model == V_INFO_MM_DIRECT) { - vesa_vmode[modes].vi_pixel_size = (vmode.v_bpp + 7)/8; - vesa_vmode[modes].vi_pixel_fields[0] - = vmode.v_redfieldpos; - vesa_vmode[modes].vi_pixel_fields[1] - = vmode.v_greenfieldpos; - vesa_vmode[modes].vi_pixel_fields[2] - = vmode.v_bluefieldpos; - vesa_vmode[modes].vi_pixel_fields[3] - = vmode.v_resfieldpos; - vesa_vmode[modes].vi_pixel_fsizes[0] - = vmode.v_redmasksize; - vesa_vmode[modes].vi_pixel_fsizes[1] - = vmode.v_greenmasksize; - vesa_vmode[modes].vi_pixel_fsizes[2] - = vmode.v_bluemasksize; - vesa_vmode[modes].vi_pixel_fsizes[3] - = vmode.v_resmasksize; - } else { - vesa_vmode[modes].vi_pixel_size = 0; + vesa_vmode[modes].vi_buffer_size = bsize; + vesa_vmode[modes].vi_mem_model = + vesa_translate_mmodel(vmode.v_memmodel); + switch (vesa_vmode[modes].vi_mem_model) { + case V_INFO_MM_DIRECT: + if ((vmode.v_modeattr & V_MODELFB) != 0 && + vers >= 0x0300) { + vesa_vmode[modes].vi_pixel_fields[0] = + vmode.v_linredfieldpos; + vesa_vmode[modes].vi_pixel_fields[1] = + vmode.v_lingreenfieldpos; + vesa_vmode[modes].vi_pixel_fields[2] = + vmode.v_linbluefieldpos; + vesa_vmode[modes].vi_pixel_fields[3] = + vmode.v_linresfieldpos; + vesa_vmode[modes].vi_pixel_fsizes[0] = + vmode.v_linredmasksize; + vesa_vmode[modes].vi_pixel_fsizes[1] = + vmode.v_lingreenmasksize; + vesa_vmode[modes].vi_pixel_fsizes[2] = + vmode.v_linbluemasksize; + vesa_vmode[modes].vi_pixel_fsizes[3] = + vmode.v_linresmasksize; + } else { + vesa_vmode[modes].vi_pixel_fields[0] = + vmode.v_redfieldpos; + vesa_vmode[modes].vi_pixel_fields[1] = + vmode.v_greenfieldpos; + vesa_vmode[modes].vi_pixel_fields[2] = + vmode.v_bluefieldpos; + vesa_vmode[modes].vi_pixel_fields[3] = + vmode.v_resfieldpos; + vesa_vmode[modes].vi_pixel_fsizes[0] = + vmode.v_redmasksize; + vesa_vmode[modes].vi_pixel_fsizes[1] = + vmode.v_greenmasksize; + vesa_vmode[modes].vi_pixel_fsizes[2] = + vmode.v_bluemasksize; + vesa_vmode[modes].vi_pixel_fsizes[3] = + vmode.v_resmasksize; + } + /* FALLTHROUGH */ + case V_INFO_MM_PACKED: + vesa_vmode[modes].vi_pixel_size = (vmode.v_bpp + 7) / 8; + break; } - - vesa_vmode[modes].vi_flags - = vesa_translate_flags(vmode.v_modeattr) | V_INFO_VESA; + vesa_vmode[modes].vi_flags = + vesa_translate_flags(vmode.v_modeattr) | V_INFO_VESA; + ++modes; } vesa_vmode[modes].vi_mode = EOT; + 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 @@ -825,30 +1015,6 @@ vesa_clear_modes(video_info_t *info, int color) } } -static vm_offset_t -vesa_map_buffer(u_int paddr, size_t size) -{ - vm_offset_t vaddr; - u_int off; - - off = paddr - trunc_page(paddr); - vaddr = (vm_offset_t)pmap_mapdev(paddr - off, size + off); -#if VESA_DEBUG > 1 - printf("vesa_map_buffer: paddr:%x vaddr:%x size:%x off:%x\n", - paddr, vaddr, size, off); -#endif - return (vaddr + off); -} - -static void -vesa_unmap_buffer(vm_offset_t vaddr, size_t size) -{ -#if VESA_DEBUG > 1 - printf("vesa_unmap_buffer: vaddr:%x size:%x\n", vaddr, size); -#endif - kmem_free(kernel_map, vaddr, size); -} - /* entry points */ static int @@ -860,9 +1026,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 @@ -870,10 +1036,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 @@ -882,7 +1049,7 @@ vesa_configure(int flags) */ if (adp == NULL) { vga_sub_configure = vesa_configure; - return ENODEV; + return (ENODEV); } /* count number of registered adapters */ @@ -894,7 +1061,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; @@ -911,36 +1078,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 @@ -949,10 +1120,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); @@ -961,10 +1132,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 @@ -973,9 +1144,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) @@ -1001,19 +1172,18 @@ 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 vesa_set_mode(video_adapter_t *adp, int mode) { video_info_t info; - int len; 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); @@ -1030,11 +1200,16 @@ 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) { + if ((adp->va_flags & V_ADP_DAC8) != 0) { + vesa_bios_set_dac(6); + adp->va_flags &= ~V_ADP_DAC8; + } int10_set_mode(adp->va_initial_bios_mode); if (adp->va_info.vi_flags & V_INFO_LINEAR) - vesa_unmap_buffer(adp->va_buffer, - vesa_adp_info->v_memsize*64*1024); + pmap_unmapdev(adp->va_buffer, + adp->va_buffer_size); /* * Once (*prevvidsw->get_info)() succeeded, * (*prevvidsw->set_mode)() below won't fail... @@ -1043,12 +1218,12 @@ 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; + if (!VESA_MODE(mode) && (*prevvidsw->set_mode)(adp, mode) == 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 @@ -1059,11 +1234,19 @@ 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); + + /* Palette format is reset by the above VBE function call. */ + adp->va_flags &= ~V_ADP_DAC8; + + if ((vesa_adp_info->v_flags & V_DAC8) != 0 && + (info.vi_flags & V_INFO_GRAPHICS) != 0 && + (info.vi_flags & V_INFO_NONVGA) != 0 && + vesa_bios_set_dac(8) > 6) + adp->va_flags |= V_ADP_DAC8; if (adp->va_info.vi_flags & V_INFO_LINEAR) - vesa_unmap_buffer(adp->va_buffer, - vesa_adp_info->v_memsize*64*1024); + pmap_unmapdev(adp->va_buffer, adp->va_buffer_size); #if VESA_DEBUG > 0 printf("VESA: mode set!\n"); @@ -1079,183 +1262,161 @@ vesa_set_mode(video_adapter_t *adp, int mode) printf("VESA: setting up LFB\n"); #endif vesa_adp->va_buffer = - vesa_map_buffer(info.vi_buffer, - vesa_adp_info->v_memsize*64*1024); - vesa_adp->va_buffer_size = info.vi_buffer_size; + (vm_offset_t)pmap_mapdev_attr(info.vi_buffer, + info.vi_buffer_size, PAT_WRITE_COMBINING); vesa_adp->va_window = vesa_adp->va_buffer; - vesa_adp->va_window_size = info.vi_buffer_size/info.vi_planes; - vesa_adp->va_window_gran = info.vi_buffer_size/info.vi_planes; + vesa_adp->va_window_size = info.vi_buffer_size / info.vi_planes; + vesa_adp->va_window_gran = info.vi_buffer_size / info.vi_planes; } else { vesa_adp->va_buffer = 0; - vesa_adp->va_buffer_size = info.vi_buffer_size; - vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window); + vesa_adp->va_window = (vm_offset_t)x86bios_offset(info.vi_window); vesa_adp->va_window_size = info.vi_window_size; vesa_adp->va_window_gran = info.vi_window_gran; } + vesa_adp->va_buffer_size = info.vi_buffer_size; vesa_adp->va_window_orig = 0; - len = vesa_bios_get_line_length(); - if (len > 0) { - vesa_adp->va_line_width = len; - } else if (info.vi_flags & V_INFO_GRAPHICS) { - switch (info.vi_depth/info.vi_planes) { - case 1: - vesa_adp->va_line_width = info.vi_width/8; - break; - case 2: - vesa_adp->va_line_width = info.vi_width/4; - break; - case 4: - vesa_adp->va_line_width = info.vi_width/2; - break; - case 8: - default: /* shouldn't happen */ - vesa_adp->va_line_width = info.vi_width; - break; - case 15: - case 16: - vesa_adp->va_line_width = info.vi_width*2; - break; - case 24: - case 32: - vesa_adp->va_line_width = info.vi_width*4; - break; - } - } else { - vesa_adp->va_line_width = info.vi_width; - } + vesa_adp->va_line_width = info.vi_buffer_size / info.vi_height; + if ((info.vi_flags & V_INFO_GRAPHICS) != 0) + vesa_adp->va_line_width /= info.vi_planes; vesa_adp->va_disp_start.x = 0; vesa_adp->va_disp_start.y = 0; #if VESA_DEBUG > 0 - printf("vesa_set_mode(): vi_width:%d, len:%d, line_width:%d\n", - info.vi_width, len, vesa_adp->va_line_width); + printf("vesa_set_mode(): vi_width:%d, line_width:%d\n", + info.vi_width, vesa_adp->va_line_width); #endif bcopy(&info, &vesa_adp->va_info, sizeof(vesa_adp->va_info)); /* 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 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 && VESA_MODE(adp->va_mode) && + (adp->va_info.vi_flags & V_INFO_NONVGA) != 0) { + bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6; + return (vesa_bios_save_palette(0, 256, palette, bits)); } - return (*prevvidsw->save_palette)(adp, palette); + return ((*prevvidsw->save_palette)(adp, 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; + if (adp == vesa_adp && VESA_MODE(adp->va_mode) && + (adp->va_info.vi_flags & V_INFO_NONVGA) != 0) { + bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6; + return (vesa_bios_load_palette(0, 256, palette, bits)); } -#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); - if (vesa_state_buf_size == 0) + if (adp != vesa_adp) + return ((*prevvidsw->save_state)(adp, p, size)); + + 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 1; + 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; 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); - 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)); + + if (vesa_state_buf_size <= 0) + return (1); + + /* Try BIOS POST to restore a sane state. */ + (void)vesa_bios_post(); + (void)int10_set_mode(adp->va_initial_bios_mode); + + return (vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, + vesa_state_buf_size)); } #if 0 static int vesa_get_origin(video_adapter_t *adp, off_t *offset) { - struct vm86frame vmf; - int err; + x86regs_t regs; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f05; - vmf.vmf_ebx = 0x10; /* WINDOW_A, XXX */ - err = vm86_intcall(0x10, &vmf); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 1; - *offset = vmf.vmf_dx*adp->va_window_gran; - return 0; + x86bios_init_regs(®s); + regs.R_AX = 0x4f05; + regs.R_BL = 0x10; + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) + return (1); + *offset = regs.DX * adp->va_window_gran; + + return (0); } #endif static int vesa_set_origin(video_adapter_t *adp, off_t offset) { - struct vm86frame vmf; - int err; + x86regs_t regs; /* * This function should return as quickly as possible to @@ -1264,96 +1425,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); + + x86bios_init_regs(®s); + regs.R_AX = 0x4f05; + regs.R_DX = offset / adp->va_window_gran; + + x86bios_intr(®s, 0x10); + + if (regs.R_AX != 0x004f) + return (1); + + x86bios_init_regs(®s); + regs.R_AX = 0x4f05; + regs.R_BL = 1; + regs.R_DX = offset / adp->va_window_gran; + x86bios_intr(®s, 0x10); - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f05; - vmf.vmf_ebx = 0; /* WINDOW_A, XXX */ - vmf.vmf_edx = offset/adp->va_window_gran; - err = vm86_intcall(0x10, &vmf); - if ((err != 0) || (vmf.vmf_ax != 0x4f)) - return 1; - bzero(&vmf, sizeof(vmf)); - vmf.vmf_eax = 0x4f05; - vmf.vmf_ebx = 1; /* WINDOW_B, XXX */ - vmf.vmf_edx = offset/adp->va_window_gran; - err = vm86_intcall(0x10, &vmf); 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%x, buffer:0x%x, offset:0x%x\n", + 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 @@ -1366,18 +1538,17 @@ get_palette(video_adapter_t *adp, int base, int count, int bits; int error; - if ((base < 0) || (base >= 256) || (count < 0) || (count > 256)) - return 1; + if (base < 0 || base >= 256 || count < 0 || count > 256) + return (1); if ((base + count) > 256) - return 1; - if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode)) - return 1; + return (1); + if (!VESA_MODE(adp->va_mode)) + return (1); + if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0) + return (1); - bits = vesa_bios_get_dac(); - if (bits <= 6) - return 1; - - r = malloc(count*3, M_DEVBUF, M_WAITOK); + bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6; + 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); @@ -1392,29 +1563,30 @@ 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; -#ifdef notyet u_char *r; u_char *g; u_char *b; int bits; int error; - 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)) - return 1; + if (base < 0 || base >= 256 || count < 0 || count > 256) + return (1); + if ((base + count) > 256) + return (1); + if (!VESA_MODE(adp->va_mode)) + return (1); + if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0) + return (1); - r = malloc(count*3, M_DEVBUF, M_WAITOK); + bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6; + r = malloc(count * 3, M_DEVBUF, M_WAITOK); g = r + count; b = g + count; copyin(red, r, count); @@ -1423,13 +1595,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 @@ -1438,7 +1605,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 */ @@ -1448,24 +1615,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, @@ -1474,8 +1641,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 */ @@ -1485,8 +1652,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, @@ -1494,8 +1661,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, @@ -1503,11 +1670,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)); } } @@ -1519,15 +1686,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 @@ -1537,15 +1704,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); @@ -1555,9 +1723,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", @@ -1604,7 +1772,7 @@ vesa_bios_info(int level) } #endif /* VESA_DEBUG > 1 */ - return 0; + return (0); } /* module loading */ @@ -1616,7 +1784,7 @@ vesa_load(void) int s; if (vesa_init_done) - return 0; + return (0); /* locate a VGA adapter */ s = spltty(); @@ -1627,7 +1795,7 @@ vesa_load(void) if (error == 0) vesa_bios_info(bootverbose); - return error; + return (error); } static int @@ -1635,12 +1803,11 @@ vesa_unload(void) { u_char palette[256*3]; int error; - int bits; int s; /* 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 @@ -1649,15 +1816,11 @@ vesa_unload(void) s = spltty(); if ((error = vesa_unload_ioctl()) == 0) { if (vesa_adp != NULL) { - if (vesa_adp_info->v_flags & V_DAC8) { - bits = vesa_bios_get_dac(); - if (bits > 6) { - vesa_bios_save_palette(0, 256, - palette, bits); - vesa_bios_set_dac(6); - vesa_bios_load_palette(0, 256, - palette, 6); - } + if ((vesa_adp->va_flags & V_ADP_DAC8) != 0) { + vesa_bios_save_palette(0, 256, palette, 8); + vesa_bios_set_dac(6); + vesa_adp->va_flags &= ~V_ADP_DAC8; + vesa_bios_load_palette(0, 256, palette, 6); } vesa_adp->va_flags &= ~V_ADP_VESA; vidsw[vesa_adp->va_index] = prevvidsw; @@ -1665,24 +1828,30 @@ vesa_unload(void) } splx(s); - if (vesa_vm86_buf != NULL) - free(vesa_vm86_buf, M_DEVBUF); - - 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 = { @@ -1692,5 +1861,6 @@ static moduledata_t vesa_mod = { }; DECLARE_MODULE(vesa, vesa_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); +MODULE_DEPEND(vesa, x86bios, 1, 1, 1); #endif /* VGA_NO_MODE_CHANGE */ diff --git a/sys/i386/include/pc/vesa.h b/sys/dev/fb/vesa.h similarity index 86% rename from sys/i386/include/pc/vesa.h rename to sys/dev/fb/vesa.h index 06f1c1180b0..25b9bd50f2d 100644 --- a/sys/i386/include/pc/vesa.h +++ b/sys/dev/fb/vesa.h @@ -26,8 +26,8 @@ * $FreeBSD$ */ -#ifndef _MACHINE_PC_VESA_H -#define _MACHINE_PC_VESA_H +#ifndef _DEV_FB_VESA_H_ +#define _DEV_FB_VESA_H_ struct vesa_info { @@ -46,6 +46,8 @@ struct vesa_info u_int32_t v_venderstr; /* vender */ u_int32_t v_prodstr; /* product name */ u_int32_t v_revstr; /* product rev */ + u_int8_t v_strach[222]; + u_int8_t v_oemdata[256]; } __packed; struct vesa_mode @@ -106,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 @@ -117,4 +133,4 @@ int vesa_unload_ioctl(void); #endif -#endif /* !_MACHINE_PC_VESA_H */ +#endif /* !_DEV_FB_VESA_H_ */ diff --git a/sys/dev/fb/vga.c b/sys/dev/fb/vga.c index 425aec296cc..a2e99f2b24e 100644 --- a/sys/dev/fb/vga.c +++ b/sys/dev/fb/vga.c @@ -156,7 +156,7 @@ vga_mmap(struct cdev *dev, vga_softc_t *sc, vm_offset_t offset, vm_offset_t *pad #include #ifdef __i386__ -#include +#include #endif #define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED) 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/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index 3e5b1a64bdd..19fe9df7beb 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_RDTUN, + &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/dev/syscons/scvesactl.c b/sys/dev/syscons/scvesactl.c index 9a2c253869c..b896484bb76 100644 --- a/sys/dev/syscons/scvesactl.c +++ b/sys/dev/syscons/scvesactl.c @@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include #include diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c index 1ab41d2e5e4..fd823ce434b 100644 --- a/sys/dev/syscons/scvgarndr.c +++ b/sys/dev/syscons/scvgarndr.c @@ -193,6 +193,8 @@ static u_short mouse_or_mask[16] = { case 15: \ writew(pos, vga_palette15[color]); \ break; \ + case 8: \ + writeb(pos, (uint8_t)color); \ } static uint32_t vga_palette32[16] = { @@ -215,6 +217,7 @@ static uint16_t vga_palette15[16] = { #ifndef SC_NO_CUTPASTE static uint32_t mouse_buf32[256]; static uint16_t mouse_buf16[256]; +static uint8_t mouse_buf8[256]; #endif #endif @@ -498,7 +501,9 @@ vga_rndrinit(scr_stat *scp) scp->rndr->draw_cursor = vga_pxlcursor_planar; scp->rndr->blink_cursor = vga_pxlblink_planar; scp->rndr->draw_mouse = vga_pxlmouse_planar; - } else if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT) { + } else + if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT || + scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_PACKED) { scp->rndr->clear = vga_pxlclear_direct; scp->rndr->draw_border = vga_pxlborder_direct; scp->rndr->draw = vga_vgadraw_direct; @@ -1148,6 +1153,7 @@ vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on) int i, j; uint32_t *u32; uint16_t *u16; + uint8_t *u8; int bpp; if (!on) @@ -1179,6 +1185,10 @@ vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on) u16 = (uint16_t*)(p + j * pixel_size); writew(u16, mouse_buf16[i * 16 + j]); break; + case 8: + u8 = (uint8_t*)(p + j * pixel_size); + writeb(u8, mouse_buf8[i * 16 + j]); + break; } } @@ -1214,6 +1224,14 @@ vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on) else if (mouse_and_mask[i] & (1 << (15 - j))) writew(u16, 0); break; + case 8: + u8 = (uint8_t*)(p + j * pixel_size); + mouse_buf8[i * 16 + j] = *u8; + if (mouse_or_mask[i] & (1 << (15 - j))) + writeb(u8, 15); + else if (mouse_and_mask[i] & (1 << (15 - j))) + writeb(u8, 0); + break; } } diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c index d69e0a8fc36..0f55499bac7 100644 --- a/sys/dev/syscons/scvidctl.c +++ b/sys/dev/syscons/scvidctl.c @@ -369,30 +369,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize)) return EINVAL; - /* - * We currently support the following graphic modes: - * - * - 4 bpp planar modes whose memory size does not exceed 64K - * - 15, 16, 24 and 32 bpp linear modes - */ - - if (info.vi_mem_model == V_INFO_MM_PLANAR) { - if (info.vi_planes != 4) - return ENODEV; - - /* - * A memory size >64K requires bank switching to access the entire - * screen. XXX - */ - - if (info.vi_width * info.vi_height / 8 > info.vi_window_size) - return ENODEV; - } else if (info.vi_mem_model == V_INFO_MM_DIRECT) { - if (!(info.vi_flags & V_INFO_LINEAR) && - (info.vi_depth != 15) && (info.vi_depth != 16) && - (info.vi_depth != 24) && (info.vi_depth != 32)) - return ENODEV; - } else + if (!sc_support_pixel_mode(&info)) return ENODEV; /* stop screen saver, etc */ @@ -468,6 +445,48 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, #endif /* SC_PIXEL_MODE */ } +int +sc_support_pixel_mode(void *arg) +{ +#ifdef SC_PIXEL_MODE + video_info_t *info = arg; + + if ((info->vi_flags & V_INFO_GRAPHICS) == 0) + return (0); + + /* + * We currently support the following graphic modes: + * + * - 4 bpp planar modes whose memory size does not exceed 64K + * - 15, 16, 24 and 32 bpp linear modes + */ + switch (info->vi_mem_model) { + case V_INFO_MM_PLANAR: + if (info->vi_planes != 4) + break; + /* + * A memory size >64K requires bank switching to access + * the entire screen. XXX + */ + if (info->vi_width * info->vi_height / 8 > info->vi_window_size) + break; + return (1); + case V_INFO_MM_DIRECT: + if ((info->vi_flags & V_INFO_LINEAR) == 0 && + info->vi_depth != 15 && info->vi_depth != 16 && + info->vi_depth != 24 && info->vi_depth != 32) + break; + return (1); + case V_INFO_MM_PACKED: + if ((info->vi_flags & V_INFO_LINEAR) == 0 && + info->vi_depth != 8) + break; + return (1); + } +#endif + return (0); +} + #define fb_ioctl(a, c, d) \ (((a) == NULL) ? ENODEV : \ vidd_ioctl((a), (c), (caddr_t)(d))) @@ -721,6 +740,11 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) #endif #ifndef SC_NO_PALETTE_LOADING +#ifdef SC_PIXEL_MODE + if ((adp->va_flags & V_ADP_DAC8) != 0) + vidd_load_palette(adp, scp->sc->palette2); + else +#endif vidd_load_palette(adp, scp->sc->palette); #endif @@ -778,7 +802,10 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) if (scp == scp->sc->cur_scp) { set_mode(scp); #ifndef SC_NO_PALETTE_LOADING - vidd_load_palette(adp, scp->sc->palette); + if ((adp->va_flags & V_ADP_DAC8) != 0) + vidd_load_palette(adp, scp->sc->palette2); + else + vidd_load_palette(adp, scp->sc->palette); #endif } sc_clear_screen(scp); diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 653ff08274a..8dffe5cd538 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -342,16 +343,105 @@ sc_alloc_tty(int index, int devnum) return (tp); } +#ifdef SC_PIXEL_MODE +static void +sc_set_vesa_mode(scr_stat *scp, sc_softc_t *sc, int unit) +{ + video_info_t info; + int depth; + int i; + int vmode; + + vmode = 0; + (void)resource_int_value("sc", unit, "vesa_mode", &vmode); + if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX || + vidd_get_info(sc->adp, vmode, &info) != 0 || + !sc_support_pixel_mode(&info)) + vmode = 0; + + /* + * If the mode is unset or unsupported, search for an available + * 800x600 graphics mode with the highest color depth. + */ + if (vmode == 0) { + for (depth = 0, i = M_VESA_BASE; i <= M_VESA_MODE_MAX; i++) + if (vidd_get_info(sc->adp, i, &info) == 0 && + info.vi_width == 800 && info.vi_height == 600 && + sc_support_pixel_mode(&info) && + info.vi_depth > depth) { + vmode = i; + depth = info.vi_depth; + } + if (vmode == 0) + return; + vidd_get_info(sc->adp, vmode, &info); + } + +#ifndef SC_NO_FONT_LOADING + if ((sc->fonts_loaded & FONT_16) == 0) + return; +#endif +#ifdef DEV_SPLASH + if ((sc->flags & SC_SPLASH_SCRN) != 0) + splash_term(sc->adp); +#endif +#ifndef SC_NO_HISTORY + if (scp->history != NULL) { + sc_vtb_append(&scp->vtb, 0, scp->history, + scp->ypos * scp->xsize + scp->xpos); + scp->history_pos = sc_vtb_tail(scp->history); + } +#endif + vidd_set_mode(sc->adp, vmode); + scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN); + scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE); + scp->xpixel = info.vi_width; + scp->ypixel = info.vi_height; + scp->xsize = scp->xpixel / 8; + scp->ysize = scp->ypixel / 16; + scp->xpos = 0; + scp->ypos = scp->ysize - 1; + scp->xoff = scp->yoff = 0; +#ifndef SC_NO_FONT_LOADING + scp->font = sc->font_16; +#else + scp->font = NULL; +#endif + scp->font_size = 16; + scp->font_width = 8; + scp->start = scp->xsize * scp->ysize - 1; + scp->end = 0; + scp->cursor_pos = scp->cursor_oldpos = scp->xsize * scp->xsize; + scp->mode = sc->initial_mode = vmode; +#ifndef __sparc64__ + sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize, + (void *)sc->adp->va_window, FALSE); +#endif + sc_alloc_scr_buffer(scp, FALSE, FALSE); + sc_init_emulator(scp, NULL); +#ifndef SC_NO_CUTPASTE + sc_alloc_cut_buffer(scp, FALSE); +#endif +#ifndef SC_NO_HISTORY + sc_alloc_history_buffer(scp, 0, 0, FALSE); +#endif + sc_set_border(scp, scp->border); + sc_set_cursor_image(scp); + scp->status &= ~UNKNOWN_MODE; +#ifdef DEV_SPLASH + if ((sc->flags & SC_SPLASH_SCRN) != 0) + splash_init(sc->adp, scsplash_callback, sc); +#endif +} +#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; + int vc; flags &= ~SC_KERNEL_CONSOLE; @@ -373,21 +463,8 @@ sc_attach_unit(int unit, int flags) sc_console = scp; #ifdef SC_PIXEL_MODE - if ((sc->config & SC_VESA800X600) - && (vidd_get_info(sc->adp, M_VESA_800x600, &info) == 0)) { -#ifdef DEV_SPLASH - if (sc->flags & SC_SPLASH_SCRN) - splash_term(sc->adp); -#endif - sc_set_graphics_mode(scp, NULL, M_VESA_800x600); - sc_set_pixel_mode(scp, NULL, COL, ROW, 16, 8); - sc->initial_mode = M_VESA_800x600; -#ifdef DEV_SPLASH - /* put up the splash again! */ - if (sc->flags & SC_SPLASH_SCRN) - splash_init(sc->adp, scsplash_callback, sc); -#endif - } + if ((sc->config & SC_VESAMODE) != 0) + sc_set_vesa_mode(scp, sc, unit); #endif /* SC_PIXEL_MODE */ /* initialize cursor */ @@ -517,7 +594,7 @@ sctty_open(struct tty *tp) if (scp == NULL) { scp = SC_STAT(tp) = alloc_scp(sc, SC_VTY(tp)); if (ISGRAPHSC(scp)) - sc_set_pixel_mode(scp, NULL, COL, ROW, 16, 8); + sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8); } if (!tp->t_winsize.ws_col && !tp->t_winsize.ws_row) { tp->t_winsize.ws_col = scp->xsize; @@ -2049,6 +2126,11 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode) } if (set_mode(scp) == 0) { #ifndef SC_NO_PALETTE_LOADING +#ifdef SC_PIXEL_MODE + if ((scp->sc->adp->va_flags & V_ADP_DAC8) != 0) + vidd_load_palette(scp->sc->adp, scp->sc->palette2); + else +#endif vidd_load_palette(scp->sc->adp, scp->sc->palette); #endif --scrn_blanked; @@ -2452,8 +2534,14 @@ exchange_scr(sc_softc_t *sc) if (!ISGRAPHSC(scp)) sc_set_cursor_image(scp); #ifndef SC_NO_PALETTE_LOADING - if (ISGRAPHSC(sc->old_scp)) + if (ISGRAPHSC(sc->old_scp)) { +#ifdef SC_PIXEL_MODE + if ((sc->adp->va_flags & V_ADP_DAC8) != 0) + vidd_load_palette(sc->adp, sc->palette2); + else +#endif vidd_load_palette(sc->adp, sc->palette); + } #endif sc_set_border(scp, scp->border); @@ -2802,6 +2890,10 @@ scinit(int unit, int flags) #ifndef SC_NO_PALETTE_LOADING vidd_save_palette(sc->adp, sc->palette); +#ifdef SC_PIXEL_MODE + for (i = 0; i < sizeof(sc->palette2); i++) + sc->palette2[i] = i / 3; +#endif #endif #ifdef DEV_SPLASH @@ -2995,6 +3087,8 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp) scp->ysize = info.vi_height; scp->xpixel = scp->xsize*info.vi_cwidth; scp->ypixel = scp->ysize*info.vi_cheight; + } + scp->font_size = info.vi_cheight; scp->font_width = info.vi_cwidth; if (info.vi_cheight < 14) { @@ -3016,7 +3110,7 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp) scp->font = NULL; #endif } - } + sc_vtb_init(&scp->vtb, VTB_MEMORY, 0, 0, NULL, FALSE); #ifndef __sparc64__ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, 0, 0, NULL, FALSE); diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h index c0ed6c1fd64..aab6b5c82f1 100644 --- a/sys/dev/syscons/syscons.h +++ b/sys/dev/syscons/syscons.h @@ -191,7 +191,7 @@ struct tty; typedef struct sc_softc { int unit; /* unit # */ int config; /* configuration flags */ -#define SC_VESA800X600 (1 << 7) +#define SC_VESAMODE (1 << 7) #define SC_AUTODETECT_KBD (1 << 8) #define SC_KERNEL_CONSOLE (1 << 9) @@ -245,7 +245,10 @@ typedef struct sc_softc { #endif #ifndef SC_NO_PALETTE_LOADING - u_char palette[256*3]; + u_char palette[256 * 3]; +#ifdef SC_PIXEL_MODE + u_char palette2[256 * 3]; +#endif #endif #ifndef SC_NO_FONT_LOADING @@ -616,6 +619,7 @@ int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode); int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, int fontsize, int font_width); +int sc_support_pixel_mode(void *arg); int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td); diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index c4d24d71016..22ae19e2627 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -361,6 +361,9 @@ options VESA_DEBUG device dpms # DPMS suspend & resume via VESA BIOS +# x86 real mode BIOS emulator, required by atkbdc/dpms/vesa +options X86BIOS + # # The Numeric Processing eXtension driver. This is non-optional. device npx @@ -444,6 +447,9 @@ options VGA_WIDTH90 # support 90 column modes # Debugging. options VGA_DEBUG +# Linear framebuffer driver for S3 VESA 1.2 cards. Works on top of VESA. +device s3pci + # 3Dfx Voodoo Graphics, Voodoo II /dev/3dfx CDEV support. This will create # the /dev/3dfx0 device to work with glide implementations. This should get # linked to /dev/3dfx and /dev/voodoo. Note that this is not the same as diff --git a/sys/isa/vga_isa.c b/sys/isa/vga_isa.c index 3d7cd3ad9fd..f9b26302d7d 100644 --- a/sys/isa/vga_isa.c +++ b/sys/isa/vga_isa.c @@ -59,6 +59,69 @@ __FBSDID("$FreeBSD$"); #include #include +static void +vga_suspend(device_t dev) +{ + vga_softc_t *sc; + int nbytes; + + sc = device_get_softc(dev); + + /* 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; + sc->pal_buf = malloc(256 * 3, M_TEMP, M_NOWAIT); + if (sc->pal_buf == NULL) + return; + 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; + } +} + +static void +vga_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"); + 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; + } +} + #define VGA_SOFTC(unit) \ ((vga_softc_t *)devclass_get_softc(isavga_devclass, unit)) @@ -103,9 +166,9 @@ isavga_probe(device_t dev) if (isa_get_vendorid(dev)) return (ENXIO); - device_set_desc(dev, "Generic ISA VGA"); error = vga_probe_unit(device_get_unit(dev), &adp, device_get_flags(dev)); if (error == 0) { + device_set_desc(dev, "Generic ISA VGA"); bus_set_resource(dev, SYS_RES_IOPORT, 0, adp.va_io_base, adp.va_io_size); bus_set_resource(dev, SYS_RES_MEMORY, 0, @@ -117,7 +180,7 @@ isavga_probe(device_t dev) isa_set_msize(dev, adp.va_mem_size); #endif } - return error; + return (error); } static int @@ -140,13 +203,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,57 +220,29 @@ isavga_attach(device_t dev) bus_generic_attach(dev); #endif - return 0; + return (0); } static int isavga_suspend(device_t dev) { - vga_softc_t *sc; - int err, nbytes; + int error; - sc = device_get_softc(dev); - err = bus_generic_suspend(dev); - if (err) - return (err); + error = bus_generic_suspend(dev); + if (error != 0) + return (error); + vga_suspend(dev); - /* Save the video state across the suspend. */ - if (sc->state_buf != NULL) { - 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 | 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; - } - return (0); + return (error); } static int 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"); - free(sc->state_buf, M_TEMP); - sc->state_buf = NULL; - } + vga_resume(dev); - bus_generic_resume(dev); - return 0; + return (bus_generic_resume(dev)); } #ifdef FB_INSTALL_CDEV @@ -215,37 +250,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 */ @@ -268,3 +303,79 @@ static driver_t isavga_driver = { }; DRIVER_MODULE(vga, isa, isavga_driver, isavga_devclass, 0, 0); + +static devclass_t vgapm_devclass; + +static void +vgapm_identify(driver_t *driver, device_t parent) +{ + + if (device_get_flags(parent) != 0) + device_add_child(parent, "vgapm", 0); +} + +static int +vgapm_probe(device_t dev) +{ + + device_set_desc(dev, "VGA suspend/resume"); + device_quiet(dev); + + return (BUS_PROBE_DEFAULT); +} + +static int +vgapm_attach(device_t dev) +{ + + bus_generic_probe(dev); + bus_generic_attach(dev); + + return (0); +} + +static int +vgapm_suspend(device_t dev) +{ + device_t vga_dev; + int error; + + error = bus_generic_suspend(dev); + if (error != 0) + return (error); + vga_dev = devclass_get_device(isavga_devclass, 0); + if (vga_dev == NULL) + return (0); + vga_suspend(vga_dev); + + return (0); +} + +static int +vgapm_resume(device_t dev) +{ + device_t vga_dev; + + vga_dev = devclass_get_device(isavga_devclass, 0); + if (vga_dev != NULL) + vga_resume(vga_dev); + + return (bus_generic_resume(dev)); +} + +static device_method_t vgapm_methods[] = { + DEVMETHOD(device_identify, vgapm_identify), + DEVMETHOD(device_probe, vgapm_probe), + DEVMETHOD(device_attach, vgapm_attach), + DEVMETHOD(device_suspend, vgapm_suspend), + DEVMETHOD(device_resume, vgapm_resume), + { 0, 0 } +}; + +static driver_t vgapm_driver = { + "vgapm", + vgapm_methods, + 0 +}; + +DRIVER_MODULE(vgapm, vgapci, vgapm_driver, vgapm_devclass, 0, 0); diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 07e4bfbacd1..9b7d5504c8b 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -300,6 +300,7 @@ SUBDIR= ${_3dfx} \ wlan_xauth \ ${_wpi} \ ${_wpifw} \ + ${_x86bios} \ ${_xe} \ xfs \ xl \ @@ -463,6 +464,7 @@ _padlock= padlock _s3= s3 _twa= twa _vesa= vesa +_x86bios= x86bios .elif ${MACHINE} == "pc98" _canbepm= canbepm _canbus= canbus @@ -490,6 +492,7 @@ _cpufreq= cpufreq .if ${MK_CDDL} != "no" || defined(ALL_MODULES) _cyclic= cyclic .endif +_dpms= dpms _drm= drm .if ${MK_CDDL} != "no" || defined(ALL_MODULES) _dtrace= dtrace @@ -538,14 +541,18 @@ _padlock= padlock .endif _pccard= pccard _rdma= rdma +_s3= s3 _safe= safe _scsi_low= scsi_low _smbfs= smbfs _sound= sound _speaker= speaker +_splash= splash _sppp= sppp _tmpfs= tmpfs _twa= twa +_vesa= vesa +_x86bios= x86bios _wi= wi _wpi= wpi _wpifw= wpifw diff --git a/sys/modules/dpms/Makefile b/sys/modules/dpms/Makefile index a58072e994f..4eabf14fc98 100644 --- a/sys/modules/dpms/Makefile +++ b/sys/modules/dpms/Makefile @@ -1,9 +1,9 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../i386/isa - KMOD= dpms -SRCS= dpms.c -SRCS+= bus_if.h device_if.h +SRCS= bus_if.h device_if.h pci_if.h + +.PATH: ${.CURDIR}/../../dev/dpms +SRCS+= dpms.c .include diff --git a/sys/modules/vesa/Makefile b/sys/modules/vesa/Makefile index eb49f933c9b..69a0c330688 100644 --- a/sys/modules/vesa/Makefile +++ b/sys/modules/vesa/Makefile @@ -1,8 +1,13 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../dev/syscons ${.CURDIR}/../../i386/isa - KMOD= vesa -SRCS= vesa.c scvesactl.c opt_vga.h opt_vesa.h +SRCS= opt_vga.h opt_vesa.h +SRCS+= bus_if.h device_if.h pci_if.h + +.PATH: ${.CURDIR}/../../dev/fb +SRCS+= vesa.c + +.PATH: ${.CURDIR}/../../dev/syscons +SRCS+= scvesactl.c .include diff --git a/sys/modules/x86bios/Makefile b/sys/modules/x86bios/Makefile new file mode 100644 index 00000000000..3cab2853172 --- /dev/null +++ b/sys/modules/x86bios/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +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 x86emu.c + +.include diff --git a/sys/modules/x86emu/Makefile b/sys/modules/x86emu/Makefile new file mode 100644 index 00000000000..3991d6c70d0 --- /dev/null +++ b/sys/modules/x86emu/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../contrib/x86emu + +KMOD= x86emu +SRCS= x86emu.c x86emu_util.c + +.include diff --git a/sys/sys/fbio.h b/sys/sys/fbio.h index c7183dfc38c..5745182316b 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; @@ -331,6 +332,7 @@ struct video_adapter { #define V_ADP_INITIALIZED (1 << 17) #define V_ADP_REGISTERED (1 << 18) #define V_ADP_ATTACHED (1 << 19) +#define V_ADP_DAC8 (1 << 20) vm_offset_t va_io_base; int va_io_size; vm_offset_t va_crtc_addr; diff --git a/sys/sys/param.h b/sys/sys/param.h index 6da5e607b1e..35caa514017 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 800503 /* Master, propagated to newvers */ +#define __FreeBSD_version 800504 /* Master, propagated to newvers */ #ifndef LOCORE #include From a131b83ef074d21c10acd5ec7e684596c9eaa420 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 2 Mar 2010 07:48:12 +0000 Subject: [PATCH 1530/2592] MFC r197042: remove dpms.4. --- share/man/man4/man4.i386/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/share/man/man4/man4.i386/Makefile b/share/man/man4/man4.i386/Makefile index 9608ddf2c23..803dfd88238 100644 --- a/share/man/man4/man4.i386/Makefile +++ b/share/man/man4/man4.i386/Makefile @@ -10,7 +10,6 @@ MAN= aic.4 \ cs.4 \ ct.4 \ ctau.4 \ - dpms.4 \ cx.4 \ ep.4 \ ex.4 \ From 61865144b3888290f92ee3a57920c1d33a68c146 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Tue, 2 Mar 2010 10:05:20 +0000 Subject: [PATCH 1531/2592] MFC of r204566, tzdata2010c: Paraguay changes its DST schedule, postponing the March rule to April and modifying the October date. --- share/zoneinfo/southamerica | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/share/zoneinfo/southamerica b/share/zoneinfo/southamerica index 9c4edcb7ceb..7ad8170826c 100644 --- a/share/zoneinfo/southamerica +++ b/share/zoneinfo/southamerica @@ -1,5 +1,5 @@ #

    -# @(#)southamerica	8.40
    +# @(#)southamerica	8.41
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -1364,8 +1364,24 @@ Rule	Para	2002	2003	-	Sep	Sun>=1	0:00	1:00	S
     # Decree 1,867 (2004-03-05)
     # From Carlos Raul Perasso via Jesper Norgaard Welen (2006-10-13)
     # 
    -Rule	Para	2004	max	-	Oct	Sun>=15	0:00	1:00	S
    -Rule	Para	2005	max	-	Mar	Sun>=8	0:00	0	-
    +Rule	Para	2004	2009	-	Oct	Sun>=15	0:00	1:00	S
    +Rule	Para	2005	2009	-	Mar	Sun>=8	0:00	0	-
    +# From Carlos Raul Perasso (2010-02-18):
    +# By decree number 3958 issued yesterday (
    +# 
    +# http://www.presidencia.gov.py/v1/wp-content/uploads/2010/02/decreto3958.pdf
    +# 
    +# )
    +# Paraguay changes its DST schedule, postponing the March rule to April and
    +# modifying the October date. The decree reads:
    +# ...
    +# Art. 1. It is hereby established that from the second Sunday of the month of
    +# April of this year (2010), the official time is to be set back 60 minutes,
    +# and that on the first Sunday of the month of October, it is to be set
    +# forward 60 minutes, in all the territory of the Paraguayan Republic.
    +# ...
    +Rule	Para	2010	max	-	Oct	Sun<=7	0:00	1:00	S
    +Rule	Para	2010	max	-	Apr	Sun>=8	0:00	0	-
     
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
     Zone America/Asuncion	-3:50:40 -	LMT	1890
    
    From bfc990442477460a3a5faecf12c39d0440037324 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 2 Mar 2010 10:32:34 +0000
    Subject: [PATCH 1532/2592] MFC r204412: Fix several style issues. Define
     make_dev_credv() as static to match declaration.
    
    ---
     sys/kern/kern_conf.c | 7 +++++--
     1 file changed, 5 insertions(+), 2 deletions(-)
    
    diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
    index e570fddbea3..daf0e95cace 100644
    --- a/sys/kern/kern_conf.c
    +++ b/sys/kern/kern_conf.c
    @@ -655,7 +655,7 @@ prep_cdevsw(struct cdevsw *devsw)
     		cdevsw_free_devlocked(dsw2);
     }
     
    -struct cdev *
    +static struct cdev *
     make_dev_credv(int flags, struct cdevsw *devsw, int unit,
         struct ucred *cr, uid_t uid,
         gid_t gid, int mode, const char *fmt, va_list ap)
    @@ -953,7 +953,8 @@ clone_setup(struct clonedevs **cdp)
     }
     
     int
    -clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up, struct cdev **dp, int extra)
    +clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up,
    +    struct cdev **dp, int extra)
     {
     	struct clonedevs *cd;
     	struct cdev *dev, *ndev, *dl, *de;
    @@ -1124,6 +1125,7 @@ destroy_dev_sched_cbl(struct cdev *dev, void (*cb)(void *), void *arg)
     int
     destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg)
     {
    +
     	dev_lock();
     	return (destroy_dev_sched_cbl(dev, cb, arg));
     }
    @@ -1131,6 +1133,7 @@ destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg)
     int
     destroy_dev_sched(struct cdev *dev)
     {
    +
     	return (destroy_dev_sched_cb(dev, NULL, NULL));
     }
     
    
    From 95e5a0907c6e2b65c9f8d2483c63cf14e674e9b0 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 2 Mar 2010 10:41:34 +0000
    Subject: [PATCH 1533/2592] MFC r204415: Update comment for vm_page_alloc(9),
     listing all acceptable flags [1]. Note that the function does not sleep, it
     can block.
    
    ---
     sys/vm/vm_page.c | 7 ++++++-
     1 file changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
    index ac363b70166..8ba2f7f7ad0 100644
    --- a/sys/vm/vm_page.c
    +++ b/sys/vm/vm_page.c
    @@ -1020,8 +1020,13 @@ vm_page_cache_transfer(vm_object_t orig_object, vm_pindex_t offidxstart,
      *	VM_ALLOC_SYSTEM		system *really* needs a page
      *	VM_ALLOC_INTERRUPT	interrupt time request
      *	VM_ALLOC_ZERO		zero page
    + *	VM_ALLOC_WIRED		wire the allocated page
    + *	VM_ALLOC_NOOBJ		page is not associated with a vm object
    + *	VM_ALLOC_NOBUSY		do not set the page busy
    + *	VM_ALLOC_IFNOTCACHED	return NULL, do not reactivate if the page
    + *				is cached
      *
    - *	This routine may not block.
    + *	This routine may not sleep.
      */
     vm_page_t
     vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
    
    From 29d703dd0ac828ec23a471a861f40670b49c9e43 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 2 Mar 2010 11:00:10 +0000
    Subject: [PATCH 1534/2592] MFC r204416: Update man page for vm_page_alloc(9).
    
    ---
     share/man/man9/vm_page_alloc.9 | 40 ++++++++++++++++++++++++++--------
     1 file changed, 31 insertions(+), 9 deletions(-)
    
    diff --git a/share/man/man9/vm_page_alloc.9 b/share/man/man9/vm_page_alloc.9
    index 02e2b939b48..81070d665ef 100644
    --- a/share/man/man9/vm_page_alloc.9
    +++ b/share/man/man9/vm_page_alloc.9
    @@ -26,7 +26,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd July 13, 2001
    +.Dd February 27, 2010
     .Dt VM_PAGE_ALLOC 9
     .Os
     .Sh NAME
    @@ -48,16 +48,26 @@ within
     .Fa object .
     It is assumed that a page has not already been allocated at
     .Fa pindex .
    -The page returned is inserted into the object, but is not inserted
    -into the pmap.
    +The page returned is inserted into the object, unless
    +.Dv VM_ALLOC_NOOBJ
    +is specified in the
    +.Fa page_req ,
    +but is not inserted into a pmap.
    +The page may exists in the vm object cache, in which case it will
    +be reactivated instead, moving from the cache into the object page list.
     .Pp
     .Fn vm_page_alloc
    -will not block.
    +will not sleep.
     .Pp
     Its arguments are:
     .Bl -tag -width ".Fa page_req"
     .It Fa object
     The VM object to allocate the page for.
    +The
    +.Fa object
    +must be locked if
    +.Dv VM_ALLOC_NOOBJ
    +is not specified.
     .It Fa pindex
     The index into the object at which the page should be inserted.
     .It Fa page_req
    @@ -82,12 +92,24 @@ than zero.
     .It Dv VM_ALLOC_ZERO
     Indicate a preference for a pre-zeroed page.
     There is no guarantee that the page thus returned will be zeroed, but
    -it will be marked as such.
    +it will be marked by
    +.Dv PG_ZERO
    +flag if it is zeroed.
     .It Dv VM_ALLOC_NOOBJ
    -The page is associated with an unmanaged memory region, that is, there
    -is no backing VM object.
    -This is typically used to allocate pages within the kernel virtual
    -address space.
    +Do not associate the allocated page with a vm object.
    +The
    +.Fa object
    +argument is ignored.
    +.It Dv VM_ALLOC_NOBUSY
    +The page returned will not be busied.
    +.It Dv VM_ALLOC_WIRED
    +The returned page is wired.
    +.It Dv VM_ALLOC_IFNOTCACHED
    +Only allocate the page if it is not cached in the
    +.Fa object .
    +If the page at the specified
    +.Fa pindex
    +is cached, NULL is returned instead.
     .El
     .El
     .Sh RETURN VALUES
    
    From 2d057e0f6a593a9f64c23fb70498265227f025cb Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Tue, 2 Mar 2010 13:13:12 +0000
    Subject: [PATCH 1535/2592] MFC r197948 r203156 r203158 r203159 r203680 r203682
     r203750 r203882 r203930     r203933 r203959 r204521 r204578:
    
    Atheros AR9285 support.
    ---
     sys/conf/files                                |  91 +-
     sys/dev/ath/ath_hal/ah.h                      |   4 +
     sys/dev/ath/ath_hal/ah_eeprom_v14.h           |   3 +-
     sys/dev/ath/ath_hal/ah_eeprom_v4k.c           | 404 ++++++++
     sys/dev/ath/ath_hal/ah_eeprom_v4k.h           | 155 +++
     sys/dev/ath/ath_hal/ar5212/ar5212.h           |   3 +
     sys/dev/ath/ath_hal/ar5212/ar5212_attach.c    |   3 +
     sys/dev/ath/ath_hal/ar5212/ar5212_power.c     |   6 +-
     sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c      |  11 +-
     sys/dev/ath/ath_hal/ar5212/ar5212reg.h        |   1 +
     sys/dev/ath/ath_hal/ar5416/ar5416.h           |  17 +
     sys/dev/ath/ath_hal/ar5416/ar5416_ani.c       |   6 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_attach.c    |   2 +
     sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c    |   2 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c |   2 +-
     .../ath/ath_hal/ar5416/ar5416_cal_adcgain.c   |   2 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_cal_iq.c    |   2 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_eeprom.c    |   2 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c      |   4 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_keycache.c  |   2 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_misc.c      |   4 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_phy.c       |   2 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_power.c     |   2 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_recv.c      |   2 +-
     sys/dev/ath/ath_hal/ar5416/ar5416_reset.c     |  30 +-
     sys/dev/ath/ath_hal/ar5416/ar5416desc.h       |   2 +-
     sys/dev/ath/ath_hal/ar5416/ar5416phy.h        |  21 +-
     sys/dev/ath/ath_hal/ar5416/ar5416reg.h        | 134 ++-
     sys/dev/ath/ath_hal/ar5416/ar9280.h           |   5 +
     sys/dev/ath/ath_hal/ar5416/ar9280_attach.c    |   4 +-
     sys/dev/ath/ath_hal/ar5416/ar9285.c           |  64 ++
     sys/dev/ath/ath_hal/ar5416/ar9285.h           |  43 +
     sys/dev/ath/ath_hal/ar5416/ar9285.ini         | 699 +++++++++++++
     sys/dev/ath/ath_hal/ar5416/ar9285_attach.c    | 397 ++++++++
     sys/dev/ath/ath_hal/ar5416/ar9285_reset.c     | 951 ++++++++++++++++++
     sys/dev/ath/ath_hal/ar5416/ar9285v2.ini       | 746 ++++++++++++++
     sys/modules/ath/Makefile                      |   1 +
     37 files changed, 3717 insertions(+), 112 deletions(-)
     create mode 100644 sys/dev/ath/ath_hal/ah_eeprom_v4k.c
     create mode 100644 sys/dev/ath/ath_hal/ah_eeprom_v4k.h
     create mode 100644 sys/dev/ath/ath_hal/ar5416/ar9285.c
     create mode 100644 sys/dev/ath/ath_hal/ar5416/ar9285.h
     create mode 100644 sys/dev/ath/ath_hal/ar5416/ar9285.ini
     create mode 100644 sys/dev/ath/ath_hal/ar5416/ar9285_attach.c
     create mode 100644 sys/dev/ath/ath_hal/ar5416/ar9285_reset.c
     create mode 100644 sys/dev/ath/ath_hal/ar5416/ar9285v2.ini
    
    diff --git a/sys/conf/files b/sys/conf/files
    index 588e7d737c0..313b51e0116 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -554,6 +554,9 @@ dev/ath/ath_hal/ah_eeprom_v3.c	optional ath_hal | ath_ar5211 | ath_ar5212 \
     dev/ath/ath_hal/ah_eeprom_v14.c \
     	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
     	compile-with "${NORMAL_C} -I$S/dev/ath"
    +dev/ath/ath_hal/ah_eeprom_v4k.c \
    +	optional ath_hal | ath_ar9285 \
    +	compile-with "${NORMAL_C} -I$S/dev/ath"
     dev/ath/ath_hal/ah_regdomain.c	optional ath \
     	compile-with "${NORMAL_C} -I$S/dev/ath"
     # ar5210
    @@ -600,104 +603,124 @@ dev/ath/ath_hal/ar5211/ar5211_xmit.c		optional ath_hal | ath_ar5211 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     # ar5212
     dev/ath/ath_hal/ar5212/ar5212_ani.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_attach.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_beacon.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_eeprom.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_gpio.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_interrupts.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_keycache.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_misc.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_phy.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_power.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_recv.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_reset.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_rfgain.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5212/ar5212_xmit.c \
    -	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \
    +	ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     # ar5416 (depends on ar5212)
     dev/ath/ath_hal/ar5416/ar5416_ani.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_attach.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_beacon.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_cal.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_cal_iq.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_cal_adcgain.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_eeprom.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_gpio.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_interrupts.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_keycache.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_misc.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_phy.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_power.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_recv.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_reset.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar5416_xmit.c \
    -	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \
    +	optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     # ar9160 (depends on ar5416)
     dev/ath/ath_hal/ar5416/ar9160_attach.c optional ath_hal | ath_ar9160 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     # ar9280 (depends on ar5416)
    -dev/ath/ath_hal/ar5416/ar9280_attach.c optional ath_hal | ath_ar9280 \
    +dev/ath/ath_hal/ar5416/ar9280_attach.c optional ath_hal | ath_ar9280 | \
    +	ath_ar9285 \ 
    +	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
    +# ar9285 (depends on ar5416 and ar9280)
    +dev/ath/ath_hal/ar5416/ar9285_attach.c optional ath_hal | ath_ar9285 \ 
    +	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
    +dev/ath/ath_hal/ar5416/ar9285_reset.c optional ath_hal | ath_ar9285 \ 
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     # rf backends
     dev/ath/ath_hal/ar5212/ar2316.c	optional ath_rf2316 \
    @@ -716,7 +739,9 @@ dev/ath/ath_hal/ar5212/ar5413.c	optional ath_hal | ath_rf5413 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     dev/ath/ath_hal/ar5416/ar2133.c optional ath_hal | ath_ar5416 | ath_ar9160 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
    -dev/ath/ath_hal/ar5416/ar9280.c optional ath_hal | ath_ar9280 \
    +dev/ath/ath_hal/ar5416/ar9280.c optional ath_hal | ath_ar9280 | ath_ar9285 \
    +	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
    +dev/ath/ath_hal/ar5416/ar9285.c optional ath_hal | ath_ar9285 \
     	compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal"
     # ath rate control algorithms
     dev/ath/ath_rate/amrr/amrr.c	optional ath_rate_amrr \
    diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h
    index f7434f87eef..26288489a8c 100644
    --- a/sys/dev/ath/ath_hal/ah.h
    +++ b/sys/dev/ath/ath_hal/ah.h
    @@ -638,7 +638,11 @@ struct ath_hal {
     			HAL_BOOL longCal, HAL_BOOL *isCalDone);
     	HAL_BOOL  __ahdecl(*ah_resetCalValid)(struct ath_hal *,
     			const struct ieee80211_channel *);
    +	HAL_BOOL  __ahdecl(*ah_setTxPower)(struct ath_hal *,
    +	    		const struct ieee80211_channel *, uint16_t *);
     	HAL_BOOL  __ahdecl(*ah_setTxPowerLimit)(struct ath_hal *, uint32_t);
    +	HAL_BOOL  __ahdecl(*ah_setBoardValues)(struct ath_hal *,
    +	    		const struct ieee80211_channel *);
     
     	/* Transmit functions */
     	HAL_BOOL  __ahdecl(*ah_updateTxTrigLevel)(struct ath_hal*,
    diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v14.h b/sys/dev/ath/ath_hal/ah_eeprom_v14.h
    index 90e2c7479bb..d2caa8087bf 100644
    --- a/sys/dev/ath/ath_hal/ah_eeprom_v14.h
    +++ b/sys/dev/ath/ath_hal/ah_eeprom_v14.h
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ah_eeprom_v14.h,v 1.3 2008/11/10 04:08:00 sam Exp $
    + * $FreeBSD$
      */
     #ifndef _AH_EEPROM_V14_H_
     #define _AH_EEPROM_V14_H_
    @@ -76,6 +76,7 @@
     #define AR5416_EEPMISC_BIG_ENDIAN    	0x01
     #define FREQ2FBIN(x,y) 			((y) ? ((x) - 2300) : (((x) - 4800) / 5))
     #define AR5416_MAX_CHAINS            	3
    +#define	AR5416_PWR_TABLE_OFFSET_DB	-5
     #define AR5416_ANT_16S               	25
     
     #define AR5416_NUM_ANT_CHAIN_FIELDS     7
    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..fd0c69979a4
    --- /dev/null
    +++ b/sys/dev/ath/ath_hal/ah_eeprom_v4k.h
    @@ -0,0 +1,155 @@
    +/*
    + * 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_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_PD_GAIN_ICEPTS];
    +	uint8_t		vpdPdg[AR5416_4K_NUM_PD_GAINS][AR5416_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_ */
    diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212.h b/sys/dev/ath/ath_hal/ar5212/ar5212.h
    index 4f60c3bcb18..6590eb4a202 100644
    --- a/sys/dev/ath/ath_hal/ar5212/ar5212.h
    +++ b/sys/dev/ath/ath_hal/ar5212/ar5212.h
    @@ -327,6 +327,9 @@ struct ath_hal_5212 {
     	uint16_t	*ah_pcdacTable;
     	u_int		ah_pcdacTableSize;
     	uint16_t	ah_ratesArray[16];
    +
    +	uint8_t		ah_txTrigLev;		/* current Tx trigger level */
    +	uint8_t		ah_maxTxTrigLev;	/* max tx trigger level */
     };
     #define	AH5212(_ah)	((struct ath_hal_5212 *)(_ah))
     
    diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
    index ace6989747e..78571227f6b 100644
    --- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
    +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
    @@ -248,6 +248,9 @@ ar5212InitState(struct ath_hal_5212 *ahp, uint16_t devid, HAL_SOFTC sc,
     	ahp->ah_acktimeout = (u_int) -1;
     	ahp->ah_ctstimeout = (u_int) -1;
     	ahp->ah_sifstime = (u_int) -1;
    +	ahp->ah_txTrigLev = INIT_TX_FIFO_THRESHOLD,
    +	ahp->ah_maxTxTrigLev = MAX_TX_FIFO_THRESHOLD,
    +
     	OS_MEMCPY(&ahp->ah_bssidmask, defbssidmask, IEEE80211_ADDR_LEN);
     #undef N
     }
    diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_power.c b/sys/dev/ath/ath_hal/ar5212/ar5212_power.c
    index aca52adf797..3f755bdcfe9 100644
    --- a/sys/dev/ath/ath_hal/ar5212/ar5212_power.c
    +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_power.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5212_power.c,v 1.4 2008/11/10 04:08:03 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    @@ -38,8 +38,8 @@ static HAL_BOOL
     ar5212SetPowerModeAwake(struct ath_hal *ah, int setChip)
     {
     #define	AR_SCR_MASK \
    -    (AR_SCR_SLDUR|AR_SCR_SLE|AR_SCR_SLE|AR_SCR_SLDTP|AR_SCR_SLDWP|\
    -     AR_SCR_SLEPOL|AR_SCR_MIBIE)
    +    (AR_SCR_SLDUR|AR_SCR_SLE|AR_SCR_SLDTP|AR_SCR_SLDWP|\
    +     AR_SCR_SLEPOL|AR_SCR_MIBIE|AR_SCR_UNKNOWN)
     #define	POWER_UP_TIME	2000
     	uint32_t scr, val;
     	int i;
    diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
    index ecdf34ebe46..ed9de14d00a 100644
    --- a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
    +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
    @@ -48,16 +48,19 @@ ar5212UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
     	uint32_t txcfg, curLevel, newLevel;
     	HAL_INT omask;
     
    +	if (ahp->ah_txTrigLev >= ahp->ah_maxTxTrigLev)
    +		return AH_FALSE;
    +
     	/*
     	 * Disable interrupts while futzing with the fifo level.
     	 */
    -	omask = ar5212SetInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL);
    +	omask = ah->ah_setInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL);
     
     	txcfg = OS_REG_READ(ah, AR_TXCFG);
     	curLevel = MS(txcfg, AR_FTRIG);
     	newLevel = curLevel;
     	if (bIncTrigLevel) {		/* increase the trigger level */
    -		if (curLevel < MAX_TX_FIFO_THRESHOLD)
    +		if (curLevel < ahp->ah_maxTxTrigLev)
     			newLevel++;
     	} else if (curLevel > MIN_TX_FIFO_THRESHOLD)
     		newLevel--;
    @@ -66,8 +69,10 @@ ar5212UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
     		OS_REG_WRITE(ah, AR_TXCFG,
     			(txcfg &~ AR_FTRIG) | SM(newLevel, AR_FTRIG));
     
    +	ahp->ah_txTrigLev = newLevel;
    +
     	/* re-enable chip interrupts */
    -	ar5212SetInterrupts(ah, omask);
    +	ah->ah_setInterrupts(ah, omask);
     
     	return (newLevel != curLevel);
     }
    diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212reg.h b/sys/dev/ath/ath_hal/ar5212/ar5212reg.h
    index ef6d600fd35..f99b203e95f 100644
    --- a/sys/dev/ath/ath_hal/ar5212/ar5212reg.h
    +++ b/sys/dev/ath/ath_hal/ar5212/ar5212reg.h
    @@ -700,6 +700,7 @@
     #define	AR_SCR_SLDWP		0x00080000 /* sleep duration write policy */
     #define	AR_SCR_SLEPOL		0x00100000 /* sleep policy mode */
     #define	AR_SCR_MIBIE		0x00200000 /* sleep perf cntrs MIB intr ena */
    +#define	AR_SCR_UNKNOWN		0x00400000
     
     #define	AR_INTPEND_TRUE		0x00000001 /* interrupt pending */
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h
    index a02f7322f8d..8d1484b60aa 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416.h
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416.h
    @@ -21,6 +21,7 @@
     
     #include "ar5212/ar5212.h"
     #include "ar5416_cal.h"
    +#include "ah_eeprom_v14.h"	/* for CAL_TARGET_POWER_* */
     
     #define	AR5416_MAGIC	0x20065416
     
    @@ -44,6 +45,7 @@ typedef struct {
     #define	AR5416_CCA_MAX_GOOD_VALUE	-85
     #define	AR5416_CCA_MAX_HIGH_VALUE	-62
     #define	AR5416_CCA_MIN_BAD_VALUE	-140
    +#define	AR9285_CCA_MAX_GOOD_VALUE	-118
     
     #define AR5416_SPUR_RSSI_THRESH		40
     
    @@ -178,12 +180,27 @@ extern	HAL_RFGAIN ar5416GetRfgain(struct ath_hal *ah);
     extern	HAL_BOOL ar5416Disable(struct ath_hal *ah);
     extern	HAL_BOOL ar5416ChipReset(struct ath_hal *ah,
     		const struct ieee80211_channel *);
    +extern	HAL_BOOL ar5416SetBoardValues(struct ath_hal *,
    +		const struct ieee80211_channel *);
     extern	HAL_BOOL ar5416SetResetReg(struct ath_hal *, uint32_t type);
     extern	HAL_BOOL ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit);
    +extern	HAL_BOOL ar5416SetTransmitPower(struct ath_hal *,
    +    		const struct ieee80211_channel *, uint16_t *);
     extern	HAL_BOOL ar5416GetChipPowerLimits(struct ath_hal *ah,
     		struct ieee80211_channel *chan);
     extern	void ar5416GetChannelCenters(struct ath_hal *,
     		const struct ieee80211_channel *chan, CHAN_CENTERS *centers);
    +extern	void ar5416GetTargetPowers(struct ath_hal *ah, 
    +		const struct ieee80211_channel *chan,
    +		CAL_TARGET_POWER_HT *powInfo,
    +		uint16_t numChannels, CAL_TARGET_POWER_HT *pNewPower,
    +		uint16_t numRates, HAL_BOOL isHt40Target);
    +extern	void ar5416GetTargetPowersLeg(struct ath_hal *ah, 
    +		const struct ieee80211_channel *chan,
    +		CAL_TARGET_POWER_LEG *powInfo,
    +		uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower,
    +		uint16_t numRates, HAL_BOOL isExtTarget);
    +
     
     extern	HAL_BOOL ar5416StopTxDma(struct ath_hal *ah, u_int q);
     extern	HAL_BOOL ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
    index 6134a207ced..b10296c4e68 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
    @@ -183,7 +183,7 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
     
     		if (level >= params->maxNoiseImmunityLevel) {
     			HALDEBUG(ah, HAL_DEBUG_ANY,
    -			    "%s: level out of range (%u > %u)\n",
    +			    "%s: immunity level out of range (%u > %u)\n",
     			    __func__, level, params->maxNoiseImmunityLevel);
     			return AH_FALSE;
     		}
    @@ -267,7 +267,7 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
     
     		if (level >= params->maxFirstepLevel) {
     			HALDEBUG(ah, HAL_DEBUG_ANY,
    -			    "%s: level out of range (%u > %u)\n",
    +			    "%s: firstep level out of range (%u > %u)\n",
     			    __func__, level, params->maxFirstepLevel);
     			return AH_FALSE;
     		}
    @@ -285,7 +285,7 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
     
     		if (level >= params->maxSpurImmunityLevel) {
     			HALDEBUG(ah, HAL_DEBUG_ANY,
    -			    "%s: level out of range (%u > %u)\n",
    +			    "%s: spur immunity level out of range (%u > %u)\n",
     			    __func__, level, params->maxSpurImmunityLevel);
     			return AH_FALSE;
     		}
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
    index e59a09962be..a0bf7bdd627 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
    @@ -89,6 +89,8 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
     	ah->ah_perCalibrationN		= ar5416PerCalibrationN,
     	ah->ah_resetCalValid		= ar5416ResetCalValid,
     	ah->ah_setTxPowerLimit		= ar5416SetTxPowerLimit;
    +	ah->ah_setTxPower		= ar5416SetTransmitPower;
    +	ah->ah_setBoardValues		= ar5416SetBoardValues;
     
     	/* Transmit functions */
     	ah->ah_stopTxDma		= ar5416StopTxDma;
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c b/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c
    index 1d68c684241..358a0eed245 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_beacon.c,v 1.8 2008/11/11 01:03:12 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c
    index 2e580bdd37e..9083d3ab656 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_cal_adcdc.c,v 1.2 2008/11/11 17:43:23 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal_adcgain.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal_adcgain.c
    index ce38b03fd24..4af1ca4d670 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal_adcgain.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal_adcgain.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_cal_adcgain.c,v 1.2 2008/11/11 17:43:23 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal_iq.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal_iq.c
    index 931249e3075..82555b274c6 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal_iq.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal_iq.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_cal_iq.c,v 1.2 2008/11/11 17:43:23 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_eeprom.c b/sys/dev/ath/ath_hal/ar5416/ar5416_eeprom.c
    index 812159f0e44..2947726d8eb 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_eeprom.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_eeprom.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_eeprom.c,v 1.6 2008/11/10 04:08:04 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c b/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c
    index 9defa1c6e5f..dc56d15114e 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c
    @@ -146,7 +146,9 @@ ar5416GpioGet(struct ath_hal *ah, uint32_t gpio)
     	 * Read output value for all gpio's, shift it,
     	 * and verify whether the specific bit is set.
     	 */
    -	if (AR_SREV_MERLIN_10_OR_LATER(ah))
    +	if (AR_SREV_KITE_10_OR_LATER(ah))
    +		bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR9285_GPIO_IN_VAL);
    +	else if (AR_SREV_MERLIN_10_OR_LATER(ah))
     		bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR928X_GPIO_IN_VAL);
     	else
     		bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL);
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_keycache.c b/sys/dev/ath/ath_hal/ar5416/ar5416_keycache.c
    index cb8ad71db48..533fe03e22f 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_keycache.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_keycache.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_keycache.c,v 1.3 2008/11/10 04:08:04 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c
    index 0ed704fd4ad..ac6009bac8b 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_misc.c,v 1.12 2008/11/27 22:30:07 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    @@ -30,7 +30,7 @@
     #include "ar5416/ar5416phy.h"
     
     /*
    - * Return the wireless modes (a,b,g,t) supported by hardware.
    + * Return the wireless modes (a,b,g,n,t) supported by hardware.
      *
      * This value is what is actually supported by the hardware
      * and is unaffected by regulatory/country code settings.
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_phy.c b/sys/dev/ath/ath_hal/ar5416/ar5416_phy.c
    index f8f5b2a80c2..0f99399f308 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_phy.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_phy.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_phy.c,v 1.4 2008/11/27 22:30:08 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_power.c b/sys/dev/ath/ath_hal/ar5416/ar5416_power.c
    index b83b0f8951d..c3b1285f375 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_power.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_power.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_power.c,v 1.6 2008/11/11 00:11:30 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c b/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
    index e8883737eaa..4a480aa91e4 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416_recv.c,v 1.7 2008/11/11 20:46:06 sam Exp $
    + * $FreeBSD$
      */
     #include "opt_ah.h"
     
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
    index 1b75715f1df..d506a6aaf0a 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
    @@ -45,9 +45,6 @@ static void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode);
     static void ar5416InitQoS(struct ath_hal *ah);
     static void ar5416InitUserSettings(struct ath_hal *ah);
     
    -static HAL_BOOL ar5416SetTransmitPower(struct ath_hal *ah, 
    -	const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
    -
     #if 0
     static HAL_BOOL	ar5416ChannelChange(struct ath_hal *, const struct ieee80211_channel *);
     #endif
    @@ -56,7 +53,6 @@ static void ar5416SetDeltaSlope(struct ath_hal *, const struct ieee80211_channel
     static HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah);
     static HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type);
     static void ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan);
    -static HAL_BOOL ar5416SetBoardValues(struct ath_hal *, const struct ieee80211_channel *);
     static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah,
     	struct ar5416eeprom *pEepData, 
     	const struct ieee80211_channel *chan, int16_t *ratesArray,
    @@ -69,14 +65,6 @@ static HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah,
     	int16_t *pTxPowerIndexOffset);
     static uint16_t ar5416GetMaxEdgePower(uint16_t freq,
     	CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz);
    -static void ar5416GetTargetPowers(struct ath_hal *ah, 
    -	const struct ieee80211_channel *chan, CAL_TARGET_POWER_HT *powInfo,
    -	uint16_t numChannels, CAL_TARGET_POWER_HT *pNewPower,
    -	uint16_t numRates, HAL_BOOL isHt40Target);
    -static void ar5416GetTargetPowersLeg(struct ath_hal *ah, 
    -	const struct ieee80211_channel *chan, CAL_TARGET_POWER_LEG *powInfo,
    -	uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower,
    -	uint16_t numRates, HAL_BOOL isExtTarget);
     
     static int16_t interpolate(uint16_t target, uint16_t srcLeft,
     	uint16_t srcRight, int16_t targetLeft, int16_t targetRight);
    @@ -224,7 +212,7 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
     	OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask);
     
     	/* Setup the transmit power values. */
    -	if (!ar5416SetTransmitPower(ah, chan, rfXpdGain)) {
    +	if (!ah->ah_setTxPower(ah, chan, rfXpdGain)) {
     		HALDEBUG(ah, HAL_DEBUG_ANY,
     		    "%s: error init'ing transmit power\n", __func__);
     		FAIL(HAL_EIO);
    @@ -245,7 +233,7 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
     	AH5416(ah)->ah_spurMitigate(ah, chan);
     
     	/* Setup board specific options for EEPROM version 3 */
    -	if (!ar5416SetBoardValues(ah, chan)) {
    +	if (!ah->ah_setBoardValues(ah, chan)) {
     		HALDEBUG(ah, HAL_DEBUG_ANY,
     		    "%s: error setting board options\n", __func__);
     		FAIL(HAL_EIO);
    @@ -448,6 +436,7 @@ ar5416ChannelChange(struct ath_hal *ah, const structu ieee80211_channel *chan)
     static void
     ar5416InitDMA(struct ath_hal *ah)
     {
    +	struct ath_hal_5212 *ahp = AH5212(ah);
     
     	/*
     	 * set AHB_MODE not to do cacheline prefetches
    @@ -466,7 +455,10 @@ ar5416InitDMA(struct ath_hal *ah)
     	OS_REG_WRITE(ah, AR_RXCFG, 
     		(OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B);
     
    -	/* XXX restore TX trigger level */
    +	/* restore TX trigger level */
    +	OS_REG_WRITE(ah, AR_TXCFG,
    +		(OS_REG_READ(ah, AR_TXCFG) &~ AR_FTRIG) |
    +		    SM(ahp->ah_txTrigLev, AR_FTRIG));
     
     	/*
     	 * Setup receive FIFO threshold to hold off TX activities
    @@ -793,7 +785,7 @@ typedef enum Ar5416_Rates {
      * Set the transmit power in the baseband for the given
      * operating channel and mode.
      */
    -static HAL_BOOL
    +HAL_BOOL
     ar5416SetTransmitPower(struct ath_hal *ah,
     	const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
     {
    @@ -1185,7 +1177,7 @@ ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
      * Read EEPROM header info and program the device for correct operation
      * given the channel value.
      */
    -static HAL_BOOL
    +HAL_BOOL
     ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
     {
         const HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom;
    @@ -1622,7 +1614,7 @@ ar5416GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2G
      * Return the rates of target power for the given target power table
      * channel, and number of channels
      */
    -static void
    +void
     ar5416GetTargetPowers(struct ath_hal *ah,  const struct ieee80211_channel *chan,
                           CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels,
                           CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates,
    @@ -1681,7 +1673,7 @@ ar5416GetTargetPowers(struct ath_hal *ah,  const struct ieee80211_channel *chan,
      * Return the four rates of target power for the given target power table
      * channel, and number of channels
      */
    -static void
    +void
     ar5416GetTargetPowersLeg(struct ath_hal *ah, 
                              const struct ieee80211_channel *chan,
                              CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels,
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
    index 7c60b24c89c..e52ded63551 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416desc.h,v 1.7 2008/11/11 00:11:30 sam Exp $
    + * $FreeBSD$
      */
     #ifndef _ATH_AR5416_DESC_H_
     #define _ATH_AR5416_DESC_H
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
    index 416aae68d23..d5185b6ffdc 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
    @@ -14,7 +14,7 @@
      * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      *
    - * $Id: ar5416phy.h,v 1.10 2008/11/11 20:46:06 sam Exp $
    + * $FreeBSD$
      */
     #ifndef _DEV_ATH_AR5416PHY_H_
     #define _DEV_ATH_AR5416PHY_H_
    @@ -48,6 +48,7 @@
     #define AR_PHY_FC_SHORT_GI_40       0x00000080      /* allow short GI for HT 40 */
     #define AR_PHY_FC_WALSH             0x00000100      /* walsh spatial spreading for 2 chains,2 streams TX */
     #define AR_PHY_FC_SINGLE_HT_LTF1    0x00000200      /* single length (4us) 1st HT long training symbol */
    +#define	AR_PHY_FC_ENABLE_DAC_FIFO   0x00000800
     
     #define AR_PHY_TIMING2      0x9810      /* Timing Control 2 */
     #define AR_PHY_TIMING2_USE_FORCE    0x00001000
    @@ -78,6 +79,20 @@
     #define AR_PHY_GAIN_2GHZ_BSW_ATTEN	0x0000001F
     #define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S	0
     
    +#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN	    0x003E0000
    +#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S   17
    +#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN     0x0001F000
    +#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S   12
    +#define AR_PHY_GAIN_2GHZ_XATTEN2_DB         0x00000FC0
    +#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S       6
    +#define AR_PHY_GAIN_2GHZ_XATTEN1_DB         0x0000003F
    +#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S       0
    +
    +#define AR9280_PHY_RXGAIN_TXRX_ATTEN	0x00003F80
    +#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S	7
    +#define AR9280_PHY_RXGAIN_TXRX_MARGIN	0x001FC000
    +#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S	14
    +
     #define AR_PHY_EXT_CCA          0x99bc
     #define AR_PHY_EXT_CCA_CYCPWR_THR1      0x0000FE00
     #define AR_PHY_EXT_CCA_CYCPWR_THR1_S    9
    @@ -207,6 +222,9 @@
     #define	AR_PHY_TPCRG1_PD_GAIN_3		0x00300000
     #define	AR_PHY_TPCRG1_PD_GAIN_3_S	20
     
    +#define	AR_PHY_TPCRG1_PD_CAL_ENABLE	0x00400000
    +#define	AR_PHY_TPCRG1_PD_CAL_ENABLE_S	22
    +
     #define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
     #define AR_PHY_MASK2_M_31_45     0xa3a4
     #define AR_PHY_MASK2_M_16_30     0xa3a8
    @@ -247,4 +265,5 @@
     
     #define	AR_PHY_CL_CAL_CTL	0xA358		/* carrier leak cal control */
     #define	AR_PHY_CL_CAL_ENABLE	0x00000002
    +#define	AR_PHY_PARALLEL_CAL_ENABLE	0x00000001
     #endif /* _DEV_ATH_AR5416PHY_H_ */
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
    index 3afb16325fd..cab34ccd7f5 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
    +++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
    @@ -70,8 +70,20 @@
     #define	AR_AN_RF5G1_CH1         0x783C
     #define	AR_AN_TOP2		0x7894
     #define	AR_AN_SYNTH9            0x7868
    -#define	AR9285_AN_RF2G3         0x7828
    +#define	AR9285_AN_RF2G1		0x7820
    +#define	AR9285_AN_RF2G2		0x7824
    +#define	AR9285_AN_RF2G3		0x7828
    +#define	AR9285_AN_RF2G4		0x782C
    +#define	AR9285_AN_RF2G6		0x7834
    +#define	AR9285_AN_RF2G7		0x7838
    +#define	AR9285_AN_RF2G8		0x783C
    +#define	AR9285_AN_RF2G9		0x7840
    +#define	AR9285_AN_RXTXBB1	0x7854
    +#define	AR9285_AN_TOP2		0x7868
     #define	AR9285_AN_TOP3		0x786c
    +#define	AR9285_AN_TOP4		0x7870
    +#define	AR9285_AN_TOP4_DEFAULT	0x10142c00
    +
     #define	AR_RESET_TSF		0x8020
     #define	AR_RXFIFO_CFG		0x8114
     #define	AR_PHY_ERR_1		0x812c
    @@ -359,42 +371,83 @@
     #define	AR_AN_SYNTH9_REFDIVA_S  27
     
     /* AR9285 Analog registers */
    -#define	AR9285_AN_RF2G3_OB_0    0x00E00000
    -#define	AR9285_AN_RF2G3_OB_0_S    21
    -#define	AR9285_AN_RF2G3_OB_1    0x001C0000
    -#define	AR9285_AN_RF2G3_OB_1_S    18
    -#define	AR9285_AN_RF2G3_OB_2    0x00038000
    -#define	AR9285_AN_RF2G3_OB_2_S    15
    -#define	AR9285_AN_RF2G3_OB_3    0x00007000
    -#define	AR9285_AN_RF2G3_OB_3_S    12
    -#define	AR9285_AN_RF2G3_OB_4    0x00000E00
    -#define	AR9285_AN_RF2G3_OB_4_S    9
    +#define	AR9285_AN_RF2G1_ENPACAL      0x00000800
    +#define	AR9285_AN_RF2G1_ENPACAL_S    11
    +#define	AR9285_AN_RF2G1_PDPADRV1     0x02000000
    +#define	AR9285_AN_RF2G1_PDPADRV1_S   25
    +#define	AR9285_AN_RF2G1_PDPADRV2     0x01000000
    +#define	AR9285_AN_RF2G1_PDPADRV2_S   24
    +#define	AR9285_AN_RF2G1_PDPAOUT      0x00800000
    +#define	AR9285_AN_RF2G1_PDPAOUT_S    23
     
    -#define	AR9285_AN_RF2G3_DB1_0    0x000001C0
    -#define	AR9285_AN_RF2G3_DB1_0_S    6
    -#define	AR9285_AN_RF2G3_DB1_1    0x00000038
    -#define	AR9285_AN_RF2G3_DB1_1_S    3
    -#define	AR9285_AN_RF2G3_DB1_2    0x00000007
    -#define	AR9285_AN_RF2G3_DB1_2_S    0
    -#define	AR9285_AN_RF2G4         0x782C
    -#define	AR9285_AN_RF2G4_DB1_3    0xE0000000
    -#define	AR9285_AN_RF2G4_DB1_3_S    29
    -#define	AR9285_AN_RF2G4_DB1_4    0x1C000000
    -#define	AR9285_AN_RF2G4_DB1_4_S    26
    +#define	AR9285_AN_RF2G2_OFFCAL       0x00001000
    +#define	AR9285_AN_RF2G2_OFFCAL_S     12
     
    -#define	AR9285_AN_RF2G4_DB2_0    0x03800000
    -#define	AR9285_AN_RF2G4_DB2_0_S    23
    -#define	AR9285_AN_RF2G4_DB2_1    0x00700000
    -#define	AR9285_AN_RF2G4_DB2_1_S    20
    -#define	AR9285_AN_RF2G4_DB2_2    0x000E0000
    -#define	AR9285_AN_RF2G4_DB2_2_S    17
    -#define	AR9285_AN_RF2G4_DB2_3    0x0001C000
    -#define	AR9285_AN_RF2G4_DB2_3_S    14
    -#define	AR9285_AN_RF2G4_DB2_4    0x00003800
    -#define	AR9285_AN_RF2G4_DB2_4_S    11
    +#define	AR9285_AN_RF2G3_PDVCCOMP	0x02000000
    +#define	AR9285_AN_RF2G3_PDVCCOMP_S	25
    +#define	AR9285_AN_RF2G3_OB_0	0x00E00000
    +#define	AR9285_AN_RF2G3_OB_0_S	21
    +#define	AR9285_AN_RF2G3_OB_1	0x001C0000
    +#define	AR9285_AN_RF2G3_OB_1_S	18
    +#define	AR9285_AN_RF2G3_OB_2	0x00038000
    +#define	AR9285_AN_RF2G3_OB_2_S	15
    +#define	AR9285_AN_RF2G3_OB_3	0x00007000
    +#define	AR9285_AN_RF2G3_OB_3_S	12
    +#define	AR9285_AN_RF2G3_OB_4	0x00000E00
    +#define	AR9285_AN_RF2G3_OB_4_S	9
    +
    +#define	AR9285_AN_RF2G3_DB1_0	0x000001C0
    +#define	AR9285_AN_RF2G3_DB1_0_S	6
    +#define	AR9285_AN_RF2G3_DB1_1	0x00000038
    +#define	AR9285_AN_RF2G3_DB1_1_S	3
    +#define	AR9285_AN_RF2G3_DB1_2	0x00000007
    +#define	AR9285_AN_RF2G3_DB1_2_S	0
    +
    +#define	AR9285_AN_RF2G4_DB1_3	0xE0000000
    +#define	AR9285_AN_RF2G4_DB1_3_S	29
    +#define	AR9285_AN_RF2G4_DB1_4	0x1C000000
    +#define	AR9285_AN_RF2G4_DB1_4_S	26
    +
    +#define	AR9285_AN_RF2G4_DB2_0	0x03800000
    +#define	AR9285_AN_RF2G4_DB2_0_S	23
    +#define	AR9285_AN_RF2G4_DB2_1	0x00700000
    +#define	AR9285_AN_RF2G4_DB2_1_S	20
    +#define	AR9285_AN_RF2G4_DB2_2	0x000E0000
    +#define	AR9285_AN_RF2G4_DB2_2_S	17
    +#define	AR9285_AN_RF2G4_DB2_3	0x0001C000
    +#define	AR9285_AN_RF2G4_DB2_3_S	14
    +#define	AR9285_AN_RF2G4_DB2_4	0x00003800
    +#define	AR9285_AN_RF2G4_DB2_4_S	11
    +
    +#define	AR9285_AN_RF2G6_CCOMP	0x00007800
    +#define	AR9285_AN_RF2G6_CCOMP_S	11
    +#define	AR9285_AN_RF2G6_OFFS	0x03f00000
    +#define	AR9285_AN_RF2G6_OFFS_S	20
    +
    +#define	AR9271_AN_RF2G6_OFFS	0x07f00000
    +#define	AR9271_AN_RF2G6_OFFS_S	20
    +
    +#define	AR9285_AN_RF2G7_PWDDB	0x00000002
    +#define	AR9285_AN_RF2G7_PWDDB_S	1
    +#define	AR9285_AN_RF2G7_PADRVGN2TAB0	0xE0000000
    +#define	AR9285_AN_RF2G7_PADRVGN2TAB0_S	29
    +
    +#define	AR9285_AN_RF2G8_PADRVGN2TAB0	0x0001C000
    +#define	AR9285_AN_RF2G8_PADRVGN2TAB0_S	14
    +
    +#define	AR9285_AN_RXTXBB1_PDRXTXBB1    0x00000020
    +#define	AR9285_AN_RXTXBB1_PDRXTXBB1_S  5
    +#define	AR9285_AN_RXTXBB1_PDV2I        0x00000080
    +#define	AR9285_AN_RXTXBB1_PDV2I_S      7
    +#define	AR9285_AN_RXTXBB1_PDDACIF      0x00000100
    +#define	AR9285_AN_RXTXBB1_PDDACIF_S    8
    +#define	AR9285_AN_RXTXBB1_SPARE9       0x00000001
    +#define	AR9285_AN_RXTXBB1_SPARE9_S     0
     
     #define	AR9285_AN_TOP3_XPABIAS_LVL      0x0000000C
     #define	AR9285_AN_TOP3_XPABIAS_LVL_S    2
    +#define	AR9285_AN_TOP3_PWDDAC		0x00800000
    +#define	AR9285_AN_TOP3_PWDDAC_S		23
     
     /* Sleep control */
     #define	AR5416_SLEEP1_CAB_TIMEOUT	0xFFE00000	/* Cab timeout (TU) */
    @@ -472,6 +525,7 @@
     
     #define	AR_PCU_TXBUF_CTRL_SIZE_MASK	0x7FF
     #define	AR_PCU_TXBUF_CTRL_USABLE_SIZE	0x700
    +#define	AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
     
     /* Eeprom defines */
     #define	AR_EEPROM_STATUS_DATA_VAL           0x0000ffff
    @@ -522,6 +576,8 @@
     #define	AR_XSREV_REVISION_MERLIN_21	2	/* Merlin 2.1 */
     #define	AR_XSREV_VERSION_KITE		0xC0	/* Kite Version */
     #define	AR_XSREV_REVISION_KITE_10	0	/* Kite 1.0 */
    +#define	AR_XSREV_REVISION_KITE_11	1	/* Kite 1.1 */
    +#define	AR_XSREV_REVISION_KITE_12	2	/* Kite 1.2 */
     
     #define	AR_SREV_OWL_20_OR_LATER(_ah) \
     	(AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_SOWL || \
    @@ -544,7 +600,7 @@
     	(AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_MERLIN)
     #define	AR_SREV_MERLIN_20(_ah) \
     	(AR_SREV_MERLIN(_ah) && \
    -	 AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_MERLIN_20)
    +	 AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_MERLIN_20)
     #define	AR_SREV_MERLIN_20_OR_LATER(_ah) \
     	(AR_SREV_MERLIN_20(_ah) || \
     	 AH_PRIVATE((_ah))->ah_macVersion > AR_XSREV_VERSION_MERLIN)
    @@ -553,4 +609,16 @@
     	(AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_KITE)
     #define	AR_SREV_KITE_10_OR_LATER(_ah) \
     	(AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_KITE)
    +#define	AR_SREV_KITE_11(_ah) \
    +	(AR_SREV_KITE(ah) && \
    +	 AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KITE_11)
    +#define	AR_SREV_KITE_11_OR_LATER(_ah) \
    +	(AR_SREV_KITE_11(_ah) || \
    +	 AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KITE_11)
    +#define	AR_SREV_KITE_12(_ah) \
    +	(AR_SREV_KITE(ah) && \
    +	 AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KITE_12)
    +#define	AR_SREV_KITE_12_OR_LATER(_ah) \
    +	(AR_SREV_KITE_12(_ah) || \
    +	 AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KITE_12)
     #endif /* _DEV_ATH_AR5416REG_H */
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar9280.h b/sys/dev/ath/ath_hal/ar5416/ar9280.h
    index f2e97d9680c..59039f0157e 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar9280.h
    +++ b/sys/dev/ath/ath_hal/ar5416/ar9280.h
    @@ -30,11 +30,16 @@ struct ath_hal_9280 {
     #define	AH9280(_ah)	((struct ath_hal_9280 *)(_ah))
     
     #define	AR9280_DEFAULT_RXCHAINMASK	3
    +#define	AR9285_DEFAULT_RXCHAINMASK	1
     #define	AR9280_DEFAULT_TXCHAINMASK	1
    +#define	AR9285_DEFAULT_TXCHAINMASK	1
     
     HAL_BOOL ar9280RfAttach(struct ath_hal *, HAL_STATUS *);
     
     struct ath_hal;
     
     HAL_BOOL	ar9280SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
    +void		ar9280SpurMitigate(struct ath_hal *,
    +    			const struct ieee80211_channel *);
    +
     #endif	/* _ATH_AR9280_H_ */
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar9280_attach.c b/sys/dev/ath/ath_hal/ar5416/ar9280_attach.c
    index d998af05943..8436482b11c 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar9280_attach.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar9280_attach.c
    @@ -64,8 +64,6 @@ static void ar9280ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
     static HAL_BOOL ar9280FillCapabilityInfo(struct ath_hal *ah);
     static void ar9280WriteIni(struct ath_hal *ah,
     	const struct ieee80211_channel *chan);
    -static void ar9280SpurMitigate(struct ath_hal *ah,
    -	const struct ieee80211_channel *chan);
     
     static void
     ar9280AniSetup(struct ath_hal *ah)
    @@ -360,7 +358,7 @@ ar9280WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
     #define	AR_SPUR_FEEQ_BOUND_HT40	19
     #define	AR_SPUR_FEEQ_BOUND_HT20	10
     
    -static void
    +void
     ar9280SpurMitigate(struct ath_hal *ah, const struct ieee80211_channel *chan)
     {
         static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar9285.c b/sys/dev/ath/ath_hal/ar5416/ar9285.c
    new file mode 100644
    index 00000000000..800c92fa1b6
    --- /dev/null
    +++ b/sys/dev/ath/ath_hal/ar5416/ar9285.c
    @@ -0,0 +1,64 @@
    +/*
    + * Copyright (c) 2008-2009 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 "ar5416/ar9280.h"
    +#include "ar5416/ar9285.h"
    +#include "ar5416/ar5416reg.h"
    +#include "ar5416/ar5416phy.h"
    +
    +static void
    +ar9285GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
    +{
    +	int16_t nf;
    +
    +	nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
    +	if (nf & 0x100)
    +		nf = 0 - ((nf ^ 0x1ff) + 1);
    +	HALDEBUG(ah, HAL_DEBUG_NFCAL,
    +	    "NF calibrated [ctl] [chain 0] is %d\n", nf);
    +	nfarray[0] = nf;
    +
    +	nfarray[1] = 0;
    +
    +	nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
    +	if (nf & 0x100)
    +		nf = 0 - ((nf ^ 0x1ff) + 1);
    +	HALDEBUG(ah, HAL_DEBUG_NFCAL,
    +	    "NF calibrated [ext] [chain 0] is %d\n", nf);
    +	nfarray[3] = nf;
    +
    +	nfarray[4] = 0;
    +}
    +
    +HAL_BOOL
    +ar9285RfAttach(struct ath_hal *ah, HAL_STATUS *status)
    +{
    +	if (ar9280RfAttach(ah, status) == AH_FALSE)
    +		return AH_FALSE;
    +
    +	AH_PRIVATE(ah)->ah_getNoiseFloor = ar9285GetNoiseFloor;
    +
    +	return AH_TRUE;
    +}
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar9285.h b/sys/dev/ath/ath_hal/ar5416/ar9285.h
    new file mode 100644
    index 00000000000..1ee058bf312
    --- /dev/null
    +++ b/sys/dev/ath/ath_hal/ar5416/ar9285.h
    @@ -0,0 +1,43 @@
    +/*
    + * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting
    + *
    + * 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 _ATH_AR9285_H_
    +#define _ATH_AR9285_H_
    +
    +#include "ar5416/ar5416.h"
    +
    +struct ath_hal_9285 {
    +	struct ath_hal_5416 ah_5416;
    +
    +	HAL_INI_ARRAY	ah_ini_txgain;
    +	HAL_INI_ARRAY	ah_ini_rxgain;
    +};
    +#define	AH9285(_ah)	((struct ath_hal_9285 *)(_ah))
    +
    +#define	AR9285_DEFAULT_RXCHAINMASK	1
    +#define	AR9285_DEFAULT_TXCHAINMASK	1
    +
    +
    +HAL_BOOL ar9285SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
    +HAL_BOOL ar9285RfAttach(struct ath_hal *, HAL_STATUS *);
    +
    +extern	HAL_BOOL ar9285SetTransmitPower(struct ath_hal *,
    +		const struct ieee80211_channel *, uint16_t *);
    +extern HAL_BOOL ar9285SetBoardValues(struct ath_hal *,
    +		const struct ieee80211_channel *);
    +
    +#endif	/* _ATH_AR9285_H_ */
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar9285.ini b/sys/dev/ath/ath_hal/ar5416/ar9285.ini
    new file mode 100644
    index 00000000000..ef0ff2de89e
    --- /dev/null
    +++ b/sys/dev/ath/ath_hal/ar5416/ar9285.ini
    @@ -0,0 +1,699 @@
    +/*
    + * Copyright (c) 2008-2009 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$
    + */
    +
    +/* AR9285 Revsion 10 */
    +static const u_int32_t ar9285Modes[][6] = {
    +    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
    +    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
    +    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
    +    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
    +    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
    +    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
    +    { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
    +    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
    +    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
    +    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
    +    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
    +    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
    +    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
    +    { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
    +    { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 },
    +    { 0x00009848, 0x00001066, 0x00001066, 0x0000004e, 0x0000004e, 0x00001059 },
    +    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
    +    { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
    +    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e },
    +    { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
    +    { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
    +    { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
    +    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
    +    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
    +    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
    +    { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
    +    { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1020, 0xdfbc1020, 0xdfbc1010 },
    +    { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x000099b8, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c },
    +    { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
    +    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
    +    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
    +    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
    +    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
    +    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
    +    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
    +    { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
    +    { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
    +    { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
    +    { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
    +    { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
    +    { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
    +    { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
    +    { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 },
    +    { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
    +    { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
    +    { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
    +    { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
    +    { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
    +    { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
    +    { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
    +    { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
    +    { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
    +    { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 },
    +    { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 },
    +    { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 },
    +    { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
    +    { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
    +    { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 },
    +    { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
    +    { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
    +    { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 },
    +    { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 },
    +    { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
    +    { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
    +    { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
    +    { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
    +    { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
    +    { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
    +    { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 },
    +    { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
    +    { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
    +    { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 },
    +    { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 },
    +    { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 },
    +    { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 },
    +    { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 },
    +    { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 },
    +    { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 },
    +    { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
    +    { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
    +    { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 },
    +    { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 },
    +    { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 },
    +    { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 },
    +    { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
    +    { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
    +    { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 },
    +    { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 },
    +    { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 },
    +    { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 },
    +    { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
    +    { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
    +    { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 },
    +    { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 },
    +    { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 },
    +    { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 },
    +    { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 },
    +    { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 },
    +    { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
    +    { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
    +    { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 },
    +    { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
    +    { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
    +    { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
    +    { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 },
    +    { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
    +    { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
    +    { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 },
    +    { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 },
    +    { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
    +    { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
    +    { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 },
    +    { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
    +    { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
    +    { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
    +    { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
    +    { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
    +    { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
    +    { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
    +    { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 },
    +    { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
    +    { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 },
    +    { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 },
    +    { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
    +    { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
    +    { 0x0000aa04, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 },
    +    { 0x0000aa08, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
    +    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
    +    { 0x0000aa10, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
    +    { 0x0000aa14, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
    +    { 0x0000aa18, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
    +    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
    +    { 0x0000aa20, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
    +    { 0x0000aa24, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
    +    { 0x0000aa28, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
    +    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
    +    { 0x0000aa30, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
    +    { 0x0000aa34, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
    +    { 0x0000aa38, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
    +    { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
    +    { 0x0000aa40, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
    +    { 0x0000aa44, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
    +    { 0x0000aa48, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
    +    { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
    +    { 0x0000aa50, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 },
    +    { 0x0000aa54, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 },
    +    { 0x0000aa58, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 },
    +    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
    +    { 0x0000aa60, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
    +    { 0x0000aa64, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
    +    { 0x0000aa68, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
    +    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 },
    +    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 },
    +    { 0x0000aa74, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 },
    +    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 },
    +    { 0x0000aa7c, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 },
    +    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 },
    +    { 0x0000aa84, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 },
    +    { 0x0000aa88, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 },
    +    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 },
    +    { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 },
    +    { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 },
    +    { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 },
    +    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 },
    +    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 },
    +    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 },
    +    { 0x0000aaa8, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 },
    +    { 0x0000aaac, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 },
    +    { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 },
    +    { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
    +    { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
    +    { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
    +    { 0x0000aac0, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 },
    +    { 0x0000aac4, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
    +    { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
    +    { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 },
    +    { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 },
    +    { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 },
    +    { 0x0000aad8, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 },
    +    { 0x0000aadc, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
    +    { 0x0000aae0, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
    +    { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 },
    +    { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 },
    +    { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 },
    +    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 },
    +    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 },
    +    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 },
    +    { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 },
    +    { 0x0000ab00, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 },
    +    { 0x0000ab04, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
    +    { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
    +    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
    +    { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
    +    { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
    +    { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 },
    +    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 },
    +    { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
    +    { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
    +    { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
    +    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
    +    { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 },
    +    { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
    +    { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 },
    +    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
    +    { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
    +    { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 },
    +    { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
    +    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
    +    { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
    +    { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
    +    { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
    +    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
    +    { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
    +    { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
    +    { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
    +    { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 },
    +    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
    +    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
    +    { 0x0000a250, 0x001ff000, 0x001ff000, 0x001ca000, 0x001ca000, 0x001da000 },
    +    { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 },
    +    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
    +    { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 },
    +    { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 },
    +    { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 },
    +    { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 },
    +    { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 },
    +    { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 },
    +    { 0x0000a320, 0x00000000, 0x00000000, 0x0002c89a, 0x0002c89a, 0x00000000 },
    +    { 0x0000a324, 0x00000000, 0x00000000, 0x0002e89b, 0x0002e89b, 0x00000000 },
    +    { 0x0000a328, 0x00000000, 0x00000000, 0x0003089c, 0x0003089c, 0x00000000 },
    +    { 0x0000a32c, 0x00000000, 0x00000000, 0x0003289d, 0x0003289d, 0x00000000 },
    +    { 0x0000a330, 0x00000000, 0x00000000, 0x0003489e, 0x0003489e, 0x00000000 },
    +    { 0x0000a334, 0x00000000, 0x00000000, 0x000388de, 0x000388de, 0x00000000 },
    +    { 0x0000a338, 0x00000000, 0x00000000, 0x0003b91e, 0x0003b91e, 0x00000000 },
    +    { 0x0000a33c, 0x00000000, 0x00000000, 0x0003d95e, 0x0003d95e, 0x00000000 },
    +    { 0x0000a340, 0x00000000, 0x00000000, 0x000419df, 0x000419df, 0x00000000 },
    +    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
    +};
    +
    +static const u_int32_t ar9285Common[][2] = {
    +    { 0x0000000c, 0x00000000 },
    +    { 0x00000030, 0x00020045 },
    +    { 0x00000034, 0x00000005 },
    +    { 0x00000040, 0x00000000 },
    +    { 0x00000044, 0x00000008 },
    +    { 0x00000048, 0x00000008 },
    +    { 0x0000004c, 0x00000010 },
    +    { 0x00000050, 0x00000000 },
    +    { 0x00000054, 0x0000001f },
    +    { 0x00000800, 0x00000000 },
    +    { 0x00000804, 0x00000000 },
    +    { 0x00000808, 0x00000000 },
    +    { 0x0000080c, 0x00000000 },
    +    { 0x00000810, 0x00000000 },
    +    { 0x00000814, 0x00000000 },
    +    { 0x00000818, 0x00000000 },
    +    { 0x0000081c, 0x00000000 },
    +    { 0x00000820, 0x00000000 },
    +    { 0x00000824, 0x00000000 },
    +    { 0x00001040, 0x002ffc0f },
    +    { 0x00001044, 0x002ffc0f },
    +    { 0x00001048, 0x002ffc0f },
    +    { 0x0000104c, 0x002ffc0f },
    +    { 0x00001050, 0x002ffc0f },
    +    { 0x00001054, 0x002ffc0f },
    +    { 0x00001058, 0x002ffc0f },
    +    { 0x0000105c, 0x002ffc0f },
    +    { 0x00001060, 0x002ffc0f },
    +    { 0x00001064, 0x002ffc0f },
    +    { 0x00001230, 0x00000000 },
    +    { 0x00001270, 0x00000000 },
    +    { 0x00001038, 0x00000000 },
    +    { 0x00001078, 0x00000000 },
    +    { 0x000010b8, 0x00000000 },
    +    { 0x000010f8, 0x00000000 },
    +    { 0x00001138, 0x00000000 },
    +    { 0x00001178, 0x00000000 },
    +    { 0x000011b8, 0x00000000 },
    +    { 0x000011f8, 0x00000000 },
    +    { 0x00001238, 0x00000000 },
    +    { 0x00001278, 0x00000000 },
    +    { 0x000012b8, 0x00000000 },
    +    { 0x000012f8, 0x00000000 },
    +    { 0x00001338, 0x00000000 },
    +    { 0x00001378, 0x00000000 },
    +    { 0x000013b8, 0x00000000 },
    +    { 0x000013f8, 0x00000000 },
    +    { 0x00001438, 0x00000000 },
    +    { 0x00001478, 0x00000000 },
    +    { 0x000014b8, 0x00000000 },
    +    { 0x000014f8, 0x00000000 },
    +    { 0x00001538, 0x00000000 },
    +    { 0x00001578, 0x00000000 },
    +    { 0x000015b8, 0x00000000 },
    +    { 0x000015f8, 0x00000000 },
    +    { 0x00001638, 0x00000000 },
    +    { 0x00001678, 0x00000000 },
    +    { 0x000016b8, 0x00000000 },
    +    { 0x000016f8, 0x00000000 },
    +    { 0x00001738, 0x00000000 },
    +    { 0x00001778, 0x00000000 },
    +    { 0x000017b8, 0x00000000 },
    +    { 0x000017f8, 0x00000000 },
    +    { 0x0000103c, 0x00000000 },
    +    { 0x0000107c, 0x00000000 },
    +    { 0x000010bc, 0x00000000 },
    +    { 0x000010fc, 0x00000000 },
    +    { 0x0000113c, 0x00000000 },
    +    { 0x0000117c, 0x00000000 },
    +    { 0x000011bc, 0x00000000 },
    +    { 0x000011fc, 0x00000000 },
    +    { 0x0000123c, 0x00000000 },
    +    { 0x0000127c, 0x00000000 },
    +    { 0x000012bc, 0x00000000 },
    +    { 0x000012fc, 0x00000000 },
    +    { 0x0000133c, 0x00000000 },
    +    { 0x0000137c, 0x00000000 },
    +    { 0x000013bc, 0x00000000 },
    +    { 0x000013fc, 0x00000000 },
    +    { 0x0000143c, 0x00000000 },
    +    { 0x0000147c, 0x00000000 },
    +    { 0x00004030, 0x00000002 },
    +    { 0x0000403c, 0x00000002 },
    +    { 0x00004024, 0x0000001f },
    +    { 0x00004060, 0x00000000 },
    +    { 0x00004064, 0x00000000 },
    +    { 0x00007010, 0x00000031 },
    +    { 0x00007034, 0x00000002 },
    +    { 0x00007038, 0x000004c2 },
    +    { 0x00008004, 0x00000000 },
    +    { 0x00008008, 0x00000000 },
    +    { 0x0000800c, 0x00000000 },
    +    { 0x00008018, 0x00000700 },
    +    { 0x00008020, 0x00000000 },
    +    { 0x00008038, 0x00000000 },
    +    { 0x0000803c, 0x00000000 },
    +    { 0x00008048, 0x00000000 },
    +    { 0x00008054, 0x00000000 },
    +    { 0x00008058, 0x00000000 },
    +    { 0x0000805c, 0x000fc78f },
    +    { 0x00008060, 0x0000000f },
    +    { 0x00008064, 0x00000000 },
    +    { 0x00008070, 0x00000000 },
    +    { 0x000080c0, 0x2a80001a },
    +    { 0x000080c4, 0x05dc01e0 },
    +    { 0x000080c8, 0x1f402710 },
    +    { 0x000080cc, 0x01f40000 },
    +    { 0x000080d0, 0x00001e00 },
    +    { 0x000080d4, 0x00000000 },
    +    { 0x000080d8, 0x00400000 },
    +    { 0x000080e0, 0xffffffff },
    +    { 0x000080e4, 0x0000ffff },
    +    { 0x000080e8, 0x003f3f3f },
    +    { 0x000080ec, 0x00000000 },
    +    { 0x000080f0, 0x00000000 },
    +    { 0x000080f4, 0x00000000 },
    +    { 0x000080f8, 0x00000000 },
    +    { 0x000080fc, 0x00020000 },
    +    { 0x00008100, 0x00020000 },
    +    { 0x00008104, 0x00000001 },
    +    { 0x00008108, 0x00000052 },
    +    { 0x0000810c, 0x00000000 },
    +    { 0x00008110, 0x00000168 },
    +    { 0x00008118, 0x000100aa },
    +    { 0x0000811c, 0x00003210 },
    +    { 0x00008120, 0x08f04800 },
    +    { 0x00008124, 0x00000000 },
    +    { 0x00008128, 0x00000000 },
    +    { 0x0000812c, 0x00000000 },
    +    { 0x00008130, 0x00000000 },
    +    { 0x00008134, 0x00000000 },
    +    { 0x00008138, 0x00000000 },
    +    { 0x0000813c, 0x00000000 },
    +    { 0x00008144, 0x00000000 },
    +    { 0x00008168, 0x00000000 },
    +    { 0x0000816c, 0x00000000 },
    +    { 0x00008170, 0x32143320 },
    +    { 0x00008174, 0xfaa4fa50 },
    +    { 0x00008178, 0x00000100 },
    +    { 0x0000817c, 0x00000000 },
    +    { 0x000081c0, 0x00000000 },
    +    { 0x000081d0, 0x00003210 },
    +    { 0x000081ec, 0x00000000 },
    +    { 0x000081f0, 0x00000000 },
    +    { 0x000081f4, 0x00000000 },
    +    { 0x000081f8, 0x00000000 },
    +    { 0x000081fc, 0x00000000 },
    +    { 0x00008200, 0x00000000 },
    +    { 0x00008204, 0x00000000 },
    +    { 0x00008208, 0x00000000 },
    +    { 0x0000820c, 0x00000000 },
    +    { 0x00008210, 0x00000000 },
    +    { 0x00008214, 0x00000000 },
    +    { 0x00008218, 0x00000000 },
    +    { 0x0000821c, 0x00000000 },
    +    { 0x00008220, 0x00000000 },
    +    { 0x00008224, 0x00000000 },
    +    { 0x00008228, 0x00000000 },
    +    { 0x0000822c, 0x00000000 },
    +    { 0x00008230, 0x00000000 },
    +    { 0x00008234, 0x00000000 },
    +    { 0x00008238, 0x00000000 },
    +    { 0x0000823c, 0x00000000 },
    +    { 0x00008240, 0x00100000 },
    +    { 0x00008244, 0x0010f400 },
    +    { 0x00008248, 0x00000100 },
    +    { 0x0000824c, 0x0001e800 },
    +    { 0x00008250, 0x00000000 },
    +    { 0x00008254, 0x00000000 },
    +    { 0x00008258, 0x00000000 },
    +    { 0x0000825c, 0x400000ff },
    +    { 0x00008260, 0x00080922 },
    +    { 0x00008264, 0xa8a00010 },
    +    { 0x00008270, 0x00000000 },
    +    { 0x00008274, 0x40000000 },
    +    { 0x00008278, 0x003e4180 },
    +    { 0x0000827c, 0x00000000 },
    +    { 0x00008284, 0x0000002c },
    +    { 0x00008288, 0x0000002c },
    +    { 0x0000828c, 0x00000000 },
    +    { 0x00008294, 0x00000000 },
    +    { 0x00008298, 0x00000000 },
    +    { 0x0000829c, 0x00000000 },
    +    { 0x00008300, 0x00000040 },
    +    { 0x00008314, 0x00000000 },
    +    { 0x00008328, 0x00000000 },
    +    { 0x0000832c, 0x00000001 },
    +    { 0x00008330, 0x00000302 },
    +    { 0x00008334, 0x00000e00 },
    +    { 0x00008338, 0x00000000 },
    +    { 0x0000833c, 0x00000000 },
    +    { 0x00008340, 0x00010380 },
    +    { 0x00008344, 0x00481043 },
    +    { 0x00009808, 0x00000000 },
    +    { 0x0000980c, 0xafe68e30 },
    +    { 0x00009810, 0xfd14e000 },
    +    { 0x00009814, 0x9c0a9f6b },
    +    { 0x0000981c, 0x00000000 },
    +    { 0x0000982c, 0x0000a000 },
    +    { 0x00009830, 0x00000000 },
    +    { 0x0000983c, 0x00200400 },
    +    { 0x0000984c, 0x0040233c },
    +    { 0x00009854, 0x00000044 },
    +    { 0x00009900, 0x00000000 },
    +    { 0x00009904, 0x00000000 },
    +    { 0x00009908, 0x00000000 },
    +    { 0x0000990c, 0x00000000 },
    +    { 0x00009910, 0x01002310 },
    +    { 0x0000991c, 0x10000fff },
    +    { 0x00009920, 0x04900000 },
    +    { 0x00009928, 0x00000001 },
    +    { 0x0000992c, 0x00000004 },
    +    { 0x00009934, 0x1e1f2022 },
    +    { 0x00009938, 0x0a0b0c0d },
    +    { 0x0000993c, 0x00000000 },
    +    { 0x00009940, 0x14750604 },
    +    { 0x00009948, 0x9280c00a },
    +    { 0x0000994c, 0x00020028 },
    +    { 0x00009954, 0x5f3ca3de },
    +    { 0x00009958, 0x2108ecff },
    +    { 0x00009968, 0x000003ce },
    +    { 0x00009970, 0x1927b515 },
    +    { 0x00009974, 0x00000000 },
    +    { 0x00009978, 0x00000001 },
    +    { 0x0000997c, 0x00000000 },
    +    { 0x00009980, 0x00000000 },
    +    { 0x00009984, 0x00000000 },
    +    { 0x00009988, 0x00000000 },
    +    { 0x0000998c, 0x00000000 },
    +    { 0x00009990, 0x00000000 },
    +    { 0x00009994, 0x00000000 },
    +    { 0x00009998, 0x00000000 },
    +    { 0x0000999c, 0x00000000 },
    +    { 0x000099a0, 0x00000000 },
    +    { 0x000099a4, 0x00000001 },
    +    { 0x000099a8, 0x201fff00 },
    +    { 0x000099ac, 0x2def0a00 },
    +    { 0x000099b0, 0x03051000 },
    +    { 0x000099b4, 0x00000820 },
    +    { 0x000099dc, 0x00000000 },
    +    { 0x000099e0, 0x00000000 },
    +    { 0x000099e4, 0xaaaaaaaa },
    +    { 0x000099e8, 0x3c466478 },
    +    { 0x000099ec, 0x0cc80caa },
    +    { 0x000099f0, 0x00000000 },
    +    { 0x0000a208, 0x803e6788 },
    +    { 0x0000a210, 0x4080a333 },
    +    { 0x0000a214, 0x00206c10 },
    +    { 0x0000a218, 0x009c4060 },
    +    { 0x0000a220, 0x01834061 },
    +    { 0x0000a224, 0x00000400 },
    +    { 0x0000a228, 0x000003b5 },
    +    { 0x0000a22c, 0x00000000 },
    +    { 0x0000a234, 0x20202020 },
    +    { 0x0000a238, 0x20202020 },
    +    { 0x0000a244, 0x00000000 },
    +    { 0x0000a248, 0xfffffffc },
    +    { 0x0000a24c, 0x00000000 },
    +    { 0x0000a254, 0x00000000 },
    +    { 0x0000a258, 0x0ccb5380 },
    +    { 0x0000a25c, 0x15151501 },
    +    { 0x0000a260, 0xdfa90f01 },
    +    { 0x0000a268, 0x00000000 },
    +    { 0x0000a26c, 0x0ebae9e6 },
    +    { 0x0000d270, 0x0d820820 },
    +    { 0x0000a278, 0x39ce739c },
    +    { 0x0000a27c, 0x050e039c },
    +    { 0x0000d35c, 0x07ffffef },
    +    { 0x0000d360, 0x0fffffe7 },
    +    { 0x0000d364, 0x17ffffe5 },
    +    { 0x0000d368, 0x1fffffe4 },
    +    { 0x0000d36c, 0x37ffffe3 },
    +    { 0x0000d370, 0x3fffffe3 },
    +    { 0x0000d374, 0x57ffffe3 },
    +    { 0x0000d378, 0x5fffffe2 },
    +    { 0x0000d37c, 0x7fffffe2 },
    +    { 0x0000d380, 0x7f3c7bba },
    +    { 0x0000d384, 0xf3307ff0 },
    +    { 0x0000a388, 0x0c000000 },
    +    { 0x0000a38c, 0x20202020 },
    +    { 0x0000a390, 0x20202020 },
    +    { 0x0000a394, 0x39ce739c },
    +    { 0x0000a398, 0x0000039c },
    +    { 0x0000a39c, 0x00000001 },
    +    { 0x0000a3a0, 0x00000000 },
    +    { 0x0000a3a4, 0x00000000 },
    +    { 0x0000a3a8, 0x00000000 },
    +    { 0x0000a3ac, 0x00000000 },
    +    { 0x0000a3b0, 0x00000000 },
    +    { 0x0000a3b4, 0x00000000 },
    +    { 0x0000a3b8, 0x00000000 },
    +    { 0x0000a3bc, 0x00000000 },
    +    { 0x0000a3c0, 0x00000000 },
    +    { 0x0000a3c4, 0x00000000 },
    +    { 0x0000a3cc, 0x20202020 },
    +    { 0x0000a3d0, 0x20202020 },
    +    { 0x0000a3d4, 0x20202020 },
    +    { 0x0000a3dc, 0x39ce739c },
    +    { 0x0000a3e0, 0x0000039c },
    +    { 0x0000a3e4, 0x00000000 },
    +    { 0x0000a3e8, 0x18c43433 },
    +    { 0x0000a3ec, 0x00f70081 },
    +    { 0x00007800, 0x00140000 },
    +    { 0x00007804, 0x0e4548d8 },
    +    { 0x00007808, 0x54214514 },
    +    { 0x0000780c, 0x02025820 },
    +    { 0x00007810, 0x71c0d388 },
    +    { 0x00007814, 0x924934a8 },
    +    { 0x0000781c, 0x00000000 },
    +    { 0x00007820, 0x00000c04 },
    +    { 0x00007824, 0x00d86fff },
    +    { 0x00007828, 0x26d2491b },
    +    { 0x0000782c, 0x6e36d97b },
    +    { 0x00007830, 0xedb6d96c },
    +    { 0x00007834, 0x71400086 },
    +    { 0x00007838, 0xfac68800 },
    +    { 0x0000783c, 0x0001fffe },
    +    { 0x00007840, 0xffeb1a20 },
    +    { 0x00007844, 0x000c0db6 },
    +    { 0x00007848, 0x6db61b6f },
    +    { 0x0000784c, 0x6d9b66db },
    +    { 0x00007850, 0x6d8c6dba },
    +    { 0x00007854, 0x00040000 },
    +    { 0x00007858, 0xdb003012 },
    +    { 0x0000785c, 0x04924914 },
    +    { 0x00007860, 0x21084210 },
    +    { 0x00007864, 0xf7d7ffde },
    +    { 0x00007868, 0xc2034080 },
    +    { 0x0000786c, 0x48609eb4 },
    +    { 0x00007870, 0x10142c00 },
    +};
    +
    +static const u_int32_t ar9285PciePhy_clkreq_always_on_L1[][2] = {
    +    {0x00004040,  0x9248fd00 },
    +    {0x00004040,  0x24924924 },
    +    {0x00004040,  0xa8000019 },
    +    {0x00004040,  0x13160820 },
    +    {0x00004040,  0xe5980560 },
    +    {0x00004040,  0xc01dcffd },
    +    {0x00004040,  0x1aaabe41 },
    +    {0x00004040,  0xbe105554 },
    +    {0x00004040,  0x00043007 },
    +    {0x00004044,  0x00000000 },
    +};
    +
    +static const u_int32_t ar9285PciePhy_clkreq_off_L1[][2] = {
    +    {0x00004040,  0x9248fd00 },
    +    {0x00004040,  0x24924924 },
    +    {0x00004040,  0xa8000019 },
    +    {0x00004040,  0x13160820 },
    +    {0x00004040,  0xe5980560 },
    +    {0x00004040,  0xc01dcffc },
    +    {0x00004040,  0x1aaabe41 },
    +    {0x00004040,  0xbe105554 },
    +    {0x00004040,  0x00043007 },
    +    {0x00004044,  0x00000000 },
    +};
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c b/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c
    new file mode 100644
    index 00000000000..946133a396f
    --- /dev/null
    +++ b/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c
    @@ -0,0 +1,397 @@
    +/*
    + * Copyright (c) 2008-2009 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_devid.h"
    +
    +#include "ah_eeprom_v4k.h"		/* XXX for tx/rx gain */
    +
    +#include "ar5416/ar9280.h"
    +#include "ar5416/ar9285.h"
    +#include "ar5416/ar5416reg.h"
    +#include "ar5416/ar5416phy.h"
    +
    +#include "ar5416/ar9285.ini"
    +#include "ar5416/ar9285v2.ini"
    +#include "ar5416/ar9280v2.ini"		/* XXX ini for tx/rx gain */
    +
    +static const HAL_PERCAL_DATA ar9280_iq_cal = {		/* single sample */
    +	.calName = "IQ", .calType = IQ_MISMATCH_CAL,
    +	.calNumSamples	= MIN_CAL_SAMPLES,
    +	.calCountMax	= PER_MAX_LOG_COUNT,
    +	.calCollect	= ar5416IQCalCollect,
    +	.calPostProc	= ar5416IQCalibration
    +};
    +static const HAL_PERCAL_DATA ar9280_adc_gain_cal = {	/* single sample */
    +	.calName = "ADC Gain", .calType = ADC_GAIN_CAL,
    +	.calNumSamples	= MIN_CAL_SAMPLES,
    +	.calCountMax	= PER_MIN_LOG_COUNT,
    +	.calCollect	= ar5416AdcGainCalCollect,
    +	.calPostProc	= ar5416AdcGainCalibration
    +};
    +static const HAL_PERCAL_DATA ar9280_adc_dc_cal = {	/* single sample */
    +	.calName = "ADC DC", .calType = ADC_DC_CAL,
    +	.calNumSamples	= MIN_CAL_SAMPLES,
    +	.calCountMax	= PER_MIN_LOG_COUNT,
    +	.calCollect	= ar5416AdcDcCalCollect,
    +	.calPostProc	= ar5416AdcDcCalibration
    +};
    +static const HAL_PERCAL_DATA ar9280_adc_init_dc_cal = {
    +	.calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
    +	.calNumSamples	= MIN_CAL_SAMPLES,
    +	.calCountMax	= INIT_LOG_COUNT,
    +	.calCollect	= ar5416AdcDcCalCollect,
    +	.calPostProc	= ar5416AdcDcCalibration
    +};
    +
    +static void ar9285ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
    +static HAL_BOOL ar9285FillCapabilityInfo(struct ath_hal *ah);
    +static void ar9285WriteIni(struct ath_hal *ah,
    +	const struct ieee80211_channel *chan);
    +
    +static void
    +ar9285AniSetup(struct ath_hal *ah)
    +{
    +	/* NB: disable ANI for reliable RIFS rx */
    +	ar5212AniAttach(ah, AH_NULL, AH_NULL, AH_FALSE);
    +}
    +
    +/*
    + * Attach for an AR9285 part.
    + */
    +static struct ath_hal *
    +ar9285Attach(uint16_t devid, HAL_SOFTC sc,
    +	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status)
    +{
    +	struct ath_hal_9285 *ahp9285;
    +	struct ath_hal_5212 *ahp;
    +	struct ath_hal *ah;
    +	uint32_t val;
    +	HAL_STATUS ecode;
    +	HAL_BOOL rfStatus;
    +
    +	HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
    +	    __func__, sc, (void*) st, (void*) sh);
    +
    +	/* NB: memory is returned zero'd */
    +	ahp9285 = ath_hal_malloc(sizeof (struct ath_hal_9285));
    +	if (ahp9285 == AH_NULL) {
    +		HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
    +		    "%s: cannot allocate memory for state block\n", __func__);
    +		*status = HAL_ENOMEM;
    +		return AH_NULL;
    +	}
    +	ahp = AH5212(ahp9285);
    +	ah = &ahp->ah_priv.h;
    +
    +	ar5416InitState(AH5416(ah), devid, sc, st, sh, status);
    +
    +	/* XXX override with 9285 specific state */
    +	/* override 5416 methods for our needs */
    +	ah->ah_setAntennaSwitch		= ar9285SetAntennaSwitch;
    +	ah->ah_configPCIE		= ar9285ConfigPCIE;
    +	ah->ah_setTxPower		= ar9285SetTransmitPower;
    +	ah->ah_setBoardValues		= ar9285SetBoardValues;
    +
    +	AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal;
    +	AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal;
    +	AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9280_adc_dc_cal;
    +	AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9280_adc_init_dc_cal;
    +	AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
    +
    +	AH5416(ah)->ah_spurMitigate	= ar9280SpurMitigate;
    +	AH5416(ah)->ah_writeIni		= ar9285WriteIni;
    +	AH5416(ah)->ah_rx_chainmask	= AR9285_DEFAULT_RXCHAINMASK;
    +	AH5416(ah)->ah_tx_chainmask	= AR9285_DEFAULT_TXCHAINMASK;
    +	
    +	ahp->ah_maxTxTrigLev		= MAX_TX_FIFO_THRESHOLD >> 1;
    +
    +	if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
    +		/* reset chip */
    +		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
    +		    __func__);
    +		ecode = HAL_EIO;
    +		goto bad;
    +	}
    +
    +	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
    +		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
    +		    __func__);
    +		ecode = HAL_EIO;
    +		goto bad;
    +	}
    +	/* Read Revisions from Chips before taking out of reset */
    +	val = OS_REG_READ(ah, AR_SREV);
    +	HALDEBUG(ah, HAL_DEBUG_ATTACH,
    +	    "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
    +	    __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
    +	    MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
    +	/* NB: include chip type to differentiate from pre-Sowl versions */
    +	AH_PRIVATE(ah)->ah_macVersion =
    +	    (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S;
    +	AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
    +	AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0;
    +
    +	/* setup common ini data; rf backends handle remainder */
    +	if (AR_SREV_KITE_12_OR_LATER(ah)) {
    +		HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes_v2, 6);
    +		HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common_v2, 2);
    +		HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
    +		    ar9285PciePhy_clkreq_always_on_L1_v2, 2);
    +	} else {
    +		HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes, 6);
    +		HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common, 2);
    +		HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
    +		    ar9285PciePhy_clkreq_always_on_L1, 2);
    +	}
    +	ar5416AttachPCIE(ah);
    +
    +	ecode = ath_hal_v4kEepromAttach(ah);
    +	if (ecode != HAL_OK)
    +		goto bad;
    +
    +	if (!ar5416ChipReset(ah, AH_NULL)) {	/* reset chip */
    +		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
    +		    __func__);
    +		ecode = HAL_EIO;
    +		goto bad;
    +	}
    +
    +	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
    +
    +	if (!ar5212ChipTest(ah)) {
    +		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
    +		    __func__);
    +		ecode = HAL_ESELFTEST;
    +		goto bad;
    +	}
    +
    +	/*
    +	 * Set correct Baseband to analog shift
    +	 * setting to access analog chips.
    +	 */
    +	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
    +
    +	/* Read Radio Chip Rev Extract */
    +	AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
    +	switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
    +        case AR_RAD2133_SREV_MAJOR:	/* Sowl: 2G/3x3 */
    +	case AR_RAD5133_SREV_MAJOR:	/* Sowl: 2+5G/3x3 */
    +		break;
    +	default:
    +		if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
    +			AH_PRIVATE(ah)->ah_analog5GhzRev =
    +				AR_RAD5133_SREV_MAJOR;
    +			break;
    +		}
    +#ifdef AH_DEBUG
    +		HALDEBUG(ah, HAL_DEBUG_ANY,
    +		    "%s: 5G Radio Chip Rev 0x%02X is not supported by "
    +		    "this driver\n", __func__,
    +		    AH_PRIVATE(ah)->ah_analog5GhzRev);
    +		ecode = HAL_ENOTSUPP;
    +		goto bad;
    +#endif
    +	}
    +	rfStatus = ar9285RfAttach(ah, &ecode);
    +	if (!rfStatus) {
    +		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
    +		    __func__, ecode);
    +		goto bad;
    +	}
    +
    +	HAL_INI_INIT(&ahp9285->ah_ini_rxgain, ar9280Modes_original_rxgain_v2,
    +	    6);
    +	/* setup txgain table */
    +	switch (ath_hal_eepromGet(ah, AR_EEP_TXGAIN_TYPE, AH_NULL)) {
    +	case AR5416_EEP_TXGAIN_HIGH_POWER:
    +		HAL_INI_INIT(&ahp9285->ah_ini_txgain,
    +		    ar9285Modes_high_power_tx_gain_v2, 6);
    +		break;
    +	case AR5416_EEP_TXGAIN_ORIG:
    +		HAL_INI_INIT(&ahp9285->ah_ini_txgain,
    +		    ar9285Modes_original_tx_gain_v2, 6);
    +		break;
    +	default:
    +		HALASSERT(AH_FALSE);
    +		goto bad;		/* XXX ? try to continue */
    +	}
    +
    +	/*
    +	 * Got everything we need now to setup the capabilities.
    +	 */
    +	if (!ar9285FillCapabilityInfo(ah)) {
    +		ecode = HAL_EEREAD;
    +		goto bad;
    +	}
    +
    +	ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
    +	if (ecode != HAL_OK) {
    +		HALDEBUG(ah, HAL_DEBUG_ANY,
    +		    "%s: error getting mac address from EEPROM\n", __func__);
    +		goto bad;
    +        }
    +	/* XXX How about the serial number ? */
    +	/* Read Reg Domain */
    +	AH_PRIVATE(ah)->ah_currentRD =
    +	    ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
    +
    +	/*
    +	 * ah_miscMode is populated by ar5416FillCapabilityInfo()
    +	 * starting from griffin. Set here to make sure that
    +	 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
    +	 * placed into hardware.
    +	 */
    +	if (ahp->ah_miscMode != 0)
    +		OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
    +
    +	ar9285AniSetup(ah);			/* Anti Noise Immunity */
    +	ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
    +
    +	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
    +
    +	return ah;
    +bad:
    +	if (ah != AH_NULL)
    +		ah->ah_detach(ah);
    +	if (status)
    +		*status = ecode;
    +	return AH_NULL;
    +}
    +
    +static void
    +ar9285ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore)
    +{
    +	if (AH_PRIVATE(ah)->ah_ispcie && !restore) {
    +		ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0);
    +		OS_DELAY(1000);
    +		OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
    +		OS_REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
    +	}
    +}
    +
    +static void
    +ar9285WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
    +{
    +	u_int modesIndex, freqIndex;
    +	int regWrites = 0;
    +
    +	/* Setup the indices for the next set of register array writes */
    +	/* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
    +	freqIndex = 2;
    +	if (IEEE80211_IS_CHAN_HT40(chan))
    +		modesIndex = 3;
    +	else if (IEEE80211_IS_CHAN_108G(chan))
    +		modesIndex = 5;
    +	else
    +		modesIndex = 4;
    +
    +	/* Set correct Baseband to analog shift setting to access analog chips. */
    +	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
    +	OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
    +	regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes,
    +	    modesIndex, regWrites);
    +	if (AR_SREV_KITE_12_OR_LATER(ah)) {
    +		regWrites = ath_hal_ini_write(ah, &AH9285(ah)->ah_ini_txgain,
    +		    modesIndex, regWrites);
    +	}
    +	regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common,
    +	    1, regWrites);
    +
    +}
    +
    +/*
    + * Fill all software cached or static hardware state information.
    + * Return failure if capabilities are to come from EEPROM and
    + * cannot be read.
    + */
    +static HAL_BOOL
    +ar9285FillCapabilityInfo(struct ath_hal *ah)
    +{
    +	HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
    +
    +	if (!ar5416FillCapabilityInfo(ah))
    +		return AH_FALSE;
    +	pCap->halNumGpioPins = 12;
    +	pCap->halWowSupport = AH_TRUE;
    +	pCap->halWowMatchPatternExact = AH_TRUE;
    +#if 0
    +	pCap->halWowMatchPatternDword = AH_TRUE;
    +#endif
    +	pCap->halCSTSupport = AH_TRUE;
    +	pCap->halRifsRxSupport = AH_TRUE;
    +	pCap->halRifsTxSupport = AH_TRUE;
    +	pCap->halRtsAggrLimit = 64*1024;	/* 802.11n max */
    +	pCap->halExtChanDfsSupport = AH_TRUE;
    +#if 0
    +	/* XXX bluetooth */
    +	pCap->halBtCoexSupport = AH_TRUE;
    +#endif
    +	pCap->halAutoSleepSupport = AH_FALSE;	/* XXX? */
    +#if 0
    +	pCap->hal4kbSplitTransSupport = AH_FALSE;
    +#endif
    +	pCap->halRxStbcSupport = 1;
    +	pCap->halTxStbcSupport = 1;
    +
    +	return AH_TRUE;
    +}
    +
    +HAL_BOOL
    +ar9285SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
    +{
    +#define ANTENNA0_CHAINMASK    0x1
    +#define ANTENNA1_CHAINMASK    0x2
    +	struct ath_hal_5416 *ahp = AH5416(ah);
    +
    +	/* Antenna selection is done by setting the tx/rx chainmasks approp. */
    +	switch (settings) {
    +	case HAL_ANT_FIXED_A:
    +		/* Enable first antenna only */
    +		ahp->ah_tx_chainmask = ANTENNA0_CHAINMASK;
    +		ahp->ah_rx_chainmask = ANTENNA0_CHAINMASK;
    +		break;
    +	case HAL_ANT_FIXED_B:
    +		/* Enable second antenna only, after checking capability */
    +		if (AH_PRIVATE(ah)->ah_caps.halTxChainMask > ANTENNA1_CHAINMASK)
    +			ahp->ah_tx_chainmask = ANTENNA1_CHAINMASK;
    +		ahp->ah_rx_chainmask = ANTENNA1_CHAINMASK;
    +		break;
    +	case HAL_ANT_VARIABLE:
    +		/* Restore original chainmask settings */
    +		/* XXX */
    +		ahp->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK;
    +		ahp->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK;
    +		break;
    +	}
    +	return AH_TRUE;
    +#undef ANTENNA0_CHAINMASK
    +#undef ANTENNA1_CHAINMASK
    +}
    +
    +static const char*
    +ar9285Probe(uint16_t vendorid, uint16_t devid)
    +{
    +	if (vendorid == ATHEROS_VENDOR_ID && devid == AR9285_DEVID_PCIE)
    +		return "Atheros 9285";
    +	return AH_NULL;
    +}
    +AH_CHIP(AR9285, ar9285Probe, ar9285Attach);
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar9285_reset.c b/sys/dev/ath/ath_hal/ar5416/ar9285_reset.c
    new file mode 100644
    index 00000000000..8c2de10c3c5
    --- /dev/null
    +++ b/sys/dev/ath/ath_hal/ar5416/ar9285_reset.c
    @@ -0,0 +1,951 @@
    +/*
    + * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
    + * Copyright (c) 2002-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$
    + */
    +
    +/*
    + * This is almost the same as ar5416_reset.c but uses the v4k EEPROM and
    + * supports only 2Ghz operation.
    + */
    +
    +#include "opt_ah.h"
    +
    +#include "ah.h"
    +#include "ah_internal.h"
    +#include "ah_devid.h"
    +
    +#include "ah_eeprom_v14.h"
    +#include "ah_eeprom_v4k.h"
    +
    +#include "ar5416/ar9285.h"
    +#include "ar5416/ar5416.h"
    +#include "ar5416/ar5416reg.h"
    +#include "ar5416/ar5416phy.h"
    +
    +/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */ 
    +#define	EEP_MINOR(_ah) \
    +	(AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK)
    +#define IS_EEP_MINOR_V2(_ah)	(EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2)
    +#define IS_EEP_MINOR_V3(_ah)	(EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3)
    +
    +/* Additional Time delay to wait after activiting the Base band */
    +#define BASE_ACTIVATE_DELAY	100	/* 100 usec */
    +#define PLL_SETTLE_DELAY	300	/* 300 usec */
    +#define RTC_PLL_SETTLE_DELAY    1000    /* 1 ms     */
    +
    +static HAL_BOOL ar9285SetPowerPerRateTable(struct ath_hal *ah,
    +	struct ar5416eeprom_4k *pEepData, 
    +	const struct ieee80211_channel *chan, int16_t *ratesArray,
    +	uint16_t cfgCtl, uint16_t AntennaReduction,
    +	uint16_t twiceMaxRegulatoryPower, 
    +	uint16_t powerLimit);
    +static HAL_BOOL ar9285SetPowerCalTable(struct ath_hal *ah,
    +	struct ar5416eeprom_4k *pEepData,
    +	const struct ieee80211_channel *chan,
    +	int16_t *pTxPowerIndexOffset);
    +static int16_t interpolate(uint16_t target, uint16_t srcLeft,
    +	uint16_t srcRight, int16_t targetLeft, int16_t targetRight);
    +static HAL_BOOL ar9285FillVpdTable(uint8_t, uint8_t, uint8_t *, uint8_t *,
    +		                   uint16_t, uint8_t *);
    +static void ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah, 
    +	const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ_4K *pRawDataSet,
    +	uint8_t * bChans, uint16_t availPiers,
    +	uint16_t tPdGainOverlap, int16_t *pMinCalPower,
    +	uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues,
    +	uint16_t numXpdGains);
    +static HAL_BOOL getLowerUpperIndex(uint8_t target, uint8_t *pList,
    +	uint16_t listSize,  uint16_t *indexL, uint16_t *indexR);
    +static uint16_t ar9285GetMaxEdgePower(uint16_t, CAL_CTL_EDGES *);
    +
    +/* XXX gag, this is sick */
    +typedef enum Ar5416_Rates {
    +	rate6mb,  rate9mb,  rate12mb, rate18mb,
    +	rate24mb, rate36mb, rate48mb, rate54mb,
    +	rate1l,   rate2l,   rate2s,   rate5_5l,
    +	rate5_5s, rate11l,  rate11s,  rateXr,
    +	rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
    +	rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
    +	rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
    +	rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
    +	rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
    +	Ar5416RateSize
    +} AR5416_RATES;
    +
    +HAL_BOOL
    +ar9285SetTransmitPower(struct ath_hal *ah,
    +	const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
    +{
    +#define POW_SM(_r, _s)     (((_r) & 0x3f) << (_s))
    +#define N(a)            (sizeof (a) / sizeof (a[0]))
    +
    +    MODAL_EEP4K_HEADER	*pModal;
    +    struct ath_hal_5212 *ahp = AH5212(ah);
    +    int16_t		ratesArray[Ar5416RateSize];
    +    int16_t		txPowerIndexOffset = 0;
    +    uint8_t		ht40PowerIncForPdadc = 2;	
    +    int			i;
    +    
    +    uint16_t		cfgCtl;
    +    uint16_t		powerLimit;
    +    uint16_t		twiceAntennaReduction;
    +    uint16_t		twiceMaxRegulatoryPower;
    +    int16_t		maxPower;
    +    HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
    +    struct ar5416eeprom_4k *pEepData = &ee->ee_base;
    +
    +    HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
    +
    +    /* Setup info for the actual eeprom */
    +    OS_MEMZERO(ratesArray, sizeof(ratesArray));
    +    cfgCtl = ath_hal_getctl(ah, chan);
    +    powerLimit = chan->ic_maxregpower * 2;
    +    twiceAntennaReduction = chan->ic_maxantgain;
    +    twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); 
    +    pModal = &pEepData->modalHeader;
    +    HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n",
    +	__func__,chan->ic_freq, cfgCtl );      
    +  
    +    if (IS_EEP_MINOR_V2(ah)) {
    +        ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
    +    }
    + 
    +    if (!ar9285SetPowerPerRateTable(ah, pEepData,  chan,
    +                                    &ratesArray[0],cfgCtl,
    +                                    twiceAntennaReduction,
    +				    twiceMaxRegulatoryPower, powerLimit)) {
    +        HALDEBUG(ah, HAL_DEBUG_ANY,
    +	    "%s: unable to set tx power per rate table\n", __func__);
    +        return AH_FALSE;
    +    }
    +
    +    if (!ar9285SetPowerCalTable(ah,  pEepData, chan, &txPowerIndexOffset)) {
    +        HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n",
    +	    __func__);
    +        return AH_FALSE;
    +    }
    +  
    +    maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]);
    +    maxPower = AH_MAX(maxPower, ratesArray[rate1l]);
    +
    +    if (IEEE80211_IS_CHAN_HT40(chan)) {
    +        maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]);
    +    }
    +
    +    ahp->ah_tx6PowerInHalfDbm = maxPower;   
    +    AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower;
    +    ahp->ah_txPowerIndexOffset = txPowerIndexOffset;
    +
    +    /*
    +     * txPowerIndexOffset is set by the SetPowerTable() call -
    +     *  adjust the rate table (0 offset if rates EEPROM not loaded)
    +     */
    +    for (i = 0; i < N(ratesArray); i++) {
    +        ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
    +        if (ratesArray[i] > AR5416_MAX_RATE_POWER)
    +            ratesArray[i] = AR5416_MAX_RATE_POWER;
    +	ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
    +    }
    +
    +#ifdef AH_EEPROM_DUMP
    +    ar5416PrintPowerPerRate(ah, ratesArray);
    +#endif
    +
    +    /* Write the OFDM power per rate set */
    +    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
    +        POW_SM(ratesArray[rate18mb], 24)
    +          | POW_SM(ratesArray[rate12mb], 16)
    +          | POW_SM(ratesArray[rate9mb], 8)
    +          | POW_SM(ratesArray[rate6mb], 0)
    +    );
    +    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
    +        POW_SM(ratesArray[rate54mb], 24)
    +          | POW_SM(ratesArray[rate48mb], 16)
    +          | POW_SM(ratesArray[rate36mb], 8)
    +          | POW_SM(ratesArray[rate24mb], 0)
    +    );
    +
    +    /* Write the CCK power per rate set */
    +    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
    +        POW_SM(ratesArray[rate2s], 24)
    +          | POW_SM(ratesArray[rate2l],  16)
    +          | POW_SM(ratesArray[rateXr],  8) /* XR target power */
    +          | POW_SM(ratesArray[rate1l],   0)
    +    );
    +    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
    +        POW_SM(ratesArray[rate11s], 24)
    +          | POW_SM(ratesArray[rate11l], 16)
    +          | POW_SM(ratesArray[rate5_5s], 8)
    +          | POW_SM(ratesArray[rate5_5l], 0)
    +    );
    +    HALDEBUG(ah, HAL_DEBUG_RESET,
    +	"%s AR_PHY_POWER_TX_RATE3=0x%x AR_PHY_POWER_TX_RATE4=0x%x\n",
    +	    __func__, OS_REG_READ(ah,AR_PHY_POWER_TX_RATE3),
    +	    OS_REG_READ(ah,AR_PHY_POWER_TX_RATE4)); 
    +
    +    /* Write the HT20 power per rate set */
    +    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
    +        POW_SM(ratesArray[rateHt20_3], 24)
    +          | POW_SM(ratesArray[rateHt20_2], 16)
    +          | POW_SM(ratesArray[rateHt20_1], 8)
    +          | POW_SM(ratesArray[rateHt20_0], 0)
    +    );
    +    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
    +        POW_SM(ratesArray[rateHt20_7], 24)
    +          | POW_SM(ratesArray[rateHt20_6], 16)
    +          | POW_SM(ratesArray[rateHt20_5], 8)
    +          | POW_SM(ratesArray[rateHt20_4], 0)
    +    );
    +
    +    if (IEEE80211_IS_CHAN_HT40(chan)) {
    +        /* Write the HT40 power per rate set */
    +	/* Correct PAR difference between HT40 and HT20/LEGACY */
    +        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
    +            POW_SM(ratesArray[rateHt40_3] + ht40PowerIncForPdadc, 24)
    +              | POW_SM(ratesArray[rateHt40_2] + ht40PowerIncForPdadc, 16)
    +              | POW_SM(ratesArray[rateHt40_1] + ht40PowerIncForPdadc, 8)
    +              | POW_SM(ratesArray[rateHt40_0] + ht40PowerIncForPdadc, 0)
    +        );
    +        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
    +            POW_SM(ratesArray[rateHt40_7] + ht40PowerIncForPdadc, 24)
    +              | POW_SM(ratesArray[rateHt40_6] + ht40PowerIncForPdadc, 16)
    +              | POW_SM(ratesArray[rateHt40_5] + ht40PowerIncForPdadc, 8)
    +              | POW_SM(ratesArray[rateHt40_4] + ht40PowerIncForPdadc, 0)
    +        );
    +        /* Write the Dup/Ext 40 power per rate set */
    +        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
    +            POW_SM(ratesArray[rateExtOfdm], 24)
    +              | POW_SM(ratesArray[rateExtCck], 16)
    +              | POW_SM(ratesArray[rateDupOfdm], 8)
    +              | POW_SM(ratesArray[rateDupCck], 0)
    +        );
    +    }
    +
    +    return AH_TRUE;
    +#undef POW_SM
    +#undef N
    +}
    +
    +HAL_BOOL
    +ar9285SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
    +{
    +    const HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
    +    const struct ar5416eeprom_4k *eep = &ee->ee_base;
    +    const MODAL_EEP4K_HEADER *pModal;
    +    int			i, regChainOffset;
    +    uint8_t		txRxAttenLocal;    /* workaround for eeprom versions <= 14.2 */
    +
    +    HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
    +    pModal = &eep->modalHeader;
    +
    +    /* NB: workaround for eeprom versions <= 14.2 */
    +    txRxAttenLocal = 23;
    +
    +    OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
    +    for (i = 0; i < AR5416_4K_MAX_CHAINS; i++) { 
    +	   if (AR_SREV_MERLIN(ah)) {
    +		if (i >= 2) break;
    +	   }
    +       	   if (AR_SREV_OWL_20_OR_LATER(ah) &&
    +            (AH5416(ah)->ah_rx_chainmask == 0x5 ||
    +	     AH5416(ah)->ah_tx_chainmask == 0x5) && i != 0) {
    +            /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 
    +             * only chains 0 and 2 populated 
    +             */
    +            regChainOffset = (i == 1) ? 0x2000 : 0x1000;
    +        } else {
    +            regChainOffset = i * 0x1000;
    +        }
    +
    +        OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, pModal->antCtrlChain[i]);
    +        OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4 + regChainOffset, 
    +        	(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4 + regChainOffset) &
    +        	~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
    +        	SM(pModal->iqCalICh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
    +        	SM(pModal->iqCalQCh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
    +
    +        /*
    +         * Large signal upgrade.
    +	 * XXX update
    +         */
    +
    +        if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
    +            OS_REG_WRITE(ah, AR_PHY_RXGAIN + regChainOffset, 
    +		(OS_REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & ~AR_PHY_RXGAIN_TXRX_ATTEN) |
    +			SM(IS_EEP_MINOR_V3(ah)  ? pModal->txRxAttenCh[i] : txRxAttenLocal,
    +				AR_PHY_RXGAIN_TXRX_ATTEN));
    +
    +            OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 
    +	    	(OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
    +			SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
    +        }
    +    }
    +
    +    OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
    +    OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
    +    OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize);
    +    OS_REG_WRITE(ah, AR_PHY_RF_CTL4,
    +        SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
    +        | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
    +        | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
    +        | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
    +
    +    OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn);
    +
    +     OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
    +	    pModal->thresh62);
    +     OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
    +	    pModal->thresh62);
    +    
    +    /* Minor Version Specific application */
    +    if (IS_EEP_MINOR_V2(ah)) {
    +        OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,  AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart);
    +        OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,  AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn);    
    +    }	
    +    
    +    if (IS_EEP_MINOR_V3(ah)) {
    +	if (IEEE80211_IS_CHAN_HT40(chan)) {
    +		/* Overwrite switch settling with HT40 value */
    +		OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
    +	}
    +	
    +        if ((AR_SREV_OWL_20_OR_LATER(ah)) &&
    +            (  AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5)){
    +            /* Reg Offsets are swapped for logical mapping */
    +		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
    +			SM(pModal->bswMargin[2], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
    +		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
    +			SM(pModal->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
    +		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
    +			SM(pModal->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
    +		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
    +			SM(pModal->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
    +        } else {
    +		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
    +			SM(pModal->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
    +		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
    +			SM(pModal->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
    +		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
    +			SM(pModal->bswMargin[2],AR_PHY_GAIN_2GHZ_BSW_MARGIN));
    +		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
    +			SM(pModal->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
    +        }
    +        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_MARGIN, pModal->bswMargin[0]);
    +        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_ATTEN, pModal->bswAtten[0]);
    +    }
    +    return AH_TRUE;
    +}
    +
    +/*
    + * Helper functions common for AP/CB/XB
    + */
    +
    +static HAL_BOOL
    +ar9285SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom_4k *pEepData,
    +                           const struct ieee80211_channel *chan,
    +                           int16_t *ratesArray, uint16_t cfgCtl,
    +                           uint16_t AntennaReduction, 
    +                           uint16_t twiceMaxRegulatoryPower,
    +                           uint16_t powerLimit)
    +{
    +#define	N(a)	(sizeof(a)/sizeof(a[0]))
    +/* Local defines to distinguish between extension and control CTL's */
    +#define EXT_ADDITIVE (0x8000)
    +#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
    +#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
    +
    +	uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
    +	int i;
    +	int16_t  twiceLargestAntenna;
    +	CAL_CTL_DATA_4K *rep;
    +	CAL_TARGET_POWER_LEG targetPowerOfdm, targetPowerCck = {0, {0, 0, 0, 0}};
    +	CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}}, targetPowerCckExt = {0, {0, 0, 0, 0}};
    +	CAL_TARGET_POWER_HT  targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0}};
    +	int16_t scaledPower, minCtlPower;
    +
    +#define SUB_NUM_CTL_MODES_AT_2G_40 3   /* excluding HT40, EXT-OFDM, EXT-CCK */
    +	static const uint16_t ctlModesFor11g[] = {
    +	   CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
    +	};
    +	const uint16_t *pCtlMode;
    +	uint16_t numCtlModes, ctlMode, freq;
    +	CHAN_CENTERS centers;
    +
    +	ar5416GetChannelCenters(ah,  chan, ¢ers);
    +
    +	/* Compute TxPower reduction due to Antenna Gain */
    +
    +	twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
    +	twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0);
    +
    +	/* XXX setup for 5212 use (really used?) */
    +	ath_hal_eepromSet(ah, AR_EEP_ANTGAINMAX_2, twiceLargestAntenna);
    +
    +	/* 
    +	 * scaledPower is the minimum of the user input power level and
    +	 * the regulatory allowed power level
    +	 */
    +	scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna);
    +
    +	/* Get target powers from EEPROM - our baseline for TX Power */
    +	/* Setup for CTL modes */
    +	numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */
    +	pCtlMode = ctlModesFor11g;
    +
    +	ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPowerCck,
    +			AR5416_4K_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE);
    +	ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPower2G,
    +			AR5416_4K_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE);
    +	ar5416GetTargetPowers(ah,  chan, pEepData->calTargetPower2GHT20,
    +			AR5416_4K_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE);
    +
    +	if (IEEE80211_IS_CHAN_HT40(chan)) {
    +		numCtlModes = N(ctlModesFor11g);    /* All 2G CTL's */
    +
    +		ar5416GetTargetPowers(ah,  chan, pEepData->calTargetPower2GHT40,
    +			AR5416_4K_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE);
    +		/* Get target powers for extension channels */
    +		ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPowerCck,
    +			AR5416_4K_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE);
    +		ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPower2G,
    +			AR5416_4K_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE);
    +	}
    +
    +	/*
    +	 * For MIMO, need to apply regulatory caps individually across dynamically
    +	 * running modes: CCK, OFDM, HT20, HT40
    +	 *
    +	 * The outer loop walks through each possible applicable runtime mode.
    +	 * The inner loop walks through each ctlIndex entry in EEPROM.
    +	 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
    +	 *
    +	 */
    +	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
    +		HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
    +		    (pCtlMode[ctlMode] == CTL_2GHT40);
    +		if (isHt40CtlMode) {
    +			freq = centers.ctl_center;
    +		} else if (pCtlMode[ctlMode] & EXT_ADDITIVE) {
    +			freq = centers.ext_center;
    +		} else {
    +			freq = centers.ctl_center;
    +		}
    +
    +		/* walk through each CTL index stored in EEPROM */
    +		for (i = 0; (i < AR5416_4K_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
    +			uint16_t twiceMinEdgePower;
    +
    +			/* compare test group from regulatory channel list with test mode from pCtlMode list */
    +			if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) ||
    +				(((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == 
    +				 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
    +				rep = &(pEepData->ctlData[i]);
    +				twiceMinEdgePower = ar9285GetMaxEdgePower(freq,
    +							rep->ctlEdges[
    +							  owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1]);
    +				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
    +					/* Find the minimum of all CTL edge powers that apply to this channel */
    +					twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
    +				} else {
    +					/* specific */
    +					twiceMaxEdgePower = twiceMinEdgePower;
    +					break;
    +				}
    +			}
    +		}
    +		minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower);
    +		/* Apply ctl mode to correct target power set */
    +		switch(pCtlMode[ctlMode]) {
    +		case CTL_11B:
    +			for (i = 0; i < N(targetPowerCck.tPow2x); i++) {
    +				targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower);
    +			}
    +			break;
    +		case CTL_11A:
    +		case CTL_11G:
    +			for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) {
    +				targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower);
    +			}
    +			break;
    +		case CTL_5GHT20:
    +		case CTL_2GHT20:
    +			for (i = 0; i < N(targetPowerHt20.tPow2x); i++) {
    +				targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower);
    +			}
    +			break;
    +		case CTL_11B_EXT:
    +			targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower);
    +			break;
    +		case CTL_11G_EXT:
    +			targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower);
    +			break;
    +		case CTL_5GHT40:
    +		case CTL_2GHT40:
    +			for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
    +				targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower);
    +			}
    +			break;
    +		default:
    +			return AH_FALSE;
    +			break;
    +		}
    +	} /* end ctl mode checking */
    +
    +	/* Set rates Array from collected data */
    +	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0];
    +	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
    +	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
    +	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
    +	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
    +
    +	for (i = 0; i < N(targetPowerHt20.tPow2x); i++) {
    +		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
    +	}
    +
    +	ratesArray[rate1l]  = targetPowerCck.tPow2x[0];
    +	ratesArray[rate2s] = ratesArray[rate2l]  = targetPowerCck.tPow2x[1];
    +	ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
    +	ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
    +	if (IEEE80211_IS_CHAN_HT40(chan)) {
    +		for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
    +			ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
    +		}
    +		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
    +		ratesArray[rateDupCck]  = targetPowerHt40.tPow2x[0];
    +		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
    +		if (IEEE80211_IS_CHAN_2GHZ(chan)) {
    +			ratesArray[rateExtCck]  = targetPowerCckExt.tPow2x[0];
    +		}
    +	}
    +	return AH_TRUE;
    +#undef EXT_ADDITIVE
    +#undef CTL_11G_EXT
    +#undef CTL_11B_EXT
    +#undef SUB_NUM_CTL_MODES_AT_2G_40
    +#undef N
    +}
    +
    +/**************************************************************************
    + * fbin2freq
    + *
    + * Get channel value from binary representation held in eeprom
    + * RETURNS: the frequency in MHz
    + */
    +static uint16_t
    +fbin2freq(uint8_t fbin)
    +{
    +    /*
    +     * 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)(2300 + fbin);
    +}
    +
    +/*
    + * XXX almost the same as ar5416GetMaxEdgePower.
    + */
    +static uint16_t
    +ar9285GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower)
    +{
    +    uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
    +    int      i;
    +
    +    /* Get the edge power */
    +    for (i = 0; (i < AR5416_NUM_BAND_EDGES) && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) {
    +        /*
    +         * If there's an exact channel match or an inband flag set
    +         * on the lower channel use the given rdEdgePower
    +         */
    +        if (freq == fbin2freq(pRdEdgesPower[i].bChannel)) {
    +            twiceMaxEdgePower = MS(pRdEdgesPower[i].tPowerFlag, CAL_CTL_EDGES_POWER);
    +            break;
    +        } else if ((i > 0) && (freq < fbin2freq(pRdEdgesPower[i].bChannel))) {
    +            if (fbin2freq(pRdEdgesPower[i - 1].bChannel) < freq && (pRdEdgesPower[i - 1].tPowerFlag & CAL_CTL_EDGES_FLAG) != 0) {
    +                twiceMaxEdgePower = MS(pRdEdgesPower[i - 1].tPowerFlag, CAL_CTL_EDGES_POWER);
    +            }
    +            /* Leave loop - no more affecting edges possible in this monotonic increasing list */
    +            break;
    +        }
    +    }
    +    HALASSERT(twiceMaxEdgePower > 0);
    +    return twiceMaxEdgePower;
    +}
    +
    +
    +
    +static HAL_BOOL
    +ar9285SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom_4k *pEepData,
    +	const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
    +{
    +    CAL_DATA_PER_FREQ_4K *pRawDataset;
    +    uint8_t  *pCalBChans = AH_NULL;
    +    uint16_t pdGainOverlap_t2;
    +    static uint8_t  pdadcValues[AR5416_NUM_PDADC_VALUES];
    +    uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
    +    uint16_t numPiers, i, j;
    +    int16_t  tMinCalPower;
    +    uint16_t numXpdGain, xpdMask;
    +    uint16_t xpdGainValues[AR5416_4K_NUM_PD_GAINS];
    +    uint32_t reg32, regOffset, regChainOffset;
    +
    +    OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues));
    +    
    +    xpdMask = pEepData->modalHeader.xpdGain;
    +
    +    if (IS_EEP_MINOR_V2(ah)) {
    +        pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
    +    } else { 
    +    	pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
    +    }
    +
    +    pCalBChans = pEepData->calFreqPier2G;
    +    numPiers = AR5416_4K_NUM_2G_CAL_PIERS;
    +    numXpdGain = 0;
    +    /* Calculate the value of xpdgains from the xpdGain Mask */
    +    for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
    +        if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
    +            if (numXpdGain >= AR5416_4K_NUM_PD_GAINS) {
    +                HALASSERT(0);
    +                break;
    +            }
    +            xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
    +            numXpdGain++;
    +        }
    +    }
    +    
    +    /* Write the detector gain biases and their number */
    +    OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) & 
    +    	~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) | 
    +	SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) |
    +	SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(xpdGainValues[2],  AR_PHY_TPCRG1_PD_GAIN_3));
    +
    +    for (i = 0; i < AR5416_MAX_CHAINS; i++) {
    +
    +            if (AR_SREV_OWL_20_OR_LATER(ah) && 
    +            ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) {
    +            /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 
    +             * only chains 0 and 2 populated 
    +             */
    +            regChainOffset = (i == 1) ? 0x2000 : 0x1000;
    +        } else {
    +            regChainOffset = i * 0x1000;
    +        }
    +
    +        if (pEepData->baseEepHeader.txMask & (1 << i)) {
    +            pRawDataset = pEepData->calPierData2G[i];
    +
    +            ar9285GetGainBoundariesAndPdadcs(ah,  chan, pRawDataset,
    +                                             pCalBChans, numPiers,
    +                                             pdGainOverlap_t2,
    +                                             &tMinCalPower, gainBoundaries,
    +                                             pdadcValues, numXpdGain);
    +
    +            if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
    +                /*
    +                 * Note the pdadc table may not start at 0 dBm power, could be
    +                 * negative or greater than 0.  Need to offset the power
    +                 * values by the amount of minPower for griffin
    +                 */
    +
    +                OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
    +                     SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
    +                     SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)  |
    +                     SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)  |
    +                     SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)  |
    +                     SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
    +            }
    +
    +            /* Write the power values into the baseband power table */
    +            regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
    +
    +            for (j = 0; j < 32; j++) {
    +                reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0)  |
    +                    ((pdadcValues[4*j + 1] & 0xFF) << 8)  |
    +                    ((pdadcValues[4*j + 2] & 0xFF) << 16) |
    +                    ((pdadcValues[4*j + 3] & 0xFF) << 24) ;
    +                OS_REG_WRITE(ah, regOffset, reg32);
    +
    +#ifdef PDADC_DUMP
    +		ath_hal_printf(ah, "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n",
    +			       i,
    +			       4*j, pdadcValues[4*j],
    +			       4*j+1, pdadcValues[4*j + 1],
    +			       4*j+2, pdadcValues[4*j + 2],
    +			       4*j+3, pdadcValues[4*j + 3]);
    +#endif
    +                regOffset += 4;
    +            }
    +        }
    +    }
    +    *pTxPowerIndexOffset = 0;
    +
    +    return AH_TRUE;
    +}
    +
    +static void
    +ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah, 
    +                                 const struct ieee80211_channel *chan,
    +				 CAL_DATA_PER_FREQ_4K *pRawDataSet,
    +                                 uint8_t * bChans,  uint16_t availPiers,
    +                                 uint16_t tPdGainOverlap, int16_t *pMinCalPower, uint16_t * pPdGainBoundaries,
    +                                 uint8_t * pPDADCValues, uint16_t numXpdGains)
    +{
    +
    +    int       i, j, k;
    +    int16_t   ss;         /* potentially -ve index for taking care of pdGainOverlap */
    +    uint16_t  idxL, idxR, numPiers; /* Pier indexes */
    +
    +    /* filled out Vpd table for all pdGains (chanL) */
    +    static uint8_t   vpdTableL[AR5416_4K_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];
    +
    +    /* filled out Vpd table for all pdGains (chanR) */
    +    static uint8_t   vpdTableR[AR5416_4K_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];
    +
    +    /* filled out Vpd table for all pdGains (interpolated) */
    +    static uint8_t   vpdTableI[AR5416_4K_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];
    +
    +    uint8_t   *pVpdL, *pVpdR, *pPwrL, *pPwrR;
    +    uint8_t   minPwrT4[AR5416_4K_NUM_PD_GAINS];
    +    uint8_t   maxPwrT4[AR5416_4K_NUM_PD_GAINS];
    +    int16_t   vpdStep;
    +    int16_t   tmpVal;
    +    uint16_t  sizeCurrVpdTable, maxIndex, tgtIndex;
    +    HAL_BOOL    match;
    +    int16_t  minDelta = 0;
    +    CHAN_CENTERS centers;
    +
    +    ar5416GetChannelCenters(ah, chan, ¢ers);
    +
    +    /* Trim numPiers for the number of populated channel Piers */
    +    for (numPiers = 0; numPiers < availPiers; numPiers++) {
    +        if (bChans[numPiers] == AR5416_BCHAN_UNUSED) {
    +            break;
    +        }
    +    }
    +
    +    /* Find pier indexes around the current channel */
    +    match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
    +			bChans, numPiers, &idxL, &idxR);
    +
    +    if (match) {
    +        /* Directly fill both vpd tables from the matching index */
    +        for (i = 0; i < numXpdGains; i++) {
    +            minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
    +            maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
    +            ar9285FillVpdTable(minPwrT4[i], maxPwrT4[i],
    +			       pRawDataSet[idxL].pwrPdg[i],
    +                               pRawDataSet[idxL].vpdPdg[i],
    +			       AR5416_PD_GAIN_ICEPTS, vpdTableI[i]);
    +        }
    +    } else {
    +        for (i = 0; i < numXpdGains; i++) {
    +            pVpdL = pRawDataSet[idxL].vpdPdg[i];
    +            pPwrL = pRawDataSet[idxL].pwrPdg[i];
    +            pVpdR = pRawDataSet[idxR].vpdPdg[i];
    +            pPwrR = pRawDataSet[idxR].pwrPdg[i];
    +
    +            /* Start Vpd interpolation from the max of the minimum powers */
    +            minPwrT4[i] = AH_MAX(pPwrL[0], pPwrR[0]);
    +
    +            /* End Vpd interpolation from the min of the max powers */
    +            maxPwrT4[i] = AH_MIN(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
    +            HALASSERT(maxPwrT4[i] > minPwrT4[i]);
    +
    +            /* Fill pier Vpds */
    +            ar9285FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL,
    +			       AR5416_PD_GAIN_ICEPTS, vpdTableL[i]);
    +            ar9285FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR,
    +			       AR5416_PD_GAIN_ICEPTS, vpdTableR[i]);
    +
    +            /* Interpolate the final vpd */
    +            for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
    +                vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
    +                    bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j]));
    +            }
    +        }
    +    }
    +    *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
    +
    +    k = 0; /* index for the final table */
    +    for (i = 0; i < numXpdGains; i++) {
    +        if (i == (numXpdGains - 1)) {
    +            pPdGainBoundaries[i] = (uint16_t)(maxPwrT4[i] / 2);
    +        } else {
    +            pPdGainBoundaries[i] = (uint16_t)((maxPwrT4[i] + minPwrT4[i+1]) / 4);
    +        }
    +
    +        pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
    +
    +	/* NB: only applies to owl 1.0 */
    +        if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) {
    +	    /*
    +             * fix the gain delta, but get a delta that can be applied to min to
    +             * keep the upper power values accurate, don't think max needs to
    +             * be adjusted because should not be at that area of the table?
    +	     */
    +            minDelta = pPdGainBoundaries[0] - 23;
    +            pPdGainBoundaries[0] = 23;
    +        }
    +        else {
    +            minDelta = 0;
    +        }
    +
    +        /* Find starting index for this pdGain */
    +        if (i == 0) {
    +            ss = 0; /* for the first pdGain, start from index 0 */
    +        } else {
    +	    /* need overlap entries extrapolated below. */
    +            ss = (int16_t)((pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta);
    +        }
    +        vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
    +        vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
    +        /*
    +         *-ve ss indicates need to extrapolate data below for this pdGain
    +         */
    +        while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
    +            tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
    +            pPDADCValues[k++] = (uint8_t)((tmpVal < 0) ? 0 : tmpVal);
    +            ss++;
    +        }
    +
    +        sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1);
    +        tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2));
    +        maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
    +
    +        while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
    +            pPDADCValues[k++] = vpdTableI[i][ss++];
    +        }
    +
    +        vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]);
    +        vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
    +        /*
    +         * for last gain, pdGainBoundary == Pmax_t2, so will
    +         * have to extrapolate
    +         */
    +        if (tgtIndex > maxIndex) {  /* need to extrapolate above */
    +            while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
    +                tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
    +                          (ss - maxIndex +1) * vpdStep));
    +                pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ? 255 : tmpVal);
    +                ss++;
    +            }
    +        }               /* extrapolated above */
    +    }                   /* for all pdGainUsed */
    +
    +    /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */
    +    while (i < AR5416_PD_GAINS_IN_MASK) {
    +        pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
    +        i++;
    +    }
    +
    +    while (k < AR5416_NUM_PDADC_VALUES) {
    +        pPDADCValues[k] = pPDADCValues[k-1];
    +        k++;
    +    }
    +    return;
    +}
    +/*
    + * XXX same as ar5416FillVpdTable
    + */
    +static HAL_BOOL
    +ar9285FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
    +                   uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
    +{
    +    uint16_t  i, k;
    +    uint8_t   currPwr = pwrMin;
    +    uint16_t  idxL, idxR;
    +
    +    HALASSERT(pwrMax > pwrMin);
    +    for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
    +        getLowerUpperIndex(currPwr, pPwrList, numIntercepts,
    +                           &(idxL), &(idxR));
    +        if (idxR < 1)
    +            idxR = 1;           /* extrapolate below */
    +        if (idxL == numIntercepts - 1)
    +            idxL = (uint16_t)(numIntercepts - 2);   /* extrapolate above */
    +        if (pPwrList[idxL] == pPwrList[idxR])
    +            k = pVpdList[idxL];
    +        else
    +            k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
    +                  (pPwrList[idxR] - pPwrList[idxL]) );
    +        HALASSERT(k < 256);
    +        pRetVpdList[i] = (uint8_t)k;
    +        currPwr += 2;               /* half dB steps */
    +    }
    +
    +    return AH_TRUE;
    +}
    +static int16_t
    +interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
    +            int16_t targetLeft, int16_t targetRight)
    +{
    +    int16_t rv;
    +
    +    if (srcRight == srcLeft) {
    +        rv = targetLeft;
    +    } else {
    +        rv = (int16_t)( ((target - srcLeft) * targetRight +
    +              (srcRight - target) * targetLeft) / (srcRight - srcLeft) );
    +    }
    +    return rv;
    +}
    +
    +HAL_BOOL
    +getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize,
    +                   uint16_t *indexL, uint16_t *indexR)
    +{
    +    uint16_t i;
    +
    +    /*
    +     * Check first and last elements for beyond ordered array cases.
    +     */
    +    if (target <= pList[0]) {
    +        *indexL = *indexR = 0;
    +        return AH_TRUE;
    +    }
    +    if (target >= pList[listSize-1]) {
    +        *indexL = *indexR = (uint16_t)(listSize - 1);
    +        return AH_TRUE;
    +    }
    +
    +    /* look for value being near or between 2 values in list */
    +    for (i = 0; i < listSize - 1; i++) {
    +        /*
    +         * If value is close to the current value of the list
    +         * then target is not between values, it is one of the values
    +         */
    +        if (pList[i] == target) {
    +            *indexL = *indexR = i;
    +            return AH_TRUE;
    +        }
    +        /*
    +         * Look for value being between current value and next value
    +         * if so return these 2 values
    +         */
    +        if (target < pList[i + 1]) {
    +            *indexL = i;
    +            *indexR = (uint16_t)(i + 1);
    +            return AH_FALSE;
    +        }
    +    }
    +    HALASSERT(0);
    +    *indexL = *indexR = 0;
    +    return AH_FALSE;
    +}
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar9285v2.ini b/sys/dev/ath/ath_hal/ar5416/ar9285v2.ini
    new file mode 100644
    index 00000000000..2a9de1dba47
    --- /dev/null
    +++ b/sys/dev/ath/ath_hal/ar5416/ar9285v2.ini
    @@ -0,0 +1,746 @@
    +/*
    + * Copyright (c) 2008-2009 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$
    + */
    +
    +/* AR9285 v1_2 PCI Register Writes.  Created: 04/13/09 */
    +static const u_int32_t ar9285Modes_v2[][6] = {
    +    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
    +    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
    +    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
    +    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
    +    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
    +    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
    +    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
    +    { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
    +    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
    +    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
    +    { 0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e },
    +    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
    +    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
    +    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
    +    { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
    +    { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
    +    { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
    +    { 0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
    +    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
    +    { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
    +    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
    +    { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
    +    { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
    +    { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
    +    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
    +    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
    +    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
    +    { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
    +    { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010 },
    +    { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c },
    +    { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
    +    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
    +    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
    +    { 0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f },
    +    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
    +    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
    +    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
    +    { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
    +    { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
    +    { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
    +    { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
    +    { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
    +    { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
    +    { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
    +    { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
    +    { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
    +    { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
    +    { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
    +    { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
    +    { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
    +    { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
    +    { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
    +    { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
    +    { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
    +    { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
    +    { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
    +    { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
    +    { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
    +    { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
    +    { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
    +    { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
    +    { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
    +    { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
    +    { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
    +    { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
    +    { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
    +    { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
    +    { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
    +    { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
    +    { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
    +    { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
    +    { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
    +    { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
    +    { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
    +    { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
    +    { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
    +    { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
    +    { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
    +    { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
    +    { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
    +    { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
    +    { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
    +    { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
    +    { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
    +    { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
    +    { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
    +    { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
    +    { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
    +    { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
    +    { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
    +    { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
    +    { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
    +    { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
    +    { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
    +    { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
    +    { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
    +    { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
    +    { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
    +    { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
    +    { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
    +    { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
    +    { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
    +    { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
    +    { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
    +    { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
    +    { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
    +    { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
    +    { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
    +    { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
    +    { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
    +    { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
    +    { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
    +    { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
    +    { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
    +    { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
    +    { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
    +    { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
    +    { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
    +    { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
    +    { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
    +    { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
    +    { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
    +    { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
    +    { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
    +    { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
    +    { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
    +    { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
    +    { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
    +    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
    +    { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
    +    { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
    +    { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
    +    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
    +    { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
    +    { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
    +    { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
    +    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
    +    { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
    +    { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
    +    { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
    +    { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
    +    { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
    +    { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
    +    { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
    +    { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
    +    { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
    +    { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
    +    { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
    +    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
    +    { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
    +    { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
    +    { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
    +    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
    +    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
    +    { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
    +    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
    +    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
    +    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
    +    { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
    +    { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
    +    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
    +    { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
    +    { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
    +    { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
    +    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
    +    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
    +    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
    +    { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
    +    { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
    +    { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
    +    { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
    +    { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
    +    { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
    +    { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
    +    { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
    +    { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
    +    { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
    +    { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
    +    { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
    +    { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
    +    { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
    +    { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
    +    { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
    +    { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
    +    { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
    +    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
    +    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
    +    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
    +    { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
    +    { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
    +    { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
    +    { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
    +    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
    +    { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
    +    { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
    +    { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
    +    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
    +    { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
    +    { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
    +    { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
    +    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
    +    { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
    +    { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
    +    { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
    +    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
    +    { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
    +    { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
    +    { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
    +    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
    +    { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
    +    { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
    +    { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
    +    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
    +    { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
    +    { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
    +    { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
    +    { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
    +    { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
    +    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
    +    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
    +    { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
    +    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
    +};
    +
    +static const u_int32_t ar9285Common_v2[][2] = {
    +    { 0x0000000c, 0x00000000 },
    +    { 0x00000030, 0x00020045 },
    +    { 0x00000034, 0x00000005 },
    +    { 0x00000040, 0x00000000 },
    +    { 0x00000044, 0x00000008 },
    +    { 0x00000048, 0x00000008 },
    +    { 0x0000004c, 0x00000010 },
    +    { 0x00000050, 0x00000000 },
    +    { 0x00000054, 0x0000001f },
    +    { 0x00000800, 0x00000000 },
    +    { 0x00000804, 0x00000000 },
    +    { 0x00000808, 0x00000000 },
    +    { 0x0000080c, 0x00000000 },
    +    { 0x00000810, 0x00000000 },
    +    { 0x00000814, 0x00000000 },
    +    { 0x00000818, 0x00000000 },
    +    { 0x0000081c, 0x00000000 },
    +    { 0x00000820, 0x00000000 },
    +    { 0x00000824, 0x00000000 },
    +    { 0x00001040, 0x002ffc0f },
    +    { 0x00001044, 0x002ffc0f },
    +    { 0x00001048, 0x002ffc0f },
    +    { 0x0000104c, 0x002ffc0f },
    +    { 0x00001050, 0x002ffc0f },
    +    { 0x00001054, 0x002ffc0f },
    +    { 0x00001058, 0x002ffc0f },
    +    { 0x0000105c, 0x002ffc0f },
    +    { 0x00001060, 0x002ffc0f },
    +    { 0x00001064, 0x002ffc0f },
    +    { 0x00001230, 0x00000000 },
    +    { 0x00001270, 0x00000000 },
    +    { 0x00001038, 0x00000000 },
    +    { 0x00001078, 0x00000000 },
    +    { 0x000010b8, 0x00000000 },
    +    { 0x000010f8, 0x00000000 },
    +    { 0x00001138, 0x00000000 },
    +    { 0x00001178, 0x00000000 },
    +    { 0x000011b8, 0x00000000 },
    +    { 0x000011f8, 0x00000000 },
    +    { 0x00001238, 0x00000000 },
    +    { 0x00001278, 0x00000000 },
    +    { 0x000012b8, 0x00000000 },
    +    { 0x000012f8, 0x00000000 },
    +    { 0x00001338, 0x00000000 },
    +    { 0x00001378, 0x00000000 },
    +    { 0x000013b8, 0x00000000 },
    +    { 0x000013f8, 0x00000000 },
    +    { 0x00001438, 0x00000000 },
    +    { 0x00001478, 0x00000000 },
    +    { 0x000014b8, 0x00000000 },
    +    { 0x000014f8, 0x00000000 },
    +    { 0x00001538, 0x00000000 },
    +    { 0x00001578, 0x00000000 },
    +    { 0x000015b8, 0x00000000 },
    +    { 0x000015f8, 0x00000000 },
    +    { 0x00001638, 0x00000000 },
    +    { 0x00001678, 0x00000000 },
    +    { 0x000016b8, 0x00000000 },
    +    { 0x000016f8, 0x00000000 },
    +    { 0x00001738, 0x00000000 },
    +    { 0x00001778, 0x00000000 },
    +    { 0x000017b8, 0x00000000 },
    +    { 0x000017f8, 0x00000000 },
    +    { 0x0000103c, 0x00000000 },
    +    { 0x0000107c, 0x00000000 },
    +    { 0x000010bc, 0x00000000 },
    +    { 0x000010fc, 0x00000000 },
    +    { 0x0000113c, 0x00000000 },
    +    { 0x0000117c, 0x00000000 },
    +    { 0x000011bc, 0x00000000 },
    +    { 0x000011fc, 0x00000000 },
    +    { 0x0000123c, 0x00000000 },
    +    { 0x0000127c, 0x00000000 },
    +    { 0x000012bc, 0x00000000 },
    +    { 0x000012fc, 0x00000000 },
    +    { 0x0000133c, 0x00000000 },
    +    { 0x0000137c, 0x00000000 },
    +    { 0x000013bc, 0x00000000 },
    +    { 0x000013fc, 0x00000000 },
    +    { 0x0000143c, 0x00000000 },
    +    { 0x0000147c, 0x00000000 },
    +    { 0x00004030, 0x00000002 },
    +    { 0x0000403c, 0x00000002 },
    +    { 0x00004024, 0x0000001f },
    +    { 0x00004060, 0x00000000 },
    +    { 0x00004064, 0x00000000 },
    +    { 0x00007010, 0x00000031 },
    +    { 0x00007034, 0x00000002 },
    +    { 0x00007038, 0x000004c2 },
    +    { 0x00008004, 0x00000000 },
    +    { 0x00008008, 0x00000000 },
    +    { 0x0000800c, 0x00000000 },
    +    { 0x00008018, 0x00000700 },
    +    { 0x00008020, 0x00000000 },
    +    { 0x00008038, 0x00000000 },
    +    { 0x0000803c, 0x00000000 },
    +    { 0x00008048, 0x00000000 },
    +    { 0x00008054, 0x00000000 },
    +    { 0x00008058, 0x00000000 },
    +    { 0x0000805c, 0x000fc78f },
    +    { 0x00008060, 0x0000000f },
    +    { 0x00008064, 0x00000000 },
    +    { 0x00008070, 0x00000000 },
    +    { 0x000080c0, 0x2a80001a },
    +    { 0x000080c4, 0x05dc01e0 },
    +    { 0x000080c8, 0x1f402710 },
    +    { 0x000080cc, 0x01f40000 },
    +    { 0x000080d0, 0x00001e00 },
    +    { 0x000080d4, 0x00000000 },
    +    { 0x000080d8, 0x00400000 },
    +    { 0x000080e0, 0xffffffff },
    +    { 0x000080e4, 0x0000ffff },
    +    { 0x000080e8, 0x003f3f3f },
    +    { 0x000080ec, 0x00000000 },
    +    { 0x000080f0, 0x00000000 },
    +    { 0x000080f4, 0x00000000 },
    +    { 0x000080f8, 0x00000000 },
    +    { 0x000080fc, 0x00020000 },
    +    { 0x00008100, 0x00020000 },
    +    { 0x00008104, 0x00000001 },
    +    { 0x00008108, 0x00000052 },
    +    { 0x0000810c, 0x00000000 },
    +    { 0x00008110, 0x00000168 },
    +    { 0x00008118, 0x000100aa },
    +    { 0x0000811c, 0x00003210 },
    +    { 0x00008120, 0x08f04810 },
    +    { 0x00008124, 0x00000000 },
    +    { 0x00008128, 0x00000000 },
    +    { 0x0000812c, 0x00000000 },
    +    { 0x00008130, 0x00000000 },
    +    { 0x00008134, 0x00000000 },
    +    { 0x00008138, 0x00000000 },
    +    { 0x0000813c, 0x00000000 },
    +    { 0x00008144, 0xffffffff },
    +    { 0x00008168, 0x00000000 },
    +    { 0x0000816c, 0x00000000 },
    +    { 0x00008170, 0x32143320 },
    +    { 0x00008174, 0xfaa4fa50 },
    +    { 0x00008178, 0x00000100 },
    +    { 0x0000817c, 0x00000000 },
    +    { 0x000081c0, 0x00000000 },
    +    { 0x000081d0, 0x0000320a },
    +    { 0x000081ec, 0x00000000 },
    +    { 0x000081f0, 0x00000000 },
    +    { 0x000081f4, 0x00000000 },
    +    { 0x000081f8, 0x00000000 },
    +    { 0x000081fc, 0x00000000 },
    +    { 0x00008200, 0x00000000 },
    +    { 0x00008204, 0x00000000 },
    +    { 0x00008208, 0x00000000 },
    +    { 0x0000820c, 0x00000000 },
    +    { 0x00008210, 0x00000000 },
    +    { 0x00008214, 0x00000000 },
    +    { 0x00008218, 0x00000000 },
    +    { 0x0000821c, 0x00000000 },
    +    { 0x00008220, 0x00000000 },
    +    { 0x00008224, 0x00000000 },
    +    { 0x00008228, 0x00000000 },
    +    { 0x0000822c, 0x00000000 },
    +    { 0x00008230, 0x00000000 },
    +    { 0x00008234, 0x00000000 },
    +    { 0x00008238, 0x00000000 },
    +    { 0x0000823c, 0x00000000 },
    +    { 0x00008240, 0x00100000 },
    +    { 0x00008244, 0x0010f400 },
    +    { 0x00008248, 0x00000100 },
    +    { 0x0000824c, 0x0001e800 },
    +    { 0x00008250, 0x00000000 },
    +    { 0x00008254, 0x00000000 },
    +    { 0x00008258, 0x00000000 },
    +    { 0x0000825c, 0x400000ff },
    +    { 0x00008260, 0x00080922 },
    +    { 0x00008264, 0x88a00010 },
    +    { 0x00008270, 0x00000000 },
    +    { 0x00008274, 0x40000000 },
    +    { 0x00008278, 0x003e4180 },
    +    { 0x0000827c, 0x00000000 },
    +    { 0x00008284, 0x0000002c },
    +    { 0x00008288, 0x0000002c },
    +    { 0x0000828c, 0x00000000 },
    +    { 0x00008294, 0x00000000 },
    +    { 0x00008298, 0x00000000 },
    +    { 0x0000829c, 0x00000000 },
    +    { 0x00008300, 0x00000040 },
    +    { 0x00008314, 0x00000000 },
    +    { 0x00008328, 0x00000000 },
    +    { 0x0000832c, 0x00000001 },
    +    { 0x00008330, 0x00000302 },
    +    { 0x00008334, 0x00000e00 },
    +    { 0x00008338, 0x00ff0000 },
    +    { 0x0000833c, 0x00000000 },
    +    { 0x00008340, 0x00010380 },
    +    { 0x00008344, 0x00481043 },
    +    { 0x00009808, 0x00000000 },
    +    { 0x0000980c, 0xafe68e30 },
    +    { 0x00009810, 0xfd14e000 },
    +    { 0x00009814, 0x9c0a9f6b },
    +    { 0x0000981c, 0x00000000 },
    +    { 0x0000982c, 0x0000a000 },
    +    { 0x00009830, 0x00000000 },
    +    { 0x0000983c, 0x00200400 },
    +    { 0x0000984c, 0x0040233c },
    +    { 0x00009854, 0x00000044 },
    +    { 0x00009900, 0x00000000 },
    +    { 0x00009904, 0x00000000 },
    +    { 0x00009908, 0x00000000 },
    +    { 0x0000990c, 0x00000000 },
    +    { 0x00009910, 0x01002310 },
    +    { 0x0000991c, 0x10000fff },
    +    { 0x00009920, 0x04900000 },
    +    { 0x00009928, 0x00000001 },
    +    { 0x0000992c, 0x00000004 },
    +    { 0x00009934, 0x1e1f2022 },
    +    { 0x00009938, 0x0a0b0c0d },
    +    { 0x0000993c, 0x00000000 },
    +    { 0x00009940, 0x14750604 },
    +    { 0x00009948, 0x9280c00a },
    +    { 0x0000994c, 0x00020028 },
    +    { 0x00009954, 0x5f3ca3de },
    +    { 0x00009958, 0x2108ecff },
    +    { 0x00009968, 0x000003ce },
    +    { 0x00009970, 0x192bb514 },
    +    { 0x00009974, 0x00000000 },
    +    { 0x00009978, 0x00000001 },
    +    { 0x0000997c, 0x00000000 },
    +    { 0x00009980, 0x00000000 },
    +    { 0x00009984, 0x00000000 },
    +    { 0x00009988, 0x00000000 },
    +    { 0x0000998c, 0x00000000 },
    +    { 0x00009990, 0x00000000 },
    +    { 0x00009994, 0x00000000 },
    +    { 0x00009998, 0x00000000 },
    +    { 0x0000999c, 0x00000000 },
    +    { 0x000099a0, 0x00000000 },
    +    { 0x000099a4, 0x00000001 },
    +    { 0x000099a8, 0x201fff00 },
    +    { 0x000099ac, 0x2def0400 },
    +    { 0x000099b0, 0x03051000 },
    +    { 0x000099b4, 0x00000820 },
    +    { 0x000099dc, 0x00000000 },
    +    { 0x000099e0, 0x00000000 },
    +    { 0x000099e4, 0xaaaaaaaa },
    +    { 0x000099e8, 0x3c466478 },
    +    { 0x000099ec, 0x0cc80caa },
    +    { 0x000099f0, 0x00000000 },
    +    { 0x0000a208, 0x803e68c8 },
    +    { 0x0000a210, 0x4080a333 },
    +    { 0x0000a214, 0x00206c10 },
    +    { 0x0000a218, 0x009c4060 },
    +    { 0x0000a220, 0x01834061 },
    +    { 0x0000a224, 0x00000400 },
    +    { 0x0000a228, 0x000003b5 },
    +    { 0x0000a22c, 0x00000000 },
    +    { 0x0000a234, 0x20202020 },
    +    { 0x0000a238, 0x20202020 },
    +    { 0x0000a244, 0x00000000 },
    +    { 0x0000a248, 0xfffffffc },
    +    { 0x0000a24c, 0x00000000 },
    +    { 0x0000a254, 0x00000000 },
    +    { 0x0000a258, 0x0ccb5380 },
    +    { 0x0000a25c, 0x15151501 },
    +    { 0x0000a260, 0xdfa90f01 },
    +    { 0x0000a268, 0x00000000 },
    +    { 0x0000a26c, 0x0ebae9e6 },
    +    { 0x0000d270, 0x0d820820 },
    +    { 0x0000d35c, 0x07ffffef },
    +    { 0x0000d360, 0x0fffffe7 },
    +    { 0x0000d364, 0x17ffffe5 },
    +    { 0x0000d368, 0x1fffffe4 },
    +    { 0x0000d36c, 0x37ffffe3 },
    +    { 0x0000d370, 0x3fffffe3 },
    +    { 0x0000d374, 0x57ffffe3 },
    +    { 0x0000d378, 0x5fffffe2 },
    +    { 0x0000d37c, 0x7fffffe2 },
    +    { 0x0000d380, 0x7f3c7bba },
    +    { 0x0000d384, 0xf3307ff0 },
    +    { 0x0000a388, 0x0c000000 },
    +    { 0x0000a38c, 0x20202020 },
    +    { 0x0000a390, 0x20202020 },
    +    { 0x0000a39c, 0x00000001 },
    +    { 0x0000a3a0, 0x00000000 },
    +    { 0x0000a3a4, 0x00000000 },
    +    { 0x0000a3a8, 0x00000000 },
    +    { 0x0000a3ac, 0x00000000 },
    +    { 0x0000a3b0, 0x00000000 },
    +    { 0x0000a3b4, 0x00000000 },
    +    { 0x0000a3b8, 0x00000000 },
    +    { 0x0000a3bc, 0x00000000 },
    +    { 0x0000a3c0, 0x00000000 },
    +    { 0x0000a3c4, 0x00000000 },
    +    { 0x0000a3cc, 0x20202020 },
    +    { 0x0000a3d0, 0x20202020 },
    +    { 0x0000a3d4, 0x20202020 },
    +    { 0x0000a3e4, 0x00000000 },
    +    { 0x0000a3e8, 0x18c43433 },
    +    { 0x0000a3ec, 0x00f70081 },
    +    { 0x00007800, 0x00140000 },
    +    { 0x00007804, 0x0e4548d8 },
    +    { 0x00007808, 0x54214514 },
    +    { 0x0000780c, 0x02025830 },
    +    { 0x00007810, 0x71c0d388 },
    +    { 0x00007814, 0x924934a8 },
    +    { 0x0000781c, 0x00000000 },
    +    { 0x00007824, 0x00d86fff },
    +    { 0x00007828, 0x26d2491b },
    +    { 0x0000782c, 0x6e36d97b },
    +    { 0x00007830, 0xedb6d96e },
    +    { 0x00007834, 0x71400087 },
    +    { 0x0000783c, 0x0001fffe },
    +    { 0x00007840, 0xffeb1a20 },
    +    { 0x00007844, 0x000c0db6 },
    +    { 0x00007848, 0x6db61b6f },
    +    { 0x0000784c, 0x6d9b66db },
    +    { 0x00007850, 0x6d8c6dba },
    +    { 0x00007854, 0x00040000 },
    +    { 0x00007858, 0xdb003012 },
    +    { 0x0000785c, 0x04924914 },
    +    { 0x00007860, 0x21084210 },
    +    { 0x00007864, 0xf7d7ffde },
    +    { 0x00007868, 0xc2034080 },
    +    { 0x00007870, 0x10142c00 },
    +};
    +
    +static const u_int32_t ar9285Modes_high_power_tx_gain_v2[][6] = {
    +    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
    +    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 },
    +    { 0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000 },
    +    { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
    +    { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
    +    { 0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000 },
    +    { 0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000 },
    +    { 0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000 },
    +    { 0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000 },
    +    { 0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000 },
    +    { 0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000 },
    +    { 0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
    +    { 0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000 },
    +    { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
    +    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
    +    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
    +    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
    +    { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
    +    { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
    +    { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 },
    +    { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
    +    { 0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7 },
    +    { 0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
    +    { 0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
    +    { 0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
    +    { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
    +};
    +
    +static const u_int32_t ar9285Modes_original_tx_gain_v2[][6] = {
    +    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
    +    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    +    { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
    +    { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
    +    { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
    +    { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
    +    { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
    +    { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
    +    { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
    +    { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
    +    { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
    +    { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
    +    { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
    +    { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
    +    { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
    +    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
    +    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
    +    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
    +    { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
    +    { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
    +    { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
    +    { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
    +    { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
    +    { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
    +    { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
    +    { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
    +    { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
    +    { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
    +};
    +
    +static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_v2[][2] = {
    +    {0x00004040,  0x9248fd00 },
    +    {0x00004040,  0x24924924 },
    +    {0x00004040,  0xa8000019 },
    +    {0x00004040,  0x13160820 },
    +    {0x00004040,  0xe5980560 },
    +    {0x00004040,  0xc01dcffd },
    +    {0x00004040,  0x1aaabe41 },
    +    {0x00004040,  0xbe105554 },
    +    {0x00004040,  0x00043007 },
    +    {0x00004044,  0x00000000 },
    +};
    +
    +static const u_int32_t ar9285PciePhy_clkreq_off_L1_v2[][2] = {
    +    {0x00004040,  0x9248fd00 },
    +    {0x00004040,  0x24924924 },
    +    {0x00004040,  0xa8000019 },
    +    {0x00004040,  0x13160820 },
    +    {0x00004040,  0xe5980560 },
    +    {0x00004040,  0xc01dcffc },
    +    {0x00004040,  0x1aaabe41 },
    +    {0x00004040,  0xbe105554 },
    +    {0x00004040,  0x00043007 },
    +    {0x00004044,  0x00000000 },
    +};
    diff --git a/sys/modules/ath/Makefile b/sys/modules/ath/Makefile
    index d494c45634c..d6f798fd255 100644
    --- a/sys/modules/ath/Makefile
    +++ b/sys/modules/ath/Makefile
    @@ -91,6 +91,7 @@ SRCS+=	ah_eeprom_v14.c \
     SRCS+=	ar9160_attach.c
     # RF backend for 5416 and 9160
     SRCS+=	ar2133.c
    +SRCS+=	ar9285.c ar9285_attach.c
     
     # NB: rate control is bound to the driver by symbol names so only pick one
     .if ${ATH_RATE} == "sample"
    
    From 69b94525454387bb958cfe89f8755c58386a8348 Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Tue, 2 Mar 2010 16:25:07 +0000
    Subject: [PATCH 1536/2592] MFC 204427: Add the shutdown KEYWORD.
    
    ---
     etc/rc.d/rtsold | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/etc/rc.d/rtsold b/etc/rc.d/rtsold
    index bbecebb4d3a..64a83e3a08a 100755
    --- a/etc/rc.d/rtsold
    +++ b/etc/rc.d/rtsold
    @@ -6,7 +6,7 @@
     # PROVIDE: rtsold
     # REQUIRE: netif
     # BEFORE: NETWORKING
    -# KEYWORD: nojail
    +# KEYWORD: nojail shutdown
     
     . /etc/rc.subr
     
    
    From c288186fe8d670bb085c18fd9ac9d315b2acc19b Mon Sep 17 00:00:00 2001
    From: Alan Cox 
    Date: Tue, 2 Mar 2010 16:29:08 +0000
    Subject: [PATCH 1537/2592] MFC r204420   When running as a guest operating
     system, the FreeBSD kernel must assume   that the virtual machine monitor has
     enabled machine check exceptions.   Unfortunately, on AMD Family 10h
     processors the machine check hardware   has a bug (Erratum 383) that can
     result in a false machine check exception   when a superpage promotion
     occurs.  Thus, I am disabling superpage   promotion when the FreeBSD kernel
     is running as a guest operating system   on an AMD Family 10h processor.
    
    ---
     sys/amd64/amd64/pmap.c | 9 +++++++++
     sys/i386/i386/pmap.c   | 9 +++++++++
     sys/kern/subr_param.c  | 8 ++++----
     sys/sys/systm.h        | 3 +++
     4 files changed, 25 insertions(+), 4 deletions(-)
    
    diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
    index b26cc68f751..7bb81ccfcae 100644
    --- a/sys/amd64/amd64/pmap.c
    +++ b/sys/amd64/amd64/pmap.c
    @@ -653,6 +653,15 @@ pmap_init(void)
     	TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
     	pv_entry_high_water = 9 * (pv_entry_max / 10);
     
    +	/*
    +	 * Disable large page mappings by default if the kernel is running in
    +	 * a virtual machine on an AMD Family 10h processor.  This is a work-
    +	 * around for Erratum 383.
    +	 */
    +	if (vm_guest == VM_GUEST_VM && cpu_vendor_id == CPU_VENDOR_AMD &&
    +	    CPUID_TO_FAMILY(cpu_id) == 0x10)
    +		pg_ps_enabled = 0;
    +
     	/*
     	 * Are large page mappings enabled?
     	 */
    diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
    index 85e6ffb284a..c75491f10e5 100644
    --- a/sys/i386/i386/pmap.c
    +++ b/sys/i386/i386/pmap.c
    @@ -677,6 +677,15 @@ pmap_init(void)
     	pv_entry_max = roundup(pv_entry_max, _NPCPV);
     	pv_entry_high_water = 9 * (pv_entry_max / 10);
     
    +	/*
    +	 * Disable large page mappings by default if the kernel is running in
    +	 * a virtual machine on an AMD Family 10h processor.  This is a work-
    +	 * around for Erratum 383.
    +	 */
    +	if (vm_guest == VM_GUEST_VM && cpu_vendor_id == CPU_VENDOR_AMD &&
    +	    CPUID_TO_FAMILY(cpu_id) == 0x10)
    +		pg_ps_enabled = 0;
    +
     	/*
     	 * Are large page mappings enabled?
     	 */
    diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c
    index 1504a784c77..a4d4ff87c44 100644
    --- a/sys/kern/subr_param.c
    +++ b/sys/kern/subr_param.c
    @@ -74,10 +74,6 @@ __FBSDID("$FreeBSD$");
     #define	MAXFILES (maxproc * 2)
     #endif
     
    -/* Values of enum VM_GUEST members are used as indices in 
    - * vm_guest_sysctl_names */
    -enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
    -
     static int sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS);
     
     int	hz;
    @@ -137,6 +133,10 @@ SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CTLTYPE_STRING,
      */
     struct	buf *swbuf;
     
    +/*
    + * The elements of this array are ordered based upon the values of the
    + * corresponding enum VM_GUEST members.
    + */
     static const char *const vm_guest_sysctl_names[] = {
     	"none",
     	"generic",
    diff --git a/sys/sys/systm.h b/sys/sys/systm.h
    index a95ca0e986f..1359bcd7c37 100644
    --- a/sys/sys/systm.h
    +++ b/sys/sys/systm.h
    @@ -65,6 +65,9 @@ extern int bootverbose;		/* nonzero to print verbose messages */
     
     extern int maxusers;		/* system tune hint */
     extern int ngroups_max;		/* max # of supplemental groups */
    +extern int vm_guest;		/* Running as virtual machine guest? */
    +
    +enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
     
     #ifdef	INVARIANTS		/* The option is always available */
     #define	KASSERT(exp,msg) do {						\
    
    From 7b6f635a13b11f8ef474729c0dd103493eac43ac Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Tue, 2 Mar 2010 18:38:00 +0000
    Subject: [PATCH 1538/2592] MFC r203823: kgdb: initialize n_type field of nlist
     entry for kvm_nlist
    
    ---
     gnu/usr.bin/gdb/kgdb/kthr.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/gnu/usr.bin/gdb/kgdb/kthr.c b/gnu/usr.bin/gdb/kgdb/kthr.c
    index 7e5b1c00665..1ab66eb61f5 100644
    --- a/gnu/usr.bin/gdb/kgdb/kthr.c
    +++ b/gnu/usr.bin/gdb/kgdb/kthr.c
    @@ -58,6 +58,7 @@ kgdb_lookup(const char *sym)
     {
     	struct nlist nl[2];
     
    +	nl[0].n_type = N_UNDF;
     	nl[0].n_name = (char *)(uintptr_t)sym;
     	nl[1].n_name = NULL;
     	if (kvm_nlist(kvm, nl) != 0)
    
    From 91288970cef24eec42482ddae319a49571084ceb Mon Sep 17 00:00:00 2001
    From: Jaakko Heinonen 
    Date: Wed, 3 Mar 2010 16:06:43 +0000
    Subject: [PATCH 1539/2592] MFC r204276:
    
    Fix expansion of \W in prompt strings when the working directory is "/".
    The prompt string was truncated after \W when the working directory was "/".
    
    PR:		bin/89410
    ---
     bin/sh/parser.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/bin/sh/parser.c b/bin/sh/parser.c
    index b898d7a3990..73d628eb7e6 100644
    --- a/bin/sh/parser.c
    +++ b/bin/sh/parser.c
    @@ -1631,7 +1631,7 @@ getprompt(void *unused __unused)
     			case 'w':
     				ps[i] = '\0';
     				getcwd(&ps[i], PROMPTLEN - i);
    -				if (*fmt == 'W') {
    +				if (*fmt == 'W' && ps[i + 1] != '\0') {
     					/* Final path component only. */
     					trim = 1;
     					for (j = i; ps[j] != '\0'; j++)
    
    From 4c881381613d22635f9c3d4820df20afba665568 Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Wed, 3 Mar 2010 19:11:39 +0000
    Subject: [PATCH 1540/2592] MFC r204210, r204216: Add Intel PCH SATA controller
     IDs.
    
    ---
     sys/dev/ata/chipsets/ata-intel.c | 16 ++++++++++++++++
     1 file changed, 16 insertions(+)
    
    diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c
    index ec05f30182b..4c15013951e 100644
    --- a/sys/dev/ata/chipsets/ata-intel.c
    +++ b/sys/dev/ata/chipsets/ata-intel.c
    @@ -140,6 +140,22 @@ ata_intel_probe(device_t dev)
          { 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" },
    +     { 0x3a208086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a218086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a228086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a238086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a248086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a258086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a268086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a278086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a288086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a298086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a2a8086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a2b8086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a2c8086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a2d8086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a2e8086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
    +     { 0x3a2f8086,       0, INTEL_AHCI, 0, ATA_SA300, "PCH" },
          { ATA_I31244,       0,          0, 2, ATA_SA150, "31244" },
          { ATA_ISCH,         0,          0, 1, ATA_UDMA5, "SCH" },
          { 0, 0, 0, 0, 0, 0}};
    
    From 3a8904bf97267f9ea7a448f67791204a24f7531f Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Wed, 3 Mar 2010 19:12:53 +0000
    Subject: [PATCH 1541/2592] MFC r204250: Fix recursive lock attempt on hot-plug
     event in non-ATA_CAM mode.
    
    ---
     sys/dev/ata/ata-all.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
    index 0195781cd29..73dfa94fd83 100644
    --- a/sys/dev/ata/ata-all.c
    +++ b/sys/dev/ata/ata-all.c
    @@ -289,15 +289,13 @@ static void
     ata_conn_event(void *context, int dummy)
     {
     	device_t dev = (device_t)context;
    -	struct ata_channel *ch = device_get_softc(dev);
     #ifdef ATA_CAM
    +	struct ata_channel *ch = device_get_softc(dev);
     	union ccb *ccb;
    -#endif
     
     	mtx_lock(&ch->state_mtx);
     	ata_reinit(dev);
     	mtx_unlock(&ch->state_mtx);
    -#ifdef ATA_CAM
     	if ((ccb = xpt_alloc_ccb()) == NULL)
     		return;
     	if (xpt_create_path(&ccb->ccb_h.path, NULL,
    @@ -307,6 +305,8 @@ ata_conn_event(void *context, int dummy)
     		return;
     	}
     	xpt_rescan(ccb);
    +#else
    +	ata_reinit(dev);
     #endif
     }
     
    
    From 576e956f32619f2600b19704804a7388b199825d Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Wed, 3 Mar 2010 19:14:05 +0000
    Subject: [PATCH 1542/2592] MFC r204509: - Add ALI M5228 PATA ID. - Add missed
     DMA initialization for ALI SATA chips.
    
    ---
     sys/dev/ata/ata-pci.h               | 1 +
     sys/dev/ata/chipsets/ata-acerlabs.c | 3 ++-
     2 files changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
    index b9c535c6ec2..1378f879ce0 100644
    --- a/sys/dev/ata/ata-pci.h
    +++ b/sys/dev/ata/ata-pci.h
    @@ -84,6 +84,7 @@ struct ata_pci_controller {
     
     #define ATA_ACER_LABS_ID        0x10b9
     #define ATA_ALI_1533            0x153310b9
    +#define ATA_ALI_5228            0x522810b9
     #define ATA_ALI_5229            0x522910b9
     #define ATA_ALI_5281            0x528110b9
     #define ATA_ALI_5287            0x528710b9
    diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c
    index b5036d77cd4..b7f11472da2 100644
    --- a/sys/dev/ata/chipsets/ata-acerlabs.c
    +++ b/sys/dev/ata/chipsets/ata-acerlabs.c
    @@ -79,6 +79,7 @@ ata_ali_probe(device_t dev)
          { ATA_ALI_5288, 0x00, 4, ALI_SATA, ATA_SA300, "M5288" },
          { ATA_ALI_5287, 0x00, 4, ALI_SATA, ATA_SA150, "M5287" },
          { ATA_ALI_5281, 0x00, 2, ALI_SATA, ATA_SA150, "M5281" },
    +     { ATA_ALI_5228, 0xc5, 0, ALI_NEW,  ATA_UDMA6, "M5228" },
          { ATA_ALI_5229, 0xc5, 0, ALI_NEW,  ATA_UDMA6, "M5229" },
          { ATA_ALI_5229, 0xc4, 0, ALI_NEW,  ATA_UDMA5, "M5229" },
          { ATA_ALI_5229, 0xc2, 0, ALI_NEW,  ATA_UDMA4, "M5229" },
    @@ -208,7 +209,7 @@ ata_ali_sata_ch_attach(device_t dev)
     	    io = res->bars[0];
     	    ctlio = res->bars[1];
         }
    -		
    +    ata_pci_dmainit(dev);
         for (i = ATA_DATA; i <= ATA_COMMAND; i ++) {
     	ch->r_io[i].res = io;
     	ch->r_io[i].offset = i + (unit10 ? 8 : 0);
    
    From fe0da2ff6e6139b14eccb9ee6cae2f0e18128c9b Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Wed, 3 Mar 2010 20:06:50 +0000
    Subject: [PATCH 1543/2592] MFC 204656: 	Add missing ar9285_reset.c file.
    
    ---
     sys/modules/ath/Makefile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/modules/ath/Makefile b/sys/modules/ath/Makefile
    index d6f798fd255..511d3f8c510 100644
    --- a/sys/modules/ath/Makefile
    +++ b/sys/modules/ath/Makefile
    @@ -91,7 +91,7 @@ SRCS+=	ah_eeprom_v14.c \
     SRCS+=	ar9160_attach.c
     # RF backend for 5416 and 9160
     SRCS+=	ar2133.c
    -SRCS+=	ar9285.c ar9285_attach.c
    +SRCS+=	ar9285.c ar9285_reset.c ar9285_attach.c
     
     # NB: rate control is bound to the driver by symbol names so only pick one
     .if ${ATH_RATE} == "sample"
    
    From 8004f2b3536d805449cdc4eba575c7d5aed0c521 Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Wed, 3 Mar 2010 20:08:12 +0000
    Subject: [PATCH 1544/2592] Add ar9280.c and ar9280_attach.c.
    
    ---
     sys/modules/ath/Makefile | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/modules/ath/Makefile b/sys/modules/ath/Makefile
    index 511d3f8c510..c50da588f2e 100644
    --- a/sys/modules/ath/Makefile
    +++ b/sys/modules/ath/Makefile
    @@ -91,6 +91,7 @@ SRCS+=	ah_eeprom_v14.c \
     SRCS+=	ar9160_attach.c
     # RF backend for 5416 and 9160
     SRCS+=	ar2133.c
    +SRCS+=	ar9280.c ar9280_attach.c
     SRCS+=	ar9285.c ar9285_reset.c ar9285_attach.c
     
     # NB: rate control is bound to the driver by symbol names so only pick one
    
    From ae266114fbd693e8f6ee5d0e34446f67bdab3c15 Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Wed, 3 Mar 2010 20:28:35 +0000
    Subject: [PATCH 1545/2592] Add ah_eeprom_v4k.c
    
    ---
     sys/modules/ath/Makefile | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/modules/ath/Makefile b/sys/modules/ath/Makefile
    index c50da588f2e..209ae3c1907 100644
    --- a/sys/modules/ath/Makefile
    +++ b/sys/modules/ath/Makefile
    @@ -83,6 +83,7 @@ SRCS+=	ar5413.c
     #
     .PATH:	${.CURDIR}/../../dev/ath/ath_hal/ar5416
     SRCS+=	ah_eeprom_v14.c \
    +	ah_eeprom_v4k.c \
     	ar5416_ani.c ar5416_attach.c ar5416_beacon.c ar5416_cal.c \
     	ar5416_cal_iq.c ar5416_cal_adcgain.c ar5416_cal_adcdc.c \
     	ar5416_eeprom.c ar5416_gpio.c ar5416_interrupts.c ar5416_keycache.c \
    
    From d4e3872db360df1cf2b9e0d72007e42cf5d6eed7 Mon Sep 17 00:00:00 2001
    From: Brooks Davis 
    Date: Wed, 3 Mar 2010 21:47:25 +0000
    Subject: [PATCH 1546/2592] MFC r201959
    
    Use the correct types to store uids and gids in the credential cache and
    eliminate an inappropriate use of NGROUPS.
    ---
     lib/libc/rpc/svc_auth_des.c | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/lib/libc/rpc/svc_auth_des.c b/lib/libc/rpc/svc_auth_des.c
    index 84f1e19a175..de4d1b4069f 100644
    --- a/lib/libc/rpc/svc_auth_des.c
    +++ b/lib/libc/rpc/svc_auth_des.c
    @@ -449,10 +449,10 @@ cache_spot(key, name, timestamp)
     #define INVALID		-1 	/* grouplen, if cache entry is invalid */
     
     struct bsdcred {
    -	short uid;		/* cached uid */
    -	short gid;		/* cached gid */
    -	short grouplen;	/* length of cached groups */
    -	short groups[NGROUPS];	/* cached groups */
    +	uid_t uid;		/* cached uid */
    +	gid_t gid;		/* cached gid */
    +	int grouplen;	/* length of cached groups */
    +	gid_t groups[NGRPS];	/* cached groups */
     };
     
     /*
    
    From a6179399953633d27195d9d87eb2c8396136a0c5 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Thu, 4 Mar 2010 07:08:01 +0000
    Subject: [PATCH 1547/2592] MFC r204308: Do not restrict the allowed signals
     that can be specified by number to the list of signals that has symbolic
     name. It was impossible to send rt signals with kill(1) due to the check.
    
    ---
     bin/kill/kill.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/bin/kill/kill.c b/bin/kill/kill.c
    index bb9982e33b5..8ee1d85d398 100644
    --- a/bin/kill/kill.c
    +++ b/bin/kill/kill.c
    @@ -108,7 +108,7 @@ main(int argc, char *argv[])
     			numsig = strtol(*argv, &ep, 10);
     			if (!**argv || *ep)
     				errx(1, "illegal signal number: %s", *argv);
    -			if (numsig < 0 || numsig >= sys_nsig)
    +			if (numsig < 0)
     				nosig(*argv);
     		} else
     			nosig(*argv);
    
    From bd94a8bcdc31f341d626dbdd77cf8e9ba8a39af4 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Thu, 4 Mar 2010 07:12:44 +0000
    Subject: [PATCH 1548/2592] MFC r204307: Make pause(3) implementation not
     depended on the legacy sigcompat.c interfaces. Do not block rt signals during
     and after pause(3) calls. Use private libc namespace to call proper methods.
    
    ---
     lib/libc/gen/pause.c | 8 +++++++-
     1 file changed, 7 insertions(+), 1 deletion(-)
    
    diff --git a/lib/libc/gen/pause.c b/lib/libc/gen/pause.c
    index 86d3643435d..cb0fa97f6b9 100644
    --- a/lib/libc/gen/pause.c
    +++ b/lib/libc/gen/pause.c
    @@ -33,8 +33,10 @@ static char sccsid[] = "@(#)pause.c	8.1 (Berkeley) 6/4/93";
     #include 
     __FBSDID("$FreeBSD$");
     
    +#include "namespace.h"
     #include 
     #include 
    +#include "un-namespace.h"
     
     /*
      * Backwards compatible pause.
    @@ -42,7 +44,11 @@ __FBSDID("$FreeBSD$");
     int
     __pause()
     {
    -	return sigpause(sigblock(0L));
    +	sigset_t oset;
    +
    +	if (_sigprocmask(SIG_BLOCK, NULL, &oset) == -1)
    +		return (-1);
    +	return (_sigsuspend(&oset));
     }
     __weak_reference(__pause, pause);
     __weak_reference(__pause, _pause);
    
    From e483194cabdaa62b29c70b150e98a5151db2a9c9 Mon Sep 17 00:00:00 2001
    From: Brooks Davis 
    Date: Thu, 4 Mar 2010 19:35:22 +0000
    Subject: [PATCH 1549/2592] MFC r201853:
    
    Make options KGSSAPI build and add it to NOTES.
    
    rpcsec_gss_prot.c:
      Use kernel printf and headers.
    
    vc_rpcsec_gss.c:
      Use a local RPCAUTH_UNIXGIDS definition for 16 instead of using NGROUPS.
    ---
     sys/conf/NOTES                       |  1 +
     sys/rpc/rpcsec_gss/rpcsec_gss_prot.c | 10 +++++-----
     sys/rpc/rpcsec_gss/svc_rpcsec_gss.c  |  9 ++++++---
     3 files changed, 12 insertions(+), 8 deletions(-)
    
    diff --git a/sys/conf/NOTES b/sys/conf/NOTES
    index 768c23af099..107f581f4d2 100644
    --- a/sys/conf/NOTES
    +++ b/sys/conf/NOTES
    @@ -978,6 +978,7 @@ options 	NFSSERVER		#Network File System server
     options 	NFSLOCKD		#Network Lock Manager
     options 	NFSCL			#experimental NFS client with NFSv4
     options 	NFSD			#experimental NFS server with NFSv4
    +options 	KGSSAPI			#Kernel GSSAPI implementaion
     
     # NT File System. Read-mostly, see mount_ntfs(8) for details.
     # For a full read-write NTFS support consider sysutils/fusefs-ntfs
    diff --git a/sys/rpc/rpcsec_gss/rpcsec_gss_prot.c b/sys/rpc/rpcsec_gss/rpcsec_gss_prot.c
    index 0654a6e6a22..91112a1aa67 100644
    --- a/sys/rpc/rpcsec_gss/rpcsec_gss_prot.c
    +++ b/sys/rpc/rpcsec_gss/rpcsec_gss_prot.c
    @@ -307,7 +307,7 @@ xdr_rpc_gss_unwrap_data(struct mbuf **resultsp,
     }
     
     #ifdef DEBUG
    -#include 
    +#include 
     
     void
     rpc_gss_log_debug(const char *fmt, ...)
    @@ -315,9 +315,9 @@ rpc_gss_log_debug(const char *fmt, ...)
     	va_list ap;
     
     	va_start(ap, fmt);
    -	fprintf(stderr, "rpcsec_gss: ");
    -	vfprintf(stderr, fmt, ap);
    -	fprintf(stderr, "\n");
    +	printf("rpcsec_gss: ");
    +	vprintf(fmt, ap);
    +	printf("\n");
     	va_end(ap);
     }
     
    @@ -328,7 +328,7 @@ rpc_gss_log_status(const char *m, gss_OID mech, OM_uint32 maj_stat, OM_uint32 mi
     	gss_buffer_desc msg;
     	int msg_ctx = 0;
     
    -	fprintf(stderr, "rpcsec_gss: %s: ", m);
    +	printf("rpcsec_gss: %s: ", m);
     	
     	gss_display_status(&min, maj_stat, GSS_C_GSS_CODE, GSS_C_NULL_OID,
     			   &msg_ctx, &msg);
    diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
    index 55c0a8309ed..7433b79d2bb 100644
    --- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
    +++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
    @@ -121,6 +121,9 @@ enum svc_rpc_gss_client_state {
     };
     
     #define SVC_RPC_GSS_SEQWINDOW	128
    +#ifndef RPCAUTH_UNIXGIDS
    +#define RPCAUTH_UNIXGIDS	16
    +#endif
     
     struct svc_rpc_gss_clientid {
     	unsigned long		ci_hostid;
    @@ -147,7 +150,7 @@ struct svc_rpc_gss_client {
     	int			cl_rpcflavor;	/* RPC pseudo sec flavor */
     	bool_t			cl_done_callback; /* TRUE after call */
     	void			*cl_cookie;	/* user cookie from callback */
    -	gid_t			cl_gid_storage[NGROUPS];
    +	gid_t			cl_gid_storage[RPCAUTH_UNIXGIDS];
     	gss_OID			cl_mech;	/* mechanism */
     	gss_qop_t		cl_qop;		/* quality of protection */
     	uint32_t		cl_seqlast;	/* sequence window origin */
    @@ -735,7 +738,7 @@ svc_rpc_gss_build_ucred(struct svc_rpc_gss_client *client,
     	uc->gid = 65534;
     	uc->gidlist = client->cl_gid_storage;
     
    -	numgroups = NGROUPS;
    +	numgroups = RPCAUTH_UNIXGIDS;
     	maj_stat = gss_pname_to_unix_cred(&min_stat, name, client->cl_mech,
     	    &uc->uid, &uc->gid, &numgroups, &uc->gidlist[0]);
     	if (GSS_ERROR(maj_stat))
    @@ -932,7 +935,7 @@ svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client,
     			    "",
     			    client->cl_rawcred.client_principal->name,
     			    mechname.length, (char *)mechname.value,
    -			    client->cl_qop, client->rawcred.service);
    +			    client->cl_qop, client->cl_rawcred.service);
     
     			gss_release_buffer(&min_stat, &mechname);
     		}
    
    From bdf0c295b93964510ff64fc8df12ab581b2a28a4 Mon Sep 17 00:00:00 2001
    From: Rafal Jaworowski 
    Date: Thu, 4 Mar 2010 20:03:26 +0000
    Subject: [PATCH 1550/2592] MFC r204315
    
    Enable U-Boot storage for PowerPC. While there fix loader(8) help file name.
    ---
     sys/boot/powerpc/uboot/Makefile | 8 ++++----
     sys/boot/powerpc/uboot/conf.c   | 2 +-
     2 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/sys/boot/powerpc/uboot/Makefile b/sys/boot/powerpc/uboot/Makefile
    index efb401e9cef..62a286831ce 100644
    --- a/sys/boot/powerpc/uboot/Makefile
    +++ b/sys/boot/powerpc/uboot/Makefile
    @@ -9,8 +9,8 @@ NO_MAN=
     # Architecture-specific loader code
     SRCS=		start.S conf.c vers.c
     
    -LOADER_DISK_SUPPORT?=	no
    -LOADER_UFS_SUPPORT?=	no
    +LOADER_DISK_SUPPORT?=	yes
    +LOADER_UFS_SUPPORT?=	yes
     LOADER_CD9660_SUPPORT?=	no
     LOADER_EXT2FS_SUPPORT?=	no
     LOADER_NET_SUPPORT?=	yes
    @@ -85,11 +85,11 @@ LDADD=		${LIBFICL} ${LIBUBOOT} -lstand
     vers.c:	${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
     	sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
     
    -${PROG}.help: help.common help.uboot
    +loader.help: help.common help.uboot
     	cat ${.ALLSRC} | \
     	    awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
     
     .PATH: ${.CURDIR}/../../forth
    -FILES=	${PROG}.help
    +FILES=	loader.help
     
     .include 
    diff --git a/sys/boot/powerpc/uboot/conf.c b/sys/boot/powerpc/uboot/conf.c
    index 5a9515a452d..35305371ce6 100644
    --- a/sys/boot/powerpc/uboot/conf.c
    +++ b/sys/boot/powerpc/uboot/conf.c
    @@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$");
     /* Exported for libstand */
     struct devsw *devsw[] = {
     #if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT)
    -    &uboot_disk,
    +    &uboot_storage,
     #endif
     #if defined(LOADER_NET_SUPPORT)
         &netdev,
    
    From 17b7e3fbec8efb9aa1e15b47869934786fa86482 Mon Sep 17 00:00:00 2001
    From: Rafal Jaworowski 
    Date: Thu, 4 Mar 2010 20:07:59 +0000
    Subject: [PATCH 1551/2592] MFC r204316
    
    Let loader(8) for U-Boot use default storage more flexibly.
    
    Obtained from:	Semihalf
    ---
     sys/boot/uboot/common/main.c | 25 ++++++++++++++++++-------
     1 file changed, 18 insertions(+), 7 deletions(-)
    
    diff --git a/sys/boot/uboot/common/main.c b/sys/boot/uboot/common/main.c
    index 1ebb09750f6..7d068ee9617 100644
    --- a/sys/boot/uboot/common/main.c
    +++ b/sys/boot/uboot/common/main.c
    @@ -117,6 +117,7 @@ main(void)
     {
     	struct api_signature *sig = NULL;
     	int i;
    +	struct open_file f;
     
     	if (!api_search_sig(&sig))
     		return (-1);
    @@ -168,18 +169,28 @@ main(void)
     	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
     	meminfo();
     
    -	/* XXX only support netbooting for now */
    -	for (i = 0; devsw[i] != NULL; i++)
    +	for (i = 0; devsw[i] != NULL; i++) {
    +		printf("\nDevice %d: %s\n", i, devsw[i]->dv_name);
    +
    +		currdev.d_dev = devsw[i];
    +		currdev.d_type = currdev.d_dev->dv_type;
    +		currdev.d_unit = 0;
    +
    +		if (strncmp(devsw[i]->dv_name, "disk",
    +		    strlen(devsw[i]->dv_name)) == 0) {
    +			f.f_devdata = &currdev;
    +			currdev.d_disk.pnum = 0;
    +			if (devsw[i]->dv_open(&f,&currdev) == 0)
    +				break;
    +		}
    +
     		if (strncmp(devsw[i]->dv_name, "net",
     		    strlen(devsw[i]->dv_name)) == 0)
     			break;
    +	}
     
     	if (devsw[i] == NULL)
    -		panic("no network devices?!");
    -
    -	currdev.d_dev = devsw[i];
    -	currdev.d_type = currdev.d_dev->dv_type;
    -	currdev.d_unit = 0;
    +		panic("No boot device found!");
     
     	env_setenv("currdev", EV_VOLATILE, uboot_fmtdev(&currdev),
     	    uboot_setcurrdev, env_nounset);
    
    From c1e213930348ef4ec466fba5d10ef7d5561e9223 Mon Sep 17 00:00:00 2001
    From: Rafal Jaworowski 
    Date: Thu, 4 Mar 2010 20:12:12 +0000
    Subject: [PATCH 1552/2592] MFC r204317
    
    Fix handling of GPT disk partition index.
    
    Obtained from:	Semihalf
    ---
     sys/boot/uboot/lib/disk.c | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/sys/boot/uboot/lib/disk.c b/sys/boot/uboot/lib/disk.c
    index 4cbdbea445f..3af4c795694 100644
    --- a/sys/boot/uboot/lib/disk.c
    +++ b/sys/boot/uboot/lib/disk.c
    @@ -376,6 +376,14 @@ stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev)
     	}
     
     	dev->d_disk.ptype = PTYPE_GPT;
    +	/*
    +	 * If index of partition to open (dev->d_disk.pnum) is not defined
    +	 * we set it to the index of the first existing partition. This
    +	 * handles cases when only a disk device is specified (without full
    +	 * partition information) by the caller.
    +	 */
    +	if ((od->od_nparts > 0) && (dev->d_disk.pnum == 0))
    +		dev->d_disk.pnum = od->od_partitions[0].gp_index;
     
     	for (i = 0; i < od->od_nparts; i++)
     		if (od->od_partitions[i].gp_index == dev->d_disk.pnum)
    
    From 0500dff0e4d7a16a85c7ad05ec321a9c41b4fb30 Mon Sep 17 00:00:00 2001
    From: Rafal Jaworowski 
    Date: Thu, 4 Mar 2010 20:22:48 +0000
    Subject: [PATCH 1553/2592] MFC r204283
    
    Do not force verbose and single mode in non-metadata boot case.
    
    We want to go multi-user by default also in case of booting without
    loader(8).
    ---
     sys/arm/mv/mv_machdep.c | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c
    index 2dc20ceb08e..e2d8bfc8636 100644
    --- a/sys/arm/mv/mv_machdep.c
    +++ b/sys/arm/mv/mv_machdep.c
    @@ -407,8 +407,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;
    +		/* Fall back to hardcoded metadata. */
     		lastaddr = fake_preload_metadata();
     
     		/*
    
    From 6e064db94e7da47d12149ee275ebe2a1ad43f405 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Fri, 5 Mar 2010 00:31:03 +0000
    Subject: [PATCH 1554/2592] MFC r203459:
    
    Plug two memory leaks in error case.
    ---
     sbin/dump/itime.c | 4 +++-
     sbin/dump/main.c  | 3 ++-
     2 files changed, 5 insertions(+), 2 deletions(-)
    
    diff --git a/sbin/dump/itime.c b/sbin/dump/itime.c
    index 1f1a3e58711..4cac87b41a1 100644
    --- a/sbin/dump/itime.c
    +++ b/sbin/dump/itime.c
    @@ -106,8 +106,10 @@ readdumptimes(FILE *df)
     
     	for (;;) {
     		dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime));
    -		if (getrecord(df, &(dtwalk->dt_value)) < 0)
    +		if (getrecord(df, &(dtwalk->dt_value)) < 0) {
    +			free(dtwalk);
     			break;
    +		}
     		nddates++;
     		SLIST_INSERT_HEAD(&dthead, dtwalk, dt_list);
     	}
    diff --git a/sbin/dump/main.c b/sbin/dump/main.c
    index 7a99522783f..e344887de14 100644
    --- a/sbin/dump/main.c
    +++ b/sbin/dump/main.c
    @@ -767,7 +767,8 @@ obsolete(int *argcp, char **argvp[])
     	if (flags) {
     		*p = '\0';
     		*nargv++ = flagsp;
    -	}
    +	} else
    +		free(flagsp);
     
     	/* Copy remaining arguments. */
     	while ((*nargv++ = *argv++));
    
    From 949a9c3cf16ac6a6f2d4ecee13df508dac7c208b Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Fri, 5 Mar 2010 00:32:22 +0000
    Subject: [PATCH 1555/2592] MFC r203460:
    
    pukeText is an internal function so define it as static rather than
    exporting it.
    ---
     sbin/iscontrol/iscontrol.h | 1 -
     sbin/iscontrol/pdu.c       | 4 +++-
     2 files changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/sbin/iscontrol/iscontrol.h b/sbin/iscontrol/iscontrol.h
    index a89d7afd5f3..5ab296d0a5c 100644
    --- a/sbin/iscontrol/iscontrol.h
    +++ b/sbin/iscontrol/iscontrol.h
    @@ -144,7 +144,6 @@ int	addText(pdu_t *pp, char *fmt, ...);
     void	freePDU(pdu_t *pp);
     int	xmitpdu(isess_t *sess, pdu_t *pp);
     int	recvpdu(isess_t *sess, pdu_t *pp);
    -void	pukeText(char *it, pdu_t *pp);
     
     int	lookup(token_t *tbl, char *m);
     
    diff --git a/sbin/iscontrol/pdu.c b/sbin/iscontrol/pdu.c
    index 980d20a4104..444c1f11ab2 100644
    --- a/sbin/iscontrol/pdu.c
    +++ b/sbin/iscontrol/pdu.c
    @@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
     #include "iscsi.h"
     #include "iscontrol.h"
     
    +static void	pukeText(char *it, pdu_t *pp);
    +
     int
     xmitpdu(isess_t *sess, pdu_t *pp)
     {
    @@ -153,7 +155,7 @@ freePDU(pdu_t *pp)
          pp->ds_size = pp->ds_len = 0;
     }
     
    -void
    +static void
     pukeText(char *it, pdu_t *pp)
     {
          char	*ptr;
    
    From 3905c549f01a0716b97e81412700aaf3b0f69eb0 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Fri, 5 Mar 2010 00:33:05 +0000
    Subject: [PATCH 1556/2592] MFC r203461:
    
    static'ify function prototypes and convert K&R to ANSI.
    ---
     sbin/mount_nfs/mount_nfs.c | 47 +++++++++++++++++++-------------------
     1 file changed, 23 insertions(+), 24 deletions(-)
    
    diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c
    index 5f6d2887e02..5e722a00936 100644
    --- a/sbin/mount_nfs/mount_nfs.c
    +++ b/sbin/mount_nfs/mount_nfs.c
    @@ -130,20 +130,19 @@ enum tryret {
     	TRYRET_LOCALERR		/* Local failure. */
     };
     
    -int	fallback_mount(struct iovec *iov, int iovlen, int mntflags);
    -int	sec_name_to_num(char *sec);
    -char	*sec_num_to_name(int num);
    -int	getnfsargs(char *, struct iovec **iov, int *iovlen);
    +static int	fallback_mount(struct iovec *iov, int iovlen, int mntflags);
    +static int	sec_name_to_num(char *sec);
    +static char	*sec_num_to_name(int num);
    +static int	getnfsargs(char *, struct iovec **iov, int *iovlen);
     /* void	set_rpc_maxgrouplist(int); */
    -struct netconfig *getnetconf_cached(const char *netid);
    -const char	*netidbytype(int af, int sotype);
    -void	usage(void) __dead2;
    -int	xdr_dir(XDR *, char *);
    -int	xdr_fh(XDR *, struct nfhret *);
    -enum tryret nfs_tryproto(struct addrinfo *ai, char *hostp, char *spec,
    +static struct netconfig *getnetconf_cached(const char *netid);
    +static const char	*netidbytype(int af, int sotype);
    +static void	usage(void) __dead2;
    +static int	xdr_dir(XDR *, char *);
    +static int	xdr_fh(XDR *, struct nfhret *);
    +static enum tryret nfs_tryproto(struct addrinfo *ai, char *hostp, char *spec,
         char **errstr, struct iovec **iov, int *iovlen);
    -enum tryret returncode(enum clnt_stat stat, struct rpc_err *rpcerr);
    -extern int getosreldate(void);
    +static enum tryret returncode(enum clnt_stat stat, struct rpc_err *rpcerr);
     
     int
     main(int argc, char *argv[])
    @@ -476,7 +475,7 @@ copyopt(struct iovec **newiov, int *newiovlen,
      *      passing NFS mount options to nmount() as individual
      *      parameters.  It should be eventually be removed.
      */
    -int
    +static int
     fallback_mount(struct iovec *iov, int iovlen, int mntflags)
     {
     	struct nfs_args args = {
    @@ -663,7 +662,7 @@ fallback_mount(struct iovec *iov, int iovlen, int mntflags)
     	return nmount(newiov, newiovlen, mntflags);
     }
     
    -int
    +static int
     sec_name_to_num(char *sec)
     {
     	if (!strcmp(sec, "krb5"))
    @@ -677,7 +676,7 @@ sec_name_to_num(char *sec)
     	return (-1);
     }
     
    -char *
    +static char *
     sec_num_to_name(int flavor)
     {
     	switch (flavor) {
    @@ -693,7 +692,7 @@ sec_num_to_name(int flavor)
     	return (NULL);
     }
     
    -int
    +static int
     getnfsargs(char *spec, struct iovec **iov, int *iovlen)
     {
     	struct addrinfo hints, *ai_nfs, *ai;
    @@ -849,7 +848,7 @@ getnfsargs(char *spec, struct iovec **iov, int *iovlen)
      * In all error cases, *errstr will be set to a statically-allocated string
      * describing the error.
      */
    -enum tryret
    +static enum tryret
     nfs_tryproto(struct addrinfo *ai, char *hostp, char *spec, char **errstr,
         struct iovec **iov, int *iovlen)
     {
    @@ -1071,7 +1070,7 @@ tryagain:
      * Catagorise a RPC return status and error into an `enum tryret'
      * return code.
      */
    -enum tryret
    +static enum tryret
     returncode(enum clnt_stat stat, struct rpc_err *rpcerr)
     {
     	switch (stat) {
    @@ -1106,7 +1105,7 @@ returncode(enum clnt_stat stat, struct rpc_err *rpcerr)
      *
      * XXX there should be a library function for this.
      */
    -const char *
    +static const char *
     netidbytype(int af, int sotype)
     {
     	struct nc_protos *p;
    @@ -1126,7 +1125,7 @@ netidbytype(int af, int sotype)
      * Otherwise it behaves just like getnetconfigent(), so nc_*error()
      * work on failure.
      */
    -struct netconfig *
    +static struct netconfig *
     getnetconf_cached(const char *netid)
     {
     	static struct nc_entry {
    @@ -1154,13 +1153,13 @@ getnetconf_cached(const char *netid)
     /*
      * xdr routines for mount rpc's
      */
    -int
    +static int
     xdr_dir(XDR *xdrsp, char *dirp)
     {
     	return (xdr_string(xdrsp, &dirp, MNTPATHLEN));
     }
     
    -int
    +static int
     xdr_fh(XDR *xdrsp, struct nfhret *np)
     {
     	int i;
    @@ -1206,8 +1205,8 @@ xdr_fh(XDR *xdrsp, struct nfhret *np)
     	return (0);
     }
     
    -void
    -usage()
    +static void
    +usage(void)
     {
     	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
     "usage: mount_nfs [-23bcdiLlNPsTU] [-a maxreadahead] [-D deadthresh]",
    
    From 2553c385552395c56638f4836e6ddb5b4770ee51 Mon Sep 17 00:00:00 2001
    From: Fabien Thomas 
    Date: Fri, 5 Mar 2010 22:40:31 +0000
    Subject: [PATCH 1557/2592] MFC 203790: - Reorganize code in 'plugin' to share
     log processing. - Kcachegrind (calltree) support with assembly/source   code
     mapping and call count estimator (-F). - Top mode for calltree and callgraph
     plugin (-T).
    
    ---
     usr.sbin/pmcstat/Makefile          |    5 +-
     usr.sbin/pmcstat/pmcpl_annotate.c  |  111 ++
     usr.sbin/pmcstat/pmcpl_annotate.h  |   41 +
     usr.sbin/pmcstat/pmcpl_callgraph.c |  682 +++++++++++
     usr.sbin/pmcstat/pmcpl_callgraph.h |   67 ++
     usr.sbin/pmcstat/pmcpl_calltree.c  | 1000 ++++++++++++++++
     usr.sbin/pmcstat/pmcpl_calltree.h  |   42 +
     usr.sbin/pmcstat/pmcpl_gprof.c     |  533 +++++++++
     usr.sbin/pmcstat/pmcpl_gprof.h     |   47 +
     usr.sbin/pmcstat/pmcstat.8         |   28 +-
     usr.sbin/pmcstat/pmcstat.c         |  286 +++--
     usr.sbin/pmcstat/pmcstat.h         |   75 +-
     usr.sbin/pmcstat/pmcstat_log.c     | 1712 ++++++++++------------------
     usr.sbin/pmcstat/pmcstat_log.h     |  196 ++++
     usr.sbin/pmcstat/pmcstat_top.h     |   75 ++
     15 files changed, 3675 insertions(+), 1225 deletions(-)
     create mode 100644 usr.sbin/pmcstat/pmcpl_annotate.c
     create mode 100644 usr.sbin/pmcstat/pmcpl_annotate.h
     create mode 100644 usr.sbin/pmcstat/pmcpl_callgraph.c
     create mode 100644 usr.sbin/pmcstat/pmcpl_callgraph.h
     create mode 100644 usr.sbin/pmcstat/pmcpl_calltree.c
     create mode 100644 usr.sbin/pmcstat/pmcpl_calltree.h
     create mode 100644 usr.sbin/pmcstat/pmcpl_gprof.c
     create mode 100644 usr.sbin/pmcstat/pmcpl_gprof.h
     create mode 100644 usr.sbin/pmcstat/pmcstat_log.h
     create mode 100644 usr.sbin/pmcstat/pmcstat_top.h
    
    diff --git a/usr.sbin/pmcstat/Makefile b/usr.sbin/pmcstat/Makefile
    index 6b11d8d945a..4412e24d9ca 100644
    --- a/usr.sbin/pmcstat/Makefile
    +++ b/usr.sbin/pmcstat/Makefile
    @@ -6,10 +6,11 @@ PROG=	pmcstat
     MAN=	pmcstat.8
     
     DPADD=	${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM}
    -LDADD=	-lelf -lkvm -lpmc -lm
    +LDADD=	-lelf -lkvm -lpmc -lm -lncurses
     
     WARNS?=	6
     
    -SRCS=	pmcstat.c pmcstat.h pmcstat_log.c
    +SRCS=	pmcstat.c pmcstat.h pmcstat_log.c \
    +pmcpl_callgraph.c pmcpl_gprof.c pmcpl_annotate.c pmcpl_calltree.c
     
     .include 
    diff --git a/usr.sbin/pmcstat/pmcpl_annotate.c b/usr.sbin/pmcstat/pmcpl_annotate.c
    new file mode 100644
    index 00000000000..802983cd9bd
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcpl_annotate.c
    @@ -0,0 +1,111 @@
    +/*-
    + * Copyright (c) 2005-2007, Joseph Koshy
    + * Copyright (c) 2007 The FreeBSD Foundation
    + * All rights reserved.
    + *
    + * Portions of this software were developed by A. Joseph Koshy under
    + * sponsorship from the FreeBSD Foundation and 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.
    + */
    +
    +/*
    + * Transform a hwpmc(4) log into human readable form, and into
    + * gprof(1) compatible profiles.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include "pmcstat.h"
    +#include "pmcstat_log.h"
    +#include "pmcpl_annotate.h"
    +
    +/*
    + * Record a callchain.
    + */
    +
    +void
    +pmcpl_annotate_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
    +    uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
    +{
    +	struct pmcstat_pcmap *map;
    +	struct pmcstat_symbol *sym;
    +	uintfptr_t newpc;
    +	struct pmcstat_image *image;
    +
    +	(void) pmcr; (void) nsamples; (void) usermode; (void) cpu;
    +
    +	map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[0]);
    +	if (map == NULL) {
    +		/* Unknown offset. */
    +		pmcstat_stats.ps_samples_unknown_offset++;
    +		return;
    +	}
    +
    +	assert(cc[0] >= map->ppm_lowpc && cc[0] < map->ppm_highpc);
    +
    +	image = map->ppm_image;
    +	newpc = cc[0] - (map->ppm_lowpc +
    +		(image->pi_vaddr - image->pi_start));
    +	sym = pmcstat_symbol_search(image, newpc);
    +	if (sym == NULL)
    +		return;
    +
    +	fprintf(args.pa_graphfile, "%p %s 0x%jx 0x%jx\n",
    +		(void *)cc[0],
    +		pmcstat_string_unintern(sym->ps_name),
    +		(uintmax_t)(sym->ps_start +
    +		image->pi_vaddr), (uintmax_t)(sym->ps_end +
    +		image->pi_vaddr));
    +}
    diff --git a/usr.sbin/pmcstat/pmcpl_annotate.h b/usr.sbin/pmcstat/pmcpl_annotate.h
    new file mode 100644
    index 00000000000..482bcd41e8d
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcpl_annotate.h
    @@ -0,0 +1,41 @@
    +/*-
    + * Copyright (c) 2005-2007, Joseph Koshy
    + * Copyright (c) 2007 The FreeBSD Foundation
    + * All rights reserved.
    + *
    + * Portions of this software were developed by A. Joseph Koshy under
    + * sponsorship from the FreeBSD Foundation and 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.
    + *
    + * $FreeBSD$
    + */
    +
    +#ifndef	_PMCSTAT_PL_ANNOTATE_H_
    +#define	_PMCSTAT_PL_ANNOTATE_H_
    +
    +/* Function prototypes */
    +void pmcpl_annotate_process(
    +    struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
    +    uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
    +
    +#endif	/* _PMCSTAT_PL_ANNOTATE_H_ */
    diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.c b/usr.sbin/pmcstat/pmcpl_callgraph.c
    new file mode 100644
    index 00000000000..d6f1a9d2697
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcpl_callgraph.c
    @@ -0,0 +1,682 @@
    +/*-
    + * Copyright (c) 2005-2007, Joseph Koshy
    + * Copyright (c) 2007 The FreeBSD Foundation
    + * All rights reserved.
    + *
    + * Portions of this software were developed by A. Joseph Koshy under
    + * sponsorship from the FreeBSD Foundation and 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.
    + */
    +
    +/*
    + * Transform a hwpmc(4) log into human readable form, and into
    + * gprof(1) compatible profiles.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include "pmcstat.h"
    +#include "pmcstat_log.h"
    +#include "pmcstat_top.h"
    +#include "pmcpl_callgraph.h"
    +
    +/* Get the sample value in percent related to nsamples. */
    +#define PMCPL_CG_COUNTP(a) \
    +	((a)->pcg_count * 100.0 / nsamples)
    +
    +/*
    + * The toplevel CG nodes (i.e., with rank == 0) are placed in a hash table.
    + */
    +
    +struct pmcstat_cgnode_hash_list pmcstat_cgnode_hash[PMCSTAT_NHASH];
    +int pmcstat_cgnode_hash_count;
    +
    +static pmcstat_interned_string pmcstat_previous_filename_printed;
    +
    +static struct pmcstat_cgnode *
    +pmcstat_cgnode_allocate(struct pmcstat_image *image, uintfptr_t pc)
    +{
    +	struct pmcstat_cgnode *cg;
    +
    +	if ((cg = malloc(sizeof(*cg))) == NULL)
    +		err(EX_OSERR, "ERROR: Cannot allocate callgraph node");
    +
    +	cg->pcg_image = image;
    +	cg->pcg_func = pc;
    +
    +	cg->pcg_count = 0;
    +	cg->pcg_nchildren = 0;
    +	LIST_INIT(&cg->pcg_children);
    +
    +	return (cg);
    +}
    +
    +/*
    + * Free a node and its children.
    + */
    +static void
    +pmcstat_cgnode_free(struct pmcstat_cgnode *cg)
    +{
    +	struct pmcstat_cgnode *cgc, *cgtmp;
    +
    +	LIST_FOREACH_SAFE(cgc, &cg->pcg_children, pcg_sibling, cgtmp)
    +		pmcstat_cgnode_free(cgc);
    +	free(cg);
    +}
    +
    +/*
    + * Look for a callgraph node associated with pmc `pmcid' in the global
    + * hash table that corresponds to the given `pc' value in the process
    + * `pp'.
    + */
    +static struct pmcstat_cgnode *
    +pmcstat_cgnode_hash_lookup_pc(struct pmcstat_process *pp, pmc_id_t pmcid,
    +    uintfptr_t pc, int usermode)
    +{
    +	struct pmcstat_pcmap *ppm;
    +	struct pmcstat_symbol *sym;
    +	struct pmcstat_image *image;
    +	struct pmcstat_cgnode *cg;
    +	struct pmcstat_cgnode_hash *h;
    +	uintfptr_t loadaddress;
    +	unsigned int i, hash;
    +
    +	ppm = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, pc);
    +	if (ppm == NULL)
    +		return (NULL);
    +
    +	image = ppm->ppm_image;
    +
    +	loadaddress = ppm->ppm_lowpc + image->pi_vaddr - image->pi_start;
    +	pc -= loadaddress;	/* Convert to an offset in the image. */
    +
    +	/*
    +	 * Try determine the function at this offset.  If we can't
    +	 * find a function round leave the `pc' value alone.
    +	 */
    +	if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
    +		pc = sym->ps_start;
    +
    +	for (hash = i = 0; i < sizeof(uintfptr_t); i++)
    +		hash += (pc >> i) & 0xFF;
    +
    +	hash &= PMCSTAT_HASH_MASK;
    +
    +	cg = NULL;
    +	LIST_FOREACH(h, &pmcstat_cgnode_hash[hash], pch_next)
    +	{
    +		if (h->pch_pmcid != pmcid)
    +			continue;
    +
    +		cg = h->pch_cgnode;
    +
    +		assert(cg != NULL);
    +
    +		if (cg->pcg_image == image && cg->pcg_func == pc)
    +			return (cg);
    +	}
    +
    +	/*
    +	 * We haven't seen this (pmcid, pc) tuple yet, so allocate a
    +	 * new callgraph node and a new hash table entry for it.
    +	 */
    +	cg = pmcstat_cgnode_allocate(image, pc);
    +	if ((h = malloc(sizeof(*h))) == NULL)
    +		err(EX_OSERR, "ERROR: Could not allocate callgraph node");
    +
    +	h->pch_pmcid = pmcid;
    +	h->pch_cgnode = cg;
    +	LIST_INSERT_HEAD(&pmcstat_cgnode_hash[hash], h, pch_next);
    +
    +	pmcstat_cgnode_hash_count++;
    +
    +	return (cg);
    +}
    +
    +/*
    + * Compare two callgraph nodes for sorting.
    + */
    +static int
    +pmcstat_cgnode_compare(const void *a, const void *b)
    +{
    +	const struct pmcstat_cgnode *const *pcg1, *const *pcg2, *cg1, *cg2;
    +
    +	pcg1 = (const struct pmcstat_cgnode *const *) a;
    +	cg1 = *pcg1;
    +	pcg2 = (const struct pmcstat_cgnode *const *) b;
    +	cg2 = *pcg2;
    +
    +	/* Sort in reverse order */
    +	if (cg1->pcg_count < cg2->pcg_count)
    +		return (1);
    +	if (cg1->pcg_count > cg2->pcg_count)
    +		return (-1);
    +	return (0);
    +}
    +
    +/*
    + * Find (allocating if a needed) a callgraph node in the given
    + * parent with the same (image, pcoffset) pair.
    + */
    +
    +static struct pmcstat_cgnode *
    +pmcstat_cgnode_find(struct pmcstat_cgnode *parent, struct pmcstat_image *image,
    +    uintfptr_t pcoffset)
    +{
    +	struct pmcstat_cgnode *child;
    +
    +	LIST_FOREACH(child, &parent->pcg_children, pcg_sibling) {
    +		if (child->pcg_image == image &&
    +		    child->pcg_func == pcoffset)
    +			return (child);
    +	}
    +
    +	/*
    +	 * Allocate a new structure.
    +	 */
    +
    +	child = pmcstat_cgnode_allocate(image, pcoffset);
    +
    +	/*
    +	 * Link it into the parent.
    +	 */
    +	LIST_INSERT_HEAD(&parent->pcg_children, child, pcg_sibling);
    +	parent->pcg_nchildren++;
    +
    +	return (child);
    +}
    +
    +/*
    + * Print one callgraph node.  The output format is:
    + *
    + * indentation %(parent's samples) #nsamples function@object
    + */
    +static void
    +pmcstat_cgnode_print(struct pmcstat_cgnode *cg, int depth, uint32_t total)
    +{
    +	uint32_t n;
    +	const char *space;
    +	struct pmcstat_symbol *sym;
    +	struct pmcstat_cgnode **sortbuffer, **cgn, *pcg;
    +
    +	space = " ";
    +
    +	if (depth > 0)
    +		(void) fprintf(args.pa_graphfile, "%*s", depth, space);
    +
    +	if (cg->pcg_count == total)
    +		(void) fprintf(args.pa_graphfile, "100.0%% ");
    +	else
    +		(void) fprintf(args.pa_graphfile, "%05.2f%% ",
    +		    100.0 * cg->pcg_count / total);
    +
    +	n = fprintf(args.pa_graphfile, " [%u] ", cg->pcg_count);
    +
    +	/* #samples is a 12 character wide field. */
    +	if (n < 12)
    +		(void) fprintf(args.pa_graphfile, "%*s", 12 - n, space);
    +
    +	if (depth > 0)
    +		(void) fprintf(args.pa_graphfile, "%*s", depth, space);
    +
    +	sym = pmcstat_symbol_search(cg->pcg_image, cg->pcg_func);
    +	if (sym)
    +		(void) fprintf(args.pa_graphfile, "%s",
    +		    pmcstat_string_unintern(sym->ps_name));
    +	else
    +		(void) fprintf(args.pa_graphfile, "%p",
    +		    (void *) (cg->pcg_image->pi_vaddr + cg->pcg_func));
    +
    +	if (pmcstat_previous_filename_printed !=
    +	    cg->pcg_image->pi_fullpath) {
    +		pmcstat_previous_filename_printed = cg->pcg_image->pi_fullpath;
    +		(void) fprintf(args.pa_graphfile, " @ %s\n",
    +		    pmcstat_string_unintern(
    +		    pmcstat_previous_filename_printed));
    +	} else
    +		(void) fprintf(args.pa_graphfile, "\n");
    +
    +	if (cg->pcg_nchildren == 0)
    +		return;
    +
    +	if ((sortbuffer = (struct pmcstat_cgnode **)
    +		malloc(sizeof(struct pmcstat_cgnode *) *
    +		    cg->pcg_nchildren)) == NULL)
    +		err(EX_OSERR, "ERROR: Cannot print callgraph");
    +	cgn = sortbuffer;
    +
    +	LIST_FOREACH(pcg, &cg->pcg_children, pcg_sibling)
    +	    *cgn++ = pcg;
    +
    +	assert(cgn - sortbuffer == (int) cg->pcg_nchildren);
    +
    +	qsort(sortbuffer, cg->pcg_nchildren, sizeof(struct pmcstat_cgnode *),
    +	    pmcstat_cgnode_compare);
    +
    +	for (cgn = sortbuffer, n = 0; n < cg->pcg_nchildren; n++, cgn++)
    +		pmcstat_cgnode_print(*cgn, depth+1, cg->pcg_count);
    +
    +	free(sortbuffer);
    +}
    +
    +/*
    + * Record a callchain.
    + */
    +
    +void
    +pmcpl_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
    +    uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
    +{
    +	uintfptr_t pc, loadaddress;
    +	uint32_t n;
    +	struct pmcstat_image *image;
    +	struct pmcstat_pcmap *ppm;
    +	struct pmcstat_symbol *sym;
    +	struct pmcstat_cgnode *parent, *child;
    +	struct pmcstat_process *km;
    +	pmc_id_t pmcid;
    +
    +	(void) cpu;
    +
    +	/*
    +	 * Find the callgraph node recorded in the global hash table
    +	 * for this (pmcid, pc).
    +	 */
    +
    +	pc = cc[0];
    +	pmcid = pmcr->pr_pmcid;
    +	parent = pmcstat_cgnode_hash_lookup_pc(pp, pmcid, pc, usermode);
    +	if (parent == NULL) {
    +		pmcstat_stats.ps_callchain_dubious_frames++;
    +		return;
    +	}
    +
    +	parent->pcg_count++;
    +
    +	/*
    +	 * For each return address in the call chain record, subject
    +	 * to the maximum depth desired.
    +	 * - Find the image associated with the sample.  Stop if there
    +	 *   there is no valid image at that address.
    +	 * - Find the function that overlaps the return address.
    +	 * - If found: use the start address of the function.
    +	 *   If not found (say an object's symbol table is not present or
    +	 *   is incomplete), round down to th gprof bucket granularity.
    +	 * - Convert return virtual address to an offset in the image.
    +	 * - Look for a child with the same {offset,image} tuple,
    +	 *   inserting one if needed.
    +	 * - Increment the count of occurrences of the child.
    +	 */
    +	km = pmcstat_kernproc;
    +
    +	for (n = 1; n < (uint32_t) args.pa_graphdepth && n < nsamples; n++,
    +	    parent = child) {
    +		pc = cc[n];
    +
    +		ppm = pmcstat_process_find_map(usermode ? pp : km, pc);
    +		if (ppm == NULL) {
    +			/* Detect full frame capture (kernel + user). */
    +			if (!usermode) {
    +				ppm = pmcstat_process_find_map(pp, pc);
    +				if (ppm != NULL)
    +					km = pp;
    +			}
    +		}
    +		if (ppm == NULL)
    +			return;
    +
    +		image = ppm->ppm_image;
    +		loadaddress = ppm->ppm_lowpc + image->pi_vaddr -
    +		    image->pi_start;
    +		pc -= loadaddress;
    +
    +		if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
    +			pc = sym->ps_start;
    +
    +		child = pmcstat_cgnode_find(parent, image, pc);
    +		child->pcg_count++;
    +	}
    +}
    +
    +/*
    + * Printing a callgraph for a PMC.
    + */
    +static void
    +pmcstat_callgraph_print_for_pmcid(struct pmcstat_pmcrecord *pmcr)
    +{
    +	int n, nentries;
    +	uint32_t nsamples;
    +	pmc_id_t pmcid;
    +	struct pmcstat_cgnode **sortbuffer, **cgn;
    +	struct pmcstat_cgnode_hash *pch;
    +
    +	/*
    +	 * We pull out all callgraph nodes in the top-level hash table
    +	 * with a matching PMC id.  We then sort these based on the
    +	 * frequency of occurrence.  Each callgraph node is then
    +	 * printed.
    +	 */
    +
    +	nsamples = 0;
    +	pmcid = pmcr->pr_pmcid;
    +	if ((sortbuffer = (struct pmcstat_cgnode **)
    +	    malloc(sizeof(struct pmcstat_cgnode *) *
    +	    pmcstat_cgnode_hash_count)) == NULL)
    +		err(EX_OSERR, "ERROR: Cannot sort callgraph");
    +	cgn = sortbuffer;
    +
    +	for (n = 0; n < PMCSTAT_NHASH; n++)
    +		LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
    +		    if (pch->pch_pmcid == pmcid) {
    +			    nsamples += pch->pch_cgnode->pcg_count;
    +			    *cgn++ = pch->pch_cgnode;
    +		    }
    +
    +	nentries = cgn - sortbuffer;
    +	assert(nentries <= pmcstat_cgnode_hash_count);
    +
    +	if (nentries == 0) {
    +		free(sortbuffer);
    +		return;
    +	}
    +
    +	qsort(sortbuffer, nentries, sizeof(struct pmcstat_cgnode *),
    +	    pmcstat_cgnode_compare);
    +
    +	(void) fprintf(args.pa_graphfile,
    +	    "@ %s [%u samples]\n\n",
    +	    pmcstat_string_unintern(pmcr->pr_pmcname),
    +	    nsamples);
    +
    +	for (cgn = sortbuffer, n = 0; n < nentries; n++, cgn++) {
    +		pmcstat_previous_filename_printed = NULL;
    +		pmcstat_cgnode_print(*cgn, 0, nsamples);
    +		(void) fprintf(args.pa_graphfile, "\n");
    +	}
    +
    +	free(sortbuffer);
    +}
    +
    +/*
    + * Print out callgraphs.
    + */
    +
    +static void
    +pmcstat_callgraph_print(void)
    +{
    +	struct pmcstat_pmcrecord *pmcr;
    +
    +	LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
    +	    pmcstat_callgraph_print_for_pmcid(pmcr);
    +}
    +
    +static void
    +pmcstat_cgnode_topprint(struct pmcstat_cgnode *cg,
    +    int depth, uint32_t nsamples)
    +{
    +	int v_attrs, vs_len, ns_len, width, len, n, nchildren;
    +	float v;
    +	char ns[30], vs[10];
    +	struct pmcstat_symbol *sym;
    +	struct pmcstat_cgnode **sortbuffer, **cgn, *pcg;
    +
    +	(void) depth;
    +
    +	/* Format value. */
    +	v = PMCPL_CG_COUNTP(cg);
    +	snprintf(vs, sizeof(vs), "%.1f", v);
    +	v_attrs = PMCSTAT_ATTRPERCENT(v);
    +
    +	/* Format name. */
    +	sym = pmcstat_symbol_search(cg->pcg_image, cg->pcg_func);
    +	if (sym != NULL) {
    +		snprintf(ns, sizeof(ns), "%s",
    +		    pmcstat_string_unintern(sym->ps_name));
    +	} else
    +		snprintf(ns, sizeof(ns), "%p",
    +		    (void *)cg->pcg_func);
    +
    +	PMCSTAT_ATTRON(v_attrs);
    +	PMCSTAT_PRINTW("%5.5s", vs);
    +	PMCSTAT_ATTROFF(v_attrs);
    +	PMCSTAT_PRINTW(" %-10.10s %-20.20s",
    +	    pmcstat_string_unintern(cg->pcg_image->pi_name),
    +	    ns);
    +
    +	nchildren = cg->pcg_nchildren;
    +	if (nchildren == 0) {
    +		PMCSTAT_PRINTW("\n");
    +		return;
    +	}
    +
    +	width = pmcstat_displaywidth - 40;
    +
    +	if ((sortbuffer = (struct pmcstat_cgnode **)
    +		malloc(sizeof(struct pmcstat_cgnode *) *
    +		    nchildren)) == NULL)
    +		err(EX_OSERR, "ERROR: Cannot print callgraph");
    +	cgn = sortbuffer;
    +
    +	LIST_FOREACH(pcg, &cg->pcg_children, pcg_sibling)
    +	    *cgn++ = pcg;
    +
    +	assert(cgn - sortbuffer == (int)nchildren);
    +
    +	qsort(sortbuffer, nchildren, sizeof(struct pmcstat_cgnode *),
    +	    pmcstat_cgnode_compare);
    +
    +	/* Count how many callers. */
    +	for (cgn = sortbuffer, n = 0; n < nchildren; n++, cgn++) {
    +		pcg = *cgn;
    +
    +		v = PMCPL_CG_COUNTP(pcg);
    +		if (v < pmcstat_threshold)
    +			break;
    +	}
    +	nchildren = n;
    +
    +	for (cgn = sortbuffer, n = 0; n < nchildren; n++, cgn++) {
    +		pcg = *cgn;
    +
    +		/* Format value. */
    +		if (nchildren > 1) {
    +			v = PMCPL_CG_COUNTP(pcg);
    +			vs_len = snprintf(vs, sizeof(vs), ":%.1f", v);
    +			v_attrs = PMCSTAT_ATTRPERCENT(v);
    +		} else
    +			vs_len = 0;
    +
    +		/* Format name. */
    +		sym = pmcstat_symbol_search(pcg->pcg_image, pcg->pcg_func);
    +		if (sym != NULL) {
    +			ns_len = snprintf(ns, sizeof(ns), "%s",
    +			    pmcstat_string_unintern(sym->ps_name));
    +		} else
    +			ns_len = snprintf(ns, sizeof(ns), "%p",
    +			    (void *)pcg->pcg_func);
    +
    +		len = ns_len + vs_len + 1;
    +		if (width - len < 0) {
    +			PMCSTAT_PRINTW("...");
    +			break;
    +		}
    +		width -= len;
    +
    +		PMCSTAT_PRINTW(" %s", ns);
    +		if (nchildren > 1) {
    +			PMCSTAT_ATTRON(v_attrs);
    +			PMCSTAT_PRINTW("%s", vs);
    +			PMCSTAT_ATTROFF(v_attrs);
    +		}
    +	}
    +	PMCSTAT_PRINTW("\n");
    +	free(sortbuffer);
    +}
    +
    +/*
    + * Top mode display.
    + */
    +
    +void
    +pmcpl_cg_topdisplay(void)
    +{
    +	int n, nentries;
    +	uint32_t nsamples;
    +	struct pmcstat_cgnode **sortbuffer, **cgn;
    +	struct pmcstat_cgnode_hash *pch;
    +	struct pmcstat_pmcrecord *pmcr;
    +
    +	pmcr = pmcstat_pmcindex_to_pmcr(pmcstat_pmcinfilter);
    +
    +	/*
    +	 * We pull out all callgraph nodes in the top-level hash table
    +	 * with a matching PMC index.  We then sort these based on the
    +	 * frequency of occurrence.  Each callgraph node is then
    +	 * printed.
    +	 */
    +
    +	nsamples = 0;
    +
    +	if ((sortbuffer = (struct pmcstat_cgnode **)
    +	    malloc(sizeof(struct pmcstat_cgnode *) *
    +	    pmcstat_cgnode_hash_count)) == NULL)
    +		err(EX_OSERR, "ERROR: Cannot sort callgraph");
    +	cgn = sortbuffer;
    +
    +	for (n = 0; n < PMCSTAT_NHASH; n++)
    +		LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
    +		    if (pmcr == NULL || pch->pch_pmcid == pmcr->pr_pmcid) {
    +			    nsamples += pch->pch_cgnode->pcg_count;
    +			    *cgn++ = pch->pch_cgnode;
    +		    }
    +
    +	nentries = cgn - sortbuffer;
    +	assert(nentries <= pmcstat_cgnode_hash_count);
    +
    +	if (nentries == 0) {
    +		free(sortbuffer);
    +		return;
    +	}
    +
    +	qsort(sortbuffer, nentries, sizeof(struct pmcstat_cgnode *),
    +	    pmcstat_cgnode_compare);
    +
    +	PMCSTAT_PRINTW("%5.5s %-10.10s %-20.20s %s\n",
    +	    "%SAMP", "IMAGE", "FUNCTION", "CALLERS");
    +
    +	nentries = min(pmcstat_displayheight - 2, nentries);
    +
    +	for (cgn = sortbuffer, n = 0; n < nentries; n++, cgn++) {
    +		if (PMCPL_CG_COUNTP(*cgn) < pmcstat_threshold)
    +			break;
    +		pmcstat_cgnode_topprint(*cgn, 0, nsamples);
    +	}
    +
    +	free(sortbuffer);
    +}
    +
    +/*
    + * Handle top mode keypress.
    + */
    +
    +int
    +pmcpl_cg_topkeypress(int c, WINDOW *w)
    +{
    +
    +	(void) c; (void) w;
    +
    +	return 0;
    +}
    +
    +int
    +pmcpl_cg_init(void)
    +{
    +	int i;
    +
    +	pmcstat_cgnode_hash_count = 0;
    +	pmcstat_previous_filename_printed = NULL;
    +
    +	for (i = 0; i < PMCSTAT_NHASH; i++) {
    +		LIST_INIT(&pmcstat_cgnode_hash[i]);
    +	}
    +
    +	return (0);
    +}
    +
    +void
    +pmcpl_cg_shutdown(FILE *mf)
    +{
    +	int i;
    +	struct pmcstat_cgnode_hash *pch, *pchtmp;
    +
    +	(void) mf;
    +
    +	if (args.pa_flags & FLAG_DO_CALLGRAPHS)
    +		pmcstat_callgraph_print();
    +
    +	/*
    +	 * Free memory.
    +	 */
    +	for (i = 0; i < PMCSTAT_NHASH; i++) {
    +		LIST_FOREACH_SAFE(pch, &pmcstat_cgnode_hash[i], pch_next,
    +		    pchtmp) {
    +			pmcstat_cgnode_free(pch->pch_cgnode);
    +			LIST_REMOVE(pch, pch_next);
    +			free(pch);
    +		}
    +	}
    +}
    +
    diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.h b/usr.sbin/pmcstat/pmcpl_callgraph.h
    new file mode 100644
    index 00000000000..aaf0e1ba1d6
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcpl_callgraph.h
    @@ -0,0 +1,67 @@
    +/*-
    + * Copyright (c) 2005-2007, Joseph Koshy
    + * Copyright (c) 2007 The FreeBSD Foundation
    + * All rights reserved.
    + *
    + * Portions of this software were developed by A. Joseph Koshy under
    + * sponsorship from the FreeBSD Foundation and 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.
    + *
    + * $FreeBSD$
    + */
    +
    +#ifndef	_PMCSTAT_PL_CALLGRAPH_H_
    +#define	_PMCSTAT_PL_CALLGRAPH_H_
    +
    +/*
    + * Each call graph node is tracked by a pmcstat_cgnode struct.
    + */
    +
    +struct pmcstat_cgnode {
    +	struct pmcstat_image	*pcg_image;
    +	uintfptr_t		pcg_func;
    +	uint32_t		pcg_count;
    +	uint32_t		pcg_nchildren;
    +	LIST_ENTRY(pmcstat_cgnode) pcg_sibling;
    +	LIST_HEAD(,pmcstat_cgnode) pcg_children;
    +};
    +
    +struct pmcstat_cgnode_hash {
    +	struct pmcstat_cgnode  *pch_cgnode;
    +	pmc_id_t		pch_pmcid;
    +	LIST_ENTRY(pmcstat_cgnode_hash) pch_next;
    +};
    +extern LIST_HEAD(pmcstat_cgnode_hash_list, pmcstat_cgnode_hash) pmcstat_cgnode_hash[PMCSTAT_NHASH];
    +extern int pmcstat_cgnode_hash_count;
    +
    +/* Function prototypes */
    +int pmcpl_cg_init(void);
    +void pmcpl_cg_shutdown(FILE *mf);
    +void pmcpl_cg_process(
    +    struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
    +    uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
    +int pmcpl_cg_topkeypress(int c, WINDOW *w);
    +void pmcpl_cg_topdisplay(void);
    +void pmcpl_cg_configure(char *opt);
    +
    +#endif	/* _PMCSTAT_PL_CALLGRAPH_H_ */
    diff --git a/usr.sbin/pmcstat/pmcpl_calltree.c b/usr.sbin/pmcstat/pmcpl_calltree.c
    new file mode 100644
    index 00000000000..498092dcca8
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcpl_calltree.c
    @@ -0,0 +1,1000 @@
    +/*-
    + * Copyright (c) 2009, Fabien Thomas
    + * 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.
    + */
    +
    +/*
    + * Process hwpmc(4) samples as calltree.
    + *
    + * Output file format compatible with Kcachegrind (kdesdk).
    + * Handle top mode with a sorted tree display.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include "pmcstat.h"
    +#include "pmcstat_log.h"
    +#include "pmcstat_top.h"
    +#include "pmcpl_calltree.h"
    +
    +#define PMCPL_CT_GROWSIZE	4
    +
    +static pmcstat_interned_string pmcpl_ct_prevfn;
    +
    +static int pmcstat_skiplink = 0;
    +
    +struct pmcpl_ct_node;
    +
    +/* Get the sample value for PMC a. */
    +#define PMCPL_CT_SAMPLE(a, b) \
    +	((a) < (b)->npmcs ? (b)->sb[a] : 0)
    +
    +/* Get the sample value in percent related to rsamples. */
    +#define PMCPL_CT_SAMPLEP(a, b) \
    +	(PMCPL_CT_SAMPLE(a, b) * 100.0 / rsamples->sb[a])
    +
    +struct pmcpl_ct_sample {
    +	int		npmcs;		/* Max pmc index available. */
    +	unsigned	*sb;		/* Sample buffer for 0..npmcs. */
    +};
    +
    +struct pmcpl_ct_arc {
    +	struct pmcpl_ct_sample	pcta_samples;
    +	struct pmcpl_ct_sample	pcta_callid;
    +	unsigned		pcta_call;
    +	struct pmcpl_ct_node	*pcta_child;
    +};
    +
    +struct pmcpl_ct_instr {
    +	uintfptr_t		pctf_func;
    +	struct pmcpl_ct_sample	pctf_samples;
    +};
    +
    +/*
    + * Each calltree node is tracked by a pmcpl_ct_node struct.
    + */
    +struct pmcpl_ct_node {
    +#define PMCPL_PCT_TAG	0x00000001	/* Loop detection. */
    +	uint32_t		pct_flags;
    +	struct pmcstat_image	*pct_image;
    +	uintfptr_t		pct_func;
    +	struct pmcpl_ct_sample	pct_samples;
    +
    +	int			pct_narc;
    +	int			pct_arc_c;
    +	struct pmcpl_ct_arc 	*pct_arc;
    +
    +	/* TODO: optimize for large number of items. */
    +	int			pct_ninstr;
    +	int			pct_instr_c;
    +	struct pmcpl_ct_instr	*pct_instr;
    +};
    +
    +struct pmcpl_ct_node_hash {
    +	struct pmcpl_ct_node  *pch_ctnode;
    +	LIST_ENTRY(pmcpl_ct_node_hash) pch_next;
    +};
    +
    +struct pmcpl_ct_sample pmcpl_ct_callid;
    +
    +#define PMCPL_CT_MAXCOL		PMC_CALLCHAIN_DEPTH_MAX	
    +#define PMCPL_CT_MAXLINE	256
    +struct pmcpl_ct_node  *pmcpl_ct_topscreen[PMCPL_CT_MAXCOL][PMCPL_CT_MAXLINE];
    +
    +/*
    + * All nodes indexed by function/image name are placed in a hash table.
    + */
    +static LIST_HEAD(,pmcpl_ct_node_hash) pmcpl_ct_node_hash[PMCSTAT_NHASH];
    +
    +/*
    + * Root node for the graph.
    + */
    +static struct pmcpl_ct_node *pmcpl_ct_root;
    +
    +/*
    + * Prototypes
    + */
    +
    +/*
    + * Initialize a samples.
    + */
    +
    +static void
    +pmcpl_ct_samples_init(struct pmcpl_ct_sample *samples)
    +{
    +
    +	samples->npmcs = 0;
    +	samples->sb = NULL;
    +}
    +
    +/*
    + * Free a samples.
    + */
    +
    +static void
    +pmcpl_ct_samples_free(struct pmcpl_ct_sample *samples)
    +{
    +
    +	samples->npmcs = 0;
    +	free(samples->sb);
    +	samples->sb = NULL;
    +}
    +
    +/*
    + * Grow a sample block to store pmcstat_npmcs PMCs.
    + */
    +
    +static void
    +pmcpl_ct_samples_grow(struct pmcpl_ct_sample *samples)
    +{
    +	int npmcs;
    +
    +	/* Enough storage. */
    +	if (pmcstat_npmcs <= samples->npmcs)
    +                return;
    +
    +	npmcs = samples->npmcs +
    +	    max(pmcstat_npmcs - samples->npmcs, PMCPL_CT_GROWSIZE);
    +	samples->sb = realloc(samples->sb, npmcs * sizeof(unsigned));
    +	if (samples->sb == NULL)
    +		errx(EX_SOFTWARE, "ERROR: out of memory");
    +	bzero((char *)samples->sb + samples->npmcs * sizeof(unsigned),
    +	    (npmcs - samples->npmcs) * sizeof(unsigned));
    +	samples->npmcs = npmcs;
    +}
    +
    +/*
    + * Compute the sum of all root arcs.
    + */
    +
    +static void
    +pmcpl_ct_samples_root(struct pmcpl_ct_sample *samples)
    +{
    +	int i, pmcin;
    +
    +	pmcpl_ct_samples_init(samples);
    +	pmcpl_ct_samples_grow(samples);
    +
    +	for (i = 0; i < pmcpl_ct_root->pct_narc; i++)
    +		for (pmcin = 0; pmcin < pmcstat_npmcs; pmcin++)
    +			samples->sb[pmcin] += PMCPL_CT_SAMPLE(pmcin,
    +			    &pmcpl_ct_root->pct_arc[i].pcta_samples);
    +}
    +
    +/*
    + * Grow the arc table.
    + */
    +
    +static void
    +pmcpl_ct_arc_grow(int cursize, int *maxsize, struct pmcpl_ct_arc **items)
    +{
    +	int nmaxsize;
    +
    +	if (cursize < *maxsize)
    +		return;
    +
    +	nmaxsize = *maxsize + max(cursize + 1 - *maxsize, PMCPL_CT_GROWSIZE);
    +	*items = realloc(*items, nmaxsize * sizeof(struct pmcpl_ct_arc));
    +	if (*items == NULL)
    +		errx(EX_SOFTWARE, "ERROR: out of memory");
    +	bzero((char *)*items + *maxsize * sizeof(struct pmcpl_ct_arc),
    +	    (nmaxsize - *maxsize) * sizeof(struct pmcpl_ct_arc));
    +	*maxsize = nmaxsize;
    +}
    +
    +/*
    + * Compare two arc by samples value.
    + */
    +static int
    +pmcpl_ct_arc_compare(void *thunk, const void *a, const void *b)
    +{
    +	const struct pmcpl_ct_arc *ct1, *ct2;
    +	int pmcin = *(int *)thunk;
    +
    +	ct1 = (const struct pmcpl_ct_arc *) a;
    +	ct2 = (const struct pmcpl_ct_arc *) b;
    +
    +	/* Sort in reverse order */
    +	if (PMCPL_CT_SAMPLE(pmcin, &ct1->pcta_samples) <
    +	    PMCPL_CT_SAMPLE(pmcin, &ct2->pcta_samples))
    +		return (1);
    +	if (PMCPL_CT_SAMPLE(pmcin, &ct1->pcta_samples) >
    +	    PMCPL_CT_SAMPLE(pmcin, &ct2->pcta_samples))
    +		return (-1);
    +	return (0);
    +}
    +
    +/*
    + * Grow the instr table.
    + */
    +
    +static void
    +pmcpl_ct_instr_grow(int cursize, int *maxsize, struct pmcpl_ct_instr **items)
    +{
    +	int nmaxsize;
    +
    +	if (cursize < *maxsize)
    +		return;
    +
    +	nmaxsize = *maxsize + max(cursize + 1 - *maxsize, PMCPL_CT_GROWSIZE);
    +	*items = realloc(*items, nmaxsize * sizeof(struct pmcpl_ct_instr));
    +	if (*items == NULL)
    +		errx(EX_SOFTWARE, "ERROR: out of memory");
    +	bzero((char *)*items + *maxsize * sizeof(struct pmcpl_ct_instr),
    +	    (nmaxsize - *maxsize) * sizeof(struct pmcpl_ct_instr));
    +	*maxsize = nmaxsize;
    +}
    +
    +/*
    + * Add a new instruction sample to given node.
    + */
    +
    +static void
    +pmcpl_ct_instr_add(struct pmcpl_ct_node *ct, int pmcin, uintfptr_t pc)
    +{
    +	int i;
    +	struct pmcpl_ct_instr *in;
    +
    +	for (i = 0; ipct_ninstr; i++) {
    +		if (ct->pct_instr[i].pctf_func == pc) {
    +			in = &ct->pct_instr[i];
    +			pmcpl_ct_samples_grow(&in->pctf_samples);
    +			in->pctf_samples.sb[pmcin]++;
    +			return;
    +		}
    +	}
    +
    +	pmcpl_ct_instr_grow(ct->pct_ninstr, &ct->pct_instr_c, &ct->pct_instr);
    +	in = &ct->pct_instr[ct->pct_ninstr];
    +	in->pctf_func = pc;
    +	pmcpl_ct_samples_init(&in->pctf_samples);
    +	pmcpl_ct_samples_grow(&in->pctf_samples);
    +	in->pctf_samples.sb[pmcin] = 1;
    +	ct->pct_ninstr++;
    +}
    +
    +/*
    + * Allocate a new node.
    + */
    +
    +static struct pmcpl_ct_node *
    +pmcpl_ct_node_allocate(struct pmcstat_image *image, uintfptr_t pc)
    +{
    +	struct pmcpl_ct_node *ct;
    +
    +	if ((ct = malloc(sizeof(*ct))) == NULL)
    +		err(EX_OSERR, "ERROR: Cannot allocate callgraph node");
    +
    +	ct->pct_flags	= 0;
    +	ct->pct_image 	= image;
    +	ct->pct_func	= pc;
    +
    +	pmcpl_ct_samples_init(&ct->pct_samples);
    +
    +	ct->pct_narc	= 0;
    +	ct->pct_arc_c	= 0;
    +	ct->pct_arc	= NULL;
    +
    +	ct->pct_ninstr	= 0;
    +	ct->pct_instr_c	= 0;
    +	ct->pct_instr	= NULL;
    +
    +	return (ct);
    +}
    +
    +/*
    + * Free a node.
    + */
    +
    +static void
    +pmcpl_ct_node_free(struct pmcpl_ct_node *ct)
    +{
    +	int i;
    +
    +	for (i = 0; i < ct->pct_narc; i++) {
    +		pmcpl_ct_samples_free(&ct->pct_arc[i].pcta_samples);
    +		pmcpl_ct_samples_free(&ct->pct_arc[i].pcta_callid);
    +	}
    +
    +	pmcpl_ct_samples_free(&ct->pct_samples);
    +	free(ct->pct_arc);
    +	free(ct->pct_instr);
    +	free(ct);
    +}
    +
    +/*
    + * Clear the graph tag on each node.
    + */
    +static void
    +pmcpl_ct_node_cleartag(void)
    +{
    +	int i;
    +	struct pmcpl_ct_node_hash *pch;
    +
    +	for (i = 0; i < PMCSTAT_NHASH; i++)
    +		LIST_FOREACH(pch, &pmcpl_ct_node_hash[i], pch_next)
    +			pch->pch_ctnode->pct_flags &= ~PMCPL_PCT_TAG;
    +
    +	pmcpl_ct_root->pct_flags &= ~PMCPL_PCT_TAG;
    +}
    +
    +/*
    + * Print the callchain line by line with maximum cost at top.
    + */ 
    +
    +static int
    +pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct,
    +    struct pmcpl_ct_sample *rsamples, int x, int *y)
    +{
    +	int i;
    +
    +	if (ct->pct_flags & PMCPL_PCT_TAG)
    +		return 0;
    +
    +	ct->pct_flags |= PMCPL_PCT_TAG;
    +
    +	if (x >= PMCPL_CT_MAXCOL) {
    +		pmcpl_ct_topscreen[x][*y] = NULL;
    +		return 1;
    +	}
    +	pmcpl_ct_topscreen[x][*y] = ct;
    +
    +	/*
    +	 * This is a terminal node
    +	 */
    +	if (ct->pct_narc == 0) {
    +		pmcpl_ct_topscreen[x+1][*y] = NULL;
    +		if (*y >= PMCPL_CT_MAXLINE ||
    +		    *y >= pmcstat_displaywidth)
    +			return 1;
    +		*y = *y + 1;
    +		for (i=0; i < x; i++)
    +			pmcpl_ct_topscreen[i][*y] =
    +			    pmcpl_ct_topscreen[i][*y - 1];
    +		return 0;
    +	}
    +
    +	/*
    +	 * Quicksort the arcs.
    +	 */
    +	qsort_r(ct->pct_arc, ct->pct_narc, sizeof(struct pmcpl_ct_arc),
    +	    &pmcin, pmcpl_ct_arc_compare);
    +
    +	for (i = 0; i < ct->pct_narc; i++) {
    +		if (PMCPL_CT_SAMPLEP(pmcin,
    +		    &ct->pct_arc[i].pcta_samples) > pmcstat_threshold) {
    +			if (pmcpl_ct_node_dumptop(pmcin,
    +			        ct->pct_arc[i].pcta_child,
    +			        rsamples, x+1, y))
    +				return 1;
    +		}
    +	}
    +
    +	return 0;
    +}
    +
    +/*
    + * Format and display given PMC index.
    + */
    +
    +static void
    +pmcpl_ct_node_printtop(struct pmcpl_ct_sample *rsamples, int pmcin, int maxy)
    +{
    +	int v_attrs, ns_len, vs_len, is_len, width, indentwidth, x, y;
    +	float v;
    +	char ns[30], vs[10], is[20];
    +	struct pmcpl_ct_node *ct;
    +	struct pmcstat_symbol *sym;
    +	const char *space = " ";
    +
    +	for (y = 0; y < maxy; y++) {
    +		/* Output image. */
    +		ct = pmcpl_ct_topscreen[0][y];
    +		snprintf(is, sizeof(is), "%-10.10s",
    +		    pmcstat_string_unintern(ct->pct_image->pi_name));
    +		PMCSTAT_PRINTW("%s ", is);
    +		width = indentwidth = 11;
    +
    +		for (x = 0; pmcpl_ct_topscreen[x][y] !=NULL; x++) {
    +
    +			ct = pmcpl_ct_topscreen[x][y];
    +
    +			ns[0] = '\0'; ns_len = 0;
    +			vs[0] = '\0'; vs_len = 0;
    +			is[0] = '\0'; is_len = 0;
    +
    +			/* Format value. */
    +			v = PMCPL_CT_SAMPLEP(pmcin, &ct->pct_samples);
    +			if (v > pmcstat_threshold)
    +				vs_len  = snprintf(vs, sizeof(vs), "(%.1f%%)", v);
    +			v_attrs = PMCSTAT_ATTRPERCENT(v);
    +
    +			if (pmcstat_skiplink && v <= pmcstat_threshold) {
    +				PMCSTAT_PRINTW(". ");
    +				width += 2;
    +				continue;
    +			}
    +			sym = pmcstat_symbol_search(ct->pct_image, ct->pct_func);
    +			if (sym != NULL) {
    +				ns_len = snprintf(ns, sizeof(ns), "%s",
    +				    pmcstat_string_unintern(sym->ps_name));
    +			} else
    +				ns_len = snprintf(ns, sizeof(ns), "%p",
    +				    (void *)ct->pct_func);
    +
    +			/* Format image. */
    +			if (x > 0 && pmcpl_ct_topscreen[x-1][y]->pct_image != ct->pct_image)
    +				is_len = snprintf(is, sizeof(is), "@%s",
    +				    pmcstat_string_unintern(ct->pct_image->pi_name));
    +
    +			/* Check for line wrap. */
    +			width += ns_len + is_len + vs_len + 1;
    +			if (width >= pmcstat_displaywidth) {
    +				PMCSTAT_PRINTW("\n%*s", indentwidth, space);
    +				width = indentwidth + ns_len + is_len + vs_len;
    +			}
    +
    +			PMCSTAT_ATTRON(v_attrs);
    +			PMCSTAT_PRINTW("%s%s%s ", ns, is, vs);
    +			PMCSTAT_ATTROFF(v_attrs);
    +		}
    +		PMCSTAT_PRINTW("\n");
    +	}
    +}
    +
    +/*
    + * Output top mode snapshot.
    + */
    +
    +void
    +pmcpl_ct_topdisplay(void)
    +{
    +	int i, x, y, pmcin;
    +	struct pmcpl_ct_sample rsamples;
    +
    +	pmcpl_ct_samples_root(&rsamples);
    +
    +	PMCSTAT_PRINTW("%-10.10s %s\n", "IMAGE", "CALLTREE");
    +
    +	for (pmcin = 0; pmcin < pmcstat_npmcs; pmcin++) {
    +		/* Filter PMCs. */
    +		if (pmcstat_pmcinfilter != pmcin)
    +			continue;
    +
    +		pmcpl_ct_node_cleartag();
    +
    +		/* Quicksort the arcs. */
    +		qsort_r(pmcpl_ct_root->pct_arc,
    +		    pmcpl_ct_root->pct_narc,
    +		    sizeof(struct pmcpl_ct_arc),
    +		    &pmcin, pmcpl_ct_arc_compare);
    +
    +		x = y = 0;
    +		for (i = 0; i < pmcpl_ct_root->pct_narc; i++) {
    +			if (pmcpl_ct_node_dumptop(pmcin,
    +			        pmcpl_ct_root->pct_arc[i].pcta_child,
    +			        &rsamples, x, &y)) {
    +				break;
    +			}
    +		}
    +
    +		pmcpl_ct_node_printtop(&rsamples, pmcin, y);
    +	}
    +	pmcpl_ct_samples_free(&rsamples);
    +}
    +
    +/*
    + * Handle top mode keypress.
    + */
    +
    +int
    +pmcpl_ct_topkeypress(int c, WINDOW *w)
    +{
    +
    +	switch (c) {
    +	case 'f':
    +		pmcstat_skiplink = !pmcstat_skiplink;
    +		wprintw(w, "skip empty link %s", pmcstat_skiplink ? "on" : "off");
    +		break;
    +	}
    +
    +	return 0;
    +}
    +
    +/*
    + * Look for a callgraph node associated with pmc `pmcid' in the global
    + * hash table that corresponds to the given `pc' value in the process map
    + * `ppm'.
    + */
    +
    +static struct pmcpl_ct_node *
    +pmcpl_ct_node_hash_lookup_pc(struct pmcpl_ct_node *parent,
    +    struct pmcstat_pcmap *ppm, uintfptr_t pc, int pmcin)
    +{
    +	struct pmcstat_symbol *sym;
    +	struct pmcstat_image *image;
    +	struct pmcpl_ct_node *ct;
    +	struct pmcpl_ct_node_hash *h;
    +	struct pmcpl_ct_arc *arc;
    +	uintfptr_t loadaddress;
    +	int i;
    +	unsigned int hash;
    +
    +	assert(parent != NULL);
    +
    +	image = ppm->ppm_image;
    +
    +	loadaddress = ppm->ppm_lowpc + image->pi_vaddr - image->pi_start;
    +	pc -= loadaddress;	/* Convert to an offset in the image. */
    +
    +	/*
    +	 * Try determine the function at this offset.  If we can't
    +	 * find a function round leave the `pc' value alone.
    +	 */
    +	if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
    +		pc = sym->ps_start;
    +
    +	for (hash = i = 0; i < (int)sizeof(uintfptr_t); i++)
    +		hash += (pc >> i) & 0xFF;
    +
    +	hash &= PMCSTAT_HASH_MASK;
    +
    +	ct = NULL;
    +	LIST_FOREACH(h, &pmcpl_ct_node_hash[hash], pch_next) {
    +		ct = h->pch_ctnode;
    +
    +		assert(ct != NULL);
    +
    +		if (ct->pct_image == image && ct->pct_func == pc) {
    +			/*
    +			 * Find related arc in parent node and
    +			 * increment the sample count.
    +			 */
    +			for (i = 0; i < parent->pct_narc; i++) {
    +				if (parent->pct_arc[i].pcta_child == ct) {
    +					arc = &parent->pct_arc[i];
    +					pmcpl_ct_samples_grow(&arc->pcta_samples);
    +					arc->pcta_samples.sb[pmcin]++;
    +					/* Estimate call count. */
    +					pmcpl_ct_samples_grow(&arc->pcta_callid);
    +					if (pmcpl_ct_callid.sb[pmcin] -
    +					    arc->pcta_callid.sb[pmcin] > 1)
    +						arc->pcta_call++;
    +					arc->pcta_callid.sb[pmcin] =
    +					    pmcpl_ct_callid.sb[pmcin];
    +					return (ct);
    +				}
    +			}
    +
    +			/*
    +			 * No arc found for us, add ourself to the parent.
    +			 */
    +			pmcpl_ct_arc_grow(parent->pct_narc,
    +			    &parent->pct_arc_c, &parent->pct_arc);
    +			arc = &parent->pct_arc[parent->pct_narc];
    +			pmcpl_ct_samples_grow(&arc->pcta_samples);
    +			arc->pcta_samples.sb[pmcin] = 1;
    +			arc->pcta_call = 1;
    +			pmcpl_ct_samples_grow(&arc->pcta_callid);
    +			arc->pcta_callid.sb[pmcin] = pmcpl_ct_callid.sb[pmcin];
    +			arc->pcta_child = ct;
    +			parent->pct_narc++;
    +			return (ct);
    +		}
    +	}
    +
    +	/*
    +	 * We haven't seen this (pmcid, pc) tuple yet, so allocate a
    +	 * new callgraph node and a new hash table entry for it.
    +	 */
    +	ct = pmcpl_ct_node_allocate(image, pc);
    +	if ((h = malloc(sizeof(*h))) == NULL)
    +		err(EX_OSERR, "ERROR: Could not allocate callgraph node");
    +
    +	h->pch_ctnode = ct;
    +	LIST_INSERT_HEAD(&pmcpl_ct_node_hash[hash], h, pch_next);
    +
    +	pmcpl_ct_arc_grow(parent->pct_narc,
    +	    &parent->pct_arc_c, &parent->pct_arc);
    +	arc = &parent->pct_arc[parent->pct_narc];
    +	pmcpl_ct_samples_grow(&arc->pcta_samples);
    +	arc->pcta_samples.sb[pmcin] = 1;
    +	arc->pcta_call = 1;
    +	pmcpl_ct_samples_grow(&arc->pcta_callid);
    +	arc->pcta_callid.sb[pmcin] = pmcpl_ct_callid.sb[pmcin];
    +	arc->pcta_child = ct;
    +	parent->pct_narc++;
    +	return (ct);
    +}
    +
    +/*
    + * Record a callchain.
    + */
    +
    +void
    +pmcpl_ct_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
    +    uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
    +{
    +	int n, pmcin;
    +	struct pmcstat_pcmap *ppm[PMC_CALLCHAIN_DEPTH_MAX];
    +	struct pmcstat_process *km;
    +	struct pmcpl_ct_node *parent, *child;
    +
    +	(void) cpu;
    +
    +	assert(nsamples>0 && nsamples<=PMC_CALLCHAIN_DEPTH_MAX);
    +
    +	/* Get the PMC index. */
    +	pmcin = pmcr->pr_pmcin;
    +
    +	/*
    +	 * Validate mapping for the callchain.
    +	 * Go from bottom to first invalid entry.
    +	 */
    +	km = pmcstat_kernproc;
    +	for (n = 0; n < (int)nsamples; n++) {
    +		ppm[n] = pmcstat_process_find_map(usermode ?
    +		    pp : km, cc[n]);
    +		if (ppm[n] == NULL) {
    +			/* Detect full frame capture (kernel + user). */
    +			if (!usermode) {
    +				ppm[n] = pmcstat_process_find_map(pp, cc[n]);
    +				if (ppm[n] != NULL)
    +					km = pp;
    +			}
    +		}
    +		if (ppm[n] == NULL)
    +			break;
    +	}
    +	if (n-- == 0) {
    +		pmcstat_stats.ps_callchain_dubious_frames++;
    +		return;
    +	}
    +
    +	/* Increase the call generation counter. */
    +	pmcpl_ct_samples_grow(&pmcpl_ct_callid);
    +	pmcpl_ct_callid.sb[pmcin]++;
    +
    +	/*
    +	 * Iterate remaining addresses.
    +	 */
    +	for (parent = pmcpl_ct_root, child = NULL; n >= 0; n--) {
    +		child = pmcpl_ct_node_hash_lookup_pc(parent, ppm[n], cc[n],
    +		    pmcin);
    +		if (child == NULL) {
    +			pmcstat_stats.ps_callchain_dubious_frames++;
    +			continue;
    +		}
    +		parent = child;
    +	}
    +
    +	/*
    +	 * Increment the sample count for this PMC.
    +	 */
    +	if (child != NULL) {
    +		pmcpl_ct_samples_grow(&child->pct_samples);
    +		child->pct_samples.sb[pmcin]++;
    +
    +		/* Update per instruction sample if required. */
    +		if (args.pa_ctdumpinstr)
    +			pmcpl_ct_instr_add(child, pmcin, cc[0] -
    +			    (ppm[0]->ppm_lowpc + ppm[0]->ppm_image->pi_vaddr -
    +			     ppm[0]->ppm_image->pi_start));
    +	}
    +}
    +
    +/*
    + * Print node self cost.
    + */
    +
    +static void
    +pmcpl_ct_node_printself(struct pmcpl_ct_node *ct)
    +{
    +	int i, j, line;
    +	uintptr_t addr;
    +	struct pmcstat_symbol *sym;
    +	char sourcefile[PATH_MAX];
    +	char funcname[PATH_MAX];
    +
    +	/*
    +	 * Object binary.
    +	 */
    +#ifdef PMCPL_CT_OPTIMIZEFN
    +	if (pmcpl_ct_prevfn != ct->pct_image->pi_fullpath) {
    +#endif
    +		pmcpl_ct_prevfn = ct->pct_image->pi_fullpath;
    +		fprintf(args.pa_graphfile, "ob=%s\n",
    +		    pmcstat_string_unintern(pmcpl_ct_prevfn));
    +#ifdef PMCPL_CT_OPTIMIZEFN
    +	}
    +#endif
    +
    +	/*
    +	 * Function name.
    +	 */
    +	if (pmcstat_image_addr2line(ct->pct_image, ct->pct_func,
    +	    sourcefile, sizeof(sourcefile), &line,
    +	    funcname, sizeof(funcname))) {
    +		fprintf(args.pa_graphfile, "fn=%s\n",
    +		    funcname);
    +	} else {
    +		sym = pmcstat_symbol_search(ct->pct_image, ct->pct_func);
    +		if (sym != NULL)
    +			fprintf(args.pa_graphfile, "fn=%s\n",
    +			    pmcstat_string_unintern(sym->ps_name));
    +		else
    +			fprintf(args.pa_graphfile, "fn=%p\n",
    +			    (void *)(ct->pct_image->pi_vaddr + ct->pct_func));
    +	}
    +
    +	/*
    +	 * Self cost.
    +	 */
    +	if (ct->pct_ninstr > 0) {
    +		for (i = 0; i < ct->pct_ninstr; i++) {
    +			addr = ct->pct_image->pi_vaddr +
    +			    ct->pct_instr[i].pctf_func;
    +			line = 0;
    +			if (pmcstat_image_addr2line(ct->pct_image, addr,
    +			    sourcefile, sizeof(sourcefile), &line,
    +			    funcname, sizeof(funcname)))
    +				fprintf(args.pa_graphfile, "fl=%s\n", sourcefile);
    +			fprintf(args.pa_graphfile, "%p %u", (void *)addr, line);
    +			for (j = 0; jpct_instr[i].pctf_samples));
    +			fprintf(args.pa_graphfile, "\n");
    +		}
    +	} else {
    +		addr = ct->pct_image->pi_vaddr + ct->pct_func;
    +		line = 0;
    +		if (pmcstat_image_addr2line(ct->pct_image, addr,
    +		    sourcefile, sizeof(sourcefile), &line,
    +		    funcname, sizeof(funcname)))
    +			fprintf(args.pa_graphfile, "fl=%s\n", sourcefile);
    +		fprintf(args.pa_graphfile, "* *");
    +		for (i = 0; ipct_samples));
    +		fprintf(args.pa_graphfile, "\n");
    +	}
    +}
    +
    +/*
    + * Print node child cost.
    + */
    +
    +static void
    +pmcpl_ct_node_printchild(struct pmcpl_ct_node *ct)
    +{
    +	int i, j, line;
    +	uintptr_t addr;
    +	struct pmcstat_symbol *sym;
    +	struct pmcpl_ct_node *child;
    +	char sourcefile[PATH_MAX];
    +	char funcname[PATH_MAX];
    +
    +	/*
    +	 * Child cost.
    +	 * TODO: attach child cost to the real position in the funtion.
    +	 * TODO: cfn= / call  addr() / addr(call ) 
    +	 */
    +	for (i=0 ; ipct_narc; i++) {
    +		child = ct->pct_arc[i].pcta_child;
    +
    +		/* Object binary. */
    +#ifdef PMCPL_CT_OPTIMIZEFN
    +		if (pmcpl_ct_prevfn != child->pct_image->pi_fullpath) {
    +#endif
    +			pmcpl_ct_prevfn = child->pct_image->pi_fullpath;
    +			fprintf(args.pa_graphfile, "cob=%s\n",
    +			    pmcstat_string_unintern(pmcpl_ct_prevfn));
    +#if PMCPL_CT_OPTIMIZEFN
    +		}
    +#endif
    +		/* Child function name. */
    +		addr = child->pct_image->pi_vaddr + child->pct_func;
    +		/* Child function source file. */
    +		if (pmcstat_image_addr2line(child->pct_image, addr,
    +		    sourcefile, sizeof(sourcefile), &line,
    +		    funcname, sizeof(funcname))) {
    +			fprintf(args.pa_graphfile, "cfn=%s\n", funcname);
    +			fprintf(args.pa_graphfile, "cfl=%s\n", sourcefile);
    +		} else {
    +			sym = pmcstat_symbol_search(child->pct_image,
    +			    child->pct_func);
    +			if (sym != NULL)
    +				fprintf(args.pa_graphfile, "cfn=%s\n",
    +				    pmcstat_string_unintern(sym->ps_name));
    +			else
    +				fprintf(args.pa_graphfile, "cfn=%p\n", (void *)addr);
    +		}
    +
    +		/* Child function address, line and call count. */
    +		fprintf(args.pa_graphfile, "calls=%u %p %u\n",
    +		    ct->pct_arc[i].pcta_call, (void *)addr, line);
    +
    +		if (ct->pct_image != NULL) {
    +			/* Call address, line, sample. */
    +			addr = ct->pct_image->pi_vaddr + ct->pct_func;
    +			line = 0;
    +			pmcstat_image_addr2line(ct->pct_image, addr, sourcefile,
    +			    sizeof(sourcefile), &line,
    +			    funcname, sizeof(funcname));
    +			fprintf(args.pa_graphfile, "%p %u", (void *)addr, line);
    +		}
    +		else
    +			fprintf(args.pa_graphfile, "* *");
    +		for (j = 0; jpct_arc[i].pcta_samples));
    +		fprintf(args.pa_graphfile, "\n");
    +	}
    +}
    +
    +/*
    + * Clean the PMC name for Kcachegrind formula
    + */
    +
    +static void
    +pmcpl_ct_fixup_pmcname(char *s)
    +{
    +	char *p;
    +
    +	for (p = s; *p; p++)
    +		if (!isalnum(*p))
    +			*p = '_';
    +}
    +
    +/*
    + * Print a calltree (KCachegrind) for all PMCs.
    + */
    +
    +static void
    +pmcpl_ct_print(void)
    +{
    +	int n, i;
    +	struct pmcpl_ct_node_hash *pch;
    +	struct pmcpl_ct_sample rsamples;
    +	char name[40];
    +
    +	pmcpl_ct_samples_root(&rsamples);
    +	pmcpl_ct_prevfn = NULL;
    +
    +	fprintf(args.pa_graphfile,
    +		"version: 1\n"
    +		"creator: pmcstat\n"
    +		"positions: instr line\n"
    +		"events:");
    +	for (i=0; ipch_ctnode);
    +			pmcpl_ct_node_printchild(pch->pch_ctnode);
    +	}
    +
    +	pmcpl_ct_samples_free(&rsamples);
    +}
    +
    +int
    +pmcpl_ct_configure(char *opt)
    +{
    +
    +	if (strncmp(opt, "skiplink=", 9) == 0) {
    +		pmcstat_skiplink = atoi(opt+9);
    +	} else
    +		return (0);
    +
    +	return (1);
    +}
    +
    +int
    +pmcpl_ct_init(void)
    +{
    +	int i;
    +
    +	pmcpl_ct_prevfn = NULL;
    +	pmcpl_ct_root = pmcpl_ct_node_allocate(NULL, 0);
    +
    +	for (i = 0; i < PMCSTAT_NHASH; i++)
    +		LIST_INIT(&pmcpl_ct_node_hash[i]);
    +
    +	pmcpl_ct_samples_init(&pmcpl_ct_callid);
    +
    +	return (0);
    +}
    +
    +void
    +pmcpl_ct_shutdown(FILE *mf)
    +{
    +	int i;
    +	struct pmcpl_ct_node_hash *pch, *pchtmp;
    +
    +	(void) mf;
    +
    +	if (args.pa_flags & FLAG_DO_CALLGRAPHS)
    +		pmcpl_ct_print();
    +
    +	/*
    +	 * Free memory.
    +	 */
    +
    +	for (i = 0; i < PMCSTAT_NHASH; i++) {
    +		LIST_FOREACH_SAFE(pch, &pmcpl_ct_node_hash[i], pch_next,
    +		    pchtmp) {
    +			pmcpl_ct_node_free(pch->pch_ctnode);
    +			free(pch);
    +		}
    +	}
    +
    +	pmcpl_ct_node_free(pmcpl_ct_root);
    +	pmcpl_ct_root = NULL;
    +
    +	pmcpl_ct_samples_free(&pmcpl_ct_callid);
    +}
    +
    diff --git a/usr.sbin/pmcstat/pmcpl_calltree.h b/usr.sbin/pmcstat/pmcpl_calltree.h
    new file mode 100644
    index 00000000000..f54957f83f7
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcpl_calltree.h
    @@ -0,0 +1,42 @@
    +/*-
    + * Copyright (c) 2009, Fabien Thomas
    + * 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	_PMCSTAT_PL_CALLTREE_H_
    +#define	_PMCSTAT_PL_CALLTREE_H_
    +
    +/* Function prototypes */
    +int pmcpl_ct_init(void);
    +void pmcpl_ct_shutdown(FILE *mf);
    +void pmcpl_ct_process(
    +    struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
    +    uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
    +int pmcpl_ct_topkeypress(int c, WINDOW *w);
    +void pmcpl_ct_topdisplay(void);
    +int pmcpl_ct_configure(char *opt);
    +
    +#endif	/* _PMCSTAT_PL_CALLTREE_H_ */
    diff --git a/usr.sbin/pmcstat/pmcpl_gprof.c b/usr.sbin/pmcstat/pmcpl_gprof.c
    new file mode 100644
    index 00000000000..9327eb95b62
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcpl_gprof.c
    @@ -0,0 +1,533 @@
    +/*-
    + * Copyright (c) 2005-2007, Joseph Koshy
    + * Copyright (c) 2007 The FreeBSD Foundation
    + * Copyright (c) 2009, Fabien Thomas
    + * All rights reserved.
    + *
    + * Portions of this software were developed by A. Joseph Koshy under
    + * sponsorship from the FreeBSD Foundation and 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.
    + */
    +
    +/*
    + * Transform a hwpmc(4) log into human readable form, and into
    + * gprof(1) compatible profiles.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include "pmcstat.h"
    +#include "pmcstat_log.h"
    +#include "pmcpl_callgraph.h"
    +#include "pmcpl_gprof.h"
    +
    +/*
    + * struct pmcstat_gmonfile tracks a given 'gmon.out' file.  These
    + * files are mmap()'ed in as needed.
    + */
    +
    +struct pmcstat_gmonfile {
    +	LIST_ENTRY(pmcstat_gmonfile)	pgf_next; /* list of entries */
    +	int		pgf_overflow;	/* whether a count overflowed */
    +	pmc_id_t	pgf_pmcid;	/* id of the associated pmc */
    +	size_t		pgf_nbuckets;	/* #buckets in this gmon.out */
    +	unsigned int	pgf_nsamples;	/* #samples in this gmon.out */
    +	pmcstat_interned_string pgf_name;	/* pathname of gmon.out file */
    +	size_t		pgf_ndatabytes;	/* number of bytes mapped */
    +	void		*pgf_gmondata;	/* pointer to mmap'ed data */
    +	FILE		*pgf_file;	/* used when writing gmon arcs */
    +};
    +
    +/*
    + * Prototypes
    + */
    +
    +static void	pmcstat_gmon_create_file(struct pmcstat_gmonfile *_pgf,
    +    struct pmcstat_image *_image);
    +static pmcstat_interned_string pmcstat_gmon_create_name(const char *_sd,
    +    struct pmcstat_image *_img, pmc_id_t _pmcid);
    +static void	pmcstat_gmon_map_file(struct pmcstat_gmonfile *_pgf);
    +static void	pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *_pgf);
    +
    +static struct pmcstat_gmonfile *pmcstat_image_find_gmonfile(struct
    +    pmcstat_image *_i, pmc_id_t _id);
    +
    +/*
    + * Create a gmon.out file and size it.
    + */
    +
    +static void
    +pmcstat_gmon_create_file(struct pmcstat_gmonfile *pgf,
    +    struct pmcstat_image *image)
    +{
    +	int fd;
    +	size_t count;
    +	struct gmonhdr gm;
    +	const char *pathname;
    +	char buffer[DEFAULT_BUFFER_SIZE];
    +
    +	pathname = pmcstat_string_unintern(pgf->pgf_name);
    +	if ((fd = open(pathname, O_RDWR|O_NOFOLLOW|O_CREAT,
    +		 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
    +		err(EX_OSERR, "ERROR: Cannot open \"%s\"", pathname);
    +
    +	gm.lpc = image->pi_start;
    +	gm.hpc = image->pi_end;
    +	gm.ncnt = (pgf->pgf_nbuckets * sizeof(HISTCOUNTER)) +
    +	    sizeof(struct gmonhdr);
    +	gm.version = GMONVERSION;
    +	gm.profrate = 0;		/* use ticks */
    +	gm.histcounter_type = 0;	/* compatibility with moncontrol() */
    +	gm.spare[0] = gm.spare[1] = 0;
    +
    +	/* Write out the gmon header */
    +	if (write(fd, &gm, sizeof(gm)) < 0)
    +		goto error;
    +
    +	/* Zero fill the samples[] array */
    +	(void) memset(buffer, 0, sizeof(buffer));
    +
    +	count = pgf->pgf_ndatabytes - sizeof(struct gmonhdr);
    +	while (count > sizeof(buffer)) {
    +		if (write(fd, &buffer, sizeof(buffer)) < 0)
    +			goto error;
    +		count -= sizeof(buffer);
    +	}
    +
    +	if (write(fd, &buffer, count) < 0)
    +		goto error;
    +
    +	(void) close(fd);
    +
    +	return;
    +
    + error:
    +	err(EX_OSERR, "ERROR: Cannot write \"%s\"", pathname);
    +}
    +
    +/*
    + * Determine the full pathname of a gmon.out file for a given
    + * (image,pmcid) combination.  Return the interned string.
    + */
    +
    +pmcstat_interned_string
    +pmcstat_gmon_create_name(const char *samplesdir, struct pmcstat_image *image,
    +    pmc_id_t pmcid)
    +{
    +	const char *pmcname;
    +	char fullpath[PATH_MAX];
    +
    +	pmcname = pmcstat_pmcid_to_name(pmcid);
    +
    +	(void) snprintf(fullpath, sizeof(fullpath),
    +	    "%s/%s/%s", samplesdir, pmcname,
    +	    pmcstat_string_unintern(image->pi_samplename));
    +
    +	return (pmcstat_string_intern(fullpath));
    +}
    +
    +
    +/*
    + * Mmap in a gmon.out file for processing.
    + */
    +
    +static void
    +pmcstat_gmon_map_file(struct pmcstat_gmonfile *pgf)
    +{
    +	int fd;
    +	const char *pathname;
    +
    +	pathname = pmcstat_string_unintern(pgf->pgf_name);
    +
    +	/* the gmon.out file must already exist */
    +	if ((fd = open(pathname, O_RDWR | O_NOFOLLOW, 0)) < 0)
    +		err(EX_OSERR, "ERROR: cannot open \"%s\"", pathname);
    +
    +	pgf->pgf_gmondata = mmap(NULL, pgf->pgf_ndatabytes,
    +	    PROT_READ|PROT_WRITE, MAP_NOSYNC|MAP_SHARED, fd, 0);
    +
    +	if (pgf->pgf_gmondata == MAP_FAILED)
    +		err(EX_OSERR, "ERROR: cannot map \"%s\"", pathname);
    +
    +	(void) close(fd);
    +}
    +
    +/*
    + * Unmap a gmon.out file after sync'ing its data to disk.
    + */
    +
    +static void
    +pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *pgf)
    +{
    +	(void) msync(pgf->pgf_gmondata, pgf->pgf_ndatabytes,
    +	    MS_SYNC);
    +	(void) munmap(pgf->pgf_gmondata, pgf->pgf_ndatabytes);
    +	pgf->pgf_gmondata = NULL;
    +}
    +
    +static void
    +pmcstat_gmon_append_arc(struct pmcstat_image *image, pmc_id_t pmcid,
    +    uintptr_t rawfrom, uintptr_t rawto, uint32_t count)
    +{
    +	struct rawarc arc;	/* from  */
    +	const char *pathname;
    +	struct pmcstat_gmonfile *pgf;
    +
    +	if ((pgf = pmcstat_image_find_gmonfile(image, pmcid)) == NULL)
    +		return;
    +
    +	if (pgf->pgf_file == NULL) {
    +		pathname = pmcstat_string_unintern(pgf->pgf_name);
    +		if ((pgf->pgf_file = fopen(pathname, "a")) == NULL)
    +			return;
    +	}
    +
    +	arc.raw_frompc = rawfrom + image->pi_vaddr;
    +	arc.raw_selfpc = rawto + image->pi_vaddr;
    +	arc.raw_count = count;
    +
    +	(void) fwrite(&arc, sizeof(arc), 1, pgf->pgf_file);
    +
    +}
    +
    +static struct pmcstat_gmonfile *
    +pmcstat_image_find_gmonfile(struct pmcstat_image *image, pmc_id_t pmcid)
    +{
    +	struct pmcstat_gmonfile *pgf;
    +	LIST_FOREACH(pgf, &image->pi_gmlist, pgf_next)
    +	    if (pgf->pgf_pmcid == pmcid)
    +		    return (pgf);
    +	return (NULL);
    +}
    +
    +static void
    +pmcstat_cgnode_do_gmon_arcs(struct pmcstat_cgnode *cg, pmc_id_t pmcid)
    +{
    +	struct pmcstat_cgnode *cgc;
    +
    +	/*
    +	 * Look for child nodes that belong to the same image.
    +	 */
    +
    +	LIST_FOREACH(cgc, &cg->pcg_children, pcg_sibling) {
    +		if (cgc->pcg_image == cg->pcg_image)
    +			pmcstat_gmon_append_arc(cg->pcg_image, pmcid,
    +			    cgc->pcg_func, cg->pcg_func, cgc->pcg_count);
    +		if (cgc->pcg_nchildren > 0)
    +			pmcstat_cgnode_do_gmon_arcs(cgc, pmcid);
    +	}
    +}
    +
    +static void
    +pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmc_id_t pmcid)
    +{
    +	int n;
    +	struct pmcstat_cgnode_hash *pch;
    +
    +	for (n = 0; n < PMCSTAT_NHASH; n++)
    +		LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
    +			if (pch->pch_pmcid == pmcid &&
    +			    pch->pch_cgnode->pcg_nchildren > 1)
    +				pmcstat_cgnode_do_gmon_arcs(pch->pch_cgnode,
    +				    pmcid);
    +}
    +
    +
    +static void
    +pmcstat_callgraph_do_gmon_arcs(void)
    +{
    +	struct pmcstat_pmcrecord *pmcr;
    +
    +	LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
    +		pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmcr->pr_pmcid);
    +}
    +
    +void
    +pmcpl_gmon_initimage(struct pmcstat_image *pi)
    +{
    +	int count, nlen;
    +	char *sn;
    +	char name[NAME_MAX];
    +
    +	/*
    +	 * Look for a suitable name for the sample files associated
    +	 * with this image: if `basename(path)`+".gmon" is available,
    +	 * we use that, otherwise we try iterating through
    +	 * `basename(path)`+ "~" + NNN + ".gmon" till we get a free
    +	 * entry.
    +	 */
    +	if ((sn = basename(pmcstat_string_unintern(pi->pi_execpath))) == NULL)
    +		err(EX_OSERR, "ERROR: Cannot process \"%s\"",
    +		    pmcstat_string_unintern(pi->pi_execpath));
    +
    +	nlen = strlen(sn);
    +	nlen = min(nlen, (int) (sizeof(name) - sizeof(".gmon")));
    +
    +	snprintf(name, sizeof(name), "%.*s.gmon", nlen, sn);
    +
    +	/* try use the unabridged name first */
    +	if (pmcstat_string_lookup(name) == NULL)
    +		pi->pi_samplename = pmcstat_string_intern(name);
    +	else {
    +		/*
    +		 * Otherwise use a prefix from the original name and
    +		 * upto 3 digits.
    +		 */
    +		nlen = strlen(sn);
    +		nlen = min(nlen, (int) (sizeof(name)-sizeof("~NNN.gmon")));
    +		count = 0;
    +		do {
    +			if (++count > 999)
    +				errx(EX_CANTCREAT, "ERROR: cannot create a "
    +				    "gmon file for \"%s\"", name);
    +			snprintf(name, sizeof(name), "%.*s~%3.3d.gmon",
    +			    nlen, sn, count);
    +			if (pmcstat_string_lookup(name) == NULL) {
    +				pi->pi_samplename =
    +				    pmcstat_string_intern(name);
    +				count = 0;
    +			}
    +		} while (count > 0);
    +	}
    +
    +	LIST_INIT(&pi->pi_gmlist);
    +}
    +
    +void
    +pmcpl_gmon_shutdownimage(struct pmcstat_image *pi)
    +{
    +	struct pmcstat_gmonfile *pgf, *pgftmp;
    +
    +	LIST_FOREACH_SAFE(pgf, &pi->pi_gmlist, pgf_next, pgftmp) {
    +		if (pgf->pgf_file)
    +			(void) fclose(pgf->pgf_file);
    +		LIST_REMOVE(pgf, pgf_next);
    +		free(pgf);
    +	}
    +}
    +
    +void
    +pmcpl_gmon_newpmc(pmcstat_interned_string ps, struct pmcstat_pmcrecord *pr)
    +{
    +	struct stat st;
    +	char fullpath[PATH_MAX];
    +
    +	(void) pr;
    +
    +	/*
    +	 * Create the appropriate directory to hold gmon.out files.
    +	 */
    +
    +	(void) snprintf(fullpath, sizeof(fullpath), "%s/%s", args.pa_samplesdir,
    +	    pmcstat_string_unintern(ps));
    +
    +	/* If the path name exists, it should be a directory */
    +	if (stat(fullpath, &st) == 0 && S_ISDIR(st.st_mode))
    +		return;
    +
    +	if (mkdir(fullpath, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) < 0)
    +		err(EX_OSERR, "ERROR: Cannot create directory \"%s\"",
    +		    fullpath);
    +}
    +
    +/*
    + * Increment the bucket in the gmon.out file corresponding to 'pmcid'
    + * and 'pc'.
    + */
    +
    +void
    +pmcpl_gmon_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
    +    uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
    +{
    +	struct pmcstat_pcmap *map;
    +	struct pmcstat_image *image;
    +	struct pmcstat_gmonfile *pgf;
    +	uintfptr_t bucket;
    +	HISTCOUNTER *hc;
    +	pmc_id_t pmcid;
    +
    +	(void) nsamples; (void) usermode; (void) cpu;
    +
    +	map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[0]);
    +	if (map == NULL) {
    +		/* Unknown offset. */
    +		pmcstat_stats.ps_samples_unknown_offset++;
    +		return;
    +	}
    +
    +	assert(cc[0] >= map->ppm_lowpc && cc[0] < map->ppm_highpc);
    +
    +	image = map->ppm_image;
    +	pmcid = pmcr->pr_pmcid;
    +
    +	/*
    +	 * If this is the first time we are seeing a sample for
    +	 * this executable image, try determine its parameters.
    +	 */
    +	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
    +		pmcstat_image_determine_type(image);
    +
    +	assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN);
    +
    +	/* Ignore samples in images that we know nothing about. */
    +	if (image->pi_type == PMCSTAT_IMAGE_INDETERMINABLE) {
    +		pmcstat_stats.ps_samples_indeterminable++;
    +		return;
    +	}
    +
    +	/*
    +	 * Find the gmon file corresponding to 'pmcid', creating it if
    +	 * needed.
    +	 */
    +	pgf = pmcstat_image_find_gmonfile(image, pmcid);
    +	if (pgf == NULL) {
    +		if ((pgf = calloc(1, sizeof(*pgf))) == NULL)
    +			err(EX_OSERR, "ERROR:");
    +
    +		pgf->pgf_gmondata = NULL;	/* mark as unmapped */
    +		pgf->pgf_name = pmcstat_gmon_create_name(args.pa_samplesdir,
    +		    image, pmcid);
    +		pgf->pgf_pmcid = pmcid;
    +		assert(image->pi_end > image->pi_start);
    +		pgf->pgf_nbuckets = (image->pi_end - image->pi_start) /
    +		    FUNCTION_ALIGNMENT;	/* see  */
    +		pgf->pgf_ndatabytes = sizeof(struct gmonhdr) +
    +		    pgf->pgf_nbuckets * sizeof(HISTCOUNTER);
    +		pgf->pgf_nsamples = 0;
    +		pgf->pgf_file = NULL;
    +
    +		pmcstat_gmon_create_file(pgf, image);
    +
    +		LIST_INSERT_HEAD(&image->pi_gmlist, pgf, pgf_next);
    +	}
    +
    +	/*
    +	 * Map the gmon file in if needed.  It may have been mapped
    +	 * out under memory pressure.
    +	 */
    +	if (pgf->pgf_gmondata == NULL)
    +		pmcstat_gmon_map_file(pgf);
    +
    +	assert(pgf->pgf_gmondata != NULL);
    +
    +	/*
    +	 *
    +	 */
    +
    +	bucket = (cc[0] - map->ppm_lowpc) / FUNCTION_ALIGNMENT;
    +
    +	assert(bucket < pgf->pgf_nbuckets);
    +
    +	hc = (HISTCOUNTER *) ((uintptr_t) pgf->pgf_gmondata +
    +	    sizeof(struct gmonhdr));
    +
    +	/* saturating add */
    +	if (hc[bucket] < 0xFFFFU)  /* XXX tie this to sizeof(HISTCOUNTER) */
    +		hc[bucket]++;
    +	else /* mark that an overflow occurred */
    +		pgf->pgf_overflow = 1;
    +
    +	pgf->pgf_nsamples++;
    +}
    +
    +/*
    + * Shutdown module.
    + */
    +
    +void
    +pmcpl_gmon_shutdown(FILE *mf)
    +{
    +	int i;
    +	struct pmcstat_gmonfile *pgf;
    +	struct pmcstat_image *pi;
    +
    +	/*
    +	 * Sync back all gprof flat profile data.
    +	 */
    +	for (i = 0; i < PMCSTAT_NHASH; i++) {
    +		LIST_FOREACH(pi, &pmcstat_image_hash[i], pi_next) {
    +			if (mf)
    +				(void) fprintf(mf, " \"%s\" => \"%s\"",
    +				    pmcstat_string_unintern(pi->pi_execpath),
    +				    pmcstat_string_unintern(
    +				    pi->pi_samplename));
    +
    +			/* flush gmon.out data to disk */
    +			LIST_FOREACH(pgf, &pi->pi_gmlist, pgf_next) {
    +				pmcstat_gmon_unmap_file(pgf);
    +				if (mf)
    +					(void) fprintf(mf, " %s/%d",
    +					    pmcstat_pmcid_to_name(
    +					    pgf->pgf_pmcid),
    +					    pgf->pgf_nsamples);
    +				if (pgf->pgf_overflow && args.pa_verbosity >= 1)
    +					warnx("WARNING: profile \"%s\" "
    +					    "overflowed.",
    +					    pmcstat_string_unintern(
    +					        pgf->pgf_name));
    +			}
    +
    +			if (mf)
    +				(void) fprintf(mf, "\n");
    +		}
    +	}
    +
    +	/*
    +	 * Compute arcs and add these to the gprof files.
    +	 */
    +	if (args.pa_flags & FLAG_DO_GPROF && args.pa_graphdepth > 1)
    +		pmcstat_callgraph_do_gmon_arcs();
    +}
    diff --git a/usr.sbin/pmcstat/pmcpl_gprof.h b/usr.sbin/pmcstat/pmcpl_gprof.h
    new file mode 100644
    index 00000000000..069082fe3e2
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcpl_gprof.h
    @@ -0,0 +1,47 @@
    +/*-
    + * Copyright (c) 2005-2007, Joseph Koshy
    + * Copyright (c) 2007 The FreeBSD Foundation
    + * Copyright (c) 2009, Fabien Thomas
    + * All rights reserved.
    + *
    + * Portions of this software were developed by A. Joseph Koshy under
    + * sponsorship from the FreeBSD Foundation and 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.
    + *
    + * $FreeBSD$
    + */
    +
    +#ifndef	_PMCSTAT_PL_GPROF_H_
    +#define	_PMCSTAT_PL_GPROF_H_
    +
    +/* Function prototypes */
    +void pmcpl_gmon_shutdown(FILE *mf);
    +void pmcpl_gmon_process(
    +    struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
    +    uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
    +void pmcpl_gmon_initimage(struct pmcstat_image *pi);
    +void pmcpl_gmon_shutdownimage(struct pmcstat_image *pi);
    +void pmcpl_gmon_newpmc(pmcstat_interned_string ps,
    +	struct pmcstat_pmcrecord *pr);
    +
    +#endif	/* _PMCSTAT_PL_GPROF_H_ */
    diff --git a/usr.sbin/pmcstat/pmcstat.8 b/usr.sbin/pmcstat/pmcstat.8
    index a4e6f1f87a4..309eb3eae2d 100644
    --- a/usr.sbin/pmcstat/pmcstat.8
    +++ b/usr.sbin/pmcstat/pmcstat.8
    @@ -36,6 +36,7 @@
     .Op Fl C
     .Op Fl D Ar pathname
     .Op Fl E
    +.Op Fl F Ar pathname
     .Op Fl G Ar pathname
     .Op Fl M Ar mapfilename
     .Op Fl N
    @@ -43,9 +44,11 @@
     .Op Fl P Ar event-spec
     .Op Fl R Ar logfilename
     .Op Fl S Ar event-spec
    +.Op Fl T
     .Op Fl W
     .Op Fl c Ar cpu-spec
     .Op Fl d
    +.Op Fl f Ar pluginopt
     .Op Fl g
     .Op Fl k Ar kerneldir
     .Op Fl m Ar pathname
    @@ -129,6 +132,16 @@ complex pipeline of processes when used in conjunction with the
     .Fl d
     option.
     The default is to not to enable per-process tracking.
    +.It Fl F Ar pathname
    +Print calltree (Kcachegrind) information to file
    +.Ar pathname .
    +If argument
    +.Ar pathname
    +is a
    +.Dq Li -
    +this information is sent to the output file specified by the
    +.Fl o
    +option.
     .It Fl G Ar pathname
     Print callchain information to file
     .Ar pathname .
    @@ -195,6 +208,12 @@ Perform offline analysis using sampling data in file
     Allocate a system mode sampling PMC measuring hardware events
     specified in
     .Ar event-spec .
    +.It Fl T
    +Use a top like mode for sampling PMCs. The following hotkeys
    +can be used: 'c+a' switch to accumulative mode, 'c+d' switch
    +to delta mode, 'm' merge PMCs, 'n' change view, 'p' show next
    +PMC, ' ' pause, 'q' quit. calltree only: 'f' cost under threshold
    +is seen as a dot.
     .It Fl W
     Toggle logging the incremental counts seen by the threads of a
     tracked process each time they are scheduled on a CPU.
    @@ -218,6 +237,12 @@ Toggle between process mode PMCs measuring events for the target
     process' current and future children or only measuring events for
     the target process.
     The default is to measure events for the target process alone.
    +.It Fl f Ar pluginopt
    +Pass option string to the active plugin.
    +.br
    +threshold= do not display cost under specified value (Top).
    +.br
    +skiplink=0|1 replace node with cost under threshold by a dot (Top).
     .It Fl g
     Produce profiles in a format compatible with
     .Xr gprof 1 .
    @@ -286,7 +311,8 @@ regular expression for selecting processes based on their command names.
     .It Fl v
     Increase verbosity.
     .It Fl w Ar secs
    -Print the values of all counting mode PMCs every
    +Print the values of all counting mode PMCs or sampling mode PMCs
    +for top mode every
     .Ar secs
     seconds.
     The argument
    diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c
    index 6496ddbeb1a..a73d29380f1 100644
    --- a/usr.sbin/pmcstat/pmcstat.c
    +++ b/usr.sbin/pmcstat/pmcstat.c
    @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
     #include 
     
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -106,13 +107,15 @@ __FBSDID("$FreeBSD$");
     
     int	pmcstat_interrupt = 0;
     int	pmcstat_displayheight = DEFAULT_DISPLAY_HEIGHT;
    +int	pmcstat_displaywidth  = DEFAULT_DISPLAY_WIDTH;
     int	pmcstat_sockpair[NSOCKPAIRFD];
     int	pmcstat_kq;
     kvm_t	*pmcstat_kvm;
     struct kinfo_proc *pmcstat_plist;
    +struct pmcstat_args args;
     
     void
    -pmcstat_attach_pmcs(struct pmcstat_args *a)
    +pmcstat_attach_pmcs(void)
     {
     	struct pmcstat_ev *ev;
     	struct pmcstat_target *pt;
    @@ -120,10 +123,10 @@ pmcstat_attach_pmcs(struct pmcstat_args *a)
     
     	/* Attach all process PMCs to target processes. */
     	count = 0;
    -	STAILQ_FOREACH(ev, &a->pa_events, ev_next) {
    +	STAILQ_FOREACH(ev, &args.pa_events, ev_next) {
     		if (PMC_IS_SYSTEM_MODE(ev->ev_mode))
     			continue;
    -		SLIST_FOREACH(pt, &a->pa_targets, pt_next)
    +		SLIST_FOREACH(pt, &args.pa_targets, pt_next)
     			if (pmc_attach(ev->ev_pmcid, pt->pt_pid) == 0)
     				count++;
     			else if (errno != ESRCH)
    @@ -138,12 +141,12 @@ pmcstat_attach_pmcs(struct pmcstat_args *a)
     
     
     void
    -pmcstat_cleanup(struct pmcstat_args *a)
    +pmcstat_cleanup(void)
     {
     	struct pmcstat_ev *ev, *tmp;
     
     	/* release allocated PMCs. */
    -	STAILQ_FOREACH_SAFE(ev, &a->pa_events, ev_next, tmp)
    +	STAILQ_FOREACH_SAFE(ev, &args.pa_events, ev_next, tmp)
     	    if (ev->ev_pmcid != PMC_ID_INVALID) {
     		if (pmc_stop(ev->ev_pmcid) < 0)
     			err(EX_OSERR, "ERROR: cannot stop pmc 0x%x "
    @@ -153,25 +156,25 @@ pmcstat_cleanup(struct pmcstat_args *a)
     			    "0x%x \"%s\"", ev->ev_pmcid, ev->ev_name);
     		free(ev->ev_name);
     		free(ev->ev_spec);
    -		STAILQ_REMOVE(&a->pa_events, ev, pmcstat_ev, ev_next);
    +		STAILQ_REMOVE(&args.pa_events, ev, pmcstat_ev, ev_next);
     		free(ev);
     	    }
     
     	/* de-configure the log file if present. */
    -	if (a->pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE))
    +	if (args.pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE))
     		(void) pmc_configure_logfile(-1);
     
    -	if (a->pa_logparser) {
    -		pmclog_close(a->pa_logparser);
    -		a->pa_logparser = NULL;
    +	if (args.pa_logparser) {
    +		pmclog_close(args.pa_logparser);
    +		args.pa_logparser = NULL;
     	}
     
    -	if (a->pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE))
    -		pmcstat_shutdown_logging(a);
    +	if (args.pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE))
    +		pmcstat_shutdown_logging();
     }
     
     void
    -pmcstat_clone_event_descriptor(struct pmcstat_args *a, struct pmcstat_ev *ev,
    +pmcstat_clone_event_descriptor(struct pmcstat_ev *ev,
         uint32_t cpumask)
     {
     	int cpu;
    @@ -194,14 +197,14 @@ pmcstat_clone_event_descriptor(struct pmcstat_args *a, struct pmcstat_ev *ev,
     		ev_clone->ev_saved = ev->ev_saved;
     		ev_clone->ev_spec  = strdup(ev->ev_spec);
     
    -		STAILQ_INSERT_TAIL(&a->pa_events, ev_clone, ev_next);
    +		STAILQ_INSERT_TAIL(&args.pa_events, ev_clone, ev_next);
     
     		cpumask &= ~(1 << cpu);
     	}
     }
     
     void
    -pmcstat_create_process(struct pmcstat_args *a)
    +pmcstat_create_process(void)
     {
     	char token;
     	pid_t pid;
    @@ -229,10 +232,10 @@ pmcstat_create_process(struct pmcstat_args *a)
     		(void) close(pmcstat_sockpair[CHILDSOCKET]);
     
     		/* exec() the program requested */
    -		execvp(*a->pa_argv, a->pa_argv);
    +		execvp(*args.pa_argv, args.pa_argv);
     		/* and if that fails, notify the parent */
     		kill(getppid(), SIGCHLD);
    -		err(EX_OSERR, "ERROR: execvp \"%s\" failed", *a->pa_argv);
    +		err(EX_OSERR, "ERROR: execvp \"%s\" failed", *args.pa_argv);
     		/*NOTREACHED*/
     
     	default:	/* parent */
    @@ -250,7 +253,7 @@ pmcstat_create_process(struct pmcstat_args *a)
     		errx(EX_SOFTWARE, "ERROR: Out of memory.");
     
     	pt->pt_pid = pid;
    -	SLIST_INSERT_HEAD(&a->pa_targets, pt, pt_next);
    +	SLIST_INSERT_HEAD(&args.pa_targets, pt, pt_next);
     
     	/* Wait for the child to signal that its ready to go. */
     	if (read(pmcstat_sockpair[PARENTSOCKET], &token, 1) < 0)
    @@ -260,7 +263,7 @@ pmcstat_create_process(struct pmcstat_args *a)
     }
     
     void
    -pmcstat_find_targets(struct pmcstat_args *a, const char *spec)
    +pmcstat_find_targets(const char *spec)
     {
     	int n, nproc, pid, rv;
     	struct pmcstat_target *pt;
    @@ -275,7 +278,7 @@ pmcstat_find_targets(struct pmcstat_args *a, const char *spec)
     		if ((pt = malloc(sizeof(*pt))) == NULL)
     			goto outofmemory;
     		pt->pt_pid = pid;
    -		SLIST_INSERT_HEAD(&a->pa_targets, pt, pt_next);
    +		SLIST_INSERT_HEAD(&args.pa_targets, pt, pt_next);
     		return;
     	}
     
    @@ -302,7 +305,7 @@ pmcstat_find_targets(struct pmcstat_args *a, const char *spec)
     			if ((pt = malloc(sizeof(*pt))) == NULL)
     				goto outofmemory;
     			pt->pt_pid = kp->ki_pid;
    -			SLIST_INSERT_HEAD(&a->pa_targets, pt, pt_next);
    +			SLIST_INSERT_HEAD(&args.pa_targets, pt, pt_next);
     		} else if (rv != REG_NOMATCH) {
     			regerror(rv, ®, errbuf, sizeof(errbuf));
     			errx(EX_SOFTWARE, "ERROR: Regex evalation failed: %s",
    @@ -343,17 +346,17 @@ pmcstat_get_cpumask(const char *cpuspec)
     }
     
     void
    -pmcstat_kill_process(struct pmcstat_args *a)
    +pmcstat_kill_process(void)
     {
     	struct pmcstat_target *pt;
     
    -	assert(a->pa_flags & FLAG_HAS_COMMANDLINE);
    +	assert(args.pa_flags & FLAG_HAS_COMMANDLINE);
     
     	/*
     	 * If a command line was specified, it would be the very first
     	 * in the list, before any other processes specified by -t.
     	 */
    -	pt = SLIST_FIRST(&a->pa_targets);
    +	pt = SLIST_FIRST(&args.pa_targets);
     	assert(pt != NULL);
     
     	if (kill(pt->pt_pid, SIGINT) != 0)
    @@ -361,7 +364,7 @@ pmcstat_kill_process(struct pmcstat_args *a)
     }
     
     void
    -pmcstat_start_pmcs(struct pmcstat_args *a)
    +pmcstat_start_pmcs(void)
     {
     	struct pmcstat_ev *ev;
     
    @@ -372,7 +375,7 @@ pmcstat_start_pmcs(struct pmcstat_args *a)
     	    if (pmc_start(ev->ev_pmcid) < 0) {
     	        warn("ERROR: Cannot start pmc 0x%x \"%s\"",
     		    ev->ev_pmcid, ev->ev_name);
    -		pmcstat_cleanup(a);
    +		pmcstat_cleanup();
     		exit(EX_OSERR);
     	    }
     	}
    @@ -380,37 +383,37 @@ pmcstat_start_pmcs(struct pmcstat_args *a)
     }
     
     void
    -pmcstat_print_headers(struct pmcstat_args *a)
    +pmcstat_print_headers(void)
     {
     	struct pmcstat_ev *ev;
     	int c, w;
     
    -	(void) fprintf(a->pa_printfile, PRINT_HEADER_PREFIX);
    +	(void) fprintf(args.pa_printfile, PRINT_HEADER_PREFIX);
     
    -	STAILQ_FOREACH(ev, &a->pa_events, ev_next) {
    +	STAILQ_FOREACH(ev, &args.pa_events, ev_next) {
     		if (PMC_IS_SAMPLING_MODE(ev->ev_mode))
     			continue;
     
     		c = PMC_IS_SYSTEM_MODE(ev->ev_mode) ? 's' : 'p';
     
     		if (ev->ev_fieldskip != 0)
    -			(void) fprintf(a->pa_printfile, "%*s",
    +			(void) fprintf(args.pa_printfile, "%*s",
     			    ev->ev_fieldskip, "");
     		w = ev->ev_fieldwidth - ev->ev_fieldskip - 2;
     
     		if (c == 's')
    -			(void) fprintf(a->pa_printfile, "s/%02d/%-*s ",
    +			(void) fprintf(args.pa_printfile, "s/%02d/%-*s ",
     			    ev->ev_cpu, w-3, ev->ev_name);
     		else
    -			(void) fprintf(a->pa_printfile, "p/%*s ", w,
    +			(void) fprintf(args.pa_printfile, "p/%*s ", w,
     			    ev->ev_name);
     	}
     
    -	(void) fflush(a->pa_printfile);
    +	(void) fflush(args.pa_printfile);
     }
     
     void
    -pmcstat_print_counters(struct pmcstat_args *a)
    +pmcstat_print_counters(void)
     {
     	int extra_width;
     	struct pmcstat_ev *ev;
    @@ -418,7 +421,7 @@ pmcstat_print_counters(struct pmcstat_args *a)
     
     	extra_width = sizeof(PRINT_HEADER_PREFIX) - 1;
     
    -	STAILQ_FOREACH(ev, &a->pa_events, ev_next) {
    +	STAILQ_FOREACH(ev, &args.pa_events, ev_next) {
     
     		/* skip sampling mode counters */
     		if (PMC_IS_SAMPLING_MODE(ev->ev_mode))
    @@ -428,7 +431,7 @@ pmcstat_print_counters(struct pmcstat_args *a)
     			err(EX_OSERR, "ERROR: Cannot read pmc "
     			    "\"%s\"", ev->ev_name);
     
    -		(void) fprintf(a->pa_printfile, "%*ju ",
    +		(void) fprintf(args.pa_printfile, "%*ju ",
     		    ev->ev_fieldwidth + extra_width,
     		    (uintmax_t) ev->ev_cumulative ? value :
     		    (value - ev->ev_saved));
    @@ -438,7 +441,7 @@ pmcstat_print_counters(struct pmcstat_args *a)
     		extra_width = 0;
     	}
     
    -	(void) fflush(a->pa_printfile);
    +	(void) fflush(args.pa_printfile);
     }
     
     /*
    @@ -446,20 +449,20 @@ pmcstat_print_counters(struct pmcstat_args *a)
      */
     
     void
    -pmcstat_print_pmcs(struct pmcstat_args *a)
    +pmcstat_print_pmcs(void)
     {
     	static int linecount = 0;
     
     	/* check if we need to print a header line */
     	if (++linecount > pmcstat_displayheight) {
    -		(void) fprintf(a->pa_printfile, "\n");
    +		(void) fprintf(args.pa_printfile, "\n");
     		linecount = 1;
     	}
     	if (linecount == 1)
    -		pmcstat_print_headers(a);
    -	(void) fprintf(a->pa_printfile, "\n");
    +		pmcstat_print_headers();
    +	(void) fprintf(args.pa_printfile, "\n");
     
    -	pmcstat_print_counters(a);
    +	pmcstat_print_counters();
     
     	return;
     }
    @@ -493,6 +496,8 @@ pmcstat_show_usage(void)
     	    "\t -C\t\t (toggle) show cumulative counts\n"
     	    "\t -D path\t create profiles in directory \"path\"\n"
     	    "\t -E\t\t (toggle) show counts at process exit\n"
    +	    "\t -F file\t write a system-wide callgraph (Kcachegrind format)"
    +		" to \"file\"\n"
     	    "\t -G file\t write a system-wide callgraph to \"file\"\n"
     	    "\t -M file\t print executable/gmon file map to \"file\"\n"
     	    "\t -N\t\t (toggle) capture callchains\n"
    @@ -500,9 +505,11 @@ pmcstat_show_usage(void)
     	    "\t -P spec\t allocate a process-private sampling PMC\n"
     	    "\t -R file\t read events from \"file\"\n"
     	    "\t -S spec\t allocate a system-wide sampling PMC\n"
    +	    "\t -T\t\t start in top mode\n"
     	    "\t -W\t\t (toggle) show counts per context switch\n"
     	    "\t -c cpu-list\t set cpus for subsequent system-wide PMCs\n"
     	    "\t -d\t\t (toggle) track descendants\n"
    +	    "\t -f spec\t pass \"spec\" to as plugin option\n"
     	    "\t -g\t\t produce gprof(1) compatible profiles\n"
     	    "\t -k dir\t\t set the path to the kernel\n"
     	    "\t -n rate\t set sampling rate\n"
    @@ -519,6 +526,24 @@ pmcstat_show_usage(void)
     	);
     }
     
    +/*
    + * At exit handler for top mode
    + */
    +
    +void
    +pmcstat_topexit(void)
    +{
    +	if (!args.pa_toptty)
    +		return;
    +
    +	/*
    +	 * Shutdown ncurses.
    +	 */
    +	clrtoeol();
    +	refresh();
    +	endwin();
    +}
    +
     /*
      * Main
      */
    @@ -535,6 +560,7 @@ main(int argc, char **argv)
     	int graphdepth;
     	int pipefd[2];
     	int use_cumulative_counts;
    +	short cf, cb;
     	uint32_t cpumask;
     	char *end, *tmp;
     	const char *errmsg, *graphfilename;
    @@ -570,6 +596,13 @@ main(int argc, char **argv)
     	args.pa_mapfilename	= NULL;
     	args.pa_inputpath	= NULL;
     	args.pa_outputpath	= NULL;
    +	args.pa_pplugin		= PMCSTAT_PL_NONE;
    +	args.pa_plugin		= PMCSTAT_PL_NONE;
    +	args.pa_ctdumpinstr	= 1;
    +	args.pa_topmode		= PMCSTAT_TOP_DELTA;
    +	args.pa_toptty		= 0;
    +	args.pa_topcolor	= 0;
    +	args.pa_mergepmc	= 0;
     	STAILQ_INIT(&args.pa_events);
     	SLIST_INIT(&args.pa_targets);
     	bzero(&ds_start, sizeof(ds_start));
    @@ -594,7 +627,7 @@ main(int argc, char **argv)
     	}
     
     	while ((option = getopt(argc, argv,
    -	    "CD:EG:M:NO:P:R:S:Wc:dgk:m:n:o:p:qr:s:t:vw:z:")) != -1)
    +	    "CD:EF:G:M:NO:P:R:S:TWc:df:gk:m:n:o:p:qr:s:t:vw:z:")) != -1)
     		switch (option) {
     		case 'C':	/* cumulative values */
     			use_cumulative_counts = !use_cumulative_counts;
    @@ -628,13 +661,28 @@ main(int argc, char **argv)
     			args.pa_required |= FLAG_HAS_PROCESS_PMCS;
     			break;
     
    +		case 'F':	/* produce a system-wide calltree */
    +			args.pa_flags |= FLAG_DO_CALLGRAPHS;
    +			args.pa_plugin = PMCSTAT_PL_CALLTREE;
    +			graphfilename = optarg;
    +			break;
    +
    +		case 'f':	/* plugins options */
    +			if (args.pa_plugin == PMCSTAT_PL_NONE)
    +				err(EX_USAGE, "ERROR: Need -g/-G/-m/-T.");
    +			pmcstat_pluginconfigure_log(optarg);
    +			break;
    +
     		case 'G':	/* produce a system-wide callgraph */
     			args.pa_flags |= FLAG_DO_CALLGRAPHS;
    +			args.pa_plugin = PMCSTAT_PL_CALLGRAPH;
     			graphfilename = optarg;
     			break;
     
     		case 'g':	/* produce gprof compatible profiles */
     			args.pa_flags |= FLAG_DO_GPROF;
    +			args.pa_pplugin = PMCSTAT_PL_CALLGRAPH;
    +			args.pa_plugin	= PMCSTAT_PL_GPROF;
     			break;
     
     		case 'k':	/* pathname to the kernel */
    @@ -645,8 +693,9 @@ main(int argc, char **argv)
     			break;
     
     		case 'm':
    -			args.pa_flags |= FLAG_WANTS_MAPPINGS;
    -			graphfilename = optarg;
    +			args.pa_flags |= FLAG_DO_ANNOTATE;
    +			args.pa_plugin = PMCSTAT_PL_ANNOTATE;
    +			graphfilename  = optarg;
     			break;
     
     		case 'E':	/* log process exit */
    @@ -732,7 +781,7 @@ main(int argc, char **argv)
     			STAILQ_INSERT_TAIL(&args.pa_events, ev, ev_next);
     
     			if (option == 's' || option == 'S')
    -				pmcstat_clone_event_descriptor(&args, ev,
    +				pmcstat_clone_event_descriptor(ev,
     				    cpumask & ~(1 << ev->ev_cpu));
     
     			break;
    @@ -782,12 +831,21 @@ main(int argc, char **argv)
     			break;
     
     		case 't':	/* target pid or process name */
    -			pmcstat_find_targets(&args, optarg);
    +			pmcstat_find_targets(optarg);
     
     			args.pa_flags |= FLAG_HAS_TARGET;
     			args.pa_required |= FLAG_HAS_PROCESS_PMCS;
     			break;
     
    +		case 'T':	/* top mode */
    +			args.pa_flags |= FLAG_DO_TOP;
    +			args.pa_plugin = PMCSTAT_PL_CALLGRAPH;
    +			args.pa_ctdumpinstr = 0;
    +			args.pa_mergepmc = 1;
    +			if (args.pa_printfile == stderr)
    +				args.pa_printfile = stdout;
    +			break;
    +
     		case 'v':	/* verbose */
     			args.pa_verbosity++;
     			break;
    @@ -798,7 +856,6 @@ main(int argc, char **argv)
     				errx(EX_USAGE, "ERROR: Illegal wait interval "
     				    "value \"%s\".", optarg);
     			args.pa_flags |= FLAG_HAS_WAIT_INTERVAL;
    -			args.pa_required |= FLAG_HAS_COUNTING_PMCS;
     			args.pa_interval = interval;
     			break;
     
    @@ -833,7 +890,7 @@ main(int argc, char **argv)
     		args.pa_flags |= FLAG_HAS_COMMANDLINE;
     
     	if (args.pa_flags & (FLAG_DO_GPROF | FLAG_DO_CALLGRAPHS |
    -	    FLAG_WANTS_MAPPINGS))
    +	    FLAG_DO_ANNOTATE | FLAG_DO_TOP))
     		args.pa_flags |= FLAG_DO_ANALYSIS;
     
     	/*
    @@ -846,11 +903,11 @@ main(int argc, char **argv)
     		    "exclusive.");
     
     	/* -m option is allowed with -R only. */
    -	if (args.pa_flags & FLAG_WANTS_MAPPINGS && args.pa_inputpath == NULL)
    +	if (args.pa_flags & FLAG_DO_ANNOTATE && args.pa_inputpath == NULL)
     		errx(EX_USAGE, "ERROR: option -m requires an input file");
     
     	/* -m option is not allowed combined with -g or -G. */
    -	if (args.pa_flags & FLAG_WANTS_MAPPINGS &&
    +	if (args.pa_flags & FLAG_DO_ANNOTATE &&
     	    args.pa_flags & (FLAG_DO_GPROF | FLAG_DO_CALLGRAPHS))
     		errx(EX_USAGE, "ERROR: option -m and -g | -G are mutually "
     		    "exclusive");
    @@ -904,7 +961,7 @@ main(int argc, char **argv)
     	/* check for counting mode options without a counting PMC */
     	if ((args.pa_required & FLAG_HAS_COUNTING_PMCS) &&
     	    (args.pa_flags & FLAG_HAS_COUNTING_PMCS) == 0)
    -		errx(EX_USAGE, "ERROR: options -C, -W, -o and -w require at "
    +		errx(EX_USAGE, "ERROR: options -C, -W and -o require at "
     		    "least one counting mode PMC to be specified.");
     
     	/* check for sampling mode options without a sampling PMC spec */
    @@ -913,10 +970,10 @@ main(int argc, char **argv)
     		errx(EX_USAGE, "ERROR: options -N, -n and -O require at "
     		    "least one sampling mode PMC to be specified.");
     
    -	/* check if -g/-G are being used correctly */
    +	/* check if -g/-G/-m/-T are being used correctly */
     	if ((args.pa_flags & FLAG_DO_ANALYSIS) &&
     	    !(args.pa_flags & (FLAG_HAS_SAMPLING_PMCS|FLAG_READ_LOGFILE)))
    -		errx(EX_USAGE, "ERROR: options -g/-G require sampling PMCs "
    +		errx(EX_USAGE, "ERROR: options -g/-G/-m/-T require sampling PMCs "
     		    "or -R to be specified.");
     
     	/* check if -O was spuriously specified */
    @@ -926,11 +983,11 @@ main(int argc, char **argv)
     		    "ERROR: option -O is used only with options "
     		    "-E, -P, -S and -W.");
     
    -	/* -k kernel path require -g/-G or -R */
    +	/* -k kernel path require -g/-G/-m/-T or -R */
     	if ((args.pa_flags & FLAG_HAS_KERNELPATH) &&
     	    (args.pa_flags & FLAG_DO_ANALYSIS) == 0 &&
     	    (args.pa_flags & FLAG_READ_LOGFILE) == 0)
    -	    errx(EX_USAGE, "ERROR: option -k is only used with -g/-R.");
    +	    errx(EX_USAGE, "ERROR: option -k is only used with -g/-R/-m/-T.");
     
     	/* -D only applies to gprof output mode (-g) */
     	if ((args.pa_flags & FLAG_HAS_SAMPLESDIR) &&
    @@ -943,6 +1000,11 @@ main(int argc, char **argv)
     	    (args.pa_flags & FLAG_READ_LOGFILE) == 0)
     	    errx(EX_USAGE, "ERROR: option -M is only used with -g/-R.");
     
    +	/* -T is incompatible with -R (replay logfile is a TODO) */
    +	if ((args.pa_flags & FLAG_DO_TOP) &&
    +	    (args.pa_flags & FLAG_READ_LOGFILE))
    +		errx(EX_USAGE, "ERROR: option -T is incompatible with -R.");
    +
     	/*
     	 * Disallow textual output of sampling PMCs if counting PMCs
     	 * have also been asked for, mostly because the combined output
    @@ -996,7 +1058,7 @@ main(int argc, char **argv)
     				    "for writing", graphfilename);
     		}
     	}
    -	if (args.pa_flags & FLAG_WANTS_MAPPINGS) {
    +	if (args.pa_flags & FLAG_DO_ANNOTATE) {
     		args.pa_graphfile = fopen(graphfilename, "w");
     		if (args.pa_graphfile == NULL)
     			err(EX_OSERR, "ERROR: cannot open \"%s\" for writing",
    @@ -1012,13 +1074,13 @@ main(int argc, char **argv)
     		if ((args.pa_flags & FLAG_DO_ANALYSIS) == 0)
     			args.pa_flags |= FLAG_DO_PRINT;
     
    -		pmcstat_initialize_logging(&args);
    +		pmcstat_initialize_logging();
     		args.pa_logfd = pmcstat_open_log(args.pa_inputpath,
     		    PMCSTAT_OPEN_FOR_READ);
     		if ((args.pa_logparser = pmclog_open(args.pa_logfd)) == NULL)
     			err(EX_OSERR, "ERROR: Cannot create parser");
    -		pmcstat_process_log(&args);
    -		pmcstat_shutdown_logging(&args);
    +		pmcstat_process_log();
    +		pmcstat_shutdown_logging();
     		exit(EX_OK);
     	}
     
    @@ -1062,7 +1124,9 @@ main(int argc, char **argv)
     
     			args.pa_logfd = pipefd[WRITEPIPEFD];
     
    -			args.pa_flags |= (FLAG_HAS_PIPE | FLAG_DO_PRINT);
    +			args.pa_flags |= FLAG_HAS_PIPE;
    +			if ((args.pa_flags & FLAG_DO_TOP) == 0)
    +				args.pa_flags |= FLAG_DO_PRINT;
     			args.pa_logparser = pmclog_open(pipefd[READPIPEFD]);
     		}
     
    @@ -1126,12 +1190,24 @@ main(int argc, char **argv)
     			err(EX_OSERR, "ERROR: Cannot determine window size");
     
     		pmcstat_displayheight = ws.ws_row - 1;
    +		pmcstat_displaywidth  = ws.ws_col - 1;
     
     		EV_SET(&kev, SIGWINCH, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
     
     		if (kevent(pmcstat_kq, &kev, 1, NULL, 0, NULL) < 0)
     			err(EX_OSERR, "ERROR: Cannot register kevent for "
     			    "SIGWINCH");
    +
    +		args.pa_toptty = 1;
    +	}
    +
    +	/*
    +	 * Listen to key input in top mode.
    +	 */
    +	if (args.pa_flags & FLAG_DO_TOP) {
    +		EV_SET(&kev, fileno(stdin), EVFILT_READ, EV_ADD, 0, 0, NULL);
    +		if (kevent(pmcstat_kq, &kev, 1, NULL, 0, NULL) < 0)
    +			err(EX_OSERR, "ERROR: Cannot register kevent");
     	}
     
     	EV_SET(&kev, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
    @@ -1152,9 +1228,13 @@ main(int argc, char **argv)
     	if (kevent(pmcstat_kq, &kev, 1, NULL, 0, NULL) < 0)
     		err(EX_OSERR, "ERROR: Cannot register kevent for SIGCHLD");
     
    -	/* setup a timer if we have counting mode PMCs needing to be printed */
    -	if ((args.pa_flags & FLAG_HAS_COUNTING_PMCS) &&
    -	    (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) {
    +	/* 
    +	 * Setup a timer if we have counting mode PMCs needing to be printed or
    +	 * top mode plugin is active.
    +	 */
    +	if (((args.pa_flags & FLAG_HAS_COUNTING_PMCS) &&
    +	     (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) ||
    +	    (args.pa_flags & FLAG_DO_TOP)) {
     		EV_SET(&kev, 0, EVFILT_TIMER, EV_ADD, 0,
     		    args.pa_interval * 1000, NULL);
     
    @@ -1165,7 +1245,7 @@ main(int argc, char **argv)
     
     	/* attach PMCs to the target process, starting it if specified */
     	if (args.pa_flags & FLAG_HAS_COMMANDLINE)
    -		pmcstat_create_process(&args);
    +		pmcstat_create_process();
     
     	if (check_driver_stats && pmc_get_driver_stats(&ds_start) < 0)
     		err(EX_OSERR, "ERROR: Cannot retrieve driver statistics");
    @@ -1176,7 +1256,7 @@ main(int argc, char **argv)
     			errx(EX_DATAERR, "ERROR: No matching target "
     			    "processes.");
     		if (args.pa_flags & FLAG_HAS_PROCESS_PMCS)
    -			pmcstat_attach_pmcs(&args);
    +			pmcstat_attach_pmcs();
     
     		if (pmcstat_kvm) {
     			kvm_close(pmcstat_kvm);
    @@ -1185,16 +1265,16 @@ main(int argc, char **argv)
     	}
     
     	/* start the pmcs */
    -	pmcstat_start_pmcs(&args);
    +	pmcstat_start_pmcs();
     
     	/* start the (commandline) process if needed */
     	if (args.pa_flags & FLAG_HAS_COMMANDLINE)
     		pmcstat_start_process();
     
     	/* initialize logging if printing the configured log */
    -	if ((args.pa_flags & FLAG_DO_PRINT) &&
    +	if ((args.pa_flags & (FLAG_DO_PRINT | FLAG_DO_TOP)) &&
     	    (args.pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE)))
    -		pmcstat_initialize_logging(&args);
    +		pmcstat_initialize_logging();
     
     	/* Handle SIGINT using the kqueue loop */
     	sa.sa_handler = SIG_IGN;
    @@ -1204,6 +1284,37 @@ main(int argc, char **argv)
     	if (sigaction(SIGINT, &sa, NULL) < 0)
     		err(EX_OSERR, "ERROR: Cannot install signal handler");
     
    +	/*
    +	 * Setup the top mode display.
    +	 */
    +	if (args.pa_flags & FLAG_DO_TOP) {
    +		args.pa_flags &= ~FLAG_DO_PRINT;
    +
    +		if (args.pa_toptty) {
    +			/*
    +			 * Init ncurses.
    +			 */
    +			initscr();
    +			if(has_colors() == TRUE) {
    +				args.pa_topcolor = 1;
    +				start_color();
    +				use_default_colors();
    +				pair_content(0, &cf, &cb);
    +				init_pair(1, COLOR_RED, cb);
    +				init_pair(2, COLOR_YELLOW, cb);
    +				init_pair(3, COLOR_GREEN, cb);
    +			}
    +			cbreak();
    +			noecho();
    +			nonl();
    +			nodelay(stdscr, 1);
    +			intrflush(stdscr, FALSE);
    +			keypad(stdscr, TRUE);
    +			clear();
    +			atexit(pmcstat_topexit);
    +		}
    +	}
    +
     	/*
     	 * loop till either the target process (if any) exits, or we
     	 * are killed by a SIGINT.
    @@ -1225,14 +1336,18 @@ main(int argc, char **argv)
     		case EVFILT_PROC:  /* target has exited */
     			if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE |
     				FLAG_HAS_PIPE))
    -				runstate = pmcstat_close_log(&args);
    +				runstate = pmcstat_close_log();
     			else
     				runstate = PMCSTAT_FINISHED;
     			do_print = 1;
     			break;
     
     		case EVFILT_READ:  /* log file data is present */
    -			runstate = pmcstat_process_log(&args);
    +			if (kev.ident == (unsigned)fileno(stdin)) {
    +				if (pmcstat_keypress_log())
    +					runstate = pmcstat_close_log();
    +			} else
    +				runstate = pmcstat_process_log();
     			break;
     
     		case EVFILT_SIGNAL:
    @@ -1253,17 +1368,17 @@ main(int argc, char **argv)
     				 */
     				if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE |
     				    FLAG_HAS_PIPE)) {
    -					runstate = pmcstat_close_log(&args);
    +					runstate = pmcstat_close_log();
     					if (args.pa_flags &
     					    (FLAG_DO_PRINT|FLAG_DO_ANALYSIS))
    -						pmcstat_process_log(&args);
    +						pmcstat_process_log();
     				}
     				do_print = 1; /* print PMCs at exit */
     				runstate = PMCSTAT_FINISHED;
     			} else if (kev.ident == SIGINT) {
     				/* Kill the child process if we started it */
     				if (args.pa_flags & FLAG_HAS_COMMANDLINE)
    -					pmcstat_kill_process(&args);
    +					pmcstat_kill_process();
     				/* Close the pipe to self, if present. */
     				if (args.pa_flags & FLAG_HAS_PIPE)
     					(void) close(pipefd[READPIPEFD]);
    @@ -1274,6 +1389,7 @@ main(int argc, char **argv)
     				    err(EX_OSERR, "ERROR: Cannot determine "
     					"window size");
     				pmcstat_displayheight = ws.ws_row - 1;
    +				pmcstat_displaywidth  = ws.ws_col - 1;
     			} else
     				assert(0);
     
    @@ -1285,22 +1401,30 @@ main(int argc, char **argv)
     
     		}
     
    -		if (do_print &&
    -		    (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) {
    -			pmcstat_print_pmcs(&args);
    -			if (runstate == PMCSTAT_FINISHED && /* final newline */
    -			    (args.pa_flags & FLAG_DO_PRINT) == 0)
    -				(void) fprintf(args.pa_printfile, "\n");
    +		if (do_print) {
    +			if ((args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) {
    +				pmcstat_print_pmcs();
    +				if (runstate == PMCSTAT_FINISHED && /* final newline */
    +				    (args.pa_flags & FLAG_DO_PRINT) == 0)
    +					(void) fprintf(args.pa_printfile, "\n");
    +			}
    +			if (args.pa_flags & FLAG_DO_TOP)
    +				pmcstat_display_log();
     			do_print = 0;
     		}
     
     	} while (runstate != PMCSTAT_FINISHED);
     
    +	if ((args.pa_flags & FLAG_DO_TOP) && args.pa_toptty) {
    +		pmcstat_topexit();
    +		args.pa_toptty = 0;
    +	}
    +
     	/* flush any pending log entries */
     	if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE))
     		pmc_flush_logfile();
     
    -	pmcstat_cleanup(&args);
    +	pmcstat_cleanup();
     
     	free(args.pa_kernel);
     
    diff --git a/usr.sbin/pmcstat/pmcstat.h b/usr.sbin/pmcstat/pmcstat.h
    index 5d6f5f296e2..1bb78627d6d 100644
    --- a/usr.sbin/pmcstat/pmcstat.h
    +++ b/usr.sbin/pmcstat/pmcstat.h
    @@ -47,13 +47,15 @@
     #define	FLAG_HAS_SAMPLESDIR		0x00000800	/* -D dir */
     #define	FLAG_HAS_KERNELPATH		0x00001000	/* -k kernel */
     #define	FLAG_DO_PRINT			0x00002000	/* -o */
    -#define	FLAG_DO_CALLGRAPHS		0x00004000	/* -G */
    -#define	FLAG_DO_ANALYSIS		0x00008000	/* -g or -G */
    -#define	FLAG_WANTS_MAPPINGS		0x00010000	/* -m */
    +#define	FLAG_DO_CALLGRAPHS		0x00004000	/* -G or -F */
    +#define	FLAG_DO_ANNOTATE		0x00008000	/* -m */
    +#define	FLAG_DO_TOP			0x00010000	/* -T */
    +#define	FLAG_DO_ANALYSIS		0x00020000	/* -g or -G or -m or -T */
     
     #define	DEFAULT_SAMPLE_COUNT		65536
     #define	DEFAULT_WAIT_INTERVAL		5.0
    -#define	DEFAULT_DISPLAY_HEIGHT		23
    +#define	DEFAULT_DISPLAY_HEIGHT		256		/* file virtual height */
    +#define	DEFAULT_DISPLAY_WIDTH		1024		/* file virtual width */
     #define	DEFAULT_BUFFER_SIZE		4096
     #define	DEFAULT_CALLGRAPH_DEPTH		4
     
    @@ -75,12 +77,24 @@
     
     #define	PMCSTAT_LDD_COMMAND		"/usr/bin/ldd"
     
    -#define	PMCSTAT_PRINT_ENTRY(A,T,...) do {				\
    -		(void) fprintf((A)->pa_printfile, "%-9s", T);		\
    -		(void) fprintf((A)->pa_printfile, " "  __VA_ARGS__);	\
    -		(void) fprintf((A)->pa_printfile, "\n");		\
    +#define	PMCSTAT_PRINT_ENTRY(T,...) do {					\
    +		(void) fprintf(args.pa_printfile, "%-9s", T);		\
    +		(void) fprintf(args.pa_printfile, " "  __VA_ARGS__);	\
    +		(void) fprintf(args.pa_printfile, "\n");		\
     	} while (0)
     
    +#define PMCSTAT_PL_NONE		0
    +#define PMCSTAT_PL_CALLGRAPH	1
    +#define PMCSTAT_PL_GPROF	2
    +#define PMCSTAT_PL_ANNOTATE	3
    +#define PMCSTAT_PL_CALLTREE	4
    +
    +#define PMCSTAT_TOP_DELTA 	0
    +#define PMCSTAT_TOP_ACCUM	1
    +
    +#define	min(A,B)		((A) < (B) ? (A) : (B))
    +#define	max(A,B)		((A) > (B) ? (A) : (B))
    +
     enum pmcstat_state {
     	PMCSTAT_FINISHED = 0,
     	PMCSTAT_EXITING  = 1,
    @@ -110,6 +124,8 @@ struct pmcstat_target {
     struct pmcstat_args {
     	int	pa_flags;		/* argument flags */
     	int	pa_required;		/* required features */
    +	int	pa_pplugin;		/* pre-processing plugin */
    +	int	pa_plugin;		/* analysis plugin */
     	int	pa_verbosity;		/* verbosity level */
     	FILE	*pa_printfile;		/* where to send printed output */
     	int	pa_logfd;		/* output log file */
    @@ -124,31 +140,44 @@ struct pmcstat_args {
     	int	pa_graphdepth;		/* print depth for callgraphs */
     	double	pa_interval;		/* printing interval in seconds */
     	uint32_t pa_cpumask;		/* filter for CPUs analysed */
    +	int	pa_ctdumpinstr;		/* dump instructions with calltree */
    +	int	pa_topmode;		/* delta or accumulative */
    +	int	pa_toptty;		/* output to tty or file */
    +	int	pa_topcolor;		/* terminal support color */
    +	int	pa_mergepmc;		/* merge PMC with same name */
     	int	pa_argc;
     	char	**pa_argv;
     	STAILQ_HEAD(, pmcstat_ev) pa_events;
     	SLIST_HEAD(, pmcstat_target) pa_targets;
    -} args;
    +};
    +
    +extern int pmcstat_displayheight;	/* current terminal height */
    +extern int pmcstat_displaywidth;	/* current terminal width */
    +extern struct pmcstat_args args;	/* command line args */
     
     /* Function prototypes */
    -void	pmcstat_attach_pmcs(struct pmcstat_args *_a);
    -void	pmcstat_cleanup(struct pmcstat_args *_a);
    -void	pmcstat_clone_event_descriptor(struct pmcstat_args *_a,
    +void	pmcstat_attach_pmcs(void);
    +void	pmcstat_cleanup(void);
    +void	pmcstat_clone_event_descriptor(
         struct pmcstat_ev *_ev, uint32_t _cpumask);
    -int	pmcstat_close_log(struct pmcstat_args *_a);
    -void	pmcstat_create_process(struct pmcstat_args *_a);
    -void	pmcstat_find_targets(struct pmcstat_args *_a, const char *_arg);
    -void	pmcstat_initialize_logging(struct pmcstat_args *_a);
    -void	pmcstat_kill_process(struct pmcstat_args *_a);
    +int	pmcstat_close_log(void);
    +void	pmcstat_create_process(void);
    +void	pmcstat_find_targets(const char *_arg);
    +void	pmcstat_initialize_logging(void);
    +void	pmcstat_kill_process(void);
     int	pmcstat_open_log(const char *_p, int _mode);
    -void	pmcstat_print_counters(struct pmcstat_args *_a);
    -void	pmcstat_print_headers(struct pmcstat_args *_a);
    -void	pmcstat_print_pmcs(struct pmcstat_args *_a);
    +void	pmcstat_print_counters(void);
    +void	pmcstat_print_headers(void);
    +void	pmcstat_print_pmcs(void);
     void	pmcstat_show_usage(void);
    -void	pmcstat_shutdown_logging(struct pmcstat_args *_a);
    -void	pmcstat_start_pmcs(struct pmcstat_args *_a);
    +void	pmcstat_shutdown_logging(void);
    +void	pmcstat_start_pmcs(void);
     void	pmcstat_start_process(void);
    -int	pmcstat_process_log(struct pmcstat_args *_a);
    +int	pmcstat_process_log(void);
    +int	pmcstat_keypress_log(void);
    +void	pmcstat_display_log(void);
    +void	pmcstat_pluginconfigure_log(char *_opt);
     uint32_t pmcstat_get_cpumask(const char *_a);
    +void    pmcstat_topexit(void);
     
     #endif	/* _PMCSTAT_H_ */
    diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c
    index a403852edf5..5811af3f1c6 100644
    --- a/usr.sbin/pmcstat/pmcstat_log.c
    +++ b/usr.sbin/pmcstat/pmcstat_log.c
    @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
     #include 
     
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -68,9 +69,8 @@ __FBSDID("$FreeBSD$");
     #include 
     
     #include "pmcstat.h"
    -
    -#define	min(A,B)		((A) < (B) ? (A) : (B))
    -#define	max(A,B)		((A) > (B) ? (A) : (B))
    +#include "pmcstat_log.h"
    +#include "pmcstat_top.h"
     
     #define	PMCSTAT_ALLOCATE		1
     
    @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$");
      * pmcstat_shutdown_logging()		orderly shutdown, called last
      * pmcstat_open_log()			open an eventlog for processing
      * pmcstat_process_log()		print/convert an event log
    + * pmcstat_display_log()		top mode display for the log
      * pmcstat_close_log()			finish processing an event log
      *
      * IMPLEMENTATION NOTES
    @@ -127,236 +128,125 @@ __FBSDID("$FreeBSD$");
      * also given a 'rank' that reflects its depth in the call stack.
      */
     
    -typedef const void *pmcstat_interned_string;
    -
    -/*
    - * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable
    - * names.
    - */
    -
    -struct pmcstat_pmcrecord {
    -	LIST_ENTRY(pmcstat_pmcrecord)	pr_next;
    -	pmc_id_t			pr_pmcid;
    -	pmcstat_interned_string	pr_pmcname;
    -};
    -
    -static LIST_HEAD(,pmcstat_pmcrecord)	pmcstat_pmcs =
    -	LIST_HEAD_INITIALIZER(pmcstat_pmcs);
    -
    -
    -/*
    - * struct pmcstat_gmonfile tracks a given 'gmon.out' file.  These
    - * files are mmap()'ed in as needed.
    - */
    -
    -struct pmcstat_gmonfile {
    -	LIST_ENTRY(pmcstat_gmonfile)	pgf_next; /* list of entries */
    -	int		pgf_overflow;	/* whether a count overflowed */
    -	pmc_id_t	pgf_pmcid;	/* id of the associated pmc */
    -	size_t		pgf_nbuckets;	/* #buckets in this gmon.out */
    -	unsigned int	pgf_nsamples;	/* #samples in this gmon.out */
    -	pmcstat_interned_string pgf_name;	/* pathname of gmon.out file */
    -	size_t		pgf_ndatabytes;	/* number of bytes mapped */
    -	void		*pgf_gmondata;	/* pointer to mmap'ed data */
    -	FILE		*pgf_file;	/* used when writing gmon arcs */
    -};
    -
    -/*
    - * A 'pmcstat_image' structure describes an executable program on
    - * disk.  'pi_execpath' is a cookie representing the pathname of
    - * the executable.  'pi_start' and 'pi_end' are the least and greatest
    - * virtual addresses for the text segments in the executable.
    - * 'pi_gmonlist' contains a linked list of gmon.out files associated
    - * with this image.
    - */
    -
    -enum pmcstat_image_type {
    -	PMCSTAT_IMAGE_UNKNOWN = 0,	/* never looked at the image */
    -	PMCSTAT_IMAGE_INDETERMINABLE,	/* can't tell what the image is */
    -	PMCSTAT_IMAGE_ELF32,		/* ELF 32 bit object */
    -	PMCSTAT_IMAGE_ELF64,		/* ELF 64 bit object */
    -	PMCSTAT_IMAGE_AOUT		/* AOUT object */
    -};
    -
    -struct pmcstat_image {
    -	LIST_ENTRY(pmcstat_image) pi_next;	/* hash link */
    -	TAILQ_ENTRY(pmcstat_image) pi_lru;	/* LRU list */
    -	pmcstat_interned_string	pi_execpath;    /* cookie */
    -	pmcstat_interned_string pi_samplename;  /* sample path name */
    -	pmcstat_interned_string pi_fullpath;    /* path to FS object */
    -
    -	enum pmcstat_image_type pi_type;	/* executable type */
    -
    -	/*
    -	 * Executables have pi_start and pi_end; these are zero
    -	 * for shared libraries.
    -	 */
    -	uintfptr_t	pi_start;	/* start address (inclusive) */
    -	uintfptr_t	pi_end;		/* end address (exclusive) */
    -	uintfptr_t	pi_entry;	/* entry address */
    -	uintfptr_t	pi_vaddr;	/* virtual address where loaded */
    -	int		pi_isdynamic;	/* whether a dynamic object */
    -	int		pi_iskernelmodule;
    -	pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */
    -
    -	/* All symbols associated with this object. */
    -	struct pmcstat_symbol *pi_symbols;
    -	size_t		pi_symcount;
    -
    -	/*
    -	 * An image can be associated with one or more gmon.out files;
    -	 * one per PMC.
    -	 */
    -	LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
    -};
    +struct pmcstat_pmcs pmcstat_pmcs = LIST_HEAD_INITIALIZER(pmcstat_pmcs);
     
     /*
      * All image descriptors are kept in a hash table.
      */
    -static LIST_HEAD(,pmcstat_image)	pmcstat_image_hash[PMCSTAT_NHASH];
    -
    -/*
    - * A 'pmcstat_pcmap' structure maps a virtual address range to an
    - * underlying 'pmcstat_image' descriptor.
    - */
    -struct pmcstat_pcmap {
    -	TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
    -	uintfptr_t	ppm_lowpc;
    -	uintfptr_t	ppm_highpc;
    -	struct pmcstat_image *ppm_image;
    -};
    -
    -/*
    - * A 'pmcstat_process' structure models processes.  Each process is
    - * associated with a set of pmcstat_pcmap structures that map
    - * addresses inside it to executable objects.  This set is implemented
    - * as a list, kept sorted in ascending order of mapped addresses.
    - *
    - * 'pp_pid' holds the pid of the process.  When a process exits, the
    - * 'pp_isactive' field is set to zero, but the process structure is
    - * not immediately reclaimed because there may still be samples in the
    - * log for this process.
    - */
    -
    -struct pmcstat_process {
    -	LIST_ENTRY(pmcstat_process) pp_next;	/* hash-next */
    -	pid_t			pp_pid;		/* associated pid */
    -	int			pp_isactive;	/* whether active */
    -	uintfptr_t		pp_entryaddr;	/* entry address */
    -	TAILQ_HEAD(,pmcstat_pcmap) pp_map;	/* address range map */
    -};
    +struct pmcstat_image_hash_list pmcstat_image_hash[PMCSTAT_NHASH];
     
     /*
      * All process descriptors are kept in a hash table.
      */
    -static LIST_HEAD(,pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH];
    +struct pmcstat_process_hash_list pmcstat_process_hash[PMCSTAT_NHASH];
     
    -static struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
    +struct pmcstat_stats pmcstat_stats; /* statistics */
     
    -/*
    - * Each function symbol tracked by pmcstat(8).
    - */
    +struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
     
    -struct pmcstat_symbol {
    -	pmcstat_interned_string ps_name;
    -	uint64_t	ps_start;
    -	uint64_t	ps_end;
    +#include "pmcpl_gprof.h"
    +#include "pmcpl_callgraph.h"
    +#include "pmcpl_annotate.h"
    +#include "pmcpl_calltree.h"
    +
    +struct pmc_plugins  {
    +	const char 	*pl_name;	/* name */
    +
    +	/* configure */
    +	int (*pl_configure)(char *opt);
    +
    +	/* init and shutdown */
    +	int (*pl_init)(void);
    +	void (*pl_shutdown)(FILE *mf);
    +
    +	/* sample processing */
    +	void (*pl_process)(struct pmcstat_process *pp,
    +	    struct pmcstat_pmcrecord *pmcr, uint32_t nsamples,
    +	    uintfptr_t *cc, int usermode, uint32_t cpu);
    +
    +	/* image */
    +	void (*pl_initimage)(struct pmcstat_image *pi);
    +	void (*pl_shutdownimage)(struct pmcstat_image *pi);
    +
    +	/* pmc */
    +	void (*pl_newpmc)(pmcstat_interned_string ps,
    +		struct pmcstat_pmcrecord *pr);
    +	
    +	/* top display */
    +	void (*pl_topdisplay)(void);
    +
    +	/* top keypress */
    +	int (*pl_topkeypress)(int c, WINDOW *w);
    +
    +} plugins[] = {
    +	{
    +		.pl_name		= "none",
    +	},
    +	{
    +		.pl_name		= "callgraph",
    +		.pl_init		= pmcpl_cg_init,
    +		.pl_shutdown		= pmcpl_cg_shutdown,
    +		.pl_process		= pmcpl_cg_process,
    +		.pl_topkeypress		= pmcpl_cg_topkeypress,
    +		.pl_topdisplay		= pmcpl_cg_topdisplay
    +	},
    +	{
    +		.pl_name		= "gprof",
    +		.pl_shutdown		= pmcpl_gmon_shutdown,
    +		.pl_process		= pmcpl_gmon_process,
    +		.pl_initimage		= pmcpl_gmon_initimage,
    +		.pl_shutdownimage	= pmcpl_gmon_shutdownimage,
    +		.pl_newpmc		= pmcpl_gmon_newpmc
    +	},
    +	{
    +		.pl_name		= "annotate",
    +		.pl_process		= pmcpl_annotate_process
    +	},
    +	{
    +		.pl_name		= "calltree",
    +		.pl_configure		= pmcpl_ct_configure,
    +		.pl_init		= pmcpl_ct_init,
    +		.pl_shutdown		= pmcpl_ct_shutdown,
    +		.pl_process		= pmcpl_ct_process,
    +		.pl_topkeypress		= pmcpl_ct_topkeypress,
    +		.pl_topdisplay		= pmcpl_ct_topdisplay
    +	},
    +	{
    +		.pl_name		= NULL
    +	}
     };
     
    -/*
    - * Each call graph node is tracked by a pmcstat_cgnode struct.
    - */
    -
    -struct pmcstat_cgnode {
    -	struct pmcstat_image	*pcg_image;
    -	uintfptr_t		pcg_func;
    -	uint32_t		pcg_count;
    -	uint32_t		pcg_nchildren;
    -	LIST_ENTRY(pmcstat_cgnode) pcg_sibling;
    -	LIST_HEAD(,pmcstat_cgnode) pcg_children;
    -};
    -
    -struct pmcstat_cgnode_hash {
    -	struct pmcstat_cgnode  *pch_cgnode;
    -	uint32_t		pch_pmcid;
    -	LIST_ENTRY(pmcstat_cgnode_hash) pch_next;
    -};
    -
    -static int pmcstat_cgnode_hash_count;
    -static pmcstat_interned_string pmcstat_previous_filename_printed;
    -
    -/*
    - * The toplevel CG nodes (i.e., with rank == 0) are placed in a hash table.
    - */
    -
    -static LIST_HEAD(,pmcstat_cgnode_hash) pmcstat_cgnode_hash[PMCSTAT_NHASH];
    -
    -/* Misc. statistics */
    -static struct pmcstat_stats {
    -	int ps_exec_aout;	/* # a.out executables seen */
    -	int ps_exec_elf;	/* # elf executables seen */
    -	int ps_exec_errors;	/* # errors processing executables */
    -	int ps_exec_indeterminable; /* # unknown executables seen */
    -	int ps_samples_total;	/* total number of samples processed */
    -	int ps_samples_skipped; /* #samples filtered out for any reason */
    -	int ps_samples_unknown_offset;	/* #samples of rank 0 not in a map */
    -	int ps_samples_indeterminable;	/* #samples in indeterminable images */
    -	int ps_callchain_dubious_frames;/* #dubious frame pointers seen */
    -} pmcstat_stats;
    +int pmcstat_mergepmc;
     
    +int pmcstat_pmcinfilter = 0; /* PMC filter for top mode. */
    +float pmcstat_threshold = 0.5; /* Cost filter for top mode. */
     
     /*
      * Prototypes
      */
     
    -static void	pmcstat_gmon_create_file(struct pmcstat_gmonfile *_pgf,
    -    struct pmcstat_image *_image);
    -static pmcstat_interned_string pmcstat_gmon_create_name(const char *_sd,
    -    struct pmcstat_image *_img, pmc_id_t _pmcid);
    -static void	pmcstat_gmon_map_file(struct pmcstat_gmonfile *_pgf);
    -static void	pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *_pgf);
    -
    -static void pmcstat_image_determine_type(struct pmcstat_image *_image,
    -    struct pmcstat_args *_a);
    -static struct pmcstat_gmonfile *pmcstat_image_find_gmonfile(struct
    -    pmcstat_image *_i, pmc_id_t _id);
     static struct pmcstat_image *pmcstat_image_from_path(pmcstat_interned_string
         _path, int _iskernelmodule);
    -static void pmcstat_image_get_aout_params(struct pmcstat_image *_image,
    -    struct pmcstat_args *_a);
    -static void pmcstat_image_get_elf_params(struct pmcstat_image *_image,
    -    struct pmcstat_args *_a);
    -static void	pmcstat_image_increment_bucket(struct pmcstat_pcmap *_pcm,
    -    uintfptr_t _pc, pmc_id_t _pmcid, struct pmcstat_args *_a);
    +static void pmcstat_image_get_aout_params(struct pmcstat_image *_image);
    +static void pmcstat_image_get_elf_params(struct pmcstat_image *_image);
     static void	pmcstat_image_link(struct pmcstat_process *_pp,
         struct pmcstat_image *_i, uintfptr_t _lpc);
     
     static void	pmcstat_pmcid_add(pmc_id_t _pmcid,
    -    pmcstat_interned_string _name, struct pmcstat_args *_a);
    -static const char *pmcstat_pmcid_to_name(pmc_id_t _pmcid);
    +    pmcstat_interned_string _name);
     
     static void	pmcstat_process_aout_exec(struct pmcstat_process *_pp,
    -    struct pmcstat_image *_image, uintfptr_t _entryaddr,
    -    struct pmcstat_args *_a);
    +    struct pmcstat_image *_image, uintfptr_t _entryaddr);
     static void	pmcstat_process_elf_exec(struct pmcstat_process *_pp,
    -    struct pmcstat_image *_image, uintfptr_t _entryaddr,
    -    struct pmcstat_args *_a);
    +    struct pmcstat_image *_image, uintfptr_t _entryaddr);
     static void	pmcstat_process_exec(struct pmcstat_process *_pp,
    -    pmcstat_interned_string _path, uintfptr_t _entryaddr,
    -    struct pmcstat_args *_ao);
    +    pmcstat_interned_string _path, uintfptr_t _entryaddr);
     static struct pmcstat_process *pmcstat_process_lookup(pid_t _pid,
         int _allocate);
    -static struct pmcstat_pcmap *pmcstat_process_find_map(
    -    struct pmcstat_process *_p, uintfptr_t _pc);
    -
     static int	pmcstat_string_compute_hash(const char *_string);
     static void pmcstat_string_initialize(void);
    -static pmcstat_interned_string pmcstat_string_intern(const char *_s);
    -static pmcstat_interned_string pmcstat_string_lookup(const char *_s);
     static int	pmcstat_string_lookup_hash(pmcstat_interned_string _is);
     static void pmcstat_string_shutdown(void);
    -static const char *pmcstat_string_unintern(pmcstat_interned_string _is);
    -
     
     /*
      * A simple implementation of interned strings.  Each interned string
    @@ -374,6 +264,16 @@ struct pmcstat_string {
     
     static LIST_HEAD(,pmcstat_string)	pmcstat_string_hash[PMCSTAT_NHASH];
     
    +/*
    + * PMC count.
    + */
    +int pmcstat_npmcs;
    +
    +/*
    + * PMC Top mode pause state.
    + */
    +int pmcstat_pause;
    +
     /*
      * Compute a 'hash' value for a string.
      */
    @@ -394,7 +294,7 @@ pmcstat_string_compute_hash(const char *s)
      * interned structure.
      */
     
    -static pmcstat_interned_string
    +pmcstat_interned_string
     pmcstat_string_intern(const char *s)
     {
     	struct pmcstat_string *ps;
    @@ -416,7 +316,7 @@ pmcstat_string_intern(const char *s)
     	return ((pmcstat_interned_string) ps);
     }
     
    -static const char *
    +const char *
     pmcstat_string_unintern(pmcstat_interned_string str)
     {
     	const char *s;
    @@ -425,7 +325,7 @@ pmcstat_string_unintern(pmcstat_interned_string str)
     	return (s);
     }
     
    -static pmcstat_interned_string
    +pmcstat_interned_string
     pmcstat_string_lookup(const char *s)
     {
     	struct pmcstat_string *ps;
    @@ -482,155 +382,6 @@ pmcstat_string_shutdown(void)
     		}
     }
     
    -/*
    - * Create a gmon.out file and size it.
    - */
    -
    -static void
    -pmcstat_gmon_create_file(struct pmcstat_gmonfile *pgf,
    -    struct pmcstat_image *image)
    -{
    -	int fd;
    -	size_t count;
    -	struct gmonhdr gm;
    -	const char *pathname;
    -	char buffer[DEFAULT_BUFFER_SIZE];
    -
    -	pathname = pmcstat_string_unintern(pgf->pgf_name);
    -	if ((fd = open(pathname, O_RDWR|O_NOFOLLOW|O_CREAT,
    -		 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
    -		err(EX_OSERR, "ERROR: Cannot open \"%s\"", pathname);
    -
    -	gm.lpc = image->pi_start;
    -	gm.hpc = image->pi_end;
    -	gm.ncnt = (pgf->pgf_nbuckets * sizeof(HISTCOUNTER)) +
    -	    sizeof(struct gmonhdr);
    -	gm.version = GMONVERSION;
    -	gm.profrate = 0;		/* use ticks */
    -	gm.histcounter_type = 0;	/* compatibility with moncontrol() */
    -	gm.spare[0] = gm.spare[1] = 0;
    -
    -	/* Write out the gmon header */
    -	if (write(fd, &gm, sizeof(gm)) < 0)
    -		goto error;
    -
    -	/* Zero fill the samples[] array */
    -	(void) memset(buffer, 0, sizeof(buffer));
    -
    -	count = pgf->pgf_ndatabytes - sizeof(struct gmonhdr);
    -	while (count > sizeof(buffer)) {
    -		if (write(fd, &buffer, sizeof(buffer)) < 0)
    -			goto error;
    -		count -= sizeof(buffer);
    -	}
    -
    -	if (write(fd, &buffer, count) < 0)
    -		goto error;
    -
    -	(void) close(fd);
    -
    -	return;
    -
    - error:
    -	err(EX_OSERR, "ERROR: Cannot write \"%s\"", pathname);
    -}
    -
    -/*
    - * Determine the full pathname of a gmon.out file for a given
    - * (image,pmcid) combination.  Return the interned string.
    - */
    -
    -pmcstat_interned_string
    -pmcstat_gmon_create_name(const char *samplesdir, struct pmcstat_image *image,
    -    pmc_id_t pmcid)
    -{
    -	const char *pmcname;
    -	char fullpath[PATH_MAX];
    -
    -	pmcname = pmcstat_pmcid_to_name(pmcid);
    -
    -	(void) snprintf(fullpath, sizeof(fullpath),
    -	    "%s/%s/%s", samplesdir, pmcname,
    -	    pmcstat_string_unintern(image->pi_samplename));
    -
    -	return (pmcstat_string_intern(fullpath));
    -}
    -
    -
    -/*
    - * Mmap in a gmon.out file for processing.
    - */
    -
    -static void
    -pmcstat_gmon_map_file(struct pmcstat_gmonfile *pgf)
    -{
    -	int fd;
    -	const char *pathname;
    -
    -	pathname = pmcstat_string_unintern(pgf->pgf_name);
    -
    -	/* the gmon.out file must already exist */
    -	if ((fd = open(pathname, O_RDWR | O_NOFOLLOW, 0)) < 0)
    -		err(EX_OSERR, "ERROR: cannot open \"%s\"", pathname);
    -
    -	pgf->pgf_gmondata = mmap(NULL, pgf->pgf_ndatabytes,
    -	    PROT_READ|PROT_WRITE, MAP_NOSYNC|MAP_SHARED, fd, 0);
    -
    -	if (pgf->pgf_gmondata == MAP_FAILED)
    -		err(EX_OSERR, "ERROR: cannot map \"%s\"", pathname);
    -
    -	(void) close(fd);
    -}
    -
    -/*
    - * Unmap a gmon.out file after sync'ing its data to disk.
    - */
    -
    -static void
    -pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *pgf)
    -{
    -	(void) msync(pgf->pgf_gmondata, pgf->pgf_ndatabytes,
    -	    MS_SYNC);
    -	(void) munmap(pgf->pgf_gmondata, pgf->pgf_ndatabytes);
    -	pgf->pgf_gmondata = NULL;
    -}
    -
    -static void
    -pmcstat_gmon_append_arc(struct pmcstat_image *image, pmc_id_t pmcid,
    -    uintptr_t rawfrom, uintptr_t rawto, uint32_t count)
    -{
    -	struct rawarc arc;	/* from  */
    -	const char *pathname;
    -	struct pmcstat_gmonfile *pgf;
    -
    -	if ((pgf = pmcstat_image_find_gmonfile(image, pmcid)) == NULL)
    -		return;
    -
    -	if (pgf->pgf_file == NULL) {
    -		pathname = pmcstat_string_unintern(pgf->pgf_name);
    -		if ((pgf->pgf_file = fopen(pathname, "a")) == NULL)
    -			return;
    -	}
    -
    -	arc.raw_frompc = rawfrom + image->pi_vaddr;
    -	arc.raw_selfpc = rawto + image->pi_vaddr;
    -	arc.raw_count = count;
    -
    -	(void) fwrite(&arc, sizeof(arc), 1, pgf->pgf_file);
    -
    -}
    -
    -static struct pmcstat_gmonfile *
    -pmcstat_image_find_gmonfile(struct pmcstat_image *image, pmc_id_t pmcid)
    -{
    -	struct pmcstat_gmonfile *pgf;
    -	LIST_FOREACH(pgf, &image->pi_gmlist, pgf_next)
    -	    if (pgf->pgf_pmcid == pmcid)
    -		    return (pgf);
    -	return (NULL);
    -}
    -
    -
     /*
      * Determine whether a given executable image is an A.OUT object, and
      * if so, fill in its parameters from the text file.
    @@ -638,8 +389,7 @@ pmcstat_image_find_gmonfile(struct pmcstat_image *image, pmc_id_t pmcid)
      */
     
     static void
    -pmcstat_image_get_aout_params(struct pmcstat_image *image,
    -    struct pmcstat_args *a)
    +pmcstat_image_get_aout_params(struct pmcstat_image *image)
     {
     	int fd;
     	ssize_t nbytes;
    @@ -655,7 +405,7 @@ pmcstat_image_get_aout_params(struct pmcstat_image *image,
     		    "unsupported \"%s\"", path);
     
     	(void) snprintf(buffer, sizeof(buffer), "%s%s",
    -	    a->pa_fsroot, path);
    +	    args.pa_fsroot, path);
     
     	if ((fd = open(buffer, O_RDONLY, 0)) < 0 ||
     	    (nbytes = read(fd, &ex, sizeof(ex))) < 0) {
    @@ -702,7 +452,7 @@ pmcstat_symbol_compare(const void *a, const void *b)
      * Map an address to a symbol in an image.
      */
     
    -static struct pmcstat_symbol *
    +struct pmcstat_symbol *
     pmcstat_symbol_search(struct pmcstat_image *image, uintfptr_t addr)
     {
     	struct pmcstat_symbol sym;
    @@ -825,12 +575,12 @@ pmcstat_image_add_symbols(struct pmcstat_image *image, Elf *e,
      */
     
     static void
    -pmcstat_image_get_elf_params(struct pmcstat_image *image,
    -    struct pmcstat_args *a)
    +pmcstat_image_get_elf_params(struct pmcstat_image *image)
     {
     	int fd;
     	size_t i, nph, nsh;
     	const char *path, *elfbase;
    +	char *p, *endp;
     	uintfptr_t minva, maxva;
     	Elf *e;
     	Elf_Scn *scn;
    @@ -858,10 +608,10 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image,
     	 */
     	if (image->pi_iskernelmodule)
     		(void) snprintf(buffer, sizeof(buffer), "%s%s/%s",
    -		    a->pa_fsroot, a->pa_kernel, path);
    +		    args.pa_fsroot, args.pa_kernel, path);
     	else
     		(void) snprintf(buffer, sizeof(buffer), "%s%s",
    -		    a->pa_fsroot, path);
    +		    args.pa_fsroot, path);
     
     	e = NULL;
     	if ((fd = open(buffer, O_RDONLY, 0)) < 0 ||
    @@ -960,6 +710,14 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image,
     	image->pi_type  = image_type;
     	image->pi_fullpath = pmcstat_string_intern(buffer);
     
    +	/* Build display name
    +	 */
    +	endp = buffer;
    +	for (p = buffer; *p; p++)
    +		if (*p == '/')
    +			endp = p+1;
    +	image->pi_name = pmcstat_string_intern(endp);
    +
      done:
     	(void) elf_end(e);
     	if (fd >= 0)
    @@ -972,17 +730,16 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image,
      * If no handler claims the image, set its type to 'INDETERMINABLE'.
      */
     
    -static void
    -pmcstat_image_determine_type(struct pmcstat_image *image,
    -    struct pmcstat_args *a)
    +void
    +pmcstat_image_determine_type(struct pmcstat_image *image)
     {
     	assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN);
     
     	/* Try each kind of handler in turn */
     	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
    -		pmcstat_image_get_elf_params(image, a);
    +		pmcstat_image_get_elf_params(image);
     	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
    -		pmcstat_image_get_aout_params(image, a);
    +		pmcstat_image_get_aout_params(image);
     
     	/*
     	 * Otherwise, remember that we tried to determine
    @@ -1006,10 +763,8 @@ static struct pmcstat_image *
     pmcstat_image_from_path(pmcstat_interned_string internedpath,
         int iskernelmodule)
     {
    -	int count, hash, nlen;
    +	int hash;
     	struct pmcstat_image *pi;
    -	char *sn;
    -	char name[NAME_MAX];
     
     	hash = pmcstat_string_lookup_hash(internedpath);
     
    @@ -1038,144 +793,18 @@ pmcstat_image_from_path(pmcstat_interned_string internedpath,
     	pi->pi_dynlinkerpath = NULL;
     	pi->pi_symbols = NULL;
     	pi->pi_symcount = 0;
    +	pi->pi_addr2line = NULL;
     
    -	/*
    -	 * Look for a suitable name for the sample files associated
    -	 * with this image: if `basename(path)`+".gmon" is available,
    -	 * we use that, otherwise we try iterating through
    -	 * `basename(path)`+ "~" + NNN + ".gmon" till we get a free
    -	 * entry.
    -	 */
    -	if ((sn = basename(pmcstat_string_unintern(internedpath))) == NULL)
    -		err(EX_OSERR, "ERROR: Cannot process \"%s\"",
    -		    pmcstat_string_unintern(internedpath));
    -
    -	nlen = strlen(sn);
    -	nlen = min(nlen, (int) (sizeof(name) - sizeof(".gmon")));
    -
    -	snprintf(name, sizeof(name), "%.*s.gmon", nlen, sn);
    -
    -	/* try use the unabridged name first */
    -	if (pmcstat_string_lookup(name) == NULL)
    -		pi->pi_samplename = pmcstat_string_intern(name);
    -	else {
    -		/*
    -		 * Otherwise use a prefix from the original name and
    -		 * upto 3 digits.
    -		 */
    -		nlen = strlen(sn);
    -		nlen = min(nlen, (int) (sizeof(name)-sizeof("~NNN.gmon")));
    -		count = 0;
    -		do {
    -			if (++count > 999)
    -				errx(EX_CANTCREAT, "ERROR: cannot create a "
    -				    "gmon file for \"%s\"", name);
    -			snprintf(name, sizeof(name), "%.*s~%3.3d.gmon",
    -			    nlen, sn, count);
    -			if (pmcstat_string_lookup(name) == NULL) {
    -				pi->pi_samplename =
    -				    pmcstat_string_intern(name);
    -				count = 0;
    -			}
    -		} while (count > 0);
    -	}
    -
    -
    -	LIST_INIT(&pi->pi_gmlist);
    +	if (plugins[args.pa_pplugin].pl_initimage != NULL)
    +		plugins[args.pa_pplugin].pl_initimage(pi);
    +	if (plugins[args.pa_plugin].pl_initimage != NULL)
    +		plugins[args.pa_plugin].pl_initimage(pi);
     
     	LIST_INSERT_HEAD(&pmcstat_image_hash[hash], pi, pi_next);
     
     	return (pi);
     }
     
    -/*
    - * Increment the bucket in the gmon.out file corresponding to 'pmcid'
    - * and 'pc'.
    - */
    -
    -static void
    -pmcstat_image_increment_bucket(struct pmcstat_pcmap *map, uintfptr_t pc,
    -    pmc_id_t pmcid, struct pmcstat_args *a)
    -{
    -	struct pmcstat_image *image;
    -	struct pmcstat_gmonfile *pgf;
    -	uintfptr_t bucket;
    -	HISTCOUNTER *hc;
    -
    -	assert(pc >= map->ppm_lowpc && pc < map->ppm_highpc);
    -
    -	image = map->ppm_image;
    -
    -	/*
    -	 * If this is the first time we are seeing a sample for
    -	 * this executable image, try determine its parameters.
    -	 */
    -	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
    -		pmcstat_image_determine_type(image, a);
    -
    -	assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN);
    -
    -	/* Ignore samples in images that we know nothing about. */
    -	if (image->pi_type == PMCSTAT_IMAGE_INDETERMINABLE) {
    -		pmcstat_stats.ps_samples_indeterminable++;
    -		return;
    -	}
    -
    -	/*
    -	 * Find the gmon file corresponding to 'pmcid', creating it if
    -	 * needed.
    -	 */
    -	pgf = pmcstat_image_find_gmonfile(image, pmcid);
    -	if (pgf == NULL) {
    -		if ((pgf = calloc(1, sizeof(*pgf))) == NULL)
    -			err(EX_OSERR, "ERROR:");
    -
    -		pgf->pgf_gmondata = NULL;	/* mark as unmapped */
    -		pgf->pgf_name = pmcstat_gmon_create_name(a->pa_samplesdir,
    -		    image, pmcid);
    -		pgf->pgf_pmcid = pmcid;
    -		assert(image->pi_end > image->pi_start);
    -		pgf->pgf_nbuckets = (image->pi_end - image->pi_start) /
    -		    FUNCTION_ALIGNMENT;	/* see  */
    -		pgf->pgf_ndatabytes = sizeof(struct gmonhdr) +
    -		    pgf->pgf_nbuckets * sizeof(HISTCOUNTER);
    -		pgf->pgf_nsamples = 0;
    -		pgf->pgf_file = NULL;
    -
    -		pmcstat_gmon_create_file(pgf, image);
    -
    -		LIST_INSERT_HEAD(&image->pi_gmlist, pgf, pgf_next);
    -	}
    -
    -	/*
    -	 * Map the gmon file in if needed.  It may have been mapped
    -	 * out under memory pressure.
    -	 */
    -	if (pgf->pgf_gmondata == NULL)
    -		pmcstat_gmon_map_file(pgf);
    -
    -	assert(pgf->pgf_gmondata != NULL);
    -
    -	/*
    -	 *
    -	 */
    -
    -	bucket = (pc - map->ppm_lowpc) / FUNCTION_ALIGNMENT;
    -
    -	assert(bucket < pgf->pgf_nbuckets);
    -
    -	hc = (HISTCOUNTER *) ((uintptr_t) pgf->pgf_gmondata +
    -	    sizeof(struct gmonhdr));
    -
    -	/* saturating add */
    -	if (hc[bucket] < 0xFFFFU)  /* XXX tie this to sizeof(HISTCOUNTER) */
    -		hc[bucket]++;
    -	else /* mark that an overflow occurred */
    -		pgf->pgf_overflow = 1;
    -
    -	pgf->pgf_nsamples++;
    -}
    -
     /*
      * Record the fact that PC values from 'start' to 'end' come from
      * image 'image'.
    @@ -1283,73 +912,182 @@ pmcstat_image_unmap(struct pmcstat_process *pp, uintfptr_t start,
     	}
     }
     
    +/*
    + * Resolve file name and line number for the given address.
    + */
    +int
    +pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr,
    +    char *sourcefile, size_t sourcefile_len, unsigned *sourceline,
    +    char *funcname, size_t funcname_len)
    +{
    +	static int addr2line_warn = 0;
    +
    +	char *sep, cmdline[PATH_MAX], imagepath[PATH_MAX];
    +	int fd;
    +
    +	if (image->pi_addr2line == NULL) {
    +		snprintf(imagepath, sizeof(imagepath), "%s.symbols",
    +		    pmcstat_string_unintern(image->pi_fullpath));
    +		fd = open(imagepath, O_RDONLY);
    +		if (fd < 0) {
    +			snprintf(imagepath, sizeof(imagepath), "%s",
    +			    pmcstat_string_unintern(image->pi_fullpath));
    +		} else
    +			close(fd);
    +		snprintf(cmdline, sizeof(cmdline), "addr2line -Cfe \"%s\"",
    +		    imagepath);
    +		image->pi_addr2line = popen(cmdline, "r+");
    +		if (image->pi_addr2line == NULL) {
    +			if (!addr2line_warn) {
    +				addr2line_warn = 1;
    +				warnx("WARNING: addr2line is needed"
    +				    "for source code information.");
    +			}
    +			return (0);
    +		}
    +	}
    +
    +	if (feof(image->pi_addr2line) || ferror(image->pi_addr2line)) {
    +		warnx("WARNING: addr2line pipe error");
    +		pclose(image->pi_addr2line);
    +		image->pi_addr2line = NULL;
    +		return (0);
    +	}
    +
    +	fprintf(image->pi_addr2line, "%p\n", (void *)addr);
    +
    +	if (fgets(funcname, funcname_len, image->pi_addr2line) == NULL) {
    +		warnx("WARNING: addr2line function name read error");
    +		return (0);
    +	}
    +	sep = strchr(funcname, '\n');
    +	if (sep != NULL)
    +		*sep = '\0';
    +
    +	if (fgets(sourcefile, sourcefile_len, image->pi_addr2line) == NULL) {
    +		warnx("WARNING: addr2line source file read error");
    +		return (0);
    +	}
    +	sep = strchr(sourcefile, ':');
    +	if (sep == NULL) {
    +		warnx("WARNING: addr2line source line separator missing");
    +		return (0);
    +	}
    +	*sep = '\0';
    +	*sourceline = atoi(sep+1);
    +	if (*sourceline == 0)
    +		return (0);
    +
    +	return (1);
    +}
    +
     /*
      * Add a {pmcid,name} mapping.
      */
     
     static void
    -pmcstat_pmcid_add(pmc_id_t pmcid, pmcstat_interned_string ps,
    -    struct pmcstat_args *a)
    +pmcstat_pmcid_add(pmc_id_t pmcid, pmcstat_interned_string ps)
     {
    -	struct pmcstat_pmcrecord *pr;
    -	struct stat st;
    -	char fullpath[PATH_MAX];
    +	struct pmcstat_pmcrecord *pr, *prm;
     
     	/* Replace an existing name for the PMC. */
    +	prm = NULL;
     	LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
    -	    if (pr->pr_pmcid == pmcid) {
    -		    pr->pr_pmcname = ps;
    -		    return;
    -	    }
    +		if (pr->pr_pmcid == pmcid) {
    +			pr->pr_pmcname = ps;
    +			return;
    +		} else if (pr->pr_pmcname == ps)
    +			prm = pr;
     
     	/*
    -	 * Otherwise, allocate a new descriptor and create the
    -	 * appropriate directory to hold gmon.out files.
    +	 * Otherwise, allocate a new descriptor and call the
    +	 * plugins hook.
     	 */
     	if ((pr = malloc(sizeof(*pr))) == NULL)
     		err(EX_OSERR, "ERROR: Cannot allocate pmc record");
     
     	pr->pr_pmcid = pmcid;
     	pr->pr_pmcname = ps;
    +	pr->pr_pmcin = pmcstat_npmcs++;
    +	pr->pr_merge = prm == NULL ? pr : prm;
    +
     	LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next);
     
    -	(void) snprintf(fullpath, sizeof(fullpath), "%s/%s", a->pa_samplesdir,
    -	    pmcstat_string_unintern(ps));
    -
    -	/* If the path name exists, it should be a directory */
    -	if (stat(fullpath, &st) == 0 && S_ISDIR(st.st_mode))
    -		return;
    -
    -	if (mkdir(fullpath, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) < 0)
    -		err(EX_OSERR, "ERROR: Cannot create directory \"%s\"",
    -		    fullpath);
    +	if (plugins[args.pa_pplugin].pl_newpmc != NULL)
    +		plugins[args.pa_pplugin].pl_newpmc(ps, pr);
    +	if (plugins[args.pa_plugin].pl_newpmc != NULL)
    +		plugins[args.pa_plugin].pl_newpmc(ps, pr);
     }
     
     /*
      * Given a pmcid in use, find its human-readable name.
      */
     
    -static const char *
    +const char *
     pmcstat_pmcid_to_name(pmc_id_t pmcid)
     {
     	struct pmcstat_pmcrecord *pr;
    -	char fullpath[PATH_MAX];
     
     	LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
     	    if (pr->pr_pmcid == pmcid)
     		    return (pmcstat_string_unintern(pr->pr_pmcname));
     
    -	/* create a default name and add this entry */
    -	if ((pr = malloc(sizeof(*pr))) == NULL)
    -		err(EX_OSERR, "ERROR: ");
    -	pr->pr_pmcid = pmcid;
    +	err(EX_SOFTWARE, "ERROR: cannot find pmcid");
    +	return NULL;
    +}
     
    -	(void) snprintf(fullpath, sizeof(fullpath), "%X", (unsigned int) pmcid);
    -	pr->pr_pmcname = pmcstat_string_intern(fullpath);
    +/*
    + * Convert PMC index to name.
    + */
     
    -	LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next);
    +const char *
    +pmcstat_pmcindex_to_name(int pmcin)
    +{
    +	struct pmcstat_pmcrecord *pr;
     
    -	return (pmcstat_string_unintern(pr->pr_pmcname));
    +	LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
    +		if (pr->pr_pmcin == pmcin)
    +			return pmcstat_string_unintern(pr->pr_pmcname);
    +
    +	err(EX_SOFTWARE, "ERROR: cannot find pmcid name");
    +	return NULL;
    +}
    +
    +/*
    + * Return PMC record with given index.
    + */
    +
    +struct pmcstat_pmcrecord *
    +pmcstat_pmcindex_to_pmcr(int pmcin)
    +{
    +	struct pmcstat_pmcrecord *pr;
    +
    +	LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
    +		if (pr->pr_pmcin == pmcin)
    +			return pr;
    +
    +	err(EX_SOFTWARE, "ERROR: invalid pmcindex");
    +	return NULL;
    +}
    +
    +/*
    + * Get PMC record by id, apply merge policy.
    + */
    +
    +static struct pmcstat_pmcrecord *
    +pmcstat_lookup_pmcid(pmc_id_t pmcid)
    +{
    +	struct pmcstat_pmcrecord *pr;
    +
    +	LIST_FOREACH(pr, &pmcstat_pmcs, pr_next) {
    +		if (pr->pr_pmcid == pmcid) {
    +			if (pmcstat_mergepmc)
    +				return pr->pr_merge;
    +			return pr;
    +		}
    +	}
    +
    +	return NULL;
     }
     
     /*
    @@ -1358,13 +1096,11 @@ pmcstat_pmcid_to_name(pmc_id_t pmcid)
     
     static void
     pmcstat_process_aout_exec(struct pmcstat_process *pp,
    -    struct pmcstat_image *image, uintfptr_t entryaddr,
    -    struct pmcstat_args *a)
    +    struct pmcstat_image *image, uintfptr_t entryaddr)
     {
     	(void) pp;
     	(void) image;
     	(void) entryaddr;
    -	(void) a;
     	/* TODO Implement a.out handling */
     }
     
    @@ -1374,8 +1110,7 @@ pmcstat_process_aout_exec(struct pmcstat_process *pp,
     
     static void
     pmcstat_process_elf_exec(struct pmcstat_process *pp,
    -    struct pmcstat_image *image, uintfptr_t entryaddr,
    -    struct pmcstat_args *a)
    +    struct pmcstat_image *image, uintfptr_t entryaddr)
     {
     	uintmax_t libstart;
     	struct pmcstat_image *rtldimage;
    @@ -1414,8 +1149,7 @@ pmcstat_process_elf_exec(struct pmcstat_process *pp,
     		 * this we can figure out the address where the
     		 * runtime loader's file object had been mapped to.
     		 */
    -		rtldimage = pmcstat_image_from_path(image->pi_dynlinkerpath,
    -		    0);
    +		rtldimage = pmcstat_image_from_path(image->pi_dynlinkerpath, 0);
     		if (rtldimage == NULL) {
     			warnx("WARNING: Cannot find image for \"%s\".",
     			    pmcstat_string_unintern(image->pi_dynlinkerpath));
    @@ -1424,7 +1158,7 @@ pmcstat_process_elf_exec(struct pmcstat_process *pp,
     		}
     
     		if (rtldimage->pi_type == PMCSTAT_IMAGE_UNKNOWN)
    -			pmcstat_image_get_elf_params(rtldimage, a);
    +			pmcstat_image_get_elf_params(rtldimage);
     
     		if (rtldimage->pi_type != PMCSTAT_IMAGE_ELF32 &&
     		    rtldimage->pi_type != PMCSTAT_IMAGE_ELF64) {
    @@ -1495,8 +1229,7 @@ pmcstat_process_lookup(pid_t pid, int allocate)
     
     static void
     pmcstat_process_exec(struct pmcstat_process *pp,
    -    pmcstat_interned_string path, uintfptr_t entryaddr,
    -    struct pmcstat_args *a)
    +    pmcstat_interned_string path, uintfptr_t entryaddr)
     {
     	struct pmcstat_image *image;
     
    @@ -1506,7 +1239,7 @@ pmcstat_process_exec(struct pmcstat_process *pp,
     	}
     
     	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
    -		pmcstat_image_determine_type(image, a);
    +		pmcstat_image_determine_type(image);
     
     	assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN);
     
    @@ -1514,12 +1247,12 @@ pmcstat_process_exec(struct pmcstat_process *pp,
     	case PMCSTAT_IMAGE_ELF32:
     	case PMCSTAT_IMAGE_ELF64:
     		pmcstat_stats.ps_exec_elf++;
    -		pmcstat_process_elf_exec(pp, image, entryaddr, a);
    +		pmcstat_process_elf_exec(pp, image, entryaddr);
     		break;
     
     	case PMCSTAT_IMAGE_AOUT:
     		pmcstat_stats.ps_exec_aout++;
    -		pmcstat_process_aout_exec(pp, image, entryaddr, a);
    +		pmcstat_process_aout_exec(pp, image, entryaddr);
     		break;
     
     	case PMCSTAT_IMAGE_INDETERMINABLE:
    @@ -1537,7 +1270,7 @@ pmcstat_process_exec(struct pmcstat_process *pp,
      * Find the map entry associated with process 'p' at PC value 'pc'.
      */
     
    -static struct pmcstat_pcmap *
    +struct pmcstat_pcmap *
     pmcstat_process_find_map(struct pmcstat_process *p, uintfptr_t pc)
     {
     	struct pmcstat_pcmap *ppm;
    @@ -1552,444 +1285,36 @@ pmcstat_process_find_map(struct pmcstat_process *p, uintfptr_t pc)
     	return (NULL);
     }
     
    -static struct pmcstat_cgnode *
    -pmcstat_cgnode_allocate(struct pmcstat_image *image, uintfptr_t pc)
    -{
    -	struct pmcstat_cgnode *cg;
    -
    -	if ((cg = malloc(sizeof(*cg))) == NULL)
    -		err(EX_OSERR, "ERROR: Cannot allocate callgraph node");
    -
    -	cg->pcg_image = image;
    -	cg->pcg_func = pc;
    -
    -	cg->pcg_count = 0;
    -	cg->pcg_nchildren = 0;
    -	LIST_INIT(&cg->pcg_children);
    -
    -	return (cg);
    -}
    -
    -/*
    - * Free a node and its children.
    - */
    -static void
    -pmcstat_cgnode_free(struct pmcstat_cgnode *cg)
    -{
    -	struct pmcstat_cgnode *cgc, *cgtmp;
    -
    -	LIST_FOREACH_SAFE(cgc, &cg->pcg_children, pcg_sibling, cgtmp)
    -		pmcstat_cgnode_free(cgc);
    -	free(cg);
    -}
    -
    -/*
    - * Look for a callgraph node associated with pmc `pmcid' in the global
    - * hash table that corresponds to the given `pc' value in the process
    - * `pp'.
    - */
    -static struct pmcstat_cgnode *
    -pmcstat_cgnode_hash_lookup_pc(struct pmcstat_process *pp, uint32_t pmcid,
    -    uintfptr_t pc, int usermode)
    -{
    -	struct pmcstat_pcmap *ppm;
    -	struct pmcstat_symbol *sym;
    -	struct pmcstat_image *image;
    -	struct pmcstat_cgnode *cg;
    -	struct pmcstat_cgnode_hash *h;
    -	uintfptr_t loadaddress;
    -	unsigned int i, hash;
    -
    -	ppm = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, pc);
    -	if (ppm == NULL)
    -		return (NULL);
    -
    -	image = ppm->ppm_image;
    -
    -	loadaddress = ppm->ppm_lowpc + image->pi_vaddr - image->pi_start;
    -	pc -= loadaddress;	/* Convert to an offset in the image. */
    -
    -	/*
    -	 * Try determine the function at this offset.  If we can't
    -	 * find a function round leave the `pc' value alone.
    -	 */
    -	if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
    -		pc = sym->ps_start;
    -
    -	for (hash = i = 0; i < sizeof(uintfptr_t); i++)
    -		hash += (pc >> i) & 0xFF;
    -
    -	hash &= PMCSTAT_HASH_MASK;
    -
    -	cg = NULL;
    -	LIST_FOREACH(h, &pmcstat_cgnode_hash[hash], pch_next)
    -	{
    -		if (h->pch_pmcid != pmcid)
    -			continue;
    -
    -		cg = h->pch_cgnode;
    -
    -		assert(cg != NULL);
    -
    -		if (cg->pcg_image == image && cg->pcg_func == pc)
    -			return (cg);
    -	}
    -
    -	/*
    -	 * We haven't seen this (pmcid, pc) tuple yet, so allocate a
    -	 * new callgraph node and a new hash table entry for it.
    -	 */
    -	cg = pmcstat_cgnode_allocate(image, pc);
    -	if ((h = malloc(sizeof(*h))) == NULL)
    -		err(EX_OSERR, "ERROR: Could not allocate callgraph node");
    -
    -	h->pch_pmcid = pmcid;
    -	h->pch_cgnode = cg;
    -	LIST_INSERT_HEAD(&pmcstat_cgnode_hash[hash], h, pch_next);
    -
    -	pmcstat_cgnode_hash_count++;
    -
    -	return (cg);
    -}
    -
    -/*
    - * Compare two callgraph nodes for sorting.
    - */
    -static int
    -pmcstat_cgnode_compare(const void *a, const void *b)
    -{
    -	const struct pmcstat_cgnode *const *pcg1, *const *pcg2, *cg1, *cg2;
    -
    -	pcg1 = (const struct pmcstat_cgnode *const *) a;
    -	cg1 = *pcg1;
    -	pcg2 = (const struct pmcstat_cgnode *const *) b;
    -	cg2 = *pcg2;
    -
    -	/* Sort in reverse order */
    -	if (cg1->pcg_count < cg2->pcg_count)
    -		return (1);
    -	if (cg1->pcg_count > cg2->pcg_count)
    -		return (-1);
    -	return (0);
    -}
    -
    -/*
    - * Find (allocating if a needed) a callgraph node in the given
    - * parent with the same (image, pcoffset) pair.
    - */
    -
    -static struct pmcstat_cgnode *
    -pmcstat_cgnode_find(struct pmcstat_cgnode *parent, struct pmcstat_image *image,
    -    uintfptr_t pcoffset)
    -{
    -	struct pmcstat_cgnode *child;
    -
    -	LIST_FOREACH(child, &parent->pcg_children, pcg_sibling) {
    -		if (child->pcg_image == image &&
    -		    child->pcg_func == pcoffset)
    -			return (child);
    -	}
    -
    -	/*
    -	 * Allocate a new structure.
    -	 */
    -
    -	child = pmcstat_cgnode_allocate(image, pcoffset);
    -
    -	/*
    -	 * Link it into the parent.
    -	 */
    -	LIST_INSERT_HEAD(&parent->pcg_children, child, pcg_sibling);
    -	parent->pcg_nchildren++;
    -
    -	return (child);
    -}
    -
    -/*
    - * Print one callgraph node.  The output format is:
    - *
    - * indentation %(parent's samples) #nsamples function@object
    - */
    -static void
    -pmcstat_cgnode_print(struct pmcstat_args *a, struct pmcstat_cgnode *cg,
    -    int depth, uint32_t total)
    -{
    -	uint32_t n;
    -	const char *space;
    -	struct pmcstat_symbol *sym;
    -	struct pmcstat_cgnode **sortbuffer, **cgn, *pcg;
    -
    -	space = " ";
    -
    -	if (depth > 0)
    -		(void) fprintf(a->pa_graphfile, "%*s", depth, space);
    -
    -	if (cg->pcg_count == total)
    -		(void) fprintf(a->pa_graphfile, "100.0%% ");
    -	else
    -		(void) fprintf(a->pa_graphfile, "%05.2f%% ",
    -		    100.0 * cg->pcg_count / total);
    -
    -	n = fprintf(a->pa_graphfile, " [%u] ", cg->pcg_count);
    -
    -	/* #samples is a 12 character wide field. */
    -	if (n < 12)
    -		(void) fprintf(a->pa_graphfile, "%*s", 12 - n, space);
    -
    -	if (depth > 0)
    -		(void) fprintf(a->pa_graphfile, "%*s", depth, space);
    -
    -	sym = pmcstat_symbol_search(cg->pcg_image, cg->pcg_func);
    -	if (sym)
    -		(void) fprintf(a->pa_graphfile, "%s",
    -		    pmcstat_string_unintern(sym->ps_name));
    -	else
    -		(void) fprintf(a->pa_graphfile, "%p",
    -		    (void *) (cg->pcg_image->pi_vaddr + cg->pcg_func));
    -
    -	if (pmcstat_previous_filename_printed !=
    -	    cg->pcg_image->pi_fullpath) {
    -		pmcstat_previous_filename_printed = cg->pcg_image->pi_fullpath;
    -		(void) fprintf(a->pa_graphfile, " @ %s\n",
    -		    pmcstat_string_unintern(
    -		    pmcstat_previous_filename_printed));
    -	} else
    -		(void) fprintf(a->pa_graphfile, "\n");
    -
    -	if (cg->pcg_nchildren == 0)
    -		return;
    -
    -	if ((sortbuffer = (struct pmcstat_cgnode **)
    -		malloc(sizeof(struct pmcstat_cgnode *) *
    -		    cg->pcg_nchildren)) == NULL)
    -		err(EX_OSERR, "ERROR: Cannot print callgraph");
    -	cgn = sortbuffer;
    -
    -	LIST_FOREACH(pcg, &cg->pcg_children, pcg_sibling)
    -	    *cgn++ = pcg;
    -
    -	assert(cgn - sortbuffer == (int) cg->pcg_nchildren);
    -
    -	qsort(sortbuffer, cg->pcg_nchildren, sizeof(struct pmcstat_cgnode *),
    -	    pmcstat_cgnode_compare);
    -
    -	for (cgn = sortbuffer, n = 0; n < cg->pcg_nchildren; n++, cgn++)
    -		pmcstat_cgnode_print(a, *cgn, depth+1, cg->pcg_count);
    -
    -	free(sortbuffer);
    -}
    -
    -/*
    - * Record a callchain.
    - */
    -
    -static void
    -pmcstat_record_callchain(struct pmcstat_process *pp, uint32_t pmcid,
    -    uint32_t nsamples, uintfptr_t *cc, int usermode, struct pmcstat_args *a)
    -{
    -	uintfptr_t pc, loadaddress;
    -	uint32_t n;
    -	struct pmcstat_image *image;
    -	struct pmcstat_pcmap *ppm;
    -	struct pmcstat_symbol *sym;
    -	struct pmcstat_cgnode *parent, *child;
    -
    -	/*
    -	 * Find the callgraph node recorded in the global hash table
    -	 * for this (pmcid, pc).
    -	 */
    -
    -	pc = cc[0];
    -	parent = pmcstat_cgnode_hash_lookup_pc(pp, pmcid, pc, usermode);
    -	if (parent == NULL) {
    -		pmcstat_stats.ps_callchain_dubious_frames++;
    -		return;
    -	}
    -
    -	parent->pcg_count++;
    -
    -	/*
    -	 * For each return address in the call chain record, subject
    -	 * to the maximum depth desired.
    -	 * - Find the image associated with the sample.  Stop if there
    -	 *   there is no valid image at that address.
    -	 * - Find the function that overlaps the return address.
    -	 * - If found: use the start address of the function.
    -	 *   If not found (say an object's symbol table is not present or
    -	 *   is incomplete), round down to th gprof bucket granularity.
    -	 * - Convert return virtual address to an offset in the image.
    -	 * - Look for a child with the same {offset,image} tuple,
    -	 *   inserting one if needed.
    -	 * - Increment the count of occurrences of the child.
    -	 */
    -
    -	for (n = 1; n < (uint32_t) a->pa_graphdepth && n < nsamples; n++,
    -	    parent = child) {
    -		pc = cc[n];
    -
    -		ppm = pmcstat_process_find_map(usermode ? pp :
    -		    pmcstat_kernproc, pc);
    -		if (ppm == NULL)
    -			return;
    -
    -		image = ppm->ppm_image;
    -		loadaddress = ppm->ppm_lowpc + image->pi_vaddr -
    -		    image->pi_start;
    -		pc -= loadaddress;
    -
    -		if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
    -			pc = sym->ps_start;
    -
    -		child = pmcstat_cgnode_find(parent, image, pc);
    -		child->pcg_count++;
    -	}
    -}
    -
    -/*
    - * Printing a callgraph for a PMC.
    - */
    -static void
    -pmcstat_callgraph_print_for_pmcid(struct pmcstat_args *a,
    -    struct pmcstat_pmcrecord *pmcr)
    -{
    -	int n, nentries;
    -	uint32_t nsamples, pmcid;
    -	struct pmcstat_cgnode **sortbuffer, **cgn;
    -	struct pmcstat_cgnode_hash *pch;
    -
    -	/*
    -	 * We pull out all callgraph nodes in the top-level hash table
    -	 * with a matching PMC id.  We then sort these based on the
    -	 * frequency of occurrence.  Each callgraph node is then
    -	 * printed.
    -	 */
    -
    -	nsamples = 0;
    -	pmcid = pmcr->pr_pmcid;
    -	if ((sortbuffer = (struct pmcstat_cgnode **)
    -	    malloc(sizeof(struct pmcstat_cgnode *) *
    -	    pmcstat_cgnode_hash_count)) == NULL)
    -		err(EX_OSERR, "ERROR: Cannot sort callgraph");
    -	cgn = sortbuffer;
    -
    -	memset(sortbuffer, 0xFF, pmcstat_cgnode_hash_count *
    -	    sizeof(struct pmcstat_cgnode **));
    -
    -	for (n = 0; n < PMCSTAT_NHASH; n++)
    -		LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
    -		    if (pch->pch_pmcid == pmcid) {
    -			    nsamples += pch->pch_cgnode->pcg_count;
    -			    *cgn++ = pch->pch_cgnode;
    -		    }
    -
    -	nentries = cgn - sortbuffer;
    -	assert(nentries <= pmcstat_cgnode_hash_count);
    -
    -	if (nentries == 0)
    -		return;
    -
    -	qsort(sortbuffer, nentries, sizeof(struct pmcstat_cgnode *),
    -	    pmcstat_cgnode_compare);
    -
    -	(void) fprintf(a->pa_graphfile,
    -	    "@ %s [%u samples]\n\n",
    -	    pmcstat_string_unintern(pmcr->pr_pmcname),
    -	    nsamples);
    -
    -	for (cgn = sortbuffer, n = 0; n < nentries; n++, cgn++) {
    -		pmcstat_previous_filename_printed = NULL;
    -		pmcstat_cgnode_print(a, *cgn, 0, nsamples);
    -		(void) fprintf(a->pa_graphfile, "\n");
    -	}
    -
    -	free(sortbuffer);
    -}
    -
    -/*
    - * Print out callgraphs.
    - */
    -
    -static void
    -pmcstat_callgraph_print(struct pmcstat_args *a)
    -{
    -	struct pmcstat_pmcrecord *pmcr;
    -
    -	LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
    -	    pmcstat_callgraph_print_for_pmcid(a, pmcr);
    -}
    -
    -static void
    -pmcstat_cgnode_do_gmon_arcs(struct pmcstat_cgnode *cg, pmc_id_t pmcid)
    -{
    -	struct pmcstat_cgnode *cgc;
    -
    -	/*
    -	 * Look for child nodes that belong to the same image.
    -	 */
    -
    -	LIST_FOREACH(cgc, &cg->pcg_children, pcg_sibling) {
    -		if (cgc->pcg_image == cg->pcg_image)
    -			pmcstat_gmon_append_arc(cg->pcg_image, pmcid,
    -			    cgc->pcg_func, cg->pcg_func, cgc->pcg_count);
    -		if (cgc->pcg_nchildren > 0)
    -			pmcstat_cgnode_do_gmon_arcs(cgc, pmcid);
    -	}
    -}
    -
    -static void
    -pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmc_id_t pmcid)
    -{
    -	int n;
    -	struct pmcstat_cgnode_hash *pch;
    -
    -	for (n = 0; n < PMCSTAT_NHASH; n++)
    -		LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
    -			if (pch->pch_pmcid == pmcid &&
    -			    pch->pch_cgnode->pcg_nchildren > 1)
    -				pmcstat_cgnode_do_gmon_arcs(pch->pch_cgnode,
    -				    pmcid);
    -}
    -
    -
    -static void
    -pmcstat_callgraph_do_gmon_arcs(void)
    -{
    -	struct pmcstat_pmcrecord *pmcr;
    -
    -	LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
    -		pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmcr->pr_pmcid);
    -}
    -
     /*
      * Convert a hwpmc(4) log to profile information.  A system-wide
      * callgraph is generated if FLAG_DO_CALLGRAPHS is set.  gmon.out
      * files usable by gprof(1) are created if FLAG_DO_GPROF is set.
      */
     static int
    -pmcstat_analyze_log(struct pmcstat_args *a)
    +pmcstat_analyze_log(void)
     {
     	uint32_t cpu, cpuflags;
    -	uintfptr_t pc, newpc;
    +	uintfptr_t pc;
     	pid_t pid;
     	struct pmcstat_image *image;
    -	struct pmcstat_symbol *sym;
     	struct pmcstat_process *pp, *ppnew;
     	struct pmcstat_pcmap *ppm, *ppmtmp;
     	struct pmclog_ev ev;
    +	struct pmcstat_pmcrecord *pmcr;
     	pmcstat_interned_string image_path;
     
    -	assert(a->pa_flags & FLAG_DO_ANALYSIS);
    +	assert(args.pa_flags & FLAG_DO_ANALYSIS);
     
     	if (elf_version(EV_CURRENT) == EV_NONE)
     		err(EX_UNAVAILABLE, "Elf library intialization failed");
     
    -	while (pmclog_read(a->pa_logparser, &ev) == 0) {
    +	while (pmclog_read(args.pa_logparser, &ev) == 0) {
     		assert(ev.pl_state == PMCLOG_OK);
     
     		switch (ev.pl_type) {
     		case PMCLOG_TYPE_INITIALIZE:
     			if ((ev.pl_u.pl_i.pl_version & 0xFF000000) !=
    -			    PMC_VERSION_MAJOR << 24 && a->pa_verbosity > 0)
    +			    PMC_VERSION_MAJOR << 24 && args.pa_verbosity > 0)
     				warnx("WARNING: Log version 0x%x does not "
     				    "match compiled version 0x%x.",
     				    ev.pl_u.pl_i.pl_version,
    @@ -2019,7 +1344,7 @@ pmcstat_analyze_log(struct pmcstat_args *a)
     			    pl_pathname);
     			image = pmcstat_image_from_path(image_path, pid == -1);
     			if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
    -				pmcstat_image_determine_type(image, a);
    +				pmcstat_image_determine_type(image);
     			if (image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE)
     				pmcstat_image_link(pp, image,
     				    ev.pl_u.pl_mi.pl_start);
    @@ -2059,16 +1384,23 @@ pmcstat_analyze_log(struct pmcstat_args *a)
     			pc = ev.pl_u.pl_s.pl_pc;
     			pp = pmcstat_process_lookup(ev.pl_u.pl_s.pl_pid,
     			    PMCSTAT_ALLOCATE);
    -			if ((ppm = pmcstat_process_find_map(pp, pc)) == NULL &&
    -			    (ppm = pmcstat_process_find_map(pmcstat_kernproc,
    -				pc)) == NULL) {	/* unknown process,offset pair */
    -				pmcstat_stats.ps_samples_unknown_offset++;
    -				break;
    -			}
     
    -			pmcstat_image_increment_bucket(ppm, pc,
    -			    ev.pl_u.pl_s.pl_pmcid, a);
    +			/* Get PMC record. */
    +			pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_s.pl_pmcid);
    +			assert(pmcr != NULL);
     
    +			/*
    +			 * Call the plugins processing
    +			 * TODO: move pmcstat_process_find_map inside plugins
    +			 */
    +
    +			if (plugins[args.pa_pplugin].pl_process != NULL)
    +				plugins[args.pa_pplugin].pl_process(
    +				    pp, pmcr, 1, &pc,
    +				    pmcstat_process_find_map(pp, pc) != NULL, 0);
    +			plugins[args.pa_plugin].pl_process(
    +			    pp, pmcr, 1, &pc,
    +			    pmcstat_process_find_map(pp, pc) != NULL, 0);
     			break;
     
     		case PMCLOG_TYPE_CALLCHAIN:
    @@ -2078,7 +1410,7 @@ pmcstat_analyze_log(struct pmcstat_args *a)
     			cpu = PMC_CALLCHAIN_CPUFLAGS_TO_CPU(cpuflags);
     
     			/* Filter on the CPU id. */
    -			if ((a->pa_cpumask & (1 << cpu)) == 0) {
    +			if ((args.pa_cpumask & (1 << cpu)) == 0) {
     				pmcstat_stats.ps_samples_skipped++;
     				break;
     			}
    @@ -2086,45 +1418,27 @@ pmcstat_analyze_log(struct pmcstat_args *a)
     			pp = pmcstat_process_lookup(ev.pl_u.pl_cc.pl_pid,
     			    PMCSTAT_ALLOCATE);
     
    -			if ((a->pa_flags & FLAG_WANTS_MAPPINGS) == 0)
    -				pmcstat_record_callchain(pp,
    -				    ev.pl_u.pl_cc.pl_pmcid,
    -				    ev.pl_u.pl_cc.pl_npc, ev.pl_u.pl_cc.pl_pc,
    -			PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags), a);
    +			/* Get PMC record. */
    +			pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_cc.pl_pmcid);
    +			assert(pmcr != NULL);
     
    -			if ((a->pa_flags &
    -			    (FLAG_DO_GPROF | FLAG_WANTS_MAPPINGS)) == 0)
    -				break;
    -
    -			pc = ev.pl_u.pl_cc.pl_pc[0];
    -			if (PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags) == 0)
    -				pp = pmcstat_kernproc;
    -			ppm = pmcstat_process_find_map(pp, pc);
    -			if (ppm == NULL) {
    -
    -				/* Unknown offset. */
    -				pmcstat_stats.ps_samples_unknown_offset++;
    -				break;
    -			}
    -			if (a->pa_flags & FLAG_WANTS_MAPPINGS) {
    -				image = ppm->ppm_image;
    -				newpc = pc - (ppm->ppm_lowpc +
    -				    (image->pi_vaddr - image->pi_start));
    -				sym = pmcstat_symbol_search(image, newpc);
    -				if (sym == NULL)
    -					break;
    -				fprintf(a->pa_graphfile, "%p %s 0x%jx 0x%jx\n",
    -				    (void *)pc,
    -				    pmcstat_string_unintern(sym->ps_name),
    -				    (uintmax_t)(sym->ps_start +
    -				    image->pi_vaddr), (uintmax_t)(sym->ps_end +
    -				    image->pi_vaddr));
    -				break;
    -			}
    -
    -			pmcstat_image_increment_bucket(ppm, pc,
    -			    ev.pl_u.pl_cc.pl_pmcid, a);
    +			/*
    +			 * Call the plugins processing
    +			 */
     
    +			if (plugins[args.pa_pplugin].pl_process != NULL)
    +				plugins[args.pa_pplugin].pl_process(
    +				    pp, pmcr,
    +				    ev.pl_u.pl_cc.pl_npc,
    +				    ev.pl_u.pl_cc.pl_pc,
    +				    PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags),
    +				    cpu);
    +			plugins[args.pa_plugin].pl_process(
    +			    pp, pmcr,
    +			    ev.pl_u.pl_cc.pl_npc,
    +			    ev.pl_u.pl_cc.pl_pc,
    +			    PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags),
    +			    cpu);
     			break;
     
     		case PMCLOG_TYPE_PMCALLOCATE:
    @@ -2133,7 +1447,7 @@ pmcstat_analyze_log(struct pmcstat_args *a)
     			 * PMC and its name.
     			 */
     			pmcstat_pmcid_add(ev.pl_u.pl_a.pl_pmcid,
    -			    pmcstat_string_intern(ev.pl_u.pl_a.pl_evname), a);
    +			    pmcstat_string_intern(ev.pl_u.pl_a.pl_evname));
     			break;
     
     		case PMCLOG_TYPE_PROCEXEC:
    @@ -2156,7 +1470,7 @@ pmcstat_analyze_log(struct pmcstat_args *a)
     				ev.pl_u.pl_x.pl_pathname);
     			assert(image_path != NULL);
     			pmcstat_process_exec(pp, image_path,
    -			    ev.pl_u.pl_x.pl_entryaddr, a);
    +			    ev.pl_u.pl_x.pl_entryaddr);
     			break;
     
     		case PMCLOG_TYPE_PROCEXIT:
    @@ -2224,16 +1538,16 @@ pmcstat_analyze_log(struct pmcstat_args *a)
      */
     
     static int
    -pmcstat_print_log(struct pmcstat_args *a)
    +pmcstat_print_log(void)
     {
     	struct pmclog_ev ev;
     	uint32_t npc;
     
    -	while (pmclog_read(a->pa_logparser, &ev) == 0) {
    +	while (pmclog_read(args.pa_logparser, &ev) == 0) {
     		assert(ev.pl_state == PMCLOG_OK);
     		switch (ev.pl_type) {
     		case PMCLOG_TYPE_CALLCHAIN:
    -			PMCSTAT_PRINT_ENTRY(a, "callchain",
    +			PMCSTAT_PRINT_ENTRY("callchain",
     			    "%d 0x%x %d %d %c", ev.pl_u.pl_cc.pl_pid,
     			    ev.pl_u.pl_cc.pl_pmcid,
     			    PMC_CALLCHAIN_CPUFLAGS_TO_CPU(ev.pl_u.pl_cc. \
    @@ -2241,95 +1555,95 @@ pmcstat_print_log(struct pmcstat_args *a)
     			    PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(ev.pl_u.pl_cc.\
     			        pl_cpuflags) ? 'u' : 's');
     			for (npc = 0; npc < ev.pl_u.pl_cc.pl_npc; npc++)
    -				PMCSTAT_PRINT_ENTRY(a, "...", "%p",
    +				PMCSTAT_PRINT_ENTRY("...", "%p",
     				    (void *) ev.pl_u.pl_cc.pl_pc[npc]);
     			break;
     		case PMCLOG_TYPE_CLOSELOG:
    -			PMCSTAT_PRINT_ENTRY(a,"closelog",);
    +			PMCSTAT_PRINT_ENTRY("closelog",);
     			break;
     		case PMCLOG_TYPE_DROPNOTIFY:
    -			PMCSTAT_PRINT_ENTRY(a,"drop",);
    +			PMCSTAT_PRINT_ENTRY("drop",);
     			break;
     		case PMCLOG_TYPE_INITIALIZE:
    -			PMCSTAT_PRINT_ENTRY(a,"initlog","0x%x \"%s\"",
    +			PMCSTAT_PRINT_ENTRY("initlog","0x%x \"%s\"",
     			    ev.pl_u.pl_i.pl_version,
     			    pmc_name_of_cputype(ev.pl_u.pl_i.pl_arch));
     			if ((ev.pl_u.pl_i.pl_version & 0xFF000000) !=
    -			    PMC_VERSION_MAJOR << 24 && a->pa_verbosity > 0)
    +			    PMC_VERSION_MAJOR << 24 && args.pa_verbosity > 0)
     				warnx("WARNING: Log version 0x%x != expected "
     				    "version 0x%x.", ev.pl_u.pl_i.pl_version,
     				    PMC_VERSION);
     			break;
     		case PMCLOG_TYPE_MAP_IN:
    -			PMCSTAT_PRINT_ENTRY(a,"map-in","%d %p \"%s\"",
    +			PMCSTAT_PRINT_ENTRY("map-in","%d %p \"%s\"",
     			    ev.pl_u.pl_mi.pl_pid,
     			    (void *) ev.pl_u.pl_mi.pl_start,
     			    ev.pl_u.pl_mi.pl_pathname);
     			break;
     		case PMCLOG_TYPE_MAP_OUT:
    -			PMCSTAT_PRINT_ENTRY(a,"map-out","%d %p %p",
    +			PMCSTAT_PRINT_ENTRY("map-out","%d %p %p",
     			    ev.pl_u.pl_mo.pl_pid,
     			    (void *) ev.pl_u.pl_mo.pl_start,
     			    (void *) ev.pl_u.pl_mo.pl_end);
     			break;
     		case PMCLOG_TYPE_PCSAMPLE:
    -			PMCSTAT_PRINT_ENTRY(a,"sample","0x%x %d %p %c",
    +			PMCSTAT_PRINT_ENTRY("sample","0x%x %d %p %c",
     			    ev.pl_u.pl_s.pl_pmcid,
     			    ev.pl_u.pl_s.pl_pid,
     			    (void *) ev.pl_u.pl_s.pl_pc,
     			    ev.pl_u.pl_s.pl_usermode ? 'u' : 's');
     			break;
     		case PMCLOG_TYPE_PMCALLOCATE:
    -			PMCSTAT_PRINT_ENTRY(a,"allocate","0x%x \"%s\" 0x%x",
    +			PMCSTAT_PRINT_ENTRY("allocate","0x%x \"%s\" 0x%x",
     			    ev.pl_u.pl_a.pl_pmcid,
     			    ev.pl_u.pl_a.pl_evname,
     			    ev.pl_u.pl_a.pl_flags);
     			break;
     		case PMCLOG_TYPE_PMCATTACH:
    -			PMCSTAT_PRINT_ENTRY(a,"attach","0x%x %d \"%s\"",
    +			PMCSTAT_PRINT_ENTRY("attach","0x%x %d \"%s\"",
     			    ev.pl_u.pl_t.pl_pmcid,
     			    ev.pl_u.pl_t.pl_pid,
     			    ev.pl_u.pl_t.pl_pathname);
     			break;
     		case PMCLOG_TYPE_PMCDETACH:
    -			PMCSTAT_PRINT_ENTRY(a,"detach","0x%x %d",
    +			PMCSTAT_PRINT_ENTRY("detach","0x%x %d",
     			    ev.pl_u.pl_d.pl_pmcid,
     			    ev.pl_u.pl_d.pl_pid);
     			break;
     		case PMCLOG_TYPE_PROCCSW:
    -			PMCSTAT_PRINT_ENTRY(a,"cswval","0x%x %d %jd",
    +			PMCSTAT_PRINT_ENTRY("cswval","0x%x %d %jd",
     			    ev.pl_u.pl_c.pl_pmcid,
     			    ev.pl_u.pl_c.pl_pid,
     			    ev.pl_u.pl_c.pl_value);
     			break;
     		case PMCLOG_TYPE_PROCEXEC:
    -			PMCSTAT_PRINT_ENTRY(a,"exec","0x%x %d %p \"%s\"",
    +			PMCSTAT_PRINT_ENTRY("exec","0x%x %d %p \"%s\"",
     			    ev.pl_u.pl_x.pl_pmcid,
     			    ev.pl_u.pl_x.pl_pid,
     			    (void *) ev.pl_u.pl_x.pl_entryaddr,
     			    ev.pl_u.pl_x.pl_pathname);
     			break;
     		case PMCLOG_TYPE_PROCEXIT:
    -			PMCSTAT_PRINT_ENTRY(a,"exitval","0x%x %d %jd",
    +			PMCSTAT_PRINT_ENTRY("exitval","0x%x %d %jd",
     			    ev.pl_u.pl_e.pl_pmcid,
     			    ev.pl_u.pl_e.pl_pid,
     			    ev.pl_u.pl_e.pl_value);
     			break;
     		case PMCLOG_TYPE_PROCFORK:
    -			PMCSTAT_PRINT_ENTRY(a,"fork","%d %d",
    +			PMCSTAT_PRINT_ENTRY("fork","%d %d",
     			    ev.pl_u.pl_f.pl_oldpid,
     			    ev.pl_u.pl_f.pl_newpid);
     			break;
     		case PMCLOG_TYPE_USERDATA:
    -			PMCSTAT_PRINT_ENTRY(a,"userdata","0x%x",
    +			PMCSTAT_PRINT_ENTRY("userdata","0x%x",
     			    ev.pl_u.pl_u.pl_userdata);
     			break;
     		case PMCLOG_TYPE_SYSEXIT:
    -			PMCSTAT_PRINT_ENTRY(a,"exit","%d",
    +			PMCSTAT_PRINT_ENTRY("exit","%d",
     			    ev.pl_u.pl_se.pl_pid);
     			break;
     		default:
    -			fprintf(a->pa_printfile, "unknown event (type %d).\n",
    +			fprintf(args.pa_printfile, "unknown event (type %d).\n",
     			    ev.pl_type);
     		}
     	}
    @@ -2354,13 +1668,13 @@ pmcstat_print_log(struct pmcstat_args *a)
      */
     
     int
    -pmcstat_close_log(struct pmcstat_args *a)
    +pmcstat_close_log(void)
     {
     	if (pmc_flush_logfile() < 0 ||
     	    pmc_configure_logfile(-1) < 0)
     		err(EX_OSERR, "ERROR: logging failed");
    -	a->pa_flags &= ~(FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE);
    -	return (a->pa_flags & FLAG_HAS_PIPE ? PMCSTAT_EXITING :
    +	args.pa_flags &= ~(FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE);
    +	return (args.pa_flags & FLAG_HAS_PIPE ? PMCSTAT_EXITING :
     	    PMCSTAT_FINISHED);
     }
     
    @@ -2456,17 +1770,208 @@ pmcstat_open_log(const char *path, int mode)
      */
     
     int
    -pmcstat_process_log(struct pmcstat_args *a)
    +pmcstat_process_log(void)
     {
     
     	/*
     	 * If analysis has not been asked for, just print the log to
     	 * the current output file.
     	 */
    -	if (a->pa_flags & FLAG_DO_PRINT)
    -		return (pmcstat_print_log(a));
    +	if (args.pa_flags & FLAG_DO_PRINT)
    +		return (pmcstat_print_log());
     	else
    -		return (pmcstat_analyze_log(a));
    +		return (pmcstat_analyze_log());
    +}
    +
    +/*
    + * Refresh top display.
    + */
    +
    +static void
    +pmcstat_refresh_top(void)
    +{
    +	char pmcname[40];
    +
    +	/* If in pause mode do not refresh display. */
    +	if (pmcstat_pause)
    +		return;
    +
    +	/* Format PMC name. */
    +	if (pmcstat_mergepmc)
    +		snprintf(pmcname, sizeof(pmcname), "[%s]",
    +		    pmcstat_pmcindex_to_name(pmcstat_pmcinfilter));
    +	else
    +		snprintf(pmcname, sizeof(pmcname), "%s.%d",
    +		    pmcstat_pmcindex_to_name(pmcstat_pmcinfilter),
    +		    pmcstat_pmcinfilter);
    +
    +	PMCSTAT_PRINTBEGIN();
    +	PMCSTAT_PRINTW("PMC: %s Samples: %u processed, %u invalid\n\n",
    +	    pmcname,
    +	    pmcstat_stats.ps_samples_total,
    +	    pmcstat_stats.ps_samples_unknown_offset +
    +	    pmcstat_stats.ps_samples_indeterminable +
    +	    pmcstat_stats.ps_callchain_dubious_frames);
    +	if (plugins[args.pa_plugin].pl_topdisplay != NULL)
    +		plugins[args.pa_plugin].pl_topdisplay();
    +	PMCSTAT_PRINTEND();
    +}
    +
    +/*
    + * Find the next pmc index to display.
    + */
    +
    +static void
    +pmcstat_changefilter(void)
    +{
    +	int pmcin;
    +	struct pmcstat_pmcrecord *pmcr;
    +
    +	/*
    +	 * Find the next merge target.
    +	 */
    +	if (pmcstat_mergepmc) {
    +		pmcin = pmcstat_pmcinfilter;
    +
    +		do {
    +			pmcr = pmcstat_pmcindex_to_pmcr(pmcstat_pmcinfilter);
    +			if (pmcr == pmcr->pr_merge)
    +				break;
    +
    +			pmcstat_pmcinfilter++;
    +			if (pmcstat_pmcinfilter >= pmcstat_npmcs)
    +				pmcstat_pmcinfilter = 0;
    +
    +		} while (pmcstat_pmcinfilter != pmcin);
    +	}
    +}
    +
    +/*
    + * Top mode keypress.
    + */
    +
    +int
    +pmcstat_keypress_log(void)
    +{
    +	int c, ret = 0;
    +	WINDOW *w;
    +
    +	w = newwin(1, 0, 1, 0);
    +	c = wgetch(w);
    +	wprintw(w, "Key: %c => ", c);
    +	switch (c) {
    +	case 'c':
    +		wprintw(w, "enter mode 'd' or 'a' => ");
    +		c = wgetch(w);
    +		if (c == 'd') {
    +			args.pa_topmode = PMCSTAT_TOP_DELTA;
    +			wprintw(w, "switching to delta mode");
    +		} else {
    +			args.pa_topmode = PMCSTAT_TOP_ACCUM;
    +			wprintw(w, "switching to accumulation mode");
    +		}
    +		break;
    +	case 'm':
    +		pmcstat_mergepmc = !pmcstat_mergepmc;
    +		/*
    +		 * Changing merge state require data reset.
    +		 */
    +		if (plugins[args.pa_plugin].pl_shutdown != NULL)
    +			plugins[args.pa_plugin].pl_shutdown(NULL);
    +		bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
    +		if (plugins[args.pa_plugin].pl_init != NULL)
    +			plugins[args.pa_plugin].pl_init();
    +
    +		/* Update filter to be on a merge target. */
    +		pmcstat_changefilter();
    +		wprintw(w, "merge PMC %s", pmcstat_mergepmc ? "on" : "off");
    +		break;
    +	case 'n':
    +		/* Close current plugin. */
    +		if (plugins[args.pa_plugin].pl_shutdown != NULL)
    +			plugins[args.pa_plugin].pl_shutdown(NULL);
    +
    +		/* Find next top display available. */
    +		do {
    +			args.pa_plugin++;
    +			if (plugins[args.pa_plugin].pl_name == NULL)
    +				args.pa_plugin = 0;
    +		} while (plugins[args.pa_plugin].pl_topdisplay == NULL);
    +
    +		/* Open new plugin. */
    +		bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
    +		if (plugins[args.pa_plugin].pl_init != NULL)
    +			plugins[args.pa_plugin].pl_init();
    +		wprintw(w, "switching to plugin %s",
    +		    plugins[args.pa_plugin].pl_name);
    +		break;
    +	case 'p':
    +		pmcstat_pmcinfilter++;
    +		if (pmcstat_pmcinfilter >= pmcstat_npmcs)
    +			pmcstat_pmcinfilter = 0;
    +		pmcstat_changefilter();
    +		wprintw(w, "switching to PMC %s.%d",
    +		    pmcstat_pmcindex_to_name(pmcstat_pmcinfilter),
    +		    pmcstat_pmcinfilter);
    +		break;
    +	case ' ':
    +		pmcstat_pause = !pmcstat_pause;
    +		if (pmcstat_pause)
    +			wprintw(w, "pause => press space again to continue");
    +		break;
    +	case 'q':
    +		wprintw(w, "exiting...");
    +		ret = 1;
    +	default:
    +		if (plugins[args.pa_plugin].pl_topkeypress != NULL)
    +			if (plugins[args.pa_plugin].pl_topkeypress(c, w))
    +				ret = 1;
    +	}
    +
    +	wrefresh(w);
    +	delwin(w);
    +	return ret;
    +}
    +
    +
    +/*
    + * Top mode display.
    + */
    +
    +void
    +pmcstat_display_log(void)
    +{
    +
    +	pmcstat_refresh_top();
    +
    +	/* Reset everythings if delta mode. */
    +	if (args.pa_topmode == PMCSTAT_TOP_DELTA) {
    +		if (plugins[args.pa_plugin].pl_shutdown != NULL)
    +			plugins[args.pa_plugin].pl_shutdown(NULL);
    +		bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
    +		if (plugins[args.pa_plugin].pl_init != NULL)
    +			plugins[args.pa_plugin].pl_init();
    +	}
    +
    +}
    +
    +/*
    + * Configure a plugins.
    + */
    +
    +void
    +pmcstat_pluginconfigure_log(char *opt)
    +{
    +
    +	if (strncmp(opt, "threshold=", 10) == 0) {
    +		pmcstat_threshold = atof(opt+10);
    +	} else {
    +		if (plugins[args.pa_plugin].pl_configure != NULL) {
    +			if (!plugins[args.pa_plugin].pl_configure(opt))
    +				err(EX_USAGE,
    +				    "ERROR: unknown option <%s>.", opt);
    +		}
    +	}
     }
     
     /*
    @@ -2474,12 +1979,10 @@ pmcstat_process_log(struct pmcstat_args *a)
      */
     
     void
    -pmcstat_initialize_logging(struct pmcstat_args *a)
    +pmcstat_initialize_logging(void)
     {
     	int i;
     
    -	(void) a;
    -
     	/* use a convenient format for 'ldd' output */
     	if (setenv("LD_TRACE_LOADED_OBJECTS_FMT1","%o \"%p\" %x\n",1) != 0)
     		err(EX_OSERR, "ERROR: Cannot setenv");
    @@ -2499,6 +2002,21 @@ pmcstat_initialize_logging(struct pmcstat_args *a)
     	if ((pmcstat_kernproc = pmcstat_process_lookup((pid_t) -1,
     		 PMCSTAT_ALLOCATE)) == NULL)
     		err(EX_OSERR, "ERROR: Cannot initialize logging");
    +
    +	/* PMC count. */
    +	pmcstat_npmcs = 0;
    +
    +	/* Merge PMC with same name. */
    +	pmcstat_mergepmc = args.pa_mergepmc;
    +
    +	/*
    +	 * Initialize plugins
    +	 */
    +
    +	if (plugins[args.pa_pplugin].pl_init != NULL)
    +		plugins[args.pa_pplugin].pl_init();
    +	if (plugins[args.pa_plugin].pl_init != NULL)
    +		plugins[args.pa_plugin].pl_init();
     }
     
     /*
    @@ -2506,99 +2024,57 @@ pmcstat_initialize_logging(struct pmcstat_args *a)
      */
     
     void
    -pmcstat_shutdown_logging(struct pmcstat_args *a)
    +pmcstat_shutdown_logging(void)
     {
     	int i;
     	FILE *mf;
    -	struct pmcstat_gmonfile *pgf, *pgftmp;
     	struct pmcstat_image *pi, *pitmp;
     	struct pmcstat_process *pp, *pptmp;
    -	struct pmcstat_cgnode_hash *pch, *pchtmp;
    +	struct pmcstat_pcmap *ppm, *ppmtmp;
     
     	/* determine where to send the map file */
     	mf = NULL;
    -	if (a->pa_mapfilename != NULL)
    -		mf = (strcmp(a->pa_mapfilename, "-") == 0) ?
    -		    a->pa_printfile : fopen(a->pa_mapfilename, "w");
    +	if (args.pa_mapfilename != NULL)
    +		mf = (strcmp(args.pa_mapfilename, "-") == 0) ?
    +		    args.pa_printfile : fopen(args.pa_mapfilename, "w");
     
    -	if (mf == NULL && a->pa_flags & FLAG_DO_GPROF &&
    -	    a->pa_verbosity >= 2)
    -		mf = a->pa_printfile;
    +	if (mf == NULL && args.pa_flags & FLAG_DO_GPROF &&
    +	    args.pa_verbosity >= 2)
    +		mf = args.pa_printfile;
     
     	if (mf)
     		(void) fprintf(mf, "MAP:\n");
     
    -
    -	if (a->pa_flags & FLAG_DO_CALLGRAPHS)
    -		pmcstat_callgraph_print(a);
    -
     	/*
    -	 * Sync back all gprof flat profile data.
    +	 * Shutdown the plugins
     	 */
    -	for (i = 0; i < PMCSTAT_NHASH; i++) {
    -		LIST_FOREACH(pi, &pmcstat_image_hash[i], pi_next) {
    -			if (mf)
    -				(void) fprintf(mf, " \"%s\" => \"%s\"",
    -				    pmcstat_string_unintern(pi->pi_execpath),
    -				    pmcstat_string_unintern(
    -				    pi->pi_samplename));
     
    -			/* flush gmon.out data to disk */
    -			LIST_FOREACH(pgf, &pi->pi_gmlist, pgf_next) {
    -				pmcstat_gmon_unmap_file(pgf);
    -				if (mf)
    -					(void) fprintf(mf, " %s/%d",
    -					    pmcstat_pmcid_to_name(
    -					    pgf->pgf_pmcid),
    -					    pgf->pgf_nsamples);
    -				if (pgf->pgf_overflow && a->pa_verbosity >= 1)
    -					warnx("WARNING: profile \"%s\" "
    -					    "overflowed.",
    -					    pmcstat_string_unintern(
    -					        pgf->pgf_name));
    -			}
    -
    -			if (mf)
    -				(void) fprintf(mf, "\n");
    -		}
    -	}
    -
    -	/*
    -	 * Compute arcs and add these to the gprof files.
    -	 */
    -	if (a->pa_flags & FLAG_DO_GPROF && a->pa_graphdepth > 1)
    -		pmcstat_callgraph_do_gmon_arcs();
    -
    -	/*
    -	 * Free memory.
    -	 */
    -	for (i = 0; i < PMCSTAT_NHASH; i++) {
    -		LIST_FOREACH_SAFE(pch, &pmcstat_cgnode_hash[i], pch_next,
    -		    pchtmp) {
    -			pmcstat_cgnode_free(pch->pch_cgnode);
    -			free(pch);
    -		}
    -	}
    +	if (plugins[args.pa_plugin].pl_shutdown != NULL)
    +		plugins[args.pa_plugin].pl_shutdown(mf);
    +	if (plugins[args.pa_pplugin].pl_shutdown != NULL)
    +		plugins[args.pa_pplugin].pl_shutdown(mf);
     
     	for (i = 0; i < PMCSTAT_NHASH; i++) {
    -		LIST_FOREACH_SAFE(pi, &pmcstat_image_hash[i], pi_next, pitmp)
    -		{
    -			LIST_FOREACH_SAFE(pgf, &pi->pi_gmlist, pgf_next,
    -			    pgftmp) {
    -				if (pgf->pgf_file)
    -					(void) fclose(pgf->pgf_file);
    -				LIST_REMOVE(pgf, pgf_next);
    -				free(pgf);
    -			}
    -			if (pi->pi_symbols)
    -				free(pi->pi_symbols);
    +		LIST_FOREACH_SAFE(pi, &pmcstat_image_hash[i], pi_next,
    +		    pitmp) {
    +			if (plugins[args.pa_plugin].pl_shutdownimage != NULL)
    +				plugins[args.pa_plugin].pl_shutdownimage(pi);
    +			if (plugins[args.pa_pplugin].pl_shutdownimage != NULL)
    +				plugins[args.pa_pplugin].pl_shutdownimage(pi);
     
    +			free(pi->pi_symbols);
    +			if (pi->pi_addr2line != NULL)
    +				pclose(pi->pi_addr2line);
     			LIST_REMOVE(pi, pi_next);
     			free(pi);
     		}
     
     		LIST_FOREACH_SAFE(pp, &pmcstat_process_hash[i], pp_next,
     		    pptmp) {
    +			TAILQ_FOREACH_SAFE(ppm, &pp->pp_map, ppm_next, ppmtmp) {
    +				TAILQ_REMOVE(&pp->pp_map, ppm, ppm_next);
    +				free(ppm);
    +			}
     			LIST_REMOVE(pp, pp_next);
     			free(pp);
     		}
    @@ -2610,23 +2086,23 @@ pmcstat_shutdown_logging(struct pmcstat_args *a)
     	 * Print errors unless -q was specified.  Print all statistics
     	 * if verbosity > 1.
     	 */
    -#define	PRINT(N,V,A) do {						\
    -		if (pmcstat_stats.ps_##V || (A)->pa_verbosity >= 2)	\
    -			(void) fprintf((A)->pa_printfile, " %-40s %d\n",\
    +#define	PRINT(N,V) do {							\
    +		if (pmcstat_stats.ps_##V || args.pa_verbosity >= 2)	\
    +			(void) fprintf(args.pa_printfile, " %-40s %d\n",\
     			    N, pmcstat_stats.ps_##V);			\
     	} while (0)
     
    -	if (a->pa_verbosity >= 1 && a->pa_flags & FLAG_DO_GPROF) {
    -		(void) fprintf(a->pa_printfile, "CONVERSION STATISTICS:\n");
    -		PRINT("#exec/a.out", exec_aout, a);
    -		PRINT("#exec/elf", exec_elf, a);
    -		PRINT("#exec/unknown", exec_indeterminable, a);
    -		PRINT("#exec handling errors", exec_errors, a);
    -		PRINT("#samples/total", samples_total, a);
    -		PRINT("#samples/unclaimed", samples_unknown_offset, a);
    -		PRINT("#samples/unknown-object", samples_indeterminable, a);
    -		PRINT("#callchain/dubious-frames", callchain_dubious_frames,
    -		    a);
    +	if (args.pa_verbosity >= 1 && (args.pa_flags & FLAG_DO_ANALYSIS) &&
    +	    (args.pa_flags & FLAG_DO_TOP) == 0) {
    +		(void) fprintf(args.pa_printfile, "CONVERSION STATISTICS:\n");
    +		PRINT("#exec/a.out", exec_aout);
    +		PRINT("#exec/elf", exec_elf);
    +		PRINT("#exec/unknown", exec_indeterminable);
    +		PRINT("#exec handling errors", exec_errors);
    +		PRINT("#samples/total", samples_total);
    +		PRINT("#samples/unclaimed", samples_unknown_offset);
    +		PRINT("#samples/unknown-object", samples_indeterminable);
    +		PRINT("#callchain/dubious-frames", callchain_dubious_frames);
     	}
     
     	if (mf)
    diff --git a/usr.sbin/pmcstat/pmcstat_log.h b/usr.sbin/pmcstat/pmcstat_log.h
    new file mode 100644
    index 00000000000..de92649c0d7
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcstat_log.h
    @@ -0,0 +1,196 @@
    +/*-
    + * Copyright (c) 2005-2007, Joseph Koshy
    + * Copyright (c) 2007 The FreeBSD Foundation
    + * Copyright (c) 2009, Fabien Thomas
    + * All rights reserved.
    + *
    + * Portions of this software were developed by A. Joseph Koshy under
    + * sponsorship from the FreeBSD Foundation and 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.
    + *
    + * $FreeBSD$
    + */
    +
    +#ifndef	_PMCSTAT_LOG_H_
    +#define	_PMCSTAT_LOG_H_
    +
    +typedef const void *pmcstat_interned_string;
    +
    +/*
    + * A 'pmcstat_process' structure models processes.  Each process is
    + * associated with a set of pmcstat_pcmap structures that map
    + * addresses inside it to executable objects.  This set is implemented
    + * as a list, kept sorted in ascending order of mapped addresses.
    + *
    + * 'pp_pid' holds the pid of the process.  When a process exits, the
    + * 'pp_isactive' field is set to zero, but the process structure is
    + * not immediately reclaimed because there may still be samples in the
    + * log for this process.
    + */
    +
    +struct pmcstat_process {
    +	LIST_ENTRY(pmcstat_process) pp_next;	/* hash-next */
    +	pid_t			pp_pid;		/* associated pid */
    +	int			pp_isactive;	/* whether active */
    +	uintfptr_t		pp_entryaddr;	/* entry address */
    +	TAILQ_HEAD(,pmcstat_pcmap) pp_map;	/* address range map */
    +};
    +extern LIST_HEAD(pmcstat_process_hash_list, pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH];
    +
    +/*
    + * A 'pmcstat_image' structure describes an executable program on
    + * disk.  'pi_execpath' is a cookie representing the pathname of
    + * the executable.  'pi_start' and 'pi_end' are the least and greatest
    + * virtual addresses for the text segments in the executable.
    + * 'pi_gmonlist' contains a linked list of gmon.out files associated
    + * with this image.
    + */
    +
    +enum pmcstat_image_type {
    +	PMCSTAT_IMAGE_UNKNOWN = 0,	/* never looked at the image */
    +	PMCSTAT_IMAGE_INDETERMINABLE,	/* can't tell what the image is */
    +	PMCSTAT_IMAGE_ELF32,		/* ELF 32 bit object */
    +	PMCSTAT_IMAGE_ELF64,		/* ELF 64 bit object */
    +	PMCSTAT_IMAGE_AOUT		/* AOUT object */
    +};
    +
    +struct pmcstat_image {
    +	LIST_ENTRY(pmcstat_image) pi_next;	/* hash link */
    +	TAILQ_ENTRY(pmcstat_image) pi_lru;	/* LRU list */
    +	pmcstat_interned_string	pi_execpath;    /* cookie */
    +	pmcstat_interned_string pi_samplename;  /* sample path name */
    +	pmcstat_interned_string pi_fullpath;    /* path to FS object */
    +	pmcstat_interned_string pi_name;	/* display name */
    +
    +	enum pmcstat_image_type pi_type;	/* executable type */
    +
    +	/*
    +	 * Executables have pi_start and pi_end; these are zero
    +	 * for shared libraries.
    +	 */
    +	uintfptr_t	pi_start;	/* start address (inclusive) */
    +	uintfptr_t	pi_end;		/* end address (exclusive) */
    +	uintfptr_t	pi_entry;	/* entry address */
    +	uintfptr_t	pi_vaddr;	/* virtual address where loaded */
    +	int		pi_isdynamic;	/* whether a dynamic object */
    +	int		pi_iskernelmodule;
    +	pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */
    +
    +	/* All symbols associated with this object. */
    +	struct pmcstat_symbol *pi_symbols;
    +	size_t		pi_symcount;
    +
    +	/* Handle to addr2line for this image. */
    +	FILE *pi_addr2line;
    +
    +	/*
    +	 * Plugins private data
    +	 */
    +
    +	/* gprof:
    +	 * An image can be associated with one or more gmon.out files;
    +	 * one per PMC.
    +	 */
    +	LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
    +};
    +extern LIST_HEAD(pmcstat_image_hash_list, pmcstat_image) pmcstat_image_hash[PMCSTAT_NHASH];
    +
    +/*
    + * A 'pmcstat_pcmap' structure maps a virtual address range to an
    + * underlying 'pmcstat_image' descriptor.
    + */
    +struct pmcstat_pcmap {
    +	TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
    +	uintfptr_t	ppm_lowpc;
    +	uintfptr_t	ppm_highpc;
    +	struct pmcstat_image *ppm_image;
    +};
    +
    +/*
    + * Each function symbol tracked by pmcstat(8).
    + */
    +
    +struct pmcstat_symbol {
    +	pmcstat_interned_string ps_name;
    +	uint64_t	ps_start;
    +	uint64_t	ps_end;
    +};
    +
    +/*
    + * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable
    + * names.
    + */
    +
    +struct pmcstat_pmcrecord {
    +	LIST_ENTRY(pmcstat_pmcrecord)	pr_next;
    +	pmc_id_t			pr_pmcid;
    +	int				pr_pmcin;
    +	pmcstat_interned_string		pr_pmcname;
    +	struct pmcstat_pmcrecord	*pr_merge;
    +};
    +extern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs; /* PMC list */
    +
    +/*
    + * Misc. statistics
    + */
    +struct pmcstat_stats {
    +	int ps_exec_aout;	/* # a.out executables seen */
    +	int ps_exec_elf;	/* # elf executables seen */
    +	int ps_exec_errors;	/* # errors processing executables */
    +	int ps_exec_indeterminable; /* # unknown executables seen */
    +	int ps_samples_total;	/* total number of samples processed */
    +	int ps_samples_skipped; /* #samples filtered out for any reason */
    +	int ps_samples_unknown_offset;	/* #samples of rank 0 not in a map */
    +	int ps_samples_indeterminable;	/* #samples in indeterminable images */
    +	int ps_callchain_dubious_frames;/* #dubious frame pointers seen */
    +};
    +extern struct pmcstat_stats pmcstat_stats; /* statistics */
    +
    +extern struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
    +
    +extern int pmcstat_npmcs; /* PMC count. */
    +
    +/*
    + * Top mode global options.
    + */
    +float pmcstat_threshold; /* Threshold to filter node. */
    +int pmcstat_pmcinfilter; /* PMC index displayed. */
    +
    +/* Function prototypes */
    +const char *pmcstat_pmcid_to_name(pmc_id_t _pmcid);
    +const char *pmcstat_pmcindex_to_name(int pmcin);
    +struct pmcstat_pmcrecord *pmcstat_pmcindex_to_pmcr(int pmcin);
    +struct pmcstat_pcmap *pmcstat_process_find_map(struct pmcstat_process *_p,
    +	uintfptr_t _pc);
    +struct pmcstat_symbol *pmcstat_symbol_search(struct pmcstat_image *image,
    +	uintfptr_t addr);
    +const char *pmcstat_string_unintern(pmcstat_interned_string _is);
    +pmcstat_interned_string pmcstat_string_intern(const char *_s);
    +void pmcstat_image_determine_type(struct pmcstat_image *_image);
    +pmcstat_interned_string pmcstat_string_lookup(const char *_s);
    +int pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr,
    +    char *sourcefile, size_t sourcefile_len, unsigned *sourceline,
    +    char *funcname, size_t funcname_len);
    +
    +#endif	/* _PMCSTAT_LOG_H_ */
    +
    diff --git a/usr.sbin/pmcstat/pmcstat_top.h b/usr.sbin/pmcstat/pmcstat_top.h
    new file mode 100644
    index 00000000000..281410b09ca
    --- /dev/null
    +++ b/usr.sbin/pmcstat/pmcstat_top.h
    @@ -0,0 +1,75 @@
    +/*-
    + * Copyright (c) 2009, Fabien Thomas
    + * 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	_PMCSTAT_TOP_H_
    +#define	_PMCSTAT_TOP_H_
    +
    +/* Return the ncurses attributes for the given value. */
    +#define PMCSTAT_ATTRPERCENT(b) 					\
    +    ((b) > 10.0 ? (args.pa_topcolor ? COLOR_PAIR(1) : A_BOLD) :	\
    +    ((b) >  5.0 ? (args.pa_topcolor ? COLOR_PAIR(2) : 0) : 	\
    +    ((b) >  2.5 ? (args.pa_topcolor ? COLOR_PAIR(3) : 0) : 0)))
    +
    +/* Print to the default ncurse windows if on a terminal or to the file. */
    +#define PMCSTAT_PRINTW(...) do {			\
    +	if (args.pa_toptty)				\
    +		printw(__VA_ARGS__);			\
    +	else						\
    +		fprintf(args.pa_printfile, __VA_ARGS__);\
    +} while (0)
    +
    +/* If ncurses mode active set attributes. */
    +#define PMCSTAT_ATTRON(b) do {				\
    +	if (args.pa_toptty)				\
    +		attron(b);				\
    +} while (0)
    +
    +/* If ncurses mode active unset attributes. */
    +#define PMCSTAT_ATTROFF(b) do {				\
    +	if (args.pa_toptty)				\
    +		attroff(b);				\
    +} while (0)
    +
    +/* Erase screen and set cursor to top left. */
    +#define PMCSTAT_PRINTBEGIN() do {			\
    +	if (args.pa_toptty)				\
    +		clear();				\
    +} while (0)
    +
    +/* Flush buffer to backend. */
    +#define PMCSTAT_PRINTEND() do {				\
    +	if (!args.pa_toptty) {				\
    +		PMCSTAT_PRINTW("---\n");		\
    +		fflush(args.pa_printfile);		\
    +	} else						\
    +		refresh();				\
    +} while (0)
    +
    +/* Function prototypes */
    +
    +#endif	/* _PMCSTAT_TOP_H_ */
    
    From 02178aec70ae348343390664535dce4e2d384b23 Mon Sep 17 00:00:00 2001
    From: Fabien Thomas 
    Date: Fri, 5 Mar 2010 22:52:41 +0000
    Subject: [PATCH 1558/2592] MFC 204329 partially: Fixed dependencies (make
     checkdpadd).
    
    ---
     usr.sbin/pmcstat/Makefile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/usr.sbin/pmcstat/Makefile b/usr.sbin/pmcstat/Makefile
    index 4412e24d9ca..2bd8133ed17 100644
    --- a/usr.sbin/pmcstat/Makefile
    +++ b/usr.sbin/pmcstat/Makefile
    @@ -5,7 +5,7 @@
     PROG=	pmcstat
     MAN=	pmcstat.8
     
    -DPADD=	${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM}
    +DPADD=	${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM} ${LIBNCURSES}
     LDADD=	-lelf -lkvm -lpmc -lm -lncurses
     
     WARNS?=	6
    
    From d3fe3690fbc9bc0028a602bf101387931e309caf Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Sat, 6 Mar 2010 12:35:33 +0000
    Subject: [PATCH 1559/2592] MFC r204413: For kinfo_proc in kp->ki_siglist,
     return the set of the signals pending in the process queue when gathering
     information for the process, and set of signals pending for the thread, when
     gathering information for the thread.
    
    ---
     sys/kern/kern_proc.c | 10 ++++++----
     1 file changed, 6 insertions(+), 4 deletions(-)
    
    diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
    index 353a4e667c6..51136981189 100644
    --- a/sys/kern/kern_proc.c
    +++ b/sys/kern/kern_proc.c
    @@ -829,9 +829,10 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp)
     }
     
     /*
    - * Fill in information that is thread specific.  Must be called with p_slock
    - * locked.  If 'preferthread' is set, overwrite certain process-related
    - * fields that are maintained for both threads and processes.
    + * Fill in information that is thread specific.  Must be called with
    + * target process locked.  If 'preferthread' is set, overwrite certain
    + * process-related fields that are maintained for both threads and
    + * processes.
      */
     static void
     fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread)
    @@ -900,7 +901,8 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread)
     	/* We can't get this anymore but ps etc never used it anyway. */
     	kp->ki_rqindex = 0;
     
    -	SIGSETOR(kp->ki_siglist, td->td_siglist);
    +	if (preferthread)
    +		kp->ki_siglist = td->td_siglist;
     	kp->ki_sigmask = td->td_sigmask;
     	thread_unlock(td);
     }
    
    From d5f57f7e08d2216f52e36a393b677d95cb9865ee Mon Sep 17 00:00:00 2001
    From: Marcel Moolenaar 
    Date: Sun, 7 Mar 2010 00:05:44 +0000
    Subject: [PATCH 1560/2592] MFC revs 203696, 203708, 203783 and 203788: Add
     PT_VM_TIMESTAMP and PT_VM_ENTRY so that the tracing process can obtain the
     memory map of the traced process.
    
    Requested by: kib@
    ---
     sys/kern/sys_process.c | 179 +++++++++++++++++++++++++++++++++++++++++
     sys/sys/ptrace.h       |  18 +++++
     2 files changed, 197 insertions(+)
    
    diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
    index a4e0be8438b..313167ddbc8 100644
    --- a/sys/kern/sys_process.c
    +++ b/sys/kern/sys_process.c
    @@ -72,6 +72,20 @@ struct ptrace_io_desc32 {
     	u_int32_t	piod_addr;
     	u_int32_t	piod_len;
     };
    +
    +struct ptrace_vm_entry32 {
    +	int		pve_entry;
    +	int		pve_timestamp;
    +	uint32_t	pve_start;
    +	uint32_t	pve_end;
    +	uint32_t	pve_offset;
    +	u_int		pve_prot;
    +	u_int		pve_pathlen;
    +	int32_t		pve_fileid;
    +	u_int		pve_fsid;
    +	uint32_t	pve_path;
    +};
    +
     #endif
     
     /*
    @@ -339,6 +353,148 @@ proc_rwmem(struct proc *p, struct uio *uio)
     	return (error);
     }
     
    +static int
    +ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
    +{
    +	struct vattr vattr;
    +	vm_map_t map;
    +	vm_map_entry_t entry;
    +	vm_object_t obj, tobj, lobj;
    +	struct vmspace *vm;
    +	struct vnode *vp;
    +	char *freepath, *fullpath;
    +	u_int pathlen;
    +	int error, index, vfslocked;
    +
    +	error = 0;
    +	obj = NULL;
    +
    +	vm = vmspace_acquire_ref(p);
    +	map = &vm->vm_map;
    +	vm_map_lock_read(map);
    +
    +	do {
    +		entry = map->header.next;
    +		index = 0;
    +		while (index < pve->pve_entry && entry != &map->header) {
    +			entry = entry->next;
    +			index++;
    +		}
    +		if (index != pve->pve_entry) {
    +			error = EINVAL;
    +			break;
    +		}
    +		while (entry != &map->header &&
    +		    (entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0) {
    +			entry = entry->next;
    +			index++;
    +		}
    +		if (entry == &map->header) {
    +			error = ENOENT;
    +			break;
    +		}
    +
    +		/* We got an entry. */
    +		pve->pve_entry = index + 1;
    +		pve->pve_timestamp = map->timestamp;
    +		pve->pve_start = entry->start;
    +		pve->pve_end = entry->end - 1;
    +		pve->pve_offset = entry->offset;
    +		pve->pve_prot = entry->protection;
    +
    +		/* Backing object's path needed? */
    +		if (pve->pve_pathlen == 0)
    +			break;
    +
    +		pathlen = pve->pve_pathlen;
    +		pve->pve_pathlen = 0;
    +
    +		obj = entry->object.vm_object;
    +		if (obj != NULL)
    +			VM_OBJECT_LOCK(obj);
    +	} while (0);
    +
    +	vm_map_unlock_read(map);
    +	vmspace_free(vm);
    +
    +	pve->pve_fsid = VNOVAL;
    +	pve->pve_fileid = VNOVAL;
    +
    +	if (error == 0 && obj != NULL) {
    +		lobj = obj;
    +		for (tobj = obj; tobj != NULL; tobj = tobj->backing_object) {
    +			if (tobj != obj)
    +				VM_OBJECT_LOCK(tobj);
    +			if (lobj != obj)
    +				VM_OBJECT_UNLOCK(lobj);
    +			lobj = tobj;
    +			pve->pve_offset += tobj->backing_object_offset;
    +		}
    +		vp = (lobj->type == OBJT_VNODE) ? lobj->handle : NULL;
    +		if (vp != NULL)
    +			vref(vp);
    +		if (lobj != obj)
    +			VM_OBJECT_UNLOCK(lobj);
    +		VM_OBJECT_UNLOCK(obj);
    +
    +		if (vp != NULL) {
    +			freepath = NULL;
    +			fullpath = NULL;
    +			vn_fullpath(td, vp, &fullpath, &freepath);
    +			vfslocked = VFS_LOCK_GIANT(vp->v_mount);
    +			vn_lock(vp, LK_SHARED | LK_RETRY);
    +			if (VOP_GETATTR(vp, &vattr, td->td_ucred) == 0) {
    +				pve->pve_fileid = vattr.va_fileid;
    +				pve->pve_fsid = vattr.va_fsid;
    +			}
    +			vput(vp);
    +			VFS_UNLOCK_GIANT(vfslocked);
    +
    +			if (fullpath != NULL) {
    +				pve->pve_pathlen = strlen(fullpath) + 1;
    +				if (pve->pve_pathlen <= pathlen) {
    +					error = copyout(fullpath, pve->pve_path,
    +					    pve->pve_pathlen);
    +				} else
    +					error = ENAMETOOLONG;
    +			}
    +			if (freepath != NULL)
    +				free(freepath, M_TEMP);
    +		}
    +	}
    +
    +	return (error);
    +}
    +
    +#ifdef COMPAT_IA32
    +static int      
    +ptrace_vm_entry32(struct thread *td, struct proc *p,
    +    struct ptrace_vm_entry32 *pve32)
    +{
    +	struct ptrace_vm_entry pve;
    +	int error;
    +
    +	pve.pve_entry = pve32->pve_entry;
    +	pve.pve_pathlen = pve32->pve_pathlen;
    +	pve.pve_path = (void *)(uintptr_t)pve32->pve_path;
    +
    +	error = ptrace_vm_entry(td, p, &pve);
    +	if (error == 0) {
    +		pve32->pve_entry = pve.pve_entry;
    +		pve32->pve_timestamp = pve.pve_timestamp;
    +		pve32->pve_start = pve.pve_start;
    +		pve32->pve_end = pve.pve_end;
    +		pve32->pve_offset = pve.pve_offset;
    +		pve32->pve_prot = pve.pve_prot;
    +		pve32->pve_fileid = pve.pve_fileid;
    +		pve32->pve_fsid = pve.pve_fsid;
    +	}
    +
    +	pve32->pve_pathlen = pve.pve_pathlen;
    +	return (error);
    +}
    +#endif /* COMPAT_IA32 */
    +
     /*
      * Process debugging system call.
      */
    @@ -382,6 +538,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
     	union {
     		struct ptrace_io_desc piod;
     		struct ptrace_lwpinfo pl;
    +		struct ptrace_vm_entry pve;
     		struct dbreg dbreg;
     		struct fpreg fpreg;
     		struct reg reg;
    @@ -390,6 +547,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
     		struct fpreg32 fpreg32;
     		struct reg32 reg32;
     		struct ptrace_io_desc32 piod32;
    +		struct ptrace_vm_entry32 pve32;
     #endif
     	} r;
     	void *addr;
    @@ -422,6 +580,9 @@ ptrace(struct thread *td, struct ptrace_args *uap)
     	case PT_IO:
     		error = COPYIN(uap->addr, &r.piod, sizeof r.piod);
     		break;
    +	case PT_VM_ENTRY:
    +		error = COPYIN(uap->addr, &r.pve, sizeof r.pve);
    +		break;
     	default:
     		addr = uap->addr;
     		break;
    @@ -434,6 +595,9 @@ ptrace(struct thread *td, struct ptrace_args *uap)
     		return (error);
     
     	switch (uap->req) {
    +	case PT_VM_ENTRY:
    +		error = COPYOUT(&r.pve, uap->addr, sizeof r.pve);
    +		break;
     	case PT_IO:
     		error = COPYOUT(&r.piod, uap->addr, sizeof r.piod);
     		break;
    @@ -970,6 +1134,21 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
     		PROC_LOCK(p);
     		break;
     
    +	case PT_VM_TIMESTAMP:
    +		td->td_retval[0] = p->p_vmspace->vm_map.timestamp;
    +		break;
    +
    +	case PT_VM_ENTRY:
    +		PROC_UNLOCK(p);
    +#ifdef COMPAT_IA32
    +		if (wrap32)
    +			error = ptrace_vm_entry32(td, p, addr);
    +		else
    +#endif
    +		error = ptrace_vm_entry(td, p, addr);
    +		PROC_LOCK(p);
    +		break;
    +
     	default:
     #ifdef __HAVE_PTRACE_MACHDEP
     		if (req >= PT_FIRSTMACH) {
    diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
    index 8fd52cb4451..e3653b657d1 100644
    --- a/sys/sys/ptrace.h
    +++ b/sys/sys/ptrace.h
    @@ -67,6 +67,10 @@
     #define PT_SETFPREGS    36	/* set floating-point registers */
     #define PT_GETDBREGS    37	/* get debugging registers */
     #define PT_SETDBREGS    38	/* set debugging registers */
    +
    +#define	PT_VM_TIMESTAMP	40	/* Get VM version (timestamp) */
    +#define	PT_VM_ENTRY	41	/* Get VM map (entry) */
    +
     #define PT_FIRSTMACH    64	/* for machine-specific requests */
     #include 	/* machine-specific requests, if any */
     
    @@ -98,6 +102,20 @@ struct ptrace_lwpinfo {
     	sigset_t	pl_siglist;	/* LWP pending signal */
     };
     
    +/* Argument structure for PT_VM_ENTRY. */
    +struct ptrace_vm_entry {
    +	int		pve_entry;	/* Entry number used for iteration. */
    +	int		pve_timestamp;	/* Generation number of VM map. */
    +	u_long		pve_start;	/* Start VA of range. */
    +	u_long		pve_end;	/* End VA of range (incl). */
    +	u_long		pve_offset;	/* Offset in backing object. */
    +	u_int		pve_prot;	/* Protection of memory range. */
    +	u_int		pve_pathlen;	/* Size of path. */
    +	long		pve_fileid;	/* File ID. */
    +	uint32_t	pve_fsid;	/* File system ID. */
    +	char		*pve_path;	/* Path name of object. */
    +};
    +
     #ifdef _KERNEL
     
     #define	PTRACESTOP_SC(p, td, flag)				\
    
    From 35420d4867448e87d00dc06633556ca04302d3e6 Mon Sep 17 00:00:00 2001
    From: Marcel Moolenaar 
    Date: Sun, 7 Mar 2010 00:07:00 +0000
    Subject: [PATCH 1561/2592] MFC revs 203696, 203783: Add PT_VM_TIMESTAMP and
     PT_VM_ENTRY so that the tracing process can obtain the memory map of the
     traced process.
    
    Requested by: kib@
    ---
     lib/libc/sys/ptrace.2 | 85 ++++++++++++++++++++++++++++++++++++++++++-
     1 file changed, 84 insertions(+), 1 deletion(-)
    
    diff --git a/lib/libc/sys/ptrace.2 b/lib/libc/sys/ptrace.2
    index 9d8f5507c41..8265fb638b4 100644
    --- a/lib/libc/sys/ptrace.2
    +++ b/lib/libc/sys/ptrace.2
    @@ -2,7 +2,7 @@
     .\"	$NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
     .\"
     .\" This file is in the public domain.
    -.Dd March 27, 2009
    +.Dd February 11, 2010
     .Dt PTRACE 2
     .Os
     .Sh NAME
    @@ -327,6 +327,68 @@ This request will trace the specified process on each system call exit.
     .It PT_SYSCALL
     This request will trace the specified process
     on each system call entry and exit.
    +.It PT_VM_TIMESTAMP
    +This request returns the generation number or timestamp of the memory map of
    +the traced process as the return value from
    +.Fn ptrace .
    +This provides a low-cost way for the tracing process to determine if the
    +VM map changed since the last time this request was made.
    +.It PT_VM_ENTRY
    +This request is used to iterate over the entries of the VM map of the traced
    +process.
    +The
    +.Fa addr
    +argument specifies a pointer to a 
    +.Vt "struct ptrace_vm_entry" ,
    +which is defined as follows:
    +.Bd -literal
    +struct ptrace_vm_entry {
    +	int		pve_entry;
    +	int		pve_timestamp;
    +	u_long		pve_start;
    +	u_long		pve_end;
    +	u_long		pve_offset;
    +	u_int		pve_prot;
    +	u_int		pve_pathlen;
    +	long		pve_fileid;
    +	uint32_t	pve_fsid;
    +	char		*pve_path;
    +};
    +.Ed
    +.Pp
    +The first entry is returned by setting
    +.Va pve_entry
    +to zero.
    +Subsequent entries are returned by leaving
    +.Va pve_entry
    +unmodified from the value returned by previous requests.
    +The
    +.Va pve_timestamp
    +field can be used to detect changes to the VM map while iterating over the
    +entries.
    +The tracing process can then take appropriate action, such as restarting.
    +By setting
    +.Va pve_pathlen
    +to a non-zero value on entry, the pathname of the backing object is returned
    +in the buffer pointed to by
    +.Va pve_path ,
    +provided the entry is backed by a vnode.
    +The
    +.Va pve_pathlen
    +field is updated with the actual length of the pathname (including the
    +terminating null character).
    +The
    +.Va pve_offset
    +field is the offset within the backing object at which the range starts.
    +The range is located in the VM space at
    +.Va pve_start
    +and extends up to
    +.Va pve_end
    +(inclusive).
    +.Pp
    +The
    +.Fa data
    +argument is ignored.
     .El
     .Pp
     Additionally, machine-specific requests can exist.
    @@ -376,6 +438,11 @@ or
     .Dv PT_SETDBREGS
     was attempted on a process with no valid register set.
     (This is normally true only of system processes.)
    +.It
    +.Dv PT_VM_ENTRY
    +was given an invalid value for
    +.Fa pve_entry .
    +This can also be caused by changes to the VM map of the process.
     .El
     .It Bq Er EBUSY
     .Bl -bullet -compact
    @@ -405,6 +472,22 @@ on a process in violation of the requirements listed under
     .Dv PT_ATTACH
     above.
     .El
    +.It Bq Er ENOENT
    +.Bl -bullet -compact
    +.It
    +.Dv PT_VM_ENTRY
    +previously returned the last entry of the memory map.
    +No more entries exist.
    +.El
    +.It Bq Er ENAMETOOLONG
    +.Bl -bullet -compact
    +.It
    +.Dv PT_VM_ENTRY
    +cannot return the pathname of the backing object because the buffer is not big
    +enough.
    +.Fa pve_pathlen
    +holds the minimum buffer size required on return.
    +.El
     .El
     .Sh SEE ALSO
     .Xr execve 2 ,
    
    From 1b0154570eee6c21b5189f038c61afe3afaccfa2 Mon Sep 17 00:00:00 2001
    From: Gregory Neil Shapiro 
    Date: Sun, 7 Mar 2010 02:02:07 +0000
    Subject: [PATCH 1562/2592] MFC: Enable the use of nanosleep() instead of using
     pause() and signals.      This Makefile change can be removed when the next
     version of sendmail      is imported as it will have this built in to the
     FreeBSD conf.h section.
    
    ---
     lib/libsm/Makefile | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/lib/libsm/Makefile b/lib/libsm/Makefile
    index 38c780617e7..0fdcaa18c69 100644
    --- a/lib/libsm/Makefile
    +++ b/lib/libsm/Makefile
    @@ -7,6 +7,7 @@ SENDMAIL_DIR=${.CURDIR}/../../contrib/sendmail
     
     CFLAGS+=-I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include -I.
     CFLAGS+=-DNEWDB -DNIS -DMAP_REGEX -DNOT_SENDMAIL
    +CFLAGS+=-DHAVE_NANOSLEEP
     
     .if ${MK_INET6_SUPPORT} != "no"
     CFLAGS+=-DNETINET6
    
    From 272a1b69012160be3a004c27e6ec6c0ace005ed9 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Sun, 7 Mar 2010 09:52:35 +0000
    Subject: [PATCH 1563/2592] MFC r204464: Several fixes for miscellaneous clone
     handlers in if_tun and if_tap.
    
    ---
     sys/net/if_tap.c | 13 +++----------
     sys/net/if_tun.c | 11 ++---------
     2 files changed, 5 insertions(+), 19 deletions(-)
    
    diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c
    index 950e96ca9d2..93801f10412 100644
    --- a/sys/net/if_tap.c
    +++ b/sys/net/if_tap.c
    @@ -192,10 +192,6 @@ tap_clone_create(struct if_clone *ifc, int unit, caddr_t params)
     	if (i) {
     		dev = make_dev(&tap_cdevsw, unit | extra,
     		     UID_ROOT, GID_WHEEL, 0600, "%s%d", ifc->ifc_name, unit);
    -		if (dev != NULL) {
    -			dev_ref(dev);
    -			dev->si_flags |= SI_CHEAPCLONE;
    -		}
     	}
     
     	tapcreate(dev);
    @@ -300,6 +296,7 @@ tapmodevent(module_t mod, int type, void *data)
     		EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
     		if_clone_detach(&tap_cloner);
     		if_clone_detach(&vmnet_cloner);
    +		drain_dev_clone_events();
     
     		mtx_lock(&tapmtx);
     		while ((tp = SLIST_FIRST(&taphead)) != NULL) {
    @@ -381,12 +378,8 @@ tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **d
     			name = devname;
     		}
     
    -		*dev = make_dev(&tap_cdevsw, unit | extra,
    -		     UID_ROOT, GID_WHEEL, 0600, "%s", name);
    -		if (*dev != NULL) {
    -			dev_ref(*dev);
    -			(*dev)->si_flags |= SI_CHEAPCLONE;
    -		}
    +		*dev = make_dev_credf(MAKEDEV_REF, &tap_cdevsw, unit | extra,
    +		     cred, UID_ROOT, GID_WHEEL, 0600, "%s", name);
     	}
     
     	if_clone_create(name, namelen, NULL);
    diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
    index 37b5e70302c..1fa02ac9f11 100644
    --- a/sys/net/if_tun.c
    +++ b/sys/net/if_tun.c
    @@ -188,10 +188,6 @@ tun_clone_create(struct if_clone *ifc, int unit, caddr_t params)
     		/* No preexisting struct cdev *, create one */
     		dev = make_dev(&tun_cdevsw, unit,
     		    UID_UUCP, GID_DIALER, 0600, "%s%d", ifc->ifc_name, unit);
    -		if (dev != NULL) {
    -			dev_ref(dev);
    -			dev->si_flags |= SI_CHEAPCLONE;
    -		}
     	}
     	tuncreate(ifc->ifc_name, dev);
     
    @@ -237,12 +233,8 @@ tunclone(void *arg, struct ucred *cred, char *name, int namelen,
     			name = devname;
     		}
     		/* No preexisting struct cdev *, create one */
    -		*dev = make_dev(&tun_cdevsw, u,
    +		*dev = make_dev_credf(MAKEDEV_REF, &tun_cdevsw, u, cred,
     		    UID_UUCP, GID_DIALER, 0600, "%s", name);
    -		if (*dev != NULL) {
    -			dev_ref(*dev);
    -			(*dev)->si_flags |= SI_CHEAPCLONE;
    -		}
     	}
     
     	if_clone_create(name, namelen, NULL);
    @@ -303,6 +295,7 @@ tunmodevent(module_t mod, int type, void *data)
     	case MOD_UNLOAD:
     		if_clone_detach(&tun_cloner);
     		EVENTHANDLER_DEREGISTER(dev_clone, tag);
    +		drain_dev_clone_events();
     
     		mtx_lock(&tunmtx);
     		while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
    
    From 90cb9e50f4841a1084eee9a42936a667da7dd82e Mon Sep 17 00:00:00 2001
    From: Ivan Voras 
    Date: Sun, 7 Mar 2010 12:29:50 +0000
    Subject: [PATCH 1564/2592] MFC r204611, r204633: Comment and better sysctl
     documentation string for VM guest detection variable and sysctl.
    
    ---
     sys/kern/subr_param.c | 2 +-
     sys/sys/systm.h       | 5 +++++
     2 files changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c
    index a4d4ff87c44..f8d60dd7a4c 100644
    --- a/sys/kern/subr_param.c
    +++ b/sys/kern/subr_param.c
    @@ -124,7 +124,7 @@ SYSCTL_ULONG(_kern, OID_AUTO, sgrowsiz, CTLFLAG_RDTUN, &sgrowsiz, 0,
         "Amount to grow stack on a stack fault");
     SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CTLTYPE_STRING,
         NULL, 0, sysctl_kern_vm_guest, "A",
    -    "Virtual machine detected? (none|generic|xen)");
    +    "Virtual machine guest detected? (none|generic|xen)");
     
     /*
      * These have to be allocated somewhere; allocating
    diff --git a/sys/sys/systm.h b/sys/sys/systm.h
    index 1359bcd7c37..13014be5a7e 100644
    --- a/sys/sys/systm.h
    +++ b/sys/sys/systm.h
    @@ -67,6 +67,11 @@ extern int maxusers;		/* system tune hint */
     extern int ngroups_max;		/* max # of supplemental groups */
     extern int vm_guest;		/* Running as virtual machine guest? */
     
    +/*
    + * Detected virtual machine guest types. The intention is to expand
    + * and/or add to the VM_GUEST_VM type if specific VM functionality is
    + * ever implemented (e.g. vendor-specific paravirtualization features).
    + */
     enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
     
     #ifdef	INVARIANTS		/* The option is always available */
    
    From f078d8617f6aae1d715b49766db930ade8d7d7aa Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Sun, 7 Mar 2010 14:29:12 +0000
    Subject: [PATCH 1565/2592] MFC r197137 and r200510, which fixes a problem in
     8.0 with callouts firing one tick too late. See the logs for the original
     patch for details. RELENG_7 is not affected by the problem.
    
    ---
     sys/kern/kern_timeout.c | 25 ++++++++++++++++++++++---
     1 file changed, 22 insertions(+), 3 deletions(-)
    
    diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
    index 7df03dc91e1..c38888a5f89 100644
    --- a/sys/kern/kern_timeout.c
    +++ b/sys/kern/kern_timeout.c
    @@ -82,6 +82,23 @@ SYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls, CTLFLAG_RD, &avg_mpcalls, 0,
      */
     int callwheelsize, callwheelbits, callwheelmask;
     
    +/*
    + * There is one struct callout_cpu per cpu, holding all relevant
    + * state for the callout processing thread on the individual CPU.
    + * In particular:
    + *	cc_ticks is incremented once per tick in callout_cpu().
    + *	It tracks the global 'ticks' but in a way that the individual
    + *	threads should not worry about races in the order in which
    + *	hardclock() and hardclock_cpu() run on the various CPUs.
    + *	cc_softclock is advanced in callout_cpu() to point to the
    + *	first entry in cc_callwheel that may need handling. In turn,
    + *	a softclock() is scheduled so it can serve the various entries i
    + *	such that cc_softclock <= i <= cc_ticks .
    + *	XXX maybe cc_softclock and cc_ticks should be volatile ?
    + *
    + *	cc_ticks is also used in callout_reset_cpu() to determine
    + *	when the callout should be served.
    + */
     struct callout_cpu {
     	struct mtx		cc_lock;
     	struct callout		*cc_callout;
    @@ -90,6 +107,7 @@ struct callout_cpu {
     	struct callout		*cc_next;
     	struct callout		*cc_curr;
     	void			*cc_cookie;
    +	int 			cc_ticks;
     	int 			cc_softticks;
     	int			cc_cancel;
     	int			cc_waiting;
    @@ -244,7 +262,8 @@ callout_tick(void)
     	need_softclock = 0;
     	cc = CC_SELF();
     	mtx_lock_spin_flags(&cc->cc_lock, MTX_QUIET);
    -	for (; (cc->cc_softticks - ticks) < 0; cc->cc_softticks++) {
    +	cc->cc_ticks++;
    +	for (; (cc->cc_softticks - cc->cc_ticks) <= 0; cc->cc_softticks++) {
     		bucket = cc->cc_softticks & callwheelmask;
     		if (!TAILQ_EMPTY(&cc->cc_callwheel[bucket])) {
     			need_softclock = 1;
    @@ -323,7 +342,7 @@ softclock(void *arg)
     	steps = 0;
     	cc = (struct callout_cpu *)arg;
     	CC_LOCK(cc);
    -	while (cc->cc_softticks != ticks) {
    +	while (cc->cc_softticks - 1 != cc->cc_ticks) {
     		/*
     		 * cc_softticks may be modified by hard clock, so cache
     		 * it while we work on a given bucket.
    @@ -622,7 +641,7 @@ retry:
     	c->c_arg = arg;
     	c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING);
     	c->c_func = ftn;
    -	c->c_time = ticks + to_ticks;
    +	c->c_time = cc->cc_ticks + to_ticks;
     	TAILQ_INSERT_TAIL(&cc->cc_callwheel[c->c_time & callwheelmask], 
     			  c, c_links.tqe);
     	CTR5(KTR_CALLOUT, "%sscheduled %p func %p arg %p in %d",
    
    From 1fce10e7708278db685acd658475c21b757da9ee Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Sun, 7 Mar 2010 15:07:24 +0000
    Subject: [PATCH 1566/2592] reduce diffs from HEAD
    
    ---
     release/picobsd/bridge/PICOBSD                | 6 +++---
     release/picobsd/bridge/crunch.conf            | 2 +-
     release/picobsd/build/mfs.mtree               | 2 ++
     release/picobsd/floppy.tree/etc/master.passwd | 2 ++
     4 files changed, 8 insertions(+), 4 deletions(-)
    
    diff --git a/release/picobsd/bridge/PICOBSD b/release/picobsd/bridge/PICOBSD
    index 3d206efb2a0..47f88963265 100644
    --- a/release/picobsd/bridge/PICOBSD
    +++ b/release/picobsd/bridge/PICOBSD
    @@ -16,8 +16,8 @@ cpu		I586_CPU
     cpu		I686_CPU
     ident		PICOBSD
     
    -options                SMP
    -device apic
    +options		SMP
    +device	apic
     
     options		SCHED_4BSD		# mandatory to have one scheduler
     #options	MATH_EMULATE		#Support for x87 emulation
    @@ -48,7 +48,7 @@ options		DUMMYNET
     device		if_bridge
     # Running with less than 1000 seems to give poor timing on
     # qemu, so we set HZ explicitly.
    -options         HZ=1000
    +options		HZ=1000
     
     device		random			# used by ssh
     device		pci
    diff --git a/release/picobsd/bridge/crunch.conf b/release/picobsd/bridge/crunch.conf
    index c81d00f7877..2a64021fad9 100644
    --- a/release/picobsd/bridge/crunch.conf
    +++ b/release/picobsd/bridge/crunch.conf
    @@ -180,4 +180,4 @@ libs_so -lkvm
     libs_so -lz
     libs_so -lbsdxml
     libs_so -lsbuf
    -libs_so -ljail		# used by ifconfig
    +libs_so -ljail	# used by ifconfig
    diff --git a/release/picobsd/build/mfs.mtree b/release/picobsd/build/mfs.mtree
    index 5c8e70ce6b2..28c0d39ec77 100644
    --- a/release/picobsd/build/mfs.mtree
    +++ b/release/picobsd/build/mfs.mtree
    @@ -58,6 +58,8 @@
         var            
             db             
             ..
    +	empty
    +	..
             run            
             ..
             spool          
    diff --git a/release/picobsd/floppy.tree/etc/master.passwd b/release/picobsd/floppy.tree/etc/master.passwd
    index e9bb1cee3bd..e649b84d847 100644
    --- a/release/picobsd/floppy.tree/etc/master.passwd
    +++ b/release/picobsd/floppy.tree/etc/master.passwd
    @@ -1,3 +1,4 @@
    +# $FreeBSD$
     root:$1$xOOaGnKU$U9QdsCI40XXcCUMBN.7Az.:0:0::0:0:Charlie &:/root:/bin/sh
     toor:*:0:0::0:0:Bourne-again Superuser:/root:
     daemon:*:1:1::0:0:Owner of many system processes:/root:/nonexistent
    @@ -5,4 +6,5 @@ operator:*:2:20::0:0:System &:/usr/guest/operator:/bin/csh
     bin:*:3:7::0:0:Binaries Commands and Source,,,:/:/nonexistent
     tty:*:4:65533::0:0:Tty Sandbox:/:/nonexistent
     nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/nonexistent
    +_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
     user:*:1002:1002:Sample User:0:0:user:/home/user:/bin/sh
    
    From e6d9522c455012cafb2b57b6640e89bc10133c07 Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Sun, 7 Mar 2010 16:24:33 +0000
    Subject: [PATCH 1567/2592] MFC qemu configuration
    
    ---
     release/picobsd/qemu/PICOBSD             | 122 +++++++++++++++
     release/picobsd/qemu/PICOBSD.hints       |  39 +++++
     release/picobsd/qemu/config              |  26 +++
     release/picobsd/qemu/crunch.conf         | 191 +++++++++++++++++++++++
     release/picobsd/qemu/floppy.tree.exclude |   2 +
     5 files changed, 380 insertions(+)
     create mode 100644 release/picobsd/qemu/PICOBSD
     create mode 100644 release/picobsd/qemu/PICOBSD.hints
     create mode 100644 release/picobsd/qemu/config
     create mode 100644 release/picobsd/qemu/crunch.conf
     create mode 100644 release/picobsd/qemu/floppy.tree.exclude
    
    diff --git a/release/picobsd/qemu/PICOBSD b/release/picobsd/qemu/PICOBSD
    new file mode 100644
    index 00000000000..837e902d797
    --- /dev/null
    +++ b/release/picobsd/qemu/PICOBSD
    @@ -0,0 +1,122 @@
    +#
    +# $FreeBSD$
    +# A configuration file to run tests on qemu.
    +# We disable SMP because it does not work well with qemu, and set HZ=1000
    +# to avoid it being overridden.
    +#
    +# Line starting with #PicoBSD contains PicoBSD build parameters
    +#marker         def_sz  init    MFS_inodes      floppy_inodes
    +#PicoBSD	18000	init	8192		32768
    +options MD_ROOT_SIZE=18000      # same as def_sz
    +
    +hints	"PICOBSD.hints"
    +
    +# values accessible through getenv()
    +# env		"PICOBSD.env"
    +
    +#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
    +#options	INET6
    +options 	FFS			#Berkeley Fast Filesystem
    +#options	BOOTP			#Use BOOTP to obtain IP address/hostname
    +options 	MD_ROOT			#MD is a potential root device
    +
    +#options	NFS			#Network Filesystem
    +#options	NFS_ROOT		#NFS usable as root device, NFS required
    +
    +#options 	MSDOSFS			#MSDOS Filesystem
    +#options 	CD9660			#ISO 9660 Filesystem
    +#options 	CD9660_ROOT		#CD-ROM usable as root, CD9660 required
    +#options	DEVFS			#Device Filesystem
    +#options 	PROCFS			#Process filesystem
    +options		COMPAT_43		#Compatible with BSD 4.3 [KEEP THIS!]
    +
    +options		KDB
    +options		DDB
    +
    +options		IPFIREWALL
    +options		IPFIREWALL_DEFAULT_TO_ACCEPT
    +options		IPDIVERT		# divert (for natd)
    +
    +# Support for bridging and bandwidth limiting
    +options		DUMMYNET
    +device		if_bridge
    +# Running with less than 1000 seems to give poor timing on
    +# qemu, so we set HZ explicitly.
    +options		HZ=1000
    +
    +device		random			# used by ssh
    +device		pci
    +
    +# Floppy drives
    +device		fdc
    +
    +# ATA and ATAPI devices
    +#device		ata
    +#device		atadisk			# ATA disk drives
    +#device		atapicd			# ATAPI CDROM drives
    +#options		ATA_STATIC_ID		#Static device numbering
    +
    +# atkbdc0 controls both the keyboard and the PS/2 mouse
    +device		atkbdc			# At keyboard controller
    +device		atkbd
    +#device		psm			# do we need the mouse ??
    +
    +device		vga			# VGA screen
    +
    +# syscons is the default console driver, resembling an SCO console
    +device		sc
    +
    +# Serial (COM) ports
    +device		uart
    +
    +# Audio support
    +#device		pcm
    +
    +# PCCARD (PCMCIA) support
    +#device		card		# pccard bus
    +#device		pcic		# PCMCIA bridge
    +
    +# Parallel port
    +#device		ppc
    +#device		ppbus		# Parallel port bus (required)
    +#device		lpt		# Printer
    +#device		plip		# TCP/IP over parallel
    +#device		ppi		# Parallel port interface device
    +
    +#
    +# The following Ethernet NICs are all PCI devices.
    +#
    +device	miibus 
    +device		fxp		# Intel EtherExpress PRO/100B (82557, 82558)
    +device		nfe		# nVidia nForce MCP on-board Ethernet
    +#device		xl		# 3Com
    +device		rl		# RealTek 8129/8139
    +device		re		# RealTek 8139C+/8169/8169S/8110S
    +device		sis		# National/SiS
    +device		dc		# DEC/Intel 21143 and various workalikes
    +device		ed
    +
    +device		loop		# Network loopback
    +device		ether		# Ethernet support
    +device		tun		# Packet tunnel.
    +device		pty		# Pseudo-ttys (telnet etc)
    +device		md		# Memory "disks"
    +#device		gif	4	# IPv6 and IPv4 tunneling
    +#device		faith	1	# IPv6-to-IPv4 relaying (translation)
    +device		tap
    +
    +#options               DEVICE_POLLING
    +
    +# The `bpf' device enables the Berkeley Packet Filter.
    +# Be aware of the administrative consequences of enabling this!
    +device		bpf		# Berkeley packet filter
    diff --git a/release/picobsd/qemu/PICOBSD.hints b/release/picobsd/qemu/PICOBSD.hints
    new file mode 100644
    index 00000000000..4f1b40380e5
    --- /dev/null
    +++ b/release/picobsd/qemu/PICOBSD.hints
    @@ -0,0 +1,39 @@
    +# $FreeBSD$
    +hint.fdc.0.at="isa"
    +hint.fdc.0.port="0x3F0"
    +hint.fdc.0.irq="6"
    +hint.fdc.0.drq="2"
    +hint.fd.0.at="fdc0"
    +hint.fd.0.drive="0"
    +hint.ata.0.at="isa"
    +hint.ata.0.port="0x1F0"
    +hint.ata.0.irq="14"
    +hint.ata.1.at="isa"
    +hint.ata.1.port="0x170"
    +hint.ata.1.irq="15"
    +hint.atkbdc.0.at="isa"
    +hint.atkbdc.0.port="0x060"
    +hint.atkbd.0.at="atkbdc"
    +hint.atkbd.0.irq="1"
    +hint.psm.0.at="atkbdc"
    +hint.psm.0.irq="12"
    +hint.vga.0.at="isa"
    +hint.sc.0.at="isa"
    +hint.npx.0.at="nexus"
    +hint.npx.0.port="0x0F0"
    +hint.npx.0.irq="13"
    +hint.uart.0.at="isa"
    +hint.uart.0.port="0x3F8"
    +hint.uart.0.flags="0x10"
    +hint.uart.0.irq="4"
    +hint.uart.1.at="isa"
    +hint.uart.1.port="0x2F8"
    +hint.uart.1.irq="3"
    +hint.ed.0.at="isa"
    +hint.ed.0.port="0x280"
    +hint.ed.0.irq="5"
    +hint.ed.0.maddr="0xd8000"
    +hint.ed.1.at="isa"
    +hint.ed.1.port="0x300"
    +hint.ed.1.irq="5"
    +hint.ed.1.maddr="0xd0000"
    diff --git a/release/picobsd/qemu/config b/release/picobsd/qemu/config
    new file mode 100644
    index 00000000000..88f1954d7ab
    --- /dev/null
    +++ b/release/picobsd/qemu/config
    @@ -0,0 +1,26 @@
    +# configuration for picobsd build script.
    +# $FreeBSD$
    +# it should only contain variable definitions -- it is sourced
    +# by the shell much like rc.conf* files
    +
    +fd_size="8192"
    +
    +# To copy individual files you can use the function  do_copyfiles_user
    +# as below (find_progs locates the programs and their libraries,
    +# then you manually copy them.
    +#copy_files="
    +#"
    +do_copyfiles_user() {
    +	local dst=$1 # the destination root
    +	log "--- put the libraries in /usr/lib to avoid conflicts"
    +	mkdir -p ${dst}/usr/lib
    +	log "-- import dropbear from its build directory --"
    +	find_progs -L / -P /usr/ports/security/dropbear/work/dropbear-0.52 \
    +		dbclient dropbear
    +	cp -p ${u_progs} ${dst}/bin
    +	cp -p ${u_libs} ${dst}/usr/lib
    +	log "--- also import ssh, scp and sshd ---"
    +	find_progs -L / /usr/bin/ssh /usr/bin/scp /usr/sbin/sshd
    +	cp -p ${u_progs} ${dst}/bin
    +	cp -p ${u_libs} ${dst}/usr/lib
    +}
    diff --git a/release/picobsd/qemu/crunch.conf b/release/picobsd/qemu/crunch.conf
    new file mode 100644
    index 00000000000..d6566ae7056
    --- /dev/null
    +++ b/release/picobsd/qemu/crunch.conf
    @@ -0,0 +1,191 @@
    +#
    +# $FreeBSD$
    +#
    +# Configuration file for "qemu" images..
    +#
    +# Depending on your needs, you will almost surely need to
    +# add/remove/change programs according to your needs.
    +# Remember that some programs require matching kernel options to
    +# enable device drivers etc.
    +#
    +# To figure out how much space is used by each program, do
    +#
    +#	size build_dir-bridge/crunch/*lo
    +#
    +# Remember that programs require libraries, which add up to the
    +# total size. The final binary is build_dir-bridge/mfs.tree/stand/crunch
    +# and you can check which libraries it uses with
    +#
    +#	ldd build_dir-bridge/mfs.tree/stand/crunch
    +
    +# crunchgen configuration to build the crunched binary, see "man crunchgen"
    +# We need to specify generic build options, the places where to look
    +# for sources, and the list of program and libraries we want to put
    +# in the crunched binary.
    +#
    +# NOTE: the string "/usr/src" below will be automatically replaced with
    +# the path set in the 'build' script.
    +
    +# Default build options. Basically tell the Makefiles
    +# that to use the most compact possible version of the code.
    +
    +buildopts -DNO_PAM -DRELEASE_CRUNCH -DPPP_NO_NETGRAPH
    +buildopts -DTRACEROUTE_NO_IPSEC -DNO_INET6
    +buildopts -DWITHOUT_IPX
    +
    +# Directories where to look for sources of various binaries.
    +# @__CWD__@ is a magic keyword in the picobsd's (Makefile.conf)
    +# which is replaced with the directory with the picobsd configuration
    +# corresponding to your image. This way you can have custom sources
    +# in that directory overriding system programs.
    +
    +srcdirs @__CWD__@/src
    +
    +# Some programs are especially written for PicoBSD and reside in
    +# release/picobsd/tinyware.
    +# Put this entry near the head of the list to override standard binaries.
    +
    +srcdirs /usr/src/release/picobsd/tinyware
    +
    +# Other standard locations for sources.
    +# If a program uses its own source directory, add
    +
    +srcdirs /usr/src/bin
    +srcdirs /usr/src/sbin/i386
    +srcdirs /usr/src/sbin
    +srcdirs /usr/src/usr.bin
    +srcdirs /usr/src/gnu/usr.bin
    +srcdirs /usr/src/usr.sbin
    +srcdirs /usr/src/libexec
    +
    +# For programs that reside in different places, the best option
    +# is to use the command "special XXX srcdir YYY" where XXX is the
    +# program name and YYY is the directory path.
    +# "special XXX ..." can be used to specify more options, see again
    +# the crunchgen manpage.
    +
    +#--- Basic configuraton
    +# init is always necessary (unless you have a replacement, oinit)
    +progs init
    +
    +# fsck is almost always necessary, unless you have everything on the
    +# image and use 'tar' or something similar to read/write raw blocks
    +# from the floppy.
    +
    +progs fsck
    +
    +# ifconfig is needed if you want to configure interfaces.
    +progs ifconfig
    +
    +# You will also need a shell and a bunch of utilities.
    +# The standard shell is not that large, but you need many
    +# external programs. In fact most of them do not take much space
    +# as they merely issue a system call, and print the result.
    +# For a more compact version of shell and utilities, you could
    +# try busybox, however most system management commands in busybox
    +# will not work as they use linux-specific interfaces.
    +
    +progs sh
    +ln sh -sh
    +
    +# the small utilities
    +progs echo
    +progs pwd mkdir rmdir
    +progs chmod chown
    +ln chown chgrp
    +progs mv ln cp rm ls
    +progs cat tail tee
    +progs test
    +ln test [
    +
    +progs less
    +ln less more
    +progs mount
    +progs minigzip
    +ln minigzip gzip
    +progs kill
    +progs df
    +progs ps
    +progs ns	# this is the picobsd version
    +ln ns netstat
    +progs vm
    +progs hostname
    +progs login
    +progs getty
    +progs stty
    +progs w
    +progs msg
    +ln msg dmesg
    +progs reboot
    +
    +progs sysctl
    +progs swapon
    +progs pwd_mkdb
    +progs umount
    +progs du
    +progs passwd
    +
    +progs route
    +
    +# If you want to run natd, remember the alias library
    +progs natd
    +libs_so -lalias # natd
    +progs tcpdump
    +special tcpdump srcdir /usr/src/usr.sbin/tcpdump/tcpdump
    +libs_so -lpcap # used by tcpdump
    +
    +# ppp is rather large. Note that as of Jan.01, RELEASE_CRUNCH
    +# makes ppp not use libalias, so you cannot have aliasing.
    +#progs ppp
    +
    +# You need an editor. ee is relatively small, though there are
    +# smaller ones. vi is much larger.
    +# The editor also usually need a curses library.
    +progs ee
    +
    +progs arp
    +
    +# these require libgeom
    +# progs bsdlabel fdisk mdconfig
    +
    +progs kldload kldunload kldstat
    +progs kldxref
    +progs grep
    +libs_so -lgnuregex -lbz2
    +# dhclient-script requires 'sed'
    +progs dhclient
    +progs sed
    +progs date
    +progs time
    +progs ping
    +#progs routed
    +progs ipfw
    +progs traceroute
    +progs mdmfs
    +ln mdmfs mount_mfs
    +# Various filesystem support -- remember to enable the kernel parts
    +# progs mount_msdosfs
    +progs mount_nfs
    +# progs mount_cd9660
    +ln mount_nfs nfs
    +ln mount_cd9660 cd9660
    +#progs newfs
    +#ln newfs mount_mfs
    +# ln mount_msdosfs msdos
    +
    +# For a small ssh client/server use dropbear
    +
    +# Now the libraries
    +libs_so	-lc		# the C library
    +libs_so -ll		# used by sh (really ?)
    +libs_so -lufs		# used by mount
    +### ee uses ncurses but as a dependency
    +#libs_so -lncurses
    +libs_so -lm
    +libs_so -ledit -lutil
    +libs_so -lcrypt
    +libs_so -lkvm
    +libs_so -lz
    +libs_so -lbsdxml
    +libs_so -lsbuf
    +libs_so -ljail	# used by ifconfig
    diff --git a/release/picobsd/qemu/floppy.tree.exclude b/release/picobsd/qemu/floppy.tree.exclude
    new file mode 100644
    index 00000000000..adfc6cc7542
    --- /dev/null
    +++ b/release/picobsd/qemu/floppy.tree.exclude
    @@ -0,0 +1,2 @@
    +etc/snmpd.conf
    +etc/ppp
    
    From 433d44f161395b8430bbcc8ff916ed947513bade Mon Sep 17 00:00:00 2001
    From: Fabien Thomas 
    Date: Mon, 8 Mar 2010 07:53:44 +0000
    Subject: [PATCH 1568/2592] MFC r204783:  Bug fixed:  - no display on serial
     terminal in top mode.  - display alignment for continuation string.  -
     correct invalid value used for display limit.
    
    ---
     usr.sbin/pmcstat/pmcpl_callgraph.c | 2 +-
     usr.sbin/pmcstat/pmcpl_calltree.c  | 2 +-
     usr.sbin/pmcstat/pmcstat.c         | 3 +++
     3 files changed, 5 insertions(+), 2 deletions(-)
    
    diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.c b/usr.sbin/pmcstat/pmcpl_callgraph.c
    index d6f1a9d2697..84e281958de 100644
    --- a/usr.sbin/pmcstat/pmcpl_callgraph.c
    +++ b/usr.sbin/pmcstat/pmcpl_callgraph.c
    @@ -550,7 +550,7 @@ pmcstat_cgnode_topprint(struct pmcstat_cgnode *cg,
     
     		len = ns_len + vs_len + 1;
     		if (width - len < 0) {
    -			PMCSTAT_PRINTW("...");
    +			PMCSTAT_PRINTW(" ...");
     			break;
     		}
     		width -= len;
    diff --git a/usr.sbin/pmcstat/pmcpl_calltree.c b/usr.sbin/pmcstat/pmcpl_calltree.c
    index 498092dcca8..404653ebd7c 100644
    --- a/usr.sbin/pmcstat/pmcpl_calltree.c
    +++ b/usr.sbin/pmcstat/pmcpl_calltree.c
    @@ -387,7 +387,7 @@ pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct,
     	if (ct->pct_narc == 0) {
     		pmcpl_ct_topscreen[x+1][*y] = NULL;
     		if (*y >= PMCPL_CT_MAXLINE ||
    -		    *y >= pmcstat_displaywidth)
    +		    *y >= pmcstat_displayheight)
     			return 1;
     		*y = *y + 1;
     		for (i=0; i < x; i++)
    diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c
    index a73d29380f1..89ec8f06b56 100644
    --- a/usr.sbin/pmcstat/pmcstat.c
    +++ b/usr.sbin/pmcstat/pmcstat.c
    @@ -1311,6 +1311,9 @@ main(int argc, char **argv)
     			intrflush(stdscr, FALSE);
     			keypad(stdscr, TRUE);
     			clear();
    +			/* Get terminal width / height with ncurses. */
    +			getmaxyx(stdscr, pmcstat_displayheight, pmcstat_displaywidth);
    +			pmcstat_displayheight--; pmcstat_displaywidth--;
     			atexit(pmcstat_topexit);
     		}
     	}
    
    From 0b98eb0a9ebc8fdcb6f6439b3ff519e2b0c38698 Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Mon, 8 Mar 2010 13:37:14 +0000
    Subject: [PATCH 1569/2592] MFC main build script and missing directory
    
    ---
     release/picobsd/build/picobsd    |  67 ++++--
     release/picobsd/floppy.tree/sbin | 384 +++++++++++++++++++++++++++++++
     2 files changed, 431 insertions(+), 20 deletions(-)
     create mode 100755 release/picobsd/floppy.tree/sbin
    
    diff --git a/release/picobsd/build/picobsd b/release/picobsd/build/picobsd
    index 0549b0c6e69..c9e8fc7296f 100755
    --- a/release/picobsd/build/picobsd
    +++ b/release/picobsd/build/picobsd
    @@ -167,7 +167,7 @@ create_includes_and_libraries2() { # opt_dir opt_target
         local no
         log "create_includes_and_libraries2() for ${SRC}"
         if [ ${OSVERSION} -ge 600000 ] ; then
    -	no="-DNO_CLEAN -DNO_PROFILE -DNO_GAMES -DNO_LIBC_R" # WITOUT_CDDL=1"
    +	no="-DNO_CLEAN -DNO_PROFILE -DNO_GAMES -DNO_LIBC_R" # WITHOUT_CDDL=1"
         else
     	no="-DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R"
         fi
    @@ -568,10 +568,17 @@ do_links() {	# rootdir varname
     # find_progs is a helper function to locate the named programs
     # or libraries in ${o_objdir} or ${_SHLIBDIRPREFIX},
     # and return the full pathnames.
    -# Sets ${u_progs} to the list of programs, and ${u_libs}
    +# Called as "find_progs [-L libpath] [-P binpath] prog1 prog2 ... "
    +# On return it sets ${u_progs} to the list of programs, and ${u_libs}
     # to the list of shared libraries used.
    +# 
    +# '-L path' can be used to specify a search path for libraries
    +#    (which searches in $path/lib:$path/usr/lib:$path/usr/local/lib
    +# '-P binpath' can be used to specify a search path for programs
    +#    (which searches in a lot of places in the subtree)
    +# -L must be the first, followed by -P
     #
    -# You can use it e.g. in a local configuration file by writing
    +# You can use it e.g. in a local confign file by writing
     #
     #  do_copyfiles_user() {
     #	local dst=$1
    @@ -580,41 +587,61 @@ do_links() {	# rootdir varname
     #	cp -p ${u_libs} ${dst}/lib
     #	mkdir -p ${dst}/libexec
     #	find_progs ld-elf.so.1
    -#	cp -p ${u_progs} ${dst}/libexec
    +#	cp -p ${u_progs} ${dst}/libexec # ignore errors
     #  }
     
     find_progs() {	# programs
     	local i
    +	local oo=${o_objdir:-${_SHLIBDIRPREFIX}} # default objdir
    +	local lp=$oo/lib			# default lib.prefix
    +	local o=""				# additional objdir
    +	if [ x"$1" = "x-L" -a -d "$2" ] ; then # set lib search path
    +		o=$2; shift; shift
    +		lp="$lp:$o/lib:$o/usr/lib:$o/usr/local/lib"
    +		o="-P $o"
    +	fi
    +	u_libs=""
     	u_progs="`find_progs_helper $*`"
    -	local o=${o_objdir:-${_SHLIBDIRPREFIX}}
    -	log "looking for libs for $u_progs in $_SHLIBDIRPREFIX"
    +	log "looking for libs for <$u_progs> in $lp"
     	[ -z "${u_progs}" ] && return 1	# not found, error
    -	i="`LD_LIBRARY_PATH=$o/lib ldd ${u_progs} | grep -v '^/' | awk '{print $1}' | sort | uniq`"
    -	u_libs="`find_progs_helper $i`"
    +	i="`( LD_LIBRARY_PATH=$lp ldd ${u_progs} ) | \
    +		grep -v '^/' | awk '{print $1}' | sort | uniq`"
    +	u_libs="`find_progs_helper $o $i`"
     	return 0
     }
     
     find_progs_helper() {	# programs
    +	local dir=${o_objdir:-${_SHLIBDIRPREFIX}/..}
    +	local ldir=""
    +	if [ x"$1" = "x-P" -a -d "$2" ] ; then # set path
    +		ldir=$2; shift; shift
    +	fi
     	local progs="$*"
    -	local i o places names
    -	local subdirs="bin sbin usr.bin usr.sbin libexec lib \
    +	local subdirs=". local/bin local/sbin local/lib local/libexec \
    +		bin sbin usr.bin usr.sbin libexec lib \
     		gnu/usr.bin gnu/lib \
     		secure/usr.bin secure/usr.sbin secure/libexec secure/lib"
    -	names=""	# files to search
    -	o=""
    +	local names=""	# files to search
    +	local o=""
    +	local i
     	for i in $progs ; do
    -		# plain programs come out verbatim
    +		# full pathnames are just listed
     		[ -f "$i" ] && echo $i && continue
     		names="${names} ${o} -name $i"
     		o="-o"
     	done
     	[ -z "${names}" ] && return 0
    -	places=""				# places to search
    -	o=${o_objdir:-${_SHLIBDIRPREFIX}/..}
    +	local places=""				# places to search
     	for i in $subdirs ; do
    -		[ -d "${o}/${i}" ] && places="${places} ${o}/${i}"
    +		[ -d "${dir}/${i}" ] && places="${places} ${dir}/${i}"
     	done
    -	find ${places} -type f \( ${names} \)
    +	if [ -n "${ldir}" ] ; then
    +	    for i in $subdirs ; do
    +		[ -d "${ldir}/${i}" ] && places="${places} ${ldir}/${i}"
    +	    done
    +	fi
    +	# use maxdepth 3 because some libs are way down
    +	find ${places} -maxdepth 3 -type f \( ${names} \)
     }
     
     # Populate the memory filesystem with binaries and non-variable
    @@ -862,7 +889,7 @@ fill_floppy_image() {
         if [ ${mfs_start} -gt 0 -a ${mfs_size} -ge ${imgsize} ] ; then
     	mfs_ofs=$((${mfs_start} + 8192))
     	log "Preload kernel with file ${c_fs} at ${mfs_ofs}"
    -	logverbose "`ls -l ${c_fs}` to fit in ${mfs_size}"
    +	log "`ls -l ${c_fs}` to fit in ${mfs_size}"
     	dd if=${c_fs} ibs=8192 iseek=1 of=kernel obs=${mfs_ofs} \
     	    oseek=1 conv=notrunc # 2> /dev/null
         else
    @@ -917,7 +944,7 @@ fill_floppy_image() {
     
         ls -l ${c_img}
         ${c_label} -f `pwd`/${c_img}
    -    logverbose "after disklabel"
    +    log "after disklabel"
         )
     
         echo "BUILDDIR ${BUILDDIR}"
    @@ -931,7 +958,7 @@ fill_floppy_image() {
     
         dd if=${b2} iseek=1 ibs=276 2> /dev/null | \
     	dd of=${BUILDDIR}/${c_img} oseek=1 obs=788 conv=notrunc 2>/dev/null
    -    logverbose "done floppy image"
    +    log "done disk image"
         # XXX (log "Fixing permissions"; cd ${dst}; chown -R root *)
         rm -rf ${BUILDDIR}/floppy.tree || true # cleanup
         # df -ik ${dst} | colrm 70 > .build.reply
    diff --git a/release/picobsd/floppy.tree/sbin b/release/picobsd/floppy.tree/sbin
    new file mode 100755
    index 00000000000..c457bf46530
    --- /dev/null
    +++ b/release/picobsd/floppy.tree/sbin
    @@ -0,0 +1,384 @@
    +#!/bin/sh
    +#
    +# $OpenBSD: dhclient-script,v 1.6 2004/05/06 18:22:41 claudio Exp $
    +# $FreeBSD$
    +#
    +# Copyright (c) 2003 Kenneth R Westerback 
    +#
    +# Permission to use, copy, modify, and 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.
    +#
    +#
    +
    +ARP=/usr/sbin/arp
    +HOSTNAME=/bin/hostname
    +IFCONFIG='/sbin/ifconfig -n'
    +
    +LOCALHOST=127.0.0.1
    +
    +if [ -x /usr/bin/logger ]; then
    +	LOGGER="/usr/bin/logger -s -p user.notice -t dhclient"
    +else
    +	LOGGER=echo
    +fi
    +
    +#
    +# Helper functions that implement common actions.
    +#
    +
    +check_hostname() {
    +	current_hostname=`$HOSTNAME`
    +	if [ -z "$current_hostname" ]; then
    +		$LOGGER "New Hostname ($interface): $new_host_name"
    +		$HOSTNAME $new_host_name
    +	elif [ "$current_hostname" = "$old_host_name" -a \
    +	       "$new_host_name" != "$old_host_name" ]; then
    +		$LOGGER "New Hostname ($interface): $new_host_name"
    +		$HOSTNAME $new_host_name
    +	fi
    +}
    +
    +arp_flush() {
    +	arp -an -i $interface | \
    +		sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' | \
    +		sh >/dev/null 2>&1
    +}
    +
    +delete_old_address() {
    +	eval "$IFCONFIG $interface inet -alias $old_ip_address $medium"
    +}
    +
    +add_new_address() {
    +	eval "$IFCONFIG $interface \
    +		inet $new_ip_address \
    +		netmask $new_subnet_mask \
    +		broadcast $new_broadcast_address \
    +		$medium"
    +
    +	$LOGGER "New IP Address ($interface): $new_ip_address"
    +	$LOGGER "New Subnet Mask ($interface): $new_subnet_mask"
    +	$LOGGER "New Broadcast Address ($interface): $new_broadcast_address"
    +	$LOGGER "New Routers ($interface): $new_routers"
    +}
    +
    +delete_old_alias() {
    +	if [ -n "$alias_ip_address" ]; then
    +		$IFCONFIG $interface inet -alias $alias_ip_address > /dev/null 2>&1
    +		#route delete $alias_ip_address $LOCALHOST > /dev/null 2>&1
    +	fi
    +}
    +
    +add_new_alias() {
    +	if [ -n "$alias_ip_address" ]; then
    +		$IFCONFIG $interface inet alias $alias_ip_address netmask \
    +		    $alias_subnet_mask
    +		#route add $alias_ip_address $LOCALHOST
    +	fi
    +}
    +
    +fill_classless_routes() {
    +	set $1
    +	while [ $# -ge 5 ]; do
    +		if [ $1 -eq 0 ]; then
    +			route="default"
    +		elif [ $1 -le 8 ]; then
    +			route="$2.0.0.0/$1"
    +			shift
    +		elif [ $1 -le 16 ]; then
    +			route="$2.$3.0.0/$1"
    +			shift; shift
    +		elif [ $1 -le 24 ]; then
    +			route="$2.$3.$4.0/$1"
    +			shift; shift; shift
    +		else
    +			route="$2.$3.$4.$5/$1"
    +			shift; shift; shift; shift
    +		fi
    +		shift
    +		router="$1.$2.$3.$4"
    +		classless_routes="$classless_routes $route $router"
    +		shift; shift; shift; shift
    +	done
    +}
    +
    +delete_old_routes() {
    +	#route delete "$old_ip_address" $LOCALHOST >/dev/null 2>&1
    +	if [ -n "$old_classless_routes" ]; then
    +		fill_classless_routes "$old_classless_routes"
    +		set $classless_routes
    +		while [ $# -gt 1 ]; do
    +			route delete "$1" "$2"
    +			shift; shift
    +		done
    +		return 0;
    +	fi
    +
    +	# If we supported multiple default routes, we'd be removing each
    +	# one here.  We don't so just delete the default route if it's
    +	# through our interface.
    +	if is_default_interface; then
    +		route delete default >/dev/null 2>&1
    +	fi
    +
    +	if [ -n "$old_static_routes" ]; then
    +		set $old_static_routes
    +		while [ $# -gt 1 ]; do
    +			route delete "$1" "$2"
    +			shift; shift
    +		done
    +	fi
    +
    +	arp_flush
    +}
    +
    +add_new_routes() {
    +	#route add $new_ip_address $LOCALHOST >/dev/null 2>&1
    +
    +	# RFC 3442: If the DHCP server returns both a Classless Static
    +	# Routes option and a Router option, the DHCP client MUST ignore
    +	# the Router option.
    +	#
    +	# DHCP clients that support this option (Classless Static Routes)
    +	# MUST NOT install the routes specified in the Static Routes
    +	# option (option code 33) if both a Static Routes option and the
    +	# Classless Static Routes option are provided.
    +
    +	if [ -n "$new_classless_routes" ]; then
    +		fill_classless_routes "$new_classless_routes"
    +		$LOGGER "New Classless Static Routes ($interface): $classless_routes"
    +		set $classless_routes
    +		while [ $# -gt 1 ]; do
    +			if [ "0.0.0.0" = "$2" ]; then
    +				route add "$1" -iface "$interface"
    +			else
    +				route add "$1" "$2"
    +			fi
    +			shift; shift
    +		done
    +		return
    +	fi
    +
    +	for router in $new_routers; do
    +		if is_default_interface; then
    +
    +			if [ "$new_ip_address" = "$router" ]; then
    +				route add default -iface $router >/dev/null 2>&1
    +			else
    +				route add default $router >/dev/null 2>&1
    +			fi
    +		fi
    +		# 2nd and subsequent default routers error out, so explicitly
    +		# stop processing the list after the first one.
    +		break
    +	done
    +
    +	if [ -n "$new_static_routes" ]; then
    +		$LOGGER "New Static Routes ($interface): $new_static_routes"
    +		set $new_static_routes
    +		while [ $# -gt 1 ]; do
    +			route add $1 $2
    +			shift; shift
    +		done
    +	fi
    +}
    +
    +add_new_resolv_conf() {
    +	# XXX Old code did not create/update resolv.conf unless both
    +	# $new_domain_name and $new_domain_name_servers were provided.  PR
    +	# #3135 reported some ISP's only provide $new_domain_name_servers and
    +	# thus broke the script. This code creates the resolv.conf if either
    +	# are provided.
    +
    +	local tmpres=/var/run/resolv.conf.${interface}
    +	rm -f $tmpres
    +
    +	if [ -n "$new_domain_name" ]; then
    +		echo "search $new_domain_name" >>$tmpres
    +	fi
    +
    +	if [ -n "$new_domain_name_servers" ]; then
    +		for nameserver in $new_domain_name_servers; do
    +			echo "nameserver $nameserver" >>$tmpres
    +		done
    +	fi
    +
    +	if [ -f $tmpres ]; then
    +		if [ -f /etc/resolv.conf.tail ]; then
    +			cat /etc/resolv.conf.tail >>$tmpres
    +		fi
    +
    +		# When resolv.conf is not changed actually, we don't
    +		# need to update it.
    +		# If /usr is not mounted yet, we cannot use cmp, then
    +		# the following test fails.  In such case, we simply
    +		# ignore an error and do update resolv.conf.
    +		if cmp -s $tmpres /etc/resolv.conf; then
    +			rm -f $tmpres
    +			return 0
    +		fi 2>/dev/null
    +
    +		# In case (e.g. during OpenBSD installs) /etc/resolv.conf
    +		# is a symbolic link, take care to preserve the link and write
    +		# the new data in the correct location.
    +
    +		if [ -f /etc/resolv.conf ]; then
    +			cat /etc/resolv.conf > /etc/resolv.conf.save
    +		fi
    +		cat $tmpres > /etc/resolv.conf
    +		rm -f $tmpres
    +
    +		# Try to ensure correct ownership and permissions.
    +		chown -RL root:wheel /etc/resolv.conf
    +		chmod -RL 644 /etc/resolv.conf
    +
    +		return 0
    +	fi
    +
    +	return 1
    +}
    +
    +# Must be used on exit.   Invokes the local dhcp client exit hooks, if any.
    +exit_with_hooks() {
    +	exit_status=$1
    +	if [ -f /etc/dhclient-exit-hooks ]; then
    +		. /etc/dhclient-exit-hooks
    +	fi
    +	# probably should do something with exit status of the local script
    +	exit $exit_status
    +}
    +
    +# Get the interface with the current ipv4 default route on it using only
    +# commands that are available prior to /usr being mounted.
    +is_default_interface()
    +{
    +	routeget="`route -n get -inet default`"
    +	oldifs="$IFS"
    +	IFS="
    +"
    +	defif=
    +	for line in $routeget ; do
    +		case $line in
    +		*interface:*)
    +			defif=${line##*: }
    +			;;
    +		esac
    +	done
    +	IFS=${oldifs}
    +
    +	if [ -z "$defif" -o "$defif" = "$interface" ]; then
    +		return 0
    +	else
    +		return 1
    +	fi
    +}
    +
    +#
    +# Start of active code.
    +#
    +
    +# Invoke the local dhcp client enter hooks, if they exist.
    +if [ -f /etc/dhclient-enter-hooks ]; then
    +	exit_status=0
    +	. /etc/dhclient-enter-hooks
    +	# allow the local script to abort processing of this state
    +	# local script must set exit_status variable to nonzero.
    +	if [ $exit_status -ne 0 ]; then
    +		exit $exit_status
    +	fi
    +fi
    +
    +case $reason in
    +MEDIUM)
    +	eval "$IFCONFIG $interface $medium"
    +	eval "$IFCONFIG $interface inet -alias 0.0.0.0 $medium" >/dev/null 2>&1
    +	sleep 1
    +	;;
    +
    +PREINIT)
    +	delete_old_alias
    +	$IFCONFIG $interface inet alias 0.0.0.0 netmask 0.0.0.0 broadcast 255.255.255.255 up
    +	;;
    +
    +ARPCHECK|ARPSEND)
    +	;;
    +
    +BOUND|RENEW|REBIND|REBOOT)
    +	check_hostname
    +	if [ -n "$old_ip_address" ]; then
    +		if [ "$old_ip_address" != "$alias_ip_address" ]; then
    +			delete_old_alias
    +		fi
    +		if [ "$old_ip_address" != "$new_ip_address" ]; then
    +			delete_old_address
    +			delete_old_routes
    +		fi
    +	fi
    +	if [ "$reason" = BOUND ] || \
    +	   [ "$reason" = REBOOT ] || \
    +	   [ -z "$old_ip_address" ] || \
    +	   [ "$old_ip_address" != "$new_ip_address" ]; then
    +		add_new_address
    +		add_new_routes
    +	fi
    +	if [ "$new_ip_address" != "$alias_ip_address" ]; then
    +		add_new_alias
    +	fi
    +	if is_default_interface; then
    +		add_new_resolv_conf
    +	fi
    +	;;
    +
    +EXPIRE|FAIL)
    +	delete_old_alias
    +	if [ -n "$old_ip_address" ]; then
    +		delete_old_address
    +		delete_old_routes
    +	fi
    +	if [ -x $ARP ]; then
    +		$ARP -d -a -i $interface
    +	fi
    +	# XXX Why add alias we just deleted above?
    +	add_new_alias
    +	if is_default_interface; then
    +		if [ -f /etc/resolv.conf.save ]; then
    +			cat /etc/resolv.conf.save > /etc/resolv.conf
    +		fi
    +	fi
    +	;;
    +
    +TIMEOUT)
    +	delete_old_alias
    +	add_new_address
    +	sleep 1
    +	if [ -n "$new_routers" ]; then
    +		$LOGGER "New Routers ($interface): $new_routers"
    +		set "$new_routers"
    +		if ping -q -c 1 -t 1 "$1"; then
    +			if [ "$new_ip_address" != "$alias_ip_address" ]; then
    +				add_new_alias
    +			fi
    +			add_new_routes
    +			if ! is_default_interface; then
    +				exit_with_hooks 0
    +			fi
    +			if add_new_resolv_conf; then
    +				exit_with_hooks 0
    +			fi
    +		fi
    +	fi
    +	eval "$IFCONFIG $interface inet -alias $new_ip_address $medium"
    +	delete_old_routes
    +	exit_with_hooks 1
    +	;;
    +esac
    +
    +exit_with_hooks 0
    
    From f50241e45207862c5cc659aa0cb45a8ffc4c6841 Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Mon, 8 Mar 2010 16:53:58 +0000
    Subject: [PATCH 1570/2592] MFC r204648: Several changes to fix livelock under
     high load, introduced by r203489:  - change the way in which command queue
     overflow is handled;  - do not expose to CAM two command slots, used for
     driver's internal purposes;  - allow driver to use up to 1024 command slots,
     instead of 256 before.
    
    ---
     sys/dev/ciss/ciss.c    | 13 ++++++++++---
     sys/dev/ciss/cissvar.h |  3 ++-
     2 files changed, 12 insertions(+), 4 deletions(-)
    
    diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
    index 66a046d8105..7293bb1682d 100644
    --- a/sys/dev/ciss/ciss.c
    +++ b/sys/dev/ciss/ciss.c
    @@ -1353,7 +1353,7 @@ ciss_init_logical(struct ciss_softc *sc)
     
         /* sanity-check reply */
         ndrives = (ntohl(cll->list_size) / sizeof(union ciss_device_address));
    -    if ((ndrives < 0) || (ndrives >= CISS_MAX_LOGICAL)) {
    +    if ((ndrives < 0) || (ndrives > CISS_MAX_LOGICAL)) {
     	ciss_printf(sc, "adapter claims to report absurd number of logical drives (%d > %d)\n",
     		    ndrives, CISS_MAX_LOGICAL);
     	error = ENXIO;
    @@ -2791,7 +2791,7 @@ ciss_cam_init(struct ciss_softc *sc)
          * Allocate a devq.  We can reuse this for the masked physical
          * devices if we decide to export these as well.
          */
    -    if ((sc->ciss_cam_devq = cam_simq_alloc(sc->ciss_max_requests)) == NULL) {
    +    if ((sc->ciss_cam_devq = cam_simq_alloc(sc->ciss_max_requests - 2)) == NULL) {
     	ciss_printf(sc, "can't allocate CAM SIM queue\n");
     	return(ENOMEM);
         }
    @@ -3065,7 +3065,7 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
          */
         if ((error = ciss_get_request(sc, &cr)) != 0) {
     	xpt_freeze_simq(sim, 1);
    -	csio->ccb_h.status |= CAM_RELEASE_SIMQ;
    +	sc->ciss_flags |= CISS_FLAG_BUSY;
     	csio->ccb_h.status |= CAM_REQUEUE_REQ;
     	return(error);
         }
    @@ -3275,6 +3275,13 @@ ciss_cam_complete(struct ciss_request *cr)
         ciss_cam_complete_fixup(sc, csio);
     
         ciss_release_request(cr);
    +    if (sc->ciss_flags & CISS_FLAG_BUSY) {
    +	sc->ciss_flags &= ~CISS_FLAG_BUSY;
    +	if (csio->ccb_h.status & CAM_RELEASE_SIMQ)
    +	    xpt_release_simq(xpt_path_sim(csio->ccb_h.path), 0);
    +	else
    +	    csio->ccb_h.status |= CAM_RELEASE_SIMQ;
    +    }
         xpt_done((union ccb *)csio);
     }
     
    diff --git a/sys/dev/ciss/cissvar.h b/sys/dev/ciss/cissvar.h
    index 3bad2b3b292..07d72b7cef1 100644
    --- a/sys/dev/ciss/cissvar.h
    +++ b/sys/dev/ciss/cissvar.h
    @@ -41,7 +41,7 @@ typedef STAILQ_HEAD(, ciss_request)	cr_qhead_t;
      * commands an adapter may claim to support.  Cap it at a reasonable
      * value.
      */
    -#define CISS_MAX_REQUESTS	256
    +#define CISS_MAX_REQUESTS	1024
     
     /*
      * Maximum number of logical drives we support.
    @@ -251,6 +251,7 @@ struct ciss_softc
     #define CISS_FLAG_CONTROL_OPEN	(1<<1)		/* control device is open */
     #define CISS_FLAG_ABORTING	(1<<2)		/* driver is going away */
     #define CISS_FLAG_RUNNING	(1<<3)		/* driver is running (interrupts usable) */
    +#define CISS_FLAG_BUSY		(1<<4)		/* no free commands */
     
     #define CISS_FLAG_FAKE_SYNCH	(1<<16)		/* needs SYNCHRONISE_CACHE faked */
     #define CISS_FLAG_BMIC_ABORT	(1<<17)		/* use BMIC command to abort Notify on Event */
    
    From ca493fb650bbe2e27ffc06c0e93ab0e1012dda67 Mon Sep 17 00:00:00 2001
    From: Edwin Groothuis 
    Date: Mon, 8 Mar 2010 21:29:00 +0000
    Subject: [PATCH 1571/2592] MFC of tzdata2010e, r204887
    
    - Adjust beginning / end of DST in Bangladesh (minimal impact)
    - Fiji ends DST one month earlier to last Sunday of March
    - Samoa changes
    - Chile extends DST until 3 April this year.
    ---
     share/zoneinfo/asia         | 30 ++++++++++--
     share/zoneinfo/australasia  | 93 ++++++++++++++-----------------------
     share/zoneinfo/southamerica | 20 ++++++--
     3 files changed, 78 insertions(+), 65 deletions(-)
    
    diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia
    index b7aa43a6b55..41aeb4bb0ab 100644
    --- a/share/zoneinfo/asia
    +++ b/share/zoneinfo/asia
    @@ -1,4 +1,4 @@
    -# @(#)asia	8.50
    +# @(#)asia	8.55
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -225,11 +225,31 @@ Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al Manamah
     # until further notice." I take that last sentence as the
     # establishment of a rule.
     
    +# From Nobutomo Nakano (2010-02-19):
    +# We received a report from Bangladesh saying that the start/end of
    +# Bangladesh DST is incorrect. Currently we have only the Bengali version
    +# of the official mail from BTRC which describes the following:
    +#
    +# "From 2010 each year when local standard time is about to reach
    +# March 31 at 10:59:00 PM clocks are turned forward 1 hour (11:59:00 PM)
    +# and when local daylight time is about to October 31 at 11:59:00 PM
    +# clocks are turned backward 1 hour (10:59:00 PM)."
    +#
    +# So, DST will start/end 1 minute earlier.
    +
    +# From Arthur David Olson (2010-03-03):
    +# The file
    +# 
    +# http://www.cabinet.gov/bd/file_upload/news_events/en_169.pdf
    +# 
    +# is in Bengali; it does contain two "31"s as well as two "11.59"s and a "10.59"
    +# which is consistent with the information provided by Nobutomo Nakano.
    +
     # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
    -Rule	Dhaka	2009	only	-	Jun	29	23:00	1	S
    -Rule	Dhaka	2010	only	-	Jan	1	0:00	-	-
    -Rule	Dhaka	2010	max	-	Mar	31	23:00	1	S
    -Rule	Dhaka	2010	max	-	Nov	1	0:00	-	-
    +Rule	Dhaka	2009	only	-	Jun	19	23:00	1:00	S
    +Rule	Dhaka	2009	only	-	Dec	31	23:59	0	-
    +Rule	Dhaka	2010	max	-	Mar	31	22:59	1:00	S
    +Rule	Dhaka	2010	max	-	Oct	31	23:59	0	-
     
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
     Zone	Asia/Dhaka	6:01:40 -	LMT	1890
    diff --git a/share/zoneinfo/australasia b/share/zoneinfo/australasia
    index 38123900870..614a446c13a 100644
    --- a/share/zoneinfo/australasia
    +++ b/share/zoneinfo/australasia
    @@ -1,5 +1,5 @@
     # 
    -# @(#)australasia	8.15
    +# @(#)australasia	8.16
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -267,11 +267,30 @@ Zone	Indian/Cocos	6:27:40	-	LMT	1900
     # 
     # http://www.fiji.gov.fj/publish/page_16198.shtml
     # 
    +
    +# From Steffen Thorsen (2010-03-03):
    +# The Cabinet in Fiji has decided to end DST about a month early, on
    +# 2010-03-28 at 03:00.
    +# The plan is to observe DST again, from 2010-10-24 to sometime in March
    +# 2011 (last Sunday a good guess?).
    +#
    +# Official source:
    +# 
    +# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166
    +# 
    +#
    +# A bit more background info here:
    +# 
    +# http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html
    +# 
    +
     # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
     Rule	Fiji	1998	1999	-	Nov	Sun>=1	2:00	1:00	S
     Rule	Fiji	1999	2000	-	Feb	lastSun	3:00	0	-
     Rule	Fiji	2009	only	-	Nov	29	2:00	1:00	S
    -Rule	Fiji	2010	only	-	Apr	25	3:00	0	-
    +Rule	Fiji	2010	only	-	Mar	lastSun	3:00	0	-
    +Rule	Fiji	2010	only	-	Oct	24	2:00	1:00	S
    +Rule	Fiji	2011	only	-	Mar	lastSun 3:00	0	-
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
     Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
     			12:00	Fiji	FJ%sT	# Fiji Time
    @@ -449,70 +468,30 @@ Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
     
     # Samoa
     
    -# From Alexander Krivenyshev (2008-12-06):
    -# The Samoa government (Western Samoa) may implement DST on the first Sunday of 
    -# October 2009 (October 4, 2009) until the last Sunday of March 2010 (March 28, 
    -# 2010). 
    -# 
    -# "Selected Committee reports to Cabinet on Daylight Saving Time",
    -# Government of Samoa:
    -# 
    -# http://www.govt.ws/pr_article.cfm?pr_id=560
    -# 
    -# or
    -# 
    -# http://www.worldtimezone.com/dst_news/dst_news_samoa01.html
    -# 
    -
    -# From Steffen Thorsen (2009-08-27):
    -# Samoa's parliament passed the Daylight Saving Bill 2009, and will start 
    -# daylight saving time on the first Sunday of October 2009 and end on the 
    -# last Sunday of March 2010. We hope that the full text will be published 
    -# soon, but we believe that the bill is only valid for 2009-2010. Samoa's 
    -# Daylight Saving Act 2009 will be enforced as soon as the Head of State 
    -# executes a proclamation publicizing this Act.
    +# From Steffen Thorsen (2009-10-16):
    +# We have been in contact with the government of Samoa again, and received
    +# the following info:
     #
    -# Some background information here, which will be updated once we have 
    -# more details:
    +# "Cabinet has now approved Daylight Saving to be effected next year
    +# commencing from the last Sunday of September 2010 and conclude first
    +# Sunday of April 2011."
    +#
    +# Background info:
     # 
     # 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.
    +# Samoa's Daylight Saving Time Act 2009 is available here, but does not
    +# contain any dates:
    +# 
    +# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf
    +# 
     
     Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
     			-11:26:56 -	LMT	1911
     			-11:30	-	SAMT	1950		# Samoa Time
    -			-11:00	-	WST	2009 Oct 4
    -			-11:00	1:00	WSDT	2010 Mar 28
    +			-11:00	-	WST	2010 Oct 24
    +			-11:00	1:00	WSDT	2011 Apr 3
     			-11:00	-	WST
     
     # Solomon Is
    diff --git a/share/zoneinfo/southamerica b/share/zoneinfo/southamerica
    index 7ad8170826c..8db45ccda9a 100644
    --- a/share/zoneinfo/southamerica
    +++ b/share/zoneinfo/southamerica
    @@ -1,5 +1,5 @@
     # 
    -# @(#)southamerica	8.41
    +# @(#)southamerica	8.43
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -1121,6 +1121,18 @@ Zone America/Rio_Branco	-4:31:12 -	LMT	1914
     # http://www.shoa.cl/noticias/2008/04hora/hora.htm
     # .
     
    +# From Angel Chiang (2010-03-04):
    +# Subject: DST in Chile exceptionally extended to 3 April due to earthquake
    +# 
    +# http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098
    +# 
    +# (in Spanish, last paragraph).
    +#
    +# This is breaking news. There should be more information available later.
    +
    +# From Arthur Daivd Olson (2010-03-06):
    +# Angel Chiang's message confirmed by Julio Pacheco; Julio provided a patch.
    +
     # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
     Rule	Chile	1927	1932	-	Sep	 1	0:00	1:00	S
     Rule	Chile	1928	1932	-	Apr	 1	0:00	0	-
    @@ -1155,7 +1167,9 @@ Rule	Chile	2000	2007	-	Mar	Sun>=9	3:00u	0	-
     # N.B.: the end of March 29 in Chile is March 30 in Universal time,
     # which is used below in specifying the transition.
     Rule	Chile	2008	only	-	Mar	30	3:00u	0	-
    -Rule	Chile	2009	max	-	Mar	Sun>=9	3:00u	0	-
    +Rule	Chile	2009	only	-	Mar	Sun>=9	3:00u	0	-
    +Rule	Chile	2010	only	-	Apr	 4	3:00u	0	-
    +Rule	Chile	2011	max	-	Mar	Sun>=9	3:00u	0	-
     # IATA SSIM anomalies: (1992-02) says 1992-03-14;
     # (1996-09) says 1998-03-08.  Ignore these.
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
    @@ -1380,7 +1394,7 @@ Rule	Para	2005	2009	-	Mar	Sun>=8	0:00	0	-
     # and that on the first Sunday of the month of October, it is to be set
     # forward 60 minutes, in all the territory of the Paraguayan Republic.
     # ...
    -Rule	Para	2010	max	-	Oct	Sun<=7	0:00	1:00	S
    +Rule	Para	2010	max	-	Oct	Sun>=1	0:00	1:00	S
     Rule	Para	2010	max	-	Apr	Sun>=8	0:00	0	-
     
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
    
    From 44520d2930e35a19fdaa0db3e606b3e987618266 Mon Sep 17 00:00:00 2001
    From: Qing Li 
    Date: Mon, 8 Mar 2010 21:30:12 +0000
    Subject: [PATCH 1572/2592] MFC 204402
    
    Use reference counting instead of locking to secure an address while
    that address is being used to generate temporary IPv6 address. This
    approach is sufficient and avoids recursive locking.
    ---
     sys/netinet6/nd6.c | 9 ++++++---
     1 file changed, 6 insertions(+), 3 deletions(-)
    
    diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
    index 50c273d87a3..4c941da2c77 100644
    --- a/sys/netinet6/nd6.c
    +++ b/sys/netinet6/nd6.c
    @@ -759,22 +759,25 @@ regen_tmpaddr(struct in6_ifaddr *ia6)
     		 */
     		if (!IFA6_IS_DEPRECATED(it6))
     		    public_ifa6 = it6;
    +
    +		if (public_ifa6 != NULL)
    +			ifa_ref(&public_ifa6->ia_ifa);
     	}
    +	IF_ADDR_UNLOCK(ifp);
     
     	if (public_ifa6 != NULL) {
     		int e;
     
     		if ((e = in6_tmpifadd(public_ifa6, 0, 0)) != 0) {
    -			IF_ADDR_UNLOCK(ifp);
    +			ifa_free(&public_ifa6->ia_ifa);
     			log(LOG_NOTICE, "regen_tmpaddr: failed to create a new"
     			    " tmp addr,errno=%d\n", e);
     			return (-1);
     		}
    -		IF_ADDR_UNLOCK(ifp);
    +		ifa_free(&public_ifa6->ia_ifa);
     		return (0);
     	}
     
    -	IF_ADDR_UNLOCK(ifp);
     	return (-1);
     }
     
    
    From cd6f0f7554f66e10c85a03ce20cb922c188b144f Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Mon, 8 Mar 2010 21:36:20 +0000
    Subject: [PATCH 1573/2592] MFC 204518: Print the contents of the miscellaneous
     (MISC) register to the console if it is valid along with the other register
     values when a machine check is encountered.
    
    ---
     sys/amd64/amd64/mca.c | 2 ++
     sys/i386/i386/mca.c   | 2 ++
     2 files changed, 4 insertions(+)
    
    diff --git a/sys/amd64/amd64/mca.c b/sys/amd64/amd64/mca.c
    index 0403de4c47b..b0e842a778b 100644
    --- a/sys/amd64/amd64/mca.c
    +++ b/sys/amd64/amd64/mca.c
    @@ -288,6 +288,8 @@ mca_log(const struct mca_record *rec)
     	printf("\n");
     	if (rec->mr_status & MC_STATUS_ADDRV)
     		printf("MCA: Address 0x%llx\n", (long long)rec->mr_addr);
    +	if (rec->mr_status & MC_STATUS_MISCV)
    +		printf("MCA: Misc 0x%llx\n", (long long)rec->mr_misc);
     }
     
     static int __nonnull(2)
    diff --git a/sys/i386/i386/mca.c b/sys/i386/i386/mca.c
    index eaa78b86262..6148af79243 100644
    --- a/sys/i386/i386/mca.c
    +++ b/sys/i386/i386/mca.c
    @@ -288,6 +288,8 @@ mca_log(const struct mca_record *rec)
     	printf("\n");
     	if (rec->mr_status & MC_STATUS_ADDRV)
     		printf("MCA: Address 0x%llx\n", (long long)rec->mr_addr);
    +	if (rec->mr_status & MC_STATUS_MISCV)
    +		printf("MCA: Misc 0x%llx\n", (long long)rec->mr_misc);
     }
     
     static int __nonnull(2)
    
    From bf5483fddcb0fe26df818bb830576e2672a03a68 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 9 Mar 2010 13:32:50 +0000
    Subject: [PATCH 1574/2592] MFC r204590: Correct mfip module dependency on mfi.
     This allows mfip to be loaded as module when mfi is a module itself.
    
    ---
     sys/dev/mfi/mfi_cam.c | 1 +
     sys/dev/mfi/mfi_pci.c | 1 +
     2 files changed, 2 insertions(+)
    
    diff --git a/sys/dev/mfi/mfi_cam.c b/sys/dev/mfi/mfi_cam.c
    index 83a8e4eda79..fe1ffe5806f 100644
    --- a/sys/dev/mfi/mfi_cam.c
    +++ b/sys/dev/mfi/mfi_cam.c
    @@ -95,6 +95,7 @@ static driver_t mfip_driver = {
     };
     DRIVER_MODULE(mfip, mfi, mfip_driver, mfip_devclass, 0, 0);
     MODULE_DEPEND(mfip, cam, 1, 1, 1);
    +MODULE_DEPEND(mfip, mfi, 1, 1, 1);
     
     #define ccb_mfip_ptr sim_priv.entries[0].ptr
     
    diff --git a/sys/dev/mfi/mfi_pci.c b/sys/dev/mfi/mfi_pci.c
    index 5f0b341ab35..685aa0b4b8c 100644
    --- a/sys/dev/mfi/mfi_pci.c
    +++ b/sys/dev/mfi/mfi_pci.c
    @@ -105,6 +105,7 @@ static driver_t mfi_pci_driver = {
     
     static devclass_t	mfi_devclass;
     DRIVER_MODULE(mfi, pci, mfi_pci_driver, mfi_devclass, 0, 0);
    +MODULE_VERSION(mfi, 1);
     
     struct mfi_ident {
     	uint16_t	vendor;
    
    From 50819829d316194ca10673147cc299b5a9695568 Mon Sep 17 00:00:00 2001
    From: Gavin Atkinson 
    Date: Wed, 10 Mar 2010 13:40:37 +0000
    Subject: [PATCH 1575/2592] Merge r204053 from head:
    
      The correct value of DEL is 0x7f, not 0xff.  This is purely a documentation
      issue - od(1) and hexdump(1) behave as expected.
    
    PR:		docs/143869
    Submitted by:	gcooper
    ---
     usr.bin/hexdump/hexdump.1 | 4 ++--
     usr.bin/hexdump/od.1      | 4 ++--
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/usr.bin/hexdump/hexdump.1 b/usr.bin/hexdump/hexdump.1
    index 4d8c2daefec..baf9d463652 100644
    --- a/usr.bin/hexdump/hexdump.1
    +++ b/usr.bin/hexdump/hexdump.1
    @@ -32,7 +32,7 @@
     .\"	@(#)hexdump.1	8.2 (Berkeley) 4/18/94
     .\" $FreeBSD$
     .\"
    -.Dd July 10, 2004
    +.Dd February 18, 2010
     .Dt HEXDUMP 1
     .Os
     .Sh NAME
    @@ -258,7 +258,7 @@ strings.
     .It "\&00C\ FF\t00D\ CR\t00E\ SO\t00F\ SI\t010\ DLE\t011\ DC1
     .It "\&012\ DC2\t013\ DC3\t014\ DC4\t015\ NAK\t016\ SYN\t017\ ETB
     .It "\&018\ CAN\t019\ EM\t01A\ SUB\t01B\ ESC\t01C\ FS\t01D\ GS
    -.It "\&01E\ RS\t01F\ US\t0FF\ DEL
    +.It "\&01E\ RS\t01F\ US\t07F\ DEL
     .El
     .El
     .Pp
    diff --git a/usr.bin/hexdump/od.1 b/usr.bin/hexdump/od.1
    index 9bf79676210..dd67ff58b23 100644
    --- a/usr.bin/hexdump/od.1
    +++ b/usr.bin/hexdump/od.1
    @@ -32,7 +32,7 @@
     .\"	@(#)od.1	8.1 (Berkeley) 6/6/93
     .\" $FreeBSD$
     .\"
    -.Dd December 24, 2006
    +.Dd February 18, 2010
     .Os
     .Dt OD 1
     .Sh NAME
    @@ -155,7 +155,7 @@ Control characters are displayed using the following names:
     .It "00c FF	00d CR	00e SO	00f SI	010 DLE	011 DC1"
     .It "012 DC2	013 DC3	014 DC4	015 NAK	016 SYN	017 ETB"
     .It "018 CAN	019 EM	01a SUB	01b ESC	01c FS	01d GS"
    -.It "01e RS	01f US	020 SP	0ff DEL"
    +.It "01e RS	01f US	020 SP	07f DEL"
     .El
     .It Cm c
     Characters in the default character set.
    
    From 0cd9e69daeda2f6afc56c8ccf8c94aba73136cf9 Mon Sep 17 00:00:00 2001
    From: Jung-uk Kim 
    Date: Wed, 10 Mar 2010 17:58:32 +0000
    Subject: [PATCH 1576/2592] MFC:	r197438, r203810, r203813, r203935, r203936
    
    Sync acpi_video(4) with HEAD.
    
    r197438:
    Uninline an instance of STAILQ_FOREACH_SAFE().
    
    r203810:
    Implement LCD brightness control notify handler.
    
    r203813:
    Make sanity check slightly more useful and tweak an error message.
    
    r203935:
    Add support for `cycle' and `zero' events for LCD brightness control.
    
    r203936:
    Rename some macros to clarify their intentions and fix style nits.
    ---
     sys/dev/acpica/acpi_video.c | 177 ++++++++++++++++++++++++++++--------
     1 file changed, 140 insertions(+), 37 deletions(-)
    
    diff --git a/sys/dev/acpica/acpi_video.c b/sys/dev/acpica/acpi_video.c
    index c253abceaf6..94ef7be655b 100644
    --- a/sys/dev/acpica/acpi_video.c
    +++ b/sys/dev/acpica/acpi_video.c
    @@ -83,6 +83,7 @@ static struct acpi_video_output *acpi_video_vo_init(UINT32);
     static void	acpi_video_vo_bind(struct acpi_video_output *, ACPI_HANDLE);
     static void	acpi_video_vo_destroy(struct acpi_video_output *);
     static int	acpi_video_vo_check_level(struct acpi_video_output *, int);
    +static void	acpi_video_vo_notify_handler(ACPI_HANDLE, UINT32, void *);
     static int	acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS);
     static int	acpi_video_vo_bright_sysctl(SYSCTL_HANDLER_ARGS);
     static int	acpi_video_vo_presets_sysctl(SYSCTL_HANDLER_ARGS);
    @@ -93,56 +94,61 @@ static void	vid_set_switch_policy(ACPI_HANDLE, UINT32);
     static int	vid_enum_outputs(ACPI_HANDLE,
     		    void(*)(ACPI_HANDLE, UINT32, void *), void *);
     static int	vo_get_brightness_levels(ACPI_HANDLE, int **);
    +static int	vo_get_brightness(ACPI_HANDLE);
     static void	vo_set_brightness(ACPI_HANDLE, int);
     static UINT32	vo_get_device_status(ACPI_HANDLE);
     static UINT32	vo_get_graphics_state(ACPI_HANDLE);
     static void	vo_set_device_state(ACPI_HANDLE, UINT32);
     
     /* events */
    -#define VID_NOTIFY_SWITCHED	0x80
    -#define VID_NOTIFY_REPROBE	0x81
    +#define	VID_NOTIFY_SWITCHED	0x80
    +#define	VID_NOTIFY_REPROBE	0x81
    +#define	VID_NOTIFY_CYCLE_BRN	0x85
    +#define	VID_NOTIFY_INC_BRN	0x86
    +#define	VID_NOTIFY_DEC_BRN	0x87
    +#define	VID_NOTIFY_ZERO_BRN	0x88
     
     /* _DOS (Enable/Disable Output Switching) argument bits */
    -#define DOS_SWITCH_MASK		3
    -#define DOS_SWITCH_BY_OSPM	0
    -#define DOS_SWITCH_BY_BIOS	1
    -#define DOS_SWITCH_LOCKED	2
    -#define DOS_BRIGHTNESS_BY_BIOS	(1 << 2)
    +#define	DOS_SWITCH_MASK		3
    +#define	DOS_SWITCH_BY_OSPM	0
    +#define	DOS_SWITCH_BY_BIOS	1
    +#define	DOS_SWITCH_LOCKED	2
    +#define	DOS_BRIGHTNESS_BY_OSPM	(1 << 2)
     
     /* _DOD and subdev's _ADR */
    -#define DOD_DEVID_MASK		0x0f00
    -#define DOD_DEVID_MASK_FULL	0xffff
    -#define DOD_DEVID_MASK_DISPIDX	0x000f
    -#define DOD_DEVID_MASK_DISPPORT	0x00f0
    -#define DOD_DEVID_MONITOR	0x0100
    -#define DOD_DEVID_LCD		0x0110
    -#define DOD_DEVID_TV		0x0200
    -#define DOD_DEVID_EXT		0x0300
    -#define DOD_DEVID_INTDFP	0x0400
    -#define DOD_BIOS		(1 << 16)
    -#define DOD_NONVGA		(1 << 17)
    -#define DOD_HEAD_ID_SHIFT	18
    -#define DOD_HEAD_ID_BITS	3
    -#define DOD_HEAD_ID_MASK \
    +#define	DOD_DEVID_MASK		0x0f00
    +#define	DOD_DEVID_MASK_FULL	0xffff
    +#define	DOD_DEVID_MASK_DISPIDX	0x000f
    +#define	DOD_DEVID_MASK_DISPPORT	0x00f0
    +#define	DOD_DEVID_MONITOR	0x0100
    +#define	DOD_DEVID_LCD		0x0110
    +#define	DOD_DEVID_TV		0x0200
    +#define	DOD_DEVID_EXT		0x0300
    +#define	DOD_DEVID_INTDFP	0x0400
    +#define	DOD_BIOS		(1 << 16)
    +#define	DOD_NONVGA		(1 << 17)
    +#define	DOD_HEAD_ID_SHIFT	18
    +#define	DOD_HEAD_ID_BITS	3
    +#define	DOD_HEAD_ID_MASK \
     		(((1 << DOD_HEAD_ID_BITS) - 1) << DOD_HEAD_ID_SHIFT)
    -#define DOD_DEVID_SCHEME_STD	(1 << 31)
    +#define	DOD_DEVID_SCHEME_STD	(1 << 31)
     
     /* _BCL related constants */
    -#define BCL_FULLPOWER		0
    -#define BCL_ECONOMY		1
    +#define	BCL_FULLPOWER		0
    +#define	BCL_ECONOMY		1
     
     /* _DCS (Device Currrent Status) value bits and masks. */
    -#define DCS_EXISTS		(1 << 0)
    -#define DCS_ACTIVE		(1 << 1)
    -#define DCS_READY		(1 << 2)
    -#define DCS_FUNCTIONAL		(1 << 3)
    -#define DCS_ATTACHED		(1 << 4)
    +#define	DCS_EXISTS		(1 << 0)
    +#define	DCS_ACTIVE		(1 << 1)
    +#define	DCS_READY		(1 << 2)
    +#define	DCS_FUNCTIONAL		(1 << 3)
    +#define	DCS_ATTACHED		(1 << 4)
     
     /* _DSS (Device Set Status) argument bits and masks. */
    -#define DSS_INACTIVE		0
    -#define DSS_ACTIVE		(1 << 0)
    -#define DSS_SETNEXT		(1 << 30)
    -#define DSS_COMMIT		(1 << 31)
    +#define	DSS_INACTIVE		0
    +#define	DSS_ACTIVE		(1 << 0)
    +#define	DSS_SETNEXT		(1 << 30)
    +#define	DSS_COMMIT		(1 << 31)
     
     static device_method_t acpi_video_methods[] = {
     	DEVMETHOD(device_identify, acpi_video_identify),
    @@ -269,7 +275,7 @@ acpi_video_attach(device_t dev)
     	 * brightness levels.
     	 */
     	vid_set_switch_policy(sc->handle, DOS_SWITCH_BY_OSPM |
    -	    DOS_BRIGHTNESS_BY_BIOS);
    +	    DOS_BRIGHTNESS_BY_OSPM);
     
     	acpi_video_power_profile(sc);
     
    @@ -290,8 +296,7 @@ acpi_video_detach(device_t dev)
     				acpi_video_notify_handler);
     
     	ACPI_SERIAL_BEGIN(video);
    -	for (vo = STAILQ_FIRST(&sc->vid_outputs); vo != NULL; vo = vn) {
    -		vn = STAILQ_NEXT(vo, vo_next);
    +	STAILQ_FOREACH_SAFE(vo, &sc->vid_outputs, vo_next, vn) {
     		acpi_video_vo_destroy(vo);
     	}
     	ACPI_SERIAL_END(video);
    @@ -578,6 +583,9 @@ acpi_video_vo_bind(struct acpi_video_output *vo, ACPI_HANDLE handle)
     			/* XXX - see above. */
     			vo->vo_economy = vo->vo_levels[BCL_ECONOMY];
     	}
    +	if (vo->vo_levels != NULL)
    +	    AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
    +		acpi_video_vo_notify_handler, vo);
     	ACPI_SERIAL_END(video_output);
     }
     
    @@ -591,8 +599,11 @@ acpi_video_vo_destroy(struct acpi_video_output *vo)
     		vo->vo_sysctl_tree = NULL;
     		sysctl_ctx_free(&vo->vo_sysctl_ctx);
     	}
    -	if (vo->vo_levels != NULL)
    +	if (vo->vo_levels != NULL) {
    +		AcpiRemoveNotifyHandler(vo->handle, ACPI_DEVICE_NOTIFY,
    +		    acpi_video_vo_notify_handler);
     		AcpiOsFree(vo->vo_levels);
    +	}
     
     	switch (vo->adr & DOD_DEVID_MASK) {
     	case DOD_DEVID_MONITOR:
    @@ -628,6 +639,79 @@ acpi_video_vo_check_level(struct acpi_video_output *vo, int level)
     	return (EINVAL);
     }
     
    +static void
    +acpi_video_vo_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
    +{
    +	struct acpi_video_output *vo;
    +	int i, j, level, new_level;
    +
    +	vo = context;
    +	ACPI_SERIAL_BEGIN(video_output);
    +	if (vo->handle != handle)
    +		goto out;
    +
    +	switch (notify) {
    +	case VID_NOTIFY_CYCLE_BRN:
    +		if (vo->vo_numlevels <= 3)
    +			goto out;
    +		/* FALLTHROUGH */
    +	case VID_NOTIFY_INC_BRN:
    +	case VID_NOTIFY_DEC_BRN:
    +	case VID_NOTIFY_ZERO_BRN:
    +		if (vo->vo_levels == NULL)
    +			goto out;
    +		level = vo_get_brightness(handle);
    +		if (level < 0)
    +			goto out;
    +		break;
    +	default:
    +		printf("unknown notify event 0x%x from %s\n",
    +		    notify, acpi_name(handle));
    +		goto out;
    +	}
    +
    +	new_level = level;
    +	switch (notify) {
    +	case VID_NOTIFY_CYCLE_BRN:
    +		for (i = 2; i < vo->vo_numlevels; i++)
    +			if (vo->vo_levels[i] == level) {
    +				new_level = vo->vo_numlevels > i + 1 ?
    +				     vo->vo_levels[i + 1] : vo->vo_levels[2];
    +				break;
    +			}
    +		break;
    +	case VID_NOTIFY_INC_BRN:
    +	case VID_NOTIFY_DEC_BRN:
    +		for (i = 0; i < vo->vo_numlevels; i++) {
    +			j = vo->vo_levels[i];
    +			if (notify == VID_NOTIFY_INC_BRN) {
    +				if (j > level &&
    +				    (j < new_level || level == new_level))
    +					new_level = j;
    +			} else {
    +				if (j < level &&
    +				    (j > new_level || level == new_level))
    +					new_level = j;
    +			}
    +		}
    +		break;
    +	case VID_NOTIFY_ZERO_BRN:
    +		for (i = 0; i < vo->vo_numlevels; i++)
    +			if (vo->vo_levels[i] == 0) {
    +				new_level = 0;
    +				break;
    +			}
    +		break;
    +	}
    +	if (new_level != level) {
    +		vo_set_brightness(handle, new_level);
    +		vo->vo_brightness = new_level;
    +	}
    +
    +out:
    +	ACPI_SERIAL_END(video_output);
    +}
    +
     /* ARGSUSED */
     static int
     acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS)
    @@ -901,6 +985,25 @@ out:
     	return (num);
     }
     
    +static int
    +vo_get_brightness(ACPI_HANDLE handle)
    +{
    +	UINT32 level;
    +	ACPI_STATUS status;
    +
    +	ACPI_SERIAL_ASSERT(video_output);
    +	status = acpi_GetInteger(handle, "_BQC", &level);
    +	if (ACPI_FAILURE(status)) {
    +		printf("can't evaluate %s._BQC - %s\n", acpi_name(handle),
    +		    AcpiFormatException(status));
    +		return (-1);
    +	}
    +	if (level > 100)
    +		return (-1);
    +
    +	return (level);
    +}
    +
     static void
     vo_set_brightness(ACPI_HANDLE handle, int level)
     {
    
    From 7a547c991a331ea88994d4daf512136670fe95f7 Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Wed, 10 Mar 2010 19:47:05 +0000
    Subject: [PATCH 1577/2592] MFC 204638: Allow lseek(SEEK_END) to work on disk
     devices by using the DIOCGMEDIASIZE to determine the media size.
    
    ---
     sys/kern/vfs_syscalls.c | 12 +++++++++++-
     1 file changed, 11 insertions(+), 1 deletion(-)
    
    diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
    index 0a8ef463957..c9226952228 100644
    --- a/sys/kern/vfs_syscalls.c
    +++ b/sys/kern/vfs_syscalls.c
    @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -1914,7 +1915,7 @@ lseek(td, uap)
     	struct file *fp;
     	struct vnode *vp;
     	struct vattr vattr;
    -	off_t offset;
    +	off_t offset, size;
     	int error, noneg;
     	int vfslocked;
     
    @@ -1945,6 +1946,15 @@ lseek(td, uap)
     		VOP_UNLOCK(vp, 0);
     		if (error)
     			break;
    +
    +		/*
    +		 * If the file references a disk device, then fetch
    +		 * the media size and use that to determine the ending
    +		 * offset.
    +		 */
    +		if (vattr.va_size == 0 && vp->v_type == VCHR &&
    +		    fo_ioctl(fp, DIOCGMEDIASIZE, &size, cred, td) == 0)
    +			vattr.va_size = size;
     		if (noneg &&
     		    (vattr.va_size > OFF_MAX ||
     		    (offset > 0 && vattr.va_size > OFF_MAX - offset))) {
    
    From f4153ff1eaf6dbe703ce620ea2bbf9be68f06487 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Wed, 10 Mar 2010 22:21:07 +0000
    Subject: [PATCH 1578/2592] MFC r204647:   Remove programming LED register and
     enable 25MHz TX clock for   88E1149 PHY. This will fix intermittent watchdog
     timeouts as well   as very slow network performance on 88E8072 Yukon Extreme.
    
      PR:	kern/144148
    ---
     sys/dev/mii/e1000phy.c | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c
    index 2ff31d3520e..b50eb07a651 100644
    --- a/sys/dev/mii/e1000phy.c
    +++ b/sys/dev/mii/e1000phy.c
    @@ -276,7 +276,6 @@ e1000phy_reset(struct mii_softc *sc)
     	case MII_MODEL_MARVELL_E1118:
     		break;
     	case MII_MODEL_MARVELL_E1116:
    -	case MII_MODEL_MARVELL_E1149:
     		page = PHY_READ(sc, E1000_EADR);
     		/* Select page 3, LED control register. */
     		PHY_WRITE(sc, E1000_EADR, 3);
    
    From 4e0c5d79a0aa5fa7109e017111c07d0ce1988de2 Mon Sep 17 00:00:00 2001
    From: Fabien Thomas 
    Date: Thu, 11 Mar 2010 07:35:30 +0000
    Subject: [PATCH 1579/2592] MFC r204878:  Change the way shutdown is handled
     for log file.
    
     pmc_flush_logfile is now non-blocking and just ask the kernel
     to shutdown the file. From that point, no more data is
     accepted by the log thread and when the last buffer is flushed
     the file is closed.
    
     This will remove a deadlock between pmcstat asking for
     flush while it cannot flush the pipe itself.
    ---
     sys/dev/hwpmc/hwpmc_logging.c | 48 ++++++++++++++++++++---------------
     sys/sys/pmc.h                 |  2 +-
     2 files changed, 28 insertions(+), 22 deletions(-)
    
    diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c
    index a36a8dc7e72..055433da4b3 100644
    --- a/sys/dev/hwpmc/hwpmc_logging.c
    +++ b/sys/dev/hwpmc/hwpmc_logging.c
    @@ -237,7 +237,7 @@ pmclog_get_buffer(struct pmc_owner *po)
     static void
     pmclog_loop(void *arg)
     {
    -	int error;
    +	int error, last_buffer;
     	struct pmc_owner *po;
     	struct pmclog_buffer *lb;
     	struct proc *p;
    @@ -252,6 +252,7 @@ pmclog_loop(void *arg)
     	p = po->po_owner;
     	td = curthread;
     	mycred = td->td_ucred;
    +	last_buffer = 0;
     
     	PROC_LOCK(p);
     	ownercred = crhold(p->p_ucred);
    @@ -284,27 +285,20 @@ pmclog_loop(void *arg)
     			if ((lb = TAILQ_FIRST(&po->po_logbuffers)) == NULL) {
     				mtx_unlock_spin(&po->po_mtx);
     
    -				/*
    -				 * Wakeup the thread waiting for the
    -				 * PMC_OP_FLUSHLOG request to
    -				 * complete.
    -				 */
    -				if (po->po_flags & PMC_PO_IN_FLUSH) {
    -					po->po_flags &= ~PMC_PO_IN_FLUSH;
    -					wakeup_one(po->po_kthread);
    -				}
    -
     				(void) msleep(po, &pmc_kthread_mtx, PWAIT,
     				    "pmcloop", 0);
     				continue;
     			}
     
     			TAILQ_REMOVE(&po->po_logbuffers, lb, plb_next);
    +			if (po->po_flags & PMC_PO_SHUTDOWN)
    +				last_buffer = TAILQ_EMPTY(&po->po_logbuffers);
     			mtx_unlock_spin(&po->po_mtx);
     		}
     
     		mtx_unlock(&pmc_kthread_mtx);
     
    +sigpipe_retry:
     		/* process the request */
     		PMCDBG(LOG,WRI,2, "po=%p base=%p ptr=%p", po,
     		    lb->plb_base, lb->plb_ptr);
    @@ -328,7 +322,8 @@ pmclog_loop(void *arg)
     
     		if (error) {
     			/* XXX some errors are recoverable */
    -			/* XXX also check for SIGPIPE if a socket */
    +			if (error == EPIPE)
    +				goto sigpipe_retry;
     
     			/* send a SIGIO to the owner and exit */
     			PROC_LOCK(p);
    @@ -344,6 +339,14 @@ pmclog_loop(void *arg)
     			break;
     		}
     
    +		if (last_buffer) {
    +			/*
    +			 * Close the file to get PMCLOG_EOF error
    +			 * in pmclog(3).
    +			 */
    +			fo_close(po->po_file, curthread);
    +		}
    +
     		mtx_lock(&pmc_kthread_mtx);
     
     		/* put the used buffer back into the global pool */
    @@ -425,6 +428,12 @@ pmclog_reserve(struct pmc_owner *po, int length)
     
     	mtx_lock_spin(&po->po_mtx);
     
    +	/* No more data when shutdown in progress. */
    +	if (po->po_flags & PMC_PO_SHUTDOWN) {
    +		mtx_unlock_spin(&po->po_mtx);
    +		return (NULL);
    +	}
    +
     	if (po->po_curbuf == NULL)
     		if (pmclog_get_buffer(po) != 0) {
     			mtx_unlock_spin(&po->po_mtx);
    @@ -686,7 +695,7 @@ pmclog_deconfigure_log(struct pmc_owner *po)
     int
     pmclog_flush(struct pmc_owner *po)
     {
    -	int error, has_pending_buffers;
    +	int error;
     
     	PMCDBG(LOG,FLS,1, "po=%p", po);
     
    @@ -714,16 +723,13 @@ pmclog_flush(struct pmc_owner *po)
     	mtx_lock_spin(&po->po_mtx);
     	if (po->po_curbuf)
     		pmclog_schedule_io(po);
    -	has_pending_buffers = !TAILQ_EMPTY(&po->po_logbuffers);
     	mtx_unlock_spin(&po->po_mtx);
     
    -	if (has_pending_buffers) {
    -		po->po_flags |= PMC_PO_IN_FLUSH; /* ask for a wakeup */
    -		error = msleep(po->po_kthread, &pmc_kthread_mtx, PWAIT,
    -		    "pmcflush", 0);
    -		if (error == 0)
    -			error = po->po_error;
    -	}
    +	/*
    +	 * Initiate shutdown: no new data queued,
    +	 * thread will close file on last block.
    +	 */
    +	po->po_flags |= PMC_PO_SHUTDOWN;
     
      error:
     	mtx_unlock(&pmc_kthread_mtx);
    diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
    index 13ae433983d..1cc23933a9a 100644
    --- a/sys/sys/pmc.h
    +++ b/sys/sys/pmc.h
    @@ -755,7 +755,7 @@ struct pmc_owner  {
     };
     
     #define	PMC_PO_OWNS_LOGFILE		0x00000001 /* has a log file */
    -#define	PMC_PO_IN_FLUSH			0x00000010 /* in the middle of a flush */
    +#define	PMC_PO_SHUTDOWN			0x00000010 /* in the process of shutdown */
     #define	PMC_PO_INITIAL_MAPPINGS_DONE	0x00000020
     
     /*
    
    From 060d3bde0412a787c9bf84a535d07d4fa9639f3f Mon Sep 17 00:00:00 2001
    From: Fabien Thomas 
    Date: Thu, 11 Mar 2010 07:36:45 +0000
    Subject: [PATCH 1580/2592] MFC r204878:  Change the way shutdown is handled
     for log file.
    
     pmc_flush_logfile is now non-blocking and just ask the kernel
     to shutdown the file. From that point, no more data is
     accepted by the log thread and when the last buffer is flushed
     the file is closed.
    
     This will remove a deadlock between pmcstat asking for
     flush while it cannot flush the pipe itself.
    ---
     usr.sbin/pmcstat/pmcstat_log.c | 4 +---
     1 file changed, 1 insertion(+), 3 deletions(-)
    
    diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c
    index 5811af3f1c6..fc26001a592 100644
    --- a/usr.sbin/pmcstat/pmcstat_log.c
    +++ b/usr.sbin/pmcstat/pmcstat_log.c
    @@ -1670,10 +1670,8 @@ pmcstat_print_log(void)
     int
     pmcstat_close_log(void)
     {
    -	if (pmc_flush_logfile() < 0 ||
    -	    pmc_configure_logfile(-1) < 0)
    +	if (pmc_flush_logfile() < 0)
     		err(EX_OSERR, "ERROR: logging failed");
    -	args.pa_flags &= ~(FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE);
     	return (args.pa_flags & FLAG_HAS_PIPE ? PMCSTAT_EXITING :
     	    PMCSTAT_FINISHED);
     }
    
    From 57ff35ce7463326ebf23f67f798a1da7f8c5b3fb Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Thu, 11 Mar 2010 08:55:03 +0000
    Subject: [PATCH 1581/2592] MFC r203776: acpi cpu: probe+attach before all
     other enumerated children
    
    X-MFCto7 after:	1 week
    ---
     sys/dev/acpica/acpi.c     | 10 +++++-----
     sys/dev/acpica/acpi_cpu.c | 26 ++++++++++++++++++++++----
     2 files changed, 27 insertions(+), 9 deletions(-)
    
    diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
    index 8de8d900472..63112721dc4 100644
    --- a/sys/dev/acpica/acpi.c
    +++ b/sys/dev/acpica/acpi.c
    @@ -1691,14 +1691,14 @@ acpi_probe_order(ACPI_HANDLE handle, int *order)
          * 100000. CPUs
          */
         AcpiGetType(handle, &type);
    -    if (acpi_MatchHid(handle, "PNP0C01") || acpi_MatchHid(handle, "PNP0C02"))
    +    if (type == ACPI_TYPE_PROCESSOR)
     	*order = 1;
    -    else if (acpi_MatchHid(handle, "PNP0C09"))
    +    else if (acpi_MatchHid(handle, "PNP0C01") || acpi_MatchHid(handle, "PNP0C02"))
     	*order = 2;
    -    else if (acpi_MatchHid(handle, "PNP0C0F"))
    +    else if (acpi_MatchHid(handle, "PNP0C09"))
     	*order = 3;
    -    else if (type == ACPI_TYPE_PROCESSOR)
    -	*order = 100000;
    +    else if (acpi_MatchHid(handle, "PNP0C0F"))
    +	*order = 4;
     }
     
     /*
    diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
    index bbbd23926c2..06c29548132 100644
    --- a/sys/dev/acpica/acpi_cpu.c
    +++ b/sys/dev/acpica/acpi_cpu.c
    @@ -384,13 +384,31 @@ acpi_cpu_attach(device_t dev)
         /* Probe for Cx state support. */
         acpi_cpu_cx_probe(sc);
     
    -    /* Finally,  call identify and probe/attach for child devices. */
    -    bus_generic_probe(dev);
    -    bus_generic_attach(dev);
    -
         return (0);
     }
     
    +static void
    +acpi_cpu_postattach(void *unused __unused)
    +{
    +    device_t *devices;
    +    int err;
    +    int i, n;
    +
    +    err = devclass_get_devices(acpi_cpu_devclass, &devices, &n);
    +    if (err != 0) {
    +	printf("devclass_get_devices(acpi_cpu_devclass) failed\n");
    +	return;
    +    }
    +    for (i = 0; i < n; i++)
    +	bus_generic_probe(devices[i]);
    +    for (i = 0; i < n; i++)
    +	bus_generic_attach(devices[i]);
    +    free(devices, M_TEMP);
    +}
    +
    +SYSINIT(acpi_cpu, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE,
    +    acpi_cpu_postattach, NULL);
    +
     /*
      * Disable any entry to the idle function during suspend and re-enable it
      * during resume.
    
    From e850e4719faf504a1f6f38777e769547795c04c4 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Thu, 11 Mar 2010 08:58:13 +0000
    Subject: [PATCH 1582/2592] MFC r203785: acpi: drop the second
     bus_generic_attach pass
    
    X-MFCto7 after: 1 week
    ---
     sys/dev/acpica/acpi.c | 9 +--------
     1 file changed, 1 insertion(+), 8 deletions(-)
    
    diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
    index 63112721dc4..28bde01d1ad 100644
    --- a/sys/dev/acpica/acpi.c
    +++ b/sys/dev/acpica/acpi.c
    @@ -1659,14 +1659,7 @@ acpi_probe_children(device_t bus)
         bus_generic_probe(bus);
     
         /* Probe/attach all children, created staticly and from the namespace. */
    -    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "first bus_generic_attach\n"));
    -    bus_generic_attach(bus);
    -
    -    /*
    -     * Some of these children may have attached others as part of their attach
    -     * process (eg. the root PCI bus driver), so rescan.
    -     */
    -    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "second bus_generic_attach\n"));
    +    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "acpi bus_generic_attach\n"));
         bus_generic_attach(bus);
     
         /* Attach wake sysctls. */
    
    From 8b354843922beab3db10ac84c125c734104af0b6 Mon Sep 17 00:00:00 2001
    From: Bernhard Schmidt 
    Date: Thu, 11 Mar 2010 17:11:07 +0000
    Subject: [PATCH 1583/2592] MFC r204213: Fix some typos.
    
    Approved by:	rpaulo (mentor)
    ---
     share/man/man9/ieee80211_scan.9 | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/share/man/man9/ieee80211_scan.9 b/share/man/man9/ieee80211_scan.9
    index 7ac41bdb903..018f70f8d74 100644
    --- a/share/man/man9/ieee80211_scan.9
    +++ b/share/man/man9/ieee80211_scan.9
    @@ -25,7 +25,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd August 4, 2009
    +.Dd February 20, 2010
     .Dt IEEE80211_SCAN 9
     .Os
     .Sh NAME
    @@ -177,8 +177,8 @@ Scanning is not tied to the
     state machine that governs vaps except for linkage to the
     .Dv IEEE80211_S_SCAN
     state.
    -One one vap at a time may be scanning; this scheduling policy
    -is handle in
    +Only one vap at a time may be scanning; this scheduling policy
    +is handled in
     .Fn ieee80211_new_state
     and is transparent to scanning code.
     .Pp
    
    From 36026f82d6d78bc7079136b27d8ae8eaa973214d Mon Sep 17 00:00:00 2001
    From: Bernhard Schmidt 
    Date: Thu, 11 Mar 2010 17:15:40 +0000
    Subject: [PATCH 1584/2592] MFC r203934: Fix for the Intel WiFi Link 1000.  The
     EEPROM image is in the OTPROM block before the last block, not in the last
     block itself.
    
    Approved by:	rpaulo (mentor)
    Obtained from:	OpenBSD
    ---
     sys/dev/iwn/if_iwn.c | 14 +++++++-------
     1 file changed, 7 insertions(+), 7 deletions(-)
    
    diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
    index bbd8dd9453e..b6af7b8896b 100644
    --- a/sys/dev/iwn/if_iwn.c
    +++ b/sys/dev/iwn/if_iwn.c
    @@ -972,8 +972,7 @@ iwn_eeprom_unlock(struct iwn_softc *sc)
     int
     iwn_init_otprom(struct iwn_softc *sc)
     {
    -	uint32_t base;
    -	uint16_t next;
    +	uint16_t prev, base, next;
     	int count, error;
     
     	/* Wait for clock stabilization before accessing prph. */
    @@ -1000,25 +999,26 @@ iwn_init_otprom(struct iwn_softc *sc)
     	    IWN_OTP_GP_ECC_CORR_STTS | IWN_OTP_GP_ECC_UNCORR_STTS);
     
     	/*
    -	 * Find last valid OTP block (contains the EEPROM image) for HW
    -	 * without OTP shadow RAM.
    +	 * Find the block before last block (contains the EEPROM image)
    +	 * for HW without OTP shadow RAM.
     	 */
     	if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
     		/* Switch to absolute addressing mode. */
     		IWN_CLRBITS(sc, IWN_OTP_GP, IWN_OTP_GP_RELATIVE_ACCESS);
    -		base = 0;
    +		base = prev = 0;
     		for (count = 0; count < IWN1000_OTP_NBLOCKS; count++) {
     			error = iwn_read_prom_data(sc, base, &next, 2);
     			if (error != 0)
     				return error;
     			if (next == 0)	/* End of linked-list. */
     				break;
    +			prev = base;
     			base = le16toh(next);
     		}
    -		if (base == 0 || count == IWN1000_OTP_NBLOCKS)
    +		if (count == 0 || count == IWN1000_OTP_NBLOCKS)
     			return EIO;
     		/* Skip "next" word. */
    -		sc->prom_base = base + 1;
    +		sc->prom_base = prev + 1;
     	}
     	return 0;
     }
    
    From ea2c000633765fbfb42e63a74b8ee3fb10bb4aff Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Fri, 12 Mar 2010 00:51:13 +0000
    Subject: [PATCH 1585/2592] MFC r203760: Improve time precision for grdc(6):
    
    Traditionally, grdc would obtain time through time(3) which in turn gets
    only the second part of clock (CLOCK_SECOND), and sleep for 1 second after
    each screen refresh.
    
    This approach would have two problems.  First, we are not guaranteed to
    be waken up at the beginning of a whole second, which will typically
    exhibit as a "lag" on second number.  Second, because we sleep for whole
    second, and the refresh process would take some time, the error would
    accumulate from time to time, making the lag variable.
    
    Make grdc(6) to use time(3) to get time only at the beginning, and sample
    time in CLOCK_REALTIME_FAST granularity after refreshing, and use the
    nanosecond part to caculate how much time we want to sleep.
    
    PR:		bin/120813
    ---
     games/grdc/grdc.c | 17 +++++++++++++++--
     1 file changed, 15 insertions(+), 2 deletions(-)
    
    diff --git a/games/grdc/grdc.c b/games/grdc/grdc.c
    index d27b10ed791..c467b533e28 100644
    --- a/games/grdc/grdc.c
    +++ b/games/grdc/grdc.c
    @@ -59,6 +59,7 @@ main(argc, argv)
     int argc;
     char **argv;
     {
    +struct timespec ts;
     long t, a;
     int i, j, s, k;
     int n;
    @@ -136,9 +137,9 @@ int t12;
     
     		attrset(COLOR_PAIR(2));
     	}
    +	time(&now);
     	do {
     		mask = 0;
    -		time(&now);
     		tm = localtime(&now);
     		set(tm->tm_sec%10, 0);
     		set(tm->tm_sec/10, 4);
    @@ -193,7 +194,19 @@ int t12;
     		}
     		movto(6, 0);
     		refresh();
    -		sleep(1);
    +		clock_gettime(CLOCK_REALTIME_FAST, &ts);
    +		if (ts.tv_sec == now) {
    +			if (ts.tv_nsec > 0) {
    +				ts.tv_sec = 0;
    +				ts.tv_nsec = 1000000000 - ts.tv_nsec;
    +			} else {
    +				ts.tv_sec = 1;
    +				ts.tv_nsec = 0;
    +			}
    +			nanosleep(&ts, NULL);
    +			now = ts.tv_sec + 1;
    +		} else
    +			now = ts.tv_sec;
     		if (sigtermed) {
     			standend();
     			clear();
    
    From cf4bd5e4d96f57c576b1e23183a01b6820e53ff7 Mon Sep 17 00:00:00 2001
    From: Joerg Wunsch 
    Date: Fri, 12 Mar 2010 05:16:24 +0000
    Subject: [PATCH 1586/2592] (r205011) The "number" argument is everything but
     optional.
    
    ---
     usr.bin/perror/perror.1 | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/usr.bin/perror/perror.1 b/usr.bin/perror/perror.1
    index 7faf77f10d9..0b724b14ca6 100644
    --- a/usr.bin/perror/perror.1
    +++ b/usr.bin/perror/perror.1
    @@ -34,7 +34,7 @@
     .Nd "print an error number as a string"
     .Sh SYNOPSIS
     .Nm
    -.Op Ar number
    +.Ar number
     .Sh DESCRIPTION
     The
     .Nm
    
    From 324846ecfa1b8fd110d421572848e8e7194940bf Mon Sep 17 00:00:00 2001
    From: Jaakko Heinonen 
    Date: Fri, 12 Mar 2010 06:56:51 +0000
    Subject: [PATCH 1587/2592] MFC r204447:
    
    In _gettemp(), check that the length of the path doesn't exceed
    MAXPATHLEN. Otherwise the path name (or part of it) may not fit to
    carrybuf causing a buffer overflow.
    
    PR:		bin/140228
    ---
     lib/libc/stdio/mktemp.c | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/lib/libc/stdio/mktemp.c b/lib/libc/stdio/mktemp.c
    index 3f1e699f213..a30b930354e 100644
    --- a/lib/libc/stdio/mktemp.c
    +++ b/lib/libc/stdio/mktemp.c
    @@ -116,6 +116,10 @@ _gettemp(path, doopen, domkdir, slen)
     
     	for (trv = path; *trv != '\0'; ++trv)
     		;
    +	if (trv - path >= MAXPATHLEN) {
    +		errno = ENAMETOOLONG;
    +		return (0);
    +	}
     	trv -= slen;
     	suffp = trv;
     	--trv;
    
    From 6c96d2f595439b32c9c3a2ec77269531a236c981 Mon Sep 17 00:00:00 2001
    From: Bernd Walter 
    Date: Sat, 13 Mar 2010 16:37:17 +0000
    Subject: [PATCH 1588/2592] MFC 204462,204463,204476: fix multicast hashes
    
    ---
     sys/arm/at91/if_ate.c | 14 ++++++++++++--
     1 file changed, 12 insertions(+), 2 deletions(-)
    
    diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c
    index ec4771c81ac..49ed9ee5d89 100644
    --- a/sys/arm/at91/if_ate.c
    +++ b/sys/arm/at91/if_ate.c
    @@ -383,6 +383,16 @@ ate_load_rx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
     	bus_dmamap_sync(sc->rxtag, sc->rx_map[i], BUS_DMASYNC_PREREAD);
     }
     
    +static uint32_t
    +ate_mac_hash(const uint8_t *buf)
    +{
    +	uint32_t index = 0;
    +	for (int i = 0; i < 48; i++) {
    +		index ^= ((buf[i >> 3] >> (i & 7)) & 1) << (i % 6);
    +	}
    +	return (index);
    +}
    +
     /*
      * Compute the multicast filter for this device using the standard
      * algorithm.  I wonder why this isn't in ether somewhere as a lot
    @@ -417,8 +427,8 @@ ate_setmcast(struct ate_softc *sc)
     	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
     		if (ifma->ifma_addr->sa_family != AF_LINK)
     			continue;
    -		index = ether_crc32_be(LLADDR((struct sockaddr_dl *)
    -		    ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
    +		index = ate_mac_hash(LLADDR((struct sockaddr_dl *)
    +		    ifma->ifma_addr));
     		af[index >> 3] |= 1 << (index & 7);
     	}
     	if_maddr_runlock(ifp);
    
    From 873d27446aa513109f831d03b5e046cc30161dfa Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sun, 14 Mar 2010 13:07:40 +0000
    Subject: [PATCH 1589/2592] MFC r204410: Include terminated threads in ps's
     process cpu time field.
    
    When a kinfo_proc is filled, first fill_kinfo_proc_only() fills in
    ki_runtime using p->p_rux.rux_runtime (all cpu time used by the process
    including terminated threads). If information for a specific thread is
    requested, fill_kinfo_thread() then overwrites this with the thread's
    td->td_runtime (good). If not, fill_kinfo_aggregate() overwrote it with
    the sum of all threads' td->td_runtime which does not include terminated
    threads.
    
    This affects ps(1)'s TIME field, not its %CPU field nor anything in
    top(1).
    ---
     sys/kern/kern_proc.c | 2 --
     1 file changed, 2 deletions(-)
    
    diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
    index 51136981189..166baa086fe 100644
    --- a/sys/kern/kern_proc.c
    +++ b/sys/kern/kern_proc.c
    @@ -675,11 +675,9 @@ fill_kinfo_aggregate(struct proc *p, struct kinfo_proc *kp)
     
     	kp->ki_estcpu = 0;
     	kp->ki_pctcpu = 0;
    -	kp->ki_runtime = 0;
     	FOREACH_THREAD_IN_PROC(p, td) {
     		thread_lock(td);
     		kp->ki_pctcpu += sched_pctcpu(td);
    -		kp->ki_runtime += cputick2usec(td->td_runtime);
     		kp->ki_estcpu += td->td_estcpu;
     		thread_unlock(td);
     	}
    
    From 2173958d3e5a3344642d2fab64c32f1d3cae21f3 Mon Sep 17 00:00:00 2001
    From: Bruno Ducrot 
    Date: Mon, 15 Mar 2010 15:33:32 +0000
    Subject: [PATCH 1590/2592] MFC r204519: Deliver siginfo when signal is
     generated by thr_kill(2) (SI_USER with properly filled si_uid and si_pid).
    
    PR:		141956
    ---
     sys/kern/kern_thr.c | 21 +++++++++++++++++----
     1 file changed, 17 insertions(+), 4 deletions(-)
    
    diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
    index 3159a910b0b..116e79bae33 100644
    --- a/sys/kern/kern_thr.c
    +++ b/sys/kern/kern_thr.c
    @@ -303,12 +303,18 @@ int
     thr_kill(struct thread *td, struct thr_kill_args *uap)
         /* long id, int sig */
     {
    +	ksiginfo_t ksi;
     	struct thread *ttd;
     	struct proc *p;
     	int error;
     
     	p = td->td_proc;
     	error = 0;
    +	ksiginfo_init(&ksi);
    +	ksi.ksi_signo = uap->sig;
    +	ksi.ksi_code = SI_USER;
    +	ksi.ksi_pid = p->p_pid;
    +	ksi.ksi_uid = td->td_ucred->cr_ruid;
     	PROC_LOCK(p);
     	if (uap->id == -1) {
     		if (uap->sig != 0 && !_SIG_VALID(uap->sig)) {
    @@ -320,7 +326,7 @@ thr_kill(struct thread *td, struct thr_kill_args *uap)
     					error = 0;
     					if (uap->sig == 0)
     						break;
    -					tdsignal(p, ttd, uap->sig, NULL);
    +					tdsignal(p, ttd, uap->sig, &ksi);
     				}
     			}
     		}
    @@ -336,7 +342,7 @@ thr_kill(struct thread *td, struct thr_kill_args *uap)
     		else if (!_SIG_VALID(uap->sig))
     			error = EINVAL;
     		else
    -			tdsignal(p, ttd, uap->sig, NULL);
    +			tdsignal(p, ttd, uap->sig, &ksi);
     	}
     	PROC_UNLOCK(p);
     	return (error);
    @@ -346,6 +352,7 @@ int
     thr_kill2(struct thread *td, struct thr_kill2_args *uap)
         /* pid_t pid, long id, int sig */
     {
    +	ksiginfo_t ksi;
     	struct thread *ttd;
     	struct proc *p;
     	int error;
    @@ -362,6 +369,11 @@ thr_kill2(struct thread *td, struct thr_kill2_args *uap)
     
     	error = p_cansignal(td, p, uap->sig);
     	if (error == 0) {
    +		ksiginfo_init(&ksi);
    +		ksi.ksi_signo = uap->sig;
    +		ksi.ksi_code = SI_USER;
    +		ksi.ksi_pid = td->td_proc->p_pid;
    +		ksi.ksi_uid = td->td_ucred->cr_ruid;
     		if (uap->id == -1) {
     			if (uap->sig != 0 && !_SIG_VALID(uap->sig)) {
     				error = EINVAL;
    @@ -372,7 +384,8 @@ thr_kill2(struct thread *td, struct thr_kill2_args *uap)
     						error = 0;
     						if (uap->sig == 0)
     							break;
    -						tdsignal(p, ttd, uap->sig, NULL);
    +						tdsignal(p, ttd, uap->sig,
    +						    &ksi);
     					}
     				}
     			}
    @@ -388,7 +401,7 @@ thr_kill2(struct thread *td, struct thr_kill2_args *uap)
     			else if (!_SIG_VALID(uap->sig))
     				error = EINVAL;
     			else
    -				tdsignal(p, ttd, uap->sig, NULL);
    +				tdsignal(p, ttd, uap->sig, &ksi);
     		}
     	}
     	PROC_UNLOCK(p);
    
    From 77d503efb1a57ce1c377d19f74c0a465a4a32575 Mon Sep 17 00:00:00 2001
    From: Jaakko Heinonen 
    Date: Mon, 15 Mar 2010 16:39:52 +0000
    Subject: [PATCH 1591/2592] MFC r204872: Pass the correct size to memset().
    
    PR:		bin/128094
    ---
     usr.bin/xlint/lint1/scan.l | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/usr.bin/xlint/lint1/scan.l b/usr.bin/xlint/lint1/scan.l
    index ea5a2c57bdc..05f4ed7984a 100644
    --- a/usr.bin/xlint/lint1/scan.l
    +++ b/usr.bin/xlint/lint1/scan.l
    @@ -319,7 +319,7 @@ allocsb(void)
     		if ((sb = malloc(sizeof (sbuf_t))) == NULL)
     			nomem();
     	}
    -	(void)memset(sb, 0, sizeof (sb));
    +	(void)memset(sb, 0, sizeof (*sb));
     	return (sb);
     }
     
    
    From 2faf8829c4556460f978c6aa44e6e7814cd951b2 Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Mon, 15 Mar 2010 17:52:55 +0000
    Subject: [PATCH 1592/2592] wrong name for this file...
    
    ---
     release/picobsd/floppy.tree/{sbin => dhclient-script} | 0
     1 file changed, 0 insertions(+), 0 deletions(-)
     rename release/picobsd/floppy.tree/{sbin => dhclient-script} (100%)
    
    diff --git a/release/picobsd/floppy.tree/sbin b/release/picobsd/floppy.tree/dhclient-script
    similarity index 100%
    rename from release/picobsd/floppy.tree/sbin
    rename to release/picobsd/floppy.tree/dhclient-script
    
    From 2ad0f3f2581905c6b2581f41d37665791286d58e Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Mon, 15 Mar 2010 17:54:01 +0000
    Subject: [PATCH 1593/2592] and wrong place too!
    
    ---
     release/picobsd/floppy.tree/{ => sbin}/dhclient-script | 0
     1 file changed, 0 insertions(+), 0 deletions(-)
     rename release/picobsd/floppy.tree/{ => sbin}/dhclient-script (100%)
    
    diff --git a/release/picobsd/floppy.tree/dhclient-script b/release/picobsd/floppy.tree/sbin/dhclient-script
    similarity index 100%
    rename from release/picobsd/floppy.tree/dhclient-script
    rename to release/picobsd/floppy.tree/sbin/dhclient-script
    
    From 256794862ef6393d9002036c7dc7e6aa95c581f7 Mon Sep 17 00:00:00 2001
    From: Jung-uk Kim 
    Date: Mon, 15 Mar 2010 18:22:19 +0000
    Subject: [PATCH 1594/2592] MFC:	r204235
    
    Fix FBIO_ADPINFO ioctl on amd64.
    ---
     sys/dev/fb/fb.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sys/dev/fb/fb.c b/sys/dev/fb/fb.c
    index 21871f69e78..64e48e9b05e 100644
    --- a/sys/dev/fb/fb.c
    +++ b/sys/dev/fb/fb.c
    @@ -653,7 +653,7 @@ fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
     		((video_adapter_info_t *)arg)->va_mem_base = adp->va_mem_base;
     		((video_adapter_info_t *)arg)->va_mem_size = adp->va_mem_size;
     		((video_adapter_info_t *)arg)->va_window
    -#ifdef __i386__
    +#if defined(__amd64__) || defined(__i386__)
     			= vtophys(adp->va_window);
     #else
     			= adp->va_window;
    @@ -665,8 +665,8 @@ fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
     		((video_adapter_info_t *)arg)->va_window_orig
     			= adp->va_window_orig;
     		((video_adapter_info_t *)arg)->va_unused0
    -#ifdef __i386__
    -			= (adp->va_buffer) ? vtophys(adp->va_buffer) : 0;
    +#if defined(__amd64__) || defined(__i386__)
    +			= adp->va_buffer != 0 ? vtophys(adp->va_buffer) : 0;
     #else
     			= adp->va_buffer;
     #endif
    
    From 2181f8f5be1f4d9163b133e3114f2d1ca765468a Mon Sep 17 00:00:00 2001
    From: Marius Strobl 
    Date: Mon, 15 Mar 2010 18:32:57 +0000
    Subject: [PATCH 1595/2592] MFC: r204974, r205002
    
    - The OPSZ macro actually only does the right thing for int32 and int64
      operands but not for double and extended double ones. Instead of trying
      to fix the macro just nuke it and unroll the loops in the correct way
      though as extended double operands turn out to be the only special case.
    - For FxTO{s,d,q} the source operand is int64 so rs2 has to be re-decoded
      after setting type accordingly as it's generally decoded using the low
      2 bits as the type, which are 0 for these three instructions.
    - Similarly, in case of F{s,d,q}TOx the target is int64 so rd has to be
      re-decoded using not only the operand mask appropriate for int64 but
      also the correct register number encoding.
    - Use const where appropriate.
    - Wrap long lines.
    
    Submitted by:	Peter Jeremy (partly)
    ---
     lib/libc/sparc64/fpu/fpu.c     | 48 ++++++++++++++--------------------
     lib/libc/sparc64/fpu/fpu_emu.h |  2 +-
     2 files changed, 21 insertions(+), 29 deletions(-)
    
    diff --git a/lib/libc/sparc64/fpu/fpu.c b/lib/libc/sparc64/fpu/fpu.c
    index 74f07ec280d..7c8a3a96739 100644
    --- a/lib/libc/sparc64/fpu/fpu.c
    +++ b/lib/libc/sparc64/fpu/fpu.c
    @@ -97,7 +97,7 @@ __FBSDID("$FreeBSD$");
     #define	X8(x) X4(x),X4(x)
     #define	X16(x) X8(x),X8(x)
     
    -static char cx_to_trapx[] = {
    +static const char cx_to_trapx[] = {
     	X1(FSR_NX),
     	X2(FSR_DZ),
     	X4(FSR_UF),
    @@ -113,7 +113,8 @@ int __fpe_debug = 0;
     #endif
     #endif	/* FPU_DEBUG */
     
    -static int __fpu_execute(struct utrapframe *, struct fpemu *, u_int32_t, u_long);
    +static int __fpu_execute(struct utrapframe *, struct fpemu *, u_int32_t,
    +    u_long);
     
     /*
      * Need to use an fpstate on the stack; we could switch, so we cannot safely
    @@ -169,7 +170,7 @@ __fpu_exception(struct utrapframe *uf)
     void
     __fpu_dumpfpn(struct fpn *fp)
     {
    -	static char *class[] = {
    +	static const char *const class[] = {
     		"SNAN", "QNAN", "ZERO", "NUM", "INF"
     	};
     
    @@ -181,15 +182,11 @@ __fpu_dumpfpn(struct fpn *fp)
     }
     #endif
     
    -static int opmask[] = {0, 0, 1, 3};
    +static const int opmask[] = {0, 0, 1, 3, 1};
     
     /* Decode 5 bit register field depending on the type. */
     #define	RN_DECODE(tp, rn) \
    -	((tp == FTYPE_DBL || tp == FTYPE_EXT ? INSFPdq_RN((rn)) : (rn)) & \
    -	    ~opmask[tp])
    -
    -/* Operand size in 32-bit registers. */
    -#define	OPSZ(tp)	((tp) == FTYPE_LNG ? 2 : (1 << (tp)))
    +	((tp) >= FTYPE_DBL ? INSFPdq_RN(rn) & ~opmask[tp] : (rn))
     
     /*
      * Helper for forming the below case statements. Build only the op3 and opf
    @@ -209,8 +206,6 @@ static void
     __fpu_mov(struct fpemu *fe, int type, int rd, int rs2, u_int32_t nand,
         u_int32_t xor)
     {
    -	u_int64_t tmp64;
    -	int i;
     
     	if (type == FTYPE_INT || type == FTYPE_SNG)
     		__fpu_setreg(rd, (__fpu_getreg(rs2) & ~nand) ^ xor);
    @@ -219,13 +214,10 @@ __fpu_mov(struct fpemu *fe, int type, int rd, int rs2, u_int32_t nand,
     		 * Need to use the double versions to be able to access
     		 * the upper 32 fp registers.
     		 */
    -		for (i = 0; i < OPSZ(type); i += 2, rd += 2, rs2 += 2) {
    -			tmp64 = __fpu_getreg64(rs2);
    -			if (i == 0)
    -				tmp64 = (tmp64 & ~((u_int64_t)nand << 32)) ^
    -				    ((u_int64_t)xor << 32);
    -			__fpu_setreg64(rd, tmp64);
    -		}
    +		__fpu_setreg64(rd, (__fpu_getreg64(rs2) &
    +		    ~((u_int64_t)nand << 32)) ^ ((u_int64_t)xor << 32));
    +		if (type == FTYPE_EXT)
    +			__fpu_setreg64(rd + 2, __fpu_getreg64(rs2 + 2));
     	}
     }
     
    @@ -271,17 +263,17 @@ __fpu_cmpck(struct fpemu *fe)
      * multiply two integers this way.
      */
     static int
    -__fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long tstate)
    +__fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn,
    +    u_long tstate)
     {
     	struct fpn *fp;
     	int opf, rs1, rs2, rd, type, mask, cx, cond;
     	u_long reg, fsr;
     	u_int space[4];
    -	int i;
     
     	/*
     	 * `Decode' and execute instruction.  Start with no exceptions.
    -	 * The type of any opf opcode is in the bottom two bits, so we
    +	 * The type of almost any OPF opcode is in the bottom two bits, so we
     	 * squish them out here.
     	 */
     	opf = insn & (IF_MASK(IF_F3_OP3_SHIFT, IF_F3_OP3_BITS) |
    @@ -359,7 +351,7 @@ __fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long ts
     		__fpu_explode(fe, &fe->fe_f2, type, rs2);
     		__fpu_compare(fe, 1, IF_F3_CC(insn));
     		return (__fpu_cmpck(fe));
    -	case FOP(INS2_FPop1, INSFP1_FMOV):	/* these should all be pretty obvious */
    +	case FOP(INS2_FPop1, INSFP1_FMOV):
     		__fpu_mov(fe, type, rd, rs2, 0, 0);
     		return (0);
     	case FOP(INS2_FPop1, INSFP1_FNEG):
    @@ -410,6 +402,7 @@ __fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long ts
     	case FOP(INS2_FPop1, INSFP1_FxTOd):
     	case FOP(INS2_FPop1, INSFP1_FxTOq):
     		type = FTYPE_LNG;
    +		rs2 = RN_DECODE(type, IF_F3_RS2(insn));
     		__fpu_explode(fe, fp = &fe->fe_f1, type, rs2);
     		/* sneaky; depends on instruction encoding */
     		type = (IF_F3_OPF(insn) >> 2) & 3;
    @@ -418,8 +411,7 @@ __fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long ts
     	case FOP(INS2_FPop1, INSFP1_FTOx):
     		__fpu_explode(fe, fp = &fe->fe_f1, type, rs2);
     		type = FTYPE_LNG;
    -		mask = 1;	/* needs 2 registers */
    -		rd = IF_F3_RD(insn) & ~mask;
    +		rd = RN_DECODE(type, IF_F3_RD(insn));
     		break;
     	case FOP(INS2_FPop1, INSFP1_FTOs):
     	case FOP(INS2_FPop1, INSFP1_FTOd):
    @@ -457,10 +449,10 @@ __fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long ts
     	if (type == FTYPE_INT || type == FTYPE_SNG)
     		__fpu_setreg(rd, space[0]);
     	else {
    -		for (i = 0; i < OPSZ(type); i += 2) {
    -			__fpu_setreg64(rd + i, ((u_int64_t)space[i] << 32) |
    -			    space[i + 1]);
    -		}
    +		__fpu_setreg64(rd, ((u_int64_t)space[0] << 32) | space[1]);
    +		if (type == FTYPE_EXT)
    +			__fpu_setreg64(rd + 2,
    +			    ((u_int64_t)space[2] << 32) | space[3]);
     	}
     	return (0);	/* success */
     }
    diff --git a/lib/libc/sparc64/fpu/fpu_emu.h b/lib/libc/sparc64/fpu/fpu_emu.h
    index de156e2dee9..0d1d16dd1e5 100644
    --- a/lib/libc/sparc64/fpu/fpu_emu.h
    +++ b/lib/libc/sparc64/fpu/fpu_emu.h
    @@ -140,7 +140,7 @@ struct fpn {
     #define	FTYPE_SNG	INSFP_s
     #define	FTYPE_DBL	INSFP_d
     #define	FTYPE_EXT	INSFP_q
    -#define	FTYPE_LNG	-1
    +#define	FTYPE_LNG	4
     
     /*
      * Emulator state.
    
    From a130bd42f5780cfc77323f3a7563ca33863f62ce Mon Sep 17 00:00:00 2001
    From: Marius Strobl 
    Date: Mon, 15 Mar 2010 19:04:44 +0000
    Subject: [PATCH 1596/2592] MFC: r204144
    
    Add support for BCM54K2 found in combination with Apple K2 GMAC.
    
    Submitted by:   Andreas Tobler
    Obtained from:  OpenBSD
    ---
     sys/dev/mii/brgphy.c | 26 ++++++++++++++++++++++++++
     sys/dev/mii/miidevs  |  1 +
     2 files changed, 27 insertions(+)
    
    diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
    index 1f7d2ebbae0..ddbec6761ba 100644
    --- a/sys/dev/mii/brgphy.c
    +++ b/sys/dev/mii/brgphy.c
    @@ -104,6 +104,7 @@ static void	brgphy_reset(struct mii_softc *);
     static void	brgphy_enable_loopback(struct mii_softc *);
     static void	bcm5401_load_dspcode(struct mii_softc *);
     static void	bcm5411_load_dspcode(struct mii_softc *);
    +static void	bcm54k2_load_dspcode(struct mii_softc *);
     static void	brgphy_fixup_5704_a0_bug(struct mii_softc *);
     static void	brgphy_fixup_adc_bug(struct mii_softc *);
     static void	brgphy_fixup_adjust_trim(struct mii_softc *);
    @@ -117,6 +118,7 @@ static const struct mii_phydesc brgphys[] = {
     	MII_PHY_DESC(xxBROADCOM, BCM5400),
     	MII_PHY_DESC(xxBROADCOM, BCM5401),
     	MII_PHY_DESC(xxBROADCOM, BCM5411),
    +	MII_PHY_DESC(xxBROADCOM, BCM54K2),
     	MII_PHY_DESC(xxBROADCOM, BCM5701),
     	MII_PHY_DESC(xxBROADCOM, BCM5703),
     	MII_PHY_DESC(xxBROADCOM, BCM5704),
    @@ -415,6 +417,9 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
     			case MII_MODEL_xxBROADCOM_BCM5411:
     				bcm5411_load_dspcode(sc);
     				break;
    +			case MII_MODEL_xxBROADCOM_BCM54K2:
    +				bcm54k2_load_dspcode(sc);
    +				break;
     			}
     			break;
     		case MII_OUI_xxBROADCOM_ALT1:
    @@ -730,6 +735,24 @@ bcm5411_load_dspcode(struct mii_softc *sc)
     		PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
     }
     
    +void
    +bcm54k2_load_dspcode(struct mii_softc *sc)
    +{
    +	static const struct {
    +		int		reg;
    +		uint16_t	val;
    +	} dspcode[] = {
    +		{ 4,				0x01e1 },
    +		{ 9,				0x0300 },
    +		{ 0,				0 },
    +	};
    +	int i;
    +
    +	for (i = 0; dspcode[i].reg != 0; i++)
    +		PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
    +
    +}
    +
     static void
     brgphy_fixup_5704_a0_bug(struct mii_softc *sc)
     {
    @@ -932,6 +955,9 @@ brgphy_reset(struct mii_softc *sc)
     		case MII_MODEL_xxBROADCOM_BCM5411:
     			bcm5411_load_dspcode(sc);
     			break;
    +		case MII_MODEL_xxBROADCOM_BCM54K2:
    +			bcm54k2_load_dspcode(sc);
    +			break;
     		}
     		break;
     	case MII_OUI_xxBROADCOM_ALT1:
    diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
    index 325d733c3f5..06e07be53ea 100644
    --- a/sys/dev/mii/miidevs
    +++ b/sys/dev/mii/miidevs
    @@ -145,6 +145,7 @@ model xxBROADCOM BCM5703	0x0016 BCM5703 10/100/1000baseTX PHY
     model xxBROADCOM BCM5704	0x0019 BCM5704 10/100/1000baseTX PHY
     model xxBROADCOM BCM5705	0x001a BCM5705 10/100/1000baseTX PHY
     model xxBROADCOM BCM5750	0x0018 BCM5750 10/100/1000baseTX PHY
    +model xxBROADCOM BCM54K2	0x002e BCM54K2 10/100/1000baseTX PHY
     model xxBROADCOM BCM5714	0x0034 BCM5714 10/100/1000baseTX PHY
     model xxBROADCOM BCM5780	0x0035 BCM5780 10/100/1000baseTX PHY
     model xxBROADCOM BCM5708C	0x0036 BCM5708C 10/100/1000baseTX PHY
    
    From 8bf5ec104798ebef075021da4a85c65376fdf835 Mon Sep 17 00:00:00 2001
    From: Marius Strobl 
    Date: Mon, 15 Mar 2010 19:13:36 +0000
    Subject: [PATCH 1597/2592] MFC: r204222
    
    According to the Linux sungem driver, in case of Apple (K2) GMACs
    GEM_MIF_CONFIG_MDI0 cannot be trusted when the firmware has powered
    down the chip so the internal transceiver has to be hardcoded. This
    is also in line with the AppleGMACEthernet driver, which just doesn't
    distinguish between internal/external transceiver and MDIO/MDI1
    respectively in the first place. Tested by: Andreas Tobler
    ---
     sys/dev/gem/if_gem.c | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/gem/if_gem.c b/sys/dev/gem/if_gem.c
    index 945638395b2..7cba6e7e133 100644
    --- a/sys/dev/gem/if_gem.c
    +++ b/sys/dev/gem/if_gem.c
    @@ -297,8 +297,11 @@ gem_attach(struct gem_softc *sc)
     
     	/*
     	 * Fall back on an internal PHY if no external PHY was found.
    +	 * Note that with Apple (K2) GMACs GEM_MIF_CONFIG_MDI0 can't be
    +	 * trusted when the firmware has powered down the chip.
     	 */
    -	if (error != 0 && (v & GEM_MIF_CONFIG_MDI0) != 0) {
    +	if (error != 0 &&
    +	    ((v & GEM_MIF_CONFIG_MDI0) != 0 || GEM_IS_APPLE(sc))) {
     		v &= ~GEM_MIF_CONFIG_PHY_SEL;
     		GEM_BANK1_WRITE_4(sc, GEM_MIF_CONFIG, v);
     		switch (sc->sc_variant) {
    
    From 7bfaecdca3b15c900112399e5b55cbc176766ff0 Mon Sep 17 00:00:00 2001
    From: Rafal Jaworowski 
    Date: Mon, 15 Mar 2010 19:51:24 +0000
    Subject: [PATCH 1598/2592] MFC r204764
    
    Provide correct TCLK value for Kirkwood A1 silicon revision.
    
    While there improve SOC ID output accordingly.
    
    Obtained from:	Semihalf
    ---
     sys/arm/mv/common.c            | 2 ++
     sys/arm/mv/kirkwood/kirkwood.c | 4 ++--
     2 files changed, 4 insertions(+), 2 deletions(-)
    
    diff --git a/sys/arm/mv/common.c b/sys/arm/mv/common.c
    index d31e0819762..a14225949c2 100644
    --- a/sys/arm/mv/common.c
    +++ b/sys/arm/mv/common.c
    @@ -261,6 +261,8 @@ soc_identify(void)
     			rev = "Z0";
     		else if (r == 2)
     			rev = "A0";
    +		else if (r == 3)
    +			rev = "A1";
     		break;
     	case MV_DEV_MV78100_Z0:
     		dev = "Marvell MV78100 Z0";
    diff --git a/sys/arm/mv/kirkwood/kirkwood.c b/sys/arm/mv/kirkwood/kirkwood.c
    index 1be6d4580f5..cc60afe2653 100644
    --- a/sys/arm/mv/kirkwood/kirkwood.c
    +++ b/sys/arm/mv/kirkwood/kirkwood.c
    @@ -176,11 +176,11 @@ get_tclk(void)
     	/*
     	 * On Kirkwood TCLK is not configurable and depends on silicon
     	 * revision:
    -	 * - A0 has TCLK hardcoded to 200 MHz.
    +	 * - A0 and A1 have TCLK hardcoded to 200 MHz.
     	 * - Z0 and others have TCLK hardcoded to 166 MHz.
     	 */
     	soc_id(&dev, &rev);
    -	if (dev == MV_DEV_88F6281 && rev == 2)
    +	if (dev == MV_DEV_88F6281 && (rev == 2 || rev == 3))
     		return (TCLK_200MHZ);
     
     	return (TCLK_166MHZ);
    
    From 9f36044770047b23d874692d1c0f51e3446698f3 Mon Sep 17 00:00:00 2001
    From: Rafal Jaworowski 
    Date: Mon, 15 Mar 2010 19:59:16 +0000
    Subject: [PATCH 1599/2592] MFC r205028
    
     Fix ARM cache handling yet more.
    
     1) vm_machdep.c: remove the dangling allocations so they do not
        un-necessarily turn off the cache upon consecutive access.
    
     2) busdma_machdep.c: remove the same amount than shadow mapped.
    
    Reported by:	Maks Verver
    Submitted by:	Mark Tinguely
    Reviewed by:	Grzegorz Bernacki
    ---
     sys/arm/arm/busdma_machdep.c | 3 ++-
     sys/arm/arm/vm_machdep.c     | 8 +++++++-
     2 files changed, 9 insertions(+), 2 deletions(-)
    
    diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
    index cf4873f5094..e8425d96e2c 100644
    --- a/sys/arm/arm/busdma_machdep.c
    +++ b/sys/arm/arm/busdma_machdep.c
    @@ -649,7 +649,8 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
     		KASSERT(map->allocbuffer == vaddr,
     		    ("Trying to freeing the wrong DMA buffer"));
     		vaddr = map->origbuffer;
    -		arm_unmap_nocache(map->allocbuffer, dmat->maxsize);
    +		arm_unmap_nocache(map->allocbuffer,
    +		    dmat->maxsize + ((vm_offset_t)vaddr & PAGE_MASK));
     	}
             if (dmat->maxsize <= PAGE_SIZE &&
     	   dmat->alignment < dmat->maxsize &&
    diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
    index 95b9ca8fc9a..9b530ab0362 100644
    --- a/sys/arm/arm/vm_machdep.c
    +++ b/sys/arm/arm/vm_machdep.c
    @@ -171,6 +171,9 @@ sf_buf_free(struct sf_buf *sf)
     	 if (sf->ref_count == 0) {
     		 TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
     		 nsfbufsused--;
    +		 pmap_kremove(sf->kva);
    +		 sf->m = NULL;
    +		 LIST_REMOVE(sf, list_entry);
     		 if (sf_buf_alloc_want > 0)
     			 wakeup_one(&sf_buf_freelist);
     	 }
    @@ -502,9 +505,12 @@ arm_unmap_nocache(void *addr, vm_size_t size)
     
     	size = round_page(size);
     	i = (raddr - arm_nocache_startaddr) / (PAGE_SIZE);
    -	for (; size > 0; size -= PAGE_SIZE, i++)
    +	for (; size > 0; size -= PAGE_SIZE, i++) {
     		arm_nocache_allocated[i / BITS_PER_INT] &= ~(1 << (i % 
     		    BITS_PER_INT));
    +		pmap_kremove(raddr);
    +		raddr += PAGE_SIZE;
    +	}
     }
     
     #ifdef ARM_USE_SMALL_ALLOC
    
    From 01bd5afb0f95473942da4a513c3d19dcedb79a10 Mon Sep 17 00:00:00 2001
    From: Joerg Wunsch 
    Date: Tue, 16 Mar 2010 05:13:20 +0000
    Subject: [PATCH 1600/2592] r205170: then -> than
    
    ---
     usr.sbin/powerd/powerd.8 | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/usr.sbin/powerd/powerd.8 b/usr.sbin/powerd/powerd.8
    index 580886268e0..2d6acffd22a 100644
    --- a/usr.sbin/powerd/powerd.8
    +++ b/usr.sbin/powerd/powerd.8
    @@ -58,7 +58,7 @@ the system appears idle and increasing it when the system is busy.
     It offers a good balance between a small performance loss for greatly
     increased power savings.
     Hiadaptive mode is like adaptive mode, but tuned for systems where
    -performance and interactivity are more important then power consumption.
    +performance and interactivity are more important than power consumption.
     It increases frequency faster, reduces the frequency less aggressively and
     will maintain full frequency for longer.
     The default mode is adaptive for battery power and hiadaptive for the rest.
    
    From 6b5b49ce7f95e28c9cbe06fc0607c0d169b782a2 Mon Sep 17 00:00:00 2001
    From: Doug Barton 
    Date: Wed, 17 Mar 2010 07:26:00 +0000
    Subject: [PATCH 1601/2592] MFC r205145:
    
    Make it more clear in the docs that -a is not compatible with -iFU,
    and enforce this in the code. Apparently a lot of users mistakenly
    combine -a with these flags and are then mystified that no changes
    were made.
    
    While I'm here, fix a trailing space in mergemaster.8
    ---
     usr.sbin/mergemaster/mergemaster.8  | 15 +++++++++------
     usr.sbin/mergemaster/mergemaster.sh | 14 +++++++++++++-
     2 files changed, 22 insertions(+), 7 deletions(-)
    
    diff --git a/usr.sbin/mergemaster/mergemaster.8 b/usr.sbin/mergemaster/mergemaster.8
    index c9217b3f4ca..a8bafb7c667 100644
    --- a/usr.sbin/mergemaster/mergemaster.8
    +++ b/usr.sbin/mergemaster/mergemaster.8
    @@ -24,7 +24,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd January 7, 2010
    +.Dd March 13, 2010
     .Dt MERGEMASTER 8
     .Os
     .Sh NAME
    @@ -32,7 +32,8 @@
     .Nd merge configuration files, et al during an upgrade
     .Sh SYNOPSIS
     .Nm
    -.Op Fl scrvahipFCPU
    +.Op Fl scrvhpCP
    +.Op Fl a|iFU
     .Op Fl m Ar /path/to/sources
     .Op Fl t Ar /path/to/temp/root
     .Op Fl d
    @@ -168,7 +169,7 @@ and therefore can override both files.
     When the comparison is done if there are any files remaining
     in the temproot directory they will be listed, and if the
     .Fl a
    -option is not in use the user will be given the option of 
    +option is not in use the user will be given the option of
     deleting the temproot directory.
     If there are no files remaining in the temproot directory
     it will be deleted.
    @@ -206,9 +207,11 @@ If the
     directory exists, it creates a new one in a previously
     non-existent directory.
     This option unsets the verbose flag,
    -but other than
    -.Fl U
    -it is compatible with all other options.
    +and is not compatible with
    +.Fl i ,
    +.Fl F ,
    +or
    +.Fl U .
     Setting
     .Fl a
     makes
    diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh
    index d21d80bcfd1..43126ae84f4 100755
    --- a/usr.sbin/mergemaster/mergemaster.sh
    +++ b/usr.sbin/mergemaster/mergemaster.sh
    @@ -15,7 +15,7 @@ PATH=/bin:/usr/bin:/usr/sbin
     display_usage () {
       VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
       echo "mergemaster version ${VERSION_NUMBER}"
    -  echo 'Usage: mergemaster [-scrvahipFCPU]'
    +  echo 'Usage: mergemaster [-scrvhpCP] [-a|[-iFU]]'
       echo '    [-m /path] [-t /path] [-d] [-u N] [-w N] [-A arch] [-D /path]'
       echo "Options:"
       echo "  -s  Strict comparison (diff every pair of files)"
    @@ -337,6 +337,18 @@ while getopts ":ascrvhipCPm:t:du:w:D:A:FU" COMMAND_LINE_ARGUMENT ; do
       esac
     done
     
    +if [ -n "$AUTO_RUN" ]; then
    +  if [ -n "$FREEBSD_ID" -o -n "$AUTO_UPGRADE" -o -n "$AUTO_INSTALL" ]; then
    +    echo ''
    +    echo "*** You have included the -a option along with one or more options"
    +    echo '    that indicate that you wish mergemaster to actually make updates'
    +    echo '    (-F, -U, or -i), however these options are not compatible.'
    +    echo '    Please read mergemaster(8) for more information.'
    +    echo ''
    +    exit 1
    +  fi
    +fi
    +
     # Assign the location of the mtree database
     #
     MTREEDB=${MTREEDB:-${DESTDIR}/var/db}
    
    From 84d7d98fa107740dcf87424c2104b412210e8dc8 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 17 Mar 2010 09:52:26 +0000
    Subject: [PATCH 1602/2592] MFC r205148: Make it compile on LP64 arches.
    
    ---
     tools/regression/posixsem/posixsem.c | 12 ++++++++----
     1 file changed, 8 insertions(+), 4 deletions(-)
    
    diff --git a/tools/regression/posixsem/posixsem.c b/tools/regression/posixsem/posixsem.c
    index 465d6e7f26d..6401b5cb46b 100644
    --- a/tools/regression/posixsem/posixsem.c
    +++ b/tools/regression/posixsem/posixsem.c
    @@ -1239,7 +1239,8 @@ exhaust_unnamed_sems(void)
     		return;
     	}
     
    -	if (child_worker(exhaust_unnamed_child, (void *)nsems_max, &stat))
    +	if (child_worker(exhaust_unnamed_child, (void *)(uintptr_t)nsems_max,
    +	    &stat))
     		return;
     	errno = CSTAT_ERROR(stat);
     	switch (CSTAT_CLASS(stat)) {
    @@ -1293,7 +1294,8 @@ exhaust_named_sems(void)
     		return;
     	}
     
    -	if (child_worker(exhaust_named_child, (void *)nsems_max, &stat) < 0)
    +	if (child_worker(exhaust_named_child, (void *)(uintptr_t)nsems_max,
    +	    &stat) < 0)
     		return;
     	errno = CSTAT_ERROR(stat);
     	switch (CSTAT_CLASS(stat)) {
    @@ -1351,7 +1353,8 @@ fdlimit_unnamed_sems(void)
     	int nsems_max, stat;
     
     	nsems_max = 10;
    -	if (child_worker(fdlimit_unnamed_child, (void *)nsems_max, &stat))
    +	if (child_worker(fdlimit_unnamed_child, (void *)(uintptr_t)nsems_max,
    +	    &stat))
     		return;
     	errno = CSTAT_ERROR(stat);
     	switch (CSTAT_CLASS(stat)) {
    @@ -1395,7 +1398,8 @@ fdlimit_named_sems(void)
     	int i, nsems_max, stat;
     
     	nsems_max = 10;
    -	if (child_worker(fdlimit_named_child, (void *)nsems_max, &stat) < 0)
    +	if (child_worker(fdlimit_named_child, (void *)(uintptr_t)nsems_max,
    +	    &stat) < 0)
     		return;
     	errno = CSTAT_ERROR(stat);
     	switch (CSTAT_CLASS(stat)) {
    
    From 27dfb536f20f77bf1abea77b092345b3e3a46e69 Mon Sep 17 00:00:00 2001
    From: Gavin Atkinson 
    Date: Wed, 17 Mar 2010 20:16:28 +0000
    Subject: [PATCH 1603/2592] Merge r203865 from head:
    
      The -newerXB option was being interpreted the same as the -newerXm option
      as a check for F_TIME2_B was missing.  Fix this.
    
    PR:		bin/138245
    Submitted by:	"David E. Cross"  
    ---
     usr.bin/find/function.c | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
    index c11d24f8bab..5a4b7d51e6e 100644
    --- a/usr.bin/find/function.c
    +++ b/usr.bin/find/function.c
    @@ -1165,6 +1165,8 @@ c_newer(OPTION *option, char ***argvp)
     			new->t_data = sb.st_ctime;
     		else if (option->flags & F_TIME2_A)
     			new->t_data = sb.st_atime;
    +		else if (option->flags & F_TIME2_B)
    +			new->t_data = sb.st_birthtime;
     		else
     			new->t_data = sb.st_mtime;
     	}
    
    From 40df979212ce3d31e39bc11ec3232c10febfe392 Mon Sep 17 00:00:00 2001
    From: Gavin Atkinson 
    Date: Wed, 17 Mar 2010 20:27:35 +0000
    Subject: [PATCH 1604/2592] Merge r203835 from head:
    
      When growing a UFS1 filesystem, we need to initialise all inodes in any new
      cylinder groups that are created.  When the filesystem is first created,
      newfs always initialises the first two blocks of inodes, and then in the
      UFS1 case will also initialise the remaining inode blocks.  The changes in
      growfs.c 1.23 broke the initialisation of all inodes, seemingly based on
      this implementation detail in newfs(8).  The result was that instead of
      initialising all inodes, we would actually end up initialising all but the
      first two blocks of inodes.  If the filesystem was grown into empty
      (all-zeros) space then the resulting filesystem was fine, however when
      grown onto non-zeroed space the filesystem produced would appear to have
      massive corruption on the first fsck after growing.
      A test case for this problem can be found in the PR audit trail.
    
      Fix this by once again initialising all inodes in the UFS1 case.
    
    PR:		bin/115174
    Submitted by:	"Nate Eldredge"  
    Reviewed by:	mjacob
    ---
     sbin/growfs/growfs.c | 6 ++----
     1 file changed, 2 insertions(+), 4 deletions(-)
    
    diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c
    index bf803acd8d9..ef055f18a77 100644
    --- a/sbin/growfs/growfs.c
    +++ b/sbin/growfs/growfs.c
    @@ -445,13 +445,11 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag)
     			acg.cg_cs.cs_nifree--;
     		}
     	/*
    -	 * XXX Newfs writes out two blocks of initialized inodes
    -	 *     unconditionally.  Should we check here to make sure that they
    -	 *     were actually written?
    +	 * For the old file system, we have to initialize all the inodes.
     	 */
     	if (sblock.fs_magic == FS_UFS1_MAGIC) {
     		bzero(iobuf, sblock.fs_bsize);
    -		for (i = 2 * sblock.fs_frag; i < sblock.fs_ipg / INOPF(&sblock);
    +		for (i = 0; i < sblock.fs_ipg / INOPF(&sblock);
     		     i += sblock.fs_frag) {
     			dp1 = (struct ufs1_dinode *)iobuf;
     #ifdef FSIRAND
    
    From 0761ef3362e645088ab019e524430b4b2ec3e33b Mon Sep 17 00:00:00 2001
    From: Gavin Atkinson 
    Date: Wed, 17 Mar 2010 20:39:21 +0000
    Subject: [PATCH 1605/2592] Merge r203622 from head:
    
      Add support for a few more Sony-specific ACPI features (default display
      brightness, wired LAN power and bass gain), and update the description of
      one previously unknown feature (display contrast).  While here, expand on
      a comment and remove two defines left over from an old version of the code.
    
      Also update man page to document the above changes, and correct grammar.
    
    PR:		kern/127581
    ---
     share/man/man4/acpi_sony.4       | 13 +++++++++++--
     sys/dev/acpi_support/acpi_sony.c | 20 +++++++++++++++-----
     2 files changed, 26 insertions(+), 7 deletions(-)
    
    diff --git a/share/man/man4/acpi_sony.4 b/share/man/man4/acpi_sony.4
    index 52a7fbe2fd9..3a0607009bd 100644
    --- a/share/man/man4/acpi_sony.4
    +++ b/share/man/man4/acpi_sony.4
    @@ -24,7 +24,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd September 14, 2005
    +.Dd February 7, 2010
     .Dt ACPI_SONY 4 i386
     .Os
     .Sh NAME
    @@ -48,15 +48,24 @@ acpi_sony_load="YES"
     The
     .Nm
     driver provides support for the notebook controller in Sony laptops.
    +Note that not all features will work on all laptop models.
     .Sh SYSCTLS
    -The following sysctl is currently implemented:
    +The following sysctl nodes are currently implemented:
     .Bl -tag -width indent
     .It Va dev.acpi_sony.0.brightness
     Current brightness level of the display.
    +.It Va dev.acpi_sony.0.brightness_default
    +Default brightness level of the display (survives reboot).
    +.It Va dev.acpi_sony.0.contrast
    +Current contrast level of the display.
    +.It Va dev.acpi_sony.0.bass_gain
    +Enable or disable the Bass Gain feature.
     .It Va dev.acpi_sony.0.cdp
     Turns the CD power on or off.
     .It Va dev.acpi_sony.0.azp
     Turns the audio power on or off.
    +.It Va dev.acpi_sony.0.lnp
    +Turns the wired network interface power on or off.
     .El
     .Sh SEE ALSO
     .Xr acpi 4 ,
    diff --git a/sys/dev/acpi_support/acpi_sony.c b/sys/dev/acpi_support/acpi_sony.c
    index 905461d1e12..2a0d40e5266 100644
    --- a/sys/dev/acpi_support/acpi_sony.c
    +++ b/sys/dev/acpi_support/acpi_sony.c
    @@ -42,14 +42,21 @@ __FBSDID("$FreeBSD$");
     #define _COMPONENT	ACPI_OEM
     ACPI_MODULE_NAME("Sony")
     
    -#define ACPI_SONY_GET_BRIGHTNESS "GBRT"
    -#define ACPI_SONY_SET_BRIGHTNESS "SBRT"
     #define ACPI_SONY_GET_PID "GPID"
     
     /*
      * SNY5001
    + *   This is the ACPI handle for the "Sony Notebook Control" driver under
    + *   Windows.
    + *   It provides several methods within the ACPI namespace, including:
      *  [GS]BRT [GS]PBR [GS]CTR [GS]PCR [GS]CMI [CDPW GCDP]? GWDP PWAK PWRN 
      *
    + * SNY6001
    + *   This is the ACPI handle for the "Sony Programmable I/O" driver under
    + *   Windows.
    + *   It is not yet supported by this driver, but provides control over the
    + *   power to the bluetooth, built-in camera and HSDPA modem devices in some
    + *   laptops, and also allows some control of the fan speed.
      */
     
     struct acpi_sony_softc {
    @@ -63,14 +70,17 @@ static struct acpi_sony_name_list
     	char *comment;
     } acpi_sony_oids[] = {
     	{ "brightness", "GBRT", "SBRT", "Display Brightness"},
    -	{ "ctr", "GCTR", "SCTR", "??"},
    +	{ "brightness_default", "GPBR", "SPBR", "Default Display Brightness"},
    +	{ "contrast", "GCTR", "SCTR", "Display Contrast"},
    +	{ "bass_gain", "GMGB", "SMGB", "Multimedia Bass Gain"},
     	{ "pcr", "GPCR", "SPCR", "???"},
     #if 0
    -	{ "cmi", "GCMI", "SCMI", "????"},
    +	{ "cmi", "GCMI", "SCMI", "???"},
     #endif
    -	{ "wdp", "GWDP", NULL, "?????"},
    +	{ "wdp", "GWDP", NULL, "???"},
     	{ "cdp", "GCDP", "CDPW", "CD Power"},  /*shares [\GL03]&0x8 flag*/
     	{ "azp", "GAZP", "AZPW", "Audio Power"}, 
    +	{ "lnp", "GLNP", "LNPW", "LAN Power"},
     	{ NULL, NULL, NULL }
     };
     
    
    From 7088545a405775a01fe77b4f46fd01dcb05bbf78 Mon Sep 17 00:00:00 2001
    From: Rafal Jaworowski 
    Date: Thu, 18 Mar 2010 11:53:32 +0000
    Subject: [PATCH 1606/2592] MFC r205027
    
    Let detailed info about CPU features print on Marvell Sheeva CPU as well.
    
    Provide missing entry in the cpu_classes[].
    
    Reported by:	Maks Verver
    ---
     sys/arm/arm/identcpu.c | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sys/arm/arm/identcpu.c b/sys/arm/arm/identcpu.c
    index df67a8a022a..2940325b8e1 100644
    --- a/sys/arm/arm/identcpu.c
    +++ b/sys/arm/arm/identcpu.c
    @@ -343,6 +343,7 @@ const struct cpu_classtab cpu_classes[] = {
     	{ "SA-1",	"CPU_SA110" },		/* CPU_CLASS_SA1 */
     	{ "XScale",	"CPU_XSCALE_..." },	/* CPU_CLASS_XSCALE */
     	{ "ARM11J",	"CPU_ARM11" },		/* CPU_CLASS_ARM11J */
    +	{ "Marvell",	"CPU_MARVELL" },	/* CPU_CLASS_MARVELL */
     };
     
     /*
    @@ -418,6 +419,7 @@ identify_arm_cpu(void)
     	case CPU_CLASS_SA1:
     	case CPU_CLASS_XSCALE:
     	case CPU_CLASS_ARM11J:
    +	case CPU_CLASS_MARVELL:
     		if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0)
     			printf(" DC disabled");
     		else
    
    From 29f2c008fd146c26e0bfe5c5f9d11e26ec44974b Mon Sep 17 00:00:00 2001
    From: Max Laier 
    Date: Thu, 18 Mar 2010 17:00:44 +0000
    Subject: [PATCH 1607/2592] MFC r203834 and r205197: Make ALTQ work for drbr
     consumers.
    
    ---
     sys/dev/cxgb/cxgb_sge.c |  4 +++-
     sys/dev/e1000/if_em.c   |  2 +-
     sys/dev/e1000/if_igb.c  |  2 +-
     sys/dev/ixgbe/ixgbe.c   |  2 +-
     sys/dev/mxge/if_mxge.c  |  2 +-
     sys/net/if_var.h        | 36 +++++++++++++++++++++++-------------
     6 files changed, 30 insertions(+), 18 deletions(-)
    
    diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c
    index 88478b261a3..27a7c899209 100644
    --- a/sys/dev/cxgb/cxgb_sge.c
    +++ b/sys/dev/cxgb/cxgb_sge.c
    @@ -228,6 +228,8 @@ static uint8_t flit_desc_map[] = {
     #define	TXQ_LOCK(qs)		mtx_lock(&(qs)->lock)	
     #define	TXQ_UNLOCK(qs)		mtx_unlock(&(qs)->lock)	
     #define	TXQ_RING_EMPTY(qs)	drbr_empty((qs)->port->ifp, (qs)->txq[TXQ_ETH].txq_mr)
    +#define	TXQ_RING_NEEDS_ENQUEUE(qs)					\
    +	drbr_needs_enqueue((qs)->port->ifp, (qs)->txq[TXQ_ETH].txq_mr)
     #define	TXQ_RING_FLUSH(qs)	drbr_flush((qs)->port->ifp, (qs)->txq[TXQ_ETH].txq_mr)
     #define	TXQ_RING_DEQUEUE_COND(qs, func, arg)				\
     	drbr_dequeue_cond((qs)->port->ifp, (qs)->txq[TXQ_ETH].txq_mr, func, arg)
    @@ -1712,7 +1714,7 @@ cxgb_transmit_locked(struct ifnet *ifp, struct sge_qset *qs, struct mbuf *m)
     	 * - there is space in hardware transmit queue 
     	 */
     	if (check_pkt_coalesce(qs) == 0 &&
    -	    TXQ_RING_EMPTY(qs) && avail > 4) {
    +	    !TXQ_RING_NEEDS_ENQUEUE(qs) && avail > 4) {
     		if (t3_encap(qs, &m)) {
     			if (m != NULL &&
     			    (error = drbr_enqueue(ifp, br, m)) != 0) 
    diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
    index eec23d0c5b7..96d0788c377 100644
    --- a/sys/dev/e1000/if_em.c
    +++ b/sys/dev/e1000/if_em.c
    @@ -1032,7 +1032,7 @@ em_mq_start_locked(struct ifnet *ifp, struct mbuf *m)
     	    || (!adapter->link_active)) {
     		error = drbr_enqueue(ifp, adapter->br, m);
     		return (error);
    -	} else if (drbr_empty(ifp, adapter->br) &&
    +	} else if (!drbr_needs_enqueue(ifp, adapter->br) &&
     	    (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) {
     		if ((error = em_xmit(adapter, &m)) != 0) {
     			if (m != NULL)
    diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
    index 61743dfdc0b..8b3290a3f77 100644
    --- a/sys/dev/e1000/if_igb.c
    +++ b/sys/dev/e1000/if_igb.c
    @@ -853,7 +853,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
     		goto process;
     
     	/* If nothing queued go right to xmit */
    -	if (drbr_empty(ifp, txr->br)) {
    +	if (!drbr_needs_enqueue(ifp, txr->br)) {
     		if ((err = igb_xmit(txr, &m)) != 0) {
     			if (m != NULL)
     				err = drbr_enqueue(ifp, txr->br, m);
    diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c
    index 5284134ead2..b9fdab516de 100644
    --- a/sys/dev/ixgbe/ixgbe.c
    +++ b/sys/dev/ixgbe/ixgbe.c
    @@ -768,7 +768,7 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
     		goto process;
     
     	/* If nothing queued go right to xmit */
    -	if (drbr_empty(ifp, txr->br)) {
    +	if (!drbr_needs_enqueue(ifp, txr->br)) {
     		if (ixgbe_xmit(txr, &m)) {
     			if (m && (err = drbr_enqueue(ifp, txr->br, m)) != 0)
                                     return (err);
    diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
    index 19647b29a6f..a9046d0131e 100644
    --- a/sys/dev/mxge/if_mxge.c
    +++ b/sys/dev/mxge/if_mxge.c
    @@ -2249,7 +2249,7 @@ mxge_transmit_locked(struct mxge_slice_state *ss, struct mbuf *m)
     		return (err);
     	}
     
    -	if (drbr_empty(ifp, tx->br) &&
    +	if (!drbr_needs_enqueue(ifp, tx->br) &&
     	    ((tx->mask - (tx->req - tx->done)) > tx->max_desc)) {
     		/* let BPF see it */
     		BPF_MTAP(ifp, m);
    diff --git a/sys/net/if_var.h b/sys/net/if_var.h
    index 5f9064b5847..7685e8be756 100644
    --- a/sys/net/if_var.h
    +++ b/sys/net/if_var.h
    @@ -602,12 +602,8 @@ drbr_flush(struct ifnet *ifp, struct buf_ring *br)
     	struct mbuf *m;
     
     #ifdef ALTQ
    -	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
    -		while (!IFQ_IS_EMPTY(&ifp->if_snd)) {
    -			IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
    -			m_freem(m);
    -		}
    -	}
    +	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
    +		IFQ_PURGE(&ifp->if_snd);
     #endif	
     	while ((m = buf_ring_dequeue_sc(br)) != NULL)
     		m_freem(m);
    @@ -628,7 +624,7 @@ drbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
     	struct mbuf *m;
     
     	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {	
    -		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
    +		IFQ_DEQUEUE(&ifp->if_snd, m);
     		return (m);
     	}
     #endif
    @@ -641,11 +637,15 @@ drbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
     {
     	struct mbuf *m;
     #ifdef ALTQ
    -	/*
    -	 * XXX need to evaluate / requeue 
    -	 */
    -	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {	
    -		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
    +	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
    +		IFQ_LOCK(&ifp->if_snd);
    +		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
    +		if (m != NULL && func(m, arg) == 0) {
    +			IFQ_UNLOCK(&ifp->if_snd);
    +			return (NULL);
    +		}
    +		IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
    +		IFQ_UNLOCK(&ifp->if_snd);
     		return (m);
     	}
     #endif
    @@ -661,11 +661,21 @@ drbr_empty(struct ifnet *ifp, struct buf_ring *br)
     {
     #ifdef ALTQ
     	if (ALTQ_IS_ENABLED(&ifp->if_snd))
    -		return (IFQ_DRV_IS_EMPTY(&ifp->if_snd));
    +		return (IFQ_IS_EMPTY(&ifp->if_snd));
     #endif
     	return (buf_ring_empty(br));
     }
     
    +static __inline int
    +drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
    +{
    +#ifdef ALTQ
    +	if (ALTQ_IS_ENABLED(&ifp->if_snd))
    +		return (1);
    +#endif
    +	return (!buf_ring_empty(br));
    +}
    +
     static __inline int
     drbr_inuse(struct ifnet *ifp, struct buf_ring *br)
     {
    
    From 194bfbdd245931584502ce7b2d578dfb1dd432f2 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 18 Mar 2010 18:35:28 +0000
    Subject: [PATCH 1608/2592] MFC r202821-202822.
    
    r202821:
      Fix a long standing ASF heartbeat sending bug. The initial
      implementation of heartbeat interval was 2 but there was typo which
      caused the heartbeat is sent approximately every 5 seconds. This
      caused unintended controller reset by firmware because firmware
      thought OS was crashed.
    
      Submitted by:	Floris Bos < info <> je-eigen-domein dot nl >
      Tested by:	Andrzej Tobola < ato <> iem dot pw dot edu dot pl >
    
    r202822:
      Use new handshake command for BCM5750 or new controllers.
    ---
     sys/dev/bge/if_bge.c | 5 ++---
     1 file changed, 2 insertions(+), 3 deletions(-)
    
    diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
    index 4d8f3f48293..80d4ba18863 100644
    --- a/sys/dev/bge/if_bge.c
    +++ b/sys/dev/bge/if_bge.c
    @@ -2744,9 +2744,8 @@ bge_attach(device_t dev)
     		    & BGE_HWCFG_ASF) {
     			sc->bge_asf_mode |= ASF_ENABLE;
     			sc->bge_asf_mode |= ASF_STACKUP;
    -			if (sc->bge_asicrev == BGE_ASICREV_BCM5750) {
    +			if (BGE_IS_575X_PLUS(sc))
     				sc->bge_asf_mode |= ASF_NEW_HANDSHAKE;
    -			}
     		}
     	}
     
    @@ -3677,7 +3676,7 @@ bge_asf_driver_up(struct bge_softc *sc)
     		if (sc->bge_asf_count)
     			sc->bge_asf_count --;
     		else {
    -			sc->bge_asf_count = 5;
    +			sc->bge_asf_count = 2;
     			bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW,
     			    BGE_FW_DRV_ALIVE);
     			bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_LEN, 4);
    
    From bb8c5f9792857419b4da4e03f2737f78825283a9 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 18 Mar 2010 18:44:08 +0000
    Subject: [PATCH 1609/2592] MFC r203355:   Add more bit definitions to PCI
     express device control and device   status register.
    
    ---
     sys/dev/pci/pcireg.h | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
    index 981d1e0cde4..54ed1f3124d 100644
    --- a/sys/dev/pci/pcireg.h
    +++ b/sys/dev/pci/pcireg.h
    @@ -605,9 +605,17 @@
     #define	PCIR_EXPRESS_DEVICE_CAP	0x4
     #define	PCIM_EXP_CAP_MAX_PAYLOAD	0x0007
     #define	PCIR_EXPRESS_DEVICE_CTL	0x8
    +#define	PCIM_EXP_CTL_RELAXED_ORD_ENABLE	0x0010
     #define	PCIM_EXP_CTL_MAX_PAYLOAD	0x00e0
    +#define	PCIM_EXP_CTL_NOSNOOP_ENABLE	0x0800
     #define	PCIM_EXP_CTL_MAX_READ_REQUEST	0x7000
     #define	PCIR_EXPRESS_DEVICE_STA	0xa
    +#define	PCIM_EXP_STA_CORRECTABLE_ERROR	0x0001
    +#define	PCIM_EXP_STA_NON_FATAL_ERROR	0x0002
    +#define	PCIM_EXP_STA_FATAL_ERROR	0x0004
    +#define	PCIM_EXP_STA_UNSUPPORTED_REQ	0x0008
    +#define	PCIM_EXP_STA_AUX_POWER		0x0010
    +#define	PCIM_EXP_STA_TRANSACTION_PND	0x0020
     #define	PCIR_EXPRESS_LINK_CAP	0xc
     #define	PCIM_LINK_CAP_MAX_SPEED		0x0000000f
     #define	PCIM_LINK_CAP_MAX_WIDTH		0x000003f0
    
    From 0debac0d3abcdf195eed502ea316537712c2e3a6 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 18 Mar 2010 18:50:20 +0000
    Subject: [PATCH 1610/2592] MFC r203358,203716:
    
    r203358:
      PCI express device status register has W1C feature. Writing 0 has
      no effect. Make sure to clear error bits by writing 1. [1]
      While I'm here use predefined value instead of hardcodig magic
      vlaue.
    
      Submitted by:	msaitoh at NetBSD [1]
    
    r203716:
      Move device specific flag configuration to attach routine.
      The softc obtained in device probe wouldn't be the same one used in
      device attach. Drivers should not assume any values stored in softc
      structure in probe routine will be available for its attach routine.
    ---
     sys/dev/bge/if_bge.c | 15 +++++++++------
     1 file changed, 9 insertions(+), 6 deletions(-)
    
    diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
    index 80d4ba18863..5209b6a6c9f 100644
    --- a/sys/dev/bge/if_bge.c
    +++ b/sys/dev/bge/if_bge.c
    @@ -1993,10 +1993,6 @@ bge_probe(device_t dev)
     			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;
    -			if (did == BCOM_DEVICEID_BCM5755M)
    -				sc->bge_flags |= BGE_FLAG_ADJUST_TRIM;
     			return (0);
     		}
     		t++;
    @@ -2607,6 +2603,10 @@ bge_attach(device_t dev)
     		sc->bge_flags |= BGE_FLAG_ADC_BUG;
     	if (sc->bge_chipid == BGE_CHIPID_BCM5704_A0)
     		sc->bge_flags |= BGE_FLAG_5704_A0_BUG;
    +	if (pci_get_subvendor(dev) == DELL_VENDORID)
    +		sc->bge_flags |= BGE_FLAG_NO_3LED;
    +	if (pci_get_device(dev) == BCOM_DEVICEID_BCM5755M)
    +		sc->bge_flags |= BGE_FLAG_ADJUST_TRIM;
     	if (BGE_IS_5705_PLUS(sc) &&
     	    !(sc->bge_flags & BGE_FLAG_ADJUST_TRIM)) {
     		if (sc->bge_asicrev == BGE_ASICREV_BCM5755 ||
    @@ -3136,14 +3136,17 @@ bge_reset(struct bge_softc *sc)
     		devctl = pci_read_config(dev,
     		    sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL, 2);
     		/* Clear enable no snoop and disable relaxed ordering. */
    -		devctl &= ~(0x0010 | 0x0800);
    +		devctl &= ~(PCIM_EXP_CTL_RELAXED_ORD_ENABLE |
    +		    PCIM_EXP_CTL_NOSNOOP_ENABLE);
     		/* Set PCIE max payload size to 128. */
     		devctl &= ~PCIM_EXP_CTL_MAX_PAYLOAD;
     		pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL,
     		    devctl, 2);
     		/* Clear error status. */
     		pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_STA,
    -		    0, 2);
    +		    PCIM_EXP_STA_CORRECTABLE_ERROR |
    +		    PCIM_EXP_STA_NON_FATAL_ERROR | PCIM_EXP_STA_FATAL_ERROR |
    +		    PCIM_EXP_STA_UNSUPPORTED_REQ, 2);
     	}
     
     	/* Reset some of the PCI state that got zapped by reset. */
    
    From 12c4b5ef43699b9b97263fb9b79b91fcda45fbc9 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 18 Mar 2010 18:58:24 +0000
    Subject: [PATCH 1611/2592] MFC r202826-202827,204146
    
    r202826:
      s/Mhz/MHz/g
    
      Submitted by:	N.J. Mann  njm dot me dot uk >
    
    r202827:
      Yukon Ultra2 has 125MHz clock.
    
    r204146:
      Correct inversed programming of ethernet hardware address on
      big-endian architecture.
    
      Submitted by:	C. Jayachandran  (initial version)
    ---
     sys/dev/msk/if_msk.c | 42 ++++++++++++++++++++++++------------------
     1 file changed, 24 insertions(+), 18 deletions(-)
    
    diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
    index 8fbd5b4a244..dd52abe54c3 100644
    --- a/sys/dev/msk/if_msk.c
    +++ b/sys/dev/msk/if_msk.c
    @@ -1699,15 +1699,15 @@ mskc_attach(device_t dev)
     
     	switch (sc->msk_hw_id) {
     	case CHIP_ID_YUKON_EC:
    -		sc->msk_clock = 125;	/* 125 Mhz */
    +		sc->msk_clock = 125;	/* 125 MHz */
     		sc->msk_pflags |= MSK_FLAG_JUMBO;
     		break;
     	case CHIP_ID_YUKON_EC_U:
    -		sc->msk_clock = 125;	/* 125 Mhz */
    +		sc->msk_clock = 125;	/* 125 MHz */
     		sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_JUMBO_NOCSUM;
     		break;
     	case CHIP_ID_YUKON_EX:
    -		sc->msk_clock = 125;	/* 125 Mhz */
    +		sc->msk_clock = 125;	/* 125 MHz */
     		sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_DESCV2 |
     		    MSK_FLAG_AUTOTX_CSUM;
     		/*
    @@ -1725,11 +1725,11 @@ mskc_attach(device_t dev)
     			sc->msk_pflags |= MSK_FLAG_JUMBO_NOCSUM;
     		break;
     	case CHIP_ID_YUKON_FE:
    -		sc->msk_clock = 100;	/* 100 Mhz */
    +		sc->msk_clock = 100;	/* 100 MHz */
     		sc->msk_pflags |= MSK_FLAG_FASTETHER;
     		break;
     	case CHIP_ID_YUKON_FE_P:
    -		sc->msk_clock = 50;	/* 50 Mhz */
    +		sc->msk_clock = 50;	/* 50 MHz */
     		sc->msk_pflags |= MSK_FLAG_FASTETHER | MSK_FLAG_DESCV2 |
     		    MSK_FLAG_AUTOTX_CSUM;
     		if (sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
    @@ -1748,15 +1748,15 @@ mskc_attach(device_t dev)
     		}
     		break;
     	case CHIP_ID_YUKON_XL:
    -		sc->msk_clock = 156;	/* 156 Mhz */
    +		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_clock = 125;	/* 125 MHz */
     		sc->msk_pflags |= MSK_FLAG_JUMBO;
     		break;
     	default:
    -		sc->msk_clock = 156;	/* 156 Mhz */
    +		sc->msk_clock = 156;	/* 156 MHz */
     		break;
     	}
     
    @@ -3715,10 +3715,10 @@ msk_init_locked(struct msk_if_softc *sc_if)
     	struct msk_softc *sc;
     	struct ifnet *ifp;
     	struct mii_data	 *mii;
    -	uint16_t eaddr[ETHER_ADDR_LEN / 2];
    +	uint8_t *eaddr;
     	uint16_t gmac;
     	uint32_t reg;
    -	int error, i;
    +	int error;
     
     	MSK_IF_LOCK_ASSERT(sc_if);
     
    @@ -3787,14 +3787,20 @@ msk_init_locked(struct msk_if_softc *sc_if)
     	GMAC_WRITE_2(sc, sc_if->msk_port, GM_SERIAL_MODE, gmac);
     
     	/* Set station address. */
    -        bcopy(IF_LLADDR(ifp), eaddr, ETHER_ADDR_LEN);
    -        for (i = 0; i < ETHER_ADDR_LEN /2; i++)
    -		GMAC_WRITE_2(sc, sc_if->msk_port, GM_SRC_ADDR_1L + i * 4,
    -		    eaddr[i]);
    -        for (i = 0; i < ETHER_ADDR_LEN /2; i++)
    -		GMAC_WRITE_2(sc, sc_if->msk_port, GM_SRC_ADDR_2L + i * 4,
    -		    eaddr[i]);
    -
    +	eaddr = IF_LLADDR(ifp);
    +	GMAC_WRITE_2(sc, sc_if->msk_port, GM_SRC_ADDR_1L,
    +	    eaddr[0] | (eaddr[1] << 8));
    +	GMAC_WRITE_2(sc, sc_if->msk_port, GM_SRC_ADDR_1M,
    +	    eaddr[2] | (eaddr[3] << 8));
    +	GMAC_WRITE_2(sc, sc_if->msk_port, GM_SRC_ADDR_1H,
    +	    eaddr[4] | (eaddr[5] << 8));
    +	GMAC_WRITE_2(sc, sc_if->msk_port, GM_SRC_ADDR_2L,
    +	    eaddr[0] | (eaddr[1] << 8));
    +	GMAC_WRITE_2(sc, sc_if->msk_port, GM_SRC_ADDR_2M,
    +	    eaddr[2] | (eaddr[3] << 8));
    +	GMAC_WRITE_2(sc, sc_if->msk_port, GM_SRC_ADDR_2H,
    +	    eaddr[4] | (eaddr[5] << 8));
    +	
     	/* Disable interrupts for counter overflows. */
     	GMAC_WRITE_2(sc, sc_if->msk_port, GM_TX_IRQ_MSK, 0);
     	GMAC_WRITE_2(sc, sc_if->msk_port, GM_RX_IRQ_MSK, 0);
    
    From d5eda01f756124850ff39706d664a35e2e5c7c71 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 18 Mar 2010 19:04:04 +0000
    Subject: [PATCH 1612/2592] MFC r204149:   Add TSO support on VLANs.
     Intentionally separated IFCAP_VLAN_HWTSO   from IFCAP_VLAN_HWTAGGING. I think
     some hardwares may be able to   TSO over VLAN without VLAN hardware tagging. 
      Driver changes and userland support will follow.
    
    ---
     sys/net/if.h      |  1 +
     sys/net/if_vlan.c | 17 ++++++++++++++++-
     2 files changed, 17 insertions(+), 1 deletion(-)
    
    diff --git a/sys/net/if.h b/sys/net/if.h
    index aff0d76da71..e226654b34b 100644
    --- a/sys/net/if.h
    +++ b/sys/net/if.h
    @@ -218,6 +218,7 @@ struct if_data {
     #define	IFCAP_TOE6		0x08000	/* interface can offload TCP6 */
     #define	IFCAP_VLAN_HWFILTER	0x10000 /* interface hw can filter vlan tag */
     #define	IFCAP_POLLING_NOCOUNT	0x20000 /* polling ticks cannot be fragmented */
    +#define	IFCAP_VLAN_HWTSO	0x40000 /* can do IFCAP_TSO on VLANs */
     
     #define IFCAP_HWCSUM	(IFCAP_RXCSUM | IFCAP_TXCSUM)
     #define	IFCAP_TSO	(IFCAP_TSO4 | IFCAP_TSO6)
    diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
    index f0cd3b31d69..9dcbedd346e 100644
    --- a/sys/net/if_vlan.c
    +++ b/sys/net/if_vlan.c
    @@ -1275,11 +1275,26 @@ vlan_capabilities(struct ifvlan *ifv)
     	if (p->if_capenable & IFCAP_VLAN_HWCSUM &&
     	    p->if_capenable & IFCAP_VLAN_HWTAGGING) {
     		ifp->if_capenable = p->if_capenable & IFCAP_HWCSUM;
    -		ifp->if_hwassist = p->if_hwassist;
    +		ifp->if_hwassist = p->if_hwassist & (CSUM_IP | CSUM_TCP |
    +		    CSUM_UDP | CSUM_SCTP | CSUM_IP_FRAGS | CSUM_FRAGMENT);
     	} else {
     		ifp->if_capenable = 0;
     		ifp->if_hwassist = 0;
     	}
    +	/*
    +	 * If the parent interface can do TSO on VLANs then
    +	 * propagate the hardware-assisted flag. TSO on VLANs
    +	 * does not necessarily require hardware VLAN tagging.
    +	 */
    +	if (p->if_capabilities & IFCAP_VLAN_HWTSO)
    +		ifp->if_capabilities |= p->if_capabilities & IFCAP_TSO;
    +	if (p->if_capenable & IFCAP_VLAN_HWTSO) {
    +		ifp->if_capenable |= p->if_capenable & IFCAP_TSO;
    +		ifp->if_hwassist |= p->if_hwassist & CSUM_TSO;
    +	} else {
    +		ifp->if_capenable &= ~(p->if_capenable & IFCAP_TSO);
    +		ifp->if_hwassist &= ~(p->if_hwassist & CSUM_TSO);
    +	}
     }
     
     static void
    
    From be3410a939382ecd7f03df12949230098cb32fac Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 18 Mar 2010 19:10:03 +0000
    Subject: [PATCH 1613/2592] MFC r204150:   Add TSO support on VLAN in
     fconfig(8).
    
    ---
     sbin/ifconfig/ifconfig.8 | 14 +++++++-------
     sbin/ifconfig/ifconfig.c |  2 +-
     sbin/ifconfig/ifvlan.c   |  2 ++
     3 files changed, 10 insertions(+), 8 deletions(-)
    
    diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
    index 32e8fa3993e..a7b148a0446 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 January 26, 2010
    +.Dd February 20, 2010
     .Dt IFCONFIG 8
     .Os
     .Sh NAME
    @@ -408,20 +408,20 @@ they support in their capabilities.
     is a synonym for enabling all available WOL mechanisms.
     To disable WOL use
     .Fl wol .
    -.It Cm vlanmtu , vlanhwtag, vlanhwfilter
    +.It Cm vlanmtu , vlanhwtag, vlanhwfilter, vlanhwtso
     If the driver offers user-configurable VLAN support, enable
    -reception of extended frames, tag processing in hardware, or
    -frame filtering in hardware,
    +reception of extended frames, tag processing in hardware,
    +frame filtering in hardware, or TSO on VLAN,
     respectively.
     Note that this must be issued on a physical interface associated with
     .Xr vlan 4 ,
     not on a
     .Xr vlan 4
     interface itself.
    -.It Fl vlanmtu , vlanhwtag, vlanhwfilter
    +.It Fl vlanmtu , vlanhwtag, vlanhwfilter, vlanhwtso
     If the driver offers user-configurable VLAN support, disable
    -reception of extended frames, tag processing in hardware, or
    -frame filtering in hardware,
    +reception of extended frames, tag processing in hardware,
    +frame filtering in hardware, or TSO on VLAN,
     respectively.
     .It Cm vnet Ar jail
     Move the interface to the
    diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
    index ec5e4032f1d..45c6d40e047 100644
    --- a/sbin/ifconfig/ifconfig.c
    +++ b/sbin/ifconfig/ifconfig.c
    @@ -865,7 +865,7 @@ unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
     #define	IFCAPBITS \
     "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \
     "\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \
    -"\21VLAN_HWFILTER"
    +"\21VLAN_HWFILTER\23VLAN_HWTSO"
     
     /*
      * Print the status of the interface.  If an address family was
    diff --git a/sbin/ifconfig/ifvlan.c b/sbin/ifconfig/ifvlan.c
    index c59cac11e54..30005852f16 100644
    --- a/sbin/ifconfig/ifvlan.c
    +++ b/sbin/ifconfig/ifvlan.c
    @@ -181,6 +181,8 @@ static struct cmd vlan_cmds[] = {
     	DEF_CMD("-vlanhwtag",	-IFCAP_VLAN_HWTAGGING,	setifcap),
     	DEF_CMD("vlanhwfilter",	IFCAP_VLAN_HWFILTER,	setifcap),
     	DEF_CMD("-vlanhwfilter", -IFCAP_VLAN_HWFILTER,	setifcap),
    +	DEF_CMD("-vlanhwtso",	-IFCAP_VLAN_HWTSO,	setifcap),
    +	DEF_CMD("vlanhwtso",	IFCAP_VLAN_HWTSO,	setifcap),
     };
     static struct afswtch af_vlan = {
     	.af_name	= "af_vlan",
    
    From 4f7bf104f096661837454744fee638adfdfc80ad Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Fri, 19 Mar 2010 00:26:45 +0000
    Subject: [PATCH 1614/2592] MFC r202717:   - Added a workaround for NC-SI
     management firmware that would allow     frames to be accepted while the
     driver is resetting the hardware.     This failure is generally observed when
     broadcast frames are received     during driver load and will generate
     "Unable to write CTX memory"     errors.   - Small changes to driver flags
     display.
    
    PR:	kern/135836, kern/140684
    ---
     sys/dev/bce/if_bce.c    | 162 +++++++++++++++++++++++++++++++++-------
     sys/dev/bce/if_bcereg.h |   4 +
     2 files changed, 137 insertions(+), 29 deletions(-)
    
    diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
    index aa076c44d0c..94198e870c4 100644
    --- a/sys/dev/bce/if_bce.c
    +++ b/sys/dev/bce/if_bce.c
    @@ -371,6 +371,9 @@ static void bce_release_resources	(struct bce_softc *);
     static int  bce_fw_sync				(struct bce_softc *, u32);
     static void bce_load_rv2p_fw		(struct bce_softc *, u32 *, u32, u32);
     static void bce_load_cpu_fw			(struct bce_softc *, struct cpu_reg *, struct fw_info *);
    +static void bce_start_cpu           (struct bce_softc *, struct cpu_reg *);
    +static void bce_halt_cpu            (struct bce_softc *, struct cpu_reg *);
    +static void bce_start_rxp_cpu       (struct bce_softc *);
     static void bce_init_rxp_cpu		(struct bce_softc *);
     static void bce_init_txp_cpu 		(struct bce_softc *);
     static void bce_init_tpat_cpu		(struct bce_softc *);
    @@ -603,9 +606,10 @@ bce_print_adapter_info(struct bce_softc *sc)
     	printf("B/C (%s); Flags (", sc->bce_bc_ver);
     
     #ifdef BCE_JUMBO_HDRSPLIT
    -	printf("SPLT ");
    +	printf("SPLT");
         i++;
     #endif
    +
         if (sc->bce_flags & BCE_USING_MSI_FLAG) {
             if (i > 0) printf("|");
     		printf("MSI"); i++;
    @@ -613,7 +617,7 @@ bce_print_adapter_info(struct bce_softc *sc)
     
         if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
             if (i > 0) printf("|");
    -		printf("MSI-X "); i++;
    +		printf("MSI-X"); i++;
         }
     
         if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
    @@ -2976,6 +2980,7 @@ bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
     /* |PG Buffers       |   none   |   none   |   none   |   none   |          */
     /* |TX Buffers       |   none   |   none   |   none   |   none   |          */
     /* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
    +/* |Context Memory   |          |          |          |          |          */
     /* +-----------------+----------+----------+----------+----------+          */
     /*                                                                          */
     /* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
    @@ -3665,15 +3670,10 @@ bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
     	struct fw_info *fw)
     {
     	u32 offset;
    -	u32 val;
     
     	DBENTER(BCE_VERBOSE_RESET);
     
    -	/* Halt the CPU. */
    -	val = REG_RD_IND(sc, cpu_reg->mode);
    -	val |= cpu_reg->mode_value_halt;
    -	REG_WR_IND(sc, cpu_reg->mode, val);
    -	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
    +    bce_halt_cpu(sc, cpu_reg);
     
     	/* Load the Text area. */
     	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
    @@ -3726,9 +3726,28 @@ bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
     		}
     	}
     
    -	/* Clear the pre-fetch instruction. */
    -	REG_WR_IND(sc, cpu_reg->inst, 0);
    -	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
    +    /* Clear the pre-fetch instruction and set the FW start address. */
    +    REG_WR_IND(sc, cpu_reg->inst, 0);
    +    REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
    +
    +	DBEXIT(BCE_VERBOSE_RESET);
    +}
    +
    +
    +/****************************************************************************/
    +/* Starts the RISC processor.                                               */
    +/*                                                                          */
    +/* Assumes the CPU starting address has already been set.                   */
    +/*                                                                          */
    +/* Returns:                                                                 */
    +/*   Nothing.                                                               */
    +/****************************************************************************/
    +static void
    +bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
    +{
    +	u32 val;
    +
    +	DBENTER(BCE_VERBOSE_RESET);
     
     	/* Start the CPU. */
     	val = REG_RD_IND(sc, cpu_reg->mode);
    @@ -3740,6 +3759,62 @@ bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
     }
     
     
    +/****************************************************************************/
    +/* Halts the RISC processor.                                                */
    +/*                                                                          */
    +/* Returns:                                                                 */
    +/*   Nothing.                                                               */
    +/****************************************************************************/
    +static void
    +bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
    +{
    +	u32 val;
    +
    +	DBENTER(BCE_VERBOSE_RESET);
    +
    +    /* Halt the CPU. */
    +    val = REG_RD_IND(sc, cpu_reg->mode);
    +    val |= cpu_reg->mode_value_halt;
    +    REG_WR_IND(sc, cpu_reg->mode, val);
    +    REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
    +
    +	DBEXIT(BCE_VERBOSE_RESET);
    +}
    +
    +
    +/****************************************************************************/
    +/* Initialize the RX CPU.                                                   */
    +/*                                                                          */
    +/* Returns:                                                                 */
    +/*   Nothing.                                                               */
    +/****************************************************************************/
    +static void
    +bce_start_rxp_cpu(struct bce_softc *sc)
    +{
    +	struct cpu_reg cpu_reg;
    +
    +	DBENTER(BCE_VERBOSE_RESET);
    +
    +	cpu_reg.mode = BCE_RXP_CPU_MODE;
    +	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
    +	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
    +	cpu_reg.state = BCE_RXP_CPU_STATE;
    +	cpu_reg.state_value_clear = 0xffffff;
    +	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
    +	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
    +	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
    +	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
    +	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
    +	cpu_reg.spad_base = BCE_RXP_SCRATCH;
    +	cpu_reg.mips_view_base = 0x8000000;
    +
    +	DBPRINT(sc, BCE_INFO_RESET, "Starting RX firmware.\n");
    +	bce_start_cpu(sc, &cpu_reg);
    +
    +	DBEXIT(BCE_VERBOSE_RESET);
    +}
    +
    +
     /****************************************************************************/
     /* Initialize the RX CPU.                                                   */
     /*                                                                          */
    @@ -3833,6 +3908,8 @@ bce_init_rxp_cpu(struct bce_softc *sc)
     	DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
     	bce_load_cpu_fw(sc, &cpu_reg, &fw);
     
    +    /* Delay RXP start until initialization is complete. */
    +
     	DBEXIT(BCE_VERBOSE_RESET);
     }
     
    @@ -3929,6 +4006,7 @@ bce_init_txp_cpu(struct bce_softc *sc)
     
     	DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
     	bce_load_cpu_fw(sc, &cpu_reg, &fw);
    +    bce_start_cpu(sc, &cpu_reg);
     
     	DBEXIT(BCE_VERBOSE_RESET);
     }
    @@ -4026,6 +4104,7 @@ bce_init_tpat_cpu(struct bce_softc *sc)
     
     	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
     	bce_load_cpu_fw(sc, &cpu_reg, &fw);
    +    bce_start_cpu(sc, &cpu_reg);
     
     	DBEXIT(BCE_VERBOSE_RESET);
     }
    @@ -4123,6 +4202,7 @@ bce_init_cp_cpu(struct bce_softc *sc)
     
     	DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
     	bce_load_cpu_fw(sc, &cpu_reg, &fw);
    +    bce_start_cpu(sc, &cpu_reg);
     
     	DBEXIT(BCE_VERBOSE_RESET);
     }
    @@ -4220,6 +4300,7 @@ bce_init_com_cpu(struct bce_softc *sc)
     
     	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
     	bce_load_cpu_fw(sc, &cpu_reg, &fw);
    +    bce_start_cpu(sc, &cpu_reg);
     
     	DBEXIT(BCE_VERBOSE_RESET);
     }
    @@ -4665,6 +4746,12 @@ bce_chipinit(struct bce_softc *sc)
     	/* Initialize the on-boards CPUs */
     	bce_init_cpus(sc);
     
    +    /* Enable management frames (NC-SI) to flow to the MCP. */
    +    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    +        val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
    +        REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
    +    }
    +
     	/* Prepare NVRAM for access. */
     	if (bce_init_nvram(sc)) {
     		rc = ENODEV;
    @@ -4845,6 +4932,15 @@ bce_blockinit(struct bce_softc *sc)
     	/* Enable link state change interrupt generation. */
     	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
     
    +    /* Enable the RXP. */
    +    bce_start_rxp_cpu(sc);
    +
    +    /* Disable management frames (NC-SI) from flowing to the MCP. */
    +    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    +        val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) & ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
    +        REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
    +    }
    +
     	/* Enable all remaining blocks in the MAC. */
     	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
     		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
    @@ -5851,22 +5947,29 @@ bce_rx_intr(struct bce_softc *sc)
     		DBRUN(sc->debug_rx_mbuf_alloc--);
     		sc->free_rx_bd++;
     
    -		/*
    -		 * Frames received on the NetXteme II are prepended	with an
    -		 * l2_fhdr structure which provides status information about
    -		 * the received frame (including VLAN tags and checksum info).
    -		 * The frames are also automatically adjusted to align the IP
    -		 * header (i.e. two null bytes are inserted before the Ethernet
    -		 * header).  As a result the data DMA'd by the controller into
    -		 * the mbuf is as follows:
    -		 * 
    -		 * +---------+-----+---------------------+-----+
    -		 * | l2_fhdr | pad | packet data         | FCS |
    -		 * +---------+-----+---------------------+-----+
    -		 * 
    -		 * The l2_fhdr needs to be checked and skipped and the FCS needs
    -		 * to be stripped before sending the packet up the stack.
    -		 */
    +        if(m0 == NULL) {
    +            DBPRINT(sc, BCE_EXTREME_RECV, "%s(): Oops! Empty mbuf pointer "
    +                "found in sc->rx_mbuf_ptr[0x%04X]!\n",
    +                __FUNCTION__, sw_rx_cons_idx);
    +            goto bce_rx_int_next_rx;
    +        }
    +
    +        /*
    +         * Frames received on the NetXteme II are prepended	with an
    +         * l2_fhdr structure which provides status information about
    +         * the received frame (including VLAN tags and checksum info).
    +         * The frames are also automatically adjusted to align the IP
    +         * header (i.e. two null bytes are inserted before the Ethernet
    +         * header).  As a result the data DMA'd by the controller into
    +         * the mbuf is as follows:
    +         * 
    +         * +---------+-----+---------------------+-----+
    +         * | l2_fhdr | pad | packet data         | FCS |
    +         * +---------+-----+---------------------+-----+
    +         * 
    +         * The l2_fhdr needs to be checked and skipped and the FCS needs
    +         * to be stripped before sending the packet up the stack.
    +         */
     		l2fhdr  = mtod(m0, struct l2_fhdr *);
     
     		/* Get the packet data + FCS length and the status. */
    @@ -6387,6 +6490,7 @@ bce_init_locked(struct bce_softc *sc)
     
     	bce_ifmedia_upd_locked(ifp);
     
    +	/* Let the OS know the driver is up and running. */
     	ifp->if_drv_flags |= IFF_DRV_RUNNING;
     	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
     
    @@ -10038,9 +10142,9 @@ bce_dump_bc_state(struct bce_softc *sc)
     	BCE_PRINTF("0x%08X - (0x%06X) state\n",
     		val, BCE_BC_STATE);
     
    -	val = bce_shmem_rd(sc, BCE_BC_CONDITION);
    +	val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
     	BCE_PRINTF("0x%08X - (0x%06X) condition\n",
    -		val, BCE_BC_CONDITION);
    +		val, BCE_BC_STATE_CONDITION);
     
     	val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
     	BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
    diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h
    index 3ee7b1d03d4..a437686478e 100644
    --- a/sys/dev/bce/if_bcereg.h
    +++ b/sys/dev/bce/if_bcereg.h
    @@ -3715,6 +3715,10 @@ struct l2_fhdr {
     #define BCE_RPM_CONFIG_SORT_VECT_VAL			 (0xfL<<4)
     #define BCE_RPM_CONFIG_IGNORE_VLAN			 (1L<<31)
     
    +#define BCE_RPM_MGMT_PKT_CTRL					0x0000180c
    +#define BCE_RPM_MGMT_PKT_CTRL_MGMT_DISCARD_EN	 (1L<<30)
    +#define BCE_RPM_MGMT_PKT_CTRL_MGMT_EN   		 (1L<<31)
    +
     #define BCE_RPM_VLAN_MATCH0				0x00001810
     #define BCE_RPM_VLAN_MATCH0_RPM_VLAN_MTCH0_VALUE	 (0xfffL<<0)
     
    
    From 5a9ca220b28c001fe57f4db23f09c9214a8afc65 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Fri, 19 Mar 2010 10:25:59 +0000
    Subject: [PATCH 1615/2592] MFC r204755: Update the list of the process flags.
     Note that the lists of pending signals for process and its threads are
     distinct.
    
    ---
     bin/ps/ps.1 | 18 +++++++++++++++---
     1 file changed, 15 insertions(+), 3 deletions(-)
    
    diff --git a/bin/ps/ps.1 b/bin/ps/ps.1
    index 46a371cd48b..5c9689e1063 100644
    --- a/bin/ps/ps.1
    +++ b/bin/ps/ps.1
    @@ -29,7 +29,7 @@
     .\"     @(#)ps.1	8.3 (Berkeley) 4/18/94
     .\" $FreeBSD$
     .\"
    -.Dd July 9, 2009
    +.Dd March 5, 2010
     .Dt PS 1
     .Os
     .Sh NAME
    @@ -284,11 +284,10 @@ The percentage of real memory used by this process.
     The flags associated with the process as in
     the include file
     .In sys/proc.h :
    -.Bl -column P_STOPPED_SINGLE 0x4000000
    +.Bl -column P_SINGLE_BOUNDARY 0x40000000
     .It Dv "P_ADVLOCK" Ta No "0x00001	Process may hold a POSIX advisory lock"
     .It Dv "P_CONTROLT" Ta No "0x00002	Has a controlling terminal"
     .It Dv "P_KTHREAD" Ta No "0x00004	Kernel thread"
    -.It Dv "P_NOLOAD" Ta No "0x00008	Ignore during load avg calculations"
     .It Dv "P_PPWAIT" Ta No "0x00010	Parent is waiting for child to exec/exit"
     .It Dv "P_PROFIL" Ta No "0x00020	Has started profiling"
     .It Dv "P_STOPPROF" Ta No "0x00040	Has thread in requesting to stop prof"
    @@ -305,8 +304,14 @@ the include file
     .It Dv "P_STOPPED_SINGLE" Ta No "0x80000	Only one thread can continue"
     .It Dv "P_PROTECTED" Ta No "0x100000	Do not kill on memory overcommit"
     .It Dv "P_SIGEVENT" Ta No "0x200000	Process pending signals changed"
    +.It Dv "P_SINGLE_BOUNDARY" Ta No "0x400000	Threads should suspend at user boundary"
    +.It Dv "P_HWPMC" Ta No "0x800000	Process is using HWPMCs"
     .It Dv "P_JAILED" Ta No "0x1000000	Process is in jail"
     .It Dv "P_INEXEC" Ta No "0x4000000	Process is in execve()"
    +.It Dv "P_STATCHILD" Ta No "0x8000000	Child process stopped or exited"
    +.It Dv "P_INMEM" Ta No "0x10000000	Loaded into memory"
    +.It Dv "P_SWAPPINGOUT" Ta No "0x20000000	Process is being swapped out"
    +.It Dv "P_SWAPPINGIN" Ta No "0x40000000	Process is being swapped in"
     .El
     .It Cm label
     The MAC label of the process.
    @@ -615,6 +620,13 @@ wait channel (as a symbolic name)
     .It Cm xstat
     exit or stop status (valid only for stopped or zombie process)
     .El
    +.Pp
    +Note that the
    +.Cm pending
    +column displays bitmask of signals pending in the process queue when
    +.Fl H
    +option is not specified, otherwise the per-thread queue of pending signals
    +is shown.
     .Sh ENVIRONMENT
     The following environment variables affect the execution of
     .Nm :
    
    From b2eaa3b2c2e8d2a9d3dd0b939d23aa67a7c12a24 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Fri, 19 Mar 2010 10:28:49 +0000
    Subject: [PATCH 1616/2592] MFC r205224: Add missing headers.
    
    ---
     tools/regression/aio/aiotest/aiotest.c | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/tools/regression/aio/aiotest/aiotest.c b/tools/regression/aio/aiotest/aiotest.c
    index 8769dc1a93d..60de273dc46 100644
    --- a/tools/regression/aio/aiotest/aiotest.c
    +++ b/tools/regression/aio/aiotest/aiotest.c
    @@ -40,14 +40,17 @@
     
     #include 
     #include 
    +#include 
     #include 
     
     #include 
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    
    From 2219384ff79ca0d61cfb1cb255cbc5b8c9dc4fa9 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Fri, 19 Mar 2010 10:33:45 +0000
    Subject: [PATCH 1617/2592] MFC r205225: Add missing headers. While there,
     arrange headers alphabetically.
    
    ---
     tools/regression/mqueue/mqtest1/mqtest1.c |  9 +++++----
     tools/regression/mqueue/mqtest2/mqtest2.c |  9 +++++++--
     tools/regression/mqueue/mqtest3/mqtest3.c | 15 ++++++++++-----
     tools/regression/mqueue/mqtest4/mqtest4.c | 17 +++++++++++------
     tools/regression/mqueue/mqtest5/mqtest5.c | 16 ++++++++++------
     5 files changed, 43 insertions(+), 23 deletions(-)
    
    diff --git a/tools/regression/mqueue/mqtest1/mqtest1.c b/tools/regression/mqueue/mqtest1/mqtest1.c
    index 8551b9f9858..25fc1ba881e 100644
    --- a/tools/regression/mqueue/mqtest1/mqtest1.c
    +++ b/tools/regression/mqueue/mqtest1/mqtest1.c
    @@ -1,10 +1,11 @@
     /* $FreeBSD$ */
     
    -#include 
    -#include 
    -#include 
    -#include 
    +#include 
     #include 
    +#include 
    +#include 
    +#include 
    +#include 
     
     #define MQNAME	"/mytstqueue1"
     
    diff --git a/tools/regression/mqueue/mqtest2/mqtest2.c b/tools/regression/mqueue/mqtest2/mqtest2.c
    index f37af20c3ec..bfe6d97fc7d 100644
    --- a/tools/regression/mqueue/mqtest2/mqtest2.c
    +++ b/tools/regression/mqueue/mqtest2/mqtest2.c
    @@ -1,8 +1,13 @@
     /* $FreeBSD$ */
    -#include 
    -#include 
    +
    +#include 
    +#include 
    +#include 
     #include 
    +#include 
     #include 
    +#include 
    +#include 
     #include 
     
     #define MQNAME	"/mytstqueue2"
    diff --git a/tools/regression/mqueue/mqtest3/mqtest3.c b/tools/regression/mqueue/mqtest3/mqtest3.c
    index e2d8a9ef35a..aa47ffac309 100644
    --- a/tools/regression/mqueue/mqtest3/mqtest3.c
    +++ b/tools/regression/mqueue/mqtest3/mqtest3.c
    @@ -1,10 +1,15 @@
     /* $FreeBSD$ */
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    +
    +#include 
     #include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
     
     #define MQNAME	"/mytstqueue3"
     #define LOOPS	1000
    diff --git a/tools/regression/mqueue/mqtest4/mqtest4.c b/tools/regression/mqueue/mqtest4/mqtest4.c
    index a49c210a229..80a7f88d9ed 100644
    --- a/tools/regression/mqueue/mqtest4/mqtest4.c
    +++ b/tools/regression/mqueue/mqtest4/mqtest4.c
    @@ -1,11 +1,16 @@
     /* $FreeBSD$ */
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    +
    +#include 
     #include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
     
     #define MQNAME	"/mytstqueue4"
     #define LOOPS	1000
    diff --git a/tools/regression/mqueue/mqtest5/mqtest5.c b/tools/regression/mqueue/mqtest5/mqtest5.c
    index adf54dcc65a..354a7bb30ce 100644
    --- a/tools/regression/mqueue/mqtest5/mqtest5.c
    +++ b/tools/regression/mqueue/mqtest5/mqtest5.c
    @@ -1,12 +1,16 @@
     /* $FreeBSD$ */
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    +
    +#include 
     #include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
     #include 
    +#include 
    +#include 
    +#include 
     
     #define MQNAME	"/mytstqueue5"
     #define LOOPS	1000
    
    From 81484b9174609e1c7619e135f81778f2eecef89b Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Sat, 20 Mar 2010 14:49:44 +0000
    Subject: [PATCH 1618/2592] MFC
     r204082,204179,204180,204218,204241,204247,204270,204692:
    
    Provide thermal management and monitoring features in smu(4). This allows
    fan control and thermal monitoring on SMU-based Apple G5 machines, as well
    as an led(4) interface to control the sleep LED.
    ---
     share/man/man4/man4.powerpc/Makefile |   1 +
     share/man/man4/man4.powerpc/smu.4    | 125 +++++
     sys/powerpc/powermac/smu.c           | 807 ++++++++++++++++++++++++++-
     3 files changed, 908 insertions(+), 25 deletions(-)
     create mode 100644 share/man/man4/man4.powerpc/smu.4
    
    diff --git a/share/man/man4/man4.powerpc/Makefile b/share/man/man4/man4.powerpc/Makefile
    index d213d83fe68..57196a3b92b 100644
    --- a/share/man/man4/man4.powerpc/Makefile
    +++ b/share/man/man4/man4.powerpc/Makefile
    @@ -7,6 +7,7 @@ MAN=	adb.4 \
     	cuda.4 \
     	pmu.4 \
     	powermac_nvram.4 \
    +	smu.4 \
     	snd_ai2s.4 \
     	snd_davbus.4 \
     	tsec.4
    diff --git a/share/man/man4/man4.powerpc/smu.4 b/share/man/man4/man4.powerpc/smu.4
    new file mode 100644
    index 00000000000..893522c9c36
    --- /dev/null
    +++ b/share/man/man4/man4.powerpc/smu.4
    @@ -0,0 +1,125 @@
    +.\"-
    +.\" Copyright (c) 2010 Nathan Whitehorn 
    +.\" All rights reserved.
    +.\"
    +.\" Redistribution and use in source and binary forms, with or without
    +.\" modification, are permitted provided that the following conditions
    +.\" are met:
    +.\" 1. Redistributions of source code must retain the above copyright
    +.\"    notice, this list of conditions and the following disclaimer.
    +.\" 2. Redistributions in binary form must reproduce the above copyright
    +.\"    notice, this list of conditions and the following disclaimer in the
    +.\"    documentation and/or other materials provided with the distribution.
    +.\"
    +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    +.\" DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
    +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    +.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    +.\" POSSIBILITY OF SUCH DAMAGE.
    +.\"
    +.\" $FreeBSD$
    +.\"
    +.Dd February 22, 2010
    +.Dt SMU 4
    +.Os
    +.Sh NAME
    +.Nm smu
    +.Nd Apple System Management Unit Driver
    +.Sh SYNOPSIS
    +To compile this driver into the kernel,
    +place the following lines in your
    +kernel configuration file:
    +.Bd -ragged -offset indent
    +.Cd "device smu"
    +.Ed
    +.Sh DESCRIPTION
    +The
    +.Nm
    +driver provides support for the System Management Unit (SMU) found in many
    +Apple G5 systems.
    +This includes most Power Macintosh G5 and all iMac G5 systems.
    +.Pp
    +The Apple SMU controller provides software power management and thermal
    +control functionality, and is responsible for managing system cooling
    +devices.
    +.Sh HARDWARE
    +Chips supported by the
    +.Nm
    +driver include:
    +.Pp
    +.Bl -bullet -compact
    +.It
    +Apple System Management Unit
    +.El
    +.Sh THERMAL MANAGEMENT
    +The
    +.Nm
    +driver provides basic automatic thermal management. Without a userspace
    +daemon providing more advanced control, the driver will attempt to maintain
    +system temperatures in a conservative range through coarse-grained control of
    +system cooling devices (see below). Automatic kernel-level thermal control
    +will take over if more than 3 seconds elapses between userspace cooling
    +setting adjustments.
    +.Sh SYSCTL VARIABLES
    +The
    +.Nm
    +driver provides power management services and thermal readout through a
    +sysctl interface.
    +The following sysctls can be used to control the
    +power management behavior and to examine current system power and
    +thermal conditions.
    +.Bl -tag -width indent
    +.It Va dev.smu.%d.server_mode
    +Restart after power failure behavior (1 causes system to reboot after power
    +cut, 0 causes system to remain off).
    +.It Va dev.smu.%d.target_temp
    +Target system temperature, in degrees Celsius. The
    +.Nm
    +driver will attempt to adjust fans to maintain the temperature of the
    +warmest component in the system at or below this level.
    +.It Va dev.smu.%d.critical_temp
    +System critical temperature, in degrees Celsius. If any component in
    +the system exceeds this temperature, the machine will be shut down within
    +500 ms.
    +.It Va dev.smu.%d.fans.%s.minrpm
    +Minimum allowed speed for this fan.
    +.It Va dev.smu.%d.fans.%s.maxrpm
    +Maximum allowed speed for this fan.
    +.It Va dev.smu.%d.fans.%s.rpm
    +Current speed for this fan. The fan speed can be adjusted by changing this
    +sysctl. If more than 3 seconds elapses between fan speed adjustments, the
    +kernel will resume automatic control of the fan.
    +.It Va dev.smu.%d.sensors.%s
    +Current reading from this sensor. Four sensor types are supported. Temperature
    +sensors are in units of degrees Celsius, current sensors in milliamps, voltage
    +sensors in millivolts, and power sensors in milliwatts.
    +.El
    +.Sh LED INTERFACE
    +The
    +.Nm
    +driver provides an 
    +.Xr led 4
    +annunciator interface at
    +.Pa /dev/led/sleepled .
    +.Sh SEE ALSO
    +.Xr acpi 4 ,
    +.Xr pmu 4 ,
    +.Xr led 4
    +.Sh HISTORY
    +The
    +.Nm
    +device driver appeared in
    +.Fx 8.0 .
    +.Sh AUTHORS
    +.An -nosplit
    +The
    +.Nm
    +driver was written by
    +.An Nathan Whitehorn
    +.Aq nwhitehorn@FreeBSD.org .
    diff --git a/sys/powerpc/powermac/smu.c b/sys/powerpc/powermac/smu.c
    index 4d5e1c8fac5..6754b3ba7d1 100644
    --- a/sys/powerpc/powermac/smu.c
    +++ b/sys/powerpc/powermac/smu.c
    @@ -34,21 +34,53 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
    +#include 
    +#include 
     #include 
     #include 
    +#include 
     
     #include 
    +#include 
     #include 
     
    +#include 
     #include 
     #include 
     #include 
     
     struct smu_cmd {
    -	uint8_t		cmd;
    +	volatile uint8_t cmd;
     	uint8_t		len;
     	uint8_t		data[254];
    +
    +	STAILQ_ENTRY(smu_cmd) cmd_q;
    +};
    +
    +STAILQ_HEAD(smu_cmdq, smu_cmd);
    +
    +struct smu_fan {
    +	cell_t	reg;
    +	cell_t	min_rpm;
    +	cell_t	max_rpm;
    +	cell_t	unmanaged_rpm;
    +	char	location[32];
    +
    +	int	old_style;
    +	int	setpoint;
    +};
    +
    +struct smu_sensor {
    +	cell_t	reg;
    +	char	location[32];
    +	enum {
    +		SMU_CURRENT_SENSOR,
    +		SMU_VOLTAGE_SENSOR,
    +		SMU_POWER_SENSOR,
    +		SMU_TEMP_SENSOR
    +	} type;
     };
     
     struct smu_softc {
    @@ -62,9 +94,40 @@ struct smu_softc {
     	bus_space_tag_t	sc_bt;
     	bus_space_handle_t sc_mailbox;
     
    -	struct smu_cmd	*sc_cmd;
    +	struct smu_cmd	*sc_cmd, *sc_cur_cmd;
     	bus_addr_t	sc_cmd_phys;
     	bus_dmamap_t	sc_cmd_dmamap;
    +	struct smu_cmdq	sc_cmdq;
    +
    +	struct smu_fan	*sc_fans;
    +	int		sc_nfans;
    +	struct smu_sensor *sc_sensors;
    +	int		sc_nsensors;
    +
    +	int		sc_doorbellirqid;
    +	struct resource	*sc_doorbellirq;
    +	void		*sc_doorbellirqcookie;
    +
    +	struct proc	*sc_fanmgt_proc;
    +	time_t		sc_lastuserchange;
    +
    +	/* Calibration data */
    +	uint16_t	sc_cpu_diode_scale;
    +	int16_t		sc_cpu_diode_offset;
    +
    +	uint16_t	sc_cpu_volt_scale;
    +	int16_t		sc_cpu_volt_offset;
    +	uint16_t	sc_cpu_curr_scale;
    +	int16_t		sc_cpu_curr_offset;
    +
    +	uint16_t	sc_slots_pow_scale;
    +	int16_t		sc_slots_pow_offset;
    +
    +	/* Thermal management parameters */
    +	int		sc_target_temp;		/* Default 55 C */
    +	int		sc_critical_temp;	/* Default 90 C */
    +
    +	struct cdev 	*sc_leddev;
     };
     
     /* regular bus attachment functions */
    @@ -77,6 +140,18 @@ static int	smu_attach(device_t);
     static void	smu_cpufreq_pre_change(device_t, const struct cf_level *level);
     static void	smu_cpufreq_post_change(device_t, const struct cf_level *level);
     
    +/* utility functions */
    +static int	smu_run_cmd(device_t dev, struct smu_cmd *cmd, int wait);
    +static int	smu_get_datablock(device_t dev, int8_t id, uint8_t *buf,
    +		    size_t len);
    +static void	smu_attach_fans(device_t dev, phandle_t fanroot);
    +static void	smu_attach_sensors(device_t dev, phandle_t sensroot);
    +static void	smu_fan_management_proc(void *xdev);
    +static void	smu_manage_fans(device_t smu);
    +static void	smu_set_sleepled(void *xdev, int onoff);
    +static int	smu_server_mode(SYSCTL_HANDLER_ARGS);
    +static void	smu_doorbell_intr(void *xdev);
    +
     /* where to find the doorbell GPIO */
     
     static device_t	smu_doorbell = NULL;
    @@ -97,11 +172,43 @@ static driver_t smu_driver = {
     static devclass_t smu_devclass;
     
     DRIVER_MODULE(smu, nexus, smu_driver, smu_devclass, 0, 0);
    +MALLOC_DEFINE(M_SMU, "smu", "SMU Sensor Information");
     
    -#define SMU_MAILBOX	0x860c
    +#define SMU_MAILBOX		0x8000860c
    +#define SMU_FANMGT_INTERVAL	1000 /* ms */
     
     /* Command types */
    -#define SMU_POWER	0xaa
    +#define SMU_ADC			0xd8
    +#define SMU_FAN			0x4a
    +#define SMU_I2C			0x9a
    +#define  SMU_I2C_SIMPLE		0x00
    +#define  SMU_I2C_NORMAL		0x01
    +#define  SMU_I2C_COMBINED	0x02
    +#define SMU_MISC		0xee
    +#define  SMU_MISC_GET_DATA	0x02
    +#define  SMU_MISC_LED_CTRL	0x04
    +#define SMU_POWER		0xaa
    +#define SMU_POWER_EVENTS	0x8f
    +#define  SMU_PWR_GET_POWERUP	0x00
    +#define  SMU_PWR_SET_POWERUP	0x01
    +#define  SMU_PWR_CLR_POWERUP	0x02
    +
    +/* Power event types */
    +#define SMU_WAKEUP_KEYPRESS	0x01
    +#define SMU_WAKEUP_AC_INSERT	0x02
    +#define SMU_WAKEUP_AC_CHANGE	0x04
    +#define SMU_WAKEUP_RING		0x10
    +
    +/* Data blocks */
    +#define SMU_CPUTEMP_CAL		0x18
    +#define SMU_CPUVOLT_CAL		0x21
    +#define SMU_SLOTPW_CAL		0x78
    +
    +/* Partitions */
    +#define SMU_PARTITION		0x3e
    +#define SMU_PARTITION_LATEST	0x01
    +#define SMU_PARTITION_BASE	0x02
    +#define SMU_PARTITION_UPDATE	0x03
     
     static int
     smu_probe(device_t dev)
    @@ -127,10 +234,14 @@ static int
     smu_attach(device_t dev)
     {
     	struct smu_softc *sc;
    +	phandle_t	node, child;
    +	uint8_t		data[12];
     
     	sc = device_get_softc(dev);
     
     	mtx_init(&sc->sc_mtx, "smu", NULL, MTX_DEF);
    +	sc->sc_cur_cmd = NULL;
    +	sc->sc_doorbellirqid = -1;
     
     	/*
     	 * Map the mailbox area. This should be determined from firmware,
    @@ -139,7 +250,7 @@ smu_attach(device_t dev)
     	bus_dma_tag_create(NULL, 16, 0, BUS_SPACE_MAXADDR_32BIT,
     	    BUS_SPACE_MAXADDR, NULL, NULL, PAGE_SIZE, 1, PAGE_SIZE, 0, NULL,
     	    NULL, &(sc->sc_dmatag));
    -	sc->sc_bt = &bs_be_tag;
    +	sc->sc_bt = &bs_le_tag;
     	bus_space_map(sc->sc_bt, SMU_MAILBOX, 4, 0, &sc->sc_mailbox);
     
     	/*
    @@ -150,6 +261,7 @@ smu_attach(device_t dev)
     	    BUS_DMA_ZERO, &sc->sc_cmd_dmamap);
     	bus_dmamap_load(sc->sc_dmatag, sc->sc_cmd_dmamap,
     	    sc->sc_cmd, PAGE_SIZE, smu_phys_callback, sc, 0);
    +	STAILQ_INIT(&sc->sc_cmdq);
     
     	/*
     	 * Set up handlers to change CPU voltage when CPU frequency is changed.
    @@ -159,51 +271,241 @@ smu_attach(device_t dev)
     	EVENTHANDLER_REGISTER(cpufreq_post_change, smu_cpufreq_post_change, dev,
     	    EVENTHANDLER_PRI_ANY);
     
    +	/*
    +	 * Detect and attach child devices.
    +	 */
    +	node = ofw_bus_get_node(dev);
    +	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
    +		char name[32];
    +		memset(name, 0, sizeof(name));
    +		OF_getprop(child, "name", name, sizeof(name));
    +
    +		if (strncmp(name, "rpm-fans", 9) == 0 ||
    +		    strncmp(name, "fans", 5) == 0)
    +			smu_attach_fans(dev, child);
    +
    +		if (strncmp(name, "sensors", 8) == 0)
    +			smu_attach_sensors(dev, child);
    +	}
    +
    +	/*
    +	 * Collect calibration constants.
    +	 */
    +	smu_get_datablock(dev, SMU_CPUTEMP_CAL, data, sizeof(data));
    +	sc->sc_cpu_diode_scale = (data[4] << 8) + data[5];
    +	sc->sc_cpu_diode_offset = (data[6] << 8) + data[7];
    +
    +	smu_get_datablock(dev, SMU_CPUVOLT_CAL, data, sizeof(data));
    +	sc->sc_cpu_volt_scale = (data[4] << 8) + data[5];
    +	sc->sc_cpu_volt_offset = (data[6] << 8) + data[7];
    +	sc->sc_cpu_curr_scale = (data[8] << 8) + data[9];
    +	sc->sc_cpu_curr_offset = (data[10] << 8) + data[11];
    +
    +	smu_get_datablock(dev, SMU_SLOTPW_CAL, data, sizeof(data));
    +	sc->sc_slots_pow_scale = (data[4] << 8) + data[5];
    +	sc->sc_slots_pow_offset = (data[6] << 8) + data[7];
    +
    +	/*
    +	 * Set up simple-minded thermal management.
    +	 */
    +	sc->sc_target_temp = 55;
    +	sc->sc_critical_temp = 90;
    +
    +	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    +	    "target_temp", CTLTYPE_INT | CTLFLAG_RW, &sc->sc_target_temp,
    +	    sizeof(int), "Target temperature (C)");
    +	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    +	    "critical_temp", CTLTYPE_INT | CTLFLAG_RW,
    +	    &sc->sc_critical_temp, sizeof(int), "Critical temperature (C)");
    +
    +	kproc_create(smu_fan_management_proc, dev, &sc->sc_fanmgt_proc,
    +	    RFHIGHPID, 0, "smu_thermal");
    +
    +	/*
    +	 * Set up LED interface
    +	 */
    +	sc->sc_leddev = led_create(smu_set_sleepled, dev, "sleepled");
    +
    +	/*
    +	 * Reset on power loss behavior
    +	 */
    +
    +	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
    +            SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    +	    "server_mode", CTLTYPE_INT | CTLFLAG_RW, dev, 0,
    +	    smu_server_mode, "I", "Enable reboot after power failure");
    +
    +	/*
    +	 * Set up doorbell interrupt.
    +	 */
    +	sc->sc_doorbellirqid = 0;
    +	sc->sc_doorbellirq = bus_alloc_resource_any(smu_doorbell, SYS_RES_IRQ,
    +	    &sc->sc_doorbellirqid, RF_ACTIVE);
    +	bus_setup_intr(smu_doorbell, sc->sc_doorbellirq,
    +	    INTR_TYPE_MISC | INTR_MPSAFE, NULL, smu_doorbell_intr, dev,
    +	    &sc->sc_doorbellirqcookie);
    +	powerpc_config_intr(rman_get_start(sc->sc_doorbellirq),
    +	    INTR_TRIGGER_EDGE, INTR_POLARITY_LOW);
    +
     	return (0);
     }
     
    -static int
    -smu_run_cmd(device_t dev, struct smu_cmd *cmd)
    +static void
    +smu_send_cmd(device_t dev, struct smu_cmd *cmd)
     {
     	struct smu_softc *sc;
    -	int doorbell_ack, result;
     
     	sc = device_get_softc(dev);
     
    -	mtx_lock(&sc->sc_mtx);
    +	mtx_assert(&sc->sc_mtx, MA_OWNED);
    +
    +	powerpc_pow_enabled = 0;	/* SMU cannot work if we go to NAP */
    +	sc->sc_cur_cmd = cmd;
     
     	/* Copy the command to the mailbox */
    -	memcpy(sc->sc_cmd, cmd, sizeof(*cmd));
    +	sc->sc_cmd->cmd = cmd->cmd;
    +	sc->sc_cmd->len = cmd->len;
    +	memcpy(sc->sc_cmd->data, cmd->data, sizeof(cmd->data));
     	bus_dmamap_sync(sc->sc_dmatag, sc->sc_cmd_dmamap, BUS_DMASYNC_PREWRITE);
     	bus_space_write_4(sc->sc_bt, sc->sc_mailbox, 0, sc->sc_cmd_phys);
     
    -	/* Invalidate the cacheline it is in -- SMU bypasses the cache */
    -	__asm __volatile("dcbst 0,%0; sync" :: "r"(sc->sc_cmd): "memory");
    +	/* Flush the cacheline it is in -- SMU bypasses the cache */
    +	__asm __volatile("sync; dcbf 0,%0; sync" :: "r"(sc->sc_cmd): "memory");
     
     	/* Ring SMU doorbell */
     	macgpio_write(smu_doorbell, GPIO_DDR_OUTPUT);
    +}
     
    -	/* Wait for the doorbell GPIO to go high, signaling completion */
    -	do {
    -		/* XXX: timeout */
    -		DELAY(50);
    -		doorbell_ack = macgpio_read(smu_doorbell);
    -	} while (!doorbell_ack);
    +static void
    +smu_doorbell_intr(void *xdev)
    +{
    +	device_t smu;
    +	struct smu_softc *sc;
    +	int doorbell_ack;
    +
    +	smu = xdev;
    +	doorbell_ack = macgpio_read(smu_doorbell);
    +	sc = device_get_softc(smu);
    +
    +	if (doorbell_ack != (GPIO_DDR_OUTPUT | GPIO_LEVEL_RO | GPIO_DATA)) 
    +		return;
    +
    +	mtx_lock(&sc->sc_mtx);
    +
    +	if (sc->sc_cur_cmd == NULL)	/* spurious */
    +		goto done;
     
     	/* Check result. First invalidate the cache again... */
     	__asm __volatile("dcbf 0,%0; sync" :: "r"(sc->sc_cmd) : "memory");
     	
     	bus_dmamap_sync(sc->sc_dmatag, sc->sc_cmd_dmamap, BUS_DMASYNC_POSTREAD);
     
    -	/* SMU acks the command by inverting the command bits */
    -	if (sc->sc_cmd->cmd == ~cmd->cmd)
    -		result = 0;
    -	else
    -		result = EIO;
    +	sc->sc_cur_cmd->cmd = sc->sc_cmd->cmd;
    +	sc->sc_cur_cmd->len = sc->sc_cmd->len;
    +	memcpy(sc->sc_cur_cmd->data, sc->sc_cmd->data,
    +	    sizeof(sc->sc_cmd->data));
    +	wakeup(sc->sc_cur_cmd);
    +	sc->sc_cur_cmd = NULL;
    +	powerpc_pow_enabled = 1;
    +
    +    done:
    +	/* Queue next command if one is pending */
    +	if (STAILQ_FIRST(&sc->sc_cmdq) != NULL) {
    +		sc->sc_cur_cmd = STAILQ_FIRST(&sc->sc_cmdq);
    +		STAILQ_REMOVE_HEAD(&sc->sc_cmdq, cmd_q);
    +		smu_send_cmd(smu, sc->sc_cur_cmd);
    +	}
     
     	mtx_unlock(&sc->sc_mtx);
    +}
     
    -	return (result);
    +static int
    +smu_run_cmd(device_t dev, struct smu_cmd *cmd, int wait)
    +{
    +	struct smu_softc *sc;
    +	uint8_t cmd_code;
    +	int error;
    +
    +	sc = device_get_softc(dev);
    +	cmd_code = cmd->cmd;
    +
    +	mtx_lock(&sc->sc_mtx);
    +	if (sc->sc_cur_cmd != NULL) {
    +		STAILQ_INSERT_TAIL(&sc->sc_cmdq, cmd, cmd_q);
    +	} else
    +		smu_send_cmd(dev, cmd);
    +	mtx_unlock(&sc->sc_mtx);
    +
    +	if (!wait)
    +		return (0);
    +
    +	if (sc->sc_doorbellirqid < 0) {
    +		/* Poll if the IRQ has not been set up yet */
    +		do {
    +			DELAY(50);
    +			smu_doorbell_intr(dev);
    +		} while (sc->sc_cur_cmd != NULL);
    +	} else {
    +		/* smu_doorbell_intr will wake us when the command is ACK'ed */
    +		error = tsleep(cmd, 0, "smu", 800 * hz / 1000);
    +		if (error != 0)
    +			smu_doorbell_intr(dev);	/* One last chance */
    +		
    +		if (error != 0) {
    +		    mtx_lock(&sc->sc_mtx);
    +		    if (cmd->cmd == cmd_code) {	/* Never processed */
    +			/* Abort this command if we timed out */
    +			if (sc->sc_cur_cmd == cmd)
    +				sc->sc_cur_cmd = NULL;
    +			else
    +				STAILQ_REMOVE(&sc->sc_cmdq, cmd, smu_cmd,
    +				    cmd_q);
    +			mtx_unlock(&sc->sc_mtx);
    +			return (error);
    +		    }
    +		    error = 0;
    +		    mtx_unlock(&sc->sc_mtx);
    +		}
    +	}
    +
    +	/* SMU acks the command by inverting the command bits */
    +	if (cmd->cmd == ((~cmd_code) & 0xff))
    +		error = 0;
    +	else
    +		error = EIO;
    +
    +	return (error);
    +}
    +
    +static int
    +smu_get_datablock(device_t dev, int8_t id, uint8_t *buf, size_t len)
    +{
    +	struct smu_cmd cmd;
    +	uint8_t addr[4];
    +
    +	cmd.cmd = SMU_PARTITION;
    +	cmd.len = 2;
    +	cmd.data[0] = SMU_PARTITION_LATEST;
    +	cmd.data[1] = id; 
    +
    +	smu_run_cmd(dev, &cmd, 1);
    +
    +	addr[0] = addr[1] = 0;
    +	addr[2] = cmd.data[0];
    +	addr[3] = cmd.data[1];
    +
    +	cmd.cmd = SMU_MISC;
    +	cmd.len = 7;
    +	cmd.data[0] = SMU_MISC_GET_DATA;
    +	cmd.data[1] = sizeof(addr);
    +	memcpy(&cmd.data[2], addr, sizeof(addr));
    +	cmd.data[6] = len;
    +
    +	smu_run_cmd(dev, &cmd, 1);
    +	memcpy(buf, cmd.data, len);
    +	return (0);
     }
     
     static void
    @@ -222,7 +524,7 @@ smu_slew_cpu_voltage(device_t dev, int to)
     	cmd.data[6] = 1;
     	cmd.data[7] = to;
     
    -	smu_run_cmd(dev, &cmd);
    +	smu_run_cmd(dev, &cmd, 1);
     }
     
     static void
    @@ -286,3 +588,458 @@ doorbell_attach(device_t dev)
     	smu_doorbell = dev;
     	return (0);
     }
    +
    +/*
    + * Sensor and fan management
    + */
    +
    +static int
    +smu_fan_set_rpm(device_t smu, struct smu_fan *fan, int rpm)
    +{
    +	struct smu_cmd cmd;
    +	int error;
    +
    +	cmd.cmd = SMU_FAN;
    +	error = EIO;
    +
    +	/* Clamp to allowed range */
    +	rpm = max(fan->min_rpm, rpm);
    +	rpm = min(fan->max_rpm, rpm);
    +
    +	/*
    +	 * Apple has two fan control mechanisms. We can't distinguish
    +	 * them except by seeing if the new one fails. If the new one
    +	 * fails, use the old one.
    +	 */
    +	
    +	if (!fan->old_style) {
    +		cmd.len = 4;
    +		cmd.data[0] = 0x30;
    +		cmd.data[1] = fan->reg;
    +		cmd.data[2] = (rpm >> 8) & 0xff;
    +		cmd.data[3] = rpm & 0xff;
    +	
    +		error = smu_run_cmd(smu, &cmd, 1);
    +		if (error)
    +			fan->old_style = 1;
    +	}
    +
    +	if (fan->old_style) {
    +		cmd.len = 14;
    +		cmd.data[0] = 0;
    +		cmd.data[1] = 1 << fan->reg;
    +		cmd.data[2 + 2*fan->reg] = (rpm >> 8) & 0xff;
    +		cmd.data[3 + 2*fan->reg] = rpm & 0xff;
    +		error = smu_run_cmd(smu, &cmd, 1);
    +	}
    +
    +	if (error == 0)
    +		fan->setpoint = rpm;
    +
    +	return (error);
    +}
    +
    +static int
    +smu_fan_read_rpm(device_t smu, struct smu_fan *fan)
    +{
    +	struct smu_cmd cmd;
    +
    +	cmd.cmd = SMU_FAN;
    +	cmd.len = 1;
    +	cmd.data[0] = 1;
    +
    +	smu_run_cmd(smu, &cmd, 1);
    +
    +	return ((cmd.data[fan->reg*2+1] << 8) | cmd.data[fan->reg*2+2]);
    +}
    +
    +static int
    +smu_fanrpm_sysctl(SYSCTL_HANDLER_ARGS)
    +{
    +	device_t smu;
    +	struct smu_softc *sc;
    +	struct smu_fan *fan;
    +	int rpm, error;
    +
    +	smu = arg1;
    +	sc = device_get_softc(smu);
    +	fan = &sc->sc_fans[arg2];
    +
    +	rpm = smu_fan_read_rpm(smu, fan);
    +	error = sysctl_handle_int(oidp, &rpm, 0, req);
    +
    +	if (error || !req->newptr)
    +		return (error);
    +
    +	sc->sc_lastuserchange = time_uptime;
    +
    +	return (smu_fan_set_rpm(smu, fan, rpm));
    +}
    +
    +static void
    +smu_attach_fans(device_t dev, phandle_t fanroot)
    +{
    +	struct smu_fan *fan;
    +	struct smu_softc *sc;
    +	struct sysctl_oid *oid, *fanroot_oid;
    +	struct sysctl_ctx_list *ctx;
    +	phandle_t child;
    +	char type[32], sysctl_name[32];
    +	int i;
    +
    +	sc = device_get_softc(dev);
    +	sc->sc_nfans = 0;
    +
    +	for (child = OF_child(fanroot); child != 0; child = OF_peer(child))
    +		sc->sc_nfans++;
    +
    +	if (sc->sc_nfans == 0) {
    +		device_printf(dev, "WARNING: No fans detected!\n");
    +		return;
    +	}
    +
    +	sc->sc_fans = malloc(sc->sc_nfans * sizeof(struct smu_fan), M_SMU,
    +	    M_WAITOK | M_ZERO);
    +
    +	fan = sc->sc_fans;
    +	sc->sc_nfans = 0;
    +
    +	ctx = device_get_sysctl_ctx(dev);
    +	fanroot_oid = SYSCTL_ADD_NODE(ctx,
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "fans",
    +	    CTLFLAG_RD, 0, "SMU Fan Information");
    +
    +	for (child = OF_child(fanroot); child != 0; child = OF_peer(child)) {
    +		OF_getprop(child, "device_type", type, sizeof(type));
    +		if (strcmp(type, "fan-rpm-control") != 0)
    +			continue;
    +
    +		fan->old_style = 0;
    +		OF_getprop(child, "reg", &fan->reg, sizeof(cell_t));
    +		OF_getprop(child, "min-value", &fan->min_rpm, sizeof(cell_t));
    +		OF_getprop(child, "max-value", &fan->max_rpm, sizeof(cell_t));
    +
    +		if (OF_getprop(child, "unmanaged-value", &fan->unmanaged_rpm,
    +		    sizeof(cell_t)) != sizeof(cell_t))
    +			fan->unmanaged_rpm = fan->max_rpm;
    +
    +		fan->setpoint = smu_fan_read_rpm(dev, fan);
    +
    +		OF_getprop(child, "location", fan->location,
    +		    sizeof(fan->location));
    +	
    +		/* Add sysctls */
    +		for (i = 0; i < strlen(fan->location); i++) {
    +			sysctl_name[i] = tolower(fan->location[i]);
    +			if (isspace(sysctl_name[i]))
    +				sysctl_name[i] = '_';
    +		}
    +		sysctl_name[i] = 0;
    +
    +		oid = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(fanroot_oid),
    +		    OID_AUTO, sysctl_name, CTLFLAG_RD, 0, "Fan Information");
    +		SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "minrpm",
    +		    CTLTYPE_INT | CTLFLAG_RD, &fan->min_rpm, sizeof(cell_t),
    +		    "Minimum allowed RPM");
    +		SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "maxrpm",
    +		    CTLTYPE_INT | CTLFLAG_RD, &fan->max_rpm, sizeof(cell_t),
    +		    "Maximum allowed RPM");
    +		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "rpm",
    +		    CTLTYPE_INT | CTLFLAG_RW, dev, sc->sc_nfans,
    +		    smu_fanrpm_sysctl, "I", "Fan RPM");
    +
    +		fan++;
    +		sc->sc_nfans++;
    +	}
    +}
    +
    +static int
    +smu_sensor_read(device_t smu, struct smu_sensor *sens, int *val)
    +{
    +	struct smu_cmd cmd;
    +	struct smu_softc *sc;
    +	int64_t value;
    +	int error;
    +
    +	cmd.cmd = SMU_ADC;
    +	cmd.len = 1;
    +	cmd.data[0] = sens->reg;
    +	error = 0;
    +
    +	error = smu_run_cmd(smu, &cmd, 1);
    +	if (error != 0)
    +		return (error);
    +	
    +	sc = device_get_softc(smu);
    +	value = (cmd.data[0] << 8) | cmd.data[1];
    +
    +	switch (sens->type) {
    +	case SMU_TEMP_SENSOR:
    +		value *= sc->sc_cpu_diode_scale;
    +		value >>= 3;
    +		value += ((int64_t)sc->sc_cpu_diode_offset) << 9;
    +		value <<= 1;
    +
    +		/* Convert from 16.16 fixed point degC into integer C. */
    +		value >>= 16;
    +		break;
    +	case SMU_VOLTAGE_SENSOR:
    +		value *= sc->sc_cpu_volt_scale;
    +		value += sc->sc_cpu_volt_offset;
    +		value <<= 4;
    +
    +		/* Convert from 16.16 fixed point V into mV. */
    +		value *= 15625;
    +		value /= 1024;
    +		value /= 1000;
    +		break;
    +	case SMU_CURRENT_SENSOR:
    +		value *= sc->sc_cpu_curr_scale;
    +		value += sc->sc_cpu_curr_offset;
    +		value <<= 4;
    +
    +		/* Convert from 16.16 fixed point A into mA. */
    +		value *= 15625;
    +		value /= 1024;
    +		value /= 1000;
    +		break;
    +	case SMU_POWER_SENSOR:
    +		value *= sc->sc_slots_pow_scale;
    +		value += sc->sc_slots_pow_offset;
    +		value <<= 4;
    +
    +		/* Convert from 16.16 fixed point W into mW. */
    +		value *= 15625;
    +		value /= 1024;
    +		value /= 1000;
    +		break;
    +	}
    +
    +	*val = value;
    +	return (0);
    +}
    +
    +static int
    +smu_sensor_sysctl(SYSCTL_HANDLER_ARGS)
    +{
    +	device_t smu;
    +	struct smu_softc *sc;
    +	struct smu_sensor *sens;
    +	int value, error;
    +
    +	smu = arg1;
    +	sc = device_get_softc(smu);
    +	sens = &sc->sc_sensors[arg2];
    +
    +	error = smu_sensor_read(smu, sens, &value);
    +	if (error != 0)
    +		return (error);
    +
    +	error = sysctl_handle_int(oidp, &value, 0, req);
    +
    +	return (error);
    +}
    +
    +static void
    +smu_attach_sensors(device_t dev, phandle_t sensroot)
    +{
    +	struct smu_sensor *sens;
    +	struct smu_softc *sc;
    +	struct sysctl_oid *sensroot_oid;
    +	struct sysctl_ctx_list *ctx;
    +	phandle_t child;
    +	char type[32];
    +	int i;
    +
    +	sc = device_get_softc(dev);
    +	sc->sc_nsensors = 0;
    +
    +	for (child = OF_child(sensroot); child != 0; child = OF_peer(child))
    +		sc->sc_nsensors++;
    +
    +	if (sc->sc_nsensors == 0) {
    +		device_printf(dev, "WARNING: No sensors detected!\n");
    +		return;
    +	}
    +
    +	sc->sc_sensors = malloc(sc->sc_nsensors * sizeof(struct smu_sensor),
    +	    M_SMU, M_WAITOK | M_ZERO);
    +
    +	sens = sc->sc_sensors;
    +	sc->sc_nsensors = 0;
    +
    +	ctx = device_get_sysctl_ctx(dev);
    +	sensroot_oid = SYSCTL_ADD_NODE(ctx,
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "sensors",
    +	    CTLFLAG_RD, 0, "SMU Sensor Information");
    +
    +	for (child = OF_child(sensroot); child != 0; child = OF_peer(child)) {
    +		char sysctl_name[40], sysctl_desc[40];
    +		const char *units;
    +
    +		OF_getprop(child, "device_type", type, sizeof(type));
    +
    +		if (strcmp(type, "current-sensor") == 0) {
    +			sens->type = SMU_CURRENT_SENSOR;
    +			units = "mA";
    +		} else if (strcmp(type, "temp-sensor") == 0) {
    +			sens->type = SMU_TEMP_SENSOR;
    +			units = "C";
    +		} else if (strcmp(type, "voltage-sensor") == 0) {
    +			sens->type = SMU_VOLTAGE_SENSOR;
    +			units = "mV";
    +		} else if (strcmp(type, "power-sensor") == 0) {
    +			sens->type = SMU_POWER_SENSOR;
    +			units = "mW";
    +		} else {
    +			continue;
    +		}
    +
    +		OF_getprop(child, "reg", &sens->reg, sizeof(cell_t));
    +		OF_getprop(child, "location", sens->location,
    +		    sizeof(sens->location));
    +
    +		for (i = 0; i < strlen(sens->location); i++) {
    +			sysctl_name[i] = tolower(sens->location[i]);
    +			if (isspace(sysctl_name[i]))
    +				sysctl_name[i] = '_';
    +		}
    +		sysctl_name[i] = 0;
    +
    +		sprintf(sysctl_desc,"%s (%s)", sens->location, units);
    +
    +		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(sensroot_oid), OID_AUTO,
    +		    sysctl_name, CTLTYPE_INT | CTLFLAG_RD, dev, sc->sc_nsensors,
    +		    smu_sensor_sysctl, "I", sysctl_desc);
    +
    +		sens++;
    +		sc->sc_nsensors++;
    +	}
    +}
    +
    +static void
    +smu_fan_management_proc(void *xdev)
    +{
    +	device_t smu = xdev;
    +
    +	while(1) {
    +		smu_manage_fans(smu);
    +		pause("smu", SMU_FANMGT_INTERVAL * hz / 1000);
    +	}
    +}
    +
    +static void
    +smu_manage_fans(device_t smu)
    +{
    +	struct smu_softc *sc;
    +	int i, maxtemp, temp, factor, error;
    +
    +	sc = device_get_softc(smu);
    +
    +	maxtemp = 0;
    +	for (i = 0; i < sc->sc_nsensors; i++) {
    +		if (sc->sc_sensors[i].type != SMU_TEMP_SENSOR)
    +			continue;
    +
    +		error = smu_sensor_read(smu, &sc->sc_sensors[i], &temp);
    +		if (error == 0 && temp > maxtemp)
    +			maxtemp = temp;
    +	}
    +
    +	if (maxtemp < 10) { /* Bail if no good sensors */
    +		for (i = 0; i < sc->sc_nfans; i++) 
    +			smu_fan_set_rpm(smu, &sc->sc_fans[i],
    +			    sc->sc_fans[i].unmanaged_rpm);
    +		return;
    +	}
    +
    +	if (maxtemp > sc->sc_critical_temp) {
    +		device_printf(smu, "WARNING: Current system temperature (%d C) "
    +		    "exceeds critical temperature (%d C)! Shutting down!\n",
    +		    maxtemp, sc->sc_critical_temp);
    +		shutdown_nice(RB_POWEROFF);
    +	}
    +
    +	if (maxtemp - sc->sc_target_temp > 20)
    +		device_printf(smu, "WARNING: Current system temperature (%d C) "
    +		    "more than 20 degrees over target temperature (%d C)!\n",
    +		    maxtemp, sc->sc_target_temp);
    +
    +	if (time_uptime - sc->sc_lastuserchange < 3) {
    +		/*
    +		 * If we have heard from a user process in the last 3 seconds,
    +		 * go away.
    +		 */
    +
    +		return;
    +	}
    +
    +	if (maxtemp - sc->sc_target_temp > 4) 
    +		factor = 110;
    +	else if (maxtemp - sc->sc_target_temp > 1) 
    +		factor = 105;
    +	else if (sc->sc_target_temp - maxtemp > 4) 
    +		factor = 90;
    +	else if (sc->sc_target_temp - maxtemp > 1) 
    +		factor = 95;
    +	else
    +		factor = 100;
    +
    +	for (i = 0; i < sc->sc_nfans; i++) 
    +		smu_fan_set_rpm(smu, &sc->sc_fans[i],
    +		    (sc->sc_fans[i].setpoint * factor) / 100);
    +}
    +
    +static void
    +smu_set_sleepled(void *xdev, int onoff)
    +{
    +	static struct smu_cmd cmd;
    +	device_t smu = xdev;
    +
    +	cmd.cmd = SMU_MISC;
    +	cmd.len = 3;
    +	cmd.data[0] = SMU_MISC_LED_CTRL;
    +	cmd.data[1] = 0;
    +	cmd.data[2] = onoff; 
    +
    +	smu_run_cmd(smu, &cmd, 0);
    +}
    +
    +static int
    +smu_server_mode(SYSCTL_HANDLER_ARGS)
    +{
    +	struct smu_cmd cmd;
    +	u_int server_mode;
    +	device_t smu = arg1;
    +	int error;
    +	
    +	cmd.cmd = SMU_POWER_EVENTS;
    +	cmd.len = 1;
    +	cmd.data[0] = SMU_PWR_GET_POWERUP;
    +
    +	error = smu_run_cmd(smu, &cmd, 1);
    +
    +	if (error)
    +		return (error);
    +
    +	server_mode = (cmd.data[1] & SMU_WAKEUP_AC_INSERT) ? 1 : 0;
    +
    +	error = sysctl_handle_int(oidp, &server_mode, 0, req);
    +
    +	if (error || !req->newptr)
    +		return (error);
    +
    +	if (server_mode == 1)
    +		cmd.data[0] = SMU_PWR_SET_POWERUP;
    +	else if (server_mode == 0)
    +		cmd.data[0] = SMU_PWR_CLR_POWERUP;
    +	else
    +		return (EINVAL);
    +
    +	cmd.len = 3;
    +	cmd.data[1] = 0;
    +	cmd.data[2] = SMU_WAKEUP_AC_INSERT;
    +
    +	return (smu_run_cmd(smu, &cmd, 1));
    +}
    +
    
    From 006e2f2ce58226e71ac05c787a851bbaaff177db Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Sat, 20 Mar 2010 14:55:22 +0000
    Subject: [PATCH 1619/2592] MFC r204903:
    
    Place interrupt handling in a critical section and remove double
    counting in incrementing the interrupt nesting level. This fixes a number
    of bugs in which the interrupt thread could be preempted by an IPI,
    indefinitely delaying acknowledgement of the interrupt to the PIC, causing
    interrupt starvation and hangs.
    
    Reported by:	linimon
    Reviewed by:	marcel, jhb
    ---
     sys/powerpc/aim/interrupt.c   | 6 ++++--
     sys/powerpc/booke/interrupt.c | 8 ++++----
     2 files changed, 8 insertions(+), 6 deletions(-)
    
    diff --git a/sys/powerpc/aim/interrupt.c b/sys/powerpc/aim/interrupt.c
    index d7f489ad4e2..b4360384155 100644
    --- a/sys/powerpc/aim/interrupt.c
    +++ b/sys/powerpc/aim/interrupt.c
    @@ -80,15 +80,17 @@ powerpc_interrupt(struct trapframe *framep)
     
     	switch (framep->exc) {
     	case EXC_EXI:
    -		atomic_add_int(&td->td_intr_nesting_level, 1);
    +		critical_enter();
     		PIC_DISPATCH(pic, framep);
    -		atomic_subtract_int(&td->td_intr_nesting_level, 1);	
    +		critical_exit();
     		break;
     
     	case EXC_DECR:
    +		critical_enter();
     		atomic_add_int(&td->td_intr_nesting_level, 1);
     		decr_intr(framep);
     		atomic_subtract_int(&td->td_intr_nesting_level, 1);	
    +		critical_exit();
     		break;
     
     	default:
    diff --git a/sys/powerpc/booke/interrupt.c b/sys/powerpc/booke/interrupt.c
    index 01ee3d9fa83..2367bf94b33 100644
    --- a/sys/powerpc/booke/interrupt.c
    +++ b/sys/powerpc/booke/interrupt.c
    @@ -118,9 +118,11 @@ powerpc_decr_interrupt(struct trapframe *framep)
     	struct thread *td;
     
     	td = PCPU_GET(curthread);
    +	critical_enter();
     	atomic_add_int(&td->td_intr_nesting_level, 1);
     	decr_intr(framep);
     	atomic_subtract_int(&td->td_intr_nesting_level, 1);
    +	critical_exit();
     }
     
     /*
    @@ -129,10 +131,8 @@ powerpc_decr_interrupt(struct trapframe *framep)
     void
     powerpc_extr_interrupt(struct trapframe *framep)
     {
    -	struct thread *td;
     
    -	td = PCPU_GET(curthread);
    -	atomic_add_int(&td->td_intr_nesting_level, 1);
    +	critical_enter();
     	PIC_DISPATCH(pic, framep);
    -	atomic_subtract_int(&td->td_intr_nesting_level, 1);
    +	critical_exit();
     }
    
    From 6f88556c522708afcb9341e169d1477fe60a9d4c Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Sat, 20 Mar 2010 15:05:44 +0000
    Subject: [PATCH 1620/2592] Fix a bug where pages being removed from memory
     entirely no longer have PVOs, and so the modified state of the page can no
     longer be communicated to the VM layer, causing pages not to be flushed to
     swap when needed, in turn causing memory corruption. Also make several
     correctness adjustments to I-Cache synchronization and TLB invalidation for
     64-bit Book-S CPUs.
    
    Obtained from:	projects/ppc64
    Discussed with:	grehan
    ---
     sys/powerpc/aim/mmu_oea.c   |  6 ++-
     sys/powerpc/aim/mmu_oea64.c | 83 ++++++++++++++-----------------------
     2 files changed, 36 insertions(+), 53 deletions(-)
    
    diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
    index 597f9258076..5caa3b9707f 100644
    --- a/sys/powerpc/aim/mmu_oea.c
    +++ b/sys/powerpc/aim/mmu_oea.c
    @@ -1729,6 +1729,10 @@ moea_remove_all(mmu_t mmu, vm_page_t m)
     		moea_pvo_remove(pvo, -1);
     		PMAP_UNLOCK(pmap);
     	}
    +	if ((m->flags & PG_WRITEABLE) && moea_is_modified(mmu, m)) {
    +		moea_attr_clear(m, LPTE_CHG);
    +		vm_page_dirty(m);
    +	}
     	vm_page_flag_clear(m, PG_WRITEABLE);
     }
     
    @@ -2203,10 +2207,8 @@ moea_query_bit(vm_page_t m, int ptebit)
     	struct	pvo_entry *pvo;
     	struct	pte *pt;
     
    -#if 0
     	if (moea_attr_fetch(m) & ptebit)
     		return (TRUE);
    -#endif
     
     	LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
     		MOEA_PVO_CHECK(pvo);	/* sanity check */
    diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
    index f83cd1436a0..ebe7361b6b2 100644
    --- a/sys/powerpc/aim/mmu_oea64.c
    +++ b/sys/powerpc/aim/mmu_oea64.c
    @@ -172,6 +172,7 @@ va_to_vsid(pmap_t pm, vm_offset_t va)
     	return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK);
     }
     
    +#define	PTESYNC()	__asm __volatile("ptesync");
     #define	TLBSYNC()	__asm __volatile("tlbsync; ptesync");
     #define	SYNC()		__asm __volatile("sync");
     #define	EIEIO()		__asm __volatile("eieio");
    @@ -194,6 +195,7 @@ TLBIE(pmap_t pmap, vm_offset_t va) {
     	vpn = (uint64_t)(va & ADDR_PIDX);
     	if (pmap != NULL)
     		vpn |= (va_to_vsid(pmap,va) << 28);
    +	vpn &= ~(0xffffULL << 48);
     
     	vpn_hi = (uint32_t)(vpn >> 32);
     	vpn_lo = (uint32_t)vpn;
    @@ -201,8 +203,7 @@ TLBIE(pmap_t pmap, vm_offset_t va) {
     	mtx_lock_spin(&tlbie_mutex);
     	__asm __volatile("\
     	    mfmsr %0; \
    -	    clrldi %1,%0,49; \
    -	    mtmsr %1; \
    +	    mr %1, %0; \
     	    insrdi %1,%5,1,0; \
     	    mtmsrd %1; \
     	    ptesync; \
    @@ -215,7 +216,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"(1));
    +	: "=r"(msr), "=r"(scratch) : "r"(vpn_hi), "r"(vpn_lo), "r"(32), "r"(1)
    +	    : "memory");
     	mtx_unlock_spin(&tlbie_mutex);
     }
     
    @@ -226,13 +228,13 @@ TLBIE(pmap_t pmap, vm_offset_t va) {
     #define	VSID_TO_SR(vsid)	((vsid) & 0xf)
     #define	VSID_TO_HASH(vsid)	(((vsid) >> 4) & 0xfffff)
     
    -#define	PVO_PTEGIDX_MASK	0x007		/* which PTEG slot */
    -#define	PVO_PTEGIDX_VALID	0x008		/* slot is valid */
    -#define	PVO_WIRED		0x010		/* PVO entry is wired */
    -#define	PVO_MANAGED		0x020		/* PVO entry is managed */
    -#define	PVO_BOOTSTRAP		0x080		/* PVO entry allocated during
    +#define	PVO_PTEGIDX_MASK	0x007UL		/* which PTEG slot */
    +#define	PVO_PTEGIDX_VALID	0x008UL		/* slot is valid */
    +#define	PVO_WIRED		0x010UL		/* PVO entry is wired */
    +#define	PVO_MANAGED		0x020UL		/* PVO entry is managed */
    +#define	PVO_BOOTSTRAP		0x080UL		/* PVO entry allocated during
     						   bootstrap */
    -#define PVO_FAKE		0x100		/* fictitious phys page */
    +#define PVO_FAKE		0x100UL		/* fictitious phys page */
     #define	PVO_VADDR(pvo)		((pvo)->pvo_vaddr & ~ADDR_POFF)
     #define PVO_ISFAKE(pvo)		((pvo)->pvo_vaddr & PVO_FAKE)
     #define	PVO_PTEGIDX_GET(pvo)	((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK)
    @@ -512,23 +514,6 @@ moea64_attr_save(vm_page_t m, u_int64_t ptebit)
     	m->md.mdpg_attrs |= ptebit;
     }
     
    -static __inline int
    -moea64_pte_compare(const struct lpte *pt, const struct lpte *pvo_pt)
    -{
    -	if (pt->pte_hi == pvo_pt->pte_hi)
    -		return (1);
    -
    -	return (0);
    -}
    -
    -static __inline int
    -moea64_pte_match(struct lpte *pt, uint64_t vsid, vm_offset_t va, int which)
    -{
    -	return (pt->pte_hi & ~LPTE_VALID) ==
    -	    ((vsid << LPTE_VSID_SHIFT) |
    -	    ((uint64_t)(va >> ADDR_API_SHFT64) & LPTE_API) | which);
    -}
    -
     static __inline void
     moea64_pte_create(struct lpte *pt, uint64_t vsid, vm_offset_t va, 
         uint64_t pte_lo)
    @@ -583,7 +568,7 @@ moea64_pte_set(struct lpte *pt, struct lpte *pvo_pt)
     	pt->pte_lo = pvo_pt->pte_lo;
     	EIEIO();
     	pt->pte_hi = pvo_pt->pte_hi;
    -	SYNC();
    +	PTESYNC();
     	moea64_pte_valid++;
     }
     
    @@ -602,7 +587,6 @@ moea64_pte_unset(struct lpte *pt, struct lpte *pvo_pt, pmap_t pmap, vm_offset_t
     	 * Invalidate the pte.
     	 */
     	pt->pte_hi &= ~LPTE_VALID;
    -
     	TLBIE(pmap,va);
     
     	/*
    @@ -621,6 +605,8 @@ moea64_pte_change(struct lpte *pt, struct lpte *pvo_pt, pmap_t pmap, vm_offset_t
     	 */
     	moea64_pte_unset(pt, pvo_pt, pmap, va);
     	moea64_pte_set(pt, pvo_pt);
    +	if (pmap == kernel_pmap)
    +		isync();
     }
     
     static __inline uint64_t
    @@ -701,7 +687,7 @@ moea64_bridge_cpu_bootstrap(mmu_t mmup, int ap)
     	for (i = 0; i < 16; i++) {
     		mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]);
     	}
    -	__asm __volatile ("sync; mtsdr1 %0; isync"
    +	__asm __volatile ("ptesync; mtsdr1 %0; isync"
     	    :: "r"((u_int)moea64_pteg_table 
     		     | (32 - cntlzw(moea64_pteg_mask >> 11))));
     	tlbia();
    @@ -1135,7 +1121,7 @@ void moea64_set_scratchpage_pa(int which, vm_offset_t pa) {
     	EIEIO();
     
     	moea64_scratchpage_pte[which]->pte_hi |= LPTE_VALID;
    -	TLBIE(kernel_pmap, moea64_scratchpage_va[which]);
    +	PTESYNC(); isync();
     }
     
     void
    @@ -1155,8 +1141,6 @@ moea64_copy_page(mmu_t mmu, vm_page_t msrc, vm_page_t mdst)
     	kcopy((void *)moea64_scratchpage_va[0], 
     	    (void *)moea64_scratchpage_va[1], PAGE_SIZE);
     
    -	__syncicache((void *)moea64_scratchpage_va[1],PAGE_SIZE);
    -
     	mtx_unlock(&moea64_scratchpage_mtx);
     }
     
    @@ -1174,8 +1158,6 @@ moea64_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
     
     	moea64_set_scratchpage_pa(0,pa);
     	bzero((caddr_t)moea64_scratchpage_va[0] + off, size);
    -	__syncicache((void *)moea64_scratchpage_va[0],PAGE_SIZE);
    -
     	mtx_unlock(&moea64_scratchpage_mtx);
     }
     
    @@ -1266,9 +1248,6 @@ moea64_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
     	error = moea64_pvo_enter(pmap, zone, pvo_head, va, VM_PAGE_TO_PHYS(m),
     	    pte_lo, pvo_flags);
     
    -	if (pmap == kernel_pmap)
    -		TLBIE(pmap, va);
    -
     	/*
     	 * Flush the page from the instruction cache if this page is
     	 * mapped executable and cacheable.
    @@ -1281,6 +1260,7 @@ moea64_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
     static void
     moea64_syncicache(pmap_t pmap, vm_offset_t va, vm_offset_t pa)
     {
    +
     	/*
     	 * This is much trickier than on older systems because
     	 * we can't sync the icache on physical addresses directly
    @@ -1441,8 +1421,6 @@ moea64_uma_page_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
     	    &moea64_pvo_kunmanaged, va,  VM_PAGE_TO_PHYS(m), LPTE_M, 
     	    PVO_WIRED | PVO_BOOTSTRAP);
     
    -	TLBIE(kernel_pmap, va);
    -
     	if (needed_lock)
     		PMAP_UNLOCK(kernel_pmap);
     	
    @@ -1531,7 +1509,7 @@ moea64_remove_write(mmu_t mmu, vm_page_t m)
     				lo |= pvo->pvo_pte.lpte.pte_lo;
     				pvo->pvo_pte.lpte.pte_lo &= ~LPTE_CHG;
     				moea64_pte_change(pt, &pvo->pvo_pte.lpte,
    -				    pvo->pvo_pmap, pvo->pvo_vaddr);
    +				    pvo->pvo_pmap, PVO_VADDR(pvo));
     			}
     			UNLOCK_TABLE();
     		}
    @@ -1590,8 +1568,6 @@ moea64_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa)
     	    &moea64_pvo_kunmanaged, va, pa, pte_lo, 
     	    PVO_WIRED | VM_PROT_EXECUTE);
     
    -	TLBIE(kernel_pmap, va);
    -
     	if (error != 0 && error != ENOENT)
     		panic("moea64_kenter: failed to enter va %#x pa %#x: %d", va,
     		    pa, error);
    @@ -1823,7 +1799,7 @@ moea64_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva,
     		 */
     		if (pt != NULL) {
     			moea64_pte_change(pt, &pvo->pvo_pte.lpte, 
    -			    pvo->pvo_pmap, pvo->pvo_vaddr);
    +			    pvo->pvo_pmap, PVO_VADDR(pvo));
     			if ((pvo->pvo_pte.lpte.pte_lo & 
     			    (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) {
     				moea64_syncicache(pm, sva, 
    @@ -1926,6 +1902,10 @@ moea64_remove_all(mmu_t mmu, vm_page_t m)
     		moea64_pvo_remove(pvo, -1);
     		PMAP_UNLOCK(pmap);
     	}
    +	if ((m->flags & PG_WRITEABLE) && moea64_is_modified(mmu, m)) {
    +		moea64_attr_clear(m, LPTE_CHG);
    +		vm_page_dirty(m);
    +	}
     	vm_page_flag_clear(m, PG_WRITEABLE);
     }
     
    @@ -2106,7 +2086,7 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
     		first = 1;
     	LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
     
    -	if (pvo->pvo_pte.lpte.pte_lo & PVO_WIRED)
    +	if (pvo->pvo_vaddr & PVO_WIRED)
     		pm->pm_stats.wired_count++;
     	pm->pm_stats.resident_count++;
     
    @@ -2121,6 +2101,9 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
     		moea64_pte_overflow++;
     	}
     
    +	if (pm == kernel_pmap)
    +		isync();
    +
     	UNLOCK_TABLE();
     
     	return (first ? ENOENT : 0);
    @@ -2139,7 +2122,7 @@ moea64_pvo_remove(struct pvo_entry *pvo, int pteidx)
     	pt = moea64_pvo_to_pte(pvo, pteidx);
     	if (pt != NULL) {
     		moea64_pte_unset(pt, &pvo->pvo_pte.lpte, pvo->pvo_pmap,
    -		    pvo->pvo_vaddr);
    +		    PVO_VADDR(pvo));
     		PVO_PTEGIDX_CLR(pvo);
     	} else {
     		moea64_pte_overflow--;
    @@ -2150,7 +2133,7 @@ moea64_pvo_remove(struct pvo_entry *pvo, int pteidx)
     	 * Update our statistics.
     	 */
     	pvo->pvo_pmap->pm_stats.resident_count--;
    -	if (pvo->pvo_pte.lpte.pte_lo & PVO_WIRED)
    +	if (pvo->pvo_vaddr & PVO_WIRED)
     		pvo->pvo_pmap->pm_stats.wired_count--;
     
     	/*
    @@ -2177,7 +2160,7 @@ moea64_pvo_remove(struct pvo_entry *pvo, int pteidx)
     	 */
     	LIST_REMOVE(pvo, pvo_olink);
     	if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP))
    -		uma_zfree(pvo->pvo_vaddr & PVO_MANAGED ? moea64_mpvo_zone :
    +		uma_zfree((pvo->pvo_vaddr & PVO_MANAGED) ? moea64_mpvo_zone :
     		    moea64_upvo_zone, pvo);
     	moea64_pvo_entries--;
     	moea64_pvo_remove_calls++;
    @@ -2236,8 +2219,8 @@ moea64_pvo_to_pte(const struct pvo_entry *pvo, int pteidx)
     		int		ptegidx;
     		uint64_t	vsid;
     
    -		vsid = va_to_vsid(pvo->pvo_pmap, pvo->pvo_vaddr);
    -		ptegidx = va_to_pteg(vsid, pvo->pvo_vaddr);
    +		vsid = va_to_vsid(pvo->pvo_pmap, PVO_VADDR(pvo));
    +		ptegidx = va_to_pteg(vsid, PVO_VADDR(pvo));
     		pteidx = moea64_pvo_pte_index(pvo, ptegidx);
     	}
     
    @@ -2324,10 +2307,8 @@ moea64_query_bit(vm_page_t m, u_int64_t ptebit)
     	struct	pvo_entry *pvo;
     	struct	lpte *pt;
     
    -#if 0
     	if (moea64_attr_fetch(m) & ptebit)
     		return (TRUE);
    -#endif
     
     	LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
     		MOEA_PVO_CHECK(pvo);	/* sanity check */
    
    From e868629641c144d088c004aa44093ee86f35df59 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Sat, 20 Mar 2010 15:15:54 +0000
    Subject: [PATCH 1621/2592] MFC r204128:
    
    Reduce KVA pressure on OEA64 systems running in bridge mode by mapping
    UMA segments at their physical addresses instead of into KVA. This emulates
    the direct mapping behavior of OEA32 in an ad-hoc way. To make this work
    properly required sharing the entire kernel PMAP with Open Firmware, so
    ofw_pmap is transformed into a stub on 64-bit CPUs.
    
    Also implement some more tweaks to get more mileage out of our limited
    amount of KVA, principally by extending KVA into segment 16 until the
    beginning of the first OFW mapping.
    
    Reported by:	linimon
    ---
     sys/powerpc/aim/machdep.c     |  5 +++
     sys/powerpc/aim/mmu_oea.c     |  4 +-
     sys/powerpc/aim/mmu_oea64.c   | 76 +++++++++++++----------------------
     sys/powerpc/aim/uma_machdep.c | 21 ++++------
     sys/powerpc/include/sr.h      |  1 +
     sys/powerpc/include/vmparam.h | 10 +----
     6 files changed, 46 insertions(+), 71 deletions(-)
    
    diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
    index 4be11b52eaa..37bbc7febae 100644
    --- a/sys/powerpc/aim/machdep.c
    +++ b/sys/powerpc/aim/machdep.c
    @@ -198,6 +198,11 @@ cpu_startup(void *dummy)
     	    ptoa(physmem) / 1048576);
     	realmem = physmem;
     
    +	if (bootverbose)
    +		printf("available KVA = %zd (%zd MB)\n",
    +		    virtual_end - virtual_avail,
    +		    (virtual_end - virtual_avail) / 1048576);
    +
     	/*
     	 * Display any holes after the first chunk of extended memory.
     	 */
    diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
    index 5caa3b9707f..dfa80516c22 100644
    --- a/sys/powerpc/aim/mmu_oea.c
    +++ b/sys/powerpc/aim/mmu_oea.c
    @@ -909,7 +909,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
     	 * Set the start and end of kva.
     	 */
     	virtual_avail = VM_MIN_KERNEL_ADDRESS;
    -	virtual_end = VM_MAX_KERNEL_ADDRESS;
    +	virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS;
     
     	/*
     	 * Allocate a kernel stack with a guard page for thread0 and map it
    @@ -2419,7 +2419,7 @@ moea_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size)
     	 * If this is outside kernel virtual space, then it's a
     	 * battable entry and doesn't require unmapping
     	 */
    -	if ((va >= VM_MIN_KERNEL_ADDRESS) && (va <= VM_MAX_KERNEL_ADDRESS)) {
    +	if ((va >= VM_MIN_KERNEL_ADDRESS) && (va <= virtual_end)) {
     		base = trunc_page(va);
     		offset = va & PAGE_MASK;
     		size = roundup(offset + size, PAGE_SIZE);
    diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
    index ebe7361b6b2..be154547155 100644
    --- a/sys/powerpc/aim/mmu_oea64.c
    +++ b/sys/powerpc/aim/mmu_oea64.c
    @@ -297,9 +297,6 @@ struct	pvo_head moea64_pvo_unmanaged =
     uma_zone_t	moea64_upvo_zone; /* zone for pvo entries for unmanaged pages */
     uma_zone_t	moea64_mpvo_zone; /* zone for pvo entries for managed pages */
     
    -vm_offset_t	pvo_allocator_start;
    -vm_offset_t	pvo_allocator_end;
    -
     #define	BPVO_POOL_SIZE	327680
     static struct	pvo_entry *moea64_bpvo_pool;
     static int	moea64_bpvo_pool_index = 0;
    @@ -699,6 +696,7 @@ moea64_add_ofw_mappings(mmu_t mmup, phandle_t mmu, size_t sz)
     	struct ofw_map	translations[sz/sizeof(struct ofw_map)];
     	register_t	msr;
     	vm_offset_t	off;
    +	vm_paddr_t	pa_base;
     	int		i, ofw_mappings;
     
     	bzero(translations, sz);
    @@ -720,33 +718,18 @@ moea64_add_ofw_mappings(mmu_t mmup, phandle_t mmu, size_t sz)
     		if (translations[i].om_pa_hi)
     			panic("OFW translations above 32-bit boundary!");
     
    +		pa_base = translations[i].om_pa_lo;
    +
     		/* Now enter the pages for this mapping */
     
    -		/*
    -		 * Lock the ofw pmap. pmap_kenter(), which we use for the
    -		 * pages the kernel also needs, does its own locking.
    -		 */
    -		PMAP_LOCK(&ofw_pmap); 
     		DISABLE_TRANS(msr);
     		for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) {
    -			struct vm_page m;
    -
    -			/* Map low memory mappings into the kernel pmap, too.
    -			 * These are typically mappings made by the loader,
    -			 * so we need them if we want to keep executing. */
    -
    -			if (translations[i].om_va + off < SEGMENT_LENGTH)
    -				moea64_kenter(mmup, translations[i].om_va + off,
    -				    translations[i].om_va + off);
    -
    -			m.phys_addr = translations[i].om_pa_lo + off;
    -			moea64_enter_locked(&ofw_pmap,
    -			    translations[i].om_va + off, &m, VM_PROT_ALL, 1);
    +			moea64_kenter(mmup, translations[i].om_va + off,
    +			    pa_base + off);
     
     			ofw_mappings++;
     		}
     		ENABLE_TRANS(msr);
    -		PMAP_UNLOCK(&ofw_pmap);
     	}
     }
     
    @@ -926,8 +909,8 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
     	     */
     
     	    moea64_pinit(mmup, &ofw_pmap);
    -	    ofw_pmap.pm_sr[KERNEL_SR] = kernel_pmap->pm_sr[KERNEL_SR];
    -	    ofw_pmap.pm_sr[KERNEL2_SR] = kernel_pmap->pm_sr[KERNEL2_SR];
    +	    for (i = 0; i < 16; i++)
    +		ofw_pmap.pm_sr[i] = kernel_pmap->pm_sr[i];
     
     	    if ((chosen = OF_finddevice("/chosen")) == -1)
     		panic("moea64_bootstrap: can't find /chosen");
    @@ -965,15 +948,20 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
     	 * Set the start and end of kva.
     	 */
     	virtual_avail = VM_MIN_KERNEL_ADDRESS;
    -	virtual_end = VM_MAX_KERNEL_ADDRESS;
    +	virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS; 
     
     	/*
    -	 * Allocate some stupid buffer regions.
    +	 * Figure out how far we can extend virtual_end into segment 16
    +	 * without running into existing mappings. Segment 16 is guaranteed
    +	 * to contain neither RAM nor devices (at least on Apple hardware),
    +	 * but will generally contain some OFW mappings we should not
    +	 * step on.
     	 */
     
    -	pvo_allocator_start = virtual_avail;
    -	virtual_avail += SEGMENT_LENGTH/4;
    -	pvo_allocator_end = virtual_avail;
    +	PMAP_LOCK(kernel_pmap);
    +	while (moea64_pvo_find_va(kernel_pmap, virtual_end+1, NULL) == NULL)
    +		virtual_end += PAGE_SIZE;
    +	PMAP_UNLOCK(kernel_pmap);
     
     	/*
     	 * Allocate some things for page zeroing
    @@ -1014,26 +1002,20 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
     	 * Allocate virtual address space for the message buffer.
     	 */
     	pa = msgbuf_phys = moea64_bootstrap_alloc(MSGBUF_SIZE, PAGE_SIZE);
    -	msgbufp = (struct msgbuf *)virtual_avail;
    -	va = virtual_avail;
    -	virtual_avail += round_page(MSGBUF_SIZE);
    -	while (va < virtual_avail) {
    -		moea64_kenter(mmup, va, pa);
    +	msgbufp = (struct msgbuf *)msgbuf_phys;
    +	while (pa - msgbuf_phys < MSGBUF_SIZE) {
    +		moea64_kenter(mmup, pa, pa);
     		pa += PAGE_SIZE;
    -		va += PAGE_SIZE;
     	}
     
     	/*
     	 * Allocate virtual address space for the dynamic percpu area.
     	 */
     	pa = moea64_bootstrap_alloc(DPCPU_SIZE, PAGE_SIZE);
    -	dpcpu = (void *)virtual_avail;
    -	va = virtual_avail;
    -	virtual_avail += DPCPU_SIZE;
    -	while (va < virtual_avail) {
    -		moea64_kenter(mmup, va, pa);
    +	dpcpu = (void *)pa;
    +	while (pa - (vm_offset_t)dpcpu < DPCPU_SIZE) {
    +		moea64_kenter(mmup, pa, pa);
     		pa += PAGE_SIZE;
    -		va += PAGE_SIZE;
     	}
     	dpcpu_init(dpcpu, 0);
     }
    @@ -1411,14 +1393,10 @@ moea64_uma_page_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
                             break;
             }
     
    -	va = pvo_allocator_start;
    -	pvo_allocator_start += PAGE_SIZE;
    -
    -	if (pvo_allocator_start >= pvo_allocator_end)
    -		panic("Ran out of PVO allocator buffer space!");
    +	va = VM_PAGE_TO_PHYS(m);
     
     	moea64_pvo_enter(kernel_pmap, moea64_upvo_zone,
    -	    &moea64_pvo_kunmanaged, va,  VM_PAGE_TO_PHYS(m), LPTE_M, 
    +	    &moea64_pvo_kunmanaged, va, VM_PAGE_TO_PHYS(m), LPTE_M,
     	    PVO_WIRED | PVO_BOOTSTRAP);
     
     	if (needed_lock)
    @@ -1556,10 +1534,12 @@ moea64_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa)
     	uint64_t	pte_lo;
     	int		error;	
     
    +#if 0
     	if (!pmap_bootstrapped) {
    -		if (va >= VM_MIN_KERNEL_ADDRESS && va < VM_MAX_KERNEL_ADDRESS)
    +		if (va >= VM_MIN_KERNEL_ADDRESS && va < virtual_end)
     			panic("Trying to enter an address in KVA -- %#x!\n",pa);
     	}
    +#endif
     
     	pte_lo = moea64_calc_wimg(pa);
     
    diff --git a/sys/powerpc/aim/uma_machdep.c b/sys/powerpc/aim/uma_machdep.c
    index dc03a263d7f..6b28d67186f 100644
    --- a/sys/powerpc/aim/uma_machdep.c
    +++ b/sys/powerpc/aim/uma_machdep.c
    @@ -56,13 +56,6 @@ uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
     	vm_page_t m;
     	int pflags;
     	
    -	if (!hw_direct_map) {
    -		*flags = UMA_SLAB_KMEM;
    -		va = (void *)kmem_malloc(kmem_map, bytes, wait);
    -	
    -		return va;
    -	}
    -
     	*flags = UMA_SLAB_PRIV;
     	if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT)
     		pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED;
    @@ -82,6 +75,10 @@ uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
     	}
     
     	va = (void *) VM_PAGE_TO_PHYS(m);
    +
    +	if (!hw_direct_map)
    +		pmap_kenter((vm_offset_t)va, VM_PAGE_TO_PHYS(m));
    +
     	if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
     		bzero(va, PAGE_SIZE);
     	atomic_add_int(&hw_uma_mdpages, 1);
    @@ -94,13 +91,11 @@ uma_small_free(void *mem, int size, u_int8_t flags)
     {
     	vm_page_t m;
     
    -	if (!hw_direct_map) {
    -		kmem_free(kmem_map, (vm_offset_t)mem, size);
    +	if (!hw_direct_map)
    +		pmap_remove(kernel_pmap,(vm_offset_t)mem,
    +		    (vm_offset_t)mem + PAGE_SIZE);
     
    -		return;
    -	}
    -
    -	m = PHYS_TO_VM_PAGE((u_int32_t)mem);
    +	m = PHYS_TO_VM_PAGE((vm_offset_t)mem);
     	m->wire_count--;
     	vm_page_free(m);
     	atomic_subtract_int(&cnt.v_wire_count, 1);
    diff --git a/sys/powerpc/include/sr.h b/sys/powerpc/include/sr.h
    index 2ef7b358507..061195dd055 100644
    --- a/sys/powerpc/include/sr.h
    +++ b/sys/powerpc/include/sr.h
    @@ -45,6 +45,7 @@
     #define	USER_SR		12
     #define	KERNEL_SR	13
     #define	KERNEL2_SR	14
    +#define	KERNEL3_SR	15
     #define	KERNEL_VSIDBITS	0xfffff
     #define	KERNEL_SEGMENT	(0xfffff0 + KERNEL_SR)
     #define	KERNEL2_SEGMENT	(0xfffff0 + KERNEL2_SR)
    diff --git a/sys/powerpc/include/vmparam.h b/sys/powerpc/include/vmparam.h
    index e77823363a1..b7424f6c191 100644
    --- a/sys/powerpc/include/vmparam.h
    +++ b/sys/powerpc/include/vmparam.h
    @@ -98,7 +98,8 @@
     #define	KERNBASE		0x00100000	/* start of kernel virtual */
     
     #define	VM_MIN_KERNEL_ADDRESS	((vm_offset_t)(KERNEL_SR << ADDR_SR_SHFT))
    -#define	VM_MAX_KERNEL_ADDRESS	(VM_MIN_KERNEL_ADDRESS + 2*SEGMENT_LENGTH - 1)
    +#define	VM_MAX_SAFE_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + 2*SEGMENT_LENGTH -1)
    +#define	VM_MAX_KERNEL_ADDRESS	(VM_MIN_KERNEL_ADDRESS + 3*SEGMENT_LENGTH - 1)
     
     /*
      * Use the direct-mapped BAT registers for UMA small allocs. This
    @@ -106,13 +107,6 @@
      */
     #define UMA_MD_SMALL_ALLOC
     
    -/*
    - * On 64-bit systems in bridge mode, we have no direct map, so we fake
    - * the small_alloc() calls. But we need the VM to be in a reasonable
    - * state first.
    - */
    -#define UMA_MD_SMALL_ALLOC_NEEDS_VM
    -
     #else
     
     /*
    
    From aba7e013d6fc755fc9e3c78c302365844553aeb1 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Sat, 20 Mar 2010 15:19:57 +0000
    Subject: [PATCH 1622/2592] MFC r204268:
    
    Close a race involving the OEA64 scratchpage. When the scratch page's
    physical address is changed, there is a brief window during which its PTE
    is invalid. Since moea64_set_scratchpage_pa() does not and cannot hold
    the page table lock, it was possible for another CPU to insert a new PTE
    into the scratch page's PTEG slot during this interval, corrupting both
    mappings.
    
    Solve this by creating a new flag, LPTE_LOCKED, such that
    moea64_pte_insert will avoid claiming locked PTEG slots even if they
    are invalid. This change also incorporates some additional paranoia
    added to solve things I thought might be this bug.
    
    Reported by:	linimon
    ---
     sys/powerpc/aim/mmu_oea64.c | 24 ++++++++++++++----------
     sys/powerpc/include/pte.h   |  1 +
     2 files changed, 15 insertions(+), 10 deletions(-)
    
    diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
    index be154547155..23e5950c74e 100644
    --- a/sys/powerpc/aim/mmu_oea64.c
    +++ b/sys/powerpc/aim/mmu_oea64.c
    @@ -227,6 +227,7 @@ TLBIE(pmap_t pmap, vm_offset_t va) {
     #define	VSID_MAKE(sr, hash)	((sr) | (((hash) & 0xfffff) << 4))
     #define	VSID_TO_SR(vsid)	((vsid) & 0xf)
     #define	VSID_TO_HASH(vsid)	(((vsid) >> 4) & 0xfffff)
    +#define	VSID_HASH_MASK		0x0000007fffffffffULL
     
     #define	PVO_PTEGIDX_MASK	0x007UL		/* which PTEG slot */
     #define	PVO_PTEGIDX_VALID	0x008UL		/* slot is valid */
    @@ -458,9 +459,9 @@ MMU_DEF(oea64_bridge_mmu);
     static __inline u_int
     va_to_pteg(uint64_t vsid, vm_offset_t addr)
     {
    -	u_int hash;
    +	uint64_t hash;
     
    -	hash = vsid ^ (((uint64_t)addr & ADDR_PIDX) >>
    +	hash = (vsid & VSID_HASH_MASK) ^ (((uint64_t)addr & ADDR_PIDX) >>
     	    ADDR_PIDX_SHFT);
     	return (hash & moea64_pteg_mask);
     }
    @@ -979,6 +980,7 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
     		    moea64_scratchpage_va[i],&j);
     		moea64_scratchpage_pte[i] = moea64_pvo_to_pte(
     		    moea64_scratchpage_pvo[i],j);
    +		moea64_scratchpage_pte[i]->pte_hi |= LPTE_LOCKED;
     		UNLOCK_TABLE();
     	}
     
    @@ -1090,8 +1092,10 @@ moea64_zero_page(mmu_t mmu, vm_page_t m)
     
     static __inline
     void moea64_set_scratchpage_pa(int which, vm_offset_t pa) {
    +	mtx_assert(&moea64_scratchpage_mtx, MA_OWNED);
    +
     	moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo &= 
    -	    (~LPTE_WIMG & ~LPTE_RPGN);
    +	    ~(LPTE_WIMG | LPTE_RPGN);
     	moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo |= 
     	    moea64_calc_wimg(pa) | (uint64_t)pa;
     
    @@ -2149,18 +2153,16 @@ moea64_pvo_remove(struct pvo_entry *pvo, int pteidx)
     static __inline int
     moea64_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx)
     {
    -	int	pteidx;
     
     	/*
     	 * We can find the actual pte entry without searching by grabbing
    -	 * the PTEG index from 3 unused bits in pte_lo[11:9] and by
    +	 * the PTEG index from 3 unused bits in pvo_vaddr and by
     	 * noticing the HID bit.
     	 */
    -	pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo);
     	if (pvo->pvo_pte.lpte.pte_hi & LPTE_HID)
    -		pteidx ^= moea64_pteg_mask * 8;
    +		ptegidx ^= moea64_pteg_mask;
     
    -	return (pteidx);
    +	return ((ptegidx << 3) | PVO_PTEGIDX_GET(pvo));
     }
     
     static struct pvo_entry *
    @@ -2257,7 +2259,8 @@ moea64_pte_insert(u_int ptegidx, struct lpte *pvo_pt)
     	 * First try primary hash.
     	 */
     	for (pt = moea64_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
    -		if ((pt->pte_hi & LPTE_VALID) == 0) {
    +		if ((pt->pte_hi & LPTE_VALID) == 0 &&
    +		    (pt->pte_hi & LPTE_LOCKED) == 0) {
     			pvo_pt->pte_hi &= ~LPTE_HID;
     			moea64_pte_set(pt, pvo_pt);
     			return (i);
    @@ -2270,7 +2273,8 @@ moea64_pte_insert(u_int ptegidx, struct lpte *pvo_pt)
     	ptegidx ^= moea64_pteg_mask;
     
     	for (pt = moea64_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
    -		if ((pt->pte_hi & LPTE_VALID) == 0) {
    +		if ((pt->pte_hi & LPTE_VALID) == 0 &&
    +		    (pt->pte_hi & LPTE_LOCKED) == 0) {
     			pvo_pt->pte_hi |= LPTE_HID;
     			moea64_pte_set(pt, pvo_pt);
     			return (i);
    diff --git a/sys/powerpc/include/pte.h b/sys/powerpc/include/pte.h
    index f1e5319a5bc..b7f5fd971e9 100644
    --- a/sys/powerpc/include/pte.h
    +++ b/sys/powerpc/include/pte.h
    @@ -95,6 +95,7 @@ struct lpteg {
     /* High quadword: */
     #define LPTE_VSID_SHIFT		12
     #define LPTE_API		0x0000000000000F80ULL
    +#define LPTE_LOCKED		0x0000000000000008ULL
     #define LPTE_BIG		0x0000000000000004ULL	/* 4kb/16Mb page */
     #define LPTE_HID		0x0000000000000002ULL
     #define LPTE_VALID		0x0000000000000001ULL
    
    From 59908d2f728e5706f539fa42e4b5667e62a220d5 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Sat, 20 Mar 2010 15:21:13 +0000
    Subject: [PATCH 1623/2592] MFC r204269:
    
    Use dcbz instead of word stores for page zeroing, providing a factor of
    3-4 speedup.
    ---
     sys/powerpc/aim/mmu_oea64.c | 30 +++++++++++++++++++++---------
     1 file changed, 21 insertions(+), 9 deletions(-)
    
    diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
    index 23e5950c74e..f5ebfef2e76 100644
    --- a/sys/powerpc/aim/mmu_oea64.c
    +++ b/sys/powerpc/aim/mmu_oea64.c
    @@ -1074,15 +1074,6 @@ moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
     	PMAP_UNLOCK(pm);
     }
     
    -/*
    - * Zero a page of physical memory by temporarily mapping it into the tlb.
    - */
    -void
    -moea64_zero_page(mmu_t mmu, vm_page_t m)
    -{
    -	moea64_zero_page_area(mmu,m,0,PAGE_SIZE);
    -}
    -
     /*
      * This goes through and sets the physical address of our
      * special scratch PTE to the PA we want to zero or copy. Because
    @@ -1147,6 +1138,27 @@ moea64_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
     	mtx_unlock(&moea64_scratchpage_mtx);
     }
     
    +/*
    + * Zero a page of physical memory by temporarily mapping it
    + */
    +void
    +moea64_zero_page(mmu_t mmu, vm_page_t m)
    +{
    +	vm_offset_t pa = VM_PAGE_TO_PHYS(m);
    +	vm_offset_t off;
    +
    +	if (!moea64_initialized)
    +		panic("moea64_zero_page: can't zero pa %#x", pa);
    +
    +	mtx_lock(&moea64_scratchpage_mtx);
    +
    +	moea64_set_scratchpage_pa(0,pa);
    +	for (off = 0; off < PAGE_SIZE; off += cacheline_size)
    +		__asm __volatile("dcbz 0,%0" ::
    +		    "r"(moea64_scratchpage_va[0] + off));
    +	mtx_unlock(&moea64_scratchpage_mtx);
    +}
    +
     void
     moea64_zero_page_idle(mmu_t mmu, vm_page_t m)
     {
    
    From 1f70273a79f4d24a37c93cb5230fde3edd8b6892 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Sat, 20 Mar 2010 15:23:06 +0000
    Subject: [PATCH 1624/2592] MFC r204296:
    
    Provide an implementation of pmap_dev_direct_mapped() on OEA64. This is
    required in order to be able to mmap the running kernel, which is turn
    required to avoid fstat returning gibberish.
    ---
     sys/powerpc/aim/mmu_oea64.c | 17 ++++++++++++++++-
     1 file changed, 16 insertions(+), 1 deletion(-)
    
    diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
    index f5ebfef2e76..eac6f8e9653 100644
    --- a/sys/powerpc/aim/mmu_oea64.c
    +++ b/sys/powerpc/aim/mmu_oea64.c
    @@ -2408,7 +2408,22 @@ moea64_clear_bit(vm_page_t m, u_int64_t ptebit, u_int64_t *origbit)
     boolean_t
     moea64_dev_direct_mapped(mmu_t mmu, vm_offset_t pa, vm_size_t size)
     {
    -	return (EFAULT);
    +	struct pvo_entry *pvo;
    +	vm_offset_t ppa;
    +	int error = 0;
    +
    +	PMAP_LOCK(kernel_pmap);
    +	for (ppa = pa & ~ADDR_POFF; ppa < pa + size; ppa += PAGE_SIZE) {
    +		pvo = moea64_pvo_find_va(kernel_pmap, ppa, NULL);
    +		if (pvo == NULL ||
    +		    (pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) != ppa) {
    +			error = EFAULT;
    +			break;
    +		}
    +	}
    +	PMAP_UNLOCK(kernel_pmap);
    +
    +	return (error);
     }
     
     boolean_t
    
    From fca060b9f9c3c2d537c9d0b3658a9c83e84bf6ea Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Sat, 20 Mar 2010 15:27:01 +0000
    Subject: [PATCH 1625/2592] MFC r204297:
    
    Move the OEA64 scratchpage to the end of KVA from the beginning, and set
    its PVO to map physical address 0 instead of kernelstart. This fixes a
    situation in which a user process could attempt to return this address
    via KVM, have it fault while being modified, and then panic the kernel
    because (a) it is supposed to map a valid address and (b) it lies in the
    no-fault region between VM_MIN_KERNEL_ADDRESS and virtual_avail.
    
    While here, move msgbuf and dpcpu back into regular KVA space for
    consistency with other implementations.
    ---
     sys/powerpc/aim/mmu_oea64.c | 23 ++++++++++++++---------
     1 file changed, 14 insertions(+), 9 deletions(-)
    
    diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
    index eac6f8e9653..9d04a023914 100644
    --- a/sys/powerpc/aim/mmu_oea64.c
    +++ b/sys/powerpc/aim/mmu_oea64.c
    @@ -970,10 +970,10 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
     
     	mtx_init(&moea64_scratchpage_mtx, "pvo zero page", NULL, MTX_DEF);
     	for (i = 0; i < 2; i++) {
    -		moea64_scratchpage_va[i] = virtual_avail;
    -		virtual_avail += PAGE_SIZE;
    +		moea64_scratchpage_va[i] = (virtual_end+1) - PAGE_SIZE;
    +		virtual_end -= PAGE_SIZE;
     
    -		moea64_kenter(mmup,moea64_scratchpage_va[i],kernelstart);
    +		moea64_kenter(mmup,moea64_scratchpage_va[i],0);
     
     		LOCK_TABLE();
     		moea64_scratchpage_pvo[i] = moea64_pvo_find_va(kernel_pmap,
    @@ -1004,20 +1004,25 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele
     	 * Allocate virtual address space for the message buffer.
     	 */
     	pa = msgbuf_phys = moea64_bootstrap_alloc(MSGBUF_SIZE, PAGE_SIZE);
    -	msgbufp = (struct msgbuf *)msgbuf_phys;
    -	while (pa - msgbuf_phys < MSGBUF_SIZE) {
    -		moea64_kenter(mmup, pa, pa);
    +	msgbufp = (struct msgbuf *)virtual_avail;
    +	va = virtual_avail;
    +	virtual_avail += round_page(MSGBUF_SIZE);
    +	while (va < virtual_avail) {
    +		moea64_kenter(mmup, va, pa);
     		pa += PAGE_SIZE;
    +		va += PAGE_SIZE;
     	}
     
     	/*
     	 * Allocate virtual address space for the dynamic percpu area.
     	 */
     	pa = moea64_bootstrap_alloc(DPCPU_SIZE, PAGE_SIZE);
    -	dpcpu = (void *)pa;
    -	while (pa - (vm_offset_t)dpcpu < DPCPU_SIZE) {
    -		moea64_kenter(mmup, pa, pa);
    +	dpcpu = (void *)virtual_avail;
    +	virtual_avail += DPCPU_SIZE;
    +	while (va < virtual_avail) {
    +		moea64_kenter(mmup, va, pa);
     		pa += PAGE_SIZE;
    +		va += PAGE_SIZE;
     	}
     	dpcpu_init(dpcpu, 0);
     }
    
    From 9c4dbddb292eb906710b7b35fd29c5771b728629 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Sat, 20 Mar 2010 15:28:39 +0000
    Subject: [PATCH 1626/2592] MFC r204211:
    
    Support the extended PLT format used when objects have more than 8192
    PLT relocations on PPC32.
    ---
     libexec/rtld-elf/powerpc/reloc.c        | 85 +++++++++++++++++--------
     libexec/rtld-elf/powerpc/rtld_machdep.h |  1 +
     libexec/rtld-elf/powerpc/rtld_start.S   |  6 ++
     3 files changed, 67 insertions(+), 25 deletions(-)
    
    diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c
    index 22524283bc1..ccdcd90de24 100644
    --- a/libexec/rtld-elf/powerpc/reloc.c
    +++ b/libexec/rtld-elf/powerpc/reloc.c
    @@ -47,6 +47,13 @@
                             ((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16)
     #define _ppc_la(x) ((u_int32_t)(x) & 0xffff)
     
    +#define min(a,b) (((a) < (b)) ? (a) : (b))
    +#define max(a,b) (((a) > (b)) ? (a) : (b))
    +
    +#define PLT_EXTENDED_BEGIN	(1 << 13)
    +#define JMPTAB_BASE(N)		(18 + N*2 + ((N > PLT_EXTENDED_BEGIN) ? \
    +				    (N - PLT_EXTENDED_BEGIN)*2 : 0))
    +
     /*
      * Process the R_PPC_COPY relocations
      */
    @@ -313,7 +320,6 @@ done:
     	return (r);
     }
     
    -
     /*
      * Initialise a PLT slot to the resolving trampoline
      */
    @@ -321,27 +327,43 @@ static int
     reloc_plt_object(Obj_Entry *obj, const Elf_Rela *rela)
     {
     	Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
    -	Elf_Addr *pltresolve;
    +	Elf_Addr *pltresolve, *pltlongresolve, *jmptab;
     	Elf_Addr distance;
    +	int N = obj->pltrelasize / sizeof(Elf_Rela);
     	int reloff;
     
     	reloff = rela - obj->pltrela;
     
    -	if ((reloff < 0) || (reloff >= 0x8000)) {
    +	if (reloff < 0)
     		return (-1);
    -	}
     
    -	pltresolve = obj->pltgot + 8;
    +	pltlongresolve = obj->pltgot + 5;
    +	pltresolve = pltlongresolve + 5;
     
     	distance = (Elf_Addr)pltresolve - (Elf_Addr)(where + 1);
     
     	dbg(" reloc_plt_object: where=%p,pltres=%p,reloff=%x,distance=%x",
     	    (void *)where, (void *)pltresolve, reloff, distance);
     
    -	/* li   r11,reloff  */
    -	/* b    pltresolve  */
    -	where[0] = 0x39600000 | reloff;
    -	where[1] = 0x48000000 | (distance & 0x03fffffc);
    +	if (reloff < PLT_EXTENDED_BEGIN) {
    +		/* li   r11,reloff  */
    +		/* b    pltresolve  */
    +		where[0] = 0x39600000 | reloff;
    +		where[1] = 0x48000000 | (distance & 0x03fffffc);
    +	} else {
    +		jmptab = obj->pltgot + JMPTAB_BASE(N);
    +		jmptab[reloff] = (u_int)pltlongresolve;
    +
    +		/* lis	r11,jmptab[reloff]@ha */
    +		/* lwzu	r12,jmptab[reloff]@l(r11) */
    +		/* mtctr r12 */
    +		/* bctr */
    +		where[0] = 0x3d600000 | _ppc_ha(&jmptab[reloff]);
    +		where[1] = 0x858b0000 | _ppc_la(&jmptab[reloff]);
    +		where[2] = 0x7d8903a6;
    +		where[3] = 0x4e800420;
    +	}
    +		
     
     	/*
     	 * The icache will be sync'd in init_pltgot, which is called
    @@ -453,25 +475,28 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *defobj,
     		int N = obj->pltrelasize / sizeof(Elf_Rela);
     		int reloff = rela - obj->pltrela;
     
    -		if ((reloff < 0) || (reloff >= 0x8000)) {
    +		if (reloff < 0)
     			return (-1);
    -		}
     
     		pltcall = obj->pltgot;
     
    -		dbg(" reloc_jmpslot: indir, reloff=%d, N=%d\n",
    +		dbg(" reloc_jmpslot: indir, reloff=%x, N=%x\n",
     		    reloff, N);
     
    -		jmptab = obj->pltgot + 18 + N * 2;
    +		jmptab = obj->pltgot + JMPTAB_BASE(N);
     		jmptab[reloff] = target;
     
    -		distance = (Elf_Addr)pltcall - (Elf_Addr)(wherep + 1);
    +		if (reloff < PLT_EXTENDED_BEGIN) {
    +			/* for extended PLT entries, we keep the old code */
     
    -		/* li   r11,reloff */
    -		/* b    pltcall  # use indirect pltcall routine */
    -		wherep[0] = 0x39600000 | reloff;
    -		wherep[1] = 0x48000000 | (distance & 0x03fffffc);
    -		__syncicache(wherep, 8);
    +			distance = (Elf_Addr)pltcall - (Elf_Addr)(wherep + 1);
    +
    +			/* li   r11,reloff */
    +			/* b    pltcall  # use indirect pltcall routine */
    +			wherep[0] = 0x39600000 | reloff;
    +			wherep[1] = 0x48000000 | (distance & 0x03fffffc);
    +			__syncicache(wherep, 8);
    +		}
     	}
     
     	return (target);
    @@ -481,13 +506,14 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *defobj,
     /*
      * Setup the plt glue routines.
      */
    -#define PLTCALL_SIZE    20
    -#define PLTRESOLVE_SIZE 24
    +#define PLTCALL_SIZE	   	20
    +#define PLTLONGRESOLVE_SIZE	20
    +#define PLTRESOLVE_SIZE		24
     
     void
     init_pltgot(Obj_Entry *obj)
     {
    -	Elf_Word *pltcall, *pltresolve;
    +	Elf_Word *pltcall, *pltresolve, *pltlongresolve;
     	Elf_Word *jmptab;
     	int N = obj->pltrelasize / sizeof(Elf_Rela);
     
    @@ -524,18 +550,27 @@ init_pltgot(Obj_Entry *obj)
     	 * of the jumptable into the absolute-call assembler code so it
     	 * can determine this address.
     	 */
    -	jmptab = pltcall + 18 + N * 2;
    +	jmptab = obj->pltgot + JMPTAB_BASE(N);
     	pltcall[1] |= _ppc_ha(jmptab);	   /* addis 11,11,jmptab@ha */
     	pltcall[2] |= _ppc_la(jmptab);     /* lwz   11,jmptab@l(11) */
     
     	/*
    -	 * Skip down 32 bytes into the initial reserved area and copy
    +	 * Skip down 20 bytes into the initial reserved area and copy
     	 * in the standard resolving assembler call. Into this assembler,
     	 * insert the absolute address of the _rtld_bind_start routine
     	 * and the address of the relocation object.
    +	 *
    +	 * We place pltlongresolve first, so it can fix up its arguments
    +	 * and then fall through to the regular PLT resolver.
     	 */
    -	pltresolve = obj->pltgot + 8;
    +	pltlongresolve = obj->pltgot + 5;
     
    +	memcpy(pltlongresolve, _rtld_powerpc_pltlongresolve,
    +	    PLTLONGRESOLVE_SIZE);
    +	pltlongresolve[0] |= _ppc_ha(jmptab);	/* lis	12,jmptab@ha	*/
    +	pltlongresolve[1] |= _ppc_la(jmptab);	/* addi	12,12,jmptab@l	*/
    +
    +	pltresolve = pltlongresolve + PLTLONGRESOLVE_SIZE/sizeof(uint32_t);
     	memcpy(pltresolve, _rtld_powerpc_pltresolve, PLTRESOLVE_SIZE);
     	pltresolve[0] |= _ppc_ha(_rtld_bind_start);
     	pltresolve[1] |= _ppc_la(_rtld_bind_start);
    diff --git a/libexec/rtld-elf/powerpc/rtld_machdep.h b/libexec/rtld-elf/powerpc/rtld_machdep.h
    index f5f21a41fad..bf589c5728f 100644
    --- a/libexec/rtld-elf/powerpc/rtld_machdep.h
    +++ b/libexec/rtld-elf/powerpc/rtld_machdep.h
    @@ -57,6 +57,7 @@ void _rtld_bind_start(void);
      * PLT functions. Not really correct prototypes, but the
      * symbol values are needed.
      */
    +void _rtld_powerpc_pltlongresolve(void);
     void _rtld_powerpc_pltresolve(void);
     void _rtld_powerpc_pltcall(void);
     
    diff --git a/libexec/rtld-elf/powerpc/rtld_start.S b/libexec/rtld-elf/powerpc/rtld_start.S
    index 86f76e6d282..00692d284e9 100644
    --- a/libexec/rtld-elf/powerpc/rtld_start.S
    +++ b/libexec/rtld-elf/powerpc/rtld_start.S
    @@ -163,6 +163,12 @@ _ENTRY(_rtld_bind_start)
      * The ELF object is shifted into %r11, and _rtld_bind_start is called
      * to complete the binding.
      */
    +_ENTRY(_rtld_powerpc_pltlongresolve)
    +	lis	%r12,0			# lis	12,jmptab@ha
    +	addi    %r12,%r12,0		# addi  12,12,jmptab@l
    +	subf	%r11,%r12,%r11		# reloff
    +	li	%r12,2
    +	srw	%r11,%r11,%r12		# index = reloff/sizeof(Elf_Addr)
     _ENTRY(_rtld_powerpc_pltresolve)
             lis     %r12,0			# lis   12,_rtld_bind_start@ha
             addi    %r12,%r12,0		# addi  12,12,_rtld_bind_start@l
    
    From 1b90b87fbad469d067fd29debee76d04b4933b14 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Mon, 22 Mar 2010 09:29:56 +0000
    Subject: [PATCH 1627/2592] MFC r204879: Teach procstat(1) to display some
     information about signal disposition and pending/blocked status for signals.
    
    MFC r204880:
    Add file forgotten in r204879.
    ---
     usr.bin/procstat/Makefile        |   1 +
     usr.bin/procstat/procstat.1      |  61 +++++++++++++-
     usr.bin/procstat/procstat.c      |  26 ++++--
     usr.bin/procstat/procstat.h      |   4 +-
     usr.bin/procstat/procstat_sigs.c | 139 +++++++++++++++++++++++++++++++
     5 files changed, 223 insertions(+), 8 deletions(-)
     create mode 100644 usr.bin/procstat/procstat_sigs.c
    
    diff --git a/usr.bin/procstat/Makefile b/usr.bin/procstat/Makefile
    index 6cb58956518..ddad5edb402 100644
    --- a/usr.bin/procstat/Makefile
    +++ b/usr.bin/procstat/Makefile
    @@ -9,6 +9,7 @@ SRCS=	procstat.c		\
     	procstat_cred.c		\
     	procstat_files.c	\
     	procstat_kstack.c	\
    +	procstat_sigs.c		\
     	procstat_threads.c	\
     	procstat_vm.c
     
    diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1
    index 0fdff9a3c52..dab1c2b7ad8 100644
    --- a/usr.bin/procstat/procstat.1
    +++ b/usr.bin/procstat/procstat.1
    @@ -25,7 +25,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd August 20, 2008
    +.Dd March 7, 2010
     .Dt PROCSTAT 1
     .Os
     .Sh NAME
    @@ -34,8 +34,9 @@
     .Sh SYNOPSIS
     .Nm
     .Op Fl h
    +.Op Fl n
     .Op Fl w Ar interval
    -.Op Fl b | c | f | k | s | t | v
    +.Op Fl b | c | f | i | j | k | s | t | v
     .Op Fl a | Ar pid ...
     .Sh DESCRIPTION
     The
    @@ -56,6 +57,10 @@ Display binary information for the process.
     Display command line arguments for the process.
     .It Fl f
     Display file descriptor information for the process.
    +.It Fl i
    +Display signal pending and disposition information for the process.
    +.It Fl j
    +Display signal pending and blocked information for the process threads.
     .It Fl k
     Display the stacks of kernel threads in the process, excluding stacks of
     threads currently running on a CPU and threads with stacks swapped to disk.
    @@ -198,6 +203,58 @@ direct I/O
     .It l
     lock held
     .El
    +.Ss Signal Disposition Information
    +Display signal pending and disposition for a process:
    +.Pp
    +.Bl -tag -width ident -compact
    +.It PID
    +process ID
    +.It COMM
    +command
    +.It SIG
    +signal name
    +.It FLAGS
    +process signal disposition details, three symbols
    +.Bl -tag -width X -compact
    +.It P
    +if signal is pending in the global process queue, - otherwise
    +.It I
    +if signal delivery disposition is SIGIGN, - otherwise
    +.It C
    +if signal delivery is to catch it, - otherwise
    +.El
    +.El
    +.Pp
    +If
    +.Fl n
    +switch is given, the signal numbers are shown instead of signal names.
    +.Ss Thread Signal Information
    +Display signal pending and blocked for a process threads:
    +.Pp
    +.Bl -tag -width ident -compact
    +.It PID
    +process ID
    +.It COMM
    +command
    +.It TID
    +thread ID
    +.It SIG
    +signal name
    +.It FLAGS
    +thread signal delivery status, two symbols
    +.Bl -tag -width X -compact
    +.It P
    +if signal is pending for the thread, - otherwise
    +.It B
    +if signal is blocked in the thread signal mask, - if not blocked
    +.El
    +.El
    +.Pp
    +The
    +.Fl n
    +switch has the same effect as for the
    +.Fl i
    +switch, the signals numbers are shown instead of signal names.
     .Ss Kernel Thread Stacks
     Display kernel thread stacks for a process, allowing further interpretation
     of thread wait channels.
    diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c
    index bc026821f8f..ee95ae29005 100644
    --- a/usr.bin/procstat/procstat.c
    +++ b/usr.bin/procstat/procstat.c
    @@ -38,15 +38,15 @@
     
     #include "procstat.h"
     
    -static int aflag, bflag, cflag, fflag, kflag, sflag, tflag, vflag;
    -int	hflag;
    +static int aflag, bflag, cflag, fflag, iflag, jflag, kflag, sflag, tflag, vflag;
    +int	hflag, nflag;
     
     static void
     usage(void)
     {
     
    -	fprintf(stderr, "usage: procstat [-h] [-w interval] [-b | -c | -f | "
    -	    "-k | -s | -t | -v]\n");
    +	fprintf(stderr, "usage: procstat [-h] [-n] [-w interval] [-b | -c | -f | "
    +	    "-i | -j | -k | -s | -t | -v]\n");
     	fprintf(stderr, "                [-a | pid ...]\n");
     	exit(EX_USAGE);
     }
    @@ -61,6 +61,10 @@ procstat(pid_t pid, struct kinfo_proc *kipp)
     		procstat_args(pid, kipp);
     	else if (fflag)
     		procstat_files(pid, kipp);
    +	else if (iflag)
    +		procstat_sigs(pid, kipp);
    +	else if (jflag)
    +		procstat_threads_sigs(pid, kipp);
     	else if (kflag)
     		procstat_kstack(pid, kipp, kflag);
     	else if (sflag)
    @@ -109,7 +113,7 @@ main(int argc, char *argv[])
     	char *dummy;
     
     	interval = 0;
    -	while ((ch = getopt(argc, argv, "abcfkhstvw:")) != -1) {
    +	while ((ch = getopt(argc, argv, "abcfijknhstvw:")) != -1) {
     		switch (ch) {
     		case 'a':
     			aflag++;
    @@ -127,10 +131,22 @@ main(int argc, char *argv[])
     			fflag++;
     			break;
     
    +		case 'i':
    +			iflag++;
    +			break;
    +
    +		case 'j':
    +			jflag++;
    +			break;
    +
     		case 'k':
     			kflag++;
     			break;
     
    +		case 'n':
    +			nflag++;
    +			break;
    +
     		case 'h':
     			hflag++;
     			break;
    diff --git a/usr.bin/procstat/procstat.h b/usr.bin/procstat/procstat.h
    index 8bacab72876..d73a2030775 100644
    --- a/usr.bin/procstat/procstat.h
    +++ b/usr.bin/procstat/procstat.h
    @@ -29,7 +29,7 @@
     #ifndef PROCSTAT_H
     #define	PROCSTAT_H
     
    -extern int	hflag;
    +extern int	hflag, nflag;
     
     struct kinfo_proc;
     void	kinfo_proc_sort(struct kinfo_proc *kipp, int count);
    @@ -40,7 +40,9 @@ void	procstat_bin(pid_t pid, struct kinfo_proc *kipp);
     void	procstat_cred(pid_t pid, struct kinfo_proc *kipp);
     void	procstat_files(pid_t pid, struct kinfo_proc *kipp);
     void	procstat_kstack(pid_t pid, struct kinfo_proc *kipp, int kflag);
    +void	procstat_sigs(pid_t pid, struct kinfo_proc *kipp);
     void	procstat_threads(pid_t pid, struct kinfo_proc *kipp);
    +void	procstat_threads_sigs(pid_t pid, struct kinfo_proc *kipp);
     void	procstat_vm(pid_t pid, struct kinfo_proc *kipp);
     
     #endif /* !PROCSTAT_H */
    diff --git a/usr.bin/procstat/procstat_sigs.c b/usr.bin/procstat/procstat_sigs.c
    new file mode 100644
    index 00000000000..b1f5e35fb46
    --- /dev/null
    +++ b/usr.bin/procstat/procstat_sigs.c
    @@ -0,0 +1,139 @@
    +/*-
    + * Copyright (c) 2010 Konstantin Belousov
    + * 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$
    + */
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include "procstat.h"
    +
    +static void
    +procstat_print_signame(int sig)
    +{
    +	char name[12];
    +	int i;
    +
    +	if (!nflag && sig < sys_nsig) {
    +		strlcpy(name, sys_signame[sig], sizeof(name));
    +		for (i = 0; name[i] != 0; i++)
    +			name[i] = toupper(name[i]);
    +		printf("%-7s ", name);
    +	} else
    +		printf("%-7d ", sig);
    +}
    +
    +static void
    +procstat_print_sig(const sigset_t *set, int sig, char flag)
    +{
    +
    +	printf("%c", sigismember(set, sig) ? flag : '-');
    +}
    +
    +void
    +procstat_sigs(pid_t pid, struct kinfo_proc *kipp)
    +{
    +	int j;
    +
    +	if (!hflag)
    +		printf("%5s %-16s %-7s %4s\n", "PID", "COMM", "SIG", "FLAGS");
    +
    +	for (j = 1; j <= _SIG_MAXSIG; j++) {
    +		printf("%5d ", pid);
    +		printf("%-16s ", kipp->ki_comm);
    +		procstat_print_signame(j);
    +		printf(" ");
    +		procstat_print_sig(&kipp->ki_siglist, j, 'P');
    +		procstat_print_sig(&kipp->ki_sigignore, j, 'I');
    +		procstat_print_sig(&kipp->ki_sigcatch, j, 'C');
    +		printf("\n");
    +	}
    +}
    +
    +void
    +procstat_threads_sigs(pid_t pid, struct kinfo_proc *kipp)
    +{
    +	struct kinfo_proc *kip;
    +	int error, name[4], j;
    +	unsigned int i;
    +	size_t len;
    +
    +	if (!hflag)
    +		printf("%5s %6s %-16s %-7s %4s\n", "PID", "TID", "COMM",
    +		     "SIG", "FLAGS");
    +
    +	/*
    +	 * We need to re-query for thread information, so don't use *kipp.
    +	 */
    +	name[0] = CTL_KERN;
    +	name[1] = KERN_PROC;
    +	name[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD;
    +	name[3] = pid;
    +
    +	len = 0;
    +	error = sysctl(name, 4, NULL, &len, NULL, 0);
    +	if (error < 0 && errno != ESRCH) {
    +		warn("sysctl: kern.proc.pid: %d", pid);
    +		return;
    +	}
    +	if (error < 0)
    +		return;
    +
    +	kip = malloc(len);
    +	if (kip == NULL)
    +		err(-1, "malloc");
    +
    +	if (sysctl(name, 4, kip, &len, NULL, 0) < 0) {
    +		warn("sysctl: kern.proc.pid: %d", pid);
    +		free(kip);
    +		return;
    +	}
    +
    +	kinfo_proc_sort(kip, len / sizeof(*kipp));
    +	for (i = 0; i < len / sizeof(*kipp); i++) {
    +		kipp = &kip[i];
    +		for (j = 1; j <= _SIG_MAXSIG; j++) {
    +			printf("%5d ", pid);
    +			printf("%6d ", kipp->ki_tid);
    +			printf("%-16s ", kipp->ki_comm);
    +			procstat_print_signame(j);
    +			printf(" ");
    +			procstat_print_sig(&kipp->ki_siglist, j, 'P');
    +			procstat_print_sig(&kipp->ki_sigmask, j, 'B');
    +			printf("\n");
    +		}
    +	}
    +	free(kip);
    +}
    
    From 948165be1caad9d8d430a3924c50b6a0aa1335a9 Mon Sep 17 00:00:00 2001
    From: Gleb Smirnoff 
    Date: Mon, 22 Mar 2010 10:11:59 +0000
    Subject: [PATCH 1628/2592] MFC r200183 by luigi:
    
      restore setting of sin_len (was removed in 1.146 last february) as
      it seems that now it is necessary for 'forward' to work outside lo0.
    
    Approved by:	luigi
    ---
     sbin/ipfw/ipfw2.c | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
    index 58094a18e97..7edfbd56313 100644
    --- a/sbin/ipfw/ipfw2.c
    +++ b/sbin/ipfw/ipfw2.c
    @@ -2740,9 +2740,11 @@ chkarg:
     
     		/*
     		 * In the kernel we assume AF_INET and use only
    -		 * sin_port and sin_addr.
    +		 * sin_port and sin_addr. Remember to set sin_len as
    +		 * the routing code seems to use it too.
     		 */
     		p->sa.sin_family = AF_INET;
    +		p->sa.sin_len = sizeof(struct sockaddr_in);
     		p->sa.sin_port = 0;
     		/*
     		 * locate the address-port separator (':' or ',')
    
    From c6c73f98802e3bcde0855ad3e717b042dbfdd29b Mon Sep 17 00:00:00 2001
    From: Andrew Gallatin 
    Date: Mon, 22 Mar 2010 11:18:51 +0000
    Subject: [PATCH 1629/2592] MFC 205255: Fix 2 bugs in mxge_attach()
    
    ---
     sys/dev/mxge/if_mxge.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
    index a9046d0131e..2dcd730278e 100644
    --- a/sys/dev/mxge/if_mxge.c
    +++ b/sys/dev/mxge/if_mxge.c
    @@ -4610,8 +4610,6 @@ mxge_attach(device_t dev)
     		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 */
    @@ -4717,7 +4715,7 @@ mxge_attach(device_t dev)
     	err = mxge_alloc_rings(sc);
     	if (err != 0) {
     		device_printf(sc->dev, "failed to allocate rings\n");
    -		goto abort_with_dmabench;
    +		goto abort_with_slices;
     	}
     
     	err = mxge_add_irq(sc);
    @@ -4770,6 +4768,8 @@ mxge_attach(device_t dev)
     	ifp->if_transmit = mxge_transmit;
     	ifp->if_qflush = mxge_qflush;
     #endif
    +	taskqueue_start_threads(&sc->tq, 1, PI_NET, "%s taskq",
    +				device_get_nameunit(sc->dev));
     	callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
     	return 0;
     
    
    From accbb468d5727112d5b66a4a2c5bc30edb4e203c Mon Sep 17 00:00:00 2001
    From: Andrew Gallatin 
    Date: Mon, 22 Mar 2010 14:50:08 +0000
    Subject: [PATCH 1630/2592] MFC 204212: Update mxge to support
     IFCAP_VLAN_HWTSO.
    
    ---
     sys/dev/mxge/if_mxge.c | 12 ++++++++++++
     1 file changed, 12 insertions(+)
    
    diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
    index 2dcd730278e..643a78a9dce 100644
    --- a/sys/dev/mxge/if_mxge.c
    +++ b/sys/dev/mxge/if_mxge.c
    @@ -4122,6 +4122,13 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     		}
     		if (mask & IFCAP_VLAN_HWTAGGING)
     			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    +		if (mask & IFCAP_VLAN_HWTSO)
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
    +
    +		if (!(ifp->if_capabilities & IFCAP_VLAN_HWTSO) ||
    +		    !(ifp->if_capenable & IFCAP_VLAN_HWTAGGING))
    +			ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
    +
     		mtx_unlock(&sc->driver_mtx);
     		VLAN_CAPABILITIES(ifp);
     
    @@ -4733,6 +4740,11 @@ mxge_attach(device_t dev)
     
     #ifdef MXGE_NEW_VLAN_API
     	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM;
    +
    +	/* Only FW 1.4.32 and newer can do TSO over vlans */
    +	if (sc->fw_ver_major == 1 && sc->fw_ver_minor == 4 &&
    +	    sc->fw_ver_tiny >= 32)
    +		ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
     #endif
     
     	sc->max_mtu = mxge_max_mtu(sc);
    
    From f5ccef8fd9baedaeb699cbad6d99e275c6e590ef Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Mon, 22 Mar 2010 15:52:26 +0000
    Subject: [PATCH 1631/2592] MFC 204950,205020: Use thr_once() with once_t
     controls to initialize various thread_key_t objects used to provide
     per-thread storage in the RPC code.  Almost all of these used double-checking
     with a dedicated mutex (tsd_lock) to do this before.  However, that is not
     always safe with more relaxed memory orders. There were also other bugs, such
     as one in __rpc_createrr() that caused a new key to be allocated each time
     __rpc_createrr() was invoked.
    
    ---
     lib/libc/rpc/Symbol.map     |  4 ----
     lib/libc/rpc/clnt_simple.c  | 22 ++++++++++++++++------
     lib/libc/rpc/getnetconfig.c | 29 +++++++++++++++--------------
     lib/libc/rpc/key_call.c     | 20 +++++++++++++-------
     lib/libc/rpc/mt_misc.c      | 27 +++++++++++++--------------
     lib/libc/rpc/mt_misc.h      |  1 -
     lib/libc/rpc/rpc_generic.c  | 28 +++++++++++++++-------------
     lib/libc/rpc/rpc_soc.c      | 15 +++++++++------
     8 files changed, 81 insertions(+), 65 deletions(-)
    
    diff --git a/lib/libc/rpc/Symbol.map b/lib/libc/rpc/Symbol.map
    index ccf0bfa79b6..4f356de9974 100644
    --- a/lib/libc/rpc/Symbol.map
    +++ b/lib/libc/rpc/Symbol.map
    @@ -239,10 +239,6 @@ FBSDprivate_1.0 {
     	__key_encryptsession_pk_LOCAL;
     	__key_decryptsession_pk_LOCAL;
     	__key_gendes_LOCAL;
    -	__tsd_lock;	/*
    -			 * Why does usr.bin/rpcinfo/Makefile need rpc_generic.c?
    -			 * Remove this hack if rpcinfo stops building with it.
    -			 */
     	__svc_clean_idle;
     	__rpc_gss_unwrap;
     	__rpc_gss_unwrap_stub;
    diff --git a/lib/libc/rpc/clnt_simple.c b/lib/libc/rpc/clnt_simple.c
    index 12b6679f240..ba21d2d8237 100644
    --- a/lib/libc/rpc/clnt_simple.c
    +++ b/lib/libc/rpc/clnt_simple.c
    @@ -76,7 +76,11 @@ struct rpc_call_private {
     	char	nettype[NETIDLEN];	/* Network type */
     };
     static struct rpc_call_private *rpc_call_private_main;
    +static thread_key_t rpc_call_key;
    +static once_t rpc_call_once = ONCE_INITIALIZER;
    +static int rpc_call_key_error;
     
    +static void rpc_call_key_init(void);
     static void rpc_call_destroy(void *);
     
     static void
    @@ -91,6 +95,13 @@ rpc_call_destroy(void *vp)
     	}
     }
     
    +static void
    +rpc_call_key_init(void)
    +{
    +
    +	rpc_call_key_error = thr_keycreate(&rpc_call_key, rpc_call_destroy);
    +}
    +
     /*
      * This is the simplified interface to the client rpc layer.
      * The client handle is not destroyed here and is reused for
    @@ -112,17 +123,16 @@ rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype)
     	struct rpc_call_private *rcp = (struct rpc_call_private *) 0;
     	enum clnt_stat clnt_stat;
     	struct timeval timeout, tottimeout;
    -	static thread_key_t rpc_call_key;
     	int main_thread = 1;
     
     	if ((main_thread = thr_main())) {
     		rcp = rpc_call_private_main;
     	} else {
    -		if (rpc_call_key == 0) {
    -			mutex_lock(&tsd_lock);
    -			if (rpc_call_key == 0)
    -				thr_keycreate(&rpc_call_key, rpc_call_destroy);
    -			mutex_unlock(&tsd_lock);
    +		if (thr_once(&rpc_call_once, rpc_call_key_init) != 0 ||
    +		    rpc_call_key_error != 0) {
    +			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
    +			rpc_createerr.cf_error.re_errno = rpc_call_key_error;
    +			return (rpc_createerr.cf_stat);
     		}
     		rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key);
     	}
    diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c
    index e5db51ac3a3..1310e361501 100644
    --- a/lib/libc/rpc/getnetconfig.c
    +++ b/lib/libc/rpc/getnetconfig.c
    @@ -130,21 +130,29 @@ static struct netconfig *dup_ncp(struct netconfig *);
     
     
     static FILE *nc_file;		/* for netconfig db */
    -static pthread_mutex_t nc_file_lock = PTHREAD_MUTEX_INITIALIZER;
    +static mutex_t nc_file_lock = MUTEX_INITIALIZER;
     
     static struct netconfig_info	ni = { 0, 0, NULL, NULL};
    -static pthread_mutex_t ni_lock = PTHREAD_MUTEX_INITIALIZER;
    +static mutex_t ni_lock = MUTEX_INITIALIZER;
     
    +static thread_key_t nc_key;
    +static once_t nc_once = ONCE_INITIALIZER;
    +static int nc_key_error;
    +
    +static void
    +nc_key_init(void)
    +{
    +
    +	nc_key_error = thr_keycreate(&nc_key, free);
    +}
     
     #define MAXNETCONFIGLINE    1000
     
     static int *
     __nc_error()
     {
    -	static pthread_mutex_t nc_lock = PTHREAD_MUTEX_INITIALIZER;
    -	static thread_key_t nc_key = 0;
     	static int nc_error = 0;
    -	int error, *nc_addr;
    +	int *nc_addr;
     
     	/*
     	 * Use the static `nc_error' if we are the main thread
    @@ -153,15 +161,8 @@ __nc_error()
     	 */
     	if (thr_main())
     		return (&nc_error);
    -	if (nc_key == 0) {
    -		error = 0;
    -		mutex_lock(&nc_lock);
    -		if (nc_key == 0)
    -			error = thr_keycreate(&nc_key, free);
    -		mutex_unlock(&nc_lock);
    -		if (error)
    -			return (&nc_error);
    -	}
    +	if (thr_once(&nc_once, nc_key_init) != 0 || nc_key_error != 0)
    +		return (&nc_error);
     	if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) {
     		nc_addr = (int *)malloc(sizeof (int));
     		if (thr_setspecific(nc_key, (void *) nc_addr) != 0) {
    diff --git a/lib/libc/rpc/key_call.c b/lib/libc/rpc/key_call.c
    index 6cc1139ab52..afb11c83884 100644
    --- a/lib/libc/rpc/key_call.c
    +++ b/lib/libc/rpc/key_call.c
    @@ -279,6 +279,9 @@ struct  key_call_private {
     	uid_t	uid;		/* user-id at last authorization */
     };
     static struct key_call_private *key_call_private_main = NULL;
    +static thread_key_t key_call_key;
    +static once_t key_call_once = ONCE_INITIALIZER;
    +static int key_call_key_error;
     
     static void
     key_call_destroy(void *vp)
    @@ -292,6 +295,13 @@ key_call_destroy(void *vp)
     	}
     }
     
    +static void
    +key_call_init(void)
    +{
    +
    +	key_call_key_error = thr_keycreate(&key_call_key, key_call_destroy);
    +}
    +
     /*
      * Keep the handle cached.  This call may be made quite often.
      */
    @@ -307,7 +317,6 @@ int	vers;
     	struct utsname u;
     	int main_thread;
     	int fd;
    -	static thread_key_t key_call_key;
     
     #define	TOTAL_TIMEOUT	30	/* total timeout talking to keyserver */
     #define	TOTAL_TRIES	5	/* Number of tries */
    @@ -315,12 +324,9 @@ int	vers;
     	if ((main_thread = thr_main())) {
     		kcp = key_call_private_main;
     	} else {
    -		if (key_call_key == 0) {
    -			mutex_lock(&tsd_lock);
    -			if (key_call_key == 0)
    -				thr_keycreate(&key_call_key, key_call_destroy);
    -			mutex_unlock(&tsd_lock);
    -		}
    +		if (thr_once(&key_call_once, key_call_init) != 0 ||
    +		    key_call_key_error != 0)
    +			return ((CLIENT *) NULL);
     		kcp = (struct key_call_private *)thr_getspecific(key_call_key);
     	}	
     	if (kcp == (struct key_call_private *)NULL) {
    diff --git a/lib/libc/rpc/mt_misc.c b/lib/libc/rpc/mt_misc.c
    index 62416117382..7abcaedaee2 100644
    --- a/lib/libc/rpc/mt_misc.c
    +++ b/lib/libc/rpc/mt_misc.c
    @@ -28,7 +28,6 @@ __FBSDID("$FreeBSD$");
     #define	proglst_lock		__proglst_lock
     #define	rpcsoc_lock		__rpcsoc_lock
     #define	svcraw_lock		__svcraw_lock
    -#define	tsd_lock		__tsd_lock
     #define	xprtlist_lock		__xprtlist_lock
     
     /* protects the services list (svc.c) */
    @@ -76,33 +75,33 @@ pthread_mutex_t	rpcsoc_lock = PTHREAD_MUTEX_INITIALIZER;
     /* svc_raw.c serialization */
     pthread_mutex_t	svcraw_lock = PTHREAD_MUTEX_INITIALIZER;
     
    -/* protects TSD key creation */
    -pthread_mutex_t	tsd_lock = PTHREAD_MUTEX_INITIALIZER;
    -
     /* xprtlist (svc_generic.c) */
     pthread_mutex_t	xprtlist_lock = PTHREAD_MUTEX_INITIALIZER;
     
     #undef	rpc_createerr
     
     struct rpc_createerr rpc_createerr;
    +static thread_key_t rce_key;
    +static once_t rce_once = ONCE_INITIALIZER;
    +static int rce_key_error;
    +
    +static void
    +rce_key_init(void)
    +{
    +
    +	rce_key_error = thr_keycreate(&rce_key, free);
    +}
     
     struct rpc_createerr *
     __rpc_createerr()
     {
    -	static thread_key_t rce_key = 0;
     	struct rpc_createerr *rce_addr = 0;
     
     	if (thr_main())
     		return (&rpc_createerr);
    -	if ((rce_addr =
    -	    (struct rpc_createerr *)thr_getspecific(rce_key)) != 0) {
    -		mutex_lock(&tsd_lock);
    -		if (thr_keycreate(&rce_key, free) != 0) {
    -			mutex_unlock(&tsd_lock);
    -			return (&rpc_createerr);
    -		}
    -		mutex_unlock(&tsd_lock);
    -	}
    +	if (thr_once(&rce_once, rce_key_init) != 0 || rce_key_error != 0)
    +		return (&rpc_createerr);
    +	rce_addr = (struct rpc_createerr *)thr_getspecific(rce_key);
     	if (!rce_addr) {
     		rce_addr = (struct rpc_createerr *)
     			malloc(sizeof (struct rpc_createerr));
    diff --git a/lib/libc/rpc/mt_misc.h b/lib/libc/rpc/mt_misc.h
    index e785c306368..9cc2349c126 100644
    --- a/lib/libc/rpc/mt_misc.h
    +++ b/lib/libc/rpc/mt_misc.h
    @@ -42,7 +42,6 @@
     #define	proglst_lock		__proglst_lock
     #define	rpcsoc_lock		__rpcsoc_lock
     #define	svcraw_lock		__svcraw_lock
    -#define	tsd_lock		__tsd_lock
     #define	xprtlist_lock		__xprtlist_lock
     
     extern pthread_rwlock_t	svc_lock;
    diff --git a/lib/libc/rpc/rpc_generic.c b/lib/libc/rpc/rpc_generic.c
    index 81bd92b1e13..ab259d59f30 100644
    --- a/lib/libc/rpc/rpc_generic.c
    +++ b/lib/libc/rpc/rpc_generic.c
    @@ -221,6 +221,18 @@ getnettype(nettype)
     	return (_rpctypelist[i].type);
     }
     
    +static thread_key_t tcp_key, udp_key;
    +static once_t keys_once = ONCE_INITIALIZER;
    +static int tcp_key_error, udp_key_error;
    +
    +static void
    +keys_init(void)
    +{
    +
    +	tcp_key_error = thr_keycreate(&tcp_key, free);
    +	udp_key_error = thr_keycreate(&udp_key, free);
    +}
    +
     /*
      * For the given nettype (tcp or udp only), return the first structure found.
      * This should be freed by calling freenetconfigent()
    @@ -236,25 +248,15 @@ __rpc_getconfip(nettype)
     	static char *netid_udp_main;
     	struct netconfig *dummy;
     	int main_thread;
    -	static thread_key_t tcp_key, udp_key;
     
     	if ((main_thread = thr_main())) {
     		netid_udp = netid_udp_main;
     		netid_tcp = netid_tcp_main;
     	} else {
    -		if (tcp_key == 0) {
    -			mutex_lock(&tsd_lock);
    -			if (tcp_key == 0)
    -				thr_keycreate(&tcp_key, free);
    -			mutex_unlock(&tsd_lock);
    -		}
    +		if (thr_once(&keys_once, keys_init) != 0 ||
    +		    tcp_key_error != 0 || udp_key_error != 0)
    +			return (NULL);
     		netid_tcp = (char *)thr_getspecific(tcp_key);
    -		if (udp_key == 0) {
    -			mutex_lock(&tsd_lock);
    -			if (udp_key == 0)
    -				thr_keycreate(&udp_key, free);
    -			mutex_unlock(&tsd_lock);
    -		}
     		netid_udp = (char *)thr_getspecific(udp_key);
     	}
     	if (!netid_udp && !netid_tcp) {
    diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c
    index 59220634db1..2568d4373b2 100644
    --- a/lib/libc/rpc/rpc_soc.c
    +++ b/lib/libc/rpc/rpc_soc.c
    @@ -360,6 +360,14 @@ registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
      */
     static thread_key_t	clnt_broadcast_key;
     static resultproc_t	clnt_broadcast_result_main;
    +static once_t		clnt_broadcast_once = ONCE_INITIALIZER;
    +
    +static void
    +clnt_broadcast_key_init(void)
    +{
    +
    +	thr_keycreate(&clnt_broadcast_key, free);
    +}
     
     /*
      * Need to translate the netbuf address into sockaddr_in address.
    @@ -402,12 +410,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
     	if (thr_main())
     		clnt_broadcast_result_main = eachresult;
     	else {
    -		if (clnt_broadcast_key == 0) {
    -			mutex_lock(&tsd_lock);
    -			if (clnt_broadcast_key == 0)
    -				thr_keycreate(&clnt_broadcast_key, free);
    -			mutex_unlock(&tsd_lock);
    -		}
    +		thr_once(&clnt_broadcast_once, clnt_broadcast_key_init);
     		thr_setspecific(clnt_broadcast_key, (void *) eachresult);
     	}
     	return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers,
    
    From f2f7c1447aa1006933799c95b7c724009b30f1ff Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Mon, 22 Mar 2010 16:40:10 +0000
    Subject: [PATCH 1632/2592] mfc r205179: print correctly addresses with an OR
     block
    
    ---
     sbin/ipfw/ipfw2.c | 25 +++++++++++++++++--------
     1 file changed, 17 insertions(+), 8 deletions(-)
    
    diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
    index 7edfbd56313..b19f390b294 100644
    --- a/sbin/ipfw/ipfw2.c
    +++ b/sbin/ipfw/ipfw2.c
    @@ -895,9 +895,9 @@ print_icmptypes(ipfw_insn_u32 *cmd)
     #define	HAVE_DSTIP	0x0004
     #define	HAVE_PROTO4	0x0008
     #define	HAVE_PROTO6	0x0010
    +#define	HAVE_IP		0x0100
     #define	HAVE_OPTIONS	0x8000
     
    -#define	HAVE_IP		(HAVE_PROTO | HAVE_SRCIP | HAVE_DSTIP)
     static void
     show_prerequisites(int *flags, int want, int cmd __unused)
     {
    @@ -998,7 +998,9 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
     		switch(cmd->opcode) {
     		case O_CHECK_STATE:
     			printf("check-state");
    -			flags = HAVE_IP; /* avoid printing anything else */
    +			/* avoid printing anything else */
    +			flags = HAVE_PROTO | HAVE_SRCIP |
    +				HAVE_DSTIP | HAVE_IP;
     			break;
     
     		case O_ACCEPT:
    @@ -1136,7 +1138,8 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
     			show_prerequisites(&flags, HAVE_PROTO, 0);
     			printf(" from any to any");
     		}
    -		flags |= HAVE_IP | HAVE_OPTIONS;
    +		flags |= HAVE_IP | HAVE_OPTIONS | HAVE_PROTO |
    +			 HAVE_SRCIP | HAVE_DSTIP;
     	}
     
     	if (co.comment_only)
    @@ -1225,9 +1228,12 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
     		break;
     
     		case O_IP_DSTPORT:
    -			show_prerequisites(&flags, HAVE_IP, 0);
    +			show_prerequisites(&flags,
    +				HAVE_PROTO | HAVE_SRCIP |
    +				HAVE_DSTIP | HAVE_IP, 0);
     		case O_IP_SRCPORT:
    -			show_prerequisites(&flags, HAVE_PROTO|HAVE_SRCIP, 0);
    +			show_prerequisites(&flags,
    +				HAVE_PROTO | HAVE_SRCIP, 0);
     			if ((cmd->len & F_OR) && !or_block)
     				printf(" {");
     			if (cmd->len & F_NOT)
    @@ -1248,7 +1254,8 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
     			if ((flags & (HAVE_PROTO4 | HAVE_PROTO6)) &&
     			    !(flags & HAVE_PROTO))
     				show_prerequisites(&flags,
    -				    HAVE_IP | HAVE_OPTIONS, 0);
    +				    HAVE_PROTO | HAVE_IP | HAVE_SRCIP |
    +				    HAVE_DSTIP | HAVE_OPTIONS, 0);
     			if (flags & HAVE_OPTIONS)
     				printf(" proto");
     			if (pe)
    @@ -1266,7 +1273,8 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
     				    ((cmd->opcode == O_IP4) &&
     				    (flags & HAVE_PROTO4)))
     					break;
    -			show_prerequisites(&flags, HAVE_IP | HAVE_OPTIONS, 0);
    +			show_prerequisites(&flags, HAVE_PROTO | HAVE_SRCIP |
    +				    HAVE_DSTIP | HAVE_IP | HAVE_OPTIONS, 0);
     			if ((cmd->len & F_OR) && !or_block)
     				printf(" {");
     			if (cmd->len & F_NOT && cmd->opcode != O_IN)
    @@ -1520,7 +1528,8 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
     			or_block = 0;
     		}
     	}
    -	show_prerequisites(&flags, HAVE_IP, 0);
    +	show_prerequisites(&flags, HAVE_PROTO | HAVE_SRCIP | HAVE_DSTIP
    +				              | HAVE_IP, 0);
     	if (comment)
     		printf(" // %s", comment);
     	printf("\n");
    
    From e651ff978b72b790458d41e02f56e78d1121d8ba Mon Sep 17 00:00:00 2001
    From: Jung-uk Kim 
    Date: Mon, 22 Mar 2010 19:50:57 +0000
    Subject: [PATCH 1633/2592] MFC:	r203943
    
    Remove COMPILATIONDATE from the default section.  This string is no longer
    being substituted since r162063.
    ---
     etc/ppp/ppp.conf | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/etc/ppp/ppp.conf b/etc/ppp/ppp.conf
    index 251231468fd..2b63834839f 100644
    --- a/etc/ppp/ppp.conf
    +++ b/etc/ppp/ppp.conf
    @@ -10,7 +10,7 @@
     
     default:
      set log Phase Chat LCP IPCP CCP tun command
    - ident user-ppp VERSION (built COMPILATIONDATE)
    + ident user-ppp VERSION
     
      # Ensure that "device" references the correct serial port
      # for your modem. (cuau0 = COM1, cuau1 = COM2)
    
    From 1288863fa29e734e19dc07b68868e03a1e7e14e6 Mon Sep 17 00:00:00 2001
    From: Jung-uk Kim 
    Date: Mon, 22 Mar 2010 19:59:00 +0000
    Subject: [PATCH 1634/2592] MFC:	r205092
    
    Tidy up callout for select(2) and read timeout.
    
    - Add a missing callout_drain(9) before the descriptor deallocation.[1]
    - Prefer callout_init_mtx(9) over callout_init(9) and let the callout
    subsystem handle the mutex for callout function.
    
    PR:		kern/144453
    Submitted by:	Alexander Sack (asack at niksun dot com)[1]
    ---
     sys/net/bpf.c | 9 ++++++---
     1 file changed, 6 insertions(+), 3 deletions(-)
    
    diff --git a/sys/net/bpf.c b/sys/net/bpf.c
    index 60f8924d580..fcac33d44dc 100644
    --- a/sys/net/bpf.c
    +++ b/sys/net/bpf.c
    @@ -611,6 +611,7 @@ bpf_dtor(void *data)
     	mac_bpfdesc_destroy(d);
     #endif /* MAC */
     	knlist_destroy(&d->bd_sel.si_note);
    +	callout_drain(&d->bd_callout);
     	bpf_freed(d);
     	free(d, M_BPF);
     }
    @@ -648,7 +649,7 @@ bpfopen(struct cdev *dev, int flags, int fmt, struct thread *td)
     	mac_bpfdesc_create(td->td_ucred, d);
     #endif
     	mtx_init(&d->bd_mtx, devtoname(dev), "bpf cdev lock", MTX_DEF);
    -	callout_init(&d->bd_callout, CALLOUT_MPSAFE);
    +	callout_init_mtx(&d->bd_callout, &d->bd_mtx, 0);
     	knlist_init_mtx(&d->bd_sel.si_note, &d->bd_mtx);
     
     	return (0);
    @@ -804,13 +805,15 @@ bpf_timed_out(void *arg)
     {
     	struct bpf_d *d = (struct bpf_d *)arg;
     
    -	BPFD_LOCK(d);
    +	BPFD_LOCK_ASSERT(d);
    +
    +	if (callout_pending(&d->bd_callout) || !callout_active(&d->bd_callout))
    +		return;
     	if (d->bd_state == BPF_WAITING) {
     		d->bd_state = BPF_TIMED_OUT;
     		if (d->bd_slen != 0)
     			bpf_wakeup(d);
     	}
    -	BPFD_UNLOCK(d);
     }
     
     static int
    
    From a0bc6d1ca6a57bf77277a35a3bf593cbc8adc10a Mon Sep 17 00:00:00 2001
    From: Jung-uk Kim 
    Date: Mon, 22 Mar 2010 20:36:35 +0000
    Subject: [PATCH 1635/2592] MFC:	r205223
    
    Fix a long standing regression of readdir(3) in fdescfs(5) introduced
    in r1.48.  We were stopping at the first null pointer when multiple file
    descriptors were opened and one in the middle was closed.  This restores
    traditional behaviour of fdescfs.
    ---
     sys/fs/fdescfs/fdesc_vnops.c | 29 +++++++++++++----------------
     1 file changed, 13 insertions(+), 16 deletions(-)
    
    diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c
    index 07b2547b175..43cf65efb1a 100644
    --- a/sys/fs/fdescfs/fdesc_vnops.c
    +++ b/sys/fs/fdescfs/fdesc_vnops.c
    @@ -522,11 +522,10 @@ fdesc_readdir(ap)
     
     	FILEDESC_SLOCK(fdp);
     	while (i < fdp->fd_nfiles + 2 && uio->uio_resid >= UIO_MX) {
    +		bzero((caddr_t)dp, UIO_MX);
     		switch (i) {
     		case 0:	/* `.' */
     		case 1: /* `..' */
    -			bzero((caddr_t)dp, UIO_MX);
    -
     			dp->d_fileno = i + FD_ROOT;
     			dp->d_namlen = i + 1;
     			dp->d_reclen = UIO_MX;
    @@ -535,26 +534,24 @@ fdesc_readdir(ap)
     			dp->d_type = DT_DIR;
     			break;
     		default:
    -			if (fdp->fd_ofiles[fcnt] == NULL) {
    -				FILEDESC_SUNLOCK(fdp);
    -				goto done;
    -			}
    -
    -			bzero((caddr_t) dp, UIO_MX);
    +			if (fdp->fd_ofiles[fcnt] == NULL)
    +				break;
     			dp->d_namlen = sprintf(dp->d_name, "%d", fcnt);
     			dp->d_reclen = UIO_MX;
     			dp->d_type = DT_UNKNOWN;
     			dp->d_fileno = i + FD_DESC;
     			break;
     		}
    -		/*
    -		 * And ship to userland
    -		 */
    -		FILEDESC_SUNLOCK(fdp);
    -		error = uiomove(dp, UIO_MX, uio);
    -		if (error)
    -			goto done;
    -		FILEDESC_SLOCK(fdp);
    +		if (dp->d_namlen != 0) {
    +			/*
    +			 * And ship to userland
    +			 */
    +			FILEDESC_SUNLOCK(fdp);
    +			error = uiomove(dp, UIO_MX, uio);
    +			if (error)
    +				goto done;
    +			FILEDESC_SLOCK(fdp);
    +		}
     		i++;
     		fcnt++;
     	}
    
    From 274885ab2097cb6bdb1b57f825fb1007d3249523 Mon Sep 17 00:00:00 2001
    From: Edwin Groothuis 
    Date: Mon, 22 Mar 2010 21:35:54 +0000
    Subject: [PATCH 1636/2592] MFC of r205475, tzdata2010f:
    
    The Australian Antartic Division:
    - Macquarie Island will stay on UTC+11 for winter and not switch back from DST.
    - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
    - Davis station will revert to its normal time of UTC+7 at 10 March 2010
    - Mawson station stays on UTC+5.
    
    Syria will start DST on Thursday 1 April 2010 at midnight.
    
    Correct Samao DST start date (26 Sep vs 24 Oct)
    ---
     share/zoneinfo/antarctica  | 65 ++++++++++++++++++++++++++++++++++++--
     share/zoneinfo/asia        | 13 ++++++--
     share/zoneinfo/australasia |  4 +--
     share/zoneinfo/zone.tab    |  3 +-
     4 files changed, 77 insertions(+), 8 deletions(-)
    
    diff --git a/share/zoneinfo/antarctica b/share/zoneinfo/antarctica
    index f18ae959e3e..629b2d7b815 100644
    --- a/share/zoneinfo/antarctica
    +++ b/share/zoneinfo/antarctica
    @@ -1,5 +1,5 @@
     # 
    -# @(#)antarctica	8.7
    +# @(#)antarctica	8.8
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -57,6 +57,33 @@ Rule	ChileAQ	1999	only	-	Apr	 4	3:00u	0	-
     Rule	ChileAQ	1999	max	-	Oct	Sun>=9	4:00u	1:00	S
     Rule	ChileAQ	2000	max	-	Mar	Sun>=9	3:00u	0	-
     
    +# These rules are stolen from the `australasia' file.
    +Rule	AusAQ	1917	only	-	Jan	 1	0:01	1:00	-
    +Rule	AusAQ	1917	only	-	Mar	25	2:00	0	-
    +Rule	AusAQ	1942	only	-	Jan	 1	2:00	1:00	-
    +Rule	AusAQ	1942	only	-	Mar	29	2:00	0	-
    +Rule	AusAQ	1942	only	-	Sep	27	2:00	1:00	-
    +Rule	AusAQ	1943	1944	-	Mar	lastSun	2:00	0	-
    +Rule	AusAQ	1943	only	-	Oct	 3	2:00	1:00	-
    +Rule	ATAQ	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
    +Rule	ATAQ	1968	only	-	Mar	lastSun	2:00s	0	-
    +Rule	ATAQ	1968	1985	-	Oct	lastSun	2:00s	1:00	-
    +Rule	ATAQ	1969	1971	-	Mar	Sun>=8	2:00s	0	-
    +Rule	ATAQ	1972	only	-	Feb	lastSun	2:00s	0	-
    +Rule	ATAQ	1973	1981	-	Mar	Sun>=1	2:00s	0	-
    +Rule	ATAQ	1982	1983	-	Mar	lastSun	2:00s	0	-
    +Rule	ATAQ	1984	1986	-	Mar	Sun>=1	2:00s	0	-
    +Rule	ATAQ	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
    +Rule	ATAQ	1987	1990	-	Mar	Sun>=15	2:00s	0	-
    +Rule	ATAQ	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
    +Rule	ATAQ	1988	1990	-	Oct	lastSun	2:00s	1:00	-
    +Rule	ATAQ	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
    +Rule	ATAQ	1991	2005	-	Mar	lastSun	2:00s	0	-
    +Rule	ATAQ	2000	only	-	Aug	lastSun	2:00s	1:00	-
    +Rule	ATAQ	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
    +Rule	ATAQ	2006	only	-	Apr	Sun>=1	2:00s	0	-
    +Rule	ATAQ	2007	only	-	Mar	lastSun	2:00s	0	-
    +Rule	ATAQ	2008	max	-	Apr	Sun>=1	2:00s	0	-
     
     # Argentina - year-round bases
     # Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
    @@ -98,20 +125,52 @@ Rule	ChileAQ	2000	max	-	Mar	Sun>=9	3:00u	0	-
     # http://www.timeanddate.com/news/time/antarctica-new-times.html
     # 
     
    +# From Steffen Thorsen (2010-03-10):
    +# We got these changes from the Australian Antarctic Division:
    +# - Macquarie Island will stay on UTC+11 for winter and therefore not
    +# switch back from daylight savings time when other parts of Australia do
    +# on 4 April.
    +#
    +# - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
    +# The change to UTC+11 is being considered as a regular summer thing but
    +# has not been decided yet.
    +#
    +# - Davis station will revert to its normal time of UTC+7 at 10 March 2010
    +# 20:00 UTC.
    +#
    +# - Mawson station stays on UTC+5.
    +#
    +# In addition to the Rule changes for Casey/Davis, it means that Macquarie
    +# will no longer be like Hobart and will have to have its own Zone created.
    +#
    +# Background:
    +# 
    +# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
    +# 
    +
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
     Zone Antarctica/Casey	0	-	zzz	1969
     			8:00	-	WST	2009 Oct 18 2:00
     						# Western (Aus) Standard Time
    -			11:00	-	CAST	# Casey Time
    +			11:00	-	CAST	2010 Mar 5 2:00
    +						# Casey Time
    +			8:00	-	WST
     Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
     			7:00	-	DAVT	1964 Nov # Davis Time
     			0	-	zzz	1969 Feb
     			7:00	-	DAVT	2009 Oct 18 2:00
    -			5:00	-	DAVT
    +			5:00	-	DAVT	2010 Mar 10 20:00u
    +			7:00	-	DAVT
     Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
     			6:00	-	MAWT	2009 Oct 18 2:00
     						# Mawson Time
     			5:00	-	MAWT
    +Zone Antarctica/Macquarie 0	-	zzz	1911
    +			10:00	-	EST	1916 Oct 1 2:00
    +			10:00	1:00	EST	1917 Feb
    +			10:00	AusAQ	EST	1967
    +			10:00	ATAQ	EST	2010 Apr 4 3:00
    +			11:00	-	MIST	# Macquarie Island Time
     # References:
     # 
     # Casey Weather (1998-02-26)
    diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia
    index 41aeb4bb0ab..859d9c54d43 100644
    --- a/share/zoneinfo/asia
    +++ b/share/zoneinfo/asia
    @@ -1,4 +1,4 @@
    -# @(#)asia	8.55
    +# @(#)asia	8.56
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -2438,9 +2438,18 @@ Rule	Syria	2007	only	-	Nov	 Fri>=1	0:00	0	-
     # 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.
     
    +# From Steffen Thorsen (2010-03-17):
    +# The "Syrian News Station" reported on 2010-03-16 that the Council of
    +# Ministers has decided that Syria will start DST on midnight Thursday
    +# 2010-04-01: (midnight between Thursday and Friday):
    +# 
    +# http://sns.sy/sns/?path=news/read/11421 (Arabic)
    +# 
    +
     Rule	Syria	2008	only	-	Apr	Fri>=1	0:00	1:00	S
     Rule	Syria	2008	only	-	Nov	1	0:00	0	-
    -Rule	Syria	2009	max	-	Mar	lastFri	0:00	1:00	S
    +Rule	Syria	2009	only	-	Mar	lastFri	0:00	1:00	S
    +Rule	Syria	2010	max	-	Apr	Fri>=1	0:00	1:00	S
     Rule	Syria	2009	max	-	Oct	lastFri	0:00	0	-
     
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
    diff --git a/share/zoneinfo/australasia b/share/zoneinfo/australasia
    index 614a446c13a..9884b6750a7 100644
    --- a/share/zoneinfo/australasia
    +++ b/share/zoneinfo/australasia
    @@ -1,5 +1,5 @@
     # 
    -# @(#)australasia	8.16
    +# @(#)australasia	8.17
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -490,7 +490,7 @@ Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
     Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
     			-11:26:56 -	LMT	1911
     			-11:30	-	SAMT	1950		# Samoa Time
    -			-11:00	-	WST	2010 Oct 24
    +			-11:00	-	WST	2010 Sep 26
     			-11:00	1:00	WSDT	2011 Apr 3
     			-11:00	-	WST
     
    diff --git a/share/zoneinfo/zone.tab b/share/zoneinfo/zone.tab
    index c8fb2503db8..59b86007e30 100644
    --- a/share/zoneinfo/zone.tab
    +++ b/share/zoneinfo/zone.tab
    @@ -1,5 +1,5 @@
     # 
    -# @(#)zone.tab	8.33
    +# @(#)zone.tab	8.34
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     #
    @@ -44,6 +44,7 @@ AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
     AQ	-7824+10654	Antarctica/Vostok	Vostok Station, S Magnetic Pole
     AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
     AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
    +AQ	-5430+15857	Antarctica/Macquarie	Macquarie Island Station, Macquarie Island
     AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
     AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, MN, SE, SF)
     AR	-2447-06525	America/Argentina/Salta	(SA, LP, NQ, RN)
    
    From 7fe6975097dbb701cacda774268e5b690f6d1666 Mon Sep 17 00:00:00 2001
    From: Hiroki Sato 
    Date: Mon, 22 Mar 2010 22:07:19 +0000
    Subject: [PATCH 1637/2592] MFC r203272:
    
    - Fix a bug when adding an interface with an invalid MTU sets the
      bridge's MTU if it is the firstly-added one while the addition
      itself fails.
    
    - Allow SIOCSIFMTU only when all members have the same MTU.
    
    - Remove IFT_GIF check when defining the brige MTU by the
      firstly-added interface's one.  The MTU of the gif interface
      has to be the same as the bridge's one.
    ---
     sys/net/if_bridge.c | 48 ++++++++++++++++++++++++++++++++-------------
     1 file changed, 34 insertions(+), 14 deletions(-)
    
    diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
    index 8e0e6e1e6a5..18730955864 100644
    --- a/sys/net/if_bridge.c
    +++ b/sys/net/if_bridge.c
    @@ -682,6 +682,8 @@ static int
     bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     {
     	struct bridge_softc *sc = ifp->if_softc;
    +	struct ifreq *ifr = (struct ifreq *)data;
    +	struct bridge_iflist *bif;
     	struct thread *td = curthread;
     	union {
     		struct ifbreq ifbreq;
    @@ -771,10 +773,29 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     		break;
     
     	case SIOCSIFMTU:
    -		/* Do not allow the MTU to be changed on the bridge */
    -		error = EINVAL;
    +		if (ifr->ifr_mtu < 576) {
    +			error = EINVAL;
    +			break;
    +		}
    +		if (LIST_EMPTY(&sc->sc_iflist)) {
    +			sc->sc_ifp->if_mtu = ifr->ifr_mtu;
    +			break;
    +		}
    +		BRIDGE_LOCK(sc);
    +		LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
    +			if (bif->bif_ifp->if_mtu != ifr->ifr_mtu) {
    +				log(LOG_NOTICE, "%s: invalid MTU: %lu(%s)"
    +				    " != %d\n", sc->sc_ifp->if_xname,
    +				    bif->bif_ifp->if_mtu,
    +				    bif->bif_ifp->if_xname, ifr->ifr_mtu);
    +				error = EINVAL;
    +				break;
    +			}
    +		}
    +		if (!error)
    +			sc->sc_ifp->if_mtu = ifr->ifr_mtu;
    +		BRIDGE_UNLOCK(sc);
     		break;
    -
     	default:
     		/*
     		 * drop the lock as ether_ioctl() will call bridge_start() and
    @@ -987,17 +1008,6 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
     		if (ifs == bif->bif_ifp)
     			return (EBUSY);
     
    -	/* Allow the first Ethernet member to define the MTU */
    -	if (ifs->if_type != IFT_GIF) {
    -		if (LIST_EMPTY(&sc->sc_iflist))
    -			sc->sc_ifp->if_mtu = ifs->if_mtu;
    -		else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
    -			if_printf(sc->sc_ifp, "invalid MTU for %s\n",
    -			    ifs->if_xname);
    -			return (EINVAL);
    -		}
    -	}
    -
     	if (ifs->if_bridge == sc)
     		return (EEXIST);
     
    @@ -1023,6 +1033,16 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
     		goto out;
     	}
     
    +	/* Allow the first Ethernet member to define the MTU */
    +	if (LIST_EMPTY(&sc->sc_iflist))
    +		sc->sc_ifp->if_mtu = ifs->if_mtu;
    +	else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
    +		if_printf(sc->sc_ifp, "invalid MTU: %lu(%s) != %lu\n",
    +		    ifs->if_mtu, ifs->if_xname, sc->sc_ifp->if_mtu);
    +		error = EINVAL;
    +		goto out;
    +	}
    +
     	/*
     	 * Assign the interface's MAC address to the bridge if it's the first
     	 * member and the MAC address of the bridge has not been changed from
    
    From 98323201291107c9c99382ac4d36fa59e4e52750 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Mon, 22 Mar 2010 23:23:47 +0000
    Subject: [PATCH 1638/2592] MFC r204156:   Add __FBSDID.
    
    ---
     sys/net/if_vlan.c | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
    index 9dcbedd346e..47bdc07f1c9 100644
    --- a/sys/net/if_vlan.c
    +++ b/sys/net/if_vlan.c
    @@ -25,8 +25,6 @@
      * 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$
      */
     
     /*
    @@ -41,6 +39,9 @@
      * and ask it to send them.
      */
     
    +#include 
    +__FBSDID("$FreeBSD$");
    +
     #include "opt_vlan.h"
     
     #include 
    
    From 521dd44db5984f54a173250e431554f9674d5911 Mon Sep 17 00:00:00 2001
    From: Qing Li 
    Date: Mon, 22 Mar 2010 23:33:40 +0000
    Subject: [PATCH 1639/2592] MFC	r205272
    
    Need to set the proper flag bit when inserting ARP
    entries into the kernel.
    ---
     usr.sbin/ppp/arp.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/usr.sbin/ppp/arp.c b/usr.sbin/ppp/arp.c
    index 02dce51ab50..e67f89bea8a 100644
    --- a/usr.sbin/ppp/arp.c
    +++ b/usr.sbin/ppp/arp.c
    @@ -119,7 +119,7 @@ arp_ProxySub(struct bundle *bundle, struct in_addr addr, int add)
         return 0;
       }
       arpmsg.hdr.rtm_type = add ? RTM_ADD : RTM_DELETE;
    -  arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC;
    +  arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC | RTF_LLDATA;
       arpmsg.hdr.rtm_version = RTM_VERSION;
       arpmsg.hdr.rtm_seq = ++bundle->routing_seq;
       arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
    
    From 8018e843a306400d5d6ad3d57f9bcf932d5df52b Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Tue, 23 Mar 2010 09:58:59 +0000
    Subject: [PATCH 1640/2592] MFC of a large number of ipfw and dummynet fixes
     and enhancements done in CURRENT over the last 4 months. HEAD and RELENG_8
     are almost in sync now for ipfw, dummynet the pfil hooks and related
     components.
    
    Among the most noticeable changes:
    - r200855 more efficient lookup of skipto rules, and remove O(N)
      blocks from critical sections in the kernel;
    - r204591 large restructuring of the dummynet module, with support
      for multiple scheduling algorithms (4 available so far)
    See the original commit logs for details.
    
    Changes in the kernel/userland ABI should be harmless because the
    kernel is able to understand previous requests from RELENG_8 and
    RELENG_7. For this reason, this changeset would be applicable
    to RELENG_7 as well, but i am not sure if it is worthwhile.
    ---
     sbin/ipfw/Makefile                    |    1 +
     sbin/ipfw/altq.c                      |    1 +
     sbin/ipfw/dummynet.c                  |  971 ++++--
     sbin/ipfw/ipfw.8                      |  264 +-
     sbin/ipfw/ipfw2.c                     |  363 ++-
     sbin/ipfw/ipfw2.h                     |   31 +-
     sbin/ipfw/main.c                      |  158 +-
     sys/conf/files                        |   11 +
     sys/net/if_bridge.c                   |   34 +-
     sys/net/if_ethersubr.c                |   32 +-
     sys/net/radix.c                       |   58 +-
     sys/net/radix.h                       |    3 +-
     sys/net/route.c                       |    9 +-
     sys/netgraph/ng_ipfw.c                |   53 +-
     sys/netgraph/ng_ipfw.h                |   24 +-
     sys/netinet/in.h                      |   26 +
     sys/netinet/ip_divert.c               |   90 +-
     sys/netinet/ip_divert.h               |   63 +-
     sys/netinet/ip_dummynet.h             |  491 ++-
     sys/netinet/ip_fw.h                   |  158 +-
     sys/netinet/ip_var.h                  |   47 +-
     sys/netinet/ipfw/dn_heap.c            |  550 ++++
     sys/netinet/ipfw/dn_heap.h            |  191 ++
     sys/netinet/ipfw/dn_sched.h           |  189 ++
     sys/netinet/ipfw/dn_sched_fifo.c      |  120 +
     sys/netinet/ipfw/dn_sched_qfq.c       |  864 ++++++
     sys/netinet/ipfw/dn_sched_rr.c        |  307 ++
     sys/netinet/ipfw/dn_sched_wf2q.c      |  373 +++
     sys/netinet/ipfw/dummynet.txt         |  860 ++++++
     sys/netinet/ipfw/ip_dn_glue.c         |  845 +++++
     sys/netinet/ipfw/ip_dn_io.c           |  788 +++++
     sys/netinet/ipfw/ip_dn_private.h      |  402 +++
     sys/netinet/ipfw/ip_dummynet.c        | 4090 ++++++++++++-------------
     sys/netinet/ipfw/ip_fw2.c             | 3608 ++++------------------
     sys/netinet/ipfw/ip_fw_dynamic.c      | 1244 ++++++++
     sys/netinet/ipfw/ip_fw_log.c          |  435 +++
     sys/netinet/ipfw/ip_fw_nat.c          |  491 ++-
     sys/netinet/ipfw/ip_fw_pfil.c         |  572 ++--
     sys/netinet/ipfw/ip_fw_private.h      |  301 ++
     sys/netinet/ipfw/ip_fw_sockopt.c      | 1287 ++++++++
     sys/netinet/ipfw/ip_fw_table.c        |  286 ++
     sys/netinet/ipfw/test/Makefile        |   50 +
     sys/netinet/ipfw/test/dn_test.h       |  175 ++
     sys/netinet/ipfw/test/main.c          |  636 ++++
     sys/netinet/ipfw/test/mylist.h        |   49 +
     sys/netinet/ipfw/test/test_dn_heap.c  |  162 +
     sys/netinet/ipfw/test/test_dn_sched.c |   89 +
     sys/netinet/raw_ip.c                  |   10 +-
     48 files changed, 14837 insertions(+), 7025 deletions(-)
     create mode 100644 sys/netinet/ipfw/dn_heap.c
     create mode 100644 sys/netinet/ipfw/dn_heap.h
     create mode 100644 sys/netinet/ipfw/dn_sched.h
     create mode 100644 sys/netinet/ipfw/dn_sched_fifo.c
     create mode 100644 sys/netinet/ipfw/dn_sched_qfq.c
     create mode 100644 sys/netinet/ipfw/dn_sched_rr.c
     create mode 100644 sys/netinet/ipfw/dn_sched_wf2q.c
     create mode 100644 sys/netinet/ipfw/dummynet.txt
     create mode 100644 sys/netinet/ipfw/ip_dn_glue.c
     create mode 100644 sys/netinet/ipfw/ip_dn_io.c
     create mode 100644 sys/netinet/ipfw/ip_dn_private.h
     create mode 100644 sys/netinet/ipfw/ip_fw_dynamic.c
     create mode 100644 sys/netinet/ipfw/ip_fw_log.c
     create mode 100644 sys/netinet/ipfw/ip_fw_private.h
     create mode 100644 sys/netinet/ipfw/ip_fw_sockopt.c
     create mode 100644 sys/netinet/ipfw/ip_fw_table.c
     create mode 100644 sys/netinet/ipfw/test/Makefile
     create mode 100644 sys/netinet/ipfw/test/dn_test.h
     create mode 100644 sys/netinet/ipfw/test/main.c
     create mode 100644 sys/netinet/ipfw/test/mylist.h
     create mode 100644 sys/netinet/ipfw/test/test_dn_heap.c
     create mode 100644 sys/netinet/ipfw/test/test_dn_sched.c
    
    diff --git a/sbin/ipfw/Makefile b/sbin/ipfw/Makefile
    index c09ebca32e8..b25f38ca2e8 100644
    --- a/sbin/ipfw/Makefile
    +++ b/sbin/ipfw/Makefile
    @@ -3,6 +3,7 @@
     PROG=	ipfw
     SRCS=	ipfw2.c dummynet.c ipv6.c main.c nat.c altq.c
     WARNS?=	2
    +DPADD=	${LIBUTIL}
     LDADD=	-lutil
     MAN=	ipfw.8
     
    diff --git a/sbin/ipfw/altq.c b/sbin/ipfw/altq.c
    index b00a1e07041..8cf19e54a4e 100644
    --- a/sbin/ipfw/altq.c
    +++ b/sbin/ipfw/altq.c
    @@ -39,6 +39,7 @@
     
     #include 		/* IFNAMSIZ */
     #include 
    +#include 	/* in_addr */
     #include 
     
     /*
    diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c
    index 9e68e659dd4..eb6547a046c 100644
    --- a/sbin/ipfw/dummynet.c
    +++ b/sbin/ipfw/dummynet.c
    @@ -1,10 +1,5 @@
     /*
    - * Copyright (c) 2002-2003 Luigi Rizzo
    - * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
    - * Copyright (c) 1994 Ugen J.S.Antsilevich
    - *
    - * Idea and grammar partially left from:
    - * Copyright (c) 1993 Daniel Boulet
    + * Copyright (c) 2002-2003,2010 Luigi Rizzo
      *
      * Redistribution and use in source forms, with and without modification,
      * are permitted provided that this entire comment appears intact.
    @@ -15,8 +10,6 @@
      *
      * This software is provided ``AS IS'' without any warranties of any kind.
      *
    - * NEW command line interface for IP firewall facility
    - *
      * $FreeBSD$
      *
      * dummynet support
    @@ -24,7 +17,6 @@
     
     #include 
     #include 
    -#include 
     /* XXX there are several sysctl leftover here */
     #include 
     
    @@ -46,6 +38,7 @@
     #include 
     #include 	/* inet_ntoa */
     
    +
     static struct _s_x dummynet_params[] = {
     	{ "plr",		TOK_PLR },
     	{ "noerror",		TOK_NOERROR },
    @@ -56,27 +49,59 @@ static struct _s_x dummynet_params[] = {
     	{ "src-port",		TOK_SRCPORT },
     	{ "proto",		TOK_PROTO },
     	{ "weight",		TOK_WEIGHT },
    +	{ "lmax",		TOK_LMAX },
    +	{ "maxlen",		TOK_LMAX },
     	{ "all",		TOK_ALL },
    -	{ "mask",		TOK_MASK },
    +	{ "mask",		TOK_MASK }, /* alias for both */
    +	{ "sched_mask",		TOK_SCHED_MASK },
    +	{ "flow_mask",		TOK_FLOW_MASK },
     	{ "droptail",		TOK_DROPTAIL },
     	{ "red",		TOK_RED },
     	{ "gred",		TOK_GRED },
     	{ "bw",			TOK_BW },
     	{ "bandwidth",		TOK_BW },
     	{ "delay",		TOK_DELAY },
    +	{ "link",		TOK_LINK },
     	{ "pipe",		TOK_PIPE },
     	{ "queue",		TOK_QUEUE },
    +	{ "flowset",		TOK_FLOWSET },
    +	{ "sched",		TOK_SCHED },
    +	{ "pri",		TOK_PRI },
    +	{ "priority",		TOK_PRI },
    +	{ "type",		TOK_TYPE },
     	{ "flow-id",		TOK_FLOWID},
     	{ "dst-ipv6",		TOK_DSTIP6},
     	{ "dst-ip6",		TOK_DSTIP6},
     	{ "src-ipv6",		TOK_SRCIP6},
     	{ "src-ip6",		TOK_SRCIP6},
    -	{ "profile",		TOK_PIPE_PROFILE},
    +	{ "profile",		TOK_PROFILE},
     	{ "burst",		TOK_BURST},
     	{ "dummynet-params",	TOK_NULL },
     	{ NULL, 0 }	/* terminator */
     };
     
    +#define O_NEXT(p, len) ((void *)((char *)p + len))
    +
    +static void
    +oid_fill(struct dn_id *oid, int len, int type, uintptr_t id)
    +{
    +	oid->len = len;
    +	oid->type = type;
    +	oid->subtype = 0;
    +	oid->id = id;
    +}
    +
    +/* make room in the buffer and move the pointer forward */
    +static void *
    +o_next(struct dn_id **o, int len, int type)
    +{
    +	struct dn_id *ret = *o;
    +	oid_fill(ret, len, type, 0);
    +	*o = O_NEXT(*o, len);
    +	return ret;
    +}
    +
    +#if 0
     static int
     sort_q(void *arg, const void *pa, const void *pb)
     {
    @@ -108,117 +133,84 @@ sort_q(void *arg, const void *pa, const void *pb)
     		res = 1;
     	return (int)(rev ? res : -res);
     }
    +#endif
     
    +/* print a mask and header for the subsequent list of flows */
     static void
    -list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q)
    +print_mask(struct ipfw_flow_id *id)
     {
    -	int l;
    -	int index_printed, indexes = 0;
    -	char buff[255];
    -	struct protoent *pe;
    +	if (!IS_IP6_FLOW_ID(id)) {
    +		printf("    "
    +		    "mask: %s 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
    +		    id->extra ? "queue," : "",
    +		    id->proto,
    +		    id->src_ip, id->src_port,
    +		    id->dst_ip, id->dst_port);
     
    -	if (fs->rq_elements == 0)
    -		return;
    +		printf("BKT Prot ___Source IP/port____ "
    +		    "____Dest. IP/port____ "
    +		    "Tot_pkt/bytes Pkt/Byte Drp\n");
    +	} else {
    +		char buf[255];
    +		printf("\n        mask: %sproto: 0x%02x, flow_id: 0x%08x,  ",
    +		    id->extra ? "queue," : "",
    +		    id->proto, id->flow_id6);
    +		inet_ntop(AF_INET6, &(id->src_ip6), buf, sizeof(buf));
    +		printf("%s/0x%04x -> ", buf, id->src_port);
    +		inet_ntop(AF_INET6, &(id->dst_ip6), buf, sizeof(buf));
    +		printf("%s/0x%04x\n", buf, id->dst_port);
     
    -	if (co.do_sort != 0)
    -		qsort_r(q, fs->rq_elements, sizeof *q, NULL, sort_q);
    -
    -	/* Print IPv4 flows */
    -	index_printed = 0;
    -	for (l = 0; l < fs->rq_elements; l++) {
    -		struct in_addr ina;
    -
    -		/* XXX: Should check for IPv4 flows */
    -		if (IS_IP6_FLOW_ID(&(q[l].id)))
    -			continue;
    -
    -		if (!index_printed) {
    -			index_printed = 1;
    -			if (indexes > 0)	/* currently a no-op */
    -				printf("\n");
    -			indexes++;
    -			printf("    "
    -			    "mask: 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
    -			    fs->flow_mask.proto,
    -			    fs->flow_mask.src_ip, fs->flow_mask.src_port,
    -			    fs->flow_mask.dst_ip, fs->flow_mask.dst_port);
    -
    -			printf("BKT Prot ___Source IP/port____ "
    -			    "____Dest. IP/port____ "
    -			    "Tot_pkt/bytes Pkt/Byte Drp\n");
    -		}
    -
    -		printf("%3d ", q[l].hash_slot);
    -		pe = getprotobynumber(q[l].id.proto);
    -		if (pe)
    -			printf("%-4s ", pe->p_name);
    -		else
    -			printf("%4u ", q[l].id.proto);
    -		ina.s_addr = htonl(q[l].id.src_ip);
    -		printf("%15s/%-5d ",
    -		    inet_ntoa(ina), q[l].id.src_port);
    -		ina.s_addr = htonl(q[l].id.dst_ip);
    -		printf("%15s/%-5d ",
    -		    inet_ntoa(ina), q[l].id.dst_port);
    -		printf("%4llu %8llu %2u %4u %3u\n",
    -		    align_uint64(&q[l].tot_pkts),
    -		    align_uint64(&q[l].tot_bytes),
    -		    q[l].len, q[l].len_bytes, q[l].drops);
    -		if (co.verbose)
    -			printf("   S %20llu  F %20llu\n",
    -			    align_uint64(&q[l].S), align_uint64(&q[l].F));
    -	}
    -
    -	/* Print IPv6 flows */
    -	index_printed = 0;
    -	for (l = 0; l < fs->rq_elements; l++) {
    -		if (!IS_IP6_FLOW_ID(&(q[l].id)))
    -			continue;
    -
    -		if (!index_printed) {
    -			index_printed = 1;
    -			if (indexes > 0)
    -				printf("\n");
    -			indexes++;
    -			printf("\n        mask: proto: 0x%02x, flow_id: 0x%08x,  ",
    -			    fs->flow_mask.proto, fs->flow_mask.flow_id6);
    -			inet_ntop(AF_INET6, &(fs->flow_mask.src_ip6),
    -			    buff, sizeof(buff));
    -			printf("%s/0x%04x -> ", buff, fs->flow_mask.src_port);
    -			inet_ntop( AF_INET6, &(fs->flow_mask.dst_ip6),
    -			    buff, sizeof(buff) );
    -			printf("%s/0x%04x\n", buff, fs->flow_mask.dst_port);
    -
    -			printf("BKT ___Prot___ _flow-id_ "
    -			    "______________Source IPv6/port_______________ "
    -			    "_______________Dest. IPv6/port_______________ "
    -			    "Tot_pkt/bytes Pkt/Byte Drp\n");
    -		}
    -		printf("%3d ", q[l].hash_slot);
    -		pe = getprotobynumber(q[l].id.proto);
    -		if (pe != NULL)
    -			printf("%9s ", pe->p_name);
    -		else
    -			printf("%9u ", q[l].id.proto);
    -		printf("%7d  %39s/%-5d ", q[l].id.flow_id6,
    -		    inet_ntop(AF_INET6, &(q[l].id.src_ip6), buff, sizeof(buff)),
    -		    q[l].id.src_port);
    -		printf(" %39s/%-5d ",
    -		    inet_ntop(AF_INET6, &(q[l].id.dst_ip6), buff, sizeof(buff)),
    -		    q[l].id.dst_port);
    -		printf(" %4llu %8llu %2u %4u %3u\n",
    -		    align_uint64(&q[l].tot_pkts),
    -		    align_uint64(&q[l].tot_bytes),
    -		    q[l].len, q[l].len_bytes, q[l].drops);
    -		if (co.verbose)
    -			printf("   S %20llu  F %20llu\n",
    -			    align_uint64(&q[l].S),
    -			    align_uint64(&q[l].F));
    +		printf("BKT ___Prot___ _flow-id_ "
    +		    "______________Source IPv6/port_______________ "
    +		    "_______________Dest. IPv6/port_______________ "
    +		    "Tot_pkt/bytes Pkt/Byte Drp\n");
     	}
     }
     
     static void
    -print_flowset_parms(struct dn_flow_set *fs, char *prefix)
    +list_flow(struct dn_flow *ni)
    +{
    +	char buff[255];
    +	struct protoent *pe;
    +	struct in_addr ina;
    +	struct ipfw_flow_id *id = &ni->fid;
    +
    +	pe = getprotobynumber(id->proto);
    +		/* XXX: Should check for IPv4 flows */
    +	printf("%3u%c", (ni->oid.id) & 0xff,
    +		id->extra ? '*' : ' ');
    +	if (!IS_IP6_FLOW_ID(id)) {
    +		if (pe)
    +			printf("%-4s ", pe->p_name);
    +		else
    +			printf("%4u ", id->proto);
    +		ina.s_addr = htonl(id->src_ip);
    +		printf("%15s/%-5d ",
    +		    inet_ntoa(ina), id->src_port);
    +		ina.s_addr = htonl(id->dst_ip);
    +		printf("%15s/%-5d ",
    +		    inet_ntoa(ina), id->dst_port);
    +	} else {
    +		/* Print IPv6 flows */
    +		if (pe != NULL)
    +			printf("%9s ", pe->p_name);
    +		else
    +			printf("%9u ", id->proto);
    +		printf("%7d  %39s/%-5d ", id->flow_id6,
    +		    inet_ntop(AF_INET6, &(id->src_ip6), buff, sizeof(buff)),
    +		    id->src_port);
    +		printf(" %39s/%-5d ",
    +		    inet_ntop(AF_INET6, &(id->dst_ip6), buff, sizeof(buff)),
    +		    id->dst_port);
    +	}
    +	printf("%4llu %8llu %2u %4u %3u\n",
    +	    align_uint64(&ni->tot_pkts),
    +	    align_uint64(&ni->tot_bytes),
    +	    ni->length, ni->len_bytes, ni->drops);
    +}
    +
    +static void
    +print_flowset_parms(struct dn_fs *fs, char *prefix)
     {
     	int l;
     	char qs[30];
    @@ -226,7 +218,7 @@ print_flowset_parms(struct dn_flow_set *fs, char *prefix)
     	char red[90];	/* Display RED parameters */
     
     	l = fs->qsize;
    -	if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
    +	if (fs->flags & DN_QSIZE_BYTES) {
     		if (l >= 8192)
     			sprintf(qs, "%d KB", l / 1024);
     		else
    @@ -237,23 +229,34 @@ print_flowset_parms(struct dn_flow_set *fs, char *prefix)
     		sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
     	else
     		plr[0] = '\0';
    -	if (fs->flags_fs & DN_IS_RED)	/* RED parameters */
    +
    +	if (fs->flags & DN_IS_RED)	/* RED parameters */
     		sprintf(red,
     		    "\n\t %cRED w_q %f min_th %d max_th %d max_p %f",
    -		    (fs->flags_fs & DN_IS_GENTLE_RED) ? 'G' : ' ',
    +		    (fs->flags & DN_IS_GENTLE_RED) ? 'G' : ' ',
     		    1.0 * fs->w_q / (double)(1 << SCALE_RED),
    -		    SCALE_VAL(fs->min_th),
    -		    SCALE_VAL(fs->max_th),
    +		    fs->min_th,
    +		    fs->max_th,
     		    1.0 * fs->max_p / (double)(1 << SCALE_RED));
     	else
     		sprintf(red, "droptail");
     
    -	printf("%s %s%s %d queues (%d buckets) %s\n",
    -	    prefix, qs, plr, fs->rq_elements, fs->rq_size, red);
    +	if (prefix[0]) {
    +	    printf("%s %s%s %d queues (%d buckets) %s\n",
    +		prefix, qs, plr, fs->oid.id, fs->buckets, red);
    +	    prefix[0] = '\0';
    +	} else {
    +	    printf("q%05d %s%s %d flows (%d buckets) sched %d "
    +			"weight %d lmax %d pri %d %s\n",
    +		fs->fs_nr, qs, plr, fs->oid.id, fs->buckets,
    +		fs->sched_nr, fs->par[0], fs->par[1], fs->par[2], red);
    +	    if (fs->flags & DN_HAVE_MASK)
    +		print_mask(&fs->flow_mask);
    +	}
     }
     
     static void
    -print_extra_delay_parms(struct dn_pipe *p)
    +print_extra_delay_parms(struct dn_profile *p)
     {
     	double loss;
     	if (p->samples_no <= 0)
    @@ -265,105 +268,126 @@ print_extra_delay_parms(struct dn_pipe *p)
     		p->name, loss, p->samples_no);
     }
     
    -void
    -ipfw_list_pipes(void *data, uint nbytes, int ac, char *av[])
    +static void
    +flush_buf(char *buf)
     {
    -	int rulenum;
    -	void *next = data;
    -	struct dn_pipe *p = (struct dn_pipe *) data;
    -	struct dn_flow_set *fs;
    -	struct dn_flow_queue *q;
    -	int l;
    +	if (buf[0])
    +		printf("%s\n", buf);
    +	buf[0] = '\0';
    +}
    +	
    +/*
    + * generic list routine. We expect objects in a specific order, i.e.
    + * PIPES AND SCHEDULERS:
    + *	link; scheduler; internal flowset if any; instances
    + * we can tell a pipe from the number.
    + *
    + * FLOWSETS:
    + *	flowset; queues;
    + * link i (int queue); scheduler i; si(i) { flowsets() : queues }
    + */
    +static void
    +list_pipes(struct dn_id *oid, struct dn_id *end)
    +{
    +    char buf[160];	/* pending buffer */
    +    buf[0] = '\0';
     
    -	if (ac > 0)
    -		rulenum = strtoul(*av++, NULL, 10);
    -	else
    -		rulenum = 0;
    -	for (; nbytes >= sizeof *p; p = (struct dn_pipe *)next) {
    -		double b = p->bandwidth;
    -		char buf[30];
    -		char prefix[80];
    -		char burst[5 + 7];
    +    for (; oid != end; oid = O_NEXT(oid, oid->len)) {
    +	if (oid->len < sizeof(*oid))
    +		errx(1, "invalid oid len %d\n", oid->len);
     
    -		if (SLIST_NEXT(p, next) != (struct dn_pipe *)DN_IS_PIPE)
    -			break;	/* done with pipes, now queues */
    +	switch (oid->type) {
    +	default:
    +	    flush_buf(buf);
    +	    printf("unrecognized object %d size %d\n", oid->type, oid->len);
    +	    break;
    +	case DN_TEXT: /* list of attached flowsets */
    +	    {
    +		int i, l;
    +		struct {
    +			struct dn_id id;
    +			uint32_t p[0];
    +		} *d = (void *)oid;
    +		l = (oid->len - sizeof(*oid))/sizeof(d->p[0]);
    +		if (l == 0)
    +		    break;
    +		printf("   Children flowsets: ");
    +		for (i = 0; i < l; i++)
    +			printf("%u ", d->p[i]);
    +		printf("\n");
    +		break;
    +	    }
    +	case DN_CMD_GET:
    +	    if (co.verbose)
    +		printf("answer for cmd %d, len %d\n", oid->type, oid->id);
    +	    break;
    +	case DN_SCH: {
    +	    struct dn_sch *s = (struct dn_sch *)oid;
    +	    flush_buf(buf);
    +	    printf(" sched %d type %s flags 0x%x %d buckets %d active\n",
    +			s->sched_nr,
    +			s->name, s->flags, s->buckets, s->oid.id);
    +	    if (s->flags & DN_HAVE_MASK)
    +		print_mask(&s->sched_mask);
    +	    }
    +	    break;
     
    -		/*
    -		 * compute length, as pipe have variable size
    -		 */
    -		l = sizeof(*p) + p->fs.rq_elements * sizeof(*q);
    -		next = (char *)p + l;
    -		nbytes -= l;
    +	case DN_FLOW:
    +	    list_flow((struct dn_flow *)oid);
    +	    break;
     
    -		if ((rulenum != 0 && rulenum != p->pipe_nr) || co.do_pipe == 2)
    -			continue;
    +	case DN_LINK: {
    +	    struct dn_link *p = (struct dn_link *)oid;
    +	    double b = p->bandwidth;
    +	    char bwbuf[30];
    +	    char burst[5 + 7];
     
    -		/*
    -		 * Print rate (or clocking interface)
    -		 */
    -		if (p->if_name[0] != '\0')
    -			sprintf(buf, "%s", p->if_name);
    -		else if (b == 0)
    -			sprintf(buf, "unlimited");
    -		else if (b >= 1000000)
    -			sprintf(buf, "%7.3f Mbit/s", b/1000000);
    -		else if (b >= 1000)
    -			sprintf(buf, "%7.3f Kbit/s", b/1000);
    -		else
    -			sprintf(buf, "%7.3f bit/s ", b);
    +	    /* This starts a new object so flush buffer */
    +	    flush_buf(buf);
    +	    /* data rate */
    +	    if (b == 0)
    +		sprintf(bwbuf, "unlimited     ");
    +	    else if (b >= 1000000)
    +		sprintf(bwbuf, "%7.3f Mbit/s", b/1000000);
    +	    else if (b >= 1000)
    +		sprintf(bwbuf, "%7.3f Kbit/s", b/1000);
    +	    else
    +		sprintf(bwbuf, "%7.3f bit/s ", b);
     
    -		sprintf(prefix, "%05d: %s %4d ms ",
    -		    p->pipe_nr, buf, p->delay);
    +	    if (humanize_number(burst, sizeof(burst), p->burst,
    +		    "", HN_AUTOSCALE, 0) < 0 || co.verbose)
    +		sprintf(burst, "%d", (int)p->burst);
    +	    sprintf(buf, "%05d: %s %4d ms burst %s",
    +		p->link_nr % DN_MAX_ID, bwbuf, p->delay, burst);
    +	    }
    +	    break;
     
    -		print_flowset_parms(&(p->fs), prefix);
    -
    -		if (humanize_number(burst, sizeof(burst), p->burst,
    -		    "Byte", HN_AUTOSCALE, 0) < 0 || co.verbose)
    -			printf("\t burst: %ju Byte\n", p->burst);
    -		else
    -			printf("\t burst: %s\n", burst);
    -
    -		print_extra_delay_parms(p);
    -
    -		q = (struct dn_flow_queue *)(p+1);
    -		list_queues(&(p->fs), q);
    -	}
    -	for (fs = next; nbytes >= sizeof *fs; fs = next) {
    -		char prefix[80];
    -
    -		if (SLIST_NEXT(fs, next) != (struct dn_flow_set *)DN_IS_QUEUE)
    -			break;
    -		l = sizeof(*fs) + fs->rq_elements * sizeof(*q);
    -		next = (char *)fs + l;
    -		nbytes -= l;
    -
    -		if (rulenum != 0 && ((rulenum != fs->fs_nr && co.do_pipe == 2) ||
    -		    (rulenum != fs->parent_nr && co.do_pipe == 1))) {
    -			continue;
    -		}
    -
    -		q = (struct dn_flow_queue *)(fs+1);
    -		sprintf(prefix, "q%05d: weight %d pipe %d ",
    -		    fs->fs_nr, fs->weight, fs->parent_nr);
    -		print_flowset_parms(fs, prefix);
    -		list_queues(fs, q);
    +	case DN_FS:
    +	    print_flowset_parms((struct dn_fs *)oid, buf);
    +	    break;
    +	case DN_PROFILE:
    +	    flush_buf(buf);
    +	    print_extra_delay_parms((struct dn_profile *)oid);
     	}
    +	flush_buf(buf); // XXX does it really go here ?
    +    }
     }
     
     /*
    - * Delete pipe or queue i
    + * Delete pipe, queue or scheduler i
      */
     int
    -ipfw_delete_pipe(int pipe_or_queue, int i)
    +ipfw_delete_pipe(int do_pipe, int i)
     {
    -	struct dn_pipe p;
    -
    -	memset(&p, 0, sizeof p);
    -	if (pipe_or_queue == 1)
    -		p.pipe_nr = i;		/* pipe */
    -	else
    -		p.fs.fs_nr = i;		/* queue */
    -	i = do_cmd(IP_DUMMYNET_DEL, &p, sizeof p);
    +	struct {
    +		struct dn_id oid;
    +		uintptr_t a[1];	/* add more if we want a list */
    +	} cmd;
    +	oid_fill((void *)&cmd, sizeof(cmd), DN_CMD_DELETE, DN_API_VERSION);
    +	cmd.oid.subtype = (do_pipe == 1) ? DN_LINK :
    +		( (do_pipe == 2) ? DN_FS : DN_SCH);
    +	cmd.a[0] = i;
    +	i = do_cmd(IP_DUMMYNET3, &cmd, cmd.oid.len);
     	if (i) {
     		i = 1;
     		warn("rule %u: setsockopt(IP_DUMMYNET_DEL)", i);
    @@ -400,7 +424,7 @@ ipfw_delete_pipe(int pipe_or_queue, int i)
      * The empirical curve may have both vertical and horizontal lines.
      * Vertical lines represent constant delay for a range of
      * probabilities; horizontal lines correspond to a discontinuty
    - * in the delay distribution: the pipe will use the largest delay
    + * in the delay distribution: the link will use the largest delay
      * for a given probability.
      * 
      * To pass the curve to dummynet, we must store the parameters
    @@ -490,9 +514,12 @@ static void
     read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen)
     {
     	if (*bandwidth != -1)
    -		warn("duplicate token, override bandwidth value!");
    +		warnx("duplicate token, override bandwidth value!");
     
     	if (arg[0] >= 'a' && arg[0] <= 'z') {
    +		if (!if_name) {
    +			errx(1, "no if support");
    +		}
     		if (namelen >= IFNAMSIZ)
     			warn("interface name truncated");
     		namelen--;
    @@ -508,7 +535,7 @@ read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen)
     		if (*end == 'K' || *end == 'k') {
     			end++;
     			bw *= 1000;
    -		} else if (*end == 'M') {
    +		} else if (*end == 'M' || *end == 'm') {
     			end++;
     			bw *= 1000000;
     		}
    @@ -521,7 +548,8 @@ read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen)
     			errx(EX_DATAERR, "bandwidth too large");
     
     		*bandwidth = bw;
    -		if_name[0] = '\0';
    +		if (if_name)
    +			if_name[0] = '\0';
     	}
     }
     
    @@ -551,7 +579,8 @@ compare_points(const void *vp1, const void *vp2)
     #define ED_EFMT(s) EX_DATAERR,"error in %s at line %d: "#s,filename,lineno
     
     static void
    -load_extra_delays(const char *filename, struct dn_pipe *p)
    +load_extra_delays(const char *filename, struct dn_profile *p,
    +	struct dn_link *link)
     {
     	char    line[ED_MAX_LINE_LEN];
     	FILE    *f;
    @@ -566,6 +595,9 @@ load_extra_delays(const char *filename, struct dn_pipe *p)
     	struct point    points[ED_MAX_SAMPLES_NO];
     	int     points_no = 0;
     
    +	/* XXX link never NULL? */
    +	p->link_nr = link->link_nr;
    +
     	profile_name[0] = '\0';
     	f = fopen(filename, "r");
     	if (f == NULL)
    @@ -606,7 +638,8 @@ load_extra_delays(const char *filename, struct dn_pipe *p)
     				ED_MAX_SAMPLES_NO);
     		    do_points = 0;
     		} else if (!strcasecmp(name, ED_TOK_BW)) {
    -		    read_bandwidth(arg, &p->bandwidth, p->if_name, sizeof(p->if_name));
    +		    char buf[IFNAMSIZ];
    +		    read_bandwidth(arg, &link->bandwidth, buf, sizeof(buf));
     		} else if (!strcasecmp(name, ED_TOK_LOSS)) {
     		    if (loss != -1.0)
     			errx(ED_EFMT("duplicated token: %s"), name);
    @@ -676,17 +709,17 @@ load_extra_delays(const char *filename, struct dn_pipe *p)
     	    double y2 = points[i+1].prob * samples;
     	    double x2 = points[i+1].delay;
     
    -	    int index = y1;
    +	    int ix = y1;
     	    int stop = y2;
     
     	    if (x1 == x2) {
    -		for (; indexsamples[index] = x1;
    +		for (; ixsamples[ix] = x1;
     	    } else {
     		double m = (y2-y1)/(x2-x1);
     		double c = y1 - m*x1;
    -		for (; indexsamples[index] = (index - c)/m;
    +		for (; ixsamples[ix] = (ix - c)/m;
     	    }
     	}
     	p->samples_no = samples;
    @@ -694,27 +727,120 @@ load_extra_delays(const char *filename, struct dn_pipe *p)
     	strncpy(p->name, profile_name, sizeof(p->name));
     }
     
    +/*
    + * configuration of pipes, schedulers, flowsets.
    + * When we configure a new scheduler, an empty pipe is created, so:
    + * 
    + * do_pipe = 1 -> "pipe N config ..." only for backward compatibility
    + *	sched N+Delta type fifo sched_mask ...
    + *	pipe N+Delta 
    + *	flowset N+Delta pipe N+Delta (no parameters)
    + *	sched N type wf2q+ sched_mask ...
    + *	pipe N 
    + *
    + * do_pipe = 2 -> flowset N config
    + *	flowset N parameters
    + *
    + * do_pipe = 3 -> sched N config
    + *	sched N parameters (default no pipe)
    + *	optional Pipe N config ...
    + * pipe ==>
    + */
     void
     ipfw_config_pipe(int ac, char **av)
     {
    -	int samples[ED_MAX_SAMPLES_NO];
    -	struct dn_pipe p;
    -	int i;
    +	int i, j;
     	char *end;
     	void *par = NULL;
    +	struct dn_id *buf, *base;
    +	struct dn_sch *sch = NULL;
    +	struct dn_link *p = NULL;
    +	struct dn_fs *fs = NULL;
    +	struct dn_profile *pf = NULL;
    +	struct ipfw_flow_id *mask = NULL;
    +	int lmax;
    +	uint32_t _foo = 0, *flags = &_foo , *buckets = &_foo;
     
    -	memset(&p, 0, sizeof p);
    -	p.bandwidth = -1;
    +	/*
    +	 * allocate space for 1 header,
    +	 * 1 scheduler, 1 link, 1 flowset, 1 profile
    +	 */
    +	lmax = sizeof(struct dn_id);	/* command header */
    +	lmax += sizeof(struct dn_sch) + sizeof(struct dn_link) +
    +		sizeof(struct dn_fs) + sizeof(struct dn_profile);
     
     	av++; ac--;
     	/* Pipe number */
     	if (ac && isdigit(**av)) {
     		i = atoi(*av); av++; ac--;
    -		if (co.do_pipe == 1)
    -			p.pipe_nr = i;
    -		else
    -			p.fs.fs_nr = i;
    +	} else
    +		i = -1;
    +	if (i <= 0)
    +		errx(EX_USAGE, "need a pipe/flowset/sched number");
    +	base = buf = safe_calloc(1, lmax);
    +	/* all commands start with a 'CONFIGURE' and a version */
    +	o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIG);
    +	base->id = DN_API_VERSION;
    +
    +	switch (co.do_pipe) {
    +	case 1: /* "pipe N config ..." */
    +		/* Allocate space for the WF2Q+ scheduler, its link
    +		 * and the FIFO flowset. Set the number, but leave
    +		 * the scheduler subtype and other parameters to 0
    +		 * so the kernel will use appropriate defaults.
    +		 * XXX todo: add a flag to record if a parameter
    +		 * is actually configured.
    +		 * If we do a 'pipe config' mask -> sched_mask.
    +		 * The FIFO scheduler and link are derived from the
    +		 * WF2Q+ one in the kernel.
    +		 */
    +		sch = o_next(&buf, sizeof(*sch), DN_SCH);
    +		p = o_next(&buf, sizeof(*p), DN_LINK);
    +		fs = o_next(&buf, sizeof(*fs), DN_FS);
    +
    +		sch->sched_nr = i;
    +		sch->oid.subtype = 0;	/* defaults to WF2Q+ */
    +		mask = &sch->sched_mask;
    +		flags = &sch->flags;
    +		buckets = &sch->buckets;
    +		*flags |= DN_PIPE_CMD;
    +
    +		p->link_nr = i;
    +
    +		/* This flowset is only for the FIFO scheduler */
    +		fs->fs_nr = i + 2*DN_MAX_ID;
    +		fs->sched_nr = i + DN_MAX_ID;
    +		break;
    +
    +	case 2: /* "queue N config ... " */
    +		fs = o_next(&buf, sizeof(*fs), DN_FS);
    +		fs->fs_nr = i;
    +		mask = &fs->flow_mask;
    +		flags = &fs->flags;
    +		buckets = &fs->buckets;
    +		break;
    +
    +	case 3: /* "sched N config ..." */
    +		sch = o_next(&buf, sizeof(*sch), DN_SCH);
    +		fs = o_next(&buf, sizeof(*fs), DN_FS);
    +		sch->sched_nr = i;
    +		mask = &sch->sched_mask;
    +		flags = &sch->flags;
    +		buckets = &sch->buckets;
    +		/* fs is used only with !MULTIQUEUE schedulers */
    +		fs->fs_nr = i + DN_MAX_ID;
    +		fs->sched_nr = i;
    +		break;
     	}
    +	/* set to -1 those fields for which we want to reuse existing
    +	 * values from the kernel.
    +	 * Also, *_nr and subtype = 0 mean reuse the value from the kernel.
    +	 * XXX todo: support reuse of the mask.
    +	 */
    +	if (p)
    +		p->bandwidth = -1;
    +	for (j = 0; j < sizeof(fs->par)/sizeof(fs->par[0]); j++)
    +		fs->par[j] = -1;
     	while (ac > 0) {
     		double d;
     		int tok = match_token(dummynet_params, *av);
    @@ -722,41 +848,48 @@ ipfw_config_pipe(int ac, char **av)
     
     		switch(tok) {
     		case TOK_NOERROR:
    -			p.fs.flags_fs |= DN_NOERROR;
    +			NEED(fs, "noerror is only for pipes");
    +			fs->flags |= DN_NOERROR;
     			break;
     
     		case TOK_PLR:
    +			NEED(fs, "plr is only for pipes");
     			NEED1("plr needs argument 0..1\n");
     			d = strtod(av[0], NULL);
     			if (d > 1)
     				d = 1;
     			else if (d < 0)
     				d = 0;
    -			p.fs.plr = (int)(d*0x7fffffff);
    +			fs->plr = (int)(d*0x7fffffff);
     			ac--; av++;
     			break;
     
     		case TOK_QUEUE:
    +			NEED(fs, "queue is only for pipes or flowsets");
     			NEED1("queue needs queue size\n");
     			end = NULL;
    -			p.fs.qsize = strtoul(av[0], &end, 0);
    +			fs->qsize = strtoul(av[0], &end, 0);
     			if (*end == 'K' || *end == 'k') {
    -				p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
    -				p.fs.qsize *= 1024;
    +				fs->flags |= DN_QSIZE_BYTES;
    +				fs->qsize *= 1024;
     			} else if (*end == 'B' ||
     			    _substrcmp2(end, "by", "bytes") == 0) {
    -				p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
    +				fs->flags |= DN_QSIZE_BYTES;
     			}
     			ac--; av++;
     			break;
     
     		case TOK_BUCKETS:
    +			NEED(fs, "buckets is only for pipes or flowsets");
     			NEED1("buckets needs argument\n");
    -			p.fs.rq_size = strtoul(av[0], NULL, 0);
    +			*buckets = strtoul(av[0], NULL, 0);
     			ac--; av++;
     			break;
     
    +		case TOK_FLOW_MASK:
    +		case TOK_SCHED_MASK:
     		case TOK_MASK:
    +			NEED(mask, "tok_mask");
     			NEED1("mask needs mask specifier\n");
     			/*
     			 * per-flow queue, mask is dst_ip, dst_port,
    @@ -764,7 +897,7 @@ ipfw_config_pipe(int ac, char **av)
     			 */
     			par = NULL;
     
    -			bzero(&p.fs.flow_mask, sizeof(p.fs.flow_mask));
    +			bzero(mask, sizeof(*mask));
     			end = NULL;
     
     			while (ac >= 1) {
    @@ -780,44 +913,55 @@ ipfw_config_pipe(int ac, char **av)
     			    case TOK_ALL:
     				    /*
     				     * special case, all bits significant
    +				     * except 'extra' (the queue number)
     				     */
    -				    p.fs.flow_mask.dst_ip = ~0;
    -				    p.fs.flow_mask.src_ip = ~0;
    -				    p.fs.flow_mask.dst_port = ~0;
    -				    p.fs.flow_mask.src_port = ~0;
    -				    p.fs.flow_mask.proto = ~0;
    -				    n2mask(&(p.fs.flow_mask.dst_ip6), 128);
    -				    n2mask(&(p.fs.flow_mask.src_ip6), 128);
    -				    p.fs.flow_mask.flow_id6 = ~0;
    -				    p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
    +				    mask->dst_ip = ~0;
    +				    mask->src_ip = ~0;
    +				    mask->dst_port = ~0;
    +				    mask->src_port = ~0;
    +				    mask->proto = ~0;
    +				    n2mask(&mask->dst_ip6, 128);
    +				    n2mask(&mask->src_ip6, 128);
    +				    mask->flow_id6 = ~0;
    +				    *flags |= DN_HAVE_MASK;
    +				    goto end_mask;
    +
    +			    case TOK_QUEUE:
    +				    mask->extra = ~0;
    +				    *flags |= DN_HAVE_MASK;
     				    goto end_mask;
     
     			    case TOK_DSTIP:
    -				    p32 = &p.fs.flow_mask.dst_ip;
    +				    mask->addr_type = 4;
    +				    p32 = &mask->dst_ip;
     				    break;
     
     			    case TOK_SRCIP:
    -				    p32 = &p.fs.flow_mask.src_ip;
    +				    mask->addr_type = 4;
    +				    p32 = &mask->src_ip;
     				    break;
     
     			    case TOK_DSTIP6:
    -				    pa6 = &(p.fs.flow_mask.dst_ip6);
    +				    mask->addr_type = 6;
    +				    pa6 = &mask->dst_ip6;
     				    break;
     			    
     			    case TOK_SRCIP6:
    -				    pa6 = &(p.fs.flow_mask.src_ip6);
    +				    mask->addr_type = 6;
    +				    pa6 = &mask->src_ip6;
     				    break;
     
     			    case TOK_FLOWID:
    -				    p20 = &p.fs.flow_mask.flow_id6;
    +				    mask->addr_type = 6;
    +				    p20 = &mask->flow_id6;
     				    break;
     
     			    case TOK_DSTPORT:
    -				    p16 = &p.fs.flow_mask.dst_port;
    +				    p16 = &mask->dst_port;
     				    break;
     
     			    case TOK_SRCPORT:
    -				    p16 = &p.fs.flow_mask.src_port;
    +				    p16 = &mask->src_port;
     				    break;
     
     			    case TOK_PROTO:
    @@ -857,10 +1001,10 @@ ipfw_config_pipe(int ac, char **av)
     				    if (a > 0xFF)
     					    errx(EX_DATAERR,
     						"proto mask must be 8 bit");
    -				    p.fs.flow_mask.proto = (uint8_t)a;
    +				    mask->proto = (uint8_t)a;
     			    }
     			    if (a != 0)
    -				    p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
    +				    *flags |= DN_HAVE_MASK;
     			    ac--; av++;
     			} /* end while, config masks */
     end_mask:
    @@ -869,9 +1013,9 @@ end_mask:
     		case TOK_RED:
     		case TOK_GRED:
     			NEED1("red/gred needs w_q/min_th/max_th/max_p\n");
    -			p.fs.flags_fs |= DN_IS_RED;
    +			fs->flags |= DN_IS_RED;
     			if (tok == TOK_GRED)
    -				p.fs.flags_fs |= DN_IS_GENTLE_RED;
    +				fs->flags |= DN_IS_GENTLE_RED;
     			/*
     			 * the format for parameters is w_q/min_th/max_th/max_p
     			 */
    @@ -879,82 +1023,108 @@ end_mask:
     			    double w_q = strtod(end, NULL);
     			    if (w_q > 1 || w_q <= 0)
     				errx(EX_DATAERR, "0 < w_q <= 1");
    -			    p.fs.w_q = (int) (w_q * (1 << SCALE_RED));
    +			    fs->w_q = (int) (w_q * (1 << SCALE_RED));
     			}
     			if ((end = strsep(&av[0], "/"))) {
    -			    p.fs.min_th = strtoul(end, &end, 0);
    +			    fs->min_th = strtoul(end, &end, 0);
     			    if (*end == 'K' || *end == 'k')
    -				p.fs.min_th *= 1024;
    +				fs->min_th *= 1024;
     			}
     			if ((end = strsep(&av[0], "/"))) {
    -			    p.fs.max_th = strtoul(end, &end, 0);
    +			    fs->max_th = strtoul(end, &end, 0);
     			    if (*end == 'K' || *end == 'k')
    -				p.fs.max_th *= 1024;
    +				fs->max_th *= 1024;
     			}
     			if ((end = strsep(&av[0], "/"))) {
     			    double max_p = strtod(end, NULL);
     			    if (max_p > 1 || max_p <= 0)
     				errx(EX_DATAERR, "0 < max_p <= 1");
    -			    p.fs.max_p = (int)(max_p * (1 << SCALE_RED));
    +			    fs->max_p = (int)(max_p * (1 << SCALE_RED));
     			}
     			ac--; av++;
     			break;
     
     		case TOK_DROPTAIL:
    -			p.fs.flags_fs &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
    +			NEED(fs, "droptail is only for flowsets");
    +			fs->flags &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
     			break;
     
     		case TOK_BW:
    +			NEED(p, "bw is only for links");
     			NEED1("bw needs bandwidth or interface\n");
    -			if (co.do_pipe != 1)
    -			    errx(EX_DATAERR, "bandwidth only valid for pipes");
    -			read_bandwidth(av[0], &p.bandwidth, p.if_name, sizeof(p.if_name));
    +			read_bandwidth(av[0], &p->bandwidth, NULL, 0);
     			ac--; av++;
     			break;
     
     		case TOK_DELAY:
    -			if (co.do_pipe != 1)
    -				errx(EX_DATAERR, "delay only valid for pipes");
    +			NEED(p, "delay is only for links");
     			NEED1("delay needs argument 0..10000ms\n");
    -			p.delay = strtoul(av[0], NULL, 0);
    +			p->delay = strtoul(av[0], NULL, 0);
     			ac--; av++;
     			break;
     
    +		case TOK_TYPE: {
    +			int l;
    +			NEED(sch, "type is only for schedulers");
    +			NEED1("type needs a string");
    +			l = strlen(av[0]);
    +			if (l == 0 || l > 15)
    +				errx(1, "type %s too long\n", av[0]);
    +			strcpy(sch->name, av[0]);
    +			sch->oid.subtype = 0; /* use string */
    +			ac--; av++;
    +			break;
    +		    }
    +
     		case TOK_WEIGHT:
    -			if (co.do_pipe == 1)
    -				errx(EX_DATAERR,"weight only valid for queues");
    -			NEED1("weight needs argument 0..100\n");
    -			p.fs.weight = strtoul(av[0], &end, 0);
    +			NEED(fs, "weight is only for flowsets");
    +			NEED1("weight needs argument\n");
    +			fs->par[0] = strtol(av[0], &end, 0);
     			ac--; av++;
     			break;
     
    +		case TOK_LMAX:
    +			NEED(fs, "lmax is only for flowsets");
    +			NEED1("lmax needs argument\n");
    +			fs->par[1] = strtol(av[0], &end, 0);
    +			ac--; av++;
    +			break;
    +
    +		case TOK_PRI:
    +			NEED(fs, "priority is only for flowsets");
    +			NEED1("priority needs argument\n");
    +			fs->par[2] = strtol(av[0], &end, 0);
    +			ac--; av++;
    +			break;
    +
    +		case TOK_SCHED:
     		case TOK_PIPE:
    -			if (co.do_pipe == 1)
    -				errx(EX_DATAERR,"pipe only valid for queues");
    -			NEED1("pipe needs pipe_number\n");
    -			p.fs.parent_nr = strtoul(av[0], &end, 0);
    +			NEED(fs, "pipe/sched");
    +			NEED1("pipe/link/sched needs number\n");
    +			fs->sched_nr = strtoul(av[0], &end, 0);
     			ac--; av++;
     			break;
     
    -		case TOK_PIPE_PROFILE:
    -			if (co.do_pipe != 1)
    -			    errx(EX_DATAERR, "extra delay only valid for pipes");
    +		case TOK_PROFILE:
    +			NEED((!pf), "profile already set");
    +			NEED(p, "profile");
    +		    {
     			NEED1("extra delay needs the file name\n");
    -			p.samples = &samples[0];
    -			load_extra_delays(av[0], &p);
    +			pf = o_next(&buf, sizeof(*pf), DN_PROFILE);
    +			load_extra_delays(av[0], pf, p); //XXX can't fail?
     			--ac; ++av;
    +		    }
     			break;
     
     		case TOK_BURST:
    -			if (co.do_pipe != 1)
    -				errx(EX_DATAERR, "burst only valid for pipes");
    +			NEED(p, "burst");
     			NEED1("burst needs argument\n");
     			errno = 0;
    -			if (expand_number(av[0], &p.burst) < 0)
    +			if (expand_number(av[0], (int64_t *)&p->burst) < 0)
     				if (errno != ERANGE)
     					errx(EX_DATAERR,
     					    "burst: invalid argument");
    -			if (errno || p.burst > (1ULL << 48) - 1)
    +			if (errno || p->burst > (1ULL << 48) - 1)
     				errx(EX_DATAERR,
     				    "burst: out of range (0..2^48-1)");
     			ac--; av++;
    @@ -964,26 +1134,17 @@ end_mask:
     			errx(EX_DATAERR, "unrecognised option ``%s''", av[-1]);
     		}
     	}
    -	if (co.do_pipe == 1) {
    -		if (p.pipe_nr == 0)
    -			errx(EX_DATAERR, "pipe_nr must be > 0");
    -		if (p.delay > 10000)
    +
    +	/* check validity of parameters */
    +	if (p) {
    +		if (p->delay > 10000)
     			errx(EX_DATAERR, "delay must be < 10000");
    -	} else { /* co.do_pipe == 2, queue */
    -		if (p.fs.parent_nr == 0)
    -			errx(EX_DATAERR, "pipe must be > 0");
    -		if (p.fs.weight >100)
    -			errx(EX_DATAERR, "weight must be <= 100");
    +		if (p->bandwidth == -1)
    +			p->bandwidth = 0;
     	}
    -
    -	/* check for bandwidth value */
    -	if (p.bandwidth == -1) {
    -		p.bandwidth = 0;
    -		if (p.samples_no > 0)
    -			errx(EX_DATAERR, "profile requires a bandwidth limit");
    -	}
    -
    -	if (p.fs.flags_fs & DN_QSIZE_IS_BYTES) {
    +	if (fs) {
    +		/* XXX accept a 0 scheduler to keep the default */
    +	    if (fs->flags & DN_QSIZE_BYTES) {
     		size_t len;
     		long limit;
     
    @@ -991,9 +1152,9 @@ end_mask:
     		if (sysctlbyname("net.inet.ip.dummynet.pipe_byte_limit",
     			&limit, &len, NULL, 0) == -1)
     			limit = 1024*1024;
    -		if (p.fs.qsize > limit)
    +		if (fs->qsize > limit)
     			errx(EX_DATAERR, "queue size must be < %ldB", limit);
    -	} else {
    +	    } else {
     		size_t len;
     		long limit;
     
    @@ -1001,27 +1162,25 @@ end_mask:
     		if (sysctlbyname("net.inet.ip.dummynet.pipe_slot_limit",
     			&limit, &len, NULL, 0) == -1)
     			limit = 100;
    -		if (p.fs.qsize > limit)
    +		if (fs->qsize > limit)
     			errx(EX_DATAERR, "2 <= queue size <= %ld", limit);
    -	}
    -	if (p.fs.flags_fs & DN_IS_RED) {
    +	    }
    +
    +	    if (fs->flags & DN_IS_RED) {
     		size_t len;
     		int lookup_depth, avg_pkt_size;
    -		double s, idle, weight, w_q;
    -		struct clockinfo ck;
    -		int t;
    +		double w_q;
     
    -		if (p.fs.min_th >= p.fs.max_th)
    +		if (fs->min_th >= fs->max_th)
     		    errx(EX_DATAERR, "min_th %d must be < than max_th %d",
    -			p.fs.min_th, p.fs.max_th);
    -		if (p.fs.max_th == 0)
    +			fs->min_th, fs->max_th);
    +		if (fs->max_th == 0)
     		    errx(EX_DATAERR, "max_th must be > 0");
     
     		len = sizeof(int);
     		if (sysctlbyname("net.inet.ip.dummynet.red_lookup_depth",
     			&lookup_depth, &len, NULL, 0) == -1)
    -		    errx(1, "sysctlbyname(\"%s\")",
    -			"net.inet.ip.dummynet.red_lookup_depth");
    +			lookup_depth = 256;
     		if (lookup_depth == 0)
     		    errx(EX_DATAERR, "net.inet.ip.dummynet.red_lookup_depth"
     			" must be greater than zero");
    @@ -1029,18 +1188,13 @@ end_mask:
     		len = sizeof(int);
     		if (sysctlbyname("net.inet.ip.dummynet.red_avg_pkt_size",
     			&avg_pkt_size, &len, NULL, 0) == -1)
    +			avg_pkt_size = 512;
     
    -		    errx(1, "sysctlbyname(\"%s\")",
    -			"net.inet.ip.dummynet.red_avg_pkt_size");
     		if (avg_pkt_size == 0)
     			errx(EX_DATAERR,
     			    "net.inet.ip.dummynet.red_avg_pkt_size must"
     			    " be greater than zero");
     
    -		len = sizeof(struct clockinfo);
    -		if (sysctlbyname("kern.clockrate", &ck, &len, NULL, 0) == -1)
    -			errx(1, "sysctlbyname(\"%s\")", "kern.clockrate");
    -
     		/*
     		 * Ticks needed for sending a medium-sized packet.
     		 * Unfortunately, when we are configuring a WF2Q+ queue, we
    @@ -1050,38 +1204,181 @@ end_mask:
     		 * correct. But on the other hand, why do we want RED with
     		 * WF2Q+ ?
     		 */
    +#if 0
     		if (p.bandwidth==0) /* this is a WF2Q+ queue */
     			s = 0;
     		else
     			s = (double)ck.hz * avg_pkt_size * 8 / p.bandwidth;
    -
    +#endif
     		/*
     		 * max idle time (in ticks) before avg queue size becomes 0.
     		 * NOTA:  (3/w_q) is approx the value x so that
     		 * (1-w_q)^x < 10^-3.
     		 */
    -		w_q = ((double)p.fs.w_q) / (1 << SCALE_RED);
    +		w_q = ((double)fs->w_q) / (1 << SCALE_RED);
    +#if 0 // go in kernel
     		idle = s * 3. / w_q;
    -		p.fs.lookup_step = (int)idle / lookup_depth;
    -		if (!p.fs.lookup_step)
    -			p.fs.lookup_step = 1;
    +		fs->lookup_step = (int)idle / lookup_depth;
    +		if (!fs->lookup_step)
    +			fs->lookup_step = 1;
     		weight = 1 - w_q;
    -		for (t = p.fs.lookup_step; t > 1; --t)
    +		for (t = fs->lookup_step; t > 1; --t)
     			weight *= 1 - w_q;
    -		p.fs.lookup_weight = (int)(weight * (1 << SCALE_RED));
    +		fs->lookup_weight = (int)(weight * (1 << SCALE_RED));
    +#endif
    +	    }
     	}
    -	if (p.samples_no <= 0) {
    -		i = do_cmd(IP_DUMMYNET_CONFIGURE, &p, sizeof p);
    -	} else {
    -		struct dn_pipe_max pm;
    -		int len = sizeof(pm);
     
    -		memcpy(&pm.pipe, &p, sizeof(pm.pipe));
    -		memcpy(&pm.samples, samples, sizeof(pm.samples));
    -
    -		i = do_cmd(IP_DUMMYNET_CONFIGURE, &pm, len);
    -	}
    +	i = do_cmd(IP_DUMMYNET3, base, (char *)buf - (char *)base);
     
     	if (i)
     		err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE");
     }
    +
    +void
    +dummynet_flush(void)
    +{
    +	struct dn_id oid;
    +	oid_fill(&oid, sizeof(oid), DN_CMD_FLUSH, DN_API_VERSION);
    +	do_cmd(IP_DUMMYNET3, &oid, oid.len);
    +}
    +
    +/* Parse input for 'ipfw [pipe|sched|queue] show [range list]'
    + * Returns the number of ranges, and possibly stores them
    + * in the array v of size len.
    + */
    +static int
    +parse_range(int ac, char *av[], uint32_t *v, int len)
    +{
    +	int n = 0;
    +	char *endptr, *s;
    +	uint32_t base[2];
    +
    +	if (v == NULL || len < 2) {
    +		v = base;
    +		len = 2;
    +	}
    +
    +	for (s = *av; s != NULL; av++, ac--) {
    +		v[0] = strtoul(s, &endptr, 10);
    +		v[1] = (*endptr != '-') ? v[0] :
    +			 strtoul(endptr+1, &endptr, 10);
    +		if (*endptr == '\0') { /* prepare for next round */
    +			s = (ac > 0) ? *(av+1) : NULL;
    +		} else {
    +			if (*endptr != ',') {
    +				warn("invalid number: %s", s);
    +				s = ++endptr;
    +				continue;
    +			}
    +			/* continue processing from here */
    +			s = ++endptr;
    +			ac++;
    +			av--;
    +		}
    +		if (v[1] < v[0] ||
    +			v[1] < 0 || v[1] >= DN_MAX_ID-1 ||
    +			v[0] < 0 || v[1] >= DN_MAX_ID-1) {
    +			continue; /* invalid entry */
    +		}
    +		n++;
    +		/* translate if 'pipe list' */
    +		if (co.do_pipe == 1) {
    +			v[0] += DN_MAX_ID;
    +			v[1] += DN_MAX_ID;
    +		}
    +		v = (n*2 < len) ? v + 2 : base;
    +	}
    +	return n;
    +}
    +
    +/* main entry point for dummynet list functions. co.do_pipe indicates
    + * which function we want to support.
    + * av may contain filtering arguments, either individual entries
    + * or ranges, or lists (space or commas are valid separators).
    + * Format for a range can be n1-n2 or n3 n4 n5 ...
    + * In a range n1 must be <= n2, otherwise the range is ignored.
    + * A number 'n4' is translate in a range 'n4-n4'
    + * All number must be > 0 and < DN_MAX_ID-1
    + */
    +void
    +dummynet_list(int ac, char *av[], int show_counters)
    +{
    +	struct dn_id *oid, *x = NULL;
    +	int ret, i, l;
    +	int n; 		/* # of ranges */
    +	int buflen;
    +	int max_size;	/* largest obj passed up */
    +
    +	ac--;
    +	av++; 		/* skip 'list' | 'show' word */
    +
    +	n = parse_range(ac, av, NULL, 0);	/* Count # of ranges. */
    +
    +	/* Allocate space to store ranges */
    +	l = sizeof(*oid) + sizeof(uint32_t) * n * 2;
    +	oid = safe_calloc(1, l);
    +	oid_fill(oid, l, DN_CMD_GET, DN_API_VERSION);
    +
    +	if (n > 0)	/* store ranges in idx */
    +		parse_range(ac, av, (uint32_t *)(oid + 1), n*2);
    +	/*
    +	 * Compute the size of the largest object returned. If the
    +	 * response leaves at least this much spare space in the
    +	 * buffer, then surely the response is complete; otherwise
    +	 * there might be a risk of truncation and we will need to
    +	 * retry with a larger buffer.
    +	 * XXX don't bother with smaller structs.
    +	 */
    +	max_size = sizeof(struct dn_fs);
    +	if (max_size < sizeof(struct dn_sch))
    +		max_size = sizeof(struct dn_sch);
    +	if (max_size < sizeof(struct dn_flow))
    +		max_size = sizeof(struct dn_flow);
    +
    +	switch (co.do_pipe) {
    +	case 1:
    +		oid->subtype = DN_LINK;	/* list pipe */
    +		break;
    +	case 2:
    +		oid->subtype = DN_FS;	/* list queue */
    +		break;
    +	case 3:
    +		oid->subtype = DN_SCH;	/* list sched */
    +		break;
    +	}
    +
    +	/*
    +	 * Ask the kernel an estimate of the required space (result
    +	 * in oid.id), unless we are requesting a subset of objects,
    +	 * in which case the kernel does not give an exact answer.
    +	 * In any case, space might grow in the meantime due to the
    +	 * creation of new queues, so we must be prepared to retry.
    +	 */
    +	if (n > 0) {
    +		buflen = 4*1024;
    +	} else {
    +		ret = do_cmd(-IP_DUMMYNET3, oid, (uintptr_t)&l);
    +		if (ret != 0 || oid->id <= sizeof(*oid))
    +			goto done;
    +		buflen = oid->id + max_size;
    +		oid->len = sizeof(*oid); /* restore */
    +	}
    +	/* Try a few times, until the buffer fits */
    +	for (i = 0; i < 20; i++) {
    +		l = buflen;
    +		x = safe_realloc(x, l);
    +		bcopy(oid, x, oid->len);
    +		ret = do_cmd(-IP_DUMMYNET3, x, (uintptr_t)&l);
    +		if (ret != 0 || x->id <= sizeof(*oid))
    +			goto done; /* no response */
    +		if (l + max_size <= buflen)
    +			break; /* ok */
    +		buflen *= 2;	 /* double for next attempt */
    +	}
    +	list_pipes(x, O_NEXT(x, l));
    +done:
    +	if (x)
    +		free(x);
    +	free(oid);
    +}
    diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
    index f8b0746a25a..897cd3fd59a 100644
    --- a/sbin/ipfw/ipfw.8
    +++ b/sbin/ipfw/ipfw.8
    @@ -6,8 +6,10 @@
     .Os
     .Sh NAME
     .Nm ipfw
    -.Nd IP firewall and traffic shaper control program
    +.Nd User interface for firewall, traffic shaper, packet scheduler,
    +in-kernel NAT.
     .Sh SYNOPSIS
    +.Ss FIREWALL CONFIGURATION
     .Nm
     .Op Fl cq
     .Cm add
    @@ -26,12 +28,6 @@
     .Op Cm set Ar N
     .Brq Cm delete | zero | resetlog
     .Op Ar number ...
    -.Nm
    -.Cm enable
    -.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
    -.Nm
    -.Cm disable
    -.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
     .Pp
     .Nm
     .Cm set Oo Cm disable Ar number ... Oc Op Cm enable Ar number ...
    @@ -43,8 +39,17 @@
     .Cm set swap Ar number number
     .Nm
     .Cm set show
    +.Ss SYSCTL SHORTCUTS
     .Pp
     .Nm
    +.Cm enable
    +.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
    +.Nm
    +.Cm disable
    +.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
    +.Pp
    +.Ss LOOKUP TABLES
    +.Nm
     .Cm table Ar number Cm add Ar addr Ns Oo / Ns Ar masklen Oc Op Ar value
     .Nm
     .Cm table Ar number Cm delete Ar addr Ns Op / Ns Ar masklen
    @@ -57,17 +62,19 @@
     .Brq Ar number | all
     .Cm list
     .Pp
    +.Ss DUMMYNET CONFIGURATION (TRAFFIC SHAPER AND PACKET SCHEDULER)
     .Nm
    -.Brq Cm pipe | queue
    +.Brq Cm pipe | queue | sched
     .Ar number
     .Cm config
     .Ar config-options
     .Nm
     .Op Fl s Op Ar field
    -.Brq Cm pipe | queue
    +.Brq Cm pipe | queue | sched
     .Brq Cm delete | list | show
     .Op Ar number ...
     .Pp
    +.Ss IN-KERNEL NAT
     .Nm
     .Op Fl q
     .Cm nat
    @@ -89,28 +96,27 @@ The
     .Nm
     utility is the user interface for controlling the
     .Xr ipfw 4
    -firewall and the
    +firewall, the
     .Xr dummynet 4
    -traffic shaper in
    -.Fx .
    +traffic shaper/packet scheduler, and the
    +in-kernel NAT services.
     .Pp
    -An
    -.Nm
    -configuration, or
    +A firewall configuration, or
     .Em ruleset ,
     is made of a list of
     .Em rules
     numbered from 1 to 65535.
    -Packets are passed to
    -.Nm
    +Packets are passed to the firewall
     from a number of different places in the protocol stack
     (depending on the source and destination of the packet,
    -it is possible that
    -.Nm
    -is invoked multiple times on the same packet).
    +it is possible for the firewall to be
    +invoked multiple times on the same packet).
     The packet passed to the firewall is compared
    -against each of the rules in the firewall
    -.Em ruleset .
    +against each of the rules in the
    +.Em ruleset ,
    +in rule-number order
    +(multiple rules with the same number are permitted, in which case
    +they are processed in order of insertion).
     When a match is found, the action corresponding to the
     matching rule is performed.
     .Pp
    @@ -118,9 +124,7 @@ Depending on the action and certain system settings, packets
     can be reinjected into the firewall at some rule after the
     matching one for further processing.
     .Pp
    -An
    -.Nm
    -ruleset always includes a
    +A ruleset always includes a
     .Em default
     rule (numbered 65535) which cannot be modified or deleted,
     and matches all packets.
    @@ -137,14 +141,14 @@ If the ruleset includes one or more rules with the
     or
     .Cm limit
     option,
    -.Nm
    -will have a
    +the firewall will have a
     .Em stateful
    -behaviour, i.e., upon a match it will create dynamic rules matching
    -the exact parameters (source and destination addresses and ports)
    -of the matching packet.
    -.Pp
    -These dynamic rules, which have a limited lifetime, are checked
    +behaviour, i.e., upon a match it will create
    +.Em dynamic rules ,
    +i.e. rules that match packets with the same 5-tuple
    +(protocol, source and destination addresses and ports)
    +as the packet which caused their creation.
    +Dynamic rules, which have a limited lifetime, are checked
     at the first occurrence of a
     .Cm check-state ,
     .Cm keep-state
    @@ -283,6 +287,7 @@ When listing, show last match timestamp as seconds from the epoch.
     This form can be more convenient for postprocessing by scripts.
     .El
     .Pp
    +.Ss LIST OF RULES AND PREPROCESSING
     To ease configuration, rules can be put into a file which is
     processed using
     .Nm
    @@ -322,14 +327,16 @@ This allows for flexible configuration files (like conditionalizing
     them on the local hostname) and the use of macros to centralize
     frequently required arguments like IP addresses.
     .Pp
    +.Ss TRAFFIC SHAPER CONFIGURATION
     The
     .Nm
    -.Cm pipe
    +.Cm pipe , queue
     and
    -.Cm queue
    -commands are used to configure the traffic shaper, as shown in the
    +.Cm sched
    +commands are used to configure the traffic shaper and packet scheduler.
    +See the
     .Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
    -Section below.
    +Section below for details.
     .Pp
     If the world and the kernel get out of sync the
     .Nm
    @@ -362,7 +369,7 @@ have this picture in mind in order to design a correct ruleset.
            |      to devices       |
     .Ed
     .Pp
    -As can be noted from the above picture, the number of
    +The number of
     times the same packet goes through the firewall can
     vary between 0 and 4 depending on packet source and
     destination, and system configuration.
    @@ -421,9 +428,9 @@ Keywords are case-sensitive, whereas arguments may
     or may not be case-sensitive depending on their nature
     (e.g.\& uid's are, hostnames are not).
     .Pp
    -In
    -.Nm ipfw2
    -you can introduce spaces after commas ',' to make
    +Some arguments (e.g. port or address lists) are comma-separated
    +lists of values.
    +In this case, spaces after commas ',' are allowed to make
     the line more readable.
     You can also put the entire
     command (including flags) into a single argument.
    @@ -434,9 +441,7 @@ ipfw -q add deny src-ip 10.0.0.0/24, 127.0.0.1/8
     ipfw "-q add deny src-ip 10.0.0.0/24, 127.0.0.1/8"
     .Ed
     .Sh RULE FORMAT
    -The format of
    -.Nm
    -rules is the following:
    +The format of firewall rules is the following:
     .Bd -ragged -offset indent
     .Bk -words
     .Op Ar rule_number
    @@ -496,7 +501,7 @@ in future forwarding decisions.
     .El
     .Pp
     Note that some of the above information, e.g.\& source MAC or IP addresses and
    -TCP/UDP ports, could easily be spoofed, so filtering on those fields
    +TCP/UDP ports, can be easily spoofed, so filtering on those fields
     alone might not guarantee the desired results.
     .Bl -tag -width indent
     .It Ar rule_number
    @@ -1002,6 +1007,7 @@ The second format
     with multiple addresses) is provided for convenience only and
     its use is discouraged.
     .It Ar addr : Oo Cm not Oc Bro
    +.Bl -tag -width indent
     .Cm any | me | me6 |
     .Cm table Ns Pq Ar number Ns Op , Ns Ar value
     .Ar | addr-list | addr-set
    @@ -1023,6 +1029,7 @@ is also specified, an entry will match only if it has this value.
     See the
     .Sx LOOKUP TABLES
     section below for more information on lookup tables.
    +.El
     .It Ar addr-list : ip-addr Ns Op Ns , Ns Ar addr-list
     .It Ar ip-addr :
     A host or subnet address specified in one of the following ways:
    @@ -1389,6 +1396,20 @@ of source and destination addresses and ports can be
     specified.
     Currently,
     only IPv4 flows are supported.
    +.It Cm lookup Bro Cm dst-ip | dst-port | src-ip | src-port | uid | jail Brc Ar N
    +Search an entry in lookup table
    +.Ar N
    +that matches the field specified as argument.
    +If not found, the match fails.
    +Otherwise, the match succeeds and
    +.Cm tablearg
    +is set to the value extracted from the table.
    +.Pp
    +This option can be useful to quickly dispatch traffic based on
    +certain packet fields.
    +See the
    +.Sx LOOKUP TABLES
    +section below for more information on lookup tables.
     .It Cm { MAC | mac } Ar dst-mac src-mac
     Match packets with a given
     .Ar dst-mac
    @@ -1480,7 +1501,7 @@ is invalid) whenever
     .Cm xmit
     is used.
     .Pp
    -A packet may not have a receive or transmit interface: packets
    +A packet might not have a receive or transmit interface: packets
     originating from the local host have no receive interface,
     while packets destined for the local host have no transmit
     interface.
    @@ -1627,15 +1648,17 @@ because it engages only on packets with source addresses of directly
     connected networks instead of all source addresses.
     .El
     .Sh LOOKUP TABLES
    -Lookup tables are useful to handle large sparse address sets,
    -typically from a hundred to several thousands of entries.
    +Lookup tables are useful to handle large sparse sets of
    +addresses or other search keys (e.g. ports, jail IDs).
    +In the rest of this section we will use the term ``address''
    +to mean any unsigned value of up to 32-bit.
     There may be up to 128 different lookup tables, numbered 0 to 127.
     .Pp
     Each entry is represented by an
     .Ar addr Ns Op / Ns Ar masklen
     and will match all addresses with base
     .Ar addr
    -(specified as an IP address or a hostname)
    +(specified as an IP address, a hostname or an unsigned integer)
     and mask width of
     .Ar masklen
     bits.
    @@ -1653,9 +1676,9 @@ is not specified, it defaults to 0.
     .Pp
     An entry can be added to a table
     .Pq Cm add ,
    -removed from a table
    -.Pq Cm delete ,
    -a table can be examined
    +or removed from a table
    +.Pq Cm delete .
    +A table can be examined
     .Pq Cm list
     or flushed
     .Pq Cm flush .
    @@ -1664,7 +1687,7 @@ Internally, each table is stored in a Radix tree, the same way as
     the routing table (see
     .Xr route 4 ) .
     .Pp
    -Lookup tables currently support IPv4 addresses only.
    +Lookup tables currently support only ports, jail IDs and IPv4 addresses.
     .Pp
     The
     .Cm tablearg
    @@ -1822,9 +1845,9 @@ for more examples on how to use dynamic rules.
     .Nm
     is also the user interface for the
     .Nm dummynet
    -traffic shaper and network emulator, a subsystem that
    +traffic shaper, packet scheduler and network emulator, a subsystem that
     can artificially queue, delay or drop packets
    -emulator the behaviour of certain network links
    +emulating the behaviour of certain network links
     or queueing systems.
     .Pp
     .Nm dummynet
    @@ -1836,26 +1859,33 @@ Matching packets are then passed to either of two
     different objects, which implement the traffic regulation:
     .Bl -hang -offset XXXX
     .It Em pipe
    -A pipe emulates a link with given bandwidth, propagation delay,
    +A
    +.Em pipe
    +emulates a
    +.Em link
    +with given bandwidth and propagation delay,
    +driven by a FIFO scheduler and a single queue with programmable
     queue size and packet loss rate.
    -Packets are queued in front of the pipe as they come out from the classifier,
    -and then transferred to the pipe according to the pipe's parameters.
    +Packets are appended to the queue as they come out from
    +.Nm ipfw ,
    +and then transferred in FIFO order to the link at the desired rate.
     .It Em queue
    -A queue
    -is an abstraction used to implement the WF2Q+
    -(Worst-case Fair Weighted Fair Queueing) policy, which is
    -an efficient variant of the WFQ policy.
    -.Pp
    -The queue associates a
    -.Em weight
    -and a reference pipe to each flow (a flow is a set of packets
    -with the same addresses and ports after masking).
    -All backlogged flows (i.e., those
    -with packets queued) linked to the same pipe share the pipe's
    -bandwidth proportionally to their weights.
    -Note that weights are not priorities; a flow with a lower weight
    -is still guaranteed to get its fraction of the bandwidth even if a
    -flow with a higher weight is permanently backlogged.
    +A
    +.Em queue
    +is an abstraction used to implement packet scheduling
    +using one of several packet scheduling algorithms.
    +Packets sent to a
    +.Em queue
    +are first grouped into flows according to a mask on the 5-tuple.
    +Flows are then passed to the scheduler associated to the
    +.Em queue ,
    +and each flow uses scheduling parameters (weight and others)
    +as configured in the
    +.Em queue
    +itself.
    +A scheduler in turn is connected to an emulated link,
    +and arbitrates the link's bandwidth among backlogged flows according to
    +weights and to the features of the scheduling algorithm in use.
     .El
     .Pp
     In practice,
    @@ -1864,6 +1894,52 @@ can be used to set hard limits to the bandwidth that a flow can use, whereas
     .Em queues
     can be used to determine how different flows share the available bandwidth.
     .Pp
    +A graphical representation of the binding of queues,
    +flows, schedulers and links is below.
    +.Bd -literal -offset indent
    +                 (flow_mask|sched_mask)  sched_mask
    +         +---------+   weight Wx  +-------------+
    +         |         |->-[flow]-->--|             |-+
    +    -->--| QUEUE x |   ...        |             | |
    +         |         |->-[flow]-->--| SCHEDuler N | |
    +         +---------+              |             | |
    +             ...                  |             +--[LINK N]-->--
    +         +---------+   weight Wy  |             | +--[LINK N]-->--
    +         |         |->-[flow]-->--|             | |
    +    -->--| QUEUE y |   ...        |             | |
    +         |         |->-[flow]-->--|             | |
    +         +---------+              +-------------+ |
    +                                    +-------------+
    +.Ed
    +It is important to understand the role of the SCHED_MASK
    +and FLOW_MASK, which are configured through the commands
    +.Dl "ipfw sched N config mask SCHED_MASK ..."
    +and
    +.Dl "ipfw queue X config mask FLOW_MASK ..." .
    +.Pp
    +The SCHED_MASK is used to assign flows to one or more
    +scheduler instances, one for each
    +value of the packet's 5-fuple after applying SCHED_MASK.
    +As an example, using ``src-ip 0xffffff00'' creates one instance
    +for each /24 destination subnet.
    +.Pp
    +The FLOW_MASK, together with the SCHED_MASK, is used to split
    +packets into flows. As an example, using
    +``src-ip 0x000000ff''
    +together with the previous SCHED_MASK makes a flow for
    +each individual source address. In turn, flows for each /24
    +subnet will be sent to the same scheduler instance.
    +.Pp
    +The above diagram holds even for the
    +.Em pipe
    +case, with the only restriction that a
    +.Em pipe
    +only supports a SCHED_MASK, and forces the use of a FIFO
    +scheduler (these are for backward compatibility reasons;
    +in fact, internally, a
    +.Nm dummynet's
    +pipe is implemented exactly as above).
    +.Pp
     There are two modes of
     .Nm dummynet
     operation:
    @@ -1895,16 +1971,19 @@ mode can be enabled by setting the
     .Xr sysctl 8
     variable to a non-zero value.
     .Pp
    -.Ss PIPE AND QUEUE CONFIGURATION
    +.Ss PIPE, QUEUE AND SCHEDULER CONFIGURATION
     The
    -.Em pipe
    -and
    +.Em pipe ,
     .Em queue
    +and
    +.Em scheduler
     configuration commands are the following:
     .Bd -ragged -offset indent
     .Cm pipe Ar number Cm config Ar pipe-configuration
     .Pp
     .Cm queue Ar number Cm config Ar queue-configuration
    +.Pp
    +.Cm sched Ar number Cm config Ar sched-configuration
     .Ed
     .Pp
     The following parameters can be configured for a pipe:
    @@ -2057,6 +2136,41 @@ Specifies the weight to be used for flows matching this queue.
     The weight must be in the range 1..100, and defaults to 1.
     .El
     .Pp
    +The following parameters can be configured for a scheduler:
    +.Pp
    +.Bl -tag -width indent -compact
    +.It Cm type Ar {fifo | wf2qp | rr | qfq}
    +specifies the scheduling algorithm to use.
    +.Bl -tag -width indent -compact
    +.It cm fifo
    +is just a FIFO scheduler (which means that all packets
    +are stored in the same queue as they arrive to the scheduler).
    +FIFO has O(1) per-packet time complexity, with very low
    +constants (estimate 60-80ns on a 2Ghz desktop machine)
    +but gives no service guarantees.
    +.It Cm wf2qp
    +implements the WF2Q+ algorithm, which is a Weighted Fair Queueing
    +algorithm which permits flows to share bandwidth according to
    +their weights. Note that weights are not priorities; even a flow
    +with a minuscule weight will never starve.
    +WF2Q+ has O(log N) per-packet processing cost, where N is the number
    +of flows, and is the default algorithm used by previous versions
    +dummynet's queues.
    +.It Cm rr
    +implements the Deficit Round Robin algorithm, which has O(1) processing
    +costs (roughly, 100-150ns per packet)
    +and permits bandwidth allocation according to weights, but
    +with poor service guarantees.
    +.It Cm qfq
    +implements the QFQ algorithm, which is a very fast variant of
    +WF2Q+, with similar service guarantees and O(1) processing
    +costs (roughly, 200-250ns per packet).
    +.El
    +.El
    +.Pp
    +In addition to the type, all parameters allowed for a pipe can also
    +be specified for a scheduler.
    +.Pp
     Finally, the following parameters can be configured for both
     pipes and queues:
     .Pp
    diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
    index b19f390b294..1ab827f3e26 100644
    --- a/sbin/ipfw/ipfw2.c
    +++ b/sbin/ipfw/ipfw2.c
    @@ -57,7 +57,7 @@ struct cmdline_opts co;	/* global options */
     int resvd_set_number = RESVD_SET;
     
     #define GET_UINT_ARG(arg, min, max, tok, s_x) do {			\
    -	if (!ac)							\
    +	if (!av[0])							\
     		errx(EX_USAGE, "%s: missing argument", match_value(s_x, tok)); \
     	if (_substrcmp(*av, "tablearg") == 0) {				\
     		arg = IP_FW_TABLEARG;					\
    @@ -65,23 +65,23 @@ int resvd_set_number = RESVD_SET;
     	}								\
     									\
     	{								\
    -	long val;							\
    +	long _xval;							\
     	char *end;							\
     									\
    -	val = strtol(*av, &end, 10);					\
    +	_xval = strtol(*av, &end, 10);					\
     									\
    -	if (!isdigit(**av) || *end != '\0' || (val == 0 && errno == EINVAL)) \
    +	if (!isdigit(**av) || *end != '\0' || (_xval == 0 && errno == EINVAL)) \
     		errx(EX_DATAERR, "%s: invalid argument: %s",		\
     		    match_value(s_x, tok), *av);			\
     									\
    -	if (errno == ERANGE || val < min || val > max)			\
    +	if (errno == ERANGE || _xval < min || _xval > max)		\
     		errx(EX_DATAERR, "%s: argument is out of range (%u..%u): %s", \
     		    match_value(s_x, tok), min, max, *av);		\
     									\
    -	if (val == IP_FW_TABLEARG)					\
    +	if (_xval == IP_FW_TABLEARG)					\
     		errx(EX_DATAERR, "%s: illegal argument value: %s",	\
     		    match_value(s_x, tok), *av);			\
    -	arg = val;							\
    +	arg = _xval;							\
     	}								\
     } while (0)
     
    @@ -224,6 +224,15 @@ static struct _s_x rule_action_params[] = {
     	{ NULL, 0 }	/* terminator */
     };
     
    +/*
    + * The 'lookup' instruction accepts one of the following arguments.
    + * -1 is a terminator for the list.
    + * Arguments are passed as v[1] in O_DST_LOOKUP options.
    + */
    +static int lookup_key[] = {
    +	TOK_DSTIP, TOK_SRCIP, TOK_DSTPORT, TOK_SRCPORT,
    +	TOK_UID, TOK_JAIL, TOK_DSCP, -1 };
    +
     static struct _s_x rule_options[] = {
     	{ "tagged",		TOK_TAGGED },
     	{ "uid",		TOK_UID },
    @@ -249,6 +258,7 @@ static struct _s_x rule_options[] = {
     	{ "iplen",		TOK_IPLEN },
     	{ "ipid",		TOK_IPID },
     	{ "ipprecedence",	TOK_IPPRECEDENCE },
    +	{ "dscp",		TOK_DSCP },
     	{ "iptos",		TOK_IPTOS },
     	{ "ipttl",		TOK_IPTTL },
     	{ "ipversion",		TOK_IPVER },
    @@ -290,6 +300,7 @@ static struct _s_x rule_options[] = {
     	{ "dst-ip6",		TOK_DSTIP6},
     	{ "src-ipv6",		TOK_SRCIP6},
     	{ "src-ip6",		TOK_SRCIP6},
    +	{ "lookup",		TOK_LOOKUP},
     	{ "//",			TOK_COMMENT },
     
     	{ "not",		TOK_NOT },		/* pseudo option */
    @@ -343,6 +354,7 @@ safe_realloc(void *ptr, size_t size)
     
     /*
      * conditionally runs the command.
    + * Selected options or negative -> getsockopt
      */
     int
     do_cmd(int optname, void *optval, uintptr_t optlen)
    @@ -362,11 +374,15 @@ do_cmd(int optname, void *optval, uintptr_t optlen)
     	    optname == IP_FW_ADD || optname == IP_FW_TABLE_LIST ||
     	    optname == IP_FW_TABLE_GETSIZE || 
     	    optname == IP_FW_NAT_GET_CONFIG || 
    -	    optname == IP_FW_NAT_GET_LOG)
    +	    optname < 0 ||
    +	    optname == IP_FW_NAT_GET_LOG) {
    +		if (optname < 0)
    +			optname = -optname;
     		i = getsockopt(s, IPPROTO_IP, optname, optval,
     			(socklen_t *)optlen);
    -	else
    +	} else {
     		i = setsockopt(s, IPPROTO_IP, optname, optval, optlen);
    +	}
     	return i;
     }
     
    @@ -739,9 +755,19 @@ static void
     print_ip(ipfw_insn_ip *cmd, char const *s)
     {
     	struct hostent *he = NULL;
    -	int len = F_LEN((ipfw_insn *)cmd);
    +	uint32_t len = F_LEN((ipfw_insn *)cmd);
     	uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
     
    +	if (cmd->o.opcode == O_IP_DST_LOOKUP && len > F_INSN_SIZE(ipfw_insn_u32)) {
    +		uint32_t d = a[1];
    +		const char *arg = "";
    +
    +		if (d < sizeof(lookup_key)/sizeof(lookup_key[0]))
    +			arg = match_value(rule_options, lookup_key[d]);
    +		printf("%s lookup %s %d", cmd->o.len & F_NOT ? " not": "",
    +			arg, cmd->o.arg1);
    +		return;
    +	}
     	printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s);
     
     	if (cmd->o.opcode == O_IP_SRC_ME || cmd->o.opcode == O_IP_DST_ME) {
    @@ -1108,9 +1134,11 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
     		else
     			printf(" log");
     	}
    +#ifndef NO_ALTQ
     	if (altqptr) {
     		print_altq_cmd(altqptr);
     	}
    +#endif
     	if (tagptr) {
     		if (tagptr->len & F_NOT)
     			PRINT_UINT_ARG(" untag ", tagptr->arg1);
    @@ -1595,26 +1623,33 @@ show_dyn_ipfw(ipfw_dyn_rule *d, int pcwidth, int bcwidth)
      * 	ipfw set move rule X to Y
      */
     void
    -ipfw_sets_handler(int ac, char *av[])
    +ipfw_sets_handler(char *av[])
     {
     	uint32_t set_disable, masks[2];
     	int i, nbytes;
     	uint16_t rulenum;
     	uint8_t cmd, new_set;
     
    -	ac--;
     	av++;
     
    -	if (!ac)
    +	if (av[0] == NULL)
     		errx(EX_USAGE, "set needs command");
     	if (_substrcmp(*av, "show") == 0) {
    -		void *data;
    +		void *data = NULL;
     		char const *msg;
    +		int nalloc;
     
    -		nbytes = sizeof(struct ip_fw);
    +		nalloc = nbytes = sizeof(struct ip_fw);
    +		while (nbytes >= nalloc) {
    +			if (data)
    +				free(data);
    +			nalloc = nalloc * 2 + 200;
    +			nbytes = nalloc;
     		data = safe_calloc(1, nbytes);
     		if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0)
     			err(EX_OSERR, "getsockopt(IP_FW_GET)");
    +		}
    +
     		bcopy(&((struct ip_fw *)data)->next_rule,
     			&set_disable, sizeof(set_disable));
     
    @@ -1631,8 +1666,8 @@ ipfw_sets_handler(int ac, char *av[])
     			}
     		printf("\n");
     	} else if (_substrcmp(*av, "swap") == 0) {
    -		ac--; av++;
    -		if (ac != 2)
    +		av++;
    +		if ( av[0] == NULL || av[1] == NULL )
     			errx(EX_USAGE, "set swap needs 2 set numbers\n");
     		rulenum = atoi(av[0]);
     		new_set = atoi(av[1]);
    @@ -1643,13 +1678,14 @@ ipfw_sets_handler(int ac, char *av[])
     		masks[0] = (4 << 24) | (new_set << 16) | (rulenum);
     		i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t));
     	} else if (_substrcmp(*av, "move") == 0) {
    -		ac--; av++;
    -		if (ac && _substrcmp(*av, "rule") == 0) {
    +		av++;
    +		if (av[0] && _substrcmp(*av, "rule") == 0) {
     			cmd = 2;
    -			ac--; av++;
    +			av++;
     		} else
     			cmd = 3;
    -		if (ac != 3 || _substrcmp(av[1], "to") != 0)
    +		if (av[0] == NULL || av[1] == NULL || av[2] == NULL ||
    +				av[3] != NULL ||  _substrcmp(av[1], "to") != 0)
     			errx(EX_USAGE, "syntax: set move [rule] X to Y\n");
     		rulenum = atoi(av[0]);
     		new_set = atoi(av[2]);
    @@ -1664,10 +1700,10 @@ ipfw_sets_handler(int ac, char *av[])
     		   _substrcmp(*av, "enable") == 0 ) {
     		int which = _substrcmp(*av, "enable") == 0 ? 1 : 0;
     
    -		ac--; av++;
    +		av++;
     		masks[0] = masks[1] = 0;
     
    -		while (ac) {
    +		while (av[0]) {
     			if (isdigit(**av)) {
     				i = atoi(*av);
     				if (i < 0 || i > RESVD_SET)
    @@ -1681,7 +1717,7 @@ ipfw_sets_handler(int ac, char *av[])
     			else
     				errx(EX_DATAERR,
     					"invalid set command %s\n", *av);
    -			av++; ac--;
    +			av++;
     		}
     		if ( (masks[0] & masks[1]) != 0 )
     			errx(EX_DATAERR,
    @@ -1695,12 +1731,11 @@ ipfw_sets_handler(int ac, char *av[])
     }
     
     void
    -ipfw_sysctl_handler(int ac, char *av[], int which)
    +ipfw_sysctl_handler(char *av[], int which)
     {
    -	ac--;
     	av++;
     
    -	if (ac == 0) {
    +	if (av[0] == NULL) {
     		warnx("missing keyword to enable/disable\n");
     	} else if (_substrcmp(*av, "firewall") == 0) {
     		sysctlbyname("net.inet.ip.fw.enable", NULL, 0,
    @@ -1717,8 +1752,10 @@ ipfw_sysctl_handler(int ac, char *av[], int which)
     	} else if (_substrcmp(*av, "dyn_keepalive") == 0) {
     		sysctlbyname("net.inet.ip.fw.dyn_keepalive", NULL, 0,
     		    &which, sizeof(which));
    +#ifndef NO_ALTQ
     	} else if (_substrcmp(*av, "altq") == 0) {
     		altq_set_enabled(which);
    +#endif
     	} else {
     		warnx("unrecognize enable/disable keyword: %s\n", *av);
     	}
    @@ -1751,6 +1788,10 @@ ipfw_list(int ac, char *av[], int show_counters)
     		fprintf(stderr, "Testing only, list disabled\n");
     		return;
     	}
    +	if (co.do_pipe) {
    +		dummynet_list(ac, av, show_counters);
    +		return;
    +	}
     
     	ac--;
     	av++;
    @@ -1767,11 +1808,6 @@ ipfw_list(int ac, char *av[], int show_counters)
     				co.do_pipe ? "DUMMYNET" : "FW");
     	}
     
    -	if (co.do_pipe) {
    -		ipfw_list_pipes(data, nbytes, ac, av);
    -		goto done;
    -	}
    -
     	/*
     	 * Count static rules. They have variable size so we
     	 * need to scan the list to count them.
    @@ -2119,7 +2155,7 @@ fill_ip(ipfw_insn_ip *cmd, char *av)
     		return;
     	}
     	/* A single IP can be stored in an optimized format */
    -	if (d[1] == ~0 && av == NULL && len == 0) {
    +	if (d[1] == (uint32_t)~0 && av == NULL && len == 0) {
     		cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32);
     		return;
     	}
    @@ -2188,29 +2224,28 @@ fill_flags(ipfw_insn *cmd, enum ipfw_opcodes opcode,
     
     
     void
    -ipfw_delete(int ac, char *av[])
    +ipfw_delete(char *av[])
     {
     	uint32_t rulenum;
     	int i;
     	int exitval = EX_OK;
     	int do_set = 0;
     
    -
    -	av++; ac--;
    +	av++;
     	NEED1("missing rule specification");
    -	if (ac > 0 && _substrcmp(*av, "set") == 0) {
    +	if ( *av && _substrcmp(*av, "set") == 0) {
     		/* Do not allow using the following syntax:
     		 *	ipfw set N delete set M
     		 */
     		if (co.use_set)
     			errx(EX_DATAERR, "invalid syntax");
     		do_set = 1;	/* delete set */
    -		ac--; av++;
    +		av++;
     	}
     
     	/* Rule number */
    -	while (ac && isdigit(**av)) {
    -		i = atoi(*av); av++; ac--;
    +	while (*av && isdigit(**av)) {
    +		i = atoi(*av); av++;
     		if (co.do_nat) {
     			exitval = do_cmd(IP_FW_NAT_DEL, &i, sizeof i);
     			if (exitval) {
    @@ -2264,7 +2299,8 @@ fill_iface(ipfw_insn_if *cmd, char *arg)
     static void
     get_mac_addr_mask(const char *p, uint8_t *addr, uint8_t *mask)
     {
    -	int i, l;
    +	int i;
    +	size_t l;
     	char *ap, *ptr, *optr;
     	struct ether_addr *mac;
     	const char *macset = "0123456789abcdefABCDEF:";
    @@ -2286,11 +2322,11 @@ get_mac_addr_mask(const char *p, uint8_t *addr, uint8_t *mask)
     
     	if (ptr != NULL) { /* we have mask? */
     		if (p[ptr - optr - 1] == '/') { /* mask len */
    -			l = strtol(ptr, &ap, 10);
    -			if (*ap != 0 || l > ETHER_ADDR_LEN * 8 || l < 0)
    +			long ml = strtol(ptr, &ap, 10);
    +			if (*ap != 0 || ml > ETHER_ADDR_LEN * 8 || ml < 0)
     				errx(EX_DATAERR, "Incorrect mask length");
    -			for (i = 0; l > 0 && i < ETHER_ADDR_LEN; l -= 8, i++)
    -				mask[i] = (l >= 8) ? 0xff: (~0) << (8 - l);
    +			for (i = 0; ml > 0 && i < ETHER_ADDR_LEN; ml -= 8, i++)
    +				mask[i] = (ml >= 8) ? 0xff: (~0) << (8 - ml);
     		} else { /* mask */
     			l = strlen(ptr);
     			if (strspn(ptr, macset) != l ||
    @@ -2325,7 +2361,7 @@ next_cmd(ipfw_insn *cmd)
      * Takes arguments and copies them into a comment
      */
     static void
    -fill_comment(ipfw_insn *cmd, int ac, char **av)
    +fill_comment(ipfw_insn *cmd, char **av)
     {
     	int i, l;
     	char *p = (char *)(cmd + 1);
    @@ -2334,7 +2370,7 @@ fill_comment(ipfw_insn *cmd, int ac, char **av)
     	cmd->len =  (cmd->len & (F_NOT | F_OR));
     
     	/* Compute length of comment string. */
    -	for (i = 0, l = 0; i < ac; i++)
    +	for (i = 0, l = 0; av[i] != NULL; i++)
     		l += strlen(av[i]) + 1;
     	if (l == 0)
     		return;
    @@ -2343,7 +2379,7 @@ fill_comment(ipfw_insn *cmd, int ac, char **av)
     		    "comment too long (max 80 chars)");
     	l = 1 + (l+3)/4;
     	cmd->len =  (cmd->len & (F_NOT | F_OR)) | l;
    -	for (i = 0; i < ac; i++) {
    +	for (i = 0; av[i] != NULL; i++) {
     		strcpy(p, av[i]);
     		p += strlen(av[i]);
     		*p++ = ' ';
    @@ -2368,11 +2404,11 @@ fill_cmd(ipfw_insn *cmd, enum ipfw_opcodes opcode, int flags, uint16_t arg)
      * two microinstructions, and returns the pointer to the last one.
      */
     static ipfw_insn *
    -add_mac(ipfw_insn *cmd, int ac, char *av[])
    +add_mac(ipfw_insn *cmd, char *av[])
     {
     	ipfw_insn_mac *mac;
     
    -	if (ac < 2)
    +	if ( ( av[0] == NULL ) || ( av[1] == NULL ) )
     		errx(EX_DATAERR, "MAC dst src");
     
     	cmd->opcode = O_MACADDR2;
    @@ -2386,9 +2422,9 @@ add_mac(ipfw_insn *cmd, int ac, char *av[])
     }
     
     static ipfw_insn *
    -add_mactype(ipfw_insn *cmd, int ac, char *av)
    +add_mactype(ipfw_insn *cmd, char *av)
     {
    -	if (ac < 1)
    +	if (!av)
     		errx(EX_DATAERR, "missing MAC type");
     	if (strcmp(av, "any") != 0) { /* we have a non-null type */
     		fill_newports((ipfw_insn_u16 *)cmd, av, IPPROTO_ETHERTYPE);
    @@ -2496,6 +2532,7 @@ add_dstip(ipfw_insn *cmd, char *av)
     static ipfw_insn *
     add_ports(ipfw_insn *cmd, char *av, u_char proto, int opcode)
     {
    +	/* XXX "any" is trapped before. Perhaps "to" */
     	if (_substrcmp(av, "any") == 0) {
     		return NULL;
     	} else if (fill_newports((ipfw_insn_u16 *)cmd, av, proto)) {
    @@ -2519,11 +2556,11 @@ add_src(ipfw_insn *cmd, char *av, u_char proto)
     		*ch = '\0';
     
     	if (proto == IPPROTO_IPV6  || strcmp(av, "me6") == 0 ||
    -	    inet_pton(AF_INET6, host, &a))
    +	    inet_pton(AF_INET6, host, &a) == 1)
     		ret = add_srcip6(cmd, av);
     	/* XXX: should check for IPv4, not !IPv6 */
     	if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 ||
    -	    !inet_pton(AF_INET6, host, &a)))
    +	    inet_pton(AF_INET6, host, &a) != 1))
     		ret = add_srcip(cmd, av);
     	if (ret == NULL && strcmp(av, "any") != 0)
     		ret = cmd;
    @@ -2545,11 +2582,11 @@ add_dst(ipfw_insn *cmd, char *av, u_char proto)
     		*ch = '\0';
     
     	if (proto == IPPROTO_IPV6  || strcmp(av, "me6") == 0 ||
    -	    inet_pton(AF_INET6, host, &a))
    +	    inet_pton(AF_INET6, host, &a) == 1)
     		ret = add_dstip6(cmd, av);
     	/* XXX: should check for IPv4, not !IPv6 */
     	if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 ||
    -	    !inet_pton(AF_INET6, host, &a)))
    +	    inet_pton(AF_INET6, host, &a) != 1))
     		ret = add_dstip(cmd, av);
     	if (ret == NULL && strcmp(av, "any") != 0)
     		ret = cmd;
    @@ -2571,7 +2608,7 @@ add_dst(ipfw_insn *cmd, char *av, u_char proto)
      *
      */
     void
    -ipfw_add(int ac, char *av[])
    +ipfw_add(char *av[])
     {
     	/*
     	 * rules are added into the 'rulebuf' and then copied in
    @@ -2610,37 +2647,36 @@ ipfw_add(int ac, char *av[])
     	cmd = (ipfw_insn *)cmdbuf;
     	action = (ipfw_insn *)actbuf;
     
    -	av++; ac--;
    +	av++;
     
     	/* [rule N]	-- Rule number optional */
    -	if (ac && isdigit(**av)) {
    +	if (av[0] && isdigit(**av)) {
     		rule->rulenum = atoi(*av);
     		av++;
    -		ac--;
     	}
     
     	/* [set N]	-- set number (0..RESVD_SET), optional */
    -	if (ac > 1 && _substrcmp(*av, "set") == 0) {
    +	if (av[0] && !av[1] && _substrcmp(*av, "set") == 0) {
     		int set = strtoul(av[1], NULL, 10);
     		if (set < 0 || set > RESVD_SET)
     			errx(EX_DATAERR, "illegal set %s", av[1]);
     		rule->set = set;
    -		av += 2; ac -= 2;
    +		av += 2;
     	}
     
     	/* [prob D]	-- match probability, optional */
    -	if (ac > 1 && _substrcmp(*av, "prob") == 0) {
    +	if (av[0] && av[1] && _substrcmp(*av, "prob") == 0) {
     		match_prob = strtod(av[1], NULL);
     
     		if (match_prob <= 0 || match_prob > 1)
     			errx(EX_DATAERR, "illegal match prob. %s", av[1]);
    -		av += 2; ac -= 2;
    +		av += 2;
     	}
     
     	/* action	-- mandatory */
     	NEED1("missing action");
     	i = match_token(rule_actions, *av);
    -	ac--; av++;
    +	av++;
     	action->len = 1;	/* default */
     	switch(i) {
     	case TOK_CHECKSTATE:
    @@ -2676,14 +2712,14 @@ ipfw_add(int ac, char *av[])
     		action->opcode = O_REJECT;
     		NEED1("missing reject code");
     		fill_reject_code(&action->arg1, *av);
    -		ac--; av++;
    +		av++;
     		break;
     
     	case TOK_UNREACH6:
     		action->opcode = O_UNREACH6;
     		NEED1("missing unreach code");
     		fill_unreach6_code(&action->arg1, *av);
    -		ac--; av++;
    +		av++;
     		break;
     
     	case TOK_COUNT:
    @@ -2716,7 +2752,7 @@ ipfw_add(int ac, char *av[])
     	case TOK_TEE:
     		action->opcode = O_TEE;
     chkarg:	
    -		if (!ac)
    +		if (!av[0])
     			errx(EX_USAGE, "missing argument for %s", *(av - 1));
     		if (isdigit(**av)) {
     			action->arg1 = strtoul(*av, NULL, 10);
    @@ -2735,7 +2771,7 @@ chkarg:
     				errx(EX_DATAERR, "illegal divert/tee port");
     		} else
     			errx(EX_DATAERR, "illegal argument for %s", *(av - 1));
    -		ac--; av++;
    +		av++;
     		break;
     
     	case TOK_FORWARD: {
    @@ -2773,13 +2809,13 @@ chkarg:
     			p->sa.sin_addr.s_addr = INADDR_ANY;
     		else
     			lookup_host(*av, &(p->sa.sin_addr));
    -		ac--; av++;
    +		av++;
     		break;
     	    }
     	case TOK_COMMENT:
     		/* pretend it is a 'count' rule followed by the comment */
     		action->opcode = O_COUNT;
    -		ac++; av--;	/* go back... */
    +		av--;		/* go back... */
     		break;
     
     	case TOK_SETFIB:
    @@ -2794,7 +2830,7 @@ chkarg:
     			errx(EX_DATAERR, "fibs not suported.\n");
     		if (action->arg1 >= numfibs)  /* Temporary */
     			errx(EX_DATAERR, "fib too large.\n");
    - 		ac--; av++;
    + 		av++;
      		break;
     	    }
     
    @@ -2814,8 +2850,8 @@ chkarg:
     	 * If they exist, it go first in the cmdbuf, but then it is
     	 * skipped in the copy section to the end of the buffer.
     	 */
    -	while (ac != 0 && (i = match_token(rule_action_params, *av)) != -1) {
    -		ac--; av++;
    +	while (av[0] != NULL && (i = match_token(rule_action_params, *av)) != -1) {
    +		av++;
     		switch (i) {
     		case TOK_LOG:
     		    {
    @@ -2828,15 +2864,15 @@ chkarg:
     			have_log = (ipfw_insn *)c;
     			cmd->len = F_INSN_SIZE(ipfw_insn_log);
     			cmd->opcode = O_LOG;
    -			if (ac && _substrcmp(*av, "logamount") == 0) {
    -				ac--; av++;
    +			if (av[0] && _substrcmp(*av, "logamount") == 0) {
    +				av++;
     				NEED1("logamount requires argument");
     				l = atoi(*av);
     				if (l < 0)
     					errx(EX_DATAERR,
     					    "logamount must be positive");
     				c->max_log = l;
    -				ac--; av++;
    +				av++;
     			} else {
     				len = sizeof(c->max_log);
     				if (sysctlbyname("net.inet.ip.fw.verbose_limit",
    @@ -2847,6 +2883,7 @@ chkarg:
     		    }
     			break;
     
    +#ifndef NO_ALTQ
     		case TOK_ALTQ:
     		    {
     			ipfw_insn_altq *a = (ipfw_insn_altq *)cmd;
    @@ -2859,9 +2896,10 @@ chkarg:
     			cmd->len = F_INSN_SIZE(ipfw_insn_altq);
     			cmd->opcode = O_ALTQ;
     			a->qid = altq_name_to_qid(*av);
    -			ac--; av++;
    +			av++;
     		    }
     			break;
    +#endif
     
     		case TOK_TAG:
     		case TOK_UNTAG: {
    @@ -2874,7 +2912,7 @@ chkarg:
     			   rule_action_params);
     			have_tag = cmd;
     			fill_cmd(cmd, O_TAG, (i == TOK_TAG) ? 0: F_NOT, tag);
    -			ac--; av++;
    +			av++;
     			break;
     		}
     
    @@ -2888,13 +2926,13 @@ chkarg:
     		goto done;
     
     #define OR_START(target)					\
    -	if (ac && (*av[0] == '(' || *av[0] == '{')) {		\
    +	if (av[0] && (*av[0] == '(' || *av[0] == '{')) { 	\
     		if (open_par)					\
     			errx(EX_USAGE, "nested \"(\" not allowed\n"); \
     		prev = NULL;					\
     		open_par = 1;					\
     		if ( (av[0])[1] == '\0') {			\
    -			ac--; av++;				\
    +			av++;					\
     		} else						\
     			(*av)++;				\
     	}							\
    @@ -2903,30 +2941,30 @@ chkarg:
     
     #define	CLOSE_PAR						\
     	if (open_par) {						\
    -		if (ac && (					\
    +		if (av[0] && (					\
     		    strcmp(*av, ")") == 0 ||			\
     		    strcmp(*av, "}") == 0)) {			\
     			prev = NULL;				\
     			open_par = 0;				\
    -			ac--; av++;				\
    +			av++;					\
     		} else						\
     			errx(EX_USAGE, "missing \")\"\n");	\
     	}
     
     #define NOT_BLOCK						\
    -	if (ac && _substrcmp(*av, "not") == 0) {		\
    +	if (av[0] && _substrcmp(*av, "not") == 0) {		\
     		if (cmd->len & F_NOT)				\
     			errx(EX_USAGE, "double \"not\" not allowed\n"); \
     		cmd->len |= F_NOT;				\
    -		ac--; av++;					\
    +		av++;						\
     	}
     
     #define OR_BLOCK(target)					\
    -	if (ac && _substrcmp(*av, "or") == 0) {		\
    +	if (av[0] && _substrcmp(*av, "or") == 0) {		\
     		if (prev == NULL || open_par == 0)		\
     			errx(EX_DATAERR, "invalid OR block");	\
     		prev->len |= F_OR;				\
    -		ac--; av++;					\
    +		av++;					\
     		goto target;					\
     	}							\
     	CLOSE_PAR;
    @@ -2943,15 +2981,15 @@ chkarg:
     	NEED1("missing protocol");
     	if (_substrcmp(*av, "MAC") == 0 ||
     	    _substrcmp(*av, "mac") == 0) {
    -		ac--; av++;	/* the "MAC" keyword */
    -		add_mac(cmd, ac, av); /* exits in case of errors */
    +		av++;			/* the "MAC" keyword */
    +		add_mac(cmd, av);	/* exits in case of errors */
     		cmd = next_cmd(cmd);
    -		ac -= 2; av += 2;	/* dst-mac and src-mac */
    +		av += 2;		/* dst-mac and src-mac */
     		NOT_BLOCK;
     		NEED1("missing mac type");
    -		if (add_mactype(cmd, ac, av[0]))
    +		if (add_mactype(cmd, av[0]))
     			cmd = next_cmd(cmd);
    -		ac--; av++;	/* any or mac-type */
    +		av++;			/* any or mac-type */
     		goto read_options;
     	}
     #endif
    @@ -2963,7 +3001,7 @@ chkarg:
     	NOT_BLOCK;
     	NEED1("missing protocol");
     	if (add_proto_compat(cmd, *av, &proto)) {
    -		av++; ac--;
    +		av++;
     		if (F_LEN(cmd) != 0) {
     			prev = cmd;
     			cmd = next_cmd(cmd);
    @@ -2977,9 +3015,9 @@ chkarg:
     	/*
     	 * "from", mandatory
     	 */
    -	if (!ac || _substrcmp(*av, "from") != 0)
    +	if ((av[0] == NULL) || _substrcmp(*av, "from") != 0)
     		errx(EX_USAGE, "missing ``from''");
    -	ac--; av++;
    +	av++;
     
     	/*
     	 * source IP, mandatory
    @@ -2988,7 +3026,7 @@ chkarg:
     	NOT_BLOCK;	/* optional "not" */
     	NEED1("missing source address");
     	if (add_src(cmd, *av, proto)) {
    -		ac--; av++;
    +		av++;
     		if (F_LEN(cmd) != 0) {	/* ! any */
     			prev = cmd;
     			cmd = next_cmd(cmd);
    @@ -3001,10 +3039,10 @@ chkarg:
     	 * source ports, optional
     	 */
     	NOT_BLOCK;	/* optional "not" */
    -	if (ac) {
    +	if ( av[0] != NULL ) {
     		if (_substrcmp(*av, "any") == 0 ||
     		    add_ports(cmd, *av, proto, O_IP_SRCPORT)) {
    -			ac--; av++;
    +			av++;
     			if (F_LEN(cmd) != 0)
     				cmd = next_cmd(cmd);
     		}
    @@ -3013,9 +3051,9 @@ chkarg:
     	/*
     	 * "to", mandatory
     	 */
    -	if (!ac || _substrcmp(*av, "to") != 0)
    +	if ( (av[0] == NULL) || _substrcmp(*av, "to") != 0 )
     		errx(EX_USAGE, "missing ``to''");
    -	av++; ac--;
    +	av++;
     
     	/*
     	 * destination, mandatory
    @@ -3024,7 +3062,7 @@ chkarg:
     	NOT_BLOCK;	/* optional "not" */
     	NEED1("missing dst address");
     	if (add_dst(cmd, *av, proto)) {
    -		ac--; av++;
    +		av++;
     		if (F_LEN(cmd) != 0) {	/* ! any */
     			prev = cmd;
     			cmd = next_cmd(cmd);
    @@ -3037,17 +3075,17 @@ chkarg:
     	 * dest. ports, optional
     	 */
     	NOT_BLOCK;	/* optional "not" */
    -	if (ac) {
    +	if (av[0]) {
     		if (_substrcmp(*av, "any") == 0 ||
     		    add_ports(cmd, *av, proto, O_IP_DSTPORT)) {
    -			ac--; av++;
    +			av++;
     			if (F_LEN(cmd) != 0)
     				cmd = next_cmd(cmd);
     		}
     	}
     
     read_options:
    -	if (ac && first_cmd == cmd) {
    +	if (av[0] && first_cmd == cmd) {
     		/*
     		 * nothing specified so far, store in the rule to ease
     		 * printout later.
    @@ -3055,7 +3093,7 @@ read_options:
     		 rule->_pad = 1;
     	}
     	prev = NULL;
    -	while (ac) {
    +	while ( av[0] != NULL ) {
     		char *s;
     		ipfw_insn_u32 *cmd32;	/* alias for cmd */
     
    @@ -3069,7 +3107,7 @@ read_options:
     			s++;
     		}
     		i = match_token(rule_options, s);
    -		ac--; av++;
    +		av++;
     		switch(i) {
     		case TOK_NOT:
     			if (cmd->len & F_NOT)
    @@ -3131,7 +3169,7 @@ read_options:
     			NEED1("recv, xmit, via require interface name"
     				" or address");
     			fill_iface((ipfw_insn_if *)cmd, av[0]);
    -			ac--; av++;
    +			av++;
     			if (F_LEN(cmd) == 0)	/* not a valid address */
     				break;
     			if (i == TOK_XMIT)
    @@ -3145,13 +3183,13 @@ read_options:
     		case TOK_ICMPTYPES:
     			NEED1("icmptypes requires list of types");
     			fill_icmptypes((ipfw_insn_u32 *)cmd, *av);
    -			av++; ac--;
    +			av++;
     			break;
     		
     		case TOK_ICMP6TYPES:
     			NEED1("icmptypes requires list of types");
     			fill_icmp6types((ipfw_insn_icmp6 *)cmd, *av);
    -			av++; ac--;
    +			av++;
     			break;
     
     		case TOK_IPTTL:
    @@ -3161,7 +3199,7 @@ read_options:
     				errx(EX_DATAERR, "invalid ipttl %s", *av);
     			} else
     			    fill_cmd(cmd, O_IPTTL, 0, strtoul(*av, NULL, 0));
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_IPID:
    @@ -3171,7 +3209,7 @@ read_options:
     				errx(EX_DATAERR, "invalid ipid %s", *av);
     			} else
     			    fill_cmd(cmd, O_IPID, 0, strtoul(*av, NULL, 0));
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_IPLEN:
    @@ -3181,32 +3219,32 @@ read_options:
     				errx(EX_DATAERR, "invalid ip len %s", *av);
     			} else
     			    fill_cmd(cmd, O_IPLEN, 0, strtoul(*av, NULL, 0));
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_IPVER:
     			NEED1("ipver requires version");
     			fill_cmd(cmd, O_IPVER, 0, strtoul(*av, NULL, 0));
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_IPPRECEDENCE:
     			NEED1("ipprecedence requires value");
     			fill_cmd(cmd, O_IPPRECEDENCE, 0,
     			    (strtoul(*av, NULL, 0) & 7) << 5);
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_IPOPTS:
     			NEED1("missing argument for ipoptions");
     			fill_flags(cmd, O_IPOPT, f_ipopts, *av);
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_IPTOS:
     			NEED1("missing argument for iptos");
     			fill_flags(cmd, O_IPTOS, f_iptos, *av);
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_UID:
    @@ -3223,7 +3261,7 @@ read_options:
     				errx(EX_DATAERR, "uid \"%s\" nonexistent", *av);
     			cmd32->d[0] = pwd->pw_uid;
     			cmd->len |= F_INSN_SIZE(ipfw_insn_u32);
    -			ac--; av++;
    +			av++;
     		    }
     			break;
     
    @@ -3241,7 +3279,7 @@ read_options:
     				errx(EX_DATAERR, "gid \"%s\" nonexistent", *av);
     			cmd32->d[0] = grp->gr_gid;
     			cmd->len |= F_INSN_SIZE(ipfw_insn_u32);
    -			ac--; av++;
    +			av++;
     		    }
     			break;
     
    @@ -3257,7 +3295,7 @@ read_options:
     				errx(EX_DATAERR, "jail requires prison ID");
     			cmd32->d[0] = (uint32_t)jid;
     			cmd->len |= F_INSN_SIZE(ipfw_insn_u32);
    -			ac--; av++;
    +			av++;
     		    }
     			break;
     
    @@ -3278,13 +3316,13 @@ read_options:
     			} else
     			    fill_cmd(cmd, O_TCPDATALEN, 0,
     				    strtoul(*av, NULL, 0));
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_TCPOPTS:
     			NEED1("missing argument for tcpoptions");
     			fill_flags(cmd, O_TCPOPTS, f_tcpopts, *av);
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_TCPSEQ:
    @@ -3293,21 +3331,21 @@ read_options:
     			cmd->len = F_INSN_SIZE(ipfw_insn_u32);
     			cmd->opcode = (i == TOK_TCPSEQ) ? O_TCPSEQ : O_TCPACK;
     			cmd32->d[0] = htonl(strtoul(*av, NULL, 0));
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_TCPWIN:
     			NEED1("tcpwin requires length");
     			fill_cmd(cmd, O_TCPWIN, 0,
     			    htons(strtoul(*av, NULL, 0)));
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_TCPFLAGS:
     			NEED1("missing argument for tcpflags");
     			cmd->opcode = O_TCPFLAGS;
     			fill_flags(cmd, O_TCPFLAGS, f_tcpflags, *av);
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_KEEPSTATE:
    @@ -3337,11 +3375,11 @@ read_options:
     			cmd->opcode = O_LIMIT;
     			c->limit_mask = c->conn_limit = 0;
     
    -			while (ac > 0) {
    +			while ( av[0] != NULL ) {
     				if ((val = match_token(limit_masks, *av)) <= 0)
     					break;
     				c->limit_mask |= val;
    -				ac--; av++;
    +				av++;
     			}
     
     			if (c->limit_mask == 0)
    @@ -3350,14 +3388,14 @@ read_options:
     			GET_UINT_ARG(c->conn_limit, IPFW_ARG_MIN, IPFW_ARG_MAX,
     			    TOK_LIMIT, rule_options);
     
    -			ac--; av++;
    +			av++;
     			break;
     		}
     
     		case TOK_PROTO:
     			NEED1("missing protocol");
     			if (add_proto(cmd, *av, &proto)) {
    -				ac--; av++;
    +				av++;
     			} else
     				errx(EX_DATAERR, "invalid protocol ``%s''",
     				    *av);
    @@ -3366,28 +3404,28 @@ read_options:
     		case TOK_SRCIP:
     			NEED1("missing source IP");
     			if (add_srcip(cmd, *av)) {
    -				ac--; av++;
    +				av++;
     			}
     			break;
     
     		case TOK_DSTIP:
     			NEED1("missing destination IP");
     			if (add_dstip(cmd, *av)) {
    -				ac--; av++;
    +				av++;
     			}
     			break;
     
     		case TOK_SRCIP6:
     			NEED1("missing source IP6");
     			if (add_srcip6(cmd, *av)) {
    -				ac--; av++;
    +				av++;
     			}
     			break;
     				
     		case TOK_DSTIP6:
     			NEED1("missing destination IP6");
     			if (add_dstip6(cmd, *av)) {
    -				ac--; av++;
    +				av++;
     			}
     			break;
     
    @@ -3395,7 +3433,7 @@ read_options:
     			NEED1("missing source port");
     			if (_substrcmp(*av, "any") == 0 ||
     			    add_ports(cmd, *av, proto, O_IP_SRCPORT)) {
    -				ac--; av++;
    +				av++;
     			} else
     				errx(EX_DATAERR, "invalid source port %s", *av);
     			break;
    @@ -3404,23 +3442,22 @@ read_options:
     			NEED1("missing destination port");
     			if (_substrcmp(*av, "any") == 0 ||
     			    add_ports(cmd, *av, proto, O_IP_DSTPORT)) {
    -				ac--; av++;
    +				av++;
     			} else
     				errx(EX_DATAERR, "invalid destination port %s",
     				    *av);
     			break;
     
     		case TOK_MAC:
    -			if (add_mac(cmd, ac, av)) {
    -				ac -= 2; av += 2;
    -			}
    +			if (add_mac(cmd, av))
    +				av += 2;
     			break;
     
     		case TOK_MACTYPE:
     			NEED1("missing mac type");
    -			if (!add_mactype(cmd, ac, *av))
    +			if (!add_mactype(cmd, *av))
     				errx(EX_DATAERR, "invalid mac type %s", *av);
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_VERREVPATH:
    @@ -3449,7 +3486,7 @@ read_options:
     
     		case TOK_EXT6HDR:
     			fill_ext6hdr( cmd, *av );
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_FLOWID:
    @@ -3457,17 +3494,16 @@ read_options:
     				errx( EX_USAGE, "flow-id filter is active "
     				    "only for ipv6 protocol\n");
     			fill_flow6( (ipfw_insn_u32 *) cmd, *av );
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_COMMENT:
    -			fill_comment(cmd, ac, av);
    -			av += ac;
    -			ac = 0;
    +			fill_comment(cmd, av);
    +			av[0]=NULL;
     			break;
     
     		case TOK_TAGGED:
    -			if (ac > 0 && strpbrk(*av, "-,")) {
    +			if (av[0] && strpbrk(*av, "-,")) {
     				if (!add_ports(cmd, *av, 0, O_TAGGED))
     					errx(EX_DATAERR, "tagged: invalid tag"
     					    " list: %s", *av);
    @@ -3479,13 +3515,38 @@ read_options:
     				    TOK_TAGGED, rule_options);
     				fill_cmd(cmd, O_TAGGED, 0, tag);
     			}
    -			ac--; av++;
    +			av++;
     			break;
     
     		case TOK_FIB:
     			NEED1("fib requires fib number");
     			fill_cmd(cmd, O_FIB, 0, strtoul(*av, NULL, 0));
    -			ac--; av++;
    +			av++;
    +			break;
    +
    +		case TOK_LOOKUP: {
    +			ipfw_insn_u32 *c = (ipfw_insn_u32 *)cmd;
    +			char *p;
    +			int j;
    +
    +			if (!av[0] || !av[1])
    +				errx(EX_USAGE, "format: lookup argument tablenum");
    +			cmd->opcode = O_IP_DST_LOOKUP;
    +			cmd->len |= F_INSN_SIZE(ipfw_insn) + 2;
    +			i = match_token(rule_options, *av);
    +			for (j = 0; lookup_key[j] >= 0 ; j++) {
    +				if (i == lookup_key[j])
    +					break;
    +			}
    +			if (lookup_key[j] <= 0)
    +				errx(EX_USAGE, "format: cannot lookup on %s", *av);
    +			c->d[1] = j; // i converted to option
    +			av++;
    +			cmd->arg1 = strtoul(*av, &p, 0);
    +			if (p && *p)
    +				errx(EX_USAGE, "format: lookup argument tablenum");
    +			av++;
    +		    }
     			break;
     
     		default:
    @@ -3662,6 +3723,10 @@ ipfw_flush(int force)
     		if (c == 'N')	/* user said no */
     			return;
     	}
    +	if (co.do_pipe) {
    +		dummynet_flush();
    +		return;
    +	}
     	/* `ipfw set N flush` - is the same that `ipfw delete set N` */
     	if (co.use_set) {
     		uint32_t arg = ((co.use_set - 1) & 0xffff) | (1 << 24);
    @@ -3775,14 +3840,14 @@ ipfw_table_handler(int ac, char *av[])
     			}
     		}
     	} else if (_substrcmp(*av, "flush") == 0) {
    -		a = is_all ? tables_max : (ent.tbl + 1);
    +		a = is_all ? tables_max : (uint32_t)(ent.tbl + 1);
     		do {
     			if (do_cmd(IP_FW_TABLE_FLUSH, &ent.tbl,
     			    sizeof(ent.tbl)) < 0)
     				err(EX_OSERR, "setsockopt(IP_FW_TABLE_FLUSH)");
     		} while (++ent.tbl < a);
     	} else if (_substrcmp(*av, "list") == 0) {
    -		a = is_all ? tables_max : (ent.tbl + 1);
    +		a = is_all ? tables_max : (uint32_t)(ent.tbl + 1);
     		do {
     			table_list(ent, is_all);
     		} while (++ent.tbl < a);
    diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
    index d3ce7fb6e08..d1729841e97 100644
    --- a/sbin/ipfw/ipfw2.h
    +++ b/sbin/ipfw/ipfw2.h
    @@ -35,7 +35,7 @@ struct cmdline_opts {
     	int	do_resolv;	/* try to resolve all ip to names */
     	int	do_time;	/* Show time stamps */
     	int	do_quiet;	/* Be quiet in add and flush */
    -	int	do_pipe;	/* this cmd refers to a pipe */
    +	int	do_pipe;	/* this cmd refers to a pipe/queue/sched */
     	int	do_nat; 	/* this cmd refers to a nat config */
     	int	do_dynamic;	/* display dynamic rules */
     	int	do_expired;	/* display expired dynamic rules */
    @@ -82,7 +82,10 @@ enum tokens {
     	TOK_ACCEPT,
     	TOK_COUNT,
     	TOK_PIPE,
    +	TOK_LINK,
     	TOK_QUEUE,
    +	TOK_FLOWSET,
    +	TOK_SCHED,
     	TOK_DIVERT,
     	TOK_TEE,
     	TOK_NETGRAPH,
    @@ -122,6 +125,7 @@ enum tokens {
     	TOK_IPLEN,
     	TOK_IPID,
     	TOK_IPPRECEDENCE,
    +	TOK_DSCP,
     	TOK_IPTOS,
     	TOK_IPTTL,
     	TOK_IPVER,
    @@ -151,15 +155,23 @@ enum tokens {
     	TOK_SRCPORT,
     	TOK_ALL,
     	TOK_MASK,
    +	TOK_FLOW_MASK,
    +	TOK_SCHED_MASK,
     	TOK_BW,
     	TOK_DELAY,
    -	TOK_PIPE_PROFILE,
    +	TOK_PROFILE,
     	TOK_BURST,
     	TOK_RED,
     	TOK_GRED,
     	TOK_DROPTAIL,
     	TOK_PROTO,
    +	/* dummynet tokens */
     	TOK_WEIGHT,
    +	TOK_LMAX,
    +	TOK_PRI,
    +	TOK_TYPE,
    +	TOK_SLOTSIZE,
    +
     	TOK_IP,
     	TOK_IF,
      	TOK_ALOG,
    @@ -186,12 +198,14 @@ enum tokens {
     
     	TOK_FIB,
     	TOK_SETFIB,
    +	TOK_LOOKUP,
     };
     /*
      * the following macro returns an error message if we run out of
      * arguments.
      */
    -#define NEED1(msg)      {if (!ac) errx(EX_USAGE, msg);}
    +#define NEED(_p, msg)      {if (!_p) errx(EX_USAGE, msg);}
    +#define NEED1(msg)      {if (!(*av)) errx(EX_USAGE, msg);}
     
     unsigned long long align_uint64(const uint64_t *pll);
     
    @@ -235,14 +249,14 @@ struct _ipfw_insn_icmp6;
     extern int resvd_set_number;
     
     /* first-level command handlers */
    -void ipfw_add(int ac, char *av[]);
    +void ipfw_add(char *av[]);
     void ipfw_show_nat(int ac, char **av);
     void ipfw_config_pipe(int ac, char **av);
     void ipfw_config_nat(int ac, char **av);
    -void ipfw_sets_handler(int ac, char *av[]);
    +void ipfw_sets_handler(char *av[]);
     void ipfw_table_handler(int ac, char *av[]);
    -void ipfw_sysctl_handler(int ac, char *av[], int which);
    -void ipfw_delete(int ac, char *av[]);
    +void ipfw_sysctl_handler(char *av[], int which);
    +void ipfw_delete(char *av[]);
     void ipfw_flush(int force);
     void ipfw_zero(int ac, char *av[], int optname);
     void ipfw_list(int ac, char *av[], int show_counters);
    @@ -254,7 +268,8 @@ u_int32_t altq_name_to_qid(const char *name);
     void print_altq_cmd(struct _ipfw_insn_altq *altqptr);
     
     /* dummynet.c */
    -void ipfw_list_pipes(void *data, uint nbytes, int ac, char *av[]);
    +void dummynet_list(int ac, char *av[], int show_counters);
    +void dummynet_flush(void);
     int ipfw_delete_pipe(int pipe_or_queue, int n);
     
     /* ipv6.c */
    diff --git a/sbin/ipfw/main.c b/sbin/ipfw/main.c
    index 39160578a6d..cd39cf13bfd 100644
    --- a/sbin/ipfw/main.c
    +++ b/sbin/ipfw/main.c
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2002-2003 Luigi Rizzo
    + * Copyright (c) 2002-2003,2010 Luigi Rizzo
      * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
      * Copyright (c) 1994 Ugen J.S.Antsilevich
      *
    @@ -79,32 +79,28 @@ help(void)
     	exit(0);
     }
     
    -/*
    - * Free a the (locally allocated) copy of command line arguments.
    - */
    -static void
    -free_args(int ac, char **av)
    -{
    -	int i;
    -
    -	for (i=0; i < ac; i++)
    -		free(av[i]);
    -	free(av);
    -}
    -
     /*
      * Called with the arguments, including program name because getopt
      * wants it to be present.
      * Returns 0 if successful, 1 if empty command, errx() in case of errors.
    + * First thing we do is process parameters creating an argv[] array
    + * which includes the program name and a NULL entry at the end.
    + * If we are called with a single string, we split it on whitespace.
    + * Also, arguments with a trailing ',' are joined to the next one.
    + * The pointers (av[]) and data are in a a single chunk of memory.
    + * av[0] points to the original program name, all other entries
    + * point into the allocated chunk.
      */
     static int
     ipfw_main(int oldac, char **oldav)
     {
    -	int ch, ac, save_ac;
    +	int ch, ac;
     	const char *errstr;
     	char **av, **save_av;
     	int do_acct = 0;		/* Show packet/byte count */
     	int try_next = 0;		/* set if pipe cmd not found */
    +	int av_size;			/* compute the av size */
    +	char *av_p;			/* used to build the av list */
     
     #define WHITESP		" \t\f\v\n\r"
     	if (oldac < 2)
    @@ -112,10 +108,9 @@ ipfw_main(int oldac, char **oldav)
     
     	if (oldac == 2) {
     		/*
    -		 * If we are called with a single string, try to split it into
    -		 * arguments for subsequent parsing.
    -		 * But first, remove spaces after a ',', by copying the string
    -		 * in-place.
    +		 * If we are called with one argument, try to split it into
    +		 * words for subsequent parsing. Spaces after a ',' are
    +		 * removed by copying the string in-place.
     		 */
     		char *arg = oldav[1];	/* The string is the first arg. */
     		int l = strlen(arg);
    @@ -150,31 +145,59 @@ ipfw_main(int oldac, char **oldav)
     				ac++;
     
     		/*
    -		 * Allocate the argument list, including one entry for
    -		 * the program name because getopt expects it.
    +		 * Allocate the argument list structure as a single block
    +		 * of memory, containing pointers and the argument
    +		 * strings. We include one entry for the program name
    +		 * because getopt expects it, and a NULL at the end
    +		 * to simplify further parsing.
     		 */
    -		av = safe_calloc(ac + 1, sizeof(char *));
    +		ac++;		/* add 1 for the program name */
    +		av_size = (ac+1) * sizeof(char *) + l + 1;
    +		av = safe_calloc(av_size, 1);
     
     		/*
    -		 * Second, copy arguments from arg[] to av[]. For each one,
    +		 * Init the argument pointer to the end of the array
    +		 * and copy arguments from arg[] to av[]. For each one,
     		 * j is the initial character, i is the one past the end.
     		 */
    -		for (ac = 1, i = j = 0; i < l; i++)
    +		av_p = (char *)&av[ac+1];
    +		for (ac = 1, i = j = 0; i < l; i++) {
     			if (index(WHITESP, arg[i]) != NULL || i == l-1) {
     				if (i == l-1)
     					i++;
    -				av[ac] = safe_calloc(i-j+1, 1);
    -				bcopy(arg+j, av[ac], i-j);
    +				bcopy(arg+j, av_p, i-j);
    +				av[ac] = av_p;
    +				av_p += i-j;	/* the lenght of the string */
    +				*av_p++ = '\0';
     				ac++;
     				j = i + 1;
     			}
    +		}
     	} else {
     		/*
     		 * If an argument ends with ',' join with the next one.
     		 */
    -		int first, i, l;
    +		int first, i, l=0;
     
    -		av = safe_calloc(oldac, sizeof(char *));
    +		/*
    +		 * Allocate the argument list structure as a single block
    +		 * of memory, containing both pointers and the argument
    +		 * strings. We include some space for the program name
    +		 * because getopt expects it.
    +		 * We add an extra pointer to the end of the array,
    +		 * to make simpler further parsing.
    +		 */
    +		for (i=0; i= 2 && !strcmp(av[1], "sysctl")) {
    +		char *s;
    +		int i;
    +
    +		if (ac != 3) {
    +			printf(	"sysctl emulation usage:\n"
    +				"	ipfw sysctl name[=value]\n"
    +				"	ipfw sysctl -a\n");
    +			return 0;
    +		}
    +		s = index(av[2], '=');
    +		if (s == NULL) {
    +			s = !strcmp(av[2], "-a") ? NULL : av[2];
    +			sysctlbyname(s, NULL, NULL, NULL, 0);
    +		} else {	/* ipfw sysctl x.y.z=value */
    +			/* assume an INT value, will extend later */
    +			if (s[1] == '\0') {
    +				printf("ipfw sysctl: missing value\n\n");
    +				return 0;
    +			}
    +			*s = '\0';
    +			i = strtol(s+1, NULL, 0);
    +			sysctlbyname(av[2], NULL, NULL, &i, sizeof(int));
    +		}
    +		return 0;
    +	}
    +#endif
    +
     	/* Save arguments for final freeing of memory. */
    -	save_ac = ac;
     	save_av = av;
     
     	optind = optreset = 1;	/* restart getopt() */
    @@ -232,7 +290,7 @@ ipfw_main(int oldac, char **oldav)
     			break;
     
     		case 'h': /* help */
    -			free_args(save_ac, save_av);
    +			free(save_av);
     			help();
     			break;	/* NOTREACHED */
     
    @@ -273,7 +331,7 @@ ipfw_main(int oldac, char **oldav)
     			break;
     
     		default:
    -			free_args(save_ac, save_av);
    +			free(save_av);
     			return 1;
     		}
     
    @@ -304,6 +362,10 @@ ipfw_main(int oldac, char **oldav)
     		co.do_pipe = 1;
     	else if (_substrcmp(*av, "queue") == 0)
     		co.do_pipe = 2;
    +	else if (_substrcmp(*av, "flowset") == 0)
    +		co.do_pipe = 2;
    +	else if (_substrcmp(*av, "sched") == 0)
    +		co.do_pipe = 3;
     	else if (!strncmp(*av, "set", strlen(*av))) {
     		if (ac > 1 && isdigit(av[1][0])) {
     			co.use_set = strtonum(av[1], 0, resvd_set_number,
    @@ -335,7 +397,7 @@ ipfw_main(int oldac, char **oldav)
     
     	if (co.use_set == 0) {
     		if (_substrcmp(*av, "add") == 0)
    -			ipfw_add(ac, av);
    +			ipfw_add(av);
     		else if (co.do_nat && _substrcmp(*av, "show") == 0)
      			ipfw_show_nat(ac, av);
     		else if (co.do_pipe && _substrcmp(*av, "config") == 0)
    @@ -343,20 +405,20 @@ ipfw_main(int oldac, char **oldav)
     		else if (co.do_nat && _substrcmp(*av, "config") == 0)
      			ipfw_config_nat(ac, av);
     		else if (_substrcmp(*av, "set") == 0)
    -			ipfw_sets_handler(ac, av);
    +			ipfw_sets_handler(av);
     		else if (_substrcmp(*av, "table") == 0)
     			ipfw_table_handler(ac, av);
     		else if (_substrcmp(*av, "enable") == 0)
    -			ipfw_sysctl_handler(ac, av, 1);
    +			ipfw_sysctl_handler(av, 1);
     		else if (_substrcmp(*av, "disable") == 0)
    -			ipfw_sysctl_handler(ac, av, 0);
    +			ipfw_sysctl_handler(av, 0);
     		else
     			try_next = 1;
     	}
     
     	if (co.use_set || try_next) {
     		if (_substrcmp(*av, "delete") == 0)
    -			ipfw_delete(ac, av);
    +			ipfw_delete(av);
     		else if (_substrcmp(*av, "flush") == 0)
     			ipfw_flush(co.do_force);
     		else if (_substrcmp(*av, "zero") == 0)
    @@ -373,7 +435,7 @@ ipfw_main(int oldac, char **oldav)
     	}
     
     	/* Free memory allocated in the argument parsing. */
    -	free_args(save_ac, save_av);
    +	free(save_av);
     	return 0;
     }
     
    @@ -521,6 +583,20 @@ ipfw_readfile(int ac, char *av[])
     int
     main(int ac, char *av[])
     {
    +#if defined(_WIN32) && defined(TCC)
    +	{
    +		WSADATA wsaData;
    +		int ret=0;
    +		unsigned short wVersionRequested = MAKEWORD(2, 2);
    +		ret = WSAStartup(wVersionRequested, &wsaData);
    +		if (ret != 0) {
    +			/* Tell the user that we could not find a usable */
    +			/* Winsock DLL.                                  */
    +			printf("WSAStartup failed with error: %d\n", ret);
    +			return 1;
    +		}
    +	}
    +#endif
     	/*
     	 * If the last argument is an absolute pathname, interpret it
     	 * as a file to be preprocessed.
    diff --git a/sys/conf/files b/sys/conf/files
    index 313b51e0116..b48801263b5 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -2474,13 +2474,24 @@ netinet/in_proto.c		optional inet \
     	compile-with "${NORMAL_C} -I$S/contrib/pf"
     netinet/in_rmx.c		optional inet
     netinet/ip_divert.c		optional inet ipdivert ipfirewall
    +netinet/ipfw/dn_heap.c		optional inet dummynet
    +netinet/ipfw/dn_sched_fifo.c	optional inet dummynet
    +netinet/ipfw/dn_sched_rr.c	optional inet dummynet
    +netinet/ipfw/dn_sched_wf2q.c	optional inet dummynet 
    +netinet/ipfw/dn_sched_qfq.c	optional inet dummynet 
     netinet/ipfw/ip_dummynet.c	optional inet dummynet
    +netinet/ipfw/ip_dn_io.c		optional inet dummynet
    +netinet/ipfw/ip_dn_glue.c	optional inet dummynet
     netinet/ip_ecn.c		optional inet | inet6
     netinet/ip_encap.c		optional inet | inet6
     netinet/ip_fastfwd.c		optional inet
     netinet/ipfw/ip_fw2.c		optional inet ipfirewall \
     	compile-with "${NORMAL_C} -I$S/contrib/pf"
    +netinet/ipfw/ip_fw_dynamic.c	optional inet ipfirewall
    +netinet/ipfw/ip_fw_log.c	optional inet ipfirewall
     netinet/ipfw/ip_fw_pfil.c	optional inet ipfirewall
    +netinet/ipfw/ip_fw_sockopt.c	optional inet ipfirewall
    +netinet/ipfw/ip_fw_table.c	optional inet ipfirewall
     netinet/ipfw/ip_fw_nat.c	optional inet ipfirewall_nat
     netinet/ip_icmp.c		optional inet
     netinet/ip_input.c		optional inet
    diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
    index 18730955864..fe4e18b3250 100644
    --- a/sys/net/if_bridge.c
    +++ b/sys/net/if_bridge.c
    @@ -134,7 +134,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     #include 
    -#include 
    +#include 
     
     /*
      * Size of the route hash table.  Must be a power of two.
    @@ -3058,20 +3058,28 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
     			goto bad;
     	}
     
    -	if (V_ip_fw_chk_ptr && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) {
    -		struct dn_pkt_tag *dn_tag;
    +	/* XXX this section is also in if_ethersubr.c */
    +	// XXX PFIL_OUT or DIR_OUT ?
    +	if (V_ip_fw_chk_ptr && pfil_ipfw != 0 &&
    +			dir == PFIL_OUT && ifp != NULL) {
    +		struct m_tag *mtag;
     
     		error = -1;
    -		dn_tag = ip_dn_claim_tag(*mp);
    -		if (dn_tag != NULL) {
    -			if (dn_tag->rule != NULL && V_fw_one_pass)
    -				/* packet already partially processed */
    +		/* fetch the start point from existing tags, if any */
    +		mtag = m_tag_locate(*mp, MTAG_IPFW_RULE, 0, NULL);
    +		if (mtag == NULL) {
    +			args.rule.slot = 0;
    +		} else {
    +			struct ipfw_rule_ref *r;
    +
    +			/* XXX can we free the tag after use ? */
    +			mtag->m_tag_id = PACKET_TAG_NONE;
    +			r = (struct ipfw_rule_ref *)(mtag + 1);
    +			/* packet already partially processed ? */
    +			if (r->info & IPFW_ONEPASS)
     				goto ipfwpass;
    -			args.rule = dn_tag->rule; /* matching rule to restart */
    -			args.rule_id = dn_tag->rule_id;
    -			args.chain_id = dn_tag->chain_id;
    -		} else
    -			args.rule = NULL;
    +			args.rule = *r;
    +		}
     
     		args.m = *mp;
     		args.oif = ifp;
    @@ -3097,7 +3105,7 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
     			 * packet will return to us via bridge_dummynet().
     			 */
     			args.oif = ifp;
    -			ip_dn_io_ptr(mp, DN_TO_IFB_FWD, &args);
    +			ip_dn_io_ptr(mp, DIR_FWD | PROTO_IFB, &args);
     			return (error);
     		}
     
    diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
    index 5dff9bce55d..46c44e90a7b 100644
    --- a/sys/net/if_ethersubr.c
    +++ b/sys/net/if_ethersubr.c
    @@ -70,9 +70,9 @@
     #include 
     #include 
     #include 
    -#include 
    -#include 
     #include 
    +#include 
    +#include 
     #endif
     #ifdef INET6
     #include 
    @@ -466,19 +466,23 @@ ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, int shared)
     	struct mbuf *m;
     	int i;
     	struct ip_fw_args args;
    -	struct dn_pkt_tag *dn_tag;
    +	struct m_tag *mtag;
     
    -	dn_tag = ip_dn_claim_tag(*m0);
    -
    -	if (dn_tag != NULL) {
    -		if (dn_tag->rule != NULL && V_fw_one_pass)
    +	/* fetch start point from rule, if any */
    +	mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
    +	if (mtag == NULL) {
    +		args.rule.slot = 0;
    +	} else {
     			/* dummynet packet, already partially processed */
    +		struct ipfw_rule_ref *r;
    +
    +		/* XXX can we free it after use ? */
    +		mtag->m_tag_id = PACKET_TAG_NONE;
    +		r = (struct ipfw_rule_ref *)(mtag + 1);
    +		if (r->info & IPFW_ONEPASS)
     			return (1);
    -		args.rule = dn_tag->rule;	/* matching rule to restart */
    -		args.rule_id = dn_tag->rule_id;
    -		args.chain_id = dn_tag->chain_id;
    -	} else
    -		args.rule = NULL;
    +		args.rule = *r;
    +	}
     
     	/*
     	 * I need some amt of data to be contiguous, and in case others need
    @@ -529,6 +533,7 @@ ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, int shared)
     		return 1;
     
     	if (ip_dn_io_ptr && (i == IP_FW_DUMMYNET)) {
    +		int dir;
     		/*
     		 * Pass the pkt to dummynet, which consumes it.
     		 * If shared, make a copy and keep the original.
    @@ -544,7 +549,8 @@ ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, int shared)
     			 */
     			*m0 = NULL ;
     		}
    -		ip_dn_io_ptr(&m, dst ? DN_TO_ETH_OUT: DN_TO_ETH_DEMUX, &args);
    +		dir = PROTO_LAYER2 | (dst ? DIR_OUT : DIR_IN);
    +		ip_dn_io_ptr(&m, dir, &args);
     		return 0;
     	}
     	/*
    diff --git a/sys/net/radix.c b/sys/net/radix.c
    index 39b198eaf49..9f2383d7c7c 100644
    --- a/sys/net/radix.c
    +++ b/sys/net/radix.c
    @@ -33,7 +33,6 @@
     /*
      * Routines to build and maintain radix trees for routing lookups.
      */
    -#ifndef _RADIX_H_
     #include 
     #ifdef	_KERNEL
     #include 
    @@ -41,20 +40,21 @@
     #include 
     #include 
     #include 
    -#include 
    -#else
    -#include 
    -#endif
     #include 
     #include 
    -#endif
    -
     #include "opt_mpath.h"
    -
     #ifdef RADIX_MPATH
     #include 
     #endif
    -
    +#else /* !_KERNEL */
    +#include 
    +#include 
    +#include 
    +#define log(x, arg...)  fprintf(stderr, ## arg)
    +#define panic(x)        fprintf(stderr, "PANIC: %s", x), exit(1)
    +#define min(a, b) ((a) < (b) ? (a) : (b) )
    +#include 
    +#endif /* !_KERNEL */
     
     static int	rn_walktree_from(struct radix_node_head *h, void *a, void *m,
     		    walktree_f_t *f, void *w);
    @@ -72,6 +72,8 @@ static struct radix_node_head *mask_rnhead;
     /*
      * Work area -- the following point to 3 buffers of size max_keylen,
      * allocated in this order in a block of memory malloc'ed by rn_init.
    + * rn_zeros, rn_ones are set in rn_init and used in readonly afterwards.
    + * addmask_key is used in rn_addmask in rw mode and not thread-safe.
      */
     static char *rn_zeros, *rn_ones, *addmask_key;
     
    @@ -135,8 +137,9 @@ static int	rn_satisfies_leaf(char *trial, struct radix_node *leaf,
      * To make the assumption more explicit, we use the LEN() macro to access
      * this field. It is safe to pass an expression with side effects
      * to LEN() as the argument is evaluated only once.
    + * We cast the result to int as this is the dominant usage.
      */
    -#define LEN(x) (*(const u_char *)(x))
    +#define LEN(x) ( (int) (*(const u_char *)(x)) )
     
     /*
      * XXX THIS NEEDS TO BE FIXED
    @@ -197,7 +200,7 @@ rn_refines(m_arg, n_arg)
     {
     	register caddr_t m = m_arg, n = n_arg;
     	register caddr_t lim, lim2 = lim = n + LEN(n);
    -	int longer = LEN(n++) - (int)LEN(m++);
    +	int longer = LEN(n++) - LEN(m++);
     	int masks_are_equal = 1;
     
     	if (longer > 0)
    @@ -250,10 +253,10 @@ rn_satisfies_leaf(trial, leaf, skip)
     	char *cplim;
     	int length = min(LEN(cp), LEN(cp2));
     
    -	if (cp3 == 0)
    +	if (cp3 == NULL)
     		cp3 = rn_ones;
     	else
    -		length = min(length, *(u_char *)cp3);
    +		length = min(length, LEN(cp3));
     	cplim = cp + length; cp3 += skip; cp2 += skip;
     	for (cp += skip; cp < cplim; cp++, cp2++, cp3++)
     		if ((*cp ^ *cp2) & *cp3)
    @@ -424,7 +427,7 @@ rn_insert(v_arg, head, dupentry, nodes)
     {
     	caddr_t v = v_arg;
     	struct radix_node *top = head->rnh_treetop;
    -	int head_off = top->rn_offset, vlen = (int)LEN(v);
    +	int head_off = top->rn_offset, vlen = LEN(v);
     	register struct radix_node *t = rn_search(v_arg, top);
     	register caddr_t cp = v + head_off;
     	register int b;
    @@ -933,7 +936,7 @@ on1:
     			if (m)
     				log(LOG_ERR,
     				    "rn_delete: Orphaned Mask %p at %p\n",
    -				    (void *)m, (void *)x);
    +				    m, x);
     		}
     	}
     	/*
    @@ -1158,17 +1161,28 @@ rn_inithead(head, off)
     	return (1);
     }
     
    +int
    +rn_detachhead(void **head)
    +{
    +	struct radix_node_head *rnh;
    +
    +	KASSERT((head != NULL && *head != NULL),
    +	    ("%s: head already freed", __func__));
    +	rnh = *head;
    +	
    +	/* Free  nodes. */
    +	Free(rnh);
    +
    +	*head = NULL;
    +	return (1);
    +}
    +
     void
    -rn_init()
    +rn_init(int maxk)
     {
     	char *cp, *cplim;
    -#ifdef _KERNEL
    -	struct domain *dom;
     
    -	for (dom = domains; dom; dom = dom->dom_next)
    -		if (dom->dom_maxrtkey > max_keylen)
    -			max_keylen = dom->dom_maxrtkey;
    -#endif
    +	max_keylen = maxk;
     	if (max_keylen == 0) {
     		log(LOG_ERR,
     		    "rn_init: radix functions require max_keylen be set\n");
    diff --git a/sys/net/radix.h b/sys/net/radix.h
    index e84072fb9ef..29659b54651 100644
    --- a/sys/net/radix.h
    +++ b/sys/net/radix.h
    @@ -160,8 +160,9 @@ struct radix_node_head {
     #define	RADIX_NODE_HEAD_WLOCK_ASSERT(rnh) rw_assert(&(rnh)->rnh_lock, RA_WLOCKED)
     #endif /* _KERNEL */
     
    -void	 rn_init(void);
    +void	 rn_init(int);
     int	 rn_inithead(void **, int);
    +int	 rn_detachhead(void **);
     int	 rn_refines(void *, void *);
     struct radix_node
     	 *rn_addmask(void *, int, int),
    diff --git a/sys/net/route.c b/sys/net/route.c
    index b00ea69f206..a938c9c1b7f 100644
    --- a/sys/net/route.c
    +++ b/sys/net/route.c
    @@ -169,13 +169,20 @@ rt_tables_get_rnh(int table, int fam)
     static void
     route_init(void)
     {
    +	struct domain *dom;
    +	int max_keylen = 0;
     
     	/* whack the tunable ints into  line. */
     	if (rt_numfibs > RT_MAXFIBS)
     		rt_numfibs = RT_MAXFIBS;
     	if (rt_numfibs == 0)
     		rt_numfibs = 1;
    -	rn_init();	/* initialize all zeroes, all ones, mask table */
    +
    +	for (dom = domains; dom; dom = dom->dom_next)
    +		if (dom->dom_maxrtkey > max_keylen)
    +			max_keylen = dom->dom_maxrtkey;
    +
    +	rn_init(max_keylen);	/* init all zeroes, all ones, mask table */
     }
     SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0);
     
    diff --git a/sys/netgraph/ng_ipfw.c b/sys/netgraph/ng_ipfw.c
    index 46bac8eb9bc..d331828160d 100644
    --- a/sys/netgraph/ng_ipfw.c
    +++ b/sys/netgraph/ng_ipfw.c
    @@ -43,9 +43,10 @@
     #include 
     #include 
     #include 
    -#include 
    -#include 
     #include 
    +#include 
    +#include 
    +#include 
     
     #include 
     #include 
    @@ -220,21 +221,23 @@ ng_ipfw_findhook1(node_p node, u_int16_t rulenum)
     static int
     ng_ipfw_rcvdata(hook_p hook, item_p item)
     {
    -	struct ng_ipfw_tag	*ngit;
    +	struct ipfw_rule_ref	*tag;
     	struct mbuf *m;
     
     	NGI_GET_M(item, m);
     	NG_FREE_ITEM(item);
     
    -	if ((ngit = (struct ng_ipfw_tag *)m_tag_locate(m, NGM_IPFW_COOKIE, 0,
    -	    NULL)) == NULL) {
    +	tag = (struct ipfw_rule_ref *)
    +		m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL);
    +	if (tag == NULL) {
     		NG_FREE_M(m);
     		return (EINVAL);	/* XXX: find smth better */
     	};
     
    -	switch (ngit->dir) {
    -	case NG_IPFW_OUT:
    -	    {
    +	if (tag->info & IPFW_INFO_IN) {
    +		ip_input(m);
    +		return (0);
    +	} else {
     		struct ip *ip;
     
     		if (m->m_len < sizeof(struct ip) &&
    @@ -243,27 +246,16 @@ ng_ipfw_rcvdata(hook_p hook, item_p item)
     
     		ip = mtod(m, struct ip *);
     
    -		ip->ip_len = ntohs(ip->ip_len);
    -		ip->ip_off = ntohs(ip->ip_off);
    +		SET_HOST_IPLEN(ip);
     
     		return ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
     	    }
    -	case NG_IPFW_IN:
    -		ip_input(m);
    -		return (0);
    -	default:
    -		panic("ng_ipfw_rcvdata: bad dir %u", ngit->dir);
    -	}	
    -
    -	/* not reached */
    -	return (0);
     }
     
     static int
     ng_ipfw_input(struct mbuf **m0, int dir, struct ip_fw_args *fwa, int tee)
     {
     	struct mbuf *m;
    -	struct ng_ipfw_tag *ngit;
     	struct ip *ip;
     	hook_p	hook;
     	int error = 0;
    @@ -272,7 +264,7 @@ ng_ipfw_input(struct mbuf **m0, int dir, struct ip_fw_args *fwa, int tee)
     	 * Node must be loaded and corresponding hook must be present.
     	 */
     	if (fw_node == NULL || 
    -	   (hook = ng_ipfw_findhook1(fw_node, fwa->cookie)) == NULL) {
    +	   (hook = ng_ipfw_findhook1(fw_node, fwa->rule.info)) == NULL) {
     		if (tee == 0)
     			m_freem(*m0);
     		return (ESRCH);		/* no hook associated with this rule */
    @@ -284,20 +276,21 @@ ng_ipfw_input(struct mbuf **m0, int dir, struct ip_fw_args *fwa, int tee)
     	 * a copy of a packet and forward it into netgraph without a tag.
     	 */
     	if (tee == 0) {
    +		struct m_tag *tag;
    +		struct ipfw_rule_ref *r;
     		m = *m0;
     		*m0 = NULL;	/* it belongs now to netgraph */
     
    -		if ((ngit = (struct ng_ipfw_tag *)m_tag_alloc(NGM_IPFW_COOKIE,
    -		    0, TAGSIZ, M_NOWAIT|M_ZERO)) == NULL) {
    +		tag = m_tag_alloc(MTAG_IPFW_RULE, 0, sizeof(*r),
    +			M_NOWAIT|M_ZERO);
    +		if (tag == NULL) {
     			m_freem(m);
     			return (ENOMEM);
     		}
    -		ngit->rule = fwa->rule;
    -		ngit->rule_id = fwa->rule_id;
    -		ngit->chain_id = fwa->chain_id;
    -		ngit->dir = dir;
    -		ngit->ifp = fwa->oif;
    -		m_tag_prepend(m, &ngit->mt);
    +		r = (struct ipfw_rule_ref *)(tag + 1);
    +		*r = fwa->rule;
    +		r->info = dir ? IPFW_INFO_IN : IPFW_INFO_OUT;
    +		m_tag_prepend(m, tag);
     
     	} else
     		if ((m = m_dup(*m0, M_DONTWAIT)) == NULL)
    @@ -308,8 +301,6 @@ ng_ipfw_input(struct mbuf **m0, int dir, struct ip_fw_args *fwa, int tee)
     		return (EINVAL);
     
     	ip = mtod(m, struct ip *);
    -	ip->ip_len = htons(ip->ip_len);
    -	ip->ip_off = htons(ip->ip_off);
     
     	NG_SEND_DATA_ONLY(error, hook, m);
     
    diff --git a/sys/netgraph/ng_ipfw.h b/sys/netgraph/ng_ipfw.h
    index 29039f2f7a6..c2cab6a0396 100644
    --- a/sys/netgraph/ng_ipfw.h
    +++ b/sys/netgraph/ng_ipfw.h
    @@ -26,26 +26,8 @@
      * $FreeBSD$
      */
     
    +#ifndef _NG_IPFW_H
    +#define _NG_IPFW_H
     #define NG_IPFW_NODE_TYPE    "ipfw"
     #define NGM_IPFW_COOKIE      1105988990
    -
    -#ifdef _KERNEL
    -
    -typedef int ng_ipfw_input_t(struct mbuf **, int, struct ip_fw_args *, int);
    -extern	ng_ipfw_input_t	*ng_ipfw_input_p;
    -#define	NG_IPFW_LOADED	(ng_ipfw_input_p != NULL)
    -
    -struct ng_ipfw_tag {
    -	struct m_tag	mt;		/* tag header */
    -	struct ip_fw	*rule;		/* matching rule */
    -	uint32_t	rule_id;	/* matching rule id */
    -	uint32_t	chain_id;	/* ruleset id */
    -	struct ifnet	*ifp;		/* interface, for ip_output */
    -	int		dir;
    -#define	NG_IPFW_OUT	0
    -#define	NG_IPFW_IN	1
    -};
    -
    -#define	TAGSIZ	(sizeof(struct ng_ipfw_tag) - sizeof(struct m_tag))
    -
    -#endif /* _KERNEL */
    +#endif /* _NG_IPFW_H */
    diff --git a/sys/netinet/in.h b/sys/netinet/in.h
    index 7aa16453e15..4a7e11a48bd 100644
    --- a/sys/netinet/in.h
    +++ b/sys/netinet/in.h
    @@ -754,6 +754,32 @@ void	 in_ifdetach(struct ifnet *);
     #define	sintosa(sin)	((struct sockaddr *)(sin))
     #define	ifatoia(ifa)	((struct in_ifaddr *)(ifa))
     
    +/*
    + * Historically, BSD keeps ip_len and ip_off in host format
    + * when doing layer 3 processing, and this often requires
    + * to translate the format back and forth.
    + * To make the process explicit, we define a couple of macros
    + * that also take into account the fact that at some point
    + * we may want to keep those fields always in net format.
    + */
    +
    +#if (BYTE_ORDER == BIG_ENDIAN) || defined(HAVE_NET_IPLEN)
    +#define SET_NET_IPLEN(p)	do {} while (0)
    +#define SET_HOST_IPLEN(p)	do {} while (0)
    +#else
    +#define SET_NET_IPLEN(p)	do {		\
    +	struct ip *h_ip = (p);			\
    +	h_ip->ip_len = htons(h_ip->ip_len);	\
    +	h_ip->ip_off = htons(h_ip->ip_off);	\
    +	} while (0)
    +
    +#define SET_HOST_IPLEN(p)	do {		\
    +	struct ip *h_ip = (p);			\
    +	h_ip->ip_len = ntohs(h_ip->ip_len);	\
    +	h_ip->ip_off = ntohs(h_ip->ip_off);	\
    +	} while (0)
    +#endif /* !HAVE_NET_IPLEN */
    +
     #endif /* _KERNEL */
     
     /* INET6 stuff */
    diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
    index 401c0908de5..9e7f0621917 100644
    --- a/sys/netinet/ip_divert.c
    +++ b/sys/netinet/ip_divert.c
    @@ -32,14 +32,10 @@ __FBSDID("$FreeBSD$");
     
     #if !defined(KLD_MODULE)
     #include "opt_inet.h"
    -#include "opt_ipfw.h"
     #include "opt_sctp.h"
     #ifndef INET
     #error "IPDIVERT requires INET."
     #endif
    -#ifndef IPFIREWALL
    -#error "IPDIVERT requires IPFIREWALL"
    -#endif
     #endif
     
     #include 
    @@ -72,9 +68,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    -#include 
     #include 
    -#include 
     #ifdef SCTP
     #include 
     #endif
    @@ -92,27 +86,29 @@ __FBSDID("$FreeBSD$");
     #define	DIVRCVQ		(65536 + 100)
     
     /*
    - * Divert sockets work in conjunction with ipfw, see the divert(4)
    - * manpage for features.
    - * Internally, packets selected by ipfw in ip_input() or ip_output(),
    - * and never diverted before, are passed to the input queue of the
    - * divert socket with a given 'divert_port' number (as specified in
    - * the matching ipfw rule), and they are tagged with a 16 bit cookie
    - * (representing the rule number of the matching ipfw rule), which
    - * is passed to process reading from the socket.
    + * Divert sockets work in conjunction with ipfw or other packet filters,
    + * see the divert(4) manpage for features.
    + * Packets are selected by the packet filter and tagged with an
    + * MTAG_IPFW_RULE tag carrying the 'divert port' number (as set by
    + * the packet filter) and information on the matching filter rule for
    + * subsequent reinjection. The divert_port is used to put the packet
    + * on the corresponding divert socket, while the rule number is passed
    + * up (at least partially) as the sin_port in the struct sockaddr.
      *
    - * Packets written to the divert socket are again tagged with a cookie
    - * (usually the same as above) and a destination address.
    - * If the destination address is INADDR_ANY then the packet is
    - * treated as outgoing and sent to ip_output(), otherwise it is
    - * treated as incoming and sent to ip_input().
    - * In both cases, the packet is tagged with the cookie.
    + * Packets written to the divert socket carry in sin_addr a
    + * destination address, and in sin_port the number of the filter rule
    + * after which to continue processing.
    + * If the destination address is INADDR_ANY, the packet is treated as
    + * as outgoing and sent to ip_output(); otherwise it is treated as
    + * incoming and sent to ip_input().
    + * Further, sin_zero carries some information on the interface,
    + * which can be used in the reinject -- see comments in the code.
      *
      * On reinjection, processing in ip_input() and ip_output()
      * will be exactly the same as for the original packet, except that
    - * ipfw processing will start at the rule number after the one
    - * written in the cookie (so, tagging a packet with a cookie of 0
    - * will cause it to be effectively considered as a standard packet).
    + * packet filter processing will start at the rule number after the one
    + * written in the sin_port (ipfw does not allow a rule #0, so sin_port=0
    + * will apply the entire ruleset to the packet).
      */
     
     /* Internal variables. */
    @@ -193,7 +189,7 @@ div_destroy(void)
      * IPPROTO_DIVERT is not in the real IP protocol number space; this
      * function should never be called.  Just in case, drop any packets.
      */
    -void
    +static void
     div_input(struct mbuf *m, int off)
     {
     
    @@ -217,9 +213,8 @@ divert_packet(struct mbuf *m, int incoming)
     	struct sockaddr_in divsrc;
     	struct m_tag *mtag;
     
    -	mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
    +	mtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL);
     	if (mtag == NULL) {
    -		printf("%s: no divert tag\n", __func__);
     		m_freem(m);
     		return;
     	}
    @@ -244,14 +239,15 @@ divert_packet(struct mbuf *m, int incoming)
     		ip->ip_len = htons(ip->ip_len);
     	}
     #endif
    +	bzero(&divsrc, sizeof(divsrc));
    +	divsrc.sin_len = sizeof(divsrc);
    +	divsrc.sin_family = AF_INET;
    +	/* record matching rule, in host format */
    +	divsrc.sin_port = ((struct ipfw_rule_ref *)(mtag+1))->rulenum;
     	/*
     	 * Record receive interface address, if any.
     	 * But only for incoming packets.
     	 */
    -	bzero(&divsrc, sizeof(divsrc));
    -	divsrc.sin_len = sizeof(divsrc);
    -	divsrc.sin_family = AF_INET;
    -	divsrc.sin_port = divert_cookie(mtag);	/* record matching rule */
     	if (incoming) {
     		struct ifaddr *ifa;
     		struct ifnet *ifp;
    @@ -299,7 +295,7 @@ divert_packet(struct mbuf *m, int incoming)
     
     	/* Put packet on socket queue, if any */
     	sa = NULL;
    -	nport = htons((u_int16_t)divert_info(mtag));
    +	nport = htons((u_int16_t)(((struct ipfw_rule_ref *)(mtag+1))->info));
     	INP_INFO_RLOCK(&V_divcbinfo);
     	LIST_FOREACH(inp, &V_divcb, inp_list) {
     		/* XXX why does only one socket match? */
    @@ -338,7 +334,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
         struct mbuf *control)
     {
     	struct m_tag *mtag;
    -	struct divert_tag *dt;
    +	struct ipfw_rule_ref *dt;
     	int error = 0;
     	struct mbuf *options;
     
    @@ -353,23 +349,31 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
     	if (control)
     		m_freem(control);		/* XXX */
     
    -	if ((mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL)) == NULL) {
    -		mtag = m_tag_get(PACKET_TAG_DIVERT, sizeof(struct divert_tag),
    -		    M_NOWAIT | M_ZERO);
    +	mtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL);
    +	if (mtag == NULL) {
    +		/* this should be normal */
    +		mtag = m_tag_alloc(MTAG_IPFW_RULE, 0,
    +		    sizeof(struct ipfw_rule_ref), M_NOWAIT | M_ZERO);
     		if (mtag == NULL) {
     			error = ENOBUFS;
     			goto cantsend;
     		}
    -		dt = (struct divert_tag *)(mtag+1);
     		m_tag_prepend(m, mtag);
    -	} else
    -		dt = (struct divert_tag *)(mtag+1);
    +	}
    +	dt = (struct ipfw_rule_ref *)(mtag+1);
     
     	/* Loopback avoidance and state recovery */
     	if (sin) {
     		int i;
     
    -		dt->cookie = sin->sin_port;
    +		/* set the starting point. We provide a non-zero slot,
    +		 * but a non_matching chain_id to skip that info and use
    +		 * the rulenum/rule_id.
    +		 */
    +		dt->slot = 1; /* dummy, chain_id is invalid */
    +		dt->chain_id = 0;
    +		dt->rulenum = sin->sin_port+1; /* host format ? */
    +		dt->rule_id = 0;
     		/*
     		 * Find receive interface with the given name, stuffed
     		 * (if it exists) in the sin_zero[] field.
    @@ -387,7 +391,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
     		struct ip *const ip = mtod(m, struct ip *);
     		struct inpcb *inp;
     
    -		dt->info |= IP_FW_DIVERT_OUTPUT_FLAG;
    +		dt->info |= IPFW_IS_DIVERT | IPFW_INFO_OUT;
     		INP_INFO_WLOCK(&V_divcbinfo);
     		inp = sotoinpcb(so);
     		INP_RLOCK(inp);
    @@ -453,7 +457,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
     				m_freem(options);
     		}
     	} else {
    -		dt->info |= IP_FW_DIVERT_LOOPBACK_FLAG;
    +		dt->info |= IPFW_IS_DIVERT | IPFW_INFO_IN;
     		if (m->m_pkthdr.rcvif == NULL) {
     			/*
     			 * No luck with the name, check by IP address.
    @@ -587,7 +591,7 @@ div_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
     	return div_output(so, m, (struct sockaddr_in *)nam, control);
     }
     
    -void
    +static void
     div_ctlinput(int cmd, struct sockaddr *sa, void *vip)
     {
             struct in_addr faddr;
    @@ -800,5 +804,5 @@ static moduledata_t ipdivertmod = {
     };
     
     DECLARE_MODULE(ipdivert, ipdivertmod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
    -MODULE_DEPEND(dummynet, ipfw, 2, 2, 2);
    +MODULE_DEPEND(ipdivert, ipfw, 2, 2, 2);
     MODULE_VERSION(ipdivert, 1);
    diff --git a/sys/netinet/ip_divert.h b/sys/netinet/ip_divert.h
    index 50363554982..b8bcf4fb675 100644
    --- a/sys/netinet/ip_divert.h
    +++ b/sys/netinet/ip_divert.h
    @@ -36,53 +36,20 @@
     #define	_NETINET_IP_DIVERT_H_
     
     /*
    - * Sysctl declaration.
    + * divert has no custom kernel-userland API.
    + *
    + * All communication occurs through a sockaddr_in socket where
    + *
    + * kernel-->userland
    + *	sin_port = matching rule, host format;
    + * 	sin_addr = IN: first address of the incoming interface;
    + *		   OUT: INADDR_ANY
    + *	sin_zero = if fits, the interface name (max 7 bytes + NUL)
    + *
    + * userland->kernel
    + *	sin_port = restart-rule - 1, host order
    + *		(we restart at sin_port + 1)
    + *	sin_addr = IN: address of the incoming interface;
    + *		   OUT: INADDR_ANY
      */
    -#ifdef SYSCTL_DECL
    -SYSCTL_DECL(_net_inet_divert);
    -#endif
    -
    -/*
    - * Divert socket definitions.
    - */
    -struct divert_tag {
    -	u_int32_t	info;		/* port & flags */
    -	u_int16_t	cookie;		/* ipfw rule number */
    -};
    -
    -/*
    - * Return the divert cookie associated with the mbuf; if any.
    - */
    -static __inline u_int16_t
    -divert_cookie(struct m_tag *mtag)
    -{
    -	return ((struct divert_tag *)(mtag+1))->cookie;
    -}
    -static __inline u_int16_t
    -divert_find_cookie(struct mbuf *m)
    -{
    -	struct m_tag *mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
    -	return mtag ? divert_cookie(mtag) : 0;
    -}
    -
    -/*
    - * Return the divert info associated with the mbuf; if any.
    - */
    -static __inline u_int32_t
    -divert_info(struct m_tag *mtag)
    -{
    -	return ((struct divert_tag *)(mtag+1))->info;
    -}
    -static __inline u_int32_t
    -divert_find_info(struct mbuf *m)
    -{
    -	struct m_tag *mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
    -	return mtag ? divert_info(mtag) : 0;
    -}
    -
    -typedef	void ip_divert_packet_t(struct mbuf *m, int incoming);
    -extern	ip_divert_packet_t *ip_divert_ptr;
    -
    -extern	void div_input(struct mbuf *, int);
    -extern	void div_ctlinput(int, struct sockaddr *, void *);
     #endif /* _NETINET_IP_DIVERT_H_ */
    diff --git a/sys/netinet/ip_dummynet.h b/sys/netinet/ip_dummynet.h
    index b5ef19e49a6..0bbc32638c9 100644
    --- a/sys/netinet/ip_dummynet.h
    +++ b/sys/netinet/ip_dummynet.h
    @@ -1,5 +1,5 @@
     /*-
    - * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa
    + * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa
      * Portions Copyright (c) 2000 Akamba Corp.
      * All rights reserved
      *
    @@ -31,262 +31,124 @@
     #define _IP_DUMMYNET_H
     
     /*
    - * Definition of dummynet data structures. In the structures, I decided
    - * not to use the macros in  in the hope of making the code
    - * easier to port to other architectures. The type of lists and queue we
    - * use here is pretty simple anyways.
    - */
    -
    -/*
    - * We start with a heap, which is used in the scheduler to decide when
    - * to transmit packets etc.
    + * Definition of the kernel-userland API for dummynet.
      *
    - * The key for the heap is used for two different values:
    + * Setsockopt() and getsockopt() pass a batch of objects, each
    + * of them starting with a "struct dn_id" which should fully identify
    + * the object and its relation with others in the sequence.
    + * The first object in each request should have
    + *	 type= DN_CMD_*, id = DN_API_VERSION.
    + * For other objects, type and subtype specify the object, len indicates
    + * the total length including the header, and 'id' identifies the specific
    + * object.
      *
    - * 1. timer ticks- max 10K/second, so 32 bits are enough;
    - *
    - * 2. virtual times. These increase in steps of len/x, where len is the
    - *    packet length, and x is either the weight of the flow, or the
    - *    sum of all weights.
    - *    If we limit to max 1000 flows and a max weight of 100, then
    - *    x needs 17 bits. The packet size is 16 bits, so we can easily
    - *    overflow if we do not allow errors.
    - * So we use a key "dn_key" which is 64 bits. Some macros are used to
    - * compare key values and handle wraparounds.
    - * MAX64 returns the largest of two key values.
    - * MY_M is used as a shift count when doing fixed point arithmetic
    - * (a better name would be useful...).
    - */
    -typedef u_int64_t dn_key ;      /* sorting key */
    -#define DN_KEY_LT(a,b)     ((int64_t)((a)-(b)) < 0)
    -#define DN_KEY_LEQ(a,b)    ((int64_t)((a)-(b)) <= 0)
    -#define DN_KEY_GT(a,b)     ((int64_t)((a)-(b)) > 0)
    -#define DN_KEY_GEQ(a,b)    ((int64_t)((a)-(b)) >= 0)
    -#define MAX64(x,y)  (( (int64_t) ( (y)-(x) )) > 0 ) ? (y) : (x)
    -#define MY_M	16 /* number of left shift to obtain a larger precision */
    -
    -/*
    - * XXX With this scaling, max 1000 flows, max weight 100, 1Gbit/s, the
    - * virtual time wraps every 15 days.
    + * Most objects are numbered with an identifier in the range 1..65535.
    + * DN_MAX_ID indicates the first value outside the range.
      */
     
    +#define	DN_API_VERSION	12500000
    +#define	DN_MAX_ID	0x10000
     
    -/*
    - * The maximum hash table size for queues.  This value must be a power
    - * of 2.
    - */
    -#define DN_MAX_HASH_SIZE 65536
    -
    -/*
    - * A heap entry is made of a key and a pointer to the actual
    - * object stored in the heap.
    - * The heap is an array of dn_heap_entry entries, dynamically allocated.
    - * Current size is "size", with "elements" actually in use.
    - * The heap normally supports only ordered insert and extract from the top.
    - * If we want to extract an object from the middle of the heap, we
    - * have to know where the object itself is located in the heap (or we
    - * need to scan the whole array). To this purpose, an object has a
    - * field (int) which contains the index of the object itself into the
    - * heap. When the object is moved, the field must also be updated.
    - * The offset of the index in the object is stored in the 'offset'
    - * field in the heap descriptor. The assumption is that this offset
    - * is non-zero if we want to support extract from the middle.
    - */
    -struct dn_heap_entry {
    -    dn_key key ;	/* sorting key. Topmost element is smallest one */
    -    void *object ;	/* object pointer */
    -} ;
    -
    -struct dn_heap {
    -    int size ;
    -    int elements ;
    -    int offset ; /* XXX if > 0 this is the offset of direct ptr to obj */
    -    struct dn_heap_entry *p ;	/* really an array of "size" entries */
    -} ;
    -
    -#ifdef _KERNEL
    -/*
    - * Packets processed by dummynet have an mbuf tag associated with
    - * them that carries their dummynet state.  This is used within
    - * the dummynet code as well as outside when checking for special
    - * processing requirements.
    - */
    -struct dn_pkt_tag {
    -    struct ip_fw *rule;		/* matching rule */
    -    uint32_t rule_id;		/* matching rule id */
    -    uint32_t chain_id;		/* ruleset id */
    -    int dn_dir;			/* action when packet comes out. */
    -#define DN_TO_IP_OUT	1
    -#define DN_TO_IP_IN	2
    -/* Obsolete: #define DN_TO_BDG_FWD	3 */
    -#define DN_TO_ETH_DEMUX	4
    -#define DN_TO_ETH_OUT	5
    -#define DN_TO_IP6_IN	6
    -#define DN_TO_IP6_OUT	7
    -#define DN_TO_IFB_FWD	8
    -
    -    dn_key output_time;		/* when the pkt is due for delivery	*/
    -    struct ifnet *ifp;		/* interface, for ip_output		*/
    -    struct _ip6dn_args ip6opt;	/* XXX ipv6 options			*/
    +struct dn_id {
    +	uint16_t	len;	/* total obj len including this header */
    +	uint8_t		type;
    +	uint8_t		subtype;
    +	uint32_t	id;	/* generic id */
     };
    -#endif /* _KERNEL */
     
     /*
    - * Overall structure of dummynet (with WF2Q+):
    -
    -In dummynet, packets are selected with the firewall rules, and passed
    -to two different objects: PIPE or QUEUE.
    -
    -A QUEUE is just a queue with configurable size and queue management
    -policy. It is also associated with a mask (to discriminate among
    -different flows), a weight (used to give different shares of the
    -bandwidth to different flows) and a "pipe", which essentially
    -supplies the transmit clock for all queues associated with that
    -pipe.
    -
    -A PIPE emulates a fixed-bandwidth link, whose bandwidth is
    -configurable.  The "clock" for a pipe can come from either an
    -internal timer, or from the transmit interrupt of an interface.
    -A pipe is also associated with one (or more, if masks are used)
    -queue, where all packets for that pipe are stored.
    -
    -The bandwidth available on the pipe is shared by the queues
    -associated with that pipe (only one in case the packet is sent
    -to a PIPE) according to the WF2Q+ scheduling algorithm and the
    -configured weights.
    -
    -In general, incoming packets are stored in the appropriate queue,
    -which is then placed into one of a few heaps managed by a scheduler
    -to decide when the packet should be extracted.
    -The scheduler (a function called dummynet()) is run at every timer
    -tick, and grabs queues from the head of the heaps when they are
    -ready for processing.
    -
    -There are three data structures definining a pipe and associated queues:
    -
    - + dn_pipe, which contains the main configuration parameters related
    -   to delay and bandwidth;
    - + dn_flow_set, which contains WF2Q+ configuration, flow
    -   masks, plr and RED configuration;
    - + dn_flow_queue, which is the per-flow queue (containing the packets)
    -
    -Multiple dn_flow_set can be linked to the same pipe, and multiple
    -dn_flow_queue can be linked to the same dn_flow_set.
    -All data structures are linked in a linear list which is used for
    -housekeeping purposes.
    -
    -During configuration, we create and initialize the dn_flow_set
    -and dn_pipe structures (a dn_pipe also contains a dn_flow_set).
    -
    -At runtime: packets are sent to the appropriate dn_flow_set (either
    -WFQ ones, or the one embedded in the dn_pipe for fixed-rate flows),
    -which in turn dispatches them to the appropriate dn_flow_queue
    -(created dynamically according to the masks).
    -
    -The transmit clock for fixed rate flows (ready_event()) selects the
    -dn_flow_queue to be used to transmit the next packet. For WF2Q,
    -wfq_ready_event() extract a pipe which in turn selects the right
    -flow using a number of heaps defined into the pipe itself.
    -
    - *
    + * These values are in the type field of struct dn_id.
    + * To preserve the ABI, never rearrange the list or delete
    + * entries with the exception of DN_LAST
      */
    +enum {
    +	DN_NONE = 0,
    +	DN_LINK = 1,
    +	DN_FS,
    +	DN_SCH,
    +	DN_SCH_I,
    +	DN_QUEUE,
    +	DN_DELAY_LINE,
    +	DN_PROFILE,
    +	DN_FLOW,		/* struct dn_flow */
    +	DN_TEXT,		/* opaque text is the object */
    +
    +	DN_CMD_CONFIG = 0x80,	/* objects follow */
    +	DN_CMD_DELETE,		/* subtype + list of entries */
    +	DN_CMD_GET,		/* subtype + list of entries */
    +	DN_CMD_FLUSH,
    +	/* for compatibility with FreeBSD 7.2/8 */
    +	DN_COMPAT_PIPE,
    +	DN_COMPAT_QUEUE,
    +	DN_GET_COMPAT,
    +
    +	/* special commands for emulation of sysctl variables */
    +	DN_SYSCTL_GET,
    +	DN_SYSCTL_SET,
    +
    +	DN_LAST,
    +} ;
    +
    +enum { /* subtype for schedulers, flowset and the like */
    +	DN_SCHED_UNKNOWN = 0,
    +	DN_SCHED_FIFO = 1,
    +	DN_SCHED_WF2QP = 2,
    +	/* others are in individual modules */
    +} ;
    +
    +enum {	/* user flags */
    +	DN_HAVE_MASK	= 0x0001,	/* fs or sched has a mask */
    +	DN_NOERROR	= 0x0002,	/* do not report errors */
    +	DN_QHT_HASH	= 0x0004,	/* qht is a hash table */
    +	DN_QSIZE_BYTES	= 0x0008,	/* queue size is in bytes */
    +	DN_HAS_PROFILE	= 0x0010,	/* a link has a profile */
    +	DN_IS_RED	= 0x0020,
    +	DN_IS_GENTLE_RED= 0x0040,
    +	DN_PIPE_CMD	= 0x1000,	/* pipe config... */
    +};
     
     /*
    - * per flow queue. This contains the flow identifier, the queue
    - * of packets, counters, and parameters used to support both RED and
    - * WF2Q+.
    - *
    - * A dn_flow_queue is created and initialized whenever a packet for
    - * a new flow arrives.
    + * link template.
      */
    -struct dn_flow_queue {
    -    struct dn_flow_queue *next ;
    -    struct ipfw_flow_id id ;
    -
    -    struct mbuf *head, *tail ;	/* queue of packets */
    -    u_int len ;
    -    u_int len_bytes ;
    +struct dn_link {
    +	struct dn_id oid;
     
         /*
    -     * When we emulate MAC overheads, or channel unavailability due
    -     * to other traffic on a shared medium, we augment the packet at
    -     * the head of the queue with an 'extra_bits' field representsing
    -     * the additional delay the packet will be subject to:
    -     *		extra_bits = bw*unavailable_time.
    -     * With large bandwidth and large delays, extra_bits (and also numbytes)
    -     * can become very large, so better play safe and use 64 bit
    -     */
    -    uint64_t numbytes ;		/* credit for transmission (dynamic queues) */
    -    int64_t extra_bits;		/* extra bits simulating unavailable channel */
    -
    -    u_int64_t tot_pkts ;	/* statistics counters	*/
    -    u_int64_t tot_bytes ;
    -    u_int32_t drops ;
    -
    -    int hash_slot ;		/* debugging/diagnostic */
    -
    -    /* RED parameters */
    -    int avg ;                   /* average queue length est. (scaled) */
    -    int count ;                 /* arrivals since last RED drop */
    -    int random ;                /* random value (scaled) */
    -    dn_key idle_time;		/* start of queue idle time */
    -
    -    /* WF2Q+ support */
    -    struct dn_flow_set *fs ;	/* parent flow set */
    -    int heap_pos ;		/* position (index) of struct in heap */
    -    dn_key sched_time ;		/* current time when queue enters ready_heap */
    -
    -    dn_key S,F ;		/* start time, finish time */
    -    /*
    -     * Setting F < S means the timestamp is invalid. We only need
    -     * to test this when the queue is empty.
    +	 * Userland sets bw and delay in bits/s and milliseconds.
    +	 * The kernel converts this back and forth to bits/tick and ticks.
    +	 * XXX what about burst ?
          */
    +	int32_t		link_nr;
    +	int		bandwidth;	/* bit/s or bits/tick.   */
    +	int		delay;		/* ms and ticks */
    +	uint64_t	burst;		/* scaled. bits*Hz  XXX */
     } ;
     
     /*
    - * flow_set descriptor. Contains the "template" parameters for the
    - * queue configuration, and pointers to the hash table of dn_flow_queue's.
    - *
    - * The hash table is an array of lists -- we identify the slot by
    - * hashing the flow-id, then scan the list looking for a match.
    - * The size of the hash table (buckets) is configurable on a per-queue
    - * basis.
    - *
    - * A dn_flow_set is created whenever a new queue or pipe is created (in the
    - * latter case, the structure is located inside the struct dn_pipe).
    + * A flowset, which is a template for flows. Contains parameters
    + * from the command line: id, target scheduler, queue sizes, plr,
    + * flow masks, buckets for the flow hash, and possibly scheduler-
    + * specific parameters (weight, quantum and so on).
      */
    -struct dn_flow_set {
    -    SLIST_ENTRY(dn_flow_set)	next;	/* linked list in a hash slot */
    -
    -    u_short fs_nr ;             /* flow_set number       */
    -    u_short flags_fs;
    -#define DN_HAVE_FLOW_MASK	0x0001
    -#define DN_IS_RED		0x0002
    -#define DN_IS_GENTLE_RED	0x0004
    -#define DN_QSIZE_IS_BYTES	0x0008	/* queue size is measured in bytes */
    -#define DN_NOERROR		0x0010	/* do not report ENOBUFS on drops  */
    -#define	DN_HAS_PROFILE		0x0020	/* the pipe has a delay profile. */
    -#define DN_IS_PIPE		0x4000
    -#define DN_IS_QUEUE		0x8000
    -
    -    struct dn_pipe *pipe ;	/* pointer to parent pipe */
    -    u_short parent_nr ;		/* parent pipe#, 0 if local to a pipe */
    -
    -    int weight ;		/* WFQ queue weight */
    +struct dn_fs {
    +	struct dn_id oid;
    +	uint32_t fs_nr;	/* the flowset number */
    +	uint32_t flags;	/* userland flags */
         int qsize ;			/* queue size in slots or bytes */
    -    int plr ;			/* pkt loss rate (2^31-1 means 100%) */
    +	int32_t plr;	/* PLR, pkt loss rate (2^31-1 means 100%) */
    +	uint32_t buckets;	/* buckets used for the queue hash table */
     
         struct ipfw_flow_id flow_mask ;
    +	uint32_t sched_nr;	/* the scheduler we attach to */
    +	/* generic scheduler parameters. Leave them at -1 if unset.
    +	 * Now we use 0: weight, 1: lmax, 2: priority
    +	 */
    +	int par[4];
     
    -    /* hash table of queues onto this flow_set */
    -    int rq_size ;		/* number of slots */
    -    int rq_elements ;		/* active elements */
    -    struct dn_flow_queue **rq;	/* array of rq_size entries */
    -
    -    u_int32_t last_expired ;	/* do not expire too frequently */
    -    int backlogged ;		/* #active queues for this flowset */
    -
    -        /* RED parameters */
    +	/* RED/GRED parameters.
    +	 * weight and probabilities are in the range 0..1 represented
    +	 * in fixed point arithmetic with SCALE_RED decimal bits.
    +	 */
     #define SCALE_RED               16
     #define SCALE(x)                ( (x) << SCALE_RED )
     #define SCALE_VAL(x)            ( (x) >> SCALE_RED )
    @@ -295,102 +157,107 @@ struct dn_flow_set {
         int max_th ;		/* maximum threshold for queue (scaled) */
         int min_th ;		/* minimum threshold for queue (scaled) */
         int max_p ;			/* maximum value for p_b (scaled) */
    -    u_int c_1 ;			/* max_p/(max_th-min_th) (scaled) */
    -    u_int c_2 ;			/* max_p*min_th/(max_th-min_th) (scaled) */
    -    u_int c_3 ;			/* for GRED, (1-max_p)/max_th (scaled) */
    -    u_int c_4 ;			/* for GRED, 1 - 2*max_p (scaled) */
    -    u_int * w_q_lookup ;	/* lookup table for computing (1-w_q)^t */
    -    u_int lookup_depth ;	/* depth of lookup table */
    -    int lookup_step ;		/* granularity inside the lookup table */
    -    int lookup_weight ;		/* equal to (1-w_q)^t / (1-w_q)^(t+1) */
    -    int avg_pkt_size ;		/* medium packet size */
    -    int max_pkt_size ;		/* max packet size */
    +
     };
    -SLIST_HEAD(dn_flow_set_head, dn_flow_set);
     
     /*
    - * Pipe descriptor. Contains global parameters, delay-line queue,
    - * and the flow_set used for fixed-rate queues.
    - *
    - * For WF2Q+ support it also has 3 heaps holding dn_flow_queue:
    - *   not_eligible_heap, for queues whose start time is higher
    - *	than the virtual time. Sorted by start time.
    - *   scheduler_heap, for queues eligible for scheduling. Sorted by
    - *	finish time.
    - *   idle_heap, all flows that are idle and can be removed. We
    - *	do that on each tick so we do not slow down too much
    - *	operations during forwarding.
    - *
    + * dn_flow collects flow_id and stats for queues and scheduler
    + * instances, and is used to pass these info to userland.
    + * oid.type/oid.subtype describe the object, oid.id is number
    + * of the parent object.
      */
    -struct dn_pipe {		/* a pipe */
    -    SLIST_ENTRY(dn_pipe)	next;	/* linked list in a hash slot */
    +struct dn_flow {
    +	struct dn_id	oid;
    +	struct ipfw_flow_id fid;
    +	uint64_t	tot_pkts; /* statistics counters  */
    +	uint64_t	tot_bytes;
    +	uint32_t	length; /* Queue lenght, in packets */
    +	uint32_t	len_bytes; /* Queue lenght, in bytes */
    +	uint32_t	drops;
    +};
     
    -    int	pipe_nr ;		/* number	*/
    -    int bandwidth;		/* really, bytes/tick.	*/
    -    int	delay ;			/* really, ticks	*/
    -
    -    struct	mbuf *head, *tail ;	/* packets in delay line */
    -
    -    /* WF2Q+ */
    -    struct dn_heap scheduler_heap ; /* top extract - key Finish time*/
    -    struct dn_heap not_eligible_heap; /* top extract- key Start time */
    -    struct dn_heap idle_heap ; /* random extract - key Start=Finish time */
    -
    -    dn_key V ;			/* virtual time */
    -    int sum;			/* sum of weights of all active sessions */
    -
    -    /* Same as in dn_flow_queue, numbytes can become large */
    -    int64_t numbytes;		/* bits I can transmit (more or less). */
    -    uint64_t burst;		/* burst size, scaled: bits * hz */
    -
    -    dn_key sched_time ;		/* time pipe was scheduled in ready_heap */
    -    dn_key idle_time;		/* start of pipe idle time */
     
         /*
    -     * When the tx clock come from an interface (if_name[0] != '\0'), its name
    -     * is stored below, whereas the ifp is filled when the rule is configured.
    + * Scheduler template, mostly indicating the name, number,
    + * sched_mask and buckets.
          */
    -    char if_name[IFNAMSIZ];
    -    struct ifnet *ifp ;
    -    int ready ; /* set if ifp != NULL and we got a signal from it */
    +struct dn_sch {
    +	struct dn_id	oid;
    +	uint32_t	sched_nr; /* N, scheduler number */
    +	uint32_t	buckets; /* number of buckets for the instances */
    +	uint32_t	flags;	/* have_mask, ... */
     
    -    struct dn_flow_set fs ; /* used with fixed-rate flows */
    +	char name[16];	/* null terminated */
    +	/* mask to select the appropriate scheduler instance */
    +	struct ipfw_flow_id sched_mask; /* M */
    +};
     
    +
    +/* A delay profile is attached to a link.
    + * Note that a profile, as any other object, cannot be longer than 2^16
    + */
    +#define	ED_MAX_SAMPLES_NO	1024
    +struct dn_profile {
    +	struct dn_id	oid;
         /* fields to simulate a delay profile */
    -
     #define ED_MAX_NAME_LEN		32
         char name[ED_MAX_NAME_LEN];
    +	int		link_nr;
         int loss_level;
    -    int samples_no;
    -    int *samples;
    +	int		bandwidth;	// XXX use link bandwidth?
    +	int		samples_no;	/* actual length of samples[] */
    +	int samples[ED_MAX_SAMPLES_NO]; /* may be shorter */
     };
     
    -/* dn_pipe_max is used to pass pipe configuration from userland onto
    - * kernel space and back
    - */
    -#define ED_MAX_SAMPLES_NO	1024
    -struct dn_pipe_max {
    -	struct dn_pipe pipe;
    -	int samples[ED_MAX_SAMPLES_NO];
    -};
     
    -SLIST_HEAD(dn_pipe_head, dn_pipe);
    -
    -#ifdef _KERNEL
     
     /*
    - * Return the dummynet tag; if any.
    - * Make sure that the dummynet tag is not reused by lower layers.
    + * Overall structure of dummynet
    +
    +In dummynet, packets are selected with the firewall rules, and passed
    +to two different objects: PIPE or QUEUE (bad name).
    +
    +A QUEUE defines a classifier, which groups packets into flows
    +according to a 'mask', puts them into independent queues (one
    +per flow) with configurable size and queue management policy,
    +and passes flows to a scheduler:
    +
    +                 (flow_mask|sched_mask)  sched_mask
    +	 +---------+   weight Wx  +-------------+
    +         |         |->-[flow]-->--|             |-+
    +    -->--| QUEUE x |   ...        |             | |
    +         |         |->-[flow]-->--| SCHEDuler N | |
    +	 +---------+              |             | |
    +	     ...                  |             +--[LINK N]-->--
    +	 +---------+   weight Wy  |             | +--[LINK N]-->--
    +         |         |->-[flow]-->--|             | |
    +    -->--| QUEUE y |   ...        |             | |
    +         |         |->-[flow]-->--|             | |
    +	 +---------+              +-------------+ |
    +	                            +-------------+
    +
    +Many QUEUE objects can connect to the same scheduler, each
    +QUEUE object can have its own set of parameters.
    +
    +In turn, the SCHEDuler 'forks' multiple instances according
    +to a 'sched_mask', each instance manages its own set of queues
    +and transmits on a private instance of a configurable LINK.
    +
    +A PIPE is a simplified version of the above, where there
    +is no flow_mask, and each scheduler instance handles a single queue.
    +
    +The following data structures (visible from userland) describe
    +the objects used by dummynet:
    +
    + + dn_link, contains the main configuration parameters related
    +   to delay and bandwidth;
    + + dn_profile describes a delay profile;
    + + dn_flow describes the flow status (flow id, statistics)
    +   
    + + dn_sch describes a scheduler
    + + dn_fs describes a flowset (msk, weight, queue parameters)
    +
    + *
      */
    -static __inline struct dn_pkt_tag *
    -ip_dn_claim_tag(struct mbuf *m)
    -{
    -	struct m_tag *mtag = m_tag_find(m, PACKET_TAG_DUMMYNET, NULL);
    -	if (mtag != NULL) {
    -		mtag->m_tag_id = PACKET_TAG_NONE;
    -		return ((struct dn_pkt_tag *)(mtag + 1));
    -	} else
    -		return (NULL);
    -}
    -#endif
    +
     #endif /* _IP_DUMMYNET_H */
    diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
    index 1e6feb4d3c1..cf5d8d03a90 100644
    --- a/sys/netinet/ip_fw.h
    +++ b/sys/netinet/ip_fw.h
    @@ -461,7 +461,7 @@ typedef struct _ipfw_insn_icmp6 {
      */
     
     struct ip_fw {
    -	struct ip_fw	*next;		/* linked list of rules		*/
    +	struct ip_fw	*x_next;	/* linked list of rules		*/
     	struct ip_fw	*next_rule;	/* ptr to next [skipto] rule	*/
     	/* 'next_rule' is used to pass up 'set_disable' status		*/
     
    @@ -487,24 +487,29 @@ struct ip_fw {
     #define RULESIZE(rule)  (sizeof(struct ip_fw) + \
     	((struct ip_fw *)(rule))->cmd_len * 4 - 4)
     
    +#if 1 // should be moved to in.h
     /*
      * This structure is used as a flow mask and a flow id for various
      * parts of the code.
    + * addr_type is used in userland and kernel to mark the address type.
    + * fib is used in the kernel to record the fib in use.
    + * _flags is used in the kernel to store tcp flags for dynamic rules.
      */
     struct ipfw_flow_id {
    -	u_int32_t	dst_ip;
    -	u_int32_t	src_ip;
    -	u_int16_t	dst_port;
    -	u_int16_t	src_port;
    -	u_int8_t	fib;
    -	u_int8_t	proto;
    -	u_int8_t	flags;	/* protocol-specific flags */
    -	uint8_t		addr_type; /* 4 = ipv4, 6 = ipv6, 1=ether ? */
    -	struct in6_addr dst_ip6;	/* could also store MAC addr! */
    +	uint32_t	dst_ip;
    +	uint32_t	src_ip;
    +	uint16_t	dst_port;
    +	uint16_t	src_port;
    +	uint8_t		fib;
    +	uint8_t		proto;
    +	uint8_t		_flags;	/* protocol-specific flags */
    +	uint8_t		addr_type; /* 4=ip4, 6=ip6, 1=ether ? */
    +	struct in6_addr dst_ip6;
     	struct in6_addr src_ip6;
    -	u_int32_t	flow_id6;
    -	u_int32_t	frag_id6;
    +	uint32_t	flow_id6;
    +	uint32_t	extra; /* queue/pipe or frag_id */
     };
    +#endif
     
     #define IS_IP6_FLOW_ID(id)	((id)->addr_type == 6)
     
    @@ -571,133 +576,4 @@ typedef struct	_ipfw_table {
     	ipfw_table_entry ent[0];	/* entries			*/
     } ipfw_table;
     
    -/*
    - * Main firewall chains definitions and global var's definitions.
    - */
    -#ifdef _KERNEL
    -
    -#define MTAG_IPFW	1148380143	/* IPFW-tagged cookie */
    -
    -/* Return values from ipfw_chk() */
    -enum {
    -	IP_FW_PASS = 0,
    -	IP_FW_DENY,
    -	IP_FW_DIVERT,
    -	IP_FW_TEE,
    -	IP_FW_DUMMYNET,
    -	IP_FW_NETGRAPH,
    -	IP_FW_NGTEE,
    -	IP_FW_NAT,
    -	IP_FW_REASS,
    -};
    -
    -/* flags for divert mtag */
    -#define	IP_FW_DIVERT_LOOPBACK_FLAG	0x00080000
    -#define	IP_FW_DIVERT_OUTPUT_FLAG	0x00100000
    -
    -/*
    - * Structure for collecting parameters to dummynet for ip6_output forwarding
    - */
    -struct _ip6dn_args {
    -       struct ip6_pktopts *opt_or;
    -       struct route_in6 ro_or;
    -       int flags_or;
    -       struct ip6_moptions *im6o_or;
    -       struct ifnet *origifp_or;
    -       struct ifnet *ifp_or;
    -       struct sockaddr_in6 dst_or;
    -       u_long mtu_or;
    -       struct route_in6 ro_pmtu_or;
    -};
    -
    -/*
    - * Arguments for calling ipfw_chk() and dummynet_io(). We put them
    - * all into a structure because this way it is easier and more
    - * efficient to pass variables around and extend the interface.
    - */
    -struct ip_fw_args {
    -	struct mbuf	*m;		/* the mbuf chain		*/
    -	struct ifnet	*oif;		/* output interface		*/
    -	struct sockaddr_in *next_hop;	/* forward address		*/
    -	struct ip_fw	*rule;		/* matching rule		*/
    -	uint32_t	rule_id;	/* matching rule id */
    -	uint32_t	chain_id;	/* ruleset id */
    -	struct ether_header *eh;	/* for bridged packets		*/
    -
    -	struct ipfw_flow_id f_id;	/* grabbed from IP header	*/
    -	uint32_t	cookie;		/* a cookie depending on rule action */
    -	struct inpcb	*inp;
    -
    -	struct _ip6dn_args	dummypar; /* dummynet->ip6_output */
    -	struct sockaddr_in hopstore;	/* store here if cannot use a pointer */
    -};
    -
    -/*
    - * Function definitions.
    - */
    -
    -/* Firewall hooks */
    -struct sockopt;
    -struct dn_flow_set;
    -
    -int ipfw_check_in(void *, struct mbuf **, struct ifnet *, int, struct inpcb *inp);
    -int ipfw_check_out(void *, struct mbuf **, struct ifnet *, int, struct inpcb *inp);
    -
    -int ipfw_chk(struct ip_fw_args *);
    -
    -int ipfw_hook(void);
    -int ipfw6_hook(void);
    -int ipfw_unhook(void);
    -int ipfw6_unhook(void);
    -#ifdef NOTYET
    -void ipfw_nat_destroy(void);
    -#endif
    -
    -VNET_DECLARE(int, fw_one_pass);
    -VNET_DECLARE(int, fw_enable);
    -#define	V_fw_one_pass		VNET(fw_one_pass)
    -#define	V_fw_enable		VNET(fw_enable)
    -
    -#ifdef INET6
    -VNET_DECLARE(int, fw6_enable);
    -#define	V_fw6_enable		VNET(fw6_enable)
    -#endif
    -
    -struct ip_fw_chain {
    -	struct ip_fw	*rules;		/* list of rules */
    -	struct ip_fw	*reap;		/* list of rules to reap */
    -	LIST_HEAD(, cfg_nat) nat;       /* list of nat entries */
    -	struct radix_node_head *tables[IPFW_TABLES_MAX];
    -	struct rwlock	rwmtx;
    -	uint32_t	id;		/* ruleset id */
    -};
    -
    -#ifdef IPFW_INTERNAL
    -
    -#define	IPFW_LOCK_INIT(_chain) \
    -	rw_init(&(_chain)->rwmtx, "IPFW static rules")
    -#define	IPFW_LOCK_DESTROY(_chain)	rw_destroy(&(_chain)->rwmtx)
    -#define	IPFW_WLOCK_ASSERT(_chain)	rw_assert(&(_chain)->rwmtx, RA_WLOCKED)
    -
    -#define IPFW_RLOCK(p) rw_rlock(&(p)->rwmtx)
    -#define IPFW_RUNLOCK(p) rw_runlock(&(p)->rwmtx)
    -#define IPFW_WLOCK(p) rw_wlock(&(p)->rwmtx)
    -#define IPFW_WUNLOCK(p) rw_wunlock(&(p)->rwmtx)
    -
    -#define LOOKUP_NAT(l, i, p) do {					\
    -		LIST_FOREACH((p), &(l.nat), _next) {			\
    -			if ((p)->id == (i)) {				\
    -				break;					\
    -			} 						\
    -		}							\
    -	} while (0)
    -
    -typedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *);
    -typedef int ipfw_nat_cfg_t(struct sockopt *);
    -#endif
    -
    -VNET_DECLARE(struct ip_fw_chain, layer3_chain);
    -#define	V_layer3_chain		VNET(layer3_chain)
    -
    -#endif /* _KERNEL */
     #endif /* _IPFW2_H */
    diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
    index a1d2166ac3a..d041dd3feb9 100644
    --- a/sys/netinet/ip_var.h
    +++ b/sys/netinet/ip_var.h
    @@ -249,7 +249,43 @@ VNET_DECLARE(struct pfil_head, inet_pfil_hook);	/* packet filter hooks */
     
     void	in_delayed_cksum(struct mbuf *m);
     
    -/* ipfw and dummynet hooks. Most are declared in raw_ip.c */
    +/* Hooks for ipfw, dummynet, divert etc. Most are declared in raw_ip.c */
    +/*
    + * Reference to an ipfw or packet filter rule that can be carried
    + * outside critical sections.
    + * A rule is identified by rulenum:rule_id which is ordered.
    + * In version chain_id the rule can be found in slot 'slot', so
    + * we don't need a lookup if chain_id == chain->id.
    + *
    + * On exit from the firewall this structure refers to the rule after
    + * the matching one (slot points to the new rule; rulenum:rule_id-1
    + * is the matching rule), and additional info (e.g. info often contains
    + * the insn argument or tablearg in the low 16 bits, in host format).
    + * On entry, the structure is valid if slot>0, and refers to the starting
    + * rules. 'info' contains the reason for reinject, e.g. divert port,
    + * divert direction, and so on.
    + */
    +struct ipfw_rule_ref {
    +	uint32_t	slot;		/* slot for matching rule	*/
    +	uint32_t	rulenum;	/* matching rule number		*/
    +	uint32_t	rule_id;	/* matching rule id		*/
    +	uint32_t	chain_id;	/* ruleset id			*/
    +	uint32_t	info;		/* see below			*/
    +};
    +
    +enum {
    +	IPFW_INFO_MASK	= 0x0000ffff,
    +	IPFW_INFO_OUT	= 0x00000000,	/* outgoing, just for convenience */
    +	IPFW_INFO_IN	= 0x80000000,	/* incoming, overloads dir */
    +	IPFW_ONEPASS	= 0x40000000,	/* One-pass, do not reinject */
    +	IPFW_IS_MASK	= 0x30000000,	/* which source ? */
    +	IPFW_IS_DIVERT	= 0x20000000,
    +	IPFW_IS_DUMMYNET =0x10000000,
    +	IPFW_IS_PIPE	= 0x08000000,	/* pip1=1, queue = 0 */
    +};
    +#define MTAG_IPFW	1148380143	/* IPFW-tagged cookie */
    +#define MTAG_IPFW_RULE	1262273568	/* rule reference */
    +
     struct ip_fw_args;
     typedef int	(*ip_fw_chk_ptr_t)(struct ip_fw_args *args);
     typedef int	(*ip_fw_ctl_ptr_t)(struct sockopt *);
    @@ -258,9 +294,14 @@ 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)
     
    +/* Divert hooks. */
    +extern void	(*ip_divert_ptr)(struct mbuf *m, int incoming);
    +/* ng_ipfw hooks -- XXX make it the same as divert and dummynet */
    +extern int	(*ng_ipfw_input_p)(struct mbuf **, int,
    +			struct ip_fw_args *, int);
    +
     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 */
    +extern int	(*ip_dn_io_ptr)(struct mbuf **, int, struct ip_fw_args *);
     
     VNET_DECLARE(int, ip_do_randomid);
     #define	V_ip_do_randomid	VNET(ip_do_randomid)
    diff --git a/sys/netinet/ipfw/dn_heap.c b/sys/netinet/ipfw/dn_heap.c
    new file mode 100644
    index 00000000000..6773851327c
    --- /dev/null
    +++ b/sys/netinet/ipfw/dn_heap.c
    @@ -0,0 +1,550 @@
    +/*-
    + * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
    + * 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.
    + */
    +
    +/*
    + * Binary heap and hash tables, used in dummynet
    + *
    + * $FreeBSD$
    + */
    +
    +#include 
    +#include 
    +#ifdef _KERNEL
    +__FBSDID("$FreeBSD$");
    +#include 
    +#include 
    +#include 
    +#include 
    +#ifndef log
    +#define log(x, arg...)
    +#endif
    +
    +#else /* !_KERNEL */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include  "dn_heap.h"
    +#define log(x, arg...)	fprintf(stderr, ## arg)
    +#define panic(x...)	fprintf(stderr, ## x), exit(1)
    +#define MALLOC_DEFINE(a, b, c)
    +static void *my_malloc(int s) {	return malloc(s); }
    +static void my_free(void *p) {	free(p); }
    +#define malloc(s, t, w)	my_malloc(s)
    +#define free(p, t)	my_free(p)
    +#endif /* !_KERNEL */
    +
    +MALLOC_DEFINE(M_DN_HEAP, "dummynet", "dummynet heap");
    +
    +/*
    + * Heap management functions.
    + *
    + * In the heap, first node is element 0. Children of i are 2i+1 and 2i+2.
    + * Some macros help finding parent/children so we can optimize them.
    + *
    + * heap_init() is called to expand the heap when needed.
    + * Increment size in blocks of 16 entries.
    + * Returns 1 on error, 0 on success
    + */
    +#define HEAP_FATHER(x) ( ( (x) - 1 ) / 2 )
    +#define HEAP_LEFT(x) ( (x)+(x) + 1 )
    +#define	HEAP_SWAP(a, b, buffer) { buffer = a ; a = b ; b = buffer ; }
    +#define HEAP_INCREMENT	15
    +
    +static int
    +heap_resize(struct dn_heap *h, unsigned int new_size)
    +{
    +	struct dn_heap_entry *p;
    +
    +	if (h->size >= new_size )	/* have enough room */
    +		return 0;
    +#if 1  /* round to the next power of 2 */
    +	new_size |= new_size >> 1;
    +	new_size |= new_size >> 2;
    +	new_size |= new_size >> 4;
    +	new_size |= new_size >> 8;
    +	new_size |= new_size >> 16;
    +#else
    +	new_size = (new_size + HEAP_INCREMENT ) & ~HEAP_INCREMENT;
    +#endif
    +	p = malloc(new_size * sizeof(*p), M_DN_HEAP, M_NOWAIT);
    +	if (p == NULL) {
    +		printf("--- %s, resize %d failed\n", __func__, new_size );
    +		return 1; /* error */
    +	}
    +	if (h->size > 0) {
    +		bcopy(h->p, p, h->size * sizeof(*p) );
    +		free(h->p, M_DN_HEAP);
    +	}
    +	h->p = p;
    +	h->size = new_size;
    +	return 0;
    +}
    +
    +int
    +heap_init(struct dn_heap *h, int size, int ofs)
    +{
    +	if (heap_resize(h, size))
    +		return 1;
    +	h->elements = 0;
    +	h->ofs = ofs;
    +	return 0;
    +}
    +
    +/*
    + * Insert element in heap. Normally, p != NULL, we insert p in
    + * a new position and bubble up. If p == NULL, then the element is
    + * already in place, and key is the position where to start the
    + * bubble-up.
    + * Returns 1 on failure (cannot allocate new heap entry)
    + *
    + * If ofs > 0 the position (index, int) of the element in the heap is
    + * also stored in the element itself at the given offset in bytes.
    + */
    +#define SET_OFFSET(h, i) do {					\
    +	if (h->ofs > 0)						\
    +	    *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = i;	\
    +	} while (0)
    +/*
    + * RESET_OFFSET is used for sanity checks. It sets ofs
    + * to an invalid value.
    + */
    +#define RESET_OFFSET(h, i) do {					\
    +	if (h->ofs > 0)						\
    +	    *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = -16;	\
    +	} while (0)
    +
    +int
    +heap_insert(struct dn_heap *h, uint64_t key1, void *p)
    +{
    +	int son = h->elements;
    +
    +	//log("%s key %llu p %p\n", __FUNCTION__, key1, p);
    +	if (p == NULL) { /* data already there, set starting point */
    +		son = key1;
    +	} else { /* insert new element at the end, possibly resize */
    +		son = h->elements;
    +		if (son == h->size) /* need resize... */
    +			// XXX expand by 16 or so
    +			if (heap_resize(h, h->elements+16) )
    +				return 1; /* failure... */
    +		h->p[son].object = p;
    +		h->p[son].key = key1;
    +		h->elements++;
    +	}
    +	/* make sure that son >= father along the path */
    +	while (son > 0) {
    +		int father = HEAP_FATHER(son);
    +		struct dn_heap_entry tmp;
    +
    +		if (DN_KEY_LT( h->p[father].key, h->p[son].key ) )
    +			break; /* found right position */
    +		/* son smaller than father, swap and repeat */
    +		HEAP_SWAP(h->p[son], h->p[father], tmp);
    +		SET_OFFSET(h, son);
    +		son = father;
    +	}
    +	SET_OFFSET(h, son);
    +	return 0;
    +}
    +
    +/*
    + * remove top element from heap, or obj if obj != NULL
    + */
    +void
    +heap_extract(struct dn_heap *h, void *obj)
    +{
    +	int child, father, max = h->elements - 1;
    +
    +	if (max < 0) {
    +		printf("--- %s: empty heap 0x%p\n", __FUNCTION__, h);
    +		return;
    +	}
    +	if (obj == NULL)
    +		father = 0; /* default: move up smallest child */
    +	else { /* extract specific element, index is at offset */
    +		if (h->ofs <= 0)
    +			panic("%s: extract from middle not set on %p\n",
    +				__FUNCTION__, h);
    +		father = *((int *)((char *)obj + h->ofs));
    +		if (father < 0 || father >= h->elements) {
    +			panic("%s: father %d out of bound 0..%d\n",
    +				__FUNCTION__, father, h->elements);
    +		}
    +	}
    +	/*
    +	 * below, father is the index of the empty element, which
    +	 * we replace at each step with the smallest child until we
    +	 * reach the bottom level.
    +	 */
    +	// XXX why removing RESET_OFFSET increases runtime by 10% ?
    +	RESET_OFFSET(h, father);
    +	while ( (child = HEAP_LEFT(father)) <= max ) {
    +		if (child != max &&
    +		    DN_KEY_LT(h->p[child+1].key, h->p[child].key) )
    +			child++; /* take right child, otherwise left */
    +		h->p[father] = h->p[child];
    +		SET_OFFSET(h, father);
    +		father = child;
    +	}
    +	h->elements--;
    +	if (father != max) {
    +		/*
    +		 * Fill hole with last entry and bubble up,
    +		 * reusing the insert code
    +		 */
    +		h->p[father] = h->p[max];
    +		heap_insert(h, father, NULL);
    +	}
    +}
    +
    +#if 0
    +/*
    + * change object position and update references
    + * XXX this one is never used!
    + */
    +static void
    +heap_move(struct dn_heap *h, uint64_t new_key, void *object)
    +{
    +	int temp, i, max = h->elements-1;
    +	struct dn_heap_entry *p, buf;
    +
    +	if (h->ofs <= 0)
    +		panic("cannot move items on this heap");
    +	p = h->p;	/* shortcut */
    +
    +	i = *((int *)((char *)object + h->ofs));
    +	if (DN_KEY_LT(new_key, p[i].key) ) { /* must move up */
    +		p[i].key = new_key;
    +		for (; i>0 &&
    +		    DN_KEY_LT(new_key, p[(temp = HEAP_FATHER(i))].key);
    +		    i = temp ) { /* bubble up */
    +			HEAP_SWAP(p[i], p[temp], buf);
    +			SET_OFFSET(h, i);
    +		}
    +	} else {		/* must move down */
    +		p[i].key = new_key;
    +		while ( (temp = HEAP_LEFT(i)) <= max ) {
    +			/* found left child */
    +			if (temp != max &&
    +			    DN_KEY_LT(p[temp+1].key, p[temp].key))
    +				temp++; /* select child with min key */
    +			if (DN_KEY_LT(>p[temp].key, new_key)) {
    +				/* go down */
    +				HEAP_SWAP(p[i], p[temp], buf);
    +				SET_OFFSET(h, i);
    +			} else
    +				break;
    +			i = temp;
    +		}
    +	}
    +	SET_OFFSET(h, i);
    +}
    +#endif /* heap_move, unused */
    +
    +/*
    + * heapify() will reorganize data inside an array to maintain the
    + * heap property. It is needed when we delete a bunch of entries.
    + */
    +static void
    +heapify(struct dn_heap *h)
    +{
    +	int i;
    +
    +	for (i = 0; i < h->elements; i++ )
    +		heap_insert(h, i , NULL);
    +}
    +
    +int
    +heap_scan(struct dn_heap *h, int (*fn)(void *, uintptr_t),
    +	uintptr_t arg)
    +{
    +	int i, ret, found;
    +
    +	for (i = found = 0 ; i < h->elements ;) {
    +		ret = fn(h->p[i].object, arg);
    +		if (ret & HEAP_SCAN_DEL) {
    +			h->elements-- ;
    +			h->p[i] = h->p[h->elements] ;
    +			found++ ;
    +		} else
    +			i++ ;
    +		if (ret & HEAP_SCAN_END)
    +			break;
    +	}
    +	if (found)
    +		heapify(h);
    +	return found;
    +}
    +
    +/*
    + * cleanup the heap and free data structure
    + */
    +void
    +heap_free(struct dn_heap *h)
    +{
    +	if (h->size >0 )
    +		free(h->p, M_DN_HEAP);
    +	bzero(h, sizeof(*h) );
    +}
    +
    +/*
    + * hash table support.
    + */
    +
    +struct dn_ht {
    +        int buckets;            /* how many buckets, really buckets - 1*/
    +        int entries;            /* how many entries */
    +        int ofs;	        /* offset of link field */
    +        uint32_t (*hash)(uintptr_t, int, void *arg);
    +        int (*match)(void *_el, uintptr_t key, int, void *);
    +        void *(*newh)(uintptr_t, int, void *);
    +        void **ht;              /* bucket heads */
    +};
    +/*
    + * Initialize, allocating bucket pointers inline.
    + * Recycle previous record if possible.
    + * If the 'newh' function is not supplied, we assume that the
    + * key passed to ht_find is the same object to be stored in.
    + */
    +struct dn_ht *
    +dn_ht_init(struct dn_ht *ht, int buckets, int ofs,
    +        uint32_t (*h)(uintptr_t, int, void *),
    +        int (*match)(void *, uintptr_t, int, void *),
    +	void *(*newh)(uintptr_t, int, void *))
    +{
    +	int l;
    +
    +	/*
    +	 * Notes about rounding bucket size to a power of two.
    +	 * Given the original bucket size, we compute the nearest lower and
    +	 * higher power of two, minus 1  (respectively b_min and b_max) because
    +	 * this value will be used to do an AND with the index returned
    +	 * by hash function.
    +	 * To choice between these two values, the original bucket size is
    +	 * compared with b_min. If the original size is greater than 4/3 b_min,
    +	 * we round the bucket size to b_max, else to b_min.
    +	 * This ratio try to round to the nearest power of two, advantaging
    +	 * the greater size if the different between two power is relatively
    +	 * big.
    +	 * Rounding the bucket size to a power of two avoid the use of
    +	 * module when calculating the correct bucket.
    +	 * The ht->buckets variable store the bucket size - 1 to simply
    +	 * do an AND between the index returned by hash function and ht->bucket
    +	 * instead of a module.
    +	 */
    +	int b_min; /* min buckets */
    +	int b_max; /* max buckets */
    +	int b_ori; /* original buckets */
    +
    +	if (h == NULL || match == NULL) {
    +		printf("--- missing hash or match function");
    +		return NULL;
    +	}
    +	if (buckets < 1 || buckets > 65536)
    +		return NULL;
    +
    +	b_ori = buckets;
    +	/* calculate next power of 2, - 1*/
    +	buckets |= buckets >> 1;
    +	buckets |= buckets >> 2;
    +	buckets |= buckets >> 4;
    +	buckets |= buckets >> 8;
    +	buckets |= buckets >> 16;
    +
    +	b_max = buckets; /* Next power */
    +	b_min = buckets >> 1; /* Previous power */
    +
    +	/* Calculate the 'nearest' bucket size */
    +	if (b_min * 4000 / 3000 < b_ori)
    +		buckets = b_max;
    +	else
    +		buckets = b_min;
    +
    +	if (ht) {	/* see if we can reuse */
    +		if (buckets <= ht->buckets) {
    +			ht->buckets = buckets;
    +		} else {
    +			/* free pointers if not allocated inline */
    +			if (ht->ht != (void *)(ht + 1))
    +				free(ht->ht, M_DN_HEAP);
    +			free(ht, M_DN_HEAP);
    +			ht = NULL;
    +		}
    +	}
    +	if (ht == NULL) {
    +		/* Allocate buckets + 1 entries because buckets is use to
    +		 * do the AND with the index returned by hash function
    +		 */
    +		l = sizeof(*ht) + (buckets + 1) * sizeof(void **);
    +		ht = malloc(l, M_DN_HEAP, M_NOWAIT | M_ZERO);
    +	}
    +	if (ht) {
    +		ht->ht = (void **)(ht + 1);
    +		ht->buckets = buckets;
    +		ht->ofs = ofs;
    +		ht->hash = h;
    +		ht->match = match;
    +		ht->newh = newh;
    +	}
    +	return ht;
    +}
    +
    +/* dummy callback for dn_ht_free to unlink all */
    +static int
    +do_del(void *obj, void *arg)
    +{
    +	return DNHT_SCAN_DEL;
    +}
    +
    +void
    +dn_ht_free(struct dn_ht *ht, int flags)
    +{
    +	if (ht == NULL)
    +		return;
    +	if (flags & DNHT_REMOVE) {
    +		(void)dn_ht_scan(ht, do_del, NULL);
    +	} else {
    +		if (ht->ht && ht->ht != (void *)(ht + 1))
    +			free(ht->ht, M_DN_HEAP);
    +		free(ht, M_DN_HEAP);
    +	}
    +}
    +
    +int
    +dn_ht_entries(struct dn_ht *ht)
    +{
    +	return ht ? ht->entries : 0;
    +}
    +
    +/* lookup and optionally create or delete element */
    +void *
    +dn_ht_find(struct dn_ht *ht, uintptr_t key, int flags, void *arg)
    +{
    +	int i;
    +	void **pp, *p;
    +
    +	if (ht == NULL)	/* easy on an empty hash */
    +		return NULL;
    +	i = (ht->buckets == 1) ? 0 :
    +		(ht->hash(key, flags, arg) & ht->buckets);
    +
    +	for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) {
    +		if (flags & DNHT_MATCH_PTR) {
    +			if (key == (uintptr_t)p)
    +				break;
    +		} else if (ht->match(p, key, flags, arg)) /* found match */
    +			break;
    +	}
    +	if (p) {
    +		if (flags & DNHT_REMOVE) {
    +			/* link in the next element */
    +			*pp = *(void **)((char *)p + ht->ofs);
    +			*(void **)((char *)p + ht->ofs) = NULL;
    +			ht->entries--;
    +		}
    +	} else if (flags & DNHT_INSERT) {
    +		// printf("%s before calling new, bucket %d ofs %d\n",
    +		//	__FUNCTION__, i, ht->ofs);
    +		p = ht->newh ? ht->newh(key, flags, arg) : (void *)key;
    +		// printf("%s newh returns %p\n", __FUNCTION__, p);
    +		if (p) {
    +			ht->entries++;
    +			*(void **)((char *)p + ht->ofs) = ht->ht[i];
    +			ht->ht[i] = p;
    +		}
    +	}
    +	return p;
    +}
    +
    +/*
    + * do a scan with the option to delete the object. Extract next before
    + * running the callback because the element may be destroyed there.
    + */
    +int
    +dn_ht_scan(struct dn_ht *ht, int (*fn)(void *, void *), void *arg)
    +{
    +	int i, ret, found = 0;
    +	void **curp, *cur, *next;
    +
    +	if (ht == NULL || fn == NULL)
    +		return 0;
    +	for (i = 0; i <= ht->buckets; i++) {
    +		curp = &ht->ht[i];
    +		while ( (cur = *curp) != NULL) {
    +			next = *(void **)((char *)cur + ht->ofs);
    +			ret = fn(cur, arg);
    +			if (ret & DNHT_SCAN_DEL) {
    +				found++;
    +				ht->entries--;
    +				*curp = next;
    +			} else {
    +				curp = (void **)((char *)cur + ht->ofs);
    +			}
    +			if (ret & DNHT_SCAN_END)
    +				return found;
    +		}
    +	}
    +	return found;
    +}
    +
    +/*
    + * Similar to dn_ht_scan(), except thah the scan is performed only
    + * in the bucket 'bucket'. The function returns a correct bucket number if
    + * the original is invalid
    + */
    +int
    +dn_ht_scan_bucket(struct dn_ht *ht, int *bucket, int (*fn)(void *, void *),
    +		 void *arg)
    +{
    +	int i, ret, found = 0;
    +	void **curp, *cur, *next;
    +
    +	if (ht == NULL || fn == NULL)
    +		return 0;
    +	if (*bucket > ht->buckets)
    +		*bucket = 0;
    +	i = *bucket;
    +
    +	curp = &ht->ht[i];
    +	while ( (cur = *curp) != NULL) {
    +		next = *(void **)((char *)cur + ht->ofs);
    +		ret = fn(cur, arg);
    +		if (ret & DNHT_SCAN_DEL) {
    +			found++;
    +			ht->entries--;
    +			*curp = next;
    +		} else {
    +			curp = (void **)((char *)cur + ht->ofs);
    +		}
    +		if (ret & DNHT_SCAN_END)
    +			return found;
    +	}
    +	return found;
    +}
    +
    diff --git a/sys/netinet/ipfw/dn_heap.h b/sys/netinet/ipfw/dn_heap.h
    new file mode 100644
    index 00000000000..c95473ade39
    --- /dev/null
    +++ b/sys/netinet/ipfw/dn_heap.h
    @@ -0,0 +1,191 @@
    +/*-
    + * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa
    + * 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.
    + */
    +
    +/*
    + * Binary heap and hash tables, header file
    + *
    + * $FreeBSD$
    + */
    +
    +#ifndef _IP_DN_HEAP_H
    +#define _IP_DN_HEAP_H
    +
    +#define DN_KEY_LT(a,b)     ((int64_t)((a)-(b)) < 0)
    +#define DN_KEY_LEQ(a,b)    ((int64_t)((a)-(b)) <= 0)
    +
    +/*
    + * This module implements a binary heap supporting random extraction.
    + *
    + * A heap entry contains an uint64_t key and a pointer to object.
    + * DN_KEY_LT(a,b) returns true if key 'a' is smaller than 'b'
    + *
    + * The heap is a struct dn_heap plus a dynamically allocated
    + * array of dn_heap_entry entries. 'size' represents the size of
    + * the array, 'elements' count entries in use. The topmost
    + * element has the smallest key.
    + * The heap supports ordered insert, and extract from the top.
    + * To extract an object from the middle of the heap, we the object
    + * must reserve an 'int32_t' to store the position of the object
    + * in the heap itself, and the location of this field must be
    + * passed as an argument to heap_init() -- use -1 if the feature
    + * is not used.
    + */
    +struct dn_heap_entry {
    +	uint64_t key;	/* sorting key, smallest comes first */
    +	void *object;	/* object pointer */
    +};
    +
    +struct dn_heap {
    +	int size;	/* the size of the array */
    +	int elements;	/* elements in use */
    +	int ofs;	/* offset in the object of heap index */
    +	struct dn_heap_entry *p;	/* array of "size" entries */
    +};
    +
    +enum {
    +	HEAP_SCAN_DEL = 1,
    +	HEAP_SCAN_END = 2,
    +};
    +
    +/*
    + * heap_init() reinitializes the heap setting the size and the offset
    + *	of the index for random extraction (use -1 if not used).
    + *	The 'elements' counter is set to 0.
    + *
    + * SET_HEAP_OFS() indicates where, in the object, is stored the index
    + *	for random extractions from the heap.
    + *
    + * heap_free() frees the memory associated to a heap.
    + *
    + * heap_insert() adds a key-pointer pair to the heap
    + *
    + * HEAP_TOP() returns a pointer to the top element of the heap,
    + *	but makes no checks on its existance (XXX should we change ?)
    + *
    + * heap_extract() removes the entry at the top, returing the pointer.
    + *	(the key should have been read before).
    + *
    + * heap_scan() invokes a callback on each entry of the heap.
    + *	The callback can return a combination of HEAP_SCAN_DEL and
    + *	HEAP_SCAN_END. HEAP_SCAN_DEL means the current element must
    + *	be removed, and HEAP_SCAN_END means to terminate the scan.
    + *	heap_scan() returns the number of elements removed.
    + *	Because the order is not guaranteed, we should use heap_scan()
    + *	only as a last resort mechanism.
    + */
    +#define HEAP_TOP(h)	((h)->p)
    +#define SET_HEAP_OFS(h, n)	do { (h)->ofs = n; } while (0)
    +int     heap_init(struct dn_heap *h, int size, int ofs);
    +int     heap_insert(struct dn_heap *h, uint64_t key1, void *p);
    +void    heap_extract(struct dn_heap *h, void *obj);
    +void heap_free(struct dn_heap *h);
    +int heap_scan(struct dn_heap *, int (*)(void *, uintptr_t), uintptr_t);
    +
    +/*------------------------------------------------------
    + * This module implements a generic hash table with support for
    + * running callbacks on the entire table. To avoid allocating
    + * memory during hash table operations, objects must reserve
    + * space for a link field. XXX if the heap is moderately full,
    + * an SLIST suffices, and we can tolerate the cost of a hash
    + * computation on each removal.
    + *
    + * dn_ht_init() initializes the table, setting the number of
    + *	buckets, the offset of the link field, the main callbacks.
    + *	Callbacks are:
    + * 
    + *	hash(key, flags, arg) called to return a bucket index.
    + *	match(obj, key, flags, arg) called to determine if key
    + *		matches the current 'obj' in the heap
    + *	newh(key, flags, arg) optional, used to allocate a new
    + *		object during insertions.
    + *
    + * dn_ht_free() frees the heap or unlink elements.
    + *	DNHT_REMOVE unlink elements, 0 frees the heap.
    + *	You need two calls to do both.
    + *
    + * dn_ht_find() is the main lookup function, which can also be
    + *	used to insert or delete elements in the hash table.
    + *	The final 'arg' is passed to all callbacks.
    + *
    + * dn_ht_scan() is used to invoke a callback on all entries of
    + *	the heap, or possibly on just one bucket. The callback
    + *	is invoked with a pointer to the object, and must return
    + *	one of DNHT_SCAN_DEL or DNHT_SCAN_END to request the
    + *	removal of the object from the heap and the end of the
    + *	scan, respectively.
    + *
    + * dn_ht_scan_bucket() is similar to dn_ht_scan(), except that it scans
    + *	only the specific bucket of the table. The bucket is a in-out
    + *	parameter and return a valid bucket number if the original
    + *	is invalid.
    + *
    + * A combination of flags can be used to modify the operation
    + * of the dn_ht_find(), and of the callbacks:
    + *
    + * DNHT_KEY_IS_OBJ	means the key is the object pointer.
    + *	It is usally of interest for the hash and match functions.
    + *
    + * DNHT_MATCH_PTR	during a lookup, match pointers instead
    + *	of calling match(). Normally used when removing specific
    + *	entries. Does not imply KEY_IS_OBJ as the latter _is_ used
    + *	by the match function.
    + *
    + * DNHT_INSERT		insert the element if not found.
    + *	Calls new() to allocates a new object unless
    + *	DNHT_KEY_IS_OBJ is set.
    + *
    + * DNHT_UNIQUE		only insert if object not found.
    + *	XXX should it imply DNHT_INSERT ?
    + *
    + * DNHT_REMOVE		remove objects if we find them.
    + */
    +struct dn_ht;	/* should be opaque */
    +
    +struct dn_ht *dn_ht_init(struct dn_ht *, int buckets, int ofs, 
    +        uint32_t (*hash)(uintptr_t, int, void *),
    +        int (*match)(void *, uintptr_t, int, void *),
    +        void *(*newh)(uintptr_t, int, void *));
    +void dn_ht_free(struct dn_ht *, int flags);
    +
    +void *dn_ht_find(struct dn_ht *, uintptr_t, int, void *);
    +int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *);
    +int dn_ht_scan_bucket(struct dn_ht *, int * , int (*)(void *, void *), void *);
    +int dn_ht_entries(struct dn_ht *);
    +
    +enum {  /* flags values.
    +	 * first two are returned by the scan callback to indicate
    +	 * to delete the matching element or to end the scan
    +	 */
    +        DNHT_SCAN_DEL	= 0x0001,
    +        DNHT_SCAN_END	= 0x0002,
    +        DNHT_KEY_IS_OBJ	= 0x0004,	/* key is the obj pointer */
    +        DNHT_MATCH_PTR	= 0x0008,	/* match by pointer, not match() */
    +        DNHT_INSERT	= 0x0010,	/* insert if not found */
    +        DNHT_UNIQUE	= 0x0020,	/* report error if already there */
    +        DNHT_REMOVE	= 0x0040,	/* remove on find or dn_ht_free */
    +}; 
    +
    +#endif /* _IP_DN_HEAP_H */
    diff --git a/sys/netinet/ipfw/dn_sched.h b/sys/netinet/ipfw/dn_sched.h
    new file mode 100644
    index 00000000000..fe54b0205cf
    --- /dev/null
    +++ b/sys/netinet/ipfw/dn_sched.h
    @@ -0,0 +1,189 @@
    +/*
    + * Copyright (c) 2010 Riccardo Panicucci, Luigi Rizzo, Universita` di Pisa
    + * 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 API to write a packet scheduling algorithm for dummynet.
    + *
    + * $FreeBSD$
    + */
    +
    +#ifndef _DN_SCHED_H
    +#define _DN_SCHED_H
    +
    +#define	DN_MULTIQUEUE	0x01
    +/*
    + * Descriptor for a scheduling algorithm.
    + * Contains all function pointers for a given scheduler
    + * This is typically created when a module is loaded, and stored
    + * in a global list of schedulers.
    + */
    +struct dn_alg {
    +	uint32_t type;           /* the scheduler type */
    +	const char *name;   /* scheduler name */
    +	uint32_t flags;	/* DN_MULTIQUEUE if supports multiple queues */
    +
    +	/*
    +	 * The following define the size of 3 optional data structures
    +	 * that may need to be allocated at runtime, and are appended
    +	 * to each of the base data structures: scheduler, sched.inst,
    +	 * and queue. We don't have a per-flowset structure.
    +	 */
    +	/*    + parameters attached to the template, e.g.
    +	 *	default queue sizes, weights, quantum size, and so on;
    +	 */
    +	size_t schk_datalen;
    +
    +	/*    + per-instance parameters, such as timestamps,
    +	 *	containers for queues, etc;
    +	 */
    +	size_t si_datalen;
    +
    +	size_t q_datalen;	/* per-queue parameters (e.g. S,F) */
    +
    +	/*
    +	 * Methods implemented by the scheduler:
    +	 * enqueue	enqueue packet 'm' on scheduler 's', queue 'q'.
    +	 *	q is NULL for !MULTIQUEUE.
    +	 *	Return 0 on success, 1 on drop (packet consumed anyways).
    +	 *	Note that q should be interpreted only as a hint
    +	 *	on the flow that the mbuf belongs to: while a
    +	 *	scheduler will normally enqueue m into q, it is ok
    +	 *	to leave q alone and put the mbuf elsewhere.
    +	 *	This function is called in two cases:
    +	 *	 - when a new packet arrives to the scheduler;
    +	 *	 - when a scheduler is reconfigured. In this case the
    +	 *	   call is issued by the new_queue callback, with a 
    +	 *	   non empty queue (q) and m pointing to the first
    +	 *	   mbuf in the queue. For this reason, the function
    +	 *	   should internally check for (m != q->mq.head)
    +	 *	   before calling dn_enqueue().
    +	 *
    +	 * dequeue	Called when scheduler instance 's' can
    +	 *	dequeue a packet. Return NULL if none are available.
    +	 *	XXX what about non work-conserving ?
    +	 *
    +	 * config	called on 'sched X config ...', normally writes
    +	 *	in the area of size sch_arg
    +	 *
    +	 * destroy	called on 'sched delete', frees everything
    +	 *	in sch_arg (other parts are handled by more specific
    +	 *	functions)
    +	 *
    +	 * new_sched    called when a new instance is created, e.g.
    +	 *	to create the local queue for !MULTIQUEUE, set V or
    +	 *	copy parameters for WFQ, and so on.
    +	 *
    +	 * free_sched	called when deleting an instance, cleans
    +	 *	extra data in the per-instance area.
    +	 *
    +	 * new_fsk	called when a flowset is linked to a scheduler,
    +	 *	e.g. to validate parameters such as weights etc.
    +	 * free_fsk	when a flowset is unlinked from a scheduler.
    +	 *	(probably unnecessary)
    +	 *
    +	 * new_queue	called to set the per-queue parameters,
    +	 *	e.g. S and F, adjust sum of weights in the parent, etc.
    +	 *
    +	 *	The new_queue callback is normally called from when
    +	 *	creating a new queue. In some cases (such as a
    +	 *	scheduler change or reconfiguration) it can be called
    +	 *	with a non empty queue. In this case, the queue
    +	 *	In case of non empty queue, the new_queue callback could
    +	 *	need to call the enqueue function. In this case,
    +	 *	the callback should eventually call enqueue() passing
    +	 *	as m the first element in the queue.
    +	 *
    +	 * free_queue	actions related to a queue removal, e.g. undo
    +	 *	all the above. If the queue has data in it, also remove
    +	 *	from the scheduler. This can e.g. happen during a reconfigure.
    +	 */
    +	int (*enqueue)(struct dn_sch_inst *, struct dn_queue *,
    +		struct mbuf *);
    +	struct mbuf * (*dequeue)(struct dn_sch_inst *);
    +
    +	int (*config)(struct dn_schk *);
    +	int (*destroy)(struct dn_schk*);
    +	int (*new_sched)(struct dn_sch_inst *);
    +	int (*free_sched)(struct dn_sch_inst *);
    +	int (*new_fsk)(struct dn_fsk *f);
    +	int (*free_fsk)(struct dn_fsk *f);
    +	int (*new_queue)(struct dn_queue *q);
    +	int (*free_queue)(struct dn_queue *q);
    +
    +	/* run-time fields */
    +	int ref_count;      /* XXX number of instances in the system */
    +	SLIST_ENTRY(dn_alg) next; /* Next scheduler in the list */
    +};
    +
    +/* MSVC does not support initializers so we need this ugly macro */
    +#ifdef _WIN32
    +#define _SI(fld)        
    +#else
    +#define _SI(fld)        fld
    +#endif
    +
    +/*
    + * Additionally, dummynet exports some functions and macros
    + * to be used by schedulers:
    + */
    +
    +void dn_free_pkts(struct mbuf *mnext);
    +int dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop);
    +/* bound a variable between min and max */
    +int ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg);
    +
    +/*
    + * Extract the head of a queue, update stats. Must be the very last
    + * thing done on a dequeue as the queue itself may go away.
    + */
    +static __inline struct mbuf*
    +dn_dequeue(struct dn_queue *q)
    +{
    +	struct mbuf *m = q->mq.head;
    +	if (m == NULL)
    +		return NULL;
    +	q->mq.head = m->m_nextpkt;
    +	q->ni.length--;
    +	q->ni.len_bytes -= m->m_pkthdr.len;
    +	if (q->_si) {
    +		q->_si->ni.length--;
    +		q->_si->ni.len_bytes -= m->m_pkthdr.len;
    +	}
    +	if (q->ni.length == 0) /* queue is now idle */
    +		q->q_time = dn_cfg.curr_time;
    +	return m;
    +}
    +
    +int dn_sched_modevent(module_t mod, int cmd, void *arg);
    +
    +#define DECLARE_DNSCHED_MODULE(name, dnsched)			\
    +	static moduledata_t name##_mod = {			\
    +		#name, dn_sched_modevent, dnsched		\
    +	};							\
    +	DECLARE_MODULE(name, name##_mod, 			\
    +		SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); 	\
    +        MODULE_DEPEND(name, dummynet, 3, 3, 3);
    +#endif /* _DN_SCHED_H */
    diff --git a/sys/netinet/ipfw/dn_sched_fifo.c b/sys/netinet/ipfw/dn_sched_fifo.c
    new file mode 100644
    index 00000000000..0bb3800a9c2
    --- /dev/null
    +++ b/sys/netinet/ipfw/dn_sched_fifo.c
    @@ -0,0 +1,120 @@
    +/*
    + * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
    + * 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$
    + */
    +
    +#ifdef _KERNEL
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 	/* IFNAMSIZ */
    +#include 
    +#include 		/* ipfw_rule_ref */
    +#include 	/* flow_id */
    +#include 
    +#include 
    +#include 
    +#include 
    +#else
    +#include 
    +#endif
    +
    +/*
    + * This file implements a FIFO scheduler for a single queue.
    + * The queue is allocated as part of the scheduler instance,
    + * and there is a single flowset is in the template which stores
    + * queue size and policy.
    + * Enqueue and dequeue use the default library functions.
    + */
    +static int 
    +fifo_enqueue(struct dn_sch_inst *si, struct dn_queue *q, struct mbuf *m)
    +{
    +	/* XXX if called with q != NULL and m=NULL, this is a
    +	 * re-enqueue from an existing scheduler, which we should
    +	 * handle.
    +	 */
    +	return dn_enqueue((struct dn_queue *)(si+1), m, 0);
    +}
    +
    +static struct mbuf *
    +fifo_dequeue(struct dn_sch_inst *si)
    +{
    +	return dn_dequeue((struct dn_queue *)(si + 1));
    +}
    +
    +static int
    +fifo_new_sched(struct dn_sch_inst *si)
    +{
    +	/* This scheduler instance contains the queue */
    +	struct dn_queue *q = (struct dn_queue *)(si + 1);
    +
    +        set_oid(&q->ni.oid, DN_QUEUE, sizeof(*q));
    +	q->_si = si;
    +	q->fs = si->sched->fs;
    +	return 0;
    +}
    +
    +static int
    +fifo_free_sched(struct dn_sch_inst *si)
    +{
    +	struct dn_queue *q = (struct dn_queue *)(si + 1);
    +	dn_free_pkts(q->mq.head);
    +	bzero(q, sizeof(*q));
    +	return 0;
    +}
    +
    +/*
    + * FIFO scheduler descriptor
    + * contains the type of the scheduler, the name, the size of extra
    + * data structures, and function pointers.
    + */
    +static struct dn_alg fifo_desc = {
    +	_SI( .type = )  DN_SCHED_FIFO,
    +	_SI( .name = )  "FIFO",
    +	_SI( .flags = ) 0,
    +
    +	_SI( .schk_datalen = ) 0,
    +	_SI( .si_datalen = )  sizeof(struct dn_queue),
    +	_SI( .q_datalen = )  0,
    +
    +	_SI( .enqueue = )  fifo_enqueue,
    +	_SI( .dequeue = )  fifo_dequeue,
    +	_SI( .config = )  NULL,
    +	_SI( .destroy = )  NULL,
    +	_SI( .new_sched = )  fifo_new_sched,
    +	_SI( .free_sched = )  fifo_free_sched,
    +	_SI( .new_fsk = )  NULL,
    +	_SI( .free_fsk = )  NULL,
    +	_SI( .new_queue = )  NULL,
    +	_SI( .free_queue = )  NULL,
    +};
    +
    +DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc);
    diff --git a/sys/netinet/ipfw/dn_sched_qfq.c b/sys/netinet/ipfw/dn_sched_qfq.c
    new file mode 100644
    index 00000000000..44555ee09e2
    --- /dev/null
    +++ b/sys/netinet/ipfw/dn_sched_qfq.c
    @@ -0,0 +1,864 @@
    +/*
    + * Copyright (c) 2010 Fabio Checconi, Luigi Rizzo, Paolo Valente
    + * 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$
    + */
    +
    +#ifdef _KERNEL
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 	/* IFNAMSIZ */
    +#include 
    +#include 		/* ipfw_rule_ref */
    +#include 	/* flow_id */
    +#include 
    +#include 
    +#include 
    +#include 
    +#else
    +#include 
    +#endif
    +
    +#ifdef QFQ_DEBUG
    +struct qfq_sched;
    +static void dump_sched(struct qfq_sched *q, const char *msg);
    +#define	NO(x)	x
    +#else
    +#define NO(x)
    +#endif
    +#define DN_SCHED_QFQ	4 // XXX Where?
    +typedef	unsigned long	bitmap;
    +
    +/*
    + * bitmaps ops are critical. Some linux versions have __fls
    + * and the bitmap ops. Some machines have ffs
    + */
    +#if defined(_WIN32)
    +int fls(unsigned int n)
    +{
    +	int i = 0;
    +	for (i = 0; n > 0; n >>= 1, i++)
    +		;
    +	return i;
    +}
    +#endif
    +
    +#if !defined(_KERNEL) || defined( __FreeBSD__ ) || defined(_WIN32)
    +static inline unsigned long __fls(unsigned long word)
    +{
    +	return fls(word) - 1;
    +}
    +#endif
    +
    +#if !defined(_KERNEL) || !defined(__linux__)
    +#ifdef QFQ_DEBUG
    +int test_bit(int ix, bitmap *p)
    +{
    +	if (ix < 0 || ix > 31)
    +		D("bad index %d", ix);
    +	return *p & (1< 31)
    +		D("bad index %d", ix);
    +	*p |= (1< 31)
    +		D("bad index %d", ix);
    +	*p &= ~(1<index = 0
    +  				 *.__grp->slot_shift
    +  
    +   where MIN_SLOT_SHIFT is derived by difference from the others.
    +
    +The max group index corresponds to Lmax/w_min, where
    +Lmax=1<group mapping. Class weights are
    + * in the range [1, QFQ_MAX_WEIGHT], we to map each class i to the
    + * group with the smallest index that can support the L_i / r_i
    + * configured for the class.
    + *
    + * grp->index is the index of the group; and grp->slot_shift
    + * is the shift for the corresponding (scaled) sigma_i.
    + *
    + * When computing the group index, we do (len<i_wsum)
    +#define IWSUM	((1< 0;
    +}
    +
    +/* Round a precise timestamp to its slotted value. */
    +static inline uint64_t qfq_round_down(uint64_t ts, unsigned int shift)
    +{
    +	return ts & ~((1ULL << shift) - 1);
    +}
    +
    +/* return the pointer to the group with lowest index in the bitmap */
    +static inline struct qfq_group *qfq_ffs(struct qfq_sched *q,
    +					unsigned long bitmap)
    +{
    +	int index = ffs(bitmap) - 1; // zero-based
    +	return &q->groups[index];
    +}
    +
    +/*
    + * Calculate a flow index, given its weight and maximum packet length.
    + * index = log_2(maxlen/weight) but we need to apply the scaling.
    + * This is used only once at flow creation.
    + */
    +static int qfq_calc_index(uint32_t inv_w, unsigned int maxlen)
    +{
    +	uint64_t slot_size = (uint64_t)maxlen *inv_w;
    +	unsigned long size_map;
    +	int index = 0;
    +
    +	size_map = (unsigned long)(slot_size >> QFQ_MIN_SLOT_SHIFT);
    +	if (!size_map)
    +		goto out;
    +
    +	index = __fls(size_map) + 1;	// basically a log_2()
    +	index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1)));
    +
    +	if (index < 0)
    +		index = 0;
    +
    +out:
    +	ND("W = %d, L = %d, I = %d\n", ONE_FP/inv_w, maxlen, index);
    +	return index;
    +}
    +/*---- end support functions ----*/
    +
    +/*-------- API calls --------------------------------*/
    +/*
    + * Validate and copy parameters from flowset.
    + */
    +static int
    +qfq_new_queue(struct dn_queue *_q)
    +{
    +	struct qfq_sched *q = (struct qfq_sched *)(_q->_si + 1);
    +	struct qfq_class *cl = (struct qfq_class *)_q;
    +	int i;
    +	uint32_t w;	/* approximated weight */
    +
    +	/* import parameters from the flowset. They should be correct
    +	 * already.
    +	 */
    +	w = _q->fs->fs.par[0];
    +	cl->lmax = _q->fs->fs.par[1];
    +	if (!w || w > QFQ_MAX_WEIGHT) {
    +		w = 1;
    +		D("rounding weight to 1");
    +	}
    +	cl->inv_w = ONE_FP/w;
    +	w = ONE_FP/cl->inv_w;	
    +	if (q->wsum + w > QFQ_MAX_WSUM)
    +		return EINVAL;
    +
    +	i = qfq_calc_index(cl->inv_w, cl->lmax);
    +	cl->grp = &q->groups[i];
    +	q->wsum += w;
    +	// XXX cl->S = q->V; ?
    +	// XXX compute q->i_wsum
    +	return 0;
    +}
    +
    +/* remove an empty queue */
    +static int
    +qfq_free_queue(struct dn_queue *_q)
    +{
    +	struct qfq_sched *q = (struct qfq_sched *)(_q->_si + 1);
    +	struct qfq_class *cl = (struct qfq_class *)_q;
    +	if (cl->inv_w) {
    +		q->wsum -= ONE_FP/cl->inv_w;
    +		cl->inv_w = 0; /* reset weight to avoid run twice */
    +	}
    +	return 0;
    +}
    +
    +/* Calculate a mask to mimic what would be ffs_from(). */
    +static inline unsigned long
    +mask_from(unsigned long bitmap, int from)
    +{
    +	return bitmap & ~((1UL << from) - 1);
    +}
    +
    +/*
    + * The state computation relies on ER=0, IR=1, EB=2, IB=3
    + * First compute eligibility comparing grp->S, q->V,
    + * then check if someone is blocking us and possibly add EB
    + */
    +static inline unsigned int
    +qfq_calc_state(struct qfq_sched *q, struct qfq_group *grp)
    +{
    +	/* if S > V we are not eligible */
    +	unsigned int state = qfq_gt(grp->S, q->V);
    +	unsigned long mask = mask_from(q->bitmaps[ER], grp->index);
    +	struct qfq_group *next;
    +
    +	if (mask) {
    +		next = qfq_ffs(q, mask);
    +		if (qfq_gt(grp->F, next->F))
    +			state |= EB;
    +	}
    +
    +	return state;
    +}
    +
    +/*
    + * In principle
    + *	q->bitmaps[dst] |= q->bitmaps[src] & mask;
    + *	q->bitmaps[src] &= ~mask;
    + * but we should make sure that src != dst
    + */
    +static inline void
    +qfq_move_groups(struct qfq_sched *q, unsigned long mask, int src, int dst)
    +{
    +	q->bitmaps[dst] |= q->bitmaps[src] & mask;
    +	q->bitmaps[src] &= ~mask;
    +}
    +
    +static inline void
    +qfq_unblock_groups(struct qfq_sched *q, int index, uint64_t old_finish)
    +{
    +	unsigned long mask = mask_from(q->bitmaps[ER], index + 1);
    +	struct qfq_group *next;
    +
    +	if (mask) {
    +		next = qfq_ffs(q, mask);
    +		if (!qfq_gt(next->F, old_finish))
    +			return;
    +	}
    +
    +	mask = (1UL << index) - 1;
    +	qfq_move_groups(q, mask, EB, ER);
    +	qfq_move_groups(q, mask, IB, IR);
    +}
    +
    +/*
    + * perhaps
    + *
    +	old_V ^= q->V;
    +	old_V >>= QFQ_MIN_SLOT_SHIFT;
    +	if (old_V) {
    +		...
    +	}
    + *
    + */
    +static inline void
    +qfq_make_eligible(struct qfq_sched *q, uint64_t old_V)
    +{
    +	unsigned long mask, vslot, old_vslot;
    +
    +	vslot = q->V >> QFQ_MIN_SLOT_SHIFT;
    +	old_vslot = old_V >> QFQ_MIN_SLOT_SHIFT;
    +
    +	if (vslot != old_vslot) {
    +		mask = (2UL << (__fls(vslot ^ old_vslot))) - 1;
    +		qfq_move_groups(q, mask, IR, ER);
    +		qfq_move_groups(q, mask, IB, EB);
    +	}
    +}
    +
    +/*
    + * XXX we should make sure that slot becomes less than 32.
    + * This is guaranteed by the input values.
    + * roundedS is always cl->S rounded on grp->slot_shift bits.
    + */
    +static inline void
    +qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, uint64_t roundedS)
    +{
    +	uint64_t slot = (roundedS - grp->S) >> grp->slot_shift;
    +	unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS;
    +
    +	cl->next = grp->slots[i];
    +	grp->slots[i] = cl;
    +	__set_bit(slot, &grp->full_slots);
    +}
    +
    +/*
    + * remove the entry from the slot
    + */
    +static inline void
    +qfq_front_slot_remove(struct qfq_group *grp)
    +{
    +	struct qfq_class **h = &grp->slots[grp->front];
    +
    +	*h = (*h)->next;
    +	if (!*h)
    +		__clear_bit(0, &grp->full_slots);
    +}
    +
    +/*
    + * Returns the first full queue in a group. As a side effect,
    + * adjust the bucket list so the first non-empty bucket is at
    + * position 0 in full_slots.
    + */
    +static inline struct qfq_class *
    +qfq_slot_scan(struct qfq_group *grp)
    +{
    +	int i;
    +
    +	ND("grp %d full %x", grp->index, grp->full_slots);
    +	if (!grp->full_slots)
    +		return NULL;
    +
    +	i = ffs(grp->full_slots) - 1; // zero-based
    +	if (i > 0) {
    +		grp->front = (grp->front + i) % QFQ_MAX_SLOTS;
    +		grp->full_slots >>= i;
    +	}
    +
    +	return grp->slots[grp->front];
    +}
    +
    +/*
    + * adjust the bucket list. When the start time of a group decreases,
    + * we move the index down (modulo QFQ_MAX_SLOTS) so we don't need to
    + * move the objects. The mask of occupied slots must be shifted
    + * because we use ffs() to find the first non-empty slot.
    + * This covers decreases in the group's start time, but what about
    + * increases of the start time ?
    + * Here too we should make sure that i is less than 32
    + */
    +static inline void
    +qfq_slot_rotate(struct qfq_sched *q, struct qfq_group *grp, uint64_t roundedS)
    +{
    +	unsigned int i = (grp->S - roundedS) >> grp->slot_shift;
    +
    +	grp->full_slots <<= i;
    +	grp->front = (grp->front - i) % QFQ_MAX_SLOTS;
    +}
    +
    +
    +static inline void
    +qfq_update_eligible(struct qfq_sched *q, uint64_t old_V)
    +{
    +	bitmap ineligible;
    +
    +	ineligible = q->bitmaps[IR] | q->bitmaps[IB];
    +	if (ineligible) {
    +		if (!q->bitmaps[ER]) {
    +			struct qfq_group *grp;
    +			grp = qfq_ffs(q, ineligible);
    +			if (qfq_gt(grp->S, q->V))
    +				q->V = grp->S;
    +		}
    +		qfq_make_eligible(q, old_V);
    +	}
    +}
    +
    +/*
    + * Updates the class, returns true if also the group needs to be updated.
    + */
    +static inline int
    +qfq_update_class(struct qfq_sched *q, struct qfq_group *grp,
    +	    struct qfq_class *cl)
    +{
    +
    +	cl->S = cl->F;
    +	if (cl->_q.mq.head == NULL)  {
    +		qfq_front_slot_remove(grp);
    +	} else {
    +		unsigned int len;
    +		uint64_t roundedS;
    +
    +		len = cl->_q.mq.head->m_pkthdr.len;
    +		cl->F = cl->S + (uint64_t)len * cl->inv_w;
    +		roundedS = qfq_round_down(cl->S, grp->slot_shift);
    +		if (roundedS == grp->S)
    +			return 0;
    +
    +		qfq_front_slot_remove(grp);
    +		qfq_slot_insert(grp, cl, roundedS);
    +	}
    +	return 1;
    +}
    +
    +static struct mbuf *
    +qfq_dequeue(struct dn_sch_inst *si)
    +{
    +	struct qfq_sched *q = (struct qfq_sched *)(si + 1);
    +	struct qfq_group *grp;
    +	struct qfq_class *cl;
    +	struct mbuf *m;
    +	uint64_t old_V;
    +
    +	NO(q->loops++;)
    +	if (!q->bitmaps[ER]) {
    +		NO(if (q->queued)
    +			dump_sched(q, "start dequeue");)
    +		return NULL;
    +	}
    +
    +	grp = qfq_ffs(q, q->bitmaps[ER]);
    +
    +	cl = grp->slots[grp->front];
    +	/* extract from the first bucket in the bucket list */
    +	m = dn_dequeue(&cl->_q);
    +
    +	if (!m) {
    +		D("BUG/* non-workconserving leaf */");
    +		return NULL;
    +	}
    +	NO(q->queued--;)
    +	old_V = q->V;
    +	q->V += (uint64_t)m->m_pkthdr.len * IWSUM;
    +	ND("m is %p F 0x%llx V now 0x%llx", m, cl->F, q->V);
    +
    +	if (qfq_update_class(q, grp, cl)) {
    +		uint64_t old_F = grp->F;
    +		cl = qfq_slot_scan(grp);
    +		if (!cl) { /* group gone, remove from ER */
    +			__clear_bit(grp->index, &q->bitmaps[ER]);
    +			// grp->S = grp->F + 1; // XXX debugging only
    +		} else {
    +			uint64_t roundedS = qfq_round_down(cl->S, grp->slot_shift);
    +			unsigned int s;
    +
    +			if (grp->S == roundedS)
    +				goto skip_unblock;
    +			grp->S = roundedS;
    +			grp->F = roundedS + (2ULL << grp->slot_shift);
    +			/* remove from ER and put in the new set */
    +			__clear_bit(grp->index, &q->bitmaps[ER]);
    +			s = qfq_calc_state(q, grp);
    +			__set_bit(grp->index, &q->bitmaps[s]);
    +		}
    +		/* we need to unblock even if the group has gone away */
    +		qfq_unblock_groups(q, grp->index, old_F);
    +	}
    +
    +skip_unblock:
    +	qfq_update_eligible(q, old_V);
    +	NO(if (!q->bitmaps[ER] && q->queued)
    +		dump_sched(q, "end dequeue");)
    +
    +	return m;
    +}
    +
    +/*
    + * Assign a reasonable start time for a new flow k in group i.
    + * Admissible values for \hat(F) are multiples of \sigma_i
    + * no greater than V+\sigma_i . Larger values mean that
    + * we had a wraparound so we consider the timestamp to be stale.
    + *
    + * If F is not stale and F >= V then we set S = F.
    + * Otherwise we should assign S = V, but this may violate
    + * the ordering in ER. So, if we have groups in ER, set S to
    + * the F_j of the first group j which would be blocking us.
    + * We are guaranteed not to move S backward because
    + * otherwise our group i would still be blocked.
    + */
    +static inline void
    +qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
    +{
    +	unsigned long mask;
    +	uint32_t limit, roundedF;
    +	int slot_shift = cl->grp->slot_shift;
    +
    +	roundedF = qfq_round_down(cl->F, slot_shift);
    +	limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift);
    +
    +	if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) {
    +		/* timestamp was stale */
    +		mask = mask_from(q->bitmaps[ER], cl->grp->index);
    +		if (mask) {
    +			struct qfq_group *next = qfq_ffs(q, mask);
    +			if (qfq_gt(roundedF, next->F)) {
    +				cl->S = next->F;
    +				return;
    +			}
    +		}
    +		cl->S = q->V;
    +	} else { /* timestamp is not stale */
    +		cl->S = cl->F;
    +	}
    +}
    +
    +static int
    +qfq_enqueue(struct dn_sch_inst *si, struct dn_queue *_q, struct mbuf *m)
    +{
    +	struct qfq_sched *q = (struct qfq_sched *)(si + 1);
    +	struct qfq_group *grp;
    +	struct qfq_class *cl = (struct qfq_class *)_q;
    +	uint64_t roundedS;
    +	int s;
    +
    +	NO(q->loops++;)
    +	DX(4, "len %d flow %p inv_w 0x%x grp %d", m->m_pkthdr.len,
    +		_q, cl->inv_w, cl->grp->index);
    +	/* XXX verify that the packet obeys the parameters */
    +	if (m != _q->mq.head) {
    +		if (dn_enqueue(_q, m, 0)) /* packet was dropped */
    +			return 1;
    +		NO(q->queued++;)
    +		if (m != _q->mq.head)
    +			return 0;
    +	}
    +	/* If reach this point, queue q was idle */
    +	grp = cl->grp;
    +	qfq_update_start(q, cl); /* adjust start time */
    +	/* compute new finish time and rounded start. */
    +	cl->F = cl->S + (uint64_t)(m->m_pkthdr.len) * cl->inv_w;
    +	roundedS = qfq_round_down(cl->S, grp->slot_shift);
    +
    +	/*
    +	 * insert cl in the correct bucket.
    +	 * If cl->S >= grp->S we don't need to adjust the
    +	 * bucket list and simply go to the insertion phase.
    +	 * Otherwise grp->S is decreasing, we must make room
    +	 * in the bucket list, and also recompute the group state.
    +	 * Finally, if there were no flows in this group and nobody
    +	 * was in ER make sure to adjust V.
    +	 */
    +	if (grp->full_slots) {
    +		if (!qfq_gt(grp->S, cl->S))
    +			goto skip_update;
    +		/* create a slot for this cl->S */
    +		qfq_slot_rotate(q, grp, roundedS);
    +		/* group was surely ineligible, remove */
    +		__clear_bit(grp->index, &q->bitmaps[IR]);
    +		__clear_bit(grp->index, &q->bitmaps[IB]);
    +	} else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
    +		q->V = roundedS;
    +
    +	grp->S = roundedS;
    +	grp->F = roundedS + (2ULL << grp->slot_shift); // i.e. 2\sigma_i
    +	s = qfq_calc_state(q, grp);
    +	__set_bit(grp->index, &q->bitmaps[s]);
    +	ND("new state %d 0x%x", s, q->bitmaps[s]);
    +	ND("S %llx F %llx V %llx", cl->S, cl->F, q->V);
    +skip_update:
    +	qfq_slot_insert(grp, cl, roundedS);
    +
    +	return 0;
    +}
    +
    +
    +#if 0
    +static inline void
    +qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
    +	struct qfq_class *cl, struct qfq_class **pprev)
    +{
    +	unsigned int i, offset;
    +	uint64_t roundedS;
    +
    +	roundedS = qfq_round_down(cl->S, grp->slot_shift);
    +	offset = (roundedS - grp->S) >> grp->slot_shift;
    +	i = (grp->front + offset) % QFQ_MAX_SLOTS;
    +
    +#ifdef notyet
    +	if (!pprev) {
    +		pprev = &grp->slots[i];
    +		while (*pprev && *pprev != cl)
    +			pprev = &(*pprev)->next;
    +	}
    +#endif
    +
    +	*pprev = cl->next;
    +	if (!grp->slots[i])
    +		__clear_bit(offset, &grp->full_slots);
    +}
    +
    +/*
    + * called to forcibly destroy a queue.
    + * If the queue is not in the front bucket, or if it has
    + * other queues in the front bucket, we can simply remove
    + * the queue with no other side effects.
    + * Otherwise we must propagate the event up.
    + * XXX description to be completed.
    + */
    +static void
    +qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl,
    +				 struct qfq_class **pprev)
    +{
    +	struct qfq_group *grp = &q->groups[cl->index];
    +	unsigned long mask;
    +	uint64_t roundedS;
    +	int s;
    +
    +	cl->F = cl->S;	// not needed if the class goes away.
    +	qfq_slot_remove(q, grp, cl, pprev);
    +
    +	if (!grp->full_slots) {
    +		/* nothing left in the group, remove from all sets.
    +		 * Do ER last because if we were blocking other groups
    +		 * we must unblock them.
    +		 */
    +		__clear_bit(grp->index, &q->bitmaps[IR]);
    +		__clear_bit(grp->index, &q->bitmaps[EB]);
    +		__clear_bit(grp->index, &q->bitmaps[IB]);
    +
    +		if (test_bit(grp->index, &q->bitmaps[ER]) &&
    +		    !(q->bitmaps[ER] & ~((1UL << grp->index) - 1))) {
    +			mask = q->bitmaps[ER] & ((1UL << grp->index) - 1);
    +			if (mask)
    +				mask = ~((1UL << __fls(mask)) - 1);
    +			else
    +				mask = ~0UL;
    +			qfq_move_groups(q, mask, EB, ER);
    +			qfq_move_groups(q, mask, IB, IR);
    +		}
    +		__clear_bit(grp->index, &q->bitmaps[ER]);
    +	} else if (!grp->slots[grp->front]) {
    +		cl = qfq_slot_scan(grp);
    +		roundedS = qfq_round_down(cl->S, grp->slot_shift);
    +		if (grp->S != roundedS) {
    +			__clear_bit(grp->index, &q->bitmaps[ER]);
    +			__clear_bit(grp->index, &q->bitmaps[IR]);
    +			__clear_bit(grp->index, &q->bitmaps[EB]);
    +			__clear_bit(grp->index, &q->bitmaps[IB]);
    +			grp->S = roundedS;
    +			grp->F = roundedS + (2ULL << grp->slot_shift);
    +			s = qfq_calc_state(q, grp);
    +			__set_bit(grp->index, &q->bitmaps[s]);
    +		}
    +	}
    +	qfq_update_eligible(q, q->V);
    +}
    +#endif
    +
    +static int
    +qfq_new_fsk(struct dn_fsk *f)
    +{
    +	ipdn_bound_var(&f->fs.par[0], 1, 1, QFQ_MAX_WEIGHT, "qfq weight");
    +	ipdn_bound_var(&f->fs.par[1], 1500, 1, 2000, "qfq maxlen");
    +	ND("weight %d len %d\n", f->fs.par[0], f->fs.par[1]);
    +	return 0;
    +}
    +
    +/*
    + * initialize a new scheduler instance
    + */
    +static int
    +qfq_new_sched(struct dn_sch_inst *si)
    +{
    +	struct qfq_sched *q = (struct qfq_sched *)(si + 1);
    +	struct qfq_group *grp;
    +	int i;
    +
    +	for (i = 0; i <= QFQ_MAX_INDEX; i++) {
    +		grp = &q->groups[i];
    +		grp->index = i;
    +		grp->slot_shift = QFQ_MTU_SHIFT + FRAC_BITS -
    +					(QFQ_MAX_INDEX - i);
    +	}
    +	return 0;
    +}
    +
    +/*
    + * QFQ scheduler descriptor
    + */
    +static struct dn_alg qfq_desc = {
    +	_SI( .type = ) DN_SCHED_QFQ,
    +	_SI( .name = ) "QFQ",
    +	_SI( .flags = ) DN_MULTIQUEUE,
    +
    +	_SI( .schk_datalen = ) 0,
    +	_SI( .si_datalen = ) sizeof(struct qfq_sched),
    +	_SI( .q_datalen = ) sizeof(struct qfq_class) - sizeof(struct dn_queue),
    +
    +	_SI( .enqueue = ) qfq_enqueue,
    +	_SI( .dequeue = ) qfq_dequeue,
    +
    +	_SI( .config = )  NULL,
    +	_SI( .destroy = )  NULL,
    +	_SI( .new_sched = ) qfq_new_sched,
    +	_SI( .free_sched = )  NULL,
    +	_SI( .new_fsk = ) qfq_new_fsk,
    +	_SI( .free_fsk = )  NULL,
    +	_SI( .new_queue = ) qfq_new_queue,
    +	_SI( .free_queue = ) qfq_free_queue,
    +};
    +
    +DECLARE_DNSCHED_MODULE(dn_qfq, &qfq_desc);
    +
    +#ifdef QFQ_DEBUG
    +static void
    +dump_groups(struct qfq_sched *q, uint32_t mask)
    +{
    +	int i, j;
    +
    +	for (i = 0; i < QFQ_MAX_INDEX + 1; i++) {
    +		struct qfq_group *g = &q->groups[i];
    +
    +		if (0 == (mask & (1<slots[j])
    +				D("    bucket %d %p", j, g->slots[j]);
    +		}
    +		D("full_slots 0x%x", g->full_slots);
    +		D("        %2d S 0x%20llx F 0x%llx %c", i,
    +			g->S, g->F,
    +			mask & (1<loops, q->queued, q->V);
    +	D("    ER 0x%08x", q->bitmaps[ER]);
    +	D("    EB 0x%08x", q->bitmaps[EB]);
    +	D("    IR 0x%08x", q->bitmaps[IR]);
    +	D("    IB 0x%08x", q->bitmaps[IB]);
    +	dump_groups(q, 0xffffffff);
    +};
    +#endif /* QFQ_DEBUG */
    diff --git a/sys/netinet/ipfw/dn_sched_rr.c b/sys/netinet/ipfw/dn_sched_rr.c
    new file mode 100644
    index 00000000000..fc7be001b30
    --- /dev/null
    +++ b/sys/netinet/ipfw/dn_sched_rr.c
    @@ -0,0 +1,307 @@
    +/*
    + * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
    + * 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$
    + */
    +
    +#ifdef _KERNEL
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 	/* IFNAMSIZ */
    +#include 
    +#include 		/* ipfw_rule_ref */
    +#include 	/* flow_id */
    +#include 
    +#include 
    +#include 
    +#include 
    +#else
    +#include 
    +#endif
    +
    +#define DN_SCHED_RR	3 // XXX Where?
    +
    +struct rr_queue {
    +	struct dn_queue q;		/* Standard queue */
    +	int status;			/* 1: queue is in the list */
    +	int credit;			/* Number of bytes to transmit */
    +	int quantum;			/* quantum * C */
    +	struct rr_queue *qnext;		/* */
    +};
    +
    +/* struct rr_schk contains global config parameters
    + * and is right after dn_schk
    + */
    +struct rr_schk {
    +	int min_q;		/* Min quantum */
    +	int max_q;		/* Max quantum */
    +	int q_bytes;		/* Bytes per quantum */
    +};
    +
    +/* per-instance round robin list, right after dn_sch_inst */
    +struct rr_si {
    +	struct rr_queue *head, *tail;	/* Pointer to current queue */
    +};
    +
    +/* Append a queue to the rr list */
    +static inline void
    +rr_append(struct rr_queue *q, struct rr_si *si)
    +{
    +	q->status = 1;		/* mark as in-rr_list */
    +	q->credit = q->quantum;	/* initialize credit */
    +
    +	/* append to the tail */
    +	if (si->head == NULL)
    +		si->head = q;
    +	else
    +		si->tail->qnext = q;
    +	si->tail = q;		/* advance the tail pointer */
    +	q->qnext = si->head;	/* make it circular */
    +}
    +
    +/* Remove the head queue from circular list. */
    +static inline void
    +rr_remove_head(struct rr_si *si)
    +{
    +	if (si->head == NULL)
    +		return; /* empty queue */
    +	si->head->status = 0;
    +	
    +	if (si->head == si->tail) {
    +		si->head = si->tail = NULL;
    +		return;
    +	}
    +
    +	si->head = si->head->qnext;
    +	si->tail->qnext = si->head;
    +}
    +
    +/* Remove a queue from circular list.
    + * XXX see if ti can be merge with remove_queue()
    + */
    +static inline void
    +remove_queue_q(struct rr_queue *q, struct rr_si *si)
    +{
    +	struct rr_queue *prev;
    +
    +	if (q->status != 1)
    +		return;
    +	if (q == si->head) {
    +		rr_remove_head(si);
    +		return;
    +	}
    +
    +	for (prev = si->head; prev; prev = prev->qnext) {
    +		if (prev->qnext != q)
    +			continue;
    +		prev->qnext = q->qnext;
    +		if (q == si->tail)
    +			si->tail = prev;
    +		q->status = 0;
    +		break;
    +	}
    +}
    +
    +
    +static inline void
    +next_pointer(struct rr_si *si)
    +{
    +	if (si->head == NULL)
    +		return; /* empty queue */
    +
    +	si->head = si->head->qnext;
    +	si->tail = si->tail->qnext;
    +}
    +
    +static int 
    +rr_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
    +{
    +	struct rr_si *si;
    +	struct rr_queue *rrq;
    +
    +	if (m != q->mq.head) {
    +		if (dn_enqueue(q, m, 0)) /* packet was dropped */
    +			return 1;
    +		if (m != q->mq.head)
    +			return 0;
    +	}
    +
    +	/* If reach this point, queue q was idle */ 
    +	si = (struct rr_si *)(_si + 1);
    +	rrq = (struct rr_queue *)q;
    +
    +	if (rrq->status == 1) /* Queue is already in the queue list */
    +		return 0;
    +
    +	/* Insert the queue in the queue list */
    +	rr_append(rrq, si);
    +
    +	return 0;
    +}
    +
    +static struct mbuf *
    +rr_dequeue(struct dn_sch_inst *_si)
    +{
    +	/* Access scheduler instance private data */
    +	struct rr_si *si = (struct rr_si *)(_si + 1);
    +	struct rr_queue *rrq;
    +	uint64_t len;
    +
    +	while ( (rrq = si->head) ) {
    +		struct mbuf *m = rrq->q.mq.head;
    +		if ( m == NULL) {
    +			/* empty queue, remove from list */
    +			rr_remove_head(si);
    +			continue;
    +		}
    +		len = m->m_pkthdr.len;
    +
    +		if (len > rrq->credit) {
    +			/* Packet too big */
    +			rrq->credit += rrq->quantum;
    +			/* Try next queue */
    +			next_pointer(si);
    +		} else {
    +			rrq->credit -= len;
    +			return dn_dequeue(&rrq->q);
    +		}
    +	}
    +
    +	/* no packet to dequeue*/
    +	return NULL;
    +}
    +
    +static int
    +rr_config(struct dn_schk *_schk)
    +{
    +	struct rr_schk *schk = (struct rr_schk *)(_schk + 1);
    +	ND("called");
    +
    +	/* use reasonable quantums (64..2k bytes, default 1500) */
    +	schk->min_q = 64;
    +	schk->max_q = 2048;
    +	schk->q_bytes = 1500;	/* quantum */
    +
    +	return 0;
    +}
    +
    +static int
    +rr_new_sched(struct dn_sch_inst *_si)
    +{
    +	struct rr_si *si = (struct rr_si *)(_si + 1);
    +
    +	ND("called");
    +	si->head = si->tail = NULL;
    +
    +	return 0;
    +}
    +
    +static int
    +rr_free_sched(struct dn_sch_inst *_si)
    +{
    +	ND("called");
    +	/* Nothing to do? */
    +	return 0;
    +}
    +
    +static int
    +rr_new_fsk(struct dn_fsk *fs)
    +{
    +	struct rr_schk *schk = (struct rr_schk *)(fs->sched + 1);
    +	/* par[0] is the weight, par[1] is the quantum step */
    +	ipdn_bound_var(&fs->fs.par[0], 1,
    +		1, 65536, "RR weight");
    +	ipdn_bound_var(&fs->fs.par[1], schk->q_bytes,
    +		schk->min_q, schk->max_q, "RR quantum");
    +	return 0;
    +}
    +
    +static int
    +rr_new_queue(struct dn_queue *_q)
    +{
    +	struct rr_queue *q = (struct rr_queue *)_q;
    +
    +	_q->ni.oid.subtype = DN_SCHED_RR;
    +
    +	q->quantum = _q->fs->fs.par[0] * _q->fs->fs.par[1];
    +	ND("called, q->quantum %d", q->quantum);
    +	q->credit = q->quantum;
    +	q->status = 0;
    +
    +	if (_q->mq.head != NULL) {
    +		/* Queue NOT empty, insert in the queue list */
    +		rr_append(q, (struct rr_si *)(_q->_si + 1));
    +	}
    +	return 0;
    +}
    +
    +static int
    +rr_free_queue(struct dn_queue *_q)
    +{
    +	struct rr_queue *q = (struct rr_queue *)_q;
    +
    +	ND("called");
    +	if (q->status == 1) {
    +		struct rr_si *si = (struct rr_si *)(_q->_si + 1);
    +		remove_queue_q(q, si);
    +	}
    +	return 0;
    +}
    +
    +/*
    + * RR scheduler descriptor
    + * contains the type of the scheduler, the name, the size of the
    + * structures and function pointers.
    + */
    +static struct dn_alg rr_desc = {
    +	_SI( .type = ) DN_SCHED_RR,
    +	_SI( .name = ) "RR",
    +	_SI( .flags = ) DN_MULTIQUEUE,
    +
    +	_SI( .schk_datalen = ) 0,
    +	_SI( .si_datalen = ) sizeof(struct rr_si),
    +	_SI( .q_datalen = ) sizeof(struct rr_queue) - sizeof(struct dn_queue),
    +
    +	_SI( .enqueue = ) rr_enqueue,
    +	_SI( .dequeue = ) rr_dequeue,
    +
    +	_SI( .config = ) rr_config,
    +	_SI( .destroy = ) NULL,
    +	_SI( .new_sched = ) rr_new_sched,
    +	_SI( .free_sched = ) rr_free_sched,
    +	_SI( .new_fsk = ) rr_new_fsk,
    +	_SI( .free_fsk = ) NULL,
    +	_SI( .new_queue = ) rr_new_queue,
    +	_SI( .free_queue = ) rr_free_queue,
    +};
    +
    +
    +DECLARE_DNSCHED_MODULE(dn_rr, &rr_desc);
    diff --git a/sys/netinet/ipfw/dn_sched_wf2q.c b/sys/netinet/ipfw/dn_sched_wf2q.c
    new file mode 100644
    index 00000000000..1fbc1202e40
    --- /dev/null
    +++ b/sys/netinet/ipfw/dn_sched_wf2q.c
    @@ -0,0 +1,373 @@
    +/*
    + * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
    + * Copyright (c) 2000-2002 Luigi Rizzo, Universita` di Pisa
    + * 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$
    + */
    +
    +#ifdef _KERNEL
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 	/* IFNAMSIZ */
    +#include 
    +#include 		/* ipfw_rule_ref */
    +#include 	/* flow_id */
    +#include 
    +#include 
    +#include 
    +#include 
    +#else
    +#include 
    +#endif
    +
    +#ifndef MAX64
    +#define MAX64(x,y)  (( (int64_t) ( (y)-(x) )) > 0 ) ? (y) : (x)
    +#endif
    +
    +/*
    + * timestamps are computed on 64 bit using fixed point arithmetic.
    + * LMAX_BITS, WMAX_BITS are the max number of bits for the packet len
    + * and sum of weights, respectively. FRAC_BITS is the number of
    + * fractional bits. We want FRAC_BITS >> WMAX_BITS to avoid too large
    + * errors when computing the inverse, FRAC_BITS < 32 so we can do 1/w
    + * using an unsigned 32-bit division, and to avoid wraparounds we need
    + * LMAX_BITS + WMAX_BITS + FRAC_BITS << 64
    + * As an example
    + * FRAC_BITS = 26, LMAX_BITS=14, WMAX_BITS = 19
    + */
    +#ifndef FRAC_BITS
    +#define FRAC_BITS    28 /* shift for fixed point arithmetic */
    +#define	ONE_FP	(1UL << FRAC_BITS)
    +#endif
    +
    +/*
    + * Private information for the scheduler instance:
    + * sch_heap (key is Finish time) returns the next queue to serve
    + * ne_heap (key is Start time) stores not-eligible queues
    + * idle_heap (key=start/finish time) stores idle flows. It must
    + *	support extract-from-middle.
    + * A flow is only in 1 of the three heaps.
    + * XXX todo: use a more efficient data structure, e.g. a tree sorted
    + * by F with min_subtree(S) in each node
    + */
    +struct wf2qp_si {
    +    struct dn_heap sch_heap;	/* top extract - key Finish  time */
    +    struct dn_heap ne_heap;	/* top extract - key Start   time */
    +    struct dn_heap idle_heap;	/* random extract - key Start=Finish time */
    +    uint64_t V;			/* virtual time */
    +    uint32_t inv_wsum;		/* inverse of sum of weights */
    +    uint32_t wsum;		/* sum of weights */
    +};
    +
    +struct wf2qp_queue {
    +    struct dn_queue _q;
    +    uint64_t S, F;		/* start time, finish time */
    +    uint32_t inv_w;		/* ONE_FP / weight */
    +    int32_t heap_pos;		/* position (index) of struct in heap */
    +};
    +
    +/*
    + * This file implements a WF2Q+ scheduler as it has been in dummynet
    + * since 2000.
    + * The scheduler supports per-flow queues and has O(log N) complexity.
    + *
    + * WF2Q+ needs to drain entries from the idle heap so that we
    + * can keep the sum of weights up to date. We can do it whenever
    + * we get a chance, or periodically, or following some other
    + * strategy. The function idle_check() drains at most N elements
    + * from the idle heap.
    + */
    +static void
    +idle_check(struct wf2qp_si *si, int n, int force)
    +{
    +    struct dn_heap *h = &si->idle_heap;
    +    while (n-- > 0 && h->elements > 0 &&
    +		(force || DN_KEY_LT(HEAP_TOP(h)->key, si->V))) {
    +	struct dn_queue *q = HEAP_TOP(h)->object;
    +        struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q;
    +
    +        heap_extract(h, NULL);
    +        /* XXX to let the flowset delete the queue we should
    +	 * mark it as 'unused' by the scheduler.
    +	 */
    +        alg_fq->S = alg_fq->F + 1; /* Mark timestamp as invalid. */
    +        si->wsum -= q->fs->fs.par[0];	/* adjust sum of weights */
    +	if (si->wsum > 0)
    +		si->inv_wsum = ONE_FP/si->wsum;
    +    }
    +}
    +
    +static int 
    +wf2qp_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
    +{
    +    struct dn_fsk *fs = q->fs;
    +    struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
    +    struct wf2qp_queue *alg_fq;
    +    uint64_t len = m->m_pkthdr.len;
    +
    +    if (m != q->mq.head) {
    +	if (dn_enqueue(q, m, 0)) /* packet was dropped */
    +	    return 1;
    +	if (m != q->mq.head)	/* queue was already busy */
    +	    return 0;
    +    }
    +
    +    /* If reach this point, queue q was idle */ 
    +    alg_fq = (struct wf2qp_queue *)q;
    +
    +    if (DN_KEY_LT(alg_fq->F, alg_fq->S)) {
    +        /* Fbrand new queue. */
    +        alg_fq->S = si->V;		/* init start time */
    +        si->wsum += fs->fs.par[0];	/* add weight of new queue. */
    +	si->inv_wsum = ONE_FP/si->wsum;
    +    } else { /* if it was idle then it was in the idle heap */
    +        heap_extract(&si->idle_heap, q);
    +        alg_fq->S = MAX64(alg_fq->F, si->V);	/* compute new S */
    +    }
    +    alg_fq->F = alg_fq->S + len * alg_fq->inv_w;
    +
    +    /* if nothing is backlogged, make sure this flow is eligible */
    +    if (si->ne_heap.elements == 0 && si->sch_heap.elements == 0)
    +        si->V = MAX64(alg_fq->S, si->V);
    +
    +    /*
    +     * Look at eligibility. A flow is not eligibile if S>V (when
    +     * this happens, it means that there is some other flow already
    +     * scheduled for the same pipe, so the sch_heap cannot be
    +     * empty). If the flow is not eligible we just store it in the
    +     * ne_heap. Otherwise, we store in the sch_heap.
    +     * Note that for all flows in sch_heap (SCH), S_i <= V,
    +     * and for all flows in ne_heap (NEH), S_i > V.
    +     * So when we need to compute max(V, min(S_i)) forall i in
    +     * SCH+NEH, we only need to look into NEH.
    +     */
    +    if (DN_KEY_LT(si->V, alg_fq->S)) {
    +        /* S>V means flow Not eligible. */
    +        if (si->sch_heap.elements == 0)
    +            D("++ ouch! not eligible but empty scheduler!");
    +        heap_insert(&si->ne_heap, alg_fq->S, q);
    +    } else {
    +        heap_insert(&si->sch_heap, alg_fq->F, q);
    +    }
    +    return 0;
    +}
    +
    +/* XXX invariant: sch > 0 || V >= min(S in neh) */
    +static struct mbuf *
    +wf2qp_dequeue(struct dn_sch_inst *_si)
    +{
    +	/* Access scheduler instance private data */
    +	struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
    +	struct mbuf *m;
    +	struct dn_queue *q;
    +	struct dn_heap *sch = &si->sch_heap;
    +	struct dn_heap *neh = &si->ne_heap;
    +	struct wf2qp_queue *alg_fq;
    +
    +	if (sch->elements == 0 && neh->elements == 0) {
    +		/* we have nothing to do. We could kill the idle heap
    +		 * altogether and reset V
    +		 */
    +		idle_check(si, 0x7fffffff, 1);
    +		si->V = 0;
    +		si->wsum = 0;	/* should be set already */
    +		return NULL;	/* quick return if nothing to do */
    +	}
    +	idle_check(si, 1, 0);	/* drain something from the idle heap */
    +
    +	/* make sure at least one element is eligible, bumping V
    +	 * and moving entries that have become eligible.
    +	 * We need to repeat the first part twice, before and
    +	 * after extracting the candidate, or enqueue() will
    +	 * find the data structure in a wrong state.
    +	 */
    +  m = NULL;
    +  for(;;) {
    +	/*
    +	 * Compute V = max(V, min(S_i)). Remember that all elements
    +	 * in sch have by definition S_i <= V so if sch is not empty,
    +	 * V is surely the max and we must not update it. Conversely,
    +	 * if sch is empty we only need to look at neh.
    +	 * We don't need to move the queues, as it will be done at the
    +	 * next enqueue
    +	 */
    +	if (sch->elements == 0 && neh->elements > 0) {
    +		si->V = MAX64(si->V, HEAP_TOP(neh)->key);
    +	}
    +	while (neh->elements > 0 &&
    +		    DN_KEY_LEQ(HEAP_TOP(neh)->key, si->V)) {
    +		q = HEAP_TOP(neh)->object;
    +		alg_fq = (struct wf2qp_queue *)q;
    +		heap_extract(neh, NULL);
    +		heap_insert(sch, alg_fq->F, q);
    +	}
    +	if (m) /* pkt found in previous iteration */
    +		break;
    +	/* ok we have at least one eligible pkt */
    +	q = HEAP_TOP(sch)->object;
    +	alg_fq = (struct wf2qp_queue *)q;
    +	m = dn_dequeue(q);
    +	heap_extract(sch, NULL); /* Remove queue from heap. */
    +	si->V += (uint64_t)(m->m_pkthdr.len) * si->inv_wsum;
    +	alg_fq->S = alg_fq->F;  /* Update start time. */
    +	if (q->mq.head == 0) {	/* not backlogged any more. */
    +		heap_insert(&si->idle_heap, alg_fq->F, q);
    +	} else {			/* Still backlogged. */
    +		/* Update F, store in neh or sch */
    +		uint64_t len = q->mq.head->m_pkthdr.len;
    +		alg_fq->F += len * alg_fq->inv_w;
    +		if (DN_KEY_LEQ(alg_fq->S, si->V)) {
    +			heap_insert(sch, alg_fq->F, q);
    +		} else {
    +			heap_insert(neh, alg_fq->S, q);
    +		}
    +	}
    +    }
    +	return m;
    +}
    +
    +static int
    +wf2qp_new_sched(struct dn_sch_inst *_si)
    +{
    +	struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
    +	int ofs = offsetof(struct wf2qp_queue, heap_pos);
    +
    +	/* all heaps support extract from middle */
    +	if (heap_init(&si->idle_heap, 16, ofs) ||
    +	    heap_init(&si->sch_heap, 16, ofs) ||
    +	    heap_init(&si->ne_heap, 16, ofs)) {
    +		heap_free(&si->ne_heap);
    +		heap_free(&si->sch_heap);
    +		heap_free(&si->idle_heap);
    +		return ENOMEM;
    +	}
    +	return 0;
    +}
    +
    +static int
    +wf2qp_free_sched(struct dn_sch_inst *_si)
    +{
    +	struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
    +
    +	heap_free(&si->sch_heap);
    +	heap_free(&si->ne_heap);
    +	heap_free(&si->idle_heap);
    +
    +	return 0;
    +}
    +
    +static int
    +wf2qp_new_fsk(struct dn_fsk *fs)
    +{
    +	ipdn_bound_var(&fs->fs.par[0], 1,
    +		1, 100, "WF2Q+ weight");
    +	return 0;
    +}
    +
    +static int
    +wf2qp_new_queue(struct dn_queue *_q)
    +{
    +	struct wf2qp_queue *q = (struct wf2qp_queue *)_q;
    +
    +	_q->ni.oid.subtype = DN_SCHED_WF2QP;
    +	q->F = 0;	/* not strictly necessary */
    +	q->S = q->F + 1;    /* mark timestamp as invalid. */
    +        q->inv_w = ONE_FP / _q->fs->fs.par[0];
    +	if (_q->mq.head != NULL) {
    +		wf2qp_enqueue(_q->_si, _q, _q->mq.head);
    +	}
    +	return 0;
    +}
    +
    +/*
    + * Called when the infrastructure removes a queue (e.g. flowset
    + * is reconfigured). Nothing to do if we did not 'own' the queue,
    + * otherwise remove it from the right heap and adjust the sum
    + * of weights.
    + */
    +static int
    +wf2qp_free_queue(struct dn_queue *q)
    +{
    +	struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q;
    +	struct wf2qp_si *si = (struct wf2qp_si *)(q->_si + 1);
    +    
    +	if (alg_fq->S >= alg_fq->F + 1)
    +		return 0;	/* nothing to do, not in any heap */
    +	si->wsum -= q->fs->fs.par[0];
    +	if (si->wsum > 0)
    +		si->inv_wsum = ONE_FP/si->wsum;
    +
    +	/* extract from the heap. XXX TODO we may need to adjust V
    +	 * to make sure the invariants hold.
    +	 */
    +	if (q->mq.head == NULL) {
    +		heap_extract(&si->idle_heap, q);
    +	} else if (DN_KEY_LT(si->V, alg_fq->S)) {
    +		heap_extract(&si->ne_heap, q);
    +	} else {
    +		heap_extract(&si->sch_heap, q);
    +	}
    +	return 0;
    +}
    +
    +/*
    + * WF2Q+ scheduler descriptor
    + * contains the type of the scheduler, the name, the size of the
    + * structures and function pointers.
    + */
    +static struct dn_alg wf2qp_desc = {
    +	_SI( .type = ) DN_SCHED_WF2QP,
    +	_SI( .name = ) "WF2Q+",
    +	_SI( .flags = ) DN_MULTIQUEUE,
    +
    +	/* we need extra space in the si and the queue */
    +	_SI( .schk_datalen = ) 0,
    +	_SI( .si_datalen = ) sizeof(struct wf2qp_si),
    +	_SI( .q_datalen = ) sizeof(struct wf2qp_queue) -
    +				sizeof(struct dn_queue),
    +
    +	_SI( .enqueue = ) wf2qp_enqueue,
    +	_SI( .dequeue = ) wf2qp_dequeue,
    +
    +	_SI( .config = )  NULL,
    +	_SI( .destroy = )  NULL,
    +	_SI( .new_sched = ) wf2qp_new_sched,
    +	_SI( .free_sched = ) wf2qp_free_sched,
    +    
    +	_SI( .new_fsk = ) wf2qp_new_fsk,
    +	_SI( .free_fsk = )  NULL,
    +
    +	_SI( .new_queue = ) wf2qp_new_queue,
    +	_SI( .free_queue = ) wf2qp_free_queue,
    +};
    +
    +
    +DECLARE_DNSCHED_MODULE(dn_wf2qp, &wf2qp_desc);
    diff --git a/sys/netinet/ipfw/dummynet.txt b/sys/netinet/ipfw/dummynet.txt
    new file mode 100644
    index 00000000000..0ed6ad15d32
    --- /dev/null
    +++ b/sys/netinet/ipfw/dummynet.txt
    @@ -0,0 +1,860 @@
    +#
    +# $FreeBSD$
    +#
    +
    +Notes on the internal structure of dummynet (2010 version)
    +by Riccardo Panicucci and Luigi Rizzo
    +Work supported by the EC project ONELAB2
    +
    +
    +*********
    +* INDEX *
    +*********
    +Implementation of new dummynet
    +    Internal structure
    +    Files
    +Packet arrival
    +    The reconfiguration routine
    +dummynet_task()
    +Configuration
    +    Add a pipe
    +    Add a scheduler
    +    Add a flowset
    +Listing object
    +Delete of object
    +    Delete a pipe
    +    Delete a flowset
    +    Delete a scheduler
    +Compatibility with FreeBSD7.2 and FreeBSD 8 ipfw binary
    +    ip_dummynet_glue.c
    +    ip_fw_glue.c
    +How to configure dummynet
    +How to implement a new scheduler
    +
    +
    +
    +OPEN ISSUES
    +------------------------------
    +20100131 deleting RR causes infinite loop
    +	presumably in the rr_free_queue() call -- seems to hang
    +	forever when deleting a live flow
    +------------------------------
    +
    +Dummynet is a traffic shaper and network emulator. Packets are
    +selected by an external filter such as ipfw, and passed to the emulator
    +with a tag such as "pipe 10" or "queue 5" which tells what to
    +do with the packet. As an example
    +
    +	ipfw add queue 5 icmp from 10.0.0.2 to all
    +
    +All packets with the same tag belong to a "flowset", or a set
    +of flows which can be further partitioned according to a mask.
    +Flowsets are then passed to a scheduler for processing. The
    +association of flowsets and schedulers is configurable e.g.
    +
    +	ipfw queue 5 config sched 10 weight 3 flow_mask xxxx
    +	ipfw queue 8 config sched 10 weight 1 ...
    +	ipfw queue 3 config sched 20 weight 1 ...
    +
    +"sched 10" represents one or more scheduler instances,
    +selected through a mask on the 5-tuple itself.
    +
    +	ipfw sched 20 config type FIFO sched_mask yyy ...
    +
    +There are in fact two masks applied to each packet:
    ++ the "sched_mask" sends packets arriving to a scheduler_id to
    +  one of many instances.
    ++ the "flow_mask" together with the flowset_id is used to
    +  collect packets into independent flows on each scheduler.
    +
    +As an example, we can have
    +	ipfw queue 5 config sched 10 flow_mask src-ip 0x000000ff
    +	ipfw sched 10 config type WF2Q+ sched_mask src-ip 0xffffff00
    +
    +means that sched 10 will have one instance per /24 source subnet,
    +and within that, each individual source will be a flow.
    +	
    +Internal structure
    +-----------------
    +Dummynet-related data is split into several data structures,
    +part of them constituting the userland-kernel API, and others
    +specific to the kernel.
    +NOTE: for up-to-date details please look at the relevant source
    +	headers (ip_dummynet.h, ip_dn_private.h, dn_sched.h)
    +
    +USERLAND-KERNEL API	(ip_dummynet.h)
    +
    +    struct dn_link:
    +	contains data about the physical link such as
    +	bandwith, delay, burst size;
    +
    +    struct dn_fs:
    +	describes a flowset, i.e. a template for queues.
    +	Main parameters are the scheduler we attach to, a flow_mask,
    +	buckets, queue size, plr, weight, and other scheduler-specific
    +	parameters.
    +
    +    struct dn_flow
    +	contains information on a flow, including masks and
    +	statistics
    +
    +    struct dn_sch:
    +	defines a scheduler (and a link attached to it).
    +	Parameters include scheduler type, sched_mask, number of
    +	buckets, and possibly other scheduler-specific parameters,
    +
    +    struct dn_profile:
    +	fields to simulate a delay profile
    +
    +
    +KERNEL REPRESENTATION	(ip_dn_private.h)
    +
    +    struct mq
    +	a queue of mbufs with head and tail.
    +
    +    struct dn_queue
    +	individual queue of packets, created by a flowset using
    +	flow_mask and attached to a scheduler instance selected
    +	through sched_mask.
    +	A dn_queue has a pointer to the dn_fsk (which in turn counts
    +	how many queues point to it), a pointer to the
    +	dn_sch_inst it attaches to, and is in a hash table in the
    +	flowset. scheduler instances also should store queues in
    +	their own containers used for scheduling (lists, trees, etc.)
    +	CREATE: done on packet arrivals when a flow matches a flowset.
    +	DELETE: done only when deleting the parent dn_sch_inst
    +		or draining memory.
    +
    +    struct dn_fsk
    +	includes a dn_fs; a pointer to the dn_schk; a link field
    +	for the list of dn_fsk attached to the same scheduler,
    +	or for the unlinked list;
    +	a refcount for the number of queues pointing to it;
    +	The dn_fsk is in a hash table, fshash.
    +	CREATE: done on configuration commands.
    +	DELETE: on configuration commands.
    +
    +    struct dn_sch_inst
    +	a scheduler instance, created from a dn_schk applying sched_mask.
    +	Contains a delay line, a reference to the parent, and scheduler-
    +	specific info.  Both dn_sch_inst and its delay line can be in the
    +	evheap if they have events to be processed.
    +	CREATE: created from a dn_schk applying sched_mask
    +	DELETE: configuration command delete a scheduler which in turn
    +		sweeps the hash table of instances deleting them
    +
    +    struct dn_schk
    +	includes dn_sch, dn_link, a pointer to dn_profile,
    +	a hash table of dn_sch_inst, a list of dn_fsk
    +	attached to it.
    +	CREATE: configuration command. If there are flowsets that
    +		refer to this number, they are attached and moved
    +		to the hash table
    +	DELETE: manual, see dn_sch_inst
    +
    +
    +	fshash                            schedhash
    +      +---------------+   sched        +--------------+
    +      |      sched-------------------->|      NEW_SCHK|
    +  -<----*sch_chain    |<-----------------*fsk_list    |
    +      |NEW_FSK        |<----.          | [dn_link]    |
    +      +---------------+     |          +--------------+
    +      |qht (hash)     |     |          |  siht(hash)  |
    +      |   [dn_queue]  |     |          |  [dn_si]     |
    +      |   [dn_queue]  |     |          |  [dn_si]     |
    +      |     ...       |     |          |   ...        |
    +      |   +--------+  |     |          | +---------+  |
    +      |   |dn_queue|  |     |          | |dn_si    |  |
    +      |  |    fs *----------'          | |         |  |
    +      |  |    si *---------------------->|         |  |
    +      |  +---------+  |                | +---------+  |
    +      +---------------+                +--------------+
    +
    +The following global data structures contain all
    +schedulers and flowsets.
    +
    +- schedhash[x]: contains all scheduler templates in the system.
    +	Looked up only on manual configurations, where flowsets
    +	are attached to matching schedulers.
    +	We have one entry per 'sched X config' command
    +	(plus one for each 'pipe X config').
    +
    +- fshash[x]: contains all flowsets.
    +	We do a lookup on this for each packet.
    +	We have one entry for each 'queue X config'
    +	(plus one for each 'pipe X config').
    +
    +Additionally, a list that contains all unlinked flowset:
    +- fsu:  contains flowset that are not linked with any scheduler.
    +	Flowset are put in this list when they refer to a non
    +	existing scheduler.
    +	We don't need an efficient data structure as we never search
    +	here on a packet arrivals.
    +
    +Scheduler instances and the delay lines associated with each scheduler
    +instance need to be woken up at certain times. Because we have many
    +such objects, we keep them in a priority heap (system_heap).
    +
    +Almost all objects in this implementation are preceded by a structure
    +(struct dn_id) which makes it easier to identify them.
    +
    +
    +Files
    +-----
    +The dummynet code is split in several files.
    +All kernel code is in sys/netinet/ipfw except ip_dummynet.h
    +All userland code is in sbin/ipfw.
    +Files are
    +- sys/netinet/ip_dummynet.h defines the kernel-userland API
    +- ip_dn_private.h contains the kernel-specific APIs
    +  and data structures
    +- dn_sched.h defines the scheduler API
    +- ip_dummynet.c cointains module glue and sockopt handlers, with all
    +  functions to configure and list objects.
    +- ip_dn_io.c contains the functions directly related to packet processing,
    +  and run in the critical path. It also contains some functions
    +  exported to the schedulers.
    +- dn_heap.[ch] implement a binary heap and a generic hash table
    +- dn_sched_* implement the various scheduler modules
    +  
    +- dummynet.c is the file used to implement the user side of dummynet.
    +  It contains the function to parsing command line, and functions to
    +  show the output of dummynet objects.
    +Moreover, there are two new file (ip_dummynet_glue.c and ip_fw_glue.c) that
    +are used to allow compatibility with the "ipfw" binary from FreeBSD 7.2 and
    +FreeBSD 8.
    +
    +LOCKING
    +=======
    +At the moment the entire processing occurs under a single lock
    +which is expected to be acquired in exclusive mode
    +DN_BH_WLOCK() / DN_BH_WUNLOCK().
    +
    +In perspective we aim at the following:
    +- the 'busy' flag, 'pending' list and all structures modified by packet
    +  arrivals and departures are protected by the BH_WLOCK.
    +  This is normally acquired in exclusive mode by the packet processing
    +  functions for short sections of code (exception -- the timer).
    +  If 'busy' is not set, we can do regular packet processing.
    +  If 'busy' is set, no pieces can be accessed.
    +  We must enqueue the packet on 'pending' and return immediately.
    +
    +- the 'busy' flag is set/cleared by long sections of code as follows:
    +	UH_WLOCK(); KASSERT(busy == 0);
    +	BH_WLOCK(); busy=1; BH_WUNLOCK();
    +	... do processing ...
    +	BH_WLOCK(); busy=0; drain_queue(pending); BH_WUNLOCK();
    +	UH_WUNLOCK();
    +  this normally happens when the upper half has something heavy
    +  to do. The prologue and epilogue are not in the critical path.
    +
    +- the main containers (fshash, schedhash, ...) are protected by
    +  UH_WLOCK.
    +  
    +Packet processing
    +=================
    +A packet enters dummynet through dummynet_io(). We first lookup
    +the flowset number in fshash using dn_ht_find(), then find the scheduler
    +instance using ipdn_si_find(), then possibly identify the correct
    +queue with ipdn_q_find().
    +If successful, we call the scheduler's enqueue function(), and
    +if needed start I/O on the link calling serve_sched().
    +If the packet can be returned immediately, this is done by
    +leaving *m0 set. Otherwise, the packet is absorbed by dummynet
    +and we simply return, possibly with some appropriate error code.
    +
    +Reconfiguration
    +---------------
    +Reconfiguration is the complex part of the system because we need to
    +keep track of the various objects and containers.
    +At the moment we do not use reference counts for objects so all
    +processing must be done under a lock.
    +
    +The main entry points for configuration is the ip_dn_ctl() handler
    +for the IP_DUMMYNET3 sockopt (others are provided only for backward
    +compatibility). Modifications to the configuration call do_config().
    +The argument is a sequence of blocks each starting with a  struct dn_id
    +which specifies its content.
    +The first dn_id must contain as obj.id the DN_API_VERSION
    +The obj.type is DN_CMD_CONFIG (followed by actual objects),
    +DN_CMD_DELETE (with the correct subtype and list of objects), or
    +DN_CMD_FLUSH.
    +
    +DN_CMD_CONFIG is followed by objects to add/reconfigure. In general,
    +if an object already exists it is reconfigured, otherwise it is
    +created in a way that keeps the structure consistent.
    +We have the following objects in the system, normally numbered with
    +an identifier N between 1 and 65535. For certain objects we have
    +"shadow" copies numbered I+NMAX and I+ 2*NMAX which are used to
    +implement certain backward compatibility features.
    +
    +In general we have the following linking
    +
    +  TRADITIONAL DUMMYNET QUEUES "queue N config ... pipe M ..."
    +	corresponds to a dn_fs object numbered N
    +
    +  TRADITIONAL DUMMYNET PIPES "pipe N config ..."
    +	dn_fs N+2*NMAX --> dn_sch N+NMAX type FIFO --> dn_link N+NMAX
    +
    +  GENERIC SCHEDULER "sched N config ... "
    +	[dn_fs N+NMAX] --> dn_sch N --> dn_link N
    +	The flowset N+NMAX is created only if the scheduler is not
    +	of type MULTIQUEUE.
    +
    +  DELAY PROFILE	"pipe N config profile ..."
    +	it is always attached to an existing dn_link N
    +
    +Because traditional dummynet pipes actually configure both a
    +'standalone' instance and one that can be used by queues,
    +we do the following:
    +
    +    "pipe N config ..." configures:
    +	dn_sched N type WF2Q+
    +	dn_sched N+NMAX type FIFO
    +	dn_fs N+2NMAX attached to dn_sched N+NMAX
    +	dn_pipe N
    +	dn_pipe N+NMAX
    +
    +    "queue N config" configures
    +	dn_fs N
    +
    +    "sched N config" configures
    +	dn_sched N type as desired
    +	dn_fs N+NMAX attached to dn_sched N
    +
    +
    +dummynet_task()
    +===============
    +The dummynet_task() is the the main dummynet processing function and is
    +called every tick. This function first calculate the new current time, then
    +it checks if it is the time to wake up object from the system_heap comparing
    +the current time and the key of the heap. Two types of object (really the
    +heap contains pointer to objects) are in the
    +system_heap:
    +
    +- scheduler instance: if a scheduler instance is waked up, the dequeue()
    +  function is called until it has credit. If the dequeue() returns packets,
    +  the scheduler instance is inserted in the heap with a new key depending of
    +  the data that will be send out. If the scheduler instance remains with
    +  some credit, it means that is hasn't other packet to send and so the
    +  instance is no longer inserted in the heap.
    +
    +  If the scheduler instance extracted from the heap has the DELETE flag set,
    +  the dequeue() is not called and the instance is destroyed now.
    +
    +- delay line: when extracting a delay line, the function transmit_event() is
    +  called to send out packet from delay line.
    +
    +  If the scheduler instance associated with this delay line doesn't exists,
    +  the delay line will be delete now.
    +
    +Configuration
    +=============
    +To create a pipe, queue or scheduler, the user should type commands like:
    +"ipfw pipe x config"
    +"ipfw queue y config pipe x"
    +"ipfw pipe x config sched "
    +
    +The userland side of dummynet will prepare a buffer contains data to pass to
    +kernel side.
    +The buffer contains all struct needed to configure an object. In more detail,
    +to configure a pipe all three structs (dn_link, dn_sch, dn_fs) are needed,
    +plus the delay profile struct if the pipe has a delay profile.
    +
    +If configuring a scheduler only the struct dn_sch is wrote in the buffer,
    +while if configuring a flowset only the dn_fs struct is wrote.
    +
    +The first struct in the buffer contains the type of command request, that is
    +if it is configuring a pipe, a queue, or a scheduler. Then there are structs
    +need to configure the object, and finally there is the struct that mark
    +the end of the buffer.
    +
    +To support the insertion of pipe and queue using the old syntax, when adding
    +a pipe it's necessary to create a FIFO flowset and a FIFO scheduler, which
    +have a number x + DN_PIPEOFFSET.
    +
    +Add a pipe
    +----------
    +A pipe is only a template for a link.
    +If the pipe already exists, parameters are updated. If a delay profile exists
    +it is deleted and a new one is created.
    +If the pipe doesn't exist a new one is created. After the creation, the
    +flowset unlinked list is scanned to see if there are some flowset that would
    +be linked with this pipe. If so, these flowset will be of wf2q+ type (for
    +compatibility) and a new wf2q+ scheduler is created now.
    +
    +Add a scheduler
    +---------------
    +If the scheduler already exists, and the type and the mask are the same, the
    +scheduler is simply reconfigured calling the config_scheduler() scheduler
    +function with the RECONFIGURE flag active.
    +If the type or the mask differ, it is necessary to delete the old scheduler
    +and create a new one.
    +If the scheduler doesn't exists, a new one is created. If the scheduler has
    +a mask, the hash table is created to store pointers to scheduler instances.
    +When a new scheduler is created, it is necessary to scan the unlinked
    +flowset list to search eventually flowset that would be linked with this
    +scheduler number. If some are found, flowsets became of the type of this
    +scheduler and they are configured properly.
    +
    +Add a flowset
    +-------------
    +Flowset pointers are store in the system in two list. The unlinked flowset list
    +contains all flowset that aren't linked with a scheduler, the flowset list
    +contains flowset linked to a scheduler, and so they have a type.
    +When adding a new flowset, first it is checked if the flowset exists (that is,
    +it is in the flowset list) and if it doesn't exists a new flowset is created
    +and added to unlinked flowset list if the scheduler which the flowset would be
    +linked doesn't exists, or added in the flowset list and configured properly if
    +the scheduler exists. If the flowset (before to be created) was in the
    +unlinked flowset list, it is removed and deleted, and then recreated.
    +If the flowset exists, to allow reconfiguration of this flowset, the
    +scheduler number and types must match with the one in memory. If this isn't
    +so, the flowset is deleted and a new one will be created. Really, the flowset
    +it isn't deleted now, but it is removed from flowset list and it will be
    +deleted later because there could be some queues that are using it.
    +
    +Listing of object
    +=================
    +The user can request a list of object present in dummynet through the command
    +"ipfw [-v] pipe|queue [x] list|show"
    +The kernel side of dummynet send a buffer to user side that contains all
    +pipe, all scheduler, all flowset, plus all scheduler instances and all queues.
    +The dummynet user land will format the output and show only the relevant
    +information.
    +The buffer sent start with all pipe from the system. The entire struct dn_link
    +is passed, except the delay_profile struct that is useless in user space.
    +After pipes, all flowset are wrote in the buffer. The struct contains
    +scheduler flowset specific data is linked with the flowset writing the
    +'obj' id of the extension into the 'alg_fs' pointer.
    +Then schedulers are wrote. If a scheduler has one or more scheduler instance,
    +these are linked to the parent scheduler writing the id of the parent in the
    +'ptr_sched' pointer. If a scheduler instance has queues, there are wrote in
    +the buffer and linked thorugh the 'obj' and 'sched_inst' pointer.
    +Finally, flowsets in the unlinked flowset list  are write in the buffer, and
    +then a struct gen in saved in the buffer to mark the last struct in the buffer.
    +
    +
    +Delete of object
    +================
    +An object is usually removed by user through a command like
    +"ipfw pipe|queue x delete". XXX sched?
    +ipfw pass to the kernel a struct gen that contains the type and the number
    +of the object to remove
    +
    +Delete of pipe x
    +----------------
    +A pipe can be deleted by the user throught the command 'ipfw pipe x delete'.
    +To delete a pipe, the pipe is removed from the pipe list, and then deleted.
    +Also the scheduler associated with this pipe should be deleted.
    +For compatibility with old dummynet syntax, the associated FIFO scheduler and
    +FIFO flowset must be deleted.
    +
    +Delete of flowset x
    +-------------------
    +To remove a flowset, we must be sure that is no loger referenced by any object.
    +If the flowset to remove is in the unlinked flowset list, there is not any
    +issue, the flowset can be safely removed calling a free() (the flowset
    +extension is not yet created if the flowset is in this list).
    +If the flowset is in the flowset list, first we remove from it so new packet
    +are discarded when arrive. Next, the flowset is marked as delete.
    +Now we must check if some queue is using this flowset.
    +To do this, a counter (active_f) is provided. This counter indicate how many
    +queues exist using this flowset.
    +The active_f counter is automatically incremented when a queue is created
    +and decremented when a queue is deleted.
    +If the counter is 0, the flowset can be safely deleted, and the delete_alg_fs()
    +scheduler function is called before deallocate memory.
    +If the counter is not 0, the flowset remain in memory until the counter become
    +zero. When a queue is delete (by dn_delete_queue() function) it is checked if
    +the linked flowset is deleting and if so the counter is decrementing. If the
    +counter reaches 0, the flowset is deleted.
    +The deletion of a queue can be done only by the scheduler, or when the scheduler
    +is destroyed.
    +
    +Delete of scheduler x
    +---------------------
    +To delete a scheduler we must be sure that any scheduler instance of this type
    +are in the system_heap. To do so, a counter (inst_counter) is provided.
    +This counter is managed by the system: it is incremented every time it is
    +inserted in the system_heap, and decremented every time it is extracted from it.
    +To delete the scheduler, first we remove it from the scheduler list, so new
    +packet are discarded when they arrive, and mark the scheduler as deleting.
    +
    +If the counter is 0, we can remove the scheduler safely calling the
    +really_deletescheduler() function. This function will scan all scheduler
    +instances and call the delete_scheduler_instance() function that will delete
    +the instance. When all instance are deleted, the scheduler template is
    +deleted calling the delete_scheduler_template(). If the delay line associate
    +with the scheduler is empty, it is deleted now, else it will be deleted when
    +it will became empy.
    +If the counter was not 0, we wait for it. Every time the dummynet_task()
    +function extract a scheduler from the system_heap, the counter is decremented.
    +If the scheduler has the delete flag enabled the dequeue() is not called and
    +delete_scheduler_instance() is called to delete the instance.
    +Obviously this scheduler instance is no loger inserted in the system_heap.
    +If the counter reaches 0, the delete_scheduler_template() function is called
    +all memory is released.
    +NOTE: Flowsets that belong to this scheduler are not deleted, so if a new
    +      scheduler with the same number is inserted will use these flowsets.
    +      To do so, the best approach would be insert these flowset in the
    +      unlinked flowset list, but doing this now will be very expensive.
    +      So flowsets will remain in memory and linked with a scheduler that no
    +      longer exists until a packet belonging to this flowset arrives. When
    +      this packet arrives, the reconfigure() function is called because the
    +      generation number mismatch with one contains in the flowset and so
    +      the flowset will be moved into the flowset unlinked list, or will be
    +      linked with the new scheduler if a new one was created.
    +
    +
    +COMPATIBILITY WITH FREEBSD 7.2 AND FREEBSD 8 'IPFW' BINARY
    +==========================================================
    +Dummynet is not compatible with old ipfw binary because internal structs are
    +changed. Moreover, the old ipfw binary is not compatible with new kernels
    +because the struct that represents a firewall rule has changed. So, if a user
    +install a new kernel on a FreeBSD 7.2, the ipfw (and possibly many other
    +commands) will not work.
    +New dummynet uses a new socket option: IP_DUMMYNET3, used for both set and get.
    +The old option can be used to allow compatibility with the 'ipfw' binary of
    +older version (tested with 7.2 and 8.0) of FreeBSD.
    +Two file are provided for this purpose:
    +- ip_dummynet_glue.c translates old dummynet requests to the new ones,
    +- ip_fw_glue.c converts the rule format between 7.2 and 8 versions.
    +Let see in detail these two files.
    +
    +IP_DUMMYNET_GLUE.C
    +------------------
    +The internal structs of new dummynet are very different from the original.
    +Because of there are some difference from between dummynet in FreeBSD 7.2 and
    +dummynet in FreeBSD 8 (the FreeBSD 8 version includes support to pipe delay
    +profile and burst option), I have to include both header files. I copied
    +the revision 191715 (for version 7.2) and the revision 196045 (for version 8)
    +and I appended a number to each struct to mark them.
    +
    +The main function of this file is ip_dummynet_compat() that is called by
    +ip_dn_ctl() when it receive a request of old socket option.
    +
    +A global variabile ('is7') store the version of 'ipfw' that FreeBSD is using.
    +This variable is set every time a request of configuration is done, because
    +with this request we receive a buffer of which size depending of ipfw version.
    +Because of in general the first action is a configuration, this variable is
    +usually set accordly. If the first action is a request of listing of pipes
    +or queues, the system cannot know the version of ipfw, and we suppose that
    +version 7.2 is used. If version is wrong, the output can be senseless, but
    +the application should not crash.
    +
    +There are four request for old dummynet:
    +- IP_DUMMYNET_FLUSH: the flush options have no parameter, so simply the
    +  dummynet_flush() function is called;
    +- IP_DUMMYNET_DEL: the delete option need to be translate.
    +  It is only necessary to extract the number and the type of the object
    +  (pipe or queue) to delete from the buffer received and build a new struct
    +  gen contains the right parameters, then call the delete_object() function;
    +- IP_DUMMYNET_CONFIGURE: the configure command receive a buffer depending of
    +  the ipfw version. After the properly extraction of all data, that depends
    +  by the ipfw version used, new structures are filled and then the dummynet
    +  config_link() function is properly called. Note that the 7.2 version does
    +  not support some parameter as burst or delay profile.
    +- IP_DUMMYNET_GET: The get command should send to the ipfw the correct buffer
    +  depending of its version. There are two function that build the
    +  corrected buffer, ip_dummynet_get7() and ip_dummynet_get8(). These
    +  functions reproduce the buffer exactly as 'ipfw' expect. The only difference
    +  is that the weight parameter for a queue is no loger sent by dummynet and so
    +  it is set to 0.
    +  Moreover, because of the internal structure has changed, the bucket size
    +  of a queue could not be correct, because now all flowset share the hash
    +  table.
    +  If the version of ipfw is wrong, the output could be senseless or truncated,
    +  but the application should not crash.
    +
    +IP_FW_GLUE.C
    +------------
    +The ipfw binary also is used to add rules to FreeBSD firewall. Because of the
    +struct ip_fw is changed from FreeBsd 7.2 to FreeBSD 8, it is necessary
    +to write some glue code to allow use ipfw from FreeBSD 7.2 with the kernel
    +provided with FreeBSD 8.
    +This file contains two functions to convert a rule from FreeBSD 7.2 format to
    +FreeBSD 8 format, and viceversa.
    +The conversion should be done when a rule passes from userspace to kernel space
    +and viceversa.
    +I have to modify the ip_fw2.c file to manage these two case, and added a
    +variable (is7) to store the ipfw version used, using an approach like the
    +previous file:
    +- when a new rule is added (option IP_FW_ADD) the is7 variable is set if the
    +  size of the rule received corrispond to FreeBSD 7.2 ipfw version. If so, the
    +  rule is converted to version 8 calling the function convert_rule_to_8().
    +  Moreover, after the insertion of the rule, the rule is now reconverted to
    +  version 7 because the ipfw binary will print it.
    +- when the user request a list of rules (option IP_FW_GET) the is7 variable
    +  should be set correctly because we suppose that a configure command was done,
    +  else we suppose that the FreeBSD version is 8. The function ipfw_getrules()
    +  in ip_fw2.c file return all rules, eventually converted to version 7 (if
    +  the is7 is set) to the ipfw binary.
    +The conversion of a rule is quite simple. The only difference between the
    +two structures (struct ip_fw) is that in the new there is a new field
    +(uint32_t id). So, I copy the entire rule in a buffer and the copy the rule in
    +the right position in the new (or old) struct. The size of commands are not
    +changed, and the copy is done into a cicle.
    +
    +How to configure dummynet
    +=========================
    +It is possible to configure dummynet through two main commands:
    +'ipfw pipe' and 'ipfw queue'.
    +To allow compatibility with old version, it is possible configure dummynet
    +using the old command syntax. Doing so, obviously, it is only possible to
    +configure a FIFO scheduler or a wf2q+ scheduler.
    +A new command, 'ipfw pipe x config sched ' is supported to add a new
    +scheduler to the system.
    +
    +- ipfw pipe x config ...
    +  create a new pipe with the link parameters
    +  create a new scheduler fifo (x + offset)
    +  create a new flowset fifo (x + offset)
    +  the mask is eventually stored in the FIFO scheduler
    +
    +- ipfw queue y config pipe x ...
    +  create a new flowset y linked to sched x.
    +    The type of flowset depends by the specified scheduler.
    +    If the scheduler does not exist, this flowset is inserted in a special
    +    list and will be not active.
    +    If pipe x exists and sched does not exist, a new wf2q+ scheduler is
    +    created and the flowset will be linked to this new scheduler (this is
    +    done for compatibility with old syntax).
    +
    +- ipfw pipe x config sched  ...
    +  create a new scheduler x of type .
    +  Search into the flowset unlinked list if there are some flowset that
    +  should be linked with this new scheduler.
    +
    +- ipfw pipe x delete
    +  delete the pipe x
    +  delete the scheduler fifo (x + offset)
    +  delete the scheduler x
    +  delete the flowset fifo (x + offset)
    +
    +- ipfw queue x delete
    +  delete the flowset x
    +
    +- ipfw sched x delete ///XXX
    +  delete the scheduler x
    +
    +Follow now some examples to how configure dummynet:
    +- Ex1:
    +  ipfw pipe 10 config bw 1M delay 15 // create a pipe with band and delay
    +                                        A FIFO flowset and scheduler is
    +                                        also created
    +  ipfw queue 5 config pipe 10 weight 56 // create a flowset. This flowset
    +                                           will be of wf2q+ because a pipe 10
    +                                           exists. Moreover, the wf2q+
    +                                           scheduler is created now.
    +- Ex2:
    +  ipfw queue 5 config pipe 10 weight 56 // Create a flowset. Scheduler 10
    +                                           does not exist, so this flowset
    +                                           is inserted in the unlinked
    +                                           flowset list.
    +  ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
    +                               Because of a flowset with 'pipe 10' exists,
    +                               a wf2q+ scheduler is created now and that
    +                               flowset is linked with this sceduler.
    +
    +- Ex3:
    +  ipfw pipe 10 config bw...    // Create a pipe, a FIFO flowset and scheduler.
    +  ipfw pipe 10 config sched rr // Create a scheduler of type RR, linked to
    +                                  pipe 10
    +  ipfw queue 5 config pipe 10 weight 56 // Create a flowset 5. This flowset
    +                                           will belong to scheduler 10 and
    +                                           it is of type RR
    +
    +- Ex4:
    +  ipfw pipe 10 config sched rr // Create a scheduler of type RR, linked to
    +                                  pipe 10 (not exist yet)
    +  ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
    +  ipfw queue 5 config pipe 10 weight 56 // Create a flowset 5.This flowset
    +                                           will belong to scheduler 10 and
    +                                           it is of type RR
    +  ipfw pipe 10 config sched wf2q+ // Modify the type of scheduler 10. It
    +                                     becomes a wf2q+ scheduler.
    +                                     When a new packet of flowset 5 arrives,
    +                                     the flowset 5 becomes to wf2q+ type.
    +
    +How to implement a new scheduler
    +================================
    +In dummynet, a scheduler algorithm is represented by two main structs, some
    +functions and other minor structs.
    +- A struct dn_sch_xyz (where xyz is the 'type' of scheduler algorithm
    +  implemented) contains data relative to scheduler, as global parameter that
    +  are common to all instances of the scheduler
    +- A struct dn_sch_inst_xyz contains data relative to a single scheduler
    +  instance, as local status variable depending for example by flows that
    +  are linked with the scheduler, and so on.
    +To add a scheduler to dummynet, the user should type a command like:
    +'ipfw pipe x config sched  [mask ... ...]'
    +This command creates a new struct dn_sch_xyz of type , and
    +store the optional parameter in that struct.
    +
    +The parameter mask determines how many scheduler instance of this
    +scheduler may exist. For example, it is possible to divide traffic
    +depending on the source port (or destination, or ip address...),
    +so that every scheduler instance act as an independent scheduler.
    +If the mask is not set, all traffic goes to the same instance.
    +
    +When a packet arrives to a scheduler, the system search the corrected
    +scheduler instance, and if it does not exist it is created now (the
    +struct dn_sch_inst_xyz is allocated by the system, and the scheduler
    +fills the field correctly). It is a task of the scheduler to create
    +the struct that contains all queues for a scheduler instance.
    +Dummynet provides some function to create an hash table to store
    +queues, but the schedule algorithm can choice the own struct.
    +
    +To link a flow to a scheduler, the user should type a command like:
    +'ipfw queue z config pipe x [mask... ...]'
    +
    +This command creates a new 'dn_fs' struct that will be inserted
    +in the system.  If the scheduler x exists, this flowset will be
    +linked to that scheduler and the flowset type become the same as
    +the scheduler type. At this point, the function create_alg_fs_xyz()
    +is called to allow store eventually parameter for the flowset that
    +depend by scheduler (for example the 'weight' parameter for a wf2q+
    +scheduler, or some priority...). A parameter mask can be used for
    +a flowset. If the mask parameter is set, the scheduler instance can
    +separate packet according to its flow id (src and dst ip, ports...)
    +and assign it to a separate queue. This is done by the scheduler,
    +so it can ignore the mask if it wants.
    +
    +See now the two main structs:
    +struct dn_sch_xyz {
    +    struct gen g; /* important the name g */
    +    /* global params */
    +};
    +struct dn_sch_inst_xyz {
    +    struct gen g; /* important the name g */
    +    /* params of the instance */
    +};
    +It is important to embed the struct gen as first parameter. The struct gen
    +contains some values that the scheduler instance must fill (the 'type' of
    +scheduler, the 'len' of the struct...)
    +The function create_scheduler_xyz() should be implemented to initialize global
    +parameters in the first struct, and if memory allocation is done it is
    +mandatory to implement the delete_scheduler_template() function to free that
    +memory.
    +The function create_scheduler_instance_xyz() must be implemented even if the
    +scheduler instance does not use extra parameters. In this function the struct
    +gen fields must be filled with corrected infos. The
    +delete_scheduler_instance_xyz() function must bu implemented if the instance
    +has allocated some memory in the previous function.
    +
    +To store data belonging to a flowset the follow struct is used:
    +struct alg_fs_xyz {
    +    struct gen g;
    +    /* fill correctly the gen struct
    +     g.subtype = DN_XYZ;
    +     g.len = sizeof(struct alg_fs_xyz)
    +     ...
    +     */
    +    /* params for the flow */
    +};
    +The create_alg_fs_xyz() function is mandatory, because it must fill the struct
    +gen, but the delete_alg_fs_xyz() is mandatory only if the previous function
    +has allocated some memory.
    +
    +A struct dn_queue contains packets belonging to a queue and some statistical
    +data. The scheduler could have to store data in this struct, so it must define
    +a dn_queue_xyz struct:
    +struct dn_queue_xyz {
    +    struct dn_queue q;
    +    /* parameter for a queue */
    +}
    +
    +All structures are allocated by the system. To do so, the scheduler must
    +set the size of its structs in the scheduler descriptor:
    +scheduler_size:     sizeof(dn_sch_xyz)
    +scheduler_i_size:   sizeof(dn_sch_inst_xyz)
    +flowset_size:       sizeof(alg_fs_xyz)
    +queue_size:         sizeof(dn_queue_xyz);
    +The scheduler_size could be 0, but other struct must have at least a struct gen.
    +
    +
    +After the definition of structs, it is necessary to implement the
    +scheduler functions.
    +
    +- int (*config_scheduler)(char *command, void *sch, int reconfigure);
    +    Configure a scheduler, or reconfigure if 'reconfigure' == 1.
    +    This function performs additional allocation and initialization of global
    +    parameter for this scheduler.
    +    If memory is allocated here, the delete_scheduler_template() function
    +    should be implemented to remove this memory.
    +- int (*delete_scheduler_template)(void* sch);
    +    Delete a scheduler template. This function is mandatory if the scheduler
    +    uses extra data respect the struct dn_sch.
    +- int (*create_scheduler_instance)(void *s);
    +    Create a new scheduler instance. The system allocate the necessary memory
    +    and the schedulet can access it using the 's' pointer.
    +    The scheduler instance stores all queues, and to do this can use the
    +    hash table provided by the system.
    +- int (*delete_scheduler_instance)(void *s);
    +    Delete a scheduler instance. It is important to free memory allocated
    +    by create_scheduler_instance() function. The memory allocated by system
    +    is freed by the system itself. The struct contains all queue also has
    +    to be deleted.
    +- int (*enqueue)(void *s, struct gen *f, struct mbuf *m,
    +                 struct ipfw_flow_id *id);
    +    Called when a packet arrives. The packet 'm' belongs to the scheduler
    +    instance 's', has a flowset 'f' and the flowid 'id' has already been
    +    masked. The enqueue() must call dn_queue_packet(q, m) function to really
    +    enqueue packet in the queue q. The queue 'q' is chosen by the scheduler
    +    and if it does not exist should be created calling the dn_create_queue()
    +    function. If the schedule want to drop the packet, it must call the
    +    dn_drop_packet() function and then return 1.
    +- struct mbuf * (*dequeue)(void *s);
    +    Called when the timer expires (or when a packet arrives and the scheduler
    +    instance is idle).
    +    This function is called when at least a packet can be send out. The
    +    scheduler choices the packet and returns it; if no packet are in the
    +    schedulerinstance, the function must return NULL.
    +    Before return a packet, it is important to call the function
    +    dn_return_packet() to update some statistic of the queue and update the
    +    queue counters.
    +- int (*drain_queue)(void *s, int flag);
    +    The system request to scheduler to delete all queues that is not using
    +    to free memory. The flag parameter indicate if a queue must be deleted
    +    even if it is active.
    +
    +- int (*create_alg_fs)(char *command, struct gen *g, int reconfigure);
    +    It is called when a flowset is linked with a scheduler. This is done
    +    when the scheduler is defined, so we can know the type of flowset.
    +    The function initialize the flowset paramenter parsing the command
    +    line. The parameter will be stored in the g struct that have the right
    +    size allocated by the system. If the reconfigure flag is set, it means
    +    that the flowset is reconfiguring
    +- int (*delete_alg_fs)(struct gen *f);
    +    It is called when a flowset is deleting. Must remove the memory allocate
    +    by the create_alg_fs() function.
    +
    +- int (*create_queue_alg)(struct dn_queue *q, struct gen *f);
    +    Called when a queue is created. The function should link the queue
    +    to the struct used by the scheduler instance to store all queues.
    +- int (*delete_queue_alg)(struct dn_queue *q);
    +    Called when a queue is deleting. The function should remove extra data
    +    and update the struct contains all queues in the scheduler instance.
    +
    +The struct scheduler represent the scheduler descriptor that is passed to
    +dummynet when a scheduler module is loaded.
    +This struct contains the type of scheduler, the lenght of all structs and
    +all function pointers.
    +If a function is not implemented should be initialize to NULL. Some functions
    +are mandatory, other are mandatory if some memory should be freed.
    +Mandatory functions:
    +- create_scheduler_instance()
    +- enqueue()
    +- dequeue()
    +- create_alg_fs()
    +- drain_queue()
    +Optional functions:
    +- config_scheduler()
    +- create_queue_alg()
    +Mandatory functions if the corresponding create...() has allocated memory:
    +- delete_scheduler_template()
    +- delete_scheduler_instance()
    +- delete_alg_fs()
    +- delete_queue_alg()
    +
    diff --git a/sys/netinet/ipfw/ip_dn_glue.c b/sys/netinet/ipfw/ip_dn_glue.c
    new file mode 100644
    index 00000000000..c0df1fc04be
    --- /dev/null
    +++ b/sys/netinet/ipfw/ip_dn_glue.c
    @@ -0,0 +1,845 @@
    +/*-    
    + * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
    + * 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$
    + *
    + * Binary compatibility support for /sbin/ipfw RELENG_7 and RELENG_8
    + */
    +
    +#include "opt_inet6.h"
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 	/* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
    +#include 
    +#include 	/* ip_output(), IP_FORWARDING */
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +/* FREEBSD7.2 ip_dummynet.h r191715*/
    +
    +struct dn_heap_entry7 {
    +	int64_t key;        /* sorting key. Topmost element is smallest one */
    +	void *object;      /* object pointer */
    +};
    +
    +struct dn_heap7 {
    +	int size;
    +	int elements;
    +	int offset; /* XXX if > 0 this is the offset of direct ptr to obj */
    +	struct dn_heap_entry7 *p;   /* really an array of "size" entries */
    +};
    +
    +/* Common to 7.2 and 8 */
    +struct dn_flow_set {
    +	SLIST_ENTRY(dn_flow_set)    next;   /* linked list in a hash slot */
    +
    +	u_short fs_nr ;             /* flow_set number       */
    +	u_short flags_fs;
    +#define DNOLD_HAVE_FLOW_MASK   0x0001
    +#define DNOLD_IS_RED       0x0002
    +#define DNOLD_IS_GENTLE_RED    0x0004
    +#define DNOLD_QSIZE_IS_BYTES   0x0008  /* queue size is measured in bytes */
    +#define DNOLD_NOERROR      0x0010  /* do not report ENOBUFS on drops  */
    +#define DNOLD_HAS_PROFILE      0x0020  /* the pipe has a delay profile. */
    +#define DNOLD_IS_PIPE      0x4000
    +#define DNOLD_IS_QUEUE     0x8000
    +
    +	struct dn_pipe7 *pipe ;  /* pointer to parent pipe */
    +	u_short parent_nr ;     /* parent pipe#, 0 if local to a pipe */
    +
    +	int weight ;        /* WFQ queue weight */
    +	int qsize ;         /* queue size in slots or bytes */
    +	int plr ;           /* pkt loss rate (2^31-1 means 100%) */
    +
    +	struct ipfw_flow_id flow_mask ;
    +
    +	/* hash table of queues onto this flow_set */
    +	int rq_size ;       /* number of slots */
    +	int rq_elements ;       /* active elements */
    +	struct dn_flow_queue7 **rq;  /* array of rq_size entries */
    +
    +	u_int32_t last_expired ;    /* do not expire too frequently */
    +	int backlogged ;        /* #active queues for this flowset */
    +
    +        /* RED parameters */
    +#define SCALE_RED               16
    +#define SCALE(x)                ( (x) << SCALE_RED )
    +#define SCALE_VAL(x)            ( (x) >> SCALE_RED )
    +#define SCALE_MUL(x,y)          ( ( (x) * (y) ) >> SCALE_RED )
    +	int w_q ;           /* queue weight (scaled) */
    +	int max_th ;        /* maximum threshold for queue (scaled) */
    +	int min_th ;        /* minimum threshold for queue (scaled) */
    +	int max_p ;         /* maximum value for p_b (scaled) */
    +	u_int c_1 ;         /* max_p/(max_th-min_th) (scaled) */
    +	u_int c_2 ;         /* max_p*min_th/(max_th-min_th) (scaled) */
    +	u_int c_3 ;         /* for GRED, (1-max_p)/max_th (scaled) */
    +	u_int c_4 ;         /* for GRED, 1 - 2*max_p (scaled) */
    +	u_int * w_q_lookup ;    /* lookup table for computing (1-w_q)^t */
    +	u_int lookup_depth ;    /* depth of lookup table */
    +	int lookup_step ;       /* granularity inside the lookup table */
    +	int lookup_weight ;     /* equal to (1-w_q)^t / (1-w_q)^(t+1) */
    +	int avg_pkt_size ;      /* medium packet size */
    +	int max_pkt_size ;      /* max packet size */
    +};
    +SLIST_HEAD(dn_flow_set_head, dn_flow_set);
    +
    +#define DN_IS_PIPE		0x4000
    +#define DN_IS_QUEUE		0x8000
    +struct dn_flow_queue7 {
    +	struct dn_flow_queue7 *next ;
    +	struct ipfw_flow_id id ;
    +
    +	struct mbuf *head, *tail ;  /* queue of packets */
    +	u_int len ;
    +	u_int len_bytes ;
    +
    +	u_long numbytes;
    +
    +	u_int64_t tot_pkts ;    /* statistics counters  */
    +	u_int64_t tot_bytes ;
    +	u_int32_t drops ;
    +
    +	int hash_slot ;     /* debugging/diagnostic */
    +
    +	/* RED parameters */
    +	int avg ;                   /* average queue length est. (scaled) */
    +	int count ;                 /* arrivals since last RED drop */
    +	int random ;                /* random value (scaled) */
    +	u_int32_t q_time;      /* start of queue idle time */
    +
    +	/* WF2Q+ support */
    +	struct dn_flow_set *fs ;    /* parent flow set */
    +	int heap_pos ;      /* position (index) of struct in heap */
    +	int64_t sched_time ;     /* current time when queue enters ready_heap */
    +
    +	int64_t S,F ;        /* start time, finish time */
    +};
    +
    +struct dn_pipe7 {        /* a pipe */
    +	SLIST_ENTRY(dn_pipe7)    next;   /* linked list in a hash slot */
    +
    +	int pipe_nr ;       /* number   */
    +	int bandwidth;      /* really, bytes/tick.  */
    +	int delay ;         /* really, ticks    */
    +
    +	struct  mbuf *head, *tail ; /* packets in delay line */
    +
    +	/* WF2Q+ */
    +	struct dn_heap7 scheduler_heap ; /* top extract - key Finish time*/
    +	struct dn_heap7 not_eligible_heap; /* top extract- key Start time */
    +	struct dn_heap7 idle_heap ; /* random extract - key Start=Finish time */
    +
    +	int64_t V ;          /* virtual time */
    +	int sum;            /* sum of weights of all active sessions */
    +
    +	int numbytes;
    +
    +	int64_t sched_time ;     /* time pipe was scheduled in ready_heap */
    +
    +	/*
    +	* When the tx clock come from an interface (if_name[0] != '\0'), its name
    +	* is stored below, whereas the ifp is filled when the rule is configured.
    +	*/
    +	char if_name[IFNAMSIZ];
    +	struct ifnet *ifp ;
    +	int ready ; /* set if ifp != NULL and we got a signal from it */
    +
    +	struct dn_flow_set fs ; /* used with fixed-rate flows */
    +};
    +SLIST_HEAD(dn_pipe_head7, dn_pipe7);
    +
    +
    +/* FREEBSD8 ip_dummynet.h r196045 */
    +struct dn_flow_queue8 {
    +	struct dn_flow_queue8 *next ;
    +	struct ipfw_flow_id id ;
    +
    +	struct mbuf *head, *tail ;  /* queue of packets */
    +	u_int len ;
    +	u_int len_bytes ;
    +
    +	uint64_t numbytes ;     /* credit for transmission (dynamic queues) */
    +	int64_t extra_bits;     /* extra bits simulating unavailable channel */
    +
    +	u_int64_t tot_pkts ;    /* statistics counters  */
    +	u_int64_t tot_bytes ;
    +	u_int32_t drops ;
    +
    +	int hash_slot ;     /* debugging/diagnostic */
    +
    +	/* RED parameters */
    +	int avg ;                   /* average queue length est. (scaled) */
    +	int count ;                 /* arrivals since last RED drop */
    +	int random ;                /* random value (scaled) */
    +	int64_t idle_time;       /* start of queue idle time */
    +
    +	/* WF2Q+ support */
    +	struct dn_flow_set *fs ;    /* parent flow set */
    +	int heap_pos ;      /* position (index) of struct in heap */
    +	int64_t sched_time ;     /* current time when queue enters ready_heap */
    +
    +	int64_t S,F ;        /* start time, finish time */
    +};
    +
    +struct dn_pipe8 {        /* a pipe */
    +	SLIST_ENTRY(dn_pipe8)    next;   /* linked list in a hash slot */
    +
    +	int pipe_nr ;       /* number   */
    +	int bandwidth;      /* really, bytes/tick.  */
    +	int delay ;         /* really, ticks    */
    +
    +	struct  mbuf *head, *tail ; /* packets in delay line */
    +
    +	/* WF2Q+ */
    +	struct dn_heap7 scheduler_heap ; /* top extract - key Finish time*/
    +	struct dn_heap7 not_eligible_heap; /* top extract- key Start time */
    +	struct dn_heap7 idle_heap ; /* random extract - key Start=Finish time */
    +
    +	int64_t V ;          /* virtual time */
    +	int sum;            /* sum of weights of all active sessions */
    +
    +	/* Same as in dn_flow_queue, numbytes can become large */
    +	int64_t numbytes;       /* bits I can transmit (more or less). */
    +	uint64_t burst;     /* burst size, scaled: bits * hz */
    +
    +	int64_t sched_time ;     /* time pipe was scheduled in ready_heap */
    +	int64_t idle_time;       /* start of pipe idle time */
    +
    +	char if_name[IFNAMSIZ];
    +	struct ifnet *ifp ;
    +	int ready ; /* set if ifp != NULL and we got a signal from it */
    +
    +	struct dn_flow_set fs ; /* used with fixed-rate flows */
    +
    +    /* fields to simulate a delay profile */
    +#define ED_MAX_NAME_LEN     32
    +	char name[ED_MAX_NAME_LEN];
    +	int loss_level;
    +	int samples_no;
    +	int *samples;
    +};
    +
    +#define ED_MAX_SAMPLES_NO   1024
    +struct dn_pipe_max8 {
    +	struct dn_pipe8 pipe;
    +	int samples[ED_MAX_SAMPLES_NO];
    +};
    +SLIST_HEAD(dn_pipe_head8, dn_pipe8);
    +
    +/*
    + * Changes from 7.2 to 8:
    + * dn_pipe:
    + *      numbytes from int to int64_t
    + *      add burst (int64_t)
    + *      add idle_time (int64_t)
    + *      add profile
    + *      add struct dn_pipe_max
    + *      add flag DN_HAS_PROFILE
    + *
    + * dn_flow_queue
    + *      numbytes from u_long to int64_t
    + *      add extra_bits (int64_t)
    + *      q_time from u_int32_t to int64_t and name idle_time
    + *
    + * dn_flow_set unchanged
    + *
    + */
    +
    +/* NOTE:XXX copied from dummynet.c */
    +#define O_NEXT(p, len) ((void *)((char *)p + len))
    +static void
    +oid_fill(struct dn_id *oid, int len, int type, uintptr_t id)
    +{
    +	oid->len = len;
    +	oid->type = type;
    +	oid->subtype = 0;
    +	oid->id = id;
    +}
    +/* make room in the buffer and move the pointer forward */
    +static void *
    +o_next(struct dn_id **o, int len, int type)
    +{
    +	struct dn_id *ret = *o;
    +	oid_fill(ret, len, type, 0);
    +	*o = O_NEXT(*o, len);
    +	return ret;
    +}
    +
    +
    +static size_t pipesize7 = sizeof(struct dn_pipe7);
    +static size_t pipesize8 = sizeof(struct dn_pipe8);
    +static size_t pipesizemax8 = sizeof(struct dn_pipe_max8);
    +
    +/* Indicate 'ipfw' version
    + * 1: from FreeBSD 7.2
    + * 0: from FreeBSD 8
    + * -1: unknow (for now is unused)
    + *
    + * It is update when a IP_DUMMYNET_DEL or IP_DUMMYNET_CONFIGURE request arrives
    + * NOTE: if a IP_DUMMYNET_GET arrives and the 'ipfw' version is unknow,
    + *       it is suppose to be the FreeBSD 8 version.
    + */
    +static int is7 = 0;
    +
    +static int
    +convertflags2new(int src)
    +{
    +	int dst = 0;
    +
    +	if (src & DNOLD_HAVE_FLOW_MASK)
    +		dst |= DN_HAVE_MASK;
    +	if (src & DNOLD_QSIZE_IS_BYTES)
    +		dst |= DN_QSIZE_BYTES;
    +	if (src & DNOLD_NOERROR)
    +		dst |= DN_NOERROR;
    +	if (src & DNOLD_IS_RED)
    +		dst |= DN_IS_RED;
    +	if (src & DNOLD_IS_GENTLE_RED)
    +		dst |= DN_IS_GENTLE_RED;
    +	if (src & DNOLD_HAS_PROFILE)
    +		dst |= DN_HAS_PROFILE;
    +
    +	return dst;
    +}
    +
    +static int
    +convertflags2old(int src)
    +{
    +	int dst = 0;
    +
    +	if (src & DN_HAVE_MASK)
    +		dst |= DNOLD_HAVE_FLOW_MASK;
    +	if (src & DN_IS_RED)
    +		dst |= DNOLD_IS_RED;
    +	if (src & DN_IS_GENTLE_RED)
    +		dst |= DNOLD_IS_GENTLE_RED;
    +	if (src & DN_NOERROR)
    +		dst |= DNOLD_NOERROR;
    +	if (src & DN_HAS_PROFILE)
    +		dst |= DNOLD_HAS_PROFILE;
    +	if (src & DN_QSIZE_BYTES)
    +		dst |= DNOLD_QSIZE_IS_BYTES;
    +
    +	return dst;
    +}
    +
    +static int
    +dn_compat_del(void *v)
    +{
    +	struct dn_pipe7 *p = (struct dn_pipe7 *) v;
    +	struct dn_pipe8 *p8 = (struct dn_pipe8 *) v;
    +	struct {
    +		struct dn_id oid;
    +		uintptr_t a[1];	/* add more if we want a list */
    +	} cmd;
    +
    +	/* XXX DN_API_VERSION ??? */
    +	oid_fill((void *)&cmd, sizeof(cmd), DN_CMD_DELETE, DN_API_VERSION);
    +
    +	if (is7) {
    +		if (p->pipe_nr == 0 && p->fs.fs_nr == 0)
    +			return EINVAL;
    +		if (p->pipe_nr != 0 && p->fs.fs_nr != 0)
    +			return EINVAL;
    +	} else {
    +		if (p8->pipe_nr == 0 && p8->fs.fs_nr == 0)
    +			return EINVAL;
    +		if (p8->pipe_nr != 0 && p8->fs.fs_nr != 0)
    +			return EINVAL;
    +	}
    +
    +	if (p->pipe_nr != 0) { /* pipe x delete */
    +		cmd.a[0] = p->pipe_nr;
    +		cmd.oid.subtype = DN_LINK;
    +	} else { /* queue x delete */
    +		cmd.oid.subtype = DN_FS;
    +		cmd.a[0] = (is7) ? p->fs.fs_nr : p8->fs.fs_nr;
    +	}
    +
    +	return do_config(&cmd, cmd.oid.len);
    +}
    +
    +static int
    +dn_compat_config_queue(struct dn_fs *fs, void* v)
    +{
    +	struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
    +	struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
    +	struct dn_flow_set *f;
    +
    +	if (is7)
    +		f = &p7->fs;
    +	else
    +		f = &p8->fs;
    +
    +	fs->fs_nr = f->fs_nr;
    +	fs->sched_nr = f->parent_nr;
    +	fs->flow_mask = f->flow_mask;
    +	fs->buckets = f->rq_size;
    +	fs->qsize = f->qsize;
    +	fs->plr = f->plr;
    +	fs->par[0] = f->weight;
    +	fs->flags = convertflags2new(f->flags_fs);
    +	if (fs->flags & DN_IS_GENTLE_RED || fs->flags & DN_IS_RED) {
    +		fs->w_q = f->w_q;
    +		fs->max_th = f->max_th;
    +		fs->min_th = f->min_th;
    +		fs->max_p = f->max_p;
    +	}
    +
    +	return 0;
    +}
    +
    +static int
    +dn_compat_config_pipe(struct dn_sch *sch, struct dn_link *p, 
    +		      struct dn_fs *fs, void* v)
    +{
    +	struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
    +	struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
    +	int i = p7->pipe_nr;
    +
    +	sch->sched_nr = i;
    +	sch->oid.subtype = 0;
    +	p->link_nr = i;
    +	fs->fs_nr = i + 2*DN_MAX_ID;
    +	fs->sched_nr = i + DN_MAX_ID;
    +
    +	/* Common to 7 and 8 */
    +	p->bandwidth = p7->bandwidth;
    +	p->delay = p7->delay;
    +	if (!is7) {
    +		/* FreeBSD 8 has burst  */
    +		p->burst = p8->burst;
    +	}
    +
    +	/* fill the fifo flowset */
    +	dn_compat_config_queue(fs, v);
    +	fs->fs_nr = i + 2*DN_MAX_ID;
    +	fs->sched_nr = i + DN_MAX_ID;
    +
    +	/* Move scheduler related parameter from fs to sch */
    +	sch->buckets = fs->buckets; /*XXX*/
    +	fs->buckets = 0;
    +	if (fs->flags & DN_HAVE_MASK) {
    +		sch->flags |= DN_HAVE_MASK;
    +		fs->flags &= ~DN_HAVE_MASK;
    +		sch->sched_mask = fs->flow_mask;
    +		bzero(&fs->flow_mask, sizeof(struct ipfw_flow_id));
    +	}
    +
    +	return 0;
    +}
    +
    +static int
    +dn_compat_config_profile(struct dn_profile *pf, struct dn_link *p,
    +			 void *v)
    +{
    +	struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
    +
    +	p8->samples = &(((struct dn_pipe_max8 *)p8)->samples[0]);
    +	
    +	pf->link_nr = p->link_nr;
    +	pf->loss_level = p8->loss_level;
    +// 	pf->bandwidth = p->bandwidth; //XXX bandwidth redundant?
    +	pf->samples_no = p8->samples_no;
    +	strncpy(pf->name, p8->name,sizeof(pf->name));
    +	bcopy(p8->samples, pf->samples, sizeof(pf->samples));
    +
    +	return 0;
    +}
    +
    +/*
    + * If p->pipe_nr != 0 the command is 'pipe x config', so need to create
    + * the three main struct, else only a flowset is created
    + */
    +static int
    +dn_compat_configure(void *v)
    +{
    +	struct dn_id *buf = NULL, *base;
    +	struct dn_sch *sch = NULL;
    +	struct dn_link *p = NULL;
    +	struct dn_fs *fs = NULL;
    +	struct dn_profile *pf = NULL;
    +	int lmax;
    +	int error;
    +
    +	struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
    +	struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
    +
    +	int i; /* number of object to configure */
    +
    +	lmax = sizeof(struct dn_id);	/* command header */
    +	lmax += sizeof(struct dn_sch) + sizeof(struct dn_link) +
    +		sizeof(struct dn_fs) + sizeof(struct dn_profile);
    +
    +	base = buf = malloc(lmax, M_DUMMYNET, M_WAIT|M_ZERO);
    +	o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIG);
    +	base->id = DN_API_VERSION;
    +
    +	/* pipe_nr is the same in p7 and p8 */
    +	i = p7->pipe_nr;
    +	if (i != 0) { /* pipe config */
    +		sch = o_next(&buf, sizeof(*sch), DN_SCH);
    +		p = o_next(&buf, sizeof(*p), DN_LINK);
    +		fs = o_next(&buf, sizeof(*fs), DN_FS);
    +
    +		error = dn_compat_config_pipe(sch, p, fs, v);
    +		if (error) {
    +			free(buf, M_DUMMYNET);
    +			return error;
    +		}
    +		if (!is7 && p8->samples_no > 0) {
    +			/* Add profiles*/
    +			pf = o_next(&buf, sizeof(*pf), DN_PROFILE);
    +			error = dn_compat_config_profile(pf, p, v);
    +			if (error) {
    +				free(buf, M_DUMMYNET);
    +				return error;
    +			}
    +		}
    +	} else { /* queue config */
    +		fs = o_next(&buf, sizeof(*fs), DN_FS);
    +		error = dn_compat_config_queue(fs, v);
    +		if (error) {
    +			free(buf, M_DUMMYNET);
    +			return error;
    +		}
    +	}
    +	error = do_config(base, (char *)buf - (char *)base);
    +
    +	if (buf)
    +		free(buf, M_DUMMYNET);
    +	return error;
    +}
    +
    +int
    +dn_compat_calc_size(struct dn_parms dn_cfg)
    +{
    +	int need = 0;
    +	/* XXX use FreeBSD 8 struct size */
    +	/* NOTE:
    +	 * - half scheduler: 		schk_count/2
    +	 * - all flowset:		fsk_count
    +	 * - all flowset queues:	queue_count
    +	 * - all pipe queue:		si_count
    +	 */
    +	need += dn_cfg.schk_count * sizeof(struct dn_pipe8) / 2;
    +	need += dn_cfg.fsk_count * sizeof(struct dn_flow_set);
    +	need += dn_cfg.si_count * sizeof(struct dn_flow_queue8);
    +	need += dn_cfg.queue_count * sizeof(struct dn_flow_queue8);
    +
    +	return need;
    +}
    +
    +int
    +dn_c_copy_q (void *_ni, void *arg)
    +{
    +	struct copy_args *a = arg;
    +	struct dn_flow_queue7 *fq7 = (struct dn_flow_queue7 *)*a->start;
    +	struct dn_flow_queue8 *fq8 = (struct dn_flow_queue8 *)*a->start;
    +	struct dn_flow *ni = (struct dn_flow *)_ni;
    +	int size = 0;
    +
    +	/* XXX hash slot not set */
    +	/* No difference between 7.2/8 */
    +	fq7->len = ni->length;
    +	fq7->len_bytes = ni->len_bytes;
    +	fq7->id = ni->fid;
    +
    +	if (is7) {
    +		size = sizeof(struct dn_flow_queue7);
    +		fq7->tot_pkts = ni->tot_pkts;
    +		fq7->tot_bytes = ni->tot_bytes;
    +		fq7->drops = ni->drops;
    +	} else {
    +		size = sizeof(struct dn_flow_queue8);
    +		fq8->tot_pkts = ni->tot_pkts;
    +		fq8->tot_bytes = ni->tot_bytes;
    +		fq8->drops = ni->drops;
    +	}
    +
    +	*a->start += size;
    +	return 0;
    +}
    +
    +int
    +dn_c_copy_pipe(struct dn_schk *s, struct copy_args *a, int nq)
    +{
    +	struct dn_link *l = &s->link;
    +	struct dn_fsk *f = s->fs;
    +
    +	struct dn_pipe7 *pipe7 = (struct dn_pipe7 *)*a->start;
    +	struct dn_pipe8 *pipe8 = (struct dn_pipe8 *)*a->start;
    +	struct dn_flow_set *fs;
    +	int size = 0;
    +
    +	if (is7) {
    +		fs = &pipe7->fs;
    +		size = sizeof(struct dn_pipe7);
    +	} else {
    +		fs = &pipe8->fs;
    +		size = sizeof(struct dn_pipe8);
    +	}
    +
    +	/* These 4 field are the same in pipe7 and pipe8 */
    +	pipe7->next.sle_next = (struct dn_pipe7 *)DN_IS_PIPE;
    +	pipe7->bandwidth = l->bandwidth;
    +	pipe7->delay = l->delay;
    +	pipe7->pipe_nr = l->link_nr - DN_MAX_ID;
    +
    +	if (!is7) {
    +		if (s->profile) {
    +			struct dn_profile *pf = s->profile;
    +			strncpy(pipe8->name, pf->name, sizeof(pf->name));
    +			pipe8->loss_level = pf->loss_level;
    +			pipe8->samples_no = pf->samples_no;
    +		}
    +		pipe8->burst = div64(l->burst , 8 * hz);
    +	}
    +
    +	fs->flow_mask = s->sch.sched_mask;
    +	fs->rq_size = s->sch.buckets ? s->sch.buckets : 1;
    +
    +	fs->parent_nr = l->link_nr - DN_MAX_ID;
    +	fs->qsize = f->fs.qsize;
    +	fs->plr = f->fs.plr;
    +	fs->w_q = f->fs.w_q;
    +	fs->max_th = f->max_th;
    +	fs->min_th = f->min_th;
    +	fs->max_p = f->fs.max_p;
    +	fs->rq_elements = nq;
    +
    +	fs->flags_fs = convertflags2old(f->fs.flags);
    +
    +	*a->start += size;
    +	return 0;
    +}
    +
    +
    +int
    +dn_compat_copy_pipe(struct copy_args *a, void *_o)
    +{
    +	int have = a->end - *a->start;
    +	int need = 0;
    +	int pipe_size = sizeof(struct dn_pipe8);
    +	int queue_size = sizeof(struct dn_flow_queue8);
    +	int n_queue = 0; /* number of queues */
    +
    +	struct dn_schk *s = (struct dn_schk *)_o;
    +	/* calculate needed space:
    +	 * - struct dn_pipe
    +	 * - if there are instances, dn_queue * n_instances
    +	 */
    +	n_queue = (s->sch.flags & DN_HAVE_MASK ? dn_ht_entries(s->siht) :
    +						(s->siht ? 1 : 0));
    +	need = pipe_size + queue_size * n_queue;
    +	if (have < need) {
    +		D("have %d < need %d", have, need);
    +		return 1;
    +	}
    +	/* copy pipe */
    +	dn_c_copy_pipe(s, a, n_queue);
    +
    +	/* copy queues */
    +	if (s->sch.flags & DN_HAVE_MASK)
    +		dn_ht_scan(s->siht, dn_c_copy_q, a);
    +	else if (s->siht)
    +		dn_c_copy_q(s->siht, a);
    +	return 0;
    +}
    +
    +int
    +dn_c_copy_fs(struct dn_fsk *f, struct copy_args *a, int nq)
    +{
    +	struct dn_flow_set *fs = (struct dn_flow_set *)*a->start;
    +
    +	fs->next.sle_next = (struct dn_flow_set *)DN_IS_QUEUE;
    +	fs->fs_nr = f->fs.fs_nr;
    +	fs->qsize = f->fs.qsize;
    +	fs->plr = f->fs.plr;
    +	fs->w_q = f->fs.w_q;
    +	fs->max_th = f->max_th;
    +	fs->min_th = f->min_th;
    +	fs->max_p = f->fs.max_p;
    +	fs->flow_mask = f->fs.flow_mask;
    +	fs->rq_elements = nq;
    +	fs->rq_size = (f->fs.buckets ? f->fs.buckets : 1);
    +	fs->parent_nr = f->fs.sched_nr;
    +	fs->weight = f->fs.par[0];
    +
    +	fs->flags_fs = convertflags2old(f->fs.flags);
    +	*a->start += sizeof(struct dn_flow_set);
    +	return 0;
    +}
    +
    +int
    +dn_compat_copy_queue(struct copy_args *a, void *_o)
    +{
    +	int have = a->end - *a->start;
    +	int need = 0;
    +	int fs_size = sizeof(struct dn_flow_set);
    +	int queue_size = sizeof(struct dn_flow_queue8);
    +
    +	struct dn_fsk *fs = (struct dn_fsk *)_o;
    +	int n_queue = 0; /* number of queues */
    +
    +	n_queue = (fs->fs.flags & DN_HAVE_MASK ? dn_ht_entries(fs->qht) :
    +						(fs->qht ? 1 : 0));
    +
    +	need = fs_size + queue_size * n_queue;
    +	if (have < need) {
    +		D("have < need");
    +		return 1;
    +	}
    +
    +	/* copy flowset */
    +	dn_c_copy_fs(fs, a, n_queue);
    +
    +	/* copy queues */
    +	if (fs->fs.flags & DN_HAVE_MASK)
    +		dn_ht_scan(fs->qht, dn_c_copy_q, a);
    +	else if (fs->qht)
    +		dn_c_copy_q(fs->qht, a);
    +
    +	return 0;
    +}
    +
    +int
    +copy_data_helper_compat(void *_o, void *_arg)
    +{
    +	struct copy_args *a = _arg;
    +
    +	if (a->type == DN_COMPAT_PIPE) {
    +		struct dn_schk *s = _o;
    +		if (s->sch.oid.subtype != 1 || s->sch.sched_nr <= DN_MAX_ID) {
    +			return 0;	/* not old type */
    +		}
    +		/* copy pipe parameters, and if instance exists, copy
    +		 * other parameters and eventually queues.
    +		 */
    +		if(dn_compat_copy_pipe(a, _o))
    +			return DNHT_SCAN_END;
    +	} else if (a->type == DN_COMPAT_QUEUE) {
    +		struct dn_fsk *fs = _o;
    +		if (fs->fs.fs_nr >= DN_MAX_ID)
    +			return 0;
    +		if (dn_compat_copy_queue(a, _o))
    +			return DNHT_SCAN_END;
    +	}
    +	return 0;
    +}
    +
    +/* Main function to manage old requests */
    +int
    +ip_dummynet_compat(struct sockopt *sopt)
    +{
    +	int error=0;
    +	void *v = NULL;
    +	struct dn_id oid;
    +
    +	/* Lenght of data, used to found ipfw version... */
    +	int len = sopt->sopt_valsize;
    +
    +	/* len can be 0 if command was dummynet_flush */
    +	if (len == pipesize7) {
    +		D("setting compatibility with FreeBSD 7.2");
    +		is7 = 1;
    +	}
    +	else if (len == pipesize8 || len == pipesizemax8) {
    +		D("setting compatibility with FreeBSD 8");
    +		is7 = 0;
    +	}
    +
    +	switch (sopt->sopt_name) {
    +	default:
    +		printf("dummynet: -- unknown option %d", sopt->sopt_name);
    +		error = EINVAL;
    +		break;
    +
    +	case IP_DUMMYNET_FLUSH:
    +		oid_fill(&oid, sizeof(oid), DN_CMD_FLUSH, DN_API_VERSION);
    +		do_config(&oid, oid.len);
    +		break;
    +
    +	case IP_DUMMYNET_DEL:
    +		v = malloc(len, M_TEMP, M_WAITOK);
    +		error = sooptcopyin(sopt, v, len, len);
    +		if (error)
    +			break;
    +		error = dn_compat_del(v);
    +		free(v, M_DUMMYNET);
    +		break;
    +
    +	case IP_DUMMYNET_CONFIGURE:
    +		v = malloc(len, M_TEMP, M_WAITOK);
    +		error = sooptcopyin(sopt, v, len, len);
    +		if (error)
    +			break;
    +		error = dn_compat_configure(v);
    +		free(v, M_DUMMYNET);
    +		break;
    +
    +	case IP_DUMMYNET_GET: {
    +		void *buf;
    +		int ret;
    +		int original_size = sopt->sopt_valsize;
    +		int size;
    +
    +		ret = dummynet_get(sopt, &buf);
    +		if (ret)
    +			return 0;//XXX ?
    +		size = sopt->sopt_valsize;
    +		sopt->sopt_valsize = original_size;
    +		D("size=%d, buf=%p", size, buf);
    +		ret = sooptcopyout(sopt, buf, size);
    +		if (ret)
    +			printf("  %s ERROR sooptcopyout\n", __FUNCTION__);
    +		if (buf)
    +			free(buf, M_DUMMYNET);
    +	    }
    +	}
    +
    +	return error;
    +}
    +
    +
    diff --git a/sys/netinet/ipfw/ip_dn_io.c b/sys/netinet/ipfw/ip_dn_io.c
    new file mode 100644
    index 00000000000..70f14ca65d7
    --- /dev/null
    +++ b/sys/netinet/ipfw/ip_dn_io.c
    @@ -0,0 +1,788 @@
    +/*-
    + * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa
    + * 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.
    + */
    +
    +/*
    + * Dummynet portions related to packet handling.
    + */
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include "opt_inet6.h"
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 	/* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
    +#include 
    +#include 
    +#include 		/* ip_len, ip_off */
    +#include 	/* ip_output(), IP_FORWARDING */
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include  /* various ether_* routines */
    +
    +#include        /* for ip6_input, ip6_output prototypes */
    +#include 
    +
    +/*
    + * We keep a private variable for the simulation time, but we could
    + * probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
    + * instead of dn_cfg.curr_time
    + */
    +
    +struct dn_parms dn_cfg;
    +
    +static long tick_last;		/* Last tick duration (usec). */
    +static long tick_delta;		/* Last vs standard tick diff (usec). */
    +static long tick_delta_sum;	/* Accumulated tick difference (usec).*/
    +static long tick_adjustment;	/* Tick adjustments done. */
    +static long tick_lost;		/* Lost(coalesced) ticks number. */
    +/* Adjusted vs non-adjusted curr_time difference (ticks). */
    +static long tick_diff;
    +
    +static unsigned long	io_pkt;
    +static unsigned long	io_pkt_fast;
    +static unsigned long	io_pkt_drop;
    +
    +/*
    + * We use a heap to store entities for which we have pending timer events.
    + * The heap is checked at every tick and all entities with expired events
    + * are extracted.
    + */
    +  
    +MALLOC_DEFINE(M_DUMMYNET, "dummynet", "dummynet heap");
    +
    +extern	void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
    +
    +#ifdef SYSCTL_NODE
    +
    +SYSBEGIN(f4)
    +
    +SYSCTL_DECL(_net_inet);
    +SYSCTL_DECL(_net_inet_ip);
    +SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet");
    +
    +/* parameters */
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, hash_size,
    +    CTLFLAG_RW, &dn_cfg.hash_size, 0, "Default hash table size");
    +SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_slot_limit,
    +    CTLFLAG_RW, &dn_cfg.slot_limit, 0,
    +    "Upper limit in slots for pipe queue.");
    +SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_byte_limit,
    +    CTLFLAG_RW, &dn_cfg.byte_limit, 0,
    +    "Upper limit in bytes for pipe queue.");
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, io_fast,
    +    CTLFLAG_RW, &dn_cfg.io_fast, 0, "Enable fast dummynet io.");
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, debug,
    +    CTLFLAG_RW, &dn_cfg.debug, 0, "Dummynet debug level");
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, expire,
    +    CTLFLAG_RW, &dn_cfg.expire, 0, "Expire empty queues/pipes");
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, expire_cycle,
    +    CTLFLAG_RD, &dn_cfg.expire_cycle, 0, "Expire cycle for queues/pipes");
    +
    +/* RED parameters */
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_lookup_depth,
    +    CTLFLAG_RD, &dn_cfg.red_lookup_depth, 0, "Depth of RED lookup table");
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_avg_pkt_size,
    +    CTLFLAG_RD, &dn_cfg.red_avg_pkt_size, 0, "RED Medium packet size");
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_max_pkt_size,
    +    CTLFLAG_RD, &dn_cfg.red_max_pkt_size, 0, "RED Max packet size");
    +
    +/* time adjustment */
    +SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta,
    +    CTLFLAG_RD, &tick_delta, 0, "Last vs standard tick difference (usec).");
    +SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta_sum,
    +    CTLFLAG_RD, &tick_delta_sum, 0, "Accumulated tick difference (usec).");
    +SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_adjustment,
    +    CTLFLAG_RD, &tick_adjustment, 0, "Tick adjustments done.");
    +SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_diff,
    +    CTLFLAG_RD, &tick_diff, 0,
    +    "Adjusted vs non-adjusted curr_time difference (ticks).");
    +SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_lost,
    +    CTLFLAG_RD, &tick_lost, 0,
    +    "Number of ticks coalesced by dummynet taskqueue.");
    +
    +/* statistics */
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, schk_count,
    +    CTLFLAG_RD, &dn_cfg.schk_count, 0, "Number of schedulers");
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, si_count,
    +    CTLFLAG_RD, &dn_cfg.si_count, 0, "Number of scheduler instances");
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, fsk_count,
    +    CTLFLAG_RD, &dn_cfg.fsk_count, 0, "Number of flowsets");
    +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, queue_count,
    +    CTLFLAG_RD, &dn_cfg.queue_count, 0, "Number of queues");
    +SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt,
    +    CTLFLAG_RD, &io_pkt, 0,
    +    "Number of packets passed to dummynet.");
    +SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_fast,
    +    CTLFLAG_RD, &io_pkt_fast, 0,
    +    "Number of packets bypassed dummynet scheduler.");
    +SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_drop,
    +    CTLFLAG_RD, &io_pkt_drop, 0,
    +    "Number of packets dropped by dummynet.");
    +
    +SYSEND
    +
    +#endif
    +
    +static void	dummynet_send(struct mbuf *);
    +
    +/*
    + * Packets processed by dummynet have an mbuf tag associated with
    + * them that carries their dummynet state.
    + * Outside dummynet, only the 'rule' field is relevant, and it must
    + * be at the beginning of the structure.
    + */
    +struct dn_pkt_tag {
    +	struct ipfw_rule_ref rule;	/* matching rule	*/
    +
    +	/* second part, dummynet specific */
    +	int dn_dir;		/* action when packet comes out.*/
    +				/* see ip_fw_private.h		*/
    +	uint64_t output_time;	/* when the pkt is due for delivery*/
    +	struct ifnet *ifp;	/* interface, for ip_output	*/
    +	struct _ip6dn_args ip6opt;	/* XXX ipv6 options	*/
    +};
    +
    +/*
    + * Return the mbuf tag holding the dummynet state (it should
    + * be the first one on the list).
    + */
    +static struct dn_pkt_tag *
    +dn_tag_get(struct mbuf *m)
    +{
    +	struct m_tag *mtag = m_tag_first(m);
    +	KASSERT(mtag != NULL &&
    +	    mtag->m_tag_cookie == MTAG_ABI_COMPAT &&
    +	    mtag->m_tag_id == PACKET_TAG_DUMMYNET,
    +	    ("packet on dummynet queue w/o dummynet tag!"));
    +	return (struct dn_pkt_tag *)(mtag+1);
    +}
    +
    +static inline void
    +mq_append(struct mq *q, struct mbuf *m)
    +{
    +	if (q->head == NULL)
    +		q->head = m;
    +	else
    +		q->tail->m_nextpkt = m;
    +	q->tail = m;
    +	m->m_nextpkt = NULL;
    +}
    +
    +/*
    + * Dispose a list of packet. Use a functions so if we need to do
    + * more work, this is a central point to do it.
    + */
    +void dn_free_pkts(struct mbuf *mnext)
    +{
    +        struct mbuf *m;
    +    
    +        while ((m = mnext) != NULL) {
    +                mnext = m->m_nextpkt;
    +                FREE_PKT(m);
    +        }
    +}
    +
    +static int
    +red_drops (struct dn_queue *q, int len)
    +{
    +	/*
    +	 * RED algorithm
    +	 *
    +	 * RED calculates the average queue size (avg) using a low-pass filter
    +	 * with an exponential weighted (w_q) moving average:
    +	 * 	avg  <-  (1-w_q) * avg + w_q * q_size
    +	 * where q_size is the queue length (measured in bytes or * packets).
    +	 *
    +	 * If q_size == 0, we compute the idle time for the link, and set
    +	 *	avg = (1 - w_q)^(idle/s)
    +	 * where s is the time needed for transmitting a medium-sized packet.
    +	 *
    +	 * Now, if avg < min_th the packet is enqueued.
    +	 * If avg > max_th the packet is dropped. Otherwise, the packet is
    +	 * dropped with probability P function of avg.
    +	 */
    +
    +	struct dn_fsk *fs = q->fs;
    +	int64_t p_b = 0;
    +
    +	/* Queue in bytes or packets? */
    +	uint32_t q_size = (fs->fs.flags & DN_QSIZE_BYTES) ?
    +	    q->ni.len_bytes : q->ni.length;
    +
    +	/* Average queue size estimation. */
    +	if (q_size != 0) {
    +		/* Queue is not empty, avg <- avg + (q_size - avg) * w_q */
    +		int diff = SCALE(q_size) - q->avg;
    +		int64_t v = SCALE_MUL((int64_t)diff, (int64_t)fs->w_q);
    +
    +		q->avg += (int)v;
    +	} else {
    +		/*
    +		 * Queue is empty, find for how long the queue has been
    +		 * empty and use a lookup table for computing
    +		 * (1 - * w_q)^(idle_time/s) where s is the time to send a
    +		 * (small) packet.
    +		 * XXX check wraps...
    +		 */
    +		if (q->avg) {
    +			u_int t = div64((dn_cfg.curr_time - q->q_time), fs->lookup_step);
    +
    +			q->avg = (t < fs->lookup_depth) ?
    +			    SCALE_MUL(q->avg, fs->w_q_lookup[t]) : 0;
    +		}
    +	}
    +
    +	/* Should i drop? */
    +	if (q->avg < fs->min_th) {
    +		q->count = -1;
    +		return (0);	/* accept packet */
    +	}
    +	if (q->avg >= fs->max_th) {	/* average queue >=  max threshold */
    +		if (fs->fs.flags & DN_IS_GENTLE_RED) {
    +			/*
    +			 * According to Gentle-RED, if avg is greater than
    +			 * max_th the packet is dropped with a probability
    +			 *	 p_b = c_3 * avg - c_4
    +			 * where c_3 = (1 - max_p) / max_th
    +			 *       c_4 = 1 - 2 * max_p
    +			 */
    +			p_b = SCALE_MUL((int64_t)fs->c_3, (int64_t)q->avg) -
    +			    fs->c_4;
    +		} else {
    +			q->count = -1;
    +			return (1);
    +		}
    +	} else if (q->avg > fs->min_th) {
    +		/*
    +		 * We compute p_b using the linear dropping function
    +		 *	 p_b = c_1 * avg - c_2
    +		 * where c_1 = max_p / (max_th - min_th)
    +		 * 	 c_2 = max_p * min_th / (max_th - min_th)
    +		 */
    +		p_b = SCALE_MUL((int64_t)fs->c_1, (int64_t)q->avg) - fs->c_2;
    +	}
    +
    +	if (fs->fs.flags & DN_QSIZE_BYTES)
    +		p_b = div64((p_b * len) , fs->max_pkt_size);
    +	if (++q->count == 0)
    +		q->random = random() & 0xffff;
    +	else {
    +		/*
    +		 * q->count counts packets arrived since last drop, so a greater
    +		 * value of q->count means a greater packet drop probability.
    +		 */
    +		if (SCALE_MUL(p_b, SCALE((int64_t)q->count)) > q->random) {
    +			q->count = 0;
    +			/* After a drop we calculate a new random value. */
    +			q->random = random() & 0xffff;
    +			return (1);	/* drop */
    +		}
    +	}
    +	/* End of RED algorithm. */
    +
    +	return (0);	/* accept */
    +
    +}
    +
    +/*
    + * Enqueue a packet in q, subject to space and queue management policy
    + * (whose parameters are in q->fs).
    + * Update stats for the queue and the scheduler.
    + * Return 0 on success, 1 on drop. The packet is consumed anyways.
    + */
    +int
    +dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
    +{   
    +	struct dn_fs *f;
    +	struct dn_flow *ni;	/* stats for scheduler instance */
    +	uint64_t len;
    +
    +	if (q->fs == NULL || q->_si == NULL) {
    +		printf("%s fs %p si %p, dropping\n",
    +			__FUNCTION__, q->fs, q->_si);
    +		FREE_PKT(m);
    +		return 1;
    +	}
    +	f = &(q->fs->fs);
    +	ni = &q->_si->ni;
    +	len = m->m_pkthdr.len;
    +	/* Update statistics, then check reasons to drop pkt. */
    +	q->ni.tot_bytes += len;
    +	q->ni.tot_pkts++;
    +	ni->tot_bytes += len;
    +	ni->tot_pkts++;
    +	if (drop)
    +		goto drop;
    +	if (f->plr && random() < f->plr)
    +		goto drop;
    +	if (f->flags & DN_IS_RED && red_drops(q, m->m_pkthdr.len))
    +		goto drop;
    +	if (f->flags & DN_QSIZE_BYTES) {
    +		if (q->ni.len_bytes > f->qsize)
    +			goto drop;
    +	} else if (q->ni.length >= f->qsize) {
    +		goto drop;
    +	}
    +	mq_append(&q->mq, m);
    +	q->ni.length++;
    +	q->ni.len_bytes += len;
    +	ni->length++;
    +	ni->len_bytes += len;
    +	return 0;
    +
    +drop:
    +	io_pkt_drop++;
    +	q->ni.drops++;
    +	ni->drops++;
    +	FREE_PKT(m);
    +	return 1;
    +}
    +
    +/*
    + * Fetch packets from the delay line which are due now. If there are
    + * leftover packets, reinsert the delay line in the heap.
    + * Runs under scheduler lock.
    + */
    +static void
    +transmit_event(struct mq *q, struct delay_line *dline, uint64_t now)
    +{
    +	struct mbuf *m;
    +	struct dn_pkt_tag *pkt = NULL;
    +
    +	dline->oid.subtype = 0; /* not in heap */
    +	while ((m = dline->mq.head) != NULL) {
    +		pkt = dn_tag_get(m);
    +		if (!DN_KEY_LEQ(pkt->output_time, now))
    +			break;
    +		dline->mq.head = m->m_nextpkt;
    +		mq_append(q, m);
    +	}
    +	if (m != NULL) {
    +		dline->oid.subtype = 1; /* in heap */
    +		heap_insert(&dn_cfg.evheap, pkt->output_time, dline);
    +	}
    +}
    +
    +/*
    + * Convert the additional MAC overheads/delays into an equivalent
    + * number of bits for the given data rate. The samples are
    + * in milliseconds so we need to divide by 1000.
    + */
    +static uint64_t
    +extra_bits(struct mbuf *m, struct dn_schk *s)
    +{
    +	int index;
    +	uint64_t bits;
    +	struct dn_profile *pf = s->profile;
    +
    +	if (!pf || pf->samples_no == 0)
    +		return 0;
    +	index  = random() % pf->samples_no;
    +	bits = div64((uint64_t)pf->samples[index] * s->link.bandwidth, 1000);
    +	if (index >= pf->loss_level) {
    +		struct dn_pkt_tag *dt = dn_tag_get(m);
    +		if (dt)
    +			dt->dn_dir = DIR_DROP;
    +	}
    +	return bits;
    +}
    +
    +/*
    + * Send traffic from a scheduler instance due by 'now'.
    + * Return a pointer to the head of the queue.
    + */
    +static struct mbuf *
    +serve_sched(struct mq *q, struct dn_sch_inst *si, uint64_t now)
    +{
    +	struct mq def_q;
    +	struct dn_schk *s = si->sched;
    +	struct mbuf *m = NULL;
    +	int delay_line_idle = (si->dline.mq.head == NULL);
    +	int done, bw;
    +
    +	if (q == NULL) {
    +		q = &def_q;
    +		q->head = NULL;
    +	}
    +
    +	bw = s->link.bandwidth;
    +	si->kflags &= ~DN_ACTIVE;
    +
    +	if (bw > 0)
    +		si->credit += (now - si->sched_time) * bw;
    +	else
    +		si->credit = 0;
    +	si->sched_time = now;
    +	done = 0;
    +	while (si->credit >= 0 && (m = s->fp->dequeue(si)) != NULL) {
    +		uint64_t len_scaled;
    +		done++;
    +		len_scaled = (bw == 0) ? 0 : hz *
    +		    (m->m_pkthdr.len * 8 + extra_bits(m, s));
    +		si->credit -= len_scaled;
    +		/* Move packet in the delay line */
    +		dn_tag_get(m)->output_time += s->link.delay ;
    +		mq_append(&si->dline.mq, m);
    +	}
    +	/*
    +	 * If credit >= 0 the instance is idle, mark time.
    +	 * Otherwise put back in the heap, and adjust the output
    +	 * time of the last inserted packet, m, which was too early.
    +	 */
    +	if (si->credit >= 0) {
    +		si->idle_time = now;
    +	} else {
    +		uint64_t t;
    +		KASSERT (bw > 0, ("bw=0 and credit<0 ?"));
    +		t = div64(bw - 1 - si->credit, bw);
    +		if (m)
    +			dn_tag_get(m)->output_time += t;
    +		si->kflags |= DN_ACTIVE;
    +		heap_insert(&dn_cfg.evheap, now + t, si);
    +	}
    +	if (delay_line_idle && done)
    +		transmit_event(q, &si->dline, now);
    +	return q->head;
    +}
    +
    +/*
    + * The timer handler for dummynet. Time is computed in ticks, but
    + * but the code is tolerant to the actual rate at which this is called.
    + * Once complete, the function reschedules itself for the next tick.
    + */
    +void
    +dummynet_task(void *context, int pending)
    +{
    +	struct timeval t;
    +	struct mq q = { NULL, NULL }; /* queue to accumulate results */
    +
    +	DN_BH_WLOCK();
    +
    +	/* Update number of lost(coalesced) ticks. */
    +	tick_lost += pending - 1;
    +
    +	getmicrouptime(&t);
    +	/* Last tick duration (usec). */
    +	tick_last = (t.tv_sec - dn_cfg.prev_t.tv_sec) * 1000000 +
    +	(t.tv_usec - dn_cfg.prev_t.tv_usec);
    +	/* Last tick vs standard tick difference (usec). */
    +	tick_delta = (tick_last * hz - 1000000) / hz;
    +	/* Accumulated tick difference (usec). */
    +	tick_delta_sum += tick_delta;
    +
    +	dn_cfg.prev_t = t;
    +
    +	/*
    +	* Adjust curr_time if the accumulated tick difference is
    +	* greater than the 'standard' tick. Since curr_time should
    +	* be monotonically increasing, we do positive adjustments
    +	* as required, and throttle curr_time in case of negative
    +	* adjustment.
    +	*/
    +	dn_cfg.curr_time++;
    +	if (tick_delta_sum - tick >= 0) {
    +		int diff = tick_delta_sum / tick;
    +
    +		dn_cfg.curr_time += diff;
    +		tick_diff += diff;
    +		tick_delta_sum %= tick;
    +		tick_adjustment++;
    +	} else if (tick_delta_sum + tick <= 0) {
    +		dn_cfg.curr_time--;
    +		tick_diff--;
    +		tick_delta_sum += tick;
    +		tick_adjustment++;
    +	}
    +
    +	/* serve pending events, accumulate in q */
    +	for (;;) {
    +		struct dn_id *p;    /* generic parameter to handler */
    +
    +		if (dn_cfg.evheap.elements == 0 ||
    +		    DN_KEY_LT(dn_cfg.curr_time, HEAP_TOP(&dn_cfg.evheap)->key))
    +			break;
    +		p = HEAP_TOP(&dn_cfg.evheap)->object;
    +		heap_extract(&dn_cfg.evheap, NULL);
    +
    +		if (p->type == DN_SCH_I) {
    +			serve_sched(&q, (struct dn_sch_inst *)p, dn_cfg.curr_time);
    +		} else { /* extracted a delay line */
    +			transmit_event(&q, (struct delay_line *)p, dn_cfg.curr_time);
    +		}
    +	}
    +	if (dn_cfg.expire && ++dn_cfg.expire_cycle >= dn_cfg.expire) {
    +		dn_cfg.expire_cycle = 0;
    +		dn_drain_scheduler();
    +		dn_drain_queue();
    +	}
    +
    +	DN_BH_WUNLOCK();
    +	dn_reschedule();
    +	if (q.head != NULL)
    +		dummynet_send(q.head);
    +}
    +
    +/*
    + * forward a chain of packets to the proper destination.
    + * This runs outside the dummynet lock.
    + */
    +static void
    +dummynet_send(struct mbuf *m)
    +{
    +	struct mbuf *n;
    +
    +	for (; m != NULL; m = n) {
    +		struct ifnet *ifp = NULL;	/* gcc 3.4.6 complains */
    +        	struct m_tag *tag;
    +		int dst;
    +
    +		n = m->m_nextpkt;
    +		m->m_nextpkt = NULL;
    +		tag = m_tag_first(m);
    +		if (tag == NULL) { /* should not happen */
    +			dst = DIR_DROP;
    +		} else {
    +			struct dn_pkt_tag *pkt = dn_tag_get(m);
    +			/* extract the dummynet info, rename the tag
    +			 * to carry reinject info.
    +			 */
    +			dst = pkt->dn_dir;
    +			ifp = pkt->ifp;
    +			tag->m_tag_cookie = MTAG_IPFW_RULE;
    +			tag->m_tag_id = 0;
    +		}
    +
    +		switch (dst) {
    +		case DIR_OUT:
    +			SET_HOST_IPLEN(mtod(m, struct ip *));
    +			ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
    +			break ;
    +
    +		case DIR_IN :
    +			/* put header in network format for ip_input() */
    +			//SET_NET_IPLEN(mtod(m, struct ip *));
    +			netisr_dispatch(NETISR_IP, m);
    +			break;
    +
    +#ifdef INET6
    +		case DIR_IN | PROTO_IPV6:
    +			netisr_dispatch(NETISR_IPV6, m);
    +			break;
    +
    +		case DIR_OUT | PROTO_IPV6:
    +			SET_HOST_IPLEN(mtod(m, struct ip *));
    +			ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
    +			break;
    +#endif
    +
    +		case DIR_FWD | PROTO_IFB: /* DN_TO_IFB_FWD: */
    +			if (bridge_dn_p != NULL)
    +				((*bridge_dn_p)(m, ifp));
    +			else
    +				printf("dummynet: if_bridge not loaded\n");
    +
    +			break;
    +
    +		case DIR_IN | PROTO_LAYER2: /* DN_TO_ETH_DEMUX: */
    +			/*
    +			 * The Ethernet code assumes the Ethernet header is
    +			 * contiguous in the first mbuf header.
    +			 * Insure this is true.
    +			 */
    +			if (m->m_len < ETHER_HDR_LEN &&
    +			    (m = m_pullup(m, ETHER_HDR_LEN)) == NULL) {
    +				printf("dummynet/ether: pullup failed, "
    +				    "dropping packet\n");
    +				break;
    +			}
    +			ether_demux(m->m_pkthdr.rcvif, m);
    +			break;
    +
    +		case DIR_OUT | PROTO_LAYER2: /* N_TO_ETH_OUT: */
    +			ether_output_frame(ifp, m);
    +			break;
    +
    +		case DIR_DROP:
    +			/* drop the packet after some time */
    +			FREE_PKT(m);
    +			break;
    +
    +		default:
    +			printf("dummynet: bad switch %d!\n", dst);
    +			FREE_PKT(m);
    +			break;
    +		}
    +	}
    +}
    +
    +static inline int
    +tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *fwa)
    +{
    +	struct dn_pkt_tag *dt;
    +	struct m_tag *mtag;
    +
    +	mtag = m_tag_get(PACKET_TAG_DUMMYNET,
    +		    sizeof(*dt), M_NOWAIT | M_ZERO);
    +	if (mtag == NULL)
    +		return 1;		/* Cannot allocate packet header. */
    +	m_tag_prepend(m, mtag);		/* Attach to mbuf chain. */
    +	dt = (struct dn_pkt_tag *)(mtag + 1);
    +	dt->rule = fwa->rule;
    +	dt->rule.info &= IPFW_ONEPASS;	/* only keep this info */
    +	dt->dn_dir = dir;
    +	dt->ifp = fwa->oif;
    +	/* dt->output tame is updated as we move through */
    +	dt->output_time = dn_cfg.curr_time;
    +	return 0;
    +}
    +
    +
    +/*
    + * dummynet hook for packets.
    + * We use the argument to locate the flowset fs and the sched_set sch
    + * associated to it. The we apply flow_mask and sched_mask to
    + * determine the queue and scheduler instances.
    + *
    + * dir		where shall we send the packet after dummynet.
    + * *m0		the mbuf with the packet
    + * ifp		the 'ifp' parameter from the caller.
    + *		NULL in ip_input, destination interface in ip_output,
    + */
    +int
    +dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa)
    +{
    +	struct mbuf *m = *m0;
    +	struct dn_fsk *fs = NULL;
    +	struct dn_sch_inst *si;
    +	struct dn_queue *q = NULL;	/* default */
    +
    +	int fs_id = (fwa->rule.info & IPFW_INFO_MASK) +
    +		((fwa->rule.info & IPFW_IS_PIPE) ? 2*DN_MAX_ID : 0);
    +	DN_BH_WLOCK();
    +	io_pkt++;
    +	/* we could actually tag outside the lock, but who cares... */
    +	if (tag_mbuf(m, dir, fwa))
    +		goto dropit;
    +	if (dn_cfg.busy) {
    +		/* if the upper half is busy doing something expensive,
    +		 * lets queue the packet and move forward
    +		 */
    +		mq_append(&dn_cfg.pending, m);
    +		m = *m0 = NULL; /* consumed */
    +		goto done; /* already active, nothing to do */
    +	}
    +	/* XXX locate_flowset could be optimised with a direct ref. */
    +	fs = dn_ht_find(dn_cfg.fshash, fs_id, 0, NULL);
    +	if (fs == NULL)
    +		goto dropit;	/* This queue/pipe does not exist! */
    +	if (fs->sched == NULL)	/* should not happen */
    +		goto dropit;
    +	/* find scheduler instance, possibly applying sched_mask */
    +	si = ipdn_si_find(fs->sched, &(fwa->f_id));
    +	if (si == NULL)
    +		goto dropit;
    +	/*
    +	 * If the scheduler supports multiple queues, find the right one
    +	 * (otherwise it will be ignored by enqueue).
    +	 */
    +	if (fs->sched->fp->flags & DN_MULTIQUEUE) {
    +		q = ipdn_q_find(fs, si, &(fwa->f_id));
    +		if (q == NULL)
    +			goto dropit;
    +	}
    +	if (fs->sched->fp->enqueue(si, q, m)) {
    +		printf("%s dropped by enqueue\n", __FUNCTION__);
    +		/* packet was dropped by enqueue() */
    +		m = *m0 = NULL;
    +		goto dropit;
    +	}
    +
    +	if (si->kflags & DN_ACTIVE) {
    +		m = *m0 = NULL; /* consumed */
    +		goto done; /* already active, nothing to do */
    +	}
    +
    +	/* compute the initial allowance */
    +	{
    +	    struct dn_link *p = &fs->sched->link;
    +	    si->credit = dn_cfg.io_fast ? p->bandwidth : 0;
    +	    if (p->burst) {
    +		uint64_t burst = (dn_cfg.curr_time - si->idle_time) * p->bandwidth;
    +		if (burst > p->burst)
    +			burst = p->burst;
    +		si->credit += burst;
    +	    }
    +	}
    +	/* pass through scheduler and delay line */
    +	m = serve_sched(NULL, si, dn_cfg.curr_time);
    +
    +	/* optimization -- pass it back to ipfw for immediate send */
    +	/* XXX Don't call dummynet_send() if scheduler return the packet
    +	 *     just enqueued. This avoid a lock order reversal.
    +	 *     
    +	 */
    +	if (/*dn_cfg.io_fast &&*/ m == *m0 && (dir & PROTO_LAYER2) == 0 ) {
    +		/* fast io */
    +		io_pkt_fast++;
    +		if (m->m_nextpkt != NULL) {
    +			printf("dummynet: fast io: pkt chain detected!\n");
    +			m->m_nextpkt = NULL;
    +		}
    +		m = NULL;
    +	} else {
    +		*m0 = NULL;
    +	}
    +done:
    +	DN_BH_WUNLOCK();
    +	if (m)
    +		dummynet_send(m);
    +	return 0;
    +
    +dropit:
    +	io_pkt_drop++;
    +	DN_BH_WUNLOCK();
    +	if (m)
    +		FREE_PKT(m);
    +	*m0 = NULL;
    +	return (fs && (fs->fs.flags & DN_NOERROR)) ? 0 : ENOBUFS;
    +}
    diff --git a/sys/netinet/ipfw/ip_dn_private.h b/sys/netinet/ipfw/ip_dn_private.h
    new file mode 100644
    index 00000000000..270f1881326
    --- /dev/null
    +++ b/sys/netinet/ipfw/ip_dn_private.h
    @@ -0,0 +1,402 @@
    +/*-
    + * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa
    + * 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.
    + */
    +
    +/*
    + * internal dummynet APIs.
    + *
    + * $FreeBSD$
    + */
    +
    +#ifndef _IP_DN_PRIVATE_H
    +#define _IP_DN_PRIVATE_H
    +
    +/* debugging support
    + * use ND() to remove debugging, D() to print a line,
    + * DX(level, ...) to print above a certain level
    + * If you redefine D() you are expected to redefine all.
    + */
    +#ifndef D
    +#define ND(fmt, ...) do {} while (0)
    +#define D1(fmt, ...) do {} while (0)
    +#define D(fmt, ...) printf("%-10s " fmt "\n",      \
    +        __FUNCTION__, ## __VA_ARGS__)
    +#define DX(lev, fmt, ...) do {              \
    +        if (dn_cfg.debug > lev) D(fmt, ## __VA_ARGS__); } while (0)
    +#endif
    +
    +MALLOC_DECLARE(M_DUMMYNET);
    +
    +#ifndef FREE_PKT
    +#define	FREE_PKT(m)	m_freem(m)
    +#endif
    +
    +#ifndef __linux__
    +#define div64(a, b)  ((int64_t)(a) / (int64_t)(b))
    +#endif
    +
    +#define DN_LOCK_INIT() do {				\
    +	mtx_init(&dn_cfg.uh_mtx, "dn_uh", NULL, MTX_DEF);	\
    +	mtx_init(&dn_cfg.bh_mtx, "dn_bh", NULL, MTX_DEF);	\
    +	} while (0)
    +#define DN_LOCK_DESTROY() do {				\
    +	mtx_destroy(&dn_cfg.uh_mtx);			\
    +	mtx_destroy(&dn_cfg.bh_mtx);			\
    +	} while (0)
    +#if 0 /* not used yet */
    +#define DN_UH_RLOCK()		mtx_lock(&dn_cfg.uh_mtx)
    +#define DN_UH_RUNLOCK()		mtx_unlock(&dn_cfg.uh_mtx)
    +#define DN_UH_WLOCK()		mtx_lock(&dn_cfg.uh_mtx)
    +#define DN_UH_WUNLOCK()		mtx_unlock(&dn_cfg.uh_mtx)
    +#define DN_UH_LOCK_ASSERT()	mtx_assert(&dn_cfg.uh_mtx, MA_OWNED)
    +#endif
    +
    +#define DN_BH_RLOCK()		mtx_lock(&dn_cfg.uh_mtx)
    +#define DN_BH_RUNLOCK()		mtx_unlock(&dn_cfg.uh_mtx)
    +#define DN_BH_WLOCK()		mtx_lock(&dn_cfg.uh_mtx)
    +#define DN_BH_WUNLOCK()		mtx_unlock(&dn_cfg.uh_mtx)
    +#define DN_BH_LOCK_ASSERT()	mtx_assert(&dn_cfg.uh_mtx, MA_OWNED)
    +
    +SLIST_HEAD(dn_schk_head, dn_schk);
    +SLIST_HEAD(dn_sch_inst_head, dn_sch_inst);
    +SLIST_HEAD(dn_fsk_head, dn_fsk);
    +SLIST_HEAD(dn_queue_head, dn_queue);
    +SLIST_HEAD(dn_alg_head, dn_alg);
    +
    +struct mq {	/* a basic queue of packets*/
    +        struct mbuf *head, *tail;
    +};
    +
    +static inline void
    +set_oid(struct dn_id *o, int type, int len)
    +{
    +        o->type = type;
    +        o->len = len;
    +        o->subtype = 0;
    +};
    +
    +/*
    + * configuration and global data for a dummynet instance
    + *
    + * When a configuration is modified from userland, 'id' is incremented
    + * so we can use the value to check for stale pointers.
    + */
    +struct dn_parms {
    +	uint32_t	id;		/* configuration version */
    +
    +	/* defaults (sysctl-accessible) */
    +	int	red_lookup_depth;
    +	int	red_avg_pkt_size;
    +	int	red_max_pkt_size;
    +	int	hash_size;
    +	int	max_hash_size;
    +	long	byte_limit;		/* max queue sizes */
    +	long	slot_limit;
    +
    +	int	io_fast;
    +	int	debug;
    +
    +	/* timekeeping */
    +	struct timeval prev_t;		/* last time dummynet_tick ran */
    +	struct dn_heap	evheap;		/* scheduled events */
    +
    +	/* counters of objects -- used for reporting space */
    +	int	schk_count;
    +	int	si_count;
    +	int	fsk_count;
    +	int	queue_count;
    +
    +	/* ticks and other stuff */
    +	uint64_t	curr_time;
    +	/* flowsets and schedulers are in hash tables, with 'hash_size'
    +	 * buckets. fshash is looked up at every packet arrival
    +	 * so better be generous if we expect many entries.
    +	 */
    +	struct dn_ht	*fshash;
    +	struct dn_ht	*schedhash;
    +	/* list of flowsets without a scheduler -- use sch_chain */
    +	struct dn_fsk_head	fsu;	/* list of unlinked flowsets */
    +	struct dn_alg_head	schedlist;	/* list of algorithms */
    +
    +	/* Store the fs/sch to scan when draining. The value is the
    +	 * bucket number of the hash table. Expire can be disabled
    +	 * with net.inet.ip.dummynet.expire=0, or it happens every
    +	 * expire ticks.
    +	 **/
    +	int drain_fs;
    +	int drain_sch;
    +	uint32_t expire;
    +	uint32_t expire_cycle;	/* tick count */
    +	
    +	/* if the upper half is busy doing something long,
    +	 * can set the busy flag and we will enqueue packets in
    +	 * a queue for later processing.
    +	 */
    +	int	busy;
    +	struct	mq	pending;
    +
    +#ifdef _KERNEL
    +	/*
    +	 * This file is normally used in the kernel, unless we do
    +	 * some userland tests, in which case we do not need a mtx.
    +	 * uh_mtx arbitrates between system calls and also
    +	 * protects fshash, schedhash and fsunlinked.
    +	 * These structures are readonly for the lower half.
    +	 * bh_mtx protects all other structures which may be
    +	 * modified upon packet arrivals
    +	 */
    +#if defined( __linux__ ) || defined( _WIN32 )
    +	spinlock_t uh_mtx;
    +	spinlock_t bh_mtx;
    +#else
    +	struct mtx uh_mtx;
    +	struct mtx bh_mtx;
    +#endif
    +
    +#endif /* _KERNEL */
    +};
    +
    +/*
    + * Delay line, contains all packets on output from a link.
    + * Every scheduler instance has one.
    + */
    +struct delay_line {
    +	struct dn_id oid;
    +	struct dn_sch_inst *si;
    +	struct mq mq;
    +};
    +
    +/*
    + * The kernel side of a flowset. It is linked in a hash table
    + * of flowsets, and in a list of children of their parent scheduler.
    + * qht is either the queue or (if HAVE_MASK) a hash table queues.
    + * Note that the mask to use is the (flow_mask|sched_mask), which
    + * changes as we attach/detach schedulers. So we store it here.
    + *
    + * XXX If we want to add scheduler-specific parameters, we need to
    + * put them in external storage because the scheduler may not be
    + * available when the fsk is created.
    + */
    +struct dn_fsk { /* kernel side of a flowset */
    +	struct dn_fs fs;
    +	SLIST_ENTRY(dn_fsk) fsk_next;	/* hash chain for fshash */
    +
    +	struct ipfw_flow_id fsk_mask;
    +
    +	/* qht is a hash table of queues, or just a single queue
    +	 * a bit in fs.flags tells us which one
    +	 */
    +	struct dn_ht	*qht;
    +	struct dn_schk *sched;		/* Sched we are linked to */
    +	SLIST_ENTRY(dn_fsk) sch_chain;	/* list of fsk attached to sched */
    +
    +	/* bucket index used by drain routine to drain queues for this
    +	 * flowset
    +	 */
    +	int drain_bucket;
    +	/* Parameter realted to RED / GRED */
    +	/* original values are in dn_fs*/
    +	int w_q ;		/* queue weight (scaled) */
    +	int max_th ;		/* maximum threshold for queue (scaled) */
    +	int min_th ;		/* minimum threshold for queue (scaled) */
    +	int max_p ;		/* maximum value for p_b (scaled) */
    +
    +	u_int c_1 ;		/* max_p/(max_th-min_th) (scaled) */
    +	u_int c_2 ;		/* max_p*min_th/(max_th-min_th) (scaled) */
    +	u_int c_3 ;		/* for GRED, (1-max_p)/max_th (scaled) */
    +	u_int c_4 ;		/* for GRED, 1 - 2*max_p (scaled) */
    +	u_int * w_q_lookup ;	/* lookup table for computing (1-w_q)^t */
    +	u_int lookup_depth ;	/* depth of lookup table */
    +	int lookup_step ;	/* granularity inside the lookup table */
    +	int lookup_weight ;	/* equal to (1-w_q)^t / (1-w_q)^(t+1) */
    +	int avg_pkt_size ;	/* medium packet size */
    +	int max_pkt_size ;	/* max packet size */
    +};
    +
    +/*
    + * A queue is created as a child of a flowset unless it belongs to
    + * a !MULTIQUEUE scheduler. It is normally in a hash table in the
    + * flowset. fs always points to the parent flowset.
    + * si normally points to the sch_inst, unless the flowset has been
    + * detached from the scheduler -- in this case si == NULL and we
    + * should not enqueue.
    + */
    +struct dn_queue {
    +	struct dn_flow ni;	/* oid, flow_id, stats */
    +	struct mq mq;	/* packets queue */
    +	struct dn_sch_inst *_si;	/* owner scheduler instance */
    +	SLIST_ENTRY(dn_queue) q_next; /* hash chain list for qht */
    +	struct dn_fsk *fs;		/* parent flowset. */
    +
    +	/* RED parameters */
    +	int avg;		/* average queue length est. (scaled) */
    +	int count;		/* arrivals since last RED drop */
    +	int random;		/* random value (scaled) */
    +	uint64_t q_time;	/* start of queue idle time */
    +
    +};
    +
    +/*
    + * The kernel side of a scheduler. Contains the userland config,
    + * a link, pointer to extra config arguments from command line,
    + * kernel flags, and a pointer to the scheduler methods.
    + * It is stored in a hash table, and holds a list of all
    + * flowsets and scheduler instances.
    + * XXX sch must be at the beginning, see schk_hash().
    + */
    +struct dn_schk {
    +	struct dn_sch sch;
    +	struct dn_alg *fp;	/* Pointer to scheduler functions */
    +	struct dn_link link;	/* The link, embedded */
    +	struct dn_profile *profile; /* delay profile, if any */
    +	struct dn_id *cfg;	/* extra config arguments */
    +
    +	SLIST_ENTRY(dn_schk) schk_next;  /* hash chain for schedhash */
    +
    +	struct dn_fsk_head fsk_list;  /* all fsk linked to me */
    +	struct dn_fsk *fs;	/* Flowset for !MULTIQUEUE */
    +
    +	/* bucket index used by the drain routine to drain the scheduler
    +	 * instance for this flowset.
    +	 */
    +	int drain_bucket;
    +
    +	/* Hash table of all instances (through sch.sched_mask)
    +	 * or single instance if no mask. Always valid.
    +	 */
    +	struct dn_ht	*siht;
    +};
    +
    +
    +/*
    + * Scheduler instance.
    + * Contains variables and all queues relative to a this instance.
    + * This struct is created a runtime.
    + */
    +struct dn_sch_inst {
    +	struct dn_flow	ni;	/* oid, flowid and stats */
    +	SLIST_ENTRY(dn_sch_inst) si_next; /* hash chain for siht */
    +	struct delay_line dline;
    +	struct dn_schk *sched;	/* the template */
    +	int		kflags;	/* DN_ACTIVE */
    +
    +	int64_t	credit;		/* bits I can transmit (more or less). */
    +	uint64_t sched_time;	/* time link was scheduled in ready_heap */
    +	uint64_t idle_time;	/* start of scheduler instance idle time */
    +
    +	/* q_count is the number of queues that this instance is using.
    +	 * The counter is incremented or decremented when
    +	 * a reference from the queue is created or deleted.
    +	 * It is used to make sure that a scheduler instance can be safely
    +	 * deleted by the drain routine. See notes below.
    +	 */
    +	int q_count;
    +
    +};
    +
    +/*
    + * NOTE about object drain.
    + * The system will automatically (XXX check when) drain queues and
    + * scheduler instances when they are idle.
    + * A queue is idle when it has no packets; an instance is idle when
    + * it is not in the evheap heap, and the corresponding delay line is empty.
    + * A queue can be safely deleted when it is idle because of the scheduler
    + * function xxx_free_queue() will remove any references to it.
    + * An instance can be only deleted when no queues reference it. To be sure
    + * of that, a counter (q_count) stores the number of queues that are pointing
    + * to the instance.
    + *
    + * XXX
    + * Order of scan:
    + * - take all flowset in a bucket for the flowset hash table
    + * - take all queues in a bucket for the flowset
    + * - increment the queue bucket
    + * - scan next flowset bucket
    + * Nothing is done if a bucket contains no entries.
    + *
    + * The same schema is used for sceduler instances
    + */
    +
    +
    +/* kernel-side flags. Linux has DN_DELETE in fcntl.h
    + */
    +enum {
    +	/* 1 and 2 are reserved for the SCAN flags */
    +	DN_DESTROY	= 0x0004, /* destroy */
    +	DN_DELETE_FS	= 0x0008, /* destroy flowset */
    +	DN_DETACH	= 0x0010,
    +	DN_ACTIVE	= 0x0020, /* object is in evheap */
    +	DN_F_DLINE	= 0x0040, /* object is a delay line */
    +	DN_F_SCHI	= 0x00C0, /* object is a sched.instance */
    +	DN_QHT_IS_Q	= 0x0100, /* in flowset, qht is a single queue */
    +};
    +
    +extern struct dn_parms dn_cfg;
    +
    +int dummynet_io(struct mbuf **, int , struct ip_fw_args *);
    +void dummynet_task(void *context, int pending);
    +void dn_reschedule(void);
    +
    +struct dn_queue *ipdn_q_find(struct dn_fsk *, struct dn_sch_inst *,
    +        struct ipfw_flow_id *);
    +struct dn_sch_inst *ipdn_si_find(struct dn_schk *, struct ipfw_flow_id *);
    +
    +/*
    + * copy_range is a template for requests for ranges of pipes/queues/scheds.
    + * The number of ranges is variable and can be derived by o.len.
    + * As a default, we use a small number of entries so that the struct
    + * fits easily on the stack and is sufficient for most common requests.
    + */
    +#define DEFAULT_RANGES	5
    +struct copy_range {
    +        struct dn_id o;
    +        uint32_t	r[ 2 * DEFAULT_RANGES ];
    +};
    +
    +struct copy_args {
    +	char **start;
    +	char *end;
    +	int flags;
    +	int type;
    +	struct copy_range *extra;	/* extra filtering */
    +};
    +
    +struct sockopt;
    +int ip_dummynet_compat(struct sockopt *sopt);
    +int dummynet_get(struct sockopt *sopt, void **compat);
    +int dn_c_copy_q (void *_ni, void *arg);
    +int dn_c_copy_pipe(struct dn_schk *s, struct copy_args *a, int nq);
    +int dn_c_copy_fs(struct dn_fsk *f, struct copy_args *a, int nq);
    +int dn_compat_copy_queue(struct copy_args *a, void *_o);
    +int dn_compat_copy_pipe(struct copy_args *a, void *_o);
    +int copy_data_helper_compat(void *_o, void *_arg);
    +int dn_compat_calc_size(struct dn_parms dn_cfg);
    +int do_config(void *p, int l);
    +
    +/* function to drain idle object */
    +void dn_drain_scheduler(void);
    +void dn_drain_queue(void);
    +
    +#endif /* _IP_DN_PRIVATE_H */
    diff --git a/sys/netinet/ipfw/ip_dummynet.c b/sys/netinet/ipfw/ip_dummynet.c
    index e961a55e817..d7073eb797e 100644
    --- a/sys/netinet/ipfw/ip_dummynet.c
    +++ b/sys/netinet/ipfw/ip_dummynet.c
    @@ -1,5 +1,5 @@
     /*-
    - * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa
    + * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
      * Portions Copyright (c) 2000 Akamba Corp.
      * All rights reserved
      *
    @@ -28,34 +28,12 @@
     #include 
     __FBSDID("$FreeBSD$");
     
    -#define	DUMMYNET_DEBUG
    +/*
    + * Configuration and internal object management for dummynet.
    + */
     
     #include "opt_inet6.h"
     
    -/*
    - * This module implements IP dummynet, a bandwidth limiter/delay emulator
    - * used in conjunction with the ipfw package.
    - * Description of the data structures used is in ip_dummynet.h
    - * Here you mainly find the following blocks of code:
    - *  + variable declarations;
    - *  + heap management functions;
    - *  + scheduler and dummynet functions;
    - *  + configuration and initialization.
    - *
    - * NOTA BENE: critical sections are protected by the "dummynet lock".
    - *
    - * Most important Changes:
    - *
    - * 011004: KLDable
    - * 010124: Fixed WF2Q behaviour
    - * 010122: Fixed spl protection.
    - * 000601: WF2Q support
    - * 000106: large rewrite, use heaps to handle very many pipes.
    - * 980513:	initial release
    - *
    - * include files marked with XXX are probably not needed
    - */
    -
     #include 
     #include 
     #include 
    @@ -69,761 +47,35 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    -#include 
     #include 
     #include 	/* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
    -#include 
     #include 
    -#include 		/* ip_len, ip_off */
    -#include 
    -#include 
     #include 	/* ip_output(), IP_FORWARDING */
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
     
    -#include  /* various ether_* routines */
    +/* which objects to copy */
    +#define DN_C_LINK 	0x01
    +#define DN_C_SCH	0x02
    +#define DN_C_FLOW	0x04
    +#define DN_C_FS		0x08
    +#define DN_C_QUEUE	0x10
     
    -#include        /* for ip6_input, ip6_output prototypes */
    -#include 
    -
    -/*
    - * We keep a private variable for the simulation time, but we could
    - * probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
    - */
    -static dn_key curr_time = 0 ; /* current simulation time */
    -
    -static int dn_hash_size = 64 ;	/* default hash size */
    -
    -/* statistics on number of queue searches and search steps */
    -static long searches, search_steps ;
    -static int pipe_expire = 1 ;   /* expire queue if empty */
    -static int dn_max_ratio = 16 ; /* max queues/buckets ratio */
    -
    -static long pipe_slot_limit = 100; /* Foot shooting limit for pipe queues. */
    -static long pipe_byte_limit = 1024 * 1024;
    -
    -static int red_lookup_depth = 256;	/* RED - default lookup table depth */
    -static int red_avg_pkt_size = 512;      /* RED - default medium packet size */
    -static int red_max_pkt_size = 1500;     /* RED - default max packet size */
    -
    -static struct timeval prev_t, t;
    -static long tick_last;			/* Last tick duration (usec). */
    -static long tick_delta;			/* Last vs standard tick diff (usec). */
    -static long tick_delta_sum;		/* Accumulated tick difference (usec).*/
    -static long tick_adjustment;		/* Tick adjustments done. */
    -static long tick_lost;			/* Lost(coalesced) ticks number. */
    -/* Adjusted vs non-adjusted curr_time difference (ticks). */
    -static long tick_diff;
    -
    -static int		io_fast;
    -static unsigned long	io_pkt;
    -static unsigned long	io_pkt_fast;
    -static unsigned long	io_pkt_drop;
    -
    -/*
    - * Three heaps contain queues and pipes that the scheduler handles:
    - *
    - * ready_heap contains all dn_flow_queue related to fixed-rate pipes.
    - *
    - * wfq_ready_heap contains the pipes associated with WF2Q flows
    - *
    - * extract_heap contains pipes associated with delay lines.
    - *
    - */
    -
    -MALLOC_DEFINE(M_DUMMYNET, "dummynet", "dummynet heap");
    -
    -static struct dn_heap ready_heap, extract_heap, wfq_ready_heap ;
    -
    -static int	heap_init(struct dn_heap *h, int size);
    -static int	heap_insert (struct dn_heap *h, dn_key key1, void *p);
    -static void	heap_extract(struct dn_heap *h, void *obj);
    -static void	transmit_event(struct dn_pipe *pipe, struct mbuf **head,
    -		    struct mbuf **tail);
    -static void	ready_event(struct dn_flow_queue *q, struct mbuf **head,
    -		    struct mbuf **tail);
    -static void	ready_event_wfq(struct dn_pipe *p, struct mbuf **head,
    -		    struct mbuf **tail);
    -
    -#define	HASHSIZE	16
    -#define	HASH(num)	((((num) >> 8) ^ ((num) >> 4) ^ (num)) & 0x0f)
    -static struct dn_pipe_head	pipehash[HASHSIZE];	/* all pipes */
    -static struct dn_flow_set_head	flowsethash[HASHSIZE];	/* all flowsets */
    +/* we use this argument in case of a schk_new */
    +struct schk_new_arg {
    +	struct dn_alg *fp;
    +	struct dn_sch *sch;
    +};
     
    +/*---- callout hooks. ----*/
     static struct callout dn_timeout;
    -
    -extern	void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
    -
    -#ifdef SYSCTL_NODE
    -SYSCTL_DECL(_net_inet);
    -SYSCTL_DECL(_net_inet_ip);
    -
    -SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet");
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, hash_size,
    -    CTLFLAG_RW, &dn_hash_size, 0, "Default hash table size");
    -#if 0	/* curr_time is 64 bit */
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, curr_time,
    -    CTLFLAG_RD, &curr_time, 0, "Current tick");
    -#endif
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, ready_heap,
    -    CTLFLAG_RD, &ready_heap.size, 0, "Size of ready heap");
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, extract_heap,
    -    CTLFLAG_RD, &extract_heap.size, 0, "Size of extract heap");
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, searches,
    -    CTLFLAG_RD, &searches, 0, "Number of queue searches");
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, search_steps,
    -    CTLFLAG_RD, &search_steps, 0, "Number of queue search steps");
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, expire,
    -    CTLFLAG_RW, &pipe_expire, 0, "Expire queue if empty");
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, max_chain_len,
    -    CTLFLAG_RW, &dn_max_ratio, 0,
    -    "Max ratio between dynamic queues and buckets");
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_lookup_depth,
    -    CTLFLAG_RD, &red_lookup_depth, 0, "Depth of RED lookup table");
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_avg_pkt_size,
    -    CTLFLAG_RD, &red_avg_pkt_size, 0, "RED Medium packet size");
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_max_pkt_size,
    -    CTLFLAG_RD, &red_max_pkt_size, 0, "RED Max packet size");
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta,
    -    CTLFLAG_RD, &tick_delta, 0, "Last vs standard tick difference (usec).");
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta_sum,
    -    CTLFLAG_RD, &tick_delta_sum, 0, "Accumulated tick difference (usec).");
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_adjustment,
    -    CTLFLAG_RD, &tick_adjustment, 0, "Tick adjustments done.");
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_diff,
    -    CTLFLAG_RD, &tick_diff, 0,
    -    "Adjusted vs non-adjusted curr_time difference (ticks).");
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_lost,
    -    CTLFLAG_RD, &tick_lost, 0,
    -    "Number of ticks coalesced by dummynet taskqueue.");
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, io_fast,
    -    CTLFLAG_RW, &io_fast, 0, "Enable fast dummynet io.");
    -SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt,
    -    CTLFLAG_RD, &io_pkt, 0,
    -    "Number of packets passed to dummynet.");
    -SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_fast,
    -    CTLFLAG_RD, &io_pkt_fast, 0,
    -    "Number of packets bypassed dummynet scheduler.");
    -SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_drop,
    -    CTLFLAG_RD, &io_pkt_drop, 0,
    -    "Number of packets dropped by dummynet.");
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_slot_limit,
    -    CTLFLAG_RW, &pipe_slot_limit, 0, "Upper limit in slots for pipe queue.");
    -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_byte_limit,
    -    CTLFLAG_RW, &pipe_byte_limit, 0, "Upper limit in bytes for pipe queue.");
    -#endif
    -
    -#ifdef DUMMYNET_DEBUG
    -int	dummynet_debug = 0;
    -#ifdef SYSCTL_NODE
    -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, debug, CTLFLAG_RW, &dummynet_debug,
    -	    0, "control debugging printfs");
    -#endif
    -#define	DPRINTF(X)	if (dummynet_debug) printf X
    -#else
    -#define	DPRINTF(X)
    -#endif
    -
     static struct task	dn_task;
     static struct taskqueue	*dn_tq = NULL;
    -static void dummynet_task(void *, int);
     
    -static struct mtx dummynet_mtx;
    -#define	DUMMYNET_LOCK_INIT() \
    -	mtx_init(&dummynet_mtx, "dummynet", NULL, MTX_DEF)
    -#define	DUMMYNET_LOCK_DESTROY()	mtx_destroy(&dummynet_mtx)
    -#define	DUMMYNET_LOCK()		mtx_lock(&dummynet_mtx)
    -#define	DUMMYNET_UNLOCK()	mtx_unlock(&dummynet_mtx)
    -#define	DUMMYNET_LOCK_ASSERT()	mtx_assert(&dummynet_mtx, MA_OWNED)
    -
    -static int	config_pipe(struct dn_pipe *p);
    -static int	ip_dn_ctl(struct sockopt *sopt);
    -
    -static void	dummynet(void *);
    -static void	dummynet_flush(void);
    -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.
    - *
    - * In the heap, first node is element 0. Children of i are 2i+1 and 2i+2.
    - * Some macros help finding parent/children so we can optimize them.
    - *
    - * heap_init() is called to expand the heap when needed.
    - * Increment size in blocks of 16 entries.
    - * XXX failure to allocate a new element is a pretty bad failure
    - * as we basically stall a whole queue forever!!
    - * Returns 1 on error, 0 on success
    - */
    -#define HEAP_FATHER(x) ( ( (x) - 1 ) / 2 )
    -#define HEAP_LEFT(x) ( 2*(x) + 1 )
    -#define HEAP_IS_LEFT(x) ( (x) & 1 )
    -#define HEAP_RIGHT(x) ( 2*(x) + 2 )
    -#define	HEAP_SWAP(a, b, buffer) { buffer = a ; a = b ; b = buffer ; }
    -#define HEAP_INCREMENT	15
    -
    -static int
    -heap_init(struct dn_heap *h, int new_size)
    -{
    -    struct dn_heap_entry *p;
    -
    -    if (h->size >= new_size ) {
    -	printf("dummynet: %s, Bogus call, have %d want %d\n", __func__,
    -		h->size, new_size);
    -	return 0 ;
    -    }
    -    new_size = (new_size + HEAP_INCREMENT ) & ~HEAP_INCREMENT ;
    -    p = malloc(new_size * sizeof(*p), M_DUMMYNET, M_NOWAIT);
    -    if (p == NULL) {
    -	printf("dummynet: %s, resize %d failed\n", __func__, new_size );
    -	return 1 ; /* error */
    -    }
    -    if (h->size > 0) {
    -	bcopy(h->p, p, h->size * sizeof(*p) );
    -	free(h->p, M_DUMMYNET);
    -    }
    -    h->p = p ;
    -    h->size = new_size ;
    -    return 0 ;
    -}
    -
    -/*
    - * Insert element in heap. Normally, p != NULL, we insert p in
    - * a new position and bubble up. If p == NULL, then the element is
    - * already in place, and key is the position where to start the
    - * bubble-up.
    - * Returns 1 on failure (cannot allocate new heap entry)
    - *
    - * If offset > 0 the position (index, int) of the element in the heap is
    - * also stored in the element itself at the given offset in bytes.
    - */
    -#define SET_OFFSET(heap, node) \
    -    if (heap->offset > 0) \
    -	    *((int *)((char *)(heap->p[node].object) + heap->offset)) = node ;
    -/*
    - * RESET_OFFSET is used for sanity checks. It sets offset to an invalid value.
    - */
    -#define RESET_OFFSET(heap, node) \
    -    if (heap->offset > 0) \
    -	    *((int *)((char *)(heap->p[node].object) + heap->offset)) = -1 ;
    -static int
    -heap_insert(struct dn_heap *h, dn_key key1, void *p)
    -{
    -    int son = h->elements ;
    -
    -    if (p == NULL)	/* data already there, set starting point */
    -	son = key1 ;
    -    else {		/* insert new element at the end, possibly resize */
    -	son = h->elements ;
    -	if (son == h->size) /* need resize... */
    -	    if (heap_init(h, h->elements+1) )
    -		return 1 ; /* failure... */
    -	h->p[son].object = p ;
    -	h->p[son].key = key1 ;
    -	h->elements++ ;
    -    }
    -    while (son > 0) {				/* bubble up */
    -	int father = HEAP_FATHER(son) ;
    -	struct dn_heap_entry tmp  ;
    -
    -	if (DN_KEY_LT( h->p[father].key, h->p[son].key ) )
    -	    break ; /* found right position */
    -	/* son smaller than father, swap and repeat */
    -	HEAP_SWAP(h->p[son], h->p[father], tmp) ;
    -	SET_OFFSET(h, son);
    -	son = father ;
    -    }
    -    SET_OFFSET(h, son);
    -    return 0 ;
    -}
    -
    -/*
    - * remove top element from heap, or obj if obj != NULL
    - */
    -static void
    -heap_extract(struct dn_heap *h, void *obj)
    -{
    -    int child, father, max = h->elements - 1 ;
    -
    -    if (max < 0) {
    -	printf("dummynet: warning, extract from empty heap 0x%p\n", h);
    -	return ;
    -    }
    -    father = 0 ; /* default: move up smallest child */
    -    if (obj != NULL) { /* extract specific element, index is at offset */
    -	if (h->offset <= 0)
    -	    panic("dummynet: heap_extract from middle not supported on this heap!!!\n");
    -	father = *((int *)((char *)obj + h->offset)) ;
    -	if (father < 0 || father >= h->elements) {
    -	    printf("dummynet: heap_extract, father %d out of bound 0..%d\n",
    -		father, h->elements);
    -	    panic("dummynet: heap_extract");
    -	}
    -    }
    -    RESET_OFFSET(h, father);
    -    child = HEAP_LEFT(father) ;		/* left child */
    -    while (child <= max) {		/* valid entry */
    -	if (child != max && DN_KEY_LT(h->p[child+1].key, h->p[child].key) )
    -	    child = child+1 ;		/* take right child, otherwise left */
    -	h->p[father] = h->p[child] ;
    -	SET_OFFSET(h, father);
    -	father = child ;
    -	child = HEAP_LEFT(child) ;   /* left child for next loop */
    -    }
    -    h->elements-- ;
    -    if (father != max) {
    -	/*
    -	 * Fill hole with last entry and bubble up, reusing the insert code
    -	 */
    -	h->p[father] = h->p[max] ;
    -	heap_insert(h, father, NULL); /* this one cannot fail */
    -    }
    -}
    -
    -#if 0
    -/*
    - * change object position and update references
    - * XXX this one is never used!
    - */
    -static void
    -heap_move(struct dn_heap *h, dn_key new_key, void *object)
    -{
    -    int temp;
    -    int i ;
    -    int max = h->elements-1 ;
    -    struct dn_heap_entry buf ;
    -
    -    if (h->offset <= 0)
    -	panic("cannot move items on this heap");
    -
    -    i = *((int *)((char *)object + h->offset));
    -    if (DN_KEY_LT(new_key, h->p[i].key) ) { /* must move up */
    -	h->p[i].key = new_key ;
    -	for (; i>0 && DN_KEY_LT(new_key, h->p[(temp = HEAP_FATHER(i))].key) ;
    -		 i = temp ) { /* bubble up */
    -	    HEAP_SWAP(h->p[i], h->p[temp], buf) ;
    -	    SET_OFFSET(h, i);
    -	}
    -    } else {		/* must move down */
    -	h->p[i].key = new_key ;
    -	while ( (temp = HEAP_LEFT(i)) <= max ) { /* found left child */
    -	    if ((temp != max) && DN_KEY_GT(h->p[temp].key, h->p[temp+1].key))
    -		temp++ ; /* select child with min key */
    -	    if (DN_KEY_GT(new_key, h->p[temp].key)) { /* go down */
    -		HEAP_SWAP(h->p[i], h->p[temp], buf) ;
    -		SET_OFFSET(h, i);
    -	    } else
    -		break ;
    -	    i = temp ;
    -	}
    -    }
    -    SET_OFFSET(h, i);
    -}
    -#endif /* heap_move, unused */
    -
    -/*
    - * heapify() will reorganize data inside an array to maintain the
    - * heap property. It is needed when we delete a bunch of entries.
    - */
    -static void
    -heapify(struct dn_heap *h)
    -{
    -    int i ;
    -
    -    for (i = 0 ; i < h->elements ; i++ )
    -	heap_insert(h, i , NULL) ;
    -}
    -
    -/*
    - * cleanup the heap and free data structure
    - */
    -static void
    -heap_free(struct dn_heap *h)
    -{
    -    if (h->size >0 )
    -	free(h->p, M_DUMMYNET);
    -    bzero(h, sizeof(*h) );
    -}
    -
    -/*
    - * --- end of heap management functions ---
    - */
    -
    -/*
    - * Return the mbuf tag holding the dummynet state.  As an optimization
    - * this is assumed to be the first tag on the list.  If this turns out
    - * wrong we'll need to search the list.
    - */
    -static struct dn_pkt_tag *
    -dn_tag_get(struct mbuf *m)
    -{
    -    struct m_tag *mtag = m_tag_first(m);
    -    KASSERT(mtag != NULL &&
    -	    mtag->m_tag_cookie == MTAG_ABI_COMPAT &&
    -	    mtag->m_tag_id == PACKET_TAG_DUMMYNET,
    -	    ("packet on dummynet queue w/o dummynet tag!"));
    -    return (struct dn_pkt_tag *)(mtag+1);
    -}
    -
    -/*
    - * Scheduler functions:
    - *
    - * transmit_event() is called when the delay-line needs to enter
    - * the scheduler, either because of existing pkts getting ready,
    - * or new packets entering the queue. The event handled is the delivery
    - * time of the packet.
    - *
    - * ready_event() does something similar with fixed-rate queues, and the
    - * event handled is the finish time of the head pkt.
    - *
    - * wfq_ready_event() does something similar with WF2Q queues, and the
    - * event handled is the start time of the head pkt.
    - *
    - * In all cases, we make sure that the data structures are consistent
    - * before passing pkts out, because this might trigger recursive
    - * invocations of the procedures.
    - */
    -static void
    -transmit_event(struct dn_pipe *pipe, struct mbuf **head, struct mbuf **tail)
    -{
    -	struct mbuf *m;
    -	struct dn_pkt_tag *pkt;
    -
    -	DUMMYNET_LOCK_ASSERT();
    -
    -	while ((m = pipe->head) != NULL) {
    -		pkt = dn_tag_get(m);
    -		if (!DN_KEY_LEQ(pkt->output_time, curr_time))
    -			break;
    -
    -		pipe->head = m->m_nextpkt;
    -		if (*tail != NULL)
    -			(*tail)->m_nextpkt = m;
    -		else
    -			*head = m;
    -		*tail = m;
    -	}
    -	if (*tail != NULL)
    -		(*tail)->m_nextpkt = NULL;
    -
    -	/* If there are leftover packets, put into the heap for next event. */
    -	if ((m = pipe->head) != NULL) {
    -		pkt = dn_tag_get(m);
    -		/*
    -		 * XXX Should check errors on heap_insert, by draining the
    -		 * whole pipe p and hoping in the future we are more successful.
    -		 */
    -		heap_insert(&extract_heap, pkt->output_time, pipe);
    -	}
    -}
    -
    -#define div64(a, b)	((int64_t)(a) / (int64_t)(b))
    -#define DN_TO_DROP	0xffff
    -/*
    - * Compute how many ticks we have to wait before being able to send
    - * a packet. This is computed as the "wire time" for the packet
    - * (length + extra bits), minus the credit available, scaled to ticks.
    - * Check that the result is not be negative (it could be if we have
    - * too much leftover credit in q->numbytes).
    - */
    -static inline dn_key
    -set_ticks(struct mbuf *m, struct dn_flow_queue *q, struct dn_pipe *p)
    -{
    -	int64_t ret;
    -
    -	ret = div64( (m->m_pkthdr.len * 8 + q->extra_bits) * hz
    -		- q->numbytes + p->bandwidth - 1 , p->bandwidth);
    -#if 0
    -	printf("%s %d extra_bits %d numb %d ret %d\n",
    -		__FUNCTION__, __LINE__,
    -		(int)(q->extra_bits & 0xffffffff),
    -		(int)(q->numbytes & 0xffffffff),
    -		(int)(ret & 0xffffffff));
    -#endif
    -	if (ret < 0)
    -		ret = 0;
    -	return ret;
    -}
    -
    -/*
    - * Convert the additional MAC overheads/delays into an equivalent
    - * number of bits for the given data rate. The samples are in milliseconds
    - * so we need to divide by 1000.
    - */
    -static dn_key
    -compute_extra_bits(struct mbuf *pkt, struct dn_pipe *p)
    -{
    -	int index;
    -	dn_key extra_bits;
    -
    -	if (!p->samples || p->samples_no == 0)
    -		return 0;
    -	index  = random() % p->samples_no;
    -	extra_bits = ((dn_key)p->samples[index] * p->bandwidth) / 1000;
    -	if (index >= p->loss_level) {
    -		struct dn_pkt_tag *dt = dn_tag_get(pkt);
    -		if (dt)
    -			dt->dn_dir = DN_TO_DROP;
    -	}
    -	return extra_bits;
    -}
    -
    -static void
    -free_pipe(struct dn_pipe *p)
    -{
    -	if (p->samples)
    -		free(p->samples, M_DUMMYNET);
    -	free(p, M_DUMMYNET);
    -}
    -
    -/*
    - * extract pkt from queue, compute output time (could be now)
    - * and put into delay line (p_queue)
    - */
    -static void
    -move_pkt(struct mbuf *pkt, struct dn_flow_queue *q, struct dn_pipe *p,
    -    int len)
    -{
    -    struct dn_pkt_tag *dt = dn_tag_get(pkt);
    -
    -    q->head = pkt->m_nextpkt ;
    -    q->len-- ;
    -    q->len_bytes -= len ;
    -
    -    dt->output_time = curr_time + p->delay ;
    -
    -    if (p->head == NULL)
    -	p->head = pkt;
    -    else
    -	p->tail->m_nextpkt = pkt;
    -    p->tail = pkt;
    -    p->tail->m_nextpkt = NULL;
    -}
    -
    -/*
    - * ready_event() is invoked every time the queue must enter the
    - * scheduler, either because the first packet arrives, or because
    - * a previously scheduled event fired.
    - * On invokation, drain as many pkts as possible (could be 0) and then
    - * if there are leftover packets reinsert the pkt in the scheduler.
    - */
    -static void
    -ready_event(struct dn_flow_queue *q, struct mbuf **head, struct mbuf **tail)
    -{
    -	struct mbuf *pkt;
    -	struct dn_pipe *p = q->fs->pipe;
    -	int p_was_empty;
    -
    -	DUMMYNET_LOCK_ASSERT();
    -
    -	if (p == NULL) {
    -		printf("dummynet: ready_event- pipe is gone\n");
    -		return;
    -	}
    -	p_was_empty = (p->head == NULL);
    -
    -	/*
    -	 * Schedule fixed-rate queues linked to this pipe:
    -	 * account for the bw accumulated since last scheduling, then
    -	 * drain as many pkts as allowed by q->numbytes and move to
    -	 * the delay line (in p) computing output time.
    -	 * bandwidth==0 (no limit) means we can drain the whole queue,
    -	 * setting len_scaled = 0 does the job.
    -	 */
    -	q->numbytes += (curr_time - q->sched_time) * p->bandwidth;
    -	while ((pkt = q->head) != NULL) {
    -		int len = pkt->m_pkthdr.len;
    -		dn_key len_scaled = p->bandwidth ? len*8*hz
    -			+ q->extra_bits*hz
    -			: 0;
    -
    -		if (DN_KEY_GT(len_scaled, q->numbytes))
    -			break;
    -		q->numbytes -= len_scaled;
    -		move_pkt(pkt, q, p, len);
    -		if (q->head)
    -			q->extra_bits = compute_extra_bits(q->head, p);
    -	}
    -	/*
    -	 * If we have more packets queued, schedule next ready event
    -	 * (can only occur when bandwidth != 0, otherwise we would have
    -	 * flushed the whole queue in the previous loop).
    -	 * To this purpose we record the current time and compute how many
    -	 * ticks to go for the finish time of the packet.
    -	 */
    -	if ((pkt = q->head) != NULL) {	/* this implies bandwidth != 0 */
    -		dn_key t = set_ticks(pkt, q, p); /* ticks i have to wait */
    -
    -		q->sched_time = curr_time;
    -		heap_insert(&ready_heap, curr_time + t, (void *)q);
    -		/*
    -		 * XXX Should check errors on heap_insert, and drain the whole
    -		 * queue on error hoping next time we are luckier.
    -		 */
    -	} else		/* RED needs to know when the queue becomes empty. */
    -		q->idle_time = curr_time;
    -
    -	/*
    -	 * If the delay line was empty call transmit_event() now.
    -	 * Otherwise, the scheduler will take care of it.
    -	 */
    -	if (p_was_empty)
    -		transmit_event(p, head, tail);
    -}
    -
    -/*
    - * Called when we can transmit packets on WF2Q queues. Take pkts out of
    - * the queues at their start time, and enqueue into the delay line.
    - * Packets are drained until p->numbytes < 0. As long as
    - * len_scaled >= p->numbytes, the packet goes into the delay line
    - * with a deadline p->delay. For the last packet, if p->numbytes < 0,
    - * there is an additional delay.
    - */
    -static void
    -ready_event_wfq(struct dn_pipe *p, struct mbuf **head, struct mbuf **tail)
    -{
    -	int p_was_empty = (p->head == NULL);
    -	struct dn_heap *sch = &(p->scheduler_heap);
    -	struct dn_heap *neh = &(p->not_eligible_heap);
    -
    -	DUMMYNET_LOCK_ASSERT();
    -
    -	if (p->if_name[0] == 0)		/* tx clock is simulated */
    -		p->numbytes += (curr_time - p->sched_time) * p->bandwidth;
    -	else {	/*
    -		 * tx clock is for real,
    -		 * the ifq must be empty or this is a NOP.
    -		 */
    -		if (p->ifp && p->ifp->if_snd.ifq_head != NULL)
    -			return;
    -		else {
    -			DPRINTF(("dummynet: pipe %d ready from %s --\n",
    -			    p->pipe_nr, p->if_name));
    -		}
    -	}
    -
    -	/*
    -	 * While we have backlogged traffic AND credit, we need to do
    -	 * something on the queue.
    -	 */
    -	while (p->numbytes >= 0 && (sch->elements > 0 || neh->elements > 0)) {
    -		if (sch->elements > 0) {
    -			/* Have some eligible pkts to send out. */
    -			struct dn_flow_queue *q = sch->p[0].object;
    -			struct mbuf *pkt = q->head;
    -			struct dn_flow_set *fs = q->fs;
    -			uint64_t len = pkt->m_pkthdr.len;
    -			int len_scaled = p->bandwidth ? len * 8 * hz : 0;
    -
    -			heap_extract(sch, NULL); /* Remove queue from heap. */
    -			p->numbytes -= len_scaled;
    -			move_pkt(pkt, q, p, len);
    -
    -			p->V += (len << MY_M) / p->sum;	/* Update V. */
    -			q->S = q->F;			/* Update start time. */
    -			if (q->len == 0) {
    -				/* Flow not backlogged any more. */
    -				fs->backlogged--;
    -				heap_insert(&(p->idle_heap), q->F, q);
    -			} else {
    -				/* Still backlogged. */
    -
    -				/*
    -				 * Update F and position in backlogged queue,
    -				 * then put flow in not_eligible_heap
    -				 * (we will fix this later).
    -				 */
    -				len = (q->head)->m_pkthdr.len;
    -				q->F += (len << MY_M) / (uint64_t)fs->weight;
    -				if (DN_KEY_LEQ(q->S, p->V))
    -					heap_insert(neh, q->S, q);
    -				else
    -					heap_insert(sch, q->F, q);
    -			}
    -		}
    -		/*
    -		 * Now compute V = max(V, min(S_i)). Remember that all elements
    -		 * in sch have by definition S_i <= V so if sch is not empty,
    -		 * V is surely the max and we must not update it. Conversely,
    -		 * if sch is empty we only need to look at neh.
    -		 */
    -		if (sch->elements == 0 && neh->elements > 0)
    -			p->V = MAX64(p->V, neh->p[0].key);
    -		/* Move from neh to sch any packets that have become eligible */
    -		while (neh->elements > 0 && DN_KEY_LEQ(neh->p[0].key, p->V)) {
    -			struct dn_flow_queue *q = neh->p[0].object;
    -			heap_extract(neh, NULL);
    -			heap_insert(sch, q->F, q);
    -		}
    -
    -		if (p->if_name[0] != '\0') { /* Tx clock is from a real thing */
    -			p->numbytes = -1;	/* Mark not ready for I/O. */
    -			break;
    -		}
    -	}
    -	if (sch->elements == 0 && neh->elements == 0 && p->numbytes >= 0) {
    -		p->idle_time = curr_time;
    -		/*
    -		 * No traffic and no events scheduled.
    -		 * We can get rid of idle-heap.
    -		 */
    -		if (p->idle_heap.elements > 0) {
    -			int i;
    -
    -			for (i = 0; i < p->idle_heap.elements; i++) {
    -				struct dn_flow_queue *q;
    -				
    -				q = p->idle_heap.p[i].object;
    -				q->F = 0;
    -				q->S = q->F + 1;
    -			}
    -			p->sum = 0;
    -			p->V = 0;
    -			p->idle_heap.elements = 0;
    -		}
    -	}
    -	/*
    -	 * If we are getting clocks from dummynet (not a real interface) and
    -	 * If we are under credit, schedule the next ready event.
    -	 * Also fix the delivery time of the last packet.
    -	 */
    -	if (p->if_name[0]==0 && p->numbytes < 0) { /* This implies bw > 0. */
    -		dn_key t = 0;		/* Number of ticks i have to wait. */
    -
    -		if (p->bandwidth > 0)
    -			t = (p->bandwidth - 1 - p->numbytes) / p->bandwidth;
    -		dn_tag_get(p->tail)->output_time += t;
    -		p->sched_time = curr_time;
    -		heap_insert(&wfq_ready_heap, curr_time + t, (void *)p);
    -		/*
    -		 * XXX Should check errors on heap_insert, and drain the whole
    -		 * queue on error hoping next time we are luckier.
    -		 */
    -	}
    -
    -	/*
    -	 * If the delay line was empty call transmit_event() now.
    -	 * Otherwise, the scheduler will take care of it.
    -	 */
    -	if (p_was_empty)
    -		transmit_event(p, head, tail);
    -}
    -
    -/*
    - * This is called one tick, after previous run. It is used to
    - * schedule next run.
    - */
     static void
     dummynet(void * __unused unused)
     {
    @@ -831,1448 +83,2079 @@ dummynet(void * __unused unused)
     	taskqueue_enqueue(dn_tq, &dn_task);
     }
     
    -/*
    - * The main dummynet processing function.
    - */
    -static void
    -dummynet_task(void *context, int pending)
    +void
    +dn_reschedule(void)
     {
    -	struct mbuf *head = NULL, *tail = NULL;
    -	struct dn_pipe *pipe;
    -	struct dn_heap *heaps[3];
    -	struct dn_heap *h;
    -	void *p;	/* generic parameter to handler */
    -	int i;
    -
    -	DUMMYNET_LOCK();
    -
    -	heaps[0] = &ready_heap;			/* fixed-rate queues */
    -	heaps[1] = &wfq_ready_heap;		/* wfq queues */
    -	heaps[2] = &extract_heap;		/* delay line */
    -
    - 	/* Update number of lost(coalesced) ticks. */
    - 	tick_lost += pending - 1;
    - 
    - 	getmicrouptime(&t);
    - 	/* Last tick duration (usec). */
    - 	tick_last = (t.tv_sec - prev_t.tv_sec) * 1000000 +
    - 	    (t.tv_usec - prev_t.tv_usec);
    - 	/* Last tick vs standard tick difference (usec). */
    - 	tick_delta = (tick_last * hz - 1000000) / hz;
    - 	/* Accumulated tick difference (usec). */
    - 	tick_delta_sum += tick_delta;
    - 
    - 	prev_t = t;
    - 
    - 	/*
    - 	 * Adjust curr_time if accumulated tick difference greater than
    - 	 * 'standard' tick. Since curr_time should be monotonically increasing,
    - 	 * we do positive adjustment as required and throttle curr_time in
    - 	 * case of negative adjustment.
    - 	 */
    -  	curr_time++;
    - 	if (tick_delta_sum - tick >= 0) {
    - 		int diff = tick_delta_sum / tick;
    - 
    - 		curr_time += diff;
    - 		tick_diff += diff;
    - 		tick_delta_sum %= tick;
    - 		tick_adjustment++;
    - 	} else if (tick_delta_sum + tick <= 0) {
    - 		curr_time--;
    - 		tick_diff--;
    - 		tick_delta_sum += tick;
    - 		tick_adjustment++;
    - 	}
    -
    -	for (i = 0; i < 3; i++) {
    -		h = heaps[i];
    -		while (h->elements > 0 && DN_KEY_LEQ(h->p[0].key, curr_time)) {
    -			if (h->p[0].key > curr_time)
    -				printf("dummynet: warning, "
    -				    "heap %d is %d ticks late\n",
    -				    i, (int)(curr_time - h->p[0].key));
    -			/* store a copy before heap_extract */
    -			p = h->p[0].object;
    -			/* need to extract before processing */
    -			heap_extract(h, NULL);
    -			if (i == 0)
    -				ready_event(p, &head, &tail);
    -			else if (i == 1) {
    -				struct dn_pipe *pipe = p;
    -				if (pipe->if_name[0] != '\0')
    -					printf("dummynet: bad ready_event_wfq "
    -					    "for pipe %s\n", pipe->if_name);
    -				else
    -					ready_event_wfq(p, &head, &tail);
    -			} else
    -				transmit_event(p, &head, &tail);
    -		}
    -	}
    -
    -	/* Sweep pipes trying to expire idle flow_queues. */
    -	for (i = 0; i < HASHSIZE; i++)
    -		SLIST_FOREACH(pipe, &pipehash[i], next)
    -			if (pipe->idle_heap.elements > 0 &&
    -			    DN_KEY_LT(pipe->idle_heap.p[0].key, pipe->V)) {
    -				struct dn_flow_queue *q =
    -				    pipe->idle_heap.p[0].object;
    -
    -				heap_extract(&(pipe->idle_heap), NULL);
    -				/* Mark timestamp as invalid. */
    -				q->S = q->F + 1;
    -				pipe->sum -= q->fs->weight;
    -			}
    -
    -	DUMMYNET_UNLOCK();
    -
    -	if (head != NULL)
    -		dummynet_send(head);
    -
     	callout_reset(&dn_timeout, 1, dummynet, NULL);
     }
    +/*----- end of callout hooks -----*/
     
    -static void
    -dummynet_send(struct mbuf *m)
    +/* Return a scheduler descriptor given the type or name. */
    +static struct dn_alg *
    +find_sched_type(int type, char *name)
     {
    -	struct dn_pkt_tag *pkt;
    -	struct mbuf *n;
    -	struct ip *ip;
    +	struct dn_alg *d;
     
    -	for (; m != NULL; m = n) {
    -		n = m->m_nextpkt;
    -		m->m_nextpkt = NULL;
    -		pkt = dn_tag_get(m);
    -		switch (pkt->dn_dir) {
    -		case DN_TO_IP_OUT:
    -			ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
    -			break ;
    -		case DN_TO_IP_IN :
    -			ip = mtod(m, struct ip *);
    -			ip->ip_len = htons(ip->ip_len);
    -			ip->ip_off = htons(ip->ip_off);
    -			netisr_dispatch(NETISR_IP, m);
    -			break;
    -#ifdef INET6
    -		case DN_TO_IP6_IN:
    -			netisr_dispatch(NETISR_IPV6, m);
    -			break;
    -
    -		case DN_TO_IP6_OUT:
    -			ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
    -			break;
    -#endif
    -		case DN_TO_IFB_FWD:
    -			if (bridge_dn_p != NULL)
    -				((*bridge_dn_p)(m, pkt->ifp));
    -			else
    -				printf("dummynet: if_bridge not loaded\n");
    -
    -			break;
    -		case DN_TO_ETH_DEMUX:
    -			/*
    -			 * The Ethernet code assumes the Ethernet header is
    -			 * contiguous in the first mbuf header.
    -			 * Insure this is true.
    -			 */
    -			if (m->m_len < ETHER_HDR_LEN &&
    -			    (m = m_pullup(m, ETHER_HDR_LEN)) == NULL) {
    -				printf("dummynet/ether: pullup failed, "
    -				    "dropping packet\n");
    -				break;
    -			}
    -			ether_demux(m->m_pkthdr.rcvif, m);
    -			break;
    -		case DN_TO_ETH_OUT:
    -			ether_output_frame(pkt->ifp, m);
    -			break;
    -
    -		case DN_TO_DROP:
    -			/* drop the packet after some time */
    -			m_freem(m);
    -			break;
    -
    -		default:
    -			printf("dummynet: bad switch %d!\n", pkt->dn_dir);
    -			m_freem(m);
    -			break;
    -		}
    +	SLIST_FOREACH(d, &dn_cfg.schedlist, next) {
    +		if (d->type == type || (name && !strcmp(d->name, name)))
    +			return d;
     	}
    +	return NULL; /* not found */
     }
     
    -/*
    - * Unconditionally expire empty queues in case of shortage.
    - * Returns the number of queues freed.
    - */
    -static int
    -expire_queues(struct dn_flow_set *fs)
    +int
    +ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg)
     {
    -    struct dn_flow_queue *q, *prev ;
    -    int i, initial_elements = fs->rq_elements ;
    -
    -    if (fs->last_expired == time_uptime)
    -	return 0 ;
    -    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 (!QUEUE_IS_IDLE(q)) {
    -  		prev = q ;
    -  	        q = q->next ;
    -  	    } else { /* entry is idle, expire it */
    -		struct dn_flow_queue *old_q = q ;
    -
    -		if (prev != NULL)
    -		    prev->next = q = q->next ;
    -		else
    -		    fs->rq[i] = q = q->next ;
    -		fs->rq_elements-- ;
    -		free(old_q, M_DUMMYNET);
    -	    }
    -    return initial_elements - fs->rq_elements ;
    +	int oldv = *v;
    +	const char *op = NULL;
    +	if (oldv < lo) {
    +		*v = dflt;
    +		op = "Bump";
    +	} else if (oldv > hi) {
    +		*v = hi;
    +		op = "Clamp";
    +	} else
    +		return *v;
    +	if (op && msg)
    +		printf("%s %s to %d (was %d)\n", op, msg, *v, oldv);
    +	return *v;
     }
     
    +/*---- flow_id mask, hash and compare functions ---*/
     /*
    - * If room, create a new queue and put at head of slot i;
    - * otherwise, create or use the default queue.
    + * The flow_id includes the 5-tuple, the queue/pipe number
    + * which we store in the extra area in host order,
    + * and for ipv6 also the flow_id6.
    + * XXX see if we want the tos byte (can store in 'flags')
      */
    -static struct dn_flow_queue *
    -create_queue(struct dn_flow_set *fs, int i)
    +static struct ipfw_flow_id *
    +flow_id_mask(struct ipfw_flow_id *mask, struct ipfw_flow_id *id)
     {
    -	struct dn_flow_queue *q;
    +	int is_v6 = IS_IP6_FLOW_ID(id);
     
    -	if (fs->rq_elements > fs->rq_size * dn_max_ratio &&
    -	    expire_queues(fs) == 0) {
    -		/* No way to get room, use or create overflow queue. */
    -		i = fs->rq_size;
    -		if (fs->rq[i] != NULL)
    -		    return fs->rq[i];
    -	}
    -	q = malloc(sizeof(*q), M_DUMMYNET, M_NOWAIT | M_ZERO);
    -	if (q == NULL) {
    -		printf("dummynet: sorry, cannot allocate queue for new flow\n");
    -		return (NULL);
    -	}
    -	q->fs = fs;
    -	q->hash_slot = i;
    -	q->next = fs->rq[i];
    -	q->S = q->F + 1;	/* hack - mark timestamp as invalid. */
    -	q->numbytes = fs->pipe->burst + (io_fast ? fs->pipe->bandwidth : 0);
    -	fs->rq[i] = q;
    -	fs->rq_elements++;
    -	return (q);
    -}
    -
    -/*
    - * Given a flow_set and a pkt in last_pkt, find a matching queue
    - * after appropriate masking. The queue is moved to front
    - * so that further searches take less time.
    - */
    -static struct dn_flow_queue *
    -find_queue(struct dn_flow_set *fs, struct ipfw_flow_id *id)
    -{
    -    int i = 0 ; /* we need i and q for new allocations */
    -    struct dn_flow_queue *q, *prev;
    -    int is_v6 = IS_IP6_FLOW_ID(id);
    -
    -    if ( !(fs->flags_fs & DN_HAVE_FLOW_MASK) )
    -	q = fs->rq[0] ;
    -    else {
    -	/* first, do the masking, then hash */
    -	id->dst_port &= fs->flow_mask.dst_port ;
    -	id->src_port &= fs->flow_mask.src_port ;
    -	id->proto &= fs->flow_mask.proto ;
    -	id->flags = 0 ; /* we don't care about this one */
    +	id->dst_port &= mask->dst_port;
    +	id->src_port &= mask->src_port;
    +	id->proto &= mask->proto;
    +	id->extra &= mask->extra;
     	if (is_v6) {
    -	    APPLY_MASK(&id->dst_ip6, &fs->flow_mask.dst_ip6);
    -	    APPLY_MASK(&id->src_ip6, &fs->flow_mask.src_ip6);
    -	    id->flow_id6 &= fs->flow_mask.flow_id6;
    -
    -	    i = ((id->dst_ip6.__u6_addr.__u6_addr32[0]) & 0xffff)^
    -		((id->dst_ip6.__u6_addr.__u6_addr32[1]) & 0xffff)^
    -		((id->dst_ip6.__u6_addr.__u6_addr32[2]) & 0xffff)^
    -		((id->dst_ip6.__u6_addr.__u6_addr32[3]) & 0xffff)^
    -
    -		((id->dst_ip6.__u6_addr.__u6_addr32[0] >> 15) & 0xffff)^
    -		((id->dst_ip6.__u6_addr.__u6_addr32[1] >> 15) & 0xffff)^
    -		((id->dst_ip6.__u6_addr.__u6_addr32[2] >> 15) & 0xffff)^
    -		((id->dst_ip6.__u6_addr.__u6_addr32[3] >> 15) & 0xffff)^
    -
    -		((id->src_ip6.__u6_addr.__u6_addr32[0] << 1) & 0xfffff)^
    -		((id->src_ip6.__u6_addr.__u6_addr32[1] << 1) & 0xfffff)^
    -		((id->src_ip6.__u6_addr.__u6_addr32[2] << 1) & 0xfffff)^
    -		((id->src_ip6.__u6_addr.__u6_addr32[3] << 1) & 0xfffff)^
    -
    -		((id->src_ip6.__u6_addr.__u6_addr32[0] << 16) & 0xffff)^
    -		((id->src_ip6.__u6_addr.__u6_addr32[1] << 16) & 0xffff)^
    -		((id->src_ip6.__u6_addr.__u6_addr32[2] << 16) & 0xffff)^
    -		((id->src_ip6.__u6_addr.__u6_addr32[3] << 16) & 0xffff)^
    -
    -		(id->dst_port << 1) ^ (id->src_port) ^
    -		(id->proto ) ^
    -		(id->flow_id6);
    +		APPLY_MASK(&id->dst_ip6, &mask->dst_ip6);
    +		APPLY_MASK(&id->src_ip6, &mask->src_ip6);
    +		id->flow_id6 &= mask->flow_id6;
     	} else {
    -	    id->dst_ip &= fs->flow_mask.dst_ip ;
    -	    id->src_ip &= fs->flow_mask.src_ip ;
    -
    -	    i = ( (id->dst_ip) & 0xffff ) ^
    -		( (id->dst_ip >> 15) & 0xffff ) ^
    -		( (id->src_ip << 1) & 0xffff ) ^
    -		( (id->src_ip >> 16 ) & 0xffff ) ^
    -		(id->dst_port << 1) ^ (id->src_port) ^
    -		(id->proto );
    +		id->dst_ip &= mask->dst_ip;
    +		id->src_ip &= mask->src_ip;
     	}
    -	i = i % fs->rq_size ;
    -	/* finally, scan the current list for a match */
    -	searches++ ;
    -	for (prev=NULL, q = fs->rq[i] ; q ; ) {
    -	    search_steps++;
    -	    if (is_v6 &&
    -		    IN6_ARE_ADDR_EQUAL(&id->dst_ip6,&q->id.dst_ip6) &&  
    -		    IN6_ARE_ADDR_EQUAL(&id->src_ip6,&q->id.src_ip6) &&  
    -		    id->dst_port == q->id.dst_port &&
    -		    id->src_port == q->id.src_port &&
    -		    id->proto == q->id.proto &&
    -		    id->flags == q->id.flags &&
    -		    id->flow_id6 == q->id.flow_id6)
    -		break ; /* found */
    +	return id;
    +}
     
    -	    if (!is_v6 && id->dst_ip == q->id.dst_ip &&
    -		    id->src_ip == q->id.src_ip &&
    -		    id->dst_port == q->id.dst_port &&
    -		    id->src_port == q->id.src_port &&
    -		    id->proto == q->id.proto &&
    -		    id->flags == q->id.flags)
    -		break ; /* found */
    +/* computes an OR of two masks, result in dst and also returned */
    +static struct ipfw_flow_id *
    +flow_id_or(struct ipfw_flow_id *src, struct ipfw_flow_id *dst)
    +{
    +	int is_v6 = IS_IP6_FLOW_ID(dst);
     
    -	    /* No match. Check if we can expire the entry */
    -	    if (pipe_expire && QUEUE_IS_IDLE(q)) {
    -		/* entry is idle and not in any heap, expire it */
    -		struct dn_flow_queue *old_q = q ;
    -
    -		if (prev != NULL)
    -		    prev->next = q = q->next ;
    -		else
    -		    fs->rq[i] = q = q->next ;
    -		fs->rq_elements-- ;
    -		free(old_q, M_DUMMYNET);
    -		continue ;
    -	    }
    -	    prev = q ;
    -	    q = q->next ;
    +	dst->dst_port |= src->dst_port;
    +	dst->src_port |= src->src_port;
    +	dst->proto |= src->proto;
    +	dst->extra |= src->extra;
    +	if (is_v6) {
    +#define OR_MASK(_d, _s)                          \
    +    (_d)->__u6_addr.__u6_addr32[0] |= (_s)->__u6_addr.__u6_addr32[0]; \
    +    (_d)->__u6_addr.__u6_addr32[1] |= (_s)->__u6_addr.__u6_addr32[1]; \
    +    (_d)->__u6_addr.__u6_addr32[2] |= (_s)->__u6_addr.__u6_addr32[2]; \
    +    (_d)->__u6_addr.__u6_addr32[3] |= (_s)->__u6_addr.__u6_addr32[3];
    +		OR_MASK(&dst->dst_ip6, &src->dst_ip6);
    +		OR_MASK(&dst->src_ip6, &src->src_ip6);
    +#undef OR_MASK
    +		dst->flow_id6 |= src->flow_id6;
    +	} else {
    +		dst->dst_ip |= src->dst_ip;
    +		dst->src_ip |= src->src_ip;
     	}
    -	if (q && prev != NULL) { /* found and not in front */
    -	    prev->next = q->next ;
    -	    q->next = fs->rq[i] ;
    -	    fs->rq[i] = q ;
    -	}
    -    }
    -    if (q == NULL) { /* no match, need to allocate a new entry */
    -	q = create_queue(fs, i);
    -	if (q != NULL)
    -	q->id = *id ;
    -    }
    -    return q ;
    +	return dst;
     }
     
     static int
    -red_drops(struct dn_flow_set *fs, struct dn_flow_queue *q, int len)
    +nonzero_mask(struct ipfw_flow_id *m)
     {
    -	/*
    -	 * RED algorithm
    -	 *
    -	 * RED calculates the average queue size (avg) using a low-pass filter
    -	 * with an exponential weighted (w_q) moving average:
    -	 * 	avg  <-  (1-w_q) * avg + w_q * q_size
    -	 * where q_size is the queue length (measured in bytes or * packets).
    -	 *
    -	 * If q_size == 0, we compute the idle time for the link, and set
    -	 *	avg = (1 - w_q)^(idle/s)
    -	 * where s is the time needed for transmitting a medium-sized packet.
    -	 *
    -	 * Now, if avg < min_th the packet is enqueued.
    -	 * If avg > max_th the packet is dropped. Otherwise, the packet is
    -	 * dropped with probability P function of avg.
    -	 */
    -
    -	int64_t p_b = 0;
    -
    -	/* Queue in bytes or packets? */
    -	u_int q_size = (fs->flags_fs & DN_QSIZE_IS_BYTES) ?
    -	    q->len_bytes : q->len;
    -
    -	DPRINTF(("\ndummynet: %d q: %2u ", (int)curr_time, q_size));
    -
    -	/* Average queue size estimation. */
    -	if (q_size != 0) {
    -		/* Queue is not empty, avg <- avg + (q_size - avg) * w_q */
    -		int diff = SCALE(q_size) - q->avg;
    -		int64_t v = SCALE_MUL((int64_t)diff, (int64_t)fs->w_q);
    -
    -		q->avg += (int)v;
    +	if (m->dst_port || m->src_port || m->proto || m->extra)
    +		return 1;
    +	if (IS_IP6_FLOW_ID(m)) {
    +		return
    +			m->dst_ip6.__u6_addr.__u6_addr32[0] ||
    +			m->dst_ip6.__u6_addr.__u6_addr32[1] ||
    +			m->dst_ip6.__u6_addr.__u6_addr32[2] ||
    +			m->dst_ip6.__u6_addr.__u6_addr32[3] ||
    +			m->src_ip6.__u6_addr.__u6_addr32[0] ||
    +			m->src_ip6.__u6_addr.__u6_addr32[1] ||
    +			m->src_ip6.__u6_addr.__u6_addr32[2] ||
    +			m->src_ip6.__u6_addr.__u6_addr32[3] ||
    +			m->flow_id6;
     	} else {
    -		/*
    -		 * Queue is empty, find for how long the queue has been
    -		 * empty and use a lookup table for computing
    -		 * (1 - * w_q)^(idle_time/s) where s is the time to send a
    -		 * (small) packet.
    -		 * XXX check wraps...
    -		 */
    -		if (q->avg) {
    -			u_int t = (curr_time - q->idle_time) / fs->lookup_step;
    -
    -			q->avg = (t < fs->lookup_depth) ?
    -			    SCALE_MUL(q->avg, fs->w_q_lookup[t]) : 0;
    -		}
    +		return m->dst_ip || m->src_ip;
     	}
    -	DPRINTF(("dummynet: avg: %u ", SCALE_VAL(q->avg)));
    -
    -	/* Should i drop? */
    -	if (q->avg < fs->min_th) {
    -		q->count = -1;
    -		return (0);	/* accept packet */
    -	}
    -	if (q->avg >= fs->max_th) {	/* average queue >=  max threshold */
    -		if (fs->flags_fs & DN_IS_GENTLE_RED) {
    -			/*
    -			 * According to Gentle-RED, if avg is greater than
    -			 * max_th the packet is dropped with a probability
    -			 *	 p_b = c_3 * avg - c_4
    -			 * where c_3 = (1 - max_p) / max_th
    -			 *       c_4 = 1 - 2 * max_p
    -			 */
    -			p_b = SCALE_MUL((int64_t)fs->c_3, (int64_t)q->avg) -
    -			    fs->c_4;
    -		} else {
    -			q->count = -1;
    -			DPRINTF(("dummynet: - drop"));
    -			return (1);
    -		}
    -	} else if (q->avg > fs->min_th) {
    -		/*
    -		 * We compute p_b using the linear dropping function
    -		 *	 p_b = c_1 * avg - c_2
    -		 * where c_1 = max_p / (max_th - min_th)
    -		 * 	 c_2 = max_p * min_th / (max_th - min_th)
    -		 */
    -		p_b = SCALE_MUL((int64_t)fs->c_1, (int64_t)q->avg) - fs->c_2;
    -	}
    -
    -	if (fs->flags_fs & DN_QSIZE_IS_BYTES)
    -		p_b = (p_b * len) / fs->max_pkt_size;
    -	if (++q->count == 0)
    -		q->random = random() & 0xffff;
    -	else {
    -		/*
    -		 * q->count counts packets arrived since last drop, so a greater
    -		 * value of q->count means a greater packet drop probability.
    -		 */
    -		if (SCALE_MUL(p_b, SCALE((int64_t)q->count)) > q->random) {
    -			q->count = 0;
    -			DPRINTF(("dummynet: - red drop"));
    -			/* After a drop we calculate a new random value. */
    -			q->random = random() & 0xffff;
    -			return (1);	/* drop */
    -		}
    -	}
    -	/* End of RED algorithm. */
    -
    -	return (0);	/* accept */
     }
     
    -static __inline struct dn_flow_set *
    -locate_flowset(int fs_nr)
    +/* XXX we may want a better hash function */
    +static uint32_t
    +flow_id_hash(struct ipfw_flow_id *id)
     {
    -	struct dn_flow_set *fs;
    +    uint32_t i;
     
    -	SLIST_FOREACH(fs, &flowsethash[HASH(fs_nr)], next)
    -		if (fs->fs_nr == fs_nr)
    -			return (fs);
    -
    -	return (NULL);
    +    if (IS_IP6_FLOW_ID(id)) {
    +	uint32_t *d = (uint32_t *)&id->dst_ip6;
    +	uint32_t *s = (uint32_t *)&id->src_ip6;
    +        i = (d[0]      ) ^ (d[1])       ^
    +            (d[2]      ) ^ (d[3])       ^
    +            (d[0] >> 15) ^ (d[1] >> 15) ^
    +            (d[2] >> 15) ^ (d[3] >> 15) ^
    +            (s[0] <<  1) ^ (s[1] <<  1) ^
    +            (s[2] <<  1) ^ (s[3] <<  1) ^
    +            (s[0] << 16) ^ (s[1] << 16) ^
    +            (s[2] << 16) ^ (s[3] << 16) ^
    +            (id->dst_port << 1) ^ (id->src_port) ^
    +	    (id->extra) ^
    +            (id->proto ) ^ (id->flow_id6);
    +    } else {
    +        i = (id->dst_ip)        ^ (id->dst_ip >> 15) ^
    +            (id->src_ip << 1)   ^ (id->src_ip >> 16) ^
    +	    (id->extra) ^
    +            (id->dst_port << 1) ^ (id->src_port)     ^ (id->proto);
    +    }
    +    return i;
     }
     
    -static __inline struct dn_pipe *
    -locate_pipe(int pipe_nr)
    +/* Like bcmp, returns 0 if ids match, 1 otherwise. */
    +static int
    +flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2)
     {
    -	struct dn_pipe *pipe;
    +	int is_v6 = IS_IP6_FLOW_ID(id1);
     
    -	SLIST_FOREACH(pipe, &pipehash[HASH(pipe_nr)], next)
    -		if (pipe->pipe_nr == pipe_nr)
    -			return (pipe);
    +	if (!is_v6) {
    +	    if (IS_IP6_FLOW_ID(id2))
    +		return 1; /* different address families */
     
    -	return (NULL);
    +	    return (id1->dst_ip == id2->dst_ip &&
    +		    id1->src_ip == id2->src_ip &&
    +		    id1->dst_port == id2->dst_port &&
    +		    id1->src_port == id2->src_port &&
    +		    id1->proto == id2->proto &&
    +		    id1->extra == id2->extra) ? 0 : 1;
    +	}
    +	/* the ipv6 case */
    +	return (
    +	    !bcmp(&id1->dst_ip6,&id2->dst_ip6, sizeof(id1->dst_ip6)) &&
    +	    !bcmp(&id1->src_ip6,&id2->src_ip6, sizeof(id1->src_ip6)) &&
    +	    id1->dst_port == id2->dst_port &&
    +	    id1->src_port == id2->src_port &&
    +	    id1->proto == id2->proto &&
    +	    id1->extra == id2->extra &&
    +	    id1->flow_id6 == id2->flow_id6) ? 0 : 1;
    +}
    +/*--------- end of flow-id mask, hash and compare ---------*/
    +
    +/*--- support functions for the qht hashtable ----
    + * Entries are hashed by flow-id
    + */
    +static uint32_t
    +q_hash(uintptr_t key, int flags, void *arg)
    +{
    +	/* compute the hash slot from the flow id */
    +	struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
    +		&((struct dn_queue *)key)->ni.fid :
    +		(struct ipfw_flow_id *)key;
    +
    +	return flow_id_hash(id);
    +}
    +
    +static int
    +q_match(void *obj, uintptr_t key, int flags, void *arg)
    +{
    +	struct dn_queue *o = (struct dn_queue *)obj;
    +	struct ipfw_flow_id *id2;
    +
    +	if (flags & DNHT_KEY_IS_OBJ) {
    +		/* compare pointers */
    +		id2 = &((struct dn_queue *)key)->ni.fid;
    +	} else {
    +		id2 = (struct ipfw_flow_id *)key;
    +	}
    +	return (0 == flow_id_cmp(&o->ni.fid,  id2));
     }
     
     /*
    - * dummynet hook for packets. Below 'pipe' is a pipe or a queue
    - * depending on whether WF2Q or fixed bw is used.
    + * create a new queue instance for the given 'key'.
    + */
    +static void *
    +q_new(uintptr_t key, int flags, void *arg)
    +{   
    +	struct dn_queue *q, *template = arg;
    +	struct dn_fsk *fs = template->fs;
    +	int size = sizeof(*q) + fs->sched->fp->q_datalen;
    +
    +	q = malloc(size, M_DUMMYNET, M_NOWAIT | M_ZERO);
    +	if (q == NULL) {
    +		D("no memory for new queue");
    +		return NULL;
    +	}
    +
    +	set_oid(&q->ni.oid, DN_QUEUE, size);
    +	if (fs->fs.flags & DN_QHT_HASH)
    +		q->ni.fid = *(struct ipfw_flow_id *)key;
    +	q->fs = fs;
    +	q->_si = template->_si;
    +	q->_si->q_count++;
    +
    +	if (fs->sched->fp->new_queue)
    +		fs->sched->fp->new_queue(q);
    +	dn_cfg.queue_count++;
    +	return q;
    +}
    +
    +/*
    + * Notify schedulers that a queue is going away.
    + * If (flags & DN_DESTROY), also free the packets.
    + * The version for callbacks is called q_delete_cb().
    + */
    +static void
    +dn_delete_queue(struct dn_queue *q, int flags)
    +{
    +	struct dn_fsk *fs = q->fs;
    +
    +	// D("fs %p si %p\n", fs, q->_si);
    +	/* notify the parent scheduler that the queue is going away */
    +	if (fs && fs->sched->fp->free_queue)
    +		fs->sched->fp->free_queue(q);
    +	q->_si->q_count--;
    +	q->_si = NULL;
    +	if (flags & DN_DESTROY) {
    +		if (q->mq.head)
    +			dn_free_pkts(q->mq.head);
    +		bzero(q, sizeof(*q));	// safety
    +		free(q, M_DUMMYNET);
    +		dn_cfg.queue_count--;
    +	}
    +}
    +
    +static int
    +q_delete_cb(void *q, void *arg)
    +{
    +	int flags = (int)(uintptr_t)arg;
    +	dn_delete_queue(q, flags);
    +	return (flags & DN_DESTROY) ? DNHT_SCAN_DEL : 0;
    +}
    +
    +/*
    + * calls dn_delete_queue/q_delete_cb on all queues,
    + * which notifies the parent scheduler and possibly drains packets.
    + * flags & DN_DESTROY: drains queues and destroy qht;
    + */
    +static void
    +qht_delete(struct dn_fsk *fs, int flags)
    +{
    +	ND("fs %d start flags %d qht %p",
    +		fs->fs.fs_nr, flags, fs->qht);
    +	if (!fs->qht)
    +		return;
    +	if (fs->fs.flags & DN_QHT_HASH) {
    +		dn_ht_scan(fs->qht, q_delete_cb, (void *)(uintptr_t)flags);
    +		if (flags & DN_DESTROY) {
    +			dn_ht_free(fs->qht, 0);
    +			fs->qht = NULL;
    +		}
    +	} else {
    +		dn_delete_queue((struct dn_queue *)(fs->qht), flags);
    +		if (flags & DN_DESTROY)
    +			fs->qht = NULL;
    +	}
    +}
    +
    +/*
    + * Find and possibly create the queue for a MULTIQUEUE scheduler.
    + * We never call it for !MULTIQUEUE (the queue is in the sch_inst).
    + */
    +struct dn_queue *
    +ipdn_q_find(struct dn_fsk *fs, struct dn_sch_inst *si,
    +	struct ipfw_flow_id *id)
    +{
    +	struct dn_queue template;
    +
    +	template._si = si;
    +	template.fs = fs;
    +
    +	if (fs->fs.flags & DN_QHT_HASH) {
    +		struct ipfw_flow_id masked_id;
    +		if (fs->qht == NULL) {
    +			fs->qht = dn_ht_init(NULL, fs->fs.buckets,
    +				offsetof(struct dn_queue, q_next),
    +				q_hash, q_match, q_new);
    +			if (fs->qht == NULL)
    +				return NULL;
    +		}
    +		masked_id = *id;
    +		flow_id_mask(&fs->fsk_mask, &masked_id);
    +		return dn_ht_find(fs->qht, (uintptr_t)&masked_id,
    +			DNHT_INSERT, &template);
    +	} else {
    +		if (fs->qht == NULL)
    +			fs->qht = q_new(0, 0, &template);
    +		return (struct dn_queue *)fs->qht;
    +	}
    +}
    +/*--- end of queue hash table ---*/
    +
    +/*--- support functions for the sch_inst hashtable ----
      *
    - * pipe_nr	pipe or queue the packet is destined for.
    - * dir		where shall we send the packet after dummynet.
    - * m		the mbuf with the packet
    - * ifp		the 'ifp' parameter from the caller.
    - *		NULL in ip_input, destination interface in ip_output,
    - * rule		matching rule, in case of multiple passes
    + * These are hashed by flow-id
    + */
    +static uint32_t
    +si_hash(uintptr_t key, int flags, void *arg)
    +{
    +	/* compute the hash slot from the flow id */
    +	struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
    +		&((struct dn_sch_inst *)key)->ni.fid :
    +		(struct ipfw_flow_id *)key;
    +
    +	return flow_id_hash(id);
    +}
    +
    +static int
    +si_match(void *obj, uintptr_t key, int flags, void *arg)
    +{
    +	struct dn_sch_inst *o = obj;
    +	struct ipfw_flow_id *id2;
    +
    +	id2 = (flags & DNHT_KEY_IS_OBJ) ?
    +		&((struct dn_sch_inst *)key)->ni.fid :
    +		(struct ipfw_flow_id *)key;
    +	return flow_id_cmp(&o->ni.fid,  id2) == 0;
    +}
    +
    +/*
    + * create a new instance for the given 'key'
    + * Allocate memory for instance, delay line and scheduler private data.
    + */
    +static void *
    +si_new(uintptr_t key, int flags, void *arg)
    +{
    +	struct dn_schk *s = arg;
    +	struct dn_sch_inst *si;
    +	int l = sizeof(*si) + s->fp->si_datalen;
    +
    +	si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
    +	if (si == NULL)
    +		goto error;
    +	/* Set length only for the part passed up to userland. */
    +	set_oid(&si->ni.oid, DN_SCH_I, sizeof(struct dn_flow));
    +	set_oid(&(si->dline.oid), DN_DELAY_LINE,
    +		sizeof(struct delay_line));
    +	/* mark si and dline as outside the event queue */
    +	si->ni.oid.id = si->dline.oid.id = -1;
    +
    +	si->sched = s;
    +	si->dline.si = si;
    +
    +	if (s->fp->new_sched && s->fp->new_sched(si)) {
    +		D("new_sched error");
    +		goto error;
    +	}
    +	if (s->sch.flags & DN_HAVE_MASK)
    +		si->ni.fid = *(struct ipfw_flow_id *)key;
    +
    +	dn_cfg.si_count++;
    +	return si;
    +
    +error:
    +	if (si) {
    +		bzero(si, sizeof(*si)); // safety
    +		free(si, M_DUMMYNET);
    +	}
    +        return NULL;
    +}
    +
    +/*
    + * Callback from siht to delete all scheduler instances. Remove
    + * si and delay line from the system heap, destroy all queues.
    + * We assume that all flowset have been notified and do not
    + * point to us anymore.
      */
     static int
    -dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa)
    +si_destroy(void *_si, void *arg)
     {
    -	struct mbuf *m = *m0, *head = NULL, *tail = NULL;
    -	struct dn_pkt_tag *pkt;
    -	struct m_tag *mtag;
    -	struct dn_flow_set *fs = NULL;
    -	struct dn_pipe *pipe;
    -	uint64_t len = m->m_pkthdr.len;
    -	struct dn_flow_queue *q = NULL;
    -	int is_pipe;
    -	ipfw_insn *cmd = ACTION_PTR(fwa->rule);
    +	struct dn_sch_inst *si = _si;
    +	struct dn_schk *s = si->sched;
    +	struct delay_line *dl = &si->dline;
     
    -	KASSERT(m->m_nextpkt == NULL,
    -	    ("dummynet_io: mbuf queue passed to dummynet"));
    +	if (dl->oid.subtype) /* remove delay line from event heap */
    +		heap_extract(&dn_cfg.evheap, dl);
    +	dn_free_pkts(dl->mq.head);	/* drain delay line */
    +	if (si->kflags & DN_ACTIVE) /* remove si from event heap */
    +		heap_extract(&dn_cfg.evheap, si);
    +	if (s->fp->free_sched)
    +		s->fp->free_sched(si);
    +	bzero(si, sizeof(*si));	/* safety */
    +	free(si, M_DUMMYNET);
    +	dn_cfg.si_count--;
    +	return DNHT_SCAN_DEL;
    +}
     
    -	if (cmd->opcode == O_LOG)
    -		cmd += F_LEN(cmd);
    -	if (cmd->opcode == O_ALTQ)
    -		cmd += F_LEN(cmd);
    -	if (cmd->opcode == O_TAG)
    -		cmd += F_LEN(cmd);
    -	is_pipe = (cmd->opcode == O_PIPE);
    +/*
    + * Find the scheduler instance for this packet. If we need to apply
    + * a mask, do on a local copy of the flow_id to preserve the original.
    + * Assume siht is always initialized if we have a mask.
    + */
    +struct dn_sch_inst *
    +ipdn_si_find(struct dn_schk *s, struct ipfw_flow_id *id)
    +{
     
    -	DUMMYNET_LOCK();
    -	io_pkt++;
    -	/*
    -	 * This is a dummynet rule, so we expect an O_PIPE or O_QUEUE rule.
    -	 *
    -	 * XXXGL: probably the pipe->fs and fs->pipe logic here
    -	 * below can be simplified.
    +	if (s->sch.flags & DN_HAVE_MASK) {
    +		struct ipfw_flow_id id_t = *id;
    +		flow_id_mask(&s->sch.sched_mask, &id_t);
    +		return dn_ht_find(s->siht, (uintptr_t)&id_t,
    +			DNHT_INSERT, s);
    +	}
    +	if (!s->siht)
    +		s->siht = si_new(0, 0, s);
    +	return (struct dn_sch_inst *)s->siht;
    +}
    +
    +/* callback to flush credit for the scheduler instance */
    +static int
    +si_reset_credit(void *_si, void *arg)
    +{
    +	struct dn_sch_inst *si = _si;
    +	struct dn_link *p = &si->sched->link;
    +
    +	si->credit = p->burst + (dn_cfg.io_fast ?  p->bandwidth : 0);
    +	return 0;
    +}
    +
    +static void
    +schk_reset_credit(struct dn_schk *s)
    +{
    +	if (s->sch.flags & DN_HAVE_MASK)
    +		dn_ht_scan(s->siht, si_reset_credit, NULL);
    +	else if (s->siht)
    +		si_reset_credit(s->siht, NULL);
    +}
    +/*---- end of sch_inst hashtable ---------------------*/
    +
    +/*-------------------------------------------------------
    + * flowset hash (fshash) support. Entries are hashed by fs_nr.
    + * New allocations are put in the fsunlinked list, from which
    + * they are removed when they point to a specific scheduler.
    + */
    +static uint32_t
    +fsk_hash(uintptr_t key, int flags, void *arg)
    +{
    +	uint32_t i = !(flags & DNHT_KEY_IS_OBJ) ? key :
    +		((struct dn_fsk *)key)->fs.fs_nr;
    +
    +	return ( (i>>8)^(i>>4)^i );
    +}
    +
    +static int
    +fsk_match(void *obj, uintptr_t key, int flags, void *arg)
    +{
    +	struct dn_fsk *fs = obj;
    +	int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
    +		((struct dn_fsk *)key)->fs.fs_nr;
    +
    +	return (fs->fs.fs_nr == i);
    +}
    +
    +static void *
    +fsk_new(uintptr_t key, int flags, void *arg)
    +{
    +	struct dn_fsk *fs;
    +
    +	fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO);
    +	if (fs) {
    +		set_oid(&fs->fs.oid, DN_FS, sizeof(fs->fs));
    +		dn_cfg.fsk_count++;
    +		fs->drain_bucket = 0;
    +		SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
    +	}
    +	return fs;
    +}
    +
    +/*
    + * detach flowset from its current scheduler. Flags as follows:
    + * DN_DETACH removes from the fsk_list
    + * DN_DESTROY deletes individual queues
    + * DN_DELETE_FS destroys the flowset (otherwise goes in unlinked).
    + */
    +static void
    +fsk_detach(struct dn_fsk *fs, int flags)
    +{
    +	if (flags & DN_DELETE_FS)
    +		flags |= DN_DESTROY;
    +	ND("fs %d from sched %d flags %s %s %s",
    +		fs->fs.fs_nr, fs->fs.sched_nr,
    +		(flags & DN_DELETE_FS) ? "DEL_FS":"",
    +		(flags & DN_DESTROY) ? "DEL":"",
    +		(flags & DN_DETACH) ? "DET":"");
    +	if (flags & DN_DETACH) { /* detach from the list */
    +		struct dn_fsk_head *h;
    +		h = fs->sched ? &fs->sched->fsk_list : &dn_cfg.fsu;
    +		SLIST_REMOVE(h, fs, dn_fsk, sch_chain);
    +	}
    +	/* Free the RED parameters, they will be recomputed on
    +	 * subsequent attach if needed.
     	 */
    -	if (is_pipe) {
    -		pipe = locate_pipe(fwa->cookie);
    -		if (pipe != NULL)
    -			fs = &(pipe->fs);
    -	} else
    -		fs = locate_flowset(fwa->cookie);
    +	if (fs->w_q_lookup)
    +		free(fs->w_q_lookup, M_DUMMYNET);
    +	fs->w_q_lookup = NULL;
    +	qht_delete(fs, flags);
    +	if (fs->sched && fs->sched->fp->free_fsk)
    +		fs->sched->fp->free_fsk(fs);
    +	fs->sched = NULL;
    +	if (flags & DN_DELETE_FS) {
    +		bzero(fs, sizeof(fs));	/* safety */
    +		free(fs, M_DUMMYNET);
    +		dn_cfg.fsk_count--;
    +	} else {
    +		SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
    +	}
    +}
     
    -	if (fs == NULL)
    -		goto dropit;	/* This queue/pipe does not exist! */
    -	pipe = fs->pipe;
    -	if (pipe == NULL) {	/* Must be a queue, try find a matching pipe. */
    -		pipe = locate_pipe(fs->parent_nr);
    -		if (pipe != NULL)
    -			fs->pipe = pipe;
    -		else {
    -			printf("dummynet: no pipe %d for queue %d, drop pkt\n",
    -			    fs->parent_nr, fs->fs_nr);
    -			goto dropit;
    +/*
    + * Detach or destroy all flowsets in a list.
    + * flags specifies what to do:
    + * DN_DESTROY:	flush all queues
    + * DN_DELETE_FS:	DN_DESTROY + destroy flowset
    + *	DN_DELETE_FS implies DN_DESTROY
    + */
    +static void
    +fsk_detach_list(struct dn_fsk_head *h, int flags)
    +{
    +	struct dn_fsk *fs;
    +	int n = 0; /* only for stats */
    +
    +	ND("head %p flags %x", h, flags);
    +	while ((fs = SLIST_FIRST(h))) {
    +		SLIST_REMOVE_HEAD(h, sch_chain);
    +		n++;
    +		fsk_detach(fs, flags);
    +	}
    +	ND("done %d flowsets", n);
    +}
    +
    +/*
    + * called on 'queue X delete' -- removes the flowset from fshash,
    + * deletes all queues for the flowset, and removes the flowset.
    + */
    +static int
    +delete_fs(int i, int locked)
    +{
    +	struct dn_fsk *fs;
    +	int err = 0;
    +
    +	if (!locked)
    +		DN_BH_WLOCK();
    +	fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL);
    +	ND("fs %d found %p", i, fs);
    +	if (fs) {
    +		fsk_detach(fs, DN_DETACH | DN_DELETE_FS);
    +		err = 0;
    +	} else
    +		err = EINVAL;
    +	if (!locked)
    +		DN_BH_WUNLOCK();
    +	return err;
    +}
    +
    +/*----- end of flowset hashtable support -------------*/
    +
    +/*------------------------------------------------------------
    + * Scheduler hash. When searching by index we pass sched_nr,
    + * otherwise we pass struct dn_sch * which is the first field in
    + * struct dn_schk so we can cast between the two. We use this trick
    + * because in the create phase (but it should be fixed).
    + */
    +static uint32_t
    +schk_hash(uintptr_t key, int flags, void *_arg)
    +{
    +	uint32_t i = !(flags & DNHT_KEY_IS_OBJ) ? key :
    +		((struct dn_schk *)key)->sch.sched_nr;
    +	return ( (i>>8)^(i>>4)^i );
    +}
    +
    +static int
    +schk_match(void *obj, uintptr_t key, int flags, void *_arg)
    +{
    +	struct dn_schk *s = (struct dn_schk *)obj;
    +	int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
    +		((struct dn_schk *)key)->sch.sched_nr;
    +	return (s->sch.sched_nr == i);
    +}
    +
    +/*
    + * Create the entry and intialize with the sched hash if needed.
    + * Leave s->fp unset so we can tell whether a dn_ht_find() returns
    + * a new object or a previously existing one.
    + */
    +static void *
    +schk_new(uintptr_t key, int flags, void *arg)
    +{
    +	struct schk_new_arg *a = arg;
    +	struct dn_schk *s;
    +	int l = sizeof(*s) +a->fp->schk_datalen;
    +
    +	s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
    +	if (s == NULL)
    +		return NULL;
    +	set_oid(&s->link.oid, DN_LINK, sizeof(s->link));
    +	s->sch = *a->sch; // copy initial values
    +	s->link.link_nr = s->sch.sched_nr;
    +	SLIST_INIT(&s->fsk_list);
    +	/* initialize the hash table or create the single instance */
    +	s->fp = a->fp;	/* si_new needs this */
    +	s->drain_bucket = 0;
    +	if (s->sch.flags & DN_HAVE_MASK) {
    +		s->siht = dn_ht_init(NULL, s->sch.buckets,
    +			offsetof(struct dn_sch_inst, si_next),
    +			si_hash, si_match, si_new);
    +		if (s->siht == NULL) {
    +			free(s, M_DUMMYNET);
    +			return NULL;
     		}
     	}
    -	q = find_queue(fs, &(fwa->f_id));
    -	if (q == NULL)
    -		goto dropit;		/* Cannot allocate queue. */
    +	s->fp = NULL;	/* mark as a new scheduler */
    +	dn_cfg.schk_count++;
    +	return s;
    +}
     
    -	/* Update statistics, then check reasons to drop pkt. */
    -	q->tot_bytes += len;
    -	q->tot_pkts++;
    -	if (fs->plr && random() < fs->plr)
    -		goto dropit;		/* Random pkt drop. */
    -	if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
    -		if (q->len_bytes > fs->qsize)
    -			goto dropit;	/* Queue size overflow. */
    -	} else {
    -		if (q->len >= fs->qsize)
    -			goto dropit;	/* Queue count overflow. */
    +/*
    + * Callback for sched delete. Notify all attached flowsets to
    + * detach from the scheduler, destroy the internal flowset, and
    + * all instances. The scheduler goes away too.
    + * arg is 0 (only detach flowsets and destroy instances)
    + * DN_DESTROY (detach & delete queues, delete schk)
    + * or DN_DELETE_FS (delete queues and flowsets, delete schk)
    + */
    +static int
    +schk_delete_cb(void *obj, void *arg)
    +{
    +	struct dn_schk *s = obj;
    +#if 0
    +	int a = (int)arg;
    +	ND("sched %d arg %s%s",
    +		s->sch.sched_nr,
    +		a&DN_DESTROY ? "DEL ":"",
    +		a&DN_DELETE_FS ? "DEL_FS":"");
    +#endif
    +	fsk_detach_list(&s->fsk_list, arg ? DN_DESTROY : 0);
    +	/* no more flowset pointing to us now */
    +	if (s->sch.flags & DN_HAVE_MASK)
    +		dn_ht_scan(s->siht, si_destroy, NULL);
    +	else if (s->siht)
    +		si_destroy(s->siht, NULL);
    +	if (s->profile) {
    +		free(s->profile, M_DUMMYNET);
    +		s->profile = NULL;
     	}
    -	if (fs->flags_fs & DN_IS_RED && red_drops(fs, q, len))
    -		goto dropit;
    +	s->siht = NULL;
    +	if (s->fp->destroy)
    +		s->fp->destroy(s);
    +	bzero(s, sizeof(*s));	// safety
    +	free(obj, M_DUMMYNET);
    +	dn_cfg.schk_count--;
    +	return DNHT_SCAN_DEL;
    +}
     
    -	/* XXX expensive to zero, see if we can remove it. */
    -	mtag = m_tag_get(PACKET_TAG_DUMMYNET,
    -	    sizeof(struct dn_pkt_tag), M_NOWAIT | M_ZERO);
    -	if (mtag == NULL)
    -		goto dropit;		/* Cannot allocate packet header. */
    -	m_tag_prepend(m, mtag);		/* Attach to mbuf chain. */
    +/*
    + * called on a 'sched X delete' command. Deletes a single scheduler.
    + * This is done by removing from the schedhash, unlinking all
    + * flowsets and deleting their traffic.
    + */
    +static int
    +delete_schk(int i)
    +{
    +	struct dn_schk *s;
     
    -	pkt = (struct dn_pkt_tag *)(mtag + 1);
    -	/*
    -	 * Ok, i can handle the pkt now...
    -	 * Build and enqueue packet + parameters.
    -	 */
    -	pkt->rule = fwa->rule;
    -	pkt->rule_id = fwa->rule_id;
    -	pkt->chain_id = fwa->chain_id;
    -	pkt->dn_dir = dir;
    +	s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
    +	ND("%d %p", i, s);
    +	if (!s)
    +		return EINVAL;
    +	delete_fs(i + DN_MAX_ID, 1); /* first delete internal fs */
    +	/* then detach flowsets, delete traffic */
    +	schk_delete_cb(s, (void*)(uintptr_t)DN_DESTROY);
    +	return 0;
    +}
    +/*--- end of schk hashtable support ---*/
     
    -	pkt->ifp = fwa->oif;
    +static int
    +copy_obj(char **start, char *end, void *_o, const char *msg, int i)
    +{
    +	struct dn_id *o = _o;
    +	int have = end - *start;
     
    -	if (q->head == NULL)
    -		q->head = m;
    +	if (have < o->len || o->len == 0 || o->type == 0) {
    +		D("(WARN) type %d %s %d have %d need %d",
    +			o->type, msg, i, have, o->len);
    +		return 1;
    +	}
    +	ND("type %d %s %d len %d", o->type, msg, i, o->len);
    +	bcopy(_o, *start, o->len);
    +	if (o->type == DN_LINK) {
    +		/* Adjust burst parameter for link */
    +		struct dn_link *l = (struct dn_link *)*start;
    +		l->burst =  div64(l->burst, 8 * hz);
    +	} else if (o->type == DN_SCH) {
    +		/* Set id->id to the number of instances */
    +		struct dn_schk *s = _o;
    +		struct dn_id *id = (struct dn_id *)(*start);
    +		id->id = (s->sch.flags & DN_HAVE_MASK) ?
    +			dn_ht_entries(s->siht) : (s->siht ? 1 : 0);
    +	}
    +	*start += o->len;
    +	return 0;
    +}
    +
    +/* Specific function to copy a queue.
    + * Copies only the user-visible part of a queue (which is in
    + * a struct dn_flow), and sets len accordingly.
    + */
    +static int
    +copy_obj_q(char **start, char *end, void *_o, const char *msg, int i)
    +{
    +	struct dn_id *o = _o;
    +	int have = end - *start;
    +	int len = sizeof(struct dn_flow); /* see above comment */
    +
    +	if (have < len || o->len == 0 || o->type != DN_QUEUE) {
    +		D("ERROR type %d %s %d have %d need %d",
    +			o->type, msg, i, have, len);
    +		return 1;
    +	}
    +	ND("type %d %s %d len %d", o->type, msg, i, len);
    +	bcopy(_o, *start, len);
    +	((struct dn_id*)(*start))->len = len;
    +	*start += len;
    +	return 0;
    +}
    +
    +static int
    +copy_q_cb(void *obj, void *arg)
    +{
    +	struct dn_queue *q = obj;
    +	struct copy_args *a = arg;
    +	struct dn_flow *ni = (struct dn_flow *)(*a->start);
    +        if (copy_obj_q(a->start, a->end, &q->ni, "queue", -1))
    +                return DNHT_SCAN_END;
    +        ni->oid.type = DN_FLOW; /* override the DN_QUEUE */
    +        ni->oid.id = si_hash((uintptr_t)&ni->fid, 0, NULL);
    +        return 0;
    +}
    +
    +static int
    +copy_q(struct copy_args *a, struct dn_fsk *fs, int flags)
    +{
    +	if (!fs->qht)
    +		return 0;
    +	if (fs->fs.flags & DN_QHT_HASH)
    +		dn_ht_scan(fs->qht, copy_q_cb, a);
     	else
    -		q->tail->m_nextpkt = m;
    -	q->tail = m;
    -	q->len++;
    -	q->len_bytes += len;
    -
    -	if (q->head != m)		/* Flow was not idle, we are done. */
    -		goto done;
    -
    -	if (is_pipe) {			/* Fixed rate queues. */
    -		if (q->idle_time < curr_time) {
    -			/* Calculate available burst size. */
    -			q->numbytes +=
    -			    (curr_time - q->idle_time - 1) * pipe->bandwidth;
    -			if (q->numbytes > pipe->burst)
    -				q->numbytes = pipe->burst;
    -			if (io_fast)
    -				q->numbytes += pipe->bandwidth;
    -		}
    -	} else {			/* WF2Q. */
    -		if (pipe->idle_time < curr_time) {
    -			/* Calculate available burst size. */
    -			pipe->numbytes +=
    -			    (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;
    -		}
    -		pipe->idle_time = curr_time;
    -	}
    -	/* Necessary for both: fixed rate & WF2Q queues. */
    -	q->idle_time = curr_time;
    -
    -	/*
    -	 * If we reach this point the flow was previously idle, so we need
    -	 * to schedule it. This involves different actions for fixed-rate or
    -	 * WF2Q queues.
    -	 */
    -	if (is_pipe) {
    -		/* Fixed-rate queue: just insert into the ready_heap. */
    -		dn_key t = 0;
    -
    -		if (pipe->bandwidth) {
    -			q->extra_bits = compute_extra_bits(m, pipe);
    -			t = set_ticks(m, q, pipe);
    -		}
    -		q->sched_time = curr_time;
    -		if (t == 0)		/* Must process it now. */
    -			ready_event(q, &head, &tail);
    -		else
    -			heap_insert(&ready_heap, curr_time + t , q);
    -	} else {
    -		/*
    -		 * WF2Q. First, compute start time S: if the flow was
    -		 * idle (S = F + 1) set S to the virtual time V for the
    -		 * controlling pipe, and update the sum of weights for the pipe;
    -		 * otherwise, remove flow from idle_heap and set S to max(F,V).
    -		 * Second, compute finish time F = S + len / weight.
    -		 * Third, if pipe was idle, update V = max(S, V).
    -		 * Fourth, count one more backlogged flow.
    -		 */
    -		if (DN_KEY_GT(q->S, q->F)) { /* Means timestamps are invalid. */
    -			q->S = pipe->V;
    -			pipe->sum += fs->weight; /* Add weight of new queue. */
    -		} else {
    -			heap_extract(&(pipe->idle_heap), q);
    -			q->S = MAX64(q->F, pipe->V);
    -		}
    -		q->F = q->S + (len << MY_M) / (uint64_t)fs->weight;
    -
    -		if (pipe->not_eligible_heap.elements == 0 &&
    -		    pipe->scheduler_heap.elements == 0)
    -			pipe->V = MAX64(q->S, pipe->V);
    -		fs->backlogged++;
    -		/*
    -		 * Look at eligibility. A flow is not eligibile if S>V (when
    -		 * this happens, it means that there is some other flow already
    -		 * scheduled for the same pipe, so the scheduler_heap cannot be
    -		 * empty). If the flow is not eligible we just store it in the
    -		 * not_eligible_heap. Otherwise, we store in the scheduler_heap
    -		 * and possibly invoke ready_event_wfq() right now if there is
    -		 * leftover credit.
    -		 * Note that for all flows in scheduler_heap (SCH), S_i <= V,
    -		 * and for all flows in not_eligible_heap (NEH), S_i > V.
    -		 * So when we need to compute max(V, min(S_i)) forall i in
    -		 * SCH+NEH, we only need to look into NEH.
    -		 */
    -		if (DN_KEY_GT(q->S, pipe->V)) {		/* Not eligible. */
    -			if (pipe->scheduler_heap.elements == 0)
    -				printf("dummynet: ++ ouch! not eligible but empty scheduler!\n");
    -			heap_insert(&(pipe->not_eligible_heap), q->S, q);
    -		} else {
    -			heap_insert(&(pipe->scheduler_heap), q->F, q);
    -			if (pipe->numbytes >= 0) {	 /* Pipe is idle. */
    -				if (pipe->scheduler_heap.elements != 1)
    -					printf("dummynet: OUCH! pipe should have been idle!\n");
    -				DPRINTF(("dummynet: waking up pipe %d at %d\n",
    -				    pipe->pipe_nr, (int)(q->F >> MY_M)));
    -				pipe->sched_time = curr_time;
    -				ready_event_wfq(pipe, &head, &tail);
    -			}
    -		}
    -	}
    -done:
    -	if (head == m && dir != DN_TO_IFB_FWD && dir != DN_TO_ETH_DEMUX &&
    -	    dir != DN_TO_ETH_OUT) {	/* Fast io. */
    -		io_pkt_fast++;
    -		if (m->m_nextpkt != NULL)
    -			printf("dummynet: fast io: pkt chain detected!\n");
    -		head = m->m_nextpkt = NULL;
    -	} else
    -		*m0 = NULL;		/* Normal io. */
    -
    -	DUMMYNET_UNLOCK();
    -	if (head != NULL)
    -		dummynet_send(head);
    -	return (0);
    -
    -dropit:
    -	io_pkt_drop++;
    -	if (q)
    -		q->drops++;
    -	DUMMYNET_UNLOCK();
    -	m_freem(m);
    -	*m0 = NULL;
    -	return ((fs && (fs->flags_fs & DN_NOERROR)) ? 0 : ENOBUFS);
    +		copy_q_cb(fs->qht, a);
    +	return 0;
     }
     
     /*
    - * Below, the rt_unref is only needed when (pkt->dn_dir == DN_TO_IP_OUT)
    - * Doing this would probably save us the initial bzero of dn_pkt
    - */
    -#define	DN_FREE_PKT(_m) do {				\
    -	m_freem(_m);					\
    -} while (0)
    -
    -/*
    - * Dispose all packets and flow_queues on a flow_set.
    - * If all=1, also remove red lookup table and other storage,
    - * including the descriptor itself.
    - * For the one in dn_pipe MUST also cleanup ready_heap...
    - */
    -static void
    -purge_flow_set(struct dn_flow_set *fs, int all)
    -{
    -	struct dn_flow_queue *q, *qn;
    -	int i;
    -
    -	DUMMYNET_LOCK_ASSERT();
    -
    -	for (i = 0; i <= fs->rq_size; i++) {
    -		for (q = fs->rq[i]; q != NULL; q = qn) {
    -			struct mbuf *m, *mnext;
    -
    -			mnext = q->head;
    -			while ((m = mnext) != NULL) {
    -				mnext = m->m_nextpkt;
    -				DN_FREE_PKT(m);
    -			}
    -			qn = q->next;
    -			free(q, M_DUMMYNET);
    -		}
    -		fs->rq[i] = NULL;
    -	}
    -
    -	fs->rq_elements = 0;
    -	if (all) {
    -		/* RED - free lookup table. */
    -		if (fs->w_q_lookup != NULL)
    -			free(fs->w_q_lookup, M_DUMMYNET);
    -		if (fs->rq != NULL)
    -			free(fs->rq, M_DUMMYNET);
    -		/* If this fs is not part of a pipe, free it. */
    -		if (fs->pipe == NULL || fs != &(fs->pipe->fs))
    -			free(fs, M_DUMMYNET);
    -	}
    -}
    -
    -/*
    - * Dispose all packets queued on a pipe (not a flow_set).
    - * Also free all resources associated to a pipe, which is about
    - * to be deleted.
    - */
    -static void
    -purge_pipe(struct dn_pipe *pipe)
    -{
    -    struct mbuf *m, *mnext;
    -
    -    purge_flow_set( &(pipe->fs), 1 );
    -
    -    mnext = pipe->head;
    -    while ((m = mnext) != NULL) {
    -	mnext = m->m_nextpkt;
    -	DN_FREE_PKT(m);
    -    }
    -
    -    heap_free( &(pipe->scheduler_heap) );
    -    heap_free( &(pipe->not_eligible_heap) );
    -    heap_free( &(pipe->idle_heap) );
    -}
    -
    -/*
    - * Delete all pipes and heaps returning memory. Must also
    - * remove references from all ipfw rules to all pipes.
    - */
    -static void
    -dummynet_flush(void)
    -{
    -	struct dn_pipe *pipe, *pipe1;
    -	struct dn_flow_set *fs, *fs1;
    -	int i;
    -
    -	DUMMYNET_LOCK();
    -	/* Free heaps so we don't have unwanted events. */
    -	heap_free(&ready_heap);
    -	heap_free(&wfq_ready_heap);
    -	heap_free(&extract_heap);
    -
    -	/*
    -	 * Now purge all queued pkts and delete all pipes.
    -	 *
    -	 * XXXGL: can we merge the for(;;) cycles into one or not?
    -	 */
    -	for (i = 0; i < HASHSIZE; i++)
    -		SLIST_FOREACH_SAFE(fs, &flowsethash[i], next, fs1) {
    -			SLIST_REMOVE(&flowsethash[i], fs, dn_flow_set, next);
    -			purge_flow_set(fs, 1);
    -		}
    -	for (i = 0; i < HASHSIZE; i++)
    -		SLIST_FOREACH_SAFE(pipe, &pipehash[i], next, pipe1) {
    -			SLIST_REMOVE(&pipehash[i], pipe, dn_pipe, next);
    -			purge_pipe(pipe);
    -			free_pipe(pipe);
    -		}
    -	DUMMYNET_UNLOCK();
    -}
    -
    -/*
    - * setup RED parameters
    + * This routine only copies the initial part of a profile ? XXX
      */
     static int
    -config_red(struct dn_flow_set *p, struct dn_flow_set *x)
    +copy_profile(struct copy_args *a, struct dn_profile *p)
     {
    -	int i;
    +	int have = a->end - *a->start;
    +	/* XXX here we check for max length */
    +	int profile_len = sizeof(struct dn_profile) - 
    +		ED_MAX_SAMPLES_NO*sizeof(int);
     
    -	x->w_q = p->w_q;
    -	x->min_th = SCALE(p->min_th);
    -	x->max_th = SCALE(p->max_th);
    -	x->max_p = p->max_p;
    +	if (p == NULL)
    +		return 0;
    +	if (have < profile_len) {
    +		D("error have %d need %d", have, profile_len);
    +		return 1;
    +	}
    +	bcopy(p, *a->start, profile_len);
    +	((struct dn_id *)(*a->start))->len = profile_len;
    +	*a->start += profile_len;
    +	return 0;
    +}
     
    -	x->c_1 = p->max_p / (p->max_th - p->min_th);
    -	x->c_2 = SCALE_MUL(x->c_1, SCALE(p->min_th));
    +static int
    +copy_flowset(struct copy_args *a, struct dn_fsk *fs, int flags)
    +{
    +	struct dn_fs *ufs = (struct dn_fs *)(*a->start);
    +	if (!fs)
    +		return 0;
    +	ND("flowset %d", fs->fs.fs_nr);
    +	if (copy_obj(a->start, a->end, &fs->fs, "flowset", fs->fs.fs_nr))
    +		return DNHT_SCAN_END;
    +	ufs->oid.id = (fs->fs.flags & DN_QHT_HASH) ?
    +		dn_ht_entries(fs->qht) : (fs->qht ? 1 : 0);
    +	if (flags) {	/* copy queues */
    +		copy_q(a, fs, 0);
    +	}
    +	return 0;
    +}
     
    -	if (x->flags_fs & DN_IS_GENTLE_RED) {
    -		x->c_3 = (SCALE(1) - p->max_p) / p->max_th;
    -		x->c_4 = SCALE(1) - 2 * p->max_p;
    +static int
    +copy_si_cb(void *obj, void *arg)
    +{
    +	struct dn_sch_inst *si = obj;
    +	struct copy_args *a = arg;
    +	struct dn_flow *ni = (struct dn_flow *)(*a->start);
    +	if (copy_obj(a->start, a->end, &si->ni, "inst",
    +			si->sched->sch.sched_nr))
    +		return DNHT_SCAN_END;
    +	ni->oid.type = DN_FLOW; /* override the DN_SCH_I */
    +	ni->oid.id = si_hash((uintptr_t)si, DNHT_KEY_IS_OBJ, NULL);
    +	return 0;
    +}
    +
    +static int
    +copy_si(struct copy_args *a, struct dn_schk *s, int flags)
    +{
    +	if (s->sch.flags & DN_HAVE_MASK)
    +		dn_ht_scan(s->siht, copy_si_cb, a);
    +	else if (s->siht)
    +		copy_si_cb(s->siht, a);
    +	return 0;
    +}
    +
    +/*
    + * compute a list of children of a scheduler and copy up
    + */
    +static int
    +copy_fsk_list(struct copy_args *a, struct dn_schk *s, int flags)
    +{
    +	struct dn_fsk *fs;
    +	struct dn_id *o;
    +	uint32_t *p;
    +
    +	int n = 0, space = sizeof(*o);
    +	SLIST_FOREACH(fs, &s->fsk_list, sch_chain) {
    +		if (fs->fs.fs_nr < DN_MAX_ID)
    +			n++;
    +	}
    +	space += n * sizeof(uint32_t);
    +	DX(3, "sched %d has %d flowsets", s->sch.sched_nr, n);
    +	if (a->end - *(a->start) < space)
    +		return DNHT_SCAN_END;
    +	o = (struct dn_id *)(*(a->start));
    +	o->len = space;
    +	*a->start += o->len;
    +	o->type = DN_TEXT;
    +	p = (uint32_t *)(o+1);
    +	SLIST_FOREACH(fs, &s->fsk_list, sch_chain)
    +		if (fs->fs.fs_nr < DN_MAX_ID)
    +			*p++ = fs->fs.fs_nr;
    +	return 0;
    +}
    +
    +static int
    +copy_data_helper(void *_o, void *_arg)
    +{
    +	struct copy_args *a = _arg;
    +	uint32_t *r = a->extra->r; /* start of first range */
    +	uint32_t *lim;	/* first invalid pointer */
    +	int n;
    +
    +	lim = (uint32_t *)((char *)(a->extra) + a->extra->o.len);
    +
    +	if (a->type == DN_LINK || a->type == DN_SCH) {
    +		/* pipe|sched show, we receive a dn_schk */
    +		struct dn_schk *s = _o;
    +
    +		n = s->sch.sched_nr;
    +		if (a->type == DN_SCH && n >= DN_MAX_ID)
    +			return 0;	/* not a scheduler */
    +		if (a->type == DN_LINK && n <= DN_MAX_ID)
    +		    return 0;	/* not a pipe */
    +
    +		/* see if the object is within one of our ranges */
    +		for (;r < lim; r += 2) {
    +			if (n < r[0] || n > r[1])
    +				continue;
    +			/* Found a valid entry, copy and we are done */
    +			if (a->flags & DN_C_LINK) {
    +				if (copy_obj(a->start, a->end,
    +				    &s->link, "link", n))
    +					return DNHT_SCAN_END;
    +				if (copy_profile(a, s->profile))
    +					return DNHT_SCAN_END;
    +				if (copy_flowset(a, s->fs, 0))
    +					return DNHT_SCAN_END;
    +			}
    +			if (a->flags & DN_C_SCH) {
    +				if (copy_obj(a->start, a->end,
    +				    &s->sch, "sched", n))
    +					return DNHT_SCAN_END;
    +				/* list all attached flowsets */
    +				if (copy_fsk_list(a, s, 0))
    +					return DNHT_SCAN_END;
    +			}
    +			if (a->flags & DN_C_FLOW)
    +				copy_si(a, s, 0);
    +			break;
    +		}
    +	} else if (a->type == DN_FS) {
    +		/* queue show, skip internal flowsets */
    +		struct dn_fsk *fs = _o;
    +
    +		n = fs->fs.fs_nr;
    +		if (n >= DN_MAX_ID)
    +			return 0;
    +		/* see if the object is within one of our ranges */
    +		for (;r < lim; r += 2) {
    +			if (n < r[0] || n > r[1])
    +				continue;
    +			if (copy_flowset(a, fs, 0))
    +				return DNHT_SCAN_END;
    +			copy_q(a, fs, 0);
    +			break; /* we are done */
    +		}
    +	}
    +	return 0;
    +}
    +
    +static inline struct dn_schk *
    +locate_scheduler(int i)
    +{
    +	return dn_ht_find(dn_cfg.schedhash, i, 0, NULL);
    +}
    +
    +/*
    + * red parameters are in fixed point arithmetic.
    + */
    +static int
    +config_red(struct dn_fsk *fs)
    +{
    +	int64_t s, idle, weight, w0;
    +	int t, i;
    +
    +	fs->w_q = fs->fs.w_q;
    +	fs->max_p = fs->fs.max_p;
    +	D("called");
    +	/* Doing stuff that was in userland */
    +	i = fs->sched->link.bandwidth;
    +	s = (i <= 0) ? 0 :
    +		hz * dn_cfg.red_avg_pkt_size * 8 * SCALE(1) / i;
    +
    +	idle = div64((s * 3) , fs->w_q); /* s, fs->w_q scaled; idle not scaled */
    +	fs->lookup_step = div64(idle , dn_cfg.red_lookup_depth);
    +	/* fs->lookup_step not scaled, */
    +	if (!fs->lookup_step)
    +		fs->lookup_step = 1;
    +	w0 = weight = SCALE(1) - fs->w_q; //fs->w_q scaled
    +
    +	for (t = fs->lookup_step; t > 1; --t)
    +		weight = SCALE_MUL(weight, w0);
    +	fs->lookup_weight = (int)(weight); // scaled
    +
    +	/* Now doing stuff that was in kerneland */
    +	fs->min_th = SCALE(fs->fs.min_th);
    +	fs->max_th = SCALE(fs->fs.max_th);
    +
    +	fs->c_1 = fs->max_p / (fs->fs.max_th - fs->fs.min_th);
    +	fs->c_2 = SCALE_MUL(fs->c_1, SCALE(fs->fs.min_th));
    +
    +	if (fs->fs.flags & DN_IS_GENTLE_RED) {
    +		fs->c_3 = (SCALE(1) - fs->max_p) / fs->fs.max_th;
    +		fs->c_4 = SCALE(1) - 2 * fs->max_p;
     	}
     
     	/* If the lookup table already exist, free and create it again. */
    -	if (x->w_q_lookup) {
    -		free(x->w_q_lookup, M_DUMMYNET);
    -		x->w_q_lookup = NULL;
    +	if (fs->w_q_lookup) {
    +		free(fs->w_q_lookup, M_DUMMYNET);
    +		fs->w_q_lookup = NULL;
     	}
    -	if (red_lookup_depth == 0) {
    +	if (dn_cfg.red_lookup_depth == 0) {
     		printf("\ndummynet: net.inet.ip.dummynet.red_lookup_depth"
     		    "must be > 0\n");
    -		free(x, M_DUMMYNET);
    +		fs->fs.flags &= ~DN_IS_RED;
    +		fs->fs.flags &= ~DN_IS_GENTLE_RED;
     		return (EINVAL);
     	}
    -	x->lookup_depth = red_lookup_depth;
    -	x->w_q_lookup = (u_int *)malloc(x->lookup_depth * sizeof(int),
    +	fs->lookup_depth = dn_cfg.red_lookup_depth;
    +	fs->w_q_lookup = (u_int *)malloc(fs->lookup_depth * sizeof(int),
     	    M_DUMMYNET, M_NOWAIT);
    -	if (x->w_q_lookup == NULL) {
    +	if (fs->w_q_lookup == NULL) {
     		printf("dummynet: sorry, cannot allocate red lookup table\n");
    -		free(x, M_DUMMYNET);
    +		fs->fs.flags &= ~DN_IS_RED;
    +		fs->fs.flags &= ~DN_IS_GENTLE_RED;
     		return(ENOSPC);
     	}
     
     	/* Fill the lookup table with (1 - w_q)^x */
    -	x->lookup_step = p->lookup_step;
    -	x->lookup_weight = p->lookup_weight;
    -	x->w_q_lookup[0] = SCALE(1) - x->w_q;
    +	fs->w_q_lookup[0] = SCALE(1) - fs->w_q;
     
    -	for (i = 1; i < x->lookup_depth; i++)
    -		x->w_q_lookup[i] =
    -		    SCALE_MUL(x->w_q_lookup[i - 1], x->lookup_weight);
    +	for (i = 1; i < fs->lookup_depth; i++)
    +		fs->w_q_lookup[i] =
    +		    SCALE_MUL(fs->w_q_lookup[i - 1], fs->lookup_weight);
     
    -	if (red_avg_pkt_size < 1)
    -		red_avg_pkt_size = 512;
    -	x->avg_pkt_size = red_avg_pkt_size;
    -	if (red_max_pkt_size < 1)
    -		red_max_pkt_size = 1500;
    -	x->max_pkt_size = red_max_pkt_size;
    -	return (0);
    -}
    -
    -static int
    -alloc_hash(struct dn_flow_set *x, struct dn_flow_set *pfs)
    -{
    -    if (x->flags_fs & DN_HAVE_FLOW_MASK) {     /* allocate some slots */
    -	int l = pfs->rq_size;
    -
    -	if (l == 0)
    -	    l = dn_hash_size;
    -	if (l < 4)
    -	    l = 4;
    -	else if (l > DN_MAX_HASH_SIZE)
    -	    l = DN_MAX_HASH_SIZE;
    -	x->rq_size = l;
    -    } else                  /* one is enough for null mask */
    -	x->rq_size = 1;
    -    x->rq = malloc((1 + x->rq_size) * sizeof(struct dn_flow_queue *),
    -	    M_DUMMYNET, M_NOWAIT | M_ZERO);
    -    if (x->rq == NULL) {
    -	printf("dummynet: sorry, cannot allocate queue\n");
    -	return (ENOMEM);
    -    }
    -    x->rq_elements = 0;
    -    return 0 ;
    +	if (dn_cfg.red_avg_pkt_size < 1)
    +		dn_cfg.red_avg_pkt_size = 512;
    +	fs->avg_pkt_size = dn_cfg.red_avg_pkt_size;
    +	if (dn_cfg.red_max_pkt_size < 1)
    +		dn_cfg.red_max_pkt_size = 1500;
    +	fs->max_pkt_size = dn_cfg.red_max_pkt_size;
    +	D("exit");
    +	return 0;
     }
     
    +/* Scan all flowset attached to this scheduler and update red */
     static void
    -set_fs_parms(struct dn_flow_set *x, struct dn_flow_set *src)
    +update_red(struct dn_schk *s)
     {
    -	x->flags_fs = src->flags_fs;
    -	x->qsize = src->qsize;
    -	x->plr = src->plr;
    -	x->flow_mask = src->flow_mask;
    -	if (x->flags_fs & DN_QSIZE_IS_BYTES) {
    -		if (x->qsize > pipe_byte_limit)
    -			x->qsize = 1024 * 1024;
    -	} else {
    -		if (x->qsize == 0)
    -			x->qsize = 50;
    -		if (x->qsize > pipe_slot_limit)
    -			x->qsize = 50;
    +	struct dn_fsk *fs;
    +	SLIST_FOREACH(fs, &s->fsk_list, sch_chain) {
    +		if (fs && (fs->fs.flags & DN_IS_RED))
    +			config_red(fs);
    +	}
    +}
    +
    +/* attach flowset to scheduler s, possibly requeue */
    +static void
    +fsk_attach(struct dn_fsk *fs, struct dn_schk *s)
    +{
    +	ND("remove fs %d from fsunlinked, link to sched %d",
    +		fs->fs.fs_nr, s->sch.sched_nr);
    +	SLIST_REMOVE(&dn_cfg.fsu, fs, dn_fsk, sch_chain);
    +	fs->sched = s;
    +	SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain);
    +	if (s->fp->new_fsk)
    +		s->fp->new_fsk(fs);
    +	/* XXX compute fsk_mask */
    +	fs->fsk_mask = fs->fs.flow_mask;
    +	if (fs->sched->sch.flags & DN_HAVE_MASK)
    +		flow_id_or(&fs->sched->sch.sched_mask, &fs->fsk_mask);
    +	if (fs->qht) {
    +		/*
    +		 * we must drain qht according to the old
    +		 * type, and reinsert according to the new one.
    +		 * The requeue is complex -- in general we need to
    +		 * reclassify every single packet.
    +		 * For the time being, let's hope qht is never set
    +		 * when we reach this point.
    +		 */
    +		D("XXX TODO requeue from fs %d to sch %d",
    +			fs->fs.fs_nr, s->sch.sched_nr);
    +		fs->qht = NULL;
    +	}
    +	/* set the new type for qht */
    +	if (nonzero_mask(&fs->fsk_mask))
    +		fs->fs.flags |= DN_QHT_HASH;
    +	else
    +		fs->fs.flags &= ~DN_QHT_HASH;
    +
    +	/* XXX config_red() can fail... */
    +	if (fs->fs.flags & DN_IS_RED)
    +		config_red(fs);
    +}
    +
    +/* update all flowsets which may refer to this scheduler */
    +static void
    +update_fs(struct dn_schk *s)
    +{
    +	struct dn_fsk *fs, *tmp;
    +
    +	SLIST_FOREACH_SAFE(fs, &dn_cfg.fsu, sch_chain, tmp) {
    +		if (s->sch.sched_nr != fs->fs.sched_nr) {
    +			D("fs %d for sch %d not %d still unlinked",
    +				fs->fs.fs_nr, fs->fs.sched_nr,
    +				s->sch.sched_nr);
    +			continue;
    +		}
    +		fsk_attach(fs, s);
     	}
    -	/* Configuring RED. */
    -	if (x->flags_fs & DN_IS_RED)
    -		config_red(src, x);	/* XXX should check errors */
     }
     
     /*
    - * Setup pipe or queue parameters.
    + * Configuration -- to preserve backward compatibility we use
    + * the following scheme (N is 65536)
    + *	NUMBER		SCHED	LINK	FLOWSET
    + *	   1 ..  N-1	(1)WFQ	(2)WFQ	(3)queue
    + *	 N+1 .. 2N-1	(4)FIFO (5)FIFO	(6)FIFO for sched 1..N-1
    + *	2N+1 .. 3N-1	--	--	(7)FIFO for sched N+1..2N-1
    + *
    + * "pipe i config" configures #1, #2 and #3
    + * "sched i config" configures #1 and possibly #6
    + * "queue i config" configures #3
    + * #1 is configured with 'pipe i config' or 'sched i config'
    + * #2 is configured with 'pipe i config', and created if not
    + *	existing with 'sched i config'
    + * #3 is configured with 'queue i config'
    + * #4 is automatically configured after #1, can only be FIFO
    + * #5 is automatically configured after #2
    + * #6 is automatically created when #1 is !MULTIQUEUE,
    + *	and can be updated.
    + * #7 is automatically configured after #2
    + */
    +
    +/*
    + * configure a link (and its FIFO instance)
      */
     static int
    -config_pipe(struct dn_pipe *p)
    +config_link(struct dn_link *p, struct dn_id *arg)
     {
    -	struct dn_flow_set *pfs = &(p->fs);
    -	struct dn_flow_queue *q;
    -	int i, error;
    +	int i;
     
    +	if (p->oid.len != sizeof(*p)) {
    +		D("invalid pipe len %d", p->oid.len);
    +		return EINVAL;
    +	}
    +	i = p->link_nr;
    +	if (i <= 0 || i >= DN_MAX_ID)
    +		return EINVAL;
     	/*
     	 * The config program passes parameters as follows:
     	 * bw = bits/second (0 means no limits),
     	 * delay = ms, must be translated into ticks.
     	 * qsize = slots/bytes
    +	 * burst ???
     	 */
     	p->delay = (p->delay * hz) / 1000;
     	/* Scale burst size: bytes -> bits * hz */
     	p->burst *= 8 * hz;
    -	/* We need either a pipe number or a flow_set number. */
    -	if (p->pipe_nr == 0 && pfs->fs_nr == 0)
    -		return (EINVAL);
    -	if (p->pipe_nr != 0 && pfs->fs_nr != 0)
    -		return (EINVAL);
    -	if (p->pipe_nr != 0) {			/* this is a pipe */
    -		struct dn_pipe *pipe;
     
    -		DUMMYNET_LOCK();
    -		pipe = locate_pipe(p->pipe_nr);	/* locate pipe */
    -
    -		if (pipe == NULL) {		/* new pipe */
    -			pipe = malloc(sizeof(struct dn_pipe), M_DUMMYNET,
    -			    M_NOWAIT | M_ZERO);
    -			if (pipe == NULL) {
    -				DUMMYNET_UNLOCK();
    -				printf("dummynet: no memory for new pipe\n");
    -				return (ENOMEM);
    -			}
    -			pipe->pipe_nr = p->pipe_nr;
    -			pipe->fs.pipe = pipe;
    -			/*
    -			 * idle_heap is the only one from which
    -			 * we extract from the middle.
    -			 */
    -			pipe->idle_heap.size = pipe->idle_heap.elements = 0;
    -			pipe->idle_heap.offset =
    -			    offsetof(struct dn_flow_queue, heap_pos);
    -		} else
    -			/* Flush accumulated credit for all queues. */
    -			for (i = 0; i <= pipe->fs.rq_size; i++)
    -				for (q = pipe->fs.rq[i]; q; q = q->next) {
    -					q->numbytes = p->burst +
    -					    (io_fast ? p->bandwidth : 0);
    -				}
    -
    -		pipe->bandwidth = p->bandwidth;
    -		pipe->burst = p->burst;
    -		pipe->numbytes = pipe->burst + (io_fast ? pipe->bandwidth : 0);
    -		bcopy(p->if_name, pipe->if_name, sizeof(p->if_name));
    -		pipe->ifp = NULL;		/* reset interface ptr */
    -		pipe->delay = p->delay;
    -		set_fs_parms(&(pipe->fs), pfs);
    -
    -		/* Handle changes in the delay profile. */
    -		if (p->samples_no > 0) {
    -			if (pipe->samples_no != p->samples_no) {
    -				if (pipe->samples != NULL)
    -					free(pipe->samples, M_DUMMYNET);
    -				pipe->samples =
    -				    malloc(p->samples_no*sizeof(dn_key),
    -					M_DUMMYNET, M_NOWAIT | M_ZERO);
    -				if (pipe->samples == NULL) {
    -					DUMMYNET_UNLOCK();
    -					printf("dummynet: no memory "
    -						"for new samples\n");
    -					return (ENOMEM);
    -				}
    -				pipe->samples_no = p->samples_no;
    -			}
    -
    -			strncpy(pipe->name,p->name,sizeof(pipe->name));
    -			pipe->loss_level = p->loss_level;
    -			for (i = 0; isamples_no; ++i)
    -				pipe->samples[i] = p->samples[i];
    -		} else if (pipe->samples != NULL) {
    -			free(pipe->samples, M_DUMMYNET);
    -			pipe->samples = NULL;
    -			pipe->samples_no = 0;
    -		}
    -
    -		if (pipe->fs.rq == NULL) {	/* a new pipe */
    -			error = alloc_hash(&(pipe->fs), pfs);
    -			if (error) {
    -				DUMMYNET_UNLOCK();
    -				free_pipe(pipe);
    -				return (error);
    -			}
    -			SLIST_INSERT_HEAD(&pipehash[HASH(pipe->pipe_nr)],
    -			    pipe, next);
    -		}
    -		DUMMYNET_UNLOCK();
    -	} else {				/* config queue */
    -		struct dn_flow_set *fs;
    -
    -		DUMMYNET_LOCK();
    -		fs = locate_flowset(pfs->fs_nr); /* locate flow_set */
    -
    -		if (fs == NULL) {		/* new */
    -			if (pfs->parent_nr == 0) { /* need link to a pipe */
    -				DUMMYNET_UNLOCK();
    -				return (EINVAL);
    -			}
    -			fs = malloc(sizeof(struct dn_flow_set), M_DUMMYNET,
    -			    M_NOWAIT | M_ZERO);
    -			if (fs == NULL) {
    -				DUMMYNET_UNLOCK();
    -				printf(
    -				    "dummynet: no memory for new flow_set\n");
    -				return (ENOMEM);
    -			}
    -			fs->fs_nr = pfs->fs_nr;
    -			fs->parent_nr = pfs->parent_nr;
    -			fs->weight = pfs->weight;
    -			if (fs->weight == 0)
    -				fs->weight = 1;
    -			else if (fs->weight > 100)
    -				fs->weight = 100;
    -		} else {
    -			/*
    -			 * Change parent pipe not allowed;
    -			 * must delete and recreate.
    -			 */
    -			if (pfs->parent_nr != 0 &&
    -			    fs->parent_nr != pfs->parent_nr) {
    -				DUMMYNET_UNLOCK();
    -				return (EINVAL);
    -			}
    -		}
    -
    -		set_fs_parms(fs, pfs);
    -
    -		if (fs->rq == NULL) {		/* a new flow_set */
    -			error = alloc_hash(fs, pfs);
    -			if (error) {
    -				DUMMYNET_UNLOCK();
    -				free(fs, M_DUMMYNET);
    -				return (error);
    -			}
    -			SLIST_INSERT_HEAD(&flowsethash[HASH(fs->fs_nr)],
    -			    fs, next);
    -		}
    -		DUMMYNET_UNLOCK();
    -	}
    -	return (0);
    -}
    -
    -/*
    - * Helper function to remove from a heap queues which are linked to
    - * a flow_set about to be deleted.
    - */
    -static void
    -fs_remove_from_heap(struct dn_heap *h, struct dn_flow_set *fs)
    -{
    -    int i = 0, found = 0 ;
    -    for (; i < h->elements ;)
    -	if ( ((struct dn_flow_queue *)h->p[i].object)->fs == fs) {
    -	    h->elements-- ;
    -	    h->p[i] = h->p[h->elements] ;
    -	    found++ ;
    -	} else
    -	    i++ ;
    -    if (found)
    -	heapify(h);
    -}
    -
    -/*
    - * helper function to remove a pipe from a heap (can be there at most once)
    - */
    -static void
    -pipe_remove_from_heap(struct dn_heap *h, struct dn_pipe *p)
    -{
    -    if (h->elements > 0) {
    -	int i = 0 ;
    -	for (i=0; i < h->elements ; i++ ) {
    -	    if (h->p[i].object == p) { /* found it */
    -		h->elements-- ;
    -		h->p[i] = h->p[h->elements] ;
    -		heapify(h);
    -		break ;
    +	DN_BH_WLOCK();
    +	/* do it twice, base link and FIFO link */
    +	for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) {
    +	    struct dn_schk *s = locate_scheduler(i);
    +	    if (s == NULL) {
    +		DN_BH_WUNLOCK();
    +		D("sched %d not found", i);
    +		return EINVAL;
     	    }
    +	    /* remove profile if exists */
    +	    if (s->profile) {
    +		free(s->profile, M_DUMMYNET);
    +		s->profile = NULL;
    +	    }
    +	    /* copy all parameters */
    +	    s->link.oid = p->oid;
    +	    s->link.link_nr = i;
    +	    s->link.delay = p->delay;
    +	    if (s->link.bandwidth != p->bandwidth) {
    +		/* XXX bandwidth changes, need to update red params */
    +	    s->link.bandwidth = p->bandwidth;
    +		update_red(s);
    +	    }
    +	    s->link.burst = p->burst;
    +	    schk_reset_credit(s);
     	}
    -    }
    +	dn_cfg.id++;
    +	DN_BH_WUNLOCK();
    +	return 0;
     }
     
     /*
    - * drain all queues. Called in case of severe mbuf shortage.
    + * configure a flowset. Can be called from inside with locked=1,
      */
    -void
    -dummynet_drain(void)
    +static struct dn_fsk *
    +config_fs(struct dn_fs *nfs, struct dn_id *arg, int locked)
     {
    -    struct dn_flow_set *fs;
    -    struct dn_pipe *pipe;
    -    struct mbuf *m, *mnext;
    -    int i;
    -
    -    DUMMYNET_LOCK_ASSERT();
    -
    -    heap_free(&ready_heap);
    -    heap_free(&wfq_ready_heap);
    -    heap_free(&extract_heap);
    -    /* remove all references to this pipe from flow_sets */
    -    for (i = 0; i < HASHSIZE; i++)
    -	SLIST_FOREACH(fs, &flowsethash[i], next)
    -		purge_flow_set(fs, 0);
    -
    -    for (i = 0; i < HASHSIZE; i++) {
    -	SLIST_FOREACH(pipe, &pipehash[i], next) {
    -		purge_flow_set(&(pipe->fs), 0);
    -
    -		mnext = pipe->head;
    -		while ((m = mnext) != NULL) {
    -			mnext = m->m_nextpkt;
    -			DN_FREE_PKT(m);
    -		}
    -		pipe->head = pipe->tail = NULL;
    -	}
    -    }
    -}
    -
    -/*
    - * Fully delete a pipe or a queue, cleaning up associated info.
    - */
    -static int
    -delete_pipe(struct dn_pipe *p)
    -{
    -
    -    if (p->pipe_nr == 0 && p->fs.fs_nr == 0)
    -	return EINVAL ;
    -    if (p->pipe_nr != 0 && p->fs.fs_nr != 0)
    -	return EINVAL ;
    -    if (p->pipe_nr != 0) { /* this is an old-style pipe */
    -	struct dn_pipe *pipe;
    -	struct dn_flow_set *fs;
     	int i;
    +	struct dn_fsk *fs;
     
    -	DUMMYNET_LOCK();
    -	pipe = locate_pipe(p->pipe_nr);	/* locate pipe */
    -
    -	if (pipe == NULL) {
    -	    DUMMYNET_UNLOCK();
    -	    return (ENOENT);	/* not found */
    +	if (nfs->oid.len != sizeof(*nfs)) {
    +		D("invalid flowset len %d", nfs->oid.len);
    +		return NULL;
     	}
    -
    -	/* Unlink from list of pipes. */
    -	SLIST_REMOVE(&pipehash[HASH(pipe->pipe_nr)], pipe, dn_pipe, next);
    -
    -	/* Remove all references to this pipe from flow_sets. */
    -	for (i = 0; i < HASHSIZE; i++)
    -	    SLIST_FOREACH(fs, &flowsethash[i], next)
    -		if (fs->pipe == pipe) {
    -			printf("dummynet: ++ ref to pipe %d from fs %d\n",
    -			    p->pipe_nr, fs->fs_nr);
    -			fs->pipe = NULL ;
    -			purge_flow_set(fs, 0);
    -		}
    -	fs_remove_from_heap(&ready_heap, &(pipe->fs));
    -	purge_pipe(pipe); /* remove all data associated to this pipe */
    -	/* remove reference to here from extract_heap and wfq_ready_heap */
    -	pipe_remove_from_heap(&extract_heap, pipe);
    -	pipe_remove_from_heap(&wfq_ready_heap, pipe);
    -	DUMMYNET_UNLOCK();
    -
    -	free_pipe(pipe);
    -    } else { /* this is a WF2Q queue (dn_flow_set) */
    -	struct dn_flow_set *fs;
    -
    -	DUMMYNET_LOCK();
    -	fs = locate_flowset(p->fs.fs_nr); /* locate set */
    -
    -	if (fs == NULL) {
    -	    DUMMYNET_UNLOCK();
    -	    return (ENOENT); /* not found */
    +	i = nfs->fs_nr;
    +	if (i <= 0 || i >= 3*DN_MAX_ID)
    +		return NULL;
    +	ND("flowset %d", i);
    +	/* XXX other sanity checks */
    +        if (nfs->flags & DN_QSIZE_BYTES) {
    +		ipdn_bound_var(&nfs->qsize, 16384,
    +		    1500, dn_cfg.byte_limit, NULL); // "queue byte size");
    +        } else {
    +		ipdn_bound_var(&nfs->qsize, 50,
    +		    1, dn_cfg.slot_limit, NULL); // "queue slot size");
    +        }
    +	if (nfs->flags & DN_HAVE_MASK) {
    +		/* make sure we have some buckets */
    +		ipdn_bound_var(&nfs->buckets, dn_cfg.hash_size,
    +			1, dn_cfg.max_hash_size, "flowset buckets");
    +	} else {
    +		nfs->buckets = 1;	/* we only need 1 */
     	}
    -
    -	/* Unlink from list of flowsets. */
    -	SLIST_REMOVE( &flowsethash[HASH(fs->fs_nr)], fs, dn_flow_set, next);
    -
    -	if (fs->pipe != NULL) {
    -	    /* Update total weight on parent pipe and cleanup parent heaps. */
    -	    fs->pipe->sum -= fs->weight * fs->backlogged ;
    -	    fs_remove_from_heap(&(fs->pipe->not_eligible_heap), fs);
    -	    fs_remove_from_heap(&(fs->pipe->scheduler_heap), fs);
    -#if 1	/* XXX should i remove from idle_heap as well ? */
    -	    fs_remove_from_heap(&(fs->pipe->idle_heap), fs);
    -#endif
    -	}
    -	purge_flow_set(fs, 1);
    -	DUMMYNET_UNLOCK();
    -    }
    -    return 0 ;
    +	if (!locked)
    +		DN_BH_WLOCK();
    +	do { /* exit with break when done */
    +	    struct dn_schk *s;
    +	    int flags = nfs->sched_nr ? DNHT_INSERT : 0;
    +	    int j;
    +	    int oldc = dn_cfg.fsk_count;
    +	    fs = dn_ht_find(dn_cfg.fshash, i, flags, NULL);
    +	    if (fs == NULL) {
    +		D("missing sched for flowset %d", i);
    +	        break;
    +	    }
    +	    /* grab some defaults from the existing one */
    +	    if (nfs->sched_nr == 0) /* reuse */
    +		nfs->sched_nr = fs->fs.sched_nr;
    +	    for (j = 0; j < sizeof(nfs->par)/sizeof(nfs->par[0]); j++) {
    +		if (nfs->par[j] == -1) /* reuse */
    +		    nfs->par[j] = fs->fs.par[j];
    +	    }
    +	    if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0) {
    +		ND("flowset %d unchanged", i);
    +		break; /* no change, nothing to do */
    +	    }
    +	    if (oldc != dn_cfg.fsk_count)	/* new item */
    +		dn_cfg.id++;
    +	    s = locate_scheduler(nfs->sched_nr);
    +	    /* detach from old scheduler if needed, preserving
    +	     * queues if we need to reattach. Then update the
    +	     * configuration, and possibly attach to the new sched.
    +	     */
    +	    DX(2, "fs %d changed sched %d@%p to %d@%p",
    +		fs->fs.fs_nr,
    +		fs->fs.sched_nr, fs->sched, nfs->sched_nr, s);
    +	    if (fs->sched) {
    +		int flags = s ? DN_DETACH : (DN_DETACH | DN_DESTROY);
    +		flags |= DN_DESTROY; /* XXX temporary */
    +		fsk_detach(fs, flags);
    +	    }
    +	    fs->fs = *nfs; /* copy configuration */
    +	    if (s != NULL)
    +		fsk_attach(fs, s);
    +	} while (0);
    +	if (!locked)
    +		DN_BH_WUNLOCK();
    +	return fs;
     }
     
     /*
    - * helper function used to copy data from kernel in DUMMYNET_GET
    + * config/reconfig a scheduler and its FIFO variant.
    + * For !MULTIQUEUE schedulers, also set up the flowset.
    + *
    + * On reconfigurations (detected because s->fp is set),
    + * detach existing flowsets preserving traffic, preserve link,
    + * and delete the old scheduler creating a new one.
      */
    -static char *
    -dn_copy_set(struct dn_flow_set *set, char *bp)
    +static int
    +config_sched(struct dn_sch *_nsch, struct dn_id *arg)
     {
    -    int i, copied = 0 ;
    -    struct dn_flow_queue *q, *qp = (struct dn_flow_queue *)bp;
    +	struct dn_schk *s;
    +	struct schk_new_arg a; /* argument for schk_new */
    +	int i;
    +	struct dn_link p;	/* copy of oldlink */
    +	struct dn_profile *pf = NULL;	/* copy of old link profile */
    +	/* Used to preserv mask parameter */
    +	struct ipfw_flow_id new_mask;
    +	int new_buckets = 0;
    +	int new_flags = 0;
    +	int pipe_cmd;
    +	int err = ENOMEM;
     
    -    DUMMYNET_LOCK_ASSERT();
    -
    -    for (i = 0 ; i <= set->rq_size ; i++)
    -	for (q = set->rq[i] ; q ; q = q->next, qp++ ) {
    -	    if (q->hash_slot != i)
    -		printf("dummynet: ++ at %d: wrong slot (have %d, "
    -		    "should be %d)\n", copied, q->hash_slot, i);
    -	    if (q->fs != set)
    -		printf("dummynet: ++ at %d: wrong fs ptr (have %p, should be %p)\n",
    -			i, q->fs, set);
    -	    copied++ ;
    -	    bcopy(q, qp, sizeof( *q ) );
    -	    /* cleanup pointers */
    -	    qp->next = NULL ;
    -	    qp->head = qp->tail = NULL ;
    -	    qp->fs = NULL ;
    +	a.sch = _nsch;
    +	if (a.sch->oid.len != sizeof(*a.sch)) {
    +		D("bad sched len %d", a.sch->oid.len);
    +		return EINVAL;
     	}
    -    if (copied != set->rq_elements)
    -	printf("dummynet: ++ wrong count, have %d should be %d\n",
    -	    copied, set->rq_elements);
    -    return (char *)qp ;
    +	i = a.sch->sched_nr;
    +	if (i <= 0 || i >= DN_MAX_ID)
    +		return EINVAL;
    +	/* make sure we have some buckets */
    +	if (a.sch->flags & DN_HAVE_MASK)
    +		ipdn_bound_var(&a.sch->buckets, dn_cfg.hash_size,
    +			1, dn_cfg.max_hash_size, "sched buckets");
    +	/* XXX other sanity checks */
    +	bzero(&p, sizeof(p));
    +
    +	pipe_cmd = a.sch->flags & DN_PIPE_CMD;
    +	a.sch->flags &= ~DN_PIPE_CMD; //XXX do it even if is not set?
    +	if (pipe_cmd) {
    +		/* Copy mask parameter */
    +		new_mask = a.sch->sched_mask;
    +		new_buckets = a.sch->buckets;
    +		new_flags = a.sch->flags;
    +	}
    +	DN_BH_WLOCK();
    +again: /* run twice, for wfq and fifo */
    +	/*
    +	 * lookup the type. If not supplied, use the previous one
    +	 * or default to WF2Q+. Otherwise, return an error.
    +	 */
    +	dn_cfg.id++;
    +	a.fp = find_sched_type(a.sch->oid.subtype, a.sch->name);
    +	if (a.fp != NULL) {
    +		/* found. Lookup or create entry */
    +		s = dn_ht_find(dn_cfg.schedhash, i, DNHT_INSERT, &a);
    +	} else if (a.sch->oid.subtype == 0 && !a.sch->name[0]) {
    +		/* No type. search existing s* or retry with WF2Q+ */
    +		s = dn_ht_find(dn_cfg.schedhash, i, 0, &a);
    +		if (s != NULL) {
    +			a.fp = s->fp;
    +			/* Scheduler exists, skip to FIFO scheduler 
    +			 * if command was pipe config...
    +			 */
    +			if (pipe_cmd)
    +				goto next;
    +		} else {
    +			/* New scheduler, create a wf2q+ with no mask
    +			 * if command was pipe config...
    +			 */
    +			if (pipe_cmd) {
    +				/* clear mask parameter */
    +				bzero(&a.sch->sched_mask, sizeof(new_mask));
    +				a.sch->buckets = 0;
    +				a.sch->flags &= ~DN_HAVE_MASK;
    +			}
    +			a.sch->oid.subtype = DN_SCHED_WF2QP;
    +			goto again;
    +		}
    +	} else {
    +		D("invalid scheduler type %d %s",
    +			a.sch->oid.subtype, a.sch->name);
    +		err = EINVAL;
    +		goto error;
    +	}
    +	/* normalize name and subtype */
    +	a.sch->oid.subtype = a.fp->type;
    +	bzero(a.sch->name, sizeof(a.sch->name));
    +	strlcpy(a.sch->name, a.fp->name, sizeof(a.sch->name));
    +	if (s == NULL) {
    +		D("cannot allocate scheduler %d", i);
    +		goto error;
    +	}
    +	/* restore existing link if any */
    +	if (p.link_nr) {
    +		s->link = p;
    +		if (!pf || pf->link_nr != p.link_nr) { /* no saved value */
    +			s->profile = NULL; /* XXX maybe not needed */
    +		} else {
    +			s->profile = malloc(sizeof(struct dn_profile),
    +					     M_DUMMYNET, M_NOWAIT | M_ZERO);
    +			if (s->profile == NULL) {
    +				D("cannot allocate profile");
    +				goto error; //XXX
    +			}
    +			bcopy(pf, s->profile, sizeof(*pf));
    +		}
    +	}
    +	p.link_nr = 0;
    +	if (s->fp == NULL) {
    +		DX(2, "sched %d new type %s", i, a.fp->name);
    +	} else if (s->fp != a.fp ||
    +			bcmp(a.sch, &s->sch, sizeof(*a.sch)) ) {
    +		/* already existing. */
    +		DX(2, "sched %d type changed from %s to %s",
    +			i, s->fp->name, a.fp->name);
    +		DX(4, "   type/sub %d/%d -> %d/%d",
    +			s->sch.oid.type, s->sch.oid.subtype, 
    +			a.sch->oid.type, a.sch->oid.subtype);
    +		if (s->link.link_nr == 0)
    +			D("XXX WARNING link 0 for sched %d", i);
    +		p = s->link;	/* preserve link */
    +		if (s->profile) {/* preserve profile */
    +			if (!pf)
    +				pf = malloc(sizeof(*pf),
    +				    M_DUMMYNET, M_NOWAIT | M_ZERO);
    +			if (pf)	/* XXX should issue a warning otherwise */
    +				bcopy(s->profile, pf, sizeof(*pf));
    +		}
    +		/* remove from the hash */
    +		dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
    +		/* Detach flowsets, preserve queues. */
    +		// schk_delete_cb(s, NULL);
    +		// XXX temporarily, kill queues
    +		schk_delete_cb(s, (void *)DN_DESTROY);
    +		goto again;
    +	} else {
    +		DX(4, "sched %d unchanged type %s", i, a.fp->name);
    +	}
    +	/* complete initialization */
    +	s->sch = *a.sch;
    +	s->fp = a.fp;
    +	s->cfg = arg;
    +	// XXX schk_reset_credit(s);
    +	/* create the internal flowset if needed,
    +	 * trying to reuse existing ones if available
    +	 */
    +	if (!(s->fp->flags & DN_MULTIQUEUE) && !s->fs) {
    +	        s->fs = dn_ht_find(dn_cfg.fshash, i, 0, NULL);
    +		if (!s->fs) {
    +			struct dn_fs fs;
    +			bzero(&fs, sizeof(fs));
    +			set_oid(&fs.oid, DN_FS, sizeof(fs));
    +			fs.fs_nr = i + DN_MAX_ID;
    +			fs.sched_nr = i;
    +			s->fs = config_fs(&fs, NULL, 1 /* locked */);
    +		}
    +		if (!s->fs) {
    +			schk_delete_cb(s, (void *)DN_DESTROY);
    +			D("error creating internal fs for %d", i);
    +			goto error;
    +		}
    +	}
    +	/* call init function after the flowset is created */
    +	if (s->fp->config)
    +		s->fp->config(s);
    +	update_fs(s);
    +next:
    +	if (i < DN_MAX_ID) { /* now configure the FIFO instance */
    +		i += DN_MAX_ID;
    +		if (pipe_cmd) {
    +			/* Restore mask parameter for FIFO */
    +			a.sch->sched_mask = new_mask;
    +			a.sch->buckets = new_buckets;
    +			a.sch->flags = new_flags;
    +		} else {
    +			/* sched config shouldn't modify the FIFO scheduler */
    +			if (dn_ht_find(dn_cfg.schedhash, i, 0, &a) != NULL) {
    +				/* FIFO already exist, don't touch it */
    +				err = 0; /* and this is not an error */
    +				goto error;
    +			}
    +		}
    +		a.sch->sched_nr = i;
    +		a.sch->oid.subtype = DN_SCHED_FIFO;
    +		bzero(a.sch->name, sizeof(a.sch->name));
    +		goto again;
    +	}
    +	err = 0;
    +error:
    +	DN_BH_WUNLOCK();
    +	if (pf)
    +		free(pf, M_DUMMYNET);
    +	return err;
     }
     
    -static size_t
    -dn_calc_size(void)
    +/*
    + * attach a profile to a link
    + */
    +static int
    +config_profile(struct dn_profile *pf, struct dn_id *arg)
     {
    -    struct dn_flow_set *fs;
    -    struct dn_pipe *pipe;
    -    size_t size = 0;
    -    int i;
    +	struct dn_schk *s;
    +	int i, olen, err = 0;
     
    -    DUMMYNET_LOCK_ASSERT();
    -    /*
    -     * Compute size of data structures: list of pipes and flow_sets.
    -     */
    -    for (i = 0; i < HASHSIZE; i++) {
    -	SLIST_FOREACH(pipe, &pipehash[i], next)
    -		size += sizeof(*pipe) +
    -		    pipe->fs.rq_elements * sizeof(struct dn_flow_queue);
    -	SLIST_FOREACH(fs, &flowsethash[i], next)
    -		size += sizeof (*fs) +
    -		    fs->rq_elements * sizeof(struct dn_flow_queue);
    -    }
    -    return size;
    +	if (pf->oid.len < sizeof(*pf)) {
    +		D("short profile len %d", pf->oid.len);
    +		return EINVAL;
    +	}
    +	i = pf->link_nr;
    +	if (i <= 0 || i >= DN_MAX_ID)
    +		return EINVAL;
    +	/* XXX other sanity checks */
    +	DN_BH_WLOCK();
    +	for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) {
    +	s = locate_scheduler(i);
    +
    +	if (s == NULL) {
    +			err = EINVAL;
    +			break;
    +	}
    +	dn_cfg.id++;
    +	/*
    +	 * If we had a profile and the new one does not fit,
    +	 * or it is deleted, then we need to free memory.
    +	 */
    +	if (s->profile && (pf->samples_no == 0 ||
    +			s->profile->oid.len < pf->oid.len)) {
    +		free(s->profile, M_DUMMYNET);
    +		s->profile = NULL;
    +	}
    +		if (pf->samples_no == 0)
    +			continue;
    +	/*
    +		 * new profile, possibly allocate memory
    +	 * and copy data.
    +	 */
    +		if (s->profile == NULL)
    +			s->profile = malloc(pf->oid.len,
    +			    M_DUMMYNET, M_NOWAIT | M_ZERO);
    +		if (s->profile == NULL) {
    +			D("no memory for profile %d", i);
    +			err = ENOMEM;
    +			break;
    +		}
    +		/* preserve larger length XXX double check */
    +		olen = s->profile->oid.len;
    +		if (olen < pf->oid.len)
    +			olen = pf->oid.len;
    +		bcopy(pf, s->profile, pf->oid.len);
    +		s->profile->oid.len = olen;
    +	}
    +	DN_BH_WUNLOCK();
    +	return err;
    +}
    +
    +/*
    + * Delete all objects:
    + */
    +static void
    +dummynet_flush(void)
    +{
    +
    +	/* delete all schedulers and related links/queues/flowsets */
    +	dn_ht_scan(dn_cfg.schedhash, schk_delete_cb,
    +		(void *)(uintptr_t)DN_DELETE_FS);
    +	/* delete all remaining (unlinked) flowsets */
    +	DX(4, "still %d unlinked fs", dn_cfg.fsk_count);
    +	dn_ht_free(dn_cfg.fshash, DNHT_REMOVE);
    +	fsk_detach_list(&dn_cfg.fsu, DN_DELETE_FS);
    +	/* Reinitialize system heap... */
    +	heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id));
    +}
    +
    +/*
    + * Main handler for configuration. We are guaranteed to be called
    + * with an oid which is at least a dn_id.
    + * - the first object is the command (config, delete, flush, ...)
    + * - config_link must be issued after the corresponding config_sched
    + * - parameters (DN_TXT) for an object must preceed the object
    + *   processed on a config_sched.
    + */
    +int
    +do_config(void *p, int l)
    +{
    +	struct dn_id *next, *o;
    +	int err = 0, err2 = 0;
    +	struct dn_id *arg = NULL;
    +	uintptr_t *a;
    +
    +	o = p;
    +	if (o->id != DN_API_VERSION) {
    +		D("invalid api version got %d need %d",
    +			o->id, DN_API_VERSION);
    +		return EINVAL;
    +	}
    +	for (; l >= sizeof(*o); o = next) {
    +		struct dn_id *prev = arg;
    +		if (o->len < sizeof(*o) || l < o->len) {
    +			D("bad len o->len %d len %d", o->len, l);
    +			err = EINVAL;
    +			break;
    +		}
    +		l -= o->len;
    +		next = (struct dn_id *)((char *)o + o->len);
    +		err = 0;
    +		switch (o->type) {
    +		default:
    +			D("cmd %d not implemented", o->type);
    +			break;
    +#ifdef EMULATE_SYSCTL		
    +		/* sysctl emulation.
    +		 * if we recognize the command, jump to the correct
    +		 * handler and return
    +		 */
    +		case DN_SYSCTL_SET:
    +			err = kesysctl_emu_set(p, l);
    +			return err;
    +#endif
    +		case DN_CMD_CONFIG: /* simply a header */
    +			break;
    +
    +		case DN_CMD_DELETE:
    +			/* the argument is in the first uintptr_t after o */
    +			a = (uintptr_t *)(o+1);
    +			if (o->len < sizeof(*o) + sizeof(*a)) {
    +				err = EINVAL;
    +				break;
    +			}
    +			switch (o->subtype) {
    +			case DN_LINK:
    +				/* delete base and derived schedulers */
    +				DN_BH_WLOCK();
    +				err = delete_schk(*a);
    +				err2 = delete_schk(*a + DN_MAX_ID);
    +				DN_BH_WUNLOCK();
    +				if (!err)
    +					err = err2;
    +				break;
    +
    +			default:
    +				D("invalid delete type %d",
    +					o->subtype);
    +				err = EINVAL;
    +				break;
    +
    +			case DN_FS:
    +				err = (*a <1 || *a >= DN_MAX_ID) ?
    +					EINVAL : delete_fs(*a, 0) ;
    +				break;
    +			}
    +			break;
    +
    +		case DN_CMD_FLUSH:
    +			DN_BH_WLOCK();
    +			dummynet_flush();
    +			DN_BH_WUNLOCK();
    +			break;
    +		case DN_TEXT:	/* store argument the next block */
    +			prev = NULL;
    +			arg = o;
    +			break;
    +		case DN_LINK:
    +			err = config_link((struct dn_link *)o, arg);
    +			break;
    +		case DN_PROFILE:
    +			err = config_profile((struct dn_profile *)o, arg);
    +			break;
    +		case DN_SCH:
    +			err = config_sched((struct dn_sch *)o, arg);
    +			break;
    +		case DN_FS:
    +			err = (NULL==config_fs((struct dn_fs *)o, arg, 0));
    +			break;
    +		}
    +		if (prev)
    +			arg = NULL;
    +		if (err != 0)
    +			break;
    +	}
    +	return err;
     }
     
     static int
    -dummynet_get(struct sockopt *sopt)
    +compute_space(struct dn_id *cmd, struct copy_args *a)
     {
    -    char *buf, *bp ; /* bp is the "copy-pointer" */
    -    size_t size ;
    -    struct dn_flow_set *fs;
    -    struct dn_pipe *pipe;
    -    int error=0, i ;
    +	int x = 0, need = 0;
    +	int profile_size = sizeof(struct dn_profile) - 
    +		ED_MAX_SAMPLES_NO*sizeof(int);
     
    -    /* XXX lock held too long */
    -    DUMMYNET_LOCK();
    -    /*
    -     * XXX: Ugly, but we need to allocate memory with M_WAITOK flag and we
    -     *      cannot use this flag while holding a mutex.
    -     */
    -    for (i = 0; i < 10; i++) {
    -	size = dn_calc_size();
    -	DUMMYNET_UNLOCK();
    -	buf = malloc(size, M_TEMP, M_WAITOK);
    -	DUMMYNET_LOCK();
    -	if (size == dn_calc_size())
    +	/* NOTE about compute space:
    +	 * NP 	= dn_cfg.schk_count
    +	 * NSI 	= dn_cfg.si_count
    +	 * NF 	= dn_cfg.fsk_count
    +	 * NQ 	= dn_cfg.queue_count
    +	 * - ipfw pipe show
    +	 *   (NP/2)*(dn_link + dn_sch + dn_id + dn_fs) only half scheduler
    +	 *                             link, scheduler template, flowset
    +	 *                             integrated in scheduler and header
    +	 *                             for flowset list
    +	 *   (NSI)*(dn_flow) all scheduler instance (includes
    +	 *                              the queue instance)
    +	 * - ipfw sched show
    +	 *   (NP/2)*(dn_link + dn_sch + dn_id + dn_fs) only half scheduler
    +	 *                             link, scheduler template, flowset
    +	 *                             integrated in scheduler and header
    +	 *                             for flowset list
    +	 *   (NSI * dn_flow) all scheduler instances
    +	 *   (NF * sizeof(uint_32)) space for flowset list linked to scheduler
    +	 *   (NQ * dn_queue) all queue [XXXfor now not listed]
    +	 * - ipfw queue show
    +	 *   (NF * dn_fs) all flowset
    +	 *   (NQ * dn_queue) all queues
    +	 */
    +	switch (cmd->subtype) {
    +	default:
    +		return -1;
    +	/* XXX where do LINK and SCH differ ? */
    +	/* 'ipfw sched show' could list all queues associated to
    +	 * a scheduler. This feature for now is disabled
    +	 */
    +	case DN_LINK:	/* pipe show */
    +		x = DN_C_LINK | DN_C_SCH | DN_C_FLOW;
    +		need += dn_cfg.schk_count *
    +			(sizeof(struct dn_fs) + profile_size) / 2;
    +		need += dn_cfg.fsk_count * sizeof(uint32_t);
    +		break;
    +	case DN_SCH:	/* sched show */
    +		need += dn_cfg.schk_count *
    +			(sizeof(struct dn_fs) + profile_size) / 2;
    +		need += dn_cfg.fsk_count * sizeof(uint32_t);
    +		x = DN_C_SCH | DN_C_LINK | DN_C_FLOW;
    +		break;
    +	case DN_FS:	/* queue show */
    +		x = DN_C_FS | DN_C_QUEUE;
    +		break;
    +	case DN_GET_COMPAT:	/* compatibility mode */
    +		need =  dn_compat_calc_size(dn_cfg); 
     		break;
    -	free(buf, M_TEMP);
    -	buf = NULL;
    -    }
    -    if (buf == NULL) {
    -	DUMMYNET_UNLOCK();
    -	return ENOBUFS ;
    -    }
    -    bp = buf;
    -    for (i = 0; i < HASHSIZE; i++)
    -	SLIST_FOREACH(pipe, &pipehash[i], next) {
    -		struct dn_pipe *pipe_bp = (struct dn_pipe *)bp;
    -
    -		/*
    -		 * Copy pipe descriptor into *bp, convert delay back to ms,
    -		 * then copy the flow_set descriptor(s) one at a time.
    -		 * After each flow_set, copy the queue descriptor it owns.
    -		 */
    -		bcopy(pipe, bp, sizeof(*pipe));
    -		pipe_bp->delay = (pipe_bp->delay * 1000) / hz;
    -		pipe_bp->burst /= 8 * hz;
    -		/*
    -		 * XXX the following is a hack based on ->next being the
    -		 * first field in dn_pipe and dn_flow_set. The correct
    -		 * solution would be to move the dn_flow_set to the beginning
    -		 * of struct dn_pipe.
    -		 */
    -		pipe_bp->next.sle_next = (struct dn_pipe *)DN_IS_PIPE;
    -		/* Clean pointers. */
    -		pipe_bp->head = pipe_bp->tail = NULL;
    -		pipe_bp->fs.next.sle_next = NULL;
    -		pipe_bp->fs.pipe = NULL;
    -		pipe_bp->fs.rq = NULL;
    -		pipe_bp->samples = NULL;
    -
    -		bp += sizeof(*pipe) ;
    -		bp = dn_copy_set(&(pipe->fs), bp);
     	}
    -
    -    for (i = 0; i < HASHSIZE; i++)
    -	SLIST_FOREACH(fs, &flowsethash[i], next) {
    -		struct dn_flow_set *fs_bp = (struct dn_flow_set *)bp;
    -
    -		bcopy(fs, bp, sizeof(*fs));
    -		/* XXX same hack as above */
    -		fs_bp->next.sle_next = (struct dn_flow_set *)DN_IS_QUEUE;
    -		fs_bp->pipe = NULL;
    -		fs_bp->rq = NULL;
    -		bp += sizeof(*fs);
    -		bp = dn_copy_set(fs, bp);
    +	a->flags = x;
    +	if (x & DN_C_SCH) {
    +		need += dn_cfg.schk_count * sizeof(struct dn_sch) / 2;
    +		/* NOT also, each fs might be attached to a sched */
    +		need += dn_cfg.schk_count * sizeof(struct dn_id) / 2;
     	}
    +	if (x & DN_C_FS)
    +		need += dn_cfg.fsk_count * sizeof(struct dn_fs);
    +	if (x & DN_C_LINK) {
    +		need += dn_cfg.schk_count * sizeof(struct dn_link) / 2;
    +	}
    +	/*
    +	 * When exporting a queue to userland, only pass up the
    +	 * struct dn_flow, which is the only visible part.
    +	 */
     
    -    DUMMYNET_UNLOCK();
    -
    -    error = sooptcopyout(sopt, buf, size);
    -    free(buf, M_TEMP);
    -    return error ;
    +	if (x & DN_C_QUEUE)
    +		need += dn_cfg.queue_count * sizeof(struct dn_flow);
    +	if (x & DN_C_FLOW)
    +		need += dn_cfg.si_count * (sizeof(struct dn_flow));
    +	return need;
     }
     
     /*
    - * Handler for the various dummynet socket options (get, flush, config, del)
    + * If compat != NULL dummynet_get is called in compatibility mode.
    + * *compat will be the pointer to the buffer to pass to ipfw
    + */
    +int
    +dummynet_get(struct sockopt *sopt, void **compat)
    +{
    +	int have, i, need, error;
    +	char *start = NULL, *buf;
    +	size_t sopt_valsize;
    +	struct dn_id *cmd;
    +	struct copy_args a;
    +	struct copy_range r;
    +	int l = sizeof(struct dn_id);
    +
    +	bzero(&a, sizeof(a));
    +	bzero(&r, sizeof(r));
    +
    +	/* save and restore original sopt_valsize around copyin */
    +	sopt_valsize = sopt->sopt_valsize;
    +
    +	cmd = &r.o;
    +
    +	if (!compat) {
    +		/* copy at least an oid, and possibly a full object */
    +		error = sooptcopyin(sopt, cmd, sizeof(r), sizeof(*cmd));
    +		sopt->sopt_valsize = sopt_valsize;
    +		if (error)
    +			goto done;
    +		l = cmd->len;
    +#ifdef EMULATE_SYSCTL
    +		/* sysctl emulation. */
    +		if (cmd->type == DN_SYSCTL_GET)
    +			return kesysctl_emu_get(sopt);
    +#endif
    +		if (l > sizeof(r)) {
    +			/* request larger than default, allocate buffer */
    +			cmd = malloc(l,  M_DUMMYNET, M_WAIT);
    +			if (cmd == NULL)
    +				return ENOMEM; //XXX
    +			error = sooptcopyin(sopt, cmd, l, l);
    +			sopt->sopt_valsize = sopt_valsize;
    +			if (error)
    +				goto done;
    +		}
    +	} else { /* compatibility */
    +		error = 0;
    +		cmd->type = DN_CMD_GET;
    +		cmd->len = sizeof(struct dn_id);
    +		cmd->subtype = DN_GET_COMPAT;
    +		// cmd->id = sopt_valsize;
    +		D("compatibility mode");
    +	}
    +	a.extra = (struct copy_range *)cmd;
    +	if (cmd->len == sizeof(*cmd)) { /* no range, create a default */
    +		uint32_t *rp = (uint32_t *)(cmd + 1);
    +		cmd->len += 2* sizeof(uint32_t);
    +		rp[0] = 1;
    +		rp[1] = DN_MAX_ID - 1;
    +		if (cmd->subtype == DN_LINK) {
    +			rp[0] += DN_MAX_ID;
    +			rp[1] += DN_MAX_ID;
    +		}
    +	}
    +	/* Count space (under lock) and allocate (outside lock).
    +	 * Exit with lock held if we manage to get enough buffer.
    +	 * Try a few times then give up.
    +	 */
    +	for (have = 0, i = 0; i < 10; i++) {
    +		DN_BH_WLOCK();
    +		need = compute_space(cmd, &a);
    +
    +		/* if there is a range, ignore value from compute_space() */
    +		if (l > sizeof(*cmd))
    +			need = sopt_valsize - sizeof(*cmd);
    +
    +		if (need < 0) {
    +			DN_BH_WUNLOCK();
    +			error = EINVAL;
    +			goto done;
    +		}
    +		need += sizeof(*cmd);
    +		cmd->id = need;
    +		if (have >= need)
    +			break;
    +
    +		DN_BH_WUNLOCK();
    +		if (start)
    +			free(start, M_DUMMYNET);
    +		start = NULL;
    +		if (need > sopt_valsize)
    +			break;
    +
    +		have = need;
    +		start = malloc(have, M_DUMMYNET, M_WAITOK | M_ZERO);
    +		if (start == NULL) {
    +			error = ENOMEM;
    +			goto done;
    +		}
    +	}
    +
    +	if (start == NULL) {
    +		if (compat) {
    +			*compat = NULL;
    +			error =  1; // XXX
    +		} else {
    +			error = sooptcopyout(sopt, cmd, sizeof(*cmd));
    +		}
    +		goto done;
    +	}
    +	ND("have %d:%d sched %d, %d:%d links %d, %d:%d flowsets %d, "
    +		"%d:%d si %d, %d:%d queues %d",
    +		dn_cfg.schk_count, sizeof(struct dn_sch), DN_SCH,
    +		dn_cfg.schk_count, sizeof(struct dn_link), DN_LINK,
    +		dn_cfg.fsk_count, sizeof(struct dn_fs), DN_FS,
    +		dn_cfg.si_count, sizeof(struct dn_flow), DN_SCH_I,
    +		dn_cfg.queue_count, sizeof(struct dn_queue), DN_QUEUE);
    +	sopt->sopt_valsize = sopt_valsize;
    +	a.type = cmd->subtype;
    +
    +	if (compat == NULL) {
    +		bcopy(cmd, start, sizeof(*cmd));
    +		((struct dn_id*)(start))->len = sizeof(struct dn_id);
    +		buf = start + sizeof(*cmd);
    +	} else
    +		buf = start;
    +	a.start = &buf;
    +	a.end = start + have;
    +	/* start copying other objects */
    +	if (compat) {
    +		a.type = DN_COMPAT_PIPE;
    +		dn_ht_scan(dn_cfg.schedhash, copy_data_helper_compat, &a);
    +		a.type = DN_COMPAT_QUEUE;
    +		dn_ht_scan(dn_cfg.fshash, copy_data_helper_compat, &a);
    +	} else if (a.type == DN_FS) {
    +		dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a);
    +	} else {
    +		dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a);
    +	}
    +	DN_BH_WUNLOCK();
    +
    +	if (compat) {
    +		*compat = start;
    +		sopt->sopt_valsize = buf - start;
    +		/* free() is done by ip_dummynet_compat() */
    +		start = NULL; //XXX hack
    +	} else {
    +		error = sooptcopyout(sopt, start, buf - start);
    +	}
    +done:
    +	if (cmd && cmd != &r.o)
    +		free(cmd, M_DUMMYNET);
    +	if (start)
    +		free(start, M_DUMMYNET);
    +	return error;
    +}
    +
    +/* Callback called on scheduler instance to delete it if idle */
    +static int
    +drain_scheduler_cb(void *_si, void *arg)
    +{
    +	struct dn_sch_inst *si = _si;
    +
    +	if ((si->kflags & DN_ACTIVE) || si->dline.mq.head != NULL)
    +		return 0;
    +
    +	if (si->sched->fp->flags & DN_MULTIQUEUE) {
    +		if (si->q_count == 0)
    +			return si_destroy(si, NULL);
    +		else
    +			return 0;
    +	} else { /* !DN_MULTIQUEUE */
    +		if ((si+1)->ni.length == 0)
    +			return si_destroy(si, NULL);
    +		else
    +			return 0;
    +	}
    +	return 0; /* unreachable */
    +}
    +
    +/* Callback called on scheduler to check if it has instances */
    +static int
    +drain_scheduler_sch_cb(void *_s, void *arg)
    +{
    +	struct dn_schk *s = _s;
    +
    +	if (s->sch.flags & DN_HAVE_MASK) {
    +		dn_ht_scan_bucket(s->siht, &s->drain_bucket,
    +				drain_scheduler_cb, NULL);
    +		s->drain_bucket++;
    +	} else {
    +		if (s->siht) {
    +			if (drain_scheduler_cb(s->siht, NULL) == DNHT_SCAN_DEL)
    +				s->siht = NULL;
    +		}
    +	}
    +	return 0;
    +}
    +
    +/* Called every tick, try to delete a 'bucket' of scheduler */
    +void
    +dn_drain_scheduler(void)
    +{
    +	dn_ht_scan_bucket(dn_cfg.schedhash, &dn_cfg.drain_sch,
    +			   drain_scheduler_sch_cb, NULL);
    +	dn_cfg.drain_sch++;
    +}
    +
    +/* Callback called on queue to delete if it is idle */
    +static int
    +drain_queue_cb(void *_q, void *arg)
    +{
    +	struct dn_queue *q = _q;
    +
    +	if (q->ni.length == 0) {
    +		dn_delete_queue(q, DN_DESTROY);
    +		return DNHT_SCAN_DEL; /* queue is deleted */
    +	}
    +
    +	return 0; /* queue isn't deleted */
    +}
    +
    +/* Callback called on flowset used to check if it has queues */
    +static int
    +drain_queue_fs_cb(void *_fs, void *arg)
    +{
    +	struct dn_fsk *fs = _fs;
    +
    +	if (fs->fs.flags & DN_QHT_HASH) {
    +		/* Flowset has a hash table for queues */
    +		dn_ht_scan_bucket(fs->qht, &fs->drain_bucket,
    +				drain_queue_cb, NULL);
    +		fs->drain_bucket++;
    +	} else {
    +		/* No hash table for this flowset, null the pointer 
    +		 * if the queue is deleted
    +		 */
    +		if (fs->qht) {
    +			if (drain_queue_cb(fs->qht, NULL) == DNHT_SCAN_DEL)
    +				fs->qht = NULL;
    +		}
    +	}
    +	return 0;
    +}
    +
    +/* Called every tick, try to delete a 'bucket' of queue */
    +void
    +dn_drain_queue(void)
    +{
    +	/* scan a bucket of flowset */
    +	dn_ht_scan_bucket(dn_cfg.fshash, &dn_cfg.drain_fs,
    +                               drain_queue_fs_cb, NULL);
    +	dn_cfg.drain_fs++;
    +}
    +
    +/*
    + * Handler for the various dummynet socket options
      */
     static int
     ip_dn_ctl(struct sockopt *sopt)
     {
    -    int error;
    -    struct dn_pipe *p = NULL;
    +	void *p = NULL;
    +	int error, l;
     
    -    error = priv_check(sopt->sopt_td, PRIV_NETINET_DUMMYNET);
    -    if (error)
    -	return (error);
    -
    -    /* Disallow sets in really-really secure mode. */
    -    if (sopt->sopt_dir == SOPT_SET) {
    -#if __FreeBSD_version >= 500034
    -	error =  securelevel_ge(sopt->sopt_td->td_ucred, 3);
    +	error = priv_check(sopt->sopt_td, PRIV_NETINET_DUMMYNET);
     	if (error)
    -	    return (error);
    -#else
    -	if (securelevel >= 3)
    -	    return (EPERM);
    -#endif
    -    }
    +		return (error);
     
    -    switch (sopt->sopt_name) {
    -    default :
    -	printf("dummynet: -- unknown option %d", sopt->sopt_name);
    -	error = EINVAL ;
    -	break;
    +	/* Disallow sets in really-really secure mode. */
    +	if (sopt->sopt_dir == SOPT_SET) {
    +		error =  securelevel_ge(sopt->sopt_td->td_ucred, 3);
    +		if (error)
    +			return (error);
    +	}
     
    -    case IP_DUMMYNET_GET :
    -	error = dummynet_get(sopt);
    -	break ;
    +	switch (sopt->sopt_name) {
    +	default :
    +		D("dummynet: unknown option %d", sopt->sopt_name);
    +		error = EINVAL;
    +		break;
     
    -    case IP_DUMMYNET_FLUSH :
    -	dummynet_flush() ;
    -	break ;
    +	case IP_DUMMYNET_FLUSH:
    +	case IP_DUMMYNET_CONFIGURE:
    +	case IP_DUMMYNET_DEL:	/* remove a pipe or queue */
    +	case IP_DUMMYNET_GET:
    +		D("dummynet: compat option %d", sopt->sopt_name);
    +		error = ip_dummynet_compat(sopt);
    +		break;
     
    -    case IP_DUMMYNET_CONFIGURE :
    -	p = malloc(sizeof(struct dn_pipe_max), M_TEMP, M_WAITOK);
    -	error = sooptcopyin(sopt, p, sizeof(struct dn_pipe_max), sizeof *p);
    -	if (error)
    -	    break ;
    -	if (p->samples_no > 0)
    -	    p->samples = &(((struct dn_pipe_max *)p)->samples[0]);
    +	case IP_DUMMYNET3 :
    +		if (sopt->sopt_dir == SOPT_GET) {
    +			error = dummynet_get(sopt, NULL);
    +			break;
    +		}
    +		l = sopt->sopt_valsize;
    +		if (l < sizeof(struct dn_id) || l > 12000) {
    +			D("argument len %d invalid", l);
    +			break;
    +		}
    +		p = malloc(l, M_TEMP, M_WAITOK); // XXX can it fail ?
    +		error = sooptcopyin(sopt, p, l, l);
    +		if (error)
    +			break ;
    +		error = do_config(p, l);
    +		break;
    +	}
     
    -	error = config_pipe(p);
    -	break ;
    +	if (p != NULL)
    +		free(p, M_TEMP);
     
    -    case IP_DUMMYNET_DEL :	/* remove a pipe or queue */
    -	p = malloc(sizeof(struct dn_pipe), M_TEMP, M_WAITOK);
    -	error = sooptcopyin(sopt, p, sizeof(struct dn_pipe), sizeof *p);
    -	if (error)
    -	    break ;
    -
    -	error = delete_pipe(p);
    -	break ;
    -    }
    -    if (p != NULL)
    -	free(p, M_TEMP);
    -    return error ;
    +	return error ;
     }
     
    +
     static void
     ip_dn_init(void)
     {
    -	int i;
    +	static int init_done = 0;
     
    +	if (init_done)
    +		return;
    +	init_done = 1;
     	if (bootverbose)
    -		printf("DUMMYNET with IPv6 initialized (040826)\n");
    +		printf("DUMMYNET with IPv6 initialized (100131)\n");
     
    -	DUMMYNET_LOCK_INIT();
    +	/* Set defaults here. MSVC does not accept initializers,
    +	 * and this is also useful for vimages
    +	 */
    +	/* queue limits */
    +	dn_cfg.slot_limit = 100; /* Foot shooting limit for queues. */
    +	dn_cfg.byte_limit = 1024 * 1024;
    +	dn_cfg.expire = 1;
     
    -	for (i = 0; i < HASHSIZE; i++) {
    -		SLIST_INIT(&pipehash[i]);
    -		SLIST_INIT(&flowsethash[i]);
    -	}
    -	ready_heap.size = ready_heap.elements = 0;
    -	ready_heap.offset = 0;
    +	/* RED parameters */
    +	dn_cfg.red_lookup_depth = 256;	/* default lookup table depth */
    +	dn_cfg.red_avg_pkt_size = 512;	/* default medium packet size */
    +	dn_cfg.red_max_pkt_size = 1500;	/* default max packet size */
     
    -	wfq_ready_heap.size = wfq_ready_heap.elements = 0;
    -	wfq_ready_heap.offset = 0;
    +	/* hash tables */
    +	dn_cfg.max_hash_size = 1024;	/* max in the hash tables */
    +	dn_cfg.hash_size = 64;		/* default hash size */
     
    -	extract_heap.size = extract_heap.elements = 0;
    -	extract_heap.offset = 0;
    +	/* create hash tables for schedulers and flowsets.
    +	 * In both we search by key and by pointer.
    +	 */
    +	dn_cfg.schedhash = dn_ht_init(NULL, dn_cfg.hash_size,
    +		offsetof(struct dn_schk, schk_next),
    +		schk_hash, schk_match, schk_new);
    +	dn_cfg.fshash = dn_ht_init(NULL, dn_cfg.hash_size,
    +		offsetof(struct dn_fsk, fsk_next),
    +		fsk_hash, fsk_match, fsk_new);
     
    +	/* bucket index to drain object */
    +	dn_cfg.drain_fs = 0;
    +	dn_cfg.drain_sch = 0;
    +
    +	heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id));
    +	SLIST_INIT(&dn_cfg.fsu);
    +	SLIST_INIT(&dn_cfg.schedlist);
    +
    +	DN_LOCK_INIT();
     	ip_dn_ctl_ptr = ip_dn_ctl;
     	ip_dn_io_ptr = dummynet_io;
     
    @@ -2285,25 +2168,29 @@ ip_dn_init(void)
     	callout_reset(&dn_timeout, 1, dummynet, NULL);
     
     	/* Initialize curr_time adjustment mechanics. */
    -	getmicrouptime(&prev_t);
    +	getmicrouptime(&dn_cfg.prev_t);
     }
     
     #ifdef KLD_MODULE
     static void
     ip_dn_destroy(void)
     {
    +	callout_drain(&dn_timeout);
    +
    +	DN_BH_WLOCK();
     	ip_dn_ctl_ptr = NULL;
     	ip_dn_io_ptr = NULL;
     
    -	DUMMYNET_LOCK();
    -	callout_stop(&dn_timeout);
    -	DUMMYNET_UNLOCK();
    +	dummynet_flush();
    +	DN_BH_WUNLOCK();
     	taskqueue_drain(dn_tq, &dn_task);
     	taskqueue_free(dn_tq);
     
    -	dummynet_flush();
    +	dn_ht_free(dn_cfg.schedhash, 0);
    +	dn_ht_free(dn_cfg.fshash, 0);
    +	heap_free(&dn_cfg.evheap);
     
    -	DUMMYNET_LOCK_DESTROY();
    +	DN_LOCK_DESTROY();
     }
     #endif /* KLD_MODULE */
     
    @@ -2311,35 +2198,98 @@ static int
     dummynet_modevent(module_t mod, int type, void *data)
     {
     
    -	switch (type) {
    -	case MOD_LOAD:
    +	if (type == MOD_LOAD) {
     		if (ip_dn_io_ptr) {
    -		    printf("DUMMYNET already loaded\n");
    -		    return EEXIST ;
    +			printf("DUMMYNET already loaded\n");
    +			return EEXIST ;
     		}
     		ip_dn_init();
    -		break;
    -
    -	case MOD_UNLOAD:
    +		return 0;
    +	} else if (type == MOD_UNLOAD) {
     #if !defined(KLD_MODULE)
     		printf("dummynet statically compiled, cannot unload\n");
     		return EINVAL ;
     #else
     		ip_dn_destroy();
    +		return 0;
     #endif
    -		break ;
    -	default:
    +	} else
     		return EOPNOTSUPP;
    -		break ;
    +}
    +
    +/* modevent helpers for the modules */
    +static int
    +load_dn_sched(struct dn_alg *d)
    +{
    +	struct dn_alg *s;
    +
    +	if (d == NULL)
    +		return 1; /* error */
    +	ip_dn_init();	/* just in case, we need the lock */
    +
    +	/* Check that mandatory funcs exists */
    +	if (d->enqueue == NULL || d->dequeue == NULL) {
    +		D("missing enqueue or dequeue for %s", d->name);
    +		return 1;
     	}
    -	return 0 ;
    +
    +	/* Search if scheduler already exists */
    +	DN_BH_WLOCK();
    +	SLIST_FOREACH(s, &dn_cfg.schedlist, next) {
    +		if (strcmp(s->name, d->name) == 0) {
    +			D("%s already loaded", d->name);
    +			break; /* scheduler already exists */
    +		}
    +	}
    +	if (s == NULL)
    +		SLIST_INSERT_HEAD(&dn_cfg.schedlist, d, next);
    +	DN_BH_WUNLOCK();
    +	D("dn_sched %s %sloaded", d->name, s ? "not ":"");
    +	return s ? 1 : 0;
    +}
    +
    +static int
    +unload_dn_sched(struct dn_alg *s)
    +{
    +	struct dn_alg *tmp, *r;
    +	int err = EINVAL;
    +
    +	D("called for %s", s->name);
    +
    +	DN_BH_WLOCK();
    +	SLIST_FOREACH_SAFE(r, &dn_cfg.schedlist, next, tmp) {
    +		if (strcmp(s->name, r->name) != 0)
    +			continue;
    +		D("ref_count = %d", r->ref_count);
    +		err = (r->ref_count != 0) ? EBUSY : 0;
    +		if (err == 0)
    +			SLIST_REMOVE(&dn_cfg.schedlist, r, dn_alg, next);
    +		break;
    +	}
    +	DN_BH_WUNLOCK();
    +	D("dn_sched %s %sunloaded", s->name, err ? "not ":"");
    +	return err;
    +}
    +
    +int
    +dn_sched_modevent(module_t mod, int cmd, void *arg)
    +{
    +	struct dn_alg *sch = arg;
    +
    +	if (cmd == MOD_LOAD)
    +		return load_dn_sched(sch);
    +	else if (cmd == MOD_UNLOAD)
    +		return unload_dn_sched(sch);
    +	else
    +		return EINVAL;
     }
     
     static moduledata_t dummynet_mod = {
    -	"dummynet",
    -	dummynet_modevent,
    -	NULL
    +	"dummynet", dummynet_modevent, NULL
     };
    -DECLARE_MODULE(dummynet, dummynet_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
    +
    +DECLARE_MODULE(dummynet, dummynet_mod,
    +	SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY-1);
     MODULE_DEPEND(dummynet, ipfw, 2, 2, 2);
     MODULE_VERSION(dummynet, 1);
    +/* end of file */
    diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c
    index 1ccbf2bcb78..959ad8e3ad9 100644
    --- a/sys/netinet/ipfw/ip_fw2.c
    +++ b/sys/netinet/ipfw/ip_fw2.c
    @@ -1,5 +1,5 @@
     /*-
    - * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa
    + * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
      *
      * Redistribution and use in source and binary forms, with or without
      * modification, are permitted provided that the following conditions
    @@ -26,11 +26,8 @@
     #include 
     __FBSDID("$FreeBSD$");
     
    -#define        DEB(x)
    -#define        DDB(x) x
    -
     /*
    - * Implement IP packet firewall (new version)
    + * The FreeBSD IP packet firewall, main file
      */
     
     #if !defined(KLD_MODULE)
    @@ -65,13 +62,10 @@ __FBSDID("$FreeBSD$");
     #include 
     #include  /* for ETHERTYPE_IP */
     #include 
    -#include 
     #include 
     #include 
     #include 
     
    -#define	IPFW_INTERNAL	/* Access to protected data structures in ip_fw.h. */
    -
     #include 
     #include 
     #include 
    @@ -79,8 +73,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    -#include 
    -#include 
    +#include 
     #include 
     #include 
     #include 
    @@ -88,8 +81,6 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#include 
    -
     #include 
     #include 
     #ifdef INET6
    @@ -103,73 +94,66 @@ __FBSDID("$FreeBSD$");
     #include 
     #endif
     
    +/*
    + * static variables followed by global ones.
    + * All ipfw global variables are here.
    + */
    +
    +/* ipfw_vnet_ready controls when we are open for business */
     static VNET_DEFINE(int, ipfw_vnet_ready) = 0;
     #define	V_ipfw_vnet_ready	VNET(ipfw_vnet_ready)
    -/*
    - * set_disable contains one bit per set value (0..31).
    - * If the bit is set, all rules with the corresponding set
    - * are disabled. Set RESVD_SET(31) is reserved for the default rule
    - * and rules that are not deleted by the flush command,
    - * and CANNOT be disabled.
    - * Rules in set RESVD_SET can only be deleted explicitly.
    - */
    -static VNET_DEFINE(u_int32_t, set_disable);
    -static VNET_DEFINE(int, fw_verbose);
    -static VNET_DEFINE(struct callout, ipfw_timeout);
    -static VNET_DEFINE(int, verbose_limit);
     
    -#define	V_set_disable			VNET(set_disable)
    -#define	V_fw_verbose			VNET(fw_verbose)
    -#define	V_ipfw_timeout			VNET(ipfw_timeout)
    -#define	V_verbose_limit			VNET(verbose_limit)
    +static VNET_DEFINE(int, fw_deny_unknown_exthdrs);
    +#define	V_fw_deny_unknown_exthdrs	VNET(fw_deny_unknown_exthdrs)
     
     #ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
     static int default_to_accept = 1;
     #else
     static int default_to_accept;
     #endif
    -static uma_zone_t ipfw_dyn_rule_zone;
     
    -struct ip_fw *ip_fw_default_rule;
    +VNET_DEFINE(int, autoinc_step);
     
     /*
    - * list of rules for layer 3
    + * Each rule belongs to one of 32 different sets (0..31).
    + * The variable set_disable contains one bit per set.
    + * If the bit is set, all rules in the corresponding set
    + * are disabled. Set RESVD_SET(31) is reserved for the default rule
    + * and rules that are not deleted by the flush command,
    + * and CANNOT be disabled.
    + * Rules in set RESVD_SET can only be deleted individually.
      */
    +VNET_DEFINE(u_int32_t, set_disable);
    +#define	V_set_disable			VNET(set_disable)
    +
    +VNET_DEFINE(int, fw_verbose);
    +/* counter for ipfw_log(NULL...) */
    +VNET_DEFINE(u_int64_t, norule_counter);
    +VNET_DEFINE(int, verbose_limit);
    +
    +/* layer3_chain contains the list of rules for layer 3 */
     VNET_DEFINE(struct ip_fw_chain, layer3_chain);
     
    -MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
    -MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables");
    -#define IPFW_NAT_LOADED (ipfw_nat_ptr != NULL)
     ipfw_nat_t *ipfw_nat_ptr = NULL;
    +struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
     ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
     ipfw_nat_cfg_t *ipfw_nat_del_ptr;
     ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
     ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
     
    -struct table_entry {
    -	struct radix_node	rn[2];
    -	struct sockaddr_in	addr, mask;
    -	u_int32_t		value;
    -};
    -
    -static VNET_DEFINE(int, autoinc_step);
    -#define	V_autoinc_step			VNET(autoinc_step)
    -static VNET_DEFINE(int, fw_deny_unknown_exthdrs);
    -#define	V_fw_deny_unknown_exthdrs	VNET(fw_deny_unknown_exthdrs)
    -
    -extern int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
    -
     #ifdef SYSCTL_NODE
    +uint32_t dummy_def = IPFW_DEFAULT_RULE;
    +uint32_t dummy_tables_max = IPFW_TABLES_MAX;
    +
    +SYSBEGIN(f3)
    +
     SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
    -SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AUTO, enable,
    -    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_enable), 0,
    -    ipfw_chg_hook, "I", "Enable ipfw");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step,
    -    CTLFLAG_RW, &VNET_NAME(autoinc_step), 0,
    -    "Rule number auto-increment step");
     SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
         CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
         "Only do a single pass through ipfw when using dummynet(4)");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step,
    +    CTLFLAG_RW, &VNET_NAME(autoinc_step), 0,
    +    "Rule number auto-increment step");
     SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose,
         CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_verbose), 0,
         "Log matches to ipfw rules");
    @@ -177,168 +161,34 @@ SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit,
         CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
         "Set upper limit of matches of ipfw rules logged");
     SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
    -    NULL, IPFW_DEFAULT_RULE,
    +    &dummy_def, 0,
         "The default/max possible rule number.");
     SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD,
    -    NULL, IPFW_TABLES_MAX,
    +    &dummy_tables_max, 0,
         "The maximum number of tables.");
     SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN,
         &default_to_accept, 0,
         "Make the default rule accept all packets.");
     TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept);
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count,
    +    CTLFLAG_RD, &VNET_NAME(layer3_chain.n_rules), 0,
    +    "Number of static rules");
     
     #ifdef INET6
     SYSCTL_DECL(_net_inet6_ip6);
     SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
    -SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_AUTO, enable,
    -    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw6_enable), 0,
    -    ipfw_chg_hook, "I", "Enable ipfw+6");
     SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
         CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_deny_unknown_exthdrs), 0,
         "Deny packets with unknown IPv6 Extension Headers");
     #endif /* INET6 */
     
    +SYSEND
    +
     #endif /* SYSCTL_NODE */
     
    -/*
    - * Description of dynamic rules.
    - *
    - * Dynamic rules are stored in lists accessed through a hash table
    - * (ipfw_dyn_v) whose size is curr_dyn_buckets. This value can
    - * be modified through the sysctl variable dyn_buckets which is
    - * updated when the table becomes empty.
    - *
    - * XXX currently there is only one list, ipfw_dyn.
    - *
    - * When a packet is received, its address fields are first masked
    - * with the mask defined for the rule, then hashed, then matched
    - * against the entries in the corresponding list.
    - * Dynamic rules can be used for different purposes:
    - *  + stateful rules;
    - *  + enforcing limits on the number of sessions;
    - *  + in-kernel NAT (not implemented yet)
    - *
    - * The lifetime of dynamic rules is regulated by dyn_*_lifetime,
    - * measured in seconds and depending on the flags.
    - *
    - * The total number of dynamic rules is stored in dyn_count.
    - * The max number of dynamic rules is dyn_max. When we reach
    - * the maximum number of rules we do not create anymore. This is
    - * done to avoid consuming too much memory, but also too much
    - * time when searching on each packet (ideally, we should try instead
    - * to put a limit on the length of the list on each bucket...).
    - *
    - * Each dynamic rule holds a pointer to the parent ipfw rule so
    - * we know what action to perform. Dynamic rules are removed when
    - * the parent rule is deleted. XXX we should make them survive.
    - *
    - * There are some limitations with dynamic rules -- we do not
    - * obey the 'randomized match', and we do not do multiple
    - * passes through the firewall. XXX check the latter!!!
    - */
    -static VNET_DEFINE(ipfw_dyn_rule **, ipfw_dyn_v);
    -static VNET_DEFINE(u_int32_t, dyn_buckets);
    -static VNET_DEFINE(u_int32_t, curr_dyn_buckets);
    -
    -#define	V_ipfw_dyn_v			VNET(ipfw_dyn_v)
    -#define	V_dyn_buckets			VNET(dyn_buckets)
    -#define	V_curr_dyn_buckets		VNET(curr_dyn_buckets)
    -
    -static struct mtx ipfw_dyn_mtx;		/* mutex guarding dynamic rules */
    -#define	IPFW_DYN_LOCK_INIT() \
    -	mtx_init(&ipfw_dyn_mtx, "IPFW dynamic rules", NULL, MTX_DEF)
    -#define	IPFW_DYN_LOCK_DESTROY()	mtx_destroy(&ipfw_dyn_mtx)
    -#define	IPFW_DYN_LOCK()		mtx_lock(&ipfw_dyn_mtx)
    -#define	IPFW_DYN_UNLOCK()	mtx_unlock(&ipfw_dyn_mtx)
    -#define	IPFW_DYN_LOCK_ASSERT()	mtx_assert(&ipfw_dyn_mtx, MA_OWNED)
    -
    -static struct mbuf *send_pkt(struct mbuf *, struct ipfw_flow_id *,
    -    u_int32_t, u_int32_t, int);
    -
    -
    -/*
    - * Timeouts for various events in handing dynamic rules.
    - */
    -static VNET_DEFINE(u_int32_t, dyn_ack_lifetime);
    -static VNET_DEFINE(u_int32_t, dyn_syn_lifetime);
    -static VNET_DEFINE(u_int32_t, dyn_fin_lifetime);
    -static VNET_DEFINE(u_int32_t, dyn_rst_lifetime);
    -static VNET_DEFINE(u_int32_t, dyn_udp_lifetime);
    -static VNET_DEFINE(u_int32_t, dyn_short_lifetime);
    -
    -#define	V_dyn_ack_lifetime		VNET(dyn_ack_lifetime)
    -#define	V_dyn_syn_lifetime		VNET(dyn_syn_lifetime)
    -#define	V_dyn_fin_lifetime		VNET(dyn_fin_lifetime)
    -#define	V_dyn_rst_lifetime		VNET(dyn_rst_lifetime)
    -#define	V_dyn_udp_lifetime		VNET(dyn_udp_lifetime)
    -#define	V_dyn_short_lifetime		VNET(dyn_short_lifetime)
    -
    -/*
    - * Keepalives are sent if dyn_keepalive is set. They are sent every
    - * dyn_keepalive_period seconds, in the last dyn_keepalive_interval
    - * seconds of lifetime of a rule.
    - * dyn_rst_lifetime and dyn_fin_lifetime should be strictly lower
    - * than dyn_keepalive_period.
    - */
    -
    -static VNET_DEFINE(u_int32_t, dyn_keepalive_interval);
    -static VNET_DEFINE(u_int32_t, dyn_keepalive_period);
    -static VNET_DEFINE(u_int32_t, dyn_keepalive);
    -
    -#define	V_dyn_keepalive_interval	VNET(dyn_keepalive_interval)
    -#define	V_dyn_keepalive_period		VNET(dyn_keepalive_period)
    -#define	V_dyn_keepalive			VNET(dyn_keepalive)
    -
    -static VNET_DEFINE(u_int32_t, static_count);	/* # of static rules */
    -static VNET_DEFINE(u_int32_t, static_len);	/* bytes of static rules */
    -static VNET_DEFINE(u_int32_t, dyn_count);	/* # of dynamic rules */
    -static VNET_DEFINE(u_int32_t, dyn_max);		/* max # of dynamic rules */
    -
    -#define	V_static_count			VNET(static_count)
    -#define	V_static_len			VNET(static_len)
    -#define	V_dyn_count			VNET(dyn_count)
    -#define	V_dyn_max			VNET(dyn_max)
    -
    -#ifdef SYSCTL_NODE
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets,
    -    CTLFLAG_RW, &VNET_NAME(dyn_buckets), 0,
    -    "Number of dyn. buckets");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets,
    -    CTLFLAG_RD, &VNET_NAME(curr_dyn_buckets), 0,
    -    "Current Number of dyn. buckets");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_count,
    -    CTLFLAG_RD, &VNET_NAME(dyn_count), 0,
    -    "Number of dyn. rules");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_max,
    -    CTLFLAG_RW, &VNET_NAME(dyn_max), 0,
    -    "Max number of dyn. rules");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count,
    -    CTLFLAG_RD, &VNET_NAME(static_count), 0,
    -    "Number of static rules");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime,
    -    CTLFLAG_RW, &VNET_NAME(dyn_ack_lifetime), 0,
    -    "Lifetime of dyn. rules for acks");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime,
    -    CTLFLAG_RW, &VNET_NAME(dyn_syn_lifetime), 0,
    -    "Lifetime of dyn. rules for syn");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime,
    -    CTLFLAG_RW, &VNET_NAME(dyn_fin_lifetime), 0,
    -    "Lifetime of dyn. rules for fin");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime,
    -    CTLFLAG_RW, &VNET_NAME(dyn_rst_lifetime), 0,
    -    "Lifetime of dyn. rules for rst");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime,
    -    CTLFLAG_RW, &VNET_NAME(dyn_udp_lifetime), 0,
    -    "Lifetime of dyn. rules for UDP");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime,
    -    CTLFLAG_RW, &VNET_NAME(dyn_short_lifetime), 0,
    -    "Lifetime of dyn. rules for other situations");
    -SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive,
    -    CTLFLAG_RW, &VNET_NAME(dyn_keepalive), 0,
    -    "Enable keepalives for dyn. rules");
    -#endif /* SYSCTL_NODE */
     
     /*
    + * Some macros used in the various matching options.
      * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
      * Other macros just cast void * into the appropriate type
      */
    @@ -501,6 +351,7 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
     				return(1);
     		}
     	} else {
    +#ifdef	__FreeBSD__	/* and OSX too ? */
     		struct ifaddr *ia;
     
     		if_addr_rlock(ifp);
    @@ -514,6 +365,7 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
     			}
     		}
     		if_addr_runlock(ifp);
    +#endif /* __FreeBSD__ */
     	}
     	return(0);	/* no match, fail ... */
     }
    @@ -524,23 +376,27 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
      * 
      * The 'verrevpath' option checks that the interface that an IP packet
      * arrives on is the same interface that traffic destined for the
    - * packet's source address would be routed out of.  The 'versrcreach'
    - * option just checks that the source address is reachable via any route
    - * (except default) in the routing table.  These two are a measure to block
    - * forged packets.  This is also commonly known as "anti-spoofing" or Unicast
    - * Reverse Path Forwarding (Unicast RFP) in Cisco-ese. The name of the knobs
    + * packet's source address would be routed out of.
    + * The 'versrcreach' option just checks that the source address is
    + * reachable via any route (except default) in the routing table.
    + * These two are a measure to block forged packets. This is also
    + * commonly known as "anti-spoofing" or Unicast Reverse Path
    + * Forwarding (Unicast RFP) in Cisco-ese. The name of the knobs
      * is purposely reminiscent of the Cisco IOS command,
      *
      *   ip verify unicast reverse-path
      *   ip verify unicast source reachable-via any
      *
    - * which implements the same functionality. But note that syntax is
    - * misleading. The check may be performed on all IP packets whether unicast,
    - * multicast, or broadcast.
    + * which implements the same functionality. But note that the syntax
    + * is misleading, and the check may be performed on all IP packets
    + * whether unicast, multicast, or broadcast.
      */
     static int
     verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
     {
    +#ifndef __FreeBSD__
    +	return 0;
    +#else
     	struct route ro;
     	struct sockaddr_in *dst;
     
    @@ -583,6 +439,7 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
     	/* found valid route */
     	RTFREE(ro.ro_rt);
     	return 1;
    +#endif /* __FreeBSD__ */
     }
     
     #ifdef INET6
    @@ -681,17 +538,6 @@ verify_path6(struct in6_addr *src, struct ifnet *ifp)
     	return 1;
     
     }
    -static __inline int
    -hash_packet6(struct ipfw_flow_id *id)
    -{
    -	u_int32_t i;
    -	i = (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
    -	    (id->dst_ip6.__u6_addr.__u6_addr32[3]) ^
    -	    (id->src_ip6.__u6_addr.__u6_addr32[2]) ^
    -	    (id->src_ip6.__u6_addr.__u6_addr32[3]) ^
    -	    (id->dst_port) ^ (id->src_port);
    -	return i;
    -}
     
     static int
     is_icmp6_query(int icmp6_type)
    @@ -719,14 +565,14 @@ send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr *ip6)
     
     		if ((tcp->th_flags & TH_RST) == 0) {
     			struct mbuf *m0;
    -			m0 = send_pkt(args->m, &(args->f_id),
    +			m0 = ipfw_send_pkt(args->m, &(args->f_id),
     			    ntohl(tcp->th_seq), ntohl(tcp->th_ack),
     			    tcp->th_flags | TH_RST);
     			if (m0 != NULL)
     				ip6_output(m0, NULL, NULL, 0, NULL, NULL,
     				    NULL);
     		}
    -		m_freem(m);
    +		FREE_PKT(m);
     	} else if (code != ICMP6_UNREACH_RST) { /* Send an ICMPv6 unreach. */
     #if 0
     		/*
    @@ -742,1085 +588,19 @@ send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr *ip6)
     #endif
     		icmp6_error(m, ICMP6_DST_UNREACH, code, 0);
     	} else
    -		m_freem(m);
    +		FREE_PKT(m);
     
     	args->m = NULL;
     }
     
     #endif /* INET6 */
     
    -/* counter for ipfw_log(NULL...) */
    -static VNET_DEFINE(u_int64_t, norule_counter);
    -#define	V_norule_counter		VNET(norule_counter)
    -
    -#define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
    -#define SNP(buf) buf, sizeof(buf)
    -
    -/*
    - * We enter here when we have a rule with O_LOG.
    - * XXX this function alone takes about 2Kbytes of code!
    - */
    -static void
    -ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
    -    struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
    -    struct ip *ip)
    -{
    -	struct ether_header *eh = args->eh;
    -	char *action;
    -	int limit_reached = 0;
    -	char action2[40], proto[128], fragment[32];
    -
    -	fragment[0] = '\0';
    -	proto[0] = '\0';
    -
    -	if (f == NULL) {	/* bogus pkt */
    -		if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit)
    -			return;
    -		V_norule_counter++;
    -		if (V_norule_counter == V_verbose_limit)
    -			limit_reached = V_verbose_limit;
    -		action = "Refuse";
    -	} else {	/* O_LOG is the first action, find the real one */
    -		ipfw_insn *cmd = ACTION_PTR(f);
    -		ipfw_insn_log *l = (ipfw_insn_log *)cmd;
    -
    -		if (l->max_log != 0 && l->log_left == 0)
    -			return;
    -		l->log_left--;
    -		if (l->log_left == 0)
    -			limit_reached = l->max_log;
    -		cmd += F_LEN(cmd);	/* point to first action */
    -		if (cmd->opcode == O_ALTQ) {
    -			ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
    -
    -			snprintf(SNPARGS(action2, 0), "Altq %d",
    -				altq->qid);
    -			cmd += F_LEN(cmd);
    -		}
    -		if (cmd->opcode == O_PROB)
    -			cmd += F_LEN(cmd);
    -
    -		if (cmd->opcode == O_TAG)
    -			cmd += F_LEN(cmd);
    -
    -		action = action2;
    -		switch (cmd->opcode) {
    -		case O_DENY:
    -			action = "Deny";
    -			break;
    -
    -		case O_REJECT:
    -			if (cmd->arg1==ICMP_REJECT_RST)
    -				action = "Reset";
    -			else if (cmd->arg1==ICMP_UNREACH_HOST)
    -				action = "Reject";
    -			else
    -				snprintf(SNPARGS(action2, 0), "Unreach %d",
    -					cmd->arg1);
    -			break;
    -
    -		case O_UNREACH6:
    -			if (cmd->arg1==ICMP6_UNREACH_RST)
    -				action = "Reset";
    -			else
    -				snprintf(SNPARGS(action2, 0), "Unreach %d",
    -					cmd->arg1);
    -			break;
    -
    -		case O_ACCEPT:
    -			action = "Accept";
    -			break;
    -		case O_COUNT:
    -			action = "Count";
    -			break;
    -		case O_DIVERT:
    -			snprintf(SNPARGS(action2, 0), "Divert %d",
    -				cmd->arg1);
    -			break;
    -		case O_TEE:
    -			snprintf(SNPARGS(action2, 0), "Tee %d",
    -				cmd->arg1);
    -			break;
    -		case O_SETFIB:
    -			snprintf(SNPARGS(action2, 0), "SetFib %d",
    -				cmd->arg1);
    -			break;
    -		case O_SKIPTO:
    -			snprintf(SNPARGS(action2, 0), "SkipTo %d",
    -				cmd->arg1);
    -			break;
    -		case O_PIPE:
    -			snprintf(SNPARGS(action2, 0), "Pipe %d",
    -				cmd->arg1);
    -			break;
    -		case O_QUEUE:
    -			snprintf(SNPARGS(action2, 0), "Queue %d",
    -				cmd->arg1);
    -			break;
    -		case O_FORWARD_IP: {
    -			ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
    -			int len;
    -			struct in_addr dummyaddr;
    -			if (sa->sa.sin_addr.s_addr == INADDR_ANY)
    -				dummyaddr.s_addr = htonl(tablearg);
    -			else
    -				dummyaddr.s_addr = sa->sa.sin_addr.s_addr;
    -
    -			len = snprintf(SNPARGS(action2, 0), "Forward to %s",
    -				inet_ntoa(dummyaddr));
    -
    -			if (sa->sa.sin_port)
    -				snprintf(SNPARGS(action2, len), ":%d",
    -				    sa->sa.sin_port);
    -			}
    -			break;
    -		case O_NETGRAPH:
    -			snprintf(SNPARGS(action2, 0), "Netgraph %d",
    -				cmd->arg1);
    -			break;
    -		case O_NGTEE:
    -			snprintf(SNPARGS(action2, 0), "Ngtee %d",
    -				cmd->arg1);
    -			break;
    -		case O_NAT:
    -			action = "Nat";
    - 			break;
    -		case O_REASS:
    -			action = "Reass";
    -			break;
    -		default:
    -			action = "UNKNOWN";
    -			break;
    -		}
    -	}
    -
    -	if (hlen == 0) {	/* non-ip */
    -		snprintf(SNPARGS(proto, 0), "MAC");
    -
    -	} else {
    -		int len;
    -#ifdef INET6
    -		char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
    -#else
    -		char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
    -#endif
    -		struct icmphdr *icmp;
    -		struct tcphdr *tcp;
    -		struct udphdr *udp;
    -#ifdef INET6
    -		struct ip6_hdr *ip6 = NULL;
    -		struct icmp6_hdr *icmp6;
    -#endif
    -		src[0] = '\0';
    -		dst[0] = '\0';
    -#ifdef INET6
    -		if (IS_IP6_FLOW_ID(&(args->f_id))) {
    -			char ip6buf[INET6_ADDRSTRLEN];
    -			snprintf(src, sizeof(src), "[%s]",
    -			    ip6_sprintf(ip6buf, &args->f_id.src_ip6));
    -			snprintf(dst, sizeof(dst), "[%s]",
    -			    ip6_sprintf(ip6buf, &args->f_id.dst_ip6));
    -
    -			ip6 = (struct ip6_hdr *)ip;
    -			tcp = (struct tcphdr *)(((char *)ip) + hlen);
    -			udp = (struct udphdr *)(((char *)ip) + hlen);
    -		} else
    -#endif
    -		{
    -			tcp = L3HDR(struct tcphdr, ip);
    -			udp = L3HDR(struct udphdr, ip);
    -
    -			inet_ntoa_r(ip->ip_src, src);
    -			inet_ntoa_r(ip->ip_dst, dst);
    -		}
    -
    -		switch (args->f_id.proto) {
    -		case IPPROTO_TCP:
    -			len = snprintf(SNPARGS(proto, 0), "TCP %s", src);
    -			if (offset == 0)
    -				snprintf(SNPARGS(proto, len), ":%d %s:%d",
    -				    ntohs(tcp->th_sport),
    -				    dst,
    -				    ntohs(tcp->th_dport));
    -			else
    -				snprintf(SNPARGS(proto, len), " %s", dst);
    -			break;
    -
    -		case IPPROTO_UDP:
    -			len = snprintf(SNPARGS(proto, 0), "UDP %s", src);
    -			if (offset == 0)
    -				snprintf(SNPARGS(proto, len), ":%d %s:%d",
    -				    ntohs(udp->uh_sport),
    -				    dst,
    -				    ntohs(udp->uh_dport));
    -			else
    -				snprintf(SNPARGS(proto, len), " %s", dst);
    -			break;
    -
    -		case IPPROTO_ICMP:
    -			icmp = L3HDR(struct icmphdr, ip);
    -			if (offset == 0)
    -				len = snprintf(SNPARGS(proto, 0),
    -				    "ICMP:%u.%u ",
    -				    icmp->icmp_type, icmp->icmp_code);
    -			else
    -				len = snprintf(SNPARGS(proto, 0), "ICMP ");
    -			len += snprintf(SNPARGS(proto, len), "%s", src);
    -			snprintf(SNPARGS(proto, len), " %s", dst);
    -			break;
    -#ifdef INET6
    -		case IPPROTO_ICMPV6:
    -			icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen);
    -			if (offset == 0)
    -				len = snprintf(SNPARGS(proto, 0),
    -				    "ICMPv6:%u.%u ",
    -				    icmp6->icmp6_type, icmp6->icmp6_code);
    -			else
    -				len = snprintf(SNPARGS(proto, 0), "ICMPv6 ");
    -			len += snprintf(SNPARGS(proto, len), "%s", src);
    -			snprintf(SNPARGS(proto, len), " %s", dst);
    -			break;
    -#endif
    -		default:
    -			len = snprintf(SNPARGS(proto, 0), "P:%d %s",
    -			    args->f_id.proto, src);
    -			snprintf(SNPARGS(proto, len), " %s", dst);
    -			break;
    -		}
    -
    -#ifdef INET6
    -		if (IS_IP6_FLOW_ID(&(args->f_id))) {
    -			if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG))
    -				snprintf(SNPARGS(fragment, 0),
    -				    " (frag %08x:%d@%d%s)",
    -				    args->f_id.frag_id6,
    -				    ntohs(ip6->ip6_plen) - hlen,
    -				    ntohs(offset & IP6F_OFF_MASK) << 3,
    -				    (offset & IP6F_MORE_FRAG) ? "+" : "");
    -		} else
    -#endif
    -		{
    -			int ip_off, ip_len;
    -			if (eh != NULL) { /* layer 2 packets are as on the wire */
    -				ip_off = ntohs(ip->ip_off);
    -				ip_len = ntohs(ip->ip_len);
    -			} else {
    -				ip_off = ip->ip_off;
    -				ip_len = ip->ip_len;
    -			}
    -			if (ip_off & (IP_MF | IP_OFFMASK))
    -				snprintf(SNPARGS(fragment, 0),
    -				    " (frag %d:%d@%d%s)",
    -				    ntohs(ip->ip_id), ip_len - (ip->ip_hl << 2),
    -				    offset << 3,
    -				    (ip_off & IP_MF) ? "+" : "");
    -		}
    -	}
    -	if (oif || m->m_pkthdr.rcvif)
    -		log(LOG_SECURITY | LOG_INFO,
    -		    "ipfw: %d %s %s %s via %s%s\n",
    -		    f ? f->rulenum : -1,
    -		    action, proto, oif ? "out" : "in",
    -		    oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname,
    -		    fragment);
    -	else
    -		log(LOG_SECURITY | LOG_INFO,
    -		    "ipfw: %d %s %s [no if info]%s\n",
    -		    f ? f->rulenum : -1,
    -		    action, proto, fragment);
    -	if (limit_reached)
    -		log(LOG_SECURITY | LOG_NOTICE,
    -		    "ipfw: limit %d reached on entry %d\n",
    -		    limit_reached, f ? f->rulenum : -1);
    -}
    -
    -/*
    - * IMPORTANT: the hash function for dynamic rules must be commutative
    - * in source and destination (ip,port), because rules are bidirectional
    - * and we want to find both in the same bucket.
    - */
    -static __inline int
    -hash_packet(struct ipfw_flow_id *id)
    -{
    -	u_int32_t i;
    -
    -#ifdef INET6
    -	if (IS_IP6_FLOW_ID(id)) 
    -		i = hash_packet6(id);
    -	else
    -#endif /* INET6 */
    -	i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
    -	i &= (V_curr_dyn_buckets - 1);
    -	return i;
    -}
    -
    -static __inline void
    -unlink_dyn_rule_print(struct ipfw_flow_id *id)
    -{
    -	struct in_addr da;
    -#ifdef INET6
    -	char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
    -#else
    -	char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
    -#endif
    -
    -#ifdef INET6
    -	if (IS_IP6_FLOW_ID(id)) {
    -		ip6_sprintf(src, &id->src_ip6);
    -		ip6_sprintf(dst, &id->dst_ip6);
    -	} else
    -#endif
    -	{
    -		da.s_addr = htonl(id->src_ip);
    -		inet_ntoa_r(da, src);
    -		da.s_addr = htonl(id->dst_ip);
    -		inet_ntoa_r(da, dst);
    -	}
    -	printf("ipfw: unlink entry %s %d -> %s %d, %d left\n",
    -	    src, id->src_port, dst, id->dst_port, V_dyn_count - 1);
    -}
    -
    -/**
    - * unlink a dynamic rule from a chain. prev is a pointer to
    - * the previous one, q is a pointer to the rule to delete,
    - * head is a pointer to the head of the queue.
    - * Modifies q and potentially also head.
    - */
    -#define UNLINK_DYN_RULE(prev, head, q) {				\
    -	ipfw_dyn_rule *old_q = q;					\
    -									\
    -	/* remove a refcount to the parent */				\
    -	if (q->dyn_type == O_LIMIT)					\
    -		q->parent->count--;					\
    -	DEB(unlink_dyn_rule_print(&q->id);)				\
    -	if (prev != NULL)						\
    -		prev->next = q = q->next;				\
    -	else								\
    -		head = q = q->next;					\
    -	V_dyn_count--;							\
    -	uma_zfree(ipfw_dyn_rule_zone, old_q); }
    -
    -#define TIME_LEQ(a,b)       ((int)((a)-(b)) <= 0)
    -
    -/**
    - * Remove dynamic rules pointing to "rule", or all of them if rule == NULL.
    - *
    - * If keep_me == NULL, rules are deleted even if not expired,
    - * otherwise only expired rules are removed.
    - *
    - * The value of the second parameter is also used to point to identify
    - * a rule we absolutely do not want to remove (e.g. because we are
    - * holding a reference to it -- this is the case with O_LIMIT_PARENT
    - * rules). The pointer is only used for comparison, so any non-null
    - * value will do.
    - */
    -static void
    -remove_dyn_rule(struct ip_fw *rule, ipfw_dyn_rule *keep_me)
    -{
    -	static u_int32_t last_remove = 0;
    -
    -#define FORCE (keep_me == NULL)
    -
    -	ipfw_dyn_rule *prev, *q;
    -	int i, pass = 0, max_pass = 0;
    -
    -	IPFW_DYN_LOCK_ASSERT();
    -
    -	if (V_ipfw_dyn_v == NULL || V_dyn_count == 0)
    -		return;
    -	/* do not expire more than once per second, it is useless */
    -	if (!FORCE && last_remove == time_uptime)
    -		return;
    -	last_remove = time_uptime;
    -
    -	/*
    -	 * because O_LIMIT refer to parent rules, during the first pass only
    -	 * remove child and mark any pending LIMIT_PARENT, and remove
    -	 * them in a second pass.
    -	 */
    -next_pass:
    -	for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
    -		for (prev=NULL, q = V_ipfw_dyn_v[i] ; q ; ) {
    -			/*
    -			 * Logic can become complex here, so we split tests.
    -			 */
    -			if (q == keep_me)
    -				goto next;
    -			if (rule != NULL && rule != q->rule)
    -				goto next; /* not the one we are looking for */
    -			if (q->dyn_type == O_LIMIT_PARENT) {
    -				/*
    -				 * handle parent in the second pass,
    -				 * record we need one.
    -				 */
    -				max_pass = 1;
    -				if (pass == 0)
    -					goto next;
    -				if (FORCE && q->count != 0 ) {
    -					/* XXX should not happen! */
    -					printf("ipfw: OUCH! cannot remove rule,"
    -					     " count %d\n", q->count);
    -				}
    -			} else {
    -				if (!FORCE &&
    -				    !TIME_LEQ( q->expire, time_uptime ))
    -					goto next;
    -			}
    -             if (q->dyn_type != O_LIMIT_PARENT || !q->count) {
    -                     UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
    -                     continue;
    -             }
    -next:
    -			prev=q;
    -			q=q->next;
    -		}
    -	}
    -	if (pass++ < max_pass)
    -		goto next_pass;
    -}
    -
    -
    -/**
    - * lookup a dynamic rule.
    - */
    -static ipfw_dyn_rule *
    -lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int *match_direction,
    -    struct tcphdr *tcp)
    -{
    -	/*
    -	 * stateful ipfw extensions.
    -	 * Lookup into dynamic session queue
    -	 */
    -#define MATCH_REVERSE	0
    -#define MATCH_FORWARD	1
    -#define MATCH_NONE	2
    -#define MATCH_UNKNOWN	3
    -	int i, dir = MATCH_NONE;
    -	ipfw_dyn_rule *prev, *q=NULL;
    -
    -	IPFW_DYN_LOCK_ASSERT();
    -
    -	if (V_ipfw_dyn_v == NULL)
    -		goto done;	/* not found */
    -	i = hash_packet( pkt );
    -	for (prev=NULL, q = V_ipfw_dyn_v[i] ; q != NULL ; ) {
    -		if (q->dyn_type == O_LIMIT_PARENT && q->count)
    -			goto next;
    -		if (TIME_LEQ( q->expire, time_uptime)) { /* expire entry */
    -			UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
    -			continue;
    -		}
    -		if (pkt->proto == q->id.proto &&
    -		    q->dyn_type != O_LIMIT_PARENT) {
    -			if (IS_IP6_FLOW_ID(pkt)) {
    -			    if (IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
    -				&(q->id.src_ip6)) &&
    -			    IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
    -				&(q->id.dst_ip6)) &&
    -			    pkt->src_port == q->id.src_port &&
    -			    pkt->dst_port == q->id.dst_port ) {
    -				dir = MATCH_FORWARD;
    -				break;
    -			    }
    -			    if (IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
    -				    &(q->id.dst_ip6)) &&
    -				IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
    -				    &(q->id.src_ip6)) &&
    -				pkt->src_port == q->id.dst_port &&
    -				pkt->dst_port == q->id.src_port ) {
    -				    dir = MATCH_REVERSE;
    -				    break;
    -			    }
    -			} else {
    -			    if (pkt->src_ip == q->id.src_ip &&
    -				pkt->dst_ip == q->id.dst_ip &&
    -				pkt->src_port == q->id.src_port &&
    -				pkt->dst_port == q->id.dst_port ) {
    -				    dir = MATCH_FORWARD;
    -				    break;
    -			    }
    -			    if (pkt->src_ip == q->id.dst_ip &&
    -				pkt->dst_ip == q->id.src_ip &&
    -				pkt->src_port == q->id.dst_port &&
    -				pkt->dst_port == q->id.src_port ) {
    -				    dir = MATCH_REVERSE;
    -				    break;
    -			    }
    -			}
    -		}
    -next:
    -		prev = q;
    -		q = q->next;
    -	}
    -	if (q == NULL)
    -		goto done; /* q = NULL, not found */
    -
    -	if ( prev != NULL) { /* found and not in front */
    -		prev->next = q->next;
    -		q->next = V_ipfw_dyn_v[i];
    -		V_ipfw_dyn_v[i] = q;
    -	}
    -	if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
    -		u_char flags = pkt->flags & (TH_FIN|TH_SYN|TH_RST);
    -
    -#define BOTH_SYN	(TH_SYN | (TH_SYN << 8))
    -#define BOTH_FIN	(TH_FIN | (TH_FIN << 8))
    -		q->state |= (dir == MATCH_FORWARD ) ? flags : (flags << 8);
    -		switch (q->state) {
    -		case TH_SYN:				/* opening */
    -			q->expire = time_uptime + V_dyn_syn_lifetime;
    -			break;
    -
    -		case BOTH_SYN:			/* move to established */
    -		case BOTH_SYN | TH_FIN :	/* one side tries to close */
    -		case BOTH_SYN | (TH_FIN << 8) :
    - 			if (tcp) {
    -#define _SEQ_GE(a,b) ((int)(a) - (int)(b) >= 0)
    -			    u_int32_t ack = ntohl(tcp->th_ack);
    -			    if (dir == MATCH_FORWARD) {
    -				if (q->ack_fwd == 0 || _SEQ_GE(ack, q->ack_fwd))
    -				    q->ack_fwd = ack;
    -				else { /* ignore out-of-sequence */
    -				    break;
    -				}
    -			    } else {
    -				if (q->ack_rev == 0 || _SEQ_GE(ack, q->ack_rev))
    -				    q->ack_rev = ack;
    -				else { /* ignore out-of-sequence */
    -				    break;
    -				}
    -			    }
    -			}
    -			q->expire = time_uptime + V_dyn_ack_lifetime;
    -			break;
    -
    -		case BOTH_SYN | BOTH_FIN:	/* both sides closed */
    -			if (V_dyn_fin_lifetime >= V_dyn_keepalive_period)
    -				V_dyn_fin_lifetime = V_dyn_keepalive_period - 1;
    -			q->expire = time_uptime + V_dyn_fin_lifetime;
    -			break;
    -
    -		default:
    -#if 0
    -			/*
    -			 * reset or some invalid combination, but can also
    -			 * occur if we use keep-state the wrong way.
    -			 */
    -			if ( (q->state & ((TH_RST << 8)|TH_RST)) == 0)
    -				printf("invalid state: 0x%x\n", q->state);
    -#endif
    -			if (V_dyn_rst_lifetime >= V_dyn_keepalive_period)
    -				V_dyn_rst_lifetime = V_dyn_keepalive_period - 1;
    -			q->expire = time_uptime + V_dyn_rst_lifetime;
    -			break;
    -		}
    -	} else if (pkt->proto == IPPROTO_UDP) {
    -		q->expire = time_uptime + V_dyn_udp_lifetime;
    -	} else {
    -		/* other protocols */
    -		q->expire = time_uptime + V_dyn_short_lifetime;
    -	}
    -done:
    -	if (match_direction)
    -		*match_direction = dir;
    -	return q;
    -}
    -
    -static ipfw_dyn_rule *
    -lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction,
    -    struct tcphdr *tcp)
    -{
    -	ipfw_dyn_rule *q;
    -
    -	IPFW_DYN_LOCK();
    -	q = lookup_dyn_rule_locked(pkt, match_direction, tcp);
    -	if (q == NULL)
    -		IPFW_DYN_UNLOCK();
    -	/* NB: return table locked when q is not NULL */
    -	return q;
    -}
    -
    -static void
    -realloc_dynamic_table(void)
    -{
    -	IPFW_DYN_LOCK_ASSERT();
    -
    -	/*
    -	 * Try reallocation, make sure we have a power of 2 and do
    -	 * not allow more than 64k entries. In case of overflow,
    -	 * default to 1024.
    -	 */
    -
    -	if (V_dyn_buckets > 65536)
    -		V_dyn_buckets = 1024;
    -	if ((V_dyn_buckets & (V_dyn_buckets-1)) != 0) { /* not a power of 2 */
    -		V_dyn_buckets = V_curr_dyn_buckets; /* reset */
    -		return;
    -	}
    -	V_curr_dyn_buckets = V_dyn_buckets;
    -	if (V_ipfw_dyn_v != NULL)
    -		free(V_ipfw_dyn_v, M_IPFW);
    -	for (;;) {
    -		V_ipfw_dyn_v = malloc(V_curr_dyn_buckets * sizeof(ipfw_dyn_rule *),
    -		       M_IPFW, M_NOWAIT | M_ZERO);
    -		if (V_ipfw_dyn_v != NULL || V_curr_dyn_buckets <= 2)
    -			break;
    -		V_curr_dyn_buckets /= 2;
    -	}
    -}
    -
    -/**
    - * Install state of type 'type' for a dynamic session.
    - * The hash table contains two type of rules:
    - * - regular rules (O_KEEP_STATE)
    - * - rules for sessions with limited number of sess per user
    - *   (O_LIMIT). When they are created, the parent is
    - *   increased by 1, and decreased on delete. In this case,
    - *   the third parameter is the parent rule and not the chain.
    - * - "parent" rules for the above (O_LIMIT_PARENT).
    - */
    -static ipfw_dyn_rule *
    -add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
    -{
    -	ipfw_dyn_rule *r;
    -	int i;
    -
    -	IPFW_DYN_LOCK_ASSERT();
    -
    -	if (V_ipfw_dyn_v == NULL ||
    -	    (V_dyn_count == 0 && V_dyn_buckets != V_curr_dyn_buckets)) {
    -		realloc_dynamic_table();
    -		if (V_ipfw_dyn_v == NULL)
    -			return NULL; /* failed ! */
    -	}
    -	i = hash_packet(id);
    -
    -	r = uma_zalloc(ipfw_dyn_rule_zone, M_NOWAIT | M_ZERO);
    -	if (r == NULL) {
    -		printf ("ipfw: sorry cannot allocate state\n");
    -		return NULL;
    -	}
    -
    -	/* increase refcount on parent, and set pointer */
    -	if (dyn_type == O_LIMIT) {
    -		ipfw_dyn_rule *parent = (ipfw_dyn_rule *)rule;
    -		if ( parent->dyn_type != O_LIMIT_PARENT)
    -			panic("invalid parent");
    -		parent->count++;
    -		r->parent = parent;
    -		rule = parent->rule;
    -	}
    -
    -	r->id = *id;
    -	r->expire = time_uptime + V_dyn_syn_lifetime;
    -	r->rule = rule;
    -	r->dyn_type = dyn_type;
    -	r->pcnt = r->bcnt = 0;
    -	r->count = 0;
    -
    -	r->bucket = i;
    -	r->next = V_ipfw_dyn_v[i];
    -	V_ipfw_dyn_v[i] = r;
    -	V_dyn_count++;
    -	DEB({
    -		struct in_addr da;
    -#ifdef INET6
    -		char src[INET6_ADDRSTRLEN];
    -		char dst[INET6_ADDRSTRLEN];
    -#else
    -		char src[INET_ADDRSTRLEN];
    -		char dst[INET_ADDRSTRLEN];
    -#endif
    -
    -#ifdef INET6
    -		if (IS_IP6_FLOW_ID(&(r->id))) {
    -			ip6_sprintf(src, &r->id.src_ip6);
    -			ip6_sprintf(dst, &r->id.dst_ip6);
    -		} else
    -#endif
    -		{
    -			da.s_addr = htonl(r->id.src_ip);
    -			inet_ntoa_r(da, src);
    -			da.s_addr = htonl(r->id.dst_ip);
    -			inet_ntoa_r(da, dst);
    -		}
    -		printf("ipfw: add dyn entry ty %d %s %d -> %s %d, total %d\n",
    -		    dyn_type, src, r->id.src_port, dst, r->id.dst_port,
    -		    V_dyn_count);
    -	})
    -	return r;
    -}
    -
    -/**
    - * lookup dynamic parent rule using pkt and rule as search keys.
    - * If the lookup fails, then install one.
    - */
    -static ipfw_dyn_rule *
    -lookup_dyn_parent(struct ipfw_flow_id *pkt, struct ip_fw *rule)
    -{
    -	ipfw_dyn_rule *q;
    -	int i;
    -
    -	IPFW_DYN_LOCK_ASSERT();
    -
    -	if (V_ipfw_dyn_v) {
    -		int is_v6 = IS_IP6_FLOW_ID(pkt);
    -		i = hash_packet( pkt );
    -		for (q = V_ipfw_dyn_v[i] ; q != NULL ; q=q->next)
    -			if (q->dyn_type == O_LIMIT_PARENT &&
    -			    rule== q->rule &&
    -			    pkt->proto == q->id.proto &&
    -			    pkt->src_port == q->id.src_port &&
    -			    pkt->dst_port == q->id.dst_port &&
    -			    (
    -				(is_v6 &&
    -				 IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
    -					&(q->id.src_ip6)) &&
    -				 IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
    -					&(q->id.dst_ip6))) ||
    -				(!is_v6 &&
    -				 pkt->src_ip == q->id.src_ip &&
    -				 pkt->dst_ip == q->id.dst_ip)
    -			    )
    -			) {
    -				q->expire = time_uptime + V_dyn_short_lifetime;
    -				DEB(printf("ipfw: lookup_dyn_parent found 0x%p\n",q);)
    -				return q;
    -			}
    -	}
    -	return add_dyn_rule(pkt, O_LIMIT_PARENT, rule);
    -}
    -
    -/**
    - * Install dynamic state for rule type cmd->o.opcode
    - *
    - * Returns 1 (failure) if state is not installed because of errors or because
    - * session limitations are enforced.
    - */
    -static int
    -install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
    -    struct ip_fw_args *args, uint32_t tablearg)
    -{
    -	static int last_log;
    -	ipfw_dyn_rule *q;
    -	struct in_addr da;
    -#ifdef INET6
    -	char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
    -#else
    -	char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
    -#endif
    -
    -	src[0] = '\0';
    -	dst[0] = '\0';
    -
    -	IPFW_DYN_LOCK();
    -
    -	DEB(
    -#ifdef INET6
    -	if (IS_IP6_FLOW_ID(&(args->f_id))) {
    -		ip6_sprintf(src, &args->f_id.src_ip6);
    -		ip6_sprintf(dst, &args->f_id.dst_ip6);
    -	} else
    -#endif
    -	{
    -		da.s_addr = htonl(args->f_id.src_ip);
    -		inet_ntoa_r(da, src);
    -		da.s_addr = htonl(args->f_id.dst_ip);
    -		inet_ntoa_r(da, dst);
    -	}
    -	printf("ipfw: %s: type %d %s %u -> %s %u\n",
    -	    __func__, cmd->o.opcode, src, args->f_id.src_port,
    -	    dst, args->f_id.dst_port);
    -	src[0] = '\0';
    -	dst[0] = '\0';
    -	)
    -
    -	q = lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
    -
    -	if (q != NULL) {	/* should never occur */
    -		if (last_log != time_uptime) {
    -			last_log = time_uptime;
    -			printf("ipfw: %s: entry already present, done\n",
    -			    __func__);
    -		}
    -		IPFW_DYN_UNLOCK();
    -		return (0);
    -	}
    -
    -	if (V_dyn_count >= V_dyn_max)
    -		/* Run out of slots, try to remove any expired rule. */
    -		remove_dyn_rule(NULL, (ipfw_dyn_rule *)1);
    -
    -	if (V_dyn_count >= V_dyn_max) {
    -		if (last_log != time_uptime) {
    -			last_log = time_uptime;
    -			printf("ipfw: %s: Too many dynamic rules\n", __func__);
    -		}
    -		IPFW_DYN_UNLOCK();
    -		return (1);	/* cannot install, notify caller */
    -	}
    -
    -	switch (cmd->o.opcode) {
    -	case O_KEEP_STATE:	/* bidir rule */
    -		add_dyn_rule(&args->f_id, O_KEEP_STATE, rule);
    -		break;
    -
    -	case O_LIMIT: {		/* limit number of sessions */
    -		struct ipfw_flow_id id;
    -		ipfw_dyn_rule *parent;
    -		uint32_t conn_limit;
    -		uint16_t limit_mask = cmd->limit_mask;
    -
    -		conn_limit = (cmd->conn_limit == IP_FW_TABLEARG) ?
    -		    tablearg : cmd->conn_limit;
    -		  
    -		DEB(
    -		if (cmd->conn_limit == IP_FW_TABLEARG)
    -			printf("ipfw: %s: O_LIMIT rule, conn_limit: %u "
    -			    "(tablearg)\n", __func__, conn_limit);
    -		else
    -			printf("ipfw: %s: O_LIMIT rule, conn_limit: %u\n",
    -			    __func__, conn_limit);
    -		)
    -
    -		id.dst_ip = id.src_ip = id.dst_port = id.src_port = 0;
    -		id.proto = args->f_id.proto;
    -		id.addr_type = args->f_id.addr_type;
    -		id.fib = M_GETFIB(args->m);
    -
    -		if (IS_IP6_FLOW_ID (&(args->f_id))) {
    -			if (limit_mask & DYN_SRC_ADDR)
    -				id.src_ip6 = args->f_id.src_ip6;
    -			if (limit_mask & DYN_DST_ADDR)
    -				id.dst_ip6 = args->f_id.dst_ip6;
    -		} else {
    -			if (limit_mask & DYN_SRC_ADDR)
    -				id.src_ip = args->f_id.src_ip;
    -			if (limit_mask & DYN_DST_ADDR)
    -				id.dst_ip = args->f_id.dst_ip;
    -		}
    -		if (limit_mask & DYN_SRC_PORT)
    -			id.src_port = args->f_id.src_port;
    -		if (limit_mask & DYN_DST_PORT)
    -			id.dst_port = args->f_id.dst_port;
    -		if ((parent = lookup_dyn_parent(&id, rule)) == NULL) {
    -			printf("ipfw: %s: add parent failed\n", __func__);
    -			IPFW_DYN_UNLOCK();
    -			return (1);
    -		}
    -
    -		if (parent->count >= conn_limit) {
    -			/* See if we can remove some expired rule. */
    -			remove_dyn_rule(rule, parent);
    -			if (parent->count >= conn_limit) {
    -				if (V_fw_verbose && last_log != time_uptime) {
    -					last_log = time_uptime;
    -#ifdef INET6
    -					/*
    -					 * XXX IPv6 flows are not
    -					 * supported yet.
    -					 */
    -					if (IS_IP6_FLOW_ID(&(args->f_id))) {
    -						char ip6buf[INET6_ADDRSTRLEN];
    -						snprintf(src, sizeof(src),
    -						    "[%s]", ip6_sprintf(ip6buf,
    -							&args->f_id.src_ip6));
    -						snprintf(dst, sizeof(dst),
    -						    "[%s]", ip6_sprintf(ip6buf,
    -							&args->f_id.dst_ip6));
    -					} else
    -#endif
    -					{
    -						da.s_addr =
    -						    htonl(args->f_id.src_ip);
    -						inet_ntoa_r(da, src);
    -						da.s_addr =
    -						    htonl(args->f_id.dst_ip);
    -						inet_ntoa_r(da, dst);
    -					}
    -					log(LOG_SECURITY | LOG_DEBUG,
    -					    "ipfw: %d %s %s:%u -> %s:%u, %s\n",
    -					    parent->rule->rulenum,
    -					    "drop session",
    -					    src, (args->f_id.src_port),
    -					    dst, (args->f_id.dst_port),
    -					    "too many entries");
    -				}
    -				IPFW_DYN_UNLOCK();
    -				return (1);
    -			}
    -		}
    -		add_dyn_rule(&args->f_id, O_LIMIT, (struct ip_fw *)parent);
    -		break;
    -	}
    -	default:
    -		printf("ipfw: %s: unknown dynamic rule type %u\n",
    -		    __func__, cmd->o.opcode);
    -		IPFW_DYN_UNLOCK();
    -		return (1);
    -	}
    -
    -	/* XXX just set lifetime */
    -	lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
    -
    -	IPFW_DYN_UNLOCK();
    -	return (0);
    -}
    -
    -/*
    - * Generate a TCP packet, containing either a RST or a keepalive.
    - * When flags & TH_RST, we are sending a RST packet, because of a
    - * "reset" action matched the packet.
    - * Otherwise we are sending a keepalive, and flags & TH_
    - * The 'replyto' mbuf is the mbuf being replied to, if any, and is required
    - * so that MAC can label the reply appropriately.
    - */
    -static struct mbuf *
    -send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
    -    u_int32_t ack, int flags)
    -{
    -	struct mbuf *m;
    -	int len, dir;
    -	struct ip *h = NULL;		/* stupid compiler */
    -#ifdef INET6
    -	struct ip6_hdr *h6 = NULL;
    -#endif
    -	struct tcphdr *th = NULL;
    -
    -	MGETHDR(m, M_DONTWAIT, MT_DATA);
    -	if (m == NULL)
    -		return (NULL);
    -
    -	M_SETFIB(m, id->fib);
    -#ifdef MAC
    -	if (replyto != NULL)
    -		mac_netinet_firewall_reply(replyto, m);
    -	else
    -		mac_netinet_firewall_send(m);
    -#else
    -	(void)replyto;		/* don't warn about unused arg */
    -#endif
    -
    -	switch (id->addr_type) {
    -	case 4:
    -		len = sizeof(struct ip) + sizeof(struct tcphdr);
    -		break;
    -#ifdef INET6
    -	case 6:
    -		len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
    -		break;
    -#endif
    -	default:
    -		/* XXX: log me?!? */
    -		m_freem(m);
    -		return (NULL);
    -	}
    -	dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN);
    -
    -	m->m_data += max_linkhdr;
    -	m->m_flags |= M_SKIP_FIREWALL;
    -	m->m_pkthdr.len = m->m_len = len;
    -	m->m_pkthdr.rcvif = NULL;
    -	bzero(m->m_data, len);
    -
    -	switch (id->addr_type) {
    -	case 4:
    -		h = mtod(m, struct ip *);
    -
    -		/* prepare for checksum */
    -		h->ip_p = IPPROTO_TCP;
    -		h->ip_len = htons(sizeof(struct tcphdr));
    -		if (dir) {
    -			h->ip_src.s_addr = htonl(id->src_ip);
    -			h->ip_dst.s_addr = htonl(id->dst_ip);
    -		} else {
    -			h->ip_src.s_addr = htonl(id->dst_ip);
    -			h->ip_dst.s_addr = htonl(id->src_ip);
    -		}
    -
    -		th = (struct tcphdr *)(h + 1);
    -		break;
    -#ifdef INET6
    -	case 6:
    -		h6 = mtod(m, struct ip6_hdr *);
    -
    -		/* prepare for checksum */
    -		h6->ip6_nxt = IPPROTO_TCP;
    -		h6->ip6_plen = htons(sizeof(struct tcphdr));
    -		if (dir) {
    -			h6->ip6_src = id->src_ip6;
    -			h6->ip6_dst = id->dst_ip6;
    -		} else {
    -			h6->ip6_src = id->dst_ip6;
    -			h6->ip6_dst = id->src_ip6;
    -		}
    -
    -		th = (struct tcphdr *)(h6 + 1);
    -		break;
    -#endif
    -	}
    -
    -	if (dir) {
    -		th->th_sport = htons(id->src_port);
    -		th->th_dport = htons(id->dst_port);
    -	} else {
    -		th->th_sport = htons(id->dst_port);
    -		th->th_dport = htons(id->src_port);
    -	}
    -	th->th_off = sizeof(struct tcphdr) >> 2;
    -
    -	if (flags & TH_RST) {
    -		if (flags & TH_ACK) {
    -			th->th_seq = htonl(ack);
    -			th->th_flags = TH_RST;
    -		} else {
    -			if (flags & TH_SYN)
    -				seq++;
    -			th->th_ack = htonl(seq);
    -			th->th_flags = TH_RST | TH_ACK;
    -		}
    -	} else {
    -		/*
    -		 * Keepalive - use caller provided sequence numbers
    -		 */
    -		th->th_seq = htonl(seq);
    -		th->th_ack = htonl(ack);
    -		th->th_flags = TH_ACK;
    -	}
    -
    -	switch (id->addr_type) {
    -	case 4:
    -		th->th_sum = in_cksum(m, len);
    -
    -		/* finish the ip header */
    -		h->ip_v = 4;
    -		h->ip_hl = sizeof(*h) >> 2;
    -		h->ip_tos = IPTOS_LOWDELAY;
    -		h->ip_off = 0;
    -		h->ip_len = len;
    -		h->ip_ttl = V_ip_defttl;
    -		h->ip_sum = 0;
    -		break;
    -#ifdef INET6
    -	case 6:
    -		th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6),
    -		    sizeof(struct tcphdr));
    -
    -		/* finish the ip6 header */
    -		h6->ip6_vfc |= IPV6_VERSION;
    -		h6->ip6_hlim = IPV6_DEFHLIM;
    -		break;
    -#endif
    -	}
    -
    -	return (m);
    -}
     
     /*
      * sends a reject message, consuming the mbuf passed as an argument.
      */
     static void
    -send_reject(struct ip_fw_args *args, int code, int ip_len, struct ip *ip)
    +send_reject(struct ip_fw_args *args, int code, int iplen, struct ip *ip)
     {
     
     #if 0
    @@ -1835,269 +615,46 @@ send_reject(struct ip_fw_args *args, int code, int ip_len, struct ip *ip)
     #endif
     	if (code != ICMP_REJECT_RST) { /* Send an ICMP unreach */
     		/* We need the IP header in host order for icmp_error(). */
    -		if (args->eh != NULL) {
    -			ip->ip_len = ntohs(ip->ip_len);
    -			ip->ip_off = ntohs(ip->ip_off);
    -		}
    +		SET_HOST_IPLEN(ip);
     		icmp_error(args->m, ICMP_UNREACH, code, 0L, 0);
     	} else if (args->f_id.proto == IPPROTO_TCP) {
     		struct tcphdr *const tcp =
     		    L3HDR(struct tcphdr, mtod(args->m, struct ip *));
     		if ( (tcp->th_flags & TH_RST) == 0) {
     			struct mbuf *m;
    -			m = send_pkt(args->m, &(args->f_id),
    +			m = ipfw_send_pkt(args->m, &(args->f_id),
     				ntohl(tcp->th_seq), ntohl(tcp->th_ack),
     				tcp->th_flags | TH_RST);
     			if (m != NULL)
     				ip_output(m, NULL, NULL, 0, NULL, NULL);
     		}
    -		m_freem(args->m);
    +		FREE_PKT(args->m);
     	} else
    -		m_freem(args->m);
    +		FREE_PKT(args->m);
     	args->m = NULL;
     }
     
    -/**
    - *
    - * Given an ip_fw *, lookup_next_rule will return a pointer
    - * to the next rule, which can be either the jump
    - * target (for skipto instructions) or the next one in the list (in
    - * all other cases including a missing jump target).
    - * The result is also written in the "next_rule" field of the rule.
    - * Backward jumps are not allowed, so start looking from the next
    - * rule...
    - *
    - * This never returns NULL -- in case we do not have an exact match,
    - * the next rule is returned. When the ruleset is changed,
    - * pointers are flushed so we are always correct.
    +/*
    + * Support for uid/gid/jail lookup. These tests are expensive
    + * (because we may need to look into the list of active sockets)
    + * so we cache the results. ugid_lookupp is 0 if we have not
    + * yet done a lookup, 1 if we succeeded, and -1 if we tried
    + * and failed. The function always returns the match value.
    + * We could actually spare the variable and use *uc, setting
    + * it to '(void *)check_uidgid if we have no info, NULL if
    + * we tried and failed, or any other value if successful.
      */
    -
    -static struct ip_fw *
    -lookup_next_rule(struct ip_fw *me, u_int32_t tablearg)
    -{
    -	struct ip_fw *rule = NULL;
    -	ipfw_insn *cmd;
    -	u_int16_t	rulenum;
    -
    -	/* look for action, in case it is a skipto */
    -	cmd = ACTION_PTR(me);
    -	if (cmd->opcode == O_LOG)
    -		cmd += F_LEN(cmd);
    -	if (cmd->opcode == O_ALTQ)
    -		cmd += F_LEN(cmd);
    -	if (cmd->opcode == O_TAG)
    -		cmd += F_LEN(cmd);
    -	if (cmd->opcode == O_SKIPTO ) {
    -		if (tablearg != 0) {
    -			rulenum = (u_int16_t)tablearg;
    -		} else {
    -			rulenum = cmd->arg1;
    -		}
    -		for (rule = me->next; rule ; rule = rule->next) {
    -			if (rule->rulenum >= rulenum) {
    -				break;
    -			}
    -		}
    -	}
    -	if (rule == NULL)			/* failure or not a skipto */
    -		rule = me->next;
    -	me->next_rule = rule;
    -	return rule;
    -}
    -
    -static int
    -add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
    -    uint8_t mlen, uint32_t value)
    -{
    -	struct radix_node_head *rnh;
    -	struct table_entry *ent;
    -	struct radix_node *rn;
    -
    -	if (tbl >= IPFW_TABLES_MAX)
    -		return (EINVAL);
    -	rnh = ch->tables[tbl];
    -	ent = malloc(sizeof(*ent), M_IPFW_TBL, M_NOWAIT | M_ZERO);
    -	if (ent == NULL)
    -		return (ENOMEM);
    -	ent->value = value;
    -	ent->addr.sin_len = ent->mask.sin_len = 8;
    -	ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
    -	ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr;
    -	IPFW_WLOCK(ch);
    -	rn = rnh->rnh_addaddr(&ent->addr, &ent->mask, rnh, (void *)ent);
    -	if (rn == NULL) {
    -		IPFW_WUNLOCK(ch);
    -		free(ent, M_IPFW_TBL);
    -		return (EEXIST);
    -	}
    -	IPFW_WUNLOCK(ch);
    -	return (0);
    -}
    -
    -static int
    -del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
    -    uint8_t mlen)
    -{
    -	struct radix_node_head *rnh;
    -	struct table_entry *ent;
    -	struct sockaddr_in sa, mask;
    -
    -	if (tbl >= IPFW_TABLES_MAX)
    -		return (EINVAL);
    -	rnh = ch->tables[tbl];
    -	sa.sin_len = mask.sin_len = 8;
    -	mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
    -	sa.sin_addr.s_addr = addr & mask.sin_addr.s_addr;
    -	IPFW_WLOCK(ch);
    -	ent = (struct table_entry *)rnh->rnh_deladdr(&sa, &mask, rnh);
    -	if (ent == NULL) {
    -		IPFW_WUNLOCK(ch);
    -		return (ESRCH);
    -	}
    -	IPFW_WUNLOCK(ch);
    -	free(ent, M_IPFW_TBL);
    -	return (0);
    -}
    -
    -static int
    -flush_table_entry(struct radix_node *rn, void *arg)
    -{
    -	struct radix_node_head * const rnh = arg;
    -	struct table_entry *ent;
    -
    -	ent = (struct table_entry *)
    -	    rnh->rnh_deladdr(rn->rn_key, rn->rn_mask, rnh);
    -	if (ent != NULL)
    -		free(ent, M_IPFW_TBL);
    -	return (0);
    -}
    -
    -static int
    -flush_table(struct ip_fw_chain *ch, uint16_t tbl)
    -{
    -	struct radix_node_head *rnh;
    -
    -	IPFW_WLOCK_ASSERT(ch);
    -
    -	if (tbl >= IPFW_TABLES_MAX)
    -		return (EINVAL);
    -	rnh = ch->tables[tbl];
    -	KASSERT(rnh != NULL, ("NULL IPFW table"));
    -	rnh->rnh_walktree(rnh, flush_table_entry, rnh);
    -	return (0);
    -}
    -
    -static void
    -flush_tables(struct ip_fw_chain *ch)
    -{
    -	uint16_t tbl;
    -
    -	IPFW_WLOCK_ASSERT(ch);
    -
    -	for (tbl = 0; tbl < IPFW_TABLES_MAX; tbl++)
    -		flush_table(ch, tbl);
    -}
    -
    -static int
    -init_tables(struct ip_fw_chain *ch)
    -{ 
    -	int i;
    -	uint16_t j;
    -
    -	for (i = 0; i < IPFW_TABLES_MAX; i++) {
    -		if (!rn_inithead((void **)&ch->tables[i], 32)) {
    -			for (j = 0; j < i; j++) {
    -				(void) flush_table(ch, j);
    -			}
    -			return (ENOMEM);
    -		}
    -	}
    -	return (0);
    -}
    -
    -static int
    -lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
    -    uint32_t *val)
    -{
    -	struct radix_node_head *rnh;
    -	struct table_entry *ent;
    -	struct sockaddr_in sa;
    -
    -	if (tbl >= IPFW_TABLES_MAX)
    -		return (0);
    -	rnh = ch->tables[tbl];
    -	sa.sin_len = 8;
    -	sa.sin_addr.s_addr = addr;
    -	ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh));
    -	if (ent != NULL) {
    -		*val = ent->value;
    -		return (1);
    -	}
    -	return (0);
    -}
    -
    -static int
    -count_table_entry(struct radix_node *rn, void *arg)
    -{
    -	u_int32_t * const cnt = arg;
    -
    -	(*cnt)++;
    -	return (0);
    -}
    -
    -static int
    -count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt)
    -{
    -	struct radix_node_head *rnh;
    -
    -	if (tbl >= IPFW_TABLES_MAX)
    -		return (EINVAL);
    -	rnh = ch->tables[tbl];
    -	*cnt = 0;
    -	rnh->rnh_walktree(rnh, count_table_entry, cnt);
    -	return (0);
    -}
    -
    -static int
    -dump_table_entry(struct radix_node *rn, void *arg)
    -{
    -	struct table_entry * const n = (struct table_entry *)rn;
    -	ipfw_table * const tbl = arg;
    -	ipfw_table_entry *ent;
    -
    -	if (tbl->cnt == tbl->size)
    -		return (1);
    -	ent = &tbl->ent[tbl->cnt];
    -	ent->tbl = tbl->tbl;
    -	if (in_nullhost(n->mask.sin_addr))
    -		ent->masklen = 0;
    -	else
    -		ent->masklen = 33 - ffs(ntohl(n->mask.sin_addr.s_addr));
    -	ent->addr = n->addr.sin_addr.s_addr;
    -	ent->value = n->value;
    -	tbl->cnt++;
    -	return (0);
    -}
    -
    -static int
    -dump_table(struct ip_fw_chain *ch, ipfw_table *tbl)
    -{
    -	struct radix_node_head *rnh;
    -
    -	if (tbl->tbl >= IPFW_TABLES_MAX)
    -		return (EINVAL);
    -	rnh = ch->tables[tbl->tbl];
    -	tbl->cnt = 0;
    -	rnh->rnh_walktree(rnh, dump_table_entry, tbl);
    -	return (0);
    -}
    -
     static int
     check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
         struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
    -    u_int16_t src_port, struct ucred **uc, int *ugid_lookupp,
    -    struct inpcb *inp)
    +    u_int16_t src_port, int *ugid_lookupp,
    +    struct ucred **uc, struct inpcb *inp)
     {
    +#ifndef __FreeBSD__
    +	return cred_check(insn, proto, oif,
    +	    dst_ip, dst_port, src_ip, src_port,
    +	    (struct bsd_ucred *)uc, ugid_lookupp, ((struct mbuf *)inp)->m_skb);
    +#else  /* FreeBSD */
     	struct inpcbinfo *pi;
     	int wildcard;
     	struct inpcb *pcb;
    @@ -2150,10 +707,8 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
     		INP_INFO_RUNLOCK(pi);
     		if (*ugid_lookupp == 0) {
     			/*
    -			 * If the lookup did not yield any results, there
    -			 * is no sense in coming back and trying again. So
    -			 * we can set lookup to -1 and ensure that we wont
    -			 * bother the pcb system again.
    +			 * We tried and failed, set the variable to -1
    +			 * so we will not try again on this packet.
     			 */
     			*ugid_lookupp = -1;
     			return (0);
    @@ -2166,6 +721,22 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
     	else if (insn->o.opcode == O_JAIL)
     		match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]);
     	return match;
    +#endif /* __FreeBSD__ */
    +}
    +
    +/*
    + * Helper function to set args with info on the rule after the matching
    + * one. slot is precise, whereas we guess rule_id as they are
    + * assigned sequentially.
    + */
    +static inline void
    +set_match(struct ip_fw_args *args, int slot,
    +	struct ip_fw_chain *chain)
    +{
    +	args->rule.chain_id = chain->id;
    +	args->rule.slot = slot + 1; /* we use 0 as a marker */
    +	args->rule.rule_id = 1 + chain->map[slot]->id;
    +	args->rule.rulenum = chain->map[slot]->rulenum;
     }
     
     /*
    @@ -2178,10 +749,10 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
      *
      *	args->m	(in/out) The packet; we set to NULL when/if we nuke it.
      *		Starts with the IP header.
    - *	args->eh (in)	Mac header if present, or NULL for layer3 packet.
    + *	args->eh (in)	Mac header if present, NULL for layer3 packet.
      *	args->L3offset	Number of bytes bypassed if we came from L2.
      *			e.g. often sizeof(eh)  ** NOTYET **
    - *	args->oif	Outgoing interface, or NULL if packet is incoming.
    + *	args->oif	Outgoing interface, NULL if packet is incoming.
      *		The incoming interface is in the mbuf. (in)
      *	args->divert_rule (in/out)
      *		Skip up to the first rule past this rule number;
    @@ -2190,7 +761,7 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
      *	args->rule	Pointer to the last matching rule (in/out)
      *	args->next_hop	Socket we are forwarding to (out).
      *	args->f_id	Addresses grabbed from the packet (out)
    - * 	args->cookie	a cookie depending on rule action
    + * 	args->rule.info	a cookie depending on rule action
      *
      * Return value:
      *
    @@ -2200,6 +771,8 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
      *	IP_FW_TEE	tee packet, port in m_tag
      *	IP_FW_DUMMYNET	to dummynet, pipe in args->cookie
      *	IP_FW_NETGRAPH	into netgraph, cookie args->cookie
    + *		args->rule contains the matching rule,
    + *		args->rule.info has additional information.
      *
      */
     int
    @@ -2207,7 +780,7 @@ ipfw_chk(struct ip_fw_args *args)
     {
     
     	/*
    -	 * Local variables holding state during the processing of a packet:
    +	 * Local variables holding state while processing a packet:
     	 *
     	 * IMPORTANT NOTE: to speed up the processing of rules, there
     	 * are some assumption on the values of the variables, which
    @@ -2240,17 +813,13 @@ ipfw_chk(struct ip_fw_args *args)
     	 * these types of constraints, as well as decrease contention
     	 * on pcb related locks.
     	 */
    +#ifndef __FreeBSD__
    +	struct bsd_ucred ucred_cache;
    +#else
     	struct ucred *ucred_cache = NULL;
    +#endif
     	int ucred_lookup = 0;
     
    -	/*
    -	 * divinput_flags	If non-zero, set to the IP_FW_DIVERT_*_FLAG
    -	 *	associated with a packet input on a divert socket.  This
    -	 *	will allow to distinguish traffic and its direction when
    -	 *	it originates from a divert socket.
    -	 */
    -	u_int divinput_flags = 0;
    -
     	/*
     	 * oif | args->oif	If NULL, ipfw_chk has been called on the
     	 *	inbound path (ether_input, ip_input).
    @@ -2259,7 +828,7 @@ ipfw_chk(struct ip_fw_args *args)
     	 */
     	struct ifnet *oif = args->oif;
     
    -	struct ip_fw *f = NULL;		/* matching rule */
    +	int f_pos = 0;		/* index of current rule in the array */
     	int retval = 0;
     
     	/*
    @@ -2294,12 +863,12 @@ ipfw_chk(struct ip_fw_args *args)
     	 * src_ip, dst_ip	ip addresses, in NETWORK format.
     	 *	Only valid for IPv4 packets.
     	 */
    -	u_int8_t proto;
    -	u_int16_t src_port = 0, dst_port = 0;	/* NOTE: host format	*/
    +	uint8_t proto;
    +	uint16_t src_port = 0, dst_port = 0;	/* NOTE: host format	*/
     	struct in_addr src_ip, dst_ip;		/* NOTE: network format	*/
    -	u_int16_t ip_len=0;
    +	uint16_t iplen=0;
     	int pktlen;
    -	u_int16_t	etype = 0;	/* Host order stored ether type */
    +	uint16_t	etype = 0;	/* Host order stored ether type */
     
     	/*
     	 * dyn_dir = MATCH_UNKNOWN when rules unchecked,
    @@ -2309,7 +878,6 @@ ipfw_chk(struct ip_fw_args *args)
     	int dyn_dir = MATCH_UNKNOWN;
     	ipfw_dyn_rule *q = NULL;
     	struct ip_fw_chain *chain = &V_layer3_chain;
    -	struct m_tag *mtag;
     
     	/*
     	 * We store in ulp a pointer to the upper layer protocol header.
    @@ -2318,12 +886,17 @@ ipfw_chk(struct ip_fw_args *args)
     	 * ulp is NULL if not found.
     	 */
     	void *ulp = NULL;		/* upper layer protocol pointer. */
    +
     	/* XXX ipv6 variables */
     	int is_ipv6 = 0;
    -	u_int16_t ext_hd = 0;	/* bits vector for extension header filtering */
    +	uint8_t	icmp6_type = 0;
    +	uint16_t ext_hd = 0;	/* bits vector for extension header filtering */
     	/* end of ipv6 variables */
    +
     	int is_ipv4 = 0;
     
    +	int done = 0;		/* flag to exit the outer loop */
    +
     	if (m->m_flags & M_SKIP_FIREWALL || (! V_ipfw_vnet_ready))
     		return (IP_FW_PASS);	/* accept */
     
    @@ -2340,15 +913,15 @@ ipfw_chk(struct ip_fw_args *args)
      * pointer might become stale after other pullups (but we never use it
      * this way).
      */
    -#define PULLUP_TO(_len, p, T)						\
    -do {									\
    -	int x = (_len) + sizeof(T);					\
    -	if ((m)->m_len < x) {						\
    -		args->m = m = m_pullup(m, x);				\
    -		if (m == NULL)						\
    -			goto pullup_failed;				\
    -	}								\
    -	p = (mtod(m, char *) + (_len));					\
    +#define PULLUP_TO(_len, p, T)					\
    +do {								\
    +	int x = (_len) + sizeof(T);				\
    +	if ((m)->m_len < x) {					\
    +		args->m = m = m_pullup(m, x);			\
    +		if (m == NULL)					\
    +			goto pullup_failed;			\
    +	}							\
    +	p = (mtod(m, char *) + (_len));				\
     } while (0)
     
     	/*
    @@ -2371,14 +944,15 @@ do {									\
     			switch (proto) {
     			case IPPROTO_ICMPV6:
     				PULLUP_TO(hlen, ulp, struct icmp6_hdr);
    -				args->f_id.flags = ICMP6(ulp)->icmp6_type;
    +				icmp6_type = ICMP6(ulp)->icmp6_type;
     				break;
     
     			case IPPROTO_TCP:
     				PULLUP_TO(hlen, ulp, struct tcphdr);
     				dst_port = TCP(ulp)->th_dport;
     				src_port = TCP(ulp)->th_sport;
    -				args->f_id.flags = TCP(ulp)->th_flags;
    +				/* save flags for dynamic rules */
    +				args->f_id._flags = TCP(ulp)->th_flags;
     				break;
     
     			case IPPROTO_SCTP:
    @@ -2442,7 +1016,7 @@ do {									\
     					    return (IP_FW_DENY);
     					break;
     				}
    -				args->f_id.frag_id6 =
    +				args->f_id.extra =
     				    ntohl(((struct ip6_frag *)ulp)->ip6f_ident);
     				ulp = NULL;
     				break;
    @@ -2535,14 +1109,9 @@ do {									\
     		proto = ip->ip_p;
     		src_ip = ip->ip_src;
     		dst_ip = ip->ip_dst;
    -		if (args->eh != NULL) { /* layer 2 packets are as on the wire */
    -			offset = ntohs(ip->ip_off) & IP_OFFMASK;
    -			ip_len = ntohs(ip->ip_len);
    -		} else {
    -			offset = ip->ip_off & IP_OFFMASK;
    -			ip_len = ip->ip_len;
    -		}
    -		pktlen = ip_len < pktlen ? ip_len : pktlen;
    +		offset = ntohs(ip->ip_off) & IP_OFFMASK;
    +		iplen = ntohs(ip->ip_len);
    +		pktlen = iplen < pktlen ? iplen : pktlen;
     
     		if (offset == 0) {
     			switch (proto) {
    @@ -2550,7 +1119,8 @@ do {									\
     				PULLUP_TO(hlen, ulp, struct tcphdr);
     				dst_port = TCP(ulp)->th_dport;
     				src_port = TCP(ulp)->th_sport;
    -				args->f_id.flags = TCP(ulp)->th_flags;
    +				/* save flags for dynamic rules */
    +				args->f_id._flags = TCP(ulp)->th_flags;
     				break;
     
     			case IPPROTO_UDP:
    @@ -2561,7 +1131,7 @@ do {									\
     
     			case IPPROTO_ICMP:
     				PULLUP_TO(hlen, ulp, struct icmphdr);
    -				args->f_id.flags = ICMP(ulp)->icmp_type;
    +				//args->f_id.flags = ICMP(ulp)->icmp_type;
     				break;
     
     			default:
    @@ -2585,64 +1155,47 @@ do {									\
     		IPFW_RUNLOCK(chain);
     		return (IP_FW_PASS);	/* accept */
     	}
    -	mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
    -	if (args->rule) {
    +	if (args->rule.slot) {
     		/*
    -		 * Packet has already been tagged. Look for the next rule
    -		 * to restart processing. Make sure that args->rule still
    -		 * exists and not changed.
    +		 * Packet has already been tagged as a result of a previous
    +		 * match on rule args->rule aka args->rule_id (PIPE, QUEUE,
    +		 * REASS, NETGRAPH, DIVERT/TEE...)
    +		 * Validate the slot and continue from the next one
    +		 * if still present, otherwise do a lookup.
     		 */
    -		if (chain->id != args->chain_id) {
    -			for (f = chain->rules; f != NULL; f = f->next)
    -				if (f == args->rule && f->id == args->rule_id)
    -					break;
    -
    -			if (f != NULL)
    -				f = f->next_rule;
    -			else
    -				f = ip_fw_default_rule;
    -		} else 
    -			f = args->rule->next_rule;
    -
    -		if (f == NULL)
    -			f = lookup_next_rule(args->rule, 0);
    +		f_pos = (args->rule.chain_id == chain->id) ?
    +		    args->rule.slot :
    +		    ipfw_find_rule(chain, args->rule.rulenum,
    +			args->rule.rule_id);
     	} else {
    -		/*
    -		 * Find the starting rule. It can be either the first
    -		 * one, or the one after divert_rule if asked so.
    -		 */
    -		int skipto = mtag ? divert_cookie(mtag) : 0;
    -
    -		f = chain->rules;
    -		if (args->eh == NULL && skipto != 0) {
    -			if (skipto >= IPFW_DEFAULT_RULE) {
    -				IPFW_RUNLOCK(chain);
    -				return (IP_FW_DENY); /* invalid */
    -			}
    -			while (f && f->rulenum <= skipto)
    -				f = f->next;
    -			if (f == NULL) {	/* drop packet */
    -				IPFW_RUNLOCK(chain);
    -				return (IP_FW_DENY);
    -			}
    -		}
    -	}
    -	/* reset divert rule to avoid confusion later */
    -	if (mtag) {
    -		divinput_flags = divert_info(mtag) &
    -		    (IP_FW_DIVERT_OUTPUT_FLAG | IP_FW_DIVERT_LOOPBACK_FLAG);
    -		m_tag_delete(m, mtag);
    +		f_pos = 0;
     	}
     
     	/*
     	 * Now scan the rules, and parse microinstructions for each rule.
    +	 * We have two nested loops and an inner switch. Sometimes we
    +	 * need to break out of one or both loops, or re-enter one of
    +	 * the loops with updated variables. Loop variables are:
    +	 *
    +	 *	f_pos (outer loop) points to the current rule.
    +	 *		On output it points to the matching rule.
    +	 *	done (outer loop) is used as a flag to break the loop.
    +	 *	l (inner loop)	residual length of current rule.
    +	 *		cmd points to the current microinstruction.
    +	 *
    +	 * We break the inner loop by setting l=0 and possibly
    +	 * cmdlen=0 if we don't want to advance cmd.
    +	 * We break the outer loop by setting done=1
    +	 * We can restart the inner loop by setting l>0 and f_pos, f, cmd
    +	 * as needed.
     	 */
    -	for (; f; f = f->next) {
    +	for (; f_pos < chain->n_rules; f_pos++) {
     		ipfw_insn *cmd;
     		uint32_t tablearg = 0;
     		int l, cmdlen, skip_or; /* skip rest of OR block */
    +		struct ip_fw *f;
     
    -again:
    +		f = chain->map[f_pos];
     		if (V_set_disable & (1 << f->set) )
     			continue;
     
    @@ -2657,7 +1210,7 @@ again:
     			 * the target rule.
     			 */
     
    -check_body:
    +/* check_body: */
     			cmdlen = F_LEN(cmd);
     			/*
     			 * An OR block (insn_1 || .. || insn_n) has the
    @@ -2708,8 +1261,13 @@ check_body:
     						    (ipfw_insn_u32 *)cmd,
     						    proto, oif,
     						    dst_ip, dst_port,
    -						    src_ip, src_port, &ucred_cache,
    -						    &ucred_lookup, args->inp);
    +						    src_ip, src_port, &ucred_lookup,
    +#ifdef __FreeBSD__
    +						    &ucred_cache, args->inp);
    +#else
    +						    (void *)&ucred_cache,
    +						    (struct inpcb *)args->m);
    +#endif
     				break;
     
     			case O_RECV:
    @@ -2767,10 +1325,15 @@ check_body:
     				break;
     
     			case O_DIVERTED:
    -				match = (cmd->arg1 & 1 && divinput_flags &
    -				    IP_FW_DIVERT_LOOPBACK_FLAG) ||
    -					(cmd->arg1 & 2 && divinput_flags &
    -				    IP_FW_DIVERT_OUTPUT_FLAG);
    +			    {
    +				/* For diverted packets, args->rule.info
    +				 * contains the divert port (in host format)
    +				 * reason and direction.
    +	 			 */
    +				uint32_t i = args->rule.info;
    +				match = (i&IPFW_IS_MASK) == IPFW_IS_DIVERT &&
    +				    cmd->arg1 & ((i & IPFW_INFO_IN) ? 1 : 2);
    +			    }
     				break;
     
     			case O_PROTO:
    @@ -2790,13 +1353,57 @@ check_body:
     			case O_IP_SRC_LOOKUP:
     			case O_IP_DST_LOOKUP:
     				if (is_ipv4) {
    -				    uint32_t a =
    +				    uint32_t key =
     					(cmd->opcode == O_IP_DST_LOOKUP) ?
     					    dst_ip.s_addr : src_ip.s_addr;
     				    uint32_t v = 0;
     
    -				    match = lookup_table(chain, cmd->arg1, a,
    -					&v);
    +				    if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
    +					/* generic lookup. The key must be
    +					 * in 32bit big-endian format.
    +					 */
    +					v = ((ipfw_insn_u32 *)cmd)->d[1];
    +					if (v == 0)
    +					    key = dst_ip.s_addr;
    +					else if (v == 1)
    +					    key = src_ip.s_addr;
    +					else if (v == 6) /* dscp */
    +					    key = (ip->ip_tos >> 2) & 0x3f;
    +					else if (offset != 0)
    +					    break;
    +					else if (proto != IPPROTO_TCP &&
    +						proto != IPPROTO_UDP)
    +					    break;
    +					else if (v == 2)
    +					    key = htonl(dst_port);
    +					else if (v == 3)
    +					    key = htonl(src_port);
    +					else if (v == 4 || v == 5) {
    +					    check_uidgid(
    +						(ipfw_insn_u32 *)cmd,
    +						proto, oif,
    +						dst_ip, dst_port,
    +						src_ip, src_port, &ucred_lookup,
    +#ifdef __FreeBSD__
    +						&ucred_cache, args->inp);
    +					    if (v == 4 /* O_UID */)
    +						key = ucred_cache->cr_uid;
    +					    else if (v == 5 /* O_JAIL */)
    +						key = ucred_cache->cr_prison->pr_id;
    +#else /* !__FreeBSD__ */
    +						(void *)&ucred_cache,
    +						(struct inpcb *)args->m);
    +					    if (v ==4 /* O_UID */)
    +						key = ucred_cache.uid;
    +					    else if (v == 5 /* O_JAIL */)
    +						key = ucred_cache.xid;
    +#endif /* !__FreeBSD__ */
    +					    key = htonl(key);
    +					} else
    +					    break;
    +				    }
    +				    match = ipfw_lookup_table(chain,
    +					cmd->arg1, key, &v);
     				    if (!match)
     					break;
     				    if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
    @@ -2827,7 +1434,13 @@ check_body:
     
     					INADDR_TO_IFP(src_ip, tif);
     					match = (tif != NULL);
    +					break;
     				}
    +#ifdef INET6
    +				/* FALLTHROUGH */
    +			case O_IP6_SRC_ME:
    +				match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
    +#endif
     				break;
     
     			case O_IP_DST_SET:
    @@ -2860,9 +1473,16 @@ check_body:
     
     					INADDR_TO_IFP(dst_ip, tif);
     					match = (tif != NULL);
    +					break;
     				}
    +#ifdef INET6
    +				/* FALLTHROUGH */
    +			case O_IP6_DST_ME:
    +				match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
    +#endif
     				break;
     
    +
     			case O_IP_SRCPORT:
     			case O_IP_DSTPORT:
     				/*
    @@ -2919,7 +1539,7 @@ check_body:
     				    int i;
     
     				    if (cmd->opcode == O_IPLEN)
    -					x = ip_len;
    +					x = iplen;
     				    else if (cmd->opcode == O_IPTTL)
     					x = ip->ip_ttl;
     				    else /* must be IPID */
    @@ -2954,7 +1574,7 @@ check_body:
     				    int i;
     
     				    tcp = TCP(ulp);
    -				    x = ip_len -
    +				    x = iplen -
     					((ip->ip_hl + tcp->th_off) << 2);
     				    if (cmdlen == 1) {
     					match = (cmd->arg1 == x);
    @@ -3029,8 +1649,7 @@ check_body:
     			}
     
     			case O_LOG:
    -				if (V_fw_verbose)
    -					ipfw_log(f, hlen, args, m,
    +				ipfw_log(f, hlen, args, m,
     					    oif, offset, tablearg, ip);
     				match = 1;
     				break;
    @@ -3129,14 +1748,6 @@ check_body:
     				}
     				break;
     
    -			case O_IP6_SRC_ME:
    -				match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
    -				break;
    -
    -			case O_IP6_DST_ME:
    -				match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
    -				break;
    -
     			case O_FLOW6ID:
     				match = is_ipv6 &&
     				    flow6id_match(args->f_id.flow_id6,
    @@ -3158,6 +1769,7 @@ check_body:
     				break;
     
     			case O_TAG: {
    +				struct m_tag *mtag;
     				uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
     				    tablearg : cmd->arg1;
     
    @@ -3174,12 +1786,13 @@ check_body:
     				if (cmd->len & F_NOT) { /* `untag' action */
     					if (mtag != NULL)
     						m_tag_delete(m, mtag);
    +					match = 0;
     				} else if (mtag == NULL) {
     					if ((mtag = m_tag_alloc(MTAG_IPFW,
     					    tag, 0, M_NOWAIT)) != NULL)
     						m_tag_prepend(m, mtag);
    +					match = 1;
     				}
    -				match = (cmd->len & F_NOT) ? 0: 1;
     				break;
     			}
     
    @@ -3189,6 +1802,7 @@ check_body:
     				break;
     
     			case O_TAGGED: {
    +				struct m_tag *mtag;
     				uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
     				    tablearg : cmd->arg1;
     
    @@ -3228,14 +1842,13 @@ check_body:
     			 *
     			 * In general, here we set retval and terminate the
     			 * outer loop (would be a 'break 3' in some language,
    -			 * but we need to do a 'goto done').
    +			 * but we need to set l=0, done=1)
     			 *
     			 * Exceptions:
     			 * O_COUNT and O_SKIPTO actions:
     			 *   instead of terminating, we jump to the next rule
    -			 *   ('goto next_rule', equivalent to a 'break 2'),
    -			 *   or to the SKIPTO target ('goto again' after
    -			 *   having set f, cmd and l), respectively.
    +			 *   (setting l=0), or to the SKIPTO target (setting
    +			 *   f/f_len, cmd and l as needed), respectively.
     			 *
     			 * O_TAG, O_LOG and O_ALTQ action parameters:
     			 *   perform some action and set match = 1;
    @@ -3246,25 +1859,28 @@ check_body:
     			 *   These opcodes try to install an entry in the
     			 *   state tables; if successful, we continue with
     			 *   the next opcode (match=1; break;), otherwise
    -			 *   the packet *   must be dropped
    -			 *   ('goto done' after setting retval);
    +			 *   the packet must be dropped (set retval,
    +			 *   break loops with l=0, done=1)
     			 *
     			 * O_PROBE_STATE and O_CHECK_STATE: these opcodes
     			 *   cause a lookup of the state table, and a jump
     			 *   to the 'action' part of the parent rule
    -			 *   ('goto check_body') if an entry is found, or
    +			 *   if an entry is found, or
     			 *   (CHECK_STATE only) a jump to the next rule if
    -			 *   the entry is not found ('goto next_rule').
    -			 *   The result of the lookup is cached to make
    -			 *   further instances of these opcodes are
    -			 *   effectively NOPs.
    +			 *   the entry is not found.
    +			 *   The result of the lookup is cached so that
    +			 *   further instances of these opcodes become NOPs.
    +			 *   The jump to the next rule is done by setting
    +			 *   l=0, cmdlen=0.
     			 */
     			case O_LIMIT:
     			case O_KEEP_STATE:
    -				if (install_state(f,
    +				if (ipfw_install_state(f,
     				    (ipfw_insn_limit *)cmd, args, tablearg)) {
    +					/* error or limit violation */
     					retval = IP_FW_DENY;
    -					goto done; /* error/limit violation */
    +					l = 0;	/* exit inner loop */
    +					done = 1; /* exit outer loop */
     				}
     				match = 1;
     				break;
    @@ -3281,22 +1897,32 @@ check_body:
     				 * to be run first).
     				 */
     				if (dyn_dir == MATCH_UNKNOWN &&
    -				    (q = lookup_dyn_rule(&args->f_id,
    +				    (q = ipfw_lookup_dyn_rule(&args->f_id,
     				     &dyn_dir, proto == IPPROTO_TCP ?
     					TCP(ulp) : NULL))
     					!= NULL) {
     					/*
     					 * Found dynamic entry, update stats
     					 * and jump to the 'action' part of
    -					 * the parent rule.
    +					 * the parent rule by setting
    +					 * f, cmd, l and clearing cmdlen.
     					 */
     					q->pcnt++;
     					q->bcnt += pktlen;
    +					/* XXX we would like to have f_pos
    +					 * readily accessible in the dynamic
    +				         * rule, instead of having to
    +					 * lookup q->rule.
    +					 */
     					f = q->rule;
    +					f_pos = ipfw_find_rule(chain,
    +						f->rulenum, f->id);
     					cmd = ACTION_PTR(f);
     					l = f->cmd_len - f->act_ofs;
    -					IPFW_DYN_UNLOCK();
    -					goto check_body;
    +					ipfw_dyn_unlock();
    +					cmdlen = 0;
    +					match = 1;
    +					break;
     				}
     				/*
     				 * Dynamic entry not found. If CHECK_STATE,
    @@ -3304,70 +1930,96 @@ check_body:
     				 * ignore and continue with next opcode.
     				 */
     				if (cmd->opcode == O_CHECK_STATE)
    -					goto next_rule;
    +					l = 0;	/* exit inner loop */
     				match = 1;
     				break;
     
     			case O_ACCEPT:
     				retval = 0;	/* accept */
    -				goto done;
    +				l = 0;		/* exit inner loop */
    +				done = 1;	/* exit outer loop */
    +				break;
     
     			case O_PIPE:
     			case O_QUEUE:
    -				args->rule = f; /* report matching rule */
    -				args->rule_id = f->id;
    -				args->chain_id = chain->id;
    -				if (cmd->arg1 == IP_FW_TABLEARG)
    -					args->cookie = tablearg;
    -				else
    -					args->cookie = cmd->arg1;
    +				set_match(args, f_pos, chain);
    +				args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
    +					tablearg : cmd->arg1;
    +				if (cmd->opcode == O_PIPE)
    +					args->rule.info |= IPFW_IS_PIPE;
    +				if (V_fw_one_pass)
    +					args->rule.info |= IPFW_ONEPASS;
     				retval = IP_FW_DUMMYNET;
    -				goto done;
    +				l = 0;          /* exit inner loop */
    +				done = 1;       /* exit outer loop */
    +				break;
     
     			case O_DIVERT:
    -			case O_TEE: {
    -				struct divert_tag *dt;
    -
    +			case O_TEE:
     				if (args->eh) /* not on layer 2 */
    -					break;
    -				mtag = m_tag_get(PACKET_TAG_DIVERT,
    -						sizeof(struct divert_tag),
    -						M_NOWAIT);
    -				if (mtag == NULL) {
    -					/* XXX statistic */
    -					/* drop packet */
    -					IPFW_RUNLOCK(chain);
    -					if (ucred_cache != NULL)
    -						crfree(ucred_cache);
    -					return (IP_FW_DENY);
    -				}
    -				dt = (struct divert_tag *)(mtag+1);
    -				dt->cookie = f->rulenum;
    -				if (cmd->arg1 == IP_FW_TABLEARG)
    -					dt->info = tablearg;
    -				else
    -					dt->info = cmd->arg1;
    -				m_tag_prepend(m, mtag);
    +				    break;
    +				/* otherwise this is terminal */
    +				l = 0;		/* exit inner loop */
    +				done = 1;	/* exit outer loop */
     				retval = (cmd->opcode == O_DIVERT) ?
    -				    IP_FW_DIVERT : IP_FW_TEE;
    -				goto done;
    -			}
    +					IP_FW_DIVERT : IP_FW_TEE;
    +				set_match(args, f_pos, chain);
    +				args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
    +				    tablearg : cmd->arg1;
    +				break;
    +
     			case O_COUNT:
    -			case O_SKIPTO:
     				f->pcnt++;	/* update stats */
     				f->bcnt += pktlen;
     				f->timestamp = time_uptime;
    -				if (cmd->opcode == O_COUNT)
    -					goto next_rule;
    -				/* handle skipto */
    -				if (cmd->arg1 == IP_FW_TABLEARG) {
    -					f = lookup_next_rule(f, tablearg);
    -				} else {
    -					if (f->next_rule == NULL)
    -						lookup_next_rule(f, 0);
    -					f = f->next_rule;
    +				l = 0;		/* exit inner loop */
    +				break;
    +
    +			case O_SKIPTO:
    +			    f->pcnt++;	/* update stats */
    +			    f->bcnt += pktlen;
    +			    f->timestamp = time_uptime;
    +			    /* If possible use cached f_pos (in f->next_rule),
    +			     * whose version is written in f->next_rule
    +			     * (horrible hacks to avoid changing the ABI).
    +			     */
    +			    if (cmd->arg1 != IP_FW_TABLEARG &&
    +				    (uintptr_t)f->x_next == chain->id) {
    +				f_pos = (uintptr_t)f->next_rule;
    +			    } else {
    +				int i = (cmd->arg1 == IP_FW_TABLEARG) ?
    +					tablearg : cmd->arg1;
    +				/* make sure we do not jump backward */
    +				if (i <= f->rulenum)
    +				    i = f->rulenum + 1;
    +				f_pos = ipfw_find_rule(chain, i, 0);
    +				/* update the cache */
    +				if (cmd->arg1 != IP_FW_TABLEARG) {
    +				    f->next_rule =
    +					(void *)(uintptr_t)f_pos;
    +				    f->x_next =
    +					(void *)(uintptr_t)chain->id;
     				}
    -				goto again;
    +			    }
    +			    /*
    +			     * Skip disabled rules, and re-enter
    +			     * the inner loop with the correct
    +			     * f_pos, f, l and cmd.
    +			     * Also clear cmdlen and skip_or
    +			     */
    +			    for (; f_pos < chain->n_rules - 1 &&
    +				    (V_set_disable &
    +				     (1 << chain->map[f_pos]->set));
    +				    f_pos++)
    +				;
    +			    /* prepare to enter the inner loop */
    +			    f = chain->map[f_pos];
    +			    l = f->cmd_len;
    +			    cmd = f->cmd;
    +			    match = 1;
    +			    cmdlen = 0;
    +			    skip_or = 0;
    +			    break;
     
     			case O_REJECT:
     				/*
    @@ -3380,7 +2032,7 @@ check_body:
     				     is_icmp_query(ICMP(ulp))) &&
     				    !(m->m_flags & (M_BCAST|M_MCAST)) &&
     				    !IN_MULTICAST(ntohl(dst_ip.s_addr))) {
    -					send_reject(args, cmd->arg1, ip_len, ip);
    +					send_reject(args, cmd->arg1, iplen, ip);
     					m = args->m;
     				}
     				/* FALLTHROUGH */
    @@ -3389,7 +2041,7 @@ check_body:
     				if (hlen > 0 && is_ipv6 &&
     				    ((offset & IP6F_OFF_MASK) == 0) &&
     				    (proto != IPPROTO_ICMPV6 ||
    -				     (is_icmp6_query(args->f_id.flags) == 1)) &&
    +				     (is_icmp6_query(icmp6_type) == 1)) &&
     				    !(m->m_flags & (M_BCAST|M_MCAST)) &&
     				    !IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
     					send_reject6(
    @@ -3401,41 +2053,41 @@ check_body:
     #endif
     			case O_DENY:
     				retval = IP_FW_DENY;
    -				goto done;
    +				l = 0;		/* exit inner loop */
    +				done = 1;	/* exit outer loop */
    +				break;
     
    -			case O_FORWARD_IP: {
    -				struct sockaddr_in *sa;
    -				sa = &(((ipfw_insn_sa *)cmd)->sa);
    +			case O_FORWARD_IP:
     				if (args->eh)	/* not valid on layer2 pkts */
     					break;
     				if (!q || dyn_dir == MATCH_FORWARD) {
    -					if (sa->sin_addr.s_addr == INADDR_ANY) {
    -						bcopy(sa, &args->hopstore,
    +				    struct sockaddr_in *sa;
    +				    sa = &(((ipfw_insn_sa *)cmd)->sa);
    +				    if (sa->sin_addr.s_addr == INADDR_ANY) {
    +					bcopy(sa, &args->hopstore,
     							sizeof(*sa));
    -						args->hopstore.sin_addr.s_addr =
    +					args->hopstore.sin_addr.s_addr =
     						    htonl(tablearg);
    -						args->next_hop =
    -						    &args->hopstore;
    -					} else {
    -						args->next_hop = sa;
    -					}
    +					args->next_hop = &args->hopstore;
    +				    } else {
    +					args->next_hop = sa;
    +				    }
     				}
     				retval = IP_FW_PASS;
    -			    }
    -			    goto done;
    +				l = 0;          /* exit inner loop */
    +				done = 1;       /* exit outer loop */
    +				break;
     
     			case O_NETGRAPH:
     			case O_NGTEE:
    -				args->rule = f;	/* report matching rule */
    -				args->rule_id = f->id;
    -				args->chain_id = chain->id;
    -				if (cmd->arg1 == IP_FW_TABLEARG)
    -					args->cookie = tablearg;
    -				else
    -					args->cookie = cmd->arg1;
    +				set_match(args, f_pos, chain);
    +				args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
    +					tablearg : cmd->arg1;
     				retval = (cmd->opcode == O_NETGRAPH) ?
     				    IP_FW_NETGRAPH : IP_FW_NGTEE;
    -				goto done;
    +				l = 0;          /* exit inner loop */
    +				done = 1;       /* exit outer loop */
    +				break;
     
     			case O_SETFIB:
     				f->pcnt++;	/* update stats */
    @@ -3443,88 +2095,86 @@ check_body:
     				f->timestamp = time_uptime;
     				M_SETFIB(m, cmd->arg1);
     				args->f_id.fib = cmd->arg1;
    -				goto next_rule;
    +				l = 0;		/* exit inner loop */
    +				break;
     
    -			case O_NAT: {
    -                        	struct cfg_nat *t;
    -                        	int nat_id;
    +			case O_NAT:
    + 				if (!IPFW_NAT_LOADED) {
    +				    retval = IP_FW_DENY;
    +				} else {
    +				    struct cfg_nat *t;
    +				    int nat_id;
    +
    +				    set_match(args, f_pos, chain);
    +				    t = ((ipfw_insn_nat *)cmd)->nat;
    +				    if (t == NULL) {
    +					nat_id = (cmd->arg1 == IP_FW_TABLEARG) ?
    +						tablearg : cmd->arg1;
    +					t = (*lookup_nat_ptr)(&chain->nat, nat_id);
     
    - 				if (IPFW_NAT_LOADED) {
    -					args->rule = f; /* Report matching rule. */
    -					args->rule_id = f->id;
    -					args->chain_id = chain->id;
    -					t = ((ipfw_insn_nat *)cmd)->nat;
     					if (t == NULL) {
    -						nat_id = (cmd->arg1 == IP_FW_TABLEARG) ?
    -						    tablearg : cmd->arg1;
    -						LOOKUP_NAT(V_layer3_chain, nat_id, t);
    -						if (t == NULL) {
    -							retval = IP_FW_DENY;
    -							goto done;
    -						}
    -						if (cmd->arg1 != IP_FW_TABLEARG)
    -							((ipfw_insn_nat *)cmd)->nat = t;
    +					    retval = IP_FW_DENY;
    +					    l = 0;	/* exit inner loop */
    +					    done = 1;	/* exit outer loop */
    +					    break;
     					}
    -					retval = ipfw_nat_ptr(args, t, m);
    -				} else
    -					retval = IP_FW_DENY;
    -				goto done;
    -			}
    +					if (cmd->arg1 != IP_FW_TABLEARG)
    +					    ((ipfw_insn_nat *)cmd)->nat = t;
    +				    }
    +				    retval = ipfw_nat_ptr(args, t, m);
    +				}
    +				l = 0;          /* exit inner loop */
    +				done = 1;       /* exit outer loop */
    +				break;
     
     			case O_REASS: {
     				int ip_off;
     
     				f->pcnt++;
     				f->bcnt += pktlen;
    -				ip_off = (args->eh != NULL) ? ntohs(ip->ip_off) : ip->ip_off;
    -				if (ip_off & (IP_MF | IP_OFFMASK)) {
    -					/* 
    -					 * ip_reass() expects len & off in host
    -					 * byte order: fix them in case we come
    -					 * from layer2.
    -					 */
    -					if (args->eh != NULL) {
    -						ip->ip_len = ntohs(ip->ip_len);
    -						ip->ip_off = ntohs(ip->ip_off);
    -					}
    +				l = 0;	/* in any case exit inner loop */
    +				ip_off = ntohs(ip->ip_off);
     
    -					m = ip_reass(m);
    -					args->m = m;
    -					
    -					/*
    -					 * IP header checksum fixup after 
    -					 * reassembly and leave header
    -					 * in network byte order.
    -					 */
    -					if (m != NULL) {
    -						int hlen;
    -					
    -						ip = mtod(m, struct ip *);
    -						hlen = ip->ip_hl << 2;
    -						/* revert len & off for layer2 pkts */
    -						if (args->eh != NULL)
    -							ip->ip_len = htons(ip->ip_len);
    -						ip->ip_sum = 0;
    -						if (hlen == sizeof(struct ip))
    -							ip->ip_sum = in_cksum_hdr(ip);
    -						else
    -							ip->ip_sum = in_cksum(m, hlen);
    -						retval = IP_FW_REASS;
    -						args->rule = f;
    -						args->rule_id = f->id;
    -						args->chain_id = chain->id;
    -						goto done;
    -					} else {
    -						retval = IP_FW_DENY;
    -						goto done;
    -					}
    +				/* if not fragmented, go to next rule */
    +				if ((ip_off & (IP_MF | IP_OFFMASK)) == 0)
    +				    break;
    +				/* 
    +				 * ip_reass() expects len & off in host
    +				 * byte order.
    +				 */
    +				SET_HOST_IPLEN(ip);
    +
    +				args->m = m = ip_reass(m);
    +
    +				/*
    +				 * do IP header checksum fixup.
    +				 */
    +				if (m == NULL) { /* fragment got swallowed */
    +				    retval = IP_FW_DENY;
    +				} else { /* good, packet complete */
    +				    int hlen;
    +
    +				    ip = mtod(m, struct ip *);
    +				    hlen = ip->ip_hl << 2;
    +				    SET_NET_IPLEN(ip);
    +				    ip->ip_sum = 0;
    +				    if (hlen == sizeof(struct ip))
    +					ip->ip_sum = in_cksum_hdr(ip);
    +				    else
    +					ip->ip_sum = in_cksum(m, hlen);
    +				    retval = IP_FW_REASS;
    +				    set_match(args, f_pos, chain);
     				}
    -				goto next_rule;
    +				done = 1;	/* exit outer loop */
    +				break;
     			}
     
     			default:
     				panic("-- unknown opcode %d\n", cmd->opcode);
     			} /* end of switch() on opcodes */
    +			/*
    +			 * if we get here with l=0, then match is irrelevant.
    +			 */
     
     			if (cmd->len & F_NOT)
     				match = !match;
    @@ -3537,25 +2187,30 @@ check_body:
     					break;		/* try next rule    */
     			}
     
    -		}	/* end of inner for, scan opcodes */
    +		}	/* end of inner loop, scan opcodes */
     
    -next_rule:;		/* try next rule		*/
    +		if (done)
    +			break;
    +
    +/* next_rule:; */	/* try next rule		*/
     
     	}		/* end of outer for, scan rules */
    -	printf("ipfw: ouch!, skip past end of rules, denying packet\n");
    -	IPFW_RUNLOCK(chain);
    -	if (ucred_cache != NULL)
    -		crfree(ucred_cache);
    -	return (IP_FW_DENY);
     
    -done:
    -	/* Update statistics */
    -	f->pcnt++;
    -	f->bcnt += pktlen;
    -	f->timestamp = time_uptime;
    +	if (done) {
    +		struct ip_fw *rule = chain->map[f_pos];
    +		/* Update statistics */
    +		rule->pcnt++;
    +		rule->bcnt += pktlen;
    +		rule->timestamp = time_uptime;
    +	} else {
    +		retval = IP_FW_DENY;
    +		printf("ipfw: ouch!, skip past end of rules, denying packet\n");
    +	}
     	IPFW_RUNLOCK(chain);
    +#ifdef __FreeBSD__
     	if (ucred_cache != NULL)
     		crfree(ucred_cache);
    +#endif
     	return (retval);
     
     pullup_failed:
    @@ -3565,1150 +2220,10 @@ pullup_failed:
     }
     
     /*
    - * When a rule is added/deleted, clear the next_rule pointers in all rules.
    - * These will be reconstructed on the fly as packets are matched.
    + * Module and VNET glue
      */
    -static void
    -flush_rule_ptrs(struct ip_fw_chain *chain)
    -{
    -	struct ip_fw *rule;
    -
    -	IPFW_WLOCK_ASSERT(chain);
    -
    -	chain->id++;
    -
    -	for (rule = chain->rules; rule; rule = rule->next)
    -		rule->next_rule = NULL;
    -}
     
     /*
    - * Add a new rule to the list. Copy the rule into a malloc'ed area, then
    - * possibly create a rule number and add the rule to the list.
    - * Update the rule_number in the input struct so the caller knows it as well.
    - */
    -static int
    -add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule)
    -{
    -	struct ip_fw *rule, *f, *prev;
    -	int l = RULESIZE(input_rule);
    -
    -	if (chain->rules == NULL && input_rule->rulenum != IPFW_DEFAULT_RULE)
    -		return (EINVAL);
    -
    -	rule = malloc(l, M_IPFW, M_NOWAIT | M_ZERO);
    -	if (rule == NULL)
    -		return (ENOSPC);
    -
    -	bcopy(input_rule, rule, l);
    -
    -	rule->next = NULL;
    -	rule->next_rule = NULL;
    -
    -	rule->pcnt = 0;
    -	rule->bcnt = 0;
    -	rule->timestamp = 0;
    -
    -	IPFW_WLOCK(chain);
    -
    -	if (chain->rules == NULL) {	/* default rule */
    -		chain->rules = rule;
    -		rule->id = ++chain->id;
    -		goto done;
    -        }
    -
    -	/*
    -	 * If rulenum is 0, find highest numbered rule before the
    -	 * default rule, and add autoinc_step
    -	 */
    -	if (V_autoinc_step < 1)
    -		V_autoinc_step = 1;
    -	else if (V_autoinc_step > 1000)
    -		V_autoinc_step = 1000;
    -	if (rule->rulenum == 0) {
    -		/*
    -		 * locate the highest numbered rule before default
    -		 */
    -		for (f = chain->rules; f; f = f->next) {
    -			if (f->rulenum == IPFW_DEFAULT_RULE)
    -				break;
    -			rule->rulenum = f->rulenum;
    -		}
    -		if (rule->rulenum < IPFW_DEFAULT_RULE - V_autoinc_step)
    -			rule->rulenum += V_autoinc_step;
    -		input_rule->rulenum = rule->rulenum;
    -	}
    -
    -	/*
    -	 * Now insert the new rule in the right place in the sorted list.
    -	 */
    -	for (prev = NULL, f = chain->rules; f; prev = f, f = f->next) {
    -		if (f->rulenum > rule->rulenum) { /* found the location */
    -			if (prev) {
    -				rule->next = f;
    -				prev->next = rule;
    -			} else { /* head insert */
    -				rule->next = chain->rules;
    -				chain->rules = rule;
    -			}
    -			break;
    -		}
    -	}
    -	flush_rule_ptrs(chain);
    -	/* chain->id incremented inside flush_rule_ptrs() */
    -	rule->id = chain->id;
    -done:
    -	V_static_count++;
    -	V_static_len += l;
    -	IPFW_WUNLOCK(chain);
    -	DEB(printf("ipfw: installed rule %d, static count now %d\n",
    -		rule->rulenum, V_static_count);)
    -	return (0);
    -}
    -
    -/**
    - * Remove a static rule (including derived * dynamic rules)
    - * and place it on the ``reap list'' for later reclamation.
    - * The caller is in charge of clearing rule pointers to avoid
    - * dangling pointers.
    - * @return a pointer to the next entry.
    - * Arguments are not checked, so they better be correct.
    - */
    -static struct ip_fw *
    -remove_rule(struct ip_fw_chain *chain, struct ip_fw *rule,
    -    struct ip_fw *prev)
    -{
    -	struct ip_fw *n;
    -	int l = RULESIZE(rule);
    -
    -	IPFW_WLOCK_ASSERT(chain);
    -
    -	n = rule->next;
    -	IPFW_DYN_LOCK();
    -	remove_dyn_rule(rule, NULL /* force removal */);
    -	IPFW_DYN_UNLOCK();
    -	if (prev == NULL)
    -		chain->rules = n;
    -	else
    -		prev->next = n;
    -	V_static_count--;
    -	V_static_len -= l;
    -
    -	rule->next = chain->reap;
    -	chain->reap = rule;
    -
    -	return n;
    -}
    -
    -/*
    - * Reclaim storage associated with a list of rules.  This is
    - * typically the list created using remove_rule.
    - * A NULL pointer on input is handled correctly.
    - */
    -static void
    -reap_rules(struct ip_fw *head)
    -{
    -	struct ip_fw *rule;
    -
    -	while ((rule = head) != NULL) {
    -		head = head->next;
    -		free(rule, M_IPFW);
    -	}
    -}
    -
    -/*
    - * Remove all rules from a chain (except rules in set RESVD_SET
    - * unless kill_default = 1).  The caller is responsible for
    - * reclaiming storage for the rules left in chain->reap.
    - */
    -static void
    -free_chain(struct ip_fw_chain *chain, int kill_default)
    -{
    -	struct ip_fw *prev, *rule;
    -
    -	IPFW_WLOCK_ASSERT(chain);
    -
    -	chain->reap = NULL;
    -	flush_rule_ptrs(chain); /* more efficient to do outside the loop */
    -	for (prev = NULL, rule = chain->rules; rule ; )
    -		if (kill_default || rule->set != RESVD_SET)
    -			rule = remove_rule(chain, rule, prev);
    -		else {
    -			prev = rule;
    -			rule = rule->next;
    -		}
    -}
    -
    -/**
    - * Remove all rules with given number, and also do set manipulation.
    - * Assumes chain != NULL && *chain != NULL.
    - *
    - * The argument is an u_int32_t. The low 16 bit are the rule or set number,
    - * the next 8 bits are the new set, the top 8 bits are the command:
    - *
    - *	0	delete rules with given number
    - *	1	delete rules with given set number
    - *	2	move rules with given number to new set
    - *	3	move rules with given set number to new set
    - *	4	swap sets with given numbers
    - *	5	delete rules with given number and with given set number
    - */
    -static int
    -del_entry(struct ip_fw_chain *chain, u_int32_t arg)
    -{
    -	struct ip_fw *prev = NULL, *rule;
    -	u_int16_t rulenum;	/* rule or old_set */
    -	u_int8_t cmd, new_set;
    -
    -	rulenum = arg & 0xffff;
    -	cmd = (arg >> 24) & 0xff;
    -	new_set = (arg >> 16) & 0xff;
    -
    -	if (cmd > 5 || new_set > RESVD_SET)
    -		return EINVAL;
    -	if (cmd == 0 || cmd == 2 || cmd == 5) {
    -		if (rulenum >= IPFW_DEFAULT_RULE)
    -			return EINVAL;
    -	} else {
    -		if (rulenum > RESVD_SET)	/* old_set */
    -			return EINVAL;
    -	}
    -
    -	IPFW_WLOCK(chain);
    -	rule = chain->rules;	/* common starting point */
    -	chain->reap = NULL;	/* prepare for deletions */
    -	switch (cmd) {
    -	case 0:	/* delete rules with given number */
    -		/*
    -		 * locate first rule to delete
    -		 */
    -		for (; rule->rulenum < rulenum; prev = rule, rule = rule->next)
    -			;
    -		if (rule->rulenum != rulenum) {
    -			IPFW_WUNLOCK(chain);
    -			return EINVAL;
    -		}
    -
    -		/*
    -		 * flush pointers outside the loop, then delete all matching
    -		 * rules. prev remains the same throughout the cycle.
    -		 */
    -		flush_rule_ptrs(chain);
    -		while (rule->rulenum == rulenum)
    -			rule = remove_rule(chain, rule, prev);
    -		break;
    -
    -	case 1:	/* delete all rules with given set number */
    -		flush_rule_ptrs(chain);
    -		while (rule->rulenum < IPFW_DEFAULT_RULE) {
    -			if (rule->set == rulenum)
    -				rule = remove_rule(chain, rule, prev);
    -			else {
    -				prev = rule;
    -				rule = rule->next;
    -			}
    -		}
    -		break;
    -
    -	case 2:	/* move rules with given number to new set */
    -		for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
    -			if (rule->rulenum == rulenum)
    -				rule->set = new_set;
    -		break;
    -
    -	case 3: /* move rules with given set number to new set */
    -		for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
    -			if (rule->set == rulenum)
    -				rule->set = new_set;
    -		break;
    -
    -	case 4: /* swap two sets */
    -		for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
    -			if (rule->set == rulenum)
    -				rule->set = new_set;
    -			else if (rule->set == new_set)
    -				rule->set = rulenum;
    -		break;
    -
    -	case 5: /* delete rules with given number and with given set number.
    -		 * rulenum - given rule number;
    -		 * new_set - given set number.
    -		 */
    -		for (; rule->rulenum < rulenum; prev = rule, rule = rule->next)
    -			;
    -		if (rule->rulenum != rulenum) {
    -			IPFW_WUNLOCK(chain);
    -			return (EINVAL);
    -		}
    -		flush_rule_ptrs(chain);
    -		while (rule->rulenum == rulenum) {
    -			if (rule->set == new_set)
    -				rule = remove_rule(chain, rule, prev);
    -			else {
    -				prev = rule;
    -				rule = rule->next;
    -			}
    -		}
    -	}
    -	/*
    -	 * Look for rules to reclaim.  We grab the list before
    -	 * releasing the lock then reclaim them w/o the lock to
    -	 * avoid a LOR with dummynet.
    -	 */
    -	rule = chain->reap;
    -	IPFW_WUNLOCK(chain);
    -	reap_rules(rule);
    -	return 0;
    -}
    -
    -/*
    - * Clear counters for a specific rule.
    - * The enclosing "table" is assumed locked.
    - */
    -static void
    -clear_counters(struct ip_fw *rule, int log_only)
    -{
    -	ipfw_insn_log *l = (ipfw_insn_log *)ACTION_PTR(rule);
    -
    -	if (log_only == 0) {
    -		rule->bcnt = rule->pcnt = 0;
    -		rule->timestamp = 0;
    -	}
    -	if (l->o.opcode == O_LOG)
    -		l->log_left = l->max_log;
    -}
    -
    -/**
    - * Reset some or all counters on firewall rules.
    - * The argument `arg' is an u_int32_t. The low 16 bit are the rule number,
    - * the next 8 bits are the set number, the top 8 bits are the command:
    - *	0	work with rules from all set's;
    - *	1	work with rules only from specified set.
    - * Specified rule number is zero if we want to clear all entries.
    - * log_only is 1 if we only want to reset logs, zero otherwise.
    - */
    -static int
    -zero_entry(struct ip_fw_chain *chain, u_int32_t arg, int log_only)
    -{
    -	struct ip_fw *rule;
    -	char *msg;
    -
    -	uint16_t rulenum = arg & 0xffff;
    -	uint8_t set = (arg >> 16) & 0xff;
    -	uint8_t cmd = (arg >> 24) & 0xff;
    -
    -	if (cmd > 1)
    -		return (EINVAL);
    -	if (cmd == 1 && set > RESVD_SET)
    -		return (EINVAL);
    -
    -	IPFW_WLOCK(chain);
    -	if (rulenum == 0) {
    -		V_norule_counter = 0;
    -		for (rule = chain->rules; rule; rule = rule->next) {
    -			/* Skip rules from another set. */
    -			if (cmd == 1 && rule->set != set)
    -				continue;
    -			clear_counters(rule, log_only);
    -		}
    -		msg = log_only ? "All logging counts reset" :
    -		    "Accounting cleared";
    -	} else {
    -		int cleared = 0;
    -		/*
    -		 * We can have multiple rules with the same number, so we
    -		 * need to clear them all.
    -		 */
    -		for (rule = chain->rules; rule; rule = rule->next)
    -			if (rule->rulenum == rulenum) {
    -				while (rule && rule->rulenum == rulenum) {
    -					if (cmd == 0 || rule->set == set)
    -						clear_counters(rule, log_only);
    -					rule = rule->next;
    -				}
    -				cleared = 1;
    -				break;
    -			}
    -		if (!cleared) {	/* we did not find any matching rules */
    -			IPFW_WUNLOCK(chain);
    -			return (EINVAL);
    -		}
    -		msg = log_only ? "logging count reset" : "cleared";
    -	}
    -	IPFW_WUNLOCK(chain);
    -
    -	if (V_fw_verbose) {
    -		int lev = LOG_SECURITY | LOG_NOTICE;
    -
    -		if (rulenum)
    -			log(lev, "ipfw: Entry %d %s.\n", rulenum, msg);
    -		else
    -			log(lev, "ipfw: %s.\n", msg);
    -	}
    -	return (0);
    -}
    -
    -/*
    - * Check validity of the structure before insert.
    - * Fortunately rules are simple, so this mostly need to check rule sizes.
    - */
    -static int
    -check_ipfw_struct(struct ip_fw *rule, int size)
    -{
    -	int l, cmdlen = 0;
    -	int have_action=0;
    -	ipfw_insn *cmd;
    -
    -	if (size < sizeof(*rule)) {
    -		printf("ipfw: rule too short\n");
    -		return (EINVAL);
    -	}
    -	/* first, check for valid size */
    -	l = RULESIZE(rule);
    -	if (l != size) {
    -		printf("ipfw: size mismatch (have %d want %d)\n", size, l);
    -		return (EINVAL);
    -	}
    -	if (rule->act_ofs >= rule->cmd_len) {
    -		printf("ipfw: bogus action offset (%u > %u)\n",
    -		    rule->act_ofs, rule->cmd_len - 1);
    -		return (EINVAL);
    -	}
    -	/*
    -	 * Now go for the individual checks. Very simple ones, basically only
    -	 * instruction sizes.
    -	 */
    -	for (l = rule->cmd_len, cmd = rule->cmd ;
    -			l > 0 ; l -= cmdlen, cmd += cmdlen) {
    -		cmdlen = F_LEN(cmd);
    -		if (cmdlen > l) {
    -			printf("ipfw: opcode %d size truncated\n",
    -			    cmd->opcode);
    -			return EINVAL;
    -		}
    -		DEB(printf("ipfw: opcode %d\n", cmd->opcode);)
    -		switch (cmd->opcode) {
    -		case O_PROBE_STATE:
    -		case O_KEEP_STATE:
    -		case O_PROTO:
    -		case O_IP_SRC_ME:
    -		case O_IP_DST_ME:
    -		case O_LAYER2:
    -		case O_IN:
    -		case O_FRAG:
    -		case O_DIVERTED:
    -		case O_IPOPT:
    -		case O_IPTOS:
    -		case O_IPPRECEDENCE:
    -		case O_IPVER:
    -		case O_TCPWIN:
    -		case O_TCPFLAGS:
    -		case O_TCPOPTS:
    -		case O_ESTAB:
    -		case O_VERREVPATH:
    -		case O_VERSRCREACH:
    -		case O_ANTISPOOF:
    -		case O_IPSEC:
    -#ifdef INET6
    -		case O_IP6_SRC_ME:
    -		case O_IP6_DST_ME:
    -		case O_EXT_HDR:
    -		case O_IP6:
    -#endif
    -		case O_IP4:
    -		case O_TAG:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    -				goto bad_size;
    -			break;
    -
    -		case O_FIB:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    -				goto bad_size;
    -			if (cmd->arg1 >= rt_numfibs) {
    -				printf("ipfw: invalid fib number %d\n",
    -					cmd->arg1);
    -				return EINVAL;
    -			}
    -			break;
    -
    -		case O_SETFIB:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    -				goto bad_size;
    -			if (cmd->arg1 >= rt_numfibs) {
    -				printf("ipfw: invalid fib number %d\n",
    -					cmd->arg1);
    -				return EINVAL;
    -			}
    -			goto check_action;
    -
    -		case O_UID:
    -		case O_GID:
    -		case O_JAIL:
    -		case O_IP_SRC:
    -		case O_IP_DST:
    -		case O_TCPSEQ:
    -		case O_TCPACK:
    -		case O_PROB:
    -		case O_ICMPTYPE:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_u32))
    -				goto bad_size;
    -			break;
    -
    -		case O_LIMIT:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_limit))
    -				goto bad_size;
    -			break;
    -
    -		case O_LOG:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_log))
    -				goto bad_size;
    -
    -			((ipfw_insn_log *)cmd)->log_left =
    -			    ((ipfw_insn_log *)cmd)->max_log;
    -
    -			break;
    -
    -		case O_IP_SRC_MASK:
    -		case O_IP_DST_MASK:
    -			/* only odd command lengths */
    -			if ( !(cmdlen & 1) || cmdlen > 31)
    -				goto bad_size;
    -			break;
    -
    -		case O_IP_SRC_SET:
    -		case O_IP_DST_SET:
    -			if (cmd->arg1 == 0 || cmd->arg1 > 256) {
    -				printf("ipfw: invalid set size %d\n",
    -					cmd->arg1);
    -				return EINVAL;
    -			}
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
    -			    (cmd->arg1+31)/32 )
    -				goto bad_size;
    -			break;
    -
    -		case O_IP_SRC_LOOKUP:
    -		case O_IP_DST_LOOKUP:
    -			if (cmd->arg1 >= IPFW_TABLES_MAX) {
    -				printf("ipfw: invalid table number %d\n",
    -				    cmd->arg1);
    -				return (EINVAL);
    -			}
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn) &&
    -			    cmdlen != F_INSN_SIZE(ipfw_insn_u32))
    -				goto bad_size;
    -			break;
    -
    -		case O_MACADDR2:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_mac))
    -				goto bad_size;
    -			break;
    -
    -		case O_NOP:
    -		case O_IPID:
    -		case O_IPTTL:
    -		case O_IPLEN:
    -		case O_TCPDATALEN:
    -		case O_TAGGED:
    -			if (cmdlen < 1 || cmdlen > 31)
    -				goto bad_size;
    -			break;
    -
    -		case O_MAC_TYPE:
    -		case O_IP_SRCPORT:
    -		case O_IP_DSTPORT: /* XXX artificial limit, 30 port pairs */
    -			if (cmdlen < 2 || cmdlen > 31)
    -				goto bad_size;
    -			break;
    -
    -		case O_RECV:
    -		case O_XMIT:
    -		case O_VIA:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_if))
    -				goto bad_size;
    -			break;
    -
    -		case O_ALTQ:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_altq))
    -				goto bad_size;
    -			break;
    -
    -		case O_PIPE:
    -		case O_QUEUE:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    -				goto bad_size;
    -			goto check_action;
    -
    -		case O_FORWARD_IP:
    -#ifdef	IPFIREWALL_FORWARD
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_sa))
    -				goto bad_size;
    -			goto check_action;
    -#else
    -			return EINVAL;
    -#endif
    -
    -		case O_DIVERT:
    -		case O_TEE:
    -			if (ip_divert_ptr == NULL)
    -				return EINVAL;
    -			else
    -				goto check_size;
    -		case O_NETGRAPH:
    -		case O_NGTEE:
    -			if (!NG_IPFW_LOADED)
    -				return EINVAL;
    -			else
    -				goto check_size;
    -		case O_NAT:
    -			if (!IPFW_NAT_LOADED)
    -				return EINVAL;
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_nat))
    - 				goto bad_size;		
    - 			goto check_action;
    -		case O_FORWARD_MAC: /* XXX not implemented yet */
    -		case O_CHECK_STATE:
    -		case O_COUNT:
    -		case O_ACCEPT:
    -		case O_DENY:
    -		case O_REJECT:
    -#ifdef INET6
    -		case O_UNREACH6:
    -#endif
    -		case O_SKIPTO:
    -		case O_REASS:
    -check_size:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    -				goto bad_size;
    -check_action:
    -			if (have_action) {
    -				printf("ipfw: opcode %d, multiple actions"
    -					" not allowed\n",
    -					cmd->opcode);
    -				return EINVAL;
    -			}
    -			have_action = 1;
    -			if (l != cmdlen) {
    -				printf("ipfw: opcode %d, action must be"
    -					" last opcode\n",
    -					cmd->opcode);
    -				return EINVAL;
    -			}
    -			break;
    -#ifdef INET6
    -		case O_IP6_SRC:
    -		case O_IP6_DST:
    -			if (cmdlen != F_INSN_SIZE(struct in6_addr) +
    -			    F_INSN_SIZE(ipfw_insn))
    -				goto bad_size;
    -			break;
    -
    -		case O_FLOW6ID:
    -			if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
    -			    ((ipfw_insn_u32 *)cmd)->o.arg1)
    -				goto bad_size;
    -			break;
    -
    -		case O_IP6_SRC_MASK:
    -		case O_IP6_DST_MASK:
    -			if ( !(cmdlen & 1) || cmdlen > 127)
    -				goto bad_size;
    -			break;
    -		case O_ICMP6TYPE:
    -			if( cmdlen != F_INSN_SIZE( ipfw_insn_icmp6 ) )
    -				goto bad_size;
    -			break;
    -#endif
    -
    -		default:
    -			switch (cmd->opcode) {
    -#ifndef INET6
    -			case O_IP6_SRC_ME:
    -			case O_IP6_DST_ME:
    -			case O_EXT_HDR:
    -			case O_IP6:
    -			case O_UNREACH6:
    -			case O_IP6_SRC:
    -			case O_IP6_DST:
    -			case O_FLOW6ID:
    -			case O_IP6_SRC_MASK:
    -			case O_IP6_DST_MASK:
    -			case O_ICMP6TYPE:
    -				printf("ipfw: no IPv6 support in kernel\n");
    -				return EPROTONOSUPPORT;
    -#endif
    -			default:
    -				printf("ipfw: opcode %d, unknown opcode\n",
    -					cmd->opcode);
    -				return EINVAL;
    -			}
    -		}
    -	}
    -	if (have_action == 0) {
    -		printf("ipfw: missing action\n");
    -		return EINVAL;
    -	}
    -	return 0;
    -
    -bad_size:
    -	printf("ipfw: opcode %d size %d wrong\n",
    -		cmd->opcode, cmdlen);
    -	return EINVAL;
    -}
    -
    -/*
    - * Copy the static and dynamic rules to the supplied buffer
    - * and return the amount of space actually used.
    - */
    -static size_t
    -ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
    -{
    -	char *bp = buf;
    -	char *ep = bp + space;
    -	struct ip_fw *rule;
    -	int i;
    -	time_t	boot_seconds;
    -
    -        boot_seconds = boottime.tv_sec;
    -	/* XXX this can take a long time and locking will block packet flow */
    -	IPFW_RLOCK(chain);
    -	for (rule = chain->rules; rule ; rule = rule->next) {
    -		/*
    -		 * Verify the entry fits in the buffer in case the
    -		 * rules changed between calculating buffer space and
    -		 * now.  This would be better done using a generation
    -		 * number but should suffice for now.
    -		 */
    -		i = RULESIZE(rule);
    -		if (bp + i <= ep) {
    -			bcopy(rule, bp, i);
    -			/*
    -			 * XXX HACK. Store the disable mask in the "next"
    -			 * pointer in a wild attempt to keep the ABI the same.
    -			 * Why do we do this on EVERY rule?
    -			 */
    -			bcopy(&V_set_disable,
    -			    &(((struct ip_fw *)bp)->next_rule),
    -			    sizeof(V_set_disable));
    -			if (((struct ip_fw *)bp)->timestamp)
    -				((struct ip_fw *)bp)->timestamp += boot_seconds;
    -			bp += i;
    -		}
    -	}
    -	IPFW_RUNLOCK(chain);
    -	if (V_ipfw_dyn_v) {
    -		ipfw_dyn_rule *p, *last = NULL;
    -
    -		IPFW_DYN_LOCK();
    -		for (i = 0 ; i < V_curr_dyn_buckets; i++)
    -			for (p = V_ipfw_dyn_v[i] ; p != NULL; p = p->next) {
    -				if (bp + sizeof *p <= ep) {
    -					ipfw_dyn_rule *dst =
    -						(ipfw_dyn_rule *)bp;
    -					bcopy(p, dst, sizeof *p);
    -					bcopy(&(p->rule->rulenum), &(dst->rule),
    -					    sizeof(p->rule->rulenum));
    -					/*
    -					 * store set number into high word of
    -					 * dst->rule pointer.
    -					 */
    -					bcopy(&(p->rule->set),
    -					    (char *)&dst->rule +
    -					    sizeof(p->rule->rulenum),
    -					    sizeof(p->rule->set));
    -					/*
    -					 * store a non-null value in "next".
    -					 * The userland code will interpret a
    -					 * NULL here as a marker
    -					 * for the last dynamic rule.
    -					 */
    -					bcopy(&dst, &dst->next, sizeof(dst));
    -					last = dst;
    -					dst->expire =
    -					    TIME_LEQ(dst->expire, time_uptime) ?
    -						0 : dst->expire - time_uptime ;
    -					bp += sizeof(ipfw_dyn_rule);
    -				}
    -			}
    -		IPFW_DYN_UNLOCK();
    -		if (last != NULL) /* mark last dynamic rule */
    -			bzero(&last->next, sizeof(last));
    -	}
    -	return (bp - (char *)buf);
    -}
    -
    -
    -/**
    - * {set|get}sockopt parser.
    - */
    -static int
    -ipfw_ctl(struct sockopt *sopt)
    -{
    -#define	RULE_MAXSIZE	(256*sizeof(u_int32_t))
    -	int error;
    -	size_t size;
    -	struct ip_fw *buf, *rule;
    -	u_int32_t rulenum[2];
    -
    -	error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW);
    -	if (error)
    -		return (error);
    -
    -	/*
    -	 * Disallow modifications in really-really secure mode, but still allow
    -	 * the logging counters to be reset.
    -	 */
    -	if (sopt->sopt_name == IP_FW_ADD ||
    -	    (sopt->sopt_dir == SOPT_SET && sopt->sopt_name != IP_FW_RESETLOG)) {
    -		error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
    -		if (error)
    -			return (error);
    -	}
    -
    -	error = 0;
    -
    -	switch (sopt->sopt_name) {
    -	case IP_FW_GET:
    -		/*
    -		 * pass up a copy of the current rules. Static rules
    -		 * come first (the last of which has number IPFW_DEFAULT_RULE),
    -		 * followed by a possibly empty list of dynamic rule.
    -		 * The last dynamic rule has NULL in the "next" field.
    -		 *
    -		 * Note that the calculated size is used to bound the
    -		 * amount of data returned to the user.  The rule set may
    -		 * change between calculating the size and returning the
    -		 * data in which case we'll just return what fits.
    -		 */
    -		size = V_static_len;	/* size of static rules */
    -		if (V_ipfw_dyn_v)		/* add size of dyn.rules */
    -			size += (V_dyn_count * sizeof(ipfw_dyn_rule));
    -
    -		if (size >= sopt->sopt_valsize)
    -			break;
    -		/*
    -		 * XXX todo: if the user passes a short length just to know
    -		 * how much room is needed, do not bother filling up the
    -		 * buffer, just jump to the sooptcopyout.
    -		 */
    -		buf = malloc(size, M_TEMP, M_WAITOK);
    -		error = sooptcopyout(sopt, buf,
    -				ipfw_getrules(&V_layer3_chain, buf, size));
    -		free(buf, M_TEMP);
    -		break;
    -
    -	case IP_FW_FLUSH:
    -		/*
    -		 * Normally we cannot release the lock on each iteration.
    -		 * We could do it here only because we start from the head all
    -		 * the times so there is no risk of missing some entries.
    -		 * On the other hand, the risk is that we end up with
    -		 * a very inconsistent ruleset, so better keep the lock
    -		 * around the whole cycle.
    -		 *
    -		 * XXX this code can be improved by resetting the head of
    -		 * the list to point to the default rule, and then freeing
    -		 * the old list without the need for a lock.
    -		 */
    -
    -		IPFW_WLOCK(&V_layer3_chain);
    -		free_chain(&V_layer3_chain, 0 /* keep default rule */);
    -		rule = V_layer3_chain.reap;
    -		IPFW_WUNLOCK(&V_layer3_chain);
    -		reap_rules(rule);
    -		break;
    -
    -	case IP_FW_ADD:
    -		rule = malloc(RULE_MAXSIZE, M_TEMP, M_WAITOK);
    -		error = sooptcopyin(sopt, rule, RULE_MAXSIZE,
    -			sizeof(struct ip_fw) );
    -		if (error == 0)
    -			error = check_ipfw_struct(rule, sopt->sopt_valsize);
    -		if (error == 0) {
    -			error = add_rule(&V_layer3_chain, rule);
    -			size = RULESIZE(rule);
    -			if (!error && sopt->sopt_dir == SOPT_GET)
    -				error = sooptcopyout(sopt, rule, size);
    -		}
    -		free(rule, M_TEMP);
    -		break;
    -
    -	case IP_FW_DEL:
    -		/*
    -		 * IP_FW_DEL is used for deleting single rules or sets,
    -		 * and (ab)used to atomically manipulate sets. Argument size
    -		 * is used to distinguish between the two:
    -		 *    sizeof(u_int32_t)
    -		 *	delete single rule or set of rules,
    -		 *	or reassign rules (or sets) to a different set.
    -		 *    2*sizeof(u_int32_t)
    -		 *	atomic disable/enable sets.
    -		 *	first u_int32_t contains sets to be disabled,
    -		 *	second u_int32_t contains sets to be enabled.
    -		 */
    -		error = sooptcopyin(sopt, rulenum,
    -			2*sizeof(u_int32_t), sizeof(u_int32_t));
    -		if (error)
    -			break;
    -		size = sopt->sopt_valsize;
    -		if (size == sizeof(u_int32_t))	/* delete or reassign */
    -			error = del_entry(&V_layer3_chain, rulenum[0]);
    -		else if (size == 2*sizeof(u_int32_t)) /* set enable/disable */
    -			V_set_disable =
    -			    (V_set_disable | rulenum[0]) & ~rulenum[1] &
    -			    ~(1<sopt_val != 0) {
    -		    error = sooptcopyin(sopt, rulenum,
    -			    sizeof(u_int32_t), sizeof(u_int32_t));
    -		    if (error)
    -			break;
    -		}
    -		error = zero_entry(&V_layer3_chain, rulenum[0],
    -			sopt->sopt_name == IP_FW_RESETLOG);
    -		break;
    -
    -	case IP_FW_TABLE_ADD:
    -		{
    -			ipfw_table_entry ent;
    -
    -			error = sooptcopyin(sopt, &ent,
    -			    sizeof(ent), sizeof(ent));
    -			if (error)
    -				break;
    -			error = add_table_entry(&V_layer3_chain, ent.tbl,
    -			    ent.addr, ent.masklen, ent.value);
    -		}
    -		break;
    -
    -	case IP_FW_TABLE_DEL:
    -		{
    -			ipfw_table_entry ent;
    -
    -			error = sooptcopyin(sopt, &ent,
    -			    sizeof(ent), sizeof(ent));
    -			if (error)
    -				break;
    -			error = del_table_entry(&V_layer3_chain, ent.tbl,
    -			    ent.addr, ent.masklen);
    -		}
    -		break;
    -
    -	case IP_FW_TABLE_FLUSH:
    -		{
    -			u_int16_t tbl;
    -
    -			error = sooptcopyin(sopt, &tbl,
    -			    sizeof(tbl), sizeof(tbl));
    -			if (error)
    -				break;
    -			IPFW_WLOCK(&V_layer3_chain);
    -			error = flush_table(&V_layer3_chain, tbl);
    -			IPFW_WUNLOCK(&V_layer3_chain);
    -		}
    -		break;
    -
    -	case IP_FW_TABLE_GETSIZE:
    -		{
    -			u_int32_t tbl, cnt;
    -
    -			if ((error = sooptcopyin(sopt, &tbl, sizeof(tbl),
    -			    sizeof(tbl))))
    -				break;
    -			IPFW_RLOCK(&V_layer3_chain);
    -			error = count_table(&V_layer3_chain, tbl, &cnt);
    -			IPFW_RUNLOCK(&V_layer3_chain);
    -			if (error)
    -				break;
    -			error = sooptcopyout(sopt, &cnt, sizeof(cnt));
    -		}
    -		break;
    -
    -	case IP_FW_TABLE_LIST:
    -		{
    -			ipfw_table *tbl;
    -
    -			if (sopt->sopt_valsize < sizeof(*tbl)) {
    -				error = EINVAL;
    -				break;
    -			}
    -			size = sopt->sopt_valsize;
    -			tbl = malloc(size, M_TEMP, M_WAITOK);
    -			error = sooptcopyin(sopt, tbl, size, sizeof(*tbl));
    -			if (error) {
    -				free(tbl, M_TEMP);
    -				break;
    -			}
    -			tbl->size = (size - sizeof(*tbl)) /
    -			    sizeof(ipfw_table_entry);
    -			IPFW_RLOCK(&V_layer3_chain);
    -			error = dump_table(&V_layer3_chain, tbl);
    -			IPFW_RUNLOCK(&V_layer3_chain);
    -			if (error) {
    -				free(tbl, M_TEMP);
    -				break;
    -			}
    -			error = sooptcopyout(sopt, tbl, size);
    -			free(tbl, M_TEMP);
    -		}
    -		break;
    -
    -	case IP_FW_NAT_CFG:
    -		if (IPFW_NAT_LOADED)
    -			error = ipfw_nat_cfg_ptr(sopt);
    -		else {
    -			printf("IP_FW_NAT_CFG: %s\n",
    -			    "ipfw_nat not present, please load it");
    -			error = EINVAL;
    -		}
    -		break;
    -
    -	case IP_FW_NAT_DEL:
    -		if (IPFW_NAT_LOADED)
    -			error = ipfw_nat_del_ptr(sopt);
    -		else {
    -			printf("IP_FW_NAT_DEL: %s\n",
    -			    "ipfw_nat not present, please load it");
    -			error = EINVAL;
    -		}
    -		break;
    -
    -	case IP_FW_NAT_GET_CONFIG:
    -		if (IPFW_NAT_LOADED)
    -			error = ipfw_nat_get_cfg_ptr(sopt);
    -		else {
    -			printf("IP_FW_NAT_GET_CFG: %s\n",
    -			    "ipfw_nat not present, please load it");
    -			error = EINVAL;
    -		}
    -		break;
    -
    -	case IP_FW_NAT_GET_LOG:
    -		if (IPFW_NAT_LOADED)
    -			error = ipfw_nat_get_log_ptr(sopt);
    -		else {
    -			printf("IP_FW_NAT_GET_LOG: %s\n",
    -			    "ipfw_nat not present, please load it");
    -			error = EINVAL;
    -		}
    -		break;
    -
    -	default:
    -		printf("ipfw: ipfw_ctl invalid option %d\n", sopt->sopt_name);
    -		error = EINVAL;
    -	}
    -
    -	return (error);
    -#undef RULE_MAXSIZE
    -}
    -
    -
    -/*
    - * This procedure is only used to handle keepalives. It is invoked
    - * every dyn_keepalive_period
    - */
    -static void
    -ipfw_tick(void * vnetx) 
    -{
    -	struct mbuf *m0, *m, *mnext, **mtailp;
    -#ifdef INET6
    -	struct mbuf *m6, **m6_tailp;
    -#endif
    -	int i;
    -	ipfw_dyn_rule *q;
    -#ifdef VIMAGE
    -	struct vnet *vp = vnetx;
    -#endif
    -
    -	CURVNET_SET(vp);
    -	if (V_dyn_keepalive == 0 || V_ipfw_dyn_v == NULL || V_dyn_count == 0)
    -		goto done;
    -
    -	/*
    -	 * We make a chain of packets to go out here -- not deferring
    -	 * until after we drop the IPFW dynamic rule lock would result
    -	 * in a lock order reversal with the normal packet input -> ipfw
    -	 * call stack.
    -	 */
    -	m0 = NULL;
    -	mtailp = &m0;
    -#ifdef INET6
    -	m6 = NULL;
    -	m6_tailp = &m6;
    -#endif
    -	IPFW_DYN_LOCK();
    -	for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
    -		for (q = V_ipfw_dyn_v[i] ; q ; q = q->next ) {
    -			if (q->dyn_type == O_LIMIT_PARENT)
    -				continue;
    -			if (q->id.proto != IPPROTO_TCP)
    -				continue;
    -			if ( (q->state & BOTH_SYN) != BOTH_SYN)
    -				continue;
    -			if (TIME_LEQ(time_uptime + V_dyn_keepalive_interval,
    -			    q->expire))
    -				continue;	/* too early */
    -			if (TIME_LEQ(q->expire, time_uptime))
    -				continue;	/* too late, rule expired */
    -
    -			m = send_pkt(NULL, &(q->id), q->ack_rev - 1,
    -				q->ack_fwd, TH_SYN);
    -			mnext = send_pkt(NULL, &(q->id), q->ack_fwd - 1,
    -				q->ack_rev, 0);
    -
    -			switch (q->id.addr_type) {
    -			case 4:
    -				if (m != NULL) {
    -					*mtailp = m;
    -					mtailp = &(*mtailp)->m_nextpkt;
    -				}
    -				if (mnext != NULL) {
    -					*mtailp = mnext;
    -					mtailp = &(*mtailp)->m_nextpkt;
    -				}
    -				break;
    -#ifdef INET6
    -			case 6:
    -				if (m != NULL) {
    -					*m6_tailp = m;
    -					m6_tailp = &(*m6_tailp)->m_nextpkt;
    -				}
    -				if (mnext != NULL) {
    -					*m6_tailp = mnext;
    -					m6_tailp = &(*m6_tailp)->m_nextpkt;
    -				}
    -				break;
    -#endif
    -			}
    -
    -			m = mnext = NULL;
    -		}
    -	}
    -	IPFW_DYN_UNLOCK();
    -	for (m = mnext = m0; m != NULL; m = mnext) {
    -		mnext = m->m_nextpkt;
    -		m->m_nextpkt = NULL;
    -		ip_output(m, NULL, NULL, 0, NULL, NULL);
    -	}
    -#ifdef INET6
    -	for (m = mnext = m6; m != NULL; m = mnext) {
    -		mnext = m->m_nextpkt;
    -		m->m_nextpkt = NULL;
    -		ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
    -	}
    -#endif
    -done:
    -	callout_reset(&V_ipfw_timeout, V_dyn_keepalive_period * hz,
    -		      ipfw_tick, vnetx);
    -	CURVNET_RESTORE();
    -}
    -
    -/****************
      * Stuff that must be initialised only on boot or module load
      */
     static int
    @@ -4716,11 +2231,7 @@ ipfw_init(void)
     {
     	int error = 0;
     
    -	ipfw_dyn_rule_zone = uma_zcreate("IPFW dynamic rule",
    -	    sizeof(ipfw_dyn_rule), NULL, NULL, NULL, NULL,
    -	    UMA_ALIGN_PTR, 0);
    -
    -	IPFW_DYN_LOCK_INIT();
    +	ipfw_dyn_attach();
     	/*
      	 * Only print out this stuff the first time around,
     	 * when called from the sysinit code.
    @@ -4764,22 +2275,23 @@ ipfw_init(void)
     		printf("limited to %d packets/entry by default\n",
     		    V_verbose_limit);
     
    +	ipfw_log_bpf(1); /* init */
     	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();
    +	ipfw_log_bpf(0); /* uninit */
    +	ipfw_dyn_detach();
     	printf("IP firewall unloaded\n");
     }
     
    -/****************
    +/*
      * Stuff that must be initialized for every instance
      * (including the first of course).
      */
    @@ -4787,139 +2299,121 @@ static int
     vnet_ipfw_init(const void *unused)
     {
     	int error;
    -	struct ip_fw default_rule;
    +	struct ip_fw *rule = NULL;
    +	struct ip_fw_chain *chain;
    +
    +	chain = &V_layer3_chain;
     
     	/* First set up some values that are compile time options */
    +	V_autoinc_step = 100;	/* bounded to 1..1000 in add_rule() */
    +	V_fw_deny_unknown_exthdrs = 1;
     #ifdef IPFIREWALL_VERBOSE
     	V_fw_verbose = 1;
     #endif
     #ifdef IPFIREWALL_VERBOSE_LIMIT
     	V_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
     #endif
    +#ifdef IPFIREWALL_NAT
    +	LIST_INIT(&chain->nat);
    +#endif
     
    -	error = init_tables(&V_layer3_chain);
    +	/* insert the default rule and create the initial map */
    +	chain->n_rules = 1;
    +	chain->static_len = sizeof(struct ip_fw);
    +	chain->map = malloc(sizeof(struct ip_fw *), M_IPFW, M_NOWAIT | M_ZERO);
    +	if (chain->map)
    +		rule = malloc(chain->static_len, M_IPFW, M_NOWAIT | M_ZERO);
    +	if (rule == NULL) {
    +		if (chain->map)
    +			free(chain->map, M_IPFW);
    +		printf("ipfw2: ENOSPC initializing default rule "
    +			"(support disabled)\n");
    +		return (ENOSPC);
    +	}
    +	error = ipfw_init_tables(chain);
     	if (error) {
     		panic("init_tables"); /* XXX Marko fix this ! */
     	}
    -#ifdef IPFIREWALL_NAT
    -	LIST_INIT(&V_layer3_chain.nat);
    -#endif
     
    -	V_autoinc_step = 100;	/* bounded to 1..1000 in add_rule() */
    +	/* fill and insert the default rule */
    +	rule->act_ofs = 0;
    +	rule->rulenum = IPFW_DEFAULT_RULE;
    +	rule->cmd_len = 1;
    +	rule->set = RESVD_SET;
    +	rule->cmd[0].len = 1;
    +	rule->cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY;
    +	chain->rules = chain->default_rule = chain->map[0] = rule;
    +	chain->id = rule->id = 1;
     
    -	V_ipfw_dyn_v = NULL;
    -	V_dyn_buckets = 256;	/* must be power of 2 */
    -	V_curr_dyn_buckets = 256; /* must be power of 2 */
    -
    -	V_dyn_ack_lifetime = 300;
    -	V_dyn_syn_lifetime = 20;
    -	V_dyn_fin_lifetime = 1;
    -	V_dyn_rst_lifetime = 1;
    -	V_dyn_udp_lifetime = 10;
    -	V_dyn_short_lifetime = 5;
    -
    -	V_dyn_keepalive_interval = 20;
    -	V_dyn_keepalive_period = 5;
    -	V_dyn_keepalive = 1;	/* do send keepalives */
    -
    -	V_dyn_max = 4096;	/* max # of dynamic rules */
    -
    -	V_fw_deny_unknown_exthdrs = 1;
    -
    -	V_layer3_chain.rules = NULL;
    -	IPFW_LOCK_INIT(&V_layer3_chain);
    -	callout_init(&V_ipfw_timeout, CALLOUT_MPSAFE);
    -
    -	bzero(&default_rule, sizeof default_rule);
    -	default_rule.act_ofs = 0;
    -	default_rule.rulenum = IPFW_DEFAULT_RULE;
    -	default_rule.cmd_len = 1;
    -	default_rule.set = RESVD_SET;
    -	default_rule.cmd[0].len = 1;
    -	default_rule.cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY;
    -	error = add_rule(&V_layer3_chain, &default_rule);
    -
    -	if (error != 0) {
    -		printf("ipfw2: error %u initializing default rule "
    -			"(support disabled)\n", error);
    -		IPFW_LOCK_DESTROY(&V_layer3_chain);
    -		printf("leaving ipfw_iattach (1) with error %d\n", error);
    -		return (error);
    -	}
    -
    -	ip_fw_default_rule = V_layer3_chain.rules;
    -
    -	if (error) {
    -		IPFW_LOCK_DESTROY(&V_layer3_chain);
    -		printf("leaving ipfw_iattach (2) with error %d\n", error);
    -		return (error);
    -	}
    -#ifdef VIMAGE  /* want a better way to do this */
    -	callout_reset(&V_ipfw_timeout, hz, ipfw_tick, curvnet);	
    -#else
    -	callout_reset(&V_ipfw_timeout, hz, ipfw_tick, NULL);	
    -#endif
    +	IPFW_LOCK_INIT(chain);
    +	ipfw_dyn_init();
     
     	/* First set up some values that are compile time options */
     	V_ipfw_vnet_ready = 1;		/* Open for business */
     
    -	/* Hook up the raw inputs */
    +	/*
    +	 * Hook the sockopt handler, and the layer2 (V_ip_fw_chk_ptr)
    +	 * and pfil hooks for ipv4 and ipv6. Even if the latter two fail
    +	 * we still keep the module alive because the sockopt and
    +	 * layer2 paths are still useful.
    +	 * ipfw[6]_hook return 0 on success, ENOENT on failure,
    +	 * so we can ignore the exact return value and just set a flag.
    +	 *
    +	 * Note that V_fw[6]_enable are manipulated by a SYSCTL_PROC so
    +	 * changes in the underlying (per-vnet) variables trigger
    +	 * immediate hook()/unhook() calls.
    +	 * In layer2 we have the same behaviour, except that V_ether_ipfw
    +	 * is checked on each packet because there are no pfil hooks.
    +	 */
     	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);
    +	error = ipfw_attach_hooks(1);
    +	return (error);
     }
     
    -/***********************
    +/*
      * Called for the removal of each instance.
      */
     static int
     vnet_ipfw_uninit(const void *unused)
     {
    -	struct ip_fw *reap;
    +	struct ip_fw *reap, *rule;
    +	struct ip_fw_chain *chain = &V_layer3_chain;
    +	int i;
     
     	V_ipfw_vnet_ready = 0; /* tell new callers to go away */
    -	ipfw_unhook();
    -#ifdef INET6
    -	ipfw6_unhook();
    -#endif
    -	/* layer2 and other entrypoints still come in this way. */
    +	/*
    +	 * disconnect from ipv4, ipv6, layer2 and sockopt.
    +	 * Then grab, release and grab again the WLOCK so we make
    +	 * sure the update is propagated and nobody will be in.
    +	 */
    +	(void)ipfw_attach_hooks(0 /* detach */);
     	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 */);
    -	reap = V_layer3_chain.reap;
    -	V_layer3_chain.reap = NULL;
    -	IPFW_WUNLOCK(&V_layer3_chain);
    +	IPFW_UH_WLOCK(chain);
    +	IPFW_UH_WUNLOCK(chain);
    +	IPFW_UH_WLOCK(chain);
    +
    +	IPFW_WLOCK(chain);
    +	IPFW_WUNLOCK(chain);
    +	IPFW_WLOCK(chain);
    +
    +	ipfw_dyn_uninit(0);	/* run the callout_drain */
    +	ipfw_destroy_tables(chain);
    +	reap = NULL;
    +	for (i = 0; i < chain->n_rules; i++) {
    +		rule = chain->map[i];
    +		rule->x_next = reap;
    +		reap = rule;
    +	}
    +	if (chain->map)
    +		free(chain->map, M_IPFW);
    +	IPFW_WUNLOCK(chain);
    +	IPFW_UH_WUNLOCK(chain);
     	if (reap != NULL)
    -		reap_rules(reap);
    -	IPFW_LOCK_DESTROY(&V_layer3_chain);
    -	if (V_ipfw_dyn_v != NULL)
    -		free(V_ipfw_dyn_v, M_IPFW);
    +		ipfw_reap_rules(reap);
    +	IPFW_LOCK_DESTROY(chain);
    +	ipfw_dyn_uninit(1);	/* free the remaining parts */
     	return 0;
     }
     
    @@ -4993,4 +2487,4 @@ SYSUNINIT(ipfw_destroy, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER,
     	    ipfw_destroy, NULL);
     VNET_SYSUNINIT(vnet_ipfw_uninit, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER,
     	    vnet_ipfw_uninit, NULL);
    -
    +/* end of file */
    diff --git a/sys/netinet/ipfw/ip_fw_dynamic.c b/sys/netinet/ipfw/ip_fw_dynamic.c
    new file mode 100644
    index 00000000000..69475828e1e
    --- /dev/null
    +++ b/sys/netinet/ipfw/ip_fw_dynamic.c
    @@ -0,0 +1,1244 @@
    +/*-
    + * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa
    + *
    + * 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$");
    +
    +#define        DEB(x)
    +#define        DDB(x) x
    +
    +/*
    + * Dynamic rule support for ipfw
    + */
    +
    +#if !defined(KLD_MODULE)
    +#include "opt_ipfw.h"
    +#include "opt_ipdivert.h"
    +#include "opt_ipdn.h"
    +#include "opt_inet.h"
    +#ifndef INET
    +#error IPFIREWALL requires INET.
    +#endif /* INET */
    +#endif
    +#include "opt_inet6.h"
    +#include "opt_ipsec.h"
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include  /* for ETHERTYPE_IP */
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 	/* ip_defttl */
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 	/* IN6_ARE_ADDR_EQUAL */
    +#ifdef INET6
    +#include 
    +#include 
    +#endif
    +
    +#include 	/* XXX for in_cksum */
    +
    +#ifdef MAC
    +#include 
    +#endif
    +
    +/*
    + * Description of dynamic rules.
    + *
    + * Dynamic rules are stored in lists accessed through a hash table
    + * (ipfw_dyn_v) whose size is curr_dyn_buckets. This value can
    + * be modified through the sysctl variable dyn_buckets which is
    + * updated when the table becomes empty.
    + *
    + * XXX currently there is only one list, ipfw_dyn.
    + *
    + * When a packet is received, its address fields are first masked
    + * with the mask defined for the rule, then hashed, then matched
    + * against the entries in the corresponding list.
    + * Dynamic rules can be used for different purposes:
    + *  + stateful rules;
    + *  + enforcing limits on the number of sessions;
    + *  + in-kernel NAT (not implemented yet)
    + *
    + * The lifetime of dynamic rules is regulated by dyn_*_lifetime,
    + * measured in seconds and depending on the flags.
    + *
    + * The total number of dynamic rules is stored in dyn_count.
    + * The max number of dynamic rules is dyn_max. When we reach
    + * the maximum number of rules we do not create anymore. This is
    + * done to avoid consuming too much memory, but also too much
    + * time when searching on each packet (ideally, we should try instead
    + * to put a limit on the length of the list on each bucket...).
    + *
    + * Each dynamic rule holds a pointer to the parent ipfw rule so
    + * we know what action to perform. Dynamic rules are removed when
    + * the parent rule is deleted. XXX we should make them survive.
    + *
    + * There are some limitations with dynamic rules -- we do not
    + * obey the 'randomized match', and we do not do multiple
    + * passes through the firewall. XXX check the latter!!!
    + */
    +
    +/*
    + * Static variables followed by global ones
    + */
    +static VNET_DEFINE(ipfw_dyn_rule **, ipfw_dyn_v);
    +static VNET_DEFINE(u_int32_t, dyn_buckets);
    +static VNET_DEFINE(u_int32_t, curr_dyn_buckets);
    +static VNET_DEFINE(struct callout, ipfw_timeout);
    +#define	V_ipfw_dyn_v			VNET(ipfw_dyn_v)
    +#define	V_dyn_buckets			VNET(dyn_buckets)
    +#define	V_curr_dyn_buckets		VNET(curr_dyn_buckets)
    +#define V_ipfw_timeout                  VNET(ipfw_timeout)
    +
    +static uma_zone_t ipfw_dyn_rule_zone;
    +#ifndef __FreeBSD__
    +DEFINE_SPINLOCK(ipfw_dyn_mtx);
    +#else
    +static struct mtx ipfw_dyn_mtx;		/* mutex guarding dynamic rules */
    +#endif
    +
    +#define	IPFW_DYN_LOCK_INIT() \
    +	mtx_init(&ipfw_dyn_mtx, "IPFW dynamic rules", NULL, MTX_DEF)
    +#define	IPFW_DYN_LOCK_DESTROY()	mtx_destroy(&ipfw_dyn_mtx)
    +#define	IPFW_DYN_LOCK()		mtx_lock(&ipfw_dyn_mtx)
    +#define	IPFW_DYN_UNLOCK()	mtx_unlock(&ipfw_dyn_mtx)
    +#define	IPFW_DYN_LOCK_ASSERT()	mtx_assert(&ipfw_dyn_mtx, MA_OWNED)
    +
    +void
    +ipfw_dyn_unlock(void)
    +{
    +	IPFW_DYN_UNLOCK();
    +}
    +
    +/*
    + * Timeouts for various events in handing dynamic rules.
    + */
    +static VNET_DEFINE(u_int32_t, dyn_ack_lifetime);
    +static VNET_DEFINE(u_int32_t, dyn_syn_lifetime);
    +static VNET_DEFINE(u_int32_t, dyn_fin_lifetime);
    +static VNET_DEFINE(u_int32_t, dyn_rst_lifetime);
    +static VNET_DEFINE(u_int32_t, dyn_udp_lifetime);
    +static VNET_DEFINE(u_int32_t, dyn_short_lifetime);
    +
    +#define	V_dyn_ack_lifetime		VNET(dyn_ack_lifetime)
    +#define	V_dyn_syn_lifetime		VNET(dyn_syn_lifetime)
    +#define	V_dyn_fin_lifetime		VNET(dyn_fin_lifetime)
    +#define	V_dyn_rst_lifetime		VNET(dyn_rst_lifetime)
    +#define	V_dyn_udp_lifetime		VNET(dyn_udp_lifetime)
    +#define	V_dyn_short_lifetime		VNET(dyn_short_lifetime)
    +
    +/*
    + * Keepalives are sent if dyn_keepalive is set. They are sent every
    + * dyn_keepalive_period seconds, in the last dyn_keepalive_interval
    + * seconds of lifetime of a rule.
    + * dyn_rst_lifetime and dyn_fin_lifetime should be strictly lower
    + * than dyn_keepalive_period.
    + */
    +
    +static VNET_DEFINE(u_int32_t, dyn_keepalive_interval);
    +static VNET_DEFINE(u_int32_t, dyn_keepalive_period);
    +static VNET_DEFINE(u_int32_t, dyn_keepalive);
    +
    +#define	V_dyn_keepalive_interval	VNET(dyn_keepalive_interval)
    +#define	V_dyn_keepalive_period		VNET(dyn_keepalive_period)
    +#define	V_dyn_keepalive			VNET(dyn_keepalive)
    +
    +static VNET_DEFINE(u_int32_t, dyn_count);	/* # of dynamic rules */
    +static VNET_DEFINE(u_int32_t, dyn_max);		/* max # of dynamic rules */
    +
    +#define	V_dyn_count			VNET(dyn_count)
    +#define	V_dyn_max			VNET(dyn_max)
    +
    +#ifdef SYSCTL_NODE
    +
    +SYSBEGIN(f2)
    +
    +SYSCTL_DECL(_net_inet_ip_fw);
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets,
    +    CTLFLAG_RW, &VNET_NAME(dyn_buckets), 0,
    +    "Number of dyn. buckets");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets,
    +    CTLFLAG_RD, &VNET_NAME(curr_dyn_buckets), 0,
    +    "Current Number of dyn. buckets");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_count,
    +    CTLFLAG_RD, &VNET_NAME(dyn_count), 0,
    +    "Number of dyn. rules");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_max,
    +    CTLFLAG_RW, &VNET_NAME(dyn_max), 0,
    +    "Max number of dyn. rules");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime,
    +    CTLFLAG_RW, &VNET_NAME(dyn_ack_lifetime), 0,
    +    "Lifetime of dyn. rules for acks");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime,
    +    CTLFLAG_RW, &VNET_NAME(dyn_syn_lifetime), 0,
    +    "Lifetime of dyn. rules for syn");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime,
    +    CTLFLAG_RW, &VNET_NAME(dyn_fin_lifetime), 0,
    +    "Lifetime of dyn. rules for fin");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime,
    +    CTLFLAG_RW, &VNET_NAME(dyn_rst_lifetime), 0,
    +    "Lifetime of dyn. rules for rst");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime,
    +    CTLFLAG_RW, &VNET_NAME(dyn_udp_lifetime), 0,
    +    "Lifetime of dyn. rules for UDP");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime,
    +    CTLFLAG_RW, &VNET_NAME(dyn_short_lifetime), 0,
    +    "Lifetime of dyn. rules for other situations");
    +SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive,
    +    CTLFLAG_RW, &VNET_NAME(dyn_keepalive), 0,
    +    "Enable keepalives for dyn. rules");
    +
    +SYSEND
    +
    +#endif /* SYSCTL_NODE */
    +
    +
    +static __inline int
    +hash_packet6(struct ipfw_flow_id *id)
    +{
    +	u_int32_t i;
    +	i = (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
    +	    (id->dst_ip6.__u6_addr.__u6_addr32[3]) ^
    +	    (id->src_ip6.__u6_addr.__u6_addr32[2]) ^
    +	    (id->src_ip6.__u6_addr.__u6_addr32[3]) ^
    +	    (id->dst_port) ^ (id->src_port);
    +	return i;
    +}
    +
    +/*
    + * IMPORTANT: the hash function for dynamic rules must be commutative
    + * in source and destination (ip,port), because rules are bidirectional
    + * and we want to find both in the same bucket.
    + */
    +static __inline int
    +hash_packet(struct ipfw_flow_id *id)
    +{
    +	u_int32_t i;
    +
    +#ifdef INET6
    +	if (IS_IP6_FLOW_ID(id)) 
    +		i = hash_packet6(id);
    +	else
    +#endif /* INET6 */
    +	i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
    +	i &= (V_curr_dyn_buckets - 1);
    +	return i;
    +}
    +
    +static __inline void
    +unlink_dyn_rule_print(struct ipfw_flow_id *id)
    +{
    +	struct in_addr da;
    +#ifdef INET6
    +	char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
    +#else
    +	char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
    +#endif
    +
    +#ifdef INET6
    +	if (IS_IP6_FLOW_ID(id)) {
    +		ip6_sprintf(src, &id->src_ip6);
    +		ip6_sprintf(dst, &id->dst_ip6);
    +	} else
    +#endif
    +	{
    +		da.s_addr = htonl(id->src_ip);
    +		inet_ntoa_r(da, src);
    +		da.s_addr = htonl(id->dst_ip);
    +		inet_ntoa_r(da, dst);
    +	}
    +	printf("ipfw: unlink entry %s %d -> %s %d, %d left\n",
    +	    src, id->src_port, dst, id->dst_port, V_dyn_count - 1);
    +}
    +
    +/**
    + * unlink a dynamic rule from a chain. prev is a pointer to
    + * the previous one, q is a pointer to the rule to delete,
    + * head is a pointer to the head of the queue.
    + * Modifies q and potentially also head.
    + */
    +#define UNLINK_DYN_RULE(prev, head, q) {				\
    +	ipfw_dyn_rule *old_q = q;					\
    +									\
    +	/* remove a refcount to the parent */				\
    +	if (q->dyn_type == O_LIMIT)					\
    +		q->parent->count--;					\
    +	DEB(unlink_dyn_rule_print(&q->id);)				\
    +	if (prev != NULL)						\
    +		prev->next = q = q->next;				\
    +	else								\
    +		head = q = q->next;					\
    +	V_dyn_count--;							\
    +	uma_zfree(ipfw_dyn_rule_zone, old_q); }
    +
    +#define TIME_LEQ(a,b)       ((int)((a)-(b)) <= 0)
    +
    +/**
    + * Remove dynamic rules pointing to "rule", or all of them if rule == NULL.
    + *
    + * If keep_me == NULL, rules are deleted even if not expired,
    + * otherwise only expired rules are removed.
    + *
    + * The value of the second parameter is also used to point to identify
    + * a rule we absolutely do not want to remove (e.g. because we are
    + * holding a reference to it -- this is the case with O_LIMIT_PARENT
    + * rules). The pointer is only used for comparison, so any non-null
    + * value will do.
    + */
    +static void
    +remove_dyn_rule(struct ip_fw *rule, ipfw_dyn_rule *keep_me)
    +{
    +	static u_int32_t last_remove = 0;
    +
    +#define FORCE (keep_me == NULL)
    +
    +	ipfw_dyn_rule *prev, *q;
    +	int i, pass = 0, max_pass = 0;
    +
    +	IPFW_DYN_LOCK_ASSERT();
    +
    +	if (V_ipfw_dyn_v == NULL || V_dyn_count == 0)
    +		return;
    +	/* do not expire more than once per second, it is useless */
    +	if (!FORCE && last_remove == time_uptime)
    +		return;
    +	last_remove = time_uptime;
    +
    +	/*
    +	 * because O_LIMIT refer to parent rules, during the first pass only
    +	 * remove child and mark any pending LIMIT_PARENT, and remove
    +	 * them in a second pass.
    +	 */
    +next_pass:
    +	for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
    +		for (prev=NULL, q = V_ipfw_dyn_v[i] ; q ; ) {
    +			/*
    +			 * Logic can become complex here, so we split tests.
    +			 */
    +			if (q == keep_me)
    +				goto next;
    +			if (rule != NULL && rule != q->rule)
    +				goto next; /* not the one we are looking for */
    +			if (q->dyn_type == O_LIMIT_PARENT) {
    +				/*
    +				 * handle parent in the second pass,
    +				 * record we need one.
    +				 */
    +				max_pass = 1;
    +				if (pass == 0)
    +					goto next;
    +				if (FORCE && q->count != 0 ) {
    +					/* XXX should not happen! */
    +					printf("ipfw: OUCH! cannot remove rule,"
    +					     " count %d\n", q->count);
    +				}
    +			} else {
    +				if (!FORCE &&
    +				    !TIME_LEQ( q->expire, time_uptime ))
    +					goto next;
    +			}
    +             if (q->dyn_type != O_LIMIT_PARENT || !q->count) {
    +                     UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
    +                     continue;
    +             }
    +next:
    +			prev=q;
    +			q=q->next;
    +		}
    +	}
    +	if (pass++ < max_pass)
    +		goto next_pass;
    +}
    +
    +void
    +ipfw_remove_dyn_children(struct ip_fw *rule)
    +{
    +	IPFW_DYN_LOCK();
    +	remove_dyn_rule(rule, NULL /* force removal */);
    +	IPFW_DYN_UNLOCK();
    +}
    +
    +/**
    + * lookup a dynamic rule, locked version
    + */
    +static ipfw_dyn_rule *
    +lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int *match_direction,
    +    struct tcphdr *tcp)
    +{
    +	/*
    +	 * stateful ipfw extensions.
    +	 * Lookup into dynamic session queue
    +	 */
    +#define MATCH_REVERSE	0
    +#define MATCH_FORWARD	1
    +#define MATCH_NONE	2
    +#define MATCH_UNKNOWN	3
    +	int i, dir = MATCH_NONE;
    +	ipfw_dyn_rule *prev, *q=NULL;
    +
    +	IPFW_DYN_LOCK_ASSERT();
    +
    +	if (V_ipfw_dyn_v == NULL)
    +		goto done;	/* not found */
    +	i = hash_packet( pkt );
    +	for (prev=NULL, q = V_ipfw_dyn_v[i] ; q != NULL ; ) {
    +		if (q->dyn_type == O_LIMIT_PARENT && q->count)
    +			goto next;
    +		if (TIME_LEQ( q->expire, time_uptime)) { /* expire entry */
    +			UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
    +			continue;
    +		}
    +		if (pkt->proto == q->id.proto &&
    +		    q->dyn_type != O_LIMIT_PARENT) {
    +			if (IS_IP6_FLOW_ID(pkt)) {
    +			    if (IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
    +				&(q->id.src_ip6)) &&
    +			    IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
    +				&(q->id.dst_ip6)) &&
    +			    pkt->src_port == q->id.src_port &&
    +			    pkt->dst_port == q->id.dst_port ) {
    +				dir = MATCH_FORWARD;
    +				break;
    +			    }
    +			    if (IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
    +				    &(q->id.dst_ip6)) &&
    +				IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
    +				    &(q->id.src_ip6)) &&
    +				pkt->src_port == q->id.dst_port &&
    +				pkt->dst_port == q->id.src_port ) {
    +				    dir = MATCH_REVERSE;
    +				    break;
    +			    }
    +			} else {
    +			    if (pkt->src_ip == q->id.src_ip &&
    +				pkt->dst_ip == q->id.dst_ip &&
    +				pkt->src_port == q->id.src_port &&
    +				pkt->dst_port == q->id.dst_port ) {
    +				    dir = MATCH_FORWARD;
    +				    break;
    +			    }
    +			    if (pkt->src_ip == q->id.dst_ip &&
    +				pkt->dst_ip == q->id.src_ip &&
    +				pkt->src_port == q->id.dst_port &&
    +				pkt->dst_port == q->id.src_port ) {
    +				    dir = MATCH_REVERSE;
    +				    break;
    +			    }
    +			}
    +		}
    +next:
    +		prev = q;
    +		q = q->next;
    +	}
    +	if (q == NULL)
    +		goto done; /* q = NULL, not found */
    +
    +	if ( prev != NULL) { /* found and not in front */
    +		prev->next = q->next;
    +		q->next = V_ipfw_dyn_v[i];
    +		V_ipfw_dyn_v[i] = q;
    +	}
    +	if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
    +		u_char flags = pkt->_flags & (TH_FIN|TH_SYN|TH_RST);
    +
    +#define BOTH_SYN	(TH_SYN | (TH_SYN << 8))
    +#define BOTH_FIN	(TH_FIN | (TH_FIN << 8))
    +		q->state |= (dir == MATCH_FORWARD ) ? flags : (flags << 8);
    +		switch (q->state) {
    +		case TH_SYN:				/* opening */
    +			q->expire = time_uptime + V_dyn_syn_lifetime;
    +			break;
    +
    +		case BOTH_SYN:			/* move to established */
    +		case BOTH_SYN | TH_FIN :	/* one side tries to close */
    +		case BOTH_SYN | (TH_FIN << 8) :
    + 			if (tcp) {
    +#define _SEQ_GE(a,b) ((int)(a) - (int)(b) >= 0)
    +			    u_int32_t ack = ntohl(tcp->th_ack);
    +			    if (dir == MATCH_FORWARD) {
    +				if (q->ack_fwd == 0 || _SEQ_GE(ack, q->ack_fwd))
    +				    q->ack_fwd = ack;
    +				else { /* ignore out-of-sequence */
    +				    break;
    +				}
    +			    } else {
    +				if (q->ack_rev == 0 || _SEQ_GE(ack, q->ack_rev))
    +				    q->ack_rev = ack;
    +				else { /* ignore out-of-sequence */
    +				    break;
    +				}
    +			    }
    +			}
    +			q->expire = time_uptime + V_dyn_ack_lifetime;
    +			break;
    +
    +		case BOTH_SYN | BOTH_FIN:	/* both sides closed */
    +			if (V_dyn_fin_lifetime >= V_dyn_keepalive_period)
    +				V_dyn_fin_lifetime = V_dyn_keepalive_period - 1;
    +			q->expire = time_uptime + V_dyn_fin_lifetime;
    +			break;
    +
    +		default:
    +#if 0
    +			/*
    +			 * reset or some invalid combination, but can also
    +			 * occur if we use keep-state the wrong way.
    +			 */
    +			if ( (q->state & ((TH_RST << 8)|TH_RST)) == 0)
    +				printf("invalid state: 0x%x\n", q->state);
    +#endif
    +			if (V_dyn_rst_lifetime >= V_dyn_keepalive_period)
    +				V_dyn_rst_lifetime = V_dyn_keepalive_period - 1;
    +			q->expire = time_uptime + V_dyn_rst_lifetime;
    +			break;
    +		}
    +	} else if (pkt->proto == IPPROTO_UDP) {
    +		q->expire = time_uptime + V_dyn_udp_lifetime;
    +	} else {
    +		/* other protocols */
    +		q->expire = time_uptime + V_dyn_short_lifetime;
    +	}
    +done:
    +	if (match_direction)
    +		*match_direction = dir;
    +	return q;
    +}
    +
    +ipfw_dyn_rule *
    +ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction,
    +    struct tcphdr *tcp)
    +{
    +	ipfw_dyn_rule *q;
    +
    +	IPFW_DYN_LOCK();
    +	q = lookup_dyn_rule_locked(pkt, match_direction, tcp);
    +	if (q == NULL)
    +		IPFW_DYN_UNLOCK();
    +	/* NB: return table locked when q is not NULL */
    +	return q;
    +}
    +
    +static void
    +realloc_dynamic_table(void)
    +{
    +	IPFW_DYN_LOCK_ASSERT();
    +
    +	/*
    +	 * Try reallocation, make sure we have a power of 2 and do
    +	 * not allow more than 64k entries. In case of overflow,
    +	 * default to 1024.
    +	 */
    +
    +	if (V_dyn_buckets > 65536)
    +		V_dyn_buckets = 1024;
    +	if ((V_dyn_buckets & (V_dyn_buckets-1)) != 0) { /* not a power of 2 */
    +		V_dyn_buckets = V_curr_dyn_buckets; /* reset */
    +		return;
    +	}
    +	V_curr_dyn_buckets = V_dyn_buckets;
    +	if (V_ipfw_dyn_v != NULL)
    +		free(V_ipfw_dyn_v, M_IPFW);
    +	for (;;) {
    +		V_ipfw_dyn_v = malloc(V_curr_dyn_buckets * sizeof(ipfw_dyn_rule *),
    +		       M_IPFW, M_NOWAIT | M_ZERO);
    +		if (V_ipfw_dyn_v != NULL || V_curr_dyn_buckets <= 2)
    +			break;
    +		V_curr_dyn_buckets /= 2;
    +	}
    +}
    +
    +/**
    + * Install state of type 'type' for a dynamic session.
    + * The hash table contains two type of rules:
    + * - regular rules (O_KEEP_STATE)
    + * - rules for sessions with limited number of sess per user
    + *   (O_LIMIT). When they are created, the parent is
    + *   increased by 1, and decreased on delete. In this case,
    + *   the third parameter is the parent rule and not the chain.
    + * - "parent" rules for the above (O_LIMIT_PARENT).
    + */
    +static ipfw_dyn_rule *
    +add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
    +{
    +	ipfw_dyn_rule *r;
    +	int i;
    +
    +	IPFW_DYN_LOCK_ASSERT();
    +
    +	if (V_ipfw_dyn_v == NULL ||
    +	    (V_dyn_count == 0 && V_dyn_buckets != V_curr_dyn_buckets)) {
    +		realloc_dynamic_table();
    +		if (V_ipfw_dyn_v == NULL)
    +			return NULL; /* failed ! */
    +	}
    +	i = hash_packet(id);
    +
    +	r = uma_zalloc(ipfw_dyn_rule_zone, M_NOWAIT | M_ZERO);
    +	if (r == NULL) {
    +		printf ("ipfw: sorry cannot allocate state\n");
    +		return NULL;
    +	}
    +
    +	/* increase refcount on parent, and set pointer */
    +	if (dyn_type == O_LIMIT) {
    +		ipfw_dyn_rule *parent = (ipfw_dyn_rule *)rule;
    +		if ( parent->dyn_type != O_LIMIT_PARENT)
    +			panic("invalid parent");
    +		parent->count++;
    +		r->parent = parent;
    +		rule = parent->rule;
    +	}
    +
    +	r->id = *id;
    +	r->expire = time_uptime + V_dyn_syn_lifetime;
    +	r->rule = rule;
    +	r->dyn_type = dyn_type;
    +	r->pcnt = r->bcnt = 0;
    +	r->count = 0;
    +
    +	r->bucket = i;
    +	r->next = V_ipfw_dyn_v[i];
    +	V_ipfw_dyn_v[i] = r;
    +	V_dyn_count++;
    +	DEB({
    +		struct in_addr da;
    +#ifdef INET6
    +		char src[INET6_ADDRSTRLEN];
    +		char dst[INET6_ADDRSTRLEN];
    +#else
    +		char src[INET_ADDRSTRLEN];
    +		char dst[INET_ADDRSTRLEN];
    +#endif
    +
    +#ifdef INET6
    +		if (IS_IP6_FLOW_ID(&(r->id))) {
    +			ip6_sprintf(src, &r->id.src_ip6);
    +			ip6_sprintf(dst, &r->id.dst_ip6);
    +		} else
    +#endif
    +		{
    +			da.s_addr = htonl(r->id.src_ip);
    +			inet_ntoa_r(da, src);
    +			da.s_addr = htonl(r->id.dst_ip);
    +			inet_ntoa_r(da, dst);
    +		}
    +		printf("ipfw: add dyn entry ty %d %s %d -> %s %d, total %d\n",
    +		    dyn_type, src, r->id.src_port, dst, r->id.dst_port,
    +		    V_dyn_count);
    +	})
    +	return r;
    +}
    +
    +/**
    + * lookup dynamic parent rule using pkt and rule as search keys.
    + * If the lookup fails, then install one.
    + */
    +static ipfw_dyn_rule *
    +lookup_dyn_parent(struct ipfw_flow_id *pkt, struct ip_fw *rule)
    +{
    +	ipfw_dyn_rule *q;
    +	int i;
    +
    +	IPFW_DYN_LOCK_ASSERT();
    +
    +	if (V_ipfw_dyn_v) {
    +		int is_v6 = IS_IP6_FLOW_ID(pkt);
    +		i = hash_packet( pkt );
    +		for (q = V_ipfw_dyn_v[i] ; q != NULL ; q=q->next)
    +			if (q->dyn_type == O_LIMIT_PARENT &&
    +			    rule== q->rule &&
    +			    pkt->proto == q->id.proto &&
    +			    pkt->src_port == q->id.src_port &&
    +			    pkt->dst_port == q->id.dst_port &&
    +			    (
    +				(is_v6 &&
    +				 IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
    +					&(q->id.src_ip6)) &&
    +				 IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
    +					&(q->id.dst_ip6))) ||
    +				(!is_v6 &&
    +				 pkt->src_ip == q->id.src_ip &&
    +				 pkt->dst_ip == q->id.dst_ip)
    +			    )
    +			) {
    +				q->expire = time_uptime + V_dyn_short_lifetime;
    +				DEB(printf("ipfw: lookup_dyn_parent found 0x%p\n",q);)
    +				return q;
    +			}
    +	}
    +	return add_dyn_rule(pkt, O_LIMIT_PARENT, rule);
    +}
    +
    +/**
    + * Install dynamic state for rule type cmd->o.opcode
    + *
    + * Returns 1 (failure) if state is not installed because of errors or because
    + * session limitations are enforced.
    + */
    +int
    +ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
    +    struct ip_fw_args *args, uint32_t tablearg)
    +{
    +	static int last_log;
    +	ipfw_dyn_rule *q;
    +	struct in_addr da;
    +#ifdef INET6
    +	char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
    +#else
    +	char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
    +#endif
    +
    +	src[0] = '\0';
    +	dst[0] = '\0';
    +
    +	IPFW_DYN_LOCK();
    +
    +	DEB(
    +#ifdef INET6
    +	if (IS_IP6_FLOW_ID(&(args->f_id))) {
    +		ip6_sprintf(src, &args->f_id.src_ip6);
    +		ip6_sprintf(dst, &args->f_id.dst_ip6);
    +	} else
    +#endif
    +	{
    +		da.s_addr = htonl(args->f_id.src_ip);
    +		inet_ntoa_r(da, src);
    +		da.s_addr = htonl(args->f_id.dst_ip);
    +		inet_ntoa_r(da, dst);
    +	}
    +	printf("ipfw: %s: type %d %s %u -> %s %u\n",
    +	    __func__, cmd->o.opcode, src, args->f_id.src_port,
    +	    dst, args->f_id.dst_port);
    +	src[0] = '\0';
    +	dst[0] = '\0';
    +	)
    +
    +	q = lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
    +
    +	if (q != NULL) {	/* should never occur */
    +		if (last_log != time_uptime) {
    +			last_log = time_uptime;
    +			printf("ipfw: %s: entry already present, done\n",
    +			    __func__);
    +		}
    +		IPFW_DYN_UNLOCK();
    +		return (0);
    +	}
    +
    +	if (V_dyn_count >= V_dyn_max)
    +		/* Run out of slots, try to remove any expired rule. */
    +		remove_dyn_rule(NULL, (ipfw_dyn_rule *)1);
    +
    +	if (V_dyn_count >= V_dyn_max) {
    +		if (last_log != time_uptime) {
    +			last_log = time_uptime;
    +			printf("ipfw: %s: Too many dynamic rules\n", __func__);
    +		}
    +		IPFW_DYN_UNLOCK();
    +		return (1);	/* cannot install, notify caller */
    +	}
    +
    +	switch (cmd->o.opcode) {
    +	case O_KEEP_STATE:	/* bidir rule */
    +		add_dyn_rule(&args->f_id, O_KEEP_STATE, rule);
    +		break;
    +
    +	case O_LIMIT: {		/* limit number of sessions */
    +		struct ipfw_flow_id id;
    +		ipfw_dyn_rule *parent;
    +		uint32_t conn_limit;
    +		uint16_t limit_mask = cmd->limit_mask;
    +
    +		conn_limit = (cmd->conn_limit == IP_FW_TABLEARG) ?
    +		    tablearg : cmd->conn_limit;
    +		  
    +		DEB(
    +		if (cmd->conn_limit == IP_FW_TABLEARG)
    +			printf("ipfw: %s: O_LIMIT rule, conn_limit: %u "
    +			    "(tablearg)\n", __func__, conn_limit);
    +		else
    +			printf("ipfw: %s: O_LIMIT rule, conn_limit: %u\n",
    +			    __func__, conn_limit);
    +		)
    +
    +		id.dst_ip = id.src_ip = id.dst_port = id.src_port = 0;
    +		id.proto = args->f_id.proto;
    +		id.addr_type = args->f_id.addr_type;
    +		id.fib = M_GETFIB(args->m);
    +
    +		if (IS_IP6_FLOW_ID (&(args->f_id))) {
    +			if (limit_mask & DYN_SRC_ADDR)
    +				id.src_ip6 = args->f_id.src_ip6;
    +			if (limit_mask & DYN_DST_ADDR)
    +				id.dst_ip6 = args->f_id.dst_ip6;
    +		} else {
    +			if (limit_mask & DYN_SRC_ADDR)
    +				id.src_ip = args->f_id.src_ip;
    +			if (limit_mask & DYN_DST_ADDR)
    +				id.dst_ip = args->f_id.dst_ip;
    +		}
    +		if (limit_mask & DYN_SRC_PORT)
    +			id.src_port = args->f_id.src_port;
    +		if (limit_mask & DYN_DST_PORT)
    +			id.dst_port = args->f_id.dst_port;
    +		if ((parent = lookup_dyn_parent(&id, rule)) == NULL) {
    +			printf("ipfw: %s: add parent failed\n", __func__);
    +			IPFW_DYN_UNLOCK();
    +			return (1);
    +		}
    +
    +		if (parent->count >= conn_limit) {
    +			/* See if we can remove some expired rule. */
    +			remove_dyn_rule(rule, parent);
    +			if (parent->count >= conn_limit) {
    +				if (V_fw_verbose && last_log != time_uptime) {
    +					last_log = time_uptime;
    +#ifdef INET6
    +					/*
    +					 * XXX IPv6 flows are not
    +					 * supported yet.
    +					 */
    +					if (IS_IP6_FLOW_ID(&(args->f_id))) {
    +						char ip6buf[INET6_ADDRSTRLEN];
    +						snprintf(src, sizeof(src),
    +						    "[%s]", ip6_sprintf(ip6buf,
    +							&args->f_id.src_ip6));
    +						snprintf(dst, sizeof(dst),
    +						    "[%s]", ip6_sprintf(ip6buf,
    +							&args->f_id.dst_ip6));
    +					} else
    +#endif
    +					{
    +						da.s_addr =
    +						    htonl(args->f_id.src_ip);
    +						inet_ntoa_r(da, src);
    +						da.s_addr =
    +						    htonl(args->f_id.dst_ip);
    +						inet_ntoa_r(da, dst);
    +					}
    +					log(LOG_SECURITY | LOG_DEBUG,
    +					    "ipfw: %d %s %s:%u -> %s:%u, %s\n",
    +					    parent->rule->rulenum,
    +					    "drop session",
    +					    src, (args->f_id.src_port),
    +					    dst, (args->f_id.dst_port),
    +					    "too many entries");
    +				}
    +				IPFW_DYN_UNLOCK();
    +				return (1);
    +			}
    +		}
    +		add_dyn_rule(&args->f_id, O_LIMIT, (struct ip_fw *)parent);
    +		break;
    +	}
    +	default:
    +		printf("ipfw: %s: unknown dynamic rule type %u\n",
    +		    __func__, cmd->o.opcode);
    +		IPFW_DYN_UNLOCK();
    +		return (1);
    +	}
    +
    +	/* XXX just set lifetime */
    +	lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
    +
    +	IPFW_DYN_UNLOCK();
    +	return (0);
    +}
    +
    +/*
    + * Generate a TCP packet, containing either a RST or a keepalive.
    + * When flags & TH_RST, we are sending a RST packet, because of a
    + * "reset" action matched the packet.
    + * Otherwise we are sending a keepalive, and flags & TH_
    + * The 'replyto' mbuf is the mbuf being replied to, if any, and is required
    + * so that MAC can label the reply appropriately.
    + */
    +struct mbuf *
    +ipfw_send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
    +    u_int32_t ack, int flags)
    +{
    +#ifndef __FreeBSD__
    +	return NULL;
    +#else
    +	struct mbuf *m;
    +	int len, dir;
    +	struct ip *h = NULL;		/* stupid compiler */
    +#ifdef INET6
    +	struct ip6_hdr *h6 = NULL;
    +#endif
    +	struct tcphdr *th = NULL;
    +
    +	MGETHDR(m, M_DONTWAIT, MT_DATA);
    +	if (m == NULL)
    +		return (NULL);
    +
    +	M_SETFIB(m, id->fib);
    +#ifdef MAC
    +	if (replyto != NULL)
    +		mac_netinet_firewall_reply(replyto, m);
    +	else
    +		mac_netinet_firewall_send(m);
    +#else
    +	(void)replyto;		/* don't warn about unused arg */
    +#endif
    +
    +	switch (id->addr_type) {
    +	case 4:
    +		len = sizeof(struct ip) + sizeof(struct tcphdr);
    +		break;
    +#ifdef INET6
    +	case 6:
    +		len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
    +		break;
    +#endif
    +	default:
    +		/* XXX: log me?!? */
    +		FREE_PKT(m);
    +		return (NULL);
    +	}
    +	dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN);
    +
    +	m->m_data += max_linkhdr;
    +	m->m_flags |= M_SKIP_FIREWALL;
    +	m->m_pkthdr.len = m->m_len = len;
    +	m->m_pkthdr.rcvif = NULL;
    +	bzero(m->m_data, len);
    +
    +	switch (id->addr_type) {
    +	case 4:
    +		h = mtod(m, struct ip *);
    +
    +		/* prepare for checksum */
    +		h->ip_p = IPPROTO_TCP;
    +		h->ip_len = htons(sizeof(struct tcphdr));
    +		if (dir) {
    +			h->ip_src.s_addr = htonl(id->src_ip);
    +			h->ip_dst.s_addr = htonl(id->dst_ip);
    +		} else {
    +			h->ip_src.s_addr = htonl(id->dst_ip);
    +			h->ip_dst.s_addr = htonl(id->src_ip);
    +		}
    +
    +		th = (struct tcphdr *)(h + 1);
    +		break;
    +#ifdef INET6
    +	case 6:
    +		h6 = mtod(m, struct ip6_hdr *);
    +
    +		/* prepare for checksum */
    +		h6->ip6_nxt = IPPROTO_TCP;
    +		h6->ip6_plen = htons(sizeof(struct tcphdr));
    +		if (dir) {
    +			h6->ip6_src = id->src_ip6;
    +			h6->ip6_dst = id->dst_ip6;
    +		} else {
    +			h6->ip6_src = id->dst_ip6;
    +			h6->ip6_dst = id->src_ip6;
    +		}
    +
    +		th = (struct tcphdr *)(h6 + 1);
    +		break;
    +#endif
    +	}
    +
    +	if (dir) {
    +		th->th_sport = htons(id->src_port);
    +		th->th_dport = htons(id->dst_port);
    +	} else {
    +		th->th_sport = htons(id->dst_port);
    +		th->th_dport = htons(id->src_port);
    +	}
    +	th->th_off = sizeof(struct tcphdr) >> 2;
    +
    +	if (flags & TH_RST) {
    +		if (flags & TH_ACK) {
    +			th->th_seq = htonl(ack);
    +			th->th_flags = TH_RST;
    +		} else {
    +			if (flags & TH_SYN)
    +				seq++;
    +			th->th_ack = htonl(seq);
    +			th->th_flags = TH_RST | TH_ACK;
    +		}
    +	} else {
    +		/*
    +		 * Keepalive - use caller provided sequence numbers
    +		 */
    +		th->th_seq = htonl(seq);
    +		th->th_ack = htonl(ack);
    +		th->th_flags = TH_ACK;
    +	}
    +
    +	switch (id->addr_type) {
    +	case 4:
    +		th->th_sum = in_cksum(m, len);
    +
    +		/* finish the ip header */
    +		h->ip_v = 4;
    +		h->ip_hl = sizeof(*h) >> 2;
    +		h->ip_tos = IPTOS_LOWDELAY;
    +		h->ip_off = 0;
    +		/* ip_len must be in host format for ip_output */
    +		h->ip_len = len;
    +		h->ip_ttl = V_ip_defttl;
    +		h->ip_sum = 0;
    +		break;
    +#ifdef INET6
    +	case 6:
    +		th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6),
    +		    sizeof(struct tcphdr));
    +
    +		/* finish the ip6 header */
    +		h6->ip6_vfc |= IPV6_VERSION;
    +		h6->ip6_hlim = IPV6_DEFHLIM;
    +		break;
    +#endif
    +	}
    +
    +	return (m);
    +#endif /* __FreeBSD__ */
    +}
    +
    +/*
    + * This procedure is only used to handle keepalives. It is invoked
    + * every dyn_keepalive_period
    + */
    +static void
    +ipfw_tick(void * vnetx) 
    +{
    +	struct mbuf *m0, *m, *mnext, **mtailp;
    +#ifdef INET6
    +	struct mbuf *m6, **m6_tailp;
    +#endif
    +	int i;
    +	ipfw_dyn_rule *q;
    +#ifdef VIMAGE
    +	struct vnet *vp = vnetx;
    +#endif
    +
    +	CURVNET_SET(vp);
    +	if (V_dyn_keepalive == 0 || V_ipfw_dyn_v == NULL || V_dyn_count == 0)
    +		goto done;
    +
    +	/*
    +	 * We make a chain of packets to go out here -- not deferring
    +	 * until after we drop the IPFW dynamic rule lock would result
    +	 * in a lock order reversal with the normal packet input -> ipfw
    +	 * call stack.
    +	 */
    +	m0 = NULL;
    +	mtailp = &m0;
    +#ifdef INET6
    +	m6 = NULL;
    +	m6_tailp = &m6;
    +#endif
    +	IPFW_DYN_LOCK();
    +	for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
    +		for (q = V_ipfw_dyn_v[i] ; q ; q = q->next ) {
    +			if (q->dyn_type == O_LIMIT_PARENT)
    +				continue;
    +			if (q->id.proto != IPPROTO_TCP)
    +				continue;
    +			if ( (q->state & BOTH_SYN) != BOTH_SYN)
    +				continue;
    +			if (TIME_LEQ(time_uptime + V_dyn_keepalive_interval,
    +			    q->expire))
    +				continue;	/* too early */
    +			if (TIME_LEQ(q->expire, time_uptime))
    +				continue;	/* too late, rule expired */
    +
    +			m = ipfw_send_pkt(NULL, &(q->id), q->ack_rev - 1,
    +				q->ack_fwd, TH_SYN);
    +			mnext = ipfw_send_pkt(NULL, &(q->id), q->ack_fwd - 1,
    +				q->ack_rev, 0);
    +
    +			switch (q->id.addr_type) {
    +			case 4:
    +				if (m != NULL) {
    +					*mtailp = m;
    +					mtailp = &(*mtailp)->m_nextpkt;
    +				}
    +				if (mnext != NULL) {
    +					*mtailp = mnext;
    +					mtailp = &(*mtailp)->m_nextpkt;
    +				}
    +				break;
    +#ifdef INET6
    +			case 6:
    +				if (m != NULL) {
    +					*m6_tailp = m;
    +					m6_tailp = &(*m6_tailp)->m_nextpkt;
    +				}
    +				if (mnext != NULL) {
    +					*m6_tailp = mnext;
    +					m6_tailp = &(*m6_tailp)->m_nextpkt;
    +				}
    +				break;
    +#endif
    +			}
    +
    +			m = mnext = NULL;
    +		}
    +	}
    +	IPFW_DYN_UNLOCK();
    +	for (m = mnext = m0; m != NULL; m = mnext) {
    +		mnext = m->m_nextpkt;
    +		m->m_nextpkt = NULL;
    +		ip_output(m, NULL, NULL, 0, NULL, NULL);
    +	}
    +#ifdef INET6
    +	for (m = mnext = m6; m != NULL; m = mnext) {
    +		mnext = m->m_nextpkt;
    +		m->m_nextpkt = NULL;
    +		ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
    +	}
    +#endif
    +done:
    +	callout_reset(&V_ipfw_timeout, V_dyn_keepalive_period * hz,
    +		      ipfw_tick, vnetx);
    +	CURVNET_RESTORE();
    +}
    +
    +void
    +ipfw_dyn_attach(void)
    +{
    +        ipfw_dyn_rule_zone = uma_zcreate("IPFW dynamic rule",
    +            sizeof(ipfw_dyn_rule), NULL, NULL, NULL, NULL,
    +            UMA_ALIGN_PTR, 0);
    +
    +        IPFW_DYN_LOCK_INIT();
    +}
    +
    +void
    +ipfw_dyn_detach(void)
    +{
    +        uma_zdestroy(ipfw_dyn_rule_zone);
    +        IPFW_DYN_LOCK_DESTROY();
    +}
    +
    +void
    +ipfw_dyn_init(void)
    +{
    +        V_ipfw_dyn_v = NULL;
    +        V_dyn_buckets = 256;    /* must be power of 2 */
    +        V_curr_dyn_buckets = 256; /* must be power of 2 */
    + 
    +        V_dyn_ack_lifetime = 300;
    +        V_dyn_syn_lifetime = 20;
    +        V_dyn_fin_lifetime = 1;
    +        V_dyn_rst_lifetime = 1;
    +        V_dyn_udp_lifetime = 10;
    +        V_dyn_short_lifetime = 5;
    +
    +        V_dyn_keepalive_interval = 20;
    +        V_dyn_keepalive_period = 5;
    +        V_dyn_keepalive = 1;    /* do send keepalives */
    +        
    +        V_dyn_max = 4096;       /* max # of dynamic rules */
    +        callout_init(&V_ipfw_timeout, CALLOUT_MPSAFE);
    +        callout_reset(&V_ipfw_timeout, hz, ipfw_tick, curvnet);
    +}
    +
    +void
    +ipfw_dyn_uninit(int pass)
    +{
    +	if (pass == 0)
    +		callout_drain(&V_ipfw_timeout);
    +	else {
    +		if (V_ipfw_dyn_v != NULL)
    +			free(V_ipfw_dyn_v, M_IPFW);
    +	}
    +}
    +
    +int
    +ipfw_dyn_len(void)
    +{
    +	return (V_ipfw_dyn_v == NULL) ? 0 :
    +		(V_dyn_count * sizeof(ipfw_dyn_rule));
    +}
    +
    +void
    +ipfw_get_dynamic(char **pbp, const char *ep)
    +{
    +	ipfw_dyn_rule *p, *last = NULL;
    +	char *bp;
    +	int i;
    +
    +	if (V_ipfw_dyn_v == NULL)
    +		return;
    +	bp = *pbp;
    +
    +	IPFW_DYN_LOCK();
    +	for (i = 0 ; i < V_curr_dyn_buckets; i++)
    +		for (p = V_ipfw_dyn_v[i] ; p != NULL; p = p->next) {
    +			if (bp + sizeof *p <= ep) {
    +				ipfw_dyn_rule *dst =
    +					(ipfw_dyn_rule *)bp;
    +				bcopy(p, dst, sizeof *p);
    +				bcopy(&(p->rule->rulenum), &(dst->rule),
    +				    sizeof(p->rule->rulenum));
    +				/*
    +				 * store set number into high word of
    +				 * dst->rule pointer.
    +				 */
    +				bcopy(&(p->rule->set),
    +				    (char *)&dst->rule +
    +				    sizeof(p->rule->rulenum),
    +				    sizeof(p->rule->set));
    +				/*
    +				 * store a non-null value in "next".
    +				 * The userland code will interpret a
    +				 * NULL here as a marker
    +				 * for the last dynamic rule.
    +				 */
    +				bcopy(&dst, &dst->next, sizeof(dst));
    +				last = dst;
    +				dst->expire =
    +				    TIME_LEQ(dst->expire, time_uptime) ?
    +					0 : dst->expire - time_uptime ;
    +				bp += sizeof(ipfw_dyn_rule);
    +			}
    +		}
    +	IPFW_DYN_UNLOCK();
    +	if (last != NULL) /* mark last dynamic rule */
    +		bzero(&last->next, sizeof(last));
    +	*pbp = bp;
    +}
    +/* end of file */
    diff --git a/sys/netinet/ipfw/ip_fw_log.c b/sys/netinet/ipfw/ip_fw_log.c
    new file mode 100644
    index 00000000000..93bd19b22e1
    --- /dev/null
    +++ b/sys/netinet/ipfw/ip_fw_log.c
    @@ -0,0 +1,435 @@
    +/*-
    + * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
    + *
    + * 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$");
    +
    +/*
    + * Logging support for ipfw
    + */
    +
    +#if !defined(KLD_MODULE)
    +#include "opt_ipfw.h"
    +#include "opt_ipdivert.h"
    +#include "opt_ipdn.h"
    +#include "opt_inet.h"
    +#ifndef INET
    +#error IPFIREWALL requires INET.
    +#endif /* INET */
    +#endif
    +#include "opt_inet6.h"
    +#include "opt_ipsec.h"
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include  /* for ETHERTYPE_IP */
    +#include 
    +#include 
    +#include 	/* for IFT_ETHER */
    +#include 		/* for BPF */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#ifdef INET6
    +#include 	/* ip6_sprintf() */
    +#endif
    +
    +#ifdef MAC
    +#include 
    +#endif
    +
    +/*
    + * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
    + * Other macros just cast void * into the appropriate type
    + */
    +#define	L3HDR(T, ip)	((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
    +#define	TCP(p)		((struct tcphdr *)(p))
    +#define	SCTP(p)		((struct sctphdr *)(p))
    +#define	UDP(p)		((struct udphdr *)(p))
    +#define	ICMP(p)		((struct icmphdr *)(p))
    +#define	ICMP6(p)	((struct icmp6_hdr *)(p))
    +
    +#define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
    +#define SNP(buf) buf, sizeof(buf)
    +
    +#ifdef WITHOUT_BPF
    +void
    +ipfw_log_bpf(int onoff)
    +{
    +}
    +#else /* !WITHOUT_BPF */
    +static struct ifnet *log_if;	/* hook to attach to bpf */
    +
    +/* we use this dummy function for all ifnet callbacks */
    +static int
    +log_dummy(struct ifnet *ifp, u_long cmd, caddr_t addr)
    +{
    +	return EINVAL;
    +}
    +
    +void
    +ipfw_log_bpf(int onoff)
    +{
    +	struct ifnet *ifp;
    +
    +	if (onoff) {
    +		if (log_if)
    +			return;
    +		ifp = if_alloc(IFT_ETHER);
    +		if (ifp == NULL)
    +			return;
    +		if_initname(ifp, "ipfw", 0);
    +		ifp->if_mtu = 65536;
    +		ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
    +		ifp->if_init = (void *)log_dummy;
    +		ifp->if_ioctl = log_dummy;
    +		ifp->if_start = (void *)log_dummy;
    +		ifp->if_output = (void *)log_dummy;
    +		ifp->if_addrlen = 6;
    +		ifp->if_hdrlen = 14;
    +		if_attach(ifp);
    +		ifp->if_baudrate = IF_Mbps(10);
    +		bpfattach(ifp, DLT_EN10MB, 14);
    +		log_if = ifp;
    +	} else {
    +		if (log_if) {
    +			ether_ifdetach(log_if);
    +			if_free(log_if);
    +		}
    +		log_if = NULL;
    +	}
    +}
    +#endif /* !WITHOUT_BPF */
    +
    +/*
    + * We enter here when we have a rule with O_LOG.
    + * XXX this function alone takes about 2Kbytes of code!
    + */
    +void
    +ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
    +    struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
    +    struct ip *ip)
    +{
    +	char *action;
    +	int limit_reached = 0;
    +	char action2[40], proto[128], fragment[32];
    +
    +	if (V_fw_verbose == 0) {
    +#ifndef WITHOUT_BPF
    +		struct m_hdr mh;
    +
    +		if (log_if == NULL || log_if->if_bpf == NULL)
    +			return;
    +		/* BPF treats the "mbuf" as read-only */
    +		mh.mh_next = m;
    +		mh.mh_len = ETHER_HDR_LEN;
    +		if (args->eh) { /* layer2, use orig hdr */
    +			mh.mh_data = (char *)args->eh;
    +		} else {
    +			/* add fake header. Later we will store
    +			 * more info in the header
    +			 */
    +			mh.mh_data = "DDDDDDSSSSSS\x08\x00";
    +		}
    +		BPF_MTAP(log_if, (struct mbuf *)&mh);
    +#endif /* !WITHOUT_BPF */
    +		return;
    +	}
    +	/* the old 'log' function */
    +	fragment[0] = '\0';
    +	proto[0] = '\0';
    +
    +	if (f == NULL) {	/* bogus pkt */
    +		if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit)
    +			return;
    +		V_norule_counter++;
    +		if (V_norule_counter == V_verbose_limit)
    +			limit_reached = V_verbose_limit;
    +		action = "Refuse";
    +	} else {	/* O_LOG is the first action, find the real one */
    +		ipfw_insn *cmd = ACTION_PTR(f);
    +		ipfw_insn_log *l = (ipfw_insn_log *)cmd;
    +
    +		if (l->max_log != 0 && l->log_left == 0)
    +			return;
    +		l->log_left--;
    +		if (l->log_left == 0)
    +			limit_reached = l->max_log;
    +		cmd += F_LEN(cmd);	/* point to first action */
    +		if (cmd->opcode == O_ALTQ) {
    +			ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
    +
    +			snprintf(SNPARGS(action2, 0), "Altq %d",
    +				altq->qid);
    +			cmd += F_LEN(cmd);
    +		}
    +		if (cmd->opcode == O_PROB)
    +			cmd += F_LEN(cmd);
    +
    +		if (cmd->opcode == O_TAG)
    +			cmd += F_LEN(cmd);
    +
    +		action = action2;
    +		switch (cmd->opcode) {
    +		case O_DENY:
    +			action = "Deny";
    +			break;
    +
    +		case O_REJECT:
    +			if (cmd->arg1==ICMP_REJECT_RST)
    +				action = "Reset";
    +			else if (cmd->arg1==ICMP_UNREACH_HOST)
    +				action = "Reject";
    +			else
    +				snprintf(SNPARGS(action2, 0), "Unreach %d",
    +					cmd->arg1);
    +			break;
    +
    +		case O_UNREACH6:
    +			if (cmd->arg1==ICMP6_UNREACH_RST)
    +				action = "Reset";
    +			else
    +				snprintf(SNPARGS(action2, 0), "Unreach %d",
    +					cmd->arg1);
    +			break;
    +
    +		case O_ACCEPT:
    +			action = "Accept";
    +			break;
    +		case O_COUNT:
    +			action = "Count";
    +			break;
    +		case O_DIVERT:
    +			snprintf(SNPARGS(action2, 0), "Divert %d",
    +				cmd->arg1);
    +			break;
    +		case O_TEE:
    +			snprintf(SNPARGS(action2, 0), "Tee %d",
    +				cmd->arg1);
    +			break;
    +		case O_SETFIB:
    +			snprintf(SNPARGS(action2, 0), "SetFib %d",
    +				cmd->arg1);
    +			break;
    +		case O_SKIPTO:
    +			snprintf(SNPARGS(action2, 0), "SkipTo %d",
    +				cmd->arg1);
    +			break;
    +		case O_PIPE:
    +			snprintf(SNPARGS(action2, 0), "Pipe %d",
    +				cmd->arg1);
    +			break;
    +		case O_QUEUE:
    +			snprintf(SNPARGS(action2, 0), "Queue %d",
    +				cmd->arg1);
    +			break;
    +		case O_FORWARD_IP: {
    +			ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
    +			int len;
    +			struct in_addr dummyaddr;
    +			if (sa->sa.sin_addr.s_addr == INADDR_ANY)
    +				dummyaddr.s_addr = htonl(tablearg);
    +			else
    +				dummyaddr.s_addr = sa->sa.sin_addr.s_addr;
    +
    +			len = snprintf(SNPARGS(action2, 0), "Forward to %s",
    +				inet_ntoa(dummyaddr));
    +
    +			if (sa->sa.sin_port)
    +				snprintf(SNPARGS(action2, len), ":%d",
    +				    sa->sa.sin_port);
    +			}
    +			break;
    +		case O_NETGRAPH:
    +			snprintf(SNPARGS(action2, 0), "Netgraph %d",
    +				cmd->arg1);
    +			break;
    +		case O_NGTEE:
    +			snprintf(SNPARGS(action2, 0), "Ngtee %d",
    +				cmd->arg1);
    +			break;
    +		case O_NAT:
    +			action = "Nat";
    + 			break;
    +		case O_REASS:
    +			action = "Reass";
    +			break;
    +		default:
    +			action = "UNKNOWN";
    +			break;
    +		}
    +	}
    +
    +	if (hlen == 0) {	/* non-ip */
    +		snprintf(SNPARGS(proto, 0), "MAC");
    +
    +	} else {
    +		int len;
    +#ifdef INET6
    +		char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
    +#else
    +		char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
    +#endif
    +		struct icmphdr *icmp;
    +		struct tcphdr *tcp;
    +		struct udphdr *udp;
    +#ifdef INET6
    +		struct ip6_hdr *ip6 = NULL;
    +		struct icmp6_hdr *icmp6;
    +#endif
    +		src[0] = '\0';
    +		dst[0] = '\0';
    +#ifdef INET6
    +		if (IS_IP6_FLOW_ID(&(args->f_id))) {
    +			char ip6buf[INET6_ADDRSTRLEN];
    +			snprintf(src, sizeof(src), "[%s]",
    +			    ip6_sprintf(ip6buf, &args->f_id.src_ip6));
    +			snprintf(dst, sizeof(dst), "[%s]",
    +			    ip6_sprintf(ip6buf, &args->f_id.dst_ip6));
    +
    +			ip6 = (struct ip6_hdr *)ip;
    +			tcp = (struct tcphdr *)(((char *)ip) + hlen);
    +			udp = (struct udphdr *)(((char *)ip) + hlen);
    +		} else
    +#endif
    +		{
    +			tcp = L3HDR(struct tcphdr, ip);
    +			udp = L3HDR(struct udphdr, ip);
    +
    +			inet_ntoa_r(ip->ip_src, src);
    +			inet_ntoa_r(ip->ip_dst, dst);
    +		}
    +
    +		switch (args->f_id.proto) {
    +		case IPPROTO_TCP:
    +			len = snprintf(SNPARGS(proto, 0), "TCP %s", src);
    +			if (offset == 0)
    +				snprintf(SNPARGS(proto, len), ":%d %s:%d",
    +				    ntohs(tcp->th_sport),
    +				    dst,
    +				    ntohs(tcp->th_dport));
    +			else
    +				snprintf(SNPARGS(proto, len), " %s", dst);
    +			break;
    +
    +		case IPPROTO_UDP:
    +			len = snprintf(SNPARGS(proto, 0), "UDP %s", src);
    +			if (offset == 0)
    +				snprintf(SNPARGS(proto, len), ":%d %s:%d",
    +				    ntohs(udp->uh_sport),
    +				    dst,
    +				    ntohs(udp->uh_dport));
    +			else
    +				snprintf(SNPARGS(proto, len), " %s", dst);
    +			break;
    +
    +		case IPPROTO_ICMP:
    +			icmp = L3HDR(struct icmphdr, ip);
    +			if (offset == 0)
    +				len = snprintf(SNPARGS(proto, 0),
    +				    "ICMP:%u.%u ",
    +				    icmp->icmp_type, icmp->icmp_code);
    +			else
    +				len = snprintf(SNPARGS(proto, 0), "ICMP ");
    +			len += snprintf(SNPARGS(proto, len), "%s", src);
    +			snprintf(SNPARGS(proto, len), " %s", dst);
    +			break;
    +#ifdef INET6
    +		case IPPROTO_ICMPV6:
    +			icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen);
    +			if (offset == 0)
    +				len = snprintf(SNPARGS(proto, 0),
    +				    "ICMPv6:%u.%u ",
    +				    icmp6->icmp6_type, icmp6->icmp6_code);
    +			else
    +				len = snprintf(SNPARGS(proto, 0), "ICMPv6 ");
    +			len += snprintf(SNPARGS(proto, len), "%s", src);
    +			snprintf(SNPARGS(proto, len), " %s", dst);
    +			break;
    +#endif
    +		default:
    +			len = snprintf(SNPARGS(proto, 0), "P:%d %s",
    +			    args->f_id.proto, src);
    +			snprintf(SNPARGS(proto, len), " %s", dst);
    +			break;
    +		}
    +
    +#ifdef INET6
    +		if (IS_IP6_FLOW_ID(&(args->f_id))) {
    +			if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG))
    +				snprintf(SNPARGS(fragment, 0),
    +				    " (frag %08x:%d@%d%s)",
    +				    args->f_id.extra,
    +				    ntohs(ip6->ip6_plen) - hlen,
    +				    ntohs(offset & IP6F_OFF_MASK) << 3,
    +				    (offset & IP6F_MORE_FRAG) ? "+" : "");
    +		} else
    +#endif
    +		{
    +			int ipoff, iplen;
    +			ipoff = ntohs(ip->ip_off);
    +			iplen = ntohs(ip->ip_len);
    +			if (ipoff & (IP_MF | IP_OFFMASK))
    +				snprintf(SNPARGS(fragment, 0),
    +				    " (frag %d:%d@%d%s)",
    +				    ntohs(ip->ip_id), iplen - (ip->ip_hl << 2),
    +				    offset << 3,
    +				    (ipoff & IP_MF) ? "+" : "");
    +		}
    +	}
    +#ifdef __FreeBSD__
    +	if (oif || m->m_pkthdr.rcvif)
    +		log(LOG_SECURITY | LOG_INFO,
    +		    "ipfw: %d %s %s %s via %s%s\n",
    +		    f ? f->rulenum : -1,
    +		    action, proto, oif ? "out" : "in",
    +		    oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname,
    +		    fragment);
    +	else
    +#endif
    +		log(LOG_SECURITY | LOG_INFO,
    +		    "ipfw: %d %s %s [no if info]%s\n",
    +		    f ? f->rulenum : -1,
    +		    action, proto, fragment);
    +	if (limit_reached)
    +		log(LOG_SECURITY | LOG_NOTICE,
    +		    "ipfw: limit %d reached on entry %d\n",
    +		    limit_reached, f ? f->rulenum : -1);
    +}
    +/* end of file */
    diff --git a/sys/netinet/ipfw/ip_fw_nat.c b/sys/netinet/ipfw/ip_fw_nat.c
    index cd6a1cfd740..f30b754dc16 100644
    --- a/sys/netinet/ipfw/ip_fw_nat.c
    +++ b/sys/netinet/ipfw/ip_fw_nat.c
    @@ -29,114 +29,80 @@ __FBSDID("$FreeBSD$");
     
     #include 
     #include 
    -#include 
     #include 
     #include 
    -#include 
     #include 
     #include 
    -#include 
     #include 
    -#include 
    -#include 
     #include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    +
    +#define        IPFW_INTERNAL   /* Access to protected data structures in ip_fw.h. */
     
     #include 
     #include 
     
    -#define	IPFW_INTERNAL	/* Access to protected data structures in ip_fw.h. */
    -
     #include 
     #include 
     #include 
     #include 
    -#include 
     #include 
    +#include 
     #include 
    -#include 
    -#include 
    -#include 
     #include 
    -#include 
     
     #include 	/* XXX for in_cksum */
     
    -MALLOC_DECLARE(M_IPFW);
    -
     static VNET_DEFINE(eventhandler_tag, ifaddr_event_tag);
     #define	V_ifaddr_event_tag	VNET(ifaddr_event_tag)
     
    -extern ipfw_nat_t *ipfw_nat_ptr;
    -extern ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
    -extern ipfw_nat_cfg_t *ipfw_nat_del_ptr;
    -extern ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
    -extern ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
    -
    -static void 
    +static void
     ifaddr_change(void *arg __unused, struct ifnet *ifp)
     {
     	struct cfg_nat *ptr;
     	struct ifaddr *ifa;
    +	struct ip_fw_chain *chain;
     
    -	IPFW_WLOCK(&V_layer3_chain);			
    +	chain = &V_layer3_chain;
    +	IPFW_WLOCK(chain);
     	/* Check every nat entry... */
    -	LIST_FOREACH(ptr, &V_layer3_chain.nat, _next) {
    +	LIST_FOREACH(ptr, &chain->nat, _next) {
     		/* ...using nic 'ifp->if_xname' as dynamic alias address. */
    -		if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) == 0) {
    -			if_addr_rlock(ifp);
    -			TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
    -				if (ifa->ifa_addr == NULL)
    -					continue;
    -				if (ifa->ifa_addr->sa_family != AF_INET)
    -					continue;
    -				ptr->ip = ((struct sockaddr_in *) 
    -				    (ifa->ifa_addr))->sin_addr;
    -				LibAliasSetAddress(ptr->lib, ptr->ip);
    -			}
    -			if_addr_runlock(ifp);
    +		if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) != 0)
    +			continue;
    +		if_addr_rlock(ifp);
    +		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
    +			if (ifa->ifa_addr == NULL)
    +				continue;
    +			if (ifa->ifa_addr->sa_family != AF_INET)
    +				continue;
    +			ptr->ip = ((struct sockaddr_in *)
    +			    (ifa->ifa_addr))->sin_addr;
    +			LibAliasSetAddress(ptr->lib, ptr->ip);
     		}
    +		if_addr_runlock(ifp);
     	}
    -	IPFW_WUNLOCK(&V_layer3_chain);	
    +	IPFW_WUNLOCK(chain);
     }
     
    +/*
    + * delete the pointers for nat entry ix, or all of them if ix < 0
    + */
     static void
    -flush_nat_ptrs(const int i)
    +flush_nat_ptrs(struct ip_fw_chain *chain, const int ix)
     {
    -	struct ip_fw *rule;
    +	int i;
    +	ipfw_insn_nat *cmd;
     
    -	IPFW_WLOCK_ASSERT(&V_layer3_chain);
    -	for (rule = V_layer3_chain.rules; rule; rule = rule->next) {
    -		ipfw_insn_nat *cmd = (ipfw_insn_nat *)ACTION_PTR(rule);
    -		if (cmd->o.opcode != O_NAT)
    -			continue;
    -		if (cmd->nat != NULL && cmd->nat->id == i)
    +	IPFW_WLOCK_ASSERT(chain);
    +	for (i = 0; i < chain->n_rules; i++) {
    +		cmd = (ipfw_insn_nat *)ACTION_PTR(chain->map[i]);
    +		/* XXX skip log and the like ? */
    +		if (cmd->o.opcode == O_NAT && cmd->nat != NULL &&
    +			    (ix < 0 || cmd->nat->id == ix))
     			cmd->nat = NULL;
     	}
     }
     
    -#define HOOK_NAT(b, p) do {				\
    -		IPFW_WLOCK_ASSERT(&V_layer3_chain);	\
    -		LIST_INSERT_HEAD(b, p, _next);		\
    -	} while (0)
    -
    -#define UNHOOK_NAT(p) do {				\
    -		IPFW_WLOCK_ASSERT(&V_layer3_chain);	\
    -		LIST_REMOVE(p, _next);			\
    -	} while (0)
    -
    -#define HOOK_REDIR(b, p) do {			\
    -		LIST_INSERT_HEAD(b, p, _next);	\
    -	} while (0)
    -
    -#define HOOK_SPOOL(b, p) do {			\
    -		LIST_INSERT_HEAD(b, p, _next);	\
    -	} while (0)
    -
     static void
     del_redir_spool_cfg(struct cfg_nat *n, struct redir_chain *head)
     {
    @@ -165,9 +131,9 @@ del_redir_spool_cfg(struct cfg_nat *n, struct redir_chain *head)
     			free(r, M_IPFW);
     			break;
     		default:
    -			printf("unknown redirect mode: %u\n", r->mode);				
    +			printf("unknown redirect mode: %u\n", r->mode);
     			/* XXX - panic?!?!? */
    -			break; 
    +			break;
     		}
     	}
     }
    @@ -178,7 +144,6 @@ add_redir_spool_cfg(char *buf, struct cfg_nat *ptr)
     	struct cfg_redir *r, *ser_r;
     	struct cfg_spool *s, *ser_s;
     	int cnt, off, i;
    -	char *panic_err;
     
     	for (cnt = 0, off = 0; cnt < ptr->redir_cnt; cnt++) {
     		ser_r = (struct cfg_redir *)&buf[off];
    @@ -201,7 +166,7 @@ add_redir_spool_cfg(char *buf, struct cfg_nat *ptr)
     					remotePortCopy = 0;
     				r->alink[i] = LibAliasRedirectPort(ptr->lib,
     				    r->laddr, htons(r->lport + i), r->raddr,
    -				    htons(remotePortCopy), r->paddr, 
    +				    htons(remotePortCopy), r->paddr,
     				    htons(r->pport + i), r->proto);
     				if (r->alink[i] == NULL) {
     					r->alink[0] = NULL;
    @@ -215,30 +180,26 @@ add_redir_spool_cfg(char *buf, struct cfg_nat *ptr)
     			break;
     		default:
     			printf("unknown redirect mode: %u\n", r->mode);
    -			break; 
    +			break;
    +		}
    +		/* XXX perhaps return an error instead of panic ? */
    +		if (r->alink[0] == NULL)
    +			panic("LibAliasRedirect* returned NULL");
    +		/* LSNAT handling. */
    +		for (i = 0; i < r->spool_cnt; i++) {
    +			ser_s = (struct cfg_spool *)&buf[off];
    +			s = malloc(SOF_REDIR, M_IPFW, M_WAITOK | M_ZERO);
    +			memcpy(s, ser_s, SOF_SPOOL);
    +			LibAliasAddServer(ptr->lib, r->alink[0],
    +			    s->addr, htons(s->port));
    +			off += SOF_SPOOL;
    +			/* Hook spool entry. */
    +			LIST_INSERT_HEAD(&r->spool_chain, s, _next);
     		}
    -		if (r->alink[0] == NULL) {
    -			panic_err = "LibAliasRedirect* returned NULL";
    -			goto bad;
    -		} else /* LSNAT handling. */
    -			for (i = 0; i < r->spool_cnt; i++) {
    -				ser_s = (struct cfg_spool *)&buf[off];
    -				s = malloc(SOF_REDIR, M_IPFW, 
    -				    M_WAITOK | M_ZERO);
    -				memcpy(s, ser_s, SOF_SPOOL);
    -				LibAliasAddServer(ptr->lib, r->alink[0], 
    -				    s->addr, htons(s->port));
    -				off += SOF_SPOOL;
    -				/* Hook spool entry. */
    -				HOOK_SPOOL(&r->spool_chain, s);
    -			}
     		/* And finally hook this redir entry. */
    -		HOOK_REDIR(&ptr->redir_chain, r);
    +		LIST_INSERT_HEAD(&ptr->redir_chain, r, _next);
     	}
     	return (1);
    -bad:
    -	/* something really bad happened: panic! */
    -	panic("%s\n", panic_err);
     }
     
     static int
    @@ -252,101 +213,80 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
     
     	ldt = 0;
     	retval = 0;
    -	if ((mcl = m_megapullup(m, m->m_pkthdr.len)) ==
    -	    NULL)
    -		goto badnat;
    -	ip = mtod(mcl, struct ip *);
    -	if (args->eh == NULL) {
    -		ip->ip_len = htons(ip->ip_len);
    -		ip->ip_off = htons(ip->ip_off);
    +	mcl = m_megapullup(m, m->m_pkthdr.len);
    +	if (mcl == NULL) {
    +		args->m = NULL;
    +		return (IP_FW_DENY);
     	}
    +	ip = mtod(mcl, struct ip *);
     
    -	/* 
    +	/*
     	 * XXX - Libalias checksum offload 'duct tape':
    -	 * 
    -	 * locally generated packets have only
    -	 * pseudo-header checksum calculated
    -	 * and libalias will screw it[1], so
    -	 * mark them for later fix.  Moreover
    -	 * there are cases when libalias
    -	 * modify tcp packet data[2], mark it
    -	 * for later fix too.
     	 *
    -	 * [1] libalias was never meant to run
    -	 * in kernel, so it doesn't have any
    -	 * knowledge about checksum
    -	 * offloading, and it expects a packet
    -	 * with a full internet
    -	 * checksum. Unfortunately, packets
    -	 * generated locally will have just the
    -	 * pseudo header calculated, and when
    -	 * libalias tries to adjust the
    -	 * checksum it will actually screw it.
    +	 * locally generated packets have only pseudo-header checksum
    +	 * calculated and libalias will break it[1], so mark them for
    +	 * later fix.  Moreover there are cases when libalias modifies
    +	 * tcp packet data[2], mark them for later fix too.
     	 *
    -	 * [2] when libalias modify tcp's data
    -	 * content, full TCP checksum has to
    -	 * be recomputed: the problem is that
    -	 * libalias doesn't have any idea
    -	 * about checksum offloading To
    -	 * workaround this, we do not do
    -	 * checksumming in LibAlias, but only
    -	 * mark the packets in th_x2 field. If
    -	 * we receive a marked packet, we
    -	 * calculate correct checksum for it
    -	 * aware of offloading.  Why such a
    -	 * terrible hack instead of
    -	 * recalculating checksum for each
    -	 * packet?  Because the previous
    -	 * checksum was not checked!
    -	 * Recalculating checksums for EVERY
    -	 * packet will hide ALL transmission
    -	 * errors. Yes, marked packets still
    -	 * suffer from this problem. But,
    -	 * sigh, natd(8) has this problem,
    -	 * too.
    +	 * [1] libalias was never meant to run in kernel, so it does
    +	 * not have any knowledge about checksum offloading, and
    +	 * expects a packet with a full internet checksum.
    +	 * Unfortunately, packets generated locally will have just the
    +	 * pseudo header calculated, and when libalias tries to adjust
    +	 * the checksum it will actually compute a wrong value.
    +	 *
    +	 * [2] when libalias modifies tcp's data content, full TCP
    +	 * checksum has to be recomputed: the problem is that
    +	 * libalias does not have any idea about checksum offloading.
    +	 * To work around this, we do not do checksumming in LibAlias,
    +	 * but only mark the packets in th_x2 field. If we receive a
    +	 * marked packet, we calculate correct checksum for it
    +	 * aware of offloading.  Why such a terrible hack instead of
    +	 * recalculating checksum for each packet?
    +	 * Because the previous checksum was not checked!
    +	 * Recalculating checksums for EVERY packet will hide ALL
    +	 * transmission errors. Yes, marked packets still suffer from
    +	 * this problem. But, sigh, natd(8) has this problem, too.
     	 *
     	 * TODO: -make libalias mbuf aware (so
     	 * it can handle delayed checksum and tso)
     	 */
     
    -	if (mcl->m_pkthdr.rcvif == NULL && 
    -	    mcl->m_pkthdr.csum_flags & 
    -	    CSUM_DELAY_DATA)
    +	if (mcl->m_pkthdr.rcvif == NULL &&
    +	    mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA)
     		ldt = 1;
     
     	c = mtod(mcl, char *);
     	if (args->oif == NULL)
    -		retval = LibAliasIn(t->lib, c, 
    +		retval = LibAliasIn(t->lib, c,
     			mcl->m_len + M_TRAILINGSPACE(mcl));
     	else
    -		retval = LibAliasOut(t->lib, c, 
    +		retval = LibAliasOut(t->lib, c,
     			mcl->m_len + M_TRAILINGSPACE(mcl));
     	if (retval == PKT_ALIAS_RESPOND) {
    -	  m->m_flags |= M_SKIP_FIREWALL;
    -	  retval = PKT_ALIAS_OK;
    +		m->m_flags |= M_SKIP_FIREWALL;
    +		retval = PKT_ALIAS_OK;
     	}
     	if (retval != PKT_ALIAS_OK &&
     	    retval != PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
     		/* XXX - should i add some logging? */
     		m_free(mcl);
    -	badnat:
     		args->m = NULL;
     		return (IP_FW_DENY);
     	}
    -	mcl->m_pkthdr.len = mcl->m_len = 
    -	    ntohs(ip->ip_len);
    +	mcl->m_pkthdr.len = mcl->m_len = ntohs(ip->ip_len);
     
    -	/* 
    -	 * XXX - libalias checksum offload 
    -	 * 'duct tape' (see above) 
    +	/*
    +	 * XXX - libalias checksum offload
    +	 * 'duct tape' (see above)
     	 */
     
    -	if ((ip->ip_off & htons(IP_OFFMASK)) == 0 && 
    +	if ((ip->ip_off & htons(IP_OFFMASK)) == 0 &&
     	    ip->ip_p == IPPROTO_TCP) {
    -		struct tcphdr 	*th; 
    +		struct tcphdr 	*th;
     
     		th = (struct tcphdr *)(ip + 1);
    -		if (th->th_x2) 
    +		if (th->th_x2)
     			ldt = 1;
     	}
     
    @@ -355,82 +295,83 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
     		struct udphdr 	*uh;
     		u_short cksum;
     
    -		ip->ip_len = ntohs(ip->ip_len);
    +		/* XXX check if ip_len can stay in net format */
     		cksum = in_pseudo(
     		    ip->ip_src.s_addr,
    -		    ip->ip_dst.s_addr, 
    -		    htons(ip->ip_p + ip->ip_len - (ip->ip_hl << 2))
    +		    ip->ip_dst.s_addr,
    +		    htons(ip->ip_p + ntohs(ip->ip_len) - (ip->ip_hl << 2))
     		);
    -					
    +
     		switch (ip->ip_p) {
     		case IPPROTO_TCP:
     			th = (struct tcphdr *)(ip + 1);
    -			/* 
    -			 * Maybe it was set in 
    -			 * libalias... 
    +			/*
    +			 * Maybe it was set in
    +			 * libalias...
     			 */
     			th->th_x2 = 0;
     			th->th_sum = cksum;
    -			mcl->m_pkthdr.csum_data = 
    +			mcl->m_pkthdr.csum_data =
     			    offsetof(struct tcphdr, th_sum);
     			break;
     		case IPPROTO_UDP:
     			uh = (struct udphdr *)(ip + 1);
     			uh->uh_sum = cksum;
    -			mcl->m_pkthdr.csum_data = 
    +			mcl->m_pkthdr.csum_data =
     			    offsetof(struct udphdr, uh_sum);
    -			break;						
    +			break;
     		}
    -		/* 
    -		 * No hw checksum offloading: do it 
    -		 * by ourself. 
    -		 */
    -		if ((mcl->m_pkthdr.csum_flags & 
    -		     CSUM_DELAY_DATA) == 0) {
    +		/* No hw checksum offloading: do it ourselves */
    +		if ((mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA) == 0) {
     			in_delayed_cksum(mcl);
    -			mcl->m_pkthdr.csum_flags &= 
    -			    ~CSUM_DELAY_DATA;
    +			mcl->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
     		}
    -		ip->ip_len = htons(ip->ip_len);
     	}
    -
    -	if (args->eh == NULL) {
    -		ip->ip_len = ntohs(ip->ip_len);
    -		ip->ip_off = ntohs(ip->ip_off);
    -	}
    -
     	args->m = mcl;
     	return (IP_FW_NAT);
     }
     
    -static int 
    +static struct cfg_nat *
    +lookup_nat(struct nat_list *l, int nat_id)
    +{
    +	struct cfg_nat *res;
    +
    +	LIST_FOREACH(res, l, _next) {
    +		if (res->id == nat_id)
    +			break;
    +	}
    +	return res;
    +}
    +
    +static int
     ipfw_nat_cfg(struct sockopt *sopt)
     {
     	struct cfg_nat *ptr, *ser_n;
     	char *buf;
    +	struct ip_fw_chain *chain = &V_layer3_chain;
     
     	buf = malloc(NAT_BUF_LEN, M_IPFW, M_WAITOK | M_ZERO);
    -	sooptcopyin(sopt, buf, NAT_BUF_LEN, 
    -	    sizeof(struct cfg_nat));
    +	sooptcopyin(sopt, buf, NAT_BUF_LEN, sizeof(struct cfg_nat));
     	ser_n = (struct cfg_nat *)buf;
     
    -	/* 
    +	/* check valid parameter ser_n->id > 0 ? */
    +	/*
     	 * Find/create nat rule.
     	 */
    -	IPFW_WLOCK(&V_layer3_chain);
    -	LOOKUP_NAT(V_layer3_chain, ser_n->id, ptr);
    +	IPFW_WLOCK(chain);
    +	ptr = lookup_nat(&chain->nat, ser_n->id);
     	if (ptr == NULL) {
     		/* New rule: allocate and init new instance. */
    -		ptr = malloc(sizeof(struct cfg_nat), 
    +		ptr = malloc(sizeof(struct cfg_nat),
     		    M_IPFW, M_NOWAIT | M_ZERO);
     		if (ptr == NULL) {
    -			IPFW_WUNLOCK(&V_layer3_chain);				
    +			IPFW_WUNLOCK(chain);
     			free(buf, M_IPFW);
     			return (ENOSPC);
     		}
     		ptr->lib = LibAliasInit(NULL);
     		if (ptr->lib == NULL) {
    -			IPFW_WUNLOCK(&V_layer3_chain);
    +			IPFW_WUNLOCK(chain);
     			free(ptr, M_IPFW);
     			free(buf, M_IPFW);
     			return (EINVAL);
    @@ -438,18 +379,18 @@ ipfw_nat_cfg(struct sockopt *sopt)
     		LIST_INIT(&ptr->redir_chain);
     	} else {
     		/* Entry already present: temporarly unhook it. */
    -		UNHOOK_NAT(ptr);
    -		flush_nat_ptrs(ser_n->id);
    +		LIST_REMOVE(ptr, _next);
    +		flush_nat_ptrs(chain, ser_n->id);
     	}
    -	IPFW_WUNLOCK(&V_layer3_chain);
    +	IPFW_WUNLOCK(chain);
     
    -	/* 
    +	/*
     	 * Basic nat configuration.
     	 */
     	ptr->id = ser_n->id;
    -	/* 
    -	 * XXX - what if this rule doesn't nat any ip and just 
    -	 * redirect? 
    +	/*
    +	 * XXX - what if this rule doesn't nat any ip and just
    +	 * redirect?
     	 * do we set aliasaddress to 0.0.0.0?
     	 */
     	ptr->ip = ser_n->ip;
    @@ -459,7 +400,7 @@ ipfw_nat_cfg(struct sockopt *sopt)
     	LibAliasSetAddress(ptr->lib, ptr->ip);
     	memcpy(ptr->if_name, ser_n->if_name, IF_NAMESIZE);
     
    -	/* 
    +	/*
     	 * Redir and LSNAT configuration.
     	 */
     	/* Delete old cfgs. */
    @@ -467,9 +408,9 @@ ipfw_nat_cfg(struct sockopt *sopt)
     	/* Add new entries. */
     	add_redir_spool_cfg(&buf[(sizeof(struct cfg_nat))], ptr);
     	free(buf, M_IPFW);
    -	IPFW_WLOCK(&V_layer3_chain);
    -	HOOK_NAT(&V_layer3_chain.nat, ptr);
    -	IPFW_WUNLOCK(&V_layer3_chain);
    +	IPFW_WLOCK(chain);
    +	LIST_INSERT_HEAD(&chain->nat, ptr, _next);
    +	IPFW_WUNLOCK(chain);
     	return (0);
     }
     
    @@ -477,18 +418,20 @@ static int
     ipfw_nat_del(struct sockopt *sopt)
     {
     	struct cfg_nat *ptr;
    +	struct ip_fw_chain *chain = &V_layer3_chain;
     	int i;
    -		
    +
     	sooptcopyin(sopt, &i, sizeof i, sizeof i);
    -	IPFW_WLOCK(&V_layer3_chain);
    -	LOOKUP_NAT(V_layer3_chain, i, ptr);
    +	/* XXX validate i */
    +	IPFW_WLOCK(chain);
    +	ptr = lookup_nat(&chain->nat, i);
     	if (ptr == NULL) {
    -		IPFW_WUNLOCK(&V_layer3_chain);
    +		IPFW_WUNLOCK(chain);
     		return (EINVAL);
     	}
    -	UNHOOK_NAT(ptr);
    -	flush_nat_ptrs(i);
    -	IPFW_WUNLOCK(&V_layer3_chain);
    +	LIST_REMOVE(ptr, _next);
    +	flush_nat_ptrs(chain, i);
    +	IPFW_WUNLOCK(chain);
     	del_redir_spool_cfg(ptr, &ptr->redir_chain);
     	LibAliasUninit(ptr->lib);
     	free(ptr, M_IPFW);
    @@ -497,56 +440,53 @@ ipfw_nat_del(struct sockopt *sopt)
     
     static int
     ipfw_nat_get_cfg(struct sockopt *sopt)
    -{	
    +{
     	uint8_t *data;
     	struct cfg_nat *n;
     	struct cfg_redir *r;
     	struct cfg_spool *s;
     	int nat_cnt, off;
    -		
    +	struct ip_fw_chain *chain;
    +	int err = ENOSPC;
    +
    +	chain = &V_layer3_chain;
     	nat_cnt = 0;
     	off = sizeof(nat_cnt);
     
     	data = malloc(NAT_BUF_LEN, M_IPFW, M_WAITOK | M_ZERO);
    -	IPFW_RLOCK(&V_layer3_chain);
    +	IPFW_RLOCK(chain);
     	/* Serialize all the data. */
    -	LIST_FOREACH(n, &V_layer3_chain.nat, _next) {
    +	LIST_FOREACH(n, &chain->nat, _next) {
     		nat_cnt++;
    -		if (off + SOF_NAT < NAT_BUF_LEN) {
    -			bcopy(n, &data[off], SOF_NAT);
    -			off += SOF_NAT;
    -			LIST_FOREACH(r, &n->redir_chain, _next) {
    -				if (off + SOF_REDIR < NAT_BUF_LEN) {
    -					bcopy(r, &data[off], 
    -					    SOF_REDIR);
    -					off += SOF_REDIR;
    -					LIST_FOREACH(s, &r->spool_chain, 
    -					    _next) {
    -						if (off + SOF_SPOOL < 
    -						    NAT_BUF_LEN) {
    -							bcopy(s, &data[off],
    -							    SOF_SPOOL);
    -							off += SOF_SPOOL;
    -						} else
    -							goto nospace;
    -					}
    -				} else
    -					goto nospace;
    -			}
    -		} else
    +		if (off + SOF_NAT >= NAT_BUF_LEN)
     			goto nospace;
    +		bcopy(n, &data[off], SOF_NAT);
    +		off += SOF_NAT;
    +		LIST_FOREACH(r, &n->redir_chain, _next) {
    +			if (off + SOF_REDIR >= NAT_BUF_LEN)
    +				goto nospace;
    +			bcopy(r, &data[off], SOF_REDIR);
    +			off += SOF_REDIR;
    +			LIST_FOREACH(s, &r->spool_chain, _next) {
    +				if (off + SOF_SPOOL >= NAT_BUF_LEN)
    +					goto nospace;
    +				bcopy(s, &data[off], SOF_SPOOL);
    +				off += SOF_SPOOL;
    +			}
    +		}
     	}
    -	bcopy(&nat_cnt, data, sizeof(nat_cnt));
    -	IPFW_RUNLOCK(&V_layer3_chain);
    -	sooptcopyout(sopt, data, NAT_BUF_LEN);
    -	free(data, M_IPFW);
    -	return (0);
    +	err = 0; /* all good */
     nospace:
    -	IPFW_RUNLOCK(&V_layer3_chain);
    -	printf("serialized data buffer not big enough:"
    -	    "please increase NAT_BUF_LEN\n");
    +	IPFW_RUNLOCK(chain);
    +	if (err == 0) {
    +		bcopy(&nat_cnt, data, sizeof(nat_cnt));
    +		sooptcopyout(sopt, data, NAT_BUF_LEN);
    +	} else {
    +		printf("serialized data buffer not big enough:"
    +		    "please increase NAT_BUF_LEN\n");
    +	}
     	free(data, M_IPFW);
    -	return (ENOSPC);
    +	return (err);
     }
     
     static int
    @@ -554,30 +494,35 @@ ipfw_nat_get_log(struct sockopt *sopt)
     {
     	uint8_t *data;
     	struct cfg_nat *ptr;
    -	int i, size, cnt, sof;
    +	int i, size;
    +	struct ip_fw_chain *chain;
     
    -	data = NULL;
    -	sof = LIBALIAS_BUF_SIZE;
    -	cnt = 0;
    +	chain = &V_layer3_chain;
     
    -	IPFW_RLOCK(&V_layer3_chain);
    -	size = i = 0;
    -	LIST_FOREACH(ptr, &V_layer3_chain.nat, _next) {
    -		if (ptr->lib->logDesc == NULL) 
    +	IPFW_RLOCK(chain);
    +	/* one pass to count, one to copy the data */
    +	i = 0;
    +	LIST_FOREACH(ptr, &chain->nat, _next) {
    +		if (ptr->lib->logDesc == NULL)
    +			continue;
    +		i++;
    +	}
    +	size = i * (LIBALIAS_BUF_SIZE + sizeof(int));
    +	data = malloc(size, M_IPFW, M_NOWAIT | M_ZERO);
    +	if (data == NULL) {
    +		IPFW_RUNLOCK(chain);
    +		return (ENOSPC);
    +	}
    +	i = 0;
    +	LIST_FOREACH(ptr, &chain->nat, _next) {
    +		if (ptr->lib->logDesc == NULL)
     			continue;
    -		cnt++;
    -		size = cnt * (sof + sizeof(int));
    -		data = realloc(data, size, M_IPFW, M_NOWAIT | M_ZERO);
    -		if (data == NULL) {
    -			IPFW_RUNLOCK(&V_layer3_chain);
    -			return (ENOSPC);
    -		}
     		bcopy(&ptr->id, &data[i], sizeof(int));
     		i += sizeof(int);
    -		bcopy(ptr->lib->logDesc, &data[i], sof);
    -		i += sof;
    +		bcopy(ptr->lib->logDesc, &data[i], LIBALIAS_BUF_SIZE);
    +		i += LIBALIAS_BUF_SIZE;
     	}
    -	IPFW_RUNLOCK(&V_layer3_chain);
    +	IPFW_RUNLOCK(chain);
     	sooptcopyout(sopt, data, size);
     	free(data, M_IPFW);
     	return(0);
    @@ -590,38 +535,41 @@ ipfw_nat_init(void)
     	IPFW_WLOCK(&V_layer3_chain);
     	/* init ipfw hooks */
     	ipfw_nat_ptr = ipfw_nat;
    +	lookup_nat_ptr = lookup_nat;
     	ipfw_nat_cfg_ptr = ipfw_nat_cfg;
     	ipfw_nat_del_ptr = ipfw_nat_del;
     	ipfw_nat_get_cfg_ptr = ipfw_nat_get_cfg;
     	ipfw_nat_get_log_ptr = ipfw_nat_get_log;
     	IPFW_WUNLOCK(&V_layer3_chain);
    -	V_ifaddr_event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_change, 
    +	V_ifaddr_event_tag = EVENTHANDLER_REGISTER(
    +	    ifaddr_event, ifaddr_change,
     	    NULL, EVENTHANDLER_PRI_ANY);
     }
     
     static void
     ipfw_nat_destroy(void)
     {
    -	struct ip_fw *rule;
     	struct cfg_nat *ptr, *ptr_temp;
    -	
    -	IPFW_WLOCK(&V_layer3_chain);
    -	LIST_FOREACH_SAFE(ptr, &V_layer3_chain.nat, _next, ptr_temp) {
    +	struct ip_fw_chain *chain;
    +
    +	chain = &V_layer3_chain;
    +	IPFW_WLOCK(chain);
    +	LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) {
     		LIST_REMOVE(ptr, _next);
     		del_redir_spool_cfg(ptr, &ptr->redir_chain);
     		LibAliasUninit(ptr->lib);
     		free(ptr, M_IPFW);
     	}
     	EVENTHANDLER_DEREGISTER(ifaddr_event, V_ifaddr_event_tag);
    -	/* flush all nat ptrs */
    -	for (rule = V_layer3_chain.rules; rule; rule = rule->next) {
    -		ipfw_insn_nat *cmd = (ipfw_insn_nat *)ACTION_PTR(rule);
    -		if (cmd->o.opcode == O_NAT)
    -			cmd->nat = NULL;
    -	}
    +	flush_nat_ptrs(chain, -1 /* flush all */);
     	/* deregister ipfw_nat */
     	ipfw_nat_ptr = NULL;
    -	IPFW_WUNLOCK(&V_layer3_chain);
    +	lookup_nat_ptr = NULL;
    +	ipfw_nat_cfg_ptr = NULL;
    +	ipfw_nat_del_ptr = NULL;
    +	ipfw_nat_get_cfg_ptr = NULL;
    +	ipfw_nat_get_log_ptr = NULL;
    +	IPFW_WUNLOCK(chain);
     }
     
     static int
    @@ -655,3 +603,4 @@ DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY
     MODULE_DEPEND(ipfw_nat, libalias, 1, 1, 1);
     MODULE_DEPEND(ipfw_nat, ipfw, 2, 2, 2);
     MODULE_VERSION(ipfw_nat, 1);
    +/* end of file */
    diff --git a/sys/netinet/ipfw/ip_fw_pfil.c b/sys/netinet/ipfw/ip_fw_pfil.c
    index db7308407a8..b4e31d4c8c8 100644
    --- a/sys/netinet/ipfw/ip_fw_pfil.c
    +++ b/sys/netinet/ipfw/ip_fw_pfil.c
    @@ -46,9 +46,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    -#include 
     #include 
    -#include 
     
     #include 
     #include 
    @@ -60,471 +58,326 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    -#include 
    -#include 
    -
    +#include 
     #include 
     
     #include 
     
    -VNET_DEFINE(int, fw_enable) = 1;
    +static VNET_DEFINE(int, fw_enable) = 1;
    +#define V_fw_enable	VNET(fw_enable)
    +
     #ifdef INET6
    -VNET_DEFINE(int, fw6_enable) = 1;
    +static VNET_DEFINE(int, fw6_enable) = 1;
    +#define V_fw6_enable	VNET(fw6_enable)
     #endif
     
     int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
     
    -/* Divert hooks. */
    -ip_divert_packet_t *ip_divert_ptr = NULL;
    -
    -/* ng_ipfw hooks. */
    -ng_ipfw_input_t *ng_ipfw_input_p = NULL;
    -
     /* Forward declarations. */
    -static int	ipfw_divert(struct mbuf **, int, int);
    -#define	DIV_DIR_IN	1
    -#define	DIV_DIR_OUT	0
    +static int ipfw_divert(struct mbuf **, int, struct ipfw_rule_ref *, int);
     
    +#ifdef SYSCTL_NODE
    +
    +SYSBEGIN(f1)
    +
    +SYSCTL_DECL(_net_inet_ip_fw);
    +SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AUTO, enable,
    +    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_enable), 0,
    +    ipfw_chg_hook, "I", "Enable ipfw");
    +#ifdef INET6
    +SYSCTL_DECL(_net_inet6_ip6_fw);
    +SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_AUTO, enable,
    +    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw6_enable), 0,
    +    ipfw_chg_hook, "I", "Enable ipfw+6");
    +#endif /* INET6 */
    +
    +SYSEND
    +
    +#endif /* SYSCTL_NODE */
    +
    +/*
    + * The pfilter hook to pass packets to ipfw_chk and then to
    + * dummynet, divert, netgraph or other modules.
    + * The packet may be consumed.
    + */
     int
    -ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
    +ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
         struct inpcb *inp)
     {
     	struct ip_fw_args args;
    -	struct ng_ipfw_tag *ng_tag;
    -	struct m_tag *dn_tag;
    -	int ipfw = 0;
    -	int divert;
    -	int tee;
    -#ifdef IPFIREWALL_FORWARD
    -	struct m_tag *fwd_tag;
    -#endif
    +	struct m_tag *tag;
    +	int ipfw;
    +	int ret;
     
    -	KASSERT(dir == PFIL_IN, ("ipfw_check_in wrong direction!"));
    +	/* all the processing now uses ip_len in net format */
    +	if (mtod(*m0, struct ip *)->ip_v == 4)
    +		SET_NET_IPLEN(mtod(*m0, struct ip *));
     
    +	/* convert dir to IPFW values */
    +	dir = (dir == PFIL_IN) ? DIR_IN : DIR_OUT;
     	bzero(&args, sizeof(args));
     
    -	ng_tag = (struct ng_ipfw_tag *)m_tag_locate(*m0, NGM_IPFW_COOKIE, 0,
    -	    NULL);
    -	if (ng_tag != NULL) {
    -		KASSERT(ng_tag->dir == NG_IPFW_IN,
    -		    ("ng_ipfw tag with wrong direction"));
    -		args.rule = ng_tag->rule;
    -		args.rule_id = ng_tag->rule_id;
    -		args.chain_id = ng_tag->chain_id;
    -		m_tag_delete(*m0, (struct m_tag *)ng_tag);
    -	}
    -
     again:
    -	dn_tag = m_tag_find(*m0, PACKET_TAG_DUMMYNET, NULL);
    -	if (dn_tag != NULL){
    -		struct dn_pkt_tag *dt;
    -
    -		dt = (struct dn_pkt_tag *)(dn_tag+1);
    -		args.rule = dt->rule;
    -		args.rule_id = dt->rule_id;
    -		args.chain_id = dt->chain_id;
    -
    -		m_tag_delete(*m0, dn_tag);
    -	}
    -
    -	args.m = *m0;
    -	args.inp = inp;
    -	tee = 0;
    -
    -	if (V_fw_one_pass == 0 || args.rule == NULL) {
    -		ipfw = ipfw_chk(&args);
    -		*m0 = args.m;
    -	} else
    -		ipfw = IP_FW_PASS;
    -		
    -	KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
    -	    __func__));
    -
    -	switch (ipfw) {
    -	case IP_FW_PASS:
    -		if (args.next_hop == NULL)
    -			goto pass;
    -
    -#ifdef IPFIREWALL_FORWARD
    -		fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD,
    -				sizeof(struct sockaddr_in), M_NOWAIT);
    -		if (fwd_tag == NULL)
    -			goto drop;
    -		bcopy(args.next_hop, (fwd_tag+1), sizeof(struct sockaddr_in));
    -		m_tag_prepend(*m0, fwd_tag);
    -
    -		if (in_localip(args.next_hop->sin_addr))
    -			(*m0)->m_flags |= M_FASTFWD_OURS;
    -		goto pass;
    -#endif
    -		break;			/* not reached */
    -
    -	case IP_FW_DENY:
    -		goto drop;
    -		break;			/* not reached */
    -
    -	case IP_FW_DUMMYNET:
    -		if (ip_dn_io_ptr == NULL)
    -			goto drop;
    -		if (mtod(*m0, struct ip *)->ip_v == 4)
    -			ip_dn_io_ptr(m0, DN_TO_IP_IN, &args);
    -		else if (mtod(*m0, struct ip *)->ip_v == 6)
    -			ip_dn_io_ptr(m0, DN_TO_IP6_IN, &args);
    -		if (*m0 != NULL)
    -			goto again;
    -		return 0;		/* packet consumed */
    -
    -	case IP_FW_TEE:
    -		tee = 1;
    -		/* fall through */
    -
    -	case IP_FW_DIVERT:
    -		divert = ipfw_divert(m0, DIV_DIR_IN, tee);
    -		if (divert) {
    -			*m0 = NULL;
    -			return 0;	/* packet consumed */
    -		} else {
    -			args.rule = NULL;
    -			goto again;	/* continue with packet */
    +	/*
    +	 * extract and remove the tag if present. If we are left
    +	 * with onepass, optimize the outgoing path.
    +	 */
    +	tag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
    +	if (tag != NULL) {
    +		args.rule = *((struct ipfw_rule_ref *)(tag+1));
    +		m_tag_delete(*m0, tag);
    +		if (args.rule.info & IPFW_ONEPASS) {
    +			SET_HOST_IPLEN(mtod(*m0, struct ip *));
    +			return 0;
     		}
    -
    -	case IP_FW_NGTEE:
    -		if (!NG_IPFW_LOADED)
    -			goto drop;
    -		(void)ng_ipfw_input_p(m0, NG_IPFW_IN, &args, 1);
    -		goto again;		/* continue with packet */
    -
    -	case IP_FW_NETGRAPH:
    -		if (!NG_IPFW_LOADED)
    -			goto drop;
    -		return ng_ipfw_input_p(m0, NG_IPFW_IN, &args, 0);
    -		
    -	case IP_FW_NAT:
    -		goto again;		/* continue with packet */
    -
    -	case IP_FW_REASS:
    -		goto again;
    -
    -	default:
    -		KASSERT(0, ("%s: unknown retval", __func__));
    -	}
    -
    -drop:
    -	if (*m0)
    -		m_freem(*m0);
    -	*m0 = NULL;
    -	return (EACCES);
    -pass:
    -	return 0;	/* not filtered */
    -}
    -
    -int
    -ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
    -    struct inpcb *inp)
    -{
    -	struct ip_fw_args args;
    -	struct ng_ipfw_tag *ng_tag;
    -	struct m_tag *dn_tag;
    -	int ipfw = 0;
    -	int divert;
    -	int tee;
    -#ifdef IPFIREWALL_FORWARD
    -	struct m_tag *fwd_tag;
    -#endif
    -
    -	KASSERT(dir == PFIL_OUT, ("ipfw_check_out wrong direction!"));
    -
    -	bzero(&args, sizeof(args));
    -
    -	ng_tag = (struct ng_ipfw_tag *)m_tag_locate(*m0, NGM_IPFW_COOKIE, 0,
    -	    NULL);
    -	if (ng_tag != NULL) {
    -		KASSERT(ng_tag->dir == NG_IPFW_OUT,
    -		    ("ng_ipfw tag with wrong direction"));
    -		args.rule = ng_tag->rule;
    -		args.rule_id = ng_tag->rule_id;
    -		args.chain_id = ng_tag->chain_id;
    -		m_tag_delete(*m0, (struct m_tag *)ng_tag);
    -	}
    -
    -again:
    -	dn_tag = m_tag_find(*m0, PACKET_TAG_DUMMYNET, NULL);
    -	if (dn_tag != NULL) {
    -		struct dn_pkt_tag *dt;
    -
    -		dt = (struct dn_pkt_tag *)(dn_tag+1);
    -		args.rule = dt->rule;
    -		args.rule_id = dt->rule_id;
    -		args.chain_id = dt->chain_id;
    -
    -		m_tag_delete(*m0, dn_tag);
     	}
     
     	args.m = *m0;
    -	args.oif = ifp;
    +	args.oif = dir == DIR_OUT ? ifp : NULL;
     	args.inp = inp;
    -	tee = 0;
     
    -	if (V_fw_one_pass == 0 || args.rule == NULL) {
    -		ipfw = ipfw_chk(&args);
    -		*m0 = args.m;
    -	} else
    -		ipfw = IP_FW_PASS;
    +	ipfw = ipfw_chk(&args);
    +	*m0 = args.m;
     
     	KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
     	    __func__));
     
    +	/* breaking out of the switch means drop */
    +	ret = 0;	/* default return value for pass */
     	switch (ipfw) {
     	case IP_FW_PASS:
    +		/* next_hop may be set by ipfw_chk */
                     if (args.next_hop == NULL)
    -                        goto pass;
    -#ifdef IPFIREWALL_FORWARD
    -		/* Overwrite existing tag. */
    -		fwd_tag = m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL);
    -		if (fwd_tag == NULL) {
    +                        break; /* pass */
    +#ifndef IPFIREWALL_FORWARD
    +		ret = EACCES;
    +#else
    +	    {
    +		struct m_tag *fwd_tag;
    +
    +		/* Incoming packets should not be tagged so we do not
    +		 * m_tag_find. Outgoing packets may be tagged, so we
    +		 * reuse the tag if present.
    +		 */
    +		fwd_tag = (dir == DIR_IN) ? NULL :
    +			m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL);
    +		if (fwd_tag != NULL) {
    +			m_tag_unlink(*m0, fwd_tag);
    +		} else {
     			fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD,
     				sizeof(struct sockaddr_in), M_NOWAIT);
    -			if (fwd_tag == NULL)
    -				goto drop;
    -		} else
    -			m_tag_unlink(*m0, fwd_tag);
    +			if (fwd_tag == NULL) {
    +				ret = EACCES;
    +				break; /* i.e. drop */
    +			}
    +		}
     		bcopy(args.next_hop, (fwd_tag+1), sizeof(struct sockaddr_in));
     		m_tag_prepend(*m0, fwd_tag);
     
     		if (in_localip(args.next_hop->sin_addr))
     			(*m0)->m_flags |= M_FASTFWD_OURS;
    -		goto pass;
    +	    }
     #endif
    -		break;			/* not reached */
    +		break;
     
     	case IP_FW_DENY:
    -		goto drop;
    -		break;  		/* not reached */
    +		ret = EACCES;
    +		break; /* i.e. drop */
     
     	case IP_FW_DUMMYNET:
    +		ret = EACCES;
     		if (ip_dn_io_ptr == NULL)
    -			break;
    +			break; /* i.e. drop */
     		if (mtod(*m0, struct ip *)->ip_v == 4)
    -			ip_dn_io_ptr(m0, DN_TO_IP_OUT, &args);
    +			ret = ip_dn_io_ptr(m0, dir, &args);
     		else if (mtod(*m0, struct ip *)->ip_v == 6)
    -			ip_dn_io_ptr(m0, DN_TO_IP6_OUT, &args);
    +			ret = ip_dn_io_ptr(m0, dir | PROTO_IPV6, &args);
    +		else
    +			break; /* drop it */
    +		/*
    +		 * XXX should read the return value.
    +		 * dummynet normally eats the packet and sets *m0=NULL
    +		 * unless the packet can be sent immediately. In this
    +		 * case args is updated and we should re-run the
    +		 * check without clearing args.
    +		 */
     		if (*m0 != NULL)
     			goto again;
    -		return 0;		/* packet consumed */
    -
     		break;
     
     	case IP_FW_TEE:
    -		tee = 1;
    -		/* fall through */
    -
     	case IP_FW_DIVERT:
    -		divert = ipfw_divert(m0, DIV_DIR_OUT, tee);
    -		if (divert) {
    -			*m0 = NULL;
    -			return 0;	/* packet consumed */
    -		} else {
    -			args.rule = NULL;
    -			goto again;	/* continue with packet */
    +		if (ip_divert_ptr == NULL) {
    +			ret = EACCES;
    +			break; /* i.e. drop */
     		}
    +		ret = ipfw_divert(m0, dir, &args.rule,
    +			(ipfw == IP_FW_TEE) ? 1 : 0);
    +		/* continue processing for the original packet (tee). */
    +		if (*m0)
    +			goto again;
    +		break;
     
     	case IP_FW_NGTEE:
    -		if (!NG_IPFW_LOADED)
    -			goto drop;
    -		(void)ng_ipfw_input_p(m0, NG_IPFW_OUT, &args, 1);
    -		goto again;		/* continue with packet */
    -
     	case IP_FW_NETGRAPH:
    -		if (!NG_IPFW_LOADED)
    -			goto drop;
    -		return ng_ipfw_input_p(m0, NG_IPFW_OUT, &args, 0);
    +		if (ng_ipfw_input_p == NULL) {
    +			ret = EACCES;
    +			break; /* i.e. drop */
    +		}
    +		ret = ng_ipfw_input_p(m0, dir, &args,
    +			(ipfw == IP_FW_NGTEE) ? 1 : 0);
    +		if (ipfw == IP_FW_NGTEE) /* ignore errors for NGTEE */
    +			goto again;	/* continue with packet */
    +		break;
     
     	case IP_FW_NAT:
    -		goto again;		/* continue with packet */
    -		
     	case IP_FW_REASS:
    -		goto again;	
    +		goto again;		/* continue with packet */
     	
     	default:
     		KASSERT(0, ("%s: unknown retval", __func__));
     	}
     
    -drop:
    -	if (*m0)
    -		m_freem(*m0);
    -	*m0 = NULL;
    -	return (EACCES);
    -pass:
    -	return 0;	/* not filtered */
    +	if (ret != 0) {
    +		if (*m0)
    +			FREE_PKT(*m0);
    +		*m0 = NULL;
    +	}
    +	if (*m0 && mtod(*m0, struct ip *)->ip_v == 4)
    +		SET_HOST_IPLEN(mtod(*m0, struct ip *));
    +	return ret;
     }
     
    +/* do the divert, return 1 on error 0 on success */
     static int
    -ipfw_divert(struct mbuf **m, int incoming, int tee)
    +ipfw_divert(struct mbuf **m0, int incoming, struct ipfw_rule_ref *rule,
    +	int tee)
     {
     	/*
     	 * ipfw_chk() has already tagged the packet with the divert tag.
     	 * If tee is set, copy packet and return original.
     	 * If not tee, consume packet and send it to divert socket.
     	 */
    -	struct mbuf *clone, *reass;
    +	struct mbuf *clone;
     	struct ip *ip;
    -	int hlen;
    -
    -	reass = NULL;
    -
    -	/* Is divert module loaded? */
    -	if (ip_divert_ptr == NULL)
    -		goto nodivert;
    +	struct m_tag *tag;
     
     	/* Cloning needed for tee? */
    -	if (tee)
    -		clone = m_dup(*m, M_DONTWAIT);
    -	else
    -		clone = *m;
    -
    -	/* In case m_dup was unable to allocate mbufs. */
    -	if (clone == NULL)
    -		goto teeout;
    +	if (tee == 0) {
    +		clone = *m0;	/* use the original mbuf */
    +		*m0 = NULL;
    +	} else {
    +		clone = m_dup(*m0, M_DONTWAIT);
    +		/* If we cannot duplicate the mbuf, we sacrifice the divert
    +		 * chain and continue with the tee-ed packet.
    +		 */
    +		if (clone == NULL)
    +			return 1;
    +	}
     
     	/*
    -	 * Divert listeners can only handle non-fragmented packets.
    -	 * However when tee is set we will *not* de-fragment the packets;
    -	 * Doing do would put the reassembly into double-jeopardy.  On top
    -	 * of that someone doing a tee will probably want to get the packet
    -	 * in its original form.
    +	 * Divert listeners can normally handle non-fragmented packets,
    +	 * but we can only reass in the non-tee case.
    +	 * This means that listeners on a tee rule may get fragments,
    +	 * and have to live with that.
    +	 * Note that we now have the 'reass' ipfw option so if we care
    +	 * we can do it before a 'tee'.
     	 */
     	ip = mtod(clone, struct ip *);
    -	if (!tee && ip->ip_off & (IP_MF | IP_OFFMASK)) {
    -
    -		/* Reassemble packet. */
    -		reass = ip_reass(clone);
    +	if (!tee && ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK)) {
    +		int hlen;
    +		struct mbuf *reass;
     
    +		SET_HOST_IPLEN(ip); /* ip_reass wants host order */
    +		reass = ip_reass(clone); /* Reassemble packet. */
    +		if (reass == NULL)
    +			return 0; /* not an error */
    +		/* if reass = NULL then it was consumed by ip_reass */
     		/*
     		 * IP header checksum fixup after reassembly and leave header
     		 * in network byte order.
     		 */
    -		if (reass != NULL) {
    -			ip = mtod(reass, struct ip *);
    -			hlen = ip->ip_hl << 2;
    -			ip->ip_len = htons(ip->ip_len);
    -			ip->ip_off = htons(ip->ip_off);
    -			ip->ip_sum = 0;
    -			if (hlen == sizeof(struct ip))
    -				ip->ip_sum = in_cksum_hdr(ip);
    -			else
    -				ip->ip_sum = in_cksum(reass, hlen);
    -			clone = reass;
    -		} else
    -			clone = NULL;
    -	} else {
    -		/* Convert header to network byte order. */
    -		ip->ip_len = htons(ip->ip_len);
    -		ip->ip_off = htons(ip->ip_off);
    +		ip = mtod(reass, struct ip *);
    +		hlen = ip->ip_hl << 2;
    +		SET_NET_IPLEN(ip);
    +		ip->ip_sum = 0;
    +		if (hlen == sizeof(struct ip))
    +			ip->ip_sum = in_cksum_hdr(ip);
    +		else
    +			ip->ip_sum = in_cksum(reass, hlen);
    +		clone = reass;
     	}
    +	/* attach a tag to the packet with the reinject info */
    +	tag = m_tag_alloc(MTAG_IPFW_RULE, 0,
    +		    sizeof(struct ipfw_rule_ref), M_NOWAIT);
    +	if (tag == NULL) {
    +		FREE_PKT(clone);
    +		return 1;
    +	}
    +	*((struct ipfw_rule_ref *)(tag+1)) = *rule;
    +	m_tag_prepend(clone, tag);
     
     	/* Do the dirty job... */
    -	if (clone && ip_divert_ptr != NULL)
    -		ip_divert_ptr(clone, incoming);
    -
    -teeout:
    -	/*
    -	 * For tee we leave the divert tag attached to original packet.
    -	 * It will then continue rule evaluation after the tee rule.
    -	 */
    -	if (tee)
    -		return 0;
    -
    -	/* Packet diverted and consumed */
    -	return 1;
    -
    -nodivert:
    -	m_freem(*m);
    -	return 1;
    +	ip_divert_ptr(clone, incoming);
    +	return 0;
     }
     
    -int
    -ipfw_hook(void)
    +/*
    + * attach or detach hooks for a given protocol family
    + */
    +static int
    +ipfw_hook(int onoff, int pf)
     {
    -	struct pfil_head *pfh_inet;
    +	struct pfil_head *pfh;
     
    -	pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
    -	if (pfh_inet == NULL)
    +	pfh = pfil_head_get(PFIL_TYPE_AF, pf);
    +	if (pfh == NULL)
     		return ENOENT;
     
    -	(void)pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK,
    -	    pfh_inet);
    -	(void)pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
    -	    pfh_inet);
    +	(void) (onoff ? pfil_add_hook : pfil_remove_hook)
    +	    (ipfw_check_hook, NULL, PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh);
     
     	return 0;
     }
     
     int
    -ipfw_unhook(void)
    +ipfw_attach_hooks(int arg)
     {
    -	struct pfil_head *pfh_inet;
    -
    -	pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
    -	if (pfh_inet == NULL)
    -		return ENOENT;
    -
    -	(void)pfil_remove_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK,
    -	    pfh_inet);
    -	(void)pfil_remove_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
    -	    pfh_inet);
    -
    -	return 0;
    -}
    +	int error = 0;
     
    +	if (arg == 0) /* detach */
    +		ipfw_hook(0, AF_INET);
    +        else if (V_fw_enable && ipfw_hook(1, AF_INET) != 0) {
    +                error = ENOENT; /* see ip_fw_pfil.c::ipfw_hook() */
    +                printf("ipfw_hook() error\n");
    +        }
     #ifdef INET6
    -int
    -ipfw6_hook(void)
    -{
    -	struct pfil_head *pfh_inet6;
    -
    -	pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
    -	if (pfh_inet6 == NULL)
    -		return ENOENT;
    -
    -	(void)pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK,
    -	    pfh_inet6);
    -	(void)pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
    -	    pfh_inet6);
    -
    -	return 0;
    +	if (arg == 0) /* detach */
    +		ipfw_hook(0, AF_INET6);
    +        else if (V_fw6_enable && ipfw_hook(1, AF_INET6) != 0) {
    +                error = ENOENT;
    +                printf("ipfw6_hook() error\n");
    +        }
    +#endif
    +	return error;
     }
     
    -int
    -ipfw6_unhook(void)
    -{
    -	struct pfil_head *pfh_inet6;
    -
    -	pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
    -	if (pfh_inet6 == NULL)
    -		return ENOENT;
    -
    -	(void)pfil_remove_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK,
    -	    pfh_inet6);
    -	(void)pfil_remove_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
    -	    pfh_inet6);
    -
    -	return 0;
    -}
    -#endif /* INET6 */
    -
     int
     ipfw_chg_hook(SYSCTL_HANDLER_ARGS)
     {
     	int enable;
     	int oldenable;
     	int error;
    +	int af;
     
     	if (arg1 == &VNET_NAME(fw_enable)) {
     		enable = V_fw_enable;
    +		af = AF_INET;
     	}
     #ifdef INET6
     	else if (arg1 == &VNET_NAME(fw6_enable)) {
     		enable = V_fw6_enable;
    +		af = AF_INET6;
     	}
     #endif
     	else 
    @@ -542,27 +395,16 @@ ipfw_chg_hook(SYSCTL_HANDLER_ARGS)
     	if (enable == oldenable)
     		return (0);
     
    -	if (arg1 == &VNET_NAME(fw_enable)) {
    -		if (enable)
    -			error = ipfw_hook();
    -		else
    -			error = ipfw_unhook();
    -		if (error)
    -			return (error);
    +	error = ipfw_hook(enable, af);
    +	if (error)
    +		return (error);
    +	if (af == AF_INET)
     		V_fw_enable = enable;
    -	}
     #ifdef INET6
    -	else if (arg1 == &VNET_NAME(fw6_enable)) {
    -		if (enable)
    -			error = ipfw6_hook();
    -		else
    -			error = ipfw6_unhook();
    -		if (error)
    -			return (error);
    +	else if (af == AF_INET6)
     		V_fw6_enable = enable;
    -	}
     #endif
     
     	return (0);
     }
    -
    +/* end of file */
    diff --git a/sys/netinet/ipfw/ip_fw_private.h b/sys/netinet/ipfw/ip_fw_private.h
    new file mode 100644
    index 00000000000..c29ae0ad90b
    --- /dev/null
    +++ b/sys/netinet/ipfw/ip_fw_private.h
    @@ -0,0 +1,301 @@
    +/*-
    + * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
    + *
    + * 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 _IPFW2_PRIVATE_H
    +#define _IPFW2_PRIVATE_H
    +
    +/*
    + * Internal constants and data structures used by ipfw components
    + * and not meant to be exported outside the kernel.
    + */
    +
    +#ifdef _KERNEL
    +
    +/*
    + * For platforms that do not have SYSCTL support, we wrap the
    + * SYSCTL_* into a function (one per file) to collect the values
    + * into an array at module initialization. The wrapping macros,
    + * SYSBEGIN() and SYSEND, are empty in the default case.
    + */
    +#ifndef SYSBEGIN
    +#define SYSBEGIN(x)
    +#endif
    +#ifndef SYSEND
    +#define SYSEND
    +#endif
    +
    +/* Return values from ipfw_chk() */
    +enum {
    +	IP_FW_PASS = 0,
    +	IP_FW_DENY,
    +	IP_FW_DIVERT,
    +	IP_FW_TEE,
    +	IP_FW_DUMMYNET,
    +	IP_FW_NETGRAPH,
    +	IP_FW_NGTEE,
    +	IP_FW_NAT,
    +	IP_FW_REASS,
    +};
    +
    +/*
    + * Structure for collecting parameters to dummynet for ip6_output forwarding
    + */
    +struct _ip6dn_args {
    +       struct ip6_pktopts *opt_or;
    +       struct route_in6 ro_or;
    +       int flags_or;
    +       struct ip6_moptions *im6o_or;
    +       struct ifnet *origifp_or;
    +       struct ifnet *ifp_or;
    +       struct sockaddr_in6 dst_or;
    +       u_long mtu_or;
    +       struct route_in6 ro_pmtu_or;
    +};
    +
    +
    +/*
    + * Arguments for calling ipfw_chk() and dummynet_io(). We put them
    + * all into a structure because this way it is easier and more
    + * efficient to pass variables around and extend the interface.
    + */
    +struct ip_fw_args {
    +	struct mbuf	*m;		/* the mbuf chain		*/
    +	struct ifnet	*oif;		/* output interface		*/
    +	struct sockaddr_in *next_hop;	/* forward address		*/
    +
    +	/*
    +	 * On return, it points to the matching rule.
    +	 * On entry, rule.slot > 0 means the info is valid and
    +	 * contains the the starting rule for an ipfw search.
    +	 * If chain_id == chain->id && slot >0 then jump to that slot.
    +	 * Otherwise, we locate the first rule >= rulenum:rule_id
    +	 */
    +	struct ipfw_rule_ref rule;	/* match/restart info		*/
    +
    +	struct ether_header *eh;	/* for bridged packets		*/
    +
    +	struct ipfw_flow_id f_id;	/* grabbed from IP header	*/
    +	//uint32_t	cookie;		/* a cookie depending on rule action */
    +	struct inpcb	*inp;
    +
    +	struct _ip6dn_args	dummypar; /* dummynet->ip6_output */
    +	struct sockaddr_in hopstore;	/* store here if cannot use a pointer */
    +};
    +
    +MALLOC_DECLARE(M_IPFW);
    +
    +/*
    + * Hooks sometime need to know the direction of the packet
    + * (divert, dummynet, netgraph, ...)
    + * We use a generic definition here, with bit0-1 indicating the
    + * direction, bit 2 indicating layer2 or 3, bit 3-4 indicating the
    + * specific protocol
    + * indicating the protocol (if necessary)
    + */
    +enum {
    +	DIR_MASK =	0x3,
    +	DIR_OUT =	0,
    +	DIR_IN =	1,
    +	DIR_FWD =	2,
    +	DIR_DROP =	3,
    +	PROTO_LAYER2 =	0x4, /* set for layer 2 */
    +	/* PROTO_DEFAULT = 0, */
    +	PROTO_IPV4 =	0x08,
    +	PROTO_IPV6 =	0x10,
    +	PROTO_IFB =	0x0c, /* layer2 + ifbridge */
    +   /*	PROTO_OLDBDG =	0x14, unused, old bridge */
    +};
    +
    +/* wrapper for freeing a packet, in case we need to do more work */
    +#ifndef FREE_PKT
    +#if defined(__linux__) || defined(_WIN32)
    +#define FREE_PKT(m)	netisr_dispatch(-1, m)
    +#else
    +#define FREE_PKT(m)	m_freem(m)
    +#endif
    +#endif /* !FREE_PKT */
    +
    +/*
    + * Function definitions.
    + */
    +
    +/* attach (arg = 1) or detach (arg = 0) hooks */
    +int ipfw_attach_hooks(int);
    +#ifdef NOTYET
    +void ipfw_nat_destroy(void);
    +#endif
    +
    +/* In ip_fw_log.c */
    +struct ip;
    +void ipfw_log_bpf(int);
    +void ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
    +	struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
    +	struct ip *ip);
    +VNET_DECLARE(u_int64_t, norule_counter);
    +#define	V_norule_counter	VNET(norule_counter)
    +VNET_DECLARE(int, verbose_limit);
    +#define	V_verbose_limit		VNET(verbose_limit)
    +
    +/* In ip_fw_dynamic.c */
    +
    +enum { /* result for matching dynamic rules */
    +	MATCH_REVERSE = 0,
    +	MATCH_FORWARD,
    +	MATCH_NONE,
    +	MATCH_UNKNOWN,
    +};
    +
    +/*
    + * The lock for dynamic rules is only used once outside the file,
    + * and only to release the result of lookup_dyn_rule().
    + * Eventually we may implement it with a callback on the function.
    + */
    +void ipfw_dyn_unlock(void);
    +
    +struct tcphdr;
    +struct mbuf *ipfw_send_pkt(struct mbuf *, struct ipfw_flow_id *,
    +    u_int32_t, u_int32_t, int);
    +int ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
    +    struct ip_fw_args *args, uint32_t tablearg);
    +ipfw_dyn_rule *ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt,
    +	int *match_direction, struct tcphdr *tcp);
    +void ipfw_remove_dyn_children(struct ip_fw *rule);
    +void ipfw_get_dynamic(char **bp, const char *ep);
    +
    +void ipfw_dyn_attach(void);	/* uma_zcreate .... */
    +void ipfw_dyn_detach(void);	/* uma_zdestroy ... */
    +void ipfw_dyn_init(void);	/* per-vnet initialization */
    +void ipfw_dyn_uninit(int);	/* per-vnet deinitialization */
    +int ipfw_dyn_len(void);
    +
    +/* common variables */
    +VNET_DECLARE(int, fw_one_pass);
    +#define	V_fw_one_pass		VNET(fw_one_pass)
    +
    +VNET_DECLARE(int, fw_verbose);
    +#define	V_fw_verbose		VNET(fw_verbose)
    +
    +VNET_DECLARE(struct ip_fw_chain, layer3_chain);
    +#define	V_layer3_chain		VNET(layer3_chain)
    +
    +VNET_DECLARE(u_int32_t, set_disable);
    +#define	V_set_disable		VNET(set_disable)
    +
    +VNET_DECLARE(int, autoinc_step);
    +#define V_autoinc_step		VNET(autoinc_step)
    +
    +struct ip_fw_chain {
    +	struct ip_fw	*rules;		/* list of rules */
    +	struct ip_fw	*reap;		/* list of rules to reap */
    +	struct ip_fw	*default_rule;
    +	int		n_rules;	/* number of static rules */
    +	int		static_len;	/* total len of static rules */
    +	struct ip_fw    **map;	/* array of rule ptrs to ease lookup */
    +	LIST_HEAD(nat_list, cfg_nat) nat;       /* list of nat entries */
    +	struct radix_node_head *tables[IPFW_TABLES_MAX];
    +#if defined( __linux__ ) || defined( _WIN32 )
    +	spinlock_t rwmtx;
    +	spinlock_t uh_lock;
    +#else
    +	struct rwlock	rwmtx;
    +	struct rwlock	uh_lock;	/* lock for upper half */
    +#endif
    +	uint32_t	id;		/* ruleset id */
    +};
    +
    +struct sockopt;	/* used by tcp_var.h */
    +
    +/*
    + * The lock is heavily used by ip_fw2.c (the main file) and ip_fw_nat.c
    + * so the variable and the macros must be here.
    + */
    +
    +#define	IPFW_LOCK_INIT(_chain) do {			\
    +	rw_init(&(_chain)->rwmtx, "IPFW static rules");	\
    +	rw_init(&(_chain)->uh_lock, "IPFW UH lock");	\
    +	} while (0)
    +
    +#define	IPFW_LOCK_DESTROY(_chain) do {			\
    +	rw_destroy(&(_chain)->rwmtx);			\
    +	rw_destroy(&(_chain)->uh_lock);			\
    +	} while (0)
    +
    +#define	IPFW_WLOCK_ASSERT(_chain)	rw_assert(&(_chain)->rwmtx, RA_WLOCKED)
    +
    +#define IPFW_RLOCK(p) rw_rlock(&(p)->rwmtx)
    +#define IPFW_RUNLOCK(p) rw_runlock(&(p)->rwmtx)
    +#define IPFW_WLOCK(p) rw_wlock(&(p)->rwmtx)
    +#define IPFW_WUNLOCK(p) rw_wunlock(&(p)->rwmtx)
    +
    +#define IPFW_UH_RLOCK(p) rw_rlock(&(p)->uh_lock)
    +#define IPFW_UH_RUNLOCK(p) rw_runlock(&(p)->uh_lock)
    +#define IPFW_UH_WLOCK(p) rw_wlock(&(p)->uh_lock)
    +#define IPFW_UH_WUNLOCK(p) rw_wunlock(&(p)->uh_lock)
    +
    +/* In ip_fw_sockopt.c */
    +int ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id);
    +int ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule);
    +int ipfw_ctl(struct sockopt *sopt);
    +int ipfw_chk(struct ip_fw_args *args);
    +void ipfw_reap_rules(struct ip_fw *head);
    +
    +/* In ip_fw_pfil */
    +int ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
    +     struct inpcb *inp);
    +
    +/* In ip_fw_table.c */
    +struct radix_node;
    +int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
    +    uint32_t *val);
    +int ipfw_init_tables(struct ip_fw_chain *ch);
    +void ipfw_destroy_tables(struct ip_fw_chain *ch);
    +int ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl);
    +int ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
    +    uint8_t mlen, uint32_t value);
    +int ipfw_dump_table_entry(struct radix_node *rn, void *arg);
    +int ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
    +    uint8_t mlen);
    +int ipfw_count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
    +int ipfw_dump_table(struct ip_fw_chain *ch, ipfw_table *tbl);
    +
    +/* In ip_fw_nat.c -- XXX to be moved to ip_var.h */
    +
    +extern struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
    +
    +typedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *);
    +typedef int ipfw_nat_cfg_t(struct sockopt *);
    +
    +extern ipfw_nat_t *ipfw_nat_ptr;
    +#define IPFW_NAT_LOADED (ipfw_nat_ptr != NULL)
    +
    +extern ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
    +extern ipfw_nat_cfg_t *ipfw_nat_del_ptr;
    +extern ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
    +extern ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
    +
    +#endif /* _KERNEL */
    +#endif /* _IPFW2_PRIVATE_H */
    diff --git a/sys/netinet/ipfw/ip_fw_sockopt.c b/sys/netinet/ipfw/ip_fw_sockopt.c
    new file mode 100644
    index 00000000000..e25b960e640
    --- /dev/null
    +++ b/sys/netinet/ipfw/ip_fw_sockopt.c
    @@ -0,0 +1,1287 @@
    +/*-
    + * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
    + *
    + * Supported by: Valeria Paoli
    + *
    + * 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$");
    +
    +/*
    + * Sockopt support for ipfw. The routines here implement
    + * the upper half of the ipfw code.
    + */
    +
    +#if !defined(KLD_MODULE)
    +#include "opt_ipfw.h"
    +#include "opt_ipdivert.h"
    +#include "opt_ipdn.h"
    +#include "opt_inet.h"
    +#ifndef INET
    +#error IPFIREWALL requires INET.
    +#endif /* INET */
    +#endif
    +#include "opt_inet6.h"
    +#include "opt_ipsec.h"
    +
    +#include 
    +#include 
    +#include 
    +#include 	/* struct m_tag used by nested headers */
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include  /* hooks */
    +#include 
    +#include 
    +
    +#ifdef MAC
    +#include 
    +#endif
    +
    +MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
    +
    +/*
    + * static variables followed by global ones (none in this file)
    + */
    +
    +/*
    + * Find the smallest rule >= key, id.
    + * We could use bsearch but it is so simple that we code it directly
    + */
    +int
    +ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id)
    +{
    +	int i, lo, hi;
    +	struct ip_fw *r;
    +
    +  	for (lo = 0, hi = chain->n_rules - 1; lo < hi;) {
    +		i = (lo + hi) / 2;
    +		r = chain->map[i];
    +		if (r->rulenum < key)
    +			lo = i + 1;	/* continue from the next one */
    +		else if (r->rulenum > key)
    +			hi = i;		/* this might be good */
    +		else if (r->id < id)
    +			lo = i + 1;	/* continue from the next one */
    +		else /* r->id >= id */
    +			hi = i;		/* this might be good */
    +	};
    +	return hi;
    +}
    +
    +/*
    + * allocate a new map, returns the chain locked. extra is the number
    + * of entries to add or delete.
    + */
    +static struct ip_fw **
    +get_map(struct ip_fw_chain *chain, int extra, int locked)
    +{
    +
    +	for (;;) {
    +		struct ip_fw **map;
    +		int i;
    +
    +		i = chain->n_rules + extra;
    +		map = malloc(i * sizeof(struct ip_fw *), M_IPFW,
    +			locked ? M_NOWAIT : M_WAITOK);
    +		if (map == NULL) {
    +			printf("%s: cannot allocate map\n", __FUNCTION__);
    +			return NULL;
    +		}
    +		if (!locked)
    +			IPFW_UH_WLOCK(chain);
    +		if (i >= chain->n_rules + extra) /* good */
    +			return map;
    +		/* otherwise we lost the race, free and retry */
    +		if (!locked)
    +			IPFW_UH_WUNLOCK(chain);
    +		free(map, M_IPFW);
    +	}
    +}
    +
    +/*
    + * swap the maps. It is supposed to be called with IPFW_UH_WLOCK
    + */
    +static struct ip_fw **
    +swap_map(struct ip_fw_chain *chain, struct ip_fw **new_map, int new_len)
    +{
    +	struct ip_fw **old_map;
    +
    +	IPFW_WLOCK(chain);
    +	chain->id++;
    +	chain->n_rules = new_len;
    +	old_map = chain->map;
    +	chain->map = new_map;
    +	IPFW_WUNLOCK(chain);
    +	return old_map;
    +}
    +
    +/*
    + * Add a new rule to the list. Copy the rule into a malloc'ed area, then
    + * possibly create a rule number and add the rule to the list.
    + * Update the rule_number in the input struct so the caller knows it as well.
    + * XXX DO NOT USE FOR THE DEFAULT RULE.
    + * Must be called without IPFW_UH held
    + */
    +int
    +ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule)
    +{
    +	struct ip_fw *rule;
    +	int i, l, insert_before;
    +	struct ip_fw **map;	/* the new array of pointers */
    +
    +	if (chain->rules == NULL || input_rule->rulenum > IPFW_DEFAULT_RULE-1)
    +		return (EINVAL);
    +
    +	l = RULESIZE(input_rule);
    +	rule = malloc(l, M_IPFW, M_WAITOK | M_ZERO);
    +	if (rule == NULL)
    +		return (ENOSPC);
    +	/* get_map returns with IPFW_UH_WLOCK if successful */
    +	map = get_map(chain, 1, 0 /* not locked */);
    +	if (map == NULL) {
    +		free(rule, M_IPFW);
    +		return ENOSPC;
    +	}
    +
    +	bcopy(input_rule, rule, l);
    +	/* clear fields not settable from userland */
    +	rule->x_next = NULL;
    +	rule->next_rule = NULL;
    +	rule->pcnt = 0;
    +	rule->bcnt = 0;
    +	rule->timestamp = 0;
    +
    +	if (V_autoinc_step < 1)
    +		V_autoinc_step = 1;
    +	else if (V_autoinc_step > 1000)
    +		V_autoinc_step = 1000;
    +	/* find the insertion point, we will insert before */
    +	insert_before = rule->rulenum ? rule->rulenum + 1 : IPFW_DEFAULT_RULE;
    +	i = ipfw_find_rule(chain, insert_before, 0);
    +	/* duplicate first part */
    +	if (i > 0)
    +		bcopy(chain->map, map, i * sizeof(struct ip_fw *));
    +	map[i] = rule;
    +	/* duplicate remaining part, we always have the default rule */
    +	bcopy(chain->map + i, map + i + 1,
    +		sizeof(struct ip_fw *) *(chain->n_rules - i));
    +	if (rule->rulenum == 0) {
    +		/* write back the number */
    +		rule->rulenum = i > 0 ? map[i-1]->rulenum : 0;
    +		if (rule->rulenum < IPFW_DEFAULT_RULE - V_autoinc_step)
    +			rule->rulenum += V_autoinc_step;
    +		input_rule->rulenum = rule->rulenum;
    +	}
    +
    +	rule->id = chain->id + 1;
    +	map = swap_map(chain, map, chain->n_rules + 1);
    +	chain->static_len += l;
    +	IPFW_UH_WUNLOCK(chain);
    +	if (map)
    +		free(map, M_IPFW);
    +	return (0);
    +}
    +
    +/*
    + * Reclaim storage associated with a list of rules.  This is
    + * typically the list created using remove_rule.
    + * A NULL pointer on input is handled correctly.
    + */
    +void
    +ipfw_reap_rules(struct ip_fw *head)
    +{
    +	struct ip_fw *rule;
    +
    +	while ((rule = head) != NULL) {
    +		head = head->x_next;
    +		free(rule, M_IPFW);
    +	}
    +}
    +
    +/**
    + * Remove all rules with given number, and also do set manipulation.
    + * Assumes chain != NULL && *chain != NULL.
    + *
    + * The argument is an u_int32_t. The low 16 bit are the rule or set number,
    + * the next 8 bits are the new set, the top 8 bits are the command:
    + *
    + *	0	delete rules with given number
    + *	1	delete rules with given set number
    + *	2	move rules with given number to new set
    + *	3	move rules with given set number to new set
    + *	4	swap sets with given numbers
    + *	5	delete rules with given number and with given set number
    + */
    +static int
    +del_entry(struct ip_fw_chain *chain, u_int32_t arg)
    +{
    +	struct ip_fw *rule;
    +	uint32_t rulenum;	/* rule or old_set */
    +	uint8_t cmd, new_set;
    +	int start, end = 0, i, ofs, n;
    +	struct ip_fw **map = NULL;
    +	int error = 0;
    +
    +	rulenum = arg & 0xffff;
    +	cmd = (arg >> 24) & 0xff;
    +	new_set = (arg >> 16) & 0xff;
    +
    +	if (cmd > 5 || new_set > RESVD_SET)
    +		return EINVAL;
    +	if (cmd == 0 || cmd == 2 || cmd == 5) {
    +		if (rulenum >= IPFW_DEFAULT_RULE)
    +			return EINVAL;
    +	} else {
    +		if (rulenum > RESVD_SET)	/* old_set */
    +			return EINVAL;
    +	}
    +
    +	IPFW_UH_WLOCK(chain); /* prevent conflicts among the writers */
    +	chain->reap = NULL;	/* prepare for deletions */
    +
    +	switch (cmd) {
    +	case 0:	/* delete rules with given number (0 is special means all) */
    +	case 1:	/* delete all rules with given set number, rule->set == rulenum */
    +	case 5: /* delete rules with given number and with given set number.
    +		 * rulenum - given rule number;
    +		 * new_set - given set number.
    +		 */
    +		/* locate first rule to delete (start), the one after the
    +		 * last one (end), and count how many rules to delete (n)
    +		 */
    +		n = 0;
    +		if (cmd == 1) { /* look for a specific set, must scan all */
    +			for (start = -1, i = 0; i < chain->n_rules; i++) {
    +				if (chain->map[start]->set != rulenum)
    +					continue;
    +				if (start < 0)
    +					start = i;
    +				end = i;
    +				n++;
    +			}
    +			end++;	/* first non-matching */
    +		} else {
    +			start = ipfw_find_rule(chain, rulenum, 0);
    +			for (end = start; end < chain->n_rules; end++) {
    +				rule = chain->map[end];
    +				if (rulenum > 0 && rule->rulenum != rulenum)
    +					break;
    +				if (rule->set != RESVD_SET &&
    +				    (cmd == 0 || rule->set == new_set) )
    +					n++;
    +			}
    +		}
    +		if (n == 0 && arg == 0)
    +			break; /* special case, flush on empty ruleset */
    +		/* allocate the map, if needed */
    +		if (n > 0)
    +			map = get_map(chain, -n, 1 /* locked */);
    +		if (n == 0 || map == NULL) {
    +			error = EINVAL;
    +			break;
    +		}
    +		/* copy the initial part of the map */
    +		if (start > 0)
    +			bcopy(chain->map, map, start * sizeof(struct ip_fw *));
    +		/* copy active rules between start and end */
    +		for (i = ofs = start; i < end; i++) {
    +			rule = chain->map[i];
    +			if (!(rule->set != RESVD_SET &&
    +			    (cmd == 0 || rule->set == new_set) ))
    +				map[ofs++] = chain->map[i];
    +		}
    +		/* finally the tail */
    +		bcopy(chain->map + end, map + ofs,
    +			(chain->n_rules - end) * sizeof(struct ip_fw *));
    +		map = swap_map(chain, map, chain->n_rules - n);
    +		/* now remove the rules deleted */
    +		for (i = start; i < end; i++) {
    +			rule = map[i];
    +			if (rule->set != RESVD_SET &&
    +			    (cmd == 0 || rule->set == new_set) ) {
    +				int l = RULESIZE(rule);
    +
    +				chain->static_len -= l;
    +				ipfw_remove_dyn_children(rule);
    +				rule->x_next = chain->reap;
    +				chain->reap = rule;
    +			}
    +		}
    +		break;
    +
    +	case 2:	/* move rules with given number to new set */
    +		for (i = 0; i < chain->n_rules; i++) {
    +			rule = chain->map[i];
    +			if (rule->rulenum == rulenum)
    +				rule->set = new_set;
    +		}
    +		break;
    +
    +	case 3: /* move rules with given set number to new set */
    +		for (i = 0; i < chain->n_rules; i++) {
    +			rule = chain->map[i];
    +			if (rule->set == rulenum)
    +				rule->set = new_set;
    +		}
    +		break;
    +
    +	case 4: /* swap two sets */
    +		for (i = 0; i < chain->n_rules; i++) {
    +			rule = chain->map[i];
    +			if (rule->set == rulenum)
    +				rule->set = new_set;
    +			else if (rule->set == new_set)
    +				rule->set = rulenum;
    +		}
    +		break;
    +	}
    +	rule = chain->reap;
    +	chain->reap = NULL;
    +	IPFW_UH_WUNLOCK(chain);
    +	ipfw_reap_rules(rule);
    +	if (map)
    +		free(map, M_IPFW);
    +	return error;
    +}
    +
    +/*
    + * Clear counters for a specific rule.
    + * Normally run under IPFW_UH_RLOCK, but these are idempotent ops
    + * so we only care that rules do not disappear.
    + */
    +static void
    +clear_counters(struct ip_fw *rule, int log_only)
    +{
    +	ipfw_insn_log *l = (ipfw_insn_log *)ACTION_PTR(rule);
    +
    +	if (log_only == 0) {
    +		rule->bcnt = rule->pcnt = 0;
    +		rule->timestamp = 0;
    +	}
    +	if (l->o.opcode == O_LOG)
    +		l->log_left = l->max_log;
    +}
    +
    +/**
    + * Reset some or all counters on firewall rules.
    + * The argument `arg' is an u_int32_t. The low 16 bit are the rule number,
    + * the next 8 bits are the set number, the top 8 bits are the command:
    + *	0	work with rules from all set's;
    + *	1	work with rules only from specified set.
    + * Specified rule number is zero if we want to clear all entries.
    + * log_only is 1 if we only want to reset logs, zero otherwise.
    + */
    +static int
    +zero_entry(struct ip_fw_chain *chain, u_int32_t arg, int log_only)
    +{
    +	struct ip_fw *rule;
    +	char *msg;
    +	int i;
    +
    +	uint16_t rulenum = arg & 0xffff;
    +	uint8_t set = (arg >> 16) & 0xff;
    +	uint8_t cmd = (arg >> 24) & 0xff;
    +
    +	if (cmd > 1)
    +		return (EINVAL);
    +	if (cmd == 1 && set > RESVD_SET)
    +		return (EINVAL);
    +
    +	IPFW_UH_RLOCK(chain);
    +	if (rulenum == 0) {
    +		V_norule_counter = 0;
    +		for (i = 0; i < chain->n_rules; i++) {
    +			rule = chain->map[i];
    +			/* Skip rules not in our set. */
    +			if (cmd == 1 && rule->set != set)
    +				continue;
    +			clear_counters(rule, log_only);
    +		}
    +		msg = log_only ? "All logging counts reset" :
    +		    "Accounting cleared";
    +	} else {
    +		int cleared = 0;
    +		for (i = 0; i < chain->n_rules; i++) {
    +			rule = chain->map[i];
    +			if (rule->rulenum == rulenum) {
    +				if (cmd == 0 || rule->set == set)
    +					clear_counters(rule, log_only);
    +				cleared = 1;
    +			}
    +			if (rule->rulenum > rulenum)
    +				break;
    +		}
    +		if (!cleared) {	/* we did not find any matching rules */
    +			IPFW_WUNLOCK(chain);
    +			return (EINVAL);
    +		}
    +		msg = log_only ? "logging count reset" : "cleared";
    +	}
    +	IPFW_UH_RUNLOCK(chain);
    +
    +	if (V_fw_verbose) {
    +		int lev = LOG_SECURITY | LOG_NOTICE;
    +
    +		if (rulenum)
    +			log(lev, "ipfw: Entry %d %s.\n", rulenum, msg);
    +		else
    +			log(lev, "ipfw: %s.\n", msg);
    +	}
    +	return (0);
    +}
    +
    +/*
    + * Check validity of the structure before insert.
    + * Rules are simple, so this mostly need to check rule sizes.
    + */
    +static int
    +check_ipfw_struct(struct ip_fw *rule, int size)
    +{
    +	int l, cmdlen = 0;
    +	int have_action=0;
    +	ipfw_insn *cmd;
    +
    +	if (size < sizeof(*rule)) {
    +		printf("ipfw: rule too short\n");
    +		return (EINVAL);
    +	}
    +	/* first, check for valid size */
    +	l = RULESIZE(rule);
    +	if (l != size) {
    +		printf("ipfw: size mismatch (have %d want %d)\n", size, l);
    +		return (EINVAL);
    +	}
    +	if (rule->act_ofs >= rule->cmd_len) {
    +		printf("ipfw: bogus action offset (%u > %u)\n",
    +		    rule->act_ofs, rule->cmd_len - 1);
    +		return (EINVAL);
    +	}
    +	/*
    +	 * Now go for the individual checks. Very simple ones, basically only
    +	 * instruction sizes.
    +	 */
    +	for (l = rule->cmd_len, cmd = rule->cmd ;
    +			l > 0 ; l -= cmdlen, cmd += cmdlen) {
    +		cmdlen = F_LEN(cmd);
    +		if (cmdlen > l) {
    +			printf("ipfw: opcode %d size truncated\n",
    +			    cmd->opcode);
    +			return EINVAL;
    +		}
    +		switch (cmd->opcode) {
    +		case O_PROBE_STATE:
    +		case O_KEEP_STATE:
    +		case O_PROTO:
    +		case O_IP_SRC_ME:
    +		case O_IP_DST_ME:
    +		case O_LAYER2:
    +		case O_IN:
    +		case O_FRAG:
    +		case O_DIVERTED:
    +		case O_IPOPT:
    +		case O_IPTOS:
    +		case O_IPPRECEDENCE:
    +		case O_IPVER:
    +		case O_TCPWIN:
    +		case O_TCPFLAGS:
    +		case O_TCPOPTS:
    +		case O_ESTAB:
    +		case O_VERREVPATH:
    +		case O_VERSRCREACH:
    +		case O_ANTISPOOF:
    +		case O_IPSEC:
    +#ifdef INET6
    +		case O_IP6_SRC_ME:
    +		case O_IP6_DST_ME:
    +		case O_EXT_HDR:
    +		case O_IP6:
    +#endif
    +		case O_IP4:
    +		case O_TAG:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    +				goto bad_size;
    +			break;
    +
    +		case O_FIB:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    +				goto bad_size;
    +			if (cmd->arg1 >= rt_numfibs) {
    +				printf("ipfw: invalid fib number %d\n",
    +					cmd->arg1);
    +				return EINVAL;
    +			}
    +			break;
    +
    +		case O_SETFIB:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    +				goto bad_size;
    +			if (cmd->arg1 >= rt_numfibs) {
    +				printf("ipfw: invalid fib number %d\n",
    +					cmd->arg1);
    +				return EINVAL;
    +			}
    +			goto check_action;
    +
    +		case O_UID:
    +		case O_GID:
    +		case O_JAIL:
    +		case O_IP_SRC:
    +		case O_IP_DST:
    +		case O_TCPSEQ:
    +		case O_TCPACK:
    +		case O_PROB:
    +		case O_ICMPTYPE:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_u32))
    +				goto bad_size;
    +			break;
    +
    +		case O_LIMIT:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_limit))
    +				goto bad_size;
    +			break;
    +
    +		case O_LOG:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_log))
    +				goto bad_size;
    +
    +			((ipfw_insn_log *)cmd)->log_left =
    +			    ((ipfw_insn_log *)cmd)->max_log;
    +
    +			break;
    +
    +		case O_IP_SRC_MASK:
    +		case O_IP_DST_MASK:
    +			/* only odd command lengths */
    +			if ( !(cmdlen & 1) || cmdlen > 31)
    +				goto bad_size;
    +			break;
    +
    +		case O_IP_SRC_SET:
    +		case O_IP_DST_SET:
    +			if (cmd->arg1 == 0 || cmd->arg1 > 256) {
    +				printf("ipfw: invalid set size %d\n",
    +					cmd->arg1);
    +				return EINVAL;
    +			}
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
    +			    (cmd->arg1+31)/32 )
    +				goto bad_size;
    +			break;
    +
    +		case O_IP_SRC_LOOKUP:
    +		case O_IP_DST_LOOKUP:
    +			if (cmd->arg1 >= IPFW_TABLES_MAX) {
    +				printf("ipfw: invalid table number %d\n",
    +				    cmd->arg1);
    +				return (EINVAL);
    +			}
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn) &&
    +			    cmdlen != F_INSN_SIZE(ipfw_insn_u32) + 1 &&
    +			    cmdlen != F_INSN_SIZE(ipfw_insn_u32))
    +				goto bad_size;
    +			break;
    +
    +		case O_MACADDR2:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_mac))
    +				goto bad_size;
    +			break;
    +
    +		case O_NOP:
    +		case O_IPID:
    +		case O_IPTTL:
    +		case O_IPLEN:
    +		case O_TCPDATALEN:
    +		case O_TAGGED:
    +			if (cmdlen < 1 || cmdlen > 31)
    +				goto bad_size;
    +			break;
    +
    +		case O_MAC_TYPE:
    +		case O_IP_SRCPORT:
    +		case O_IP_DSTPORT: /* XXX artificial limit, 30 port pairs */
    +			if (cmdlen < 2 || cmdlen > 31)
    +				goto bad_size;
    +			break;
    +
    +		case O_RECV:
    +		case O_XMIT:
    +		case O_VIA:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_if))
    +				goto bad_size;
    +			break;
    +
    +		case O_ALTQ:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_altq))
    +				goto bad_size;
    +			break;
    +
    +		case O_PIPE:
    +		case O_QUEUE:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    +				goto bad_size;
    +			goto check_action;
    +
    +		case O_FORWARD_IP:
    +#ifdef	IPFIREWALL_FORWARD
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_sa))
    +				goto bad_size;
    +			goto check_action;
    +#else
    +			return EINVAL;
    +#endif
    +
    +		case O_DIVERT:
    +		case O_TEE:
    +			if (ip_divert_ptr == NULL)
    +				return EINVAL;
    +			else
    +				goto check_size;
    +		case O_NETGRAPH:
    +		case O_NGTEE:
    +			if (ng_ipfw_input_p == NULL)
    +				return EINVAL;
    +			else
    +				goto check_size;
    +		case O_NAT:
    +			if (!IPFW_NAT_LOADED)
    +				return EINVAL;
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_nat))
    + 				goto bad_size;		
    + 			goto check_action;
    +		case O_FORWARD_MAC: /* XXX not implemented yet */
    +		case O_CHECK_STATE:
    +		case O_COUNT:
    +		case O_ACCEPT:
    +		case O_DENY:
    +		case O_REJECT:
    +#ifdef INET6
    +		case O_UNREACH6:
    +#endif
    +		case O_SKIPTO:
    +		case O_REASS:
    +check_size:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn))
    +				goto bad_size;
    +check_action:
    +			if (have_action) {
    +				printf("ipfw: opcode %d, multiple actions"
    +					" not allowed\n",
    +					cmd->opcode);
    +				return EINVAL;
    +			}
    +			have_action = 1;
    +			if (l != cmdlen) {
    +				printf("ipfw: opcode %d, action must be"
    +					" last opcode\n",
    +					cmd->opcode);
    +				return EINVAL;
    +			}
    +			break;
    +#ifdef INET6
    +		case O_IP6_SRC:
    +		case O_IP6_DST:
    +			if (cmdlen != F_INSN_SIZE(struct in6_addr) +
    +			    F_INSN_SIZE(ipfw_insn))
    +				goto bad_size;
    +			break;
    +
    +		case O_FLOW6ID:
    +			if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
    +			    ((ipfw_insn_u32 *)cmd)->o.arg1)
    +				goto bad_size;
    +			break;
    +
    +		case O_IP6_SRC_MASK:
    +		case O_IP6_DST_MASK:
    +			if ( !(cmdlen & 1) || cmdlen > 127)
    +				goto bad_size;
    +			break;
    +		case O_ICMP6TYPE:
    +			if( cmdlen != F_INSN_SIZE( ipfw_insn_icmp6 ) )
    +				goto bad_size;
    +			break;
    +#endif
    +
    +		default:
    +			switch (cmd->opcode) {
    +#ifndef INET6
    +			case O_IP6_SRC_ME:
    +			case O_IP6_DST_ME:
    +			case O_EXT_HDR:
    +			case O_IP6:
    +			case O_UNREACH6:
    +			case O_IP6_SRC:
    +			case O_IP6_DST:
    +			case O_FLOW6ID:
    +			case O_IP6_SRC_MASK:
    +			case O_IP6_DST_MASK:
    +			case O_ICMP6TYPE:
    +				printf("ipfw: no IPv6 support in kernel\n");
    +				return EPROTONOSUPPORT;
    +#endif
    +			default:
    +				printf("ipfw: opcode %d, unknown opcode\n",
    +					cmd->opcode);
    +				return EINVAL;
    +			}
    +		}
    +	}
    +	if (have_action == 0) {
    +		printf("ipfw: missing action\n");
    +		return EINVAL;
    +	}
    +	return 0;
    +
    +bad_size:
    +	printf("ipfw: opcode %d size %d wrong\n",
    +		cmd->opcode, cmdlen);
    +	return EINVAL;
    +}
    +
    +
    +/*
    + * Translation of requests for compatibility with FreeBSD 7.2/8.
    + * a static variable tells us if we have an old client from userland,
    + * and if necessary we translate requests and responses between the
    + * two formats.
    + */
    +static int is7 = 0;
    +
    +struct ip_fw7 {
    +	struct ip_fw7	*next;		/* linked list of rules     */
    +	struct ip_fw7	*next_rule;	/* ptr to next [skipto] rule    */
    +	/* 'next_rule' is used to pass up 'set_disable' status      */
    +
    +	uint16_t	act_ofs;	/* offset of action in 32-bit units */
    +	uint16_t	cmd_len;	/* # of 32-bit words in cmd */
    +	uint16_t	rulenum;	/* rule number          */
    +	uint8_t		set;		/* rule set (0..31)     */
    +	// #define RESVD_SET   31  /* set for default and persistent rules */
    +	uint8_t		_pad;		/* padding          */
    +	// uint32_t        id;             /* rule id, only in v.8 */
    +	/* These fields are present in all rules.           */
    +	uint64_t	pcnt;		/* Packet counter       */
    +	uint64_t	bcnt;		/* Byte counter         */
    +	uint32_t	timestamp;	/* tv_sec of last match     */
    +
    +	ipfw_insn	cmd[1];		/* storage for commands     */
    +};
    +
    +	int convert_rule_to_7(struct ip_fw *rule);
    +int convert_rule_to_8(struct ip_fw *rule);
    +
    +#ifndef RULESIZE7
    +#define RULESIZE7(rule)  (sizeof(struct ip_fw7) + \
    +	((struct ip_fw7 *)(rule))->cmd_len * 4 - 4)
    +#endif
    +
    +
    +/*
    + * Copy the static and dynamic rules to the supplied buffer
    + * and return the amount of space actually used.
    + * Must be run under IPFW_UH_RLOCK
    + */
    +static size_t
    +ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
    +{
    +	char *bp = buf;
    +	char *ep = bp + space;
    +	struct ip_fw *rule, *dst;
    +	int l, i;
    +	time_t	boot_seconds;
    +
    +        boot_seconds = boottime.tv_sec;
    +	for (i = 0; i < chain->n_rules; i++) {
    +		rule = chain->map[i];
    +
    +		if (is7) {
    +		    /* Convert rule to FreeBSd 7.2 format */
    +		    l = RULESIZE7(rule);
    +		    if (bp + l + sizeof(uint32_t) <= ep) {
    +			int error;
    +			bcopy(rule, bp, l + sizeof(uint32_t));
    +			error = convert_rule_to_7((struct ip_fw *) bp);
    +			if (error)
    +				return 0; /*XXX correct? */
    +			/*
    +			 * XXX HACK. Store the disable mask in the "next"
    +			 * pointer in a wild attempt to keep the ABI the same.
    +			 * Why do we do this on EVERY rule?
    +			 */
    +			bcopy(&V_set_disable,
    +				&(((struct ip_fw7 *)bp)->next_rule),
    +				sizeof(V_set_disable));
    +			if (((struct ip_fw7 *)bp)->timestamp)
    +			    ((struct ip_fw7 *)bp)->timestamp += boot_seconds;
    +			bp += l;
    +		    }
    +		    continue; /* go to next rule */
    +		}
    +
    +		/* normal mode, don't touch rules */
    +		l = RULESIZE(rule);
    +		if (bp + l > ep) { /* should not happen */
    +			printf("overflow dumping static rules\n");
    +			break;
    +		}
    +		dst = (struct ip_fw *)bp;
    +		bcopy(rule, dst, l);
    +		/*
    +		 * XXX HACK. Store the disable mask in the "next"
    +		 * pointer in a wild attempt to keep the ABI the same.
    +		 * Why do we do this on EVERY rule?
    +		 */
    +		bcopy(&V_set_disable, &dst->next_rule, sizeof(V_set_disable));
    +		if (dst->timestamp)
    +			dst->timestamp += boot_seconds;
    +		bp += l;
    +	}
    +	ipfw_get_dynamic(&bp, ep); /* protected by the dynamic lock */
    +	return (bp - (char *)buf);
    +}
    +
    +
    +/**
    + * {set|get}sockopt parser.
    + */
    +int
    +ipfw_ctl(struct sockopt *sopt)
    +{
    +#define	RULE_MAXSIZE	(256*sizeof(u_int32_t))
    +	int error;
    +	size_t size;
    +	struct ip_fw *buf, *rule;
    +	struct ip_fw_chain *chain;
    +	u_int32_t rulenum[2];
    +
    +	error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW);
    +	if (error)
    +		return (error);
    +
    +	/*
    +	 * Disallow modifications in really-really secure mode, but still allow
    +	 * the logging counters to be reset.
    +	 */
    +	if (sopt->sopt_name == IP_FW_ADD ||
    +	    (sopt->sopt_dir == SOPT_SET && sopt->sopt_name != IP_FW_RESETLOG)) {
    +		error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
    +		if (error)
    +			return (error);
    +	}
    +
    +	chain = &V_layer3_chain;
    +	error = 0;
    +
    +	switch (sopt->sopt_name) {
    +	case IP_FW_GET:
    +		/*
    +		 * pass up a copy of the current rules. Static rules
    +		 * come first (the last of which has number IPFW_DEFAULT_RULE),
    +		 * followed by a possibly empty list of dynamic rule.
    +		 * The last dynamic rule has NULL in the "next" field.
    +		 *
    +		 * Note that the calculated size is used to bound the
    +		 * amount of data returned to the user.  The rule set may
    +		 * change between calculating the size and returning the
    +		 * data in which case we'll just return what fits.
    +		 */
    +		for (;;) {
    +			int len = 0, want;
    +
    +			size = chain->static_len;
    +			size += ipfw_dyn_len();
    +			if (size >= sopt->sopt_valsize)
    +				break;
    +			buf = malloc(size, M_TEMP, M_WAITOK);
    +			if (buf == NULL)
    +				break;
    +			IPFW_UH_RLOCK(chain);
    +			/* check again how much space we need */
    +			want = chain->static_len + ipfw_dyn_len();
    +			if (size >= want)
    +				len = ipfw_getrules(chain, buf, size);
    +			IPFW_UH_RUNLOCK(chain);
    +			if (size >= want)
    +				error = sooptcopyout(sopt, buf, len);
    +			free(buf, M_TEMP);
    +			if (size >= want)
    +				break;
    +		}
    +		break;
    +
    +	case IP_FW_FLUSH:
    +		/* locking is done within del_entry() */
    +		error = del_entry(chain, 0); /* special case, rule=0, cmd=0 means all */
    +		break;
    +
    +	case IP_FW_ADD:
    +		rule = malloc(RULE_MAXSIZE, M_TEMP, M_WAITOK);
    +		error = sooptcopyin(sopt, rule, RULE_MAXSIZE,
    +			sizeof(struct ip_fw7) );
    +
    +		/*
    +		 * If the size of commands equals RULESIZE7 then we assume
    +		 * a FreeBSD7.2 binary is talking to us (set is7=1).
    +		 * is7 is persistent so the next 'ipfw list' command
    +		 * will use this format.
    +		 * NOTE: If wrong version is guessed (this can happen if
    +		 *       the first ipfw command is 'ipfw [pipe] list')
    +		 *       the ipfw binary may crash or loop infinitly...
    +		 */
    +		if (sopt->sopt_valsize == RULESIZE7(rule)) {
    +		    is7 = 1;
    +		    error = convert_rule_to_8(rule);
    +		    if (error)
    +			return error;
    +		    if (error == 0)
    +			error = check_ipfw_struct(rule, RULESIZE(rule));
    +		} else {
    +		    is7 = 0;
    +		if (error == 0)
    +			error = check_ipfw_struct(rule, sopt->sopt_valsize);
    +		}
    +		if (error == 0) {
    +			/* locking is done within ipfw_add_rule() */
    +			error = ipfw_add_rule(chain, rule);
    +			size = RULESIZE(rule);
    +			if (!error && sopt->sopt_dir == SOPT_GET) {
    +				if (is7) {
    +					error = convert_rule_to_7(rule);
    +					size = RULESIZE7(rule);
    +					if (error)
    +						return error;
    +				}
    +				error = sooptcopyout(sopt, rule, size);
    +		}
    +		}
    +		free(rule, M_TEMP);
    +		break;
    +
    +	case IP_FW_DEL:
    +		/*
    +		 * IP_FW_DEL is used for deleting single rules or sets,
    +		 * and (ab)used to atomically manipulate sets. Argument size
    +		 * is used to distinguish between the two:
    +		 *    sizeof(u_int32_t)
    +		 *	delete single rule or set of rules,
    +		 *	or reassign rules (or sets) to a different set.
    +		 *    2*sizeof(u_int32_t)
    +		 *	atomic disable/enable sets.
    +		 *	first u_int32_t contains sets to be disabled,
    +		 *	second u_int32_t contains sets to be enabled.
    +		 */
    +		error = sooptcopyin(sopt, rulenum,
    +			2*sizeof(u_int32_t), sizeof(u_int32_t));
    +		if (error)
    +			break;
    +		size = sopt->sopt_valsize;
    +		if (size == sizeof(u_int32_t) && rulenum[0] != 0) {
    +			/* delete or reassign, locking done in del_entry() */
    +			error = del_entry(chain, rulenum[0]);
    +		} else if (size == 2*sizeof(u_int32_t)) { /* set enable/disable */
    +			IPFW_UH_WLOCK(chain);
    +			V_set_disable =
    +			    (V_set_disable | rulenum[0]) & ~rulenum[1] &
    +			    ~(1<sopt_val != 0) {
    +		    error = sooptcopyin(sopt, rulenum,
    +			    sizeof(u_int32_t), sizeof(u_int32_t));
    +		    if (error)
    +			break;
    +		}
    +		error = zero_entry(chain, rulenum[0],
    +			sopt->sopt_name == IP_FW_RESETLOG);
    +		break;
    +
    +	/*--- TABLE manipulations are protected by the IPFW_LOCK ---*/
    +	case IP_FW_TABLE_ADD:
    +		{
    +			ipfw_table_entry ent;
    +
    +			error = sooptcopyin(sopt, &ent,
    +			    sizeof(ent), sizeof(ent));
    +			if (error)
    +				break;
    +			error = ipfw_add_table_entry(chain, ent.tbl,
    +			    ent.addr, ent.masklen, ent.value);
    +		}
    +		break;
    +
    +	case IP_FW_TABLE_DEL:
    +		{
    +			ipfw_table_entry ent;
    +
    +			error = sooptcopyin(sopt, &ent,
    +			    sizeof(ent), sizeof(ent));
    +			if (error)
    +				break;
    +			error = ipfw_del_table_entry(chain, ent.tbl,
    +			    ent.addr, ent.masklen);
    +		}
    +		break;
    +
    +	case IP_FW_TABLE_FLUSH:
    +		{
    +			u_int16_t tbl;
    +
    +			error = sooptcopyin(sopt, &tbl,
    +			    sizeof(tbl), sizeof(tbl));
    +			if (error)
    +				break;
    +			IPFW_WLOCK(chain);
    +			error = ipfw_flush_table(chain, tbl);
    +			IPFW_WUNLOCK(chain);
    +		}
    +		break;
    +
    +	case IP_FW_TABLE_GETSIZE:
    +		{
    +			u_int32_t tbl, cnt;
    +
    +			if ((error = sooptcopyin(sopt, &tbl, sizeof(tbl),
    +			    sizeof(tbl))))
    +				break;
    +			IPFW_RLOCK(chain);
    +			error = ipfw_count_table(chain, tbl, &cnt);
    +			IPFW_RUNLOCK(chain);
    +			if (error)
    +				break;
    +			error = sooptcopyout(sopt, &cnt, sizeof(cnt));
    +		}
    +		break;
    +
    +	case IP_FW_TABLE_LIST:
    +		{
    +			ipfw_table *tbl;
    +
    +			if (sopt->sopt_valsize < sizeof(*tbl)) {
    +				error = EINVAL;
    +				break;
    +			}
    +			size = sopt->sopt_valsize;
    +			tbl = malloc(size, M_TEMP, M_WAITOK);
    +			error = sooptcopyin(sopt, tbl, size, sizeof(*tbl));
    +			if (error) {
    +				free(tbl, M_TEMP);
    +				break;
    +			}
    +			tbl->size = (size - sizeof(*tbl)) /
    +			    sizeof(ipfw_table_entry);
    +			IPFW_RLOCK(chain);
    +			error = ipfw_dump_table(chain, tbl);
    +			IPFW_RUNLOCK(chain);
    +			if (error) {
    +				free(tbl, M_TEMP);
    +				break;
    +			}
    +			error = sooptcopyout(sopt, tbl, size);
    +			free(tbl, M_TEMP);
    +		}
    +		break;
    +
    +	/*--- NAT operations are protected by the IPFW_LOCK ---*/
    +	case IP_FW_NAT_CFG:
    +		if (IPFW_NAT_LOADED)
    +			error = ipfw_nat_cfg_ptr(sopt);
    +		else {
    +			printf("IP_FW_NAT_CFG: %s\n",
    +			    "ipfw_nat not present, please load it");
    +			error = EINVAL;
    +		}
    +		break;
    +
    +	case IP_FW_NAT_DEL:
    +		if (IPFW_NAT_LOADED)
    +			error = ipfw_nat_del_ptr(sopt);
    +		else {
    +			printf("IP_FW_NAT_DEL: %s\n",
    +			    "ipfw_nat not present, please load it");
    +			error = EINVAL;
    +		}
    +		break;
    +
    +	case IP_FW_NAT_GET_CONFIG:
    +		if (IPFW_NAT_LOADED)
    +			error = ipfw_nat_get_cfg_ptr(sopt);
    +		else {
    +			printf("IP_FW_NAT_GET_CFG: %s\n",
    +			    "ipfw_nat not present, please load it");
    +			error = EINVAL;
    +		}
    +		break;
    +
    +	case IP_FW_NAT_GET_LOG:
    +		if (IPFW_NAT_LOADED)
    +			error = ipfw_nat_get_log_ptr(sopt);
    +		else {
    +			printf("IP_FW_NAT_GET_LOG: %s\n",
    +			    "ipfw_nat not present, please load it");
    +			error = EINVAL;
    +		}
    +		break;
    +
    +	default:
    +		printf("ipfw: ipfw_ctl invalid option %d\n", sopt->sopt_name);
    +		error = EINVAL;
    +	}
    +
    +	return (error);
    +#undef RULE_MAXSIZE
    +}
    +
    +
    +#define	RULE_MAXSIZE	(256*sizeof(u_int32_t))
    +
    +/* Functions to convert rules 7.2 <==> 8.0 */
    +int
    +convert_rule_to_7(struct ip_fw *rule)
    +{
    +	/* Used to modify original rule */
    +	struct ip_fw7 *rule7 = (struct ip_fw7 *)rule;
    +	/* copy of original rule, version 8 */
    +	struct ip_fw *tmp;
    +
    +	/* Used to copy commands */
    +	ipfw_insn *ccmd, *dst;
    +	int ll = 0, ccmdlen = 0;
    +
    +	tmp = malloc(RULE_MAXSIZE, M_TEMP, M_NOWAIT | M_ZERO);
    +	if (tmp == NULL) {
    +		return 1; //XXX error
    +	}
    +	bcopy(rule, tmp, RULE_MAXSIZE);
    +
    +	/* Copy fields */
    +	rule7->_pad = tmp->_pad;
    +	rule7->set = tmp->set;
    +	rule7->rulenum = tmp->rulenum;
    +	rule7->cmd_len = tmp->cmd_len;
    +	rule7->act_ofs = tmp->act_ofs;
    +	rule7->next_rule = (struct ip_fw7 *)tmp->next_rule;
    +	rule7->next = (struct ip_fw7 *)tmp->x_next;
    +	rule7->cmd_len = tmp->cmd_len;
    +	rule7->pcnt = tmp->pcnt;
    +	rule7->bcnt = tmp->bcnt;
    +	rule7->timestamp = tmp->timestamp;
    +
    +	/* Copy commands */
    +	for (ll = tmp->cmd_len, ccmd = tmp->cmd, dst = rule7->cmd ;
    +			ll > 0 ; ll -= ccmdlen, ccmd += ccmdlen, dst += ccmdlen) {
    +		ccmdlen = F_LEN(ccmd);
    +
    +		bcopy(ccmd, dst, F_LEN(ccmd)*sizeof(uint32_t));
    +
    +		if (dst->opcode > O_NAT)
    +			/* O_REASS doesn't exists in 7.2 version, so
    +			 * decrement opcode if it is after O_REASS
    +			 */
    +			dst->opcode--;
    +
    +		if (ccmdlen > ll) {
    +			printf("ipfw: opcode %d size truncated\n",
    +				ccmd->opcode);
    +			return EINVAL;
    +		}
    +	}
    +	free(tmp, M_TEMP);
    +
    +	return 0;
    +}
    +
    +int
    +convert_rule_to_8(struct ip_fw *rule)
    +{
    +	/* Used to modify original rule */
    +	struct ip_fw7 *rule7 = (struct ip_fw7 *) rule;
    +
    +	/* Used to copy commands */
    +	ipfw_insn *ccmd, *dst;
    +	int ll = 0, ccmdlen = 0;
    +
    +	/* Copy of original rule */
    +	struct ip_fw7 *tmp = malloc(RULE_MAXSIZE, M_TEMP, M_NOWAIT | M_ZERO);
    +	if (tmp == NULL) {
    +		return 1; //XXX error
    +	}
    +
    +	bcopy(rule7, tmp, RULE_MAXSIZE);
    +
    +	for (ll = tmp->cmd_len, ccmd = tmp->cmd, dst = rule->cmd ;
    +			ll > 0 ; ll -= ccmdlen, ccmd += ccmdlen, dst += ccmdlen) {
    +		ccmdlen = F_LEN(ccmd);
    +		
    +		bcopy(ccmd, dst, F_LEN(ccmd)*sizeof(uint32_t));
    +
    +		if (dst->opcode > O_NAT)
    +			/* O_REASS doesn't exists in 7.2 version, so
    +			 * increment opcode if it is after O_REASS
    +			 */
    +			dst->opcode++;
    +
    +		if (ccmdlen > ll) {
    +			printf("ipfw: opcode %d size truncated\n",
    +			    ccmd->opcode);
    +			return EINVAL;
    +		}
    +	}
    +
    +	rule->_pad = tmp->_pad;
    +	rule->set = tmp->set;
    +	rule->rulenum = tmp->rulenum;
    +	rule->cmd_len = tmp->cmd_len;
    +	rule->act_ofs = tmp->act_ofs;
    +	rule->next_rule = (struct ip_fw *)tmp->next_rule;
    +	rule->x_next = (struct ip_fw *)tmp->next;
    +	rule->cmd_len = tmp->cmd_len;
    +	rule->id = 0; /* XXX see if is ok = 0 */
    +	rule->pcnt = tmp->pcnt;
    +	rule->bcnt = tmp->bcnt;
    +	rule->timestamp = tmp->timestamp;
    +
    +	free (tmp, M_TEMP);
    +	return 0;
    +}
    +
    +/* end of file */
    diff --git a/sys/netinet/ipfw/ip_fw_table.c b/sys/netinet/ipfw/ip_fw_table.c
    new file mode 100644
    index 00000000000..517622f0217
    --- /dev/null
    +++ b/sys/netinet/ipfw/ip_fw_table.c
    @@ -0,0 +1,286 @@
    +/*-
    + * Copyright (c) 2004 Ruslan Ermilov and Vsevolod Lobko.
    + *
    + * 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$");
    +
    +/*
    + * Lookup table support for ipfw
    + *
    + * Lookup tables are implemented (at the moment) using the radix
    + * tree used for routing tables. Tables store key-value entries, where
    + * keys are network prefixes (addr/masklen), and values are integers.
    + * As a degenerate case we can interpret keys as 32-bit integers
    + * (with a /32 mask).
    + *
    + * The table is protected by the IPFW lock even for manipulation coming
    + * from userland, because operations are typically fast.
    + */
    +
    +#if !defined(KLD_MODULE)
    +#include "opt_ipfw.h"
    +#include "opt_ipdivert.h"
    +#include "opt_ipdn.h"
    +#include "opt_inet.h"
    +#ifndef INET
    +#error IPFIREWALL requires INET.
    +#endif /* INET */
    +#endif
    +#include "opt_inet6.h"
    +#include "opt_ipsec.h"
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 	/* ip_fw.h requires IFNAMSIZ */
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 	/* struct ipfw_rule_ref */
    +#include 
    +#include  /* LIST_HEAD */
    +#include 
    +
    +#ifdef MAC
    +#include 
    +#endif
    +
    +MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables");
    +
    +struct table_entry {
    +	struct radix_node	rn[2];
    +	struct sockaddr_in	addr, mask;
    +	u_int32_t		value;
    +};
    +
    +/*
    + * The radix code expects addr and mask to be array of bytes,
    + * with the first byte being the length of the array. rn_inithead
    + * is called with the offset in bits of the lookup key within the
    + * array. If we use a sockaddr_in as the underlying type,
    + * sin_len is conveniently located at offset 0, sin_addr is at
    + * offset 4 and normally aligned.
    + * But for portability, let's avoid assumption and make the code explicit
    + */
    +#define KEY_LEN(v)	*((uint8_t *)&(v))
    +#define KEY_OFS		(8*offsetof(struct sockaddr_in, sin_addr))
    +
    +int
    +ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
    +    uint8_t mlen, uint32_t value)
    +{
    +	struct radix_node_head *rnh;
    +	struct table_entry *ent;
    +	struct radix_node *rn;
    +
    +	if (tbl >= IPFW_TABLES_MAX)
    +		return (EINVAL);
    +	rnh = ch->tables[tbl];
    +	ent = malloc(sizeof(*ent), M_IPFW_TBL, M_NOWAIT | M_ZERO);
    +	if (ent == NULL)
    +		return (ENOMEM);
    +	ent->value = value;
    +	KEY_LEN(ent->addr) = KEY_LEN(ent->mask) = 8;
    +	ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
    +	ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr;
    +	IPFW_WLOCK(ch);
    +	rn = rnh->rnh_addaddr(&ent->addr, &ent->mask, rnh, (void *)ent);
    +	if (rn == NULL) {
    +		IPFW_WUNLOCK(ch);
    +		free(ent, M_IPFW_TBL);
    +		return (EEXIST);
    +	}
    +	IPFW_WUNLOCK(ch);
    +	return (0);
    +}
    +
    +int
    +ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
    +    uint8_t mlen)
    +{
    +	struct radix_node_head *rnh;
    +	struct table_entry *ent;
    +	struct sockaddr_in sa, mask;
    +
    +	if (tbl >= IPFW_TABLES_MAX)
    +		return (EINVAL);
    +	rnh = ch->tables[tbl];
    +	KEY_LEN(sa) = KEY_LEN(mask) = 8;
    +	mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
    +	sa.sin_addr.s_addr = addr & mask.sin_addr.s_addr;
    +	IPFW_WLOCK(ch);
    +	ent = (struct table_entry *)rnh->rnh_deladdr(&sa, &mask, rnh);
    +	if (ent == NULL) {
    +		IPFW_WUNLOCK(ch);
    +		return (ESRCH);
    +	}
    +	IPFW_WUNLOCK(ch);
    +	free(ent, M_IPFW_TBL);
    +	return (0);
    +}
    +
    +static int
    +flush_table_entry(struct radix_node *rn, void *arg)
    +{
    +	struct radix_node_head * const rnh = arg;
    +	struct table_entry *ent;
    +
    +	ent = (struct table_entry *)
    +	    rnh->rnh_deladdr(rn->rn_key, rn->rn_mask, rnh);
    +	if (ent != NULL)
    +		free(ent, M_IPFW_TBL);
    +	return (0);
    +}
    +
    +int
    +ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl)
    +{
    +	struct radix_node_head *rnh;
    +
    +	IPFW_WLOCK_ASSERT(ch);
    +
    +	if (tbl >= IPFW_TABLES_MAX)
    +		return (EINVAL);
    +	rnh = ch->tables[tbl];
    +	KASSERT(rnh != NULL, ("NULL IPFW table"));
    +	rnh->rnh_walktree(rnh, flush_table_entry, rnh);
    +	return (0);
    +}
    +
    +void
    +ipfw_destroy_tables(struct ip_fw_chain *ch)
    +{
    +	uint16_t tbl;
    +	struct radix_node_head *rnh;
    +
    +	IPFW_WLOCK_ASSERT(ch);
    +
    +	for (tbl = 0; tbl < IPFW_TABLES_MAX; tbl++) {
    +		ipfw_flush_table(ch, tbl);
    +		rnh = ch->tables[tbl];
    +		rn_detachhead((void **)&rnh);
    +	}
    +}
    +
    +int
    +ipfw_init_tables(struct ip_fw_chain *ch)
    +{ 
    +	int i;
    +	uint16_t j;
    +
    +	for (i = 0; i < IPFW_TABLES_MAX; i++) {
    +		if (!rn_inithead((void **)&ch->tables[i], KEY_OFS)) {
    +			for (j = 0; j < i; j++) {
    +				(void) ipfw_flush_table(ch, j);
    +			}
    +			return (ENOMEM);
    +		}
    +	}
    +	return (0);
    +}
    +
    +int
    +ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
    +    uint32_t *val)
    +{
    +	struct radix_node_head *rnh;
    +	struct table_entry *ent;
    +	struct sockaddr_in sa;
    +
    +	if (tbl >= IPFW_TABLES_MAX)
    +		return (0);
    +	rnh = ch->tables[tbl];
    +	KEY_LEN(sa) = 8;
    +	sa.sin_addr.s_addr = addr;
    +	ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh));
    +	if (ent != NULL) {
    +		*val = ent->value;
    +		return (1);
    +	}
    +	return (0);
    +}
    +
    +static int
    +count_table_entry(struct radix_node *rn, void *arg)
    +{
    +	u_int32_t * const cnt = arg;
    +
    +	(*cnt)++;
    +	return (0);
    +}
    +
    +int
    +ipfw_count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt)
    +{
    +	struct radix_node_head *rnh;
    +
    +	if (tbl >= IPFW_TABLES_MAX)
    +		return (EINVAL);
    +	rnh = ch->tables[tbl];
    +	*cnt = 0;
    +	rnh->rnh_walktree(rnh, count_table_entry, cnt);
    +	return (0);
    +}
    +
    +static int
    +dump_table_entry(struct radix_node *rn, void *arg)
    +{
    +	struct table_entry * const n = (struct table_entry *)rn;
    +	ipfw_table * const tbl = arg;
    +	ipfw_table_entry *ent;
    +
    +	if (tbl->cnt == tbl->size)
    +		return (1);
    +	ent = &tbl->ent[tbl->cnt];
    +	ent->tbl = tbl->tbl;
    +	if (in_nullhost(n->mask.sin_addr))
    +		ent->masklen = 0;
    +	else
    +		ent->masklen = 33 - ffs(ntohl(n->mask.sin_addr.s_addr));
    +	ent->addr = n->addr.sin_addr.s_addr;
    +	ent->value = n->value;
    +	tbl->cnt++;
    +	return (0);
    +}
    +
    +int
    +ipfw_dump_table(struct ip_fw_chain *ch, ipfw_table *tbl)
    +{
    +	struct radix_node_head *rnh;
    +
    +	if (tbl->tbl >= IPFW_TABLES_MAX)
    +		return (EINVAL);
    +	rnh = ch->tables[tbl->tbl];
    +	tbl->cnt = 0;
    +	rnh->rnh_walktree(rnh, dump_table_entry, tbl);
    +	return (0);
    +}
    +/* end of file */
    diff --git a/sys/netinet/ipfw/test/Makefile b/sys/netinet/ipfw/test/Makefile
    new file mode 100644
    index 00000000000..bbeb94278ac
    --- /dev/null
    +++ b/sys/netinet/ipfw/test/Makefile
    @@ -0,0 +1,50 @@
    +#
    +# $FreeBSD$
    +#
    +# Makefile for building userland tests
    +# this is written in a form compatible with gmake
    +
    +SCHED_SRCS = test_dn_sched.c
    +SCHED_SRCS += dn_sched_fifo.c
    +SCHED_SRCS += dn_sched_wf2q.c
    +SCHED_SRCS += dn_sched_qfq.c
    +SCHED_SRCS += dn_sched_rr.c
    +SCHED_SRCS += dn_heap.c
    +SCHED_SRCS += main.c
    +
    +SCHED_OBJS=$(SCHED_SRCS:.c=.o)
    +
    +HEAP_SRCS = dn_heap.c test_dn_heap.c
    +HEAP_OBJS=$(HEAP_SRCS:.c=.o)
    +
    +VPATH=	.:..
    +
    +CFLAGS = -I.. -I. -Wall -Werror -O3 -DIPFW
    +TARGETS= test_sched # no test_heap by default
    +
    +all:	$(TARGETS)
    +
    +test_heap : $(HEAP_OBJS)
    +	$(CC) -o $@ $(HEAP_OBJS)
    +
    +test_sched : $(SCHED_OBJS)
    +	$(CC) -o $@ $(SCHED_OBJS)
    +
    +$(SCHED_OBJS): dn_test.h
    +main.o: mylist.h
    +
    +clean:
    +	- rm *.o $(TARGETS) *.core
    +
    +ALLSRCS = $(SCHED_SRCS) dn_test.h mylist.h \
    +	dn_sched.h dn_heap.h ip_dn_private.h Makefile
    +TMPBASE = /tmp/testXYZ
    +TMPDIR = $(TMPBASE)/test
    +
    +tgz:
    +	-rm -rf $(TMPDIR)
    +	mkdir -p $(TMPDIR)
    +	-cp -p $(ALLSRCS) $(TMPDIR)
    +	-(cd ..; cp -p $(ALLSRCS) $(TMPDIR))
    +	ls -la  $(TMPDIR)
    +	(cd $(TMPBASE); tar cvzf /tmp/test.tgz test)
    diff --git a/sys/netinet/ipfw/test/dn_test.h b/sys/netinet/ipfw/test/dn_test.h
    new file mode 100644
    index 00000000000..4e079bc4d68
    --- /dev/null
    +++ b/sys/netinet/ipfw/test/dn_test.h
    @@ -0,0 +1,175 @@
    +/*
    + * $FreeBSD$
    + *
    + * userspace compatibility code for dummynet schedulers
    + */
    +
    +#ifndef _DN_TEST_H
    +#define _DN_TEST_H
    +
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +
    +#include 
    +#include 
    +#include 
    +#include 	/* bzero, ffs, ... */
    +#include 	/* strcmp */
    +#include 
    +#include 
    +#include 
    +
    +extern int debug;
    +#define ND(fmt, args...) do {} while (0)
    +#define D1(fmt, args...) do {} while (0)
    +#define D(fmt, args...) fprintf(stderr, "%-8s " fmt "\n",      \
    +        __FUNCTION__, ## args)
    +#define DX(lev, fmt, args...) do {              \
    +        if (debug > lev) D(fmt, ## args); } while (0)
    +
    +
    +#ifndef offsetof
    +#define offsetof(t,m) (int)((&((t *)0L)->m))
    +#endif
    +
    +#include 
    +
    +/* prevent include of other system headers */
    +#define	_NETINET_IP_VAR_H_	/* ip_fw_args */
    +#define _IPFW2_H
    +#define _SYS_MBUF_H_
    +
    +enum	{
    +	DN_QUEUE,
    +};
    +
    +enum	{
    +	DN_SCHED_FIFO,
    +	DN_SCHED_WF2QP,
    +};
    +
    +struct dn_id {
    +	int type, subtype, len, id;
    +};
    +
    +struct dn_fs {
    +	int par[4];	/* flowset parameters */
    +
    +	/* simulation entries.
    +	 * 'index' is not strictly necessary
    +	 * y is used for the inverse mapping ,
    +	 */
    +	int index;
    +	int y;	/* inverse mapping */
    +	int base_y;	/* inverse mapping */
    +	int next_y;	/* inverse mapping */
    +	int n_flows;
    +	int first_flow;
    +	int next_flow;	/* first_flow + n_flows */
    +	/*
    +	 * when generating, let 'cur' go from 0 to n_flows-1,
    +	 * then point to flow first_flow + cur
    +	 */
    +	int	cur;
    +};
    +
    +struct dn_sch {
    +};
    +
    +struct dn_flow {
    +	struct dn_id oid;
    +	int length;
    +	int len_bytes;
    +	int drops;
    +	uint64_t tot_bytes;
    +	uint32_t flow_id;
    +	struct list_head h;	/* used by the generator */
    +};
    +
    +struct dn_link {
    +};
    +
    +struct ip_fw_args {
    +};
    +
    +struct mbuf {
    +        struct {
    +                int len;
    +        } m_pkthdr;
    +        struct mbuf *m_nextpkt;
    +	int flow_id;	/* for testing, index of a flow */
    +	//int flowset_id;	/* for testing, index of a flowset */
    +	void *cfg;	/* config args */
    +};
    +
    +#define MALLOC_DECLARE(x)
    +#define KASSERT(x, y)	do { if (!(x)) printf y ; exit(0); } while (0)
    +struct ipfw_flow_id {
    +};
    +
    +typedef void * module_t;
    +
    +struct _md_t {
    +	const char *name;
    +	int (*f)(module_t, int, void *);
    +	void *p;
    +};
    +
    +typedef struct _md_t moduledata_t;
    +
    +#define DECLARE_MODULE(name, b, c, d)	\
    +	moduledata_t *_g_##name = & b
    +#define MODULE_DEPEND(a, b, c, d, e)
    +
    +#ifdef IPFW
    +#include 
    +#include 
    +#include 
    +#else
    +struct dn_queue {
    +        struct dn_fsk *fs;             /* parent flowset. */
    +        struct dn_sch_inst *_si;	/* parent sched instance. */
    +};
    +struct dn_schk {
    +};
    +struct dn_fsk {
    +	struct dn_fs fs;
    +	struct dn_schk *sched;
    +};
    +struct dn_sch_inst {
    +	struct dn_schk *sched;
    +};
    +struct dn_alg {
    +	int type;
    +	const char *name;
    +	void *enqueue, *dequeue;
    +	int q_datalen, si_datalen, schk_datalen;
    +	int (*config)(struct dn_schk *);
    +	int (*new_sched)(struct dn_sch_inst *);
    +	int (*new_fsk)(struct dn_fsk *);
    +        int (*new_queue)(struct dn_queue *q);
    +};
    +
    +#endif
    +
    +#ifndef __FreeBSD__
    +int fls(int);
    +#endif
    +
    +static inline void
    +mq_append(struct mq *q, struct mbuf *m)
    +{
    +        if (q->head == NULL)
    +                q->head = m;
    +        else
    +                q->tail->m_nextpkt = m;
    +        q->tail = m;
    +        m->m_nextpkt = NULL;
    +}
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +#endif /* _DN_TEST_H */
    diff --git a/sys/netinet/ipfw/test/main.c b/sys/netinet/ipfw/test/main.c
    new file mode 100644
    index 00000000000..be9fdf53612
    --- /dev/null
    +++ b/sys/netinet/ipfw/test/main.c
    @@ -0,0 +1,636 @@
    +/*
    + * $FreeBSD$
    + *
    + * Testing program for schedulers
    + *
    + * The framework include a simple controller which, at each
    + * iteration, decides whether we can enqueue and/or dequeue.
    + * Then the mainloop runs the required number of tests,
    + * keeping track of statistics.
    + */
    +
    +#include "dn_test.h"
    +
    +struct q_list {
    +	struct list_head h;
    +};
    +
    +struct cfg_s {
    +	int ac;
    +	char * const *av;
    +
    +	const char *name;
    +	int loops;
    +	struct timeval time;
    +
    +	/* running counters */
    +	uint32_t	_enqueue;
    +	uint32_t	drop;
    +	uint32_t	pending;
    +	uint32_t	dequeue;
    +
    +	/* generator parameters */
    +	int th_min, th_max;
    +	int maxburst;
    +	int lmin, lmax;	/* packet len */
    +	int flows;	/* number of flows */
    +	int flowsets;	/* number of flowsets */
    +	int wsum;	/* sum of weights of all flows */
    +	int max_y;	/* max random number in the generation */
    +	int cur_y, cur_fs;	/* used in generation, between 0 and max_y - 1 */
    +	const char *fs_config; /* flowset config */
    +	int can_dequeue;
    +	int burst;	/* count of packets sent in a burst */
    +	struct mbuf *tosend;	/* packet to send -- also flag to enqueue */
    +
    +	struct mbuf *freelist;
    +
    +	struct mbuf *head, *tail;	/* a simple tailq */
    +
    +	/* scheduler hooks */
    +	int (*enq)(struct dn_sch_inst *, struct dn_queue *,
    +		struct mbuf *);
    +	struct mbuf * (*deq)(struct dn_sch_inst *);
    +	/* size of the three fields including sched-specific areas */
    +	int schk_len;
    +	int q_len; /* size of a queue including sched-fields */
    +	int si_len; /* size of a sch_inst including sched-fields */
    +	char *q;	/* array of flow queues */
    +		/* use a char* because size is variable */
    +	struct dn_fsk *fs;	/* array of flowsets */
    +	struct dn_sch_inst *si;
    +	struct dn_schk *sched;
    +
    +	/* generator state */
    +	int state;		/* 0 = going up, 1: going down */
    +
    +	/*
    +	 * We keep lists for each backlog level, and always serve
    +	 * the one with shortest backlog. llmask contains a bitmap
    +	 * of lists, and ll are the heads of the lists. The last
    +	 * entry (BACKLOG) contains all entries considered 'full'
    +	 * XXX to optimize things, entry i could contain queues with
    +	 * 2^{i-1}+1 .. 2^i entries.
    +	 */
    +#define BACKLOG	30
    +	uint32_t	llmask;
    +	struct list_head ll[BACKLOG + 10];
    +};
    +
    +/* FI2Q and Q2FI converts from flow_id to dn_queue and back.
    + * We cannot easily use pointer arithmetic because it is variable size.
    +  */
    +#define FI2Q(c, i)	((struct dn_queue *)((c)->q + (c)->q_len * (i)))
    +#define Q2FI(c, q)	(((char *)(q) - (c)->q)/(c)->q_len)
    +
    +int debug = 0;
    +
    +struct dn_parms dn_cfg;
    +
    +static void controller(struct cfg_s *c);
    +
    +/* release a packet: put the mbuf in the freelist, and the queue in
    + * the bucket.
    + */
    +int
    +drop(struct cfg_s *c, struct mbuf *m)
    +{
    +	struct dn_queue *q;
    +	int i;
    +
    +	c->drop++;
    +	q = FI2Q(c, m->flow_id);
    +	i = q->ni.length; // XXX or ffs...
    +
    +	ND("q %p id %d current length %d", q, m->flow_id, i);
    +	if (i < BACKLOG) {
    +		struct list_head *h = &q->ni.h;
    +		c->llmask &= ~(1<<(i+1));
    +		c->llmask |= (1<<(i));
    +		list_del(h);
    +		list_add_tail(h, &c->ll[i]);
    +	}
    +	m->m_nextpkt = c->freelist;
    +	c->freelist = m;
    +	return 0;
    +}
    +
    +/* dequeue returns NON-NULL when a packet is dropped */
    +static int
    +enqueue(struct cfg_s *c, void *_m)
    +{
    +	struct mbuf *m = _m;
    +	if (c->enq)
    +		return c->enq(c->si, FI2Q(c, m->flow_id), m);
    +	if (c->head == NULL)
    +		c->head = m;
    +	else
    +		c->tail->m_nextpkt = m;
    +	c->tail = m;
    +	return 0; /* default - success */
    +}
    +
    +/* dequeue returns NON-NULL when a packet is available */
    +static void *
    +dequeue(struct cfg_s *c)
    +{
    +	struct mbuf *m;
    +	if (c->deq)
    +		return c->deq(c->si);
    +	if ((m = c->head)) {
    +		m = c->head;
    +		c->head = m->m_nextpkt;
    +		m->m_nextpkt = NULL;
    +	}
    +	return m;
    +}
    +
    +static int
    +mainloop(struct cfg_s *c)
    +{
    +	int i;
    +	struct mbuf *m;
    +
    +	for (i=0; i < c->loops; i++) {
    +		/* implement histeresis */
    +		controller(c);
    +		DX(3, "loop %d enq %d send %p rx %d",
    +			i, c->_enqueue, c->tosend, c->can_dequeue);
    +		if ( (m = c->tosend) ) {
    +			c->_enqueue++;
    +			if (enqueue(c, m)) {
    +				drop(c, m);
    +				ND("loop %d enqueue fail", i );
    +			} else {
    +				ND("enqueue ok");
    +				c->pending++;
    +			}
    +		}
    +		if (c->can_dequeue) {
    +			c->dequeue++;
    +			if ((m = dequeue(c))) {
    +				c->pending--;
    +				drop(c, m);
    +				c->drop--;	/* compensate */
    +			}
    +		}
    +	}
    +	DX(1, "mainloop ends %d", i);
    +	return 0;
    +}
    +
    +int
    +dump(struct cfg_s *c)
    +{
    +	int i;
    +	struct dn_queue *q;
    +
    +	for (i=0; i < c->flows; i++) {
    +		q = FI2Q(c, i);
    +		DX(1, "queue %4d tot %10lld", i, q->ni.tot_bytes);
    +	}
    +	DX(1, "done %d loops\n", c->loops);
    +	return 0;
    +}
    +
    +/* interpret a number in human form */
    +static long
    +getnum(const char *s, char **next, const char *key)
    +{
    +	char *end = NULL;
    +	long l;
    +
    +	if (next)	/* default */
    +		*next = NULL;
    +	if (s && *s) {
    +		DX(3, "token is <%s> %s", s, key ? key : "-");
    +		l = strtol(s, &end, 0);
    +	} else {
    +		DX(3, "empty string");
    +		l = -1;
    +	}
    +	if (l < 0) {
    +		DX(2, "invalid %s for %s", s ? s : "NULL", (key ? key : "") );
    +		return 0;	// invalid 
    +	}
    +	if (!end || !*end)
    +		return l;
    +	if (*end == 'n')
    +		l = -l;	/* multiply by n */
    +	else if (*end == 'K')
    +		l = l*1000;
    +	else if (*end == 'M')
    +		l = l*1000000;
    +	else if (*end == 'k')
    +		l = l*1024;
    +	else if (*end == 'm')
    +		l = l*1024*1024;
    +	else if (*end == 'w')
    +		;
    +	else {/* not recognized */
    +		D("suffix %s for %s, next %p", end, key, next);
    +		end--;
    +	}
    +	end++;
    +	DX(3, "suffix now %s for %s, next %p", end, key, next);
    +	if (next && *end) {
    +		DX(3, "setting next to %s for %s", end, key);
    +		*next = end;
    +	}
    +	return l;
    +}
    +
    +/*
    + * flowsets are a comma-separated list of
    + *     weight:maxlen:flows
    + * indicating how many flows are hooked to that fs.
    + * Both weight and range can be min-max-steps.
    + * In a first pass we just count the number of flowsets and flows,
    + * in a second pass we complete the setup.
    + */
    +static void
    +parse_flowsets(struct cfg_s *c, const char *fs, int pass)
    +{
    +	char *s, *cur, *next;
    +	int n_flows = 0, n_fs = 0, wsum = 0;
    +	int i, j;
    +	struct dn_fs *prev = NULL;
    +
    +	DX(3, "--- pass %d flows %d flowsets %d", pass, c->flows, c->flowsets);
    +	if (pass == 0)
    +		c->fs_config = fs;
    +	s = c->fs_config ? strdup(c->fs_config) : NULL;
    +	if (s == NULL) {
    +		if (pass == 0)
    +			D("no fsconfig");
    +		return;
    +	}
    +	for (next = s; (cur = strsep(&next, ","));) {
    +		char *p = NULL;
    +		int w, w_h, w_steps, wi;
    +		int len, len_h, l_steps, li;
    +		int flows;
    +
    +		w = getnum(strsep(&cur, ":"), &p, "weight");
    +		if (w <= 0)
    +			w = 1;
    +		w_h = p ? getnum(p+1, &p, "weight_max") : w;
    +		w_steps = p ? getnum(p+1, &p, "w_steps") : (w_h == w ?1:2);
    +		len = getnum(strsep(&cur, ":"), &p, "len");
    +		if (len <= 0)
    +			len = 1000;
    +		len_h = p ? getnum(p+1, &p, "len_max") : len;
    +		l_steps = p ? getnum(p+1, &p, "l_steps") : (len_h == len ? 1 : 2);
    +		flows = getnum(strsep(&cur, ":"), NULL, "flows");
    +		if (flows == 0)
    +			flows = 1;
    +		DX(4, "weight %d..%d (%d) len %d..%d (%d) flows %d",
    +			w, w_h, w_steps, len, len_h, l_steps, flows);
    +		if (w == 0 || w_h < w || len == 0 || len_h < len ||
    +				flows == 0) {
    +			DX(4,"wrong parameters %s", fs);
    +			return;
    +		}
    +		n_flows += flows * w_steps * l_steps;
    +		for (i = 0; i < w_steps; i++) {
    +			wi = w + ((w_h - w)* i)/(w_steps == 1 ? 1 : (w_steps-1));
    +			for (j = 0; j < l_steps; j++, n_fs++) {
    +				struct dn_fs *fs = &c->fs[n_fs].fs; // tentative
    +				int x;
    +
    +				li = len + ((len_h - len)* j)/(l_steps == 1 ? 1 : (l_steps-1));
    +				x = (wi*2048)/li;
    +				DX(3, "----- fs %4d weight %4d lmax %4d X %4d flows %d",
    +					n_fs, wi, li, x, flows);
    +				if (pass == 0)
    +					continue;
    +				if (c->fs == NULL || c->flowsets <= n_fs) {
    +					D("error in number of flowsets");
    +					return;
    +				}
    +				wsum += wi * flows;
    +				fs->par[0] = wi;
    +				fs->par[1] = li;
    +				fs->index = n_fs;
    +				fs->n_flows = flows;
    +				fs->cur = fs->first_flow = prev==NULL ? 0 : prev->next_flow;
    +				fs->next_flow = fs->first_flow + fs->n_flows;
    +				fs->y = x * flows;
    +				fs->base_y = (prev == NULL) ? 0 : prev->next_y;
    +				fs->next_y = fs->base_y + fs->y;
    +				prev = fs;
    +			}
    +		}
    +	}
    +	c->max_y = prev ? prev->base_y + prev->y : 0;
    +	c->flows = n_flows;
    +	c->flowsets = n_fs;
    +	c->wsum = wsum;
    +	if (pass == 0)
    +		return;
    +
    +	/* now link all flows to their parent flowsets */
    +	DX(1,"%d flows on %d flowsets max_y %d", c->flows, c->flowsets, c->max_y);
    +	for (i=0; i < c->flowsets; i++) {
    +		struct dn_fs *fs = &c->fs[i].fs;
    +		DX(1, "fs %3d w %5d l %4d flow %5d .. %5d y %6d .. %6d",
    +			i, fs->par[0], fs->par[1],
    +			fs->first_flow, fs->next_flow,
    +			fs->base_y, fs->next_y);
    +		for (j = fs->first_flow; j < fs->next_flow; j++) {
    +			struct dn_queue *q = FI2Q(c, j);
    +			q->fs = &c->fs[i];
    +		}
    +	}
    +}
    +
    +static int
    +init(struct cfg_s *c)
    +{
    +	int i;
    +	int ac = c->ac;
    +	char * const *av = c->av;
    +
    +	c->si_len = sizeof(struct dn_sch_inst);
    +	c->q_len = sizeof(struct dn_queue);
    +	moduledata_t *mod = NULL;
    +	struct dn_alg *p = NULL;
    +
    +	c->th_min = 0;
    +	c->th_max = -20;/* 20 packets per flow */
    +	c->lmin = c->lmax = 1280;	/* packet len */
    +	c->flows = 1;
    +	c->flowsets = 1;
    +	c->name = "null";
    +	ac--; av++;
    +	while (ac > 1) {
    +		if (!strcmp(*av, "-n")) {
    +			c->loops = getnum(av[1], NULL, av[0]);
    +		} else if (!strcmp(*av, "-d")) {
    +			debug = atoi(av[1]);
    +		} else if (!strcmp(*av, "-alg")) {
    +			extern moduledata_t *_g_dn_fifo;
    +			extern moduledata_t *_g_dn_wf2qp;
    +			extern moduledata_t *_g_dn_rr;
    +			extern moduledata_t *_g_dn_qfq;
    +#ifdef WITH_KPS
    +			extern moduledata_t *_g_dn_kps;
    +#endif
    +			if (!strcmp(av[1], "rr"))
    +				mod = _g_dn_rr;
    +			else if (!strcmp(av[1], "wf2qp"))
    +				mod = _g_dn_wf2qp;
    +			else if (!strcmp(av[1], "fifo"))
    +				mod = _g_dn_fifo;
    +			else if (!strcmp(av[1], "qfq"))
    +				mod = _g_dn_qfq;
    +#ifdef WITH_KPS
    +			else if (!strcmp(av[1], "kps"))
    +				mod = _g_dn_kps;
    +#endif
    +			else
    +				mod = NULL;
    +			c->name = mod ? mod->name : "NULL";
    +			DX(3, "using scheduler %s", c->name);
    +		} else if (!strcmp(*av, "-len")) {
    +			c->lmin = getnum(av[1], NULL, av[0]);
    +			c->lmax = c->lmin;
    +			DX(3, "setting max to %d", c->th_max);
    +		} else if (!strcmp(*av, "-burst")) {
    +			c->maxburst = getnum(av[1], NULL, av[0]);
    +			DX(3, "setting max to %d", c->th_max);
    +		} else if (!strcmp(*av, "-qmax")) {
    +			c->th_max = getnum(av[1], NULL, av[0]);
    +			DX(3, "setting max to %d", c->th_max);
    +		} else if (!strcmp(*av, "-qmin")) {
    +			c->th_min = getnum(av[1], NULL, av[0]);
    +			DX(3, "setting min to %d", c->th_min);
    +		} else if (!strcmp(*av, "-flows")) {
    +			c->flows = getnum(av[1], NULL, av[0]);
    +			DX(3, "setting flows to %d", c->flows);
    +		} else if (!strcmp(*av, "-flowsets")) {
    +			parse_flowsets(c, av[1], 0);
    +			DX(3, "setting flowsets to %d", c->flowsets);
    +		} else {
    +			D("option %s not recognised, ignore", *av);
    +		}
    +		ac -= 2; av += 2;
    +	}
    +	if (c->maxburst <= 0)
    +		c->maxburst = 1;
    +	if (c->loops <= 0)
    +		c->loops = 1;
    +	if (c->flows <= 0)
    +		c->flows = 1;
    +	if (c->flowsets <= 0)
    +		c->flowsets = 1;
    +	if (c->lmin <= 0)
    +		c->lmin = 1;
    +	if (c->lmax <= 0)
    +		c->lmax = 1;
    +	/* multiply by N */
    +	if (c->th_min < 0)
    +		c->th_min = c->flows * -c->th_min;
    +	if (c->th_max < 0)
    +		c->th_max = c->flows * -c->th_max;
    +	if (c->th_max <= c->th_min)
    +		c->th_max = c->th_min + 1;
    +	if (mod) {
    +		p = mod->p;
    +		DX(3, "using module %s f %p p %p", mod->name, mod->f, mod->p);
    +		DX(3, "modname %s ty %d", p->name, p->type);
    +		c->enq = p->enqueue;
    +		c->deq = p->dequeue;
    +		c->si_len += p->si_datalen;
    +		c->q_len += p->q_datalen;
    +		c->schk_len += p->schk_datalen;
    +	}
    +	/* allocate queues, flowsets and one scheduler */
    +	c->q = calloc(c->flows, c->q_len);
    +	c->fs = calloc(c->flowsets, sizeof(struct dn_fsk));
    +	c->si = calloc(1, c->si_len);
    +	c->sched = calloc(c->flows, c->schk_len);
    +	if (c->q == NULL || c->fs == NULL) {
    +		D("error allocating memory for flows");
    +		exit(1);
    +	}
    +	c->si->sched = c->sched;
    +	if (p) {
    +		if (p->config)
    +			p->config(c->sched);
    +		if (p->new_sched)
    +			p->new_sched(c->si);
    +	}
    +	/* parse_flowsets links queues to their flowsets */
    +	parse_flowsets(c, av[1], 1);
    +	/* complete the work calling new_fsk */
    +	for (i = 0; i < c->flowsets; i++) {
    +		if (c->fs[i].fs.par[1] == 0)
    +			c->fs[i].fs.par[1] = 1000;	/* default pkt len */
    +		c->fs[i].sched = c->sched;
    +		if (p && p->new_fsk)
    +			p->new_fsk(&c->fs[i]);
    +	}
    +
    +	/* initialize the lists for the generator, and put
    +	 * all flows in the list for backlog = 0
    +	 */
    +	for (i=0; i <= BACKLOG+5; i++)
    +		INIT_LIST_HEAD(&c->ll[i]);
    +
    +	for (i = 0; i < c->flows; i++) {
    +		struct dn_queue *q = FI2Q(c, i);
    +		if (q->fs == NULL)
    +			q->fs = &c->fs[0]; /* XXX */
    +		q->_si = c->si;
    +		if (p && p->new_queue)
    +			p->new_queue(q);
    +		INIT_LIST_HEAD(&q->ni.h);
    +		list_add_tail(&q->ni.h, &c->ll[0]);
    +	}
    +	c->llmask = 1;
    +	return 0;
    +}
    +
    +
    +int
    +main(int ac, char *av[])
    +{
    +	struct cfg_s c;
    +	struct timeval end;
    +	double ll;
    +	int i;
    +	char msg[40];
    +
    +	bzero(&c, sizeof(c));
    +	c.ac = ac;
    +	c.av = av;
    +	init(&c);
    +	gettimeofday(&c.time, NULL);
    +	mainloop(&c);
    +	gettimeofday(&end, NULL);
    +	end.tv_sec -= c.time.tv_sec;
    +	end.tv_usec -= c.time.tv_usec;
    +	if (end.tv_usec < 0) {
    +		end.tv_usec += 1000000;
    +		end.tv_sec--;
    +	}
    +	c.time = end;
    +	ll = end.tv_sec*1000000 + end.tv_usec;
    +	ll *= 1000;	/* convert to nanoseconds */
    +	ll /= c._enqueue;
    +	sprintf(msg, "1::%d", c.flows);
    +	D("%-8s n %d %d time %d.%06d %8.3f qlen %d %d flows %s drops %d",
    +		c.name, c._enqueue, c.loops,
    +		(int)c.time.tv_sec, (int)c.time.tv_usec, ll,
    +		c.th_min, c.th_max,
    +		c.fs_config ? c.fs_config : msg, c.drop);
    +	dump(&c);
    +	DX(1, "done ac %d av %p", ac, av);
    +	for (i=0; i < ac; i++)
    +		DX(1, "arg %d %s", i, av[i]);
    +	return 0;
    +}
    +
    +/*
    + * The controller decides whether in this iteration we should send
    + * (the packet is in c->tosend) and/or receive (flag c->can_dequeue)
    + */
    +static void
    +controller(struct cfg_s *c)
    +{
    +	struct mbuf *m;
    +	struct dn_fs *fs;
    +	int flow_id;
    +
    +	/* histeresis between max and min */
    +	if (c->state == 0 && c->pending >= c->th_max)
    +		c->state = 1;
    +	else if (c->state == 1 && c->pending <= c->th_min)
    +		c->state = 0;
    +	ND(1, "state %d pending %2d", c->state, c->pending);
    +	c->can_dequeue = c->state;
    +	c->tosend = NULL;
    +	if (c->state)
    +		return;
    +
    +    if (1) {
    +	int i;
    +	struct dn_queue *q;
    +	struct list_head *h;
    +
    +	i = ffs(c->llmask) - 1;
    +	if (i < 0) {
    +		DX(2, "no candidate");
    +		c->can_dequeue = 1;
    +		return;
    +	}
    +	h = &c->ll[i];
    +	ND(1, "backlog %d p %p prev %p next %p", i, h, h->prev, h->next);
    +	q = list_first_entry(h, struct dn_queue, ni.h);
    +	list_del(&q->ni.h);
    +	flow_id = Q2FI(c, q);
    +	DX(2, "extracted flow %p %d backlog %d", q, flow_id, i);
    +	if (list_empty(h)) {
    +		ND(2, "backlog %d empty", i);
    +		c->llmask &= ~(1<ni.h, h+1);
    +	ND(1, " after %d p %p prev %p next %p", i+1, h+1, h[1].prev, h[1].next);
    +	if (i < BACKLOG) {
    +		ND(2, "backlog %d full", i+1);
    +		c->llmask |= 1<<(1+i);
    +	}
    +	fs = &q->fs->fs;
    +	c->cur_fs = q->fs - c->fs;
    +	fs->cur = flow_id;
    +    } else {
    +	/* XXX this does not work ? */
    +	/* now decide whom to send the packet, and the length */
    +	/* lookup in the flow table */
    +	if (c->cur_y >= c->max_y) {	/* handle wraparound */
    +		c->cur_y = 0;
    +		c->cur_fs = 0;
    +	}
    +	fs = &c->fs[c->cur_fs].fs;
    +	flow_id = fs->cur++;
    +	if (fs->cur >= fs->next_flow)
    +		fs->cur = fs->first_flow;
    +	c->cur_y++;
    +	if (c->cur_y >= fs->next_y)
    +		c->cur_fs++;
    +    }
    +
    +	/* construct a packet */
    +	if (c->freelist) {
    +		m = c->tosend = c->freelist;
    +		c->freelist = c->freelist->m_nextpkt;
    +	} else {
    +		m = c->tosend = calloc(1, sizeof(struct mbuf));
    +	}
    +	if (m == NULL)
    +		return;
    +
    +	m->cfg = c;
    +	m->m_nextpkt = NULL;
    +	m->m_pkthdr.len = fs->par[1]; // XXX maxlen
    +	m->flow_id = flow_id;
    +
    +	ND(2,"y %6d flow %5d fs %3d weight %4d len %4d",
    +		c->cur_y, m->flow_id, c->cur_fs,
    +		fs->par[0], m->m_pkthdr.len);
    +
    +}
    +
    +/*
    +Packet allocation:
    +to achieve a distribution that matches weights, for each X=w/lmax class
    +we should generate a number of packets proportional to Y = X times the number
    +of flows in the class.
    +So we construct an array with the cumulative distribution of Y's,
    +and use it to identify the flow via inverse mapping (if the Y's are
    +not too many we can use an array for the lookup). In practice,
    +each flow will have X entries [virtually] pointing to it.
    +
    +*/
    diff --git a/sys/netinet/ipfw/test/mylist.h b/sys/netinet/ipfw/test/mylist.h
    new file mode 100644
    index 00000000000..6247f32ea4e
    --- /dev/null
    +++ b/sys/netinet/ipfw/test/mylist.h
    @@ -0,0 +1,49 @@
    +/*
    + * $FreeBSD$
    + *
    + * linux-like bidirectional lists
    + */
    +
    +#ifndef _MYLIST_H
    +#define _MYLIST_H
    +struct list_head {
    +        struct list_head *prev, *next;
    +};
    +
    +#define INIT_LIST_HEAD(l) do {  (l)->prev = (l)->next = (l); } while (0)
    +#define list_empty(l)   ( (l)->next == l )
    +static inline void
    +__list_add(struct list_head *o, struct list_head *prev,
    +        struct list_head *next)
    +{
    +        next->prev = o;
    +        o->next = next;
    +        o->prev = prev;
    +        prev->next = o;
    +}
    + 
    +static inline void
    +list_add_tail(struct list_head *o, struct list_head *head)
    +{
    +        __list_add(o, head->prev, head);
    +}
    +
    +#define list_first_entry(pL, ty, member)        \
    +        (ty *)((char *)((pL)->next) - offsetof(ty, member))
    +
    +static inline void
    +__list_del(struct list_head *prev, struct list_head *next)
    +{
    +        next->prev = prev;
    +        prev->next = next;
    +}
    +
    +static inline void
    +list_del(struct list_head *entry)
    +{
    +	ND("called on %p", entry);
    +        __list_del(entry->prev, entry->next);
    +        entry->next = entry->prev = NULL;
    +}
    +
    +#endif /* _MYLIST_H */
    diff --git a/sys/netinet/ipfw/test/test_dn_heap.c b/sys/netinet/ipfw/test/test_dn_heap.c
    new file mode 100644
    index 00000000000..d460cf2ff36
    --- /dev/null
    +++ b/sys/netinet/ipfw/test/test_dn_heap.c
    @@ -0,0 +1,162 @@
    +/*-
    + * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
    + * 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.
    + */
    +
    +/*
    + * Userland code for testing binary heaps and hash tables
    + *
    + * $FreeBSD$
    + */
    +
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +#include  "dn_heap.h"
    +#define log(x, arg...)	fprintf(stderr, ## arg)
    +#define panic(x...)	fprintf(stderr, ## x), exit(1)
    +
    +#include 
    +
    +struct x {
    +	struct x *ht_link;
    +	char buf[0];
    +};
    +
    +uint32_t hf(uintptr_t key, int flags, void *arg)
    +{
    +	return (flags & DNHT_KEY_IS_OBJ) ?
    +		((struct x *)key)->buf[0] : *(char *)key;
    +}
    +
    +int matchf(void *obj, uintptr_t key, int flags, void *arg)
    +{
    +	char *s = (flags & DNHT_KEY_IS_OBJ) ?
    +		((struct x *)key)->buf : (char *)key;
    +	return (strcmp(((struct x *)obj)->buf, s) == 0);
    +}
    +
    +void *newfn(uintptr_t key, int flags, void *arg)
    +{
    +	char *s = (char *)key;
    +	struct x *p = malloc(sizeof(*p) + 1 + strlen(s));
    +	if (p)
    +		strcpy(p->buf, s);
    +	return p;
    +}
    +
    +char *strings[] = {
    +	"undici", "unico", "doppio", "devoto",
    +	"uno", "due", "tre", "quattro", "cinque", "sei",
    +	"uno", "due", "tre", "quattro", "cinque", "sei",
    +	NULL,
    +};
    +
    +int doprint(void *_x, void *arg)
    +{
    +	struct x *x = _x;
    +	printf("found element <%s>\n", x->buf);
    +	return (int)arg;
    +}
    +
    +static void
    +test_hash()
    +{
    +	char **p;
    +	struct dn_ht *h;
    +	uintptr_t x = 0;
    +	uintptr_t x1 = 0;
    +
    +	/* first, find and allocate */
    +	h = dn_ht_init(NULL, 10, 0, hf, matchf, newfn);
    +
    +	for (p = strings; *p; p++) {
    +		dn_ht_find(h, (uintptr_t)*p, DNHT_INSERT, NULL);
    +	}
    +	dn_ht_scan(h, doprint, 0);
    +	printf("/* second -- find without allocate */\n");
    +	h = dn_ht_init(NULL, 10, 0, hf, matchf, NULL);
    +	for (p = strings; *p; p++) {
    +		void **y = newfn((uintptr_t)*p, 0, NULL);
    +		if (x == 0)
    +			x = (uintptr_t)y;
    +		else {
    +			if (x1 == 0)
    +				x1 = (uintptr_t)*p;
    +		}
    +		dn_ht_find(h, (uintptr_t)y, DNHT_INSERT | DNHT_KEY_IS_OBJ, NULL);
    +	}
    +	dn_ht_scan(h, doprint, 0);
    +	printf("remove %p gives %p\n", (void *)x,
    +		dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
    +	printf("remove %p gives %p\n", (void *)x,
    +		dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
    +	printf("remove %p gives %p\n", (void *)x,
    +		dn_ht_find(h, x1, DNHT_REMOVE, NULL));
    +	printf("remove %p gives %p\n", (void *)x,
    +		dn_ht_find(h, x1, DNHT_REMOVE, NULL));
    +	dn_ht_scan(h, doprint, 0);
    +}
    +
    +int
    +main(int argc, char *argv[])
    +{
    +	struct dn_heap h;
    +	int i, n, n2, n3;
    +
    +	test_hash();
    +	return 0;
    +
    +	/* n = elements, n2 = cycles */
    +	n = (argc > 1) ? atoi(argv[1]) : 0;
    +	if (n <= 0 || n > 1000000)
    +		n = 100;
    +	n2 = (argc > 2) ? atoi(argv[2]) : 0;
    +	if (n2 <= 0)
    +		n = 1000000;
    +	n3 = (argc > 3) ? atoi(argv[3]) : 0;
    +	bzero(&h, sizeof(h));
    +	heap_init(&h, n, -1);
    +	while (n2-- > 0) {
    +		uint64_t prevk = 0;
    +		for (i=0; i < n; i++)
    +			heap_insert(&h, n3 ? n-i: random(), (void *)(100+i));
    +		
    +		for (i=0; h.elements > 0; i++) {
    +			uint64_t k = h.p[0].key;
    +			if (k < prevk)
    +				panic("wrong sequence\n");
    +			prevk = k;
    +			if (0)
    +			printf("%d key %llu, val %p\n",
    +				i, h.p[0].key, h.p[0].object);
    +			heap_extract(&h, NULL);
    +		}
    +	}
    +	return 0;
    +}
    diff --git a/sys/netinet/ipfw/test/test_dn_sched.c b/sys/netinet/ipfw/test/test_dn_sched.c
    new file mode 100644
    index 00000000000..ee46c95ed86
    --- /dev/null
    +++ b/sys/netinet/ipfw/test/test_dn_sched.c
    @@ -0,0 +1,89 @@
    +/*
    + * $FreeBSD$
    + *
    + * library functions for userland testing of dummynet schedulers
    + */
    +
    +#include "dn_test.h"
    +
    +void
    +m_freem(struct mbuf *m)
    +{
    +	printf("free %p\n", m);
    +}
    +
    +int
    +dn_sched_modevent(module_t mod, int cmd, void *arg)
    +{
    +	return 0;
    +}
    +
    +void
    +dn_free_pkts(struct mbuf *m)
    +{
    +	struct mbuf *x;
    +	while ( (x = m) ) {
    +		m = m->m_nextpkt;
    +		m_freem(x);
    +	}
    +}
    +		
    +int
    +dn_delete_queue(void *_q, void *do_free)
    +{
    +	struct dn_queue *q = _q;
    +        if (q->mq.head)
    +                dn_free_pkts(q->mq.head);
    +        free(q);
    +        return 0;
    +}
    +
    +/*
    + * This is a simplified function for testing purposes, which does
    + * not implement statistics or random loss.
    + * Enqueue a packet in q, subject to space and queue management policy
    + * (whose parameters are in q->fs).
    + * Update stats for the queue and the scheduler.
    + * Return 0 on success, 1 on drop. The packet is consumed anyways.
    + */
    +int
    +dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
    +{
    +        if (drop)
    +                goto drop;
    +        if (q->ni.length >= 200)
    +                goto drop;
    +        mq_append(&q->mq, m);
    +        q->ni.length++;
    +        q->ni.tot_bytes += m->m_pkthdr.len;
    +        return 0;
    +
    +drop:
    +        q->ni.drops++;
    +        return 1;
    +}
    +
    +int
    +ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg)
    +{
    +        if (*v < lo) {
    +                *v = dflt;
    +        } else if (*v > hi) {
    +                *v = hi;
    +        }
    +        return *v;
    +}
    +
    +#ifndef __FreeBSD__
    +int
    +fls(int mask)
    +{
    +	int bit;
    +
    +	if (mask == 0)
    +		return (0);
    +	for (bit = 1; mask != 1; bit++)
    +		mask = (unsigned int)mask >> 1;
    +	return (bit);
    +}
    +#endif
    diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
    index 3573472bf25..9341cf29bbe 100644
    --- a/sys/netinet/raw_ip.c
    +++ b/sys/netinet/raw_ip.c
    @@ -80,14 +80,18 @@ VNET_DEFINE(struct inpcbinfo, ripcbinfo);
     #define	V_ripcbinfo		VNET(ripcbinfo)
     
     /*
    - * Control and data hooks for ipfw and dummynet.
    + * Control and data hooks for ipfw, dummynet, divert and so on.
      * The data hooks are not used here but it is convenient
      * to keep them all in one place.
      */
     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_dn_io_ptr)(struct mbuf **m, int dir, struct ip_fw_args *fwa) = NULL;
    +
    +int	(*ip_dn_ctl_ptr)(struct sockopt *);
    +int	(*ip_dn_io_ptr)(struct mbuf **, int, struct ip_fw_args *);
    +void	(*ip_divert_ptr)(struct mbuf *, int);
    +int	(*ng_ipfw_input_p)(struct mbuf **, int,
    +			struct ip_fw_args *, int);
     
     /*
      * Hooks for multicast routing. They all default to NULL, so leave them not
    
    From 0ebeb8cec4edb46c8bb931c7c2ff075d7561ac21 Mon Sep 17 00:00:00 2001
    From: Jaakko Heinonen 
    Date: Tue, 23 Mar 2010 16:45:29 +0000
    Subject: [PATCH 1641/2592] MFC r205121:
    
    Use an unique directory name instead of hardcoded /tmp/.diskless.
    A malicious user could create a file named /tmp/.diskless and cause
    the script to misbehave.
    
    PR:		conf/141258
    ---
     etc/rc.d/tmp | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/etc/rc.d/tmp b/etc/rc.d/tmp
    index abf53ac4de1..282709e5e35 100755
    --- a/etc/rc.d/tmp
    +++ b/etc/rc.d/tmp
    @@ -51,8 +51,8 @@ case "${tmpmfs}" in
     [Nn][Oo])
     	;;
     *)
    -	if /bin/mkdir -p /tmp/.diskless 2> /dev/null; then
    -		rmdir /tmp/.diskless
    +	if _tmpdir=$(mktemp -d -q /tmp/.diskless.XXXXXX); then
    +		rmdir ${_tmpdir}
     	else
     		if [ -h /tmp ]; then
     			echo "*** /tmp is a symlink to a non-writable area!"
    
    From 229c84e85bb140719cf9aec3fcab325d3287b193 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Tue, 23 Mar 2010 17:14:50 +0000
    Subject: [PATCH 1642/2592] MFC r205333: vfs_mount.9: drop cross-reference to a
     removed manual
    
    ---
     share/man/man9/vfs_mount.9 | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/share/man/man9/vfs_mount.9 b/share/man/man9/vfs_mount.9
    index b64698c119c..47f60486d84 100644
    --- a/share/man/man9/vfs_mount.9
    +++ b/share/man/man9/vfs_mount.9
    @@ -127,8 +127,7 @@ this call relies on a large number of other kernel services
     whose errors it returns so this list may not be exhaustive.
     .Sh SEE ALSO
     .Xr mount 2 ,
    -.Xr mount 8 ,
    -.Xr vfs_mountedon 9
    +.Xr mount 8
     .Pp
     .Va vfs.usermount
     .Sh AUTHORS
    
    From 60a337785e3b6eaf1e0b82b7819cd724dd1e1cb6 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 19:16:35 +0000
    Subject: [PATCH 1643/2592] MFC r204151,204223: r204151:   Add TSO support on
     VLAN. Controller requires VLAN hardware tagging   to make TSO work on VLAN.
     So if VLAN hardware tagging is disabled   explicitly clear TSO on VLAN. While
     I'm here remove duplicated   VLAN_CAPABILITIES call.
    
    r204223:
      Remove Tx mbuf parsing code for VLAN in TSO path. Controller does
      not support TSO over VLAN if VLAN hardware tagging is disabled so
      there is no need to check VLAN here.
      While I'm here make sure to pullup IP/TCP headers in the first
      buffer.
    ---
     sys/dev/bge/if_bge.c | 43 ++++++++++++++++---------------------------
     1 file changed, 16 insertions(+), 27 deletions(-)
    
    diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
    index 5209b6a6c9f..390222816ba 100644
    --- a/sys/dev/bge/if_bge.c
    +++ b/sys/dev/bge/if_bge.c
    @@ -2816,7 +2816,7 @@ bge_attach(device_t dev)
     	    IFCAP_VLAN_MTU;
     	if ((sc->bge_flags & BGE_FLAG_TSO) != 0) {
     		ifp->if_hwassist |= CSUM_TSO;
    -		ifp->if_capabilities |= IFCAP_TSO4;
    +		ifp->if_capabilities |= IFCAP_TSO4 | IFCAP_VLAN_HWTSO;
     	}
     #ifdef IFCAP_VLAN_HWCSUM
     	ifp->if_capabilities |= IFCAP_VLAN_HWCSUM;
    @@ -3835,12 +3835,11 @@ bge_cksum_pad(struct mbuf *m)
     static struct mbuf *
     bge_setup_tso(struct bge_softc *sc, struct mbuf *m, uint16_t *mss)
     {
    -	struct ether_header *eh;
     	struct ip *ip;
     	struct tcphdr *tcp;
     	struct mbuf *n;
     	uint16_t hlen;
    -	uint32_t ip_off, poff;
    +	uint32_t poff;
     
     	if (M_WRITABLE(m) == 0) {
     		/* Get a writable copy. */
    @@ -3850,28 +3849,16 @@ bge_setup_tso(struct bge_softc *sc, struct mbuf *m, uint16_t *mss)
     			return (NULL);
     		m = n;
     	}
    -	ip_off = sizeof(struct ether_header);
    -	m = m_pullup(m, ip_off);
    +	m = m_pullup(m, sizeof(struct ether_header) + sizeof(struct ip));
     	if (m == NULL)
     		return (NULL);
    -	eh = mtod(m, struct ether_header *);
    -	/* Check the existence of VLAN tag. */
    -	if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
    -		ip_off = sizeof(struct ether_vlan_header);
    -		m = m_pullup(m, ip_off);
    -		if (m == NULL)
    -			return (NULL);
    -	}
    -	m = m_pullup(m, ip_off + sizeof(struct ip));
    -	if (m == NULL)
    -		return (NULL);
    -	ip = (struct ip *)(mtod(m, char *) + ip_off);
    -	poff = ip_off + (ip->ip_hl << 2);
    +	ip = (struct ip *)(mtod(m, char *) + sizeof(struct ether_header));
    +	poff = sizeof(struct ether_header) + (ip->ip_hl << 2);
     	m = m_pullup(m, poff + sizeof(struct tcphdr));
     	if (m == NULL)
     		return (NULL);
     	tcp = (struct tcphdr *)(mtod(m, char *) + poff);
    -	m = m_pullup(m, poff + sizeof(struct tcphdr) + tcp->th_off);
    +	m = m_pullup(m, poff + (tcp->th_off << 2));
     	if (m == NULL)
     		return (NULL);
     	/*
    @@ -4526,9 +4513,6 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     				ifp->if_hwassist |= BGE_CSUM_FEATURES;
     			else
     				ifp->if_hwassist &= ~BGE_CSUM_FEATURES;
    -#ifdef VLAN_CAPABILITIES
    -			VLAN_CAPABILITIES(ifp);
    -#endif
     		}
     
     		if ((mask & IFCAP_TSO4) != 0 &&
    @@ -4546,16 +4530,21 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			bge_init(sc);
     		}
     
    -		if (mask & IFCAP_VLAN_HWTAGGING) {
    +		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
    +		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) != 0) {
     			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    +			if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
    +				ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
     			BGE_LOCK(sc);
     			bge_setvlan(sc);
     			BGE_UNLOCK(sc);
    -#ifdef VLAN_CAPABILITIES
    -			VLAN_CAPABILITIES(ifp);
    -#endif
     		}
    -
    +#ifdef VLAN_CAPABILITIES
    +		VLAN_CAPABILITIES(ifp);
    +#endif
     		break;
     	default:
     		error = ether_ioctl(ifp, command, data);
    
    From d95d4a8336336368bc17e4d616daad8a5358e70d Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 19:30:15 +0000
    Subject: [PATCH 1644/2592] MFC r204155,204219: r204155:   Increase PCIe
     maximuim read request size to 2048. Because re(4) uses   Tx DMA burst size
     2048, I beleive PCIe maximum read request size   also should match to the
     value of Tx DMA burst size. With this   change I can get more than 800Mbps
     for TCP bulk transfers.   Previously I was not able to get more than 700Mbps.
     If I enable TSO   it now shows 927Mbps.
    
    r204219:
      Add TSO on VLANs. Because re(4) has a TSO limitation for jumbo
      frame, make sure to update VLAN capabilities whenever jumbo frame
      is configured.
      While I'm here rearrange interface capabilities configuration. The
      controller requires VLAN hardware tagging to make TSO work on VLANs
      so explicitly check this requirement.
    ---
     sys/dev/re/if_re.c | 29 ++++++++++++++++++++---------
     1 file changed, 20 insertions(+), 9 deletions(-)
    
    diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
    index a642925b50c..978580179d5 100644
    --- a/sys/dev/re/if_re.c
    +++ b/sys/dev/re/if_re.c
    @@ -1162,6 +1162,9 @@ re_attach(device_t dev)
     	msic = 0;
     	if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
     		sc->rl_flags |= RL_FLAG_PCIE;
    +		/* Set PCIe maximum read request size to 2048. */
    +		if (pci_get_max_read_req(dev) < 2048)
    +			pci_set_max_read_req(dev, 2048);
     		msic = pci_msi_count(dev);
     		if (bootverbose)
     			device_printf(dev, "MSI count : %d\n", msic);
    @@ -1426,7 +1429,7 @@ re_attach(device_t dev)
     	 */
     	if ((sc->rl_flags & RL_FLAG_DESCV2) == 0) {
     		ifp->if_hwassist |= CSUM_TSO;
    -		ifp->if_capabilities |= IFCAP_TSO4;
    +		ifp->if_capabilities |= IFCAP_TSO4 | IFCAP_VLAN_HWTSO;
     	}
     
     	/*
    @@ -1448,7 +1451,7 @@ re_attach(device_t dev)
     	 * packets in TSO size.
     	 */
     	ifp->if_hwassist &= ~CSUM_TSO;
    -	ifp->if_capenable &= ~IFCAP_TSO4;
    +	ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO);
     #ifdef DEVICE_POLLING
     	ifp->if_capabilities |= IFCAP_POLLING;
     #endif
    @@ -2786,6 +2789,7 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     		    (ifp->if_capenable & IFCAP_TSO4) != 0) {
     			ifp->if_capenable &= ~IFCAP_TSO4;
     			ifp->if_hwassist &= ~CSUM_TSO;
    +			VLAN_CAPABILITIES(ifp);
     		}
     		RL_UNLOCK(sc);
     		break;
    @@ -2852,14 +2856,10 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     				ifp->if_hwassist &= ~RE_CSUM_FEATURES;
     			reinit = 1;
     		}
    -		if (mask & IFCAP_VLAN_HWTAGGING) {
    -			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    -			reinit = 1;
    -		}
    -		if (mask & IFCAP_TSO4) {
    +		if ((mask & IFCAP_TSO4) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_TSO) != 0) {
     			ifp->if_capenable ^= IFCAP_TSO4;
    -			if ((IFCAP_TSO4 & ifp->if_capenable) &&
    -			    (IFCAP_TSO4 & ifp->if_capabilities))
    +			if ((IFCAP_TSO4 & ifp->if_capenable) != 0)
     				ifp->if_hwassist |= CSUM_TSO;
     			else
     				ifp->if_hwassist &= ~CSUM_TSO;
    @@ -2869,6 +2869,17 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     				ifp->if_hwassist &= ~CSUM_TSO;
     			}
     		}
    +		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
    +		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) != 0) {
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    +			/* TSO over VLAN requires VLAN hardware tagging. */
    +			if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
    +				ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
    +			reinit = 1;
    +		}
     		if ((mask & IFCAP_WOL) != 0 &&
     		    (ifp->if_capabilities & IFCAP_WOL) != 0) {
     			if ((mask & IFCAP_WOL_UCAST) != 0)
    
    From ac8ed73502f53826616724164cff45bf77ef7e93 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 19:37:15 +0000
    Subject: [PATCH 1645/2592] MFC r204225:   Add TSO support on VLANs. jme(4)
     controllers do not require VLAN   hardware tagging to make TSO work over
     VLANs.
    
    ---
     sys/dev/jme/if_jme.c | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/jme/if_jme.c b/sys/dev/jme/if_jme.c
    index eb8b6304523..91642937c2c 100644
    --- a/sys/dev/jme/if_jme.c
    +++ b/sys/dev/jme/if_jme.c
    @@ -783,7 +783,7 @@ jme_attach(device_t dev)
     
     	/* VLAN capability setup */
     	ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING |
    -	    IFCAP_VLAN_HWCSUM;
    +	    IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWTSO;
     	ifp->if_capenable = ifp->if_capabilities;
     
     	/* Tell the upper layer(s) we support long frames. */
    @@ -2000,6 +2000,9 @@ jme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     		if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
     		    (ifp->if_capabilities & IFCAP_VLAN_HWCSUM) != 0)
     			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
    +		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
     		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
     		    (IFCAP_VLAN_HWTAGGING & ifp->if_capabilities) != 0) {
     			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    
    From 061d3abfa8a3a4f955e7458556a08fdd6e28e5f5 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 19:41:43 +0000
    Subject: [PATCH 1646/2592] MFC r204228,204230: r204228:   Add TSO support on
     VLANs. Also make sure to update TSO capability   whenever jumbo frame is
     configured.   While I'm here remove unnecessary check of VLAN hardware
     checksum   offloading. vlan(4) already takes care of this.
    
    r204230:
      Remove Tx mbuf parsing code for VLAN in TSO path. Controller does
      not support TSO over VLAN if VLAN hardware tagging is disabled so
      there is no need to check VLAN here.
    ---
     sys/dev/alc/if_alc.c | 46 ++++++++------------------------------------
     1 file changed, 8 insertions(+), 38 deletions(-)
    
    diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
    index a483f160fa0..e95b04453cd 100644
    --- a/sys/dev/alc/if_alc.c
    +++ b/sys/dev/alc/if_alc.c
    @@ -84,9 +84,6 @@ __FBSDID("$FreeBSD$");
     #else
     #define	ALC_CSUM_FEATURES	(CSUM_IP | CSUM_TCP | CSUM_UDP)
     #endif
    -#ifndef	IFCAP_VLAN_HWTSO
    -#define	IFCAP_VLAN_HWTSO	0
    -#endif
     
     MODULE_DEPEND(alc, pci, 1, 1, 1);
     MODULE_DEPEND(alc, ether, 1, 1, 1);
    @@ -756,8 +753,8 @@ alc_attach(device_t dev)
     	ether_ifattach(ifp, sc->alc_eaddr);
     
     	/* VLAN capability setup. */
    -	ifp->if_capabilities |= IFCAP_VLAN_MTU;
    -	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM;
    +	ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING |
    +	    IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWTSO;
     	ifp->if_capenable = ifp->if_capabilities;
     	/*
     	 * XXX
    @@ -1791,7 +1788,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
     	struct tcphdr *tcp;
     	bus_dma_segment_t txsegs[ALC_MAXTXSEGS];
     	bus_dmamap_t map;
    -	uint32_t cflags, hdrlen, ip_off, poff, vtag;
    +	uint32_t cflags, hdrlen, poff, vtag;
     	int error, idx, nsegs, prod;
     
     	ALC_LOCK_ASSERT(sc);
    @@ -1801,7 +1798,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
     	m = *m_head;
     	ip = NULL;
     	tcp = NULL;
    -	ip_off = poff = 0;
    +	poff = 0;
     	if ((m->m_pkthdr.csum_flags & (ALC_CSUM_FEATURES | CSUM_TSO)) != 0) {
     		/*
     		 * AR8131/AR8132 requires offset of TCP/UDP header in its
    @@ -1811,7 +1808,6 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
     		 * cycles on FreeBSD so fast host CPU is required to get
     		 * smooth TSO performance.
     		 */
    -		struct ether_header *eh;
     
     		if (M_WRITABLE(m) == 0) {
     			/* Get a writable copy. */
    @@ -1825,32 +1821,13 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
     			*m_head = m;
     		}
     
    -		ip_off = sizeof(struct ether_header);
    -		m = m_pullup(m, ip_off);
    +		m = m_pullup(m, sizeof(struct ether_header) + sizeof(struct ip));
     		if (m == NULL) {
     			*m_head = NULL;
     			return (ENOBUFS);
     		}
    -		eh = mtod(m, struct ether_header *);
    -		/*
    -		 * Check if hardware VLAN insertion is off.
    -		 * Additional check for LLC/SNAP frame?
    -		 */
    -		if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
    -			ip_off = sizeof(struct ether_vlan_header);
    -			m = m_pullup(m, ip_off);
    -			if (m == NULL) {
    -				*m_head = NULL;
    -				return (ENOBUFS);
    -			}
    -		}
    -		m = m_pullup(m, ip_off + sizeof(struct ip));
    -		if (m == NULL) {
    -			*m_head = NULL;
    -			return (ENOBUFS);
    -		}
    -		ip = (struct ip *)(mtod(m, char *) + ip_off);
    -		poff = ip_off + (ip->ip_hl << 2);
    +		ip = (struct ip *)(mtod(m, char *) + sizeof(struct ether_header));
    +		poff = sizeof(struct ether_header) + (ip->ip_hl << 2);
     		if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
     			m = m_pullup(m, poff + sizeof(struct tcphdr));
     			if (m == NULL) {
    @@ -2133,6 +2110,7 @@ alc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     			    (ifp->if_capenable & IFCAP_TSO4) != 0) {
     				ifp->if_capenable &= ~IFCAP_TSO4;
     				ifp->if_hwassist &= ~CSUM_TSO;
    +				VLAN_CAPABILITIES(ifp);
     			}
     			ALC_UNLOCK(sc);
     		}
    @@ -2204,14 +2182,6 @@ alc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
     		    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
     			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
    -		/*
    -		 * VLAN hardware tagging is required to do checksum
    -		 * offload or TSO on VLAN interface. Checksum offload
    -		 * on VLAN interface also requires hardware checksum
    -		 * offload of parent interface.
    -		 */
    -		if ((ifp->if_capenable & IFCAP_TXCSUM) == 0)
    -			ifp->if_capenable &= ~IFCAP_VLAN_HWCSUM;
     		if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
     			ifp->if_capenable &=
     			    ~(IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM);
    
    From b951499f98f74bf1e1593b31f8e866bcac08a4df Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 21:38:25 +0000
    Subject: [PATCH 1647/2592] MFC r204361-204362: r204361:   Reuse the configured
     LE for VLAN if new LE was created for TSO.   Only old controllers need to
     create new LE for TSO. This change   makes TSO work over VLANs.
    
    r204362:
      Add TSO support on VLANs. Controller requires VLAN hardware tagging
      to make TSO work over VLANs.
    ---
     sys/dev/msk/if_msk.c | 19 ++++++++++++-------
     1 file changed, 12 insertions(+), 7 deletions(-)
    
    diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
    index dd52abe54c3..29b22051af9 100644
    --- a/sys/dev/msk/if_msk.c
    +++ b/sys/dev/msk/if_msk.c
    @@ -1006,11 +1006,6 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     		if ((mask & IFCAP_RXCSUM) != 0 &&
     		    (IFCAP_RXCSUM & ifp->if_capabilities) != 0)
     			ifp->if_capenable ^= IFCAP_RXCSUM;
    -		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    -		    (IFCAP_VLAN_HWTAGGING & ifp->if_capabilities) != 0) {
    -			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    -			msk_setvlan(sc_if, ifp);
    -		}
     		if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
     		    (IFCAP_VLAN_HWCSUM & ifp->if_capabilities) != 0)
     			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
    @@ -1022,6 +1017,16 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			else
     				ifp->if_hwassist &= ~CSUM_TSO;
     		}
    +		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
    +		    (IFCAP_VLAN_HWTSO & ifp->if_capabilities) != 0)
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
    +		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    +		    (IFCAP_VLAN_HWTAGGING & ifp->if_capabilities) != 0) {
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    +			if ((IFCAP_VLAN_HWTAGGING & ifp->if_capenable) == 0)
    +				ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
    +			msk_setvlan(sc_if, ifp);
    +		}
     		if (ifp->if_mtu > ETHERMTU &&
     		    (sc_if->msk_flags & MSK_FLAG_JUMBO_NOCSUM) != 0) {
     			ifp->if_hwassist &= ~(MSK_CSUM_FEATURES | CSUM_TSO);
    @@ -1561,7 +1566,7 @@ msk_attach(device_t dev)
     		 * this workaround does not work so disable checksum offload
     		 * for VLAN interface.
     		 */
    -        	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
    +        	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO;
     		/*
     		 * Enable Rx checksum offloading for VLAN taggedd frames
     		 * if controller support new descriptor format.
    @@ -2688,7 +2693,7 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
     	}
     	/* Check if we have a VLAN tag to insert. */
     	if ((m->m_flags & M_VLANTAG) != 0) {
    -		if (tso == 0) {
    +		if (tx_le == NULL) {
     			tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
     			tx_le->msk_addr = htole32(0);
     			tx_le->msk_control = htole32(OP_VLAN | HW_OWNER |
    
    From 5774c1ed84d612329defe7a422f06002271dff51 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 21:51:31 +0000
    Subject: [PATCH 1648/2592] MFC r204363,204365-204367,204539-204540: r204363:  
     Optimize inserting LE for TX checksum computation. Controller does   not
     require checksum LE configuration if checksum start and write   position is
     the same as before. So keep track last checksum start   and write position
     and insert new LE whenever the position is   changed. This reduces number of
     LEs used in TX path as well as   slightly enhance TX performance.
    
    r204365:
      Don't hardcod register offset to set PCIe max read request size.
      The register offset is not valid on 88E8072 controller. Also don't
      blindly increase max read request size to 4096, instead, use 2048
      which seems to be more sane value and only change the value if the
      hardware default size(512) was used on that register.
      For PCIX controllers, use system defined constant rather than using
      magic value.
      While I'm here stop showing negotiated link width.
    
    r204366:
      Allocate single MSI message. msk(4) used to allocate 2 MSI messages
      for controllers like 88E8053 which reports two MSI messages.
      Because we don't get anything useful things with 2 MSI messages,
      allocating 1 MSI message would be more sane approach.
      While I'm here, enable MSI for dual-port controllers too. Because
      status block is shared for dual-port controllers, I don't think
      msk(4) will encounter problem for using MSI on dual-port
      controllers.
    
    r204367:
      Remove trailing white spaces.
    
    r204539:
      Properly sync status LEs after processing.
    
    r204540:
      Make sure to enable flow-control only if established link is
      full-duplex. Previously msk(4) used to allow flow-control on
      1000baseT half-duplex media. Also GMAC pause is enabled if link
      partner is capable of handling it.
      While I'm here use IFM_OPTIONS instead of using IFM_GMASK to check
      optional flags of link.
    ---
     sys/dev/msk/if_msk.c    | 174 +++++++++++++++-------------------------
     sys/dev/msk/if_mskreg.h |   7 +-
     2 files changed, 69 insertions(+), 112 deletions(-)
    
    diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
    index 29b22051af9..06bacae0c81 100644
    --- a/sys/dev/msk/if_msk.c
    +++ b/sys/dev/msk/if_msk.c
    @@ -393,12 +393,6 @@ static struct resource_spec msk_irq_spec_msi[] = {
     	{ -1,			0,		0 }
     };
     
    -static struct resource_spec msk_irq_spec_msi2[] = {
    -	{ SYS_RES_IRQ,		1,		RF_ACTIVE },
    -	{ SYS_RES_IRQ,		2,		RF_ACTIVE },
    -	{ -1,			0,		0 }
    -};
    -
     static int
     msk_miibus_readreg(device_t dev, int phy, int reg)
     {
    @@ -538,28 +532,25 @@ msk_miibus_statchg(device_t dev)
     			break;
     		}
     
    -		if (((mii->mii_media_active & IFM_GMASK) & IFM_FDX) != 0)
    -			gmac |= GM_GPCR_DUP_FULL;
     		/* Disable Rx flow control. */
    -		if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG0) == 0)
    +		if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FLAG0) == 0)
     			gmac |= GM_GPCR_FC_RX_DIS;
     		/* Disable Tx flow control. */
    -		if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG1) == 0)
    +		if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FLAG1) == 0)
     			gmac |= GM_GPCR_FC_TX_DIS;
    +		if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
    +			gmac |= GM_GPCR_DUP_FULL;
    +		else
    +			gmac |= GM_GPCR_FC_RX_DIS | GM_GPCR_FC_TX_DIS;
     		gmac |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
     		GMAC_WRITE_2(sc, sc_if->msk_port, GM_GP_CTRL, gmac);
     		/* Read again to ensure writing. */
     		GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL);
    -
    -		gmac = GMC_PAUSE_ON;
    -		if (((mii->mii_media_active & IFM_GMASK) &
    -		    (IFM_FLAG0 | IFM_FLAG1)) == 0)
    -			gmac = GMC_PAUSE_OFF;
    -		/* Diable pause for 10/100 Mbps in half-duplex mode. */
    -		if ((((mii->mii_media_active & IFM_GMASK) & IFM_FDX) == 0) &&
    -		    (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX ||
    -		    IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T))
    -			gmac = GMC_PAUSE_OFF;
    +		gmac = GMC_PAUSE_OFF;
    +		if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
    +			if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FLAG0) != 0)
    +				gmac = GMC_PAUSE_ON;
    +		}
     		CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), gmac);
     
     		/* Enable PHY interrupt for FIFO underrun/overflow. */
    @@ -738,6 +729,7 @@ msk_init_tx_ring(struct msk_if_softc *sc_if)
     	int i;
     
     	sc_if->msk_cdata.msk_tso_mtu = 0;
    +	sc_if->msk_cdata.msk_last_csum = 0;
     	sc_if->msk_cdata.msk_tx_prod = 0;
     	sc_if->msk_cdata.msk_tx_cons = 0;
     	sc_if->msk_cdata.msk_tx_cnt = 0;
    @@ -1355,35 +1347,22 @@ mskc_reset(struct msk_softc *sc)
              * On dual port PCI-X card, there is an problem where status
              * can be received out of order due to split transactions.
              */
    -	if (sc->msk_bustype == MSK_PCIX_BUS && sc->msk_num_port > 1) {
    -		int pcix;
    +	if (sc->msk_pcixcap != 0 && sc->msk_num_port > 1) {
     		uint16_t pcix_cmd;
     
    -		if (pci_find_extcap(sc->msk_dev, PCIY_PCIX, &pcix) == 0) {
    -			pcix_cmd = pci_read_config(sc->msk_dev, pcix + 2, 2);
    -			/* Clear Max Outstanding Split Transactions. */
    -			pcix_cmd &= ~0x70;
    -			CSR_WRITE_1(sc, B2_TST_CTRL1, TST_CFG_WRITE_ON);
    -			pci_write_config(sc->msk_dev, pcix + 2, pcix_cmd, 2);
    -			CSR_WRITE_1(sc, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
    -		}
    +		pcix_cmd = pci_read_config(sc->msk_dev,
    +		    sc->msk_pcixcap + PCIXR_COMMAND, 2);
    +		/* Clear Max Outstanding Split Transactions. */
    +		pcix_cmd &= ~PCIXM_COMMAND_MAX_SPLITS;
    +		CSR_WRITE_1(sc, B2_TST_CTRL1, TST_CFG_WRITE_ON);
    +		pci_write_config(sc->msk_dev,
    +		    sc->msk_pcixcap + PCIXR_COMMAND, pcix_cmd, 2);
    +		CSR_WRITE_1(sc, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
             }
    -	if (sc->msk_bustype == MSK_PEX_BUS) {
    -		uint16_t v, width;
    -
    -		v = pci_read_config(sc->msk_dev, PEX_DEV_CTRL, 2);
    -		/* Change Max. Read Request Size to 4096 bytes. */
    -		v &= ~PEX_DC_MAX_RRS_MSK;
    -		v |= PEX_DC_MAX_RD_RQ_SIZE(5);
    -		pci_write_config(sc->msk_dev, PEX_DEV_CTRL, v, 2);
    -		width = pci_read_config(sc->msk_dev, PEX_LNK_STAT, 2);
    -		width = (width & PEX_LS_LINK_WI_MSK) >> 4;
    -		v = pci_read_config(sc->msk_dev, PEX_LNK_CAP, 2);
    -		v = (v & PEX_LS_LINK_WI_MSK) >> 4;
    -		if (v != width)
    -			device_printf(sc->msk_dev,
    -			    "negotiated width of link(x%d) != "
    -			    "max. width of link(x%d)\n", width, v); 
    +	if (sc->msk_expcap != 0) {
    +		/* Change Max. Read Request Size to 2048 bytes. */
    +		if (pci_get_max_read_req(sc->msk_dev) == 512)
    +			pci_set_max_read_req(sc->msk_dev, 2048);
     	}
     
     	/* Clear status list. */
    @@ -1521,7 +1500,7 @@ msk_attach(device_t dev)
     	 * Enable Rx checksum offloading if controller support new
     	 * descriptor format.
     	 */
    -	if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 && 
    +	if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 &&
     	    (sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0)
     		ifp->if_capabilities |= IFCAP_RXCSUM;
     	ifp->if_hwassist = MSK_CSUM_FEATURES | CSUM_TSO;
    @@ -1571,7 +1550,7 @@ msk_attach(device_t dev)
     		 * Enable Rx checksum offloading for VLAN taggedd frames
     		 * if controller support new descriptor format.
     		 */
    -		if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 && 
    +		if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 &&
     		    (sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0)
     			ifp->if_capabilities |= IFCAP_VLAN_HWCSUM;
     	}
    @@ -1695,11 +1674,13 @@ mskc_attach(device_t dev)
     	}
     
     	/* Check bus type. */
    -	if (pci_find_extcap(sc->msk_dev, PCIY_EXPRESS, ®) == 0)
    +	if (pci_find_extcap(sc->msk_dev, PCIY_EXPRESS, ®) == 0) {
     		sc->msk_bustype = MSK_PEX_BUS;
    -	else if (pci_find_extcap(sc->msk_dev, PCIY_PCIX, ®) == 0)
    +		sc->msk_expcap = reg;
    +	} else if (pci_find_extcap(sc->msk_dev, PCIY_PCIX, ®) == 0) {
     		sc->msk_bustype = MSK_PCIX_BUS;
    -	else
    +		sc->msk_pcixcap = reg;
    +	} else
     		sc->msk_bustype = MSK_PCI_BUS;
     
     	switch (sc->msk_hw_id) {
    @@ -1769,37 +1750,16 @@ mskc_attach(device_t dev)
     	msic = pci_msi_count(dev);
     	if (bootverbose)
     		device_printf(dev, "MSI count : %d\n", msic);
    -	/*
    -	 * The Yukon II reports it can handle two messages, one for each
    -	 * possible port.  We go ahead and allocate two messages and only
    -	 * setup a handler for both if we have a dual port card.
    -	 *
    -	 * XXX: I haven't untangled the interrupt handler to handle dual
    -	 * port cards with separate MSI messages, so for now I disable MSI
    -	 * on dual port cards.
    -	 */
     	if (legacy_intr != 0)
     		msi_disable = 1;
    -	if (msi_disable == 0) {
    -		switch (msic) {
    -		case 2:
    -		case 1: /* 88E8058 reports 1 MSI message */
    -			msir = msic;
    -			if (sc->msk_num_port == 1 &&
    -			    pci_alloc_msi(dev, &msir) == 0) {
    -				if (msic == msir) {
    -					sc->msk_pflags |= MSK_FLAG_MSI;
    -					sc->msk_irq_spec = msic == 2 ?
    -					    msk_irq_spec_msi2 :
    -					    msk_irq_spec_msi;
    -				} else
    -					pci_release_msi(dev);
    -			}
    -			break;
    -		default:
    -			device_printf(dev,
    -			    "Unexpected number of MSI messages : %d\n", msic);
    -			break;
    +	if (msi_disable == 0 && msic > 0) {
    +		msir = 1;
    +		if (pci_alloc_msi(dev, &msir) == 0) {
    +			if (msir == 1) {
    +				sc->msk_pflags |= MSK_FLAG_MSI;
    +				sc->msk_irq_spec = msk_irq_spec_msi;
    +			} else
    +				pci_release_msi(dev);
     		}
     	}
     
    @@ -1873,7 +1833,7 @@ mskc_attach(device_t dev)
     	if (legacy_intr)
     		error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
     		    INTR_MPSAFE, NULL, msk_legacy_intr, sc,
    -		    &sc->msk_intrhand[0]);
    +		    &sc->msk_intrhand);
     	else {
     		TASK_INIT(&sc->msk_int_task, 0, msk_int_task, sc);
     		sc->msk_tq = taskqueue_create_fast("msk_taskq", M_WAITOK,
    @@ -1881,7 +1841,7 @@ mskc_attach(device_t dev)
     		taskqueue_start_threads(&sc->msk_tq, 1, PI_NET, "%s taskq",
     		    device_get_nameunit(sc->msk_dev));
     		error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
    -		    INTR_MPSAFE, msk_intr, NULL, sc, &sc->msk_intrhand[0]);
    +		    INTR_MPSAFE, msk_intr, NULL, sc, &sc->msk_intrhand);
     	}
     
     	if (error != 0) {
    @@ -1995,13 +1955,9 @@ mskc_detach(device_t dev)
     		taskqueue_free(sc->msk_tq);
     		sc->msk_tq = NULL;
     	}
    -	if (sc->msk_intrhand[0]) {
    -		bus_teardown_intr(dev, sc->msk_irq[0], sc->msk_intrhand[0]);
    -		sc->msk_intrhand[0] = NULL;
    -	}
    -	if (sc->msk_intrhand[1]) {
    -		bus_teardown_intr(dev, sc->msk_irq[0], sc->msk_intrhand[0]);
    -		sc->msk_intrhand[1] = NULL;
    +	if (sc->msk_intrhand) {
    +		bus_teardown_intr(dev, sc->msk_irq[0], sc->msk_intrhand);
    +		sc->msk_intrhand = NULL;
     	}
     	bus_release_resources(dev, sc->msk_irq_spec, sc->msk_irq);
     	if ((sc->msk_pflags & MSK_FLAG_MSI) != 0)
    @@ -2532,7 +2488,7 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
     	struct mbuf *m;
     	bus_dmamap_t map;
     	bus_dma_segment_t txsegs[MSK_MAXTXSEGS];
    -	uint32_t control, prod, si;
    +	uint32_t control, csum, prod, si;
     	uint16_t offset, tcp_offset, tso_mtu;
     	int error, i, nseg, tso;
     
    @@ -2711,17 +2667,22 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
     		if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) != 0)
     			control |= CALSUM;
     		else {
    -			tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
    -			tx_le->msk_addr = htole32(((tcp_offset +
    -			    m->m_pkthdr.csum_data) & 0xffff) |
    -			    ((uint32_t)tcp_offset << 16));
    -			tx_le->msk_control = htole32(1 << 16 |
    -			    (OP_TCPLISW | HW_OWNER));
    -			control = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
    +			control |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
     			if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
     				control |= UDPTCP;
    -			sc_if->msk_cdata.msk_tx_cnt++;
    -			MSK_INC(prod, MSK_TX_RING_CNT);
    +			/* Checksum write position. */
    +			csum = (tcp_offset + m->m_pkthdr.csum_data) & 0xffff;
    +			/* Checksum start position. */
    +			csum |= (uint32_t)tcp_offset << 16;
    +			if (csum != sc_if->msk_cdata.msk_last_csum) {
    +				tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
    +				tx_le->msk_addr = htole32(csum);
    +				tx_le->msk_control = htole32(1 << 16 |
    +				    (OP_TCPLISW | HW_OWNER));
    +				sc_if->msk_cdata.msk_tx_cnt++;
    +				MSK_INC(prod, MSK_TX_RING_CNT);
    +				sc_if->msk_cdata.msk_last_csum = csum;
    +			}
     		}
     	}
     
    @@ -3414,7 +3375,6 @@ msk_handle_events(struct msk_softc *sc)
     	/* Sync status LEs. */
     	bus_dmamap_sync(sc->msk_stat_tag, sc->msk_stat_map,
     	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
    -	/* XXX Sync Rx LEs here. */
     
     	rxput[MSK_PORT_A] = rxput[MSK_PORT_B] = 0;
     
    @@ -3424,13 +3384,6 @@ msk_handle_events(struct msk_softc *sc)
     		control = le32toh(sd->msk_control);
     		if ((control & HW_OWNER) == 0)
     			break;
    -		/*
    -		 * Marvell's FreeBSD driver updates status LE after clearing
    -		 * HW_OWNER. However we don't have a way to sync single LE
    -		 * with bus_dma(9) API. bus_dma(9) provides a way to sync
    -		 * an entire DMA map. So don't sync LE until we have a better
    -		 * way to sync LEs.
    -		 */
     		control &= ~HW_OWNER;
     		sd->msk_control = htole32(control);
     		status = le32toh(sd->msk_status);
    @@ -3491,7 +3444,8 @@ msk_handle_events(struct msk_softc *sc)
     	}
     
     	sc->msk_stat_cons = cons;
    -	/* XXX We should sync status LEs here. See above notes. */
    +	bus_dmamap_sync(sc->msk_stat_tag, sc->msk_stat_map,
    +	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
     
     	if (rxput[MSK_PORT_A] > 0)
     		msk_rxput(sc->msk_if[MSK_PORT_A]);
    @@ -3757,7 +3711,7 @@ msk_init_locked(struct msk_if_softc *sc_if)
     		CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL),
     		    GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON |
     		    GMC_BYP_RETR_ON);
    - 
    +
     	/*
     	 * Initialize GMAC first such that speed/duplex/flow-control
     	 * parameters are renegotiated when interface is brought up.
    @@ -3805,7 +3759,7 @@ msk_init_locked(struct msk_if_softc *sc_if)
     	    eaddr[2] | (eaddr[3] << 8));
     	GMAC_WRITE_2(sc, sc_if->msk_port, GM_SRC_ADDR_2H,
     	    eaddr[4] | (eaddr[5] << 8));
    -	
    +
     	/* Disable interrupts for counter overflows. */
     	GMAC_WRITE_2(sc, sc_if->msk_port, GM_TX_IRQ_MSK, 0);
     	GMAC_WRITE_2(sc, sc_if->msk_port, GM_RX_IRQ_MSK, 0);
    diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
    index 2f4e2164584..9e2adc359ee 100644
    --- a/sys/dev/msk/if_mskreg.h
    +++ b/sys/dev/msk/if_mskreg.h
    @@ -2361,6 +2361,7 @@ struct msk_chain_data {
     	bus_dmamap_t		msk_jumbo_rx_ring_map;
     	bus_dmamap_t		msk_jumbo_rx_sparemap;
     	uint16_t		msk_tso_mtu;
    +	uint32_t		msk_last_csum;
     	int			msk_tx_prod;
     	int			msk_tx_cons;
     	int			msk_tx_cnt;
    @@ -2467,14 +2468,16 @@ struct msk_hw_stats {
     struct msk_softc {
     	struct resource		*msk_res[1];	/* I/O resource */
     	struct resource_spec	*msk_res_spec;
    -	struct resource		*msk_irq[2];	/* IRQ resources */
    +	struct resource		*msk_irq[1];	/* IRQ resources */
     	struct resource_spec	*msk_irq_spec;
    -	void			*msk_intrhand[2]; /* irq handler handle */
    +	void			*msk_intrhand; /* irq handler handle */
     	device_t		msk_dev;
     	uint8_t			msk_hw_id;
     	uint8_t			msk_hw_rev;
     	uint8_t			msk_bustype;
     	uint8_t			msk_num_port;
    +	int			msk_expcap;
    +	int			msk_pcixcap;
     	int			msk_ramsize;	/* amount of SRAM on NIC */
     	uint32_t		msk_pmd;	/* physical media type */
     	uint32_t		msk_intrmask;
    
    From 2634815492c2453cfe0f288a99733110e00c0200 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 22:04:18 +0000
    Subject: [PATCH 1649/2592] MFC r204368,204370-204372: r204368:   Allow
     disabling VLAN hardware tag stripping with software work   around. Management
     firmware(ASF/IPMI/UMP) requires the VLAN   hardware tag stripping so don't
     actually disable VLAN hardware tag   stripping. If VLAN hardware tag
     stripping was disabled, bce(4)   manually reconstruct VLAN frame by appending
     stripped VLAN tag.   Also remove unnecessary IFCAP_VLAN_MTU message.
    
    r204370:
      Make sure to stop controller first before changing MTU. And if
      interface is not running don't initialize controller.
      While here remove unnecessary update of error variable.
    
    r204371:
      Make toggling TSO, VLAN hardware checksum offloading work. Also fix
      TX/RX checksum handler to set/clear relavant assist bits which was
      used to cause unexpected results.
      With this change, bce(4) can be bridged with other interfaces that
      lack TSO, VLAN checksum offloading.
    
    r204372:
      Prefer m_collapse(9) over m_defrag(9).
    ---
     sys/dev/bce/if_bce.c | 111 +++++++++++++++++++++++++++----------------
     1 file changed, 70 insertions(+), 41 deletions(-)
    
    diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
    index 94198e870c4..2decf2d2e98 100644
    --- a/sys/dev/bce/if_bce.c
    +++ b/sys/dev/bce/if_bce.c
    @@ -5886,6 +5886,7 @@ bce_rx_intr(struct bce_softc *sc)
     {
     	struct ifnet *ifp = sc->bce_ifp;
     	struct l2_fhdr *l2fhdr;
    +	struct ether_vlan_header *vh;
     	unsigned int pkt_len;
     	u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
     	u32 status;
    @@ -6141,12 +6142,37 @@ bce_rx_intr(struct bce_softc *sc)
     
     		/* Attach the VLAN tag.	*/
     		if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
    +			if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
     #if __FreeBSD_version < 700000
    -			VLAN_INPUT_TAG(ifp, m0, l2fhdr->l2_fhdr_vlan_tag, continue);
    +				VLAN_INPUT_TAG(ifp, m0,
    +				    l2fhdr->l2_fhdr_vlan_tag, continue);
     #else
    -			m0->m_pkthdr.ether_vtag = l2fhdr->l2_fhdr_vlan_tag;
    -			m0->m_flags |= M_VLANTAG;
    +				m0->m_pkthdr.ether_vtag =
    +				    l2fhdr->l2_fhdr_vlan_tag;
    +				m0->m_flags |= M_VLANTAG;
     #endif
    +			} else {
    +				/*
    +				 * bce(4) controllers can't disable VLAN
    +				 * tag stripping if management firmware
    +				 * (ASF/IPMI/UMP) is running. So we always
    +				 * strip VLAN tag and manually reconstruct
    +				 * the VLAN frame by appending stripped
    +				 * VLAN tag in driver if VLAN tag stripping
    +				 * was disabled.
    +				 *
    +				 * TODO: LLC SNAP handling.
    +				 */
    +				bcopy(mtod(m0, uint8_t *),
    +				    mtod(m0, uint8_t *) - ETHER_VLAN_ENCAP_LEN,
    +				    ETHER_ADDR_LEN * 2);
    +				m0->m_data -= ETHER_VLAN_ENCAP_LEN;
    +				vh = mtod(m0, struct ether_vlan_header *);
    +				vh->evl_encap_proto = htons(ETHERTYPE_VLAN);
    +				vh->evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
    +				m0->m_pkthdr.len += ETHER_VLAN_ENCAP_LEN;
    +				m0->m_len += ETHER_VLAN_ENCAP_LEN;
    +			}
     		}
     
     		/* Increment received packet statistics. */
    @@ -6687,7 +6713,7 @@ bce_tx_encap_skip_tso:
     		sc->fragmented_mbuf_count++;
     
     		/* Try to defrag the mbuf. */
    -		m0 = m_defrag(*m_head, M_DONTWAIT);
    +		m0 = m_collapse(*m_head, M_DONTWAIT, BCE_MAX_SEGMENTS);
     		if (m0 == NULL) {
     			/* Defrag was unsuccessful */
     			m_freem(*m_head);
    @@ -6963,7 +6989,7 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     	struct bce_softc *sc = ifp->if_softc;
     	struct ifreq *ifr = (struct ifreq *) data;
     	struct mii_data *mii;
    -	int mask, error = 0;
    +	int mask, error = 0, reinit;
     
     	DBENTER(BCE_VERBOSE_MISC);
     
    @@ -6984,7 +7010,16 @@ 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;
    +			reinit = 0;
    +			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    +				/*
    +				 * Because allocation size is used in RX
    +				 * buffer allocation, stop controller if
    +				 * it is already running.
    +				 */
    +				bce_stop(sc);
    +				reinit = 1;
    +			}
     #ifdef BCE_JUMBO_HDRSPLIT
     			/* No buffer allocation size changes are necessary. */
     #else
    @@ -7002,7 +7037,8 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			}
     #endif
     
    -			bce_init_locked(sc);
    +			if (reinit != 0)
    +				bce_init_locked(sc);
     			BCE_UNLOCK(sc);
     			break;
     
    @@ -7036,7 +7072,6 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			}
     
     			BCE_UNLOCK(sc);
    -			error = 0;
     
     			break;
     
    @@ -7046,10 +7081,8 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCADDMULTI/SIOCDELMULTI\n");
     
     			BCE_LOCK(sc);
    -			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    +			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
     				bce_set_rx_mode(sc);
    -				error = 0;
    -			}
     			BCE_UNLOCK(sc);
     
     			break;
    @@ -7069,50 +7102,46 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			mask = ifr->ifr_reqcap ^ ifp->if_capenable;
     			DBPRINT(sc, BCE_INFO_MISC, "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
     
    -			/* Toggle the TX checksum capabilites enable flag. */
    -			if (mask & IFCAP_TXCSUM) {
    +			/* Toggle the TX checksum capabilities enable flag. */
    +			if (mask & IFCAP_TXCSUM &&
    +			    ifp->if_capabilities & IFCAP_TXCSUM) {
     				ifp->if_capenable ^= IFCAP_TXCSUM;
     				if (IFCAP_TXCSUM & ifp->if_capenable)
    -					ifp->if_hwassist = BCE_IF_HWASSIST;
    +					ifp->if_hwassist |= BCE_IF_HWASSIST;
     				else
    -					ifp->if_hwassist = 0;
    +					ifp->if_hwassist &= ~BCE_IF_HWASSIST;
     			}
     
     			/* Toggle the RX checksum capabilities enable flag. */
    -			if (mask & IFCAP_RXCSUM) {
    +			if (mask & IFCAP_RXCSUM &&
    +			    ifp->if_capabilities & IFCAP_RXCSUM)
     				ifp->if_capenable ^= IFCAP_RXCSUM;
    -				if (IFCAP_RXCSUM & ifp->if_capenable)
    -					ifp->if_hwassist = BCE_IF_HWASSIST;
    -				else
    -					ifp->if_hwassist = 0;
    -			}
     
     			/* Toggle the TSO capabilities enable flag. */
    -			if (bce_tso_enable && (mask & IFCAP_TSO4)) {
    +			if (bce_tso_enable && (mask & IFCAP_TSO4) &&
    +			    ifp->if_capabilities & IFCAP_TSO4) {
     				ifp->if_capenable ^= IFCAP_TSO4;
    -				if (IFCAP_RXCSUM & ifp->if_capenable)
    -					ifp->if_hwassist = BCE_IF_HWASSIST;
    +				if (IFCAP_TSO4 & ifp->if_capenable)
    +					ifp->if_hwassist |= CSUM_TSO;
     				else
    -					ifp->if_hwassist = 0;
    +					ifp->if_hwassist &= ~CSUM_TSO;
     			}
     
    -			/* Toggle VLAN_MTU capabilities enable flag. */
    -			if (mask & IFCAP_VLAN_MTU) {
    -				BCE_PRINTF("%s(%d): Changing VLAN_MTU not supported.\n",
    -					__FILE__, __LINE__);
    -			}
    -
    -			/* Toggle VLANHWTAG capabilities enabled flag. */
    -			if (mask & IFCAP_VLAN_HWTAGGING) {
    -				if (sc->bce_flags & BCE_MFW_ENABLE_FLAG)
    -					BCE_PRINTF("%s(%d): Cannot change VLAN_HWTAGGING while "
    -						"management firmware (ASF/IPMI/UMP) is running!\n",
    -						__FILE__, __LINE__);
    -				else
    -					BCE_PRINTF("%s(%d): Changing VLAN_HWTAGGING not supported!\n",
    -						__FILE__, __LINE__);
    -			}
    +			if (mask & IFCAP_VLAN_HWCSUM &&
    +			    ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
    +				ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
     
    +			/*
    +			 * Don't actually disable VLAN tag stripping as
    +			 * management firmware (ASF/IPMI/UMP) requires the
    +			 * feature. If VLAN tag stripping is disabled driver
    +			 * will manually reconstruct the VLAN frame by
    +			 * appending stripped VLAN tag.
    +			 */
    +			if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    +			    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING))
    +				ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    +			VLAN_CAPABILITIES(ifp);
     			break;
     		default:
     			/* We don't know how to handle the IOCTL, pass it on. */
    
    From 051ea6ca198ec3ae9682cbc7403177df6a65c43d Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 22:11:39 +0000
    Subject: [PATCH 1650/2592] MFC r204373-204374: r204373:   Move TSO setup to
     new function bce_tso_setup(). Also remove VLAN   parsing code in TSO path as
     the controller requires VLAN hardware   tagging to make TSO work over VLANs. 
      While parsing the mbuf in TSO patch, always perform check for   writable
     mbuf as bce(4) have to reset IP length and IP checksum   field of IP header
     and make sure to ensure contiguous buffer before   accessing IP/TCP headers.
     While I'm here replace magic number 40 to   more readable sizeof(struct ip) +
     sizeof(struct tcphdr).
    
    r204374:
      Add TSO support on VLANs. bce(4) controllers require VLAN hardware
      tagging to make TSO work on VLANs so explicitly disable TSO on VLAN
      if VLAN hardware tagging is disabled.
    ---
     sys/dev/bce/if_bce.c | 195 +++++++++++++++++++++++++++----------------
     1 file changed, 124 insertions(+), 71 deletions(-)
    
    diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
    index 2decf2d2e98..8b6f2226a1f 100644
    --- a/sys/dev/bce/if_bce.c
    +++ b/sys/dev/bce/if_bce.c
    @@ -403,6 +403,7 @@ static void bce_fill_pg_chain		(struct bce_softc *);
     static void bce_free_pg_chain		(struct bce_softc *);
     #endif
     
    +static struct mbuf *bce_tso_setup	(struct bce_softc *, struct mbuf **, u16 *);
     static int  bce_tx_encap			(struct bce_softc *, struct mbuf **);
     static void bce_start_locked		(struct ifnet *);
     static void bce_start				(struct ifnet *);
    @@ -1057,7 +1058,8 @@ bce_attach(device_t dev)
     
     	if (bce_tso_enable) {
     		ifp->if_hwassist = BCE_IF_HWASSIST | CSUM_TSO;
    -		ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4;
    +		ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4 |
    +		    IFCAP_VLAN_HWTSO;
     	} else {
     		ifp->if_hwassist = BCE_IF_HWASSIST;
     		ifp->if_capabilities = BCE_IF_CAPABILITIES;
    @@ -6585,6 +6587,110 @@ bce_init(void *xsc)
     }
     
     
    +static struct mbuf *
    +bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
    +{
    +	struct mbuf *m;
    +	struct ether_header *eh;
    +	struct ip *ip;
    +	struct tcphdr *th;
    +	u16 etype;
    +	int hdr_len, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
    +
    +	DBRUN(sc->requested_tso_frames++);
    +	/* Controller requires to monify mbuf chains. */
    +	if (M_WRITABLE(*m_head) == 0) {
    +		m = m_dup(*m_head, M_DONTWAIT);
    +		m_freem(*m_head);
    +		if (m == NULL) {
    +			sc->mbuf_alloc_failed_count++;
    +			*m_head = NULL;
    +			return (NULL);
    +		}
    +		*m_head = m;
    +	}
    +	/*
    +	 * For TSO the controller needs two pieces of info,
    +	 * the MSS and the IP+TCP options length.
    +	 */
    +	m = m_pullup(*m_head, sizeof(struct ether_header) + sizeof(struct ip));
    +	if (m == NULL) {
    +		*m_head = NULL;
    +		return (NULL);
    +	}
    +	eh = mtod(m, struct ether_header *);
    +	etype = ntohs(eh->ether_type);
    +
    +	/* Check for supported TSO Ethernet types (only IPv4 for now) */
    +	switch (etype) {
    +	case ETHERTYPE_IP:
    +		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
    +		/* TSO only supported for TCP protocol. */
    +		if (ip->ip_p != IPPROTO_TCP) {
    +			BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
    +			    __FILE__, __LINE__);
    +			m_freem(*m_head);
    +			*m_head = NULL;
    +			return (NULL);
    +		}
    +
    +		/* Get IP header length in bytes (min 20) */
    +		ip_hlen = ip->ip_hl << 2;
    +		m = m_pullup(*m_head, sizeof(struct ether_header) + ip_hlen +
    +		    sizeof(struct tcphdr));
    +		if (m == NULL) {
    +			*m_head = NULL;
    +			return (NULL);
    +		}
    +
    +		/* Get the TCP header length in bytes (min 20) */
    +		th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
    +		tcp_hlen = (th->th_off << 2);
    +
    +		/* Make sure all IP/TCP options live in the same buffer. */
    +		m = m_pullup(*m_head,  sizeof(struct ether_header)+ ip_hlen +
    +		    tcp_hlen);
    +		if (m == NULL) {
    +			*m_head = NULL;
    +			return (NULL);
    +		}
    +
    +		/* IP header length and checksum will be calc'd by hardware */
    +		ip_len = ip->ip_len;
    +		ip->ip_len = 0;
    +		ip->ip_sum = 0;
    +		break;
    +	case ETHERTYPE_IPV6:
    +		BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
    +		    __FILE__, __LINE__);
    +		m_freem(*m_head);
    +		*m_head = NULL;
    +		return (NULL);
    +		/* NOT REACHED */
    +	default:
    +		BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
    +		    __FILE__, __LINE__);
    +		m_freem(*m_head);
    +		*m_head = NULL;
    +		return (NULL);
    +	}
    +
    +	hdr_len = sizeof(struct ether_header) + ip_hlen + tcp_hlen;
    +
    +	DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
    +	    "ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
    +	    __FUNCTION__, hdr_len, sizeof(struct ether_header), ip_hlen,
    +	    tcp_hlen, ip_len);
    +
    +	/* Set the LSO flag in the TX BD */
    +	*flags |= TX_BD_FLAGS_SW_LSO;
    +	/* Set the length of IP + TCP options (in 32 bit words) */
    +	*flags |= (((ip_hlen + tcp_hlen - sizeof(struct ip) -
    +	    sizeof(struct tcphdr)) >> 2) << 8);
    +	return (*m_head);
    +}
    +
    +
     /****************************************************************************/
     /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
     /* memory visible to the controller.                                        */
    @@ -6601,12 +6707,8 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
     	bus_dmamap_t map;
     	struct tx_bd *txbd = NULL;
     	struct mbuf *m0;
    -	struct ether_vlan_header *eh;
    -	struct ip *ip;
    -	struct tcphdr *th;
    -	u16 prod, chain_prod, etype, mss = 0, vlan_tag = 0, flags = 0;
    +	u16 prod, chain_prod, mss = 0, vlan_tag = 0, flags = 0;
     	u32 prod_bseq;
    -	int hdr_len = 0, e_hlen = 0, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
     
     #ifdef BCE_DEBUG
     	u16 debug_prod;
    @@ -6623,72 +6725,16 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
     	/* Transfer any checksum offload flags to the bd. */
     	m0 = *m_head;
     	if (m0->m_pkthdr.csum_flags) {
    -		if (m0->m_pkthdr.csum_flags & CSUM_IP)
    -			flags |= TX_BD_FLAGS_IP_CKSUM;
    -		if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
    -			flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
     		if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
    -			/* For TSO the controller needs two pieces of info, */
    -			/* the MSS and the IP+TCP options length.           */
    +			m0 = bce_tso_setup(sc, m_head, &flags);
    +			if (m0 == NULL)
    +				goto bce_tx_encap_exit;
     			mss = htole16(m0->m_pkthdr.tso_segsz);
    -
    -			/* Map the header and find the Ethernet type & header length */
    -			eh = mtod(m0, struct ether_vlan_header *);
    -			if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
    -				etype = ntohs(eh->evl_proto);
    -				e_hlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
    -			} else {
    -				etype = ntohs(eh->evl_encap_proto);
    -				e_hlen = ETHER_HDR_LEN;
    -			}
    -
    -			/* Check for supported TSO Ethernet types (only IPv4 for now) */
    -			switch (etype) {
    -				case ETHERTYPE_IP:
    -					ip = (struct ip *)(m0->m_data + e_hlen);
    -
    -					/* TSO only supported for TCP protocol */
    -					if (ip->ip_p != IPPROTO_TCP) {
    -						BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
    -							__FILE__, __LINE__);
    -						goto bce_tx_encap_skip_tso;
    -					}
    -
    -					/* Get IP header length in bytes (min 20) */
    -					ip_hlen = ip->ip_hl << 2;
    -
    -					/* Get the TCP header length in bytes (min 20) */
    -					th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
    -					tcp_hlen = (th->th_off << 2);
    -
    -					/* IP header length and checksum will be calc'd by hardware */
    -					ip_len = ip->ip_len;
    -					ip->ip_len = 0;
    -					ip->ip_sum = 0;
    -					break;
    -				case ETHERTYPE_IPV6:
    -					BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
    -						__FILE__, __LINE__);
    -					goto bce_tx_encap_skip_tso;
    -				default:
    -					BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
    -						__FILE__, __LINE__);
    -					goto bce_tx_encap_skip_tso;
    -			}
    -
    -			hdr_len = e_hlen + ip_hlen + tcp_hlen;
    -
    -			DBPRINT(sc, BCE_EXTREME_SEND,
    -				"%s(): hdr_len = %d, e_hlen = %d, ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
    -				 __FUNCTION__, hdr_len, e_hlen, ip_hlen, tcp_hlen, ip_len);
    -
    -			/* Set the LSO flag in the TX BD */
    -			flags |= TX_BD_FLAGS_SW_LSO;
    -			/* Set the length of IP + TCP options (in 32 bit words) */
    -			flags |= (((ip_hlen + tcp_hlen - 40) >> 2) << 8);
    -
    -bce_tx_encap_skip_tso:
    -			DBRUN(sc->requested_tso_frames++);
    +		} else {
    +			if (m0->m_pkthdr.csum_flags & CSUM_IP)
    +				flags |= TX_BD_FLAGS_IP_CKSUM;
    +			if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
    +				flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
     		}
     	}
     
    @@ -7131,6 +7177,9 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			    ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
     				ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
     
    +			if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
    +			    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
    +				ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
     			/*
     			 * Don't actually disable VLAN tag stripping as
     			 * management firmware (ASF/IPMI/UMP) requires the
    @@ -7139,8 +7188,12 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			 * appending stripped VLAN tag.
     			 */
     			if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    -			    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING))
    +			    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)) {
     				ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    +				if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
    +				    == 0)
    +					ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
    +			}
     			VLAN_CAPABILITIES(ifp);
     			break;
     		default:
    
    From 7b575694a1e80443c8495cd9448ea947f86a01ae Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 22:16:12 +0000
    Subject: [PATCH 1651/2592] MFC r204376:   Disable TSO on BCM5755M controller
     until I understand better for   the issue. I still have no idea why TSO does
     not work on this   controller. davidch@ also confirmed there is no known TSO
     related   issues for this controller.
    
    ---
     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 390222816ba..222de4decdf 100644
    --- a/sys/dev/bge/if_bge.c
    +++ b/sys/dev/bge/if_bge.c
    @@ -2656,9 +2656,11 @@ bge_attach(device_t dev)
     		/*
     		 * BCM5754 and BCM5787 shares the same ASIC id so
     		 * explicit device id check is required.
    +		 * Due to unknown reason TSO does not work on BCM5755M.
     		 */
     		if (pci_get_device(dev) != BCOM_DEVICEID_BCM5754 &&
    -		    pci_get_device(dev) != BCOM_DEVICEID_BCM5754M)
    +		    pci_get_device(dev) != BCOM_DEVICEID_BCM5754M &&
    +		    pci_get_device(dev) != BCOM_DEVICEID_BCM5755M)
     			sc->bge_flags |= BGE_FLAG_TSO;
     	}
     
    
    From 14b52a7e1c0f88356b86b953b6bddc3df90418c7 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 22:19:27 +0000
    Subject: [PATCH 1652/2592] MFC r204377:   Add TSO support on VLANs. While I'm
     here remove unnecessary check   of VLAN hardware checksum offloading. vlan(4)
     already takes care of   this.
    
    ---
     sys/dev/age/if_age.c | 31 +++++++++----------------------
     1 file changed, 9 insertions(+), 22 deletions(-)
    
    diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c
    index 01d68b2f064..3c5a1079774 100644
    --- a/sys/dev/age/if_age.c
    +++ b/sys/dev/age/if_age.c
    @@ -74,9 +74,6 @@ __FBSDID("$FreeBSD$");
     /* "device miibus" required.  See GENERIC if you get errors here. */
     #include "miibus_if.h"
     
    -#ifndef	IFCAP_VLAN_HWTSO
    -#define	IFCAP_VLAN_HWTSO	0
    -#endif
     #define	AGE_CSUM_FEATURES	(CSUM_TCP | CSUM_UDP)
     
     MODULE_DEPEND(age, pci, 1, 1, 1);
    @@ -633,8 +630,8 @@ age_attach(device_t dev)
     	ether_ifattach(ifp, sc->age_eaddr);
     
     	/* VLAN capability setup. */
    -	ifp->if_capabilities |= IFCAP_VLAN_MTU;
    -	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM;
    +	ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING |
    +	    IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWTSO;
     	ifp->if_capenable = ifp->if_capabilities;
     
     	/* Tell the upper layer(s) we support long frames. */
    @@ -1892,29 +1889,19 @@ age_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     		if ((mask & IFCAP_WOL_MAGIC) != 0 &&
     		    (ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0)
     			ifp->if_capenable ^= IFCAP_WOL_MAGIC;
    -
    -		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    -		    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) != 0) {
    -			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    -			age_rxvlan(sc);
    -		}
     		if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
     		    (ifp->if_capabilities & IFCAP_VLAN_HWCSUM) != 0)
     			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
     		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
     		    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
     			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
    -		/*
    -		 * VLAN hardware tagging is required to do checksum
    -		 * offload or TSO on VLAN interface. Checksum offload
    -		 * on VLAN interface also requires hardware assistance
    -		 * of parent interface.
    -		 */
    -		if ((ifp->if_capenable & IFCAP_TXCSUM) == 0)
    -			ifp->if_capenable &= ~IFCAP_VLAN_HWCSUM;
    -		if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
    -			ifp->if_capenable &=
    -			    ~(IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM);
    +		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) != 0) {
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    +			if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
    +				ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
    +			age_rxvlan(sc);
    +		}
     		AGE_UNLOCK(sc);
     		VLAN_CAPABILITIES(ifp);
     		break;
    
    From 065ee77712aa37504ee9d76c34f258b98b8b3c41 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Tue, 23 Mar 2010 22:22:26 +0000
    Subject: [PATCH 1653/2592] MFC r204378:   Add TSO support on VLANs. While I'm
     here remove unnecessary check   of VLAN hardware checksum offloading. vlan(4)
     already takes care of   this.
    
    ---
     sys/dev/ale/if_ale.c | 31 +++++++++----------------------
     1 file changed, 9 insertions(+), 22 deletions(-)
    
    diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c
    index 305eda4810a..76f1b74f2af 100644
    --- a/sys/dev/ale/if_ale.c
    +++ b/sys/dev/ale/if_ale.c
    @@ -78,9 +78,6 @@ __FBSDID("$FreeBSD$");
     
     /* For more information about Tx checksum offload issues see ale_encap(). */
     #define	ALE_CSUM_FEATURES	(CSUM_TCP | CSUM_UDP)
    -#ifndef	IFCAP_VLAN_HWTSO
    -#define	IFCAP_VLAN_HWTSO	0
    -#endif
     
     MODULE_DEPEND(ale, pci, 1, 1, 1);
     MODULE_DEPEND(ale, ether, 1, 1, 1);
    @@ -617,8 +614,8 @@ ale_attach(device_t dev)
     	ether_ifattach(ifp, sc->ale_eaddr);
     
     	/* VLAN capability setup. */
    -	ifp->if_capabilities |= IFCAP_VLAN_MTU;
    -	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM;
    +	ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING |
    +	    IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWTSO;
     	ifp->if_capenable = ifp->if_capabilities;
     	/*
     	 * Even though controllers supported by ale(3) have Rx checksum
    @@ -2003,29 +2000,19 @@ ale_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     		if ((mask & IFCAP_WOL_MAGIC) != 0 &&
     		    (ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0)
     			ifp->if_capenable ^= IFCAP_WOL_MAGIC;
    -
    -		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    -		    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) != 0) {
    -			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    -			ale_rxvlan(sc);
    -		}
     		if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
     		    (ifp->if_capabilities & IFCAP_VLAN_HWCSUM) != 0)
     			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
     		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
     		    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
     			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
    -		/*
    -		 * VLAN hardware tagging is required to do checksum
    -		 * offload or TSO on VLAN interface. Checksum offload
    -		 * on VLAN interface also requires hardware checksum
    -		 * offload of parent interface.
    -		 */
    -		if ((ifp->if_capenable & IFCAP_TXCSUM) == 0)
    -			ifp->if_capenable &= ~IFCAP_VLAN_HWCSUM;
    -		if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
    -			ifp->if_capenable &=
    -			    ~(IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM);
    +		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) != 0) {
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    +			if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
    +				ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
    +			ale_rxvlan(sc);
    +		}
     		ALE_UNLOCK(sc);
     		VLAN_CAPABILITIES(ifp);
     		break;
    
    From 135346b2c1c63b9ca049233b69b6fd1847d9b18e Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Tue, 23 Mar 2010 23:25:17 +0000
    Subject: [PATCH 1654/2592] MFC r205398: Do not create *.gmon files for PIE
     executables on i386.
    
    Scrt1_c.o was accidentally compiled with -DGCRT (profiling), like gcrt1_c.o.
    This problem is i386-specific, the other architectures are OK.
    
    If you have problems with PIE executables such as samba and cups leaving
    behind gmon files, rebuild them after installing this change.
    
    PR:		ports/143924
    ---
     lib/csu/i386-elf/Makefile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/lib/csu/i386-elf/Makefile b/lib/csu/i386-elf/Makefile
    index c2af118fe4f..45c162fba2b 100644
    --- a/lib/csu/i386-elf/Makefile
    +++ b/lib/csu/i386-elf/Makefile
    @@ -24,7 +24,7 @@ crt1.o:	crt1_c.o crt1_s.o
     	objcopy --localize-symbol _start1 crt1.o
     
     Scrt1_c.o:	crt1_c.c
    -	${CC} ${CFLAGS} -DGCRT -fPIC -DPIC -c -o Scrt1_c.o ${.CURDIR}/crt1_c.c
    +	${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1_c.o ${.CURDIR}/crt1_c.c
     
     Scrt1.o: Scrt1_c.o crt1_s.o
     	${LD} ${LDFLAGS} -o Scrt1.o -r crt1_s.o Scrt1_c.o
    
    From 3770189a658de2803e4a7a6ee1627b168cd2d989 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 09:27:12 +0000
    Subject: [PATCH 1655/2592] MFC r205416: Correct the type for uio_resid.
    
    ---
     share/man/man9/uio.9 | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/share/man/man9/uio.9 b/share/man/man9/uio.9
    index b23e9fdac60..b5c12cbe3bd 100644
    --- a/share/man/man9/uio.9
    +++ b/share/man/man9/uio.9
    @@ -25,7 +25,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd October 30, 2007
    +.Dd March 21, 2010
     .Os
     .Dt UIO 9
     .Sh NAME
    @@ -41,7 +41,7 @@ struct uio {
     	struct	iovec *uio_iov;		/* scatter/gather list */
     	int	uio_iovcnt;		/* length of scatter/gather list */
     	off_t	uio_offset;		/* offset in target object */
    -	int	uio_resid;		/* remaining bytes to copy */
    +	ssize_t	uio_resid;		/* remaining bytes to copy */
     	enum	uio_seg uio_segflg;	/* address space */
     	enum	uio_rw uio_rw;		/* operation */
     	struct	thread *uio_td;		/* owner */
    
    From 2dec7615c6f39f0a8d524db883b585726976fd04 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 09:45:17 +0000
    Subject: [PATCH 1656/2592] MFC r204957: Fall back to wbinvd when region for
     CLFLUSH is >= 2MB.
    
    MFC r205334 (by avg):
    Fix a typo in a comment.
    ---
     sys/amd64/amd64/pmap.c | 6 ++++--
     sys/i386/i386/pmap.c   | 6 ++++--
     2 files changed, 8 insertions(+), 4 deletions(-)
    
    diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
    index 7bb81ccfcae..0935506c7d7 100644
    --- a/sys/amd64/amd64/pmap.c
    +++ b/sys/amd64/amd64/pmap.c
    @@ -941,7 +941,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
     
     	if (cpu_feature & CPUID_SS)
     		; /* If "Self Snoop" is supported, do nothing. */
    -	else if (cpu_feature & CPUID_CLFSH) {
    +	else if ((cpu_feature & CPUID_CLFSH) != 0 &&
    +		 eva - sva < 2 * 1024 * 1024) {
     
     		/*
     		 * Otherwise, do per-cache line flush.  Use the mfence
    @@ -958,7 +959,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
     
     		/*
     		 * No targeted cache flush methods are supported by CPU,
    -		 * globally invalidate cache as a last resort.
    +		 * or the supplied range is bigger than 2MB.
    +		 * Globally invalidate cache.
     		 */
     		pmap_invalidate_cache();
     	}
    diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
    index c75491f10e5..06dd8f4d904 100644
    --- a/sys/i386/i386/pmap.c
    +++ b/sys/i386/i386/pmap.c
    @@ -982,7 +982,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
     
     	if (cpu_feature & CPUID_SS)
     		; /* If "Self Snoop" is supported, do nothing. */
    -	else if (cpu_feature & CPUID_CLFSH) {
    +	else if ((cpu_feature & CPUID_CLFSH) != 0 &&
    +		 eva - sva < 2 * 1024 * 1024) {
     
     		/*
     		 * Otherwise, do per-cache line flush.  Use the mfence
    @@ -999,7 +1000,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
     
     		/*
     		 * No targeted cache flush methods are supported by CPU,
    -		 * globally invalidate cache as a last resort.
    +		 * or the supplied range is bigger than 2MB.
    +		 * Globally invalidate cache.
     		 */
     		pmap_invalidate_cache();
     	}
    
    From be24350167f3bcef486c17adaf43809d9c6a2da9 Mon Sep 17 00:00:00 2001
    From: Ed Schouten 
    Date: Wed, 24 Mar 2010 12:11:59 +0000
    Subject: [PATCH 1657/2592] MFC r205296:
    
      Properly progress through the list of IPv6 addresses using in6_addr size.
    
      Right now if a jail has multiple IPv6 addresses, it will print them
      shifting only 4 bytes at a time. Example:
    
            2001:4dd0:ff41::b23f:a9
            2001:4dd0:ff41::b23f:aa
    
      Becomes:
    
            2001:4dd0:ff41::b23f:a9
            ff41::b23f:a9:2001:4dd0
    
      By casting to in6_addr, it uses the correct offsets.
    ---
     usr.sbin/jls/jls.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/usr.sbin/jls/jls.c b/usr.sbin/jls/jls.c
    index 3f4800cb5a4..a3a23b77936 100644
    --- a/usr.sbin/jls/jls.c
    +++ b/usr.sbin/jls/jls.c
    @@ -355,7 +355,7 @@ print_jail(int pflags, int jflags)
     			count = params[7].jp_valuelen / sizeof(struct in6_addr);
     			for (ai = 0; ai < count; ai++)
     				if (inet_ntop(AF_INET6,
    -				    &((struct in_addr *)params[7].jp_value)[ai],
    +				    &((struct in6_addr *)params[7].jp_value)[ai],
     				    ipbuf, sizeof(ipbuf)) == NULL)
     					err(1, "inet_ntop");
     				else
    
    From 63f82f9410f90a5cc8a37f81bf1f13ee2a45c75b Mon Sep 17 00:00:00 2001
    From: Ed Schouten 
    Date: Wed, 24 Mar 2010 12:14:59 +0000
    Subject: [PATCH 1658/2592] MFC r205329 and r205335:
    
      Don't add the atrun-line to the crontab when MK_AT is set.
    
      This prevents spurious calls to sendmail every 5 minutes.
    ---
     etc/Makefile | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/etc/Makefile b/etc/Makefile
    index e68df034bb5..23bc526da05 100644
    --- a/etc/Makefile
    +++ b/etc/Makefile
    @@ -157,6 +157,9 @@ distribution:
     		${BIN2} ${DESTDIR}/etc; \
     	    ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 600 \
     		master.passwd nsmb.conf opieaccess ${DESTDIR}/etc;
    +.if ${MK_AT} == "no"
    +	sed -i "" -e 's;.*/usr/libexec/atrun;#&;' ${DESTDIR}/etc/crontab
    +.endif
     .if ${MK_TCSH} == "no"
     	sed -i "" -e 's;/bin/csh;/bin/sh;' ${DESTDIR}/etc/master.passwd
     .endif
    
    From 99cb1f2430af0cd69ab4803519d5e3b153b0420d Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:08:01 +0000
    Subject: [PATCH 1659/2592] MFC r204465: Remove unused global statistic about
     fat cache usage.
    
    ---
     sys/fs/msdosfs/msdosfs_fat.c | 21 ---------------------
     1 file changed, 21 deletions(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c
    index 76d1527c5a4..9677a7a761c 100644
    --- a/sys/fs/msdosfs/msdosfs_fat.c
    +++ b/sys/fs/msdosfs/msdosfs_fat.c
    @@ -60,19 +60,6 @@
     #include 
     #include 
     
    -/*
    - * Fat cache stats.
    - */
    -static int fc_fileextends;	/* # of file extends			 */
    -static int fc_lfcempty;		/* # of time last file cluster cache entry
    -				 * was empty */
    -static int fc_bmapcalls;		/* # of times pcbmap was called		 */
    -
    -#define	LMMAX	20
    -static int fc_lmdistance[LMMAX];/* counters for how far off the last
    -				 * cluster mapped entry was. */
    -static int fc_largedistance;	/* off by more than LMMAX		 */
    -
     static int	chainalloc(struct msdosfsmount *pmp, u_long start,
     		    u_long count, u_long fillwith, u_long *retcluster,
     		    u_long *got);
    @@ -152,8 +139,6 @@ pcbmap(dep, findcn, bnp, cnp, sp)
     	struct msdosfsmount *pmp = dep->de_pmp;
     	u_long bsize;
     
    -	fc_bmapcalls++;
    -
     	/*
     	 * If they don't give us someplace to return a value then don't
     	 * bother doing anything.
    @@ -203,10 +188,6 @@ pcbmap(dep, findcn, bnp, cnp, sp)
     	 */
     	i = 0;
     	fc_lookup(dep, findcn, &i, &cn);
    -	if ((bn = findcn - i) >= LMMAX)
    -		fc_largedistance++;
    -	else
    -		fc_lmdistance[bn]++;
     
     	/*
     	 * Handle all other files or directories the normal way.
    @@ -992,10 +973,8 @@ extendfile(dep, count, bpp, ncp, flags)
     	 * If the "file's last cluster" cache entry is empty, and the file
     	 * is not empty, then fill the cache entry by calling pcbmap().
     	 */
    -	fc_fileextends++;
     	if (dep->de_fc[FC_LASTFC].fc_frcn == FCE_EMPTY &&
     	    dep->de_StartCluster != 0) {
    -		fc_lfcempty++;
     		error = pcbmap(dep, 0xffff, 0, &cn, 0);
     		/* we expect it to return E2BIG */
     		if (error != E2BIG)
    
    From 1a07617f97c1618dc7fda04b69d3f88235c719db Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:10:08 +0000
    Subject: [PATCH 1660/2592] MFC r204466: Assert that the msdosfs vnode is
     (e)locked in several places. Change the check and return on impossible
     condition into KASSERT().
    
    ---
     sys/fs/msdosfs/msdosfs_denode.c |  3 +--
     sys/fs/msdosfs/msdosfs_fat.c    | 13 +++++++------
     2 files changed, 8 insertions(+), 8 deletions(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c
    index b689b5d3ae0..0399a595e51 100644
    --- a/sys/fs/msdosfs/msdosfs_denode.c
    +++ b/sys/fs/msdosfs/msdosfs_denode.c
    @@ -167,9 +167,8 @@ deget(pmp, dirclust, diroffset, depp)
     	ldep->de_dirclust = dirclust;
     	ldep->de_diroffset = diroffset;
     	ldep->de_inode = inode;
    -	fc_purge(ldep, 0);	/* init the fat cache for this denode */
    -
     	lockmgr(nvp->v_vnlock, LK_EXCLUSIVE, NULL);
    +	fc_purge(ldep, 0);	/* init the fat cache for this denode */
     	error = insmntque(nvp, mntp);
     	if (error != 0) {
     		free(ldep, M_MSDOSFSNODE);
    diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c
    index 9677a7a761c..bb71d63ab06 100644
    --- a/sys/fs/msdosfs/msdosfs_fat.c
    +++ b/sys/fs/msdosfs/msdosfs_fat.c
    @@ -139,12 +139,9 @@ pcbmap(dep, findcn, bnp, cnp, sp)
     	struct msdosfsmount *pmp = dep->de_pmp;
     	u_long bsize;
     
    -	/*
    -	 * If they don't give us someplace to return a value then don't
    -	 * bother doing anything.
    -	 */
    -	if (bnp == NULL && cnp == NULL && sp == NULL)
    -		return (0);
    +	KASSERT(bnp != NULL || cnp != NULL || sp != NULL,
    +	    ("pcbmap: extra call"));
    +	ASSERT_VOP_ELOCKED(DETOV(dep), "pcbmap");
     
     	cn = dep->de_StartCluster;
     	/*
    @@ -270,6 +267,8 @@ fc_lookup(dep, findcn, frcnp, fsrcnp)
     	u_long cn;
     	struct fatcache *closest = 0;
     
    +	ASSERT_VOP_LOCKED(DETOV(dep), "fc_lookup");
    +
     	for (i = 0; i < FC_SIZE; i++) {
     		cn = dep->de_fc[i].fc_frcn;
     		if (cn != FCE_EMPTY && cn <= findcn) {
    @@ -295,6 +294,8 @@ fc_purge(dep, frcn)
     	int i;
     	struct fatcache *fcp;
     
    +	ASSERT_VOP_ELOCKED(DETOV(dep), "fc_purge");
    +
     	fcp = dep->de_fc;
     	for (i = 0; i < FC_SIZE; i++, fcp++) {
     		if (fcp->fc_frcn >= frcn)
    
    From b2c1c014b39fd5ac0ccb645360465a27f10befa2 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:13:27 +0000
    Subject: [PATCH 1661/2592] MFC r204467: Remove seemingly unneeded
     unlock/relock of the dvp in msdosfs_rmdir, causing LOR.
    
    ---
     sys/fs/msdosfs/msdosfs_vnops.c | 2 --
     1 file changed, 2 deletions(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
    index e232f49b4c0..b7b1e8ee804 100644
    --- a/sys/fs/msdosfs/msdosfs_vnops.c
    +++ b/sys/fs/msdosfs/msdosfs_vnops.c
    @@ -1468,14 +1468,12 @@ msdosfs_rmdir(ap)
     	 * the name cache.
     	 */
     	cache_purge(dvp);
    -	VOP_UNLOCK(dvp, 0);
     	/*
     	 * Truncate the directory that is being deleted.
     	 */
     	error = detrunc(ip, (u_long)0, IO_SYNC, cnp->cn_cred, td);
     	cache_purge(vp);
     
    -	vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
     out:
     	return (error);
     }
    
    From ac8743bcd3275cce74bfba84ee7068e565291030 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:15:46 +0000
    Subject: [PATCH 1662/2592] MFC r204468: In msdosfs_inactive(), reclaim the
     vnodes both for SLOT_DELETED and SLOT_EMPTY deName[0] values.
    
    ---
     sys/fs/msdosfs/msdosfs_denode.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c
    index 0399a595e51..ed24d492029 100644
    --- a/sys/fs/msdosfs/msdosfs_denode.c
    +++ b/sys/fs/msdosfs/msdosfs_denode.c
    @@ -593,7 +593,7 @@ msdosfs_inactive(ap)
     	/*
     	 * Ignore denodes related to stale file handles.
     	 */
    -	if (dep->de_Name[0] == SLOT_DELETED)
    +	if (dep->de_Name[0] == SLOT_DELETED || dep->de_Name[0] == SLOT_EMPTY)
     		goto out;
     
     	/*
    @@ -621,7 +621,7 @@ out:
     	printf("msdosfs_inactive(): v_usecount %d, de_Name[0] %x\n",
     	       vrefcnt(vp), dep->de_Name[0]);
     #endif
    -	if (dep->de_Name[0] == SLOT_DELETED)
    +	if (dep->de_Name[0] == SLOT_DELETED || dep->de_Name[0] == SLOT_EMPTY)
     		vrecycle(vp, td);
     	return (error);
     }
    
    From 670baf9dfe976e9b58b8e9631813e8a8d9c1a252 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:18:10 +0000
    Subject: [PATCH 1663/2592] MFC r204469: In msdosfs deget(), properly handle
     the case when the vnode is found in hash.
    
    ---
     sys/fs/msdosfs/msdosfs_denode.c | 5 ++---
     1 file changed, 2 insertions(+), 3 deletions(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c
    index ed24d492029..279ee9990d8 100644
    --- a/sys/fs/msdosfs/msdosfs_denode.c
    +++ b/sys/fs/msdosfs/msdosfs_denode.c
    @@ -182,9 +182,8 @@ deget(pmp, dirclust, diroffset, depp)
     		return (error);
     	}
     	if (xvp != NULL) {
    -		/* XXX: Not sure this is right */
    -		nvp = xvp;
    -		ldep->de_vnode = nvp;
    +		*depp = xvp->v_data;
    +		return (0);
     	}
     
     	ldep->de_pmp = pmp;
    
    From 3a141f45c544cdc621f89d79255e17ae2d2ca267 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:25:15 +0000
    Subject: [PATCH 1664/2592] MFC r204470: Add per-mountpoint lockmgr lock for
     msdosfs.
    
    MFC r204576:
    Only destroy pm_fatlock on error if it was initialized.
    ---
     sys/fs/msdosfs/msdosfs_vfsops.c |  6 ++++++
     sys/fs/msdosfs/msdosfsmount.h   | 14 +++++++++++++-
     2 files changed, 19 insertions(+), 1 deletion(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
    index 81867634e0d..ee8a54dd5e1 100644
    --- a/sys/fs/msdosfs/msdosfs_vfsops.c
    +++ b/sys/fs/msdosfs/msdosfs_vfsops.c
    @@ -75,6 +75,8 @@
     #include 
     #include 
     
    +static const char msdosfs_lock_msg[] = "fatlk";
    +
     /* Mount options that we support. */
     static const char *msdosfs_opts[] = {
     	"async", "noatime", "noclusterr", "noclusterw",
    @@ -466,6 +468,8 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
     	pmp->pm_cp = cp;
     	pmp->pm_bo = bo;
     
    +	lockinit(&pmp->pm_fatlock, 0, msdosfs_lock_msg, 0, 0);
    +
     	/*
     	 * Initialize ownerships and permissions, since nothing else will
     	 * initialize them iff we are mounting root.
    @@ -763,6 +767,7 @@ error_exit:
     		PICKUP_GIANT();
     	}
     	if (pmp) {
    +		lockdestroy(&pmp->pm_fatlock);
     		if (pmp->pm_inusemap)
     			free(pmp->pm_inusemap, M_MSDOSFSFAT);
     		free(pmp, M_MSDOSFSMNT);
    @@ -837,6 +842,7 @@ msdosfs_unmount(struct mount *mp, int mntflags)
     	free(pmp->pm_inusemap, M_MSDOSFSFAT);
     	if (pmp->pm_flags & MSDOSFS_LARGEFS)
     		msdosfs_fileno_free(mp);
    +	lockdestroy(&pmp->pm_fatlock);
     	free(pmp, M_MSDOSFSMNT);
     	mp->mnt_data = NULL;
     	MNT_ILOCK(mp);
    diff --git a/sys/fs/msdosfs/msdosfsmount.h b/sys/fs/msdosfs/msdosfsmount.h
    index bfe3ec3d1e5..2951b2c9f0b 100644
    --- a/sys/fs/msdosfs/msdosfsmount.h
    +++ b/sys/fs/msdosfs/msdosfsmount.h
    @@ -53,6 +53,9 @@
     
     #ifdef _KERNEL
     
    +#include 
    +#include 
    +#include 
     #include 
     
     #ifdef MALLOC_DECLARE
    @@ -106,7 +109,9 @@ struct msdosfsmount {
     	void *pm_u2d;	/* Unicode->DOS iconv handle */
     	void *pm_d2u;	/* DOS->Local iconv handle */
     	u_int32_t pm_nfileno;	/* next 32-bit fileno */
    -	RB_HEAD(msdosfs_filenotree, msdosfs_fileno) pm_filenos; /* 64<->32-bit fileno mapping */
    +	RB_HEAD(msdosfs_filenotree, msdosfs_fileno)
    +	    pm_filenos; /* 64<->32-bit fileno mapping */
    +	struct lock pm_fatlock;	/* lockmgr protecting allocations and rb tree */
     };
     
     /*
    @@ -215,6 +220,13 @@ void msdosfs_fileno_init(struct mount *);
     void msdosfs_fileno_free(struct mount *);
     uint32_t msdosfs_fileno_map(struct mount *, uint64_t);
     
    +#define	MSDOSFS_LOCK_MP(pmp) \
    +	lockmgr(&(pmp)->pm_fatlock, LK_EXCLUSIVE, NULL)
    +#define	MSDOSFS_UNLOCK_MP(pmp) \
    +	lockmgr(&(pmp)->pm_fatlock, LK_RELEASE, NULL)
    +#define	MSDOSFS_ASSERT_MP_LOCKED(pmp) \
    +	lockmgr_assert(&(pmp)->pm_fatlock, KA_XLOCKED)
    +
     #endif /* _KERNEL */
     
     /*
    
    From 05ecce0c28c82d296891e09de61a6b0628388ae2 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:37:17 +0000
    Subject: [PATCH 1665/2592] MFC r204471: Use pm_fatlock to protect fat bitmap.
    
    ---
     sys/fs/msdosfs/msdosfs_fat.c    | 45 +++++++++++++++++++++++++--------
     sys/fs/msdosfs/msdosfs_vfsops.c |  5 +++-
     2 files changed, 38 insertions(+), 12 deletions(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c
    index bb71d63ab06..02cb17ea45d 100644
    --- a/sys/fs/msdosfs/msdosfs_fat.c
    +++ b/sys/fs/msdosfs/msdosfs_fat.c
    @@ -77,6 +77,9 @@ static __inline void
     		usemap_alloc(struct msdosfsmount *pmp, u_long cn);
     static __inline void
     		usemap_free(struct msdosfsmount *pmp, u_long cn);
    +static int	clusteralloc1(struct msdosfsmount *pmp, u_long start,
    +		    u_long count, u_long fillwith, u_long *retcluster,
    +		    u_long *got);
     
     static void
     fatblock(pmp, ofs, bnp, sizep, bop)
    @@ -409,6 +412,7 @@ usemap_alloc(pmp, cn)
     	u_long cn;
     {
     
    +	MSDOSFS_ASSERT_MP_LOCKED(pmp);
     	pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS);
     	pmp->pm_freeclustercount--;
     }
    @@ -419,6 +423,7 @@ usemap_free(pmp, cn)
     	u_long cn;
     {
     
    +	MSDOSFS_ASSERT_MP_LOCKED(pmp);
     	pmp->pm_freeclustercount++;
     	pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS));
     }
    @@ -432,17 +437,17 @@ clusterfree(pmp, cluster, oldcnp)
     	int error;
     	u_long oldcn;
     
    -	usemap_free(pmp, cluster);
     	error = fatentry(FAT_GET_AND_SET, pmp, cluster, &oldcn, MSDOSFSFREE);
    -	if (error) {
    -		usemap_alloc(pmp, cluster);
    +	if (error)
     		return (error);
    -	}
     	/*
     	 * If the cluster was successfully marked free, then update
     	 * the count of free clusters, and turn off the "allocated"
     	 * bit in the "in use" cluster bit map.
     	 */
    +	MSDOSFS_LOCK_MP(pmp);
    +	usemap_free(pmp, cluster);
    +	MSDOSFS_UNLOCK_MP(pmp);
     	if (oldcnp)
     		*oldcnp = oldcn;
     	return (0);
    @@ -660,6 +665,8 @@ chainlength(pmp, start, count)
     	u_int map;
     	u_long len;
     
    +	MSDOSFS_ASSERT_MP_LOCKED(pmp);
    +
     	max_idx = pmp->pm_maxcluster / N_INUSEBITS;
     	idx = start / N_INUSEBITS;
     	start %= N_INUSEBITS;
    @@ -708,6 +715,8 @@ chainalloc(pmp, start, count, fillwith, retcluster, got)
     	int error;
     	u_long cl, n;
     
    +	MSDOSFS_ASSERT_MP_LOCKED(pmp);
    +
     	for (cl = start, n = count; n-- > 0;)
     		usemap_alloc(pmp, cl++);
     
    @@ -740,19 +749,28 @@ chainalloc(pmp, start, count, fillwith, retcluster, got)
      * got	      - how many clusters were actually allocated.
      */
     int
    -clusteralloc(pmp, start, count, fillwith, retcluster, got)
    -	struct msdosfsmount *pmp;
    -	u_long start;
    -	u_long count;
    -	u_long fillwith;
    -	u_long *retcluster;
    -	u_long *got;
    +clusteralloc(struct msdosfsmount *pmp, u_long start, u_long count,
    +    u_long fillwith, u_long *retcluster, u_long *got)
    +{
    +	int error;
    +
    +	MSDOSFS_LOCK_MP(pmp);
    +	error = clusteralloc1(pmp, start, count, fillwith, retcluster, got);
    +	MSDOSFS_UNLOCK_MP(pmp);
    +	return (error);
    +}
    +
    +static int
    +clusteralloc1(struct msdosfsmount *pmp, u_long start, u_long count,
    +    u_long fillwith, u_long *retcluster, u_long *got)
     {
     	u_long idx;
     	u_long len, newst, foundl, cn, l;
     	u_long foundcn = 0; /* XXX: foundcn could be used unititialized */
     	u_int map;
     
    +	MSDOSFS_ASSERT_MP_LOCKED(pmp);
    +
     #ifdef MSDOSFS_DEBUG
     	printf("clusteralloc(): find %lu clusters\n", count);
     #endif
    @@ -828,6 +846,7 @@ freeclusterchain(pmp, cluster)
     	u_long bn, bo, bsize, byteoffset;
     	u_long readcn, lbn = -1;
     
    +	MSDOSFS_LOCK_MP(pmp);
     	while (cluster >= CLUST_FIRST && cluster <= pmp->pm_maxcluster) {
     		byteoffset = FATOFS(pmp, cluster);
     		fatblock(pmp, byteoffset, &bn, &bsize, &bo);
    @@ -837,6 +856,7 @@ freeclusterchain(pmp, cluster)
     			error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
     			if (error) {
     				brelse(bp);
    +				MSDOSFS_UNLOCK_MP(pmp);
     				return (error);
     			}
     			lbn = bn;
    @@ -872,6 +892,7 @@ freeclusterchain(pmp, cluster)
     	}
     	if (bp)
     		updatefats(pmp, bp, bn);
    +	MSDOSFS_UNLOCK_MP(pmp);
     	return (0);
     }
     
    @@ -888,6 +909,8 @@ fillinusemap(pmp)
     	int error;
     	u_long bn, bo, bsize, byteoffset;
     
    +	MSDOSFS_ASSERT_MP_LOCKED(pmp);
    +
     	/*
     	 * Mark all clusters in use, we mark the free ones in the fat scan
     	 * loop further down.
    diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
    index ee8a54dd5e1..38198593107 100644
    --- a/sys/fs/msdosfs/msdosfs_vfsops.c
    +++ b/sys/fs/msdosfs/msdosfs_vfsops.c
    @@ -720,7 +720,10 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
     	/*
     	 * Have the inuse map filled in.
     	 */
    -	if ((error = fillinusemap(pmp)) != 0)
    +	MSDOSFS_LOCK_MP(pmp);
    +	error = fillinusemap(pmp);
    +	MSDOSFS_UNLOCK_MP(pmp);
    +	if (error != 0)
     		goto error_exit;
     
     	/*
    
    From 255ca65791a980c20b5d0289945b69eb96673bf9 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:43:19 +0000
    Subject: [PATCH 1666/2592] MFC r204472: Add assertions for FAT bitmap state.
    
    ---
     sys/fs/msdosfs/msdosfs_fat.c | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c
    index 02cb17ea45d..c857b342626 100644
    --- a/sys/fs/msdosfs/msdosfs_fat.c
    +++ b/sys/fs/msdosfs/msdosfs_fat.c
    @@ -413,7 +413,12 @@ usemap_alloc(pmp, cn)
     {
     
     	MSDOSFS_ASSERT_MP_LOCKED(pmp);
    +
    +	KASSERT((pmp->pm_inusemap[cn / N_INUSEBITS] & (1 << (cn % N_INUSEBITS)))
    +	    == 0, ("Allocating used sector %ld %ld %x", cn, cn % N_INUSEBITS,
    +		(unsigned)pmp->pm_inusemap[cn / N_INUSEBITS]));
     	pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS);
    +	KASSERT(pmp->pm_freeclustercount > 0, ("usemap_alloc: too little"));
     	pmp->pm_freeclustercount--;
     }
     
    @@ -425,6 +430,9 @@ usemap_free(pmp, cn)
     
     	MSDOSFS_ASSERT_MP_LOCKED(pmp);
     	pmp->pm_freeclustercount++;
    +	KASSERT((pmp->pm_inusemap[cn / N_INUSEBITS] & (1 << (cn % N_INUSEBITS)))
    +	    != 0, ("Freeing unused sector %ld %ld %x", cn, cn % N_INUSEBITS,
    +		(unsigned)pmp->pm_inusemap[cn / N_INUSEBITS]));
     	pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS));
     }
     
    
    From 7825951721c6dd911b3c2658096433c59c22bcc0 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:45:50 +0000
    Subject: [PATCH 1667/2592] MFC r204473: Use pm_fatlock to protect
     per-filesystem rb tree used to allocate fileno on the large FAT volumes.
    
    ---
     sys/fs/msdosfs/msdosfs_fileno.c | 16 ++++++----------
     1 file changed, 6 insertions(+), 10 deletions(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_fileno.c b/sys/fs/msdosfs/msdosfs_fileno.c
    index ff1f2b7d378..b56fb43874b 100644
    --- a/sys/fs/msdosfs/msdosfs_fileno.c
    +++ b/sys/fs/msdosfs/msdosfs_fileno.c
    @@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    -#include 
     
     #include 
     #include 
    @@ -59,9 +58,6 @@ __FBSDID("$FreeBSD$");
     
     static MALLOC_DEFINE(M_MSDOSFSFILENO, "msdosfs_fileno", "MSDOSFS fileno mapping node");
     
    -static struct mtx fileno_mtx;
    -MTX_SYSINIT(fileno, &fileno_mtx, "MSDOSFS fileno", MTX_DEF);
    -
     RB_PROTOTYPE(msdosfs_filenotree, msdosfs_fileno, mf_tree,
         msdosfs_fileno_compare)
     
    @@ -117,30 +113,30 @@ msdosfs_fileno_map(mp, fileno)
     	}
     	if (fileno < FILENO_FIRST_DYN)
     		return ((uint32_t)fileno);
    -	mtx_lock(&fileno_mtx);
    +	MSDOSFS_LOCK_MP(pmp);
     	key.mf_fileno64 = fileno;
     	mf = RB_FIND(msdosfs_filenotree, &pmp->pm_filenos, &key);
     	if (mf != NULL) {
     		mapped = mf->mf_fileno32;
    -		mtx_unlock(&fileno_mtx);
    +		MSDOSFS_UNLOCK_MP(pmp);
     		return (mapped);
     	}
     	if (pmp->pm_nfileno < FILENO_FIRST_DYN)
     		panic("msdosfs_fileno_map: wraparound");
    -	mtx_unlock(&fileno_mtx);
    +	MSDOSFS_UNLOCK_MP(pmp);
     	mf = malloc(sizeof(*mf), M_MSDOSFSFILENO, M_WAITOK);
    -	mtx_lock(&fileno_mtx);
    +	MSDOSFS_LOCK_MP(pmp);
     	tmf = RB_FIND(msdosfs_filenotree, &pmp->pm_filenos, &key);
     	if (tmf != NULL) {
     		mapped = tmf->mf_fileno32;
    -		mtx_unlock(&fileno_mtx);
    +		MSDOSFS_UNLOCK_MP(pmp);
     		free(mf, M_MSDOSFSFILENO);
     		return (mapped);
     	}
     	mf->mf_fileno64 = fileno;
     	mapped = mf->mf_fileno32 = pmp->pm_nfileno++;
     	RB_INSERT(msdosfs_filenotree, &pmp->pm_filenos, mf);
    -	mtx_unlock(&fileno_mtx);
    +	MSDOSFS_UNLOCK_MP(pmp);
     	return (mapped);
     }
     
    
    From a8428ad0f174fdad62b8013fc8ff678ecfca2e68 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:50:04 +0000
    Subject: [PATCH 1668/2592] MFC r204474: Fix the race between dotdot lookup and
     forced unmount, by using msdosfs-specific variant of vn_vget_ino(),
     msdosfs_deget_dotdot().
    
    As was done for UFS, relookup the dotdot denode after the call to
    msdosfs_deget_dotdot(), because vnode lock is dropped and directory
    might be moved.
    
    MFC r204675:
    When returning error from msdosfs_lookup(), make sure that *vpp is NULL.
    ---
     sys/fs/msdosfs/msdosfs_lookup.c | 109 +++++++++++++++++++++++++-------
     1 file changed, 85 insertions(+), 24 deletions(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
    index 8e0c3d5950b..999125d4eb8 100644
    --- a/sys/fs/msdosfs/msdosfs_lookup.c
    +++ b/sys/fs/msdosfs/msdosfs_lookup.c
    @@ -61,6 +61,18 @@
     #include 
     #include 
     
    +static int msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
    +    struct componentname *cnp, u_int64_t *inum);
    +static int msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff,
    +    struct vnode **rvp);
    +
    +int
    +msdosfs_lookup(struct vop_cachedlookup_args *ap)
    +{
    +
    +	return (msdosfs_lookup_(ap->a_dvp, ap->a_vpp, ap->a_cnp, NULL));
    +}
    +
     /*
      * When we search a directory the blocks containing directory entries are
      * read and examined.  The directory entries contain information that would
    @@ -76,18 +88,11 @@
      * out to disk.  This way disk blocks containing directory entries and in
      * memory denode's will be in synch.
      */
    -int
    -msdosfs_lookup(ap)
    -	struct vop_cachedlookup_args /* {
    -		struct vnode *a_dvp;
    -		struct vnode **a_vpp;
    -		struct componentname *a_cnp;
    -	} */ *ap;
    +static int
    +msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
    +    struct componentname *cnp, u_int64_t *dd_inum)
     {
     	struct mbnambuf nb;
    -	struct vnode *vdp = ap->a_dvp;
    -	struct vnode **vpp = ap->a_vpp;
    -	struct componentname *cnp = ap->a_cnp;
     	daddr_t bn;
     	int error;
     	int slotcount;
    @@ -109,6 +114,7 @@ msdosfs_lookup(ap)
     	int flags = cnp->cn_flags;
     	int nameiop = cnp->cn_nameiop;
     	int unlen;
    +	u_int64_t inode1;
     
     	int wincnt = 1;
     	int chksum = -1, chksum_ok;
    @@ -119,12 +125,14 @@ msdosfs_lookup(ap)
     #endif
     	dp = VTODE(vdp);
     	pmp = dp->de_pmp;
    -	*vpp = NULL;
     #ifdef MSDOSFS_DEBUG
     	printf("msdosfs_lookup(): vdp %p, dp %p, Attr %02x\n",
     	    vdp, dp, dp->de_Attributes);
     #endif
     
    + restart:
    +	if (vpp != NULL)
    +		*vpp = NULL;
     	/*
     	 * If they are going after the . or .. entry in the root directory,
     	 * they won't find it.  DOS filesystems don't have them in the root
    @@ -436,6 +444,11 @@ foundroot:
     	if (FAT32(pmp) && scn == MSDOSFSROOT)
     		scn = pmp->pm_rootdirblk;
     
    +	if (dd_inum != NULL) {
    +		*dd_inum = (uint64_t)pmp->pm_bpcluster * scn + blkoff;
    +		return (0);
    +	}
    +
     	/*
     	 * If deleting, and at end of pathname, return
     	 * parameters which can be used to remove file.
    @@ -508,23 +521,28 @@ foundroot:
     	 * inodes from the root, moving down the directory tree. Thus
     	 * when following backward pointers ".." we must unlock the
     	 * parent directory before getting the requested directory.
    -	 * There is a potential race condition here if both the current
    -	 * and parent directories are removed before the VFS_VGET for the
    -	 * inode associated with ".." returns.  We hope that this occurs
    -	 * infrequently since we cannot avoid this race condition without
    -	 * implementing a sophisticated deadlock detection algorithm.
    -	 * Note also that this simple deadlock detection scheme will not
    -	 * work if the filesystem has any hard links other than ".."
    -	 * that point backwards in the directory structure.
     	 */
     	pdp = vdp;
     	if (flags & ISDOTDOT) {
    -		VOP_UNLOCK(pdp, 0);
    -		error = deget(pmp, cluster, blkoff,  &tdp);
    -		vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY); 
    -		if (error)
    +		error = msdosfs_deget_dotdot(pdp, cluster, blkoff, vpp);
    +		if (error) {
    +			*vpp = NULL;
     			return (error);
    -		*vpp = DETOV(tdp);
    +		}
    +		/*
    +		 * Recheck that ".." still points to the inode we
    +		 * looked up before pdp lock was dropped.
    +		 */
    +		error = msdosfs_lookup_(pdp, NULL, cnp, &inode1);
    +		if (error) {
    +			vput(*vpp);
    +			*vpp = NULL;
    +			return (error);
    +		}
    +		if (VTODE(*vpp)->de_inode != inode1) {
    +			vput(*vpp);
    +			goto restart;
    +		}
     	} else if (dp->de_StartCluster == scn && isadir) {
     		VREF(vdp);	/* we want ourself, ie "." */
     		*vpp = vdp;
    @@ -542,6 +560,49 @@ foundroot:
     	return (0);
     }
     
    +static int
    +msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff,
    +    struct vnode **rvp)
    +{
    +	struct mount *mp;
    +	struct msdosfsmount *pmp;
    +	struct denode *rdp;
    +	int ltype, error;
    +
    +	mp = vp->v_mount;
    +	pmp = VFSTOMSDOSFS(mp);
    +	ltype = VOP_ISLOCKED(vp);
    +	KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED,
    +	    ("msdosfs_deget_dotdot: vp not locked"));
    +
    +	error = vfs_busy(mp, MBF_NOWAIT);
    +	if (error != 0) {
    +		vfs_ref(mp);
    +		VOP_UNLOCK(vp, 0);
    +		error = vfs_busy(mp, 0);
    +		vn_lock(vp, ltype | LK_RETRY);
    +		vfs_rel(mp);
    +		if (error != 0)
    +			return (ENOENT);
    +		if (vp->v_iflag & VI_DOOMED) {
    +			vfs_unbusy(mp);
    +			return (ENOENT);
    +		}
    +	}
    +	VOP_UNLOCK(vp, 0);
    +	error = deget(pmp, cluster, blkoff,  &rdp);
    +	vfs_unbusy(mp);
    +	if (error == 0)
    +		*rvp = DETOV(rdp);
    +	vn_lock(vp, ltype | LK_RETRY);
    +	if (vp->v_iflag & VI_DOOMED) {
    +		if (error == 0)
    +			vput(*rvp);
    +		error = ENOENT;
    +	}
    +	return (error);
    +}
    +
     /*
      * dep  - directory entry to copy into the directory
      * ddep - directory to add to
    
    From 3d9ee8abe26c3154b5152d454b77f0fa764191b9 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:53:28 +0000
    Subject: [PATCH 1669/2592] MFC r204589: Do not leak vnode lock when msdosfs
     mount is updated and specified device is different from the device used to
     the original mount.
    
    ---
     sys/fs/msdosfs/msdosfs_vfsops.c | 5 ++---
     1 file changed, 2 insertions(+), 3 deletions(-)
    
    diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
    index 38198593107..a7c31d7d6f7 100644
    --- a/sys/fs/msdosfs/msdosfs_vfsops.c
    +++ b/sys/fs/msdosfs/msdosfs_vfsops.c
    @@ -383,10 +383,9 @@ msdosfs_mount(struct mount *mp)
     		pmp = VFSTOMSDOSFS(mp);
     #endif
     	} else {
    +		vput(devvp);
     		if (devvp != pmp->pm_devvp)
    -			error = EINVAL;	/* XXX needs translation */
    -		else
    -			vput(devvp);
    +			return (EINVAL);	/* XXX needs translation */
     	}
     	if (error) {
     		vrele(devvp);
    
    From 9e211e57150138d0fcddf1773b25ae7f4cb4c910 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 24 Mar 2010 14:56:56 +0000
    Subject: [PATCH 1670/2592] MFC r204475: Mark msdosfs as mpsafe.
    
    ---
     sys/fs/msdosfs/msdosfs_vfsops.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
    index a7c31d7d6f7..77583eecd39 100644
    --- a/sys/fs/msdosfs/msdosfs_vfsops.c
    +++ b/sys/fs/msdosfs/msdosfs_vfsops.c
    @@ -751,6 +751,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
     	mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
     	MNT_ILOCK(mp);
     	mp->mnt_flag |= MNT_LOCAL;
    +	mp->mnt_kern_flag |= MNTK_MPSAFE;
     	MNT_IUNLOCK(mp);
     
     	if (pmp->pm_flags & MSDOSFS_LARGEFS)
    
    From 183fd3c950efaafb6509dd17724ff518728caab6 Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Wed, 24 Mar 2010 15:11:10 +0000
    Subject: [PATCH 1671/2592] MFC r200636, list all files needed to build the
     ipfw module
    
    Submitted by:	Alexander Wittig
    ---
     sys/modules/ipfw/Makefile | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sys/modules/ipfw/Makefile b/sys/modules/ipfw/Makefile
    index dd31d7e053f..b48d5c59882 100644
    --- a/sys/modules/ipfw/Makefile
    +++ b/sys/modules/ipfw/Makefile
    @@ -6,6 +6,8 @@
     
     KMOD=	ipfw
     SRCS=	ip_fw2.c ip_fw_pfil.c
    +SRCS+=	ip_fw_dynamic.c ip_fw_log.c ip_fw_nat.c
    +SRCS+=	ip_fw_sockopt.c ip_fw_table.c
     SRCS+=	opt_inet6.h opt_ipsec.h
     
     CFLAGS+= -DIPFIREWALL
    
    From 7da98b8ab6a64fba2fab60e556f6171ae31b03ba Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Wed, 24 Mar 2010 15:19:47 +0000
    Subject: [PATCH 1672/2592] MFC 205602: Honor ip.fw.one_pass when a packet
     comes out of a pipe without being delayed. I forgot to handle this case when
     i did the mtag cleanup three months ago.
    
    I am merging immediately because this bugfix is important for
    people using RELENG_8.
    
    PR:           145004
    ---
     sys/netinet/ipfw/ip_dn_io.c | 6 +++++-
     1 file changed, 5 insertions(+), 1 deletion(-)
    
    diff --git a/sys/netinet/ipfw/ip_dn_io.c b/sys/netinet/ipfw/ip_dn_io.c
    index 70f14ca65d7..ae168ce86b9 100644
    --- a/sys/netinet/ipfw/ip_dn_io.c
    +++ b/sys/netinet/ipfw/ip_dn_io.c
    @@ -762,7 +762,11 @@ dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa)
     	 *     
     	 */
     	if (/*dn_cfg.io_fast &&*/ m == *m0 && (dir & PROTO_LAYER2) == 0 ) {
    -		/* fast io */
    +		/* fast io, rename the tag * to carry reinject info. */
    +		struct m_tag *tag = m_tag_first(m);
    +
    +		tag->m_tag_cookie = MTAG_IPFW_RULE;
    +		tag->m_tag_id = 0;
     		io_pkt_fast++;
     		if (m->m_nextpkt != NULL) {
     			printf("dummynet: fast io: pkt chain detected!\n");
    
    From 51574f115239b066dd76f30907e5d7f0befe6d73 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Wed, 24 Mar 2010 17:11:01 +0000
    Subject: [PATCH 1673/2592] MFC r204541:   Implement rudimentary interrupt
     moderation with programmable   countdown timer register. The timer resolution
     may vary among   controllers but the value would be represented by core clock
       cycles. msk(4) will automatically computes number of required clock  
     cycles from given micro-seconds unit.   The default interrupt holdoff timer
     value is 100us which will   ensure less than 10k interrupts under load. The
     timer value can be   changed with dev.mskc.0.int_holdoff sysctl node.
    
      Note, the interrupt moderation is shared resource on dual-port
      controllers so you can't use separate interrupt moderation value
      for each port. This means we can't stop interrupt moderation in
      driver stop routine. Also have msk_tick() reclaim transmitted Tx
      buffers as safety belt. With this change there is no need to check
      missing Tx completion interrupt in watchdog handler, so remove it.
    ---
     sys/dev/msk/if_msk.c    | 40 ++++++++++++++++++++--------------------
     sys/dev/msk/if_mskreg.h |  3 +++
     2 files changed, 23 insertions(+), 20 deletions(-)
    
    diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
    index 06bacae0c81..968d0595884 100644
    --- a/sys/dev/msk/if_msk.c
    +++ b/sys/dev/msk/if_msk.c
    @@ -1661,6 +1661,14 @@ mskc_attach(device_t dev)
     		}
     	}
     
    +	sc->msk_int_holdoff = MSK_INT_HOLDOFF_DEFAULT;
    +	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    +	    "int_holdoff", CTLFLAG_RW, &sc->msk_int_holdoff, 0,
    +	    "Maximum number of time to delay interrupts");
    +	resource_int_value(device_get_name(dev), device_get_unit(dev),
    +	    "int_holdoff", &sc->msk_int_holdoff);
    +
     	/* Soft reset. */
     	CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
     	CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
    @@ -2803,8 +2811,6 @@ static void
     msk_watchdog(struct msk_if_softc *sc_if)
     {
     	struct ifnet *ifp;
    -	uint32_t ridx;
    -	int idx;
     
     	MSK_IF_LOCK_ASSERT(sc_if);
     
    @@ -2821,24 +2827,6 @@ msk_watchdog(struct msk_if_softc *sc_if)
     		return;
     	}
     
    -	/*
    -	 * Reclaim first as there is a possibility of losing Tx completion
    -	 * interrupts.
    -	 */
    -	ridx = sc_if->msk_port == MSK_PORT_A ? STAT_TXA1_RIDX : STAT_TXA2_RIDX;
    -	idx = CSR_READ_2(sc_if->msk_softc, ridx);
    -	if (sc_if->msk_cdata.msk_tx_cons != idx) {
    -		msk_txeof(sc_if, idx);
    -		if (sc_if->msk_cdata.msk_tx_cnt == 0) {
    -			if_printf(ifp, "watchdog timeout (missed Tx interrupts) "
    -			    "-- recovering\n");
    -			if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
    -				taskqueue_enqueue(taskqueue_fast,
    -				    &sc_if->msk_tx_task);
    -			return;
    -		}
    -	}
    -
     	if_printf(ifp, "watchdog timeout\n");
     	ifp->if_oerrors++;
     	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
    @@ -3168,6 +3156,7 @@ msk_tick(void *xsc_if)
     	mii_tick(mii);
     	if ((sc_if->msk_flags & MSK_FLAG_LINK) == 0)
     		msk_miibus_statchg(sc_if->msk_if_dev);
    +	msk_handle_events(sc_if->msk_softc);
     	msk_watchdog(sc_if);
     	callout_reset(&sc_if->msk_tick_ch, hz, msk_tick, sc_if);
     }
    @@ -3906,6 +3895,17 @@ msk_init_locked(struct msk_if_softc *sc_if)
     		sc->msk_intrmask |= Y2_IS_PORT_B;
     		sc->msk_intrhwemask |= Y2_HWE_L2_MASK;
     	}
    +	/* Configure IRQ moderation mask. */
    +	CSR_WRITE_4(sc, B2_IRQM_MSK, sc->msk_intrmask);
    +	if (sc->msk_int_holdoff > 0) {
    +		/* Configure initial IRQ moderation timer value. */
    +		CSR_WRITE_4(sc, B2_IRQM_INI,
    +		    MSK_USECS(sc, sc->msk_int_holdoff));
    +		CSR_WRITE_4(sc, B2_IRQM_VAL,
    +		    MSK_USECS(sc, sc->msk_int_holdoff));
    +		/* Start IRQ moderation. */
    +		CSR_WRITE_1(sc, B2_IRQM_CTRL, TIM_START);
    +	}
     	CSR_WRITE_4(sc, B0_HWE_IMSK, sc->msk_intrhwemask);
     	CSR_READ_4(sc, B0_HWE_IMSK);
     	CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask);
    diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
    index 9e2adc359ee..c773742454f 100644
    --- a/sys/dev/msk/if_mskreg.h
    +++ b/sys/dev/msk/if_mskreg.h
    @@ -2406,6 +2406,8 @@ struct msk_ring_data {
     #define	MSK_PROC_MIN		30
     #define	MSK_PROC_MAX		(MSK_RX_RING_CNT - 1)
     
    +#define	MSK_INT_HOLDOFF_DEFAULT	100
    +
     #define	MSK_TX_TIMEOUT		5
     #define	MSK_PUT_WM	10
     
    @@ -2496,6 +2498,7 @@ struct msk_softc {
     	bus_dmamap_t		msk_stat_map;
     	struct msk_stat_desc	*msk_stat_ring;
     	bus_addr_t		msk_stat_ring_paddr;
    +	int			msk_int_holdoff;
     	int			msk_process_limit;
     	int			msk_stat_cons;
     	struct taskqueue	*msk_tq;
    
    From 0f6d584c9bf14ec955cbb8a1e6995424a5af9b5d Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Wed, 24 Mar 2010 17:15:04 +0000
    Subject: [PATCH 1674/2592] MFC r204543:   Document newly added loader tunable
     and sysctl variable dev.mskc.%d.int_holdoff
    
    ---
     share/man/man4/msk.4 | 8 +++++++-
     1 file changed, 7 insertions(+), 1 deletion(-)
    
    diff --git a/share/man/man4/msk.4 b/share/man/man4/msk.4
    index f0991e996e7..7a842f5ecfd 100644
    --- a/share/man/man4/msk.4
    +++ b/share/man/man4/msk.4
    @@ -24,7 +24,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd November 6, 2009
    +.Dd March 1, 2010
     .Dt MSK 4
     .Os
     .Sh NAME
    @@ -235,6 +235,12 @@ variables and
     .Xr loader 8
     tunables:
     .Bl -tag -width indent
    +.It Va dev.mskc.%d.int_holdoff
    +Maximum number of time to delay interrupts.
    +The valid range is 0 to 34359738 for 125MHz clock in units of 1us,
    +the default is 100 (100us).
    +The interface need to be brought down and up again before a change
    +takes effect.
     .It Va dev.mskc.%d.process_limit
     Maximum amount of Rx events to be processed in the event loop before
     rescheduling a taskqueue.
    
    From 51e48a8ee4b9bc131841d5d7acedb7b661870f06 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Wed, 24 Mar 2010 17:18:44 +0000
    Subject: [PATCH 1675/2592] MFC r204545:   Remove taskqueue based interrupt
     handling. After r204541 msk(4)   does not generate excessive interrupts any
     more so we don't need   to have two copies of interrupt handler.   While I'm
     here remove two STAT_PUT_IDX register accesses in LE   status event handler.
     After r204539 msk(4) always sync status LEs   so there is no need to resort
     to reading STAT_PUT_IDX register to   know the end of status LE processing.
     Just trust status LE's   ownership bit.
    
    ---
     sys/dev/msk/if_msk.c    | 190 +++++++---------------------------------
     sys/dev/msk/if_mskreg.h |   3 -
     2 files changed, 32 insertions(+), 161 deletions(-)
    
    diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
    index 968d0595884..5d19f5f87d1 100644
    --- a/sys/dev/msk/if_msk.c
    +++ b/sys/dev/msk/if_msk.c
    @@ -113,7 +113,6 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    -#include 
     
     #include 
     #include 
    @@ -257,9 +256,7 @@ static int msk_attach(device_t);
     static int msk_detach(device_t);
     
     static void msk_tick(void *);
    -static void msk_legacy_intr(void *);
    -static int msk_intr(void *);
    -static void msk_int_task(void *, int);
    +static void msk_intr(void *);
     static void msk_intr_phy(struct msk_if_softc *);
     static void msk_intr_gmac(struct msk_if_softc *);
     static __inline void msk_rxput(struct msk_if_softc *);
    @@ -273,8 +270,8 @@ static void msk_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
     static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
     static void msk_txeof(struct msk_if_softc *, int);
     static int msk_encap(struct msk_if_softc *, struct mbuf **);
    -static void msk_tx_task(void *, int);
     static void msk_start(struct ifnet *);
    +static void msk_start_locked(struct ifnet *);
     static int msk_ioctl(struct ifnet *, u_long, caddr_t);
     static void msk_set_prefetch(struct msk_softc *, int, bus_addr_t, uint32_t);
     static void msk_set_rambuffer(struct msk_if_softc *);
    @@ -1513,9 +1510,6 @@ msk_attach(device_t dev)
     	IFQ_SET_MAXLEN(&ifp->if_snd, MSK_TX_RING_CNT - 1);
     	ifp->if_snd.ifq_drv_maxlen = MSK_TX_RING_CNT - 1;
     	IFQ_SET_READY(&ifp->if_snd);
    -
    -	TASK_INIT(&sc_if->msk_tx_task, 1, msk_tx_task, ifp);
    -
     	/*
     	 * Get station address for this interface. Note that
     	 * dual port cards actually come with three station
    @@ -1838,25 +1832,10 @@ mskc_attach(device_t dev)
     	}
     
     	/* Hook interrupt last to avoid having to lock softc. */
    -	if (legacy_intr)
    -		error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
    -		    INTR_MPSAFE, NULL, msk_legacy_intr, sc,
    -		    &sc->msk_intrhand);
    -	else {
    -		TASK_INIT(&sc->msk_int_task, 0, msk_int_task, sc);
    -		sc->msk_tq = taskqueue_create_fast("msk_taskq", M_WAITOK,
    -		    taskqueue_thread_enqueue, &sc->msk_tq);
    -		taskqueue_start_threads(&sc->msk_tq, 1, PI_NET, "%s taskq",
    -		    device_get_nameunit(sc->msk_dev));
    -		error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
    -		    INTR_MPSAFE, msk_intr, NULL, sc, &sc->msk_intrhand);
    -	}
    -
    +	error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
    +	    INTR_MPSAFE, NULL, msk_intr, sc, &sc->msk_intrhand);
     	if (error != 0) {
     		device_printf(dev, "couldn't set up interrupt handler\n");
    -		if (legacy_intr == 0)
    -			taskqueue_free(sc->msk_tq);
    -		sc->msk_tq = NULL;
     		goto fail;
     	}
     fail:
    @@ -1893,7 +1872,6 @@ msk_detach(device_t dev)
     		/* Can't hold locks while calling detach. */
     		MSK_IF_UNLOCK(sc_if);
     		callout_drain(&sc_if->msk_tick_ch);
    -		taskqueue_drain(taskqueue_fast, &sc_if->msk_tx_task);
     		ether_ifdetach(ifp);
     		MSK_IF_LOCK(sc_if);
     	}
    @@ -1958,11 +1936,6 @@ mskc_detach(device_t dev)
     
     	msk_status_dma_free(sc);
     
    -	if (legacy_intr == 0 && sc->msk_tq != NULL) {
    -		taskqueue_drain(sc->msk_tq, &sc->msk_int_task);
    -		taskqueue_free(sc->msk_tq);
    -		sc->msk_tq = NULL;
    -	}
     	if (sc->msk_intrhand) {
     		bus_teardown_intr(dev, sc->msk_irq[0], sc->msk_intrhand);
     		sc->msk_intrhand = NULL;
    @@ -2742,30 +2715,29 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
     }
     
     static void
    -msk_tx_task(void *arg, int pending)
    +msk_start(struct ifnet *ifp)
     {
    -	struct ifnet *ifp;
    +	struct msk_if_softc *sc_if;
     
    -	ifp = arg;
    -	msk_start(ifp);
    +	sc_if = ifp->if_softc;
    +	MSK_IF_LOCK(sc_if);
    +	msk_start_locked(ifp);
    +	MSK_IF_UNLOCK(sc_if);
     }
     
     static void
    -msk_start(struct ifnet *ifp)
    +msk_start_locked(struct ifnet *ifp)
     {
    -        struct msk_if_softc *sc_if;
    -        struct mbuf *m_head;
    +	struct msk_if_softc *sc_if;
    +	struct mbuf *m_head;
     	int enq;
     
     	sc_if = ifp->if_softc;
    -
    -	MSK_IF_LOCK(sc_if);
    +	MSK_IF_LOCK_ASSERT(sc_if);
     
     	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
    -	    IFF_DRV_RUNNING || (sc_if->msk_flags & MSK_FLAG_LINK) == 0) {
    -		MSK_IF_UNLOCK(sc_if);
    +	    IFF_DRV_RUNNING || (sc_if->msk_flags & MSK_FLAG_LINK) == 0)
     		return;
    -	}
     
     	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
     	    sc_if->msk_cdata.msk_tx_cnt <
    @@ -2803,8 +2775,6 @@ msk_start(struct ifnet *ifp)
     		/* Set a timeout in case the chip goes out to lunch. */
     		sc_if->msk_watchdog_timer = MSK_TX_TIMEOUT;
     	}
    -
    -	MSK_IF_UNLOCK(sc_if);
     }
     
     static void
    @@ -2832,7 +2802,7 @@ msk_watchdog(struct msk_if_softc *sc_if)
     	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
     	msk_init_locked(sc_if);
     	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
    -		taskqueue_enqueue(taskqueue_fast, &sc_if->msk_tx_task);
    +		msk_start_locked(ifp);
     }
     
     static int
    @@ -3355,20 +3325,16 @@ msk_handle_events(struct msk_softc *sc)
     	int rxput[2];
     	struct msk_stat_desc *sd;
     	uint32_t control, status;
    -	int cons, idx, len, port, rxprog;
    -
    -	idx = CSR_READ_2(sc, STAT_PUT_IDX);
    -	if (idx == sc->msk_stat_cons)
    -		return (0);
    +	int cons, len, port, rxprog;
     
     	/* Sync status LEs. */
     	bus_dmamap_sync(sc->msk_stat_tag, sc->msk_stat_map,
     	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
     
     	rxput[MSK_PORT_A] = rxput[MSK_PORT_B] = 0;
    -
     	rxprog = 0;
    -	for (cons = sc->msk_stat_cons; cons != idx;) {
    +	cons = sc->msk_stat_cons;
    +	for (;;) {
     		sd = &sc->msk_stat_ring[cons];
     		control = le32toh(sd->msk_control);
     		if ((control & HW_OWNER) == 0)
    @@ -3441,17 +3407,17 @@ msk_handle_events(struct msk_softc *sc)
     	if (rxput[MSK_PORT_B] > 0)
     		msk_rxput(sc->msk_if[MSK_PORT_B]);
     
    -	return (sc->msk_stat_cons != CSR_READ_2(sc, STAT_PUT_IDX));
    +	return (rxprog > sc->msk_process_limit ? EAGAIN : 0);
     }
     
    -/* Legacy interrupt handler for shared interrupt. */
     static void
    -msk_legacy_intr(void *xsc)
    +msk_intr(void *xsc)
     {
     	struct msk_softc *sc;
     	struct msk_if_softc *sc_if0, *sc_if1;
     	struct ifnet *ifp0, *ifp1;
     	uint32_t status;
    +	int domore;
     
     	sc = xsc;
     	MSK_LOCK(sc);
    @@ -3465,92 +3431,6 @@ msk_legacy_intr(void *xsc)
     		return;
     	}
     
    -	sc_if0 = sc->msk_if[MSK_PORT_A];
    -	sc_if1 = sc->msk_if[MSK_PORT_B];
    -	ifp0 = ifp1 = NULL;
    -	if (sc_if0 != NULL)
    -		ifp0 = sc_if0->msk_ifp;
    -	if (sc_if1 != NULL)
    -		ifp1 = sc_if1->msk_ifp;
    -
    -	if ((status & Y2_IS_IRQ_PHY1) != 0 && sc_if0 != NULL)
    -		msk_intr_phy(sc_if0);
    -	if ((status & Y2_IS_IRQ_PHY2) != 0 && sc_if1 != NULL)
    -		msk_intr_phy(sc_if1);
    -	if ((status & Y2_IS_IRQ_MAC1) != 0 && sc_if0 != NULL)
    -		msk_intr_gmac(sc_if0);
    -	if ((status & Y2_IS_IRQ_MAC2) != 0 && sc_if1 != NULL)
    -		msk_intr_gmac(sc_if1);
    -	if ((status & (Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2)) != 0) {
    -		device_printf(sc->msk_dev, "Rx descriptor error\n");
    -		sc->msk_intrmask &= ~(Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2);
    -		CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask);
    -		CSR_READ_4(sc, B0_IMSK);
    -	}
    -        if ((status & (Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXA2)) != 0) {
    -		device_printf(sc->msk_dev, "Tx descriptor error\n");
    -		sc->msk_intrmask &= ~(Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXA2);
    -		CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask);
    -		CSR_READ_4(sc, B0_IMSK);
    -	}
    -	if ((status & Y2_IS_HW_ERR) != 0)
    -		msk_intr_hwerr(sc);
    -
    -	while (msk_handle_events(sc) != 0)
    -		;
    -	if ((status & Y2_IS_STAT_BMU) != 0)
    -		CSR_WRITE_4(sc, STAT_CTRL, SC_STAT_CLR_IRQ);
    -
    -	/* Reenable interrupts. */
    -	CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2);
    -
    -	if (ifp0 != NULL && (ifp0->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
    -	    !IFQ_DRV_IS_EMPTY(&ifp0->if_snd))
    -		taskqueue_enqueue(taskqueue_fast, &sc_if0->msk_tx_task);
    -	if (ifp1 != NULL && (ifp1->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
    -	    !IFQ_DRV_IS_EMPTY(&ifp1->if_snd))
    -		taskqueue_enqueue(taskqueue_fast, &sc_if1->msk_tx_task);
    -
    -	MSK_UNLOCK(sc);
    -}
    -
    -static int
    -msk_intr(void *xsc)
    -{
    -	struct msk_softc *sc;
    -	uint32_t status;
    -
    -	sc = xsc;
    -	status = CSR_READ_4(sc, B0_Y2_SP_ISRC2);
    -	/* Reading B0_Y2_SP_ISRC2 masks further interrupts. */
    -	if (status == 0 || status == 0xffffffff) {
    -		CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2);
    -		return (FILTER_STRAY);
    -	}
    -
    -	taskqueue_enqueue(sc->msk_tq, &sc->msk_int_task);
    -	return (FILTER_HANDLED);
    -}
    -
    -static void
    -msk_int_task(void *arg, int pending)
    -{
    -	struct msk_softc *sc;
    -	struct msk_if_softc *sc_if0, *sc_if1;
    -	struct ifnet *ifp0, *ifp1;
    -	uint32_t status;
    -	int domore;
    -
    -	sc = arg;
    -	MSK_LOCK(sc);
    -
    -	/* Get interrupt source. */
    -	status = CSR_READ_4(sc, B0_ISRC);
    -	if (status == 0 || status == 0xffffffff ||
    -	    (sc->msk_pflags & MSK_FLAG_SUSPEND) != 0 ||
    -	    (status & sc->msk_intrmask) == 0)
    -		goto done;
    -
     	sc_if0 = sc->msk_if[MSK_PORT_A];
     	sc_if1 = sc->msk_if[MSK_PORT_B];
     	ifp0 = ifp1 = NULL;
    @@ -3583,26 +3463,20 @@ msk_int_task(void *arg, int pending)
     		msk_intr_hwerr(sc);
     
     	domore = msk_handle_events(sc);
    -	if ((status & Y2_IS_STAT_BMU) != 0)
    +	if ((status & Y2_IS_STAT_BMU) != 0 && domore == 0)
     		CSR_WRITE_4(sc, STAT_CTRL, SC_STAT_CLR_IRQ);
     
    -	if (ifp0 != NULL && (ifp0->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
    -	    !IFQ_DRV_IS_EMPTY(&ifp0->if_snd))
    -		taskqueue_enqueue(taskqueue_fast, &sc_if0->msk_tx_task);
    -	if (ifp1 != NULL && (ifp1->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
    -	    !IFQ_DRV_IS_EMPTY(&ifp1->if_snd))
    -		taskqueue_enqueue(taskqueue_fast, &sc_if1->msk_tx_task);
    -
    -	if (domore > 0) {
    -		taskqueue_enqueue(sc->msk_tq, &sc->msk_int_task);
    -		MSK_UNLOCK(sc);
    -		return;
    -	}
    -done:
    -	MSK_UNLOCK(sc);
    -
     	/* Reenable interrupts. */
     	CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2);
    +
    +	if (ifp0 != NULL && (ifp0->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
    +	    !IFQ_DRV_IS_EMPTY(&ifp0->if_snd))
    +		msk_start_locked(ifp0);
    +	if (ifp1 != NULL && (ifp1->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
    +	    !IFQ_DRV_IS_EMPTY(&ifp1->if_snd))
    +		msk_start_locked(ifp1);
    +
    +	MSK_UNLOCK(sc);
     }
     
     static void
    diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
    index c773742454f..9c18ba71986 100644
    --- a/sys/dev/msk/if_mskreg.h
    +++ b/sys/dev/msk/if_mskreg.h
    @@ -2501,8 +2501,6 @@ struct msk_softc {
     	int			msk_int_holdoff;
     	int			msk_process_limit;
     	int			msk_stat_cons;
    -	struct taskqueue	*msk_tq;
    -	struct task		msk_int_task;
     	struct mtx		msk_mtx;
     };
     
    @@ -2547,7 +2545,6 @@ struct msk_if_softc {
     	struct msk_ring_data	msk_rdata;
     	struct msk_softc	*msk_softc;	/* parent controller */
     	struct msk_hw_stats	msk_stats;
    -	struct task		msk_tx_task;
     	int			msk_if_flags;
     	uint16_t		msk_vtag;	/* VLAN tag id. */
     };
    
    From f305cd92af559a18988abb5a9fb4ccdeb7a5278b Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Wed, 24 Mar 2010 17:29:32 +0000
    Subject: [PATCH 1676/2592] MFC r204975,204978-204979,204981: r204975:   Enable
     hardware fixes for BCM5704 B0 as recommended by data sheet. r204978:   Set
     maximum read byte count to 2048 for PCI-X BCM5703/5704 devices.   Also
     disable relaxed ordering as recommended by data sheet for   PCI-X devices.
     For PCI-X BCM5704, set maximum outstanding split   transactions to 0 as
     indicated by data sheet.   For BCM5703 in PCI-X mode, DMA read watermark
     should be less than   or equal to maximum read byte count configuration.
     Enforce this   limitation in DMA read watermark configuration. r204979:   Fix
     typo in r204975. r204981:   Fix typo in r204978.
    
    ---
     sys/dev/bge/if_bge.c | 42 +++++++++++++++++++++++++++++++++++++++++-
     1 file changed, 41 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
    index 222de4decdf..6748c1c61b5 100644
    --- a/sys/dev/bge/if_bge.c
    +++ b/sys/dev/bge/if_bge.c
    @@ -1342,6 +1342,7 @@ static int
     bge_chipinit(struct bge_softc *sc)
     {
     	uint32_t dma_rw_ctl;
    +	uint16_t val;
     	int i;
     
     	/* Set endianness before we access any non-PCI registers. */
    @@ -1362,6 +1363,17 @@ bge_chipinit(struct bge_softc *sc)
     	    i < BGE_STATUS_BLOCK_END + 1; i += sizeof(uint32_t))
     		BGE_MEMWIN_WRITE(sc, i, 0);
     
    +	if (sc->bge_chiprev == BGE_CHIPREV_5704_BX) {
    +		/*
    +		 *  Fix data corruption caused by non-qword write with WB.
    +		 *  Fix master abort in PCI mode.
    +		 *  Fix PCI latency timer.
    +		 */
    +		val = pci_read_config(sc->bge_dev, BGE_PCI_MSI_DATA + 2, 2);
    +		val |= (1 << 10) | (1 << 12) | (1 << 13);
    +		pci_write_config(sc->bge_dev, BGE_PCI_MSI_DATA + 2, val, 2);
    +	}
    +
     	/*
     	 * Set up the PCI DMA control register.
     	 */
    @@ -1378,6 +1390,15 @@ bge_chipinit(struct bge_softc *sc)
     			dma_rw_ctl |= (sc->bge_asicrev == BGE_ASICREV_BCM5780) ?
     			    BGE_PCIDMARWCTL_ONEDMA_ATONCE_GLOBAL :
     			    BGE_PCIDMARWCTL_ONEDMA_ATONCE_LOCAL;
    +		} else if (sc->bge_asicrev == BGE_ASICREV_BCM5703) {
    +			/*
    +			 * In the BCM5703, the DMA read watermark should
    +			 * be set to less than or equal to the maximum
    +			 * memory read byte count of the PCI-X command
    +			 * register.
    +			 */
    +			dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(4) |
    +			    BGE_PCIDMARWCTL_WR_WAT_SHIFT(3);
     		} else if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
     			/* 1536 bytes for read, 384 bytes for write. */
     			dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(7) |
    @@ -3158,7 +3179,26 @@ bge_reset(struct bge_softc *sc)
     	pci_write_config(dev, BGE_PCI_CACHESZ, cachesize, 4);
     	pci_write_config(dev, BGE_PCI_CMD, command, 4);
     	write_op(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ);
    -
    +	/*
    +	 * Disable PCI-X relaxed ordering to ensure status block update
    +	 * comes first then packet buffer DMA. Otherwise driver may
    +	 * read stale status block.
    +	 */
    +	if (sc->bge_flags & BGE_FLAG_PCIX) {
    +		devctl = pci_read_config(dev,
    +		    sc->bge_pcixcap + PCIXR_COMMAND, 2);
    +		devctl &= ~PCIXM_COMMAND_ERO;
    +		if (sc->bge_asicrev == BGE_ASICREV_BCM5703) {
    +			devctl &= ~PCIXM_COMMAND_MAX_READ;
    +			devctl |= PCIXM_COMMAND_MAX_READ_2048;
    +		} else if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
    +			devctl &= ~(PCIXM_COMMAND_MAX_SPLITS |
    +			    PCIXM_COMMAND_MAX_READ);
    +			devctl |= PCIXM_COMMAND_MAX_READ_2048;
    +		}
    +		pci_write_config(dev, sc->bge_pcixcap + PCIXR_COMMAND,
    +		    devctl, 2);
    +	}
     	/* Re-enable MSI, if neccesary, and enable the memory arbiter. */
     	if (BGE_IS_5714_FAMILY(sc)) {
     		/* This chip disables MSI on reset. */
    
    From 5c55bc1bf18809d2f6e0ea47e7faab8c9b36bdb7 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Wed, 24 Mar 2010 17:36:56 +0000
    Subject: [PATCH 1677/2592] MFC r205161:   It seems PCI_OUR_REG_[1-5] registers
     are not mapped on PCI   configuration space on Yukon Ultra(88E8056) such that
     accesses to   these registers were NOPs which in turn make msk(4) instable on
       this controller. Use indirect access method to access   PCI_OUR_REG_[1-5]
     registers. This should fix a long standing   instability bug which prevented
     msk(4) working on Yukon Ultra.   Special thanks to koitsu who gave me remote
     access to his system.
    
      PR:	kern/114631, kern/116853
    ---
     sys/dev/msk/if_msk.c | 20 ++++++++++----------
     1 file changed, 10 insertions(+), 10 deletions(-)
    
    diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
    index 5d19f5f87d1..9f97a87ecf3 100644
    --- a/sys/dev/msk/if_msk.c
    +++ b/sys/dev/msk/if_msk.c
    @@ -1125,7 +1125,7 @@ msk_phy_power(struct msk_softc *sc, int mode)
     		 */
     		CSR_WRITE_1(sc, B2_Y2_CLK_GATE, val);
     
    -		val = pci_read_config(sc->msk_dev, PCI_OUR_REG_1, 4);
    +		val = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
     		val &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
     		if (sc->msk_hw_id == CHIP_ID_YUKON_XL) {
     			if (sc->msk_hw_rev > CHIP_REV_YU_XL_A1) {
    @@ -1136,7 +1136,7 @@ msk_phy_power(struct msk_softc *sc, int mode)
     			}
     		}
     		/* Release PHY from PowerDown/COMA mode. */
    -		pci_write_config(sc->msk_dev, PCI_OUR_REG_1, val, 4);
    +		CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, val);
     		switch (sc->msk_hw_id) {
     		case CHIP_ID_YUKON_EC_U:
     		case CHIP_ID_YUKON_EX:
    @@ -1145,16 +1145,16 @@ msk_phy_power(struct msk_softc *sc, int mode)
     			CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF);
     
     			/* Enable all clocks. */
    -			pci_write_config(sc->msk_dev, PCI_OUR_REG_3, 0, 4);
    -			our = pci_read_config(sc->msk_dev, PCI_OUR_REG_4, 4);
    +			CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
    +			our = CSR_PCI_READ_4(sc, PCI_OUR_REG_4);
     			our &= (PCI_FORCE_ASPM_REQUEST|PCI_ASPM_GPHY_LINK_DOWN|
     			    PCI_ASPM_INT_FIFO_EMPTY|PCI_ASPM_CLKRUN_REQUEST);
     			/* Set all bits to 0 except bits 15..12. */
    -			pci_write_config(sc->msk_dev, PCI_OUR_REG_4, our, 4);
    -			our = pci_read_config(sc->msk_dev, PCI_OUR_REG_5, 4);
    +			CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, our);
    +			our = CSR_PCI_READ_4(sc, PCI_OUR_REG_5);
     			our &= PCI_CTL_TIM_VMAIN_AV_MSK;
    -			pci_write_config(sc->msk_dev, PCI_OUR_REG_5, our, 4);
    -			pci_write_config(sc->msk_dev, PCI_CFG_REG_1, 0, 4);
    +			CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, our);
    +			CSR_PCI_WRITE_4(sc, PCI_CFG_REG_1, 0);
     			/*
     			 * Disable status race, workaround for
     			 * Yukon EC Ultra & Yukon EX.
    @@ -1175,7 +1175,7 @@ msk_phy_power(struct msk_softc *sc, int mode)
     		}
     		break;
     	case MSK_PHY_POWERDOWN:
    -		val = pci_read_config(sc->msk_dev, PCI_OUR_REG_1, 4);
    +		val = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
     		val |= PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD;
     		if (sc->msk_hw_id == CHIP_ID_YUKON_XL &&
     		    sc->msk_hw_rev > CHIP_REV_YU_XL_A1) {
    @@ -1183,7 +1183,7 @@ msk_phy_power(struct msk_softc *sc, int mode)
     			if (sc->msk_num_port > 1)
     				val &= ~PCI_Y2_PHY2_COMA;
     		}
    -		pci_write_config(sc->msk_dev, PCI_OUR_REG_1, val, 4);
    +		CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, val);
     
     		val = Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
     		      Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
    
    From f818fb99696d798befee28ef14e25b0ab464723a Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Wed, 24 Mar 2010 18:37:58 +0000
    Subject: [PATCH 1678/2592] make the module loadable
    
    Submitted by:	Marcin Wisnicki
    ---
     sys/modules/dummynet/Makefile | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sys/modules/dummynet/Makefile b/sys/modules/dummynet/Makefile
    index c25a7a7b0f4..7b01ca183b9 100644
    --- a/sys/modules/dummynet/Makefile
    +++ b/sys/modules/dummynet/Makefile
    @@ -5,6 +5,8 @@
     .PATH:  ${.CURDIR}/../../netinet/ipfw
     KMOD=   dummynet
     SRCS=   ip_dummynet.c
    +SRCS+= ip_dn_glue.c ip_dn_io.c
    +SRCS+= dn_heap.c dn_sched_fifo.c dn_sched_qfq.c dn_sched_rr.c dn_sched_wf2q.
     SRCS+=	opt_inet6.h
     
     .if !defined(KERNBUILDDIR)
    
    From 51aa112a4ce205fe9dfb656c38e34ed1e4d00e20 Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Wed, 24 Mar 2010 19:20:49 +0000
    Subject: [PATCH 1679/2592] typo...
    
    ---
     sys/modules/dummynet/Makefile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/modules/dummynet/Makefile b/sys/modules/dummynet/Makefile
    index 7b01ca183b9..0e22ca53570 100644
    --- a/sys/modules/dummynet/Makefile
    +++ b/sys/modules/dummynet/Makefile
    @@ -6,7 +6,7 @@
     KMOD=   dummynet
     SRCS=   ip_dummynet.c
     SRCS+= ip_dn_glue.c ip_dn_io.c
    -SRCS+= dn_heap.c dn_sched_fifo.c dn_sched_qfq.c dn_sched_rr.c dn_sched_wf2q.
    +SRCS+= dn_heap.c dn_sched_fifo.c dn_sched_qfq.c dn_sched_rr.c dn_sched_wf2q.c
     SRCS+=	opt_inet6.h
     
     .if !defined(KERNBUILDDIR)
    
    From 8c5156f3effa13fb015c1a326d66fa1861a7a4f8 Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Wed, 24 Mar 2010 23:08:25 +0000
    Subject: [PATCH 1680/2592] fix handling of "ipfw set N ..."
    
    Submitted by:	Marcin Wisnicki
    ---
     sbin/ipfw/ipfw2.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
    index 1ab827f3e26..9e212fc012a 100644
    --- a/sbin/ipfw/ipfw2.c
    +++ b/sbin/ipfw/ipfw2.c
    @@ -2656,7 +2656,7 @@ ipfw_add(char *av[])
     	}
     
     	/* [set N]	-- set number (0..RESVD_SET), optional */
    -	if (av[0] && !av[1] && _substrcmp(*av, "set") == 0) {
    +	if (av[0] && av[1] && _substrcmp(*av, "set") == 0) {
     		int set = strtoul(av[1], NULL, 10);
     		if (set < 0 || set > RESVD_SET)
     			errx(EX_DATAERR, "illegal set %s", av[1]);
    
    From 934f51ed85e146a153cd915104cdf73217484c8c Mon Sep 17 00:00:00 2001
    From: Maxim Sobolev 
    Date: Thu, 25 Mar 2010 02:14:04 +0000
    Subject: [PATCH 1681/2592] MFC: Allow comment in the middle of the line.
    
    ---
     contrib/tcp_wrappers/hosts_access.c | 12 +++++++++++-
     1 file changed, 11 insertions(+), 1 deletion(-)
    
    diff --git a/contrib/tcp_wrappers/hosts_access.c b/contrib/tcp_wrappers/hosts_access.c
    index 8220e649706..03d305b7dc2 100644
    --- a/contrib/tcp_wrappers/hosts_access.c
    +++ b/contrib/tcp_wrappers/hosts_access.c
    @@ -148,6 +148,7 @@ struct request_info *request;
         char   *sh_cmd;			/* becomes optional shell command */
         int     match = NO;
         struct tcpd_context saved_context;
    +    char   *cp;
     
         saved_context = tcpd_context;		/* stupid compilers */
     
    @@ -164,7 +165,16 @@ struct request_info *request;
     		tcpd_warn("missing newline or line too long");
     		continue;
     	    }
    -	    if (sv_list[0] == '#' || sv_list[strspn(sv_list, " \t\r\n")] == 0)
    +	    /* Ignore anything after unescaped # character */
    +	    for (cp = strchr(sv_list, '#'); cp != NULL;) {
    +		if (cp > sv_list && cp[-1] == '\\') {
    +		    cp = strchr(cp + 1, '#');
    +		    continue;
    +		}
    +		*cp = '\0';
    +		break;
    +	    }
    +	    if (sv_list[strspn(sv_list, " \t\r\n")] == 0)
     		continue;
     	    if ((cl_list = split_at(sv_list, ':')) == 0) {
     		tcpd_warn("missing \":\" separator");
    
    From 4ae65fe952e1b101a8d0a15c0b129c570cfb633a Mon Sep 17 00:00:00 2001
    From: Ed Schouten 
    Date: Thu, 25 Mar 2010 08:33:56 +0000
    Subject: [PATCH 1682/2592] MFC r205008 and 205009:
    
      Make script(1) a little less broken.
    
      Close the file descriptor to the TTY. There is no reason why the parent
      process should keep track of the descriptor. This ensures that the
      application inside properly drains the TTY during exit(2).
    
      Reported by:  alfred
    ---
     usr.bin/script/script.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c
    index ad706dcdd35..ef4d3ef2dde 100644
    --- a/usr.bin/script/script.c
    +++ b/usr.bin/script/script.c
    @@ -158,6 +158,7 @@ main(int argc, char *argv[])
     	}
     	if (child == 0)
     		doshell(argv);
    +	close(slave);
     
     	if (flushtime > 0)
     		tvp = &tv;
    
    From f9e27ffac55fb9a10b783965fd58ef9a10713f9f Mon Sep 17 00:00:00 2001
    From: Gavin Atkinson 
    Date: Thu, 25 Mar 2010 12:56:20 +0000
    Subject: [PATCH 1683/2592] Merge r204165 from head:
    
      Add a "-x" option to chown(8)/chgrp(1) similar to the same option in
      du(1), cp(1) etc, to prevent the crossing of mountpoints whilst using the
      commands recursively.
    
    PR:		bin/130855
    Submitted by:	keramida
    ---
     usr.sbin/chown/chgrp.1 | 10 +++++++---
     usr.sbin/chown/chown.8 | 12 ++++++++----
     usr.sbin/chown/chown.c | 17 +++++++++++------
     3 files changed, 26 insertions(+), 13 deletions(-)
    
    diff --git a/usr.sbin/chown/chgrp.1 b/usr.sbin/chown/chgrp.1
    index 71b68066612..8a4c2711edf 100644
    --- a/usr.sbin/chown/chgrp.1
    +++ b/usr.sbin/chown/chgrp.1
    @@ -31,7 +31,7 @@
     .\"     @(#)chgrp.1	8.3 (Berkeley) 3/31/94
     .\" $FreeBSD$
     .\"
    -.Dd April 25, 2003
    +.Dd February 21, 2010
     .Dt CHGRP 1
     .Os
     .Sh NAME
    @@ -39,7 +39,7 @@
     .Nd change group
     .Sh SYNOPSIS
     .Nm
    -.Op Fl fhv
    +.Op Fl fhvx
     .Oo
     .Fl R
     .Op Fl H | Fl L | Fl P
    @@ -89,6 +89,8 @@ If the
     flag is specified more than once,
     .Nm
     will print the filename, followed by the old and new numeric group ID.
    +.It Fl x
    +File system mount points are not traversed.
     .El
     .Pp
     The
    @@ -125,7 +127,9 @@ In previous versions of this system, symbolic links did not have groups.
     .Pp
     The
     .Fl v
    -option is non-standard and its use in scripts is not recommended.
    +and
    +.Fl x
    +options are non-standard and their use in scripts is not recommended.
     .Sh SEE ALSO
     .Xr chown 2 ,
     .Xr fts 3 ,
    diff --git a/usr.sbin/chown/chown.8 b/usr.sbin/chown/chown.8
    index f617f735550..b5882a3cc6a 100644
    --- a/usr.sbin/chown/chown.8
    +++ b/usr.sbin/chown/chown.8
    @@ -28,7 +28,7 @@
     .\"     @(#)chown.8	8.3 (Berkeley) 3/31/94
     .\" $FreeBSD$
     .\"
    -.Dd April 25, 2003
    +.Dd February 21, 2010
     .Dt CHOWN 8
     .Os
     .Sh NAME
    @@ -36,7 +36,7 @@
     .Nd change file owner and group
     .Sh SYNOPSIS
     .Nm
    -.Op Fl fhv
    +.Op Fl fhvx
     .Oo
     .Fl R
     .Op Fl H | Fl L | Fl P
    @@ -44,7 +44,7 @@
     .Ar owner Ns Op : Ns Ar group
     .Ar
     .Nm
    -.Op Fl fhv
    +.Op Fl fhvx
     .Oo
     .Fl R
     .Op Fl H | Fl L | Fl P
    @@ -97,6 +97,8 @@ If the
     flag is specified more than once,
     .Nm
     will print the filename, followed by the old and new numeric user/group ID.
    +.It Fl x
    +File system mount points are not traversed.
     .El
     .Pp
     The
    @@ -146,7 +148,9 @@ owners.
     .Pp
     The
     .Fl v
    -option is non-standard and its use in scripts is not recommended.
    +and
    +.Fl x
    +options are non-standard and their use in scripts is not recommended.
     .Sh SEE ALSO
     .Xr chgrp 1 ,
     .Xr find 1 ,
    diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c
    index b79decaa6a0..7a22292731d 100644
    --- a/usr.sbin/chown/chown.c
    +++ b/usr.sbin/chown/chown.c
    @@ -73,14 +73,14 @@ main(int argc, char **argv)
     {
     	FTS *ftsp;
     	FTSENT *p;
    -	int Hflag, Lflag, Rflag, fflag, hflag, vflag;
    +	int Hflag, Lflag, Rflag, fflag, hflag, vflag, xflag;
     	int ch, fts_options, rval;
     	char *cp;
     
     	ischown = (strcmp(basename(argv[0]), "chown") == 0);
     
    -	Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
    -	while ((ch = getopt(argc, argv, "HLPRfhv")) != -1)
    +	Hflag = Lflag = Rflag = fflag = hflag = vflag = xflag = 0;
    +	while ((ch = getopt(argc, argv, "HLPRfhvx")) != -1)
     		switch (ch) {
     		case 'H':
     			Hflag = 1;
    @@ -105,6 +105,9 @@ main(int argc, char **argv)
     		case 'v':
     			vflag++;
     			break;
    +		case 'x':
    +			xflag = 1;
    +			break;
     		case '?':
     		default:
     			usage();
    @@ -128,6 +131,8 @@ main(int argc, char **argv)
     		}
     	} else
     		fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL;
    +	if (xflag)
    +		fts_options |= FTS_XDEV;
     
     	uid = (uid_t)-1;
     	gid = (gid_t)-1;
    @@ -301,11 +306,11 @@ usage(void)
     
     	if (ischown)
     		(void)fprintf(stderr, "%s\n%s\n",
    -		    "usage: chown [-fhv] [-R [-H | -L | -P]] owner[:group]"
    +		    "usage: chown [-fhvx] [-R [-H | -L | -P]] owner[:group]"
     		    " file ...",
    -		    "       chown [-fhv] [-R [-H | -L | -P]] :group file ...");
    +		    "       chown [-fhvx] [-R [-H | -L | -P]] :group file ...");
     	else
     		(void)fprintf(stderr, "%s\n",
    -		    "usage: chgrp [-fhv] [-R [-H | -L | -P]] group file ...");
    +		    "usage: chgrp [-fhvx] [-R [-H | -L | -P]] group file ...");
     	exit(1);
     }
    
    From b1fc296597125d14e967132d460363ba25e9c9c9 Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Thu, 25 Mar 2010 15:48:23 +0000
    Subject: [PATCH 1684/2592] MFC 205013: Print out the family and model from the
     cpu_id.  This is especially useful given the advent of the extended family
     and extended model fields.  The values are printed in hex to match their
     common usage in documentation.
    
    ---
     sys/amd64/amd64/identcpu.c | 4 +++-
     sys/i386/i386/identcpu.c   | 6 ++++--
     2 files changed, 7 insertions(+), 3 deletions(-)
    
    diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
    index 3cd2f5e4ba8..b0da729c368 100644
    --- a/sys/amd64/amd64/identcpu.c
    +++ b/sys/amd64/amd64/identcpu.c
    @@ -187,7 +187,9 @@ printcpuinfo(void)
     	if (cpu_vendor_id == CPU_VENDOR_INTEL ||
     	    cpu_vendor_id == CPU_VENDOR_AMD ||
     	    cpu_vendor_id == CPU_VENDOR_CENTAUR) {
    -		printf("  Stepping = %u", cpu_id & 0xf);
    +		printf("  Family = %x", CPUID_TO_FAMILY(cpu_id));
    +		printf("  Model = %x", CPUID_TO_MODEL(cpu_id));
    +		printf("  Stepping = %u", cpu_id & CPUID_STEPPING);
     		if (cpu_high > 0) {
     
     			/*
    diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
    index 62c27abca47..931bfaf6777 100644
    --- a/sys/i386/i386/identcpu.c
    +++ b/sys/i386/i386/identcpu.c
    @@ -672,9 +672,11 @@ printcpuinfo(void)
     	    cpu_vendor_id == CPU_VENDOR_NSC ||
     		(cpu_vendor_id == CPU_VENDOR_CYRIX &&
     		 ((cpu_id & 0xf00) > 0x500))) {
    -		printf("  Stepping = %u", cpu_id & 0xf);
    +		printf("  Family = %x", CPUID_TO_FAMILY(cpu_id));
    +		printf("  Model = %x", CPUID_TO_MODEL(cpu_id));
    +		printf("  Stepping = %u", cpu_id & CPUID_STEPPING);
     		if (cpu_vendor_id == CPU_VENDOR_CYRIX)
    -			printf("  DIR=0x%04x", cyrix_did);
    +			printf("\n  DIR=0x%04x", cyrix_did);
     		if (cpu_high > 0) {
     
     			/*
    
    From 3776abf91b6d2623778e91540ad06946f329fa31 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Thu, 25 Mar 2010 20:07:30 +0000
    Subject: [PATCH 1685/2592] MFC r205654:
    
    The rmt client in GNU cpio could have a heap overflow when a malicious
    remote tape service returns deliberately crafted packets containing
    more data than requested.
    
    Fix this by checking the returned amount of data and bail out when it
    is more than what we requested.
    
    PR:		gnu/145010
    Submitted by:	naddy
    Reviewed by:	imp
    Security:	CVE-2010-0624
    ---
     contrib/cpio/lib/rtapelib.c | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/contrib/cpio/lib/rtapelib.c b/contrib/cpio/lib/rtapelib.c
    index af19b04c5d4..d73d1364e84 100644
    --- a/contrib/cpio/lib/rtapelib.c
    +++ b/contrib/cpio/lib/rtapelib.c
    @@ -570,7 +570,8 @@ rmt_read__ (int handle, char *buffer, size_t length)
     
       sprintf (command_buffer, "R%lu\n", (unsigned long) length);
       if (do_command (handle, command_buffer) == -1
    -      || (status = get_status (handle)) == SAFE_READ_ERROR)
    +      || (status = get_status (handle)) == SAFE_READ_ERROR
    +      || status > length)
         return SAFE_READ_ERROR;
     
       for (counter = 0; counter < status; counter += rlen, buffer += rlen)
    
    From 77119642465407a01036c904789e1b07d43caad2 Mon Sep 17 00:00:00 2001
    From: Maxim Sobolev 
    Date: Thu, 25 Mar 2010 23:38:10 +0000
    Subject: [PATCH 1686/2592] MFC: workaround no-carrier issue on IBM HS21.
    
    PR:		118238
    ---
     sys/dev/mii/brgphy.c | 38 +++++++++++++++++++++++++++++++++++---
     1 file changed, 35 insertions(+), 3 deletions(-)
    
    diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
    index ddbec6761ba..ce73d8c9e5b 100644
    --- a/sys/dev/mii/brgphy.c
    +++ b/sys/dev/mii/brgphy.c
    @@ -72,8 +72,9 @@ struct brgphy_softc {
     	int mii_model;
     	int mii_rev;
     	int serdes_flags;	/* Keeps track of the serdes type used */
    -#define BRGPHY_5706S	0x0001
    -#define BRGPHY_5708S	0x0002
    +#define BRGPHY_5706S		0x0001
    +#define BRGPHY_5708S		0x0002
    +#define BRGPHY_NOANWAIT		0x0004
     	int bce_phy_flags;	/* PHY flags transferred from the MAC driver */
     };
     
    @@ -142,6 +143,23 @@ static const struct mii_phydesc brgphys[] = {
     	MII_PHY_END
     };
     
    +#define HS21_PRODUCT_ID	"IBM eServer BladeCenter HS21"
    +#define HS21_BCM_CHIPID	0x57081021
    +
    +static int
    +detect_hs21(struct bce_softc *bce_sc)
    +{
    +	char *sysenv;
    +
    +	if (bce_sc->bce_chipid != HS21_BCM_CHIPID)
    +		return (0);
    +	sysenv = getenv("smbios.system.product");
    +	if (sysenv == NULL)
    +		return (0);
    +	if (strncmp(sysenv, HS21_PRODUCT_ID, strlen(HS21_PRODUCT_ID)) != 0)
    +		return (0);
    +	return (1);
    +}
     
     /* Search for our PHY in the list of known PHYs */
     static int
    @@ -291,6 +309,19 @@ brgphy_attach(device_t dev)
     		if (bce_sc && (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)) {
     			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0);
     			printf("2500baseSX-FDX, ");
    +		} else if ((bsc->serdes_flags & BRGPHY_5708S) && bce_sc &&
    +		    (detect_hs21(bce_sc) != 0)) {
    +			/*
    +			 * There appears to be certain silicon revision
    +			 * in IBM HS21 blades that is having issues with
    +			 * this driver wating for the auto-negotiation to
    +			 * complete. This happens with a specific chip id
    +			 * only and when the 1000baseSX-FDX is the only
    +			 * mode. Workaround this issue since it's unlikely
    +			 * to be ever addressed.
    +			 */
    +			printf("auto-neg workaround, ");
    +			bsc->serdes_flags |= BRGPHY_NOANWAIT;
     		}
     	}
     
    @@ -544,7 +575,8 @@ brgphy_status(struct mii_softc *sc)
     
     	/* Autoneg is still in progress. */
     	if ((bmcr & BRGPHY_BMCR_AUTOEN) &&
    -	    (bmsr & BRGPHY_BMSR_ACOMP) == 0) {
    +	    (bmsr & BRGPHY_BMSR_ACOMP) == 0 &&
    +	    (bsc->serdes_flags & BRGPHY_NOANWAIT) == 0) {
     		/* Erg, still trying, I guess... */
     		mii->mii_media_active |= IFM_NONE;
     		goto brgphy_status_exit;
    
    From 828bb4f8d4a301070b4be55ab6a62428e52bd601 Mon Sep 17 00:00:00 2001
    From: Joerg Wunsch 
    Date: Fri, 26 Mar 2010 05:13:43 +0000
    Subject: [PATCH 1687/2592] r205509:
    
      Add .snap to daily_clean_tmps_ignore; /tmp/.snap ist not supposed to
      be auto-removed (and /tmp is a filesystem of its own now by
      default).
    ---
     etc/defaults/periodic.conf | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/etc/defaults/periodic.conf b/etc/defaults/periodic.conf
    index c79e956cf99..9c11d3561d9 100644
    --- a/etc/defaults/periodic.conf
    +++ b/etc/defaults/periodic.conf
    @@ -46,7 +46,7 @@ daily_clean_tmps_enable="NO"				# Delete stuff daily
     daily_clean_tmps_dirs="/tmp"				# Delete under here
     daily_clean_tmps_days="3"				# If not accessed for
     daily_clean_tmps_ignore=".X*-lock .X11-unix .ICE-unix .font-unix .XIM-unix"
    -daily_clean_tmps_ignore="$daily_clean_tmps_ignore quota.user quota.group"
    +daily_clean_tmps_ignore="$daily_clean_tmps_ignore quota.user quota.group .snap"
     							# Don't delete these
     daily_clean_tmps_verbose="YES"				# Mention files deleted
     
    
    From d62da942914b4ddb2b6b262b1c717d538af518c4 Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Fri, 26 Mar 2010 13:01:30 +0000
    Subject: [PATCH 1688/2592] MFC 205210,205448: Remove unneeded type specifiers
     from 64-bit constants.  The compiler infers their natural type from the
     constants' values.
    
    ---
     sys/amd64/include/specialreg.h | 44 +++++++++++++++++-----------------
     sys/i386/include/specialreg.h  | 44 +++++++++++++++++-----------------
     2 files changed, 44 insertions(+), 44 deletions(-)
    
    diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
    index 8cadbcd22f6..733f4d7e8fb 100644
    --- a/sys/amd64/include/specialreg.h
    +++ b/sys/amd64/include/specialreg.h
    @@ -320,16 +320,16 @@
     #define	MTRR_N64K		8	/* numbers of fixed-size entries */
     #define	MTRR_N16K		16
     #define	MTRR_N4K		64
    -#define	MTRR_CAP_WC		0x0000000000000400UL
    -#define	MTRR_CAP_FIXED		0x0000000000000100UL
    -#define	MTRR_CAP_VCNT		0x00000000000000ffUL
    -#define	MTRR_DEF_ENABLE		0x0000000000000800UL
    -#define	MTRR_DEF_FIXED_ENABLE	0x0000000000000400UL
    -#define	MTRR_DEF_TYPE		0x00000000000000ffUL
    -#define	MTRR_PHYSBASE_PHYSBASE	0x000ffffffffff000UL
    -#define	MTRR_PHYSBASE_TYPE	0x00000000000000ffUL
    -#define	MTRR_PHYSMASK_PHYSMASK	0x000ffffffffff000UL
    -#define	MTRR_PHYSMASK_VALID	0x0000000000000800UL
    +#define	MTRR_CAP_WC		0x0000000000000400
    +#define	MTRR_CAP_FIXED		0x0000000000000100
    +#define	MTRR_CAP_VCNT		0x00000000000000ff
    +#define	MTRR_DEF_ENABLE		0x0000000000000800
    +#define	MTRR_DEF_FIXED_ENABLE	0x0000000000000400
    +#define	MTRR_DEF_TYPE		0x00000000000000ff
    +#define	MTRR_PHYSBASE_PHYSBASE	0x000ffffffffff000
    +#define	MTRR_PHYSBASE_TYPE	0x00000000000000ff
    +#define	MTRR_PHYSMASK_PHYSMASK	0x000ffffffffff000
    +#define	MTRR_PHYSMASK_VALID	0x0000000000000800
     
     /* Performance Control Register (5x86 only). */
     #define	PCR0			0x20
    @@ -357,22 +357,22 @@
     #define	MCG_STATUS_RIPV		0x00000001
     #define	MCG_STATUS_EIPV		0x00000002
     #define	MCG_STATUS_MCIP		0x00000004
    -#define	MCG_CTL_ENABLE		0xffffffffffffffffUL
    -#define	MCG_CTL_DISABLE		0x0000000000000000UL
    +#define	MCG_CTL_ENABLE		0xffffffffffffffff
    +#define	MCG_CTL_DISABLE		0x0000000000000000
     #define	MSR_MC_CTL(x)		(MSR_MC0_CTL + (x) * 4)
     #define	MSR_MC_STATUS(x)	(MSR_MC0_STATUS + (x) * 4)
     #define	MSR_MC_ADDR(x)		(MSR_MC0_ADDR + (x) * 4)
     #define	MSR_MC_MISC(x)		(MSR_MC0_MISC + (x) * 4)
    -#define	MC_STATUS_MCA_ERROR	0x000000000000ffffUL
    -#define	MC_STATUS_MODEL_ERROR	0x00000000ffff0000UL
    -#define	MC_STATUS_OTHER_INFO	0x01ffffff00000000UL
    -#define	MC_STATUS_PCC		0x0200000000000000UL
    -#define	MC_STATUS_ADDRV		0x0400000000000000UL
    -#define	MC_STATUS_MISCV		0x0800000000000000UL
    -#define	MC_STATUS_EN		0x1000000000000000UL
    -#define	MC_STATUS_UC		0x2000000000000000UL
    -#define	MC_STATUS_OVER		0x4000000000000000UL
    -#define	MC_STATUS_VAL		0x8000000000000000UL
    +#define	MC_STATUS_MCA_ERROR	0x000000000000ffff
    +#define	MC_STATUS_MODEL_ERROR	0x00000000ffff0000
    +#define	MC_STATUS_OTHER_INFO	0x01ffffff00000000
    +#define	MC_STATUS_PCC		0x0200000000000000
    +#define	MC_STATUS_ADDRV		0x0400000000000000
    +#define	MC_STATUS_MISCV		0x0800000000000000
    +#define	MC_STATUS_EN		0x1000000000000000
    +#define	MC_STATUS_UC		0x2000000000000000
    +#define	MC_STATUS_OVER		0x4000000000000000
    +#define	MC_STATUS_VAL		0x8000000000000000
     
     /*
      * The following four 3-byte registers control the non-cacheable regions.
    diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h
    index d51da6d59fe..f0f678b1f5c 100644
    --- a/sys/i386/include/specialreg.h
    +++ b/sys/i386/include/specialreg.h
    @@ -326,16 +326,16 @@
     #define	MTRR_N64K		8	/* numbers of fixed-size entries */
     #define	MTRR_N16K		16
     #define	MTRR_N4K		64
    -#define	MTRR_CAP_WC		0x0000000000000400ULL
    -#define	MTRR_CAP_FIXED		0x0000000000000100ULL
    -#define	MTRR_CAP_VCNT		0x00000000000000ffULL
    -#define	MTRR_DEF_ENABLE		0x0000000000000800ULL
    -#define	MTRR_DEF_FIXED_ENABLE	0x0000000000000400ULL
    -#define	MTRR_DEF_TYPE		0x00000000000000ffULL
    -#define	MTRR_PHYSBASE_PHYSBASE	0x000ffffffffff000ULL
    -#define	MTRR_PHYSBASE_TYPE	0x00000000000000ffULL
    -#define	MTRR_PHYSMASK_PHYSMASK	0x000ffffffffff000ULL
    -#define	MTRR_PHYSMASK_VALID	0x0000000000000800ULL
    +#define	MTRR_CAP_WC		0x0000000000000400
    +#define	MTRR_CAP_FIXED		0x0000000000000100
    +#define	MTRR_CAP_VCNT		0x00000000000000ff
    +#define	MTRR_DEF_ENABLE		0x0000000000000800
    +#define	MTRR_DEF_FIXED_ENABLE	0x0000000000000400
    +#define	MTRR_DEF_TYPE		0x00000000000000ff
    +#define	MTRR_PHYSBASE_PHYSBASE	0x000ffffffffff000
    +#define	MTRR_PHYSBASE_TYPE	0x00000000000000ff
    +#define	MTRR_PHYSMASK_PHYSMASK	0x000ffffffffff000
    +#define	MTRR_PHYSMASK_VALID	0x0000000000000800
     
     /*
      * Cyrix configuration registers, accessible as IO ports.
    @@ -426,22 +426,22 @@
     #define	MCG_STATUS_RIPV		0x00000001
     #define	MCG_STATUS_EIPV		0x00000002
     #define	MCG_STATUS_MCIP		0x00000004
    -#define	MCG_CTL_ENABLE		0xffffffffffffffffUL
    -#define	MCG_CTL_DISABLE		0x0000000000000000UL
    +#define	MCG_CTL_ENABLE		0xffffffffffffffff
    +#define	MCG_CTL_DISABLE		0x0000000000000000
     #define	MSR_MC_CTL(x)		(MSR_MC0_CTL + (x) * 4)
     #define	MSR_MC_STATUS(x)	(MSR_MC0_STATUS + (x) * 4)
     #define	MSR_MC_ADDR(x)		(MSR_MC0_ADDR + (x) * 4)
     #define	MSR_MC_MISC(x)		(MSR_MC0_MISC + (x) * 4)
    -#define	MC_STATUS_MCA_ERROR	0x000000000000ffffUL
    -#define	MC_STATUS_MODEL_ERROR	0x00000000ffff0000UL
    -#define	MC_STATUS_OTHER_INFO	0x01ffffff00000000UL
    -#define	MC_STATUS_PCC		0x0200000000000000UL
    -#define	MC_STATUS_ADDRV		0x0400000000000000UL
    -#define	MC_STATUS_MISCV		0x0800000000000000UL
    -#define	MC_STATUS_EN		0x1000000000000000UL
    -#define	MC_STATUS_UC		0x2000000000000000UL
    -#define	MC_STATUS_OVER		0x4000000000000000UL
    -#define	MC_STATUS_VAL		0x8000000000000000UL
    +#define	MC_STATUS_MCA_ERROR	0x000000000000ffff
    +#define	MC_STATUS_MODEL_ERROR	0x00000000ffff0000
    +#define	MC_STATUS_OTHER_INFO	0x01ffffff00000000
    +#define	MC_STATUS_PCC		0x0200000000000000
    +#define	MC_STATUS_ADDRV		0x0400000000000000
    +#define	MC_STATUS_MISCV		0x0800000000000000
    +#define	MC_STATUS_EN		0x1000000000000000
    +#define	MC_STATUS_UC		0x2000000000000000
    +#define	MC_STATUS_OVER		0x4000000000000000
    +#define	MC_STATUS_VAL		0x8000000000000000
     
     /*
      * The following four 3-byte registers control the non-cacheable regions.
    
    From c7402c0bbc021a09ccf4e84e9753ac11a688d664 Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Fri, 26 Mar 2010 13:49:46 +0000
    Subject: [PATCH 1689/2592] MFC 205214: - Extend the machine check record
     structure to include several fields useful   for parsing model-specific and
     other fields in machine check events   including the global machine check
     capabilities and status registers,   CPU identification, and the FreeBSD CPU
     ID. - Report these added fields in the console log of a machine check so that
       a record structure can be reconstituted from the console messages. - Parse
     new architectural errors including memory controller errors.
    
    ---
     sys/amd64/amd64/mca.c          | 52 ++++++++++++++++++++++++++++++++--
     sys/amd64/include/mca.h        |  5 ++++
     sys/amd64/include/specialreg.h | 12 ++++++++
     sys/i386/i386/mca.c            | 52 ++++++++++++++++++++++++++++++++--
     sys/i386/include/mca.h         |  5 ++++
     sys/i386/include/specialreg.h  | 12 ++++++++
     6 files changed, 132 insertions(+), 6 deletions(-)
    
    diff --git a/sys/amd64/amd64/mca.c b/sys/amd64/amd64/mca.c
    index b0e842a778b..76bee77a061 100644
    --- a/sys/amd64/amd64/mca.c
    +++ b/sys/amd64/amd64/mca.c
    @@ -177,19 +177,46 @@ mca_error_request(uint16_t mca_error)
     	return ("???");
     }
     
    +static const char *
    +mca_error_mmtype(uint16_t mca_error)
    +{
    +
    +	switch ((mca_error & 0x70) >> 4) {
    +	case 0x0:
    +		return ("GEN");
    +	case 0x1:
    +		return ("RD");
    +	case 0x2:
    +		return ("WR");
    +	case 0x3:
    +		return ("AC");
    +	case 0x4:
    +		return ("MS");
    +	}
    +	return ("???");
    +}
    +
     /* Dump details about a single machine check. */
     static void __nonnull(1)
     mca_log(const struct mca_record *rec)
     {
     	uint16_t mca_error;
     
    -	printf("MCA: bank %d, status 0x%016llx\n", rec->mr_bank,
    +	printf("MCA: Bank %d, Status 0x%016llx\n", rec->mr_bank,
     	    (long long)rec->mr_status);
    -	printf("MCA: CPU %d ", rec->mr_apic_id);
    +	printf("MCA: Global Cap 0x%016llx, Status 0x%016llx\n",
    +	    (long long)rec->mr_mcg_cap, (long long)rec->mr_mcg_status);
    +	printf("MCA: Vendor \"%s\", ID 0x%x, APIC ID %d\n", cpu_vendor,
    +	    rec->mr_cpu_id, rec->mr_apic_id);
    +	printf("MCA: CPU %d ", rec->mr_cpu);
     	if (rec->mr_status & MC_STATUS_UC)
     		printf("UNCOR ");
    -	else
    +	else {
     		printf("COR ");
    +		if (rec->mr_mcg_cap & MCG_CAP_TES_P)
    +			printf("(%lld) ", ((long long)rec->mr_status &
    +			    MC_STATUS_COR_COUNT) >> 38);
    +	}
     	if (rec->mr_status & MC_STATUS_PCC)
     		printf("PCC ");
     	if (rec->mr_status & MC_STATUS_OVER)
    @@ -212,6 +239,9 @@ mca_log(const struct mca_record *rec)
     	case 0x0004:
     		printf("FRC error");
     		break;
    +	case 0x0005:
    +		printf("internal parity error");
    +		break;
     	case 0x0400:
     		printf("internal timer error");
     		break;
    @@ -236,6 +266,17 @@ mca_log(const struct mca_record *rec)
     			break;
     		}
     
    +		/* Memory controller error. */
    +		if ((mca_error & 0xef80) == 0x0080) {
    +			printf("%s channel ", mca_error_mmtype(mca_error));
    +			if ((mca_error & 0x000f) != 0x000f)
    +				printf("%d", mca_error & 0x000f);
    +			else
    +				printf("??");
    +			printf(" memory error");
    +			break;
    +		}
    +		
     		/* Cache error. */
     		if ((mca_error & 0xef00) == 0x0100) {
     			printf("%sCACHE %s %s error",
    @@ -313,6 +354,11 @@ mca_check_status(int bank, struct mca_record *rec)
     		rec->mr_misc = rdmsr(MSR_MC_MISC(bank));
     	rec->mr_tsc = rdtsc();
     	rec->mr_apic_id = PCPU_GET(apic_id);
    +	rec->mr_mcg_cap = rdmsr(MSR_MCG_CAP);
    +	rec->mr_mcg_status = rdmsr(MSR_MCG_STATUS);
    +	rec->mr_cpu_id = cpu_id;
    +	rec->mr_cpu_vendor_id = cpu_vendor_id;
    +	rec->mr_cpu = PCPU_GET(cpuid);
     
     	/*
     	 * Clear machine check.  Don't do this for uncorrectable
    diff --git a/sys/amd64/include/mca.h b/sys/amd64/include/mca.h
    index ddc3aeb649a..bc09480906b 100644
    --- a/sys/amd64/include/mca.h
    +++ b/sys/amd64/include/mca.h
    @@ -37,6 +37,11 @@ struct mca_record {
     	uint64_t	mr_tsc;
     	int		mr_apic_id;
     	int		mr_bank;
    +	uint64_t	mr_mcg_cap;
    +	uint64_t	mr_mcg_status;
    +	int		mr_cpu_id;
    +	int		mr_cpu_vendor_id;
    +	int		mr_cpu;
     };
     
     #ifdef _KERNEL
    diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
    index 733f4d7e8fb..925346297cb 100644
    --- a/sys/amd64/include/specialreg.h
    +++ b/sys/amd64/include/specialreg.h
    @@ -267,6 +267,7 @@
     #define	MSR_MTRR16kBase		0x258
     #define	MSR_MTRR4kBase		0x268
     #define	MSR_PAT			0x277
    +#define	MSR_MC0_CTL2		0x280
     #define	MSR_MTRRdefType		0x2ff
     #define	MSR_MC0_CTL		0x400
     #define	MSR_MC0_STATUS		0x401
    @@ -352,8 +353,10 @@
     #define	MCG_CAP_COUNT		0x000000ff
     #define	MCG_CAP_CTL_P		0x00000100
     #define	MCG_CAP_EXT_P		0x00000200
    +#define	MCG_CAP_CMCI_P		0x00000400
     #define	MCG_CAP_TES_P		0x00000800
     #define	MCG_CAP_EXT_CNT		0x00ff0000
    +#define	MCG_CAP_SER_P		0x01000000
     #define	MCG_STATUS_RIPV		0x00000001
     #define	MCG_STATUS_EIPV		0x00000002
     #define	MCG_STATUS_MCIP		0x00000004
    @@ -363,9 +366,14 @@
     #define	MSR_MC_STATUS(x)	(MSR_MC0_STATUS + (x) * 4)
     #define	MSR_MC_ADDR(x)		(MSR_MC0_ADDR + (x) * 4)
     #define	MSR_MC_MISC(x)		(MSR_MC0_MISC + (x) * 4)
    +#define	MSR_MC_CTL2(x)		(MSR_MC0_CTL2 + (x))	/* If MCG_CAP_CMCI_P */
     #define	MC_STATUS_MCA_ERROR	0x000000000000ffff
     #define	MC_STATUS_MODEL_ERROR	0x00000000ffff0000
     #define	MC_STATUS_OTHER_INFO	0x01ffffff00000000
    +#define	MC_STATUS_COR_COUNT	0x001fffc000000000	/* If MCG_CAP_TES_P */
    +#define	MC_STATUS_TES_STATUS	0x0060000000000000	/* If MCG_CAP_TES_P */
    +#define	MC_STATUS_AR		0x0080000000000000	/* If MCG_CAP_CMCI_P */
    +#define	MC_STATUS_S		0x0100000000000000	/* If MCG_CAP_CMCI_P */
     #define	MC_STATUS_PCC		0x0200000000000000
     #define	MC_STATUS_ADDRV		0x0400000000000000
     #define	MC_STATUS_MISCV		0x0800000000000000
    @@ -373,6 +381,10 @@
     #define	MC_STATUS_UC		0x2000000000000000
     #define	MC_STATUS_OVER		0x4000000000000000
     #define	MC_STATUS_VAL		0x8000000000000000
    +#define	MC_MISC_RA_LSB		0x000000000000003f	/* If MCG_CAP_SER_P */
    +#define	MC_MISC_ADDRESS_MODE	0x00000000000001c0	/* If MCG_CAP_SER_P */
    +#define	MC_CTL2_THRESHOLD	0x0000000000003fff
    +#define	MC_CTL2_CMCI_EN		0x0000000040000000
     
     /*
      * The following four 3-byte registers control the non-cacheable regions.
    diff --git a/sys/i386/i386/mca.c b/sys/i386/i386/mca.c
    index 6148af79243..9b9f9451597 100644
    --- a/sys/i386/i386/mca.c
    +++ b/sys/i386/i386/mca.c
    @@ -177,19 +177,46 @@ mca_error_request(uint16_t mca_error)
     	return ("???");
     }
     
    +static const char *
    +mca_error_mmtype(uint16_t mca_error)
    +{
    +
    +	switch ((mca_error & 0x70) >> 4) {
    +	case 0x0:
    +		return ("GEN");
    +	case 0x1:
    +		return ("RD");
    +	case 0x2:
    +		return ("WR");
    +	case 0x3:
    +		return ("AC");
    +	case 0x4:
    +		return ("MS");
    +	}
    +	return ("???");
    +}
    +
     /* Dump details about a single machine check. */
     static void __nonnull(1)
     mca_log(const struct mca_record *rec)
     {
     	uint16_t mca_error;
     
    -	printf("MCA: bank %d, status 0x%016llx\n", rec->mr_bank,
    +	printf("MCA: Bank %d, Status 0x%016llx\n", rec->mr_bank,
     	    (long long)rec->mr_status);
    -	printf("MCA: CPU %d ", rec->mr_apic_id);
    +	printf("MCA: Global Cap 0x%016llx, Status 0x%016llx\n",
    +	    (long long)rec->mr_mcg_cap, (long long)rec->mr_mcg_status);
    +	printf("MCA: Vendor \"%s\", ID 0x%x, APIC ID %d\n", cpu_vendor,
    +	    rec->mr_cpu_id, rec->mr_apic_id);
    +	printf("MCA: CPU %d ", rec->mr_cpu);
     	if (rec->mr_status & MC_STATUS_UC)
     		printf("UNCOR ");
    -	else
    +	else {
     		printf("COR ");
    +		if (rec->mr_mcg_cap & MCG_CAP_TES_P)
    +			printf("(%lld) ", ((long long)rec->mr_status &
    +			    MC_STATUS_COR_COUNT) >> 38);
    +	}
     	if (rec->mr_status & MC_STATUS_PCC)
     		printf("PCC ");
     	if (rec->mr_status & MC_STATUS_OVER)
    @@ -212,6 +239,9 @@ mca_log(const struct mca_record *rec)
     	case 0x0004:
     		printf("FRC error");
     		break;
    +	case 0x0005:
    +		printf("internal parity error");
    +		break;
     	case 0x0400:
     		printf("internal timer error");
     		break;
    @@ -236,6 +266,17 @@ mca_log(const struct mca_record *rec)
     			break;
     		}
     
    +		/* Memory controller error. */
    +		if ((mca_error & 0xef80) == 0x0080) {
    +			printf("%s channel ", mca_error_mmtype(mca_error));
    +			if ((mca_error & 0x000f) != 0x000f)
    +				printf("%d", mca_error & 0x000f);
    +			else
    +				printf("??");
    +			printf(" memory error");
    +			break;
    +		}
    +		
     		/* Cache error. */
     		if ((mca_error & 0xef00) == 0x0100) {
     			printf("%sCACHE %s %s error",
    @@ -313,6 +354,11 @@ mca_check_status(int bank, struct mca_record *rec)
     		rec->mr_misc = rdmsr(MSR_MC_MISC(bank));
     	rec->mr_tsc = rdtsc();
     	rec->mr_apic_id = PCPU_GET(apic_id);
    +	rec->mr_mcg_cap = rdmsr(MSR_MCG_CAP);
    +	rec->mr_mcg_status = rdmsr(MSR_MCG_STATUS);
    +	rec->mr_cpu_id = cpu_id;
    +	rec->mr_cpu_vendor_id = cpu_vendor_id;
    +	rec->mr_cpu = PCPU_GET(cpuid);
     
     	/*
     	 * Clear machine check.  Don't do this for uncorrectable
    diff --git a/sys/i386/include/mca.h b/sys/i386/include/mca.h
    index ddc3aeb649a..bc09480906b 100644
    --- a/sys/i386/include/mca.h
    +++ b/sys/i386/include/mca.h
    @@ -37,6 +37,11 @@ struct mca_record {
     	uint64_t	mr_tsc;
     	int		mr_apic_id;
     	int		mr_bank;
    +	uint64_t	mr_mcg_cap;
    +	uint64_t	mr_mcg_status;
    +	int		mr_cpu_id;
    +	int		mr_cpu_vendor_id;
    +	int		mr_cpu;
     };
     
     #ifdef _KERNEL
    diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h
    index f0f678b1f5c..64a55350391 100644
    --- a/sys/i386/include/specialreg.h
    +++ b/sys/i386/include/specialreg.h
    @@ -273,6 +273,7 @@
     #define	MSR_MTRR16kBase		0x258
     #define	MSR_MTRR4kBase		0x268
     #define	MSR_PAT			0x277
    +#define	MSR_MC0_CTL2		0x280
     #define	MSR_MTRRdefType		0x2ff
     #define	MSR_MC0_CTL		0x400
     #define	MSR_MC0_STATUS		0x401
    @@ -421,8 +422,10 @@
     #define	MCG_CAP_COUNT		0x000000ff
     #define	MCG_CAP_CTL_P		0x00000100
     #define	MCG_CAP_EXT_P		0x00000200
    +#define	MCG_CAP_CMCI_P		0x00000400
     #define	MCG_CAP_TES_P		0x00000800
     #define	MCG_CAP_EXT_CNT		0x00ff0000
    +#define	MCG_CAP_SER_P		0x01000000
     #define	MCG_STATUS_RIPV		0x00000001
     #define	MCG_STATUS_EIPV		0x00000002
     #define	MCG_STATUS_MCIP		0x00000004
    @@ -432,9 +435,14 @@
     #define	MSR_MC_STATUS(x)	(MSR_MC0_STATUS + (x) * 4)
     #define	MSR_MC_ADDR(x)		(MSR_MC0_ADDR + (x) * 4)
     #define	MSR_MC_MISC(x)		(MSR_MC0_MISC + (x) * 4)
    +#define	MSR_MC_CTL2(x)		(MSR_MC0_CTL2 + (x))	/* If MCG_CAP_CMCI_P */
     #define	MC_STATUS_MCA_ERROR	0x000000000000ffff
     #define	MC_STATUS_MODEL_ERROR	0x00000000ffff0000
     #define	MC_STATUS_OTHER_INFO	0x01ffffff00000000
    +#define	MC_STATUS_COR_COUNT	0x001fffc000000000	/* If MCG_CAP_TES_P */
    +#define	MC_STATUS_TES_STATUS	0x0060000000000000	/* If MCG_CAP_TES_P */
    +#define	MC_STATUS_AR		0x0080000000000000	/* If MCG_CAP_CMCI_P */
    +#define	MC_STATUS_S		0x0100000000000000	/* If MCG_CAP_CMCI_P */
     #define	MC_STATUS_PCC		0x0200000000000000
     #define	MC_STATUS_ADDRV		0x0400000000000000
     #define	MC_STATUS_MISCV		0x0800000000000000
    @@ -442,6 +450,10 @@
     #define	MC_STATUS_UC		0x2000000000000000
     #define	MC_STATUS_OVER		0x4000000000000000
     #define	MC_STATUS_VAL		0x8000000000000000
    +#define	MC_MISC_RA_LSB		0x000000000000003f	/* If MCG_CAP_SER_P */
    +#define	MC_MISC_ADDRESS_MODE	0x00000000000001c0	/* If MCG_CAP_SER_P */
    +#define	MC_CTL2_THRESHOLD	0x0000000000003fff
    +#define	MC_CTL2_CMCI_EN		0x0000000040000000
     
     /*
      * The following four 3-byte registers control the non-cacheable regions.
    
    From e617a8cfde4a299462a73d93450edd327e07f78c Mon Sep 17 00:00:00 2001
    From: Ivan Voras 
    Date: Fri, 26 Mar 2010 14:03:42 +0000
    Subject: [PATCH 1690/2592] MFC r204248,r204249 - "fancy snake_saver" with
     color coded load averages
    
    ---
     sys/dev/syscons/snake/snake_saver.c | 55 +++++++++++++++++++++++++----
     1 file changed, 49 insertions(+), 6 deletions(-)
    
    diff --git a/sys/dev/syscons/snake/snake_saver.c b/sys/dev/syscons/snake/snake_saver.c
    index bbdcda31b5e..dbcc21758b2 100644
    --- a/sys/dev/syscons/snake/snake_saver.c
    +++ b/sys/dev/syscons/snake/snake_saver.c
    @@ -36,6 +36,8 @@
     #include 
     #include 
     #include 
    +#include 
    +#include 
     
     #include 
     
    @@ -48,11 +50,22 @@ static int	*messagep;
     static int	messagelen;
     static int	blanked;
     
    +#define MSGBUF_LEN 	70
    +
    +static int	nofancy = 0;
    +TUNABLE_INT("hw.syscons.saver_snake_nofancy", &nofancy);
    +
    +#define FANCY_SNAKE 	(!nofancy)
    +#define LOAD_HIGH(ld) 	(((ld * 100 + FSCALE / 2) >> FSHIFT) / 100)
    +#define LOAD_LOW(ld) 	(((ld * 100 + FSCALE / 2) >> FSHIFT) % 100)
    +
    +static inline void update_msg(void);
    +
     static int
     snake_saver(video_adapter_t *adp, int blank)
     {
     	static int	dirx, diry;
    -	int		f;
    +	int		f, color, load;
     	sc_softc_t	*sc;
     	scr_stat	*scp;
     
    @@ -99,22 +112,52 @@ snake_saver(video_adapter_t *adp, int blank)
     		    (random() % 20) == 0)
     			diry = -diry;
     		savs[0] += dirx + diry;
    +		if (FANCY_SNAKE) {
    +			update_msg();
    +			load = ((averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT);
    +			if (load == 0)
    +				color = FG_LIGHTGREY | BG_BLACK;
    +			else if (load / mp_ncpus <= 50)
    +				color = FG_LIGHTGREEN | BG_BLACK;
    +			else if (load / mp_ncpus <= 75)
    +				color = FG_YELLOW | BG_BLACK;
    +			else if (load / mp_ncpus <= 99)
    +				color = FG_LIGHTRED | BG_BLACK;
    +			else
    +				color = FG_RED | FG_BLINK | BG_BLACK;
    +		} else
    +			color = FG_LIGHTGREY | BG_BLACK;
    +
     		for (f=messagelen-1; f>=0; f--)
     			sc_vtb_putc(&scp->scr, savs[f], sc->scr_map[save[f]],
    -				    (FG_LIGHTGREY | BG_BLACK) << 8);
    +				    color << 8);
     	} else
     		blanked = 0;
     
     	return 0;
     }
     
    +static inline void
    +update_msg(void)
    +{
    +	if (!FANCY_SNAKE) {
    +		messagelen = sprintf(message, "%s %s", ostype, osrelease);
    +		return;
    +	}
    +	messagelen = snprintf(message, MSGBUF_LEN,
    +	    "%s %s (%d.%02d %d.%02d, %d.%02d)",
    +	    ostype, osrelease,
    +	    LOAD_HIGH(averunnable.ldavg[0]), LOAD_LOW(averunnable.ldavg[0]),
    +	    LOAD_HIGH(averunnable.ldavg[1]), LOAD_LOW(averunnable.ldavg[1]),
    +	    LOAD_HIGH(averunnable.ldavg[2]), LOAD_LOW(averunnable.ldavg[2]));
    +}
    +
     static int
     snake_init(video_adapter_t *adp)
     {
    -	messagelen = strlen(ostype) + 1 + strlen(osrelease);
    -	message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK);
    -	sprintf(message, "%s %s", ostype, osrelease);
    -	messagep = malloc(messagelen * sizeof *messagep, M_DEVBUF, M_WAITOK);
    +	message = malloc(MSGBUF_LEN, M_DEVBUF, M_WAITOK);
    +	messagep = malloc(MSGBUF_LEN * sizeof *messagep, M_DEVBUF, M_WAITOK);
    +	update_msg();
     	return 0;
     }
     
    
    From 12d11e21553e22c5354bd82c8b496f003cce6f02 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Fri, 26 Mar 2010 16:45:21 +0000
    Subject: [PATCH 1691/2592] MFC r205630 (imp):
    
    This broke when we went to gnu99 as the default standard.  Fix the build
    by reverting to the gnu89 standard.
    ---
     gnu/usr.bin/cpio/Makefile | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/gnu/usr.bin/cpio/Makefile b/gnu/usr.bin/cpio/Makefile
    index 60756efa997..c31527be94a 100644
    --- a/gnu/usr.bin/cpio/Makefile
    +++ b/gnu/usr.bin/cpio/Makefile
    @@ -58,6 +58,7 @@ SRCS=   copyin.c \
     	xstrndup.c \
     	alloca.h \
     	getopt.h
    +CSTD=gnu89
     
     CLEANFILES+= alloca.h getopt.h
     
    
    From 7bf38446dddc75f6c1bf8b6eb27ae46c33f740da Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Fri, 26 Mar 2010 18:54:25 +0000
    Subject: [PATCH 1692/2592] MFC 204972: Make NKPT a kernel option on i386 so
     that it can be set to a non-default value from kernel config files.
    
    ---
     sys/conf/options.i386      | 1 +
     sys/i386/conf/NOTES        | 9 +++++++++
     sys/i386/i386/mp_machdep.c | 1 +
     sys/i386/xen/mp_machdep.c  | 1 +
     4 files changed, 12 insertions(+)
    
    diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
    index cd2ab98dafc..a8e40e1462d 100644
    --- a/sys/conf/options.i386
    +++ b/sys/conf/options.i386
    @@ -12,6 +12,7 @@ I586_PMC_GUPROF		opt_i586_guprof.h
     MAXMEM
     MPTABLE_FORCE_HTT
     MP_WATCHDOG
    +NKPT			opt_pmap.h
     PERFMON
     PMAP_SHPGPERPROC	opt_pmap.h
     POWERFAIL_NMI		opt_trap.h
    diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
    index 22ae19e2627..38b68ed0db3 100644
    --- a/sys/i386/conf/NOTES
    +++ b/sys/i386/conf/NOTES
    @@ -833,6 +833,15 @@ options 	PMAP_SHPGPERPROC=201
     #
     options 	KVA_PAGES=260
     
    +#
    +# Number of initial kernel page table pages used for early bootstrap.
    +# This number should include enough pages to map the kernel, any
    +# modules or other data loaded with the kernel by the loader, and data
    +# structures allocated before the VM system is initialized such as the
    +# vm_page_t array.  Each page table page maps 4MB (2MB with PAE).
    +#
    +options 	NKPT=31
    +
     
     #####################################################################
     # ABI Emulation
    diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
    index 6729288d69c..716c25e7e46 100644
    --- a/sys/i386/i386/mp_machdep.c
    +++ b/sys/i386/i386/mp_machdep.c
    @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
     #include "opt_cpu.h"
     #include "opt_kstack_pages.h"
     #include "opt_mp_watchdog.h"
    +#include "opt_pmap.h"
     #include "opt_sched.h"
     #include "opt_smp.h"
     
    diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c
    index 92533662b26..0fc2a7c3a14 100644
    --- a/sys/i386/xen/mp_machdep.c
    +++ b/sys/i386/xen/mp_machdep.c
    @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
     #include "opt_cpu.h"
     #include "opt_kstack_pages.h"
     #include "opt_mp_watchdog.h"
    +#include "opt_pmap.h"
     #include "opt_sched.h"
     #include "opt_smp.h"
     
    
    From d8c0d3dd97d43f90ca14af4c1bf3ee068752aa03 Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Fri, 26 Mar 2010 18:58:22 +0000
    Subject: [PATCH 1693/2592] MFC 205332: Use the same policy for rejecting /
     not-reject ACPI tables with incorrect checksums as the base acpi(4) driver. 
     This fixes a problem where the MADT parser would reject the MADT table during
     early boot causing the MP Table to be, but then the acpi(4) driver would
     attach and use non-SMP interrupt routing.
    
    ---
     sys/amd64/acpica/acpi_machdep.c | 2 ++
     sys/i386/acpica/acpi_machdep.c  | 2 ++
     2 files changed, 4 insertions(+)
    
    diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c
    index 0d866e89832..ad5f85489a9 100644
    --- a/sys/amd64/acpica/acpi_machdep.c
    +++ b/sys/amd64/acpica/acpi_machdep.c
    @@ -187,8 +187,10 @@ map_table(vm_paddr_t pa, int offset, const char *sig)
     	if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
     		if (bootverbose)
     			printf("ACPI: Failed checksum for table %s\n", sig);
    +#if (ACPI_CHECKSUM_ABORT)
     		table_unmap(table, length);
     		return (NULL);
    +#endif
     	}
     	return (table);
     }
    diff --git a/sys/i386/acpica/acpi_machdep.c b/sys/i386/acpica/acpi_machdep.c
    index a1f1a07e03a..fa99b48c154 100644
    --- a/sys/i386/acpica/acpi_machdep.c
    +++ b/sys/i386/acpica/acpi_machdep.c
    @@ -638,8 +638,10 @@ map_table(vm_paddr_t pa, int offset, const char *sig)
     	if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
     		if (bootverbose)
     			printf("ACPI: Failed checksum for table %s\n", sig);
    +#if (ACPI_CHECKSUM_ABORT)
     		table_unmap(table, length);
     		return (NULL);
    +#endif
     	}
     	return (table);
     }
    
    From ae3c92a10678c99c4d19d56aa7385f95be8f72b5 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 14:43:40 +0000
    Subject: [PATCH 1694/2592] MFC r204408:
    
    Fix panic on invalid 'mdconfig -at preload' usage.
    
    PR:		kern/80136
    ---
     sys/dev/md/md.c | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
    index 20060999a23..78f2af3673c 100644
    --- a/sys/dev/md/md.c
    +++ b/sys/dev/md/md.c
    @@ -814,6 +814,8 @@ mdcreate_preload(struct md_s *sc, struct md_ioctl *mdio)
     
     	if (mdio->md_options & ~(MD_AUTOUNIT | MD_FORCE))
     		return (EINVAL);
    +	if (mdio->md_base == 0)
    +		return (EINVAL);
     	sc->flags = mdio->md_options & MD_FORCE;
     	/* Cast to pointer size, then to pointer to avoid warning */
     	sc->pl_ptr = (u_char *)(uintptr_t)mdio->md_base;
    
    From c0d73b99f2247ef89b2c619d990b2bfd0cfb5903 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 14:58:28 +0000
    Subject: [PATCH 1695/2592] MFC r202919:
    
    Fix array overflow.  This routine is only called from procfs,
    which is not mounted by default, and I've been unable to trigger
    a panic without this fix applied anyway.
    
    Reviewed by:	kib, cperciva
    ---
     sys/amd64/ia32/ia32_reg.c | 2 --
     1 file changed, 2 deletions(-)
    
    diff --git a/sys/amd64/ia32/ia32_reg.c b/sys/amd64/ia32/ia32_reg.c
    index 83f6783e55c..da5190f0db9 100644
    --- a/sys/amd64/ia32/ia32_reg.c
    +++ b/sys/amd64/ia32/ia32_reg.c
    @@ -213,8 +213,6 @@ fill_dbregs32(struct thread *td, struct dbreg32 *regs)
     	err = fill_dbregs(td, &dr);
     	for (i = 0; i < 8; i++)
     		regs->dr[i] = dr.dr[i];
    -	for (i = 8; i < 16; i++)
    -		regs->dr[i] = 0;
     	return (err);
     }
     
    
    From ec85a28567eae7939af2d83c452b41388ee532b4 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 15:02:28 +0000
    Subject: [PATCH 1696/2592] MFC r201818:
    
    Fix array overflow.
    
    Reviewed by:	philip
    ---
     sys/contrib/ngatm/netnatm/api/cc_conn.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/contrib/ngatm/netnatm/api/cc_conn.c b/sys/contrib/ngatm/netnatm/api/cc_conn.c
    index c57bc1a2b23..2ba972aa009 100644
    --- a/sys/contrib/ngatm/netnatm/api/cc_conn.c
    +++ b/sys/contrib/ngatm/netnatm/api/cc_conn.c
    @@ -768,7 +768,7 @@ cc_party_drop_ack_ind(struct ccconn *conn,
     	party = cc_party_find(conn, drop->epref.epref);
     	if (party == NULL) {
     		cc_party_log(party, "no party for %s",
    -		    ptab[CONN_SIG_DROP_PARTY_ACK_IND]);
    +		    cc_conn_sigtab[CONN_SIG_DROP_PARTY_ACK_IND]);
     		return;
     	}
     	switch (party->state) {
    
    From 285438bfc08e9461cc08d7cb219780f11d027c03 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 15:05:06 +0000
    Subject: [PATCH 1697/2592] MFC r201438:
    
    Make mac_lomac(4) able to interpret NFSv4 access bits.
    
    Reviewed by:	rwatson
    ---
     sys/security/mac_lomac/mac_lomac.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/security/mac_lomac/mac_lomac.c b/sys/security/mac_lomac/mac_lomac.c
    index 63a6a63a2f8..af9539ccd5e 100644
    --- a/sys/security/mac_lomac/mac_lomac.c
    +++ b/sys/security/mac_lomac/mac_lomac.c
    @@ -2470,7 +2470,7 @@ lomac_vnode_check_open(struct ucred *cred, struct vnode *vp,
     	obj = SLOT(vplabel);
     
     	/* XXX privilege override for admin? */
    -	if (accmode & (VWRITE | VAPPEND | VADMIN)) {
    +	if (accmode & VMODIFY_PERMS) {
     		if (!lomac_subject_dominate(subj, obj))
     			return (EACCES);
     	}
    
    From 78e32164b099aab2fbc1870824fcb0a524623ff2 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 16:31:49 +0000
    Subject: [PATCH 1698/2592] MFC r197405:
    
    Add pieces of infrastructure required for NFSv4 ACL support in UFS.
    
    Reviewed by:	rwatson
    ---
     sys/conf/files           |   1 +
     sys/kern/subr_acl_nfs4.c | 497 ++++++++++++++++++++++++++++++++++++++-
     sys/sys/vnode.h          |   3 +
     3 files changed, 499 insertions(+), 2 deletions(-)
    
    diff --git a/sys/conf/files b/sys/conf/files
    index b48801263b5..d4de3668a10 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -2098,6 +2098,7 @@ kern/sched_ule.c		optional sched_ule
     kern/serdev_if.m		standard
     kern/stack_protector.c		standard \
     	compile-with "${NORMAL_C:N-fstack-protector*}"
    +kern/subr_acl_nfs4.c		standard
     kern/subr_acl_posix1e.c		standard
     kern/subr_autoconf.c		standard
     kern/subr_blist.c		standard
    diff --git a/sys/kern/subr_acl_nfs4.c b/sys/kern/subr_acl_nfs4.c
    index 85609b98bd9..c3f4b65cbd5 100644
    --- a/sys/kern/subr_acl_nfs4.c
    +++ b/sys/kern/subr_acl_nfs4.c
    @@ -1,5 +1,5 @@
     /*-
    - * Copyright (c) 2008 Edward Tomasz Napierała 
    + * Copyright (c) 2008-2009 Edward Tomasz Napierała 
      * All rights reserved.
      *
      * Redistribution and use in source and binary forms, with or without
    @@ -49,7 +49,213 @@ __FBSDID("$FreeBSD$");
     #include 
     #define KASSERT(a, b) assert(a)
     #define CTASSERT(a)
    -#endif
    +#endif /* _KERNEL */
    +
    +#ifdef _KERNEL
    +
    +static struct {
    +	accmode_t accmode;
    +	int mask;
    +} accmode2mask[] = {{VREAD, ACL_READ_DATA},
    +		    {VWRITE, ACL_WRITE_DATA},
    +		    {VAPPEND, ACL_APPEND_DATA},
    +		    {VEXEC, ACL_EXECUTE},
    +		    {VREAD_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
    +		    {VWRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
    +		    {VDELETE_CHILD, ACL_DELETE_CHILD},
    +		    {VREAD_ATTRIBUTES, ACL_READ_ATTRIBUTES},
    +		    {VWRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
    +		    {VDELETE, ACL_DELETE},
    +		    {VREAD_ACL, ACL_READ_ACL},
    +		    {VWRITE_ACL, ACL_WRITE_ACL},
    +		    {VWRITE_OWNER, ACL_WRITE_OWNER},
    +		    {VSYNCHRONIZE, ACL_SYNCHRONIZE},
    +		    {0, 0}};
    +
    +static int
    +_access_mask_from_accmode(accmode_t accmode)
    +{
    +	int access_mask = 0, i;
    +
    +	for (i = 0; accmode2mask[i].accmode != 0; i++) {
    +		if (accmode & accmode2mask[i].accmode)
    +			access_mask |= accmode2mask[i].mask;
    +	}
    +
    +	return (access_mask);
    +}
    +
    +/*
    + * Return 0, iff access is allowed, 1 otherwise.
    + */
    +static int
    +_acl_denies(const struct acl *aclp, int access_mask, struct ucred *cred,
    +    int file_uid, int file_gid, int *denied_explicitly)
    +{
    +	int i;
    +	const struct acl_entry *entry;
    +
    +	if (denied_explicitly != NULL)
    +		*denied_explicitly = 0;
    +
    +	KASSERT(aclp->acl_cnt > 0, ("aclp->acl_cnt > 0"));
    +	KASSERT(aclp->acl_cnt <= ACL_MAX_ENTRIES,
    +	    ("aclp->acl_cnt <= ACL_MAX_ENTRIES"));
    +
    +	for (i = 0; i < aclp->acl_cnt; i++) {
    +		entry = &(aclp->acl_entry[i]);
    +
    +		if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW &&
    +		    entry->ae_entry_type != ACL_ENTRY_TYPE_DENY)
    +			continue;
    +		if (entry->ae_flags & ACL_ENTRY_INHERIT_ONLY)
    +			continue;
    +		switch (entry->ae_tag) {
    +		case ACL_USER_OBJ:
    +			if (file_uid != cred->cr_uid)
    +				continue;
    +			break;
    +		case ACL_USER:
    +			if (entry->ae_id != cred->cr_uid)
    +				continue;
    +			break;
    +		case ACL_GROUP_OBJ:
    +			if (!groupmember(file_gid, cred))
    +				continue;
    +			break;
    +		case ACL_GROUP:
    +			if (!groupmember(entry->ae_id, cred))
    +				continue;
    +			break;
    +		default:
    +			KASSERT(entry->ae_tag == ACL_EVERYONE,
    +			    ("entry->ae_tag == ACL_EVERYONE"));
    +		}
    +
    +		if (entry->ae_entry_type == ACL_ENTRY_TYPE_DENY) {
    +			if (entry->ae_perm & access_mask) {
    +				if (denied_explicitly != NULL)
    +					*denied_explicitly = 1;
    +				return (1);
    +			}
    +		}
    +
    +		access_mask &= ~(entry->ae_perm);
    +		if (access_mask == 0)
    +			return (0);
    +	}
    +
    +	return (1);
    +}
    +
    +int
    +vaccess_acl_nfs4(enum vtype type, uid_t file_uid, gid_t file_gid,
    +    struct acl *aclp, accmode_t accmode, struct ucred *cred, int *privused)
    +{
    +	accmode_t priv_granted = 0;
    +	int denied, explicitly_denied, access_mask, is_directory,
    +	    must_be_owner = 0;
    +
    +	if (privused != NULL)
    +		*privused = 0;
    +
    +	if (accmode & VADMIN)
    +		must_be_owner = 1;
    +
    +	/*
    +	 * Ignore VSYNCHRONIZE permission.
    +	 */
    +	accmode &= ~VSYNCHRONIZE;
    +
    +	access_mask = _access_mask_from_accmode(accmode);
    +
    +	if (type == VDIR)
    +		is_directory = 1;
    +	else
    +		is_directory = 0;
    +
    +	/*
    +	 * File owner is always allowed to read and write the ACL
    +	 * and basic attributes.  This is to prevent a situation
    +	 * where user would change ACL in a way that prevents him
    +	 * from undoing the change.
    +	 */
    +	if (file_uid == cred->cr_uid)
    +		access_mask &= ~(ACL_READ_ACL | ACL_WRITE_ACL |
    +		    ACL_READ_ATTRIBUTES | ACL_WRITE_ATTRIBUTES);
    +
    +	/*
    +	 * Ignore append permission for regular files; use write
    +	 * permission instead.
    +	 */
    +	if (!is_directory && (access_mask & ACL_APPEND_DATA)) {
    +		access_mask &= ~ACL_APPEND_DATA;
    +		access_mask |= ACL_WRITE_DATA;
    +	}
    +
    +	denied = _acl_denies(aclp, access_mask, cred, file_uid, file_gid,
    +	    &explicitly_denied);
    +
    +	if (must_be_owner) {
    +		if (file_uid != cred->cr_uid)
    +			denied = EPERM;
    +	}
    +
    +	if (!denied)
    +		return (0);
    +
    +	/*
    +	 * Access failed.  Iff it was not denied explicitly and
    +	 * VEXPLICIT_DENY flag was specified, allow access.
    +	 */
    +	if ((accmode & VEXPLICIT_DENY) && explicitly_denied == 0)
    +		return (0);
    +
    +	accmode &= ~VEXPLICIT_DENY;
    +
    +	/*
    +	 * No match.  Try to use privileges, if there are any.
    +	 */
    +	if (is_directory) {
    +		if ((accmode & VEXEC) && !priv_check_cred(cred,
    +		    PRIV_VFS_LOOKUP, 0))
    +			priv_granted |= VEXEC;
    +	} else {
    +		if ((accmode & VEXEC) && !priv_check_cred(cred,
    +		    PRIV_VFS_EXEC, 0))
    +			priv_granted |= VEXEC;
    +	}
    +
    +	if ((accmode & VREAD) && !priv_check_cred(cred, PRIV_VFS_READ, 0))
    +		priv_granted |= VREAD;
    +
    +	if ((accmode & (VWRITE | VAPPEND | VDELETE_CHILD)) &&
    +	    !priv_check_cred(cred, PRIV_VFS_WRITE, 0))
    +		priv_granted |= (VWRITE | VAPPEND | VDELETE_CHILD);
    +
    +	if ((accmode & VADMIN_PERMS) &&
    +	    !priv_check_cred(cred, PRIV_VFS_ADMIN, 0))
    +		priv_granted |= VADMIN_PERMS;
    +
    +	if ((accmode & VSTAT_PERMS) &&
    +	    !priv_check_cred(cred, PRIV_VFS_STAT, 0))
    +		priv_granted |= VSTAT_PERMS;
    +
    +	if ((accmode & priv_granted) == accmode) {
    +		if (privused != NULL)
    +			*privused = 1;
    +
    +		return (0);
    +	}
    +
    +	if (accmode & (VADMIN_PERMS | VDELETE_CHILD | VDELETE))
    +		denied = EPERM;
    +	else
    +		denied = EACCES;
    +
    +	return (denied);
    +}
    +#endif /* _KERNEL */
     
     static int
     _acl_entry_matches(struct acl_entry *entry, acl_tag_t tag, acl_perm_t perm,
    @@ -577,3 +783,290 @@ acl_nfs4_sync_mode_from_acl(mode_t *_mode, const struct acl *aclp)
     
     	*_mode = mode | (old_mode & ACL_PRESERVE_MASK);
     }
    +
    +void		
    +acl_nfs4_compute_inherited_acl(const struct acl *parent_aclp,
    +    struct acl *child_aclp, mode_t mode, int file_owner_id,
    +    int is_directory)
    +{
    +	int i, flags;
    +	const struct acl_entry *parent_entry;
    +	struct acl_entry *entry, *copy;
    +
    +	KASSERT(child_aclp->acl_cnt == 0, ("child_aclp->acl_cnt == 0"));
    +	KASSERT(parent_aclp->acl_cnt > 0, ("parent_aclp->acl_cnt > 0"));
    +	KASSERT(parent_aclp->acl_cnt <= ACL_MAX_ENTRIES,
    +	    ("parent_aclp->acl_cnt <= ACL_MAX_ENTRIES"));
    +
    +	/*
    +	 * NFSv4 Minor Version 1, draft-ietf-nfsv4-minorversion1-03.txt
    +	 *
    +	 * 3.16.6.2. Applying the mode given to CREATE or OPEN
    +	 *           to an inherited ACL
    +	 */
    +
    +	/*
    +	 * 1. Form an ACL that is the concatenation of all inheritable ACEs.
    +	 */
    +	for (i = 0; i < parent_aclp->acl_cnt; i++) {
    +		parent_entry = &(parent_aclp->acl_entry[i]);
    +		flags = parent_entry->ae_flags;
    +
    +		/*
    +		 * Entry is not inheritable at all.
    +		 */
    +		if ((flags & (ACL_ENTRY_DIRECTORY_INHERIT |
    +		    ACL_ENTRY_FILE_INHERIT)) == 0)
    +			continue;
    +
    +		/*
    +		 * We're creating a file, but entry is not inheritable
    +		 * by files.
    +		 */
    +		if (!is_directory && (flags & ACL_ENTRY_FILE_INHERIT) == 0)
    +			continue;
    +
    +		/*
    +		 * Entry is inheritable only by files, but has NO_PROPAGATE
    +		 * flag set, and we're creating a directory, so it wouldn't
    +		 * propagate to any file in that directory anyway.
    +		 */
    +		if (is_directory &&
    +		    (flags & ACL_ENTRY_DIRECTORY_INHERIT) == 0 &&
    +		    (flags & ACL_ENTRY_NO_PROPAGATE_INHERIT))
    +			continue;
    +
    +		KASSERT(child_aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES,
    +		    ("child_aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES"));
    +		child_aclp->acl_entry[child_aclp->acl_cnt] = *parent_entry;
    +		child_aclp->acl_cnt++;
    +	}
    +
    +	/*
    +	 * 2. For each entry in the new ACL, adjust its flags, possibly
    +	 *    creating two entries in place of one.
    +	 */
    +	for (i = 0; i < child_aclp->acl_cnt; i++) {
    +		entry = &(child_aclp->acl_entry[i]);
    +
    +		/*
    +		 * This is not in the specification, but SunOS
    +		 * apparently does that.
    +		 */
    +		if (((entry->ae_flags & ACL_ENTRY_NO_PROPAGATE_INHERIT) ||
    +		    !is_directory) &&
    +		    entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW)
    +			entry->ae_perm &= ~(ACL_WRITE_ACL | ACL_WRITE_OWNER);
    +
    +		/*
    +		 * 2.A. If the ACL_ENTRY_NO_PROPAGATE_INHERIT is set, or if the object
    +		 *      being created is not a directory, then clear the
    +		 *      following flags: ACL_ENTRY_NO_PROPAGATE_INHERIT,
    +		 *      ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT,
    +		 *      ACL_ENTRY_INHERIT_ONLY.
    +		 */
    +		if (entry->ae_flags & ACL_ENTRY_NO_PROPAGATE_INHERIT ||
    +		    !is_directory) {
    +			entry->ae_flags &= ~(ACL_ENTRY_NO_PROPAGATE_INHERIT |
    +			ACL_ENTRY_FILE_INHERIT | ACL_ENTRY_DIRECTORY_INHERIT |
    +			ACL_ENTRY_INHERIT_ONLY);
    +
    +			/*
    +			 * Continue on to the next ACE.
    +			 */
    +			continue;
    +		}
    +
    +		/*
    +		 * 2.B. If the object is a directory and ACL_ENTRY_FILE_INHERIT
    +		 *      is set, but ACL_ENTRY_NO_PROPAGATE_INHERIT is not set, ensure
    +		 *      that ACL_ENTRY_INHERIT_ONLY is set.  Continue to the
    +		 *      next ACE.  Otherwise...
    +		 */
    +		/*
    +		 * XXX: Read it again and make sure what does the "otherwise"
    +		 *      apply to.
    +		 */
    +		if (is_directory &&
    +		    (entry->ae_flags & ACL_ENTRY_FILE_INHERIT) &&
    +		    ((entry->ae_flags & ACL_ENTRY_DIRECTORY_INHERIT) == 0)) {
    +			entry->ae_flags |= ACL_ENTRY_INHERIT_ONLY;
    +			continue;
    +		}
    +
    +		/*
    +		 * 2.C. If the type of the ACE is neither ALLOW nor deny,
    +		 *      then continue.
    +		 */
    +		if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW &&
    +		    entry->ae_entry_type != ACL_ENTRY_TYPE_DENY)
    +			continue;
    +
    +		/*
    +		 * 2.D. Copy the original ACE into a second, adjacent ACE.
    +		 */
    +		copy = _acl_duplicate_entry(child_aclp, i);
    +
    +		/*
    +		 * 2.E. On the first ACE, ensure that ACL_ENTRY_INHERIT_ONLY
    +		 *      is set.
    +		 */
    +		entry->ae_flags |= ACL_ENTRY_INHERIT_ONLY;
    +
    +		/*
    +		 * 2.F. On the second ACE, clear the following flags:
    +		 *      ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_FILE_INHERIT,
    +		 *      ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_INHERIT_ONLY.
    +		 */
    +		copy->ae_flags &= ~(ACL_ENTRY_NO_PROPAGATE_INHERIT |
    +		    ACL_ENTRY_FILE_INHERIT | ACL_ENTRY_DIRECTORY_INHERIT |
    +		    ACL_ENTRY_INHERIT_ONLY);
    +
    +		/*
    +		 * 2.G. On the second ACE, if the type is ALLOW,
    +		 *      an implementation MAY clear the following
    +		 *      mask bits: ACL_WRITE_ACL, ACL_WRITE_OWNER.
    +		 */
    +		if (copy->ae_entry_type == ACL_ENTRY_TYPE_ALLOW)
    +			copy->ae_perm &= ~(ACL_WRITE_ACL | ACL_WRITE_OWNER);
    +
    +		/*
    +		 * Increment the counter to skip the copied entry.
    +		 */
    +		i++;
    +	}
    +
    +	/*
    +	 * 3. To ensure that the mode is honored, apply the algorithm describe
    +	 *    in Section 2.16.6.3, using the mode that is to be used for file
    +	 *    creation.
    +	 */
    +	acl_nfs4_sync_acl_from_mode(child_aclp, mode, file_owner_id);
    +}
    +
    +#ifdef _KERNEL
    +static int
    +_acls_are_equal(const struct acl *a, const struct acl *b)
    +{
    +	int i;
    +	const struct acl_entry *entrya, *entryb;
    +
    +	if (a->acl_cnt != b->acl_cnt)
    +		return (0);
    +
    +	for (i = 0; i < b->acl_cnt; i++) {
    +		entrya = &(a->acl_entry[i]);
    +		entryb = &(b->acl_entry[i]);
    +
    +		if (entrya->ae_tag != entryb->ae_tag ||
    +		    entrya->ae_id != entryb->ae_id ||
    +		    entrya->ae_perm != entryb->ae_perm ||
    +		    entrya->ae_entry_type != entryb->ae_entry_type ||
    +		    entrya->ae_flags != entryb->ae_flags)
    +			return (0);
    +	}
    +
    +	return (1);
    +}
    +
    +/*
    + * This routine is used to determine whether to remove entry_type attribute
    + * that stores ACL contents.
    + */
    +int
    +acl_nfs4_is_trivial(const struct acl *aclp, int file_owner_id)
    +{
    +	int trivial;
    +	mode_t tmpmode = 0;
    +	struct acl *tmpaclp;
    +
    +	if (aclp->acl_cnt != 6)
    +		return (0);
    +
    +	/*
    +	 * Compute the mode from the ACL, then compute new ACL from that mode.
    +	 * If the ACLs are identical, then the ACL is trivial.
    +	 *
    +	 * XXX: I guess there is a faster way to do this.  However, even
    +	 *      this slow implementation significantly speeds things up
    +	 *      for files that don't have any entry_type ACL entries - it's
    +	 *      critical for performance to not use EA when they are not
    +	 *      needed.
    +	 */
    +	tmpaclp = acl_alloc(M_WAITOK | M_ZERO);
    +	acl_nfs4_sync_mode_from_acl(&tmpmode, aclp);
    +	acl_nfs4_sync_acl_from_mode(tmpaclp, tmpmode, file_owner_id);
    +	trivial = _acls_are_equal(aclp, tmpaclp);
    +	acl_free(tmpaclp);
    +
    +	return (trivial);
    +}
    +#endif /* _KERNEL */
    +
    +int
    +acl_nfs4_check(const struct acl *aclp, int is_directory)
    +{
    +	int i;
    +	const struct acl_entry *entry;
    +
    +	/*
    +	 * The spec doesn't seem to say anything about ACL validity.
    +	 * It seems there is not much to do here.  There is even no need
    +	 * to count "owner@" or "everyone@" (ACL_USER_OBJ and ACL_EVERYONE)
    +	 * entries, as there can be several of them and that's perfectly
    +	 * valid.  There can be none of them too.  Really.
    +	 */
    +
    +	if (aclp->acl_cnt > ACL_MAX_ENTRIES || aclp->acl_cnt <= 0)
    +		return (EINVAL);
    +
    +	for (i = 0; i < aclp->acl_cnt; i++) {
    +		entry = &(aclp->acl_entry[i]);
    +
    +		switch (entry->ae_tag) {
    +		case ACL_USER_OBJ:
    +		case ACL_GROUP_OBJ:
    +		case ACL_EVERYONE:
    +			if (entry->ae_id != ACL_UNDEFINED_ID)
    +				return (EINVAL);
    +			break;
    +
    +		case ACL_USER:
    +		case ACL_GROUP:
    +			if (entry->ae_id == ACL_UNDEFINED_ID)
    +				return (EINVAL);
    +			break;
    +
    +		default:
    +			return (EINVAL);
    +		}
    +
    +		if ((entry->ae_perm | ACL_NFS4_PERM_BITS) != ACL_NFS4_PERM_BITS)
    +			return (EINVAL);
    +
    +		/*
    +		 * Disallow ACL_ENTRY_TYPE_AUDIT and ACL_ENTRY_TYPE_ALARM for now.
    +		 */
    +		if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW &&
    +		    entry->ae_entry_type != ACL_ENTRY_TYPE_DENY)
    +			return (EINVAL);
    +
    +		if ((entry->ae_flags | ACL_FLAGS_BITS) != ACL_FLAGS_BITS)
    +			return (EINVAL);
    +
    +		/* Disallow unimplemented flags. */
    +		if (entry->ae_flags & (ACL_ENTRY_SUCCESSFUL_ACCESS |
    +		    ACL_ENTRY_FAILED_ACCESS))
    +			return (EINVAL);
    +
    +		/* Disallow flags not allowed for ordinary files. */
    +		if (!is_directory) {
    +			if (entry->ae_flags & (ACL_ENTRY_FILE_INHERIT |
    +			    ACL_ENTRY_DIRECTORY_INHERIT |
    +			    ACL_ENTRY_NO_PROPAGATE_INHERIT | ACL_ENTRY_INHERIT_ONLY))
    +				return (EINVAL);
    +		}
    +	}
    +
    +	return (0);
    +}
    diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
    index 96482bce5e9..8676f0fd653 100644
    --- a/sys/sys/vnode.h
    +++ b/sys/sys/vnode.h
    @@ -613,6 +613,9 @@ int	vn_commname(struct vnode *vn, char *buf, u_int buflen);
     int	vaccess(enum vtype type, mode_t file_mode, uid_t file_uid,
     	    gid_t file_gid, accmode_t accmode, struct ucred *cred,
     	    int *privused);
    +int	vaccess_acl_nfs4(enum vtype type, uid_t file_uid, gid_t file_gid,
    +	    struct acl *aclp, accmode_t accmode, struct ucred *cred,
    +	    int *privused);
     int	vaccess_acl_posix1e(enum vtype type, uid_t file_uid,
     	    gid_t file_gid, struct acl *acl, accmode_t accmode,
     	    struct ucred *cred, int *privused);
    
    From e8db8028648ecd20afe2497dd03c1a7dfc1316f1 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 16:35:25 +0000
    Subject: [PATCH 1699/2592] MFC r197650:
    
    Fix typo in the comment.
    ---
     sys/fs/nfs/nfs_commonacl.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/fs/nfs/nfs_commonacl.c b/sys/fs/nfs/nfs_commonacl.c
    index 3127ca4cbae..1994c005096 100644
    --- a/sys/fs/nfs/nfs_commonacl.c
    +++ b/sys/fs/nfs/nfs_commonacl.c
    @@ -631,7 +631,7 @@ nfsrv_setacl(vnode_t vp, NFSACL_T *aclp, struct ucred *cred,
     	if (nfsrv_useacl == 0 || !NFSHASNFS4ACL(vnode_mount(vp)))
     		return (NFSERR_ATTRNOTSUPP);
     	/*
    -	 * With NFS4 ACLs, chmod(2) may need to add additional entries.
    +	 * With NFSv4 ACLs, chmod(2) may need to add additional entries.
     	 * Make sure it has enough room for that - splitting every entry
     	 * into two and appending "canonical six" entries at the end.
     	 * Cribbed out of kern/vfs_acl.c - Rick M.
    
    From 90d592712567ed9a58e6011e9557be559de83e2e Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 16:41:23 +0000
    Subject: [PATCH 1700/2592] MFC r197405, missing part:
    
    Add pieces of infrastructure required for NFSv4 ACL support in UFS.
    
    Reviewed by:	rwatson
    ---
     share/man/man9/Makefile           |   1 +
     share/man/man9/VOP_ACCESS.9       |   3 +-
     share/man/man9/acl.9              |   3 +-
     share/man/man9/vaccess.9          |   3 +-
     share/man/man9/vaccess_acl_nfs4.9 | 129 ++++++++++++++++++++++++++++++
     5 files changed, 136 insertions(+), 3 deletions(-)
     create mode 100644 share/man/man9/vaccess_acl_nfs4.9
    
    diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
    index 8af826cab4f..65d9e8de202 100644
    --- a/share/man/man9/Makefile
    +++ b/share/man/man9/Makefile
    @@ -255,6 +255,7 @@ MAN=	accept_filter.9 \
     	usbdi.9 \
     	utopia.9 \
     	vaccess.9 \
    +	vaccess_acl_nfs4.9 \
     	vaccess_acl_posix1e.9 \
     	vcount.9 \
     	vflush.9 \
    diff --git a/share/man/man9/VOP_ACCESS.9 b/share/man/man9/VOP_ACCESS.9
    index 533cd50ab3e..927c1187ce1 100644
    --- a/share/man/man9/VOP_ACCESS.9
    +++ b/share/man/man9/VOP_ACCESS.9
    @@ -29,7 +29,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd June 1, 2009
    +.Dd September 18, 2009
     .Os
     .Dt VOP_ACCESS 9
     .Sh NAME
    @@ -95,6 +95,7 @@ requested access.
     .El
     .Sh SEE ALSO
     .Xr vaccess 9 ,
    +.Xr vaccess_acl_nfs4 9 ,
     .Xr vaccess_acl_posix1e 9 ,
     .Xr vnode 9
     .Sh AUTHORS
    diff --git a/share/man/man9/acl.9 b/share/man/man9/acl.9
    index c7ba84016b3..c5192fc8b14 100644
    --- a/share/man/man9/acl.9
    +++ b/share/man/man9/acl.9
    @@ -25,7 +25,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd December 23, 1999
    +.Dd September 18, 2009
     .Os
     .Dt ACL 9
     .Sh NAME
    @@ -207,6 +207,7 @@ The following values are valid:
     .El
     .Sh SEE ALSO
     .Xr acl 3 ,
    +.Xr vaccess_acl_nfs4 9 ,
     .Xr vaccess_acl_posix1e 9 ,
     .Xr VFS 9 ,
     .Xr vnaccess 9 ,
    diff --git a/share/man/man9/vaccess.9 b/share/man/man9/vaccess.9
    index 5315d982f6e..a2e2ec5b72a 100644
    --- a/share/man/man9/vaccess.9
    +++ b/share/man/man9/vaccess.9
    @@ -25,7 +25,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd August 22, 2001
    +.Dd September 18, 2009
     .Os
     .Dt VACCESS 9
     .Sh NAME
    @@ -117,6 +117,7 @@ An attempt was made to perform an operation limited to processes with
     appropriate privileges or to the owner of a file or other resource.
     .El
     .Sh SEE ALSO
    +.Xr vaccess_acl_nfs4 9 ,
     .Xr vaccess_acl_posix1e 9 ,
     .Xr vnode 9 ,
     .Xr VOP_ACCESS 9
    diff --git a/share/man/man9/vaccess_acl_nfs4.9 b/share/man/man9/vaccess_acl_nfs4.9
    new file mode 100644
    index 00000000000..32cbdb3a940
    --- /dev/null
    +++ b/share/man/man9/vaccess_acl_nfs4.9
    @@ -0,0 +1,129 @@
    +.\"-
    +.\" Copyright (c) 2001 Robert N. M. Watson
    +.\" 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 September 18, 2009
    +.Os
    +.Dt VACCESS_ACL_NFS4 9
    +.Sh NAME
    +.Nm vaccess_acl_nfs4
    +.Nd generate a NFSv4 ACL access control decision using vnode parameters
    +.Sh SYNOPSIS
    +.In sys/param.h
    +.In sys/vnode.h
    +.In sys/acl.h
    +.Ft int
    +.Fo vaccess_acl_nfs4
    +.Fa "enum vtype type"
    +.Fa "uid_t file_uid"
    +.Fa "gid_t file_gid"
    +.Fa "struct acl *acl"
    +.Fa "accmode_t accmode"
    +.Fa "struct ucred *cred"
    +.Fa "int *privused"
    +.Fc
    +.Sh DESCRIPTION
    +This call implements the logic for the
    +.Ux
    +discretionary file security model
    +with NFSv4 ACL extensions.
    +It accepts the vnodes type
    +.Fa type ,
    +owning UID
    +.Fa file_uid ,
    +owning GID
    +.Fa file_gid ,
    +access ACL for the file
    +.Fa acl ,
    +desired access mode
    +.Fa accmode ,
    +requesting credential
    +.Fa cred ,
    +and an optional call-by-reference
    +.Vt int
    +pointer returning whether or not
    +privilege was required for successful evaluation of the call; the
    +.Fa privused
    +pointer may be set to
    +.Dv NULL
    +by the caller in order not to be informed of
    +privilege information, or it may point to an integer that will be set to
    +1 if privilege is used, and 0 otherwise.
    +.Pp
    +This call is intended to support implementations of
    +.Xr VOP_ACCESS 9 ,
    +which will use their own access methods to retrieve the vnode properties,
    +and then invoke
    +.Fn vaccess_acl_nfs4
    +in order to perform the actual check.
    +Implementations of
    +.Xr VOP_ACCESS 9
    +may choose to implement additional security mechanisms whose results will
    +be composed with the return value.
    +.Pp
    +The algorithm used by
    +.Fn vaccess_acl_nfs4
    +is based on the NFSv4 ACL evaluation algorithm, as described in
    +NFSv4 Minor Version 1, draft-ietf-nfsv4-minorversion1-21.txt.
    +The algorithm selects a
    +.Em matching
    +entry from the access ACL, which may
    +then be composed with an available ACL mask entry, providing
    +.Ux
    +security compatibility.
    +.Pp
    +Once appropriate protections are selected for the current credential,
    +the requested access mode, in combination with the vnode type, will be
    +compared with the discretionary rights available for the credential.
    +If the rights granted by discretionary protections are insufficient,
    +then super-user privilege, if available for the credential, will also be
    +considered.
    +.Sh RETURN VALUES
    +.Fn vaccess_acl_nfs4
    +will return 0 on success, or a non-zero error value on failure.
    +.Sh ERRORS
    +.Bl -tag -width Er
    +.It Bq Er EACCES
    +Permission denied.
    +An attempt was made to access a file in a way forbidden by its file access
    +permissions.
    +.It Bq Er EPERM
    +Operation not permitted.
    +An attempt was made to perform an operation limited to processes with
    +appropriate privileges or to the owner of a file or other resource.
    +.El
    +.Sh SEE ALSO
    +.Xr vaccess 9 ,
    +.Xr vnode 9 ,
    +.Xr VOP_ACCESS 9
    +.Sh AUTHORS
    +Current implementation of
    +.Fn vaccess_acl_nfs4
    +was written by
    +.An Edward Tomasz Napierala Aq trasz@FreeBSD.org .
    +.Sh BUGS
    +This manual page should include a full description of the NFSv4 ACL
    +evaluation algorithm, or cross reference another page that does.
    
    From cbd7567e6bdda5be484e72c4308daf4d3439b1ba Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:11:06 +0000
    Subject: [PATCH 1701/2592] MFC r202123:
    
      Change DDB show prison:
      - name some columns more closely to the user space variables,
        as we do for host.* or allow.* (in the listing) already.
      - print pr_childmax (children.max).
      - prefix hex values with 0x.
    ---
     sys/kern/kern_jail.c | 11 ++++++-----
     1 file changed, 6 insertions(+), 5 deletions(-)
    
    diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
    index f10522e2e28..93fdfa9303b 100644
    --- a/sys/kern/kern_jail.c
    +++ b/sys/kern/kern_jail.c
    @@ -4276,10 +4276,11 @@ db_show_prison(struct prison *pr)
     #endif
     	db_printf(" root            = %p\n", pr->pr_root);
     	db_printf(" securelevel     = %d\n", pr->pr_securelevel);
    -	db_printf(" childcount      = %d\n", pr->pr_childcount);
    +	db_printf(" children.max    = %d\n", pr->pr_childmax);
    +	db_printf(" children.cur    = %d\n", pr->pr_childcount);
     	db_printf(" child           = %p\n", LIST_FIRST(&pr->pr_children));
     	db_printf(" sibling         = %p\n", LIST_NEXT(pr, pr_sibling));
    -	db_printf(" flags           = %x", pr->pr_flags);
    +	db_printf(" flags           = 0x%x", pr->pr_flags);
     	for (fi = 0; fi < sizeof(pr_flag_names) / sizeof(pr_flag_names[0]);
     	    fi++)
     		if (pr_flag_names[fi] != NULL && (pr->pr_flags & (1 << fi)))
    @@ -4294,7 +4295,7 @@ db_show_prison(struct prison *pr)
     		    : (jsf == pr_flag_jailsys[fi].new) ? "new"
     		    : "inherit");
     	}
    -	db_printf(" allow           = %x", pr->pr_allow);
    +	db_printf(" allow           = 0x%x", pr->pr_allow);
     	for (fi = 0; fi < sizeof(pr_allow_names) / sizeof(pr_allow_names[0]);
     	    fi++)
     		if (pr_allow_names[fi] != NULL && (pr->pr_allow & (1 << fi)))
    @@ -4309,14 +4310,14 @@ db_show_prison(struct prison *pr)
     	db_printf(" ip4s            = %d\n", pr->pr_ip4s);
     	for (ii = 0; ii < pr->pr_ip4s; ii++)
     		db_printf(" %s %s\n",
    -		    ii == 0 ? "ip4             =" : "                 ",
    +		    ii == 0 ? "ip4.addr        =" : "                 ",
     		    inet_ntoa(pr->pr_ip4[ii]));
     #endif
     #ifdef INET6
     	db_printf(" ip6s            = %d\n", pr->pr_ip6s);
     	for (ii = 0; ii < pr->pr_ip6s; ii++)
     		db_printf(" %s %s\n",
    -		    ii == 0 ? "ip6             =" : "                 ",
    +		    ii == 0 ? "ip6.addr        =" : "                 ",
     		    ip6_sprintf(ip6buf, &pr->pr_ip6[ii]));
     #endif
     }
    
    From 1a52f90b23510c52e756c1c5c6f60e5cc60c3213 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:14:55 +0000
    Subject: [PATCH 1702/2592] MFC r201813:
    
      In sys//conf/Makefile set TARGET to . That allows
      sys/conf/makeLINT.mk to only do certain things for certain
      architectures.
    
      Note that neither arm nor mips have the Makefile there, thus
      essentially not (yet) supporting LINT.  This would enable them
      do add special treatment to sys/conf/makeLINT.mk as well chosing
      one of the many configurations as LINT.
    ---
     sys/amd64/conf/Makefile   | 2 ++
     sys/i386/conf/Makefile    | 2 ++
     sys/ia64/conf/Makefile    | 2 ++
     sys/pc98/conf/Makefile    | 2 ++
     sys/powerpc/conf/Makefile | 2 ++
     sys/sparc64/conf/Makefile | 2 ++
     sys/sun4v/conf/Makefile   | 2 ++
     7 files changed, 14 insertions(+)
    
    diff --git a/sys/amd64/conf/Makefile b/sys/amd64/conf/Makefile
    index 2c006e9c2c8..1d2513f2abf 100644
    --- a/sys/amd64/conf/Makefile
    +++ b/sys/amd64/conf/Makefile
    @@ -1,3 +1,5 @@
     # $FreeBSD$
     
    +TARGET=amd64
    +
     .include "${.CURDIR}/../../conf/makeLINT.mk"
    diff --git a/sys/i386/conf/Makefile b/sys/i386/conf/Makefile
    index 2c006e9c2c8..e04b0abe62f 100644
    --- a/sys/i386/conf/Makefile
    +++ b/sys/i386/conf/Makefile
    @@ -1,3 +1,5 @@
     # $FreeBSD$
     
    +TARGET=i386
    +
     .include "${.CURDIR}/../../conf/makeLINT.mk"
    diff --git a/sys/ia64/conf/Makefile b/sys/ia64/conf/Makefile
    index 2c006e9c2c8..122a7d09c25 100644
    --- a/sys/ia64/conf/Makefile
    +++ b/sys/ia64/conf/Makefile
    @@ -1,3 +1,5 @@
     # $FreeBSD$
     
    +TARGET=ia64
    +
     .include "${.CURDIR}/../../conf/makeLINT.mk"
    diff --git a/sys/pc98/conf/Makefile b/sys/pc98/conf/Makefile
    index 2c006e9c2c8..dabcd9a48a5 100644
    --- a/sys/pc98/conf/Makefile
    +++ b/sys/pc98/conf/Makefile
    @@ -1,3 +1,5 @@
     # $FreeBSD$
     
    +TARGET=pc98
    +
     .include "${.CURDIR}/../../conf/makeLINT.mk"
    diff --git a/sys/powerpc/conf/Makefile b/sys/powerpc/conf/Makefile
    index 2c006e9c2c8..562bc4693cd 100644
    --- a/sys/powerpc/conf/Makefile
    +++ b/sys/powerpc/conf/Makefile
    @@ -1,3 +1,5 @@
     # $FreeBSD$
     
    +TARGET=powerpc
    +
     .include "${.CURDIR}/../../conf/makeLINT.mk"
    diff --git a/sys/sparc64/conf/Makefile b/sys/sparc64/conf/Makefile
    index 2c006e9c2c8..b0b5857849c 100644
    --- a/sys/sparc64/conf/Makefile
    +++ b/sys/sparc64/conf/Makefile
    @@ -1,3 +1,5 @@
     # $FreeBSD$
     
    +TARGET=sparc64
    +
     .include "${.CURDIR}/../../conf/makeLINT.mk"
    diff --git a/sys/sun4v/conf/Makefile b/sys/sun4v/conf/Makefile
    index 2c006e9c2c8..1c33841c248 100644
    --- a/sys/sun4v/conf/Makefile
    +++ b/sys/sun4v/conf/Makefile
    @@ -1,3 +1,5 @@
     # $FreeBSD$
     
    +TARGET=sun4v
    +
     .include "${.CURDIR}/../../conf/makeLINT.mk"
    
    From f0dd3ce0879d63ccb821f2d64944fb096d7f5477 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:17:11 +0000
    Subject: [PATCH 1703/2592] MFC r201814:
    
      Generate a second LINT configuration for i386 and amd64 in
      sys/conf/makeLINT.mk, which includes LINT and sets options VIMAGE
      so that we will have VIMAGE LINT builds. For now only do it for
      those two architectures to avoid massive universe times for archs,
      where people will less likely use VIMAGE or not at all.
    ---
     sys/conf/makeLINT.mk | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/sys/conf/makeLINT.mk b/sys/conf/makeLINT.mk
    index 08947a91db0..e7ca9092193 100644
    --- a/sys/conf/makeLINT.mk
    +++ b/sys/conf/makeLINT.mk
    @@ -5,7 +5,15 @@ all:
     
     clean:
     	rm -f LINT
    +.if ${TARGET} == "amd64" || ${TARGET} == "i386"
    +	rm -f LINT-VIMAGE
    +.endif
     
     NOTES=	../../conf/NOTES NOTES
     LINT: ${NOTES} ../../conf/makeLINT.sed
     	cat ${NOTES} | sed -E -n -f ../../conf/makeLINT.sed > ${.TARGET}
    +.if ${TARGET} == "amd64" || ${TARGET} == "i386"
    +	echo "include ${.TARGET}"	>  ${.TARGET}-VIMAGE
    +	echo "ident ${.TARGET}-VIMAGE"	>> ${.TARGET}-VIMAGE
    +	echo "options VIMAGE"		>> ${.TARGET}-VIMAGE
    +.endif
    
    From 456f25942f4f914222e449e2934f3ecdc8f435ff Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:22:08 +0000
    Subject: [PATCH 1704/2592] MFC r201815:
    
      To avoid hardcoding further kernel configuration names for
      make universe, split the logic into two parts:
      - 1st to build worlds and generate kernel configs like LINT.
      - 2nd to build kernels for a given TARGET architecture correctly
        finding all newly generated configs, not knowing anything about
        LINT anymore.
    
    MFC rr201960:
    
      Use uname -m [1] and rename BUILD_ARCH to XMACHINE[2].
    
      Submitted by: nyan[1], imp[2]
    
    MFC r202095:
    
      Rather than using an extra variable, only call uname if really needed and
      then directly assign the result.
    
      Submitted by: jmallett
    ---
     Makefile | 28 +++++++++++++++++-----------
     1 file changed, 17 insertions(+), 11 deletions(-)
    
    diff --git a/Makefile b/Makefile
    index ebaeb6d49c6..bd267162386 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -278,7 +278,7 @@ tinderbox:
     # with a reasonable chance of success, regardless of how old your
     # existing system is.
     #
    -.if make(universe) || make(tinderbox)
    +.if make(universe) || make(universe_kernels) || make(tinderbox)
     TARGETS?=amd64 arm i386 ia64 mips pc98 powerpc sparc64 sun4v
     
     .if defined(DOING_TINDERBOX)
    @@ -297,10 +297,6 @@ universe_prologue:
     	rm -f ${FAILFILE}
     .endif
     .for target in ${TARGETS}
    -KERNCONFS!=	cd ${.CURDIR}/sys/${target}/conf && \
    -		find [A-Z0-9]*[A-Z0-9] -type f -maxdepth 0 \
    -		! -name DEFAULTS ! -name LINT
    -KERNCONFS:=	${KERNCONFS:S/^NOTES$/LINT/}
     universe: universe_${target}
     .ORDER: universe_prologue universe_${target} universe_epilogue
     universe_${target}:
    @@ -320,16 +316,26 @@ universe_${target}:
     	    (echo "${target} 'make LINT' failed," \
     	    "check _.${target}.makeLINT for details"| ${MAKEFAIL}))
     .endif
    +	@cd ${.CURDIR} && ${MAKE} ${.MAKEFLAGS} TARGET=${target} \
    +	    universe_kernels
    +	@echo ">> ${target} completed on `LC_ALL=C date`"
    +.endfor
    +universe_kernels: universe_kernconfs
    +.if !defined(TARGET)
    +TARGET!=	uname -m
    +.endif
    +KERNCONFS!=	cd ${.CURDIR}/sys/${TARGET}/conf && \
    +		find [A-Z0-9]*[A-Z0-9] -type f -maxdepth 0 \
    +		! -name DEFAULTS ! -name NOTES
    +universe_kernconfs:
     .for kernel in ${KERNCONFS}
     	@(cd ${.CURDIR} && env __MAKE_CONF=/dev/null \
     	    ${MAKE} ${JFLAG} buildkernel \
    -	    TARGET=${target} \
    +	    TARGET=${TARGET} \
     	    KERNCONF=${kernel} \
    -	    > _.${target}.${kernel} 2>&1 || \
    -	    (echo "${target} ${kernel} kernel failed," \
    -	    "check _.${target}.${kernel} for details"| ${MAKEFAIL}))
    -.endfor
    -	@echo ">> ${target} completed on `LC_ALL=C date`"
    +	    > _.${TARGET}.${kernel} 2>&1 || \
    +	    (echo "${TARGET} ${kernel} kernel failed," \
    +	    "check _.${TARGET}.${kernel} for details"| ${MAKEFAIL}))
     .endfor
     universe: universe_epilogue
     universe_epilogue:
    
    From bd7ae20991813bf44f86f8ad9e7490f7941b12f0 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 17:22:11 +0000
    Subject: [PATCH 1705/2592] MFC r197680:
    
    Provide default implementation for VOP_ACCESS(9), so that filesystems which
    want to provide VOP_ACCESSX(9) don't have to implement both.  Note that
    this commit makes implementation of either of these two mandatory.
    
    Reviewed by:	kib
    ---
     sys/fs/fifofs/fifo_vnops.c  |  1 -
     sys/kern/subr_acl_posix1e.c |  3 +++
     sys/kern/vfs_default.c      | 15 +++++++++++++++
     sys/kern/vfs_subr.c         |  3 +++
     sys/sys/vnode.h             |  1 +
     5 files changed, 22 insertions(+), 1 deletion(-)
    
    diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
    index 224536fb23e..7dbceee85e7 100644
    --- a/sys/fs/fifofs/fifo_vnops.c
    +++ b/sys/fs/fifofs/fifo_vnops.c
    @@ -114,7 +114,6 @@ static struct filterops fifo_notsup_filtops =
     struct vop_vector fifo_specops = {
     	.vop_default =		&default_vnodeops,
     
    -	.vop_access =		VOP_EBADF,
     	.vop_advlock =		fifo_advlock,
     	.vop_close =		fifo_close,
     	.vop_create =		VOP_PANIC,
    diff --git a/sys/kern/subr_acl_posix1e.c b/sys/kern/subr_acl_posix1e.c
    index e0016e7e767..9690580e3d8 100644
    --- a/sys/kern/subr_acl_posix1e.c
    +++ b/sys/kern/subr_acl_posix1e.c
    @@ -61,6 +61,9 @@ vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
     	accmode_t acl_mask_granted;
     	int group_matched, i;
     
    +	KASSERT((accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | VAPPEND)) == 0,
    +	    ("invalid bit in accmode"));
    +
     	/*
     	 * Look for a normal, non-privileged way to access the file/directory
     	 * as requested.  If it exists, go with that.  Otherwise, attempt to
    diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
    index 86ab01eb034..b80d03d0e9e 100644
    --- a/sys/kern/vfs_default.c
    +++ b/sys/kern/vfs_default.c
    @@ -83,12 +83,17 @@ static int	dirent_exists(struct vnode *vp, const char *dirname,
      *
      * If there is no specific entry here, we will return EOPNOTSUPP.
      *
    + * Note that every filesystem has to implement either vop_access
    + * or vop_accessx; failing to do so will result in immediate crash
    + * due to stack overflow, as vop_stdaccess() calls vop_stdaccessx(),
    + * which calls vop_stdaccess() etc.
      */
     
     struct vop_vector default_vnodeops = {
     	.vop_default =		NULL,
     	.vop_bypass =		VOP_EOPNOTSUPP,
     
    +	.vop_access =		vop_stdaccess,
     	.vop_accessx =		vop_stdaccessx,
     	.vop_advlock =		vop_stdadvlock,
     	.vop_advlockasync =	vop_stdadvlockasync,
    @@ -325,6 +330,16 @@ out:
     	return (found);
     }
     
    +int
    +vop_stdaccess(struct vop_access_args *ap)
    +{
    +
    +	KASSERT((ap->a_accmode & ~(VEXEC | VWRITE | VREAD | VADMIN |
    +	    VAPPEND)) == 0, ("invalid bit in accmode"));
    +
    +	return (VOP_ACCESSX(ap->a_vp, ap->a_accmode, ap->a_cred, ap->a_td));
    +}
    +
     int
     vop_stdaccessx(struct vop_accessx_args *ap)
     {
    diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
    index a9c1a247ef2..cf73dff0458 100644
    --- a/sys/kern/vfs_subr.c
    +++ b/sys/kern/vfs_subr.c
    @@ -3523,6 +3523,9 @@ vaccess(enum vtype type, mode_t file_mode, uid_t file_uid, gid_t file_gid,
     	accmode_t dac_granted;
     	accmode_t priv_granted;
     
    +	KASSERT((accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | VAPPEND)) == 0,
    +	    ("invalid bit in accmode"));
    +
     	/*
     	 * Look for a normal, non-privileged way to access the file/directory
     	 * as requested.  If it exists, go with that.
    diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
    index 8676f0fd653..4c84ea30ebe 100644
    --- a/sys/sys/vnode.h
    +++ b/sys/sys/vnode.h
    @@ -685,6 +685,7 @@ int	vop_stdlock(struct vop_lock1_args *);
     int	vop_stdputpages(struct vop_putpages_args *);
     int	vop_stdunlock(struct vop_unlock_args *);
     int	vop_nopoll(struct vop_poll_args *);
    +int	vop_stdaccess(struct vop_access_args *ap);
     int	vop_stdaccessx(struct vop_accessx_args *ap);
     int	vop_stdadvlock(struct vop_advlock_args *ap);
     int	vop_stdadvlockasync(struct vop_advlockasync_args *ap);
    
    From 90a7b167a8c3491ac9f676aabb457ca825f6ada2 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 17:25:17 +0000
    Subject: [PATCH 1706/2592] MFC r197780:
    
    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 65d9e8de202..bf9deff1902 100644
    --- a/share/man/man9/Makefile
    +++ b/share/man/man9/Makefile
    @@ -610,8 +610,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 \
    @@ -1147,8 +1149,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 ef18ad7e2db15e847869363b7046400747556d21 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:26:31 +0000
    Subject: [PATCH 1707/2592] MFC r203724:
    
      Properly free resources when destroying the TCP hostcache while
      tearing down a network stack (in the VIMAGE jail+vnet case).
    
      For that break out the logic from tcp_hc_purge() into an internal
      function we can call from both, the sysctl handler and the
      tcp_hc_destroy().
    
      Reviewed by:  silby, lstewart
    ---
     sys/netinet/tcp_hostcache.c | 44 +++++++++++++++++++++++++++----------
     1 file changed, 32 insertions(+), 12 deletions(-)
    
    diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c
    index acbc860a26e..a0c4012f21f 100644
    --- a/sys/netinet/tcp_hostcache.c
    +++ b/sys/netinet/tcp_hostcache.c
    @@ -115,6 +115,7 @@ static VNET_DEFINE(struct callout, tcp_hc_callout);
     static struct hc_metrics *tcp_hc_lookup(struct in_conninfo *);
     static struct hc_metrics *tcp_hc_insert(struct in_conninfo *);
     static int sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS);
    +static void tcp_hc_purge_internal(int);
     static void tcp_hc_purge(void *);
     
     SYSCTL_NODE(_net_inet_tcp, OID_AUTO, hostcache, CTLFLAG_RW, 0,
    @@ -235,10 +236,19 @@ tcp_hc_init(void)
     void
     tcp_hc_destroy(void)
     {
    -
    -	/* XXX TODO walk the hashtable and free all entries  */
    +	int i;
     
     	callout_drain(&V_tcp_hc_callout);
    +
    +	/* Purge all hc entries. */
    +	tcp_hc_purge_internal(1);
    +
    +	/* Free the uma zone and the allocated hash table. */
    +	uma_zdestroy(V_tcp_hostcache.zone);
    +
    +	for (i = 0; i < V_tcp_hostcache.hashsize; i++)
    +		mtx_destroy(&V_tcp_hostcache.hashbase[i].hch_mtx);
    +	free(V_tcp_hostcache.hashbase, M_HOSTCACHE);
     }
     #endif
     
    @@ -633,22 +643,14 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
     }
     
     /*
    - * Expire and purge (old|all) entries in the tcp_hostcache.  Runs
    - * periodically from the callout.
    + * Caller has to make sure the curvnet is set properly.
      */
     static void
    -tcp_hc_purge(void *arg)
    +tcp_hc_purge_internal(int all)
     {
    -	CURVNET_SET((struct vnet *) arg);
     	struct hc_metrics *hc_entry, *hc_next;
    -	int all = 0;
     	int i;
     
    -	if (V_tcp_hostcache.purgeall) {
    -		all = 1;
    -		V_tcp_hostcache.purgeall = 0;
    -	}
    -
     	for (i = 0; i < V_tcp_hostcache.hashsize; i++) {
     		THC_LOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
     		TAILQ_FOREACH_SAFE(hc_entry,
    @@ -664,6 +666,24 @@ tcp_hc_purge(void *arg)
     		}
     		THC_UNLOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
     	}
    +}
    +
    +/*
    + * Expire and purge (old|all) entries in the tcp_hostcache.  Runs
    + * periodically from the callout.
    + */
    +static void
    +tcp_hc_purge(void *arg)
    +{
    +	CURVNET_SET((struct vnet *) arg);
    +	int all = 0;
    +
    +	if (V_tcp_hostcache.purgeall) {
    +		all = 1;
    +		V_tcp_hostcache.purgeall = 0;
    +	}
    +
    +	tcp_hc_purge_internal(all);
     
     	callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz,
     	    tcp_hc_purge, arg);
    
    From 72ec67fcb739bc48e83157a3e7f4b9e7e073127d Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:29:50 +0000
    Subject: [PATCH 1708/2592] MFC r203727:
    
      Add an SDT provider for "vnet"s along with probes for vnet_alloc
      and vnet_destroy.
      Use the line number rather than NULL as dummy argument.
    
      Note: the fbt provider does not reliably provide :return probes
      (depending on optimization levels used at compile time) making
      it unusable for scripts to generate complete call-traces with
      well defined boundaries over allocations or destructions of
      virtual network stacks.
    ---
     sys/net/vnet.c | 14 ++++++++++++++
     1 file changed, 14 insertions(+)
    
    diff --git a/sys/net/vnet.c b/sys/net/vnet.c
    index 26635db0cae..fe8df65389d 100644
    --- a/sys/net/vnet.c
    +++ b/sys/net/vnet.c
    @@ -38,11 +38,13 @@ __FBSDID("$FreeBSD$");
     
     #include "opt_ddb.h"
     #include "opt_kdb.h"
    +#include "opt_kdtrace.h"
     
     #include 
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -210,6 +212,13 @@ static TAILQ_HEAD(, vnet_data_free) vnet_data_free_head =
     	    TAILQ_HEAD_INITIALIZER(vnet_data_free_head);
     static struct sx vnet_data_free_lock;
     
    +SDT_PROVIDER_DEFINE(vnet);
    +SDT_PROBE_DEFINE1(vnet, functions, vnet_alloc, entry, "int");
    +SDT_PROBE_DEFINE2(vnet, functions, vnet_alloc, alloc, "int", "struct vnet *");
    +SDT_PROBE_DEFINE2(vnet, functions, vnet_alloc, return, "int", "struct vnet *");
    +SDT_PROBE_DEFINE2(vnet, functions, vnet_destroy, entry, "int", "struct vnet *");
    +SDT_PROBE_DEFINE1(vnet, functions, vnet_destroy, return, "int");
    +
     /*
      * Allocate a virtual network stack.
      */
    @@ -218,8 +227,10 @@ vnet_alloc(void)
     {
     	struct vnet *vnet;
     
    +	SDT_PROBE1(vnet, functions, vnet_alloc, entry, __LINE__);
     	vnet = malloc(sizeof(struct vnet), M_VNET, M_WAITOK | M_ZERO);
     	vnet->vnet_magic_n = VNET_MAGIC_N;
    +	SDT_PROBE2(vnet, functions, vnet_alloc, alloc, __LINE__, vnet);
     
     	/*
     	 * Allocate storage for virtualized global variables and copy in
    @@ -244,6 +255,7 @@ vnet_alloc(void)
     	LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le);
     	VNET_LIST_WUNLOCK();
     
    +	SDT_PROBE2(vnet, functions, vnet_alloc, return, __LINE__, vnet);
     	return (vnet);
     }
     
    @@ -255,6 +267,7 @@ vnet_destroy(struct vnet *vnet)
     {
     	struct ifnet *ifp, *nifp;
     
    +	SDT_PROBE2(vnet, functions, vnet_destroy, entry, __LINE__, vnet);
     	KASSERT(vnet->vnet_sockcnt == 0,
     	    ("%s: vnet still has sockets", __func__));
     
    @@ -281,6 +294,7 @@ vnet_destroy(struct vnet *vnet)
     	vnet->vnet_data_base = 0;
     	vnet->vnet_magic_n = 0xdeadbeef;
     	free(vnet, M_VNET);
    +	SDT_PROBE1(vnet, functions, vnet_destroy, return, __LINE__);
     }
     
     /*
    
    From 78ba8b295c29d51814968f65655d9ca782f7d27b Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:31:54 +0000
    Subject: [PATCH 1709/2592] MFC r203729:
    
      Add DDB support for printing vnet_sysinit and vnet_sysuninit
      ordered call lists. Try to lookup function/symbol names and print
      those in addition to the pointers, along with the constants for
      subsystem and order.
      This is useful for debugging vnet teardown ordering issues.
    
      Make it possible to call the actual printing frunction from normal
      code at runtime, ie. from vnet_sysuninit(), if DDB support is there.
    ---
     sys/net/vnet.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++
     1 file changed, 63 insertions(+)
    
    diff --git a/sys/net/vnet.c b/sys/net/vnet.c
    index fe8df65389d..323ed085563 100644
    --- a/sys/net/vnet.c
    +++ b/sys/net/vnet.c
    @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
     
     #ifdef DDB
     #include 
    +#include 
     #endif
     
     #include 
    @@ -219,6 +220,10 @@ SDT_PROBE_DEFINE2(vnet, functions, vnet_alloc, return, "int", "struct vnet *");
     SDT_PROBE_DEFINE2(vnet, functions, vnet_destroy, entry, "int", "struct vnet *");
     SDT_PROBE_DEFINE1(vnet, functions, vnet_destroy, return, "int");
     
    +#ifdef DDB
    +static void db_show_vnet_print_vs(struct vnet_sysinit *, int);
    +#endif
    +
     /*
      * Allocate a virtual network stack.
      */
    @@ -713,6 +718,64 @@ DB_SHOW_COMMAND(vnets, db_show_vnets)
     	}
     }
     
    +static void
    +db_show_vnet_print_vs(struct vnet_sysinit *vs, int ddb)
    +{
    +	const char *vsname, *funcname;
    +	c_db_sym_t sym;
    +	db_expr_t  offset;
    +
    +#define xprint(...)							\
    +	if (ddb)							\
    +		db_printf(__VA_ARGS__);					\
    +	else								\
    +		printf(__VA_ARGS__)
    +
    +	if (vs == NULL) {
    +		xprint("%s: no vnet_sysinit * given\n", __func__);
    +		return;
    +	}
    +
    +	sym = db_search_symbol((vm_offset_t)vs, DB_STGY_ANY, &offset);
    +	db_symbol_values(sym, &vsname, NULL);
    +	sym = db_search_symbol((vm_offset_t)vs->func, DB_STGY_PROC, &offset);
    +	db_symbol_values(sym, &funcname, NULL);
    +	xprint("%s(%p)\n", (vsname != NULL) ? vsname : "", vs);
    +	xprint("  0x%08x 0x%08x\n", vs->subsystem, vs->order);
    +	xprint("  %p(%s)(%p)\n",
    +	    vs->func, (funcname != NULL) ? funcname : "", vs->arg);
    +#undef xprint
    +}
    +
    +DB_SHOW_COMMAND(vnet_sysinit, db_show_vnet_sysinit)
    +{
    +	struct vnet_sysinit *vs;
    +
    +	db_printf("VNET_SYSINIT vs Name(Ptr)\n");
    +	db_printf("  Subsystem  Order\n");
    +	db_printf("  Function(Name)(Arg)\n");
    +	TAILQ_FOREACH(vs, &vnet_constructors, link) {
    +		db_show_vnet_print_vs(vs, 1);
    +		if (db_pager_quit)
    +			break;
    +	}
    +}
    +
    +DB_SHOW_COMMAND(vnet_sysuninit, db_show_vnet_sysuninit)
    +{
    +	struct vnet_sysinit *vs;
    +
    +	db_printf("VNET_SYSUNINIT vs Name(Ptr)\n");
    +	db_printf("  Subsystem  Order\n");
    +	db_printf("  Function(Name)(Arg)\n");
    +	TAILQ_FOREACH_REVERSE(vs, &vnet_destructors, vnet_sysuninit_head,
    +	    link) {
    +		db_show_vnet_print_vs(vs, 1);
    +		if (db_pager_quit)
    +			break;
    +	}
    +}
    +
     #ifdef VNET_DEBUG
     DB_SHOW_COMMAND(vnetrcrs, db_show_vnetrcrs)
     {
    
    From 9bdad32791730b0289c515ea47a566b79ed01aec Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:33:19 +0000
    Subject: [PATCH 1710/2592] MFC r204142:
    
      Enhance a panic string to contain more useful debugging information.
    ---
     sys/net/if.c | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/sys/net/if.c b/sys/net/if.c
    index 64135ac81e1..45f11f9d609 100644
    --- a/sys/net/if.c
    +++ b/sys/net/if.c
    @@ -842,7 +842,8 @@ if_detach_internal(struct ifnet *ifp, int vmove)
     	IFNET_WUNLOCK();
     	if (!found) {
     		if (vmove)
    -			panic("interface not in it's own ifnet list");
    +			panic("%s: ifp=%p not on the ifnet tailq %p",
    +			    __func__, ifp, &V_ifnet);
     		else
     			return; /* XXX this should panic as well? */
     	}
    
    From e47658ce90a2aea4fac40b8f74fc8b568d4f2cd8 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:34:57 +0000
    Subject: [PATCH 1711/2592] MFC r204140:
    
      Split up ip_drain() into an outer lock and iterator part and
      a "locked" version that will only handle a single network stack
      instance. The latter is called directly from ip_destroy().
    
      Hook up an ip_destroy() function to release resources from the
      legacy IP network layer upon virtual network stack teardown.
    
      Reviewed by:  rwatson
    ---
     sys/netinet/in_proto.c |  3 +++
     sys/netinet/ip_input.c | 42 ++++++++++++++++++++++++++++++++++--------
     sys/netinet/ip_var.h   |  3 +++
     3 files changed, 40 insertions(+), 8 deletions(-)
    
    diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
    index 2bc6ca9632e..d9cab845aee 100644
    --- a/sys/netinet/in_proto.c
    +++ b/sys/netinet/in_proto.c
    @@ -114,6 +114,9 @@ struct protosw inetsw[] = {
     	.pr_domain =		&inetdomain,
     	.pr_protocol =		IPPROTO_IP,
     	.pr_init =		ip_init,
    +#ifdef VIMAGE
    +	.pr_destroy =		ip_destroy,
    +#endif
     	.pr_slowtimo =		ip_slowtimo,
     	.pr_drain =		ip_drain,
     	.pr_usrreqs =		&nousrreqs
    diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
    index 8ffa01ab8a2..084bac06955 100644
    --- a/sys/netinet/ip_input.c
    +++ b/sys/netinet/ip_input.c
    @@ -199,6 +199,7 @@ static struct mtx ipqlock;
     
     static void	maxnipq_update(void);
     static void	ipq_zone_change(void *);
    +static void	ip_drain_locked(void);
     
     SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, fragpackets, CTLFLAG_RD,
         &VNET_NAME(nipq), 0,
    @@ -368,6 +369,22 @@ ip_init(void)
     	netisr_register(&ip_nh);
     }
     
    +#ifdef VIMAGE
    +void
    +ip_destroy(void)
    +{
    +
    +	/* Cleanup in_ifaddr hash table; should be empty. */
    +	hashdestroy(V_in_ifaddrhashtbl, M_IFADDR, V_in_ifaddrhmask);
    +
    +	IPQ_LOCK();
    +	ip_drain_locked();
    +	IPQ_UNLOCK();
    +
    +	uma_zdestroy(V_ipq_zone);
    +}
    +#endif
    +
     void
     ip_fini(void *xtp)
     {
    @@ -1237,23 +1254,32 @@ ip_slowtimo(void)
     /*
      * Drain off all datagram fragments.
      */
    +static void
    +ip_drain_locked(void)
    +{
    +	int     i;
    +
    +	IPQ_LOCK_ASSERT();
    +
    +	for (i = 0; i < IPREASS_NHASH; i++) {
    +		while(!TAILQ_EMPTY(&V_ipq[i])) {
    +			IPSTAT_ADD(ips_fragdropped,
    +			    TAILQ_FIRST(&V_ipq[i])->ipq_nfrags);
    +			ip_freef(&V_ipq[i], TAILQ_FIRST(&V_ipq[i]));
    +		}
    +	}
    +}
    +
     void
     ip_drain(void)
     {
     	VNET_ITERATOR_DECL(vnet_iter);
    -	int     i;
     
     	VNET_LIST_RLOCK_NOSLEEP();
     	IPQ_LOCK();
     	VNET_FOREACH(vnet_iter) {
     		CURVNET_SET(vnet_iter);
    -		for (i = 0; i < IPREASS_NHASH; i++) {
    -			while(!TAILQ_EMPTY(&V_ipq[i])) {
    -				IPSTAT_ADD(ips_fragdropped,
    -				    TAILQ_FIRST(&V_ipq[i])->ipq_nfrags);
    -				ip_freef(&V_ipq[i], TAILQ_FIRST(&V_ipq[i]));
    -			}
    -		}
    +		ip_drain_locked();
     		CURVNET_RESTORE();
     	}
     	IPQ_UNLOCK();
    diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
    index d041dd3feb9..389ad6ee316 100644
    --- a/sys/netinet/ip_var.h
    +++ b/sys/netinet/ip_var.h
    @@ -212,6 +212,9 @@ int	ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
     	    u_long if_hwassist_flags, int sw_csum);
     void	ip_forward(struct mbuf *m, int srcrt);
     void	ip_init(void);
    +#ifdef VIMAGE
    +void	ip_destroy(void);
    +#endif
     extern int
     	(*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
     	    struct ip_moptions *);
    
    From 1198bd71ba85dc33dc929ba3332e0ac97e2a5867 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:36:52 +0000
    Subject: [PATCH 1712/2592] MFC r204143:
    
      Upon virtual network stack teardown properly release the TCP syncache
      resources.
    
      Reviewed by:  rwatson
    ---
     sys/netinet/tcp_syncache.c | 26 ++++++++++++++++++++++++--
     1 file changed, 24 insertions(+), 2 deletions(-)
    
    diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
    index 16c4f676ebb..4d9d487b503 100644
    --- a/sys/netinet/tcp_syncache.c
    +++ b/sys/netinet/tcp_syncache.c
    @@ -278,11 +278,33 @@ syncache_init(void)
     void
     syncache_destroy(void)
     {
    +	struct syncache_head *sch;
    +	struct syncache *sc, *nsc;
    +	int i;
     
    -	/* XXX walk the cache, free remaining objects, stop timers */
    +	/* Cleanup hash buckets: stop timers, free entries, destroy locks. */
    +	for (i = 0; i < V_tcp_syncache.hashsize; i++) {
     
    +		sch = &V_tcp_syncache.hashbase[i];
    +		callout_drain(&sch->sch_timer);
    +
    +		SCH_LOCK(sch);
    +		TAILQ_FOREACH_SAFE(sc, &sch->sch_bucket, sc_hash, nsc)
    +			syncache_drop(sc, sch);
    +		SCH_UNLOCK(sch);
    +		KASSERT(TAILQ_EMPTY(&sch->sch_bucket),
    +		    ("%s: sch->sch_bucket not empty", __func__));
    +		KASSERT(sch->sch_length == 0, ("%s: sch->sch_length %d not 0",
    +		    __func__, sch->sch_length));
    +		mtx_destroy(&sch->sch_mtx);
    +	}
    +
    +	KASSERT(V_tcp_syncache.cache_count == 0, ("%s: cache_count %d not 0",
    +	    __func__, V_tcp_syncache.cache_count));
    +
    +	/* Free the allocated global resources. */
     	uma_zdestroy(V_tcp_syncache.zone);
    -	FREE(V_tcp_syncache.hashbase, M_SYNCACHE);
    +	free(V_tcp_syncache.hashbase, M_SYNCACHE);
     }
     #endif
     
    
    From 0519db7239a48043910e132651df7e7d8cb8d8c9 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:39:02 +0000
    Subject: [PATCH 1713/2592] MFC r204145:
    
      Start to implement ifnet DDB support:
      - 'show ifnets' prints a list of ifnet *s per virtual network stack,
      - 'show ifnet ' prints fields matching the given ifp.
    
      We do not yet print the complete set of fields and might want to
      factor this out to an extra if_debug.c file in case this grows
      a lot[1]. We may also want to grow 'show ifnet ' support[1].
    
      Suggested by: rwatson [1]
      Reviewed by:  rwatson
    ---
     sys/net/if.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++
     1 file changed, 80 insertions(+)
    
    diff --git a/sys/net/if.c b/sys/net/if.c
    index 45f11f9d609..98551fd453a 100644
    --- a/sys/net/if.c
    +++ b/sys/net/if.c
    @@ -34,6 +34,7 @@
     #include "opt_inet6.h"
     #include "opt_inet.h"
     #include "opt_carp.h"
    +#include "opt_ddb.h"
     
     #include 
     #include 
    @@ -62,6 +63,10 @@
     #include 
     #include 
     
    +#ifdef DDB
    +#include 
    +#endif
    +
     #include 
     #include 
     #include 
    @@ -3396,3 +3401,78 @@ if_deregister_com_alloc(u_char type)
     	if_com_alloc[type] = NULL;
     	if_com_free[type] = NULL;
     }
    +
    +#ifdef DDB
    +static void
    +if_show_ifnet(struct ifnet *ifp)
    +{
    +
    +	if (ifp == NULL)
    +		return;
    +	db_printf("%s:\n", ifp->if_xname);
    +#define	IF_DB_PRINTF(f, e)	db_printf("   %s = " f "\n", #e, ifp->e);
    +	IF_DB_PRINTF("%s", if_dname);
    +	IF_DB_PRINTF("%d", if_dunit);
    +	IF_DB_PRINTF("%s", if_description);
    +	IF_DB_PRINTF("%u", if_index);
    +	IF_DB_PRINTF("%u", if_refcount);
    +	IF_DB_PRINTF("%p", if_softc);
    +	IF_DB_PRINTF("%p", if_l2com);
    +	IF_DB_PRINTF("%p", if_vnet);
    +	IF_DB_PRINTF("%p", if_home_vnet);
    +	IF_DB_PRINTF("%p", if_addr);
    +	IF_DB_PRINTF("%p", if_llsoftc);
    +	IF_DB_PRINTF("%p", if_label);
    +	IF_DB_PRINTF("%u", if_pcount);
    +	IF_DB_PRINTF("0x%08x", if_flags);
    +	IF_DB_PRINTF("0x%08x", if_drv_flags);
    +	IF_DB_PRINTF("0x%08x", if_capabilities);
    +	IF_DB_PRINTF("0x%08x", if_capenable);
    +	IF_DB_PRINTF("%p", if_snd.ifq_head);
    +	IF_DB_PRINTF("%p", if_snd.ifq_tail);
    +	IF_DB_PRINTF("%d", if_snd.ifq_len);
    +	IF_DB_PRINTF("%d", if_snd.ifq_maxlen);
    +	IF_DB_PRINTF("%d", if_snd.ifq_drops);
    +	IF_DB_PRINTF("%p", if_snd.ifq_drv_head);
    +	IF_DB_PRINTF("%p", if_snd.ifq_drv_tail);
    +	IF_DB_PRINTF("%d", if_snd.ifq_drv_len);
    +	IF_DB_PRINTF("%d", if_snd.ifq_drv_maxlen);
    +	IF_DB_PRINTF("%d", if_snd.altq_type);
    +	IF_DB_PRINTF("%x", if_snd.altq_flags);
    +#undef IF_DB_PRINTF
    +}
    +
    +DB_SHOW_COMMAND(ifnet, db_show_ifnet)
    +{
    +
    +	if (!have_addr) {
    +		db_printf("usage: show ifnet \n");
    +		return;
    +	}
    +
    +	if_show_ifnet((struct ifnet *)addr);
    +}
    +
    +DB_SHOW_COMMAND(ifnets, db_show_ifnets)
    +{
    +	VNET_ITERATOR_DECL(vnet_iter);
    +	struct ifnet *ifp;
    +	u_short idx;
    +
    +	VNET_FOREACH(vnet_iter) {
    +		CURVNET_SET_QUIET(vnet_iter);
    +#ifdef VIMAGE
    +		db_printf("vnet=%p\n", curvnet);
    +#endif
    +		for (idx = 1; idx <= V_if_index; idx++) {
    +			ifp = V_ifindex_table[idx].ife_ifnet;
    +			if (ifp == NULL)
    +				continue;
    +			db_printf( "%20s ifp=%p\n", ifp->if_xname, ifp);
    +			if (db_pager_quit)
    +				break;
    +		}
    +		CURVNET_RESTORE();
    +	}
    +}
    +#endif
    
    From 1386abc0a7f1df49f8ce9166b8d0b4324298e6df Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:40:28 +0000
    Subject: [PATCH 1714/2592] MFC r204279:
    
      Use the DB_SHOW_ALL_COMMAND() macro to register the formerly 'show ifnets'
      in the db_show_all_table as 'show all ifnets' and with that follow the
      convention for showing complete lists.
    
      Submitted by: thompsa
    ---
     sys/net/if.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/net/if.c b/sys/net/if.c
    index 98551fd453a..8eff017e29d 100644
    --- a/sys/net/if.c
    +++ b/sys/net/if.c
    @@ -3453,7 +3453,7 @@ DB_SHOW_COMMAND(ifnet, db_show_ifnet)
     	if_show_ifnet((struct ifnet *)addr);
     }
     
    -DB_SHOW_COMMAND(ifnets, db_show_ifnets)
    +DB_SHOW_ALL_COMMAND(ifnets, db_show_all_ifnets)
     {
     	VNET_ITERATOR_DECL(vnet_iter);
     	struct ifnet *ifp;
    
    From 67208dfa16f4f7b1824927546f397c65dfe8f75b Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:42:04 +0000
    Subject: [PATCH 1715/2592] MFC r204147:
    
      Set curvnet earlier so that it also covers calls to sodisconnect(), which
      before were possibly panicing the system in ULP code in the VIMAGE case.
    
      Submitted by: Igor (igor ispsystem.com)
    ---
     sys/kern/uipc_socket.c | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
    index acccc54cf50..afa3d71884c 100644
    --- a/sys/kern/uipc_socket.c
    +++ b/sys/kern/uipc_socket.c
    @@ -764,6 +764,8 @@ soconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
     
     	if (so->so_options & SO_ACCEPTCONN)
     		return (EOPNOTSUPP);
    +
    +	CURVNET_SET(so->so_vnet);
     	/*
     	 * If protocol is connection-based, can only connect once.
     	 * Otherwise, if connected, try to disconnect first.  This allows
    @@ -779,10 +781,9 @@ soconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
     		 * biting us.
     		 */
     		so->so_error = 0;
    -		CURVNET_SET(so->so_vnet);
     		error = (*so->so_proto->pr_usrreqs->pru_connect)(so, nam, td);
    -		CURVNET_RESTORE();
     	}
    +	CURVNET_RESTORE();
     
     	return (error);
     }
    
    From 3662f299d2dfebe80138e63af815a42cc330b7c8 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:46:06 +0000
    Subject: [PATCH 1716/2592] MFC r204807:
    
      Destroy UDP UMA zones (empty or not) upon network stack teardown
      to not leak them making UMA/vmstat -z unhappy with every stoped vnet.
      We will still leak pages (especially as zones are marked NOFREE).
    ---
     sys/netinet/udp_usrreq.c | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
    index 019ceb3ef28..b5846c36c43 100644
    --- a/sys/netinet/udp_usrreq.c
    +++ b/sys/netinet/udp_usrreq.c
    @@ -245,6 +245,9 @@ udp_destroy(void)
     	    V_udbinfo.ipi_hashmask);
     	hashdestroy(V_udbinfo.ipi_porthashbase, M_PCB,
     	    V_udbinfo.ipi_porthashmask);
    +
    +	uma_zdestroy(V_udpcb_zone);
    +	uma_zdestroy(V_udbinfo.ipi_zone);
     	INP_INFO_LOCK_DESTROY(&V_udbinfo);
     }
     #endif
    
    From a4f688946097473e5013f23551dba94f098f9869 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:48:13 +0000
    Subject: [PATCH 1717/2592] MFC r204805:
    
      Rework reference counting in case we queue into the netisr,
      or overflow the netisr queue and fall back to the interface
      queue so that we can garuantee that the ifnet pointer stays
      valid.   Formerly we ended up with reference counts <= 0 in
      case the netisr had returned ENOBUFS.  The idea is to track
      any packet in the netisr queue and only change the refount
      on edge operations for the fallback interface queue. This
      also avoids problems in case the if_snd.ifq_len lies to us.
    
      Also rework refount assertions to make sure they trigger if
      we go below 1. Formerly a negative refence count did not
      trigger the assert as the refcount variable is u_int.
    ---
     sys/net/if_epair.c | 91 ++++++++++++++++++++++++++++++++++++----------
     1 file changed, 71 insertions(+), 20 deletions(-)
    
    diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
    index a6b7a7c86cf..316418217de 100644
    --- a/sys/net/if_epair.c
    +++ b/sys/net/if_epair.c
    @@ -1,6 +1,6 @@
     /*-
      * Copyright (c) 2008 The FreeBSD Foundation
    - * Copyright (c) 2009 Bjoern A. Zeeb 
    + * Copyright (c) 2009-2010 Bjoern A. Zeeb 
      * All rights reserved.
      *
      * This software was developed by CK Software GmbH under sponsorship
    @@ -256,6 +256,9 @@ epair_nh_sintr(struct mbuf *m)
     	(*ifp->if_input)(ifp, m);
     	sc = ifp->if_softc;
     	EPAIR_REFCOUNT_RELEASE(&sc->refcount);
    +	EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
    +	    ("%s: ifp=%p sc->refcount not >= 1: %d",
    +	    __func__, ifp, sc->refcount));
     	DPRINTF("ifp=%p refcount=%u\n", ifp, sc->refcount);
     }
     
    @@ -292,8 +295,16 @@ epair_nh_drainedcpu(u_int cpuid)
     
     		IFQ_LOCK(&ifp->if_snd);
     		if (IFQ_IS_EMPTY(&ifp->if_snd)) {
    +			struct epair_softc *sc;
    +
     			STAILQ_REMOVE(&epair_dpcpu->epair_ifp_drain_list,
     			    elm, epair_ifp_drain, ifp_next);
    +			/* The cached ifp goes off the list. */
    +			sc = ifp->if_softc;
    +			EPAIR_REFCOUNT_RELEASE(&sc->refcount);
    +			EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
    +			    ("%s: ifp=%p sc->refcount not >= 1: %d",
    +			    __func__, ifp, sc->refcount));
     			free(elm, M_EPAIR);
     		}
     		IFQ_UNLOCK(&ifp->if_snd);
    @@ -312,14 +323,50 @@ epair_nh_drainedcpu(u_int cpuid)
     /*
      * Network interface (`if') related functions.
      */
    +static void
    +epair_remove_ifp_from_draining(struct ifnet *ifp)
    +{
    +	struct epair_dpcpu *epair_dpcpu;
    +	struct epair_ifp_drain *elm, *tvar;
    +	u_int cpuid;
    +
    +	for (cpuid = 0; cpuid <= mp_maxid; cpuid++) {
    +		if (CPU_ABSENT(cpuid))
    +			continue;
    +
    +		epair_dpcpu = DPCPU_ID_PTR(cpuid, epair_dpcpu);
    +		EPAIR_LOCK(epair_dpcpu);
    +		STAILQ_FOREACH_SAFE(elm, &epair_dpcpu->epair_ifp_drain_list,
    +		    ifp_next, tvar) {
    +			if (ifp == elm->ifp) {
    +				struct epair_softc *sc;
    +
    +				STAILQ_REMOVE(
    +				    &epair_dpcpu->epair_ifp_drain_list, elm,
    +				    epair_ifp_drain, ifp_next);
    +				/* The cached ifp goes off the list. */
    +				sc = ifp->if_softc;
    +				EPAIR_REFCOUNT_RELEASE(&sc->refcount);
    +				EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
    +				    ("%s: ifp=%p sc->refcount not >= 1: %d",
    +				    __func__, ifp, sc->refcount));
    +				free(elm, M_EPAIR);
    +			}
    +		}
    +		EPAIR_UNLOCK(epair_dpcpu);
    +	}
    +}
    +
     static int
     epair_add_ifp_for_draining(struct ifnet *ifp)
     {
     	struct epair_dpcpu *epair_dpcpu;
    -	struct epair_softc *sc = sc = ifp->if_softc;
    +	struct epair_softc *sc;
     	struct epair_ifp_drain *elm = NULL;
     
    +	sc = ifp->if_softc;
     	epair_dpcpu = DPCPU_ID_PTR(sc->cpuid, epair_dpcpu);
    +	EPAIR_LOCK_ASSERT(epair_dpcpu);
     	STAILQ_FOREACH(elm, &epair_dpcpu->epair_ifp_drain_list, ifp_next)
     		if (elm->ifp == ifp)
     			break;
    @@ -332,6 +379,8 @@ epair_add_ifp_for_draining(struct ifnet *ifp)
     		return (ENOMEM);
     
     	elm->ifp = ifp;
    +	/* Add a reference for the ifp pointer on the list. */
    +	EPAIR_REFCOUNT_AQUIRE(&sc->refcount);
     	STAILQ_INSERT_TAIL(&epair_dpcpu->epair_ifp_drain_list, elm, ifp_next);
     
     	return (0);
    @@ -395,13 +444,15 @@ epair_start_locked(struct ifnet *ifp)
     			/* Someone else received the packet. */
     			oifp->if_ipackets++;
     		} else {
    +			/* The packet was freed already. */
     			epair_dpcpu->epair_drv_flags |= IFF_DRV_OACTIVE;
     			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    -			if (epair_add_ifp_for_draining(ifp)) {
    -				ifp->if_oerrors++;
    -				m_freem(m);
    -			}
    +			(void) epair_add_ifp_for_draining(ifp);
    +			ifp->if_oerrors++;
     			EPAIR_REFCOUNT_RELEASE(&sc->refcount);
    +			EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
    +			    ("%s: ifp=%p sc->refcount not >= 1: %d",
    +			    __func__, oifp, sc->refcount));
     		}
     	}
     }
    @@ -524,9 +575,13 @@ epair_transmit_locked(struct ifnet *ifp, struct mbuf *m)
     		oifp->if_ipackets++;
     	} else {
     		/* The packet was freed already. */
    -		EPAIR_REFCOUNT_RELEASE(&sc->refcount);
     		epair_dpcpu->epair_drv_flags |= IFF_DRV_OACTIVE;
     		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +		ifp->if_oerrors++;
    +		EPAIR_REFCOUNT_RELEASE(&sc->refcount);
    +		EPAIR_REFCOUNT_ASSERT((int)sc->refcount >= 1,
    +		    ("%s: ifp=%p sc->refcount not >= 1: %d",
    +		    __func__, oifp, sc->refcount));
     	}
     
     	return (error);
    @@ -548,22 +603,18 @@ epair_transmit(struct ifnet *ifp, struct mbuf *m)
     static void
     epair_qflush(struct ifnet *ifp)
     {
    -	struct epair_dpcpu *epair_dpcpu;
     	struct epair_softc *sc;
    -	struct ifaltq *ifq;
     	
     	sc = ifp->if_softc;
    -	epair_dpcpu = DPCPU_ID_PTR(sc->cpuid, epair_dpcpu);
    -	EPAIR_LOCK(epair_dpcpu);
    -	ifq = &ifp->if_snd;
    -	DPRINTF("ifp=%p sc refcnt=%u ifq_len=%u\n",
    -	    ifp, sc->refcount, ifq->ifq_len);
    +	KASSERT(sc != NULL, ("%s: ifp=%p, epair_softc gone? sc=%p\n",
    +	    __func__, ifp, sc));
     	/*
    -	 * Instead of calling EPAIR_REFCOUNT_RELEASE(&sc->refcount);
    -	 * n times, just subtract for the cleanup.
    +	 * Remove this ifp from all backpointer lists. The interface will not
    +	 * usable for flushing anyway nor should it have anything to flush
    +	 * after if_qflush().
     	 */
    -	sc->refcount -= ifq->ifq_len;
    -	EPAIR_UNLOCK(epair_dpcpu);
    +	epair_remove_ifp_from_draining(ifp);
    +
     	if (sc->if_qflush)
     		sc->if_qflush(ifp);
     }
    @@ -828,8 +879,8 @@ epair_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
     	 */
     	DPRINTF("sca refcnt=%u scb refcnt=%u\n", sca->refcount, scb->refcount);
     	EPAIR_REFCOUNT_ASSERT(sca->refcount == 1 && scb->refcount == 1,
    -	    ("%s: sca->refcount!=1: %d || scb->refcount!=1: %d",
    -	    __func__, sca->refcount, scb->refcount));
    +	    ("%s: ifp=%p sca->refcount!=1: %d || ifp=%p scb->refcount!=1: %d",
    +	    __func__, ifp, sca->refcount, oifp, scb->refcount));
     
     	/*
     	 * Get rid of our second half.
    
    From 62f500d0c2b29c297a3da2751feb23e20724e630 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:50:02 +0000
    Subject: [PATCH 1718/2592] MFC r204838:
    
      Destroy TCP UMA zones (empty or not) upon network stack teardown
      to not leak them, otherwise making UMA/vmstat unhappy with every
      stoped vnet.
      We will still leak pages (especially for zones marked NOFREE).
    
      Reshuffle cleanup order in tcp_destroy() to get rid of what we can
      easily free first.
    
      Reviewed by:  rwatson
    ---
     sys/netinet/tcp_reass.c    | 9 +++++++++
     sys/netinet/tcp_subr.c     | 8 +++++++-
     sys/netinet/tcp_timewait.c | 2 ++
     sys/netinet/tcp_var.h      | 3 +++
     4 files changed, 21 insertions(+), 1 deletion(-)
    
    diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
    index 8115b2b8e16..cd7eb1ce39f 100644
    --- a/sys/netinet/tcp_reass.c
    +++ b/sys/netinet/tcp_reass.c
    @@ -132,6 +132,15 @@ tcp_reass_init(void)
     	    tcp_reass_zone_change, NULL, EVENTHANDLER_PRI_ANY);
     }
     
    +#ifdef VIMAGE
    +void
    +tcp_reass_destroy(void)
    +{
    +
    +	uma_zdestroy(V_tcp_reass_zone);
    +}
    +#endif
    +
     int
     tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
     {
    diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
    index 622c508f381..a784f367498 100644
    --- a/sys/netinet/tcp_subr.c
    +++ b/sys/netinet/tcp_subr.c
    @@ -445,15 +445,21 @@ void
     tcp_destroy(void)
     {
     
    -	tcp_tw_destroy();
    +	tcp_reass_destroy();
     	tcp_hc_destroy();
     	syncache_destroy();
    +	tcp_tw_destroy();
     
     	/* XXX check that hashes are empty! */
     	hashdestroy(V_tcbinfo.ipi_hashbase, M_PCB,
     	    V_tcbinfo.ipi_hashmask);
     	hashdestroy(V_tcbinfo.ipi_porthashbase, M_PCB,
     	    V_tcbinfo.ipi_porthashmask);
    +
    +	uma_zdestroy(V_sack_hole_zone);
    +	uma_zdestroy(V_tcpcb_zone);
    +	uma_zdestroy(V_tcbinfo.ipi_zone);
    +
     	INP_INFO_LOCK_DESTROY(&V_tcbinfo);
     }
     #endif
    diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
    index f755fa1eea8..6e5b013ae98 100644
    --- a/sys/netinet/tcp_timewait.c
    +++ b/sys/netinet/tcp_timewait.c
    @@ -185,6 +185,8 @@ tcp_tw_destroy(void)
     	while((tw = TAILQ_FIRST(&V_twq_2msl)) != NULL)
     		tcp_twclose(tw, 0);
     	INP_INFO_WUNLOCK(&V_tcbinfo);
    +
    +	uma_zdestroy(V_tcptw_zone);
     }
     #endif
     
    diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
    index 4d426943fd4..b6d01c1f321 100644
    --- a/sys/netinet/tcp_var.h
    +++ b/sys/netinet/tcp_var.h
    @@ -648,6 +648,9 @@ char 	*tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *,
     	    const void *);
     int	 tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *);
     void	 tcp_reass_init(void);
    +#ifdef VIMAGE
    +void	 tcp_reass_destroy(void);
    +#endif
     void	 tcp_input(struct mbuf *, int);
     u_long	 tcp_maxmtu(struct in_conninfo *, int *);
     u_long	 tcp_maxmtu6(struct in_conninfo *, int *);
    
    From 397069f2c5512d22490fd5a2af537b5e8f46ae36 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:51:27 +0000
    Subject: [PATCH 1719/2592] MFC r205251:
    
      Add pcb reference counting to the pcblist sysctl handler functions
      to ensure type stability while caching the pcb pointers for the
      copyout.
    
      Reviewed by:  rwatson
    ---
     sys/netinet/ip_divert.c  | 17 ++++++++++++++---
     sys/netinet/raw_ip.c     | 15 ++++++++++++---
     sys/netinet/tcp_subr.c   | 18 ++++++++++++++----
     sys/netinet/udp_usrreq.c | 18 +++++++++++++++---
     4 files changed, 55 insertions(+), 13 deletions(-)
    
    diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
    index 9e7f0621917..a2caef54a30 100644
    --- a/sys/netinet/ip_divert.c
    +++ b/sys/netinet/ip_divert.c
    @@ -653,11 +653,13 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
     	INP_INFO_RLOCK(&V_divcbinfo);
     	for (inp = LIST_FIRST(V_divcbinfo.ipi_listhead), i = 0; inp && i < n;
     	     inp = LIST_NEXT(inp, inp_list)) {
    -		INP_RLOCK(inp);
    +		INP_WLOCK(inp);
     		if (inp->inp_gencnt <= gencnt &&
    -		    cr_canseeinpcb(req->td->td_ucred, inp) == 0)
    +		    cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
    +			in_pcbref(inp);
     			inp_list[i++] = inp;
    -		INP_RUNLOCK(inp);
    +		}
    +		INP_WUNLOCK(inp);
     	}
     	INP_INFO_RUNLOCK(&V_divcbinfo);
     	n = i;
    @@ -679,6 +681,15 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
     		} else
     			INP_RUNLOCK(inp);
     	}
    +	INP_INFO_WLOCK(&V_divcbinfo);
    +	for (i = 0; i < n; i++) {
    +		inp = inp_list[i];
    +		INP_WLOCK(inp);
    +		if (!in_pcbrele(inp))
    +			INP_WUNLOCK(inp);
    +	}
    +	INP_INFO_WUNLOCK(&V_divcbinfo);
    +
     	if (!error) {
     		/*
     		 * Give the user an updated idea of our state.
    diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
    index 9341cf29bbe..6b3ca8b6d19 100644
    --- a/sys/netinet/raw_ip.c
    +++ b/sys/netinet/raw_ip.c
    @@ -1025,13 +1025,13 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
     	INP_INFO_RLOCK(&V_ripcbinfo);
     	for (inp = LIST_FIRST(V_ripcbinfo.ipi_listhead), i = 0; inp && i < n;
     	     inp = LIST_NEXT(inp, inp_list)) {
    -		INP_RLOCK(inp);
    +		INP_WLOCK(inp);
     		if (inp->inp_gencnt <= gencnt &&
     		    cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
    -			/* XXX held references? */
    +			in_pcbref(inp);
     			inp_list[i++] = inp;
     		}
    -		INP_RUNLOCK(inp);
    +		INP_WUNLOCK(inp);
     	}
     	INP_INFO_RUNLOCK(&V_ripcbinfo);
     	n = i;
    @@ -1054,6 +1054,15 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
     		} else
     			INP_RUNLOCK(inp);
     	}
    +	INP_INFO_WLOCK(&V_ripcbinfo);
    +	for (i = 0; i < n; i++) {
    +		inp = inp_list[i];
    +		INP_WLOCK(inp);
    +		if (!in_pcbrele(inp))
    +			INP_WUNLOCK(inp);
    +	}
    +	INP_INFO_WUNLOCK(&V_ripcbinfo);
    +
     	if (!error) {
     		/*
     		 * Give the user an updated idea of our state.  If the
    diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
    index a784f367498..2fc1468d00d 100644
    --- a/sys/netinet/tcp_subr.c
    +++ b/sys/netinet/tcp_subr.c
    @@ -1102,7 +1102,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
     	INP_INFO_RLOCK(&V_tcbinfo);
     	for (inp = LIST_FIRST(V_tcbinfo.ipi_listhead), i = 0;
     	    inp != NULL && i < n; inp = LIST_NEXT(inp, inp_list)) {
    -		INP_RLOCK(inp);
    +		INP_WLOCK(inp);
     		if (inp->inp_gencnt <= gencnt) {
     			/*
     			 * XXX: This use of cr_cansee(), introduced with
    @@ -1117,10 +1117,12 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
     					error = EINVAL;	/* Skip this inp. */
     			} else
     				error = cr_canseeinpcb(req->td->td_ucred, inp);
    -			if (error == 0)
    +			if (error == 0) {
    +				in_pcbref(inp);
     				inp_list[i++] = inp;
    +			}
     		}
    -		INP_RUNLOCK(inp);
    +		INP_WUNLOCK(inp);
     	}
     	INP_INFO_RUNLOCK(&V_tcbinfo);
     	n = i;
    @@ -1156,8 +1158,16 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
     			error = SYSCTL_OUT(req, &xt, sizeof xt);
     		} else
     			INP_RUNLOCK(inp);
    -	
     	}
    +	INP_INFO_WLOCK(&V_tcbinfo);
    +	for (i = 0; i < n; i++) {
    +		inp = inp_list[i];
    +		INP_WLOCK(inp);
    +		if (!in_pcbrele(inp))
    +			INP_WUNLOCK(inp);
    +	}
    +	INP_INFO_WUNLOCK(&V_tcbinfo);
    +
     	if (!error) {
     		/*
     		 * Give the user an updated idea of our state.
    diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
    index b5846c36c43..a349d387b5f 100644
    --- a/sys/netinet/udp_usrreq.c
    +++ b/sys/netinet/udp_usrreq.c
    @@ -766,11 +766,13 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
     	INP_INFO_RLOCK(&V_udbinfo);
     	for (inp = LIST_FIRST(V_udbinfo.ipi_listhead), i = 0; inp && i < n;
     	     inp = LIST_NEXT(inp, inp_list)) {
    -		INP_RLOCK(inp);
    +		INP_WLOCK(inp);
     		if (inp->inp_gencnt <= gencnt &&
    -		    cr_canseeinpcb(req->td->td_ucred, inp) == 0)
    +		    cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
    +			in_pcbref(inp);
     			inp_list[i++] = inp;
    -		INP_RUNLOCK(inp);
    +		}
    +		INP_WUNLOCK(inp);
     	}
     	INP_INFO_RUNLOCK(&V_udbinfo);
     	n = i;
    @@ -781,6 +783,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
     		INP_RLOCK(inp);
     		if (inp->inp_gencnt <= gencnt) {
     			struct xinpcb xi;
    +
     			bzero(&xi, sizeof(xi));
     			xi.xi_len = sizeof xi;
     			/* XXX should avoid extra copy */
    @@ -793,6 +796,15 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
     		} else
     			INP_RUNLOCK(inp);
     	}
    +	INP_INFO_WLOCK(&V_udbinfo);
    +	for (i = 0; i < n; i++) {
    +		inp = inp_list[i];
    +		INP_WLOCK(inp);
    +		if (!in_pcbrele(inp))
    +			INP_WUNLOCK(inp);
    +	}
    +	INP_INFO_WUNLOCK(&V_udbinfo);
    +
     	if (!error) {
     		/*
     		 * Give the user an updated idea of our state.  If the
    
    From 0b93ad54a24a8902c5d798e9d970c9f82fe9cbc9 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:52:56 +0000
    Subject: [PATCH 1720/2592] MFC r205276:
    
      Add ddb support to the "new" link layer code ("new-arp"):
       - show all lltables [1] (optional flag to also show the llentries as well)
       - show lltable 
       - show llentry 
    ---
     sys/net/if_llatbl.c | 136 ++++++++++++++++++++++++++++++++++++++++++++
     1 file changed, 136 insertions(+)
    
    diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
    index 5992f6d82e0..52d73db863e 100644
    --- a/sys/net/if_llatbl.c
    +++ b/sys/net/if_llatbl.c
    @@ -27,6 +27,7 @@
     #include 
     __FBSDID("$FreeBSD$");
     
    +#include "opt_ddb.h"
     #include "opt_inet.h"
     #include "opt_inet6.h"
     
    @@ -42,6 +43,10 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    +#ifdef DDB
    +#include 
    +#endif
    +
     #include 
     
     #include 
    @@ -382,3 +387,134 @@ vnet_lltable_init()
     VNET_SYSINIT(vnet_lltable_init, SI_SUB_PSEUDO, SI_ORDER_FIRST,
         vnet_lltable_init, NULL);
     
    +#ifdef DDB
    +struct llentry_sa {
    +	struct llentry		base;
    +	struct sockaddr		l3_addr;
    +};
    +
    +static void
    +llatbl_lle_show(struct llentry_sa *la)
    +{
    +	struct llentry *lle;
    +	uint8_t octet[6];
    +
    +	lle = &la->base;
    +	db_printf("lle=%p\n", lle);
    +	db_printf(" lle_next=%p\n", lle->lle_next.le_next);
    +	db_printf(" lle_lock=%p\n", &lle->lle_lock);
    +	db_printf(" lle_tbl=%p\n", lle->lle_tbl);
    +	db_printf(" lle_head=%p\n", lle->lle_head);
    +	db_printf(" la_hold=%p\n", lle->la_hold);
    +	db_printf(" la_expire=%ju\n", (uintmax_t)lle->la_expire);
    +	db_printf(" la_flags=0x%04x\n", lle->la_flags);
    +	db_printf(" la_asked=%u\n", lle->la_asked);
    +	db_printf(" la_preempt=%u\n", lle->la_preempt);
    +	db_printf(" ln_byhint=%u\n", lle->ln_byhint);
    +	db_printf(" ln_state=%d\n", lle->ln_state);
    +	db_printf(" ln_router=%u\n", lle->ln_router);
    +	db_printf(" ln_ntick=%ju\n", (uintmax_t)lle->ln_ntick);
    +	db_printf(" lle_refcnt=%d\n", lle->lle_refcnt);
    +	bcopy(&lle->ll_addr.mac16, octet, sizeof(octet));
    +	db_printf(" ll_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
    +	    octet[0], octet[1], octet[2], octet[3], octet[4], octet[5]);
    +	db_printf(" la_timer=%p\n", &lle->la_timer);
    +
    +	switch (la->l3_addr.sa_family) {
    +#ifdef INET
    +	case AF_INET:
    +	{
    +		struct sockaddr_in *sin;
    +		char l3s[INET_ADDRSTRLEN];
    +
    +		sin = (struct sockaddr_in *)&la->l3_addr;
    +		inet_ntoa_r(sin->sin_addr, l3s);
    +		db_printf(" l3_addr=%s\n", l3s);	
    +		break;
    +	}
    +#endif
    +#ifdef INET6
    +	case AF_INET6:
    +	{
    +		struct sockaddr_in6 *sin6;
    +		char l3s[INET6_ADDRSTRLEN];
    +
    +		sin6 = (struct sockaddr_in6 *)&la->l3_addr;
    +		ip6_sprintf(l3s, &sin6->sin6_addr);
    +		db_printf(" l3_addr=%s\n", l3s);	
    +		break;
    +	}
    +#endif
    +	default:
    +		db_printf(" l3_addr=N/A (af=%d)\n", la->l3_addr.sa_family);
    +		break;
    +	}
    +}
    +
    +DB_SHOW_COMMAND(llentry, db_show_llentry)
    +{
    +
    +	if (!have_addr) {
    +		db_printf("usage: show llentry \n");
    +		return;
    +	}
    +
    +	llatbl_lle_show((struct llentry_sa *)addr);
    +}
    +
    +static void
    +llatbl_llt_show(struct lltable *llt)
    +{
    +	int i;
    +	struct llentry *lle;
    +
    +	db_printf("llt=%p llt_af=%d llt_ifp=%p\n",
    +	    llt, llt->llt_af, llt->llt_ifp);
    +
    +	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
    +		LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
    +
    +			llatbl_lle_show((struct llentry_sa *)lle);
    +			if (db_pager_quit)
    +				return;
    +		}
    +	}
    +}
    +
    +DB_SHOW_COMMAND(lltable, db_show_lltable)
    +{
    +
    +	if (!have_addr) {
    +		db_printf("usage: show lltable \n");
    +		return;
    +	}
    +
    +	llatbl_llt_show((struct lltable *)addr);
    +}
    +
    +DB_SHOW_ALL_COMMAND(lltables, db_show_all_lltables)
    +{
    +	VNET_ITERATOR_DECL(vnet_iter);
    +	struct lltable *llt;
    +
    +	VNET_FOREACH(vnet_iter) {
    +		CURVNET_SET_QUIET(vnet_iter);
    +#ifdef VIMAGE
    +		db_printf("vnet=%p\n", curvnet);
    +#endif
    +		SLIST_FOREACH(llt, &V_lltables, llt_link) {
    +			db_printf("llt=%p llt_af=%d llt_ifp=%p(%s)\n",
    +			    llt, llt->llt_af, llt->llt_ifp,
    +			    (llt->llt_ifp != NULL) ?
    +				llt->llt_ifp->if_xname : "?");
    +			if (have_addr && addr != 0) /* verbose */
    +				llatbl_llt_show(llt);
    +			if (db_pager_quit) {
    +				CURVNET_RESTORE();
    +				return;
    +			}
    +		}
    +		CURVNET_RESTORE();
    +	}
    +}
    +#endif
    
    From 2287aa049caedb4abac1b8ff900550f7607fff44 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:54:44 +0000
    Subject: [PATCH 1721/2592] MFC r205626:
    
      Print the pointer to the lock with the panic message. The previous
            panic: rw lock not unlocked
      was not really helpful for debugging. Now one can at least call
            show lock 
      form ddb to learn more about the lock.
    ---
     sys/kern/kern_rwlock.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
    index 10de56a7773..7bedf7682a6 100644
    --- a/sys/kern/kern_rwlock.c
    +++ b/sys/kern/kern_rwlock.c
    @@ -196,8 +196,8 @@ void
     rw_destroy(struct rwlock *rw)
     {
     
    -	KASSERT(rw->rw_lock == RW_UNLOCKED, ("rw lock not unlocked"));
    -	KASSERT(rw->rw_recurse == 0, ("rw lock still recursed"));
    +	KASSERT(rw->rw_lock == RW_UNLOCKED, ("rw lock %p not unlocked", rw));
    +	KASSERT(rw->rw_recurse == 0, ("rw lock %p still recursed", rw));
     	rw->rw_lock = RW_DESTROYED;
     	lock_destroy(&rw->lock_object);
     }
    
    From 168d1f006bba2eaab15d79d8395871a381eea17e Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 17:56:45 +0000
    Subject: [PATCH 1722/2592] MFC r197945:
    
    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 578204a985a..458c839bff2 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 08611830aaa62482836c36110db2dc5f01691b1d Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sat, 27 Mar 2010 17:57:17 +0000
    Subject: [PATCH 1723/2592] MFC r204840:
    
      As statfs.f_flags are uint64_t the local variables should be as well.
      We'll start noticing this with the next flag introduced as the lower
      32bit are all used.
    
      While here compare to 0 explicitly [1].
    
      Suggested by: kib [1]
      Reviewed by:  kib
    ---
     sbin/mount/mount.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c
    index 0bd553377bb..1a6903d3c25 100644
    --- a/sbin/mount/mount.c
    +++ b/sbin/mount/mount.c
    @@ -91,7 +91,7 @@ char   *flags2opts(int);
     
     /* Map from mount options to printable formats. */
     static struct opt {
    -	int o_opt;
    +	uint64_t o_opt;
     	const char *o_name;
     } optnames[] = {
     	{ MNT_ASYNC,		"asynchronous" },
    @@ -611,7 +611,7 @@ mountfs(const char *vfstype, const char *spec, const char *name, int flags,
     void
     prmount(struct statfs *sfp)
     {
    -	int flags;
    +	uint64_t flags;
     	unsigned int i;
     	struct opt *o;
     	struct passwd *pw;
    @@ -620,7 +620,7 @@ prmount(struct statfs *sfp)
     	    sfp->f_fstypename);
     
     	flags = sfp->f_flags & MNT_VISFLAGMASK;
    -	for (o = optnames; flags && o->o_opt; o++)
    +	for (o = optnames; flags != 0 && o->o_opt != 0; o++)
     		if (flags & o->o_opt) {
     			(void)printf(", %s", o->o_name);
     			flags &= ~o->o_opt;
    
    From f2f6fe304d48f18733cf829718e731a4eaccce5b Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 18:01:38 +0000
    Subject: [PATCH 1724/2592] MFC r199182:
    
    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 3fbc03cc995a2b36b95c0a88abcdc71710eee68c Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 18:04:33 +0000
    Subject: [PATCH 1725/2592] MFC r199875:
    
    Provide a set of sysctls and tunables to disable device node creation
    for specific "kinds" of disk labels - for example, GPT UUIDs.  Reason
    for this is that sometimes, other GEOM classes attach to these device
    nodes instead of the proper ones - e.g. they attach to /dev/gptid/XXX
    instead of /dev/ada0p2, which is annoying.
    
    Reviewed by:	pjd (earlier version)
    ---
     sys/geom/label/g_label.c          |  3 ++-
     sys/geom/label/g_label.h          | 32 ++++++++++++++++++++++---------
     sys/geom/label/g_label_ext2fs.c   |  7 +++++--
     sys/geom/label/g_label_gpt.c      | 13 +++++++++----
     sys/geom/label/g_label_iso9660.c  |  7 +++++--
     sys/geom/label/g_label_msdosfs.c  |  7 +++++--
     sys/geom/label/g_label_ntfs.c     |  7 +++++--
     sys/geom/label/g_label_reiserfs.c |  7 +++++--
     sys/geom/label/g_label_ufs.c      | 14 +++++++++-----
     9 files changed, 68 insertions(+), 29 deletions(-)
    
    diff --git a/sys/geom/label/g_label.c b/sys/geom/label/g_label.c
    index e39c2335e74..48329aa3656 100644
    --- a/sys/geom/label/g_label.c
    +++ b/sys/geom/label/g_label.c
    @@ -34,7 +34,6 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    -#include 
     #include 
     #include 
     #include 
    @@ -316,6 +315,8 @@ g_label_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
     	for (i = 0; g_labels[i] != NULL; i++) {
     		char label[64];
     
    +		if (g_labels[i]->ld_enabled == 0)
    +			continue;
     		g_topology_unlock();
     		g_labels[i]->ld_taste(cp, label, sizeof(label));
     		g_topology_lock();
    diff --git a/sys/geom/label/g_label.h b/sys/geom/label/g_label.h
    index 6e5d8f0d992..06ba2f55ef2 100644
    --- a/sys/geom/label/g_label.h
    +++ b/sys/geom/label/g_label.h
    @@ -30,6 +30,9 @@
     #define	_G_LABEL_H_
     
     #include 
    +#ifdef _KERNEL
    +#include 
    +#endif
     
     #define	G_LABEL_CLASS_NAME	"LABEL"
     
    @@ -56,23 +59,34 @@ extern u_int g_label_debug;
     	}								\
     } while (0)
     
    +SYSCTL_DECL(_kern_geom_label);
    +
    +#define	G_LABEL_INIT(kind, label, descr) 				\
    +	SYSCTL_NODE(_kern_geom_label, OID_AUTO, kind, CTLFLAG_RD,	\
    +	    NULL, "");							\
    +	SYSCTL_INT(_kern_geom_label_##kind, OID_AUTO, enable, 		\
    +	    CTLFLAG_RW, &label.ld_enabled, 1, descr);			\
    +	TUNABLE_INT("kern.geom.label." __XSTRING(kind) ".enable",	\
    +	    &label.ld_enabled)
    +
     typedef void g_label_taste_t (struct g_consumer *cp, char *label, size_t size);
     
     struct g_label_desc {
     	g_label_taste_t	*ld_taste;
     	char		*ld_dir;
    +	int		 ld_enabled;
     };
     
     /* Supported labels. */
    -extern const struct g_label_desc g_label_ufs_id;
    -extern const struct g_label_desc g_label_ufs_volume;
    -extern const struct g_label_desc g_label_iso9660;
    -extern const struct g_label_desc g_label_msdosfs;
    -extern const struct g_label_desc g_label_ext2fs;
    -extern const struct g_label_desc g_label_reiserfs;
    -extern const struct g_label_desc g_label_ntfs;
    -extern const struct g_label_desc g_label_gpt;
    -extern const struct g_label_desc g_label_gpt_uuid;
    +extern struct g_label_desc g_label_ufs_id;
    +extern struct g_label_desc g_label_ufs_volume;
    +extern struct g_label_desc g_label_iso9660;
    +extern struct g_label_desc g_label_msdosfs;
    +extern struct g_label_desc g_label_ext2fs;
    +extern struct g_label_desc g_label_reiserfs;
    +extern struct g_label_desc g_label_ntfs;
    +extern struct g_label_desc g_label_gpt;
    +extern struct g_label_desc g_label_gpt_uuid;
     #endif	/* _KERNEL */
     
     struct g_label_metadata {
    diff --git a/sys/geom/label/g_label_ext2fs.c b/sys/geom/label/g_label_ext2fs.c
    index 379785f5455..2e004930730 100644
    --- a/sys/geom/label/g_label_ext2fs.c
    +++ b/sys/geom/label/g_label_ext2fs.c
    @@ -86,7 +86,10 @@ exit_free:
     	g_free(fs);
     }
     
    -const struct g_label_desc g_label_ext2fs = {
    +struct g_label_desc g_label_ext2fs = {
     	.ld_taste = g_label_ext2fs_taste,
    -	.ld_dir = "ext2fs"
    +	.ld_dir = "ext2fs",
    +	.ld_enabled = 1
     };
    +
    +G_LABEL_INIT(ext2fs, g_label_ext2fs, "Create device nodes for EXT2FS volumes");
    diff --git a/sys/geom/label/g_label_gpt.c b/sys/geom/label/g_label_gpt.c
    index b186782097a..37014959cff 100644
    --- a/sys/geom/label/g_label_gpt.c
    +++ b/sys/geom/label/g_label_gpt.c
    @@ -153,12 +153,17 @@ g_label_gpt_uuid_taste(struct g_consumer *cp, char *label, size_t size)
     	snprintf_uuid(label, size, &part_gpt_entry->ent.ent_uuid);
     }
     
    -const struct g_label_desc g_label_gpt = {
    +struct g_label_desc g_label_gpt = {
     	.ld_taste = g_label_gpt_taste,
    -	.ld_dir = G_LABEL_GPT_VOLUME_DIR
    +	.ld_dir = G_LABEL_GPT_VOLUME_DIR,
    +	.ld_enabled = 1
     };
     
    -const struct g_label_desc g_label_gpt_uuid = {
    +struct g_label_desc g_label_gpt_uuid = {
     	.ld_taste = g_label_gpt_uuid_taste,
    -	.ld_dir = G_LABEL_GPT_ID_DIR
    +	.ld_dir = G_LABEL_GPT_ID_DIR,
    +	.ld_enabled = 1
     };
    +
    +G_LABEL_INIT(gpt, g_label_gpt, "Create device nodes for GPT labels");
    +G_LABEL_INIT(gptid, g_label_gpt_uuid, "Create device nodes for GPT UUIDs");
    diff --git a/sys/geom/label/g_label_iso9660.c b/sys/geom/label/g_label_iso9660.c
    index 7d29bcd864d..154cefcb4a8 100644
    --- a/sys/geom/label/g_label_iso9660.c
    +++ b/sys/geom/label/g_label_iso9660.c
    @@ -78,7 +78,10 @@ g_label_iso9660_taste(struct g_consumer *cp, char *label, size_t size)
     	}
     }
     
    -const struct g_label_desc g_label_iso9660 = {
    +struct g_label_desc g_label_iso9660 = {
     	.ld_taste = g_label_iso9660_taste,
    -	.ld_dir = G_LABEL_ISO9660_DIR
    +	.ld_dir = G_LABEL_ISO9660_DIR,
    +	.ld_enabled = 1
     };
    +
    +G_LABEL_INIT(iso9660, g_label_iso9660, "Create device nodes for ISO9660 volume names");
    diff --git a/sys/geom/label/g_label_msdosfs.c b/sys/geom/label/g_label_msdosfs.c
    index 94d88d20fa4..5f65a72d20d 100644
    --- a/sys/geom/label/g_label_msdosfs.c
    +++ b/sys/geom/label/g_label_msdosfs.c
    @@ -216,7 +216,10 @@ error:
     		g_free(sector);
     }
     
    -const struct g_label_desc g_label_msdosfs = {
    +struct g_label_desc g_label_msdosfs = {
     	.ld_taste = g_label_msdosfs_taste,
    -	.ld_dir = G_LABEL_MSDOSFS_DIR
    +	.ld_dir = G_LABEL_MSDOSFS_DIR,
    +	.ld_enabled = 1
     };
    +
    +G_LABEL_INIT(msdosfs, g_label_msdosfs, "Create device nodes for MSDOSFS volumes");
    diff --git a/sys/geom/label/g_label_ntfs.c b/sys/geom/label/g_label_ntfs.c
    index 4781d7debbe..1ee3f797f26 100644
    --- a/sys/geom/label/g_label_ntfs.c
    +++ b/sys/geom/label/g_label_ntfs.c
    @@ -114,7 +114,10 @@ done:
     		g_free(filerecp);
     }
     
    -const struct g_label_desc g_label_ntfs = {
    +struct g_label_desc g_label_ntfs = {
     	.ld_taste = g_label_ntfs_taste,
    -	.ld_dir = G_LABEL_NTFS_DIR
    +	.ld_dir = G_LABEL_NTFS_DIR,
    +	.ld_enabled = 1
     };
    +
    +G_LABEL_INIT(ntfs, g_label_ntfs, "Create device nodes for NTFS volumes");
    diff --git a/sys/geom/label/g_label_reiserfs.c b/sys/geom/label/g_label_reiserfs.c
    index 18ce1efd4f8..a912e979914 100644
    --- a/sys/geom/label/g_label_reiserfs.c
    +++ b/sys/geom/label/g_label_reiserfs.c
    @@ -111,7 +111,10 @@ exit_free:
     	g_free(fs);
     }
     
    -const struct g_label_desc g_label_reiserfs = {
    +struct g_label_desc g_label_reiserfs = {
     	.ld_taste = g_label_reiserfs_taste,
    -	.ld_dir = "reiserfs"
    +	.ld_dir = "reiserfs",
    +	.ld_enabled = 1
     };
    +
    +G_LABEL_INIT(reiserfs, g_label_reiserfs, "Create device nodes for REISERFS volumes");
    diff --git a/sys/geom/label/g_label_ufs.c b/sys/geom/label/g_label_ufs.c
    index 8510fc06912..b9b04437f0a 100644
    --- a/sys/geom/label/g_label_ufs.c
    +++ b/sys/geom/label/g_label_ufs.c
    @@ -137,13 +137,17 @@ g_label_ufs_id_taste(struct g_consumer *cp, char *label, size_t size)
     	g_label_ufs_taste_common(cp, label, size, G_LABEL_UFS_ID);
     }
     
    -
    -const struct g_label_desc g_label_ufs_volume = {
    +struct g_label_desc g_label_ufs_volume = {
     	.ld_taste = g_label_ufs_volume_taste,
    -	.ld_dir = G_LABEL_UFS_VOLUME_DIR
    +	.ld_dir = G_LABEL_UFS_VOLUME_DIR,
    +	.ld_enabled = 1
     };
     
    -const struct g_label_desc g_label_ufs_id = {
    +struct g_label_desc g_label_ufs_id = {
     	.ld_taste = g_label_ufs_id_taste,
    -	.ld_dir = G_LABEL_UFS_ID_DIR
    +	.ld_dir = G_LABEL_UFS_ID_DIR,
    +	.ld_enabled = 1
     };
    +
    +G_LABEL_INIT(ufsid, g_label_ufs_id, "Create device nodes for UFS file system IDs");
    +G_LABEL_INIT(ufs, g_label_ufs_volume, "Create device nodes for UFS volume names");
    
    From 89a2dbabbaff989aa801326124edec98cd35b45e Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 18:08:14 +0000
    Subject: [PATCH 1726/2592] MFC r200058:
    
    Add change that was somehow missed in r192586.  It could manifest by
    incorrectly returning EINVAL from acl_valid(3) for applications linked
    against pre-8.0 libc.
    ---
     sys/kern/vfs_acl.c | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c
    index 2dd64f44e45..74caae1ee5b 100644
    --- a/sys/kern/vfs_acl.c
    +++ b/sys/kern/vfs_acl.c
    @@ -173,7 +173,7 @@ acl_copyout(struct acl *kernel_acl, void *user_acl, acl_type_t type)
     
     /*
      * Convert "old" type - ACL_TYPE_{ACCESS,DEFAULT}_OLD - into its "new"
    - * counterpart.  It's required for old (pre-NFS4 ACLs) libc to work
    + * counterpart.  It's required for old (pre-NFSv4 ACLs) libc to work
      * with new kernel.  Fixing 'type' for old binaries with new libc
      * is being done in lib/libc/posix1e/acl_support.c:_acl_type_unold().
      */
    @@ -307,7 +307,8 @@ vacl_aclcheck(struct thread *td, struct vnode *vp, acl_type_t type,
     	error = acl_copyin(aclp, inkernelacl, type);
     	if (error)
     		goto out;
    -	error = VOP_ACLCHECK(vp, type, inkernelacl, td->td_ucred, td);
    +	error = VOP_ACLCHECK(vp, acl_type_unold(type), inkernelacl,
    +	    td->td_ucred, td);
     out:
     	acl_free(inkernelacl);
     	return (error);
    
    From bf876fcd34eac7f46d8bea6eeaa7291ab9337b1d Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 18:09:40 +0000
    Subject: [PATCH 1727/2592] MFC r200273:
    
    Don't add VAPPEND if the file is not being opened for writing.  Note that this
    only affects cases where open(2) is being used improperly - i.e. when the user
    specifies O_APPEND without O_WRONLY or O_RDWR.
    
    Reviewed by:	rwatson
    ---
     sys/kern/vfs_syscalls.c | 2 +-
     sys/kern/vfs_vnops.c    | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
    index c9226952228..2e4c7cfba0c 100644
    --- a/sys/kern/vfs_syscalls.c
    +++ b/sys/kern/vfs_syscalls.c
    @@ -4436,7 +4436,7 @@ fhopen(td, uap)
     	}
     	if (fmode & FREAD)
     		accmode |= VREAD;
    -	if (fmode & O_APPEND)
    +	if ((fmode & O_APPEND) && (fmode & FWRITE))
     		accmode |= VAPPEND;
     #ifdef MAC
     	error = mac_vnode_check_open(td->td_ucred, vp, accmode);
    diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
    index 03e8d938bac..d0b713cb310 100644
    --- a/sys/kern/vfs_vnops.c
    +++ b/sys/kern/vfs_vnops.c
    @@ -212,7 +212,7 @@ restart:
     		accmode |= VREAD;
     	if (fmode & FEXEC)
     		accmode |= VEXEC;
    -	if (fmode & O_APPEND)
    +	if ((fmode & O_APPEND) && (fmode & FWRITE))
     		accmode |= VAPPEND;
     #ifdef MAC
     	error = mac_vnode_check_open(cred, vp, accmode);
    
    From fddc12138a1512bc235a4fcb05548716e8a26d06 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 18:12:00 +0000
    Subject: [PATCH 1728/2592] MFC r200723:
    
    Interpret VAPPEND correctly in vaccess_acl_nfs4(9).
    ---
     sys/kern/subr_acl_nfs4.c | 7 +++++++
     1 file changed, 7 insertions(+)
    
    diff --git a/sys/kern/subr_acl_nfs4.c b/sys/kern/subr_acl_nfs4.c
    index c3f4b65cbd5..fbd233ba764 100644
    --- a/sys/kern/subr_acl_nfs4.c
    +++ b/sys/kern/subr_acl_nfs4.c
    @@ -82,6 +82,13 @@ _access_mask_from_accmode(accmode_t accmode)
     			access_mask |= accmode2mask[i].mask;
     	}
     
    +	/*
    +	 * VAPPEND is just a modifier for VWRITE; if the caller asked
    +	 * for 'VAPPEND | VWRITE', we want to check for ACL_APPEND_DATA only.
    +	 */
    +	if (access_mask & ACL_APPEND_DATA)
    +		access_mask &= ~ACL_WRITE_DATA;
    +
     	return (access_mask);
     }
     
    
    From 79964ec98ded205581daf625e6ee288ac182752b Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 18:15:18 +0000
    Subject: [PATCH 1729/2592] MFC r201432:
    
    Add manual page for gcache(8).
    ---
     sbin/geom/class/cache/Makefile |   1 -
     sbin/geom/class/cache/gcache.8 | 192 +++++++++++++++++++++++++++++++++
     sbin/geom/core/geom.8          |   2 +-
     3 files changed, 193 insertions(+), 2 deletions(-)
     create mode 100644 sbin/geom/class/cache/gcache.8
    
    diff --git a/sbin/geom/class/cache/Makefile b/sbin/geom/class/cache/Makefile
    index 6ca37e6c05e..615c927588c 100644
    --- a/sbin/geom/class/cache/Makefile
    +++ b/sbin/geom/class/cache/Makefile
    @@ -3,6 +3,5 @@
     .PATH: ${.CURDIR}/../../misc
     
     CLASS=	cache
    -NO_MAN=	# notyet
     
     .include 
    diff --git a/sbin/geom/class/cache/gcache.8 b/sbin/geom/class/cache/gcache.8
    new file mode 100644
    index 00000000000..d3f782c9a3d
    --- /dev/null
    +++ b/sbin/geom/class/cache/gcache.8
    @@ -0,0 +1,192 @@
    +.\"-
    +.\" Copyright (c) 2010 Edward Tomasz Napierala
    +.\" 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 THE VOICES IN HIS HEAD 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 January 3, 2010
    +.Dt GCACHE 8
    +.Os
    +.Sh NAME
    +.Nm gcache
    +.Nd "control utility for CACHE GEOM class"
    +.Sh SYNOPSIS
    +.Nm
    +.Cm create
    +.Op Fl v
    +.Op Fl b Ar blocksize
    +.Op Fl s Ar size
    +.Ar name
    +.Ar prov
    +.Nm
    +.Cm configure
    +.Op Fl v
    +.Op Fl b Ar blocksize
    +.Op Fl s Ar size
    +.Ar name
    +.Nm
    +.Cm destroy
    +.Op Fl fv
    +.Ar name
    +.Nm
    +.Cm label
    +.Op Fl v
    +.Op Fl b Ar blocksize
    +.Op Fl s Ar size
    +.Ar name
    +.Ar prov
    +.Nm
    +.Cm stop
    +.Op Fl fv
    +.Ar name ...
    +.Nm
    +.Cm clear
    +.Op Fl v
    +.Ar prov ...
    +.Nm
    +.Cm dump
    +.Ar prov ...
    +.Nm
    +.Cm list
    +.Nm
    +.Cm status
    +.Op Fl s Ar name
    +.Nm
    +.Cm load
    +.Op Fl v
    +.Nm
    +.Cm unload
    +.Op Fl v
    +.Sh DESCRIPTION
    +The
    +.Nm
    +utility is used to control GEOM cache, which can
    +speed up read performance by sending fixed size
    +read requests to its consumer.  It has been developed to address
    +the problem of a horrible read performance of a 64k blocksize FS
    +residing on a RAID3 array with 8 data components, where a single
    +disk component would only get 8k read requests, thus effectively
    +killing disk performance under high load.
    +.Pp
    +Caching can be configured using two different methods:
    +.Dq manual
    +or
    +.Dq automatic .
    +When using the
    +.Dq manual
    +method, no metadata are stored on the devices, so the cached
    +device has to be configured by hand every time it is needed.
    +The
    +.Dq automatic
    +method uses on-disk metadata to detect devices.
    +Once devices are labeled, they will be automatically detected and
    +configured.
    +.Pp
    +The first argument to
    +.Nm
    +indicates an action to be performed:
    +.Bl -tag -width ".Cm destroy"
    +.It Cm create
    +Cache the given devices with specified
    +.Ar name .
    +This is the
    +.Dq manual
    +method.
    +The kernel module
    +.Pa geom_cache.ko
    +will be loaded if it is not loaded already.
    +.It Cm label
    +Cache the given devices with the specified
    +.Ar name .
    +This is the
    +.Dq automatic
    +method, where metadata are stored in every device's last sector.
    +The kernel module
    +.Pa geom_cache.ko
    +will be loaded if it is not loaded already.
    +.It Cm stop
    +Turn off existing cache device by its
    +.Ar name .
    +This command does not touch on-disk metadata!
    +.It Cm destroy
    +Same as
    +.Cm stop .
    +.It Cm clear
    +Clear metadata on the given devices.
    +.It Cm dump
    +Dump metadata stored on the given devices.
    +.It Cm list
    +See
    +.Xr geom 8 .
    +.It Cm status
    +See
    +.Xr geom 8 .
    +.It Cm load
    +See
    +.Xr geom 8 .
    +.It Cm unload
    +See
    +.Xr geom 8 .
    +.El
    +.Pp
    +Additional options:
    +.Bl -tag -width indent
    +.It Fl f
    +Force the removal of the specified cache device.
    +.It Fl v
    +Be more verbose.
    +.El
    +.Sh SYSCTL VARIABLES
    +The following
    +.Xr sysctl 8
    +variables can be used to control the behavior of the
    +.Nm CACHE
    +GEOM class.
    +The default value is shown next to each variable.
    +.Bl -tag -width indent
    +.It Va kern.geom.cache.used_hi : No 20
    +.It Va kern.geom.cache.used_lo : No 5
    +.It Va kern.geom.cache.idletime : No 5
    +.It Va kern.geom.cache.timeout : No 10
    +.It Va kern.geom.cache.enable : No 1
    +.It Va kern.geom.cache.debug : No 0
    +Debug level of the
    +.Nm CACHE
    +GEOM class.
    +This can be set to a number between 0 and 3 inclusive.
    +If set to 0 minimal debug information is printed, and if set to 3 the
    +maximum amount of debug information is printed.
    +.El
    +.Sh EXIT STATUS
    +Exit status is 0 on success, and 1 if the command fails.
    +.Sh SEE ALSO
    +.Xr geom 4 ,
    +.Xr geom 8
    +.Sh HISTORY
    +The
    +.Nm
    +utility appeared in
    +.Fx 7.0 .
    +.Sh AUTHORS
    +.An Ruslan Ermilov Aq ru@FreeBSD.org
    diff --git a/sbin/geom/core/geom.8 b/sbin/geom/core/geom.8
    index 8477205244b..c80816d1fd7 100644
    --- a/sbin/geom/core/geom.8
    +++ b/sbin/geom/core/geom.8
    @@ -166,7 +166,7 @@ geom md unload
     .Sh SEE ALSO
     .Xr libgeom 3 ,
     .Xr geom 4 ,
    -.\" .Xr gcache 8 ,
    +.Xr gcache 8 ,
     .Xr gconcat 8 ,
     .Xr geli 8 ,
     .Xr gjournal 8 ,
    
    From a4325efcbe177339024f55242ee155df4081e3ea Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sat, 27 Mar 2010 18:45:53 +0000
    Subject: [PATCH 1730/2592] MFC r203122:
    
    Improve descriptions, remove turnstiles (since, from what I understand,
    they are only used to implement other synchronization primitives), tweak
    formatting.
    
    MFC r203127:
    
    Add description of bounded sleep vs unbounded sleep (aka blocking).  Move
    rules into their own section.
    
    MFC r203131:
    
    Cosmetic fixes.
    
    MFC r203759:
    
    Improve description for Giant and mention blocking inside interrupt threads.
    
    MFC r203762:
    
    Start sentences with a new line.
    
    Submitted by:	brueffer
    
    MFC r203825:
    
    Remove list of locking primitives, which is kind of redundant, move
    information about witness(9) to the section about interactions, and
    expand 'contexts' table.
    
    MFC r203929:
    
    Some rewording and language fixes.
    
    PR:		docs/136918, docs/134074
    Submitted by:	Ben Kaduk , Haven Hash 
    ---
     share/man/man9/locking.9 | 340 +++++++++++++++++++--------------------
     1 file changed, 164 insertions(+), 176 deletions(-)
    
    diff --git a/share/man/man9/locking.9 b/share/man/man9/locking.9
    index 825eb7f097a..8457e25c134 100644
    --- a/share/man/man9/locking.9
    +++ b/share/man/man9/locking.9
    @@ -24,108 +24,52 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd March 14, 2007
    +.Dd February 15, 2010
     .Dt LOCKING 9
     .Os
     .Sh NAME
     .Nm locking
     .Nd kernel synchronization primitives
    -.Sh SYNOPSIS
    -All sorts of stuff to go here.
    -.Pp
     .Sh DESCRIPTION
     The
     .Em FreeBSD
     kernel is written to run across multiple CPUs and as such requires
     several different synchronization primitives to allow the developers
     to safely access and manipulate the many data types required.
    -.Pp
    -These include:
    -.Bl -enum
    -.It
    -Spin Mutexes
    -.It
    -Sleep Mutexes
    -.It
    -pool Mutexes
    -.It
    -Shared-Exclusive locks
    -.It
    -Reader-Writer locks
    -.It
    -Read-Mostly locks
    -.It
    -Turnstiles
    -.It
    -Semaphores
    -.It
    -Condition variables
    -.It
    -Sleep/wakeup
    -.It
    -Giant
    -.It
    -Lockmanager locks
    -.El
    -.Pp
    -The primitives interact and have a number of rules regarding how
    -they can and can not be combined.
    -There are too many for the average
    -human mind and they keep changing.
    -(if you disagree, please write replacement text)  :-)
    -.Pp
    -Some of these primitives may be used at the low (interrupt) level and
    -some may not.
    -.Pp
    -There are strict ordering requirements and for some of the types this
    -is checked using the
    -.Xr witness 4
    -code.
    -.Pp
    -.Ss SPIN Mutexes
    -Mutexes are the basic primitive.
    -You either hold it or you don't.
    -If you don't own it then you just spin, waiting for the holder (on
    -another CPU) to release it.
    -Hopefully they are doing something fast.
    -You 
    -.Em must not
    -do anything that deschedules the thread while you
    -are holding a SPIN mutex.
     .Ss Mutexes
    -Basically (regular) mutexes will deschedule the thread if the
    -mutex can not be acquired.
    -A non-spin mutex can be considered to be equivalent
    -to getting a write lock on an 
    -.Em rw_lock
    -(see below), and in fact non-spin mutexes and rw_locks may soon become the same thing.
    -As in spin mutexes, you either get it or you don't.
    -You may only call the
    -.Xr sleep 9
    -call via
    -.Fn msleep
    -or the new
    -.Fn mtx_sleep
    -variant.
    -These will atomically drop the mutex and reacquire it
    -as part of waking up.
    -This is often however a
    -.Em BAD
    -idea because it generally relies on you having
    -such a good knowledge of all the call graph above you
    -and what assumptions it is making that there are a lot
    -of ways to make hard-to-find mistakes.
    -For example you MUST re-test all the assumptions you made before,
    -all the way up the call graph to where you got the lock.
    -You can not just assume that mtx_sleep can be inserted anywhere.
    -If any caller above you has any mutex or
    -rwlock, your sleep, will cause a panic.
    -If the sleep only happens rarely it may be years before the 
    -bad code path is found.
    -.Ss Pool Mutexes
    -A variant of regular mutexes where the allocation of the mutex is handled
    -more by the system.
    -.Ss Rw_locks
    +Mutexes (also called "sleep mutexes") are the most commonly used
    +synchronization primitive in the kernel.
    +Thread acquires (locks) a mutex before accessing data shared with other
    +threads (including interrupt threads), and releases (unlocks) it afterwards.
    +If the mutex cannot be acquired, the thread requesting it will sleep.
    +Mutexes fully support priority propagation.
    +.Pp
    +See
    +.Xr mutex 9
    +for details.
    +.Ss Spin mutexes
    +Spin mutexes are variation of basic mutexes; the main difference between
    +the two is that spin mutexes never sleep - instead, they spin, waiting
    +for the thread holding the lock, which runs on another CPU, to release it.
    +Differently from ordinary mutex, spin mutexes disable interrupts when acquired.
    +Since disabling interrupts is expensive, they are also generally slower.
    +Spin mutexes should be used only when neccessary, e.g. to protect data shared
    +with interrupt filter code (see
    +.Xr bus_setup_intr 9
    +for details).
    +.Ss Pool mutexes
    +With most synchronisaton primitives, such as mutexes, programmer must
    +provide a piece of allocated memory to hold the primitive.
    +For example, a mutex may be embedded inside the structure it protects.
    +Pool mutex is a variant of mutex without this requirement - to lock or unlock
    +a pool mutex, one uses address of the structure being protected with it,
    +not the mutex itself.
    +Pool mutexes are seldom used.
    +.Pp
    +See
    +.Xr mtx_pool 9
    +for details.
    +.Ss Reader/writer locks
     Reader/writer locks allow shared access to protected data by multiple threads,
     or exclusive access by a single thread.
     The threads with shared access are known as
    @@ -135,23 +79,12 @@ A thread with exclusive access is known as a
     .Em writer
     since it may modify protected data.
     .Pp
    -Although reader/writer locks look very similar to
    -.Xr sx 9
    -(see below) locks, their usage pattern is different.
     Reader/writer locks can be treated as mutexes (see above and
     .Xr mutex 9 )
     with shared/exclusive semantics.
     More specifically, regular mutexes can be 
     considered to be equivalent to a write-lock on an
     .Em rw_lock.
    -In the future this may in fact
    -become literally the fact.
    -An
    -.Em rw_lock
    -can be locked while holding a regular mutex, but 
    -can
    -.Em not
    -be held while sleeping.
     The
     .Em rw_lock
     locks have priority propagation like mutexes, but priority
    @@ -163,54 +96,49 @@ Another important property is that shared holders of
     can recurse, but exclusive locks are not allowed to recurse.
     This ability should not be used lightly and 
     .Em may go away.
    -Users of recursion in any locks should be prepared to 
    -defend their decision against vigorous criticism.
    -.Ss Rm_locks
    +.Pp
    +See
    +.Xr rwlock 9
    +for details.
    +.Ss Read-mostly locks
     Mostly reader locks are similar to
    -.Em Reader/write
    -locks but optimized for very infrequent 
    -.Em writer
    -locking.
    -.Em rm_lock
    +.Em reader/writer
    +locks but optimized for very infrequent write locking.
    +.Em Read-mostly
     locks implement full priority propagation by tracking shared owners
    -using a lock user supplied
    +using a caller-supplied
     .Em tracker
     data structure.
    -.Ss Sx_locks
    -Shared/exclusive locks are used to protect data that are read far more often
    -than they are written.
    -Mutexes are inherently more efficient than shared/exclusive locks, so
    -shared/exclusive locks should be used prudently.
    -The main reason for using an
    -.Em sx_lock
    -is that a thread may hold a shared or exclusive lock on an
    -.Em sx_lock
    -lock while sleeping.
    -As a consequence of this however, an
    -.Em sx_lock
    -lock may not be acquired while holding a mutex.
    -The reason for this is that, if one thread slept while holding an
    -.Em sx_lock
    -lock while another thread blocked on the same
    -.Em sx_lock
    -lock after acquiring a mutex, then the second thread would effectively
    -end up sleeping while holding a mutex, which is not allowed.
    -The
    -.Em sx_lock
    -should be considered to be closely related to
    +.Pp
    +See
    +.Xr rmlock 9
    +for details.
    +.Ss Shared/exclusive locks
    +Shared/exclusive locks are similar to reader/writer locks; the main difference
    +between them is that shared/exclusive locks may be held during unbounded sleep
    +(and may thus perform an unbounded sleep).
    +They are inherently less efficient than mutexes, reader/writer locks
    +and read-mostly locks.
    +They don't support priority propagation.
    +They should be considered to be closely related to
     .Xr sleep 9 .
     In fact it could in some cases be 
     considered a conditional sleep.
    -.Ss Turnstiles
    -Turnstiles are used to hold a queue of threads blocked on
    -non-sleepable locks.
    -Sleepable locks use condition variables to implement their queues.
    -Turnstiles differ from a sleep queue in that turnstile queue's
    -are assigned to a lock held by an owning thread.
    -Thus, when one thread is enqueued onto a turnstile, it can lend its
    -priority to the owning thread.
    -If this sounds confusing, we need to describe it better.
    -.Ss Semaphores
    +.Pp
    +See
    +.Xr sx 9
    +for details.
    +.Ss Counting semaphores
    +Counting semaphores provide a mechanism for synchronizing access
    +to a pool of resources.
    +Unlike mutexes, semaphores do not have the concept of an owner,
    +so they can be useful in situations where one thread needs
    +to acquire a resource, and another thread needs to release it.
    +They are largely deprecated.
    +.Pp
    +See
    +.Xr sema 9
    +for details.
     .Ss Condition variables
     Condition variables are used in conjunction with mutexes to wait for
     conditions to occur.
    @@ -220,24 +148,30 @@ functions.
     When a thread waits on a condition, the mutex
     is atomically released before the thread is blocked, then reacquired
     before the function call returns.
    +.Pp
    +See
    +.Xr condvar 9
    +for details.
     .Ss Giant
    -Giant is a special instance of a sleep lock.
    -It has several special characteristics.
    +Giant is an instance of a mutex, with some special characteristics:
     .Bl -enum
     .It
     It is recursive.
     .It
    -Drivers can request that Giant be locked around them, but this is
    -going away.
    -.It
    -You can sleep while it has recursed, but other recursive locks cannot.
    +Drivers and filesystems can request that Giant be locked around them
    +by not marking themselves MPSAFE.
    +Note that infrastructure to do this is slowly going away as non-MPSAFE
    +drivers either became properly locked or disappear.
     .It
     Giant must be locked first before other locks.
     .It
    +It is OK to hold Giant while performing unbounded sleep; in such case,
    +Giant will be dropped before sleeping and picked up after wakeup.
    +.It
     There are places in the kernel that drop Giant and pick it back up
     again.
     Sleep locks will do this before sleeping.
    -Parts of the Network or VM code may do this as well, depending on the
    +Parts of the network or VM code may do this as well, depending on the
     setting of a sysctl.
     This means that you cannot count on Giant keeping other code from
     running if your code sleeps, even if you want it to.
    @@ -298,26 +232,76 @@ while the thread is suspended and will reacquire the
     .Va Giant
     mutex before the function returns.
     .Pp
    -.Ss lockmanager locks
    -Largely deprecated.
    -See the
    +See
    +.Xr sleep 9
    +for details.
    +.Pp
    +.Ss Lockmanager locks
    +Shared/exclusive locks, used mostly in
    +.Xr VFS 9 ,
    +in particular as a
    +.Xr vnode 9
    +lock.
    +They have features other lock types don't have, such as sleep timeout,
    +writer starvation avoidance, draining, and interlock mutex, but this makes them
    +complicated to implement; for this reason, they are deprecated.
    +.Pp
    +See
     .Xr lock 9
    -page for more information.
    -I don't know what the downsides are but I'm sure someone will fill in this part.
    -.Sh Usage tables.
    -.Ss Interaction table.
    -The following table shows what you can and can not do if you hold
    -one of the synchronization primitives discussed here:
    -(someone who knows what they are talking about should write this table)
    -.Bl -column ".Ic xxxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXX" -offset indent
    +for details.
    +.Sh INTERACTIONS
    +The primitives interact and have a number of rules regarding how
    +they can and can not be combined.
    +Many of these rules are checked using the
    +.Xr witness 4
    +code.
    +.Ss Bounded vs. unbounded sleep
    +The following primitives perform bounded sleep: mutexes, pool mutexes,
    +reader/writer locks and read-mostly locks.
    +.Pp
    +The following primitives block (perform unbounded sleep): shared/exclusive locks,
    +counting semaphores, condition variables, sleep/wakeup and lockmanager locks.
    +.Pp
    +It is an error to do any operation that could result in any kind of sleep while
    +holding spin mutex.
    +.Pp
    +As a general rule, it is an error to do any operation that could result
    +in unbounded sleep while holding any primitive from the 'bounded sleep' group.
    +For example, it is an error to try to acquire shared/exclusive lock while
    +holding mutex, or to try to allocate memory with M_WAITOK while holding
    +read-write lock.
    +.Pp
    +As a special case, it is possible to call
    +.Fn sleep
    +or
    +.Fn mtx_sleep
    +while holding a single mutex.
    +It will atomically drop that mutex and reacquire it as part of waking up.
    +This is often a bad idea because it generally relies on the programmer having
    +good knowledge of all of the call graph above the place where
    +.Fn mtx_sleep
    +is being called and assumptions the calling code has made.
    +Because the lock gets dropped during sleep, one one must re-test all
    +the assumptions that were made before, all the way up the call graph to the
    +place where the lock was acquired.
    +.Pp
    +It is an error to do any operation that could result in any kind of sleep when
    +running inside an interrupt filter.
    +.Pp
    +It is an error to do any operation that could result in unbounded sleep when
    +running inside an interrupt thread.
    +.Ss Interaction table
    +The following table shows what you can and can not do while holding
    +one of the synchronization primitives discussed:
    +.Bl -column ".Ic xxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXX" -offset indent
     .It Xo
    -.Em "You have: You want:" Ta Spin_mtx Ta Slp_mtx Ta sx_lock Ta rw_lock Ta rm_lock Ta sleep
    +.Em "You have: You want:" Ta spin mtx Ta mutex Ta sx Ta rwlock Ta rmlock Ta sleep
     .Xc
    -.It Ic SPIN mutex  Ta \&ok-1 Ta \&no Ta \&no Ta \&no Ta \&no Ta \&no-3
    -.It Ic Sleep mutex Ta \&ok Ta \&ok-1 Ta \&no Ta \&ok Ta \&ok Ta \&no-3
    -.It Ic sx_lock     Ta \&ok Ta \&ok Ta \&ok-2 Ta \&ok Ta \&ok Ta \&ok-4
    -.It Ic rw_lock     Ta \&ok Ta \&ok Ta \&no Ta \&ok-2 Ta \&ok Ta \&no-3
    -.It Ic rm_lock     Ta \&ok Ta \&ok Ta \&no Ta \&ok Ta \&ok-2 Ta \&no
    +.It spin mtx  Ta \&ok-1 Ta \&no Ta \&no Ta \&no Ta \&no Ta \&no-3
    +.It mutex     Ta \&ok Ta \&ok-1 Ta \&no Ta \&ok Ta \&ok Ta \&no-3
    +.It sx        Ta \&ok Ta \&ok Ta \&ok-2 Ta \&ok Ta \&ok Ta \&ok-4
    +.It rwlock    Ta \&ok Ta \&ok Ta \&no Ta \&ok-2 Ta \&ok Ta \&no-3
    +.It rmlock    Ta \&ok Ta \&ok Ta \&no Ta \&ok Ta \&ok-2 Ta \&no
     .El
     .Pp
     .Em *1
    @@ -325,11 +309,11 @@ Recursion is defined per lock.
     Lock order is important.
     .Pp
     .Em *2
    -readers can recurse though writers can not.
    +Readers can recurse though writers can not.
     Lock order is important.
     .Pp
     .Em *3
    -There are calls atomically release this primitive when going to sleep
    +There are calls that atomically release this primitive when going to sleep
     and reacquire it on wakeup (e.g.
     .Fn mtx_sleep ,
     .Fn rw_sleep
    @@ -340,19 +324,22 @@ and
     .Em *4
     Though one can sleep holding an sx lock, one can also use
     .Fn sx_sleep
    -which atomically release this primitive when going to sleep and
    +which will atomically release this primitive when going to sleep and
     reacquire it on wakeup.
    -.Ss Context mode table.
    +.Ss Context mode table
     The next table shows what can be used in different contexts.
     At this time this is a rather easy to remember table.
    -.Bl -column ".Ic Xxxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXX" -offset indent
    +.Bl -column ".Ic Xxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXX" -offset indent
     .It Xo
    -.Em "Context:" Ta Spin_mtx Ta Slp_mtx Ta sx_lock Ta rw_lock Ta rm_lock Ta sleep
    +.Em "Context:"  Ta spin mtx Ta mutex Ta sx Ta rwlock Ta rmlock Ta sleep
     .Xc
    -.It interrupt:  Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no Ta \&no 
    -.It idle:  Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no Ta \&no 
    +.It interrupt filter:  Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no Ta \&no 
    +.It ithread:    Ta \&ok Ta \&ok Ta \&no Ta \&ok Ta \&ok Ta \&no 
    +.It callout:    Ta \&ok Ta \&ok Ta \&no Ta \&ok Ta \&no Ta \&no 
    +.It syscall:    Ta \&ok Ta \&ok Ta \&ok Ta \&ok Ta \&ok Ta \&ok 
     .El
     .Sh SEE ALSO
    +.Xr witness 4 ,
     .Xr condvar 9 ,
     .Xr lock 9 ,
     .Xr mtx_pool 9 ,
    @@ -362,11 +349,12 @@ At this time this is a rather easy to remember table.
     .Xr sema 9 ,
     .Xr sleep 9 ,
     .Xr sx 9 ,
    -.Xr LOCK_PROFILING 9 ,
    -.Xr WITNESS 9
    +.Xr LOCK_PROFILING 9
     .Sh HISTORY
     These
     functions appeared in
     .Bsx 4.1
     through
     .Fx 7.0
    +.Sh BUGS
    +There are too many locking primitives to choose from.
    
    From f004e8133a9190332abee40b9933c6d87611984f Mon Sep 17 00:00:00 2001
    From: Jaakko Heinonen 
    Date: Sun, 28 Mar 2010 11:22:38 +0000
    Subject: [PATCH 1731/2592] MFC r198175:
    
    - 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
    ---
     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 616900d1eb809a760181d5756da7e9ed1970bae8 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sun, 28 Mar 2010 18:43:04 +0000
    Subject: [PATCH 1732/2592] MFC r203549:
    
    Add missing coma.
    ---
     share/man/man9/mtx_pool.9 | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/share/man/man9/mtx_pool.9 b/share/man/man9/mtx_pool.9
    index e289f3c1836..ab2cc8b31b1 100644
    --- a/share/man/man9/mtx_pool.9
    +++ b/share/man/man9/mtx_pool.9
    @@ -27,7 +27,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd March 25, 2002
    +.Dd February 6, 2010
     .Dt MTX_POOL 9
     .Os
     .Sh NAME
    @@ -177,7 +177,7 @@ on each mutex in the specified pool,
     deallocates the memory associated with the pool,
     and assigns NULL to the pool pointer.
     .Sh SEE ALSO
    -.Xr locking 9
    +.Xr locking 9 ,
     .Xr mutex 9
     .Sh HISTORY
     These routines first appeared in
    
    From b1711e4af4e501d079747994ce232c0b43f07730 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sun, 28 Mar 2010 18:44:54 +0000
    Subject: [PATCH 1733/2592] MFC r203721:
    
    Add references to VOP_* man pages to vnode(9).
    ---
     share/man/man9/vnode.9 | 34 +++++++++++++++++++++++++++++++++-
     1 file changed, 33 insertions(+), 1 deletion(-)
    
    diff --git a/share/man/man9/vnode.9 b/share/man/man9/vnode.9
    index b55b19b650b..96aec73e6b3 100644
    --- a/share/man/man9/vnode.9
    +++ b/share/man/man9/vnode.9
    @@ -26,7 +26,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd May 20, 2003
    +.Dd February 9, 2010
     .Os
     .Dt VNODE 9
     .Sh NAME
    @@ -161,6 +161,38 @@ interlock, will cause a LOR (Lock Order Reversal) due to the
     intertwining of VM Objects and Vnodes.
     .Sh SEE ALSO
     .Xr malloc 9 ,
    +.Xr VOP_ACCESS 9 ,
    +.Xr VOP_ACLCHECK 9 ,
    +.Xr VOP_ADVLOCK 9 ,
    +.Xr VOP_ATTRIB 9 ,
    +.Xr VOP_BWRITE 9 ,
    +.Xr VOP_CREATE 9 ,
    +.Xr VOP_FSYNC 9 ,
    +.Xr VOP_GETACL 9 ,
    +.Xr VOP_GETEXTATTR 9 ,
    +.Xr VOP_GETPAGES 9 ,
    +.Xr VOP_GETVOBJECT 9 ,
    +.Xr VOP_INACTIVE 9 ,
    +.Xr VOP_IOCTL 9 ,
    +.Xr VOP_LINK 9 ,
    +.Xr VOP_LISTEXTATTR 9 ,
    +.Xr VOP_LOCK 9 ,
    +.Xr VOP_LOOKUP 9 ,
    +.Xr VOP_OPENCLOSE 9 ,
    +.Xr VOP_PATHCONF 9 ,
    +.Xr VOP_PRINT 9 ,
    +.Xr VOP_RDWR 9 ,
    +.Xr VOP_READDIR 9 ,
    +.Xr VOP_READLINK 9 ,
    +.Xr VOP_REALLOCBLKS 9 ,
    +.Xr VOP_REMOVE 9 ,
    +.Xr VOP_RENAME 9 ,
    +.Xr VOP_REVOKE 9 ,
    +.Xr VOP_SETACL 9 ,
    +.Xr VOP_SETEXTATTR 9 ,
    +.Xr VOP_STRATEGY 9 ,
    +.Xr VOP_VPTOCNP 9 ,
    +.Xr VOP_VPTOFH 9 ,
     .Xr VFS 9
     .Sh AUTHORS
     This manual page was written by
    
    From dc40ac1d45e24ef6e4a3a53846ec87dead4be8ae Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Sun, 28 Mar 2010 18:46:01 +0000
    Subject: [PATCH 1734/2592] MFC r203824:
    
    Fix VBAD description.
    ---
     share/man/man9/vnode.9 | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/share/man/man9/vnode.9 b/share/man/man9/vnode.9
    index 96aec73e6b3..49a2cc77d1c 100644
    --- a/share/man/man9/vnode.9
    +++ b/share/man/man9/vnode.9
    @@ -26,7 +26,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd February 9, 2010
    +.Dd February 13, 2010
     .Os
     .Dt VNODE 9
     .Sh NAME
    @@ -137,7 +137,7 @@ Advisory locking will not work on this.
     A FIFO (named pipe).
     Advisory locking will not work on this.
     .It Dv VBAD
    -An old style bad sector map
    +Indicates that the vnode has been reclaimed.
     .El
     .Sh IMPLEMENTATION NOTES
     VFIFO uses the "struct fileops" from
    
    From f76db14de93f9fb9dc1e0184ba376860a26824f6 Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sun, 28 Mar 2010 19:34:57 +0000
    Subject: [PATCH 1735/2592] MFC
     r196607,r198453,r204016,r204017,r204836,r204842,r205105,r205153 Various
     testcases that work correctly with stable/8 sh.
    
    Note: this creates some gaps in the numbering due to lower-numbered tests
    for new functionality which is not or not yet MFC'ed.
    ---
     tools/regression/bin/sh/builtins/eval3.0      |  9 ++
     .../bin/sh/errors/redirection-error5.0        |  5 ++
     tools/regression/bin/sh/expansion/arith2.0    |  1 +
     tools/regression/bin/sh/expansion/arith3.0    | 14 +++
     tools/regression/bin/sh/expansion/assign1.0   | 37 ++++++++
     tools/regression/bin/sh/expansion/cmdsubst2.0 | 43 ++++++++++
     .../regression/bin/sh/expansion/plus-minus1.0 | 81 ++++++++++++++++++
     tools/regression/bin/sh/expansion/question1.0 | 22 +++++
     tools/regression/bin/sh/expansion/set-u1.0    | 29 +++++++
     tools/regression/bin/sh/parser/heredoc1.0     | 85 +++++++++++++++++++
     10 files changed, 326 insertions(+)
     create mode 100644 tools/regression/bin/sh/builtins/eval3.0
     create mode 100644 tools/regression/bin/sh/errors/redirection-error5.0
     create mode 100644 tools/regression/bin/sh/expansion/arith3.0
     create mode 100644 tools/regression/bin/sh/expansion/assign1.0
     create mode 100644 tools/regression/bin/sh/expansion/cmdsubst2.0
     create mode 100644 tools/regression/bin/sh/expansion/plus-minus1.0
     create mode 100644 tools/regression/bin/sh/expansion/question1.0
     create mode 100644 tools/regression/bin/sh/expansion/set-u1.0
     create mode 100644 tools/regression/bin/sh/parser/heredoc1.0
    
    diff --git a/tools/regression/bin/sh/builtins/eval3.0 b/tools/regression/bin/sh/builtins/eval3.0
    new file mode 100644
    index 00000000000..dfb8357c727
    --- /dev/null
    +++ b/tools/regression/bin/sh/builtins/eval3.0
    @@ -0,0 +1,9 @@
    +# $FreeBSD$
    +
    +eval 'false;' && exit 1
    +eval 'true;' || exit 1
    +eval 'false;
    +' && exit 1
    +eval 'true;
    +' || exit 1
    +exit 0
    diff --git a/tools/regression/bin/sh/errors/redirection-error5.0 b/tools/regression/bin/sh/errors/redirection-error5.0
    new file mode 100644
    index 00000000000..1fcd47eebf9
    --- /dev/null
    +++ b/tools/regression/bin/sh/errors/redirection-error5.0
    @@ -0,0 +1,5 @@
    +# $FreeBSD$
    +# A redirection error on a subshell should not abort the shell.
    +exec 2>/dev/null
    +( echo bad )  0))
    diff --git a/tools/regression/bin/sh/expansion/plus-minus1.0 b/tools/regression/bin/sh/expansion/plus-minus1.0
    new file mode 100644
    index 00000000000..e98c9895392
    --- /dev/null
    +++ b/tools/regression/bin/sh/expansion/plus-minus1.0
    @@ -0,0 +1,81 @@
    +# $FreeBSD$
    +
    +e= q='?' a='*' t=texttext s='ast*que?non' p='/et[c]/' w='a b c' b='{{(#)}}'
    +h='##'
    +failures=''
    +ok=''
    +
    +testcase() {
    +	code="$1"
    +	expected="$2"
    +	oIFS="$IFS"
    +	eval "$code"
    +	IFS='|'
    +	result="$#|$*"
    +	IFS="$oIFS"
    +	if [ "x$result" = "x$expected" ]; then
    +		ok=x$ok
    +	else
    +		failures=x$failures
    +		echo "For $code, expected $expected actual $result"
    +	fi
    +}
    +
    +testcase 'set -- a b'				'2|a|b'
    +testcase 'set --'				'0|'
    +testcase 'set -- ${e}'				'0|'
    +testcase 'set -- "${e}"'			'1|'
    +
    +testcase 'set -- $p'				'1|/etc/'
    +testcase 'set -- "$p"'				'1|/et[c]/'
    +testcase 'set -- ${s+$p}'			'1|/etc/'
    +testcase 'set -- "${s+$p}"'			'1|/et[c]/'
    +testcase 'set -- ${s+"$p"}'			'1|/et[c]/'
    +# Dquotes in dquotes is undefined for Bourne shell operators
    +#testcase 'set -- "${s+"$p"}"'			'1|/et[c]/'
    +testcase 'set -- ${e:-$p}'			'1|/etc/'
    +testcase 'set -- "${e:-$p}"'			'1|/et[c]/'
    +testcase 'set -- ${e:-"$p"}'			'1|/et[c]/'
    +# Dquotes in dquotes is undefined for Bourne shell operators
    +#testcase 'set -- "${e:-"$p"}"'			'1|/et[c]/'
    +testcase 'set -- ${e:+"$e"}'			'0|'
    +testcase 'set -- ${e:+$w"$e"}'			'0|'
    +testcase 'set -- ${w:+"$w"}'			'1|a b c'
    +testcase 'set -- ${w:+$w"$w"}'			'3|a|b|ca b c'
    +
    +# These two are known broken in FreeBSD /bin/sh
    +#testcase 'set -- ${s+a b}'			'2|a|b'
    +#testcase 'set -- ${e:-a b}'			'2|a|b'
    +testcase 'set -- "${s+a b}"'			'1|a b'
    +testcase 'set -- "${e:-a b}"'			'1|a b'
    +testcase 'set -- ${e:-\}}'			'1|}'
    +# Currently broken in FreeBSD /bin/sh
    +#testcase 'set -- "${e:-\}}"'			'1|}'
    +testcase 'set -- ${e:+{}}'			'1|}'
    +testcase 'set -- "${e:+{}}"'			'1|}'
    +
    +testcase 'set -- ${e+x}${e+x}'			'1|xx'
    +testcase 'set -- "${e+x}"${e+x}'		'1|xx'
    +testcase 'set -- ${e+x}"${e+x}"'		'1|xx'
    +testcase 'set -- "${e+x}${e+x}"'		'1|xx'
    +testcase 'set -- "${e+x}""${e+x}"'		'1|xx'
    +
    +testcase 'set -- ${e:-${e:-$p}}'		'1|/etc/'
    +testcase 'set -- "${e:-${e:-$p}}"'		'1|/et[c]/'
    +testcase 'set -- ${e:-"${e:-$p}"}'		'1|/et[c]/'
    +testcase 'set -- ${e:-${e:-"$p"}}'		'1|/et[c]/'
    +testcase 'set -- ${e:-${e:-${e:-$w}}}'		'3|a|b|c'
    +testcase 'set -- ${e:-${e:-${e:-"$w"}}}'	'1|a b c'
    +testcase 'set -- ${e:-${e:-"${e:-$w}"}}'	'1|a b c'
    +testcase 'set -- ${e:-"${e:-${e:-$w}}"}'	'1|a b c'
    +testcase 'set -- "${e:-${e:-${e:-$w}}}"'	'1|a b c'
    +
    +testcase 'shift $#; set -- ${1+"$@"}'		'0|'
    +testcase 'set -- ""; set -- ${1+"$@"}'		'1|'
    +testcase 'set -- "" a; set -- ${1+"$@"}'	'2||a'
    +testcase 'set -- a ""; set -- ${1+"$@"}'	'2|a|'
    +testcase 'set -- a b; set -- ${1+"$@"}'		'2|a|b'
    +testcase 'set -- a\ b; set -- ${1+"$@"}'	'1|a b'
    +testcase 'set -- " " ""; set -- ${1+"$@"}'	'2| |'
    +
    +test "x$failures" = x
    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
    diff --git a/tools/regression/bin/sh/parser/heredoc1.0 b/tools/regression/bin/sh/parser/heredoc1.0
    new file mode 100644
    index 00000000000..5ce38977d7f
    --- /dev/null
    +++ b/tools/regression/bin/sh/parser/heredoc1.0
    @@ -0,0 +1,85 @@
    +# $FreeBSD$
    +
    +failures=0
    +
    +check() {
    +	if ! eval "[ $* ]"; then
    +		echo "Failed: $*"
    +		: $((failures += 1))
    +	fi
    +}
    +
    +check '"$(cat <
    Date: Sun, 28 Mar 2010 20:19:41 +0000
    Subject: [PATCH 1736/2592] MFC r200818: rc.subr: Use pwait in wait_for_pids.
    
    This waits for the requested process(es) to terminate, rather than polling
    with an interval of 2 seconds.
    
    If pwait is not available, the old method is used.
    
    PR:		conf/132766
    ---
     etc/rc.subr | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/etc/rc.subr b/etc/rc.subr
    index cfb2942965c..091ac3fed7e 100644
    --- a/etc/rc.subr
    +++ b/etc/rc.subr
    @@ -390,7 +390,7 @@ wait_for_pids()
     		_list=$_nlist
     		echo -n ${_prefix:-"Waiting for PIDS: "}$_list
     		_prefix=", "
    -		sleep 2
    +		pwait $_list 2>/dev/null || sleep 2
     	done
     	if [ -n "$_prefix" ]; then
     		echo "."
    
    From 83867e0aa4f7fb6b1b02ab838a9747ef7af8b724 Mon Sep 17 00:00:00 2001
    From: Ed Maste 
    Date: Mon, 29 Mar 2010 00:08:58 +0000
    Subject: [PATCH 1737/2592] MFC r205411:
    
      Avoid holding the VLAN_LOCK() over the parent interface SIOCGIFMEDIA
      ioctl call, as it may sleep.
    
      Reviewed by:    rwatson
    ---
     sys/net/if_vlan.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
    index 47bdc07f1c9..c513bd719f9 100644
    --- a/sys/net/if_vlan.c
    +++ b/sys/net/if_vlan.c
    @@ -1335,9 +1335,9 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     	case SIOCGIFMEDIA:
     		VLAN_LOCK();
     		if (TRUNK(ifv) != NULL) {
    -			error = (*PARENT(ifv)->if_ioctl)(PARENT(ifv),
    -					SIOCGIFMEDIA, data);
    +			p = PARENT(ifv);
     			VLAN_UNLOCK();
    +			error = (*p->if_ioctl)(p, SIOCGIFMEDIA, data);
     			/* Limit the result to the parent's current config. */
     			if (error == 0) {
     				struct ifmediareq *ifmr;
    
    From 436405f5222234e1494d87108954d7f0b026a3eb Mon Sep 17 00:00:00 2001
    From: Ed Maste 
    Date: Mon, 29 Mar 2010 00:14:34 +0000
    Subject: [PATCH 1738/2592] MFC r204264:
    
      Minor diff reduction with Adaptec's driver: in aac_release_command() set
      cm_queue to AAC_ADAP_NORM_CMD_QUEUE by default.  In every place it was
      set, it was set to AAC_ADAP_NORM_CMD_QUEUE anyhow.
    ---
     sys/dev/aac/aac.c     | 3 +--
     sys/dev/aac/aac_cam.c | 1 -
     2 files changed, 1 insertion(+), 3 deletions(-)
    
    diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
    index ea58895a2a6..9d7ed6ba568 100644
    --- a/sys/dev/aac/aac.c
    +++ b/sys/dev/aac/aac.c
    @@ -1218,7 +1218,6 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
     	cm->cm_complete = aac_bio_complete;
     	cm->cm_private = bp;
     	cm->cm_timestamp = time_uptime;
    -	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
     
     	/* build the FIB */
     	fib = cm->cm_fib;
    @@ -1373,7 +1372,6 @@ aac_wait_command(struct aac_command *cm)
     	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
     
     	/* Put the command on the ready queue and get things going */
    -	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
     	aac_enqueue_ready(cm);
     	aac_startio(sc);
     	error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0);
    @@ -1423,6 +1421,7 @@ aac_release_command(struct aac_command *cm)
     	cm->cm_flags = 0;
     	cm->cm_complete = NULL;
     	cm->cm_private = NULL;
    +	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
     	cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
     	cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
     	cm->cm_fib->Header.Flags = 0;
    diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c
    index e9fc8e26c00..827ce8e51c5 100644
    --- a/sys/dev/aac/aac_cam.c
    +++ b/sys/dev/aac/aac_cam.c
    @@ -453,7 +453,6 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
     	cm->cm_complete = aac_cam_complete;
     	cm->cm_private = ccb;
     	cm->cm_timestamp = time_uptime;
    -	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
     
     	fib->Header.XferState =
     	    AAC_FIBSTATE_HOSTOWNED	|
    
    From 171dfe111d0a03a13c4a1dfefd1b37c628162e5b Mon Sep 17 00:00:00 2001
    From: Ed Maste 
    Date: Mon, 29 Mar 2010 00:30:44 +0000
    Subject: [PATCH 1739/2592] MFC aac(4) driver changes
    
    r204019:
    
      Include command type in COMMAND TIMEOUT messages to aid in debugging.
    
    r203885:
    
      Diff reduction with Adaptec's vendor driver.
    
      Driver version 2.1.9 chosen as that Adaptec version roughly corresponds
      with the current feature set merged to the in-tree driver.
    
    r203801:
    
      Garbage collect Falcon/PPC support that has not been used in released
      products, based on discussion with Adaptec.
    
    r198617:
    
      Rename aac_srb32 to aac_srb, to match Adaptec's vendor driver.
    ---
     sys/dev/aac/aac.c     | 129 +++++-------------------------------------
     sys/dev/aac/aac_cam.c |  18 +++---
     sys/dev/aac/aac_pci.c |   4 --
     sys/dev/aac/aacreg.h  |  22 +------
     sys/dev/aac/aacvar.h  |  11 +++-
     5 files changed, 35 insertions(+), 149 deletions(-)
    
    diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
    index 9d7ed6ba568..3d9ae7223d0 100644
    --- a/sys/dev/aac/aac.c
    +++ b/sys/dev/aac/aac.c
    @@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$");
     /*
      * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
      */
    -#define AAC_DRIVER_VERSION		0x02000000
     #define AAC_DRIVERNAME			"aac"
     
     #include "opt_aac.h"
    @@ -107,28 +106,6 @@ static int	aac_dequeue_fib(struct aac_softc *sc, int queue,
     static int	aac_enqueue_response(struct aac_softc *sc, int queue,
     				     struct aac_fib *fib);
     
    -/* Falcon/PPC interface */
    -static int	aac_fa_get_fwstatus(struct aac_softc *sc);
    -static void	aac_fa_qnotify(struct aac_softc *sc, int qbit);
    -static int	aac_fa_get_istatus(struct aac_softc *sc);
    -static void	aac_fa_clear_istatus(struct aac_softc *sc, int mask);
    -static void	aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
    -				   u_int32_t arg0, u_int32_t arg1,
    -				   u_int32_t arg2, u_int32_t arg3);
    -static int	aac_fa_get_mailbox(struct aac_softc *sc, int mb);
    -static void	aac_fa_set_interrupts(struct aac_softc *sc, int enable);
    -
    -struct aac_interface aac_fa_interface = {
    -	aac_fa_get_fwstatus,
    -	aac_fa_qnotify,
    -	aac_fa_get_istatus,
    -	aac_fa_clear_istatus,
    -	aac_fa_set_mailbox,
    -	aac_fa_get_mailbox,
    -	aac_fa_set_interrupts,
    -	NULL, NULL, NULL
    -};
    -
     /* StrongARM interface */
     static int	aac_sa_get_fwstatus(struct aac_softc *sc);
     static void	aac_sa_qnotify(struct aac_softc *sc, int qbit);
    @@ -2374,8 +2351,9 @@ aac_timeout(struct aac_softc *sc)
     			/* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
     			cm->cm_flags |= AAC_CMD_TIMEDOUT;
     			device_printf(sc->aac_dev,
    -				      "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
    -				      cm, (int)(time_uptime-cm->cm_timestamp));
    +			    "COMMAND %p (TYPE %d) TIMEOUT AFTER %d SECONDS\n",
    +			    cm, cm->cm_fib->Header.Command,
    +			    (int)(time_uptime-cm->cm_timestamp));
     			AAC_PRINT_FIB(sc, cm->cm_fib);
     			timedout++;
     		}
    @@ -2415,17 +2393,6 @@ aac_rx_get_fwstatus(struct aac_softc *sc)
     	    AAC_RX_OMR0 : AAC_RX_FWSTATUS));
     }
     
    -static int
    -aac_fa_get_fwstatus(struct aac_softc *sc)
    -{
    -	int val;
    -
    -	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
    -
    -	val = AAC_MEM0_GETREG4(sc, AAC_FA_FWSTATUS);
    -	return (val);
    -}
    -
     static int
     aac_rkt_get_fwstatus(struct aac_softc *sc)
     {
    @@ -2455,15 +2422,6 @@ aac_rx_qnotify(struct aac_softc *sc, int qbit)
     	AAC_MEM0_SETREG4(sc, AAC_RX_IDBR, qbit);
     }
     
    -static void
    -aac_fa_qnotify(struct aac_softc *sc, int qbit)
    -{
    -	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
    -
    -	AAC_MEM0_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
    -	AAC_FA_HACK(sc);
    -}
    -
     static void
     aac_rkt_qnotify(struct aac_softc *sc, int qbit)
     {
    @@ -2491,17 +2449,6 @@ aac_rx_get_istatus(struct aac_softc *sc)
     	return(AAC_MEM0_GETREG4(sc, AAC_RX_ODBR));
     }
     
    -static int
    -aac_fa_get_istatus(struct aac_softc *sc)
    -{
    -	int val;
    -
    -	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
    -
    -	val = AAC_MEM0_GETREG2(sc, AAC_FA_DOORBELL0);
    -	return (val);
    -}
    -
     static int
     aac_rkt_get_istatus(struct aac_softc *sc)
     {
    @@ -2529,15 +2476,6 @@ aac_rx_clear_istatus(struct aac_softc *sc, int mask)
     	AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, mask);
     }
     
    -static void
    -aac_fa_clear_istatus(struct aac_softc *sc, int mask)
    -{
    -	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
    -
    -	AAC_MEM0_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
    -	AAC_FA_HACK(sc);
    -}
    -
     static void
     aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
     {
    @@ -2575,24 +2513,6 @@ aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
     	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
     }
     
    -static void
    -aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
    -		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
    -{
    -	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
    -
    -	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX, command);
    -	AAC_FA_HACK(sc);
    -	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
    -	AAC_FA_HACK(sc);
    -	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
    -	AAC_FA_HACK(sc);
    -	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
    -	AAC_FA_HACK(sc);
    -	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
    -	AAC_FA_HACK(sc);
    -}
    -
     static void
     aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
     		    u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
    @@ -2625,17 +2545,6 @@ aac_rx_get_mailbox(struct aac_softc *sc, int mb)
     	return(AAC_MEM1_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
     }
     
    -static int
    -aac_fa_get_mailbox(struct aac_softc *sc, int mb)
    -{
    -	int val;
    -
    -	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
    -
    -	val = AAC_MEM1_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4));
    -	return (val);
    -}
    -
     static int
     aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
     {
    @@ -2674,20 +2583,6 @@ aac_rx_set_interrupts(struct aac_softc *sc, int enable)
     	}
     }
     
    -static void
    -aac_fa_set_interrupts(struct aac_softc *sc, int enable)
    -{
    -	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
    -
    -	if (enable) {
    -		AAC_MEM0_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
    -		AAC_FA_HACK(sc);
    -	} else {
    -		AAC_MEM0_SETREG2((sc), AAC_FA_MASK0, ~0);
    -		AAC_FA_HACK(sc);
    -	}
    -}
    -
     static void
     aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
     {
    @@ -2871,10 +2766,8 @@ aac_describe_controller(struct aac_softc *sc)
     	}
     	device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
     		adapter_type,
    -		AAC_DRIVER_VERSION >> 24,
    -		(AAC_DRIVER_VERSION >> 16) & 0xFF,
    -		AAC_DRIVER_VERSION & 0xFF,
    -		AAC_DRIVER_BUILD);
    +		AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION,
    +		AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD);
     
     	aac_release_sync_fib(sc);
     	mtx_unlock(&sc->aac_io_lock);
    @@ -3359,10 +3252,16 @@ aac_rev_check(struct aac_softc *sc, caddr_t udata)
     	 * Doctor up the response struct.
     	 */
     	rev_check_resp.possiblyCompatible = 1;
    -	rev_check_resp.adapterSWRevision.external.ul =
    -	    sc->aac_revision.external.ul;
    +	rev_check_resp.adapterSWRevision.external.comp.major =
    +	    AAC_DRIVER_MAJOR_VERSION;
    +	rev_check_resp.adapterSWRevision.external.comp.minor =
    +	    AAC_DRIVER_MINOR_VERSION;
    +	rev_check_resp.adapterSWRevision.external.comp.type =
    +	    AAC_DRIVER_TYPE;
    +	rev_check_resp.adapterSWRevision.external.comp.dash =
    +	    AAC_DRIVER_BUGFIX_LEVEL;
     	rev_check_resp.adapterSWRevision.buildNumber =
    -	    sc->aac_revision.buildNumber;
    +	    AAC_DRIVER_BUILD;
     
     	return(copyout((caddr_t)&rev_check_resp, udata,
     			sizeof(struct aac_rev_check_resp)));
    diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c
    index 827ce8e51c5..c1164aa2d3f 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;
     
    @@ -354,7 +354,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) {
    @@ -405,10 +405,10 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
     				if (ccb->ccb_h.flags & CAM_DATA_PHYS) {
     					/* Send a 32bit command */
     					fib->Header.Command = ScsiPortCommand;
    -					srb->sg_map32.SgCount = 1;
    -					srb->sg_map32.SgEntry[0].SgAddress =
    +					srb->sg_map.SgCount = 1;
    +					srb->sg_map.SgEntry[0].SgAddress =
     					    (uint32_t)(uintptr_t)csio->data_ptr;
    -					srb->sg_map32.SgEntry[0].SgByteCount =
    +					srb->sg_map.SgEntry[0].SgByteCount =
     					    csio->dxfer_len;
     				} else {
     					/*
    @@ -417,15 +417,15 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
     					 */
     					cm->cm_data = (void *)csio->data_ptr;
     					cm->cm_datalen = csio->dxfer_len;
    -					cm->cm_sgtable = &srb->sg_map32;
    +					cm->cm_sgtable = &srb->sg_map;
     				}
     			} else {
     				/* XXX Need to handle multiple s/g elements */
     				panic("aac_cam: multiple s/g elements");
     			}
     		} else {
    -			srb->sg_map32.SgCount = 0;
    -			srb->sg_map32.SgEntry[0].SgByteCount = 0;
    +			srb->sg_map.SgCount = 0;
    +			srb->sg_map.SgEntry[0].SgByteCount = 0;
     			srb->data_len = 0;
     		}
     
    @@ -461,7 +461,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/aac_pci.c b/sys/dev/aac/aac_pci.c
    index 17731a8032c..bc993791f8b 100644
    --- a/sys/dev/aac/aac_pci.c
    +++ b/sys/dev/aac/aac_pci.c
    @@ -435,10 +435,6 @@ aac_pci_attach(device_t dev)
     		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for StrongARM");
     		sc->aac_if = aac_sa_interface;
     		break;
    -	case AAC_HWIF_FALCON:
    -		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Falcon/PPC");
    -		sc->aac_if = aac_fa_interface;
    -		break;
     	case AAC_HWIF_RKT:
     		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Rocket/MIPS");
     		sc->aac_if = aac_rkt_interface;
    diff --git a/sys/dev/aac/aacreg.h b/sys/dev/aac/aacreg.h
    index db96ff206d9..5c849664a47 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;
    @@ -1374,7 +1374,7 @@ struct aac_srb32 {
     	u_int32_t		retry_limit;
     	u_int32_t		cdb_len;
     	u_int8_t		cdb[16];
    -	struct aac_sg_table	sg_map32;
    +	struct aac_sg_table	sg_map;
     };
     
     enum {
    @@ -1452,24 +1452,6 @@ enum {
     	AAC_SRB_STS_ERROR_RECOVERY
     };
     
    -/*
    - * Register set for adapters based on the Falcon bridge and PPC core
    - */
    -
    -#define AAC_FA_DOORBELL0_CLEAR		0x00
    -#define AAC_FA_DOORBELL1_CLEAR		0x02
    -#define AAC_FA_DOORBELL0		0x04
    -#define AAC_FA_DOORBELL1		0x06
    -#define AAC_FA_MASK0_CLEAR		0x08
    -#define AAC_FA_MASK1_CLEAR		0x0a
    -#define	AAC_FA_MASK0			0x0c
    -#define AAC_FA_MASK1			0x0e
    -#define AAC_FA_MAILBOX			0x10
    -#define	AAC_FA_FWSTATUS			0x2c	/* Mailbox 7 */
    -#define	AAC_FA_INTSRC			0x900
    -
    -#define AAC_FA_HACK(sc)	(void)AAC_MEM0_GETREG4(sc, AAC_FA_INTSRC)
    -
     /*
      * Register definitions for the Adaptec AAC-364 'Jalapeno I/II' adapters, based
      * on the SA110 'StrongArm'.
    diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h
    index 3f9714d07c6..3ecb262ca7e 100644
    --- a/sys/dev/aac/aacvar.h
    +++ b/sys/dev/aac/aacvar.h
    @@ -37,6 +37,16 @@
     #include 
     #include 
     
    +#define	AAC_TYPE_DEVO			1
    +#define	AAC_TYPE_ALPHA			2
    +#define	AAC_TYPE_BETA			3
    +#define	AAC_TYPE_RELEASE		4
    +
    +#define	AAC_DRIVER_MAJOR_VERSION	2
    +#define	AAC_DRIVER_MINOR_VERSION	1
    +#define	AAC_DRIVER_BUGFIX_LEVEL		9
    +#define	AAC_DRIVER_TYPE			AAC_TYPE_RELEASE
    +
     #ifndef AAC_DRIVER_BUILD
     # define AAC_DRIVER_BUILD 1
     #endif
    @@ -319,7 +329,6 @@ struct aac_softc
     	int			aac_hwif;
     #define AAC_HWIF_I960RX		0
     #define AAC_HWIF_STRONGARM	1
    -#define AAC_HWIF_FALCON		2
     #define AAC_HWIF_RKT		3
     #define	AAC_HWIF_NARK		4
     #define AAC_HWIF_UNKNOWN	-1
    
    From b3aa5b386da3fcb80084ff85473d0a83f368bb17 Mon Sep 17 00:00:00 2001
    From: Doug Barton 
    Date: Mon, 29 Mar 2010 01:24:20 +0000
    Subject: [PATCH 1740/2592] MFC r205290:
    
    MAKE_JUST_WORLDS
    ---
     Makefile | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/Makefile b/Makefile
    index bd267162386..47148f25750 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -310,6 +310,7 @@ universe_${target}:
     	    "check _.${target}.buildworld for details" | ${MAKEFAIL}))
     	@echo ">> ${target} buildworld completed on `LC_ALL=C date`"
     .endif
    +.if !defined(MAKE_JUST_WORLDS)
     .if exists(${.CURDIR}/sys/${target}/conf/NOTES)
     	@(cd ${.CURDIR}/sys/${target}/conf && env __MAKE_CONF=/dev/null \
     	    ${MAKE} LINT > ${.CURDIR}/_.${target}.makeLINT 2>&1 || \
    @@ -318,6 +319,7 @@ universe_${target}:
     .endif
     	@cd ${.CURDIR} && ${MAKE} ${.MAKEFLAGS} TARGET=${target} \
     	    universe_kernels
    +.endif
     	@echo ">> ${target} completed on `LC_ALL=C date`"
     .endfor
     universe_kernels: universe_kernconfs
    
    From ecb246eba62d141db0fc21e8cdded1a2c3dd6283 Mon Sep 17 00:00:00 2001
    From: Doug Barton 
    Date: Mon, 29 Mar 2010 06:31:58 +0000
    Subject: [PATCH 1741/2592] Update to 9.6.2-P1, the latest patchfix release
     which deals with the problems related to the handling of broken DNSSEC trust
     chains.
    
    This fix is only relevant for those who have DNSSEC validation
    enabled and configure trust anchors from third parties, either
    manually, or through a system like DLV.
    ---
     contrib/bind9/CHANGES                         |   421 +-
     contrib/bind9/COPYRIGHT                       |     4 +-
     contrib/bind9/FAQ                             |    18 +-
     contrib/bind9/FAQ.xml                         |    35 +-
     contrib/bind9/NSEC3-NOTES                     |     4 +-
     contrib/bind9/README                          |    23 +
     contrib/bind9/bin/check/named-checkconf.8     |     4 +-
     contrib/bind9/bin/check/named-checkconf.html  |     4 +-
     contrib/bind9/bin/check/named-checkzone.8     |     8 +-
     contrib/bind9/bin/check/named-checkzone.c     |     8 +-
     .../bind9/bin/check/named-checkzone.docbook   |     4 +-
     contrib/bind9/bin/check/named-checkzone.html  |    18 +-
     contrib/bind9/bin/dig/dig.1                   |     4 +-
     contrib/bind9/bin/dig/dig.html                |     4 +-
     contrib/bind9/bin/dig/dighost.c               |    24 +-
     contrib/bind9/bin/dig/host.1                  |     4 +-
     contrib/bind9/bin/dig/host.c                  |     5 +-
     contrib/bind9/bin/dig/host.html               |     4 +-
     contrib/bind9/bin/dig/nslookup.1              |     4 +-
     contrib/bind9/bin/dig/nslookup.c              |     3 +-
     contrib/bind9/bin/dig/nslookup.html           |     4 +-
     contrib/bind9/bin/dnssec/dnssec-dsfromkey.c   |    18 +-
     .../bind9/bin/dnssec/dnssec-keyfromlabel.8    |    20 +-
     .../bind9/bin/dnssec/dnssec-keyfromlabel.c    |     7 +-
     .../bin/dnssec/dnssec-keyfromlabel.docbook    |    21 +-
     .../bind9/bin/dnssec/dnssec-keyfromlabel.html |    32 +-
     contrib/bind9/bin/dnssec/dnssec-keygen.8      |    20 +-
     contrib/bind9/bin/dnssec/dnssec-keygen.c      |    22 +-
     .../bind9/bin/dnssec/dnssec-keygen.docbook    |    31 +-
     contrib/bind9/bin/dnssec/dnssec-keygen.html   |    43 +-
     contrib/bind9/bin/dnssec/dnssec-signzone.8    |    25 +-
     contrib/bind9/bin/dnssec/dnssec-signzone.c    |   917 +-
     .../bind9/bin/dnssec/dnssec-signzone.docbook  |    33 +-
     contrib/bind9/bin/dnssec/dnssec-signzone.html |    45 +-
     contrib/bind9/bin/dnssec/dnssectool.c         |     4 +-
     contrib/bind9/bin/dnssec/dnssectool.h         |     6 +-
     contrib/bind9/bin/named/control.c             |    12 +-
     .../bind9/bin/named/include/named/server.h    |     5 +-
     contrib/bind9/bin/named/lwresd.8              |     4 +-
     contrib/bind9/bin/named/lwresd.html           |     4 +-
     contrib/bind9/bin/named/named.8               |    22 +-
     contrib/bind9/bin/named/named.conf.5          |     4 +-
     contrib/bind9/bin/named/named.conf.html       |     4 +-
     contrib/bind9/bin/named/named.docbook         |    17 +-
     contrib/bind9/bin/named/named.html            |    28 +-
     contrib/bind9/bin/named/query.c               |    53 +-
     contrib/bind9/bin/named/server.c              |    54 +-
     contrib/bind9/bin/named/statschannel.c        |   396 +-
     contrib/bind9/bin/named/update.c              |    25 +-
     contrib/bind9/bin/nsupdate/nsupdate.1         |     4 +-
     contrib/bind9/bin/nsupdate/nsupdate.html      |     4 +-
     contrib/bind9/bin/rndc/rndc-confgen.8         |     4 +-
     contrib/bind9/bin/rndc/rndc-confgen.html      |     4 +-
     contrib/bind9/bin/rndc/rndc.8                 |     4 +-
     contrib/bind9/bin/rndc/rndc.conf.5            |     4 +-
     contrib/bind9/bin/rndc/rndc.conf.html         |     4 +-
     contrib/bind9/bin/rndc/rndc.html              |     4 +-
     contrib/bind9/config.h.in                     |    28 +-
     contrib/bind9/configure.in                    |   134 +-
     contrib/bind9/doc/arm/Bv9ARM-book.xml         |   144 +-
     contrib/bind9/doc/arm/Bv9ARM.ch01.html        |    54 +-
     contrib/bind9/doc/arm/Bv9ARM.ch02.html        |    26 +-
     contrib/bind9/doc/arm/Bv9ARM.ch03.html        |    30 +-
     contrib/bind9/doc/arm/Bv9ARM.ch04.html        |   152 +-
     contrib/bind9/doc/arm/Bv9ARM.ch05.html        |    10 +-
     contrib/bind9/doc/arm/Bv9ARM.ch06.html        |   224 +-
     contrib/bind9/doc/arm/Bv9ARM.ch07.html        |    18 +-
     contrib/bind9/doc/arm/Bv9ARM.ch08.html        |    22 +-
     contrib/bind9/doc/arm/Bv9ARM.ch09.html        |   184 +-
     contrib/bind9/doc/arm/Bv9ARM.ch10.html        |     6 +-
     contrib/bind9/doc/arm/Bv9ARM.html             |   152 +-
     contrib/bind9/doc/arm/Bv9ARM.pdf              | 14190 ++++++++--------
     contrib/bind9/doc/arm/man.dig.html            |    24 +-
     .../bind9/doc/arm/man.dnssec-dsfromkey.html   |    20 +-
     .../doc/arm/man.dnssec-keyfromlabel.html      |    32 +-
     contrib/bind9/doc/arm/man.dnssec-keygen.html  |    43 +-
     .../bind9/doc/arm/man.dnssec-signzone.html    |    47 +-
     contrib/bind9/doc/arm/man.host.html           |    14 +-
     .../bind9/doc/arm/man.named-checkconf.html    |    16 +-
     .../bind9/doc/arm/man.named-checkzone.html    |    20 +-
     contrib/bind9/doc/arm/man.named.html          |    28 +-
     contrib/bind9/doc/arm/man.nsupdate.html       |    18 +-
     contrib/bind9/doc/arm/man.rndc-confgen.html   |    16 +-
     contrib/bind9/doc/arm/man.rndc.conf.html      |    16 +-
     contrib/bind9/doc/arm/man.rndc.html           |    16 +-
     contrib/bind9/doc/misc/Makefile.in            |    16 +-
     contrib/bind9/lib/dns/api                     |     4 +-
     contrib/bind9/lib/dns/db.c                    |     6 +-
     contrib/bind9/lib/dns/dispatch.c              |    28 +-
     contrib/bind9/lib/dns/dnssec.c                |    69 +-
     contrib/bind9/lib/dns/dst_api.c               |    53 +-
     contrib/bind9/lib/dns/dst_internal.h          |    12 +-
     contrib/bind9/lib/dns/dst_parse.c             |    18 +-
     contrib/bind9/lib/dns/include/dns/db.h        |     6 +-
     contrib/bind9/lib/dns/include/dns/dnssec.h    |     8 +-
     contrib/bind9/lib/dns/include/dns/journal.h   |    11 +-
     contrib/bind9/lib/dns/include/dns/keyvalues.h |     6 +-
     contrib/bind9/lib/dns/include/dns/name.h      |     8 +-
     contrib/bind9/lib/dns/include/dns/ncache.h    |     4 +-
     contrib/bind9/lib/dns/include/dns/nsec3.h     |     4 +-
     contrib/bind9/lib/dns/include/dns/rbt.h       |     6 +-
     contrib/bind9/lib/dns/include/dns/rdataset.h  |    20 +-
     contrib/bind9/lib/dns/include/dns/resolver.h  |    46 +-
     contrib/bind9/lib/dns/include/dns/result.h    |     8 +-
     contrib/bind9/lib/dns/include/dns/types.h     |     2 +-
     contrib/bind9/lib/dns/include/dns/validator.h |     6 +-
     contrib/bind9/lib/dns/include/dns/zone.h      |    20 +-
     contrib/bind9/lib/dns/include/dst/dst.h       |     6 +-
     contrib/bind9/lib/dns/journal.c               |    99 +-
     contrib/bind9/lib/dns/masterdump.c            |     2 +-
     contrib/bind9/lib/dns/message.c               |     4 +-
     contrib/bind9/lib/dns/ncache.c                |     6 +-
     contrib/bind9/lib/dns/nsec3.c                 |    25 +-
     contrib/bind9/lib/dns/opensslrsa_link.c       |   496 +-
     contrib/bind9/lib/dns/rbt.c                   |    35 +-
     contrib/bind9/lib/dns/rbtdb.c                 |   163 +-
     contrib/bind9/lib/dns/rcode.c                 |     6 +-
     .../bind9/lib/dns/rdata/generic/ipseckey_45.c |     3 +-
     contrib/bind9/lib/dns/rdatalist.c             |     6 +-
     contrib/bind9/lib/dns/rdataset.c              |    25 +-
     contrib/bind9/lib/dns/rdataslab.c             |     6 +-
     contrib/bind9/lib/dns/resolver.c              |   461 +-
     contrib/bind9/lib/dns/result.c                |     7 +-
     contrib/bind9/lib/dns/sdb.c                   |    10 +-
     contrib/bind9/lib/dns/sdlz.c                  |    10 +-
     contrib/bind9/lib/dns/spnego.c                |    18 +-
     contrib/bind9/lib/dns/validator.c             |   160 +-
     contrib/bind9/lib/dns/view.c                  |    14 +-
     contrib/bind9/lib/dns/zone.c                  |   211 +-
     contrib/bind9/lib/isc/api                     |     4 +-
     contrib/bind9/lib/isc/base32.c                |     4 +-
     contrib/bind9/lib/isc/base64.c                |     8 +-
     contrib/bind9/lib/isc/heap.c                  |    14 +-
     contrib/bind9/lib/isc/httpd.c                 |    45 +-
     .../bind9/lib/isc/ia64/include/isc/atomic.h   |     2 +-
     contrib/bind9/lib/isc/include/isc/entropy.h   |    14 +-
     contrib/bind9/lib/isc/include/isc/netscope.h  |     6 +-
     contrib/bind9/lib/isc/include/isc/portset.h   |     4 +-
     contrib/bind9/lib/isc/include/isc/sha2.h      |    10 +-
     contrib/bind9/lib/isc/include/isc/util.h      |    14 +-
     contrib/bind9/lib/isc/inet_ntop.c             |    11 +-
     .../lib/isc/powerpc/include/isc/atomic.h      |    53 +-
     contrib/bind9/lib/isc/random.c                |    27 +-
     contrib/bind9/lib/isc/sha2.c                  |    27 +-
     .../bind9/lib/isc/unix/ifiter_getifaddrs.c    |     6 +-
     contrib/bind9/lib/isc/unix/socket.c           |    31 +-
     contrib/bind9/lib/isccc/api                   |     2 +-
     contrib/bind9/lib/isccfg/aclconf.c            |    23 +-
     contrib/bind9/lib/isccfg/api                  |     2 +-
     .../lib/isccfg/include/isccfg/namedconf.h     |     6 +-
     contrib/bind9/lib/lwres/api                   |     2 +-
     contrib/bind9/lib/lwres/context.c             |    15 +-
     contrib/bind9/lib/lwres/getipnode.c           |   100 +-
     contrib/bind9/lib/lwres/man/lwres.3           |     4 +-
     contrib/bind9/lib/lwres/man/lwres.html        |     4 +-
     contrib/bind9/lib/lwres/man/lwres_buffer.3    |     4 +-
     contrib/bind9/lib/lwres/man/lwres_buffer.html |     4 +-
     contrib/bind9/lib/lwres/man/lwres_config.3    |     4 +-
     contrib/bind9/lib/lwres/man/lwres_config.html |     4 +-
     contrib/bind9/lib/lwres/man/lwres_context.3   |     4 +-
     .../bind9/lib/lwres/man/lwres_context.html    |     4 +-
     contrib/bind9/lib/lwres/man/lwres_gabn.3      |     4 +-
     contrib/bind9/lib/lwres/man/lwres_gabn.html   |     4 +-
     .../bind9/lib/lwres/man/lwres_gai_strerror.3  |     4 +-
     .../lib/lwres/man/lwres_gai_strerror.html     |     4 +-
     .../bind9/lib/lwres/man/lwres_getaddrinfo.3   |     4 +-
     .../lib/lwres/man/lwres_getaddrinfo.html      |     4 +-
     .../bind9/lib/lwres/man/lwres_gethostent.3    |     4 +-
     .../bind9/lib/lwres/man/lwres_gethostent.html |     4 +-
     contrib/bind9/lib/lwres/man/lwres_getipnode.3 |     4 +-
     .../bind9/lib/lwres/man/lwres_getipnode.html  |     4 +-
     .../bind9/lib/lwres/man/lwres_getnameinfo.3   |     4 +-
     .../lib/lwres/man/lwres_getnameinfo.html      |     4 +-
     .../lib/lwres/man/lwres_getrrsetbyname.3      |     4 +-
     .../lib/lwres/man/lwres_getrrsetbyname.html   |     4 +-
     contrib/bind9/lib/lwres/man/lwres_gnba.3      |     4 +-
     contrib/bind9/lib/lwres/man/lwres_gnba.html   |     4 +-
     contrib/bind9/lib/lwres/man/lwres_hstrerror.3 |     4 +-
     .../bind9/lib/lwres/man/lwres_hstrerror.html  |     4 +-
     contrib/bind9/lib/lwres/man/lwres_inetntop.3  |     4 +-
     .../bind9/lib/lwres/man/lwres_inetntop.html   |     4 +-
     contrib/bind9/lib/lwres/man/lwres_noop.3      |     4 +-
     contrib/bind9/lib/lwres/man/lwres_noop.html   |     4 +-
     contrib/bind9/lib/lwres/man/lwres_packet.3    |     4 +-
     contrib/bind9/lib/lwres/man/lwres_packet.html |     4 +-
     contrib/bind9/lib/lwres/man/lwres_resutil.3   |     4 +-
     .../bind9/lib/lwres/man/lwres_resutil.html    |     4 +-
     contrib/bind9/version                         |     6 +-
     lib/bind/config.h                             |     6 +
     189 files changed, 11985 insertions(+), 8922 deletions(-)
    
    diff --git a/contrib/bind9/CHANGES b/contrib/bind9/CHANGES
    index 0e9c9a6b498..d14fdd638f9 100644
    --- a/contrib/bind9/CHANGES
    +++ b/contrib/bind9/CHANGES
    @@ -1,4 +1,30 @@
    -	--- 9.6.1-P3 released ---
    +	--- 9.6.2-P1 released ---
    +
    +2852.	[bug]		Handle broken DNSSEC trust chains better. [RT #15619]
    +
    +	--- 9.6.2 released ---
    +
    +2850.	[bug]		If isc_heap_insert() failed due to memory shortage
    +			the heap would have corrupted entries. [RT #20951]
    +
    +2849.	[bug]		Don't treat errors from the xml2 library as fatal.
    +			[RT #20945]
    +
    +2846.	[bug]		EOF on unix domain sockets was not being handled
    +			correctly. [RT #20731]
    +
    +2844.	[doc]		notify-delay default in ARM was wrong.  It should have
    +			been five (5) seconds.
    +
    +	--- 9.6.2rc1 released ---
    +
    +2838.	[func]		Backport support for SHA-2 DNSSEC algorithms,
    +			RSASHA256 and RSASHA512, from BIND 9.7.  (This
    +			incorporates changes 2726 and 2738 from that
    +			release branch.) [RT #20871]
    +
    +2837.	[port]		Prevent Linux spurious warnings about fwrite().
    +			[RT #20812]
     
     2831.	[security]	Do not attempt to validate or cache
     			out-of-bailiwick data returned with a secure
    @@ -10,21 +36,286 @@
     
     2827.	[security]	Bogus NXDOMAIN could be cached as if valid. [RT #20712]
     
    -	--- 9.6.1-P2 released ---
    +2825.	[bug]		Changing the setting of OPTOUT in a NSEC3 chain that
    +			was in the process of being created was not properly
    +			recorded in the zone. [RT #20786]
    +
    +2823.	[bug]		rbtdb.c:getsigningtime() was missing locks. [RT #20781]
    +
    +2819.	[cleanup]	Removed unnecessary DNS_POINTER_MAXHOPS define
    +			[RT #20771]
    +
    +2818.	[cleanup]	rndc could return an incorrect error code 
    +			when a zone was not found. [RT #20767]
    +
    +2815.	[bug]		Exclusively lock the task when freezing a zone.
    +			[RT #19838]
    +
    +2814.	[func]		Provide a definitive error message when a master
    +			zone is not loaded. [RT #20757]
    +
    +	--- 9.6.2b1 released ---
    +
    +2797.	[bug]		Don't decrement the dispatch manager's maxbuffers.
    +			[RT #20613]
    +
    +2790.	[bug]		Handle DS queries to stub zones. [RT #20440]
    +
    +2789.   [bug]           Fixed an INSIST in dispatch.c [RT #20576]
    +
    +2786.	[bug]		Additional could be promoted to answer. [RT #20663]
    +
    +2784.	[bug]		TC was not always being set when required glue was
    +			dropped. [RT #20655]
    +
    +2783.	[func]		Return minimal responses to EDNS/UDP queries with a UDP
    +			buffer size of 512 or less.  [RT #20654]
    +
    +2782.	[port]		win32: use getaddrinfo() for hostname lookups.
    +			[RT #20650]
    +
    +2777.	[contrib]	DLZ MYSQL auto reconnect support discovery was wrong.
     
     2772.	[security]	When validating, track whether pending data was from
     			the additional section or not and only return it if
     			validates as secure. [RT #20438]
     
    -	--- 9.6.1-P1 released ---
    +2765.	[bug]		Skip masters for which the TSIG key cannot be found.
    +			[RT #20595]
    +
    +2760.	[cleanup]	Corrected named-compilezone usage summary. [RT #20533]
    +
    +2759.	[doc]		Add information about .jbk/.jnw files to
    +			the ARM. [RT #20303]
    +
    +2758.	[bug]		win32: Added a workaround for a windows 2008 bug
    +			that could cause the UDP client handler to shut
    +			down. [RT #19176]
    +
    +2757.	[bug]		dig: assertion failure could occur in connect
    +			timeout. [RT #20599]
    +
    +2755.	[doc]		Clarify documentation of keyset- files in
    +			dnssec-signzone man page. [RT #19810]
    +
    +2754.	[bug]		Secure-to-insecure transitions failed when zone
    +			was signed with NSEC3. [RT #20587]
    +
    +2750.	[bug]		dig: assertion failure could occur when a server
    +			didn't have an address. [RT #20579]
    +
    +2749.	[bug]		ixfr-from-differences generated a non-minimal ixfr
    +			for NSEC3 signed zones. [RT #20452]
    +
    +2747.	[bug]		Journal roll forwards failed to set the re-signing
    +			time of RRSIGs correctly. [RT #20541]
    +
    +2743.	[bug]		RRSIG could be incorrectly set in the NSEC3 record
    +			for a insecure delegation.
    +
    +2729.	[func]		When constructing a CNAME from a DNAME use the DNAME
    +			TTL. [RT #20451]
    +
    +2723.	[bug]		isc_base32_totext(), isc_base32hex_totext(), and
    +			isc_base64_totext(), didn't always mark regions of
    +			memory as fully consumed after conversion.  [RT #20445]
    +
    +2722.	[bug]		Ensure that the memory associated with the name of
    +			a node in a rbt tree is not altered during the life
    +			of the node. [RT #20431]
    +
    +2721.	[port]		Have dst__entropy_status() prime the random number
    +			generator. [RT #20369]
    +
    +2718.	[bug]		The space calculations in opensslrsa_todns() were
    +			incorrect. [RT #20394]
    +
    +2716.	[bug]		nslookup debug mode didn't return the ttl. [RT #20414]
    +
    +2715.	[bug]		Require OpenSSL support to be explicitly disabled.
    +			[RT #20288]
    +
    +2714.	[port]		aix/powerpc: 'asm("ics");' needs non standard assembler
    +			flags.
    +
    +2713.	[bug]		powerpc: atomic operations missing asm("ics") /
    +			__isync() calls.
    +
    +2706.	[bug]		Loading a zone with a very large NSEC3 salt could
    +			trigger an assert. [RT #20368]
    +
    +2705.	[bug]		Reconcile the XML stats version number with a later
    +                        BIND9 release, by adding a "name" attribute to
    +                        "cache" elements and increasing the version number
    +                        to 2.2.  (This is a minor version change, but may
    +                        affect XML parsers if they assume the cache element
    +                        doesn't take an attribute.)
    +
    +2704.	[bug]		Serial of dynamic and stub zones could be inconsistent
    +			with their SOA serial.  [RT #19387]
    +
    +2701.	[doc]		Correction to ARM: hmac-md5 is no longer the only
    +			supported TSIG key algorithm. [RT #18046]
    +
    +2700.	[doc]		The match-mapped-addresses option is discouraged.
    +			[RT #12252]
    +
    +2699.	[bug]		Missing lock in rbtdb.c. [RT #20037]
    +
    +2697.	[port]		win32: ensure that S_IFMT, S_IFDIR, S_IFCHR and
    +			S_IFREG are defined after including .
    +			[RT #20309]
    +
    +2696.	[bug]		named failed to successfully process some valid
    +			acl constructs. [RT #20308]
    +
    +2692.	[port]		win32: 32/64 bit cleanups. [RT #20335]
    +
    +2690.	[bug]		win32: fix isc_thread_key_getspecific() prototype.
    +			[RT #20315]
    +
    +2689.	[bug]		Correctly handle snprintf result. [RT #20306]
    +
    +2688.	[bug]		Use INTERFACE_F_POINTTOPOINT, not IFF_POINTOPOINT,
    +			to decide to fetch the destination address. [RT #20305]
    +
    +2686.	[bug]		dnssec-signzone should clean the old NSEC chain when
    +			signing with NSEC3 and vice versa. [RT #20301]
    +
    +2683.	[bug]		dnssec-signzone should clean out old NSEC3 chains when
    +			the NSEC3 parameters used to sign the zone change.
    +			[RT #20246]
    +
    +2681.	[bug]		IPSECKEY RR of gateway type 3 was not correctly
    +			decoded. [RT #20269]
    +
    +2678.	[func]		Treat DS queries as if "minimal-response yes;"
    +			was set. [RT #20258]
    +
    +2672.	[bug]		Don't enable searching in 'host' when doing reverse
    +			lookups. [RT #20218]
    +
    +2670.	[bug]		Unexpected connect failures failed to log enough
    +			information to be useful. [RT #20205]
    +
    +2663.	[func]		win32:  allow named to run as a service using
    +			"NT AUTHORITY\LocalService" as the account. [RT #19977]
    +
    +2662.	[bug]		lwres_getipnodebyname() and lwres_getipnodebyaddr()
    +			returned a misleading error code when lwresd was
    +			down. [RT #20028]
    +
    +2661.	[bug]		Check whether socket fd exceeds FD_SETSIZE when
    +			creating lwres context. [RT #20029]
    +
    +2659.	[doc]		Clarify dnssec-keygen doc: key name must match zone
    +			name for DNSSEC keys. [RT #19938]
    +
    +2656.	[func]		win32: add a "tools only" check box to the installer
    +			which causes it to only install dig, host, nslookup,
    +			nsupdate and relevant DLLs.  [RT #19998]
    +
    +2655.	[doc]		Document that key-directory does not affect
    +			rndc.key.  [RT #20155]
    +
    +2653.	[bug]		Treat ENGINE_load_private_key() failures as key
    +			not found rather than out of memory.  [RT #18033]
    +
    +2649.	[bug]		Set the domain for forward only zones. [RT #19944]
    +
    +2648.	[port]		win32: isc_time_seconds() was broken. [RT #19900]
    +
    +2647.	[bug]		Remove unnecessary SOA updates when a new KSK is
    +			added. [RT #19913]
    +
    +2646.	[bug]		Incorrect cleanup on error in socket.c. [RT #19987]
    +
    +2645.	[port]		"gcc -m32" didn't work on amd64 and x86_64 platforms
    +			which default to 64 bits. [RT #19927]
    +
    +2643.	[bug]		Stub zones interacted badly with NSEC3 support.
    +			[RT #19777]
    +
    +2642.	[bug]		nsupdate could dump core on solaris when reading
    +			improperly formatted key files.  [RT #20015]
     
     2640.	[security]	A specially crafted update packet will cause named
     			to exit. [RT #20000]
     
    +2639.	[bug]		Silence compiler warnings in gssapi code. [RT #19954]
    +
    +2637.	[func]		Rationalize dnssec-signzone's signwithkey() calling.
    +			[RT #19959]
    +
    +2635.	[bug]		isc_inet_ntop() incorrectly handled 0.0/16 addresses.
    +			[RT #19716]
    +
    +2633.	[bug]		Handle 15 bit rand() functions. [RT #19783]
    +
    +2632.	[func]		util/kit.sh: warn if documentation appears to be out of
    +			date.  [RT #19922]
    +
    +2625.	[bug]		Missing UNLOCK in rbtdb.c. [RT #19865]
    +
    +2623.	[bug]		Named started seaches for DS non-optimally. [RT #19915]
    +
    +2621.	[doc]		Made copyright boilterplate consistent.  [RT #19833]
    +
    +2920.	[bug]		Delay thawing the zone until the reload of it has
    +			completed successfully.  [RT #19750]
    +
    +2618.	[bug]		The sdb and sdlz db_interator_seek() methods could
    +			loop infinitely. [RT #19847]
    +
    +2617.	[bug]		ifconfig.sh failed to emit an error message when
    +			run from the wrong location. [RT #19375]
    +
    +2616.	[bug]		'host' used the nameservers from resolv.conf even
    +			when a explicit nameserver was specified. [RT #19852]
    +
    +2615.	[bug]		"__attribute__((unused))" was in the wrong place
    +			for ia64 gcc builds. [RT #19854]
    +
    +2614.	[port]		win32: 'named -v' should automatically be executed
    +			in the foreground. [RT #19844]
    +
    +2613.	[bug]		Option argument validation was missing for
    +			dnssec-dsfromkey. [RT #19828]
    +
    +2610.	[port]		sunos: Change #2363 was not complete. [RT #19796]
    +
    +2608.	[func]		Perform post signing verification checks in
    +			dnssec-signzone.  These can be disabled with -P.
    +
    +			The post sign verification test ensures that for each
    +			algorithm in use there is at least one non revoked
    +			self signed KSK key.  That all revoked KSK keys are
    +			self signed.  That all records in the zone are signed
    +			by the algorithm.  [RT #19653]
    +
    +2601.	[doc]		Mention file creation mode mask in the
    +			named manual page.
    +
    +2593.	[bug]		Improve a corner source of SERVFAILs [RT #19632]
    +
    +2589.	[bug]		dns_db_unregister() failed to clear '*dbimp'.
    +			[RT #19626]
    +
    +2581.	[contrib]	dlz/mysql set MYSQL_OPT_RECONNECT option on connection.
    +			Requires MySQL 5.0.19 or later. [RT #19084]
    +
    +2580.	[bug]		UpdateRej statistics counter could be incremented twice
    +			for one rejection. [RT #19476]
    +
    +2533.	[doc]		ARM: document @ (at-sign). [RT #17144]
    +
    +2500.	[contrib]	contrib/sdb/pgsql/zonetodb.c called non-existent
    +			function. [RT #18582]
    +
     	--- 9.6.1 released ---
     
     2607.	[bug]		named could incorrectly delete NSEC3 records for
    -			empty nodes when processing a update request.  
    +			empty nodes when processing a update request.
     			[RT #19749]
     
     2606.	[bug]		"delegation-only" was not being accepted in
    @@ -78,7 +369,7 @@
     			date to the version string, -DNO_VERSION_DATE.
     
     2582.	[bug]		Don't emit warning log message when we attempt to
    -			remove non-existant journal. [RT #19516]
    +			remove non-existent journal. [RT #19516]
     
     2579.	[bug]		DNSSEC lookaside validation failed to handle unknown
     			algorithms. [RT #19479]
    @@ -136,7 +427,7 @@
     2556.	[port]		Solaris: mkdir(2) on tmpfs filesystems does not do the
     			error checks in the correct order resulting in the
     			wrong error code sometimes being returned. [RT #19249]
    -			
    +
     2554.	[bug]		Validation of uppercase queries from NSEC3 zones could
     			fail. [RT #19297]
     
    @@ -185,7 +476,7 @@
     2536.	[cleanup]	Silence some warnings when -Werror=format-security is
     			specified. [RT #19083]
     
    -2535.	[bug]		dig +showsearh and +trace interacted badly. [RT #19091]
    +2535.	[bug]		dig +showsearch and +trace interacted badly. [RT #19091]
     
     2532.	[bug]		dig: check the question section of the response to
     			see if it matches the asked question. [RT #18495]
    @@ -198,8 +489,8 @@
     2529.	[cleanup]	Upgrade libtool to silence complaints from recent
     			version of autoconf. [RT #18657]
     
    -2528.   [cleanup]       Silence spurious configure warning about
    -                        --datarootdir [RT #19096]
    +2528.   [cleanup]	Silence spurious configure warning about
    +			--datarootdir [RT #19096]
     
     2527.	[bug]		named could reuse cache on reload with
     			enabling/disabling validation. [RT #19119]
    @@ -222,7 +513,7 @@
     			preceded in resolv.conf. [RT #19081]
     
     2517.	[bug]		dig +trace with -4 or -6 failed when it chose a
    -			nameserver address of the excluded address.
    +			nameserver address of the excluded address type.
     			[RT #18843]
     
     2516.	[bug]		glue sort for responses was performed even when not
    @@ -235,7 +526,7 @@
     2511.	[cleanup]	dns_rdata_tofmttext() add const to linebreak.
     			[RT #18885]
     
    -2506.	[port]		solaris: Check at configure time if 
    +2506.	[port]		solaris: Check at configure time if
     			hack_shutup_pthreadonceinit is needed. [RT #19037]
     
     2505.	[port]		Treat amd64 similarly to x86_64 when determining
    @@ -258,7 +549,7 @@
     2515.	[port]		win32: build dnssec-dsfromkey and dnssec-keyfromlabel.
     			[RT #19063]
     
    -2513	[bug]		Fix windows cli build. [RT #19062]
    +2513.	[bug]		Fix windows cli build. [RT #19062]
     
     2510.	[bug]		"dig +sigchase" could trigger REQUIRE failures.
     			[RT #19033]
    @@ -343,7 +634,7 @@
     
     2478.	[bug]		'addresses' could be used uninitialized in
     			configure_forward(). [RT #18800]
    -	
    +
     2477.	[bug]		dig: the global option to print the command line is
     			+cmd not print_cmd.  Update the output to reflect
     			this. [RT #17008]
    @@ -359,7 +650,7 @@
     
     2473.	[port]		linux: raise the limit on open files to the possible
     			maximum value before spawning threads; 'files'
    -		        specified in named.conf doesn't seem to work with
    +			specified in named.conf doesn't seem to work with
     			threads as expected. [RT #18784]
     
     2472.	[port]		linux: check the number of available cpu's before
    @@ -388,7 +679,7 @@
     2464.	[port]		linux: check that a capability is present before
     			trying to set it. [RT #18135]
     
    -2463.   [port]          linux: POSIX doesn't include the IPv6 Advanced Socket
    +2463.	[port]		linux: POSIX doesn't include the IPv6 Advanced Socket
     			API and glibc hides parts of the IPv6 Advanced Socket
     			API as a result.  This is stupid as it breaks how the
     			two halves (Basic and Advanced) of the IPv6 Socket API
    @@ -418,7 +709,7 @@
     2456.	[bug]		In ACLs, ::/0 and 0.0.0.0/0 would both match any
     			address, regardless of family.  They now correctly
     			distinguish IPv4 from IPv6.  [RT #18559]
    -                        
    +
     2455.	[bug]		Stop metadata being transferred via axfr/ixfr.
     			[RT #18639]
     
    @@ -458,7 +749,7 @@
     
     2442.	[bug]		A lock could be destroyed twice. [RT# 18626]
     
    -2441.   [bug]           isc_radix_insert() could copy radix tree nodes
    +2441.	[bug]		isc_radix_insert() could copy radix tree nodes
     			incompletely. [RT #18573]
     
     2440.   [bug]		named-checkconf used an incorrect test to determine
    @@ -515,7 +806,7 @@
     			implementation.  Allow the use of kqueue,
     			epoll and /dev/poll to be selected at compile
     			time. [RT #18277]
    -			
    +
     2423.   [security]	Randomize server selection on queries, so as to
                             make forgery a little more difficult.  Instead of
                             always preferring the server with the lowest RTT,
    @@ -583,9 +874,9 @@
     
     2406.	[placeholder]
     
    -2405.   [cleanup]       The default value for dnssec-validation was changed to
    -                        "yes" in 9.5.0-P1 and all subsequent releases; this
    -                        was inadvertently omitted from CHANGES at the time.
    +2405.	[cleanup]	The default value for dnssec-validation was changed to
    +			"yes" in 9.5.0-P1 and all subsequent releases; this
    +			was inadvertently omitted from CHANGES at the time.
     
     2404.	[port]		hpux: files unlimited support.
     
    @@ -661,7 +952,7 @@
     2380.	[bug]		dns_view_find() was not returning NXDOMAIN/NXRRSET
     			proofs which, in turn, caused validation failures
     			for insecure zones immediately below a secure zone
    -			the server was authoritative for. [RT #18112] 
    +			the server was authoritative for. [RT #18112]
     
     2379.	[contrib]	queryperf/gen-data-queryperf.py: removed redundant
     			TLDs and supported RRs with TTLs [RT #17972]
    @@ -709,7 +1000,7 @@
     2363.	[port]		sunos: pre-set "lt_cv_sys_max_cmd_len=4096;".
     			[RT #17513]
     
    -2362.   [cleanup]	Make "rrset-order fixed" a compile-time option.
    +2362.	[cleanup]	Make "rrset-order fixed" a compile-time option.
     			settable by "./configure --enable-fixed-rrset".
     			Disabled by default. [RT #17977]
     
    @@ -792,12 +1083,12 @@
     			interfaces if there are not listen-on-v6 clauses in
     			named.conf.  [RT #17581]
     
    -2335.	[port]		sunos:  libbind and *printf() support for long long. 
    +2335.	[port]		sunos:  libbind and *printf() support for long long.
     			[RT #17513]
     
     2334.	[bug]		Bad REQUIRES in fromstruct_in_naptr(),  off by one
     			bug in fromstruct_txt(). [RT #17609]
    -			
    +
     2333.	[bug]		Fix off by one error in isc_time_nowplusinterval().
     			[RT #17608]
     
    @@ -842,7 +1133,7 @@
     2320.	[func]		Make statistics counters thread-safe for platforms
     			that support certain atomic operations. [RT #17466]
     
    -2319.	[bug]		Silence Coverity warnings in 
    +2319.	[bug]		Silence Coverity warnings in
     			lib/dns/rdata/in_1/apl_42.c. [RT #17469]
     
     2318.	[port]		sunos fixes for libbind.  [RT #17514]
    @@ -894,7 +1185,7 @@
     2301.	[bug]		Remove resource leak and fix error messages in
     			bin/tests/system/lwresd/lwtest.c. [RT #17474]
     
    -2300.	[bug]		Fixed failure to close open file in 
    +2300.	[bug]		Fixed failure to close open file in
     			bin/tests/names/t_names.c. [RT #17473]
     
     2299.	[bug]		Remove unnecessary NULL check in
    @@ -1017,7 +1308,7 @@
     2261.   [bug]           Fix memory leak with "any" and "none" ACLs [RT #17272]
     
     2260.	[bug]		Reported wrong clients-per-query when increasing the
    -                        value. [RT #17236]
    +			value. [RT #17236]
     
     2259.	[placeholder]
     
    @@ -1039,10 +1330,10 @@
     			intermediate values as timer->idle was reset by
     			isc_timer_touch(). [RT #17243]
     
    -2253.	[func]	 	"max-cache-size" defaults to 32M.
    +2253.	[func]		"max-cache-size" defaults to 32M.
     			"max-acache-size" defaults to 16M.
     
    -2252.   [bug]           Fixed errors in sortlist code [RT #17216]
    +2252.	[bug]		Fixed errors in sortlist code [RT #17216]
     
     2251.	[placeholder]
     
    @@ -1050,11 +1341,11 @@
     			memory statistics file should be written or not.
     			Additionally named's -m option will cause the
     			statistics file to be written. [RT #17113]
    -			
    -2249.   [bug]           Only set Authentic Data bit if client requested
    -                        DNSSEC, per RFC 3655 [RT #17175]
     
    -2248.   [cleanup]       Fix several errors reported by Coverity. [RT #17160]
    +2249.	[bug]		Only set Authentic Data bit if client requested
    +			DNSSEC, per RFC 3655 [RT #17175]
    +
    +2248.	[cleanup]	Fix several errors reported by Coverity. [RT #17160]
     
     2247.	[doc]		Sort doc/misc/options. [RT #17067]
     
    @@ -1095,11 +1386,11 @@
     
     2235.	[bug]		 was not being installed. [RT #17135]
     
    -2234.   [port]          Correct some compiler warnings on SCO OSr5 [RT #17134]
    -  
    -2233.   [func]          Add support for O(1) ACL processing, based on
    -                        radix tree code originally written by Kevin
    -                        Brintnall. [RT #16288]
    +2234.	[port]		Correct some compiler warnings on SCO OSr5 [RT #17134]
    +
    +2233.	[func]		Add support for O(1) ACL processing, based on
    +			radix tree code originally written by Kevin
    +			Brintnall. [RT #16288]
     
     2232.	[bug]		dns_adb_findaddrinfo() could fail and return
     			ISC_R_SUCCESS. [RT #17137]
    @@ -1120,7 +1411,7 @@
     2226.	[placeholder]
     
     2225.	[bug]		More support for systems with no IPv4 addresses.
    -		        [RT #17111]
    +			[RT #17111]
     
     2224.	[bug]		Defer journal compaction if a xfrin is in progress.
     			[RT #17119]
    @@ -1128,7 +1419,7 @@
     2223.	[bug]		Make a new journal when compacting. [RT #17119]
     
     2222.	[func]		named-checkconf now checks server key references.
    -		        [RT #17097]
    +			[RT #17097]
     
     2221.	[bug]		Set the event result code to reflect the actual
     			record turned to caller when a cache update is
    @@ -1137,7 +1428,7 @@
     
     2220.	[bug]		win32: Address a race condition in final shutdown of
     			the Windows socket code. [RT #17028]
    -			
    +
     2219.	[bug]		Apply zone consistency checks to additions, not
     			removals, when updating. [RT #17049]
     
    @@ -1147,7 +1438,7 @@
     2217.	[func]		Adjust update log levels. [RT #17092]
     
     2216.	[cleanup]	Fix a number of errors reported by Coverity.
    -		        [RT #17094]
    +			[RT #17094]
     
     2215.	[bug]		Bad REQUIRE check isc_hmacsha1_verify(). [RT #17094]
     
    @@ -1193,7 +1484,7 @@
     			localhost;) is used.
     
     			[RT #16987]
    -	
    +
     2205.	[bug]		libbind: change #2119 broke thread support. [RT #16982]
     
     2204.	[bug]		"rndc flushanme name unknown-view" caused named
    @@ -1332,7 +1623,7 @@
     			allow-query-on, allow-recursion-on and
     			allow-query-cache-on. [RT #16291]
     
    -2164.	[bug]		The code to determine how named-checkzone / 
    +2164.	[bug]		The code to determine how named-checkzone /
     			named-compilezone was called failed under windows.
     			[RT #16764]
     
    @@ -1539,14 +1830,14 @@
     
     2095.	[port]		libbind: alway prototype inet_cidr_ntop_ipv6() and
     			net_cidr_ntop_ipv6(). [RT #16388]
    - 
    +
     2094.	[contrib]	Update named-bootconf.  [RT# 16404]
     
     2093.	[bug]		named-checkzone -s was broken.
     
     2092.	[bug]		win32: dig, host, nslookup.  Use registry config
     			if resolv.conf does not exist or no nameservers
    -			listed. [RT #15877] 
    +			listed. [RT #15877]
     
     2091.	[port]		dighost.c: race condition on cleanup. [RT #16417]
     
    @@ -1950,7 +2241,7 @@
     
     1964.	[func]		Separate out MX and SRV to CNAME checks. [RT #15723]
     
    -1963.	[port]		Tru64 4.0E doesn't support send() and recv(). 
    +1963.	[port]		Tru64 4.0E doesn't support send() and recv().
     			[RT #15586]
     
     1962.	[bug]		Named failed to clear old update-policy when it
    @@ -1993,7 +2284,7 @@
     1951.	[security]	Drop queries from particular well known ports.
     			Don't return FORMERR to queries from particular
     			well known ports.  [RT #15636]
    -			
    +
     1950.	[port]		Solaris 2.5.1 and earlier cannot bind() then connect()
     			a TCP socket. This prevents the source address being
     			set for TCP connections. [RT #15628]
    @@ -2015,7 +2306,7 @@
     1945.	[cleanup]	dnssec-keygen: RSA (RSAMD5) is no longer recommended.
     			To generate a RSAMD5 key you must explicitly request
     			RSAMD5. [RT #13780]
    -			
    +
     1944.	[cleanup]	isc_hash_create() does not need a read/write lock.
     			[RT #15522]
     
    @@ -2127,7 +2418,7 @@
     			[RT #15034]
     
     1905.	[bug]		Strings returned from cfg_obj_asstring() should be
    -			treated as read-only.  The prototype for 
    +			treated as read-only.  The prototype for
     			cfg_obj_asstring() has been updated to reflect this.
     			[RT #15256]
     
    @@ -2259,10 +2550,10 @@
     1863.	[bug]		rrset-order "fixed" error messages not complete.
     
     1862.	[func]		Add additional zone data constancy checks.
    -			named-checkzone has extended checking of NS, MX and 
    +			named-checkzone has extended checking of NS, MX and
     			SRV record and the hosts they reference.
     			named has extended post zone load checks.
    -			New zone options: check-mx and integrity-check. 
    +			New zone options: check-mx and integrity-check.
     			[RT #4940]
     
     1861.	[bug]		dig could trigger a INSIST on certain malformed
    @@ -2305,9 +2596,9 @@
     1848.	[bug]		Improve SMF integration. [RT #13238]
     
     1847.	[bug]		isc_ondestroy_init() is called too late in
    -			dns_rbtdb_create()/dns_rbtdb64_create(). 
    +			dns_rbtdb_create()/dns_rbtdb64_create().
     			[RT #13661]
    -			
    +
     1846.	[contrib]	query-loc-0.3.0 from Stephane Bortzmeyer
     			.
     
    @@ -2599,7 +2890,7 @@
     			[RT #12866]
     
     1748.	[func]		dig now returns the byte count for axfr/ixfr.
    -			
    +
     1747.	[bug]		BIND 8 compatibility: named/named-checkconf failed
     			to parse "host-statistics-max" in named.conf.
     
    @@ -2617,7 +2908,7 @@
     			requested number of worker threads then destruction
     			of the manager would trigger an INSIST() failure.
     			[RT #12790]
    -			
    +
     1742.	[bug]		Deleting all records at a node then adding a
     			previously existing record, in a single UPDATE
     			transaction, failed to leave / regenerate the
    @@ -2628,7 +2919,7 @@
     
     1740.	[bug]		Replace rbt's hash algorithm as it performed badly
     			with certain zones. [RT #12729]
    -			
    +
     			NOTE: a hash context now needs to be established
     			via isc_hash_create() if the application was not
     			already doing this.
    @@ -2643,7 +2934,7 @@
     
     1736.	[bug]		dst_key_fromnamedfile() could fail to read a
     			public key. [RT #12687]
    -			
    +
     1735.	[bug]		'dig +sigtrace' could die with a REQUIRE failure.
     			[RE #12688]
     
    @@ -2820,7 +3111,7 @@
     
     1675.	[bug]		named would sometimes add extra NSEC records to
     			the authority section.
    -			
    +
     1674.	[port]		linux: increase buffer size used to scan
     			/proc/net/if_inet6.
     
    @@ -2894,7 +3185,7 @@
     
     1648.	[func]		Update dnssec-lookaside named.conf syntax to support
     			multiple dnssec-lookaside namespaces (not yet
    -			implemented).  
    +			implemented).
     
     1647.	[bug]		It was possible trigger a INSIST when chasing a DS
     			record that required walking back over a empty node.
    @@ -2924,7 +3215,7 @@
     
     1638.	[bug]		"ixfr-from-differences" could generate a REQUIRE
     			failure if the journal open failed. [RT #11347]
    -			
    +
     1637.	[bug]		Node reference leak on error in addnoqname().
     
     1636.	[bug]		The dump done callback could get ISC_R_SUCCESS even if
    @@ -3018,21 +3309,21 @@
     1607.	[bug]		dig, host and nslookup were still using random()
     			to generate query ids. [RT# 11013]
     
    -1606.	[bug]	 	DLV insecurity proof was failing.
    +1606.	[bug]		DLV insecurity proof was failing.
     
     1605.	[func]		New dns_db_find() option DNS_DBFIND_COVERINGNSEC.
     
     1604.	[bug]		A xfrout_ctx_create() failure would result in
     			xfrout_ctx_destroy() being called with a
     			partially initialized structure.
    -			
    +
     1603.	[bug]		nsupdate: set interactive based on isatty().
     			[RT# 10929]
     
     1602.	[bug]		Logging to a file failed unless a size was specified.
     			[RT# 10925]
     
    -1601.	[bug]		Silence spurious warning 'both "recursion no;" and 
    +1601.	[bug]		Silence spurious warning 'both "recursion no;" and
     			"allow-recursion" active' warning from view "_bind".
     			[RT# 10920]
     
    diff --git a/contrib/bind9/COPYRIGHT b/contrib/bind9/COPYRIGHT
    index 620ee985983..d95930be8cd 100644
    --- a/contrib/bind9/COPYRIGHT
    +++ b/contrib/bind9/COPYRIGHT
    @@ -1,4 +1,4 @@
    -Copyright (C) 2004-2009  Internet Systems Consortium, Inc. ("ISC")
    +Copyright (C) 2004-2010  Internet Systems Consortium, Inc. ("ISC")
     Copyright (C) 1996-2003  Internet Software Consortium.
     
     Permission to use, copy, modify, and/or distribute this software for any
    @@ -13,7 +13,7 @@ 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.
     
    -$Id: COPYRIGHT,v 1.14.176.1 2009/01/05 23:47:22 tbox Exp $
    +$Id: COPYRIGHT,v 1.14.176.2 2010/01/07 23:47:36 tbox Exp $
     
     Portions Copyright (C) 1996-2001  Nominum, Inc.
     
    diff --git a/contrib/bind9/FAQ b/contrib/bind9/FAQ
    index b256ed8b10a..9e3469ce4ae 100644
    --- a/contrib/bind9/FAQ
    +++ b/contrib/bind9/FAQ
    @@ -1,6 +1,6 @@
     Frequently Asked Questions about BIND 9
     
    -Copyright © 2004-2009 Internet Systems Consortium, Inc. ("ISC")
    +Copyright © 2004-2010 Internet Systems Consortium, Inc. ("ISC")
     
     Copyright © 2000-2003 Internet Software Consortium.
     
    @@ -784,6 +784,22 @@ A: Red Hat Security Enhanced Linux (SELinux) policy security protections :
        See these man-pages for more information : selinux(8), named_selinux
        (8), chcon(1), setsebool(8)
     
    +Q: I'm running BIND on Ubuntu -
    +
    +   Why can't named update slave zone database files?
    +
    +   Why can't named create DDNS journal files or update the master zones
    +   from journals?
    +
    +   Why can't named create custom log files?
    +
    +A: Ubuntu uses AppArmor  in
    +   addition to normal file system permissions to protect the system.
    +
    +   Adjust the paths to use those specified in /etc/apparmor.d/
    +   usr.sbin.named or adjust /etc/apparmor.d/usr.sbin.named to allow named
    +   to write at the location specified in named.conf.
    +
     Q: Listening on individual IPv6 interfaces does not work.
     
     A: This is usually due to "/proc/net/if_inet6" not being available in the
    diff --git a/contrib/bind9/FAQ.xml b/contrib/bind9/FAQ.xml
    index 65e8efc53a2..1d87642f669 100644
    --- a/contrib/bind9/FAQ.xml
    +++ b/contrib/bind9/FAQ.xml
    @@ -1,7 +1,7 @@
     
     
     
    -
    +
     
     
    Frequently Asked Questions about BIND 9 @@ -29,6 +29,7 @@ 2007 2008 2009 + 2010 Internet Systems Consortium, Inc. ("ISC") @@ -1382,6 +1383,36 @@ named_cache_t: for files modifiable by named - $ROOTDIR/var/{tmp,named/{slaves,d + + + + I'm running BIND on Ubuntu - + + + Why can't named update slave zone database files? + + + Why can't named create DDNS journal files or update + the master zones from journals? + + + Why can't named create custom log files? + + + + + Ubuntu uses AppArmor + <http://en.wikipedia.org/wiki/AppArmor> in + addition to normal file system permissions to protect the system. + + + Adjust the paths to use those specified in /etc/apparmor.d/usr.sbin.named + or adjust /etc/apparmor.d/usr.sbin.named to allow named to write at the + location specified in named.conf. + + + + diff --git a/contrib/bind9/NSEC3-NOTES b/contrib/bind9/NSEC3-NOTES index d23b20eefd2..3f8d8f905c0 100644 --- a/contrib/bind9/NSEC3-NOTES +++ b/contrib/bind9/NSEC3-NOTES @@ -35,7 +35,7 @@ will not be completely signed until named has had time to walk the zone and generate the NSEC and RRSIG records. Initially the NSEC record at the zone apex will have the OPT bit set. When the NSEC chain is complete the OPT bit will be cleared. Additionally when -the zone is fully signed the private type (default TYPE65535) records +the zone is fully signed the private type (default TYPE65534) records will have a non zero value for the final octet. The private type record has 5 octets. @@ -45,7 +45,7 @@ The private type record has 5 octets. complete flag (octet 5) If you wish to go straight to a secure zone using NSEC3 you should -also add a NSECPARAM record to the update request with the flags +also add a NSEC3PARAM record to the update request with the flags field set to indicate whether the NSEC3 chain will have the OPTOUT bit set or not. diff --git a/contrib/bind9/README b/contrib/bind9/README index d1519884802..902d9ed97d2 100644 --- a/contrib/bind9/README +++ b/contrib/bind9/README @@ -42,6 +42,29 @@ BIND 9 Stichting NLnet - NLnet Foundation Nominum, Inc. +BIND 9.6.2 + + BIND 9.6.2 is a maintenance release, fixing bugs in 9.6.1. + It also introduces support for the SHA-2 DNSSEC algorithms, + RSASHA256 and RSASHA512. + + Known issues in this release: + + - A validating resolver that has been incorrectly configured with + an invalid trust anchor will be unable to resolve names covered + by that trust anchor. In all current versions of BIND 9, such a + resolver will also generate significant unnecessary DNS traffic + while trying to validate. The latter problem will be addressed + in future BIND 9 releases. In the meantime, to avoid these + problems, exercise caution when configuring "trusted-keys": + make sure all keys are correct and current when you add them, + and update your configuration in a timely manner when keys + roll over. + +BIND 9.6.1 + + BIND 9.6.1 is a maintenance release, fixing bugs in 9.6.0. + BIND 9.6.0 BIND 9.6.0 includes a number of changes from BIND 9.5 and earlier diff --git a/contrib/bind9/bin/check/named-checkconf.8 b/contrib/bind9/bin/check/named-checkconf.8 index 852b13364ec..072d1cfd704 100644 --- a/contrib/bind9/bin/check/named-checkconf.8 +++ b/contrib/bind9/bin/check/named-checkconf.8 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2002 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: named-checkconf.8,v 1.30 2007/06/20 02:27:32 marka Exp $ +.\" $Id: named-checkconf.8,v 1.30.334.1 2009/07/11 01:55:20 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/check/named-checkconf.html b/contrib/bind9/bin/check/named-checkconf.html index 34bec808aaa..8fd1e6df36e 100644 --- a/contrib/bind9/bin/check/named-checkconf.html +++ b/contrib/bind9/bin/check/named-checkconf.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000-2002 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/bin/check/named-checkzone.8 b/contrib/bind9/bin/check/named-checkzone.8 index 5520da34868..dfc409e5e43 100644 --- a/contrib/bind9/bin/check/named-checkzone.8 +++ b/contrib/bind9/bin/check/named-checkzone.8 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2002 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: named-checkzone.8,v 1.42.334.1 2009/01/23 01:53:33 tbox Exp $ +.\" $Id: named-checkzone.8,v 1.42.334.3 2009/11/11 01:56:22 tbox Exp $ .\" .hy 0 .ad l @@ -33,9 +33,9 @@ named\-checkzone, named\-compilezone \- zone file validity checking or converting tool .SH "SYNOPSIS" .HP 16 -\fBnamed\-checkzone\fR [\fB\-d\fR] [\fB\-h\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-M\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename} +\fBnamed\-checkzone\fR [\fB\-d\fR] [\fB\-h\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-M\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename} .HP 18 -\fBnamed\-compilezone\fR [\fB\-d\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-C\ \fR\fB\fImode\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename} +\fBnamed\-compilezone\fR [\fB\-d\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-C\ \fR\fB\fImode\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {\fB\-o\ \fR\fB\fIfilename\fR\fR} {zonename} {filename} .SH "DESCRIPTION" .PP \fBnamed\-checkzone\fR diff --git a/contrib/bind9/bin/check/named-checkzone.c b/contrib/bind9/bin/check/named-checkzone.c index 83b3bbe9acf..0b49b51afc5 100644 --- a/contrib/bind9/bin/check/named-checkzone.c +++ b/contrib/bind9/bin/check/named-checkzone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named-checkzone.c,v 1.51.34.3 2009/05/29 02:17:43 marka Exp $ */ +/* $Id: named-checkzone.c,v 1.51.34.4 2009/11/10 20:01:41 each Exp $ */ /*! \file */ @@ -73,14 +73,16 @@ static enum { progmode_check, progmode_compile } progmode; static void usage(void) { fprintf(stderr, - "usage: %s [-djqvD] [-c class] [-o output] " + "usage: %s [-djqvD] [-c class] " "[-f inputformat] [-F outputformat] " "[-t directory] [-w directory] [-k (ignore|warn|fail)] " "[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] " "[-i (full|full-sibling|local|local-sibling|none)] " "[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] " "[-W (ignore|warn)] " - "zonename filename\n", prog_name); + "%s zonename filename\n", + prog_name, + progmode == progmode_check ? "[-o filename]" : "{-o filename}"); exit(1); } diff --git a/contrib/bind9/bin/check/named-checkzone.docbook b/contrib/bind9/bin/check/named-checkzone.docbook index d8634473146..4abb07fc831 100644 --- a/contrib/bind9/bin/check/named-checkzone.docbook +++ b/contrib/bind9/bin/check/named-checkzone.docbook @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + June 13, 2000 @@ -69,7 +69,6 @@ - @@ -99,6 +98,7 @@ + zonename filename diff --git a/contrib/bind9/bin/check/named-checkzone.html b/contrib/bind9/bin/check/named-checkzone.html index 71dc445eaa7..68a6331ddf3 100644 --- a/contrib/bind9/bin/check/named-checkzone.html +++ b/contrib/bind9/bin/check/named-checkzone.html @@ -2,7 +2,7 @@ - Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000-2002 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -29,11 +29,11 @@

    Synopsis

    -

    named-checkzone [-d] [-h] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-o filename] [-s style] [-S mode] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

    -

    named-compilezone [-d] [-j] [-q] [-v] [-c class] [-C mode] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-n mode] [-o filename] [-s style] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

    +

    named-checkzone [-d] [-h] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-s style] [-S mode] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

    +

    named-compilezone [-d] [-j] [-q] [-v] [-c class] [-C mode] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-n mode] [-o filename] [-s style] [-t directory] [-w directory] [-D] [-W mode] {-o filename} {zonename} {filename}

    -

    DESCRIPTION

    +

    DESCRIPTION

    named-checkzone checks the syntax and integrity of a zone file. It performs the same checks as named does when loading a @@ -53,7 +53,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -d

    @@ -239,14 +239,14 @@

    -

    RETURN VALUES

    +

    RETURN VALUES

    named-checkzone returns an exit status of 1 if errors were detected and 0 otherwise.

    -

    SEE ALSO

    +

    SEE ALSO

    named(8), named-checkconf(8), RFC 1035, @@ -254,7 +254,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/bin/dig/dig.1 b/contrib/bind9/bin/dig/dig.1 index f7f4370a59b..c8704a1d3a2 100644 --- a/contrib/bind9/bin/dig/dig.1 +++ b/contrib/bind9/bin/dig/dig.1 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: dig.1,v 1.50.44.2 2009/02/03 01:52:10 tbox Exp $ +.\" $Id: dig.1,v 1.50.44.3 2009/07/11 01:55:20 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/dig/dig.html b/contrib/bind9/bin/dig/dig.html index 11b55cc7592..3fd3e75cdbe 100644 --- a/contrib/bind9/bin/dig/dig.html +++ b/contrib/bind9/bin/dig/dig.html @@ -2,7 +2,7 @@ - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000-2003 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/bin/dig/dighost.c b/contrib/bind9/bin/dig/dighost.c index 73264e6c2ce..d730c0ee5f3 100644 --- a/contrib/bind9/bin/dig/dighost.c +++ b/contrib/bind9/bin/dig/dighost.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.311.70.8 2009/02/25 02:39:21 marka Exp $ */ +/* $Id: dighost.c,v 1.311.70.11 2009/11/10 17:27:13 each Exp $ */ /*! \file * \note @@ -1048,7 +1048,9 @@ setup_system(void) { debug("ndots is %d.", ndots); } - copy_server_list(lwconf, &server_list); + /* If user doesn't specify server use nameservers from resolv.conf. */ + if (ISC_LIST_EMPTY(server_list)) + copy_server_list(lwconf, &server_list); /* If we don't find a nameserver fall back to localhost */ if (ISC_LIST_EMPTY(server_list)) { @@ -2397,11 +2399,9 @@ connect_timeout(isc_task_t *task, isc_event_t *event) { if (!l->tcp_mode) send_udp(ISC_LIST_NEXT(cq, link)); else { - isc_socket_cancel(query->sock, NULL, - ISC_SOCKCANCEL_ALL); - isc_socket_detach(&query->sock); - sockcount--; - debug("sockcount=%d", sockcount); + if (query->sock != NULL) + isc_socket_cancel(query->sock, NULL, + ISC_SOCKCANCEL_ALL); send_tcp_connect(ISC_LIST_NEXT(cq, link)); } UNLOCK_LOOKUP; @@ -2604,12 +2604,10 @@ connect_done(isc_task_t *task, isc_event_t *event) { if (sevent->result == ISC_R_CANCELED) { debug("in cancel handler"); - if (query->sock != NULL) { - isc_socket_detach(&query->sock); - sockcount--; - INSIST(sockcount >= 0); - debug("sockcount=%d", sockcount); - } + isc_socket_detach(&query->sock); + INSIST(sockcount > 0); + sockcount--; + debug("sockcount=%d", sockcount); query->waiting_connect = ISC_FALSE; isc_event_free(&event); l = query->lookup; diff --git a/contrib/bind9/bin/dig/host.1 b/contrib/bind9/bin/dig/host.1 index eebdad8fe80..c538ae3d624 100644 --- a/contrib/bind9/bin/dig/host.1 +++ b/contrib/bind9/bin/dig/host.1 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2002 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: host.1,v 1.29.114.1 2009/01/23 01:53:33 tbox Exp $ +.\" $Id: host.1,v 1.29.114.2 2009/07/11 01:55:20 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/dig/host.c b/contrib/bind9/bin/dig/host.c index 9f302068adf..8cd5b3db29a 100644 --- a/contrib/bind9/bin/dig/host.c +++ b/contrib/bind9/bin/dig/host.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: host.c,v 1.116.216.2 2009/05/06 23:47:18 tbox Exp $ */ +/* $Id: host.c,v 1.116.216.3 2009/09/08 23:28:20 marka Exp $ */ /*! \file */ @@ -839,11 +839,10 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { } else { strncpy(lookup->textname, hostname, sizeof(lookup->textname)); lookup->textname[sizeof(lookup->textname)-1]=0; + usesearch = ISC_TRUE; } lookup->new_search = ISC_TRUE; ISC_LIST_APPEND(lookup_list, lookup, link); - - usesearch = ISC_TRUE; } int diff --git a/contrib/bind9/bin/dig/host.html b/contrib/bind9/bin/dig/host.html index f21073174ba..3928c93e764 100644 --- a/contrib/bind9/bin/dig/host.html +++ b/contrib/bind9/bin/dig/host.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000-2002 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/bin/dig/nslookup.1 b/contrib/bind9/bin/dig/nslookup.1 index 2d195345e6f..68b419ae59b 100644 --- a/contrib/bind9/bin/dig/nslookup.1 +++ b/contrib/bind9/bin/dig/nslookup.1 @@ -1,6 +1,6 @@ .\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -12,7 +12,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: nslookup.1,v 1.14 2007/05/16 06:12:01 marka Exp $ +.\" $Id: nslookup.1,v 1.14.354.1 2009/07/11 01:55:20 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/dig/nslookup.c b/contrib/bind9/bin/dig/nslookup.c index 56796268d90..000f54e9b63 100644 --- a/contrib/bind9/bin/dig/nslookup.c +++ b/contrib/bind9/bin/dig/nslookup.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nslookup.c,v 1.117.334.4 2009/05/06 11:41:57 fdupont Exp $ */ +/* $Id: nslookup.c,v 1.117.334.5 2009/10/20 01:11:22 marka Exp $ */ #include @@ -373,6 +373,7 @@ detailsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers, printrdata(&rdata); } dns_rdata_reset(&rdata); + printf("\tttl = %u\n", rdataset->ttl); loopresult = dns_rdataset_next(rdataset); } } diff --git a/contrib/bind9/bin/dig/nslookup.html b/contrib/bind9/bin/dig/nslookup.html index 0f3817653c0..3984a16b8a2 100644 --- a/contrib/bind9/bin/dig/nslookup.html +++ b/contrib/bind9/bin/dig/nslookup.html @@ -1,7 +1,7 @@ - + diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c index 653aa3ea7a5..8bd4aa566e3 100644 --- a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c +++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2008-2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-dsfromkey.c,v 1.2.14.3 2009/03/02 02:54:15 marka Exp $ */ +/* $Id: dnssec-dsfromkey.c,v 1.2.14.6 2010/01/11 23:47:22 tbox Exp $ */ /*! \file */ @@ -78,10 +78,18 @@ loadkeys(char *dirname, char *setname) isc_buffer_init(&buf, filename, sizeof(filename)); if (dirname != NULL) { + if (isc_buffer_availablelength(&buf) < strlen(dirname)) + fatal("directory name '%s' too long", dirname); isc_buffer_putstr(&buf, dirname); - if (dirname[strlen(dirname) - 1] != '/') + if (dirname[strlen(dirname) - 1] != '/') { + if (isc_buffer_availablelength(&buf) < 1) + fatal("directory name '%s' too long", dirname); isc_buffer_putstr(&buf, "/"); + } } + + if (isc_buffer_availablelength(&buf) < strlen("keyset-")) + fatal("directory name '%s' too long", dirname); isc_buffer_putstr(&buf, "keyset-"); result = dns_name_tofilenametext(name, ISC_FALSE, &buf); check_result(result, "dns_name_tofilenametext()"); @@ -210,12 +218,12 @@ emitds(unsigned int dtype, dns_rdata_t *rdata) putchar(' '); isc_buffer_usedregion(&classb, &r); - fwrite(r.base, 1, r.length, stdout); + isc_util_fwrite(r.base, 1, r.length, stdout); printf(" DS "); isc_buffer_usedregion(&textb, &r); - fwrite(r.base, 1, r.length, stdout); + isc_util_fwrite(r.base, 1, r.length, stdout); putchar('\n'); } diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8 b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8 index 622205820db..03f13e9d30a 100644 --- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8 +++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8 @@ -1,6 +1,6 @@ -.\" Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC") .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -12,7 +12,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: dnssec-keyfromlabel.8,v 1.6 2008/11/08 01:11:47 tbox Exp $ +.\" $Id: dnssec-keyfromlabel.8,v 1.6.14.3 2010/01/16 01:55:32 tbox Exp $ .\" .hy 0 .ad l @@ -43,7 +43,13 @@ gets keys with the given label from a crypto hardware and builds key files for D .RS 4 Selects the cryptographic algorithm. The value of \fBalgorithm\fR -must be one of RSAMD5 (RSA) or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman). These values are case insensitive. +must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or DH (Diffie Hellman). These values are case insensitive. +.sp +If no algorithm is specified, then RSASHA1 will be used by default, unless the +\fB\-3\fR +option is specified, in which case NSEC3RSASHA1 will be used instead. (If +\fB\-3\fR +is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.) .sp Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. .sp @@ -138,12 +144,10 @@ file contains algorithm specific fields. For obvious security reasons, this file \fBdnssec\-keygen\fR(8), \fBdnssec\-signzone\fR(8), BIND 9 Administrator Reference Manual, -RFC 2539, -RFC 2845, -RFC 4033. +RFC 4034. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" -Copyright \(co 2008 Internet Systems Consortium, Inc. ("ISC") +Copyright \(co 2008, 2010 Internet Systems Consortium, Inc. ("ISC") .br diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c index e7587c39663..78bfda31539 100644 --- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c +++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-keyfromlabel.c,v 1.4 2008/09/24 02:46:21 marka Exp $ */ +/* $Id: dnssec-keyfromlabel.c,v 1.4.50.2 2010/01/15 23:47:31 tbox Exp $ */ /*! \file */ @@ -48,7 +48,8 @@ const char *program = "dnssec-keyfromlabel"; int verbose; static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |" - " NSEC3DSA | NSEC3RSASHA1"; + " NSEC3DSA | NSEC3RSASHA1 |" + " RSASHA256 | RSASHA512"; static void usage(void) { diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook index 2bcf0a48da4..f2ab1529833 100644 --- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook +++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []> - + February 8, 2008 @@ -37,6 +37,7 @@ 2008 + 2010 Internet Systems Consortium, Inc. ("ISC") @@ -75,10 +76,18 @@ Selects the cryptographic algorithm. The value of - must be one of RSAMD5 (RSA) - or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman). + must be one of RSAMD5, + RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, + RSASHA512 or DH (Diffie Hellman). These values are case insensitive. + + If no algorithm is specified, then RSASHA1 will be used by + default, unless the option is specified, + in which case NSEC3RSASHA1 will be used instead. (If + is used and an algorithm is specified, + that algorithm will be checked for compatibility with NSEC3.) + Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. @@ -246,9 +255,7 @@ dnssec-signzone8 , BIND 9 Administrator Reference Manual, - RFC 2539, - RFC 2845, - RFC 4033. + RFC 4034. diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html index cbea64b8d75..1aafccd97c1 100644 --- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html +++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html @@ -1,7 +1,7 @@ - + @@ -31,7 +31,7 @@

    dnssec-keyfromlabel {-a algorithm} {-l label} [-c class] [-f flag] [-k] [-n nametype] [-p protocol] [-t type] [-v level] {name}

    -

    DESCRIPTION

    +

    DESCRIPTION

    dnssec-keyfromlabel gets keys with the given label from a crypto hardware and builds key files for DNSSEC (Secure DNS), as defined in RFC 2535 @@ -39,16 +39,24 @@

    -

    OPTIONS

    +

    OPTIONS

    -a algorithm

    Selects the cryptographic algorithm. The value of - algorithm must be one of RSAMD5 (RSA) - or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman). + algorithm must be one of RSAMD5, + RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, + RSASHA512 or DH (Diffie Hellman). These values are case insensitive.

    +

    + If no algorithm is specified, then RSASHA1 will be used by + default, unless the -3 option is specified, + in which case NSEC3RSASHA1 will be used instead. (If + -3 is used and an algorithm is specified, + that algorithm will be checked for compatibility with NSEC3.) +

    Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. @@ -112,7 +120,7 @@

    -

    GENERATED KEY FILES

    +

    GENERATED KEY FILES

    When dnssec-keyfromlabel completes successfully, @@ -153,17 +161,15 @@

    -

    SEE ALSO

    +

    SEE ALSO

    dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, - RFC 2539, - RFC 2845, - RFC 4033. + RFC 4034.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.8 b/contrib/bind9/bin/dnssec/dnssec-keygen.8 index 13db3d9db14..485ea6ef244 100644 --- a/contrib/bind9/bin/dnssec/dnssec-keygen.8 +++ b/contrib/bind9/bin/dnssec/dnssec-keygen.8 @@ -1,7 +1,7 @@ -.\" Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2004, 2005, 2007-2010 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: dnssec-keygen.8,v 1.40 2008/10/15 01:11:35 tbox Exp $ +.\" $Id: dnssec-keygen.8,v 1.40.44.4 2010/01/16 01:55:32 tbox Exp $ .\" .hy 0 .ad l @@ -38,13 +38,17 @@ dnssec\-keygen \- DNSSEC key generation tool .PP \fBdnssec\-keygen\fR generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845. +.PP +The +\fBname\fR +of the key is specified on the command line. For DNSSEC keys, this must match the name of the zone for which the key is being generated. .SH "OPTIONS" .PP \-a \fIalgorithm\fR .RS 4 -Selects the cryptographic algorithm. The value of +Selects the cryptographic algorithm. For DNSSEC keys, the value of \fBalgorithm\fR -must be one of RSAMD5 (RSA) or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC\-MD5. These values are case insensitive. +must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512. These values are case insensitive. .sp Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC\-MD5 is mandatory. .sp @@ -53,7 +57,7 @@ Note 2: HMAC\-MD5 and DH automatically set the \-k flag. .PP \-b \fIkeysize\fR .RS 4 -Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC\-MD5 keys must be between 1 and 512 bits. +Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSA keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits. .RE .PP \-n \fInametype\fR @@ -189,12 +193,12 @@ and BIND 9 Administrator Reference Manual, RFC 2539, RFC 2845, -RFC 4033. +RFC 4034. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") +Copyright \(co 2004, 2005, 2007\-2010 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2003 Internet Software Consortium. .br diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.c b/contrib/bind9/bin/dnssec/dnssec-keygen.c index 614d388eb7e..2b9a863b7d4 100644 --- a/contrib/bind9/bin/dnssec/dnssec-keygen.c +++ b/contrib/bind9/bin/dnssec/dnssec-keygen.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-keygen.c,v 1.81 2008/09/25 04:02:38 tbox Exp $ */ +/* $Id: dnssec-keygen.c,v 1.81.48.2 2010/01/15 23:47:31 tbox Exp $ */ /*! \file */ @@ -62,8 +62,8 @@ const char *program = "dnssec-keygen"; int verbose; -static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | NSEC3DSA |" - " NSEC3RSASHA1 | HMAC-MD5 |" +static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | RSASHA256 |" + " RSASHA512 | NSEC3DSA | NSEC3RSASHA1 | HMAC-MD5 |" " HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 |" " HMAC-SHA384 | HMAC-SHA512"; @@ -84,6 +84,8 @@ usage(void) { fprintf(stderr, " RSAMD5:\t\t[512..%d]\n", MAX_RSA); fprintf(stderr, " RSASHA1:\t\t[512..%d]\n", MAX_RSA); fprintf(stderr, " NSEC3RSASHA1:\t\t[512..%d]\n", MAX_RSA); + fprintf(stderr, " RSASHA256:\t[512..%d]\n", MAX_RSA); + fprintf(stderr, " RSASHA512:\t[1024..%d]\n", MAX_RSA); fprintf(stderr, " DH:\t\t[128..4096]\n"); fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n"); fprintf(stderr, " NSEC3DSA:\t\t[512..1024] and divisible by 64\n"); @@ -307,9 +309,14 @@ main(int argc, char **argv) { case DNS_KEYALG_RSAMD5: case DNS_KEYALG_RSASHA1: case DNS_KEYALG_NSEC3RSASHA1: + case DNS_KEYALG_RSASHA256: if (size != 0 && (size < 512 || size > MAX_RSA)) fatal("RSA key size %d out of range", size); break; + case DNS_KEYALG_RSASHA512: + if (size != 0 && (size < 1024 || size > MAX_RSA)) + fatal("RSA key size %d out of range", size); + break; case DNS_KEYALG_DH: if (size != 0 && (size < 128 || size > 4096)) fatal("DH key size %d out of range", size); @@ -376,7 +383,8 @@ main(int argc, char **argv) { } if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1 || - alg == DNS_KEYALG_NSEC3RSASHA1) && rsa_exp != 0) + alg == DNS_KEYALG_NSEC3RSASHA1 || alg == DNS_KEYALG_RSASHA256 || + alg == DNS_KEYALG_RSASHA512) && rsa_exp != 0) fatal("specified RSA exponent for a non-RSA key"); if (alg != DNS_KEYALG_DH && generator != 0) @@ -440,12 +448,16 @@ main(int argc, char **argv) { switch(alg) { case DNS_KEYALG_RSAMD5: case DNS_KEYALG_RSASHA1: + case DNS_KEYALG_NSEC3RSASHA1: + case DNS_KEYALG_RSASHA256: + case DNS_KEYALG_RSASHA512: param = rsa_exp; break; case DNS_KEYALG_DH: param = generator; break; case DNS_KEYALG_DSA: + case DNS_KEYALG_NSEC3DSA: case DST_ALG_HMACMD5: case DST_ALG_HMACSHA1: case DST_ALG_HMACSHA224: diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.docbook b/contrib/bind9/bin/dnssec/dnssec-keygen.docbook index c267a1b4c25..92ef9b9afc5 100644 --- a/contrib/bind9/bin/dnssec/dnssec-keygen.docbook +++ b/contrib/bind9/bin/dnssec/dnssec-keygen.docbook @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []> - + June 30, 2000 @@ -41,6 +41,8 @@ 2005 2007 2008 + 2009 + 2010 Internet Systems Consortium, Inc. ("ISC") @@ -80,6 +82,11 @@ and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845. + + The of the key is specified on the command + line. For DNSSEC keys, this must match the name of the zone for + which the key is being generated. + @@ -90,10 +97,13 @@ -a algorithm - Selects the cryptographic algorithm. The value of - must be one of RSAMD5 (RSA) or RSASHA1, - DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC-MD5. - These values are case insensitive. + Selects the cryptographic algorithm. For DNSSEC keys, the value + of must be one of RSAMD5, RSASHA1, + DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. + For TSIG/TKEY, the value must + be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, + HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are + case insensitive. Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement @@ -111,11 +121,10 @@ Specifies the number of bits in the key. The choice of key - size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be - between - 512 and 2048 bits. Diffie Hellman keys must be between + size depends on the algorithm used. RSA keys must be + between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 - bits and an exact multiple of 64. HMAC-MD5 keys must be + bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits. @@ -343,7 +352,7 @@ BIND 9 Administrator Reference Manual, RFC 2539, RFC 2845, - RFC 4033. + RFC 4034. diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.html b/contrib/bind9/bin/dnssec/dnssec-keygen.html index 696ef88c370..fccec6f684c 100644 --- a/contrib/bind9/bin/dnssec/dnssec-keygen.html +++ b/contrib/bind9/bin/dnssec/dnssec-keygen.html @@ -1,8 +1,8 @@ - + @@ -32,23 +32,31 @@

    dnssec-keygen {-a algorithm} {-b keysize} {-n nametype} [-c class] [-e] [-f flag] [-g generator] [-h] [-k] [-p protocol] [-r randomdev] [-s strength] [-t type] [-v level] {name}

    -

    DESCRIPTION

    +

    DESCRIPTION

    dnssec-keygen generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845.

    +

    + The name of the key is specified on the command + line. For DNSSEC keys, this must match the name of the zone for + which the key is being generated. +

    -

    OPTIONS

    +

    OPTIONS

    -a algorithm

    - Selects the cryptographic algorithm. The value of - algorithm must be one of RSAMD5 (RSA) or RSASHA1, - DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC-MD5. - These values are case insensitive. + Selects the cryptographic algorithm. For DNSSEC keys, the value + of algorithm must be one of RSAMD5, RSASHA1, + DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. + For TSIG/TKEY, the value must + be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, + HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are + case insensitive.

    Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement @@ -62,11 +70,10 @@

    -b keysize

    Specifies the number of bits in the key. The choice of key - size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be - between - 512 and 2048 bits. Diffie Hellman keys must be between + size depends on the algorithm used. RSA keys must be + between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 - bits and an exact multiple of 64. HMAC-MD5 keys must be + bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits.

    -n nametype
    @@ -148,7 +155,7 @@
    -

    GENERATED KEYS

    +

    GENERATED KEYS

    When dnssec-keygen completes successfully, @@ -194,7 +201,7 @@

    -

    EXAMPLE

    +

    EXAMPLE

    To generate a 768-bit DSA key for the domain example.com, the following command would be @@ -215,16 +222,16 @@

    -

    SEE ALSO

    +

    SEE ALSO

    dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 2539, RFC 2845, - RFC 4033. + RFC 4034.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.8 b/contrib/bind9/bin/dnssec/dnssec-signzone.8 index 1e779271c34..7b21fb64ce3 100644 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.8 +++ b/contrib/bind9/bin/dnssec/dnssec-signzone.8 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: dnssec-signzone.8,v 1.47.44.4.8.1 2009/12/31 23:17:46 tbox Exp $ +.\" $Id: dnssec-signzone.8,v 1.47.44.8 2009/11/07 01:56:11 tbox Exp $ .\" .hy 0 .ad l @@ -33,13 +33,15 @@ dnssec\-signzone \- DNSSEC zone signing tool .SH "SYNOPSIS" .HP 16 -\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...] +\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-P\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...] .SH "DESCRIPTION" .PP \fBdnssec\-signzone\fR -signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a -\fIkeyset\fR -file for each child zone. +signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. It also generates a +\fIkeyset\-\fR +file containing the key\-signing keys for the zone, and if signing a zone which contains delegations, it can optionally generate DS records for the child zones from their +\fIkeyset\-\fR +files. .SH "OPTIONS" .PP \-a @@ -73,7 +75,9 @@ as the directory .PP \-g .RS 4 -Generate DS records for child zones from keyset files. Existing DS records will be removed. +If the zone contains any delegations, and there are +\fIkeyset\-\fR +files for any of the child zones, then DS records for the child zones will be generated from the keys in those files. Existing DS records will be removed. .RE .PP \-s \fIstart\-time\fR @@ -186,6 +190,13 @@ The format of the output file containing the signed zone. Possible formats are Use pseudo\-random data when signing the zone. This is faster, but less secure, than using real random data. This option may be useful when signing large zones or when the entropy source is limited. .RE .PP +\-P +.RS 4 +Disable post sign verification tests. +.sp +The post sign verification test ensures that for each algorithm in use there is at least one non revoked self signed KSK key, that all revoked KSK keys are self signed, and that all records in the zone are signed by the algorithm. This option skips these tests. +.RE +.PP \-r \fIrandomdev\fR .RS 4 Specifies the source of randomness. If the operating system does not provide a diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.c b/contrib/bind9/bin/dnssec/dnssec-signzone.c index 2ef2e104902..eec6110ac58 100644 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.c +++ b/contrib/bind9/bin/dnssec/dnssec-signzone.c @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-signzone.c,v 1.209.12.8 2009/06/08 22:23:06 each Exp $ */ +/* $Id: dnssec-signzone.c,v 1.209.12.18 2009/11/03 23:47:45 tbox Exp $ */ /*! \file */ @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,8 @@ struct signer_key_struct { isc_boolean_t issigningkey; isc_boolean_t isdsk; isc_boolean_t isksk; + isc_boolean_t wasused; + isc_boolean_t commandline; unsigned int position; ISC_LINK(signer_key_t) link; }; @@ -127,6 +130,7 @@ struct signer_event { static ISC_LIST(signer_key_t) keylist; static unsigned int keycount = 0; +isc_rwlock_t keylist_lock; static isc_stdtime_t starttime = 0, endtime = 0, now; static int cycle = -1; static int jitter = 0; @@ -164,6 +168,7 @@ static dns_master_style_t *dsstyle = NULL; static unsigned int serialformat = SOA_SERIAL_KEEP; static unsigned int hash_length = 0; static isc_boolean_t unknownalg = ISC_FALSE; +static isc_boolean_t disable_zone_check = ISC_FALSE; #define INCSTAT(counter) \ if (printstats) { \ @@ -175,8 +180,9 @@ static isc_boolean_t unknownalg = ISC_FALSE; static void sign(isc_task_t *task, isc_event_t *event); -static isc_boolean_t -nsec3only(dns_dbnode_t *node); +#define check_dns_dbiterator_current(result) \ + check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \ + "dns_dbiterator_current()") static void dumpnode(dns_name_t *name, dns_dbnode_t *node) { @@ -206,21 +212,37 @@ newkeystruct(dst_key_t *dstkey, isc_boolean_t signwithkey) { key->isksk = ISC_FALSE; key->isdsk = ISC_TRUE; } + key->wasused = ISC_FALSE; + key->commandline = ISC_FALSE; key->position = keycount++; ISC_LINK_INIT(key, link); return (key); } +/*% + * Sign the given RRset with given key, and add the signature record to the + * given tuple. + */ + static void -signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata, - dst_key_t *key, isc_buffer_t *b) +signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key, + dns_ttl_t ttl, dns_diff_t *add, const char *logmsg) { isc_result_t result; isc_stdtime_t jendtime; + char keystr[KEY_FORMATSIZE]; + dns_rdata_t trdata = DNS_RDATA_INIT; + unsigned char array[BUFSIZE]; + isc_buffer_t b; + dns_difftuple_t *tuple; + + key_format(key, keystr, sizeof(keystr)); + vbprintf(1, "\t%s %s\n", logmsg, keystr); jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime; + isc_buffer_init(&b, array, sizeof(array)); result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime, - mctx, b, rdata); + mctx, &b, &trdata); isc_entropy_stopcallbacksources(ectx); if (result != ISC_R_SUCCESS) { char keystr[KEY_FORMATSIZE]; @@ -232,7 +254,7 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata, if (tryverify) { result = dns_dnssec_verify(name, rdataset, key, - ISC_TRUE, mctx, rdata); + ISC_TRUE, mctx, &trdata); if (result == ISC_R_SUCCESS) { vbprintf(3, "\tsignature verified\n"); INCSTAT(nverified); @@ -241,6 +263,12 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata, INCSTAT(nverifyfailed); } } + + tuple = NULL; + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, ttl, &trdata, + &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(add, &tuple); } static inline isc_boolean_t @@ -254,6 +282,25 @@ iszonekey(signer_key_t *key) { dst_key_iszonekey(key->key))); } +/*% + * Find the key if it is in our list. If it is, return it, otherwise null. + * No locking is performed here, this must be done by the caller. + */ +static signer_key_t * +keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) { + signer_key_t *key; + + key = ISC_LIST_HEAD(keylist); + while (key != NULL) { + if (rrsig->keyid == dst_key_id(key->key) && + rrsig->algorithm == dst_key_alg(key->key) && + dns_name_equal(&rrsig->signer, dst_key_name(key->key))) + return (key); + key = ISC_LIST_NEXT(key, link); + } + return (NULL); +} + /*% * Finds the key that generated a RRSIG, if possible. First look at the keys * that we've loaded already, and then see if there's a key on disk. @@ -264,20 +311,34 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) { dst_key_t *pubkey = NULL, *privkey = NULL; signer_key_t *key; - key = ISC_LIST_HEAD(keylist); - while (key != NULL) { - if (rrsig->keyid == dst_key_id(key->key) && - rrsig->algorithm == dst_key_alg(key->key) && - dns_name_equal(&rrsig->signer, dst_key_name(key->key))) - return key; - key = ISC_LIST_NEXT(key, link); + isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read); + key = keythatsigned_unlocked(rrsig); + isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_read); + if (key != NULL) + return (key); + + /* + * We did not find the key in our list. Get a write lock now, since + * we may be modifying the bits. We could do the tryupgrade() dance, + * but instead just get a write lock and check once again to see if + * it is on our list. It's possible someone else may have added it + * after all. + */ + isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write); + + key = keythatsigned_unlocked(rrsig); + if (key != NULL) { + isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); + return (key); } result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, rrsig->algorithm, DST_TYPE_PUBLIC, NULL, mctx, &pubkey); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { + isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); return (NULL); + } result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, rrsig->algorithm, @@ -289,6 +350,8 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) { } else key = newkeystruct(pubkey, ISC_FALSE); ISC_LIST_APPEND(keylist, key, link); + + isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); return (key); } @@ -438,6 +501,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, keep = ISC_TRUE; wassignedby[key->position] = ISC_TRUE; nowsignedby[key->position] = ISC_TRUE; + key->wasused = ISC_TRUE; } else { vbprintf(2, "\trrsig by %s dropped - %s\n", sigstr, @@ -453,6 +517,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, keep = ISC_TRUE; wassignedby[key->position] = ISC_TRUE; nowsignedby[key->position] = ISC_TRUE; + key->wasused = ISC_TRUE; } else { vbprintf(2, "\trrsig by %s dropped - %s\n", sigstr, @@ -499,24 +564,12 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, } if (resign) { - isc_buffer_t b; - dns_rdata_t trdata = DNS_RDATA_INIT; - unsigned char array[BUFSIZE]; - char keystr[KEY_FORMATSIZE]; - INSIST(!keep); - key_format(key->key, keystr, sizeof(keystr)); - vbprintf(1, "\tresigning with dnskey %s\n", keystr); - isc_buffer_init(&b, array, sizeof(array)); - signwithkey(name, set, &trdata, key->key, &b); + signwithkey(name, set, key->key, ttl, add, + "resigning with dnskey"); nowsignedby[key->position] = ISC_TRUE; - tuple = NULL; - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, - name, ttl, &trdata, - &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(add, &tuple); + key->wasused = ISC_TRUE; } dns_rdata_reset(&sigrdata); @@ -534,11 +587,6 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, key != NULL; key = ISC_LIST_NEXT(key, link)) { - isc_buffer_t b; - dns_rdata_t trdata; - unsigned char array[BUFSIZE]; - char keystr[KEY_FORMATSIZE]; - if (nowsignedby[key->position]) continue; @@ -550,16 +598,9 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, dns_name_equal(name, gorigin)))) continue; - key_format(key->key, keystr, sizeof(keystr)); - vbprintf(1, "\tsigning with dnskey %s\n", keystr); - dns_rdata_init(&trdata); - isc_buffer_init(&b, array, sizeof(array)); - signwithkey(name, set, &trdata, key->key, &b); - tuple = NULL; - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, - ttl, &trdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(add, &tuple); + signwithkey(name, set, key->key, ttl, add, + "signing with dnskey"); + key->wasused = ISC_TRUE; } isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t)); @@ -787,8 +828,8 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) { return (DNS_R_BADDB); } dns_rdataset_init(&keyset); - result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0, - &keyset, NULL); + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, + 0, &keyset, NULL); if (result != ISC_R_SUCCESS) { dns_db_detachnode(db, &node); dns_db_detach(&db); @@ -1021,6 +1062,20 @@ active_node(dns_dbnode_t *node) { type = rdataset.type; covers = rdataset.covers; dns_rdataset_disassociate(&rdataset); + /* + * Delete the NSEC chain if we are signing with + * NSEC3. + */ + if (nsec_datatype == dns_rdatatype_nsec3 && + (type == dns_rdatatype_nsec || + covers == dns_rdatatype_nsec)) { + result = dns_db_deleterdataset(gdb, node, + gversion, type, + covers); + check_result(result, + "dns_db_deleterdataset(nsec/rrsig)"); + continue; + } if (type != dns_rdatatype_rrsig) continue; found = ISC_FALSE; @@ -1050,32 +1105,6 @@ active_node(dns_dbnode_t *node) { fatal("rdataset iteration failed: %s", isc_result_totext(result)); dns_rdatasetiter_destroy(&rdsiter2); - -#if 0 - /* - * Delete all NSEC records and RRSIG(NSEC) if we are in - * NSEC3 mode and vica versa. - */ - for (result = dns_rdatasetiter_first(rdsiter2); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter2)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - type = rdataset.type; - covers = rdataset.covers; - if (type == dns_rdatatype_rrsig) - type = covers; - dns_rdataset_disassociate(&rdataset); - if (type == nsec_datatype || - (type != dns_rdatatype_nsec && - type != dns_rdatatype_nsec3)) - continue; - if (covers != 0) - type = dns_rdatatype_rrsig; - result = dns_db_deleterdataset(gdb, node, gversion, - type, covers); - check_result(result, "dns_db_deleterdataset()"); - } -#endif } dns_rdatasetiter_destroy(&rdsiter); @@ -1198,7 +1227,7 @@ cleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) { dns_rdataset_t set; isc_result_t result, dresult; - if (outputformat != dns_masterformat_text) + if (outputformat != dns_masterformat_text || !disable_zone_check) return; dns_rdataset_init(&set); @@ -1248,6 +1277,424 @@ postsign(void) { dns_dbiterator_destroy(&gdbiter); } +static isc_boolean_t +goodsig(dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset, + dns_rdataset_t *rdataset) +{ + dns_rdata_dnskey_t key; + dns_rdata_rrsig_t sig; + dst_key_t *dstkey = NULL; + isc_result_t result; + + dns_rdata_tostruct(sigrdata, &sig, NULL); + + for (result = dns_rdataset_first(keyrdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(keyrdataset)) { + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdataset_current(keyrdataset, &rdata); + dns_rdata_tostruct(&rdata, &key, NULL); + result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx, + &dstkey); + if (result != ISC_R_SUCCESS) + return (ISC_FALSE); + if (sig.algorithm != key.algorithm || + sig.keyid != dst_key_id(dstkey) || + !dns_name_equal(&sig.signer, gorigin)) { + dst_key_free(&dstkey); + continue; + } + result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE, + mctx, sigrdata); + dst_key_free(&dstkey); + if (result == ISC_R_SUCCESS) + return(ISC_TRUE); + } + return (ISC_FALSE); +} + +static void +verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node, + dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms, + unsigned char *bad_algorithms) +{ + unsigned char set_algorithms[256]; + char namebuf[DNS_NAME_FORMATSIZE]; + char algbuf[80]; + char typebuf[80]; + dns_rdataset_t sigrdataset; + dns_rdatasetiter_t *rdsiter = NULL; + isc_result_t result; + int i; + + dns_rdataset_init(&sigrdataset); + result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + for (result = dns_rdatasetiter_first(rdsiter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsiter)) { + dns_rdatasetiter_current(rdsiter, &sigrdataset); + if (sigrdataset.type == dns_rdatatype_rrsig && + sigrdataset.covers == rdataset->type) + break; + dns_rdataset_disassociate(&sigrdataset); + } + if (result != ISC_R_SUCCESS) { + dns_name_format(name, namebuf, sizeof(namebuf)); + type_format(rdataset->type, typebuf, sizeof(typebuf)); + fprintf(stderr, "no signatures for %s/%s\n", namebuf, typebuf); + for (i = 0; i < 256; i++) + if (ksk_algorithms[i] != 0) + bad_algorithms[i] = 1; + return; + } + + memset(set_algorithms, 0, sizeof(set_algorithms)); + for (result = dns_rdataset_first(&sigrdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&sigrdataset)) { + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_rrsig_t sig; + + dns_rdataset_current(&sigrdataset, &rdata); + dns_rdata_tostruct(&rdata, &sig, NULL); + if ((set_algorithms[sig.algorithm] != 0) || + (ksk_algorithms[sig.algorithm] == 0)) + continue; + if (goodsig(&rdata, name, keyrdataset, rdataset)) + set_algorithms[sig.algorithm] = 1; + } + dns_rdatasetiter_destroy(&rdsiter); + if (memcmp(set_algorithms, ksk_algorithms, sizeof(set_algorithms))) { + dns_name_format(name, namebuf, sizeof(namebuf)); + type_format(rdataset->type, typebuf, sizeof(typebuf)); + for (i = 0; i < 256; i++) + if ((ksk_algorithms[i] != 0) && + (set_algorithms[i] == 0)) { + alg_format(i, algbuf, sizeof(algbuf)); + fprintf(stderr, "Missing %s signature for " + "%s %s\n", algbuf, namebuf, typebuf); + bad_algorithms[i] = 1; + } + } + dns_rdataset_disassociate(&sigrdataset); +} + +static void +verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation, + dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms, + unsigned char *bad_algorithms) +{ + dns_rdataset_t rdataset; + dns_rdatasetiter_t *rdsiter = NULL; + isc_result_t result; + + result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + result = dns_rdatasetiter_first(rdsiter); + dns_rdataset_init(&rdataset); + while (result == ISC_R_SUCCESS) { + dns_rdatasetiter_current(rdsiter, &rdataset); + if (rdataset.type != dns_rdatatype_rrsig && + rdataset.type != dns_rdatatype_dnskey && + (!delegation || rdataset.type == dns_rdatatype_ds || + rdataset.type == dns_rdatatype_nsec)) { + verifyset(&rdataset, name, node, keyrdataset, + ksk_algorithms, bad_algorithms); + } + dns_rdataset_disassociate(&rdataset); + result = dns_rdatasetiter_next(rdsiter); + } + if (result != ISC_R_NOMORE) + fatal("rdataset iteration failed: %s", + isc_result_totext(result)); + dns_rdatasetiter_destroy(&rdsiter); +} + +/*% + * Verify that certain things are sane: + * + * The apex has a DNSKEY record with at least one KSK and at least + * one ZSK. + * + * The DNSKEY record was signed with at least one of the KSKs in this + * set. + * + * The rest of the zone was signed with at least one of the ZSKs + * present in the DNSKEY RRSET. + */ +static void +verifyzone(void) { + char algbuf[80]; + dns_dbiterator_t *dbiter = NULL; + dns_dbnode_t *node = NULL, *nextnode = NULL; + dns_fixedname_t fname, fnextname, fzonecut; + dns_name_t *name, *nextname, *zonecut; + dns_rdata_dnskey_t dnskey; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdataset_t rdataset; + dns_rdataset_t sigrdataset; + int i; + isc_boolean_t done = ISC_FALSE; + isc_boolean_t first = ISC_TRUE; + isc_boolean_t goodksk = ISC_FALSE; + isc_boolean_t goodzsk = ISC_FALSE; + isc_result_t result; + unsigned char revoked[256]; + unsigned char standby[256]; + unsigned char ksk_algorithms[256]; + unsigned char zsk_algorithms[256]; + unsigned char bad_algorithms[256]; +#ifdef ALLOW_KSKLESS_ZONES + isc_boolean_t allzsksigned = ISC_TRUE; + unsigned char self_algorithms[256]; +#endif + + if (disable_zone_check) + return; + + result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node); + if (result != ISC_R_SUCCESS) + fatal("failed to find the zone's origin: %s", + isc_result_totext(result)); + + dns_rdataset_init(&rdataset); + dns_rdataset_init(&sigrdataset); + result = dns_db_findrdataset(gdb, node, gversion, + dns_rdatatype_dnskey, + 0, 0, &rdataset, &sigrdataset); + dns_db_detachnode(gdb, &node); + if (result != ISC_R_SUCCESS) + fatal("cannot find DNSKEY rrset\n"); + + if (!dns_rdataset_isassociated(&sigrdataset)) + fatal("cannot find DNSKEY RRSIGs\n"); + + memset(revoked, 0, sizeof(revoked)); + memset(standby, 0, sizeof(revoked)); + memset(ksk_algorithms, 0, sizeof(ksk_algorithms)); + memset(zsk_algorithms, 0, sizeof(zsk_algorithms)); + memset(bad_algorithms, 0, sizeof(bad_algorithms)); +#ifdef ALLOW_KSKLESS_ZONES + memset(self_algorithms, 0, sizeof(self_algorithms)); +#endif + + /* + * Check that the DNSKEY RR has at least one self signing KSK and + * one ZSK per algorithm in it. + */ + for (result = dns_rdataset_first(&rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&rdataset)) { + dns_rdataset_current(&rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &dnskey, NULL); + check_result(result, "dns_rdata_tostruct"); + + if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0) + ; + else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) { + if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 && + !dns_dnssec_selfsigns(&rdata, gorigin, &rdataset, + &sigrdataset, ISC_FALSE, + mctx)) { + char namebuf[DNS_NAME_FORMATSIZE]; + char buffer[1024]; + isc_buffer_t buf; + + dns_name_format(gorigin, namebuf, + sizeof(namebuf)); + isc_buffer_init(&buf, buffer, sizeof(buffer)); + result = dns_rdata_totext(&rdata, NULL, &buf); + check_result(result, "dns_rdata_totext"); + fatal("revoked KSK is not self signed:\n" + "%s DNSKEY %.*s", namebuf, + (int)isc_buffer_usedlength(&buf), buffer); + } + if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 && + revoked[dnskey.algorithm] != 255) + revoked[dnskey.algorithm]++; + } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) { + if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset, + &sigrdataset, ISC_FALSE, mctx)) { + if (ksk_algorithms[dnskey.algorithm] != 255) + ksk_algorithms[dnskey.algorithm]++; + goodksk = ISC_TRUE; + } else { + if (standby[dnskey.algorithm] != 255) + standby[dnskey.algorithm]++; + } + } else if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset, + &sigrdataset, ISC_FALSE, + mctx)) { +#ifdef ALLOW_KSKLESS_ZONES + if (self_algorithms[dnskey.algorithm] != 255) + self_algorithms[dnskey.algorithm]++; +#endif + if (zsk_algorithms[dnskey.algorithm] != 255) + zsk_algorithms[dnskey.algorithm]++; + goodzsk = ISC_TRUE; + } else { + if (zsk_algorithms[dnskey.algorithm] != 255) + zsk_algorithms[dnskey.algorithm]++; +#ifdef ALLOW_KSKLESS_ZONES + allzsksigned = ISC_FALSE; +#endif + } + dns_rdata_freestruct(&dnskey); + dns_rdata_reset(&rdata); + } + dns_rdataset_disassociate(&sigrdataset); + + if (!goodksk) { +#ifdef ALLOW_KSKLESS_ZONES + if (!goodzsk) + fatal("no self signing keys found"); + fprintf(stderr, "No self signing KSK found. Using self signed " + "ZSK's for active algorithm list.\n"); + memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms)); + if (!allzsksigned) + fprintf(stderr, "warning: not all ZSK's are self " + "signed.\n"); +#else + fatal("no self signed KSK's found"); +#endif + } + + fprintf(stderr, "Verifying the zone using the following algorithms:"); + for (i = 0; i < 256; i++) { + if (ksk_algorithms[i] != 0) { + alg_format(i, algbuf, sizeof(algbuf)); + fprintf(stderr, " %s", algbuf); + } + } + fprintf(stderr, ".\n"); + + for (i = 0; i < 256; i++) { + /* + * The counts should both be zero or both be non-zero. + * Mark the algorithm as bad if this is not met. + */ + if ((ksk_algorithms[i] != 0) == (zsk_algorithms[i] != 0)) + continue; + alg_format(i, algbuf, sizeof(algbuf)); + fprintf(stderr, "Missing %s for algorithm %s\n", + (ksk_algorithms[i] != 0) ? "ZSK" : "self signing KSK", + algbuf); + bad_algorithms[i] = 1; + } + + /* + * Check that all the other records were signed by keys that are + * present in the DNSKEY RRSET. + */ + + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + dns_fixedname_init(&fnextname); + nextname = dns_fixedname_name(&fnextname); + dns_fixedname_init(&fzonecut); + zonecut = NULL; + + result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); + check_result(result, "dns_db_createiterator()"); + + result = dns_dbiterator_first(dbiter); + check_result(result, "dns_dbiterator_first()"); + + while (!done) { + isc_boolean_t isdelegation = ISC_FALSE; + + result = dns_dbiterator_current(dbiter, &node, name); + check_dns_dbiterator_current(result); + if (delegation(name, node, NULL)) { + zonecut = dns_fixedname_name(&fzonecut); + dns_name_copy(name, zonecut, NULL); + isdelegation = ISC_TRUE; + } + verifynode(name, node, isdelegation, &rdataset, + ksk_algorithms, bad_algorithms); + result = dns_dbiterator_next(dbiter); + nextnode = NULL; + while (result == ISC_R_SUCCESS) { + result = dns_dbiterator_current(dbiter, &nextnode, + nextname); + check_dns_dbiterator_current(result); + if (!dns_name_issubdomain(nextname, gorigin) || + (zonecut != NULL && + dns_name_issubdomain(nextname, zonecut))) + { + dns_db_detachnode(gdb, &nextnode); + result = dns_dbiterator_next(dbiter); + continue; + } + dns_db_detachnode(gdb, &nextnode); + break; + } + if (result == ISC_R_NOMORE) { + done = ISC_TRUE; + } else if (result != ISC_R_SUCCESS) + fatal("iterating through the database failed: %s", + isc_result_totext(result)); + dns_db_detachnode(gdb, &node); + } + + dns_dbiterator_destroy(&dbiter); + + result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter); + check_result(result, "dns_db_createiterator()"); + + for (result = dns_dbiterator_first(dbiter); + result == ISC_R_SUCCESS; + result = dns_dbiterator_next(dbiter) ) { + result = dns_dbiterator_current(dbiter, &node, name); + check_dns_dbiterator_current(result); + verifynode(name, node, ISC_FALSE, &rdataset, + ksk_algorithms, bad_algorithms); + dns_db_detachnode(gdb, &node); + } + dns_dbiterator_destroy(&dbiter); + + dns_rdataset_disassociate(&rdataset); + + /* + * If we made it this far, we have what we consider a properly signed + * zone. Set the good flag. + */ + for (i = 0; i < 256; i++) { + if (bad_algorithms[i] != 0) { + if (first) + fprintf(stderr, "The zone is not fully signed " + "for the following algorithms:"); + alg_format(i, algbuf, sizeof(algbuf)); + fprintf(stderr, " %s", algbuf); + first = ISC_FALSE; + } + } + if (!first) { + fprintf(stderr, ".\n"); + fatal("DNSSEC completeness test failed."); + } + + if (goodksk) { + /* + * Print the success summary. + */ + fprintf(stderr, "Zone signing complete:\n"); + for (i = 0; i < 256; i++) { + if ((zsk_algorithms[i] != 0) || + (ksk_algorithms[i] != 0) || + (revoked[i] != 0) || (standby[i] != 0)) { + alg_format(i, algbuf, sizeof(algbuf)); + fprintf(stderr, "Algorithm: %s: ZSKs: %u, " + "KSKs: %u active, %u revoked, %u " + "stand-by\n", algbuf, + zsk_algorithms[i], ksk_algorithms[i], + revoked[i], standby[i]); + } + } + } +} + /*% * Sign the apex of the zone. * Note the origin may not be the first node if there are out of zone @@ -1265,7 +1712,7 @@ signapex(void) { result = dns_dbiterator_seek(gdbiter, gorigin); check_result(result, "dns_dbiterator_seek()"); result = dns_dbiterator_current(gdbiter, &node, name); - check_result(result, "dns_dbiterator_current()"); + check_dns_dbiterator_current(result); signname(node, name); dumpnode(name, node); cleannode(gdb, gversion, node); @@ -1317,9 +1764,7 @@ assignwork(isc_task_t *task, isc_task_t *worker) { found = ISC_FALSE; while (!found) { result = dns_dbiterator_current(gdbiter, &node, name); - if (result != ISC_R_SUCCESS) - fatal("failure iterating database: %s", - isc_result_totext(result)); + check_dns_dbiterator_current(result); /* * The origin was handled by signapex(). */ @@ -1487,7 +1932,7 @@ add_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) { } /*% - * Generate NSEC records for the zone. + * Generate NSEC records for the zone and remove NSEC3/NSEC3PARAM records. */ static void nsecify(void) { @@ -1495,10 +1940,14 @@ nsecify(void) { dns_dbnode_t *node = NULL, *nextnode = NULL; dns_fixedname_t fname, fnextname, fzonecut; dns_name_t *name, *nextname, *zonecut; + dns_rdataset_t rdataset; + dns_rdatasetiter_t *rdsiter = NULL; + dns_rdatatype_t type, covers; isc_boolean_t done = ISC_FALSE; isc_result_t result; isc_uint32_t nsttl = 0; + dns_rdataset_init(&rdataset); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&fnextname); @@ -1506,14 +1955,70 @@ nsecify(void) { dns_fixedname_init(&fzonecut); zonecut = NULL; + /* + * Remove any NSEC3 chains. + */ + result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter); + check_result(result, "dns_db_createiterator()"); + for (result = dns_dbiterator_first(dbiter); + result == ISC_R_SUCCESS; + result = dns_dbiterator_next(dbiter)) { + result = dns_dbiterator_current(dbiter, &node, name); + check_dns_dbiterator_current(result); + result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + for (result = dns_rdatasetiter_first(rdsiter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsiter)) { + dns_rdatasetiter_current(rdsiter, &rdataset); + type = rdataset.type; + covers = rdataset.covers; + dns_rdataset_disassociate(&rdataset); + result = dns_db_deleterdataset(gdb, node, gversion, + type, covers); + check_result(result, + "dns_db_deleterdataset(nsec3param/rrsig)"); + } + dns_rdatasetiter_destroy(&rdsiter); + dns_db_detachnode(gdb, &node); + } + dns_dbiterator_destroy(&dbiter); + result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); + result = dns_dbiterator_current(dbiter, &node, name); + check_dns_dbiterator_current(result); + /* + * Delete any NSEC3PARAM records at the apex. + */ + result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + for (result = dns_rdatasetiter_first(rdsiter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsiter)) { + dns_rdatasetiter_current(rdsiter, &rdataset); + type = rdataset.type; + covers = rdataset.covers; + dns_rdataset_disassociate(&rdataset); + if (type == dns_rdatatype_nsec3param || + covers == dns_rdatatype_nsec3param) { + result = dns_db_deleterdataset(gdb, node, gversion, + type, covers); + check_result(result, + "dns_db_deleterdataset(nsec3param/rrsig)"); + continue; + } + } + dns_rdatasetiter_destroy(&rdsiter); + dns_db_detachnode(gdb, &node); + while (!done) { - dns_dbiterator_current(dbiter, &node, name); + result = dns_dbiterator_current(dbiter, &node, name); + check_dns_dbiterator_current(result); if (delegation(name, node, &nsttl)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); @@ -1526,8 +2031,7 @@ nsecify(void) { isc_boolean_t active = ISC_FALSE; result = dns_dbiterator_current(dbiter, &nextnode, nextname); - if (result != ISC_R_SUCCESS) - break; + check_dns_dbiterator_current(result); active = active_node(nextnode); if (!active) { dns_db_detachnode(gdb, &nextnode); @@ -1560,37 +2064,6 @@ nsecify(void) { dns_dbiterator_destroy(&dbiter); } -/*% - * Does this node only contain NSEC3 records or RRSIG records or is empty. - */ -static isc_boolean_t -nsec3only(dns_dbnode_t *node) { - dns_rdatasetiter_t *rdsiter = NULL; - isc_result_t result; - dns_rdataset_t rdataset; - isc_boolean_t answer = ISC_TRUE; - - dns_rdataset_init(&rdataset); - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - if (rdataset.type != dns_rdatatype_nsec3 && - rdataset.type != dns_rdatatype_rrsig) { - answer = ISC_FALSE; - result = ISC_R_NOMORE; - } else - result = dns_rdatasetiter_next(rdsiter); - dns_rdataset_disassociate(&rdataset); - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - dns_rdatasetiter_destroy(&rdsiter); - return (answer); -} - static void addnsec3param(const unsigned char *salt, size_t salt_length, unsigned int iterations) @@ -1631,6 +2104,16 @@ addnsec3param(const unsigned char *salt, size_t salt_length, result = dns_db_findnode(gdb, gorigin, ISC_TRUE, &node); check_result(result, "dns_db_find(gorigin)"); + + /* + * Delete any current NSEC3PARAM records. + */ + result = dns_db_deleterdataset(gdb, node, gversion, + dns_rdatatype_nsec3param, 0); + if (result == DNS_R_UNCHANGED) + result = ISC_R_SUCCESS; + check_result(result, "dddnsec3param: dns_db_deleterdataset()"); + result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset, DNS_DBADD_MERGE, NULL); if (result == DNS_R_UNCHANGED) @@ -1719,6 +2202,7 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node, isc_buffer_t target; isc_result_t result; unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1]; + isc_boolean_t exists; /* * Get the first label. @@ -1740,8 +2224,7 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node, hash[isc_buffer_usedlength(&target)] = 0; - if (hashlist_exists(hashlist, hash)) - return; + exists = hashlist_exists(hashlist, hash); /* * Verify that the NSEC3 parameters match the current ones @@ -1756,20 +2239,21 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node, return; /* - * Delete any matching NSEC3 records which have parameters that - * match the NSEC3 chain we are building. + * Delete any NSEC3 records which are not part of the current + * NSEC3 chain. */ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_init(&rdata); dns_rdataset_current(&rdataset, &rdata); - dns_rdata_tostruct(&rdata, &nsec3, NULL); - if (nsec3.hash == hashalg && + result = dns_rdata_tostruct(&rdata, &nsec3, NULL); + check_result(result, "dns_rdata_tostruct"); + if (exists && nsec3.hash == hashalg && nsec3.iterations == iterations && nsec3.salt_length == salt_length && !memcmp(nsec3.salt, salt, salt_length)) - break; + continue; rdatalist.rdclass = rdata.rdclass; rdatalist.type = rdata.type; rdatalist.covers = 0; @@ -1783,7 +2267,7 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node, result = dns_db_subtractrdataset(gdb, node, gversion, &delrdataset, 0, NULL); dns_rdataset_disassociate(&delrdataset); - if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) + if (result != ISC_R_SUCCESS && result != DNS_R_NXRRSET) check_result(result, "dns_db_subtractrdataset(NSEC3)"); delete_rrsigs = ISC_TRUE; } @@ -1814,13 +2298,17 @@ nsec3ify(unsigned int hashalg, unsigned int iterations, dns_dbnode_t *node = NULL, *nextnode = NULL; dns_fixedname_t fname, fnextname, fzonecut; dns_name_t *name, *nextname, *zonecut; + dns_rdataset_t rdataset; + dns_rdatasetiter_t *rdsiter = NULL; + dns_rdatatype_t type, covers; + int order; + isc_boolean_t active; isc_boolean_t done = ISC_FALSE; isc_result_t result; - isc_boolean_t active; isc_uint32_t nsttl = 0; unsigned int count, nlabels; - int order; + dns_rdataset_init(&rdataset); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&fnextname); @@ -1837,15 +2325,41 @@ nsec3ify(unsigned int hashalg, unsigned int iterations, result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); + result = dns_dbiterator_current(dbiter, &node, name); + check_dns_dbiterator_current(result); + /* + * Delete any NSEC records at the apex. + */ + result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + for (result = dns_rdatasetiter_first(rdsiter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsiter)) { + dns_rdatasetiter_current(rdsiter, &rdataset); + type = rdataset.type; + covers = rdataset.covers; + dns_rdataset_disassociate(&rdataset); + if (type == dns_rdatatype_nsec || + covers == dns_rdatatype_nsec) { + result = dns_db_deleterdataset(gdb, node, gversion, + type, covers); + check_result(result, + "dns_db_deleterdataset(nsec3param/rrsig)"); + continue; + } + } + dns_rdatasetiter_destroy(&rdsiter); + dns_db_detachnode(gdb, &node); + while (!done) { - dns_dbiterator_current(dbiter, &node, name); + result = dns_dbiterator_current(dbiter, &node, name); + check_dns_dbiterator_current(result); result = dns_dbiterator_next(dbiter); nextnode = NULL; while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(dbiter, &nextnode, nextname); - if (result != ISC_R_SUCCESS) - break; + check_dns_dbiterator_current(result); active = active_node(nextnode); if (!active) { dns_db_detachnode(gdb, &nextnode); @@ -1927,6 +2441,26 @@ nsec3ify(unsigned int hashalg, unsigned int iterations, addnsec3param(salt, salt_length, iterations); + /* + * Clean out NSEC3 records which don't match this chain. + */ + result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter); + check_result(result, "dns_db_createiterator()"); + + for (result = dns_dbiterator_first(dbiter); + result == ISC_R_SUCCESS; + result = dns_dbiterator_next(dbiter)) { + result = dns_dbiterator_current(dbiter, &node, name); + check_dns_dbiterator_current(result); + nsec3clean(name, node, hashalg, iterations, salt, salt_length, + hashlist); + dns_db_detachnode(gdb, &node); + } + dns_dbiterator_destroy(&dbiter); + + /* + * Generate / complete the new chain. + */ result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); check_result(result, "dns_db_createiterator()"); @@ -1934,25 +2468,16 @@ nsec3ify(unsigned int hashalg, unsigned int iterations, check_result(result, "dns_dbiterator_first()"); while (!done) { - dns_dbiterator_current(dbiter, &node, name); + result = dns_dbiterator_current(dbiter, &node, name); + check_dns_dbiterator_current(result); result = dns_dbiterator_next(dbiter); nextnode = NULL; while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(dbiter, &nextnode, nextname); - if (result != ISC_R_SUCCESS) - break; - /* - * Cleanout NSEC3 RRsets which don't exist in the - * hash table. - */ - nsec3clean(nextname, nextnode, hashalg, iterations, - salt, salt_length, hashlist); - /* - * Skip NSEC3 only nodes when looking for the next - * node in the zone. Also skips now empty nodes. - */ - if (nsec3only(nextnode)) { + check_dns_dbiterator_current(result); + active = active_node(nextnode); + if (!active) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; @@ -2098,7 +2623,8 @@ loadzonepubkeys(dns_db_t *db) { dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, currentversion, - dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); + dns_rdatatype_dnskey, 0, 0, &rdataset, + NULL); if (result != ISC_R_SUCCESS) fatal("failed to find keys at the zone apex: %s", isc_result_totext(result)); @@ -2134,7 +2660,7 @@ warnifallksk(dns_db_t *db) { dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; - dns_rdata_key_t key; + dns_rdata_dnskey_t dnskey; isc_boolean_t have_non_ksk = ISC_FALSE; dns_db_currentversion(db, ¤tversion); @@ -2146,7 +2672,8 @@ warnifallksk(dns_db_t *db) { dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, currentversion, - dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); + dns_rdatatype_dnskey, 0, 0, &rdataset, + NULL); if (result != ISC_R_SUCCESS) fatal("failed to find keys at the zone apex: %s", isc_result_totext(result)); @@ -2155,21 +2682,27 @@ warnifallksk(dns_db_t *db) { while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &key, NULL); + result = dns_rdata_tostruct(&rdata, &dnskey, NULL); check_result(result, "dns_rdata_tostruct"); - if ((key.flags & DNS_KEYFLAG_KSK) == 0) { + if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) { have_non_ksk = ISC_TRUE; result = ISC_R_NOMORE; } else result = dns_rdataset_next(&rdataset); + dns_rdata_freestruct(&dnskey); } dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &node); dns_db_closeversion(db, ¤tversion, ISC_FALSE); - if (!have_non_ksk && !ignoreksk) - fprintf(stderr, "%s: warning: No non-KSK dnskey found. " - "Supply non-KSK dnskey or use '-z'.\n", - program); + if (!have_non_ksk && !ignoreksk) { + if (disable_zone_check) + fprintf(stderr, "%s: warning: No non-KSK dnskey found. " + "Supply non-KSK dnskey or use '-z'.\n", + program); + else + fatal("No non-KSK dnskey found. " + "Supply non-KSK dnskey or use '-z'."); + } } static void @@ -2343,7 +2876,8 @@ usage(void) { fprintf(stderr, "\t-g:\t"); fprintf(stderr, "generate DS records from keyset files\n"); fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n"); - fprintf(stderr, "\t\tRRSIG start time - absolute|offset (now - 1 hour)\n"); + fprintf(stderr, "\t\tRRSIG start time - absolute|offset " + "(now - 1 hour)\n"); fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); fprintf(stderr, "\t\tRRSIG end time - absolute|from start|from now " "(now + 30 days)\n"); @@ -2351,7 +2885,8 @@ usage(void) { fprintf(stderr, "\t\tcycle interval - resign " "if < interval from end ( (end-start)/4 )\n"); fprintf(stderr, "\t-j jitter:\n"); - fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n"); + fprintf(stderr, "\t\trandomize signature end time up to jitter " + "seconds\n"); fprintf(stderr, "\t-v debuglevel (0)\n"); fprintf(stderr, "\t-o origin:\n"); fprintf(stderr, "\t\tzone origin (name of zonefile)\n"); @@ -2370,6 +2905,8 @@ usage(void) { fprintf(stderr, "verify generated signatures\n"); fprintf(stderr, "\t-p:\t"); fprintf(stderr, "use pseudorandom data (faster but less secure)\n"); + fprintf(stderr, "\t-P:\t"); + fprintf(stderr, "disable post-sign verification\n"); fprintf(stderr, "\t-t:\t"); fprintf(stderr, "print statistics\n"); fprintf(stderr, "\t-n ncpus (number of cpus present)\n"); @@ -2448,7 +2985,7 @@ main(int argc, char *argv[]) { unsigned char saltbuf[255]; hashlist_t hashlist; -#define CMDLINE_FLAGS "3:aAc:d:e:f:ghH:i:I:j:k:l:m:n:N:o:O:pr:s:StUv:z" +#define CMDLINE_FLAGS "3:aAc:d:e:f:FghH:i:I:j:k:l:m:n:N:o:O:pPr:s:StUv:z" /* * Process memory debugging argument first. @@ -2535,19 +3072,19 @@ main(int argc, char *argv[]) { generateds = ISC_TRUE; break; - case '?': - if (isc_commandline_option != '?') - fprintf(stderr, "%s: invalid argument -%c\n", - program, isc_commandline_option); + case 'H': + iterations = strtoul(isc_commandline_argument, + &endp, 0); + if (*endp != '\0') + fatal("iterations must be numeric"); + if (iterations > 0xffffU) + fatal("iterations too big"); + break; + case 'h': usage(); break; - default: - fprintf(stderr, "%s: unhandled option -%c\n", - program, isc_commandline_option); - exit(1); - case 'i': endp = NULL; cycle = strtol(isc_commandline_argument, &endp, 0); @@ -2567,8 +3104,13 @@ main(int argc, char *argv[]) { fatal("jitter must be numeric and positive"); break; + case 'k': + if (ndskeys == MAXDSKEYS) + fatal("too many key-signing keys specified"); + dskeyfile[ndskeys++] = isc_commandline_argument; + break; + case 'l': - dns_fixedname_init(&dlv_fixed); len = strlen(isc_commandline_argument); isc_buffer_init(&b, isc_commandline_argument, len); isc_buffer_add(&b, len); @@ -2580,12 +3122,6 @@ main(int argc, char *argv[]) { check_result(result, "dns_name_fromtext(dlv)"); break; - case 'k': - if (ndskeys == MAXDSKEYS) - fatal("too many key-signing keys specified"); - dskeyfile[ndskeys++] = isc_commandline_argument; - break; - case 'm': break; @@ -2600,15 +3136,6 @@ main(int argc, char *argv[]) { serialformatstr = isc_commandline_argument; break; - case 'H': - iterations = strtoul(isc_commandline_argument, - &endp, 0); - if (*endp != '\0') - fatal("iterations must be numeric"); - if (iterations > 0xffffU) - fatal("iterations too big"); - break; - case 'o': origin = isc_commandline_argument; break; @@ -2621,6 +3148,10 @@ main(int argc, char *argv[]) { pseudorandom = ISC_TRUE; break; + case 'P': + disable_zone_check = ISC_TRUE; + break; + case 'r': setup_entropy(mctx, isc_commandline_argument, &ectx); break; @@ -2653,6 +3184,21 @@ main(int argc, char *argv[]) { case 'z': ignoreksk = ISC_TRUE; break; + + case 'F': + /* Reserved for FIPS mode */ + /* FALLTHROUGH */ + case '?': + if (isc_commandline_option != '?') + fprintf(stderr, "%s: invalid argument -%c\n", + program, isc_commandline_option); + usage(); + break; + + default: + fprintf(stderr, "%s: unhandled option -%c\n", + program, isc_commandline_option); + exit(1); } } @@ -2743,7 +3289,8 @@ main(int argc, char *argv[]) { else if (strcasecmp(serialformatstr, "unixtime") == 0) serialformat = SOA_SERIAL_UNIXTIME; else - fatal("unknown soa serial format: %s\n", serialformatstr); + fatal("unknown soa serial format: %s\n", + serialformatstr); } result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL, @@ -2769,7 +3316,12 @@ main(int argc, char *argv[]) { "NSEC only DNSKEY"); } + /* + * We need to do this early on, as we start messing with the list + * of keys rather early. + */ ISC_LIST_INIT(keylist); + isc_rwlock_init(&keylist_lock, 0, 0); if (argc == 0) { loadzonekeys(gdb); @@ -2806,6 +3358,7 @@ main(int argc, char *argv[]) { } if (key == NULL) { key = newkeystruct(newkey, ISC_TRUE); + key->commandline = ISC_TRUE; ISC_LIST_APPEND(keylist, key, link); } else dst_key_free(&newkey); @@ -2856,8 +3409,11 @@ main(int argc, char *argv[]) { } if (ISC_LIST_EMPTY(keylist)) { - fprintf(stderr, "%s: warning: No keys specified or found\n", - program); + if (disable_zone_check) + fprintf(stderr, "%s: warning: No keys specified " + "or found\n", program); + else + fatal("No signing keys specified or found."); nokeys = ISC_TRUE; } @@ -2972,6 +3528,7 @@ main(int argc, char *argv[]) { isc_taskmgr_destroy(&taskmgr); isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *)); postsign(); + verifyzone(); if (outputformat != dns_masterformat_text) { result = dns_master_dumptostream2(mctx, gdb, gversion, diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook b/contrib/bind9/bin/dnssec/dnssec-signzone.docbook index 7ed320ad575..f204fcd60d7 100644 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook +++ b/contrib/bind9/bin/dnssec/dnssec-signzone.docbook @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + June 08, 2009 @@ -73,6 +73,7 @@ + @@ -91,10 +92,10 @@ dnssec-signzone signs a zone. It generates NSEC and RRSIG records and produces a signed version of the - zone. The security status of delegations from the signed zone - (that is, whether the child zones are secure or not) is - determined by the presence or absence of a - keyset file for each child zone. + zone. It also generates a keyset- file containing + the key-signing keys for the zone, and if signing a zone which + contains delegations, it can optionally generate DS records for + the child zones from their keyset- files. @@ -154,8 +155,10 @@ -g - Generate DS records for child zones from keyset files. - Existing DS records will be removed. + If the zone contains any delegations, and there are + keyset- files for any of the child zones, + then DS records for the child zones will be generated from the + keys in those files. Existing DS records will be removed. @@ -359,6 +362,22 @@ + + -P + + + Disable post sign verification tests. + + + The post sign verification test ensures that for each algorithm + in use there is at least one non revoked self signed KSK key, + that all revoked KSK keys are self signed, and that all records + in the zone are signed by the algorithm. + This option skips these tests. + + + + -r randomdev diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.html b/contrib/bind9/bin/dnssec/dnssec-signzone.html index 652d5c4355f..e7c534f9094 100644 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.html +++ b/contrib/bind9/bin/dnssec/dnssec-signzone.html @@ -2,7 +2,7 @@ - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000-2003 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -29,21 +29,21 @@

    Synopsis

    -

    dnssec-signzone [-a] [-c class] [-d directory] [-e end-time] [-f output-file] [-g] [-h] [-k key] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-p] [-r randomdev] [-s start-time] [-t] [-v level] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

    +

    dnssec-signzone [-a] [-c class] [-d directory] [-e end-time] [-f output-file] [-g] [-h] [-k key] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-p] [-P] [-r randomdev] [-s start-time] [-t] [-v level] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

    -

    DESCRIPTION

    +

    DESCRIPTION

    dnssec-signzone signs a zone. It generates NSEC and RRSIG records and produces a signed version of the - zone. The security status of delegations from the signed zone - (that is, whether the child zones are secure or not) is - determined by the presence or absence of a - keyset file for each child zone. + zone. It also generates a keyset- file containing + the key-signing keys for the zone, and if signing a zone which + contains delegations, it can optionally generate DS records for + the child zones from their keyset- files.

    -

    OPTIONS

    +

    OPTIONS

    -a

    @@ -70,8 +70,10 @@

    -g

    - Generate DS records for child zones from keyset files. - Existing DS records will be removed. + If the zone contains any delegations, and there are + keyset- files for any of the child zones, + then DS records for the child zones will be generated from the + keys in those files. Existing DS records will be removed.

    -s start-time

    @@ -202,6 +204,19 @@ may be useful when signing large zones or when the entropy source is limited.

    +
    -P
    +
    +

    + Disable post sign verification tests. +

    +

    + The post sign verification test ensures that for each algorithm + in use there is at least one non revoked self signed KSK key, + that all revoked KSK keys are self signed, and that all records + in the zone are signed by the algorithm. + This option skips these tests. +

    +
    -r randomdev

    Specifies the source of randomness. If the operating @@ -258,7 +273,7 @@

    -

    EXAMPLE

    +

    EXAMPLE

    The following command signs the example.com zone with the DSA key generated by dnssec-keygen @@ -287,7 +302,7 @@ db.example.com.signed %

    -

    KNOWN BUGS

    +

    KNOWN BUGS

    dnssec-signzone was designed so that it could sign a zone partially, using only a subset of the DNSSEC keys @@ -312,14 +327,14 @@ db.example.com.signed

    -

    SEE ALSO

    +

    SEE ALSO

    dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 4033.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/bin/dnssec/dnssectool.c b/contrib/bind9/bin/dnssec/dnssectool.c index b89d76945b8..3a6b7f024b6 100644 --- a/contrib/bind9/bin/dnssec/dnssectool.c +++ b/contrib/bind9/bin/dnssec/dnssectool.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssectool.c,v 1.45.334.4 2009/06/08 23:47:00 tbox Exp $ */ +/* $Id: dnssectool.c,v 1.45.334.5 2009/06/22 05:05:00 marka Exp $ */ /*! \file */ @@ -65,7 +65,7 @@ void fatal(const char *format, ...) { va_list args; - fprintf(stderr, "%s: ", program); + fprintf(stderr, "%s: fatal: ", program); va_start(args, format); vfprintf(stderr, format, args); va_end(args); diff --git a/contrib/bind9/bin/dnssec/dnssectool.h b/contrib/bind9/bin/dnssec/dnssectool.h index ee476f4ea78..43b7375b26e 100644 --- a/contrib/bind9/bin/dnssec/dnssectool.h +++ b/contrib/bind9/bin/dnssec/dnssectool.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssectool.h,v 1.22 2008/09/25 04:02:38 tbox Exp $ */ +/* $Id: dnssectool.h,v 1.22.48.2 2009/09/04 23:46:58 tbox Exp $ */ #ifndef DNSSECTOOL_H #define DNSSECTOOL_H 1 @@ -45,7 +45,7 @@ type_format(const dns_rdatatype_t type, char *cp, unsigned int size); void alg_format(const dns_secalg_t alg, char *cp, unsigned int size); -#define ALG_FORMATSIZE 10 +#define ALG_FORMATSIZE 20 void sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size); diff --git a/contrib/bind9/bin/named/control.c b/contrib/bind9/bin/named/control.c index 8bd8f6ce361..ac1ec4217da 100644 --- a/contrib/bind9/bin/named/control.c +++ b/contrib/bind9/bin/named/control.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: control.c,v 1.33 2007/09/13 04:45:18 each Exp $ */ +/* $Id: control.c,v 1.33.266.2 2009/07/11 23:47:17 tbox Exp $ */ /*! \file */ @@ -56,7 +56,7 @@ command_compare(const char *text, const char *command) { /*% * This function is called to process the incoming command - * when a control channel message is received. + * when a control channel message is received. */ isc_result_t ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) { @@ -170,10 +170,12 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) { } else if (command_compare(command, NS_COMMAND_TSIGDELETE)) { result = ns_server_tsigdelete(ns_g_server, command, text); } else if (command_compare(command, NS_COMMAND_FREEZE)) { - result = ns_server_freeze(ns_g_server, ISC_TRUE, command); + result = ns_server_freeze(ns_g_server, ISC_TRUE, command, + text); } else if (command_compare(command, NS_COMMAND_UNFREEZE) || command_compare(command, NS_COMMAND_THAW)) { - result = ns_server_freeze(ns_g_server, ISC_FALSE, command); + result = ns_server_freeze(ns_g_server, ISC_FALSE, command, + text); } else if (command_compare(command, NS_COMMAND_RECURSING)) { result = ns_server_dumprecursing(ns_g_server); } else if (command_compare(command, NS_COMMAND_TIMERPOKE)) { diff --git a/contrib/bind9/bin/named/include/named/server.h b/contrib/bind9/bin/named/include/named/server.h index 43eccc4a63d..1a3f746f3fb 100644 --- a/contrib/bind9/bin/named/include/named/server.h +++ b/contrib/bind9/bin/named/include/named/server.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.h,v 1.93.120.2 2009/01/29 23:47:44 tbox Exp $ */ +/* $Id: server.h,v 1.93.120.3 2009/07/11 04:23:53 marka Exp $ */ #ifndef NAMED_SERVER_H #define NAMED_SERVER_H 1 @@ -276,7 +276,8 @@ ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t *text); * Enable or disable updates for a zone. */ isc_result_t -ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args); +ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args, + isc_buffer_t *text); /*% * Dump the current recursive queries. diff --git a/contrib/bind9/bin/named/lwresd.8 b/contrib/bind9/bin/named/lwresd.8 index c0862aae1f4..56d272b23ad 100644 --- a/contrib/bind9/bin/named/lwresd.8 +++ b/contrib/bind9/bin/named/lwresd.8 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwresd.8,v 1.29.14.1 2009/01/23 01:53:33 tbox Exp $ +.\" $Id: lwresd.8,v 1.29.14.2 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/named/lwresd.html b/contrib/bind9/bin/named/lwresd.html index 4c2b059fcfc..728acc8a816 100644 --- a/contrib/bind9/bin/named/lwresd.html +++ b/contrib/bind9/bin/named/lwresd.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/bin/named/named.8 b/contrib/bind9/bin/named/named.8 index 340840360fa..287427274cb 100644 --- a/contrib/bind9/bin/named/named.8 +++ b/contrib/bind9/bin/named/named.8 @@ -1,7 +1,7 @@ -.\" Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,18 +13,18 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: named.8,v 1.38 2008/11/07 01:11:19 tbox Exp $ +.\" $Id: named.8,v 1.38.14.2 2009/12/03 05:06:38 tbox Exp $ .\" .hy 0 .ad l .\" Title: named .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: June 30, 2000 +.\" Date: May 21, 2009 .\" Manual: BIND9 .\" Source: BIND9 .\" -.TH "NAMED" "8" "June 30, 2000" "BIND9" "BIND9" +.TH "NAMED" "8" "May 21, 2009" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -224,6 +224,16 @@ The \fBnamed\fR configuration file is too complex to describe in detail here. A complete description is provided in the BIND 9 Administrator Reference Manual. +.PP +\fBnamed\fR +inherits the +\fBumask\fR +(file creation mode mask) from the parent process. If files created by +\fBnamed\fR, such as journal files, need to have custom permissions, the +\fBumask\fR +should be set explicitly in the script used to start the +\fBnamed\fR +process. .SH "FILES" .PP \fI/etc/named.conf\fR @@ -250,7 +260,7 @@ BIND 9 Administrator Reference Manual. .PP Internet Systems Consortium .SH "COPYRIGHT" -Copyright \(co 2004\-2008 Internet Systems Consortium, Inc. ("ISC") +Copyright \(co 2004\-2009 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001, 2003 Internet Software Consortium. .br diff --git a/contrib/bind9/bin/named/named.conf.5 b/contrib/bind9/bin/named/named.conf.5 index 039c7954dfd..3206f5d6bbc 100644 --- a/contrib/bind9/bin/named/named.conf.5 +++ b/contrib/bind9/bin/named/named.conf.5 @@ -1,6 +1,6 @@ .\" Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -12,7 +12,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: named.conf.5,v 1.36 2008/09/25 04:45:04 tbox Exp $ +.\" $Id: named.conf.5,v 1.36.48.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/named/named.conf.html b/contrib/bind9/bin/named/named.conf.html index 7bbbd0acbcb..190f0c1b888 100644 --- a/contrib/bind9/bin/named/named.conf.html +++ b/contrib/bind9/bin/named/named.conf.html @@ -1,7 +1,7 @@ - + diff --git a/contrib/bind9/bin/named/named.docbook b/contrib/bind9/bin/named/named.docbook index f47eae1e6b4..246c4f5d399 100644 --- a/contrib/bind9/bin/named/named.docbook +++ b/contrib/bind9/bin/named/named.docbook @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []> - + - June 30, 2000 + May 21, 2009 @@ -42,6 +42,7 @@ 2006 2007 2008 + 2009 Internet Systems Consortium, Inc. ("ISC") @@ -374,6 +375,16 @@ in the BIND 9 Administrator Reference Manual. + + + named inherits the umask + (file creation mode mask) from the parent process. If files + created by named, such as journal files, + need to have custom permissions, the umask + should be set explicitly in the script used to start the + named process. + + diff --git a/contrib/bind9/bin/named/named.html b/contrib/bind9/bin/named/named.html index 23c9a7c32bc..35224759ee7 100644 --- a/contrib/bind9/bin/named/named.html +++ b/contrib/bind9/bin/named/named.html @@ -1,8 +1,8 @@ - + @@ -32,7 +32,7 @@

    named [-4] [-6] [-c config-file] [-d debug-level] [-f] [-g] [-m flag] [-n #cpus] [-p port] [-s] [-S #max-socks] [-t directory] [-u user] [-v] [-V] [-x cache-file]

    -

    DESCRIPTION

    +

    DESCRIPTION

    named is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC. For more @@ -47,7 +47,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -4

    @@ -220,7 +220,7 @@

    -

    SIGNALS

    +

    SIGNALS

    In routine operation, signals should not be used to control the nameserver; rndc should be used @@ -241,16 +241,24 @@

    -

    CONFIGURATION

    +

    CONFIGURATION

    The named configuration file is too complex to describe in detail here. A complete description is provided in the BIND 9 Administrator Reference Manual.

    +

    + named inherits the umask + (file creation mode mask) from the parent process. If files + created by named, such as journal files, + need to have custom permissions, the umask + should be set explicitly in the script used to start the + named process. +

    -

    FILES

    +

    FILES

    /etc/named.conf

    @@ -263,7 +271,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    RFC 1033, RFC 1034, RFC 1035, @@ -276,7 +284,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/bin/named/query.c b/contrib/bind9/bin/named/query.c index a56d2e646f7..cef6d7f7c3a 100644 --- a/contrib/bind9/bin/named/query.c +++ b/contrib/bind9/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.313.20.7.12.4 2009/12/31 22:53:03 each Exp $ */ +/* $Id: query.c,v 1.313.20.16 2009/12/30 08:34:29 jinmei Exp $ */ /*! \file */ @@ -2244,7 +2244,8 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { static inline isc_result_t query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname, - dns_trust_t trust, dns_name_t **anamep, dns_rdatatype_t type) + dns_rdataset_t *dname, dns_name_t **anamep, + dns_rdatatype_t type) { dns_rdataset_t *rdataset; dns_rdatalist_t *rdatalist; @@ -2280,7 +2281,7 @@ query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname, rdatalist->type = type; rdatalist->covers = 0; rdatalist->rdclass = client->message->rdclass; - rdatalist->ttl = 0; + rdatalist->ttl = dname->ttl; dns_name_toregion(tname, &r); rdata->data = r.base; @@ -2292,7 +2293,7 @@ query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname, ISC_LIST_APPEND(rdatalist->rdata, rdata, link); RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS); - rdataset->trust = trust; + rdataset->trust = dname->trust; query_addrrset(client, anamep, &rdataset, NULL, NULL, DNS_SECTION_ANSWER); @@ -2735,7 +2736,7 @@ query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node, return; addnsec3: - if (dns_db_iscache(db)) + if (!dns_db_iszone(db)) goto cleanup; /* * Add the NSEC3 which proves the DS does not exist. @@ -3317,6 +3318,14 @@ do { \ line = __LINE__; \ } while (0) +#define RECURSE_ERROR(r) \ +do { \ + if ((r) == DNS_R_DUPLICATE || (r) == DNS_R_DROP) \ + QUERY_ERROR(r); \ + else \ + QUERY_ERROR(DNS_R_SERVFAIL); \ +} while (0) + /* * Extract a network address from the RDATA of an A or AAAA * record. @@ -3604,7 +3613,7 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, dns_name_t *found) { unsigned char salt[256]; - size_t salt_length = sizeof(salt); + size_t salt_length; isc_uint16_t iterations; isc_result_t result; unsigned int dboptions; @@ -3999,14 +4008,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) if (result == ISC_R_SUCCESS) client->query.attributes |= NS_QUERYATTR_RECURSING; - else if (result == DNS_R_DUPLICATE || - result == DNS_R_DROP) { - /* Duplicate query. */ - QUERY_ERROR(result); - } else { - /* Unable to recurse. */ - QUERY_ERROR(DNS_R_SERVFAIL); - } + else + RECURSE_ERROR(result); goto cleanup; } else { /* Unable to give root server referral. */ @@ -4185,11 +4188,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) if (result == ISC_R_SUCCESS) client->query.attributes |= NS_QUERYATTR_RECURSING; - else if (result == DNS_R_DUPLICATE || - result == DNS_R_DROP) - QUERY_ERROR(result); else - QUERY_ERROR(DNS_R_SERVFAIL); + RECURSE_ERROR(result); } else { dns_fixedname_t fixed; @@ -4603,7 +4603,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) */ dns_name_init(tname, NULL); (void)query_addcnamelike(client, client->query.qname, fname, - trdataset->trust, &tname, + trdataset, &tname, dns_rdatatype_cname); if (tname != NULL) dns_message_puttempname(client->message, &tname); @@ -4729,7 +4729,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) client->query.attributes |= NS_QUERYATTR_RECURSING; else - QUERY_ERROR(DNS_R_SERVFAIL); } + RECURSE_ERROR(result); + } goto addauth; } /* @@ -5123,9 +5124,17 @@ ns_query_start(ns_client_t *client) { } /* - * Turn on minimal response for DNSKEY queries. + * Turn on minimal response for DNSKEY and DS queries. */ - if (qtype == dns_rdatatype_dnskey) + if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds) + client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | + NS_QUERYATTR_NOADDITIONAL); + + /* + * Turn on minimal responses for EDNS/UDP bufsize 512 queries. + */ + if (client->opt != NULL && client->udpsize <= 512U && + (client->attributes & NS_CLIENTATTR_TCP) == 0) client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | NS_QUERYATTR_NOADDITIONAL); diff --git a/contrib/bind9/bin/named/server.c b/contrib/bind9/bin/named/server.c index e685e18dc33..6608fdfe140 100644 --- a/contrib/bind9/bin/named/server.c +++ b/contrib/bind9/bin/named/server.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.520.12.7 2009/01/30 03:53:38 marka Exp $ */ +/* $Id: server.c,v 1.520.12.11.8.2 2010/02/25 10:57:11 tbox Exp $ */ /*! \file */ @@ -2826,7 +2826,7 @@ set_limit(const cfg_obj_t **maps, const char *configname, isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, result == ISC_R_SUCCESS ? ISC_LOG_DEBUG(3) : ISC_LOG_WARNING, - "set maximum %s to %" ISC_PRINT_QUADFORMAT "d: %s", + "set maximum %s to %" ISC_PRINT_QUADFORMAT "u: %s", description, value, isc_result_totext(result)); } @@ -4337,6 +4337,8 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) { /* Partial match? */ if (result != ISC_R_SUCCESS && *zonep != NULL) dns_zone_detach(zonep); + if (result == DNS_R_PARTIALMATCH) + result = ISC_R_NOTFOUND; fail1: return (result); } @@ -4724,6 +4726,8 @@ dumpdone(void *arg, isc_result_t result) { } if (dctx->cache != NULL) { dns_adb_dump(dctx->view->view->adb, dctx->fp); + dns_resolver_printbadcache(dctx->view->view->resolver, + dctx->fp); dns_db_detach(&dctx->cache); } if (dctx->dumpzones) { @@ -5401,7 +5405,9 @@ ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text) { * Act on a "freeze" or "thaw" command from the command channel. */ isc_result_t -ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) { +ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args, + isc_buffer_t *text) +{ isc_result_t result, tresult; dns_zone_t *zone = NULL; dns_zonetype_t type; @@ -5411,6 +5417,7 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) { char *journal; const char *vname, *sep; isc_boolean_t frozen; + const char *msg = NULL; result = zone_from_args(server, args, &zone); if (result != ISC_R_SUCCESS) @@ -5441,27 +5448,52 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) { return (ISC_R_NOTFOUND); } + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); frozen = dns_zone_getupdatedisabled(zone); if (freeze) { - if (frozen) + if (frozen) { + msg = "WARNING: The zone was already frozen.\n" + "Someone else may be editing it or " + "it may still be re-loading."; result = DNS_R_FROZEN; - if (result == ISC_R_SUCCESS) + } + if (result == ISC_R_SUCCESS) { result = dns_zone_flush(zone); + if (result != ISC_R_SUCCESS) + msg = "Flushing the zone updates to " + "disk failed."; + } if (result == ISC_R_SUCCESS) { journal = dns_zone_getjournal(zone); if (journal != NULL) (void)isc_file_remove(journal); } + if (result == ISC_R_SUCCESS) + dns_zone_setupdatedisabled(zone, freeze); } else { if (frozen) { - result = dns_zone_load(zone); - if (result == DNS_R_CONTINUE || - result == DNS_R_UPTODATE) + result = dns_zone_loadandthaw(zone); + switch (result) { + case ISC_R_SUCCESS: + case DNS_R_UPTODATE: + msg = "The zone reload and thaw was " + "successful."; result = ISC_R_SUCCESS; + break; + case DNS_R_CONTINUE: + msg = "A zone reload and thaw was started.\n" + "Check the logs to see the result."; + result = ISC_R_SUCCESS; + break; + } } } - if (result == ISC_R_SUCCESS) - dns_zone_setupdatedisabled(zone, freeze); + isc_task_endexclusive(server->task); + + if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text)) + isc_buffer_putmem(text, (const unsigned char *)msg, + strlen(msg) + 1); view = dns_zone_getview(zone); if (strcmp(view->name, "_bind") == 0 || diff --git a/contrib/bind9/bin/named/statschannel.c b/contrib/bind9/bin/named/statschannel.c index 81f40bb2d15..4773ec6dcad 100644 --- a/contrib/bind9/bin/named/statschannel.c +++ b/contrib/bind9/bin/named/statschannel.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2008-2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: statschannel.c,v 1.14.64.6 2009/02/17 03:43:07 marka Exp $ */ +/* $Id: statschannel.c,v 1.14.64.11 2010/02/04 23:47:46 tbox Exp $ */ /*! \file */ @@ -70,6 +70,7 @@ stats_dumparg { int ncounters; /* used for general statistics */ int *counterindices; /* used for general statistics */ isc_uint64_t *countervalues; /* used for general statistics */ + isc_result_t result; } stats_dumparg_t; static isc_once_t once = ISC_ONCE_INIT; @@ -95,6 +96,8 @@ static const char *sockstats_xmldesc[isc_sockstatscounter_max]; #define sockstats_xmldesc NULL #endif /* HAVE_LIBXML2 */ +#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) + /*% * Mapping arrays to represent statistics counters in the order of our * preference, regardless of the order of counter indices. For example, @@ -129,11 +132,11 @@ init_desc(void) { int i; /* Initialize name server statistics */ - memset((void *)nsstats_desc, 0, - dns_nsstatscounter_max * sizeof(nsstats_desc[0])); + for (i = 0; i < dns_nsstatscounter_max; i++) + nsstats_desc[i] = NULL; #ifdef HAVE_LIBXML2 - memset((void *)nsstats_xmldesc, 0, - dns_nsstatscounter_max * sizeof(nsstats_xmldesc[0])); + for (i = 0; i < dns_nsstatscounter_max; i++) + nsstats_xmldesc[i] = NULL; #endif #define SET_NSSTATDESC(counterid, desc, xmldesc) \ @@ -197,11 +200,11 @@ init_desc(void) { INSIST(i == dns_nsstatscounter_max); /* Initialize resolver statistics */ - memset((void *)resstats_desc, 0, - dns_resstatscounter_max * sizeof(resstats_desc[0])); + for (i = 0; i < dns_resstatscounter_max; i++) + resstats_desc[i] = NULL; #ifdef HAVE_LIBXML2 - memset((void *)resstats_xmldesc, 0, - dns_resstatscounter_max * sizeof(resstats_xmldesc[0])); + for (i = 0; i < dns_resstatscounter_max; i++) + resstats_xmldesc[i] = NULL; #endif #define SET_RESSTATDESC(counterid, desc, xmldesc) \ @@ -267,11 +270,11 @@ init_desc(void) { INSIST(i == dns_resstatscounter_max); /* Initialize zone statistics */ - memset((void *)zonestats_desc, 0, - dns_zonestatscounter_max * sizeof(zonestats_desc[0])); + for (i = 0; i < dns_zonestatscounter_max; i++) + zonestats_desc[i] = NULL; #ifdef HAVE_LIBXML2 - memset((void *)zonestats_xmldesc, 0, - dns_zonestatscounter_max * sizeof(zonestats_xmldesc[0])); + for (i = 0; i < dns_zonestatscounter_max; i++) + zonestats_xmldesc[i] = NULL; #endif #define SET_ZONESTATDESC(counterid, desc, xmldesc) \ @@ -299,11 +302,11 @@ init_desc(void) { INSIST(i == dns_zonestatscounter_max); /* Initialize socket statistics */ - memset((void *)sockstats_desc, 0, - isc_sockstatscounter_max * sizeof(sockstats_desc[0])); + for (i = 0; i < isc_sockstatscounter_max; i++) + sockstats_desc[i] = NULL; #ifdef HAVE_LIBXML2 - memset((void *)sockstats_xmldesc, 0, - isc_sockstatscounter_max * sizeof(sockstats_xmldesc[0])); + for (i = 0; i < isc_sockstatscounter_max; i++) + sockstats_xmldesc[i] = NULL; #endif #define SET_SOCKSTATDESC(counterid, desc, xmldesc) \ @@ -437,7 +440,7 @@ generalstat_dump(isc_statscounter_t counter, isc_uint64_t val, void *arg) { dumparg->countervalues[counter] = val; } -static void +static isc_result_t dump_counters(isc_stats_t *stats, statsformat_t type, void *arg, const char *category, const char **desc, int ncounters, int *indices, isc_uint64_t *values, int options) @@ -448,6 +451,7 @@ dump_counters(isc_stats_t *stats, statsformat_t type, void *arg, FILE *fp; #ifdef HAVE_LIBXML2 xmlTextWriterPtr writer; + int xmlrc; #endif #ifndef HAVE_LIBXML2 @@ -480,31 +484,41 @@ dump_counters(isc_stats_t *stats, statsformat_t type, void *arg, writer = arg; if (category != NULL) { - xmlTextWriterStartElement(writer, - ISC_XMLCHAR - category); - xmlTextWriterStartElement(writer, - ISC_XMLCHAR "name"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR - desc[index]); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR + category)); + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR + "name")); + TRY0(xmlTextWriterWriteString(writer, + ISC_XMLCHAR + desc[index])); + TRY0(xmlTextWriterEndElement(writer)); /* name */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR - "counter"); + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR + "counter")); } else { - xmlTextWriterStartElement(writer, ISC_XMLCHAR - desc[index]); + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR + desc[index])); } - xmlTextWriterWriteFormatString(writer, - "%" ISC_PRINT_QUADFORMAT - "u", value); - xmlTextWriterEndElement(writer); /* counter */ + TRY0(xmlTextWriterWriteFormatString(writer, + "%" + ISC_PRINT_QUADFORMAT + "u", value)); + TRY0(xmlTextWriterEndElement(writer)); /* counter */ if (category != NULL) - xmlTextWriterEndElement(writer); /* category */ + TRY0(xmlTextWriterEndElement(writer)); /* category */ #endif break; } } + return (ISC_R_SUCCESS); +#ifdef HAVE_LIBXML2 + error: + return (ISC_R_FAILURE); +#endif } static void @@ -515,6 +529,7 @@ rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) { FILE *fp; #ifdef HAVE_LIBXML2 xmlTextWriterPtr writer; + int xmlrc; #endif if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) @@ -534,22 +549,28 @@ rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) { #ifdef HAVE_LIBXML2 writer = dumparg->arg; - xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype")); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr)); + TRY0(xmlTextWriterEndElement(writer)); /* name */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"); - xmlTextWriterWriteFormatString(writer, + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); + TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - val); - xmlTextWriterEndElement(writer); /* counter */ + val)); + TRY0(xmlTextWriterEndElement(writer)); /* counter */ - xmlTextWriterEndElement(writer); /* rdtype */ + TRY0(xmlTextWriterEndElement(writer)); /* rdtype */ #endif break; } + return; +#ifdef HAVE_LIBXML2 + error: + dumparg->result = ISC_R_FAILURE; + return; +#endif } static void @@ -561,6 +582,7 @@ rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) { isc_boolean_t nxrrset = ISC_FALSE; #ifdef HAVE_LIBXML2 xmlTextWriterPtr writer; + int xmlrc; #endif if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) @@ -589,22 +611,28 @@ rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) { #ifdef HAVE_LIBXML2 writer = dumparg->arg; - xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset"); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteFormatString(writer, "%s%s", - nxrrset ? "!" : "", typestr); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset")); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteFormatString(writer, "%s%s", + nxrrset ? "!" : "", typestr)); + TRY0(xmlTextWriterEndElement(writer)); /* name */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"); - xmlTextWriterWriteFormatString(writer, + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); + TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - val); - xmlTextWriterEndElement(writer); /* counter */ + val)); + TRY0(xmlTextWriterEndElement(writer)); /* counter */ - xmlTextWriterEndElement(writer); /* rrset */ + TRY0(xmlTextWriterEndElement(writer)); /* rrset */ #endif break; } + return; +#ifdef HAVE_LIBXML2 + error: + dumparg->result = ISC_R_FAILURE; +#endif + } static void @@ -615,6 +643,7 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) { stats_dumparg_t *dumparg = arg; #ifdef HAVE_LIBXML2 xmlTextWriterPtr writer; + int xmlrc; #endif isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1); @@ -630,30 +659,35 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) { #ifdef HAVE_LIBXML2 writer = dumparg->arg; - xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode")); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf)); + TRY0(xmlTextWriterEndElement(writer)); /* name */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"); - xmlTextWriterWriteFormatString(writer, + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); + TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - val); - xmlTextWriterEndElement(writer); /* counter */ + val)); + TRY0(xmlTextWriterEndElement(writer)); /* counter */ - xmlTextWriterEndElement(writer); /* opcode */ + TRY0(xmlTextWriterEndElement(writer)); /* opcode */ #endif break; } + return; + +#ifdef HAVE_LIBXML2 + error: + dumparg->result = ISC_R_FAILURE; + return; +#endif } #ifdef HAVE_LIBXML2 /* XXXMLG below here sucks. */ -#define TRY(a) do { result = (a); INSIST(result == ISC_R_SUCCESS); } while(0); -#define TRY0(a) do { xmlrc = (a); INSIST(xmlrc >= 0); } while(0); static isc_result_t zone_xmlrender(dns_zone_t *zone, void *arg) { @@ -663,47 +697,55 @@ zone_xmlrender(dns_zone_t *zone, void *arg) { xmlTextWriterPtr writer = arg; isc_stats_t *zonestats; isc_uint64_t nsstat_values[dns_nsstatscounter_max]; + int xmlrc; + isc_result_t result; - xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone")); dns_zone_name(zone, buf, sizeof(buf)); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR buf); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf)); + TRY0(xmlTextWriterEndElement(writer)); rdclass = dns_zone_getclass(zone); dns_rdataclass_format(rdclass, buf, sizeof(buf)); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR buf); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf)); + TRY0(xmlTextWriterEndElement(writer)); - serial = dns_zone_getserial(zone); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial"); - xmlTextWriterWriteFormatString(writer, "%u", serial); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial")); + if (dns_zone_getserial2(zone, &serial) == ISC_R_SUCCESS) + TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial)); + else + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-")); + TRY0(xmlTextWriterEndElement(writer)); zonestats = dns_zone_getrequeststats(zone); if (zonestats != NULL) { - xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"); - dump_counters(zonestats, statsformat_xml, writer, NULL, - nsstats_xmldesc, dns_nsstatscounter_max, - nsstats_index, nsstat_values, - ISC_STATSDUMP_VERBOSE); - xmlTextWriterEndElement(writer); /* counters */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + result = dump_counters(zonestats, statsformat_xml, writer, NULL, + nsstats_xmldesc, dns_nsstatscounter_max, + nsstats_index, nsstat_values, + ISC_STATSDUMP_VERBOSE); + if (result != ISC_R_SUCCESS) + goto error; + TRY0(xmlTextWriterEndElement(writer)); /* counters */ } - xmlTextWriterEndElement(writer); /* zone */ + TRY0(xmlTextWriterEndElement(writer)); /* zone */ return (ISC_R_SUCCESS); + error: + return (ISC_R_FAILURE); } -static void +static isc_result_t generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"]; char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"]; isc_time_t now; - xmlTextWriterPtr writer; - xmlDocPtr doc; + xmlTextWriterPtr writer = NULL; + xmlDocPtr doc = NULL; int xmlrc; dns_view_t *view; stats_dumparg_t dumparg; @@ -712,12 +754,15 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { isc_uint64_t resstat_values[dns_resstatscounter_max]; isc_uint64_t zonestat_values[dns_zonestatscounter_max]; isc_uint64_t sockstat_values[isc_sockstatscounter_max]; + isc_result_t result; isc_time_now(&now); isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime); isc_time_formatISO8601(&now, nowstr, sizeof nowstr); writer = xmlNewTextWriterDoc(&doc, 0); + if (writer == NULL) + goto error; TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL)); TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet", ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\"")); @@ -728,7 +773,7 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "bind")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics")); TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", - ISC_XMLCHAR "2.0")); + ISC_XMLCHAR "2.2")); /* Set common fields for statistics dump */ dumparg.type = statsformat_xml; @@ -741,39 +786,55 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { view = ISC_LIST_HEAD(server->viewlist); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views")); while (view != NULL) { - xmlTextWriterStartElement(writer, ISC_XMLCHAR "view"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view")); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name)); + TRY0(xmlTextWriterEndElement(writer)); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones"); - dns_zt_apply(view->zonetable, ISC_FALSE, zone_xmlrender, - writer); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones")); + result = dns_zt_apply(view->zonetable, ISC_TRUE, zone_xmlrender, + writer); + if (result != ISC_R_SUCCESS) + goto error; + TRY0(xmlTextWriterEndElement(writer)); if (view->resquerystats != NULL) { + dumparg.result = ISC_R_SUCCESS; dns_rdatatypestats_dump(view->resquerystats, rdtypestat_dump, &dumparg, 0); + if (dumparg.result != ISC_R_SUCCESS) + goto error; } if (view->resstats != NULL) { - dump_counters(view->resstats, statsformat_xml, writer, - "resstat", resstats_xmldesc, - dns_resstatscounter_max, resstats_index, - resstat_values, ISC_STATSDUMP_VERBOSE); + result = dump_counters(view->resstats, statsformat_xml, + writer, "resstat", + resstats_xmldesc, + dns_resstatscounter_max, + resstats_index, resstat_values, + ISC_STATSDUMP_VERBOSE); + if (result != ISC_R_SUCCESS) + goto error; } cachestats = dns_db_getrrsetstats(view->cachedb); if (cachestats != NULL) { - xmlTextWriterStartElement(writer, - ISC_XMLCHAR "cache"); + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "cache")); + TRY0(xmlTextWriterWriteAttribute(writer, + ISC_XMLCHAR "name", + ISC_XMLCHAR + view->name)); + dumparg.result = ISC_R_SUCCESS; dns_rdatasetstats_dump(cachestats, rdatasetstats_dump, &dumparg, 0); - xmlTextWriterEndElement(writer); /* cache */ + if (dumparg.result != ISC_R_SUCCESS) + goto error; + TRY0(xmlTextWriterEndElement(writer)); /* cache */ } - xmlTextWriterEndElement(writer); /* view */ + TRY0(xmlTextWriterEndElement(writer)); /* view */ view = ISC_LIST_NEXT(view, link); } @@ -788,44 +849,63 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { TRY0(xmlTextWriterEndElement(writer)); /* taskmgr */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server")); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime); - xmlTextWriterEndElement(writer); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime)); + TRY0(xmlTextWriterEndElement(writer)); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr)); + TRY0(xmlTextWriterEndElement(writer)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "requests")); + dumparg.result = ISC_R_SUCCESS; dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg, 0); - xmlTextWriterEndElement(writer); /* requests */ + if (dumparg.result != ISC_R_SUCCESS) + goto error; + TRY0(xmlTextWriterEndElement(writer)); /* requests */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "queries-in")); + dumparg.result = ISC_R_SUCCESS; dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump, &dumparg, 0); - xmlTextWriterEndElement(writer); /* queries-in */ + if (dumparg.result != ISC_R_SUCCESS) + goto error; + TRY0(xmlTextWriterEndElement(writer)); /* queries-in */ - dump_counters(server->nsstats, statsformat_xml, writer, - "nsstat", nsstats_xmldesc, dns_nsstatscounter_max, - nsstats_index, nsstat_values, ISC_STATSDUMP_VERBOSE); + result = dump_counters(server->nsstats, statsformat_xml, writer, + "nsstat", nsstats_xmldesc, + dns_nsstatscounter_max, + nsstats_index, nsstat_values, + ISC_STATSDUMP_VERBOSE); + if (result != ISC_R_SUCCESS) + goto error; - dump_counters(server->zonestats, statsformat_xml, writer, "zonestat", - zonestats_xmldesc, dns_zonestatscounter_max, - zonestats_index, zonestat_values, ISC_STATSDUMP_VERBOSE); + result = dump_counters(server->zonestats, statsformat_xml, writer, + "zonestat", zonestats_xmldesc, + dns_zonestatscounter_max, zonestats_index, + zonestat_values, ISC_STATSDUMP_VERBOSE); + if (result != ISC_R_SUCCESS) + goto error; /* * Most of the common resolver statistics entries are 0, so we don't * use the verbose dump here. */ - dump_counters(server->resolverstats, statsformat_xml, writer, "resstat", - resstats_xmldesc, dns_resstatscounter_max, resstats_index, - resstat_values, 0); + result = dump_counters(server->resolverstats, statsformat_xml, writer, + "resstat", resstats_xmldesc, + dns_resstatscounter_max, resstats_index, + resstat_values, 0); + if (result != ISC_R_SUCCESS) + goto error; - dump_counters(server->sockstats, statsformat_xml, writer, "sockstat", - sockstats_xmldesc, isc_sockstatscounter_max, - sockstats_index, sockstat_values, ISC_STATSDUMP_VERBOSE); + result = dump_counters(server->sockstats, statsformat_xml, writer, + "sockstat", sockstats_xmldesc, + isc_sockstatscounter_max, sockstats_index, + sockstat_values, ISC_STATSDUMP_VERBOSE); + if (result != ISC_R_SUCCESS) + goto error; - xmlTextWriterEndElement(writer); /* server */ + TRY0(xmlTextWriterEndElement(writer)); /* server */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory")); isc_mem_renderxml(writer); @@ -841,6 +921,14 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 1); xmlFreeDoc(doc); + return (ISC_R_SUCCESS); + + error: + if (writer != NULL) + xmlFreeTextWriter(writer); + if (doc != NULL) + xmlFreeDoc(doc); + return (ISC_R_FAILURE); } static void @@ -859,21 +947,24 @@ render_index(const char *url, const char *querystring, void *arg, unsigned char *msg; int msglen; ns_server_t *server = arg; + isc_result_t result; UNUSED(url); UNUSED(querystring); - generatexml(server, &msglen, &msg); + result = generatexml(server, &msglen, &msg); - *retcode = 200; - *retmsg = "OK"; - *mimetype = "text/xml"; - isc_buffer_reinit(b, msg, msglen); - isc_buffer_add(b, msglen); - *freecb = wrap_xmlfree; - *freecb_args = NULL; + if (result == ISC_R_SUCCESS) { + *retcode = 200; + *retmsg = "OK"; + *mimetype = "text/xml"; + isc_buffer_reinit(b, msg, msglen); + isc_buffer_add(b, msglen); + *freecb = wrap_xmlfree; + *freecb_args = NULL; + } - return (ISC_R_SUCCESS); + return (result); } #endif /* HAVE_LIBXML2 */ @@ -1274,20 +1365,20 @@ ns_stats_dump(ns_server_t *server, FILE *fp) { } fprintf(fp, "++ Name Server Statistics ++\n"); - dump_counters(server->nsstats, statsformat_file, fp, NULL, - nsstats_desc, dns_nsstatscounter_max, nsstats_index, - nsstat_values, 0); + (void) dump_counters(server->nsstats, statsformat_file, fp, NULL, + nsstats_desc, dns_nsstatscounter_max, + nsstats_index, nsstat_values, 0); fprintf(fp, "++ Zone Maintenance Statistics ++\n"); - dump_counters(server->zonestats, statsformat_file, fp, NULL, - zonestats_desc, dns_zonestatscounter_max, - zonestats_index, zonestat_values, 0); + (void) dump_counters(server->zonestats, statsformat_file, fp, NULL, + zonestats_desc, dns_zonestatscounter_max, + zonestats_index, zonestat_values, 0); fprintf(fp, "++ Resolver Statistics ++\n"); fprintf(fp, "[Common]\n"); - dump_counters(server->resolverstats, statsformat_file, fp, NULL, - resstats_desc, dns_resstatscounter_max, resstats_index, - resstat_values, 0); + (void) dump_counters(server->resolverstats, statsformat_file, fp, NULL, + resstats_desc, dns_resstatscounter_max, + resstats_index, resstat_values, 0); for (view = ISC_LIST_HEAD(server->viewlist); view != NULL; view = ISC_LIST_NEXT(view, link)) { @@ -1297,9 +1388,9 @@ ns_stats_dump(ns_server_t *server, FILE *fp) { fprintf(fp, "[View: default]\n"); else fprintf(fp, "[View: %s]\n", view->name); - dump_counters(view->resstats, statsformat_file, fp, NULL, - resstats_desc, dns_resstatscounter_max, - resstats_index, resstat_values, 0); + (void) dump_counters(view->resstats, statsformat_file, fp, NULL, + resstats_desc, dns_resstatscounter_max, + resstats_index, resstat_values, 0); } fprintf(fp, "++ Cache DB RRsets ++\n"); @@ -1320,9 +1411,9 @@ ns_stats_dump(ns_server_t *server, FILE *fp) { } fprintf(fp, "++ Socket I/O Statistics ++\n"); - dump_counters(server->sockstats, statsformat_file, fp, NULL, - sockstats_desc, isc_sockstatscounter_max, sockstats_index, - sockstat_values, 0); + (void) dump_counters(server->sockstats, statsformat_file, fp, NULL, + sockstats_desc, isc_sockstatscounter_max, + sockstats_index, sockstat_values, 0); fprintf(fp, "++ Per Zone Query Statistics ++\n"); zone = NULL; @@ -1343,9 +1434,10 @@ ns_stats_dump(ns_server_t *server, FILE *fp) { fprintf(fp, " (view: %s)", view->name); fprintf(fp, "]\n"); - dump_counters(zonestats, statsformat_file, fp, NULL, - nsstats_desc, dns_nsstatscounter_max, - nsstats_index, nsstat_values, 0); + (void) dump_counters(zonestats, statsformat_file, fp, + NULL, nsstats_desc, + dns_nsstatscounter_max, + nsstats_index, nsstat_values, 0); } } diff --git a/contrib/bind9/bin/named/update.c b/contrib/bind9/bin/named/update.c index b0a556d5cc4..74a192ad07b 100644 --- a/contrib/bind9/bin/named/update.c +++ b/contrib/bind9/bin/named/update.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: update.c,v 1.151.12.5.12.1 2009/07/28 14:18:08 marka Exp $ */ +/* $Id: update.c,v 1.151.12.9 2009/12/30 04:02:56 marka Exp $ */ #include @@ -3031,7 +3031,7 @@ check_dnssec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, } else { CHECK(get_iterations(db, ver, &iterations)); CHECK(dns_nsec3_maxiterations(db, ver, client->mctx, &max)); - if (iterations > max) { + if (max != 0 && iterations > max) { flag = ISC_TRUE; update_log(client, zone, ISC_LOG_WARNING, "too many NSEC3 iterations (%u) for " @@ -3157,6 +3157,24 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, &newtuple)); CHECK(do_one_tuple(&newtuple, db, ver, diff)); } + + /* + * Remove any existing CREATE request to add an + * otherwise indentical chain with a reversed + * OPTOUT state. + */ + buf[1] ^= DNS_NSEC3FLAG_OPTOUT; + CHECK(rr_exists(db, ver, name, &rdata, &flag)); + + if (flag) { + CHECK(dns_difftuple_create(diff->mctx, + DNS_DIFFOP_DEL, + name, tuple->ttl, + &rdata, + &newtuple)); + CHECK(do_one_tuple(&newtuple, db, ver, diff)); + } + /* * Remove the temporary add record. */ @@ -4140,9 +4158,6 @@ update_action(isc_task_t *task, isc_event_t *event) { goto common; failure: - if (result == DNS_R_REFUSED) - inc_stats(zone, dns_nsstatscounter_updaterej); - /* * The reason for failure should have been logged at this point. */ diff --git a/contrib/bind9/bin/nsupdate/nsupdate.1 b/contrib/bind9/bin/nsupdate/nsupdate.1 index b0688a3ac26..83fd7d78da8 100644 --- a/contrib/bind9/bin/nsupdate/nsupdate.1 +++ b/contrib/bind9/bin/nsupdate/nsupdate.1 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: nsupdate.1,v 1.3.48.2 2009/03/10 01:54:11 tbox Exp $ +.\" $Id: nsupdate.1,v 1.3.48.3 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/nsupdate/nsupdate.html b/contrib/bind9/bin/nsupdate/nsupdate.html index dab7f9029cf..9f45171a4fe 100644 --- a/contrib/bind9/bin/nsupdate/nsupdate.html +++ b/contrib/bind9/bin/nsupdate/nsupdate.html @@ -2,7 +2,7 @@ - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000-2003 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/bin/rndc/rndc-confgen.8 b/contrib/bind9/bin/rndc/rndc-confgen.8 index 440870a54ed..d37c00adcd2 100644 --- a/contrib/bind9/bin/rndc/rndc-confgen.8 +++ b/contrib/bind9/bin/rndc/rndc-confgen.8 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2001, 2003 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: rndc-confgen.8,v 1.20 2007/01/30 00:24:59 marka Exp $ +.\" $Id: rndc-confgen.8,v 1.20.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/rndc/rndc-confgen.html b/contrib/bind9/bin/rndc/rndc-confgen.html index 4be87afb9fa..41debdcc910 100644 --- a/contrib/bind9/bin/rndc/rndc-confgen.html +++ b/contrib/bind9/bin/rndc/rndc-confgen.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2001, 2003 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/bin/rndc/rndc.8 b/contrib/bind9/bin/rndc/rndc.8 index 7f0dea110c7..8ab0df2c8f0 100644 --- a/contrib/bind9/bin/rndc/rndc.8 +++ b/contrib/bind9/bin/rndc/rndc.8 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: rndc.8,v 1.42 2007/12/14 22:37:22 marka Exp $ +.\" $Id: rndc.8,v 1.42.214.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/rndc/rndc.conf.5 b/contrib/bind9/bin/rndc/rndc.conf.5 index 9e9bad41f36..edb3a360a81 100644 --- a/contrib/bind9/bin/rndc/rndc.conf.5 +++ b/contrib/bind9/bin/rndc/rndc.conf.5 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: rndc.conf.5,v 1.38 2007/05/09 13:35:57 marka Exp $ +.\" $Id: rndc.conf.5,v 1.38.366.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/bin/rndc/rndc.conf.html b/contrib/bind9/bin/rndc/rndc.conf.html index 144cd1c91d8..6fbaaa2f7cc 100644 --- a/contrib/bind9/bin/rndc/rndc.conf.html +++ b/contrib/bind9/bin/rndc/rndc.conf.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/bin/rndc/rndc.html b/contrib/bind9/bin/rndc/rndc.html index a8d11c47bd1..52c862a9747 100644 --- a/contrib/bind9/bin/rndc/rndc.html +++ b/contrib/bind9/bin/rndc/rndc.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/config.h.in b/contrib/bind9/config.h.in index 97b13c4a5ad..28ace46a71b 100644 --- a/contrib/bind9/config.h.in +++ b/contrib/bind9/config.h.in @@ -16,7 +16,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: config.h.in,v 1.106.40.6 2009/03/13 05:35:43 marka Exp $ */ +/* $Id: config.h.in,v 1.106.40.11 2010/01/15 19:38:52 each Exp $ */ /*! \file */ @@ -144,6 +144,9 @@ int sigwait(const unsigned int *set, int *sig); /* Define if threads need PTHREAD_SCOPE_SYSTEM */ #undef NEED_PTHREAD_SCOPE_SYSTEM +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + /* Define if recvmsg() does not meet all of the BSD socket API specifications. */ #undef BROKEN_RECVMSG @@ -163,6 +166,12 @@ int sigwait(const unsigned int *set, int *sig); /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the `EVP_sha256' function. */ +#undef HAVE_EVP_SHA256 + +/* Define to 1 if you have the `EVP_sha512' function. */ +#undef HAVE_EVP_SHA512 + /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H @@ -293,6 +302,9 @@ int sigwait(const unsigned int *set, int *sig); /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME +/* Define to the home page for this package. */ +#undef PACKAGE_URL + /* Define to the version of this package. */ #undef PACKAGE_VERSION @@ -314,11 +326,15 @@ int sigwait(const unsigned int *set, int *sig); #undef WITH_IDN /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ -#if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -#elif ! defined __LITTLE_ENDIAN__ -# undef WORDS_BIGENDIAN + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif #endif /* Define to empty if `const' does not conform to ANSI C. */ diff --git a/contrib/bind9/configure.in b/contrib/bind9/configure.in index 6ebdfddcca2..76e1eb33ea4 100644 --- a/contrib/bind9/configure.in +++ b/contrib/bind9/configure.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl esyscmd([sed "s/^/# /" COPYRIGHT])dnl AC_DIVERT_POP()dnl -AC_REVISION($Revision: 1.457.26.9 $) +AC_REVISION($Revision: 1.457.26.16 $) AC_INIT(lib/dns/name.c) AC_PREREQ(2.59) @@ -28,6 +28,18 @@ AC_CONFIG_HEADER(config.h) AC_CANONICAL_HOST AC_PROG_MAKE_SET + +# +# GNU libtool support +# +case $build_os in +sunos*) + # Just set the maximum command line length for sunos as it otherwise + # takes a exceptionally long time to work it out. Required for libtool. + lt_cv_sys_max_cmd_len=4096; + ;; +esac + AC_PROG_LIBTOOL AC_PROG_INSTALL AC_PROG_LN_S @@ -466,7 +478,7 @@ AC_C_BIGENDIAN OPENSSL_WARNING= AC_MSG_CHECKING(for OpenSSL library) AC_ARG_WITH(openssl, -[ --with-openssl[=PATH] Build with OpenSSL [yes|no|path]. +[ --with-openssl[=PATH] Build with OpenSSL [yes|no|path]. (Required for DNSSEC)], use_openssl="$withval", use_openssl="auto") @@ -491,7 +503,9 @@ case "$use_openssl" in auto) DST_OPENSSL_INC="" USE_OPENSSL="" - AC_MSG_RESULT(not found) + AC_MSG_ERROR( +[OpenSSL was not found in any of $openssldirs; use --with-openssl=/path +If you don't want OpenSSL, use --without-openssl]) ;; *) if test "$use_openssl" = "yes" @@ -630,8 +644,10 @@ esac else AC_MSG_RESULT(no) fi + AC_CHECK_FUNCS(EVP_sha256 EVP_sha512) CFLAGS="$saved_cflags" LIBS="$saved_libs" + ;; esac @@ -652,7 +668,7 @@ DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS" AC_MSG_CHECKING(for PKCS11 support) AC_ARG_WITH(pkcs11, -[ --with-pkcs11 Build with PKCS11 support], +[ --with-pkcs11 Build with PKCS11 support], use_pkcs11="yes", use_pkcs11="no") case "$use_pkcs11" in @@ -670,7 +686,7 @@ AC_SUBST(USE_PKCS11) AC_MSG_CHECKING(for GSSAPI library) AC_ARG_WITH(gssapi, -[ --with-gssapi=PATH Specify path for system-supplied GSSAPI], +[ --with-gssapi=PATH Specify path for system-supplied GSSAPI], use_gssapi="$withval", use_gssapi="no") gssapidirs="/usr/local /usr/pkg /usr/kerberos /usr" @@ -824,7 +840,7 @@ AC_SUBST(DNS_CRYPTO_LIBS) # AC_MSG_CHECKING(for random device) AC_ARG_WITH(randomdev, -[ --with-randomdev=PATH Specify path for random device], +[ --with-randomdev=PATH Specify path for random device], use_randomdev="$withval", use_randomdev="unspec") case "$use_randomdev" in @@ -997,7 +1013,7 @@ AC_SUBST(ISC_THREAD_DIR) # AC_MSG_CHECKING(for libxml2 library) AC_ARG_WITH(libxml2, -[ --with-libxml2[=PATH] Build with libxml2 library [yes|no|path]], +[ --with-libxml2[=PATH] Build with libxml2 library [yes|no|path]], use_libxml2="$withval", use_libxml2="auto") case "$use_libxml2" in @@ -1191,7 +1207,7 @@ esac # AC_MSG_CHECKING(whether to use purify) AC_ARG_WITH(purify, - [ --with-purify[=PATH] use Rational purify], + [ --with-purify[=PATH] use Rational purify], use_purify="$withval", use_purify="no") case "$use_purify" in @@ -1228,19 +1244,9 @@ esac AC_SUBST(PURIFY) -# -# GNU libtool support -# -case $build_os in -sunos*) - # Just set the maximum command line length for sunos as it otherwise - # takes a exceptionally long time to work it out. Required for libtool. - lt_cv_sys_max_cmd_len=4096; - ;; -esac AC_ARG_WITH(libtool, - [ --with-libtool use GNU libtool (following indented options supported)], + [ --with-libtool use GNU libtool], use_libtool="$withval", use_libtool="no") case $use_libtool in @@ -1299,7 +1305,7 @@ AC_SUBST(LIBTOOL_IN_MAIN) # IPv6 # AC_ARG_ENABLE(ipv6, - [ --enable-ipv6 use IPv6 [default=autodetect]]) + [ --enable-ipv6 use IPv6 [default=autodetect]]) case "$enable_ipv6" in yes|''|autodetect) @@ -1330,7 +1336,7 @@ AC_TRY_COMPILE([ # AC_MSG_CHECKING(for Kame IPv6 support) AC_ARG_WITH(kame, - [ --with-kame[=PATH] use Kame IPv6 [default path /usr/local/v6]], + [ --with-kame[=PATH] use Kame IPv6 [default path /usr/local/v6]], use_kame="$withval", use_kame="no") case "$use_kame" in @@ -1780,7 +1786,7 @@ AC_SUBST(ISC_LWRES_GETADDRINFOPROTO) AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO) AC_ARG_ENABLE(getifaddrs, -[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no]].], +[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no]].], want_getifaddrs="$enableval", want_getifaddrs="yes") # @@ -1902,7 +1908,7 @@ AC_SUBST(ISC_EXTRA_SRCS) # Use our own SPNEGO implementation? # AC_ARG_ENABLE(isc-spnego, - [ --disable-isc-spnego use SPNEGO from GSSAPI library]) + [ --disable-isc-spnego use SPNEGO from GSSAPI library]) if test -n "$USE_GSSAPI" then @@ -1967,7 +1973,7 @@ AC_SUBST(LWRES_PLATFORM_QUADFORMAT) # Note it is very recommended to *not* disable chroot(), # this is only because chroot() was made obsolete by Posix. AC_ARG_ENABLE(chroot, - [ --disable-chroot disable chroot]) + [ --disable-chroot disable chroot]) case "$enable_chroot" in yes|'') AC_CHECK_FUNCS(chroot) @@ -1976,7 +1982,7 @@ case "$enable_chroot" in ;; esac AC_ARG_ENABLE(linux-caps, - [ --disable-linux-caps disable linux capabilities]) + [ --disable-linux-caps disable linux capabilities]) case "$enable_linux_caps" in yes|'') AC_CHECK_HEADERS(linux/capability.h sys/capability.h) @@ -2215,13 +2221,43 @@ AC_CHECK_FUNCS(nanosleep) # Machine architecture dependent features # AC_ARG_ENABLE(atomic, - [ --enable-atomic enable machine specific atomic operations - [[default=autodetect]]], + [ --enable-atomic enable machine specific atomic operations + [[default=autodetect]]], enable_atomic="$enableval", enable_atomic="autodetect") case "$enable_atomic" in yes|''|autodetect) - use_atomic=yes + case "$host" in + powerpc-ibm-aix*) + if test "X$GCC" = "Xyes"; then + AC_MSG_CHECKING([if asm("isc"); works]) + AC_TRY_COMPILE(,[ + main() { asm("ics"); exit(0); } + ], + [AC_MSG_RESULT(yes) + use_atomic=yes], + [ + saved_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wa,-many" + AC_TRY_RUN([ + main() { asm("ics"); exit(0); } + ], + [AC_MSG_RESULT([yes, required -Wa,-many]) + use_atomic=yes], + [AC_MSG_RESULT([no, use_atomic disabled]) + CFLAGS="$saved_cflags" + use_atomic=no], + [AC_MSG_RESULT([cross compile, assume yes]) + CFLAGS="$saved_cflags" + use_atomic=yes]) + ] + ) + fi + ;; + *) + use_atomic=yes + ;; + esac ;; no) use_atomic=no @@ -2248,8 +2284,16 @@ main() { [arch=x86_32]) ;; x86_64-*|amd64-*) - have_xaddq=yes - arch=x86_64 +AC_TRY_RUN([ +main() { + exit((sizeof(void *) == 8) ? 0 : 1); +} +], + [arch=x86_64 + have_xaddq=yes], + [arch=x86_32], + [arch=x86_64 + have_xaddq=yes]) ;; alpha*-*) arch=alpha @@ -2354,9 +2398,9 @@ else fi if test "$have_xaddq" = "yes"; then - ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1" + ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1" else - ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ" + ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ" fi AC_SUBST(ISC_PLATFORM_HAVEXADD) @@ -2376,14 +2420,14 @@ AC_SUBST(ISC_ARCH_DIR) # Activate "rrset-order fixed" or not? # AC_ARG_ENABLE(fixed-rrset, - [ --enable-fixed-rrset enable fixed rrset ordering - [[default=no]]], + [ --enable-fixed-rrset enable fixed rrset ordering + [[default=no]]], enable_fixed="$enableval", enable_fixed="no") case "$enable_fixed" in yes) AC_DEFINE(DNS_RDATASET_FIXED, 1, - [Define to enable "rrset-order fixed" syntax.]) + [Define to enable "rrset-order fixed" syntax.]) ;; no) ;; @@ -2503,7 +2547,7 @@ AC_SUBST($1) # AC_MSG_CHECKING(for Docbook-XSL path) AC_ARG_WITH(docbook-xsl, -[ --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets], +[ --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets], docbook_path="$withval", docbook_path="auto") case "$docbook_path" in auto) @@ -2571,7 +2615,7 @@ AC_SUBST(XSLT_DB2LATEX_ADMONITIONS) # IDN support # AC_ARG_WITH(idn, - [ --with-idn[=MPREFIX] enable IDN support using idnkit [default PREFIX]], + [ --with-idn[=MPREFIX] enable IDN support using idnkit [default PREFIX]], use_idn="$withval", use_idn="no") case "$use_idn" in yes) @@ -2591,7 +2635,7 @@ esac iconvinc= iconvlib= AC_ARG_WITH(libiconv, - [ --with-libiconv[=IPREFIX] GNU libiconv are in IPREFIX [default PREFIX]], + [ --with-libiconv[=IPREFIX] GNU libiconv are in IPREFIX [default PREFIX]], use_libiconv="$withval", use_libiconv="no") case "$use_libiconv" in yes) @@ -2610,7 +2654,7 @@ no) esac AC_ARG_WITH(iconv, - [ --with-iconv[=LIBSPEC] specify iconv library [default -liconv]], + [ --with-iconv[=LIBSPEC] specify iconv library [default -liconv]], iconvlib="$withval") case "$iconvlib" in no) @@ -2622,7 +2666,7 @@ yes) esac AC_ARG_WITH(idnlib, - [ --with-idnlib=ARG specify libidnkit], + [ --with-idnlib=ARG specify libidnkit], idnlib="$withval", idnlib="no") if test "$idnlib" = yes; then AC_MSG_ERROR([You must specify ARG for --with-idnlib.]) @@ -2678,7 +2722,7 @@ AC_SUBST_FILE(BIND9_MAKE_RULES) BIND9_MAKE_RULES=$BIND9_TOP_BUILDDIR/make/rules . $srcdir/version -BIND9_VERSION="VERSION=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER}" +BIND9_VERSION="VERSION=${MAJORVER}.${MINORVER}${PATCHVER:+.}${PATCHVER}${RELEASETYPE}${RELEASEVER}" AC_SUBST(BIND9_VERSION) if test -z "$ac_configure_args"; then @@ -2964,6 +3008,12 @@ AC_CONFIG_FILES([ AC_OUTPUT +if test "X$USE_OPENSSL" = "X"; then +cat << \EOF +BIND is being built without OpenSSL. This means it will not have DNSSEC support. +EOF +fi + if test "X$OPENSSL_WARNING" != "X"; then cat << \EOF WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING diff --git a/contrib/bind9/doc/arm/Bv9ARM-book.xml b/contrib/bind9/doc/arm/Bv9ARM-book.xml index 0875e57ff09..29331d98579 100644 --- a/contrib/bind9/doc/arm/Bv9ARM-book.xml +++ b/contrib/bind9/doc/arm/Bv9ARM-book.xml @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []> - + BIND 9 Administrator Reference Manual @@ -30,6 +30,7 @@ 2007 2008 2009 + 2010 Internet Systems Consortium, Inc. ("ISC")
    @@ -1679,6 +1680,11 @@ controls { each dynamic update, because that would be too slow when a large zone is updated frequently. Instead, the dump is delayed by up to 15 minutes, allowing additional updates to take place. + During the dump process, transient files will be created + with the extensions .jnw and + .jbk; under ordinary circumstances, these + will be removed when the dump is complete, and can be safely + ignored. @@ -2053,17 +2059,16 @@ nameserver 172.16.72.4 Automatic Generation - The following command will generate a 128-bit (16 byte) HMAC-MD5 + The following command will generate a 128-bit (16 byte) HMAC-SHA256 key as described above. Longer keys are better, but shorter keys - are easier to read. Note that the maximum key length is 512 bits; - keys longer than that will be digested with MD5 to produce a - 128-bit key. + are easier to read. Note that the maximum key length is the digest + length, here 256 bits. - dnssec-keygen -a hmac-md5 -b 128 -n HOST host1-host2. + dnssec-keygen -a hmac-sha256 -b 128 -n HOST host1-host2. - The key is in the file Khost1-host2.+157+00000.private. + The key is in the file Khost1-host2.+163+00000.private. Nothing directly uses this file, but the base-64 encoded string following "Key:" can be extracted from the file and used as a shared secret: @@ -2105,18 +2110,16 @@ nameserver 172.16.72.4 key host1-host2. { - algorithm hmac-md5; + algorithm hmac-sha256; secret "La/E5CjG9O+os1jq0a2jdA=="; }; - The algorithm, hmac-md5, is the only one supported by BIND. The secret is the one generated above. Since this is a secret, it - is recommended that either named.conf be non-world - readable, or the key directive be added to a non-world readable - file that is included by - named.conf. + is recommended that either named.conf be + non-world readable, or the key directive be added to a non-world + readable file that is included by named.conf. At this point, the key is recognized. This means that if the @@ -2445,14 +2448,17 @@ allow-update { key host1-host2. ;}; To enable named to respond appropriately to DNS requests from DNSSEC aware clients, dnssec-enable must be set to yes. + (This is the default setting.) To enable named to validate answers from - other servers both dnssec-enable and - dnssec-validation must be set and some - trusted-keys must be configured - into named.conf. + other servers, the dnssec-enable and + dnssec-validation options must both be + set to yes (the default setting in BIND 9.5 + and later), and at least one trust anchor must be configured + with a trusted-keys statement in + named.conf. @@ -2531,6 +2537,41 @@ options { the root key is not valid. + + When DNSSEC validation is enabled and properly configured, + the resolver will reject any answers from signed, secure zones + which fail to validate, and will return SERVFAIL to the client. + + + + Responses may fail to validate for any of several reasons, + including missing, expired, or invalid signatures, a key which + does not match the DS RRset in the parent zone, or an insecure + response from a zone which, according to its parent, should have + been secure. + + + + + When the validator receives a response from an unsigned zone + that has a signed parent, it must confirm with the parent + that the zone was intentionally left unsigned. It does + this by verifying, via signed and validated NSEC/NSEC3 records, + that the parent zone contains no DS records for the child. + + + If the validator can prove that the zone + is insecure, then the response is accepted. However, if it + cannot, then it must assume an insecure response to be a + forgery; it rejects the response and logs an error. + + + The logged error reads "insecurity proof failed" and + "got insecure response; parent indicates it should be secure". + (Prior to BIND 9.7, the logged error was "not insecure". + This referred to the zone, not the response.) + + @@ -2539,10 +2580,9 @@ options { BIND 9 fully supports all currently - defined forms of IPv6 - name to address and address to name lookups. It will also use - IPv6 addresses to make queries when running on an IPv6 capable - system. + defined forms of IPv6 name to address and address to name + lookups. It will also use IPv6 addresses to make queries when + running on an IPv6 capable system. @@ -4324,8 +4364,7 @@ category notify { null; }; Lame servers. These are misconfigurations in remote servers, discovered by BIND 9 when trying to - query - those servers during resolution. + query those servers during resolution. @@ -4785,7 +4824,7 @@ category notify { null; }; port ( ip_port | * ) ) ; use-queryport-pool yes_or_no; queryport-pool-ports number; - queryport-pool-interval number; + queryport-pool-updateinterval number; max-transfer-time-in number; max-transfer-time-out number; max-transfer-idle-in number; @@ -4826,7 +4865,7 @@ category notify { null; }; lame-ttl number; max-ncache-ttl number; max-cache-ttl number; - sig-validity-interval number ; + sig-validity-interval number number ; sig-signing-nodes number ; sig-signing-signatures number ; sig-signing-type number ; @@ -4909,11 +4948,12 @@ category notify { null; }; When performing dynamic update of secure zones, the - directory where the public and private key files should be - found, - if different than the current working directory. The - directory specified - must be an absolute path. + directory where the public and private DNSSEC key files + should be found, if different than the current working + directory. The directory specified must be an absolute + path. (Note that this option has no effect on the paths + for files containing non-DNSSEC keys such as the + rndc.key. @@ -5874,13 +5914,15 @@ options { If yes, then an IPv4-mapped IPv6 address will match any address match list entries that match the corresponding IPv4 address. - Enabling this option is sometimes useful on IPv6-enabled - Linux - systems, to work around a kernel quirk that causes IPv4 - TCP connections such as zone transfers to be accepted - on an IPv6 socket using mapped addresses, causing - address match lists designed for IPv4 to fail to match. - The use of this option for any other purpose is discouraged. + + + This option was introduced to work around a kernel quirk + in some operating systems that causes IPv4 TCP + connections, such as zone transfers, to be accepted on an + IPv6 socket using mapped addresses. This caused address + match lists designed for IPv4 to fail to match. However, + named now solves this problem + internally. The use of this option is discouraged. @@ -7663,6 +7705,13 @@ avoid-v6-udp-ports { 40000; range 50000 60000; }; 1800 (30 minutes). + + Lame-ttl also controls the amount of time DNSSEC + validation failures are cached. There is a minimum + of 30 seconds applied to bad cache entries if the + lame-ttl is set to less than 30 seconds. + + @@ -7919,7 +7968,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; }; The delay, in seconds, between sending sets of notify - messages for a zone. The default is zero. + messages for a zone. The default is five (5) seconds. @@ -8271,7 +8320,7 @@ XXX: end of RFC1918 addresses #defined out --> query-source-v6 address ( ip_addr | * ) port ( ip_port | * ) ; use-queryport-pool yes_or_no; queryport-pool-ports number; - queryport-pool-interval number; + queryport-pool-updateinterval number; }; @@ -8751,7 +8800,7 @@ view "external" { notify-source (ip4_addr | *) port ip_port ; notify-source-v6 (ip6_addr | *) port ip_port ; zone-statistics yes_or_no ; - sig-validity-interval number ; + sig-validity-interval number number ; sig-signing-nodes number ; sig-signing-signatures number ; sig-signing-type number ; @@ -11205,6 +11254,16 @@ zone zone_name class$ORIGIN, $INCLUDE, and $TTL. + + The <command>@</command> (at-sign) + + When used in the label (or name) field, the asperand or + at-sign (@) symbol represents the current origin. + At the start of the zone file, it is the + <zone_name> (followed by + trailing dot). + + The <command>$ORIGIN</command> Directive @@ -11216,7 +11275,8 @@ zone zone_name class$ORIGIN - <zone-name>. + <zone_name>. + (followed by trailing dot). The current $ORIGIN is appended to the domain specified in the $ORIGIN argument if it is not absolute. diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch01.html b/contrib/bind9/doc/arm/Bv9ARM.ch01.html index 320a8675837..ea561e6c36a 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch01.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch01.html @@ -1,8 +1,8 @@ - + @@ -45,17 +45,17 @@ @@ -71,7 +71,7 @@

    -Scope of Document

    +Scope of Document

    The Berkeley Internet Name Domain (BIND) implements a @@ -87,7 +87,7 @@

    -Organization of This Document

    +Organization of This Document

    In this document, Chapter 1 introduces the basic DNS and BIND concepts. Chapter 2 @@ -116,7 +116,7 @@

    -Conventions Used in This Document

    +Conventions Used in This Document

    In this document, we use the following general typographic conventions: @@ -243,7 +243,7 @@

    -The Domain Name System (DNS)

    +The Domain Name System (DNS)

    The purpose of this document is to explain the installation and upkeep of the BIND (Berkeley Internet @@ -253,7 +253,7 @@

    -DNS Fundamentals

    +DNS Fundamentals

    The Domain Name System (DNS) is a hierarchical, distributed database. It stores information for mapping Internet host names to @@ -275,7 +275,7 @@

    -Domains and Domain Names

    +Domains and Domain Names

    The data stored in the DNS is identified by domain names that are organized as a tree according to organizational or administrative boundaries. Each node of the tree, @@ -321,7 +321,7 @@

    -Zones

    +Zones

    To properly operate a name server, it is important to understand the difference between a zone @@ -374,7 +374,7 @@

    -Authoritative Name Servers

    +Authoritative Name Servers

    Each zone is served by at least one authoritative name server, @@ -391,7 +391,7 @@

    -The Primary Master

    +The Primary Master

    The authoritative server where the master copy of the zone data is maintained is called the @@ -411,7 +411,7 @@

    -Slave Servers

    +Slave Servers

    The other authoritative servers, the slave servers (also known as secondary servers) @@ -427,7 +427,7 @@

    -Stealth Servers

    +Stealth Servers

    Usually all of the zone's authoritative servers are listed in NS records in the parent zone. These NS records constitute @@ -462,7 +462,7 @@

    -Caching Name Servers

    +Caching Name Servers

    The resolver libraries provided by most operating systems are stub resolvers, meaning that they are not @@ -489,7 +489,7 @@

    -Forwarding

    +Forwarding

    Even a caching name server does not necessarily perform the complete recursive lookup itself. Instead, it can @@ -516,7 +516,7 @@

    -Name Servers in Multiple Roles

    +Name Servers in Multiple Roles

    The BIND name server can simultaneously act as diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch02.html b/contrib/bind9/doc/arm/Bv9ARM.ch02.html index 831e7a12407..b279c6754e7 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch02.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch02.html @@ -1,8 +1,8 @@ - + @@ -45,16 +45,16 @@

    -Hardware requirements

    +Hardware requirements

    DNS hardware requirements have traditionally been quite modest. @@ -73,7 +73,7 @@

    -CPU Requirements

    +CPU Requirements

    CPU requirements for BIND 9 range from i486-class machines @@ -84,7 +84,7 @@

    -Memory Requirements

    +Memory Requirements

    The memory of the server has to be large enough to fit the cache and zones loaded off disk. The max-cache-size @@ -107,7 +107,7 @@

    -Name Server Intensive Environment Issues

    +Name Server Intensive Environment Issues

    For name server intensive environments, there are two alternative configurations that may be used. The first is where clients and @@ -124,7 +124,7 @@

    -Supported Operating Systems

    +Supported Operating Systems

    ISC BIND 9 compiles and runs on a large number diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch03.html b/contrib/bind9/doc/arm/Bv9ARM.ch03.html index 9964823153f..59d7e73d60b 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch03.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch03.html @@ -1,8 +1,8 @@ - + @@ -47,14 +47,14 @@

    Sample Configurations
    -
    A Caching-only Name Server
    -
    An Authoritative-only Name Server
    +
    A Caching-only Name Server
    +
    An Authoritative-only Name Server
    -
    Load Balancing
    -
    Name Server Operations
    +
    Load Balancing
    +
    Name Server Operations
    -
    Tools for Use With the Name Server Daemon
    -
    Signals
    +
    Tools for Use With the Name Server Daemon
    +
    Signals
    @@ -68,7 +68,7 @@ Sample Configurations

    -A Caching-only Name Server

    +A Caching-only Name Server

    The following sample configuration is appropriate for a caching-only name server for use by clients internal to a corporation. All @@ -95,7 +95,7 @@ zone "0.0.127.in-addr.arpa" {

    -An Authoritative-only Name Server

    +An Authoritative-only Name Server

    This sample configuration is for an authoritative-only server that is the master server for "example.com" @@ -137,7 +137,7 @@ zone "eng.example.com" {

    -Load Balancing

    +Load Balancing

    A primitive form of load balancing can be achieved in the DNS by using multiple records @@ -280,10 +280,10 @@ zone "eng.example.com" {

    -Name Server Operations

    +Name Server Operations

    -Tools for Use With the Name Server Daemon

    +Tools for Use With the Name Server Daemon

    This section describes several indispensable diagnostic, administrative and monitoring tools available to the system @@ -749,7 +749,7 @@ controls {

    -Signals

    +Signals

    Certain UNIX signals cause the name server to take specific actions, as described in the following table. These signals can diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch04.html b/contrib/bind9/doc/arm/Bv9ARM.ch04.html index 123098e1ecc..2be5791f518 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch04.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch04.html @@ -1,8 +1,8 @@ - + @@ -49,29 +49,29 @@

    Dynamic Update
    The journal file
    Incremental Zone Transfers (IXFR)
    -
    Split DNS
    -
    Example split DNS setup
    +
    Split DNS
    +
    Example split DNS setup
    TSIG
    -
    Generate Shared Keys for Each Pair of Hosts
    -
    Copying the Shared Secret to Both Machines
    -
    Informing the Servers of the Key's Existence
    -
    Instructing the Server to Use the Key
    -
    TSIG Key Based Access Control
    -
    Errors
    +
    Generate Shared Keys for Each Pair of Hosts
    +
    Copying the Shared Secret to Both Machines
    +
    Informing the Servers of the Key's Existence
    +
    Instructing the Server to Use the Key
    +
    TSIG Key Based Access Control
    +
    Errors
    -
    TKEY
    -
    SIG(0)
    +
    TKEY
    +
    SIG(0)
    DNSSEC
    -
    Generating Keys
    -
    Signing the Zone
    -
    Configuring Servers
    +
    Generating Keys
    +
    Signing the Zone
    +
    Configuring Servers
    -
    IPv6 Support in BIND 9
    +
    IPv6 Support in BIND 9
    -
    Address Lookups Using AAAA Records
    -
    Address to Name Lookups Using Nibble Format
    +
    Address Lookups Using AAAA Records
    +
    Address to Name Lookups Using Nibble Format
    @@ -149,6 +149,11 @@ each dynamic update, because that would be too slow when a large zone is updated frequently. Instead, the dump is delayed by up to 15 minutes, allowing additional updates to take place. + During the dump process, transient files will be created + with the extensions .jnw and + .jbk; under ordinary circumstances, these + will be removed when the dump is complete, and can be safely + ignored.

    When a server is restarted after a shutdown or crash, it will replay @@ -210,7 +215,7 @@

    -Split DNS

    +Split DNS

    Setting up different views, or visibility, of the DNS space to internal and external resolvers is usually referred to as a @@ -240,7 +245,7 @@

    -Example split DNS setup

    +Example split DNS setup

    Let's say a company named Example, Inc. (example.com) @@ -486,7 +491,7 @@ nameserver 172.16.72.4

    -Generate Shared Keys for Each Pair of Hosts

    +Generate Shared Keys for Each Pair of Hosts

    A shared secret is generated to be shared between host1 and host2. An arbitrary key name is chosen: "host1-host2.". The key name must @@ -494,19 +499,18 @@ nameserver 172.16.72.4

    -Automatic Generation

    +Automatic Generation

    - The following command will generate a 128-bit (16 byte) HMAC-MD5 + The following command will generate a 128-bit (16 byte) HMAC-SHA256 key as described above. Longer keys are better, but shorter keys - are easier to read. Note that the maximum key length is 512 bits; - keys longer than that will be digested with MD5 to produce a - 128-bit key. + are easier to read. Note that the maximum key length is the digest + length, here 256 bits.

    - dnssec-keygen -a hmac-md5 -b 128 -n HOST host1-host2. + dnssec-keygen -a hmac-sha256 -b 128 -n HOST host1-host2.

    - The key is in the file Khost1-host2.+157+00000.private. + The key is in the file Khost1-host2.+163+00000.private. Nothing directly uses this file, but the base-64 encoded string following "Key:" can be extracted from the file and used as a shared secret: @@ -519,7 +523,7 @@ nameserver 172.16.72.4

    -Manual Generation

    +Manual Generation

    The shared secret is simply a random sequence of bits, encoded in base-64. Most ASCII strings are valid base-64 strings (assuming @@ -534,7 +538,7 @@ nameserver 172.16.72.4

    -Copying the Shared Secret to Both Machines

    +Copying the Shared Secret to Both Machines

    This is beyond the scope of DNS. A secure transport mechanism should be used. This could be secure FTP, ssh, telephone, etc. @@ -542,7 +546,7 @@ nameserver 172.16.72.4

    -Informing the Servers of the Key's Existence

    +Informing the Servers of the Key's Existence

    Imagine host1 and host 2 are @@ -550,17 +554,15 @@ nameserver 172.16.72.4

     key host1-host2. {
    -  algorithm hmac-md5;
    +  algorithm hmac-sha256;
       secret "La/E5CjG9O+os1jq0a2jdA==";
     };
     

    - The algorithm, hmac-md5, is the only one supported by BIND. The secret is the one generated above. Since this is a secret, it - is recommended that either named.conf be non-world - readable, or the key directive be added to a non-world readable - file that is included by - named.conf. + is recommended that either named.conf be + non-world readable, or the key directive be added to a non-world + readable file that is included by named.conf.

    At this point, the key is recognized. This means that if the @@ -571,7 +573,7 @@ key host1-host2. {

    -Instructing the Server to Use the Key

    +Instructing the Server to Use the Key

    Since keys are shared between two hosts only, the server must be told when keys are to be used. The following is added to the named.conf file @@ -603,7 +605,7 @@ server 10.1.2.3 {

    -TSIG Key Based Access Control

    +TSIG Key Based Access Control

    BIND allows IP addresses and ranges to be specified in ACL @@ -631,7 +633,7 @@ allow-update { key host1-host2. ;};

    -Errors

    +Errors

    The processing of TSIG signed messages can result in several errors. If a signed message is sent to a non-TSIG aware @@ -657,7 +659,7 @@ allow-update { key host1-host2. ;};

    -TKEY

    +TKEY

    TKEY is a mechanism for automatically generating a shared secret between two hosts. There are several "modes" of @@ -693,7 +695,7 @@ allow-update { key host1-host2. ;};

    -SIG(0)

    +SIG(0)

    BIND 9 partially supports DNSSEC SIG(0) transaction signatures as specified in RFC 2535 and RFC 2931. @@ -754,7 +756,7 @@ allow-update { key host1-host2. ;};

    -Generating Keys

    +Generating Keys

    The dnssec-keygen program is used to generate keys. @@ -810,7 +812,7 @@ allow-update { key host1-host2. ;};

    -Signing the Zone

    +Signing the Zone

    The dnssec-signzone program is used to sign a zone. @@ -852,18 +854,21 @@ allow-update { key host1-host2. ;};

    -Configuring Servers

    +Configuring Servers

    To enable named to respond appropriately to DNS requests from DNSSEC aware clients, dnssec-enable must be set to yes. + (This is the default setting.)

    To enable named to validate answers from - other servers both dnssec-enable and - dnssec-validation must be set and some - trusted-keys must be configured - into named.conf. + other servers, the dnssec-enable and + dnssec-validation options must both be + set to yes (the default setting in BIND 9.5 + and later), and at least one trust anchor must be configured + with a trusted-keys statement in + named.conf.

    trusted-keys are copies of DNSKEY RRs @@ -936,17 +941,50 @@ options { None of the keys listed in this example are valid. In particular, the root key is not valid. +

    + When DNSSEC validation is enabled and properly configured, + the resolver will reject any answers from signed, secure zones + which fail to validate, and will return SERVFAIL to the client. +

    +

    + Responses may fail to validate for any of several reasons, + including missing, expired, or invalid signatures, a key which + does not match the DS RRset in the parent zone, or an insecure + response from a zone which, according to its parent, should have + been secure. +

    +
    +

    Note

    +

    + When the validator receives a response from an unsigned zone + that has a signed parent, it must confirm with the parent + that the zone was intentionally left unsigned. It does + this by verifying, via signed and validated NSEC/NSEC3 records, + that the parent zone contains no DS records for the child. +

    +

    + If the validator can prove that the zone + is insecure, then the response is accepted. However, if it + cannot, then it must assume an insecure response to be a + forgery; it rejects the response and logs an error. +

    +

    + The logged error reads "insecurity proof failed" and + "got insecure response; parent indicates it should be secure". + (Prior to BIND 9.7, the logged error was "not insecure". + This referred to the zone, not the response.) +

    +

    -IPv6 Support in BIND 9

    +IPv6 Support in BIND 9

    BIND 9 fully supports all currently - defined forms of IPv6 - name to address and address to name lookups. It will also use - IPv6 addresses to make queries when running on an IPv6 capable - system. + defined forms of IPv6 name to address and address to name + lookups. It will also use IPv6 addresses to make queries when + running on an IPv6 capable system.

    For forward lookups, BIND 9 supports @@ -979,7 +1017,7 @@ options {

    -Address Lookups Using AAAA Records

    +Address Lookups Using AAAA Records

    The IPv6 AAAA record is a parallel to the IPv4 A record, and, unlike the deprecated A6 record, specifies the entire @@ -998,7 +1036,7 @@ host 3600 IN AAAA 2001:db8::1

    -Address to Name Lookups Using Nibble Format

    +Address to Name Lookups Using Nibble Format

    When looking up an address in nibble format, the address components are simply reversed, just as in IPv4, and diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch05.html b/contrib/bind9/doc/arm/Bv9ARM.ch05.html index addc97ac643..e84781f8932 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch05.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch05.html @@ -1,8 +1,8 @@ - + @@ -45,13 +45,13 @@

    -The Lightweight Resolver Library

    +The Lightweight Resolver Library

    Traditionally applications have been linked with a stub resolver library that sends recursive DNS queries to a local caching name diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch06.html b/contrib/bind9/doc/arm/Bv9ARM.ch06.html index 46fd0dd1f6a..9e0667e2525 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch06.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch06.html @@ -1,8 +1,8 @@ - + @@ -48,55 +48,55 @@

    Configuration File Elements
    Address Match Lists
    -
    Comment Syntax
    +
    Comment Syntax
    Configuration File Grammar
    -
    acl Statement Grammar
    +
    acl Statement Grammar
    acl Statement Definition and Usage
    -
    controls Statement Grammar
    +
    controls Statement Grammar
    controls Statement Definition and Usage
    -
    include Statement Grammar
    -
    include Statement Definition and +
    include Statement Grammar
    +
    include Statement Definition and Usage
    -
    key Statement Grammar
    -
    key Statement Definition and Usage
    -
    logging Statement Grammar
    -
    logging Statement Definition and +
    key Statement Grammar
    +
    key Statement Definition and Usage
    +
    logging Statement Grammar
    +
    logging Statement Definition and Usage
    -
    lwres Statement Grammar
    -
    lwres Statement Definition and Usage
    -
    masters Statement Grammar
    -
    masters Statement Definition and +
    lwres Statement Grammar
    +
    lwres Statement Definition and Usage
    +
    masters Statement Grammar
    +
    masters Statement Definition and Usage
    -
    options Statement Grammar
    +
    options Statement Grammar
    options Statement Definition and Usage
    server Statement Grammar
    server Statement Definition and Usage
    statistics-channels Statement Grammar
    -
    statistics-channels Statement Definition and +
    statistics-channels Statement Definition and Usage
    -
    trusted-keys Statement Grammar
    -
    trusted-keys Statement Definition +
    trusted-keys Statement Grammar
    +
    trusted-keys Statement Definition and Usage
    view Statement Grammar
    -
    view Statement Definition and Usage
    +
    view Statement Definition and Usage
    zone Statement Grammar
    -
    zone Statement Definition and Usage
    +
    zone Statement Definition and Usage
    -
    Zone File
    +
    Zone File
    Types of Resource Records and When to Use Them
    -
    Discussion of MX Records
    +
    Discussion of MX Records
    Setting TTLs
    -
    Inverse Mapping in IPv4
    -
    Other Zone File Directives
    -
    BIND Master File Extension: the $GENERATE Directive
    +
    Inverse Mapping in IPv4
    +
    Other Zone File Directives
    +
    BIND Master File Extension: the $GENERATE Directive
    Additional File Formats
    BIND9 Statistics
    @@ -461,7 +461,7 @@ Address Match Lists

    -Syntax

    +Syntax
    address_match_list = address_match_list_element ;
       [ address_match_list_element; ... ]
     address_match_list_element = [ ! ] (ip_address [/length] |
    @@ -470,7 +470,7 @@
     
     

    -Definition and Usage

    +Definition and Usage

    Address match lists are primarily used to determine access control for various server operations. They are also used in @@ -554,7 +554,7 @@

    -Comment Syntax

    +Comment Syntax

    The BIND 9 comment syntax allows for comments to appear @@ -564,7 +564,7 @@

    -Syntax

    +Syntax

    /* This is a BIND comment as in C */
    @@ -579,7 +579,7 @@

    -Definition and Usage

    +Definition and Usage

    Comments may appear anywhere that whitespace may appear in a BIND configuration file. @@ -820,7 +820,7 @@

    -acl Statement Grammar

    +acl Statement Grammar
    acl acl-name {
         address_match_list
     };
    @@ -902,7 +902,7 @@
     
     

    -controls Statement Grammar

    +controls Statement Grammar
    controls {
        [ inet ( ip_addr | * ) [ port ip_port ] allow {  address_match_list  }
                     keys { key_list }; ]
    @@ -1024,12 +1024,12 @@
     
     

    -include Statement Grammar

    +include Statement Grammar
    include filename;

    -include Statement Definition and +include Statement Definition and Usage

    The include statement inserts the @@ -1044,7 +1044,7 @@

    -key Statement Grammar

    +key Statement Grammar
    key key_id {
         algorithm string;
         secret string;
    @@ -1053,7 +1053,7 @@
     
     

    -key Statement Definition and Usage

    +key Statement Definition and Usage

    The key statement defines a shared secret key for use with TSIG (see the section called “TSIG”) @@ -1100,7 +1100,7 @@

    -logging Statement Grammar

    +logging Statement Grammar
    logging {
        [ channel channel_name {
          ( file path_name
    @@ -1124,7 +1124,7 @@
     
     

    -logging Statement Definition and +logging Statement Definition and Usage

    The logging statement configures a @@ -1158,7 +1158,7 @@

    -The channel Phrase

    +The channel Phrase

    All log output goes to one or more channels; you can make as many of them as you want. @@ -1666,8 +1666,7 @@ category notify { null; };

    Lame servers. These are misconfigurations in remote servers, discovered by BIND 9 when trying to - query - those servers during resolution. + query those servers during resolution.

    @@ -1724,7 +1723,7 @@ category notify { null; };

    -The query-errors Category

    +The query-errors Category

    The query-errors category is specifically intended for debugging purposes: To identify @@ -1944,7 +1943,7 @@ category notify { null; };

    -lwres Statement Grammar

    +lwres Statement Grammar

    This is the grammar of the lwres statement in the named.conf file: @@ -1959,7 +1958,7 @@ category notify { null; };

    -lwres Statement Definition and Usage

    +lwres Statement Definition and Usage

    The lwres statement configures the name @@ -2010,14 +2009,14 @@ category notify { null; };

    -masters Statement Grammar

    +masters Statement Grammar
     masters name [port ip_port] { ( masters_list | ip_addr [port ip_port] [key key] ) ; [...] };
     

    -masters Statement Definition and +masters Statement Definition and Usage

    masters lists allow for a common set of masters to be easily used by @@ -2026,7 +2025,7 @@ category notify { null; };

    -options Statement Grammar

    +options Statement Grammar

    This is the grammar of the options statement in the named.conf file: @@ -2115,7 +2114,7 @@ category notify { null; }; [ port ( ip_port | * ) ] ) ; ] [ use-queryport-pool yes_or_no; ] [ queryport-pool-ports number; ] - [ queryport-pool-interval number; ] + [ queryport-pool-updateinterval number; ] [ max-transfer-time-in number; ] [ max-transfer-time-out number; ] [ max-transfer-idle-in number; ] @@ -2156,7 +2155,7 @@ category notify { null; }; [ lame-ttl number; ] [ max-ncache-ttl number; ] [ max-cache-ttl number; ] - [ sig-validity-interval number ; ] + [ sig-validity-interval number [number] ; ] [ sig-signing-nodes number ; ] [ sig-signing-signatures number ; ] [ sig-signing-type number ; ] @@ -2228,11 +2227,12 @@ category notify { null; };

    key-directory

    When performing dynamic update of secure zones, the - directory where the public and private key files should be - found, - if different than the current working directory. The - directory specified - must be an absolute path. + directory where the public and private DNSSEC key files + should be found, if different than the current working + directory. The directory specified must be an absolute + path. (Note that this option has no effect on the paths + for files containing non-DNSSEC keys such as the + rndc.key.

    named-xfer

    @@ -2990,18 +2990,22 @@ options {

    match-mapped-addresses
    -

    +

    +

    If yes, then an IPv4-mapped IPv6 address will match any address match list entries that match the corresponding IPv4 address. - Enabling this option is sometimes useful on IPv6-enabled - Linux - systems, to work around a kernel quirk that causes IPv4 - TCP connections such as zone transfers to be accepted - on an IPv6 socket using mapped addresses, causing - address match lists designed for IPv4 to fail to match. - The use of this option for any other purpose is discouraged. -

    +

    +

    + This option was introduced to work around a kernel quirk + in some operating systems that causes IPv4 TCP + connections, such as zone transfers, to be accepted on an + IPv6 socket using mapped addresses. This caused address + match lists designed for IPv4 to fail to match. However, + named now solves this problem + internally. The use of this option is discouraged. +

    +
    ixfr-from-differences

    @@ -3181,7 +3185,7 @@ options {

    -Forwarding

    +Forwarding

    The forwarding facility can be used to create a large site-wide cache on a few servers, reducing traffic over links to external @@ -3225,7 +3229,7 @@ options {

    -Dual-stack Servers

    +Dual-stack Servers

    Dual-stack servers are used as servers of last resort to work around @@ -3422,7 +3426,7 @@ options {

    -Interfaces

    +Interfaces

    The interfaces and ports that the server will answer queries from may be specified using the listen-on option. listen-on takes @@ -3874,7 +3878,7 @@ avoid-v6-udp-ports {};

    -UDP Port Lists

    +UDP Port Lists

    use-v4-udp-ports, avoid-v4-udp-ports, @@ -3916,7 +3920,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };

    -Operating System Resource Limits

    +Operating System Resource Limits

    The server's usage of many system resources can be limited. Scaled values are allowed when specifying resource limits. For @@ -4078,7 +4082,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };

    -Periodic Task Intervals

    +Periodic Task Intervals
    cleaning-interval

    @@ -4393,14 +4397,22 @@ avoid-v6-udp-ports { 40000; range 50000 60000; }; Tuning

    lame-ttl
    -

    +

    +

    Sets the number of seconds to cache a lame server indication. 0 disables caching. (This is NOT recommended.) The default is 600 (10 minutes) and the maximum value is 1800 (30 minutes). -

    +

    +

    + Lame-ttl also controls the amount of time DNSSEC + validation failures are cached. There is a minimum + of 30 seconds applied to bad cache entries if the + lame-ttl is set to less than 30 seconds. +

    +
    max-ncache-ttl

    To reduce network traffic and increase performance, @@ -4602,7 +4614,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };

    notify-delay

    The delay, in seconds, between sending sets of notify - messages for a zone. The default is zero. + messages for a zone. The default is five (5) seconds.

    @@ -4872,7 +4884,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; }; [ query-source-v6 [ address ( ip_addr | * ) ] [ port ( ip_port | * ) ]; ] [ use-queryport-pool yes_or_no; ] [ queryport-pool-ports number; ] - [ queryport-pool-interval number; ] + [ queryport-pool-updateinterval number; ] };
    @@ -5056,7 +5068,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };

    -statistics-channels Statement Definition and +statistics-channels Statement Definition and Usage

    The statistics-channels statement @@ -5107,7 +5119,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };

    -trusted-keys Statement Grammar

    +trusted-keys Statement Grammar
    trusted-keys {
         string number number number string ;
         [ string number number number string ; [...]]
    @@ -5116,7 +5128,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
     
     

    -trusted-keys Statement Definition +trusted-keys Statement Definition and Usage

    The trusted-keys statement defines @@ -5162,7 +5174,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };

    -view Statement Definition and Usage

    +view Statement Definition and Usage

    The view statement is a powerful feature @@ -5315,7 +5327,7 @@ view "external" { [ notify-source (ip4_addr | *) [port ip_port] ; ] [ notify-source-v6 (ip6_addr | *) [port ip_port] ; ] [ zone-statistics yes_or_no ; ] - [ sig-validity-interval number ; ] + [ sig-validity-interval number [number] ; ] [ sig-signing-nodes number ; ] [ sig-signing-signatures number ; ] [ sig-signing-type number ; ] @@ -5428,10 +5440,10 @@ zone zone_name [

    -zone Statement Definition and Usage

    +zone Statement Definition and Usage

    -Zone Types

    +Zone Types
    @@ -5642,7 +5654,7 @@ zone zone_name [

    -Class

    +Class

    The zone's name may optionally be followed by a class. If a class is not specified, class IN (for Internet), @@ -5664,7 +5676,7 @@ zone zone_name [

    -Zone Options

    +Zone Options
    allow-notify

    @@ -6243,7 +6255,7 @@ zone zone_name [

    -Zone File

    +Zone File

    Types of Resource Records and When to Use Them

    @@ -6256,7 +6268,7 @@ zone zone_name [

    -Resource Records

    +Resource Records

    A domain name identifies a node. Each node has a set of resource information, which may be empty. The set of resource @@ -6993,7 +7005,7 @@ zone zone_name [

    -Textual expression of RRs

    +Textual expression of RRs

    RRs are represented in binary form in the packets of the DNS protocol, and are usually represented in highly encoded form @@ -7196,7 +7208,7 @@ zone zone_name [

    -Discussion of MX Records

    +Discussion of MX Records

    As described above, domain servers store information as a series of resource records, each of which contains a particular @@ -7452,7 +7464,7 @@ zone zone_name [

    -Inverse Mapping in IPv4

    +Inverse Mapping in IPv4

    Reverse name resolution (that is, translation from IP address to name) is achieved by means of the in-addr.arpa domain @@ -7513,7 +7525,7 @@ zone zone_name [

    -Other Zone File Directives

    +Other Zone File Directives

    The Master File Format was initially defined in RFC 1035 and has subsequently been extended. While the Master File Format @@ -7528,7 +7540,18 @@ zone zone_name [

    -The $ORIGIN Directive

    +The @ (at-sign)
    +

    + When used in the label (or name) field, the asperand or + at-sign (@) symbol represents the current origin. + At the start of the zone file, it is the + <zone_name> (followed by + trailing dot). +

    + +
    +

    +The $ORIGIN Directive

    Syntax: $ORIGIN domain-name @@ -7538,7 +7561,8 @@ zone zone_name [$ORIGIN - <zone-name>. + <zone_name>. + (followed by trailing dot). The current $ORIGIN is appended to the domain specified in the $ORIGIN argument if it is not absolute. @@ -7556,7 +7580,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.

    -The $INCLUDE Directive

    +The $INCLUDE Directive

    Syntax: $INCLUDE filename @@ -7592,7 +7616,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.

    -The $TTL Directive

    +The $TTL Directive

    Syntax: $TTL default-ttl @@ -7611,7 +7635,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.

    -BIND Master File Extension: the $GENERATE Directive

    +BIND Master File Extension: the $GENERATE Directive

    Syntax: $GENERATE range @@ -8002,7 +8026,7 @@ $GENERATE 1-127 $ CNAME $.0

    -Name Server Statistics Counters

    +Name Server Statistics Counters
    @@ -8559,7 +8583,7 @@ $GENERATE 1-127 $ CNAME $.0

    -Zone Maintenance Statistics Counters

    +Zone Maintenance Statistics Counters
    @@ -8713,7 +8737,7 @@ $GENERATE 1-127 $ CNAME $.0

    -Resolver Statistics Counters

    +Resolver Statistics Counters
    @@ -9089,7 +9113,7 @@ $GENERATE 1-127 $ CNAME $.0

    -Socket I/O Statistics Counters

    +Socket I/O Statistics Counters

    Socket I/O statistics counters are defined per socket types, which are @@ -9244,7 +9268,7 @@ $GENERATE 1-127 $ CNAME $.0

    -Compatibility with BIND 8 Counters

    +Compatibility with BIND 8 Counters

    Most statistics counters that were available in BIND 8 are also supported in diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch07.html b/contrib/bind9/doc/arm/Bv9ARM.ch07.html index ca12cb3c435..91994f3472b 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch07.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch07.html @@ -1,8 +1,8 @@ - + @@ -46,10 +46,10 @@

    Table of Contents

    Access Control Lists
    -
    Chroot and Setuid
    +
    Chroot and Setuid
    -
    The chroot Environment
    -
    Using the setuid Function
    +
    The chroot Environment
    +
    Using the setuid Function
    Dynamic Update Security
    @@ -119,7 +119,7 @@ zone "example.com" {

    -Chroot and Setuid +Chroot and Setuid

    On UNIX servers, it is possible to run BIND @@ -145,7 +145,7 @@ zone "example.com" {

    -The chroot Environment

    +The chroot Environment

    In order for a chroot environment to @@ -173,7 +173,7 @@ zone "example.com" {

    -Using the setuid Function

    +Using the setuid Function

    Prior to running the named daemon, use diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch08.html b/contrib/bind9/doc/arm/Bv9ARM.ch08.html index 5e547eb48e0..3e7c8c310fd 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch08.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch08.html @@ -1,8 +1,8 @@ - + @@ -45,18 +45,18 @@

    -Common Problems

    +Common Problems

    -It's not working; how can I figure out what's wrong?

    +It's not working; how can I figure out what's wrong?

    The best solution to solving installation and configuration issues is to take preventative measures by setting @@ -68,7 +68,7 @@

    -Incrementing and Changing the Serial Number

    +Incrementing and Changing the Serial Number

    Zone serial numbers are just numbers — they aren't date related. A lot of people set them to a number that @@ -95,7 +95,7 @@

    -Where Can I Get Help?

    +Where Can I Get Help?

    The Internet Systems Consortium (ISC) offers a wide range diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch09.html b/contrib/bind9/doc/arm/Bv9ARM.ch09.html index 87134e05c3d..6b6af6a7f1d 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch09.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch09.html @@ -1,8 +1,8 @@ - + @@ -45,21 +45,21 @@

    -Acknowledgments

    +Acknowledgments

    A Brief History of the DNS and BIND @@ -162,7 +162,7 @@

    -General DNS Reference Information

    +General DNS Reference Information

    IPv6 addresses (AAAA)

    @@ -250,17 +250,17 @@

    -Bibliography

    +Bibliography

    Standards

    -

    [RFC974] C. Partridge. Mail Routing and the Domain System. January 1986.

    +

    [RFC974] C. Partridge. Mail Routing and the Domain System. January 1986.

    -

    [RFC1034] P.V. Mockapetris. Domain Names — Concepts and Facilities. November 1987.

    +

    [RFC1034] P.V. Mockapetris. Domain Names — Concepts and Facilities. November 1987.

    -

    [RFC1035] P. V. Mockapetris. Domain Names — Implementation and +

    [RFC1035] P. V. Mockapetris. Domain Names — Implementation and Specification. November 1987.

    @@ -268,42 +268,42 @@

    Proposed Standards

    -

    [RFC2181] R., R. Bush Elz. Clarifications to the DNS +

    [RFC2181] R., R. Bush Elz. Clarifications to the DNS Specification. July 1997.

    -

    [RFC2308] M. Andrews. Negative Caching of DNS +

    [RFC2308] M. Andrews. Negative Caching of DNS Queries. March 1998.

    -

    [RFC1995] M. Ohta. Incremental Zone Transfer in DNS. August 1996.

    +

    [RFC1995] M. Ohta. Incremental Zone Transfer in DNS. August 1996.

    -

    [RFC1996] P. Vixie. A Mechanism for Prompt Notification of Zone Changes. August 1996.

    +

    [RFC1996] P. Vixie. A Mechanism for Prompt Notification of Zone Changes. August 1996.

    -

    [RFC2136] P. Vixie, S. Thomson, Y. Rekhter, and J. Bound. Dynamic Updates in the Domain Name System. April 1997.

    +

    [RFC2136] P. Vixie, S. Thomson, Y. Rekhter, and J. Bound. Dynamic Updates in the Domain Name System. April 1997.

    -

    [RFC2671] P. Vixie. Extension Mechanisms for DNS (EDNS0). August 1997.

    +

    [RFC2671] P. Vixie. Extension Mechanisms for DNS (EDNS0). August 1997.

    -

    [RFC2672] M. Crawford. Non-Terminal DNS Name Redirection. August 1999.

    +

    [RFC2672] M. Crawford. Non-Terminal DNS Name Redirection. August 1999.

    -

    [RFC2845] P. Vixie, O. Gudmundsson, D. Eastlake, 3rd, and B. Wellington. Secret Key Transaction Authentication for DNS (TSIG). May 2000.

    +

    [RFC2845] P. Vixie, O. Gudmundsson, D. Eastlake, 3rd, and B. Wellington. Secret Key Transaction Authentication for DNS (TSIG). May 2000.

    -

    [RFC2930] D. Eastlake, 3rd. Secret Key Establishment for DNS (TKEY RR). September 2000.

    +

    [RFC2930] D. Eastlake, 3rd. Secret Key Establishment for DNS (TKEY RR). September 2000.

    -

    [RFC2931] D. Eastlake, 3rd. DNS Request and Transaction Signatures (SIG(0)s). September 2000.

    +

    [RFC2931] D. Eastlake, 3rd. DNS Request and Transaction Signatures (SIG(0)s). September 2000.

    -

    [RFC3007] B. Wellington. Secure Domain Name System (DNS) Dynamic Update. November 2000.

    +

    [RFC3007] B. Wellington. Secure Domain Name System (DNS) Dynamic Update. November 2000.

    -

    [RFC3645] S. Kwan, P. Garg, J. Gilroy, L. Esibov, J. Westhead, and R. Hall. Generic Security Service Algorithm for Secret +

    [RFC3645] S. Kwan, P. Garg, J. Gilroy, L. Esibov, J. Westhead, and R. Hall. Generic Security Service Algorithm for Secret Key Transaction Authentication for DNS (GSS-TSIG). October 2003.

    @@ -312,19 +312,19 @@

    DNS Security Proposed Standards

    -

    [RFC3225] D. Conrad. Indicating Resolver Support of DNSSEC. December 2001.

    +

    [RFC3225] D. Conrad. Indicating Resolver Support of DNSSEC. December 2001.

    -

    [RFC3833] D. Atkins and R. Austein. Threat Analysis of the Domain Name System (DNS). August 2004.

    +

    [RFC3833] D. Atkins and R. Austein. Threat Analysis of the Domain Name System (DNS). August 2004.

    -

    [RFC4033] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. DNS Security Introduction and Requirements. March 2005.

    +

    [RFC4033] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. DNS Security Introduction and Requirements. March 2005.

    -

    [RFC4034] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. Resource Records for the DNS Security Extensions. March 2005.

    +

    [RFC4034] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. Resource Records for the DNS Security Extensions. March 2005.

    -

    [RFC4035] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. Protocol Modifications for the DNS +

    [RFC4035] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. Protocol Modifications for the DNS Security Extensions. March 2005.

    @@ -332,146 +332,146 @@

    Other Important RFCs About DNS Implementation

    -

    [RFC1535] E. Gavron. A Security Problem and Proposed Correction With Widely +

    [RFC1535] E. Gavron. A Security Problem and Proposed Correction With Widely Deployed DNS Software.. October 1993.

    -

    [RFC1536] A. Kumar, J. Postel, C. Neuman, P. Danzig, and S. Miller. Common DNS Implementation +

    [RFC1536] A. Kumar, J. Postel, C. Neuman, P. Danzig, and S. Miller. Common DNS Implementation Errors and Suggested Fixes. October 1993.

    -

    [RFC1982] R. Elz and R. Bush. Serial Number Arithmetic. August 1996.

    +

    [RFC1982] R. Elz and R. Bush. Serial Number Arithmetic. August 1996.

    -

    [RFC4074] Y. Morishita and T. Jinmei. Common Misbehaviour Against DNS +

    [RFC4074] Y. Morishita and T. Jinmei. Common Misbehaviour Against DNS Queries for IPv6 Addresses. May 2005.

    Resource Record Types

    -

    [RFC1183] C.F. Everhart, L. A. Mamakos, R. Ullmann, and P. Mockapetris. New DNS RR Definitions. October 1990.

    +

    [RFC1183] C.F. Everhart, L. A. Mamakos, R. Ullmann, and P. Mockapetris. New DNS RR Definitions. October 1990.

    -

    [RFC1706] B. Manning and R. Colella. DNS NSAP Resource Records. October 1994.

    +

    [RFC1706] B. Manning and R. Colella. DNS NSAP Resource Records. October 1994.

    -

    [RFC2168] R. Daniel and M. Mealling. Resolution of Uniform Resource Identifiers using +

    [RFC2168] R. Daniel and M. Mealling. Resolution of Uniform Resource Identifiers using the Domain Name System. June 1997.

    -

    [RFC1876] C. Davis, P. Vixie, T., and I. Dickinson. A Means for Expressing Location Information in the +

    [RFC1876] C. Davis, P. Vixie, T., and I. Dickinson. A Means for Expressing Location Information in the Domain Name System. January 1996.

    -

    [RFC2052] A. Gulbrandsen and P. Vixie. A DNS RR for Specifying the +

    [RFC2052] A. Gulbrandsen and P. Vixie. A DNS RR for Specifying the Location of Services.. October 1996.

    -

    [RFC2163] A. Allocchio. Using the Internet DNS to +

    [RFC2163] A. Allocchio. Using the Internet DNS to Distribute MIXER Conformant Global Address Mapping. January 1998.

    -

    [RFC2230] R. Atkinson. Key Exchange Delegation Record for the DNS. October 1997.

    +

    [RFC2230] R. Atkinson. Key Exchange Delegation Record for the DNS. October 1997.

    -

    [RFC2536] D. Eastlake, 3rd. DSA KEYs and SIGs in the Domain Name System (DNS). March 1999.

    +

    [RFC2536] D. Eastlake, 3rd. DSA KEYs and SIGs in the Domain Name System (DNS). March 1999.

    -

    [RFC2537] D. Eastlake, 3rd. RSA/MD5 KEYs and SIGs in the Domain Name System (DNS). March 1999.

    +

    [RFC2537] D. Eastlake, 3rd. RSA/MD5 KEYs and SIGs in the Domain Name System (DNS). March 1999.

    -

    [RFC2538] D. Eastlake, 3rd and O. Gudmundsson. Storing Certificates in the Domain Name System (DNS). March 1999.

    +

    [RFC2538] D. Eastlake, 3rd and O. Gudmundsson. Storing Certificates in the Domain Name System (DNS). March 1999.

    -

    [RFC2539] D. Eastlake, 3rd. Storage of Diffie-Hellman Keys in the Domain Name System (DNS). March 1999.

    +

    [RFC2539] D. Eastlake, 3rd. Storage of Diffie-Hellman Keys in the Domain Name System (DNS). March 1999.

    -

    [RFC2540] D. Eastlake, 3rd. Detached Domain Name System (DNS) Information. March 1999.

    +

    [RFC2540] D. Eastlake, 3rd. Detached Domain Name System (DNS) Information. March 1999.

    -

    [RFC2782] A. Gulbrandsen. P. Vixie. L. Esibov. A DNS RR for specifying the location of services (DNS SRV). February 2000.

    +

    [RFC2782] A. Gulbrandsen. P. Vixie. L. Esibov. A DNS RR for specifying the location of services (DNS SRV). February 2000.

    -

    [RFC2915] M. Mealling. R. Daniel. The Naming Authority Pointer (NAPTR) DNS Resource Record. September 2000.

    +

    [RFC2915] M. Mealling. R. Daniel. The Naming Authority Pointer (NAPTR) DNS Resource Record. September 2000.

    -

    [RFC3110] D. Eastlake, 3rd. RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS). May 2001.

    +

    [RFC3110] D. Eastlake, 3rd. RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS). May 2001.

    -

    [RFC3123] P. Koch. A DNS RR Type for Lists of Address Prefixes (APL RR). June 2001.

    +

    [RFC3123] P. Koch. A DNS RR Type for Lists of Address Prefixes (APL RR). June 2001.

    -

    [RFC3596] S. Thomson, C. Huitema, V. Ksinant, and M. Souissi. DNS Extensions to support IP +

    [RFC3596] S. Thomson, C. Huitema, V. Ksinant, and M. Souissi. DNS Extensions to support IP version 6. October 2003.

    -

    [RFC3597] A. Gustafsson. Handling of Unknown DNS Resource Record (RR) Types. September 2003.

    +

    [RFC3597] A. Gustafsson. Handling of Unknown DNS Resource Record (RR) Types. September 2003.

    DNS and the Internet

    -

    [RFC1101] P. V. Mockapetris. DNS Encoding of Network Names +

    [RFC1101] P. V. Mockapetris. DNS Encoding of Network Names and Other Types. April 1989.

    -

    [RFC1123] Braden. Requirements for Internet Hosts - Application and +

    [RFC1123] Braden. Requirements for Internet Hosts - Application and Support. October 1989.

    -

    [RFC1591] J. Postel. Domain Name System Structure and Delegation. March 1994.

    +

    [RFC1591] J. Postel. Domain Name System Structure and Delegation. March 1994.

    -

    [RFC2317] H. Eidnes, G. de Groot, and P. Vixie. Classless IN-ADDR.ARPA Delegation. March 1998.

    +

    [RFC2317] H. Eidnes, G. de Groot, and P. Vixie. Classless IN-ADDR.ARPA Delegation. March 1998.

    -

    [RFC2826] Internet Architecture Board. IAB Technical Comment on the Unique DNS Root. May 2000.

    +

    [RFC2826] Internet Architecture Board. IAB Technical Comment on the Unique DNS Root. May 2000.

    -

    [RFC2929] D. Eastlake, 3rd, E. Brunner-Williams, and B. Manning. Domain Name System (DNS) IANA Considerations. September 2000.

    +

    [RFC2929] D. Eastlake, 3rd, E. Brunner-Williams, and B. Manning. Domain Name System (DNS) IANA Considerations. September 2000.

    DNS Operations

    -

    [RFC1033] M. Lottor. Domain administrators operations guide.. November 1987.

    +

    [RFC1033] M. Lottor. Domain administrators operations guide.. November 1987.

    -

    [RFC1537] P. Beertema. Common DNS Data File +

    [RFC1537] P. Beertema. Common DNS Data File Configuration Errors. October 1993.

    -

    [RFC1912] D. Barr. Common DNS Operational and +

    [RFC1912] D. Barr. Common DNS Operational and Configuration Errors. February 1996.

    -

    [RFC2010] B. Manning and P. Vixie. Operational Criteria for Root Name Servers.. October 1996.

    +

    [RFC2010] B. Manning and P. Vixie. Operational Criteria for Root Name Servers.. October 1996.

    -

    [RFC2219] M. Hamilton and R. Wright. Use of DNS Aliases for +

    [RFC2219] M. Hamilton and R. Wright. Use of DNS Aliases for Network Services.. October 1997.

    Internationalized Domain Names

    -

    [RFC2825] IAB and R. Daigle. A Tangled Web: Issues of I18N, Domain Names, +

    [RFC2825] IAB and R. Daigle. A Tangled Web: Issues of I18N, Domain Names, and the Other Internet protocols. May 2000.

    -

    [RFC3490] P. Faltstrom, P. Hoffman, and A. Costello. Internationalizing Domain Names in Applications (IDNA). March 2003.

    +

    [RFC3490] P. Faltstrom, P. Hoffman, and A. Costello. Internationalizing Domain Names in Applications (IDNA). March 2003.

    -

    [RFC3491] P. Hoffman and M. Blanchet. Nameprep: A Stringprep Profile for Internationalized Domain Names. March 2003.

    +

    [RFC3491] P. Hoffman and M. Blanchet. Nameprep: A Stringprep Profile for Internationalized Domain Names. March 2003.

    -

    [RFC3492] A. Costello. Punycode: A Bootstring encoding of Unicode +

    [RFC3492] A. Costello. Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA). March 2003.

    @@ -487,47 +487,47 @@

    -

    [RFC1464] R. Rosenbaum. Using the Domain Name System To Store Arbitrary String +

    [RFC1464] R. Rosenbaum. Using the Domain Name System To Store Arbitrary String Attributes. May 1993.

    -

    [RFC1713] A. Romao. Tools for DNS Debugging. November 1994.

    +

    [RFC1713] A. Romao. Tools for DNS Debugging. November 1994.

    -

    [RFC1794] T. Brisco. DNS Support for Load +

    [RFC1794] T. Brisco. DNS Support for Load Balancing. April 1995.

    -

    [RFC2240] O. Vaughan. A Legal Basis for Domain Name Allocation. November 1997.

    +

    [RFC2240] O. Vaughan. A Legal Basis for Domain Name Allocation. November 1997.

    -

    [RFC2345] J. Klensin, T. Wolf, and G. Oglesby. Domain Names and Company Name Retrieval. May 1998.

    +

    [RFC2345] J. Klensin, T. Wolf, and G. Oglesby. Domain Names and Company Name Retrieval. May 1998.

    -

    [RFC2352] O. Vaughan. A Convention For Using Legal Names as Domain Names. May 1998.

    +

    [RFC2352] O. Vaughan. A Convention For Using Legal Names as Domain Names. May 1998.

    -

    [RFC3071] J. Klensin. Reflections on the DNS, RFC 1591, and Categories of Domains. February 2001.

    +

    [RFC3071] J. Klensin. Reflections on the DNS, RFC 1591, and Categories of Domains. February 2001.

    -

    [RFC3258] T. Hardie. Distributing Authoritative Name Servers via +

    [RFC3258] T. Hardie. Distributing Authoritative Name Servers via Shared Unicast Addresses. April 2002.

    -

    [RFC3901] A. Durand and J. Ihren. DNS IPv6 Transport Operational Guidelines. September 2004.

    +

    [RFC3901] A. Durand and J. Ihren. DNS IPv6 Transport Operational Guidelines. September 2004.

    Obsolete and Unimplemented Experimental RFC

    -

    [RFC1712] C. Farrell, M. Schulze, S. Pleitner, and D. Baldoni. DNS Encoding of Geographical +

    [RFC1712] C. Farrell, M. Schulze, S. Pleitner, and D. Baldoni. DNS Encoding of Geographical Location. November 1994.

    -

    [RFC2673] M. Crawford. Binary Labels in the Domain Name System. August 1999.

    +

    [RFC2673] M. Crawford. Binary Labels in the Domain Name System. August 1999.

    -

    [RFC2874] M. Crawford and C. Huitema. DNS Extensions to Support IPv6 Address Aggregation +

    [RFC2874] M. Crawford and C. Huitema. DNS Extensions to Support IPv6 Address Aggregation and Renumbering. July 2000.

    @@ -541,39 +541,39 @@

    -

    [RFC2065] D. Eastlake, 3rd and C. Kaufman. Domain Name System Security Extensions. January 1997.

    +

    [RFC2065] D. Eastlake, 3rd and C. Kaufman. Domain Name System Security Extensions. January 1997.

    -

    [RFC2137] D. Eastlake, 3rd. Secure Domain Name System Dynamic Update. April 1997.

    +

    [RFC2137] D. Eastlake, 3rd. Secure Domain Name System Dynamic Update. April 1997.

    -

    [RFC2535] D. Eastlake, 3rd. Domain Name System Security Extensions. March 1999.

    +

    [RFC2535] D. Eastlake, 3rd. Domain Name System Security Extensions. March 1999.

    -

    [RFC3008] B. Wellington. Domain Name System Security (DNSSEC) +

    [RFC3008] B. Wellington. Domain Name System Security (DNSSEC) Signing Authority. November 2000.

    -

    [RFC3090] E. Lewis. DNS Security Extension Clarification on Zone Status. March 2001.

    +

    [RFC3090] E. Lewis. DNS Security Extension Clarification on Zone Status. March 2001.

    -

    [RFC3445] D. Massey and S. Rose. Limiting the Scope of the KEY Resource Record (RR). December 2002.

    +

    [RFC3445] D. Massey and S. Rose. Limiting the Scope of the KEY Resource Record (RR). December 2002.

    -

    [RFC3655] B. Wellington and O. Gudmundsson. Redefinition of DNS Authenticated Data (AD) bit. November 2003.

    +

    [RFC3655] B. Wellington and O. Gudmundsson. Redefinition of DNS Authenticated Data (AD) bit. November 2003.

    -

    [RFC3658] O. Gudmundsson. Delegation Signer (DS) Resource Record (RR). December 2003.

    +

    [RFC3658] O. Gudmundsson. Delegation Signer (DS) Resource Record (RR). December 2003.

    -

    [RFC3755] S. Weiler. Legacy Resolver Compatibility for Delegation Signer (DS). May 2004.

    +

    [RFC3755] S. Weiler. Legacy Resolver Compatibility for Delegation Signer (DS). May 2004.

    -

    [RFC3757] O. Kolkman, J. Schlyter, and E. Lewis. Domain Name System KEY (DNSKEY) Resource Record +

    [RFC3757] O. Kolkman, J. Schlyter, and E. Lewis. Domain Name System KEY (DNSKEY) Resource Record (RR) Secure Entry Point (SEP) Flag. April 2004.

    -

    [RFC3845] J. Schlyter. DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format. August 2004.

    +

    [RFC3845] J. Schlyter. DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format. August 2004.

    @@ -594,14 +594,14 @@

    -Other Documents About BIND +Other Documents About BIND

    -Bibliography

    +Bibliography
    -

    Paul Albitz and Cricket Liu. DNS and BIND. Copyright © 1998 Sebastopol, CA: O'Reilly and Associates.

    +

    Paul Albitz and Cricket Liu. DNS and BIND. Copyright © 1998 Sebastopol, CA: O'Reilly and Associates.

    diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch10.html b/contrib/bind9/doc/arm/Bv9ARM.ch10.html index 5fbeb3dede9..452717c68d9 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.ch10.html +++ b/contrib/bind9/doc/arm/Bv9ARM.ch10.html @@ -1,8 +1,8 @@ - + diff --git a/contrib/bind9/doc/arm/Bv9ARM.html b/contrib/bind9/doc/arm/Bv9ARM.html index ffb7b6242f5..2f127c661c3 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.html +++ b/contrib/bind9/doc/arm/Bv9ARM.html @@ -1,8 +1,8 @@ - + @@ -41,7 +41,7 @@

    BIND 9 Administrator Reference Manual

    -
    +

    @@ -51,39 +51,39 @@
    1. Introduction
    -
    Scope of Document
    -
    Organization of This Document
    -
    Conventions Used in This Document
    -
    The Domain Name System (DNS)
    +
    Scope of Document
    +
    Organization of This Document
    +
    Conventions Used in This Document
    +
    The Domain Name System (DNS)
    -
    DNS Fundamentals
    -
    Domains and Domain Names
    -
    Zones
    -
    Authoritative Name Servers
    -
    Caching Name Servers
    -
    Name Servers in Multiple Roles
    +
    DNS Fundamentals
    +
    Domains and Domain Names
    +
    Zones
    +
    Authoritative Name Servers
    +
    Caching Name Servers
    +
    Name Servers in Multiple Roles
    2. BIND Resource Requirements
    -
    Hardware requirements
    -
    CPU Requirements
    -
    Memory Requirements
    -
    Name Server Intensive Environment Issues
    -
    Supported Operating Systems
    +
    Hardware requirements
    +
    CPU Requirements
    +
    Memory Requirements
    +
    Name Server Intensive Environment Issues
    +
    Supported Operating Systems
    3. Name Server Configuration
    Sample Configurations
    -
    A Caching-only Name Server
    -
    An Authoritative-only Name Server
    +
    A Caching-only Name Server
    +
    An Authoritative-only Name Server
    -
    Load Balancing
    -
    Name Server Operations
    +
    Load Balancing
    +
    Name Server Operations
    -
    Tools for Use With the Name Server Daemon
    -
    Signals
    +
    Tools for Use With the Name Server Daemon
    +
    Signals
    4. Advanced DNS Features
    @@ -92,34 +92,34 @@
    Dynamic Update
    The journal file
    Incremental Zone Transfers (IXFR)
    -
    Split DNS
    -
    Example split DNS setup
    +
    Split DNS
    +
    Example split DNS setup
    TSIG
    -
    Generate Shared Keys for Each Pair of Hosts
    -
    Copying the Shared Secret to Both Machines
    -
    Informing the Servers of the Key's Existence
    -
    Instructing the Server to Use the Key
    -
    TSIG Key Based Access Control
    -
    Errors
    +
    Generate Shared Keys for Each Pair of Hosts
    +
    Copying the Shared Secret to Both Machines
    +
    Informing the Servers of the Key's Existence
    +
    Instructing the Server to Use the Key
    +
    TSIG Key Based Access Control
    +
    Errors
    -
    TKEY
    -
    SIG(0)
    +
    TKEY
    +
    SIG(0)
    DNSSEC
    -
    Generating Keys
    -
    Signing the Zone
    -
    Configuring Servers
    +
    Generating Keys
    +
    Signing the Zone
    +
    Configuring Servers
    -
    IPv6 Support in BIND 9
    +
    IPv6 Support in BIND 9
    -
    Address Lookups Using AAAA Records
    -
    Address to Name Lookups Using Nibble Format
    +
    Address Lookups Using AAAA Records
    +
    Address to Name Lookups Using Nibble Format
    5. The BIND 9 Lightweight Resolver
    -
    The Lightweight Resolver Library
    +
    The Lightweight Resolver Library
    Running a Resolver Daemon
    6. BIND 9 Configuration Reference
    @@ -127,55 +127,55 @@
    Configuration File Elements
    Address Match Lists
    -
    Comment Syntax
    +
    Comment Syntax
    Configuration File Grammar
    -
    acl Statement Grammar
    +
    acl Statement Grammar
    acl Statement Definition and Usage
    -
    controls Statement Grammar
    +
    controls Statement Grammar
    controls Statement Definition and Usage
    -
    include Statement Grammar
    -
    include Statement Definition and +
    include Statement Grammar
    +
    include Statement Definition and Usage
    -
    key Statement Grammar
    -
    key Statement Definition and Usage
    -
    logging Statement Grammar
    -
    logging Statement Definition and +
    key Statement Grammar
    +
    key Statement Definition and Usage
    +
    logging Statement Grammar
    +
    logging Statement Definition and Usage
    -
    lwres Statement Grammar
    -
    lwres Statement Definition and Usage
    -
    masters Statement Grammar
    -
    masters Statement Definition and +
    lwres Statement Grammar
    +
    lwres Statement Definition and Usage
    +
    masters Statement Grammar
    +
    masters Statement Definition and Usage
    -
    options Statement Grammar
    +
    options Statement Grammar
    options Statement Definition and Usage
    server Statement Grammar
    server Statement Definition and Usage
    statistics-channels Statement Grammar
    -
    statistics-channels Statement Definition and +
    statistics-channels Statement Definition and Usage
    -
    trusted-keys Statement Grammar
    -
    trusted-keys Statement Definition +
    trusted-keys Statement Grammar
    +
    trusted-keys Statement Definition and Usage
    view Statement Grammar
    -
    view Statement Definition and Usage
    +
    view Statement Definition and Usage
    zone Statement Grammar
    -
    zone Statement Definition and Usage
    +
    zone Statement Definition and Usage
    -
    Zone File
    +
    Zone File
    Types of Resource Records and When to Use Them
    -
    Discussion of MX Records
    +
    Discussion of MX Records
    Setting TTLs
    -
    Inverse Mapping in IPv4
    -
    Other Zone File Directives
    -
    BIND Master File Extension: the $GENERATE Directive
    +
    Inverse Mapping in IPv4
    +
    Other Zone File Directives
    +
    BIND Master File Extension: the $GENERATE Directive
    Additional File Formats
    BIND9 Statistics
    @@ -184,31 +184,31 @@
    7. BIND 9 Security Considerations
    Access Control Lists
    -
    Chroot and Setuid
    +
    Chroot and Setuid
    -
    The chroot Environment
    -
    Using the setuid Function
    +
    The chroot Environment
    +
    Using the setuid Function
    Dynamic Update Security
    8. Troubleshooting
    -
    Common Problems
    -
    It's not working; how can I figure out what's wrong?
    -
    Incrementing and Changing the Serial Number
    -
    Where Can I Get Help?
    +
    Common Problems
    +
    It's not working; how can I figure out what's wrong?
    +
    Incrementing and Changing the Serial Number
    +
    Where Can I Get Help?
    A. Appendices
    -
    Acknowledgments
    +
    Acknowledgments
    A Brief History of the DNS and BIND
    -
    General DNS Reference Information
    +
    General DNS Reference Information
    IPv6 addresses (AAAA)
    Bibliography (and Suggested Reading)
    Request for Comments (RFCs)
    Internet Drafts
    -
    Other Documents About BIND
    +
    Other Documents About BIND
    I. Manual pages
    diff --git a/contrib/bind9/doc/arm/Bv9ARM.pdf b/contrib/bind9/doc/arm/Bv9ARM.pdf index fbb664f8b27..87f346299a7 100644 --- a/contrib/bind9/doc/arm/Bv9ARM.pdf +++ b/contrib/bind9/doc/arm/Bv9ARM.pdf @@ -765,323 +765,329 @@ endobj << /S /GoTo /D (subsubsection.6.3.5.1) >> endobj 516 0 obj -(6.3.5.1 The \044ORIGIN Directive) +(6.3.5.1 The @ \(at-sign\)) endobj 517 0 obj << /S /GoTo /D (subsubsection.6.3.5.2) >> endobj 520 0 obj -(6.3.5.2 The \044INCLUDE Directive) +(6.3.5.2 The \044ORIGIN Directive) endobj 521 0 obj << /S /GoTo /D (subsubsection.6.3.5.3) >> endobj 524 0 obj -(6.3.5.3 The \044TTL Directive) +(6.3.5.3 The \044INCLUDE Directive) endobj 525 0 obj -<< /S /GoTo /D (subsection.6.3.6) >> +<< /S /GoTo /D (subsubsection.6.3.5.4) >> endobj 528 0 obj -(6.3.6 BIND Master File Extension: the \044GENERATE Directive) +(6.3.5.4 The \044TTL Directive) endobj 529 0 obj -<< /S /GoTo /D (subsection.6.3.7) >> +<< /S /GoTo /D (subsection.6.3.6) >> endobj 532 0 obj -(6.3.7 Additional File Formats) +(6.3.6 BIND Master File Extension: the \044GENERATE Directive) endobj 533 0 obj -<< /S /GoTo /D (section.6.4) >> +<< /S /GoTo /D (subsection.6.3.7) >> endobj 536 0 obj -(6.4 BIND9 Statistics) +(6.3.7 Additional File Formats) endobj 537 0 obj -<< /S /GoTo /D (subsubsection.6.4.0.1) >> +<< /S /GoTo /D (section.6.4) >> endobj 540 0 obj -(6.4.0.1 The Statistics File) +(6.4 BIND9 Statistics) endobj 541 0 obj -<< /S /GoTo /D (subsection.6.4.1) >> +<< /S /GoTo /D (subsubsection.6.4.0.1) >> endobj 544 0 obj -(6.4.1 Statistics Counters) +(6.4.0.1 The Statistics File) endobj 545 0 obj -<< /S /GoTo /D (subsubsection.6.4.1.1) >> +<< /S /GoTo /D (subsection.6.4.1) >> endobj 548 0 obj -(6.4.1.1 Name Server Statistics Counters) +(6.4.1 Statistics Counters) endobj 549 0 obj -<< /S /GoTo /D (subsubsection.6.4.1.2) >> +<< /S /GoTo /D (subsubsection.6.4.1.1) >> endobj 552 0 obj -(6.4.1.2 Zone Maintenance Statistics Counters) +(6.4.1.1 Name Server Statistics Counters) endobj 553 0 obj -<< /S /GoTo /D (subsubsection.6.4.1.3) >> +<< /S /GoTo /D (subsubsection.6.4.1.2) >> endobj 556 0 obj -(6.4.1.3 Resolver Statistics Counters) +(6.4.1.2 Zone Maintenance Statistics Counters) endobj 557 0 obj -<< /S /GoTo /D (subsubsection.6.4.1.4) >> +<< /S /GoTo /D (subsubsection.6.4.1.3) >> endobj 560 0 obj -(6.4.1.4 Socket I/O Statistics Counters) +(6.4.1.3 Resolver Statistics Counters) endobj 561 0 obj -<< /S /GoTo /D (subsubsection.6.4.1.5) >> +<< /S /GoTo /D (subsubsection.6.4.1.4) >> endobj 564 0 obj -(6.4.1.5 Compatibility with BIND 8 Counters) +(6.4.1.4 Socket I/O Statistics Counters) endobj 565 0 obj -<< /S /GoTo /D (chapter.7) >> +<< /S /GoTo /D (subsubsection.6.4.1.5) >> endobj 568 0 obj -(7 BIND 9 Security Considerations) +(6.4.1.5 Compatibility with BIND 8 Counters) endobj 569 0 obj -<< /S /GoTo /D (section.7.1) >> +<< /S /GoTo /D (chapter.7) >> endobj 572 0 obj -(7.1 Access Control Lists) +(7 BIND 9 Security Considerations) endobj 573 0 obj -<< /S /GoTo /D (section.7.2) >> +<< /S /GoTo /D (section.7.1) >> endobj 576 0 obj -(7.2 Chroot and Setuid) +(7.1 Access Control Lists) endobj 577 0 obj -<< /S /GoTo /D (subsection.7.2.1) >> +<< /S /GoTo /D (section.7.2) >> endobj 580 0 obj -(7.2.1 The chroot Environment) +(7.2 Chroot and Setuid) endobj 581 0 obj -<< /S /GoTo /D (subsection.7.2.2) >> +<< /S /GoTo /D (subsection.7.2.1) >> endobj 584 0 obj -(7.2.2 Using the setuid Function) +(7.2.1 The chroot Environment) endobj 585 0 obj -<< /S /GoTo /D (section.7.3) >> +<< /S /GoTo /D (subsection.7.2.2) >> endobj 588 0 obj -(7.3 Dynamic Update Security) +(7.2.2 Using the setuid Function) endobj 589 0 obj -<< /S /GoTo /D (chapter.8) >> +<< /S /GoTo /D (section.7.3) >> endobj 592 0 obj -(8 Troubleshooting) +(7.3 Dynamic Update Security) endobj 593 0 obj -<< /S /GoTo /D (section.8.1) >> +<< /S /GoTo /D (chapter.8) >> endobj 596 0 obj -(8.1 Common Problems) +(8 Troubleshooting) endobj 597 0 obj -<< /S /GoTo /D (subsection.8.1.1) >> +<< /S /GoTo /D (section.8.1) >> endobj 600 0 obj -(8.1.1 It's not working; how can I figure out what's wrong?) +(8.1 Common Problems) endobj 601 0 obj -<< /S /GoTo /D (section.8.2) >> +<< /S /GoTo /D (subsection.8.1.1) >> endobj 604 0 obj -(8.2 Incrementing and Changing the Serial Number) +(8.1.1 It's not working; how can I figure out what's wrong?) endobj 605 0 obj -<< /S /GoTo /D (section.8.3) >> +<< /S /GoTo /D (section.8.2) >> endobj 608 0 obj -(8.3 Where Can I Get Help?) +(8.2 Incrementing and Changing the Serial Number) endobj 609 0 obj -<< /S /GoTo /D (appendix.A) >> +<< /S /GoTo /D (section.8.3) >> endobj 612 0 obj -(A Appendices) +(8.3 Where Can I Get Help?) endobj 613 0 obj -<< /S /GoTo /D (section.A.1) >> +<< /S /GoTo /D (appendix.A) >> endobj 616 0 obj -(A.1 Acknowledgments) +(A Appendices) endobj 617 0 obj -<< /S /GoTo /D (subsection.A.1.1) >> +<< /S /GoTo /D (section.A.1) >> endobj 620 0 obj -(A.1.1 A Brief History of the DNS and BIND) +(A.1 Acknowledgments) endobj 621 0 obj -<< /S /GoTo /D (section.A.2) >> +<< /S /GoTo /D (subsection.A.1.1) >> endobj 624 0 obj -(A.2 General DNS Reference Information) +(A.1.1 A Brief History of the DNS and BIND) endobj 625 0 obj -<< /S /GoTo /D (subsection.A.2.1) >> +<< /S /GoTo /D (section.A.2) >> endobj 628 0 obj -(A.2.1 IPv6 addresses \(AAAA\)) +(A.2 General DNS Reference Information) endobj 629 0 obj -<< /S /GoTo /D (section.A.3) >> +<< /S /GoTo /D (subsection.A.2.1) >> endobj 632 0 obj -(A.3 Bibliography \(and Suggested Reading\)) +(A.2.1 IPv6 addresses \(AAAA\)) endobj 633 0 obj -<< /S /GoTo /D (subsection.A.3.1) >> +<< /S /GoTo /D (section.A.3) >> endobj 636 0 obj -(A.3.1 Request for Comments \(RFCs\)) +(A.3 Bibliography \(and Suggested Reading\)) endobj 637 0 obj -<< /S /GoTo /D (subsection.A.3.2) >> +<< /S /GoTo /D (subsection.A.3.1) >> endobj 640 0 obj -(A.3.2 Internet Drafts) +(A.3.1 Request for Comments \(RFCs\)) endobj 641 0 obj -<< /S /GoTo /D (subsection.A.3.3) >> +<< /S /GoTo /D (subsection.A.3.2) >> endobj 644 0 obj -(A.3.3 Other Documents About BIND) +(A.3.2 Internet Drafts) endobj 645 0 obj -<< /S /GoTo /D (appendix.B) >> +<< /S /GoTo /D (subsection.A.3.3) >> endobj 648 0 obj -(B Manual pages) +(A.3.3 Other Documents About BIND) endobj 649 0 obj -<< /S /GoTo /D (section.B.1) >> +<< /S /GoTo /D (appendix.B) >> endobj 652 0 obj -(B.1 dig) +(B Manual pages) endobj 653 0 obj -<< /S /GoTo /D (section.B.2) >> +<< /S /GoTo /D (section.B.1) >> endobj 656 0 obj -(B.2 host) +(B.1 dig) endobj 657 0 obj -<< /S /GoTo /D (section.B.3) >> +<< /S /GoTo /D (section.B.2) >> endobj 660 0 obj -(B.3 dnssec-dsfromkey) +(B.2 host) endobj 661 0 obj -<< /S /GoTo /D (section.B.4) >> +<< /S /GoTo /D (section.B.3) >> endobj 664 0 obj -(B.4 dnssec-keyfromlabel) +(B.3 dnssec-dsfromkey) endobj 665 0 obj -<< /S /GoTo /D (section.B.5) >> +<< /S /GoTo /D (section.B.4) >> endobj 668 0 obj -(B.5 dnssec-keygen) +(B.4 dnssec-keyfromlabel) endobj 669 0 obj -<< /S /GoTo /D (section.B.6) >> +<< /S /GoTo /D (section.B.5) >> endobj 672 0 obj -(B.6 dnssec-signzone) +(B.5 dnssec-keygen) endobj 673 0 obj -<< /S /GoTo /D (section.B.7) >> +<< /S /GoTo /D (section.B.6) >> endobj 676 0 obj -(B.7 named-checkconf) +(B.6 dnssec-signzone) endobj 677 0 obj -<< /S /GoTo /D (section.B.8) >> +<< /S /GoTo /D (section.B.7) >> endobj 680 0 obj -(B.8 named-checkzone) +(B.7 named-checkconf) endobj 681 0 obj -<< /S /GoTo /D (section.B.9) >> +<< /S /GoTo /D (section.B.8) >> endobj 684 0 obj -(B.9 named) +(B.8 named-checkzone) endobj 685 0 obj -<< /S /GoTo /D (section.B.10) >> +<< /S /GoTo /D (section.B.9) >> endobj 688 0 obj -(B.10 nsupdate) +(B.9 named) endobj 689 0 obj -<< /S /GoTo /D (section.B.11) >> +<< /S /GoTo /D (section.B.10) >> endobj 692 0 obj -(B.11 rndc) +(B.10 nsupdate) endobj 693 0 obj -<< /S /GoTo /D (section.B.12) >> +<< /S /GoTo /D (section.B.11) >> endobj 696 0 obj -(B.12 rndc.conf) +(B.11 rndc) endobj 697 0 obj -<< /S /GoTo /D (section.B.13) >> +<< /S /GoTo /D (section.B.12) >> endobj 700 0 obj -(B.13 rndc-confgen) +(B.12 rndc.conf) endobj 701 0 obj -<< /S /GoTo /D [702 0 R /FitH ] >> +<< /S /GoTo /D (section.B.13) >> endobj -705 0 obj << +704 0 obj +(B.13 rndc-confgen) +endobj +705 0 obj +<< /S /GoTo /D [706 0 R /FitH ] >> +endobj +709 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚÁJA †ïó9¶‡M'™d2s´T¥‚Beoâai·Rp·t­ïïÔÕ*êArÉÿ‘ü /A}È–ՓºsžŠvíèƒ ¨B)þP+!ÃlQ¡bJÕÂwìNì1úÈP©)&>áóÚÍ®˜€-A½bEM¦pæêÍÃd¾¼[L+V?ÉcºØt»~÷ršã~[÷í¶Ú~ÝNë a¤(±øË˜’å÷9·MÿÚ<ŸwYŸÝQ DËr;yƒ|ê~üÁÁýhÌ–ÁbïVV_§æŒlåP}&ûÿsßC+WDendstream endobj -702 0 obj << +706 0 obj << /Type /Page -/Contents 705 0 R -/Resources 704 0 R +/Contents 709 0 R +/Resources 708 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 711 0 R +/Parent 715 0 R >> endobj -703 0 obj << +707 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./isc-logo.pdf) /PTEX.PageNumber 1 -/PTEX.InfoDict 712 0 R +/PTEX.InfoDict 716 0 R /Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] /BBox [0.00000000 0.00000000 255.00000000 149.00000000] /Resources << /ProcSet [ /PDF /Text ] /ColorSpace << -/R15 713 0 R -/R9 714 0 R -/R11 715 0 R -/R13 716 0 R +/R15 717 0 R +/R9 718 0 R +/R11 719 0 R +/R13 720 0 R >>/ExtGState << -/R17 717 0 R -/R8 718 0 R ->>/Font << /R19 719 0 R >> +/R17 721 0 R +/R8 722 0 R +>>/Font << /R19 723 0 R >> >> -/Length 720 0 R +/Length 724 0 R /Filter /FlateDecode >> stream @@ -1097,7 +1103,7 @@ x FÑÞIca­Ç0Ú) ¹A¿+ÇÀº ¸|-Tuùa>‚s:½¯•~K“ÒÞV׋„OÒAŠI… ɪÁr2Q“°Ø¨Á>.zÎCN’¦{Õ«'^5Mã»Åûæ¡æÔÊý¹U1z6õßvãpF)ÂÏåìÊ›C£i#]bÝLkS#ˆQÁŽv–¨Ô­«•ÇcHŸ$¬Áê³DI­ÌÑptÅ73*_åª'ŽÚ¿¢ÚòQŒ×è Œ‚,É*Ñ+ôÚ™%vŽ&u߉ xœÉ-¾kz˜ Ï‡Ú Q´Pë3ÈZ§q¢Æ0¯ˆwMÍ?©=õ*_Ç£RïÑªëÆ¬¡”’¢g!SeRâÅéz·ÝŠFLÚŸv ÏÆï¤«eÇNdæÌdï"gK2cëÉ—GoOá8GëÏϦ:B Àht[~Ðåõ—×SÒÜ£uˆQk·%È´ÔÛ†ëiATÆÌp[OU‡Ç(zßQã³* *Ñûø®á¾FÅÍ„Ï'µV‡¾;1aŠÑüËŒÜr$¿Íâ9Ë8ˆü ý‚TóþÏÍ÷_oôô¢ññCÙõ"ú*~uÊqæþéïÛ{Ç"ß~±Úú"ú…bùz+·£]OZ,SÏ¥._^·§_\^þ†56g‡3^®Ç5Z©®©¹Uý¶õòÇí÷O¿½<Ó#rYëé»Ë^~¹ÁÇ<ц®5%¥Ü~ÿñsõ\êídŽ3¼4ü~èé[iþÂÈg óžµ|¥Ïà5³m“XSô7…ÿúáò¬ä>!»Î“O÷hKYð¿þîÇ Ó3/¡úôÃgë¾4EO=öï¦üì“­‡v5”ùÜþû‚ék”ùôñR”Ì¡ÌlöÅ·ß_DÍη„Rf.{úÏåYӎͧÿ^ž©í5¬?ývýüeûMüó?Ò ƒendstream endobj -712 0 obj +716 0 obj << /Producer (AFPL Ghostscript 8.51) /CreationDate (D:20050606145621) @@ -1107,46 +1113,46 @@ endobj /Author (Douglas E. Appelt) >> endobj -713 0 obj -[/Separation/PANTONE#201805#20C/DeviceCMYK 721 0 R] -endobj -714 0 obj -[/Separation/PANTONE#207506#20C/DeviceCMYK 722 0 R] -endobj -715 0 obj -[/Separation/PANTONE#20301#20C/DeviceCMYK 723 0 R] -endobj -716 0 obj -[/Separation/PANTONE#20871#20C/DeviceCMYK 724 0 R] -endobj 717 0 obj +[/Separation/PANTONE#201805#20C/DeviceCMYK 725 0 R] +endobj +718 0 obj +[/Separation/PANTONE#207506#20C/DeviceCMYK 726 0 R] +endobj +719 0 obj +[/Separation/PANTONE#20301#20C/DeviceCMYK 727 0 R] +endobj +720 0 obj +[/Separation/PANTONE#20871#20C/DeviceCMYK 728 0 R] +endobj +721 0 obj << /Type /ExtGState /SA true >> endobj -718 0 obj +722 0 obj << /Type /ExtGState /OPM 1 >> endobj -719 0 obj +723 0 obj << /BaseFont /NVXWCK#2BTrajanPro-Bold -/FontDescriptor 725 0 R +/FontDescriptor 729 0 R /Type /Font /FirstChar 67 /LastChar 136 /Widths [ 800 0 0 0 0 0 452 0 0 0 0 0 0 0 0 0 582 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 841 633 576 686 590 540 923 827 407 760] -/Encoding 726 0 R +/Encoding 730 0 R /Subtype /Type1 >> endobj -720 0 obj +724 0 obj 2362 endobj -721 0 obj +725 0 obj << /Filter /FlateDecode /FunctionType 4 @@ -1157,7 +1163,7 @@ endobj stream xœ«N)-P0PÈ-ÍQH­HÎPsõ, QE¸zFÆ`^-=1°endstream endobj -722 0 obj +726 0 obj << /Filter /FlateDecode /FunctionType 4 @@ -1168,7 +1174,7 @@ endobj stream xœ«N)-P0PÈ-ÍQH­HÎPsõ LÑE ‘D Êk8/«endstream endobj -723 0 obj +727 0 obj << /Filter /FlateDecode /FunctionType 4 @@ -1179,7 +1185,7 @@ endobj stream xœ«N)-P0TÈ-ÍQH­HÎPq ôLLÑD\=C 0¯=D³endstream endobj -724 0 obj +728 0 obj << /Filter /FlateDecode /FunctionType 4 @@ -1190,7 +1196,7 @@ endobj stream xœ«N)-P0Ð365³TÈ-ÍQH­HÎP€Š™X ‹™›#Ä ô -,ŒÀüZ&‹ˆendstream endobj -725 0 obj +729 0 obj << /Type /FontDescriptor /FontName /NVXWCK#2BTrajanPro-Bold @@ -1203,17 +1209,17 @@ endobj /StemV 138 /MissingWidth 500 /CharSet (/Msmall/C/Ysmall/Nsmall/Osmall/Esmall/Rsmall/S/Ssmall/I/Tsmall/Ismall/Usmall) -/FontFile3 727 0 R +/FontFile3 731 0 R >> endobj -726 0 obj +730 0 obj << /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [ 127/Nsmall/Tsmall/Esmall/Rsmall/Ysmall/Ssmall/Msmall/Osmall/Ismall/Usmall] >> endobj -727 0 obj +731 0 obj << /Filter /FlateDecode /Subtype /Type1C @@ -1236,40 +1242,41 @@ x ȼLçÇ<;— *X³«¥×ÛGâ_Y1ETïƒ4ˆÒ-U…_>´üØ¢æ}õï÷v¼ §ádù#¹rÛŸå¥@ÔÁ\5l…hð<8Ús·’?h¹†!-¶‚*JŠ»,\G/Wé9OW—×µ.Ÿ—­€&¨[”ÄIÁÚ´Ó½7ýáÐäKý¡«¨ðúš.cxQn<¼À°üÖëgöõÁúhíY8³¶+oî^÷ë°‹>9p¯“°¥!ÑÚÙ®ŠðK´¢†#©óRÄlxŽJ”ب¬Ò–àá•{ϳwÿaû’ožÇ£ëHõÅâH9”ç/.~å÷Ë »O·Øèv61Bá5*È<6ÞÍ,‡bh‘˜¶ž\Î]Çé#¹#ØÔÍ1Oúñ°Ï¤5oÂ]цÆß4}h˜î0$å,6ü¼”A,¯?/å;Rôcy6Ò½UJ¿§Y½X^é¶ÙÉŸ‡‹º–2¸K|o½Ø”/Ȩ/ƒ( Â2Ð#žNMKðrˆ rœÛf9ËyZ¸Ú}$«Ö õ–©)  h`iÎGàAç÷´€H+Šˆ…Õ&*áX$žèìVŽhª”—›¾÷‡A1Ý£¤œÏ0‰÷—Hi éƒw~I(Áö2;à]¸L ™x4[¡OÜ,¾®ÆûÂQQ°”FdQ“ƒ¢¬„%\î¢Åâ:Ó;ÈÑ”ÌEb1ž’¡ˆÿ§=$¸¥?Iš¿CÐõ3¾C=VÐ'>·¯ôÌÒ+Ü~8 ç#;úÁ_£×á*qň+ô 8®‚ãÆpêŒ_YR”¾d%a ç¡H\eÄõãDf£Ñ¨­ŽR[kφG¸ù/WT®ò•A5”H¥ÛVoo8hnû)¼ÞÃDn…ñëqÌzfåhý&þcQbµXÇß‚çLŽúõ;{²Ðñðué¿ÊÛÙ†-©[SÄ-Û¼ÔyubÜñhüm´œ4^Ë™ ääšLÿQ‹¡endstream endobj -706 0 obj << -/D [702 0 R /XYZ 85.0394 794.5015 null] +710 0 obj << +/D [706 0 R /XYZ 85.0394 794.5015 null] >> endobj -707 0 obj << -/D [702 0 R /XYZ 85.0394 769.5949 null] +711 0 obj << +/D [706 0 R /XYZ 85.0394 769.5949 null] >> endobj -704 0 obj << -/Font << /F21 710 0 R >> -/XObject << /Im1 703 0 R >> +708 0 obj << +/Font << /F21 714 0 R >> +/XObject << /Im1 707 0 R >> /ProcSet [ /PDF /Text ] >> endobj -730 0 obj << +734 0 obj << /Length 1001 /Filter /FlateDecode >> stream -xÚµVM“¢:Ýû+XjU“É_Y҈ʂ8]S3³°»©jÅ'8]ýïß…$"êëÍÔ+¹IŽ÷žsr Ãh¦…,N¹fs™˜˜Úz7ÀÚ ìMDb°¦cĸÓnþ3øùk}ÈÕw˜`D8§Ún`˜ ™cjåm¾S]쪄×Õtƒ:˜ØšÎ ä»KÔ Ú¡ˆRljºmrd1Êôc6ø2#nQK˶šc#Љ£QÙæçÐ+Çâåµýξj&F6æ-5Œ`Ýl|™ã"“N‘mq»õDá~_í%`ÈØ‚(ÆÆÃH§&nB³ ­.´»ÐéB.¢`_çÇ}^‹YúQÕù®¯ÜWå±.N»…]£‘În&þE©¤^3À”4T~v6‘0ŠL˲4Û ÐÜüÔñ3Z¿„ßZN˜ gmó.ëyNÿOÏqç#éBÚ…ì®»å¶~_GÄæ×£kÿ,Œ8µ ¹(ž|fŸë—è[÷,qì.g#g‘wEUå^pªK1žª\êYƒ½#BÈPÎw妨öVVû6EU‹çS-Ö¯…ì¦êFü¶<ªˆàp:ÊJn¿õ«ˆ®Y)OÒÌm.qP 9ux0¸‹:!ˆ›&m¥½æ¢Þ³Ìÿr\Ál$éC»Yþ)6ùF±]Õ*’ÙWÏ埼³AtY;Ý—u±Î¯ôwzW¶öà‡C¾’¢ -¹¿z{kuîÀ!57áR Ô.òªmh\Ì3X#ÖFœQ»…d3_¶Y<ÉžFœÝD®©Iü=ûc1kn®›*D3±Õ¢'‚1D¡Ì%Ø CÈ*‰e/7Ÿ‚l&¢ÄŸºÉX\Ixæ2Ò—”5îÇšÍÅ;ä#/\ŽƒhzU<˜/Â@i¹Ç$žˆqî'Þ 6F¶1tƒ0È~tBvâ†c+v¤e7 ²ÈOS¤8ˆ1’|ýï>ä„g#å×£¤îc(ãIœ¨ª²|ºð½À ”ljïµÕÓ6ºY‚mŒLÎyßO/ŽRÿÛˆAR™Ó»Ó³×õ{»O3·)”¥1hKԦ˰]=»?Iâ¹Ô§Ï +Œà¹xuÆËÔWòDúö ú| )ÁìôAñð¡‘“¾í®½,ˆ£þé‚ì,q{6Eþ4 ¦~äùýJq›¹}Xˆ:„ô\4d2b6Ž—éeM™ÙM‚ôìE¼ÌúTâ+Ú@-ò/(wWã|WÁ ÞÑ6—>z&.üšgîvz&ŸÝš›7‰úc&j¾’î~Œ©zý1¦«jºa#æ8ôþ›ˆ:ðƲٙTû^½!}N™Eï0ÿŸûh~endstream +xÚµV]“¢8}÷Wð¨UM:|å‘FT¦ÀéÚš™[±›ªV\Åéê¿’€¨Û/[[>ä$9Þ{îÉ @4 ?¢™²8åšÍ dbbjëÝk¯°7ÉÁšŽãN³ù÷àço¬m€ôm W?`‚áœj»a2dŒ©•÷A:øÞ†ºØU¯³é†‘aqMgr@Ü%é†lqd[6ÕtÛäÈb”Õì§lð8È·¨¥e[Í6m@¾–•m~½òðy,^ߪÑïì›fbdcÞ(ÃXÖõÆã„‘t + ¹ÝX¢x¿À8Aí%%A½±!QŒ‡‘NM\C³ƒVí:ä-$X `_åÇ}^‰YúyªòÝIL¼r*UqÞ=(îtF0È4ñ/J õꦤV=ð³ÖOÂ(2-ËÃ47¿4¿eë—ô[÷ ³áÔmÞEý7ûéÿi?î,%¤dwÝ-·ÕÇê8"Î0¿¶]ûíM)v4›2Ði9_Ú§Èú%ûÖ=ÓASÒŬËYäÇ]q:å^hªJ1žO¹¬g öŽ!C9ß•›bÛ[Yí7åQàMqªŽÅ˹’5Vo…l¨ÓMý[õ§ÕþS€Ãùx(Orû£¨ÞR¼z¥Ä‚g"åד”îS(ñ$NTV™>]ø^à†ÊãÄ÷ê‰Ý,Aˆ¦FVßL/ŽRÿûTADлÓÖ‹ëä½Ýç™[gÉÒ +KÔé¥Ë°Ym­Ÿ$ñ\§Éµ$ŒàÁxuÀËÔWµ‰ðÍôõ@G‚ÓéƒÒáC'}Ï]5zYGý£…²³ÄíyùÓ0˜ú‘ç÷3ÅMäZ+|P‡ô[4c2b6Ô/ÓË”2°›ikE¼ÌúJâ+Õ ,ò/w×¢½§àOïXë‹Ï雸ð蜹ÛÕ3ùêÊܾJä—3QýÁt÷»LåûÏßeºÊ¦6bŽCᅧ¨ƒ·Y+ªy±Þ‡&§Ì¢w”ÿ¾Èjæendstream endobj -729 0 obj << +733 0 obj << /Type /Page -/Contents 730 0 R -/Resources 728 0 R +/Contents 734 0 R +/Resources 732 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 711 0 R +/Parent 715 0 R >> endobj -731 0 obj << -/D [729 0 R /XYZ 56.6929 794.5015 null] +735 0 obj << +/D [733 0 R /XYZ 56.6929 794.5015 null] >> endobj -728 0 obj << -/Font << /F23 734 0 R /F14 737 0 R >> +732 0 obj << +/Font << /F23 738 0 R /F14 741 0 R >> /ProcSet [ /PDF /Text ] >> endobj -740 0 obj << +744 0 obj << /Length 2891 /Filter /FlateDecode >> @@ -1289,1334 +1296,1337 @@ W M…­æ:h¾nêãô¨ýèá·oðÐkƒh—#öùlk…lMfR,`5("qP,Þ„b‰Ðø˜Ž~]í»=Ãמ,Åzž%húg°º ÁîGÓäm2ƒÅREŽ7XD‚ ˆ \@pÁ,tûµDÀ'/œÕ½ÊýØø@Á_™'Hûd !E–•B*Åéö®ÒŒ‘@aaëêdz¿µÍ:ê°uõÕ¶HA‰©”!;2¬3ÁX$1Ò5–$LCK¢[ÎÂéÌù›ödŽ÷ÇršgľڀŠL% Ù¤a½ Ò"AP‡…r=|Ê?SRxÐRèWywqqvê:ûñÌ7ƒÊ'*SƒVZâï<Ž`¨ðwæ2ciìÈÛÕ÷ Ε[~©‘&Å3çë™SÿÀóøóp%ðö?ž­®Bendstream endobj -739 0 obj << -/Type /Page -/Contents 740 0 R -/Resources 738 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 711 0 R -/Annots [ 743 0 R 744 0 R 745 0 R 746 0 R 747 0 R 748 0 R 749 0 R 750 0 R 751 0 R 752 0 R 753 0 R 754 0 R 755 0 R 756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R 762 0 R 763 0 R 764 0 R 765 0 R 766 0 R 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 774 0 R 775 0 R 776 0 R 777 0 R 778 0 R 779 0 R 780 0 R 781 0 R 782 0 R 783 0 R 784 0 R 785 0 R 786 0 R 787 0 R 788 0 R 789 0 R 790 0 R 791 0 R 792 0 R ] ->> endobj 743 0 obj << +/Type /Page +/Contents 744 0 R +/Resources 742 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 715 0 R +/Annots [ 747 0 R 748 0 R 749 0 R 750 0 R 751 0 R 752 0 R 753 0 R 754 0 R 755 0 R 756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R 762 0 R 763 0 R 764 0 R 765 0 R 766 0 R 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 774 0 R 775 0 R 776 0 R 777 0 R 778 0 R 779 0 R 780 0 R 781 0 R 782 0 R 783 0 R 784 0 R 785 0 R 786 0 R 787 0 R 788 0 R 789 0 R 790 0 R 791 0 R 792 0 R 793 0 R 794 0 R 795 0 R 796 0 R ] +>> endobj +747 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 688.709 539.579 697.2967] /Subtype /Link /A << /S /GoTo /D (chapter.1) >> >> endobj -744 0 obj << +748 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 676.5858 539.579 685.4425] /Subtype /Link /A << /S /GoTo /D (section.1.1) >> >> endobj -745 0 obj << +749 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 664.4876 539.579 673.3442] /Subtype /Link /A << /S /GoTo /D (section.1.2) >> >> endobj -746 0 obj << +750 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 652.3894 539.579 661.246] /Subtype /Link /A << /S /GoTo /D (section.1.3) >> >> endobj -747 0 obj << +751 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 640.1914 539.579 649.1477] /Subtype /Link /A << /S /GoTo /D (section.1.4) >> >> endobj -748 0 obj << +752 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 628.0932 539.579 637.0495] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.1) >> >> endobj -749 0 obj << +753 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 615.995 539.579 624.9512] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.2) >> >> endobj -750 0 obj << +754 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 603.8967 539.579 612.853] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.3) >> >> endobj -751 0 obj << +755 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 591.7985 539.579 600.7547] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.4) >> >> endobj -752 0 obj << +756 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 579.7002 539.579 588.6565] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.4.1) >> >> endobj -753 0 obj << +757 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 567.6019 539.579 576.5582] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.4.2) >> >> endobj -754 0 obj << +758 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 555.5037 539.579 564.46] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.4.3) >> >> endobj -755 0 obj << +759 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 543.4055 539.579 552.5112] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.5) >> >> endobj -756 0 obj << +760 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 531.3072 539.579 540.413] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.5.1) >> >> endobj -757 0 obj << +761 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 519.209 539.579 528.3147] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.6) >> >> endobj -758 0 obj << +762 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 496.7003 539.579 505.4125] /Subtype /Link /A << /S /GoTo /D (chapter.2) >> >> endobj -759 0 obj << +763 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 484.5772 539.579 493.5832] /Subtype /Link /A << /S /GoTo /D (section.2.1) >> >> endobj -760 0 obj << +764 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 472.4789 539.579 481.485] /Subtype /Link /A << /S /GoTo /D (section.2.2) >> >> endobj -761 0 obj << +765 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 460.3806 539.579 469.3867] /Subtype /Link /A << /S /GoTo /D (section.2.3) >> >> endobj -762 0 obj << +766 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 448.2824 539.579 457.2885] /Subtype /Link /A << /S /GoTo /D (section.2.4) >> >> endobj -763 0 obj << +767 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 436.1841 539.579 445.1902] /Subtype /Link /A << /S /GoTo /D (section.2.5) >> >> endobj -764 0 obj << +768 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 413.4314 539.579 422.288] /Subtype /Link /A << /S /GoTo /D (chapter.3) >> >> endobj -765 0 obj << +769 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 401.353 539.579 410.4588] /Subtype /Link /A << /S /GoTo /D (section.3.1) >> >> endobj -766 0 obj << +770 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 389.2548 539.579 398.3605] /Subtype /Link /A << /S /GoTo /D (subsection.3.1.1) >> >> endobj -767 0 obj << +771 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 377.1565 539.579 386.2623] /Subtype /Link /A << /S /GoTo /D (subsection.3.1.2) >> >> endobj -768 0 obj << +772 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 365.1579 539.579 374.164] /Subtype /Link /A << /S /GoTo /D (section.3.2) >> >> endobj -769 0 obj << +773 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 353.0597 539.579 362.0658] /Subtype /Link /A << /S /GoTo /D (section.3.3) >> >> endobj -770 0 obj << +774 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 340.9614 539.579 349.9675] /Subtype /Link /A << /S /GoTo /D (subsection.3.3.1) >> >> endobj -771 0 obj << +775 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 328.7635 539.579 337.8693] /Subtype /Link /A << /S /GoTo /D (subsubsection.3.3.1.1) >> >> endobj -772 0 obj << +776 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 316.6653 539.579 325.771] /Subtype /Link /A << /S /GoTo /D (subsubsection.3.3.1.2) >> >> endobj -773 0 obj << +777 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 304.567 539.579 313.6728] /Subtype /Link /A << /S /GoTo /D (subsection.3.3.2) >> >> endobj -774 0 obj << +778 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 281.9139 539.579 290.7706] /Subtype /Link /A << /S /GoTo /D (chapter.4) >> >> endobj -775 0 obj << +779 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 269.8356 539.579 278.9413] /Subtype /Link /A << /S /GoTo /D (section.4.1) >> >> endobj -776 0 obj << +780 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 257.7373 539.579 266.8431] /Subtype /Link /A << /S /GoTo /D (section.4.2) >> >> endobj -777 0 obj << +781 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 245.6391 539.579 254.7448] /Subtype /Link /A << /S /GoTo /D (subsection.4.2.1) >> >> endobj -778 0 obj << +782 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 233.5408 539.579 242.4971] /Subtype /Link /A << /S /GoTo /D (section.4.3) >> >> endobj -779 0 obj << +783 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 221.4426 539.579 230.3988] /Subtype /Link /A << /S /GoTo /D (section.4.4) >> >> endobj -780 0 obj << +784 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 209.3443 539.579 218.3006] /Subtype /Link /A << /S /GoTo /D (subsection.4.4.1) >> >> endobj -781 0 obj << +785 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 197.2461 539.579 206.2023] /Subtype /Link /A << /S /GoTo /D (section.4.5) >> >> endobj -782 0 obj << +786 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 185.1478 539.579 194.1041] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.1) >> >> endobj -783 0 obj << +787 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 173.0496 539.579 182.0058] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.5.1.1) >> >> endobj -784 0 obj << +788 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 161.051 539.579 170.0571] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.5.1.2) >> >> endobj -785 0 obj << +789 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 148.9527 539.579 157.9588] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.2) >> >> endobj -786 0 obj << +790 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 136.8545 539.579 145.8606] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.3) >> >> endobj -787 0 obj << +791 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 124.7562 539.579 133.7623] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.4) >> >> endobj -788 0 obj << +792 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 112.5583 539.579 121.5146] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.5) >> >> endobj -789 0 obj << +793 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 100.4601 539.579 109.4163] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.6) >> >> endobj -790 0 obj << +794 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 88.3618 539.579 97.3181] /Subtype /Link /A << /S /GoTo /D (section.4.6) >> >> endobj -791 0 obj << +795 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 76.2636 539.579 85.2199] /Subtype /Link /A << /S /GoTo /D (section.4.7) >> >> endobj -792 0 obj << +796 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 64.1653 539.579 73.1216] /Subtype /Link /A << /S /GoTo /D (section.4.8) >> >> endobj -741 0 obj << -/D [739 0 R /XYZ 85.0394 794.5015 null] +745 0 obj << +/D [743 0 R /XYZ 85.0394 794.5015 null] +>> endobj +746 0 obj << +/D [743 0 R /XYZ 85.0394 711.9273 null] >> endobj 742 0 obj << -/D [739 0 R /XYZ 85.0394 711.9273 null] ->> endobj -738 0 obj << -/Font << /F21 710 0 R /F23 734 0 R >> +/Font << /F21 714 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -795 0 obj << -/Length 3159 +799 0 obj << +/Length 3161 /Filter /FlateDecode >> stream -xÚí[wÛ¸Çßý)ôh?Åýò˜ûɶM²±÷¥Û}`dÆÖ‰$z%9©ûé Š8´À‘ÐÆili÷ìÚ‰9œñüÂ`@d#êÿe#¥‰vÜŒ“DQ¦F“ù ]ùŸ½9aí1ãpÐõüâä/¯…9â4×£‹Ï#©ájs2K¨µltqùûé‹÷ï.^½»8?ûãâ—“Wñ¬Ð3£¢>åŸ'¿ÿAG—>€_N(ΪÑ7ÿJ˜s|4?‘J%…3;9?ù5žütcšüM%\hžøU¸¿JýCÅFF9¢…ÿIý‹Hb ;3Néé›rQ.‹õtqu6択þµ¼[­æ§äl¬üï‹tî»ì¾ÔÔgÝÝåsK›åÕ¨ùæ#T+Ø¡á¶ZÛç¯õâz+Ž ~*ŒÔ{`E¢)Õ‘Þ²r>½ZDPÖ×eóÍ?ª…ÿÎP}$%&d5›`ˆUÈIăzÄE”¶.#Zb^T‹Rʯn—‘›órùµ\Öc ‡ŠÊ #!ÙŒCŒ¨7ÃŒ$âÀA½æ‡íË#÷UMÞBâ<"ÔóðöÃWÝ’q{sS-×ͦ‹æëó·ï^6ßyÇÙãd~@!ÇÙC ¨!·Ã%âÀB½‡A†1?ÏQ¡,¹8…yvy¹Ï«jæ§ÃÙ |ûe $âÞ:ï&kn8kàtX¶¶¼¦*©ÖŠ0Él“­Í8XWÒ˜¯áô´?þ´,–w¾œJù”Kæ !}ÙŸ$`ˆ}’ <‰806Pï‘ %c”·lð–·‹®u+RT¼,Êyå']Ψƒ›U ’’™M -0ÄHba¤$âÀHÙòžs%–ºSÝŽ¹[Cm×Áëiµä|.—åbRg.œ|ïñ`ã- Z°áŒÓa™ÚòšüL1KŒiWuo“©y= s‹W³r^.Ö~¢˜9Ô~eÒìO0Ä>YP2Œ“D/¨÷0i¥š©UÀe¸Qù{±ž\‡¢¼ªQц{Ú{¨„tf£ 1T \‚£’ˆCõθ&R09Räí`Ùà"êõ»Åºø×ÙX8u\ZÝ”˜Ê\P !JO*”T(¸÷ˉ¶‚Px Ê˲®C‹iW…ŠÅeè{‹«zuþg˜éÿˆUö˜¥l€!ÆTAˆaq`  ÞÛº¢ %Zy<®²Ïë™F»ŠÚŽʚ㨢Ò™ -0ÄPra¨$âÀPA½wÃ…²D3g:XŽuå¿%¤2`ˆ¥Â@IÄ‚zï@‘š(Û57”c]Ùf d)›`ˆ1Ur˜D¨÷Ðß*Q - ߯¿}³,æó¢^=2âØÞÞÃ%d4`ˆáÃpIÄá‚zÓΉâ2T–º®x÷÷l#ÖRéÔG“Y{LoR„3nÛcÎןì¦1‘.Ãí±Ž9Ïæ b?{Ltþ?»¬¾[Ãr™Í 0Ä8Zaœ$âÀ8A½Ç«L’r©q€”úz¤m·-oC£©ïªe˜õN®‹Å¢L­úùAN*¥Ûã>\/‹•gA ~X³šÞlx€!”O ߊƒõáÎÃb@;UŸ ?\UËÔLGR¢­¹¤ö *TLo.<Ч'Ÿ¤ƒð¤â@àÁ½wðK˜”°FÕ·§î ÏŸ·åòn\.—Õ2µø§,q҆ſ4/´Ô r2™Í 0Ä8JÉáýu©80NPïíLÆ÷ê„1êÓ³oË2Å÷ó˜8¨ Mƒ¹Ò|}<¦;%`ˆ¡åÄPJÄ¡„z()I¨e¼C‰?J»gÄ’¹'T¥BZ³‘†2P69¼ +† ê= #9¡Ò©™ÝW4çÅj]&kRÝGI§wöáú°f9!ÇÙüCŒ¨!ÆO"ŒÔ{àGÔsØ]ɇâgŸ>Ü=æ><æ2›`ˆqµÂ8IÄq‚zœ0CœÕ 4í¾¤YÝÔR¯Ò¦¬w¹ó’&;¬©MÈq6?Àãjˆñ“ˆãõø¡Š8%AÒÅÏ>6壮G!—ÙœCŒ¨•¾°™Šãõ»nîqœ[@JXï{^U³²hE}ßÒ1VÂðUɘ®\ !CO9¼~—Š÷ÞÁ`ýˆà`G¤ÃúÝëjù­hžÄ³y<¤üxûÉ=6Bö²Ù†P5\PRq`l Þ;6´#VÁÖG‡å¹—·Ål¼Z“/÷ž'~¾[Û~È R• 0Ä@€R` $âÀ@@½w (C,7½Š!žM&ñ–ùõFÌz¼¨fuÑ8Þß%. `ˆa…Á°HÄazï°Š§ÄB5X¼]øösáÙ8kÊŽ·¹¦ñ ÌÆbx@ÔðFîT¨÷!ˆÑ½Ž„è_ë+7íƒÿàƒ7„1G*bÞ²©†PŒŠD¨÷Ž -ΈýîÃ4T4O+®¡¸8sôtY,VŸ7“ -eØ‹˜¸l,€!†F oBIÅazï° ŽÊzµÄ6XüöòCCŇøÚö‰Øg'åò™M -0ÄPéé5ü@¥T,¨÷Ž&ˆ”÷:ÝÐòüv:[ÃëpV _™.>o^_wHü»ZÔkáÆ¸G¹s&f![c`ˆiÜËòðšd*LcÔ{§1eD2ݓؤ$~5¿Yßu¯V«/nüDKPÛ‚´9Ê ³Ãô‡ - oˆI©¹Žâ[G„•¢'¾mÄvy¹ÙäTÌÂUîI÷‰~QL®7uÂiýtdÙÈ•Ø!2÷r=¼Äœ‘u^PeˆP|Âw?ΡÎõŒè÷Rsó”' -ƒo¼jý«Î{ß”yÝÕvØÛ®0×Ὂšû@øìó,¼§Ðs¶ùÌwK0CßÜÒi…¼+k+‚-Dâ»~ÇÜyi“/,ñÿ1â”âÿû«…»7 ËúÖ";°=‹[J\ýÖ.á篢½s¹%fsˆü?ìÑTÿendstream +xÚí[wÛ¸Çßý)ôh?Åýò˜ûɶM²±÷¥Û}`dÆÖ‰$z%9©ûé Š8´À‘ÐÆili÷ìÚ‰9œñüÂ`@d#êÿe#¥‰vÜŒ“DQ¦F“ù ]ùŸ½9aí1ãpÐõüâä/¯…9â4×£‹Ï#©ájs2K¨µltqùûé‹÷ï.^½»8?ûãâ—“Wñ¬Ð3£¢>åŸ'¿ÿAG—>€_N(ΪÑ7ÿJ˜s|4?‘J%…3;9?ù5žütcšüM%\hžøU¸¿JýCÅFF9¢…ÿIý‹Hb ;3Néé›rQ.‹õtqu6択þµ¼[­æ§äl¬üï‹tî»ì¾ÔÔgÝÝåsK›åÕ¨ùæ#T+Ø¡á¶ZÛç¯õâz+Ž ~*ŒÔ{`E¢)Õ‘Þ²r>½ZDPÖ×eóÍ?ª…ÿÎP}$%&d5›`ˆUÈIăzÄE”¶.#Zb^T‹Rʯn—‘›órùµ\Öc ‡ŠÊ #!ÙŒCŒ¨7ÃŒ$âÀA½æ‡íË#÷UMÞBâ<"ÔóðöÃWÝ’q{sS-×ͦ‹æëó·ï^6ßyÇÙãd~@!ÇÙC ¨!·Ã%âÀB½‡A†1?ÏQ¡,¹8…yvy¹¤ùºj¾¾+æ%NÁ»é§O³ö˜×Õr^lF÷³ËS‘+34Dd9"ó¶w½·­“6†0_F6ÎU]|.. ³W6ÒN¯®×ßÊúÿáó¼ªf~Z1œ½àÀ‡±_Ö€A"î­óÖ 6œ5p:,[[^S•TkE˜d¶ÉÖf¬+iÌ×pzÚZË;_N¥|Ê%s…¾ìO0Ä>IPŒ‰D¨÷Ȇ„1Ê[6xËÆÇÛE׺)*^å¼ò“.gÔÁͪI ÉÌ&b¤@±0Rq`¤lyO޹‚K]ƒ©nÇÜ­¡¶ëàŠõ´Zr>—Ër1)‡3N¾÷x °ñ-ÄpÆÀé°LmyM~¦˜%Æ´«€:Ž·ÉÔ¼ž†¹Å«Y9/k?QÌj¿2ÈGHiö' bŸ,(ÆI"ŒÔ{˜´RMŒÔ*à2ܨü½XO®CQ^Õ¨hÃ=í=TB:³Q†*P.!‡QIÄ¡‚zg\)˜)aÒv°lpõzÈÝb]üël,œ:.­îJLe.(Ð¥'J*Ü{ŠåD[Á(¼åeYסŴ«BÅâ2ô½ÅU½:ÿ3ÌôÄ*{ÌR6Àcª Ô0‰80Pïm]Q†­< +WÙçõL£]EmG eÍqÔ@Q éÌFb¨@¹0Tq`¨ Þ»áBY¢™3,Ǻòß‚R™ +0Ä@Ra $âÀ@A½w HM”íšʱ®l3²”Í0Ä€*ˆá«·©80Pï¡¿U¢.0:¾_ûfYÌçE½zdı½½‡KÈh6.ÀÃ*†á’ˆÃõ¦!œÅe¨,u]ñîï-ØF¬¥Ò;¨*&³ö˜Þ¤gܶǜ¯‹uÙMc"]†ÛcsžÍ0Äx‚šŠá©80žPï'¸t"âħݥÌ:öô†¡6µÙÔtv4@8Œ™í 0d0×-1ÒY"ul„8;‘™T‹õ²š­ÜG(|Ç0¤¬{’ÃÐ:1ǹì@Cžž†=©8|pïëç¾ÜuL>?{L¡ ¸ rr™Í 0Ä8Z‰áG©80NPï#ë Øµ“éb2»½,S”hbÛ5Ù±ŒÔ<9d8žÎc臡³Fæ:€£}MÒº›Óè‡"g÷øò£¯ççÍ1•ÙˆCŒ(I"ŒÔ{ÀDQ"è¤ÌNL¾”w©©¯/AΊƒ‹ö¸êsžÍ0Äx‚šŠámt©80žPï'a‰ Ý¨c§Ý#Ž¢O¯“ +©Í¦¦³Ã ÂaÌl!ƒ¹Äpωa2n'2³êêªÞI–(TÆyNíZÏQò vÆg£ 1v „<‰80zPï&ýáNwKô¡øÙc¢óÿÙeõÝîËlN€!Æ Ô +ã$Æ ê=^e’”N¤Ô×#m»myM}W-ìwr],ejÕÏrR)Ý÷ázY¬< ZðÚՄôfà 1x |’ÓˆƒõáÎÃb@;UŸ ?\UËÔLGR¢­¹¤ö *TLo.<Ч'Ÿäƒð¤â@àÁ½wðK˜”°FÕ·§î ÏŸ·åòn\.—Õ2µø§,q҆ſ4/´Ô r2™Í 0Ä8JÉáýu©80NPïíLÆ÷ê„1êÓ³oË2Å÷ó˜8¨ Mƒ¹Ò|}<¦;%`ˆ¡åÄPJÄ¡„z()I¨e¼C‰?J»gÄ’¹'T¥BZ³‘†2P69¼ +† ê= #9¡Ò©™ÝW4çÅj]&kRÝGI§wöáú°f9!ÇÙüCŒ¨!ÆO"ŒÔ{àGÔsØ]ɇâgŸ>Ü=æ><æ2›`ˆqµÂ8IÄq‚zœ0CœÕ 4í¾¤YÝÔR¯Ò¦¬w¹ó’&;¬©MÈq6?Àãjˆñ“ˆãõø¡Š8%AÒÅÏ>6壮G!—ÙœCŒ¨•¾°™Šãõ»nîqœ[@JXï{^U³²hE}ßÒ1VÂðUɘ®\ !CO5¼~—Š÷ÞÁ`ýˆà`G¤ÃúÝëjù­hžÄ³y<¤üxûÉ=6Bö²Ù†P5\PRq`l Þ;6´#VÁÖG‡å¹—·Ål¼Z“/÷ž'~¾[Û~È R• 0Ä@€R` $âÀ@@½w (C,7½Š!žM&ñ–ùõFÌz¼¨fuÑ8Þß%. `ˆa…Á°HÄazï°Š§ÄB5X¼]øösáÙ8kÊŽ·¹¦ñ ÌÆbx@ÔðFîT¨÷!ˆÑ½Ž„è_ë+7íƒÿàƒ7„1G*bÞ²©†P5Ü}¤âÀ¨@½wTpFŒèw¦¡¢yZq ÅÅ™£§Ëb±ú¼™T(ÃŽXÄÄec 1, 0jxJ* Ô{‡uÄPÖ«%¶Áâ·—*>Ä'жOäQò8\t™Ëæb\ô”~Z*Œ Ô{ä‚9C´vrá.ÞßôžŽ~·Z—óîñy·›²2‰Ï]œOkd¬TkÍ2& W^hˆÈÛO𰼩8yqï¼Ví«~o-Šú‰@ì)w j˜~âMDÌQ6À# §Áð T¨÷Ž#ˆ¦ý&‚±†€årZ]N'qRÀO‹U»â°é0¾³ú3ý3¬O>,!IÙC žÃäKÅ!€zïÐŒ(#{c<ã Ñ«›jV]ù†Ás|NšÃlB€!FHO#„D!¨÷Ž鈒¼_&DKÈ;W~æ8ósÆÔ•.I(gnûJ—°ê0n'ÉÍFbèôÄÞð•ŠCõÞ¡# Qý¾‚ɆœWeÛP¼o®s”á](Ç»ñbⲩèì0( ,à —‰ 0$0×\iú-S±ÜÐÓÛöqÜú`Ÿ”JÈg6)ÀC¥§×ð•Rq`° Þ;Z˜ RÞëPtCËóÛél=¯ÃY~eºø¼y}EÜ!ñïjQ¯…ãåΙ˜…l!¦q/ËÃk’©80QïÆ”ÉtOb“’øÕüf}×½Z­¾¸ñ-A=l Òæ(€ÎÓ*€È¿¦>æ:ŠoVŠžø¶ÿÙååf“S1 W¹'Ý'úE1¹ÞÔ §õÓ‘9d#Wf`‡ÈÜËõðs"DfÔuxA•!Bqð ßý8‡v8Ot Ô3¢wÞKÍÍSž( ¾ñªMtö ¯:;ì}W@F3¼U*ö¶+Ìuxo€"‚ƒ&Â>>û< ï)ôœm>óßÝÌÐ7·D­F¶#ØB$¾ëwÌ—6ùÂÿ#N)þ¿¿Z¸{²¬o-²Û³¸¥ÄÕoí~þ*Ú;7‘[b6Èÿî¥Uendstream endobj -794 0 obj << +798 0 obj << /Type /Page -/Contents 795 0 R -/Resources 793 0 R +/Contents 799 0 R +/Resources 797 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 711 0 R -/Annots [ 800 0 R 801 0 R 802 0 R 803 0 R 804 0 R 805 0 R 806 0 R 807 0 R 808 0 R 809 0 R 810 0 R 811 0 R 812 0 R 813 0 R 814 0 R 815 0 R 816 0 R 817 0 R 818 0 R 819 0 R 820 0 R 821 0 R 822 0 R 823 0 R 824 0 R 825 0 R 826 0 R 827 0 R 828 0 R 829 0 R 830 0 R 831 0 R 832 0 R 833 0 R 834 0 R 835 0 R 836 0 R 837 0 R 838 0 R 839 0 R 840 0 R 841 0 R 842 0 R 843 0 R 844 0 R 845 0 R 846 0 R 847 0 R 848 0 R 849 0 R 850 0 R 851 0 R 852 0 R 853 0 R 854 0 R 855 0 R 856 0 R ] +/Parent 715 0 R +/Annots [ 804 0 R 805 0 R 806 0 R 807 0 R 808 0 R 809 0 R 810 0 R 811 0 R 812 0 R 813 0 R 814 0 R 815 0 R 816 0 R 817 0 R 818 0 R 819 0 R 820 0 R 821 0 R 822 0 R 823 0 R 824 0 R 825 0 R 826 0 R 827 0 R 828 0 R 829 0 R 830 0 R 831 0 R 832 0 R 833 0 R 834 0 R 835 0 R 836 0 R 837 0 R 838 0 R 839 0 R 840 0 R 841 0 R 842 0 R 843 0 R 844 0 R 845 0 R 846 0 R 847 0 R 848 0 R 849 0 R 850 0 R 851 0 R 852 0 R 853 0 R 854 0 R 855 0 R 856 0 R 857 0 R 858 0 R 859 0 R 860 0 R ] >> endobj -800 0 obj << +804 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 758.4766 511.2325 767.4329] /Subtype /Link /A << /S /GoTo /D (subsection.4.8.1) >> >> endobj -801 0 obj << +805 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 746.445 511.2325 755.4012] /Subtype /Link /A << /S /GoTo /D (subsection.4.8.2) >> >> endobj -802 0 obj << +806 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 734.5129 511.2325 743.3696] /Subtype /Link /A << /S /GoTo /D (subsection.4.8.3) >> >> endobj -803 0 obj << +807 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 722.3816 511.2325 731.3379] /Subtype /Link /A << /S /GoTo /D (section.4.9) >> >> endobj -804 0 obj << +808 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 710.3499 511.2325 719.3062] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.1) >> >> endobj -805 0 obj << +809 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 698.3182 511.2325 707.2745] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.2) >> >> endobj -806 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 675.998 511.2325 684.7301] -/Subtype /Link -/A << /S /GoTo /D (chapter.5) >> ->> endobj -807 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 663.9862 511.2325 672.9425] -/Subtype /Link -/A << /S /GoTo /D (section.5.1) >> ->> endobj -808 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 651.9545 511.2325 660.9108] -/Subtype /Link -/A << /S /GoTo /D (section.5.2) >> ->> endobj -809 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 629.6343 511.2325 638.4909] -/Subtype /Link -/A << /S /GoTo /D (chapter.6) >> ->> endobj 810 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 617.6225 511.2325 626.7282] +/Rect [499.2773 675.998 511.2325 684.8547] /Subtype /Link -/A << /S /GoTo /D (section.6.1) >> +/A << /S /GoTo /D (chapter.5) >> >> endobj 811 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 605.5908 511.2325 614.5471] +/Rect [499.2773 663.9862 511.2325 673.0919] /Subtype /Link -/A << /S /GoTo /D (subsection.6.1.1) >> +/A << /S /GoTo /D (section.5.1) >> >> endobj 812 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 593.5591 511.2325 602.5154] +/Rect [499.2773 651.9545 511.2325 661.0603] +/Subtype /Link +/A << /S /GoTo /D (section.5.2) >> +>> endobj +813 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [499.2773 629.6343 511.2325 638.3664] +/Subtype /Link +/A << /S /GoTo /D (chapter.6) >> +>> endobj +814 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [499.2773 617.6225 511.2325 626.5788] +/Subtype /Link +/A << /S /GoTo /D (section.6.1) >> +>> endobj +815 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [499.2773 605.5908 511.2325 614.6966] +/Subtype /Link +/A << /S /GoTo /D (subsection.6.1.1) >> +>> endobj +816 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [499.2773 593.5591 511.2325 602.6649] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.1.1) >> >> endobj -813 0 obj << +817 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 581.5275 511.2325 590.4837] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.1.2) >> >> endobj -814 0 obj << +818 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 569.4958 511.2325 578.4521] /Subtype /Link /A << /S /GoTo /D (subsection.6.1.2) >> >> endobj -815 0 obj << +819 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 557.4641 511.2325 566.4204] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.2.1) >> >> endobj -816 0 obj << +820 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 545.4324 511.2325 554.5382] +/Rect [499.2773 545.4324 511.2325 554.3887] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.2.2) >> >> endobj -817 0 obj << +821 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 533.4007 511.2325 542.5065] +/Rect [499.2773 533.4007 511.2325 542.357] /Subtype /Link /A << /S /GoTo /D (section.6.2) >> >> endobj -818 0 obj << +822 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 521.3691 511.2325 530.3254] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.1) >> >> endobj -819 0 obj << +823 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 509.3374 511.2325 518.2937] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.2) >> >> endobj -820 0 obj << +824 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 497.3057 511.2325 506.262] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.3) >> >> endobj -821 0 obj << +825 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 485.274 511.2325 494.2303] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.4) >> >> endobj -822 0 obj << +826 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 473.2424 511.2325 482.1986] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.5) >> >> endobj -823 0 obj << +827 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 461.2107 511.2325 470.167] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.6) >> >> endobj -824 0 obj << +828 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 449.179 511.2325 458.1353] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.7) >> >> endobj -825 0 obj << +829 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 437.1473 511.2325 446.1036] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.8) >> >> endobj -826 0 obj << +830 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 425.1157 511.2325 434.0719] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.9) >> >> endobj -827 0 obj << +831 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 413.084 511.2325 422.0403] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.10) >> >> endobj -828 0 obj << +832 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 401.0523 511.2325 410.0086] +/Rect [499.2773 401.0523 511.2325 410.158] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.10.1) >> >> endobj -829 0 obj << +833 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 389.0206 511.2325 398.1264] +/Rect [499.2773 389.1203 511.2325 398.1264] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.10.2) >> >> endobj -830 0 obj << +834 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 377.0886 511.2325 386.0947] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.10.3) >> >> endobj -831 0 obj << +835 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 365.0569 511.2325 374.063] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.11) >> >> endobj -832 0 obj << +836 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 352.9256 511.2325 362.0313] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.12) >> >> endobj -833 0 obj << +837 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 340.8939 511.2325 349.9997] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.13) >> >> endobj -834 0 obj << +838 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 328.8622 511.2325 337.968] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.14) >> >> endobj -835 0 obj << +839 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 316.8305 511.2325 325.9363] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.15) >> >> endobj -836 0 obj << +840 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 304.7989 511.2325 313.9046] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.16) >> >> endobj -837 0 obj << +841 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 292.7672 511.2325 301.873] +/Rect [499.2773 292.7672 511.2325 301.7235] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.1) >> >> endobj -838 0 obj << +842 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 280.7355 511.2325 289.6918] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.2) >> >> endobj -839 0 obj << +843 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 268.7038 511.2325 277.6601] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.3) >> >> endobj -840 0 obj << +844 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 256.6722 511.2325 265.6285] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.4) >> >> endobj -841 0 obj << +845 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 244.6405 511.2325 253.5968] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.5) >> >> endobj -842 0 obj << +846 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 232.6088 511.2325 241.5651] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.6) >> >> endobj -843 0 obj << +847 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 220.5771 511.2325 229.5334] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.7) >> >> endobj -844 0 obj << +848 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 208.5455 511.2325 217.5017] +/Rect [499.2773 208.5455 511.2325 217.6512] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.8) >> >> endobj -845 0 obj << +849 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 196.5138 511.2325 205.4701] +/Rect [499.2773 196.5138 511.2325 205.6195] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.9) >> >> endobj -846 0 obj << +850 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 184.4821 511.2325 193.4384] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.10) >> >> endobj -847 0 obj << +851 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 172.4504 511.2325 181.5562] +/Rect [499.2773 172.4504 511.2325 181.4067] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.11) >> >> endobj -848 0 obj << +852 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 160.4187 511.2325 169.5245] +/Rect [499.2773 160.4187 511.2325 169.375] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.12) >> >> endobj -849 0 obj << +853 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 148.3871 511.2325 157.3433] +/Rect [499.2773 148.3871 511.2325 157.4928] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.13) >> >> endobj -850 0 obj << +854 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 136.3554 511.2325 145.3117] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.14) >> >> endobj -851 0 obj << +855 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 124.3237 511.2325 133.4295] +/Rect [499.2773 124.3237 511.2325 133.28] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.15) >> >> endobj -852 0 obj << +856 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 112.292 511.2325 121.2483] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.16) >> >> endobj -853 0 obj << +857 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 100.2604 511.2325 109.2166] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.17) >> >> endobj -854 0 obj << +858 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 88.2287 511.2325 97.185] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.18) >> >> endobj -855 0 obj << +859 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 76.197 511.2325 85.1533] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.17) >> >> endobj -856 0 obj << +860 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 64.1653 511.2325 73.1216] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.18) >> >> endobj -796 0 obj << -/D [794 0 R /XYZ 56.6929 794.5015 null] +800 0 obj << +/D [798 0 R /XYZ 56.6929 794.5015 null] >> endobj -793 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R >> +797 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R >> /ProcSet [ /PDF /Text ] >> endobj -859 0 obj << -/Length 3451 +863 0 obj << +/Length 3456 /Filter /FlateDecode >> stream -xÚíKSGÇï| -ŽX8P®gWÕîa’qXH 8¼±¶£™tˆéÁóËŸ~«§»ªr˜êj½2°# †ÎΜüÿ:ëݰmêþeÛF*¬ÜÖVE™ÚŽ·èö…ûÝ›-Ö]³ç/ÚƒW½:ßúöµÐÛ–Ø‚ÛçÁ½ ¡Æ°íóÑÏ;ïNÎNÎÏv=ÿ~ëè<Ü:fT4wümëç_éöÈùÿ~‹aÚ¾uÿC ³–o·¤DI!üO®¶Î¶þn~»4M}% Q†ëÄ'á|Æ91V»è”%…p¿k>JA¸sÜ|w9— FŒ¡Òùh.›Íój6¯†³½á堮˫Yg#V“%•±Í™³)Çe=ßÝãŠî¼™ÆãÁtwOr½Cv÷¥øEZ{¿+ïH¬¸!§,fqM“éÅvûÍ)TÉÛíAÃu•Öï¿TÉ®ÅáUOÅ1‚zŒHM”¢<0Âé_ÁÈaù ¥¼®æÕ¤n2¨Gí7?Î¥Å> ½,øle³ 1VÔ@XHı€z,'Ya l# óéb6/G{ŸÊÏ)”!–›bC¡0’>|¡È­÷$Æç4›`ˆ5Ó´Ÿ˜D1¨÷H D˜‚Ebø%fsÙàJVJ‰âÑ”’ÿg}¹'L>ÝÙ0C &('S" &Ô{€©°ÖÐ<É/ÂÒæ"SØâëC§ŸÕ\d€B ÔL³^`A ¼ ®#.F&#-j#-Lê2M ÕVoª<Æ<å’³‰¢6ÙÙ3Œ¡(¤æý­E€„øi7ÌWÚF„Š/‚Ðæ‚£{:THk6,ÀÃʦe?0‰80dPïLI¢µûmQpbÝà@C˜â81ÿÓ°±”õ|×n?_—3—+ùÈ;,PK| -³† P" D ¨÷ˆ¢®¼á- Wƒ™CBPþ5!ñÅ9Ù„‹Oh6.Àà -¦U?.‰80\Pïg`[ÁEÜ­'ï®›¶£A‡¿”‘ ›Ï\6Àã*£‹~.q`\ Þ#ŽÍ]—p![.?׃q5ìz×#×Ùh¿?¹ª†UÓêH¥ž¬ì>1Ù²CLv˜xmúeOÄÉŽzwk„Ø.˜¹JíUw…€Ñ•Jðººj&Ï•ýê[GÝ…õ2d3 1Ơ̦ž%Æê=Ž{('ªP²¦ÿÊ8]é¶6¬M>¶_OËÙd1ÝefgXúŸ 'ËŒfw4?]–Ýg>ñCß)¾,Çn¨£Å㛤 ÉÖbzÃŒcz'âÀôF½‡¦DYJ¤EÔ{©¸Ø,­ì9ö,BÂrq€†+‚ 8¤â@pÀ½G´!’2ˆïpp€ï”¿Ïƒ«–†ò÷ë% ål&/BY8]ŽeЧÚ„ãÙ8C '¨(†S" 'Ô{ì·HE\úrÕ††ˆÚ+ù¶ý›2Rq jãÞ£ÚÍ+'ŒjËNí³ÉðSÙ%9þöÝ&Ñ‹¿x)ö ©íó‘­60ÄÔ†ùÆÔNÄ©zjëf²¦]·å—X -9¾vÒ~¨®ªùçVÛÛj~ÙNø»ÒÔ®“HýQêå¤Sb>R&™5XÄcëöáS– 0Ä€€’Øþ“Œ©80 Ö¼³ÄKiœðD*Ù.Ô7“GteÑO”ÃÅ4Pq0©gÕ¨œÚ£½yó·vÜ/_À`=âõû.óÕ¿7ÞËÓš×ÔTŠp× Í»³‚ËŽl3•²?–³PëùrêsÒ͹ýàÊäòwòe^%ÿ©ó Ï~ê€!öÔAA1Šq`4¡ÞMÍÉ,K=M©W[¸¡¶e’uåóàr:™ÌEVHB]?½»¬Ù ˜Î·D(-üÑr¾¨F©[×9”¦»ì™oòÿ_ˆõ¢f 1b!4¶¿L*ŒXÔ{˜òLNM@6nÝO.!)æ¸4ž¹a/¾n¬Ø<-íeGõM»x4©Û3Ì¢ϧ örå3ŸÍ0ĸ‚Êb\%âÀ¸B½G®¨C‰"påwÿ8 ›óÒ«”ºpw`¾ôÍzË%š†µó׋zØž†—ú94¶½Pù´gC 1¨ ¬T‰80¨Pï¾yuåÌUé™ògÙzO/Æî­VÅË4u˜Ó\` !ÌŠf0©8`Ö½§FA¼h´ÜT—ƒ ó]ÆØÎt²øpUÎ.]óÕ”£Þìt7¸ïP\Œt`X¶±Ü ËÄ]—É'G)Ò½„É„AÎÁd<ög2Þ·í³ËɸÄKù2¦É”Ú$g?HÁ {Œ¢€1k`à ~C3Î¥ ‚w¯F1ÝRÏrËýüoÝø¸žtS‰·“é'÷0ý£ý¿ËÉmûÍpà÷à·_šW×\´G»:=Yø;\Âmo»ãÅ?]ùfæµ±!'ÙJCLk˜sLíD˜Þ¨÷P)š®»T^pÞÕŠãzØ*ÖtàC.Ò=¸Ô+ý:¿ -XùJ'‹ñ‡fAö tÞCš²†PŒD¨÷À³„ÝûKLègýÔ ˆOíÁçú_Rø®¼ºv­”/ÍÆ½PòÙÎF b(A51”q`(­yOõÀ˜-HÁº#©û®’s¾³}]Ö£jXöÏ1³ûv¼ ÒóZ Çö/ÀÂÛ!9X÷šzœ˜‘DqÛå iAµvY~ª'·Wåè¢)©ÍÚ*·/®ì§'$7÷é†ÈÓ³"FL"ŒÔ{è~1͉”ÝyËý¶ûe›G¨­´¯¦UÙ¦þ®šÍ'ÓÏ«'¬CC|xrv§Ånׂ -Êž ->YÙ(C (†B" Ô{("%¢PžÞ‘7e]N}+ˆ|Z~ìZê°-ç¸þ¸Ü¾œ"+ì3YsÄ5P:æî¾`tv{Ð0ÆÝû7Ú0Ú¿öŸ -#u‹„týtÓ¦Üo§ð›"qüþ¦èžúÑÈ¿tÿŠç×£Ûwÿ¸¯¬Yµ×Ïx“·—Ñç1`ˆauB1I‚a‚ºDÄU1O‰h È«êÃU5¹˜®/?G0B+q¶¸¸(›—ïûÂ2¹Q^ËŒàü™”Ÿ¹l.€!ÆTå"Æê>–. cÝ™Éýöå]Mù8-[8í[å]ëáwCŒ»þª‡åôõÁ¬%ÂþÄ;^1Ÿ²l"€!F”%"Fê>Á¸½éHï”fWí‡ù‡ÓÁdžkùËå>Ðø¬fC 1h jŒö/µ¤Á AÝhšvFuç%÷Ûwû4Ì€×nN† P;ö?„yßv0¢Ø3)>U¹ ;„(†A" -„‚5ߩ٭‰¤-€¯šæ@ì¼ÔáÕo׃‹Ô”Ovg»iÂÇç"^žšîY½g›‰þÃÜñ^ØŸ¹ã0ù²UEoWi^-›QawFÕÅ“ª‘_Á1½NýNܧ,š!P#k=„5ÂÂrÜã–$÷§7ÿe,<~îïFÆ¿nÙ¼¬ÆôýÁ.A­‹œ6‰Is¯æƒ*dKîò"ùû\,Œendstream +xÚí[SÜFÇßùó°U tú&u÷îÃ.슱Hek“<ŒgäAeF"sx?ý¶Fêî3Lë ½‰âªƒŽÎ™óÿéô]°µØ@g„ +#ÊH’Q– FÓ:˜ØŸ½ÙaÝ5ûî¢}xÕ«‹o^ 50Ää<\|÷Ò„jÍãŸvß^Ÿ^œïýrñÝÎñ…¿)t̨hîøëÎO¿ÐÁØúÿn‡at6¸µÿ „ÃÓ™ ’I!Üw®vÎwþåo~º2}Lh’i®"Ÿ„ ðIçDe£Ë É…ýYóQrÂ­ãæƒØË¸\0¢5•ÖGsÙ|1\”óE9šï.‡UU\Í;±ž,™iÓÙœ[›bZT‹½}žÑÝ7³át:œííK®vÉÞ~Féþ%¹ß•w$θ&9§,dqC“ÙdÐ~qUrvûÐpS¥Íû7©Tl#§z,ŒÔ{`D*’e”{F8ý39*~¦”W墬«ö;ÃjÜ~ñÃ|8)¬(æ‘èeÁe+™`ˆ±ÕP¼Ÿ…H ¨÷À‚°’å°À¶²°˜-ç‹b¼ÿ©øƒ ÓÄpo)ZÒ‡/©õâžÄ¸œ& 1b f1‘80bPï.ˆÐ9 Äð/JÌö²Á3ñ89éÄ¥0`ˆ%‰Ä‚z€0F•±›²¸€Á¥ý@*ÛRJ2!M)ù#ëË=aréN† b0A91˜"q`0¡Þ=L¹1¶À€æI~–¶™Üä_:}̸¬¦"ìb fJô áupÑŠ0hɶÒòߺ*â´PeÔ¶Ê£õS.9Û(j“ ‘7à +B*ÙÐFAˆß²ÃüL™€PþEÚ^pTÆžN#åÓš 0Äp²©¼˜H2¨w–I¢”ýižsbìà@C˜âX1ÿÓ°±’õbÏŽn?_s›+ùÈ;,PK\ +“† P" H ¨÷HFmyÂ[@¯†s‹„ ükBâ‹s² —Ðd\€!† L©~\"q`¸ Þ.Ö@3¶†‹¸[OÞ]7mGƒ)#^7—¹d.€!ÆTFé~."q`\ Þ–Åm—p![.Ž>WÃi9êz×cÛÙh¿~__•£²iud–=YÙ]b’e†˜ì0ñšöˉ“õn™+`ˆq•ŸŠÄq…z÷\ÙbiI‘+·Ãü‡¹ßð_¥T¹½s¥oÞ[Ö(QÔ¯¿^V£ö R=‡Æ¶*ŸöT¨ !Õš¬T±8¨pï®yåJ5ßëÞ7ãÏGöžˆ Ý[•å/sÕq`\N“†0P3 ˜H0Þc£ že¤{Ÿ•îÆ@{Œ±ÝY½üpUÌ/mëÕT£Þä´ö÷è„Ë‘aˆÉô/ö…[aI¸ã/úÌHAïÞ—¢ýç°žNÝŸ÷mÛl2mðR¾ŒgÒ#—æäÇb”ã&Fê=4æMNf"ßIÙgêïí¿.ëÛö‹ÑÐîhÿj^Š4iŸvÕº^º;\ýmo»~ã䶈3ý˜ZZ—“dÅ!¦8Ì9¦x$LqÔ»¯vlÉòî­(zÕwkªÆI5jkºñ¾ç^«ÉZïέ–n¿Òérú¡Yf¹y]xŸ¦d€!Æ”c ÆêÝ3@¡š9\oëÇæhNxjï<×oÜ·ÅÕµ}h¥|i@î…’Ëv2JÀC ª‰¡‰CiÃ{¬Æ´$7íaç[É9ß=¸¾.ªq9*"3Í‚X:U0ÛÖë®ß‡±.ØÝû6á0Ú¿ ï‡$aÓmìybŠ)»ó˜Mª”MÃèSUß^ãISS›%Vn^ú_÷|œ¤.¹÷}|<2À0öøÜ½ÿVd"`è î}Œå”ˆ<óì4ô˜æ!jkí«YYtõ¿-ç‹zöyýô¾oŠNÏï´ÙíšPNÙbÁ%+™`ˆ±Å@Yˆ‚±€º÷eDÚþ˜îŽc4]³¦Œ¼)ªbæ:Y^å³âc×Xûý9'ÕÇÕFñÕ\YnžÉâ“SÎå.™ `ˆ‘µa´ËG,Œ Ô}¨"'¶­÷h¸*qòþ&ïûñؽÑŽç©9{`ÿkO¿æB=ãíÞNF—ÇdL€!† Ô Å$† êÞ. cÝaʃ¦_ßW凫²žÌ†×—Ÿ¾™8_N&Eó›\aŽí@¯eFpþLʇË\2Àã*ƒr ãuÊã¶»®<®|œ¿.­ö­ò¶õpÛ"¦]ÕÁröúpÞ¡&ÝN—²d"€!F”%"FêÞÑ”Œ¬; yо%jÕž4{½*7Ð?š ?6Ã_Æ(÷`Æ%5`‡%c´½% êÛã¢ÑJ\D‹ x›ËQ=Z‚ªqðÁOú¶ãŒ=“ÂáR• +°C €B`D¢@ Øð›êÉ3"x»¼õªiÄîÛaåß(x=œ ó=í}g{ÂåÈ\ˆ‡QìõÞî^ ð¿½qŸÝ.ÞüŸ1ÿ„ü¾_~¥eó6Ý÷[º56b*Íïòmìvk/‘ÿ§07endstream endobj -858 0 obj << -/Type /Page -/Contents 859 0 R -/Resources 857 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 711 0 R -/Annots [ 861 0 R 862 0 R 863 0 R 864 0 R 865 0 R 866 0 R 867 0 R 868 0 R 869 0 R 870 0 R 871 0 R 872 0 R 873 0 R 874 0 R 875 0 R 876 0 R 877 0 R 878 0 R 879 0 R 880 0 R 881 0 R 882 0 R 883 0 R 884 0 R 885 0 R 886 0 R 887 0 R 888 0 R 889 0 R 890 0 R 891 0 R 892 0 R 896 0 R 897 0 R 898 0 R 899 0 R 900 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R 909 0 R 910 0 R 911 0 R 912 0 R 913 0 R 914 0 R 915 0 R 916 0 R 917 0 R 918 0 R ] ->> endobj -861 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 758.4766 539.579 767.4329] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.19) >> ->> endobj 862 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 746.3946 539.579 755.3509] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.20) >> ->> endobj -863 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 734.3125 539.579 743.2688] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.21) >> ->> endobj -864 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 722.2305 539.579 731.1868] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.22) >> +/Type /Page +/Contents 863 0 R +/Resources 861 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 715 0 R +/Annots [ 865 0 R 866 0 R 867 0 R 868 0 R 869 0 R 870 0 R 871 0 R 872 0 R 873 0 R 874 0 R 875 0 R 876 0 R 877 0 R 878 0 R 879 0 R 880 0 R 881 0 R 882 0 R 883 0 R 884 0 R 885 0 R 886 0 R 887 0 R 888 0 R 889 0 R 890 0 R 891 0 R 892 0 R 893 0 R 894 0 R 895 0 R 896 0 R 897 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R 909 0 R 910 0 R 911 0 R 912 0 R 913 0 R 914 0 R 915 0 R 916 0 R 917 0 R 918 0 R 919 0 R 920 0 R 921 0 R 922 0 R ] >> endobj 865 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 710.1484 539.579 719.1047] +/Rect [527.6238 758.5763 539.579 767.5824] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.23) >> +/A << /S /GoTo /D (subsection.6.2.19) >> >> endobj 866 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 698.1661 539.579 707.1721] +/Rect [527.6238 746.4943 539.579 755.3509] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.24) >> +/A << /S /GoTo /D (subsection.6.2.20) >> >> endobj 867 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 686.084 539.579 694.9406] +/Rect [527.6238 734.4122 539.579 743.2688] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.25) >> +/A << /S /GoTo /D (subsection.6.2.21) >> >> endobj 868 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 674.002 539.579 683.008] +/Rect [527.6238 722.3302 539.579 731.1868] /Subtype /Link -/A << /S /GoTo /D (subsection.6.2.26) >> +/A << /S /GoTo /D (subsection.6.2.22) >> >> endobj 869 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 661.9199 539.579 670.926] +/Rect [527.6238 710.2481 539.579 719.1047] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.26.1) >> +/A << /S /GoTo /D (subsection.6.2.23) >> >> endobj 870 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 649.7382 539.579 658.6945] +/Rect [527.6238 698.0664 539.579 707.0227] +/Subtype /Link +/A << /S /GoTo /D (subsection.6.2.24) >> +>> endobj +871 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 686.084 539.579 695.0901] +/Subtype /Link +/A << /S /GoTo /D (subsection.6.2.25) >> +>> endobj +872 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 673.9023 539.579 682.8586] +/Subtype /Link +/A << /S /GoTo /D (subsection.6.2.26) >> +>> endobj +873 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 661.8203 539.579 670.7765] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.6.2.26.1) >> +>> endobj +874 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 649.8379 539.579 658.6945] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.26.2) >> >> endobj -871 0 obj << +875 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 637.6562 539.579 646.6124] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.26.3) >> >> endobj -872 0 obj << +876 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 625.5741 539.579 634.5304] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.26.4) >> >> endobj -873 0 obj << +877 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 613.4921 539.579 622.4483] /Subtype /Link /A << /S /GoTo /D (section.6.3) >> >> endobj -874 0 obj << +878 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 601.41 539.579 610.3663] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.1) >> >> endobj -875 0 obj << +879 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 589.328 539.579 598.2842] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.1.1) >> >> endobj -876 0 obj << +880 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 577.2459 539.579 586.2022] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.1.2) >> >> endobj -877 0 obj << +881 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 565.1639 539.579 574.1201] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.2) >> >> endobj -878 0 obj << +882 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 553.0818 539.579 562.1876] +/Rect [527.6238 553.0818 539.579 562.0381] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.3) >> >> endobj -879 0 obj << +883 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 540.9998 539.579 550.1055] +/Rect [527.6238 540.9998 539.579 549.956] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.4) >> >> endobj -880 0 obj << +884 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 528.9177 539.579 537.874] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.5) >> >> endobj -881 0 obj << +885 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 516.8357 539.579 525.792] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.5.1) >> >> endobj -882 0 obj << +886 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 504.7536 539.579 513.7099] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.5.2) >> >> endobj -883 0 obj << +887 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 492.6716 539.579 501.6279] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.5.3) >> >> endobj -884 0 obj << +888 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 480.5895 539.579 489.5458] /Subtype /Link -/A << /S /GoTo /D (subsection.6.3.6) >> ->> endobj -885 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 468.5075 539.579 477.4638] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.3.7) >> ->> endobj -886 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 456.4254 539.579 465.3817] -/Subtype /Link -/A << /S /GoTo /D (section.6.4) >> ->> endobj -887 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 444.3434 539.579 453.2997] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.0.1) >> ->> endobj -888 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 432.2613 539.579 441.2176] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.4.1) >> +/A << /S /GoTo /D (subsubsection.6.3.5.4) >> >> endobj 889 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 420.1793 539.579 429.1356] +/Rect [527.6238 468.5075 539.579 477.4638] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.1.1) >> +/A << /S /GoTo /D (subsection.6.3.6) >> >> endobj 890 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 408.0972 539.579 417.0535] +/Rect [527.6238 456.4254 539.579 465.3817] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.1.2) >> +/A << /S /GoTo /D (subsection.6.3.7) >> >> endobj 891 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 396.0152 539.579 404.9715] +/Rect [527.6238 444.3434 539.579 453.2997] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.1.3) >> +/A << /S /GoTo /D (section.6.4) >> >> endobj 892 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 383.9331 539.579 392.8894] +/Rect [527.6238 432.2613 539.579 441.2176] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.1.4) >> +/A << /S /GoTo /D (subsubsection.6.4.0.1) >> +>> endobj +893 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 420.1793 539.579 429.1356] +/Subtype /Link +/A << /S /GoTo /D (subsection.6.4.1) >> +>> endobj +894 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 408.0972 539.579 417.0535] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.6.4.1.1) >> +>> endobj +895 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [527.6238 396.0152 539.579 405.1209] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.6.4.1.2) >> >> endobj 896 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 371.8511 539.579 380.9568] +/Rect [527.6238 383.9331 539.579 392.8894] /Subtype /Link -/A << /S /GoTo /D (subsubsection.6.4.1.5) >> +/A << /S /GoTo /D (subsubsection.6.4.1.3) >> >> endobj 897 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 349.279 539.579 358.0111] +/Rect [527.6238 371.8511 539.579 380.8074] /Subtype /Link -/A << /S /GoTo /D (chapter.7) >> ->> endobj -898 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 337.2168 539.579 346.1731] -/Subtype /Link -/A << /S /GoTo /D (section.7.1) >> ->> endobj -899 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 325.1348 539.579 334.2405] -/Subtype /Link -/A << /S /GoTo /D (section.7.2) >> ->> endobj -900 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 313.0527 539.579 322.1585] -/Subtype /Link -/A << /S /GoTo /D (subsection.7.2.1) >> +/A << /S /GoTo /D (subsubsection.6.4.1.4) >> >> endobj 901 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 300.9707 539.579 310.0764] +/Rect [527.6238 359.769 539.579 368.7253] /Subtype /Link -/A << /S /GoTo /D (subsection.7.2.2) >> +/A << /S /GoTo /D (subsubsection.6.4.1.5) >> >> endobj 902 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 288.8886 539.579 297.9944] +/Rect [527.6238 337.1969 539.579 345.9291] /Subtype /Link -/A << /S /GoTo /D (section.7.3) >> +/A << /S /GoTo /D (chapter.7) >> >> endobj 903 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 266.3165 539.579 275.0487] +/Rect [527.6238 325.1348 539.579 334.091] /Subtype /Link -/A << /S /GoTo /D (chapter.8) >> +/A << /S /GoTo /D (section.7.1) >> >> endobj 904 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 254.2544 539.579 263.2106] +/Rect [527.6238 313.0527 539.579 322.009] /Subtype /Link -/A << /S /GoTo /D (section.8.1) >> +/A << /S /GoTo /D (section.7.2) >> >> endobj 905 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 242.1723 539.579 251.1286] +/Rect [527.6238 300.9707 539.579 309.9269] /Subtype /Link -/A << /S /GoTo /D (subsection.8.1.1) >> +/A << /S /GoTo /D (subsection.7.2.1) >> >> endobj 906 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 230.0903 539.579 239.0465] +/Rect [527.6238 288.8886 539.579 297.8449] /Subtype /Link -/A << /S /GoTo /D (section.8.2) >> +/A << /S /GoTo /D (subsection.7.2.2) >> >> endobj 907 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 218.0082 539.579 226.9645] +/Rect [527.6238 276.8066 539.579 285.7628] /Subtype /Link -/A << /S /GoTo /D (section.8.3) >> +/A << /S /GoTo /D (section.7.3) >> >> endobj 908 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 195.4361 539.579 204.1683] +/Rect [527.6238 254.2345 539.579 262.9666] /Subtype /Link -/A << /S /GoTo /D (appendix.A) >> +/A << /S /GoTo /D (chapter.8) >> >> endobj 909 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 183.3739 539.579 192.3302] +/Rect [527.6238 242.1723 539.579 251.1286] /Subtype /Link -/A << /S /GoTo /D (section.A.1) >> +/A << /S /GoTo /D (section.8.1) >> >> endobj 910 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 171.2919 539.579 180.2482] +/Rect [527.6238 230.0903 539.579 239.0465] /Subtype /Link -/A << /S /GoTo /D (subsection.A.1.1) >> +/A << /S /GoTo /D (subsection.8.1.1) >> >> endobj 911 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 159.2098 539.579 168.3156] +/Rect [527.6238 218.0082 539.579 226.9645] /Subtype /Link -/A << /S /GoTo /D (section.A.2) >> +/A << /S /GoTo /D (section.8.2) >> >> endobj 912 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 147.1278 539.579 156.2335] +/Rect [527.6238 205.9262 539.579 214.8824] /Subtype /Link -/A << /S /GoTo /D (subsection.A.2.1) >> +/A << /S /GoTo /D (section.8.3) >> >> endobj 913 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 135.0457 539.579 144.1515] +/Rect [522.6425 183.3541 539.579 192.2107] /Subtype /Link -/A << /S /GoTo /D (section.A.3) >> +/A << /S /GoTo /D (appendix.A) >> >> endobj 914 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 122.9637 539.579 132.0694] +/Rect [522.6425 171.2919 539.579 180.3976] /Subtype /Link -/A << /S /GoTo /D (subsection.A.3.1) >> +/A << /S /GoTo /D (section.A.1) >> >> endobj 915 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 110.8816 539.579 119.9874] +/Rect [522.6425 159.2098 539.579 168.3156] /Subtype /Link -/A << /S /GoTo /D (subsection.A.3.2) >> +/A << /S /GoTo /D (subsection.A.1.1) >> >> endobj 916 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 98.7996 539.579 107.9053] +/Rect [522.6425 147.1278 539.579 156.2335] /Subtype /Link -/A << /S /GoTo /D (subsection.A.3.3) >> +/A << /S /GoTo /D (section.A.2) >> >> endobj 917 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 76.2275 539.579 85.0841] +/Rect [522.6425 135.0457 539.579 144.1515] /Subtype /Link -/A << /S /GoTo /D (appendix.B) >> +/A << /S /GoTo /D (subsection.A.2.1) >> >> endobj 918 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 64.1653 539.579 73.2711] +/Rect [522.6425 122.9637 539.579 132.0694] /Subtype /Link -/A << /S /GoTo /D (section.B.1) >> +/A << /S /GoTo /D (section.A.3) >> >> endobj -860 0 obj << -/D [858 0 R /XYZ 85.0394 794.5015 null] +919 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [522.6425 110.8816 539.579 119.9874] +/Subtype /Link +/A << /S /GoTo /D (subsection.A.3.1) >> >> endobj -857 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] +920 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [522.6425 98.7996 539.579 107.9053] +/Subtype /Link +/A << /S /GoTo /D (subsection.A.3.2) >> >> endobj 921 0 obj << -/Length 844 +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [522.6425 86.7175 539.579 95.8233] +/Subtype /Link +/A << /S /GoTo /D (subsection.A.3.3) >> +>> endobj +922 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [522.6425 64.1455 539.579 73.0021] +/Subtype /Link +/A << /S /GoTo /D (appendix.B) >> +>> endobj +864 0 obj << +/D [862 0 R /XYZ 85.0394 794.5015 null] +>> endobj +861 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +925 0 obj << +/Length 881 /Filter /FlateDecode >> stream -xÚíÙOOÛ0ð{>EŽí!žŸÿûÊ“80mô†8°&” Ún”iÚ>ýœ66¯ÔyR ì!”@ýìg¿ŸÒ8’‡(µaÆ _Z¯˜æ Ëù²àå"|ö©€®MU¸Õɬøp&mé™7”³ÛRiÍ„ÞvæwÊY}5ùøùbvz1»œ^Ï΋ÓYê \¶]þ,®®yY‡ΠΤwºüþà ¼å²PZ2­¤Œÿy(.‹/©Côé64;àLH#2SMÅ3Ò„ä´'á£v&'LL+/ýän½yšVÚŠ ÎÇÃö ¼?Zg/°(hùP‡Tƒê>.ÊÝÉWTïWáÀÃzö߀¨€r‰PÜÈá7e™±:nrÇ­^m6ͼª7·Sp“õò¾ù3­¤s£¦W3Š =˜ -¤áBˆ~F™D(Fäð‰‘ÔÌ -ð#µÇ(à‰Žn¾5ÓÊq?Ú`'®î`;(²ƒ« ûíd¡ìÃ';B2kŒëìè—vÍ*¬¯Òã÷Ú‘4Åõ¬ Ršp=t¿¦L"”&rø¤ €9Ói2{š6ß«¿ëUÓz’#¤·BŠK= -¤ áRØ~H™D(Häð’ñž9mTÉî ­n–M]Íïšùý|½ºVF‹QÐk¥5*‚öjzå!ÑÃ'AÎ2Ï!nåÜ îR¤ÇkÐëÅ5,R‚p AôßVç¡‘Ã'AV3¯LÜy$(ÜD{=îÿßÿŸj0X -¤„áƒPýÂ2‰PÂÈá“0#™÷ySœqÇãîo÷ìÙÔVæAµC´ZŠl{+¿m¹×«vÃi»–£Ñ£:Œ•ìR±Ä[&Ê!9|r(\À§ãæäóu¯j±mŸiIã5â²F…)T¸¬ ‰{µL"¨ÒëÃJ{ѾšT¹7ˆá˜×Z¼ý}åókUe™tNä§+gÞJ_JÍÚ¾ÚÉšÞ©vPæÿ¾ªË“endstream +xÚíÙOOÛ0ð{>EŽí!ÆÏÿ}e‚I˜6zC  AÛ2MÛ§ŸÓÆæ•:O +NB ÄÏ~ñû)µ(yøRf¼ð¥õŠiºœ. +^Îù¯´mªØ¨Â­Ž'ÅÑ©´¥gÞSNnK¥5zÓ™cÜ9('³ËÑ—oç““óÉÅøjrVœLR¯xdà²éòWqyÅËYHà¬àLz§Ë?áÎÀ{Q. +¥%ÓJÊøŸÇâ¢øž:Dg7¡Ù+΄4"s)B¢K±ÀŒ4!9íÃA8Õ\É1ƒqå¥ÍîçáÀ‹Wšóácó¡¼?Xg¯¬(dùP†T½â>ÍËíÁTîWáÀýrï÷ßÔ¸ÝCýä¡´‘Ã'mÊ2c-´ÚÄVÛÝjýæÅÜ>Ÿ[,Hon(↠ º¹e¡¸‘Ã'nR3+À·Üd{s[®×õ´š­oŸÆàF«ÅCýw\IçMof'º7#H1Â…PÝŒ2‰PŒÈá#!™5ƵŒÔ£€':z¼¾©Ç•ã~°ÓÃNœÝÞvP eW@wÛÉ$BÙ!‡Ov˜0­ýÚμ^†ùUzø^;¦8ß½5¡@J®'±~Ê$Bi"‡šŒ÷Ìi£ZMfGÓú~¾ü·ZÖ'9@z'¤4Õ}!á@ÒN)|'¤\"$zøÉYæ9ÄmŸÝBZ^/êY5½«§ÓÕòv\-Ao縷 H Â5!»e¡‘Ã'AV3¯LÜʹ=Aí­H÷ · ŠsÜ[ +¤á‚è^Vç¡‘Ã'AF2ïyÜy$(,¢½öÿ¿ÿO5è- RÂpA˜na™D(aäðI˜ŒK7nÀä6ÄÖ¿ήŸë晓x}$¯X€Þ¼P Å ±ˆÊ$Bñ"‡O¼gÜñ¸·ØòzZΦáÜðóӽŊôö†)o¸â ‰%W&Ê9|ò&¡ãîoû4õèTj+ó š!šF E¶YÊoZîôj y|aÛ–ƒÑƒ:Œ•êíR±ÄÂ-“å>9ÃÀòôÎP¾Ü÷ªÛæ™–9Üã‹*N{oT(B…Ë +’X«eÙC•^VWÚqf¥¹÷Õá˜×Þÿvüå%¾²L:'ò—+B6ÞJ_JÍB_Û½O÷µÆV(÷ÿŽžA·endstream endobj -920 0 obj << -/Type /Page -/Contents 921 0 R -/Resources 919 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 711 0 R -/Annots [ 923 0 R 924 0 R 925 0 R 926 0 R 927 0 R 928 0 R 929 0 R 930 0 R 931 0 R 932 0 R 936 0 R 937 0 R ] ->> endobj -923 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 758.4766 511.2325 767.5824] -/Subtype /Link -/A << /S /GoTo /D (section.B.2) >> ->> endobj 924 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 746.6211 511.2325 755.6272] -/Subtype /Link -/A << /S /GoTo /D (section.B.3) >> ->> endobj -925 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 734.5663 511.2325 743.672] -/Subtype /Link -/A << /S /GoTo /D (section.B.4) >> ->> endobj -926 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 722.6111 511.2325 731.7169] -/Subtype /Link -/A << /S /GoTo /D (section.B.5) >> +/Type /Page +/Contents 925 0 R +/Resources 923 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 715 0 R +/Annots [ 927 0 R 928 0 R 929 0 R 930 0 R 931 0 R 932 0 R 933 0 R 934 0 R 935 0 R 936 0 R 937 0 R 941 0 R 942 0 R ] >> endobj 927 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 710.7556 511.2325 719.7617] +/Rect [494.296 758.4766 511.2325 767.5824] /Subtype /Link -/A << /S /GoTo /D (section.B.6) >> +/A << /S /GoTo /D (section.B.1) >> >> endobj 928 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 698.8005 511.2325 707.8065] +/Rect [494.296 746.6211 511.2325 755.6272] /Subtype /Link -/A << /S /GoTo /D (section.B.7) >> +/A << /S /GoTo /D (section.B.2) >> >> endobj 929 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 686.8453 511.2325 695.8514] +/Rect [494.296 734.666 511.2325 743.672] /Subtype /Link -/A << /S /GoTo /D (section.B.8) >> +/A << /S /GoTo /D (section.B.3) >> >> endobj 930 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 674.8901 511.2325 683.8962] +/Rect [494.296 722.6111 511.2325 731.7169] /Subtype /Link -/A << /S /GoTo /D (section.B.9) >> +/A << /S /GoTo /D (section.B.4) >> >> endobj 931 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 662.935 511.2325 671.941] +/Rect [494.296 710.7556 511.2325 719.7617] /Subtype /Link -/A << /S /GoTo /D (section.B.10) >> +/A << /S /GoTo /D (section.B.5) >> >> endobj 932 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 650.8801 511.2325 659.9859] +/Rect [494.296 698.7008 511.2325 707.8065] /Subtype /Link -/A << /S /GoTo /D (section.B.11) >> +/A << /S /GoTo /D (section.B.6) >> +>> endobj +933 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 686.7456 511.2325 695.8514] +/Subtype /Link +/A << /S /GoTo /D (section.B.7) >> +>> endobj +934 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 674.8901 511.2325 683.8962] +/Subtype /Link +/A << /S /GoTo /D (section.B.8) >> +>> endobj +935 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 662.8353 511.2325 671.941] +/Subtype /Link +/A << /S /GoTo /D (section.B.9) >> >> endobj 936 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.296 638.925 511.2325 648.0307] +/Rect [494.296 650.8801 511.2325 659.9859] /Subtype /Link -/A << /S /GoTo /D (section.B.12) >> +/A << /S /GoTo /D (section.B.10) >> >> endobj 937 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 638.925 511.2325 648.0307] +/Subtype /Link +/A << /S /GoTo /D (section.B.11) >> +>> endobj +941 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 626.9698 511.2325 636.0755] /Subtype /Link +/A << /S /GoTo /D (section.B.12) >> +>> endobj +942 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.296 615.0146 511.2325 624.1204] +/Subtype /Link /A << /S /GoTo /D (section.B.13) >> >> endobj -922 0 obj << -/D [920 0 R /XYZ 56.6929 794.5015 null] +926 0 obj << +/D [924 0 R /XYZ 56.6929 794.5015 null] >> endobj -919 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R >> +923 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -940 0 obj << +945 0 obj << /Length 2175 /Filter /FlateDecode >> @@ -2632,51 +2642,51 @@ x (ÁÝîx‰kàXÛòä¾)Óò³B£:Ò96&'ȉj\@4@a&I‹#õ‡ƒ«ËÊgÿ™Ãç)W:fïHOæDOØ[ÚðÃö˜ÑR¥Jšgö ÔŠ|\ôz×I ¬!lïþ…Üϸ®ó:ÚÝW÷»ªÙ´Åa{œË€tP‘G0‰ÁúPbç…2gª n‹ÇRÛ‘|ˆ*xáx ãRè'˜tºªºÏcLi >kòiLaÕýeÕ¦¤jŠóGϾMM¥åO]¼ÞUõW–¡ŒŽsÏegè>Q¬ƒ¿Ÿ܈Aâ–l\À‡BÇzï8;Qýo¼V‹oïNßolu …gêF)üǛ߿üÊ–å‚-X°TZ“-Ÿ ÃÀšP)îJB“e&Žì·‹ý³¢£Báª8ÁZÔŒèž.µŠgZqNÌðÓ©)šàC*XFA޶Ю<¡|¢ëJÌ~f“‡s³oñuZŸ–|Am ¥£‚ÊgªöÏ7‚%WáÒõÇÝå!2‘§*ϲW<„Pf1ŸôiîÿNB¦\ü'Îg\…“€¢ÝZyþÀ)gá$5P ²MáÓŽ‚Ëx¿õŸC ®•’p¹gbçN"ùéß?¾AÉmÓõ#IàµPÏ|>Ø‘¢wI>Ü‚éž_»'‚€k÷ÓWT¾^Gôè”_g¸¢Ÿ[Ì3‡è‘徫~÷›ý>Ue¿½ÞWÓ÷/ÞèèWäB¡Êò—ÀËeʤˆëÏiX¥9ï0|?£^Ÿ+¯Ì,~ÆÊôsPh¾mvåu(½šêk(Y2ËíKHbpMÓ°Åùˆ/K" ýç@4Úâµ0ô\ë+4ÖúB×€ójêþUp#àŽÍ4‡Ú #µPãßþ.~‚ýíÔ7ÆÌþPÿƒÛZêNœE„”‚©% y/è ³ÇŸÏ+ÅÝþ üLtendstream endobj -939 0 obj << -/Type /Page -/Contents 940 0 R -/Resources 938 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 951 0 R ->> endobj -941 0 obj << -/D [939 0 R /XYZ 85.0394 794.5015 null] ->> endobj -6 0 obj << -/D [939 0 R /XYZ 85.0394 769.5949 null] ->> endobj -942 0 obj << -/D [939 0 R /XYZ 85.0394 582.8476 null] ->> endobj -10 0 obj << -/D [939 0 R /XYZ 85.0394 512.9824 null] ->> endobj -943 0 obj << -/D [939 0 R /XYZ 85.0394 474.7837 null] ->> endobj -14 0 obj << -/D [939 0 R /XYZ 85.0394 399.5462 null] ->> endobj 944 0 obj << -/D [939 0 R /XYZ 85.0394 363.8828 null] ->> endobj -18 0 obj << -/D [939 0 R /XYZ 85.0394 223.0066 null] ->> endobj -945 0 obj << -/D [939 0 R /XYZ 85.0394 190.9009 null] +/Type /Page +/Contents 945 0 R +/Resources 943 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 956 0 R >> endobj 946 0 obj << -/D [939 0 R /XYZ 85.0394 170.4169 null] +/D [944 0 R /XYZ 85.0394 794.5015 null] +>> endobj +6 0 obj << +/D [944 0 R /XYZ 85.0394 769.5949 null] >> endobj 947 0 obj << -/D [939 0 R /XYZ 85.0394 158.4617 null] +/D [944 0 R /XYZ 85.0394 582.8476 null] >> endobj -938 0 obj << -/Font << /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F48 950 0 R >> +10 0 obj << +/D [944 0 R /XYZ 85.0394 512.9824 null] +>> endobj +948 0 obj << +/D [944 0 R /XYZ 85.0394 474.7837 null] +>> endobj +14 0 obj << +/D [944 0 R /XYZ 85.0394 399.5462 null] +>> endobj +949 0 obj << +/D [944 0 R /XYZ 85.0394 363.8828 null] +>> endobj +18 0 obj << +/D [944 0 R /XYZ 85.0394 223.0066 null] +>> endobj +950 0 obj << +/D [944 0 R /XYZ 85.0394 190.9009 null] +>> endobj +951 0 obj << +/D [944 0 R /XYZ 85.0394 170.4169 null] +>> endobj +952 0 obj << +/D [944 0 R /XYZ 85.0394 158.4617 null] +>> endobj +943 0 obj << +/Font << /F21 714 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F48 955 0 R >> /ProcSet [ /PDF /Text ] >> endobj -954 0 obj << +959 0 obj << /Length 3187 /Filter /FlateDecode >> @@ -2703,66 +2713,66 @@ W ½þ`J9ÿdÑÆÇVþ¢Ì!ûȨÀÌBÖ?e‘úñcΗ`ùX¹žŸš¦-zXæç-@fØ:\a½ã¶Gî7žÛù¨ß•=Éȧv)½»@2wl(kz+0h´zx6éqŸSS> u»žQ¶àðI¼þ˜CÍ-í‚f¡œoMoqÓâ›äÚµ|Éï…2VDÓWÜãÒ|ññþkÿ=êø_bP*˜4Õ/øÃ[Df@ ž!þêóy©òendstream endobj -953 0 obj << +958 0 obj << /Type /Page -/Contents 954 0 R -/Resources 952 0 R +/Contents 959 0 R +/Resources 957 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 951 0 R -/Annots [ 961 0 R 962 0 R ] +/Parent 956 0 R +/Annots [ 966 0 R 967 0 R ] >> endobj -961 0 obj << +966 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [272.8897 207.1951 329.1084 219.2548] /Subtype /Link /A << /S /GoTo /D (types_of_resource_records_and_when_to_use_them) >> >> endobj -962 0 obj << +967 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [190.6691 179.6723 249.6573 189.0819] /Subtype /Link /A << /S /GoTo /D (rfcs) >> >> endobj -955 0 obj << -/D [953 0 R /XYZ 56.6929 794.5015 null] +960 0 obj << +/D [958 0 R /XYZ 56.6929 794.5015 null] >> endobj -956 0 obj << -/D [953 0 R /XYZ 56.6929 756.8229 null] +961 0 obj << +/D [958 0 R /XYZ 56.6929 756.8229 null] >> endobj -957 0 obj << -/D [953 0 R /XYZ 56.6929 744.8677 null] +962 0 obj << +/D [958 0 R /XYZ 56.6929 744.8677 null] >> endobj 22 0 obj << -/D [953 0 R /XYZ 56.6929 651.295 null] ->> endobj -958 0 obj << -/D [953 0 R /XYZ 56.6929 612.4036 null] ->> endobj -26 0 obj << -/D [953 0 R /XYZ 56.6929 555.4285 null] ->> endobj -959 0 obj << -/D [953 0 R /XYZ 56.6929 530.6703 null] ->> endobj -30 0 obj << -/D [953 0 R /XYZ 56.6929 416.0112 null] ->> endobj -960 0 obj << -/D [953 0 R /XYZ 56.6929 391.253 null] ->> endobj -34 0 obj << -/D [953 0 R /XYZ 56.6929 164.815 null] +/D [958 0 R /XYZ 56.6929 651.295 null] >> endobj 963 0 obj << -/D [953 0 R /XYZ 56.6929 137.4068 null] +/D [958 0 R /XYZ 56.6929 612.4036 null] >> endobj -952 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F21 710 0 R >> -/ProcSet [ /PDF /Text ] +26 0 obj << +/D [958 0 R /XYZ 56.6929 555.4285 null] +>> endobj +964 0 obj << +/D [958 0 R /XYZ 56.6929 530.6703 null] +>> endobj +30 0 obj << +/D [958 0 R /XYZ 56.6929 416.0112 null] +>> endobj +965 0 obj << +/D [958 0 R /XYZ 56.6929 391.253 null] +>> endobj +34 0 obj << +/D [958 0 R /XYZ 56.6929 164.815 null] >> endobj 968 0 obj << +/D [958 0 R /XYZ 56.6929 137.4068 null] +>> endobj +957 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F21 714 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +973 0 obj << /Length 3415 /Filter /FlateDecode >> @@ -2781,60 +2791,60 @@ J$ ?6`³> endobj -971 0 obj << +976 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [519.8432 463.1122 539.579 475.1718] /Subtype /Link /A << /S /GoTo /D (diagnostic_tools) >> >> endobj -972 0 obj << +977 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [84.0431 451.8246 133.308 463.2167] /Subtype /Link /A << /S /GoTo /D (diagnostic_tools) >> >> endobj -969 0 obj << -/D [967 0 R /XYZ 85.0394 794.5015 null] +974 0 obj << +/D [972 0 R /XYZ 85.0394 794.5015 null] >> endobj 38 0 obj << -/D [967 0 R /XYZ 85.0394 570.5252 null] ->> endobj -970 0 obj << -/D [967 0 R /XYZ 85.0394 541.3751 null] ->> endobj -42 0 obj << -/D [967 0 R /XYZ 85.0394 434.1868 null] ->> endobj -973 0 obj << -/D [967 0 R /XYZ 85.0394 406.5769 null] ->> endobj -46 0 obj << -/D [967 0 R /XYZ 85.0394 301.1559 null] ->> endobj -974 0 obj << -/D [967 0 R /XYZ 85.0394 276.6843 null] ->> endobj -50 0 obj << -/D [967 0 R /XYZ 85.0394 200.1512 null] +/D [972 0 R /XYZ 85.0394 570.5252 null] >> endobj 975 0 obj << -/D [967 0 R /XYZ 85.0394 175.6796 null] +/D [972 0 R /XYZ 85.0394 541.3751 null] >> endobj -966 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F21 710 0 R >> -/ProcSet [ /PDF /Text ] +42 0 obj << +/D [972 0 R /XYZ 85.0394 434.1868 null] +>> endobj +978 0 obj << +/D [972 0 R /XYZ 85.0394 406.5769 null] +>> endobj +46 0 obj << +/D [972 0 R /XYZ 85.0394 301.1559 null] >> endobj 979 0 obj << +/D [972 0 R /XYZ 85.0394 276.6843 null] +>> endobj +50 0 obj << +/D [972 0 R /XYZ 85.0394 200.1512 null] +>> endobj +980 0 obj << +/D [972 0 R /XYZ 85.0394 175.6796 null] +>> endobj +971 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F21 714 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +984 0 obj << /Length 2458 /Filter /FlateDecode >> @@ -2847,39 +2857,39 @@ Y K³ËZ! U¢|õ },ä-T\Èiù)¶†—™M¬)¢Ût‡KBaŒÂ´˜ŸS7`\&Ö^±¡‰&&Ú¡Ù’å^_ˆ¼=¢ µŽ¸Š©/@ð$.˜Á²n 0ãf—«{/Qc‡çöùޱÉñ¡ÚÖ=¯tñÍX>Ëî)z /{0„öG1Y C*5÷Hò|ÅjAÀùеa0ÂXë–KƯ,†•p=†”Fä9‰ñléÜî|uÚ$1Sû52Ñ”*?õVù8ijÞC@üû 3ß‚ü¹=á¬zÛ”SsÀÖ'¨‹«ƒNøÒÕæOwíi¸þáñé=|ë5ë~ÒÅÀªƒtk¨€ƒ6¼Ý ]´Né!)½=Á˜*5$ÐyúÿPŠrla±Ö¯æj§›íb5% îÖfÏX.]äü©pšwzc 4vÖ׳Ü]Õ°»“™2_$¡OæÖ#ç’_åpÚÐذö4uîëÜzû.—H38Bn«‚'äô°…ïúýuoõÖV1J¹–cݽŒñ=Ãm}„R/"$•§Ž4÷•>‚tùª[«_Ð@âIŠý[†a{ÓШk/O \¯\iܽŒ‹µyîbm^`8O_Š­j˜=:9M®<uH&)!Íf¹² E ¤òïFÜÙ Ív¤Yžú*Ï]‚ÍŽb7KFY!ëö4¹é>a±¬z Ù\˜"T‘2»Œ·SCNE˜"¿ÄTz[Õ•=L A05h1„u”»œdkM9C€/¥x$ue¿r~EÇðyΟ¯Ž&áèBg Ú½.ßóh¦·\Q&ɧw%±»Üéu©®Œ¡™ÐÙ^ôÃo)Ó$TK …3¸U£©UPk\‘;cpËÜÓ…à8~*”©DGÊR³)=„ò6MÄU$ä¨U“—¿pf¥ÉÖ\:âç¥Z¾þ®Úé=YO½å¼zxã¿H_ø‡ÈÂ?!á˜èþïÿ]¦¿Ÿ¢4PY&—ÿRÁá("Ì”K©á çþš[Öÿ xK:óendstream endobj -978 0 obj << +983 0 obj << /Type /Page -/Contents 979 0 R -/Resources 977 0 R +/Contents 984 0 R +/Resources 982 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 951 0 R +/Parent 956 0 R >> endobj -980 0 obj << -/D [978 0 R /XYZ 56.6929 794.5015 null] +985 0 obj << +/D [983 0 R /XYZ 56.6929 794.5015 null] >> endobj 54 0 obj << -/D [978 0 R /XYZ 56.6929 717.7272 null] ->> endobj -981 0 obj << -/D [978 0 R /XYZ 56.6929 690.4227 null] ->> endobj -58 0 obj << -/D [978 0 R /XYZ 56.6929 550.0786 null] ->> endobj -982 0 obj << -/D [978 0 R /XYZ 56.6929 525.2967 null] ->> endobj -62 0 obj << -/D [978 0 R /XYZ 56.6929 393.0502 null] ->> endobj -983 0 obj << -/D [978 0 R /XYZ 56.6929 363.1913 null] ->> endobj -977 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] +/D [983 0 R /XYZ 56.6929 717.7272 null] >> endobj 986 0 obj << +/D [983 0 R /XYZ 56.6929 690.4227 null] +>> endobj +58 0 obj << +/D [983 0 R /XYZ 56.6929 550.0786 null] +>> endobj +987 0 obj << +/D [983 0 R /XYZ 56.6929 525.2967 null] +>> endobj +62 0 obj << +/D [983 0 R /XYZ 56.6929 393.0502 null] +>> endobj +988 0 obj << +/D [983 0 R /XYZ 56.6929 363.1913 null] +>> endobj +982 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +991 0 obj << /Length 2095 /Filter /FlateDecode >> @@ -2897,66 +2907,66 @@ D Õmíš™Q‘‚z â~ó ¯ fÙ"‡èâ9Lt¨ž¹£j¡ mK(ÈÏbµÌ¥X2¼É6õpT!h_¥^ÁO8,uU•a¸‡àk"¿°•6ª ÇsÓ÷Oã_IZ:ä[²ÑiÉ*Np’êZÀu ‰¡‰ñìK—!Gµ&¯!cÖ`þû$8‘ôbGÊ=6ü¡ºJ¬« z¸Äã5Âr‘> endobj -992 0 obj << +997 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [519.8432 268.1131 539.579 280.1727] /Subtype /Link /A << /S /GoTo /D (acache) >> >> endobj -993 0 obj << +998 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [84.0431 256.1579 143.5361 268.2175] /Subtype /Link /A << /S /GoTo /D (acache) >> >> endobj -987 0 obj << -/D [985 0 R /XYZ 85.0394 794.5015 null] +992 0 obj << +/D [990 0 R /XYZ 85.0394 794.5015 null] >> endobj 66 0 obj << -/D [985 0 R /XYZ 85.0394 769.5949 null] +/D [990 0 R /XYZ 85.0394 769.5949 null] >> endobj -988 0 obj << -/D [985 0 R /XYZ 85.0394 574.3444 null] +993 0 obj << +/D [990 0 R /XYZ 85.0394 574.3444 null] >> endobj 70 0 obj << -/D [985 0 R /XYZ 85.0394 574.3444 null] ->> endobj -989 0 obj << -/D [985 0 R /XYZ 85.0394 540.5052 null] ->> endobj -74 0 obj << -/D [985 0 R /XYZ 85.0394 447.7637 null] ->> endobj -990 0 obj << -/D [985 0 R /XYZ 85.0394 410.3389 null] ->> endobj -78 0 obj << -/D [985 0 R /XYZ 85.0394 348.7624 null] ->> endobj -991 0 obj << -/D [985 0 R /XYZ 85.0394 311.223 null] ->> endobj -82 0 obj << -/D [985 0 R /XYZ 85.0394 189.9853 null] +/D [990 0 R /XYZ 85.0394 574.3444 null] >> endobj 994 0 obj << -/D [985 0 R /XYZ 85.0394 156.0037 null] +/D [990 0 R /XYZ 85.0394 540.5052 null] >> endobj -984 0 obj << -/Font << /F21 710 0 R /F23 734 0 R >> +74 0 obj << +/D [990 0 R /XYZ 85.0394 447.7637 null] +>> endobj +995 0 obj << +/D [990 0 R /XYZ 85.0394 410.3389 null] +>> endobj +78 0 obj << +/D [990 0 R /XYZ 85.0394 348.7624 null] +>> endobj +996 0 obj << +/D [990 0 R /XYZ 85.0394 311.223 null] +>> endobj +82 0 obj << +/D [990 0 R /XYZ 85.0394 189.9853 null] +>> endobj +999 0 obj << +/D [990 0 R /XYZ 85.0394 156.0037 null] +>> endobj +989 0 obj << +/Font << /F21 714 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -998 0 obj << +1003 0 obj << /Length 605 /Filter /FlateDecode >> @@ -2965,27 +2975,27 @@ xÚ¥T 4‹$çÉ™‘•2' £JëØé}•ª±Ö¶Ìì¢öìJçÕ¥-ÙZ³ØÖ>ðAY³ìöwªv™÷ö»)ó?A‘ÿR¶Ph÷ÑÆÑ~»¥Ý…ÁeêsƒLÕù“éÛôÖwC’œ[yžTÝäºgGE8ìIƒ‹|7ðÒ¾omè[”—™~nlNÓímhë<ïRBHì640; ó}å*!²á ]ÖÑUA«ƒlÛ*kyÓÚ Ë54<ªàmgvd¦gíTúä,¥ì¢}Tã?9_¸ûÿcZ8^¾Klue…zR…]fù •Úµº~±®Û´î0lÒqÐÝPµS#HÓÖù]ךÃ@ÿ;ÆQ?+G†Ä¼îPÿ{$ÿ©0BLz˜¶éTÐH PGª—œÐÌÇÙýHý/š@endstream endobj -997 0 obj << +1002 0 obj << /Type /Page -/Contents 998 0 R -/Resources 996 0 R +/Contents 1003 0 R +/Resources 1001 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 951 0 R +/Parent 956 0 R >> endobj -999 0 obj << -/D [997 0 R /XYZ 56.6929 794.5015 null] +1004 0 obj << +/D [1002 0 R /XYZ 56.6929 794.5015 null] >> endobj 86 0 obj << -/D [997 0 R /XYZ 56.6929 769.5949 null] +/D [1002 0 R /XYZ 56.6929 769.5949 null] >> endobj -1000 0 obj << -/D [997 0 R /XYZ 56.6929 744.7247 null] +1005 0 obj << +/D [1002 0 R /XYZ 56.6929 744.7247 null] >> endobj -996 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R >> +1001 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1003 0 obj << +1008 0 obj << /Length 1215 /Filter /FlateDecode >> @@ -3000,45 +3010,45 @@ NT2 .Sø«ê¹”ý¿X'¶o|uÃ=-Lî…wà våã;d̛˪š¨!=ZŸÜOŸl_¯|É•o» ω¤¶j'ÇÆÌ9‚4ŒýàF%Œ}ÌÄgcê®)ÓëŸÂKÆ ®Ô,u°7tÌ)Mþ:~ø~=}Ü„O‘û4÷ùDâ‹ ~û\w¼ )x™C6.&Þz›¾¤îÝý ?»˜endstream endobj -1002 0 obj << +1007 0 obj << /Type /Page -/Contents 1003 0 R -/Resources 1001 0 R +/Contents 1008 0 R +/Resources 1006 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1009 0 R +/Parent 1014 0 R >> endobj -1004 0 obj << -/D [1002 0 R /XYZ 85.0394 794.5015 null] +1009 0 obj << +/D [1007 0 R /XYZ 85.0394 794.5015 null] >> endobj 90 0 obj << -/D [1002 0 R /XYZ 85.0394 769.5949 null] +/D [1007 0 R /XYZ 85.0394 769.5949 null] >> endobj -1005 0 obj << -/D [1002 0 R /XYZ 85.0394 575.896 null] +1010 0 obj << +/D [1007 0 R /XYZ 85.0394 575.896 null] >> endobj 94 0 obj << -/D [1002 0 R /XYZ 85.0394 529.2011 null] +/D [1007 0 R /XYZ 85.0394 529.2011 null] >> endobj -1006 0 obj << -/D [1002 0 R /XYZ 85.0394 492.9468 null] +1011 0 obj << +/D [1007 0 R /XYZ 85.0394 492.9468 null] >> endobj 98 0 obj << -/D [1002 0 R /XYZ 85.0394 492.9468 null] ->> endobj -1007 0 obj << -/D [1002 0 R /XYZ 85.0394 466.0581 null] ->> endobj -102 0 obj << -/D [1002 0 R /XYZ 85.0394 237.1121 null] ->> endobj -1008 0 obj << -/D [1002 0 R /XYZ 85.0394 206.4074 null] ->> endobj -1001 0 obj << -/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R >> -/ProcSet [ /PDF /Text ] +/D [1007 0 R /XYZ 85.0394 492.9468 null] >> endobj 1012 0 obj << +/D [1007 0 R /XYZ 85.0394 466.0581 null] +>> endobj +102 0 obj << +/D [1007 0 R /XYZ 85.0394 237.1121 null] +>> endobj +1013 0 obj << +/D [1007 0 R /XYZ 85.0394 206.4074 null] +>> endobj +1006 0 obj << +/Font << /F21 714 0 R /F23 738 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1017 0 obj << /Length 1860 /Filter /FlateDecode >> @@ -3054,53 +3064,53 @@ g:+ n9ê®ÐB©ªWúQEBŽ| ÌNuë`:ôkn‹}8ÔXÅÇtªëmý÷­¯ý=^¤8æñ Ç̃€×á<ÊÃ>%Åê+'Йú>êçòE@Û߈¶¿4E¢þhh!V²ŠúO@º¬bºMæ1áwÿ$‰%7BܲÌê½>ìsëD7c¸¦1êÿ0§‘ÌÁ¬‡^˜yö·èl™ê.$ ˆßf’È:®Ò¹ïXÀŽ2³—à‰+YÔÑ\÷¦ =n ˆi¬¢> endobj -1017 0 obj << +1022 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [55.6967 190.8043 126.3509 202.8639] /Subtype /Link /A << /S /GoTo /D (rrset_ordering) >> >> endobj -1013 0 obj << -/D [1011 0 R /XYZ 56.6929 794.5015 null] +1018 0 obj << +/D [1016 0 R /XYZ 56.6929 794.5015 null] >> endobj 106 0 obj << -/D [1011 0 R /XYZ 56.6929 480.2651 null] ->> endobj -1014 0 obj << -/D [1011 0 R /XYZ 56.6929 441.7923 null] ->> endobj -1015 0 obj << -/D [1011 0 R /XYZ 56.6929 373.7178 null] ->> endobj -1016 0 obj << -/D [1011 0 R /XYZ 56.6929 361.7627 null] ->> endobj -110 0 obj << -/D [1011 0 R /XYZ 56.6929 167.4388 null] ->> endobj -1018 0 obj << -/D [1011 0 R /XYZ 56.6929 126.8733 null] ->> endobj -114 0 obj << -/D [1011 0 R /XYZ 56.6929 126.8733 null] +/D [1016 0 R /XYZ 56.6929 480.2651 null] >> endobj 1019 0 obj << -/D [1011 0 R /XYZ 56.6929 98.4089 null] +/D [1016 0 R /XYZ 56.6929 441.7923 null] >> endobj -1010 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >> -/ProcSet [ /PDF /Text ] +1020 0 obj << +/D [1016 0 R /XYZ 56.6929 373.7178 null] +>> endobj +1021 0 obj << +/D [1016 0 R /XYZ 56.6929 361.7627 null] +>> endobj +110 0 obj << +/D [1016 0 R /XYZ 56.6929 167.4388 null] >> endobj 1023 0 obj << +/D [1016 0 R /XYZ 56.6929 126.8733 null] +>> endobj +114 0 obj << +/D [1016 0 R /XYZ 56.6929 126.8733 null] +>> endobj +1024 0 obj << +/D [1016 0 R /XYZ 56.6929 98.4089 null] +>> endobj +1015 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1028 0 obj << /Length 2720 /Filter /FlateDecode >> @@ -3123,33 +3133,33 @@ N Z,¼-¿5ëx+±/mÿ6#ö OCõ~šT.8†µ™ÌÕêÖîRMcíHa™,6fñ;xâêr«”&ËÏ+©F4èï7%‰y_…ɦSñD2¢æ€·æ$ã9?½ öG)ûj3Ø—æ¡j‹/Ã=9ÅÎûd¼½vÊ ='\©4^$R¾¾3²—Åš2ñÕå1ê"ÕETÇœs,TzŽNÓ¨.Rí°w¿Ý}=Û}aŠpjóÌÁ,Ú/‡mIOÙ·Þݬʭ™h<€kNU·a0¼Su>ti¦×Ó ¬õµ®ÌiØÂFI¦Ï‰Ž4'²û¶€*Âï ?°ú4`ƒ‚À•°qâI[„4Ú´áb+Þ³œÆsì–Ä»ÀËíé Ü”ΞuU9œ¹¼Ešé0ô›-Rbÿ³hD wsÏþ¦ÇÿëWZóq'T£çYPÊ*ÏÒ¡æñ?NUÿ£^mšendstream endobj -1022 0 obj << +1027 0 obj << /Type /Page -/Contents 1023 0 R -/Resources 1021 0 R +/Contents 1028 0 R +/Resources 1026 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1009 0 R +/Parent 1014 0 R >> endobj -1024 0 obj << -/D [1022 0 R /XYZ 85.0394 794.5015 null] +1029 0 obj << +/D [1027 0 R /XYZ 85.0394 794.5015 null] >> endobj 118 0 obj << -/D [1022 0 R /XYZ 85.0394 769.5949 null] +/D [1027 0 R /XYZ 85.0394 769.5949 null] >> endobj -976 0 obj << -/D [1022 0 R /XYZ 85.0394 749.3395 null] +981 0 obj << +/D [1027 0 R /XYZ 85.0394 749.3395 null] >> endobj 122 0 obj << -/D [1022 0 R /XYZ 85.0394 221.8894 null] +/D [1027 0 R /XYZ 85.0394 221.8894 null] >> endobj -1028 0 obj << -/D [1022 0 R /XYZ 85.0394 197.4323 null] +1033 0 obj << +/D [1027 0 R /XYZ 85.0394 197.4323 null] >> endobj -1021 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R >> +1026 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1031 0 obj << +1036 0 obj << /Length 3424 /Filter /FlateDecode >> @@ -3172,21 +3182,21 @@ x .ø¡i±"ƒ|çÌ´£²D9»W>kè:•Æâ•öÿ°³§ô9R¬Ø»dða¹}õ3~!Îð1€Ùæî•ÅÈU€øRŠÞ-?²=¡¿G¤°·ÔàÙçLS%ý¡/,gûbo“7ÍÒ¿2€áÿÌXõÏ/þð¿9tÿýïâxéjPaŽ ˜X¡p*LNŸz¢F$Ÿýßð3*endstream endobj -1030 0 obj << +1035 0 obj << /Type /Page -/Contents 1031 0 R -/Resources 1029 0 R +/Contents 1036 0 R +/Resources 1034 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1009 0 R +/Parent 1014 0 R >> endobj -1032 0 obj << -/D [1030 0 R /XYZ 56.6929 794.5015 null] +1037 0 obj << +/D [1035 0 R /XYZ 56.6929 794.5015 null] >> endobj -1029 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F53 1027 0 R /F14 737 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F55 1035 0 R >> +1034 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F53 1032 0 R /F14 741 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R /F55 1040 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1038 0 obj << +1043 0 obj << /Length 3965 /Filter /FlateDecode >> @@ -3212,29 +3222,29 @@ w ›e4?sžÜZjø ‰€Â¦‡ àÊ€'Ât´YØ8(‰5¶ºn´Ÿg¾ª wL™+x^9Pk{:ê¸wcÔb+âgj|‰ö`_ÒM¤ÒU|`°ic¢Ÿ#á«È÷&‘ü.‹ ¹Û ñê’,Ïgò8Ü> endobj -1040 0 obj << +1045 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [120.1376 318.9001 176.3563 328.1154] /Subtype /Link /A << /S /GoTo /D (controls_statement_definition_and_usage) >> >> endobj -1039 0 obj << -/D [1037 0 R /XYZ 85.0394 794.5015 null] +1044 0 obj << +/D [1042 0 R /XYZ 85.0394 794.5015 null] >> endobj -1036 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R /F41 935 0 R /F55 1035 0 R >> +1041 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R /F41 940 0 R /F55 1040 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1044 0 obj << +1049 0 obj << /Length 1676 /Filter /FlateDecode >> @@ -3249,33 +3259,33 @@ x ¹#„@Ë1!ƒìTÛ•mÕLæªÔpßÔ8ÔBZ»Ï\Ðüp—ç6ºàS[êë¥eˆHh" •êƒi¸ 8”5!lK-ñX*+k°¨’ìö~ÀšVU”?$ì!E4 hÔtmuAë" M5À1óG„à°›äéća¦ïl^FƒhÓ C('骉²6Þd|u>ýÅÜÕv?,h×gá¹'ˆë”ZÔuJýº2;šè£{»LãL06ë(nç»ïœ| gu¼ÊnÌ]¹Ü±¶Õ"µú› ºì­‹òN;s'òYu©µùÿÔ¡¢HH!=%so£t9={qõf7FD…œy}ÏÉN倗ÛI Ñ•±å扆½3NoP;²ý,â`€ ñ dàg3»î¸’DPQî¡-€ù†õˆdŠ!róŸú_E0}L3`ՀЯ ˜{ÂÈã<;½xuÂ=•á=7‡!Ü÷óÁŽóÔ1e×HÓ?²æ0Æí¤ÿoŒAŸPRð¯`ŒRÄE@Ʀç³Ãëi|4ˆíy9 ±¾›ÿÄí¤ÿˆH8$„‘ fE±ýrï[%üSEBaðšÂ,Äà'Mì}µý€ºù® íIy€r€d`>b¦¤ui4¹÷y×}iµR=×ÿ„­gÚendstream endobj -1043 0 obj << +1048 0 obj << /Type /Page -/Contents 1044 0 R -/Resources 1042 0 R +/Contents 1049 0 R +/Resources 1047 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1009 0 R +/Parent 1014 0 R >> endobj -1045 0 obj << -/D [1043 0 R /XYZ 56.6929 794.5015 null] +1050 0 obj << +/D [1048 0 R /XYZ 56.6929 794.5015 null] >> endobj 126 0 obj << -/D [1043 0 R /XYZ 56.6929 424.8255 null] +/D [1048 0 R /XYZ 56.6929 424.8255 null] >> endobj -1046 0 obj << -/D [1043 0 R /XYZ 56.6929 397.5211 null] ->> endobj -1047 0 obj << -/D [1043 0 R /XYZ 56.6929 368.0037 null] ->> endobj -1048 0 obj << -/D [1043 0 R /XYZ 56.6929 356.0485 null] ->> endobj -1042 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F21 710 0 R >> -/ProcSet [ /PDF /Text ] +1051 0 obj << +/D [1048 0 R /XYZ 56.6929 397.5211 null] >> endobj 1052 0 obj << +/D [1048 0 R /XYZ 56.6929 368.0037 null] +>> endobj +1053 0 obj << +/D [1048 0 R /XYZ 56.6929 356.0485 null] +>> endobj +1047 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F21 714 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1057 0 obj << /Length 2367 /Filter /FlateDecode >> @@ -3299,29 +3309,29 @@ G ±ÌÐ.‰`—\?ô³æûîàhT¼pªËÇà6ÅHeÃ¥>x]³jßûy«ëoÚ£aÆNèª –¥FÿM‡Œ bÎf^>6eiéã.û –QT±Øƒ—ç0pù0äB›üÆ ÿ:¥Æóà/»YÀíÛ×°/hkßûA~P´SŠsûý»ˆäãÇÛ÷?½¢ýp•P¼óKŠÀ˾y÷¸·‡æÌi,§€yËK Å"> vŠóØã`£y>Ñ>m?Ô]}*®0‘Ýåé” @|-AÅÒtž†o†aln öu›Ö³ÔçÙ­½ ÌìÔ|õ“—yP¿/†`—aËMwŠr:;4Ž0iw‘K‚©×Á&oÖñY{c%†ã tj‚0«C/e˜Ê8iìþ|êBÄÔ>S`ó!8•?º1œ™Í ¥Áq^UÓ2ytJ©6ó-‹ÕT˜L™Ë]Šê‡ Ãèç\mRfLÃ(.f›pxö–Ô¿³¶´ð\RKXöÈüÚØªrç†'TR+Þè`áÞo7Díüå±î.¶‘øÉ(ø @ÅRÒw”Þ(>9©ˆµ>Cæ™×,buN s“<ÁÖo4>IÁË÷íë(´¼ã±e,û¡Q–8ÖݧEz9O„žÚ¦!§²?ºµ„‡³ã<6…ÎL"Ìô,X¢Õl Ë4§žx s¬|¦Xžœ±l¡Öº¨¯H—4ü…²9·ü¢7êA{§¦‚Œ}Yî­ùÉÂßCÍæËËû¦+NO/”ŠÃcn«8^¦µºjÆ=Ewv|G?_×(Ã4–4kS¬©“˜­L±8$ˆt DäÏÎ4W(þpu˜endstream endobj -1051 0 obj << +1056 0 obj << /Type /Page -/Contents 1052 0 R -/Resources 1050 0 R +/Contents 1057 0 R +/Resources 1055 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1066 0 R -/Annots [ 1056 0 R 1057 0 R ] +/Parent 1071 0 R +/Annots [ 1061 0 R 1062 0 R ] >> endobj -1049 0 obj << +1054 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/usr/local/share/db2latex/xsl/figures/note.pdf) /PTEX.PageNumber 1 -/PTEX.InfoDict 1067 0 R +/PTEX.InfoDict 1072 0 R /Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] /BBox [0.00000000 0.00000000 27.00000000 27.00000000] /Resources << /ProcSet [ /PDF ] /ExtGState << -/R4 1068 0 R +/R4 1073 0 R >>>> -/Length 1069 0 R +/Length 1074 0 R /Filter /FlateDecode >> stream @@ -3334,12 +3344,12 @@ q n*Œ1½÷¨¾x¥Æˆpîâ‹&Xîܧ³±è\íD¤ßä0}#XŒûž˜‹¸À>#^V°¡|2Îi‰9ÊÎr)`˜¢Xh¡Ò& „hb—H°Œe"Ãêʱ„£~Ï“a³tŒºìZDß!#Z¶ÚÂk! e'jÝ=§ _tsÙ¬ûÍ&­Nå@‚i¬ˆ3t%kÐE„\H–YZxÿ/U¥Ç™åë—Φ@±¯iW H þrÓGçX5¾ûû8‡´ÕªOª«t–Ô³$Ây°‰—BÒ›ÀÄ5©/¨vp÷o`kA“ôr ±ñœÓ4N.4Žæ&F°ÑTÆG%V½ Î'ÌØR5¬BÔ‹`qUžv-UÍ=ëÆåQv2ë_ ”¿­qq‚~èr¯Ú5ÌJ¼ð˜°h»P¡õ‹kÜàéÚýªå>Ò¸D °o»Îi¸CrT]¿MJ¥ ÆÖ¹’°;¿ö‹ûóZ¼¬ å[Ç-œÁ¤ŸBx¿ýpü|üÈÂendstream endobj -1067 0 obj +1072 0 obj << /Producer (AFPL Ghostscript 6.50) >> endobj -1068 0 obj +1073 0 obj << /Type /ExtGState /Name /R4 @@ -3349,287 +3359,298 @@ endobj /SA true >> endobj -1069 0 obj +1074 0 obj 1049 endobj -1056 0 obj << +1061 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [470.3398 477.3512 539.579 489.4108] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1057 0 obj << +1062 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [316.7164 465.396 385.3363 477.4557] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1053 0 obj << -/D [1051 0 R /XYZ 85.0394 794.5015 null] +1058 0 obj << +/D [1056 0 R /XYZ 85.0394 794.5015 null] >> endobj 130 0 obj << -/D [1051 0 R /XYZ 85.0394 769.5949 null] +/D [1056 0 R /XYZ 85.0394 769.5949 null] >> endobj -1054 0 obj << -/D [1051 0 R /XYZ 85.0394 580.0302 null] +1059 0 obj << +/D [1056 0 R /XYZ 85.0394 580.0302 null] >> endobj 134 0 obj << -/D [1051 0 R /XYZ 85.0394 580.0302 null] +/D [1056 0 R /XYZ 85.0394 580.0302 null] >> endobj -1055 0 obj << -/D [1051 0 R /XYZ 85.0394 539.9341 null] +1060 0 obj << +/D [1056 0 R /XYZ 85.0394 539.9341 null] >> endobj 138 0 obj << -/D [1051 0 R /XYZ 85.0394 315.9171 null] +/D [1056 0 R /XYZ 85.0394 315.9171 null] >> endobj -1064 0 obj << -/D [1051 0 R /XYZ 85.0394 282.0038 null] +1069 0 obj << +/D [1056 0 R /XYZ 85.0394 282.0038 null] >> endobj 142 0 obj << -/D [1051 0 R /XYZ 85.0394 146.7217 null] +/D [1056 0 R /XYZ 85.0394 146.7217 null] >> endobj -1065 0 obj << -/D [1051 0 R /XYZ 85.0394 117.3479 null] +1070 0 obj << +/D [1056 0 R /XYZ 85.0394 117.3479 null] >> endobj -1050 0 obj << -/Font << /F21 710 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F41 935 0 R >> -/XObject << /Im2 1049 0 R >> +1055 0 obj << +/Font << /F21 714 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F41 940 0 R >> +/XObject << /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1074 0 obj << -/Length 3348 -/Filter /FlateDecode ->> -stream -xÚ¥Z[w£F~÷¯Ð[ð9#4Mþ93öÆ9‰3k{/'—‡6 ‹ …k4¿~«ºªHÌæaè{W×å«‹®ø W2ñ“,ÊV*‹}„r•ﮂÕ+Ìýý*ä5k·h=]õÝóÕ·wB­2?K¢dõ¼™œ•úAš†«çâW/ö… 'ÞýÃûÇÛŸnž¯UìÝüx½ŽdàýòóÃ-µžožînŸ¨û[ ƒûÿÜ=Â7¼^ GÞûïo>>ß>Ò|̧Þ|ø×u†ÞÍÃûÛ4õáϸ»½Á»žÿùxûtýûóW·Ï㣦/úóê×߃Uïÿá*ðE–ÊÕ:fY´Ú]ÅRø2ÂÔWOWÿœÌÚ­‹Œ ?I´ÀÉH,qRf~"` -9ù¼-áY‰òLÙ½•µU]SKצ¥V›çÚTm£ëúÈ«ºªçÍÈ×ߢ(.†Ý¿Ä_œéÝùy»Û×e?öš¾lzÃgoÎûB÷eA/mc‡S¯gZ*·ÑN €ë0ô3)#ûªß‚ ªKf,$<±ÂåYä¹oÓöÔ(èhœÚíÊ¢‚Kíë²ÐÓ›Þ²æJoyý±Ñ»*§ùô(ˆ¼—2׃áÃú­æ íPtà‹›l[j˜º=ðªmÙPK/½¦ÖÝu˜z¯x@”9~@˾¾'vAgc—À_x ª±O4Þ7¦/uG"ffG©‡B›ŸW”µ>ºó^ŽîúZ!À7”ôÝUÍЗƞ*@aàUUóJsº(ªÞ*Íü]dÅD¶!³²ÇâW*©µ¯u2tSÌ•”ößįH¿à“œ”†èÒ#6˜^wÌšd”©Û(=³ú¢=ðimGëòN›­}PºFsl0KuGšaFJïvèð©¶C*H;ˆe@Z“·Ý¾ít_ºšJì! ,bY7ts¤Æœk¤i–í§ ßx?Ø®ä±ZÞr:U`‘Óï·ºy½¼Œy;ÔÜ'kwÔÃgîH¨GËw –;³«ûN7fSv|©º#ŸÐZÌÚÚJÒÊ+ècª]…Vb;í´~ö h‚wRŒD,)CÊäÔÒy­¡ñ\7„0Ü´ÝŽáPFdß0 -0B -‡cG.º‘'`d›'Ï O0ú:hàN_ÒqõhKµeH–°˜3åíZ+æÌékܧþĈGà @·¢á~Û˜%Ò Ó6„Ê»¸ð¤ýxÒÀqÆ<Ÿí>XãÉØ4` lÌÀ-Ex·9¹ÉZcÌV†Þã²  ˆL%s°ÇéÂbåË4P!†Ä£Ð —ÜdÄœ®[]œLú_œSO¸;n\—ͨšëHÅ~áWTtâkýñÑ!ˆ-n Ú`Ì™‚p›S’ëuçA˜•w3g÷Ë<ÏÖÖæo–“\ò!@xðÓ$'þ+]r«éqi8ºUŸç=8ÂÝ·yË{-äÁNM]BhhlZ>ÄÔŒ?Ç[¼Ð&8»’±Z'ÑÀbà§~· §ÈÉ0ž âq!Š“é5Ò_0 \¨NNTZV ÖFÊù|é! ¨uö|ØOˆá¾Ì+Tzrº ‡Ò{¼{O¦I{râ=•åy -'9™¬â,ò#&ÉMv¯+j²)ôS€§³J€KÍÿg™çg ñJ`Ùyg RSúiŽœ L§e8j R6êÀ.ÕýqÑ|׎™ -%8LVì ” *Œ -& âN‰°Mó|®8Ø‹iK…mØš79K(H~ꊊéØiA-j’~+¬üâ–Œv(9•8ÎV¼Ó´;)Ê -##¸bV¶XÝom|‚—ñ×–¬p5qfz*xŽ°ØžØ_ -AîO†–H6ÉDžÅS0P—ú“¡¦cZDß-“b ËЯ¿Uš:%„$|ÃÒ 0UÄ„Ìň¸â³Æ_*ø'" “ÇÃmI [F¿½¿&p^:ÿ'³€d†UCÜHµ*{œtUhÌ_H3GZߨÚŽQÄ6[æ?ÌïJˆ`PªByß·´V §Êƒ-9ßQCÀJÀ.]ŒVæ<¤gXÇ‘Š öao’õÅ®$ÃN©7ê¢í¸j)l€°˜’BálÑþ°B §ã\YNcʾpAÛ@8ÎF}ûßBÑ#,&Æ,¨’qÔP¡‹V !¨ër) SÔÈ·-…ÅŠÓ\øn@ÓÇ!/4Ù¦Ok÷üª½º=¾Æ€@J4Õž†Ð{1Mú"–õf~àÅÏ,¯¡7„7ŒmW‹¨xÓ°ê` :"£HæÈs„Œ"™ £„Œ.¢NƇ 6V»@Ý⎺.j¶äCßþ:DCÕ‚`V -cÝ«FgÃ/å¶jНþÞדߠRÅ8hSwD§0 SÆ:vô*²øàä -^0d~œ,Ĉ5ˆF(,Ú|ÀÈ­]¼ÇýÆ|BÎI„@„qHð°ž7o¬*žQ¶A4ûÍä…õa0îWWÍvb6C«—~ÙiÔ àÙüw—ñ×:WŽŸˆSNœ“ѽÆFxBùi˜ -ú!G‡·½\@_x¥ [¾5&~(Š7,ûol -©mø¯(¡Ÿ¡AAÉM@rgJ'Ï¢«PÅ*s5M¦ õ@¬ðù T$±/ãx¬ÖÊ`¡ð+|*س«ñsröçÇI_I!Oç…DòV»·¹à ;“_q‘©¨´ž9k¢Vó2‹T…Kd'çiÏ(L5Ú&uU¿¥ÖÜdpÄ©)AìÇy‰M‘#¾ÿÈ5H% b“ Ü6è;q* -ó§ñº«¾¸Ë8‹W‰=öÃO¿PÚ¾þ-ÿ.ˆî˜ÕšÃ0«QΩ\þzÄwþë§‹@Ç‚ÎWlb?@~Hš²ôO"BúøŸ •¶`´—ÿûHNÿf+_¤i´\²‹TêÇ)ÂD!ߢà‚r÷Ÿ&—¤ÿbÈendstream -endobj -1073 0 obj << -/Type /Page -/Contents 1074 0 R -/Resources 1072 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1066 0 R -/Annots [ 1077 0 R 1078 0 R ] ->> endobj -1077 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [464.1993 488.466 511.2325 500.5257] -/Subtype /Link -/A << /S /GoTo /D (proposed_standards) >> ->> endobj -1078 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [55.6967 477.5271 105.4 488.5705] -/Subtype /Link -/A << /S /GoTo /D (proposed_standards) >> ->> endobj -1075 0 obj << -/D [1073 0 R /XYZ 56.6929 794.5015 null] ->> endobj -146 0 obj << -/D [1073 0 R /XYZ 56.6929 556.0057 null] ->> endobj -1076 0 obj << -/D [1073 0 R /XYZ 56.6929 521.4772 null] ->> endobj -150 0 obj << -/D [1073 0 R /XYZ 56.6929 361.9951 null] ->> endobj 1079 0 obj << -/D [1073 0 R /XYZ 56.6929 325.2573 null] ->> endobj -154 0 obj << -/D [1073 0 R /XYZ 56.6929 133.2872 null] ->> endobj -1080 0 obj << -/D [1073 0 R /XYZ 56.6929 104.8892 null] ->> endobj -1072 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R /F48 950 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1084 0 obj << -/Length 3001 +/Length 3492 /Filter /FlateDecode >> stream -xÚå]sÛÆñ]¿‚o¡2æå>CòäÆJãLâ&±Úfšd¦ ›¨)€! Ñj§ÿ½»·wÀI©™>u<2îc±··ß» ˜qø'fÖ0®2=K3Í f¶º»â³÷°÷Ç+áahCýáö곯T:ËX–Èdvû.Âe·VÌn×?Ï¿üúå÷·7?^/¤ásÍ®&áó—¯þr-„˜¿|óåÍ+Úzõæ- ¾ºyyêù퟼aµ±ð^xóí÷ß¾¾íßøõö›«›ÛŽÒø6‚+$ó·«Ÿå³5\ê›+ÎTfÍìÎD–ÉÙÝ•6Š­TXÙ^½½ú¡CíºW§¸c”eÆÊtŠ=Ù{LÆ%•cÏÍÇün·-^\/”¶ó×ÕŠá>û -¶û7Á’T8_9äUÛ¼Ìæ% 켬Úb_å[Z^mË¢ƒikz. Í—Ûb¸³¿v^4õöÁƒcl›ºi«ü®ðøòj¿ŽÐ«M^½÷Hïòr‹W˜-Õ !XfŒ$âËv€I:ßõÎQ㺢g» ÷mS® z’ÈùmX^Õw»¼z¤I¾mjŽÀ°ì=G`]qïZÿò&ðØóÕªhÜ®ívWžÍËÊ݈¯NXÔÕö‘TòŸu…lÂa»É[åt8Mª:¬>£Hn–·[xøÉ»€Ô/ô·sH‹öPï?°ŽJËd­£ò5²V -GźØÃ”{áÁ2Üxº-›_ß” *£4^°Ös^8”H!.7EKK÷;ÿîÁ#…†–p\Aý oíQ Ym³ùŸªb„Ìã‡ÑÒoÕþHϤ<Ÿlǘ¤Ùün8HÎmã`à‰XØëïi§Ùå«Þ4ujŽûÝ«5Œö©ÅM¢—–ª¢eÞ´eíGB¶J ʺ)WF§0ùEJ½s õÇGœ /KÞÔ!+Ø*¯üR¾ýàG5=—5šŽIÍP›Ê€Ê³íEЭ‘²½úîo“ªEfi¶3/aœØ NX^zàU]ý¹|O—_ÓªÓGx¾«÷bËšäáýßî‹}Y8å´N±k;ò ZDL™©$ .´)ÛB°ŽìckKl"=ø‹ Œ mãÝ~¬ˆYþ>Ì)©PJ Š ,q¥àài…Í:œ ’#— ?Ëc>È'a!Gqi™ŽhpÐq5(ÚMz Ç"™‚8ähR "‹=Î:´8!]Âùl9ïU´Eo=,ê8¡…¸ËÉqaZ?Àb™6ù=\?ÆŠÙ€’“¼öÜ€œÀhžüÄy)Ë Üž=.³#Åy†"Rø™VÍ”0ç*î¯*…f‰„]Èu&çhú<™{ç׫–¼Ã“@2˜$铯™°Tu¹Óôý …yòõÆÀu OE1“‡˜™Ä.f!ü%‘s„ÉÝ}㯺,<—Lʬæ ÌãØeJŸás]6à$ëÍ(€Aç;XåèCCs¯á4yG¼¿ó80Øã O¥O]S -î·ÚÞ¯Ëê½ÇïbЇ½ð™Ð1J5màŽË†»Hé’Ö)qâx¶Iw(N•Eñ ÑGÚ.•u绸|¿Ü–+”݉N¤#.¸ZqByÁý -Û9S§¼¦$K2¡/él’rñ,G–Wð¯¸\Ó0Åd}H¶þÜo×tq®²ö0Í=%0bž7ýeÝ2Ÿ–ˆ¿+Ÿvú7½óE]g•;t|ÄfR¤ÎPp‚©Ü”+€P)y°ÄÃápž•d—ø*LÜì»vw§9$*Àcþè,Dûˆw‘õ•’TÂ]껟|Æ©øÇNß\ÃR(LÃUØÝGïgµïkŒjåù;$`™Z‹K|ô*¸Ä/0Û°DwJŒ×dAö -Ž“v¢N‘ Rëu‰ÆŒ¬:3äA7&ãP¢?Á¦ãVʳw”œñä¹&!WÆ&E×h6dHHº¯0quW¬Jrv|þÝO´x$w\tÙ=…¨£²ê($¸ºÔ©¸¹õªËšÑ=£ÚüýÓO‚ré)åÒó] aŠ|8¼C1B_®#_»Þ—C´2Á]`𘪢X»¸„¯«üÞEˆ"lSÐyOÔ8kW»ÈP*KÏ?Q`‚A¨Å`xÈÚ+kÔ|[×èR°ˆµ©Ãáâ# Z}]lˇ€ÃÓm·p_h\kËž"™ÿõÚ˜yI– -õ’Šc"DŒdñbTnbBÂëê8¿¨i@Têuï÷b3TyúBá9¨7… -/ª}µX ϶N‡ø¯=™Ÿ4!µ¤§·¨a)šwŽÙ‘àsȳÏ'ŒŽGûåškŸ:šÀfØ,ÕÊ£ys½H8aƧàô š:Èû§ºq‹€tpÝ7¨`J_—Ó¨x¤v–v~•Ä‹#—±8ƒÙäÛw~Í?AÓ]È¥YYuÃB—6Á¬¯ß•Iz >-‚‰ïàÐgEîÅbRC]>ijù‡ÊÝŠgd?]ãˆÛÞ~pÑß©ÛÎùo—.´MÈÑc[gØÂÔ ë@ qQKG¾DØûíµ˜?º²Ë¼uß­·úB‰gÇ$r8GÓŒÍÏñiØXñ -<‘šGPÎÁž0ÓQ ÏU®QÓ%>d•£öxw½{¤yÒò~è2«<;pcVÅM]Ü },åûXèj›Cähp瑞]²7ÄØçî2 í3XîËŸÿ¹Õ(,xbSz(œô…‘Ç -|_æ«]ûôß;N]W—¼hs²½*!DÚŒSº¨0¾‰Wk7ªéé;•0Ú]», …JXÌQ¹;Í–RÅlØ®·ïPS„ ¡wlÂŽ5´ƒ2N<ää+ á`ÊvE±kqOä?³‰ -I!ñNDÅ/e¤ó=mEû$…÷ -Ĩ ìSgyT©¸¦y32ËÛ>xßUP‡2Çm‹U[>xHäÍÈõÄ&œí®ûøUÀ ‚Ãv -“7 `©gŒN¡wbAÎÇü&ePÁ†¬¶ÿL„N|&‚šÒŒ†¸;ô3½ú ¥G=û/mýù©ÏlJ~59ÿÑ0†r_Å (ˆÊZá¢jA¤ãC1×Ξ?µƒ:>v”¹ÃX'Ãc¿…Ì‘.Mi# 'øËQ|¢$Q†™„«Ëe¾J­yBÙ¥ŸY“¼Ñ Ì?%Až2®­½ ÁêŒÔe ž;5’àøØi ÆÇþ/%x¡'(ÒÄ>£‚~J›PfÃ6ãIAJkYzIŽÐi1 ‹R¨ËŒ:wjÄ©ñ±Ó¬Š½éJ£Â1|öë?ãåg†Ç™Æ&÷Q>´ì2ž$£²®ÏOòÿTÆö¤ "•†*Î\ø%J uFF게ÎÉh|ì´Œâcÿÿ‚ -ä•Pn»ÎK0‚:#ÁuY‚çN$8>vZ‚ñ±—­ $ZWÅ“¤h$ƒÜ.}’“gÇ“ÿRŠkáÄŒgÙtÒ ©Ù—jêä¤:êäÀ¤+3°–ñß[qú4´SlýµÎ`xðKÿpÂp´.šÕ¾\Ò3à¨eý€¿‚Rdþ¦n‹€*oÃ(žþÇ81E“¥eG£|$þbT† ¾ÇNo2æP`Žê,Z|¬ï÷ýOƒ¢Š£m¿¦(Æ*­AV+;øyXRð¤Íýû ~Œ”»ƒ_Ä/+÷1^dÄ[¬†Â­GÔ$œ ‰9²¯t‰‚1®è±²ØŒMÆõužFµûñ'š‚Zâï)HèùjK; šþË·S€MüÏ?“ú ¿˜á¢e"^ü÷A§B3p€>Õ!zßRX”»fñ¾^lŠ}q¦¢{‡àޏŸ9è_1v:¿7 ½8!2øóÖð»$Ùût E«µrZøŠ'ÌÊ, D!éòHݺ_S“þCHá endstream +xÚ¥Év¤Fò®¯ÐÍè½.H’„™“Ü’ÆígË=’fy^(n +Ê@©ºúë'¶d©Böa^È%2222ö,ÿÒƒŸ©#7J‚äÒ$¡«=__fÛ ïòæþqá ÌÊ­¦Pß>]¼¿Sæ2q“(ˆ.ŸÖ\±ëűù”ÿâ„®r¯ƒç|¼ÿðpûãíýÓ• ë®VöœŸº¿åÖÓÃõýãÝíÃ#wõ´÷ñ¿wðõ¯VÊ„óá»ëOO·< +Öë›_ù¾ï\߸½á©›{Áqw{{=ýëáöñê·§ï/nŸ†CMî{ +OôÇÅ/¿y—9œÿû ÏUI¬/Ðñ\?I‚ËíE¨•«C¥ìHuñxñÏád––.2Ò÷Ü@EÁ'µÄI¸‘‚)ääÓ¦€cEÆéŠöµh¹}(«Š[iÕ5Üj²,íʦN«ê(PmÙËbäë¯Aæûí¿Ì_œé-þ¬Ùzu_Ô}'¸×'Àû]žöEίMMÃ±Ó -¥]HSpÀˆ•ﻉÖêWÏ ª.3TŽX"x8ö[7=7rFSÛm‘—°).ñtÝ;`®H³Àët[fÜa"ßyó\dé¾dý&• ;Êá³lntUs¨MQs+]:M•¶W~ì¼ ‚ ±ü€¾#» ³&àâ=ðƒbì2ë®/Ò(T(Ìb/mŽ//ªôhñ=í&ü¥K€¯¯ù»-ë}_t„UÀÀ©Êú…çÒ2ÒÅÖ ÇF—9=„Ï"÷ÍRá#)‰!DµDJäBž +•sÜAÂp«:Ä fçáz–Àº§î»co£~*ÏsnsvrXxÎ }çaY<¸ˆÄDs téaáBãêØ3q ‘ëƒ^±›´ÁIÕ¤ù Á,ÿù)õlw‡…«¢Ds˜Ðõ<ÏCD'¾Öíõ…Àm ÐCæ»>0ßæ©W+ðAìµ3g÷ó`xžH׿o–¨žóÁCóé°N&þ+^r«ñ`âbp«<>O†qDºo²F֒Ƀ•)wÙBCcÝ’®ûãIÈ% ØÚx'[Š­‡Öx5 üLß-e%g,È-f¬g‹á®ÈJzvº‘„Úy¸ûÀ»kÂ9EqZ# Ù½Ž@Ê•ëéÈ`†Î“íË%7&)ý¿š.8OéÏñ"×~ùÄÙ»¶Á‹]í‘3™ˆõ#$9»ò¼ûí”hß ÝÐSv‘~«Œ3@­¦`礞c›ø:P~ã{ñRL¯ÂÐI³žnœÚ|ù#öË„è¬T;ß~¼¿á©„?Ý~Ñu/Ëø¶±E"Œ k°)16!Á±’Ã@Ò¨ Ì2)›R¡9æ)p} >®¬×b.ŒN $ÉR>¤+¯)©ÏdL5$ºOœ…HUû\:ÖNcÛR Ë·ãaœ‡r‰S[âwô©d ?NíÆ(.Î3¾õ;HÀP”rëR:©å³Ý‡¹Làƒ]nÞqêäA…ôFšÏè‚ØVQ +ÙX-¨×56ð„Ž¾U*tvE‹ÀvCq–Ãë=…**´F¦&¦ÆÑH^‹‘”‰ Å—ˆKDÄè@0,VÖ‚“Œ NíHÎÝ¥ +c×x¡0Ê/œ=­Öm³]å€:@T û‚CHP´ ËNÔ*ŒÜ0ð‚9OºbÈ%‰g±+D:LÇÅÝ|ã&`Cçñ*äòq¨ƒEÆÊ–Õa¬­u2ƺV`nfYÔF†•Ð +¡û¾ØîzîPhˆE8Ò€ÅÆ¡7Ù¡ìy¶”~ñeW•Y‰…1êç–æ ±î‰$Ç·ÍÛyÇL—°és³ï¹ÉøXÌÄڼ㙮(¸Á²€°E—µånÄCN *°õ^œØ›i±Â×õ+’”ó+ÒÚÕ:±W”U’_þå.ÚÀåy6º”*Ê9zå¹¾¯­´v=Ø 9c"p> /Q˜œÆF¡ÄFp'ýXeÿ“p'f·Uô"K`%0]Ãï¨#tq˜×âðkY¨Âr%‡Çºò¹„=‡,G _”]¨Alt;ª()Úà,XÁ‰­²– +ƒŠâKå;ÃŒ±5‘¦âȈ–Êwß±M\0^G‘’Ú¹PÂ]å°ý ¹VüþN%NEèÀ&3–±¼ÌØ0tcÄÃm÷ûõO£û£½ÆŽ88 —´B¡5í°(ÊäÕ<Áô’ÖåW«+0j âxHë~~2¶L0ÀµæP +ý0#ä#›|7ótR °©ùŸ–y~"oÖ%·D™ÒÏsìl`¢³R†£D¡¨»ü„@Gð][*Œ’0Ùˆƒ0Šh0BÈ…|%±B„mž¼êÄÆÀÌPL[zí€õXšq)ÉOUò vËš›,ߟpIJ»ŠŒžÞ8Ζ²²k¶2’ÏF±àF̰¡rp¿¡ø7“/•¬š93Å +Þ@"ìmOì.… GE‹´¨d¤Oâ)¨ŠôsÇM2Æ Äß-•I±#@è×_Ë”;„$²ÃÒ PU´ ‰âKŠ¥ly7„VyDN%5luéëëñ­ûç•fŸ³\N¨ + ¹VEè´­@c~Bž92|Mµ?ã*5á?Ìo ˆ`ðV•q¾k¨­6@ŽK2Ù£‚€•Àª4ÏÅZu§Ñ ƒG¬&¶{“¬/´%9¶òȽA©c«¥°R°Åœ*«‹ôÚÆ€Óq©,Ç!g_ÐÔŽ‹’@ŸÞ­dŽ˜³ ZHÆÑ¾€&bËeü%Ëe0L=r#Û4Isá»·)¬å…¦èô»“ãpíÕ®Á×’ºƒ Á÷ž È{ Mkþ‚E,ªõáÏ Û4ŒM[-?\×":¨–QEsËslU4±ŒJ³e´u4\‰²<It‹[îÚ¨™È‡>=òÐD´ ¶ +ˆƒ‰láVƒ3‚áçbSÖù›À=û݉U*ÅRêŽÖÉOüXl8z}°÷ÔÒ«™ÌO@ŒXñUKðçM¶ÇÈÂ.îcÿx0ZÎI„Àlãà‰Á^8ÞÄ|cUñ$ˆ¢+ÐìÍÄ>®í;ûjb«Ùö4ehÕÒÎL¢žÁžÍß],¦¡?¹NíÙëœÄˆö4á©ÈõTÚØÐõ%:¼eÓ+ô…SRØòFÔ¨! +5\$û¡è¿¡,2¥ðßpÂÿMe7}È‹|!ºòPl[ÓÊP” +Ÿ»@Eº:«µÚ[(ü*WùÆöâjÜŒý):í­ôˆÏg’7©=› ΰ3yYD ®äÒzbµ‰W’ä%dÿ¸ +›è$ŒNÓžá2Í ›Ü‘§r3<±ŠÊàˆS6±Ÿæ%6ÃŽøã'©Amu›l©Á߉S1˜?m1ˆOÛò«ÝL²xÚ›æ´ýé(íâ_kªZÞ ›ÿ÷?xÆÿ9…ÆUq,—Ç»a H„(äxàQnÿêsNúÿuðåÃendstream endobj -1083 0 obj << +1078 0 obj << /Type /Page -/Contents 1084 0 R -/Resources 1082 0 R +/Contents 1079 0 R +/Resources 1077 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1066 0 R -/Annots [ 1086 0 R ] ->> endobj -1086 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [417.8476 181.7231 466.5943 193.7827] -/Subtype /Link -/A << /S /GoTo /D (sample_configuration) >> ->> endobj -1085 0 obj << -/D [1083 0 R /XYZ 85.0394 794.5015 null] +/Parent 1071 0 R +/Annots [ 1082 0 R 1083 0 R ] >> endobj 1082 0 obj << -/Font << /F37 799 0 R /F39 895 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R >> +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [464.1993 469.2511 511.2325 481.3107] +/Subtype /Link +/A << /S /GoTo /D (proposed_standards) >> +>> endobj +1083 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [55.6967 458.3121 105.4 469.3555] +/Subtype /Link +/A << /S /GoTo /D (proposed_standards) >> +>> endobj +1080 0 obj << +/D [1078 0 R /XYZ 56.6929 794.5015 null] +>> endobj +146 0 obj << +/D [1078 0 R /XYZ 56.6929 535.4755 null] +>> endobj +1081 0 obj << +/D [1078 0 R /XYZ 56.6929 501.7295 null] +>> endobj +150 0 obj << +/D [1078 0 R /XYZ 56.6929 345.0948 null] +>> endobj +1084 0 obj << +/D [1078 0 R /XYZ 56.6929 309.1395 null] +>> endobj +154 0 obj << +/D [1078 0 R /XYZ 56.6929 120.0167 null] +>> endobj +1085 0 obj << +/D [1078 0 R /XYZ 56.6929 92.4013 null] +>> endobj +1077 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F55 1040 0 R /F48 955 0 R /F39 900 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1089 0 obj << -/Length 853 +/Length 3046 /Filter /FlateDecode >> stream -xÚÕWMsÚ0½ûWxr‚ƒ…¾üÕœhBÚf:™4¸½$9¸F$Ì›X& íô¿W²°‘ƒ€PÒÎt˜Y^½]½}+VȆâƒl×^ˆCÛ)p!rídjAûN¼û`¡¥S9ºÕûÈêßAèaÏŽÆV` ;]w(  +`gxùùSÔu° ;§îƒê“ýËhp¥ækÓþé·.B¨Ó¿8œjKäàlÐïú´}½ »·Ñ¹5ˆšHõÝ Hd˜Öõ-´GbSç$ \ûI<@€ÂÛS‹º¸”z&µ†Ö—P{[-5²ƒ ÀÄÃz(Òè ð €òÝx“Ѐ܄@r¡ëâjzœOq1ê:„)ì¹ÊHòéÑJjoÈÔTH¦ÎP…%}Ôn[þËŬµÆ,óI |4í­tlÚ¶¡4…zFGy-ÃbZׄpQÄåäQŽ}*j8ÛAiÊÓyÙdV*r…Y¶ê°‘§cÆ<@¦Eo¬9ƒîª°Œ9z•Fð¾áiüÈö“Hµd—Bxo=#=Jpmy äñM6P‹w¨kãð_f³Ié›—rãaÏ:>€é½ÿ£ÖŒÄ"#±Ô\.¯!R›xŨÿoä䟥¤w&z®U;&\ÑÕQÑÂJ›AÓÉ&SžâËÆGMÜ缬Žïv3ªº'5NòìB|÷N9kõ~/œÅIjda-°‡érƒ¢³“@ú¤Yl |s¤´àN -ùLšó'ÀŽäÏ[Bì½eK¸]—q¶Ð]»PïØ8ž§Ûš?Óe„¸@Þ WØðxðEeuG£> A€›;HKôØ È2(ÉÆk‘×7šõЫendstream +xÚå]“Û¶ñý~…Þ¢ËD>LžÜøÒ8»I|m3M2SJ¢-Ö:Ry'_;ýïÝÅ HQÒ]3}êxÎÅb±ß»”˜qø'fF3®òd–å Ó\èÙêîŠÏÞÃÚ¯„ƒYx E õ‡Û«Ï¿VÙ,gy*ÓÙí»—aÜ1»]ÿ<ÿê›ßßÞüx½šÏv½Ð)Ÿ¿xù—k!ÄüÅ›¯n^ÒÒË7oiðõÍ‹ë,™ßþùǘ&Ñöùo¿ÿîÕm¿ã×Ûo¯nn¥ñmWHæoW?ÿÊgk¸Ô·Wœ©ÜèÙ^8y.gwW‰VL'Jù™íÕÛ«ÂhÕnâŽV†i#³ öH5ųTÁ²§ÙÓe~‘2iî»¶Z—8¤É¶\uUSÓKóŽž=ê²;4ûŸÑ[·):U­{(ªm±Ü– ñ€nbw¿ÜV+†1æ|¶˳DZ +o>w»m ©ÄÌ_Õ~Ïàn©`i–hØ‹[EÝJæóŠf^Õ]¹¯‹-M¯¶U`6|.K%ªã•ýµ0ó²m¶¤ücÛ4mWw¥ÃWÔëx;B¯6EýÞ!½Æàf OõB–kM÷=TÝÓl¾+›¥Æ(|ZþÙ ¨ešÊù­Ÿ^5w»¢~¤—bÛ64òa=Gà-ºâÞtnó¦xp؋ժlíª ««rßUmoćWñ',šzûHbÿgS—íXg +:Ü)VÓMjPÞnB†Úô«¿]¤­,PiŒ<Ä+d­àh +@ź‹PÜ ¦áÎÀÓmÕnÜü¦jQ¥v€¹žë°áP!…8Ý–MÝïÜÞƒC ++-M!á8ƒúãwíQ ÙÄäó?Õå™Ã£¥[jÜ žI18>™ÀxÉòù/\óª¦b œ" k{õ=­´»bUÂA¯VÍq=lm`´w°H-.µ8µôP5­,‹Öy˜DB¶Jʺ©VwFÐ C>jg'šÖKM\Ö"+تpN¬+¶†iÙ ¹YoLj‡ÚTyTCoWÕ#e{ùúo#Õ"bÈ,õÀÖàÍI_Œ'L/ðª©á\¾¿§Ë¯iÖê#<ß5û±eM +¿ÿ·ûr_•V9M‚N§Üuƒ•€€<(èïAÁ”™JSïBÛª+ d{\£XjRéÀ?›À¸H´`\c`"‰€Yþ>Ì™PJKŠ ,q¥àài…ÉÎE’‘#—†²Å|OÂ>BŽâJdJ:’€³BÇYÔ h5í5‹d +bôP­A“ZyìÙð- ÅÒ%‘ÏÆ‘õ^eWzðÎÁ¢Ž:Pˆ»‚L'¦õ,–%¤¿‡ëÇX1_Qr’׎µè„gCnœ8,ÂíÙãr3Rœg("…Ÿi¥I˜Ræ”.´QL)¸ßj{¿®ê÷¿p@öü†3¡c”jÏ› ‡Hi“V)ñÅ&ðì<’p(¾x*-Š>â@'¢4!•µçÛ¸lÓy*p‰Ä'"´ ®FœP^p¿Âgj•wBÔdi.’K:›f\<Ë‘ƒåÀÜ›«bÆ¡ÜØÂÆHàÏývM7 —þ: kÓÞS#æEÛ_Ö.!óiŠø»ri§Ûéœï O KôœØLŠ _0•›r*%÷–x8.p dzÒü_…ν›}×í.à4 ‡TyxÌ­…$.âmEdG}¥$•°—zý“Ë8ŸàØé› ­Y¥³¿ +»ûèül"Áûj µòüRH +’D\â ¤WþÀ%xÙš¥IPb¼&ó²Wpœ4C`ë *µ^WhÌhÁ*˜¡¯¨§ãŠé'Ø”bÜHyöŽ’3ž>פ äÊØ¤èí† Iw&ÎîÊUEÎŽÏ_ÿD“GrÇI›ÝSH€:Z+£Æ9BmëR«jàæÖ«5£{Fµùû§ŸxåJ¦”+™ïSäÃaňÄûò$òå°ê|9D+í݆‡©.˵K¸­\÷6Ê@A`É›BÌ{àA…‹¨˜‹H_*KÇ?Q`‚¯Å`x(üœ-kÔ|Û4èR0‰µ©Åaã# :‡}]n«ÃÑ-wp_wh\kËž"ÿõZëyE–òõ’Šc"DŒdñÙ¨ÜòÄø„×ÖqnÍSíÓ€©ÞS/6M•§;ÀžƒŠqSºÑ ð¢êÐU‹õðœaëátˆÿÆ‘ù‰o™9<΢&Ûn#EÖd$øòì‹ ãÅãs–‰,µÇjig˜c«R°,Q 9š7׋”f| +NO¯©ƒ¼ª·ðH×}ƒ +¦”vu9ÊGagiçfI¼8²‹5˜M±}çæÜ4݆\z«ê€ÑO„´ Þúú]é´êÓ"xqº¬Èn,×S&hó!žÏ?ÔöV<'û #nzûÁIw§°œòß.“’£Ç¶Î°!…©Aè@ qQKG®DØ•ûíµ˜?Ú.·Í¼“¾[5nõùÏOuŽ ¦›ŸåÓ°±âx"5 ¬ƒ=a¦£ž­¨-í²ÊQ?\ïiž´¼Bæo”Ã`n̨¸©‹‹¾¥\ ]m{ˆ ®<Ò3${CŒ}î.sß>ƒé¾ qùŸÂ‚#f1%Oá¤/Œ<–çû²X}íÓ|œ0º©/yÑöd{UB(ˆ´_é¢B»rL¤N­í¨¡§ëTÂhwm³€ *a1Gåš-¥ŠÙ °¡·oQS„ö¡·l Ç ´ÏãÄg +H8˜2¡(¶-î‰ü'g&U>)$Þ‰¨ø¥Œ”c¾—˜cÑ>Iá1j»ÔÃZU*¶iގ̲ĶÞwåUã¡*üq[üðóà ‘7[ ×e š0Ý]wY«‹_%ÜÀ;l«0Eë ò–zÆèz'æå|Ì¡3¬ÏjûÏDˆáÄg"¨ ýðɨ»C?Ó«ÏÐÁQzÔ30þ¶õÅ© –e Ù³Ÿ5c(ûÝŠ‚¨L€¡Q.ªD6>síáä9ê‘O”$J3ru¹ÌW™ÑO(»’gÖ$p»tX柠Ì%3J賌¡NK0@]”àÙS{ ;)ÁÁ±ÿK ^è BâižQA?¥Í(óa›ñ´ 3¨Deš\duFê² Ï r|ì´ ãcŸ.È#ýÊò´ìNóJ§Ì £<Ï«ê ¯<Ôe^;5âÕøØi^ÅÇÞôm¥Qùè?þõŸ‡Ñ€²4Íã| #”ý4ï÷@OÓaÚóMŸ%Ÿäÿ©¼íI¡EJÇBHIŠZ2Èð²'I1}vTù/¥9œ˜ó<Ÿîäàjùe õs²$êçÀK(6°¢q_]qžÒúÌ73lvÖ`xpSÿ°ŸÃp´.ÛÕ¾ZÒO4à¨e󀿂‚dþ¦éJªèüÈåŸî'91E“f Q>9*F_‘c§·ñy³/3GÕM>6÷ûþBQÝQúæ_[–c•N„a&Qf&2Å8§ßÛÑâþýŒ?FÊàñ†cå>Æ‹ŒxÿN1qDM +~'sd_èc\Ñgbe8ÓÚ¤ã*;O£ +~Èø­ÁD0cJ‹Õ–Z~>¶ôú/×ÌÀ8SÿóÏeò¥›ÌqÒ0OþûK¯S¾%8@ïƒê½k,,ª]»xß,6å¾<Ž2¡f‡àÇ©RL3ü!å„TàÏ)üïþ½fﶨN9‘¤(É ºMGÞBiTøaç1éÿÆv–endstream endobj 1088 0 obj << /Type /Page /Contents 1089 0 R /Resources 1087 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1066 0 R ->> endobj -1090 0 obj << -/D [1088 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1087 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1093 0 obj << -/Length 1946 -/Filter /FlateDecode ->> -stream -xÚ¥ÙrÛÈñ_ÁòYeŒ0ƒ{ý¤µd[›¬ãXL^Ö[®!0$Q‹ƒÆ!™IåßÓ=Ý Ú7¥*ÍLOOß(—.üÉe×Küe”ø"pe°LË…»ÜÃÝÛ…dg@rÆX?nWo¼h™ˆ$Tár³ÑŠ…Çr¹É~Y½~wýasûqí¨À]ùbí¡»º¾ùçZJ¹º~ÿúö†®nÞßÓæÍíõ:òW›|¼EˆT ¾ øåæþîíú×ÍO‹ÛÍY¾±ÒõP¸/‹_~u—¨òÓÂ^ËG8¸B&‰Z– ?ðDà{Þ)÷‹¿Ÿ ŽníÓ9›^,‚XE3FñåÈ(I(’Ä–QˆÐSž5Š.ŠúÑùÒ›æä¤:=˜µºîêß´äUgšJí+:›¯Óó`• -6WWhLÛ5yÚÑiDP§©i[´íH)’ P# “öM›×ÕwóWþ³ü/Dgø -!¦`9Ÿ“GÀß(O$èb„þ«®XÍmÞ)ÌW] #Òº|qVHzcKµƒ÷…~à­%…,®öÝéÈx¥nÁ¯æÛåÝåɳ«k+Ë«9É]£«vgšïµÿÈVêOØJÍÚê0€µÙéß^ßÕŸLÙN×UÝLóy w?ŸuÛ}.õik¦šÏÆòŸ3åZòê äì%µ'…ù¡Å¹«¨hØ„<É}5?Gˆ YR`‘j7C8Œ…ò}ɸŸÜÀ­¢m¾ôùƒ.LÕT¬ñµ6ÐnH¡Å?Ìæ@U‚º7èYž­ÑMz »|“¦d’J—¦5ÍÃ`e)!CÿÕœŸG÷¾ºÏ“Ké Ï»"5â˜\E²Ýu/=bÆu®ð•"üÍ!‡èSa¸VMK{¨›·Ájßç™!hWó­éº¼ÚÓ¡?ÒºYC“ÂøÓ){€ E¥»¾YËxe˜zÅcO pœÉ˜ÅS --VÒ¼;±˜ ýñîý í]7gÇÌ´i“o‘§'ƒUzÐÕ~8 vÅÀ±·uõÉuÕ¾o41F B -FÐüòÑÅÈAw3,4iLÚCÓ&#èc7Y¾C8¦-^WLog.†{9Yy•}F~§ÁÑ>ªm×£DÙÑš5Ý]ÞL¬ €ß̉é*£Mß>Þæû©{ö˜wÚ‘“É!eXÉñP¢dÍKÝäʼnŽm`Föf"^æ-¯UÛÛÇ‚’æß`Š0ð&!@ætìê}£e^òÖ>ÉîP¥3‚lO´’ÿpgeðØé†Õë¦ÉkîVœÈŠ3t˜Qû–žðbü  öÔ²‘¾m-~ b•DŒÈRRå™#§öT´‡\Óf~|@6IbÅdßf8Ë@Dž8cZÎŒ!®}ÿLæ4CÆÑ>gâ'ƒ7Ö“s1,òŠ«l}ì83ñÀcJ^]Ð T?Í´ w³††QD(é,!â9MCºQÈ8â2 ò‚ -ÌKÔÂKàÔUÃd $ÏoMeé(ÎýA7†Õû˹üï•nuÊåüƒÎ›©&ï`Æjç§ ’Æ1:C‰õ¾î¹³S©:nJý5/ûò̃6ðEµ·n憥 R±Ày‡ßˆ*Q$ÔLC-ÈKúüE¦»a´NE\–Ã,Ô ç2,’ðq=c³>å—š–‹c9Èq@ãèôãiP§™¬j¡â8ðâ…>®Më¡Ô©SfC·üé¥b0ú»¿ÝoøÁ(÷žû%Î þ|6ó»™{®×ÿ÷¯t—Ÿ%ýút¬Î?ÀMòËsCjÎ,ÚCyO%?ÿœ÷­èÿ¢ „êendstream -endobj -1092 0 obj << -/Type /Page -/Contents 1093 0 R -/Resources 1091 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1066 0 R ->> endobj -1094 0 obj << -/D [1092 0 R /XYZ 85.0394 794.5015 null] ->> endobj -158 0 obj << -/D [1092 0 R /XYZ 85.0394 427.2881 null] ->> endobj -1095 0 obj << -/D [1092 0 R /XYZ 85.0394 390.6298 null] ->> endobj -162 0 obj << -/D [1092 0 R /XYZ 85.0394 229.0656 null] ->> endobj -1096 0 obj << -/D [1092 0 R /XYZ 85.0394 200.0179 null] ->> endobj -166 0 obj << -/D [1092 0 R /XYZ 85.0394 151.3455 null] ->> endobj -1097 0 obj << -/D [1092 0 R /XYZ 85.0394 127.291 null] +/Parent 1071 0 R +/Annots [ 1091 0 R ] >> endobj 1091 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R /F48 950 0 R >> +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [417.8476 169.1947 466.5943 181.2543] +/Subtype /Link +/A << /S /GoTo /D (sample_configuration) >> +>> endobj +1090 0 obj << +/D [1088 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1087 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F14 741 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1100 0 obj << -/Length 2314 +1094 0 obj << +/Length 828 /Filter /FlateDecode >> stream -xÚ¥ÛrÛ6öÝ_¡éK¨‰…àB`3}p'uw“ÍÖê¾4} $JbÊ‹"RvÝNÿ}pˆ´¡ØÙgB\Îý± …?6‘ I2žMÒ,&’29YÖgt²½wgÌÂÌÐlõj~öâ­H'ÉžLæë.E¨Rl2_ýÁ2 4š__½›Î8ã^ÿxñq~ù3L%¸xóŸ)c,ºøðúò n½ùpƒ·—Ó4Žæ¿ü|y=ýmþÓÙåÜÓ7äQ¡‰ûröëot²V~:£DdJNnaB Ë2>©Ïb)ˆŒ…p+ÕÙõÙ¿=ÂÁ®9” £„‹„„ÂEH(2#‰€--”ù¶¶@¿w8(;ýeQÙà¼wŸ(åU¡Y~ñ6fÄ™ œÅšñÛ¶ëÙLÿÏÉs&ÓçTÿ#»}y“÷öüˆ0¦$T: ƒX°èCÛoËfƒw¯Êý”©¨Xö•%óÐ#БŒžOg‚Òhqè À¥“O‘ dÀ/$ÓÖ@•AºÌ, -KÍý>_öŽžµ‘A[ã õ"½^Ì8o,,ˆÇŽòÎ~-SÛEé˜,–8ï¿04ciJ˜àqL‘˜‚ùxÆf HùŸù‹Kùúó»ì_ÏÛŽ}þBsþyuñöéÇÜÑ?ó ¹JN¸Nbßp'‹‰Á5õCyyùž–±7Ž%–I’‚ßNf"‡£©>ŒðéŒ/DïóæWˆî]Ñû¼/Û&,3.µ·D&Ò1I"„ûÆ!ôzYïŒÃÀZŽŸ=˜ˆ1!sìË,Þ"m׸º(û|ˆÇCw€uÎ: Ñn&£÷àç¸~qýúêÊ"6*íìÅHNnòª\w¤§ÜP¨ñùOTÒ¼ë5Z l÷NUÑlú-.–Ý€OÕ‡ª/wÕˆ7Yüè&z½Añ(K˜Y\‚tµÛí; =d@ -PĬ„ºvD’ª&ÀåHQ!;¬e¢`¶AÛ(VÄ#xÐEÕµšŒ”¦“4ú½ioz¯‚1Þs |÷SìZ¿Å°rØlæÌ'"É”õ ºF“˜*øhœzm÷ˆÝ†XV¹]Ûá…›}^[Zü:v-±Þ"`â,9x–‚1–í*ïó£GúãDrŸ²^¤]Ñ9âëvwçƒ÷økСóökИӖ¡¾¯ZctR;ò’d¢Ç]ר§JÐN•]ÜµÆ a o†ÅnÙî -\3& _(<n^àØÐÁ[¤>%f}ÊÚt[5U]ÃöÒö·D ÅôkÓþûl4&mš©Ò)1æúÜësÏu®‘ åÙžü‡vRàAäÙÉÜ‚öµ|÷ÉBK§6rÚV#Ë="‚ÐǾ]µ°€Œ!;šž( `(à`rúõK4t°‡'“¡ƒõØààóè4ŸéùÚttøcˆŒNƇ­%jp4 :ˆ¾Ÿ'ÃËèØGM¤íÝ HT˜·Öù%´§rSÇ$džý  @aˆí¹E=s'©‘…µD@Óåeg''@íI³ØøæHéÀ;:#­àò…2„ŠÞÐânÑb÷–Ðt{ P-¿¡×‡Íw¾Y¬.U4„1Ü\:rÄ”IePŠ"Œ×"¯¯ ë¡ÿp”‹endstream endobj -1099 0 obj << +1093 0 obj << /Type /Page -/Contents 1100 0 R -/Resources 1098 0 R +/Contents 1094 0 R +/Resources 1092 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1066 0 R +/Parent 1071 0 R >> endobj -1101 0 obj << -/D [1099 0 R /XYZ 56.6929 794.5015 null] +1095 0 obj << +/D [1093 0 R /XYZ 56.6929 794.5015 null] >> endobj -170 0 obj << -/D [1099 0 R /XYZ 56.6929 691.7741 null] ->> endobj -1102 0 obj << -/D [1099 0 R /XYZ 56.6929 668.7722 null] ->> endobj -174 0 obj << -/D [1099 0 R /XYZ 56.6929 579.8329 null] ->> endobj -1103 0 obj << -/D [1099 0 R /XYZ 56.6929 549.1878 null] ->> endobj -178 0 obj << -/D [1099 0 R /XYZ 56.6929 502.9124 null] ->> endobj -1104 0 obj << -/D [1099 0 R /XYZ 56.6929 474.9173 null] ->> endobj -182 0 obj << -/D [1099 0 R /XYZ 56.6929 277.7919 null] ->> endobj -1105 0 obj << -/D [1099 0 R /XYZ 56.6929 249.7968 null] ->> endobj -1098 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F39 895 0 R >> +1092 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj +1098 0 obj << +/Length 1945 +/Filter /FlateDecode +>> +stream +xÚ­ksÛ6ò»~…&Ÿ¤™&>›OnâÄnïÒ4ÖÝ—¦“HHâ”…;º›þ÷îbAŠTèæríxÆX,ûÞÅR|éÂ_F>seì-ÃØc¾ËýeR,ÜåÎÞ,¸¥qz"gLõýfqõZ†Ë˜Å–›ÝˆWÄÜ(âËMúËêåíõ»ÍÍûµ#|wå±µãîêúտלóÕõÛ—7¯èèÕÛ{^ß\¯Coµù×ûÄpã=ßÞÜÜß½Yÿºùaq³ôÛÀ]‰Ê}Züò«»LÁ”.“qä/aã2ÇbY,<_2ß“²Çä‹ûÅÏÃÑ©¹:ç_FÌD8ãœ,Ž=ú1 ¤Æ)*Ï«GçS§ëÓÚ \wõ_ZTyzAÐï°rßèêŠ0©Þ©.oi3ºª’D7 ús8g±ï‹K)N¢’ƒžÈÊÊV×¥Ê+Qžîb¤@­›¶Î«Áˆá×4¨uÒÕMV•ß,_xOÊ?3È¥¤cŒÍ©Ó£ÚÉ)´w„d1&bÿS•ÖÌgMÖjÎôgUsÍ’ªx6ÄåØS¡°p®,hX¡ˆ^êD|{:ZºB5àŠs†í²žï³âŠôÙU•ÑåÅÓhkU6;]«ÿG¾ÿ‡¯Ä¬¯þŸ}ÍþæŠdü©ýäÊæ¢Èªö ë[8ƒüùx¨šöc¡N[=µüotå¬'ùÈ“W¯¡3œ›ˆ–.óü824w%µFP›ˆ'F„ÀÍ‹áÒB•Tùx¤ÜÍ0"&<[Ú®ïV5ñÖŸºìAåºlË WäÀºŒ6è7äÐà…ïfs ÷Awím ÌF«:9_ž(ÓRºÑõCïe +ÆÿÅ\N´z¨vìËýKôeèDÌ|SIldŸ‚U¿*ZšCU·ú«}—¥š°meOuÛfåž6Ý‘ÖÍžBÌ?•Ø(´(UÛÕk­´QAõl$AN§VÄ%‡;iÖž¬šûýÝÛWŒÀ»vΩn’:Û¢LÉýUrPå¾ß fÅÄ1§UùÁuž« F$brK ìÍG瘃jgD(²˜6Cv‡¹@šíe‹Ç¥å·ÓgÇ=ŸË¬¬Lò.¥8ŒËàh.UæÕ£BÙÑš7ÕžïL¼ ˆßôÉ^ReJ@×–%–☪Vc$\¹º&ÅýD›!¨cê Nq.¼r¨º<µÊUeK)oÕxzâ3•F¶òÃøÌ±¤( NY¢!<QêZBß½slÄð‚dN&ZàaÖØµl:SàØP’ ê\ÄÞ¤PŸŽmµ¯Õñ@ªÌ›@Ѻ÷åþ]:%ÌöD+Å!£ ¤ÇNÕÖ¼î¨ë¬2énÔ :ý 3z¾¹d2 zžë¤/ŸÏg‘€g”­V`T1H´¥=Uí!SÌØÆq$,[ç·ÉÜg¡½d,Ë™1Äeç lN3l=à£)º¼±Ÿ Í0ÏJÛe«ck+7vLÉÊ3Fú§ž¶ávÖÑ0Š0Á]ßjxÎÒ€nXvžz}Á +îˆ8Z!Cæ +)ûÉ€q;¼Ñ¥®M¦£:÷UkkÞCûßõ&ݨĶów*«§–ÜÂŒÕ<1e@L"îÙPóRzP³êüâ^Û kKú”¤€ß[õ,™©YX±á Ù%›­nµ.I c£Ž”ntœùŒ¶Âc±_fÏ”~ˆш‘˜céFñǠᕤ¦ª·<2Øóp‹ñ5|Sûà¯Ëïh*0¥ºæçIN~Â3æ8F†{l°Ðª6ý`$ @*º¦µÉ©/††f êßömÕ¿ã(£a39‹øë†slȲ뮭 +x„bb“Î~ÿyÂ<) ñ³ÆÌ¸J7Îbí‡|ö¤Ä‡‘\Dxœ68rò€àí©Õ4zâîöŸ×/ûÛkáÛcã6pÂC~8Iâ# +Ãdj%l«=ûmð +F@l±Ä¨!è< ¢x˜‡1CúÒ¾-pbfî¯ÜÖªÉz* iÇ•bÂùÁêmÕZâ–fSYT¡>gEW 2€ïª=¹e`kC mT—/PšÁ4cóˆn>·y¢{Uqg> endobj +1099 0 obj << +/D [1097 0 R /XYZ 85.0394 794.5015 null] +>> endobj +158 0 obj << +/D [1097 0 R /XYZ 85.0394 418.0047 null] +>> endobj +1100 0 obj << +/D [1097 0 R /XYZ 85.0394 382.2497 null] +>> endobj +162 0 obj << +/D [1097 0 R /XYZ 85.0394 223.9723 null] +>> endobj +1101 0 obj << +/D [1097 0 R /XYZ 85.0394 195.8278 null] +>> endobj +166 0 obj << +/D [1097 0 R /XYZ 85.0394 149.2124 null] +>> endobj +1102 0 obj << +/D [1097 0 R /XYZ 85.0394 126.0612 null] +>> endobj +1096 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R /F48 955 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1105 0 obj << +/Length 2253 +/Filter /FlateDecode +>> +stream +xÚ¥ÛvÛ6òÝ_¡Ó—P'!‚ ÁKsúà:Nêî&›­Õ}iú@I”Ä”"‘²ëÝÓß ‘2}Én|N 3ƒ¹b¢cg2›$YÄ4z²ØžñÉÖÞŸ ‹:¤°õãììõ;•L2–Å2žÌV=Z)ãi*&³åol`S ÀƒÙõÕûi(…ÌxpñÓù§Ùå/0ÕPáüí¿¦BˆàüãÅå[Zzûñšï.ϧIÌ~ýåòzúûìç³Ë™—¯Á +÷õì·ßùd GùùŒ3•¥zr ÎD–ÉÉö,ÒŠéH)©Î®Ïþé öVÍÖQΤŠåˆR¤SŠÎX¬` •2Ûp,ÐÃÅ Ê¿"(kšwã3ç²*ðȯßE¢G8SLŠåAŠÛ4m'Bü_²—"V/9þc»}y“wvÿ@0‘j¦¸vÀ‘ÁǦ۔õšx/ËýT¤A±è*+æ¡-Z' ™$|5 çÁüÐL'¡LR¦è8‚eZKÃnž·EGdÜ¢^4ËbI“¶Û“0^5UÕÜúég)£M0—LTìTQÜ}?r^©X†ÞAH†”!ºÈkÌ +ÍŸÝ>_tNž•ÑA³¥ÙE{»˜q^[\På­ýÚCmrR¥;d± y÷ýÈB‘$L¤ +"N¤,âà>þ`a Zþ{þúR_|yŸýãeÓŠ/_y.¿,ÏøaäØ|Hcæäï«ù½jÉdªœÆ¾§ˆ‹ 4žTõ}}yý>¬1f95–i–@ÜNBAÀñÄ'Áä4 Á‡¼>ä‘{_ÔÅ>ïʦ×™Ô­=•©d(’Š{"Ѻ „—Û €åôÙƒ‹2Û¾Àã-ÑfEÐyÙµC2ê‡ÀMB<0 ÃL Î ~~}que “¶–1‰F“›¼*—&ùCa¨ÒáþÏ\ó¼m[òX¢^w–mïœi°=T]¹«gKKŸÂá5©'µ‚à´‹a·o-vÿè( ‘°j›Hiß4#§jÌ·Æ3ŒP0[“oKæ‰õ"è¼j#æÐqüQ7·5 }TÁ˜¸ÀÀpï~š ë6”Vë͈;‹T2g© í–\bÄU!F£ÄÇh³'êV0pIJÊ-lG ×û|kEhèëŽk…õ牔È!²R¨CÝ.ó.?F¤_1A¤ ö¥6Š0] ^4»;Ÿ||Ä_ƒ ]´_ƒÅœµŒœðý±1N§1P¤ =ºÆ?Ó˜ü4Õ`‹»Æ¸!Àˆ3ÛE³+f\¾Ðx0Z<'øÐÁ{$nž +Œêv×ì;‚l páºl·væ9TKÇ•`èÆXhEâEÓÁÂáůÇlÄßÍ>M¡‹ +^ÙÌØnì¨+ªb·iêÂ΋nñ¸i”7²¦¹ªWÍ~;bœbC¡ £¤þ*T¦S ФéåŸeÛ™÷”®¶ù,IxPïŽx*¤ÈE€énÆŠzÄxœi‹… æ>%‘1¥Õ£DRÊ1z1ƒNÔU®c +Â\áݯ%]`*üXQOš•ÒuKßÚ8O.Àû¤¦!´¶/Ú‘,µ`œk§†:ß‚-šz5"{ å:Ž.¨?í.")Xš J ¨&5ø¦ÅÞ¢ßHä?Æ ÿ \1¯Ö;ì6[»w›/BÈÅRÇoJÄÖˆûÝC Åw´5on +´¯ÁuIµÀ¶ç +ô¨½ë32‘§ƒò„£í£ÌäKÇ¥Ûä­‚Ü·•‚.?‰ýû‡yXâ ôSÔMÞ6{L5JÄV¢|™Ï©wWÒTÄ4êAã9^Ê»æÈZ÷Fº·ÑtÀP‚k¡‰'ꡨ2„€Ú«ƒ§=¿ÑúÆ£ÚëW’ø@¢Ê:à°À£ÄÞÚP:›²&˺–C[åàÀa9¯ëòß&Í+ÈÑ6Ík,P-Óö®ÄRu Ç–`:·sGªmóµÛQ®kò¨µt":J‰wêWcáˆ^ªxD +€u¹º£1y AÞÙz„Õ :Ÿ«ÕcH2†Ä¥Ãb¯¦ÁrlÐøÅ=O$G2´ŠjÝžR±ÇÄñüžˆ`ù±ºÓ?·A‰|„FîÞþ@¦ó_Ûâ~=|²ôÙ¼¢xŠb¶4Ê +Ì÷ \œÝmQÔ4én`¦¶»M_MÖçSN?©÷*omGôçvµk*ËávãÈ? R×8Qèëhcf›Q<¿*ÚƒÓ˽ ²Xý¯ÐÕæýX!˜JDöT!˜NR‡e[«ò´ºúäføØ,ÝçœBâQ²ßÝÈ'»§:ÁñNËÔhmW‘`±ÖÙ°":ûcÝuÛ©íÂOëè Þü5^«å³kõ‡ã…1É,K™€—æwšÛ¥ÕjA™›jóÔKö: #²lGÛï[»n_ë¬*‹]Z̓҆x˦°;ê¦#,p¸.7Wq€æµew,ûæêŽ{3Œáó,]3ï†÷β¼™j åñ­iô6z5æ]‹TªžnU$]« z]šCS‘A ø"“øŠ•ØGXÎiJÂ~=­Õ”‰æÁŽ^D-EG3 xÜ–UE£¹]ö¥Í¬šö;q@í®XØ:B^¨ ÿI¹~´ %Á¥8|Þ%Êi +A€Î=ZÓö+X;LpÇJÍÝÉO0œ_ô1íÁocXîÌhp8èìÁ¦™¹¡÷û{Éõ8é Ù…^´£)Õ„ãMU÷Ãe=vµJ4qôddÐþÞ[£ñÖûg€>i›±ææô#Œ0Öß–¹ßž?â“Ç D¬1™Š§Ót$<cK£ïum­"ÓZÇC¿FΘKŒ6g ±ú¦c³‡~.QÐï(5öã÷áÿþ)åøÛQ”0•¦rüWü‘ Â÷+ +NoÒÉÝo.÷Eÿ/Í’ÕYendstream +endobj +1104 0 obj << +/Type /Page +/Contents 1105 0 R +/Resources 1103 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1071 0 R +>> endobj +1106 0 obj << +/D [1104 0 R /XYZ 56.6929 794.5015 null] +>> endobj +170 0 obj << +/D [1104 0 R /XYZ 56.6929 691.7741 null] +>> endobj +1107 0 obj << +/D [1104 0 R /XYZ 56.6929 668.7722 null] +>> endobj +174 0 obj << +/D [1104 0 R /XYZ 56.6929 579.8329 null] +>> endobj 1108 0 obj << +/D [1104 0 R /XYZ 56.6929 549.1878 null] +>> endobj +178 0 obj << +/D [1104 0 R /XYZ 56.6929 502.9124 null] +>> endobj +1109 0 obj << +/D [1104 0 R /XYZ 56.6929 474.9173 null] +>> endobj +182 0 obj << +/D [1104 0 R /XYZ 56.6929 277.7919 null] +>> endobj +1110 0 obj << +/D [1104 0 R /XYZ 56.6929 249.7968 null] +>> endobj +1103 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F39 900 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1113 0 obj << /Length 3203 /Filter /FlateDecode >> @@ -3646,53 +3667,53 @@ gUB Ê-;1ØxÈkÊCN.—²ƒÂ9W‰;hYq  c>ú ÒŸe.èÓ ÐÐf_zÝG}Åq¯¯¯0!3ÃJ÷9ßH´15ü„ý’Ýú8€‹HݼR¦X3¶!̱~Æ äë“å¿¶N¢£ƆˤSÇ-’®1^U'>Ç;õçäEa Q1^"/µ©‘¯o=9$þÓ†Iì™ ØKA!8ûI¤…ËÇDã‘gÁ…¥ - #yp²›ì Iªˆ‰ ThÃ)Æ¢ö§ñ¾”ø£ ‘€ìsÏ”5G?‘&‰1ˆÄ†æÈÝ$¨Ó0‡º¡è o?|üxý†×NŽ"}Ë¥$Œ€IÍ¡eX.¨&_ q¢”M7ïä€Ð+{˜û ÍÍä–af0€{=£Ê _l¹w8ÞîÊÍ—` ،̿¿aš˜IÆÅï×åÿ٧к±ÒíäÙ9”ÄîÁ5h ø~FîgÎ¥üm¾÷_òª"»„n¾BˆþËIûÊûåò¡Ü¹>âèƒÜÃtý'œÆGUÙ•>&û2~ÿAcò‰f¶(Jo¸ VÊ|œè£F˜êF*­&^¨ú‹ávÇK¤Ê ‹$—1R6Èç º;n™z õ£ƒ¤„HÔVB<]ºôÕÄþ4`™{"ò‘¯NøÔ×w­¯ÒÓú¾ëÜþp’óïj–.þ&Y|é߯Ýfž‚kˆ3¯pÂtùîÆFxôés±v )âjR^¿ùQötò‰kßNëýEÀ %ðßÉg×µ§uøRØÕõΟåáàmˆ‹%‡…^vƒúðRˆ˜¿ãI{ |&2I¦ÚÇlU{ö/8eûœ#8÷ƒcüȨ̀,Õƒú¿l2üº&J“¦g¾‰Aö¤a–x¢È$ÚSÊû_¥<'ýôJ„endstream endobj -1107 0 obj << +1112 0 obj << /Type /Page -/Contents 1108 0 R -/Resources 1106 0 R +/Contents 1113 0 R +/Resources 1111 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1115 0 R -/Annots [ 1111 0 R ] +/Parent 1120 0 R +/Annots [ 1116 0 R ] >> endobj -1111 0 obj << +1116 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [418.3461 611.3335 487.0181 623.3932] /Subtype /Link /A << /S /GoTo /D (dynamic_update_policies) >> >> endobj -1109 0 obj << -/D [1107 0 R /XYZ 85.0394 794.5015 null] +1114 0 obj << +/D [1112 0 R /XYZ 85.0394 794.5015 null] >> endobj 186 0 obj << -/D [1107 0 R /XYZ 85.0394 769.5949 null] +/D [1112 0 R /XYZ 85.0394 769.5949 null] >> endobj -1110 0 obj << -/D [1107 0 R /XYZ 85.0394 749.4437 null] +1115 0 obj << +/D [1112 0 R /XYZ 85.0394 749.4437 null] >> endobj 190 0 obj << -/D [1107 0 R /XYZ 85.0394 597.4103 null] +/D [1112 0 R /XYZ 85.0394 597.4103 null] >> endobj -1112 0 obj << -/D [1107 0 R /XYZ 85.0394 573.0707 null] +1117 0 obj << +/D [1112 0 R /XYZ 85.0394 573.0707 null] >> endobj 194 0 obj << -/D [1107 0 R /XYZ 85.0394 410.9267 null] +/D [1112 0 R /XYZ 85.0394 410.9267 null] >> endobj -1113 0 obj << -/D [1107 0 R /XYZ 85.0394 378.8211 null] +1118 0 obj << +/D [1112 0 R /XYZ 85.0394 378.8211 null] >> endobj 198 0 obj << -/D [1107 0 R /XYZ 85.0394 204.765 null] ->> endobj -1114 0 obj << -/D [1107 0 R /XYZ 85.0394 171.4256 null] ->> endobj -1106 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F14 737 0 R /F41 935 0 R >> -/ProcSet [ /PDF /Text ] +/D [1112 0 R /XYZ 85.0394 204.765 null] >> endobj 1119 0 obj << +/D [1112 0 R /XYZ 85.0394 171.4256 null] +>> endobj +1111 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F14 741 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1124 0 obj << /Length 3252 /Filter /FlateDecode >> @@ -3713,133 +3734,185 @@ R UˆÄuV¼¼Ô)e ç/> –|}Ä[¾¸»¿‡CÔMT4ÃðF‹Ó üIT¸ ;?ðËPñVUè‚èô7 øpiKìOD“"VØØŒ66ð8uRÈ(L0”lÙuÇ]‰¥¶â§s$ôuJAï¡þœ .ºj2˜dàJU>¨¡“Ï•ÝPK'ºÈO1ta  øŠ#~Õ Ä9ÖsåÖåqÛ³ºÊp0ºÈe©ó['‚|ËÅežÿ~(!ˆA§Ò`xË0zDúÜMç8kO&.βºóhB×íÄe¡þ”LGOéßã¬ÎV¸@8¨aÔ8~?{%ÚÕFªµ›ðËþ”sÁ4µÈOJÆÃN//çì„èð’q$Ϙ}¯\èžôv&ÉŒ® hΨY*“Ìæêì]ºmÖŸsewvèëÆ “ +â~Ú;Ä(>õw¥üÎÄŸoDÌvþç¿úœþÝ’QÖ¦§ñŒ“< ÂI˜)Üvš_pþtÉú‡B¬ðendstream endobj -1118 0 obj << +1123 0 obj << /Type /Page -/Contents 1119 0 R -/Resources 1117 0 R +/Contents 1124 0 R +/Resources 1122 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1115 0 R +/Parent 1120 0 R >> endobj -1120 0 obj << -/D [1118 0 R /XYZ 56.6929 794.5015 null] +1125 0 obj << +/D [1123 0 R /XYZ 56.6929 794.5015 null] >> endobj 202 0 obj << -/D [1118 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1121 0 obj << -/D [1118 0 R /XYZ 56.6929 748.4014 null] ->> endobj -206 0 obj << -/D [1118 0 R /XYZ 56.6929 549.4516 null] ->> endobj -1122 0 obj << -/D [1118 0 R /XYZ 56.6929 521.7105 null] ->> endobj -210 0 obj << -/D [1118 0 R /XYZ 56.6929 231.5025 null] ->> endobj -1123 0 obj << -/D [1118 0 R /XYZ 56.6929 201.1114 null] ->> endobj -1117 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F48 950 0 R >> -/ProcSet [ /PDF /Text ] +/D [1123 0 R /XYZ 56.6929 769.5949 null] >> endobj 1126 0 obj << -/Length 2922 -/Filter /FlateDecode ->> -stream -xÚµYI“«8¾×¯¨x—qMua$±FǼ=ï;^»ç€6‹ x˜ÿ>Z€²ë1óº£c„”Je~¹ -ƒWÿÀ«"rŒr¾nÄ3ˆÉÂÀt»à@ÀKœ"ˆÙyÓ‚£€Hâ##a1kò4c|4ÈÖ†$Re‰Šú å'ì8l(|d€Ýêô¸€qŒnlx]*%¿l#(s©¬à5?f‹…ü@"‡x™Å3 E„ã’çùR- ˆKاˆ@AÙL­èlEEøb>ë 1Æ„ö¦Â",¢¾ñ¬üð› 'è>s­/œâ JJ•¤L E&`I?¤>wˆ\=±¨Ÿc:FÓ”o<ž¬8‰ÙÌ–íósB’‚èŠ~ù4~5<ÃÿR  -›PÈü0ÿ'Íuú@ŠÊ!I@Ï&÷OqjÀMnî/½Y1µ#Èœªâ¼ô8RÀÿ\âTA¸ÀÉŠ'LϺçšXòÆã¼_,¤xé@²b§‹ØBœº ßà…™ 1úƒÈIXg™Ï‚‹¤·"–œ$æ~•rLåÇI°Ð2âp -Pþ°=Xb%3¡_5 éÌ’3²Ì’º NN…yÂøñP#DêŒéÁ8ØÃÂ%s²(HFæ0‡mÑÁ*'㺕’rj|àŠÆ)=;ÛÏõx”Y4! ÊX•ƒKjP±ÃlÙKÚl<™Äl°%ù™P‘Ì•ÎÑŒIGO.6\î‚ôÜ'Ygçî c•ªíé´qg­üBžj>ƒJ*[0CÚ≠LØNÎîöÆ&I¯ª'iŠI ÀÑy¡n¦liwŠ—XÛFSÛâ9³d Ÿ'ŒÜ§ÛsJ•†1Y5C6EÄÈ*ÙCdÖWÈ“ïÁ2\È_AÎ=ä3S²LO'³¾¶ jV¶ÌPz¨ûRɶXo a$\ˆÜر(ÐÆâ„ñJ·ƒkè{Üþ£x2u|<òÂpÏF¤v`›Óð$ ÌœxÄ‚$“y^xÁ\TmœRÉÑc6Ðكن "ö|ðBœã',<ÖÊ`¯Y~’RªÙùxÀ"'¤9MPð­ÀÍN"re㬠<>»)"À)‰éà‰+“ÆÖ÷ž!DrpÈV7Ö³®,¯äI‹‚Êt—ò„‚GéÕIT1Ôí$R¯±ë)Aª(1E1%¾$éMãRæLx`”põŒºa}Y*P@¢Þ—0í½8•2»FIŸ)©Àޤabæ!{hÇ%Ö>>=ͧ†¯Pìϸnü¼©CrÞú+–®ïŸèõK`ÑFæŒÐO;iß­Œ0H‰œT˜Ìß³Øå‚$!"H2Sbziq“[¾L“€ƒ_o=×Ãìâs}¹pà7A’~Lܾ¾ü‹ž"Èœy|KÅ}Œ -x—é’Hn„$§r²€ØÂßéB&ÏÃÂ$$9“°íZ¬ü‰ôò ¶§|æË™Â"'B=;ö7îã E™ ÐÓã[u°.Ñ¢‚Ú¶ó^[š|4_ÞV~¸Iä¸ÑØv‘áM6M]»L;ר¹¿váú$µåѽsbG㻺ÌÓúñuCµ¯Â¬îÍJË[v͆p_µG¯vƒ³Qƒ3Õ_;{sv0Á<Ë­Š¹XJÏï{Á}…Šüø~ƒË›°÷ÃJ]ݧgÕÒý2ʨÕÜU{úT¶×ßË»Ív=ëžÝHkEPlöä©6žÝ«q_ Û,ųƒ›6kÅ AKm%:ݵT;~¿ú•ùzy×ÖÜ«”Aψìe¹Ûo4Ír¡Šîéü]8vj7óäZ­Óþ´B-aÙ¯“÷««C¦bОÎ~9¼-&JuQvæ}xŠTœÖ4ÇkmÑÕ]yV}“”C0ÔÆ¼Záÿ‘ùû§Ñþo‘Æ”î̹Y†ÍÍ @*íËø¢eñYMÈ‘OÓk>*õúdTá íg~>Sá”Ûöpv¨Ž:hÚ÷‹qšýÊË ”ñqŒÇã -W¸ÄÂ/içóèÝí9M-4¨.ƽYûÞ:ó5ºÛö -.MÚ¯CÉà‹ žÄ÷Õq“œ Ç·Ç5¥v~y$Wê7Ë–žbÚœ¡ØÕ‡æ”/2ómØ–ªö(¾¼¯ÖæÝ[õõv§¹ú‚y »mçn®oc¸Y£Ým\$„Ыò^MÖ‡AÜ¿­º­ÖÊšœÙÉ£ë®=^úæÑvšÇ÷3n›¼TX°ïàj¯:ŽÕÚÛÀMâéöµ7jÂóR«—'Aoù^GšõŠ”[U«ãTÖu±'ªóón:Š×–U¯Ín‹Ut­­x]oOÎN½^t¾§ÝóƱ,­3󥆳¿ß’ÁNª4žì•]Ùm+î&wûBkþû׌3 öûÞ_Ü -=îæ8î¿ýÝ‚°«#TôçŸÓ_þ+æóß',Røù/ËSûJ>»ãKB& ù«äù6?Šþ¢Ó, endstream -endobj -1125 0 obj << -/Type /Page -/Contents 1126 0 R -/Resources 1124 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1115 0 R +/D [1123 0 R /XYZ 56.6929 748.4014 null] +>> endobj +206 0 obj << +/D [1123 0 R /XYZ 56.6929 549.4516 null] >> endobj 1127 0 obj << -/D [1125 0 R /XYZ 85.0394 794.5015 null] +/D [1123 0 R /XYZ 56.6929 521.7105 null] >> endobj -214 0 obj << -/D [1125 0 R /XYZ 85.0394 717.5894 null] +210 0 obj << +/D [1123 0 R /XYZ 56.6929 231.5025 null] >> endobj 1128 0 obj << -/D [1125 0 R /XYZ 85.0394 690.1986 null] +/D [1123 0 R /XYZ 56.6929 201.1114 null] >> endobj -1124 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +1122 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F48 955 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1131 0 obj << -/Length 2380 +/Length 3056 /Filter /FlateDecode >> stream -xÚ¥YKsã6¾ûWð°ªÊBð"H:'gÆ“8•õxmMöÉ¡1w(RCRÖz«ö¿o7¤(šv¶jì*£4~|hÐ"àð+‚È0“Ê4ˆSÍ".¢`½=ãÁ˜ûùLxžeÏ´sý´:û჊ƒ”¥Fš`µÉJO¬ò?BÍR¶ <¼¾ýÝ,–2âáý§ÛÛw ‡+¸¾¡ö§ë›÷D¥‹¥†«ðÝ/—·««;Õ^ÔåûßBˆðòæÝ•_ðþ枈W—‹X‡«OwW÷‹?W¿ž]­†“ŒO+¸Âc|;ûãOäpè_Ï8Sièp&ÒTÛ3)i¥ú‘òìþìƒÀѬ[:k=Á™TFΘO‹‘ù‡Y¡LG)3J*g¿¼j[»^Ú*{(íbi8Ÿmû#ž ă‘XErÌú”•EžuE]MØ—:f‰äñéªÿþøš•àÓ èøÿ˜IH–¦‘ž7(ƒPÍåë²hYžìWœŠ:£K´Jk‚ņƒm#™Š… Lœ2A âaoð¬Ž3e‘£9»³HIÐÜq|£ ŒK#ë©e@&e1!Ò·¾‚q¦Š˜F´;ëÑnà‡ë­ Þ×p¢`t¨^ðr,Ù -âæ"XÀûƒ'…ˆS:S]A`È8 ë ¶IØ=ú¯ ÉC‹ž[š*‹¶³9ÍUÏ^´4bЇÿζ»ÒÒTÖxIO …XJGáuE㻬Y,5»b½/†<Ÿ(ÑÔuGC#u¼^« -8fz´éÄÚ€S“4 ÆAð}q…¥ë˜Ëßõ§¡ª5ð ¡*¡™ÒFŽ3ŠcÎX÷À È9çSœûÝ®n:ê8÷M@óÝ}È€Ie N<3a±Ùì˽ÁMØ’ô–&²²$b½oš…HB[uć¹ý̹¬\ ¡ŒºÙ¶$Ã… yª²­%ª«½ä<'­_”UùìÌqÉQHY×_÷»–ÍÅ˵·Ì¡pº••mMÔ¾µþ®¬9ÚͶ4ÔyîmöÕ³ÛÛ¦è§Ö½Y$ᾪŠê õk?žUÓ]ÖÙŽ ;í3¤ßö¨|ÌR%§ü‡2IJ…Ö° OæMsb²‚„ì¬}v®1;±(Bí•[·ÛÐâcC‡¬;#zÞsrä9 ðõÚî|žù#`Þ4°ÝÆm=Ú™§|'§ƒþ¥éÓiž' .gŸ[¦_††¶45J£'»r§GƒÓ0 ÚçLYI3Ÿ¥ÔUñi‹1!ÈeÍCä4ê@EÚoÉ=n‰jq¬QÖ`_gçÓµ¯TAç~­µÓŠ[Eƒ‰L<Ê=ži²ùâŸ7w£WïÀ¿/èßicà›ÊE ÜÃuVô5Õ%“L¼xðÖ~Å¿x{\¡ÅKi¨óØ'ÆïJw²8uG„G‡ÏÂ×ë—`Qª`AùßèF¢Î§öxóQiÔÞ{pÏ×î X z¬¨‹zç2DH5^4¹Di̽°ðE >צ®Ëlp/¶#ÙxáIÎJuÅ…‹2Oí«²øjO„èéUCªš7äµ;».0l;—GC¤CÑXŒÃy6ŒOŸG¾AË÷Uø© -ˆ¬‚“ÎÒøœrò‰’²$¡4ýÛÇ»ëŸñÓ~eñ«€=›;ÂcÝB†ÆXðÃVšÓ‡/ìöá€cÀ".ò‡äâB¼¨‚üÂÊG)í[)òß²¨–dœÙÂMN@zòäÁ¡¢¥…„t0Ð[g»µpMäî“› -¯7^5t\ç.<7SQK„S£Ýš£ˆ^GfˆŠ×/†qˆ€[èò::-vÞ¿÷ºÇo aàÍ>Ô)ø¹) ‰I˜ö 2±/.âF'~QÖN°vt¦yxJ2ŲÇ3àƒœÃ‡þÅyCO‡7ãÆ¤þ#'!þ_BÆ?݃UqzD:QØÙï¨ÍüäIòà@á'*¿'ÒC}¤àùáì1»«¸«Î÷³>_±Ó$ÏDŠ÷ÜI5á¿ö.ª¸vv÷ŠÌ=ô!ļ"xß½t½†rZ¸¯p㺛Í,‚HHDÏØë ƒ±Oº ‹pt8³?ð¾ì¼Eµ«# StìÙ 9µØ¦.Ëú0øâPïK¿fý„¯b*r¹f1“"÷ôÕƒ©1Ľæ_a”²C¾¼@Í™JxèØ[çm`2‹#Õ'›‡o2耵_EQÎNöÀrh…ëIvâÉ)Ä -Æßú…ìK` ¡5¯£ïíê=ÀÉHlŠåsÇ!¹õ|ÑÁ8øî/¿ ê˜)¬’f«xÝaõ¢z¥œ³’š÷ÿ‡x©úÿC|upendstream +xÚµYI“«8¾×¯¨è˸¦º0’X£cÞž÷¯Ý}À€›Å¼NÌ-@Ùõ˜yýbbÂD*•ÊåËT +ƒWÿÀ«"r† =ëžkâ°7œéA|!0¢SîÇS!6 b1Û¯äMýÌÿ'€ +8¨Bðý.áä…bÆMŠc‘HNP}–˜êKhTrŠ,dÅ%<|°´ð ‚ñ­|©X)nO,܃nÒ2‡i$ð„BRÂÍJW‘¸³jŠ_ò(§kšªdÆ ±ÚÔÛÅHôP G$"˜À>FÈ&0Gº¹g陊¬L…¢7r ¤z`8¸¶e˜¢†‚ÿf#/(4©LFe%žŒô¢hÜm¨bŽ$ÂR-󃂑N…yélŸoeEÑ +ê¹(q²$¡GPsXÏm‘p•“å\®@Ù¨âÆB’¤çìú±Ò2òŠT{ìà’¸gÈ–ÑØÇÆ“IÌ[rœ.RèS=`èèI&=Á)/VºØÏ–¤L$NQœ0>Ï öŒL@õÄgD·CÚ‘~p\ƒÁ>3ç õ†£“µPÔòÌpD„JÚa:õy.qgÁ{>AEù‹ØÀIêC Àš#,üûƒŸ’©/ÙM^?ÏübZ–ŸéF‹~ZW—B^M3‰Zà“ˆúòø ƒÂ—S>¯×¹±xœº€&uËC±ð= Ym5¿œPÈ%?I(,Rδuxê5²‚\„pþg‘ÓQúŠlv<ÅFän2¥)8ðÓŸ™ÝMí§µê™9ÉO?34N$ѹ‚tß']gçî‰`¥E⋈BŽYÍ)¸L² 3¤=4&aÂHø4r·7F$­½ž¤•,e Æç…º™Š¥Í<žb].™Lc‹i4gÉ@?%¸†º¸Z¹ç”+Mc2k†ŒDÔx*³ @õyïp° —$òW'çù,Èìh£ÄìPÐ&T¶,Pzh“¤’m±V +÷¸än0’‹:zÏ€¸`¼ÒíàºÇÞ—¯&¦ÀÇ#/ ÷l‡¾…cNÓ“L°pâ3’Jæyá…t:E®jÓä”J޳Î,6d±ç +q;œ°òØ*ƒ½fõIJ¨fûãËœÖ4A)¥íÙ‰è•óîG}ê~ˆ§$¦W¦'©L[Ü{æ!RƒC6»±ŠNß¼(n©Ìv)/(x”Þ4EûƒÂN"}"Ƹž2¤†â3sâË[’Òh—r0©ô쌺a=Ò ã÷ÚKz 3Ý‹S³+§ôY +‚HÚC²†vG¹ŧ'zz¹úzYÇ`?na}ös$„D¤ëû'Ú ,ÕÍýôÖá»±•1)““*“=[ñ7&âF¦pÊL/xnr˧iErøúýåðx¼Kg·¼˜+èrÈí ¿ ¸3ù®lHø®÷Oº ãö˜ÇWzˆ°Ÿx2—é”H®Ï¤¢r²€ØÄßéDº‡‰IH*&ÛµØá'Ò›*XžÊ} —3‹ENÄýÔ3¬á~a’¡(³zzüR¬„K´èƒ ¶í¼×–&Í—·•n9n4¶]dx“MS×.ÓÎ5jî¯E¸>ImytïœØÖ²ÌÉ<==\ÝPí«0«{³Òò–]³!ÜWíÃÄÑ«ÝàlÔàLõ×ÎÞœL0Ãr«bî–Òóû^p_¡" ßopyöÞbX©k£ûô¬Zº¿Sæ@µš»jOŸ'«ó¾ìâºrØ­lgû.m^ä÷ö¦~/ÊùþkA¥6Q€\ÿ&T«º<›”7V½u;ˆîB[.¦®´ôÃNoÓT§ÆÑ=™ïÖÞy9Aý"ËÞl6Ÿlö– Ú£ÎÔ5ý.ZßjžçËiw³³Ê‚8힌–\fâÎÚö“£$ÙÝÐïÞ %º*ÛÙÜ’Oªº¸k=ì£w­;×Õx ùocUž¾÷º3í06ŽPžÈ •ç¢3_§F»ÈêÁñbÜ…Ý긮ÃíØ´¯£®Õ¼_›TM×µn½þà¾l¢_~Ë¿[±ðþ4Èá#L ´)ähq$ƒð” ¢Ïj÷·8çºè‘É^²o‚¯©ä‹æO%”Ç$?{ÁºêþÛéÛ +3DL3¤riT*úuÔ7&ðÊ·6ã¹°°ÖU)lÔ—ï?îKbwãh»hÖzeâœÆzÍÔp"/}¹Ñ¢•êníÆé(Ÿ×å{s=3ÍÁâöÞYßO1ïÍÉÅÞ5/Îl +DQim„Nw¶Ùc¨}åpYz;¾á.QXÿ6÷w­¡ vo_2fÝÙ¶ì×äÖy{YµÊU ÂfP+B†¹A·sC[¸]îCua{ý½¼ÛlÙ³îÙ´VÅfOžjãÙ½ºgñµ°ÉR<;¸i³V Ô¹ÔV¢Ó]Kµã·«_™¯GwmͽºAôŒÈ^–»ýFÓ,šèžÎß„c§v3O®Õ:íO+Ô–ýŠ1y¿º:d&íÙèì—ÃÛb¢TegaÞ‡ç ÈÄiMs¼Ö]Ý•gÕ7I9CmÌ«þÞ?ƒö|DÚrvgàfí7'üTÙ—ñ5 Êâ³™#ßñ!×|Têõɨ Úp>Sá”Ûöpv¨Ž:hÚ÷‹qšýÊË ”ñqŒÇã +S—|K¢_ü6ŸGïnÏijÁ y@­p1îÍÚ÷nÔ™¯ÑݶohqhÒ~J_ð$¾¯Ž›äl8¾=®)µ{7ÜõË ¹R¿Y¶ôÔ§ÍŠ]}hNù¢0߆m©jâËûjmÞ½U_owš[¡/˜·°Ûvîæú6†›Õ8ÚÝÆEJ½*ïÕd}ÄýÛªÛj­¬É™í<ºîÚã¥oía§y|?ã°ÉK…Öâ\íUÇQ£Z{ø In_{£&> endobj -1134 0 obj << +1132 0 obj << +/D [1130 0 R /XYZ 85.0394 794.5015 null] +>> endobj +214 0 obj << +/D [1130 0 R /XYZ 85.0394 717.5894 null] +>> endobj +1133 0 obj << +/D [1130 0 R /XYZ 85.0394 690.1986 null] +>> endobj +1129 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1136 0 obj << +/Length 2753 +/Filter /FlateDecode +>> +stream +xÚµ]sÛ¸ñÝ¿BÔŒÅàƒÉÉ“/¶{¾i×ö¥—{ EÈbC‘ +IY§Ìô¿w LgÚÉ]2c,‹Å~cñƒÿ|«Pe"›%YÆŒÇ³åæŒÍžaîogÜÒ,ѧúéñìݵLfY˜)¡f+W²4å³Çâ· +³pXps÷IÍ"fÁïwwïç2  qsKãO7·—eóçŠÉàÃÏwW÷„,«‹ËOsÎypqûáÊ.¸¼} àúêbžDÁã¯÷Wóß9»z4ñµåL¢_Ï~ûÍ +Pú—3Ê,g{ø`!Ï21ÛœE± ãHJ‡©ÎÎþ90ôfÍÒIëq +©Ä„ù"î™3˜åRÍ’8 •ÒØ/ CÔXAÂ,Ž…Au×éåB×ùS¥ç ÅXpÐÝûï¾äUYä}ÙÔ'ä‹( SÁ·ŠüöŸ÷oO%iÈWÿ“õ¸³,ަ­‚&À4bâm^´Ž/ ºǬÆUŒ‡±àÑ`d0ä`ŽÕL‰P& ¼R™’“‘oQWC™…±¯w„± ¹¡øFã®JW§–ž, Œ,L²ÄÄÕì댇,Ê2IDltm`ïn6bvÙ€F3O)Çxás6JA8‘ùT°¿@Ö6:55†H² Yá˜ýÚ"¾Ì 4þ9t4U•]¯ š-kG^v„ÑsÉ‚?òͶÒ4•·–ÓË\Ä$¦Œâà¦&ü6o狈}¹ÜUC^žŸÑ6MO(O+•ªŠ£€¦Ðô6=qD¤²P¤Y:óƒàÇâ +#8ÎÖ˜â?õÇ¡Ê@^¨¾.§qAA îÿZk4±H±à=\} ØÏmü6„‘ÊCAympN;çiÐlu[͹±9 —Mý™1ñ¼3“º@wIaÝ« Ý5Õ‹n ³/«ÊŸû·^ön§ƒº½n;ÚaEÛn¦\Ú•Ï5í ‘ÕÊJAßß ’;÷ër¹&p•—A}C£µ‚¶lH_\D‚D\û][Ûƒ–8>]ã‰qqó÷c~¤;˪Ôu?ÔaÈEÉ ~¯»mSwF¾4 +6ù+]7À8éì|Ó@¶Àd)Ðw,œW„$ó¶@­2 Ù¹¬vEY?Û Ë®ƒ3)ýǶôüän›²6ûÛ-ÀÚùbê¬è­áÍn‘ +râà‹>àì`Ñ¥£È¤©AmòÞÍ’í¸| ñþ¾Ó–ÌŸ«îZ÷Än0òI^»µGÑ+°ña†@£•4 Ï©È3¹ˆY.³ÖÚ׋…²·8Êê¢uÝì*iëüņ̓Öõi4‡o¨Qšaʉʓäÿ)}Ã’· +•„MUuõûgj54ÊTúgž©2!Röœ©>ç·ÏTìð Á~õ•.ve4FyobæZ½Ô¥Á› ‘ƒfbSX¹jMˆJÜ0îjªƒ4ÿmÎã€q³aÞ´Î}®‘­SÙ ±Jq,%,—$霳`×™/åÊ>JŽS†b_ökš5Z"Š89dnY Ó£¨H°Ç/§Êº‡•p2åUu ùJ¯,ƒ]=Y…H#l)¤ +nPíx¨7±r àž\Ó0ÍËÕÁE¸,¼”9Q Æcw8ľÿÜÜ-œ«ïð¤oðgÓju>UB¬kÆæ&ì…°çGøƒ÷9T1×áÐhª$Œn+ó±Â¶Ë•Ïz¹.«b¼$ÐÅ +ʸ¹54XŸ>c tx?Peï¢{ªî$ü}\W‡-|óÜ9ºm£ÿd´<:~°ðYþ«Nîñ³‘;xMzõæÐį¼`…¦GH}$[f<»vß·Ú¨Íû!qS&¡êÃX]”KÈU,/,¥ªhw +#Œ&Ç9Ú÷†RA3û™ÅìU€~¨i‰ý„‹èé!8‹!&¤‹JD9ák"D…>pŸW +M§±EB‹ó¸v—œVÓ[焾9ñøP6uìÕè°¢4åo^ŽüÓü;„¿òv„bŠ˜ç³à3…2R¿ ‡Y)÷Úîe _›^ÜkÓn»mÚÞöqõë—¦±OqEüWiƒbÈÕclаڙÃL0tĽ£‰ÜÜ4w»>‘(“ ÐxÒÒ „<švÓ“C€²2Tç¦Öd‚9…ítí"J®×3ã’‘IÕ4_vÛnò%é¦?½%åUg»Þ]gÛÙÑšÞnîRæzäMþÅ’Ýé¶ïl®nç)ùõÐ\7µ»©î²Ì·ô°e:èC×ëÍÑõËH~mJ•hÊ=µå!¬¾çt µî|Fƒõ\~;B4µq@ð ÒÒ]:Ì[ƃûë4 ­‰$¨Ð[àdÉmh{s–Öˆ¸ËÊî¡&w8ŸòyYeöºèÊB¢Â>è: €á ã oBîs ]tŒêÃ’Mó¢í–Þ=*2ðø +U'îïªxw6U .³»~Ý´eŸ÷勞Rǹ"%W¤.FVëöžÀG?<.TMn0¾QO&R¥-­í¨(ªà›Ì›& ç$dè:@u;…©‰ÏÈæ­CÚ× +ZìëÆÊNm(}Íc—r—RÀ›³xB-ÿýRFtÁQSE3}iDŸ¡ +c˜)ì-,)4ØîQž]b&8~GõÛ l_ PFUl„¨bL݃™G“!@…Û°¥ŠBT¿§ªæi¹Ì °1ï÷*×J@¨´/¥ÞÛ¯ÕÉ‹îàÿB”eôúìÖ¾Ñ oÖú´ß–1 £43hP%ô®ÐÆÒTûlߨî½_ êÅHþú7Sž¨ûd¥k¥.Bè[_uþ,UP¹FÖ¯~¥h¾»ÿ)'ó å[ÏšP¡#)'·cÃóáÿ;^¢$”i*§%‡zŽ’ËA*]¤¯dw?ÖNÿ_ëÞÍ&endstream +endobj +1135 0 obj << +/Type /Page +/Contents 1136 0 R +/Resources 1134 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1120 0 R +/Annots [ 1142 0 R ] +>> endobj +1142 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [349.4919 384.4828 408.4801 395.2672] +/Rect [349.4919 62.7905 408.4801 73.5749] /Subtype /Link /A << /S /GoTo /D (ipv6addresses) >> >> endobj -1132 0 obj << -/D [1130 0 R /XYZ 56.6929 794.5015 null] +1137 0 obj << +/D [1135 0 R /XYZ 56.6929 794.5015 null] >> endobj 218 0 obj << -/D [1130 0 R /XYZ 56.6929 594.1106 null] +/D [1135 0 R /XYZ 56.6929 285.3652 null] >> endobj -1133 0 obj << -/D [1130 0 R /XYZ 56.6929 562.6395 null] +1141 0 obj << +/D [1135 0 R /XYZ 56.6929 250.4165 null] >> endobj -222 0 obj << -/D [1130 0 R /XYZ 56.6929 370.2937 null] ->> endobj -1135 0 obj << -/D [1130 0 R /XYZ 56.6929 341.714 null] ->> endobj -226 0 obj << -/D [1130 0 R /XYZ 56.6929 214.6004 null] ->> endobj -1136 0 obj << -/D [1130 0 R /XYZ 56.6929 186.0207 null] ->> endobj -1129 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F62 1060 0 R /F21 710 0 R /F39 895 0 R >> -/XObject << /Im2 1049 0 R >> +1134 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F62 1065 0 R /F65 1140 0 R /F21 714 0 R /F39 900 0 R >> +/XObject << /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1140 0 obj << +1146 0 obj << +/Length 1018 +/Filter /FlateDecode +>> +stream +xÚ¥VK“ÓH ¾ûWø°» +÷öÓÜØP[!›ñ°àà;Äà×ÆÉ üûU·ÚÆ™1Ãû ~I-}ú¤jæRø™+BE"Ý(‘DQ¦Ü»Ú¡îgØ{ã0{&ÓS/SçÏ×"r’„ÄÑÒg‚ÉÑg±§i™ãZÙ£ÌPtp>;fUUT¸pj­œØ–z$½Y«/`QP/k†Ñ¹©Ê¯Å…éåEgÕ²Sa=Y†ÏØë»â®üH)/ :òqˆ VEs*Ñ€%"£ @7ðec7Phä+«uéPV0 4LñŽoYÝUÅ Lˆd’8ŽãÖïvë7šÏ!ÕÈ][“¹mòƒˆÃQçá.I±ôtàƒ^ƒ#l‘߯‹û )&>Üô”Òk÷Zbƒ² ½Sg]§³ Ç˜j³Tö¨Ø´'\à©ë¢É‹Ü”´ðÖ{k†£õ™5”5(‘Bzkr$Z(åwñ°fð VO9y1þM2ª³[åé0“.èJPï\‚ymu±ØÃ·` ',Œ‰1ƒ¯V¢¡Œ¬Rfé4Rp±êíøÌ‰T´¡c4Ÿk¦An²ºx¾elÊÛÛÂÀÖ:;ýºgü{(4ÐМ+°jLéɹC™ÙÍ‹êÑ ¥Ýhìz¼7wêD²ñ˜Uâtm•jçÙP°zÒ—P$ßqŒë÷ű/rc5ô¾œ «¨4¸[Gf¢)fV4“z©ˆb‰°I,»dÇ.#3€)`B̆ƒƒÏP1šûè‹N‘^c¶Ÿ«“ETz ¤*EF¶“ècc'¹DlßVUû0æâ¡=Wö"ìší}™&j ‹$À1DÏ&åa€³¥1r§2ÜÁñ~èh¶`°dÇzyÒ6g +žœµð|c +‰”ŠÌ˜ x(`hÿ¼RrùÇä–ä ™™qr‘ÊÇ´`„>÷CùÅp“R÷ßpÚ~·éN§€"Jäq3Ÿ{@uë'ÅÌ[‚Žýà·_.?u2""ŽùGÉ{ACó$œ2Ùzò®Ÿ8O]ÿ¬ÊƒXendstream +endobj +1145 0 obj << +/Type /Page +/Contents 1146 0 R +/Resources 1144 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1120 0 R +>> endobj +1147 0 obj << +/D [1145 0 R /XYZ 85.0394 794.5015 null] +>> endobj +222 0 obj << +/D [1145 0 R /XYZ 85.0394 769.5949 null] +>> endobj +1148 0 obj << +/D [1145 0 R /XYZ 85.0394 749.4437 null] +>> endobj +226 0 obj << +/D [1145 0 R /XYZ 85.0394 622.33 null] +>> endobj +1149 0 obj << +/D [1145 0 R /XYZ 85.0394 593.7503 null] +>> endobj +1144 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1152 0 obj << +/Length 69 +/Filter /FlateDecode +>> +stream +xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream +endobj +1151 0 obj << +/Type /Page +/Contents 1152 0 R +/Resources 1150 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1120 0 R +>> endobj +1153 0 obj << +/D [1151 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1150 0 obj << +/ProcSet [ /PDF ] +>> endobj +1156 0 obj << /Length 1913 /Filter /FlateDecode >> @@ -3851,61 +3924,61 @@ M&P q¿–D"mX• ‘¹ÈjmËúÿ@CH®2#¶¦È²&RØš8"u£´÷Dí¦ñŽÌ~§¹G@ 8Ȱ€¿¦¯Ðžt–æøúê¾QCJºoæ°Ù²(î Ç<Ž,üˆ5kõ46i]WMPº/Ÿÿ¨Î ‚oœ»p7ª2ö·¸ÅÓº*#¼Åð`' C½žu¼?\: jº·3äŠÅ.…îÙ|˜ëãц›À¥Yé›Îe<¨õÞd[°4ÏËòÇ-Jµ¨{È‘!ètE1‘RDPż´î¡bnó‚%ŸT+)wð0Ò£Tç‚KÏXx¸¿_OIŸN@a&`ËêY‡ :åô³¡&Ä«»Û†ý5é˜âB€û}Ye¡ødÉ °]B楖x¬†Í@”üizT(þ¶Úxe訳vTn3o-òÁa^¨ª1ü8Háã=ô6³¶µ{Ó‘¡š»hW”P·Šj‰v¢æwЮ„Z[Š´»ƒhM 5ƒ© º¡s?‡+ì ïp,'èñ+)jä‘jåQúk ©ï¯‘ÙYºÝÕ¡Eâ¦Á§âÛð´â·I-§Ñ;ÀÍÍ$b®»Ö¬Ý‰ÜQµ㩺›{JýÐà4;,ÿ‰f`¨º ‡W$‚7€Úù«1[Ë/¥nÆÏX «Eš Q S£»»·ž;šWïP{“øÄDN)ój=u”ö¬ÊùßC;»òÕ]Û Ñ_;Œ`ÝÄF -q…7ÉGb†N0bèKNôJ… $ȳÈBÏ"g¥O Øêåýµ G’^—=Ys{}ñJE½Ó6l`‘“TÈ‹«Ã}%­JüŠÆ‹ŸêIÙmS:_Óß Р*çóýÃì(š´ªŠúºWy÷ËÓü-1~!EŠß×¾6F‘íE†>5.NF¸áb¼¹]mþpùv¹ÿÐÆ}endstream +q…7ÉGb†N0bèKNôJ… $ȳÈBÏ"g¥O Øêåýµ G’^—=Ys{}ñJE½Ó6l`‘“TÈ‹«Ã}%­JüŠÆ‹ŸêIÙmS:_Óß Р*çóýÃì(š´ªŠúºWy÷ËÓü-1~!EŠß×¾6F‘íE†>5.NF¸áb‚Ý®6¸|»ÜÿÏ“vendstream endobj -1139 0 obj << +1155 0 obj << /Type /Page -/Contents 1140 0 R -/Resources 1138 0 R +/Contents 1156 0 R +/Resources 1154 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1115 0 R +/Parent 1161 0 R >> endobj -1141 0 obj << -/D [1139 0 R /XYZ 85.0394 794.5015 null] +1157 0 obj << +/D [1155 0 R /XYZ 85.0394 794.5015 null] >> endobj 230 0 obj << -/D [1139 0 R /XYZ 85.0394 769.5949 null] +/D [1155 0 R /XYZ 85.0394 769.5949 null] >> endobj -1142 0 obj << -/D [1139 0 R /XYZ 85.0394 576.7004 null] +1158 0 obj << +/D [1155 0 R /XYZ 85.0394 576.7004 null] >> endobj 234 0 obj << -/D [1139 0 R /XYZ 85.0394 576.7004 null] +/D [1155 0 R /XYZ 85.0394 576.7004 null] >> endobj -1143 0 obj << -/D [1139 0 R /XYZ 85.0394 544.8207 null] +1159 0 obj << +/D [1155 0 R /XYZ 85.0394 544.8207 null] >> endobj 238 0 obj << -/D [1139 0 R /XYZ 85.0394 403.9445 null] +/D [1155 0 R /XYZ 85.0394 403.9445 null] >> endobj -1144 0 obj << -/D [1139 0 R /XYZ 85.0394 368.2811 null] +1160 0 obj << +/D [1155 0 R /XYZ 85.0394 368.2811 null] >> endobj -1138 0 obj << -/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +1154 0 obj << +/Font << /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1147 0 obj << +1164 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj -1146 0 obj << +1163 0 obj << /Type /Page -/Contents 1147 0 R -/Resources 1145 0 R +/Contents 1164 0 R +/Resources 1162 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1115 0 R +/Parent 1161 0 R >> endobj -1148 0 obj << -/D [1146 0 R /XYZ 56.6929 794.5015 null] +1165 0 obj << +/D [1163 0 R /XYZ 56.6929 794.5015 null] >> endobj -1145 0 obj << +1162 0 obj << /ProcSet [ /PDF ] >> endobj -1151 0 obj << +1168 0 obj << /Length 3113 /Filter /FlateDecode >> @@ -3924,49 +3997,49 @@ h4: 'öuð8Z¿›· CHU™îá|éAæshQ‰P¼××ãÞÍcoY~®°ç¦åú¡~ÚÕý }À£/­ê-uÊüo<»ÓŽþ­w]D÷På¢à¢î;N-xœZ¼L¤v³¡»ÙÖ%¾4©h<,z¾¥™äut¼× Ÿ6ô’fŽ&û@d !{A¹I1ùO!&Ó¦¤Ø.ªU½®{z¥ƒòæ|ú¡§ou„Œ7Ù<­^h„d;o×àçÄ^x‘!²`H¤òf®“8ÄQL;„KÅ0 ›ÕÐh³[WÛzNÃõØ­ñÂ2Ð@¥}x ‚€tŽ4ËîExoåâ[%hCŠ-ñõ¶ÿ—O,ÓP¶(E×Ç/ƒÒ›"Ÿ*zMä¦kŸ³yûè ”BaÖøH j+>~ …ëŽÚ¦¥¶ëËfAŸ4²!rNC€ &fFar¼°^äˆ C&d)ät¾ÛEñ÷°ëØ ôA¹},õãÅ:‚]Õͧ ëd·bؽøâixGäA4» ¯T ¤†£GévkªµTfÖ·³ 9=?>TýsU5Y–ÙaI’Lè µaó@yÞ‡òˇ ŽÏ–ÞDÆö³U;/WÅ(-8õyrxk\òy•ãàï²ge ò€`T/U2uUØ$V*û¾œ/C"Žíà~‡2žØZ¨U:¬i*ž žÎ×ãã£2RòñwHÂþE ²>Ÿ2˜ÄáÎG9ü)¿²ÁrÔ™½ã7àã~€ª;'è¼UðB4²nÃÑ2–'ÁN;ú3Þ*ü?ÚªŠª•YZêð€rõ\¾ÄE^í…ºbYS¦iM5> endobj -1157 0 obj << +1174 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [356.2946 363.7923 412.5133 376.6291] /Subtype /Link /A << /S /GoTo /D (address_match_lists) >> >> endobj -1152 0 obj << -/D [1150 0 R /XYZ 85.0394 794.5015 null] +1169 0 obj << +/D [1167 0 R /XYZ 85.0394 794.5015 null] >> endobj 242 0 obj << -/D [1150 0 R /XYZ 85.0394 769.5949 null] +/D [1167 0 R /XYZ 85.0394 769.5949 null] >> endobj -1153 0 obj << -/D [1150 0 R /XYZ 85.0394 576.7004 null] +1170 0 obj << +/D [1167 0 R /XYZ 85.0394 576.7004 null] >> endobj 246 0 obj << -/D [1150 0 R /XYZ 85.0394 479.565 null] +/D [1167 0 R /XYZ 85.0394 479.565 null] >> endobj -1154 0 obj << -/D [1150 0 R /XYZ 85.0394 441.8891 null] +1171 0 obj << +/D [1167 0 R /XYZ 85.0394 441.8891 null] >> endobj -1155 0 obj << -/D [1150 0 R /XYZ 85.0394 424.9629 null] +1172 0 obj << +/D [1167 0 R /XYZ 85.0394 424.9629 null] >> endobj -1156 0 obj << -/D [1150 0 R /XYZ 85.0394 413.0077 null] +1173 0 obj << +/D [1167 0 R /XYZ 85.0394 413.0077 null] >> endobj -1149 0 obj << -/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +1166 0 obj << +/Font << /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1162 0 obj << +1178 0 obj << /Length 4061 /Filter /FlateDecode >> @@ -3989,35 +4062,35 @@ Ke “@ÄŠçB”‡bW°ÖÌJ©”ÔCq]šù#!¦öŽ„`Üôo]¬ Û˳ÄKú%¾]˨ޖ9…Õ“]|Ìßlšnê.ÛµtlÔFUÝÕ‹T S÷£sÈÀÈX÷Œ–2w»(æ0 ½WbÇÿfù †¹ŽÊG<Ê5]CNÎ¥tÖŸÇí¬HñðYÿh~Áp § ´…Ì8×ü2ÅôIh°`£ ®ÚX¦€œ”H>æ*„“ûPPt3ÉÀŽØE—U.a–ðš+,š'D9³nlà𘺾ñBB0™Ôì Ò¡{Gè}r‰/+Ì6YçÜOyÑ@D(“S*ŒTzé“ñPµÿÿVJp …ô¡”]2@ÒŸfyÈÞ€ÜKf€û éÙ8òÕ žèͶKê-‰?˜^À¡E×°NžÄô;,)ÒJ”¯0¬•;ªå ëÉ3½&„–˺/ÐñÐè›»ç“_A½Îì±ê%”ÔTÚêÏk]ß­ëËAt•Û…e›(Cµ|LÌœÜnè?cX/J•–±È[Mì©ÂëJka5ó\Sî€[²Ä%ØùØê ŸÆkú2|¼uÀ(ƒovY m‰S»f?PÛûŠŒºüQ[·¨>Õ¡Ëãiß×onBË—Z1ycr®ÒíÇ™'¿ö„g 5;_{þgOå,- k€±3Á1kΆ_‰î}-ÊÅüuò<ÎÛ.β¶>¸eR°øý$~pË@œ)¥Ó···ëXîN§ßÆbsh~Ó`.g¿¸ŸâˉTmIeb?U…—þì‹Û•˜™ùC¸ìßþ¹^ÔKˆvÂýß{ŸV9’üOQø}@ Ÿb -jLŒ˜æxqºñ¿IýÅã=þ\%öúoõ꾈CþuèÃcUJ‡w7žæU¿ú£äí'ÛÒagÐ;ð-JZœòEð½™3[BóÂÔÿ Æ+h:endstream +jLŒ˜æxqºñ¿IýÅã=þ\%öúoõ꾈CþuèÃcUJ‡w7žæU¿ú£äí'ÛÒagÐ;ð-JZœòEȽ™3[BóÂÔÿ ƃh> endobj -1163 0 obj << -/D [1161 0 R /XYZ 56.6929 794.5015 null] +1179 0 obj << +/D [1177 0 R /XYZ 56.6929 794.5015 null] >> endobj 250 0 obj << -/D [1161 0 R /XYZ 56.6929 165.9801 null] +/D [1177 0 R /XYZ 56.6929 165.9801 null] >> endobj -1159 0 obj << -/D [1161 0 R /XYZ 56.6929 136.242 null] +1175 0 obj << +/D [1177 0 R /XYZ 56.6929 136.242 null] >> endobj 254 0 obj << -/D [1161 0 R /XYZ 56.6929 136.242 null] +/D [1177 0 R /XYZ 56.6929 136.242 null] >> endobj -1164 0 obj << -/D [1161 0 R /XYZ 56.6929 106.2766 null] +1180 0 obj << +/D [1177 0 R /XYZ 56.6929 106.2766 null] >> endobj -1160 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R >> +1176 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1167 0 obj << +1183 0 obj << /Length 3096 /Filter /FlateDecode >> @@ -4030,41 +4103,41 @@ e$E ËY_¯ÉÌ›H×v™ÝçUäº`×vgá…­uw/Æ23z4›ëÆ2¯s7ìW&€º+-/½TK F­( µbAm¨$FýþºÍcÏ‚P—àU¶ð_™xV(àM÷èê`¸Xw?Ëä¾ÍU›+w:ç|]yÖ/Ùj]X7KÊ%ÖN&Ó±iÒaX)”ЧÊ|ƒU™™~EUHýÍX~ë$ LAK—ªKo[P+©@"f…¥òßÁØ«Ÿ¥ÜJÍŠÛªC¬è•3¨T]rB—ÿ`TQUw›5éàž^.±JµŸÐäÀ,ÈÔ¥…n:ýÐŒW!2ˆà\ê.^¿"î­)gJ%[Á#0'IªM/X¿¸ì,cvzÎÂåñ5hD]=®¼„v© ¥ÕüÎÁð;6&O‚p>ñŸíŒH’8Ýñse‘ù›j[ÀÐl_Ó ÞÌøš¶cî]~ˆÎp|W¿éHH¶ó¡ý'è³jµ-ŠÞã ×—ç¿:óMãÿ€“ò-U'^GK¾¦z÷͘¹›þ”Á; ›1¸ÜC¯.‰}~©­mÖtãá>}?î -0{× ª»ŸŽb¯>´æøµ*P·›Ú_ýF‰s‘ïAt$§WÇ)?®ÃMPÐH§5<Ùqnë ÖT7DtùÌ}—CuB_}Û¥»¥€nºÛƒnwãÏÅÖ21guÈ¥€pvÂÏ—/O(/UõX5K[§k[wW©¸œÑú^·ÿQPB²ƒô}Âȧ}âÔiÀßXgRÄF“·}í:¼õ{Wî¸Â¿PøgFÚluîäz=wIÏ3œ€Cƒ»s²2=ú)CR¡B±Ôé)ÉýËz½|9vÅø·ÿt쬸ýáòâ_Ôr[íå•üß·óO|qÒ¡À?ÛŒ|ù º½úËÿéÙ~º‚’B'‰ÿ„¤!±'*½Rh-­w5ïþü³¯úÿÊì~Óendstream +0{× ª»ŸŽb¯>´æøµ*P·›Ú_ýF‰s‘ïAt$§WÇ)?®ÃMPÐH§5<Ùqnë ÖT7DtùÌ}—CuB_}Û¥»¥€nºÛƒnwãÏÅÖ21guÈ¥€pvÂÏ—/O(/UõX5K[§k[wW©¸œÑú^·ÿQPB²ƒô}Âȧ}âÔiÀßXgRÄF“·}í:¼õ{Wî¸Â¿PøgFÚluîäz=wIÏ3œ€Cƒ»s²2=ú)CR¡B±Ôé)ÉýËz½|9vÅø·ÿt쬸ýáòâ_Ôr[íå•üß·óO|qÒ¡À?ÛŒ|ù º½úËÿéÙ~º‚’B'‰ÿ„¤!±'*½Rh-îjÞýùg_õÿËD~Õendstream endobj -1166 0 obj << +1182 0 obj << /Type /Page -/Contents 1167 0 R -/Resources 1165 0 R +/Contents 1183 0 R +/Resources 1181 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1158 0 R +/Parent 1161 0 R >> endobj -1168 0 obj << -/D [1166 0 R /XYZ 85.0394 794.5015 null] +1184 0 obj << +/D [1182 0 R /XYZ 85.0394 794.5015 null] >> endobj 258 0 obj << -/D [1166 0 R /XYZ 85.0394 731.767 null] +/D [1182 0 R /XYZ 85.0394 731.767 null] >> endobj -1169 0 obj << -/D [1166 0 R /XYZ 85.0394 703.7216 null] +1185 0 obj << +/D [1182 0 R /XYZ 85.0394 703.7216 null] >> endobj 262 0 obj << -/D [1166 0 R /XYZ 85.0394 229.6467 null] +/D [1182 0 R /XYZ 85.0394 229.6467 null] >> endobj -1170 0 obj << -/D [1166 0 R /XYZ 85.0394 201.8883 null] +1186 0 obj << +/D [1182 0 R /XYZ 85.0394 201.8883 null] >> endobj 266 0 obj << -/D [1166 0 R /XYZ 85.0394 144.1965 null] +/D [1182 0 R /XYZ 85.0394 144.1965 null] >> endobj -1171 0 obj << -/D [1166 0 R /XYZ 85.0394 118.9605 null] +1187 0 obj << +/D [1182 0 R /XYZ 85.0394 118.9605 null] >> endobj -1165 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R /F14 737 0 R /F39 895 0 R >> +1181 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R /F14 741 0 R /F39 900 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1175 0 obj << +1191 0 obj << /Length 2474 /Filter /FlateDecode >> @@ -4081,16 +4154,17 @@ xÚ½ko Øð²¢zAËÒ@«–x£D3ži (åuc&ad#ÊÝ8 2DZo3QŠp-øÁ8‘ȶ^1°é¢M#ð»4Î8Êb³í–×?´á©K«¸²Î]‚¾L¡†‘Ù­žþnøSó ú#ÍRÕØ2ù¨ìStÓÄý ãyÒUà SÉSûã°ˆx6õË5Ÿ=Üžú;ùP"*pOi…í–€eIÊT -H¤fˆ 9"ÕÎ’ÿAÝA¤ÿC9 endstream +H¤fˆ 9"ã;%ÿƒºƒ +HÿC‘ Ÿendstream endobj -1174 0 obj << +1190 0 obj << /Type /Page -/Contents 1175 0 R -/Resources 1173 0 R +/Contents 1191 0 R +/Resources 1189 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1158 0 R +/Parent 1161 0 R >> endobj -1172 0 obj << +1188 0 obj << /Type /XObject /Subtype /Form /FormType 1 @@ -4110,33 +4184,33 @@ x 6\>RgÈbÏWÖ¹j[†› WŒÏ¢®{6;»²þFÃÇñ÷ø]š¨)Õ/Ô¬Mu;pk;Ì©Ëdh<åE–ñ¬AÏw³ð¬±±Nê¦ó¡Ä½t•‹ùD„™Â²]°Ä(‡;„ ·åްЭr²ÂÙÄLûˆ T¥Í¡èª‹ŠŽt’¹w_ =Î]ˆ‹=¦uSä÷—ä"ï±yl±‡µÃ-ËkHsŠöreOÚ³êvg›<7ºt,‡Ýe—;ãÒèЭ/I…B÷&ê(ýê³ö󻉨YÙ¹Ç,çkRÔšÚ'^ m" ^˜h±ÎW9AVªy­Â©/fýÆ"•œãûFy-Sng \Çdª¼˜©Æ¥†Í}B©•µŒÎ$âw1.¶&Øíþ²C¶O–ÃVç X×9g¹E{îÇ< •ãóP)!ÍZÜÅŸLÞª~ÑÔ'¯UâXLµüc“ÅXsЖõÚ¯½˜Ó’~òBL–§èªÆ¹O¦ºNZ_[Èü.øšŠû*]3QôçÇñ!Ö-žendstream endobj -1176 0 obj << -/D [1174 0 R /XYZ 56.6929 794.5015 null] +1192 0 obj << +/D [1190 0 R /XYZ 56.6929 794.5015 null] >> endobj 270 0 obj << -/D [1174 0 R /XYZ 56.6929 769.5949 null] +/D [1190 0 R /XYZ 56.6929 769.5949 null] >> endobj -1177 0 obj << -/D [1174 0 R /XYZ 56.6929 749.9737 null] +1193 0 obj << +/D [1190 0 R /XYZ 56.6929 749.9737 null] >> endobj 274 0 obj << -/D [1174 0 R /XYZ 56.6929 282.0726 null] +/D [1190 0 R /XYZ 56.6929 282.0726 null] >> endobj -1178 0 obj << -/D [1174 0 R /XYZ 56.6929 250.2286 null] +1194 0 obj << +/D [1190 0 R /XYZ 56.6929 250.2286 null] >> endobj -1179 0 obj << -/D [1174 0 R /XYZ 56.6929 191.4593 null] +1195 0 obj << +/D [1190 0 R /XYZ 56.6929 191.4593 null] >> endobj -1180 0 obj << -/D [1174 0 R /XYZ 56.6929 179.5041 null] +1196 0 obj << +/D [1190 0 R /XYZ 56.6929 179.5041 null] >> endobj -1173 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R >> -/XObject << /Im3 1172 0 R >> +1189 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F62 1065 0 R >> +/XObject << /Im3 1188 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1183 0 obj << +1199 0 obj << /Length 2134 /Filter /FlateDecode >> @@ -4148,47 +4222,47 @@ x TiJ¶ŒÁo Ž¡1ÿðb‚¥óeãuÜxIÈÙc¯ŠvÖÇãLÊ,_'ú !hãnr¬’Ð:Ú¨ð‚õdFàÇ$¢™¯fÄìóï±t¶Ãªö÷ÇB°ñÀ-°ÅŠH¬vZ;ñ: ±„·(˜â:eY¯òq/ÞxܤI³0sº.:©GÕͲ(Û¨¨¾{øÀ 3cŒ„, ùH‰ç½FPÕkc^úõ­ vðƒ’/¦HÕÔN!¥àUPÌhésiuß4V}OÂ#ôxí³Òß—YÝôVÕÈ ýwy-…PLkÿ*˜ÅXÂ+µ3H)7ßU?ïz´ª~fc…Ù«á5f«;®öa¦°–žïŒ²OÿÜŒ‚ìŠ7ÚÈáù/w1‰è %‘ö¢MÆ ÝË“(ZAPåíª^|¡NQµùb’Áð êû¤Ô†¼ÓÜCÑ6ÂsH^[ðÏÝH%I Vìôœ4šÅ©Ýí ^a6®«ò¶y¾ë„]b†r1O"dA4D#äT7² _ò)Ž­ý…âI_Í |Jq‚s ÊÈ5}ßqg:W(â.BnüÎè»âUí˜Ì % M×$¬ê–·Dî \б_‘ÑÏÊ‘hh´0è×sØf^T½—)¤d앺‡þO’”yJ¦í¬¡¾ b”£¨éƒZ[AïH—žW4Ö,û‘d%FY“Óû%È0 \r]•ìvu´ž»uC6µÃ¼›ðÖ'ØMoû6_Ë›oHö‡#AÄØ¾ô±^‰Å©LU×Ö%æô½†fî¾µÝëðº+¶¹µ/)sO,Á<‘ þˆÁ NŸYæJöµ•Ò;ÅOø–H¡ŠN즦S¾rŸýé“ÿ ;v&žŒl´lê¹@·.ÑGšW¬¥2v/»ýìÂËuþK*„b‰‰12«Ä©ø§"¥$ý´Úïr[/ÚµîM瓯A‘ƒ#!9ï«6ià/bÍ!†¶Žä¾'5ø¿{P”ú] -c˜á©Þ¾‹PaŒm-ã½(.«âOÒ ê jA£VµœßäÎzU…fW<]ÔËÛÇâhŸiâ˃´¯tïûï«JXLáýððÁ^ZùÜÿÌnþm .Viºã«ÑúÚy£Ðr•<ÊR*eI*MéÿUÜU?endstream +c˜á©Þ¾‹PaŒm-ã½(.«âOÒ ê jA£VµœßäÎzU…fW<]ÔËÛÇâhŸiâ˃´¯tïûï«JXLáýððÁ^ZùÜÿÌnþm .Viºã«ÑúÚy£Ðree)•²$•¦ÇôÿV4UAendstream endobj -1182 0 obj << +1198 0 obj << /Type /Page -/Contents 1183 0 R -/Resources 1181 0 R +/Contents 1199 0 R +/Resources 1197 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1158 0 R +/Parent 1206 0 R >> endobj -1184 0 obj << -/D [1182 0 R /XYZ 85.0394 794.5015 null] +1200 0 obj << +/D [1198 0 R /XYZ 85.0394 794.5015 null] >> endobj 278 0 obj << -/D [1182 0 R /XYZ 85.0394 585.0446 null] +/D [1198 0 R /XYZ 85.0394 585.0446 null] >> endobj -1185 0 obj << -/D [1182 0 R /XYZ 85.0394 560.705 null] +1201 0 obj << +/D [1198 0 R /XYZ 85.0394 560.705 null] >> endobj 282 0 obj << -/D [1182 0 R /XYZ 85.0394 491.9365 null] +/D [1198 0 R /XYZ 85.0394 491.9365 null] >> endobj -1186 0 obj << -/D [1182 0 R /XYZ 85.0394 461.8226 null] +1202 0 obj << +/D [1198 0 R /XYZ 85.0394 461.8226 null] >> endobj -1187 0 obj << -/D [1182 0 R /XYZ 85.0394 384.4846 null] +1203 0 obj << +/D [1198 0 R /XYZ 85.0394 384.4846 null] >> endobj -1188 0 obj << -/D [1182 0 R /XYZ 85.0394 372.5294 null] +1204 0 obj << +/D [1198 0 R /XYZ 85.0394 372.5294 null] >> endobj 286 0 obj << -/D [1182 0 R /XYZ 85.0394 206.4979 null] +/D [1198 0 R /XYZ 85.0394 206.4979 null] >> endobj -1189 0 obj << -/D [1182 0 R /XYZ 85.0394 171.8379 null] +1205 0 obj << +/D [1198 0 R /XYZ 85.0394 171.8379 null] >> endobj -1181 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +1197 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1192 0 obj << +1209 0 obj << /Length 4496 /Filter /FlateDecode >> @@ -4214,56 +4288,56 @@ mt ¤ kOþÕ%A\uÓìj´>?ä8b‘8)ŸÁÉÿ×ã <ásä £ %Æ$*“瓱^}ð.CFó/ó¸]NªèÐY '£ïº&’»G«±ÎÅâ(œ3¢üFÎÓurpóëXh·üÄÔ^¤–ÏaÇàÑ3v¬YÞTkt ÐÖÏ® ˜é$5±HN‘³É^6 »§tŸÀÄëjä`¦ä£L=tç’JÖɹ[¾?4C¸Â[ô«CÉ[·P«Ïüac~595_È3fù¡ ¶ÖVxá -]`‚ëYÚ‘aˆéÍ)ö¤Ã‚íw‡æ«w9øø‡n0²Nð-·3õÄCh– ý{ØÌ_üW£\! +’RæJ,…oþ§ÁIÊ`FP\¨©[( DS¸rYžqÿ»ðœõÿK]mendstream +]`‚ëYÚ‘aˆéÍ)ö¤Ã‚íw‡æ«w9øø‡n0²Nð-·3õÄCh– ý{ØÌ_üW£\! +’RæJ,…oþ§ÁIÊ`FP\¨©[( DS¸riÏ8ÿ]xÎúÿ£]oendstream endobj -1191 0 obj << +1208 0 obj << /Type /Page -/Contents 1192 0 R -/Resources 1190 0 R +/Contents 1209 0 R +/Resources 1207 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1158 0 R -/Annots [ 1194 0 R 1195 0 R ] +/Parent 1206 0 R +/Annots [ 1211 0 R 1212 0 R ] >> endobj -1194 0 obj << +1211 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [55.6967 480.2482 256.3816 492.3078] /Subtype /Link /A << /S /GoTo /D (rndc) >> >> endobj -1195 0 obj << +1212 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [268.5158 480.2482 332.4306 492.3078] /Subtype /Link /A << /S /GoTo /D (admin_tools) >> >> endobj -1193 0 obj << -/D [1191 0 R /XYZ 56.6929 794.5015 null] +1210 0 obj << +/D [1208 0 R /XYZ 56.6929 794.5015 null] >> endobj 290 0 obj << -/D [1191 0 R /XYZ 56.6929 769.5949 null] +/D [1208 0 R /XYZ 56.6929 769.5949 null] >> endobj -1041 0 obj << -/D [1191 0 R /XYZ 56.6929 749.0409 null] +1046 0 obj << +/D [1208 0 R /XYZ 56.6929 749.0409 null] >> endobj 294 0 obj << -/D [1191 0 R /XYZ 56.6929 209.5509 null] +/D [1208 0 R /XYZ 56.6929 209.5509 null] >> endobj -1196 0 obj << -/D [1191 0 R /XYZ 56.6929 183.9497 null] +1213 0 obj << +/D [1208 0 R /XYZ 56.6929 183.9497 null] >> endobj 298 0 obj << -/D [1191 0 R /XYZ 56.6929 147.0778 null] +/D [1208 0 R /XYZ 56.6929 147.0778 null] >> endobj -1197 0 obj << -/D [1191 0 R /XYZ 56.6929 116.7981 null] +1214 0 obj << +/D [1208 0 R /XYZ 56.6929 116.7981 null] >> endobj -1190 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F14 737 0 R >> +1207 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F14 741 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1201 0 obj << +1218 0 obj << /Length 2349 /Filter /FlateDecode >> @@ -4277,69 +4351,69 @@ xÚµ]s J[¨åÅ%RÉ )Σ b±ÁÑ·òÅe|–˜üVb"™ä ì=îÒRç''ä€*’'ô$ãgéùHèŠ5F²}Ê/¨É0¬ô-ÆDsNƒÅUJ!n@XÁ<¾Ò„fe K¸jœ!ž8m·¤a´€i÷¸‹BS¹Ùo©Úom€…›QËcˆ.»’Õ’-mü‚õ-·Sq%ט‚–Ôz•ÀþóZ±@“%™Pv ù1üÔBÄNh[1¢„Ï Ao¼Íg¢V ïXܽPد8 Y‚Å$†„9’ÀCwÄòôÂÁqÀ`^2eIw,>¡6úL¦ÃJ&²³ŒZñZS6h)Ø…Ú]ƒ[wI~ïbÜVÚ3°u©ž°wÐò {´Éñ‘cŒ)ÈVM›®/í'ÄèZ½ÁL×zܾ“ÂNRDz*×}›µ+Ü=Ñycýs!³h 48:Òòþjà?ñ³¯Ö妴—àpBŸ§ÔÑoÊë/\g8)—;µ94 Ê>üå)ËË5<ƒSmB¿«-ôn7Åן^¾õú(ÇuŸ6-ˆ6IX{8**‡!ÄÓõ@Ipj=TÛK¶«:Cð§×°Sû)s¶ 3YÊê©l+ôãÞr\¹>êr€z€ë/ó¾ˆ}º—iCó€³:qÚˆ—­ª¯/ß=R*îՔؘR[zw¸DeÚ¢þzÏC¹ýè’'²~›¯‡|=¸¬³ë„ïäÞPÀ­Ãþ­Îè+Bàÿ±%N…òïŽç`ò}â"emq¡zÍ9¬¹Ì,vÇ…)xL;Î@ÏÙ®ÔÆ&ÍÀä#«ÚNn[Œ‹f€Ýrá oƒ‹wh¦\é¨"“HejäfªÙ'S9‰O}¼‹é›"R%'ÿhlW» k[óþ5u^‚Ü ö -ê}»Ý·¸¶Ñíª.š7Xkã›Ì­tÙö‚½2Ñkfdã‰Cy1U–»˜\Áºk ÚÕÎÌ·ùlŠà ,Ù±+pb®®òt­  e¥„JŸ1w.9QŒ@¡˜x•v’.)1 €^ëÜÙíª~AÀ\~½w9D¾mj7ÀÌÔ(±1–ìÓŒcŒž¡ rî?!‰ù·n¢ÍF;ßûî?ÿ˜B5&’äLû]ÐjµTy¦Œ’„:å¼û÷pÌúâØ\5endstream +ê}»Ý·¸¶Ñíª.š7Xkã›Ì­tÙö‚½2Ñkfdã‰Cy1U–»˜\Áºk ÚÕÎÌ·ùlŠà ,Ù±+pb®®òt­  e¥„JŸ1w.9QŒ@¡˜x•v’.)1 €^ëÜÙíª~AÀ\~½w9D¾mj7ÀÌÔ(±1–ìÓŒcŒž¡ rî?!‰ù·n¢ÍF;ßûî?ÿ˜B5&’äLû]ÐjµTy¦Œ’DzÊy÷ïá˜õÿã0\7endstream endobj -1200 0 obj << +1217 0 obj << /Type /Page -/Contents 1201 0 R -/Resources 1199 0 R +/Contents 1218 0 R +/Resources 1216 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1210 0 R -/Annots [ 1205 0 R 1206 0 R 1207 0 R ] +/Parent 1206 0 R +/Annots [ 1222 0 R 1223 0 R 1224 0 R ] >> endobj -1205 0 obj << +1222 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [406.6264 617.3695 456.8481 629.4292] /Subtype /Link /A << /S /GoTo /D (tsig) >> >> endobj -1206 0 obj << +1223 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [140.5805 606.0819 196.7992 617.474] /Subtype /Link /A << /S /GoTo /D (controls_statement_definition_and_usage) >> >> endobj -1207 0 obj << +1224 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.6195 562.6731 159.8382 574.7328] /Subtype /Link /A << /S /GoTo /D (controls_statement_definition_and_usage) >> >> endobj -1202 0 obj << -/D [1200 0 R /XYZ 85.0394 794.5015 null] +1219 0 obj << +/D [1217 0 R /XYZ 85.0394 794.5015 null] >> endobj 302 0 obj << -/D [1200 0 R /XYZ 85.0394 769.5949 null] +/D [1217 0 R /XYZ 85.0394 769.5949 null] >> endobj -1203 0 obj << -/D [1200 0 R /XYZ 85.0394 749.0225 null] +1220 0 obj << +/D [1217 0 R /XYZ 85.0394 749.0225 null] >> endobj 306 0 obj << -/D [1200 0 R /XYZ 85.0394 668.2594 null] +/D [1217 0 R /XYZ 85.0394 668.2594 null] >> endobj -1204 0 obj << -/D [1200 0 R /XYZ 85.0394 636.8261 null] +1221 0 obj << +/D [1217 0 R /XYZ 85.0394 636.8261 null] >> endobj 310 0 obj << -/D [1200 0 R /XYZ 85.0394 425.0299 null] +/D [1217 0 R /XYZ 85.0394 425.0299 null] >> endobj -1208 0 obj << -/D [1200 0 R /XYZ 85.0394 396.4061 null] +1225 0 obj << +/D [1217 0 R /XYZ 85.0394 396.4061 null] >> endobj 314 0 obj << -/D [1200 0 R /XYZ 85.0394 136.3155 null] +/D [1217 0 R /XYZ 85.0394 136.3155 null] >> endobj -1209 0 obj << -/D [1200 0 R /XYZ 85.0394 104.8822 null] +1226 0 obj << +/D [1217 0 R /XYZ 85.0394 104.8822 null] >> endobj -1199 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F41 935 0 R /F23 734 0 R /F53 1027 0 R >> +1216 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F41 940 0 R /F23 738 0 R /F53 1032 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1213 0 obj << +1229 0 obj << /Length 3704 /Filter /FlateDecode >> @@ -4360,29 +4434,29 @@ B+ \Þ‡ÔsÌ=’K1­ûÝ9>ÇâR$u»,êP-AM,ñ¿ãÑc<ò3Ñ£>žä3K&zL^Íú–ÕÙ|$1*£J/ i.Âþvé?–Hbìõ%êôÓ%ª„»oOo'|½ºÃn×î¹× f\ýËØ Æ+0ªÀp¹ ˜¶¢Ôì[êñŸÞl@¸Òùº}*¾gþ„Ü|‡= b¯j&o|W$ü]_àsã¾ãRq aÖœ’þÖ2MÅÉn2¾ÜÐ3|ñêP¤ZMŽ-Ûfj¿â7bb‚3‡`¼£²õ ÐÀWû ÓâCI ‚>)ñqSÙk˜å›4ò:¾ñ‡)ÛafPÇŸj(̯Cße˜,Êòtêà?%#™zoÈ÷jöS ×$qdAlÇ·c”6|‚q†Å¿côqJ@Þ‰âõe(UÇXç¯ ×PRq‰È{4näÊŸ,NZ=5èÎQ=4\Rr¿kp¦Î/ìûH¡ü7îš7øÕ”þ«O•žÛý#«g]=³@¤ÂWÅ& -¿ë=~ͯÝ[G€ÿ^ ;j£i/_Ûay"Á’¸/lïžüQ'ÌÑWHÚ)õøsL=ôpèrÛ$Qžfê´á³/ª‡ î.sÒx¢¢«QŸ@àŒèk\¶±´ÁèРߨMS×,Yú“+Û¹Q³ïß#so‰27l\áŒP~ÖeÑñÐV¸ÊUÉ}ªaWÒ§0|¨>”|× }]¬t„Ÿ¾Žý×[ÿ÷—ÇÃgÙI©,“áŠ%êcH˜(äœÊžQî>Q~Nú`UðËendstream +¿ë=~ͯÝ[G€ÿ^ ;j£i/_Ûay"Á’¸/lïžüQ'ÌÑWHÚ)õøsL=ôpèrÛ$Qžfê´á³/ª‡ î.sÒx¢¢«QŸ@àŒèk\¶±´ÁèРߨMS×,Yú“+Û¹Q³ïß#so‰27l\áŒP~ÖeÑñÐV¸ÊUÉ}ªaWÒ§0|¨>”|× }]¬t„Ÿ¾Žý×[ÿ÷—ÇÃgÙI©,“áŠ%êcH˜(ä\?£Ü}¢üœôÿ_"ðÄendstream endobj -1212 0 obj << +1228 0 obj << /Type /Page -/Contents 1213 0 R -/Resources 1211 0 R +/Contents 1229 0 R +/Resources 1227 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1210 0 R +/Parent 1206 0 R >> endobj -1214 0 obj << -/D [1212 0 R /XYZ 56.6929 794.5015 null] +1230 0 obj << +/D [1228 0 R /XYZ 56.6929 794.5015 null] >> endobj 318 0 obj << -/D [1212 0 R /XYZ 56.6929 607.7662 null] +/D [1228 0 R /XYZ 56.6929 607.7662 null] >> endobj -1215 0 obj << -/D [1212 0 R /XYZ 56.6929 584.6557 null] +1231 0 obj << +/D [1228 0 R /XYZ 56.6929 584.6557 null] >> endobj -1211 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R /F39 895 0 R >> +1227 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F39 900 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1218 0 obj << +1234 0 obj << /Length 2891 /Filter /FlateDecode >> @@ -4401,31 +4475,31 @@ n ÁD˜×žtÔ³IÀy9®<þ!€sŸáe`_þ=;»Ø#WÁn_5E4MIã"ýstˆ¨Ðûž «ý >k̼Â0RΔ1H™4nVB%,Uv®šÎÙ´Ý1BM’2‘ÚF}·Ô:aZò³ˆBàñÛ*&W/c^ïÍ  …¨NÍb¼ÍõÜ3`jNÓÞ{h“·:~ôÓduÔv¦žbÕ^#Ä(H7ï VCÍ„ƒLLJKfÅøž@r8{î˜É n1•ß¼K§Æ‹†§Ìà â +‡„œâôÖ@Óá¾§•£°ãc´ýHð¾¥Î’gê]©2¦d¢g<>Sðò1ûkwXãôžˆü8¿uE-LDBK´í£¯”ßzÜL StÏ]ÔÙ*ä¶^¹jæõ!?ö4ê cŽÜÒ/u©” V³”WSâEi²{íÞÑ»ºªÊäÑÜ‚I(;ÏL=ö|;>ý¸ =5.±…ûNÅ*þ4Y›¸ht¤EQÕv©Ä¼ª_&³s͸ôk¤ˆ&–G-ÂÇl=6Ò.ïÊÇ%„YN Ž0ï¸y•ƒMlʦìòd Qû7¹Ðëf9·z>o{˜H)Q‚|.Øw4L¥Ivú†Ñâ”&2d óC”·Elù paÿPf<{­0ä,ËÆò‘Þc0#Xçûz ÐÙÈÖ†>\Š&Ø£ùh»ø¶=Ð0˜è‘våÓ¦˜´ç/힟£QþÜ]õ87ç?‰‹5©¡21#¤)þ€C“Ýæš÷“_|ÆõËé†Ë_|.ÏE*‹ðôÅÝo^‚3yNÄe¦¸°3’.~zW½BÈåiTyE \ )‘ú…‚ÁëñWo_+¦Ëèþ=ؽBÃÿòK_‚”`ØÂÔθMh9§mt> dgµf8güaÄÿ3[*#E >A]PC¿MÌéò?M¶Å¨‘3jò°Ù×™¾æÁРÎøc, H„úy©OꨨÐÅy}朔Æ|œ -=áŸË˹àÇÕÓ×ùtÄ×vÿt>íè­:0tŸyØú©¬éñ˜nõz'_&: ÊW±2sTÛú‚á—®®ÖgÔ‡zfJ€{,+W/Co]³“Þ,×oíè­:0tŸyØú©¬éñ˜nõz'_&: ÊW±2sTÛú‚á—®®ÖgÔ‡zfJ€{,+W/Co]³“Þ,×o> endobj -1220 0 obj << +1236 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [173.6261 333.9221 242.2981 343.3317] /Subtype /Link /A << /S /GoTo /D (the_category_phrase) >> >> endobj -1219 0 obj << -/D [1217 0 R /XYZ 85.0394 794.5015 null] +1235 0 obj << +/D [1233 0 R /XYZ 85.0394 794.5015 null] >> endobj -1216 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >> +1232 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1224 0 obj << +1240 0 obj << /Length 2569 /Filter /FlateDecode >> @@ -4442,35 +4516,35 @@ X ¼äñò‹¼èèyïÛåÁZru(OhÙ¡Ûqüþä.µäaÈ| ËPØCF3ûLÉP=S#Ä‹dà|Í”§õI3ðÕ]¢ê·¦iC[Â>M ´tƆ¬®&+£²Æ½!Îú:7ѹl‚žžÚme³M[YãD ¶óSÝ„ÖÅTù>4œ@F,àÐEüujCêQ¹Hìÿ’nÇÓ–åpøŒ%À­â˜Ó32½Dä/³›ø’n—ðV¹|þÁ´ܼTºkÛwÚÀe*HC OêÚh Ý!Є•ñå”iôí˨³¶qg˜€´[k÷¶M³–sB¹©}&Ž•|SårŤ˜§•ë̳½æ*i’»é>r¬Ü]Öö¥t±\² :0M‘)](ƒŽ¸Ý„¥8-€6uUÐc.®Ü¦ÝÆp|Ô¿µ?êf”4þ, }di’v ?°tBÍù}+5»½œ¤Ûñ´š½I<£eîÑg*Vmiùœš/ööÝÿ>ɤ¸ÒEæ€&ßw9õ÷V×M}B¬=¿_'‚c©òo)UD(Ô3)2V jMúBãRɳB}{œsŽ¿R쓪îÚ¥NàV)x,>-ÞãßJ¼ÿ‡Øy,âO#ñª‰Ð£´SéºÌï»'û§ÅûîãO‹¥„‚”¬vµ(æ×øÝ7š×mºÅezF4W`_[þ½¦µ¼,¿´ûšÖ÷”&Ó –·®öt*ÅF7_=$Í3jÇŠI—:µ? r¦[~Jçi~‚( ¨ù°ìJN~†öfÏF±—~ôîÿ# ˆ˜¯Ô WZµHAà -i¡ÈïÑ'y÷uÜb Xÿ/LN+8endstream +i¡Èñ蓼û:n±¬ÿL¦+:endstream endobj -1223 0 obj << +1239 0 obj << /Type /Page -/Contents 1224 0 R -/Resources 1222 0 R +/Contents 1240 0 R +/Resources 1238 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1210 0 R +/Parent 1206 0 R >> endobj -1225 0 obj << -/D [1223 0 R /XYZ 56.6929 794.5015 null] +1241 0 obj << +/D [1239 0 R /XYZ 56.6929 794.5015 null] >> endobj 322 0 obj << -/D [1223 0 R /XYZ 56.6929 556.3324 null] +/D [1239 0 R /XYZ 56.6929 556.3324 null] >> endobj -1221 0 obj << -/D [1223 0 R /XYZ 56.6929 531.5504 null] +1237 0 obj << +/D [1239 0 R /XYZ 56.6929 531.5504 null] >> endobj -1226 0 obj << -/D [1223 0 R /XYZ 56.6929 214.5791 null] +1242 0 obj << +/D [1239 0 R /XYZ 56.6929 214.5791 null] >> endobj -1227 0 obj << -/D [1223 0 R /XYZ 56.6929 202.6239 null] +1243 0 obj << +/D [1239 0 R /XYZ 56.6929 202.6239 null] >> endobj -1222 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R >> +1238 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1230 0 obj << +1246 0 obj << /Length 2985 /Filter /FlateDecode >> @@ -4483,23 +4557,23 @@ e6M2 Þ¹WT´wö_KE!žŸåýiÄAåBÄàÜFUTdâjŠ—ÁgL Âéã†ÍGŸL÷ôé , úu¤@íèŸëÝ`_»¸Še•—Ô×Å=ž(ÖvÐîxŸE]¹°€ýœ]……474` ¾ê¾óóC•cåë6ƒQ©w¬ªïÐ3e™í”öÎR¢ÎóS$(GA¸ÛÒ/s¯xã(Œá#¯žó—iœ¹[¯j⦣ó«ëéЖßÏ®Ýï„D5 "ÇE :‹•~SP9Cщ¾i€jtïn0…ÍPgÿÙ´Þɱ4œ{ #Æ;ˆ´hꨒ¶ 2Lç\‚¢½q©3²«RR:Ç |ÊÃy^#™GÝQ“×f)A‹A”H"ä Û6’î[KÑ){&{©TÁLõ„˜¡Ûðµ5Ø_Tu¨%U‡ê êóዊò1½”£Î¨› ¦mñ ayÃú‹ne²XTçÝz³|Cc³y4ÚŸß-z»Bg&À‹3£`f*|')ŠH×>Ù]ß"Éb=D`›VP¢l'©}§h§Ë¦-»òi'¹í[¯éJª .fWÕP>5U.ÐÏÆwybÌN25 ¹NxFo»`»f‰T‡KÌ;zluî…ʼnd{ï»íÚ=ݺ¬U0Êøò\h~5Ù}(Q—€ ]r Cx´î+2ÙOLàuyhQÙî2=h-ábtHúÄt"ãÉpW ïÊÔH»3ª%û¤eyÿ2hQmÔöÖ9ÚqB*§·­P²®ÄmAÛvÊâ®0–C¯r18;Lêœ -™òm4uOyU@Â7=¬»ná9…2£Ä„ÜP÷à m£Ùý ‘~ìõp4¾õq¯ã}Ìòe8h ­¶?žû5žc˜Ùû5Þÿ7*,„ë _¦‰†nøŒ~Å÷ɯù„à±ÉÂQu¿=Ȇ~óÇ&£ †ÿõ†ÛŸ_*Ë4íÁ;ƒé8™q8V¹çw§ Šïc"Ó8IŶ[oñÿÕ¾$§endstream +™òm4uOyU@Â7=¬»ná9…2£Ä„ÜP÷à m£Ùý ‘~ìõp4¾õq¯ã}Ìòe8h ­¶?žû5žc˜Ùû5Þÿ7*,„ë _¦‰†nøŒ~Å÷ɯù„à±ÉÂQu¿=Ȇ~óÇ&£ †ÿõ†ÛŸ_*Ë4íÁ;ƒé8™q8V¹çw§ Jîc"Ó8IŶ[oñÿÖ$©endstream endobj -1229 0 obj << +1245 0 obj << /Type /Page -/Contents 1230 0 R -/Resources 1228 0 R +/Contents 1246 0 R +/Resources 1244 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1210 0 R +/Parent 1248 0 R >> endobj -1231 0 obj << -/D [1229 0 R /XYZ 85.0394 794.5015 null] +1247 0 obj << +/D [1245 0 R /XYZ 85.0394 794.5015 null] >> endobj -1228 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +1244 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1234 0 obj << +1251 0 obj << /Length 3540 /Filter /FlateDecode >> @@ -4521,41 +4595,41 @@ KvF:3+ )_ U!˜I¡ª½ ¥«„ÅBF0~¹dUû+ÞBoÝ8íªmèŠð+÷[pÇ E¾Ìw‚Ÿ=Wx8ο ó‘[7äF_,ÜI\÷"'[­tSm½à€E"dI†þ]ô {ùj@îþ.P‚@°/(fAÄ„ §Â½Ýy®U"L)&}¨4<¦¶F`¯ÂúWKî¢. ûWK‘÷jɾ©„@ü§EÙr©wT£È›V—³ªt èíãêwãÔÒ+ÆUU·]>~¼§¯ïlù´aŒQÂfÿë;÷9bÓ¶ƒO¹Þô©ßqhÕè¬vÏCíìÈçø¢­Ý‰ì+>r̃å-UkuAÞ¾ßfìí¸=øG/#íÂ'½ëcÿ¶Æ{ShN‚q¡s+ì p^*عû#œÝ¡ÿgH[Pendstream +é%¯'ÁùȼÜáÀè]öçjXý5ü×4¬: «q Cö/%½=£Ê6aïפy9ÜØ”yD©ºbRâ ‡(õæoZwúUýð¥rϲÕBj Blì Ç®7ѽÚ8„{·þÀbîâjw:¶Èï°ŽyºÝc¹]Ä{aœßµ˜G^¾c̺÷ÐVÌû3©X’¨þO„°ïî‹Mí¶Ì·mÖêeåýPgx+~Ì«û]÷ÛŽòÞÊ#†¯ô!bUaËиFBÖ˜õb›áˆýEÚÝùbp¸b']ý›WåÝø)€ÜZQ豇³ L$rø4Ë®(>@ü§EÙr©wT£È›V—³ªt èíãêwãÔÒ+ÆUU·]>~¼§¯ïlù´aŒQÂfÿë;÷9bÓ¶ƒO¹Þô©ßqhÕè¬vÏCíìÈçø¢­Ý‰ì+>r̃å-UkuAÞ¾ßfìí¸=øG/#íÂ'½ëcÿ¶Æ{ShN‚q¡s+ì p^JíŒÜýÎîÐÿ g [Rendstream endobj -1233 0 obj << +1250 0 obj << /Type /Page -/Contents 1234 0 R -/Resources 1232 0 R +/Contents 1251 0 R +/Resources 1249 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1210 0 R +/Parent 1248 0 R >> endobj -1235 0 obj << -/D [1233 0 R /XYZ 56.6929 794.5015 null] +1252 0 obj << +/D [1250 0 R /XYZ 56.6929 794.5015 null] >> endobj 326 0 obj << -/D [1233 0 R /XYZ 56.6929 769.5949 null] +/D [1250 0 R /XYZ 56.6929 769.5949 null] >> endobj -1236 0 obj << -/D [1233 0 R /XYZ 56.6929 749.9737 null] +1253 0 obj << +/D [1250 0 R /XYZ 56.6929 749.9737 null] >> endobj -1237 0 obj << -/D [1233 0 R /XYZ 56.6929 433.0023 null] +1254 0 obj << +/D [1250 0 R /XYZ 56.6929 433.0023 null] >> endobj -1238 0 obj << -/D [1233 0 R /XYZ 56.6929 421.0471 null] +1255 0 obj << +/D [1250 0 R /XYZ 56.6929 421.0471 null] >> endobj 330 0 obj << -/D [1233 0 R /XYZ 56.6929 173.1316 null] +/D [1250 0 R /XYZ 56.6929 173.1316 null] >> endobj -1239 0 obj << -/D [1233 0 R /XYZ 56.6929 148.792 null] +1256 0 obj << +/D [1250 0 R /XYZ 56.6929 148.792 null] >> endobj -1232 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +1249 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1242 0 obj << +1259 0 obj << /Length 1976 /Filter /FlateDecode >> @@ -4571,62 +4645,62 @@ ab ¤v€À7>sz Ny°Ãò¦ˆ_x«¸(°n:;Þ²3õùâŠÜz?!S§…Øä…ÆÜÉ4ÀMBX@#´…¹&Âùµi›^“¼¯èåÞ‰Áé‡î4 ¶UÊ6…×ê„z»W!UçMcãľ쉗ӣi»:wÚ)`@ºg¿t(Öv’ ß‚”‰]!3aw¬;¬ª«jŠUxöR†n—…Ï¥~ÈaL“ e)¿ »ÂöNFçûm49Žÿ}CÔj_³½væó†dtGƒ´­ÎDïn{4¥vQæô ©öÚLÆ (ülëÆ›nk1ÒXó°°/›nJ?ãlÞÆéXåƒytr¶«‰4nbo|Ûö -%ܧ½)ÛaöP‘°,ÍøLÖ#¾ˆ¢iÁOŽGo> endobj -1245 0 obj << +1262 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [519.8432 682.6714 539.579 694.731] /Subtype /Link /A << /S /GoTo /D (lwresd) >> >> endobj -1246 0 obj << +1263 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [84.0431 670.7162 117.8035 682.7759] /Subtype /Link /A << /S /GoTo /D (lwresd) >> >> endobj -1243 0 obj << -/D [1241 0 R /XYZ 85.0394 794.5015 null] +1260 0 obj << +/D [1258 0 R /XYZ 85.0394 794.5015 null] >> endobj 334 0 obj << -/D [1241 0 R /XYZ 85.0394 731.9325 null] +/D [1258 0 R /XYZ 85.0394 731.9325 null] >> endobj -1244 0 obj << -/D [1241 0 R /XYZ 85.0394 701.4683 null] +1261 0 obj << +/D [1258 0 R /XYZ 85.0394 701.4683 null] >> endobj 338 0 obj << -/D [1241 0 R /XYZ 85.0394 475.6865 null] +/D [1258 0 R /XYZ 85.0394 475.6865 null] >> endobj -1247 0 obj << -/D [1241 0 R /XYZ 85.0394 450.9966 null] +1264 0 obj << +/D [1258 0 R /XYZ 85.0394 450.9966 null] >> endobj 342 0 obj << -/D [1241 0 R /XYZ 85.0394 393.3855 null] +/D [1258 0 R /XYZ 85.0394 393.3855 null] >> endobj -1248 0 obj << -/D [1241 0 R /XYZ 85.0394 362.9213 null] +1265 0 obj << +/D [1258 0 R /XYZ 85.0394 362.9213 null] >> endobj 346 0 obj << -/D [1241 0 R /XYZ 85.0394 329.3761 null] +/D [1258 0 R /XYZ 85.0394 329.3761 null] >> endobj -1249 0 obj << -/D [1241 0 R /XYZ 85.0394 301.8169 null] +1266 0 obj << +/D [1258 0 R /XYZ 85.0394 301.8169 null] >> endobj -1240 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >> +1257 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1253 0 obj << +1269 0 obj << /Length 1168 /Filter /FlateDecode >> @@ -4634,120 +4708,122 @@ stream xÚ½XÛnã6}÷WèÑ.@V÷ ö)›:iÝlëzŸÒÀ %*&B‰Z’rìnößKYK‰ÝJŽ$J<3çpf8¦¡éêÏкh^`CG7-LFºö Þ]ŒêPÚ_}œ~¾²<-€kºÚŸÎÊWn…ññæö—r$(/G@gÓ«élz{9ÜÏ?¦ó†K›¯¡[‘o£»{]‹íO#ZïhOêA‡F˜Z2² :¶eÕ#tôçè°õv7õ ~†MË5h-}ºº‚òœº–ií¼›W×Ç(—+n"– ’–C[,Œ/Rö¡|¾/È*‹À0`à8f{z„¥,D–¼!ò ‚hžµï,“„¥‡çí¹1zÄ€|Ë1ß7c®ÀÍñ si.Vào–bQ0«\F쩟‚+¤hBJp*ÅpOVLH $’DH¾$hS¾Hód‰y II‚(àXd,ø'’œJ’Q Â%§¤L’øe”Ïåo2JÂ:B«Á ‰¹ZBºíA”ã0çB…æpÿxš–î¹Í°1|z.TœG cŒ±"·¥úds°Dâ„€ßM9K@Dâsœ†õ2ý¥;úaÉKu;C‚¢5V3Œ>•!‡§hIñpÚÕô5¢$Bò¤U« (cH¨r¢]-%ÏUú 4\1Þ~Û<)–ˆ"¸X82 CœIU3ÂqtBucü ñh¿¼å]‘%ÅŒ ²ùÊèŒy;ßËKdÙEQ¥ã]ƸlÆ‹‡ûò©2!¬íí.?úè“«2¥j]ø¨äæëÆ£¶¾ïÀL ŶÞa´×¥\­EQ¹þîyW£tàúq/d®U( À ¬’m#MWpG%M¸ÂJ•VõÝó;–Æ‘ºø·üì! †´RˆÐÎyHÇG‚ì%#ã5£dó’Îmêÿ"ß¡QØdΔ+ç«:8‘Ûá©_³-wÐwä,øúým’%%éÃp•Švõ ´›…ª¹‡…X$H5… Jêºö£‡O%h« =/&¨w®Ó`c°!Rbþ/ïßèöpÉQ*âºM]ÝÙÜmpϯDž©ŽŸY‡T[t“^gpºB.s÷Q</RE• 3¥i¬¼Xšøkˆm*WXq6vKªú‰£çË¥¢Û_Û 2Pìý]W‹‘¡ë»fêÇÃ_{螯òÐ=çâk¼O½»=P§¯ê´gXºÆ¬"ó¾–ËÒ+XÎÃW[ñþŽdv«Ï¬úQ/€–é9 -z¶eïPê´ª­Mk ׃–gÚõßSlo1¯{a :žmT¶c¶½í¶nÏ•'¦38ÜÙV¢öRÂò íÛöpoŽZ,Nñßé â› ÷'©¶Zß7›s@Ójšž¯È)Ê©‚‚m¿ò¼>U|íú?ÌÕÌendstream +z¶eïPê´ª­Mk ׃–gÚõßSlo1¯{a :žmT¶c¶½í¶nÏ•'¦38ÜÙV¢öRÂò íÛöpoŽZ,Nñßé â› ÷'©¶Zß7›s@Ójšž¯È)Ê©‚‚í¾ò¼>U|íú?Í-Ìendstream endobj -1252 0 obj << +1268 0 obj << /Type /Page -/Contents 1253 0 R -/Resources 1251 0 R +/Contents 1269 0 R +/Resources 1267 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1250 0 R +/Parent 1248 0 R >> endobj -1254 0 obj << -/D [1252 0 R /XYZ 56.6929 794.5015 null] +1270 0 obj << +/D [1268 0 R /XYZ 56.6929 794.5015 null] >> endobj -1251 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >> +1267 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1257 0 obj << -/Length 1152 +1273 0 obj << +/Length 1164 /Filter /FlateDecode >> stream -xÚµXÛrÛ6}×WðÑê P\^&OŽ+»Î4N«ªOªFÆ"r¢4ý÷‚I¤EY$DƒÜƒ³g±‹°…̶<õmËõmÈfV¸!ëÞ¼»áê°ûÔ¿z;ý|M]ˇ¾Ck¶ªayy¶fÑüâê×Ëßg“é†.8ÌAooï~)GüòçêÃÝõíÍ_Ó˱k_Ìn?Ü•ÃÓÉõd:¹»šŒö6ö¤B8ap}ûÛ¤|º™^¾9/fïF“ÙÞ—º¿ÑܑϣùY‘qûÝAê{ÌúbþAû>±Ö#›QÈlJw#ñèÏÑ{ÀÚÛ´M?F=È<â¶h㚀˜è9[.ó¡C -œƒÐE*•.ŸþF •O"]†¿ç¾Z>®º6eÄOÕ+è3†­Ú …KëÅ»x³ÏM¶}hSß1O -©Sû¼áj 2¹Q!ÎS–u¾Î2ˆ"Õ ì»8&§“#Â%#JŠÌÛ6FÃIJOÍm·‹õ½bBdħ;&¸Î$w—gY'%¨ mÏfýCw>D?jõ¿z6Å -ÊÉ€Tʸßòl)Õ2‘ ,ÔªrÓäO•äÉfý‘«vò „H4WAÜe|ZI¶â -h±æè<~BnôKhˆ(îFã D' Wt˜‚0<é “3F~™ª~âÌÃÊÄ#ï>}ƒ¸™\q¹, -4ï9Í^ð¾äsÕb‘ižäÞWô]ÐVR­ƒ£¬— æƒ/|_{ªp'ÛjüP¬p¶ÕtY±Ä0éåéÞvÀÚÚÛ¦Æ×¤·È;•Êmë ’HíãÊìú·­23è»®Ó^ç‡òZÕÚEku,w2Ü…gc{í°Ú'¨ÚèD!¡®ß¾ÕÅô’µ†ö -²äC‚k•µ…ëYi Á»Èy%ºÄ…ØöÈÉ=ò¤¼}6ÊDj±Ú‚ˆÇÁvWªB™DY ¥öÄ©:¥ãBêû”`ìeiãRHmß?Ïò|Ò2ð’û’¢ý?- ×àI<;Ç$ˆ3 J¤ràß=«ƒ«çØÎØ@ à ñu¥@,ïA&¾ñýÑ?&®‰Ù`æùÓ2KyØA(M{qlÙYî(ÐAOû†+ïš‚þ“g:?½„}ó É}·ÁþJäÚ#f« äCŒÚôG"̆ú e*ÍòkfKuT[š¦)|XæXµ¨ož#c’âðí‹ ”ʸRE»Þ¬B+FŽƒ<öíÓÔk‘%eïãSÞnä%ºÇ~Ô Ÿ*ù(¢VŒN‡7sìÉô@k­òÒ*d Kƒ£&©³…x|eøPÇEÀ¬îî m7•”Áüz±å^íïd^|‹y¸âµMËæydAIhí‚’"zÄww¤rGmö”ùþºó˜úÿ;HÏÌendstream +xÚµXMsÛ6½ëWðhu(>’˜œWviœVUOªFÆ"r¢4ýï?$‘e‘t<>˜¹oßb ` ™?ly "ÊmËå6d3+XuoÞÝŒpõ Ø}ê_½~¾¦®Å!wˆcÍV5,"ÏÃÖ,œ_\ýzùûl2ÂÐ…Ç€9èâííÝ/å/ÿ]}¸»¾½ùkz9ví‹Ù퇻rx:¹žL'wW“1ÀÃÆžT' ®o›”O7ÓË÷ï/§ãÅìÝh2ÛûR÷#š;òy4_ +4n¿!H¹Ç¬/悘sb­G6£Ù”îF¢ÑŸ£?ö€µ·…i›~ŒzyÄmÐÆ51%Ðs¶\Æ¡C -œƒÐEš(]>ý*Ÿdº< Ï}µ06|\ 0tmÊ +ˆŸªW3†­Ú …KëÅ»x³ÏM¶9´)wÌSBêÔ>o„Ú‚,Ù¨@€Gç)Ë:_g釡jæ.$Ž Å)ÂäˆpÉÈ„’"ó¶Ñ0±ìSsÛíb}¯˜átÇ×™äîŠ,ë¤u¡íÙ¬è·èG­òãWÏ& XA9&ITŽoE¶LÔ2NX¨Uå¦=ÈŸ*ÉãÍú£PíäˆMúZÈX õèG=±ÖþW •g+¡€–kd|?‘lôKhÈ0êFã D' Wt‚ ’"î“9F~šÚ|̃Êä£è>}ƒ¸™\úQ¹82Ë¡çü5{)ú’ÏU‹d¦EœlD_ÑwA[%jíå~ `>ø"ö¨ +w¼­Æ% wa[M—K “^žîm¬­½mj|{‹¼S©Ü¼*ÉÔ>®Ï.‡”¸mõ™AîºN{mœŠlUq­5²ÜÏpžM¶Ã¦jŸ j£J…„º¼}Ë4è%k íd%ˆC‚k•µ…ëYi Á»Èy%ºÄ…ØöÈÉò¤¼}¶Ë8Ñrµ¡ˆüí®TIf-”Ú§Bè”6Ž ©KìS‚±—¥K!µ9?Ïò|Ò2ð’s Iq8®þ“xvމe (‘Ê÷¬®žc;`!l´ÿul,äוQr2ùM èþ1qÍ{0ÏŸ–Y*‚ ‚Ä´Ç–å6ý¡ßÓ¾áÁJF»¦ ÿä™öƒO/aDÂe|º·¸ öÂWú£ð5Ø#f+?CŒÚôG2Ȇú “41˯™-Õmiš¦àa™w`Õ¢^¼yŽŒIŠÃ·/‚R*$*ÜõfZ1räù³oŸ¦æ!COËùæ´¡õCOøÁÃPã¶Í6]Þ|J½m] +•PåE÷“yeº/²$NÂf?%ÿïëê…OAém*ñY˨$é}˜Ê›¼`÷ØäS•<ʰ£ÓQ΂2=ÐZ«¼P +øÈRÿ¨eêìD!žX™>‡òa0k½;HÛí%e0¿rl¹kDû{šßl®}mÓÀyÙ_ZZ»´¤ÈáîŽTî¨í>e¾¿=¦þ?ocÖ¦endstream endobj -1256 0 obj << +1272 0 obj << /Type /Page -/Contents 1257 0 R -/Resources 1255 0 R +/Contents 1273 0 R +/Resources 1271 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1250 0 R +/Parent 1248 0 R >> endobj -1258 0 obj << -/D [1256 0 R /XYZ 85.0394 794.5015 null] +1274 0 obj << +/D [1272 0 R /XYZ 85.0394 794.5015 null] >> endobj -1255 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >> +1271 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1261 0 obj << -/Length 2305 +1277 0 obj << +/Length 2423 /Filter /FlateDecode >> stream -xÚ¥]sÛ¸ñÝ¿Bo¥gB„?1yòåœÔמÓ:¾éC’I)’8¡H…ã(½ûïÝÅ‚)ÓŽâØ\.»‹ýÅüóE±H -¹ˆeÀB‡‹l{æ-Ö°öúŒ[·'rÇT¿Üž=åÇ Éd$¢ÅíjÄ+a^’ðÅmþΉ˜`çÀÁs^¾¹~uõú›‹ó8pn¯Þ\Ÿ»"ôœWWÿ¼$èõÍÅï¿_Üœ»< ¹óòïÿº½¼¡¥ÈòøåêúWÂHz<ÀôæòÕåÍåõËËó·¿]ÞgŸ—{>äóÙ»Þ"‡cÿvæ1_&áâ^<Æ¥‹íYú, |¿Ç”goÏþ=0­š­³öã~$f ð‘E°ŠCÉ"_øÆ€ïÎÝÈóœmQ¹ÒÍÞÕÅV®ê¶KÕü‚ðÀ ÕåœÉ0éןe±«MP±ûˆ/ó{øxOšç….ê*-ÝUSoÝ´ÓZÙ«öcÝ|¬ê“åóÊÒl£žÊ¬I«xäêK‘Y&»To>VioN‡F5Z¸mñÍnCèc»SÙ¸Fgw›îv*wáj[Õìÿ4j¥š˜¬ËÎjóÞ =‚.èñ§}ƒ¿ âúÍõå°…Ÿpv•W­Ûå»ÑÑ)žN Æ'nmêZƒ×JµN1ܺ*÷´Òëõ5+»Ü²ýŸåN-‹ÖFï_½”SÝü¹S;¬×Oµ¼hÓe©Ü´\×M¡7[ë\À´¨&š$/&‡:F[Ýÿ:%k(@U…*üÀ ø “¬TiUTk·¨´j¾¤åüžþ|Âde¡*ݺ;Õ¸Æ7§–³ûÉûTNGÇjÁ«\¼ªHçCîiõUÿÙ¤w˜T'óSÛÞ»-X¸W⇪mÏêJ§™>mÿŒøou¥Ú›ÙÀ?p$ÌF¾Zºv¤œï;­Ò-AÝŽžë²^bú#|8¼èŸ³TvC«r‚–{zâǼÝvÛ‘Àmj‰±)¦•cJ=A™"Ç„!ª-¦ŽÁšêG‘“â#v жë®Iɺ¸†˜RQ(«!õŽ'Ž¢¨¢!&f %,‘’ß²1€^rlÙgÀ[†àe’5.Ë:ûDà]R(ˆUÂ-ÁàZFÃ#¢Ð­Y/bI(å4ŸrµJ»ÒÝ]Q–wÁÝÅîÍ͜ŜG Ÿ,Jbÿ9—ˆÜ1•s'fëgðÊ(U4*Ó5”ß#É2fQ$Kî‰f$ýÀ=±â‰©hÌסsW7Ÿ µÑ (dâê'wP/ƒ­WôÔý[¢áöWˆú‹Ê’V0š¤Ë¶.;miqºÄ’‡.Åè˜×ý($E©õ'‡\÷¢i¨“ý€Î ÓOª"TÚÒ“ÎRß/=QM+Ú$ B‡ãq9çæH’[!E9È´W– ë°­[M1 Ï.ÔÞuv‰Õö/¡§ØšQâLnDG—³¦«fr îapñ6Ǩ٠-p‹)/qN„fÏé'ÂÔ$Hçè&̪Z€CK§Q9d³H<ò&. Ñ4Ë  mcìÙÂÔM ýïŒ!üȇ»¡×q6g&ã8²{F@Ûòã(œ† E\ÀÕòᬠ¦ÞÁݦ0%@»Iô!Oë`‹Z£±p¸aö3#€Mfùmê®Ìiqi÷™škCÍ4tL§ •ðC†Þw -Õ˜êáB5P¡ÔOjï>X¬8YKï‰f¤OŠ•°úSñÿÙ˜Ôæp׃yFM*Xžtò=¤G‘Ñb·ËSSv65 Z•uCoã4‚µÏ¨‘s¹wÏa€ºµD`3îºeÙËÃI…ÎC%GžjŠ/¤Žh@E@$‡ €…¥¥\Õ]…iåÒ)VD—º¬¬J8- ©Þ˜ˆ½zÀa§4£òž*{ º/Ü—ã¸åPª$4ã‰tšó|?9Œ.¾¯‡öQZÍÕ5)™ˆe` Û•¦Tx€M—ˆ2ýžô‘×B˜VOã°ÕÞ"Ÿ¨ïÊSZ=;J‹ dâ0#OMz¤· u—E\ðiÛQ}]7éÛL W&H’áãfâHì%ǩӼ·j—6©žBü€…2”–t¤I1Í ž•R¹Ê_  -ÂÌ’»êªŒ>½z?ÞùÚ4N¢´ÕÙ‡P8½Ï§¹CÇdP¥„™'£ä;)1¢z$%z*Ó±˜¯Û6ÝnÖÀ©+]À•æ8=B0± ÂÇõ¨f™”õH@G† -9ÑÄT.=*ÒÆÂø–Q ê38ºˆš3‚ú°Ÿš³mME¿º"—ÌÔaÄÀÙ[‚HÈçNµÐÁÉiº0LøS§™ë·%VÀž×oߺ·o¯^Ú”®³ºÄÛ”ÎËC .íf{…ä?T³¤2^·´Òc¤+]…¹5\û’%}@4Ý:Éc“Í|O(ìõÇ<è,Gj`}nŠ*+vær Ö̸BR9˜‘ÙPå³Ï]Ñ·J¤ÒâÛ­÷Oî`í ¿¥ÓIÝñ½TøM©,÷Èä£çJgÏ?5Ë'.ç -*\˜ £¤‰Ø¹î%¸~õ—€F¶À×mf -Cˆu3 qþßê½Õ3™|…HX¾›Wíó™Óô_YìMÙX™Ù¤÷OÇ,ö’¾£`sšÄ¹=—©I3hÓ~²ØŽ®O} ?›)®A¢0îk«©êá7¢?ÞaH˶žp_gý.£þ˜4S`¼á ÓOÿfuøA›G’ˆùJ%bðXL¬Rx® º_¤í[÷Uÿ?žz}+?¹./uƒ# 4(~o’•4¢Ä`bI]a­O ‰†Žéôh¡âÂw|ßý‹B5¤z¼PõT(õ«ÜÙ+ÆBǽ§¥wDÒGÅŠsXõÅXüÖ:µÜõ`Þ„Q“ +–[ÙÒ#Oi±Ýf‰.;ëšLÛ¾·1ÁšWT‹È¹Ì=r -Øô¤ÛvQtòpR¡€sÑAѧêüžÔÜz{swwuI0“€}Al°°0»–U[bŠ _Xù’p ×’Š jˆÃ®¨µ pö1;ÚkVSµÏº‘ê0öŽòYŒãš‡ÜÚ´¢%ÝZƒJáû¾- –âØa¤KáME O¡ˆ¤+^¢oüˆ]'YV„Æ©‘Ûšš$´(³ öİÝ;G}ÈKªbðŽ-­s¾ƒû eÓb™Ð3«Á¨nÕ1î´]«Ë,u0ŽË™:Ì/Â7•ç8ƒ‰ òžÎó!ÕãyÞSõ½Æþ¾”õQ’»°…~RvOu,\ÄÃ4gPÙc˜]FÒi,"ÚOzÂL£ˆÃø‘JNµ8vx{Æn׊vP4Œ#Jð¤oª¸BOðÔ½Ü$åQØ1cZ5yóàžïðý•blÒ½!þÁ Œ³ÃÒ¡ÛѪN6˜#0`]ëËQÔ ެ[oÀ( དۤNÔä] +b§hä{Žû±!(BRtF³”2“ÙTëÑ[c—m™Ò—Ê\í†bkÑæ4}£”ÑÙgv8½8°\'Ú`Þ|,% ¢˜ÀÓ)1 z"%:*=6`ï[5M²Íí´†S—*‡àazø`âØóŸÖ£§šPdÔ 4”‘&z¾`±K=M[ßR*ÊbG·' Ñ,ƒ Úï§YFÃ¦í Œ©‘KªÛb¨Ö!DB¾µ²‡œ¹Ì^b\Jõm—™†ÉaÏû»;{~wýžÐ& T•V^†ãغÜ÷¨Âl67^@þCÖ jÄUCk>=ºRk`&Öpí>É ú~ƒhú °×)>4ÙD«ËMAǩ؋Õðñ£s^¦ùV cæ®h\gfÝT’îëFú­Í»É©Ôšø¶«Ãý£+k³ÃohAˆ¤¾õªëSõ&)ŠÝS7 +:Ük©Ò×_ë…]H%‹©‚ +Ëc^߈쀇ÖM'’ »C4°¾vh=‚iB¬›¾ÝwC¨Oœ{FÏhôÑ&r¼ÐFlV6¯§Ú©ù(e>,h+;æ›òñIÂРݨ«Æ(XŸ&²æç1·*Ò Å´ˆ|'^0ê.†_MW/r?ìj«®êào]¼;ž•0(Цh¤rû&cüím¢À¸ý¹Ÿþ‰oÿû'6(âӕЇà±˜¥ð\^t\¤ÍoǪÿ­!–5endstream endobj -1260 0 obj << +1276 0 obj << /Type /Page -/Contents 1261 0 R -/Resources 1259 0 R +/Contents 1277 0 R +/Resources 1275 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1250 0 R +/Parent 1248 0 R >> endobj -1262 0 obj << -/D [1260 0 R /XYZ 56.6929 794.5015 null] +1278 0 obj << +/D [1276 0 R /XYZ 56.6929 794.5015 null] >> endobj 350 0 obj << -/D [1260 0 R /XYZ 56.6929 418.3076 null] +/D [1276 0 R /XYZ 56.6929 418.3076 null] >> endobj -1263 0 obj << -/D [1260 0 R /XYZ 56.6929 386.0953 null] +1279 0 obj << +/D [1276 0 R /XYZ 56.6929 386.0953 null] >> endobj -1259 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F48 950 0 R >> +1275 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R /F48 955 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1266 0 obj << -/Length 3835 +1282 0 obj << +/Length 3842 /Filter /FlateDecode >> stream -xÚµZÝsÛ¸÷_á·ÊÓˆ!‚Ó'_ìä|½8i¬›¶sw”HYœH¤"RvÜ¿¾»ØR”|Ó›&“\,±Àb?~ H\†ðW\¦:U]&YèPèËÅæ"¼|„¾‚y¦–iêsý0»xû^%—YÅ2¾œ-½±Ò LSq9+~¼ûñúóìöËÕTêpWS‡“îîoˆ’Ñãݧû÷w~ùr}•D“Ùݧ{"¹}ûåöþÝíÕT¤ZÀ÷’G8ñÁû»Ÿo©õáËõÇ×_®~Ÿýtq;skñ×+B… ùvñëïáeËþé" T–êËgx ‘eòrsièH)KY_<\üà èõšOÇôé4Ð2Š/§* -ÒÆÕr„´6MtÄJ*§e)Æ´l¹PËÝ×òeZ4›¼ª‡+‘ -„—þ¨G²-ÓˆlåÉQ%Âg«òjªt:á ˜v¾Ý^‰IYeA„®á§å®óMÙR³Yâ3™äë5ÚU¾»éÄ~ ËcÖDz.wyGÉä¹êV¸â’””°a «33üûí¿™Ë_ŽL!“Œ™ðÏUi—€ŸÀž¥I„QZA¦µ4Ü‹uUÖØeOhªßöeÛµHÑôé`N‰"¦¯L) Â$¶Lå÷Å*¯Ë7`Óa<©XÞ&¡F³#qŽP7ÌÒnËEµ|¡n£r¤e[9½~ØâYÒXñt~%„@½ÈLLî–DÞÒ-¬þ )H„!˜w÷Dûœ%,[f›áéºzÛœ™m¦ŽçÊX´æ%i)òU)bˆ(¬&»qòÂ+_·ù®Q³=G©Nx€¿ŽÈ€V¦,ÃÀ¿£Ál­¢ƒ%«>Á*wÏU[²–T"ÎŒ„§%ewB)Ö’Š]=-i :XKÐ:¡%J뻼†ZVåwjÕcF;¢¡0‚v¦Ïj\#ûß4¤ãlrWÓä7MÛÑÊy[¶oȳqùÇN4 "CõŒŽ—A¬…]I»jökФL3T<9&!¡-wO%8$•¿´D²A ùPúb–×CR^[c·›^릞–ß«¶3†‰Œí~~*›¬«¯%†^oA¿IEr¡ÁÏÀpâ, RG${É KÓt*ò.Ÿç­ý¬a8EÈZUÝv»«t²_P¡á1ülu¢™BK³xSvu±`·„Yóq°"u,½šÄK„Î Ê5Ѱ:lQ.óýºsf7‚ 1¦ˆÌb[Tn1Ü`¥RÀŽ€éu %ŸÉŸÆnÄ©?¤1‡ÞìT$‰šslÖƒQ…{)ávÊKT@ÙðJŒñ¹Îx‰åB‰›rÓvyP¯Z´§Ü%Ž ŠgÙùY8®‘iô&†â;²?ÎW¡ç0ø†ƒÏÎv[‡ñˆÂËq>vUgr ´aq˜6L{ßæüÝaÁ¥Õ¶Š8Az@¢ƒ„’QÀƒtÂgÈ€k$}D¥õÑÉ-eÙøõ´…¨d”õbÝP=è•E³wõ·=( =B GI¿B=®3!ÔrU.ö;¬OÒHcâó3p\#SèÅ `G ¦@éVk?Ýj¶jxvWbb9œÍjëZ2.´¢öú¿íñø|W•®#ï¨å‚è è^ënýB$®÷HAD2È–b#B¦}{ ]“}»ÙŒ7ùyíŠ -è(¶)øsÝFŸ êÄ?ü¿!Ý´ ÎÍ)d»Sß“†­b¸¬™=a“qˆÆ7È’ 69;S³¸Ú!„òDQ¶‹]5÷òÃÀ\¥†áC‘AI…Ž N¥ÎÝã%5¾x–ëø§þǦ{<.ÎÿV\5µ½hŽ(CªZØ? EoFGä¸^™Çñh烤8K_©@}®3aÃrxÖÐW/T`M¤Óø¼TÇ5"V NQS%VO.G‹tòËÍç·³wŸéÅÌZ€ñ÷›9[C@ã%RÄ‚-±šc1$±í–Õ“I^H2ˆ>­ G½¹ O_wÍ¢Y³¬]îN‹ˆÔ+Zãà‹ñÀò½<’°u§­0#)éÎð’I³µ–N, ¯5(ñb‘Óñ}7öðIŸwnŽ—ßtê÷7x‹…Áow©‘Ø^Ò'ö™+&"¨í<ͺÂ~Ücðê'R{^{¸±I~Ñl6ûºZÐa´Íòýð¸næ9 ª?iäRÇ`)â•Ôès6rÇu¸½œåSµ8NŒ°[B¨ø¼xÇ5"¿÷Ò Ì¢¬?Ý‹#Ú“[ð{³¤'D`2Åí P¿øœ3#Õ††b9ܘ~y&p;¬jé¹ÝU›|W­™\—eaGå+|³A·ïð¥€ÌÒÁ­s³Å[0fsÙ*ä¤Ý/Vè<`-=ÍM‰i;Õmn‚kKwŸì‘ðn/6ðe¿-Œa›±%3ÿŠŸÝQgìT†sË+{y?í´t7&X›&_c °A‡&ˆ O€"èÝ]©˜·çUe $Š:xmƒoþFrþÔ|’Eâ+žˆ}æv -(5ªBOžˆoûjG!l gdÉìÃPý/óŠ[™dbï–¼Sl¯p÷°wŽÅƒe-¿¯ò}Û™ªU%|$—ØÐaìÄ–!À{ˆ Þ¦®÷,iê¨( "<æãØŸ·ü«ƒ¨“Qd‘ïY¬ÐAE$‡ªù 3ÚWeVQÖÿQŠ¡PeTs›–»¢G=„™Í Ã’]b®üj‹;ƒe$a µ-b\†i]þÕÔnÐ,M:Z@¡÷bOF`Ø*Ëð,+އµYÕU6ð.šwéqO–ED¾nÄÈÞõ/âL»ËwÝ~ËѼ²y¤ÌŸ6‡»[ÍG¹8À~ÞâO›jœ˜Pè麞cîpÏ&Ÿëtp\éìÊe¹Û•Åô-ñ( „ˆ Óóò×ÈúY@)Dÿþ è8[]&s—½j²Æ_}ðo÷²å+`´ðkb ŸŽÈÉ5üacª=ͲWËjRnðܪ°Dï´a0]ä•@¤—ÈÃ\ò¢àx -a7ÈÔðh ÍÈZWëh[äö §4×ÎÚ-D¶’‹öÙ©Š¼@,Þ`g]Z¥“8d m™zC‡÷ŸîoQ=§ÍLšK“WNè}®3ff¹ŒÏ7M¿.ŸMÍõìÐØ(›“$=? Ç52ž±¥ -ÂH&úó˜]!jØaÈ—+*…p±½fcX”*ü€nrnŠ›ÐŸ¸!V<Èìç›–ØQÅ]³%òº|*×ü¹ù©NËÙ3åX_P²²÷8 ?B ìÉäø!ˆÌ­Mm}s+¿/Öû‚÷}&°IPÂÖ…‚øñ@å?`Uò‚;×ò;¸âѱÁœ{7yQö{¼XÝ<—‡ØaÏ Ÿ=8Mò9©ZË$jòÀØé0É‘dNReß}p9RxË‘ˆ¶‹Ðа·¥Žœ^Am%gÃÞùxÓeè_Çèâ0Oªà£iR ä'œïÕÅý¿n>}¼¾»?­ïáÍSUØtÂqäÝýõÇÛᡨÚEóTö²Mi®ñÑøOJl¬ƒhü'ð÷åOÿöûðÃx>*Må‰s‚Ê™%vR¨Â(Î\+©LF¦þ_˜ Ìuendstream +xÚµZ_sÛ6÷§ðÛÉsC Î=¥±“º×:½X»›¶´H[œJ¤"RN|Ÿþv± ¤(¹sK&!¸XbÅþù- qÃ_qit«<¹Ìò$ұЗËÍE|ù}.óÌÓ<äúvqñæ½Ê.ó(Oez¹x Æ2QlŒ¸\”¿ÌÞ}÷ö§Åͧ«¹Ôñ,®æ:gßÞÞ]%§Ç»wïo?üüéíU–Ì·ïˆüéæýͧ›»w7Wsa´€ï%pâƒ÷·?ÜPëç·?þøöÓÕo‹ï/n~-ázE¬p!Ÿ/~ù-¾,aÙß_đʾü/q$ò\^n.­"(å(ë‹û‹øƒ^ûé”þm"-“ôrÌJ‰|ZËqkÐÚ³Y±^¡[»+afîcX³>UMµ+zêÈf_ê~…+)II Û§°:;ÿßü›¹ÂåÈ,2Ë™)"ÿ\Un øÉå\™,Êâ$-‰(×ZZî庮šì2Og4ÕÏûªë;¤hút4§LD‰ŽÍ+SÊ£8KSõu¹*š§ê°é8Õ,oS¼P£Ý‘8OhZfé¶Õ²~|¡n«r¤–UW{½Z~Øây¤±Ò3èüJz‘¹˜Ý>yKt°úoHA"ŽÁ¼³Ô)ˆŸö9ÏX¶ì6ÃÓw ¶9·ÛL_jk Ðz¨HKI¨J‘êH$¹`5¹½Hã˜^ãˆøº-vý„šè91:ãþ:!Z¹r #ÿ³É´Jv”A¬ú«Ü}©»Šµ¤2ˆFŒÌˆT¡ÜN(ÅZRé¡k %` -Ak Z'´céœ`W4°R˪úJ²~ªÁh'4'ÐÎõY käÿ›†tšÏnšü¦ízZÙ²èªîòl\þ±ÍUG‰€¡j$ÁV‡Âe”jáVÒ­Úý4)MŽjƒ'Ç$$tÕî¹G€¤ò—ŽH.¨! +@_ÌsëzH*bkÝvÓkÓ6óêkÝõÖ0‘±Û?†Êgëú÷Š ÃMoà=¿J™Er¡ÁÏ€!5¢çÈ^2Ê1Ó¹kîGœ‡CNÄ} L¨ü Ùm9Gˆcã°MF:ë8»?:²L»˜‡+ÇP,br0—¿´{j°Ð˾«›'Nö÷÷óÅýí‡oèµ_Õµž‹]]<¬ù‹Í [L)«_ãX6UÎÆ©Ž£<Ó¯¤ìëtÊö\‡Y¡Çû¬²(N“ó¢Ó„èaÆ–Q e(Ûfl Ñõº~D¢ªùwÕz½±öìB1²ì;Œ;Hz`Jï¾vÞ‚˜Þ‘æò3QÃÐ…½”ÇeΉÛòPôîœ4ÚÔܸ.K€X<ôø37ÂIiPb$=Ž "[Nó 9Ä+˜´ãúu£4²) R03¶7hY@Ϻ-J¦¸!¶û‡u½ä𒉻ú™TTV´­ +!tS¶U:Js˜Û0^€Ö[½1ÖØÌ¿´»ß½³” –}»óÞºFñ[.ƒ‰Q²ÂM§òœãh +¤•Ç8éu:O£4ɲó^rö:Ïe¡B±\UsÒÖ‘ßÁ¦§ƒ/&ÏqMˆx˜m*ãl(áC“{ZàeÕðÑoRÛ¬{sݲÖÚÞE¿3ÚK¡PzE{×í9.Æ÷›íIåå‘I_‘í˜&dU—D&‘#á ‡‡¶E¿rp)=†K<¿xUHÄUt£Ê¢/ŠÎ}Ö2À¢ZZuÓõ»+3Û/©ô˜J~v-‰:Q’Ì!­™{×í& Š ÇAúØÕ½Í-ІÅaÚ°í}W<ñw‡ó8- kè X¸ÓMb*$‘„¦k3â?i}ßÿœ=Ç †<Í9â]™ªuŒívÂ`¿‰Q¯LÈuÚ`<JÜÖå)3à-XüYÙžkBø°êU‘éPøÂ…È0¬ò‘ŒÊôVÍTXͼ• Ö”4(a—eÕ1áöš9¬3iÍ;l$³cv^¥ñAœßy|™Üù$ƪԟ ¼! K$ÖX¹šovûæµú?‚­˜*†l'& ê×êWÒ4~²‹Êž„DÌïH#üŒ-ÄÏØÃ:yÚæéWEO}_ +¬-­%JW5ü}W?5źóÝ yjLJ/Òè™ÍYMC¸Â$3´Û:Àfè—"™ÝÓ‘²N fˆD™†:"[¬ ÊÝÉÊ[ÔF—u‡Ø¸£OxŠ *ˆ(˜ððÌÒ­Vñý (Áê0s"{é@©\;H™FJd£GSí+[éH†ß¶ñBG]¶pç:ªˆ¦¢ž3Ô‡'éMûŒ䎥Ӷ…Š8Az@¢­ƒÄ’QÀƒt§È€k$}`œ‚<:…¢¥<¶a…í ªU³\·TeFÙî}‰ýy +èN‡PÌËÑó!4à:B—ÅQÕr¿ÃÚñT Mt9&=?Ï51…A<€bZ©Ñ(Ýj¦[ÍV ÏþJ̇·Yíü@ëCÆ…6CÔAÿç=¨ïêÊw=µ‚c==ÐkÓ¯_ˆÄõ)ˆHÙRlÄcI3´‡ÚµÙ·u›Íx“Ÿ'Юˆ¡€NR—‚0×oÔô)¡ÎÂSÂÿÒ5hpnNUêÏO6¤©ÈdòùN¶ç²8èU$‰'<1lÜÙ)x®‰9 Ï‹R€ì©N‚2]œ„Þ,FˆÙD‘àó´=Ñcà,¶[Hgw˜Ñ~ÑÒ“«.`W]SÉO[uë¾›N\s<'KâQÀ#{T)Mb +& ¤® ßk®ø !üvˆTlЯ¨ë€TRuÂAÓ"CK<5À÷*Ë|>hHKSãƒì ÂÏhêØ—µpçl¶ p”+!%l +v©öqäp‡@vÈeÕ-wõC%F+5 ‹JJ0¶”®C©s÷tIOízþyøÁ±í‹ó¿‡×mã. “ŠÑ£ÚV@Çb0£#ò\¯Ìãx´ó¡#N#€mœ×™Ðá¸,Hkéîk-°2Ò&=/ÕsMˆU£³T£ ÐÈåhaf?_ÿôfñî'z±³ ýýæ‚«$ qˆaG¬öp Il»UýlS’,n£O›ÒS¯ïîéSFÙ}»l×,kWø3ã%â5@ŒÎøøb:²ü ›dlÝf¦æ%%ýI^6k·ÎÀÌÌÑðºƒÒ/–:=߃cŸ÷§çx)Ngƒ·TX7bð—™ë%}bŸ½z""`‚ÆÍÓ®+_‚°a:u§¶‡k—ê—íf³oê%I»\? Oëö¡à!Aõ'\j ¥çk×(!×i#÷\‡[ÍyY=×ËãÜ»%„JÏ‹÷\ò‡¨ÏDqžäà ,è¾ÑޚܒßÛGzB&Sܾõ‹Ïf¤ +ÑR‡3,Ò$nƃÕ=·»zSìê5“›ª*ݨ|µo7èþæÃ>øÌŒn£Û-ÞÝ€1ÛKX!gÝ~¹BçóèèiïKl Ü©é +\;ºe„€7x½/ûmi-Û„¨”­˜ù?PuèŽ:g§²œ[X¹Kýù”AÛì‹\Â¥CÉ×l`б "ÂÁ z÷+öí˪¶‹…,ÈE¼¼Á·p#9j>Ï"ñ5OÄ= 7‹Uq âPÄç}½£6’3X²}8ƒ-jnd’™»a +Î"°½ÂÝÃÞ,!kõuUì»ÞÖ®*ヹ̅†ìig®ÞClÌð–u½gI“PG%Y”àÙ0ÊÀþ¼á_#L@%‰C^¼{d±BGy’ŒªäƒÎh_e’;m$ùðÇ*–BÕ~’Såm[þêõç.'Œ w‰¹nôkŠ îŒ–‘ő֮”ñ¤õÅï¶‚ƒfeÓÑ#z/÷d–Í£²O´Òt\¡Õ}íï²mp—žödYDäKGŒìýð:ζûb×ï·ÍkwGÚ Àøi{¸ÁÕ| ‹ì:üÉSà +=]ý‹Š)åù$rNžË"]õXívU9BK<Ê1âBs^¾çš˜À0 èÈ%†3 Cm9v™Ü_ùªÙ Â7½ýË–/‚ÑÂßý¤DÎÞÂ6f º3-wÁ¬fÕO¯JG ÎlpÐõD^ Dúщ<Ì¥(Kާv£\ÈÐŒœuu!€v@áŽ{*{à  ÛBd«¸t_œªË‡Äá vÖGg£t‡ ¤-[oèøîãÝ ªç´™ ¨Ù“ü53 ¸Î˜™ã²>ß¶=xüºz²~6·—´ccËL¤³ÌœŸ…皘ÆÀØŒ‚0’‹á<WˆvXò‹2Î!¶7l ËjC…ÐmÎ5¸ É[b̓,~¸îˆUÜ·["¯«çjÍŸÛŸðtœ= Ç +ü‚’•»ÍÉ øjdO6ÇAdáljš[õu¹Þ—¼ßè3‘O‚RI·×÷Tþ£Ö øs0|©¾‚+Þt‡—2:¤8L$*ø¨Cڹà çÛ‡2¹û×õÇßÞÞ„.ôðö¹.]:á8òîîí7'ÂCYwËö¹d!—Ò|¢é–¸YGøcí Ÿ„¼/ú7á‡ÌðQÆœpn,šÌ37)Ta’g®„ +#³‰©ÿîÑbendstream endobj -1265 0 obj << +1281 0 obj << /Type /Page -/Contents 1266 0 R -/Resources 1264 0 R +/Contents 1282 0 R +/Resources 1280 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1250 0 R -/Annots [ 1268 0 R ] +/Parent 1285 0 R +/Annots [ 1284 0 R ] >> endobj -1268 0 obj << +1284 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [250.9056 343.4991 314.5963 352.9087] +/Rect [250.9056 335.8063 314.5963 345.2159] /Subtype /Link /A << /S /GoTo /D (statsfile) >> >> endobj -1267 0 obj << -/D [1265 0 R /XYZ 85.0394 794.5015 null] +1283 0 obj << +/D [1281 0 R /XYZ 85.0394 794.5015 null] >> endobj -1264 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +1280 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1272 0 obj << +1289 0 obj << /Length 3458 /Filter /FlateDecode >> @@ -4758,67 +4834,69 @@ xÚ¥]s o ]‘T&0ç_â:ót»`³¹W[lcXÓQ&’Êö^òˆ›w\NóÖt66<ªÅ©î€DLÑ0¼%_Žœ)EÜ™ïþµà‰ÎaÍ/«Ù’šÈ.µ¬ ákMŽ”L‚ÂßÃnÍyàØi 'ß1_l8›S k/²Ž£"×ãÕ¥ØT›+ XŠ 3%HØuç‘ÒV1› ƒ£KS͸x×ç#“$ʵ”ŒÅñvE6l•³™Y£@r—‹w4`«Z¸ê„Ô¼„†÷ÂÜÑMÇ"‰À—9.Û±M³à7mõY‹EÖÖ"cBÈ2*’1Ädû’s›Œ#!ë§Sб(%…¡¹é ’»* ¢—ˆÊØ1“M´$­è(T\_AøÐÍïa4 ³mæ»fևǡ´?ú5 S4œ‡rM±0ëåÚnÆYé,Ußÿ¤î'Mà­„áæ,ÈÌKMe^@œAúƒ:)eê‹éN_L¥ú±mkSrvü³·#†/Ö2Šã$;møB¬ã†ÏcY±oûå´ù̇¶oðâ #1yzy5²þ0n•‘` 1y¢Š¯0zw“’XòMBýäØã0†tÛYˆËË1º:J3oDœw¯œŸuUt¦´§Å¨ž˜e®å23hžL3 Øë]ÙŸV£ÀI¤r½—F“M×jàn÷ ÷¸Ò –¢$ÍœBüÎ7Uc€¹(!ÄŽæöÄ.Á¾ç:;ނýà¤m¼¦R¨e†>³eÙ<Z2(AÿAK[F3aÿ¥Ý2 oœ ³íÈ„¡'¬‘| H™”ØóH­«Í]ÙçÌÛEÿÌä^ˆVÁ ³äœ³1û‘É.|éýÀˆÔðUHëäÔõh€Ž5´øÂ=°NÜs‡eíA70>m›©ù\õ‡I*šÛBæÁc01¬ƒØz‰rÁ50,Á®Ù[a&OÎØ@ÅC»CM(¨Ý-5MÃ5WöeWòqx¶fÕR­QBòR~r‹3uƒ-=HZˆj#ü„Œ‡*Åï•'µ|­÷êá~(„JwOn¶m6ÀÖj•µêƒÔ`± —:­!Öq}ðXÖ™fª®¯f‡%10‚™*ŠÓË{¬‘õª'Q–€D ü‚O¾*ù)òƒ'k ºo¶ïŽ›Kž‚A‡=ÿBíE!0øð2F é"s1À@S&7ÄÏ+wum°Wˆò7¥ØÈxgd«Q# !A¥q¬‡áÛ¸±U‘R>îÝ6µéX¾›®ÂÇ—©}·÷"2¬Aì4§íjåõµ®ü[†»šœl féžbª]Rw¸=pQnþbÿãÚ¯  Ù¬aˆuBû•1Ëû½eu ™ÈO/ëF– wXÈl‡.;ëÀ%ÂÖ·¥Jô¨‡$ WŒ»_X {#îh̾©áV½¬#Í~„Ë~²s½ž·Ö²ºÉŒ»taaÓ;aFÞ½s¤ Œ‚F‡37VË(} ¢Cf/t"Ó$MQ ?a¼¤c§¥G0hØ*M -)­¸}\ö4àæãû1~Å¢pÑç@|ôX5pçqCˆ<£á 런Ţ7Ž]Ùr›W–ü‚#›~,¯1Œ3ëí#±ÂDŠ/+1 [–/¿µ"Ä>ŒYt[Î’)>´Î` ×|¤{–ÌÃ(¾ÇHÐèZ‡KÑŠêUHØV½ ±´6¦iŸü`µrl/Ä—öîÇ\fié+ê¶vAl¤_XÕõJ¼4å¦õœ:Jc–7‰tªÜÝ`3O–íÚ,¶÷Bw¾Ý°çw5iË7f°Oëã!ÀdÞÝoä¤Û®×ìÏ;ãbîBCÌ'CýäwÆàñØ›PŸ´>'Aå­@ùÁãÞÑØ¹cv5Î “Ìõׇæ\²‰ó’©$> Þ¦G²‡® ÿÖãŒä~%Ž´*\bì#ŸBs,æ€D\Ðï ð»ç¡5¹¶^#¬¤âÇÄ-òT™çNâ4’B§‚ŒnJ'>:·4BBøLäOV¯ø·Ì«s‡À>»CÜHOßö‰ Wib|?É0RõhÃï'¡=Öíƒ×ÿAý(ä*ÿŠóH2=<èØOç’4Âß»¸6áèÿþYÝî7‡*­ãq' ©m¤4a¦}¥£þýÝ!ëÿf ^‚endstream +)­¸}\ö4àæãû1~Å¢pÑç@|ôX5pçqCˆ<£á 런Ţ7Ž]Ùr›W–ü‚#›~,¯1Œ3ëí#±ÂDŠ/+1 [–/¿µ"Ä>ŒYt[Î’)>´Î` ×|¤{–ÌÃ(¾ÇHÐèZ‡KÑŠêUHØV½ ±´6¦iŸü`µrl/Ä—öîÇ\fié+ê¶vAl¤_XÕõJ¼4å¦õœ:Jc–7‰tªÜÝ`3O–íÚ,¶÷Bw¾Ý°çw5iË7f°Oëã!ÀdÞÝoä¤Û®×ìÏ;ãbîBCÌ'CýäwÆàñØ›PŸ´>'Aå­@ùÁãÞÑØ¹cv5Î “Ìõׇæ\²‰ó’©$> Þ¦G²‡® ÿÖãŒä~%Ž´*\bì#ŸBs,æ€D\Ðï ð»ç¡5¹¶^#¬¤âÇÄ-òT™çNâ4’B§‚ŒnJ'>:·4BBøLäOV¯ø·Ì«s‡À>»CÜHOßö‰ Wib|?É0RõhÃï'¡=Öíƒ×ÿAý(ä*ÿŠóH2=<èØOç’4Âß»¸6áèÿþYÝî7‡*­ãq' ©m¤4a¦ýTFüû»CÖÿdÙ^{endstream endobj -1271 0 obj << +1288 0 obj << /Type /Page -/Contents 1272 0 R -/Resources 1270 0 R +/Contents 1289 0 R +/Resources 1287 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1250 0 R +/Parent 1285 0 R >> endobj -1273 0 obj << -/D [1271 0 R /XYZ 56.6929 794.5015 null] +1290 0 obj << +/D [1288 0 R /XYZ 56.6929 794.5015 null] >> endobj 354 0 obj << -/D [1271 0 R /XYZ 56.6929 333.8409 null] +/D [1288 0 R /XYZ 56.6929 333.8409 null] >> endobj -1070 0 obj << -/D [1271 0 R /XYZ 56.6929 308.7186 null] +1075 0 obj << +/D [1288 0 R /XYZ 56.6929 308.7186 null] >> endobj -1270 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F48 950 0 R >> +1287 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F48 955 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1276 0 obj << +1293 0 obj << /Length 3312 /Filter /FlateDecode >> stream -xÚÍ]sã¶ñÝ¿Bo•fŽ ñE—‹}u¦çkg:i’Z¢,6©ˆ”}î¯ï.° A‰’®éÍôÆãá -\»‹ýØ$?6Ñ*N„‘“ÌÈX%LM曫dòïÞ_1‰¼½ŸýöðýÕõCÇKÈ/K2òÇÕ/¿%“°ýýU £Õä~$13†O6WR‰XI!üÈúêÇ«º ƒ·öÓ1ù)¡c¥y6"@.²`™N2eâTÀ+àír ­¦íªpÀ¿ëŠ ²qÏÜ=6yÓ»éÍ,’Ìà‡ÕÁM±{ö˜/åzíG«…ƒê};˜ùîãÃíÍÏÞ͘ž싆pÚšpý<ý2ëü¹hp @c±QŠ[¦~MT²(–ù~ÝÈ`SS™LV–#e¦ÍªÞ¯‘ØêvW>=Yjñ‡’@ÀL™¯\í7u¾*æ¿»éÊêàkK™‘”­eª~.eõä†Ë–0÷Ûm½kG¹pbAœÎê;þ²‹!@‹Ù±Ú=Aúåò`iz<ÇB/«r]Ì2¯«ª˜·e]¹ß(*»(Œ= AÁP‚~Í¢u@½ô¸åMGÆ€gª°ê|åü†‡ zМóœhxìik×ëbAï^q Ðpj¸a±ÈKãŠUÝ¢^h l-M¡å —csÅBeÒ㬛::9Ÿ41W2#ÜØrq«H­A -Yl×½ñ”“à mÈJž9>X·¯0Rïܳi÷ýWoTd€ƒ9½"ì ÐNºæÌ«i>pÃOûuN_ýʹì)Ûo ¿vÏEÞˆA¸ ân‚hL—´æŠ49ͦ`Þ»²hÜ¿êjýê m±[Ö»ûDôBœÚ±‘-ãŒÇ~Ð>¬Š|×>y•x®g°âã­Ó2N¯ ŧmIÔºuJZ/_,J² \½vOôhh´Ý)ú^>TúPÓ×ÖĤݸ)+ë]¸ UžÐ(@£ sUÏhvôÕ=÷ ôÍÔ¡6gYÌSyÙ2 è,|™„&‹»ÍA¹nØ9n€7 UùSѼ]—†Ð®î”s -lD¹Î -, äkV/¨Æ™NÕ%)ì™`€‹*vÎJ¾fA2Ä—ñZ³Ì\ˆê'öYî+ äk¶H•d–^ôÿ‚Ç:¥ª²é?/¶³†ô¥äÖ·²þ 3Y (JÀIZÐS;ê­ üƒë‹¤'¨™>ßZ“¸´Ô¿©Û®ËÒg)}öÖ†‡Y{Ø ¦œx‰HËbÞží‚p(‘  öNyر^ÀÖê,Óa×bÐËñ(Í —ÖÀ›9Ñ»%¤(Ä:Ö\ßí°lc ÿ½ˆJ,9ŽÒ6&tÌR“_¼ÃY}˜ ³Tl¸ú-óQ³XË©ÆÒÃHØ-+ylTn©è‡·E…å½hÊÍ~·n«|O±êǦ^vßaø»»à˜´íë–ÞÞþðÓõý RÙŸgŒ1Ø€=jj¨@1Zâ ^ª -×ßÁ:¦ö5L0Ÿë¨‘uuzo“4fI’^ØÛëÌÞz,»·E;_EOë}q¼µ | -¹ÑÙµ;¬‘Å[+liÈ ®î:½<Õýb3ÇÑaS3N`˜ía@í)µð=Œ€A¨Ž’Y$TøBa÷Þ~3Ï÷Õ XƒZoYЫÓÔXÒÓ¼m‹Í¶ »MÚ­H½¦4‹µ0Cp´p£©`jê½æƒÑymŸØÀAìCãsQ.ª¿¼r}G€¨áм®šv7ÓÓýœ´Þxðí1ëÙp¶¼ÍÔt=eøa›ÅÆLó™[˜ºˆÇ:‡´WøÒµ„›rQ¸)Èæäsú ïó¾™`£“¡QC*Û“#ä&½à C¬ÓÓa¹-ûfaÓµ‰ê*jVûvQ¿T‡”pÍ\rsž”k„–A ³á€8$æîLGj‰ ÈEóMÑëÀ‹âSÙ6îÕb_¸1Ò°¢|vçðîÇÛ÷×÷Þ8bÒ½ªi¦EM+`˜ ±¬ª /Ó|¨yõJa“:°‡»²-šÃC *;éùc—” ÙÕÍgöäÐ=0§F²>Ë)ʉ… W$:–2»à”C¬3:æ±l‡..Ö‹h¾.‹ª=Jú DÆ‚³tX# ˜…"²+6$Î಴óÌ¿ä4XÎØ´EšÔÚž3Žo¶ëbDÛ~7ЗΠÂè-:N°(~Χªîü<Â"¯‡Ÿ<$Ôzú03 šN÷$Tñ Óòî¹¾{ßµ¶<«EAmÖ¢KÔÜop|#ÊÆQ.]š6²9*e¸LöˆŠÙã?'&4 Ÿ6ÛbnÏ$·/µo -oó]ÞÒ°Û—QëØ}e^ó}»ŠªO‹z“—cÁ•A‚}p 2N6ObÉ;»;w çcén9ç Y¦SlLXP!u²:Õ"“Rù^r ñ­È'’CÁJqÁñ‡X§²Ã²û^7mÔ´§5m9?6J f¤Syž€k„‚¡QÂV¤Y6$Áf@ŠÑѦŠùT —þR€ü½(¶äv³iÀƒEZÚSKüôÙ%¿"³Ã’ˆõGÐbh*Ÿlò9‘G’Ç gÙÁ™IÙ®ÈÛßùbià2ì@u”œÞm–Ätçw;À:³Û )E[iá?*?¹†vô˜7Ç92˜ºIåy2<Ò1†A@†¬èð©•ì3d€Ý˜è«˜‘ŒVÇ*KLÃ"ÁÙô¶uß[?Žå¹8%Mí¥e–[ÃÝU•a7¥ ÝSNPˆû‘»G»Ë«TüvG꺦sW¦8R$4ÂR"¨ªÍ£rúÀm5wñµÃ¦¬0øO—<à5‘žŽÁŠK #“–Gˆ+Ä ÷ð[I åîáiu„ÂjL¦)Û„_Û*}°(šýv9veâµÞû4Õk±¿âAÇWt cß>Õ}ßàˆ¿ArÔoþ¤mߌž¥§&‡â»Û^_)œÚŽœËAÞžïžL~Ø¥äË,c’ ~6Ä:my–µ¼²*7ù:ÚQÅqìi3 ‚òy:¬†85æƒ"n—#Â3sêô3ººÊüÅ¥|ÐèØÎ7&T:¨±‡BþV^Ö_ÓÂ/èŒAUç€ãÊðœ"Óå{:Ñ7Â~ÂëT¹]Õ”ãÌê»zL°aá(¸/ó…cãÆ‰Aa£…ŸÄ‘å†ýÝŠ²¯…»™RÄOÖÆÐÓ¬‹'Û±ª/˜þ¶Õ®àCY¹{cg‹ÒMþÚ…ºáux«Š.²äÕ¼Þ—êoo¹M ?s±\({‰’_ æ`P/úó„3f`1;eÍX(!Gs[AG: ÃÕy:¬ -̦i,2¡‡$ÐŽ™ Ÿ°‹&õ± -†JzE® íP¬®ånàè”ýZ,Ê_Œêð}'Eubp˜ïîÞ~¸vÆU’äXM…:vlp\8ê8Ÿ>—µëê¹a«QÜßå‚×täx[ ì,§9¬ t)¼¯CT/ù`¡|ý’¿6~Ž]éÊ0|STËšzJÍÁª=KÉ!/zºï2ÇǺ] Ó1­a(¸y‡Ú5m¯ ÙrNÑj‹—ÏšøÔÍ[¡b¼.;¢EÉäâ×çÞÊí¯,C‰(´>q/B$¸É¼½¿úíáû‹ë‡ž—_‘(dä‹_~K.gÀö÷I¬¬Ñ—/ð#‰…µòru‘jëT)?²¼øñâ‡~Âà­ûtL~Z™X™Pª@€"8Í.smãLÁ+àíü*RFOºEIÀ¿›š¡ª¥gAUÑvåf‡ôæ*J…Åë½)Úróì1_ªåÒÖ3‚šm7˜ùîãÃíÍÏo®„™”lË–qº†qý<»e–ÅsÙâ€"!b«µtLýšèdV΋í²PÀ¦fi2yX8Ž´´‹f»Db`«»Mõôä¨ÅnnX +3U±$¸Þ®=êtQN§éªzïkGHÊÚ1Õî¾zƒ fÌé a2@7!è™WÛî}@ÃOÛeÁ_ý*eº£l»fü†ž³¢+ƒqAÅi‚hLç¼æ‚59Ë'`Þ›ªléŠßM½|%h]næÍfE?€H†^˜S76²eRÈ8…¼‹²ØteÑEU žë¬øpëL'‰×„òÓºbjiŠ×+f³ŠmWoè‰ í‘·;Cß+‡JjzàÚÚ¸—T 7Uí¼‹´¡ÊóhJ¡a.ªòÍÁ¾ÒsÛ2Aßܤ&Ôæ%B³L¥=MJ5BË €ÙH@ó:ÓQŠ[b +rÑbUöç:ð¢üTu-½šmKc +«g:ç€w?Þ¾¸¾ÿð†˜IzÕðL³†WÀ0b9U·@_näP1Šú•Ã&w`÷86UW¶û‡\÷5ÒóÇ.©Pi_7ŸØ“}÷ LœÙT첬‘¢œY8pUbâ4ÍÏ8å넎y,ס+€‹å,š.«²î’>‘±Å„à$=Öf¡‚ìJ Ià3¸<ë=3Â/VWbRƒ‹bMê\ÏÇWëe¹¢]¿øK2h„0z§ '8?çSÝô~a‘×ýÏ-3y¸² š¤{)TñÓòîQß}×u¶<ëYÉmÖ²OÔè78¾e“(—>MÙœ=ƒ2Ü(‘öˆŠ¹ã?'&4‰œ´ërêÎ$w/o +¯‹MÑñ0í˨u¤Ø}^‹m·ˆêO³fUTcÁU@‚½w 2N¶LâTövwê@ÎÇÒÍ|*A³"L§Ä˜° Bêeu¬E–¦Ú÷’+ˆoe1;j” +î,UgˆuÜ({,·ïMÛEmyZÛUÓC£LÁŒL–ž& Ç¡`h”°YžIpAtt©°>ˆÒ_¿—åšÝ®à#`1 xpHswj‰Ÿ>Sò 2;,‰ÄîC Oås"€ÝaB1å#ò(•q"E¾wfRu ööw¾X¸ 7PäÇw[$qŽÝéݰNì¶ÇBJÑV:øªOÔÐŽ‹ö0GS·Yzš tHd†¡GP!ë=:|j•î2d€iLíª˜‘ŒÖÄ:OlÃ"%Åä¶£ïG€ó\œ’§öR‡2‹Ö » +)DeØßUE¡;Å”bC? +zt›¢nAÀo÷¤.>wZ"EjO#%©Uuy4@¤ÜÖSЍ.e…ÁRò€×D®ðt Vœyêx„¸Â ª¥‡ßJ^¨ ‡§•…$Ô˜Ls¶ ¿Ö Tú`Q<ûí|ìÊÄk³õiª×bѝøƶ{jv}ƒþÉQǼù“¶m;z–žÙŠï¬7x}¥$µ9—ƒ¼)<ß=šüˆsÉ–YÖ&gülˆuÜòz,gyU]­Še´áŠãÐÓæ@!åÓ$ôX#4 qÌDÜÎG„g!ç4Ùg„u„uû‹Zû:  'бoLèlPcµ„ÂþV^Ö_ÓÂ/øŒAUGÀaåx¤ˆÁtÅ–Oôm +awÂKªÜ-HÊqfHõ©SbX8*é G%|áØÒ83¨\´ð“Y4ìïVT»ŠPÑÍ”2~r6†žfY>¹~ˆS}¥Á¬ð·«v•ÊŠî,JWÅkjø†×þ­*¾ÈRÔÓrx_jw{‹6ýÌÙre 8ìA%:ý5‡€zÑŸ'œ0»ë„Ùy,gvÀB‘8šº +ò0Ò‰XY©OÐcP0`6Ëb•+3$wÌý<€)BØÌÇ*ªø»z€ ¡8]·šnà1HÎ~ç/V÷ø¾“¢{1æ»»·®ÉX JJ%VS¡ŽœTD”“窡® ;’þ. PÓQâm1°³‚çp6Чxð¼OP¿ƒ…ŠåKñÚú96•aø¦¬ç ÷”Ú½Uw,%û¼˜É¶Ï›n1LÇüµR„¡à–=jß´™½‚d«)G«5^>kãc7o•Žñºìˆ%—g¸>÷VîîÊ2”ˆÊ˜#÷"T1@ÚÜ…âÐâà¬Å_ß=$ý?¯ûÿ×endstream endobj -1275 0 obj << +1292 0 obj << /Type /Page -/Contents 1276 0 R -/Resources 1274 0 R +/Contents 1293 0 R +/Resources 1291 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1280 0 R +/Parent 1285 0 R >> endobj -1277 0 obj << -/D [1275 0 R /XYZ 85.0394 794.5015 null] +1294 0 obj << +/D [1292 0 R /XYZ 85.0394 794.5015 null] >> endobj -1278 0 obj << -/D [1275 0 R /XYZ 85.0394 625.316 null] +1295 0 obj << +/D [1292 0 R /XYZ 85.0394 625.316 null] >> endobj -1279 0 obj << -/D [1275 0 R /XYZ 85.0394 613.3608 null] +1296 0 obj << +/D [1292 0 R /XYZ 85.0394 613.3608 null] >> endobj -1274 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R /F39 895 0 R >> +1291 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R /F39 900 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1283 0 obj << +1299 0 obj << /Length 3798 /Filter /FlateDecode >> @@ -4843,1011 +4921,1010 @@ tc . ÐìËë:ß–s©î' 1¿%õŸ2ÅdŸª Í"DBÓÛè1û‹ð'¶<ÆûZ Ô‚ Û=«I ŒP'Øc;®kJ2Ã!ÿ9®k¨#º¡¨ìo¦uC= ÐÇ©·Päûº¦™õÖÕ¥ÿ÷èÚpC]olÖ5ëÀ‰ÞFéZ„?±å1Þ×êšÂßð˜çÞB`cŒí¸®qPM—˜ºÖ:¢k )6Û"k9UGY½¨7Y>þ±¡L! JÅq6Z¨ >zJ§43’›>#¡ Å>€ñs&ÃÏ8t¸…™Ð*€‘£‡/àù”}-ÂŒ×_Í÷•+N†Ë©†^ól»-éò_‹þ-¼caú›”šXè^¼†àÇyû3¢ ƒÐ,+Œö0õ#欉Nø¥òõ˜m³|nr ZãûÀ†nŽm²¿Ì®é—0õìo0誄®Íé•Î×}3Všì.ÜÞx’ÍþZÎ…Ÿ<ÀÚ}–—+ükøxUeËp5cé‚&©ºÆÕR´?Ld…?_]þØ}ªíiê¾#\¡iØHÑþÞ ÞŠ5^˜.„žLgáyuKO¿5x~ørCƒ'»C÷n~À£ %óô =ï*ì“ã(p £Cç/,µ_yþë©ßLA–leçüãv–q?oÃÌ!6¬aʶåìkµ°¿“®þMûðj«±l†M†uñ¼*ד?çëuûrüñl±|/–ƒ 4Õo,ÖU¸g‡~ª¯ Íâ¡ ãmOþ/ÿŒÿ´eÊ9y8i§Td -åcø8 -p&±÷4fýÿK€ä?endstream +åcä8 +p&±÷4fýÿKØäAendstream endobj -1282 0 obj << +1298 0 obj << /Type /Page -/Contents 1283 0 R -/Resources 1281 0 R +/Contents 1299 0 R +/Resources 1297 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1280 0 R -/Annots [ 1285 0 R 1286 0 R 1287 0 R 1288 0 R 1289 0 R 1290 0 R ] +/Parent 1285 0 R +/Annots [ 1301 0 R 1302 0 R 1303 0 R 1304 0 R 1305 0 R 1306 0 R ] >> endobj -1285 0 obj << +1301 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.2681 743.8714 203.5396 755.9311] /Subtype /Link /A << /S /GoTo /D (notify) >> >> endobj -1286 0 obj << +1302 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [80.6033 237.2629 144.294 246.4782] /Subtype /Link /A << /S /GoTo /D (statsfile) >> >> endobj -1287 0 obj << +1303 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [265.4578 191.3384 326.6578 203.3981] /Subtype /Link /A << /S /GoTo /D (server_statement_definition_and_usage) >> >> endobj -1288 0 obj << +1304 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [367.5441 191.3384 416.2908 203.3981] /Subtype /Link /A << /S /GoTo /D (incremental_zone_transfers) >> >> endobj -1289 0 obj << +1305 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [280.9692 160.0192 342.1692 172.0789] /Subtype /Link /A << /S /GoTo /D (server_statement_definition_and_usage) >> >> endobj -1290 0 obj << +1306 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [277.6219 128.7 338.8219 140.7596] /Subtype /Link /A << /S /GoTo /D (server_statement_definition_and_usage) >> >> endobj -1284 0 obj << -/D [1282 0 R /XYZ 56.6929 794.5015 null] +1300 0 obj << +/D [1298 0 R /XYZ 56.6929 794.5015 null] >> endobj -1281 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F62 1060 0 R /F39 895 0 R /F14 737 0 R >> -/XObject << /Im2 1049 0 R >> +1297 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R /F62 1065 0 R /F39 900 0 R /F14 741 0 R >> +/XObject << /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1294 0 obj << -/Length 3853 +1310 0 obj << +/Length 3850 /Filter /FlateDecode >> stream -xÚ¥Ërã6òî¯ðm媈!‚£3ñd'µ™ÌÎ8•­Jr %ÈâE*"ióõÛ/€¤L{vkíFh4ú ©ËþÕen£ØÉeV$‘•½Ü.âË{ûáB ÎÚ#­§XßÝ^|ûÖd—ET¤:½¼ÝMÖÊ£8ÏÕåíö·Õ›¿_¸½ùxµÖ6^¥ÑÕÚ¦ñê»wï¿gHÁŸ7?¿ûî‡_>^_eÉêöÝÏïüñæíÍÇ›÷on®Ö*· -ækYá… oßýã†[?|¼þé§ëWÜþxqsÎ2=¯Š äÏ‹ßþˆ/·pì/âȹ½|„N©¢Ð—‡‹ÄšÈ&ÆxH}ñéâŸaÁÉ(M]â_bóÈê$½\r¢s³Ìå8Š-pm%*Š3£—µZâ²ÇB.—ÛmÕWmSÖëÝ©=¬Ë¡ßÃŒ8Ú”›½;g‹Î³(Ö±¾œîýŒÂ€µ@¢™¨ űJç4Þî]ç®Ö@ûª="Ew6mÓŸ®T¾jk˜U¿´;·/ªö$“vü-ùÂÛSÕ—}õ@º!­F+ÖòÆ;=8X$Ññêqïl)X¦{t§ª¹ç?è¸ÎcU›=7'#yd[ö%ð8Iͪ=[=^íÚºnÃêoÞ_ÿtã÷ݱ±'’õä{ÆÀÛì˪颀Âc Æú•60J¯îÚ~Ï-â |{á¯Rþ¼$æ:ît®ì×ÿöm’O.Neq¤MŒŽ»=?i~» -°œßcó…Á¢[·+‡º˜’½á°Ü`ÂËO ©„¼;G\bl¼¢V¦íX02>¬åž élÎÀ©0¬uRÐý0C‘Æ’µ.·Íïq¬ï‡°!ŽW 0†ÆéPbñÁ3}s62•iÎŒ„@žÞñX?1ü±ªe;7 -,Žu]…Rˆß|5tÄ7ɾù…p”{˜+ "+:mdñéü\0Ù °¼‰µ«w úö £]Õ¥O«:¡µ[:ÏÐl]WÊ»ÚGMlVÝ€êfcUÒL#š„: 0ðÒ¯oãN‚Ó>ð9'ÇOººF6@‚ˆ ÏMûØÌ=É(¸Šáí„"ƒú$Ë3 ¦í¹Q…922* IŒØ3|r}¦‰írf(ˆÑ©ƒ –Wf¡p¦#“s˜M»$ I¤HXe[uèu:Þ@l¬>šãlà¦>¸ŽaÁ¾!… ¹p‚N­«feÄ™­€±¢)¹bCžF©^`Û–1^©Ä„qÔqÇûë%Ûããmc&ñ tÆxÐ ½kHR°GdccèÂ8~çÁ6Ø%·æ³ãøIô¢–½(By¢™a–Y=TîqãNÎ~Ý÷îpìñ„Ú²Q×)®Ø»Cz.*N¢Ì˜×…ÂDyìËc…ò.«—àHeãÛT»'×…] ééÉm†SÇ,²¸)ä€Üû\oyS³qK¾u€!›0 ºoÚ ÌÑ£™—…ãöX±VبÛ{ˆ?,O Ç -Ð9€õ+ïÝbâñé5n$y”«ÔgË 'Dºú…ÛPY¤RåÍc¹h²æØXO56ñZ fY¢%¶žŒÌvë©ñ˱^&¢— ȬšœT¤6*²|ÎFÖW“"ëÚÏÃuÈB˜†ò‚P–lqÄŠƒˆÉ9 €1.B çH©×_,[€QLMzJ© U²úÐ &RÐ’#$bLSSxý%¥ZRCŽ]DÒ(L#íi¼ó<”öIÍ ¿%B–ÄèûÝà–¬g¶ägØñ4åA­âÝ&6|âM¼ý$[}ª ‰;Ãô§E¢5ó#ÅcÊ LyÁ:œ NJ© Öò,s ù_j…‚dLa°ÍvÚxkbEJJ\°E܇ï$ôbÀœâdN±€Èn<·©Fé(/ ýªQ5/Õu˜?»½=Å‚6‡Cº!?Ç)(&“3|È:Ë-†…©’¸#U -Ÿ}tÇ–½J.‰WáÓx€„jÏì÷Œðñæí/Ÿn¾Ά&î}^–‹ÚBã’-kžf¹ÜÃAÌLÇ…ÍïÇ´0ðž¬ÒÔÞÉÆñÏa´¶jµ§3‹òÌa¬õI°“ѳڳx!a²Ø~¥ -<Åz¹ -°8³è7ûõ¡<Ýv) PÁ©ò¬ÖÇQš'Åët¬Bæéˆ…4âš%ïvKÕE,.¦¯Ö!(ŒÎÆœÓä”ZgÍÙØlõîÃC"çä¤<4Ëä lsf`¡ÑŠçèŒÄ¤¬y^Ì…¯®:´±BcÇ2nb-þÁ~h²E‰'Å(RŽ `Á2°Ì–&«›ìKÀäT1!®ã°…» fsÝWOhÎn¨—, jF{§k‡›€äU3|áf÷àÐQE)eõèc{úÌ-ÖNò©ÏŸÏîÔ¸šÛ¨>‚-¾Z¤Ò] áÖí›2Ü6 ×Rë;Þ¼(Îháë³#ØãÎt'y‘‹¤¤ª6wäRôXY•%J¤çuíæ3%õV‹wÊ¢F“Æ«rÄ!ËçäÙ].ÂËGš‘,uÜÄàî¾!q†çaiæ%Zäcp¨¬j€ÖDŸ -öú–i&94Øg^ˆrd‹5Û‹uG½‹ÏVÇátlý:çÕ\åsêM;œ qؾhñ@Š"È¿bñ¦X/[¼€…›W_ØÍ³SÜV;ì€8pÏ Ÿ‚g¯“°è™™* (‰õœž_ƒ3ŸY>] /6_{VI -’(z8±™Ø°T!*`Ý–QX*!"¤qÜÇHŽïÖÊÍH‡ÔZ–`ÕÁÁI 𪗅 Aì`å‰Ö ¯Ž#NúS_5swATmžŒÐ‘˜ðt†*%&Û0fß0­—øðXm)ŒÍŠ#ÿŽð°bbyFÍx¶’ÈDЛ¿È -@îÐRÞmðÎÝpðžãù>‰·/\ÚHÒ‚Þ -ƒ«PôƒJª kÐ/éºQÒ;l½Ã—4ׯt¸`-…ʵë¹`ͨ)ôšÛb£éypòÜiõ¸õ\—i[ÊägH\ $™eD²9 jÈÁI! |&|NýËq*Ä&ŠóLñy–ÐP Â]Õpd2NWDüi…àH%°ðì_ă“¼/`†ÝÆZQ±p&-o>_ -ïèîplOå©ò%'T± A.:²„M§ì[ÿH'ú@E(¾W)0=ãµ/gõÑB2=×õ¯ gž¹È#ȳ}¹X*ÄE&Ae·°Ÿµ‘Õ6 >¤Ï6&2EšN\þB¥Bùçv‘ ÁCé8< -‘E.2ÿÌQ±}öÒŸMêÃЩ݃«¥-¿}Á¦„ëωZãc¢†ÞüòÿgÆfQži!Ú_¾ˆs“iò]²ØÇ†E”©pC/ó[G…Ný†þ©nÎnå©M¾Æn;}cðoþcIàˆY Õ$•Rh ŠWïúyI´eöÈ©Eä4/FÒ*V‘ -_¤§X/GÒ‹˜»Vë‘u³À91Qšçù뻬…íçOry”f±šï/Å 0<¡”jùé„c ù]´žÚqöòã Åg8Ö¾Ggéfrœª¦!s vn|â;ËðjG‚ÚÊ»-¾é$j®綉r_ ¾7{°Õô‹B-WHð‡“6Mþ‹Éø,¿`}"£ÂCV[·Ë¶'³úì9 -Èä*X–ÉSQ–y–gÞždøwªJ?a8Ü_ ÝÎÇŒÛt¿¸0¿!šh4€F£ßPtÂt™ Ôy|æq`ÂÈ\—‡«ðúƾ»ŠgíÖS¬o®¾~¯Óë<È•\?ì&keA˜eÑõÃö—Õ»ïo?>Ü}ºY+®’àfm’põÍý‡o’óçÝÞß÷Ó§Û›4^=ÜÿøÁŸîÞß}ºûðîîfe&‚ùJVxeÂûûÝqë»O·?üpûéæ·‡^Ý=ø³LÏ…òûÕ/¿…×[8ö?¯Â@癹>C' ¢Ë2Þ C§i{nT~ŽŒL…Šhö Ÿmߣi¢C»ƒ\xq +bT¢Æ FA€å•Y$œª@gÀfEÓ.IB¨òFÙVzŽ7[«q&ÂÅ8k¸©/#®e˜·oHaC.œ SëªXq`f+`@¬hBn†Ø%!/°m˯TbÂ8Hê¸ãüõÜöÄù,ÞÖzBg 5’ÑÛ†D{D76†Îãwlƒa²k><‰£D7jØ"”'êyäágéÕSeÏ“wrøÛ¾·‡cGT†­ºJ8r%ÀÞüÐK¡ˆÂ8Hµ~[*0 óæ\¡ÀËêxRÙðhËj÷,òº° 45=Ùr8uñÁ"‹›B˜ÂÅÏË‚˜[òµÌKÙ„ÕcÓzd>ˆ"eȼô"ÕLj¹ÂFÝ> +Dbqj8X€ÎÌ_ñh…éó[܈³ ‹—,'œêªWn#Jƒ(‰œ},J'kŽÕTec§†Ð`–ÅJ‚ëÉÈl·^·+f,Š ‚̺ÉYEb‚<½ÐDVX ëÚ/ÃuÈ@œ†ò‚P–lqÈŠƒˆÉI €10B 'I‰S`,[€ULtzJ¹ U²úÐ è'RÔì³#$bLŽSxý%¥ZRC^DÒ(NCíiÀó2–vYÍ ¿eB†Äèúݰ,aœÛ’§a×Óñ)žÈHò@ÍZ¨BÕ{²t"@àQ|ß7@ ™%k¢c+œ ëd?çÓ6Rwïþ„¦£ýƒ[tp\±yžP·]b:Zo4‹:#ó­U8 @°ç9vÐ901pŽçÂG!äCïìéTÔ?4"+£,-­me[ŸÌ`‡$fŠ;ÝñŠ”à-J²J ÞŒÂnÅ«4=÷iç8±áRhâ% ìÇéêsiܦS9%"­˜ &S^`Ê †@ØaepRÅrNäHešË!ÀåH9³Ç-ô̰褺âT¤O)È(/ÓW°vNÈCçP0Ž’}(i¹ð¾ªàèx%šwºÂ‘hV!ÀÊÕзCÉ›{­<·§/ŒÎâÎÙ9ŽüùbO­âVŒ-¥FãK}´µÅªDÑË`ìLÅAˆp,Õ]¬Òð‰Ñ"?¼ûèlvÓp …’ˆ<;B¦¿cdN„ÈOœÀkî$áÈÅóQ'3ÊÒ©l†ÐvæB´È ¶º¶ü‚™LÏ]©§jÊûH®– ÏxIT{‹3ã·0ãCo¹=+zÙÃ1+™‚1ÝcÓòÕè!çæŽO!Wüæ1¡5…ŒïÛ³}â¸ò«%o’§Akd£ Þ.z ‡7/EP<„æ«j^à]p71îfÖƒHQœEº: +1!Ëìªncé–…{Œ!(Ûá©ÉöU“ª xOó4Û¤N±^7© ^ýÁq{ÝmµÃˆŸ?ó²F°S¬Âômr<Ö=3[Å¡šÓó³f¦Uåèìõ_½ÜĹöi½Í˜TÂP}ö°n +Y U)ÒØ3÷1T¤;B(Åy#Ò¡s KˆÊšé³«^&1¯IÅJ]TñáÃrHÂe…ÄælEbˆ#0yÐÉ(‘猫ÔãÈtñÍ3à S #x«y +.a\N(αºÉ±xHF@‡XÔ…Å˵v˹žOIµ×ùˆÆZf!ã:rä=!eQ—C]ôÎP~õƒ>³#_bÌA{IÖ̤†uôYs,åì™ eÝ>>ò›š”cW"Œ ±ñÿ ŠÍÕ1è¸;Á¶„’±q^e\!ÆÒæÑÊe!ld}ºœCÕ÷Žr„ðÝBºÒ±Ÿ´ÅAöA‘èxbÑ-G›Î¨]ˆÄ¼@7‰Eþ F(‹þe{/Wõ‚¦&‚ÖI·åïF†Ùáàç;°¼}_•ŒFÏRLiÿ<‡:ål-j†pfo@šÖKŒ8W[ÊPCMO9øeᄆ¼Ñ¡¼Ô‡z<[!~Q¯Þ}üIVhr°‡–2ChC$Ð !kaŸØ®žÄINAb(û^'£ëÜKEì‡+6¼âa‡’âàHùVâ(Ç<ֶ犃ѣªÐ‹ l‹¦çÁÉ“ªQãÖse¦m©V0Câš§'I/+%"ÑY°1¸íf_Wýi9ÜcÅ™ì4frDØT )ÝÄqEAÄ_o¸ ÒE—ÂÞñÕÝ[8É,=¦ßm,Gå gRò.â22ÿVoÇöTœ*WÕB+É +r]“%l:eߺ‡À1öp÷ꢎK^»ŠY,X󇿿Œ.\sžÉ»ÔHŠÐy*Ál·°Ÿ1Q&ñJ¤/Ö:Ðy’L|þB1b•ºœ‹}äBô*ôOd’óÔ=¥§TÏŸýš ” ¡SCtZK[~^ƒÍ1Q¸ j– +zóËÿÛŒMƒ,UB´»|÷ØküËô¾`±» ó ü ½Îoä*qºçÀ9»£ KLüWì6Óg ÷»‚±èpÄŒ‰ªž“û¾ŸGÎ-³GN-* ¿Òy5”†“*é·#é Òë´C"ŽÁ–ÕzäÛ,lŽudYöæÖéåÞó¿,HÒ0šm.É3˜_hJ”ü0#3 ùÕ ´žÛqöòÓŽˆp¬]ÒÍžû"2¯ð{ç-Üø€ÍSHùº” ¶ò*ŒFqtñqa•òãîrVš~9ñbõ•i’¿W~Y°;Žü+Öki$þÖÀ¨‹·. “+li*ïPiêXž:K’âKß©*Ü„á°!¾@»#ŽÉ¶é~qa®ã𼄬#°•¡_vØ5Ò¯B^žOÅ` ýÃÞŒ³Ø°Nî:œÚÝeÖ+zç5tá÷w`cCÈŒÞ|»a`”àµß·jHõ¢"…~‰ÿû·¯ãƒã4ÐY¦–UR‡Ý±wD!áF_Rn@Þ ø¡ÒÿªZÁªendstream endobj -1293 0 obj << +1309 0 obj << /Type /Page -/Contents 1294 0 R -/Resources 1292 0 R +/Contents 1310 0 R +/Resources 1308 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1280 0 R +/Parent 1285 0 R >> endobj -1295 0 obj << -/D [1293 0 R /XYZ 85.0394 794.5015 null] +1311 0 obj << +/D [1309 0 R /XYZ 85.0394 794.5015 null] >> endobj -1292 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F41 935 0 R >> +1308 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1298 0 obj << +1314 0 obj << /Length 3366 /Filter /FlateDecode >> stream -xÚÅZÝsÛ6÷_áGy&B‰/|t§çN㤶{×™¶ŒDٜȤ*RqÜ¿þv± Š” )¹væâ™\,°‹ÅûJž'ð'Ïm*Ò\åçYn„M¤=Ÿ=%çÐ÷Ùdži`š¹¾¿?ûî­ÎÎs‘§*=¿_ ær"qNžßÏ›¤B‰ ˜!™¼~óöú‡_n//23¹¿~s1U6™¼½þéŠZ?Ü^¾{wy{1•ÎÊÉë]~¸¿º¥®”çøþúæ Qrz˜ôöêíÕíÕÍë«‹?î<»ºï×2\¯L4.äϳßþHÎç°ìÏ¡sgÏŸá%2ÏÕùÓ™±ZX£u ,ÏîÎ~î'ôú¡1ûë„U&=Ÿj#È[YŠLJ`Êl.R­toe%cV\håyݶålZÖÅÇe¹»f©á29ßsEäë|©¬pV«±W$yªœš¼¹¹»»zMív³Z5ëŽ^ªUÛYTF˜l’ø‰ê⩜3ÛP¬NDž܈ à`’tòK½,Û–%•,¥kh¸qƒá©Ö暇¿”mD„ÌD®Uñ*¢«:ËO)ª…K”a®åcñ¹d ~V ~²Æó&pÔM‡SP”ª©”"·Vù¹¶¶„“‘½Ü?–Ô˜—‹b³d–ªB0·KÓ¯°„ë½{ˆ©™L2‰<ç×8®œ?Ëj^tUSïAZ§"WàˆŽªÐsEt-×€•XïH‰i­³ÒØhåßã¨ÑéW€eÕ6““›¦+#S°T–`íø™ÓLØ~âbÙ6¤l]–ó–š“>òýâŽ}Ü"È œSƤ<‚p%Fé * -B<~d–‹ é&‹rÖUŸKX³–߆`•Cx1ÿ€Ó £€;ŽßÓaø¦ÁÖ³Y¹ê¦å—Uµ¦Í!FªÌ¹£:ôLûJŒV›J¡R€íP‹K/wTN¼htÐɤ­ê¢Û­%¦çDz¦ÞÏåºZ¼TõulÁ/w"`!TûÍÃÞ~óð%ºyBˆ4MÒ±g«›Ø2C6'we×yÅÝcÕR«YÑyôT†ÛïJ@>ˆ°,½+ŽV0s–$ú´g7ήϛe]®9ê Ä’iVËâ…Þ‹®+fŸÚÃÔRhÈN€pÀu… üsS®_–Íîà<©uùqÁ)"x´G‰©IÔXòݪœ€`ý&AXuå^tN:4{ zûØl–sêðni]±îÊy?KÌÍ*N1OäéÓ. .ÃOŒØÕB\/b®Ö “¦zCCîL âµíýŒG#(‹Qœ–†˜r@à[ì¸Ïê÷$QåüUÀsY÷-jƒÙ¡ÁÈ3²»ìÊõSU{;¡}Ù™`ÅGµ¬gLi;,£‰gEW>4 3bH¢œîÝ:ªVE½/˜;à ñ„÷µÒbAê(ò‡\‡‘ßs¡ÄÙc9û4E0´{nWBgÔ á=WDú8†¬6z,þÞ»%mòÞ-iÞ1¤mZï„Ùc …w¨[W³Ž{¼C…®Ùc±.f¤SˆzQϩѾÔ]ñ…zqcý rÝ‹7OÔ†²iS3,!¨+cÆîø©hI¤N'Ð%…ˆÅ~×pDj°ú«¦n‘f%Ä÷9QžÔ<Ñ­uÙ=7ëO¾ºs!ޤÃ8’B¾åaF -ÌfŸiÎÑ)ålömt°6mñ€ðÎÀ“6øLMÞÂûØÎ(lSËeD‘ éGH«þjjŸ¸gá0eƒˆÔ*m*ÊØà²EµŒ?+L.‰¡†¹ãª+8myXÛ%¹XJf!#JÝ?¨ùs±®c‚À#ÑÜ )êö¹\· ¾NMnÕ}cð OÚ‚gä·<í›D«K…Ÿ yøšqså¾€N ¦“;⢙éH™[ÿ™R³ŽnE¥]ž Ýã9LšsM°äsP_KÇ®…§ -Œâ&Uª' oN /ˇbI´Ç¦íø€c÷HB€y¹ž‚O÷€''kÃËÀÚÀwûö5‘aŸxd͌ܥ'NIÊ“?5ój:>–ŠÍŠánªhhH ؉˜5ÛdÇ»ïÖ=P7ã->«Õ’œGfÈßfš½šçÚ»9 ׈Ô=/_Q×%ü# -y] ½û• UvI˜R¤NN®;â⪠nÕЬ†ñjø­*,ü¶ÊlP›Ä§ÖNnßÐÕþwI$àáys÷Šwï/¹õîWnÐ&bßí…µ“ÓËþz´³~=~Œ_ÊR\Ï…œÐ’ðÝç¾§µŠøé÷xÃgöDñG†© ÓCƒ7›hjUõ¼Âìe˜‹Ž;“g-†¡Öiy‚eÓ|Ú¬XÂbĽ¡¯ÙÑ%‚uæÇ‚·žsºVq~w}3½|óæV\Þ~¸È•‡š'HwIþ¤s×õÍ=ú¥ƒ •Ñ)ä¹'ò©Óát*0mÏÛÓ—½:"‡3 Åæ1©g_긊0àû@‘¡Ø×(×®%„ÕÁÓ!Äç9D€–źåÍqÑOÄä‚×øu>çŒÆã_æánB#€æ \÷·%ãTÙ&"ß^j~u¨iïýR)>B¦Ýnv¶jÚ¶êËÎÏÅrS2º‚ODnH'Lgr(çÈÀÀ„"O!vÙLÿ!.Xk‘*s¢ör†lϵÅìsµœÏŠõþÝ‹J…¢ñ¨øÀ?2¾H#ùT(m¶7Ð4*”f eÆ`‡&ÅvhÔM=¥â·x ðz¶Î91 Nš”%.ŽçrÔä"sP¸ŽÕÏ ìŠ®0Ž=ûÃ6D²åsñ¾¿å×ÀB>8tFàÝ«ºÇݦw芗ÏM ”å>(©pÆ¡1\1QžŠnöHÕªW jÕª{|"è˜1ˆ™hCÎ?Ç„-Á«#X—iðZô—“¸´<ßCÐéÓæ~†’¶^^¤¡Jg"ÍÔñ;K#r£óq -SE½±ò¼Ç -4=V°og¯¡k„•b*‘J»“hÑ}JÛnØ©ô@·¦>||áˆ@Z¨Oßב㸶Ƿª»òv÷eÿüByžØãòSDþøü&B¹TøP®Á¶U :\gÈxšbN4Dµ¶Zz¯zK]þÜÃ3@û„pרKÇv” ‰ P}„ƒ'Ÿ Ù'kt„H]êÆ0ßK£ð&vø´V|ñ/‡‘ŽÞKjR•/}òKPÄ‘ÑÙ)+ÖAql=,7%Ø“¢üRµ<” ­±&Á⦣û¼Ýܪ?ˆ`ª-]Jær› Ûܨû &p4õò…º«zÊ{ -äa-…ö> úüVyÿ =h±Eßlºi³è§ÉÓD–°icbp"¥ÞgN½D?ë¾ÓpþË•8 ü$˜¶J"'xM£’ÈÞa'¯ºÃrø±\6ÏDíš3.ˆÀ‹ƒÖÖ(‰z¶FÁ£xØæNäRçcØé6Ùú#‘¿“„’RÖ3.ûãíCv4òû÷ yúËÔøI -ãäW8ù“¦ Z™©üë°gí¹†ÉütæË“½ÏªJ˜–pT~ÏQ`ìZ3a²ÜŒ5ˆ^¸çª$¤‹ï¿33Úf£kw8ü îÑ„Ç+:>§sÊçÕg¯ýɶì?Ò¸§`¯ì쨌p\ûùõÍ廫;¾ÍÁϿκø¡> E ¥E–*ýmuÄ!P%VXrT®#  -\Û kן¢ê¸üÀ‘Á”+pSÚ¸oì¢B*u ©4R€T¦¤€H÷qn )¶@й+ 2®únÂJlˆ¼‡++wóöÿ3®dª„KsWC®Ã¸ê¹¸‚bþ½/9NÈD©ãâ{®ˆüñ—-ñb¤Àh×M:YQBH…‡ÉFYŸá¤ }E}|O­ª›Þ1¬Ç“9ÈÙç@”†â¨ÛæhÐÑ)”rÒ}Kmqx'¡˜Ís}j'\Gv2pù|­\7Óº™¶M1íºå~B¯„5VW çŠh0ÞË ÂIšUཔ!í6PÜ@éçw¨Å¦{ÄZ²À_¥ ?0<ôor÷;’üÅ_%¼¿$Bø&ê©ä<í‘'¼¿ÿ‰(>’áãpÊê­ÈU&eõÃßà*Â…zµûñ8,‰³¦q³û+‰¿è†µùölGAŠ¥¬û'pçr¡´}ÏÂaÊ!©U,Ú8Å“ .kQTËXð³Âärj˜;®º‚Ó–gµ]B‹%fò¢Ôýƒš?ë:&<²Qͽ¢nŸËuËàK¡:ÎíŽOƒ}Ò<#¿ÅàáhŸØ$Zc*(ÿ\ÈÆ×ŒÓ˜+÷e|pZ0ÜÍOG°ÔÜúGÈ”šut+r•y6tç0iÎ5ÁÂÏ"Š= ÊNØÄM6þªTOÞš@^–Å’hMÛñùÆï þ„øò$ò< +îGNƆ‡±ïöík"Ã6ñÈš¹KOœ’,”'jæÕt|*[£Ý8RÑ4Р±j22ÉŽoß­} vÆ› .~V«%¹ŽÌ·Í4û 4ϵwr@ Ž© ú½|E]—ð(äsôîW"0PÙ!aB‘:9¹îˆ‹+/¸UC³Æ«á7>¨<2TðÚ*³A9lŸY;¹}C×_øß%‘|x‡ß›»WÔ¸{É­w¿rƒöûn/¬ü›ö×£õëñcüzT–âz.ä„–„Ï>ó=­UÄK¸Ç[>³'šˆÏ˜62JM˜¼qØDÛP«ªçæ.óÀ\tÜ~yÖb(*–'X6ͧ͊%,F¼álÑzš]"Pg~,zë9'kgw×7ÓË7onÅå퇋\y¨yò‡t—ä:w]ßÜ£W:˜Ne ÷s4rN§z®í‘{ú²WHäÂYÈyŽ +LÁãB€û]F’_£d´€”VŸLGÇø!À´,Ö-h†Œ‹~"&ôsýçsÎjü)y¸¥ÐÃ( 9 ×ý½É8]¶‰È·×›_.AÚ{¿TŠ‘P‰i·›¡­š¶­úÒós±Ü”Œ±àØ#ÑR +ÓßžÊ;2A00¡ŸˆÄTˆ_6ÓÿC˜‹ÁVgNäRGí€é0hÓ³ÏÕr>+Öû÷/*ªÆc²Ͼ쑽´„íÒP8J›í½´ +¥}@™1Ì¡I¡uSO©´ó(¼˜­sN Ã’&e‰‹cã¹5¹È”­#Lõs»bl+ŒcOàþ° ‘lù\¼€ïoù1°Ð:ðìU ÝÆ#nÓ;tŎßM å>(©pº¡1\1QžŠnöHµªW *Õª{|"è˜1›ˆ™hCÎ_É„ +-Á‹#XiðXô”¸´<ß–BÐ铿~†’¶þ$¡Jg"ÍÔñ{K#r£óqú SE½±ò¼Ç +4=V°og¯¡k„•`*‘J»“hÑ}BÛnØôƒ L}øàJ˜0w'^i ¹ŽÝÀµ=»UÝ•°»/û‡ŠóÄ—˜"òÇÇ7Ê¥z¬À‡r ¶õ¨JÐÕzù%(âÈèì”ë 8¶–›’FìɈNQ~©ZJÖX’`mÓÑmÞîiî"X‡*K—’¹\ÆæÂ6·ê~‚ M½|¡îªžòžyXJᄽς>¿UÞCZlä7›nÚ,úi²Á4‘ôpÓÆB4DßDJ3¼Íœz‰~Ö}§áüÛ+;pøZ07l•DNð’F%‘½ÃN^?t‡åñc¹lž‰Ú5+f\­­Q90 +ôl‚Fñ°Å×lRçû¹rH_‚?"ùI(Ø e=㊱?.Ð>dG# C±ϧßN¯¤0N~…“?ùr +¢5ÞŸÈä‡\‡=kÏ5Ìä§3_žì½ZUÂä°„£ò{®ˆcך “åf¬Aôº=V%!QŒxÿ™ÑÐ6]ºÃùã¯l¸Ef¯è@øì›Î)ŸWŸ·ö'Û²ÿHãž‚½²³£Âqí ä×7—ï®îø._;ëôå¡^E ¥E–*ýmÄPÉ\ ¥Ü‰D{ÈuT=×vÃÚõ磨:.?0EäG0¥Ç +À”6î[ »(‡JC*ͤ€ •é) ÒuœC +†m#tîã +ˆŒ«¾›p…"ïáÊÊݼýÿ+(&re³¸pÁUàà +Ê\Lø÷Þã8!¥Ž‹ï¹"òÇïq´HÄ‹‘ÿ¡]7édE !&e}†“‚öõñ=´BªnzÿİOæ dŸQfŠ  nw˜£AG§PÊI÷-µÅá„Âüê‰o"†\Gv2pù|­\7Óº™¶M1íºå~B¯„5VW çŠh0ÞË ÂIšUཔ!í6PÜ@éçw¨Å¦{ÄZ²À/S„¯ú'¹û– IþŒâ7 ï/‰Þˆz*9d{ä ïï"ŠO§dxµœ²z ðË䱬~ø•®"ܧW»¯ŽÃ’8kjñ«›Ýo$þ¢ÖæÛ³)–²îŸÀ]– •¥'Ó€éÈ—‘ÌÝtVÌ÷ƒ“MDf!I9¦CÏ´¯Äø•™> endobj -1299 0 obj << -/D [1297 0 R /XYZ 56.6929 794.5015 null] +1315 0 obj << +/D [1313 0 R /XYZ 56.6929 794.5015 null] >> endobj -1296 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R >> +1312 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1302 0 obj << +1318 0 obj << /Length 3178 /Filter /FlateDecode >> stream -xÚ¥ZÝsÛ8Ï_á·Ufj­ø¥Çn›ö²½íöœtnvv÷A¶e[YÊZrr¹¿þ¤%YNæî¦Ó’AºbÁ1KM©LÏ’L‡&f¶Ú_E³-Œ}¾Ì3wLó>×O÷W?~RÉ, ³XƳûMo­4ŒÒTÌî׿þöþÛýÍâz.MÄáõÜÄQðÓí×Dɨùðë×O·Ÿ¿/Þ_':¸¿ýõ+‘7Ÿn7_?Ü\ÏEjÌ—¼Â… Ÿnÿ~C½Ï‹÷¿üò~qýçýÏW7÷þ,ýóŠHáAþºúýÏh¶†cÿ|…*KÍì>¢Pd™œí¯´Q¡ÑJ9Juuwõ¿`oÔNÒŸ6ih¤Žgs¥Ã4†5&µ…‘­Í“…±’ÊkYŠ)-;.ÔòñqwÅ|µ+Vó‡öa|l›0±˜õ×>“ÀsMˆ z"ˆ$ -“,ÉðÏ]Qƒîe®EÛ¢.yWÖ[ ª(èv /w·Ÿ["nšªjž‰†r¢~ÿö‘.ö¦¿à_Ç¢íx­fÀß«#ñùßM]¼Ã!X• :fó8 -ÁˆÀŒ…3c¤•š¤ÊLðåî vtðG©|KĦ¦Ös}üz÷åæ7b\,x°¡v]tÅa_Ö —7·l©÷P¼ÐP»kŽÕšˆK^ùØku뱋‘V}¡=R4<Ë=í¤Ìé *­ÜÖ )iÍ€•½òà3?}ÄAÝtDõâbÁK.›nG½ç’zq×ë©9vL%(9¤ÞýŽwX›üXñ. +œkdñÎ(#)á¸xÊ—Â1 lR‡™V)ó„g~ÏΕD:Ô—üôä=®W<ÐqY;:¼Ì»ÕãüPlE»;s@ø ._ÀsMH08¬1¡HpEÁ,LR¢ )€AºË 5  ¢î±ƒ~B|ÇÖú ï?|£ÚŽ}ÿÈpÀC Ú·›¼¬à.c!ƒO`W–F¸ŽsR"¬šý#@À²¬ÊîåZ€[ª$¶"X§Ôp’8ÚñÉ$`¥i“P¡qüßZÄh•yªBƒ¶UšÔŒaŒð„œ(ŠðlÏùaÚ9ßüOÆa)ç¨Í(TÃI¨ó5©52 ¯iÁr¬òšÈKžBî{uÈB—f¿s®há-SÛpÿ¹\4ºÊWNˆ†wÈY¦â™g‡§âÐâE­ë㊅«9ä$†ÈÕf(¤70XuTeýÐR×J­² ø€`WD­ó}A=ÞÃw’·QI ÐÉ«¶¡Þ’'€B®E°î­nÙ ZP÷dŒ8é…vç]xÒ.çmÖ<Ý¢vvùS1… ë’ô±B>™ùjU´-õ­ 2eïÂmG-:Ô¤Žƒå±#†çÒ:šŸ’UÓq&@á¶ _ò:à îŽç]¹ÚQ—‚Œq×å=ж  “aÍCÙg?1?¡¾AUcv«ìáòyÝ>ûåkn;žhmø"‚Cöþg²×¼ÏuÁ=ꉜv}†ÜR„&Ùë{®‰ xa ¤‹ƒ­)p«LÍcWZÇÍDàitÁ@Ùy 6°9V4b:s€„ð­*1kê/Hn„bÿØy[K þ¾'úS^yÅfC¸§ûúS1ž6chÝ”Øáe¦©ç/Ñèø#¨-‡ØÂÐÉ[ É[(€Vó±ãM3¦0‡-öˈo¬ ¤!¦l‰R&Ô#ë)äÑ"93¡=×?tŽÍ¶¿MKáÒÞM;r¥æ$uª ªŠ¨åÌÐ#ˆÀQòËÔœæúma¼¤¨6p]Zèàvêr¤0a"½Þ­õL\N&:ÖÌd]¥|,V%*©Xãdê­mbÔx}x9Én¯YjêD«¡Z†wsÑ×u¦Â4I^wõÓeOwL=GG£û:Ög âkû:žó}~®Àø!•l|çµk gCàe·ßˆ¯×œªµž§!ª„¯J&FéÚ>÷níS6Å0Ø™ ÀÒ(°÷Gd¢š÷ÝPÑ0çë´>=ºÍÞæ0S„îæ!3‚m.2ȲRb3) %Ø¡${ö°8ÔÔ¨¯íñT¸H®Ê¤Íl°y¤òe¾nöyÉC˼-ÛwTæ½Ó°Ö¤s/èl«f‰ žÉG˜Üò¬fÊÍ­¼±²©Ñ¡\¯­W€Yq€žSó”Cøµê†±fCD÷˜aÖüÛ5"î‘è¤`l‹Ž(ù¡+WGÌí7¸%.‚Beó&-m·áâ®îˆoèzh!W<Ðày^D°œsp?[r"5OÂÄDX\PµÓ,~t|I© c¹2oY€0˜!%c‡e½³p^á2”ªzç™bìå*NñÉÜ\¥‚ʾrÐàa;£Î¢çñžÞŸpîóçëZ§‡dÒ†tz“¡4c .¢Î’@ç¯HŽë 1ÎW»Xÿ(çD5Y)®€>ójÞvùêÎpÇ9ö›åP¢R\x`ŒhéÛ?4à×?øþÐö؉×XgAb•Ûd(Œ“Í¡£*@LðÜúë7ÇzM߸·%-«bÏ» ‡bËÅÖj—/]™‹­,ž‹g#¿¯¼V¬7£½­Lƒ»(í#‹íß~{ÒC{Jì4uwhª·£Ÿ¤%iO»,¾¸€>å=0ºäA¶çîP®:{F A~G]AºÔò´˜M¦õ ™¦‹Ñ'NÑÿ]²=å¥íŠ=&d`ÖwçÙƒNu¨U¦fZB%åÙƒçŸ÷'L„í³u‡ÙˆFб<¢¼Ie2ç |=×R¸ 䱯—؆‹./«vhÂ;|뻄­!7/.´±Ÿ îÂÚxÛ].üDš`*¿Ìú\—ƒ™ç²>ŒµÀH”pÆÀGtš¼±»çšØ~øü §£ý‡% þñMJ˜zú èVfª}¸„–`ø&éßF8eÆçDâh+À?&Y/îñG!é©·N ª $ÞXiM1”ãßÎ0à¤.¾@‡O€Þò4WÙî%KÃÌ¿NŒïc¤Ä8 -•P†™÷ù ­Î¯Å)GAh{D°yËv.ƒP2Œ´v? X¹'ÞHL¨g‚€ÀE}É’~¾A쮕X_—I&’a-mì–®L´I|v‰'Å„L(‰3w|_‡âœ7JqœŒEÇT$1ôüžHÎ:ü #ô/Œ ¿1Øý¨±†D]Tš[oC$,ÌìññâLÅrh/£×¥~üÿä3@”GÊÚOAÇ?æÅ@Í·E{*19÷¦IûAœF™h]B&оr†d„ðÆTŸër\'³§WË3›O…~}sÏ5±û…ð÷5ÀýÁöC:Ù0ä…ÐÍ< -ý„B)¥š–Ø>¡qo&9½føƒ1 ¹÷ÑI0™¡Ç¡hJ/£Ã˜4”"–}4 ÈëRÀ–Hˆ‰Ç¸æF ÁB´Ó‘JXKgo@„€òhÖ‡™F~§ÞDDÐîµ xÿ .Ë#R ÜZÑg¼®7бâ Xg -íxô»=µü¯¾Ë¿Øÿú4tOûžÌõîDZàêRäé×øË7þÿžÓwÒ øXz!SRQ¦2KœP¨5£.fgç¢ÿÓÅh|endstream +xÚ¥ZÝsÛ8Ï_á·Ufj­ø¥Çn›ö²½íöœtnvv÷A¶e[YÊZrr¹¿þ¤%YNæî¦Ó’AºbÁ1KM©LÏ’L‡&f¶Ú_E³-Œ}¾Ì3wLó>×O÷W?~RÉ, ³XƳûMo­4ŒÒTÌî׿þöþÛýÍâz.MÄáõÜÄQðÓí×Dɨùðë×O·Ÿ¿/Þ_':¸¿ýõ+‘7Ÿn7_?Ü\ÏEjÌ—¼Â… Ÿnÿ~C½Ï‹÷¿üò~qýçýÏW7÷þ,ýóŠHáAþºúýÏh¶†cÿ|…*KÍì>¢Pd™œí¯´Q¡ÑJ9Juuwõ¿`oÔNÒŸ6ih¤Žgs£Ã8‰ä´–£02 µy¢²0UBy-K1¥eÇ…Z>>®ó®˜¯vÅêaþÐ>Œ-b¦"³þÚgx® TO‘Da’%#þ¹+jн̂õHƒb[ÔÅ!ïÊz TÝ® áÅâîösKÄMSUÍ3ñÀPNÔïß>ÒÅÞôüëX´¯Õ øÛbu$"ÿ»©‹w8¤«TÇlG!˜±afŒ´R“T™ ¾Ü}ÁŽþˆ"•o‰ØÔÔz®_ï¾ÜüFŒ‹6Ô®‹®8ì˺ árãæ–-õŠjwͱZqÉ+ÛbM£n=V`1Áª/´GŠÜYÈ×îi'eNgPqàhå¶nHIkØÐ¬ì•Ÿùé#ê¦#ª?8 ^rÙt;ê=—Ô‹ƒ¼^ŸHͱc*Ñ@É!õîw¼ÃºØäÇŠwYá\#‹×pFI ÇÅS¾Ži`“:Ì´J™'<ó{v®8¿uöºö¹.{ ç²vtx™w«Çù¡ØŠvwæ€ðA\¾*€çš`pXcB0<àþ:‹‚X˜¤DRƒt—j@,DÝcý„øŽ­õA$ÞøF´ûþ‘ à€‡´o?6yYÁ]ÆBŸÀ®,pç¤DX5ûG€€eY•Ý˵"·TIlE°N©á$q6ôÉ“IÀJÓ&¡B-âø¿µˆÑ*óT…2mŒ©8¡Í1ÆøBNEx¶çü°Fíœoþ'“0NMÊþ‡ÚŒb@5œ„:_“Z#úZ‘,Ç*¯‰¼ä)äþH±W‡,tið;§áŠÞ2µ-÷ŸËuA£«|å„hx‡œe*žyFqx*-^„pк>®XP¸šC¾A"`ˆ\ a†4ÔÀt`ÕQP•õCK]+µÊ‚â_‚u^µÎ÷õxW ßIÜvD%5@'¯Ú†zKž +¹Áº·ºeƒhAÝ“1â¤ÚwáI»œ·Yót‹fØÙåOÅ‚®KÒÇ +ùdä«UѶԷ2È”½·5µèP“:–ÇŽžKëh~JTMó@½ã#ñX5•Öo€Šjâ]òúå9'WA]iÉØ3&àjVðxFSW/´(ÜøÄu +·ù’×~lpwì<ïÊÕŽºdŒ».ï¶¥XükÊ<û‰ù õ ªº³[e—ÏëöÙ/_sÛñDkÃܨ$4€-¯#xŸë2‚{.Ô9íú ¹¥M"²×7ö\;@IÆ¡1.¶¦À­24]i7§Ñe_ä5ØÀæXшEèÌ:zÀCn´ªÄ¬©¿ ¹Šýcçm-øûžèOyuä› ážîëOÅxÚŒ¡uS`‡st”¦ž ¼D£Kxà JH´œ„~LÞbHÞr@´Š˜Ïˆoš1…9lѰ_F|c] 1í`“Hü2¡YoL!É™ í¹þ¡s|l¶ý}lZ +—önÚù+5'©S QUDí(g†AŽ’_¦æ4×o £à%EµëÒB·S—#… éõn­gârâ0ѱf&ëâ(åc±*QIů So€l{ ÀëÃËIv{ÍRËP'Z qvx7}]Ç °Púu_ïs]öuÏÕóu´‹±»+ U‚|}kÇ4±õÀÙmyÎ>ØûÎëØ–Î’À×n¿!_¯9ak=OC,T-_-6—LŒ’´(îÝÚ§œŠ`°3¥\`ïÈD5ﻡÒaΗj={t§½Ía¦Ýý‡Y™Ú\Àœˆ8ÇMJC™v(Àž=+55ªk{æF˜:ÿv°{$:©Û¢#Êc~èÊÕÓ@ûMn‰‹ðPÙä‰FK›Ëm¸Â«;âúŸE[H4x)9Ê9Ÿ-9‘Ÿ'ab"‡..²Úéˆ?:>Ç¥T†PиZoY€0˜&%ˆ¥½³práÒ”ªzç²™bìç*NñÝê©ô`;lgÔYô<Þ³Ï{ü綪uxH'mP§'0J3–"#*,éKsþŒä˜^—ál­‹ålN„P“âèã1¯æm—¯èwœb¿Y õ'*Åu†ˆ–¾ý;~pùƒÏmxu$V¹Íe€ÂÙ:¡úÃÏÍá¡¿~s¬×ôýˆ{[Ò²*ö¼ ú&¶\k­vùÒUi°ØúÈâ¹p6òøÊkÅú1ZÚññÑÊ4Ȱ‹Ò¾±Øþí·'=´d ÄÎ7Fy2¤î¼Öd+ëËi±Š $Neòz¨ìs]•žËfdþçíéꇋ „øÌ¼.ƒçšbø¸ C¥C)ASiÚÁºËO@´õ´£Š\Ö‚`ˆõÈèÙ +Ç}¥§¹ÇŠ®¡Q×f—¶æƒöÖè]Q†Fèt”ø kCS@X³sµ¹JR[ŽCŒòsu D›™Ýeárzs‰ŽïöÔ@µe2Pr0f¢X©“Ì{FõävÌëöËìs¸Ã–¾¸À€Þ™‹áa0¹ƒ²ƒÛ]އÓQb‡Î¥S3ó·Ô¢)aOÖž8ÇŒ|,Ýþ#»û3•º 0m‘ã8bfÚh +— )Ö>ÔÄV|–c]áýÛ EŠ¦Ú¿Qg!ÖA1üÙÓ-x™mYµ š-ÞÔú‚Ÿ¯šýÞ—Ð)z˜áv +¼ešáO ¯–§Ïõ„:´“T æöùÙYD0ü1 9"¼ï)âCSw‡¦z;øIZ’ö´K?àk èSÆ£Kd{î媳gdvÔ¤K-O‹Ù,Z²h°}âýŸ(ÏCQ^Ú®Øc*f}wž7èT‡Zej&£(4±–o$žÞŸ0µÏÖ¦ e(Æò¢dù3ðõ\oHá"€HÓ0Ž2_¬±]^VíІwø ×÷ [Cn^\lcG\†5ò¶»\ø °C(°Þx¦ïs]ŽfžË:1–sÈQÂq'ÑiòÆîžkbûáó3xLœŽöRøÇ7)mH`êé7 [™©ìáBZ>‚eà_˜¤álŸ‰£­™dÝ@ºÇ…¬§Þ:¨x’xc¥µ=‚Ä84RêQXÀˆ“ºþ=z{HÔ\e?º—, 3ÿ:1¾‘ã(TBfÞç/´:¿§¡í=\Á&v,Û¹ BÉ0ÒÚý€`åžx#1¡6ž " Ô;ö%Kúø±»Xb}^&™H†!¤´Á[º +Ñf!ðÙA(žR¡$ÎÜñ} ŠsÞP(YÄq2s‘ÄÐó{"9íð/ŒÐ¼0&üº`÷£ÆuQin½ ‘°&³ÇÇ_ˆ3÷F¯Ký8þÉg€(”¶Ÿ¢Ž7~LŒšo‹öT]ròM“öƒ@2ÿкŒM}å" AŒ•—~,÷(Ôcº BŽédóôdyA`ð©Ð¯îì™Î·þ´˜ßß{ˆ?'ë…tÂã:˜Ç Ÿð'¥,ÓÛ"4î¡$§·¿ *¦!÷2: 2ƒ -öIÝH)£³˜4”"–}Èß `e‘/2pÁt@‚9h§Ñ!•°–ÎÞ Ðäq¬2üN½‰&p Ý;jðû\–G€­%Rë1àŒ×õ:Bœ£ëL¡ Ë!¨ßnFï+ÿ«×òouç¿; Ó¾$s©;‘¸’ XMºüåÿ¿ÿ/Ïé?:é<,½$©ºÌ'j͘‹‰Ù¹èÿW+g,endstream endobj -1301 0 obj << +1317 0 obj << /Type /Page -/Contents 1302 0 R -/Resources 1300 0 R +/Contents 1318 0 R +/Resources 1316 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1280 0 R -/Annots [ 1305 0 R 1308 0 R ] +/Parent 1325 0 R +/Annots [ 1321 0 R 1324 0 R ] >> endobj -1305 0 obj << +1321 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [367.5469 435.097 428.747 446.9972] +/Rect [367.5469 410.6007 428.747 422.5009] /Subtype /Link /A << /S /GoTo /D (zone_statement_grammar) >> >> endobj -1308 0 obj << +1324 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [483.4431 226.9165 539.579 238.9762] +/Rect [483.4431 196.7586 539.579 208.8182] /Subtype /Link /A << /S /GoTo /D (address_match_lists) >> >> endobj -1303 0 obj << -/D [1301 0 R /XYZ 85.0394 794.5015 null] +1319 0 obj << +/D [1317 0 R /XYZ 85.0394 794.5015 null] >> endobj 358 0 obj << -/D [1301 0 R /XYZ 85.0394 671.5763 null] ->> endobj -1304 0 obj << -/D [1301 0 R /XYZ 85.0394 644.6731 null] ->> endobj -362 0 obj << -/D [1301 0 R /XYZ 85.0394 417.7762 null] ->> endobj -1306 0 obj << -/D [1301 0 R /XYZ 85.0394 393.3438 null] ->> endobj -366 0 obj << -/D [1301 0 R /XYZ 85.0394 274.0842 null] ->> endobj -1307 0 obj << -/D [1301 0 R /XYZ 85.0394 249.8112 null] ->> endobj -1300 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1312 0 obj << -/Length 3041 -/Filter /FlateDecode ->> -stream -xÚÕZKsã6¾ûWè¹j„à ¢æ4Éx§6NÖã=%9Ðm³F"QÇ»µÿ}»Ñ_¢d§&[µ›©ŠÁf£Ñh|ý%fþ‰™±ÌzégÎkf¸0³åæŒÏîáÝwg"ò,Ó¢ÏõÍÍÙ×”›yæ­´³›»ž¬Œñ,³›Õ/sË$; |þíOW.¿ûÇõ»s§ç7—?]/¤áó—» Ñw×ï~üñÝõùBdFÌ¿ýþÝÏ7×ôÊFß\^½'Ч?G„^_|¸¸¾¸úöâü·›Î.nÚ½ô÷+¸Âü~öËo|¶‚mÿpÆ™ò™™=ÁgÂ{9Ûœi£˜ÑJ%ÊúìãÙß[½·aê”ý´Ì˜UÖÍ@7¦¸¯YVeÁŠÙô²C0«­>.‹æq‡iÆPÔ"Ìxof ë3ÝáJ5‚yc$žnæ˜t1NÜÒé^¡}§gÆjŒ‚3£¤ÙÈñÓùŠù ü_ÎN#³ÌÃI€b‚eJâʳßg‚qí½"žÞ8l´3@ |}¹‘³÷5lgÖßQ”»è [²ª‡W!‹V°|\Ö…óõº>fþ´ø}_lŒ|þ¼XæËs<´_+{b2q¿etÙ¼"!ô°oŠv5ým‹ey÷LùrY4Íak…, CÅÆÖÓÖ3™ùlÖÛ—AÁ[^±èÀüe0]HϲÌAèšY¡³éø"”: ØGi!(&âKË•Ž‹ŽêyQWc ‰Híú’Öo¹&F;X.†|Ä£ü•sYàªlþôP.h¸®—ù‡nž¯VÛs‘Íá¤ã2¯h€xÜѸ\«²Ê·ÏDyõ‘DÀ.›]YW DCÅíü桌’6ù§$´Œrëfæó¹Yæ%o&ÏmÊÛuñä@ܼƒ5JÃܪÙåÕ2Ñ‹J{²1 ÑÐ%.…`ïð·¬vçb^l«|½¸Ë—eußÒ‹-ÿí~GƒUÙôdÔ7CÅ;’6À“æ2hžVÀ8_WEó††Oåî¡Æð¡*Уòm¹~&§ª~jg‘oÁ (X… -“vOõöÓW =ŒÅ@×Ç#ê…ÝÉ#HÁ@£…‹qb“£fBô¦¦ÑmA›P+"”¡‚Þ‡j)P ÿl2±8Ä:'yb‚cÞ›¢Ú¡ñ¤ˆ+èº0\æMÔ' -þÖŸ‹í¶\ Áãmœ…X%-T?À$]%žçkìæœµcÕ Mogqy´Ž€èÙôÍ«â.߯#_?„aÁ‡-ô xíûch$º˜buLsŸýÚæ %¾PÅæ×¿°00‡k£ÿú /ùD`„Ãu²¿²ø/çýþqýŸg~í8sÐZœÎü-×8n±ÆÉ_s&uoÖdîL `¢ “ - 4Paú•)~âð¡nv‘šSdˆ¨6ÂB) -3H¼/vñmÕ<Û8ï.Ì«7ôƒ°YlˆŒÂ@wƒ¡6` -O™*b@wN qkÄqêÈ fÁvØVFRhÅASÄ(XMh!ì• ”ÙËý¶)§Ã½àx?ZŽ\ Gå]»n¨SÀB°òö©l&óx¿2ÎÚbbi}€áê5Kã@Í÷Õ=øpY(c êp­‡UW·o`0`÷ZX ~Õ¦ê ðÒš0(ÃdÛb H!W*á9Ë’+( ¦7å\û‹á–ѸÖ÷ŒÞ -aù6m"õWnø”ñŒ3•¤‡jª¬æ-ÌòŠžÑO¦å¥ôéÜ`A“ÊXLh¡! -J9Ä0*~0S”3é¥z!õ¸N„¢Ä5ЦZè›…—Ùi-Z® 5ñÈBÔumz [îÚzš…ÔŠðÃVÞR+ïîËÏ‘ÚP„ä.á+JR@N¡HzK5¼¤š ^j.ªÕ2fœ¶Ã#ûÓ…Å©5Yõ|P“½™@§„vÂ6Fçµd™k})¯VS`÷hXGlOIãÌk›ü(\•…Öî4\û\ÇáÚr‰Áæ»Óæ´-ׄæY1nÌH…aæ´mӌÔ9aØeN|h3§¥z ÿbçK#b {úI]·Š3Ãûû‡D(㫦ØBoƒWˆ€ekÍtZE›kÕã ¤¿*¡ñL»Am(¢›¸˜Lr,bœ¹üX¾†ÊW/Fë¥Z”²R(JçN'P(&„âòµ Jí“KSµcÆù¨‰ -¡+wIçx¯v,éè@!;L$œu2鵬$~4:™^‡þHKñ‚¿ö¸Nøk⚀ØTrÑàd"Ó§uh¹&”»ŽyïÝP‹¡ËÊ6¹(Ù&¤Ž’ ¾ É%¼‹÷\H»«tÉ]±´Õ<äd¤BSŽòI¨AâÄ |JÔ1œ^›OFš|i¯ŸNZ‚ãZ¯Íi8ô¹ŽÃ¡åêà°\å»Ãž»X¥ÿÉÕ[®‰åÕèjÉgÎ ×UÝ…'äü»‘ÚÆîðb72…3b³¿Ý„Ë%¿®òM¹$ºñ*m2Õ xM‰ÔMÞìŠ8Æë®&V 7 `!ÂÈcp€ª–BS„<¯ŠP4¥[Ƚ²Ç%9ì’Q}|Uï -¢îò]˘®ÞI„W·9CK·A‡‡(€ nyq«Ž¾Š³.ބƸÐápò²jÏá] {Mqˆ•Ì0‡©E‚½\¦Ãgz¹½×+×}Ô$þEÂjäÔË]™\É15ÖF*Ét‚úÂÛr½ ƒT:\ôœ¾„ Gvy¹>á»/5„Áw{\'|7q}wê<åÛe|4N`~T§i¹&4Q£;Y—õ·uèÆVµn ÃäÆ0ìÜZ7†òÕ¹1Œ;7ƇàÆ0èùToÚ:ÿýÕCÓ“ÉQøžÇ§@ßnÈá™ ¾“eðò¡Ž¬‘' ªé”p!:„7½¼Úɯ?è¬i!QêTËÿ ŠBÎc †ÿžª}sÐìÆ9oH|²)*T@G•¥HÄ*ª£yx{GŸ€â]tžeBš¡qÒö)ÈhHÆeN:##屨‚¤ ,ïýüæÜËyMÿa&:úšÊ@Cµj¬êrø#›Äõ‚ -ZrÆõCÚÊ`S÷íýRy&ÁO— =¦ãUBbêâèg»hž+nC9jØï~¸t'h™5v{–eÐö5ˆ¿,p&~À¥ñSˆ¿›·‘ˆZ{-èLú‚eæÍ¦®C@â’_™DÙAamæïà¿ÈWGŠ¥¿xÕ6œ@ýža2ë.×) -ü*¥®Ê[Jl0eßë©ôL²Ýü6ý¶¢åÁ ™ùù÷PÛt1If]øÎÛ¸u³I·)4~*Z,9K×;U<ÆžBQ¼Åº› -Áà±s:€ÐŠ6uBh_V(u LŒšÞ*µºå}ñ½ê~5c@½)Ò*ÛªEüÅýT››n* ß¿M·ßŽ¿øWvÝOµ£Önºêwt $*…–4úÐy9 "Å¡êÿ6=Žendstream -endobj -1311 0 obj << -/Type /Page -/Contents 1312 0 R -/Resources 1310 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1280 0 R -/Annots [ 1314 0 R 1315 0 R ] ->> endobj -1314 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [184.7318 238.2538 233.4785 249.0382] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update_security) >> ->> endobj -1315 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [369.8158 116.018 418.5625 128.0776] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update_security) >> ->> endobj -1313 0 obj << -/D [1311 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1310 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F63 1063 0 R /F62 1060 0 R /F21 710 0 R /F48 950 0 R >> -/XObject << /Im2 1049 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1319 0 obj << -/Length 2727 -/Filter /FlateDecode ->> -stream -xÚ­]sÛ6òÝ¿B÷tòL„@É“›³sî4iâúæÚ>Ði,“Ž(ÛõÝÜ¿]ì")Êq§=\,‹Å~Sj"á§&Î -©½™Þ+•Ìoää ̽?RŒ3‹H³.Ö—G¯Ït1ñÂçY>¹¼îÐrB:§&—‹_§ïþyòéòôâx–Y9ÍÅñÌærúÃùÇÄÓãÝÏÏÎßÿëâä¸0ÓËóŸ?øâôìôâôã»Óã™rVÁúŒ)XpvþÓ)Þ_œ|øprqüûåG§—é,Ýó*©ñ _~ý]Npì¤ÐÞÙÉ#¼H¡¼Ï&·GÆjaÖ²>úåès"Ø™ KÇäg¬63ùdf3ád6.d)¤¡Í -£DîýNÈ™rÄB!—ëuó8Ûnʺ½®6Ã3+ãE–¹I—ðÞöid{ÝÙ^Y#2éuÿ_îªùê7)³ª=ž™ÌN—«ù’†Ë¦Ýh>-7ÇÊM+‚ž«½lz¼Z=0ÖššGñtLë: 6·<¹d¬¶Ú<€@)Ša Þi4Û†FW=Û$œV5=‘é}U¦…2:cÂAû»’/”b¤v[n«ÛªÞ¾ÊF¥øp8/[äÇÈéjKµY-ðÊžá¦p"³.J¬¹Û®šºGíˆ/® UDñ©ˆÏË æ­•œž_“×Í–!¾"H¸r,ªëò~Íx«–gz´S  ‚¢Š=‡Áf™;dXéçm·‹uØvýj]Îo–ͺÚ3Û 5ò;G¤‘{f«p&lÝ3[eÓ’ëU»¥QsÍ‹™fÛFÜí²ÜÆQE6¾0~\¡\qî0™Ï«;½¯6«HjgËaO¦pß²:ܘƒfýPEvƒîep6Ÿ›¾åâOÇJ©)«Ôç¸#ÞõnGV¥–•ipPÑIzÚxÅØŒz×Ô‹`ÜA­x¿ËCúlMÇÀL! 6†ú°ÉcÈ"¤1÷6Ó"¤+ ÐèLh©L@Ũ©ra!ˆJ ¶Uo«Íu9¯Ú‘Md§7¼”áÑ£¤Eð¢¯4q×l¶- I#pv—EÀ1Ë1,n#4)¾t®Ðȧ8ˆ}O -÷íªþ7s_F[BoDBCÅ®êYSœ|–p{zDo4˜à}i£…Ó:bnË› øbMOÚ¤Dƒ16ˆ4Î/"©MÏ7*×yŒf º ¶C7E¡•›ä2…/õ‚œ'Þ97žñÌÅY—dp:=þ´q¢È@­EÊ-Ĥ!“d2×ß‘ÉHñ[L:0·Þc2xÀC&h’ ά/ÈFð’’ûƒ1»?‘bð=×tÃs(lfJÈ<è\ÏØb‹æêiÿ:.‹$á0ÄÍ!µ¤)Y7d>kwÈVbô…à®ÁLЇ(ˆ2:+Âi>€ó[Ý­GÍS -ù—˜$ÎEʶRºËŽ´øØgN\ýQÞ¯F iæ ‡‡ùvv@…äô¿ô€R½¥·ÿ½M'î¤=ƒ•$=AngzÔþ¦À7ka˜¼½Vyöˆ†ˆïˆE¾Èv«º¼Z£ -ÍšÀº¼ePòÃE¶Æ— -p©¹n%Q8ÿD3}Ã%$ÔÂs4¥MGFæ)ë4i±‰®|(ÕÛr¾\Õ|É!ÃE¥­X1AtÑ.ÊCŠÍÂh)‰r—qŽèiÚçÍŸVÓÈÀ3Ékº˜žMEŸã¦>dƒq&e°çŸLOô tØY.»È|ß2/ÇS~.ÉìvöØæ"‡ä²Wp™ÁUú‚l›NAtýÄÀe,KºNOGJ‰©†á£Ã -œc5 Þ®K+Ik ’ªéH ¨êA0hrQ¸¡ž7·”Z€0¿v3ǼNtx Ÿú¾/«±È=Ð=veýMÜò»”ƒxe1ȉ¤›–<‘¢ÞÎE°ñϧ ™„B¢­‘àõ+þR0Žg]Šû±Ø²Ð~·ñÁ„!ÓNXë¿'‘â·˜4JXãtŸÉC ƒ…2=w,nò¯Ý»é'” V/649”â&Šê4Q˜»pãÁ¸UÄëXêà†“…vEÁ&ÚÏGöJˆWÝÎÆÖ¢uª-N“—p¼Ùkŵ+ZÉ„I1:¹+ÈÁb†ï;Õ=g¡ò®£ »‡ëÜ/j^^HøBh£ÈO7ûïüç눴ð¹R"“R½Y\¹7o^ëìíøª‰ÂwÊ -m*'´äbTN (é(@ƒZŒ»Áü!Aó\Ѐm 憶“èiWÛ%#s¬ÈHϯÑlÐstœhb§† q5bÄ#”û,>åMÐh„o8ð†HäYprÅE ¦gÎÜÑb´¯?hªw3Ú—$[st*Þ'¡d¾8 - QõM׎b³£ËcŸM›Ø*¸©ž©HRå4V„[Ùï!?‚MÜoæ¿ ;¡BC3ê` WHûr‘ã×°aY£È‘™½šÎĦ§é4=êT$K%Y¦:F±,M’¥Qƒt ¦îë5çêüQáR÷x6vÒ[Ó­K‘ÑNùž‘@ bM_©SÓ(Þ ß©Ð9,ƾó‘Y[tv¦PøÐÜ×jÆ{Û'Ÿ¡ ÿì¡ Ï¥î7Ð0¼—1ö¡ð+Tá^Ä~l±ÆÅ®«0ö€  q¦¤e19& ìÊ]œHÈ3œPÒeýHÀ߯ÚÐ26ûm·ÙŸs³ÿsø B±xWì=ßôG3ÒÑ%èŽKÐV…$½þû–&njü¸Öý}ÍŸØpMI¯PG·\¦è†´V§¶# ³¸¤¡ì¡víh3Þƒºdɼ¥YÛÜoæcŸRf ½_Øô¾‡å\IéÜög(ÐÀ€/p¨Ñ0 -|0hïC¢“ÜC…ÏmA¹"ì>ƒ!vh- vCâ§ÎšLls"Î*rïÒÁ±?> endobj 1320 0 obj << -/D [1318 0 R /XYZ 85.0394 794.5015 null] +/D [1317 0 R /XYZ 85.0394 622.3077 null] >> endobj -370 0 obj << -/D [1318 0 R /XYZ 85.0394 658.768 null] ->> endobj -1321 0 obj << -/D [1318 0 R /XYZ 85.0394 636.4568 null] ->> endobj -374 0 obj << -/D [1318 0 R /XYZ 85.0394 119.9909 null] +362 0 obj << +/D [1317 0 R /XYZ 85.0394 392.0307 null] >> endobj 1322 0 obj << -/D [1318 0 R /XYZ 85.0394 92.5589 null] +/D [1317 0 R /XYZ 85.0394 366.8157 null] >> endobj -1317 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F41 935 0 R >> +366 0 obj << +/D [1317 0 R /XYZ 85.0394 245.2415 null] +>> endobj +1323 0 obj << +/D [1317 0 R /XYZ 85.0394 220.1859 null] +>> endobj +1316 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1326 0 obj << -/Length 3170 -/Filter /FlateDecode ->> -stream -xÚ­ZßsÛ¸~÷_¡·Ò‡ß›'_⤾é9©ëÌ´sw”DÙœH¤"RvÒNÿ÷îbŠ”)ÅI:™ ©ÅX,v¿ýZL8üc™Íd6I3Í f2_ŸñÉ´½=Ag•¦}­ŸoÏ~z£ÒIÆ2+íävÙË1Ü.~K,“ìFàÉ«w×o®Þ~¸¹8Our{õîú|* OÞ\ýí’ÞÞÞ\üúëÅÍùT8#’W½x{yCM6ŒñóÕõk’dô82èÍå›Ë›ËëW—çÜþrvyÛ­¥¿^Á.äÓÙoðÉ–ýËg*sfò?8Y&'ë3m3Z©(YýãìïÝ€½VßuÔ‚3©¬q c4³J*ïÀO»bûeÚÔ»í¼˜>X\tS½n©a6MÌ…úõ¦-ë -ü¥ÀWˠߟFkØÔóÅb[4ÍȰ*eÚ ôÊfd¤Œ¥Ú˜ ñç1Ó×&Zö;7˜° ËJÉ.Œï&¤Og`š´÷yK’fSÌK\Uœ­¬¢J1–ÊÙ˜`äôAOw‹Í'Ç™VZõ²z·ëêýƒŽ¶¥ÞAO'´†ñÔ¨þ|vÜ&9sÙ¡ÛN˜~æR›CS”hŠ%S””Œ•%Åçùj·(«;jDÇø>ÞÁ nÄFtcÔq£‘ êVDÕ‡º\|͇Ôêü8î,p·Y:¶s$Uèý%¾î/H2!å T SŒÂ²Ûò¡XÅ`¤™B¿Öw§…ž‹b™ïVmC¿ê%=Çý8—Ó¼_ÜF̵€+Üt¤LªGÆ;Z,M‡Ád/•—â/ÔI÷'™23(àfˆ—ë§–ó~5 SÉLA(“Êìoûבu"3æ\šô2,KSÛïô’vG¤Ší£@Žzâ©yZ1œÄ§Y§OY§X§÷Ö¸üÑÉt@θJÓS•Ç'¾ — H{d$Z$“"͆Øóü1=Ø:“ìª:¼Ã8ÛÇÔ*_‹1†¥˜S6Æw¨"0üü¾˜ÄW›”KyˆÂ—zSlóÖC¶7_€P­©‰ŠZÀœÌŒ; ‹‡ráN,…JéØën›¯×„ˆÐVVmu»Ì1²QÒÖô¤$i·%4±ñ>¼xs eý§0I€†Ðà»Ñ/Bjx)6÷ÅÊ5ÔõIünxʯ14¼ÍK¥7¼êÈKöÐä`¯„³€ßª”òr•ÏVÅØ6e¡©5_ߦT:=Ü&˜‡æ ÍɼÞF­+ª/ØÞm¨tÁ_o^âî¥I £l˦@8v<)ƒÎÈ|%…*¬ÒQq ÷¸~¬†¸<iÔïIzy¼ø=ÂWå–Þ¬1ʼ¤÷ÿ¾îˆO¯ïó`+ø6®ëðhƒMÖùGŒ+žB Ðà/B“»}m‡÷Y5»%ªbÏË¢j¡èyùŠjÁ]‘"õ‹ùn[¶{žætrAMV˜[ µ \þ»ˆm›¢Z„¹ëŠžù¶¬wA¸É§c„œ, ª}…Ö"™í0&€¿£1õñ%ð¥ûr†ØŠòçT ½ÁKz6õ:H"£ó@òÑ…Åç|½ ̸AH~@Ø>\_ýS\ŒlèG`ðVÕ-½@>×£œ×ÁÚ»s扔•ܦƒµWDaü|í}½‹3у§ßlËÀ9c€¨˜£(&Ò‚í¡¬ÀëŠ.ëüY:¯è I€¯ Â3>¿`d|Äsà ¨Œ{PI³c%ùUx¸'¬0áÔ®cJ™Ãs½öEŽ. ®¶pü-ñâhgÑRî) -è¢Æ‹¼x¥ Õ~üxÐ-oa7Ãñ±Û:O:€·¾ ‡0”DZËÀ"BS½ÚQ"Äž’Dþ²(Vy¼HBZ.(¶1‡°bîIT¹Æ¥æUÐöø ÏCüí®4xg_’ÑñpÑ¡è<ÌójxWÙäË"‚ÑXÊêRý¾¼éã…o®JŠÖ -¨Q;zùù¸ÍxÖ­ƒW%¿áN£»ôyö¨Ï¿Öp -ïðZcdÄÜÇiþˆ}}õg1x™ußvx–ÀÁŸqä ¸Óc.vsb&Ƕï3„í¾F`Uö9‡YõjüŽ»ïÉmaŽšLiv›pÿ -œd~0/ðÁO:›b[w% ÒìGêN(8k”>ÌO’€>wFp“DYU?†Ædzáù54ÏŠyNð -M´Ë»†›GFjM¾:‚áµ S-Å#£†6ª, ™Qz3à±ÈÏï+œõî(݇ƒL0 Þö¤ÃŸq$X4q?|ö8Ø3„CuGHײٳCTñ[‡ªôËÐ/§Ç&ßóÝ!òÃÞB ´8] -oSŒ|öµ¥Öžºˆšj­!\=}k÷¼ûË—ˆZwüÒZÙà©´9ÀL -ÄQì©5Àhp¼Ñ÷"lƒ¯©‚¥BØ œ™ËŽ|û$•é^çø‡Ï s<û“§Á^âÔìΓéÕ:2fSeúóßRFúj2]e!{„§ÌúÚwÂ'=­^‰Z]„t>Ù׃gŒdZ÷{Žú&j˜1ðŽI™†ÔÚñƒþ©eNhsÚ?}­ãþé´Fü³Û,ò¶ðwƒùÓÊàX`œ;mN§5bÏà+(@´¹ô½ŽŠ‹ƒðÏúKçÿ{ì[4€1”{«Uv|,êÇa¬ð{|Öîþ"Är–‚y}‡tx@(™Jq·¡ä #BÉ±@Hèë°–`í‘ÜÂÿ2yò0&Oe:q)ãXÌ<ù4J¡³L‘Nïݯtï/øéj-'¯kXϤ·¤8î´7°_’•}ÆàXŠÇnÁ-heéž:BŠtßWà‡4´?˜Ð³«0vf -  -|Þ+1pJä •ƒs ä8vëdS&U÷4†˜Ÿ.ØA´%ËsÅýYÌàTNo^¿'ÍÀFdº> )·¯ðo.œŽ¶A¢ô-b†Fú3âþƒ…Æ*£CÝ!9Ý15ÔVW¾F9ú¼€o -çÀ³¡UGl ‘W¨˜ã"¿„ °ÆQV¼G÷‡'â [ŠÞM“N² w+x’¤ÚfLºÌM( Ä'¦°Á¿“˜îÿžè‡ÓNÖ>2n¼K×þK¨=(à×b7…þ¢cÚÁ Ê0 ÷ÃØ§u"üÉTÐê™þ?náÒ1endstream -endobj -1325 0 obj << -/Type /Page -/Contents 1326 0 R -/Resources 1324 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1323 0 R ->> endobj -1327 0 obj << -/D [1325 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1324 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R /F63 1063 0 R >> -/XObject << /Im2 1049 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1330 0 obj << -/Length 2839 -/Filter /FlateDecode ->> -stream -xÚÝZÝÛ6ß¿Âo•šå·ÈÇ4Ù䶸îæwm´¶¼bKŽ%goû×ß ‡’%¯ì$H€ŠÑˆÎ ‡¿ù ½bÂ៘8øòz’zÍ f²Ø^ñÉ|{s%"Ϭešõ¹~ž_ýôZ¥ϼ•v2_õd9Æ“ùò·äåß^¼_¿›Î¤á‰eÓ™±<ùùæöxz¼¼»}}óæŸï^LSÌoîniøÝõëëw×·/¯§3ጀù2J83áõÍ߯‰zóîů¿¾x7ýcþËÕõ¼[K½‚+\ÈÇ«ßþà“%,û—+Δwfò/œ ïåd{¥bF+ÕŽl®Þ_ý£Øû¦Žù¯ã™iǤ_¢VHæ½Ñãj9l†e6ÏŸ•Eó8ÈŠd;c(긽Özf¹O»í•j"óÆHÜ_ÏY*`[S¥Ç!ØÞ[tp`ôÌX-Opf”ÃÇÝtfE2‡ÿer}º R£?¬sÌ ‡Š''‚qí½"žVzô@øéf+'¯*XϤ·¤Vî¬'8¬ÈÊ`…LO58†sæœrÁà÷Õ&ÛàLRÔÓ™r<‘Ì0AdV.‰È#ϦÈ÷4²¬òÈ_V õa·«à³æI;’7MQ>ÀKê“fÇÑê°_D:[.÷y%­¦Š'UT0ùý‡{ßí -Ø[W‹©äÉü/oê)ÅNý¬}ʬ²j·Ø};jŸÆ[?™‘ÿ͘–– “~Y©`Ö -õ5+ 3ôÙø0À ¼4Ÿ‰+=sR™ï Œ°Î›ï!}ÉBÄxɬ֔ÔßçV™º$ÛÔ-ЪÞ,-`ÊÆ6û¬¬WSðÜ#Hgw$ò4·¯15LiÛÎÅx{._x¦\Y ÚŠÕÓe¡°ÂaGhÆùðèïð·æû‡G‡øô†b¤ -Ã0§µ+ÆÂ),K!eqΓÿTeNer>B$aƒò}ÝÃj+.¥p¦Ê­¬MÖYMÄ6_¬³²¨·ñ½(é¹Ûd!§ÙTøL“U¶(¦rf“59 ýL Lá•2-2‰ØÛ¢‰_«¨„R(²o«C«UœPeKÒÒ¬³f,wöt¢7¢ÉH¢|HÔOu“o¡ýPäy;ºª6›ê1dô0k×U¥e»Ýæ)J©èùgçøNó30:ÕÒˆ¶ =Ó’E¦YŸë<:®S´3ŠšSÝBi&½þŒòŽkDû L•g25'ê_å¿s.ËP,%¤|¤ÉæºÏ64´)ꆨ°“ðõæmd†â8.ÙÎoYÊl›ÓHï?ŒdÜyšK3ã &®ÀPçed¸½›ß¼þ7Ñ[Ð=ä!"  ßHŒ¼>v×y™ -ÕR\¤ñU4oM£‹j÷DaR´€åð9µð áš/Äbïb…v @LÑROÊq­ð‚~Ë—ÄÑÎèû!jº}? Êêdú¢ -Ï%*’¨ûŒIÖùfÉ`<ó²>tnÅqò6P°ò"ÜaíákdC[â·Çb³!êã¡X|À€¡é%º$?Ä9Áð„%f›f_hùl,¶ïB,f‰9ü*µÁ}’Z'Ж5Dm³'"îszÖ»|Q DÑ•8ðX :¤òl±Ž9²eÚGŸjÕÖ¬a|…záL[ü{€&!S yÕS"Š$«[|&e®jµ>~àvÉiRÈ=’7¬¤Á¨v>_e‡M˺¢A8Á€Ç¹OnVô¦=w„°p¾‘Æ~©#RÉE䥘GÉEM*ŠOy´­(i(Ñ õ*{«2DÕs]RCºì6¨Æò³…¸ÿ‘ÄQ3aG*@Õ¾XæäO% é„ :lÄ)œðxÛ›tõ@iÑsÔÀ1@O¦Œ§Vâ‘×Éä_kt‡Ò|Ô Î3о‚ÎóÞ·àþÌ#4 ‹t4šª/M5¦UCË«ºFlDx ¨–“›U1€Ð×5?Éëät +0 AÒšh%ëÆsÓŒgP§ä—AQ2•ÊQvÌM@щˆû V¶UFºªô1*ñmnÁØ,2ãÆÀvj洞À±.Þð¥¨ë n€ÔÅ ‡fvà†|»kbk¨ßaCËØh´åi\6æ³EF…¤üâl÷¡ R¤—»>×ùî£ãBÓ·Ùgmóƒ[>kŠm>+Êg­H -'wiõeK:®S0t -N©ÚrSÞC×Nôº  ú¨SP]r(K:¶ÃçMU>С_ÇüI]`E)Ÿhæ¶(M‡#šUš0%ßo‹ís -öYá†Û\BT.O[Îc~6Ô;àSHND§²E„$r Ç£šv|(ö£Ø¶ôò)Ûò¡dé¢Úì©'Usu¢ñ2šxÊž/£©ÇuM-×(šŠåfMx³Ç±‹–t\#¦ Ñ$ ¹89´åˆ&Ñ¡I Ñ$I+:=wÁöêáØ -à(åºY¢C–0Áé¤ \¢k£D—8˜ë¥Ö¯/—=‡-qÄÖÿ ZÒÚ‹‹Ðês‡VÇu>QU‡æ¶  -j íÁES:®[†Ø‚º§ƒcîM—„þ=#ñ Ð;ÀÂk?UÉp¤P¶ -ÜÔíªˆSSê¶^b/Ô}«ª(E‰û¿h¶’RÂH÷Hõ¸.@ªå:Ÿ­F!mԃ˦t\#¶ !…W¸é‰1GH)ÞBJq>ÈW\ó”¯à9’¯`bÈW¼ÅÍ ùŠ‹a¾â-¼ -ùŠx—D€Y–B „ü5r–€øIuª/¬Ïu`Wèãó}‘mfùþi¶ÇK¶S`YΤ·æ² ׈ `AŠ’)tU#Þo²Oè5%×Ru)†w`fµ,áp¾‹éã6«›°”èÏ—tÊ…g¸>ZÆN,V4S#é.²¨°ËfÍÆ®mæS/t ýpEŠd¼lÁ±Î - ƒØ$´‰V÷NRŠö§Yàñ=‘õ‰Ì-’Õ=®ñиˆÑCáú'°´7DøRÓV¶' ä¦0¹Â æryæ¨--3Š?ý¼¦p8·F ç¸n!’PAUQ69ÖKØ‹ø%D>wnÈrL¼Eq´æWÏE<)âð®å«óEU.ƒtðô¸bîxÉ@Ím’ŸÏ,Z=g?siÜçºYZ®÷tD¤2Î1­\Òßq0H+:½Ã´Ò·àwHú¡Ò%wH©3ð°¸ s~Æþ¥V3‰?—ô±A -Ãê#ÀÈ0Ú!>Àìïâ°'܇íbb>¢9±Ð üÅé4yJ¹#’”‚t‚?5„û]øn`áÊ'0íሕúçW„!bËÅß…º|ˆ?+>p¸nÛú}dI¯‡ºûuéÜ£c\òuyªµ;qÈ™?•Q†áß®Œ4ï~ýþæ?£9þ¸ 9B¹s‡#Å-sÒ§­Qh¾IO-7 -<âd:búÿæÜ"endstream -endobj 1329 0 obj << +/Length 2905 +/Filter /FlateDecode +>> +stream +xÚÍËnãFòî¯Ð-20êôûœ&OÖÁÆÉ:ÞS’-Ñ#b$Ò©qœÅþûVu5)’¢d“2FÅêêêêêz6)fþÄÌXfƒ 343\˜Ùr{Ág`ìÛ ‘h-Ñ¢OõõÝÅ—ï•›¬´³»‡/ϸ÷bv·úyn™d—ÀÏ¿ùáæýõ·ÿ¾}{éôüîú‡›Ë…4|þþúŸW}{ûöûïßÞ^.„7bþÍ?ÞþxwuKC6ñøúúæaýœ`z{õþêöêæ›«Ë_ï¾»¸ºëöÒ߯à +7òÛÅÏ¿òÙ +¶ýÝg*x3{‚ÎDr¶½ÐF1£•j1›‹Ÿ.þÕ1ìÆ©SúÓÒ3«¬È3)€Ç+–U>jÑO/Ëá0³ÚêÓ¼h^ lg Y-¼`&3[X§ANºã•j& ÆH<_ï˜tØ(Å8¢àxoPÁ‘00cµ@:Á™QRs¤øáraÅüþ—ó£ãð–8Š™…ÍáqáÙo3Á¸AMŽ;=h "¾¼ÞÊÙ» +ö3ëo)ñ]ôÇYÕ3X!ìW«™ † "£ÀÙfS] +3Zü¶Ïw`|þ¼XfËKÖ9í×ÊÐdÚoQƒ :?/‰ =ìë|EPSÑoý˜/‹‡gzȖ˼®‡ ¬X@àÅÆÚÓ60郟õîólAÁ!ÛŽ±8ØóçYêB潃è!AÈàÜtˆÌ aáÀ4hSw°A1b:ªöÀè°žU9V’h ]ŸóÑúÕ„“Qà–‹¡?áaþ¹Ìñ•Ÿ?­‹åšÀMµÌ6ºy¶Zí.…ŸÃY·„ˬ$Mà±!¸ŠT«¢ÌvÏ„ywó±€]ÖMQ•5DÅíün]$NÛìcË´H|«zêõ¹Yêíܤ®‹ûMþø@è|€5JÃܲn²rÙâÑ•¤cQÑ.… ïø[”Í¥˜ç»2Û,²eQ~èðù-ýý¾!`UÔ=ž`ìÛ!Ãü÷†¸Å ð¡äí +ê«2¯ßøT4ë +À‡2GŸÊvÅæ™Ëê©›EÞ@°Œ''5OÕîã5=Œ¥P×·G”Ë3'¹^ÊÎ8×z˜ëû:üjB +«Á¯ºT¥ZZ€"N¶­*æêc!g¾Õc eÁÔbজ‚k1Ü2*׆žrãY!,ߥMÄþ ŸR¾Ø«–{¬†¡Êª¿‚YAÑ3úÉ”` ¼”¡=7X@Ф"Zhˆ‚Rm? +˜m”QòB :МC‰f2M5!Æ@„”þÜúÍ‘ƒ(d!Ö:ȱ= †íw]  BÛ~ðãöF©ý€±ŧœP]øAô!üà%&@·áGKu Rƒƒ:‹ê3ÏŒÓvèºø¢Øt¦+Ÿê°7)¡…ƒïÇ9a€Z2ï:ÿÉÊÕ” .ûF{žâ%“¶­SŸ6Qå1™Œ´GuÆL[ªqwØ(C2wÚœ £š`Ø(ã%‘‰0Ì–¶k”l³%€‡l‰]¶´T#á/v»iÜÓ§„:t¨8cM6¼ÿ°nEªóô3xs¶l­™N¥¨sm bD™W%1îµÔƒ"¹‰K 1§r&Æ61‘¿Oåh¨q¥ b´^[RæB %MéÜù¤ „P\¾6irmÎ.MEÔ‹žs1ŒI tåC¢9ÝŸJ4ºNȉgM4Q,+‰¦Φé¡}°ê…¤Ò§:í¯Õ„‰M¥ N&¼>/CG5!İÀu,„à†R ]VvÉEÉ.¹ v”\p4&—8–î¶9vWéZwÅrVó˜OŠK9Ê'±îH×3ðY(Kù¨†}m>Iò¹ý}gšUìŒÏ›CêŒ9´TsØ?®²æ¸ÏJM(÷Ï®ÞQM,¯F×IÁ;7\Te.9!ç§ØØ.vLJ6v#Q<@Öûûm¼PøÝs™m‹%Ð-'`i“m ‚W“ˆÝfu“'¯¸êTܵæ "ŒÕißí¨Æ¾»qž²Ý + e|4N`~Tçé¨&$Q£{XçûÛ:vc«:7°ucnŒÃùŽ:¸1À7ƇèÆô|ª7m“}Jþ áñr¾£gãq¥)ÐkÇ[qx&ÅÅw#Q¼p¨é:Ѥ A5.F‡8ÒË m ùå{íûÖ#-$JÝÖòÿ¢óÔ6Gð¿SµbÜ4ç ±ouŠåÐQ%a)R²Lb§hGèµOºŸ‘.0/¤*§Ý> ɸˆÁI{R`ópÚbÁ²P<Ìï.ƒœWD“—Ùý&ÑuKk×W,p~CÄí=儞tPFkÃIãÆ;ÀH«†%_R-´l­f¿zQµñºKý><Ó&Å矲͞îÞRý˜®ÕÖY9!:^GpˆRîˆÞr¶Û…cšà+¡bêŠýãíMqÅ@•Ý¿vQXjîAŸÏô°¬öøzê‘ÒÑj¿l/ïhFéÑû¼ê¬88YQ.ñlCë`)g> endobj 1331 0 obj << -/D [1329 0 R /XYZ 85.0394 794.5015 null] ->> endobj -378 0 obj << -/D [1329 0 R /XYZ 85.0394 548.8286 null] ->> endobj -1071 0 obj << -/D [1329 0 R /XYZ 85.0394 526.2567 null] ->> endobj -1328 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F21 710 0 R >> -/XObject << /Im2 1049 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1334 0 obj << -/Length 3252 -/Filter /FlateDecode ->> -stream -xÚµZÝsÛ6÷_¡·“g"_üÀcš8½t®i.uçf®í-Q6§©Š’÷¯¿ßbŠ”(Û™äÆ3ÆX‹Å~Cj"ñ§&I*R§Ý$sV$R%“ùúBNn1÷Ã… -8³ˆ4ëc}}ñÝ;“Mœp©N'×ËÞZ¹y®&׋ߦ©Ðâ+È雟?¼{ÿïŸ^_fvzýþç—3Èé»÷ÿºbè‡O¯úéõ§Ë™Ê5}óÏׯ¯>ñTÖøþý‡·<â¸9³è§«wWŸ®>¼¹ºüãúÇ‹«ëî,ýó*iè ]üö‡œ,pì/¤0.O&èH¡œÓ“õ…MŒH¬1qduñËÅ¿»{³þÓ1þÙ$‰¶)8™K3Y‰L)àdÆ4w`²VcLŽXÄäݶ¨Ûe¹½Tùt¶l¶ëbw|p¥|:ûËŸÑaPazT(#EšáD2þÛÔ%nÏ%A-wçEÍÀM˜oËzÇо­êÛðÑCÃÀ¢ZÒIÂ:T>XûŠŽvÄm2‘;Kç B@Ç <`ÆíÓž@†UQ‹z1²žÊE.qQŒ³.êǰ^;²`šˆ<ÈÈ‚0pç:Š®\)á’Dû¹ë»rl3'´í:s—G{fJ$inãy7»ª©IôóiÕR›±å‚GâÌ»{`]´;làÑÚr{Ï0n%¦×UÐîªùczx£Ðâ.­9—Qt)yïNkdN¢žDÞ¨pgîËÀ„ªò28hü±J²éÛ¿ðȺlÛâ6ŒnèT4ÊBÔ6{ÌËþè¼ñí‚?‰¬ç¹ÅØ™4ôôÛJ†V%I@Þó?íEË;Ò÷Ì“j!ÕC9¥]«ìˆö–‹Ðnš¶­nVµªý¥Ò<7GbTµ€Ù~©ÔÃÈ+ãrv_3Qa÷ÒëñïRêy5~…Qm¦7û] .|ÔÔ«G†ÚýfÓlwå‚™¢S JÔ)7@6J6¬Š]u_ÒFºi]>ðd»*îËz‡Ý˜m± 3ûKÀ7ìThÄyœ$Ž`.Ÿr½`à0g… 6õCnžÊæîŒªç`+lÞgq¸žqcJ1Æ~Ø]™w¢Õé¥ÔÌU´Åª¥«—¦ÇU?Aü£6ˆ‘·¯Ôÿ©šû¡¦m–aè?—IZ4-/U æ'ªõõ¸‹rYìW"FNëÌRgŸ?½~îô™™Ìú&÷ØOŠ$s_lS­Sª£î‘c‰›’Û‡ÞV‹EY‡~h n6aùƒAŧEËæX2ÓÑGànTD4ìIdT¬°Ü ޤi€vWìÊ5®RœDøè°úÌmgU}uHø6ºÎ'wï°F¶DÊ -°'îï4{]|®Öû5wêýúÆ{ÀÍ’Ûª¾iö^Ñù›ý ^°â»w¤Iù°…€›€¹½Ì§ûºö7èšz¾ßÆ(6H)5¥PÕèh ÛZ¤ˆ“’Ý銑Éô¾XíK£ÚX5”ËÜØ(ìJŽC\;êÃÌ"~_³>—…—¹Aà"Mz¤$ñÃ&h”ë…DLq»)É®¸ßPk9Π°çžµâ¶¬çaÐ_} 4@º -ožéƒgÅŽÙ‡Èq·ÎŽ #7hQ§§Õá¸åAÁ<°jŠÅPi{SóbÅ`ûˆ°h}V’ Q¼ÒöiêcW kÈøf·C摬ا·ï°FöʉY–dC¼YåD¨AVKi4ƒ -QUˆ ž -:«Mx"à&`öUˆPϨkN.T–yN2üF«î{¼Ä_û²ÝµQ ¸-?Ïô„û_ßµæ@VNªÕjhòyÍ%…Ò‚ýuüîàíÐ ì7Ó`ƒ$Qº.²z‘ -Ÿ“B˜>™9óŒö°žÂˆ5”ÂèÉêö4‰Ì…µF=ME‡5BÆ0‰4Â"óÒÁVò ŒÔ‰Â¨wù;Tò`ΩòHPO}÷Ž£ ‹4t0Odoðý6MÏÖ\'KŽ•ˆ>ÇAš[„¢5ƒ¼ìºÙ•ܧȉ¡àÒa¡ÉPkŽìúBåBåΕ¶ÐùTEó­Çl¶pY–ö¼‚‘/ò -à–;ñ -C±8Ž,œ\žb':ª÷A™¥Hòì(Àõ>Ï>CéŸYï30Ùõêà3t|«ã±w öSz‡Þ–*xB"ï0 ¦‰4Á—èIé]â)åPV^ÊD¸Ø¤鹿è#7ƒ”Æ›Ð<}€úO9õà#£…”†Î iIͱŒlH­‹˜›»-3—h[ònã[ ÛÍEf“!—¾Y¨K5¹,Gzð¤ìc·‘ÖIAYù¼<5‘™Gö Ö3T(íH$^Dű0iY£Æ®¤CVV ÖtÌ!2jZ,¡âÑØ%š`3© &ؾ²@åã½eèúÍG Åu9§¢T¢8_ÁÞø¡FKOËrǵ¦œ5<Ì 3¡þÔ™ÿÄ…ôªWãYc ‡rUŒó!Oßöë-è‡b›ƒ|ò èª«&1 ¹bå -úaílúëÛaƒ‚혎q3$ÓìÒ#£¢‰ðj{`Œ¦~˜/¸ð}ÅEH l!΄šf¢c&ð‘‘¡¬ö vÎ.F…nC)G”:µÇÞ3Êb›ŶÕŸªRÙLd‰Œlö'>ÝN.ÕY¤¶ÙŽÕœZ§I$Îógt¤1޽Ãús˜áuÙL‰Þí~[ÄéëÏ«ò$ZÈ4’‰¡­ÜKÞâÒÓf>þ#“!lÈtz~-þNb­Æ/†KÍ"uävpC껫å$Ï„ÎàWa[„sŠâ>ô˜˜¤ÈˆÓ¿Mg ~¾œ¥jzÿzzòHš§È‡ba‘'™œü5Yç£=9€ýY<ðß½_ëÉÛ'šôžõWö‡‚ö£ĕƚ R(¨áÄð—fEVUù*"H7Õ"ŠA.Ï(Ϊò10FMðÉÕy€ âȇ :a¤ÜíXõÐacM£¬S¼ >{t–—r‚]=r-eEÌ/µœþIÿÈШ´©šÞÈú·üu‚c ©“°ò‡é¯kdr"÷™›†O’ò™Úƒ¦‚g"Ÿy¿î°Î²Ù}zZ›œžÓÒI‡ÓÐ:b2¨> y1.Ò•wZÎÖÿJ4’#§¡ù™a8è<視¯¥©M("ý}RØ -5«¢{RãgzÀ('Ï ˆRÓ³)‘–”ègªÿ}¬'®.bq`²›½$-2ozó}’k„’áÝYa·¤¼&wœeDR¹­ aei¯LH“ƒw`ô)Ž¡–uèì¢1²ªZÿdæ±ê±DYAÓÒ,ÿRoœšøÉ²¨Vm zôw²IeÝîí{FüŽofVäÎØñRóQ’ÉÓ¼%¡/wg½¤J¬0ÖfßÄKæT70î Œ]ü✗Ä2)ógœ¤²J(Ï·t’m.í·÷‘½…Ÿp‘Рiv‘ïýÛŠœ>’ÏiöÜYP)Lªàý$%õ”G^j$« Á4è MB†èÝ»õÎÎëVé\"a4ÜÞ„>å±T’“é‚ö®Ù¯.ÃÓkjÎ×Ë¢ ³0Ø z& -õ'JÓ3b4±HöÍ&D 8e—V³¦ÑÏs@#½h ÁÙóD$“`Ï,妬Ãà~ÓÔ±œ¶¤R·1ˆ ÷ï‹Í¾m‰á~즡ïùT:‹õ‡Œ0±¥l’:[$ÿœø£C‰?ñ‘h3ÏÇ=}ø: û„ôx›ÂݰtüçprûÕ¿Ð;ü|I HÓã>…BR›DÒ‰ÀZ|£I~êP%½AÐzÄÿ.:Xendstream -endobj -1333 0 obj << -/Type /Page -/Contents 1334 0 R -/Resources 1332 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1323 0 R ->> endobj -1335 0 obj << -/D [1333 0 R /XYZ 56.6929 794.5015 null] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [184.7318 214.5925 233.4785 225.3769] +/Subtype /Link +/A << /S /GoTo /D (dynamic_update_security) >> >> endobj 1332 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R /F63 1063 0 R >> -/XObject << /Im2 1049 0 R >> +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [369.8158 92.1907 418.5625 104.2503] +/Subtype /Link +/A << /S /GoTo /D (dynamic_update_security) >> +>> endobj +1330 0 obj << +/D [1328 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1327 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F63 1068 0 R /F62 1065 0 R /F21 714 0 R /F48 955 0 R >> +/XObject << /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1338 0 obj << -/Length 3258 +1336 0 obj << +/Length 2683 /Filter /FlateDecode >> stream -xÚ¥Z_sÛ6÷§Ð[噈Å‚—§4urî´NÎQnÚ>ÐesB‘ªHYu:÷Ýo P¤Ùé$™1A`±X,v» ŠOüç«&35I3•hÆõd±¾`“{{Á=Í,͆T?Ì/¾'ÓI–dF˜É|5àef-ŸÌ—¿MßþûÍÇùÕíåLh65ÉåL6ýáúæGêÉèñöÃÍ»ë÷¿Þ¾¹LÕt~ýᆺo¯Þ]Ý^ݼ½ºœq«9̞Ù ﮾¢ÖûÛ7¿üòæöòùOWó~/Ãýr&q#^üö›,aÛ?]°DfVOöðžeb²¾PZ&ZIzª‹OÿéFÝÔ˜þ”¶‰ÊLfZ$™Ui\Ë,a´6KO47¶×²à1-*Ôr^u³n›×íªØ^r;µÍn»(fæXÜòÄdf2\äD”@EDáÖ$&MåX–75œ@ÊP¦b[ç]A¯½xî åCAn”OË•§zðäMíUÙvÅ’ÚeÛ9Rˆ`6ᜠ—?¯†#é­JWaÚ*/«Ö ^/#Ë(–蔥ž|×3$‚ÃeYbE -ÞÁy’i-ž;˜:‘,“žoÙ’ù¶E—œØ®7“e‰ÊXö¼ ©Î[QO6õŒàc3‚£7pôÏ -ÓSE¤Rö¦¬‹ók‹&`­7 -›L -û&ƒ“ji¸ñuºœ)¡§×+y,‹}ëYº9ža»)åïŒ gp0Ú=”žÙ²X廪ó³º&b!3ðš”AÛ[`ÝDúð`K ìo»/ÝnáèËŽžƒá-º" X’ŠL{FO°óÈZi¢¤ -4¿3ÍVN3zˆÃ–‹f½É»ò®¬Êî Hùy#ÔÀÖÀŸ7ÂÕ3F¨H_]¹z:gv -¼Åýüò=Õ ës  ­¤}A€#}™Hm¸×粓\—5djº(ØÔÓªYäõá‡òå’ì®m_A´ti³éʦΫê‰Þýñ#ÍÙ4ÛÎïËÊ3¾+…œ%h™Q¹‹æãžmáÖ1éôæÃüúÝ©w rä÷E nbŒœÎÕãÀ@NO¹k;?´Ùà<® ¸ìx:GuËTùchÛGtQˆÓßµ–&K¸ÊësÜocv,1ˆÊ€×_0@xN<ô‘Û-ª|‡%¥r@€O'¦” ëˆ †2Üxö ÿf?#SˆÈ¢³â^ð)ZËe&<(–k;@ªuQwþµèüª)âÌDYf‚"¾Â 2m_a¹³ h ‚œqi°’—aA[Ÿ  hd/w.ær‰mË岨ýû%ŸúfN_|œöh;AŒÅžtz—·Eaðe½¨v˲¾L#a=ŒÔÊ|½:XÆÂ‰ Tü÷%yMÒÄ• -I¡4+$XÙÑbB%,Í‚h°óÈiòÄÓ)#ÊLj4}€ñÙÇ€Ú£þC€¹Æ¸t¿ÛæÔ‰=UqÑ2’ §SHŒÒìkr\i]Ênã9.ƒD3=ú,/šÇ€—o†cV³ Ü ê¨%ÀÜA¯zÔŸÝ@ª¬‚ 6u*º(8ÁDË?>„Â_1½:Ñ 0•BÛ‰,±\¹ýLþœ€ã©Ìå`lÔv»=hÁu|½“ØÓd¸­Ày6díöeÄ(äpô;@Š$µL9¡?5B)×SÞl*pjRd€Fáiª²ØRϲ)<=¸5ÚÝfƒ®¨Àx|OÑuÎÓðÅ#4eK ßF”÷ŸMW—’y“ƃzÃüíGò§¶Y\ -6ýŒÕ@¨+TÀ²4r2<èo³ie† u(¶¾Í²g’wœ¡Ggò¹lMš&Œ«겞êµbÕÁ¶†¼Oó™@a”é«@éfÇ2ü\~Ž!ž€dµ/¢+¨VÈó¼"øqQ -€MU÷ô±ÓµC~j›ºÓ^Õ«CÂéH¨¹á‰Ð{²1ù%›nHc9cŒ’&ä÷’&jý ud¬ZhPhfûªçQÍvËÍ S¬Xê‘bzh³~û‘êÐÞ†Ü$lÊåK<Á–ÔŸ_ËÓIiþ‘”3!³3Å,š»UGò>ÏÝBÊ“±ó\¥äŽW—À+uléi³¢8Wåó £“,cÇU2B›6€ÈüÉAÉášÝCÞQ‹_¤s© -ôPŠ‹-—€ÀÓA!’†rÏhtëƒ5Vaz/À )–LN?'ÕˆJÁè8äŠÈa™ƒ8ÜÞûˆq;¼ -ô³á„S?>åë‚D±ð¡„óö~(³d+Ò‘H'€ÒS½ HÀ4‰·e&Ú]ÿ¡Ùå)ùc^Vù]å_ƒ‚q¤/´]m뫦%j—³é»P’åëMUxˆÁÄíh…Uƒ©9¥Ž‘ÄÈ®Ú:¸»OÁv£Ž43Óc›×÷5¥H¥¦Ñ€7¯©ý¿×±Èñ ![˜Ä^Ÿ,¡±Û/1  %ŽŽ¢ß%BTŠ^ÃRpçuØE΄=ÜÅ~Â]ì_¹³hÖ±¼b¯°ý}T¯‹e¬ÃHc•¯Ga tK\Á•ZÂ_ã …£e8œ#ö;µ´ÿ‚ÄEó {$s…+ŒË þ½"0ò©ôPñÑ ’ù8®(šDöç°F“ªèÜÇ¢ 3Þ.jõ€ -Ieƒjâø Lm*Í?Ä_`âr3Á8á ìi {6äpxê§dRèCü?wÌPU±ô{³që,š¦%?„ÕÄBoéü:à@—da©ÁtE–Žl„ƊИZP”tø-WIÂÓKnËÊ—•Ðù„] 1ö¿w1ö9ˆQTÂŽ–;åîµ9`í.é¼t˜î,Ü´¯ý¼Õ@ðlúç®Ø>ÅpbO.¨ Dº’\qØ•ÓctW$'Žô{v/OƒYæhï†Ù>ÕíÞ ÐÞ7»jI“¨j€¾û¢r5‡™ÇŠ$nËÕh—¼·&¼xàýåÔ¢_ºèvH{÷†'iÌÑå÷yYãMWÓ›¦+4^"_mIynQ±éÜyÕ6D~ç‡hŠw -„Â0½©+¿²;Š8Œ/Õ^„µkŸ‰IÁÐ%Lú é»îqGÁÏ]k(‘X!Æ8ssØžâ5Ý@¶Ä·ÛøâÕ¾«—¹³cèr@ÏCކ= Û¶xí÷¡xó!× —=º¬¤£iËe± ¡Þ'wùâóž8,#ÕGP}Ó´myWùá¶„¼¢¯HútbÓýå?¹ö™p):2_t|ؘ„„ÌäÓSÛkÿ!³õ6•"ë2zÄG•ÉüÁ'¹ã;TŸ÷æ÷~ÔeÛÍ®óúÉÓ‡¥¡í ~ôqº)€@#$Ò -Eùf»‹¼ -Ùóc^í´C‡/Á‰*›î -ÏÑרˆ˃ë ZSme %ƒ‚IŸ F"(×ýµûò©L*‡!׺ókúÛqh•5è+÷/ ÎØ—‘ÈÕg©L·BÅ.‡ÑéXð&‡pÀ¶¯˜ð%ìš¶êò#\½öÒÝ—÷ùÝSWD‹`ÉTbGÈTûCŒ¥Ò$åýçK:ÝÖ…k(Ùséµu)¸ôeôÇ@cÿU®wkzæûøºnvuY¼í?Cù[ñÌ2³Vp±=Zß+úrßÚ瞬 ÜJ%ÚÈt™QBÆåÙì‚«¹á<ÜXtù¶ëk¬Ç“ $-¶åæp3µ!H´ì¯{ÛòËIE)µ„ÄŠ~.íyúUW\ø›‚³\=ÇÙåéõ•ÔÎ'=,ªüصµHÞˆùOÖõÉ.2ÈÏ KG»x¦.îé#2ŽLã„ï¸.v¿0á'U:Þìs•¤9ýF zA†Sn(Câ\ºt¨ôÆ¥•®ðÚÇYA_‡Bï!ŠÀkåÐ>…NœIÐVØR£ kR.F+xˆ^k!Ðõ†š~jÝA€z“8˜XÈÄšú;„/ËýµsGý­ã…-äðt‘ éÌÙÍÙð§LO?ÔžÁÎ}CÅ­X¤ Ì©Rš -G|¡ÚÓR)„=eÛî²c{°^d;»Ú RŽ.ø Æ;?†‰g>ƒ'P¥¾ô<Ð<÷ ÜѸ8Õl‹6pÁÑijkö4'‹Žâ¢0ø›¥Ñªó€exwIÓ—¢G4ʲBþ5ºÎÙ­7çL$„º<½˜ ,³Ö¼„Õß>'ç~Ó%<þ+¢ÖYúæß{~ UZ+Î@8ÅŠ× …‚ëììmÝ©èÿ½°Ñ½endstream +xÚ­]sÛ6òÝ¿B÷&ÏDA€<¹9;uç’¦®;÷Ðô’hK‰tDÚ®ïæþ{w± ˆ¤(Ç7Íèàb±Ø]ì'(9Ià''6‰rzbœY"³Éb{’Lnaîý‰dœY@šu±~¸>y}¡ÌÄ —§ùäú¦CËŠÄZ9¹^þ>}÷ãÙ§ëó«ÓYš%Ó\œÎ²<™þpùñŸqôx÷óÇ‹Ë÷¿]=½¾üù#¯Î/ίÎ?¾;?I›IXŸ2…# ..ÿuN£÷Wg>œ]þqýÓÉùu”¥+¯L +òõä÷?’ÉÄþé$ÊÙlò/‰Î¥“í‰Î”È´R²9ùõä—H°3ë—Žé/SVd65# +LUG2±Î'&s"W0… +üœ¦ºZÏç›3ùtSÌËMƒPzok|šé|]»§.¨JY7ý±~,Ê*êL[5mÖÕ‚©ÍëvE£³œžEµùõ¹Äè¡Á+o‚7²{v”øŠ þÈÉ­oŠûÍÀÛ:xÿ&8tÇ€4ð†zÔwsŸNªüyßíb÷݈…¢Ï7Åâ˪ޔn›¢E~cç€4²sÏm•V§ƒ­{n«ÒtZÐc³nZÕ7<±\’k6MÀmWEF% ØùüøqzÅ‘?COd±(ïxüõ¾Ü­©½/û=™Â}ãÉ*R`êÍCØõ¶—‚l.×}ÏÅ žN¥”S6©_ÂŽxÖûÙ”6¦ ÷ƒ…Dkœ36£ÞÕÕ2d‰¶æý®Ù§÷4_gÐ&1ì Õq—Çê‚ÆÂdf(f¬É1œ § %{,pd.2¨w’|«jËÝM±(›‘M ·¦à™*'&!F”¸ÞSNè0qWïÚ††d8Û†eÁ"pÌzô‹›Ç†€/c4Š©öê@?’ÂÄ}CÉ×o>¾´„°„ш”††]V3¨%ŸEÜžQÄM&"£Î^@Z+a• +˜mñžƲˆž´I£3¯Ò0¿Œˆd6½Ø È|™³˜.˜í0ŒEa”´“,·Â…}Iyš +g­/Ng‘â¬KÒJ[aR0ëˆF™²…œ4dÒ@õ‘äê;2(~‹I ÎáàÔ{LúxÌutÁYæ ùR 0æð#2 >çŠNs¥ÍTŠ$Ï6×s¶ÄB€™? ò_'dqê5쇸ù ¥ô #ëW¾Gsí9Sàb!„륈õ¹ÃòD{i>@ð[ßmFÝ30r/q¡TX«­X.Åæa¯-ûÓ ‚Ë?‹-pñjÄ‘fÚ-Hà}¾÷ìÌr›ÿ¥Âû–Þþ÷v¬#¬$íáj;Ý£ö ±Y ÍäàíµÌ{´㳂Ҝ +o>(w˪ànN±i°*¶ Š ¾EŸ*@ü©ä¦f”HáòÍô —Ð@Œ ýÝm’aXL ¤¨ŽÐ¤Å:Äò¡Z·Åbµ®ø”×ÜçU%[&è.8Fq̲YÛ£fº/9G 5ósúÿ¶ÓÀÀ3Õk<˜žS… á»Úꘆ™XÂ^~zÐA=!„°P +cR×—ùz¼æw“ô´³‡|Dà,9T—½þ€û n00¤­;ÑÍW¡/éF=l*b$ÔšE‡'t8§rêÃ]—VÔ*6A¤UÝÑ*@ÑÔ½b X²1võ66ö_»¥ca'D¼ˆŠÏG­êßx“qqX Šê)øþ¸ëw×xõ&fP%vZðD¬ˆz;°vÏ× i +¤[Ìà™Mÿ~6g]ЇÉ؉Qn¿ñÑŠ!Åë¯Ì}OÅo1©¥È´U}&U œXnYÝ_»gÓ¯(!j%_ìxP›žãap‘9»ÚFp0‹e]²aP8Ð}§ +f–Ü;È®ÜZåNèTf}ïhêÅv•eŸ† ^ÐMƒõ¾@£èÑôÚ÷Š-U¾‘ˆ,ˆEÄ4»á WL®¾+QrAxmž@][¯ +¦SVõý-óuöé’1ïï|,I1œ]Â&ÓÏI–D[@¨}" Ï>[Â[Ô¬Þ6õjèÕ¨ø•vª›.ýô;‚¨L§°“ÄªÅØSødaY?€DÑÐRJ–.¤ê.Ëñ– ª‰–})eôz>¿Ÿ£ä‰‰¨MÖ•— ¤Wã#TS-£“na"èÖC{ÚdYVƒ‹c³ßs^®ŠP×Ú/³œAl²±¡z@E3~RÿM(ûЀF#óÖ‡ñ®CJºëØ»^Üoн“^cx “ ßÂÁ€îý b„ô“¾J¯Yp†¯åh½¿å’oQdç…¹ó'î [¼Ž§&G<´« +vÑ~=rÐC¼ê^mܲmbsQs™ô¸*ãÝÁ]\³î]š“atj16£Ý Þwj$ŽFN##òþJv÷ÇyØÕ¼¼“pF(­ŽuÈO·üï$ü牸ð¹^"Mùf9·oÞ¼VéÛñ^ÒN¨$‹í„J¸@ µŠ6 +Po–ãk €`}Šoy.hÀ¾sC_‚IŒ´ô‘Å#k¬ÀH/®Ñ¬·s œèb§âjD¡Ä#ôû¬>é´·h„o8ð†HYprÍŸE= ¢§WÎðW&ô¯?iªw2Ú ‹K¢/û9’Š÷ñJD(¹/Ž|AT.Çì†vT˘]ŸºtZ‡»‚/å3IìœÆª¡ú=Gð÷›õïQÁ«ÐÙo¾ïá´<ÚÙ${yŒÈñsذ­‘ÈôAO§Ã­§îÜzjÙé>H—ŠºŒ}Œd]ê¨K-åLÝW®Õ‡u£ÔÂÆëãÙ˜<¤Ët·/EF;yÀ×{:JkúõÂclbú +Å‹b>TapXŽ}èÑ"Í2ÓÙ™RáCýŇÖL+<·Cò¹ʸg…‚BŒ# @|H˜)hY(ŽIûvg ò× +dbÓ¾_óGqì¯*ø‘ODÉ$ÐùÛKØÿgCCš³6ÿؤ’\ØÔ™ÀòŸ™!çñÿ ‡¬ÿ¤Eendstream endobj -1337 0 obj << +1335 0 obj << /Type /Page -/Contents 1338 0 R -/Resources 1336 0 R +/Contents 1336 0 R +/Resources 1334 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1323 0 R -/Annots [ 1341 0 R 1343 0 R ] +/Parent 1325 0 R +>> endobj +1337 0 obj << +/D [1335 0 R /XYZ 85.0394 794.5015 null] +>> endobj +370 0 obj << +/D [1335 0 R /XYZ 85.0394 625.1831 null] +>> endobj +1338 0 obj << +/D [1335 0 R /XYZ 85.0394 599.8772 null] +>> endobj +1334 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 1341 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [471.1233 402.3147 539.579 414.3744] -/Subtype /Link -/A << /S /GoTo /D (query_address) >> ->> endobj -1343 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [389.4645 133.6118 438.2112 145.6714] -/Subtype /Link -/A << /S /GoTo /D (configuration_file_elements) >> ->> endobj -1339 0 obj << -/D [1337 0 R /XYZ 85.0394 794.5015 null] ->> endobj -382 0 obj << -/D [1337 0 R /XYZ 85.0394 458.5915 null] ->> endobj +/Length 2990 +/Filter /FlateDecode +>> +stream +xÚµZßsã¶~÷_¡·È‹ß${ONâKiœÄufÚIò@IÍ9‰TDÊεÓÿ½»ØEÊ”ÎwiǤ `±Øýöh9ð''Ö%.Wù$ÍMb…´“ÅæBL í› É:³¨4ëk}yñçw:äIܯzce‰È29¹_þ“2É­U¡W³õ‹ò!”o`BçxUÎN ðݥ̦è¿ÐRTKzÙÖ»–tögÙªÞÑK³_ÑAÊ™i½)ÛÖ/ßà¯à.l„ [.ŠàÏ%©Ýü@-ƒ­FÎ2bªÜÆåÜÜ^}ýõÝ1~Àz!•!¼RІ$L_ƒ *ɳ,ÇY7â¬?äKp0™I”2ò03Zyuûϧ*@bÜÁ«•`. @¤À݃,¡|ED™{zb䇤 H"!‰H2¶ÇÎd)OÒgÄ"™¤mgB@Rä.?+:OeŒbŒŠ<£¨Èó^Th +wÖõ†¶—€B˜Ûø£ÚoæžGX…ðˆjÜsK13[ÔÈÞ~/I Æ}ðÃù·åâ=5gÓý–ǪXÀ.ÑÜóVdI®­î!N°‰–—N}ˆƒ"S ‹ƒÔ…²3½d¶¼¬”ìÂøn8}:S€›¢%Éy¶²Š*cp£>tæbb€‘³'3Û/·3œx 2‘mt/«Wq»ÿL´- z9¡³‰H­îÏçfì6%’,wCùu Fš‰û à‚"z.ýªØ¯Û†~Õ+zŽû p.µR¾®ð;À‘uÌmS32ÞÉbi;ìd½T^ü_¨“éO2dN€âÙ¡ÖÏð·^5HS©\Ãî@™„]ê€o·«×‘uÔ.ËÒ|¤—Mò4uýNoiwdª“ã(8öÄKóŒN ²Öÿ¯uÇTNæP3•©ƒÂ™Jw®òX™ÉOÂ%Ò^‰•(™æCìyý˜l3àŽUÞŒaœëc*RâåÃÒI¦]Œo®"0üâÑ/Þã«›–+ˆÂ—zë7èÂöæª 5QQ«Àɉ͎Ãâ©\€Ó60Qmb¯‡]±Ù"B[Y5<\Ù( ‡xR’´»šýSl|ä—`´l¾àI¸/À+v£_„Ôðâ·~ƒdyZ¬Iv# + oÀN&çhxÉK¿L Él¯‚ÓbØ*8¶OE¹.æk?¶M9dhêìÇ·)U™nLáCsÐæ€dQï"ŠÖÕlï6 T:‡`C¨7oq÷R:B=—G8ÎD8o¡ÎÈ|%…*¬ÒQ st.ªŸ«!.AÚõ{‘^/þMæCø*¡ÜÒ›³VÛ·ôþŸ·ÃQãéõc¾<úöaã¶n¯6¸é¦xq%R”îÜ%2M‘j;¼ÏYÖìW¨Šy¼(á8·þ@ò5Õ‚‘"õýb¿+ÛOËÌôŠš ­0%vj¬\þËǶ­¯–NÊO0¯Ôÿn^”„6°Œ†—C±Go/$2òSrœ–@ùTšói ϰôð,0ÝíÊÛçÿESW€aܱ¬»ÂU +z§éxú²ñz/x¾ 3bˆ-Š@»Gï Ò;Î#ñðOœ [“à°ñALÂçîÂm$2—H( [¬-=¤$khôúøÂ|鱜#¶¢„¼ è`ðŠžM½aId4p ëDúߋ͖™ z!‡¤G„í§Û›`Š+ÆÈ†~0+€·ªnéò¹~弬½;gžIY%\:X{E&Ì×>Öû8=Èqúí®|œ 1ˆŠ9Šb"-ØÎe^×tYÎÒEEoHB‘ñ…#ã#žAmP‚ÔÊâX+`~î +,ŸÚML){|®7¡ÈÑ¥ÒÕŽ¿~/€vú–špOQo½ÓT¼R0ú0þ<êV´°[æpG‘oבto}C7<”DZKfÜT¯÷”±'CbC’È_–~]ôÈ‹"¤ÅáX±»´ÆŠy Qå—ZT¬ðžÇøÛ'\){g_1ɉèx\-¹è<,ŠjxWÙ+Áè,eu„?©aßoúxš«§’¢µjÔŽÏÿà6ãU·>¼jõ wݥϫG}ýµF¦ðޝ5F–AÌ}œæØ×WƒWy÷õOäS8ø'9î4sÌå~AÌäÔVà}†tÝ׬Ê!çÐ"0«^ßÀ‰¬Ã{rÏQ“)Í~Ë÷¯ ,H ‚ð¤³)¶uWÒ ð À~¤î„òˆ³V›ã $ èsg„ oF( ŸíBã2Ý~ Ís¿(^¡‰vyßb‹ÈA­ äP!^Kž‚µ\\”ˆŒÚ¨²€dÎ:£ôgÀcQ˜?T8*ÜIº6 Þ¤#œqX q?|ö8ؓáz ¤kÙØ!ª„­CUú÷+è±-vÀ|÷ȇBgÞ[h¡#‚‘'¢KãmŠU¯¾¶tÒ¹sQ3c „kæÎßÚ½îþò-£"ƒ( uÇ/ • žJ›#̤ÐéAÅ.œZFÙ9øM7|O!Â6øÞ.“TB&ràW®ôÄ÷qRšõµNï´Ngqß`6ØOž·¡Ó1B@$O\ªíЊ{ÊÎPY8;ÑÍQÆIyÚ;pQ÷¼wzZg¼µºhé> endobj -386 0 obj << -/D [1337 0 R /XYZ 85.0394 213.7989 null] +/Type /Page +/Contents 1341 0 R +/Resources 1339 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1325 0 R >> endobj 1342 0 obj << -/D [1337 0 R /XYZ 85.0394 188.7485 null] +/D [1340 0 R /XYZ 56.6929 794.5015 null] >> endobj -1336 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F62 1060 0 R /F41 935 0 R >> -/XObject << /Im2 1049 0 R >> +374 0 obj << +/D [1340 0 R /XYZ 56.6929 769.5949 null] +>> endobj +1343 0 obj << +/D [1340 0 R /XYZ 56.6929 748.5275 null] +>> endobj +1339 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1346 0 obj << -/Length 3419 +/Length 2666 /Filter /FlateDecode >> stream -xÚ¥]sÛ6òÝ¿ÂoGÏT,@$8÷”¤I/6í9îô¡×Š‚l^(R©8]ì‚2%_î&ãp,X`¿!y-àŸ¼6iœæI~å:6Bšërw%®ïaìû+É8«€´šb½¾»úöÊ®ó8O“ôún;¡eca­¼¾Ûü¥qß½ùùû÷ßÿzûê&ÓÑÝûŸ?ܬ#¢wï|KÐ÷·¯~úéÕíÍJZ#£7ÿxõËÝÛ[J™Æë÷¾£žœ>gˆÞ¾}÷ööí‡7ooþ¸ûáêíÝÀË”_)2òçÕïˆë °ýÕˆUnÍõ#4D,ó<¹Þ]i£b£• -=õÕÇ«'£~êÒùicc“èNWM’åS–q&% eiåj8åD.rÀÂSÞ}ÑU¹Svsg)\Ҕ䳅ÒÂÂj²0Üj¦œ/|÷ààÄsíŠ/ÕF±kMOp»Å¯ð[dT·kO÷a~çŸÝ!ÐâÑcçàâµJÆu6n[k¦]uÈð·ïôô€”~òÌsþhx‚Gœ1¤elµ’ŒçR°¿^©<‰3›&×+)ãÜ’kÏ‹‰ŠÃ´Ñ†Zuµ«zÛ†¾#_z¸ÖŠ{Ïœ6Ñû-õñaL'™¨è{·ÛßÀQuŒÕò@]·eÑó”)íŠ×v_J×ñ¬vXƒùŸÄóã·þÍÍJ‰,ì# KTÄL=VuMж¨jm£Ç‡ª| ^¾¸”wFýñÀPíŠÏLu ?²™FǦXס¥ïÞ¶íaGï>|gU%œÝ &þ>Ìó_Ü#Ÿçz¥Ò$j÷Ä¡ï@—èê'jƒØm5Â**§ ÏcÁ8xžøõçV5÷Ôò¬ytÖ€)j¸"^bC ¬ájŸÄÙ3¦HÔø˜ÀÀ7‰Ê£õ…LÁEûo•ECsÒ -ùãìCQu<ð[8â‚¶ÝSÂFC¬¯yÃâǃ|#ч‚!¯/ -å²eü]áÅ÷óDc¬„1JLŠò¾pwOíERÖ¡¸U0¹'†%O¡dÎèE³Y )mœk­çàÊã¡«>»Û«b+šŸPYW®é»…U+c5S#ïÈV Üi±‰ŸyBv7`ùcm…ºì“¦Xç}Ò€…»ø—IíºÓu3!lþâºiaÝ)ÛVÀ Jçë’«PÙÄ%A£9îÖÞÖìža‡¾Ñ‡iƒUò$¼[°óŸyT¦!¨l¸52MÆCJy7ã&Fe•©X£ÿ¥Ë;6^ÚÝfáš z6«uîJD]ùKaÆë•,o‰ú¢ü´gdq ->óòÊiaå)“ Å©f¾4(Èóx«ÐŒÀþVáë7ɸÁÁ÷‹ãá~=1¥HCI1.4ÞjÑr¤!b+ŒýêHã¹9Xi0&M è>ÈršÑ³L!f„ X}œìýÖuíñPònD¡Y2 `e“4†ˆz¢*É£m Îý‘Ù‹,# uÁ"µ=6%ÇÆÞÏÒw’¢ž—%câÔf/øÜ)ÖY -Xç¸<#a^Ø@@ZØÀ© p^ó|tÞ^hdøì56(”DˆäW`ö€oœä›lDçž1£´e’È74x¸¿&àvÂ×€ÿcÏéc|Ù¸#vùt?Z¨89—OwÀzaÏ©QPâq³2VD¿=8Þ Yä3'Hñd"ãT›|n4‹ýÞëf‹Á, -z º½++¤áÃh쀻ÃxÙª¨kwŒåîtZ[o\×sç¡hº¢ Á(ôx%™¢;Ƨ—­y¸8öíŒBéíÿBnD¶e×~v›¯÷ßRdhóÿ!ò⥪î$Ž(ê®%h=8¤Ÿ43S²§LuõWÛ0æºèªî¼Í"6Öæ/ØŒ Ö›°™‡¶ëW4õUÝ­@aŸ™ -â,KíåM X »˜mâÌX9߯{<žÔû™f‘EiË’‰$v„BÒÀ ¦“?儾Ȏ ÒD쇊f”gBçšé~WSNþ¡íI…RƒÇ4s ªvûÚ퀖W’¯ôÊ€øi0´otŠuþF¬y69Éçn|£B·0`-ìaîÒŽJÏ7±°Ëñ’¦; ×}ѸöØi53AHuÛ~:î»Y'gÑ[R-® -žôš¥ÊÎÍÇÚ=5nÃr¡ì*ŸÖæ„b6ìÔœØ3…G©òØæ2dá°/X’DŹzRuIôÚ•!€8yD„&çà£Ôaw4 3:‚ -ÜÕ:ÖU?åj(ºbXå¸F¦ -²ij…Î -œxÊJ’ÁÇîDPûSU·ë§ÞuXiS&ÌË¢ÏE} $¶Ôµ\]‘ƒQ‘>+…œ/wdDjI>+wÐRÞãZ”°c*7ö¬¹½q%kA58dŠ"I!áJÕ‰’£邌õ,ì*¦y&Ŭg´=ɱlþBN>A:¯ëÉ_S¹?«ä@dÂåK+HÏ—žçäc3[û.Ôq'µÿtÔp€©èœžj8ô b ðÝ›_¸³m7„ ùPdkÆÙ¬f<–£)ûˆù3|~š+úWDiNI›Q‹PfqéêK…˜DgÃÁ^._úë­,R›U×–ŸÜ²ÏÍåõgaùSãž+©æëûã„Ði¸m-é¶±/„îC0Xª}ß:êà -ß=Mó™¡HÈð¿¡f×oªa“E®/ÁRZ‘rÌå—vnà ª8~׎H®«{6ú&VêÔ´¹¦=Þ£kMž_còIR…]^T$ƽ$CŸ¯Fl‹Òu‹–,‰ó< v©)v‹±$&é‰ ‰i Q‰óäÛæ›ºD \Ɖʟ¦ 9¸`$³`ºÎkŠVC1®#Î>WGÔnwœ8HІDȹ6ù+óïÇþ¾å烠Èüyt\ù·~‡¨HñdŽ{ñ)Ó„­;tü<ÀµÓtZ;MÏTàD -9èàrLÎ*k6‰ÝÇ-¯ª Uâ48­³µZH¤À}§ZÎ%J&vÉÓ ŸÔä8˜2=5›z\Y›3Á…Ì1~I‚Yú/V¬éñÏ/é‹_´f0¾©õê#g•¸8ç4:Ü*M{"`Í{Ÿä]ÔQ5#wV@pŸd'º·=öGš;¾ßåq¢’|R‚¢âÜXZy(ºàtû¾fCî¶Hf þbž^ývcðtÓ>žÏ¥$h‰™¼l—§Xçíò€µü44³Ê Ä 2ù‹ëX ˜‰u‘Øt¾ªïj;­»Œe8à£1DÏ‘0îc$mé! .Ï„j/ôœV{¡ËsŠq_¦üýcŸA–RбP¡ÈG©ð¥•üÄœ U|~,Å/??â+mC_ÎúZ–@ä¸|‘J~èMÂÃ,†º©§Ñ>åRôà Rì=,9èeR”&‘û²¯B±Û{Ö‚"Èt½X›^S ™þU€Ñôþ -ío%`ÀÑà÷EïîŸh€Ê ÀÂŒ(23>ÈÂ4Rp‹-#áë¿ÛP]$ÑÑ+B vÆðOà+æ|º]àë~b@ó]Ñ Í^¬¹û¾–ÏO ;Ǻ¾†£^î}Ð ]Tñnw„Ír&Ãí"Ø6¾èÐ#K’Ç«DàîîG^j¼_SÑ+8_úÇQfˆ&}rO¼O¶²vþX2Ì‹¡ ô?Ž©£r6q2ýI ö†tˆƒ]*Y­CýØtÕ}CEr飌{w`‚h£Å2w—ÿC;ŽS’…_e¨ðs$Ô„ZFØû<Í¡ŒÉ†z"]±chjm±í_AŸ~YÌõˇ -nºq] UðŒî¸ß·nìÚA8lx›AH%ô]Ó«“¥"Ÿ¬’ÚøûU&Üô¢ÎíÛ®ê+J>”š½"B¼,Œ'?½¦.° °ûš”0ê“7 ©†¶g:í@%¦ž÷L· f°:ØE$öbJTíë°ÅÊ=R-ÎýdPv•Ûš,_aÜh2êðÒÙžIâ1—8©ozvêè¦ÓÞÝ-Q'©ˆ”}¾¿¾»X€"eJN›tzÓÉL¸»‹Åo?@YL8ü“Ô0®¬ž$V3Ã…™,6|rïÞ_Ï3 L³>×ó‹ïß©db™e<™¯z²RÆÓTLæË_¢7yýa~y;Iã˜Mg&æÑW×oiÆÒãÍÍõ»«÷?ß¾ž&:š_Ý\Óôíå»ËÛËë7—Ó™H€õÒK8±àÝÕ_/‰zûú§Ÿ^ßN›ÿxq9ïöÒ߯à +7òùâ—ßød Ûþñ‚3eS3y„gÂZ9Ù\h£˜ÑJ…™òâãÅß:½·né˜ÿ:°Œ)nÄ©’Ykô¸Z§¢X¬•=-‹Öqåɰb(êp¼1PÆÈÃñJ5‚Y˜Ãóµœ%Ž51Î<¦ó½F;NËL¬2 +ÎŒ’`¹ã¸™ÎbÍá]ŸÈÔLK@Oª¤óÌäóD0®­UÄÔ£Ý^>pß_määm ;šô6Ïú’ݦbÙì ã‰6í,ž¯óéLKeËå.o¨¨Ùæ‹âWÎe¾¤·EEÏØbÕ—¬4‹ÁíÞ Ÿ÷ùPÌ£§YSïwSÉ£EXÖ7(N˜T:ø®Þ¶EíÕÞŽ} XMê îêvMÔÏo?gV-QÀŽƒ“Ywœ¸Í7À'Sl3Q‘7Sx¼Âé8ºC#÷-ŒÛ¤cÞ:…<òóÙv[â2÷®®Ê'Ï^ÓŒ³'Žu@«X°$—Șá&Ÿ¼Ø»Û;!fð6I£Ýü ›®74ÞW[/ó¡(ó{tNw;`ÇhÔ6a1˜5éGÂ׆±±±Ì â«C_ÆLsûmd%1‹ÀÞ—ï4¬8•FL*!¦„}!Ä|,ô7M#1]¥ü¿Fú’Ϥ‘X(¦´±Îäu™y~auX`‚H NGäžÂhG3Ë:÷üUÝÑì·½Às3yÛÕ= KÑéf!·,<Ýe/t¹uƒ0¢„ÐÔ ùOø_Þú0="ýSþ:àüùCD0(wúßÙ©_q*D4f þb¥5|¬Tü-C0µä™o"}ÉgBÄpňâþcžSRÎʦ©¢ZÀÁ´Áv—UÍ +³|î*èùRš@³¥ã°ÖÃã*m!ªÏÑV¬^ªÏ€®Œ_q:<ú'üu ùöá1Ä¡äúC1ÒÏkHÔR:0lÁEÌìe8þYW95Üó)°Dî€ò]ÓÃjGAib¸3  º¨8ŽÖYCÄ&_¬³ªh6~Œ >·eærØW¨8‰VÙ¢˜ +È™mÖæ4õ‡3Å1uV¸!eZ eQ›¢õok¯„R(²oê}åë•_PgKÒÒ®³v,wöt¢7¼ÉH¢|RDóÔ´ù ò<̮견]Fw«\çç¥a“õä¥Ôôü£s|§ùSθ4¢ bkíøåÎ3Íú\§ÁÐq¹˜‚ QÔëÆöWZý‚òŽkDû°™¶L&æHýÛÛñÊK™b¨dÝ—õ]VÒTY4-Qî$áíÕÏ Åq*Ò +dXXªl“ÓL“ïFÒŸ<­¥•~€‰Ë14yå®oæWïþAô4d÷yã;qÈ7#¯Çu^å®úÃÕ·i|åÍ[Óì¢Þ>E˜°¼>§6^!\óå+,ö©"×t›ÀROÊa¯0@¿åKâëú¾óš®?Ž™¾¨Ýs À„ŠdêÎ>c¢u^n=éì€g^5ûέ8OÞ +vîîH»½Amñ$êó¾X|€¡åº$ßû5Îð„-f%^šÜ€¶ÏÆ®7.³DbŽÃë‘6îÒ¡Ý}¨%j“=q—ÓspcĉÇÕ!•g‹µÏ‘ý(“œ3›hjÖ0¾Ž‚Â@½HM(þ=@“ +—)Њ¼òê)áE’ÕŸƒE™‡«‘,66oØrÁa+uŠVѤW'Ÿ¯²}XW4if>n£«½€eÏ!â”Iiâ/uDW\ÏK1’‹†TÞ¹·­¨h*Ñ õ*{Pé¢ê¹.©!]vÔ`ùÙ@Ü¿"±…×LXÄ™Pµ+–tm…ŒoHǰv„C$Puy2ø€P×¢ç¨cžL!­Äg©Œþ¾Fw(ÍGÝZ¦Ñ÷‚ÓyÚû1x„?ó­Â"í¦ê D[iÕÐòª®Ñ*°¼¢ï”@¨Ëëšåurº†˜†AíÒš€ðuã¹iÆ2¨SòË (™Jä‰(Ûç& èFÄS+CÕ€™®j}ˆJ­ÜÅÍ›yf<8NmSj!p®‹7ÍaÎ º˜áÐ̰—o¶­o-|àõ+håPN‘Æmc>[dTHÂ*à'»C\I¡Îw}®ÓÝGÇ…¦o²ßg¡ùÁ#ŸµÅ&ŸÕ³V$I™•±>oIÇ5bʆÐ2[ž¤C[®ª;èÝ^‡ ªß‰¦ +ê"~”ªèگ˺º§K¿öù“(ú\€¥z¢•›¢Ú·¹ŸöhJ©Ò¸%ùnSÌ蜰/éíDåò¸å<ägC½>…äDt*"$‘k¸5tâCqpÅf¿¡ÁCVîó¡d™zµÙSOªæêHãy4‰®‘*}M=®3h +\£h*–å8šb& \ÇÎZÒq˜2D“€ä’Ê¡-4‰Mbˆ&èøDHXÑé¹u¶×÷‡Vg)×uȲ„qN‡$Mà]%<¸Ä¸À\+rÈ—ƒ+>…-qÀÖÿ Zî+ÌYhõ¹NC«ã:¨ê}û [Pu íÁYS:®[†Ø‚º§ƒcnö­$°pÄ‹@ï Ã~ª’îJ ¡l帩ÛsTá—¦Õ/ |/Ô]PÕ”…¢Äí +¨?y¶J2(,/d«>×H®ÓÙjRÐ6A=8oJÇ5bËRø 792æ)Ťçƒ|ÅÅ!_qAù +ž#ù +º|Ŷh­ËW\ óðBÊå+îàå\â³²Ø` äÿ#gAˆKõRoÕc: ¯Àäšø|Wdå “{šíð Û1ªbΤÍYýÓs˜Š “ 4T} >–ÙúKÉÇ x’ LoÁÆzY,ܵܽsæÒËMÖ´.U)Ñ_/é~ O÷áhI µû&‹Mø¤Hº‹Ì+¬ö›;ÿes23†)uh²Uk²9µ~ǼwøÒ2Ž.ñ²ïæ›} ‚±@îúÉÓºO +ð ƒ÷Sþk¤LéÎùßbA\Ùi¤]Ng‰Ž¾óÒª¼}¬wŸhp—UËÇbÙ®G¿p̧VFè(÷îã(’áG_˜ë¬ÚYíAH¼ø³4Þ‚¥Þ<¶'²9’épEÒ½ºÇ5^^ zˆ~ F–ðm ]ee¸û 7؉¿öP†áŸ_Œ€”w?»|õ_‚ô¾ª'L¥©‡»â1K¥M‚Qè~c-7*epUOFLÿÝã£endstream endobj 1345 0 obj << /Type /Page /Contents 1346 0 R /Resources 1344 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1323 0 R -/Annots [ 1349 0 R ] +/Parent 1325 0 R >> endobj +1347 0 obj << +/D [1345 0 R /XYZ 85.0394 794.5015 null] +>> endobj +378 0 obj << +/D [1345 0 R /XYZ 85.0394 460.4475 null] +>> endobj +1076 0 obj << +/D [1345 0 R /XYZ 85.0394 437.5053 null] +>> endobj +1344 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R >> +/XObject << /Im2 1054 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1350 0 obj << +/Length 3385 +/Filter /FlateDecode +>> +stream +xÚ­ZÝoã6Ï_á·s€5+~Iâãv7ÛÛÃu»·MqÀµ}Pl9jK©e'Mÿúû ‡”%YN²haÀâÇÎ÷Œ$g ~rfS‘:åf™3Â&ÒΖۋdv‹¹ï.d€YD EêÛë‹o>èlæ„KU:»^÷öÊE’çrv½úyž +%.±C2÷ç¿ûéËÛËÌ̯?þðér¡l2ÿðñßWÜúîËÛï¿ûår!s+çïþùöóõÕžJÃß~üôžG?ÎlúåêÃÕ—«Oï®.½þ×ÅÕuw—þ}e¢é"¿_üük2[áÚÿºH„v¹=¢“霚m/ŒÕ­ãÈæâÇ‹ÿtöfýÒIúÉD(ª *Ý#`.…uÎÎ2ëDª1ElÖ¸R¢æû»’.ƒ%²·D¥XBh[îªb³øýPîž»bôÏÈ2¡R4÷ûª©ßà)çEÍUõ¾¼-wDÐ0Sµ4#= +d[üQm[îÔ‡í À=DD–P¨Ê°¬-ë=ßG¸¶\6õ +LUlã›Í`ˆÈ­… I)œµÊ#¹*×Åa³gÆzTðT‰8a­™”é,“Vè\egXÁ@‹>sBN‰r„‘—î6:^Ê\¤/œ`&ï³H*-R#õðôÄå¢ +¨|ž{´>#©‰–ù©hÜG‡¦F(cÌ@0øÀ¶ÜóyÌ~ŒÙÑŽý˜ðìǘ»<ìv—2Ÿ3ïý6„A·fXžIAX8î÷Ó:?Š‘Ön^l6Íc¹â™}ÃÏ›’ŸÍaßî‹zUÕ·zÏEýÄÛꡬyn_mK2(™ Ô¤yÇUÃçÉfÏà›j[…Ý< üd¸5ÍãÖt—$^‚ ß#%Í‘ÒöôâFu[7L´–Á¦9 ó(gõW°V&höYëU/‡Pµû²X‘ )hþžñðÈ1Ó‹·'Œo{¼«–wÌFeŒc6Ò\^ m=^‚¯È`h8L¯Ê_’DÕÄhêZ& šg¨‘å‚$_g3“å#‚œ1'©Å„Ð>oNúPçÍI婳+êv]zj,ÖÍn ºŽmвXçò,Ô»¢‘f&¢ñ¿¦/¤³B-w—ä¨qæ™WÔ +Lñ‹n¬ª5Ý$\¨勵o¦|—ÎDîLô^Àc±Á)Ë,ü¦´”4fJ/DžÀA3Ìšö›T + WÓ)…`16p§(òõ´Ø9ØË¡3¼Ëü{šŸØX›·–°,÷0ha&èPŽû@Uw !à6[Bz®JLo«:€³rz耞àåª÷Ò’˜’÷xH“ä$êv¨ágù¥÷Q|ÅÛàZdTýµÈ€©÷Ÿ~ä‘mÙ¶Åmõ3Ø|cYöG—l$W¼$’žçVSwRÐ?ào^)Ni£=¹/–¿Ü‹–O¤õLÄtp²F ‰rŠ»’Ù÷–‹ð¼oÚ¶ºÙPD`M˜çG ‘˜”C%k¿Vê™KípNß6IF¯ôzLFxYA½oÐó›Ã> 5õæ‰[íáþ¾ÙíËUði ²r¨E7ä†eȰ)öpÇ´Nܼ.y²Ýehz‡ÝXhßy a¦qÏ„$†A4â‰ÿyÆM)ÅùµCbÔ‰V§—t·ü,6-±>Ñ=ªú ¢=ƒu!õ÷ÕÒ5m³Cÿ½´2´j[Þª. @LÏ^ÈíaÁ5#1q{°3KùnŸ‰$K²¾ÉûIa3÷Õ6Õ8);ìž8V¸ ñEƒKïªÕª¬C?< ~܇íK‹6f7O¯ BÝ mw B¦Í"rÈ´K¿îË-Xy6ø@fIq•y>øèC>:¨>qÛEUŸD |±óÙÓ;¨‰ãQ‡4”üÚáù^I³»\‚:]T6åô¬ê›æàõ?Ù Õ V|÷Îühù°…7rw™ÏuÍ™ ’Ø ‰—Ò­Ž©¨VÈÀ³¡ ëtE'vþPl%7£Ú9”Ë\›(ì2™†¨5Q)÷Çšõ¹,¼ÌMè—D§#%‰|‡M–* +ª¯„q{_úD +ÍÃ==CœO ÏkÅmY/àg- Mb…7Ï€ôÎÁ“bÒ:gÁk•L7hQ§§ÕñºåQÁ|cÓ«¡Òö¦–>“¢â aÑö¬™<νT èCW jHx$z§µ#2‡lúÙã;¨‰ó‡râD–Ùlˆ€× #{Ù8u¢•x¦Ñ *D=V!jõTˆÀY…h«5nd_…ôŒ +±æäBf©rž“ ÏÃhÕ}·@²ÖîÛ(ü,ÿX"è ü_ùÏ95«ÍfhòyÏ5…Ò‚ýu\7(% U¥S ÖV#Íî"«W©ð9)4 +§V/Haê)ŒPC)Œž¬>-L©\£åóXtPh “H- 2Ÿ!La™ôJCè+ƒ¡4$“£9§Ë"µz²è»wY¤¡›y"{ƒõ»`4=Ys5NÖ+~ŽƒsZ\—K*Jµ!Š“ð匑öw5ªXzZ—{®5å¬áavX˜ õ§Îü[Ò«^k`dµF4ÊU1ṙ4¬í×[ÐÄ1=½™ªÔsýݦ¡"Wl¼SA?ìÍzÿ™G(#3,ÕùúÚ>!H8õŽ{Eðôx&Ç*DÜoõ‹U-yþp¿‚æPÞ®.µfz71¸ITF.ׄ:Ÿêòû–{žaÊzpìÌm0ÏÎq³ñˆ`,:34£èQ“Å ­C{ÄRlðüw¡1”K¥ÂÛ!2/—қЦ—»u± k~QÊ,7M»˜º‚D¢6hŽÚá8X}L”þý¢-®ï¼9Ì%ÚâžÅý}Yìx´ªÃ9wa¯áÞšöþÇd­D¦ÂÊ4ºaÿÆjÑiþD9.&Qã‚0@2<°NÂ\}“'²Ö1‚ÒD®QÐ AÐw¨|þMa:¯Ö Ð-ò… Àå/+*ùqÌœ˜@4?M7/ŒµÏ½wÔ Y=;UÄyÎ쩤‹´YŸp@ÁvLŸ ’)véÈ(…h"¼µØc`à€©æ îFüPq;ˆ3¡æ€™è˜©ùÄ@ˆP6‡ðÖÃŤPÀm¨¯¥ˆ‰JÍØ{F™@ÌaòQTöXíïªú¹*•ÉDf“HfãÓ“áäR•u_ì¦jέS‘óô™Ü'É\Œcoà°~fx]6ÓC¢w{ØñHâëÏ›ò$ZˆŸH Êò›®—>à@ˆKߣäÓpÀÈd2`}v/^—`¯ÐŒ+†[-"v ‰PÉæÉ ‡êxµžå™Pü*dlV\ûÔ#¢M‘5¥~ëÎ@üp¹Håüÿj~òe Õ2Ä¡›ã²¾7û}92ÎG{É íïz¤øæãVÍÞ7¸Ñ¬©°ñ¢¿³¿”pôÕ‚6¸'—…Y(l6dU¥¯’!nrs%¬Üäò<e€ÙT>ÆHx ¿†Gƒ âȇ :a¤ÜïYõÐacM£¬S| >{tÖ—r‚]¹Ž2Š"–—*™ÿFdè€Ô‰ šÔ EïÈú\þk‚£AÚÔ%°òÇψþšX#“³(sS©€¥záýµ4¤ÓH—Ÿ«;¨3†lñž„Ö:§×ié¬Âih¡&T¼h— éÊ;-gëü1ÁDŽœ +„æ_e†S’ø®ŠûæXšºE¤?O +[S_9À•Ð Œ‰o¥¦gS"*±Û,±/°®õ ë"&ûÅkÒ"5ôÎ÷YD:¨ L†¼3Â8˜ì*oÉg¡Tîjÿ‰ÎÒ^™&ïѧ8†ž¬óg‘MÕúWfªžJ”%4-í>þxµ7Nu\².ªMžüÁ rݧTÈDïøÎ̈Üi3úPæµQ’κÏ~â;*Aqî+Gm}š8Áµ¤sGù Èã硈/`”Îa]…ɱI@ÊšœŠ~øTòõÿ¤a´Pendstream +endobj 1349 0 obj << +/Type /Page +/Contents 1350 0 R +/Resources 1348 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1325 0 R +>> endobj +1351 0 obj << +/D [1349 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1348 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F62 1065 0 R >> +/XObject << /Im2 1054 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1354 0 obj << +/Length 3017 +/Filter /FlateDecode +>> +stream +xÚÅZÝ“›Fß¿BoÇV2ßÀùÉqÖ¾M9kßzýp•ä ´¢Œ@håêþ÷ëžžA !¯SÎÕ%U¦™izzzúã×£å3ÿóY¢#&S5‹SiÆõl±¾b³G˜{{ÅOè™Â!×÷Wß½‘ñ,R#Ììa9•D,Iøì!ÿ9xýWnî¯C¡Y`¢ëP|{÷¤ôxýþîÍíÛO÷¯®c<ܾ¿£áû›77÷7w¯o®Cžhß 'áÂonßÝõöþÕO?½º¿þõáÇ«›‡~/Ãýr&q#¿]ýü+›å°í¯X$ÓDÏöðÂ"ž¦b¶¾RZFZIéGª«Wÿìfí§SöS"‰Œ4ñ 4‹$Óük–•‰µb2½,ƒS‘‘Q2½,‹¾c Ë‘þ‹±¨38Cef¡ëh-ŽÇ+äŒó(…1<_Îud„Šg±Öpè†øMlYÓHÅ-'‹´ +Ä#ÇûëÐðàþÁÍé P)t2‹a¥D +k›Ùo31•¦’¸´ÝíÑ +và»Ûµ˜ýÐÀžfÃmyÉáP´Ý—·å¶˜0Ð@2`SVçÛåu( ׂÍŽ^òŸ<¨›Žöe»"ª[DdUWlу:ëÜX·½æ0S·ËkÉœF)m³Û.@P*…ÝÖ.Ïíò 0ÄÕ‘ HÈÈ$\DBëØ`¶Ùl› ¨ÍuP®ªÃ5øt ;Ê‘@y4×<ØÑ„Wik,$òbSÔnp·ij\•uK9µÉ©‹®+ëG°cœÀ2þÙ¢ýönvlž-pŸé ÍhŸxHü˜ض½l‹å¶À×ßvt¨;3:õK•Ƴr6 Šo‹3™€È’NxÌß–B‘F8 +¥±–ÓÙ›E £À'ñ1ºùDòî¹ìÁ÷žÆâ yÍ¢ŸÌY'öffÃEÎ4ñLª ]˜'&2q,Ǻ¼²^àŒb _{õì›õjPtagyP.×ʱ7µ#ª²íŠœè²v9lhÁ’ˆƒwº¸l†í)®ügˬ¬Z§88ÿù2 +ReÌ|¤a¸R\(HʉˆÕ8œ/È”XilÎÄïÊ–ª"äŒ3O'ÿà3ÃãH *—ˆ!×¼Èsç 3ÅÇnGoð迤LÏ5¡ÍÈ‘Rð7•˜±:ŸZtÄg‰$¹Ž] +&.ÕÒtã& ±E˜Í´-8óTûÖ‰´ß8í¦X”˜Š¬ÃÁl·*°¼Xf»ªs_Aþ:÷¢&f@<¡n&¨áÞ—Øß*TAG_vô¬¨ÙôŠŒ¢X¤Ú :ÀÎ'ÖŠ#%•çù…i¶´–ÑCx—ÐcѬ7YWÎ˪ìÀÊ/:¡ŽU$xÆ ‡\—°ç"{uåòpÉí”FNýåå{®gÖç2¹’É3 +œØÓÈHjÃ=ó\r]Öèt’©`¿*jè jYE£Ãt‡SYž“ßµ-¢žP‰FÖfÓ•MUX»ñýÓè›M³í󾬜àyáª3z‚†Rv +*Pª¡‚‹ÏÖVv€¸ÁÝû‡Û7ÿ¢Ñ5è‘=-„‰12x°^=ç‹´ÚlŠlK4äe+“À.SeOž,¶O¢ÿÿÖNø°4iÄEAפûí”Ë$ÒBú|ý—€¡Z+}v‹*ÛaDI©l"À§USJÄ)çz€Êpã‘TU5û\aBFP÷|LÑZ¶ááÞx°\ÛA¦Zuç^‹ÎM ™&‚Y|N7ÄW¸!¤ÌÄ—/¿ÇÌzh ë\¼dçtXdÍKË1š›;4ÖÀ‰mËö"ïe'‹ŠcqêUƒOœ&t2FûôƘ”YÇ+=‡„ñÙÕ€ÚeýUásuéq·Í0=Ð ŽTÅYŠöm¢ÂÖ9Uê/ibc„z õ׃kÿÅ¥&VAaÒ‚'Ï5± +ªIjûÕ¿°‰UÒ@ ù?ha‚¿ÐÀ*•Dq +ì¨ðǦÊ\Ëf“lˆHGœH* @ާ*m;#yS8~jshw› Æ¡Ïq#¾?מÓcG‹+@Šwé= lßKþ|Ú >¼þ@ÁÔ6®“ƒ0¥R—›²á!›ßüŸ›2™Šˆ«äË@Æ1ñóŒ5Õ‰A RVÿÕ$–ñ\ámBö =Òá]ùy*Û ª}éx6³‚e…ôxç¥[Q.y©öéꦥ=¶ð}MÝyo?€iHÔl ™HÒÜðHh‰Æ'Áò…*áe#‡¨ƒø`Œ`By0õzÈÖ;µ0‘f.ö°ãyRá.ß„¯¦`G ðÙ$i¿ý‰Î2}âqIöÔ”ùs2Á•ôž_+Ójiþ”–¡é…F‹W¢Nôý²ôàNÊ|½³]’=^i,€véHé YÒœ«rXÃè(M™c ›Ù„H¼ˆÔ ‘–ìVYG^ä³0FÞ"eÁÙ1²Žl(àžðÔÏ5HRècý¿tÌÐQ±>é÷nc×Y¬š¦¥8„ÕlŠ…ÑÒÆ; ÀæäaØX‚iéLVäŽïOîÍݬEÛ€f×Y}pü~i Ã~a* @x ]¡R„Çí.²Ê£ç§¬ÚùÏŽ(_°‚WìW…“èz4ÄD +<Õ×´:Bme AüÕ½ƒJ×ý;õ«B™XK&®5wkº›q Ê앹0çÔ¯,"’Çë>Îb+ž5u1ŒAÇ|4Ñ_ ˆcÇ„/Ù`×´U‹põÚi÷X>fóCw~µ×ƒr៲Là{Öß¡}ó_ÌÿœHÅ‘L1Ý(H½7x§”~¹99Sý¿ÓCendstream +endobj +1353 0 obj << +/Type /Page +/Contents 1354 0 R +/Resources 1352 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1359 0 R +/Annots [ 1357 0 R ] +>> endobj +1357 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [347.1258 451.8816 404.2417 463.9413] +/Rect [471.1233 313.2012 539.579 325.2608] +/Subtype /Link +/A << /S /GoTo /D (query_address) >> +>> endobj +1355 0 obj << +/D [1353 0 R /XYZ 85.0394 794.5015 null] +>> endobj +382 0 obj << +/D [1353 0 R /XYZ 85.0394 371.6561 null] +>> endobj +1356 0 obj << +/D [1353 0 R /XYZ 85.0394 347.7805 null] +>> endobj +386 0 obj << +/D [1353 0 R /XYZ 85.0394 119.9702 null] +>> endobj +1358 0 obj << +/D [1353 0 R /XYZ 85.0394 93.6238 null] +>> endobj +1352 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R /F41 940 0 R >> +/XObject << /Im2 1054 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1362 0 obj << +/Length 3265 +/Filter /FlateDecode +>> +stream +xÚ¥ZKsã6¾ûWè¹jĈÉÚÓÌÄ3;©d’µµ•C6Š‚lîP¤"Rvœ_Ÿn4@‚%e²år&ºtý øŒÁŸ)é,ÎfI&#ŸšÛ6{„¹7ÜÑ,<Ñ"¤z·¼ùÇ‘̲(Ó±ž-7ÁZiÄҔϖë_æ:Š£[XÍßÿøùçÿ¹{›ÈùòÓŸo±b󟾿£ÖÇû·?üðöþvÁSÅçïÿõö§åÝ=Mi·Æ»OŸ¿¥‘Œg½¿ûpw÷ùýÝí¯Ëïnî–ý^Âýr&p#¿Ýüò+›­aÛßݰHd©š½@‡E<ËâÙöF*))„©nnþÝ/ÌÚW'ϳ(:ž8À˜O Ê"-baðPWå¶ìÌ·/ˆà™D g pAÊý-Oçæ·ƒi»ŽA¨à]ê¶æ ¶Òy³§‘îÉPc›ÿ^n[êäÏyYå«ÊÍåÛæPw‘ã +k¥Z*'ÀÚlòCÕM*d”¥©§9Ú#þVN?–»ÖKîÈÊל-„„ãÓ t ΣL©Ø.·iìÎ CwÿòdjjÑêÐhÍþÙìÝ´]»|Gš%8›?sôÒڴžÜueã–k6SG X¤Dâ·Ö–˜c±žÌ¸/$ü¯h]Œ–NëÜ¢_q.yªP"N#35p¶2îL1qGqI¦2·:òÑ6tq.Åh4¹œQã>Ðúž~BÈ‘nœ¬‹üL1œ¼Žø±4’¥ z©Isby=ÕNWC"§u +L”­Ë"Å9M.Iu¨_U5/eýHÝÆjŒU\ Š×ùQ³Ï»ž¨}m;³¥6™mÛ-†7­A´žÃžçYç[ã98Õ†Ñ]¡)LÛ¢V39h<Ý î‰-ˆÄn"çë¦þ¦Ã&Ÿ·‡Ý®Ùw4ÞÚµ°…âà3¯_‰,ÃXù°AÒƒ Sók·À¡xr-â`$¹œç4ø’ïk{@¶SV­½rK–m{@ ³í€ßh;ÜA¦ÜèGh–ÎúƒÖщwà€§\ÏtGIšÉ3hND‹ê<˜÷T(YÑìÍDd"йºÂØM0u¼/Ïôã¥GµèQmö™Ó£ HõHxØîL.t$¬÷‡jñDŽ1æè«ÎA‚‘‚;ºó—tàù•K ¨.\Ч²’å]~æRt6{¢ ÆG—’HPÏc:ÌŒ—r·Ô¶×’1+¢#5ÛfÿJíο߃€]ËÍ‚†Ã¥I|†KƒÎä¥ ûÉõÕ—Œ0²æÕ/Ø™¡bè¨Ý‹š?åVËÖÔóF +M‹ûðö%ƒc “?ÚÍI5ÿ´¡1wáKºt€3»[8ªÖQ5n0»È;÷J¸véx›ßG<=·¯#ü´¢¿AÈM¼Ú³ '}‚4lm ¼²Ô)+%‚"Žº‹ÓN=ï{תLþìVí—¶©ð\´† =ïÁol©óíç‡á­²0ÑÔ.@MÈê]@…Á¢ÈíݹómÔöc{ºDS½RÔns@ìÖbž;šœ/¹£±þB;7A˜¯½÷@rg!©¿"ÇbM Vpµ¯Ô<ã Ü1Av`Cßl¾:¸è’âM=/òš¸˜¡&qÀ–=N Þçeë&=ýȧ«À§ko¯Ðr†¸ºq5¹# z›ÆÑos«&(Ï+Í9#´.]£¾OÜÝksb––µ¨O ZVrñ|qÈ*ŒõƒV¹a¬7sû‡ÑÕëÑ«ãå Ò$2¤<‰ÈÄ °”pçyí*¹ã‘û(™˜º/„¬iº¬;³¯ÁŸ¼R°|ÂuLÞ-8¶'ß~Ç•Ðõá›Öõ5)¸‘H¥ìŠI…TçMª§òΤü}cw½¨šÇÅ”yqi¥ò²=Õ„# “Ôv$¾"Cˆ”¹ ÇVmS™Îü"V-màNçEav6Wµ½zí¦k‡¹[ÀUA‘&¥¢Ùîà:VeUv=’&€¼Ka 7åC®n $),]öÿÀZ@“Î:í4JUÂ.ôlG)e öPåN¥6‡:(ï”îTwÏë’’WÙ•,0¤º KžêÜ.Õˆ©+x¢ Ž•ˆëKð`,^H{døèÑ;Hb‹ô&·h9Á©CžÙ·kÍiIR¢Ï‡C å¼TËóôW6vºî¨–‡IDåÓjžˆb©ÔåÓí©®Hqº…T · °Ùù϶DŒÒ"Ÿ9AŠ&ci áÑ8ƒÝ¹b†²¨è‰‚ Ö×°A4ÀÝa´œ +WEÃAërÃךjmÚÎ îóºÍ ŠÂˆ5’¼—;.¹„ÖÊM燮Ù(ÿ'pŸ°eÛ<÷5ð¯ðÞœ%ƒÙ߈»+_ˆë£ˆ¼jj­z‡ä£“z%;ÊS4µ£\åmٞŌ«/i¬.cFHu3z*ÜÌSÓv ™º²…ƒn`°'°!Y”$:½,DO5!Å8¤Š•ò±ŸðxtêñS'óµ-‰Ml‰„´C$¨ƒø^»tž¸7š6H3¯ïKZ0¡,WnÝ/àÊ"ÊÈ?7™F+LÕØ‚Êí®2[XËi¿Æ ÄJEBó+^ ¤ºp£žjœKùâØ €oLa¡‹"ôT2Œ†Y!ÇBL…ë|¸¤0\‡éªËkÓZ¢"«v›pÕï¦ùrص£Ž¿‰zi¹ª4î³ h¢E:†•yÊ+ÃÕÿcÀUwfX™cÂm# á$=Svä"‹ÒŒûÃõ©/T"Ê8“AÍ‘Åów¦È©‹“GÄVp6Jí¥£i÷ Z9MnòrO«² wÕ—\1¬² žöõ€†§cÍ&ŸÂíWV,oâ) N€Ã1£þ—²jV¯Áï  ʼnç¼:ø%644][á)£LŸBÎ;’"µ8;ˆ•bäEé:¡qãÈÊõצ sÍ©‡›rGkH·´Pc%Ai½ŽuOÁ×oõÁážµvÜ&‹3qÙÚCªóÖÞSÙ›*vgíbˆ„AÄ|‘yO5Á}œ–§‘N5f¿ôµÜ þ¯;‡6žõ±ÃH¯ÌÐ^¾ÿÉ 6umú !ë CÝ8Õ‡’4å îƒ'¤¼,=Rꯈ t ‰Qÿ£>iÊ<‰2HZ¯c¸”‘fÉ•úZHuáæ=™Š=‡õ¢mŠ/fæ3u™¿£™` ñ™àbÌß'PýmKN·c>€Ç¶ÿB³oiÀÕ ¬ôôšÍp +õ€Cžÿ†ºm·.l«dnºðÒUyYÖÆ¬] Ÿ+CK®ÊGýà–?‚~S7‡G4f)ÉÿKLAI«pȪ +4zM†y«É0fk›¼0í$žÅQ–%ð+÷TD‰©zÌ}zZAlb¬ÂÃòMýfb] * {ÇqdõÇÉCIɼfænÝc-EŠ~„6.ýG÷çrmˆ€úÍÖ¥<ÆŸ`ð±5¹/úpå‡î±qŸ¼!Cã·ƒq!–ýÞà¾E”5$ú=±‹~ñs& ³oÝ'W?ÕaýTŸ©Â1 ™hïxÏkDðC‘À«¬}¥X{×u¶^ é8q-ùX£xœNù{†A”>À{(“!lʳTgB ža{Xú +úhYÚñôaû˜`/\n‰Ì]f#uï\éµWj¬œìAöEe=ìÎ 4'9²½Í¡£ŠßðF¿JñyUüréÉÿæ©*»®r@n6¸ÌüÅ8ÉúùVáWÐuó2‘Qõ•“ó6Šðï¤ý¿Z7üîP&p-i< °pDø!Cx¡lé7>õ(î7x§¢ÿ 5_0ûendstream +endobj +1361 0 obj << +/Type /Page +/Contents 1362 0 R +/Resources 1360 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1359 0 R +/Annots [ 1364 0 R 1366 0 R ] +>> endobj +1364 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [361.118 743.8714 409.8647 755.9311] +/Subtype /Link +/A << /S /GoTo /D (configuration_file_elements) >> +>> endobj +1366 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [347.1258 350.3535 404.2417 362.4131] /Subtype /Link /A << /S /GoTo /D (journal) >> >> endobj -1347 0 obj << -/D [1345 0 R /XYZ 56.6929 794.5015 null] +1363 0 obj << +/D [1361 0 R /XYZ 56.6929 794.5015 null] >> endobj 390 0 obj << -/D [1345 0 R /XYZ 56.6929 585.2486 null] +/D [1361 0 R /XYZ 56.6929 484.9636 null] >> endobj -1348 0 obj << -/D [1345 0 R /XYZ 56.6929 561.0275 null] +1365 0 obj << +/D [1361 0 R /XYZ 56.6929 460.3339 null] >> endobj -1344 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R >> +1360 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1352 0 obj << -/Length 2983 +1369 0 obj << +/Length 3381 /Filter /FlateDecode >> stream -xÚ­]sÛ6òÝ¿B÷tòLÄà‹$8yrS§çNëä\ß½´}€%Èâ„"‘²£ëÜ¿],@¥t¦7”‹Åb±Xì'd>aðŸè4a²P“¼PIÊx:™¯¯Øäæ~¸âžfˆf1ÕwWo?È|R$E&²Éã2⥦5Ÿ<.~¾ÿÇͧÇÛ‡ë™HÙ4K®giƦßÝÝO˜‚>ï?Þ¸ûá_7×¹š>Þ}¼'ôÃí‡Û‡Ûû÷·×3®Së…çpfÁ‡»Ÿn úááæçŸo®üñêö±?K|^Î$äËÕ¯¿³ÉŽýãKd¡ÓÉ+ X‹BLÖW*•Iª¤ ˜êê—«ö £Y·tL*ÕI*T6™±H¹×2KX -Z›åŠã½–Ór B-wóͬ*ÛÎÖ³/;»³ÇÇæi‘𜓘÷‰=Õˆ2g ¼PWöz&U1%A&ifnda7Ý -®/cú@»°K³«:˜zAÀº¬ËõnMëÊ–Ò¯½[Ò¸ <>Ûmm+‚ÛÝfÓl»––" hô®Á2 GäI‘¦Â læs (u>ý1QuvëGB¨…éÌöšë©5‹="hª[9y2UÛ4oêΑ6•Ÿ[5¯¬M½'èñý§žº¶ó®lê6°4^Š×²ªz³iMú[®¬ÝaX8©=œ^p>m7fn |5eWÖÏ4X6[OЬý<![á4”fžl¿ncÚwG¸kèKZƒ»E>ý÷u!@;ÛÒde[Á¡j‚¤È6ô”•­»j?<ÝÍÖ”°s‚SGö?*)XÎ$U’ .=Fž%œC¤`ŒM?ÙmÙ,Ê9ƒÇkŽ’·ŸixWÃM¿ÀýDï‚™”h/Ùe?©ÎûiO…bÎ+kjPï¬ô"œ8j& ÂjyY„žjD†¡£æ‰ÒE6âÑ›°˜öRÐÈcí­a‰6úb«=!›§¶©lwͧî>gÙôÍKÙìZ B ¿¹ž)žzÏ„E-p'ŸÓ×fW-¤…ëæÅ“Ù¯›’p ï®9ÆÔìÈ$EÛì0wQ¥ðØ9Yð¢%ä’¼qM#€¹™Ђ\ûëâyš¥ -ÐóÙû:R²æ S÷+ tí:Ûb¬’¹Ot¸aAŸÚ 0˜gÛÆ‚¹£‹L¹àã¯AYÛ=Ñ–p5ƳêÝW¦\|÷Û•sÓ¹ÀA{Õî`šb,  í®A¦.Ö¥»q@7õ@}zºé}ÊÉìUØî‡Â$c±ê——Ë=ÅŸÑæj6Ö(.ze÷!lz/„åp§¡/'ôÂŒf»ßQJÁ–"Oր䉯œEã”ùJ…‘È3ÚœðÎ%4aAÖŠIq†wæÊ)$lmG$.Ñ‚A4»žLgbSñrª6È[ïŠÞô…:ì|¾û†'2–héeOŒ¨.xb Bq,¡Zºà‰2ɸº,B a˜‡¡(R9”nbfðC‘´ع« BF ¶Ýk³ýL”ýh«n‚Îå6!¤U¨Øœ&7žê“Ü&%Õð.eÉzŸ4+†VÐ{/2gŸøE¯Âï“€Ò)¡ƒys¨-½yÇËѼñKæPdÞ_oÞÈÍgœy#€æìyCxrù´×$Πâ]fñT=º€lƒ‰RÁŒcAtg@¹ÍÅónk|Šƒ%®ÝðÎwá[5f%ïL =½YºfdÀ å¡%c.˜nÞËödŸK¿“ï -ÇÎBÉ[¦ä°@·±-]<“Šò? )µPÛ×ʃ‹²7/6m×ÛSKc¼š b/储Jîyâ%ªªy œž<…oߎӅÖP¢A«MFéØÔ£#ÐLóèJÐZÞPDrÕÑ0Hµ]³!ˆvê‹—PnÄ禨gºP±¼øð÷L±wx5T+ŸyJˆ$Sâ1/¦:óz*êç–Ðþ ÑöËÎTø6’r_!±%ʾ ä|Õ4­õ, }j0qö@IïqˆÃœ½'ÔáÙ£_-|]è]Æñ©ˆ{‹%FÁ§%6D`üߋà "¤€—Óc[/©GöãTYÜß,¨dš)Y@œ=/¶øÐ90f®›É?0xñEëv gÇSëæ\$Šƒ¿*—ÆL7_H¨X’i&þ†ßPA›”| ¡3ÌÓ[äy’Cì ÷àž«dNU–·E÷¼¸.Ìá7sïa0lñ•Éõý08”[³4çÓ[Zq`H³ -ꈊ֒›à„­‚á k¿•iÛò¹¶^¿TÁ6ÁôÖ5˳Š"=´”û¦žÕöÙ?Æ Ø#_ˆÑϤmhXòÉ´a™«Æ…«üË-¡6M[RKN ‚{÷T®¢/K×–ôŶ`„“Ond9,Û±8áœWj¿؃ÈÛŽpcåçt/EÆ"úU³¥ßZb.ÑÑ¥‡‘Xýu¯Öýš$¥ßÅ[E´Œî-.:Þþ zYô'¼//%öJcoÑ}‹~›¨Cl|Wƒ7çxÅP0å¾"ŠÃþ¼T¶áØÉú&þ¥ f±ðoXžÚ¦¼!Ñ£°Œ i¬‰]•¨‡¸]î¶”Æ|S‡~hªÉÈŒC3äŸaÉ ;¨`[çÆÌ< _Ú~ïGö«ÁÒå E ŇɘëDjÁ‡Ya–A&ÿÃZȤÀŸxGçì­~7¦“¿q(ä[¡Þ™ÃÄhÞòì $rrÐßù·û±iò´–ˆÅ;²-}N¦—8×qòð ÎèëŸÄtÝ8Ãw€eÚj¤À¶¿+ ¸È4m& °Ù5ýxKDš&ø(°Ó%Ù€R[%§…R)¶[Ñ4‰ €ýŠ¿)ÒëPbAtTÑcNE•T8ƒ˜NÔÐáãîÞöaMéytÿut¦Êš`ðo½ ¶IÎý}L%åèÏìl,ë/ÿñÁá/3éZ‹ñ>‹c-м—Ê•¿üXöTê$Õ"þÔüendstream +xÚ­Ërã6òî¯Ðm媃'G'ñdJ&³Ž³{Èæ@KÅŠÔˆ”=Ê×o7ºÁ‡DiR•-W™F£Ñhô €äLÀŸœ¥6:3³$3‘ÒΖÛ1{¾n$Ó,ÑbHõíÓÍ7ïu2Ë¢,Vñìi=à•F"Måìiõûü»Þ}|º¼](+æqt»°±˜ûðá{Âdôùî—ï~øíñî61ó§‡_>úñþýýãý‡ïîo2µÆ+æpaÀû‡Ÿî úáñîçŸïoÿxúñæþ©[Ëp½Rh\Èç›ßÿ³,ûÇé,µ³7hˆHf™šmoŒÕ‘5ZLyóëÍ¿:†ƒ^?tJƦ‘U&ž-´‰ÒxLjYD‚։͢X+ÝiYÉ)-*Ôò6ÿ²XæË[4ÅŸîtÑdìÕóÙüÕ„z €„ÕˆÄʱOw ËKQ”b{Øb#›çÛúPµÔQ¯™Àmëý‘úÛšp‡†G¯ë=÷~Û¿:@Â>ÿ£!”_é;€=/*Â=[×€qÄÂÎÿ³qUÏ”[FRe¸JeÖ*/sNÅÊK‡ßUÞæ!güzIðÓ¸¿•éÜa»A„¢¢¡®²Øí;„m?4,á·¢,C¿îžá²öß³Bíà×}ÙD@í5¶y{ ¨<úUŠñòžóÆ­Ðì¼ÆµX3Ï+jÿôø™7í>oÝË‘:šš°í&o C‹À¯zý¢UÕLä¾,[¹ì„Vf~Gd¯yyàÁ^ÏðcÍÎ-‹¼D½ÙL$¯Šêe¼(Š'$6ò\eˆÌƒž´=ÝÊ9i艨µoÖ[¢f#“ak¬«òHЛ‘§+öÄàéé'žªßŒI©žß6nO½¼ ôÉßXN\Ó7ïM:p¨“m;T^ÁŽIG¾g“(β†x¯5¡0©ÎäÀýËzG¼÷>@iµxÆÝCøP5ÅKåUE»ïöÌð¿Â +ñe2åPJØ7£ÐX±Ü9ŽÄMû`}´ØMþЦ‚W@“or4[¶ÔÎú +ú Qãw ›WÀVW® ¬rÑv»zÏmÝñx­è za^Y8"„*dµË—¸Ó‰°ÓÇ)ÛÜÕMÑ~AR“ò‘¡4óÒ5 µÔÏ õ󷼡ü°ñìè {ïˆ#5×2«šÐÀ%"ÌCE˜œš!ê ê­h7„ÝʶؕAʽ5Kµè¢å‰Avþ;°Û•…yÐhÜ.ÇQ©íÕ!Pˆ.`ZÁn/|Ì$'¾ûð¢ ʈ_¹uR£à©Dt–È9[ÆÆD‰òzJR]N©•4ËÝ¢,šÖU‹Ïw˜HªY$‘]— £ša”Tc¨G, F2pRÍæ$Á$ÍB{]íÚOziOÛ)Ð'àjEÀ¶¨8.°Z©yìÃz”t3XûÊ•³54´Ë¨ÖDJÄú$£.— :LD¨²õö‡-¥ æVΜ«#"¨‹r'By‰i¡e]µªKîÛÔolóêHÐÓw;ê +¢DQWM`™³”mòn•¦¤¿á ÇO|X½’’ÜžÀ·¼²’oøBÅÔ[îçÒA*˜jÝÅìyvݸ]ÞPÆØ; |Ik°*KæÿF§àÐ:<¹Xiˆ* ?! S”®jËÉè´Ï‹3e•¡ý/”‰2c}šDP]'ž‹mGRBñ- è}tû¢^Kòȧ[‰’7Ÿ¨ùÉc¯¹ä§V«ÈØX_÷Ó!Õe?í¨PÌeIÅ¢`Î5VphIõu:ª ÆŽšD&Íâ±OlÂjÞIA-Æö™ Òƒ¯/Y?7u Á\Î)¯Äód4¯E}h€ +5Œ™UÚûJá·úP®䊰~e²¾8YuÙŽ)ñ‰IPB©©HZú¨’MV€N6 +Bá ¹ŽÖ%)c2.Z&÷ëDÉ©Œ„‰e(sŠêÀŽNøìˆfô©|`Cþâš¡`~éPQFgµ—ÚÖæÌª/,Aêìo[,óÖš«òÛÝc¹ªiö”êá^—~Ç]W#õ¥ó]çS^fVM`{ MŪ_±Î\)¾øørf½Ã€Ø¥dâ1ˆK€ÞäL[qêV\žGu’ÒONcˆzvPÄÀpÓ´‰m¤({¯ºÿê²ûwT¾€tù¾}vy{ÅÿãH§:½.CG5!ÄÈÿéØÊ±>ùÑŸV©±°Í ø-¡ÿ¬+&Þæ(s•WKG]-ÄÓ†ú|~A\˜à¸†pÛ|ÿ -Ñy3ás¹ÖÝAa'‘ÃnÂÑ BO£Ä¦Ùبðäã(Ì$iÈÏI6 n€ïcŒ÷ÍÌr ]} 0:Ôø3ŒytySWùsÉC»²àþ4Ãa$NM_IèU>™íðü"ÁcfbÔxT‰¸vð]áÀ¤’¸;¨Þ» TJm˜‡1ÈÚ­.ðŽ}9…„¾RGŸè!ð|›*r7À“)`ÏÐ&¼œª rĆ]‘íA.Ða—ËÃuOÄW™þÊÔê²'vT(£7Ž5TKW)ÅÁÜ`ï»ð-ëœî¢ŒJçwkqB¹ðð+ÄL'ïd{v/Ïħ©µPòÖ–ï1€ÓÆÞŸ˜µ6”ÿI©€Ê½• ®ŠfY¿ºþÀ¸ÎžjãÖÐå_ýZ¬ˆ +¯óèã%6ʲ~ œž™‚o§é"2©e£äÖÕdÆ´#Ó<Ù¾òWÕê4H5m½#ˆfꊗPn ×MQ/oCÅòÊáï…b'Îð–S­|9æÉ,‚*Ð~%æ ¨®Ä¼@…ËnZX.V†ÍÕ 'tü!:ª )NÞɉèÊlPx¸ÛÝQzž™º¬_èfT¤—Ë÷ êœL…€uaÅ|¬íY3©æ"AôEEkÁS(…½0´,ÿ°ÕæñVÁñˆÅvWº­«üqÐ#*úòÃ&@ÙÙæ›,‰bëÙ@½oàŽE3Ò³Eÿøø÷Ìih*ŠSû•`ˆa+3ÆŒ.Œ_ÑQ½«ÁŽAlWÅQš)~ç:8‚^QŒÄg È ¡ù ÑîóÁ¿^iˆØewärS×c9}*.±·§¤Û8ÄaÆ>ª¿ôèF+® +½ kÂx~Õq÷·ëø¾‚Ç¡þõnMO-±æÛ|ƒ¬\ÀäL\Rc±„¬~¤®e‰ kC?Ó·+×x´2]9yšìXÍÂ}L{yƒŒ]Ä}oò<¾b|r,]^MÌÆiâ$x¾ZðK¬Î þMN.ŽW{¼æœ—s‚”:’FÆÅÀxñUó6œez–çö-¥Š Óö3Ó+{»Üœ i8 +DÁÿŸãׄ4pRŠ39Ò›çù^BìK´ +Wjte¥ª´Ø"ý?âÚÐ‡ßØß‰A³Ñ„F_r-l"ç÷þY;Àœ%Ô%%gÁWóAÖ> endobj -1353 0 obj << -/D [1351 0 R /XYZ 85.0394 794.5015 null] +1370 0 obj << +/D [1368 0 R /XYZ 85.0394 794.5015 null] >> endobj 394 0 obj << -/D [1351 0 R /XYZ 85.0394 688.9861 null] +/D [1368 0 R /XYZ 85.0394 590.4054 null] >> endobj -1354 0 obj << -/D [1351 0 R /XYZ 85.0394 663.3646 null] +1371 0 obj << +/D [1368 0 R /XYZ 85.0394 563.4931 null] >> endobj 398 0 obj << -/D [1351 0 R /XYZ 85.0394 285.7302 null] +/D [1368 0 R /XYZ 85.0394 179.4044 null] >> endobj -1355 0 obj << -/D [1351 0 R /XYZ 85.0394 261.2794 null] +1372 0 obj << +/D [1368 0 R /XYZ 85.0394 153.6629 null] >> endobj -1350 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F62 1060 0 R /F41 935 0 R >> -/XObject << /Im2 1049 0 R >> +1367 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R /F62 1065 0 R >> +/XObject << /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1359 0 obj << -/Length 3004 +1375 0 obj << +/Length 3134 /Filter /FlateDecode >> stream -xÚµ]oãFî=¿Âo§k­æK¡OÛm¶MÑfÛl÷ÐöA±åD¨-e-¹é¢è?rÈ‘F²¼É]¶ùâp8$‡_²X$ð'&Ó\æ‹,×±I„Y¬vgÉâÖ¾= ³ô@Ëê뛳×ïT¶Èã<•éâfà²qb­Xܬ‰ÒXÆç€!‰Þ¾¿zwùí¿¯ßœg:º¹|u¾”&‰Þ]þpA½o¯ßüøã›ëó¥°FDo¿{óÓÍÅ5-¥ŒãëË«oh&§æÒë‹w×Wo/λùþì⦿Kx_‘(¼Èdz_~Kk¸ö÷gI¬rk0Hb‘çr±;ÓFÅF+åg¶gÎ~î«në,ÿDK•ÊJ5Ç@“Ç©‚%dàÍ}IwZ—›â°íhÐ5Ͷ¹ûD£ªÅ{¾~§E€Mª8‰^,E'"5Û°/M’è/j¶ÍªØÞ7m÷U0®Ë®åñß_bcšƒ|sý<> -ç¹Ñó|L€9"N%ñfíKwýŽ1ªA_S©ã4“6d·qnŒD¥2V™H©Uq’jÇ +⤓‹I¡â3Jáâ=0ED7ð_FGú(“Lf‹TÙ8wlY|\ˆ8Ñ9ŒHÐwà&^_îäâ›®³näÑ.¼î> SƒÀáÙ œ­Mœ[`Ww£4Ô4P‰\¾P¯¢Ô:¶JxÀæ¡«šT.³¨r®­›Ž'vÛrWÖ]¹æ †ä7 ½<ž²K§y,mn¡¤^&|T3“§ ýáE¾L5Çú$3=ð_Š™çkl+“ä½ýi,˜µÞRÿœÛfßm«–ßó‡®è÷õóxáiÈ4P…Aéh.lT¶Mݺ’¤•‚†ß\} ñÇC¹ÿDÝ]ñ‰W°Ž‡ÙfC“;00Èqt@spÕhvÕ¸vÝÒÆ_“\_·Ð‚Ú4û]UßÑjñ¿àà•ûw -WnK¤3×þ˜²ÃƒÀ'h­˜°X;îµåþrOýÇj»åu ©Øn?шŽíûšÆ¡1à÷;»ûj¼ª#w:uýZQÓÆê\DõºìJ¼9ˆ“fù^@ÎÌÅð>·Ä—d@uIοٱz‰Øã­Ð~t,›=#žzp8BH†m{årèîÉ3”^_š›…Q`:ÀÒ ‚ÓâþŽmÓuàÐzøe¸áØ¡ãEr>”+¶#@Œúˆ&‹[€áG®µ‡zŠ’#lÌ~Ô"™§¬E@Ðj[õœò -»%mÂÕfÍpí}sØ®C¸b¿/ê»@†®ƒê„’_J ¶.ë2Ò€ÂÙQKó°¯@Z¯p6,EGëU릲èÐÒ³Â=õ'î¬×Lj[2>²Ó‚逎sêÔ­K”èèrSR[¯x³'ˆ °ìgŽÞ)ˆ»¾kKät_µœb@òÚF…{ŠÐ ÛÒÔÊ=#è¬ñPå/5{ÞNÛ¾Ù³åèÜ“vSõ¯I"ïȾ”k$/É£ÿÜ—Œº ̽ˆ5û1h=[=”í]¶'î~LSV7μmºÍ¢Û’Ú‡rVÑùG›ómʸl69tò¶h=pøz`ºÃ¿ZRA«(ÑÏT­ßêøc½š~l«UÕÍ“êXèç퇀t2…r, “Û¿Íã2Dyü6a%6™É†“Oa3HÁ~9"=ƧˆÌ“ØJ«ÆDž2 lLï -0n'Y5uIÂÂ'ºÇ†:%åªè-ÓÌPô‡€h:ö¨_1Éã}µbÔ.ÂÎ-ï$½ÑåO¤EÂHˆÁõ$Úü4øNÞßm39ns-Û;¤ãÏ È›·?P‡ì¹{A[`ÉxÙbú}¬‘Rb Ã<áÒ¤Á©RµRªÂ x¹»`ŒË圻0þëáàÓ. Ìm®2ûiôŸ¢Q§q.ÓtLä)Ô±ÊLÎü¦ØÃ lCméŒöœñÃ?×ÅTÒi! 0ŽÃvu_®~'éÑ dVI>±QÅ]QÕ¾¤Ð •† áÆ(mPBšpÙ¸Ã×  {¨»Šƒº‚‹¯;ºvÓêõlŒ÷ÞåJs"‚¥å˜p< -w09|_0Ðméè9zÊ5>–’òñfÉüÕ½sq$Á" !îq|¼‹—q+š™à—Í(9|Wسê˜0( Uµ«ºê’†ƒ! çt8͔ӠÇ3âþA -€‡¶ßÛP > ܼ?æäþz.I#áË|ZV’9¥Ðîš?&3ý¦Ûò®ªkJ $©ùh=DêÒ2]NaB—/Iï±-¨áZYˆü‘©ðÆü”:Ê÷õlöw¬³¡h,sÖF'ô18óÌ„|L/ô -;‘@ŒžéD=•C€“ƒTc¡ÒBàÌ|‚1.C”s9„Šmhz°Ï$,ji¾‘=Æ'ˆD¯ ”Pc"O'FKË ÇxÑIiÎ&`Ÿ¤zVdo ˜Föø-JøøÕi‡31p™2Ð -ƒ,«gMÆœl=!ö,Ú¶º«]¦Ÿ’•…f ·,¨ƒ“õzˆifdÄ[M-Cˆé;†% -ŒF@»ª®v‡ÝÜ™#ÆWïOoN[“ŒŒÀœ[oq‰R³–Ÿt6ÍRw‡QÙ bî¿2¼Â‡¢òB¡¨\Jß9Veå¨vH¨°¶£Q¿Ë¹™ð°I ‘ÁàW2êqÆàúTcÆÞ]ÙÍYœðæ-Õ…‡š×]°’<©ãaù¸/2≠µ}EÚÕ©¶¼ -†­à†%ïŒäþwW‚”ëªü³#¸»‚tPÕŒ†ZÖ˹[‰Ml䋺\ü´‘È1Ñ´±x-5-1EhªEÊz €Å¦£«õ5O€-+®;&v¨§z”’Qry0XQý -F§ý³ÕIš/‚â|{ß<ÖÔ½|w(‰µ Bi…!¿QÑϽbüD1:PLÔ°†)*á:ìNùÈ›3ò诫LæuzÁÅܘ«¹Øª¼!â‡)&£u¡†ñÑLåá:ßj¦¡Åóg†ü[&ŸrËŒžññ0·0²®i† ËûÓ5Ÿî³¥3%–= ­ ‡üŒ™™33gÔjú–Ñ Ö½A¬öüQ¿±±b¼`¬­†›|áOÆßö‡/Šôm‰¢¨1i3Ÿý¥û8ùú5­\¾Ãa$lº{Xê:–¸'î¯ãŸ›¸o¾»¸¢Þ¦Ú{b7wE)—orÊ7ñóMüc|S/ä›z6ßÔsù¦žâ›| ßäËø69@`Ædáu±Þà® 'W2|ç‡=9 ²jE×[¥S¿©R&Æß“ÍTÞ“þÇK/þÙÚð›,[{ê³y ±€„‰r¿h9újÐÿ¾í˜ôÿ]ýЬendstream +xÚ­]sÛFîÝ¿B÷tôLDs¿Èåä)MœÔÖißÜCÛZ¢lN$Ò©8žLÿû ,µ¤(;7ÉdœýÂb±_”˜%ðOÌL§¹ÌgY®c“3[lN’Ù-¬½; 3÷@óê§ë“³·*›åqžÊtv½ +pÙ8±VÌ®—Fi,ãSÀD¯ß_¾½x÷Ÿ«W§™Ž®/Þ_žÎ¥I¢·¿žSïÝÕ«ß~{uu:Öˆèõϯ~¿>¿¢¥”qütqù†frjŽ ½:{~u~ùúüôïë_Nίû»„÷‰Â‹|:ùóïd¶„kÿr’Ä*·föƒ$y.g›mTl´R~f}òáäa°ê¶NòO$±T©œ` S 4yœ*©»æ¾Y7·§ó4I¢¯x¡™Tq.=› çÆH(’3ûÒ-'Ã… :“z´JúJˆæL¤/i “ëýC{æ“'ÒâÙ[ t DŸÅ¹’ÖÁù£¦™<Ø{ˆïÓÎP¥ll5èO¯RSîD[g:Þ‹4`\DÏ©Ñm³íÖ•7º¢sÜ›¶ðRǹ†×±· JGdbÚû¦nÝŒIÒJAÃ7—hüiWn©»)iqÛèx˜uv&7`c*ãà€fç:‹Áì¢qí²¥h4¯®ZgÆÔªÙnªú–V‹ÿß„ÅlK¤3×þ˜²Ãƒ FÑ`ž‰°Xî‘«£>;D\’ÀÐ>ÒˆŽívÛšÆäAr~¿³»«†«:r§Sׯ5m¬NÁû-ˮěƒ8i–ïäL¸7¼ÏÍñ%P]R§óov¨^"¶Æx;´ÝófˈG*c B2lÛ+—Ctž!Þ8Ms3ÓÊ€aNÁiq{˶é*°zøy¸ÁÙÀ àEr>” ¶#@Œú€& [à@xÄA¨×C=GÉ6f?j‘ÌSÖ" h±®zNy…]“6áj³d¸ö®Ù­—!\±Ýõm C×Au¢N‚‰KÀº T»pvTDÅ=ÅÍý¶iaˆ‘¥€¥èh½jÝTíZzV¸§~äÎrɤ¶%ã#;íc9è8¿NݺôH(±­¼ÇÙDX¶Gïä?C`ˆ‚î‹)-'¡-†9Ô ÛÒÔÂ=#è,ñPå/5[ÞNÛ¾ákѹ'í¦ê¿’DÞî8øBò’<úï]ɨ ÂÜ‹X³ƒÖ³ÕCÙžaÐe{âîÇ´1hÅqã„Ñ¢ Ù,º)©½/·h)†Îˆù6õÑv6:tò¦h=pøz`ºÃ¿[RA«(ÑÏT­ßêøc½š~ÚU ˘z®ÂSœI4È.—xA΋äKa,G¨ÞË™íÑàöÐÌA ¦Ú›¹ÞKÚ8©°é¡SàfѰ:{Šƒ›RvM9¯øˆwÇ•¢ž¢@—‡p€1#o¯SöI*)g*ƒ¨!Ëì·fXk„=Æyˆò0ÎÖÆfz(¤rStŒŒhT`Y!±?ŽÆã34*£ÎT:$òˆ$A)Tª„ç7¦|(œ +bÉ-›¦ŽVu$C°75ÍlopÔÞ—‹ +Õyá<=^ $he‡* ¦ßT*ޏ[Tg“1ò€z­bp,S¾p/÷Ì Y@<ô» „ŒtÈ Hßs~—áçá†)¿;Æ;ô»@˜÷»òP¯%Hâêðˆ ¿ËPÏQr€-ð» +2æóÂåÐ(†æž:k6âfõ¤Ä„=ÊûlåiÓ!”ö€›]ëñwm¹^‘Öè°%:j Úr•IóAú•_î×Õ¢ê&ÈIu |ÚŠHŒ…lEiHšéï~¡=Æyˆòð… +)nf²ýÉG͈°¤`‘ãsDb‰AZ5$ò˜±$÷jC(«¦.IXGàD÷ÐP§¤Œ}fšŠ È•"ò+&Ắ¹l +;7¼“ôBF¿“ #c,k c¾½·ª pÛLŽÛ\ËVéø2yõúWêPºƒ=w/h l %/ÛŽ*OcÇ!±”ažqlÇ©R<Èà4ãõªªûïŠã߯¨!ißÿ¥ûDyvF+oñ§A ›î–ºŽåGóõð·¦îëŸÏ/©·ª¶žØUÅdQÊOÐOz¾Äo<~Gsà3p‰˜’ÿ5N ¾/‡Sj?õÏaK¥¢,¶`zžÄì©Ìå‡ý…ë=9v_öO1[> endobj -1362 0 obj << +1378 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [213.6732 532.1015 286.8984 544.1612] +/Rect [213.6732 432.1255 286.8984 444.1851] /Subtype /Link /A << /S /GoTo /D (rrset_ordering) >> >> endobj -1363 0 obj << +1379 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [209.702 453.3093 283.4678 465.3689] +/Rect [209.702 354.4169 283.4678 366.4765] /Subtype /Link /A << /S /GoTo /D (topology) >> >> endobj -1360 0 obj << -/D [1358 0 R /XYZ 56.6929 794.5015 null] +1376 0 obj << +/D [1374 0 R /XYZ 56.6929 794.5015 null] >> endobj 402 0 obj << -/D [1358 0 R /XYZ 56.6929 601.5665 null] +/D [1374 0 R /XYZ 56.6929 498.9148 null] >> endobj -1361 0 obj << -/D [1358 0 R /XYZ 56.6929 578.6548 null] +1377 0 obj << +/D [1374 0 R /XYZ 56.6929 477.595 null] >> endobj -1357 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F62 1060 0 R /F63 1063 0 R /F21 710 0 R >> -/XObject << /Im2 1049 0 R >> +1373 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R >> +/XObject << /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1366 0 obj << -/Length 2639 +1382 0 obj << +/Length 2398 /Filter /FlateDecode >> stream -xÚÅ]sÛ¸ñÝ¿B“'¹sBðIÉ“/g§¾¹sZÇN'—Z¢mÎQ¢"Êqt™þ÷îb¤¨Ø©¯ÓñØÁÅbw±ß°˜pø“Ì0®¬ž¤V3Ã…™Ì—G|r ßÞ 3 @³êÇ«£—g*Xf™L®n"\ãY&&W‹Ó7=ùÛÕéåñL>MØñÌ$|úãùÅO4céñæÝÅÙùÛ\ž§zzuþ/OÏN/O/ÞœÏDf¬—Ãg翜Òèíåɯ¿ž\¼úùèôªå%æWp…Œ|:úð‘OÀöÏGœ)›™É¼p&¬•“å‘6Š­T˜©ŽÞý½E}uKÇägTÆL&Ój PðŒYmÓIj,K”TN‚ÿ~LLfR1‹$Ï„`Ö}|y°0)³Jfæê®™$Éô¦®ªú¡\ÝÒkñ%_®+ÿí¡¬*Ý–ŸýÜæXdÓ"oêU~஋»üsYoF?؆=ªzž{Dwu³¥Q¾ZtS ë=%m3ßV;š™×«¼ Ç7 “>­ŠíC½ù½=þ¦ç¸ƒI¦%b5é´)—e•ohr[û§#Îôˆ‡·úfð9_,ˆ–¦¡‰¦Þl o¹¢™ ¹ÉT3˾x*.‹f]¯š",+VÛ>Ÿî‹MYxoÜ&õ²Ï§£E)äˆC’#Žè”ʦ7ùgd'óÕŽÈ>[}ÑâL'Z÷ Ó¤IÌ~%6Æšž-øÒ²ÑR1ÂO Ä ¸3Õž}&éìa*§Ç@ ¢<ôâ5 Ö´ì&쟓5LÑNd’oi¦É—E+0¯yÿ á#°<¢}p0Ñ‘ò@ŒVõ–×=Q‡Š#3í™ûÀL°*ñ¨Χ_Ýö‰a©QºOÄW‚p‚B}½O÷~cp _¿ <l8p2ê58ÓT‘—B×,&4¸j//›ÂKâÝf¢¯3ê©$’„äŸw…ó -fº¼¯¶e뜼zÔî¹h$§Ùb{¿Y9Ïå*ø¾jÜÙá7ï—–ùŽ&®=šû¦¸¹¯hÎÙ.áÙRÙÊ ¬ÛÄuÁ2 1¯'r·Ü9xDÚo}<ñ\'$Á§ï ŸWMM£í¸Ü²B¸6AÁ÷…¦4ãReöÃ0ÉPF³$50$&9×íéÛævBƒË(=à³Þeý͇X‘ˆ÷à%éP\zE6¨†i™0¥LÖ£h/Mi¡!dRÂè<•%´‰îû¶“Õ˜ÜÌÅR/ÎVQcÂ…DP -À2IÓ§$l’Ù,ËÆÓµY‹q£$&{ÄI g­»Ý‘¯‹ùˆZHÉ47ÁîJš ù#ÔB?MIXóÊû[¥åi}˜WyÓÐF¦·Q ù~£ª'1-!ùþ4dáJiû|‰Œ³¥“X8áÂî6véFÛ‰ù\–ùH’ù°Ý­‹®Á­‰D= @1Ó‚H‚áñOcºÅøÓR¦,ÑÊ>ƒë¸Ïµ¡úÅ¢^æåjÏÓ€–ZcíŸÇx‹ñÆ•4Ðì1þbŒs˲,µ}λÐ9½d2Ë’Ø7ŒgèêQ=m0!²ÔsÌ… d¸˜¹šÌÛŠ›*ÅÔÑžK´ÒbñÌd>®ã‚Eq“CÔñKšQ÷U]’³?¹ø×¸kH¬ºË—yâ ½ÞIë¢ÝË}Ú‹\ãëÑfEÖìû~£„º\PtÊRÄîî æù}S„žÛ.î~uÕ$® 8:9ØåKÚ6žQHˆÉ÷tñZ!W]ZÙ;i%(‹©ÛP„#lZu]»Àûd͑ӣ¹¿AjBÇ‘ŠÐ9†<9c\ÈAžœWù®é·ˆ;Þo9×ã: mç¨1½/Ƨ;úØÃpä‘’;G·çöSfm¡v×OnI&h{ƒöZà`½.rGKW_ìF˜kðp®”‡p‚éÀy‚Fm6©Ê¢a‡® …ÑLiý¤6”P![£æÜ™¢ÖÁÓ]rX1pÉÝý,&ç=×Öê¨4|¶ˆ0sÐäÛ.¢ƒ0 ñT„1£d8ˆwà.Äô -þÊééP0€S  ÌbOõÃäÓD0®­U§ÜÄËó¥œüT?“ˆ¥€w!v,A(‹›t)¶œ0M3XDÐ-Â9(³؃ǼG›¢*rtNø‚aŸ”~àÈ‚Fim»öpÒïkqÆeb[>†%¤ÇÇ’wý‹e '©hk먽Žû-êÂæ”ÍýzŽ« šq)º•cHŠEpl`pÄࢻÀ‹w¿k§×HÞŽÆPƒ#¬ÃÑu@1sVzÌ0²~NW'ÖߎØ)f[ˆ³ -‹ÈÿÚ(‚—m¹,ö p¹ÌÍÎ×Ëðçs´Ã,â½—×¥]êÁ“,ø©Ë‹[Òå3¼Tà ðìö“$›‚çCìçy‰¶o,èÌw$Iú ¥Y–X9Ö»ç“GË¿§þCCçM4öy2yà6"$TÊ0ÀEǘìÝ<´ÿúÀ"âÿžóN»endstream +xÚÅÛrã¶õÝ_¡Ù'¹Á¸Ø<9[{ãLãmµÎd:›} %Êæ„"‘Z¯Òé¿÷àF‚e«u2† xpn887˜L0ü‘‰3Í'‰æH`"&‹õž<À·÷gÄÃÌÐ,†úîîìâš%´¤rr·Šp)„•"“»å§é»ï/ÿ~w5?ŸQ§Ï„ÄÓïnnÿêf´{¼ûp{}óþ§ùåy§w7nÝôüêúj~uûîê|F” °žz G\ßüíÊÞÏ/üñr~þù«»V–X^‚™ä·³OŸñd bÿp†ÓJLžà#¢5¬Ï¸`HpÆÂLqöñì-Âè«]:¦?ÁŠ&# +ä$R % î„F’Qf5ø¯ó™ÄxJ4ED*D/(ÿ¶?ź©>A“O¢8 i!è3˜á&/.ÜÇ›k£{T¥›Xi]»á»ÁzKŠ2¤ Èp +%©"Jwß_ݺѮÎÜÑoÜ Úú 2xgMh’1šäOÓ{¥ÞØÉzc§ê½¤7ú½Ñ×ém@€}I,n¾ò"ðHÂ˼Ùf«ÌO6iãFeÖXÎpŸ¥Àï¨&ÜÇ‹k8ˆÝ!5¤UæîtN¥œ®ª¢¨žòòÁ½f_Óõ¦ðßžò¢p£‡ü‹ŸÛž5ÍÒº*ÓûwŸ=¦_r#‘ÃèM QT‹Ô#z¬êÆÒrÙMÕnhŒÎ<—¹#³hн›YTe ¯ÙrL ¤§jûk Nä›Þ +BNsƒU$Ó:_çEºu“M埖9ÑcÞªÕàsº\:^êÚMÔÕ¶qxóÒÍ„° §iôÕs1ÏêMUÖYX–•MŸƒßvÙ6Ï<+K¤Z÷ÅsûiyaL=š¡Ó£¹MbLMWé#†™L˽y̳ÅÑW­™éTk_#eŠDÆb˜¯N ‹±rÏV óÒŠÑr1²]0cÔ­X»÷Šº½‡©Ô=&ŸÀóé^¼¥ÔÆ-[ +ÑþY]Ô£Dý)33uºÎzXAxŽû{AägÄèm)<Á¨¬7¸ÏÜÓØP¶Dî˜öbi{L‹ÛyÝdÈKÁÆ=®µ£Ôo£w©îû9<ê:ÏF ¶NfÀ=‡L%a.0y‘ˆ€Ë#Îçuæ5ña»U×õT'Ü"ùù1³^AL×»¢É[çäÍ£²Ïeí@R7C4»mim>çeð=¼¬ŸìÞ™oÞ/­Ó½›¸÷h <­v…›³gž`‹¿`Lv1=ïïÄÔó”y?h}ŠYüx„õ‘-ÙéÂrÍpmÉrî1À”7ikœÆß€­~¸#„ÎF~ƒv»…˜UFù#š‰„j[7i“­Û’›l»ÎíaF:ùÓ&·ç ¬œðl¹lõà ¬;S$ °„açn±uðˆ¬Þúxâ¹NIO?f>-êÊšq½©òc.‚.Â9‚—t›bkwÙ!N%bL¨G5@ õ#‡Ø 'Èí'ã`„Zò~ +rYŽé]šB'ñêl 5fœPFÁ)F°ì¤jˆ"­”¯…f-ÆYŒÒ ÙcŽjØkÞ¶[¾É#fA)âX„s—û˜°Ì̱qþÈX¡ŸvIXýÖû[P¥Æ¼ >¹DÜ=BAeI<¡ª§1N¡²5ÃIÍäë50Îb”Vc=æˆ ¼#lÓ5mG4æsY'Èg§™OÍ~“H nHì$ÅBS"Ò¸Ó?Lèã BSš É™~…Ôp_jCô›eµNóòÀÓ€•j¡õ'x‹ñÁ4ÐþfLr”Jt_ò.tŽHOUJƾa<ƒ0®Þ˜§î;œ“ ÈpMæ*T(mÍT~N¦~hÎsnNi¶„ÊŒ)×Í‚e¶J!êø%õ¨ûï'“pì/oÿ9î¤æÁv‘Cç˜Sž9H¯÷ÀÒ&kiÙGyÓ1oêo Cœ¶!í9Þäó¼YëŒÂ!\2Ed?‰é³‚­w„ž]ó¼ã/pÂÆÇ +,¥=#a›ƒd¡:‹Æ!ħuvRÿ +câã! 1Ì’±’VÙCê3÷/i±ËZ'½aN)À ØËF 10ÑmråÕ·®š%ˆ ð˜P?¡kuÊáe\l2hõýo«#¸k.åÀ­Ã€ËÊa´BÁÁ„ZBkq$¾r†d &˜¢t*V:MG›«‹j½ÉmaÉà\›Ô`™øÅl^úyK•Bl.ó&·ñ‚áaÅK]®š ¬íÁä:mc¼´Óxgí]PíïG ú{ û’ω­êu–Úw¡ôÿ[Djİö$ችªö ºeXúFƒÉÙ•¯mÃåÅ’#åÚRוïùùŽùÛ#Í<u +‘Í—¨Ÿª¼¾ v×.7þšÄ9vtéïlfFoLËyNØï›pÉÐÒr®q´ýA¹Ãìû~£Œ»\`°ýZ˜îÞ`‘ÚË×sÛÇݯ®±*“èÊÀÊhF—G»|²mãy%™¡Q’Áä{ºæZ! W]ZÙÛª)˜ + ©ÛP…#b‚s•¼]à]ŠÍ3‘ºG½[n­ÿ1~#!¡s y²B˜PÙ×iZ<¥ûºß">îwŸ r¶ÇuÚÎQcúP§ûùØÁñã‘‘[?·çSf®œŸÜ’”æì ÚkA‚Í&K-/]}±®mÀþBL +Â&ß Õ .)ò¬FÇîä¡(7é#Ý3> endobj -1368 0 obj << +1384 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [353.6787 530.3947 427.332 542.4544] +/Rect [353.6787 434.7534 427.332 446.813] /Subtype /Link /A << /S /GoTo /D (the_sortlist_statement) >> >> endobj -1367 0 obj << -/D [1365 0 R /XYZ 85.0394 794.5015 null] +1383 0 obj << +/D [1381 0 R /XYZ 85.0394 794.5015 null] >> endobj 406 0 obj << -/D [1365 0 R /XYZ 85.0394 600.9849 null] +/D [1381 0 R /XYZ 85.0394 505.3435 null] >> endobj -1020 0 obj << -/D [1365 0 R /XYZ 85.0394 573.3935 null] +1025 0 obj << +/D [1381 0 R /XYZ 85.0394 477.7522 null] >> endobj -1369 0 obj << -/D [1365 0 R /XYZ 85.0394 447.7048 null] +1385 0 obj << +/D [1381 0 R /XYZ 85.0394 352.0635 null] >> endobj -1370 0 obj << -/D [1365 0 R /XYZ 85.0394 435.7497 null] +1386 0 obj << +/D [1381 0 R /XYZ 85.0394 340.1083 null] >> endobj -1364 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F53 1027 0 R /F62 1060 0 R /F63 1063 0 R >> -/XObject << /Im2 1049 0 R >> +1380 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R /F53 1032 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1373 0 obj << -/Length 3269 +1389 0 obj << +/Length 3100 /Filter /FlateDecode >> stream -xÚ½Ërã6òî¯Ðm骃'IϬ³‰g×v¶j+É–`‹5é!){œ¯OÝàC¢äì¦jí›@Ýhô›â ÿ|¡Ó$5Â,2£͸^,·glñsŸÎ8áÄ)c}wöî£Ì&1©Hw£½ò„å9_Ü­~‰ÒD$ç°‹Þ¾þxõé盋óLEwWŸ¯Ïc¡YôñêÇK„>Ý\üôÓÅÍyÌsÍ£÷¿øçÝå N¥´Ç÷W×pÄàãȦ7—/o.¯ß_žÿv÷ÃÙå]–ñy9“î _Ï~ù-VpìÎX"M®/ðÂnŒXlÏ”–‰VR†‘ÍÙíÙ¿ú G³~é¬ü8K„LÅŒŸ 6I*…ìÈÓ„k c,º;çÂD»ª¬Ç“Œót‘ ‘ˆLçG˜A¤xŒu‚—€åxÙ[wÝfŸ° 3&?M8 Í–#Â&åá|JøÖv-ܬQ·¶QµÛÞÛë|¶vYW«º—Å׈¨ÀwŒ° y›”Õª\]YW l’åÃñUÙ÷K»ºÝœèyDX¿2ÍîÖ%±OÍž,e0äàsýùŽÆçŽÓ Bjsž­…ÇmÎyÁ©¶[[­ì*jèrÐ(Ðõ•}(v›_}5¦Ï¥JLÔ~ÊØ }Á%¤"w*ÎpÏmYí:Û"i7PT+ºÀöøVnw[|y.6;{Š,K„‘žÏó“&Šñ;ò䘤9+7Ùi c·€Ë1+¯QsvÀ…å•ú4ýk†±¸?šª|ÊÁݹ…QMÚ±Ú-¸…Š*Û½ÔÍœìšâÁÍÿʘXâ<^Ì•Õ×­Å‘'Û<ÔͶ¨–ö;7bèraª7Ø¡íj\Øâ\eÁdž ³¨ÚÛ´ÉŒ Ä -î3ÕrªÞ‡âÜ“Aš')ïµÒ[™Ñ®µ+„¼‘óµò9($Œ!Ç­œqÓºÒ»€àÔ4´¶-Ñ9ð¥¬úù@+È#LªàyüÉݽ"×tVŒ„d°Yo°‡B‚XÂ?ñg„c´àƒpm I®²`ilÞÔ¤H”2ìàDWox®ë]3XÝç¹H Sâã|YTUÝ!ûmiý圑¼ŠWâÆé¯°„ˆÈœ`'ÚôRn6è#îÉÿ´ån}óJîª9Ï!r‚“·ÁÕøÌÈ•%p\´í¦˜>É|:¯Áé÷G\¿R¼áFX'üQÀ -’>îŽ@JƤò4ùk†þÔ¨³,2@‘Y§!¤ã` ƒ¡Á0/ër¹ž¬ù7Oטö¡@t;«²*šWqªùT·eWB0~¶!<¥ƒŠ¥È½ÙyQ¡eùžÊ Á3Wè^àYWŽh®£k¿à#–!è”Í V\F8‚ž[þ€«·žçG·Å+Ëb×fá -¨_w¶)-‘ïh¹­]Sáû-dà ªt¹îÅÕßáÚ{‹;ºC²©ËqœH™G›ºídP¢-Žâ¬Z¼µ«´gnnZ­v'owîÂnA£×·øôÅM<ú㻡 ø{wpH_ðò(…@šˆàÀ PT©7;ï¤'‡Á«zBi.mÛµ3­2ÈtÒ7âþë¸õXÞÎÊ*nêºklŒ1X Ös’t5C{bc•eSâ9rÇE°,3$À¯Ò=QDèK U‹Sݺèòj®ƒÈ¿îJJ#p–Ì4GO7`Ù¶ÛC ã5ªùÕQîÉ…J¤Ú7Âb¹´Oà““?•Ùæy¥I®³œ‰˜ 5"(NÎm ôi¦%±&y« ”¹¯oóù‚´6ƒM3#Žï…ëìE`X1Ý*ÜÅ -Bt®Ót¬5½!úBBåb¡ OÓ -ËŒ‘0t -Y—WŽ;¤SŸÏÁåCB§":¨”sˆ -P®.h"˸r¤_mwö‡‚ -yn$ÁJB…­œ¸±¾öZ–oŸ6Š" ån Â'µ2·­R“ˆjб<ÿÚI}jXöÐøk - “äyf¼±W’tfŠå ½áÌz,Ÿá•1Ä«rUv¯±÷þðvàØàv”âÙbLàб¬>&ŽM W^Nù¸}²ËÒ•'>òe!ȲÁ·Á ÷mYŸÂ°\ã-€äbqÒ{*|YÛ -Q>\ßÞ^¾ÇQ8xUÄç‹]Wo¡†‰ÑAe,JYOÔµ‹Þ*meJ áµhé‰Ú–"Þá¹z­Šm¹Ä—ÝÓ -6 ….¼î‹^`BË|!M -†m¼RádóHæuói¬0„^ÂᾘÁ-©.v@ãö¹‘2ÿö7Þü@z¬7x8Üê{Ž PòýöD‘ÉwZŒ‹ ýÃ|9}ýäNQÐb,b(æhˆ)˜Û$7òz·qÙ ã!%u`;VJ7°®_ØÔÕ#B÷ö¡¬¸wÏê+Âg¢é}µóý9q3|ât¯_.½Letõ€³¾@ -üÅsù2½‚¬Pê,$V‡:/¥Äaöž°öˆ#š?Lòw -Ìa•o8”à=|6ÃÐí©¢ü=ê,Dô£e)ÜLb{£,cÏäz¬pdÑqU¯ìay*!Õ”™8ÍB5ÃÃÔÝÈ„qHg'Lø4îÁ ‚‡ŒŒ=åsûûäÕø¼§µödK•7õÎÖ_£oÁÈ×]QuaoJõÁI‚Ò¸”'Šçfßç>Nšx¿£¥ôRvëÉTe_€ôñ—ÿ9çÜðq#ÿŇå©á¢o¿Îºp(ô¥È¨½ -1™dJ¥o¨Ðë„ -¬} ->uFtæ:¶â4=Ö #“3C0ô§œ zä>%ÐGŒ5%.ëzCß.z]Øë’k¿ï'ö~©÷L"¤;~Ì6 X¾Ïå?z -%Ô°S1Ò%¨Â¥Üû.×…]¤}¾×"ëÿSÃ2ÿ-‰÷*6§aÄ÷ÆÁftž¿QnޱŽkXµ¯aÝë“=ôQP–(%NsÐcͰ09­ÔPÁi=åaÐ-£0#Rpûå3ª¼Ü|ÀŸøÞ*y^rþÉhôOðNߟ¢ëˆrgÊ­TôŵQÆ¥ö¢.­RrèQkWñë=·õ¶€[V< Q:ÕZê¹/ªÔWéÔ»à™ÒÓâÊãÔçÚE:(Ñ«`X -OESl-¦Ú<4»@ν­ŸqÊ 9Þ<&õ;L»"ÆgîúñKÚ1Rï7i;ˆÍ˜€w…Çžñ„ç©~CáGX'>`õÍbûnt»Äá»þ#ùì°Çîš×CÜ0xP’ƒj§,U§ÐcÍœaR’§) -¤P“CÜáçPn•Ö-¾@Ý¡ÛÜà€øßpÀ‚þFÙ¾ÈÝ/öû½÷v]<—>E“2ò·,ÃWÚ‡àïÑd$~Ñ…¹R‰ßb )tßL^ KQÆx˜M°„rï±ÿÙ‚#ÔŒ uýbÈË‹rãà®)ªö¾1ýÜî|êËéUp.‡G²ÆŒŠ!CL™Ð*‡:@£BÉx‡â -wˆ÷»ÇÂ÷è½='Ö.0zÿÚ/B` É8\Üí;”„&j7Å3áõÞÜÖ«x®Tu_ZKW7m¨Tº.dÓ}ðÕÊsÈ”™²° FšI‘É€Àk»_QÍè1ëØ_þ±ÖðK6¨­ežùÒ)²_üü+[¬aÙ?^°LÚ"_<à ˸µb±½P¹Ìr%eìÙ\Ü]ük`8 SOíß@ºe’åü‰å"³6W§Å²EZÈL+iÏóÂy xQ3Θ³Wy–çb<^!œgúüùj‘IÃõÂä9œ¹Æó½ñ;(m–kÅ=!gY.h(>,SÍ“{ø+’£óžÌ³0 §"ìÌâó‚gLY+‘hÒk÷ t¼¹ÞŠÅ ¬h1YTdœN9‡Ei1±Y0U ù’• + +_×ËTñ<é?V¶Z·qeçð¥yÄ'Ú¢oÙïà©,Lp¸ZNDpÅ2&´¥íhÛ%Lé\Ÿ6íR°díZš4Õ+W™áJÓœ®/{·uuòÖ#ÅꆺºýnüRÅêùEõ câëR²Ä­ý«—³H9˜¾ +hųMëIabU?i›ÜO€;|ÀeÕܹ°ŠÄyWpõÚ­3ÆA.;‹Ê=ˆ=zhÀ—(_Mås©2[Iò5c'ä –)!ãÅáWÅòÜVõ¾wŠöè•Ðè£ÛòkµÝoñåK¹Ù»×Ô1&VFuxqZ)Æ'êÈcu2DU™[(€ð5Sšç§h¬p0*)7]ƒ-0‘>lk³ ‡–G›¢m³÷@ïÛhS*B"´~¸¹»»z‹mXcµÆ‚,Ëj³ÇÃꈾ‘Loƒk²8¹éX' 'X^•Îq}`Øß <ㆌVïÏf·ÛT.žOƒÏ‡’:¢/@n´¶r4«z<8Ð͸yxŒ$©Ÿ3·èâÌpã«•C©\Ââ báy”šRG©*lTù5­ÃJOaFæ¯Ë¨N(0 0ÄÛZs î—@ ¶AääÁëýÊï¬PIíúç¦ý„ƒ}[>úqû­pKø»|…sCôã{v®}lZ¸Wî;ßcé¼D>pèúf´D«ÝXê¢,ëîÙµx,»™*ð9Ë»;Ú΃=ÐE¦ù€ÁV„Lö]°BA@ O´h”¨çЇ÷`•èS~z´›–º>ºŽúhøRÕÃx”÷#ª™Aú›µž­•@Õ  z¼IOðËÿÈæØ\ðqsŽñÐfºP&¢!; ‡RdæF±—7ŽØüØìÛ4/ DaJüšC@^/Å}]9„“Ú¯ò…´ñö‹¨ Q ó÷ØìB{®6*5DŸu¿y!i—D7p‚˜¡ëŽ$ u„J%>žÈ}ú`ñb:‹GJ+þ:MˆÎ£Q$ŠÛ|‹`‹¬…Œå5Ùѱð9y2z&â¦\Gd×Ó«:.ÝèbÐxþX­>ÎæLÐÅÓêñ2Ñ κªËö{¼Qîš®ê+•¾¸<èR)Â]ˆÖ‰š4Ÿ»ãÚtO³©½Ð"Ožû„]^˜Á¦7tˆãer‰½1$)è^‡Ù¿á%Ü`ï¶|ÁƪÜwDY†…éç½£«z{šA€µok|¿»º]ÂVý篆\^ÿôÎ}pÈñDâä5‘r›¦ë}ËâŽvØ‹£Ð ìwëÖØ1ŽÜÞváX}Û¯¼Ûûó´%õÞÜá3Ü%~à),ßw]ÂÏ›KlÇà<”‰Á|Ý'ÍfàùDt²ÃÝ\A@pÖÃ$ÄöŠiýº‹M©ÎûØ@œ¬ªÓ¶iúîÈÁóåùºèê„왋A„n•1sátg!r#ϲcz’°Ñ~7ˆ¢–œªÃ!Ÿzla¬·üó¾¢GÉM ĸ‘Êuý9¯I-¤6Hò@N(T&Õ¡–«•Ûõ½þ~ÞQÌöKgEn +ºBĉK&GÌB‚#Ã)8$âpéÉ\dÖ$—E¨€gkw˜ËÿDg%õQ;ðs7]aÎÔî +Hw $²àH`5&ÿ+jwÜ ’Eas`.ó¿¬v§SÎǵ;k©À±˜€dŽaÜ{¬Ì€ow›P4sT¿©¨ìCEdhÙó¥œé~~ÛIØ{m™ü3¥œ× ö%+ +cC=YÁó:˜Áí™ ^Ø×Ál  +±]õ”†ô²ê_Ò€þðvlÊxéf1p l‘ê„3`ÿ‚ä®Ç¯úùÄ$Ü|&†ÆŒØÛÌB¨Ü`M€àbßï‡”×øÃÕH2äÔÐ ¯Ë~’EÃx¹ï›-d/˜§†e…åÓ\ÔþöV:yrµk)t„ײ£'>ˆ3‚–"Ýá¹~©ËmµÂ—ýòzGýõz¸õ`í€jÌTÉLøjì)¶Oä^·ï§CôétÂñ!óÅn« :Q™8ÔFJøQÈ™6G†0PýŽÇܨúÂQ +þ å¾îèf +U ;¯jhªj [ßìü*JšŒé Ý9ዸÛìLƒÝm|ôÂx I}³›¥ïøØÕp$ AþFa#F˜ +ž$¢Gø‚gðêRqÿC{Üi?¡#‚a›‰ª:ôE§Ï13±” T" EÃ7š0Oκ„ |ŒÌàÚ>WÃ~Îj¦,JÄgȆ½yB~±h [¢–'6ÑÙ§³v€VÁ‡ØFžÊٹʬàñã­ø=U_ðCÅ8Î:áÔ›Ã04W"€< Nào¾{¶ÞsIk„¾1ǃ—ûä±( /¡¾ ¬^\ÙvT—V|àñõ­Ù˜µW6¯¹¢BÌí»ªÚÇ‘TÝCuGPÅHø¬¬²B ˆ>U‘¥Ðð§‹­©ÃÒ¨ÅjßbÝ +ì@’GXe:a TMØTÛj¨I …âI9vµiVŸ¨"ñÉ=ûàÙ=:.Î…ÈcIülpø­Df/_*aG6ëÑûüS3üÌþ#jO}ƒ Ø lÁª~ßr•XY„Ž»—Ø3">¾£^ÝGN1›À-ÅïþSšŒifP”£°$Ö7áÀ6ñ“g[ÆK/Ô‰zÈôëƒõ—²­š},>ñ¶ß&"ê£ÍÂ~6--`ëåïr¢óq\$ŠgHîœÖÍÚç¦âLiÄ«ò¢cæH#3Æ!’jp‡Ÿma xŒÅøø$’ƒv8y @eqRƒÏšë¾BœT'€Þ³áCÁz>ï˺¼)È¿ Àiž)` íÓ¬p÷ú8´ž«þãl¨vÏØ€ÀñïWÿ]r>Äùž?ñAL@bj¹J®'ÁÛdVŠâ\j:Ô! 'ÏŽ 9à7ÿ£ËøýnÈOÎ|:…´*S0!¥ÂÇ>}lö l²¹cÕÿlfî endstream endobj -1372 0 obj << +1388 0 obj << /Type /Page -/Contents 1373 0 R -/Resources 1371 0 R +/Contents 1389 0 R +/Resources 1387 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1356 0 R -/Annots [ 1376 0 R ] +/Parent 1359 0 R +/Annots [ 1392 0 R ] >> endobj -1376 0 obj << +1392 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [289.8576 392.4739 338.5646 404.5335] +/Rect [289.8576 239.4581 338.5646 251.5177] /Subtype /Link /A << /S /GoTo /D (dynamic_update) >> >> endobj -1374 0 obj << -/D [1372 0 R /XYZ 56.6929 794.5015 null] +1390 0 obj << +/D [1388 0 R /XYZ 56.6929 794.5015 null] >> endobj 410 0 obj << -/D [1372 0 R /XYZ 56.6929 769.5949 null] +/D [1388 0 R /XYZ 56.6929 661.3973 null] >> endobj -1375 0 obj << -/D [1372 0 R /XYZ 56.6929 749.8269 null] +1391 0 obj << +/D [1388 0 R /XYZ 56.6929 635.5371 null] >> endobj -1371 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F62 1060 0 R >> -/XObject << /Im2 1049 0 R >> +1387 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R /F41 940 0 R /F48 955 0 R >> +/XObject << /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1379 0 obj << -/Length 3862 +1395 0 obj << +/Length 3964 /Filter /FlateDecode >> stream -xÚ¥ZYsÛF~ׯÐ#Ue"s`pÔnm•ãØ‰·6vÖVö%ÉDŒH¬A€!Éʯßîéž!‚RR[ªçhÌôôt}òZÀŸ¼ÎL$t_§y!Íõf%®·0÷ý•dšµ'Z©¾½½úæN¯ó(OTr}{?Z+‹D–ÉëÛò—Õ›^ÿtûöÓÍZ±J¢›µIÄêÛ÷¾£‘œ~Þ|üðîý÷?z}“Æ«Û÷?Ðð§·ïÞ~zûáÍÛ›µÌŒ„ç¯páwïÿõ–Zßzýã¯?ÝüvûÏ«··á,ãóJ¡ñ ¿_ýò›¸.áØÿ¼‘Î3sýÉÒx¿³Á’Ð@ ¾+¶–:#ÝV ˆm„ŒY{›bw}®â:ŽÒLyƒx¬Ð¼ÝªÖ¹eTf`¦¡&_À¯#Ò3’>g*ŠÓÔLõ9(:wwë:1MÄŒKØãö.9r‡K8̸„MæZwLv% -b”"%†ñç‚ c‡M›´a ZÐoZAHØ#ö"aãDRi”¥ b‚­‰Ž -³ç™T \L°5É¢D€VNØø_§×ƒ,4ˆ5j3®wˆ¿»);ß1¢³g~BCÄ©ÒDMÎB“Çí55>Nè_8Õùºä36˜¤GI1îœ-TôyÙª¸8_í¤Xk#c…ÙL¡Ð'C“qjO¢s­Ç2ûµ_Ðeô•˜UÑ+ŽˆUÓBÑã®Ú`XSø…¿tÛ.'!0(y -¶#ØŽ} yàD ì¹@ùâá²xõ®¢ÛÇuúm)Å&éNGÛ89?¨†ðN§Ð~þ¤iâÒ“«DVŸÕÆ¥¬®k¿®I -Ú$Q’©d -c ñ¡iLágj(T‡þÖ6yš†á'&Û-ÅRküt?¬7íþòpÖq~„ÜDrìÚÁ3Ó«moiOÆfØõqç|DêÜÉá€7N­¦De%Ôô>‚Î"“ÇùT%¼a«T_º0°<é W‚Ö€Aâ”ÀŠu[”¶|µ ºØD:3ú¥È W¦*8þ'Z¶ÝW,¡®Ý[»÷‡`©lvvó…ù`Åw2mÌÐøúïøéƒ=¢$¼V`PB.=Qªf‰%Ê´,\AÌ©.›Ó‚E”I™½(A+F÷¹á{^ýP€«Ü 5è>0¹$Ö<Žô 0œÖ(ÜnÉJp^:Óv´OÙÒ©š¶§âp ìÕg±ºpT©$æiÞ$ŽÅãÒQE¤uºtRBé¦pçSÓÝÛÂUž <Å[0Ê› „û€¶»£/1)L”%qþ“±fÂ%-ºÇôÝm~ÇÛQºU¿#Žsôª+öÜr‚¦fmlM„Eçö»Œ+R¤‹NCL<+4T4[F(DL“'/›Y,MЄ¶Ám·Ã± ŠË“pC1°âòxÞî)¼‹]½³{Ž™iÐÏB wè©HFêÂÕDª²Lkˆws²)˜ñ;Ëú¤ Ëf±…àóX•¥ƒY®Üiuæt ~Æ¥S&8Ng\ÕÍÜ•ƒ2r0T5›z(1§áEîǤdOê¯ B]#üu¯6EÝ«øË—°œŽDœÎj)–Š#‘ "\œßªk2ÞäH×ITp|>Aq9Â,%8×?#‚þ]ˆÒc þGèøù(}Lu9JTÎê -DÛ­ý…ÿ>ØãÓ+â ÑÅù9—*ðy6ÕŸÓ(H;àž0ê ô"¡·J_TM@ÆU_¹š )/Žc¬Îï$0V¥y*ŸÃlx/fØßÙàƒ$…Îc5”R¸áØQç - {ˆy‹Æ¶Û˦ɦ¡Q4OÔØÂ£ 5I¢¡Kª%'F„ozÒPÆùû‚ö¥Qgv~G|õ;ðSsþ>[4°MB€òKk¦£’«È„à®åo–‘Ãb‘bð0ÏJ@›=8@bQ2¾D˜¯Jª„)@Q”e…FâîÖ±F‹Øë´%{Ù˜$äÑT6r;õ€2ÄWÊa°³õ=µú¡a&¹,nBv㞦W29x?¬I…¢®€¬IšY–Â{rý~ëv»ÅZ?WxôTY¯k¸¦0.«J1{)$…Å*Ø_ HÈ€ß2 |C³Ûµƒ‹¡M«iÈhh‡/±±'Í…ªkå8‘ lÏ 9”ƒ_RuhôãšM1'&ÂF¦xç¾øb™]w¿®­ìòË3Š,¤ÛÈ S­ÞßÓƒ¯ôf>*ÖÈÑ‘ æVKqŽ WÍâ_ -HÑ6³,àþsH>+±â`›ÃÞúÝ -¾ìŠR1O¥-j6 ‚/A.ðR£ ›ØVYb‡¶ñP•¬N¾ž4†˜òHããÓáê]”h5ß<»¥ØHÓÕëp_¸»ßñžŠÿ093u˜äÕ_-¾ ÂzBž3§±ÓVîvÎ0„c¶=‚`«Ó&#C×ࢸ㹺}䬲¤ —îÄÔg2¸—}8y(1w; rsn‰}Q5ÛÎŽ34墡‚`ŸH å±í¢S>¤FOÚ³û4šQ²nZ¦unß°XpÂÕ8<Ôè°@ÃÏÕå©0Õžž`š`g1Û™ùDCïè]Ãû?ã_ ÓNµ³À:›r#s `4믈WBÈ ¢Uàÿ¬Œ¥ˆ#P葌c•‘Œc•:ãÀHÆqª¼ê©l,cìúš–žNP8t×(lrõ‰ž/"­ö‡ÖÕ™ñÓRd,¥‡¤féèƒè¥`ÂÛ,÷qüÅ8UIˆ÷QÏÆ©cªËqj "8ë«û§uiëâéüÞ^®Ÿß=P-l?¹ÐØD9D„ÓýÉ+§‘ŽürÍ%ãT<ŨûÒ%j^úGkÃTÃi,À9$´¨¤“ðÙhŒ_ëu4CÞ† úAðvõ´|Ì ª p†4ž¹¯ƒKÑä’Q.’KÂ<*ðâ§Q„Ëäf a…X};Tu¿öMû\–Cé\Hh\Öº Hh)¾üLG¯Ð²ÓbøŽ‘ʰíCUZ~3Ju0líl}¸j",«bÛ´ïšœpAoTǯËéÍ=Ž{xÂ!WïÏðMŒ?öˆGf7_4ú^Gƒï:tv(ÛußÖ®æ±.[Dÿ¥ÒŒVQbRäwUS.‚U*½µ9–`— %p :õ¡Å›^ü¼°"*¢y—`q È -¦ÓpfLæCùW{j9YQ»#‘AŠ8}ቷl)u$!»{áIøBpLn°g«N^(™;5Vú6t”ÇBMØY€ ¦z‹óÕFiðàŒ~GùØô¾ È’®¨2ª¾ì ËRl©\–‹u ùXчcížæ8Ü‚.ñxá©K,*‘E1(/ïþþÃ’;ÀHc¯¹ ó‡lœî!Hª„Óa  /òª?LzáþÁGÀÍd/A ÖÝC†Í €+?Ѧ%昪qÇ‹†~í×C]m\0 =ÿœ!Ì‘Kj¹V‰‰Ò,ŸE5Ï ¡”¹ŠOI¸Í.¤Ø>ª–  m¼üM¸öÜüߟŸ0N#eê«b‘€®ç©gÊyp3ç<|7|Îúÿé5£ -endstream +xÚ¥Z_ã¶ßO±oõg…IýŠ—d/½´¹¤{›E’Ù¢½êÉ’Ï’wÏùôá iÉ–½ ŠÃž‡äg~%oü“·™‰„ÊõmšëÈin—›q»†¶ïn$óÌ=Ó|ÈõõãÍWïTz›Gy'·«ÁXY$²LÞ>–¿Ì¾ùûÛŸïîæ±³$º››D̾~ÿá[ªÉéç›?¼{ÿÝÏoïR={|ÿãª~¸wÿpÿá›û»¹ÌŒ„þ1p¡Ã»÷ÿ¼'껇·?üðöáî·ÇïoîÃZ†ë•BáB>ßüò›¸-aÙß߈H噹}‚ˆdžÇ·›mTd´R¾¦¾ùxó¯0à ÕuÒŸ6YdbÜÎ•Ž²ƘԲˆ„­ÍS“G‰ŠUÐr,§´ì¹PË]µžÃ_S5ô[ôûíN/3P`ž¥·ÃÎä\‚¨ 2—Qœåø¸µËju€-ˆÍ¬ Ÿþiw'³™ížÚº¤ªf¿YØÑí +õÌ‹M¼¾kÑõRÕ5×ÙݦNKÅ­ëÐ.m×ÁâGÞÍuº•‘R`ÀRF¹1±“µßoÈT^žlC« +ýüÞ6–ùªþiÔÔØ"¾ýðñ÷ÿ¹“RÎ"ªy|âN¥]ûº§Bå¶ä«wz¸¡qªÀ]T ÚG±¤ ž±®Ynb‰Î¬šM'•i”Jõš} ¸®Ø—ç:µ¯þ°µg–F s‘\— pMˆ0ZmΙÆcަ•k·ð³ÝUÏd Pxø–Àÿ{KUNT¢Zü5³—÷-‰âÝjm»+z2(²<ÛÑ, @ºlÝoÙÁ~k­Ü~;K3:Ša#K{Ý´Š´LÞßÄe&¬ Σ,Kó¡€*U¤„6è·‘à¶Øö'“'ƒ_3³_@{½[2Ô²[9Êsl‹]±±½óJhØ"œÂ¤_ö¦}¦A̬j¨¡ ŸÕÞû.5?Û]WµÌÓ6Kë'´C.š= ÒõES¤YbÀ¼hî‰ûÈŒ¹nîC®Ëæ¸P}0ó]„>ÍûjcßÐÖmŠ/“ÕŽ»ßÎy}åé +T@Ï«K\kÚÈåJÇãE€Iv fp¸Y»ía/:*,Û¦'Ь©¢b¶ÎîžÑÀþÒ‘uÅ eñØ ö©x®Z´¥fn—á—6våÑž<ê úa Uzö«0âóþNÎìîÀ\`@~¸?¾%bùT4kÛ·ä‰vÉúÐYÍVEU;úßM·ó×TÂÌ~îp*BÎj êÍ׳NJñÒhö<Ÿ=õÞC@“lyFªÂ^ PE°g( ¬€(8ûžêzÚ‡Ó1ý2Ð<3/¡›¢C§„-áq×Õ3cQ>ëêâ™ùüÞ¹¡ËùxiÒ[uÕvúvב‘ÖUß×|PÌ+ZÏ8©vG.Ûô]& [œJÔÑâTÞ]×í Õ»u¹ºr ·µôë”áx¨ŒŒ<¬]]SrmñÅמ™Þ k°ª÷yºõ¶rè4Ï·SsÜgôh­CÕsÇ~Ï\µ!£Ôñl]· XèÁGJd^!8`PŽ{0Šª$’ì ¿±ÈÛ”4A×ïT…Bu<=7ƒ·ÔÅf;µ¬Þ‡"dÚ@œiËÅ4n Ðê´å6´ÅæâQ#Ž#vx&ÿ*Dl¹/øEÀ6¸3\ÅëÓe¸öLnßʦ›ïË-D(¿ŸG&:b™é«s¦óÉGq îpHG³´=ªGĬ Š\§¯(Ä€ò=ćDýüíOD,ö+TóÊÙ›€ GÑ]‹;W‘ãÐ[?pK¿cÎxìîÂip[,?ÉYGe[l8GB«Y˿ѴÙ"Õ±´X-4ᄃV-ò„jÞC?(·û¾«JKlq@õÑ*_*æš + ž¡Hoz×8yùß}‡ë±%ÎÁR³ùbi¶Â)tSgÒÉŠ›P<Ôí»}QIë,:w°A™Ü@&Rh&G!kŒ×@ɱٙIžXR’Dyäœ3wDáOÓ6óãr ‚–ãH¿ßem™‡ iº8ûøô†ˆÑı<ÄY%ÀDºŽ(¾¢µûõU,¨ü Cc,£“V^ãB/ #{Ý.?¹Úë ìÚ>M‚vÈ=c¾rh?îã„?cvÃOàÙÑ pÖ¼Wýñ¬*ø2G +„󤋘¤ÓÜ ~%ˆr]F¥ÀåŽ[ˆ/£RiÇæÕÙ×Äôc\’‘>™`IeŒÖ +LOLp :4¡L°„,´@ÔwÅÚRa`»£ûªH¢XHÍÖÛÀµ¡œ0q¥!½CÐýÝjݱŒÆ Â4DòÍS!‡„üŒ$Æ‘NSsÁ ðpw»®ÃÑ„f\BjˆKX¸äØ.a5ã’,uB× d;‚1J‘Ãx‚mÁ…±À.Œ$Mcƒ&ì›F€»#’CD²C$$® RœFY +Æ#&­ñtd (öˆH8zA?#D +¿¾Áá¯ïâ ²)„iÄæ°Çí©ÌaOU‘z„Hx~ )ú‘‰/¶ÈNè‚ä‘°glôˆ4ê£ý9­ÆÌÇáÌC šŒ¿.!h3EU2ôÛ”v ^2s$¾:‰»FFÙÜáÎ à #œéO؈"ÊÁ¡þè©…ij‘Í_U¼‘êx¯‚êë2¨.2c¼áæ×v^°¡3b„­‰Š’Xe×…\RŒsQY”ØÊ‘Càëìš/†HhD³|ŽÆ=Ä_º89;_0¢³çyL'¥IYÚÛ/ýT.ME9>ÓŽˆã$’ú${÷òT-1,Ò~á/í¶»“ V® ¦#ØÖ>ÜòE ü¹@ýââ2={WÑî㸠ý¶tE’l§£i„œ/TAx§Ò8ye¥iâÒãQ‰¢¶ÕÒ]Y]Ñ~ád¹2I”dÇ$&!rH ¦œMM9›š†Ì)5Jb¤!Årz0)€ŸŽâ‡ù²ÝlAÎ;Η›HO§¶FðÌÔìC벿ix*HCB7¥w¨à\ TxçÄÚjÌTV1QCMï#è,2¹ÎÇ&á;NÕ¥½Ës‘¾²5 h$Ž·±n‹ÓHçªÓ&R™Q¯E^ธ>÷ÿ†m7k¨k7–ëV~¬•å“]~b9ØðN[̡ռý î½µ;Ô„· + JèHOD”Æ'KÔ3XYØÍW]v§ Š(“2{Uƒ +=V ö…ï†ïyômGår_œE;W+ :†SÁ•ÛM/•y;š§liUMÛSE±ÝÒíÕß u|a©2–xOó.±+^¦–*"¥Ò©•º‚\7…¥¨­U]±aÊ)šÈÚ>Ûš‹Î ìgf¤È…˜“·?²:±?&àöÿ9…@¨k„ß®áÀ¤h{/czæ€Ó‘Щ»Ö…+Ö‘Hƒ.žîªo2ÞåJ&ÇIâpðù Š»#œ\ Îíψ`¢ôbÛ Æ¿¥¹.GéË9C]á#ÁÜoøç½Ýc“í§RÆ \`Á¯‹¸&äGA1'Ü#A}‚^$ü#ŒOª& ãª¯\NP„+/Öc¬Îoü6%|ZûøC>A rÇδâl(]áö»Ž.q.º˜·hl»ga½Q3?˜å0õˆ5tmˆ$†t,™–9سICç¯Ö—F©Î<ì|F|ódß|^Ö|?4°MB€ò·Kc¦ƒ;$g‘ Á•ùRƒ-X¸KÄ"i8að­s\,—v뎻j)Â|VRæ`»å/;SʲB'q{k‚Z£Iì…툽WΓ„{4¬‚3õ€2$gÊ >öÕ+¢ú}ÃBrZÜ„ÛëMO2¹ õ!©€[“4c òsrþ÷Úõsýœe˜ú%dé§U¥8y’B\xò£'ü$È d÷Ôî]¬4 +@¤àþ@UOøˆÄ†,(4×Êò§K +OeÂß$lê@ôã Ȧ8e&B¢ +MQ,bmåó@j€ñdMšO£åàÖMôîØ7¬l~„— á~uE÷TÖPæ ~¦ÙÏÔàL4ôFïþÿ€N3ÐÇ€9€uvò(6pW1¦Á²þŒz%„œ ªAþêX +At¬cþJDÇ©Ó1V t¬ÓØ›^œ uŒE?@ÓRÿýÖ) +«íõƒ$gŸ¨ÑkµÙ¶.Ïì˜S‘±”?×;y•Ùù`Æ/z*€ð6Ë_ÿ¬1Åd¥|嫯#Ó•™‰°¬¯V‡yiëâpþ>‡[—««S¦ó¹G{©M”Çømä`r:SG7=~3‚Ž’ñ%<ÅxBúÒ]Ñ2L¹ô/Ö†¦†/H0ߢdN £:~Ð먅ÎQ¨.èaÛeÒò¡@>@€BÈ+ÀR}’ÄÛ…pÀ Óp8‡†ðѥϯa<üfzB«"|ëúš}ün]Ã…?b›Î…‹$ÊbÌB“Pî ̷̳Áp9‹Ó Ñÿª£eendstream endobj -1378 0 obj << +1394 0 obj << /Type /Page -/Contents 1379 0 R -/Resources 1377 0 R +/Contents 1395 0 R +/Resources 1393 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1356 0 R -/Annots [ 1381 0 R 1386 0 R ] +/Parent 1401 0 R +/Annots [ 1397 0 R ] >> endobj -1381 0 obj << +1397 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [353.2799 540.398 410.176 552.4577] +/Rect [353.2799 390.6622 410.176 402.7219] /Subtype /Link /A << /S /GoTo /D (zonefile_format) >> >> endobj -1386 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [84.0431 109.336 144.9365 121.3956] -/Subtype /Link -/A << /S /GoTo /D (view_statement_grammar) >> ->> endobj -1380 0 obj << -/D [1378 0 R /XYZ 85.0394 794.5015 null] ->> endobj -414 0 obj << -/D [1378 0 R /XYZ 85.0394 184.8801 null] ->> endobj -1385 0 obj << -/D [1378 0 R /XYZ 85.0394 156.8765 null] ->> endobj -1377 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R /F11 1384 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1391 0 obj << -/Length 2882 -/Filter /FlateDecode ->> -stream -xÚ½]sã¶ñÝ¿B“—Ê3B| Ó'ßÙN•i|W[ídšä–è3çdR©sÜ_ß],@‚2Dú&ŽÇ`±Ø/‹Ý¥ø,‚?>‹–d"›éL±8âñlýtÍ>ÁÜgÜâ,ÒÂÇz·:ûîZêYƲD$³ÕƒG+eQšòÙjóËåæ8àà°ßÕMA+ÌÙ`sX?ÄÞB—¶E“àd¹)ª¼AŸK· -è *‘S‚â<‹ Ç'ºý‡ Ohóêe7- È.È.J‰-b¬ÛC¾Ý¾8üæd3þ†/õaO½Îq,D6åààl‰TÄGgœè ‡ûkèÉ‘LÇ©sïg3{'3É"éáîýOü]"4SÑ”¿ó±Nû» ¥³g$\”›WaGÂ2Îõ8w‡à>tyœ¥™r§S™êùò’ÚÖ:_‡}çëÒ#_—â¹+*f]”_ÈÌÊ©¹¡]…ÞGuiÎï¯Q$/ÐÍÝòÒ^"€ç䜣뙞×{GÙ츈˜ÈŽŸ;ënyÆÍ>óÌî3N¸[ôŸ1wtyÉî®nÿ1óëóǰ‰É0äA§Bj3­¿&ä1äNF7OøÛ\lÒ»X$¹"D½Bhçp†ÌÅ­Bˆó@díD1¡²dèXŒã޹jh{¿„#ë—°kœ5´95ž'Ì:O„ƒÎ¶í=áwž‡ä‰°×{"•Lx¢hx€†wÜŠ>펃CËÝ‘YsìxFA¡vÁ¤ö¤Ô±—Rp8LÝÃÒyРw$"ëŽívKKÖù¡9#H1Z©‡âHÇ2®Ü6'!Ss$NÙi«ü×ÀyCPû¾"ßWÙ2ü¾šEýûªUäbwÕÅî÷F ÈÐ24àk$¶2s—¨ ÝFÈL8‹yï€èFœˆÎ…סÒîV†èÁŸ2ù­þ¹ÌŸCĦÏ1¾…ÜýPnÛEYÑËuõ´k_¨ûoàÛÃñ&Ì¥M¼1›¸±œ?š-ˆÕ¼©Í¦è¾£Ž£‚¨#Ê uŸûpAð¼²ÄnAmÚePWÛÜ<Ø®D˜íj,Üðið€þˆ[û˜·VJzˆÑ=˜õþÉF'vÜÔ’o0ä7ÙÖk‡“äuÁS–x!WæùЯêvH¼7G=‘e6ÄDÀ²j‹}U´±tÈ8Ö©¡c‚h n \Gkðu\—˜j -)½¸LªNf€¯kzT¥¹i&œ„.^™f—¯ »€ìÐöÍßü|ùá§‹å h¶ÙÕUC $©%•O³÷V2R &!ìò}[®¡}9ls“ðâóŠŽ”Ž;¡µ³tHÔÑ:p˜Ðé@x¾ÙXIZ=‘Ÿht{ýž–Às–Ú5f·û¹x.%d,” -À.¼X´mSÓÒ²Zo›"¤I,őĒ$†y’àË_™#H@O šÃ‹ÕQÄ€·ãSUlðê  eÒQâómY}£Y4vI{ÎçNb_z·½û|ý™<ÊP@#ú‘³¥½Cõ¹ªŸ«W+YÇ#…hMqß !ík„½¼mÑáÐÀ?h7\¦'“Ôá°ÄÐ]([ -ß]὆%µµešÍ Š?ʳJì›MAZv EùÅ.Ä- ³é܆ gÉc -»úLnk³@Ç:"N—vl -ˆëö9>[6ÆõMjí=ò5ÐY[%Zk윚¢÷ùVcè¹Ü¥Y7EÐø+·yëÞ8TvɶlÚaŠtÄËžƒ²ùþTEX¦œ ®ÔxÜÇ2É -¼z^XÅY"JýkOàS ô8¤ƒ£LÒk¦Ã" -¼åY™Fly³¸¸¼¼e·Ï31¿8©w"¨ü1®·‡5¢·ÃšÔ{Œi¯÷1Ó°Þ>S™Æ›5‡P h‰ Í=¬ÍÖ¤æcL{Í™†5÷™Š¿${»ö"aRB7®½‡5¢½ÃšÔ~Œi¯ý1Ó°ö>SÁðëŒx»öQÊ"™N(ß#èn‘&UáØk~Ä1¬¸ÇQ@bïÿ¿U‘fL«)øX§-ÐaM™`”igƒWLƒF0ØŸû[~L¦-ê*•é ‹yX#sX“cÚ[ì˜iØb>Sþÿ°X,ãdÂbÖˆÅ֤ů˜ö;f¶˜Ïô’]£¶oÓÜ|çúšîchî°&5cÚk~Ì4¬¹Ï4eW_£;äüq¢'â(kDw‡5©ûÓ^÷c¦aÝ}¦ÙWéÎ3ós"–ò±NëÞaMé>Ê´ÓýÓ î¦_§»r:›ˆ'|¬ÝÖ¤îcL{Ý™†u÷™¾;©;#Ų?Öú¹‰«gñ¸Ë7¸ê‹DoжÅ:+L¶ÃmÉ_Êâ™z[ÈÌ·–€É²fò5Z¸ÛQWQ®i—6令o@ËFKªón£Hw‡j;$‚Œ!g{,öek(AžîÕ0`²Þa¢ØÐ”I{¥©•t¦po˜«jnzñêă '@¬4›/–·1£tÅ™83JkFSó‰ç+Ü?˳ä}9V!Á<²Ó"˜^z²º ó[ê¿Ô—ÆVÜ£„W\äÃ. î­B(*dÙP…Ý?ò§Ý¶ø>ðy®“–£Jüþ!ýZÿ˜wAl“(šþ Õß!˪’ª™¿08œó¹ýd™%}qqX“Áêb^}rËaåî¸à§ûH÷œüÒæ°V’ÅóÇüKáU.»úVÖ!Çk _è³ó°R‡U\#vXžX$BšJ"Bv{,Ŭ Ù_Î`y·+ò½˜Ï К* vî ¾ûÄ,|P>Ðaï)¯l!»+ñÒZú6c06…Ï!v:óüWð©€{þôoâzw¯4“iz"´D¬Pæ£AòúS6œ<Èñ¢ÿ7Ú‘endstream -endobj -1390 0 obj << -/Type /Page -/Contents 1391 0 R -/Resources 1389 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1356 0 R ->> endobj -1392 0 obj << -/D [1390 0 R /XYZ 56.6929 794.5015 null] ->> endobj -418 0 obj << -/D [1390 0 R /XYZ 56.6929 551.4149 null] +1396 0 obj << +/D [1394 0 R /XYZ 85.0394 794.5015 null] >> endobj 1393 0 obj << -/D [1390 0 R /XYZ 56.6929 523.4719 null] ->> endobj -1389 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R >> +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F11 1400 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1396 0 obj << -/Length 3167 -/Filter /FlateDecode ->> -stream -xÚ¥ZKsÛ8¾ûWè¶TUÄ€$Ž™‰3ã©]g×ñÖfæ@SÍZ‰TDÊŽç×o7ºÁ‡LÙÙM¥*Ä£4úù5d¹ðO.r eõ"³:6BšE¹»‹{˜ûùB2Í*­ÆT?Þ^üðQe Û4I·›Ñ^y,ò\.n׿G?ýòþŸ·—7ËUbD”ÆË•IEôãÕõ±ôùéÓõÇ«Ÿÿ}ó~™éèöêÓ5 ß\~¼¼¹¼þér¹’¹‘°>áÎ,øxõ÷Kjý|óþÿx³üóö׋ËÛþ.ãûJ¡ð"_.~ÿS,Öpí_/D¬lnOб´6Yì.´Q±ÑJ…‘íÅç‹õŽfýÒ9ù•Ç&O²&jN€ÆÆ©‚)`UoEÛ–yt,»ãa)óÈÁ3µîðè-u6Íu±sºªSãà\ÏߨœµÍ Þ¦j1v¥ïóNŒƦv±òÂ÷ÅŽ•Žm.Õ„kGó™ZÄ€³¯Rab•fÙäL¢é©PC^+ -†§’B Ôéb¼ï‹Ó{ª™ãÇyNjgÖØéùŸ÷®¬6`PJÙèɧl1C¾©ç½a«Øï]Áó¨rüz•cƒÂ<ØP¹G>z?ž*ÿåIŸC±Á¦Í¿Ð¬u€]m¼i¯”sˆnS ¯Éc1×´œXðF˜-Ýú]ŸŽê“Ä„ûÿÐý°ÅN­"­[¿LQ¬o“"#IþºQŒ©ÎEO5EÙÔ¢Vaã$yëøžjæü‰U'â”Þ*0‘U`À ùa ³Ø`,˜¶CÀ⨨O̧¼Y SƒYà$A+˜ì#žîÍBKÝ›˜’*ý=fñG’èÿûÿÌ@ÐT™}à FT¯˜A ÌÀßy…Q{ë^ØdbHÄúuzª&&¶Ë8ÏM6åâ’Nörð*AäˆÉ8 AZAQì_ìB¾øñ9ÀÍMqÜvƒôy¼ÃBºçyaëA4^ö˜ê¼°{*¼&_i5ý¥° ä)‘¾ÎCO5ÃÄTØTÚ)zÁ*¬ ÖÕcµ>z0ý _höòšä c#ù*<Æù"°ökU*‰š}5JÕÔÔ-‹šÜpZeÀ.”HS79©o Tû`]µs„ðO4°³"!A‘¦2CQ M™Æ2‡ÂS½_¯«8*ؾ>»²#±x-ʇª¾Aê°9` @ª@3¨J¨m§´†ÇÛád Û¹wêY¶ ‘”`Ûpµ—9T²I®·~ù / ä¬ ‰Èx¹g¨¦Sªºsf‹9¡‰®¡¡j·§úꑯÒ -Rm»oê–§‰m(Ž®Hq RB’Ÿh*ÏÒhn6\û÷±h6~£ s(;0^¹ć+JÖ†ŸAÊ–šìÎ tG'Ð'dnƒï9ˆÅ÷кUyìæp¼G¢Iƹc]C1 “˜ÆöC‡Ò 4p@ÄEÝ>9½¹‰©qÝt.Rt3&Þƒƒ˜·LB‘k™3™w?d˜y]8Ä -S;‡¥yÕî‰ |±éX¯^™fòØÃ·¨×ÓŒXûÒdDÛ¢;} -èáÒ‡ëÏü8Ð3Ô—ðüp¬½„‡2j\¨™;2¤•‘çMG–× Ö~8ì¹óópé{Gm²ûÌžÚ=ìêõŠý?„îkéöÝÉÒ››Öu|w Øpù‹‚‘Ä;±+ÕÇsÑÊ ß¹móH?‘EwÇŽ&8¬ž¸4άթKã¹tðXXÜ¢‡Ý×ô&TÔÝöy)¥ô5©0ÑŸE‘Ý`‘ÛUåq[€nÆy ¸ƒ7x“G ŸcôÆvc–KÓ²kì…bµæþ±­º"ìc éÏ\½r­­ÃKŒ=¼7?ŒÁÐÚmÝ}Bæ©§ª{ )O4£¤ûí‘ít=kWÞöô êúx‹Ãw]Q1 Û ²ôµÚwÔ™¨FúÜ‘ Âàð*†½IþÉ Ù(’ÁG“Ñg»nÈoršßæMrµ94»Õ¹¸#…ŽS­B.¢§ÁÓ´–Ä©´!6ÕÍÜ6&6&‡/eMàwpùµ÷°C[‘|l#P–Ç{!Yï [/³‚cP7›¹«!à¥6{3À*¨‡EHÍQ¬ñ…*Ȉ©HÌÔ †CP—iqBÚ1©joÃÀ™wÐIü ¯¯EWÌç'n)˜ácÕ[ê p[?‚³÷azNHR‰ØêD}CJ”HÆY¶dO„VÅ_ÒÕ—cÅa‰FwGŸ+±Õ èSôŸi†üÝoÊ rô'Þ}ÜïTÙV»êÄÉ{»5'z÷>ªÞbä½wÏáe`^ª‰‘PB«4(­øºbɶÕ_srÍ¥&ë%Bw:ɤV‡S#BÙ~@h0ÃT!³*ʾÐßU5ù§åš¢zDb1ÑØ0y”Áçöøe -‘LàŽÁÉoK!¿{XÍ9Isìf 4Î2•[©•÷¥ÖËŸË4ä¿ò¹ÜVåÜ>ylàL6FÂR €ï fÂ!zÆiBc’ðÅöâ$ïôä¶Ûé­Ç‡v®Cü¤QØ`”õÜïÉu>ÞXyR {Ü„¢OTôKóäñ%Az’ÛÆ†dƆ3ˆ4¿úèo‚aɉ5˜8z+m7ìé¸:4Œ&˜ ¯~ãCÉÕlÑ8·cŽFF¥N@‰UQK•ö…[ŠP«)„Â÷?¾jÀ–·nÜÿX–Îù8,§–¦±{zqYo]Ûò¡› ?ºÇaöM”w8À’UsXÓÏ'6«s¨){P†ïæ`ôð!Ó‰ƒ+™Q#SþÝ GÂm8zÇ«(B±(¥¢‡‰ùàH€w’ÊW\ĚĦÐ2 æ<µ6ìî€TÏ{¶ãp—Éõ1¯n½Éûuhù÷èªn©WЧÝäQYTwwä@|i=“cÈ^•³ð¥ºÃï]´Ž)Ñ”¿å`PèÖ…S¸úoþôPr˜±d<ë1žºVÀ0“Â=`zy+fáämØrÓl¡*í÷ ÏãÚãnW„òb³…×™g‚™ÄáZH•ýoáúì{o–ÅI–¾ñÜ;":ÿÚˆfAÎô–> endobj -1397 0 obj << -/D [1395 0 R /XYZ 85.0394 794.5015 null] ->> endobj -422 0 obj << -/D [1395 0 R /XYZ 85.0394 453.4423 null] ->> endobj -995 0 obj << -/D [1395 0 R /XYZ 85.0394 426.3513 null] ->> endobj -1394 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F21 710 0 R >> -/XObject << /Im2 1049 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1401 0 obj << -/Length 2863 -/Filter /FlateDecode ->> -stream -xÚµ]sã¶ñÝ¿Bo•;‚O˜<]’»«3É¥uœig.ž -Q2'©ˆ”ïœ6ÿ½»X€2}¶{ÓñÅb¿°»Ø…,fþÄÌd,óÒϬ×ÌpafËÝŸm`í홈8‹„´b}}uöåegžùLf³«õ€–cÜ91»Z½ŸgL²s ÀçßüøîÍÅÛŸ/_[=¿ºøñÝùB>sñýk½½|õï.ÏÂ1ÿæo¯þ~õú’–²Hãë‹wßÄÓ碗¯ß¼¾|ýî›×ç×Wß½¾êtê+¸BE~?{Íg+Pû»3Δwfö&œ ïålw¦bF+• Û³ŸÎþѬ†­SöÓÆ1#u6[(Í🶲`V@²Æ³LIÕYYŠ)+',´r¾Ì—·Åb¹-òª¬6‹²j‹Ã]¾=U_d–)cålÈã$Ö„(j а’)Jd¹º-ट7 Bq ñ‡r»¥Ñá\¸y±«ïV›oq¨ø<(AТjeÑ| j~“7ÅŠꊾyü~ù3màäÛM}(ÛÛݨÿlá9³Êÿ -Á¼12ˆY€l÷¸~b_™1ǵKd˜Ý•ŇH'*(†,óý~[’]à>?ämÔARÈ¼ÛØ[Uâ!Lhƒf¦àBÎç^΃ì<æ€÷9& qÈ%ZŒr‰`J -s‰È~˜J8–y%]Äa].ë„Yƒ`ãÕc˜pÖt—²°pÑrÎ6äóŸZÐ}WTQ¶·‡|·Ë‚ÎR3o£k&Ð+÷¿æ«Õáý—ûC±.?n‹êšþ¬%óxóŽlöž0nêͱ¡á}ÑüZ~Ňӯès=eð¸y¨ïÊU±(?®/ !†4ÅïÇ¢i_Jc$G±ªšÏÙ»8®ö”¨:în’iŸ¡&Ö—‰ÐòªY‡æ³v/ î0ìø 7œFuU,áC¢øŸ$tuáM·EŒ™~Jéߊû&ùXø4P=À 8$ðþñÆØuôÑ?_®iSË¢×´ÜëIC$!¬‡x¶x 3«Eá_Ã’(‚°À{ÝßïëCÛEN®'äÃz™)Øô9wÙPÔ졨Þ2™…E‘ô©¨Ùl±¨’+&•õ“ÇI¿\ß?Ï X¢Z©3höyµ - -àIsŽd|Ú˜ýÉü?Äô‚I'í¤ Èc[Æ”.êÓÐŒi{(½”® žM¸Bb8é ×#~½.#f=8šJY¦Ö/f6¶‰r’™ÌèIÚ¤;»—›Jj¸Á¦|/ñœ<ÕÏ1‹y1³±Y4çL{7" v]Ó óž®·'÷×3ÒáxÿG£äW× ‰®ÕzŒÊb²”øó«©B8jË„†`é - ÷tômñ ç²*Û2ôÉ« ~nòM1Q•TFW·ÅD“)ËO­bà!-hp2ëSØ dãªÈ [¨\aº¼…Âu &+›¶\F`(_á{SÐ7ošzY™ÍcÍÌ© †OêÎÛ°êð|·F!C«í©¢ö´ß¹§­(ÓGÚ ¸˜Wà@.è §ú“dê}Ô÷ŲĽÅ*ôü¡A“+ -Üc›‚†¡ûQI¦†Ð©er¢,¡iàzþcÊy•Êxìê¦=á¼$27 ©mú:÷m‚JfÚäá»Ú†¼›§;‚6þÔ4­’³AËö°²†ÖÏÛÌÇ3Gû¯Ø²®Öîa ÿµÆd¬˜5Ð,°?0Æ~Ê =>Zé§ÜPáÛ–nhÕ|ZBÐSBæq—ië=A¶ô‡=BJu…ç°9BFñ@„l#BÉ—U…>QÎ'ÔRz£RgÚ°‰àÒÌ÷@+ô_¡—ŒgŽ[=>æÇùX‡Ö3unó² -ݧÃò˜ÀAStmöÄÙiΠŸ{ÎáI-°§ŽßÓ¨ÕupuÙ£¯'hM èÃŽ´$,J…÷©Þ/è„c}‚.'µ^]¥§“<=!`Œ–›ªî£V[N  Â] ÙYã¤7b@ƒ5ak!y:ó ûdÞÉ)û(aI7zèèvÊKh(Ä´ü_yMØã^3¸‰•Á¢ÔŸ\áñ-¡a]âD}0¡6óûúHƒUÙPz 3z˜Q: 6À0ûã<åBczÅ寮 ŽëcÜ“¯"ƒ¼ÍÑr™‡¦îð[‡Y¶ôÍ#•ØéãÞ—p¯»Hv}<€ß¦r* ñÕ†G'…„Ú~ò©ЉcÊÄëÉrÌ@\Çó!'OQdYÂJï7#Jpo‹.ÿtî9~-ÆgYu’»= à#Í3r·„‚Nwî=zü˜¸)ʼn[ºÖ0Ï­ŠoK|zq  ·E°z˜Ð+¦uóm½ÄZ a})G­ÁÜPwÐIÃb8aÀßåM;@éœmú  ÙÛsH`*‘@ "c@ËÌшãz¡ZF'' òðlþGÈ›8JÍ.Î *REømDïM°‘³ól¬•žÀ·ù] ÉãžðFÔÐjp9mmLWñµ>ðœÊJÊq¸³Ó• ö”k@ù¨U‰œO§” ÖJyòËFo¼,ãó­•T„Â,øË*â€¡Š»´c_7My³-äE¼§ég+§ƒ¦žÎõó}/ Ÿoc=0xx -ÓzTÈqijûgõ¡’**‰ÈÕ"v Ú5™Ùñ5tbOL?–„/UGÁKŸï­ÿzƒÿN ôIÇ_˜C¶QzØQv?\Áò*.“¥︧—\í GWX~lëô1àÔ|êùšRŒnò Ð€ï+ ÁhxuÛ×u,ˆCC¿oNË!j~=ý$¬Ü¼*‚B°«ŽI¸ÍKêñ¶/ÃïUÊ•wC }§¡E?¬öQI£Ub_·_ÁH§ô KÝñ*7¨Êp÷T)¦T,Þ›ñE9õŸ -¢QMþï€>û¿<úÑ–)çäôOÍpŸaêSI¨ðÔäþ²-™Êä„èÿ¬O*endstream -endobj -1400 0 obj << -/Type /Page -/Contents 1401 0 R -/Resources 1399 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1398 0 R ->> endobj -1402 0 obj << -/D [1400 0 R /XYZ 56.6929 794.5015 null] ->> endobj -426 0 obj << -/D [1400 0 R /XYZ 56.6929 654.5469 null] ->> endobj -1403 0 obj << -/D [1400 0 R /XYZ 56.6929 627.5235 null] ->> endobj -430 0 obj << -/D [1400 0 R /XYZ 56.6929 355.4402 null] ->> endobj -1291 0 obj << -/D [1400 0 R /XYZ 56.6929 325.2926 null] ->> endobj -1399 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1406 0 obj << -/Length 3514 -/Filter /FlateDecode ->> -stream -xÚÅ]sã¶ñÝ¿Brç„â“ 'O—œïêLsI}N?&Édh‘–Ù£HE¤ìSÚü÷îbФ¨“¥û†ÚOõö#0CEÑüö!'Øf·ÝÔÿ¨ïé¿…^à¬%zk‰X2 Û…¸Êf[?Y¾(>Ýoýè>eÆ2ma48­²)Œ 0„Ûü—]Þ´'f“Ä]–é®Éý¾ -ÿßÖô¿N?º Åó¢õ»¬›¦¸+ón Ÿ-”0 L‚%ÆH‡:+𔆯ÊqÂ5vŽG±$àúŸoo¨•?浞¨%çwuû@°uÚ´ù–ÚÈ×hÊôÑãƒk¿Xí{w›M½mé£h_A#óûÚcÉ?¥ëÍ¥˜ OQ]y@ Ñ‹X6Ø`“oómCJ_øÿ»Ýjµ§&Q å6mr?À­ŽÀz»½Œç»Më;²´M©å·-Ïœ~à_Æ:jfmLÊz;­k ‹µˆ½´ó¬j&4Bjfu§¤ Þ"žg9ð|]TH¼)fl©ÓÉ¡e½LK‚O¨ýT”% HÛ6_oZ?­¦¿ˆ_½yÿÁÏpGز^¯wU±LÛ¢Z‘–i°ßب¡ ž -§ÀÒ0hl/S¾®[ÿíIg…6+¸·Yäx~Ÿîʶcðû"˸Ú³fŸO±Oh–h,Š„N¨Œ¹g…$9Ó²3IÒb—mMñk>±”‹üèzÓ52ÍZØ)ê’²‘íx  ïß|çG!Z×jÒ–:‹† i¬j Ð1ú¾ÛO‘ ’P‘ JU¥ë<› S¡VEÊò¢œàœ¶{”jG)9‘9‘¾0•H†Â4øûe"Á9õ?¦åÎ)«û£ÉÔa„$(©_2×<‰r·oI¿“ùÜð>Šz×6à›©³}(83˜xéò |Ê'c`ÉŒ•a(x 1Â*D€Ø ƒrä;‚ á„íKÅ„C‡N¼oêk,]¬,<‚>üw9ïvL}Ö=‡ápÓyŽjï75ˆD1Ó]V‘.?6´tÚÐr8»OÌçIMîGþb^T”#§³ˆ›ø3µP îÏ ÍâüV Ãð{q*¯Aug5ZÎsw¢¡B, °f<6´†ø»¥Á4 òŒÊÙ9@Ð+:êtçqíª èhë:óð=Á}¶ Äã?@böÉÃ(Їᛴ]>õÌ~ ƒ]c¾îÄE[±Ë/ðŸpb "If@ç£DÏÿ…ÎÔôбtg/4šM¾,î÷ôñôP,¨IöBmwŽÛaCñØH=’`—ˆÃEÐnÚäÙÖ -É¥ ²è¬x¿¼kðKÇâ[t³¦AÎÔ×÷«iÃÉ_¶˜•ŒÇRõ”¥ªnérC5ɳW“éÌ/þÀʽ…ˆÔ¢pZ¯gX¶Öƒs~Ê”e*éøß´)äRÀq~’/J8DåÎ÷î.¥#"FáKØö|¦’qß&-!Æ–?µRkW.°!þ‚Fµ[ß¹äƹ¬Úb\-wÛC<а¢º«wÎšàƒŽ‡º#Ëut‡Ùp‘ÿqÚ0óƒ¤rJú­ XUÕSþ\—ŒõH+N°G)’èþ‰=TÄA|xÖ{@º .¹;í«Í)Å’O*<Í‹WçI-³šIÝ^0Tº Æ“D<3•F~}Ì÷'ê †Gr\oÐöd  -Ä£† 锥*¦´Â"ãR£„`Eii ¡„˜à9¥FÉ’8ާ ‹ßâ€jˆÃ8,Z)Vuf2J É⃀²÷[9§¡½ÓЧj‡p¨ÄÊŒ¶>f/G¯:?«|’—Pº -ÿdÀØ¢S—F•I—>ñÐ⃥‚‚ŠùžT”TBŽŠ1šß~¸~÷j,!"£h¦#Á"¥cd unW3jÜôª¶ÝøEÂqÕö/’ñ!¤ÇNTsDMd˜j@ÌQá8 :GÁ—烠Õ}ÊGó6-)ZG°“þSXk‡e=ð\Vòù?<"ëŽðn†+ôÀ{njÕ~vbXÈözE’A°ÂüašƒM2ZÓ`B¹ªÒv×ÕYLWô3^Áà•Wùt0£Ï]Cl0¡Ž“P áàÀ!QÂ/h¹ÆfYg„ŠYP&‡€t);=Uyl‡J³Åª¨¨ä8ÌšžUa¸o~ÿ²+|”?ôàw]AbU…¾»}X/ Cþ`Åd²äðº„Èo·‚ NsO$6VÛt½†¬Ð}à™z§9@™èŒ×6Œ‹®ž¼6b…,µ~j¨íœ6Ö»²-6¥‚81ÍRÀÎ -kî{„»ô»Q'zC©çõzþb»ðõifc1Н{Eé¹èóΗVͤôS± &MË©² dŸJ&ñ¹{>ë4ÞÅc4bi‘ÝøÊF›C: µ¯ú"ôú»GM Ÿš8Pä§ôÓ>’e>ô8)9Š|rdè„ ¦'kÏ£"\‡\ž›~.pŸb œêVzèð £ï‡ÜU€'iƒ¾ü1/ƒþã<K š¹KŠí!C¼ú¯K§²Ã"G/ù¢›5TÂÔU„<á¿çÕ\}IÎ?@¼W¦Û^!T…‹)Íi¾ 2ÈÀãÈh¸-œ{b[Ò@Fi¤y±Æ)–ØÀŒgìç-‘n):EŽ*†t.6C¿›åmZ”Í«à<ó‘{Íòf¹-BÝÍ8ï5å´ VÃ{ä—©5ú¬‘«~‡‘J¡ê¢G༘Œ•a%Ti+ÏÄ@ÝøEÂqrŒwÑÝ¿ÂìI„O‘’’Ž"¡nÔ9Bްõ …x&UW(Ô缯€ƒÜi‘FÎ.+ÏûÝ.7`œ¦XÄ|¹Ç5ÁãF'=®y¦Çu-ô äz­e1×#S¢­`¶Û•(új|N­}^®†>Ćâ¬3C›œô· -úȺ­&ÇSýnO" Ž æžò·Ö0™tOÎ -Y1Þ•6ÑQîEin¦K#/%ø„×í_?¥áÎäöÙ›d?÷”×…x -øf^¦o¦»Ó]R&·âŸ\DŒ+!Ÿ™“«ˆÏä®_?kN çÑgÍ Ýå¯}„'wgUw¶vÖ¤BÍÆ•3£¼[ÎsëßP`IÅMéY“Ò·&埯`ÇЋ_bG¹™Š_TävRÐÅ© y€>5<„ñû`@˜Ãœ2 yÂ)tƒ… *{iXÌé€%ÂK»ÎKž—ª‰†:.v—‡zÓ<Ukÿ$ÑÿZó| 3 ×H<×~Ür -` Ç›Ó^-à4ÕÄwn&— Á1 i!1lÚbÙ,–iUå¥OÎ>*²îõ›Ï»Ü2zTk•ì±P˜9BÁJÿqBøÌãP£$Š~ E…ÅAlaÉÅÃ6?;Kpÿ%B1c5V3è¢ø“ï"¤½ªZàl¿ -½ò¸?ùA.ë /„ädŠ`†?¯ñäç²ÀÄÚuüæ§~P9BJid2ª"í‘16šçX3z)òÛS’åøC–D%¡DßP®8TÝË®ïÝ¥à±>ŽD}úU@ÜݨNQ3e‚Û·ÚN\ óÒßÓ{ÙFå -b`µ‡­âz #ýãªBøË 9oö ¬Aí4[¹M^ܰØÄj¨¥m^Å…2ǪW̦¨§×yع/¡TtáÒÿ‡ÞQ?î:ñÞT|m9ÚòNSþð[ÔÃC]m™Šã12Þ—Ç2±(§“ɘòîÑê1éÿ—ðl endstream -endobj 1405 0 obj << +/Length 3058 +/Filter /FlateDecode +>> +stream +xÚ½ZÝsã¶÷_¡·Ê3J?š'ßÙN•Éù®¶ÚÉ4É-ÑçhR);î_ß],@‚4?|“Nç’!°Xì°?, ó…ÿøB,ˆE¼cŸ)«ÅöéÌ[<ÂØgÜð¬,ÓÊåú°9ûëµ 1‹,6ެˆyQÄ›Ý/Ë€ v¼åÇÏ7×ëþy{qúËÍúóÍùJ(oy½þéŠZ?Ü^|útq{¾â‘âË¿ø²¹º¥¡ÀÈø°¾¹$JLŸ¡·W×W·W7¯ÎÛüxvµi|qýåžDG~?ûå7o±·<ó˜Œ#µxŽÇx‹ÅÓ™¯$S¾”–’ŸÝý£èŒê©ƒñã2|(€*f² à?ˆ‹çANY^¯²‚­Òãsz¤vV<”ǧ¤ÎJ3øŸ²H+Œè‘ŽoÃÌç1iØìÓó•ŒZa2âËÃñœGËò9Û-Ÿ ß>ͧœwYòX”Umi°cê=‰:=îiFBôâôtoµ•D»oœÃÙ¯NÅxÁ4žs+%´ñµ6^†ËC•žvåª.«<}NóÕ®|J@’vßwÃÌ¥` +#…î³b7$2ri˜´I Õ¯+Qݾ¡a…ûùn@ ï±8Š,×6Oª +wu(p*ã…uYFËD‡Íz—kjéPá0uˆAï9K_høWOyUšŽîØ’ÒÃ`#ÒØñqAÛÁÌwøiãÊ¡k¹Ðûtk¶"õ.²o 犩XFsÞ¤OÃ5cÅ[ih‚“ 9üêЬ¢Œ™ £`f+âÂ7\/ûl»'±YEß*…ÅJjX8!¼åmþ'Ó»»ô!9å5uhÕaÖ˜‰Â‹˜{×h_ß È/B_–ïÅ´ 9õ÷;T,“â•óò>Éu†­¤ŠX(yh3¼šü9àÒVÔ©N:q¸L†læg‘ˆlº%y^¾¬~?¥Ç×ãA³ôÞ]Iв¦Fr8䯤‹B ´š²›:{ ©”—뢽–'j<¤iÞÌ Ešî ÉhÚeUrŸw$ëðÐ_†A|´>ˆ¤ ¢åI§°ïD‚F$é«å} +nŸÇb©Ù!DßÀöæ5)=°þÂÇ•‰æ †3O…v—P@ɯ¤t—þêy¢ÈŠG¢'}Ó?y¶ÍjêÙyŠ0(cÛr%ÅÂ(VÝðL !ÇÃÇ3žÔt^Á©±Ý#üaö 5¶y–5,kÊ8 9ï3!dE5êu§¶Ô& ±½/OùŽÚ”Õ‡ =;K¨a>”pº©AÆ•Y$OéÀ9)BÁ””=lä¼ ±²ñ”ÅŬÞ-¯‡¡#ÓWLÊØ¢ÔæçÍ’ASZ‰ßQ"új!¿—‡£péãA/æ=dhf€°ËEÐh;ˆñø­í(…=É©×,všúÚ:ô<+Á¬#T­ 0”Áòîn³‡WÌÉ£ÉSP<„½¥0z„¼BP‚ +Fª.Š€3Ifª¼mZU ¦·‡òÌö€n,O@»JS9€.×x6\hëÊJ»7;eƒ¥TÌhn¸TwvÆÖ{º) ƒ 5B÷jKnòÛ6×;yc”‡Ð0›‡ÐÔveŽåaÄ™±Y|kÐX"FPüÝ4D%ÃiÅ5äS¤d7¡Þ•0WS|áÉoN=¹¡$‰›{ÑñŒÖ_º¯¸KƒdºC4à +Ž“í>+^:ï\;;pî>Ê”1‹UÅVäwóç¡„«„Ôõi*|‹£@xLkk–ߦòއS¡katЋÍÞ‚ ‡cö”èí€ÓñPêJÆ7 DS[ù‘ÍB"gæ«Ë„"¢¨=ˆj‹R’3pi½v<š‹ÙºZ'|¡&Ü&UMŠ ªó"R‹Ûúçó«å¯^À6Ð…‚ëH­8 šš8Ø["ª·ÇI"Ü÷CGŽd¡Š,¼7ÈF5l,™ç{a×ñÿ ÞA…í?ƒw×ÞY.§Â WÙîMÙ°˜CM>©Ý2 h—ý’ +°ŽvÚ•Q¸\_Ò·¶„ë°m±.êa]„û.-Ü‘mš=S˜”Ðç†VZwŽÔµÞ¿X”Z +&ÐÍÝúÒ$P99ç=X½—G+Y¯¸ð˜ˆe¯5pËczcà±Yg$ŒÀ-â§âA×—ìîêö_W·C—‹tKÜþc›DÙàØœ)Þ¯·Gªs!:ü¨ÉÊ!y¸‡ò*¼ û¾_=êWjþû}o¿7zWRÉå^/òíC/œÇEè¥$Yì3%Pq%î>_=)Œ°›;úšƒ€vFAY䯸x°\ðšçO`oß<¡ó ßHºÚè±@[IÑ@uSàû3U'Pvܧô%lÐâwDÉË­eSd9RmñNÉ;E>´Í{T+¼˜£=$)ûÆ,×E‹´þ‹‘C@`PC`‚jmC¯Ë­C´‡(8¾èzb›áUSHéÔeÒolú¶¤CUÊæa š˜2Õ!Ù¦fÅ¡> ¿ùùòó§‹õ õh´:”EE$¹%}Wf‹VÒóÁMbÀ‡êl»Z—Sžè /ß‘hD…ª1:´qƒ>BãvÚHOv;c0Y $çÑz·×i +g‘™£W»SK)áÆBWX…WÖW%MÍŠm~Ú¥£¿@)zKÞ±ÆÉb ¯¿<DÒ[ˆŽ4†‰ÕnQ䀳ã±Hw˜:C4’ø2ÏŠ¯S2õ;%N©ÏùÒZìRVC{ï>Ù~5r‘ ƒèVÎF´NÅ×¢|)ÞÌdŽˆ e~#4 $„4§¶’ºFÀ¡ŽÞ~ðÝ¥LOúR‡ÝL?—ûº¶.\aQÈÊÍ3Íî•éY…·JlëEAY¦Eöl&âÐÞ´°!èXr”ª¾líVlC[Äái®»꺣þÌÔ¸nHM EXƒï Æ‰Ú;¡OÚb¾ñXÿhWƾ­B•ö‚ïTýÈp:’‚ÂÌȳªîÞzªÌ6Ȫ¿ýÊEã*ަUv¹ô]=§ªâ,#‹~Ô°§4ynƒ“J-Ó[¥Ý78ÊãXu•zl}³º¸¼¼e·_ð)ÿbÔo8»c0qÆo‡kÂoË5ë÷”ÒÖï¾Òa¿]¥.ïö\Ä,ðe0ã¹Ã5á¹åšõ|Jiëy_é°ç®R¡ î â÷{I/#5ç½Ã5á½åšõ~Jië}_é°÷®RÁð/Ä»½‡š’Á^™ù—kÜû†kÎûI¥÷o”zßQ*àvïþÿî(À50‚Ú~& +×D,×l¦”¶Qè+Ž‚«ÔcîßúK01lp.g"æpMDÌrÍFlJi±¾ÒሹJùÿ#b2bpš‹˜Ã51Ë5±)¥mÄúJ‡#æ*½d×èíû<£ʪiÏ® Ï-׬çSJ[ÏûJ‡=w•Fìê[|ÇW[òß® ß-׬ïSJ[ßûJ‡}w•Æßä{$™ +ãiÏ[žq¿ Ïœ×êŸ{ê=vÔ]|“¿bR̬tË3î¯á™ówB]ãoOÝ ¿Žºßä¯Ä?…„øßܤþôßj¶¡ƒòVFÑHªŠ÷!Æ(ýî½ý5ÈüQç[Óÿ KQo?endstream +endobj +1404 0 obj << /Type /Page -/Contents 1406 0 R -/Resources 1404 0 R +/Contents 1405 0 R +/Resources 1403 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1398 0 R -/Annots [ 1408 0 R 1409 0 R ] +/Parent 1401 0 R +/Annots [ 1408 0 R ] >> endobj 1408 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [116.0003 457.8291 166.1092 469.8888] +/Rect [55.6967 706.497 116.59 718.5566] /Subtype /Link -/A << /S /GoTo /D (tsig) >> +/A << /S /GoTo /D (view_statement_grammar) >> >> endobj -1409 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [399.2874 346.5415 467.9594 358.6011] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> +1406 0 obj << +/D [1404 0 R /XYZ 56.6929 794.5015 null] +>> endobj +414 0 obj << +/D [1404 0 R /XYZ 56.6929 769.5949 null] >> endobj 1407 0 obj << -/D [1405 0 R /XYZ 85.0394 794.5015 null] +/D [1404 0 R /XYZ 56.6929 752.2918 null] >> endobj -434 0 obj << -/D [1405 0 R /XYZ 85.0394 240.6473 null] +418 0 obj << +/D [1404 0 R /XYZ 56.6929 436.1631 null] >> endobj -1410 0 obj << -/D [1405 0 R /XYZ 85.0394 213.5966 null] +1409 0 obj << +/D [1404 0 R /XYZ 56.6929 408.2731 null] >> endobj -438 0 obj << -/D [1405 0 R /XYZ 85.0394 126.6995 null] ->> endobj -1411 0 obj << -/D [1405 0 R /XYZ 85.0394 93.8745 null] ->> endobj -1404 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >> +1403 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F14 741 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1414 0 obj << -/Length 2970 +1413 0 obj << +/Length 3230 /Filter /FlateDecode >> stream -xÚ­ËrÛ8òî¯Ðmè-‹K$LNy8Ïî$YÛsØJR)ˆ¢%V(R!©8Þ­ù÷m )ÑLùÀÐh4ý–Ù,‚?6KÒ0Õ\ϤŽÃ$bÉ,ÛœD³¬½9a„3÷Hó!Ö‹ë“¿¿r¦Còtv}3 ¥ÂH)6»^~Ò‡§@! -^¾{ûúâÍï—ÏOe\_¼{{:çI¼¾øç9Bo.ŸÿöÛóËÓ9S ^þòüýõù%.¥DãÅÅÛW8£ñsÑËó×ç—ço_žŸ~ºþõäüº¿Ëð¾,ö"_O>|ŠfK¸ö¯'Q(´Jf·0ˆB¦5ŸmNâD„I,„Ÿ)O®NþÕ¬º­“òcQÈEÊ'ÈÅ”¦–¬¯×E —biÐv¦Ë7yÕá°¨º¼ZÒZWÛ¯ 9Ž?F‘È¿‹2®Ýv[7Da³+»bëQ²z³ÙUEfº¢®pjÛœ2Ô]ÕeëO%‚ëO¼Ùu;‡–ŸÁçÁb×áJ†ósû ˆ9c¡Nîn…;ª®¼\™uå¡_®¯ß#d²,o[„ úÿùB¨$¸°gÉ”è}Ýv·6B¤8iü8AÁn½-Ê|‰£Û¢[#T‹ï›’?ƒ‘Rî¶p x/6x¯ÞU§"ËÙ;Ù÷)Ú®ÈZ¼ò¼_]=[›ªÊAžHp¨±yÌÙ€žo•¢”„é¢,qÊJhÛ9æa!ÿ–W„zCßWpk -OS”4eoZïˆ4>&Ì­ÓÜ2Æûœ:¡ç„5SÝ!6½ß¶ž çêÆ% €îC÷G@2+5~óõ¬±FzuáQ¨RÜò¼š>KBÅSEÂ*ª¼›(P1NHY]ux”e•kÿv PJ0ipxýò=ŽÛ:û’w—ðÀyUT+Ä14„‰v›g‡G9f™Ç)˜¿×—b{èD¬Ã(Rb&#ê(QOñO€©”šöNóžâ|H]Ï3‘À iÉö'[«8*ga¤%ÝÂùЧ‹@Â^ÅĽ"ˆpÌRª¿N=ÅGD'2di*Ç"0Ëes„7Tk)B·ë"[“âÃzÅêÀòƒ;qÎGéÀ/Þ‹qlÀϤ9œOkÁçÅ<¹ÇR¸=—ñ½‚å<{ár–jðJI”þ°`{Šó!ÉcÁ‚v„ŠAÐëѬÙÇ^²õ ¢Ä£«2ˆŽDSʼ«EüÛ)ª$’³ÖÇ(‰ pS´_f(aôŽÚÔC^NNÄßî#€Ãòo¥¬Ç[fÆá/é=÷oõ â (‚H¡¯“Ù8 Ô…‹;Öy -pV5?tíÂ…G\u>ØMÜà×±eöîµù©Eg¥×µêÅÁË¡‡tÇÖûã<„P!˜¨{ÖÑõ´¢ë² Ä1º°Û¼ÙÞPCídP¹`Å%505÷ó( -%õ 6 > ¸šƒðä` "…lᇮ§8’œ¸Rc ÷h–Íé0=eœ’#žÆ“=ÅG˜ðúð1“6MYDBÒ½E@R'ÐÂ#3œPAÐÀ˜óÇ4P…1Sz¤¨Î€8å-”agSé,€|…TfÓ'½Ãc mãaCÎ.ô(æUƉRÅü@8¨¼Œ=¢^‚­Š}ME…¸» fOÆî¼äÆÝžQÄ÷ŒôÊ -*ÌE y‘â6Ùò(íÛ{òhEð\Í’ƒåüK~G×»ßúMc6ÓL$ ö)´mhGvL)Úÿu/f«ævàóå,ZµÛ,òæaxˆÿlJ?ãýÿtÝçC†Ÿ>Q)0ÅûϦ„¹ž«J¡zé…ÌŸ*äW¹Mÿªbÿ°¦"Kû½5«|B¼ôEŸTL˜2º>q1‘Ö5®’©FV,‘Aפƒá«·WWç/nól×ÝŽÐpëξa­'ÖfM±Àr-²íÉÃŒ¬CÅJÌ„„JÆ.áb³š!p9hÖöøóá†ãfí1]{Õ«Þ3q¨Ž¸Á«Oô˜ë… n®„v k¼ÞnµÆ Ц3„ò®Ò ¼È3LìÀ†2Á°û,|Ó›ö"°™áe,TO“#:[ãû߇ûüI;ˆÅ«Ê¶¹'.öÎ…xa-Û~Hèv¼¶í -;³È]Q!ҾߊDµ¤„gpØ5§*pcKzÀB’(jÙ]ØDÍM7&¹Æ³EðÖféùYbÁ7SËÁæŠ(RÛ6ö„WÞ?÷aIJ1´.¿åTÆ’§dàa¦³{ߨûH4ÝÓZ° kÂiw‹e½jÇY¡ œW²w^“ýlw˜9q€\kÊùiduCwÚÖÕ’J8éÔ¤¥¾•غ¡ÅdOê©eúDŸ­¹oëî % ¾Ìó? 1äßmªî@D]Q{¨ÄŸ`ëP .Ãæ@ñ1&&TèÃ"ÎÝ6ÄiП°AY¨ƒ«bS”¦qé$¬¢_(@½tâôé@îqõdá@É£ûž·çü™«FGïeêXÄô|½ú{ -€âýãüß>WH!YHõX.——mÞ*ÿ^¤?yu'vèNä„ÃŽÊXG#ýp%}%ö©±4H„¦n¸Pƒ*f¿Iˆ¢‰¶×kŠÜõcp$&[÷{[›Š£‰hR9ÿkRpr\´]œ¶©ôÊZJ(ªùÁtö÷S³²ç‰8ýJS¦\ÙH¶Þ¸qLNŒûÀ ¡7q€o4ÈöÉÙ5×ËîDwÎç‚ì/ßÀüÕÖd¹ç§3 VùmY8s±;-#3 T?«‘»ìv÷c{}µÎnUÕ}¨z¿¾ÃG!yæ ´¤}Ø8[,<Ê×nK_.î¶þ8_TFî–á=Ù2–$É>[”-+òÛ?YŠ`2ŒR"õÙê“°°-–$9(²Ò´í§aÅrð® 3ÏÊé+÷¡.Òg‡ñÙõAÜüÏî§É/¨¾¡6ÙŸ 6è ;ZHÌæèÞ,þ]Þ~®›Ï¶ÝápÏ|RÀÈÿÔ?tºý/Œ‰l:êuå‡ÿÙcÿŸ0± …R|:-ç¶+¤€1e9—Ñçþ¿BŽYÿu´Éendstream +xÚ¥]sÛ6òÝ¿BÓ—£f" ’¸{J§uçêÜ9¾éCÛŠ¢lÎQ¤"RvÜ_»Ø J”“¹Lf¢åb,û Ë…€r‘éP(/R‡ZH½(vWbñc?]I¦Y9¢•OõÃýÕ÷ïUº0¡I¢dq¿õÖÊB‘erq¿ù=øñç·ÿº¿¾[®"-‚$\®t"‚nn߯ÐÏnßßüôŸ»·Ë4îo>ÜúîúýõÝõí×˕̴„ù¯paÂû›^ôÓÝÛ_}{·üóþ—«ëûá,þy¥PxOW¿ÿ)8ö/W"T&Ó‹gø¡4&Zì®b­B+å0õÕÇ« z£vêœü´ÊBEéŒ#5'@mÂDÁ +ðz·ï_àLRµMÙ!ùa)³ $|Wö}¾®ù+dÄSU>T—OeÍ 4µMÍËçû=0·§vL·¥¡¢Î;FÝ܆¼«:ÜCå Çzà.¤²’24ZGöˆÌ‚ÒAÕ<–‡ª·+©$ØÚ9íŽÛ}_µMGCÕ–pÊA€åcMKÈÍÈ`{0àØl·/‹ê!"··#m@£b1ÂÑ•ÐÁýÒDïÓ>•‡Cµ™=#-Š9ž>êªë½¥_Wø² ¾!ø¥=PäÍ„–>† Hfm?®@PÞŸò <o³m”Ÿóݾ.ÿާùþ},=EMe˜*Pl%ÂT€À23++Þm›|~÷Zb¢ë«é™]ã…`>ªñ¯>ŽKtUó@_t ¤ÙlˆÊª% yóP2\àØÑ !œº¼ÁëKǺÇöX3M^M¾A=1:xÌŸx3€5;F8r{Mø›Ñ[œ§tL< pìJЪ$RÁMC˜ý!/úª(髬x +˜j™ø¼sÖ–žUEÞ1ô\õíòæ… OG`Û1³.í ˆbSú;èó3‘¯ší!ïúÃ2 ŽEî,…û*(,ú Õ Éw%㪆~aéÎÍÙÃEçEÙ¡‰¥*øØž8ö'mA:nzÎP—kÈE•×3L<—>MYn¬jàíÜ…­ÙZ6å¾n_œaZ‰¶ø˜7õ©¾e¡D_Ø´Úœ§äÏ9ã<·æÏº$Fâ„—ÂY"’P鯌g2 +Ññ|<ƒÓgÑR°÷‹kÑ<k1H3N—óEaš&‘öo\€„|AJ’ú­ç2tÌ™¡Vðm)>€¥Hp¿`/Áõ©\`ÅXc:ÎB“%¸ïâÓB†"6FÛƒŽ°ˆïovÑâ] ÇYx'r뮼…íàl£o“Q +”‡NÒÐÈŒŽtoï9Í‚CIŠi‚}~(›ž°pÅè’‚§e1Š´5 ¶K@‘Ù˜ÑF²à¯¥ Ý%“ Þ ¨¬#^FèÕi0¯k\ä"7ŸŽÍ¦<xÁm œfÚŸ›‘O€Í^èkz +$D#NâàýpÌÅTXQÄ:[‹`lÊRv€Hä~élø-dâXÕýÊ:‡lŒóÇ14ãÂîieÀs5ˆ«™Ê¸Þ1Ôº›D3 ‡°iÀR‚Å×Ý”~S–{'èªNÀ¡,þ|eŽM +é`¢¾}›e¢Ð&1‹Õ˜¶~›ßXÅ`R-VQ¦ñx^HˆPè ‰ñHÚσåLˆ´ŽãÈ¢Yl€f±eñ ;‡Å^1>Q ²j1jƒ”Vecá S‹ê1§ þQ¢âoQ‹?"0oüïÿSð J©/©GõŠ8ªQ ì™WèµëòLÒ$4"Ž_ça šab¢ ™ ³L§S.®›±sEÔ¤DË´ÜE¹ +c$Ä‹^\ª¹Íu?JŸñ¹ŸÒ9/ [Id²×…íS]ö@u¡Ð;¶£X$¯ó0PÍ01¶•fÊÅ»A° +ëMõTmŽ6™€ï¡Ä—£|ELòœ'_Û%hx¯y ‡BÜÎU.APðPŸ@ OŸTÄ5%N«ØMµ™æÓö\ߨöCñ^íJÊîOné +IƒSOi5ìƒÉ$”Ùr%ÔØo7› +» +9ë×Dzè‰Aì­åÅ#Ötç58ä@¬¢ T ªŠ5Ö¨Ãr*Ž!Æñr8XÀr¶zN0³ìZ")@·áhçY 9}¦8kÏíô^"ˆYij˜Œ×·å.2ÔÐ.UÓ—f‹9¡[ ªÚí©¶zâ£ôŽ‚‹î}Ût<™Ø–üèŠ..’q(¤.“›ƒª³()i¶=šlh_Æ v˜,ø<$Œ¡ì@=†ÛÈÄ(>œQðmؤìdsæD×Û~\äîÔˆÌyÍQ,v»ÇöЯŠc?Û†ÂL4J9Öàß5„AYÄ0Fi?|P˜ ˆ8oºç’±ww!·m_ºMò~F%À:B0ý%•P ä±Ì˜Ìš2̼y‡NF±ÂЮIJ¼êvœ ¨Â榓¦#7ܼ^4;\jz±qÍ4R¢:ïOÛCºôîö£kÒ9††ò‹ÿcc%<–!Y˜Æ…ßUj<ËóUGÁ-oZÛ±4µ}pü_“Þ§æTïQ`=PP{¯øý‡Ð¢ü\”ûþdêÝ]Wö¼ 'ÜßRl 8ýrŸkÔ+5øësQËJB¯Ëº}¤Hƒõ±§v«'&#Ü=5iÄI;‹Å®.ZØCCý ¼éë—¥”2àÞí ïUqŠÜ¾*Žu~º™"Š;Øq‹'y*]ÊWröÆz8Ã¥iÑwœì¹bµáïc6Zõ¹[GÃC>—sõʵvìº\v$ymnŠjSÖåCîšË™ëõá%𹤇úÈz w=«¶™ÆãýÓ§õ·ˆ^÷yÅ$¬7ÈÒçjwÜÑÇäJáÝçŽtcG ¿&ñ'Õ¤;p‘dÚ¨L,èõcŒorßæUrµ=´»Õ%¿#E&±r±ˆÚ‚§a- +iœojÚ¹et¨uæ»/eôÀïàðëïceÛÚV>Ɖ(‹ãˆ­Œµ„ÚÊ,gŸÔívÎÁÆàð“~ÑÁ*¨‡… ÍìQŒ¶…*ˆˆ‰ˆôI.3˜ÉËE~’„t~R5V FÄ…èĺÎkÞç³Êù¡á§™výTµÇn|íÙ<±çnxNHR‰ÐÄ‘úŠ()ùQH%Îñ!Šé®>+vK„Ým¬D¨³K QðͯPdï*Ÿš¼Ø_–3~•e±’‰ +e:^Žë2ñÁHAOd*îà,ÀÐÔ:“!¬hV·Ö[»O84â¨ã‘PºãnÏJ™PÜ´Döðváðvø¾ +2Æ7—Êfn+ µ‘ÑW\V¢%Si€í¯.]ZsÃÍ{jƒ¯5wF/» ™}›)^½yÂK’„±ˆÕ«^D†q"ô«^kžÄ­’ÞpϘz–†ópÄìÛ®«ÖCDzå3 ] +¯Ã !Ðà³ô‰u÷{—ªÔÕ®:1òAoõɽOžsÏz×/®30/ÕHËPc Í—–^±d»ê¯9¹¦ +ŠR¡³@¤£.§S^BÑ~ÌÐ`„%¨\dU}á{W5dŸ±ÿùAº™d$š2&ÂM&›e4“åø$EÒŽ;NN~[jpùýãjöÅüØÏ*h˜¦*ûºR+J­ó… ?—‰‹ÅKQWÅÜ:Y¨áLæg€ߓœ QÔÆ.Ó`ð…Ÿöâ ¯ô\ÖõCó±ÑÎuˆ´. +β^†5¹ÎÃæ‘'íQ›7¡è#üÜ>ã/þi‰- ’“Øæ+’ö F0Óül½¿vŠ$'Ú ‡ÄÑÞñ8ó@àj[ª5gŽ@ãL»®Ÿ¿ 2¹šË[Ο‡£’Q©ã²ŽÈ¨ £f¥9Ó`»"ÔÐ 3þþ×V YíÆõEQ–¶vÓü°ÓñÆ„{ ŽË¦æ·û˜üÌÈO<¸c7záTéÿg¦Ï$†—Æoþ[ŸñA,•eÑ|ÃJ‰$Ì"H¿˜)Û±1§œtÎúÿ~ªüendstream endobj -1413 0 obj << +1412 0 obj << /Type /Page -/Contents 1414 0 R -/Resources 1412 0 R +/Contents 1413 0 R +/Resources 1411 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1398 0 R -/Annots [ 1418 0 R ] +/Parent 1401 0 R +>> endobj +1414 0 obj << +/D [1412 0 R /XYZ 85.0394 794.5015 null] +>> endobj +422 0 obj << +/D [1412 0 R /XYZ 85.0394 349.7668 null] +>> endobj +1000 0 obj << +/D [1412 0 R /XYZ 85.0394 323.7864 null] +>> endobj +1411 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F62 1065 0 R /F21 714 0 R >> +/XObject << /Im2 1054 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1417 0 obj << +/Length 2688 +/Filter /FlateDecode +>> +stream +xڵ˒Û6ò>_¡Ûj¶,’ *'Ç{'Û»“qíÁ™rÑ%±B‘ +IÍXÙÍ¿o7 H æá¸¶tÀƒF¿ÑhHÌ8üÄ,NXb¤™i±˜‹x–oÏøl ßÞœ ³ð@‹1Ô×gß½Vzf˜Id2»^p¥Œ§©˜]/?Î&Ù9`àóWïß½¾|óáê幎æ×—ïß/dÌç¯/¾ Þ›«—oß¾¼:_ˆ4óWÿxùÏë‹+ú”8?\¾û‘f 5 ½ºx}quñîÕÅùÍõOg×/c~WÈÈïgoøl lÿtÆ™2i<»ƒgÂ9ÛžE±bq¤”Ÿ©Î~9û×€pôÕ. ÊOp&U"”"$ÀذDIeض]Ñ/švY´È ,Q£%QÊD”¦°¢”¸™_oŠó…ɼX‹t¾*òÇzÞ¬h¾ß”Ít›f_-iö³[µ-ë¦Ey¾€±RóMsWÜã™®¬ó‚d5-ºº2©[Öô©÷ddËeÙ—MU4î€ :¨ÃnŒÍž—…Ìı´,•yVUå@~í{yS÷YYw4ʨé¶JÝz¿ý Óªµ@!u~å1Ïê% ,±Ðn³ÚãκÂA–ýó6.ëuUø]½x1E~·)óe’O¹Ã½Èb­°°¢¶)Í,¤{uÓSg›õ=ògûû|Ãä)SB¥ùµG¹jªª¹ð•[FM·ßn³öàv_¹v‡r€–¢¢Êúbéˆmœ)Ž­W +͸€ˆ@¶˜åYÜ7YiXªõÑdO=T0-D2KRÍ„2â" Åêa‡ Ž„-Š:û\§» ~,#ñøöT`ÿ1«BÆLñ8šp¹ +HÏ0‘ĉÊ~_p"b&R^p/œG¾eµé} Èé=µãK†îÇF²,VÙ¾röu›UûbXÐu"X*"ãh©›¹‚AO=©gPRªùSzA=¢g5Òs^Y BX”5¸ 0vOå‰f*ÖòqJ¨)®µdJÁA0¡…¤, ¨§½µŽ ý»ÃöÈÁ¶Í­‡ê3Œ'R‘ +ÝlQ÷mYt¨xˆÁŸ!t,éƒU7´™k¾ú@‹G0YµnÚ²ßl_P°5œi•ši8Â0ª›¥<Š'žì=,•¯„“eߘž4pMÎk¦0™pO×\®è«=lð3„";ÁQ,2BS´ãÐfYæåi%ÞÁÑ4§¼;m`ìËó½=í¶Y.Áà¸~ÂfGPج‡²ʾ,œx»ò@t2LËô ¨娈inNH ä+¤¥Üî·4ȶ;î©O*€Å¶êÓIVyèéðTV3Øî;‡pÕ´î‹ßÂ{ÈúonqÚŽ3ÿ÷¦¨K¬î Ý‚GSÝyêd¹,š/³>£^YSëŽØÈM¶O®‡ãÎC•®W•Û²·a6>®úÞd"²/êné÷[­×4ìºò¶¨Iã÷Êú#m“ü€â†%!„ ßÒçb^|É‹béy4¿¬i:£æH§:û ÍnÁÍÊ-0º-‹;NÆ1(Æ[f»]U’\á.k! $9Ì R•¨„@¶ƒbvç ì|näüÑCÈŸ<‘˜DG¯.¢ˆäm(ìhf”œ¤ÖûbV@X 7€„ƒ—¨„AÀކëŠÐpáœdÈç¿ôÀû¶¨moÚ ³¦À3œúäÏGøÊÝ'8®ÛßíÚbU~©Šú†>üÇJK*fðN2‘ÙG‚øÜ¬÷u!9øÔ´Ÿ0Ðáð{jnBæãïÚæ¶\‹ò˪ý +Úâ÷}Ñõß„£XÖ™\»Ø/wí”OòŸ¹;ÆÖoBзYÝ­Š¶{îjZ½€0¸E·ÇI¼ŠP¯©‹ÜyŒÿõD×7ß KÄtÓÇhþ­8tÞÆlÓõt±!øøðÆØ³Ñ?¿ZN‹®Ù·yqä´ÜEÖ<‡ˆBhþ¬ñ0f:Rä…·Ÿbf´Žg£ù#ïwMÛ^…ƒ›}XIÀ\<®¢sq›ŒIMî“j4“‰uP$)>%5™æ¿šTÉ“J› H!è—«ÃóЉª–ÑCM¾M ZAü4O ó¨™ÿ™F0™JÔ;²v*K÷i„ƒúÔ5]ØS/¥€c‚'Sð’ ÚÂÍd¿#/“ÍŽÓNTJ³(¢¯Þl*•J'qTÞX&ƒî¾^,Xà ²=¯‡ V¿E,ñWo6KÄ9‹L*‚bÜuaEƒ›/vMSœ_ÏüÓõ ìMNgDÔû$·Åpíz×"˜Püù}(â¶ü¦"Ó ôé4èÇâWÎe]K¶°†]¶•Nò£ë¡F4ÉòR–¤Ü_ÁRR¢Ï»m\@.ii³ù+ ó ¤¯9ˆ¬ìú2w“6‰…KŸØf]×ä¥+tÁØeΜÒjhüM½· ϶n©#Ò^᪪èªz\¹£¥HÓZ i¸˜×ë~3”?UlôIù U€}Wä%®-–öþoo$(r%í§Ùº ®½)OSG`UÞ H‹½:ðhþÞ–7ñ%óÐÙ6]²sNhk@TUfowØ?^”Ó:£Zfe£.>½£Ü¯}º @ȯáht2Tž@þK–7õ*`1܃ulÆ×ÜX1ËÔ×JÍcfh°¨=e† +kÿZÌP«yn/†Ð¡²‚ífî1&Ó7;š© +¸%:øÕHaíõ°ÞÃ5Œü &q¦rC_Ö¤û„9 °¥DÌDZCðLãgÈ'1© ɇÞ¾Ü3âít/A:É¿ºW@{[Ù´ÓËobLMÍÉAî* +]ð…ÄŠ0Šç‡fOeÙQx´#*Ϩ(±2†‰qôDZ…Ø·/jЮË[{Â~³wë?gK·AÖg(¹ÄÀÕ®ým€´/MÐf‹»ïc—ªLØsGÈ­õD»Ú·`wm(sÀ”¡ôïFd¤PûçVý›UÐ¥Rƒ_;ýA-Š$ñPÁ÷8·Åžûz€àÔ÷ß¹5kHë¢Á¼'%ÀI‘bjìwóÇƹemËÐÖ/aênSX©ÛÕ2u:¯šÜ¾oj3J@ÕˆòÒ4|´ømÖõ# áõ¬ýs@·ƒmûN‰›ÚLÄ"¨Ipqæ(‚i¾PçÎHÁH,=<™ÿaã&öü•G12R»ùëõscçÉ”+% ˜¯²Û§¤)´•¢Ž¾Z“‹´váÊUîíž¡¨¤Rg¶yÆ;˜9¾ƒáΧŒ?ðî¯b†õ²9ÒáoþOÀñÜÅÓT†ëïR§p$Ž(äFóûoîÏ÷Iÿ‘w–·endstream +endobj +1416 0 obj << +/Type /Page +/Contents 1417 0 R +/Resources 1415 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1401 0 R >> endobj 1418 0 obj << +/D [1416 0 R /XYZ 56.6929 794.5015 null] +>> endobj +426 0 obj << +/D [1416 0 R /XYZ 56.6929 550.5868 null] +>> endobj +1419 0 obj << +/D [1416 0 R /XYZ 56.6929 523.0374 null] +>> endobj +430 0 obj << +/D [1416 0 R /XYZ 56.6929 249.7563 null] +>> endobj +1307 0 obj << +/D [1416 0 R /XYZ 56.6929 219.0826 null] +>> endobj +1415 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1422 0 obj << +/Length 3904 +/Filter /FlateDecode +>> +stream +xÚÅÙrã6òÝ_áGykÄ%.‚¬¿¹øó[e/³(Kdry³îáJ£8MÅåÍê‡ÙyýÝÍ›÷WsiâY]ÍMÏ>¿~÷%A2úùâÛwo¯¿úþýë+«g7×ß¾#ðû7oß¼óî‹7Ws‘ë%c8³àíõ_ßPë«÷¯¿ùæõû«Ÿn¾¾xsÎÒ?¯ˆä—‹~Š/Wpì¯/âHe©¹¼‡N‰,“—» mTd´R²½øpñ·€°7ê–NñϨ42©´ ”jŠ&‹CÈÀöWͺ8À±¬šÝ—Û-¶älQd¸鬾+WÅŠçÜUqçWìë¦)Û§l:»^¸)ZÂÓÖÈ# Dô(‘ʱú‘†ÊÏéS+D-ÅS^!¶t–y*Ýp·æßÛ‚¶uT»º-<=‡»ñ!RÕI¸œKEB&ÀKØ?3FºÝËjÉ‹ªÍ·pV-5µ°º¥é̦@wùöÈÍš§ãØ)K„5‘&ãóîŽåóòÓú0Ác£Ä(Óë}[Öa/«n¢ ,ýn¶õ"ß2Ì-m¨³ØÖËŒ†AÇ®8£T$TÓ>gò†ô!§ŸU±ÎÛ6rKb˜j£ÌÆÆM½™>wéTI>É¡øåX4íÙc›(ëdb¹Í<¤SÂÆmqØ•Uáè(¤À 2/Ä ÎG—^ @½Ý•Á –mYmhž;LÊyî6¿+pZšyáI½ˆ9ziÕHJˆmp­:ÎÌk¿Ö•“¼d(Çf¶&mÛñ I³™mÊ»¢"ØP°ÍèL3ÌÛåMKpÔÌ4aÍLXZÝÊöUŸ?0æ¥FëuGÃé­)@-UúìkKs"­€¤ÕqI w•gw¢ ÄŠeZN†á7È0‚ CÇË04K9&)}Ž´&nïë¾E¯¢tÿžq¹bk#Äû†:ímÞÒðŠ‡‰Ó8ï¸ß×í³(,?¶õ.oKÎí ®ÉÔAk‘»õö} ("jÞ #}ëš~ñJ•SꇳõÍ™#9C» ¿é¬*ƒB;d =ÕÑӒζ¥q€ßß–Ë[jöŸöO˜…f³¼ZÑxo]M: +­•ß¾n?ƒ–öæ†ÂõÂ0߯^OH£F˜e^À`ƒS!œ‡Yknëã©L€Üí}þÐPû¾>|DÍIg¸l<€»ãŽSø=cÎSÛ6Ï6çÚ‚§ÉȵICitP¢§5ÎfÙÀNò¹Jþu7àMtJge˧dæ9 UÂD 3#Ǹ*›œ¦¦þö ¬2¹¼ óÐ*È¥FЬEÝÞŒ–k“ì@ÃY_š ')w¼YÍ£Aò S’ÿ³uÍXŠOùn–ŸI+™"2ÀØXwÄO¨J'å=ƒ²8n6lI*6-ËCÞÜÍÐJ-ëÃá*÷-¬ò–mZÌœ‘Áz™ Mµð¶¸XUSâ/uduGï:•H®S Û¹NtwŠPvó±¶É†á„¼m‹Ý¾åe5ýò&vöæËwx…;8–õnw¬Àè9ÇK~â×Ô¨áÜ—N>€1Á! ¼ ô;/ˆ:+bÖÙÎÆO°/±Q,…~ÔzeZy¢Ë¤¨L¹O^’ŒÁa•ÄKšWûySþZLl$eÀ¢‘ÇTÖŘxO>:@ó@ßùÏB´®En ˆ ù +XÕ–Î)bñ0E.Ü„JŒª*ß« :JUÈøj'§Ãƒ §TC€IÐЩ‘é_¦Ùð2 þ~•A\³-W4î¢<Œýc/çŒ%ñËfy%Y<´$ßÙìÇØÄ}õ±mÀ6Ó`{[2³ YÈ'±ÜBŒ‡þѱú÷ × +0‹hhE‹„êãî*™b„’¬[‚1 úP©q_6·4莥ãî‚ç^qf¬ÙóW-ïÀüQ\‡=ƒ¹‡æLI.ïÖ"I62ÓÍ€7B”lí-¢³ÇÛâÕØvñÊÀ²±ü1Ž% ßSX„CíS6¡ô-Íú£D +÷¡·%)Ú í·eÑ¼Ì +Cbí­È.ÿô¨~sž>Òï8óú-ø`\åŽ7¤1+;ŽM“oxroÃaÆ-#¡}ZŸc´žåÞQU­0ëMÓ¡2Æ^I½ ¹TŽSÄp±R’ŠJHžÿ©(BXEØWQ +*Šƒ$¹fE ÇÒˆ†!Š"t¨¢p&ÁJéÐûŒ–•L‚WJg1è øXÕ÷cQ{¹Dÿ~1e%óÉãÄõCªŒ–O]e™J†^NÅI¤´MO•òÊ®²¢º` 8…Œè¾&0¥»ØêªMØÛA Q¯@ÉæÖ»l;Þ4ÊM#†> ŠSs@x_LÆÀ22V𮀤…«g4´K ‰Ê‘ãõ:{ Ǘ*VL¹¬¦>ºÆÒÅÊ‚¡KÊÄ\N‡Ó…ucË!árb,GõÀ‡š +D’4Ò!«€Ì°¡­]f Ûáê>1“8ZÜü±œA9‚p2‹¸‰?SG˜‹LùåVO2 >‹yHwuÐ-!­Å +IJmF·¡!#>¶4™AžQ9=jbE@G½æ"ôÕ +èhëzÅð‚sµ ãï iô‰aèÃô}Þ.o}QŒ0 ̨QÌ/ð—pb "ÉÈ€Ì'™žý ©sô0°t¾;X–ëêpêŒMÒj;?n}„ çb±‘3¯—ˆÃEÐnÙt9'á)ßEÐRàýðîÀ.M$ÔaÕàødLÙY\O¦ëXÅ‹_¶™•QœJÕtK®Â‚^Èq ŤX½Â˜LŸ9hša~ñvîmD$ yo}ºŸU ÙZüü”*(©,ð¿ióÖi çÛÈe1DåÎ÷ÔlQŒÒÆ£ÊVWr<¥CƒÍT2íë¤ 4Ë^ ÛrçÊÖÇ_Ð¨Ž»•ØW1®–ÇC"¬¬õÑit|%T +¡ñ ÚÛdÀ\6Ìü`‰¤’|”pVS¯L—LõH*ΰG©8ן{{(ˆƒøÔó¬?»`@¾ô&9x{ÇjsN°$ä“]…'Ð<ß³8OJ™Õ‘ÔAñ¼¢rè&¢8ËÄ3SYa¤ç×ÇâáL½Áĉ×4¤=+âQC|JSU¤;Za“ñS›„`Eii ÃŒl¢“ç<¶É(KÓtú©m0Îû(émKƒV+%º²LTBFiwM«O]9Ó¡ÙtèsDp-©2#Œ™£mJÇfM ?й}˜ñ¤ÆØ"_[£ààˇK?4ú ¯ ¦böÀÏ>ÓÇ™•d0@¿ùpýÕ«ñ­‘@™$— +Rœ4†|XHƒ‡Í%5Þ÷Þ.ÃüyÁéÛå)^$ãCáIO-øUsBMb"!Ô€˜“çS?é) +Ƹ˜‚vçÄ=Mfm¾¥˜Áîüs6Ř=°_VƳ0"ëyXÁïLŠßæhiÕ>º Ü¢ßÈŠÜͦp±‚ýa²“M6ÚÓ`Z¹©òöª-&”þ ünŠª8€ ®¨{lˆ ÆW`Ê1!8Rtéö\¸åû=äž~ +f=@™ua髆B˜»º3~{VÍU™äìD}ÛüÐ+‡*ÿ<%“­·þÎäè}_&£÷}X{æXÒ@^i¤y±Ä)PÏŒgœç-‘n»DâG•BR—޾sXm^n›WÞx#óº*šå¡ôÕ7O?ï +ˆË~MõR%µF?©¤Æªß¡¤R(š>aèG`¼"™* wb#‘Ø1P˜?ï/8@Nñb úN‚‰ì I „O‰’’N"¡0ë)BN°õË…ø(†Ÿ†<¯f.€•á3° Üù+M$ø.+Ÿ¶»!C`œ¾Lá“ØÈ—[\ã-nrÖâšgZ\×B›@¦×Z0µg®-ÑbC¡²ñŸ¶Qf­ÃWpÓ¿95´ÙY{«`Œ´Ûj2L°”O{©7L6;ko­‰d>\xò’U‡'Ú#JæÁ¼(xBª¡•ñ„Õí?BåþåîíÑ÷d^{ÎêB<|3/“7^v—ž”É£ð‡I+!Ÿ™™«$|VéaU§,Ž“GÕ ò×>³§³*øÖ MÊWn\Q3ñÁ»½?·ü%ŽÑ­¸%=mrSúÚ¤ø#Xð„^ü’:ÊÍTü¢w’’žO­Ï£ìð©¡Æ~§@˜ÃœS “°ázGMü•=ƒÔ,æ|À’àÓ]°’OߪI†7[¾*ÁtœŽ‚éÿ£I´¿Ö<_ Ük"ž«?n» ÈÅÀMƒi¯»¤,1ÀùÍìj.bLBZH ›¶\6óåm^UÅ–“³]]Ö}Îy—ÛF*®Àç,K²P˜9A˜ÀNÿq—‚zÝ«TE?ÐŒ²Â!¶°ä°ýÏN\ç¿„B¨ÈXÕ úÌQü‰‡io€ª¸šw¡/¨w×ù‰'¹¬ÏS<2&U5üy‡¯!?Ó‚nà7^ú™GAê)¥‘Ù¨ŠtrÆ(ŠFëkFß‹üöÙ¹ÏîáJñ[ù‰Ø&Bð‡?Éïþ_AÛH¥©œ’ðÙ4•™õD!åVŒ)ßþ?'´À¨endstream +endobj +1421 0 obj << +/Type /Page +/Contents 1422 0 R +/Resources 1420 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1401 0 R +/Annots [ 1424 0 R 1425 0 R ] +>> endobj +1424 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [432.8521 368.6685 481.8988 380.7281] +/Rect [116.0003 361.0037 166.1092 373.0634] +/Subtype /Link +/A << /S /GoTo /D (tsig) >> +>> endobj +1425 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [399.2874 253.3317 467.9594 265.3913] +/Subtype /Link +/A << /S /GoTo /D (zone_transfers) >> +>> endobj +1423 0 obj << +/D [1421 0 R /XYZ 85.0394 794.5015 null] +>> endobj +434 0 obj << +/D [1421 0 R /XYZ 85.0394 155.2922 null] +>> endobj +1426 0 obj << +/D [1421 0 R /XYZ 85.0394 130.8971 null] +>> endobj +1420 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1429 0 obj << +/Length 3082 +/Filter /FlateDecode +>> +stream +xÚµ]sÛ6òÝ¿Bo•o,¾HÍSš:©{×4g»7i&CQ´Ä Eª$×wÓÿ~ ì‚_¢ãtÜ=p.‹Å~S|ÁàÇaDF˜ElT2.Òý[láÝ›3N8+´b}w{ö÷×2^˜ÀD"ZÜÞ hé€iÍ·›÷Ë(Á9P`ËW?¿}}õæ—ë—ç±ZÞ^ýüö|%B¶|}õÏK„Þ\¿üé§—×ç+®C¾|õÃËw·—×ø*"ß]½ýg >!z}ùúòúòí«Ëó·?ž]Þvgž—3iòÛÙûl±cÿxÆit¸¸‡ ¸1b±?S¡ B%¥Ÿ)ÎnÎþÕ¼uKgåÇY d$f(ø‚óÀ„¡I04A$…ì$(H…1¶lڤ͛6O›UºKÊ2+<ñ ¼ÈöYÙâðûìWÆD™·yUâLRnø¥I¶™• ì.×Çð:‘4nÛÛGâ$n‚Xí3‡3ÇÍ)a,VÑ` 1*¹Xn²´Hês®—Yƒ3iµßË·É2IÓ¬™¼ìOŽã¼¼«ê}Ò‹»º£ F”Éž &«?gµUØÀq‚ç:à!Ý÷í.·Dy4•æe›•zç᱂ÃuËì÷|]dÃ÷@ãx8T5QØ‹6?x”‰ íÔÁÝDÕViU4~W"è;ÞÛ#^ØL¸‡c‹oRœ_u§ròE?€+ʶ€+q¸¬Jýp{û¡NÐçô$þ³ x©Ãå•Ý+ŽˆÞoǼÓ‹Ýî’!ò|8AÁN}È «1vtŸ·;„Š|ýû¾/`¤µ;í©ö+0dÉðTýQµº÷#Õú‚i(%ø©i¡t ÓyQà”•Ð¡uÌËìsVê=[|ƒK#¸š¼ ){ÒêH¤ñ2aN]'õÃ9ë±×iBºNx—”ˆM7Dû7'蹺Kò‚@çŸdì|>³õlÎpÍËrÎù€áŠH“´ò ôT¤à¡Œæ‚Òªlq/Ë«0þ2ì@£˜`2Ááí«w8nªô“³~€ ¸á¬ÌË-â$4„‰æ¥¹u¶p+§, Ã÷ +“¦ñH*0Î( +!F()¾&" 8¡ÖóñhÕQ\ Iú`Ós&C¸"ó~gË¡ó§B<`Æ{}ç,¾^1¬Õ\>*B(Žcý׉ £ø„T<Šâ±’ͦ~DÒ[ª5)—÷»<Ý‘æÃû)=1}§ñàOœ÷ÑféÇWï>+œ#ð3BŽçÔpzJ„XC§±zT°BD`/Ž'u„Ÿ-׎àj@ñT¬ æäx¬/IU†)/VšEÎÉ!b<ñ Và[-âßæÒ ˆê,^ °~e!KÀzë¼ù0Gñ¢o4.œÖð2r© û¦÷ÿË_”¶þn“bª²¡Ëì/êjDAÐM´ —“Ú(k3u¬ë”àü\C¡»tÁß:ì&îð騲f8ß4ˆ‡L::=K™ÕžHCZ|nIJÂ÷èÍpî2 Š*H ög‰æƒm.Ð¥CÖùøS]@#âøq7È%¸É2߈«@Æqül]í(®†$O••K„û¿¬­!äBOh«P±Qß~;¡HˆPV +F)ǹàe‘%¥”ÊÙ„“Ïxâh6ÆÅDÙBwÎë@¡ Ÿ¥Ø<‹3—þã}’áèW!ÔÌ©%—Š˜yÒHÃÀÄq42RK9*b}ͱ|ªX†\ÇüñàÇ„¡2J„êù±…®†gB‹ÊÌè~ã/DW¸qÍ+„R"P2âÓâ ÃГ´`ÿ‡®Ø`䟩X |Œ*÷ ,Èi’Œ¹­ó]!ÌÙbÊ>Ñ:êÖ…%ÅÌ5€ÆÚ@åˆGHŠ¢ºŸ³Ÿ8ˆã.}†Â®×êSËWCé¶­úí@$DÖ“ºmt<£éxç|Yà˜jK²zŸ·xBµS‚Úo\NSóy¿`,ˆE¦¬w°ið4Þ^NÂGQÀylžp=ÅÕäLÄ5[¸C³lB9ŠÙÉ(á‰HýuLvŸ`RÂíCV ÆLÚ€4gÖ‡¦3 Èé$zC¸$ð†3*¨„xJu ¸6# D p¦Ä)#h  »˜Ëfd,DÀõ›™m kA¨ e‡MåÝF|à˜,šÞÞaÕ²§w®³À0åÀ^G^¦¾DK`l4á¡Û³MrÚŽØämþÙ-˜Yóv/]Cc¦š^µ€o +8ù$$íòíÎ÷#³¶Ó•ïÊ}eèu&Ý’¦Â^BšÛ)#¡u$~;Ú=9PãPçPNXÛÎvZÑuÆæÁôŒús®0P¡Ö3Õü@:OèX|,9B¿$„[­|ME•¸; íf#ÏǼèÆížQÌ÷Œ š‘à}¤F2o îE)Ó·#9µ#ÛúéÁfõ){˜ïC¾©“ý>©gR†I»qL)ÚÿuWf ö6qúµ s­<î×Yýexˆÿb.Ÿ}Š÷çéºÇû >| j`Ž÷?^Ì ›ÙÌ"ÐŒõ]s!¾VÈÿÇf¯Šº\vÄÆLfg€cε²Ørƒº6 ¿{ssù +á&KuÞ>àM·j]åËø3o<±&­ó5–l¶õz’ôyh¥åB†*`Üeþø®Þ.¸´ç;ôÕã׸W7¡jÏyÓ9#àDú„È á•“ïÒ LiùÐ:òÒ Ów"!( f¦…¨—´ä¤q„‰ ï.Êå€ly¿snDúØÀá¸.òaP°ž ÁGY•«äØî*Ø/¡Óÿ©Ê ûý>•Õ½‹#Ò7a²+^ÓR§&Îs‚GŸ±àjm~°ýM<Þq»Ã У „²ŽR#¼ÎRLì w_$°ó,}ÛÖ"Ћ̎ð0ªæÉCâ{ßÓu~§#Äámi[Ü3¡ögÞ¥5jû ¡ÛñÎ6+ìÌ:s%=†G{[Õ†^‚ö>×KgË8¶©ÿ+c’,» +û§YÒŽÉ1×t¶~Á.Ùx~ ÿF–øòsRä›Áâ’(JÛöÌ©ûëžÖ£>«Â~CAg×'NáÀ·L{÷e¼{ôñÒ]­+ñ_r(9®7Õtªg ‰ÿˆÓSØ»­ù^¶ÛMÆKrà¹Î”óÑ0H«šu¨Ê Õo±Ó“†ÚV2ÆÎ ­ÈgûPÄ&޾Ò]k@îZº}•Ô7Y¶÷;a/³ßmžî@DÝRw¨Àï0Eh >#!Ìæc<¿šiçÎ T´lŸ­AMh–7ù>/’Úå’ð x}@ꤣ¢G¤‰;ú«…õŽéúÝžph®\mÝËÔ¯Pôž^ÿ=@óþqùoŸ'D(Df,—ëë&k§Úß‹ô¯ï¤ÁÁ™|pØO™UÒG3veØWHG3ßy…4Ô —zP‚Àìàƒ$Œ(œ{¼:Ï\kQ'IÒ]·¶±i8šˆ!•ó_"‚“ à¢ñâ´M£/PÖ1dY±˜|¡³O“­ÝOªpô”¦’bkCÙnïÆŠ¼˜ðA€ïˆ½‘ÂÞÑ Ó÷ß²ákåW¢?¡óAöÀüÍ!I3ÏO›¬=Xf÷EîÌÅ®´\ÌøÎ4©¡ôÙŽüe{¬½#ëõÕz»mYu±bèþºJ /…\ä…¯Î&H}Üx[¬:Ê× +_+~;_ TFî”Á#™òI9")Sþœg÷Ï+CBD´>ºöVÄvË(œ¨Íû´HšæÃ°\™d%®³J‹8éÊ÷ ÒG‡ñÑuAÜü/©·$¾ û 5ÉžI¬¶¬Ôl…þÍâ?dÍǪþh»ÍO•JN<ؤÊÇ>sÛÑëæ?vNaºf5+`äîÿ;€nÿt3“M³NYžýßžþOP›I­Å|^.lOHK陲œÇâ„sÿ' SÖÿVíÂendstream +endobj +1428 0 obj << +/Type /Page +/Contents 1429 0 R +/Resources 1427 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1401 0 R +/Annots [ 1434 0 R ] +>> endobj +1434 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [432.8521 350.2114 481.8988 362.271] /Subtype /Link /A << /S /GoTo /D (DNSSEC) >> >> endobj -1415 0 obj << -/D [1413 0 R /XYZ 56.6929 794.5015 null] +1430 0 obj << +/D [1428 0 R /XYZ 56.6929 794.5015 null] +>> endobj +438 0 obj << +/D [1428 0 R /XYZ 56.6929 769.5949 null] +>> endobj +1431 0 obj << +/D [1428 0 R /XYZ 56.6929 749.3407 null] >> endobj 442 0 obj << -/D [1413 0 R /XYZ 56.6929 543.7303 null] +/D [1428 0 R /XYZ 56.6929 505.5458 null] >> endobj -1416 0 obj << -/D [1413 0 R /XYZ 56.6929 512.1243 null] +1432 0 obj << +/D [1428 0 R /XYZ 56.6929 477.9188 null] >> endobj 446 0 obj << -/D [1413 0 R /XYZ 56.6929 424.5706 null] +/D [1428 0 R /XYZ 56.6929 399.4257 null] >> endobj -1417 0 obj << -/D [1413 0 R /XYZ 56.6929 390.1552 null] +1433 0 obj << +/D [1428 0 R /XYZ 56.6929 368.9893 null] >> endobj 450 0 obj << -/D [1413 0 R /XYZ 56.6929 210.2494 null] +/D [1428 0 R /XYZ 56.6929 203.5616 null] >> endobj -1388 0 obj << -/D [1413 0 R /XYZ 56.6929 181.6082 null] +1410 0 obj << +/D [1428 0 R /XYZ 56.6929 178.8995 null] >> endobj -1412 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >> +1427 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1421 0 obj << +1437 0 obj << /Length 2930 /Filter /FlateDecode >> @@ -5861,134 +5938,139 @@ P; Î/(7’»â’œ—Hlò[;aA/NU^;©Gœ4üí¼ºËHC¿3Ü|Èçg”^ëW|É„3×ÃA™½ÚÕŒŽÚq…bW¶.x¬á{?äÚx®>Ìk¢vsF=Ë1…|P&pÔ©ÄJÃø0Bªÿ< ©C¸ÅXyÇ)°XÈ[Tæä€N8DO×–üôàUÒŒ§/.§Ë`â°µ+æ{Ùt¼»Or1w'n³zé?¿„Þ\ƒR@1’Ï;Yˆ;c’ÊÛr8 |ޏ¸ô±›t@.9E³Ý••]-ýðåÍæo%ù"¼ü³Ã­²™æÀ´3­±†3ψŒÆdsõ"ð%Q}@°íGzC’“œ"«©±Vª¿Þï«r®úð#ÊLr¨6qW?yèX]pª÷„Ì4ÅÎí(,d Ü]f$¶Ì¤?º¸ ‰8«ïgK5BðÆr1hÆXÐ[fà-&Q·ojšpÖsD³£™ÊÞÚŠÆ0%ÉÞć=ßeá,Yšèþäyu[®+_R'aõí®:L¥XxâU=Qt±‡(v†OÇÈL† õ‚nj)Y¦E ™(ˆ@Ù³r‡È²¹ßX€7—½@ù”›Š^¾€ôbž¸è}œK… ÇA53°Ÿ¡l*Ên¶7ÐàgYòWr;úÈ3ûÀÞújC¸5c7ȹÐzè'hð–,~dcnš -èu}Â@|ÌÞJ‰ÐDÏù)lNUŸ) á׼ŷvlÒ›…ׯ,èzR×v÷;ôö'Š\æëD²\FZî;Žû蛡¶úÿôüûÌå0h­C‘š#µ)ØÅ€¼o|±ÿ ½ÿ×KGÐ]FÑa/_Ò’kç|Hµ›æP­ˆæž Iü%Åž7½Õ¶»köŸF©cäóÓ»2Å=¤ÝßËô üñÊ3PøC¡Ðé~Üóվ쇋'¯Ýß–¿ >r"¦ÍYi™/†<\woÛçË”óF ‚¢ãÁá@fN¼ O1ï{pÀ;ܱP~7HûÕ~uûѶòŸª U[70Tã:¨Œ$y-àÖ#£…­^Í1_—Õó¥—+\Ý|óŠ=wÊŸ>ýc~RŽ'ûã0Ǩ÷=ìóQÿaÀ·«Ü€Å]¶÷ž`Ù-ðÎÉqîöö¶lípîÒ G<Ë®ìÚýõ\?ð&™¨öô×ÍŸ?²Û—Eç­ô5áÏÕrª}é7TýÛøNê/»€ÊÂ4M²¯ãþ$z˜û7+þïËÌ?½ˆþÿZþò¿Ø ÿd’P§©þ{fR èÑT$,ê•ÈcÉûÿÅy(úÿÛ"›ˆendstream +èu}Â@|ÌÞJ‰ÐDÏù)lNUŸ) á׼ŷvlÒ›…ׯ,èzR×v÷;ôö'Š\æëD²\FZî;Žû蛡¶úÿôüûÌå0h­C‘š#µ)ØÅ€¼o|±ÿ ½ÿ×KGÐ]FÑa/_Ò’kç|Hµ›æP­ˆæž Iü%Åž7½Õ¶»köŸF©cäóÓ»2Å=¤ÝßËô üñÊ3PøC¡Ðé~Üóվ쇋'¯Ýß–¿ >r"¦ÍYi™/†<\woÛçË”óF ‚¢ãÁá@fN¼ O1ï{pÀ;ܱP~7HûÕ~uûѶòŸª U[70Tã:¨Œ$y-àÖ#£…­^Í1_—Õó¥—+\Ý|óŠ=wÊŸ>ýc~RŽ'ûã0Ǩ÷=ìóQÿaÀ·«Ü€Å]¶÷ž`Ù-ðÎÉqîöö¶lípîÒ G<Ë®ìÚýõ\?ð&™¨öô×ÍŸ?²Û—Eç­ô5áÏÕrª}é7TýÛøNê/»€ÊÂ4M²¯ãþ$z˜û7+þïËÌ?½ˆþÿZþò¿Ø ÿd’P§©þ{fR èÑT$,ê•ècÉûÿÅy(úÿÛz›Šendstream endobj -1420 0 obj << +1436 0 obj << /Type /Page -/Contents 1421 0 R -/Resources 1419 0 R +/Contents 1437 0 R +/Resources 1435 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1398 0 R +/Parent 1440 0 R >> endobj -1422 0 obj << -/D [1420 0 R /XYZ 85.0394 794.5015 null] +1438 0 obj << +/D [1436 0 R /XYZ 85.0394 794.5015 null] >> endobj 454 0 obj << -/D [1420 0 R /XYZ 85.0394 769.5949 null] +/D [1436 0 R /XYZ 85.0394 769.5949 null] >> endobj -1423 0 obj << -/D [1420 0 R /XYZ 85.0394 749.1193 null] +1439 0 obj << +/D [1436 0 R /XYZ 85.0394 749.1193 null] >> endobj -1419 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R >> +1435 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1426 0 obj << -/Length 1106 +1443 0 obj << +/Length 1112 /Filter /FlateDecode >> stream -xÚÍXÛnã6}÷WèÑ)@®H‰º OÙÔI³èf[¯û”#Ñ»º-IÇqêþ{)QräKÉNÂ0$ ÉÃ3Ù!‡È²õYă^ˆCË]HlD¬(ØÖ\·] PÝ4@»×ÇÉàÃ¥ã[! =ìY“Y +€v kß=ˆá™F°‡_n.¯¯~ŸŸùîprýåæ `b/¯™·«ñùçÏçã3€‚†?Ÿÿ:M“Wc|¼¾ùÉHBóxt<ºG7£³»É§Áh²Ñ¥­/²R‘ïƒÛ;ÛŠµÚŸ6t€XKýaC†ØJ.q q§‘$ƒ¯ƒß6€­ÖjèAû!bÇà 袖C \Ë'!ôìTüûÇR 8!@†„àVã‡KŒ¬x¦'®¯çñÍ`¢ÍjÛöð9Ϙ±ÑWEKY¦jë š¦T¼-Zˆbà ‚WcM3šÖŸ·QB¥¼3U¬±ÃÒÌ5iãjUÔ#R*FA{[³[Óƒ&I¾ßL¬\#cÁ¤œ¦TEÓ„KeäÚ Õó®&ȳS`Ñ>¬4“3&Þ™í¢ˆõj½¨EžðhÛ°¦ejZ¦b‘4‹ !¼ëc ™ƒ,W|¶ Ï‹iÉ»Æ,r¡6òò£ž¡žàöˆ1šfî³5¢}¥#K#øÃ&ö’Šl=£Ü’'qDEld+&§¹˜fyg:¾µ³ž:2ôìèÓ?@JϨ@’|Þrl‘Þ7;BG”f<Ö.Ÿ/TW$ô*’âi/¤-NíT¾c—µy°§Bo\m M؂ҽ{Nb–ÐzdQžÅ²³Ú5‚ÊÌi*÷ߨjßL¯½÷ôûšÔ$b/)€n+\×ò|èøØÕ8Ðw·‚ù¡j"0ô}ÏjÉ_2Ç[±nØä;Ð!ÿfAÃÍ€@GÏ^Ó$¯Ð$GÒ Äö³<‚©O²úøÃ#ylàJ>4á±Þ«}R<6›CÏ+‘ô?Ó¡Ï?q“Ñz†[¥|Rµïõròî©•>Ò£}ªS«`3­ÀC•„ŽNŠÇ€ }&JŸûOäq„N.zË,RySÕT=T•T%ž™(ÖenJ%o»<Ø©ÂÚ¥cUÜÕÍ'wx§¸“ }do×vЄӫ°ÿkÁˆß³`\ÛžÀÀµ\c·°|hú>2&ÑtèB ^(sxõåîúöæ÷ñå…ç '·_î.€…Íáõí/#ýv3¾üüùr|ÑðêçË_'£±îrkŒ·w?iI ¯€ŽG×£ñèîjt1›|Œ&[]Úú"Ó.ù>˜ÎL#Rj˜Ð|l¬TÄ(,#8؆رíF’ ¾~Û¶z«¡Gí‡LhÙ®uÄ€j0° ƾcx8€®mÙ•ÿþ±ÔÁ6†¾‹±‚ÆV«óõ…Œ­8V“ÇSóxöv ,¬Ìjšæð9Ϩ¶ÑWI$Mi&kës’¦„k¼Z +ÎÂÙXÃi·Æšg$­›Ó0!BÌt㯊µeà4sMZ»„\õˆ”I¹VÐÜÕlª¿ I’¯À÷%åëWË£ˆS!æ)‘áþ]ÁÈ´}|ko=Ud¨?ØÓ§€”žQ$ù¢åÙ2½ov„Ž(Í6X¤\>_Ê®HèU$ÉÒ^H;œÚ©|Ï.ý O…Ú2˜Üê°¥{÷œ +D4!õ AÃ<‹Dgµk™‘“þU,ï¿Ñõ¡™^{ïé÷5;¡2HH_R+œV¸n*äzÐö,Gá@ϱ +懪 ÃÀó\£%ÉoźfgCÿ›5Gðè¶iº‡4} m5{M¿BŸH3@Ðò-ï¨1Ë#(ê$«Ž?,§®` ðH©Ý±Ú'ùc³9´Wzª³ÎžX⪦üC†¢&¿õ ¾6Jù$rÉßêåÞ3­¨"99í§*Ñr+ª”trŠ<2‘ª +8“ÇY*Õ¨ ÓPæMSùPÕU”x¦¼> endobj -1427 0 obj << -/D [1425 0 R /XYZ 56.6929 794.5015 null] +1444 0 obj << +/D [1442 0 R /XYZ 56.6929 794.5015 null] >> endobj 458 0 obj << -/D [1425 0 R /XYZ 56.6929 720.2271 null] +/D [1442 0 R /XYZ 56.6929 720.2271 null] >> endobj -1309 0 obj << -/D [1425 0 R /XYZ 56.6929 692.8842 null] +1326 0 obj << +/D [1442 0 R /XYZ 56.6929 692.8842 null] >> endobj -1424 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >> +1441 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1430 0 obj << +1447 0 obj << /Length 1141 /Filter /FlateDecode >> stream -xÚÍX[s£6~÷¯à1îŒ$!@³OÙÔÙf§›m]÷ÉÍxˆ„†Û"ygÝÿ^q1/¾@6ӎǃЧs¾óݦ«Òl -u Íb¤:¢ští^µ}¡ê°ù4¿z?_Kc™ØÔf~ˆºm#mæÍÏ.¹øm6™Ž¦ú™ Ç€šúÙû뛟ËV>.?ß\]øsz1¶Œ³Ùõ盲z:¹šL'7—“1@6Eª?®öt¸ºþuR–>L/>}º˜ŽogG“YíKÓ_¤“Ü‘/£ù­®yÊí#fSíI½è1†µhdP©AȦ&ý1ú½l´]»ø£Ä†ÔÆVjˆt2ƒYšE4 &ƒó10uýÌ Ãä ,SÏ‘øIöäd^ߗߪoI]ÀÈ(}´µÏ –êvü©­è©Rq„ñoÛ¸·º5æÃuŸÎy5©Âm Þ–Ñ\¸Çä‘k¼ #Lî"—ÑÏzeŠÌœX¨ð‚ÀSÉħáÃ@ÉR¾IQ“Ða ¡&5”ÍU:àÏi¸A[¥j@>uô -xo’*#¯£4ä%÷à!žQ'ÏÆkyF;< ¹¼;D^y£ñeɳÕ»Åh`‚ÍÁy,úööþã;ƒ®û8Ba~‰Öq{¦þÕØ¯¾«Û^dj•¶m\_ÃaÒ¸†#º m̬Q¹ÏÙµ¼¾ÔûÞôh÷Lendstream +xÚÍX[s£6~÷¯à1îŒ$ Ù§lêl³ÓͶ®ûäf<D¢†Û"ygÝÿ^q1/¾@6ӎǃЧs¾óݦ«ÒuƒššMMHtD4/éÚ½jû0BÕ7`óh~õ~6:¿2lBjaK› ,ꎃ´™??»üåâ·Ùd:˜ègbégï¯o~.khù¸ü|suýáÏéÅØ6ÏfןoÊêéäj2Ü\NÆ9©þ¸BØÓáêú×IYú0½øôéb:¾}Mfµ/M‘näŽ|ÍouÍWnéРÑžÔ‹¥X‹F&1 1 cSŽþý^6Z‹®]üÃÄÁv&jˆtR“ÚšM(´ l ÎÇÀÒõ37 “'°L}W2$Ù“›ù<¾/¿Ußø~Æ„XD®ô!²¬ÿç]ù¼ÍéP6„ %7ñ+dïyàQ<–µ+&I¶ˆ“d¶ÒKAÆeÅÃI¨í¢H@œH¬Znñt‘{V¾ÌÓ$“u}þr[¾UÌôn¬;™¯’¨Ø˜(+þÒ‰®‚¯—‡k~'Su¨5Ò!DŸ»á2m–I*yBhð•%!³Z' ¹B²,ïžKKÉgë’dÏr¹O½\ù;Yf±žj jÛò ªþ@ð—Cª´)óN½ÊŽ­I®ÖÏ„ìåE…Ã2Ñ’ã*¬E2pçŠa!-zYŸËXìm”Ú'© ¥ ¶vâÉc©þ`ÇŸÚŠž*Gÿ¶{«[c>\÷‰àü‘UÓ‘*ÜÖàmÍU€{L¹Æ :Âä¾!òxݱ¬W¦ÈÌ… +/à¾J^Ÿ +„%Kùz$É£>&¡Ã@CMj.(;š«tÀžÓ{¼-ŽR5 Ÿ:z|ºU'Á¼$öÅÉnW2"qûgkº¼«ÕÚ¤i_¹çœRD¨ùÙcÛDã©ÙH¥ul + l…mÓ0  ŸŠ&©m[Z£~›PÇfÒÒ¾|? Õ©“Å;ÁW«iªõ½©Ô†ØRÛÁÒT²ÇT2ÌT¬6í¤Ô %èEkíMl¥#BNµõ(µ#ˆlÝz`lCd:¸SKÁÀ^zûdU•”'‰Þ²¡acs_tÈ«¢ƒl&¥Ç­<.ùmþ¼EvRqqâéˆËK3 ¤+ÕzÌ=1t7 Ž+îàÝQ¤ö#Õ9¥X]¯QC@:,)ÎNƒ! +;úB´]Y†’ƒrÍ–åÇ·|åR†Ça6 EÅ´Û@Sû§jŒMs^›‹f+ŸE~îªé…®õÞ¯˜sº`å*­z<¨ýè»..ömqh…ìÞÍÏhBæ†%ÏÏËçMReäu”†,b±d><Ä3êäÙ|-Ïh‡g!—w‡È+o4¾,Y¶úa· L°98ƒEÿÃÃþÒÞ|gÐug˜_¢uÜž©5ö«ïê¶™¦Z¥××pØh\úLíQ¹Ï6Ùµ¼¾ÔûÞôiONendstream endobj -1429 0 obj << +1446 0 obj << /Type /Page -/Contents 1430 0 R -/Resources 1428 0 R +/Contents 1447 0 R +/Resources 1445 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1432 0 R +/Parent 1440 0 R >> endobj -1431 0 obj << -/D [1429 0 R /XYZ 85.0394 794.5015 null] +1448 0 obj << +/D [1446 0 R /XYZ 85.0394 794.5015 null] >> endobj -1428 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R >> +1445 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1435 0 obj << +1451 0 obj << /Length 2154 /Filter /FlateDecode >> stream -xÚÕËrÛFò®¯àÚ2Ƙ^å“ìHŽRk%+3—UT*ŠH@€ €¢¹ñþûvOÏ€ Z²T9¤t@OOOwO¿‡â£þø(ŒX”Št§Š…GÓåI0º‡½'ÜÒøŽÈïS½Ÿ¼½ñ(ei$¢ÑxÞã•° Iøh<»ñ"&Ø)p¼?_]\~üõúì4VÞøòç«S_„wqùÏs‚>^Ÿ}útv}êó$äÞ‡Ï~Ÿ_ÓVdy¼¿¼ú0)}Ž0½>¿8¿>¿úp~z;þéä|ÜÝ¥_H¼ÈNnnƒÑ ®ýÓIÀdš„£ ,ÆÓTŒ–'*”,TR:Lqòùä_ÃÞ®9:h?0!#1`@Å{LÀ*SI!oNý(¼yUo²zF‹ß‚0¨Êbûuž×M +Nøwô¹Å[ƒhŸs–†¡à£ë†ÖÒÇîæ«»l6«-nUÕm‡ÇÅížƘ“g>ÿ{†øeÖ´ì£þÜ]sïØ]‘7öÀ×ïQøæ½%€ÛŽù¾Õnà>ß¾ ߿ɿ­³²™ëÚÏg…öó’vÊõr¢ëg{dQ›/_Ìhµžt÷ì=7m—÷ßb¿wáNǦZ×S½sQ¾R='|5,xœ2)â8±XÉÐ0ú‡Ù -YÇѨ‡ß¹â©#ý°@0 ‡Íp §ÿõU«šÆL@Þý5ªŠ@BîÇé ªYÑúßeÖ7ÔIÑU½T×” †ƒîÐõIÓ -Áƒè/2­ˆW‰4íºÑþQónusWÕweõŒ¬úoUj¿i³JO>m<;{fY›M²F?7õöKD^úµž×ºY˜ -ñâ:ó&ü±&m½}­¯c±.Úܧ¦ð´C|!YÊM‚÷.5Þ - mÊôöÎïweæ4¼™YÓtýÉD÷Ûv»Ò{öÝÓÍøoØÔ÷c[ú¤*}¼À÷{D zD¾Ö#âÀ#z¾{R—·‚:ôUƒÑ,»ÑV@äUŽfÏÏP+ôR—--п(sK˜¬œðk“ÝëNÎnD (–*.{r·’þÝIŸ¦`ç•n§Ü„³(ŠùHèÇÏs¡µ„i¸?å¾èÓ¢çÈ£òé\¬,èNì³òÝ|‘H¨X OМ£Ý`rð “”œi ZöÈcÅbž& ÉÆ ´+˜´Ñõ„ä”HR/£µ+:O«Õ– jND­cåž ÈMº=*ÈÓD 6yQ4ÑCyžM -ëó¶¢ïª>å‰W=ä3»‘­ÛEUçØ¨ªl6¦&à‚ô oÙa¼¨D±$’ѨoÝ×9 #ƒ§Ì0Qô]1`O‹(fI¨Ž†@ÌRÉùH€w£8IŒ›"{ÐCˆä6ÎÐ+±¥5 sUâå a2úëëU‘O3Ú§èö»0±L ¨*!Lˆ=Îwœ»b´zÐ ×f@[³X8mé-d^éiîÛj¦b¦¢Díj,AÚBìÙò*ׄXVtZ]þB»¦e ºiº“s{À]È(W,A»ÈZY!Θ€›BÝ -î6›¶Ž‰îÈ[¯ 챜6#—n"‘“Ò™XÊÀûä^˜H`mPú±&;VYIè¬hª! } ¦ÅvÓˆBͤÖ&»×,âQVJ€‡¼÷[ÂÍô<ƒYå yßÍ¢ö@æÌ.MÀÌôP‹Sž/Aݘ{Ô¼E,¼PÆ4ø’)°y‡¡"&pOW†“K8]d彞тª™)D@¶s,`'Û!#™¸›oÍ$+•ÂØ—*´J"Âuˆèyg¸gÆ ò¢Œ…ƒ!høõCl(# -ZC[m6¤ØJ›s~WÈCåÁðmL`6oÖF²a¿' -|y…"2ݵpeã´w|×bhì.yD¡f \¢Ã¤"b6y» èPuÄ?_~$Þ÷¨V¤Þåܲ%^˜á…å†÷įñIýÙ›Áă{¥»{uM†Òv&ÜšX’ 4™¶;X9F(@"xhºF_UU„òfH/™èqR“”°ºdŠÅì’WV€:6ߌ>];†ð¶«[¬ÏQ™;5w§\êØ‹€S_èxM«%T™™Ñ]pHƼœ:–¾ÕÜÏ€ô¬!tª£FëÑŒX]äË|°€–P+m—Çö£R¯Æ„0!7œšÊ `»Ég태ÞUå(\ wT©î-eõ çÌhpW‘d uÙÊ$/`ëÒfÙÌíÌ-í¢Z7 [CïŸÝ7QÓÕÊx°+vøÛ/–X|Ó´´qXÜVujÒ&°ÀŸ ‘ѺÝT~![Ê¿©n¸ÕLzi©í0%º±_Ú 0ý‚QJ^‘ôô—A·eËU¡ßì¦K(×ÝèÑ @“¸ÄUùÄÊ5Âþðr–ÀÃÁŽú‹‘Á ,¦‰Fä0nêÈï-IYÙT»þ¡Ý-S¡8x&ÙL†º ͽ¥þŠ«¼4… Œ>]F")ôÈàí•`A,ÂNû·ß¾@3¨2‘%ß,´í/9KŒ•Ú1à&`¼-- 4ƒgW¼H¿¯M Au"€7¬;ì¦" 8…Ämí@k“ýc6€ÂÐaøHL}ª³ -Âz‰CX6[Èæe3<µ,27üCðl jŠjSX8ŸÓw[­í;bm³ß–A@0yËVò¥+.ÈTqÏ‘Yn _[8%™Ì=öÀèî¯{ (‘àO‹à)˜\ ýç%èï¯þ?ÏîŸ`0`Ãì'º×Ç~Å S 0‘!C^è•X=ú/”û‡¥ê©þ&4Cendstream +xÚÕ]sÛ6òÝ¿BôMˆ?'ONj§î\Üž£¾œëñPd±¥HAYÑ5÷ßo P”LÅŽ=}èø‹Åbw±ßù(€?>Šbg"%YÈ¢€G£éò$ÝÃÞÇni|Gä÷©ÞOÞ^Èd”±,ñh<ïñJY¦|4žÝx1ì8Þ‡Ÿ¯..?þz}vš„Þøòç«S_DwqùÏs‚>^Ÿ}útv}êó4âÞ‡Ï~Ÿ_ÓVly¼¿¼ú0}Ž0½>¿8¿>¿úp~z;þéä|ÜÝ¥_H¼ÈNnnƒÑ ®ýÓIÀd–F£ ,ƳLŒ–'a$YJé0åÉç“u {»æè ýxÀ„ŒÅ€CÞ3`°8VI”±X +i xsêÇAàÍëf“73ZüDA]•Û¯ó¢Ñ-¬8áßÑço ¢}ÎYEb€j4­ÿ¤Ý-VwùlÖXܪnÚ‹Û=1Œ1'Ï|þ÷ ñË\·ì£þÜ]sïØ]Yh{àë÷(|ó‡ÚÀmÇ|ßj7pŸoß„ïßä‹ß6y¥çªñ‹Y©ü¢¢j½œ¨æÙÙcÔË3Z­'Ý=ûGÁºmŠêþ[ì÷.Üé¨ëu3U;«°ç„¯†O2&E'–„22Œþa¶"–%I<êáw®x*äH?,L¡A3èé?Ä}UãǪf wª"ûI6¨j^¶þw™µÇ u +è¾T׌ EƒîÐõIÓ +ÁO‚ø/2­HS1hÚµVþQón•¾«›»ª~FVý·®”¯Û¼…ÒSLõƒggÏ,oóI®ÕsSo¿D•ߨy£ôÂTˆ×™—0á5i›íkõx‹uÙ>5…§â É2n¼w!¨ñVmSΠ·w~¿«r§áʹ̵îú“‰î!¶ív¥ö:í»§›ñß°©ïǶ*Õ=$H]ùxï÷ˆôˆ|­GÄGô|÷¤.o/uè9ª£Y v£­€ +ȫ͞Ÿ¡V¨¥ªZZþ ~ Q(–0y5#àWß«NÎnD „, ¹ìÉaÜJúw'i|šWJN¹)gqœð‘ bÐ=Iž5æBk‰²hÊ}Ñ!§EÏ‘GåÓ¹XYÐØgå»ù"•,“px‚æí“³€7H”fäL[(ÈвGž„,áY +"l¼@»‚Iµj°° ¼È!§Dšy9­]ÑAxZ¯¶Õs"j ,÷AnÐíÙPAž&µ)Ê’ ‰Êó|RZŸ·5}WÍ)O½ú¡˜Ù|Ý.ê¦ÀFõàP•Þ˜š€ Ò€¢e‡ñ¦!KcúÖ}Ã02xÃ,@ßöıˆ–FáÑHX&9 ðnœ¤©1 .ó50€Hnà ½’XZ:W¥^¡ “ÓÇX_­ÊbšÓ>E@·ß…‰eE5„Øã|ǹ+A«½pÕÚÊ„%ÂiKo!£ðJM ßV³0aaœ†û…K2x¶|€Ê !–5݆V—¿Ð®iˆÖº;9·Ü倌rÅ´‹¼u⌠¸)ÔÝ¡ànóië˜è޽õ +È+h3véÖ);)‰¥ ¼Oî…‰ÖF@¥k²c•W„ÎK]éièK0-¶M +5_Ú ˜î^³ˆGY”yï·„›©y³Êò¾›EíÜ™]š€™©¡;§<_‚º ÷¨y‹Dx‘$Œi*ð%S`òCD.Làž® ''–pºÈ«{5£UrSˆ€lçXÀN¶CF2q7ßšIV†!ƾ #«$"ÜX‡Ø‰šwq†{FaÜ !ÊX0‚†_?Á†2¦ 5´ÑæCŠ­”9çw…< +=¾)Ìç­ÃÚ +mØïÉÄ€_žAa…ÈLw-<´qÚ;¾k1‡4v—<¦P3 .ÑaR1›¢]t¨:âÆŸ/?ï{T+ +2ïrnÙ/ÌðÒrÃ{â×øÇ¤þìÍ`âÁ½€Òݽº&#i;nM,ÉšLÛ¬# N< ]£/„ª*B…ÒËF&zœGÔ$e ¬ne ™b1»äÀ•Õ N€M À7§Og׎!¼íšësÃDæNÍÝ©—:ö"àÔ:^Óz Ufft’±¨¦Ž°¥o=7ÆÃ3à5Ó„îBaÔh½""š«ÊbY Ð +j¥íòØ~ÂÌ«€q !LÈ '¦rÁØnŠY»À çwU; +WÃÝÄÄ%Uª{KAY=è9óCÜU$™GUiB™äÌb]Ù,›¹¹¥]Ôk ºizÿ춸‰MT+ãÁ®Øáo¿XbñMÓÒÆa`q[Õ©H›À& DNëvSû%„lIX(ÿ¦ºá–ž.ÔÒRÛaJtc¿´Aaú£”¼ "é©/ƒnË—«R½ÙM—P®»Ñ£€&q©«ò©•k„ýá'â,…‡ƒÔ#ƒAXL1ŒÈQ*ÜÔQÜ/Z’²*ó©rýC¹[Fâà™d3ê24÷–ú+®ŠÊ€rút‰¤Ðc ƒ´ uÚ¿ýöÒ„A•‰-ùf¡lyÌYr`†;ÆÜŒ— ¥¥±„F`ðìJöé÷µ $¨Näð†M‡ÝÔ”§¸­H`mò¯Ì@: ©I£OµcVC¸Cï1qK½…l^êá©e‘»á‚gK.ëMiábNßm½¶ïˆµÍv|[Áä-[=È—®¸ ?PÅ=Gf…-|m â8”> endobj -1436 0 obj << -/D [1434 0 R /XYZ 56.6929 794.5015 null] +1452 0 obj << +/D [1450 0 R /XYZ 56.6929 794.5015 null] >> endobj 462 0 obj << -/D [1434 0 R /XYZ 56.6929 373.8367 null] +/D [1450 0 R /XYZ 56.6929 373.8367 null] >> endobj -1437 0 obj << -/D [1434 0 R /XYZ 56.6929 343.7228 null] +1453 0 obj << +/D [1450 0 R /XYZ 56.6929 343.7228 null] >> endobj 466 0 obj << -/D [1434 0 R /XYZ 56.6929 343.7228 null] +/D [1450 0 R /XYZ 56.6929 343.7228 null] >> endobj -1438 0 obj << -/D [1434 0 R /XYZ 56.6929 319.3114 null] +1454 0 obj << +/D [1450 0 R /XYZ 56.6929 319.3114 null] >> endobj -1439 0 obj << -/D [1434 0 R /XYZ 56.6929 319.3114 null] +1455 0 obj << +/D [1450 0 R /XYZ 56.6929 319.3114 null] >> endobj -1440 0 obj << -/D [1434 0 R /XYZ 56.6929 307.3563 null] +1456 0 obj << +/D [1450 0 R /XYZ 56.6929 307.3563 null] >> endobj -1433 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F21 710 0 R /F23 734 0 R >> +1449 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F21 714 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1443 0 obj << +1459 0 obj << /Length 3493 /Filter /FlateDecode >> @@ -6004,37 +6086,37 @@ F 1Õh÷oÖo‹”è« w–¦ÞmPËçj6"¸Z7œ;íªU7åêí©…Tñ9²ãvcp#¿ê’¬FÑŸÓeÅ0ãM»aTk•½a6tÛ,O&3ËL¥ÂƒUùL•áixø9± Žžè¼· ì£MZ®¡ ÄžÙDeª%d§ƒ*AÏén„Äb'‹±Ç†ÅëŶh»í% ³þuå÷_~ÐÁâSBüL¯‹ÞúxÅ]÷7øryÅe¿OÐÅÜw]‡·º}åê¢é3Öeõp}«Ø¢”×# Ö›]7˜qØV~Áç5*œCÊÂA|é9`l‘Þú(Ìú´Ïø¢BœõágŠáçØ»S^PY^熜´ÎmtÿŸo?}¼¾»Í’EhÞ”2„hç2¢”±ˆCD¨Äâ¨ò ñ^ójc6`Él¼qü:À“øsÜ¥:­®Êbò }«£ÿ¤Nà ÐÞ¯HUVKq{ˆ½ñ[s¹Ë ‘Á… 8ÆËÏ8é8} ;žf¯GËY9³ ÅQ°kE0Tl̆FÊdŒ\|Kã$wô.ÎÛç ƒò~üt8LÆqH|¶.Rµ‹=áñ" Á0ØKsDÑÙK}?j„Ž£ˆûl5~C·Õ+øu†õ`«¿6øÃŸ/ÀŸûã_/ü_“@AœA²‹–U†œ<ç¨ÂÉ«$i+«ßløa†v´“Cñ÷þƒË¬Àò‘Û¹< ¤OŸä‡˜Rç|=ÿÖ2ÌÁ BTÀE€LLøûI,šÕªye㤨¤mÁ &dR>§] VaW6WjéÍ72úÜt@ -çF‡Â#ÐÆ™KCbˆnf¼ž¬Ó8W&¼ßQÕ· ÊÖÑTzXPsF6uà•@Ïý±= Y1œ`‡/̘-©Þ«¾ÖlÅ(ugÕ`1$/E+}ëâñ(ÃL™^¶T(Í}/æ‘#¨|`Ͳl«æ­”9·!†Éá/ *iééœÁþwáG †ëàAoh3ùÃÀèÂ×ǻǿɒ?pÇ/lÅq¹s¿$±&ºëŽ 8ÿÅD»,aÇÔgqž²{‘Ì4ÔÑâ Ãò€/Ŷj(®A…Ü·]¹n¹,Ÿäy×âïEvX<¤é2‚|©’\>Çn†o¶ô  +sîsðm [üáÈÔY-É`~-÷¯ƒßnüþ+ÈwŸÇnX ç³AôQ öuSï×'*Ǻ¿õ‹0KC=æàOXüÕ?;ü–®œÍ2ó† V3P…§Lý™±Yì3“Žÿ?EØ endstream +çF‡Â#ÐÆ™KCbˆnf¼ž¬Ó8W&¼ßQÕ· ÊÖÑTzXPsF6uà•@Ïý±= Y1œ`‡/̘-©Þ«¾ÖlÅ(ugÕ`1$/E+}ëâñ(ÃL™^¶T(Í}/æ‘#¨|`Ͳl«æ­”9·!†Éá/ *iééœÁþwáG †ëàAoh3ùÃÀèÂ×ǻǿɒ?pÇ/lÅq¹s¿$±&ºëŽ 8ÿÅD»,aÇÔgqž²{‘Ì4ÔÑâ Ãò€/Ŷj(®A…Ü·]¹n¹,Ÿäy×âïEvX<¤é2‚|©’\>Çn†o¶ô  +sîsðm [üáÈÔY-É`~-÷¯ƒßnüþ+ÈwŸÇnX ç³AôQ öuSï×'*Ǻ¿õ‹0KC=æàOXüÕ?;ü–®œÍ2ó† V3P…§LÓ3ÿb³Øg&#þF2 Ÿendstream endobj -1442 0 obj << +1458 0 obj << /Type /Page -/Contents 1443 0 R -/Resources 1441 0 R +/Contents 1459 0 R +/Resources 1457 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1432 0 R -/Annots [ 1445 0 R ] +/Parent 1440 0 R +/Annots [ 1461 0 R ] >> endobj -1445 0 obj << +1461 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [280.2146 205.1117 375.7455 217.8489] /Subtype /Link /A << /S /GoTo /D (root_delegation_only) >> >> endobj -1444 0 obj << -/D [1442 0 R /XYZ 85.0394 794.5015 null] +1460 0 obj << +/D [1458 0 R /XYZ 85.0394 794.5015 null] >> endobj 470 0 obj << -/D [1442 0 R /XYZ 85.0394 162.5022 null] +/D [1458 0 R /XYZ 85.0394 162.5022 null] >> endobj -1446 0 obj << -/D [1442 0 R /XYZ 85.0394 137.1661 null] +1462 0 obj << +/D [1458 0 R /XYZ 85.0394 137.1661 null] >> endobj -1441 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R >> +1457 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1450 0 obj << +1466 0 obj << /Length 2962 /Filter /FlateDecode >> @@ -6049,128 +6131,128 @@ LA Ó\{½Nã8Ôˆ~šK ­ß„·Is#Ž ÓœD§¯ÇŽe9 PØgö}ˆf9‹Ÿp:”û++l¹Pñè;Ô”!´8å0l}U2ñÍÞ>*B¹¥5ê/N?fup±&H08ÓGw Å~=D—ë¹ô5·÷ôm¡œwÕL–¶¥8ÓeJ•ød¡y^šÞG‹²¥Rn ÓR7eeJN0ÇÝ]<×ÛëÜUõ;§W6¥¾šõ$Œ}qÚDP¿¤Øæ0Ç0Øîân‚|É_žm•´PiJ¿ú/*óÝøÜ\"Q5ÏìÃÌüÑsÓjc€ç§¢ÉëC¶Êë|[ì ûªœwZt}^pj=†ºh[ur¶¬ó}S,ì5›µÛóÓ}½"•6Q@ã4Pm7 ä殢­Dë¾öîI7êãc=šß ¤=+-Î}/>²ºãöø|Ô¿:èÌ(ãæØÇ¹_ -&6 ¢NMý»ÿý‘çìeð‹•Í”å0cž4»âò™_0ôO6F&ü·ÿÇ¿ 9ýl†ëßœ=uèr†!Ö(™„Éþ„$4ý—Qëendstream +&6 ¢NMý»ÿý‘çìeð‹•Í”å0cž4»âò™_0ôO6F&ü·ÿÇ¿ 9ýl†ëßœ=uèr†!Ö(©ÂŒdBšþ?—©ëƒendstream endobj -1449 0 obj << +1465 0 obj << /Type /Page -/Contents 1450 0 R -/Resources 1448 0 R +/Contents 1466 0 R +/Resources 1464 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1432 0 R -/Annots [ 1453 0 R 1454 0 R 1455 0 R 1456 0 R 1457 0 R 1458 0 R 1459 0 R 1460 0 R 1461 0 R 1462 0 R 1463 0 R 1464 0 R 1465 0 R 1466 0 R ] +/Parent 1440 0 R +/Annots [ 1469 0 R 1470 0 R 1471 0 R 1472 0 R 1473 0 R 1474 0 R 1475 0 R 1476 0 R 1477 0 R 1478 0 R 1479 0 R 1480 0 R 1481 0 R 1482 0 R ] >> endobj -1453 0 obj << +1469 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [284.2769 667.7189 352.9489 679.7785] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj -1454 0 obj << +1470 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [282.0654 636.5559 350.7374 648.6156] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj -1455 0 obj << +1471 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [311.9531 605.393 380.6251 617.4526] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj -1456 0 obj << +1472 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [299.7586 574.23 368.4306 586.2897] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj -1457 0 obj << +1473 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [292.0084 543.0671 360.6804 555.1267] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj -1458 0 obj << +1474 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [330.7921 511.9042 399.4641 523.9638] /Subtype /Link /A << /S /GoTo /D (dynamic_update_policies) >> >> endobj -1459 0 obj << +1475 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [401.5962 480.7412 470.2682 492.8008] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj -1460 0 obj << +1476 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [257.6971 315.5214 326.3691 327.581] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1461 0 obj << +1477 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [310.7975 284.3584 379.4695 296.4181] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1462 0 obj << +1478 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [308.6055 253.1955 377.2775 265.2551] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1463 0 obj << +1479 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [294.1999 222.0326 362.8719 234.0922] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1464 0 obj << +1480 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [303.0862 190.8696 371.7582 202.9292] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1465 0 obj << +1481 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [332.9347 159.7067 401.6067 171.7663] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1466 0 obj << +1482 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [301.97 128.5437 370.642 140.6034] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1451 0 obj << -/D [1449 0 R /XYZ 56.6929 794.5015 null] +1467 0 obj << +/D [1465 0 R /XYZ 56.6929 794.5015 null] >> endobj 474 0 obj << -/D [1449 0 R /XYZ 56.6929 726.6924 null] +/D [1465 0 R /XYZ 56.6929 726.6924 null] >> endobj -1452 0 obj << -/D [1449 0 R /XYZ 56.6929 700.1172 null] +1468 0 obj << +/D [1465 0 R /XYZ 56.6929 700.1172 null] >> endobj -1448 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R >> +1464 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1469 0 obj << +1485 0 obj << /Length 3111 /Filter /FlateDecode >> @@ -6182,94 +6264,95 @@ a ãlˆŠ5$Ñ9v«SÒhëOC«ý‹ý0}®K«ìÛ,M¦N$N´2·.ÖØ²~´%¿$,ù­>Ÿ`«Iì3RºV͸ëÌÝ (¶NÙ#l)]¨-‡H™„]C ØÞþçͲI°¶ãßÚeŠGˆh†Ͱâž663´¶"ÁÂJ®ÏÛvXÁÚ¯³Œ3]ŠðÚYhqÞ:]`6…ZÀñ˜WŽþðù !Ô­-»,¢„ ΔÔÈ{—ËíuÀoU¹¸ð4b¬ãÔrÆØÙœßYKf‡R›AØ4F§‹šwœ€ê9N{8n\w݇ê&² D@MhÑë6(…Uå@à>6¹PRíê­9TñëÍõ‡—C;©vp²¾ DÜÍAÕ|Oc†8å 3géi2,rÄÀrŸÂ/*8 &$÷ƒSŠaª/ú•[{HïG’tŽídpª/ûiyàx XCiiV$æ×M»»¼Òû¹„¹Í¢ÄýVÍÌ£«ûRM÷9æ°È!0A(Õ÷Á97† .ö«24í¨Ð% Ãövè¨6PèÙʰÆvwqz»Íü¹—ߤöwHT Ωoþ5z‘:y²¢.³¾Ž‚m)Ñ×›Ó”úϩ̖!óRÄI"ÌÝô1ùÅ’(ï:jø°Í?Î9ªï%%õ}ÀDU¶e¬Z`#¨b^5ϸ€šõ¹‘NRD9ãqUjB—>ñz gO™¿‰z]“F×ͰîÃ\Í“O)Äg=³côóø…·ûÇ)«²4´ Æ¨­8 A4U $¼€"t ùP1IAŒ¸âq=h¬HŸ€úl_ô5ù›&Ý®=ÃØ§oÐB‡ Ö59Ê>?jõOp/A‹èxL\‡aKqâPGÊ¥ð×AE¨çQö0³Õ'b£}2ÝX—P‚û—ëB3’÷%®]ôqãÇùüå:ã(LöLŒ]®{ü‚±ãvÿÄå:ô'[êõ€ZPdÜZ”aXÁD;¿(Á: y~yÐexôõeö2uÔ¥R•FEÐXöð K‘„÷„N†]LHf¥z­<ÀÀI:úǘ‡Çíµ:K26^MR åÑn 5†mÅ)Æõ½žXb]T„dÕ¢¶Þ4u6¦ìfX"ãâjB~Ÿh6 ÷ø<ë¶‘Ù0að„àÕ¸~:¨z–F¹æð 6Ûýã! öö\ŸD;? –µç[Šaf]8\î€"ls -îx~øO̘P+ @c©ýseФT²'öV÷´ þXRò+ÊlÎP!'œØCú9s™EÕš“WýÅÜu$d»»0wKOí=9ÕÖ•ú²J§Ý… ÔÒ›¬Pýc~2´Ûì"Òܸº)«lãΗ)P'>ñ9_®®ˆ½·Ó¿ß¾}ÿþæµMë6ŒÎÄêá Ïö­1^lêr5Jô]¶óõìeK}°_»¢ù`£b߇©\YíØ«Ub Ü¿\”É.JO¼Øô~ Åîvû7uÝa‡k–¾B ²øž²š§¯ù#ìMÓ°5m±?,€M9ч1é4ßã1Ó³쩺òo÷ϸu*ÿ¯§gþm›yZkÒ—'gòüè_Æ9ƒ3WTT{ý"Ä‘2,³Í#¶¢¹¼b3‚¤~ª²}²¹Û¬ -ÏØÌïî|8æ;Kw‘L’Áƒî%åÄk¨ä~q™ÎápÉ¡e¡Æ.×ÀjxýXºæò¤Í½ˆOÒÏØ'ÆþÝÿòkùË% ¥RÎÜ]¦ G’(á•Ò¶ŠÑ~,<««þ?çme>endstream +ÏØÌïî|8æ;Kw‘L’Áƒî%åÄk¨ä~q™ÎápÉ¡e¡Æ.×ÀjxýXºæò¤Í½ˆOÒÏØ'ÆþÝÿòkùË% ¥RÎÜ]¦ G’(á•Ò¶ +5Ô<<««þ?çÅe@endstream endobj -1468 0 obj << +1484 0 obj << /Type /Page -/Contents 1469 0 R -/Resources 1467 0 R +/Contents 1485 0 R +/Resources 1483 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1432 0 R -/Annots [ 1471 0 R 1472 0 R 1473 0 R 1474 0 R 1475 0 R 1476 0 R 1477 0 R 1478 0 R 1479 0 R 1480 0 R ] +/Parent 1497 0 R +/Annots [ 1487 0 R 1488 0 R 1489 0 R 1490 0 R 1491 0 R 1492 0 R 1493 0 R 1494 0 R 1495 0 R 1496 0 R ] >> endobj -1471 0 obj << +1487 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [259.4835 683.3704 328.1555 695.4301] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1472 0 obj << +1488 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [172.152 623.0288 267.6829 634.8294] /Subtype /Link /A << /S /GoTo /D (root_delegation_only) >> >> endobj -1473 0 obj << +1489 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [352.4539 369.6354 426.1073 381.695] /Subtype /Link /A << /S /GoTo /D (server_resource_limits) >> >> endobj -1474 0 obj << +1490 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [387.5019 339.3849 456.1739 351.4445] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1475 0 obj << +1491 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [381.9629 309.1343 450.6349 321.194] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1476 0 obj << +1492 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [398.5803 278.8838 467.2523 290.9435] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1477 0 obj << +1493 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [393.0412 248.6333 461.7132 260.693] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1478 0 obj << +1494 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [255.0796 218.3828 323.7516 230.4425] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1479 0 obj << +1495 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [311.5276 188.1323 385.1809 200.192] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj -1480 0 obj << +1496 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [315.9507 157.8818 384.6227 169.9414] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1470 0 obj << -/D [1468 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1467 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F48 950 0 R /F21 710 0 R /F41 935 0 R >> -/ProcSet [ /PDF /Text ] +1486 0 obj << +/D [1484 0 R /XYZ 85.0394 794.5015 null] >> endobj 1483 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F48 955 0 R /F21 714 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1500 0 obj << /Length 2952 /Filter /FlateDecode >> @@ -6283,142 +6366,142 @@ a Ò´d$Çv¯¯A`«„…Š¥ÇÞ£fˆÄÖÒjƒÌ!ãbæ°eˆJ¨­GEš,@0Ê RLèA¢£oƒà¦÷ZsÔ"ˆJµh¾ÎµüŒÛ±Ýë5—)Ø5K¿G͉¬¥5庘;a€Šs Óݾ¬V‡b{(šçU[ììó?'›;t{8ÅØ¾1N™’Xò$ŠÓ$‰D¦TàA'X¢`ÍM XÓ‹‹C‡D’lÈ*¡-Oó‹¬Ê2L.â H¼¨I’aîAi‘­¤®˜‚̈Ë,-¬!ê²²<ª›Ònmг=ÔûզܚH{Šj=õ EXA ”¤ãQ|‚V#!dH¨S ¤ÚV)LòP)æÍäÒF0aôg$snÅ5™,QSVsxž¬)~f b»·½ãšBA> ²t00yk#cBGösàLÌ×8²%!èµ!ÙìU™¯òöyÓB.Ve讇åÕfÂÜT¨>¸Í.J¯º¢Êgòëçº4¼ºÅ3vM×úš—»üÓεçíhKþ_]¹»]ñZìŒ"¹8¿DØüŠ!=¿¨ÄüîQÆß‹ŒõUNS™±P<Ý{šè=ÌŒ)öÇ û·©É"'Æ™1”ƒŠd‰Ìª4ÙÄÐ…dfìð3>Çv/d)S?a\±ôÈ{Ô ØZz/ÁRê9©A ¥9P7C»¶\çi¨3)OvíAqß¡Î0bÊ aço#³± c•AÞÀ1¹¬²L#©¤z™YOûY½øc,2iÖÆä ÷˜4‡±¥¤¼¨9™€í$­¯!ê²À<ê¼üŠ1Ý«m}ØÃŠU^Q‹U’„GM°Þ1¢Ê†4ÞHkÓÎŒÝ dR‚$Ê/q I–_?ãyl÷K~âCŰ%càQ3Lbk^|QÚÁ9„›„ÃáRÓJÄ!µÇ/¿=Uù¾\[~~Ùä­ âõ®\—“É!’qEm"ã~ûÉe÷ÛO¸4Ç——úКdCzô¹¶Íù"\åmùZ؆}Ñ>×›Æ>€FºëÓ!¯Úò–,«'Û°Þ•EÕ:”ÕÜʧçÖµÕ¶£—â`„c7Þ/x8v~5C8Ð1ž_†I™ÉQ\…¸®+#ǧ£Mv6¶õÓé,ö©¤ qæñwõç•íýÂædœ«…»\­Oã­©Õ‹‰ÍäÆ/ 5ñGbu7;Ö‹æÅh²¯Ó-!ÄêÆD“™ßÁPdˆj÷uöã´‡)&®ô¯KCú¬wÇM_nžG&½<þtÿÁÍ*÷L¸«*'æ iÿj4ËÜœÂùé_wôùuî¦è'Ÿä´&¨•ÞÄ<}pZ“jP-ÃÃ@p¦AÚ&Õ¥ …0„åù˸ù™­8éwWpƒñóN ˆ›º!1Ø«ÝÉ6ï‹ÜüÚp{ÜÙg«UóÂVÜØ6²a’,ÿû\Tv~•Á–&t¼„N¸9­ÂâzÏ4=ºi¼‡àmI§7Õï ¼0¾ja5@äöñ¼·ç.ƒƒÆâ`W¦ƒ}´ng—"C!öÅÏüFH¤œæn'²2ºê†eÃŒ†à˜s¥.ìˆýŽ{Z´Ò¼íõ Ø²ø37:ol»Ðìg‡om[nÝbðÏájb>QÛ\j]XX¾Ù8¿ (]æHÉê‰2ØØ4 õd?´+^s3þjó×?¹6üsÆþòÿ‹+IJìÂ(L žGÊ8¡²¸`„òŠI:AýÿD’‘Fendstream +ûlÇlãO¶Ñ77ûb h-b[¶ÀÆŽ¾¼ßZ˜•! Ϋ¨ïÂ"¬™?ŽEÓÚ—@¬ÉŸÜÛÒ‘4¿[³œDW3w•òĪ[6n‘*Û~>¬wÇM_nžG&½<þtÿÁÍ*÷L¸«*'æ iÿj4ËÜœÂùé_wôùuî¦è'Ÿä´&¨•ÞÄ<}pZ“jP-ÃÃ@p¦AÚ&Õ¥ …0„åù˸ù™­8éwWpƒñóN ˆ›º!1Ø«ÝÉ6ï‹ÜüÚp{ÜÙg«UóÂVÜØ6²a’,ÿû\Tv~•Á–&t¼„N¸9­ÂâzÏ4=ºi¼‡àmI§7Õï ¼0¾ja5@äöñ¼·ç.ƒƒÆâ`W¦ƒ}´ng—"C!öÅÏüFH¤œæn'²2ºê†eÃŒ†à˜s¥.ìˆýŽ{Z´Ò¼íõ Ø²ø37:ol»Ðìg‡om[nÝbðÏájb>QÛ\j]XX¾Ù8¿ (]æHÉê‰2ØØ4 õd?´+^s3þjó×?¹6üsÆþòÿ‹+IJìÂ(L žGÊ8‘á¸`„òŠI:AýÿC_‘?endstream endobj -1482 0 obj << +1499 0 obj << /Type /Page -/Contents 1483 0 R -/Resources 1481 0 R +/Contents 1500 0 R +/Resources 1498 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1432 0 R -/Annots [ 1485 0 R 1486 0 R 1487 0 R 1488 0 R 1489 0 R 1490 0 R 1491 0 R 1492 0 R 1493 0 R 1494 0 R 1495 0 R 1496 0 R 1497 0 R 1498 0 R 1499 0 R 1500 0 R ] +/Parent 1497 0 R +/Annots [ 1502 0 R 1503 0 R 1504 0 R 1505 0 R 1506 0 R 1507 0 R 1508 0 R 1509 0 R 1510 0 R 1511 0 R 1512 0 R 1513 0 R 1514 0 R 1515 0 R 1516 0 R 1517 0 R ] >> endobj -1485 0 obj << +1502 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [352.879 737.5325 426.5323 749.5921] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj -1486 0 obj << +1503 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [334.0699 707.2832 407.7232 719.3428] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj -1487 0 obj << +1504 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [373.9 677.0339 447.5533 689.0936] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj -1488 0 obj << +1505 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [319.6839 646.7846 393.3372 658.8443] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj -1489 0 obj << +1506 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [307.1508 616.5353 375.8228 628.595] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1490 0 obj << +1507 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [334.8268 586.2861 403.4988 598.3457] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1491 0 obj << +1508 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [337.0185 556.0368 405.6905 568.0964] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1492 0 obj << +1509 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [364.6945 525.7875 433.3665 537.8471] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1493 0 obj << +1510 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [374.6372 495.5382 443.3092 507.5979] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1494 0 obj << +1511 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [292.0276 465.2889 360.6996 477.3486] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1495 0 obj << +1512 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [319.7036 435.0397 388.3756 447.0993] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj -1496 0 obj << +1513 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [460.1655 404.7904 533.2211 416.85] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj -1497 0 obj << +1514 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [368.9978 374.5411 438.8121 386.6007] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1498 0 obj << +1515 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [293.1435 332.3366 354.3435 344.3963] /Subtype /Link /A << /S /GoTo /D (options) >> >> endobj -1499 0 obj << +1516 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [288.6803 302.0873 357.3523 314.147] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj -1500 0 obj << +1517 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [328.5503 271.8381 402.2036 283.8977] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj -1484 0 obj << -/D [1482 0 R /XYZ 56.6929 794.5015 null] +1501 0 obj << +/D [1499 0 R /XYZ 56.6929 794.5015 null] >> endobj 478 0 obj << -/D [1482 0 R /XYZ 56.6929 256.8016 null] +/D [1499 0 R /XYZ 56.6929 256.8016 null] >> endobj -1116 0 obj << -/D [1482 0 R /XYZ 56.6929 231.4888 null] +1121 0 obj << +/D [1499 0 R /XYZ 56.6929 231.4888 null] >> endobj -1481 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R >> +1498 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F48 955 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1503 0 obj << +1520 0 obj << /Length 3016 /Filter /FlateDecode >> @@ -6433,30 +6516,30 @@ k ˜ H&á}Â9Î$Dz¼øšNëIté•Sp¨–):Gñ[Ïc²{ÚÛ?Ú@?(ÒUNGO ššÅwïšÛ,$hÛÉÛõ31tÏLÑ F¹hà=’QÎÂÛ×t?¾$,,­ö ³eº½+º‘K]Úð àˆu÷áy{‹(RÜû.ê‡ÂÅ@¬)dr.x0Ú¼rú ih¢›(Ýà^4Ù&bÅJŒ¬ Ö¢@tQ Æ Ù”ŠÀÑdF[¡¼;‹•õ=BÂ{ƵÔ?B½ùQR†ykÌwlf쇰,ÑN‚wYkuÈÕØEÐà~u›CÙ§lœÙuÙ”¥PËÖïV–ünl ~7Vú~7¶týn•¸6FÔnÝn¼K‘ªìDÝ5ˆZ6QË&´”ü82‚[ðwGÄDŒL‡‚8ðCóh4[ÆC9Tº¢>ÇÎF?<[<6Éñ$›{ñ¨”k.Þ€ÿ˜ßãJ Y3ßn¨HìvC±ç!¢®‰ˆmÜ.lŠŠí†b{B´/»†lkŒ”Ô”Æz1‚®4wDD&Àh%j× MŒ’{N b^uðä •<:yÀoùÏï‹2&y(W¢kæ‘r÷›p:!úž—:¾³UP6>vÒ°†²?v_@hÎŒñæ(ÅhÔü®b¬Ñ[Åô}]ˆ‚yïÁÓD‚G/än u›2«6n¬Æ²¬jjÙT„À}‹wßbQ>D cZcQ‘RÌmÉñj÷-a». 𚌟W–`ÞÀºâRÍóF3" £)ØíŠ;áU‡vwЀ™Š—½²!1URõ66mVÐN -fÔ¸ÝÇ É¸oIOç ÐPÇ€—0Ä(Uû/ ª“»êîwb™ç7’9­È‘þÓà–›„q£Á0 NDzyòK›,GUgë¼úD|ý·ŒÆÝ¦U¶ß2wMÞóÌèÿÔÙTƒ8~ÈÙÁ|‚O&]MÛ{“n“èË|‘®©Ð>°¡†%ÊË pà¶ÉÇìë4[Õ´@SªÉÖ=ŽK—wCá¬ð¨ÿïµtd¦-rb6™ÓÙÆJO@¥³ÿÇq‰~µæöT †O||®"Í3„Å»žÞ”-Vðc+àì£b%aw°h¬`­,ßâ¢Ô„ž!ÔLÄÕ·ãO€µ6ZÌ”îü(¤€[À$7ßC3Ny"Ú2L«> éãNÊEõ‘rŽw,úeÍ›[pÒ|ÜAlž§_2ªÝfäúA\‘±÷KžRåæå;ª„_à |F-ñ«{|¿þ ®Tjû`‹wô@³¤/rêÁËñ—(iÝ»|Ge:›Ñµ^UÔ!{² c¯£éóW¯®Ùùõ»ÓD†Ÿ7  *bŒqùÎv»âiµJ§Í“ýÐ{pêóxÐv½ƒCh•B3gà–àtzcÍ1Ù<)ÃËØ›—s–Y<:Ç£”f<ºN[ö&\J0äºûó£VµpV!¤7BФï«@†Ã÷¼±=oÁ'ãø/Ç”D¸Ã#¨Ö‰ þÁèó(xýÁíç½zw«†Ððâr)G¯JjÔ•«¡<é’rëd,s‰Ð#á% ã:0}Yã/ÉÂã#”Á3,×YÈÅ 9Ä®UYUùí©äc´ÎØ‚ŲZ•dÞ—ñ÷ Òy:mX©äöV§Â<Îkå™×Àzwož¹ß€,0M¶¿I{¥ƒâ PÔøC¶äXN —¦“Í1€És‘ ýtŽšsøìêmÅá£ò^ÿü{:Ì-2.Ùݶö'}Ͱóÿ*HÞendstream +fÔ¸ÝÇ É¸oIOç ÐPÇ€—0Ä(Uû/ ª“»êîwb™ç7’9­È‘þÓà–›„q£Á0 NDzyòK›,GUgë¼úD|ý·ŒÆÝ¦U¶ß2wMÞóÌèÿÔÙTƒ8~ÈÙÁ|‚O&]MÛ{“n“èË|‘®©Ð>°¡†%ÊË pà¶ÉÇìë4[Õ´@SªÉÖ=ŽK—wCá¬ð¨ÿïµtd¦-rb6™ÓÙÆJO@¥³ÿÇq‰~µæöT †O||®"Í3„Å»žÞ”-Vðc+àì£b%aw°h¬`­,ßâ¢Ô„ž!ÔLÄÕ·ãO€µ6ZÌ”îü(¤€[À$7ßC3Ny"Ú2L«> éãNÊEõ‘rŽw,úeÍ›[pÒ|ÜAlž§_2ªÝfäúA\‘±÷KžRåæå;ª„_à |F-ñ«{|¿þ ®Tjû`‹wô@³¤/rêÁËñ—(iÝ»|Ge:›Ñµ^UÔ!{² c¯£éóW¯®Ùùõ»ÓD†Ÿ7  *bŒqùÎv»âiµJ§Í“ýÐ{pêóxÐv½ƒCh•B3gà–àtzcÍ1Ù<)ÃËØ›—s–Y<:Ç£”f<ºN[ö&\J0äºûó£VµpV!¤7BФï«@†Ã÷¼±=oÁ'ãø/Ç”D¸Ã#¨Ö‰ þÁèó(xýÁíç½zw«†Ððâr)G¯JjÔ•«¡<é’rëd,s‰Ð#á% ã:0}Yã/ÉÂã#”Á3,×YÈÅ 9Ä®UYUùí©äc´ÎØ‚ŲZ•dÞ—ñ÷ Òy:mX©äöV§Â<Îkå™×Àzwož¹ß€,0M¶¿I{¥ƒâ PÔøC¶äXN —¦“Í1€És‘ ýtŽšsøìêmÅá£ò^ÿü{:Ì-2^ìn[û“¾fX‡ùÿ)×endstream endobj -1502 0 obj << +1519 0 obj << /Type /Page -/Contents 1503 0 R -/Resources 1501 0 R +/Contents 1520 0 R +/Resources 1518 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1507 0 R +/Parent 1497 0 R >> endobj -1504 0 obj << -/D [1502 0 R /XYZ 85.0394 794.5015 null] +1521 0 obj << +/D [1519 0 R /XYZ 85.0394 794.5015 null] >> endobj -1505 0 obj << -/D [1502 0 R /XYZ 85.0394 512.9872 null] +1522 0 obj << +/D [1519 0 R /XYZ 85.0394 512.9872 null] >> endobj -1506 0 obj << -/D [1502 0 R /XYZ 85.0394 501.0321 null] +1523 0 obj << +/D [1519 0 R /XYZ 85.0394 501.0321 null] >> endobj -1501 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R /F48 950 0 R /F62 1060 0 R >> -/XObject << /Im2 1049 0 R >> +1518 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R /F48 955 0 R /F62 1065 0 R >> +/XObject << /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1510 0 obj << +1526 0 obj << /Length 2779 /Filter /FlateDecode >> @@ -6470,69 +6553,69 @@ lP ølZO誻Æ’'9;&kË'ì¤ç¡5îìæÞñJ»Ž×##ÕÛ5g¶dÐp=¢µA~p‹Í±s¢:]}AÁG†F Þƒ€ô-D:Ì¢Y»"&‹»vãSÇhåj[÷ÕºöË®¤× Öv³ªzòXx¥Œ„­ûjUýîQà8·4aç?6pÚ/úýÑÜâþ^ýç³ù®ÃÇ•}¶ØÜxfR'o†¸ ¸ézFÖ¸¶öiŒå«¸„—$X1ÓäæÎ·w³Q…=ðOÇ KìÃ}ñ¼×þÊÃßpAõ­™P2å)K2½'ÒA©˜^“#‡zXk½/‡O9{ÏvËPý•Ïìú¬’ —1y’¿¬†ë5AvCI|óHɤf¿{˜‡¬ä‚SþISŒK!‡œ2*É|ûÇÁµC¸Ð“Ðå¥Y®ÿW]æ(À|EëìW<{K)ÓŒi©ž±H¸¥”Z0Iá }h‚/SÀ„"ÛÙáiëG£Œ’»a¨%fþ"¹êB1½mÊÃû 1Ä û6쮤bæÅ+çƒ-ÊçuŠ×0B‰Wtš&ÓÄP…ê|2Õ‰NãSԞѱm-]*š4zzSõ4q_Ô[KC†a×Lva*𸭑ÇùÄxŠlB«¹"Eíe±§N³ß˼`¨‘Þ¦Õ¡’Œå’ÍÝVXñ¬¡ÄçÜÈ×À/SèϺĜϿ;¥†{Èg Îje§%E<­«{OtºÎ‚®³ Îˆâ¯¨´»hr ôª¤78ð ûÎ9ò5Ï›kÛT.þ)ªMñÙµšÒ%ü$´u@®<ÛzS­ŠMå.UàuÛYÏpã){Å‘\›s¬PXZ\¤¡Éƒ*ÚÒ -B•H¯/¼ßEâ`Ôºáë’näy\·®Ò®6¥M¾ nŽÖ–î³e¨3nÛqÈ©Â-Ö²ÝÖå~-RVÝ¢ðué  £åmü[£€XmrùJôYÆRé¯5´k@¹?f~òQø1»ð“áÇ<é­p®  ª·Û¾]´5Qn‹âíˆEè|ïØõE"Ï“|>Þö‹TñW…¡¿Ãb*gïm^¶Xª˜ŠÂÐìý´ŠÿⵂN|˜Ëc-!PË¢/À3žî8©I¤±kÅráï$ü¹æ ž”Jp„÷#áNä™Ì±²}bw£ë”¡—pÍÛ Æiå¯2ÞÿÍïmÿgéç~'pzå,5Iþòjf-÷«âÛç®"Ã-»GQf´IŽçÊÿ@WÆG~&P3„ö\Á%! Te¨çºç hˆ8‰ÉÍŸ×þî$@KɸNócMBLyóßìþž¹Êsy܃½ø«RÌr~ð§`L©ôŽm$ü>s †endstream +B•H¯/¼ßEâ`Ôºáë’näy\·®Ò®6¥M¾ nŽÖ–î³e¨3nÛqÈ©Â-Ö²ÝÖå~-RVÝ¢ðué  £åmü[£€XmrùJôYÆRé¯5´k@¹?f~òQø1»ð“áÇ<é­p®  ª·Û¾]´5Qn‹âíˆEè|ïØõE"Ï“|>Þö‹TñW…¡¿Ãb*gïm^¶Xª˜ŠÂÐìý´ŠÿⵂN|˜Ëc-!PË¢/À3žî8©I¤±kÅráï$ü¹æ ž”Jp„÷#áNä™Ì±²}bw£ë”¡—pÍÛ Æiå¯2ÞÿÍïmÿgéç~'pzå,5Iþòjf-÷«âÛç®"Ã-»GQf´IŽçÊÿ@WÆG~&P3„ö\Á%! Te¨çºç hˆ8‰ÉÍŸ×þî$@KɸNócMBLyóßìþž¹Êsy܃½ø«RÌryð§`L©ôŽm$ü>Í ˆendstream endobj -1509 0 obj << +1525 0 obj << /Type /Page -/Contents 1510 0 R -/Resources 1508 0 R +/Contents 1526 0 R +/Resources 1524 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1507 0 R -/Annots [ 1514 0 R 1515 0 R ] +/Parent 1497 0 R +/Annots [ 1530 0 R 1531 0 R ] >> endobj -1514 0 obj << +1530 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [312.8189 298.8688 386.4723 310.9284] /Subtype /Link /A << /S /GoTo /D (the_sortlist_statement) >> >> endobj -1515 0 obj << +1531 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [406.3277 298.8688 479.981 310.9284] /Subtype /Link /A << /S /GoTo /D (rrset_ordering) >> >> endobj -1511 0 obj << -/D [1509 0 R /XYZ 56.6929 794.5015 null] +1527 0 obj << +/D [1525 0 R /XYZ 56.6929 794.5015 null] >> endobj 482 0 obj << -/D [1509 0 R /XYZ 56.6929 509.1791 null] +/D [1525 0 R /XYZ 56.6929 509.1791 null] >> endobj -1512 0 obj << -/D [1509 0 R /XYZ 56.6929 477.0735 null] +1528 0 obj << +/D [1525 0 R /XYZ 56.6929 477.0735 null] >> endobj 486 0 obj << -/D [1509 0 R /XYZ 56.6929 477.0735 null] +/D [1525 0 R /XYZ 56.6929 477.0735 null] >> endobj -964 0 obj << -/D [1509 0 R /XYZ 56.6929 447.2177 null] +969 0 obj << +/D [1525 0 R /XYZ 56.6929 447.2177 null] >> endobj 490 0 obj << -/D [1509 0 R /XYZ 56.6929 390.5598 null] +/D [1525 0 R /XYZ 56.6929 390.5598 null] >> endobj -1513 0 obj << -/D [1509 0 R /XYZ 56.6929 368.2486 null] +1529 0 obj << +/D [1525 0 R /XYZ 56.6929 368.2486 null] >> endobj -1516 0 obj << -/D [1509 0 R /XYZ 56.6929 281.9323 null] +1532 0 obj << +/D [1525 0 R /XYZ 56.6929 281.9323 null] >> endobj -1517 0 obj << -/D [1509 0 R /XYZ 56.6929 269.9771 null] +1533 0 obj << +/D [1525 0 R /XYZ 56.6929 269.9771 null] >> endobj -1518 0 obj << -/D [1509 0 R /XYZ 56.6929 89.8526 null] +1534 0 obj << +/D [1525 0 R /XYZ 56.6929 89.8526 null] >> endobj -1519 0 obj << -/D [1509 0 R /XYZ 56.6929 77.8974 null] +1535 0 obj << +/D [1525 0 R /XYZ 56.6929 77.8974 null] >> endobj -1508 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F62 1060 0 R /F53 1027 0 R /F21 710 0 R /F39 895 0 R >> -/XObject << /Im2 1049 0 R >> +1524 0 obj << +/Font << /F37 803 0 R /F41 940 0 R /F23 738 0 R /F62 1065 0 R /F53 1032 0 R /F21 714 0 R /F39 900 0 R >> +/XObject << /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1522 0 obj << +1538 0 obj << /Length 2893 /Filter /FlateDecode >> @@ -6551,23 +6634,23 @@ a ¦JI$áû œÝ$âgÇ$†l"Ÿ’T{;Ý‘³×‡ÞØ¡)z€2„#©êa„¥Cn”C½Þ‘ûÂÝÌ×KœˆîÓé2ˆܦŃ_tŽûªGY´'·Áýu1ÅV“ðô‘®4YèFÇù¨ õ ‘?n›G@¤‰gîæ’XxÑÉ|Û’ûŠ®o°ž!E­å]ìWÂv5±1E×áÑùÕz†„fÍ©Õ3‰ÀîÀÑ~½w|È y|Kwz¹N˜Ð@kÈ 'Ǿ6äjZ®=dþÚ0gºõŸÀ¶ÇKJ$¾Üï;Lr< ínÓŠ¤‹‹Ð5ì @ÚõÑIñ0CkY§ ù'ƒš”.x›’N6­Dä#Û=î´Ï™a”¢"!û™—ÕæxOd%,&â‘‹%ÆŽBëÝàîÞ ¤‹ ºVs¿SB"»úÆF­]-)¼ÛÒÐtõ“ê?u²@Dì…çd;‹›mߨ×Aì”­³/Yu­.,¤eœ»®Ãf LIÈäµ +°©ú¿¿;Ö²ñað¥ÆT¿¯熋’×T±»£»!¤L M’‡×åÁ(^®a‚÷0Áò©I,€ñd³å]¶Hñ蔾gV¼à½#V^4oÚqq7_RI*z7‰‘®Ï³Y‰ê èýÀ`—Qá]EòúÛUÑ$0”É.²þLšÕgë¤LÃ0£­Õ¯¼«<õ¶M,€dµ#µÙëî›V—Œ']O 3 ?² -燉ŒŽ.޾Á°¶ 6„»l xͰþã%o6( ª;‚LŸIl ÁÛýD·°ÞëŒjó7÷°ýIGÓp‹s ¨g†ýS¯0|Y4ç,–Öá·…ÌÚ'?\ç½NêþÜÏäWÿU²rn ³TÀLbܧáXˆº›hàWXÆÉ¦UkêÿÈ:0çendstream +燉ŒŽ.޾Á°¶ 6„»l xͰþã%o6( ª;‚LŸIl ÁÛýD·°ÞëŒjó7÷°ýIGÓp‹s ¨g†ýS¯0|Y4ç,–Öá·…ÌÚ'?\ç½NêþÜÏäWÿU²rn ³TÀLbܧáXˆºS›hàWXÆÉ¦UkêÿÈ’0éendstream endobj -1521 0 obj << +1537 0 obj << /Type /Page -/Contents 1522 0 R -/Resources 1520 0 R +/Contents 1538 0 R +/Resources 1536 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1507 0 R +/Parent 1497 0 R >> endobj -1523 0 obj << -/D [1521 0 R /XYZ 85.0394 794.5015 null] +1539 0 obj << +/D [1537 0 R /XYZ 85.0394 794.5015 null] >> endobj -1520 0 obj << -/Font << /F37 799 0 R /F23 734 0 R >> +1536 0 obj << +/Font << /F37 803 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1526 0 obj << +1542 0 obj << /Length 3252 /Filter /FlateDecode >> @@ -6581,86 +6664,92 @@ x …,‚ ‡ …BÁá)‰Ž·Ï0ëq•æ7±PÌÖî³iM€j¼ð=SBYÑFDzÍAhÚÇ>cÌ3.wÃÂã˜ÂºòƒþppÚ}Õ7ìUe" ¶9bàCH…¼•aÈÍ%j±èj± ”×ö™‡ü@øVW™I‡¾©ËbòHðå2kd¡YtC(D¥A ÝŸ1L‹{mFCÐT¸ žµWû9×!É[f\gGì/¨‘E‚¡Ûa? ½aòÉÍøUDŒkcß"å=hcÞú\¡o5àÊ?b£Ñ‹ûbbªÐB×±¬Í~¥ùý—[k‘GsŒXñŒêà çR†±#FOB‡½Û÷—7•@”¹†Æ´©È{H©);"6‹[Ø3_ŽË¢É©;%Üz”•fc×gýø]CX4³ÕücªóEQµÏÕ8°•] ½#ÝaŸ¿¤›±Ÿ‘Bø<„ý0#!›R’“±™úd±Ã¨ŸpOi‰6"­Í3{nÁê°ÇéïÛ^ùu @BB6}˜Š\úJÅ‘3@EL˜7ŒVÈCg´|È‹IŽ`dí"­ýBpe¿p„³_§ûE¼Yâr&³aÙí¯£›>ã‰wJm›¦àˆ®"¸YÎçõ¢u¼}_4-„Lör°Cš7ìz„‰ðH^ŸÄ1Ñò1hco¨;Õeç}” Â"ÉV>¶7`ø¶âH÷e_Š'ëû•c68'â­ ›ÿo–;·)bà„¸~o^ô<¹ð ì„p¯ €¨jÛÝm”€L$à¡5&@ßÕeY?`ÎtþþR$™‘„S* Ûá”I™"‹iÜÆ<ñ¹ŽÐ8ί,iS“O›èöÕ*éÊíAœ 5«ÖxK@ݧe±%$­{Hÿ±-#+h¬¢CÙ×ër4xw'÷“ >¢æ‚™â!©ÚÕuáýЊñWx³š|@Á:Û¼”Ûz…zAYä‘DIÒ…J 1ÎßãýØ®ó<­ Áé:3…pûÃ^ðBðLö°nëI]fbëR­±Yš·ÔñëÕˆF>Aò À¬È@ÍàPE˜v¢C&¨t+Hª08ò•»¢ö|¹˜×ÆWàBM îXo·¿kvFÆË¢l+/ ~X/œÒu+ê€Àä½±¾VûSÿ”¬[‡ô1pì YX«é>Vw˜˜ù±`vì~‘ìðú Wà¸d>³7ðûE„Ãb›¾‡8*b ?ï5)CÒ*i.uÁÌoÑ?^%yÔÈô½.ë9•H]ÊÆF$MΠÍTþƒ•Ö½Bx"[a=/äÊ»Â|/¶1äN"c®!Óäë›isÞMZ¡ß%­ÐwŸ.ŠziWj›•ÙVϬ7À²â8mVö4܃Ó,\ïÔ–°ça²èß*Ó55=A÷‹W‡q/%_o%¤èý•|fHÁ$½X>R°„ùJˆhR°Aö‹ í½3V…Ûy×êÊ¢f󲘭©á*o‘Úkmnâw;¥ÊÜH`Ã!‘ÁÓZ@lÙ;p³¸›nw}.k»²þ’¶Úî9K«Ç],йQÉ ÚüÞV•–”ÅKs8‚ZÒM㌭lžRй= PÞrâ èÍj;?·S;;ãMý)}•a¯‹¥7É)Q!}ƒ8xkXòŽU™0\2i8²ãåè˜ÑUdæ».¹!eC¨uL&]=`õ¡Ï¼/ÆØ@;ש©'â ¬5á‡+xf)(^´ðhô‹K4Φƒ8½°›Mð¶iÍg-Ø&ºÀ€ÔT@Ì ÝZD i>ÞÁ!h]R¼ÁÝaTH4PíñpÃwôþÙól$‹øvm³`VZ»8Õ…¶«¾Ý1îXaÑ–¹Ç_OAb¿& •ÓÌtJÌÀ’·‘âØ}É aL‰½Ì¨a4*6E'3º˜Ùáe1+ZBc ϼ~°}5íB¾1æ“#hOR;vl—ù¬çv•¢ÚØi’Nrü„$‚j”»cЮ;Ä-«M12¶_N‰ôx>GBœq'ˆ²Åð ÷šºÐD°aÇx¸ÖöÙÅÓ²±K!%2B‚ :źµ»!‚Þ±Û˜¨ëxxgY™[60oŽåñÂ%r—×2«$Ò ³_Ë‘ÃßË*TãoÑÌáì×Sø\­‘f`ê@ Às•XS76"è!×+¼^F8ºÊ^Áµ”˜ƒ®üžåN›ÐñQ ÃS7‘@`¬éiÃIÅle“yxàYñU» ¤Ÿ‰^g´HQáñ•Ž[¯¶!ÀFÙy1¦÷É:Ö62Ë)ÈÛBÛ‘F#áé²™]ï6× ›T«4ËéT768!í'H7vŠPcçõ²´±ÏØvSŒÃŸážMgÉ}që‡ðS…G» -ñ±;,%ñØÀvŸê_WvnJ0øÕt§m#…å‰=Ò»cr‚îM*·Yb%€'“ˆ¦Ù’n]á5±¡^g{˜NgÒ‘lÕÊ”ãÕ¢²åÂ:pbåѺ§[Æ£.ÿp‰WãŠEãtòÙ³]á,72Ûe.÷i¹|RéØ´á´¹¿ï#^U&Áv}sôŽ&÷ÏýÂwý•³Œ}¡Ôž;  ‰Õ©zŠ?9;Do\D|×áÿîÐMendstream +ñ±;,%ñØÀvŸê_WvnJ0øÕt§m#…å‰=Ò»cr‚îM*·Yb%€'“ˆ¦Ù’n]á5±¡^g{˜NgÒ‘lÕÊ”ãÕ¢²åÂ:pbåѺ§[Æ£.ÿp‰WãŠEãtòÙ³]á,72Ûe.÷i¹|RéØ´á´¹¿ï#^U&Áv}sôŽ&÷ÏýÂwý•³Œ}¡Ôž;  ‰Õ©zJ>9;Do\D|×áÿHÐOendstream endobj -1525 0 obj << +1541 0 obj << /Type /Page -/Contents 1526 0 R -/Resources 1524 0 R +/Contents 1542 0 R +/Resources 1540 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1507 0 R +/Parent 1497 0 R >> endobj -1527 0 obj << -/D [1525 0 R /XYZ 56.6929 794.5015 null] +1543 0 obj << +/D [1541 0 R /XYZ 56.6929 794.5015 null] >> endobj -1528 0 obj << -/D [1525 0 R /XYZ 56.6929 337.2163 null] +1544 0 obj << +/D [1541 0 R /XYZ 56.6929 337.2163 null] >> endobj -1529 0 obj << -/D [1525 0 R /XYZ 56.6929 325.2611 null] +1545 0 obj << +/D [1541 0 R /XYZ 56.6929 325.2611 null] >> endobj -1524 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R >> +1540 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1532 0 obj << +1548 0 obj << /Length 2932 /Filter /FlateDecode >> stream -xÚÍ]sã¸í=¿ÂÎL¬Šúê[6›\ss—ÝfsÞÞƒlѱº²ä³äxýï  L;rv{—¶;™‰@AAÐbŸ¥QªL’LQ(¢ÑlyŽ¡ï‡3Á4G4ñ©Þ<œýåF%£,Èbæ¯4ÓTŒŠ_ÇW»|ÿp}>‘Q8ŽƒóI‡ã7·wo “ÑçêÝÝÍí¿Ü_ž'züpûîŽÐ÷×7×÷×wW×ç¡t$bÿ|wwMD7·?]ŸÿöðãÙõC/²¿,*”÷÷³_ G¬îdz0PY¶Ð‘er´<Ó‘ -"­”ÃTgÎþÞ3ôzíÐ!5E* ¢T&z’jHOQÄ -ºPO Ë…y—TÖøãÎuÝ¿%ýà¿KBµfÖ•MMfÎt÷-,[BÌòõº45rFò,³f9-ëÜq=Ä®wé˜iæÔø}cê®ÚnÓZÑ#¾Ÿ¤Ô«¦¬;³n&l×з…­yJRfÄÊD"'ÍÛ»V\0ŽðŒÂ+Áî‹' þ†!h^16_ºM^óeµ6mKʋؙ€˜«CæR™Ú2';eÒS4^ѧ=ØÕg‚–½až7ë%AÔ뼫|öÙt<ƒ• ¾}/,Ÿèi¢¦kfMuq>Q¡bCß\›V]í^ÒŠ1à‹òqa‡ÆÙØÔ³¦ gÌœüI8Þ.LM¸¶kˆ/Ó”ŒÏ郮CCZ³~²–lÃ_–¨©°ö „ 'ãÛš†ð^)¾äËUe}Z¬„§²8žôþæŠFBчk#ÉQi¤ÞU†ÁrYV ;Û@¯´ßEÞ!$ØŸ‡“àw™·aúOa(­\ØØæ ¶Ù#=æ`*1nÍÖMÊ"Í0QÝ17ôü‚‚~t[ýЀ²2 Ú)ïÀ?¤ŒÆË¦…¥H˜š‘·x½°Lò¿‘÷÷·Ü“ÇQ§æ±¬™å¶ìtVyýÕÆéxk Ï\2‹¼m7Kðu‘qjŽ‚`K{É ­ä¦~(ë‰y·?•ͦuQ. à JK ³Õqdoæ©],žU›ÂõyÃÁš¨ó"Ÿ–UÙíl¬´ÜMSUÍÖ÷699¤ØôDzx¼e|U¢¿><ütÁ¨ÝÊ0½{ˆ›U Læ9?i׌ÀÕž¨ˆÌ‚M~4pY›eS—³vÈB…Á}_÷gô´y²›#vÑŽX™ƒþ æcöö#¹ÚxÞôz÷³’ !œÊT®C -xî%o?5¥“ -2…Ç šæ ?͆;ÅµÓ DZ†ÒN¹îUb›{FQ¶ÿÂ#Ùª?DÅKo-U²Ÿ„V­Ú› [é¹UÛ|Ç0Ö¡RBÍÁènï|©O® Ü—ÌÀS^m¾¶šeÙuý ÓgéRŠþdÊ[lÖC‡\×îTq}bã$~ÈÓý)¹±ÀŒ±.õÔ|šêç§ö3NÍQÏ©ÜÓw¿nh`èä.Fø¹n¶•)Í V`¹rfó¬^`/ß Óaø¤:Ò.kP7Ž”U~A­-[BÒ±NÔ®tôE~r홋³NHrÛü±±=¾§% ÷¥Q&pg’ò[n**ƒ8–ÑáMår‚xJ<) ƒnÄ!«I¿¨‰Î¢@€²Ý5Hû™¶PIFQ6Òp_L„Š­Mn?Ü×om«4ÿüñ|’¨DBúHÁÿq}w}ôdG -Õ™­Ò‘7õŸ[ ê <𿣟n‰H‡$uH gžNã ‰Rº4<×ÈåÇ^§ÕáÍôªú¯ªîZ"þªÃ$:HCEçC‡À\ÜbU’¡Žddˆ$OkÆ›ó;ö”|!ö* -'<%–AªùîÚ+&D/èÀãþë@' -cõ5ïˆÂ ÍdFÞáoHò|ßIA-29­oÂïxÓ¨(P‘_s [A%é¡k¸ý¡N+ÁcÿJJØ×ÐþGH`A:ËF*‚09,æ=+êýƒTf èŽè4Ñò增J³}Çæ[J*´•Ô”4 b‘?q&ñ¶ë0Õ®>ÕÂÆvQÎD -ä¶´ÙvØŠ´GìñdZv„ª7Ë©-<·—&[AªéΤúÒva}ååB^^œˆµG¹½õxù\­ë‚rANnߟàA†ÃJVò£”JIZ_Ÿ צ{Æò…ì7âÛÕAæ·ÏòXš¶üÒ/Í¥…tEGñ¶ÍѺà&Ÿ-ŽoÏ$Ó©èà÷\t(!5æy2)ã àˆ’äÛvXö‡vXö¿J&Ý¢&JÀ et*ü+Sþ•À*|FGàÇÁOW‚Ÿo8©„Lw:Ìœ`›ÅÙð$À?­ŸÁ‚'Aî?³×> ÷ -UêäÄ)#‰6 AH‹•Êø}Æ×…ïU…X89ÂÓJñ¦{%¥ü''Ãëû­H2ÈžðdP2H2‘}ãÉ kÅÙË'lÛ Y̱¨l_Ž@}ñšÙÇJz]8܉ „‡¾?ðW‚8“_œŠ`w‹rŽRÌ«¬ö5·ö!¥?/æ –( -RPâDCªâ½§¸×”·e;Û ¼àai£«™5ëâÔ;J$Šwù¥-ÃÉqaÚÙºœÚ3 g\DSÙ>î"žž xLÿØ@}eMç»ÐŸ3]Þ- £¨4¨Š)ØKØWÕZ+‡`õú£é\( òágkSÂZAÙZ[WÎ6öuÁ¶Kc«7Šßí”8\‚:m6h-:.® ` )á^VúF!'–% ក°ÀtAõ±)±†Á TQ»¬•Á’$?MÛÁ ß²„³$À·¥-|aò"ðícGhû¬!ìÛ™e•'¤cˆU'l¢œØÎÝ—îVÖ'³ÊË5!‰…²Õ!4ŽLyï+ÐK*A4 -êcljÒše`©dþÊ<åv§h[]Û,Qk:â¢! Þº ÍIö4ÖA(Ñš¶¦•+ij}dj@ØÄ ¾ S­˜Í®í̲e äKKz€ÀÉè]ASÑmÀïùÝÞÅ*QûÄ‚ŸJT_œPàGÎOȾ&¨Tÿ5¯¢d -¡u¦?Å—NÅî_Æ©ðG‘bÏAR[¹D¨]¡f¥­qó Ö˜ŠKáÏÅc"'%}Vë²±ÅTBÖ…ë*Þ;‡Ñ gÏöð$éçñÒ±¿Î–ú;Gè¿çA“xÆ}ê(»z=õ mK´yæ^u¦@ŸN„sS¼À&pZw_À‚;*pÍõð˜±TƧtóšl0ĶW•O]õ=£÷%ŠšcXº¶‚’‡Ï &PHJÇkÐv³¬\Û›?…(ÃŒ] ·swü¥Oݲ½æ‡‚Q/qÚÇðUSü”Ñ?–§zLJGº„*û^Íü‘ÂwnÅ4óœ ¸eå³Ï<®á¯cY›/Ì£"Amàî^h^¿áø}ïB8„ìÔyÑ ù$…cjtÓ”2'Þ*Ÿ¶Mµé µ–&¯©(4Ÿ¤L ’:ò^Q2;ŽkŸx+&tJÄk«›Ô.©øGÚó½gå ì¤ò½ßšèx{ø‰Šü]ÎÀrÂÑWsìoýùÏþ'PXJÓE€>%d¡Ðé³ÒJÿ;¡ç¢ÿ6³.ùendstream +xÚÍ]sã¸í=¿ÂÎL¬Šú`ß²Ùäš›»ì6›ëìôödKŽÕ•%Ÿ%Çë_€eÚ‘³Û»´ÝÉL‚  ‚£þÄ(‚P=JŒ¢PD£Ùò,=Bßg‚i&ŽhâS½y8ûËJF&0±ŒGsW„i*Fù¯ã«¿]¾¸¾?ŸÈ(ÇÁù$ŠÃñ›Û»·„1ô¹zwwsûÃ/÷—ç‰?ܾ»#ôýõÍõýõÝÕõùD(I` ˜Å?ßÝ]ÑÍíO×ç¿=üxvýЋì/K„ +åýýì×ßÂQ«ûñ, ”I£Ña Œ‘£å™ŽTi¥¦:ûpö÷ž¡×k‡©)Ri¥2ГTCzŠL+èB==, +X,,ϺŒ ²Æ¯w®ëþ-éÿ]ª-f]ÙÔÔhæLwßÒȲ%Ä,[¯Ë"§FÆHžeÖ,§e9.¢ç‚ØõާéÖeýèÖÌ)o–™²Î–E @!EÒ[Yä‘lÉ ÌÖç"3Íœ¿oŠº«v„Û´VôˆE‡ï')õª)ë®X·¶kèÛ€ÂÖ<%)3be"‘“æíÝ+.GxÆá• +„`÷E‡ÿ Ã4/„_ºMV—âËj]´-)/bDdb®™K-´eNv2ÒS4^ѧ=ØÕAK‚Þ0Ï›õ’ êuÞˆU6û\t<ƒ• ¾}/,Ÿèi¢¦kfMuq>Q¡bCß\›V]í^ÒŠ1à‹òqa‡Æf\Ô³&'g4Nþ$oEM¸¶kˆ/Ó”ŒÏ胮CCÚbýd- ؆¿,QSaì*NÆ·5 á½R|É–«Êú ´X Oe~<éýÍ„0¢/×F.’¡Ò$H½« +ËeYîl½Ò~Y‡`FN‚ßeÖvÓ +CiåÂÆ6c a›Ýñ8ÒS^L%Æí¢ÙºIY¤Y&ª;æ†Þ€_p@ÐŽc«P¶CD;eø‡”ÑxÙ´° S“ ãy +|pþš@»/Ù{ ŠT¡ª².,C=ΪnÑlÔ²–õÆ…$†¤-ÞD`¶¶Þ´âi7È;˜¬´~\J£dêG\–ËÖû”segFHŽË'ò¯–Iþ70òþ> à–{2âã8ªñ´x,kf¹-»…GUVFõ€q:ÞÃ3—Ì"kÛÍK—Rô'ÓPÞb³:äºöp§‚Œë'ñCžîOÉfŒu©§æÓT?Ï8µŸqjŽzNÝ8àž¾ûuCC'p1ÀÏu³­Šü±8Á +,WÎlžÕ ìåt: ŸTGÃe ªãÆ‘²Ê/¨µåqKHZ8Ò‰zÀ•޾ÈO®=sqÖ In›=ö!ö¯Ç÷¡D á¾4ŠÂîLR~ËMEÅaÇ2:¼©ü±QNO‰'% q!ðbÐ8d5é5Ñ& +(Û]ƒ´Ÿi •i™‘†ûb"Tlmrûá6¸~û lÃX¥áøçç“D%Ò/À@ +þë»ëûË ';R¨6"H´JGÞÔn5¨7ðÀÿŽ~R¸]$"VÔ&Î<ÆA¥tix®‘˽>N«Ã›éUõ!^U ܵDüU‡It†Š.·¹:¸ ĪĠŽd˜D’§5ãÍù{J¾{…žË Õ|wí•“€¢tàqÿŽu “@…±úšwDaiÈ;üÍIžï )¨E&§ÕâMøo*òk®¡`+¨$=t ·?Ôi%xì_I ûÚÿ㨠,H3‚P„Éa1ïYQì¤Ò$ g8¢ÓDË—‹z*5ûÍ·”T6h+©)i@Ä"{â.Lâm×aª…]}ª…í¢œ-ˆ.Èmi³?ì°7i/ŽØ)âÉ´ìUo–S[xn/M¶‚TÓ7Hõ¥9ìÂúÊË…¼,Ï9kr!{ëñò¸Z×9傜 ݾ?Áƒ* ‡•<¬dG)•’´¾>®‹î˲߈oW™ß>ËciÚòK¿4—ÒÅÛ6Gëv‚Ùlq|{&™NÕ@/¸¨€ä + C iQ?ß>pR ;™ît˜9Á6‹!²áI€Z?‚1O‚þÜ6š×> ÷ +UêäÄ)#‰6 AH‹•2ü>ãëBŒ÷ªB,œái¥xÓ½’Rþ““áõýV$²'<” #Ì7ž ¸¦Ql^>`Û¡01Ç¢²}9õAÆ kÅ>VÒëÂáHd 8ðý׸Äi,˜üâT㸛—s”b^¸Êj_sàpkRúóbj‰¢ %N4¤*Þ{Š{My[¶³ÍÀÛ –6º³fŸzGI‚Dñ.¿´e89΋v¶.§öŒÃÂÑ”ÙÇ]Äӳ騯¬é¢cú3¦Ëú±eÁ(* ªb +övÆUµÖÊ!X½þh:×J‚|øÙÚ”°VP¶ÖÖ•³}]°í²°ÕÅïvJ.Á6´– +W°?”p/+} +£Ë’…pO@X`º úØ”XÃà†ª¨] ÖÊ`É’Ÿ¦í`o&á, ðmi _˜¼|ûØÚ>kû6EfDYå ébÕ ›('¶3÷廕õ À¬²rMHb¡lu#SGÞû +ô’J‚:ÄØq¢t€fX*™¿*ž2»S´­®m–¨5qÑo]Ðæ${k € ”hM[ ÓÊ•4µ>25 lâßEQ­˜Í®íŠeË"/-é'£wME·¼çw{«üEí~*Q}qB9?!ûš Rý#@ּВ=*„VÔ‘ø)¾t*voü`œ +)ö$µ•K„ÚÚhVÚ7Ï`©¸þ\<&rRÒgµ.%d»Þ¡â½spölO’p/ûël©¿s„þ{4‰gܧþ€²«'ÐSÒ¶D›u`îUWäèÓ‰pnêÏ‚×ØdNëî XpG®¹Ó#–2|*A7¯ÉCl{UùÔUß ½/Q¬ÐÃÒý³-”<|1BR:^ƒ¶›eåêØÞü)Dfìb¸»ã/}úèföš +F½ÄiÃWMóSFÿXžê1)é:¨ì{!4³G:SܹÓÌ3‚à–•Í>󸆿Že]|a òhvõBóúµÇï{Â!d§–ÈófÈ')CP£›¦”œxG¨lÚ6Õ¦+¨µ,²šŠò@óIʄР©#ï%Íq\“øÄ[1¡S"^[ݤváHÅ?ÊОï=+/H`'•ïíüÖ¬@ÇÛëÄO|Tàïr~޾šcëÏö?Â’Pšž(ô)! …†H£cÉûß =ýß7 .ûendstream endobj -1531 0 obj << +1547 0 obj << /Type /Page -/Contents 1532 0 R -/Resources 1530 0 R +/Contents 1548 0 R +/Resources 1546 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1507 0 R +/Parent 1556 0 R >> endobj -1533 0 obj << -/D [1531 0 R /XYZ 85.0394 794.5015 null] +1549 0 obj << +/D [1547 0 R /XYZ 85.0394 794.5015 null] >> endobj 494 0 obj << -/D [1531 0 R /XYZ 85.0394 729.6823 null] +/D [1547 0 R /XYZ 85.0394 729.6823 null] >> endobj -1534 0 obj << -/D [1531 0 R /XYZ 85.0394 704.98 null] +1550 0 obj << +/D [1547 0 R /XYZ 85.0394 704.98 null] >> endobj -1535 0 obj << -/D [1531 0 R /XYZ 85.0394 519.4358 null] +1551 0 obj << +/D [1547 0 R /XYZ 85.0394 519.4358 null] >> endobj -1536 0 obj << -/D [1531 0 R /XYZ 85.0394 507.4807 null] +1552 0 obj << +/D [1547 0 R /XYZ 85.0394 507.4807 null] >> endobj -1537 0 obj << -/D [1531 0 R /XYZ 85.0394 339.3113 null] +1553 0 obj << +/D [1547 0 R /XYZ 85.0394 339.3113 null] >> endobj -1538 0 obj << -/D [1531 0 R /XYZ 85.0394 327.3562 null] +1554 0 obj << +/D [1547 0 R /XYZ 85.0394 327.3562 null] >> endobj 498 0 obj << -/D [1531 0 R /XYZ 85.0394 227.5589 null] +/D [1547 0 R /XYZ 85.0394 227.5589 null] >> endobj -1539 0 obj << -/D [1531 0 R /XYZ 85.0394 200.4217 null] +1555 0 obj << +/D [1547 0 R /XYZ 85.0394 200.4217 null] >> endobj -1530 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R >> +1546 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1542 0 obj << +1559 0 obj << /Length 2721 /Filter /FlateDecode >> @@ -6678,425 +6767,431 @@ x *ò…©ï©Ò>™ú»´&ñtáoá3E®#óW·á‘Dª‡ÄUq®"¶qÏTƒL$Q5™±wDõán}Â¬è¬±× OU|ØmÊeéñÒ7«~¤„¼ 6qÖóãH q‚TÕÚȱÌÒNçÒh<’0Ïƒä æä`V¡ê²z¾Êw»>ȱÏ^¿?1Ì Çd2¼¶¸¬Gׇ¶¬+jE·Ý®½÷Ž’d öºÏ«f“3´ôñ{Í^õè%ÃðÕ66à¤ìñ3 ÑžÂ6,mETýHÝ0‘èÀÉF¾ÑœEYMýüi‰|¿ËGäb ˜‚ éj÷åRÊTŒK¢×‹9UޝÓ1«HµŒ.Á!•>\9zU@VŠkžp²ß|4O¡a›¯Šã‘6 IÌé¶5=8M¦aÍGѰ)ï*Šcy…Îé>ÏO ò4Y¾"ŽMqëy ¿8èh_Þ­[|Ëi—@¥2€Sz·«›²-ˆÜOäÃXÌ Zþ‘(¨X´¢à¡û\ÚÍ!ßø,{ïËv:† Û¢ò¯.˜Ù~rÉà ¿ Ò›‹vBýâ§ZȉzjÖ/lPà"…ƤÜÀ 4pÌ˺™@z¬»"{ô2§¯Y뻉FÒ\sâ=Ž8íîï1u‡÷] Ræ.½*¯.¤òŽ”¿ƒi|eYPóÃwÅâ._§%os"²×]p .†rPìóôÈÇ¢û77#Q£Ð•øSWJÕD[pþånÃh3P9±D"ú;¢,¨TüdBÂ|ëœ9·}šîùI+` “ß§c“ð{×0ø…•Õ¨FäðvpKöŽ/£¼ÍÿôX&­0“¶:þ 3ég»î¨J´ˆ³TßN3U˜J;CÍ?\Ïg¿âE´UFFÇÆÐùðQ@6œëë–ß²o +…?! ˆŠ<ÂùÔ¥ -”IþÍÛVnëú釰N0ý”Ï%—ï¨B¦¥ôÄ÷8PÕJ¤Àî)>š,û9‹œ|ò¨?÷Ç3ýˆ`uÆ9=Ž‹;ü PdzvñƒŸö„_Ù0×`éÿ‹³ endstream +”IþÍÛVnëú釰N0ý”Ï%—ï¨B¦¥ôÄ÷8PÕJ¤Àî)>š,û9‹œ|ò¨?÷Ç3ýˆ`uÆ9=Ž‹;ü PdzvɃŸö„_Ù0×`éÿã³¢endstream endobj -1541 0 obj << -/Type /Page -/Contents 1542 0 R -/Resources 1540 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1507 0 R ->> endobj -1543 0 obj << -/D [1541 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1544 0 obj << -/D [1541 0 R /XYZ 56.6929 703.0246 null] ->> endobj -1545 0 obj << -/D [1541 0 R /XYZ 56.6929 691.0694 null] ->> endobj -502 0 obj << -/D [1541 0 R /XYZ 56.6929 555.5354 null] ->> endobj -1546 0 obj << -/D [1541 0 R /XYZ 56.6929 528.2309 null] ->> endobj -1547 0 obj << -/D [1541 0 R /XYZ 56.6929 486.7584 null] ->> endobj -1548 0 obj << -/D [1541 0 R /XYZ 56.6929 474.8032 null] ->> endobj -506 0 obj << -/D [1541 0 R /XYZ 56.6929 306.0886 null] ->> endobj -1549 0 obj << -/D [1541 0 R /XYZ 56.6929 276.0992 null] ->> endobj -1550 0 obj << -/D [1541 0 R /XYZ 56.6929 186.806 null] ->> endobj -1551 0 obj << -/D [1541 0 R /XYZ 56.6929 174.8508 null] ->> endobj -1540 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F21 710 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1554 0 obj << -/Length 2210 -/Filter /FlateDecode ->> -stream -xÚ½koÛÈñ»…>ôƒD{û$—EQÀçÈ©~\]S\.hiHG¤ìä~}gvv)Ò¦í´IŠáhwvvÞµqø'FÖ0®2=J3Í f´ÜñÑGØ{s$Î4"M»X?/Ž~:Ué(cY"“Ñâ¦CË2n­-VïÇ'ÿ8þu1»šL¥áã„M¦&áãŸç¯i%£ÏÉåÅéüÍoWÇ“TóË Z¾šÎ®f'³ÉT(m$PÄï—3B:ŸÍ&¿Í-Ë]±WÈï§£÷øhÒýręʬÝÃÎD–ÉÑöHÅŒV*®lŽÞý³%ØÙõG‡ÔÔâ[Lq#¾êZ!Y–=|-å+fû -:ÇVã‰>©ƒ€”´ªµ¢T#!XfŒD3fœ¥Ž§Æ€i2ãjØcfÌ$Z ¢àÌ( œ{ŒËÉ4ãü/Çì4µÖR¸Ç*‰7>ã:Ëát`/êA~á§ùVŽ^W Ш#S¤;íö"%²ã˜B¦Œ§®Wœ%<³žáÅÚ‘P‰êàJ`Ĉ(Ô_.¯æoæAøM­™5< x›¢tõdª2>.Jú6@Þn¢øøs¾½ÝD”|¶np«ÚÑÛ]5f|W¬Šò#--«²¡ãM Z=G¸ë‚Õ8h„,JÖ«ÊÍÀ|ü‡”)AHBòqX_Uô-«&néê:Þ€§"Ïoo®)!HPyÁÍe³Ï7ïëü£Cq \µæ^Ù‡ÛHÛ×nåà‘uéY_;Ä•©õ²ã·(WÅ2oâê:o"–:: 'júîÜ&oŠ»‰4ã4Û³›¢n€WAøEÉ:´ÎR–(ðœn0}[|b&0Y’¦‡ómÙ£òše¿ yÑ ùˆ—èBZP|`®5 Îùø´£tû{Uºx‹M€^;·Í’†4#…û|˜¤êvSiíø<Uï¤l6>­v[oQX½ÏkвhŠ|ƒ¾‚?WîÎeéíäwéèÕé -@Æ7åeÀY©l\ï¯k÷iïÊ&R»v®$È}n\¹r+ôYð‘wkäjÀ'É[@îV„ž6Z.šÚmn\Ów¹Éë‚/»[¼³ ø $»‰†–•ÿ®Zô€õÜõÛ}ˆ]‡•*0Ðò]ç[×á…µBZ¦•P^Èaâ`ibŒ¬¸Znö«LÁ±:‰W«§‰ʦ=Ál*¡¯ ¼W¤À­P‘Ðüâäì·×³J‚(•J¤¯r5@Rj¦”M#ÍÅâŒ1• T¶ŒC)ÍRk:ñÀDˆˆEÔeª/ÇÁÛ/e“þë_Ê0#’ÁdzJK™R¼UµÍ‹rZ¢i_žX&µŽ†x?@M±4êmYm·è“–‚: >ð> °?Y¤Â>ˆüI¿d|Cêh‡Ú5Þ¯DtWDCXŽËàº"f~€î Š<^ú:…‘0+úæåöå'¨Tf‘ãaUR\¸7§“†ì'B4‹1ÙÕ yN¥W}‰tŽ M1 _ŸQq#,#9¸1Û”¯bY4CQ% ä¤6rÑ‹™˜ˆþñ7BÐ]„”¥ÚÚ€€¢uܧG :[èê#©¿0Õ#ņ“i“E¿¡è1—ûi¡’‚Ù¦‡}Úƒº‚’&u×PÝU«vRtp*o6¥€€HL?Í×·nÙñ‘CúmÖCÉ.ɘH³äef{a›{ñ?î·m (b¹húe÷f>›]×Õfß86`Q a:ƒ>…^WY©ËÍ4Ôå¨7bäl¨¼½{÷¼“ÜÉÅñ9Î^àóãùÅôíìê_0Ì &·î}‘g¨´Å]¾ie+<æùÁY¸žÍþ}|þëÙŒ\ž3b:°’ô9é#>¶ ßHµèdpù(ƒÇjòÃRx¯\õ².ÌX‘À hH´ðÅ^í°m œ¢M›¿½ÌCäÀ›¥Iÿ—zJR8ÎÉ´ßQ\QT±-S)Ì<èýŽ´Cá ÆÝÆ x‹W5ZÛ¯R™°möÈà >¼àj^ðûþ†q—z™À^Qú´1À—ßΛ¸Yâ·ÁÚÁ“ñüf¨çŠq+Õ‹fâ @•uSïf$ª7ÇÐ,}¢?m™í¤‘ŽÊc^»/šõ`+ª6S}mFƒÞ{H—±†T°w¡'«°Þµ{Л>_D -ÖÇQþ¿ã) -SfhòTšB—ÂmßG))h-ãarW½@g=&ýNÛ¢Z€çÎí–×ÈŽ%…ÔD¿Ðê:÷Ýî -BÈ7‰`iüϵÇo´Ž~U•K×#‹ShÂ,Ì’}ê:R~¼pewXÉWì©w8)¡£Æÿ=^Ä2Ť„9ùë'îxâ©ñˆÌÞ/¼ˆIŽh‰üž/bÂdL'Ú~ÿ'±.ågÞÄ>GèP!ý­Ó,ŒÐÚòNΩi‹Â™ G8>pµólB õºÚoV„‰ :®í\ÝT;Vó?jâF^<Ê)%YbQõ?6na£ç­çïÉ ÓÔPq˜ µ6ãk|—Ú#ï:ñE1_à·.¨wA¸* ç~íè5IT?b6@tÊžXÔÀù¦®Âý!ð"sýÑ!¨ › e»¹J ¾›«TÇýš¯!§„?~½m8»ðE -—Ć?áâRY7d·½[í< çôYùgµ»"Ÿ>‰¨|5»ÙU[‚è=&¥÷˜Wæ i¹¼Ùïü#á«Ãƒ~Qާ_ܺÁúmñÿ#_Ü„„‘"¢ûâöøO%¬Y¦»ï êQwºXœý¸Î‰?îý€w«³öeÁÝäûM3mšÍÿùea¨”€ø7–?Àð6góŸ{vÄ>ÂZÙ­ Ý. %¡ý -L!ãÖ<äÜ( ÅO¦¬ÿ…ŸžÊendstream -endobj -1553 0 obj << -/Type /Page -/Contents 1554 0 R -/Resources 1552 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1560 0 R ->> endobj -1555 0 obj << -/D [1553 0 R /XYZ 85.0394 794.5015 null] ->> endobj -510 0 obj << -/D [1553 0 R /XYZ 85.0394 663.594 null] ->> endobj -1556 0 obj << -/D [1553 0 R /XYZ 85.0394 640.0743 null] ->> endobj -514 0 obj << -/D [1553 0 R /XYZ 85.0394 573.5829 null] ->> endobj -1557 0 obj << -/D [1553 0 R /XYZ 85.0394 548.3076 null] ->> endobj -518 0 obj << -/D [1553 0 R /XYZ 85.0394 357.2459 null] ->> endobj 1558 0 obj << -/D [1553 0 R /XYZ 85.0394 330.4365 null] ->> endobj -522 0 obj << -/D [1553 0 R /XYZ 85.0394 105.6253 null] ->> endobj -1559 0 obj << -/D [1553 0 R /XYZ 85.0394 82.6167 null] ->> endobj -1552 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F21 710 0 R /F53 1027 0 R /F11 1384 0 R /F41 935 0 R >> -/XObject << /Im2 1049 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1563 0 obj << -/Length 3050 -/Filter /FlateDecode ->> -stream -xÚÝÉrÛ8öî¯ð!ºÊbAöÍí(O¥Œ­éêšt”HÛ¬¡HµHÅq¾~ÞøÈ➤jªÆ>Âò€·/ ;àŸª8ŒSžžêT†*bêtµ>‰Nïaîí ³kfnÑl¼ê—ÅÉOo„>MÃ4æñéân+ £$a§‹üc‡"<Qð¯÷×ó³WQðæêô˜Š—»ø°˜ßÐDl—þruýšFRj.ß_¿¹zûÏ›‹3-ƒÅÕûk¾™¿™ß̯/çgŸ?™/ú+Ñb‘ÀûþyòñStšv?‰B‘&êô~D!KS~º>‘J„J -áFª“Û“ôG³f«—L, -¹ˆ¹‡N\øè¤Ò00…tº-:À)‚î¡ N^Üe»ÊŽ.Δ -Êuá~¥3ÆÂT)nÝfõ}A,ŒfœI-KM#-\¬Îá<Ø”c#Ê!¦‚'Ì+8ݮӗÇa"ƒ‘YT¶vŒü,k+Bo.©ÃE” gö·½;9x3¡BÆ¢¸—ë„8ŠÆâúkÖvÅÖJyYYç_º¢n˦þùl&˜c1L¼z;¿žƒPIV7^—ÛbÕ!OŸ#ès¦’I™§ºË¾üì¡\T±XY -LO1«Õl,Â(Ò®ñ¦zh=·PþB üe@ å0ô#ÀõKQ°+œ7ˆÆX”‚ÕÃHÅ/ E*Bé½Pñ¿Ûå®™ð"‰•:|Ú,Ûu;¦ f% Ø`a4ŠCÇ ”I ¡­ãDË‘÷®ZÈŽ.ŒfÄ YTì EŶ©MG“gD£ëƒ×eÛnÖvÍÆîÚR;ŒÿÔ&Dc(‚+êÁ‚‘ܶí|2‚§`ì™’òB‹6þmCxÝ*6Óe-à)yOhF¼*.ªŠ(¨Mé’¢E fuî¦èõ®µ0—…OÌ7M[b¨÷L&¥ʳx3bà÷ÉJD¸ Ü Örpù`ö[ çœ0HùŽ -‡xˆ³Ôàî-}b†ÎÊùµ¶ç#75Æ8Vgk7x··êypƒÓÏ6‹È=C»´‹†*÷š¤‹c&ƒ¶¬ï«Â·(B~»X܃t)jâbaLâò¦ª²­ƒ{_SFg~=­—MÕÒLØÐÃcß&Z{g3e…îéé§9‹ͶÝ0! }J‡?¨¿©²D&$áøÊ$› -µ‰ë´SV­‡ÀÎ ƒÝ¨×©ÒX¿7êŒv½¢_&‚CkvÝf‡ÚÇ<5;š® òÀ|gáÀd&Ì·›ýÉä8xðr†Ç‘‹³w-†§xGl–Ùêß-„Q´Ò²ÑVõ8v”¯}Ù(sÀÑœÈ4(ÂûÐ 2PÍút©ö c€É#B69 Ë,Rƒ~ùè®3"yT`,nÁ:{"j4Œ³ª²¿ -A{ÒÜ<šøGŸHxФ¤Rî´ë&/ѸCÜKy|(1wôö2S&Õ–Æ&cÞaŒ7þÜÒ/'Hj-Œ)ªÜSæÝuÑŽ{lõ2kQl5&ùpÉ3 ÷LõHUÒ„¶£k仕Á Zà\æa/Ó©ÄÌ Ë—ä©`ñÈFTÅ]G—[PIk"࠲ѼƒUÙþ3Ks `RžLiÌ1‚Í%? )2 SÇ$ÜühAÖúLWÁÅÆ„ - ½;$ãnÁÀøç†{Ï‘EŸ>y §pvÜWî_ "ÒÁc²€(Å—l½©ŠsÏ•b2ÑÛ΃XÉ—b5ãѹ8Ï}& …8‚Á„OZ–spÑ©dzÊòDsXñ€GØŠqÊqkoaxµÛ’h›ÜfŒGûËx°_áàô;¬·¥Ò%LdvAFÓy±*×YEcƼs_ ºÄÌ-eyîÛ^yñ‡‰ËT䔘+`Íݸ) |ÎÊ*[ºb9ê›”ºCù¶wTTVõšÉ(Œy_ZÈ}Ň0J4”–Û+¬º¬²üÑ`Ú±45áÏ#'e§ÆWš •è ŸÖ$€7¡)ÚÃå7œ9pP’†Rô -óÅk¤ìµÅ£ð0~÷]Ân ºáv› ‰Á -ô‘0é0ÞÊ,è ãøcð„bé3>3êkPTŸËÿ+G~m…Zô²qÐâÈ‘ÅQÜæ9‡‚9Á°þ¥¾ËI•N*ƒ¯n:êd˶©vQß!Ÿ’%÷qÅS‡+óxpÒp:×{§gÀÏ:ïƒFà§Öƒ"Ý6Q›UÆ1š÷ÜÆ* ®°ìºÉºrYVeg"i_0p²È¶UiD†±Š†%2ŸgZ‡Išö¾Íçܘ1°Âڮļá»Dâ¾.¿R˜£ŒÑö¬óÒy_pCQº_À\Æû¢ ²ew­XëójZÉë Dfìpæ8ÎȾ3ËRÇ_¡à³M¹’`nRuäAaš8ÞnÀÈ«€2(m*h:庘uͬ¢W31ÞCFÃWõÍéç^šhƒ£ª0Kª¶?2wG’)ÚwcFn…ËÂñö¡Ø–óm6Ϙª8*'øè5Þ—Õ+÷œq–»ª8øt6»CO)2ŒTꌌ…÷uB¥åñ|\w£ †¦èËâcù.JûB€"N$/†'¿¤DèGÕH~¼ íÇhਠ³$T‰<Ê¡c’®\¦„ÝoÆ(@ÍEÆ="δ+òÁr[Ç‚•ë¬3O90ØA -äà}ŪŸÇX÷wÛ ­´¡—+­ôæ¨Ø²ÿ7± Ä[.ö±Ïžt;Š-ø¦ã䍨²„‡š%jx]ý–Ø^t$c›,˜ìB0—±Ã ½-â})3ž&~K3£ú”>,nÎiؼœÓè뾟çÞ -üY÷[[®^ßaÛˆ ßGãQEÖ^ç/¸j»ã Û” -9gÇÝ*S =‹›Â?Ä“f'‡ÅAZ èÞG6bÉ›uæT"7“}]íé:q»Ymë¨-לmÍ;2=¬¹/ް`„Ü÷Ñk`ÁðYÏÿâñmA‚‘×LÊ 2 -îû¢gßq ÙW"L 9hÿÌ(Iðóe+ê…ß2‚X§‡?á‡?Éíó6}³2a·Žáë˜Â}³§oD¡€dÛnšÓ÷P qNN -ow}¥§&[ pé=¦ôÅÅ t’53Nœh0Ü'qÒ[´{é_ç§1·­pîÅa=—ï.no'ŠçR츶?'ó|G~Ó¼ô«µáË=iêCÜ/)½@ÙK!•’øÙÍÝçmϯþ<õª÷endstream -endobj -1562 0 obj << /Type /Page -/Contents 1563 0 R -/Resources 1561 0 R +/Contents 1559 0 R +/Resources 1557 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1560 0 R +/Parent 1556 0 R >> endobj -1564 0 obj << -/D [1562 0 R /XYZ 56.6929 794.5015 null] ->> endobj -526 0 obj << -/D [1562 0 R /XYZ 56.6929 713.4234 null] ->> endobj -1565 0 obj << -/D [1562 0 R /XYZ 56.6929 686.2623 null] ->> endobj -1566 0 obj << -/D [1562 0 R /XYZ 56.6929 478.4096 null] ->> endobj -1567 0 obj << -/D [1562 0 R /XYZ 56.6929 466.4545 null] +1560 0 obj << +/D [1558 0 R /XYZ 56.6929 794.5015 null] >> endobj 1561 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F53 1027 0 R /F41 935 0 R /F14 737 0 R >> +/D [1558 0 R /XYZ 56.6929 703.0246 null] +>> endobj +1562 0 obj << +/D [1558 0 R /XYZ 56.6929 691.0694 null] +>> endobj +502 0 obj << +/D [1558 0 R /XYZ 56.6929 555.5354 null] +>> endobj +1563 0 obj << +/D [1558 0 R /XYZ 56.6929 528.2309 null] +>> endobj +1564 0 obj << +/D [1558 0 R /XYZ 56.6929 486.7584 null] +>> endobj +1565 0 obj << +/D [1558 0 R /XYZ 56.6929 474.8032 null] +>> endobj +506 0 obj << +/D [1558 0 R /XYZ 56.6929 306.0886 null] +>> endobj +1566 0 obj << +/D [1558 0 R /XYZ 56.6929 276.0992 null] +>> endobj +1567 0 obj << +/D [1558 0 R /XYZ 56.6929 186.806 null] +>> endobj +1568 0 obj << +/D [1558 0 R /XYZ 56.6929 174.8508 null] +>> endobj +1557 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F21 714 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1570 0 obj << -/Length 3287 +1571 0 obj << +/Length 2430 /Filter /FlateDecode >> stream -xÚÝZÝsÛ6÷_¡·“g*_ÁÇ4qz¾™‹[Ç÷r½>Ðls"‘ªHÙuÿúÛÅ(QrÒø!“Ñhˆo,¿],°Ë' ~|bòŒÉRMŠRe9ãùd¾:c“{¨ûùŒû6³Ðh–¶úéæìÇ÷²˜”Y©…žÜÜ%c™ŒÃ'7‹ß¦oÿùæ—›‹ëó™ÈÙTgç³\³éO—ÞQIIŸ·WÞ_þüŸë7ç…šÞ\^} âë‹÷×Þ^œÏÊÒ诒|ß7ØÉ÷üxsùöãùï7ÿ:»¸‰ HÉ™Dêÿ8ûíw6YÀZÿuÆ2Yš|ò–ñ²“Õ™Êe–+)CÉòìãÙ¯qÀ¤ÖucZ.M–QŒpMð çY™çbÀ¶¼Ì´Ò±Mg2+Îgœ16}³XÔ}Ý6Õ’ü¾^ZŸj7«ªïp½0ªLö‚MfBe¥âÊ wٜϤdÓÊE¹¾õßK‰®¯šEµ9çfºðUöÏ~‹cæÎM÷dò°‡X\úÎÛõºÝ5Ã1«ÛzY÷ÏÃݶò“´ú.¶«õ°Ý_mã‡ùcbiÝRqq‘°¸—#òi sn(I”v™Oo€Ç"Åo3¦´€áp”Mõ4ÂGÁ3^pß„F¥ꎾóí†ÓôËg*ª«zYÝâ&¹¬oYy2«d;w´zR/÷†¯ès[7Õæ9mï1ã@Ÿà… !™#‚Öô進º¹'À$‚÷ŽuÓÛMÄÖ¢ê+JuýæÜL·ó~Kãøúšrs\-ç|ú•;ÖcÅí3PnUm>'|Y½"šÚÇHƒ &–mµØ•Ö+›Å­.²R -ãVö¡"J|ÁÏzS¯cDɧÝ< ¢,6"aŠ@DiD ~ûqp2SЧÁÁ2#K½‡7xG_ûçÚžóé¼· ?[Kß[OŽm즊ÕwÄŸ-ÈÓept1„P1Âp9 ·€˜¸D‘.Q”™Tyî©oª•]Ìæíj ÚÅMr¸^˜Dk¡|h»u‘¯ig„rDÜ·¨KžCÖíK·þ{·×eñ DÔsÊ ˆ-ýº§"ÇTl¾í[àt=¯–€,/*c¬(‡r0Wj ËY}GévåÁ d¢\C:”uk;¯‘Å¡72Sjy„™pH ŽxYUHíÐl'°{ü4"Ì„>íµÉi§ی̤a¥¹Òé¶ -a«xa|+T¬~]¤—!öx2“Ž16l_ªÃk‰ê®wÛ—ìÄtS5Ý](oý×ÑMÖëåsjÕÐd»=c»=/訂Œ@ÁT˜©ðBÚ ï®QP˜ŽbéÆÚEGI€*ɦۅÛÚy…G”qI(óÓl:ŸYmCÊ ,Ë‘-€»!™…„RKIOÎN`==~ˆç±ÓëžÀ(ô -g‰à@8A‚Þ,z/€!sÛuÄ+ÈAeÝC»].(}ëÊ5i-È{m]¸RŠvŶ¾ž? †!é„õʼ0 ÷8¹õxBÞÆæÌÏšœq›sØŠ¥Ï»fc‚)Á bâ 9Ée>ä¤Gô}U7Û™0&39XÀø¾Yö°òûdÙ-;~cám5ÿ´]ûõÜíèqQÎáÂã¶kë΋‚(2Îs5f†¢ü ˜ö„ÚËúž„G?&þÃÛ‰«ŠŠ6Zœ‰Õë”ZuW`ïháoGŠeBKã/[Ê_µÒk%öïÀÊ8v½2™.Jº­y³ZswŸÕiP=ü;*]¶î… -ä+–t»Ñ]yÝІ‘Ö^X±&šÌ ëGë,pέÚu„ƒù®š‡J2ª´CúÆ—9Nj46{?ø*„Ê#§_eB¨3ô´»LAI¯9Æ”¯›ùr»mÝ4ÒjÞn8?{¢U–A]@êÉÆ‹Çál΀¯ç<40T@|Äï=²¸•­ï»í2\nGþZ¿¿[Rët«@+㺋àFåBø`?`ÂQ“ç&AøŽ;cSÅ À|ºo7õ_at€Á¾¸ÜµËeûÍ/0Èq2ºö^GÊÜL”Ì3Yrýy¯#<+˜>Žü­N(8¨O¾ÎP?Cùdè1jæ4S°ç -M¢øî28åE&%hYº‹ Éý; ¨«È²kûÇÖvô¾’rL«JÎËI:Ã×ч|j©àÎ`ÌjÂOQN›íêÖÁ´ ŽeõnI{÷á#U6ýú\jŽa±™tlzõËÛ«wøTi®_‘É -=™íؾLJ'e!ò0ÉDVp%F0ùëÖnj{’é¯ÉÓDGH¦D;HÊBFHbÚðÝAsø¹Œ;¾0á`7€#aýÚ?%÷Ïk{Š¯Ç…oаFç_²¢Ðãs–•̼EY˜L±œž‘¯¶ý}ûùPL&ø:’(ž$:@q@´ƒ¢b2€ƒn– GCÁ»ôcwmx>˜WΕ?ðÚìè/&i\Éû#qBjâ {Wm—ýÈÉãöÕd¥R:Øa\©^`f?¬Qà O-Õ¡g‘R©óQzG#6uŽF™8w•!jaàE U‰éUãkê.Œï§]ÖˊʸA‘äò ‘{ºãž§´ñNPïÑÑ£MéA´¶rA%Øk<¨$×YÁcxÎn!³]PÞN]po¹ *i°åýv]¾Æ€!„uî}:è¼÷žG èèëc+ÛÞº ôç;>c„wÈcü(ó7kŒO2WhÄP4 xþP5]R¥â2ü lŒ•‡,ðÃŒ +hÍ¢:éc}Àˆ¡Mwd ö -°‚v =àžIb;¡š‘µÇâÀužIá;Õlî'”¸ zßµ>~ ø6îÐ&?kxp&íÓ‡†PºL98ˆb›“óïät ³†,4*Æ­ÌÈbLúW‡Çïx‡ŠÐqÄæ g­' -‰7Å¡aâãèIÿ?äßGendstream +xÚµYÝoÜ8Ï_1÷à:Z}ZòaqØl:éeÑ&{éìö°mœ'1à±SÛ“4÷×%Jþ˜zšöÒCš‘(Š”È)›QøÇfF*9Ó‰$Š25[oèìæ^1ϳL‹!ׯ«£ŸN…ž%$‰y<[]dBa³Õæ}tòÏãßWËËù‚+Åd¾P1~=;‰# ~N.ÎOÏ^ýqy<×2Z]œãðåòty¹±¿€ÝYNKÀ5…}! Òš§`ìà28j“¹T, +ó¦YA!LcúaÑCŽù„ù\À]gsœç¬ð›–HìÊOPÃåR6¸b/[¯‰_V"® 1Ë|x2»uÓ"¦SFu)ŠNÝFÊg7‡`8á‡ü¦n:Žr(ìòuÞNå8V#¥˜rQìXmbÁŸ"€ÂX +xîÚK}6F‰‹¡È €rM&ã:¶'QBî¡ÄAKÉTJ%ZpqE”G5BÕ£ E0ARÆÄýi +õ‚æOÖ I Ñœéq’ ‰aèäÔ;ù ½ôQiè.[ܽ¯±ºä2ÖÐ@…,â§5CPꌾÙm»B/¿žÎiîæl¸jªb×fdÂ9!Ù‹VÀažct2Òf gø"X“ ùÝ»wp7°OÎߨ‹úÍñÙùâíòòÏåå ìt†z:¿O‹Î68ð/uÞ[ Û“å¿ßüþzIN.ÞTÚ«53~y)  +H%XU¥£¢àÕãÍ5”Ó²‘Ô`]ûd6‚kBhfb¥ºdälž—Æ•þ_’›õBÛµázüp¸D@áõ%t„5de; +8ãKHãë» waà«JJóMGÆL`©ßÁÅlíâ þ~èsŠÅ'‹W//DLèå¦Ó6Læ^ø]K,´Ñ8:»žzZ0A¨é@óð5Q8@(óhO ~ˆI˜<©í6%úÀ3´Sv€#ƒ#Èö··“InQðï…4¨Föá5ê‚rãG?&[ åZÙ߯„–a¾ÁÁ+T¤l×Ä~A½­_»rÊ®Q ·" CeÓâ½í² ÊN={ŠŸkßçéb²í™Ûã±ñëºÚ"…=W=×H¦žÉÊÊÒvW»^ôMuûµvîª"õy±ÿã›êÔ]£‰>õ# …«}öOŽ=nÙ$g âÖ°„$çPÛ1èSFï­‚·¢2¼g(ÿ_¨94endstream endobj -1569 0 obj << +1570 0 obj << /Type /Page -/Contents 1570 0 R -/Resources 1568 0 R +/Contents 1571 0 R +/Resources 1569 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1560 0 R -/Annots [ 1575 0 R ] +/Parent 1556 0 R +>> endobj +1572 0 obj << +/D [1570 0 R /XYZ 85.0394 794.5015 null] +>> endobj +510 0 obj << +/D [1570 0 R /XYZ 85.0394 665.3048 null] +>> endobj +1573 0 obj << +/D [1570 0 R /XYZ 85.0394 642.5175 null] +>> endobj +514 0 obj << +/D [1570 0 R /XYZ 85.0394 578.7341 null] +>> endobj +1574 0 obj << +/D [1570 0 R /XYZ 85.0394 552.6769 null] +>> endobj +518 0 obj << +/D [1570 0 R /XYZ 85.0394 507.9859 null] >> endobj 1575 0 obj << +/D [1570 0 R /XYZ 85.0394 484.7183 null] +>> endobj +522 0 obj << +/D [1570 0 R /XYZ 85.0394 297.8603 null] +>> endobj +1576 0 obj << +/D [1570 0 R /XYZ 85.0394 271.7833 null] +>> endobj +1569 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F63 1068 0 R /F21 714 0 R /F11 1400 0 R /F41 940 0 R /F53 1032 0 R >> +/XObject << /Im2 1054 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1579 0 obj << +/Length 3049 +/Filter /FlateDecode +>> +stream +xÚÝËrÛ8òî¯Ð!ºÊÂàE‚œ›'Q²ÞÊ8YG;5µ™(‘¶YKQ‘Šã|ýv£’’!³™©­Zûúý€Ä„ÿ˜Ä K2™ML¦YÌEáŠÉ62c€Ðc™’)¡Wv@’ŒG¥tÜéc~ÇQµ*ýW&£5õß"õlï7s@A·ë-uÚÝ¢-ßá%í÷ö\¤Q¹\Û¶hið¡êî©·kŠò7ÎeSî¼ùÛ¤X+ý‚Gçu5šÁžˆrJÃëÛDx)Ëâ˜ôg›7wNøT +mtªmh¤…‹5œ÷”Ó|Ÿf«åqVW-£ŸUã´íõKêHÅÓáLº­DpSo +‚&OzÑNœ`šýsÞvåÖ„ªv8ξteÓVëæÇó©žÅ¨of×3Ð é|ö×iÄÞ)O…9QŒs¥Ýêoêû6p‹X²”Ëç*GXÃ<½bØãB°2&dl¼¢Õyº‘ÌXššl¬f`b¸rêïÜ=n‚Û ‚ø úÿ—¨ÿ£¦ŠgLÁÕ\›c Û·O’™8Qc—q´k­lC¯CÓ “hI*™w%çÔ´å¶*Ý&«¨ÐÒÊv½³eIžÚ „~ŸwnsS?R¯¨nqÉ­•}ø¾µ;Ö+SæË{·Dß-Y¸­yCmŠ“wp8ÃîO=ÖÓ^7ŸC*p•‰ð,Xâa*I¢E‰­q4ä¶eÞVˆöïÊïäÖZ­Åá¶ìZê!õpê p’ßUÔÙ;Ç€IÞlÖÛÎAÜ-¨óƒÔãÍŸËmKtêÙþ(ëò.ïÀ²ôF®]n«Å #'Œ3B/Q™ê²u;¯®§—¯^ݰ˛÷HÌKÏàX¢ƒæØ‰í»›«7WÅ$`9ÃC²ÜK¶ï ö8ˆö÷‰©t¨¹þ@í‡ÙÍ/³›löëåÏïßΞJHCÝÔ¼¼¾üÙM¾`_jÈX`ú„í†%)mlEæ)(ðçú¤ÀYü‚UþHÔXo0PÌëÚ}[‚ö¤yý``}te0)™Öíj]ThÜ!ð%‚<ÜW˜<( z{O©)“jkk“1ñ°Æ¿‡Ì·ôËÆÙ’Ú(ëCʺpÇTEwO]´ã[½È[[ƒY>\ò\DÃ=33R•,¡íèÅniñ†¨8—Ø+ „*‰ðÂr$y~`d#êò¶#ˆ‹-¨¤3pPéhQÁªÝ‰@ÿ©/=˜L¦û4æXÁ–ZѱXħ$ÜGiAÞ†L‘W!Õ>Œ=*ìIèí1÷ Ƽ°Üûx,úô)9ƒ³“¾Œp÷ íPÜD¯­É¢”_òÕ¦./WJb&To;b¥Ÿ‹ÕTò uQ„L@Æ”:Á ¡t,—à¢3-Ì>Ë;Lb%—‘äØªqÎÎ¥³·0¼ÜmI´mò3Ö€£ý2Ú€¯ðpúÎÛRí&r· §é¢\V«¼¦1kÞ‡¹¯%]bŒ–ò¢ð™m¯¼øa㲘{%–±ˆ°>nÜV>çU/|5ŽõmHJÝ¡~ Û‡;ÆTW šIÎÙ׊PõñÔˆAiÅ…»Â²ËkǦkS{ü9rä^ÝiªÍ±Xert š4C¡)ÚÃ{å7œ9rPš1­z…ù´GZ÷Ú ŠPxÉÒƯ¡À¢K¸£× T7¼Ón³!1X‚>#6¿Sô~€ úÊ8~ ƒP¬BÆg*@}Šrùßa…øk+$Ѫ—£G,N,]žs,˜S `ñÅr:ÎöJƒ¯YwÔÉíºÞuV}‡|Jï)yˆ“À(ÙWÔ}'€“Ó¥98=~6E4?|é¶ÚâQi£ù`Àm­²’1Ö]7yW-ªºêlÄ¡ÝN–ù¶®¬HÀ0–ѰF2à–fYïÛBÎM(†¹Ø€žÐvæ…ß'wMõ•œØ=l«¦¨¼÷7ijà +æp°Þm«»ÛhÅYŸû¥¼ž@dÆŽgŽãŒì;³¼!uüó+"ÕŒ›TŸLÁʲØÄúÄ‹Â~âøaFÎZ”AíRAÛ©Vå´[Okz6ƒë=4–ø²oAŸi¢ ¬ªÂ,©tÚþÈÂI¦èP€¬Ü ¥çí}¹­:ïÛ\ž±¯਼Dô¯§n_Þ,ý{ÆyíêòèÛÙX쎽¥;âÌ ê „"±Ñ§_x$8%Ç…÷1Ê`hʾ.>–ï²rO(âDòrxJúX„þ¬É_ è²&qºgŸ†y–äÐ)I}+·ßŽQ€4š‹8ŒD\_äƒå®Ž+Wygßr`°ƒÈÃûŠU¿€¬÷w» ­r¡—¯­ôæ¤ØŠÿ;±âÏ’Z©4ÿ~ÇQ©Â*.ý¤ØªŒ¥Zëáuõ¤ö²#Û¸\Á&Jø„fèm‡ÜK™u¬0ð[š•§Lô~~sAÃöà‚F_õý4º¼ðàÏy߯1õúà ®ò}4dÝu¾ÁS»GÙr Áq|šm"f™Òî'NB”{‡Ø%‚ü¨Â,Åz•{M ÀÍ&_WªNÜ^/˶õúÓV+ÈͶö™Öü/N°`„Ü÷Ñk`Áð ¨ÿÅÛF†)^®³$#Qð?Åzò“,i ùJÄ‘©b`}ÓË*ð‹¬$fJ +WO/Ãv"¿ìø¯Eäñ_‹îu›~²²Çm'ÃcJÿ3˜u£ +å#ßvû}ÿ´å¤ïn×WzhrµŸÜcBŸ?Š=-À‚j¥Dè—n|ò‡jøÜßÕ ¿-Ô¶*£Â êùèo…MÓ'w÷¿À \þ?*±Ñ;endstream +endobj +1578 0 obj << +/Type /Page +/Contents 1579 0 R +/Resources 1577 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1556 0 R +>> endobj +1580 0 obj << +/D [1578 0 R /XYZ 56.6929 794.5015 null] +>> endobj +526 0 obj << +/D [1578 0 R /XYZ 56.6929 769.5949 null] +>> endobj +1581 0 obj << +/D [1578 0 R /XYZ 56.6929 751.488 null] +>> endobj +530 0 obj << +/D [1578 0 R /XYZ 56.6929 670.5492 null] +>> endobj +1582 0 obj << +/D [1578 0 R /XYZ 56.6929 643.3882 null] +>> endobj +1583 0 obj << +/D [1578 0 R /XYZ 56.6929 435.5355 null] +>> endobj +1584 0 obj << +/D [1578 0 R /XYZ 56.6929 423.5803 null] +>> endobj +1577 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F53 1032 0 R /F41 940 0 R /F14 741 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1587 0 obj << +/Length 3094 +/Filter /FlateDecode +>> +stream +xÚÝZKsã6¾ûWè¶rÕˆÁ‹ ytfÝh€eZžÉèšR©Øx5¯1øñQGLfj”d*ŠGóõ=@ÙOÜÕ™øJ“°ÖÓ‹ÞËd”E™z4]¼Òˆ¥)M¿ßþûê×éõÝåDÄl¬£ËI¬ÙøÇ›ï('£ÏÛÛïo~úïÝÕe¢ÆÓ›Û”}wýþúîúÃÛëËI–¥Ú«€ƒk{?ÅF®åýôæíýåÓŸ/®§ÝÂAr&QúO¿ÿÁF ëÏ,’Yž Á"žeb´¾P±Œb%¥Ï)/î/~륶éÒb™Fq*’­ 9¤µ8‹´„"ÔÚAA)}µiˆªê–ˆf·ÙÔ[—hW†ˆzÓu•—”šN!"¯NÓ¿\ÝßùÆ„)M„ú©øˆó(‹cb±ÑDÆç,±éHFÉå„3ÆÆW‹Evò¾(]çïëí:oÇ/%°*ÊW–ÝMu9‘Är¬(ÕÖA¢iAî|{ÉÓñ™Ïí;ÆÄÒv÷±Çfg®1é§9â™Ïвh÷ým&wÔ[ú.vëM¿ÞŸu娠òJc‡Šƒ#Íä ŽˆÇ5ô¹%’$m¼2OA«"Ån#¦´vÈe›? èQðˆ'ÜU!®ÔCÑÐw¾ÛÒ`ª¶ÜSVþ˜e>ÃI²IW3wbæÁtdu¢Þ±Ïé3+ª|»ë[EL8È'x"¼B Å +´¡O’Õ&pÿrø.ªÖl;l-ò6wpo·—éx7owÄÇ•”šãh9çã7=PÁlO”ZçÛ  —W¬I¦ú±¨³£²Î‡Übm¢nª“(“"µ#{P™@½àg³-ÖV1"ããÆlA +ðKQÖU"!E "Qƒßv‰Œ”âÉip°(•™>B‡eÞÐ×|Þ˜K>ž·fáz«é;sR<˜Êló®xIúYÓ€œü †p.O¤\ö ÃÎ ¦¢‡(²Hª8vÒWùÚ,&óz½ïb;y>^èDk¡\ ¨»w‘®if„²BCŸ™×èKö>içÆÒµû.š,ö D1§Š€ØÓ/ZʲJÅê»¶Mó¼d9;PcIÖ·ƒ@¹R+PXÌŠ%Ñ-ÌÊÊ$:»Úç53/¬Çv­Q™RË” ‹®9/뼫¢š öx)‘`©oC+ ɩç•©zÒ0ÒXépÚXK˜*ž¤®:V7.òË@ø9†u'…e5 ë)¦¯×á¼D¾líôÅÞ'[3ÝæU³ôùµûZ¹©ÑfSî;£[õUvð3¦92qZùn`†#P0å{cê`¼@[ã=TòîéÎ ®ŒY4DTɆ®vjç9jQÆ%¡Ìu³m\b½ó”5X£Z;fK6 9¥šH'ÎÁ`<ŽÅ¾¿z‘ž_À‰þJãÌÐ<3N° «Òº÷27MCº‚d_”׬ê]¹ úÇkòZvÞ:±#$ŠfÅ®)L}1_õØuÂxeœ¤}ïÔv8™9<¡n½bcæz ÖˆnšcæÕйûCµ!Ô1ñ•šä2îkÒ!ú!/*‚íD¤i”Æ‘÷V¨«²…‘?¬Pñü…ÅE‹(Í$-ðß'#à¹kLsàn‰Ê´Oõö#%fûÖe×ÉÙ ’v–x¬‹…ãAÑÞ|U´¦[ê' ³1Õ¬ŸêPP`k—ÅC5¡ñ§Ü ©úh^ÛFB‰qSÓ·]å.§ð_4I%m`„éõ΂(Œ)p”/ßÔMSÌdJ±ñ1@aƒ EK®[o•[o•[oá Ês%EÕ ãe4$Rðpâƒßr«ëQ¸ÙìÁ·¯Á²´ÖXë´§jQü +Ù ŒÝ2`^NY.¤… ïÐ0ׯ°Øp0à[¢¬è5Äh¦ž!˜Úø:YçMO–ƒ¾1s–Ï?î6n<˃<6£³sØ€Ù)ÀÒ¢q¦ غÄj( EûA0µ³õ# ï|üù÷w'¶¨s´]ÄD½Ö©›-ñŽö›-Å"¡eê6[ÊmµÂm.¶o Êxi{•F:ÉzÛGÍíþZ¤ÁM´ðo(·¬í: +¨WÌiÜm~QÑ„‘ÖÎX±¤ ™Æqk hÎŽÚ6„…y™Ï}!UÚ"}ëò¬&5›­c>Çe€2¡ð…U ‚¯,ÔzÚn¦ $ ·9ýŠ”.ªy¹[øºv¨5¯w¬Ÿ-É*3ï.€z2ÝÆãyo6€¯Óœµb¶‹TëÒZFCþ÷?.’ô ýƇ!…yºÌÄø„œm¾_‡,`!UékFÀ’ˆIw3󶈸CðgšÏv ƒötu.Ï|RúÎBé9¶ñ7ߘÊg`DNZê0\©Û£à¦š¼ŒÈ³©à;$,£¤ÀÔób¢áƒ~a2ä¸ÿfdq>…ÿc€¯’(_µyõ-^>靈WN„W™{º¦s>ï~tGw9qôñmBpRìö¡Ø`'`Cž€¥7T˜ÚÈ+QäŒ9x5»©›Aÿ]´Å#V‹éæXÅx¯÷c.]–b‰=¨³EàÀ?ƒÚPKÐØŸ4mÝÐÉ”îñK¦ÄœæI¼™å l9' aP>l²_jHg›Àï7 âàbeš¾²€à{Ld.–¨ç;’½ùáö‹×‘°«s…B§Å÷Õ?\G²0RYÒ­#PÐ]ûa>a¹´Ï@iñ2ÿÏ6ö>ÎIxsÁ¢X'<|4øìñ dÌ*û\‘DJÀìœ|<ÈhKhš¯+¼ÞL΋:æ®y÷›EÈé6‹H‡ÇüÌÝdÂw^—¥¿»dþ +9¯ê§ŠÈçáßEwã„¿}gîfØ6 º]実®4ßµ«z‹¯óüã ïOðª/QþvŘ4§®Ê´Ž´öÏUèþ¯°Úî’®;ÓÐ*âèðÂeo†¸ú+wªƒWSà–a%jŒëàè&å`CXšž´ñN»øt¥hW” **ŽÞ»ø Â:vzŠ«‹{ÀÁ7KžÉ¾áÝ8ÞMíÏ æyã—v—5Gݦ$|y»ñ¶{±ô/i: ³Ìwe;°ðØyÍ"–ÅÝÙ¬ç+u  L¿fÔÐÃSMex¡HTxç(Ýý"Vµ÷‹2¸_<úÇ +½«OŒN•ßV®¤h<×µo²)sÊãî剤›N÷¬jèí1`HIɇž +³‘‡ù7?L><ÕÆ¹ÙÍ{÷â¥ÂyH³çÎØ=aþ/qÎ=wendstream +endobj +1586 0 obj << +/Type /Page +/Contents 1587 0 R +/Resources 1585 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1556 0 R +>> endobj +1588 0 obj << +/D [1586 0 R /XYZ 85.0394 794.5015 null] +>> endobj +534 0 obj << +/D [1586 0 R /XYZ 85.0394 741.6375 null] +>> endobj +1402 0 obj << +/D [1586 0 R /XYZ 85.0394 717.2979 null] +>> endobj +538 0 obj << +/D [1586 0 R /XYZ 85.0394 507.0674 null] +>> endobj +1589 0 obj << +/D [1586 0 R /XYZ 85.0394 474.9618 null] +>> endobj +1590 0 obj << +/D [1586 0 R /XYZ 85.0394 412.6347 null] +>> endobj +1591 0 obj << +/D [1586 0 R /XYZ 85.0394 400.6795 null] +>> endobj +1585 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F48 955 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1594 0 obj << +/Length 2603 +/Filter /FlateDecode +>> +stream +xÚÍZMsÛ8½ûWèHU",>H€˜=%ŽqžDVv§v2J¢mÎJ¤F¤äx~ýv£AвeQ±=[ªT…`£Ñh¼n<4h‰‡¢i¦­´=cCqõ&óÞ»¾'Âë j¥A[ëýèäçÊô,³ZêÞèºe+f<ŽEo4ý-Ð,d}°Àƒ÷—l #\ú& Þᣋ«ÑÅéU`m,ƒÓŸß} IK·’Ä?ýåòüâãס7ðË%‰‡gçgóËÓ³þï£O'g£fíE +®Ðû?O~û÷¦°ÖO'œ)G½;xáLX+{ó“0R, +•ª%³“«“/ÁV¯º4Á™TZî@Mª]¨E–i]ˆÚt5_¤SX–ŽƒªÀ§ ªÛ”ß8—3ß.é$CiÛ`|ïG6À“‰Ödf3BGà"NSVI••U6)Þ( Ùòݲژ9jÞ¬–0²Èi®bmˆ–ÒQ0"7mP€ KRÈJz.û"ÒyQ¥³{RJ&“´,³1MÝH¡™Š4à'³Q$ݬë,õXî![~“xr›äy:£Î»Û4'ñ„³œÛÇx3åâˆ#MkL:OóŠæqËC·¶‚9uPèÐÑGðAoOPøÆ#^¦é“¬À),¦õ-ozÔîܰ-ý=©WkáÚ®Ò‰wÍmA ùÿÐ!‚á–;6@£ÕáÅckè$ÄŽè %7Qo ¢Å2°SûÁ9÷)ˆ<ÓÎx?Ïv¦8‡¼ ™ EèŒ5ëô{E­ëb9O|»|`÷*µÆéM–{é]VÝR+¡Ç,ËÓ·uó¿éO;Ö~ì‚%½)úšgßeu?ó–«lž‚Ö| WRó4)WdØH¼É2…­1­_²|â-|JòU²¼'eñÖ‘ß&a Gîá:8/f³â.Ëo”âwëb¦¬ŸZn¯Â3!•2õÅ5=·¢ +Y±ïƒënÃbC¤˜lr»moŒpS,³¿ÜÞ‡‰ï˜¦åd™çë”Ñâΰ²µ"Êæ²½_-©bŸT¤~™ÌëM’.׎¨wdhïÉ#JS· + nÓò[h¤ºL•Ôåà…':\¢ÇRi3t«$Ë)pðN|)Ìv4œÑU^9g¡sÌV^ïÚÞa Zî iVÏŽy•Ìè…²ìÊ¥æCXÜ9ÖR0MœfI²dd³d<ó*Þ­Ò=¯ÕÆ”ë묺ï !\¸:õY +ê·É:%YB‚z…Ú"îÈ2Éò¢"iy[Üå$sG6õøp¡IŒÎ Ö¨¶âK3\- ^+\¯Ï?2š:ìWd˜áM´Î¦yÉ»c4l¢²}¿>ûpy…µw{ Ò:dOBÚröµëo€4”Lh!; #f€Ók¤Þ'SÄå_î. ä³Ñ]ååj±(–¶7µàà-›oBÞZÌC®8“¼‹s <1V6GÄèêâãóav£È‹¯‹£xMEÌ`Ig­”‚ÅÊD5>€Ä ØF? Z¾qfrͤL¢Ü²8–ªE/JÎ,_'³lºùH²ÉÖú“Lö ôev“'•ÿŒ¼ûÖªŽ{aC¦BíÇ^XÃ,ÜXZ8ýŒ5q0ìGQ€¯qpc–?’ÌmW—D,™Š£ŽbAij†ª¦w«êöËò~˜þ÷’8Œ‚á׊;U,3¼®ÓM玮œfët“¼X¢eéj/î­q"ÎBÅ;* +aBÆ…®+ŠI{ ¸RUkPŸhËÕ#4Šá>ÝE Z‚‚ê…_¯—LAy6üúëù°ÍÿyýÇÎe’—×õg§H¢Û×GÌ¡fhv`9®©„øº˜&UJ¹ª¥xAÒ ï‡û<™g_õ:/Ä·åúç® +Y¤ÃŽŠB(hD¢®(ðC!~p*PÁÕ»¼<„ h‡°Lójt-§Ž:)™æ¶kßK æ´hP¹;Ùr•ãß¡HÌQßbÊÅA=¢•ƒ?‚iËÛ#Þï‚3…]5™ 7â”ÿpîý„ÐfËÍãMP3zû±ä’É8Š7ùyà]á ,7wƒý¶œ;^cÍLW2Z°¯¸nP9ôþú~/°ûqܸøRq=¡ÄŸC2%Ä®Šñ^'ćþ.só÷Ð@ÍËÝ¿8“Š”XÉžŠXè?ðZþŒúœ^«åúÿ¹xOâendstream +endobj +1593 0 obj << +/Type /Page +/Contents 1594 0 R +/Resources 1592 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1556 0 R +/Annots [ 1596 0 R ] +>> endobj +1596 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [84.0431 62.1828 145.2431 73.5749] +/Rect [55.6967 732.5838 116.8967 743.9759] /Subtype /Link /A << /S /GoTo /D (statschannels) >> >> endobj -1571 0 obj << -/D [1569 0 R /XYZ 85.0394 794.5015 null] ->> endobj -530 0 obj << -/D [1569 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1387 0 obj << -/D [1569 0 R /XYZ 85.0394 752.4085 null] ->> endobj -534 0 obj << -/D [1569 0 R /XYZ 85.0394 542.1781 null] ->> endobj -1572 0 obj << -/D [1569 0 R /XYZ 85.0394 510.0725 null] ->> endobj -1573 0 obj << -/D [1569 0 R /XYZ 85.0394 447.7453 null] ->> endobj -1574 0 obj << -/D [1569 0 R /XYZ 85.0394 435.7902 null] ->> endobj -1568 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1578 0 obj << -/Length 2644 -/Filter /FlateDecode ->> -stream -xÚÍZKsÛH¾ûWèHU¢Þ~ðÕ³§Ä±3ÎÁIdewj's $Úâ,EjDJŽ÷×/Ðè¦(Y -åÇT©\e5A4ø€úAÑãð'zAÈB-u/Ò> ¸z“ùïÝÁ»gÂò Ó Íõ~töKõ4Ó¡ {£Û–¬˜ñ8½Ñôw/d>ëƒºþ ûpïfÔ|ïþ]ÝŒ®Îoú­céÿúîËèbH\a«#Ql÷óÏ×—W¿ ­€Ï×D^\^ /®Ï/úŒ>]ŒÚF -®Pû¿Î~ÿƒ÷¦`ë§3Î”ŽƒÞ=ÔÍB%UƒŒÜι7š¥·:©³ªÎ&=_fyŠÆ‚HÕÉ{é3í ßkº×éšZ·åržØvµ#tºš/¨5Nï²ÂRï³zF­„~ò¬HߺæÓ_¬b[1­dlôxóæÍ~3>4#6,ßyÀu¤ ”´¯áAì7“ÄG3¼b5§KjgþÆÞ"YöEì¥E=K«´²/íoB?D1%¾)õúVd?Uý[Éu6Ok¾Ã•Þ%Å*Y>³x‹V;ÓA BGœ!Cè]–y^ÞgÅ€âƒÿfÆgJð©…6àoB,Uj9Ê[úÝò.0dø¾ª¹,оôîgÙd¶-o’Ôé]¹Ìþ‡–aÇľ˜¦Õd™ Ç—딑q HÙ²ˆr€ƒýMAEì×ÉÜM’t¹F÷ï‹4àîŒ#cÅ@Ѝ¥·=ðg¢*zeà…_T¸B¥òÒ¦#ðÖIVãà¹63PDÛÞ0BWEm”…—ë$_Y¾[ãxƒ1pˆš¹Ñq"¯’œÈ!‹Á¾XBõÑ9!‚²C–‚hlâ0K¢%ë$Ë“qnY¬Z•íz騯ëë¬~è !<4< ; µQ -ì³d-!‚³0´‰[’L´¢¬‰ZÍÊû‚hYᤧû ÝMbß9—9Ä¥c}”'d¼Õ^ÚćoRšº@£EZMÝ";÷t?KÚ[MbfeSÈ=ÙfxK"×N™­>0?‹-™1MQ{¬G•þÙdvj¤? Oå?ŸBÈw)£®Ä¼á9”™E¯ÑÈŒ &šræŠÙîç.xŽ«cJIœ€ËŒH©1v+jW+Loós—¥´­ÚñjúšxE:-4¦‰°0î-×à<œ AÐ\@šíÈEL÷DƸFbí”%ÕÞîË‹Ä# ×¥·õ¼¬P êå«yAoLøîXäÛfB†K§D¯æã2'æÂäBlm„p6ÅeX9E¾keÙIHeGjbßÐL4*Næ3QSÁ¡jƒ3Rýd’V•ÉmðÌ Fb_ÿ:}!Ê–$x3™%E‘昔TìV5Ú[fw3‹žá2ÁaÄÇ»lZM( ­+cRV3*’¶Û&Í!t&ñEMÝ„—¦nw’W%Q\ò—Ŏ¨-Óà™Ò1á¯j3DØêšYÞi9YÍ!™XeUeãü^ÚŠ -ªqÙvóršá€ë(Jاµ)HئH¦É8Ë!åãdðC¡½wÓi†M:NÈØfúAsž>gÓû)H¶t:îZCðˆ åÓâÛbšÔ)Ek(à ”n|?<É<›Ø…¯‘ñB€[ªŸ.ÀB hÕ±Ã:`¬² ñ¸’ònÞÕ1Ù€:Y«´¨Cg•:ñ® -&bŤôđٕ-WÞC—£¾Æˆ‹=×£‚Ot£ì #F,Œe¤‘`2Ô~)îJù“Cð§‡`¶ô> endobj -1579 0 obj << -/D [1577 0 R /XYZ 56.6929 794.5015 null] ->> endobj -538 0 obj << -/D [1577 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1269 0 obj << -/D [1577 0 R /XYZ 56.6929 752.4444 null] +1595 0 obj << +/D [1593 0 R /XYZ 56.6929 794.5015 null] >> endobj 542 0 obj << -/D [1577 0 R /XYZ 56.6929 549.5629 null] +/D [1593 0 R /XYZ 56.6929 718.3947 null] >> endobj -1580 0 obj << -/D [1577 0 R /XYZ 56.6929 524.9842 null] +1286 0 obj << +/D [1593 0 R /XYZ 56.6929 695.4159 null] >> endobj 546 0 obj << -/D [1577 0 R /XYZ 56.6929 417.5407 null] +/D [1593 0 R /XYZ 56.6929 492.5344 null] >> endobj -1581 0 obj << -/D [1577 0 R /XYZ 56.6929 395.2295 null] +1597 0 obj << +/D [1593 0 R /XYZ 56.6929 467.9557 null] >> endobj -1582 0 obj << -/D [1577 0 R /XYZ 56.6929 395.2295 null] +550 0 obj << +/D [1593 0 R /XYZ 56.6929 360.5123 null] >> endobj -1583 0 obj << -/D [1577 0 R /XYZ 56.6929 383.2743 null] +1598 0 obj << +/D [1593 0 R /XYZ 56.6929 338.2011 null] >> endobj -1576 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> +1599 0 obj << +/D [1593 0 R /XYZ 56.6929 338.2011 null] +>> endobj +1600 0 obj << +/D [1593 0 R /XYZ 56.6929 326.2459 null] +>> endobj +1592 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1586 0 obj << -/Length 2860 +1603 0 obj << +/Length 2927 /Filter /FlateDecode >> stream -xÚÍ[[SÛH~çWøÑTŽ}¿ì[`ÖS3f+µ3ó l4k[F’C˜_¿§/’Û¶Œ0xS.Ôêë鯿sk ÒÃðGzZ Ì ï)ÑÀDôƳÜû -m?ÐgPwĽ>Üœüã‚©žAFRÙ»¹‹æÒkMz7“ßûÿõþÓÍùèt@îKt:÷? /Ï|ñW—ß~½?U¼3¼ºôÕ£ó‹óÑùåÇóÓ1šÂxÍÆ^ߨAaäõÍðãõéŸ7?Ÿœß4ˆ7I0³Ò?œüþ'îM`¯?Ÿ`ÄŒ½GxÁˆC{³.œ±ºfzr}ò¹™0juCÛ@ã\VTõ#NÈîUý -V Eʱr®/:0`…CàaƒW‡@It0’ô”0H2ÊÜ!|.žFé]ZÉÔbCX4„h’>Øw^¦E––§Æy¿8%ºŸ–Ëi•N|M6[¤®&™—iaÏÁ’aý›û,L3΋0Ó"ŸOJ+¬6 !¨[¶ÊýqV÷i1ÞUˆk)‚ˆÅîÍ0‰¨`2tçËy2¹™ó;ÿ\xQ¾eù²ô5ßÒ¢Ìòy¹Þ/b)Ú¤”` ÎD/>·/ç a S˜@°×}¦¬Gì` ÖˆÒ.ÂÀŠSæò{Q”iµ_(U|±5–/öyyu>]ÖºÊzäcVÝûÒ<÷ÏIR%¨*žWÄlóÊUZ&¹g+“yÄìL^úùÎm s%È&“ìÌ–!ö¹Î$[L²U'ö€5ƒ£â{“øjª­Žñm´X1­FõåSÖ#Ú™&MTý<Õ¤1H Ékª]ƒ«ñï‹S!úËþõE’íc¯,|üƒÇ?ë&`˜±ÞbøËnœãM¼ •M Éá€Ö1ÂUÐZ!ƒIã.®F¿‚Z@¤|ÏA{…o˜ûX#‘«7¥ü`¾UJðÕ˜³X•@†KÒ˜Ê/gW¿¾BÐB®ð¾›%lÓÍ’àf¡¥žù×àR¡´eúì(0}m®µÝJİ–œä³VÝN5ùa.5>„cu©’B$Ìt—¡"O¡VAØxé`±§EYtñ8ù¼'Uï³ñ} @²,=_˜;cW(ÓÂ:!_™ûç"-îòbs­d.žÑŽzÌôs×sâ&ãØOÕ`Lç“PçV­+} ˆ7A¥kÖB¿mÖú™_ÉÚ"ÞÇ&mû˜ÿ8ÚF”8”† ^)±Ï”õˆvÚ‚ÓEJv™7À˜(Üx³åbš“Ê5e¢?‚Š}X ¾´f­-:ÎØBÍT[Nª*-¼S±}rÿ\q5Œ¹]V¾0ÉÊAkÆyÁìT¢ˆdîŸé÷¬¬²ùWÿö°´½úOþÍÇž¶ä„³…2™…ÒðS˜h2 Ô-ßµ­¼È‹êǸ›ýɱ¦?[¨wnËvçöÍ`+V;mr²´–@°pýAƒuµ›NÊ|îÒï‹)Äg>ìfuº,èN? i®¤¦ÖÌi;.‹Ÿz µM«A3n ‹eË¥ Aš’Úϒ.1;2ÔÔIx¾¨¼æs0]`ËÔ_£ƒ=†ÚIZŽ‹lQ'ÖT"%¬^­E .²¢0,¹Í—Õ¦¹`ŒCFrpÈD¤d.mðÅמ/Œ¢¼¦ÿ °­¼Ûó>‹x,'ÂH5㶯ë^-‚¬ã­Ù¬ %¢àÈ -¯`+èÛ§í@g`!7õe—‰âA¸ðãò†ØÄ¾Ífoº~07ÀC\㎌C¤kL{²,Òn7pGg ©u ¤ìß¹áþ¸m| d@¿íøF¸øw\ÆOòÚ¶Üí”nÐô܈Ñ8cîˆ9þu*Ø–l»ïÇl Pa …î_æUúOØ–²òfe{TØ&¤ï#£zÅü[6©M€§O¾µñš·Éø¿‰Ï…|Ó8Ÿ-’*»Í¦­XV=ùlÜÛh——ûìlóÆÐ¦cõ.mª„)l¦˜%Ói˜!ñY^{0ûær­´5úýZÔ.B©zÓ¥+—.‡RR¶ù °@½šHï—Õ½KXÿj9Vž(ÖuÐ×îˆA’*± -OvÎ"uRr3ýKl¨/Dÿ1_N×<¦eî+ï$_—Í«PWyó&Dll`P žm‰ý»«7°yŒv%†ëYmiÅ"ÜHe‹ó¼ò…ÛÔ?] ϙÜAòA²áÆ:M«BåÜw[ɸõ8«lœî¶w±-9”½;ô…0“ ê/>wÛ;05ˆâïI¾Ü£ôá,Ÿ§/ {ÁÌ•Í]äßvÿ©Hæå'?¼Z¦• év¢Iz¬·¾ŒÃî;R&`CBJ‡Ïo‹ äm€ÒÅã ’ß;¾èuè Á ÖfðY‹â9ÉK×qwÇlø‚ _ñ\¼ÈÕO]{ Éy´XR°(ÂÈ,)x .iàø²ŸwΞ ãËÆ¹el„b¨€ùžÅ3’õh5œ0¤0ïø­–…¨!$Âóeö²Ì=,d$ÛÑò¤¸éˆ¯Áé"Æ„‰ùøZ2–/$_$ر‚Ga³ÊðgM CLc÷!™|*Ò"}x ‚ÞPþ•Žw.GpómHˆžkß”•Yc V)Îî3ˆ÷w¨3X}ÔùIŒ±6pí‹¢W ªÅ DZN)89ؘýU$º=غE€ˆiêzÛoƒôŽ8¢þXŠB¶/¤ÖîÔì‡WàOcÜÿOfý -éF•Γù8T\W•·†CýXç gBÀ·q¡`¬¦êEe1®a›Šíaû¨Z|@5j6åï¼]i3k÷ë i°?$iðHÚ«ÒõÓì6‡œÒeÚ?ó×]UøikíÎNHIàD¼ÈÛ·1¬õÿ êG¤i§Û - dÆP°X@JŸÝ=]-«o¼Å¤Ž”àuþ9üÙ Ëlr\[”2Wh7|‘\‡…>E‘DwÁ§®ù|ò%ðÉWÁÉuÌìs—RvÁ')¸F#ø†ó7‘/üâ‘fßZ‚Š‘xÇŒ"‡€SÞ…¢ÀPÐë ¾…‚/ÑK'ŽD& jßõëû -D¦‘G¡Ø~q¶âBxÿCñN }põ ‘„Ç $…4|RýÁª‚w½z¿¯;!¾ð×a#ÑŽAèÁ´èôÉ„#£¨ˆÜG_… íØ ¢1ˆÃä]øaHÀ3û+õ/£Qú°혭û¸ç48’ëˆÑÓÊ~ZÝå“ ‹Ò5ðöaßÞàEb1xJ Aq—+V‘£_A¼á¾ØERq0-ä´¢ËK…ˆÿ 1|ñö/ë÷#E¥»ËAÄþûOË÷¸×ÉÊ—þ#Ôê_à cµ´˜Ð\=@|aç²pi³}O£‘дé‰þ?¥w¤‹endstream +xÚÍ[[SãF~çWøQTŽ}¿ìÛd€,©&†l¥6Ƀ°ÅŒ²¶å‘dö×ïé›Ü¶eOŠâ¡[­¾œþÎýȆ?2Ðafø@Ž&b0žàÁGx÷à s†qÒ0õýíÉ?.˜d$•ƒÛûd/°Ödp;ù={ÿ¯wnÏG§C*p&ÑéPHœ}yuæGŒoÞ__]\þðëèÝ©âÙíåõ•_œÎ¯ÞŸŸÑÖód‡°öæÖ. ++on/ßßœþyûãÉùmwô’3Kýç“ßÿă ÜõÇŒ˜Ñbðcè`vÂC‚3G¦'7'¿t&oÝÒ>Ð8×€U€GŒ’=Çú#0º\!M±Ú8uh0à +ûQ˜¦1í¸@I IJ$eŽ ¿ÔO7Ëñ¸h‹ ¬`É +¢ P +ø`?wYÔeÑœ™1Y}JtV4Ëi[LN‡㬜û7¹o¿íýr†çÍcQ[f§”ÐÙí§²ñ+g¼´çÃACB‚ºÛO…e%Ë>ÃÑO¾ûø©²]hh—5¬vïrß\]ŸF×#ÿ]Tó&löX¶ŸÂü¶ïÔi‘7--TVÍ ß ÔC_f£òƒþ¶7®êÕ9“0ØV¡…[xpSvP Ê@ à6;¹0ìf*½þŒ«å¼µ$YQ¯î}»ðT<”Õ²ñ#EݔռYŸ—èÚT +Á"œ‰A*N¯“Oζìp~þ–qÅ‘l($öЄÈ(ñï–í§wó—H¼Ej]â툕xÛæ°_U—mÞ–EJ¤}'¾+Ú_‡Å·ƒW„T½_i ÒBòˆïU•„‡&d7Wù1ážW¯Ã=½Ô±€§ ™½dk˸bðŠ"&ÌÁ–Z!ƒIgÊGÅ}Q×ùô%¶œó ¨íˆ³åÝ›°©Y3ã°háÕ¦ì3è•gÓ“¨×RëÝ—aÀ@Ád˜øí-aÊ×±w%1L ¸ëK¶Œ+vH €Â¿ûFY›NS¿ÔuS´/QMª6UFœjB»ò¼«iÎó†•ÁõBo^ùv’·9ê/WÄlË•´’äÚ^Iäasï¼&p˜+A6%Éîl%Ķë’dG@’ìÐБ=$¼fÀê5÷üÕ¢¶bãëÄâ: +Á>Ó‡œÕˆPÑ9…ˆõÁjüûâTˆìÝåO€„Æà.òrz4×`íáù_þ´çäÇõ¾äx@Š„†Tj?ÐD"¢pç.®G?ƒZ@¤|ÏA{Ž…oØ{¬ ÉÇõ­üh¾Uh¤b쬘#J‚6[SùÛÙõÏï.!%Wx~‰›%lÓÍ’àfáMÜùÇàR¡·WgúväJ=†P"†µììचåpê6á”rªÉßæRS&¼U— +Ð"ÕC'4€¹^a㥃År‹²ltñ8ùå…¢’\'ù²ñòÂ|>l;MQ?¸tÔV¾]õ}UÏRY‹„ôˆ‹=f²ÊÍœ¸Í8ö›ÁðÓù$Œ¹Sã ñF ¨b>oçmK­ßù+¥¶Nï±)¶Œùß'¶‰HË? ƒ”/Ù2®è[n`gv  +$8Gœ¥öl¹˜–ã¼µ¬¦Ld#x‰ÔBBÕ•f ë+7Љ’jûyÛ³…w*vNåÛ•¬†5wËÖw&e3\—šXû!˜¯=IFß_ʦ-çý“­’ìÉ?ùØÓöq¶Óä³Ð»ü6šL‚è6ßõÉ뢪Ûï€8Æ»š5Ù噃Ô6 ¯Û§EáßæV‘ìÛñ4oš06õÇä“'ÿî®pdÛ®ØjØw¾­Ð8iºú“êÓ8åñum¿ŽÅ—RªÀÈIÇÿ%uTÝÌNÉìÞ <>6aÎø:ŸŽªz‰X¿NMVšDKþ¢l\ѯyÌ(XŠl\s@žu‘ñY]- É•-x[ë` +;ôÀôÛé\‡Š†:»€>èÔšúØ5y¯‹(¾XióÇ1šÍ—³;· #Žqvl¥oö)q:~Ih„÷žFè‰ÜTk¯Ž‚ʨGr=²ƒNl'èÑÚØc¸‘j–wMgÏÛéSßÕ¼’;ØA— ¼2 @(¶>Û‰7·}{sÛ&;ØÕMûN[†Ê³/ÐU];ÆW´,ž‹)Äg>ì^UªéN? i®¤&jæ´„7ÃEÈO½…ê©(wëÖà·XöeÒ”D_<Ë¿ Ÿ{ ÄìÈP“ðjÑzÍç`ºþÀ7…5¾F{ £“¢×å"&ÖT"%¬^­E .²¢°,¿«–í¦¹` üš:8d"†Q—6ø—õÇ¯1Ýüaº`[y·÷Ý‹xJ’]Á°Ñk$mгzY3Æ[»YBJDÁƒ [€¶¼‚t2@ßæ¶…ÜÔ—]&ŠáÂß—7+_o³¿¡À)pWûÝãŽ)íL[YÖÅa7p ¬³†TŠƒ0)³{·Ü³ÛÆBÆøæmǰÂÅðrG1–`¤$¶å~'uÃnæz¤E3æXÌÁ𯋂}³ûÞÏcAìˆÂP ]UmñO¸–²ô–½f6 LHæ#£xbõPN¢³³ ðôÉ¿í¼æ]>þïcîs!ÿj\Íy[Þ•ÓÞ´lŸ|6îm´ËË}v¶Y1´éX¼¥M•0…ËÔ³|: ;ä¾™UуÙ'—k½1àÇ:º¥â¥ÿÔ,]½¼éó¶:#I$ûÌ%¬õ°‚'Šu úú}1HR%VáÉÎÝ @$ NJn¦¹ õ…È«åÔy=ÀcÚT~ð@òcå¼ c­7oB¤ÆEðì›”éß¹BX¼ÀVÈauÇ]mo%E¸£ÊvçUë;w…o] íÌaÎ y(!Ùpk¦µapî§-ê|ÜËζ{ì]bKŽeïŽ]¦`Ÿ”ád¿½£¿3ÈÝ¥»¯GÅç3û}ýa/˜¹¦«EþÏ}”w_‘ê|ÞÜ{á‡G«±Ó¢µ!Ý.4SJßjÕ´if€© â × _Hܦ‹Çgd~vZéuðÁ"F;¸È‘oõÛ5•iÍTï¨4×a¾d³øJ$W»^eBç›ÅR0åµ<€¥PH`Ö<8€ãó>ðœ=AÎWŽ=rËØÅ0ûíÅ3¡õÍâ a³QìÀ×ZÊZSñçÙË(_`!=eoúW)”AKôøšÂ•$æ&•ƯÅæ™¢—öfÁ#Úî|ÈYCÚ!½JÀû>Ÿ|¨‹ºøü½™ü«wî<Gp÷Û=G×T6eg +V)Î$÷;V¿æ<øóPXÃ%]ÿuèW-ŠdP"m¨€s»Øˆ<©lU âDšÚÙÄþ6HˆqDüå+ü¸ò¯ì¯h!?ŒqöŸ.Îúò¶˜çóq¸±?¹j p \}“ ¦¦@œÃ¢F>ë¶Œk¸§b/ðU$QºK …ˆ–“•*A@”Ø@ âcK*&‡ñÍÓ쮂¤”‹fg¾ÞÕ†o[kE#à’ é!¯#ÜBİÖß ˜Áô.q[aA8¸*Ó—÷O×Ëö÷ØÑ<& —`Røù_[Úì8š”¦˜·h7|Ž.ùÆÑ3„Âæ‡ÀÃ`ˆâàÉç€'¿¼„¬7 :®„<ž!`Ì)M°»œ¿JîÂ׎¢|è :âÞ0„ +MŠù•A$ä¾ç!˜Ðv\É1” BuÁ ("‚˜ÂþrÙ‚sÜýçá(új7Š }¯ŒŠ0FŠJWöAÄþIÏ× <8(¤Ïý—šÕ?q–\ÓþÏ"]à‘†ÝËâfÈv”¨‘д›•þgbk"endstream endobj -1585 0 obj << +1602 0 obj << /Type /Page -/Contents 1586 0 R -/Resources 1584 0 R +/Contents 1603 0 R +/Resources 1601 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1560 0 R -/Annots [ 1588 0 R ] +/Parent 1609 0 R +/Annots [ 1605 0 R ] >> endobj -1588 0 obj << +1605 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [333.4761 480.8577 413.3061 492.9174] +/Rect [333.4761 409.1267 413.3061 421.1864] /Subtype /Link /A << /S /GoTo /D (clients-per-query) >> >> endobj -1587 0 obj << -/D [1585 0 R /XYZ 85.0394 794.5015 null] ->> endobj -550 0 obj << -/D [1585 0 R /XYZ 85.0394 244.5016 null] ->> endobj -1589 0 obj << -/D [1585 0 R /XYZ 85.0394 219.381 null] ->> endobj -1590 0 obj << -/D [1585 0 R /XYZ 85.0394 219.381 null] ->> endobj -1591 0 obj << -/D [1585 0 R /XYZ 85.0394 207.4258 null] ->> endobj -1584 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1595 0 obj << -/Length 3080 -/Filter /FlateDecode ->> -stream -xÚÍ[YoãF~÷¯Ð£„:}ØÅY{ÆR‚ì&yàHô˜‰tDÊÎüûT±y´lJ”Ö - À"›ÝŪ¯ëìn²…ÿl 4ÑŽ»q’(ÊÔ`¶<£ƒÏðìû3Võׯa¯ï¦gß^ 3pÄi®Óû€–%ÔZ6˜Îj"É(Ðáw×7n4æŠ'Ó‘‘Ãwøgz=™^ŸOFcç,žÿç݇éå弄¾¥~~{suýýOwÛß|wyuywys~9ú}úÃÙå´ ’QÜÿqöëït0Y8£D8«ÏpC sŽ–gR ¢¤uËâlrö±!<-‡v&)#Œ+1 K¤Rvûký+(¼¶ºdŒ8¥^¾ų# þÀD€HT*ÓLgÁD0¦ˆ´f`”#ZpQNÄ/÷«Éz6‹óá"À% ¼»þ/Kci±ŠÒü>^ù»ÕˆÙaüÇ:΋ܷäH1žÇsòs`ŽH扖շ‰/¤% €¨:Q) uTõ * ÑÆ°Ñ«(YÎ{ ·Ë€ÉcaÙªpŸMàCÍ ›øÿFÕŒ0íˆ0Þ˜;èfMhK¯lŠ0%+8LÄY!º§«6xm)±¤¯=#b“NÁYÄy¶xª§bRDE’ɬšˆólñ*9š#„h¸Ã2{¹)ˆÔü0Ô:Õ\Ð#Z@-ÑXK˜ mßîDµÏ `"o“¯ËOÙb„Cyé¥m…fÕ.¸äË8Ÿ­’Ç"ÉÒW~™‚8°¦ðÝoq£Z¨¿!f¸Mç„$%þ•}\Ç«¯Oâ˜Òz8¹zžìpÌ:«NVþâúŽ@ Á7¬’¸öµqZíÌBvL9øQey„à ¨”6€P ¡>€¹ÖBð|Šö)!3‚9]‚®î1KóµJRm†ww‡(¡SžD6Íâä©#Zµx¶œž0œ¦A¨¶=xRE˜rO}žú­x¬ž®‰+”Ûq³PåaÆùÔôæ—‹Û÷ï®!BªáÜ÷ÚÚÁ·ÓUIe ÉFõ há\V‘j&¨…~¾)5|wý#(¦²rx·%?}%ކq0«2}¤³' ©VD[Þã5$£\[º¯nïÞ_‚ee©“W—«U?’Í  X;a«†Š×pÓ¸*‚ ¸o‹‡x¨e+ÔFÆ >ßÂr˜0^•f«ƒÜdÈê k¤„«^<¥"BYÆ//n&t?ƒÆ®¿QE)üamôµ­2×UÚcËà £™¢eº'z+Å>z¿OòeTÌ@)‚Ø}±~Ü#|·£ÞÂC~OØØ!{´Bö Ê$݇ð鈅¯Öé,*ây?žÓ‘CÌì°ñF\ŽOX[!‹tT÷vêˆtÂö£e<Šî³¼îEÖ@èæñ"þaá}–—§‹% XOD—Î%Œ«òö]` æÌ~:òcë5=xE[L>Æ«ûlµÜeÈäéš»„LÒ=PZE 8ŠòwŸ²U±† hŽ©Í}¾®×E³:HeEä/gYZøè¿ØoÀù±ð -— ÑþzÄV|¥†â‘ö¸SiÑÜèßI6û²_¼¿ -":ÀGÙ0Iýoö§IúoÚÚs þÇÜÉám¹@ ͳl¹Ìª¡ž^”ûu»pÑ_yis·ðŠoäþY’û'‘¿ :øöìÞ?h¸ :§ñ³¿÷¬úFÔ˜fjý©tg‘,“¢t|þ¾þýR¾hœ£_–„är‡~3÷6eø[]¡PK«ž°"…!FsÖê׋¾dgëâ OXø1»p 8:áÂ9TÐ}Ki’ÃŒRíCÈ÷‹u|Cˆ‹cÂ9œL¾æ­éÞL*]Ï+[©7ní'“ô)û²3´ÌŸ0ÄŒBEí£Õˆ™ R¸ëƒ!ÖÇ…Ø3â% „š»`ʈuZ¿Ôáý¢Ë¾º»s³Aµå÷„1µênÙSV -€ÉI&_ªíÞ¨ê#¢p|¸ ƒîÁÕâ¬ö¡ýç²°ŒïŠ"^>î¨.n&“ËsÚS´HæA"y";ô,žx%)4‡Ú[ö„|¡5¡‚± o¿¼ ÃíG>Z !‡JŠîê[1jCÙSö€Qj”ÛÀð&þ|ŒFº M•“b{Z–èO±oMR,)ƒn€ö¸+ãí‚@¸·áõ·ª1×DAu¾{PÓJoÌÀ~>v—÷zÔ–·£ùjˆr‡­¬ÔC¶AÈ™gÉû<ôâŒúPõqõµÜï™NÓtÚ²9¦”ΰ€*¬ˆ>•eVn©¯ }©¾NçU(­ª+(r‰+Òw#aàŸú—W‹ÓHåÞS©6ëI—Æ_F =·¡„\â9Q1Û-"BBòã»äñ,ÁJÙ\†ÅCŒŠßU»9/ëQ|~¿ªžKdjxúqH†T *ëÚ5šò}~$¾C”ôµ xBŽ1µ!C¨“¨Š’B_ÀˆJÙ>ÇŽ8¨…µÝˆÆ ÅqHòµþî€4¤8M7äu€,áu¬ž†o:„„JÚJ¹]F%¼QÆšbŸŒ?Ì󦈼_DÈf@é–&Hj·K‹ ƒ †OÚšbŸ´NG©ÛwÙ!®…šL›Mq½­HÞt½K¥5€råNhw<Š=H óȕ٠é@chí6’ÜÛ8˜€d› PÞ‡ðaº^~ÂíKȺJ¯†mÍ$¼y~ÈòØ?}¡Õ‹cxó).žã8íòyÕiÔíà*b[²\ŸtG·¢8Iv ZJÓôBÑï'ã>F¸4n>V†‚ÏMñ¸F=%t¶Xç/UÁC@RŸÎ»Ð eïv ”–@ܳ7€†uæíXS‡$»ü #š¡7¯»mS@ý¤ÿ|%ý2Y,’<žAÄÂÕ\Aåð -—fñY˜œ#šJ³ z}AMÓÔ+ª.×ÜŸâ4©¢4T ‹(/<®–bvÆ6ÓrŸIX1̲õbŽ×ÒÓƒ6oãUªãªC”wâ+ oÃN¾ ¥Kˆéò¶·ã[Q‡$»ðÓÀZÓ­ %ÿè2dIl“QB,¡à \Ý@H–q”Vþ•Aý n¼Ë¿Â46þ¸Ï¡-8âijÿŠí›þ6þC^-|»ß?À“&Õ/ =t3³{=¥E;(¸9ç RîíQ­¡8I¾ž n Ù±í{·uàbv­M›Îc[%–o,[ÚZhÿÏŽ~ž3íï!˜|ŒnFõ|tÀ”"F™ð£Y}t0©¶²°þ¼þö¶ÿÛƒ³GÑ$Û5ÇI³3V‘Ë< ‡÷³š\yµÛo­[ŸûÛÇxU‘è_ãüÜäµÅ†t:’aÐè:òþtñAvH‚'¼¡” -btüWš1´u¥Ôàõpª%«!«·‘Wå¡0vÓáLÏ»Ù6PvÐ‡Ž»Ù6„«:†Cg}U½ÕŸÒäÏ.ª )Ú†P`?Hàäð"[FIꉗxwå1¶‹WÏ娎ºH@¢ldð¦jwÙ¿ 7w˼^y2ýM[7 Èóµ/ -çÆXÔp™Í׋2ëÁ‡ë²öæJ×A ï³Å"{ö[ÝØ^.Q”¼²pŠþT5yá¿:¤†É¶Æmúß—dðK-k7úïîÔ•ã!ßãUÌÏ=בç6 ®ò&+üóh±ð[c.G·á ú> endobj -1596 0 obj << -/D [1594 0 R /XYZ 56.6929 794.5015 null] +1604 0 obj << +/D [1602 0 R /XYZ 85.0394 794.5015 null] >> endobj 554 0 obj << -/D [1594 0 R /XYZ 56.6929 698.798 null] +/D [1602 0 R /XYZ 85.0394 172.7706 null] >> endobj -1597 0 obj << -/D [1594 0 R /XYZ 56.6929 673.6774 null] +1606 0 obj << +/D [1602 0 R /XYZ 85.0394 147.65 null] >> endobj -1598 0 obj << -/D [1594 0 R /XYZ 56.6929 673.6774 null] +1607 0 obj << +/D [1602 0 R /XYZ 85.0394 147.65 null] >> endobj -1599 0 obj << -/D [1594 0 R /XYZ 56.6929 661.7222 null] ->> endobj -558 0 obj << -/D [1594 0 R /XYZ 56.6929 173.6899 null] ->> endobj -1600 0 obj << -/D [1594 0 R /XYZ 56.6929 148.5693 null] +1608 0 obj << +/D [1602 0 R /XYZ 85.0394 135.6948 null] >> endobj 1601 0 obj << -/D [1594 0 R /XYZ 56.6929 92.1409 null] ->> endobj -1602 0 obj << -/D [1594 0 R /XYZ 56.6929 80.1857 null] ->> endobj -1593 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F11 1384 0 R >> +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1605 0 obj << -/Length 2016 +1613 0 obj << +/Length 2828 /Filter /FlateDecode >> stream -xÚÍZ[oÛ¸~÷¯Ð£ ±¼_€ÅÚ4ÙÍÛKâv±gYm„ãH^KnпC‘’)[¶šÆ1Š‘H gÈ™o†3¤I„áDZ Ì ”áH`"¢ôa‚£Ïðíç ñ4qK‡Toæ“WWLEIe4ÿðÒkM¢ùâ¯éÅ/¯?Ì/of1x*Ñ,Oß\¿{ëzŒ{\¼wuýóï7¯gŠOç×ïß¹î›Ë«Ë›Ëw—³ØMa<8ø±·s;ȼ__ÜÎþžÿ:¹œw I0³³ÿgò×ß8ZÀZ`ÄŒÑ#40"ÆÐèaÂC‚3Öö,'·“Ãàk3tHiD¨`QÌ8Òx|ƒXÆ5RX‹£˜d„8ÂËÃÀË¿¶#ú¬bÂâBY£r…¤RdkT•p†4c"R‚ *ÁàÖª·_îÊå,–ÜÐéÛ¬J×ùªÎËbWóT¯¤¤Q(äy·*b¯(¦ ™£æÜcÙŽ8¬  €ùêN„ ê‚;Ñèâ'»èWW4¤THq­€»%˜ÿùáÒÑô¸Q¸äÌý÷í Þ¯²ÂÓ°€¨ 5žè¶LÿŸÕ8†&ÓFd ûާÕ&M³ªú´Y.¿Î!Sð#ŽÙt~ŸWŽ"-7E­ÝÐܳ(ÊÚ½$«Õ2­ü…VdšÜ-3ç‰uéŸ÷ÙÀjEBRâgzõö1©Óû’9“íŠê¯« †U`¯ça`Vü”°’Æ -$ƒV=7¬®’|9 --K´Yψžf†Í´üO‚œåÅg×Y9Zxiíáe‰:xY¢Üshàe¿þ ð -ív*x¹Å‘SFp©2˜°xICÀÇœ^˲ʞ¶À¼©²8b”`µ§ÚJ^`[•J Ã%3Š2H0ªÎi”7y±øŸ·Æ±>oŸwÀ¢ñyÛè|þ É]üÈ&“༛1“I…„RgÝý/Ê¢x¦ÉR`‘¥õ¬¨ãG¶D~Ì„³šHRÐÜ™­6j± o—²ð˪6½¼ºo’71˜¼´Y ŒSÙŒ ¨_„xËvÄa›‰ˆÂtÌfðÞvÖ„è5èzU‡¯ Æ_ŒM“†Iãj¶;/Òò¡k¥Á]ÛqøgvwÞ¸›ù$ð&‹š‘©ËÓ¡Ýö»<0—Hµ9|hr&èΙˆàá߸õüþöÃÀš)·u_«ž¤X 1ÒÀ‡'_1ÅQ(û ´Yر@ åy|QP £1 DX!‰Çq}ðroP°®“×Z©q[¦Â§m™ªl´ul³xÐÕª,UWšî¯„ÃZic‹f)Ãë q"Z­ma\â6ÀT!°A—ÉÛƒÔ¦IÜ™BAh`úS¸/Y)F‚ê±Ä\À0úœ½ÉÒ/OE(šӡ¶Ï-Íò/™ûØ*5¼Íšñér³È|+Ûr@ª«”÷*dÀØ}±©ˆ}&îá#æ©m|u ÚÉÂ;„îüÓl1”²Ü}uN -÷¼¾øíƒÏnÛ©ºæl(Éç#g0¡íOD·Çößw ÿ¼c|" b -°S…°êßìÝ#0,‘¦FE17 aA¶^ÐCe{ÉÁô1æœÀ^˜$`kÆC¥ñ°«ßå˼ööyÌk¿ßIºÌÌ¢g/ÊôC¸ŸK¶ISÁåÝJà¦~£îJ@Ûú¸ÉÖy*W V&TSœè1¨Ž(³¥j”yýqO•¢Ÿ­îŽ -í¨¤öT‰Aåöf¤'ö´ª¼ñ'<ߦKj`Ûfîò°.CªÃºì¨]¾_ÕÕ>0JÂ&÷ÇÄvTr{Ú´µ÷h³ÛD‚ø×\4ŽFÔSB‚iw®lWlÚÛƒðÚç­å*8¢Ý³µÍ„ו²Z&é~F»Èþtd@Ã8=ÿÖ_¨l³c F­Ä.¹ô“jtDvgYhšª©ÿ aKendstream +xÚÍ›YsâH€ßý+x„Ø¥¶îãÑcC¯'fìi`':vfhÛŠáFÂÞþ÷›©ÒQØÁ@GÑÖQ•Êú*+’` +ÿXGi¢wã$Q”©ÎlyE;_àÞ‡+V´é—úa«Ÿ&Wÿ +ÓqÄi®;“Ç@–%ÔZÖ™Ìÿèj"I$ÐîOw÷·®×çŠvÇ“ž‘Ýküor7žÜÝŒ{}ç,ïÞüûú·É`ä[é £¿Rt¿y¸Þ}øÏ¨ðpï/ÃÁhp3èý5ùùj0©’QÚ»úã/Ú™ÃX¾¢D8«:¯pB sŽw–WR ¢¤å•ÅÕøêc%0¸›wm‚&)#Œ+Ñé K¤Rv÷cý#(<¶8dŒ8¥Þ>µÏ¨# þƒ‰€!Q©L5œÁ˜"ÒšŽQŽhÁE>ã‡ë‡Mö"´A{Àb”4ðlx÷4òÓôpí¾m¢u¥þ$’Œ¼E ºÉ>³Öì´Ñ +i‰;‚q Î PJBU-¥!ÚÔ‡Ô' 4»d€‚&”h(1œ¹œËõ§áh};ʱ?Z÷˜íF2Í¢ù|^/yéø8´´”·àã‚­í¾c ðx|^—ŒZÂyÛê1–1í™ü ã»;š^­ÖÃÓN®ÝOO;G¬Òr‹Þ1¶w4½P¯óâcgÅg%L¶Ä^m q”ùØûéq=ÞÌfQš¶òûï*‰<µl=MÒÇhýŽaFPb4ßK4Põ’ Òp"”kYÎÚ(â¤f%Ñá4^œç#ˆÛË2Pò\,ëô±-Å>†š7ùèßëU*´#BL§Ï4³&Ìcßå³Ü@k‡é’œpÅw„þ2ÙÖ8½Bòª +`Dô`Ò)$êQºZ¼”S1ΦYœfñ¬˜ˆ›Õ&É¢uúv&4#FÝQÖå¸9(—‚HÍ£ÖØ©Ô‚žq”#ê+y¦0A]å¢ÚBÕ¨,ƒè"‹lôûòójуÉp<¯lA³¸.¸äÝÛ(­ãç,^%ïj" +ëÄAj>û´á 7ª…ú!„´"Úî²¹ŠX4×Ö§›!çþŽ¡\)­»ãáëücƒ»`hMÔÉwÁ¿=e¯Ê!;'B(Z 7¼!ø;Á„ ê£êãÊ]°J8j%( +ëÓNpuÏ«$Ъ$Õ¦;c„>LyixiÅ/ ѪæYkzÁ8!îX¦m Oî˜ +¹ÍSÇSŸÊ3Põ‚—83ÄjfZ€rF$„òœÍý§Û‡_¯ïî!b©º#8oZw:‚` Û›$…$“jÕBréD‰#܇ü}ØSª{}÷ ¦²²;Ú‘Ÿ¾A‰½¡ôÆQì}Ò@ÙËE +  k ÝÒ¢„ñ¡{ø0úu+»/s›Öëv’U§Ã†ª]÷9t @«ˆ²Üî‡ì)ZµÕ­‘±îè „y70ZçWë£Üd¨ê[¤¡„JÖÂÓ¢¹ña|p{?¦‡-hlú'U”¬΃¾×U榈B{0Ö +^0E…¯yTKô†‚@éì£÷¯qºœf³'0J§ vßnžßu¯“Bx¨ïS•Êfª[¨J¨Ø™ñÅõ¤Ç`…¯7ÉlšEóvž“žCf¶[ö8‘«×øÂ;DÂŒj ìRb4÷ý—é2êõ E÷™·’õ=ݪnïÇãÁ§ö2]Äó ˜z!{A*^î²çŽBõ-Z‚>$wDPʶ@>|=áî>*†¡vçbÈq¸Öé{ˆÝ !%²µ0´œ)ÝÃûèË1t[M‘•âõ$/Ò_"5N°¨ ší~SÞ:ÁàNãõCͲ++[Ü,W–H!õÖ æc÷Ùq›G t;› †(wÜÛ’²Ë.„Lp–¬ÍHM¤q>T}\ÏßøL&Ir@uY}¨”̰€:,›~Î )¬Ý_Cúb}“Ì‹P\GP.¤þ÷¤G=aàÁ¸ÿ—ÛÓ(åÑK)^ד&‹L!zmÃr‰_ʈBÙæ)XÁPZû&és4‹±Dµ „w³§”¿ëz ržW¤xÿq šþ*€©î]âû¡T¸/¬9ë¶«ÓÔ÷ÄgHƒ#}?ü`Á†cms&I¡-çœ(íØ!q⬵͟õ+‰ýPä{ûÜh&ë'£†¬²„DZrþÙ0HM˜•r÷• ð4~Æ1–ÛÆøaž·‡ÈÛ‡å ˜!Mƒe` ’ÚÝ£Å×~ ºœo´¥Ä¶Ñ:M¥n{¸Ë†áZüøÖlׯ©Ñ›nö™´Æ/& ß M'´;€Jb ia¹2ÛâšCK·§~s0²-çTøÞM6ËÏøS€›@¯†×ªðäõi•Fþ~è ýÍi¹=†'Ÿ£ì5Š’&ŸW|º®"ÖXXKŒÍ„;ÜBb?Ù¬Œ¦j… +¢ßû%>F8D¢m|, ž›âw–åär’Ùb“B¾TI}2o2@C´¤l÷ +”ÖLÌÁ²æôXJì‡"›ü 6p\5Ûe€ +Ú1Œ>úß»Ñ/ãÅ"N£D,ÜÏTv‡¸9‹÷ªÀäÑTšmèéô+Zš¦ÞPu¾ëþ%q­àÂkñwaÀL¢&O'aBµÑ»ž £Ðêtc,%öC‘ ƈ5±Õªf¨!mtuªn'ã ?ƒ§¿q¥ÝÉSqa1M3Ï•i…ÙÛŽøQ’¿iVtÓ§Õf1ÇcéåÁ5¿ÆŸ‹TGEƒiÚÈW^‡&¾_o«3¹‚w;ßBb?ÙÄÖ¬òúÉy(ùGÓB†\ºÊ(!–@Wð„1în ’e4M +ÿвÀ7ùW(*ÿ +Ügp-øÈÓ”þ¯oûW¼YùW¼ yÙtá¯û7ø­Iñ? ?o2Ò÷sÁ Âf RNJì¾Ý˜§¢Ø$¾Ÿ n Õ±ÕSwEtPviJÛžcWÖ'Ö,u!tø¯Îÿù> endobj -1606 0 obj << -/D [1604 0 R /XYZ 85.0394 794.5015 null] ->> endobj -562 0 obj << -/D [1604 0 R /XYZ 85.0394 477.8665 null] ->> endobj -1610 0 obj << -/D [1604 0 R /XYZ 85.0394 450.2752 null] ->> endobj -1603 0 obj << -/Font << /F37 799 0 R /F39 895 0 R /F11 1384 0 R /F21 710 0 R /F23 734 0 R /F65 1609 0 R >> -/ProcSet [ /PDF /Text ] +/Parent 1609 0 R >> endobj 1614 0 obj << +/D [1612 0 R /XYZ 56.6929 794.5015 null] +>> endobj +558 0 obj << +/D [1612 0 R /XYZ 56.6929 627.067 null] +>> endobj +1615 0 obj << +/D [1612 0 R /XYZ 56.6929 601.9463 null] +>> endobj +1616 0 obj << +/D [1612 0 R /XYZ 56.6929 601.9463 null] +>> endobj +1617 0 obj << +/D [1612 0 R /XYZ 56.6929 589.9912 null] +>> endobj +1611 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1620 0 obj << +/Length 2375 +/Filter /FlateDecode +>> +stream +xÚÍZmoÛ8þž_áP³|ÁhÝd× l’&.p‡Ýý ÈJ#œcy-;Ùþû¾É”-ÛIëäb‘Î3Ï ‡‘†?ÒÓafxOŽ&¢—?œàÞWx÷Ó 4ƒH4H©>ŽOÞŸ3Õ3ÈH*{㻄—FXkÒO~ëþp5>»>Pû„Äý£‹O¾ÇøŸáåÅùè§/×NïG—¾ûúìüìúìbxv:0FSÏaìÍØ +#oÆ£áÍéã_NÎÆÍÒEÌììÿ<ùíÜ›ÀZ9Áˆ-zOÐÀˆC{'\0$8c±gzrsò¹a˜¼uC»”&˜FBSÕ¡5Jº´& ’Œ2§5»P‚øé€` +¬òÿK¿ÚÑû˰ìe¶,ëe™×A…Õj¶,µ]<ˆ`‰ÜPŽ 'Ü1ìˆ ììC°³í<²s­lqJt¿ðIñ;ÆtVL|s^,‹„ïòÛ¼¨ßÁÌ0í?Ý—ù}›Ÿcª + ‘JZõÙ9~ùtÅ;VB „D¢ß±À@ø~tõÈᙼëà+€-3bÍV¾„­ÜÅvÀ‰@Œ)Ý‚ŒÔ »§­bJ%üpÿ´¢ÀG®ò%\峸~™•uq¤HªÂÒ ¨æýOÕCVÎ<ó5¬ŸÍ&R AJËÀáüÓS¶óo â )¥x"ɨöªyá æžW˺œ¾±¼wøé ÃHܘÀœºqѨ&«ia' aƒQÙÍì éx8Š»j:­žÊÙ×ПÝN:Iº$¢ÀÓÁ‡ÃdÿÙ±j0×Qoãÿ\u°¡qÉY úW‡RF Ø(Ç{ËÜÿÔÅÌéfùÙ¦KµyQ-ýûl:õ/×ÎìFGgv4Y9«†8AÒB²6¬ïª…2#ND_ÿ‡.þÊ‹ù²¬f!*%²pV-Eᱜ…±÷áݤ¨óEé†úcŠémsÂâp#5CRÒg…sÆ5RXm„óï'‚×:Ú9?¯ðG´Y šE ¤"V&Yo±&…8fLô¤(Êôo·FrCûŸEn¨ŽÃ^£@e½TÈMܪˆÁfÈaÈìÝ\·XÆ»uÁÁ©l0Šºhûd£ É CÄÙëšê{\s§ƒ_Btêp_È ”¡&ݬãIâxÏ*Ï‹º¾[M§ßNaãéƒçrÌúãû²öÁcýÐ2°˜9dž‡l>Ÿ–ç±¸í©¹seïZÕÚÅ:¶Š„¤ä9Qš3Wä£ÌNX%öú1 ¼.¬€Bk)ÁŠÄ©¦o «sÈ¡e‰Va_€¨M¿ºƒ_‚ÎÜ~f;ÃŽjá¥u€—%jàe‰ÊÀÁÁ˾ý»Â+±Û±àõÜR0ÂÁ HA”yKx §U]¼ lys;d²Ç(Éjµ•¼‚Q„ÕÚãÅ£`fq«ÞÒ(ËÙä;|ÞÇú¼ý½!‡ÅkŸße²TÇ59ªÉ´F˜²˜€Ó†ÄêM7ÿa5›ý År`QäËm­¿³›)‰°‡26¡ ’‚ò·6ÚAƒ ƒYšóKQÛ#aYßǃKGê¶Ód‰2Že3&ì€/ÙãˆÝ6ãpæÄøÐ~%¤BÒ¨7M‡>äö4ù®&w®&ëgމó4Û]Îòê¡iåÁ}Ûsøsv÷θ™…p—C’¾ÏÒ¡û}–N˜O£bÆ/\ÆýÝ#ùú¦ªûr†JÕÓ}ýB4ðá‡S¯QÁYûþÄæ÷€:AË!ðuA9œ ùÁ@Ä<õö >èQƒSÉT‚ÓÚvè&](rê6]®¨kWÓ®|úoníCŠ[Û¶¸u¿;pkï´Ù[À6–r/n)lä¬ÑÒÑq›âX¸}…³)×üÐÙ”òMƒñM1›œ-ki ˆVöº‘)æ®ú˜âÍ•¡í«—‚ãê"s¸ÐJã!^­©ÊF[϶è<—Öój6©›ƒéöJ8¬•šxõ}Ó½J'"jm}ãó¶¦ +1Iš<Þµ:k 7¦Ð»ššþXÇÛWˆ¬œs$„9PE¶doÐë"|)@)öµuªæNú<Öò¢|,üËN©á1pãóéjR„V±æÞTŸÿ«àö~ÍØ¿ñ÷ßÊßñ7¿Ô6¼zͼ²‘»t×å“¶Ho¿…«øp±>þz’Û8Uß|€ý$ûºç&1ý±B躀úÿ¸Â'Ò ¦*ªVíJîVE—a‰45Êÿ€\Óý]¦Á;%3IAW„‚î°z˜ƒÍoËi¹ Öy*—a³“iMÀĬ!·BLËO4„ÆÝU¬l®‰%“íºð¯UmÃ3¥­b0£$©Ù·Ëû,Ð=±¼c©Ö¥$÷²œuMÛ˜)Åþ˜ÉÀ””®×cÙe-QÓº +S]ÍçÕÂùÇN¡ Ç9£/j‚Р€ú¾zš5‚bRql£œÝVñ¦ÔêĆ {·ús‘VĶÊc±lv[­Bu­A‹xi°.ãá`W;«aø|^d‹­J[½1¡ÍÏ$0„lMz#¢Áß‚¢AJµÇ "• ÐçO“ëw7öÿVUOÀ¸Ø+¼¡êÞª¢J˜%Uº-~ì5À¸L ­5´¸·àЛ" š·Ež­êΠظËny^@”À xNª"L!HýlRÍÃ\m4¼tTû‘² ½ðèUwÕÂgI¨àÀ(°icó)[¸ëÂŽIJ gq[Îê®ÕBšn$yQÒ`ZNvbŽ*û9…dû1—RíÆ\Cå0÷áßçÛh#÷%æûÅ6Tr[hƒ Ê`Kh ùÀíD2vfîøV6å”­‚øúüg[ŸWÅ¢ŒÑ¡ö'ÁÝÊ´Ù.×8¥Ú£ÌHå”9ú¼¥J8Wq{´Û+´¡êÚþüT®•i‹=®*¯ÃõÎ3uiË4‹ºL¨öè2R9]^Ηõ60JÂföûÄ6Tr[Ú´µ·Ðf³‰$ñÏÕvÇ?È¢@ ê%!Áī؛·öÄd#…¬µJ¿/Ù²µÍƒu2Ÿfùv>ÛìM1ÆH—Šqïàåøs¿\=i‹Zï"Mrgå´Ä6çÞ|UØ1ùÿ¥@ÆWendstream +endobj +1619 0 obj << +/Type /Page +/Contents 1620 0 R +/Resources 1618 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1609 0 R +>> endobj +1621 0 obj << +/D [1619 0 R /XYZ 85.0394 794.5015 null] +>> endobj +562 0 obj << +/D [1619 0 R /XYZ 85.0394 769.5949 null] +>> endobj +1622 0 obj << +/D [1619 0 R /XYZ 85.0394 752.4444 null] +>> endobj +1623 0 obj << +/D [1619 0 R /XYZ 85.0394 696.016 null] +>> endobj +1624 0 obj << +/D [1619 0 R /XYZ 85.0394 684.0608 null] +>> endobj +566 0 obj << +/D [1619 0 R /XYZ 85.0394 401.8966 null] +>> endobj +1628 0 obj << +/D [1619 0 R /XYZ 85.0394 374.3052 null] +>> endobj +1618 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F11 1400 0 R /F39 900 0 R /F67 1627 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1631 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj -1613 0 obj << +1630 0 obj << /Type /Page -/Contents 1614 0 R -/Resources 1612 0 R +/Contents 1631 0 R +/Resources 1629 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1611 0 R +/Parent 1609 0 R >> endobj -1615 0 obj << -/D [1613 0 R /XYZ 56.6929 794.5015 null] +1632 0 obj << +/D [1630 0 R /XYZ 56.6929 794.5015 null] >> endobj -1612 0 obj << +1629 0 obj << /ProcSet [ /PDF ] >> endobj -1618 0 obj << +1635 0 obj << /Length 1321 /Filter /FlateDecode >> @@ -7106,141 +7201,147 @@ xÚ•WK [#y¿ÒÛ¾­T×Þ#o: ^‹²DjUêüÉß?<ÑŒ¦8ik™O^]Þ+©¡¦j”uæúáÓ·+àæ\c®÷{]ìyZ¿­¨üv­763­6Œ$[„-Sæþ,þ¼8ý× Ç‰iÐa2>DHìo‘>¢(=›GçëpÌÅ^Ä´obS~¢:’ÈÔŠeÑè—Š™âÑ] c‹ñß%# ãó"7Mß»Øä~n".îª.!Ø.G|€°q"o°t®†viӭ߯Tó¸x}>,vøJìïèÐAãÛ¤_uïÑ“ûå‘!“F]°£‹Ò©•Þô«&?an¸jÔñÝqŠ8dùU›@§>?½Hp”ÁoÏÑ#4¦;e‰;×6|É^ªûaáŸendstream -endobj -1617 0 obj << -/Type /Page -/Contents 1618 0 R -/Resources 1616 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1611 0 R ->> endobj -1619 0 obj << -/D [1617 0 R /XYZ 85.0394 794.5015 null] ->> endobj -566 0 obj << -/D [1617 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1620 0 obj << -/D [1617 0 R /XYZ 85.0394 573.0962 null] ->> endobj -570 0 obj << -/D [1617 0 R /XYZ 85.0394 573.0962 null] ->> endobj -1621 0 obj << -/D [1617 0 R /XYZ 85.0394 542.127 null] ->> endobj -1616 0 obj << -/Font << /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1624 0 obj << -/Length 3449 -/Filter /FlateDecode ->> -stream -xÚ¥ZmoÛFþî_¡o'Å}á[q8ÀMœÖm‘ôwEÛIK¼P¤BRvÕ_3;³+R¢ëEÑh9»œÝ×g†3þ³ ôÂD&³(Ñ^à‹`–í®üÙæ¾»¼fa-†«¾]]-ß©h–xI(ÃÙêqÀ+öü8³Uþë<ò¤wýûê‡å»0¬•¾HìqÍ›ï?~ø°¢U#Ž:ö´ˆ%/»}ÿvŠSèI%4¯ùt·z¸;ÁJ8”V¡ÛòöçÕÝÇë… |8ã5ÜÑŸ{;JB?ŸîÞ<|¼_ýBOo>¼ÿtÿöîãíu¤ç«{xÂ}®îVNRCi -_¡˜¾\ýú»?ËA¨?\ùžJâ`ö ¾'’DÎvW:P^ •²”êêÓÕ¿ÃÁ¬yuR; „rB= á õ‰*˜B9¼kZºÜ"žôTÖM»Kû²©‰`·Í3 ú†~¿rûæ§n<µ7›¾Èz"›ïÖíSÑ¢o,ÙôÛ‚µ7T²’‹âÄjïöáÓP^ÌÙjFÕ‘'¾àµiþTvM{$öiÿ ½!Äà… -A&QÍ`&"ˆóê?ÏõjOkÍ"-<éˆôA³ŸgvôãI7ö…Åð £=Üÿ‚/îþØï¿Y.á_/=tYÑö^Ón`¼ÜÖK&-íí–·?-Àˆý9Qâù¾öòº;?¾V`d‘/GçÍ@¥—Äq*¼$(¿tû"+æLJGæL0ˆç¿I©i·‘%FÂÒ‡E?q boaøÖÍžâ!r‡ð8qu±qÅüfî¦í{Iâ2äžÐ—óÕ•¬³´¦ý¶Eµ§Q¹ãXúÄ—ëŽ]_ìh²+²C[öGzZižJ3'²Éϟ’LÁw=8Jde*Ý•;0òuó9D?oËlËòªhT•»²?En3ÈÓ]º±ã¦¶)å‘g”hŠGÖØ{îÊ®È n@WÆäÛºðEm’ÏãO¢Åü±HûƒËaÚ'Ç€ :Øû€„;‹yGÙ ž›GZÁ^s$m/„t]VFȆÚЯóÈá6yZì,ã”Ù¤ü|¨÷mùTVņ,ÃÜn y¸ËfÂ|%D$¢`ó=Ð’`d¾˜LëO†ã¥ jÒÎ Ð×À •ðçÿ¹N¤Ýa³):Ö.]µ&ßG5v62ÞÌ"ƒÖZNaWuŽÁtðQùFÄ£à1åC“‘´¨o {ƒðQ*ÇÆó}a D‰Äè¿ÁoñGºÛW< ¶¸3qª²f2jÞPš”çØ·€mÉ|Ò©{)‰V_q¯$H¬~Ù o&jåùÒ·ü–Oi»|)Þ€reÙ¥àÍJ…sw7{#¶åÉ ı:j(¥pšœa/ò!Ÿ~d+‘¾dl¦ã6ã÷Fš\ºvY5YZ-»uYóÝ!’úèæø1¡§ß ! ê)e«Â7•­[çþ•lÙÜa‚ää8 0QA8âLCKH!Æþr¼²–¡É"†>e2!ÀX)Ä«† \¶½HÛÈeÛ=7íg¢p˜Ýmu¤¹²¶'¡iÛ—Ù¡Jù¤9q(o 4.Áå.À¾s3²˜Iì@ˆQ‚µå…Ap–Ð_²bÀSq%ƒ…–I¬*(§QVÂQ] 1àÈX7&Ì¢§ÁSjʉðB`æ­mÊ£²ÎªC^pj. qû-çÕxWqÇn¼%9”IïzþŽóÝÜÞeä8ÈìU“`iÎÆgržÊâƒó”ˆAu$¾&„Ò‹‚ÈÎ’÷#Ôäc˜'„Hd»7å6üæû²*}ÀÍtÏÁC¡ -pžUŒHæå†~Óü‡®?Ûï)­Eçv#Pb\ ƒ±x}uv|.£Kç‰àš2´ëe˨¤ËÐF\ ‹6ñÔIhû2_ ¦Ü1ðÂ8< ri–5‡šÇ£-¹Á:Ïâ0ˆÑâ,[=Ô|MÏe¿%(Q¤mU2@¦c©h6 ¢%ÝÐÐ8‡,Ç} Ѳ:Z~ ¨‰‚AÃñaÏ_OFk"—OXш€!Œ+«´ÈàU|¬ sA×§ýðäuÓZ|St ,à!`ÇAx–‹¶)…-õ¦;÷‚q±)DØŒ»Ì‹§åŸEÛLAåE‰k´M…°LYµà+ÐÎCL!Féט©!³ªÙ¼ÐÉ‘~tB.¶úžÆšðó,úŒàA_î¦Ü4Vè¦ÒÕ`€lJy" -c  lSàa g¹°1øÇŒßq1ûW¸þÜ–M;t#9FÜ\`\ºTâ{ -ïq©Ä:U(&B(nàÁ~Óü#¨&¤<´Ô€Éú6ˆzW+ 앲mZo -K7ÔÐ!>]Ç%“i®q×ä%.ÊleÚìl$"Œ”>Ïí_Va](϶Íó”v”ôª‹ûpafãºóI§ýœµ6÷YÚm(¨X.sîr ¬œaÇÔAéMi©M(§¶µ[ß–=UBSÝiRÓ‰ ¾ª=-@ `´Éþ1„˜ ×yÑ{>ðâ¡}㬕è>2HÓ¿…vП%€…°ZÁÉd(Iåï: B ¦åÊ•ˆ‡‰ù -þ•󻋾®ôüHFPƒqHˆƒ°õìËLx¾NE‹csד ay¿“³· Üh6¸”e¼r6—‚Ø3pâÐJûǰM,cºSÓ¤-…6QˆÂ¦ŽoL’½ˆ£Í ˜ lù csïè¬U.ö %53ŠP3w¢F}ê0¸uh¬ÏþÑÓ€púÖó÷¼sìRP¨ë“KšßvôÑHÅyNq–{{S*3 --û<í ÛþæÎã« ð[ðJ(n8(®„œç–?RÌÇiÆŸºms¨r¯ùUÐ8(»â¦‰ÚZ€«šš©0ã 'ÀŒS˜ñ—óàT0WWÇ©ݳl‰âºFÏ󆟷TM½›æÖiGU¢øžh[J©ùýÏDHóœ0jÇ/QÑ¥ìJ=ß6T6)¤Å¨˜V—‘änØ¿øUé–jêÕ½°õ⤬…^ÖSç@P™^ <Tü×”Ãÿ ºé¶ñ‹ßÀ£Äâ-€íÍó‚U=Y£Æ±‹cr 9æ¹ -¸aŽä]Ño›œÁ4(Ð8Ý'Mpt(å‹ÓÍꮡ%vb¬ ÜññÔ'W!T.#S`>±3Z?¼EéØBÉ>>ˆÝ±Š´+M!Ð'Økc Bàü¶ê–xÓ»£¦–Åãèðiq|è‚·1ò¥>lL¦ð¢fT¢<)4|E3 ·|¢6‡mL#ÉtLè ƒ±d`¬'è§«Ò'^ê¾ `ÇŠv¤ÀÞŠ?KwD€á3•w\„ ¸º‚tó­M‰Ó‘v)Ôcí”ágÔÔ¦0#pZlms -ä´ïQ·9M®™Ú¹j0°n¨ih†gÖe`n}Cc‡ñ”û¼¢‡w¤)úØ2ÁŠoÃï›fA€»©† —ìÈ|¶)ÿÜ ¦OµÎiÓöL÷ƒoUåöö£¸é(†¡3O|ã1” |c>Á@‡¾´ƒØ!Ó~A‹0ë›þÝÆä·;ø…érN¡œ5ÐÚ¹gíqß7›6Ýom¯§Óœ ÆöC_0£5ï±+ÒzZ¶h‚2{¨»4cÇñsÓ¦vŸ):Z„ÅÄêÓýwü—­Èãa²4&ê—bjzZ»Òìõ˜šçæÎaa›WqsLD5éç#ÚçâHƒ|WÌwè”tÌÀv‹°°M Zž©°-[çØúhiìŸ&ÇŸº­Àà@ŒåSçBØ®€³IlàLT}ÐH¨lCÄ´Ø7U™§[Aä>Ñ:iGàÁúTñå/—ZPi)5õG ¾«iþö pÀ<ŠŒ³=öt LøPx³D_œÜþ5ÑåÑÿk$§/endstream -endobj -1623 0 obj << -/Type /Page -/Contents 1624 0 R -/Resources 1622 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1611 0 R -/Annots [ 1629 0 R ] ->> endobj -1629 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[0 1 1] -/Rect [63.4454 738.9144 452.088 749.0762] -/Subtype/Link/A<> ->> endobj -1625 0 obj << -/D [1623 0 R /XYZ 56.6929 794.5015 null] ->> endobj -574 0 obj << -/D [1623 0 R /XYZ 56.6929 723.0302 null] ->> endobj -1630 0 obj << -/D [1623 0 R /XYZ 56.6929 689.3491 null] ->> endobj -578 0 obj << -/D [1623 0 R /XYZ 56.6929 552.677 null] ->> endobj -1631 0 obj << -/D [1623 0 R /XYZ 56.6929 525.9649 null] ->> endobj -582 0 obj << -/D [1623 0 R /XYZ 56.6929 411.5673 null] ->> endobj -1632 0 obj << -/D [1623 0 R /XYZ 56.6929 383.9327 null] ->> endobj -586 0 obj << -/D [1623 0 R /XYZ 56.6929 225.6356 null] ->> endobj -1316 0 obj << -/D [1623 0 R /XYZ 56.6929 193.4614 null] ->> endobj -1622 0 obj << -/Font << /F37 799 0 R /F69 1628 0 R /F23 734 0 R /F39 895 0 R /F11 1384 0 R /F41 935 0 R /F21 710 0 R /F53 1027 0 R /F48 950 0 R /F62 1060 0 R /F63 1063 0 R >> -/XObject << /Im2 1049 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1635 0 obj << -/Length 533 -/Filter /FlateDecode ->> -stream -xÚ¥TM›0½ó+|©¸6Æ`³IÚ²RÓ4a«ÕxT‚Ó@6Úýõµ3·¶ôTEóÆoÞ|x€"b~ Ž “1JeŒ9¡•[ µ9ûêQÇ Ï¤ð–u—{Ÿ¿°I,“(AùË–ÀDŠòêÉÍóé"#Nü!Oˆ—Í&à‘ðXNÇ‹,4þ1[f“éb¤±Ÿga,ˆ0ñÌ)Lg£ïÙøó P§Ôžó{oš_¹m–f»øí==T™žï=‚™ ˜J¡­s†yÌØÙÓxKïçEðæô:4<Îæ"J¦±¡éq‰fŽìô–z«lO‰ßÕ½êÀ,7ZwÎÝkûäþ/¥và)šŒê­-¶uið[xØUE¯*8˜ØyžE_€U· ã`wXUz[€×H¶.²RZ!—{Sô7üÐŽÛôRŠ%çÑ©'ÂTÊä)…Ú{2è]·ÊÜ,#‰Ÿoê˜Çâ- ”úŸ Œ‰I§Àßë]بWÕ\cÁ*uÛ›|u»vx_÷v溵¹å¬Â¥rÚÂÏæî ªö¾ê:å8úe¨ÁÝaÕÔ%ìÝQ­Àp#¶ý¬Ní_Õ¾Ð*å­î]HÓè#˜îâÀÍ9Ε‹ÿµÛŒc»›hþ®îÿÞûë!6¯¤ÑðJ›ëÄ"’é¹(;/É?V~yAþ.ýÑFÎendstream +ÝÿîÇåðqé?á•h>@§>?½Hp”ÁoÏÑ#4¦;e‰?×6|É^ªûaZá¡endstream endobj 1634 0 obj << /Type /Page /Contents 1635 0 R /Resources 1633 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1611 0 R +/Parent 1609 0 R >> endobj 1636 0 obj << /D [1634 0 R /XYZ 85.0394 794.5015 null] >> endobj +570 0 obj << +/D [1634 0 R /XYZ 85.0394 769.5949 null] +>> endobj +1637 0 obj << +/D [1634 0 R /XYZ 85.0394 573.0962 null] +>> endobj +574 0 obj << +/D [1634 0 R /XYZ 85.0394 573.0962 null] +>> endobj +1638 0 obj << +/D [1634 0 R /XYZ 85.0394 542.127 null] +>> endobj 1633 0 obj << -/Font << /F37 799 0 R /F23 734 0 R >> +/Font << /F21 714 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj +1641 0 obj << +/Length 3450 +/Filter /FlateDecode +>> +stream +xÚ¥ZmoÛFþî_¡o'Å}á[q8ÀMœÖm‘ôwEÛIK¼P¤BRvÕ_3;³+R¢ëEÑh9»œ—g†3þ³ ôÂD&³(Ñ^à‹`–í®üÙæ¾»¼fa-†«¾]]-ß©h–xI(ÃÙêqÀ+öü8³Uþë<ò¤wýûê‡å»H ÖJß ¤ö¸æÍ÷?|XѪG{ZÄ’—ݾ;Å)ô¤š×|º[=Ü¿`%¥Uè¶¼ýyu÷ñz!d¼†3úóoïaCIèçÓÝ›‡÷«_èé͇÷ŸîßÞ}¼½Žô|uO¸ÏÕÝÊij¨Má+TÓ—«_÷g9(õ‡+ßSIÌžáÁ÷D’ÈÙîJÊ ´R–R]}ºú·c8˜5¯NÞŽðA¡œ¸ÐðÄõ‰*˜B=¼kZ:Ü"žôTÖM»Kû²©‰`·Í3 ú†~¿rûæ§n<µ7›¾Èz"›ïÖíSÑ¢o,ÙôÛ‚o/È®¤ð¢8±·wûðé \^ÌÙjFÕ‘'¾àµiþTvM{$öiÿ ½!†6´P!è$J¢ÙÌDQ`^ýçùý†ÚÓZD³H OG:¢û ÙÏ3;úñt7ö…Åð s5z¸ÿ_Üý±ß³\¿^zè²¢í½¦ÝÀx¹?¬—LZÚÓ-oZ€ûs0¢Äó}íåuw.¾V`d‘/Gò¿f ÒKâ8ž6Ï…ãøÊÁ„A­Éø€ys)a îð’B½®Â÷Áù·mÓ°§uÎñ¡èe>a‚þl!ñ2¤è=q0xÿ_…ìZ¢çeOÔ²£uû¦ëÊuUÕøPÛëx~¨‰Æ¡ +¨%óN'ÜFŠÈÃÛ!Oȶäà‘S2«Ð ’È..ê§’–×»¢îißüÀ?te½aÁ¬¯Ê¡Ö…z±vÁ=3ŠÃ7á1µoìÉÐOxùã¡Î0ì˜ÅfÓõ_ÂJ<íK >*¼$(¿tû"+F&¥## âùoRjÚmd‰‘ð„tÁaÑODì­" úÙSñáºc×;šìŠìЖý‘žÖGZ±¯ÒÌ)…¬ÅpbùSÒ)ø®¢DV§Ò¹#_7àCôó¶Ì¶<,«ŠFU¹+ûSä6ƒ<Ý¥;nj›RÙyF€¦8qd=ç®ìŠÜàt¥aL¾­Ø_Ô&ù<P-æEÚ\Ó>9L\@`ïî,æe7xni{PŒHÚ +麬Œ’ µ¡_ç‘Ãmò´ØYÆ)³IùùPïÛò©¬Š Y†9Ý@óp Ö :Ì„ùJˆH +TÁæ{ %ÁÈ|1™ÖŸ ÇKÔ¤ ¯*áÏÿsH ºÃfSt|»tÔš|¯±³±qÀðd´Ör +»ªs ¦ƒ‡ŒÈ7")žŒ¤E}ƒ»÷8X¥âpl<ßÖ@”HÌã¯ñ7ø-þHwûŠ'Áw&ÎãCUÖLÆ›7”&å9ö-`[2Ÿtê\ +F¢ÕWœ+ {¿ì„7 µò|é[~˧´]¾oàreÙ¥àÍJ…sw6{"¶åÉ ı:j(¥pšœa/ò!Ÿ~d+‘¾dl¦ã6ã÷F7¹àd:ˆç¿ Px8ÏWŒè +ÌË ý¦ùÿ]¶ßSZŠÎíF $ĸcõúê,ìø\ F—ÎÁ1eh5ÖË–;Q-*H—¡¸' mâ©“Òöe¾ EL¹cà…qxäÒ,k5ŽG[rƒ!užÅa£ÅY¶z¨ù˜žË~KP¢HÛª$d€LÇZÑl*@EKº¡¡qYŽû¢eu´üà¢& + â'ÂÊ_OFk"—Oø¢1*BWV/ÜJ ƒWñ±‚JÌ]ŸöCÉ릵ø¦èXÀCÀŽƒð,mS +[(a„y|ݦmi .FÌb"1Î…Çh·ÏD±ž€À(‰çß7ÏÅ eGÅ÷EžõòŮɯ ;UK>cö*è^€ºK´šõt9‚†ÂæUΘ{g>õ¦;÷‚q±)DØŒ»Ì‹§åŸEÛLAåE‰k´M…°LYµà+ÐÎCL!Féט©!³ªÙ¼ÐÉ‘~tB.¶úžÆšðó,úŒàA_î¦Ü4Vè¦ÒÕ`€lJy" +c  lSàa g¹°1øÇŒßq1ûW¸þÜ–M;t#9FÜ\`\ºTâ{ +ïq©Ä:U(&B(nàÁ~Óü#¨&¤<´Ô€É.*ôm=ô®V&Ø#eÛ´Þ–n"¨¡C|,ºŽK&Ó\â®ÉK\”Ù6$ên³³}Ð ¨0RúÁ@‡¾´ƒØ!Ó~A‹0ë›þÝÆä·;ø…érN¡œ5ÐÚ¹gíqß7›6Ýom¯§ÓHPcû¡/˜Ñš÷Øi=­[4A™=ÔÇ]š±c„ø¹iS»Ï-Âbbõéþ;þƒËVäñ0Y“ õK15 =­]iözLM„ssç°°Í«¸9¦ ¢šôG|Dû\iPƒ/‚ãŠù’Ä l· Û¢åù—Ú Û²uŽ­™ÆþùHarLÑñ÷©Û + ÔX> ŸÂvœMbg¢êÓ€FBe‚¤¦Å¾©Êì8ÝÂ"÷‰ÖiË8Ö§Š/¹Ô‚JK©©?bð]Mó·ÿHè„óæ©xPdœÕè±§c`ÂBáÉ’ðBrû×D—¢ÿ\æ§#endstream +endobj +1640 0 obj << +/Type /Page +/Contents 1641 0 R +/Resources 1639 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1609 0 R +/Annots [ 1646 0 R ] +>> endobj +1646 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [63.4454 738.9144 452.088 749.0762] +/Subtype/Link/A<> +>> endobj +1642 0 obj << +/D [1640 0 R /XYZ 56.6929 794.5015 null] +>> endobj +578 0 obj << +/D [1640 0 R /XYZ 56.6929 723.0302 null] +>> endobj +1647 0 obj << +/D [1640 0 R /XYZ 56.6929 689.3491 null] +>> endobj +582 0 obj << +/D [1640 0 R /XYZ 56.6929 552.677 null] +>> endobj +1648 0 obj << +/D [1640 0 R /XYZ 56.6929 525.9649 null] +>> endobj +586 0 obj << +/D [1640 0 R /XYZ 56.6929 411.5673 null] +>> endobj +1649 0 obj << +/D [1640 0 R /XYZ 56.6929 383.9327 null] +>> endobj +590 0 obj << +/D [1640 0 R /XYZ 56.6929 225.6356 null] +>> endobj +1333 0 obj << +/D [1640 0 R /XYZ 56.6929 193.4614 null] +>> endobj 1639 0 obj << +/Font << /F37 803 0 R /F71 1645 0 R /F23 738 0 R /F39 900 0 R /F11 1400 0 R /F41 940 0 R /F21 714 0 R /F53 1032 0 R /F48 955 0 R /F62 1065 0 R /F63 1068 0 R >> +/XObject << /Im2 1054 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1652 0 obj << +/Length 533 +/Filter /FlateDecode +>> +stream +xÚ¥TM›0½ó+|©¸6Æ`³IÚ²RÓ4a«ÕxT‚Ó@6Úýõµ3·¶ôTEóÆoÞ|x€"b~ Ž “1JeŒ9¡•[ µ9ûêQÇ Ï¤ð–u—{Ÿ¿°I,“(AùË–ÀDŠòêÉÍóé"#Nü!Oˆ—Í&à‘ðXNÇ‹,4þ1[f“éb¤±Ÿga,ˆ0ñÌ)Lg£ïÙøó P§Ôžó{oš_¹m–f»øí==T™žï=‚™ ˜J¡­s†yÌØÙÓxKïçEðæô:4<Îæ"J¦±¡éq‰fŽìô–z«lO‰ßÕ½êÀ,7ZwÎÝkûäþ/¥và)šŒê­-¶uið[xØUE¯*8˜ØyžE_€U· ã`wXUz[€×H¶.²RZ!—{Sô7üÐŽÛôRŠ%çÑ©'ÂTÊä)…Ú{2è]·ÊÜ,#‰Ÿoê˜Çâ- ”úŸ Œ‰I§Àßë]بWÕ\cÁ*uÛ›|u»vx_÷v溵¹å¬Â¥rÚÂÏæî ªö¾ê:å8úe¨ÁÝaÕÔ%ìÝQ­Àp#¶ý¬Ní_Õ¾Ð*å­î]HÓè#˜îâÀÍ9Ε‹ÿµÛŒc»›hþ®îÿÞûë!6¯¤ÑðJ›ëÄ"’é¹(;/™~¬üò‚ü]úÑžÐendstream +endobj +1651 0 obj << +/Type /Page +/Contents 1652 0 R +/Resources 1650 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1654 0 R +>> endobj +1653 0 obj << +/D [1651 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1650 0 obj << +/Font << /F37 803 0 R /F23 738 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1657 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj -1638 0 obj << +1656 0 obj << /Type /Page -/Contents 1639 0 R -/Resources 1637 0 R +/Contents 1657 0 R +/Resources 1655 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1611 0 R +/Parent 1654 0 R >> endobj -1640 0 obj << -/D [1638 0 R /XYZ 56.6929 794.5015 null] +1658 0 obj << +/D [1656 0 R /XYZ 56.6929 794.5015 null] >> endobj -1637 0 obj << +1655 0 obj << /ProcSet [ /PDF ] >> endobj -1643 0 obj << +1661 0 obj << /Length 1964 /Filter /FlateDecode >> @@ -7253,133 +7354,132 @@ i ­èרÚ:‰óÎÐÃBYn?z·XdÌqâd¾©Üä¤ÚNí:ørðï»QÕaáƒL·CÕMucVìâªV.Wª4 Û8Hü»Uoy)”@»Zìo+B)ˆ×­©ôD9ƒ©;B.ÊõTyåvÂ)Î6™îZds§¡ÁÓÏMí­µ°r=¶öä&vÓž®é^/yr€¡¶¯ÓP;«y Â1{9B€FãŸà{ËוÂM>p\×-ž‘7>å èWˆÌ¨WKÐÆ 5m"û¿À¥–€ã6WUŸÔž9ZØ×•å,¶VHbžþ‹'¯´=Í\¦pÀŸ'8TÃ[WyÌ#‰6Éyè5µÒÇî:4 ßál 3,•ßbÏ[œ+ªë/WF".ƒ›ËÊ?@”€/jŒu“1Ô¢+l',{_¼2ãâ•sä®ÏñÛªÊ ¿&–Bú–åç !G˜ ¥Ìrcø-мûãËü “¤%œ¡i±Iæ² —â~ÚøÑŸ/¯6³Âv¡ámÒ¥ß;»è½‡CÀê/aïoãã<,EQ^Çsór4 ÝÅpµö;[ÃïVÎy7G)JΑOü©5­¿|hW°hpk·IQ„"é5¶ÏÍŽûª‡]Ù)C™‹_Ú‘Âõ%KÄQXDñ¯oʬ±]ªÜïʽe×SX{üâññ|>‡¼+¾,}w¸ÉÀUßÄx³Q³Ô}\Wù¸·öß¶ -ߣ«ª]qöü´Þíâ³äZÄ^d{‘¡Éep …E\æÞ†Ræ·Þæ÷Í{wÿ¢BŒìendstream +ߣ«ª]qöü´Þíâ³äZÄ^d{‘¡Éep …E\æÞ†R–·Þæ÷Í{wÿ¢šŒîendstream endobj -1642 0 obj << +1660 0 obj << /Type /Page -/Contents 1643 0 R -/Resources 1641 0 R +/Contents 1661 0 R +/Resources 1659 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1652 0 R -/Annots [ 1650 0 R 1651 0 R ] +/Parent 1654 0 R +/Annots [ 1668 0 R 1669 0 R ] >> endobj -1650 0 obj << +1668 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [348.3486 128.9523 463.9152 141.0119] /Subtype/Link/A<> >> endobj -1651 0 obj << +1669 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [147.3629 116.9971 364.5484 129.0567] /Subtype/Link/A<> >> endobj -1644 0 obj << -/D [1642 0 R /XYZ 85.0394 794.5015 null] ->> endobj -590 0 obj << -/D [1642 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1645 0 obj << -/D [1642 0 R /XYZ 85.0394 576.7004 null] +1662 0 obj << +/D [1660 0 R /XYZ 85.0394 794.5015 null] >> endobj 594 0 obj << -/D [1642 0 R /XYZ 85.0394 576.7004 null] +/D [1660 0 R /XYZ 85.0394 769.5949 null] >> endobj -1646 0 obj << -/D [1642 0 R /XYZ 85.0394 548.3785 null] +1663 0 obj << +/D [1660 0 R /XYZ 85.0394 576.7004 null] >> endobj 598 0 obj << -/D [1642 0 R /XYZ 85.0394 548.3785 null] +/D [1660 0 R /XYZ 85.0394 576.7004 null] >> endobj -1647 0 obj << -/D [1642 0 R /XYZ 85.0394 518.5228 null] +1664 0 obj << +/D [1660 0 R /XYZ 85.0394 548.3785 null] >> endobj 602 0 obj << -/D [1642 0 R /XYZ 85.0394 460.6968 null] +/D [1660 0 R /XYZ 85.0394 548.3785 null] >> endobj -1648 0 obj << -/D [1642 0 R /XYZ 85.0394 425.0333 null] +1665 0 obj << +/D [1660 0 R /XYZ 85.0394 518.5228 null] >> endobj 606 0 obj << -/D [1642 0 R /XYZ 85.0394 260.2468 null] +/D [1660 0 R /XYZ 85.0394 460.6968 null] >> endobj -1649 0 obj << -/D [1642 0 R /XYZ 85.0394 224.698 null] +1666 0 obj << +/D [1660 0 R /XYZ 85.0394 425.0333 null] >> endobj -1641 0 obj << -/Font << /F21 710 0 R /F23 734 0 R /F11 1384 0 R /F41 935 0 R >> +610 0 obj << +/D [1660 0 R /XYZ 85.0394 260.2468 null] +>> endobj +1667 0 obj << +/D [1660 0 R /XYZ 85.0394 224.698 null] +>> endobj +1659 0 obj << +/Font << /F21 714 0 R /F23 738 0 R /F11 1400 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1655 0 obj << +1672 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj -1654 0 obj << +1671 0 obj << /Type /Page -/Contents 1655 0 R -/Resources 1653 0 R +/Contents 1672 0 R +/Resources 1670 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1652 0 R +/Parent 1654 0 R >> endobj -1656 0 obj << -/D [1654 0 R /XYZ 56.6929 794.5015 null] +1673 0 obj << +/D [1671 0 R /XYZ 56.6929 794.5015 null] >> endobj -1653 0 obj << +1670 0 obj << /ProcSet [ /PDF ] >> endobj -1659 0 obj << -/Length 2543 +1676 0 obj << +/Length 2544 /Filter /FlateDecode >> stream -xÚuYYsÛ8~ϯð[誑ÂûØ7[ÎádìrYÎNÕnö"! k’`ÒŠæ×O7ºyØÃ©TJ@£hôñuƒö.\øç]¤ÑÚ ²ð"ÉÂuäzÑE^½s/°öùÇ•²8T²îf²Þ:‹¢A6Ö^yƒì$Mú]·JîiøE™N·gšh&vGIƒ›û- D]°èíý \dë,öc>Ӈ˹!ë[vGÝŽ d¼ ~ø~gx©óÃuý\‰)´¶»ôyPu­êQ¬6sñ] UÓø^TLÝžM'+Éó¾mñ‰ú©3ð{YÊT÷V¯¦ß•*Òõx4ÜoEv%K>~Ú B'óÝßhÄ– -\Ó±8 ØãràÔòD3h Ä“0D,¤É[µ³:Ýê dÐ9 QÔ€EÒÔ'{)Áúrø®óɪ¢«q—µÑ$”ÄêY_ÝÔ'ÿ=>\f¾sUË"' Á_‘k/ƒ“†® -¦6pkK­é·ç÷'‘s[w²…-@Ø£åÌ­ßp,XBšÎÞ'h7ü•¿Ù*Œpv -÷Ãa…|‘¥nl Ø-H±ÈZyá6µ¨€÷ƒ( -RÜŠ1ÏuL~”6`l ¿‚~ZѨ¢<ÓCƒÚ̓ý¬j¢$¸æI·ÏÌ]¿(òAw·øYìÜÛ€eö¢ç9'ÉQ³m§Vu´:Åìe/¡P5G*@'ëR¢tGÑ­Ò…Â<x)aA· -’ r”OœBç=Á 1j"«¢ºÑpQɧUäzý"GöÄÙ G,ØÝfS6ä ÐBdz˜€z²Ó„Q™DÏ B0q¶Ah3>£Œ7«®sÙØ£FfÁ'‘«RuJãÆÕùö‘]ôçÛ/¨N‡ÝVM)gQø|$¶Ì­} 8Épat*ÌÒ¹Ã^‰©€ck ˜Ö…/ ‘úf8ùtTù‘w)Ë¥áZ½RÜ0†Oå:»^•˜Ã&Ù:v3*LO„Y‰ÅèÖt4™\a¼°[`\ÃÈÈö®ž„Ž—ÌÉAM´Ěû«„Ä„ €É,Ö£ÄvFø[vAé÷Aô´QêÜéüY4²³Álˆ†±ˆC¶ýB=ù¸!‚nÌÊw‰P‰ü¨jiˆ¯ÔàbºHêØìІ Â÷ZÁµêμûž¶ºž–Ï܈RvµïY×ÛæÕ¨äjµ¤½¬s«I˜ŒéT×wìDDåïÛÍêv{K‹<õ0Ø>Þá0(î9±Þs@ܘe·ž«„D±é Ønu»ÁƒÖÄqE?cÔq,¦…îÀ³ÆúE£ÁĘŽAÄ)ôkÙ>ËRži6”šQÑÇÑ í%"Û2R¡q¼µ2$Q†£5ÄÞÞ3Xßñ±bɾ¾Ûºù~­(z‚Hׇ î †FX³Á¿,0x,ã&þ,<^ NÖÀY_Ö# ÆÃkfÝOUÿÕ‰[¸‘{Y›åj_¼ˆ1î𥑈6Hy ÿ/óŽ#çª€Š -ã”U#7Cã@Q²€.ÿ¾ô™Ñ„K ÷yIJ­¥¥tG6µí a)\§ë€Ö&tÅŒ‚þ[år Òéú@Øèªé)ŽL½"Ÿûæ¢@ù<ópBµÙ>~æÜpËBtG‰ãÉYxEìÅbè á¥…9`°8#Û–8Ϲ6aù/3!(¬ÝˆUÐâ£:J¼TœpŠq«ëÄLM³ÿ@ÏM •($Ñì]€B‰±c€2i ?P‡nþmD4“Ç v;)*¼Q¾Ý3,$¶×`(‡æJý× éz`ê„Þw§Y1J†|%\‹B¡kùüEÙi¸U³“eÉJ}“/Ë…ü¦¯KÑX%=›4øªQÕ‘¢®óñg¯,•IJáŽg k ¥TŸ%#.Q=( ‚ש©ö¦7F ŸgàÑ[¦Ã–è@±¸ˆ$ŸægH@Ä%²ZI(Ž":ž( 6SaUŸiQc¢õFêÆ†EiX*×5ÔÏ]OÕ-ãÖXXE p³Í‚¥¢o¹‡›MÔºõÁùˆ4òK®øbðج–S€¼V(Ø&ˆ0ð[P£ ÄNg[iÝÑÒF´åêNuЧ—%KÞ©gI«w}o }U¯K­yHÝ2Ž"ÛüÁ×ý ÆŠýô3À‹¬ÉC–Påú‘?{°GÉÏæ#Sð¹c"ˆ£oë¥yó–þ®‚¸åé·žøqsˆ™Ìy™Àfá:ã¤m,ßû¶¿š°f¬…´íº¥®ÙÀoçÁâgþe5ñÐ7þùçìÀשŸ%ÃF¨g–½=mü‹Áßû j•¢Zendstream +xÚuY[sÛ¸~ï¯È[•™µ««e·Äé%í&“‰Ó³3çô<ÐmóDUQŠëýõ  ¤dµÓé˜Äå¨>ü .ÖÉÒ²ø"ÍâeâÉE^½ó/°öù]À4ºÈ–Ù*\ñ™!\ÎYß²;êþp™(ãí`ð# c8#X{?|?Ì•(‘Bk»ËÀ“Uת>Åj3¿Ñ•P5ïEÅÔíÙt²b‘<ïÛ¨o´ö­ù “êÞêÕô»Rå¢Sºކ;â­È®dÉÇO4Bìe¡ÿØR±—k:grX޼Zžˆbœ¶@< CÄBš¼U;«3ЭÎ@#%B Xd½‰ÄžAJ´¼\D¡ï}²ªèjØ%fm4‰%µú'VÁW7 É—Yè]Õ²ƒÈÉbðWâÛËड«‚© ÜÚ’pkú-Äù½ÁIâÝÖla hy'së7 –¦³7Ç Ú å¯F¶ +#œ‚Ľ;¬/²Ô »)–X+Ïܦð~EAŠC1øžÉÒŒ­‘áWÐO+U”gš€B`hC»  ŸUM”Ä×<éö™¹ëE>¨ñà–0[y÷6`™½ÞIrÔÌDÛ©U]'­N+örR¨š£  “Ωu)Qº£èˆVéBaž9^ +FXЭ‚dƒ\#åS¯ÐyOpBŒšÈª†¨n4\Tòi¹^¿È=õvÂÀ3v·Ù”¹<ƒZˆLPO–`š8I9³€øQ &ŽÀ6 CÆg”ñf±Ñu.{4ÐÈ,0ø$rUªNIƒb¼Ã°:Ý>±‹átûÕé°Ûª)å$ +£ÄÁ¶‘¹µ/!. N…Ùzê°Wâ.pl „ÓÁº°â…!R߸“OG•y—²œ ™®Õ+Å cøˆP¾·ëU é6É–+?£ÂôD˜•ZŒnMG“Ñu Æ »Æ51ŒŒl_àêiìYpɼÔ$LK­¹¿JH\ç d`L'±ž¤žÛáoAØAv¦ßÑcÐ&kïNçÏ¢‘ fC4„ˆ¹@tÙJ\ô õäã†Ovº1‹Ð'B%ò£ª¥!¾Rƒ‹é"kÏfWâ‚ßk×6ª;óî{bØêxZ>s#JÚÕJ¼g]ok˜WƒZ «Åœö²Î­&q2¦S]ß±•¿o7‹Ûí-a,òPÔÃ`ûxKl„àxàYÄzÏq?`–Ýzª6ÅÆƒ`»ÅýíZÇý QÇ0˜º£À뜉1£„Sèײ}–¥<ÓÌ•šQÑÇ‘†Èö‰m ™)€Ð8HÞÚF’‡(ÉњGboï¬ïøX1ç‡a_ßÀmý€ü ¿‡V=A¤B÷C#¬Ù`_ +¼ +–a“p¯Gkଯ ëÃá5³îǪÿêÄ- ÜȽ¬Í|µ/^ÄwxÒH‚ +D¤<ÐÎÿ—yÇ‘sU@E…ÎqÌ*Š‘×8P”Ì Ë¿/@f4áRÊ}^º¦ÖÒRº#›Úv°/×ˈÖFtÅŒ‚þ[åSr Òéú@Øèªé)ŽL½"Ÿûæ¢@ù<ñpJµÙ>~æÜpËLtGY­Fgá±[A —(-̃ÅÙ¶Ä ˜Þ°)Ëx™AaíF¼¨‚ÕáPâ¥V)§8·º>@ÌÔ4ûôÜÄP‰BÍÞ(dv P&máªëæßFD3zœ`·“¢ÂEàÛ=ÃBj{ †rh®ÔÐq½ ‘®³«zß&Å(uùJ¸8…B×ò5ø?в9Òp#ªf'Ë’•ú&_æ ùM_—¢±J6iðU£ª#E}ïãÏ^5X*‰eÃÏÖJ©>KF\¢P¯SSŒo&Œ>Ï! ·LÝ–è@±¸ˆ¤ægH@Ä9³ZI( Ž:ž()6Sq +UŸiQc¢õFêÆ†EiX*×5ÔÏ]OÕ-ãÖXXE p³Í‚¥¢o¹‡šMÔºõÁùˆ4òs®øbðج–×y­P°M”`à· FAˆ½Ž¼m¥uGKÑ–‹;ÕAŸ^–,y§ž%­Þõ½1,ôUUD¼.µæ!u[È8ˆló#_÷'k®ÿ1,°Èq‘<Äa U®ßù³{”ül>Â1¥ƒÏéD}ãX/Í›·ô(òÄ-O¿õÄ7‹›.f2ïeO˜ÅËŒ¶±|ïÛþjÄJ˜±Ò¶ë–BºfÓ„È^'Dö6!2‹Šµ>¹Õª?DZ…Ú™ðì DðFÍ\¥Pà1ª~)‰ÅïšVýØ^ .-㤎Ͱ·ÁqÏGß5p’³:ñLðÊçaAêð0xšnþ5cµN¼‡£*itUV`+c!ž¡z'[´Úzå},ÿdêUi‘دšèœ7³v«êœÈu{d¤ÌcIÀýj~ÅžXfQ‹gR`sdß׳=¥±iˆ%†zߊêÁïªÂ÷UY*»bI뎺,hùAØ7{pä‘Å?õ°–ˆV¸M¯jjK€ü­? % ÊGË _¾(XàëÿšV@%Ÿ£J4ËÝh^ý]žÔ‹f6×níƒ+LÍìS2vDN?š`®…8ä9H3ð`3zø…$ÛVÂïå4ýˆÕÕHƒ®\Büu|-Fc˜¤ë\5¢œs²knTuü×tè«ÊeÁ?Mä' ÁÙX€p†h¨k.æÍâõñkMb q‘ÌB° ƒiû†sk(ß½üdÚÿÃlhßp²ÑoC;àÐn;Õ£ž»¿¨Î…?^Uè&ŠÌ(\¹'HðêÑáC5mWp}cŒ‡XÉ„?)â’éÀ9–ÜI[(‘î¾›¨Â^5ðù©‡m7ïÍlŠR͇蕽M|1x: t´yãizaÁSBïHæ >Ëíé±³Oâ"HÓȃ…×UØNÉø©|hÑçò Å™X]ÖÌ=Î÷¯»"L1œ¬ù‹Oï×WHÎÔšæÝǧá#¾û4á·óhö3¿cYŒ<ôú9¢wEYà6B=?x{Üð'ƒ¿Ÿ÷¢nendstream endobj -1658 0 obj << +1675 0 obj << /Type /Page -/Contents 1659 0 R -/Resources 1657 0 R +/Contents 1676 0 R +/Resources 1674 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1652 0 R +/Parent 1654 0 R >> endobj -1660 0 obj << -/D [1658 0 R /XYZ 85.0394 794.5015 null] ->> endobj -610 0 obj << -/D [1658 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1661 0 obj << -/D [1658 0 R /XYZ 85.0394 573.5449 null] +1677 0 obj << +/D [1675 0 R /XYZ 85.0394 794.5015 null] >> endobj 614 0 obj << -/D [1658 0 R /XYZ 85.0394 573.5449 null] +/D [1675 0 R /XYZ 85.0394 769.5949 null] >> endobj -1662 0 obj << -/D [1658 0 R /XYZ 85.0394 539.0037 null] +1678 0 obj << +/D [1675 0 R /XYZ 85.0394 573.5449 null] >> endobj 618 0 obj << -/D [1658 0 R /XYZ 85.0394 539.0037 null] +/D [1675 0 R /XYZ 85.0394 573.5449 null] >> endobj -1663 0 obj << -/D [1658 0 R /XYZ 85.0394 510.2426 null] +1679 0 obj << +/D [1675 0 R /XYZ 85.0394 539.0037 null] >> endobj -1657 0 obj << -/Font << /F21 710 0 R /F23 734 0 R >> +622 0 obj << +/D [1675 0 R /XYZ 85.0394 539.0037 null] +>> endobj +1680 0 obj << +/D [1675 0 R /XYZ 85.0394 510.2426 null] +>> endobj +1674 0 obj << +/Font << /F21 714 0 R /F23 738 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1666 0 obj << +1683 0 obj << /Length 2810 /Filter /FlateDecode >> @@ -7391,66 +7491,66 @@ e çÑD”’-Ê:3–êv¢¡Pc^4ßL2…%æâVº³Ühò„ò4c­ô¤ˆRÊ]€Ñ–\ŠV7fžYæ¥ÇˆDJ;`XÌxäøñHÒˆ%,ëñ±ú¸ˆ0×kSìèÒØú7¥ŸMñ¬Â½³ ×j´.Þ T+(’m|ik»sPÛ` JÛ­âb¼Ý¦Õ{—BƒR)=UŽ“Ò‚hl˜gé>]aMƒ×,9DF]„e-+à¨îû–+8©¾rÑDcfÔÒh@Õ¿3zr‚ÞµRÐ4…‰HàÐNv&¦hñçTWâ †î.…}¦ÚYù°ÀÜG¶ƒˆ¤ud½˜.¦‰…ßeª5þ05…ÝÇz—Zj]4ƒ “w1Š\0húÃ|[Júó‡åã”$¤QŒ<9m» ÀDX+вI‰Nɘƒ—q€/ÖSt¯ZÈ‘ûAÃîH³ÿm!o€~½×ßt…¤ º2{Ž«@ØL…‘ú·ã£D£ú{VÕPŸïr¹Ëè{††>PKŒÀiŒZ•ÓZzhk¬I²rÆTCgl‘$Ö·aTìö¥ÚYm›šJ£²Ýb^`”–5ýv¬àdЮ&œ'à·7En¡öØ\­S('iÒi¯é·RpÕuÚ¼ž àk± ž_O…"èŠÌÖ'ãVnTFíŠÍ–Kв®¹{-‹/êªkåH½¢”¶öõ\W\å«øÊƒßä*u]Qã{µV±¸òVÒ›Hh‹ŽÎDÉ–Gaè‹ðµÆ8QF:¡ÕëÖÄÓ³2XÈܽ]†ÔÏ¡2bø;÷ßú‚ÞJtMël†xü–ÃgmÓgEhE••*>zˆÂƒ¶ÐéO¾m»Î´ë]4k~EŠÍÁ;4%¤NŠÂËëy Œ³º4†xÑÿ}uõ'ºÒÐþ˜„„/?º£ET‚2e-L^ˆç­Œ›äN)–LÊ[3ªÅBc´ÇeefΊÃÇžøL*47ÂŒºš²êªÑcßü¾‡É/ïA¶¢Þ4é~ûÚÄŽ­§ÃUaYyTiò^/¾ý""»‘Gqʶ kûèõ¡Þa€<Ž@«£¿ïqäiìØ@:ļΖ"´ZtÀɶ¡?|F0·m ~B}×Eã„Ö]ÉÞ¡M7€éæ‚Fý+¬ïÁí ½5ºÂ5æaŸ6|šq˜ÐëA¤S‘ônhaЫg#ˆV˜ilÚqø…Ë·­(„á´ª[Óà2àdƒûÚ“9òŸóv¼LZ•Ï–\'NrÓQT&1À;Þ3Y¶÷j†+~Sm vRM“—ç V¸_hvK%OÆ1e¼»YÞrîMlk‘ă,ómúOm?‹çŸ¸ÙÓ"Ñú„ôÂ@•ÒâwÖÞÊz…±rp3 ûöû\p©z»|à;Ù^Mdûu»¿º¼|yyA8….•.‹ja¬t‰­¾qý`èúÂOàZ…¶þ -Ä“N"\‹ä´_ùaEŒóŠÈ¶Å>þtâ¾%AlZv&>}ë å/3;ú±ÿîÑíX ·˜ïþðàSÊ#u UßwÈk/ùó‘ÿ8ŽŽø;úÓaò4RÆ)5äé/SyW01bŒ‰®ôÒ=<žÚ ¢¡'ñf ßµ8…¶ˆê½W¶-±O,Ý"x‹õbšé‰oi©í'ç´°OªC—íèýR­Fþ{¤²~¶¡éáÄBßñ}zÒqEðÇ^d7,†;Nè„®©ÚÞ‰T»vêfsÙ¬³ßñÜÈI\yÌÕ‘ïtX§¬ŒqJí-߉œÈ£áÏqz7!Ø$MÓ’3Ðo}ᔃŸ%'äp»Äü?ýì?s2޽é›^À 13…@î?aÝ~'=åý¿xÇðBendstream +Ä“N"\‹ä´_ùaEŒóŠÈ¶Å>þtâ¾%AlZv&>}ë å/3;ú±ÿîÑíX ·˜ïþðàSÊ#u UßwÈk/ùó‘ÿ8ŽŽø;úÓaò4RÆ)5äé/SyW01bŒ‰®ôÒ=<žÚ ¢¡'ñf ßµ8…¶ˆê½W¶-±O,Ý"x‹õbšé‰oi©í'ç´°OªC—íèýR­Fþ{¤²~¶¡éáÄBßñ}zÒqEðÇ^d7,†;Nè„®©ÚÞ‰T»vêfsÙ¬³ßñÜÈI\yÌÕ‘ïtX§¬ŒqJí-߉œÈ£áÏqz7!Ø$MÓ’3Ðo}ᔃŸ%'äp»Äü?ýì?s2޽é›^À 13…×;aÝ~'=åý¿yðDendstream endobj -1665 0 obj << +1682 0 obj << /Type /Page -/Contents 1666 0 R -/Resources 1664 0 R +/Contents 1683 0 R +/Resources 1681 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1652 0 R -/Annots [ 1670 0 R 1671 0 R ] +/Parent 1654 0 R +/Annots [ 1687 0 R 1688 0 R ] >> endobj -1670 0 obj << +1687 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [253.7995 149.3637 417.685 161.4234] /Subtype/Link/A<> >> endobj -1671 0 obj << +1688 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [63.4454 110.455 208.8999 120.6168] /Subtype/Link/A<> >> endobj -1667 0 obj << -/D [1665 0 R /XYZ 56.6929 794.5015 null] ->> endobj -622 0 obj << -/D [1665 0 R /XYZ 56.6929 662.0717 null] ->> endobj -1668 0 obj << -/D [1665 0 R /XYZ 56.6929 624.1661 null] +1684 0 obj << +/D [1682 0 R /XYZ 56.6929 794.5015 null] >> endobj 626 0 obj << -/D [1665 0 R /XYZ 56.6929 624.1661 null] +/D [1682 0 R /XYZ 56.6929 662.0717 null] >> endobj -1137 0 obj << -/D [1665 0 R /XYZ 56.6929 593.0972 null] +1685 0 obj << +/D [1682 0 R /XYZ 56.6929 624.1661 null] >> endobj 630 0 obj << -/D [1665 0 R /XYZ 56.6929 294.2701 null] +/D [1682 0 R /XYZ 56.6929 624.1661 null] >> endobj -1669 0 obj << -/D [1665 0 R /XYZ 56.6929 255.4568 null] +1143 0 obj << +/D [1682 0 R /XYZ 56.6929 593.0972 null] >> endobj 634 0 obj << -/D [1665 0 R /XYZ 56.6929 255.4568 null] +/D [1682 0 R /XYZ 56.6929 294.2701 null] >> endobj -965 0 obj << -/D [1665 0 R /XYZ 56.6929 226.1045 null] +1686 0 obj << +/D [1682 0 R /XYZ 56.6929 255.4568 null] >> endobj -1672 0 obj << -/D [1665 0 R /XYZ 56.6929 53.5688 null] +638 0 obj << +/D [1682 0 R /XYZ 56.6929 255.4568 null] >> endobj -1673 0 obj << -/D [1665 0 R /XYZ 56.6929 53.5688 null] +970 0 obj << +/D [1682 0 R /XYZ 56.6929 226.1045 null] >> endobj -1664 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F39 895 0 R /F53 1027 0 R /F11 1384 0 R /F41 935 0 R >> +1689 0 obj << +/D [1682 0 R /XYZ 56.6929 53.5688 null] +>> endobj +1690 0 obj << +/D [1682 0 R /XYZ 56.6929 53.5688 null] +>> endobj +1681 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F39 900 0 R /F53 1032 0 R /F11 1400 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1676 0 obj << +1693 0 obj << /Length 2825 /Filter /FlateDecode >> @@ -7465,191 +7565,191 @@ xÚµZ]{ ´ ¸ ¤ƒùÈ ’Tï*ÓªA<—Ǻ·ÃÐû"Âa‡˜%(ŒÏ´’–Û µ9Te>#ôá¶6Ø6Ay2¾b$´ÌHÜ)³|Þ‰zA 4lY3ª#Óò`ï§6c¿ŒI0‚¶Æ¾[g;µú,{Ù•oúùFÿÍ+”Ÿë¯’ù Ø.…‚1¦‘•ß‹WñÈÌvìï&}•/\ u˜sê 8˜$Ðk“3©-å¡ZKY\{h½ÐÙ}lÛ6ø´Üïå®+Ö›­ßÁä\²Z*)#ý&ÇÍ:±¦‚ñwù·á£s£˜cû‰†Íçƒb‘÷Ç}ªO]žkÓçÁj%¬¼SƒS5ø´‰3zÝÏÞs–äWœ¹Ïw;sâû}&ÁDÂ(ò[„%ä6-Ô~P‘xN|¸­9ô‡­ÁF^d‡\•<ÛkÒlIdu¾ª2!³ðôtÖÅ:Úsq\û½I$Ø‚?Sÿ[Bn…k¡6ãû>ûòá¶ -ï+ÜF6Þuþ}^=gÛô5Õ Œ@õµ®­Ñ LKç„ }RÛˆÈBFo_#y5Y«YȰƒŽAóañEXûDó*å!¯¶yJIŒ/…—(™»¼Øg¹vB½fgÉ>ÜprªÅ'¸ª LnÿË_úZ;‡1¢Iâ8L£Ð|Rʱ~)ñ+ppò!²ù&øôÝÿ ‡ÿb¿endstream +ï+ÜF6Þuþ}^=gÛô5Õ Œ@õµ®­Ñ LKç„ }RÛˆÈBFo_#y5Y«YȰƒŽAóañEXûDó*å!¯¶yJIŒ/…—(™»¼Øg¹vB½fgÉ>ÜprªÅ'¸ª LnÿË_úZ;‡1¢Iâ8L£Ð|Rʱ~)ñ+p@û¯n¾ >}÷ÿˆWbÁendstream endobj -1675 0 obj << -/Type /Page -/Contents 1676 0 R -/Resources 1674 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1652 0 R ->> endobj -1677 0 obj << -/D [1675 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1678 0 obj << -/D [1675 0 R /XYZ 85.0394 752.3015 null] ->> endobj -1679 0 obj << -/D [1675 0 R /XYZ 85.0394 752.3015 null] ->> endobj -1680 0 obj << -/D [1675 0 R /XYZ 85.0394 752.3015 null] ->> endobj -1681 0 obj << -/D [1675 0 R /XYZ 85.0394 746.3107 null] ->> endobj -1682 0 obj << -/D [1675 0 R /XYZ 85.0394 731.5461 null] ->> endobj -1683 0 obj << -/D [1675 0 R /XYZ 85.0394 728.1497 null] ->> endobj -1684 0 obj << -/D [1675 0 R /XYZ 85.0394 713.3851 null] ->> endobj -1685 0 obj << -/D [1675 0 R /XYZ 85.0394 709.9887 null] ->> endobj -1686 0 obj << -/D [1675 0 R /XYZ 85.0394 651.9592 null] ->> endobj -1081 0 obj << -/D [1675 0 R /XYZ 85.0394 651.9592 null] ->> endobj -1687 0 obj << -/D [1675 0 R /XYZ 85.0394 651.9592 null] ->> endobj -1688 0 obj << -/D [1675 0 R /XYZ 85.0394 648.8377 null] ->> endobj -1689 0 obj << -/D [1675 0 R /XYZ 85.0394 634.0731 null] ->> endobj -1690 0 obj << -/D [1675 0 R /XYZ 85.0394 630.6767 null] ->> endobj -1691 0 obj << -/D [1675 0 R /XYZ 85.0394 615.9121 null] ->> endobj 1692 0 obj << -/D [1675 0 R /XYZ 85.0394 612.5156 null] ->> endobj -1693 0 obj << -/D [1675 0 R /XYZ 85.0394 585.7959 null] +/Type /Page +/Contents 1693 0 R +/Resources 1691 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1750 0 R >> endobj 1694 0 obj << -/D [1675 0 R /XYZ 85.0394 582.3994 null] +/D [1692 0 R /XYZ 85.0394 794.5015 null] >> endobj 1695 0 obj << -/D [1675 0 R /XYZ 85.0394 567.6349 null] +/D [1692 0 R /XYZ 85.0394 752.3015 null] >> endobj 1696 0 obj << -/D [1675 0 R /XYZ 85.0394 564.2384 null] +/D [1692 0 R /XYZ 85.0394 752.3015 null] >> endobj 1697 0 obj << -/D [1675 0 R /XYZ 85.0394 549.5337 null] +/D [1692 0 R /XYZ 85.0394 752.3015 null] >> endobj 1698 0 obj << -/D [1675 0 R /XYZ 85.0394 546.0774 null] +/D [1692 0 R /XYZ 85.0394 746.3107 null] >> endobj 1699 0 obj << -/D [1675 0 R /XYZ 85.0394 531.3128 null] +/D [1692 0 R /XYZ 85.0394 731.5461 null] >> endobj 1700 0 obj << -/D [1675 0 R /XYZ 85.0394 527.9163 null] +/D [1692 0 R /XYZ 85.0394 728.1497 null] >> endobj 1701 0 obj << -/D [1675 0 R /XYZ 85.0394 513.1518 null] +/D [1692 0 R /XYZ 85.0394 713.3851 null] >> endobj 1702 0 obj << -/D [1675 0 R /XYZ 85.0394 509.7553 null] +/D [1692 0 R /XYZ 85.0394 709.9887 null] >> endobj 1703 0 obj << -/D [1675 0 R /XYZ 85.0394 483.0356 null] +/D [1692 0 R /XYZ 85.0394 651.9592 null] +>> endobj +1086 0 obj << +/D [1692 0 R /XYZ 85.0394 651.9592 null] >> endobj 1704 0 obj << -/D [1675 0 R /XYZ 85.0394 479.6391 null] +/D [1692 0 R /XYZ 85.0394 651.9592 null] >> endobj 1705 0 obj << -/D [1675 0 R /XYZ 85.0394 464.8745 null] +/D [1692 0 R /XYZ 85.0394 648.8377 null] >> endobj 1706 0 obj << -/D [1675 0 R /XYZ 85.0394 461.4781 null] +/D [1692 0 R /XYZ 85.0394 634.0731 null] >> endobj 1707 0 obj << -/D [1675 0 R /XYZ 85.0394 446.7135 null] +/D [1692 0 R /XYZ 85.0394 630.6767 null] >> endobj 1708 0 obj << -/D [1675 0 R /XYZ 85.0394 443.3171 null] +/D [1692 0 R /XYZ 85.0394 615.9121 null] >> endobj 1709 0 obj << -/D [1675 0 R /XYZ 85.0394 428.5525 null] +/D [1692 0 R /XYZ 85.0394 612.5156 null] >> endobj 1710 0 obj << -/D [1675 0 R /XYZ 85.0394 425.156 null] +/D [1692 0 R /XYZ 85.0394 585.7959 null] >> endobj 1711 0 obj << -/D [1675 0 R /XYZ 85.0394 355.0758 null] +/D [1692 0 R /XYZ 85.0394 582.3994 null] >> endobj 1712 0 obj << -/D [1675 0 R /XYZ 85.0394 355.0758 null] +/D [1692 0 R /XYZ 85.0394 567.6349 null] >> endobj 1713 0 obj << -/D [1675 0 R /XYZ 85.0394 355.0758 null] +/D [1692 0 R /XYZ 85.0394 564.2384 null] >> endobj 1714 0 obj << -/D [1675 0 R /XYZ 85.0394 352.0499 null] +/D [1692 0 R /XYZ 85.0394 549.5337 null] >> endobj 1715 0 obj << -/D [1675 0 R /XYZ 85.0394 337.3452 null] +/D [1692 0 R /XYZ 85.0394 546.0774 null] >> endobj 1716 0 obj << -/D [1675 0 R /XYZ 85.0394 333.8889 null] +/D [1692 0 R /XYZ 85.0394 531.3128 null] >> endobj 1717 0 obj << -/D [1675 0 R /XYZ 85.0394 309.8192 null] +/D [1692 0 R /XYZ 85.0394 527.9163 null] >> endobj 1718 0 obj << -/D [1675 0 R /XYZ 85.0394 303.7727 null] +/D [1692 0 R /XYZ 85.0394 513.1518 null] >> endobj 1719 0 obj << -/D [1675 0 R /XYZ 85.0394 278.3282 null] +/D [1692 0 R /XYZ 85.0394 509.7553 null] >> endobj 1720 0 obj << -/D [1675 0 R /XYZ 85.0394 273.6565 null] +/D [1692 0 R /XYZ 85.0394 483.0356 null] >> endobj 1721 0 obj << -/D [1675 0 R /XYZ 85.0394 246.9367 null] +/D [1692 0 R /XYZ 85.0394 479.6391 null] >> endobj 1722 0 obj << -/D [1675 0 R /XYZ 85.0394 243.5403 null] +/D [1692 0 R /XYZ 85.0394 464.8745 null] >> endobj 1723 0 obj << -/D [1675 0 R /XYZ 85.0394 173.5556 null] +/D [1692 0 R /XYZ 85.0394 461.4781 null] >> endobj 1724 0 obj << -/D [1675 0 R /XYZ 85.0394 173.5556 null] +/D [1692 0 R /XYZ 85.0394 446.7135 null] >> endobj 1725 0 obj << -/D [1675 0 R /XYZ 85.0394 173.5556 null] +/D [1692 0 R /XYZ 85.0394 443.3171 null] >> endobj 1726 0 obj << -/D [1675 0 R /XYZ 85.0394 170.4341 null] +/D [1692 0 R /XYZ 85.0394 428.5525 null] >> endobj 1727 0 obj << -/D [1675 0 R /XYZ 85.0394 144.9896 null] +/D [1692 0 R /XYZ 85.0394 425.156 null] >> endobj 1728 0 obj << -/D [1675 0 R /XYZ 85.0394 140.3179 null] +/D [1692 0 R /XYZ 85.0394 355.0758 null] >> endobj 1729 0 obj << -/D [1675 0 R /XYZ 85.0394 113.5982 null] +/D [1692 0 R /XYZ 85.0394 355.0758 null] >> endobj 1730 0 obj << -/D [1675 0 R /XYZ 85.0394 110.2017 null] +/D [1692 0 R /XYZ 85.0394 355.0758 null] >> endobj 1731 0 obj << -/D [1675 0 R /XYZ 85.0394 95.4372 null] +/D [1692 0 R /XYZ 85.0394 352.0499 null] >> endobj 1732 0 obj << -/D [1675 0 R /XYZ 85.0394 92.0407 null] +/D [1692 0 R /XYZ 85.0394 337.3452 null] >> endobj -1674 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] +1733 0 obj << +/D [1692 0 R /XYZ 85.0394 333.8889 null] +>> endobj +1734 0 obj << +/D [1692 0 R /XYZ 85.0394 309.8192 null] >> endobj 1735 0 obj << +/D [1692 0 R /XYZ 85.0394 303.7727 null] +>> endobj +1736 0 obj << +/D [1692 0 R /XYZ 85.0394 278.3282 null] +>> endobj +1737 0 obj << +/D [1692 0 R /XYZ 85.0394 273.6565 null] +>> endobj +1738 0 obj << +/D [1692 0 R /XYZ 85.0394 246.9367 null] +>> endobj +1739 0 obj << +/D [1692 0 R /XYZ 85.0394 243.5403 null] +>> endobj +1740 0 obj << +/D [1692 0 R /XYZ 85.0394 173.5556 null] +>> endobj +1741 0 obj << +/D [1692 0 R /XYZ 85.0394 173.5556 null] +>> endobj +1742 0 obj << +/D [1692 0 R /XYZ 85.0394 173.5556 null] +>> endobj +1743 0 obj << +/D [1692 0 R /XYZ 85.0394 170.4341 null] +>> endobj +1744 0 obj << +/D [1692 0 R /XYZ 85.0394 144.9896 null] +>> endobj +1745 0 obj << +/D [1692 0 R /XYZ 85.0394 140.3179 null] +>> endobj +1746 0 obj << +/D [1692 0 R /XYZ 85.0394 113.5982 null] +>> endobj +1747 0 obj << +/D [1692 0 R /XYZ 85.0394 110.2017 null] +>> endobj +1748 0 obj << +/D [1692 0 R /XYZ 85.0394 95.4372 null] +>> endobj +1749 0 obj << +/D [1692 0 R /XYZ 85.0394 92.0407 null] +>> endobj +1691 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1753 0 obj << /Length 2889 /Filter /FlateDecode >> @@ -7667,179 +7767,179 @@ id ¾šÈÖϺ`]Ë4OòJv‰šU N«µƒiqLË2í«ÿa:L˜o©3†Ø°²0VVdK5Á*mPîj÷c6µ¯aÒ2ýœQ9ÛCþ’?ó®Ó<Ül|Oº\˵ËÞòFnu<0–Îwu,«ä©l2ÇÓíªg0­÷ .XÁ”ðƒ< ŒÛÏiueK×±ôƒƒæÏBŽãŒÄaÓj˜¹¶jÞLpð0s«tÃüD»—yK[ÏÇ"ß»ø+Vý,/MÓ­ ~‚é;üd'DÄñCK˜ýl~h½u Äë!ÍTò'/Ø‹PˆÇª¦•…’²j(ÙöK«´A©«ÝOÉÔ^³ïÇTìq{–«íPo‘Í#/þéºÐ湚»×,Ý…ô¦¬+#wŸ[<¹ÂùÅ!Ù±r¹ …º#õ:ÓÊEYi(^ds›´¥«ÝÅÔOï7ÕḭD˜d™7žmôl‘‡ü€ºíÉÿ ãóa ±~ãcðÆÓÊ‚AYé´ŽbË®e•60tµû1˜Ú—YR–™> -.Wçñ|¾FñZD—øw¦~TЙìkUUIw9SAèJ6î$Í«z꾅щlÍ£ü~dÃÏu1dwGÛ›VdÊJ# ‰å4i•6uµû‘™ÚËøBm¼DÁ¶Ï9„§L½Î´ç1NîC݇MyúýȺ‡ лéz~ÐÛ–±DÇÊŽ§^I§‚ö;•“~f8ö–…a4LK5eb©TÛtV]á^T¦°Žqn¨bœñ7ƒ´ºsnÔ©b‚å2^Åâêr…tÇÉÐû¼¤é“ÖÓ?±N©áv3¥†f#¥æÒè¢.lå¹x òüßµ·eYšìÕ‹Z¤uö×ÎÚyÍnð i©³xˆ¿OÛ3ùŽ>“þϯíUñÑ08¼2ڮ嗪+ñ9ùêêßÓïþ–ùO[endstream +.Wçñ|¾FñZD—øw¦~TЙìkUUIw9SAèJ6î$Í«z꾅щlÍ£ü~dÃÏu1dwGÛ›VdÊJ# ‰å4i•6uµû‘™ÚËøBm¼DÁ¶Ï9„§L½Î´ç1NîC݇MyúýȺ‡ лéz~ÐÛ–±DÇÊŽ§^I§‚ö;•“~f8ö–…a4LK5eb©TÛtV]á^T¦°Žqn¨bœñ7ƒ´ºsnÔ©b‚å2^Åâêr…tÇÉÐû¼¤é“ÖÓ?±N©áv3¥†f#¥æÒè¢.lå¹x òüßµ·eYšìÕ‹Z¤uö×ÎÚyÍnð i©³xˆ¿OÛ3ùŽ>“þϯíUñÑ08¼2ڮ嗪+ñŽ{òÕÕ ¾§ßý?—QO]endstream endobj -1734 0 obj << -/Type /Page -/Contents 1735 0 R -/Resources 1733 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1652 0 R ->> endobj -1736 0 obj << -/D [1734 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1737 0 obj << -/D [1734 0 R /XYZ 56.6929 748.5056 null] ->> endobj -1738 0 obj << -/D [1734 0 R /XYZ 56.6929 748.5056 null] ->> endobj -1739 0 obj << -/D [1734 0 R /XYZ 56.6929 748.5056 null] ->> endobj -1740 0 obj << -/D [1734 0 R /XYZ 56.6929 743.7078 null] ->> endobj -1741 0 obj << -/D [1734 0 R /XYZ 56.6929 719.6381 null] ->> endobj -1742 0 obj << -/D [1734 0 R /XYZ 56.6929 711.8197 null] ->> endobj -1743 0 obj << -/D [1734 0 R /XYZ 56.6929 697.0552 null] ->> endobj -1744 0 obj << -/D [1734 0 R /XYZ 56.6929 691.8868 null] ->> endobj -1745 0 obj << -/D [1734 0 R /XYZ 56.6929 665.1671 null] ->> endobj -1746 0 obj << -/D [1734 0 R /XYZ 56.6929 659.9987 null] ->> endobj -1747 0 obj << -/D [1734 0 R /XYZ 56.6929 635.929 null] ->> endobj -1748 0 obj << -/D [1734 0 R /XYZ 56.6929 628.1106 null] ->> endobj -1749 0 obj << -/D [1734 0 R /XYZ 56.6929 601.3909 null] ->> endobj -1750 0 obj << -/D [1734 0 R /XYZ 56.6929 596.2225 null] ->> endobj -1751 0 obj << -/D [1734 0 R /XYZ 56.6929 569.5028 null] ->> endobj 1752 0 obj << -/D [1734 0 R /XYZ 56.6929 564.3344 null] ->> endobj -1753 0 obj << -/D [1734 0 R /XYZ 56.6929 549.6297 null] +/Type /Page +/Contents 1753 0 R +/Resources 1751 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1750 0 R >> endobj 1754 0 obj << -/D [1734 0 R /XYZ 56.6929 544.4015 null] +/D [1752 0 R /XYZ 56.6929 794.5015 null] >> endobj 1755 0 obj << -/D [1734 0 R /XYZ 56.6929 529.6968 null] +/D [1752 0 R /XYZ 56.6929 748.5056 null] >> endobj 1756 0 obj << -/D [1734 0 R /XYZ 56.6929 524.4686 null] +/D [1752 0 R /XYZ 56.6929 748.5056 null] >> endobj 1757 0 obj << -/D [1734 0 R /XYZ 56.6929 500.3989 null] +/D [1752 0 R /XYZ 56.6929 748.5056 null] >> endobj 1758 0 obj << -/D [1734 0 R /XYZ 56.6929 492.5805 null] +/D [1752 0 R /XYZ 56.6929 743.7078 null] >> endobj 1759 0 obj << -/D [1734 0 R /XYZ 56.6929 467.136 null] +/D [1752 0 R /XYZ 56.6929 719.6381 null] >> endobj 1760 0 obj << -/D [1734 0 R /XYZ 56.6929 460.6924 null] +/D [1752 0 R /XYZ 56.6929 711.8197 null] >> endobj 1761 0 obj << -/D [1734 0 R /XYZ 56.6929 436.6227 null] +/D [1752 0 R /XYZ 56.6929 697.0552 null] >> endobj 1762 0 obj << -/D [1734 0 R /XYZ 56.6929 428.8043 null] +/D [1752 0 R /XYZ 56.6929 691.8868 null] >> endobj 1763 0 obj << -/D [1734 0 R /XYZ 56.6929 414.0996 null] +/D [1752 0 R /XYZ 56.6929 665.1671 null] >> endobj 1764 0 obj << -/D [1734 0 R /XYZ 56.6929 408.8714 null] +/D [1752 0 R /XYZ 56.6929 659.9987 null] >> endobj 1765 0 obj << -/D [1734 0 R /XYZ 56.6929 382.1516 null] +/D [1752 0 R /XYZ 56.6929 635.929 null] >> endobj 1766 0 obj << -/D [1734 0 R /XYZ 56.6929 376.9833 null] +/D [1752 0 R /XYZ 56.6929 628.1106 null] >> endobj 1767 0 obj << -/D [1734 0 R /XYZ 56.6929 350.2636 null] +/D [1752 0 R /XYZ 56.6929 601.3909 null] >> endobj 1768 0 obj << -/D [1734 0 R /XYZ 56.6929 345.0952 null] +/D [1752 0 R /XYZ 56.6929 596.2225 null] >> endobj 1769 0 obj << -/D [1734 0 R /XYZ 56.6929 321.0255 null] +/D [1752 0 R /XYZ 56.6929 569.5028 null] >> endobj 1770 0 obj << -/D [1734 0 R /XYZ 56.6929 313.2071 null] +/D [1752 0 R /XYZ 56.6929 564.3344 null] >> endobj 1771 0 obj << -/D [1734 0 R /XYZ 56.6929 298.5024 null] +/D [1752 0 R /XYZ 56.6929 549.6297 null] >> endobj 1772 0 obj << -/D [1734 0 R /XYZ 56.6929 293.2742 null] +/D [1752 0 R /XYZ 56.6929 544.4015 null] >> endobj 1773 0 obj << -/D [1734 0 R /XYZ 56.6929 267.8297 null] +/D [1752 0 R /XYZ 56.6929 529.6968 null] >> endobj 1774 0 obj << -/D [1734 0 R /XYZ 56.6929 261.3861 null] +/D [1752 0 R /XYZ 56.6929 524.4686 null] >> endobj 1775 0 obj << -/D [1734 0 R /XYZ 56.6929 199.468 null] +/D [1752 0 R /XYZ 56.6929 500.3989 null] >> endobj 1776 0 obj << -/D [1734 0 R /XYZ 56.6929 199.468 null] +/D [1752 0 R /XYZ 56.6929 492.5805 null] >> endobj 1777 0 obj << -/D [1734 0 R /XYZ 56.6929 199.468 null] +/D [1752 0 R /XYZ 56.6929 467.136 null] >> endobj 1778 0 obj << -/D [1734 0 R /XYZ 56.6929 191.7053 null] +/D [1752 0 R /XYZ 56.6929 460.6924 null] >> endobj 1779 0 obj << -/D [1734 0 R /XYZ 56.6929 176.9408 null] +/D [1752 0 R /XYZ 56.6929 436.6227 null] >> endobj 1780 0 obj << -/D [1734 0 R /XYZ 56.6929 171.7724 null] +/D [1752 0 R /XYZ 56.6929 428.8043 null] >> endobj 1781 0 obj << -/D [1734 0 R /XYZ 56.6929 157.0677 null] +/D [1752 0 R /XYZ 56.6929 414.0996 null] >> endobj 1782 0 obj << -/D [1734 0 R /XYZ 56.6929 151.8395 null] +/D [1752 0 R /XYZ 56.6929 408.8714 null] >> endobj 1783 0 obj << -/D [1734 0 R /XYZ 56.6929 137.1348 null] +/D [1752 0 R /XYZ 56.6929 382.1516 null] >> endobj 1784 0 obj << -/D [1734 0 R /XYZ 56.6929 131.9066 null] +/D [1752 0 R /XYZ 56.6929 376.9833 null] >> endobj 1785 0 obj << -/D [1734 0 R /XYZ 56.6929 117.2018 null] +/D [1752 0 R /XYZ 56.6929 350.2636 null] >> endobj 1786 0 obj << -/D [1734 0 R /XYZ 56.6929 111.9736 null] +/D [1752 0 R /XYZ 56.6929 345.0952 null] >> endobj 1787 0 obj << -/D [1734 0 R /XYZ 56.6929 97.2091 null] +/D [1752 0 R /XYZ 56.6929 321.0255 null] >> endobj 1788 0 obj << -/D [1734 0 R /XYZ 56.6929 92.0407 null] +/D [1752 0 R /XYZ 56.6929 313.2071 null] >> endobj -1733 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] +1789 0 obj << +/D [1752 0 R /XYZ 56.6929 298.5024 null] +>> endobj +1790 0 obj << +/D [1752 0 R /XYZ 56.6929 293.2742 null] >> endobj 1791 0 obj << +/D [1752 0 R /XYZ 56.6929 267.8297 null] +>> endobj +1792 0 obj << +/D [1752 0 R /XYZ 56.6929 261.3861 null] +>> endobj +1793 0 obj << +/D [1752 0 R /XYZ 56.6929 199.468 null] +>> endobj +1794 0 obj << +/D [1752 0 R /XYZ 56.6929 199.468 null] +>> endobj +1795 0 obj << +/D [1752 0 R /XYZ 56.6929 199.468 null] +>> endobj +1796 0 obj << +/D [1752 0 R /XYZ 56.6929 191.7053 null] +>> endobj +1797 0 obj << +/D [1752 0 R /XYZ 56.6929 176.9408 null] +>> endobj +1798 0 obj << +/D [1752 0 R /XYZ 56.6929 171.7724 null] +>> endobj +1799 0 obj << +/D [1752 0 R /XYZ 56.6929 157.0677 null] +>> endobj +1800 0 obj << +/D [1752 0 R /XYZ 56.6929 151.8395 null] +>> endobj +1801 0 obj << +/D [1752 0 R /XYZ 56.6929 137.1348 null] +>> endobj +1802 0 obj << +/D [1752 0 R /XYZ 56.6929 131.9066 null] +>> endobj +1803 0 obj << +/D [1752 0 R /XYZ 56.6929 117.2018 null] +>> endobj +1804 0 obj << +/D [1752 0 R /XYZ 56.6929 111.9736 null] +>> endobj +1805 0 obj << +/D [1752 0 R /XYZ 56.6929 97.2091 null] +>> endobj +1806 0 obj << +/D [1752 0 R /XYZ 56.6929 92.0407 null] +>> endobj +1751 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1809 0 obj << /Length 2542 /Filter /FlateDecode >> @@ -7849,173 +7949,173 @@ xÚ¥Z[w ÇÄ¡V"l·Jäë‘¢š7&vᨒ׷„°FœEÄmÊm™E]â'B‰™`µ¸÷ÕHëÖ&&s-?¦! }™fðŠÊ S“}„Õ×iya] ½r°.…é$HÙ…kp>¶Pn ü@ÄHB;I ¡]Ktº8ól«ËGXáÝÄjù°P-Ã0MÀL(6ƒ‹º 'wiÞ@‰Úh¢¾ÀG°5Ø|=¤E»KžùóHž5Ì\‡€¶¨–ç¥fºÙ¾i¾íU…ôN‰!¸›RÆ•”A9vPî‚68b[H7Á9£ÂÅØ|šÒ„»>»i*°µÇ×€%Á /ŒxéÊÅÚØÏ÷Fâ(ßWæÃEtšDœ@Æ6}8@aÇ8¿Á¸¸WK8ßù¢W7é~§Åö5‚ð &ÐA]Êæ¦”p-eî(ƒÐágØã„÷ÀŸNÅm¹c<€Ó¨ó™^C‰U·„óó`Ê ‘gDDvXýZdüR±(’>¬Ž%PØ×q#êâ,«%7æ-y¨^ôB0WD¡õˈ…§JøŸrö³:û ¸ÊY'ˆŒ¨2”¨‚æËÓF @¨µ> ‡ÐÈ¿P˜R3RRº›‚ÐaF.hÃŒ†Ø32Á¿Ö­uˆ]Vçê(•:_ÝübU”¥ÜàÓ\ÄÞ¢zÉšªí‡Än¥ œ¼œKðˆ zløÓô´Eé˜éÛ EðÂñ…v”r¡¤4$pt‘Nhƒˆ!¶…\g„P×üPÔnppSŽiñ£Gkñž½y#$¾Äæt‡$dúÉWþ-gd¦vÕ×îÁw~áì”ù«¼@?½Ü„þ¯~ùÑEy¹Ns˜-b+Ÿ~D½(¼”.L);ŸZªã“:ŠG'tÇçö8Ÿ=ð…ž¾³¢‹Þ)—’UÁÀùTõÇg9µcºrÖ(£úÿ¬·é¶ÝM ¼ƒ ¼tBZ¤.éQäèá\¸)` 'òšA7FØÖ¨™-b¸"2ú]¨JÑ޼¡ Ý—àyõ`è×’5J%^ƒúû“¤¨sÆÑ‰7àØN¡^€‚ ¥€)å JIi¦ 7;˜rAT ±-\™àKþåW²­›$œ.Nͨ¼ŒóÎÄ’ˆƒüH¹ùI4}çsñvõM42¼ùàç¼+KëFÞo·›u=êTt„) ºC(ù>Š»ïÚñ7ßµ„ž©«{ˆôíDB—-Ô…/{¦”ƒH%¥‰LËå\БCl ‘&¸®éVOÅxê¨Ò¢îм³/÷üÓjžlü›òž:Gkêå©Òžª”«­ÞëÊÙ6ìØ¥0Xfâ{1Oý™øãK]æ¬a4°´Ã1gˆýªó½ý^1ã+êyˆ±Ø&GÁXܶ`JÙmAK]”#):¡;[8÷…¸°?œÞvC8k£'ü¿gå¾JoहXùì(0Cß‹)MÌá(žÞxâ»T|dy.wÚ/&>tËÛ·Sþ“«)ÿ”³¬)˜þîH°äö–RšŽ]Ydd¥£ð{ó˜ÿ¡…×РînJ9(VRºî #G£ì„6(b[(6Á¯³B§­Ïé S=sv–iG{ -9±ôIŒ»©Òï¯bF²SÁà´?Õæ!±ò¡‘n !; J¨û$9úhnÇÁxœY8YŒ!à4¼ªÅœ7%ÿo6×°(£2ùP.ì÷ba¯¾ëÇÊ+à.kVœ¸¥7álE‘9ôˆAWܧ«»­Ì›òž[Ý¨Ï§ÌøÆ§Sþ3ŸŸxYAFméÿÿ ˘OF‰m3Ù…«‡j»#D†®ºuþìÿ’{÷òendstream +9±ôIŒ»©Òï¯bF²SÁà´?Õæ!±ò¡‘n !; J¨û$9úhnÇÁxœY8YŒ!à4¼ªÅœ7%ÿo6×°(£2ùP.ì÷ba¯¾ëÇÊ+à.kVœ¸¥7álE‘9ôˆAWܧ«»­Ì›òž[Ý¨Ï§ÌøÆ§Sþ3ŸŸxYAFméÿÿ ˘OF‰m3Ù…«‡j»#D‡®ºuþìÿ’Ó÷ôendstream endobj -1790 0 obj << -/Type /Page -/Contents 1791 0 R -/Resources 1789 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1843 0 R ->> endobj -1792 0 obj << -/D [1790 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1793 0 obj << -/D [1790 0 R /XYZ 85.0394 748.4854 null] ->> endobj -1794 0 obj << -/D [1790 0 R /XYZ 85.0394 748.4854 null] ->> endobj -1795 0 obj << -/D [1790 0 R /XYZ 85.0394 748.4854 null] ->> endobj -1796 0 obj << -/D [1790 0 R /XYZ 85.0394 743.3452 null] ->> endobj -1797 0 obj << -/D [1790 0 R /XYZ 85.0394 728.6405 null] ->> endobj -1798 0 obj << -/D [1790 0 R /XYZ 85.0394 723.1655 null] ->> endobj -1799 0 obj << -/D [1790 0 R /XYZ 85.0394 708.4607 null] ->> endobj -1800 0 obj << -/D [1790 0 R /XYZ 85.0394 702.9857 null] ->> endobj -1801 0 obj << -/D [1790 0 R /XYZ 85.0394 688.2211 null] ->> endobj -1802 0 obj << -/D [1790 0 R /XYZ 85.0394 682.8059 null] ->> endobj -1803 0 obj << -/D [1790 0 R /XYZ 85.0394 668.0414 null] ->> endobj -1804 0 obj << -/D [1790 0 R /XYZ 85.0394 662.6262 null] ->> endobj -1805 0 obj << -/D [1790 0 R /XYZ 85.0394 599.7666 null] ->> endobj -1806 0 obj << -/D [1790 0 R /XYZ 85.0394 599.7666 null] ->> endobj -1807 0 obj << -/D [1790 0 R /XYZ 85.0394 599.7666 null] ->> endobj 1808 0 obj << -/D [1790 0 R /XYZ 85.0394 591.7571 null] ->> endobj -1809 0 obj << -/D [1790 0 R /XYZ 85.0394 565.0374 null] +/Type /Page +/Contents 1809 0 R +/Resources 1807 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1750 0 R >> endobj 1810 0 obj << -/D [1790 0 R /XYZ 85.0394 559.6222 null] +/D [1808 0 R /XYZ 85.0394 794.5015 null] >> endobj 1811 0 obj << -/D [1790 0 R /XYZ 85.0394 534.1777 null] +/D [1808 0 R /XYZ 85.0394 748.4854 null] >> endobj 1812 0 obj << -/D [1790 0 R /XYZ 85.0394 527.4872 null] +/D [1808 0 R /XYZ 85.0394 748.4854 null] >> endobj 1813 0 obj << -/D [1790 0 R /XYZ 85.0394 502.0427 null] +/D [1808 0 R /XYZ 85.0394 748.4854 null] >> endobj 1814 0 obj << -/D [1790 0 R /XYZ 85.0394 495.3523 null] +/D [1808 0 R /XYZ 85.0394 743.3452 null] >> endobj 1815 0 obj << -/D [1790 0 R /XYZ 85.0394 420.5376 null] +/D [1808 0 R /XYZ 85.0394 728.6405 null] >> endobj 1816 0 obj << -/D [1790 0 R /XYZ 85.0394 420.5376 null] +/D [1808 0 R /XYZ 85.0394 723.1655 null] >> endobj 1817 0 obj << -/D [1790 0 R /XYZ 85.0394 420.5376 null] +/D [1808 0 R /XYZ 85.0394 708.4607 null] >> endobj 1818 0 obj << -/D [1790 0 R /XYZ 85.0394 412.5281 null] +/D [1808 0 R /XYZ 85.0394 702.9857 null] >> endobj 1819 0 obj << -/D [1790 0 R /XYZ 85.0394 388.4584 null] +/D [1808 0 R /XYZ 85.0394 688.2211 null] >> endobj 1820 0 obj << -/D [1790 0 R /XYZ 85.0394 380.3932 null] +/D [1808 0 R /XYZ 85.0394 682.8059 null] >> endobj 1821 0 obj << -/D [1790 0 R /XYZ 85.0394 365.6884 null] +/D [1808 0 R /XYZ 85.0394 668.0414 null] >> endobj 1822 0 obj << -/D [1790 0 R /XYZ 85.0394 360.2134 null] +/D [1808 0 R /XYZ 85.0394 662.6262 null] >> endobj 1823 0 obj << -/D [1790 0 R /XYZ 85.0394 345.4488 null] +/D [1808 0 R /XYZ 85.0394 599.7666 null] >> endobj 1824 0 obj << -/D [1790 0 R /XYZ 85.0394 340.0336 null] +/D [1808 0 R /XYZ 85.0394 599.7666 null] >> endobj 1825 0 obj << -/D [1790 0 R /XYZ 85.0394 325.269 null] +/D [1808 0 R /XYZ 85.0394 599.7666 null] >> endobj 1826 0 obj << -/D [1790 0 R /XYZ 85.0394 319.8539 null] +/D [1808 0 R /XYZ 85.0394 591.7571 null] >> endobj 1827 0 obj << -/D [1790 0 R /XYZ 85.0394 295.7842 null] +/D [1808 0 R /XYZ 85.0394 565.0374 null] >> endobj 1828 0 obj << -/D [1790 0 R /XYZ 85.0394 287.7189 null] +/D [1808 0 R /XYZ 85.0394 559.6222 null] >> endobj 1829 0 obj << -/D [1790 0 R /XYZ 85.0394 272.9543 null] +/D [1808 0 R /XYZ 85.0394 534.1777 null] >> endobj 1830 0 obj << -/D [1790 0 R /XYZ 85.0394 267.5392 null] +/D [1808 0 R /XYZ 85.0394 527.4872 null] >> endobj 1831 0 obj << -/D [1790 0 R /XYZ 85.0394 252.7746 null] +/D [1808 0 R /XYZ 85.0394 502.0427 null] >> endobj 1832 0 obj << -/D [1790 0 R /XYZ 85.0394 247.3594 null] +/D [1808 0 R /XYZ 85.0394 495.3523 null] >> endobj 1833 0 obj << -/D [1790 0 R /XYZ 85.0394 223.2897 null] +/D [1808 0 R /XYZ 85.0394 420.5376 null] >> endobj 1834 0 obj << -/D [1790 0 R /XYZ 85.0394 215.2245 null] +/D [1808 0 R /XYZ 85.0394 420.5376 null] >> endobj 1835 0 obj << -/D [1790 0 R /XYZ 85.0394 149.4956 null] +/D [1808 0 R /XYZ 85.0394 420.5376 null] >> endobj 1836 0 obj << -/D [1790 0 R /XYZ 85.0394 149.4956 null] +/D [1808 0 R /XYZ 85.0394 412.5281 null] >> endobj 1837 0 obj << -/D [1790 0 R /XYZ 85.0394 149.4956 null] +/D [1808 0 R /XYZ 85.0394 388.4584 null] >> endobj 1838 0 obj << -/D [1790 0 R /XYZ 85.0394 144.3554 null] +/D [1808 0 R /XYZ 85.0394 380.3932 null] >> endobj 1839 0 obj << -/D [1790 0 R /XYZ 85.0394 120.2857 null] +/D [1808 0 R /XYZ 85.0394 365.6884 null] >> endobj 1840 0 obj << -/D [1790 0 R /XYZ 85.0394 112.2205 null] +/D [1808 0 R /XYZ 85.0394 360.2134 null] >> endobj 1841 0 obj << -/D [1790 0 R /XYZ 85.0394 97.4559 null] +/D [1808 0 R /XYZ 85.0394 345.4488 null] >> endobj 1842 0 obj << -/D [1790 0 R /XYZ 85.0394 92.0407 null] +/D [1808 0 R /XYZ 85.0394 340.0336 null] >> endobj -1789 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] +1843 0 obj << +/D [1808 0 R /XYZ 85.0394 325.269 null] +>> endobj +1844 0 obj << +/D [1808 0 R /XYZ 85.0394 319.8539 null] +>> endobj +1845 0 obj << +/D [1808 0 R /XYZ 85.0394 295.7842 null] >> endobj 1846 0 obj << +/D [1808 0 R /XYZ 85.0394 287.7189 null] +>> endobj +1847 0 obj << +/D [1808 0 R /XYZ 85.0394 272.9543 null] +>> endobj +1848 0 obj << +/D [1808 0 R /XYZ 85.0394 267.5392 null] +>> endobj +1849 0 obj << +/D [1808 0 R /XYZ 85.0394 252.7746 null] +>> endobj +1850 0 obj << +/D [1808 0 R /XYZ 85.0394 247.3594 null] +>> endobj +1851 0 obj << +/D [1808 0 R /XYZ 85.0394 223.2897 null] +>> endobj +1852 0 obj << +/D [1808 0 R /XYZ 85.0394 215.2245 null] +>> endobj +1853 0 obj << +/D [1808 0 R /XYZ 85.0394 149.4956 null] +>> endobj +1854 0 obj << +/D [1808 0 R /XYZ 85.0394 149.4956 null] +>> endobj +1855 0 obj << +/D [1808 0 R /XYZ 85.0394 149.4956 null] +>> endobj +1856 0 obj << +/D [1808 0 R /XYZ 85.0394 144.3554 null] +>> endobj +1857 0 obj << +/D [1808 0 R /XYZ 85.0394 120.2857 null] +>> endobj +1858 0 obj << +/D [1808 0 R /XYZ 85.0394 112.2205 null] +>> endobj +1859 0 obj << +/D [1808 0 R /XYZ 85.0394 97.4559 null] +>> endobj +1860 0 obj << +/D [1808 0 R /XYZ 85.0394 92.0407 null] +>> endobj +1807 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1863 0 obj << /Length 2121 /Filter /FlateDecode >> @@ -8028,119 +8128,119 @@ Z9 aÜo汆ÆÙ3¨¢sõd¥Ë*^ÉÛXxùÎR~ȬتýÁŠüˆ9w›m&U¿Øé½cïU¢Àâ,pò¢2ª‹ö6°L@ÎU\¿²q8.€6býN}×I?âL¥°Ž ®üHU®‹}fFµVÕx•øý}_à»*ê¬cIj†\m­17ÂÞÔ©ÏpÐÆºû<3ú$)6“.|¶qžjéŒ:¯ü≀Æ2-“,N7:‡ê‰¸jH ññBçç®:s%võrá‹(+$-K¢èp uüa„ÄøÉÒ7YÂò°§O+|Ëô'66E^­ /œ÷z‰?Ö)\6;6jVìÙ+†ÎRZ/ÙÉT[?뙉Wà BRSOÄú1£ì ô<(AD]­Xx©°óZìM¬¸¾{˜åºP¬ú\J"VßCÞäN¹Qï3;¡Ô»pý²©Î“ ì‚™8 -ÓÙ„õç‘A­Ç> endobj -1847 0 obj << -/D [1845 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1848 0 obj << -/D [1845 0 R /XYZ 56.6929 749.4437 null] ->> endobj -1849 0 obj << -/D [1845 0 R /XYZ 56.6929 749.4437 null] ->> endobj -1850 0 obj << -/D [1845 0 R /XYZ 56.6929 749.4437 null] ->> endobj -1851 0 obj << -/D [1845 0 R /XYZ 56.6929 746.6461 null] ->> endobj -1852 0 obj << -/D [1845 0 R /XYZ 56.6929 722.5763 null] ->> endobj -1853 0 obj << -/D [1845 0 R /XYZ 56.6929 716.7581 null] ->> endobj -1854 0 obj << -/D [1845 0 R /XYZ 56.6929 701.9936 null] ->> endobj -1855 0 obj << -/D [1845 0 R /XYZ 56.6929 698.8254 null] ->> endobj -1856 0 obj << -/D [1845 0 R /XYZ 56.6929 684.1207 null] ->> endobj -1857 0 obj << -/D [1845 0 R /XYZ 56.6929 680.8926 null] ->> endobj -1858 0 obj << -/D [1845 0 R /XYZ 56.6929 656.8229 null] ->> endobj -1859 0 obj << -/D [1845 0 R /XYZ 56.6929 651.0047 null] ->> endobj -1860 0 obj << -/D [1845 0 R /XYZ 56.6929 636.3 null] ->> endobj -1861 0 obj << -/D [1845 0 R /XYZ 56.6929 633.072 null] ->> endobj 1862 0 obj << -/D [1845 0 R /XYZ 56.6929 609.0023 null] ->> endobj -1863 0 obj << -/D [1845 0 R /XYZ 56.6929 603.184 null] +/Type /Page +/Contents 1863 0 R +/Resources 1861 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1750 0 R >> endobj 1864 0 obj << -/D [1845 0 R /XYZ 56.6929 579.1143 null] +/D [1862 0 R /XYZ 56.6929 794.5015 null] >> endobj 1865 0 obj << -/D [1845 0 R /XYZ 56.6929 573.2961 null] +/D [1862 0 R /XYZ 56.6929 749.4437 null] >> endobj 1866 0 obj << -/D [1845 0 R /XYZ 56.6929 558.5914 null] +/D [1862 0 R /XYZ 56.6929 749.4437 null] >> endobj 1867 0 obj << -/D [1845 0 R /XYZ 56.6929 555.3634 null] +/D [1862 0 R /XYZ 56.6929 749.4437 null] >> endobj 1868 0 obj << -/D [1845 0 R /XYZ 56.6929 540.5988 null] +/D [1862 0 R /XYZ 56.6929 746.6461 null] >> endobj 1869 0 obj << -/D [1845 0 R /XYZ 56.6929 537.4306 null] +/D [1862 0 R /XYZ 56.6929 722.5763 null] >> endobj 1870 0 obj << -/D [1845 0 R /XYZ 56.6929 510.7109 null] +/D [1862 0 R /XYZ 56.6929 716.7581 null] >> endobj 1871 0 obj << -/D [1845 0 R /XYZ 56.6929 507.5427 null] ->> endobj -638 0 obj << -/D [1845 0 R /XYZ 56.6929 477.5928 null] +/D [1862 0 R /XYZ 56.6929 701.9936 null] >> endobj 1872 0 obj << -/D [1845 0 R /XYZ 56.6929 453.2532 null] ->> endobj -642 0 obj << -/D [1845 0 R /XYZ 56.6929 369.7201 null] +/D [1862 0 R /XYZ 56.6929 698.8254 null] >> endobj 1873 0 obj << -/D [1845 0 R /XYZ 56.6929 345.3805 null] +/D [1862 0 R /XYZ 56.6929 684.1207 null] >> endobj 1874 0 obj << -/D [1845 0 R /XYZ 56.6929 310.6805 null] +/D [1862 0 R /XYZ 56.6929 680.8926 null] >> endobj 1875 0 obj << -/D [1845 0 R /XYZ 56.6929 310.6805 null] +/D [1862 0 R /XYZ 56.6929 656.8229 null] >> endobj 1876 0 obj << -/D [1845 0 R /XYZ 56.6929 310.6805 null] +/D [1862 0 R /XYZ 56.6929 651.0047 null] >> endobj 1877 0 obj << -/D [1845 0 R /XYZ 56.6929 310.6805 null] +/D [1862 0 R /XYZ 56.6929 636.3 null] >> endobj -1844 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F14 737 0 R >> -/ProcSet [ /PDF /Text ] +1878 0 obj << +/D [1862 0 R /XYZ 56.6929 633.072 null] +>> endobj +1879 0 obj << +/D [1862 0 R /XYZ 56.6929 609.0023 null] >> endobj 1880 0 obj << +/D [1862 0 R /XYZ 56.6929 603.184 null] +>> endobj +1881 0 obj << +/D [1862 0 R /XYZ 56.6929 579.1143 null] +>> endobj +1882 0 obj << +/D [1862 0 R /XYZ 56.6929 573.2961 null] +>> endobj +1883 0 obj << +/D [1862 0 R /XYZ 56.6929 558.5914 null] +>> endobj +1884 0 obj << +/D [1862 0 R /XYZ 56.6929 555.3634 null] +>> endobj +1885 0 obj << +/D [1862 0 R /XYZ 56.6929 540.5988 null] +>> endobj +1886 0 obj << +/D [1862 0 R /XYZ 56.6929 537.4306 null] +>> endobj +1887 0 obj << +/D [1862 0 R /XYZ 56.6929 510.7109 null] +>> endobj +1888 0 obj << +/D [1862 0 R /XYZ 56.6929 507.5427 null] +>> endobj +642 0 obj << +/D [1862 0 R /XYZ 56.6929 477.5928 null] +>> endobj +1889 0 obj << +/D [1862 0 R /XYZ 56.6929 453.2532 null] +>> endobj +646 0 obj << +/D [1862 0 R /XYZ 56.6929 369.7201 null] +>> endobj +1890 0 obj << +/D [1862 0 R /XYZ 56.6929 345.3805 null] +>> endobj +1891 0 obj << +/D [1862 0 R /XYZ 56.6929 310.6805 null] +>> endobj +1892 0 obj << +/D [1862 0 R /XYZ 56.6929 310.6805 null] +>> endobj +1893 0 obj << +/D [1862 0 R /XYZ 56.6929 310.6805 null] +>> endobj +1894 0 obj << +/D [1862 0 R /XYZ 56.6929 310.6805 null] +>> endobj +1861 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R /F14 741 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1897 0 obj << /Length 1945 /Filter /FlateDecode >> @@ -8151,45 +8251,45 @@ O3i_ ! ˆ(ñ7|Ùl‹²†B ù¼¬WÍn[ôeƒ•Ï×»‘Í›Öí€U¦ŽÖ š~ã\¹ŸåcåˆÜ7ME+€a{·#¤5€×kâ¤Zë>¦=‰ÒwÇnÅÓùmOT8åꈷy‡ŽºŒü™ê°*"ÖKH,£][‡@î7ŽÈEÝ=Ãq‘Zôa›—5ðиßïj·¤å©²=#-DZ q;2.ááȈ3t€Ò-Ae³OM×Ç‚ª–·•²ò˶¬Ë1ïú]Ñ7^x ï;7á l>Tœ .ݲ1Û÷ ö¤äîµÛ4 ŠnùQŒ––auÛÑÒ£[(…_nVô-û°½„ kþ ,d`…â|Oáþöè¢gZ¥h«ìÁ| ƒ›ýwß·ûýGðùg¸›ÝËv=´ C‡BDúnŠ'¶`WàG«}½À˜(ªá<¸ÍzÂà ³‰1éï\³\«XûXÌΚeyn@Çœ¥iJÿ¦ê7Í~½™8Jè8•ºvµ2eàÁÀUJÎkŒñª:àÌ›{Iôç²ßmÑl·`ý¤*kGkëýÖÕ}‡Wg$\.qU×צè‰æE¿Ûf ü=ãšR7€ÕB¹»ýB(bŠ%%}r¡h©ëCŽ8†(ÎŽ™JVÎç;C´Gˆ½ »=(½;Ф DïÀxÆØ$õÔ$ä½ ··¨X7$̉ˆnw˜‘ßêùóÆÕ4Âtò²È§9Âêp‘ÉfÚ«Lfc@¤OØð]—O®Fõšÿ³®ÊïŽè®ØU¥˜`úEÑÁiJÙMZ3{{÷ž8ò€ºm!øA÷âxR³šŒ x‰¡¾X—Lj¢7ƒw6ÏdµDãÓ*züÛ}Õ—måN£»GòcX,»nïB”Ÿø…âÀ.7€Á ³áÆN‚lF)A‘ïK¥B1”phµ$Š?(¾°© J׺E‰N¸ y,{*Œ›TCV|i@ÉsïyÍ€^5繬ª XŠ2 —Ô«‚QÕ%jUvä–¨e=á‹Â&¤ˆêk×/^à ª©žb*Ëàá$@º‘¿/šz5!÷¸Ñ‘82ÿ¿(Fd ¿éɵ1&ŒÎH>ÀŽc\|a“ŽIëë ³É®Z_Èll}@ ^ñ}Ûßè!0\E᥮þ#:ötM0!ßmzì)¢¡,<ƒyfÇ–ò}“ÍBà§ðëºÐ Õ;(P;ØZêG¨;ZZºUÖÑ: -7Ñ[¤ʘÐ×ìbyíòTSþ*¤Ñ›þüïŸ?}øÏkx»Åb¦˜Í¬ü:5¿ßDU)ÇŸªŸ µƒ8Èa€\Ô¢7…r$sÍ´gõȇ½á'®ƒ“¶…ü¹ŒYÍu\¼œcN‘‚³N¦{ß`Bɺ½£/uµ0x÷‘¾ô{ƒo™1§tDm ¦«¢¥I¨í0ê¯ÂõMK`•{rÑè•ý!`zfó%5YH§Î-œ1ñ³¼eL–ÅBç£ëMÓÙ+5´‚çžy1W±»M—ª¢T£ªÊ!Å¢´¼:Ë/ ðw¿F“™C]ôª^®×"‡¤aÉ~\”,†Ïpî‰4êHi0Fë)šP´ƒ4ʧۻ˜@`eè¡¡„*œžõÐÈøîcäw H¨©Ômá/„íàÍ]tì¦}²÷/açïðãó˜áϲ“íÀ’yèÙÑo#\Ó/UÜœ7üÀûò¼ÿйž…endstream +7Ñ[¤ʘÐ×ìbyíòTSþ*¤Ñ›þüïŸ?}øÏkx»Åb¦˜Í¬ü:5¿ßDU)ÇŸªŸ µƒ8Èa€\Ô¢7…r$sÍ´gõȇ½á'®ƒ“¶…ü¹ŒYÍu\¼œcN‘‚³N¦{ß`Bɺ½£/uµ0x÷‘¾ô{ƒo™1§tDm ¦«¢¥I¨í0ê¯ÂõMK`•{rÑè•ý!`zfó%5YH§Î-œ1ñ³¼eL–ÅBç£ëMÓÙ+5´‚çžy1W±»M—ª¢T£ªÊ!Å¢´¼:Ë/ ðw¿F“™C]ôª^®×"‡¤aÉ~\”,†Ïpî‰4êHi0Fë)šP´ƒ4ʧۻ˜@`eè¡¡„*œžõÐÈøîcäw H¨©Ômá/„íàÍ]tì¦}²÷/açïðãó˜áϲ“íÀ’yèÙÑo#\Ó/U<=?nø÷åyÿÑž‡endstream endobj -1879 0 obj << +1896 0 obj << /Type /Page -/Contents 1880 0 R -/Resources 1878 0 R +/Contents 1897 0 R +/Resources 1895 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1843 0 R +/Parent 1750 0 R >> endobj -1881 0 obj << -/D [1879 0 R /XYZ 85.0394 794.5015 null] ->> endobj -646 0 obj << -/D [1879 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1882 0 obj << -/D [1879 0 R /XYZ 85.0394 573.0107 null] +1898 0 obj << +/D [1896 0 R /XYZ 85.0394 794.5015 null] >> endobj 650 0 obj << -/D [1879 0 R /XYZ 85.0394 573.0107 null] +/D [1896 0 R /XYZ 85.0394 769.5949 null] >> endobj -1883 0 obj << -/D [1879 0 R /XYZ 85.0394 538.4209 null] +1899 0 obj << +/D [1896 0 R /XYZ 85.0394 573.0107 null] >> endobj -1884 0 obj << -/D [1879 0 R /XYZ 85.0394 504.6118 null] +654 0 obj << +/D [1896 0 R /XYZ 85.0394 573.0107 null] >> endobj -1885 0 obj << -/D [1879 0 R /XYZ 85.0394 432.7569 null] +1900 0 obj << +/D [1896 0 R /XYZ 85.0394 538.4209 null] >> endobj -1886 0 obj << -/D [1879 0 R /XYZ 85.0394 303.3232 null] +1901 0 obj << +/D [1896 0 R /XYZ 85.0394 504.6118 null] >> endobj -1878 0 obj << -/Font << /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R >> +1902 0 obj << +/D [1896 0 R /XYZ 85.0394 432.7569 null] +>> endobj +1903 0 obj << +/D [1896 0 R /XYZ 85.0394 303.3232 null] +>> endobj +1895 0 obj << +/Font << /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1889 0 obj << -/Length 3825 +1906 0 obj << +/Length 3824 /Filter /FlateDecode >> stream @@ -8208,29 +8308,29 @@ h £L¨¸Â›2ޤŠà˜ÊjŽŠåû]>ê|“(ÑÆô®³av½Ò»^q¬$C“¡Ç|qYðw)Ð÷þæ Wr–ÇëçbÙ–Ÿ‹ÿx…f&@Ã2Ô \ÙZ6Ýmž _•˜¡ áÁKa¸t…'z ù²ªr±ØðPåý¿°Èªendstream endobj -1888 0 obj << +1905 0 obj << /Type /Page -/Contents 1889 0 R -/Resources 1887 0 R +/Contents 1906 0 R +/Resources 1904 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1843 0 R +/Parent 1750 0 R >> endobj -1890 0 obj << -/D [1888 0 R /XYZ 56.6929 794.5015 null] +1907 0 obj << +/D [1905 0 R /XYZ 56.6929 794.5015 null] >> endobj -1891 0 obj << -/D [1888 0 R /XYZ 56.6929 752.1413 null] +1908 0 obj << +/D [1905 0 R /XYZ 56.6929 752.1413 null] >> endobj -1892 0 obj << -/D [1888 0 R /XYZ 56.6929 501.191 null] +1909 0 obj << +/D [1905 0 R /XYZ 56.6929 501.191 null] >> endobj -1887 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F53 1027 0 R /F11 1384 0 R >> +1904 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F53 1032 0 R /F11 1400 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1895 0 obj << +1912 0 obj << /Length 3111 /Filter /FlateDecode >> @@ -8247,99 +8347,95 @@ D “]Erü<@ÊžÔßçÍêý>¯«ÍËÔ©Zê`žÐN4á“"NÜC÷S ¯¿2²³2L‘+ÑDïÐÚ÷•l¯ãÂþåCâÁYÀÚûu¬Ö#f‚Y+žÜйñ¼»¯žÀOåäžRqä~øÆžêJMï)'åh²Å(MžUÞÒä‰öqšì©7¡)É„fˆqš±†B3–øÌ¡{+Š ´¢Ø’åë’·‚χ£=¹ä, ~Ñ4N¶Ø< [ˆéPíµ,C–Ïx£+?gHl!Ûæ@üQÖxä³g/÷\:tÒ;r çy÷öüo¢À4ÊTà…A½²ŽÔ”Y©eëêuiqàÅB½a€“:µ`pá¥àƒ°oÂ-Å-r¡­ë,k÷½Tzèlœ»Î4çIˆƒ]Ænn§¦],/òã7<Ü q0 9ÿÂêŽFÅà‹à¬j't¢»ïÚHzq(ãžòëÜ^K¤íI¥¡*¬a—Ö}×˪±™Êª+Þöå™Ïë:çËJ?†S=i}¾”÷ùÔ´ØkxSÎH -gˆ¯nGªïÜëÃ]51ŸVÍ›%”^ÒM‘1aúô,‹’0ÂÁ%ŠX¿ZñÝ)…"´¨"Ñ“çÉï_0[”ÌwÕæ’ñÕ±;«¤{-ÌM€P°~?Jj*Ê OóÚv1·½]q è\Ž÷f=1Ù¤;Y0®3ߤõì[!ZR¿Ö¡ÐypÖ{ òËí_×_¾.©bŸ–Oø†(3[Áƒñlé‹'«ÝsÔíÒ=ë1^Ô’½…®U¯imGì,æÈTìmŠËJœ—&)ïM%û<Åt¥¦)ÆI9ŠY§˜³Ê[Š9Ñ>N1=õ†b`crª–Ø5M$S –ÈÛPøxM¿H1«u¾z¦­5YQã‰0ã?2€Ã2X0a²;Je@>± 6õYÆOü¶—{ÈÇ¡ª3¬2Ì5éãúóÝݧ½åv'Äê±—XÒÅÐ$àdìo¥–¡i X¡›É{ÛsZÛkÛ¡Úñ[Û®ÞkzÄÊ×ù÷~é|üõêîÎÞ‘çeçeÔåíN¶ÏU“n…X¯ü7žUZ™i§²L{ÓÛÀbŸ¸r—D`Îhu2Cµƒ?NѰý¢°«÷¿óérùëÿÉ£öäzø—X#sî#þç?øjÿœ-À¿¾I&^ ð £”–Ö(t“ñÐt÷§a§¶ÿR+¯^endstream +gˆ¯nGªïÜëÃ]51ŸVÍ›%”^ÒM‘1aúô,‹’0ÂÁ%ŠX¿ZñÝ)…"´¨"Ñ“çÉï_0[”ÌwÕæ’ñÕ±;«¤{-ÌM€P°~?Jj*Ê OóÚv1·½]q è\Ž÷f=1Ù¤;Y0®3ߤõì[!ZR¿Ö¡ÐypÖ{ òËí_×_¾.©bŸ–Oø†(3[Áƒñlé‹'«ÝsÔíÒ=ë1^Ô’½…®U¯imGì,æÈTìmŠËJœ—&)ïM%û<Åt¥¦)ÆI9ŠY§˜³Ê[Š9Ñ>N1=õ†b`crª–Ø5M$S –ÈÛPøxM¿H1«u¾z¦­5YQã‰0ã?2€Ã2X0a²;Je@>± 6õYÆOü¶—{ÈÇ¡ª3¬2Ì5éãúóÝݧ½åv'Äê±—XÒÅÐ$àdìo¥–¡i X¡›É{ÛsZÛkÛ¡Úñ[Û®ÞkzÄÊ×ù÷~é|üõêîÎÞ‘çeçeÔåíN¶ÏU“n…X¯ü7žUZ™i§²L{ÓÛÀbŸ¸r—D`Îhu2Cµƒ?NѰý¢°«÷¿óérùëÿÉ£öäzø—X#sî#þç?øjÿœ-À¿¾I&^ ð £”–Ö(t“zhºûÓ°SÛÿ Rƒ¯`endstream endobj -1894 0 obj << +1911 0 obj << /Type /Page -/Contents 1895 0 R -/Resources 1893 0 R +/Contents 1912 0 R +/Resources 1910 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1843 0 R +/Parent 1915 0 R >> endobj -1896 0 obj << -/D [1894 0 R /XYZ 85.0394 794.5015 null] +1913 0 obj << +/D [1911 0 R /XYZ 85.0394 794.5015 null] >> endobj -1897 0 obj << -/D [1894 0 R /XYZ 85.0394 679.319 null] ->> endobj -1893 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F48 950 0 R /F53 1027 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1900 0 obj << -/Length 2838 -/Filter /FlateDecode ->> -stream -xÚ¥Z[oܺ~÷¯ØGITÞDQú éAÚS÷ÄA $~W´-D+mVÚίïð*R·=m±¢Èg8óÍ…äâ‚Þe<å)vyÁÒ ál·?\¡Ý#Œýr…-ÍGô&¤zw{õ§¿Ò|W¤'|wûÌ%R$ÞÝV_’w)N¯a”¼ÿøËõÂ3D’·77~{ÿñßðž! „’¿¿ýíóÛ¿™¾›ëÈ~ùðéúîö׫·^˜P`Œ¨’äûÕ—;´«@î_¯PJ ‘ížá¥¸(ÈîpÅ2šfŒR×Ó\}ºú§Ÿ0ÕŸ.)€e"Íã  -š”“e5á4Ljr†SR0êÕÄÄ’š•RÓ«/mww’ûó©—Ó%c"RFhðÅwO5gOhÀSš2”‘˜ÿ­Òw÷øØÈë7TàdxÒ ’ôr®qR·æ½{ˆpòû{óüŠ2tºÆ"Ñ‹¨»ÖÐW²¯MwØÐÞ׃iÔí„Ý÷³<½\cŒEŽXrûT÷Ólˆf>ºQ*Ó(ËA8-2X¢ZY%Ês3¼RL’ç§zÿ+Šä ˶W‚‚p  @/Ï3Z՟ז&Rbž„–¦íN‡²i^̼½l+%! :ÐÇiFÕkÙÃêTÉï²€^­L•ç¡;”C½7³ª¡ªîËûFVf¥³”#)Zêó“lû(}j©³Pj–Ïyf¥~Õö½,O Žùú£D·¾î´00Ü«éÕp*÷ra&*RšqbÉŒyµˆÝq€u÷æ¥4š2/ç^VéÌï­sq‘§¨@bÛCªuôTÞC•D.H8 ¾MöžjÎâ‚E -¸±ÿÒÖ£8ëiˆCË(É´]Àþõl1*RLòl·‚¦3F9 òpì´Cgž_"m呦€|êNõ˜üa»Úò @§òd§y°øo VE–"ˆN1Vv­27+’}×eÝêã°« Õº—~´éºoàºû|4ÏRÉ«ÁIŽMùbzý<ŸþñÖ [wìô³rTå`Fe©#CÄØ,ÍŒ?•:Z€ò¢…èrCC-m¿”¤Bäô~ª ü:*_ï…x!X0.Ä6oO5gCˆà”AsòGÖALÎ(¸É…ƒ4*ÙÈÇÒBŽåðdF´mºCô7–ëºÁt[è!ô -= ö|FBƒ Gp>‘¡,¶¢ƒ•Bîù¨ -LÕ¢4n!ÞÅŒuïý‹í5™FL¼;‹@Á²Õ3,y2Ey -$ä²'û t(¿Ië€õ OÞM…Ë7vé$ƒ!ÃñÚµçjÝ£ïý-aV0bõ-ë‰jÔ« ºÊ(J>f𹆢¡iÌËC×4ÝsÈäAžNeÓÛáÑæ@à™6"ki•Ƥþ§îÙ â"wLSyBvv¾;²<Z¡‘à¹ìÇLd»0„XE^¯Ô¡Ô°â÷çiNßöûjÝï=•÷ûý¡šy=‚ZÓ œ=Õœu 7È.¬`Þ£×+…q‹Âir<Õí`‚6t« 3¨ûêA!¤lÌû¾;d;¸ÁÉdÝy8žÝ`tõËŸÛS)xèˆb9.8ÈN‘*õ·K»,ÇŽF¥í:  •OJKoûµ²f„ÔSés/]‘VM­JpTd ]Õ?*#³%!<µBï-3qÖ@G  èB² ©6@ç¨<èÀ OÃj²Ùä=&›óådq¿1Þü°`5iÕ-ÕîÉôçÏYâÕ+#ÅÚuî­µð¤)ÿO -kèH+ã¶&Pr”%šº•}¢ü×&{þ¯aÐ)dÝPðeìPmØÃQ9¶œýjŽÙä=æ˜óåq·é˜ -ŸÜ¡éœ\µ_÷¨­Vhu¢0OµŠºê}ÿgušÃT‚ê§|p2%(4e%_«Í(éúú§ô Ö÷4ƉÍËÄ‹{kî®ÝDǽ„ê¥vÛÜ?’2ƒzh\ú*‚(ÏSÆÈ…ÜR­#ÈSy}?Mù"Íè¶–fÎuRS¨ža ±½5ò¥²ZÒ1Ù«ën]_nëQO\³'´VzW¯×'sÇÜ7N×(ÍS Uþ¶%F¢ CX¢Ñ*ƒ)ïY‹¬[¼ÇÀ:e¾WCîΪBÑæp•‰ß§(sp2î$¼¨ú­—ûñÅìd¨. ¥Ö54íá+ÌSZZ_8B[[‚»íïp>µ¦ðg…vºõbå¿.Wá5löã‹ÃV…öU0(ó -„.dÚjžÊãa,Ó⻎Äé6sO5ç> íà–¶mû÷a:{¨Í¶wÛ€H«.!—Ó`ko1þxÚò|½aÎRŽò )7¤Ú0Œ£ cÏzç» †Ršx›¿§š ÛÊlÊ‹%mÜm˜³ ‹lÃüI1JF‘õëhZó0c¶d”[ó°Ð<Ìš‡Yó°ètyÛ<¬(fvÝ!Õ†yÕhžªªÕêÊfn®îZòm<Õ\‚Ø> )¥"– 0wæáÎ<<2OîÌÓ@dý>Ú‡qknì×ìS8ûðÐ>ÜÚ‡[ûäÞ>:˜ò"Í©˜TDFÃI¿ë¢u“9¢ÑbM³z8·Åv<››ò]>š ’6Ƹ²mßÈÒ6•<óxó!Z>®Wi˜«0ráâ-¤ÚP‘£2W‡õAþåv¥JÛd몴×å*-b Òøqy_5@(Ë;}Öïæj¥y¸l¯H»¥+Qp•<ËÝÁýí¡€úÄ߆‚tmÕÇAˆ„ 72Y°EI@Ç ·ØŽxžò]†sÈØ¢™úæN(¥ ŒÄÜqPJ(¤Ý¹ìÿnøþ§endstream -endobj -1899 0 obj << -/Type /Page -/Contents 1900 0 R -/Resources 1898 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1843 0 R ->> endobj -1901 0 obj << -/D [1899 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1898 0 obj << -/Font << /F37 799 0 R /F48 950 0 R /F23 734 0 R /F21 710 0 R /F53 1027 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1904 0 obj << -/Length 3265 -/Filter /FlateDecode ->> -stream -xÚ­]sÛ6òÝ¿B3}¡§‚O~<äÁ©ÝœÛ4Ik§w7m(‰²9¥HU¤œº¿þv±DŠ”Üi/™„¸Ø],ö›3Å,5Œ«LÏ’L3Ã…™-7|öïÞ^3÷@ó>Ô›û‹Wߨd–±,–ñì~ÝÕ2ž¦bv¿ú9ºúøñæýõí.çÒðè »œΣï¯ÞºzGk/3]½½¹ƒil¸ `1®oß^þzÿíÅÍ}`¦Ï°à -9ùýâç_ùl|{Á™ÊR3û ÎD–ÉÙæBÅŒVʯTw?„½·vë”´I™‘:žÍ8Q™˜gÜÀ±ç‰æ,‰¥bÒ锘<ŠéËzÕtíëëãã -%Ys1ëãQPcÒRõH •°T‹#ÚwEw9W*‰ºÇ‚õ~³(v8Ž£fMkÈŸË݆ÇüÉíèzæÛmq)¢|GӲƽúÆô¹NÜ•J\ƒ·àb•7`<&âç$&oZ«’Dµt’"†ÇÈd"VñßU.6òäÎ]Ɖf<ÙyŸÚ‡:íS”õ©‹ýº-ÿ,^¿yU­AäpÅgi¨1ñ¡WÕK²Ø ©[¯*½5ãàÓõG€¶ùƒ[&Qük«ëhèÀ1Žâ(_=»®lI¬“@Ûë÷wÜ¡ŸòŒ2N0{ey3q;ÑTâÏ]Ñ2ty‚¼™e3ÿ£Üì74A‹!ó†éÄdC;Ù”µƒM2{„–†=ðÙ=–nep^˜,&±1ʸuk¢0àô °vKzZ=_ -!"d9K¢Ÿ0…@wë©î;ôäÒ)v9ÈOXZ0¶ãf_¯ŠÕ”ØoÉ0¼í¯šÏΦ!àÑÞí®ÝãKð!_¸taç}Aî0üI§¡™sH0ZæûÖÙcN¼uý¾/vϑ۸p°äVOÙšÀ›l­uÆÖ<”µµbU·¯¿šŒ¨¡9O8@)¥/èßT:$}*Q®­4RoliUµeS»÷ =ƒSq¬êk_åÊí W—ö´&|ˆLã€ÑwÎHÏòBÉ(8ÿ¡¦ýÿîÿ86˜Œ“ùäà˺Á+›p àõ”!ܲ‚xÔE:’Ŧ°Y¢Ë–† ºƒžTD“ÄÀM¬Î+bê´"({®Ÿëæ× $aeUÖÅHã”%à[ÏÓPc†ú˜@5ÀãlÈÁÇ]‰y–©“Ó²±ÏUK‹Uù[A#+OÜ}¸ÂA2½Ó|æôÑ.šÖí´'Û£Ú9d'›ÜQ§T -GûM^ÏIëbà9æGî›èæ«|Q!". Þ`þ†A!‰ \).Nбj¨ØPq¾uG‡¥"_>ÒâðL´†æˆP9M1°aáY Õ* h×ùn`Ùnw¹ÇŽz Êê Sðéç]²o - –õYÐÄ-ˆ„i¥= „•íþ´s5`Ð)7/ètêŒN{¨ Ó뼬ÆÕ!¤Ž*‰Ï“PcÚGyŒ‚|'Ò¾Æ"IC)Òt4èÐñ(í´×¾*þpïÚb÷dëFíÊx>7{‚wzPØ,ßäô¸»ùñÒ˜è§o.]ݾc´|ïÑŠ*@b+)íj· ¶|ñ –-JYà\‰:Nì‰UsKTV›ùN»:tgÅP©j´4çªÛn¿èƒcVì‘/ -¨’KÐ~8ÝIÕÑPSqÍ“óªÓ‡:­:*¨Î¢€Zd ®¡)d¬ W/0 ÆY‹-ìÍ…« -×-&Ã1y -ƒ)Ûm•?»E+l@!Ñ¡Ó!+iXuérK3Y±èÅd„Ê+t~ÅÊêóXø"èNÊÖyAHÙUj†:áC©U*›æ.a¸˜\·PŸ¶§¯TÅLÆü…T«uæJ=T¸RÝm±]§áP‰Èô<ñ5¦>¼NHk’D‹!ù H>Z¼#U3ü»›¯i< -^‚Êjûlm3À®<û—+áĪÀ1Âß¹¥Ûú 7üúü/hŽ‘Qdña÷‡÷S¼Ðkn-=êÝŒªø|µ*;H]‚mcÁÑÔãˆÒKÄ(å?¡*ƒ@“ry^úP§!@EhˇåcÞNd:’%€ã,u4¦>T¨&™©!ù¯-Ù¹„üÂ_š”X¿>Ôy·¦)±y‚}´KÞ¨?®ãÐÒk ½v`SX‰¸Í¶¬¬¡…4Gó뉆°N%Ó™Òƒ“¾Ô–,KÓtº!<_‹†[X9ËÝíÛ¯ÿuuwsZ@è1ªßy}èAÑeõ¡Ûí±é4ÿ­x~ýüéDtªÎ³ Æ< µ",VYp©*hŒn4Â?XÓî2öÔ/Ã9ðï6£GÆçÂíÜ·ÆjÅD Tif²ÐLû²oGüc+?Kí©¹´76mE ÓßÝü×·<áZÒLM%͇ÄÖ 8ưó®£ì|À·0Óe!‰…-ÎR‹øÖ6MŒ‹CIµA¨«¯&2ÙD0¡âø¥L6NC¿ÇU™@£jšßˆÈz²¥h&uh)Ú®_OÍü›"&%“™O›ÁYNv«%Sæô"Ò ¬R -~pÛ‰‹Èý’<Ž+rTª@$=qauî¾ïÙô]øá2²ïzþÊn|^qÏ_îýŒ&ý•LЙêl¦¸`BÙ?öWã¼rl°œK"Tr ü—ü•å)á›Wê´¿ -P!~uÍÖ6ÓF™L ¹×穨1ù£&XbD2¤ÿoÔ˹´ÝýÜU";3xqÌ„f4Þ;L i’Óv8Ðܵ…m!•«¼³­p0Ù±:Ág¯PAÙÅÍ‘Îþ=Øë›–&eUãë˜Ç8Ð1°j£¥9Pþk:&à({¡tîCÑ1t ?ë,Ï’>”Î#Ú“¥ó€öm½¬ö+ŸVÖÇ-2ûÝÓ¥˜‡Zôöº_HÚTÛ©E:|«ÐãÈ'óP ‚­A·R0ˆÕàÑŸS§êûOï°*½¿ýøî†ÐüðéæÇÛ›» ï ^QÆL‰ôðÅSB‘ýæö=2¬³(£…r³­ì—¿ÜeÍÚ~-­‰¥x±ÿ"2µÚýv ElK”Zêû’$€Šm…m+Ç -¤´&† Ô´HѰ»EtQ÷ GX_”Ži¬\4ÁB(KÅQø§ó)®¨ÁµçÏrd×§¿÷¡÷5܇ÔùÔ§3¡Y–d^6‹¼Ã¬I`p)"<%N›-r~IM„Ë_¸ýn Ý£mâR ®/sÇý¢8p_•ö‹4¬’‡Áu›¸XŒŸki0@4H@"fþ@@À«ÊÚ¯\ÚcYm½5¬Fl0á¥(å¿åÀh IbV1µÇßÀà ÷IÑ™ø -‰ -O½ ©¡ð°w_® ™¡ûÆÜ†åÜñS‚%>•«½-• DZ¯<Ë…ã˜tÎ5kq¥}3ùƒÆ«¢]îÊ…ûü4bºÐGÅj¾hž -üm „ wÓ’ÓïlEŽ3{￟=÷¤«YqÐvÀFî³V„ wƒ¯íÝààp‡‡Hï·,Ɔ¶/ÜsÉÂmÞoÝ>«fÒ_o^MumûŸ3ž·Å‘Ž,«¼=Ö{ºi -ßלãl›}µfl¹Wõþ”Ö#oz¬W¤wU³ ‹OÈ$¤û¹ >ƒ&Äž/«­Yè_á&Ï™û ->œ¹_¨ØE›­;¬`ÁÕ’Ôß· íðh¼1Û¢Û6Ãl­ŽëÓ· °?Ûí¶¦Q¶¿ïz¸«‚^‘RÀôK;ƒÕý¶rëä…¤UT¡é:ÝoÛMOJø¢§{0#•äò$‹pÜù©_Š)¨ÒÕä‡Bä?þÙá7r2üò>™'€÷d -?æ˜B± ž³n06¦2™àýÌMÀxendstream -endobj -1903 0 obj << -/Type /Page -/Contents 1904 0 R -/Resources 1902 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1907 0 R ->> endobj -1905 0 obj << -/D [1903 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1906 0 obj << -/D [1903 0 R /XYZ 85.0394 179.5067 null] ->> endobj -1902 0 obj << -/Font << /F37 799 0 R /F48 950 0 R /F23 734 0 R /F53 1027 0 R /F41 935 0 R /F21 710 0 R >> -/ProcSet [ /PDF /Text ] +1914 0 obj << +/D [1911 0 R /XYZ 85.0394 679.319 null] >> endobj 1910 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F48 955 0 R /F53 1032 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1918 0 obj << +/Length 2837 +/Filter /FlateDecode +>> +stream +xÚ¥Z[oܺ~÷¯ØGITÞ%èC‚¤9hOÝ-øA^Ѷ­´Yic8¿¾Ã«HÝö´Å>ˆ"GœáÌ7’‹w~xÇE* +R첂¥a¾Û®ÐîÆ~¹Â–æ#zR½»½úÓ_i¶+ÒB±»}æÊS”çxw[}IÞ¥8½†Pòþã/×oˆàˆ$oon>üöþã¿á# „’¿¿ýíóÛ¿™¾›ëÈ~ùðéúîö׫·^˜P`Œ¨’äûÕ—;´«@î_¯PJ‹œïžá¥¸(ÈîpÅ8M9£Ôõ4WŸ®þé' Fõ§K +`6òú Íq2<éIz9 ×8©ÛGóÞ=D8ùý½y~E®qžèEÔ]kè+Ùצ» +lhïëÁ4êvÂîûYž^®1Æ €"C,¹}ªûéG¶D3Ý¿(•iäˆg  œ–¨VVɇòÜ ¯“äù©Þ?ÄŠ"9ȲíÕ‡  (Ð+2Î@«úóúÑÒDJÌÒ‚ˆÂÒ´ÝéP6Í‹™·—m¥$Dúø!ͨZ`-{X€*ù=PЫ•)¢ò€ýëØbT¤˜d|·9MgŒräá8Øi‡Î<¿"DÚÊ "MùÔê0ùÃvµåA:N?äÉNó`ñ߬æýã­¶îØégå¨ÊÁŒÊRG†ˆ±Yš*u´åE Ñ 円ZÚ:~)Ió<£ðPmà×Qyüz/ŒÀ Á‚‰<ßæí©æÌcœ2(bîQþ(Àú ˆÉ…09£pp‚F%ùXZhÁ±žÌȃ¶Mwˆ>Ær]7˜n ½"„^á ÔžÏHh¤ñΗsÄc+:X)䞪 ÁT- +@ãâ]0ƒ±î½±½&Óè‰wç<ÐE0…lõ KžLQ– ¹ìÉ>ÊoÒ:`=È“wÓÜå»t¡Fà8^»ö|B­{ô]£¿%ÌêF¬¡e=Qz•A·QEÉÇÁ >×P44yy蚦{™<ÈÓ©lz;<Ú<ÓÀæ@d-­Ò8ƒÔÿÔ={A\¤ñŽi*OÈîÏÎwG§C+ôï1<—ý˜‰ì`†«£Èë•:”Vüž ‘f$Û~R­û½§ò~¿?T3¯GP«cz³§š³ŽáÙ…lÂ{ôz¥0aCMާºLІn‚au_=(„”yßw‡ƒl78™¬;dz¬€®~xñs{*Q,ÇÇÙ)R¥þviÇ3ìhTjÑ®ÃZÙ¤´ô¶_+kFH=•0÷ÒiåñØÔªÔGE¶ÐUý£2¸- á©êÐxo™ùˆ³:IŽ.$›jtŽÊƒœð4¬&›MÞc²™1_N6÷ãÍ? V“VÝRížLqþŒ%^½2ÒY¬]çÞZËÇãHÝF r÷c éç°j ¦¶«y†·-R­[ÂSyK8§X-[7ÙeëŒÿrÙ ðéI‡vpÀ/:ÿ‚óUéhuð†®ïLŸ ïÐøxcÆÊª²Aµ7ºšS#G/3Ñùp/On‚ÒÍz6MÌœ½ÌŽ0K³œ.n“(gkÛ$žr&üÎÆÃ|º³m»=’«ÔaZãáis< Pœ||0½f>ÝT1-#´ýÎï†Ô‹iC„éU.À†×b“r:‚9dkÔ®–×-ä,-hÆãôØk»EHﻳæ¶wÈMc\Á cÕr¦Ñ±ïa:ábz=Žî[-ûšvÛ5O½9½HCª OrTc"5±·_÷¤-ö'Mù¯xR(@XCGZ·5’£,ÑÔ­ìãå¿6Ùó ƒN!ëö€Ê@ˆ_°G@µaG5æØrö«9f“÷˜cfÌ—sLÄݦcšûäMçäª=øºG½hµB#¨{ýƒyªUÔýPïû?«Ó¦BT?íä〓)A¡q(+ùZmFñH××?¥g°¾§ñ0N|l^&^Ü[swí&:î%T/µÛæþ‘”ÔCãÒWDE–2F.äÆjAžÊ#èûiÊ·ÈSN/°µ4s®“ª˜Bõ [àˆíͨ‘/•Õ’ŽÉ^]wëúr[zâš=8¡µÒ»¸ú{½>™û8æ¾qºFi–b¨ò·-1mÂvPLyÏZdÝâ=Ö)óå¸rwæPŠ6‡«Lü>E™Cq'áEÕo½Ü/f'Cuh(µ®¡i_ažÒÒúÂÚÚÂm‡ó©5…?+´Ó­+ÿu¹¯a³_¶Ê(´¯‚@™W t!Ó†TëpðTc™ßup$A·™{ª9÷Ih·$°m‹Ø¿ÓéÜCm¶½ÛØDZu ¹œ[{‹ñÇÓn”çë Ö +”]H¹!Õ†aÕh{Ö;ßM0”Ò¬ÀÛü=Õ\€Ø6PfSX,ÁhælÜmXdæOŠQ2Ь_GóИ‡ó°%ó Ìš‡…æaÖ<Ìš‡E§ËÛæ`E1»°ë©6Ìã¨FóTU­VW6sûu×’m à©æÄöI)Íc ógáÌ#"ódÎ<" DÖï£}˜°öÆ>bÉ>…³í#¬}„µOæí£ƒ©(Ҍ擊hÃh¸ )b]@´n2G4Z¬iVç¶ØŽgsS¾ËGs!ãOÒÆW¶íYÚ¦’go¾"DËÇõ* uF.\¼…T*rTæê°>ȿܮTi›l]•6ãº\¥ElAC?.ï«ey§ÏáÝ\í@£4—íi·t% +®’ñÌÜß.äPŸøÛPðƒ®­ú8‘äF&+¶ˆ' 7øû·­Ö\ëy9-é° 0(Žd0‰ÝdYpØK¹SQ—°2»{›±=C¯Êì˜õâ3´ \פUìSnçö-Áu ?C]C-.Ô?7.¤ÊjµŽÊ^xײŸÃvôì-ÎkOY¯øvÈÛB×Ýt©†?†±×mzÔéè:ûÔª†Æç÷7¦áî‡"2ncúæÀ!œ¦Æ|éá¹%¨Û~e5‘Ï üEpLÕ#X®ÎË\ 6ë9¿È×Ý‹Õöâ ¶f^ßÁ¥ß|]¼”ßÏe—g?¥9¸šn¸À¬RÃ\Ý@µí6áfªsëÏÀôevÀ ¯b:ËR’‰ Ûå€hã/H–Hú$€Þb;âyÊwÎ!c‹fê8ð¨Qh›3ìѬšyÚÍ”93ÁÓÐ1{L›¾%LCš±b[$+f…t+öæ”'$5Ç>ŸÕ¡OS[:uO@iÎ +Óš8³tüÌÕÿoœ'xL:´Uœnþëvßœ«éᢾŠsPÿ~µòÇ;à«þ-·€´sÎõÿ)oüË!Ë cædO$ã)|,œPJ£¹ã ”PH»sÙÿmÅþ endstream +endobj +1917 0 obj << +/Type /Page +/Contents 1918 0 R +/Resources 1916 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1915 0 R +>> endobj +1919 0 obj << +/D [1917 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1916 0 obj << +/Font << /F37 803 0 R /F48 955 0 R /F23 738 0 R /F21 714 0 R /F53 1032 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1922 0 obj << +/Length 3268 +/Filter /FlateDecode +>> +stream +xÚ­ZÝsÛ6÷_¡™¾ÐÓ +Á'?òàÔnÎmš¤µÓ»›¶”DÙœR¤*RNÝ¿þv±DŠ”Üi/™„¸À.¿]ì.%fþŠYjW™ž%™f† 3[n.øìÞ½½Žfî‰æ}ª7÷¯¾QÉ,cY,ãÙýº·VÊxšŠÙýêçèêãÇ›÷×·ÿ¹œKã7ìrn8¾¿zÿéê}¼Ìdtõö溱ሒÅ<º¾}{ùëý·7÷A˜¾À‚+”ä÷‹Ÿå³Èýíg*KÍì3t8Y&g› m3Z)?R]Ü]üì½µS§ MÊŒÔñlĉÊÄ´š8ã¶=O4gI,uP“N§Ôä©PM_Ö«¦k__oW(ÉÒ˜‹YÍç@5f-UµP Kµ8â}Wt—s¥’¨{,¨Qï7‹b‡í8jÖ4†òy²ÜMxÌŸÜŒ®¡g¾Ý—"ÊwÔ-kÜЫoL_ +É3§Z‚ìȾÎ7Q d• “q,¬?^HHƵr×kdL)Ø$¬/T×—9Žn˦nËì[¤Q±rûY´Mµï +†«Ïæ2™”U.XfŒ´+ß[½ÐQ±Î÷UG§¼Ú»ñ²¥§Óœ¥ü…sY[6ÐÝ·%h­~ðdn^í”Ͷ˻bSÔn¾W¬}•¥šIÀ–Ûð«¢[¾Ú°'{[O)ȰX ¯Â¯`íTGVOÀC8VGuC:PI ‚­;;Qef¬¨°'-Ž”î͆A½I„iá5عÖ:zp$ŸËî[:ZŸƒ8è×Ö,<·lÝ»-t¨JKá¢á*ïʧ‚ÞÔ.yí¨?—UEC BÐÄàhÛ‚8.íúà®,Œ°G`Ÿö´°±j6yY·Ô©Ê¶óSú”ãSIÊR‘x˜"ÇåãÄY©”Á1x«)&–àŒ_‰ä9¹’7­UIªZ:M‘ÀãÅd"Vñßyrç.ãD3žˆì¼OíSö©ÊúÔÅ~Ý–¯ßŒ¼ªÖ r8â³¼Õ˜ùЫêŒ%Yl†Ü­W•Þš±ñéú#5†mþàFAHTÿÚb $ÆVå«§bו-ÁÈ: ôؼ¹~ÇÝòSžQÆ ^Á,o&Nn4•x‚ÅsW´ ]ž ofÅÌÿ(7û uÐbÈü…a:1ÙÐN6eíh“Ìn¡¥&ÞøìK72Ø/ô Øeܸ5QhpzY»%œVÏ—BˆEÎ’è' !ÐÝz®û=ù€uÊ£]ú–ôŒm»Ù׫b5åö[2 oû«æ³³i¸ðhîvW‚‡îÉ%øP.œXØy_»þ¤§¡žsHÐZæûÖÙcN +_п©tÈú Q®­6RoliÐUµeS»÷ =ƒS{ãXèk^åÊÍ G—öÐ>\Lã£ïœ‘ž•…‚ 8ÿ!Òþç|7˜Œ“ùàà˺Á#›p àõ”%ݲ‚û¨=ºéH›ÂF‰.Z +è6zˆ&‰AšXbŸê4•Ý×Ïuóë‚°²*ëb„Ç8e øÖóüÕX€!Èxœ %ø¸+1îÑ2uzZ6ö¹ji°*+¨eõ‰»WØH¦'`ø€Ïœ ÚEÓº™v§s»UÛ‡èd“;îJaëq¿Éë9¡.™c~侉o¾Ê.ÄÃŒßðRHbC—އ;èX5dlˆAìoÝÖa¨È—48Ü¡9"UN]¼Øˆ±Œp/ˆj•…e×ùN`"ÙÀÚîpõÀê ÓåÓ»dß @Z@.룠‡ [ ÓJ{¸V¶ûÓÎÕ€A§Ü¼€éÕL{ª€éu^VãìBG•ÄçYª1ï£8FA¼“ y_c’¤!i:jtèx”v赯Š?Ü»¶Ø=Ù¼Q»´žÏÍžè +e⛜w7?^ýôÍe¢£«ÛwŒ†ïýò‡¤ +±™”v¹Û„X>yR+…,°¯Dö$ª½sK«|§]º³bª-͹ê¶Û/úäûÅdÉ% vw:r*®yr:}ªÓÐ T:‹r‘5¸†n ˆX®^ P%8²›Ø›¡W$®[ †cò27R¶Û*vƒVÙЀD¢C§C4VÓ0êÂå–zþ°bÑ»“‘*¯Ðù+‹ç±ðEÀvÊÖyAÙUj†˜ðW©• ó‚”Ð Ü\·Ÿ¶§TÅLÆü…P«OuæH=U8R¸ºÛb9:NÃ!‘éyæjÌ}xœÖ$‰Cö?|´xF²f¸ðïn¾¦öèò”VÛgk‹väÙ¸X ;Ç ~øÎÍ(ÝÔ_¸á×àA}¼Eføx?% ¹6àÖÒ£ÚÍ(‹ÏW«²ƒÐ%Ø6&M=¾Qz…ü'€ 2¸hR.Ï¡Ou*¡-–y;éH–Àg¹{¢1÷! ›Ld¦†ì¿¶lçâ hRbþúPçÝ>˜¦Äâ ÖEÐ.áòFü¸ŠCK¯ñêµ ÂJ,Äm¶ee -„1Øš_O„u*™Î”ìô¥’°dYš¦ÓáyXñµh8 •CµÜݾýú_Ww7§ñJ~çñУ:ƒOeñÐíöXtšÿV<¿þþŒ0‘Æ@ªó"ª± CTd‚Å*‹‡BØl k›…u6wÁUµÑÍ"œñƒ5í.ÓhOõ2ìƒün2zd|.ÜÌ}ëi,*&J J3“…bÚ—}ó8’KùYz(OÍ%,{cÃVd˜þîæ¿¾ä Ç’fj*h>¶ö’€m ó1ï:ÊÎ|é#]‚XˆÑâ,µ ßÚ¢‰q÷PGmPê꫉H6L¨8~)’ÓPïqY&ð¨šæ7b²ž,)š„IJжê׃ƒS̤d2óa38ËÉjµdʈ^\4«„‚Üvâî ”~IÇ%9*U  ž8°:\î¾îÙô]øá0²pßõü•ø0<âž¿2Üû+hMú+™ 3ÕÙLqÁ8\eÿØ_…çý%Ç+Á¹$B%ÎÉ_I¿Hù ß¼úT§ýU  +÷W×lm1mÉÄ{p}ž{ ³?ºÀKŒH†üÿ¸œK[ÝÏ]Ö(²Ãe/Ž/3á/3jo‹†„ÔÉi:lhîʃ–ÊUÞÙR8˜ìN0ÁÙ+dgvqs„Ù¿‡1µ8iiR&ÿc~ÅyÉ ŒU-Íó_ØL@¢ì…Ô¹Oucž*` ?ëLϲ>¤Î#Þ“©ó€÷m½¬ö+VÖÇ%2ûÝÓ…˜‡\ôöºŸHÚPÛ'©E*|«PãÈ'ãP{A­[) +ÜÕàÑŸS¥êûOï0+½¿ýøî†–ùáÓÍ·7wÞ¼¢Œ™éá‹§„$ûÍí{XgQFåf[Ù/¹‹šµý0¾´Pµ&–âÅú‹Èü­Õî·[Hb[âÔRÝ—4\l)l[9ÁP!¥51 ¦Aº-`«[ôA§Uϰ…ùE鄯<ÀÝ&˜e©8ºþiŠ+*Fpíå³Ùñéï}è} ÷Wê|êÓ™Ð,K2¯›EÞaT‚,0¸î»Í¥À„¿¤&ÂÅ/ÈÜ~·’îÑ q(èÇ—¹“~Q¤¯JûEFÉÃภ\슟kGi0@'€÷d +?æ„BµÌŽE7x7¦2™ýËÀqendstream +endobj +1921 0 obj << +/Type /Page +/Contents 1922 0 R +/Resources 1920 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1915 0 R +>> endobj +1923 0 obj << +/D [1921 0 R /XYZ 85.0394 794.5015 null] +>> endobj +1924 0 obj << +/D [1921 0 R /XYZ 85.0394 179.5067 null] +>> endobj +1920 0 obj << +/Font << /F37 803 0 R /F48 955 0 R /F23 738 0 R /F53 1032 0 R /F41 940 0 R /F21 714 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1927 0 obj << /Length 1912 /Filter /FlateDecode >> @@ -8351,47 +8447,47 @@ xÚ¥X[sÛº~ׯ  aWš½ Ná¸Æ~<ö¹$ø¥?'q•è`á?í4Nû*mUx‡S`ÎH†o;¯ïæ³÷Ÿn†ÈÇ'TÊ–¤TùšcØÊµ2üj@xM sŸ Sîû¼½<‹¹ÅÓanö†YÈó§ÌI—(u€B`b*©#¶mwB^Ëë£BÛòøÀ}5ãùK ÙF¬šDÞ¶¬ÏP- HeˆTËã8¶¹½û„ï»Óº½G¯WªI¯*Uëâ•À _¶iÇ0ˆìŠ¿üû·ÏÜü犀U:d=Üx~sƒÞÏ>Í?_ä÷•®ôÌpè;ü£áŠÌ£ž0+ëZ¥Óïjÿ¢ÊÞ¤Ý@Ä}è¨Ád‡Ý—Ûð”õ‡J‚ˆ„~·n\*Á³·kìý×ó‹nAεgßeý£×gH÷új´ÆÎÚ¾‘νÍ:ûÀtØÇ^ÙÝ ä¼› ®m0ÁOx8ûvŽáásϩɸ‹ -nþó{×mEÑÖý¦¿mò"oöçÓ1›ïK½©á|ÑŽ`$Œà1FPQ@å1ðy€‘Ü7—Óð·0šÁ©ìi8å˜îË[ôæ¢yb>N“YQVõb÷úÔŠÒ¡BS˜'l/Ó´HêzðUB,-ÚEÂû…Â'Qà· Xfº9«/Œ~¹¬p»~VƒÏÅ€p.Ù±Ææ¢Æf¿üú!H̨<Ö÷÷‹úvIÞœÕ':}ø ‹‡à­ Â0>N×»´,’—¡]$‘at‚‚ìzëaíbeX <ûnÞ™]™J»£ñS{ûd(M‘ñáÏe<ô ü9h2N2FOLo¿¾Úþ_nê".endstream +nþó{×mEÑÖý¦¿mò"oöçÓ1›ïK½©á|ÑŽ`$Œà1FPQ@å1ðy€‘Ü7—Óð·0šÁ©ìi8å˜îË[ôæ¢yb>N“YQVõb÷úÔŠÒ¡BS˜'l/Ó´HêzðUB,-ÚEÂû…Â'Qà· Xfº9«/Œ~¹¬p»~VƒÏÅ€p.Ù±Ææ¢Æf¿üú!H̨<Ö÷÷‹úvIÞœÕ':}ø ‹‡à­ Â0>N×»´,’—¡]$‘at‚‚ìzëaíbeX <ûnÞ™]™J»£ñS{ûd(M‘ñáÏe<ô ü9h2N2ÆOLo¿¾Úþ_oB"0endstream endobj -1909 0 obj << +1926 0 obj << /Type /Page -/Contents 1910 0 R -/Resources 1908 0 R +/Contents 1927 0 R +/Resources 1925 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1907 0 R +/Parent 1915 0 R >> endobj -1911 0 obj << -/D [1909 0 R /XYZ 56.6929 794.5015 null] +1928 0 obj << +/D [1926 0 R /XYZ 56.6929 794.5015 null] >> endobj -1912 0 obj << -/D [1909 0 R /XYZ 56.6929 581.7741 null] +1929 0 obj << +/D [1926 0 R /XYZ 56.6929 581.7741 null] >> endobj -1913 0 obj << -/D [1909 0 R /XYZ 56.6929 460.6765 null] +1930 0 obj << +/D [1926 0 R /XYZ 56.6929 460.6765 null] >> endobj -1914 0 obj << -/D [1909 0 R /XYZ 56.6929 366.7195 null] +1931 0 obj << +/D [1926 0 R /XYZ 56.6929 366.7195 null] >> endobj -1915 0 obj << -/D [1909 0 R /XYZ 56.6929 293.4426 null] +1932 0 obj << +/D [1926 0 R /XYZ 56.6929 293.4426 null] >> endobj -654 0 obj << -/D [1909 0 R /XYZ 56.6929 247.3727 null] +658 0 obj << +/D [1926 0 R /XYZ 56.6929 247.3727 null] >> endobj -1916 0 obj << -/D [1909 0 R /XYZ 56.6929 211.2315 null] +1933 0 obj << +/D [1926 0 R /XYZ 56.6929 211.2315 null] >> endobj -1917 0 obj << -/D [1909 0 R /XYZ 56.6929 172.539 null] +1934 0 obj << +/D [1926 0 R /XYZ 56.6929 172.539 null] >> endobj -1918 0 obj << -/D [1909 0 R /XYZ 56.6929 96.3402 null] +1935 0 obj << +/D [1926 0 R /XYZ 56.6929 96.3402 null] >> endobj -1908 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F53 1027 0 R /F39 895 0 R >> +1925 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F53 1032 0 R /F39 900 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1921 0 obj << +1938 0 obj << /Length 4192 /Filter /FlateDecode >> @@ -8411,27 +8507,27 @@ VAC OˆøO´çföþþö§ïUA²$‹@d4І~¾õÕìáîG†þò‘N€ý£œ¡òÈþОˆ,Ü}²ŠÒvh#)*&[®J¦¯˜Mžè‚h@öaó‹R&MÌñÈlùYü>µ4uÉô•;>hØí+Hª˜…NÒ\ÓÒg o)¤\Š<•±½§‚aÙ¦CG¬ïµÔ2yÀy–b ïè•÷Ó/ÔŽê<ꓯêB_1ç ì`WAŠ3õÕóõ41ÒžþÀ˜¯%Ì7ÏüÌÁ¶óMŒ‚® N“:ç“ÄÄÅU@¶]¹ç¸SøûUÉôõiôõ<‡LŒB²c™ˆ5ú àlèAA]½Œ‡bá;pôå&œòo6Íëø»¾Þ‰ä ³ ÓqŒ'\ò̵î9'Ýȇÿ’J§YnìÙãdªTèÔ—Xj¨}-½%Ð|¡’®œxãÄM5ghêŽ,Ó†Nì4&Ä„9<¯yšéü)S‰ÉÓxÀö÷3ç,¶?g™<^Ä[T…‰Ã¼žft†ìÏîA¦0D¬Y^|m'NX§gOür N2ÿÆ[q#Q¤-›“«p’ž -?B£ ‚Ø{Úè€äN-(_í/ËŠéêS¦!$ë¯U~˨dÊôlÃæÉ×Öj‚ fö&4(' úuùRõ ™;‡i¿¦k~ŒðÉgêù.—Ögë¡Y¢Sm¿&%˜E%™µ£"}x•s(`Îß겉Ìss9ÛSâø®*îV¨6+*gS8`‚jÚ> endobj -1922 0 obj << -/D [1920 0 R /XYZ 85.0394 794.5015 null] +1939 0 obj << +/D [1937 0 R /XYZ 85.0394 794.5015 null] >> endobj -1923 0 obj << -/D [1920 0 R /XYZ 85.0394 751.6872 null] +1940 0 obj << +/D [1937 0 R /XYZ 85.0394 751.6872 null] >> endobj -1919 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F53 1027 0 R /F41 935 0 R >> +1936 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F53 1032 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1926 0 obj << +1943 0 obj << /Length 1971 /Filter /FlateDecode >> @@ -8444,50 +8540,50 @@ xÚ½XKs ]uI7¢Ý(ñ¬¢û-ìxM’o}À&à £áàý&ËÕ«ñÅ.XšˆoÏÄ•ø:­×ã —•kqÒÝðaÿ÷( ÖsC¶ºÎ“ºþþÊHß4˜Ø{ý£’„9ßE!´à°! Å †0JHvëÍ|ùáqñ°ZÜßyüé<ÐtA‚#(0ÇJËcs8¶œŠrË h4¹Q¹Ú:`‰e¶-ZVc š7KË8A×ÝšŽí`­Œ–‘® ÏJO_>>:†O»®£V¯el0ýxûÁXÄ…ÙkÃ8p»Ðóaȱ´@ßR˜Á½i›=+ ˜!íT}v¼Šœ÷m.ÿǰmI˜]!¯÷n_ËüíàëÝN«½B’ó%#(IÄõ%’gÉ~ED0Œ!–ƒ%?»;óò³€˜ar~Á†ƒÕPa=™oË n1{wïäø¤§6É1oήéew×µ—ß²Ù]®Y¤'åQ—*o€Êgáo$ §u%N«M}5×–<%àbIoúKÿ_Rðj€b ºqD®Ç§§ôzxœR‡ë|póƒÓNò®Ûê8óŒÍ¤¨ã5×:¥K߆´ BúŸ™¾oK€²µŽ\ŸLÐb~ -{AÈf†¬ë‰ç$?Úa¹ñ‚>dICß/ÿKÝåð|T‹ý¸kàeXoЕV»E[QIw%†—uâT²®ÇuÖh¢×þ¿…#RÿéêÉîÀô‡ÿÛ=ýƈ Aý5‚žƒ±uJÇ„zÙö_àKßÿ ýF¡Wendstream +{AÈf†¬ë‰ç$?Úa¹ñ‚>dICß/ÿKÝåð|T‹ý¸kàeXoЕV»E[QIw%†—uâT²®ÇuÖh¢×þ¿…#RÿéêÉîÀô‡ÿÛ=ýƈ Aý5‚žƒ±uJÇ„ð²!ì¿À—¾ÿýž¡Yendstream endobj -1925 0 obj << +1942 0 obj << /Type /Page -/Contents 1926 0 R -/Resources 1924 0 R +/Contents 1943 0 R +/Resources 1941 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1907 0 R +/Parent 1915 0 R >> endobj -1927 0 obj << -/D [1925 0 R /XYZ 56.6929 794.5015 null] +1944 0 obj << +/D [1942 0 R /XYZ 56.6929 794.5015 null] >> endobj -1928 0 obj << -/D [1925 0 R /XYZ 56.6929 684.0716 null] +1945 0 obj << +/D [1942 0 R /XYZ 56.6929 684.0716 null] >> endobj -1929 0 obj << -/D [1925 0 R /XYZ 56.6929 572.8605 null] +1946 0 obj << +/D [1942 0 R /XYZ 56.6929 572.8605 null] >> endobj -1930 0 obj << -/D [1925 0 R /XYZ 56.6929 509.4701 null] +1947 0 obj << +/D [1942 0 R /XYZ 56.6929 509.4701 null] >> endobj -658 0 obj << -/D [1925 0 R /XYZ 56.6929 470.2699 null] +662 0 obj << +/D [1942 0 R /XYZ 56.6929 470.2699 null] >> endobj -1931 0 obj << -/D [1925 0 R /XYZ 56.6929 433.5878 null] +1948 0 obj << +/D [1942 0 R /XYZ 56.6929 433.5878 null] >> endobj -1932 0 obj << -/D [1925 0 R /XYZ 56.6929 401.47 null] +1949 0 obj << +/D [1942 0 R /XYZ 56.6929 401.47 null] >> endobj -1933 0 obj << -/D [1925 0 R /XYZ 56.6929 335.1577 null] +1950 0 obj << +/D [1942 0 R /XYZ 56.6929 335.1577 null] >> endobj -1934 0 obj << -/D [1925 0 R /XYZ 56.6929 244.1508 null] +1951 0 obj << +/D [1942 0 R /XYZ 56.6929 244.1508 null] >> endobj -1935 0 obj << -/D [1925 0 R /XYZ 56.6929 168.8052 null] +1952 0 obj << +/D [1942 0 R /XYZ 56.6929 168.8052 null] >> endobj -1924 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F39 895 0 R /F53 1027 0 R /F55 1035 0 R >> +1941 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F41 940 0 R /F21 714 0 R /F39 900 0 R /F53 1032 0 R /F55 1040 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1938 0 obj << +1955 0 obj << /Length 1658 /Filter /FlateDecode >> @@ -8503,675 +8599,570 @@ a ¦×ã)]»Ž‘VÊÀí,1ͨ1)À«»h·uB¶q¸»+°#Ii«€Îâ!©÷ÏqlXz¼”âmŒš¡Ñ+ëþ•c¨ÄÍ>‹ìÑI$.ž”òVLK¿rS¤æ­Sø¨Šl¾çý–Ý_Yµ®Ðq¢˜ŒÇvG|5ùtü”ÝÙ{ÚJmÃÿ”…n¼®õÂèÑH¹fÞ(òE3º¼9·J"']fœ*È;ïNϵŠ™;æuRl’¼«#B+¥»ôèB£€">1î.άF&…êÎ"ÊùÏê¸ÀÑQuÝYÉ'1‰Úiž¾ÿtw> endobj -1939 0 obj << -/D [1937 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1940 0 obj << -/D [1937 0 R /XYZ 85.0394 575.4191 null] ->> endobj -1941 0 obj << -/D [1937 0 R /XYZ 85.0394 427.1073 null] ->> endobj -1942 0 obj << -/D [1937 0 R /XYZ 85.0394 329.3834 null] ->> endobj -1943 0 obj << -/D [1937 0 R /XYZ 85.0394 262.8864 null] ->> endobj -1944 0 obj << -/D [1937 0 R /XYZ 85.0394 196.3893 null] ->> endobj -662 0 obj << -/D [1937 0 R /XYZ 85.0394 155.0304 null] ->> endobj -1945 0 obj << -/D [1937 0 R /XYZ 85.0394 117.4002 null] ->> endobj -1946 0 obj << -/D [1937 0 R /XYZ 85.0394 84.3344 null] ->> endobj -1936 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F55 1035 0 R /F23 734 0 R /F41 935 0 R /F48 950 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1949 0 obj << -/Length 2406 -/Filter /FlateDecode ->> -stream -xÚ¥YÝoÛ8Ï_aà^ fù!RÒ½¥MÚdÛ:¹Úv¯ÛÅ–!²ä³äÙ¿~‡RmÚ^ààRä3CÎ'i6 ðc©ˆJy:ˆÓˆHÊä`¶º ƒ%Ì}¾`3r Qõazñþ“ˆ)IWƒé¢G+!4IØ`:ÿ9ü@"r èðz<™Ü|}¹ùãÓ÷ûo_¯>Ü|½1™$jxõðp3¾¾ûýrÄ%…%°€Òá·«ñ«¯8öp™òáÕç›Éå¯éo7ÓN¸þZ²ÿ]üüEsØÇo”ˆ4‘ƒWø „¥)¬.")ˆŒ„p#åÅäâ?ÁÞ¬Y<F ŠN„³c$•’{G"S¢æH&oU½nŠf+‚‘8Qb J¤d,ÄšÁqs ‘‹ÄŒ)«Gˆ±¢JK5¯š&Ÿžó·Å¦^•Ùc^^ލa”iAß®;LÄ$J¢øêÅY¹¬7Eû´B¨Ï͈Ì-rT†¨Å$<±ä}HHH’()-êçh ÄIµ fVfM ÄS’$qjQ¿pŸ?G‹AŸé¢Ì–!z‰â„ïÓ{îzU€òHD”D‘+ê,VWÙ*oßÖy€M“„ÓxŸÍú¬ØëMÝÖ³ºüç4Û³4Èè+ £÷r–^™¿µnt•øôô!Ôw·Oà#KEà—"Æ#½¾™|ü~÷0½»w«v (,K!`1~ÔpQ_vq*¡Îü—yÛ\Ž„dCXf{¯àØkŸrì,‹—¼Ò]nlü’ KüZl.Y2¬W˰™mÞÖmý§Ì æ¯ØZzY5ÇÎã¶(ç; °ó'¥¼ÌË¡Þè] FNpÏæ04c¤ý“J:Ég[ÇHÁ< ³wø•5ØÎsÍ¢ÊçøYTØ~ÿd)Aœ’vE5ß›‹¨€¼P!õUwo´võm “`¾Q”ħ£aå‚ôa4ìP&L¹ 'ûaŠB€Ne(æõ…cœž€O”®CÄób#W„CªñÄ›äe>Ó6Ç£íKwÐb–›lýTÌp¨rª ÉpŠX9|ÉJ°¿­ýª!Ïc „eÅÂ1ÞÎy‹\m›Ù?ZÉêÊuÈðûäêÛµD“Ôž -ß&µJÛˆÎé,Ø´08¹½ÒÆ(D<¼ž\½Ãñ1˜°èO&8ŸÀõ-¶šÃu±Ðv® 9ÇÑÛ¼,WY¥ùê:FàÌ; §¶ÍMFцŠâbúÌúþ2ËšÜ9E“WMт緌ƒIššeãºÕÈ8² •‚6³G´Ïšº§ö¾¤Û>Î ¶6 ÷©Ž,À=ÍêÕÈß2j(Îóù©mé  ·ÅðÐM(ضõ*k‹YV–o8Ô˜è©{hÉÐ=»`DE¶$ÇÜ?‚*DÄ2:íþ}Ôq÷ïP^•Òwÿ”0.ãý"¥/W*IL•<-—äòüžRˆÔñž`“u>+Œµî™­Øt×8´˜Œú±¹C»ä¢û‡ÉÅå‡/'ÿbÌ…û—b–£_ÓˆR©8£ê„>Êè£ -…cF »R£_7yј)Ñ$=-\‡ -HçGc×Ê}ñ|­¨Äž3tê×*×^¬[ ‡ƒ •Ÿ!CÚfŒ uœVÒÆi˜2§[ -Ò1aqW^ûÕ££¡ÚL…ðc4Í! Œ Ækàúßûñ Žh3À@™ ØR‘Lù‘"njaÀOm9¢‡4!¸û½4ÚŒ\I¨ÛûÉa†´7ãéÝôœÝÉÙ]¨ðëY‘µ¦ o¬»4$çÚìt'ÂŽw Žÿ˜Ü|×›åý#Wh«Úãª:®Š9ä¶É7{üpÂQ¼ŸÞö9펅à Í:ºk³2î|>lžžÉ3Á(ÝK>!—BšÆg*¨>ê¸Ëv(ã²³pÅ“û×3/†*¥xtZ0 -æÇPØ@*b_²»jé§5' —pM/Ç(Cwx—1@â䬮ڬ¨Šj¹· -:ÍS½--ú){É=6]´põ9ØíncUm…2hÔ¬N±,˜o±HÉÖæx¤¦{7¶±ß~ƒEΚø ‰ ðœ6ƒ>ê¸t(c‹`&U‰P{wjÏÀN•œËbyW5 õsÂ|±&¹)†ìåLw|­ÄÌÖºÏ1öÑ»I¼hå¥]eb{¹‹yHÊ7)­õXØp¯—W¦*‚žÃ-«â¯ HX†Ž˜€<”(ßé¿L¾ì²ø—ÜZ“biÍ>`Ô%¼ài13‘H‘8–g’{uÂDʘÈÓ>Ke¼õ K -°ì«?f„­Ígù°)*Wtf¶ -}ª7­ínW«lóæS]éT¯Û¢®š½›-ÆååV—Ù®4«¯ ª›S,wº9`ÔMŸåçJ¦ÌÝÐo$Ýó{Ä€ÃÚÅ((«9š}ßïØÕú¡¥h°TÔ’TØâ[tì;gÝ÷J¸ÂE”f;›åPynNØ1HAV=ÖW?¦·ïÇŸôXïph|0Èì E¸[¦QØy&1¾wkí*gõªoõÊZ½ò$ »!Ý“6D.ò›wÝ:’ÙcQí›?›ma¾jÍá[ÎY›iá…}™Öc†iÀ¤»lº£-탴yeÞ'ì»=jî*!LÐ3@=Ðqcw cë/á˜-¢8Úÿ»Â+[c’ò„Ÿ”Êa¥òo.œ¤4•žX“Dzyþ¸].»¢ÎHEŽýG*$Ñl¤¢Ýüÿýÿéîßâ(_JŽd#K‹•Jï±èPÏöŸÖCÙÿÉäI4endstream -endobj -1948 0 obj << -/Type /Page -/Contents 1949 0 R -/Resources 1947 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1907 0 R ->> endobj -1950 0 obj << -/D [1948 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1951 0 obj << -/D [1948 0 R /XYZ 56.6929 748.122 null] ->> endobj -1952 0 obj << -/D [1948 0 R /XYZ 56.6929 665.5133 null] ->> endobj -1953 0 obj << -/D [1948 0 R /XYZ 56.6929 579.9397 null] ->> endobj -1947 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F41 935 0 R /F53 1027 0 R /F23 734 0 R /F55 1035 0 R >> -/ProcSet [ /PDF /Text ] +/Parent 1964 0 R >> endobj 1956 0 obj << -/Length 2100 -/Filter /FlateDecode ->> -stream -xÚ­Y_“Ú8ŸOÁÃ=˜Ú³V²$[~$ÉÌnBr©Û«ÙüuòŸ“éðÛü—»É¼«+:ÁTÉôß»çox° ~¹Ãˆ·ÁwxÁˆ¤i4ØÞ1Ng”º™ânv÷¯–aç«^ê3§q%[Dd@J9zÆà)ŠiDµ1@‹ÉÓHé;ŸŒö ›¼ü&íXà3¼%šÃ¿7²´D¤C¥`X†5Ѳ¬k¹ÿo«}µ-²Yx§ K¹]³¨¶»B6²iÔ‡ÅBÖõêPoCBHðO˜<Èó}·ÏËFÓ¦Af—40·6ãježÍFšÁªÚo ¬'7ÅH°8²BüZÂú)˲Ÿrõç‘:¤äÆÑ l ›ÊÑ샺ÉÊe¶,ÍLuhv‡‹Ì7ym¦Ý3+íûR–Mþ;ÆÑ"kòªtì¬n0UN6C›ZVHǹ1ÏMf'Ö²”û¬‘KtÑ•1E8Ǽ…*íy„u†‚vx)ûüŽIrº)Á ±äú®-Õù¶½“$Æ,îo«ŽÓs†QŒ&öÌÝœ[³Ì¶ò¢©bÁc↩ºT—MÕRÝ4ÕÕ]¦:ÛÖkªÞ¶àó>KaÄ"ð‚©ÊÃVîó…yÑÎ.wæQƒwüWÇcweV¬«}Þl¶— s$HBo¸CuÅÀŽê¶¯íÚ1ðé¶~w·½(4B4ñMo<ƒÜ»hçØaÁªª‰0I¡C€-P…[NÿR'€Ejs™ÁjÍw~‰ƒÕ\ßáx -¤Ú¼dµƒ‰I`Ü#vÚ&ÖåÒÌÐC>ØærE’\€m½D!5 tÄXª•Ao9ú¢ïÍËÓ³Ø^ -çíŠËK¾—9IC.I ʾ‚=Ò—GÉ qìúžkx(–µª_ÔtZu «^^!êòêPÛurq6of• èº*UìÒ˜ÂÁäõ‘£eYI;[V1\r' =Ãm²WÙ-9Šn‚Èl=´“ûm^×"ŽpÕ©_Á¼4ôk޳‰=ˆÑÇÙç›EêÕ`åB›ŠT¥„ùXçëR9Qç³fKÓnd$p~©C…wSU4Ó$HÍc´Üæe0•5‡aêI®¤Ñ³\H3õ)+™VI ¸Ê#wè>‰pû?½¿7#NS?F!1ûûìãÿv&–(C a¤ï Sê³ A >OM×!F_矟nzÂ#d“})m%<{«!Š-ŒÞƒ·Wû&?l›2DU3`ذñÔ’ÐBwˆ1îû–Ê>"®I§ì.È8‹ù¹‡ÚlE‰™®ó$ýÛâ½­¨šª*~ nÞÊjWC,ŸÔ;14 òKSu†ÄWãõV`†]ç¥+ÔZ*ö1˜5´Õ'ï9&(&Â%#ö-׺>.|ñqƒ¾¶96¯ó?}˜Í$"ìèÂò"+aITyÓ¼í|¼ £ORáÄzf…»XY]û2IŠ„p;~3F{e;Zy8Cù™ð¶¨YÙÚÇšu0޳‰aHm„“\×7å·~ -xè±Tm{Oˆ\sw ±‡2®Ú.å«_ø·Ö2­o2…ü Ë5”·\­åÙxx†T©o*ºîŃßïúgÒ2~½)l!_eñƒîW‘î°Hy‚YŠÆ“ÙýÓã—ùãç©§=¹’À=`§ˆGiÔw9ÓbÙfdoJDQ…®gªüÑYºýî*xËìò¥TÅOiÚ5¨yš¼ ÈIÜ®(—'ß Ý1u×Cyðؘ)UâêàrÒ÷2+êªMÓ&€úäÞçPÛo®ÃÂÁ|öøáØ·)V¾\g‹c˜AÁ“5VíºUîz¨§.¶êb§Öe”jŸõÏÎÚz›/DŠ"JèõœÒ!rW›ç)Åi”véƒ÷ÒJDÊ}Ù£×û³ÅQr]´–è\¶^bÐ(!xO¸™, QVfÌvo0XìßvMµÞg»î)aªs)ý‰Ð=|àÁ+Ô$8Ø·jå P@ì”ÆÄŸ+û½F ²µ¨³=ÔÙþÅJ¦[+=X™ Ÿf£Ocn›j( D”Ò¾÷*¯*åUæžVûªÐKg#íj) Ƴ‘¾ÇeÁâ‘ö?ê)GÁƒñƒy*Öã|¥ÜVw7föAÅ6+Ãr·ãçÑ}â»4-'q]š °éÁ]•fG0€†+s$ª-ë¼É_/ß|ª+{Ïà6Fþç_Ž÷]1¨è\ìõ¯’0°4%N(¥1!üTôö7„sÙÿ(Ä7yendstream -endobj -1955 0 obj << -/Type /Page -/Contents 1956 0 R -/Resources 1954 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1966 0 R +/D [1954 0 R /XYZ 85.0394 794.5015 null] >> endobj 1957 0 obj << -/D [1955 0 R /XYZ 85.0394 794.5015 null] +/D [1954 0 R /XYZ 85.0394 575.4191 null] >> endobj 1958 0 obj << -/D [1955 0 R /XYZ 85.0394 752.0811 null] +/D [1954 0 R /XYZ 85.0394 427.1073 null] >> endobj 1959 0 obj << -/D [1955 0 R /XYZ 85.0394 529.0618 null] +/D [1954 0 R /XYZ 85.0394 329.3834 null] >> endobj 1960 0 obj << -/D [1955 0 R /XYZ 85.0394 453.6936 null] ->> endobj -666 0 obj << -/D [1955 0 R /XYZ 85.0394 414.4777 null] +/D [1954 0 R /XYZ 85.0394 262.8864 null] >> endobj 1961 0 obj << -/D [1955 0 R /XYZ 85.0394 377.7886 null] +/D [1954 0 R /XYZ 85.0394 196.3893 null] +>> endobj +666 0 obj << +/D [1954 0 R /XYZ 85.0394 155.0304 null] >> endobj 1962 0 obj << -/D [1955 0 R /XYZ 85.0394 345.6639 null] +/D [1954 0 R /XYZ 85.0394 117.4002 null] >> endobj 1963 0 obj << -/D [1955 0 R /XYZ 85.0394 279.329 null] +/D [1954 0 R /XYZ 85.0394 84.3344 null] >> endobj -1964 0 obj << -/D [1955 0 R /XYZ 85.0394 194.9705 null] ->> endobj -1965 0 obj << -/D [1955 0 R /XYZ 85.0394 119.6023 null] ->> endobj -1954 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R /F39 895 0 R /F53 1027 0 R /F55 1035 0 R >> +1953 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F55 1040 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F39 900 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1969 0 obj << -/Length 2835 -/Filter /FlateDecode ->> -stream -xÚ¥Z_sã6ϧð£3³VHJ”ÄÞSº›Ý¤’½Ú¹^ÛÅ–ÍÊ’kÉIÓO J¤-Ë7;;¤È@€Ÿ0øÇ'2b%Ô$QQ —“åöŠM60÷åŠffA3õýâêæs˜LT bOk‡V°4å“Åê÷é÷ ®›~zœÏï>Î~¼ûíËÝãõŒ«TªéíׯwŸþs=’ ŒM¾}üõö'ûz­ÄôöËÝüúÏÅWw‹N,WtÎB-Ó_W¿ÿÉ&+ØÁW,Ãä >XÀ•“íU$Ã@FahGÊ«ùÕ¿;‚άY:¨ -ÎÆb@"tt‘ò@*%'‰TA”ÖÅcÝæ°©DMùw׳0VÓö%kqd]ﱃjú)›þ2¿ßßrœ)l3l¶YµÊÚzÿŽÐ¶&ÔvWæÛ¼"ºY¹©÷Eû²5“),">ó[‡,Ø_ótš/ëíLk¶;ã`÷Jïjö¬YÞ|–ÒA‚BS%ÁÀ ä[þÞÿäÇ¢q0±(äá¸lj@¸Ðc)ƒˆ‹Ä—n¾Ë—¨Fä ªÜèMwªÃö9ßc¿^cû\´+*Ýòi{ͧ¸‚ëmÐáÎ"&a)-_êb™û”4ÖtÌÆMo•ïÀ´ˆ~mé["ùË™…aò[ÓÄÍc˜Qhüí¹Á¦w!eø7ØÛš{ϹmÛ·<¯ðCr´>è¥u¿OÅZ{Ñ$NÞçe F?ÈnÀ­ óH9ÌრÍ)J‰9ŒDLÅDæZ7èÁ0Fl`íÊ Œ»‚N§œ‰¨'ìMê¶ùßÙ’Ène[@€Ú‹>dírq ù1I);ÝKÒ½tuüÈïQjiΓt‹/x²ƒñd‹2ž\]ôä*ÛæíûnÀ•ã b©®C Hç¹2Ì†Š _<Ï•EœR„NýViOúžÑÂáàÚCñ€+÷Æ=XO½få¡_f”¹ê< x§ª…#Ñ%+ZuÑùÙ\eLÑ€ëŸïpä&Þ‹ð‘Q`II¸»=ÓÃKS»š˜þSWÆ12™!MòŽ€A_\ÿÿ€¨û§ùa†´w‹‡Åo8ÛËÙݬiêe‘µù -¿ß`;Épà¥Æ(Ó‰ÐóöÙ¯ó»_ôf…»sä - r¸Æט[$Äý?œ°Ÿ÷.§^-‚49v 4ÄSüXfRTM^ & Mѯ¹ Wù:ƒèA1À¤+ÐÒiCom“ -û›lîúº:ëø =})Œû½:ïöd¼~9äõ:ùƒ”ÍxYÂIK¥b !¢Q©,æT*Ïݯ ÃvÅz¨V÷´æD¢Ð榗c´§;¢ËçL»ÂÉe]µYQÕæhtš—úPú%{Í=œ˜6]´±µô ³tú°Æ±ª&¡ -c&tÎqß@e¨OÓ}xôÓH¼âÏ“AÊô‚8¨°(c'®6¥x:ÎÒ‚XºçC7\Æcù°öíÞ”¹ ±Åç¦Ojðb5áûC§+ZƒM‰n»¡ÑüïȪ=«Î(1æ–Œ«ÓEWg‡2ê\¸”Gi“G­ËlsâPàsiœŽ‹eAb¹*W2€«„ûbÍMíPÒ©;¾‘'œŠÝ&öÐý$G{.i•¹j]d!)ßCµ%!ݾzyeªèYܦ‚¬yH¤]Œ‡A§±ïb?δ•Ü9LóbSuÆ£tGôÑ·+×MDh“åqP#&bQÆD6ùV%Ùy(í8Ù‚¬( ¡n•®C ˆç'[:H«Ô—O»g("Ï=õw†_葮Ў£†‘@GÕã틎s]Ø\étL†bz[–õ›>v °×±aj¯cý!h¬" ¤Õk´L_°Ð· -.á0d[ó‰Ò(×´ÈR4à[¹%vwûb›cwmä©·¸ø—ÏqXÈPaï­(Kì=Ó×^¬‰^Ý4Ås™ÿK{„:?|+ÂkWHœV˜Zøw†8k¾aœŠEŠ~uÞ|;”1ß—“ #˜J.°´ –®IBÐbIzÄò뾨lNE®ð=é¢9l·Ùž|ÞÖgÝI½Ó‰UsTnÑuqÐoH}²†9½—ýG -LJ$ä—«ªiòå l¬i €M*™ÚÜéüÙè?ަœ ÌÁ|;{0#üús9æ7x,¿/èP¤ç.›õ>)pX™£±½›-;«;¡T^(€{ÌyÍÆ(nw±øÝíë¶^ÖåÙâwD¬¾ô=–k°ðuƒ[Û¼)z+:™øƒÂ˜)*`õ¤©.<8=€¸rŸ±$Yœ§Šáƒ!|v/fÂyÇÐŒ`àXXº*ÈçYâ‡`!¥ÉžéáLîD3ø0Ñ ÚP7Ì–kPìÚr æžÈ€ kÃ'~uÅ›U€ÄÛF÷\OwGhuy­Ùc™©%©°5]w °KZF[<*ÿ -?šÃr™CÕº±ÝŠä’õ:¨ûµ(cÁûKYçį·«üõ4£€š%‰’qá:Ô€t¾Ë€ËؗΈeöå“A¥UÌa˜'T†Ù¤nQÚ*7UWKÌIú•€Üõ¹‰&ôg¸Å©Umù˜MO“}¿+Zž ¼ô„`¥\ ëò7 ¬kÔiDiêŸ< -9p €°0±wú$Ü_‡lÕ˜¡ö _,ss„Ò¾«Þ/ôO=<¥få¨Ç‹¦sïç:³µ°™©v¬‚Ž7BÆÇX:dGÛ%¢tÒ{÷ðO5²gš72ÂóÄÔšåK¶Ï–­ $€C r­&XÒ˜[Èk<)ÜÌ­²–ˆêGÝ>wJ·`¤¨À(²•/ÊxvEÏ8 ›=˜Mf%~`¤=Õ¥þùAòî‰Na5üDrn-¬pÞ9ð^l»b×9G“ïésì2|¼pž–GŸx"Çœs>âÆÄ›æâÃQÓîójÓ¾œÞ˜øh}D¬s"—ÿ«Ü5"Ž\ÁŽBýÍ: ûF&3b/NF?ݸh÷÷žØþÞ3H¥ F6ÝEÉÜ‹>ÁLí.µëóй:Ó -2å{Ùò°'Ž­ýð%#ƒ©èyq•ëW9Åî°‡2·†Ó¥ZpŸž·¨Y,.S>{ýîIJØ×ùžÀæ±[·–dö\”EûîÏf˜¯Z£|â ‘\ r*Ï`Ì0H¶ºª®§í<³çÕrÿ¾£0©Éžÿ \-¼Ðȯh2¶þzña§Ì_ó“"BA©+ ¨“ÊbN¥òŸÓTÍJzbaáÅ«üù°ÙtocFªàÜßž@¦ ÿ`d@*6±‡óÿ]Jÿ÷7Q¾t®‰ `ql…ÒûƒÃ:=gú –SÙÿ殮Sendstream -endobj -1968 0 obj << -/Type /Page -/Contents 1969 0 R -/Resources 1967 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1966 0 R ->> endobj -1970 0 obj << -/D [1968 0 R /XYZ 56.6929 794.5015 null] ->> endobj 1967 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1973 0 obj << -/Length 2183 +/Length 2624 /Filter /FlateDecode >> stream -xÚ¥YM{Û¸¾ûWèЃüd‰½ÉŽ’x+i¤<Ý6ña‹»©){½¿¾ ( ½­} gï|Sd„៌C˜ÊhË1LØh¹¾À£Gxöþ‚XšÀ]ª«ÅÅßßÑx$‘ä!-:¼ÂBÑ"ý>ž|ù2½½ùå2_¡Ë€a<¾Ì¾M>™½/—2OÞOç—1‰ˆk2ŽÇogóùô:˜ß¼Ÿýçólzy·øùbºhë*O0ÕZý~ñýR8ÃÏQ)Øèn0"R†£õEÄ(b¥n'¿˜_ü³eØyÚ¼êƒQ˜c!‚$cáL"NCÚÀñ~:›~è/¦oÍù?Nÿ=×'ƒ÷iM<‚§($Òàø¯•*,éP…Â8Pk¢´¨*µ ~S/-u—'—(ލ%^–ëM®jU±W»åRUÕÃ.Ï_. !ãŸ`_Äã¬ÖW<Þl³¢¶´‰ÙªjØ{4[åƒÙ«WÊl<”ÛµQ!:P˜bXKb•øXÀz“$É›Lÿy”oŠB&í uiØk9@; -¢P Q> -Z쬪“"M¶—DŒSs¹«7»‹<^¬²Êl»kRØûTuöãp™ÔYiwÛ“Âf樰¼í˵¹®ËÌ ¶I­RÔë»8B”òp ð:T«‘¨‹,íðÒüÀ$>J€@ò(>/µ¥:{`J‚añC±Úž#†EØÝa~ -`‘¬U/T\pˆ‡(:U—ªª–jª³R÷PˆõBu œÞ‡w { *vkµÍ–æ¦ñoµ1— -·ã²M@vßLòÇr›Õ«u?À·5ÎÜ¡:°£øœÔÀÇbýwÅöe" >èû\ lÈÿÀ »ð(˺IаI'7,F¡€„u ‘ˆWåèÃKÒ)·4¶Mš4Mi4®ŸK½`c­V®*ÈÒ”±ñ3Öèª É}R©Ôìj¯h^ׇÔÏÍÝS“Þ/]sŠbödk¤¡:=ð¤HJr”“—%8hVýÙÝçΡ5?W{š¤œzt"!øD_Ap°'€Ë£‰(•ŸUǾ 2µ&ã®k×¢‹•òi µ6Œ°¤ -JŽ]m3&“`ÞÑNß%úë~ÈÜCÏ`Æ=–¥«tz¯^%µe¢«š^Ü+ê­1;ì‚”þ|ügYXñ]U´Ó§™•TCwаÒa ŸZÏÛ3ùÛÍ,°¥™#.Ä‘\úövêª*½VÒ]Ï0´"qL\sÆâÀ²­8†7"]x£Nj ªZšêoèšàÏÓJ7¤"¿kN ûåýSVîìëÏ;xýÅ<²[•Eœœ‚A²jÏΩ–ʾ_”µ,}'‡€­’'Õí&ònîOlw³QÛuVUý½8^•`$P¸¡}ðÑñHºàI°ÇmzÞ"ŒµÙÍæ0@!fcÓ­ipb¾oœÌ³¦çÒ‹êe½VuSõ­*–Û—)zúµÖ–'4µ+ËÝî|¸\[÷Ôy„èÎòîÛ·Ìfõ¤ -—ÊÝãêLÞÒ¨ø³‡yìŽÖ°ý}49¸ý¾htưeM›®µ™þ2¹ýòi:<,ôL¡{cJ x—D$×°Pf?1—˜‹à¾iU)ŒXó‰Ù5ÊR×ßÂŽ9)ì¤åbÅš]˜èHtÍŠú#Ñ#‚ÉÂ7|À©XÛØhŒ]=ÒÂÊû±£$zƒ1}rÂñ°¾7Mµ`._áÈ÷'OwGÐÑSòúÉÆíØÛÕ4•è2ÂiŠÜˆ‰t¹ªçŒ=)ŒpPºª³9 -¶Äm-n˜\A¥9îh„Ÿi=(ä=Ì]%ò~ÐÙ`{>µÕròiþy8XCTÙc¡«¹®ÝB—WkB*»l’9¥®nfö‹„´ÓuVdà‘IízÞ¯êAÛKë”·I±ƒšäsÎyð§ -@'Ú:þõݵáÓ¼ôð‹ 8j üev"bÿ;»è˜8=dç70• ‰ˆÄ~òmñáó×aÃÞ@»¾-”Mó— -Z'Û»^C«Qnël·Þ‹…ÊqWP"h[¥Я‡²€!—¹Šë(œÞmˆg0Lô¨&à\±×ç쨆±Y™¯xf½®©ÛTW—e>\ ç/E¹©²êx”„Ð#’ SǘžIRGwÈ´5½Ã-t”L4ѽgq:eº¸¥òž^׉ïArçVKs2v8‹HÑý˜—'•/é… »œÔrL='Á™ËЯC¯^n_¹¬ú o¼@WˆÑv#–yƒ3ôIí¯³1=qŽ_uþ5«Ai -…asœ r¬Ê$€q5Kò~m t œˆ“)¹ÃœðøW¬öÙ‹0£Ž'6çʽÇ=ĉ§mÚÕÖ#ë0¶ÐÔëT=õÄ7f'€WÀ×ɶî‹p PÜ6 -׺]=õ*íøç0Qå¯ÏrÞÙÞKH(fòhNûPÀ"I°C©JòÚû„&¢Çò> Çe­‡R˜6«×4±+]šäfö!!„îú>Å‚\ý;”§Vá¶>þß?wí¿éBV¡Bì¿ó~.m¾ïCb•ÒÇ#§tÛÆNuÿ/<ýøÀendstream +xÚ¥Z]oÛ¸}ϯ0p_ fù!RÒ¾¥MÚdÓ:¹µ Ün·Š­ØBdÉ×’dý9¤$ʲ³À"¤ÈáÌs8<¤ÃFþØH*¢bÂ8 ’29ZlÎèh}ŸÏ˜•™8¡IWêÃüìý'Žb+®FóÇŽ®ˆÐ(b£ùòçø È9h ãËélvõqr{õãÓ·»¯_.>\}9Ÿ0Ej|q5½¼ùßù„K +C`¥ã¯Óï_°íþ<æã‹ÏW³ó_óßÏ®æsÝ 0*´gÿ?ûù‹Ž–0ßÏ(q$G/ðA ‹c>ÚœRáZò³ÙÙ…^3tpA%\(>°"œ#±”Ü[%¸0K2{-Êm•Uý©FÂH‰Q(˜fjÈ4ƒåæœ;â  œtU·6('¥½ZU•.&Oéëã®ÜäÉCšŸO„a’hGß«­ +&BDAvõà$_•»¬^oPÔ·f\æVr’i I,xdEÐö¡"!I¤¤´R?'‹M\XÃeyRUšxL¢(Œ­Ô/œçÏÉã€Bßècž¬†ô$#Þ×÷ÔÔŠÍPPÔ FÉ&­_·é€™ $§aßÌöM··»².eþÏuÖoê<⣀Fßó›úòôy0ê&V‘¯O¯ŠúÛmÂ#øI9@nF]^Í>~»¹ŸßÜM›Q­ +Ãá,±}€ƒº¾CŠSuð_¥uu>’a˜­½ÀvÀZ½N±²ÊžÓBW¹Áø9çøõ¸;gѸܠX‚Åb÷º­K¬¯#±|ÁÒêKŠ%VöY¾l=ÀÊŸ”ò<­¬…r§g1š8Ç=ÌajÆLû'•t–.öÎnƒ~hfïð+©°\¦ÚD‘.ñ3+°üöÉj‚<%íˆbÙë ¨€sa „Ô݉ÚaÖ·‰NªˆÄñÉlØ•rIú06R&M¹¤'»iŠB‚ŽåPÎë:Ç8#<8ô®‘pÏËœÐé¹7Kót¡1Ç9G|é +"fµK¶ëlM“p¦ +ÊÆs'ûœä{[-‡¶äd Ùi8Á{ÂRƬàf_Õ¨öÁ©/Z;¦ü6»øz)ß!‹Ø +}@‚ÈìúBNDl|9»Ð5)ÇS€©èvrlj%°“KeÇâ·d»a˜òòKöËìQc]ƒÙl,5¾Nó|bü£Î/d3›¤ÐA/&£z1+»CÌrÚ}‘t·Î"q"YQ¥E•ÕH£;" ‘Üèå £qQê2î,¹iÎ*l®¶é";Çí.õ–(PÌ.ʾdyŽÍ&Pî+³]¡ïá[–éc²Ïk«h_@ʨ°GãjàbRæNŒ‰@ HÈ›¤]në¬,g1±Ppz +*}dÍüªLn¡¿°×XÅ…Õµ.(¬˜™·®=Xœ·†:M–Baüoñ…$”ìä,%$Žæ¨Ó3ëZ’6=›Š-ÛˆêOd€°T`‡š‰sdP½Nj‹°4àÓ†juëtñä³ÎýØZn¶I=dyV¿º¡ú”Ò5³ŠD£{œÓ²N1rì7ð^ÅÎhAýPÁcÄ ‰ú@taO°€m´Lêr÷Š¢µE|¶Ùæé&-êÞ0C{Šh;³‹ŽZP€¦7¼iÓb™.ɉiéÃê7ÜÓ:1˜%Þ×åk‘ä¹]«Êœò ;jòäM*’9vLëß>¦ºRÇ©FÊcÓÝc*&ŒË°O¦»~Ŷ°’§ýrB~y»€R`aϱYƒÞþ’Ù›…®šJ$M]ÑH;¤ë‡$Èñ•ûÛ³ÿ0æhÉs¶H1M‰\z":®Ôñx4R&Åm`XƒË]~ﱦH@£ø´sÔ€w>k`pµ£ÜwÏŠŠì:C¥|)R½‹õÆÖÎaã£'ŸàÜzÉë#PIË' Ëñ 6Ì'XØ\ý[ŽO'àV áó P›B*@íqVÿ¸›^a‹†&"øH\b…KªŒù²óñ_HNbK›u“Vt{õã=ˆA¡aä¨/H]ßÍæ(fLAy5ßÌ`oët$=½p-YR›¬ ß6óÆ %ùx]š™¶.´¶’Ú÷ÙÕ7=YÞ9Z…­ªžUÕXUÌIÂqµëÙçñn~ݵÔ. ÁFG‚oI6ÜìQø°$j†õ²4†¥ÃŒ·¬¾cÇ2~cËv¤NlY'e¶ìb˜ésÁdÿÁË¡ +ŽœvÌ 8æçP˜@,Bß³›b ÇOmV4îÀ5µ+ ]á͈ ;eQ'Y‘«Þ(Tªu¹Ï­ô:yN=9Þe V£^s‘ˆ­B[QZ§Œ´¥t\¿¬Ì°ÇepIMõfjs¿ýÖê( ô?T‘8 ƒ®Ôq4Rƒ')t«ÞÛÀI¤¢Ón9¡·¼' ÷¼ˆùnÍRC†ì#‚®øQ ™åºÎñüìJ·öÆÛQ&·w%Ûœ‡ª|H騇¦{=¼0¬jNnUd ºdY.D©Hù˜¸Ý¶§ømj‰Ö,[YØÂ´Ú¤„ÚA<€ŽADÄ„êלÓéH€ˆ“2Y÷M*¸ùÆá&ЀÉnøCFhõLÞï²Â‘ÎIJÐu¹³×€j¿Ù$»WŸL5Ô ¯]Uïóòj¯i¶£fåÀ«‡k\Öl_ÅVi1phÃ$c¹„y<64Ò kûv¤NÄÆI™Ø<Í)“mlLƦkòs +”)q÷Ü7’öö]bCî‚׸ÂCóа£+ÈÂðœƒ]©ã+ØH™ܾI]»ÏȃÔõ¤s-u=ônºzîÍð‰•Åö9•SpǼš¢K¦Ë’PÝi‘'¾²ñZbûSKd%¨™×jnöÜl@ýYì7:–ºé!­_Ró¦ ÔŠÁVCúáN{/[\Js‚R÷ÇÜ ~˜SJ¡ ê(VG¹ ï΂ ªÛ²ª²‡Üjj˜[ÝX¯ÎîÞï¶ØÑù¹6TQ{R`‰o¶P±ï¹œ5SìQ¸Ìe”j¿X¤Àí–pË;Èðž +ß­.™ã.KÃRî 3æ6·=´ÐÃÛ”V-¢ :ø-Æs„+¨ì=ÌÚG"ÎÜÃlkúâûüúãÝô“þ­õ6Mï™m´î‡¦Q´}ÆÃiOïÜXƒ]åP¯º¨WõÊó€´Mº&mŠ|LwVؼ påVL“æe«Ó›ìõãhmßZNêD;/ì/(ºÍ€tsš&ÝW3÷"‘æ}¾;€Ú£pWÜÂipí¡ã`wBëÏÃ9[aÐÿYÍ£­!‰yÄOzåd½òo.œÄ4–ž[³Ã‡²eú°_­Rg¼"Ç~Ë’è༢ÍOEÿúwþö¿‚öRtäy‹‡’À`åœÒóƒ`ÆÙþGÀ¡ï •úendstream endobj -1972 0 obj << +1966 0 obj << /Type /Page -/Contents 1973 0 R -/Resources 1971 0 R +/Contents 1967 0 R +/Resources 1965 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1966 0 R +/Parent 1964 0 R >> endobj -1974 0 obj << -/D [1972 0 R /XYZ 85.0394 794.5015 null] +1968 0 obj << +/D [1966 0 R /XYZ 56.6929 794.5015 null] >> endobj -1975 0 obj << -/D [1972 0 R /XYZ 85.0394 752.3199 null] +1969 0 obj << +/D [1966 0 R /XYZ 56.6929 749.0289 null] >> endobj -1976 0 obj << -/D [1972 0 R /XYZ 85.0394 504.8188 null] ->> endobj -1977 0 obj << -/D [1972 0 R /XYZ 85.0394 359.3246 null] ->> endobj -1978 0 obj << -/D [1972 0 R /XYZ 85.0394 298.3625 null] ->> endobj -670 0 obj << -/D [1972 0 R /XYZ 85.0394 260.8495 null] ->> endobj -1979 0 obj << -/D [1972 0 R /XYZ 85.0394 224.9084 null] ->> endobj -1980 0 obj << -/D [1972 0 R /XYZ 85.0394 193.5316 null] ->> endobj -1981 0 obj << -/D [1972 0 R /XYZ 85.0394 129.6476 null] +1970 0 obj << +/D [1966 0 R /XYZ 56.6929 675.7286 null] >> endobj 1971 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F14 737 0 R /F48 950 0 R /F39 895 0 R /F53 1027 0 R >> +/D [1966 0 R /XYZ 56.6929 599.4635 null] +>> endobj +1965 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F41 940 0 R /F53 1032 0 R /F23 738 0 R /F55 1040 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1984 0 obj << -/Length 3093 +1974 0 obj << +/Length 2139 /Filter /FlateDecode >> stream -xÚ¥MwãÆíî_¡#ý±óIrÒ““u7N²Þmì¤M“h‰²ùV"‘ZÇùõФ(i_k8Ä`|c(9ð/g6‰§Ü,u&¶BÚÙbs!f0÷öB2Î< ÍûX_ß_üí:¹Ø%*™Ý¯z{e±È29»_þ}'ñ%ì ¢7·ww×ßÌïnÞÞþçýíõå\f©L£«®oßÜüûr®¬t@"zwuûÓÕûpéTtõöúîò÷ûï.®ï;ÆúÌK¡‘«?.~ý]Ì–p†ï.D¬]fg/ð"b霚m.ŒÕ±5ZÈúâîâŸÝ†½Y¿tRRÄJ'jBJΤŒµj ëâD+íÅñæúî›o>Üß¼¿ÅÓø5{ Š8ÎR¡<ò²jšb1oÊÇ꯺*xî-HÓX+“ÂBÄGÄd–˜(LJŽpHT[Ý´z,ªb›·#Þ‚Nh"¯–úñGÐÁ¶—2‹ŠEíŸË°7!êèÙƒëånQ É"#ïö©Ø6e]ÑD½ÂC€è˜ïy'/`¿}*ËeÑ_`Q})#ϼ±ItOS.yì¶e s¯ hóv×Ð:ØÝÖźxÌ[ Ê+btCÓŽMz{èoŠö)o ^6_‚ü¤Œ^ž -X¸%œ6ð³x*×Kævhš“ÜüYE8$ùƒ?Ízã®·ô¬êKz)z.‹¶ØnJbÞ^éIäa@(š¢ZŒöËúÀÉ„Lßæ@G±eúX¼6E;aj:‹µ³'´ß„PkÞ}hùâ‰FA,0$ ¶Þó¹ -|J§±RÖúß{ç8ôu§R&³D›8ÂñMBš÷±‚kª éÎó1IŒs2;M2 MìK/aªåäÏ— «Ø–+Ök¾^Ó 8)Ë Ìœ••Uf"=#›Ö Ù,/›)T´Çôq¢Äb7͘1—Ä™Tæ4ci‚1= ppœÝ=‹±hF®é†mÑs6ðƒ©3Î)qÚTÇi"’Óâìcg‡åÅùqJœ2ΜÕ{7³•%±…½OrÅ8LõEé$ä-€ ˜º¿t‚ã=Æ>ð˨鄻$råyÃÏ\yC-«Ç6ëmΫ×Ñ<Ðùcƒ©_iˆõ%ï^?·>sàx“3‰‡â9ŸSà|BeÔ²Ù­Ûò9ª¶Üœð«%Ø,<­îÖ u,¯îõ„º],• ‰{Yoò²3†Ÿd¬OrÖaM°6ôà-±fÈÛ[4½ôm£7?`Åõ3Á0xhY1ÒrY¶œÑmÔÖ%—‚×*Î`'üþúNlûÒHÜu»7¾@ÑœãaŽ¥áç}&Xþü\TË j(’D)kY='}ç®òMqÄïGuÍQ›0YáÚÉ6}¬ã6Ñay›Xž Ër[,Úz{¤R±Î{š»k‚½](¨Å’4ò÷C]Üg÷êÁ@ýœþO5‡b2÷Ñ®`™‰Sçm 2UYèçãØKIÁSâëtk3ØÄÉ–}¬º X^·•„…¶Â!&HJ~[-F${nŒ©ïnÒÊGÕÚ¨F ÓûRÞX³~ÌêCo•"ºþ³lZÓÏR|)CYó0p¿Mý©Xw=°Ë4qöŒzzX'Ô°¼zš³Å 4ÛvŽéâÐ÷’8…tuš½k‚¿ï¡ÁgýÃv5/ Eˆ«0X’zEhÔp®Üð$4'Õ_JH±oê`x¨$>`ÃK?åë­ŒålŒ‹¼ -¨…­€6«~.Jî’F{~>4õzçÙW–:ØXCŸö© žÍKÈèª"äþRCzÙãÒÈó§0?-Kè |f€øvIQZƒGµÛ<ÖJÞÿø{÷îÍ|تQn|óí·ïÞÝÝ¡½§ØŸùŽòïÔM+à‡Ò+¢€( @B?B|i¾2ö«0õÓ=pö }Eï|E í&6™Úøm± ’*º"¬¡”„0ÁoIÆ"ɼH:yd,,úâöK80›Òwl½%·ô€6µ®– ëÅz_@#KÜU-ÏýéèfE ªž óê„›t¶qߤba²„Q“½ÚïK²E¦±µi2* BB²Ê¥  ½Þq âîû©ÞmCȳ"”ЛÕ/㺮œ&›ÅËa¿kND8m\lTv&õ±ŽG¸ËG¸b:Â¥P]°$¡˜šŽo П<Í\‡5Áݰ¶€°š3d¯‹oÒqÎÆÅ7ùøæç¼’pDñm€ß‹oøÊñMº‰$„ÀâÏg. -|`ÑO¼@Àš²Q­¡\6Éç©uqº¿Aa‹4Za‰¯‡>êC"Ä^\³ª³FɆ#ž %/ãpÕE&„…Èä³Å¸Ðý–£8‹äjÆyb”W+÷Vž1gŒ9MÒóTÄAÅqhÐ-½îƒ -Àúwr!m8°âºt`Œð‡r]Ðw]ò¸ô-(œt<ĪG{½?ì3A}ãiTÿÚH>$NTõË·11Äáìdˆ“FÇ*Ù„»º1el/Âáæƒ7×Ð iA3Ëü•qöD6üiýR’ ‡yyùñ H4—3$'s•ÎÄ&ƒöp e±Ê¡…>ÂT*¡HÏôG}¬ã!¬Ãò!l5Ù3'™YïÚç];_•ëà æ]ϹÓìuXü ‹´4–Rª!ƒ¾[Õ2á.=»L„&àY$`¸0E8xA .݈À{ö -Ò8þ«»·"Ý“cÐB¯U¤XÓ;uÉSÑ,3˜4XYÌ! -ZDh£åPçÌın.´gívYùÃî[”ÌqËQYœ@|á¨äJâ9oš0›3Ì;&F¡¦ë¯‰ƒ‡¢_½%.UÐù'|tï”1rv®³$vd>pôp½:¬¨›q•ÿºX‡¶"ðo9c漘6p¾¢û‚Q×€Ý œ4žlh„wY z¬ª}W¡º®"§}BO ¡l§ -˜}ˆ|gW­ï³PÁ 6“ÝaQyœ½e0¯¦­0Œ{5èyÞcçûR6Å‘%pš¦\´rÉ”kz>0UÏ%]«À[SוßÌùÐ0U±´§ïXž×ù‚[¿4‹mb÷ LBuÔeéTÂ÷Úöo !°Õëè”(@|Á°†³m·iIÖÀ§õ_"þP´/9Y{ð}‹@5*t]eˆÃýEþXw5}h.Wt\ñ}Ä¡ûX»LšÏ(ÐDlŒ •Üäm(rà²ÏmhͼûŒŸÌG-í(˜&ÀDjäçÇyüÀ®C¾|ó‰» ÷÷yË­´jÔJï™Õ)]á0á^`XŸ"ëS´Y#BsÀœp‚{¤K`§E€BOÜÅ;½ÿöÏ´¥§†C&Pò2ÿI —û[I‡ø Ó‰;/N~¦çÂwWti—¾mw᣻¿öÏuÑt·Ï9ÃèxͲ „Ï%ÀK½ ÷®G}u*'ƒJU -å×É”ÜC:ž‘’OÈ7ç -mŸÂæ ù YȰÒÎb) ®<Å\‡tȵL"˲{÷¡–fú06\hÛ}¡Í¥'ÎQZF ¡¾~6чºiÊ*À oÖpѼ·‚ƒê*Áï£Ý÷ èÓÚâÏŸ.§@jÝý -æ1¬t+ä)…Ú|èÚØUhÓ#²Í_ŽÑÀV$Sã2>â~ä¯|oëì>Í;Øó¶„š´\¿2œÑ]óoÔ?'dðN=#ŽÈÙa°|…â¾\ÐËþg4vÿ#×¼ÿ–Ɔ†–ï6Ï´"‰B›úa—¶1þk¨D÷K’ÿûG_ûŸ·šYväû©J!a83S(dÐÅ¡·òÏÃyÿ/0w¥Çendstream +xÚ¥YÝsÛ6÷_¡‡>ÐÓÅ7ÁGÅVR·‰’³”¹ë¸y )Èâ”"U‘rÆýëoA)CVo.y,‹ýøí.L&þ“‰³”O’”#‰˜äÛ+0"iJ'Û+.œ1?S^-®þÕ3¬v[CªL!¡hÐ%BP*)C¤H2Ê:eÀ-f÷SsßåìÖÞîfïï>‚ +àŽÀ‰ ´Š'°ŒÂyÇâß]9*2 ¢)èöáŽhU5Îã?õËz_oËìQ—ÎiÒ2áöäõvWêV7 N¢¢æçºiÖ‡²|¹&„D?Á¼QÑÚõݾ¨ÚŽ62·¥…¹';®×ö·Ýh;X×û­•äf).©â· +þ¡³,û±0ÿRÇL€Ü˜Nâ^Û°±­­íy0hÚ¬Zeûk¢¢•©íîЂg1‚£å¦hì´ÿÍ*÷½ÒU[ü1ͳ¶¨+ÏÎÝ Æp•“Ã@Ñv`¶•Úsníï&sOºÒû¬Õ+tÖ—1¸ †¨z; Të>4+ ð2úù“äôP‚9lâÉÛ§öT¯Y’`s9>Ö˜3`C*ÇÄÙÜàµ6«l«ÏªJšçT5¤:¯ªžê¢ªÞ<õ¨ªWÇU5:|>¤)Œ8 Ϩª:lõ¾ÈíGçìzgðâÿvñ8Ü™•Oõ¾h7Ûó +– N¨ +P½¡`OuYÁo:Pðé±a=(Œ"–(yÑÀ ÷>ÚöX°®ë¶ÃD˜$(€Ð1À¨Á-…¸Hÿ7 N˜LƒÒ.@`š\ÇíÉãîNSÖ–ÄY[Ys/7:$eŠÚ+Q„!N‘µ4¤2,Ò™¯Ìü$¦r²ß]}aÖkòÚ§D3×n²Ö11éÏ µe õ¾s3 ^QøËèïºrÇE1±*ÜI-+"fÕ:ä€ÉwóØª‹K$ÄàÈSn>~½õÙ¼Õ[=ˆ.S )¬Yð* à5{ÞàÀ”’>#õWâx¨]>@MóI¢f§s[*ØåÊUcÊW%]ws «Ÿ!èŠúи}:?›»ËÅsSW&t™d`—¢9rô¢¬jíf«ºµzK@îa¤·Mö¬‡G9L™«†vz¿-šÄ¬å+h—I¤l±s1s†˜~\|¾\¤a $0N¡ŒÝ\¨ºÅ¦xªŒ –;¾,†F‚MSïîæ®lN8«mQTYëø^¯µ½j•;5|ʪCV"¢G I¢ˆÇ¥û÷7–#ÇŒøq0Þ‚Š™â(I©+xúuùËçûËš½xÞWÚU–‹—ÂÂáÒ øO½o‹Ãöx.GÌ×–§SËZ,è¶0ÆcSùÀbÐ8µ‘5‡äqF®ÂÏu6c66;RšØ‘mãNÒ©+†û +¥­ëòMO´â,^ªz×@xœZ:ˆM(‹êÚRŒƒ% €…€®5²x][øÊ§§ +\_‚bcWΉ‘Ãa‚$QÆpò»D'¬oŒâÇ7h„XŸ¥àð¦ø;ƒ¨¨ª®îZ˜š¢Ë{ýzŸtU”¹í+m*ŠÊ–ø +ê:û뛊¨`Âí¨V'k&é™ç&¢»ÖN™²± //ýÈ”YÙÔã—>4'O)‡Æ­ù®GËÅ݇cŸµ¼N±ñæ&Ë9c5DÖºk7ƒÿ¸Œ®‹Ýuñ1S•þ?.'!Фï*œ¡PÄ›±k»%q= lúƒA×gJz,!;a¡»ÛpK^o·ÖðQ•66àÌV—†Eï –×ÿIîŠH3¹=4­em¾9áßÝývX n›‚_Ø|ÛcKÿ‘õ¾oŠ|s¶ov¶xÔý Úø!ìBíù¹ °Å«g +—®“Ä”Àäí”> òoµwkGÔ%IŸ½Å({#0¿%ïÑ[O‘¤ÉÛ¢õD¯eå夕 ·Ð%´WF­Š9…+åû—][?í³Ý¦k’amðÈ Ð5$†¶w ò.“RÏ‹EÏYyplëu q‚u̸µ‚ÖŽ4+Z'Ã1È?cÈ0í'IMøÁÚþÞ/¦Ÿn…‘Só±øeÚ;fÑíbú“%šÃ¥Øx±›:RØE*¤ã¾NCÜž} 3%1c!SâÞwÿï¿@ŸÕ 2¥hØ)†ºž¥Ä eG^¿©õ«x-û7ZX‰endstream endobj -1983 0 obj << +1973 0 obj << /Type /Page -/Contents 1984 0 R -/Resources 1982 0 R +/Contents 1974 0 R +/Resources 1972 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 1966 0 R +/Parent 1964 0 R >> endobj -1985 0 obj << -/D [1983 0 R /XYZ 56.6929 794.5015 null] +1975 0 obj << +/D [1973 0 R /XYZ 85.0394 794.5015 null] >> endobj -1986 0 obj << -/D [1983 0 R /XYZ 56.6929 752.112 null] +1976 0 obj << +/D [1973 0 R /XYZ 85.0394 752.1618 null] >> endobj -1987 0 obj << -/D [1983 0 R /XYZ 56.6929 665.106 null] +1977 0 obj << +/D [1973 0 R /XYZ 85.0394 531.002 null] +>> endobj +1978 0 obj << +/D [1973 0 R /XYZ 85.0394 468.4168 null] +>> endobj +670 0 obj << +/D [1973 0 R /XYZ 85.0394 429.776 null] +>> endobj +1979 0 obj << +/D [1973 0 R /XYZ 85.0394 393.3396 null] +>> endobj +1980 0 obj << +/D [1973 0 R /XYZ 85.0394 361.4675 null] +>> endobj +1981 0 obj << +/D [1973 0 R /XYZ 85.0394 295.9604 null] >> endobj 1982 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F55 1035 0 R >> +/D [1973 0 R /XYZ 85.0394 212.4297 null] +>> endobj +1983 0 obj << +/D [1973 0 R /XYZ 85.0394 107.4752 null] +>> endobj +1972 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F14 741 0 R /F39 900 0 R /F53 1032 0 R /F55 1040 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1986 0 obj << +/Length 2949 +/Filter /FlateDecode +>> +stream +xÚ¥ZKsã6¾ûWè(Wh<>²'gì;Ù±gGšªÍfs $Jf E*"eÇùõÛ(@¢¨Ã–@£ÑoŠüøHEA”Št§a W£ÅæŠÖ0÷ùŠÌÄ‚&.êçÙÕÍ'Ò D4š­œµ’€% Í–¿Tp +°ñÝÓtzÿqòëýoŸïŸ®'~¾™'®9çã4ؾäÔyÍʽénöMK½¹ã»zþ/Sì®X]óºLüC^–›¬‚IŽ«FÑøáËíÇÉ—;å>Nni:¦gä,oÂy*%4­€"”¼{K¨H°nD&ƒgâ°ƒânS21ž½äMN“úh õ³o&™…U“WMѯyЖ T‰&ì©n§cþž!Æe-¬4Ð!YCÊ6þ6½ÅÓLÑP›QÌZfm½{'h[Ôf[曼2ëfåºÞíËF¯á%³ÏôÖY 3-êÍSI`Åe¾D¶pFÒ€ŽÒðºö¶èI/ +íH—!®XüDËûKÅÐAùÑû¶Þdm±ÈÊò†š¼¥Ž–DìL~P &³up¢<ˆ9FQ2fç4†@E +Ã{ŒG‡ÂSMæ¸åÍ'¥$04Ih©†üÈß›âïü˜4zJ.‡iëP=ÄIoK„\Ä>uÓm¾(´ò5ÄrÒ`èTûÍ<ßQ¿^Q;/Z+*lù¸½æczƒã1ÌåN”¡ÊvñR‹Ü_ ±º£®{Ë| ¢eÖ¯íúv‘N|µäL¤ .¹¯ïû†“…¨/¨ÒRó–zd‡„ Çs :7ݼ}ËóŠ îÔ!IƒŽ`aB=<ºYÛ7Y8iLÖ¹ÉòQëlÇEBDàv=š²4BÍäÝæqhµ•Ûmba·A\n[» <Щg4ž9áaaê™IDÑ@þW¶0Ënöe[€1¡'¼B‚!IRk) išz ±¡´pžÛÖRüH¿‰bÅ̹Ïh¬J£ Vœk¬‹:¯±JkluQc«l“·ïÛ•‚%é0qª‡:Oe/΄Ož§²"JŒ©ƒNýV¡Æ +ô'H ®½®Î+¾H°ýÑÅwPŠoQZñ}ŠÁ2„È$É‹.ã˜0Ð΄‹p˜0 ê!ÌÓyH!'ñ({¬–å´ú^t˜­£EpcxˆÑEoº]Ò䢮ڬ¨Šj}ô‰tš—z_ôKöš{81n:›cWD>h˜ŒW4VÕ†(&ù˜LSBî‹ ­dâEb©î>>ùA#9ô3b&Ð@´=,.ê¼t(-'f\]šòdxK êÙÒ½àº1D.Þ–š…Žôë‹Ò.‘Zg ¾9dŠuáÖ‡ŽWæjJRÞµÍÿÚ‚™¬Úóì„Ì1Š’KìtPì´(ÍÎUVAF™ÈÈ(ÕªÌÖ':j—DÉ0YÔC–ËòTàP¸OÖ47Ñ 9t|!¹I(´)ª#ôa’“<—K7>rGDKùj‚¨™EוÎe gqë +bä>’(Öšps*OÅ~þjóð ¹I¦Åºê„ F§8Øà.9ë}¨žR„žzâsFÍQ Fº„EÅê‡VTo_ÐÎ9ëÂá ÂÇú‘ãÛ²¬ßðÚ`²ÞÔ:e|f¬2@eÞ~\‘l„ ú‚I?ì¨ÀKÉœmõ#Q“ºz€$“IAÀ +"LênwÅ&§îJÓSoèåoŸ>Ò°P2¥Þ[Q–Ô››WЮ¼X™õê¦)æeþÔHÿ0J|+ƒGUê‰6–`ø>Cœ_©Â@` ?(¾.ê¼øv(-¾/'# +X_ØÒ‚z¶tE2æ‹“£-¿îŠÊFVÆàƒ ß^4ûÍ&Û¯WG‘z‹áUs”tw±ÇŠÑ!d£ÈÞËÂDJÄF/—UÓä‹ È8HSO"‡LUbçów#D B~énÔÀÝX”¾›gïfhËÃÝœlÙ{7î–ŸI­ ·»ÈÖ7û†Å€£|H_u÷n@|ôÚY +p†qörƒ.ê<;”æàöb:¼ÝÕm½¨Ë³éð q‡tø”ºÞtØ#ü¸®¥¦V$Ð8i‹D$é)[Ž&ëðàÆ j“ãNKÁ2³ó«’Á$ó]ÅL8õ œ`fÊ<‰EOûFY(¥ãiS8‚;ö ´}ƒVbÃlI°Mã`îÙt­A¥§CÍÚ¦]‚ÿƒ=W÷ÝóvyÛSú‰”TÔjS0õʼÖ_É*¬Eiö‹EÙìn@Ž¥ +¸â‚;¨9¶(-Ç»Kqèȯ7Ëüõ4Æ€,&ãaâ:Tu¾ìŠ|êüB,³•O¹W½×—¡K¨ŒâKl‰Ú*×yX)ŠRor{ˆVp¡w¸Ã M-k»ÎÚpÚÈ÷k±4¯g= RÊSaÿ˜uc…: â0I|©&"{ü蓱õ"¤“ pî U-†¨9°|±È1 +‘ÊÖ‚Óƒ^à+{xb*Ì©Ã/šN½çuf³c=Sm÷”.(a,é£ã`mÖ˜îñÿVC{7R×Îhˆî“‚Ih/Ù.[´ÚŽ8`;jqÁÒŒ¹©=â ÃõÜ2kÍ¢X|Ávnv7ŒE¶ôIŽ·Lygfã }Ȭ¤²´§¼ÄÏŠw¥Cs ËþÒ¡äÜJXáT>ÈG¶]úëÜ£Žñ»XˆÊNÉy°˜À£8P ÃVÇE·:J[æbM©iwyµn_N½g¼$®CõPçÿ¯#¢Ð'ïÈìØï?Ъ´ ДéëD™ùŒã¢Ýo?‘ýöÓ»Ja6ʨéœ&s&<0Ó™ t¸þüË¥ãF0ŸQêkÜb¿3;¶ö›àKf„§2%ÈeŽ'®r# Ûý¼en…¨ ÁÀ·ž—!Á‡‡ª%.j@^,JËKÛë¥ÀgX[Ù÷Ý!Á»MÒa²,¨‡,¯Zò„ÿEðÈr Âæàð©ê$L–q˜q%¢Ç@¸,“09:Ñ!Šs¦üOÂè³ÀBÉÑÖ·ßgŸŸ>áŸ->ÐÐÓóÉ 7ƒATDŒ)ßâ==Ûwú²ob³ÈÍ"›EÁa{Êò«|gÀº Ž­]2›eѾû³Ùæ«V3ßì VÝü_’7Ó›ö|`èr¾ÃÚN)>¯»÷­1™¸ìù¯ã jà.|?€¾–õ׋eŸ2ÍOÒŠ4R‘ˆAª,æ”*¿Ú.‚”¥Ê#‹2 +/e^æóýzÝUÎ4UÁ¹?ó@Ô€ÿÀ顊ìåüßô9ü¡)ŒA—’3±¦ˆU/G–(<çÉé=›¿Òþ?ßý÷Kendstream +endobj +1985 0 obj << +/Type /Page +/Contents 1986 0 R +/Resources 1984 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1964 0 R +>> endobj +1987 0 obj << +/D [1985 0 R /XYZ 56.6929 794.5015 null] +>> endobj +1984 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F55 1040 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1990 0 obj << -/Length 2978 +/Length 2192 /Filter /FlateDecode >> stream -xÚ¥ZK“Û6¾Ï¯Ðm9UAGÇv¼N6c¯gRÙÚ8J¤FL$R©ýv£Š HªR[:l|Ý~€â ?¾HUȤމŽBŸZ¬÷7lñ}ïo¸Å,hÙG}ÿpóê™,t¨c/6½¹Ò¥)_<俯?}zw÷öÃn—B±àûðv© ~~}÷ËëíÓ­Áë÷ïîo—óœIäꯛß~g‹öðã ¥NÕâ^Xȵ‹ýM¤d¨")ewsóïnÂ^¯:& %ÓP¥"‘†=ipí(^$J‡±„.”ÆÆÄ®€}GIPVøŒƒŒ^«ºZ¶Å×–Þ6õqŸÙöº®Ú¬¬ÊꑜyÖíÌ*j¬ì´MùX9!óòxËÓ X·»—[Îyr•L[ >5¶QohD»-íÄõ¡-k;w^»åªºE-€(–œ‡Z)aöµÏþ,H›ûÓzK­¦¨K„ÝP7™¿TÙ¾\á[]Mx¡X2”ð82IÇ­Ò‚–}éY¥C!¿Ë?pÉW?(ÕCê •Àäˆø£lÛâ8dŒKXT²xž³5šg"xã\û¼ýº-PìqlTIZc&@Cá¹l·Dˈ€ÆõÕ¨ÞŽÍÚéŸúwå¦hË}ñ¼&,Èv;¢þ ŒFYs©Í3o¨¿lš“›ÖØ$ÐZcA@À ‰&„–j Y¬´o ç­$:(¾¬aâ -)˜J¹?íÚ¬*êSÓ³T6„ õ`¬Ý?Œ¡¥¬Ö4Ù¾€s²ƒñ†Lç÷šÂÂÂL¨¬ ÷@CžJ³â²;4)™¤oãäÉp=)XpÈš±Rð ³´²:œZj¶5uŽ‘`æ>Þ&QÌH™’à±ç,;§4;õ6{*ü™Wö`ÌþÀqdÙÈVuÇqÓgûbìô¢A<‘VÆ3˜“õÏP‡ZÈôâh ì<£NxdaÎH.‚æP¬K´O³+PoFt;•i?—U^?S»Ýš}ð¹4ÒšÙ6j:°v(X«‘À -Ò‚C'­_¨Ö8SÃÀ*â0Ÿå¬C°æVX‘ X»÷|P¤¬Ÿˆ"klDD[£Ngç Œ³p?˜ê(øþ…zòb“AøBïÃi¨ì¬çh`i—mÚìHî@&3Bj‘¡~±•-$l h -;Q©œÞ|úeZ³ -2Û4ÕW4ÛCÍhÖ¡ŒfïÆ4‹‰·K™š:[‚Ï(³ÝÒ¦¯caƒ!Ì2Ù¡F¸ì+Y0&QûlšÔ6bIpÿñ56â€X"¢Ó4¶]ŠÔ:ÒZ7Ú%؉ ¨<ÜàSÝ4åjWôghè%;‡™8—‚Ãt°ï6¾ýY|ŽÅR¨-4sgæ SÌš4ùw#«Dbtê‚/ΊáÉ„¦‰%TÊ´ÓºýËY!I•ÈÞ¬§ªüоejRjº fÊYÐ(\B5^cu¨evi¨®ÆêPc‚õ–)±HÅW–w¨‘å=7%!±ö×[»Z§sÔy¹:jcžT&‘yš!dž*N .J¨<Á¼àú°iÁu¨I›ñxˆÁe|… áÀ“]”'‘χ~Fõ7$fÚ§¦ËÌ>ÿð†\§Â†Í#ÔK{ÈÖÍŒp#j®ô5áö`3Âu¨©£ãËä¡¢ô - 5‚']R‚ðy¸/þ¶L]ÒèwÖ72žÜåÉ`B[êõv2RE\„Qþ{6RõQÓ‘ªC™HUç 2êY},Ë겺!$bžµ5›Ÿ„$PÔKå3÷ài Y£aÆäÃŒ -Þ¾÷8—NùwC]tÉžÓD{9{wå¤lÉŒg*úý0Ñtyl7‡ãkB2å üDÎ믚Ö_‡2úûx-Ó€Šêí‰,ƒ'$ÂØYþh„?O‡Ð çHú Ê„u)„L8%މ«¶¡ALRÛ)ö:ï–Æ]!©ãÒlÛ´#†þsÚq^µ¡¡3iG‚i7¤^¯'·Р7>žuXÛÍ”†x“³ç©5’óTL¥}Áù‰#q%“í£fìË¡Œ}†Kê(Œ¢èÊ’4²dwêw¡Kþ‚7¡ÀHphŠS^/éÆIïgmFÏææiÝu’É:€êÑH‚ šrBÛ²P›¬i»k¦Hò`eŒT˜"µ½L°ªL±ËOÄÛ²…Š]ÎB%ι+‘c_$°¾+I,S"‘çËcì³jPAmN`þ;z¥]# wI(¼ @™‹bê1—Éðt]¥$Ȩ®?Ø5›š6¼¶Ó”ÍØýĮܗPqMš¢HÁåkyÅÕõQӦءŒ)Gï¡ãÂë‰:/ž.SÙ4ÃÅué•Ùdv¾e;Ýks®BÅ• EV ùxY+9wVVy¹¶ßàè~Ï&k¾éŽØ$†¥m}Úå~²…{žv;ôètâ;äÙíôP3nÇ¡ŒÛ¹Hš4ã$Šæ—t ‘%½‡±R‰¿ä§cé*º¦…óß`!æ_h®ëýaW`à˜”Oñ­ó飦%Ò¡ŒDž®Ö »â©ØÝ[ŠнYÎ:ÔkÃ{K¡bŸ5¨ÚšAfž«ÓãcWíΦe¦¤ÎúJÕGÍÈÌ¡ŒÌ¾]X‘ ¥„ÌnvIYÒ³¢NœVþ’«ºÿeå§ûŸº*GfVîÚ#5l¢`>lï¾¥›.g}® Â$dZ–‚Á`WjÖ>jF–ed)Çì…Iª]&Ðd»ËZ‡CÞ-ÁPfëP#œyæ'¢0Lù¬½·o—  \ÇÁÝý»7’(ð¯ H¥OÒH4¦Š¤Çò©¨ˆ¶-¾R£¨Öu޾¸-pÞÿBÝyÖØY°±rñ -ˆ4†¤&M‚–xóÁ¢s-Ã-¿™åve·Dq)hHqþÝ&B…ªùÁGÓÎr*g9ȇWgKkZÉ7I÷YÐYdwÈ­ˆgDOÿK"çó+’8ƒfþ#aAÆ"ÿy­ -‡”™>ê]~ÍQi¨…³¬u KÞü«,Ð#“±Çܯ“âËÆ…×Éß Ù©hŸU/.Rwû&]n×W.g,œúGähÑxFÎΈþï+ÿ—%¡LÓ‰ ¹8\ÍS(?ðCÖ»ÿ5]òþ?gvH.endstream +xÚ¥YM{›H¾ûWè°ùÉÐÛMÓìMv”Ä“XñFʳ³›ä€¶˜A ÈϯßjúCHj„g×>Ð4EUõ[߈Œ0ü“‘dÓ8‰8B 6Z®/ðèž½¿ †&°DA—êjqñ÷wTŒbó^a)Éh‘~Oî·7¿\!Ãã+t0ŒÇ·“Ù×É'½ww‡ãÉûéü2 RD\‘q<~;›Ï§×Áüæýì?ŸgÓË‹Ÿ/¦ §XWy‚©Òê÷‹o?ð(…3ü|%=à F$ŽÃÑú"b±ˆR»S\Ì/þévž¶¯úÀ`T"&CáA#$#BPÌXx‹§!máx?M¿LÔ‰Ó·úü§ÿž«“Áû´ƒ&ÁS’Xãø¯UV*Ò¡ +cDã@­ˆÒ²®³eð[öò註 +ö@V7I™&ÛK"Ç©†¹Ú5›]ŽE /Vy­·í5)Í}š•Mþãp™4yevÝIa Ó }TXÞæåF_W‰á +fȶI“¥¨×wq„(åá@àu¨ZW#Q!XJÚá¥øŽ‰8J€ æ‘8/ÕQŠ=0%Á°Žø¡XeOCŽ"ln1?°LÖY/T\rˆ‡(:U—ª*G5ÕY©{¨NÄz¡: NïC +ƒ»ƒ†=P•»u¶Í—ú¦õïl£/58nÇeۀ쾙Õ6oVë~€9$îÔ8p‡ê À–jàsR;‹õÜÛ—Qhˆ¨|Ð÷¹ 3!ÿ3lÃÿ¡ªš6)Â&AžÜ0B ê"!‘¯ÊÑÃK±Un©m›´išÒhÜ-¡Ö†Â +ëA +Òḇ­mÚ¤`Ì;Ú©»D]„ê‡ô=ô z¡ÝcYÙJ§öšUÒ&ªª©Å}¦Ãl«Í»àU‡?ÿY•F|Wåôin$5д¬T¨§ÆóöLþv3 LiæˆKyäן¾¾Úª +@¯³N©®gZH‘XÛÇœ±8p…l+áHÞ¨“ƒz“-uõ×tmði­RŽßµ§†ýêþ)¯væuˆç¼þ¢™ˆ­«² NNÁ y½ggUH«Ì¼_VL€¾’“CÀVÉSÖí&ŠnîOLw³É¶ë¼®!û{q¼ªÀH ¡pCû8à£ñ(¶)À’`Ž]zÞ"Œ¹ìfr  ØXwk +Á÷“~Öö\jQ¿¬×YÓ@u›•ËíËF=õš3¤á MíÊp7;n'ׯ=U!ª³<€ûö-3Ù'{ÊJ›ªÝãêLÞR¨ø³‡~lÖ²ý}4¸ý¾htưem›®´™þ2¹½û4žj¦P½1%¼K¢’ŒXdz?ÑÁepß¶ªF¬ùDïje©íoaGŸvÒj ±bÌ.ÌNT$Úf%û#Q#‚ÉÂ7|À©˜klƶ)aUQTϺÉ‘Àb­A…gÏÕ®Hõþ½!_ßeé?<:!çH†°w¦ì†Ð Ñׂvã^_ ³a(Ûá³]?¢'{µ&ߟnìi˜™©Œ‹œ'œ©|G>û±£$zƒ1}rÂñ°¾7mµ`6_áÈ÷'Ow#"èè)yýä ã¶ðv5­ÄL ´á4Å@nÄ$¶¹ªçŒ=)ŒpPºª³9 +vŒ]-vt® ±9îh„Ÿi=(ä=Ìm%ò~àˆLÐ=Ÿšj9ù4ÿ<œŒ!êü±TÕ\Õn©Ê«1!»l$’1³J]ÝÌ̉ØL×y™ƒG&íy¿d™¶]¹4Ny›”;¨I>Ða0眻€?Uú8éêø—wך#Ló±‡_ÅQYà/³“ûßÙEÇìÀé£Av~Ó˜!qá'_>6ì ´ëÛ23ébþRCëdz×kh5ªm“ïÖ{±PÙ#n Jmklô+Ä¡,`ÈeG®bû +ç†w[â =ªI8—ðúœ•ÂPè•þЧ×ûçŠÚ¥º¦ªŠáb8)«M×Ç£$„¡\œZ`&|“¤Šî)kz‡[è(™l£{ÏâtÊ´3°£òž^Õ‰oAòî–údìp‰QD÷c^‘Ô¾¤ÆHJas’ã˜z8N’3›¡_‡^½Ú¾x˜²ñйªcš 2ÍÊ4hòµ¯%Ô\,Žy>xx|‡ÅBæRý}.xÈ ÿÃæÁñt«•[ýæ‘ Ç#Ë®Hæ "œE»bën{DzÉÇ|£Í·O6«¾è/ÐÀbÔ `Ä0oq†^"iüuVÐçøuPç_ó”ö¡ÀQFá1Ç٠ǺJWó¤è×–@ʉ<‰j;Ì ÅjŸ½3 +áxb³®Ü ±€ì!O> endobj 1991 0 obj << /D [1989 0 R /XYZ 85.0394 794.5015 null] >> endobj -1988 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F21 710 0 R /F55 1035 0 R /F41 935 0 R /F53 1027 0 R >> -/ProcSet [ /PDF /Text ] +1992 0 obj << +/D [1989 0 R /XYZ 85.0394 752.3199 null] +>> endobj +1993 0 obj << +/D [1989 0 R /XYZ 85.0394 504.8188 null] >> endobj 1994 0 obj << -/Length 2340 -/Filter /FlateDecode ->> -stream -xÚ¥]sÛ6òÝ¿B/RÓ%>J¬¦nÛ9ÓÞ5} %ÊâD"U“râûõ·‹(’¢Ïuôp±Ø/ì >‰àÇ'±f:éĤŠÅ'ËÝY4¹ƒµ·gÜá„)ìb½¾9ûùi&)KµÐ“›u‡V¢$á“›ÕŸÁk¦Ù(DÁùåb1..Þ^þçêr> yb¸ f××óËó‹?¦¡ˆ#@ä( ->Ì.?ÍÞìzšŠ`öv¾˜þuóÛÙü¦¬+<$Jõ÷ÙŸE“èðÛYÄdšÄ“¯ð1ž¦b²;S±d±’ÒC¶g‹³µ;«vë˜1Tœ°X(= ¥b ð7g†s@2qÊ´²5™àc&óXh²p6TTf4—“.±–i„¥ì°4‚ÓËß7y9 ¥Hƒ»¼Ìﳦ(ïè;£áŽNÒt¹É -‡\ç MšMN“«ë›)O‚«O7ôý9ŠdæHUnW¶Ýž½Ç]ù²²ãªvˆåŠ&«ŠÆ²jzRæh¨IÂ’ØLBÎYÇÂêã(£÷œPFà>í¤(ë|y ‚¬òm~¨Êš8œ;UÃ5SI¤¾sô¬gŽÞc¡Üÿ­ÊL&¶ùu*˜Ö&}žµGaÝuÔ0­Àq{¬o6ÎŽ¿/«²Ó¶Þ€ßGBA¨¢ñÖ}×Å]™¯ž4Nb&ÈÏš®‹õ´éZ,”ÿKþ8äi$“Qôži„g/lXäž‹}¾,Ö ¸ÖÁ×M±ÜÐd©iVoªÃvEsk!uî Övˆ6sCBC.”q\¬ TVCêYë¸H…ÁÃËW¯bìiY²¦OÖ‰[`:¹0ŒÀÜ â(ÿ–íŠÒŠ+}Ô@øA*7ÿ7Oã #·¡Eâ+[Á¥}þ ‹)FÙ£vxG¾®¥cù àvQŽø°¶Ëšå†|¾ö÷ŃOQ_-´à+Ÿž Ù€h–K…S±©î§œóàU»å¸¹vÛY;Ꮋ›uð¼AN$Ö·[áÖ“P(–FB¦P…Pâù³×ïçnC×1A5¡¡u£X+àµÝV_É:†@ÞíȆ°†ìkš¢Ú–¦J:49ÔAë¨õ‚ý6g@dD0™hëL%š 1o¼Pç‹M0XíÄ'òaÞ>¶&éH£Á"Iš:«²†œ Ø<"OÒ°8Q©?sjD>Gqô®£ û JÓOÜe`‰ƒKž’ý€€ÕãG¬C‰i§eBq -ò¦¡†Þ×98F)E]¡]}¿±°Ï\ª±ü÷DŒ¡öÉ2ªî}Dî„ÍM¤Ÿ¶(ý\˃ì¶z€Ðr_ŽÏ«»§)ãÙ -nEÝ@)…‚k”-ÏQìšY@mÓ¶íé½XÎ|–âˆ9ú¦ eÃDÝ¡…À­p謰ÁÏíýZ±êÁí c] NÈãi…­ÞÀJ cF à`•m”Ôg‡ýóˆ£;M1+¸ØÏî2Ÿ |¢j³tKæ¨g›†¹`fÛ™$8”`éæPÚì%•~«<ÌרèÒ a¡WábcO!øò’+n‹mÑ<Ò¢_²~?ÒÜ;ç/¯² ãZ´U¹Ê}z¦†ËM¾üâxVÚe_r‚Ôí³ ~à¤Í®•PÃ8p·&Ììî]Ê%ÈÒv©|¤Eì-[˜+R4Y¼ÆÛ-¾:‚,Öæ€“5P?÷nÙJ#³]&@ŸwuhìœèRh÷û<»§u <æN‡å2§+¼Ž:ÑíÞ` 9œ¯Šgó2A‰@ç }؇=kœÙm‰”Kä±&Ul¿Ç@ -½÷Ï?¸X¨wûm:2?ÒhÆbßf¦“Ç¢a³HùIrÑZOPk#´þ¾ºÚö@ö¢ÁÍѽ¸ï9¶yVÛü—ÛŒâ -ÝL`²Ë³²)v6‘ X_¼énÅ t^®œHô.✱¥!p‚=ùÀ­g½îúe¬‹0ß…@Áîë~盬yòyηžÎ‘ ×÷mïúËüã…o‘°åYWÝ÷Q_çl¾Á ™{•~1ŸÓžÙûÅÕw_1zW|¼Š%x‘r™vo[œ©Hz½¾¸<'6©ãÖ+^ô±ÛIèCV²íX?¯lyµ#?&>Mpßðüå Q™ä=ÅÁ¿cÞ^FŸÒ˜%©Øoöéæ×«ß5ÜE Ío™;wX<ÖÇÜ9¾©Ê -IqØ=õ7ŠŒþ÷1òHµþã¿XŽ&)¸2$‰n&f°Y{¡P9.¢ÓWåˆ ©ÅˆìÿÅhØ^endstream -endobj -1993 0 obj << -/Type /Page -/Contents 1994 0 R -/Resources 1992 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1966 0 R +/D [1989 0 R /XYZ 85.0394 359.3246 null] >> endobj 1995 0 obj << -/D [1993 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1996 0 obj << -/D [1993 0 R /XYZ 56.6929 614.1369 null] ->> endobj -1997 0 obj << -/D [1993 0 R /XYZ 56.6929 339.2217 null] ->> endobj -1998 0 obj << -/D [1993 0 R /XYZ 56.6929 150.6999 null] ->> endobj -1999 0 obj << -/D [1993 0 R /XYZ 56.6929 84.3474 null] ->> endobj -1992 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F48 950 0 R /F41 935 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2002 0 obj << -/Length 1439 -/Filter /FlateDecode ->> -stream -xÚ­X[sÚ8~çWð3EÕÝò#Mh›nK²ìîL›Dp×—®mÒ¦¿~,ÉØ`Èdv§3Yþ¬sôï\bøG†J ÌB> BŽ&b¸JxøïÞ ˆÃLuRµŒÓ8‰ŠäÉ÷Ï™Oà:—Oj‹©1 fÏj«:­­Ukëñ(ó D†ò“Ôc²“y -b˜ì˼G]”MÙòUμ=®Ç0@ÖcéòÒzìbûPDéK’› ˆ<1¹ìÐB €GÕøÕÆ=oÒƒzL€‘PtMÞèb“iGŸ•.]L’DM}ËwE%ÝzW²ËªcðÏg:MR#Ì,3*ÑŒëÙr}ÆfÐ÷öŒ;ž…gZ ¹¾»;ûÛ?d63‰IE:»{Œ•',Ïùì®üuþ]’&ç0›_ÞÜÞ^}¿¸}÷öæ¿n®Î<Ïx6¿øøñêæòÝÎB3`fÆæ×7?]¼'ÚÇs#æo¯nÏ¿ûñìê.6ž3‰RýqöëïlVÂ~SZ&ZIé)«³Û³…½öÓIep–™Š m>ã<1Z‹HÚ$©ÒªãòêöûOï>Þ½ûpƒ«±ßì4Èf ‘&J +Ë[6]W-]ýØüÕ6•ã—þ,K¤P|‡üÈØÊR5/ð!çø(Tj>×é±jªMÑWŽñLBESéÓ'0Ñ6ç<ŸWËÖ>K?61Êù³%·åvYÅÓ¢ •íKµéê¶¡Žöšsr/‚º@üþ©.¤VÒÔ@*V]K­¡üØAZQC-r‘3áÔò¹zíª~1¡>¥’,å^}¿1&VN„eÛôEÝÔÍ#½Ù`0kЃ£SëÔ3ãBÞ€ú™×.ÐêzúA¬>x&ÀsãB¡ƒÚ̹…Z/Oõò‰šNÀŽÞÊjU==è¹{ƒ3¯{ÇW ês1oŸ±»X­^©Ãë‘Þ.oé¹op Ò A ÃQŸêU¹“Îó‘?¬iB`®7Öa±ÕZGJ[§KBÔ "máY2‡ˆT¹ý⃲}ÐàIÆy:KK”‚øœrbZ ¹|Œï#^àÂyÅxÊT%Æðüø”žibÊ¡VRhf’ÇSþ|Î9ŸW›úá• ìL oæ’^ÑëŠ~Kf&eNéFçp‰ãºrÖM಺Y’ý´Æ+*À(z¹*ºn,˜I“œ u\0Ï4!˜Œ¦ƒð–H²ÛçjY£“YoU‘³k»oQƒ$³ÍöaÄD˜uH:‡ KO¨sÀuDžËªóó”:y’-wè7+O c•ÊñL5T¥án@‰„º;7ÌI($ŸwA¹%P*Û(:÷Œè"ÀcÌ ÄvÈEó:ê‡)dñØa!äüî©v£øQ{]¸)î«}á,Ãú˜Èc˜ZoW}ý¼rÖîëõ±èá:É :aî×s{.kîÕ„¹MÂ…ö(Y¶kØÆ‚¡Ç§¹âÇ% \¢Åñ²¥ZŲ½Ýí'>ÐóË÷˜ºýL4€y¢Öc*˺w¹ž÷-Q)¤ a­Š=¿1Í ÿyõ ´x”„hÚ¹hôΦ:h÷Šúœ6lÝ­x~®šÒ›Zè„¥ÚŒ‘vÜM±®ÄýhÃ<è +vx#Nê€é°Gx&ëåÉø/ëMµìÛÍ +p!™§ú¨hi_69ʸdšå‘pïÛö3) ˆýD@A +ž™(I›È`G—:q@Ã’£F•àÄŒO-~40èS也¿£>|J¦Ò]°ª ãF0ë€ëˆ]=—5ìã^¡a¯2'¦ôLSFeK´d£)ßY×öñ§¥Ï;4H6µ$ØEò(ëÔ>*iRŸ£»—}s !aó‡Œí+ru™šlß”ËO‡’Q˜úLWàVhÚ„õM³¡Öå­Øøä&ê á¦M}Z ?KºK‹úRÛd ˆ÷Žo˜”¥QÞœ +?÷•Ãp¢¶sC„tx!•š_ýYw=•$ÐGȧ¥¶ÒàRY\lÜG€¶n¿TåA0“y––žpû!×a·\Öí»“éa×›~ð> ¥I Àqñׄ|¤!äÃņ,Ñ&ÙÌG +4JÚ÷B™‡}õÚu¾íøed¶+¸¡¹o2 Þaí>ýR¬j0 ”Úå7ÈAUže%7Ö,a9æoCWµ Ë…©îyßµ«­_èyëzIŒÄö—Š(¸t6Æç 1?Ud—/µ¬|wü²>Çb”Ö ”ûW7?=šíúÞ‹V»ñ¿ëëËEì­—?üp}} ~.y6oÚÞ¢Ðßé¤C0ø|ãJiÆTY$òsõ­Òßú®Ÿî@²ï©msDึ9"$런‚—Ê‹‰%ó ⊵„줄 y½Jr§’ܪ$è#wúÈçßÜ 4 jýÁ'7ôèÀšÒÑØoäaÐXn7$]Ó»o?I@¤¦Ü>a af2ØÆ•(l*O«rM¿!_”Y–h ÅAäŒa£EuÉ5µÖu³uû2§ÇS»ÝP “BŸ¨AµÛ¾ìR W¬µK—~tŸ«—9bÖàFÜvÇŽå‰Ê¡Ì>Žp®#ç¹,ÂUÓ—AÊæ4 éé4¾iÀ~ü¸pkBº8eXÍ•ŠÅ øÆË…°Aø†-‹o¶Ï [„oÿßðÕá7lßXýùì’- ll~á:^°¦|TJ(@Tú5Nª ”(Úû³óH%MrtÜfS>Ä5-‚7rç8<Š\í6g ;¸ +È„4Ly\#n u7ägqºÖñ<9«^” p±‚ f$iÏv¨ ÉŠqÐ ¤zÝ +ždî@ŨÝq¦Å„í@)feè›°yœÛ¢V Zrµ£1ãè÷ãX¤Tb¸H©¸[$v4íË77 µâ°w⸂”3eùD¸‡'°!éÂáàÂ-$Ô–’QOY¼:žQ »Zû)iÐÒ¬¾ìŠÜ7HÔW8JáN‡‚…‚;rײz(¶«þ „Á&’€çŸ8…r†°Àe!ìaò"Í¥ÈvÛ?oûÅC½Ú1zÆ/pMÈ'iYÂ9±€¶þ—´VÅ[z§s‡)4Ka *ó^–8ˆ‚Â;Õf”Á9!UɾìÝ;À¨»XÚ7q±¨™ƒžÃóOÀNl~C®Ãž¸¬ç<íUµiÂLvbJÏ41eTÕò„Á6OùqS7½Ûñ —<µ§Œn»^›×g;tjè?nÜ:Õ²ÛuîÛ‰»<¡  ‡'s§/ó¨ ŠñLZGëĘSgC®#Öñ\Ö:õ©ÓEPeµ +d?3 Yy\¶À5!\Ô«v‡”@ö!³‰C/ ŽŒÇpQn«°ïÚç?ÂÅ€}®ª.ëŽF«À~§ Úñ]ðÒnWå‰`ú’Ô þlhbÛcᇠ+ÿ÷¯“v¿ÃRàAy~à2Fd¸mBÛ …*ƒj?Ÿp¿cÚ—ý¾ÑXendstream +endobj +2000 0 obj << +/Type /Page +/Contents 2001 0 R +/Resources 1999 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 1964 0 R +>> endobj +2002 0 obj << +/D [2000 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2003 0 obj << +/D [2000 0 R /XYZ 56.6929 751.9327 null] >> endobj 2004 0 obj << -/D [2001 0 R /XYZ 85.0394 747.1998 null] +/D [2000 0 R /XYZ 56.6929 651.1304 null] >> endobj -2005 0 obj << -/D [2001 0 R /XYZ 85.0394 709.1513 null] ->> endobj -2006 0 obj << -/D [2001 0 R /XYZ 85.0394 635.0632 null] +1999 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F55 1040 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2007 0 obj << -/D [2001 0 R /XYZ 85.0394 566.8617 null] ->> endobj -2008 0 obj << -/D [2001 0 R /XYZ 85.0394 495.6953 null] ->> endobj -2009 0 obj << -/D [2001 0 R /XYZ 85.0394 227.6801 null] ->> endobj -2010 0 obj << -/D [2001 0 R /XYZ 85.0394 156.5137 null] ->> endobj -2011 0 obj << -/D [2001 0 R /XYZ 85.0394 85.3474 null] ->> endobj -2000 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R /F55 1035 0 R /F39 895 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2015 0 obj << -/Length 2415 -/Filter /FlateDecode ->> -stream -xÚíZ[wÛÆ~ׯà#tޱÁÞw[I•V²©O?@(Á™­°¿¾³7ARŽÕ6µÎ1»ÃÙ™ofç²$ž%ð‡g\ ¡‰žIÍO0ŸÍ—'ÉìÖ~<Áž&DqŸêûÛ“ï~ r¦‘DÌn=^ -%JáÙmö>ú)t -’èêìòüMüú/ç¯ÿúÏ·Wç§1–‚àèìúúüêÍŻӘðÈ8I¢Ë³«¿ŸýÍÍ]Ÿjýx~súáö§“óÛN°¾ð8¡FªÏ'ï?$³ tøé$AT+>{‚—a­ÉlyÂ8EœQfÊ“›“Ÿ;†½UûÑI0p‚d ‚g˜!Ê`±׈(I xVé2ÏâùC>ÿô¯ºÊn°AL’B1K|$f8ÓÎ@E’:Ñ–jÄè•ÍÏÖËÇ¢Ìívú7B¤õæ’„”~ü%-‹¬h7îÍ2-ª{÷V¯ül]}ÉWm7ßÖuéÅ0Òœ/'åˆ -&­œ7›ª~lŠflEŠ‘T‚΄!öf£ŽA{ÂÁ.{L‚$Æb÷YX‹0<áŸÕz§±Û¼³aôÐ>v£ÏÝèK7š;xßRD(¤56r›½æeÚ4Žl ÑH)©=UÇq1ÁDW‚sOº¨WË´à8$ë8þðr»Æ KÄÀßgqgvX|SXP¤qÂ<ƒeåSHX":–ûÓQ¹¿ŽßòÛø±1¿Ë–¯zaùêãv‡(QuáfÀ“I¤H"Æ<› ž1• 8!Á!\hÚM™?ßïo^Xûö(¿¬Xåó¶^m&˜r†áxÌôé?ÁôM7úu‚½àHrÊþ&²ë‚‘¤7HÐÃSÛ÷€©ð̆³.ð7„ç>‹ýá¹£ê…ç~è?–A¢„+þœ°¬Æ6zýÂgý¿åcª$”6BŽŒþ•¬‹>šöÀ^½°|/ˆåó1WÈ0ý–8üÿ¸ÙÅMû64ͰÖ)áµ´Ö¼oÎo^ÿrq}{ñöªûÔ°ç‰Èd!?Qù+†‘]9i(SƒÓ¨}°<‹šMÕ¦¿»É´ÊÜdQµùýÊ—õ4ª~Ý­†N€úNZ0 -ÙEë&ó• ;Y\ÌÔV¥Í„ž”*„ àZ='´‹!£ô(Feun˜+==ä••uš¹þC95”SDg˜D·EãÖ–é§|J$,¹IJª/Ò1è%Ñጬ›|±.ݾ ÛÁ ×-ÁÎU˜w¨zîrCUä¡™2ë÷±ËÍr3ƒ²zÁzµm¶ò¥Qk7J·-Ÿ5ù -:´SÉ"4ív:ôDÉ=)vW{ÍÁ"œ;.lS,‹2µÚcè'¶‚óªÓÏG”NHˆ¦•U*º[·n¿¢u[¥åSºñ2dëå£:ׄõ½mUÛ¼jAí?ïÅÌçv¨r4££xYË€«Æ4á]—Lл¹Ô½FZ—V3JeÐPu•–åæclÔ¢X[m,“ÇDz0îaYµ«bÞ‚íì’…Ê-”ù—¼lÜôÝÆ=³|‘®ËÖð#ÆÕ\ë÷©ÂåØn­ßQ™}ãl¼%+ÑòÈ–hbË>Tj~©F[žWé]¸úÊò»õý=Z´Ws …¨yXñ-ѽ=‘Uûa¯ÚöÛj=ÞoRéÞ~×LÚ­ïÙÁºI®—Ëtå/}‘DùïE»½EB(9 LŸj?2•…æó>hnÙa³»å8ƒ-^¹GÇVŠvoAW a©®|Tßö\Ó#èô¨ ¨,:_vÐá¦~:²e šØr€N‚8MF[NùTMm\i¹/ªAGÕM"¾¦ê¢š†ºãÑNõý*]~•{Ð@svÄ=ªTÖw @%RÞ2Ml9h[üépK—m*êJà¾1¦oõ]Á™f#âõzU™tnó‘·\pq€´i›½ b-†°rÔ>Õ~P;* j¸±áÇAP¢í\ØôÓ) =ÆAÁÑ„`t°( ©JvcRøb3Ñ ³ãü5L7…“è¯Uu»S¼ê¾›aWæo‰&T“ól¿))䑼ԧ:`Š@eMQL˜BC+Ç娙4tJJ+Mˆ5è; ë2×(±®]C -¸2èNë¦ÍYp¯¾(eƒž×,¸&ÕÔ‘JG×uÓ6ñJ£Dã¨RßšMd2¨Ö¡‡5V‚°´ÖÚ[†Rý-ቯÕaˆ_M°g %JÓ÷ØH ‡|Ï.J9!q×-í²…–Z <þ‚ư+ëyºOzh†8Ãü_ÕîKkÙW›’ ®‰ÝB#ÊeŸsÝ''A‚KÖõ¶Âǯ ù‹a“{ÙÝúÑÍГçµs€péA™i·L`\éò›qn4w~Öô'¶¹ZÓšé3÷Z¯ü+ü›b⨌+ÝAwã(Š*Ï]2´œÖm\/âî[å˜-ñèKhMZ“€ã’>HíAÉfa¢ÆæÞgpeJ¦¶>Ú~™ìCÚå»~bêád&ŸŠùCÝBæ¾i½S¼Mt"ÁÀîŒðçÙß|?ÛÕÇí¯Æwo”¨`~ÝürÊyô÷²ëD|À|´vÏ3÷¨ý´÷&ŽGÏ€bëðâ|ÀpÚñ…¤Ða øŸú@֟ĈêÙŽIIî\ÆH@¸€n²Ìï»6œGÐOÛç„¢|¨ðÚÙÈ`µŸv^±ËÄÍm½Â¼õ€¡LæÖ+¼;HDeÂG·B‹àJÐÏŒ}ƒij¯„ÍZZ6µuçÆþÀè¾\{.i–9aO´{*`ÒÞ§Yöc$ÚŠ±L[ãnÕÞ¦8¶ö(MžíûM5×ñ“ PÒ]|óï…¶¿Œb€§R{M"9„{¡ Ö˜ÝzÎÿ²hWöÉ #ùendstream -endobj -2014 0 obj << -/Type /Page -/Contents 2015 0 R -/Resources 2013 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 2012 0 R ->> endobj -2016 0 obj << -/D [2014 0 R /XYZ 56.6929 794.5015 null] ->> endobj -678 0 obj << -/D [2014 0 R /XYZ 56.6929 769.5949 null] ->> endobj -2017 0 obj << -/D [2014 0 R /XYZ 56.6929 748.2469 null] ->> endobj -2018 0 obj << -/D [2014 0 R /XYZ 56.6929 713.4785 null] ->> endobj -2019 0 obj << -/D [2014 0 R /XYZ 56.6929 650.1391 null] ->> endobj -2020 0 obj << -/D [2014 0 R /XYZ 56.6929 514.9018 null] ->> endobj -2021 0 obj << -/D [2014 0 R /XYZ 56.6929 376.6996 null] ->> endobj -2013 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R /F55 1035 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2024 0 obj << -/Length 3046 -/Filter /FlateDecode ->> -stream -xÚÝZK—Û¶ÞϯТ Í9Š',ñ8uOÜxÒä4É‚#QO(r"Rž¸¿¾O‚IkoÚ™…@ð¸¸øî ÿd¡ÂLó…Ô LÄb½¿Â‹÷ðî›+âiVh•R}}õ×WL.4ÒÍ÷Ûd,…°Rdq¿ùeùâíÛÛ»—¯¾^Q—_£ë•ÀxùæÅÝ/¾s}o¯5]¾øæöÝõŠÈŒ R†,ÃË»on_®nþv{ó÷}w{ýÛý·W·÷‘±”y‚™áê«_~Ë ¬áÛ+Œ˜Vbñ­ébÅC‚3zª«wWÿˆ&oí§cÂL!¡¨‘e‰4†6ÏRh”1xe¤ñðÑ­¹Û®±Þ•ÕVË¥Ùf‰0ŠUriæ7#üJ)¯šu^™†§N§edBuSWÃDÅú÷ÖµïÞ¹ßÃ5QËbÝØßù´+×»ôý¶8x¦÷[Ö«7µ_À®i»:ßþë&ÐîòεÚfoWµX¢‘” th!-µ,ºIþ8–®±q_½¯Ž~‚âϲíÚ¯N‡-#»E}"SËNqøø¤¥'ÌÑ»¦Y²Lb`N!F¥°ÌMl €s,“-Ù«jÕ–UY¿ŸØ™Œ#ª8÷åõfd`Qül¯/¬ÍD`gS¶ùCedÁØÒhh*tG4@ïñs¹Û×Û€8Oeë?pÂ5‚pEÞŽ,¤‡a“¹›L"šXÕ ¬.‰† É?I ¨§v k‹uW~(@%!K·á+Eç˜?wß)IY¨8SD¸"ÃMiÏÔßì:3läßf™BÒ`fÔ*{¢UJåì±Ê‘ʰ³Ú:Ž…H(ÁN)&<ÃÛæ°];aŒ0 ÆOñyÎ"Õk 2™–CÞÞÁ6•ÛSCéùqFf{ò²7G¿bL«ÂÔ·Mkð?Áï@ÀúÈsŽ8(wWüÙÍ"WbhoŠm~¬:h?Õ(œÁ+H-h2Ë!ššD"B"”¦Ñb<&êZª´*‹–W#hõf\² p¡ˆ -PÃYÖ"ÕoC¸H&H ™‹paŠ;D0Å"\L§‹éó/¡ãØ=;×éãú(MGa\²Ñ#¨´uÄÓb„"ƈ~‚@W˜"“²S"hÅ$ì)&lèOŸ%¡dõäxíE H+–yRãT7+k¯¬¶­€ LƒuŒ;xßM¬_Ýx=^çǶJâ¾Ø±nÁR{êc f3xpÿáæ¸l'mÀº©»¢î¦ÍªÐ8Ì V5!šV“@dµä÷q-QZ-Ù{·2Њ‘âb–©@sÎÔ@?¨@ʼM¹z[ lGö—ÃJ M½™ÝÝ• Ÿ&à#ÁY’`ˆBð]>•ÝδhÐ2’j“ëØæeu 1†é0â0Іù@ÑÜ‹Ö 7c¨%GJ*‘Fa0Ãç+ŽÄVôT[z}‹^bÌZƒFC<1Ô…fÿXVÅ„6h¥ªWkòÕXl¨V*YÁS~¨§ŠLgçvâ“ù¾¨Ã"áz·ÞH&Ò (ß×Ía2"‚SvÉ ±ÍèõL¨fô3PYÝ)(GYÆÕ¬‚2”Èäf‹T#œ •|—zÈZïÄ01) ¾Í]¾ùÙužåj¦³Ý5G“ØöCá>°Û[øN“²Y¿-·þÅ®ð³Å¨ß>l6>Vn °Ÿ+ž Tpªéò9…2®õP¡¦õ•¤áïyê -Ðâ‚÷ÎdÄ|w"ìóTçyAù4€ó‹yIÏ<¡šx ²3pùž8G’b1ÏX¤álp†€fÀÚA% ˆ3AøÍÍ8<žöm‹Cëž-œÃ§lycêCÈ “ ÞÂÙœ1©SÙ§ ’Í 2C¡Šg"2CY¬Òœ}†ïé cÉÎóë/a{y¦‘8›‡fJ5 ÍHe¡YVp4ËWŒŽÎù ŒõÙ&cÖò^“¥5¾æÙÊ)”1¯!xð5‘h|mͤñ„…¯ä›g|ÏJ.§Æ—a‘¦°,ßÁ—c%X§²Ó -Ì º%Ò\|àâKEú,»ÐÿÿQ‡‚ÄòBrŸRÍhf ²šÙ\NîaG”δ“sD±äóÌEªîúÉMñSÉ!{?]K¾<”1ìŒø,1Ü'ñ̆9v <]-$AJÆ`º†“‰¹» >æèAÐåëíÈ´Dh~yHA ÍŽCÙŽvœDw±ÓDe, t¶Îmû¤á*ò¦«íŠyôœÐÒñ ¹·¸¡.}ÜF!‹Ë´C±7CtÍáãœædâ -“OVy} ÞÌ`S+³ðN©¦á©¬`Û1xcD ²o»Õˆç5›Ír©FX–®0"“!o½ïQÚ24öìØ>[èLߙ‡u/Ðé ЊEONµóàÄœÓ㵎r.›&¬Ö陯tÙ“ÇXè< 63ÚÆ #!uqŠ*7Eù‰‰Œí±åKöœB¨eR­4ñ¸·u¦–†mß -E@h;%PàB[ßÓËΔxZ×x´"jÖà…íÁ‰éË]#•ë¼2çi¦ëÁÿæ~°â1?ä¬]ÊG«€R,¿¯]g´G+ñ´)Y„öЈÜ“‘ëéWE–Aµ÷MÌâ wwe^¹ž|ÖèüÕà³nwl½9dzy ¼,6eçAüª±åÔÛ—ñâ!—gøXÈæÑÚÙ²¡Ô¡l-W6”*– ¥öeCh ˆÐˆÐ.ý‡¡l(ƒFɨEÐêˆ+¦³åëÎOQµMŠ;3òÌv/–5wù‡Óªæ¾Èkw gª˜§ÇÁ•žs”§SSFž6¡8CZ^*ÿ§T3&4PYúî³b÷Y¾bì~Î×hì>`,$•Â×5à7w?ï~¸bùO÷p–YŠ“Ìh¬'í¿™¥d–"†à–v&³ÌLmõ f–T°çg–òÐÉÔÒ0>Z2ÂÅùy—`a÷dŠ Ñ48‘Åf7z xéÃ`L\s½B4—16ËY$:gm€OH)4—”òv³s®Äh/Ãz5‡ßýå}¦Mº—E›æbgw¶Š-ÛBmÉkII»ýER–dÚ)p¸—C€h$ g†Ã3e2ÆðGÆB"©©Çš#‰Ï·#<^Á»_GÄéD^)êj½Þ¼gñX#-©Ï–[ -a¥Èx¶ø<Ú™5ã9ÄcPB±¼˜'ÛtÍ×éüÛßEžº¬3@qš™8þþ‚¨IZÕû¼´Þ’Ü^ÓïYe¥²JªÚ½-–öJì%s·é¾±SìÚKjíÚ»EZ¥ó*]xNÀÎdµN÷/Y™¢vvìD>܈I˜‚›åôæÆ¾ú0ý˜c()_°À -þ‘K;´“©y‘/;¯{LwìN#J»¤=¼çÒ€™¸mÊ…OqÈ GZæÞÞÞ][{ÚÍj±Íò¬¬öIUìí£‡téršÏ]Z?&ylî‰TˆJ)ùp^™H¢}bE£{õ8û÷§‡sµø¼Í«tŸ§!Óe•nÝÚ¿+ò²ØWY½=ø…5ä’:;œ"ðûÍ~ŒÝr˜F… ÄcˆÍ¨ÜÁ‹iÄ5g‡%¶|¡4¶R?ÊE±M²ü°øÝéþ2H`îG^ìʬVFP¬ -œ)$)‘¡j@ n*Ìz‡KŠ Œº&šJÁI Z¶ZyKÈàçˆõ’l¥¹šèâ‚Ä þÙ*Zf—èž[i–q§ÛÚ]ì²))„S]¤Oõ*Ú¤ÏéæçÍ.[iÕJÛ€+-äÄ_n’UÀå#E†>ò€½ˆ)€%“°ZÀ˜_滺 YÖH©X-ï^MʶFÈCšà£l”­4 Xî§ð—mò=*‹ù·P¼Ð[âX¨¡ýêõEÌöP»‹ýQ8Gé­_5Z—~Ç —‹Ê£œ>mªìES°`5ÝY¶ð9ú½Õüp ØõHO ÞŸºÍÑÁ¨jØ{\á¸_5¯o¦ïnïg·Ÿî~²C -°rì÷$Ô™jæ$±—kW»ŒÜÄF²u×ʦ]ßMM³\a‹94 ˆÅx²KzÍ+ÓÅÍ:¯l2’¶—…é>ÙS]e…óº´Þy»¾CVzo:”¶…ëùvµÜlz‹•åËb¿M¬Ñ¦÷»kˆ`—¾.»GÐl˶۲ËVä—>aš1ò„˜uŠmüc6~4ð\|³}BM^²j]Ô•}“4Á¯êmšWåe`‰ˆ3ñùUfc¢—l³±ömnçÚÍWC\&õÆÅuø ÆtUïÛ©‰y„+‰1⬭oÒjþ¦‰ -™z"~À/%S]V-š4î—½n´&Ã?Ý˳*K6®&U2\‚ À&ukºôÔå¯:Ýgi‰~¢Ç~jöÐ1w ’ª4¡â|íjy¾}ÜE[-ã7âC—Þj¢Î»ôJ—½: b ¶çò±tø¾½æ~7l\¢¡gæ}†ÝîuQ:>³…b–åîqæöÈ<Ù%O›´ÏÖÁ…D¡‚ P«ØWp›…!™4¹íf¥PÔˆ‰ØÓÙHž4ã÷EÒ=lë -xl;õïóM]fÏö8D[R«WPÐÑ:ƒ¯u<ˆ‚s.(8rDA×eòþÿƒs„)D}]­Ó(hµšÀ=cÝÀÍažˆ0aî†GE2ŽõùøZ­@€½|±I¡i?Bšc¦C1˜Tê§bQ*áYQb¸†Žh~܈Ì[׈9ˡΛö`´6ÑîšÚekD"€ªS+˜pº×Ä^vEYfOA&AFc¦ü½” "qË㋃‡ Ô]- -X€Í˜‡6—¡U -áX’ã¥?ƒc…(ç¾r•@ç6މ<¥ýÏYÉSYlêÊ=Ý%ÕÚÀîtuÁ1J¿R]:Zgª‹×jªË"T]RZ°ð¹¹_]Ì—8¸Ÿ¯Õ -د.P±áI/Àió¹D»…4Â"I·Eþ¯ÒÝ™è¬hCŒ¾lÏ \ ¦É©ÏôôYö2ñäÚ Y5¨o"Ú's³éŒÃö8`êNòZ²×™:ôc_/ŸÒÈb"†ÇúÏEí)§¹ƒýTøž”ƒ&íSeˆ±M•%ÑsG¯KGŠC„|0úJs;蜟Ói ·<¢7 Š-tõ3μʑ³Á6TšSÇÙC=<Úùhs0x¹ti]Ùe­ýœj3”š³&1_ðÜ×»ÂÒk ™ýšc/:õÝß|Md,4=ÜžEþëß¿ypsPT4œ*ÙÒ » L®åÇ0p¿Çþ\¹$-endstream -endobj -2027 0 obj << -/Type /Page -/Contents 2028 0 R -/Resources 2026 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 2012 0 R ->> endobj -2029 0 obj << -/D [2027 0 R /XYZ 56.6929 794.5015 null] ->> endobj -2030 0 obj << -/D [2027 0 R /XYZ 56.6929 752.1483 null] ->> endobj -2031 0 obj << -/D [2027 0 R /XYZ 56.6929 689.4255 null] ->> endobj -2032 0 obj << -/D [2027 0 R /XYZ 56.6929 626.7027 null] ->> endobj -682 0 obj << -/D [2027 0 R /XYZ 56.6929 587.9664 null] ->> endobj -2033 0 obj << -/D [2027 0 R /XYZ 56.6929 555.0457 null] ->> endobj -2034 0 obj << -/D [2027 0 R /XYZ 56.6929 519.5738 null] ->> endobj -2035 0 obj << -/D [2027 0 R /XYZ 56.6929 453.9292 null] ->> endobj -2036 0 obj << -/D [2027 0 R /XYZ 56.6929 370.2609 null] ->> endobj -2037 0 obj << -/D [2027 0 R /XYZ 56.6929 265.1402 null] ->> endobj -2026 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F41 935 0 R /F53 1027 0 R /F55 1035 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2040 0 obj << -/Length 2882 -/Filter /FlateDecode ->> -stream -xÚÅZmÛ6þ¾¿ÂÀ}8-P+|§„;°I¶ÁÍ^®Ùâ -´ý •µ»jdɵ¤lr¿þf8¤,Ù²Ý"-š+ЇóòÌ2_0øÏ‰Ž™LÕ¦*ÖŒëE¾¾`‹G{sÁ=Í2-ÇT/ï.^|-í"S#ÌâîaÄ+‰Y’ðÅÝêÇèêÝ»ëÛ×7?\.…fÑËør©‹Þ^Ý~õ-õ½»LEtõæú=¼*% ¥HfXt{õöúõåÏwß\\ß âŒEæL¢,¿^üø3[¬@òo.X,ÓD/žá…ÅÔ“­>fuG  -Í=×}Õ•›Ê½z÷}뫞OP7µ›"/Á}D±òà3±z)3ƒtu¶.æPl)S%÷°æ¹tùP»Ã ૱ÀI»b».ëÂw?ùFݯï]úW´¤Eù©gãñ¥¨;ê Ä|g7§ÙqJô,wàíÍõ”žiéWëëÌå ¤¡šÔ0Ùàxcvm· xâ.¾òe‰/u ûU~F°;±‰Œce(cîÒ»]G–Æ ró™pQÇ@åÂqs67Ͷ;ŒF'JŸ–+ÍÈ5­? m -³'Ø·eÛõ®t_ûb[?äÛÏ‚€µb‹;ªóiðÆ[Ù–3î8°¦Þ±*2PÏíH$ׂ³À1›jkc©RqÚ¦cªã6¨œMÀ3±M@'— D3KNJ[ÃÍtÉÿ^ZmËÎ+%”‰Øöe¢Sc—u`Ö2oOÔî\i@±+Ý›~Îp2"ÇpO|¡øTv -çàW)ÔÁZGØ4ý-é^&îÐy$árÀî1'Ž‹4/ß 3öj‡ ÝRõº4cµø„þ z4¤"¦Rã6~;R6 H¤d±–"¤ø_. ‡r~iDt} `*…N -Ч”k·øâ×…[!•D5j»Ýî´à:^ܬÅâu{ZŒ·8/ǬݾŒ›ŽjiÂ@‚õ@g' -$5›®$ÛZ\&Zge]}öã~¬ì.ÚŽÞ¨NµÑË›Û×4'¥ŽUq)YôñR訨È~ä´À >Ó$h õþº¹äÚÏ[ÍåPΪOYýèŠ5xq'^xfôxè»~[P{[TE¥6p=pW…éW‚£ŒâË|L&ПÌ-ww_KdçSe"8€‡äf'!l röþ|•¸Î>-Û&ÿpX*jµ3‹ñ‡Ù)PÍÈ7É#†Ãy:𪪚ç™ ÔbwÒc%”‰*Qa'áXÕ‡³W¿™âã$¯iK92§ZدõE,ŒnA€ªèڣ𨘕J’?¹Lce…ú¾;L9ÂØ8µFHð&<0rŸ™fNkV„óÒ•ƒÆïÜß[–7C[DoŽB¦„Úsk=d29¥&Çí#)OAæ˜õ È”Jø4ÓdšÐnŸš¾ZQÛá<ûº.ò¢m3<šÚAï"ŸÃ1x¡òó2¬ð¶Î~A -@­²sÓ<#ÓÑÔáÙR1…W ÃÀ,bâáEbIbK)±±7'©±9‚ìšq8ò”¹²0Z?ôõÜyæ¢ÉܰwT½Qmªêýøú8Ë-÷i9™\)/âžµ‚£WU®K,jPnÀ]).]¯ -ÒXõÙÝáhûjÛ5\½»‰©÷æ’G5Q%~má ãWl‹Î/…IpF±ÏO¨'ÅŒ+âAu*väMúxìáèý^~@õµÔ&M`Ž–o<5q¢þCÊ·Ô¨éï‰0ãXñÆ™Œ¥ågO·<FZ$rñÆ¥†b>åBñ6f}¢xã†ÅÊ$ɤxxS3*Þ¬/Þ,™ï)=8Ë/}‡i6z.»'j¡CÍ|*é Âe?ƒå\x¸C ¡¾B8çP óüi 9¸´L;ö¨è†z³uÁE/ôP„Ò÷BèÉÂHC7Ù"Z5E[ÿ½£î¢†|–û[ñ¶ÈûQ ê.ÊkQÞ´~Xí?°¤cA ûiþÓ‚/ýf” Êl¸†¢½þÄ4ð‡Ï( ÀE+²Ÿ³¦ÕØ0jkºÀ|[Q ã† Ý èzðÅ[Z¤" ,«â±ð“ݱÑbjͳ íŠÂÊ#ÐÝD`˜D¿deu<#ŽcõËÂÿ¯MˆÖÆ ¨3÷h -'®ðœsì6|´ÞñËð¡fïÂÇR½/º¾tA/Žd@[0Þž„û7ÝxºŸý€%$¸MUt”ùà}³õ~æ—ÄJÝ¥¡ÖVÜù  l –_ÃS TíÄNºk,2;OKõ2ήÂ?.R“ƒU”JÓi¤N$ò×ë‡÷Á ¿øë›#°!ã|ñ|v?b‚<öØ_†·5 ¼P¸°ñ¾èZ&±N„‘ýÿ$Áendstream -endobj -2039 0 obj << -/Type /Page -/Contents 2040 0 R -/Resources 2038 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 2012 0 R ->> endobj -2041 0 obj << -/D [2039 0 R /XYZ 85.0394 794.5015 null] ->> endobj -2038 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F55 1035 0 R /F53 1027 0 R /F62 1060 0 R /F63 1063 0 R >> -/XObject << /Im2 1049 0 R /Im3 1172 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2044 0 obj << -/Length 2113 -/Filter /FlateDecode ->> -stream -xÚµÛrÛ¸õÝ_Á·R3Œbúä4Ž«GI¥íÌî>Ð"dsV"µ"i;¿ç LJ”ÜmÚñŒœû 4‹(ü±(QDn"m$I(K¢åæ‚F°wsÁδCšö±Þ/..? -bWÑbÕ£•š¦,Zä?Çï‰! @ãùÕ§ë“)—R¨øêË—ëù‡Ù¿á=¡€(”ÆŸ®æß®n=ìËÄðøêæúëä×ÅO׋½8}‘(Ëï?ÿJ£$ÿé‚aÒ$z†J˜1<Ú\ÈDD -ÑAÖ_/þ±'ØÛuGÇL yJ”PV)á hülEê ‘Ž³¥Ñ”1EDš°ÓÄüA -ÄÂrdHlš2’“DSÅ Iæ{q‡ˆIŽNJ5á:å‘‚Pæhb‡hH¢$Cœ@9ó¡l¹a[TÒ8ˆ–•¹_Ô¶éNUS¯0µLÔP㥭AM¬;[WíniñMÇëbS4õBI™‰¿•+´Cǯ-³Æ®¿CÐø€tv)jxc³2Pm³¦[Ù q9AStž¶#fÁ줜”jÛUéiV%ˆà´ã¢ŽQÝiç å3Fiå ÷º“›øùÑ–#Q P2#ߎZ‘ò.¶‹@Ò3h19xW¥‡°ßä„–z ak0åÃû)ßÃG ˆ1ÓíÎ -¯¹a$¥œÝêHP6$Mu\%zÌ ‘áû©¨ÚÚ#ð мÈý²j<²©ÂÈxö¯ÇI@¼pèÞú÷m²¢ta‹V(Öq4СÅmq6c Ë@gÁä°ŠJeOMõ ø6Õ^è‘Ó×ÖöcMkŠÂ¥fAHÑ n*<±}3b#ÃË¥ÕÓ¡e”iTÔ'vIJCaÙOm°¼³P›?v¸Š‰‹'»«]òâKÙnî}´Q_¸pa_ŠæÈê pÒ”‰óöéc¶ÏËÙçŸGöÑD+Ø=˲Ca9°^®†,ÿKûÜ·Å:,}!¬ßý) Š”&Þˆ°>Ö vX΂/>;“¤_¸Aßæ'ŸËlùh§+¨‡Ò1m24>+ÞkD>1hºPd…QCo«,(Ϛ̯V» ƒz½ ¢Ä´ÒRŠ~ÀO;¥:-‹KßÀ«îtðÙê`/·«¬]‡8x*ì3NèGîëÑ„Â]A0ý?”µ†9Íü‰Šœ’!Ä10ôC²„†Å¸/ÿ’žæÝ`xåÆã;÷;wól¿æñÍ©±YÂjŒÔal¦Ä0¸"9¤þúÄØ,ÎŒÍ}ÊgÆf s eÆ! 7‰Dï‡\oÜ]7þÍwWX¸Ž O‰s¼Â¥ rØÚSÁ±Ç¯Va§„†j=-å›/@ßÏæüÊøGî[þ¼]W[¨6n†8h»¾”è4ÞdˆþÝ¿ \øÜÙëþžJÀÄyŸ8‡?tÀ¢ôÏÌ?VmÓîöDÖ6«­Ÿ/O5í~@ýPˆþZö 깑¼_+{QßK˜a¾L½¿ÎnæW·_Gj x/ÅPÂâ -Èa6wuªm`‚òô]†¡„Õ_0˜ëÊ '6ܬ«Ö5  -÷á$†•_¹:ÏeU6žÁÚŸñÅ vp -®íºÒ_ƒ¬ý>  kžv#ó®Ì—#qh~PÒ«hÇa×Íò“ÝKpFÔÉùîÕÇ:ݽöXÁ!ÿöå­Ñ„ÆÎ³íFØšå„j¸ûø~¬œá—¡„¶ä`Ÿ]Ã:jÞ'-㓦‚"ôAéç´™N0Òl¾ÀþF,®ï>us¸ÆšTËs2ìqŽ„-b­ ûR<¶¡[æÕsyÞ0à M'ÁÉš)¸åØö ]ïûogèÚ–yQ>tƒÕ÷° lÂ8öšnȽ—­‹€Ô–¹ý…R^ZÞ‡u_ -"5øEüÛçùÇÙÍ·»+4÷böyþv­Xt÷ë™?š‘1RBB³RÝg -((êCëK ^ÙDŒµ»ÌI߇ÖT•_,«Ívm_ün€¹­—»â¾;SvP¸®ýí‰ øb¯GLO¬±}*ÛWA.OÖA°=ƒhyãFýŠtÚD’³ÐS¶»Üµ¥·R°Õ¶È¥à ƒ+ôY1öHGr )M`W‰ ㆠ-©ßö¦E~ÞN];„£µšîãô‡ÿ)ðúO© Xü„¦šƒu -e\»˜Â=ªÖ±ìÂkè±endstream -endobj -2043 0 obj << -/Type /Page -/Contents 2044 0 R -/Resources 2042 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 2012 0 R ->> endobj -2045 0 obj << -/D [2043 0 R /XYZ 56.6929 794.5015 null] ->> endobj -2046 0 obj << -/D [2043 0 R /XYZ 56.6929 374.0222 null] ->> endobj -2047 0 obj << -/D [2043 0 R /XYZ 56.6929 216.7302 null] ->> endobj -2048 0 obj << -/D [2043 0 R /XYZ 56.6929 132.6902 null] ->> endobj -2042 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F62 1060 0 R /F63 1063 0 R /F41 935 0 R /F21 710 0 R /F55 1035 0 R /F53 1027 0 R /F39 895 0 R /F48 950 0 R >> -/XObject << /Im2 1049 0 R /Im3 1172 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2051 0 obj << /Length 3048 /Filter /FlateDecode >> stream -xÚ­ZÝsÛ6÷_¡·“§K|ûæÆnê¦q|‘3½»4”H[œH¤*Röùzýßo»à—áÄ7wãsñµX,v»$f!ü‰™‰‚P¥z–¤:ˆBÍÖ»“pvm¯O÷Y¸N‹a¯nN¾ûQ%³4HcÏnn¼L#f7ùÇùÙõõÅÕùåßN2 -ç?§‹( çoÏ®>œýBu×§©œŸ½¾XBQjC'b¿8œ_-?\ŸŸ&z~sqúéæç“‹›N¬¡è"T(Óï'?…³VðóI¨ÔD³(„HS9ÛèH‘VÊÕlO–'íZíPŸ*"e‚ÈÈÄ£ )fBiÉ‘2¢4ˆ•TVË‹ ZóÙ/Ëw¸Ð`:Ð`8ƒVXL(m÷÷?¾:]ˆ4œÃòuF}w±Ž ÃÞßz¢ˆJp‡!;ýÿe½€ÝB†r^e»"_¬7Åúóº®n £ÐÀ?ñ´ù_uUL›U¾žÖm§ÂÌ‹&÷2 Ü4µ<]ÔB¨0Huåöþáòêœ6+å=ËweU6í!këU½/n š½ZTõ6«ŽÙÖ£›@Æ0 é#à.#£Yt* -tÂfsöáæ§wï=<'örYµÅ¡*Z’dùØ´Å®¡Â«ºjêC[wý¼:P:–ÌwKF-XÂÖ†à¨UsÜçY[à(ì¦t`D”ØnW ßg„2Q†„ê8X9~“2!êüö§\sájIİï±-·eûèST8VÐò±ª÷MÙL!"?Wà¬:MIísi’ËHí…¾0#€²Å…uw-<Ð×õ¯<M~\äŸuÞQwDü›>‹z\äµG#;‚)d xGvôq³ËÖßú\ :‹ï›b}°ÃF -%Ày;wt3|öÌ ÓÀ˜$åžÀù¶Ü–ZFwpÐ-©õ°\¨$ -¢Ð’}Œ‚C[îŠúؾœ÷Ñà ÁÄ`¹Ôõ˜ïŸç -Xœ$‘™r=¼„+¨õPͳ\Ó)×÷_åzȪ¼Þ厩âŒ}ÂôÞQ¸'¸ãŸ¼8¢´!¨¹ÉùÅòÕûËë›ËwWݨgÁdèùSd‡€«µfÙJ„îÚ9QmMßæ¸Ú•-ѽ» çî@|pî4éïÇ¢i™cÆßA(+Ǿ¬è H -çÌ胪a!ŠÃ=€4¤SÈ4™ßl(À§y#Ü϶Ûú'Ž‹ÔÔGKXˆïj×µýæ¶«¦ù¡qŲ<·òi£t¡q»úÞ5ÜÚšzÇ#èƒqú?”ííØVïl\Ù>R©È˶¬î¨Ðnx€ªæ¨¯m V¸x—ÙÀðmñt»@ë¬b¢®Ú¬¬žtãc_X8.Hö˦òŽÇ¥vãø“ðÝ€‘Ö»Z§õ [äš:Líšþ,@%-Û–¨Ì͆…c•ƒ-X2w‰\mÆ–*îËÌã"Â@2'ºþ%‰©Cç¾5Ï™Ñçü§W×D±q ›½Í‰®j–~Å‚ã†ܸz¤/hŽõ°—#@÷¼r.bÕ‡ ·‘vÞS0U®y³ÑäˆÊ‡á™–ÉÃaVgàòÜ;k³±¬¸e[7­w³nÐjU”z¶»¯8Vò®Õï*XVr‡Îù°Íª¾ãÇ·v©O·X…äšX¿h‹c™:Øßd÷, j¿+.£Ëð\ÑpÞ„àRÄjìšèÆèºa fçbZö‹–Z€éT-U[•ãwÃMÈà/,HA Z¶0w9{uöö‚HÛÏÚt¨oGbH'Æ|È0—ïÎ^ìÔh'žtIåq‘ûntAábm iA;¡²Ï.ö>VAœ&æE[¯”éY‹ŸÈ»ä9òbu¼ãéê÷3Ò)++÷7÷ p®ƒÅÚb:±¹­»Œe–`ð+ -lÇ ›/\â$€=ƒæM‡·ìëÙ†wY^LÜ›ö±c²ß–x׊’"Ô "Ùp$Gáh…ÿ›Mq—ˆ.Î}›¬­»ŒÎm2­è™M–ã¼È¿´t¬Y p†êÂ\‰“9|µû}G19šìã¢o -ÒÜðËfÌ[;86b~ã¹$qZ4¤ÅS8CRÙdk6œp¢¼«²öÈ(Ku6¦#a1 -¾”»!eÑ ¾Ùv `M–2 Ñ¥r¶€©œeA1 =Q -7´éyOÜ,/_ûrO$Hô#¨®}Üs+¸ÏúP® -n°î—(›Q¥8jÃ`~¼ñJàùI¼¬5²V‘bÖÖ[¸V¦Jø–e§‡¤ìõr¹°K·%LnU,G³@µ%¶ P1à ¤ûˆ!„½EÒºL‚ÛÁÇ=:gÁì‹j}xthål{W âï¨x[sH$ÅbE@5ÿéíÙ«Ew>°¢vóíyd¥0ó‡M¹Æl ö‡›ÑIŠ6[†¯½*C$Ú..¿£+#¨¬a9";1™ß â?aÎk0v ß’Ù`z} -î‹Ko¨ò¡Ün©gU¹ÏBmaRÐZsìf4õüH-M±-l’h8‘A"ÛÃLÈö‡’¢Ö”ņ¾…•øºšŽÓgšuZT<ª BU”/³ -7Ngd*Z&óëƒ/Ñ(«¦Í@Ñ R6DzÍVxì4&E‚œ8Œút*a`[ì@‚†Êì.ÐmÅ \šj?¼K±îŠïŠvý])éñ•TBÒ]45ó&Ÿ…‰ À ªêSÈ$ ^ZOw¼‘j{$²¦©×´KX´Ì ¡ÑŒ÷[‡Àe«,Ë•e‰~—±HG‡ãËkî™ç í U`ª8è 2 U<Ù0…NŸ­’6DÌv”ÝøJ €dÄjhHue Ì4رRÚW[Þ€&ÂÂI}wÈö‚"ftƒ¯uÇ‚§¤ÏÓIã˜RªËä&Vë@8"Ïbwl8ß_1ø5mÝa½E0‡uôysñwê?mž¾|sà@˜;­ŸÁj5Í禇(âÙ(zQ’¥áîùòº`¶`$Hø,÷¸äøòN.î¿îfxŠ•éR*Øšp퉷qÉî›â°¢KþÚŸYëhTÙ¶ñ)`á¦e¹_»/Ð.d[”]®?Y¹J 0àÒÆGÿéGè$î/ <Ù§ ¢8qºwWÁ_ââÎP’ÎùJŠá9¦—ضŒR{×1HE ƒ‘k#náü®¨ÜY -zðu »2T<ÉÒ õ–‘!dDû}éIIÓÁ]$ì]$ݹ)MGç&;DßÛì¸m©òO¤lº9ơȸ¼[H[ ú@…ݱ¥»<¼ÿ\oÆîí @"濞FÑœne’çÌÁÀÂE˜~q#5F"1ÚÈo½ž æª_v:J´£ÓQf/CwL‘ ÈDŒlÛçÆá0º¾ô=~à‹Ž”Ú÷61oô~€ÙQArQ7<#ˆä.ƒ•‘A*ä$u¿E#“Ψ%ZÛÎw[¯‚ؤQÞüìÿ ¾Q|ó]óÿ@x½÷+S` {DŠdls;é¦D¨Ç .*³¶°.4Nöò 57vv-#íÑeQ`”NÆþÓ‹‘ȃ¥ø¬”¸×( -RÊ€ïnmúb(\aÍžsðF<$Bó«Mö°Ío×"ÀÜ×p.‰ÔôyÚ›˜϶ &-´39;‹€rÛÙ'ݲ⫠->ߌlä£ï'P¢ÛNûBçݾ³õQ_á2~áã· ®ôéEÅ kwµàiÈÅÎú{o'ÜT ’)R›ðyÿ-x}{ûþæÝ§ÿ\/…fÁ›ðz© þõúæëëíö:Áëïï®—<‰y  a ÞÝÜݽ»¼ûôñ濟oÞ_ÿqÿóÕûûޱ!óœIä꯫ßþ`‹öðó ešèÅ3|°§©Xì®”–¡VR:Êöêîê×nÂA¯:& ¥“P -–Z…RK5.22 "XÆ +VRÐr"|Ld…"[~¾ú õ™†Q"5LŽˆ²ÚÛå¦>ì²öT(<ŠBØGº®|Æ_‡aP–å1•ÔÂçðþ±¸^J®Ë´UPoˆÖºNÃ%õý]W–ø;cb[5PÁmÝ4åj[ˆ&k—®y$ Of û0Ž˜°²ø]Õß[üµèá.ÕÜ™fy±ÉŽÛšÜ.Uå#ËD”N·_å=O-‡œ'Ž£ ("‰E(l¦Z;Ñ•°C‘ê Þ·e]QÛÑö‡r—Êí‹%WmQåEN_m¿Q°*èûظ5ò—*Û•kúhʇÊ!ðìMm§{Ä“£–1?îö4"¢#Ã0·aEˆø}VuµÄ£ /§Ø^×U›•UY=Ѐã>ÏZÃvf5VvÚŽq@æ%)º¡pÎAºKÉRRAƒ¨ú‡#Z’0Rœ„¡×n¹ªnÇöµË¾dvÇõ#µš¢j,‘D Üd/f цg¶É€(a‚&eÖJ QÓV¢C+ñ稕àBÇVÿ,Û¶8œÙ ‹JÍsÖ¡FXóìƒÞ8O}ÞþýX Ø£È%z5‰¬fÂsÙ>-#*×wsôvlÖ­!0ýÛrS´å®ø >cdÛ-Ñ¿|A£¬ºÔæ7o¨¿lš£›Öè$ÐHë€ TÈ\]›ŠtêßÜ~+qß÷V1q…T¥ÜQɪ¢>6MM“àÓ†´Œµû’QT ”Õš&ÛpO¶æú™îî5-„…™05²‚Þ= y*ÍŠËîÒ$lòîâzR°`Ÿ5ÆvHÁƒÌÒœµ†&ì"K.1r¸ŽUÌH™à±§—ƒÎ;4;õcöTø3¯ì7Á +˜ìãȲ‘­êŽ#â¦Ïv£;Ã3ñ(0bhÌÍPÃ;N#29»'ú,“0¹³ú΀H.‚f_¬KÔO³+8ÞŒèv*Ó~.«¼~¦6™W>—FZ@3Û†_²ÜUæN¨Þ•n°møwÀ('Xƒ$…m{ÊÙŸ%wI°ùxl¬9³*“å¤ÇšjžÅ\<}rPdTZ?‡~½°;˜4T‰"ÆîNæRiw‰éËÉO(T+㜀ÚÚߦv8ð+À"µWÀEÛÐ÷S¶-Á¡Ô‡ÆÎSåvxq-jõb‰'b’Q4l¬³õ㨂›­±Jwa¢rC”-Å,Fd"¨Ž»­ }Æ9Ñ*KËëê-‘ýã“d£à—lŒÞ‰$´Qïìc l¶Ðtã‡ÓMÙÜÊžò¶h¬ª€Ã~(šþ¤A›m‹vël/4<ᣃ,ŒÒtÛ{åCw~•¶ž¶nZcì´3¨}v«¥s¬ZC@š$é¼c¢¦k‡2޵q¬ -¸tÒÚ…j½‡;uêX!ÞKÀg9ëP#¬ùŽVd'¬Ýy6H¹X[)«lD4¸étzÞÈeG ÀS¼y¡£uà6TvÖ~XÚe›6;¹VŠ"#¤ž/¶ò¢…€­È­7…èÄ׸··_§O–A€Ÿ*}ád¨™“u(s²7c'‹¹£ ™š:[‚Í(³íDv%ƒäa–É5Â¥—70Æ*Š|6Mh«XÜ}~( –ˆèNÛ.ÄF ž:ÒZ7Ú؉y ±AŸsõ34ô1s-Sp: ÃA/€lè[Qì'²"©B29žzý4²Š࣓aÊ…îɸ¦‰% —Iwzã‰x#©c9˜õX•ßѶLMÊ”ÁdsÞ=g + *†B†ãÙYv˜så Ú*²ÓŒÉÓ[„Ã”ŽæVuÓU=»¢â‰(,û®v™Mg–órsj–2RRDÊh†2B`8#&°di‡tARØŒ°jRCüZ¨­Œ.°`A#ø•& Ÿ†ñÓHÌ´M‡}ùð–> endobj -2052 0 obj << -/D [2050 0 R /XYZ 85.0394 794.5015 null] +2008 0 obj << +/D [2006 0 R /XYZ 85.0394 794.5015 null] >> endobj -2053 0 obj << -/D [2050 0 R /XYZ 85.0394 752.3578 null] ->> endobj -2054 0 obj << -/D [2050 0 R /XYZ 85.0394 679.8301 null] ->> endobj -686 0 obj << -/D [2050 0 R /XYZ 85.0394 642.5879 null] ->> endobj -2055 0 obj << -/D [2050 0 R /XYZ 85.0394 606.8804 null] ->> endobj -2056 0 obj << -/D [2050 0 R /XYZ 85.0394 575.5077 null] ->> endobj -2057 0 obj << -/D [2050 0 R /XYZ 85.0394 512.0134 null] ->> endobj -2058 0 obj << -/D [2050 0 R /XYZ 85.0394 442.4505 null] ->> endobj -2049 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F39 895 0 R /F23 734 0 R /F41 935 0 R /F53 1027 0 R >> +2005 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F55 1040 0 R /F23 738 0 R /F41 940 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2062 0 obj << -/Length 3460 +2012 0 obj << +/Length 2545 /Filter /FlateDecode >> stream -xÚ¥ZYsÜ6~ׯÐÛRUMIì›+^§ÖŽ×’+[›äCr,®‡ädȱ-ÿúíF7Àc8²][)‡`£G_”¸Œà?q©“01Ò\¦&u$ôeÑ\D—ïaîÅ…`žkÇt=åúñþâÙÏ*½4¡Idry¿¬•…Q–‰Ëûò÷àÇPDá,¯ïÞ½y~s•ÆÁýíÕµ”±J‚›7on_?ùox×0g¯n^¿»ù'ÑÞ\ܼ¸½»úóþ—‹Û{¬éÑE¤ðL]üþgtY ~¹ˆBe2}ù ^¢P#/›‹X«PÇJ9Êîâîâ_~Áɬýéª(à6R%rER­ÉB›0Q0…²è«âp%² ðž™ÞõÕÕµŠEÐmñÃC…×|ös,&‹e24iÀE®‰c¶Ð¡ŠSÁ,Ý~¨»–V¬{Ú¡¬û¢;ò÷UI›ªÈnÜ×Rû‡œŽXÒÄxäùrýq¿ßÕn­¼ç'M]Óä-ÏíêÖÞéòÌ$B"4ZK{VÚîý±©Ú" ꖞŮ‚IfÁP}F‘©H÷xœoòGšÝ\‰ ¢áǺ¯7»j¾½ºã°?ŵûv Íìû?"P&üO0ëaºF†7ÃWØ|èôòGI·W“×íÿP"ø¾á³±BA1³[ƒàað„¿õdåýCµÛ…žÕ€¢fõ~Õ$€#Ò&s6ñaÍ&âP©4e’–2A¾ë;m*zÂaðÔh~<Óï«¢ÞºÐãîå ”QÄ2ʇêq¶ŒÜù.Þu‘-ýü±Í›º éç¯ïø—û’8`Lvö×±ê‡Þ*; ^¶d9Jt221s>XéÂ|zK‚ñÂ’&×äeõAEfÒÉ|8T¢d™h€¶ÀDíîÊÙ/ šüsÝ¦Ö “sþÅþɲ€P8®tI£Mµí¼•Ã{ͬö¶Jù¦; lW‰½¢f_Ÿò&´ð¡gnÿõtmi£ˆ‚ÿT„I.Ø´srôÓ>á ¹Ö¨M‘P|>²0…4Ùé㸮¾x©H;}Œx¢2i–ö`™qt|É!ÿ¸–F³ä¢©ä©§§rË;IzKÔ/,*ŒÆ"wv;кŒ@ßð'?¬«Fë(Yª&‰œjλ‘ä˜P1€4:"fG´6©¦F%ìö@TÌeµïS­$.&ÛZÞÞ»¢ß͹"L²º`jSy§Éä2$?؈Ì8¾%=`%]{uvMY­E†B$f)j-'Ù_O„œéP á=‹ŠÞÉ,$ïÒB€µÎŸ’ a‚ 8÷€ÕCݾç…û¡jh\vnÎ-%ã{÷±.]„A+KEЊ|ÒPÆÎxžÁµŸÑÑVnŸ@¹-|Âè*Ð` ®ÀeU–ò±.lš¬œÝYª³øÉL(Xm‰i -Eü„yÓQ†Q'ä"Ø3È-.¤dÆþ˜O©óZ¦±s˜ëR¹ÂNùDIetd äô( œÍ‹Áz–r2 )+'5©â½³E)W¹‹Ó8/JENÊÉLæË¬Ár~qGáSzY‡k!cnL—ÌAÇ5ßIÁ8Ÿ’³ʵ<Æ„™N]x€|ÙVd=mE¥î³P$ÌÕ-UʈôœÎ#yçäü¢…‹ cô‰9ÑñÏÊ0ëB¢Óšt"  z¿›€{úDÎ3nQ| -®iTjöòõ›w÷ô›Ÿ}ûê{F÷+ `„õDeÚ|C(¥öàc11/ñ¦"óÒ“>Â)~¥:ÔÆÙû¶WD3]U’1±šú/,Ù`|£NÜ®6»‰‚ÛÜf„謮ÙbYø€c{߬RðŸÁ,ö ÃØÔ±AfbÑ ±­))ýîZêà®CC*ïÞÓ›/B”&kD-ð©~@ØüÈ¿Ûû®·ñ ´æô¼åÐÓ“ÕdPÕ8Cc­èX°ð8¡MÃû¹o /Q•<çÚ.¾Õ}m ¯x¨Š=qÙÆ™p-1œPuÓÛÅô$Ü"F‹{¨lC ¦§+ö¶yF+•5“×°µ:²@‡ Ìît¾‚”%(6Ít'1S Ê—­Ù+öoÞ¾…õ¸‡$'V;þ\S¿ï˜VóOóMO‘æ&™X¢\ -£œ ø ©Ó;ã{sìy™ s4ÕÀ{miâLÏ ûI>ý7jÌYŒZä,†Ïm¨ÝÏþX•ŬX™àý)³pz£ÍlµÿBeg=ÈðÑŒ»,¸Ø‚¡µóÙ亡áÌD+†ºÍëõà-ÿØFIÇ¢I¥éüÖ8 Ë÷¤Cœ¶¦ -Ï/ÕguOèÙør -¼vj^‰š¹Àó¥:]'™­ãšèÙIf8<ØEv;ìÖ¬hÛÆ)¤RÇz€ºÉ^TÍZˆ%1Œw—Ë»sc+õj›õ–ØÇR9o Ž‹M}pâCÈ:‚’ß«"×ÀŸt‡5½6ußSN‘ÍÏYÆ6#†7DÙìòö ]¼É­í½Ùš^–ß fÑNJª8qY¤íC†LËbßFa@g„€¥íW‚~qÚ¼(ŽªI5–ËÅêÙÅI˜²35»òØÎŒ(š¾Øâ¬å©±[Œ/¶[|¾é1/¾}eÈI¡ï⇧³õ •ö>” ¸u“»†Š§Âê5W’M•s¦ˆ ™&×ÙvÖäÿ~òåJ„)Ô+—Ré0ê̇&⹞0Ñg&±ò™É1‘š¹Wèo>Jâ÷}wþ\žG$i5Iúä<Ó鉿EØ\’ÍNtWQ†é`ŽX‹ƒÒi_¼cûÞ„ëf)ÌS;š¡ Ž‘¶ aïzš{IÈßt,|Kz”ÃJõÅFª]«0ÕÁoØ„£b×h̉j‹‡‚ŠÇIÛŽ¸}ÈÂW |ðœÔ€åZÇYÄYGþ»ÁSI©•ŒÜI)pÑ!,@Ãèè"¾ |F š¼üa'§ÏŒŒzŒ~Ü&Ø'Ư3`s »v›I‚W¯o^ÝRi`!Ö–@·ùŠÑ®ê -þÚ~ÿêݯ7Dœƒ.Mº B öË”Ñ.à&þ^HôætÍËMÃY„$ô“5¬L+]9eÝÜöG0Š'' åévø-4ê[Ì3‡±³ŽOÕ5“½Ë1ã Pê“î°ÞÛ„Kk À˜±É˜ÛÚšµ¿ -i>ƒ‚)‰³…ùOZj®Û< «Ë¯qc›aŠçN^ë:­æËSÍyJ…FÍÄÉÓX:å:¦ž /ºë -ßO,Ëõ@Î#i¬B$ñÓçñ\+R `ÐqšÎOÄh*ÓˆÐT¦b¢ýt&S±Ô>Îr*’º.Ðè’+(*ñ þ‹€À -0‰0‹•!TÁò¿Ñw Y«òûX’ÅÊk×N×ËP ¤"& ê«@šÉ0æ›`Tø㌢° £¨P±ó–æQ”ùõn¢¤™4òPß¶DÅ¿@1w ×pÈöE´I¾ŽÆÄÍ.²‡³%Ç#Qì§×Èz8Y†gc?®àè4ì”/Ãܘ²Úõéá½½ w<"Æ‚ÄX0ARÛSLa?Çqí’E{‰3¾$û­¾1m3®¾~ßú$ò,Ld&”êkׄ黃¹7gÂó,Ó¢ÏõÃÍÙ÷?)3ËYžÊtv³î­•1žebvSþ1ÿ¥ìVàó××Ëåå‹åÛ7×ÿ~w}y¾™f~ñþýåõë·¿Ÿ/d˜9Ÿÿzqýá⢽?ÏåüâÍåòüÏ›ŸÏ.o¢b}åW¨Õ_güÉg%ìáç3ÎTž%³'xáL乜íÎt¢X¢• +”íÙòìŸqÁÞ¬ûtÊ:ÉX"u +fÑL›4Ÿ6™`F`2š3ŽìÁdRL™,p¡É7šj–ç"›õ;˜&DªžÈ†F‰¡È·wuóp.²¹%“_-¯hð‘sUÜѸ©éùÉ>Óàic=©´}ØUuUß…©¢£Q×г­îjväAo&Ã3¦SPþ´-{\'l¸œ-Šüþ§$éq +ÎL–'°:²´Å¶ë• ™Ö+0MèÕ7xž2e´êõÆÖö¡èÀÜ"Oæ>Òù5ä‡"ÊjST5QŸªnCÄnc‰tW=Úšhû™¶^5¥-‰÷™$1qhº,Z¿ÊGžpo”¾š2K!®³ld•Ñf¤b9¦1ÁRÂë[xmoý–ömÐ)U]V+Ü2¬:[(™0)xU–'‰t v1lê6¨‡Uí0 n}¬’¤a<Þ‘yc8:ËáÀ›‡ÎÄ/FdŠé¤Õ"²ÏõrDF.‘ÿ˜ŠH,`Æ[µêœîMÝŽ•гÄ$Ùií"ׄz}_ +•°$1b¨ßo/±˜6aôB0upÔ®¨}¡¨ê¸%ˆJ%øü&8¤´ëb?v±àüeÇ(Å4—Ó~90p‹gr^¹8ª¹†™T¨“òϱ¼¾dFËt ¬¬d>°2¾ôðVÆ¡·2[ÛÑÀ4Þ½¿Áºýîà ½‡‚ãÆUl·G‹Rµ_QÕ/[ÏX—4(zÖM7Ð’’7cYb†‰Û Š£•‘¸†W +­]íû½¦´[{‚ã§'YβTvzée§&Tú禮`/¹µGõ_²45ùI¹çXî ú–j}¹1ø½pÊ¥¦îŠ^% µœ®|ØRmù²Ñ©(ð«õ¸N˜-p¡þF2Âé/È L2ù’1™‰‘Ìå½]Uk¬')´ÄMµÚÐtiiÔnšý¶¤±³<}oH© 9.°™§l<ËR’Íß®‰T7ãÕ‹²¸*ƒÎ³å+ ç-·¬.ëÕ­0½^˜@`aFd? œº*ä $ æ«Ëñ8³0g;š$¹*Æ NÝÛϸ1®icT7ZÏwØÐ×;ö¢‹0Þ>Ë_amïVŠUx»¨CqàÃm¡_…ÔE6ÔZ³öõ¿¬ü»æáù\1?9|:7ë$ˆõý z2e ‡åÖ³…„¾ÇSp`a#•æËß/~}ÿËåø­IÃ4÷ŽÒ8Õ l»mžÈ)`¡f·##ÂÊoiˆûv‹ê¬ß…áÌ!yÐ(†ÁýÖ2XdBƒ2"Koˆ0í1" +ï‚R¯—4 ¸ƒPÃKâ¼}Ž6éiƒP Ës/¡¬[(× X>žÐg¡5f::!æUo'ì;èJß #µAÈ1iDNöƒÜ>¾Å”Ðö\ÌŸýËnßvÄrëY]#Ì|–!aW´€-hÊ)2P®îïO)Í+€Üò–¶w¦Xš¥²w£îUK@VKgF-‚(ˆªú±Y¹¦êèd¾mšO- 14Ë À$سÆNáo•CIÔ&*„ÆüRiN¶Ñ>p0È/¥ÓéüÂOÛ&|Zt4z½¤ç1NÐíãÀ¹î…–Û¢ã&‹"•L#¼A}» ]0¸jŠŽKR ¿ÕÅÝ”{À—©xçØ² p¹49Àa‘³”CÝEîoÎ)ç!À1K)›²èÙг#ôÕ0ní£PzX)^ȃ©Z9\–Q{Ÿbüfº8Ñþü‰~Xlż¸m!µü›—ójÂîy΄Èô°D 6†‰\/¬(` ÚQµ? ­‘ƒÒ„IÌdNöŒ0>½À2‘y8Šºs… ¼<ÂVÀÎoÃÀ;Çš?°,i¿ö¯^…~zW1Ædm[ÝÅvà;Þ§HÆó4ŸºØxØ·ž*ô’^HyÎHq) Sp–ú;l<º_¤ßÏ"t!Œš¸§™ÇªÙ·Ûgšò¶vã°Cz Ðzg5X x€ @í¥#¨VD4àØ<‚BÁÐ/çEÛîwÓÁ=F¹ÿ l˜ª|²¬î§R:„ÝT¶OäøÉbò•EäÿQè†aÍÕõ»ß®ý%ë‡7ˉÄÁ›¯Ê|žë¤O:Zã.’®µ Õ_í¥êˆ²òI©y@åšÂSÇÄYWÁ ö€µ GhKã­¤ ßçíþÖ“Ý䚦(vt¸„¦D +êáU¼8ÓóÚZwŸ5†bh”5M¹_Y"ôXïAAg*„/%ý¹°AÈN\ïI»vðµß,È)J¼Dm;è¥Ðqvý™'Îk¬ÛÕµ¼ùÜŠáé×71—˜GÁCG!‚Ÿ­â[wÂ,Ö<ú/ȘÀ@Y×BI oyðÖ"Æ€=œÆð,h¬qHHCq '"ÝïË‚Oþâ.ÞA…JËt\ÞßZÇÒ0.Ïdó} –îöµ+_JWÚ…]ãF×P_ˆ £ +'éª )xëb?W·Õ¶êži2L¹¸Ÿ@7ÒÅ×·ÙŒ‰TƶÜX¿>]Ñ€ÀÕÆ®>y™ ‘vÅ'K”6^¹à[AÚ}ë¬â°²<䈆¦;)áï¤BR",í¦ðŽ'\à=ö| ƒª$"e“ãëüs»Å¿x@gsà):h ÷~ÚiOò³›&ÂPv³ïFâ’èXè&ïïmñ@ó°ðT8íW+K‡ø”÷²Ûß +$𯔚GD 2C`Ïz¡‹ëÌí è¼Ù]T +{ä¡ fþ¾3|c „>„ œl÷Ô³x³:?¬ÑMíÐU¦£ë¢1Z¤ú¤„ŒÖ“„íá Ø?´W‡ïäNB’o$Èèá%èØÚ¢uõ/7â M`°³EÝU;WÈ$Ì/ìŠ'h[—^%ºñÁ×Ps‚{Љ)9ÙÐíô렬ϰC ‚ üzØÿØ:¾  ØÓÔú¡í=°ñ´"\_Œ„˜g=ø.ô9WïØKÿª„៖Wn<‚ÿù¿ÑÿÀðg–½py'MÂàã4(…¦RßQr&œ¬uÿoœ±8endstream +endobj +2011 0 obj << +/Type /Page +/Contents 2012 0 R +/Resources 2010 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2009 0 R +>> endobj +2013 0 obj << +/D [2011 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2014 0 obj << +/D [2011 0 R /XYZ 56.6929 485.757 null] +>> endobj +2015 0 obj << +/D [2011 0 R /XYZ 56.6929 207.615 null] +>> endobj +2010 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F55 1040 0 R /F53 1032 0 R /F48 955 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2018 0 obj << +/Length 1499 +/Filter /FlateDecode +>> +stream +xÚ½X[sÚ8~çWøfŠª»íÇ”Ð6Ý–dÙÝ™6.ˆÄ-Ø]Û$¥¿~,ÉØ `ÛÙÉLÆ–?sô+"†?Daó Œ9˜ˆ`¾îá྽é‹:аz5ë½|Í F±¤2˜-[²"„£ˆ³ÅÇþÅÍÍxryõ×`Hî¿Bƒ¡À¸ÿábrwñÞ¬Ý bÚ¿x3ž†$”Œ(Ô0‰û“‹ãËáèíxôÛèzòzp?{×ÏÃÚÆÌ´U÷>Þã`gx×Èőžá#Ç4X÷¸`HpÆÜʪ7íýÞl}­·úÈ,B"¢¡‡ JBP,íÐ!b$e5ÓñØœúâýôZŸv±‡8€¯H +Êkø"+K5~UÛ•}ÂGð¼0YÜ&Ÿ ê@€Þ÷êjriôÄVÝbfiYI•féV-U1 Q_ese–>$Ù&YyÌ"2BTJiÅû à(޳€Û×##lbyœ ʱhdú†4(Še ™D!COw³·×·ç™»Ê*Udª2fL·e¥Ö¥yåY™UºYïôrĸ¤VXE46L¢âCÌfÉZ-†óG5ÿ:ϳ¥Þ«ÁL &Cžäˆi1D6¦í ªúDihžêÏæ>˜>lÀmižY$¬¬¬ÃÊmV%ß-X L³óVåùÊG+vtJÛ,ÿV¦å~jIÈA.0E"äÞT pB*8<{‹FXD:aZ"ê4áÄS4”—! ü>Þ»§§æéKóT™ãŠ6óLj’ÚÆ:ÒBÍ!¶Ú1Dp$i’Vê2])mŒÓñãÞª’¡ˆcÑåör<Ý^ÝÌ®®'Í.O¼ú|EÕ¢©5°FÚ€®;áð¼|ÞØàÏòj§ÖIV¥óÒBs„ÉÏD ?k•&®k¦õÛ†“éZÀÉ8j£\¹=Œ£¥õ÷UBÉæœŸQé@•m‡Ä1â:þ;*oŠ4Û§{S&ŽùÍz@üº3˲úžVè(;PaxÄØvZ¨ì8TÍŽËÑ>"T„¾|iÛFx;@ÎIã”ǺNwŜˮy£Çº;å:zŽ¡¢y²– hÆ2ôçwG‰( +›“•¹ú˜Xñi6_mʼ€ º3ΫôI•0 ýÌí²¸ƒôЋ®@ëçÄÈ1/ßÌæ +šú¢î@œXj®\q‰ÍëÔ¦e1ˆú›{Ÿ·T-ÓuºJŠÕÖõÇ™Kà:—Æ"BžÉ¼6êxl5¨:¶ž2én~F¥yTv2/_†{*}™÷¤Š²)[®Ê鯇õHÈzìFœŸ­ÇÖ·E²þ™ä¦¤DüœZ¨p¨Ú?<`,¢§U:G垉EWå*–y±îÄg¥Jë“Už,öºÍjeÖ Lgv*ý‘gʆÿ2ß8ÓÌ“ûr ÉÚCGœ3xƒx{àôºƒQÄ =SkÛ¨îp¨Ú_ÜA 9?­Ò<*;î0H@më¨üóQe;ê›Á0ÙñÜž$Mr.jèK¾)²dÕ­GiÕDvY•ÇÉ„‘s|ŽÌꙥOfìÎì°ÝéKyˆÌÓº”Gy§/驯à®öYÍ ûf0¤,2 +†6X8›àkC7 ™ÕkŸÝ]ht¡†F!úWK³j&7€•ßÔ<ÕûÕBlÜú µL6«ª´øz$ãð«–H7Ú¾TÕüå®-è)‡ÂïݦÛMèH"Q†b‚ùÉ_nÊ3 »#àíxvw;1qóǘ…_Àwãé©Á˜ÿR!6\AØ–®ïê°mšURmÊn1"ÝW…©ç……=+×ÈõÛBU0¸ÛTzlEBÏiùï&äðWîjRZ÷»Vo˜2Ù}⺀p]è ÿî б›=ïù‡GÜpöŸouv÷W02øeïÏv†uUˆ‰3JµtßôæþçÐö|‘>endstream +endobj +2017 0 obj << +/Type /Page +/Contents 2018 0 R +/Resources 2016 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2009 0 R +>> endobj +2019 0 obj << +/D [2017 0 R /XYZ 85.0394 794.5015 null] +>> endobj +2020 0 obj << +/D [2017 0 R /XYZ 85.0394 752.1815 null] +>> endobj +2021 0 obj << +/D [2017 0 R /XYZ 85.0394 689.7995 null] +>> endobj +678 0 obj << +/D [2017 0 R /XYZ 85.0394 651.2999 null] +>> endobj +2022 0 obj << +/D [2017 0 R /XYZ 85.0394 618.4832 null] +>> endobj +2023 0 obj << +/D [2017 0 R /XYZ 85.0394 583.1153 null] +>> endobj +2024 0 obj << +/D [2017 0 R /XYZ 85.0394 517.8114 null] +>> endobj +2025 0 obj << +/D [2017 0 R /XYZ 85.0394 458.3941 null] +>> endobj +2026 0 obj << +/D [2017 0 R /XYZ 85.0394 396.012 null] +>> endobj +2027 0 obj << +/D [2017 0 R /XYZ 85.0394 145.9047 null] +>> endobj +2028 0 obj << +/D [2017 0 R /XYZ 85.0394 83.5226 null] +>> endobj +2016 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F53 1032 0 R /F55 1040 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2031 0 obj << +/Length 2089 +/Filter /FlateDecode +>> +stream +xÚÕY[sÛ¶~÷¯Ð#=¢¸À£ë¸­{N·v§¦y %ÚfB‘ŽHÙU}7ФH)N|δã –{ùv±ØÉ Ù‰%šê™Ô LÄl¾<³;Xûþˆxš8Å]ªo¯¾ùŽÉ™F:¡Éìú¶ÃK!¬™]/ÞEß"…ŽŽ.NÞœ½ŽO8;ýÏïo/ÎŽc"J¢“Ë˳‹×ç¿ÇT` bŒ£7'¿œü×Í]k|vuüþúÇ£³ëV±®ò3£Õ§£wïñl6üx„ÓJÌžà#¢5-¸`HpÆÂLqtuôS˰³j_ƒ`DYBGРdFÒBÐB£„Qfá8ùåú‡·?C€œuÀó˜&ˆ +Gv^6ÙªÌÀÕ¦n²eíN«²®VM¾^z. ”#ÆêÙpl0èÎ-Óe¶ˆç÷Ùüã_U™™w 1 Xjˆ/€dB3xÒX[ª£WN+?[-ò"³ìô”J7êÌaL ?~L‹|‘7÷d™æå{ªV~¶*308Ì7UUlMßâm¬ÀÓ’Z=¯6eõPçõ0hAR%l&À-Šh6ædöWà‰@’68Ù-ÕzÇq¾y/Þ‡Ñ};úÐŽ>µ£Çv4wˆ®§h¢ÀOÄèmdÍ‹´®YO1ð¦RR{ª–ãíG•áIo«Õ2mF8öÉZŽß½G®1'qˆôYܺßÅù i»À1XV‹l KĆz<¨÷óø-¿Žò{óÂú•/¬_}_ÝlŠìóCóê¥ öaDdzˆø0j†Ñ"_eó¦ZmFD Ž*ÈPõ§ƒªÓ×íè×ö‰@R0þ®3)Éd(÷t ©¼ôgÂh…íˆûª Úa±'ƒªNíž4Ãú™4ÂB‰ÏÉœjèÓÞŽÿŸD ‡¥„b'‘ýmð\Öù çŽzî-_X¿ê°³;ÛpÀ“K¤(–Ÿ“¡ÒSÈ0íÏÌÃÍÿ"™ý«2䨿úhíñWÌFœbÕ÷ÂtÚÖ¸1åHc³g»¥î볫ӟÏ/¯Ïß^´/Mu#}À ÞWT”ÁnKi[5÷¶lçQ½)›ôO7™– 7™CÏr·òÅ<‹ª[¿îVCýÏ|ý}ƒîï¼q“ÙÊdžA3µÕƒGi=b&D¥aƒY;G¬‹9¥ö´ì»`Qe†¹âÑÓ}VºQQ¥ ×u(g†rf€êPBD×÷yíÖ–éÇlL%"…9çTW¥CÐKªC ­ëìv]8¹·¶‚A§GÉU˜w¨zn2COTä¡…2ëw±+€hQÅt?ó¯WÛë>[º8µr£tÛè¹Q­ /;–Ê`4¦!¹˜V©èfÝ8yyãD¥ÅSºñ:,ÖË?t¡ ëzÛ 6YÙ‚Ê¿ïÕÈæv(œ4gƒœÏ@¨Æ ‹¶7f8èÝ\ê £­;©M0J, Î«2-ŠÍ1!Ęň¶ÖX&EnÂòjVù¼ßÙ% •[(²Ç¬¨ÝôÍÆý.²Ût]4†5Þ(ç™[°H˜· :á>¡PÕºy0¨2»*/ +7ºÉÜ/D÷ÂÒÚÿ–þwÞ¬SOíP6£âvfxûf3Èâ@2€l¬5 ç§½z¢Ñ¯6ÖË´\[@íSß0Q«§¼6w Ø- ~A¾åŠöíq6['àlÆËuí¯yÒ&¬¦aêÆïµÔ;Ïõçšûª[²«¢Û¾í†C)Ñ™B‰!®x{«àsÉz•š€ëÞé Ñ#‹aj®ÉtÿÌzk«Ý+=ßÐ8$pPîmºTán·}h©ŒÜx1 έˆ D#"»PIh#¤ˆ<+Ó›páµÈnÖwwhѤå%È!»[š=V;kóý¤ÍÓ¶„Ú»v ÇH³:;X×é]Ñõr™®ü…Ÿ¯p”ý™7Óˆ`s«éL:T{P T—O“¸ì¹EfGä(6]‘?­óp«kËN;Š· „+ϰT•>ŸO¢C`'dò²Ú£Ó¥šF§¥²è<î #Låt@d ÙC#Áð@äXì@Q·yÆ•Sù Ú+¨kpòœz‹i*Ž[2Uw«tùœð$Ö“ò€:T{¨¬>ì8€!F¥Þ/2ˆìõ@ +þ¬/Ò}öj‹ß®3Æoñ]©™.Īõª4¹=‰¼çBˆ¤uSOƒŠá¬‰>j‡j¨Ê‚®D/pd°ÛŸ®b:AŠP¾_±@4¢ë‰LÝÑÓìÊÞ·›ˆN™ào½aú(‚£s¿VVÍN)ðªýÃÏ/Ìï‰:Ô“³Å¤+¤DTBY¾×¢iG"ë‡|Ä:8!myW'¥¡ARz¯NfW§^³­–¹ŽéêtéšP@”CGZÕMlv{ô…(ïõ¹fÁ5¦¦vT:º¬ê:·‡½¡4ÔŽ*õíØH&(Buè· ë+¬Ÿv3–ù'uˆÔ?°À¾>‡!y5žs„•fî±Ñ¶÷„[½HÒvH»l¡NÙ~Š!-û¢š§SÚC• 8{ør¤éjkÙRW#ÎtP×d푳A#&d—s Ò“¢D´W hê»34|üú·ðW“Þ~}ç1¥&ª *„Œ½RFqâŒëojÿõzW÷¿Æ"°aendstream +endobj +2030 0 obj << +/Type /Page +/Contents 2031 0 R +/Resources 2029 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2009 0 R +>> endobj +2032 0 obj << +/D [2030 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2033 0 obj << +/D [2030 0 R /XYZ 56.6929 751.9898 null] +>> endobj +682 0 obj << +/D [2030 0 R /XYZ 56.6929 712.1227 null] +>> endobj +2034 0 obj << +/D [2030 0 R /XYZ 56.6929 678.7055 null] +>> endobj +2035 0 obj << +/D [2030 0 R /XYZ 56.6929 642.737 null] +>> endobj +2036 0 obj << +/D [2030 0 R /XYZ 56.6929 575.4649 null] +>> endobj +2037 0 obj << +/D [2030 0 R /XYZ 56.6929 435.4781 null] +>> endobj +2038 0 obj << +/D [2030 0 R /XYZ 56.6929 292.5265 null] +>> endobj +2029 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R /F55 1040 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2041 0 obj << +/Length 3061 +/Filter /FlateDecode +>> +stream +xÚÝZKwã¶ÞûWhÑ…|ÎÅ“–ŽÇ“N;ÓÚisšÉ‚–¨O$Ñ©q¦¿¾O¾)9ãENí…ð¼¸øî 3 ÿd¦ÂLó™Ô LÄl¹»À³OðìÛ âihѤúæáâ¯ï˜œi¤šÌÖ¹ÂJ‘ÙÃêçùÕ‡7woßÿt¹ Ï¿A— ñüöêîÇ«ïÝØ‡KMçWßÞÜ_.ˆL("eÈ<¿»º½y»¸þÛÍõßÿóÃÝÍå/ß]Ü·"3]#2ó×m:q!È­–…8ÐЈ+N& `O9Šu·Ÿª°ýкÿç¥ó¹NT·0`^-Üï•û)ü°Ç@o7G@Qc:f¦RVúçÁ@ÖŸ4IÔÙ@³';P "X*’ù*ÛfŸÒ*/öîÉݽûX¨h¯.ñ«³–Áü~Ø¡¢?‰«Qaz Á$v&@…‡ƒDLbцC à€ô°Á5›¿¯Ü³t[®õÚ^ õi{ô³¤«•c¶ôD}­€Á|f°¯ÑyÍÆ.­ ÜÓ¢ŒÓ~ÎU^f+»ÖáöøÑ£ÍNç`—oW'ð-ä’¼ßdßnÇ_Ú®[Z7òÛ1w•{Ëí“ie¿çeU¾éN›Gv³}G¦–ìð9ðHsO˜6Dïšf9(î×Y:‰9–\”ùã6ßÙ™„#ª8÷/ä÷'†oÅ{{}jf &BvVy™>n,›ûM‡¡ÂpDŒ>+7˜ºp£ ¯Ùá9/ý N¸fB®£HË,ˆÂ°É\·7ù´Ù¡N‰† Éÿ™÷Šþ”-«üs*A@S½-VqŽùÙ¶˜4YØpÆ8ˆpEÚ›RöÔßìê…±äï + ‘%˜ÇáÜ-šT.ê$1x¤2ì,ÖŽcèÖ”•*&<Ãëâ®ËaB]ŧ9‹T¬µb‘H´lóvÛ”¯»†ÒóãŒÌºó°6G1¦ÛÌÔEiðßšÁï@ÀúÀsŽ8n)w•ý^M"Wbh¯²uzÜVÆ7ùO Â"_©E3À?¤Ïc‘"†¥q´p YVBO ¥A5–@eÑòn- ÞŒKv.Qj8ÉZ¤à­ ‰À‰6s.Lq曆p1ƒ.fÌ?´iÈÓ±rƒ0nÜˆÜ dÆ%K°5‚êIKG<Ž cDŸ‡ ЦÈ(‚ì§´€0 aÜÍžÎP²zò¼ö€"P¤K<©qª«…µW!tïL­€ LƒuŒ;xßU¬ß¾ðz¼Le”Ä+|¶6b]ƒ¥öÔÇýÖ†hÖƒûWÇÝS9j–žÊöÕ„YÅ %š¨ŠÒ šP”@eå×aEQZEÙyÏÒRŠ‘âbš¯@4ÀWKI¨€t*é0ö!;ðì2‡åÚôiv.À‘—IzåEæÏ¹Íý ºFš:åÖi¾=†Hà ‰uü¥nîA馛0×’#%•hÆbð…ΤøïêL­uÑW ÙlÐkˆ*ÚQìžòm6¢$EëÜ4úÍP„¨VÍ ï9=ìÇÊD'}kñb¾Oj²hp=åÉp$Í È?í‹Ãh\q¦ì”3ã ©H6­£MªqTVGwC:ÊQ’p5©£ N„'ÓŒEªÎÚZ +ºÍZíÊ01‰ ÁM‡ºêÊQa°ÜG“ɘöcæ^°Û›ùA[Ë1„™š¯ýƒMæ¿cÛ©ScS²€µ´T&pªé²:…®;ñþ¸¾4ü§®-.xíRÌø(¾NuÎ ÕÈËÎOœ$FËN8¡&ÕÀ•øíÀdexàIŠÅ4c‘j€³6ÀAhškו¦Ìá75?àÐíW–Y]†(]ß•§ý«l~mΛ¦RxgSÄ$€L%/A$›@d‚ Ng"2AI¬ÕôC?Ã÷xèDZdíêÒkÙ^&‚tœOC³I5ÍHe¡¹ÿªøh’¯õùŒZŒÕ9'cÖò^’¹5¾¦oËeŒ ”ËÆ×<úÊH4¾¶rRxÂÌWP òÍ€3¾½ÂK×ø2,š‰, Æ·õæP!Ö©l]£[‡™@·Dš‹W.^+(Ò/°ìBÿÿGE ²EB˜>¡™ ª Í TV3‹Ó)>쨑RO;9GK>Í\¤஥ŸÜ”@•l³÷ïKÉ燼2†‘P„g¸Nå™ sìxsµ:ô ›kè|˜K° ±ìcŽ›¿_LI@K„æ§§V‡¼š ì8‰îb1¤-ˆÊX¨lµÛ,ö9HÃÕåÍPYÓè9a¤ãò`ópCû¸B—hÝ9hÙ™)ªâðeJs’q…É‹U^Ÿ‚7U ‚Åž¨w6©Æá©¬`Ë!xCèÍH}Y}ÙxPc¹Ù$g‘j€µv Í1ióVû¥}9CcÏŽ³åÎæ3Sþ°î}ÙCéºôÉ©vœ˜sa¾ÒQNeÓÕ’gŸ6ò õjó¥AÛ9ºq²mjJó#2¶CÆR”/Üs +¡–Iµšø}°u¦æ†mß +¥@h;%PàBK?RóÊ—xZ×x²"*–à…íñ‰KU3åËtkNÕÌУÿMýdÙSzH+?Y¹<äOV¥˜ÿ°wƒU`а´ÏýÑ7í ЈpêÈÂIœ“‘©WEæAµwEÌâ`tse^¸‘tÖˆýI|ãµjs,½9djy <ÏVyåAüª±åÔÛ—ábçôó  y¸Â4Z;[<”:¡åЇRÅâ¡Ô¾xvñbñÚ¹1eÐ(µZuñpÁtbÏ•í'ì¹rdÅyf[»‹››ôs·¶¹ËÒ½;Œ3µÌî!FpeÝÓŽ¼[65ÅäqŠ%d('Mhƒj„*kBï¿*vŸä+Æî}¾c÷c!©¾®¿©û©/½@§—YŠNf 4Ö“ÖïÇÌR´2KCpK;‘Y&¦¶úŠ™%ìüÌR’x¤ŸZÆÇSKF¸è'¯À’„#œœ@gƒhœÈb³<μԇⰠ+&®éE¯Í%ŒMr‰ú¬µð )…æà’š¼]oœ+1Ú˰ŽR¹@B%ƒÌvcJÏÆeÙË.fRwÁZù~¹=®2×YùKöØ»ô`â÷á-OFÏDŸŽ/È Æ“1¬›åAÝôþ– Л¶¹O˶¥;\*0È®.Âø»e¾Ë·é¡¾¬dîƒX×1Ž*°‰ÄÉ X5¨&p¨,°ž‡‹ÅŸVÃs‘j€»6´4is·Ü˜ †@ˆ  +ÜxÖ7 *…0å´*;§•iµÃ3âÀá/þp*ìåó`—–Uvh¹ö_Þß]ÿãÛ×ëÓc œ9Õmžçâð«?¦|ˆg‰á׿}=):Ôú#1ŸYnë#Ç|? 2ŠasiÌ·ì@=ÖCR3×™ÄɤFJ^A7&±Ù ‡f ²È|Ûýdº6tŸú^ é¯}Q²&[ß{ QÓðe‹öåªeº/ö&Dn2£˜nŸÓ/¾ hÿºšJ> endobj +2042 0 obj << +/D [2040 0 R /XYZ 85.0394 794.5015 null] +>> endobj +2039 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F55 1040 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2045 0 obj << +/Length 1826 +/Filter /FlateDecode +>> +stream +xÚÝXKoÛF¾ëWÈEÌÍ.÷}tb'u‘(®%§Ò‰’‰ðáòaÇýõå.)RZÉŠ^ +8¤†3³ß¼I¦~dÊ:ÔS©â˜ðé*›àéþ{?!Ž'蘂!×›åäõ;*§iŠér3¥VŠL—ë/³7H£3€gó‹W—gAȳ‹››«ùåõpÏ10 Ƴó»‹öÙÍ™gï¯g_—¿N®–½9C“ ¦Æ–¿&_¾âé,ÿu‚ÕŠOŸà#¢u8Í&ŒSĥݓt²˜üÖ ü۾ꃀq…xÈÄ4  )ÐïŠ I0I®‘ !í +‰¨ŽËünúúçN‘”XtÃ’ëx -•ŒL‡ì꘲w±U¥YQÕ…i@4’œ+ Òœ‡­¹Qú=W&Θj +¡jÒÚÞ{ìe%iÓii_,ìµÉ×qYÕQ¾Þ84Ó>É¢zuŸä['8ÝeRßgööOÌñí»·ö‚–ÁP¬f7EU%ßÒÖ³à®ÑaŒÇ+› +mŒÂ‰I¤f.Hþ Cö•¹¹:æ¡)‡Ø/˜µŽ7àb rŠà°‡J "¤æd $ÙæES£ÅðIJ£ƒv‰"1dåô…lpȦŽËhü»Èã<ÊÒ°GD)vZsÏåQ=N…ˆÐr¬{Ù ¹.²(É-ÝÓRmìÁµîØŒ­–ú۲ͩx}9!)ÒLÉÓÈ ¹Ž#×sÙ˜ÀaêÅNså‘VÝ1yT‘Ã@ 9ÖÝ#÷ShYKQ¬}âl ^3J +¥*Ä8±Ž¹½ZÞÝÎíËŸÏH¨gîlƒÙCÒ0ˆaèæEcÎ:h]Òª?ŒwÅ wÐ.=lªÖM™wÉë¢ þ‘Ô–‚¢R7ÕøŒ.w—­œ¢tlOq_¢LpÅu¼ªãõ.i[;‘¦J?%Õx:sGð,®®ì˟ݾŒèu½0]„,ž«:ΜïßyU”uÒd;½àC&B'‡Q$0ãÝÌu5 ;wt… +DBÖrÌ]zÚCaDb‚í<ìr- ¥¥ÆFúK\—¬!¼rÏyñP%Õ~©¡PÀ” S +uUPæÉ ûëwŸ,Cmb¾Øs Î-À/ûÚQ¢§VnTÅØÃ9‘.>Lô'Û`“¤è‘Zs§]Ëîå®=r¡a+C¡e]ÇßšmÆqúób7=µí©Ì£ +j·`¤{}“F[Ž!&Ùב{ä«CD¨Ðã¡æÕê¡©|’5RJê}É/‚ò™á“e7õòªžZx$!|•E?‚ªX}÷ÙkF"ÉÕ¾üúe'&%”î¢|ö …8 ù¼Í‹B›ªË¸}w…âÓǯv‚¦ÂÔ+E:ÙíKð¹çüáQ ûìxaé”ûcn1Úé÷Mb*‚Âr\.¯oo¯o–ןæ?Ù }c(+Ã]N&f¡`ÂLýæréj—¡Û‚ØR¶ìZÚ´¯ËùÂÎÆæ+l’Aÿ ¨Ä³‡B¯ýË4qsmCØd(m/kÓ|’oMNëÆ6x§ízñYê]»E‘»©¿]=ÛÓŒ²)Éaç‚å£Ú¶þ|ob‚œwuÙ=‚^[õÍ–ž÷$;ß'L/Fýf¢ ¶7ü~·z4ðX|·}BÁ^TßMmÿ±+˶Éâ¼®Î=^$\"ªd×Szös‰» ‚Õ+µò-6‘SíΫgn£±7P‡Íœ¸mÊ"å&GO¸‰£}Íx׫׭UÈÔsßÜ‹² j8”˜aî9jh­AøÙM{yR'QêÚiTGû.H!lbçÓM7¹üÕÄeWè'zì§6‡Ç -PˆÁ'›è€éøÑ1µ_3ؾ>Ó™&ꤾŽçPߨD))黫\d_ß<².R1tË|&´T™õÝ=N\v¬¢‡È¬æ£1Tä+µÜì>²«Ýo/&&…ûžÑ¯Úã „Ý™ËnŽ ÄQ1]FDý kj`û£ÿX¥M•<ÆÇIŽ(¸óôÙóœX"-ÏÎdŸóO(ë}¿¯Ìçú²¡çÅïyö?ð|7órd¾zzœûrò¯?®î>3SëUèwl(A ´3ÊŽ„â0h1 +),=‡¶ÿµq:endstream +endobj +2044 0 obj << +/Type /Page +/Contents 2045 0 R +/Resources 2043 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2009 0 R +>> endobj +2046 0 obj << +/D [2044 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2047 0 obj << +/D [2044 0 R /XYZ 56.6929 627.8052 null] +>> endobj +2048 0 obj << +/D [2044 0 R /XYZ 56.6929 562.9454 null] +>> endobj +2049 0 obj << +/D [2044 0 R /XYZ 56.6929 498.0856 null] +>> endobj +686 0 obj << +/D [2044 0 R /XYZ 56.6929 457.8644 null] +>> endobj +2050 0 obj << +/D [2044 0 R /XYZ 56.6929 424.2917 null] +>> endobj +2051 0 obj << +/D [2044 0 R /XYZ 56.6929 388.1677 null] +>> endobj +2052 0 obj << +/D [2044 0 R /XYZ 56.6929 320.386 null] +>> endobj +2053 0 obj << +/D [2044 0 R /XYZ 56.6929 234.5807 null] +>> endobj +2054 0 obj << +/D [2044 0 R /XYZ 56.6929 126.8791 null] +>> endobj +2043 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F55 1040 0 R /F23 738 0 R /F39 900 0 R /F41 940 0 R /F53 1032 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2057 0 obj << +/Length 2978 +/Filter /FlateDecode +>> +stream +xÚÅZmÛ8þ>¿"À}8¨]½ÛLÛÙbÛÙÞvŠ[`w?xeâ«_ÒØî´÷ëÔ‹c;N2@ \ Œe‰¢(Š|HÊ¡ ÿé"‘á©XÄ©ˆ$¡r±*¯ÈâÆÞ^QGz¢pHõêþêåO<^¤Qª˜ZÜo¼’ˆ$ ]ܯÿ®ß¿¿¹{sûû2d’¯¢e( Þ]ß}¼þÅö½_¦,¸~{ó^…à +ˆR$S$¸»~wófù×ýÏW7÷½8C‘)á(Ëç«?þ"‹5Hþó‰xšÈżˆ¦)[”WBòH +Î}Oqõáê_=ÃÁ¨™:§!“H2¡!'°ßY=‘ˆHØw ©XôÄ蜞<ê)\á>_þ¯JJ"ÆAÝĬêj“?†›¼ÐSPE#Â_ W>’¯§š—U*"DÆc ?6Ú‰8¤eH‘Äó"Nøª4R‰dŽ6k–!OeÐn56Nþ“öØí³6¯+;Š=…¶í¼jZ­-u½™L_ëMÖí »°jœQ ™z)_êvõ²ÊJ½ŽxrÅ¢$ )R "úÍÌì‚ñ(E»³¼ÀR%‚{4âz +.]5Ý~I“@Û÷v›µØí-êlW~ÐQí;ýîq2´yÕéÆMt«=ÕûO– Û´z?áÚèýß¹›íú¸ÝZG]m³êQ£ryämcÈÝÈŠ/ëÜn`ÕÖûo®«Ó¶â Ÿ™}ìê¦É¼5Œ…“(%D9EsÇøXå2Ž(𡥬wÎ&4íZï÷sî&£ä@vò$ä&ŒÄiHuúz*sHåò +@@á1`SdG'I!F+ +ùæYÁzªÉFˆÈ {Me: rt{Œ‘‚&V +”`Ó&ºC_×dÚ6×LD*ˆ¨<{l0O&ï}”7¤n̾d¶f2GE¢ãZ-صfÒ­R3ÀEK5ÃUDEÏÆ€õ)6És¹@*Rï×Íé"ŸÀád +)†\ 0œzÈDì!¡«Ì„¸4â2ö ÊUûõ9‰*‚ØýVû¸[´‡Óìjïm=qáÛ¯§¶É!ÁÐ!/c©žQ±(5꟫¿Âža8àxlÅ,²„ Ö¯‹Ûzwón*ýI•ü8ùz†çåãàÖ@0–ïÍÍ«o‡>¢8ß°qºYíó½îáóçÀ˜P4oPÿÈ›ÕKpÑhûÏgd3§À, r ìTgÀÎS°«.¦™[íºæíÕ@~V²žjF´‘s@"‰h¯]îÓÎALˆ©ˆ§"gn„Ÿßae„SÞⸯõ¨°UdŸ´íÉÖ_²ªµp +¦z…g k¾+Ñë÷wCrëL²cÍN¯r,dôúÅLö‰6J¹”}B¥ Ù·à“zç)7‘ðºEì7ÚÜÇ€‘BUYæ•vÝ[רºòÁ~awƒ´(¿íÙ9dÑUk;lȇÆêpfN}àì•èXxîÀ5²´·Û“;¦¹[­«2}Æf  †Ñ‡»Â[¿ h›]ÀwñÂ%$.ɸW¸þÜ-›È8–ûÆ‚‡Ý®Oº£ˆ^hœœwÇ!Õiw쩌;î.ºã®Þ·ÇÞH¢DÈóry¢¹Æ™‡Ä벉`¿äM««C +hŸ;½ÏµƒÆÚzù¦ñ –|ñ@u9Þn&Yüȱ¦…”¹RrðÜ D2-ÉOŸ)ÞœȸΟé€êÌ™z*s¦ÍL%' Š³Kz¢™%'µT¬¨/ùïe,‚}îo1|‚ˆm— 5¶Y Çš¯š3Y;–æJ°CÒ^wsÇHo”¯à½-è¯y{¤pJ`dÀ‚$ÃØýŒ`ÏsA}"ÜrÄxC¡Î\-Ûyx¹¦Ÿ1ɼt!ç PÎFjïñ íô ñ]%VñwÕHŠ´WÂ’3â]†ŠB"*Ü©˜r&HZI”ra\tñyB¤)·Tƒ¶ÙíA ¦ãåmÉojØÓb¸-Ï9²6ûRlxÜP¤¥  ¸¢L-ßo­+ÅýM¶mŸ +Ê,¯Šon|ãÆ*@oÝ´öÍæ¨qðêöî“ÚŽµ^r|Y2‰—¬?Ü2®ÜŒ7|³“,DÇë—õ’J7o== DÅÉáŽ_Lµ ÏÌ>6]Ûíµmïu·,ÈõÈ``ÐÇ™DòýVÆèOñB÷ðãû| tåDT<^~Æ`yÖpÂ,‰Á¯—SÄ2û6õêÓqž($jD-ú%ã’'™Š5¾‚¤ 0šäº.Šúi&¯EćòóÌ¥žH„߀/¢:_iu»1&Žb™ç}I9Þü4¿gSª¿ó*Ý6'!‘ÅPÕ¤œÿH¤ÌØl‡ÝTѹñæq–Yîk8Ù}òÒÈ@PÇZ@¹UäeÞúp0€»”{º^k«±â›ýˆ£Í7ÈgKKpýþ6²½·K´¶‰*qëìµ;·b£[·†½Å>mQO‚('4Ö–‡ÍM±ãðÕk )®—P}m[Ml¡ç0nöG ÷fåŒb×Ö{7Û]DM¥³‡>†ñ¶_<ÃógÉv¾¯«Ò”‚Hiì?U&î>U¶ÛÔÌÐÝt»¥ ›Ð¯1>x ­pEWÂ!6sç @‰b|Â?˜Î¨!Ñ îêÖäEƒTiâ?×BŸ;t\µn Û€Ïyi—µCðÝž5ô×Κ³óÃÇ>мm‹Y'2ǪQÎ'äjêL£óAÑ«‚MUÁ@ÞÀè´íñÎcðRâ_Ì#Êãø8ªp‰ ¥´¿m´Å뻓Ã~¡‚–7!lMÈ}àb$†‚1‰'æcìËäO=\anÕ6>Éjm±›Â®îRb5 +ߪþÏ™…¢†&—¾ôöT&¿jgò«4‚:<žûÐ> +„"†/ —=N°<ÕŒt#“}ó#ñ^Û“ÚßLÍgDxåÉùs~  |éoõÝï­½~ª1(ÚÏHÌ¡'6VuYÚ’^ +{'„¾cæèÍá,¼û{änÌ› +¼B&bí]ûäg î2<&:õ'.#Ág „ôiÒwÿøéðã.8W0ÝSwÛ³Ô”z¡ps”ÅSÑ%Tî2añŒìÿÎ*endstream +endobj +2056 0 obj << +/Type /Page +/Contents 2057 0 R +/Resources 2055 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2059 0 R +>> endobj +2058 0 obj << +/D [2056 0 R /XYZ 85.0394 794.5015 null] +>> endobj +2055 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F55 1040 0 R /F23 738 0 R /F53 1032 0 R /F41 940 0 R /F62 1065 0 R /F63 1068 0 R >> +/XObject << /Im2 1054 0 R /Im3 1188 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2062 0 obj << +/Length 2423 +/Filter /FlateDecode +>> +stream +xÚµYÝsÛ6÷_¡·R3Šâkúä\œœ;‰“Kœ»›iû@KpÌF"]‘²ãÿ¾»XP"%J¹^’ñŒ‰Åb±ØÝßb%&þÄDf¼ôës¦¹Ð“ùêŒO>ÂÜË3‘hfѬOõìúì§ÊN<óFšÉõm—cÜ91¹^üš=cžMÏ®Î__<ŸÎdž+“¿}{qõüò¿Ð׈€„óìõùÕ‡óW4övêevþòâýô÷ë_Î.®·âôE\¡,žýú;Ÿ,@ò_Î8SÞéÉ#t8ÞËÉê,׊é\©ndyöþì_[†½Ù¸tL¹tÌ(c' S\‹ÿe[å¢"Üø¶|2óŠå.÷ÇyÑ:¼R³[1d5s‚iïõdf¬fVônHª‰Ìk-ñŠœeÒ:9±ȼ´ñŠþƒŽ”ži“ $„5ÚÂ<çÓ™‘Ù»øÿ +þ‹ìrÛ–ÙËýr†y¸‰å–9í£®&‚¼€ËDýv<ýN+qà§Ë•š<¯áŒ“þ1ãYŸs<¦‘=CRÁew«$sÜÑ1¯ïÊLËÛ¬¾o˺¶ɚ»z³\ÐøM ï¦ i¤LTóºúcSÍ»e6{,Û;jµwôŠÛ‰ eΤ‡6)p¶!š¡˜9(A䉄„úq:S\dE’t~·®ë¶¬>âr°=å™äpþí•–•ݯëyh꬧3¡³MUáÒ8Rt3À[2[Ô¡©~hi8TwE5ÔiÂ|CÊö‰†ðÜø]ÕMZÑ<5mX5?COñN hÔ$yÿã˜S xSgœ[™@gýk.áŸQx¾Î¹Hôñ6­Îá7Îe¯ ºÅrYã®qÚ zpx«ì¤Ûƒ©ƒèÄå2| iq[ÓdhæÅ=pfQ +«.+Úå’í»Fnàw“¾£~ï+pjã!Îvñëë"˜sÎúì„´~À@ÌÑÀÅé3J1‚ +[ª¾?hÝ÷Áœ×*]/8áz_{^²Ü;3éïx WG4"—êíæ-Ë­ß“ë}h7eô}‰wO2öWå’Yà¾'ãki˜¾ žÅm T‘å¼^Ý/CôçØ¿_'sK[Ö÷a]`hbY³™ßÑE•Í×Sá²P´S‘%>à‹õüS€6µwEKË–%xi•¸WdÀN³<‡“ x +Àï}½n›óípÆp°^ŒßÁˆ˜r§ õÀ¶KŽá`î¥dÆb˜3œî­´&Å}Âë”>{¼ ÕˆÕ²äÂç_¶Zå¤ë% ȲK°ç(»Ñ=¦IÉ$ `8¶,0¦ë¨H0–íø ó~v¿ŠNî踔CCŽ, õ°æ6kJÊË8ÂE4쇲Þ4D¼·_] „á‚*æz˜OvIu£ñ¢›@ýuh‹2¦U‘CD±CkàÃëk"€žLâ¼<\‡òǤ~ÿJTøî’; åF¥»ÓùQG}êa_-âLxÛcu°_Gs¸_ßk,"î÷. ÜðÇX‰‡°nè½j³º!;ã²°>—íÁv§Îáíe…Ô_PMê„n:ª¨œ(Ç2k„:½eG4²å@=r¥nùêçfS.S“B ¦uCƒ\0ññ´wD'ô—ˆ¢ú>¥ÞœYȽ»—X1¿ ³[û¢Ác€I Þ{J¶-Ñ¡pj€´Y•7é^ÕERÍ¢h jÝÆ”·^¤ã`ÌÆæfTî½í ìfLwIJŠO»þ}ÆÕé¶n÷æá¶Ø,“<”á‹SG³c€y&¸ù6Ù±µ›¹¿S#Š+Ž—ˆ$À4Ö~!5VX"â`<ßµD¤‹ñöÛ—ˆúœO$Ë܃^ò^…Hé]…Û«˜7DzôR5‹ð‹Å",_:8qšÚrÁ\‡Z·i¦ Ä‹ª 8úìòê9µ<}„óS@õ°ÄGa3V\¡(b]¶J–؉E,ø®Ã*B>qI”˜dP¢¨>vƒ±Èe]Wøݴ›õ–É2M ¤òR÷ ê«Lô;àtÏê9s û²gõ]¤”X¥”̼¿|yuþêýH0›€G¾¥wã%êOB:ÃÔž÷¶Ïy ûJ@*÷±*0IÃÉmáQ&£ÂÁ›´2U eª@ÉXliƒ%­¡Ø3˜ø6a pôs’´ +‚±•®Ë’×Õb>V±°ƒè˜ˆv¢J„6Ü´¡X…-u*|µœÄ­>ÕqàÚR¥ëøç‡·5!˸âô¶ÑȶHâ’q ÏýÁ¾/ê¨øy‚„JT‡Ynñê3èN¦6ÏŽ« +@IaEó´ªzT'TÕQ%U]^]#H¥Œ®/Þ½>Àsx¿zgóÓ’l©FD¨OCÌ6à‹CYî6 8õcuZIpS9ÀÆâ`¨æ]`}¥7[(î”Þ„jAÕ°˜]=¥YØ&åd;×ÃÝëq)b»LD›j[Xf[¿êE  +DtŠRļ¹zqùòûsTúõ囫Q#)æº{^îÎm¼©Å X©œqÐr—øÔŠúqCá_l*Ñe|Ëå„H0ÖÖ55¨ù™fÛ4¸Í|]ÞtkªnÞKj£>ñÖ8‚>R¦²fès¹ß B›çøêÄø•Šøfˆh墫?–=K‰Ç¸è½f9&ót|ÂO¤öô9_¬ÊªlZPG®õ]¸M²W#¿.ªM±Q®0sEsìÚ¹œ)”s¾µ”¯þur÷ëknáuëä¸ïÓ0?8%¡Ppx˜FI·‘#²ÿ’Cþendstream endobj 2061 0 obj << /Type /Page @@ -9184,328 +9175,444 @@ endobj /D [2061 0 R /XYZ 56.6929 794.5015 null] >> endobj 2064 0 obj << -/D [2061 0 R /XYZ 56.6929 420.5648 null] ->> endobj -2060 0 obj << -/Font << /F37 799 0 R /F23 734 0 R /F41 935 0 R /F21 710 0 R /F53 1027 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2067 0 obj << -/Length 2757 -/Filter /FlateDecode ->> -stream -xÚ½Z[oÛ¸~ϯðÛq€†Ë«H>fÑlÑE·èi¼ÀÝ<(¶’•%×’“fý^­»“ö`Q ¢¨19œËÇoȆd¡ÂLó…Ô LÄb½=Ë{øöîŒx™‹ tÑ–úuuöËoL.4Ò M«»ÖX -a¥Èbµù²¼üôéêãÛ÷_P—¿¢ó ñòË^~p}ŸÎ5]^¾»º†WÊYB¹/?^ÿùéíå¹äËÕÕùÍê÷³«UT«­:ÁÌèôíìË ^l`¿ŸaÄ´‹'xÁˆhMÛ3.œ±ÐSœ]Ÿý7Øúj:f -.”'‹ ÁãtÂ`a¸f:Ú‹’1{y!c®u‘Öµ³‹m–é6ë/œ„älÑ} BêÀZ:#!DÒQâz—­ó»g§Fó¹Æ&»KEÓRœÄ^¾¿s}ee4ýå7Ñ™€1¤uJ—g¥:j0Š˜“;©Ü[ 6zü1Í6oN*ãšy=ªC‚$¬Òÿþ㈄ -õ"hlÞ£+$NN¸½%5ã÷ eflšÂ/:[Wå¦8ìȹäóD©ºQˆS¥º:ýŽ…754ަ6½ùÖw7•{ù£íáË»jïºöçD-aö¹©»ò·þ÷éf“m ‚¨ËU˜ë1-Ùˆ©âHS­½{ʪÌF|Hø/ô”…u]dé~bU0Êâ‚1XÂЇwÉd$‰€ô—óaÐšŽ‚ dfüšù¤³iÂaŸ5CHøÎ©d†jt€"ATWë˜xÆyÊä]Ú¸Vj -Ãn“6á{ê\î…+÷¼õï«ë÷ï.êü¾Ì6þ§u^Þ‡GÝ àE•TÞ“`oø¼mÒ_ &ˆR"`—æ{³w çeŽ5ìK°Sx/» j4èx‡hD© -ŒÍÃiÅ´UÛmZnœ×ªÇl¿Ï7™G¥´ô~nA›ÿEÙC¸ÎxE^úîǿƱLc5«S*Õw+“”v´ê{•9¯ -4’J½ÐÎ%ÜŽîdË¿±À©‰OD| ›Xݸ.³ýÙÆX@±^@½qè–DJSÙE¿ê®‡P&Î@ 2í}%ȉÌnKÍø?H 3{¿¯³fèÛñž›£Âƒ°0ŒÎ+¥F´í†¤²\tÕíFe$l’Ð2ùnžC÷{ùnúB˜¶õ‰Ïÿ ½YŒ¤8Ð,@r°Ç º‘6U’z32Χ "¦´iÈMÚåe“íˬ1±K —u}ت:•˜!i¸Â|B´¤f"H ñ§‚`ضg•R#ÚöQ誻z0ã8lhíôà8¤‡ùž¶ÅÚÙqì=f‡ù©ÉóÍf„iœÈ¨e±/Êþ‚Œ ݺà_K …(çÌnµw¿Åй 1{‘/Jä_Hž`Ägó Ò–šN(õ³ âäÒ&Eh 8Õ âLœÐ¿ë¬lÒ&¯üÖÝíF8©êsÒÿøp$D!ØD7?ûyóßå$ê3EœšGý¶Ô4êG)3½;x -ÇÀEÛÐošâfÿ¿7€/~¸¹é/ƒQS8ãëˆR# édì¶X“ÞJÞZíë^¥ÿ’C‚úXô² ÔÆƒœ×E¸;+ƒ&”Ó®çGÙl±˜JõQÂØ)fD’“[Ÿˆ·I ÔG.ò«Ç|㘠- š ¼½°"³£Òp~ Ÿo;bÛêÑ\3ÌýÁ53ùêØ‘{‹Xe#]@¹Ò…œsòtj‚ÊiÌÕ;eåéP}ØíŠÜ) œq½4Fã¸I7Řù1â´k~£ø}é,yc<·Œ´Ò¹CØóãê),ÙݸÃ΀Öm^äÍó9ŸÆ€Y©“ÇOm©\ R}\I7› P‰÷4¯§”‰æb^ý(5¢ŸR&R¨î.7&t™t”eödb$êÍç~¥eúÜ¢iÙ Ã4NÔZh™bóqC$Ò,2Ö—>üß+­ <éÎɘ£Š…§'Jü¶ÔtÌE)G£«§ÁÝ6\Íì¬QjdÚîy=G,Ñ´;ïÛ¼Þé³ÉN™xnõaï‚¢l\Ç6«ëô>3i­d)P‹¼t` -_Ý]tõCg ‰ZÃþÈb4ŽHðÒ½1y¹ÎŽ£ºMÉ OoK*ÒPñ™®AÍ!¦úD Ú–šñ`räÜE_×ƒÆæNmvÖ(52m׃x0ìŒy¯³rS÷¯Œ:îƒネûyÝ…eãšÇ´ˆòöæÎô›Ý̹YØãó¸-Òòëñ:jÚÔX¢ãSÉÒ’š1ury^?eû±\•Èùy£ÔÈÄcSŠ’Du'neKÛÜ^ŸpÁ8f "MÁqê¯DÚRÓ¶ˆRϲÛÃýÐ )àGóÓF©‘y»q§Â€Ú‰WçÀ;û²{kiÕ¹‡ˆAáBÉ„™)4â’¹ýQãmx›p#Ìí:­X«³m¾®Š0ü±Nò£ ujtdZ”ÅÛÝw`¨ãMü-ÏÕ_—|úpu=²C€$p|Š9Ç6 ¡àÞî -wÿMa=ÀjÜ é¶Óc{ÿf™SÃÃfXÖžw §æ©ã=Ѻ:7…»X§ËCùwåN†ÖÙ¾q}Î2ЈEŒUl„ÿ‚èñ`ÉÎ@˜( 5!íÕ„Þhmår˜cƒ;*Y~¬šÜa¹w$2ü%4òrwðÛ­z¡ËbÙ–×½øý§vo©gŸk [R))Â9´êª?yê¤ïÝ;»4<~5æ/âë‘0«#r¦‘èhþd!_»—6µ {bV÷@7âʶ´l?üCýcè¼¹ev4õ÷qL óGm#P€cJüôßÎÿFKà%jªÆÀF˜&A)cgà$}ÕSH(€ž¡îÿbÚÏendstream -endobj -2066 0 obj << -/Type /Page -/Contents 2067 0 R -/Resources 2065 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 2059 0 R ->> endobj -2068 0 obj << -/D [2066 0 R /XYZ 85.0394 794.5015 null] ->> endobj -2069 0 obj << -/D [2066 0 R /XYZ 85.0394 108.4894 null] +/D [2061 0 R /XYZ 56.6929 243.4864 null] >> endobj 2065 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F53 1027 0 R /F41 935 0 R >> +/D [2061 0 R /XYZ 56.6929 96.2114 null] +>> endobj +2060 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F62 1065 0 R /F41 940 0 R /F21 714 0 R /F55 1040 0 R /F53 1032 0 R /F63 1068 0 R /F39 900 0 R >> +/XObject << /Im3 1188 0 R /Im2 1054 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2072 0 obj << -/Length 1863 +2068 0 obj << +/Length 2295 /Filter /FlateDecode >> stream -xÚíXK“Û6¾ëW¨*©2„ñà¼l•<3v&±g½–²•-Ç I,S¤,Pëß§)RâHÉæšR•4ýBlLáÇÆAH˜Çã(öI@Y0N7#:^ÁØÛs<^Ãäu¹^/F¯Þˆh“8äáx±ì`IB¥dãEöiòš0F¦A'ïn§÷eìOf>Ü?Þ=üý€pP:y?{üuöi¦1ŸÌÞÞϧŸ?î­8]‘F–¯£OŸé8ÉQ"bŒŸ¡C ‹c>ÞŒü@À¢¡£ùè?-`gÔNT£„‹èÀgC:ð#Fêà‡©ÂîJ½ßfI­Ì†ÕÅÄAÀ-Ë¿Å1Øv¦ -Õ´«"[Wº&ê{²ÙФÕf}0öX’eNõ<Œ$CŸÒÔ~XÄ #ì‚ÄZ•™~õ†‹Ž€YPÐ*¨Ó0ÏÊÃÂ@›ÏnÊäD¥•ýfÚùd ];:¸[3à<ì ~2p?”°BæxÊÎJüd%jT†xÎëõf> s‚:Xk$tteû¹n­ˆ‚ÑÉb­ËÏ!áTHC[' „[?YrÀÆbáåwPg<ÓÕ€Sf¨wÖ0==1ÌŸwÍíNíÔWÇþ=«6I^º^ž~)“ê©ñ¯ºåÆ©_Þ>ÎÞß;·«6êÌtÿ¿—ú– …°WküÿºÏu^Û‘`bt›×yU"ãJÕ[u3×ìyµÚ} ®ð›®Uú¥™‘ÔÈsÇ6I·Sº‰Îݪ½m¤n‰³82¬ÕÒᘠ³+¶ƒ–µqÀ9¨}ã´ÂŸ<° îÉ3œŒ7Ѓ̎›rc[Ón´§t„e’ÚÂVÂLŒÙè ZY¥Z妪﹮Ýb -„Îðâ®$Ä`í¾¿M,ú”©ªßwÊE‚³ ´ž×ÊØY2·Aٺ଑MÊvÉ4)QvÓ®Êß)yÚ šÜâVR_TåÊÓu¾U®†Bg7ÝÀÍbX¤4ßhòñÍ-œ>QjCN€ú4„Í^׎V9«O¤™4c§o1„ÊšÚÒNó’]È8“Í—Nž.¨>AÅ®UÁ¶ÉW6Òp…ÎÆLÊ0蓲f̹—I‚:;õîq>¿¿Åv^â è†"@¢ > &EQ=#É -¤ûÃëä›BÊÇó‡·7-ú/÷ÿse†ÄÇvÁ“$&ïºLÃÆí.0ÕDDpŠ}óðn ²a$b,û~L„ˆâ*dòº\XˆÈB¤å2«¾RuújY¤ø!^.O`f_\– å:¡—]YfAØ—a¯›SÏêÝœ•™*ë|éεL-“}Q»“Ò%Ú$Ó—4Æ$‰ ®¼¢±×5\FÚ_ЖÌï2’8ŠBÀ¶ÙƱ]$ŸÄ’ Ç`·p‰õÓê -ùÑhóÇ Ÿé ögÅÙãQy‚#"à ¸&P#1ù¢§ÖàTÆ!e]4GËunžûp& ¾ý¾Až­¼ÐG§PeZÙ”i{ö܃ïOïg·Þû»{FNÛH1T]ÂSãq¥†¢ÉÆ•*m5ÕOC¾&¤$jª‹®ÖazÙӦ풣mwù7WšöœMpBEà_´GËtf¾«Aj¦,”=‹´žÆâ®§™^µÄïÑÓLÏzšiô<ÍžÜÀO;=/<&á:ÊEÜ?7æ÷÷è´³wóW´܆±È²›c‰ðç@OP{£Ó“~pì™Ò¢3‡i§ vsÌÐY»•›«uå\|ýëÛùõma¡óÉÎiÓb.Ì¡a˲¸¹øeû2Kʺpƒº®™l¹ßzÊ&϶µÚ&;¬b¡¥‡ú¦šÊ*WW9šÉAìªM¹[Úâè6Á@{¹²Ô½Æ„eV]–åwóª±ÈŸvÉÎe)W¬›²V7 í°­«Õ.Ù®óÔ¥À­Ñáz¢%°bƦ¹7¦ë¤\¹CÕnß`ïëý±ºo‚ЫùDøac5Ÿ?¢}ä§pÓÚ•YÚl -"=änê±ÍNg†IèÇ!& 3oµœG/Ô¸ª¬­˜U„}y}¸èc(ÊüPV[ëÓŒ" yËPŒ# ‰x -É! }1ûw.<9¦ã¾ÍMõ“÷„[ºj -‰bÙ¤Vs L•y@Ø™ˆóK¾$”`)dÿÜ §ÈýllŠÂ|å-óB À†‰áŸÂ~¹ - Áù¦ÉitŠ©¯b ÂDnrø âvÑ!t"ôp[íê`¤(•ŸºÁ!)JV*©9àÕh4úñuƒ#~bŒ«X/ÂX³€‹`‘îŽøâÖ> ¢Yy¢ÕêýõÑ»*\Ä,6Ò,®o¼"Æ£H,®³ïË“Ë˳‹Óó¿¯dÀ—ïÙñ*à|ùåäâÛÉgœ»<ŽåòäÓÙ†R+D‚[:×ëo—§'Ç¡^^Ÿÿ¸þýèìºk(ºàÊÊôçÑ÷|‘Á ~?âLÅQ°x„g"Žåbw¤Å­”ŸÙ­þÚ3¬º­sªTÄ‚H†3ºbNAÌŒ’Êé¢Lvyf¯Äj@¬à\H8ÁRå&¯‹¶±Ú‘Ëv“ã=dH¦…iG·Kšû9¾.DõøœËmŽœÓúXDË@>©ê¶èv‡c5SÚHb£/¢HãÍ¡Ër(­Ê¦ÛgYê™ +˜Œ$Âʨ÷™b¦8õ 0`¤ ±wúÖ)R\¬±3¤íÚb[´Osjâ“ z*«}S4S°0P˜)ˆn% ‹„Œç°B€à2ÐÐÒ†,Òæê³žj|sŠü¾Ê~øÞiß»Ãο±YUã!Ý=yQ‚ƒpŸ +¿ovIúëûܪ3ÿµÉÓ:ogÊð>ý ÷3'€ñ¢(ô…p¾-¶sx ¤dý•Ú–+‚—ÆPÞR„a5ß»¼êÚ·óîfxƒGF&ðD—í_æ +ÕsÑ”ký® ÖºÈ›¹ÆS®W?åZ'eVí²üaŽ©fæPÄ÷L|ÏÚÄZüÇ,Š(!PS˜àƒáôlýáêüòúüëÅL!6†’aÜOaHZkÿ¾°#¸/ý•~Ð6ÝÍ®h±ˆvá£:ß|´CQôÏ.oZâ˜P›å6Í–ž½+K¡…ì#…2ã3l¬fHˆ¼~„†'³ÕtÉqî1ýd»­íÁF‘H Ôô¶ãð½ŸM+×fŽ”jzX¼!¢$Ëœ¼Ðu©Hpß®zð ƒwÝMzHÿX´ëÆnzç’Š«Ìa”gE[”w8Àò6ø­ª/K­!kyèF^Û·ùsÌXŠÄ¤ì«Å6)Êgd͸އ‹cÇgÈõq¼CÅåþMàù£ðý†‘ÖûY¯uÖß)‚²-B—ý;°i”tl[ì%þ4;èÊ |Áu3ïv`ï†ÆØâÄC‘ÌDˆˆ ¸}-D Kj¢3lNûp‰=rNìÓÓÌöËŠ¤¿!Á­ÁsZ„Ç­kAs¤‡•TšE€ûÈÆTˆ8õY7$>û€*R2¶u9ª|‡Ù¯IÛáTïòD´ÉØ nhe[5í¬±\­‚xÆÜ‡ÙAÙI²*ôV…ÉŠá¡ ÷Ágלê{~|vÂ]uî#T¸‘Ño2±‘±G}|Ë;!+lohlC…§‰†ª&[Kq&…Qc²alC—‡P]ö!¦åáÒR p²Åi§rí?¤À’eðÚ³K ¬±?‚BËÞA¡[ÂV,‹ Ø>Hi÷)Å­w¹ürqòå »ŽÎùT·#1¤c|Ö_OÞÔ¦÷“™jÆvû4«¹/† ð©¶ÚãW)@ äÞçñ‘íb&£7™^©èÀ:¯~ZÞ‘å7ÝWeÖžŽIáv’“ pšWEê0ÙÜVõŽžåJ‚Ã߸Tà7ä>¼ì' ì4oz¼¥XO†0¼K²|ÞífÄd¿-<ÕòâÁì~Ñì¤,Œ³ðcdaú:tu:gd Oì¾ óFƽ`d o›7Å7–ž5)¡òß²b +{˜ÇWgï;ÌÉÁÄ~„‹sTPåò×ݘL;x3ÚòÎØgI8ÔcxŠCMÙ$)9N 8QÜ•IÛÊâœËé¶ã0 +Z¬ÝlÏ¡´IV(HѳcÛéK97°¥œc9=TÊ´9ðž0¸^ŸÂèx” B=ÁœkŸö´ +á“ÖÅMN .üBåjÃH8ér€Ýµ¡Mp¾ýÀñ“ôK‡Ì²Ö–5ÔÓÄÚE ÍÊX‰9´sÇCQöi½^¹«»‘-n•‘£S`ÚbÜ”œjßâm“$(Æ¢¥«ˆ>Á¦ÙPX;ûtã·Su”Tn8&˜9±|µí}Y=gôܹJà1c?oÍ<›yï¶ÿó¿(‡‹tÈTÉùy6o+p./”U<¼Ã§¢÷ÿ·<—ý?=¯±endstream endobj -2071 0 obj << +2067 0 obj << /Type /Page -/Contents 2072 0 R -/Resources 2070 0 R +/Contents 2068 0 R +/Resources 2066 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2059 0 R >> endobj -2073 0 obj << -/D [2071 0 R /XYZ 56.6929 794.5015 null] ->> endobj -2074 0 obj << -/D [2071 0 R /XYZ 56.6929 479.6712 null] ->> endobj -2075 0 obj << -/D [2071 0 R /XYZ 56.6929 343.3873 null] ->> endobj -2076 0 obj << -/D [2071 0 R /XYZ 56.6929 280.1555 null] ->> endobj -690 0 obj << -/D [2071 0 R /XYZ 56.6929 229.1103 null] ->> endobj -2077 0 obj << -/D [2071 0 R /XYZ 56.6929 196.0344 null] ->> endobj -2078 0 obj << -/D [2071 0 R /XYZ 56.6929 160.4072 null] ->> endobj -2079 0 obj << -/D [2071 0 R /XYZ 56.6929 94.2535 null] +2069 0 obj << +/D [2067 0 R /XYZ 85.0394 794.5015 null] >> endobj 2070 0 obj << -/Font << /F37 799 0 R /F41 935 0 R /F23 734 0 R /F21 710 0 R /F48 950 0 R /F14 737 0 R /F53 1027 0 R >> +/D [2067 0 R /XYZ 85.0394 691.7632 null] +>> endobj +2071 0 obj << +/D [2067 0 R /XYZ 85.0394 587.392 null] +>> endobj +2072 0 obj << +/D [2067 0 R /XYZ 85.0394 513.3346 null] +>> endobj +690 0 obj << +/D [2067 0 R /XYZ 85.0394 475.0295 null] +>> endobj +2073 0 obj << +/D [2067 0 R /XYZ 85.0394 438.8551 null] +>> endobj +2074 0 obj << +/D [2067 0 R /XYZ 85.0394 407.0157 null] +>> endobj +2075 0 obj << +/D [2067 0 R /XYZ 85.0394 341.9916 null] +>> endobj +2076 0 obj << +/D [2067 0 R /XYZ 85.0394 270.8991 null] +>> endobj +2066 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F39 900 0 R /F53 1032 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2082 0 obj << -/Length 3151 +2079 0 obj << +/Length 3927 /Filter /FlateDecode >> stream -xÚ­]sÛ6òÝ¿Bo•g"ßÓ$í¹Ó¤¹Ú½¹™^h‰²8¡HW¤ìó¿¿]| EÉéµã\,Åb¿WlAá-Œ"TX¹È¬$Š2µXï¯èâæ~¸bg‘V)ÖwwWß~/²…%Vs½¸Û&kBa‹»ÍoË·Ÿ?øôþæß×+®èò;r½R”.?¾ýôëÛŸ<ìóµåË·?|¸…Wi¬$ÆOÓå/ŸÞ¿»þýîÇ«w=9)ÉŒ -¤å«ß~§‹ Pþã%µx†J˜µ|±¿’J%…ˆêêöêŸý‚ɬûtŽJ¢ ÏfxÀÙèµJñ”%Zpá˜ðþÃí»_n>ßÝüü Oã¾øF+nˆÌwȇz³X"Áâœ(& `#Òº©»Ã53˦joT-»]áÍcqÈ»²©ÃëÖ?sÿ¨ó}Àk‹ÃSq¸ÎԘͭZÞtaâ+´Å¦HV>¥šK ìÒžyš™3<α+«²{‰‹æa»ç<ìóèôTnЇ”ñ U|wóé=î³”(EùbÕ3y‡+U‘·E §’Â,o¶3Ä+JŒä‘øsD˜Èð‰´Hzj¾8ú@jŸËnçÁuã!ëf¿ÏëVe]xpóˆ–hþ™;jŽû¢îÚ7×+AaùÎðx(ðü£Ý5‡0Ûa—ÃKXnë9’IÂÕ‘!^ý¼T€–Á¥>Â÷Žrx t¶þÍS ƒ=ÊË*¿¯Âë@ÿ»<XzrFÈA¿À`\â81ÑËø~¬ËuÞ¡$ -TÏo9BE¦ƒ<#(ȳ7ý(÷»wŸ=>(N]¬»òš-›˜.i_Ö›²~ð˜gÜçGØ©î› yÈ‘àEIËMùPvyåUª-ê¼;z±t)Åò¦ö˜žÙ€µ>¾W¸£eËç]¹Þù™c[œÜ?ÚAÜÛ½kÿÞùw4‡ø,ò¸DQ;Té,$¼LÁ ÊHSÃii—w»HQb£Zw :Ö·»Û›Vm÷R¹¥Ì”¶E t74ƒÕÀOöÇ¢íÂq¦ÇB¯³^è3¹ü¦M¿oA~ -¤Nø¶ªFMH÷wÐzñCmwKŽìÁz—O*ÿ²?¶ó>ZóhZî_‚Ið/ÅËÔƒs“Ë4[€s Ô2ö5>œkÐÏyðU¿â*]Ò»ç‘>€×°TÚaggÛå_êæ¹o& ˆÞR.ç¬:'b´R_eåð(–EÍuו{Sì½B?Rÿ‡Rþpì]9Ì!Ä[dËMч½w4Þ5ÏîçÝB]¾îpÐB D/@ †]ƒ€ûñ³wÔ8Ý+©×äpŒ±"G߀×îep_Ç*LQ2#“à $R -Â7n±Ÿ]Ät{RB„— -¬g™™YÒ*ÅŠñÚiÌÚcᾫ{O\gb&1VESÚ6ÇúXå›Í¡hÛ)… vלÚË$öX34Ž£(E4å|Lä¯mˆÊÔH¶(‘R«³TN–µFeÑ?8§Ç¢såî{Ïuá'p!o]¦7e€>a‰í k5„‰"!ÀI#Ç‚ôñXuåcŒ?ʺíòz]´i´æQþ»>²‰š›W•×ÔÝ®sþÝ·m0SóØ©Žß|~’“@:,’ð¡ ¼(|Ä3'£23ÄfT^–Ñ뼌öXNF×s2J!djȶåÃj[Vʼn€jF(—â2}=Ö #ÕšP -b4¢p^@1%Ð ó³$NÖÕàf2‘Nfƒ$1;c#m$ŽQjÀ²ú¼wfÅðù¦Øæ doüÆr\Q¸™ŒE*¿-ºõ·hÌ Ò;§F‚h£y@?/ RñŠ0$X„!b9aøòªÁ{ïÖ»"|”Ÿ¢‚7ïŠ}Èw­¯ó¤Ë‚¬¬üµk`?Sv|ëc³/Ì`ö…ñAÉiˆn¤W²ed¢t9£ -ËGnQ,ðàF}•`.)D¤½Ué2Oxó$Å(Ê$5!„bMË,Ö0¶k\ªgxHÀÓ(ÕPN˜œÈ°d«!Œ‡\­ÊAácà4‰qF•œô’ÐèLÁO@f#Å+,„¤@‹lPùiC“,†FS•d’hªÎ볌Ê+4ź ÏËéóã« 'ÚÌ±Ž¨.Ó‘fèé2‡ ’ë a·E=[±‹Q®«k¹(87µÜ‘õ¥›k|kšHíôà:‘p…W7²ß‚èEêúzôLÁ·}>¯wöz)C?Æ^¹ÞëÂõF,w½ÿšniÁpR4œ—¶ŒH3[Žx ³ÔØñ–ê¡z -šyßD¬š‡HFÎ2k Á$,w‘ )Öy&ôXŽ /ó2.›7S«aL‚cÎøˆ®¿T«éW<=Ä„4 ¨¢Üœê %F3~™q=Ö çÆUbg@wýÕ]žŽMôqØHÛ”nRuž›œB¼È„úû¸Ù¯8ÃÍ‘ŠCt’Q8ë ;O‚x¢¬ŽñöÖ«õ~€SÓ@oÚɬâD0›g€$Òù÷±¦_ñÖ˜eÂüyÖ„:(ü>ŠE¨ "C­£KGPhh58u ‘3cù¸ŠÜ†òœJ ãîÕ{5*o»÷î*¡k¦$Fq€±ñaòµLlµZî!¾ËÂŽOyUnzw­‚§Á®àz] o^ îÃ"„BXtzÙÂ*Â4çç/+YZ˜lÁˆ¯æ/_v¿â*]òô²ø:Í35ì|ö²!H\ý(ärQ…àé±X—(ñÅæÍ\‹­ÜW´å.ùhׯe.(¤è1š/>±ôå6êjëøpù%bȇc¼~|úð’²!d¥£ˆ_]ëcÀ¥#ÜûÂ7Å` ŒÊÞ„6£€bÚ¿ñ ƒôù U¡*“˜_c~ÒØõ-Ú~ÂË©í[ÄÂyè:Ûg}6¿òÙ6öÓblCîoUÒ­Z±¦Õ\# u}q½üÔ¸™Ú¾imb·ÝÎØA˜íC\Ðå¥ÛfÒ6ÎzbsC•à!…G"š°” ñ¤I9iíœFg³Ádì -D1À†¥`Ôÿ0`R‡=yÛ&-Æbºî»ü)€Šº8äaãØíÑeÈXžÁÄŲ*X™¶%}«"=jª|ï>’± !]åâ±*ÜË»›@rV€¦-J˜¼™Ët˜ÂzæŸH߼‹ m!nõ€·›}Y—`®ó.ä—bxY¯Ãgóú,óL -v23 -çø ¢QÏœ’5ÊúÚËWekèžšc7ÓЋ‰?¥kí„™]Q=†Ö w%³Ý°Ñ`Á©‰MŸ?Ý|¼¹s?Â}ÃçÿýLržPDJ¥ò¥èF?‡è[ÓvçH?Ò¼x’ ™ÙDYËûß™ŸÆXü”˜ü4†1Û"ké˜M¤ÂµËŠÖÛPx&? p­x9 Ïç<ºH:؈¦ fF¶‰ÛqŒïÞ0s,è̔̕…øRéKž€¼B|lg)ó7„wa½Õ° ó÷#º0„¬ZÄ]/…v¼Ï“U€ã[Zq;ðêÔì0 ñ‡ ¶ØéHïï¶xlaá/-ªrP6J`ojcid]ႆöÙÜãÐ^Ì×"h¯ŽùGsÃ%ö ŸÏ§…”H€.¢ L°“x0þ¼î”öÿ…Á ‰endstream +xÚ¥ÙrÜ6ò]_¡·¥*šysb;ëdíx-¹²»Ž8ŽÄõ 9rlË©üûöðe9µå’šFßÝ :àŸ:·I˜ä:?Oó8´‘²çåþ,:¿†µÏ”À¬Ðj õýÕÙ£g&=ÏÃ<ÑÉùÕv„+ £,SçW›·Á÷¡ŠÂ @//ß¼zòø"ƒ«§+­c“_½zúòÉóÁ³ £(xñøå›Çÿà¹W¹ÿøôòâÝÕOgO¯ÞÔå sy9 6ÕoQ¤¦" ê†_?ûZE1.~iÊŠ'[8Α‡žLÁWðù‘Ë2:÷LGq8ìêòB½ãÉõnÇM/ãÑ¢é™úÖ³¸ÖüŽY†|¾å•®ÚUeÏcæ~†»ÁNz¡=k”?Ϙÿ~¬ˆÀëf<¦÷¼ò´jä­¬6}]ÂQšk¡¯ †gŽg¬*±NƒgÀŒÉÁØFë¦ë `4°Ç•Ý©î‹õ®B ļ)H)MdÒ$¼ØW{  ãçíi'`kAPl6Õ†‡ÀARýxl*:[‰ÓLtÿQÕ—PÝ7aÙ6Û[É5Ø–µßµ‚û¦èycâN‘ÑŽš4 šöD î *ƒ²hxPt][²”ð‘©Ü ÒLeˆ«]U²&ôüLÌ",È, RÆÇ0œ!~þJ 7ÆÕu<Ñn'@ã®N 4é0)ð¢®27T"z#üž:R²aãh¬HmC~8 `õ·2ü§Ü»UÇ£ÃiFDcÖ;i¯Åá†]‘ ºB'Þz²%ÿÜÝщ3†à‚Ö:бeÀ`êzöYkq~]ß2[ÅçÕÎ×ñÏÏOÿÍð T2ð2ìç¶;aZßÞã«ÍÄW³ßÄtîù¡è ”nÚJ¼pÓö<`â‹Í‚y­ ÅÇ(™*ÈÃf–u‰qf‰þXEÁ——+‰›Ypôsu\Wl2#†±A¥*vÝVn‹•ÊBc£üA>Ø["$‰.êÈiÈìä&cp½º]@¨l¨âÔ!dï8âth“Ôñ~õþa,P‰0ÔyíÝÿ‡zS ÓJwSxõÄ…±GÁu Fn±EÁuÕTGòAQð¤˜2LÌ5W·âùWJ§¡5éÌÞ #y<¹õ Ç——<ÙИ7úýTu}G±CAôݧ]ÏëýíA )]€œãwpSu²ÂÜêøaäð°?õ§b·»]roÕ§rnìC…j™ªà× kr­:½O28¸û’ cŒDj"Èo-7Œâ8þ*ÃMãØ!tVÚ dÒ`¬N3Ö\ß²öìg¯až³“]íä ä·_˶à·õn‘<f±qäav”ZH.ÚNvO$AêÆ4Óa®ôÔc 2Z;¥Ö¨mû @~d¹ó(?ÿèÿ ¿Q6 ¿ùã!³ÝÿBxý°ÌL…A(<’Õ å4´éM®TxÇÏÂí´ •3ŽúÆœ›{¬ÃL¥ñ‰.“°afâYº;‘hÁ—*¨Àè-)“íî(}É8\áÌAr°F8` +Y̯”ìáÚ²^+«Bpsù¹Ôz_î=TF‚¥ýÁ™n€M±ŠÉ¡ÀJW_7Eï3ÝXy´áw½~‡ … ùÙ„CoôÔ„FyqÞì‹ò»Òuf™£üÝCX€ý(²ïЄ*ä ÎS7¹Ä“­‘sÝT (gbàÎÄ` +ugd)')Zå”ð-X¢JÂTkgaLÕ&Å¡¾ŒuÑUIÌ“P³µpaä9X;Á»§IšOísð'h3 ¿7”‚ÅŠ-7¾×c‚­û°vŸ^™¹ÃdŒ¤*°Ã¦îÊöt,®IY`a]•ÅÉíÏO] .LÂà° ®¢“_^,Ûýž«˜ÛÕ$ÿ9$¼Ü4âúëÓž2j Å%{ð[îªkF •]õ©§BJà’ +¬ï‹[^]C]WñðCÝÕT1±ø`ОúégÈ‘/‡•C‡©¯âÔ—@cežðȾí–Ä{ 1uÓÃ)<¯…¶;9³v)lùèß$Kën Ü =è( »Zv6yYïÂï ¢Æ¤®•ÁÜ2¹¸:Qf¿èr0}åÄgºCUÖ[÷ÿLËœád@#‡`”ÇTŒzÈbŒËbÌ(‹1Ó,†„Ï1'ð-yjç¥UíR\0ËoyȲ¶‘‡œÅ³ ¨ˆFË*Œ¿œ´Ã+NüuÉÑ€€+§¯ŠŽÂ(Wή®ï1ÔÄ—ÞYÍÑèÌ'ºíƒX¼´ U?TpBm4”FF´Þò*Å9xFÙ‘7ÊîÓ´, µÖæaz\äën¤ùà[^ó yÄ58®µüE]JñÒn{ c)än‘ÑSás¢ ¡þ£HSGQ$§b¯[”Û÷¨ X’/å”X šH}UN i¬™AˆûÍ“W8HÙ`rˆ Ïxu‡Ù±ºOáY‡aB¢¡à !ivÔšÐ[žRvœn[žÝ‰{õóü‹æ ìÍM˜Be:å.{=1ýHN¤'&ÊÐ5 #O^ý ¯IKO;—9­3‘¹Ï” !HÕàà>,;8ðfôp›}ñ¾êd›¨0Éù*Ù“Œd;á‡?TìMUr£†•MÂ<ËÒiÜ¿òžŠ½°˜ð+iæÒ8Ž[0']EKñ”€‹ž¸k%ýÁŠßiŒgš4rqûbSMí@=Stæ’ŸUOL‰’yžÂ ¥ÍS_ì‹Oõþ´—Ùz/Ó…¼1øþd¦X0Q:¨DÉ£uµm½’Ãs- tXcƒbMu WŽŠ¡ö°I`ÀYøÈŽçNžÖ6›NZ-ÿ‘~Š‹5ÍT‚ü¬DOø…Tk¦HÈH@þJŒÏ0gõõÄiYà÷â¹<¨9Üwwbc²Âížò˜Ýhî¥ØQ–n…sјsÔñ¯qè‹tqz˳Ÿ…U”‹ÇÃÎnÆ+î@ZÓø #$fCòŒçΦ.i”¯-pUÔ~؆ºȥ9í×äd!îäwZ²”#ñ¹ˆa³”Æäaf} Òe*È:ÞŠ+Üg&HX«.”ÑÓK6Ók¡RÒ7Ž.2 Ñ'–<Ç{øxR…ùþ·Rù¬·Õ‡Ýȹ.,<àÙ‡£W|íùËWo®øg¿¼~ño¹®ò?xM[pË6ýŠPk›.4ŒUæ¹£²IËmæ¿RØ)wúŽß{z_ ¤<ÍØ~ñò·ådâv¥ì& +žòÕ2«ëµˆ8tgð‰„‚ø¶@¾_åâûavèÏ€ 35ëϸž²ÛÝj\¶{iàÊî?ùo?¶®\lö`S]nóƒ¼w8mGñ ^¹†0]”wrŸ2`ÓAUóg8vÑŠÉÄ`„%__,ÜOÊwt]|«»š@†WÞTåûŽ¡¨oæú‹´NAîÕ•4êÆËx‰·)¨q|›‚ËcŒõÎÓ¦–[ÆÁwàU®ÓO;‡×<g îÆq⺓xvõÔ1(¶o^¿|ÒÂ)ÇVª¹€€÷[™«åÕbÝq$µQ&–¸ÛÖÄ8F@Ø÷×J0;>3>˽p"¾gèv÷ÚòÂ=-3l' ×Rftff9K.tçÜíÀßîT–ù¬ØäÁzU@$½Ñz‚í¿PØ‘åBZî‹©µr÷qÎxqYÑpeÄEÝõr ð)ÔþØEI‡¢É¤éôÔ¸è;–!.“ªÂïçêB²ºVŽü»÷å¾¼Dµ`â^.À|®îâI&x\-;Ér „d·ÃfÍ‚d±kœj÷¹ ÔL:ˆήçg—¾Vê3.”6OÔ[Kõ´#8 Û¾pdžtpJ~¯ŠM_™Ö#A­î:ù(hÒwæO–xàÜ8ÃÇ<³ÞÍ{ºx“‰·¦Z3©^– דh§µMœ$þÒ£YÊ0-‹}Eºx@M—݌ڢ,OªY4åâ€Ü<%ašÛÙí‡+]á,Åòõg, Íb| fñý=iñí+CI +}CÐý±Ð áÊÞGRK÷ôûµSü, ¯¥ÜW…$ŠàÓè4Û–4þ»;ßKª0…r…²¸4Q÷|ÞÈ0«Ð>n ñ·TÃÁF¼ÅoßÍéQIBI’~‘ t—¢iÍ*—dŠ.+N ,è(lœ€ñÁÛµoM¸^–|«6þšÌº9|w7õÒ¾ÙXù†ôÀ‡…âjÔŽ>¯‰SËw½\ëæ6Œ ‰žštC_€dÃ'x:>ÁãGò{ð;*7Kýfga©¯ùúȆFGŽRùžŒˆ ÿ £“ løÐ rÛžARÞõžØáœâå ø> endobj -2083 0 obj << -/D [2081 0 R /XYZ 85.0394 794.5015 null] ->> endobj -2084 0 obj << -/D [2081 0 R /XYZ 85.0394 751.281 null] ->> endobj -2085 0 obj << -/D [2081 0 R /XYZ 85.0394 555.2948 null] ->> endobj -2086 0 obj << -/D [2081 0 R /XYZ 85.0394 126.1169 null] ->> endobj 2080 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F55 1035 0 R /F53 1027 0 R /F41 935 0 R >> +/D [2078 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2081 0 obj << +/D [2078 0 R /XYZ 56.6929 258.0612 null] +>> endobj +2077 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2089 0 obj << -/Length 2725 +2084 0 obj << +/Length 3135 /Filter /FlateDecode >> stream -xÚ¥Y_sÛF÷§ÐÌ=Tn£Íþç2÷ä8NëNãäbeæfš>Ðms*‘®HÚõ·?`±K‘§sãk‰±X?»3bf,³©LgIª™áÂÌVÛ>»ƒ¹ŸODàYD¦EŸëíòäõ{•ÌR–ZigËÛž,Ǹsb¶\ÿ>Ë„d§,}ýÞ¨³fÁ%,€\Ÿ¯Þ³óWï‰s V& K„JëÙ§OWï.ÿ{º†ƒøÓ…á|þáìêËÙoDûtšÊùÙÏ×(ìäbÙm¤¿YÁî⯓ßÿà³5ìù×ÎTêÌì 8i*gÛm3Z©HÙœ\Ÿü§Ø›õ¯NOp&••Ö“b&K‘ó™”Y%•ßíõÅmêì·ëdÙ7#ŸÁ,,n¬gß•ë[UåíWn¸â½Ž œ¸ËKœs½¹2ÛæëIâ¤(Ôc&¥}9É8ó’¿Þ^^½£Ó°“õ¶(‹ºÙeMµ#Òçü6ß -7ÏËUN¤YÙf›‰ 똴Öñ!¶†¦\hÑ BVY&´v:_–¿|üü²/Ë&ß•yCš\?×M¾­éá¼*ëj×ív¿®fJ[ähÁdêºÐ'.X¿Ç,N'IØ@ç²)‹È»P† Aº×¹b´‰” ¥Ì¤\5Dªt."ê«”É>Jh/~å\޵ॢ*‰ˆ”M>ið(1Ø;¥à}.«‡º¨Ç8T‚%ΪÄ$¥§p#@[i0ˆ¦A)AXôDxL L!Õq1ø~#|1ï.®Ï?_~Z^~¼:bñ)ðMY<°àÑâ`p¨˜7÷9&̳ÁÜžá ÕíaAB¨(n{¡4±¶äL'Žb•ØýÊO\.%Ÿu¾{XFÐjC“mSlŠæù‚0¸°BΗ÷´/ÞÓ\Ìï³@ÌP5°‡ôj3[tfµêb[l2\Lš9ä†S7oWMKI¨Y¹ÓÏe“ýM㦚ð‹ÐPcuØò>•M9&eIb\—MF™ùu“äó²©ÃÒ}= Gmª:÷ÊèyQõf—­òz¤)¤Èu +¨ÞÐëYI|Õf¨zÄõŠ&#Æ!´²b!ŸõËô˜E‹gôógþ<âcS¡[š€?ì^Ùh¨¨ï¡•´f)—"ðõ4R<ñ /+pŸø„&{Ìà AãÄ1¬fÜXd¯óÛ¬Ý4‹`CUœe‰6±¦hµ"hp[m6Õ“O$ðtóL¿”ÆaP†žÊ—0Lk>²}åS+¤ƒõšÜ\×DÀ÷ô²¿Ä$t*æ^ÝDû¼(UÌð0{_Õ žŠÍ†F7áÍ6$G˜»ÏË ·Â_>ª Œ£Ô»â1¾RŸ½ÚwmðPbê—cHöê÷TDÜ›6G)æéF~Äð<”jSÆ¥±c'Jö—öTïD™'!' ^qäGp@úÓ})£/³XƒE - бÜlj?©`"éºçéHèa¹NûÀXPpiè0ƒGÁ~p>ДÏ/QqëÐ߇‹C„3”Ú¯]¬'VWp¦2©é·J6?P÷ñX@T®ýNè;%-ËR‹$,\T‡ŒùŸÔ…Ú “JgMn’—Ìc¹Vc?ƒLRÖŸÛ¸Œï,y·Y³ºÆ1g…³(ï¦ -©eç‘ciDÁÉѸƒŒ[×B•¼~NÄ8¦ -.Ç#’]@²ëì¨4"%kÁÖo+M²=°D@Cºø!¬œžÈôÀI(X:cë1Ämý)›rl’¦xLÖ#hbç1a™DcE<À&·!ÁšA‚µ!Áš˜`íÜËõ£"°¢!‰2_EzE¯ø ä±Åmw[5AT€9Œ‚É|‚õÆpøÐ|Sü¦à±Ô‘ÝK^bÒAE$™±¼tð"lÁLäèJLÀöØâ{lI9ïhG4U E—v¿KÕ½£\¯¶q"è˜ÑŒ×4~°b€àqæú’Œá“Hâ<")á=$aŽ¢I:(ÁÈC ~”’¥„‡à`ò¹G*Äy -©q+Qµ»U¾Àz޵|âžo Rñ¾™0 tiÌb=Àoz‘Å£ZÇH&¬¦Cl!ªC¹‚Îw¾òý#ÐÐ H ƒ Å·Ý@©ý |§ -ƒËOšæ¨A$’ ìW¹×Úäu€SÔmàôÀõÈ…~cϰýåÙm³oʧœ£ñ&#/æeÇt§÷Uå©òJ¬_ÅÞ;vݱEî÷ÖôXÀ±³]ç¡ñι¡Ùa¼{R4¶vÝ£“‹í¥߇Í Â-Ãlá8ÒŒÎè¡ëP׆™Ã“(ãè&0…|…òʺɳðà-›x¿J„0ŒÑ1þô­æ™wÛp5r9œ„æ#°Q¾”`ÊìÏœFD1X¿¡j@ ÷—4@@»ûe„ïï”1-4ÿ2v·/–gX*:“ÆÈ¡Hì…»øþ®zÁs¦;TAá¾s|(»¹ÉO$*ò,G}ÒMøt<Õ»Ðñ!{®ÈS†T]úסºà+ýê‚,£1üÔ‘#•ÃYJËoŸ5ð[Jêï(4Çмó78öW‹Ðæs&H¡ƒáí³/H b-L,9H¥ä#t -è¦P¥p¿›8Gy ÔðÙÍS‰,±zÐñÚäÐØl9Ã2ÛÜU;ØÍvú]ÕÝ£í¾X_THEJI¼¤Ý=Ç>&öBýã‘ëôZ&ןŽ]@Jß3ùnNùvæßØ×éùªÝ…oYÍæ™&«’Frþˇ³óŇw&Ü“¥º/5º¦êm÷÷¨ÝÍ$ÇþÌ‚T<³ 5£Ç:_‘ ‘»”ã®Wè_táDè@XVç «‰ -Ö¬Ö¡ÑH²}Þθ?ÔS÷Á}_Ä˽VxùºŒxÜ/é/þBg㢎÷²ñæÝSƒ¸uÕúǵpÊ¢›úð -1~­ø¢Ä»@ÿ÷Gáýçr0åœÜïöoClT --%”>Ôý€Û-Òendstream +xÚÅkoÛ8ò{~…¿­Ô\>%ñcí]\{½Æ‹; ›Š­$Bm)µ”¤¹_3|YÔËi Ü"@D ÇäpÞ3[Pøc‹L*´\¤ZE™Zlögtq soϘÃYy¤Uë·õÙ¯¿‹t¡‰Nx²XßtÖÊÍ2¶Xo?//>~|óáõ»ÿœ¯¸¢ËßÈùJQº|ñáÏ‹XØÇsÍ—oß\Â+—"$F/¡Ë—~|}qžÊåúÍùÕú³7ë@V—tFÒôõìó]láœQ"t¦OðB Óš/ögR ¢¤²;»<ûWX°3k~:Æ +%2¢2žŽð‚‹/…±L©Ò$0…¼øo]p0)“åú®€ãêdùþÃÅû78TË¿(åÅnkáõ¶wyk!øë_ ½üç…ÎY¶,6µyníäS¹ÛÙÙr[Tmyóì—r{îó¦-؇G;N–7õalS‚œÿõwÕ=]¬#Z)nNv_Z‹q'DJ ȈS"íÊ“ó#Éeõ°¿6D´®F¶” ·’¥¹Ê÷ÅÈž '‚IåPŸî +Ë¢ÞÞÛgøy¹±Û?ÜoóÖMXì¯EÓ:zo‹Ö`&ˆOp¹|wcAUÝ9 +Ð\ÉRB™Åü9:>Ðes_lJ#óí+ qÔÑ嶸Év­}yýáÒ<¿h´œQx*/ÿÐ[2°J¨ËL©""•鸹;¤U˪83w…ÝÕ›|g È·ÛCÑ8j>#ñW}rX +éVTBOÒø šÌdäXpƒ¼bî[û²- UÙ—FcàÕ2ò¸ÜÇ!:­BœÚ>ƒc‡ñunŒ‡uÕ[Êù&·Ž‰§nÚFtÊœ¦w]LYÝ?´“†£28•jÞrºXÓ¦°ŒÛÚå>¤šá”õ¨TŠy*ÖûQ*‰é0dËɼÅЇ +˨˗è¸Â2!ˆÖÞì ‡Ú‚A/ÍT”L¾<‰êð­lFiHH +ÇtË¿û0B7oŠS²WP¨Tœ}kFö wl[ç¾Hø1©éËø(e*ç)X#$ÄɈäYÓp”;õ^GV#´Ü;°1DxîÊG‘®Â ªW·41þµû=„fÌaMI²ö{=滇Q—ŠêÉuÈg&üžrûXu³+òÃÄ©\Ò¥‰äõ ’i=`œ@u¡OèAkF<nú¥pvgŒßkÄ¡h‡Žr#(Ñg)ñH#”Än€Ų)qͨ£™O¶3Ú‰£ q‘kû¼vïëËwoW˜™XW}L¾3êÝq_èàÄx–fNžÀÇø¼Ù2(Ïáœz=¸ÏË6ˆ•µ„âfTÄí)ˆ$Ä0©E3²,§³yÖû½I€Mö…ì"©óMyåDdÜqp>_ëù¹h½]és«Ç2·¤HY ƒÐ*éÕ(¹„ò<.|ÉåC÷êË{KH€Ñ"“y+ébM[IÀ22=‡â«3”oÛzŸ—Žsv¼ œg“€Ó›%+`ÐgyØ8å1aŸ l(]Îq¾bÚ ްÀ§›®Ì`St¡ÇfÂ0]Á§Ñ³Øó½C/¾•¦:ÁñSÙÞ¹-Bž[R’ÆBìñ¨ßcQ,…:)[ð™ 5™—mkF¶«/Ûçï‘­Ð4›'+`ÐÕ—­H9 ëËVXÙÙ­4I³ì…ÜNI\ÜQ¨bùUô.w/áiTI.! 5­™Ìcj%zjõÊ•™Š’Lc£³ï|³)ø)Ô6 ƒMê€Ð)ôD2ÔAšÖ44îá)Ú¡ümãÉd~WGjjìU‚ÏR†¤FJ‘r’H‘»´Æ:•Ÿ’ÂuzÌÚiîÌËÇFÂ7¦`Ð cE§Æ¢Ï»dÏŒbít‹ôj¬ç"¡zd2‰Uc>o÷Ù=ª‘ìr+Ì0_î{d§ ¶õÅȪ’¤éþP]QïK¨B}Må€y¢Á•¤UÑ¢ÖÇWXÿa?Ót¬PJO4]»X3Æà±†îð§­Qé,±k„Ú¾=PHbr×wÈ1Iiè¢ÍCRo8ŸwѺÖq„­ŠsÆ"ppÂ"$p]«Y„|E°¿É$2Â¥ôÉìþ¡qâ7¾bÎB0 +iõ"Iþ¥E‚‰ò¼t°f Äcý¬X¼¼Í ÎuB¤P'(X#¤GŒ†¢D²¤Gûz¼ð¡­iïÛ¼1Å… ¤¸Gê´¥e²,òÍŽðZ«µ 4Ø_Œ³)ms¿ƒÒFTô{—1ÈŠ%ïUÈÍ]~°ØEŇi•ïG¯ù²ÀÅUW¤6å€GU<á@h=N÷+-„Ù†"ŽìW08Qk1HË21¯7,%Z„Œõoi>Lø“(éœÖ9Hé‰{ß.ÖŒÎy,›F×Oƒëй&d4³»¬‘mã~½$"Ñ<Þ÷uÙÜïògó1Tâ¿€J–›wûŽß!`_4M~[ Yg¬R‹²r_N%þÃ+÷Ucw¡‰ZÃüÈø/à%¾A@YmŠãª6(¡÷é…¤]îËbüpiR‚Z‘?áš`iZ~ÉfæVõbñ ãÚÜ–i¸g,<)0Åî¦þË·è²(œà‚Ç/›Ø!£Pó]À7wvÇ8f¬L£×»¼úr¼ˆšþ®H<›ÿ¬(àÌ|Udq¬m7OÅaÀcp(I–¤s;œÁ–‡9GÎv·ìØF—ÅŽ8öɲP¿3¡††{³ŸþœùøÙ¶LÁL©d'DÍ> endobj +2085 0 obj << +/D [2083 0 R /XYZ 85.0394 794.5015 null] +>> endobj +2082 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F53 1032 0 R /F21 714 0 R /F41 940 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2088 0 obj << +/Length 1929 +/Filter /FlateDecode +>> +stream +xÚí]“Û6îÝ¿Â3}±§k†_’¨—›q²NºíîÞ^ìÌô¦íƒV¢mMlÉ‘älÜ_ Aʲ­x{Ó{¼Ñƒ@A²!… ƒ„1‡Q,I@Y0L·:\Á؇s<Ï4ér½] Þ¼Ñ0&qÈÃábÙ‘¥UŠ Ùo£·„Q2tô8ÿôt;Gr´˜'œKަOO³ÇÛ»_(0'¥£‡éã§é=ÒžÆ1M?Ìæã??f‹Ö¬®éŒ +cÓ—ÁoÐa+øy@‰ˆU0|„Ç|¸È@@ +á)›Á|ð¯V`gÔNís…  ¸ Á)’ÄJõû‹‘ˆ1à‰DL&Žþâ¬Ï_žËø+ÓÏûÕùRU@d$;œ}Z=SVÑÑS"ƒŸj]Œc:ÚWº¼tkË*/VÄ4œA¢ü3áà?‹7SïóB×Èÿ¬¹~D_òfP‚¿Zoó´ÜxñI5fj¤IËíV“”YO¾*JÄ3k‘õ'c$n–F!>œH>5–Í~><Ýcâœ98¹",à.m4(1Òß’ínc×£8¬gS¾à@½Fˆ àu2PD2ÉF`QïwYÒèÕRFÊ1¦å~“¡Šg +öµv”¦DJ^Ôºj†ž Óݸ)蔺Ü[ u‹AjŠ.ËÜš–+·NÃZch™Šˆ”<Èû¬sî ©å‚ÑŸe¡a +ŽË&·š€Ü¬“ÆCŽ”»½¥…"I'éÚA(‘´,š–ˆXâäTI¾ÁL Ï›¤øŒ@tóêò\y‚Ü+\â~g—Fý’°•Ëc¾/ëž4«!¹ö e‡"FÄ…ØÂ8ÿË^×nªù¯Ç6©]! BZ]ÕWO]–è¸Ýå¹d§É+8¡‘´ úa< ¡dv3î¸f ã?ÅÛk`Ÿ=.7Ùº¬rm30ís`°$Ëœú¥_’ +%¥^¨ý±ˆFØ‹!Yÿîí8`Z #©0’Íï"íåè[3Ú»X3Ц€AÐ=Pe&2T !s_5Ìp‰ÿt­ÓÏ~F§·• ’.R¸‰=‡̼<<€ÕO#Çl9«é°Ó}ñp¥Lõ:ߤ¬£;[‰ãa†³ñ°°-ŸªSlÕy±U£%µ8± +fâ>Qmµ…u”ÚÓJ7UËëÆ)KÐ Ì…žˆãªìÀÆýküû()ƒP{ª†ÔwÎE‚‹ @/km⬘[ j3ðB¬±M©Vešh»ËâwJEžz©Øp)ï6ÍÖjR7pҙôgMÕ|kŽb+{R³8}|ÿ:j‰D´Ú$ ? a»¯G+õ'ÒL‘±ÓL¶BiCmiçUÉ*2ÉdGó¥³§+´>“ЍuAØT+»ÓPCga¦àõ¤é³¶aÌ¥—)ÂÄ@½}œÏgï¶] ‚ox $ÚÍÄdƒ"¬Aõéð:ùª‘òñãüîÃM+ý—Ù¿ÛÖñ±Ux¶‰©º×º^a—ôþî¾çªä.$ÐB— +Ó®ÞZº\öþ UÏ­¥å2Zßè&}SAÙ|…^,Ï €N›Àž×-h¹.M8©­,ˆˆ`Axjƒë›;½WžA'—/þ6³Lö›æ;Ø÷<Psã¯x¬ÃuÅcžËXû †’É.#‰£(t7ƒ¥;`»’Ì•æ»;†YÂ¥.H̨tL«×¤7ì$QR°¿jN)Œå™À…'^3È[L>ëÃy48…ˇM{5-×e}2™Ïf˜ºÓûù?_71g!á ÎLP1¹ÑÁ” Ž˜é/:cp¢v°X°›cÎڥܼº¯^yzûéÃ_~Šùh‡µ˜ÛìØÞ,öw¿l_dIÑlÜ`Ýø÷)d²=ü›1½”×z—TØÊý‡&¦šöÚW×>šÉ5 +M…cµ6=oa;t ÛªíËR÷5–-£uÝÛ›ßÎèÆMþ\%Õáìñ!÷opiuØ5åªJvkÿâQî4˜w”úæìn믎é:)Vþ½Î=ô-÷;ûÀ‚ðFèÉ÷žua+›·ØžGÛÿí'ßãÓ¶„–B©ï4p!"09ôF72Á/ 9%\„¼ÇöÿnSÎÈendstream +endobj +2087 0 obj << +/Type /Page +/Contents 2088 0 R +/Resources 2086 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2059 0 R +>> endobj +2089 0 obj << +/D [2087 0 R /XYZ 56.6929 794.5015 null] +>> endobj 2090 0 obj << -/D [2088 0 R /XYZ 56.6929 794.5015 null] +/D [2087 0 R /XYZ 56.6929 668.7228 null] >> endobj 2091 0 obj << -/D [2088 0 R /XYZ 56.6929 752.2635 null] +/D [2087 0 R /XYZ 56.6929 314.4341 null] >> endobj 2092 0 obj << -/D [2088 0 R /XYZ 56.6929 690.7232 null] ->> endobj -694 0 obj << -/D [2088 0 R /XYZ 56.6929 652.8084 null] +/D [2087 0 R /XYZ 56.6929 167.7554 null] >> endobj 2093 0 obj << -/D [2088 0 R /XYZ 56.6929 620.2916 null] +/D [2087 0 R /XYZ 56.6929 97.1798 null] >> endobj -2094 0 obj << -/D [2088 0 R /XYZ 56.6929 585.1376 null] ->> endobj -2095 0 obj << -/D [2088 0 R /XYZ 56.6929 520.6753 null] +2086 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F48 955 0 R /F14 741 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2096 0 obj << -/D [2088 0 R /XYZ 56.6929 462.0998 null] ->> endobj -2087 0 obj << -/Font << /F37 799 0 R /F53 1027 0 R /F21 710 0 R /F23 734 0 R /F39 895 0 R /F48 950 0 R /F41 935 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2099 0 obj << -/Length 1782 +/Length 3033 /Filter /FlateDecode >> stream -xÚ¥XKsÔ8¾Ï¯˜ÊeZ,ô´¥¥8’@€„Ù-ŠÇÁ{2^ücCØå¿oK-{<ÁÙ„¢æ`©Õê—Ô­¯‡M)üØT+B…‘ÓØH¢(SÓY9¡Ó X{2až'ì˜Â!×£³ÉýCO 1¦gó,M¨Ölz–¾öNONöÞî†\ÑàÙ ¥ÁñÞÉŸ{/vºkx°÷äà L¹Œ#`bœì~<{vÿP‰|a ‰¥²fYɯOö“Ç/O-ëäଷwè£Âûyòþ#¦àÚ³ %Âh5]Äf Ÿ–©QRˆŽRLÞL^õ«nëXŒ”ÐDi‰‹± )C"KÖ•³E¶Üe:ÈvCAul&qЮk¤Î견+$®“«©m”‹¬Ê–Ië%´ ¿ûpév$»-6³ 8ÐÎ_˜#8ªé{/L*ÈOíôFCµ·ZíTÇúvÕ쎪۬i‡óÛtsé7õšé6W’¦Ë¬i²þÆ<¼¬—~¤„pøýç=q&EÃhÜêER\ÔKH&Ègi|Q&³°LÕ¨3ö¡ÈÐRìD‡Çó¿¥xÙ|“ÅÕ9—/2ž?9øfŠ9+Šg//¾íü‚>ª?ãAtWܱí¼OôiôèùÚ¼[¿]Ÿˆ¿Þ=_½zøðV_«\aŸzB!(²¹rß• a‚ä¼þ’!-ûêŽèÞH½„·'fLÑœ­ŒòLë¼(PîùªòɉD¨ùHEK$íï¼³Ês .¥% €exL(üLra ÊÂD -l/ð]v7Ð?ýŒ3¢bj¶OÂ_Oû"W=‚ÇX mYä'ûuZ8۲轰ä½*::Ü6ÈK¢hj‘ϸR®P4ëžl {!iöÀHå|r^m”ŒÔÅδX¿YoâØ+ábï,>±,ŽÀà߳أ2» –ûŪaðãkMÙ, ºjYZxÓá±m‘žWi>JÓ©qÇŽz|„Ffå*—ZxÜ:xz¼÷8<ÞW¾ÙeAŸ€ŽRyh–·~ëÆXœÏŠÊŽëªMòªÙ 1z=ü€‰ @,r›ßdÐ ß«¶l5+jD@0ËýƒÖ«|^Õ$Ò ƒË+b©1Ÿç#Ùª‰Ü?LVÈ„Ö#Á‡ÊIk¢e20  w¿ªJB3$n¯q_« â]Vñ -j$nªC $¶ó Xñ‰² ö‰ê,ÅC]¾ÍÖ—oÌp¬…í¦|T ¶@¶ ¬1ø(ªŠÂ§Gñˆ³¶ÎÓåÍ––Ù¨ï\#rs³AwNxæ?<²ÒÃúΩ!LCзL¿E.ÝæÞƒL‚om6à”"‘ܪüÄJƒÊ1ÔÔ¾!ÆJ5MB°s¸â+L«»<íÃÉZWHè‚"ã 4Z1xeì‚­‚ö»†$o³Ê‹­‡âcÛ#€|ì_Óîù„Ùogd½j]ŸàPµ­ùP¡²4¬µ_ c”ĦË_£®ßtJ$ïÓÁVŸ9†w<¶æ,뢋+\°Û3ö%t€ÕIb´êRÍëô¦c‹ [Œ¢ŽµïöÝeÇWF—ÐlAH|Ò®¡Ù‹Ùv)º5i6ôg²&"JëøöNM¢Yßçf 3‘öÏ­Èf‹qÚŽoþ-ëòW‚]Kd‰G³µíàä_ü û ™­4#ØÐFþòßC›ÿÇdL„Ö|üŸhÕÖeÁ„¸nzÿGÒ¶ÿ n 8endstream +xÚ­ZKsã6¾ûWè¹j„àMâ8¯Í:µãÌÆNj«&9Ðe±F"‘²ã¿ÝxEɳ5[>šf£_7ÌfþØ,W„ +#g™‘DQ¦fËÝ=ÂÚOWÌÓ,Ñ"¦zwõã?D63Äh®g÷ëˆWNhž³ÙýêËüíçÏo?ÜüçzÁ¿#× EéüÓÛÛßÞþËÍ}¾6|þö§wð(s#ˆ1¤Ótþëí‡÷×Þÿ|õñ¾'™Q²üuõåO:[ä?_Q"L®fÏð@ 3†ÏvWR ¢¤af{uwõïža´j_R9Q9Ï&tÀÙŒI"¤æ‰”!<ϸU~Ñõ‚QøòC½ZâÛ…P„ñL[’ÛbWâ<ð‘NŠ»!}×êìÎ37ªñ=;jËÃSypãeSw‡k–Ï›­›8vÕ¶ê^ü 1#F)î·š°œ;Aî^êfßVíXít'@Z"™4Sjb 8WÆ“fD U`‹˜…U¡dfÔS Ÿ®A_î+T¬'8B0;!uÛËrQ¬V‡²myº‡ :×üÏÀy9Á)×JyRPìºz\¬«m9ÁV+’)!Çl¿¾ÊökùrާÌHÎi6æÙ¾ÊÓÛÃ)G8mÎ%sÜOpË€‡Œ«ÙÂYŒsê}sè&sA zäˆñïýèeb‹Tg ˆ±áq–&­æŒHeòoñxNLžçÓþ¾è9.b–ÖÑ8¬2nذ3ŠX­&>q"”Ðé§/›Ý®¨WSN·`2'ƒŽw>çá>Þ½ÿõæóýÍ/·ý[i0Pàœ >q28' +¸"A ¡€ªy·)Ý Ù—‡¢«šÚ?®Ýoá~|`‘7¤LÎ!*sÐ7_8‡¶\•çS©¹4p@A5Ó2ÃhôyG‚•gZøíž ¿ÏÞ}ÐSµ*Wn¦ +ß°õïnn?Ø0 S¢åÁ‚]D¶ÊmY´e _%E>¿YO¯(É%ŸӸ " +¯PH#@¤§æ«•ÒÛsÕmÜtݸ™`vr[Õ¥›nöx žEsp¿…•öñ¸+ë®}s½Øwî…ý¡‚IOç~Ú º§]m°Ëáų[;d’pAuêÒÎ*0÷èÞVrÕÛpëžœÄ0èÉ‹§¢Ú[ÿ8È?¢®|fJ¾…L9XW‚_T9|c¢7òÝîXWË¢CS™ò +Ç‘•TdÚ4N…L‰ã¦îçþýgGžS—Ë®ºfó¦­KšÁ›õªªå ûúvª;+ÄÊ›ž2±¼` +r¾ª«®Àm@¦ê±.º£³Kk’RÌojGé´ TËãÁQÔ[éÛ`0ÊŸðØÿ ð\ËWmXRG­ÈK VŽÊ\M°”ÓÇAk«:ˆ/AÛ7Š­Ì$ÊÃxäW™ë‘úŠícsÖÛð÷ŸŸÞ¾_|ú pGÃæÏ›j¹q+Ƕô4…ûi7Îqoû\.Ýsçž1âoYemI¥ ‘8ál +ÁFšNLK3¿ß‰¢ ÕÀ;ÜýÝÍO‹¶{ÙZVùXvn@è,l˜aœØ˶ó<ÂJOï^g½ÑCÿ¡ßo÷`?%Ê_øv»M6‰Î=²°æ‡îÞ#Î> ,7èÄÃÎݱõ”!¼€‡Øòðâc‚û™ÊýyBF‚%Åw§þÀpqt0>ñH†ö T>ñ;9ëæ¹ö_ÝŒ¾>Ε§„©ÉA´oŠqø%&à4wX…‹Ä.Ö+L#õ”òÇcŸÉa g\@æ^B1_•]yع<Ó›æÙÍ»u˨+–ŸÜx²P]ˆ¨ºà!®#Ó%˜·?»<˽‹:?öŸ‘ºqH xèvPyCìuÜúÅ#Ú奒š¦_,`º;)}½!4Ðrž_.JbªP×%=îÛW"*’ŒäF‰³•H,!ƒÝ5§æ²ˆ=Õ„Œ)ˆRDSÎS!kË ÔÍ) O­.ÔK kð‘«P„6å±Z¹}ÍsYºdäb‹§t (ý+,ŠœžW3"yªRTžËÔ>·]µð£ªÛ®¨—eƒ ¿¶Gûïz`\·Øn/ óvÍî6´­}jl¾Žüæó“!˜ÒžI¤ K2è¢t€gÒF±vRF¼b£Õ TÖF—S6J²35mb šÊ¥¸,_O5!`b `—”‚%N(VlþLÙðÕÐf2²Nf¼%13#q2ÄH£Õ@duxî̈áõU¹.ÀÈÞL¼N&cAÊËnù#s‚òN¹QÒv8k Ö¡&¦æ²1ÄTç¡§²ÆðõÕ€w"Kø(yY¸žjBºät¡&Ì•¤âµ“I>Ù)I˜B­Fef"3à<`g.|¦™>=r1=.X—ç!ýÁÄ…£g*'97ùÉÑ{3’-ËHFsÝŸ<àb`ÑïãECq&¶RP^šLÇ;¹ˆ؇dG¥íy)@ë&gAæç +Ág™gð ùvåF6:Âo\ÕàŒŽ B–(½á”ÇÀ‰ãj=,N$£L•±oõuÃd]«¦ô‚ÔM”ˆԙHÑvùwÕvçN¢dÎËQ]p¸@e®}5úmºÄÝ# JŽË¢õT§²¥.„h‰eY*\Ü L‹80mÙ{œkh˜PÅ™ +aä&Í÷va=z§7ûâ ‡»¢[nJÿRqJ +Ù¼+w¾Ú5®Í³[Y¸c× ~¦LzêiØùöEî@É)FÏÑÙ+µ2€§L ¾œQ…Ý#Ëû;¸Qßc€9[â½ÛÊÖðäD +(*ZB8‹-!l:°ÐÁ€¹Mc ½œûòÛNb…SÞµ@”&Ge³d‹ä’`[€Ãà4Â8I#'>†é÷ ¨Ê¤xE…Ph‘ .?®bhTÅЪ¢:CÕYF$¬˜P—ý9¦:ïÏ=•õçý« 4ôÆoæØFT—å +Dr%¾Ì¡„äz$Ø]YO6ìʵ]-‹‚ûÖ}!¸!"ë7UzjšHâô:#“°}W;2?x¼é¹˜JÚ¸íÿ:d½³Ç«T½®cª Ǩìñþ>ÞÒ@à¤8/nˆ&¶LtL&ç&Ýòc=4OÁ3šà‘ÛæñŠ‘óJ; F¿RÕÆT”¨¬^¦m\ 1o¢S؄ĜñD®ïjÕôO?b$@ªÓp—4©’kÆ/+®§šÐ\šQ%^ ¨t×ßìáépǃ‡¥·•x_LÕ…;/ +x}ûÿ¦Ížã„6t’QøÖ už€x¢Œx{íÜz7RÀih‡IÚÉdâD0“WmnÈØh¿W5=ÇWTƒw¡Läÿ»j|>ü!˜…o!âB­CJÇ)E ÕÔ"g¹Ýbµ¾=§â¶¸}tÙ@%ÍmûÜ|‡Ã_š)‰((V(׫ÁÁ(V«ùð]ñèw|*¶ÕªO×Êg¼\.KÌÍ Á,ÂY€E÷ÕF¦9?ØŠCÅ,rˆ¿LÀ1ý݇Ýs\Ä,O[A®Óãñ㯃—” •&ˆíÅÇ@KÚ‡Ò]‰ Deoü-c€b|{ã +éêA£üm¨Œ0¿J1¿ôåG¸ô-Û~ÁÙ©éoˆa +òpç”^žõÕüÂUÛx›°ñµ¿QÑ]ÕpëeZLÝ…  öZ\Ïo[#SÓßYçá²ÝLÄAXí!®#èŠÊn+ñ%®~ì BkC—æ} B4ž•ƒ†HxrE9º“:Eg“`rü?Gx])uÿ0jáÃŽN¼u7c±\·ƒMñä§˺<~ãpÛáÑ¥¯Xž!Ä…¶*D™v¢Ÿz Šà?WL¤xÚ_$|÷?Ž ÿ'±?žŸÁ}‚Bº†¡PÓLˆ“XþÅìTöÿ–@¸Zendstream endobj -2098 0 obj << +2095 0 obj << /Type /Page -/Contents 2099 0 R -/Resources 2097 0 R +/Contents 2096 0 R +/Resources 2094 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 2102 0 R ->> endobj -2100 0 obj << -/D [2098 0 R /XYZ 85.0394 794.5015 null] ->> endobj -2101 0 obj << -/D [2098 0 R /XYZ 85.0394 668.3939 null] +/Parent 2103 0 R >> endobj 2097 0 obj << -/Font << /F37 799 0 R /F53 1027 0 R /F23 734 0 R /F21 710 0 R /F41 935 0 R /F48 950 0 R >> +/D [2095 0 R /XYZ 85.0394 794.5015 null] +>> endobj +694 0 obj << +/D [2095 0 R /XYZ 85.0394 769.5949 null] +>> endobj +2098 0 obj << +/D [2095 0 R /XYZ 85.0394 748.1323 null] +>> endobj +2099 0 obj << +/D [2095 0 R /XYZ 85.0394 713.0047 null] +>> endobj +2100 0 obj << +/D [2095 0 R /XYZ 85.0394 648.4882 null] +>> endobj +2101 0 obj << +/D [2095 0 R /XYZ 85.0394 577.9033 null] +>> endobj +2102 0 obj << +/D [2095 0 R /XYZ 85.0394 396.1161 null] +>> endobj +2094 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R /F41 940 0 R /F53 1032 0 R /F55 1040 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2105 0 obj << -/Length 2487 +2106 0 obj << +/Length 2231 /Filter /FlateDecode >> stream -xÚ¥Y[oÛÆ~÷¯Ð£DÛ½_pžÜØÍqÑØ9¶sp€$2E[D%R)»î¯?³W‘ÒÊrQ×ËÑììÌì7ß,ÉÃ?2ICÍHŽ&bT¬Îðè Þ}:#Af…¦}©ŸïÏ~ú…©‘AFR9ºìéÒkMF÷óoãŸah*ðøöúâãôãÍõ/Ÿ.¯'Sb¸âãó/_.¯/®þ7™RA$1>¿þzþ›Ÿû21t|þéònòãþ׳ËûdVßt‚™µé³o?ðh;øõ #f´½ÀcèhuÆC‚3g–gwgÿI -{oÝO³® Q&iÆ”ŒAF:p†0H2Êœ3®Ï?_ú]Ý]ÞN`ûÿ…‡ûÛºåêÓ×Ûs»Ûû«›k»[ÐÉzþÅ#E˜3í”Ý/ÊÉ”9®g+7ã¶Ü<—?»Ú¶=„·ESǘ>m7¢ÇåÜ¿íÿœE¹î¼ä¦ž~~S—EW5uÄê¹—‰¿óÊŠæ©®þ -u‹°âï嫟i×eQÙÅãªUm7h·ä}æ“ÅþÐ훓޾‰D†IÂVÆÚ†À¬ÇŒ‡Àé†($ízËò,HÍxÛVõ“]›Eó˜Ý\çÌo–­Ÿi»YW®Êºóz+Ìü:,b??jAJ%QHnnÌø®,÷ìh{fã¦Þ½Î¬þRŒGn ÖüÃŧ ¤(UÑÇÔý¢·E›x°E÷tƸ3xu}áGÆ?Î竪®Ún3뚟º-K÷º?û<«·³¥?F¹yÙͪe‹‚uƒ¡g1bͺ» 'ãü·»›ÓÉo³à;XÃäƒÿ¥›ÚH<•õþ»ì¸hæ¥'~Þ­ÁLß·J!¡`ì}ûÏß”mû~t'U‹MÓtój“³èHé’”nO*Ý]ȹ•JíÔeAŠP`Jzxø..ï>Þ^}é‘’ª ¢‡dˆbS* Ai‘L›‰“¾Ø [€M œ!… í‰ÌÒ`P±^ɦj|Õ…•ga5K©ì\8÷£YXz–l|.ëÊ—Y;½´À ö>‡_ZúdŸ/›ª›:\ "¦¹樣-ÔÈ#|€Á!pœõ=äHqªäÈkvœŽH€±´oã«Z»nê¹5!ãNðÆœf"Ì .UL{»ZF›Ašº‘\5¼õ$"Óz›³dM‰3𾇬I -l)ÁÉë׺s‘·õÒp3ŒÏù.²Ë× Ð³±¥챡ç<$ >i`b3Ñãm˜{©º…ŸMáºEhD4WÁªé,ç ŒPDÛu8Üst«»uŒ&¶k?1˸Jid0!ýLʇAظï±l¯Þ'’ÕÿÜTó`Ã"l».Ë0åùá3À„Pj`Gð?> ö G¢I%â˜ìÛTÂÛhwB`p÷»RF÷S1h^vÍS ߨ/ÏóÖˆ3P0Ô³…Ÿ‡­n à3`)àú79J_*v¦‡$%Iíòª¿¤„·†è·—ŒB™%' † -ÊÞ`É €>Û®YÁñ)2á€#©—'›!Fi¯!ê à€c÷‹ªõË×b5‘°eL‘L>rKæ${×¹ -ÇêšïÚ¥ÃüSÙùÌUÀ/ 0û9[´¬h&"·¯­=‰/ ûB}ˆ–XqìÅV0E`Ыۉøâea)¬ùÎÈÍÅ—ÛjÙÙÆÊÿÙ©îŽg\à÷ Ó«{6€‡§8¥¤äDä)â$ß‘º{ÅÚô @î8SdvîkÂ6áXoºíÙJ@Ý}K¦À€~*å!Z1í×zˆVG t^f­0ÛŽÓÚ%+.YÝìãl»ìüE³ZyPêU].ý›4 glBÆ>8f‘3áp=ã—Ëæ%_åÎÈ8 M —+;Á²mm—,ƒO š1ªÄ^æUù€zÌ9?9†8pê^ä·˦ˆ·‹¦ øŠ.Œê&ÜXl7®ÝâlÜ”±—)aËMíz·ÛºÎû ¨>´iÕoU¾’+ ¨LÅdrQi½x¼‹þ.BÉv FîþqÀÄ ë~°@¡c' ?PZ»DX{îïÈÖÓ*Øîòz9+ÿ‚†[Ÿ­j¬#±åk¹8Gy ‰ç7@$FEýp,¨ö,<•m¼AØËŒòϪí<¹Üzél+°J%¿ž¢‘€bp–C -Q{¿döRèêÑ®ë‰Ç«Æ{×O–ËÙCc[ÿça瓵»QçµÄŽiî_<¼æÎ‡× Z‡~Ššã)ªULWUAÔÛüǶ -WË6&’Æ”€}ü9[­— ý½>çÑ^Ôêx÷ #«Ü>ÝM3<Ý=6Ò…ÆÆÁ(k8aü0WÃÇÞCÛÿk™·*endstream +xÚ¥YÝoÛ8Ï_aàNÙ­Y~ô-MÓ½,ڴפÀÛ}Pm%N–r–ÔlþûjHY–ém‡5$‡óù›¡ÌþØBi¢w ã$Q”©Åj{F0÷Ë k–qÑrºêõÝÙË·Â,qšëÅÝý„—%ÔZ¶¸[ÿ–½&Œ“óßï~}ùV‰Éb‹åp€_õéæÍ%¹üpóW°åÆÄ K/>~¼ºysýŸó%WØŸ/¥Ùû‹›ÏïöñÜñìâ—«[ÏììênTdª,£Âkñ¿³ß~§‹5èüë%ÂYµx‚J˜s|±=“J%…ˆ”êìöìß#ÃÉì°5i6»®Xãä×g4/gSó2E(U,˜wW¯WaÕ»(‘F„5/âáÅL¸××7oäp±Þ–uÙv»¼‹š|*î‹Ý9³YQ¯Â¶÷yÝç•?u±äBÁIåÐÂã°²ùV®&6¨3í½>¤‡/VøÞáûýu0ÈQ!y 5¤©¡*Ó‹ç9Ú!½]Zk"˜ìàÆGŒµi°YF†Ë)ÇH$nŽ»?Ø X®S^‘šŽòTîÛ²~†ŒöZ5õJùCÙ\65=¥*¢$¯¦îЉ·Å·b—‡˜+Ðs1¡Cµ1ûjï14«"xiwnd–Ì4z˜b·WW¸÷âÝ퇄։ä" Ûýª¨‚ìE˜Xú‰‡¢ösv2WçÛb$&Y§Éb¬qnM–Ó˜û„sA“ŽiŽ£@ÚãèÜÏÚáاáJ*ê¹Cc^|¾ûׇOeE\w]wÅ®ŽxsûÜvÅ6xõ²©[Ÿ²ßîÏ•DH'9aV©±_éf§Ë$#V3øÁÐ)ŽË¸v µš7l¹ç$òØ«áˆâB$Ï*4·6ö!_87û8‰ñ;Ï b†¤+Dàx¾ÏuóØÔÍñ„µµX@Jƒ¹˜Ku³Ž+FéV)¦½]ö,Ž$v"ãª?™€o®n/?]ôÅí„ÅSé—²¸!ÜÑhqþB1$‘2·Ÿ æx?.XŒC¬ªÿ^Ç#ŒÞŸŒ êsHð©„¶ØÜvwN¾¥fÐlP/:‘œe›<ó€¬ÂIuص嶬rW ƒïŽV]K¦§BYÓÏu—ÿc¨Ç~a’BÚhëøf)Ç@ñ3ÊŽx²TBe·]I ÔpôT@©ªi‹A™•5R¿îòUÑÎ$ ´Ë»"¼û­@‰æœZ!‡Îózfa4{ùÒ~z™Üðóω-/[Û¢^¶|UY)nŸëòcvÿøAnÇ€¼ùAC÷'m¶íW?r>þá2´Cr·ÉëÄiÐ’;òø{Q-¨ þ•nLOVˆ+é»#ti˜ØGÕ+ܞ׸®yôÕÎV½ÀɘäRèÙÝ' +Z?l |´xŽß…®#)oz•ùÚ  å=¶’„.”òØîO$Ô ˆ——^OÿæMö­3˜>k,;%‚–zjo4Å}ÞWÝ2XàX«‰‘*Þúð<­ Ü7UÕ< HB‡ ððD‡Aš¨_p –’&×èæ¶E‚ñaþ¹G¡s– âÝ*\E„x˜Ý4m‡£§ÒßÂüèkØÙt„¹MQ¾Òþ¡¼À8r}(¿Å y åñ}r¯EJÄþù}sŠE?R½nRp$7Äng~ —¤W WC>^¤F'ÂM õsS'upb¼—xB4Ž ^±è‹éàéO›ÒCÆ”'\ë®ô:盼í9F˜Ñ³ÛÞÜ<Œp*Ý41–\ZL£üÕm\˜Ÿþ6—]{Áµõþ>>@nƒbvò.'QÊ©i¯¤'·_ˆÊõ )‡VIG ±ØÁzRø€dß¾óq6gíÒrfüeØ|Ï<šJ1÷³vAX ~îã1Cƒ Ñ“ðºÍ»Õ&|D¬föИþºš ±5zäŒG´²GˆªK&ÀJƒ|–Å8Æ .Kc&ÛÉvÌd‹¥ÑSòl ñ¶Ê»°moé˜Ðÿ çì?Ç {ëÀ (XZcm ›õÙˆ±ÆœHMÍüçE9KÍáëбeŒôñ(7©«V€U`u†_ü¨ƒlpE¢.V‘Þà–!(iì±€ên›.° +i£`²ø9l 4‘tCNÑ9WˆÅP'´çxF¹ƒŠˆ> endobj -2106 0 obj << -/D [2104 0 R /XYZ 56.6929 794.5015 null] +/Parent 2103 0 R >> endobj 2107 0 obj << -/D [2104 0 R /XYZ 56.6929 752.3759 null] +/D [2105 0 R /XYZ 56.6929 794.5015 null] >> endobj 2108 0 obj << -/D [2104 0 R /XYZ 56.6929 668.0781 null] +/D [2105 0 R /XYZ 56.6929 703.1515 null] >> endobj 2109 0 obj << -/D [2104 0 R /XYZ 56.6929 607.6906 null] ->> endobj -698 0 obj << -/D [2104 0 R /XYZ 56.6929 570.577 null] +/D [2105 0 R /XYZ 56.6929 603.3192 null] >> endobj 2110 0 obj << -/D [2104 0 R /XYZ 56.6929 534.8112 null] +/D [2105 0 R /XYZ 56.6929 540.5015 null] +>> endobj +698 0 obj << +/D [2105 0 R /XYZ 56.6929 501.6992 null] >> endobj 2111 0 obj << -/D [2104 0 R /XYZ 56.6929 503.6098 null] +/D [2105 0 R /XYZ 56.6929 468.7926 null] >> endobj 2112 0 obj << -/D [2104 0 R /XYZ 56.6929 440.3004 null] +/D [2105 0 R /XYZ 56.6929 433.2488 null] >> endobj 2113 0 obj << -/D [2104 0 R /XYZ 56.6929 370.9227 null] +/D [2105 0 R /XYZ 56.6929 367.5092 null] >> endobj 2114 0 obj << -/D [2104 0 R /XYZ 56.6929 274.6697 null] +/D [2105 0 R /XYZ 56.6929 307.6563 null] >> endobj -2103 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F41 935 0 R /F39 895 0 R /F53 1027 0 R /F55 1035 0 R >> +2104 0 obj << +/Font << /F37 803 0 R /F53 1032 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F39 900 0 R /F48 955 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2117 0 obj << -/Length 2188 +/Length 2228 /Filter /FlateDecode >> stream -xÚ¥Y[oÛ¸~ϯð£¬YÞE>¦m¶'‹6ÍiR`Ý}P,9*K^Inýõgx“%™¶ÏÁA€ˆ¢Fäpæ›ofd²ÀðGJ Ì4_¤š#‰X¬¶WxñÏ>]/³ B˱Ôû§«w¿²t¡‘–T.žÖ£µÂJ‘ÅSþGróðp{ÿñî÷ë%8y®—ãäËÍý÷›ÏnîáZÓäæÓíãõ’hžr"ÌÈIœ|»ÿøaùáëý¯Ÿnï¯ÿzúíêöiPk¬:ÁÌèô÷ÕáE'øí -#¦•X¼Â FDkºØ^qÁàŒ…™êêñêߣ§öÕ˜)¸PHP.KA‘Â4n/Œ°€ó/SNÔú`/Jbö -RÆ^ËÍüœp<Î9YŒ;Ú2E¶d£-µFœŠÙ–mY÷sFæ.ݦi{?Üo·Yûænšµ»ö›ÂOìú²©ÃËuîí5QÉË~[ ÷9×Ì”kD)Má F‘¶ÎWËUS¯_ŠÚK•—àʨFGxðVO AŠyÁ5#©3® RÖ5?œRBŒ$€Ì+õ£x«³m1W0…Ò4Uçu¤"Êí@8C©ÐdªÝã®X•bL kq|$Rn`U³#çÇ‘Œ1½e{˜¬ûr•ÏV „€Í—ŒªäiSú=¶û®w£g¿Pæ.?³ªÌÝ0o¶YY4°Ž[,Ý™96AZjñp•ël_yÂnÖð|ì"I‘P\Œ¡cÔ<† O‘¢X^‚”æ•a?Àf,u6ƒ”…Íî"lv&Úæ˜¡™óÕ+Eôš † -°œ)6A Ó f°j æM03-’Õ&«ë¢rO¬¦vôº)l”±¸ÆÁ0Ïx=x†q¤Y¤ª²ë‹Ú«²nÚ  -l¾ò$cÔYÛ]›md[€×1ç#LDv“ñaS@tÊ•ÅE%ÇaJø–s4Ú+¸ï4˜¨BÄíy0¤Î€)HY0µ0i$"×l×euÌB’„Vê¼vƒTD½ ¦ä…ÉT¿)¦7|À„Hºfoý¶*Ü´! suÚ:™<ë37ë¼HE DT¿8‡P³,°TÓ–ÿX’'JÊ’;¿¦œÂËη ÆgŒÓ½ê@*)0•åNI’ºéÝÔΡíg™n"‹P! -*íð./~¾óçŠ$1•88˜ӬZü½/2wÝþ°D¹*~17þÐV¿† 2¶¨yh)®nçºè:wj¢¤É"Û•eÀ2Ÿ—®=]—õnߣÈ)•©Ž(™À ôŒœQHÄxìÑLLÇùÈg œ6[õ…±Ž†µ†—lÝÕ,Xù9àˆRŒE‰MfƒñMRÕÀ´³p¶@3F„ª®Øe/¸ßwEîfÊp‘ånÚÙ6”=Ö?Ö&rê³<·GÍ*'þÜ;R®<‡’Áx ƘŠHåË:7I9@´ßd½ÛuæCxf}èÎO¡—©b3Ôoš}勵gŸrÍÙOšºœ%´±ÔiB¤,¡u±ìˆeƒ…²v­»lìJ~*ví[älì‚•)ÑóØ Ä“®èඃ浶å”®gûO‹YF¡^Äú¿C>@ß ìàËv© °•ùñASúòÀ½ÓÏUðbÐK²ª §òsî @˜Ïʽ¦®Þf9èP=šJoöð ã¯Y…ÿ4¶É|¢*ç­`ZáRñ‹/£ìq=ÖPŠA»‹¥4jBM‚Ýg›Ûßo¾<|¾}Œœ»W8q­Õ“ùNÚx•ªªyØ”CÞdš\HèÔ$¡Ê}s\º‘G*Œj/5ÇÞ©°…†±â˾µ=Ø/nÖS¶ƒ•mº”PÖ`jØr £éñ¿¥Ä8xÞRK0,¡A+MÓd†™»tÙvWE) Æ&¸6;ÇûÅ縶;Øo"Øt­¯Zv ”å®Ãœ'?l¿pÞ1MJÛT]Œ5µ) ¹ØlY †DŽš†/h$EÖézˆ@ÿÖèÜ{‹=ûÃ8gšÐ0we’(%¦´“³†¡hû€ 0x1/´×óq‚8i_m(.xâ"r†Ä•j}:‘pÃÓ8{¼½uûÜ|~üz9ØÌêb(¿à ȘbôÀv$mW¤Mû ¢DÀÔû»ûþ#’W*ßBÿÚõK§’oÅÚVõʇæ~ÇKÓRÊIÞ=¢iƒ €ÙÄ.7ߟþõõÛeƒÜÕЎׅ§ÄGûÕÄóßè5š¶/÷ÛS?ÑÀ†æw•HVŃŠÿ÷Ï7‡Ÿ© ÊfJÑx~f˜ A)s8ÂÄ\uÁ òV€µcÝÿ* -zendstream +xÚ­YYsÜ6~ׯ˜òKFµAëʃlËŽœHVbeË•ãšáh¸æ1r4+oå¿§n€ä„ñQ»¥‡îƇ¾‰‡?1K4ã*f&˜æBÏ–Õ ŸÝÃÜ«A< Ï´r=»=ùú¥2³”¥±Œg·ë¬„ñ$³ÛÕ/óó››‹ë—ïNRóù3vºÐœÏ¯Î¯:ÿi7§©œŸ¿ºx Ÿ2210 ÉN»}ýõK­òUš2ik–•üãõ‹çìù›ë—–õäâ6Ø;Ü“àÊûûÉ/¿ñÙ +¶öú„3•&zv€ÎDšÊYuiÅt¤”§”'oO~³néFZ%L'ÒL€‰)tÊb%•ÛÊ*_gû²[´Í~·ÌÙjµËÛvñ# +rˆ‚Ð’‰€A–e¶oó°3Ñü°)–;TóeV#í.Gp­Ò5HióŽ›—7Îeõ*bbãNE2_³µÒ~ƒ¥  -‚m !Xªµt&×6_vÅC^>ž +!æî€a ‘°ThÄá|Ýå;%Î&·ùz‘`&1ÞÚ|÷üÅÎB©$"¶÷ùã¡qF¬Î¬ð”6 ZHŽ»¬Ë«¼î𳨗å~å…¯ ¶Ý®¨ï‘äÁ¶¼mo´lš¶«³*ÇU i †„u³Càð;©õ7Щ¤œ£po-`oÃHÆóÛŸém·K6Y‹ƒnƒ +süÜ6m[Ü•´ˆ\çŸ8KmXœFià”'–*™ÏÙ„Í hbØ6»nBŠ4°u!‰ÉúÝ„9œqc¼ +tº#i©~¼4“ñ0I·S‡¼J$Dk,ÆÐWûÖºA¬æUÖ¹S†!žnщXR³Æß œ|;ú,(ê‘5ÿ•sYæ`ž‚xë©!7ª÷ÕóK+ §° œ/¥x~ +i ,›º†0#¾†\®C°¹= +‚zi¡yú9HÇp&iâÒ‡°ÕâCÆö`ìž¹š_dîØÆÚðÈ㔉ˆæK Pfïs!EÏ›mw*æESg%,îN°ÐzÞ)0c& ÔJW£ì>)Ô†TH›Ý”HÁbüû³êW,ÑÒ׋† Ž«uá1i< e•Œ!s'îE'#ç†ðë\výHÄ ñQuV$Å´dX],Ë‘éóëÈídñ€,bt$?šÓ¤dœ§>§ Â8âÖ5ïÁq|(:ð¯Hpç&–R¬€ví +„%`±€’ù’c©˜<ìÈ…¦¬I¸§…IÌ (hd†ËîvÐ<ŸH2GGÙM¡RhU”wˬ¼ov°›j*È!9 å}wèS‘R”Š”’ó¼^î· NôBÝçÚ;³9³ÑLØFÅïêÕrêH ¥÷LÖŬDØÛSA-\îwèuW>âdSãHο½:¾¸z¡'™j%lj«wìB";_¹ØNœ1cÝ”espÞÔ»G¤føÙæK´£CrH‰0½‚±)ºËœÙ ê@XÖæ‹8B* Ù¬¨Ñ0²CÞîWí8±ãÉÏÂÆÍÀ­”ðåè½J¾³qA‚Ê&wAâVÍÞµvüû¾éÈÇ&bá°`BïÓ縎ºlªÊ¹ Ùc‹TwÆ@¹Ïë|®OÔ ­v[ª·ÛŽ­—¡ü ­éÏ6%’Z˜yvyý™S$lcs¿Ëª W$Ü=thv¬«.|ìÑÌ8úšz æOõ¦)dî³–hïèl)™Fˆ‚ýíQpgĤЦ±?ß3üÄnÓôô8æàr&¹ñ!]UÎ×ò©Ø—L&Ü7ÑxHOV¶dáûº9Ôd^;¥“',R‘UQª˜PAéA¬ãÚÞ­†a‹ÐÅÔ1˜P‡€‚íP:„æ3bnz˜_ã+œñ›Šm²Ýwlbc2ÖL‡‚ýq,#ãªÁVŠAÓ¡îvSl‘„…ÅŽÐEílJ–ï;ªÇh<•rìs>l³‡¬(³£> TYM¹}„†ªj)¼Íó£B}ñîüêæû b¶åÖËpæ¨Yµõ +l‡Š^µ¯×9‡^¬‡/˜¼¶)Ã^ÕRƒ)Ãë¨Xp“ˆíýÈÝìÒ[—ã@YÌùü¿/{„K¸]S§($ð—Í2+í5íéT +õKðÂñJ†ï§tÕkB—ü#ƒŠœÀ%jxMufµŸ´Ú©6ÉÿO5$ênø=©[ôºeD‹‚æ#úÛÉ›Ú!ÞQìH+­žâðéÈÉĽIñO"8èA"{ä›*[.ª•žÜŒ­9ZÊçOâ—WëGêMû!*ïdôæ2—Å«‹i¹eùúÍ?ÊO¾ü4‚Ñ„ê—ì þû ˆÑܱ=ùQ}{™ÜÄϾ;¤?Þ®Õ¿~þnÿÃ7ß<ù4òG©kÑÇg‰{“e½tùÞç ·¬»æ!GZþwDg Š"úDÃéÔßöéfr]¿ª(8‘ˆ-– +o:¼¿Z«ˆkà”–ü+×\HÃ8ü øÈ…Il( (°¼ÄÂì6=¼ºÿÕö?æyÔendstream endobj 2116 0 obj << /Type /Page /Contents 2117 0 R /Resources 2115 0 R /MediaBox [0 0 595.2756 841.8898] -/Parent 2102 0 R +/Parent 2103 0 R >> endobj 2118 0 obj << /D [2116 0 R /XYZ 85.0394 794.5015 null] >> endobj 2119 0 obj << -/D [2116 0 R /XYZ 85.0394 400.4859 null] ->> endobj -2120 0 obj << -/D [2116 0 R /XYZ 85.0394 274.6805 null] ->> endobj -2121 0 obj << -/D [2116 0 R /XYZ 85.0394 214.6285 null] +/D [2116 0 R /XYZ 85.0394 513.4321 null] >> endobj 2115 0 obj << -/Font << /F37 799 0 R /F21 710 0 R /F23 734 0 R /F55 1035 0 R /F41 935 0 R /F48 950 0 R /F39 895 0 R >> +/Font << /F37 803 0 R /F53 1032 0 R /F41 940 0 R /F23 738 0 R /F21 714 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1592 0 obj -[702 0 R /Fit] -endobj -1447 0 obj -[702 0 R /Fit] -endobj -1198 0 obj -[702 0 R /Fit] -endobj 2122 0 obj << +/Length 2274 +/Filter /FlateDecode +>> +stream +xÚ¥YKoã8¾çWs²1‡o‘{ó$™Þ ¦“ž$=X »Š­$BË’×’“ÍbüVñ!Ë6§1‘T©X¬ÇWU4Qøc#¥‰¶ÜŽ2+‰¢LæË:z€wNX ™F¢éê×Û“_~ÙÈ«¹ÝÞxBa£ÛÅ—ñ¯„ 2t|}yv:=½ºüíÃùådʬÌäxöéÓùåÙÅ¿&S®(%¥ã³Ëϳ?üÚ§‰åãÙ‡ó›É·ÛßOÎo{±†¢3*P¦Ÿ|ùFG 8Áï'”kÔè&”0kùhy"• J +Wª“›“?{†ƒ·îÓ¤*%\hžÐ)](K´€W¨‹‹{<P²¥!Xw¤X׋9[°ñ´Å'wEÛµÅú©X‡o‡»d†)·eë¿Ü´Å"|ûXÔ‰•$™j¸å!kÎI–e‘蹬*Ï}ÞÔu1ïÂ_ ºqSûgÕÌóê±iéªYwþ…JDIËú¡Õ¯}/^üŽÆØ˜ €£)ÓŠ)$Œ aš+'Û-:Hã塨‹uÞ~–ûÇ:¯ÍÒÛb¾ž03.:?.»Ç„Š˜ÍjÊ:šÂÉïz…u¥Áa¸ˆvø‡§f@1åÔf@é;¢áKw©g“©È,X`¹ª +8£ßfDzŠhɆÎD{‚µÊˆÊ ”_)åUñód*AÙe=¯6 gÜÎYF˜ Æ /«¿•½ð„ÑXw|qWøçóºì:8¨gÛ Ùàí€æäà`s«w²6›nµé(£ãÓf¹,ja +Ë …0×ÌŠxN1áê”H.¢Ö@Š#K„Ê¢‰A©Ýº©Ú”bÁ@ð@‡ê +”°õîv̵߬$€71Öê|Y,^³›æ„kI½º¢·Wmˆ‚ÕºD„¨|Hdì£æ.o‹©–?6š(c² ÚfÞ,ŠÄ9¤%†qóVÈ0«‰D€Ý‘»˜?‚Ô’ÄOßëæ¹öãU•ã‘ÿÓù)ªÙ rÿ@ñ‹î'?ùŸì ÇF½“¹ÀŠ˜Ìz—»œ}<÷ç¾9¿ž@Öú nŽÙìâÃçëjóöâê2Å\žëïžigg©>qu¹AÄÄÑ]x ž€ñù°ñXø·.~à™ÏçŪó”>{àj@鲩Û@V/ßо@Þ«+ɨåGZV¨ãû³6ÏÆ]Ø9»aU…ÏÐ%Ã([罌OE]úL‹Ëb3Èû¾tM¯ñíÌÔ—Ø€‰D¹—²}skõ+%€ }×x¤>Êd_,{}yή¬ãV…:Àbå·ö‰­]5µëâêMqeíñbDX"u_™õ­ßk cüÍ h@+,ÕY®×4Dœ5üMQÆ{8¹{ñ\AÜÐIL™VÚݲu¶µlÕ·®\‚Ö0W>/)CÂ(oÐêí*eHåïSUJOµõ«á–x›`™y{ËH”Ør'²`˜AÚÛÙòÌ €Ï¦k–>ó„9 $M&õÀDð×ö’8àØí£»×„í DÌ&Ú¶Ž.’ðG¨Ée¦Å»âBg4f×tû¥]Ì¿Ý<í¹ÙöÒ{. ãó#ˆý”LÚP¬Ñ7›íK‹aÑ× »­¡ÐîZÒìÆÑ3f0I`§]Ç…øâ/‚ÝÈ7Gn-¾¼Û”U‡½•Ÿv ª»wʸôx"¼ºg“¼â +jJÍÙÑÛeÉzà{%¯ÀY©±Ã +gNìV}M8&„õºÛ¬fî®\ øs­ÑJXùÖìiùÕÄfu/dVTޱi¥¼vÎJ•sV·zŸoªÎOæÍréA æ¯ê¢òoúUˆ± ƒù ÌbÍDà #¬ªæ9åx’öø=¿¢6šË¥ Ù¦Æ-‹ Èf‚gj7ƒ¾r ˆ¿H)YN¹ýõ¢Ù¿Ðp¿øaø!Þ;ºQî.ï7k×nr!¯üdÀ•Wiõûç¤íÏf«CÃÓ J(†q +•Á„>L$ᇧCÙÿ Sñendstream +endobj +2121 0 obj << +/Type /Page +/Contents 2122 0 R +/Resources 2120 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2103 0 R +>> endobj +2123 0 obj << +/D [2121 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2124 0 obj << +/D [2121 0 R /XYZ 56.6929 613.6539 null] +>> endobj +2125 0 obj << +/D [2121 0 R /XYZ 56.6929 528.5855 null] +>> endobj +2126 0 obj << +/D [2121 0 R /XYZ 56.6929 467.4275 null] +>> endobj +702 0 obj << +/D [2121 0 R /XYZ 56.6929 429.7784 null] +>> endobj +2127 0 obj << +/D [2121 0 R /XYZ 56.6929 393.7775 null] +>> endobj +2128 0 obj << +/D [2121 0 R /XYZ 56.6929 362.3409 null] +>> endobj +2129 0 obj << +/D [2121 0 R /XYZ 56.6929 298.261 null] +>> endobj +2130 0 obj << +/D [2121 0 R /XYZ 56.6929 228.1126 null] +>> endobj +2131 0 obj << +/D [2121 0 R /XYZ 56.6929 131.089 null] +>> endobj +2120 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F48 955 0 R /F41 940 0 R /F39 900 0 R /F53 1032 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2134 0 obj << +/Length 2734 +/Filter /FlateDecode +>> +stream +xÚ¥Z]oÛ6¾Ï¯ð¥Ì,¿Eâ½J×´èÐfy› °íB±äD¨,y–Ü,ûõ;‡¤dI¡ìCЦŽÈÃsžóɰ…la¡ÂÊEb%Q”©Åz{Aðîà 4«Žh5¤z{ñæ½H–XÍõâ~3XËj [Üg¿-¯no¯oÞ}üõrÅ]¾%—+EéòóÕÍ/WŸüÜí¥åË«×w—+fe"ˆ ¤ÓtùåæÝ«¾yÿáúæòûŸ.®ï{¶†¬3*§?/~ûƒ.28ÁO”kÔâ~P¬å‹í…T‚()D7S^Ü]ü¿_pðÖ}…†(Óˆ,¸È‚QK½H”%ZÀ+”Å—CUÕ#ÈÙ€\2B·°Òí«l½Z×Õæ1¯PFÉr•††{$‚$"Ñᣴ,ëçÆ“¿ýxóGziýDZe‘]&\+5Ø5²  fjQ[ûr¿þ¡É³°EØ;Û_2³¬w«"ðî~ç»2]çÛ¼jÿá¦ÞyM–w_¬8—m+ƈUŠûãEOÀ,*¹ø˜&Ê&I ùÁƒî¹hŸü¨ªýsý”Vyã´a²}Êý ÿ«hZÔ‡qà™zžß¼—#¦à*éåZ¥Û<#¨Îsšƒ +tGú;¥¼ÌIC’ ã0å‘å•"ÝÒQ¡‚”V ëW.®‡F⑇»ð&‚S89%:™Š3WØÎOõ6)_Û¤ü÷èOƒñek@$yåõ)xJˆ-À7aÊŠxÀ +D«!•wÒ,°z*'òÏ(ØïHäÆö +ÿš¿4Åßù”5±!Ií'yë©"Ì´,Áv”ecîîvùº@«FO%$÷ +Ž#7ª7“Wé†U[¬ƒÀ98ƒaâ¡hŒºF/?š6LæÝ³}Îó@ɪl0PŒã@¸%þCÓ#0&ˆab±,ߤ‡²õê.‚Ú7óÚæšXÎÍm¨Nh»£rÚ^Ç´ æ-˜:j{S”m'„1yšµŽ(ÂÚXלPÄ׈·_BlF«¸ÇÐNïfãNƒ‚'¶jâ4†±®Ahm^ü4¼LË6ßW!¤ÐeY¯Óã—è°#öoÅ ‚X{Í‘Lˆá´sc³ªWgi9—™vªRÍ«¾§rbzšn o¥”g¶ìˆ"[Og-‘\M¶¼Ý!¢.‚£ÔŸê}0„æ°Ý¦û €z3É@¼Êº«€ŒÔ¹ÊÇCŸY9}ÆÃ7ç<ùÎ…‡àgUþ[hÊϨf@uB5•SÍ×ïñÁZf}ðIÞŽ>ø5sQ<ânäƒ1— :ÒÞ©âÀ±æF^Ÿ±àhê–»0/!>lß?a­óÉ8êRïÔ?¾¥e‘ùaVoÓ¢:r@N¸àûWS_üÚ áìÊÈa™°:eÑú,l˜!ŒCéx6ª°é¨lvga³Ck›bl<ßI¾:¢_#Äp2ÐÆÆQÛ4à`]ƒÍ»@j•+Aª¼ôo§nôü”‡,?b×R8®Å0ÛŠhFHbE_'•PËäU`ÅeÝžØ|œ ²³ñ•Ü6Vw ¨ ©”gJGJd¿) :‘ÆáΡRRˆycãÙÌÔ7 &Ø€“œñACªy0õTLû˜ ˜7¢·P\½æ +‚„5æ4w=U„½¦ÄCÙ˜¿1¦”D ”Z6õÁémûi— ÂÓsëi²´Mý¬×> B èJ\$ñÅeÁKÕûâoç¤@‰š W…â»@¤ 8u{ÝZ¢„ì=Ž/]›@ÝÖ—zYí|§fP~·~jçÑö­Èr?+YX•°]ýñ&Ë¿½ çŠ1ƒ.»Ïxö~U,;Áe‚ßõûÃÅ:wh8´ã¯‡! %Š/K‡§ß¹Ê›ÆŸšÑBM*Õ¦÷ìµ×Á]ÕîÐ’È) ö¡8Á øŒ×cB&<šÙÀô:…è.gŸB¡å*o¤(÷þ雼®Z1¡¢—GácPµài'æì€†BtY¦¦>zÁïÐ8‚™¢\¤™Ÿö²íÒ§§ âK µtHVÓÒÓ€>yDŽ\¨/‡‰E•aPî zl”LtïœC¿Æ¨¦˜ >4Ð=„‹gŸuhÂbÏD)l‡Tó­§r­9[ê¤Y¶pŽ•:'YëK׬EKo㔊wúçlùñÖO k.6âTTdï¨dɹ¨(3FO£"®î{Q° q¶ÐîÇ0^ºoæã%dE„[ñïâ¥w¥P2©¿3y— e]ïÒõ×P*Œ$è +›Ç":riΔÝCªXì¨Ûhp…ì©ÓÙúi_×-¶‚¦`„,Ój(0O2×SE¸ÇVN¬ùŽØ •·µ]åmí\å éž0êL»Ž'ZN+o\²öÏcåm}gךA¬Þ‡7'9e’G¼Mï{‘eé—­N7É;×®ý¶’àæ¯Â«4[…’‚ °b3éÑgžÍ{eö±{Lqá8ÚÛĤælôèÍ50Ëú"–Ïû¢½wí:ÒðÛ «„¼ä[ ðAq¶‚~"fxÙôDÞí‹ež°%¬?ÙuSœ{À©—c$(›q$èÍr(àXû7!‰æg}%ÖŠ³µ8ìÆ²Ó<¤š·àžÊAýp¶Ö‚0·Ÿ«µNòÕ×Z¯ùŠÖZ#Æ‚í:u9ÛÕr¾k–$ŠéšYÎìÔv{(IßiïÀíõsåÒ)n&û“YÁ!_¤öûÐÝùú«L[7‘ƒ&Š(Ú×åï·«à•ïi`ñ´lºSöñ9 @aŠOíâuU¾LbÐ1{¤Ë¢š¼> endobj +2135 0 obj << +/D [2133 0 R /XYZ 85.0394 794.5015 null] +>> endobj +2136 0 obj << +/D [2133 0 R /XYZ 85.0394 229.9393 null] +>> endobj +2137 0 obj << +/D [2133 0 R /XYZ 85.0394 85.432 null] +>> endobj +2132 0 obj << +/Font << /F37 803 0 R /F23 738 0 R /F21 714 0 R /F41 940 0 R /F55 1040 0 R /F48 955 0 R /F39 900 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2140 0 obj << +/Length 317 +/Filter /FlateDecode +>> +stream +xÚ¥’AOÂ@…ïû+öØ:Îìì¶»Ç!ZJbB8  jŒÿÞ-X¨OfO3ófòÞ—%‰þ‘41ÄN9™8 ÉȧR |ñ³ MÔˆ¢¶ªSˆ›>'Ò‹U,‹çÖ- h-Ébµ:@ ¡?Á4ïu£î8ï²<ŒÈéDéd’å½ác)ƒ^안Á}šÏÓ»co:¤ƒl.‹‘ÈŠ“­¶uB®=½‹ÅåÊ' vÖÈO_ sJ–B£™›Î›˜‰‡ÓÁÖô°z!(ŽÕŠ$8cÔ/ÆAÌŠ0Òyq;žÖA¼œ[èPFJƒÓ¤ºá¦Zï6ëêH`öµ¯ÖåþXt·›ývW½~”ñ`uˆ+îñdð߬ÎB'ÀÖª3†v.•ðËqcªGl/¬7T/½óbendstream +endobj +2139 0 obj << +/Type /Page +/Contents 2140 0 R +/Resources 2138 0 R +/MediaBox [0 0 595.2756 841.8898] +/Parent 2103 0 R +>> endobj +2141 0 obj << +/D [2139 0 R /XYZ 56.6929 794.5015 null] +>> endobj +2142 0 obj << +/D [2139 0 R /XYZ 56.6929 752.4085 null] +>> endobj +2138 0 obj << +/Font << /F37 803 0 R /F21 714 0 R /F23 738 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1610 0 obj +[706 0 R /Fit] +endobj +1463 0 obj +[706 0 R /Fit] +endobj +1215 0 obj +[706 0 R /Fit] +endobj +2143 0 obj << /Type /Encoding /Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity/lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal 144/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis] >> endobj -1627 0 obj << +1644 0 obj << /Length1 1628 /Length2 8040 /Length3 532 @@ -9515,7 +9622,7 @@ endobj stream xÚíte\Ôí¶6Ò ˆtÃÐÝÝÝÝ¡Ä0 00Ì ÝÝÝÝ’‚R"‚´t ÒÈ‹>ïÞûüž³?³?½¿w¾Ìÿ^×Z׺î7¶‡Œ5Ü ¬‡¹rðpr‹ t´P(ÐWç…C­fL9g0ЇÉ]Á¢#°5@ ðòxDDD0rp'/gˆ­+€ù‘ƒ…ý_–ß.+¯ ‘.[€ññà …;9‚a®ÿã@=0àjØ@ `€œ–¶‰Š¦€YIÓ †P€¶›¨C@`˜ ˜`w@ÿ:@p˜5ä÷Õ\8¹d\@€‹y {‚ÀN¿!v€ØÙââòø €¸l0×ǸÂêfý[À£ÝþG“3üÑÃñ{$Ó†»¸º€œ!N®€Ç¬ÚòŠétµºþÎíy„p›GOk8Èí÷•þ`4¨+s¸‚=]粬!.NP ×cîG2'gÈn.˜í¿°œÁ¶@gk(ØÅ呿‘ûwuþuOÀ¹=ÐÉ êõ'þÇëŸ ®.`¨ '&ïcNëcn[ “ë÷¨¨Àlàî¿ìÖnNÿÀÜÁÎ -Äü{fXE­á0¨ÀlƒÉ¥ w}L `þŸu™ó?×äÿ@‹ÿ# þ´÷×Ü¿÷è¿,ñÿvŸÿN­è…jÁ‚ÿxcê€ßÌs:B ^ÿÎýïžFà¿4þ;Wàc!d`¶Íàáäæù €¸(B<ÁÖÚWÀ}¬Ô»Ìì …ÀÀýSL7÷ß0};Èö»ôA`˜õßå?6éx.SU}9=¶ÿöªrèA§Ë‚GPè¯íÇ9pÕ÷rþo:# ¸õ?¿ùdeáž^7Ïãú=*áðû7¹ÿñüë¬tu†x^psr?Fr~ÿsÿÎýOÀìo4 +Äü{fXE­á0¨ÀlƒÉ¥ w}L `þŸu™ó?×äÿ@‹ÿ# þ´÷×Ü¿÷è¿,ñÿvŸÿN­è…jÁ‚ÿxcê€ßÌs:B ^ÿÎýïžFà¿4þ;Wàc!d`¶Íàáäæù €¸(B<ÁÖÚWÀ}¬Ô»Ìì …ÀÀýSL7÷ß0};Èö»ôA`˜õßå?6éx.Mu=¶ÿöªrèA§Ë‚GPè¯íÇ9pÕ÷rþo:# ¸õ?¿ùdeáž^7Ïãú=*áðû7¹ÿñüë¬tu†x^psr?Fr~ÿsÿÎýOÀìo4 0Üú÷äè¹aÖÃöOÃoäæìüØã?ûÿxýœÿŒ=ì a.ÌÁAb¡ö™9Y® Ä£ò/z{xœ*Þè—ÖÁ»2#×Dj,ïêÃ8›ÇEµyÍî;Ýoª²n öA™ºÓÁß‹(üèX>ã.3v±ms™W`gÅúϨ¯"› rn­êèš—ß¡RŽwð9£_²Ò¹Ð_8=óe4%v>oFÀk(Ù?`LÙ½¼`êú4ð±ûåÃ&9[~ƒ˜;26cLà«|r)Sƒj…×Íl(ßÛ b¬Å7ÎßÊçÏVð™h9Žù,¢I‚°RÊ• e®äß·RÆ%=²ìÙ êt›œ(†Ì%³LÇî)®Ž>1Ù¥‘„µ…^Ñ2¼éˆO£Ý %õ‰>•pjÕr{2–ÂwÍ<–g¬™-j—!3cäáakIè,AŒ$ÁLˆÇÆ‹J¯³nöùU»Ïm›Þ‰D3 @@ -9538,35 +9645,35 @@ $O t‡Í=žÝbóÆÃwî6ß"£“˵?”JËOP2RÐ oQo+†â1)©w†¦ÜèådîI½ÈZ¿VÍ­(e÷åû È"QÔüFØs(úF$'‘qL ®/¶!õÔ ¤HvkÖ‰Œh¼È‰¬ê؉á¶o?Ùa:Šÿ±qêcŒ° gã!_QÇ~ÏWê¡1üaœ¯UÝGmã§Yñmn%ìRãr9÷¬ß0qˆ5†/‚E…(êÚ“†,W‚˜$Ù½ï¶åçLxËÎÔ|ú奕£w†Z|ÂV€ãž÷,éOd ÞyŠGÝ ŽÎ¨Ý3lÍ4©¿Î\×T2Zª½Ag—.7Ù#ÏPæï™v¼eŦQLÞ»±Oþ¼Ô\’ ¬ÿĵJÅñ¾(š3Ç].Å*,MÎ>ÛBx(ÃSÃó|D³uû‚Þ¡ï†{:Ò‘Á¨2G9¡Cê{É•<|?ÒK áéá@F)Ø,êw÷ó?È ¸¢Ëa„Çh%Ù±o^Œñ{‹6™Ý @¥-«ä%Å~jÉwXjz1îi´·î¬%uÕ3^¿±g¸`d+ÎK[ŽDe—„]âò†YèÖýÇ?Ï>£³HjË,èkѸÍhÔ8Š” ™v_Å [ªJÖ®²9m=·âú?\‹k>¼à¬‡¤*³Ñ³ž,Y ê<‹ý¹uÓ Z/ZV$S·é#ƒmNOš¨5M@¿§rãÝ0Hõ7¬&7[àçŽAØñêOõƧÈêÚ5±pE6~d»Ž^.x¨T1¬µ¤$£Í7¿ÿ4òÆêüj§‹G1¬èípoóÌ3³QýÐZ:œNÍÆéç,0½‹ЇZg‹ðâ£à)‹Q©¯³‹X""œÛÆ0ÏÁ¾äBvFA‚)Y9(ÎYÖý…ì¬S…|¸Ôü¾“qbæÇN.LÔX§…_ï‚¿œ%%½¥åŒìé|°D>W²7}C–Í#—ZR¸­$º`bÛGο…a¿9gÝS%\”Á/œîñhC|?s§ Ø…šg¯ÎÙÈ)ª¬m}ÐvÖËk†Ÿ.bÉ&O üõí+uqfº`Îa‡„°£â,I§ã¯½/‘˜÷ÇÝ›Á¤'P6ߢH‚Ú?÷›½šÙ¹˜Žà9¦ŠmHr7:pMRYŸ#£ 'æW¥¿ðKCß|-¡mWÝ躖ná²¶Ë0–«ÞÐ3äÛÙ=j’¸Ë-,n–³e±€¢üb½iÙ;‘˜Hâ°l<)žL.ßÐYÖÿ°Ú·)wL=(‚Œ£± L|)=å'ÀÆ-Å@²öò¾µ<ÃNrä³6îµEôʃ3±d¶kÓ»¬ÿ‹%ôµøü·(kD~ô(¬_yñ‡Í; ¯åä²fùOî{&*‰äyÒ¯9ÛB±T¨d>è.òY[a-³ZyÏ•px9ÝØÜ>穾„»*|,4°ç Žð=Ï añŽ©{ZwLVqžCÅo, H;ç_7Gg[åGx d½DŽ…*~ÂJSÛ/ *ûÎÔF‹µëújQ‹jw Ý]_-Òq;Œ,1t³õ2ߥÆíËòê{:Ö§Ùo$<×ð¬žôôJ©Àëóüλì„b›F=ÍçåcT”u;ÐuË›÷#³»Z1q“ÒYÖgHŠ^fiyv|‰¢,PkŠA±¢FH£s^…EËRôƇnQWEÛt%Ú·y3™{æÈŒõFbKã<%Æ)â"-L+{墒zS'“#é²ÊòZÃ+•÷U­Á׎#Ç©ÃCcæHŸ,êä;÷=íÏô .óYäg:¯jÔn¹¶Æô×êS:c¤¬UºW¹Þ/Ëf¹ŠšcO¥ÛøŒM¯lD‰Á¦9²ú:­ÈùÈßÛ˜ìÑËr6½õx§ç±2ú]úS¹‘ p7O¼,j1îöÐËÚ{ž$ªS7O–xYŽróæs÷â»ì(è˜Ýš‹ÏD‚@§­Y#žC²L%¯íáž›1A•ø©3¾~M+ÖAîDí>¤¶¯cãµã-Nˆ¥”ûÚÔß ÄÖtzâ"¹tãØ'>(˜“”hSðÕœM]ˆÎÛ…0ìŽ ñâSPÓKD³—dOj nÌó®|KHtÞ‘Ñ+㢟S'÷@6„iõ“¨C,÷ág3B½žpÖáΡÄêφÖÑn‰Ü;ɦc“ _7T,Q1çTiHøBÕWL8­¡¾  ,œ²£.±ß u2†)¶=–Oš ¹ÿêÚ´­Ùê², Aq¨¿râ^T!1í¢ëç2)áN\§‹¬‚)æÄËR…Ëbž÷ž6Cb5ü´çêÞ›Ô;ð¶¹mH“üÅL¸^Ȭü¤Ý¸Ê {>«m@Ë›ðzéN‹›´×»ÔÌÃBÿ]¬—š@)õp[jÊâá…6ë¶¡²BSHQø×¨.öØ«N÷Ž`ðG¿§zŽ^n)?ìû±«892ÉÿxÈÌÄ÷Ù%¼­Ø3ÕÎZJðô]\ÿ^¸Äé„SXA㣅¸r}[(â0Ò@¥elöÉmi¶ö­EWÕ9úQѲ´ˆC¶Û¯µAñ=°g>MF{Q’= †*Ëk¨+™×Øõµk¤i@ïħÕW:x<›ó"Í}<=<²šC½Q¤4Æð÷i©UµSöA-ÒiMÛk×qnñÔÆèO“¦R<)D¾€÷/ÇT#î¡ÍM© Æ$ÖžåÔ3³Ð¿Á¢\ç{Uª÷Þ<UW=ˆ$®&<ƒªZ€0óØÒgÒR*¹ÉÒO¦1‘'£ùŽŠj*5wË-·‰ûùT j4ÝióÍu``òh߯µ“K…ݻʔÑk‡‡A›”ôÈÔDôìtk¯ö2ÅÛö÷ú—¨§$ÌöZ¥ï@Î^ùÝêõ^E~§”Üúí¨u4߉<*ôޱ§¸KJßùy/žn•C*}…ÃåLgI£J·8jŽ[“Þ³ ”ØT7%JÈOïä,Á!ØžÈ+ÌÁ¯f—ÉȘs‡h`Úq¢O”1£<ƒ3(©dØOfBOŸ º'"p=Q£B¿âäpJ}ÝØü™ŸZ®¤!p{òëÈa}÷qÑ¥³äƒ£DKXôžòxÇ(žÏÑã ©¨“{ÏçÉšj¿dqX·ã·ŸP¦Üv£ä£Ï€³i¬¾AÕ;³@øyŠ*œoLœOœÕøë…ú¾›ºxOÛÝËc -@YšUʳªø;žBiäMÖð.•\rž;ùU´¾Rø'î…ç)眄š˜ …@ƒi/_ A®ÉéÙêr«0áFx<×Er;¾zÇ´UÏšøSÂö²Ù„.¥mô÷Œhâæ¨É2Ø’ç/{I;õŠjÑm÷¬ -*s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€޶Xo³êÙ}U¹ôZø: hÁ‚)8f÷EµÔëÛDäµsüð¢ qTMŠ:ù‘ɸX!±l®ûÔ”Ëû ΄,ñº17ýbŸgûŸ&fܽ×Y'jeAt ]ôÛïwV^þ%ÑåµÛR¼”tμ‡Ël¥¿é˜¦j¹„‚øÏ¸3èm>YjŸÖCƒÕ¸ÄžÄÈÊjbÆn“ªŒUý©?ô‹ïðu«ÈÃWøìý#ë,M€¾ߥJBQlމâXè-ebtxÃ]€s<—ÿ¢:XÝQ…¸w¶²-N;N¾?Vl¤‘vG‰…,Å%ë9êçöË'bìη9|1.…±!]¹¶DšÏó=RԌݬ¤Iˆg‰=Åh_ìŸ5rÿ/˜ÿŸàÿ  tv…;0ÿFsõ·endstream +*s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€޶Xo³êÙ}U¹ôZø: hÁ‚)8f÷EµÔëÛDäµsüð¢ qTMŠ:ù‘ɸX!±l®ûÔ”Ëû ΄,ñº17ýbŸgûŸ&fܽ×Y'jeAt ]ôÛïwV^þ%ÑåµÛR¼”tμ‡Ël¥¿é˜¦j¹„‚øÏ¸3èm>YjŸÖCƒÕ¸ÄžÄÈÊjbÆn“ªŒUý©?ô‹ïðu«ÈÃWøìý#ë,M€¾ߥJBQlމâXè-ebtxÃ]€s<—ÿ¢:XÝQ…¸w¶²-N;N¾?Vl¤‘vG‰…,Å%ë9êçöË'bìη9|1.…±!]¹¶DšÏó=RԌݬ¤Iˆg‰=Åh_ìŸ5rÿ/˜ÿŸàÿ  tv…;0ÿò¸õ¼endstream endobj -1628 0 obj << +1645 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2122 0 R +/Encoding 2143 0 R /FirstChar 67 /LastChar 85 -/Widths 2123 0 R -/BaseFont /ZJTCSQ+URWPalladioL-Bold-Slant_167 -/FontDescriptor 1626 0 R +/Widths 2144 0 R +/BaseFont /NYULSI+URWPalladioL-Bold-Slant_167 +/FontDescriptor 1643 0 R >> endobj -1626 0 obj << +1643 0 obj << /Ascent 708 /CapHeight 672 /Descent -266 -/FontName /ZJTCSQ+URWPalladioL-Bold-Slant_167 +/FontName /NYULSI+URWPalladioL-Bold-Slant_167 /ItalicAngle -9 /StemV 123 /XHeight 471 /FontBBox [-152 -301 1000 935] /Flags 4 /CharSet (/C/D/E/H/I/O/R/S/T/U) -/FontFile 1627 0 R +/FontFile 1644 0 R >> endobj -2123 0 obj +2144 0 obj [722 833 611 0 0 833 389 0 0 0 0 0 833 0 0 722 611 667 778 ] endobj -1608 0 obj << +1626 0 obj << /Length1 1630 /Length2 6133 /Length3 532 @@ -9578,8 +9685,7 @@ x Òy¦§aáèha …«pJ핎 HÀÈ(ã ±@Bá0Y $D¤±ÉB¬@¼¼ #Hîìå µµC‚XnxXÙÙ9þ²ürYzý‰ÜD" ¶0Ó̓;Äîì!o(þ×ZiÙ@! u %5‹‚šHƒ¸Þ¡áf鵩@­ 0„dw9þqYÁaÖÐ_¥!¸n¸¤ Âb½ ƒxZAœA gˆ«¸yA [W ò¦H8 -³rt³þ%àÆnÿ-ÈÙ~ãátƒÝiÀH„•+Ô ºÉª!+ÿ‡N¤òWnôÁmn<­áVn¿JúÝÐÜ H ( BB<‘¿rYB@ÖP„³£…×Mî2gWèon(Ìö/ Wˆ­…«µ#¸¡¹áþÕ¿êýSõÎÎŽ^¿£á¿½þ¡ŠD@m¸<¼79­7¹m¡0ø×º(Álà î?ìÖnÎbî×ß bùµ3¬7",¬á0G/5ÄVƒ#oR‚XþwSæúÏ ù?0âÿÈ€ÿ#ãý÷†û÷ýÓKüï¾Ï§–wstT³p‚üýyÏ€T@¿.Я›jõ?b,œ Ž^ÿ*êïžz?¤þ"û;ö·Ìöf&œ"\"X¡y¨'ÄZŠ´²ÙX8Þtë·]f qu„ 7SýÝP'7÷ß0m;¨•ìWûþ€ 0ë¿k¿Ôoå`Y=ͧ -ìÿúvýí«q³Hm/gè¿é©Â­ÿqøÅ$- ÷ysòqƒ8ùnäðp ñDø|þEÖßD<U-®PO777èæ÷Ïï_'“¿ÑÈÁ¬àÖ¿öF i³¾Yµ~ÁVn®®7þýößþçù÷ÒC ž+ÀôÜJ,Ø>5# YEžÓÓ/kô¡ƒ£'ŸFûu¾¼Ý/5|Q¤Ìü¢2„«vPôªÉk|ÛùrU™m­·ƒÌ‘¹=²—GåCÏú>ŸhžéûZ Ø´?í«^”÷þ˜Ê¦¡ ·îÚR¿æ3Ó¢‹{ÀÁw|®Øû§¬þôîùþ¤ 'ξV)o_=h!¬½E\U°ý•)aóô„¹«ïcOwûáÝ÷«”ìÙ¯pÅÜ1ñ™"ý]²)Ÿê”Ê•¿U»—w„ÄêÄ‚‡_)x¾¼–‹ À:7ÒD/–²‹óP'òÆ€,? N¸vðIn+\£š}§Z(Åç^XrˆL©GXrŒMß—ìdc§ õÕwÑÏíK +³rt³þ%àÆnÿ-ÈÙ~ãátƒÝiÀH„•+Ô ºÉª!+ÿ‡N¤òWnôÁmn<­áVn¿JúÝÐÜ H ( BB<‘¿rYB@ÖP„³£…×Mî2gWèon(Ìö/ Wˆ­…«µ#¸¡¹áþÕ¿êýSõÎÎŽ^¿£á¿½þ¡ŠD@m¸<¼79­7¹m¡0ø×º(Álà î?ìÖnÎbî×ß bùµ3¬7",¬á0G/5ÄVƒ#oR‚XþwSæúÏ ù?0âÿÈ€ÿ#ãý÷†û÷ýÓKüï¾Ï§–wstT³p‚üýyÏ€T@¿.Я›jõ?b,œ Ž^ÿ*êïžz?¤þ"û;ö·Ìöf&œ"\"X¡y¨'ÄZŠ´²ÙX8Þtë·]f qu„ 7SýÝP'7÷ß0m;¨•ìWûþ€ 0ë¿k¿Ôoå`=9)Ù§ìÿúvýí«q³Hm/gè¿é©Â­ÿqøÅ$- ÷ysòqƒ8ùnäðp ñDø|þEÖßD<U-®PO777èæ÷Ïï_'“¿ÑÈÁ¬àÖ¿öF i³¾Yµ~ÁVn®®7þýößþçù÷ÒC ž+ÀôÜJ,Ø>5# YEžÓÓ/kô¡ƒ£'ŸFûu¾¼Ý/5|Q¤Ìü¢2„«vPôªÉk|ÛùrU™m­·ƒÌ‘¹=²—GåCÏú>ŸhžéûZ Ø´?í«^”÷þ˜Ê¦¡ ·îÚR¿æ3Ó¢‹{ÀÁw|®Øû§¬þôîùþ¤ 'ξV)o_=h!¬½E\U°ý•)aóô„¹«ïcOwûáÝ÷«”ìÙ¯pÅÜ1ñ™"ý]²)Ÿê”Ê•¿U»—w„ÄêÄ‚‡_)x¾¼–‹ À:7ÒD/–²‹óP'òÆ€,? N¸vðIn+\£š}§Z(Åç^XrˆL©GXrŒMß—ìdc§ õÕwÑÏíK ïeë[ă»4fÖ)Æ»'c£»¶*2‡Ìu•ÙÖ£™øM×E;k"±{åè!6ÙÏgø¹a1ù‰¢§.Ô¶3àéÉS®Þ?pUì!¸?Ñ='g€$NúüVž;»;l"=+±¹ájy4&ôøë´}‚ÄÊ¡æ °Q™Ä´îÃf¤'²š‹8­‚{@|[÷n½.\ex~ûjÂâSÿ ¾jrþ¶áåkï}6KiÕI†ú€±s=Z9;ªîÕÒ/7ö[;_NÉö[BÔrw–mF¨¹]žÒ[¯éÇhy;Iþô|“Pâ±_®Ô(\{Er¿—¤ÿ}á÷,˜4½‘JÿШw‡5Z!tÒ¦(¤Œ2x<κ¶grú>0.;¼½2qøÀaZ.Ë©EL_GHx5tÕ;’T1•\,ék?‹n·‡âø£ÚÌßÒ¸nòTÀÛö• atÜÌ‹•±Õ]ç°ÊÁ†Ó%¿2þÝ{ÕÄÙ )•埉>§«#lð6šo;Þ^Ùû¡LÿUjIpÈ(F²Ó®èê~ï}=z8Ö>ß’»0?u>Ægòv[?Îú 3MØĺ??Â6ó–¸GK让ÆÂ¬—–Q„tÈ¡f´µ 8™ûÌ⟠é?;©ª•Ò {=ÕtvWŸuéR^.„«È‹zY½Ît+@½^V×^Ml¬oJfE([œ]£–å›'â#å|'OF˜îˆŠÖ¡3ûÀ~.IZÀH)L›‡jªrÌg¬±Þ=•u«Œ†t®q©,xÚ3À-ØËpõL܉'òA€ªC0[&µ{C iÇŠ¤y)>û›çeLcÑ%/³FTU§€ÙÕô¨5« ð ½’•sJÜkŒ "êC 3ó®cUÉÙ4eHÎH~0+¾÷ìEÑOÁY^€ÝˆF›ÍŽTU§h§D´çéíçǽ8IÉ{éBDWžñ»ïÝR±FêÏVë®fûÆÊ¦îíqßÇ´L…ŒJ®GЧzTÅ‚ë—âƒáJM î;£2þñN÷6…OŒHâÑ ìÞv­øózy¥Ïgg)Õ‚«?Y¾„ѼN-áf_6ÄG¦ ‘”Ï w÷‰·8I•w…p¤Y%K:¡–-@2GrMú 4¨oêÞPÀ-Ýë*õk¥sj€#}–ÕǪq.‰ã!Åp£Y2Õ tÌ( ]¡ÀC»ëƒ;hbЀ16gRtVwšÇ>oõ;#m½YÐá³0zuœÎkê @@ -9601,81 +9707,127 @@ V1-S ÐíC¡Ówï»ëÉ“º¿Zèp½÷äOô>/¨lÝ4nlްU-oMôÙ“ˆ o:œ©Í|y„7MT{õ ¯=i3RÇVHA9jQ¾rÁ3ãaÂ3œ´X_¿ÆdhÚ—E/Oö\ìKɬÝOõš_·— &†÷ê$ÀuæbsAƒytN.`.šâb™Ê¥܆€ð6é瘯l¾}êÈg|ëwRŠžhXŠs×L84ØGê} 1Y³mgzÑìÅÓŒ$»9ñNh‹Í”ŸâÕ÷ºXsm{Ôg"'H±¨ª®RU\O¹<Š>ÊlSñ" ‰ôt.CB±|…—(z?п)|Æö…›‡8csa4«ªy=~U»+jð*Ì8Ó“«&ÐÐåÇw?´,IpöÛ7oå¡#½Ëõqw¾}eüJü¢šïUølœ]Rçm‘LغÂ=Îk¡·ÐóKJ;œuY8:B.²åžðŒC\„0&õê®X¨ÕåsÊ;2•©`‡¬#¿Ê"ÿÿátökä÷g\âiì.¯(å»T·RÞç-ɳ/%º‘|™÷ó§qWru?̦hΑê¼7ôòÀ…U^ÎK:%į v›AŸ7pè1ÌÇÛtOn4 ¹Ø+`‹ï—Rp 36‚FŊݹÎ%:b‰»•¯·0Î&SwjÒ V‹­C%#N^©Û™KuÓÏy,ÅEŸq&¨ãò8¿ªÊ{D LGÌ8½UTmÚ5leUÍ?6¹6ÞÒ6!-+ÁöŽ·¶¯T(wu9eQ–éáö:Jmš»4 û_}ö~N†ŒÁOkôÚ‹Ö»µ§½Mìð}íîɲư™qÀ“ë`Á+–»5ãéö×­d[%˦×÷[M–ŠÁÃ#ߦT\Ú*wqªÝ¯¢Øg”‰˜÷Õžà$²dß]Í|®yó9¾è?)ì#IiwñùŠ€%z :õÔÝ3°ˆKzW†Fc¾òm={‚ú³8uL‚ÂôwÌY«|í»U&›±”n{ÀeóbL=Xûy*áwSYø"FžN†j×'›<ºÚyÍ7Ì4`u¹§h‚Žï›Ô'¥o¡í×ðê•Ã=)2—½«ÓõYæ©9rd…Y¾qÏà`ÞrR‚›FWM†Ð¬Œz¬ì^ãë[‹=Cù¹‘©nßíÈQ”iÇ5ÒoÔôÈ[A}s…mºŠf?´?“½Ë’: Ÿ’òÏ -M0 V”µ@¦ØRšÁSÇ8${^™æÒu”œqÿ›ÀÿüŸ °r„X¸"áN®€ÿ'yžendstream +M0 V”µ@¦ØRšÁSÇ8${^™æÒu”œqÿ›ÀÿüŸ °r„X¸"áN®€ÿÕyˆendstream endobj -1609 0 obj << +1627 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2122 0 R +/Encoding 2143 0 R /FirstChar 66 /LastChar 78 -/Widths 2124 0 R -/BaseFont /DGWQKG+URWPalladioL-BoldItal -/FontDescriptor 1607 0 R +/Widths 2145 0 R +/BaseFont /WCEADK+URWPalladioL-BoldItal +/FontDescriptor 1625 0 R >> endobj -1607 0 obj << +1625 0 obj << /Ascent 728 /CapHeight 669 /Descent -256 -/FontName /DGWQKG+URWPalladioL-BoldItal +/FontName /WCEADK+URWPalladioL-BoldItal /ItalicAngle -9.9 /StemV 114 /XHeight 469 /FontBBox [-170 -300 1073 935] /Flags 4 /CharSet (/B/D/I/N) -/FontFile 1608 0 R +/FontFile 1626 0 R >> endobj -2124 0 obj +2145 0 obj [667 0 778 0 0 0 0 389 0 0 0 0 778 ] endobj -1383 0 obj << +1399 0 obj << /Length1 771 /Length2 1151 /Length3 532 -/Length 1713 +/Length 1712 /Filter /FlateDecode >> stream -xÚíRkTSW‘ª¡¬òRIÕzX%2yj   `, ‰¹7ä–ä^z¹¤D|PIU–EltÉST” -«Š@} Ô«0|‘VXŽƒT­Š€¯¹`]]¥?g~ÍšsþœýíïìýïlšG”Œ!‚°p(† “#ÁR©„Ãä™Í¦ÐhÁ8¬  Q°p¡Óî -Àæ y+„<>…‚±tޤª àLŸ$ñH ãˆR©‚PÃZ²†R¡2L‰À„ D X7y#¬ƒ3`<†˜@ˆ’áT¥°&5IPøoaH—þ.• ã¤(à5%“H‘†j ‚UÖŒì“Zþ²¦Õi4kÚÉòSNý%¯Ð"Ãï L›®#`H1ÆÑéÔXø­8) !:íô¬„Ph¥MÕÀ€ÁYÉd¯|‹#¡ˆ†¢B©*…&žÂaš®„ôoJ+V'yÿþµSÉ(‚цt°ÿ`OÅœ?bÒ$у6“ÍæDr¿;%Mk&F•„ ©€Ëó -W(ä‘9A!X`=©˜ÅD1‚¼Hgr€ -Ã)“ÿêÃ, œ‘1‰¾¸€•:9{¤{“Ø_Ÿ„éŒ\ÀàòÈV앾€Ïcçü‰¨Ôá8ŒSãCô.V!¤§0¬‡•ëMLé·õÓ}§·×䊫:ÙÓ3šlm?¿í”Ù9Üëçroü)þè7çmΟ"ÇJF"¿aA*^õ´(Ûb”±¶õ8[Ýèûe³*‡“g\.kký@{pÇ=ëâÁôFï‡?{>»›yÞ¾nõ}¿’:R8³æÖÍWOrÓ6uôY¾†<‡J(IegVï…åÿ¼[tuâAV…Y«/ÏOÜÿÌõµ•Úz§;í¶£Y`*“ÚÝ0û¿œÃ¦ëUýδÅÖ¸RA„L8{¡Ïuy¹Ø|èïaŽ hnŠ”þ:{ ‹.ð0¿ß-ÉÏ) •ÄŒ.8V᢬Y ñ«¦ÚÂõ­ë[´èÅ‚Áúµù.iõ\ÿbNzã^Úº”ñW´ß–ìœù4éÅ‹ÞçoLÔ–‡J£‡û‰±Þ¾3½¼‡éílªýµ/,ñ -õW÷Q`x¯Ã*S›öïýÙÍcR'¸‘çvóèžV.å¾p\»¯üoÒõÞß6Yö$Šõ6‚øKèÇý•þu©Åt€›œÐ›r6ú–÷åÚ† U!®µ3“,M¡¡UKšfc=Aó=\úÍu%Fõ.ëÅn}Ñõ¹lÞÄø¢ãBŸƒÝ/ý†~*‰±4ŽñY”k?´eAÚ.æƒèåFß_íÎGÖ¦:}kOZ~œ·lÍX»/íxMdÍv­á±`ÎÞc‚úG»òìsOEM?¨Êð"Pç¹éÙrzmÕÚÇ„SQÔ‹Ê&x¶¥ÅÑÁãÆLîÙO6ðüS_wYw¨Ú¸{ÓÃÇ·V.Ú±"tèïPÓÅŸ—ä¾Ù:Ú¦sp7µ'XÑ{ÇÌw~ìC[ÎrÖyúÇ}³4 …Zwác«Ö2¸Îªh#[ï]hÛ?Aƒš+µµn4Èmðr"ÕËên‘º~/yêŽZšÓMÛC ÚáW'«Jä¬ÜÁžU§|<ˆÕc•BT¶TrZ³ÜfÆ™cOJÜŸá›^ ç7”ï‚oWD­­˜ð¿Û5¡Ës½2RØñË™R•ôM‚loÊ|U–Aß9/«©«tS¹>˜áµõÌ'Æ/¹_65n¶™‡¯‘DAßÙªÛ·_w½.wÔr¶Ä -ôÜçGã:òíÞÏ)Œ R?CMKëÆôûëÂKûŽî¼”óa宗ܽT\òÚ6^^7Ôn[–x˜+tiT6Ö›ö\¬,vüX® ÆK£ó•m·“·D KëNìvØÁ9¤Î.îš[Ðì?ØS1ç˜4 Gt ‘Íd³9$‘ÜïNÉÓš‰Q!hàò|€Çåz +9DdÄ@PÖXG*f1QŒ ¯Ò™\ ÄpÊä¿ú°K gfN¢o.`¥MÎéÞ$ö×§a:c0¸<²{¥/àóع"*´8£ÄÔø½‹•é) ë`ÅrSømýtßéíµyâê®cöôÌ…¦#[;Îo;eòc÷ù¹\Ç›~І?úÍy›ó§Èq§Ò‘ˆoX’×O=-Ê1d¬m½ÎfG7zå~Ù¬‡Šá¤”—ËÛÛ>ÐÜqϲؚÑäýðgÏgw³ÎÛׯ¹ÏáWQGŠfÖÞºùêI^ú¦Î~‹Ã×çP)%¹üÌš½pì?ï_x†Uc–šËó“ö?s}m¡¶ÝéI¿íhË¥v7Lþ/ç°é:å@'…s }±%¾L°Z&œ½Ðçzl… Ø|èïaŠhiŽþ:{°›.ô0½ß#)È- “ÄŒ.8V風] ö«¡Ú më[5èÅBkCTKzC׿„“Ñ´—¶.uüí·%;g>M~ñ¢ïù#µõ¡Âàaã~bFœ·ïÀ,/ïaz›jí ³G‚\õÕ=BÞç°ÊØ®ù{à@N˘Ä nä»Ý<ú…§…K¹/×ì«ø›t½÷·Íæ=Ib áúñ@Õ£]j5঄'ö¥ž¾å}¹®ñBuˆk]áÌdsshhõ’æÙXï`Ð|×…~sDIÖh Úe¹Ø£+~ :—ã›_t\ès°ç¥ßÐO¥1榑#>‹ò쇶,HßÅ|½Üàû«ÝùˆºT}—oÝIóó–탢sQûÒ×FÔn×è æì=&hxı«È9÷TÔüƒ²/õ^›ž-§·Ó6\©{L8G¾¨Jeâ g[ÛPµž7dqÏ~²ç—”öº'àȺC5†Ý›>¾µrÑŽ ¡Ã@ï €š!þ¼4ïÍÖÑÞ0­ƒ³¸¹#Ñ‚Þ;fºóc?"Ürî³ÖÓ?þ›¥­Ôú ÿ[Åà:+£ lu‚w‘íÀ j©ÒÔ¹Ñ 7ëå yš—ÅÝ,uý^òÔ5·d·‡´Ã¯NV—Ʋò¬½«Nùxkƪ„¨l©ä´z¹ÍŒ;3Çž”º[Ÿá›^ ç7Vì‚oWF®­œð¿Û=¡Íw½2RÔùË™R¥ôM¢loê|e¶^×5/»¹»lS….˜áµõÌ'†/¹_66m¶™‡¯•DBßÙª:¶_w½ë¨ál‰è¸ÏÆwؽŸ[´šJý 5.­Óí¯/³öÝy);æÃBó]¯X÷2qékÛ„Øú¡Ûò¤Ã\¡K“¢©Á¸çbU‰ãDZê`¼,º@Ñ~;eËêai}ã‰Ý;8‡T9%Ýs [f-ܹùg·Ç˲d•_¯8Ï/ÈŠ=Êëœó½çâb¥äž*×L»'î ÏyøÃÐ{ö!£KžÄ5¾°ªúÎøV”H†¯t‰nµí¡Õu«›kÊ +÷HçÖºlx/ÌépÇá5'ÿÝ%¼ÏÚǩˈ—¯O-wûVŸZÌ é1> +k]“ ¡GZ±ǵ}M.íÌü|QYP÷]#ª”ÆÎëåù¿ 1²FêD{õþ9œ˜|V@û,|±ÀnÖý®&|þ]j p삸5ùZï—£Q;ù/-É,zr1CN¬êáͳl|šy¸ šZ7Àþåÿþ' +(Ô°'0O§üQsŒendstream endobj -1384 0 obj << +1400 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2125 0 R +/Encoding 2146 0 R /FirstChar 60 /LastChar 62 -/Widths 2126 0 R -/BaseFont /WVJXVA+CMMI10 -/FontDescriptor 1382 0 R +/Widths 2147 0 R +/BaseFont /QAQSBE+CMMI10 +/FontDescriptor 1398 0 R >> endobj -1382 0 obj << +1398 0 obj << /Ascent 694 /CapHeight 683 /Descent -194 -/FontName /WVJXVA+CMMI10 +/FontName /QAQSBE+CMMI10 /ItalicAngle -14.04 /StemV 72 /XHeight 431 /FontBBox [-32 -250 1048 750] /Flags 4 /CharSet (/less/greater) -/FontFile 1383 0 R +/FontFile 1399 0 R >> endobj -2126 0 obj +2147 0 obj [778 0 778 ] endobj -2125 0 obj << +2146 0 obj << /Type /Encoding /Differences [ 0 /.notdef 60/less 61/.notdef 62/greater 63/.notdef] >> endobj -1062 0 obj << +1139 0 obj << +/Length1 1199 +/Length2 2269 +/Length3 544 +/Length 3057 +/Filter /FlateDecode +>> +stream +xÚíWiî'Ì5"1@6>”/È ü”Ô†AfR  rà%±(ß Ë0™ËbÁ:}9)8öÛž +Á%‚`HFö3É›÷Öím\8m!®ýüŽn›ÛÜg®¢2Î7Šæou’ :)§WEöúì'üÚ·kPÝÓØ6Ù¬2yE/­"oØ¿QªšóR5µº-NLfJÆoXð~1êŒS¨*­tï×0–ZL˜r¶§Ç¹à÷xÍÖØÀ„}yB[¯\¸ûA}«·Ð…Wó5Mâ~}ý×,…õãï%Û!9uoýå¼Nâ›o_ÑY ¨l .žæ…”êoÕÝ2¬ÕuÖ•ö&¡ÙRóÈúÓܯd=÷T)·–ÅV–MµT<,¾}^C÷\MáþR˾añÁ¦Iø@>P]á)ãЖ¼`k­¿ÅbÑ2­CÌ;uÂ÷„ÌQ…÷yEˆPó@¥ÂNÛöŒvö%÷8»‹DÊÒ”ì~³kZ=O&=78®U¼âE\?¡ àêsÓq¦¸>äjMr¨Üº¤òŽ±Ïƒê®$;GšAöÐÙ}ˆaŠrGݹ#-íùQ32M{? Iô§Lzak„«|…ÜæÝ[“^ß÷Ù‚ü$—Éç±éÕZƒƒ9ñ¦RÃkµvõWË&еb˜!ÝšB¯\L¹¹/Œ”\|­U‘ dh)óão¯Ëû¸½(Q§[¨~"%Ù—v/º p}'²Üô^F„ñ»\?~·‘·z¡<-E)i—ŠYþ³À®]£—vWO ¢m¢v!œ ÆÈUó‚g~Ê~|Éê:žôÚ –żè1œ5ºÝ 6¹ÞʱuÙiž#Z÷f”yÑœ’]^†«gIgRwU©6ßôaØ–Ÿ«œlL +wò² 6óx†l‘}&ï¿GmÛ‹KW2.øf_.䙃’—»yù¹uï°³ÒLÉ=Ò}wG5’ûÃSâwg’±ïh/Ü“V¤¸ñ{]×Àé7(u?®Õˆé±BÅ…6–VÄöìqóÿà*’°€=É­ûðèn^/+3}ýELº]NªbM7¢º¸€4N[YÊɼ}íc­[f¼ªTòÓK%¬ï+;ÿ^òsžÎ›‹ ù.æIIˆUÛÚY±/¦÷ +ûôòH/âÂ+oéLˆËÇO¤Š›9麗òo*d· nFж–Èá)“É.²©¿¿}]dÅ/Ò"Ý•Øk×xyœh¿naM÷½+ƒŽ÷ÇÏØ +OT¹‘ÞúMv±gûS‹J¤ø¬³4ŒX1µ¹Ù1ŽùÎg’új½W¸TZnzW¯]hnÆË~«WÂJ‘ê.68<¢R@ ¹žQ *^?W+kâª~'b M,k"ÃÊ1KšÙ?Lq)ã÷I™¾ßpl‘_Àõæê´êC´€Ï ÞsŠSt±ÔœwÕÆ4Í¿ØOžä¶"òL&l“†U+<|`x¡×‡Ö§v¡DØt-²’»fcf…ày­¥t¾âNiìù ÿOð?A@¦ƒ$‡Lb!£Y þ¡\þ7Cþ ‹Ú@Èendstream +endobj +1140 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 2143 0 R +/FirstChar 97 +/LastChar 110 +/Widths 2148 0 R +/BaseFont /MQZMVP+NimbusSanL-ReguItal +/FontDescriptor 1138 0 R +>> endobj +1138 0 obj << +/Ascent 712 +/CapHeight 712 +/Descent -213 +/FontName /MQZMVP+NimbusSanL-ReguItal +/ItalicAngle -12 +/StemV 88 +/XHeight 523 +/FontBBox [-178 -284 1108 953] +/Flags 4 +/CharSet (/a/c/n) +/FontFile 1139 0 R +>> endobj +2148 0 obj +[556 0 500 0 0 0 0 0 0 0 0 0 0 556 ] +endobj +1067 0 obj << /Length1 1608 /Length2 7939 /Length3 532 @@ -9686,7 +9838,7 @@ stream xÚívgPTݶ-HPPÉ™&çÐÉ™–œƒº–††î&K(HÎQÉH ’sÎ 9#$ˆ€øÐïžsn}ïüº÷üzõvÕ®ÚkιÆs޹VmVF-]^Yª„p@óùž4`ö–Î(]°ƒ¯ÜEXYå‘P0†pP£¡O†P@jÅÄÄXòGw$ÌÆ àÐ×1ääææù—åwÀÒýžÛ(˜€íöà G8ÚCзÿãºP(m XÃàP€¼¦–1HCÀ¡¬¡P†:@‘`8@ËÙ³¨Á¬ (('ÀÀÿZ¬ØïÒP|·X²(€r„ZÁn·Aݬ Ž¿]<G(Ò†BÝ~`(€ 쀾í€9XÁ!¿ ÜÚ­9"·ö·¾[0- ²BÂÑ€Û¬Z -JñDÛ‚Ñ¿s£`·nÂú6‚°rþ]Òß-Ì­ †9 h¨úw.K(C9ÂÁî·¹oÁ‘°?4œQ0›1à ¡6`$E¡nan±wç_uþ[õ`GG¸ûŸÝˆ?QÿäC£ pk> àmN+ômn˜ÿïA9X#@¿ìgÇø\ È? âø=3œ·$À„ÜZðk з)ÿ3•ùþs"ÿ$þü‘÷'îß5úo‡ø{žÿ­ä ‡k€ío௠p{àj€ßwÌÿ ¶‡ÁÝÿMôß ¡1üw 4ø¶ ²6·Rð üe„¡”`nPˆ me °Ão{ôÇ®ï"á0è­–ÚàŠˆüͧg ³²søÝôÇb\PÈß™ßÊó‡7¿ž†‘’‚÷ßoÓ?QZ·ª£õÜo‰ýWêÈ?¿1äänO^ ¨€WH@ôö° ĄżþM¾?@À­ÕÁh$Ì ðü¶hàŸÒÿëý×Êìo0ŠVÈï9ÑEƒ ·£õOÃo·•3y«èŸÓ~[ò?Ö† +JñDÛ‚Ñ¿s£`·nÂú6‚°rþ]Òß-Ì­ †9 h¨úw.K(C9ÂÁî·¹oÁ‘°?4œQ0›1à ¡6`$E¡nan±wç_uþ[õ`GG¸ûŸÝˆ?QÿäC£ pk> àmN+ômn˜ÿïA9X#@¿ìgÇø\ È? âø=3œ·$À„ÜZðk з)ÿ3•ùþs"ÿ$þü‘÷'îß5úo‡ø{žÿ­ä ‡k€ío௠p{àj€ßwÌÿ ¶‡ÁÝÿMôß ¡1üw 4ø¶ ²6·Rð üe„¡”`nPˆ me °Ão{ôÇ®ï"á0è­–ÚàŠˆüͧg ³²søÝôÇb\PÈß™ßÊó‡7¿¡¬ª®¾÷ßoÓ?QZ·ª£õÜo‰ýWêÈ?¿1äänO^ ¨€WH@ôö° ĄżþM¾?@À­ÕÁh$Ì ðü¶hàŸÒÿëý×Êìo0ŠVÈï9ÑEƒ ·£õOÃo·•3y«èŸÓ~[ò?Ö† uƒZ|™BX‰¼LLIB—Qdt ( Ã?V1ñŸx£+w¿³^õ9’e‡Ð†ŠÚ¥ÍäÊu””7œœ¸äN­Ñ÷ˆ¨/ùŠõ.‹ú…'Ð)á0äPùÝÚ…ke ¸éÛR§ö ]8sô&sß±­|*åŸî#>cÕ¯‡‹úœ‚ œEëÑymeê÷AÆ€>8m„ 1œ4¬jõõr¦XÜâd8„²³¤¿V>M¼çÀ7ÁÜ&N\€*ÄJÒÜOµøï8•^Ýçôáö¼J%qõ‡ ‘®.µ&у;ìXBÒ0ÊÚcVKŸ0-SÛ·ߌG?óí·Eƒòñ(€(§¸Ëš’=´øô•ú+y\J6.æê”‹‚œÞ»ó^eúÞ‚·V„(õb*$Ã=AÁžéÌmEéïa9žoñ€Rý3™ÙÑS×!÷8ÎãÒ9‹ÅÕçÜrƒÅ£‘C™Äù\‹-ÕÕ²k±ò¡øáÃÍ8 @@ -9718,104 +9870,103 @@ QH; ‡á{__bçâ.°ßþºæó}<¯½kb¶Þý9\¥™àpDË\TL[\a·¿«NüÆW¨œµ>¿¥t®tÉQÀRD‚!$Dr£G¢1¸AÌý¾ ¥Y í–.ç#_©ØÉ#¬w¥Å¹ò«|Sþ?Z:è:”—fÆ×’¸ʵhúÏÈ×XaÛfÚœ¯Ú3™B¶“—£Ìü¤‡uቇôä·ÏÔϾʉltãp)’&ÿT+p•°e –íZ­M31I¡ÒÏL«êÈcýªG’«ô"Hx¾çS•ö$Û_Œ*[£n~OYgÚC¢ã® ø LóÃI8GU–¿Bã¡\‚–Ÿˆ{éõ´Sû›7M‹Š–…;ûÛ䃵h¹0GQœ&÷ <‹"œ_ý¼ÈAze‰ÀN2ÿPÜJ"u]©¶ÕLòs.}æQùü‰iõHö5¨ñ‹‚‘öqLðëƒýUj[’ =Á®…1Ñè²YÆHOŠåoq ’„!¿‡RÒ¯¸ð%ê«~u¯ ³¿0Š×·6î;>nE=m½aÔ\{\ÄcïQq”&T/bµ^þü‹}m“¹ò A’ü陈×O/ÍI>c×b%ÒÌ&ìýºªú· ¶mJ;û7žb{ª6eC‰Æô_è<@ÀbW’+Q'‘šäçÚU›‚ݧ/ˆ+ƒË°a*¦Ûåõú/5 JÔ†½ó'lï 0Kf›/Ð^‰ˆÖ½žO¼¡M [If§€ãC `æÔbï1}ÚU*÷i g#™HÓÄ+¸"î2X|F#êLq¶ÀØÙªþr#g <¤þdÑ _IÒõ.˜ê¢Ï\9¾§é-xÚÖ-9?›ìÐv_ wóý}¾éH`…Ñ'>Êß4¬>äŽT‹¬ÌÛúGäµGÔà…$Í ï‚7LI›u`žUJ2ì„΃79ç¯~f´lá­ÊΚìïW 5?|¸':U—.ûrJo ÇÓlÔË5áAÜçxE ³º×ا‰3Ç•ÚTñ#åKþtâ•.iKW@ö/É›ÔÑ÷ ûj&Q ¦Œ²È˜¥t°Èð§Äh-ؤ1íý b?e¾™F Š– ÉXrÙ/&Šjz©¨rAÁM°re.2Òe%ÉÍ£™6"5[¹(H4 :\mdb“™[i:ýP½2“¿Ýä÷ö0JÑ»pÕh¯QšQ¨ý±Qó_»Ã7;mþã«÷Aú^ÁÐ; Ó èvñ¡Õñ¥ã«*’Hóß¹,QëtT½}…ÁbWý€g”ùxÔ$Ó¬GÞ×™®'}¡uÞói õ´’D§ùõ; ¼xðÞԡư~. °öâ%ÅÅ4O”˜»ª¡ Þ»Bï­\ÿÆÈæ  -†ìvm…$t§³ÎLd?莑ˆ+í–«I&VñZ"-¿35MGöÊìä§7À Ñ4‰>ÅauA×W¯½r‚…`Hã×W{Ûw1Û®­¹E¥^["W¬%BŽ… >«íÜMÑ#nNCuy‹¼Hû %Tž,TÜþ0]4.ïdîžk0œPañœ„5ðY ÓëF–?ªU'?Õ‹«žäfü¸Š·Ö¤qCr®až1j,†º¿÷2Ó“=²õáÿ¶D4ÏØeÊÀ¿I Üóv¼vþ´b„dîÿ¼ø)xý)\+"oÜ´¦ÜD1å[|)h$úØûeGUeŸ?õ¾†Ó<åízznKB†Éd–¬ö…Àÿò!øÿÿOXÁ¡`$aFÚüðI)æendstream +†ìvm…$t§³ÎLd?莑ˆ+í–«I&VñZ"-¿35MGöÊìä§7À Ñ4‰>ÅauA×W¯½r‚…`Hã×W{Ûw1Û®­¹E¥^["W¬%BŽ… >«íÜMÑ#nNCuy‹¼Hû %Tž,TÜþ0]4.ïdîžk0œPañœ„5ðY ÓëF–?ªU'?Õ‹«žäfü¸Š·Ö¤qCr®až1j,†º¿÷2Ó“=²õáÿ¶D4ÏØeÊÀ¿I Üóv¼vþ´b„dîÿ¼ø)xý)\+"oÜ´¦ÜD1å[|)h$úØûeGUeŸ?õ¾†Ó<åízznKB†Éd–¬ö…Àÿò!øÿÿOXÁ¡`$aFÚüV4)éendstream endobj -1063 0 obj << +1068 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2122 0 R +/Encoding 2143 0 R /FirstChar 36 /LastChar 121 -/Widths 2127 0 R -/BaseFont /TNXFDF+NimbusSanL-Bold -/FontDescriptor 1061 0 R +/Widths 2149 0 R +/BaseFont /WAKSUB+NimbusSanL-Bold +/FontDescriptor 1066 0 R >> endobj -1061 0 obj << +1066 0 obj << /Ascent 722 /CapHeight 722 /Descent -217 -/FontName /TNXFDF+NimbusSanL-Bold +/FontName /WAKSUB+NimbusSanL-Bold /ItalicAngle 0 /StemV 141 /XHeight 532 /FontBBox [-173 -307 1003 949] /Flags 4 /CharSet (/dollar/hyphen/semicolon/C/D/E/F/G/I/L/N/O/R/T/U/Y/a/c/d/e/f/g/h/i/l/m/n/o/p/q/r/s/t/u/w/y) -/FontFile 1062 0 R +/FontFile 1067 0 R >> endobj -2127 0 obj +2149 0 obj [556 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 722 722 667 611 778 0 278 0 0 611 0 722 778 0 0 722 0 611 722 0 0 0 667 0 0 0 0 0 0 0 556 0 556 611 556 333 611 611 278 0 0 278 889 611 611 611 611 389 556 333 611 0 778 0 556 ] endobj -1059 0 obj << +1064 0 obj << /Length1 1166 -/Length2 8309 +/Length2 8686 /Length3 544 -/Length 9124 +/Length 9500 /Filter /FlateDecode >> stream -xÚízeTÛÖ-– ‡à „à. îîîN4Òî‚÷àÁ-ÁÝÝBp—sîwî}÷Üû~½o¼îµ÷š«æÚkîY£ªÆ(JufQ 3”ÆÌÎÂÆTÛ›¹@ÕM! -Ìj +àsÛ@C£†Ùþ~ÄA¦0°DÂöŒkX»Ml@v6>¶÷|ÜìÏc6οœù€*Î`{O  -r¶Cž! s{¦îâèhY¨ .Îæ (ÐòyeÿY(îàèá ¶²†é4Õ´é™þaçååšyü…%@P°øöyà -²spü£Ò3…4r~^´Å¹*–¦’`Øíé¬a0G>VVGKSÐsŒjÉÁXéŸ* ±w°ÿƒ -øC3 °3Èü¹)Ö¿ëf qpƒxýGØ ±ø³% GVMØÉ$+ñ?ÉÏ!À¿bV ›ƒ—r‚ÜÍ­Yÿ(©ááúdÿ#l -±ðörtpZšÚAAÞ`KÐóà5uaÎ. o¯ÿø÷€h6‡Í@VÏÛð/öç0ÈòsES˜3Ø¨ÏÆÂÆÆdûãÿÏ‘áó†Z8@ì<þ•®dj²ªi©+*Ê3þ½÷f‰‰98–D2ê›-¯X 2n‚LñK€ú -ÝØ)[7q\ä딬Ÿâ}2Ç”¥Wº4BâÃ8êÁø¾d7z»{NÊ/IÈKsËQ•÷fèy eì|Tù^N ~“`³ IA“k¯¿¥•ÓC«?¸Æ-oÃ1™žéÃàö -–ÀªOÌHt‹ßñ}n縳.i±¼«tÌå–ã4t\dêÍFÔÏZïÖEη2Úú`¿Lè-вFsŽ]Ä!JÞlø*@çìwÓ>ׇ&ª©æˆy²¥@¥]kU>=­rEÞ-çŠÇ™°V£¨ÙaQmL1!h²R%^×àj¸Öl;ÓÛì^R‹×5{/¶ ¸»ßËwU°s:NXµ‘÷ -8ÆßÆûOvj(øÏñTÔ¤\¥+Ö#2\…¿n5;ÿH¯i}¤ß®£Ñå~º9$m`Ƶ'4É)ù6b›•½.†eC[•+ÚËG}*”µ>A¼­dÏGæjøf¬%€Ê4ìªÉ$›Š ÛwÃPoÄd‰÷ú´ÊÈÓƒ8~Gžõ‘÷Èe¦_h‘Q¤Ç‹×g\<©‡3Ѿ¯òJ­’ûÁ«‘e‚gìº N¦bŽO+ÞÀ“îS­™c­Hœ4ÞCØKH÷²m:§dÔ’ÆC»t½€!…Âæ©.—IóÉ^!Øæ¾ÔD’ZÐZ¢˜ÝËMïQ•¦ùÜȇ®CÄTÄZÅ‚zŽz­‹Ä#EÄ7ÏLm}.éF?:ÃÓ¬v­Ä3*ŸH“¾˜sLfZžÓ$Vf‹B4®»%DÚ”6òÛì!Ó7ôRI¿S{ŽØ¸Õü ØKÒG;ë¢Od€V@Sp¾¿–_Û«°ÅníË5n̈XÛØ~ô¡ ½ÖRb…LKúÄ6!T²ªNËg¡å‹Åí„\æ |7AÏâO“fgYPg~ø¡õ´ÆÏ³è­‘!†Øç]äÆÀ -eÀ_±2äÀéŠê×Ü÷qóºÄÃfhÙzÇð#e6Pw=3vd[¼¶#mýç;±ýO߇P÷LèLI Š `ßy·bgh¶£ûô•À|ª¿2Õ 1äÔ@ßX ˆãàç¹ÒH_Li¹=YK/0¯§E ÒÀ(èù\²ÈÖ«:˜ðCÃkX[ÐBf µÝ÷l¼ -¥ô€áëÖKŒ× m5X€>ÚíÀ½ æØ™Ô„(QjiVJÒ˜˜¢`ßÛCÄ9UoðzÙ„íÖðWvªD+žoÜhe…Rj;5ö}_”òWЖõoD…åö|ký—¹&ùü5jÖC±8.’óÓYª´'åÉrö'À+Þ@ÖŠt¦ïØÀf p2:7ßu°%¤STÇ9-g9ÜX–ÙG]td1KâƒÑŠQ¶SF$‰·U¥8:ï¾Ó5Ÿ½OÜÇ'vp¦3gGp|wã›À„J÷Wó¯c¶LLËFÊY7pŠäh·nK.q ¥'Œ/®Â9bއ±Ïw 9_2ÇÐfÊê¶VWdÞ·¸áË™w7‰œ"Óù}R4T˾jVø?âó~:Ãí1~uÊæ|*€Ó”ʱŒ«HÂ@pÎúNšú 7¹á8[³?p~¨y4Ñ5r€»ö£õ5C6Œæѵ,âM˜“ÕQÓ8®‚ùÐùU7 ¬Ûþ§>S+zâŸ[VÑUŠ<¥< s²Ê&:Nð )ÎIJÀÃTãÃX×ò„W• ¥jƒddŸv¤øZ’¾p›Kv£ZmÜ"Osë“(šn­¦ô¶yëŒZ¿gó!™PˆÉVŽõä†þ… k¥Hó'´åå0‰’šÉÍq Ž\±Ÿ‘’® Û¾Õeq_*Z¨ÒZ>ÍÆÀ¸ü¾m!Wò §ØiON²¥:LÆÁ·::¤¼Öe8èšDŽ^®´õÎ÷WàÓ;ú…co÷ -ÓsñŸ¬5ŠN!úŠNÌJiJ¥…+kkŸÏÆròæ¢ß ÛŠ)Äxžcé\Œ>Ð~í.í¯râ<èªëf׌Óy¬VÑ‹ÌYÝn§ FÈK Rd"1f…U´†ÇŠŠ”> ¿¬öH‰Bç9Ÿâ‚â%¨„$‘ûò$,gÊóMV0êôÈ­ž·ñQÔ‡‡´æ¦-‚¢óßÐÙÕþúiU:Ö-/P°Ø/%ëºAwð˜Mwk¾¿úñò›ž¨bØ©ÕEú‹÷1¼»ãÅò—{*7¯ú–eß0_.Ä?”?0: |‹Ô¡b9K½JöòÖ+Ÿ{îÞŸ©p.îë°Fˆàú75ÚT­7¬uÈìrAéÝLK4ýGý?!‘ZîäšeŒ¢#hty0£„†I^Øpw»‹õÄ/&Ä%fV-G¥ôñL8å”çѨHBr¯Ÿ­ùØóå]‘L.÷Þ”*V†Í•êüõ¡KlÜK–C†àh8%QoHZ‘×à-–šÒ‘Ô©2‹áâ"ï4ΡÇ%3£Ë!¾Ê¦ÉZý!üÌ#4øcð©“±¦¨vŠ9dB?(‹N=¦{®žu3$‘dàÝÊP^ãû%æ$±†Øx˜ØŒLûkmË‹‡ýˆ8NkšÈÙR,€ñ9#áEÅè§*ÿc¤7¡ ±sù‘$VƒpÐ3šZäñísG -åƒb3èu¯ÃízSHø”Ç!=ÐSV«ènÞèõÐ`åÍ’ª;qg?Ìj†o+ÌÊ€/F;=!`ž· ÀË!¢Ëþiú)*z‘ñÄïø.ëœØ½ 8Òà4AgÉ—õ:fÞv\JÞàrdqÍxøœ]€GÞ‡¿SÓ“9ïiŸ`ã´U´{*=©›ö„%R–ë×M[«'0¨º~×ÔZ]—röUňaÖ·<šúµìH±Jþu"­îIV5‰¹! ˽/Insã°žÆõªª<{Ïñ5gÝl ‡×;{•¬)’#ÐJ¾çzYÅçµ32%2I)OÊ>IhJãÕµÅWobAnK:B¡&ÐítEM•ËÜf-¾¢®Ë&Iº5?RDƒ} 3ez¯jcCçÀÞ½‘SÐìp)WZ¦gâjpå‰Ë6ÓŽ\‡£;vj¼ÍSl·kVÆäø÷õíþ¬ú6-A~H<ÔVï÷3ÎX7ñߟ&7$S/·ý²Ø£ÕY1ê¢Ø‘Åe5Òlß}Hù nû>…!Í:Äè¼Î/à·ŽýßMHÙµ¢ñsÕÝ"=4‰yz-Ú§ÀNèůzYj”7ÎÏ=k|ëæ] Iš>ÒL£ÄSØùIÌÓJm?IrÈ‚U¥›/ΛaÞñ)ƒ²D>´ïËKÃîÆÕ,ao$ÎdiÀ©ˆ¦7õ­œåê¥Æ7Hõ‰‹^ÃõÕÛÓÚ®Œ¶°ÇÚÆÌ_¦/Ä‘ ØM¢Sl'µII37JDÁxñš®3S¤å;Ü_rÝ’}Ò³ôò^Ü%.)ž7è!73iÓXƒÂ]r+œw"ëȦhá¯àûŒ½Ð Ú´Yä㺾ñüe?¾ [÷§“è‹MóûVö›ºÞwqt–Åw¦‘Ϩ°Óì¬è` „ì¿ßJãóf?6f'õ\ÇŒEià[ÿœ«×¨ØU»zšü[I¹hÜŸ#hÇKIçén ­R¹õ–Öi˜ž‰bш˜×5É/ÔÆu,Ì@{–‡Uºya)¨Ì˜:m/¼_iÿÓRÛå8"ž•‰6/Åfþìû—o bæ ‚¯¶ð^'d¦þ( ÷ÉšƒojþMóSêÌE¤]KS9ðHe&Ôz“Û×@U¥)zâ®|ä!aæÇûë<Ýžœ‚À%»Í=¿¦¡jÐ.‘¨µTW4Ô>½Î¯/¥^6|ð:u›Ð5™ ®õ+.›ÿÒ`þxüJYék!øTB¥(P’êi|`þ®0ymc¤ò+©ž ÐÎÏßDMøÈ© ;ßnF$¾¾xïÍÿ^õÆ·OF4ìJ²Ãþa8÷üL_šfÑÜ;’I—¼@öÃè‹VÊ‘¤¸Ý$l¤Ðn€¬¡¬æ04q|ˆ¿œ§à]Û;˜bù«ã›Ý öìô(Ôjo]º¿?Ásîit;ä -L^e°ls›NäºÔ§ßýšR6úù¤Û°éµÁkkùéÓü½I°±U-«a¾rBïñØ;e9Ïx¡‹K€q("Ãßj¯mµW.~ØÛüÔÚuf«ù)ýûU=¼?R‹ï7éÙ5ĺºWéŽò¹ÊaÉ[Ð4Œ@Çrßg|óy¢X–%}ƒ _l3÷ó*CÈz:â0ÂÈ(PóÇŽZÝô†vÌ£1Í5KUFêçöóÉ„¨Bß¹DóV¿ý\öâ•GþÐò$uI“!š›*«±5í1ÀÌD(©u›P¹©üò®¤Ãóãõ€2^DõÚTnÀo—£AÜžÈ77lŽ×¿2+ó33£‚…VØsùÜÁ&ùK - - ×yLˆßº§(Pœ(4Ä3dBmÝkÇ–?v7‹]çì£ PܹïÏ›ËèÓ}@ NdàÛæ]KT/¶@\¤·t‡Ÿ1jà1†œ]ú?p»~ˆÎV”PMy­ŸÍ~ÙçºtóÒ¾_ûᦗGPòÓu-+{Nüß"pÉU‰¹ýÕê-¨Æ·`EF^pÈ}‚%ׂ,”Á—¤O3‡PÍ2E4ÉGÿëaµÎ à§6Õ}›ê×4Q㦷^ÓÙw›«Z+J6lrÎ # s Ð<£ä3ÐfÅç¢ -ð(8ôðY&Ò”}„yäÖ5ð±KêÑ&Ek)Oá†x°ñîs=BˆFÆðïDœxѯÁÛìÍã“¶‹]Õ¼ô½Ó lIÃÏ6<<*°OÖehÞÁ»GÝ„1S¯¿–Z£K§ïË·nN ¾X{\»€#P/ö梢֜«8Ö–¨²²5 8~««Q›s(ƒé¨Ô,Ž­ÁŸn‰vÆ­Æôòç>65˜[P^·Œç"K)u€t3‘5¢²_xËœBÏ1ä_X™ÍÇ¿Êw3Ù%%T2(>b‡r©êׯjÓhÁ8©téññê9¢ùE5’~4¦*%‘'0`W"ÆæÜ" Ní1FûÎÎBâ$¼æÜq[Ü£ef¤°À9t„-„BÆKG«•Ñ2Ä.«j/‰µ/$¤ji½õ4&oØwãI¥»¢w¼6á-UFK»· ñû*­Äfk›öx‘Ô—í"ÃHmKêg@ˆ{(#¼’YD¹ÿBž›ì1ºU5Õ{˜_«H׿ÝbGû ‡*¶†u„üθ­ßáSœáxDž$q*€›¯å ’Ú‚…ÆTHAøiGõ<h7¸Zt³ÁìãX4G’Tßä±£h^ŠÃw­v2¢%%¦2äÁ0æïð¥ŽÀëÚ|Å}sÌ;Á»‡F!GÞßâýë_í\z& ‰hÍ¡ñn€4©D2©b  ʂΎ3Ü£fü’1¯æ‚±Ê¶¶f›'C9qoÝ ×ÊÐh´À­J7ŽW1ÒžB*»élMäYyÝ£k­“þ]ÎŽ‚ÁNÌúÔ6¸Å–=h¾Ÿ/š>e -4; ÃkÊZTwïG¶¾htû»Ï4êªÖR¡Þ'­ DIn>˜Qâܤ¹*'_I¦äÆ6 ¦æ>»\<º¿UQ, ‘baà&#ç^ËmÛÝ[oâù$Ç©e$òÔqµ=¿=jY ÄPs˜³ûD<‰™*Jß–¡£fo,_mSBºØÉ¾ z ªS Q_øi¼ÔR@¯KFÀ®+µ™øìiåÁMwš”¶µ<ñiÒ^ìjg–Öëã~f쇬òÑK§kY¤ÓÅx -¾¨¾TKÛzÌ‚Ä?éÁÓ€¡^ É”eÁ.5-]ãPò÷2× EQà{‚°rëáÞ8,~;;ÁWâŒÄ¯Fõ9ŠCá•Øí9c{û¸´pö²ÃŒN¸4ðÚÑù/ààWðö“µËcÌÜM¿À“¡-¿*{ÝÒÙ9ò*N²Žå ¥÷„I3ŽÖ #‰³¤~–”@¸ÂfÅÆ®»¢H2#ÌǸW·£M˜øð‡ÂMOa~Hî÷ñRj¬ nÓ‹ê÷\J”.„sÆ«ño) -j[ÕeÀUoóOõe¹#´M7îL°”XËzÛƒñ…Œ‚´Wvû¼‰¼†Æ«<¶eªhYÃ<ÀæþÆêè²o¦ B‹Ï¯¢:YAW󹄛é_³óöÛЛë7.ï.¹m{(Az>oɧÊé^˜ë@Zc—‰7*wÈê -›»WVö]°dÙ®ã\öý™fÛµ‰t9¶¤V}îñìÝØì¾Vᱸ¨Ô3Z( -ógWÎà iÔ“g±Âî1µúnG¿Õi/ Ö®aª\z6wH5VkÃÂXŒYg týSH}vˆqé-ÂY/Dbø¼ýdyP8s -$RÇÌvé…h'w$K´|†·í…§™;Y¸ñç?óg›+HGÓðF~pQD=YwW´äL;v£ˆ§&Ì3p}OG_½¼¯2y¼¢@Õï·URåo<õ4"¶ÐþÁ€àþ2½öÝCI;¥ €)ª¤ÿéì¼Íµ¾ZnùˆÛ„œß~‹øŒþ—¢@™ðÔ6!†%ÿKu9Èš¸ØA`ŸÊŒa¦ ±¾!¿¯yÙ´FmîLRÂöqu8.ó‹j5Žó®Ö?ÍžÉÎÅ¿ïÅ4‡ôc…g96·¼ oìŽ~¬ðBGÆY6-¹ª…M6õÐêY Z`–ÄR:´t‰¡¼JÆB ÂP™\µÔäœöF-ÂâÉb[&èëÛXåõ‡ R'䄉¥ü"Üñý"É)¥F{WqÜj³‡h!YNéðˆ~~ò"ÙÐ5Œ©»Xçà ‡‹-Ýxä%ñqÉ>ÿó1¹rP*#7 -¶²çìÞê’ñ¬Õ(àmÆÊÞš± ~µnH¤a0³•JT½6‹’¾eËŒL£õ•ÃSóM ›ºá8'#-¹É\ÕÕW«£¡è)͓ᤛ±AççÆl‘ tΗm;"‘¿¾:A½K£ãcôF‘–m PÕ̆3s§$Ç`ÝÈbwÈæ!Þ)‚þTìû k±oqË»g™o˜:™Æ®Xå‡S:´ žø&i{ºˆÞ ó}ÜÕG”twÏ8»ŠÂŽ¥™r&âgؘz^?6×ÐP)ÕâIî–}ú¡hö‘k±+:ÐÏÊ®®ˆ“¤0ÞÇ}#3¼;ßٳƼJ£oèߟ„¡!}|Wš|÷ŽCdI‚¤¥ZÂ?Bë̦3uqà¢?Ò¨D,FTÈÏ,ÔvˆX3íÊQ–Y˜dª¾LÇA8^ÛI6—¬¹R –-uÞmR¼óIs] 2Åúxd«ät9÷9Ñ༡ßB-B ©Ë¦J Ï;gÇÐ ¹Ndfg|§µHOÐeßóšëºšj/{f1Ê=Ä~Æ«½ó±;wjS¯FûuвÕÐùåôX¯C%‚v“µãe»ò-jÒkë-âd¤/1Tĉ>ü² Æç{¶—|ûÅ´¾F¤¯2Ä3Ò—ùôüÚʆzNŸ¦·”‚5áz;κ7MšVà9>›.¦.7UüðD= -Ëȯúô$ šü=Z¤ïs£öjïM ­È"±óBc!¤d³£©Ëb”ű‰„g²@›€³y‹u[ñBQÊüñ‡2+QÉnÎÕ…lÍ É¬Ë½p¤+M)zÙ>û!Ÿ>ÅÏ -¢ï,Ý™Š£°ƒûüµ±ÒI‡c&”ü¼ün®'ñ°~ÅH¿ßýø ‡é+RúŸRû#Ì»’ŒŒ[È1Z‚«„äî<úüEþ„þ'¢DEPˆ¨½|”‘s¼j#U(»1é·–½,ÝÓ4Ešç×Ü WŸuÓ‚S{:D¦àæ }ª¯ÏB%Ö^‰$—Y –Œ8Ǹ %³šc&h˜!ç¹ÙG£ÀŽ–+([;3ˆý¡ŸA`´ž°ç£G°øªlV˜SÞRÿS”W~V'¦—,É*ZÊÿëH™­ >FþrRZ§³¹™ª$@!È¿Æf'%N¯Íqg'á4¤ÄÛeù+¡D‚A¿x0J1»ôÖ©Cøp:©¡Ý69‡Ñr;âš>ã|º‹Úˆ²;h“Ùé gÖÐŒíõÒ½Ó’iH)è¿iŸö&Iû RKÈÜ-‹Åx°VÅ Ec°ÖH·1ÁïX™hF¸íµnQtCç¬``*s¬Räxƃ<¬ˆI·$¿Ã“,Wp¨þ>VDI`×Ï!JØÁÁH¡aÆJC××J\ë(üÕ7“íÿòøÿÿO˜ÛLaö¦Î¶/gæàüÇgR€ÿDlendstream +xÚízUX\[ÖmàÜ¡pww—à.…+ pªp‚— Á58„àN°àîî—‚ËåœþO÷íÓ}ŸîÛýîÞ{­1æsαæþê¥h)ÕµX%-ÌArNŽ®¬œlBU°ƒ¹TËÌQ™UdíxyÍPhiµÁ®ö ÿ _iÈÌìä(cæúÂkÛ¸TÌ .'‡‡€/çËšƒû¯@'ˆ@vpò¨ƒ\A{°ã %ãdáærtÕrsv¶ƒ,5AP'7ˆ*°z©ì?³¤œ½ `kWƒŽ¦#33Ë¿NAAA€¹×_ @[;è^î {'ç?2½HȃA—¢-ÿˆU·2“µ»þÑ.€ÁÆÕÕYˆÝÙÊ ô‚±A­ØA®ìŒ/…Ê:ZJ;9ü!EùÃ30dñÒ”ûß}³stòpôùØ +ìhùgK–nÎì:Ž`7Ð[™ÿ ~Pþ…Yƒ\¼\‚\ äiaÃþGJm/gП$ç°™£¥¯³“3ÀÊÌ +ò[^(>P3wÀâòõù߉ß¡pr,Á®sõË1üKýYýc¯bæ +{ 9Ø888Üÿ\¿¨¥“£½×¿ÂUÍ@vE% šš>óß{ÿg”””Ó‹$+'?€•K€÷eR^y¹ÿ®øO/þòáOTÝ ü?urüKò­£•@ðí¼øøWKî ôe6 Ž1#àßõU\Á ÿFLjƒ—ãej^œÿu¤þÿ¯ƒõ÷rnööºÂð;/~@Ê€?±7ƒüG¸™ØÞ뿼ð÷@=Ð?¦ÿÿ óÖÕÌl!éhmÿO›ÀP9°'ÈRìjaóqùËeË?¿CºüÇ— `åäåü§m¶°sA¡/gñ'r´ü[JYG 'K°£5@Ëõe*Í –ÿþ -Ü {þ< —wÿÚ[_ +‰#‡·–b6ulªƒr¨í}™7* Ð1í Šî +Åü~~f†K {5òòµn<Ÿ‘Ð"+µÍ…¬Ìø6_‹æµ*߸R"mærÞ)™Yù§¼f©Ò;$¢)4ƒm‰Òæìˆ°óÇlÿðߪ†ßõˆßµ:ƒS½$}ôón†DF¨å´E‡…E®û•vX­}Yãïš²¢6~ì<ùцߊ닩²;ÎÊúÅ5ÃV±kÌ*å JÅï†]ç! ½CËN’’çd[Ñb}Ö}Þæ[öÕÎ’‚ëó-ñ`b‡2á­YsawE÷ëlMàÙzøüÆÅbú¶ÍÏ4œ2¤€³‚7¶#]×™±yÀ/u˜Ú44‚üÐ3e`r<#7(uR‹uçÛŠ5š¥Óæ×÷ÅÕ¯¦‚¥v„µ}oPíÇF`<—0ß•værÊ·Û³%©ÌÒ‹FI¤mô¢žô/ËÝqƒŸ†µ}FõD-V;üÏ'«‘ÊŽ™*¶Ð ™Újß ôÑï í_²ÆÍ¥ ÀFKR˳S’Æ~sUñí£û · á Þü:e·}#^Á‰M•øÁš/Ð'FM¹ ÿµ=¾ö6ç¡?R9ôÛf;Qq¹C‘ÐFÿï|ÓBáZM›‘8l#7ÙÅÙ ú³òdÅ"‡3À•`{e&ËP`' ÅœŒÆ‹.tjåø]Rƒš·i‘ɰQ|Õa;¿îÕ_¿zøz {îÁ™À—8»´üµÚq=oûõ·k€»fwþȶʣÀ÷çJ¼ùÀß=p½¥n”~Â{ÉPÓ›$ ñŽŒ Ùè`œ“êè_‰:ˆtHlÊÜ·2Ùs79ç ­oÛ§è‚Ô¨ŸOÝz¥ïŠa¯B5 Z®á}ëËn¸àXrouáÖ3>ÄÝ>ßENÎ…¼öùÝhÀ‡•â$â ž`€â¸c)“½â@Íþädz®ÈˆèM6H6Â’é¿9 {5ÑRJ_ö=¨P€–üǸÜS¿‡ ´·¦ºIƒ¬:sš¶_|—qèYoÜü}¶ÆFfHoëǤÑâçîw=õË 5Ämï ¨íZ-~‘½“‚$y†E³dö¬Ó8<|›Û–=:ùeNžÍåbŽÈ;Øÿ”Òj$³ï§0æíÏb‘¾ +ÅWy\:T*‚}ò +…ÉGÿÐJãöÄ{ ¨ÃÈÝÅÔiÜVnnFʹÁtj̧é-ÖÌ÷”–7!ÀýÙ¾¿C¹x—wï\áìŒz ]Ç}Ä?âU GEu=…Ó‹ jaF«AÓNQ(E®¥~°0FHÜdùós D7jé6Ã/Ç“½ÊAdl—ú;WyOAûÓ"Ôž ½Òrã*ÙŒAÖŠ®ðïì”UIhYT¬Ž}¹¬:(k¥ì™š©˜¡%¬½}Ý"ÃòLÕ»÷a”°àmt>u‰fP:&&Õ2€ØŒsRÔ® ZŽ!6{½‡doàgƒÛŸTÕ¯ØFø™G¿ÀÃÙWHn»–ÄÍ8ªÛÈÈ"¼8µM™XÇ„eÇ™¶HŠ`²LØ¤Šæ]§ÈþKÇÍÓæ”Ÿä²#¥FÔÑ»ßþð³ÓI +³çWD`û9ÒäÝ$ËýšžÅ7—©‘+1ì‘n +eñß3:Æ=ûGÕU¿.Íúø¦ Li¿žÔubb¾¯j&ä©¢ëÝH[.=XÁŽôæU¸²Ã‘e\óJ”EuÒ$,ŸÜ5Ë:»‹¿çzFD@µÁ:^*ÃO1N]þö« 3!Óeg§N,!u*Õ™ÞŽ‘IiÙvÞ’é¬.\¹6áùütc/¹nA¦dCÜkÂüú`zJ$ÕT;ãŠÉÝæ»bðÍ&£·³ô€MÙqP-ž—:ÿ/ù¯y4tbòë¹PAàŒ¯Ú•r ÷χ§5‡»%~ßàkÈcÉÙ~|FÐPç›N\¡3$´ßÉ}W©fžoœx3Rlµà½ÏåmïfäÓå샭G0^CP±¬z¯.ÙÖìS@ÆîŸ®øÎ-ýýUį…eZ77!›s°ØJ&P­ ˜üspä'ËK¹Ù¶v<ÇÕÀ™ñ§°š¼¥°µÅ·ö/Û0ï´V 5”U¢ƒ‹F¿‚Ù¶Ô•™â‰ýkMšÐ‘û¤?§ïj¢3J¢€ðçºùœŽâÈÄ·•ÙVºš³¾u+0î¯nÒŒm‡Õfe“rà¦&öuó 2̵èä±j =ç E¤ØWÕ·Šü5p ŒÁüuΰ€?—âÃÛºvt}Í“‡Öh&:6UŸVûŸiäˆ28OwÜ;ÖÀáõb¹÷.Œ)ây"¬ üߟŸô©¢íÌÓ”]Î/¶ë‹¿;3Äð¦Úó¤­Óß‘ð¦n_4ŽÄ +W€ì­‰6ÅBÛæ¯"Åç|üž[Ü‚'0{’ˆ”£aL©“¶m\Ãa5ãBÓ€™JJñ,"Œ†K”¡¾»G4ü½59‹Ã§zŒ™g± ¶ÁþU©QPJy½Âú)ÜwUþ€ŒúçiO Æ}7œÌá8šÐp +˜†OÔ¨‰PØøàVß]ñs<å#ýûµf²ÊÌWÄX,K½ˆ‘Р†Gáî[Qذ•€…,a¡ú÷²TG‹•áE¿ÄHo®º BtÁ¦K×*5ôsŸܬ°ƒ÷: +TêCBz…Ejä'Ô cäMí&B¬är¿ùÊÔé¤K0 !Ët_‹û"jÖDEËCžøÅد˜x)ø™©á½òYöý ì])£ ý¸¡ÍþŒ\{.£‡ +s¿6ùýáÜûßa¸lÊqö¦«ÉlÇ„zªu؉¶jò r4irªè/Šð–›ši}¬=Ú±¢ž£±¾†ެVR4ØËã|hwFT+þòijÐú°ých;ôˆ4È*¬B¢ÿ¦€Ð6°$O¶^ÊÇÍ·0~ºSy æ ÍÿÍÂ' ÓµâÙŒLšM½¤gà[A¿ŠÞc‹ÍÌ“[›i±“¿„M¼~®³yE'ÛçI9Ä\ûŠø>ûKÈͧÁæXå°·wžØ#ÝGT¢$5î\u¢;º§”-®18û¤X»†KkÏÅßòû»H(sª“¼xó¼è¼-ÀTÅèÛ‹ªv"1™=¼Ù2'1ýá,BK‚ǘOý=ÄžBÑùë[ÏÓ⟎c@«ne[Ø'Ýà†(ªÕÊuyo߯æá£-º±Ëm=ý„‚W 8î»;<Ú±‹ƒÙzs,l¯ˆ·9Ëu?§\(^Ò‰“ȉ|- +ôsˆÓ Pî—¯böAGЕ=tÂb??y°÷(QZR›Ðs ­dóé¤Í\=*$3ËSfYå±s;9¿â6Œ¾;²e›\«kæã(u}5‰M§ !Ðöe˜äÝQ'-ç{÷óF{ …ýPë&=¼|ˆÙìÌ&Î’ÆåÁVí*]÷!ž£uàµFØwhIÏ)ò¹îÜäHYù +ža“î‘fh³+œ‚Ö*CÜñ¡«i«Yezœ^²¶Æg‡ä‰ÖáȽ±b×.˜V+É>´@h¬ëÍ3Œ+ èyÑÅë]ûÊÖHgU€fþ¸Rf»‡‚w`¶:Cd÷Ýaè$ñz¹'¼ÿ9™?!!MÌVT¡æ?—Î7Ñ[Þõððëàoõ»ó]顯4Í­rƒQtb,Aï‹ïÎjJ6à}dÝŸâ?ÉpG¤Ø½Ø~wß²æ:™®¥¥[éä˜jR¹Nù•Õê~V¶=0L®DÚ!$¹*µÐÙµ+.¦O¡©”i¡R}Rn<Ä)תNUŒw‚„~W²K‰9-Ê“)øY%ÿÁôCöéQYÞ·AȦùAðÚ—w•Ðlu +FºgF„L|º÷Ì®,2Éî95 mL††ÿLçÈW­ªJú93a6ùí7êÙ·IÖÞb;}õ'vT5»‰É{£s†gÊ)»Vì–ë‹bY\Ÿ5è(&·ƒÌI§ +ã1~*]èÛ—ŽÙ‡Ðƃ”ûGàf{·ûÔ9½“V0˜š¤×`¢«%n'ô'ñ¿~Ã{º,ƒð`æl&‚S†Äó¾¥·-o„"ÄuòŽ §3YG\6¶_=2[žªœ6ÏŸ*<†Nc§FÊ”çm诟pƱ¢T *¸ŸÀLõ¾VÕm&ËP +ÑœmhÎ6||ëÔ¸\Ùöz®N!qQê»ìÛo]*â> +ќȖçiH ÒÎÐx_~ƒ™Å>ç3nöe\\H¢fµî9(Zhs:Ò1?ÿ¢}5³ñÃù§üŠ)vÈyæã$këì¾dñlZw”°¯è´“(é)Þ;ØÝ ʈƒ/ÊCZ²&h­â‚QDj¾•QocÚâ *eH™ÔbN€lWü[Ò±vq»lCc«ú—ŒÈÁ¤Ïð¸fŸÎ{µÒým%Þ T¸TÃqQßt§‘Ï0‹ÍeƒÅÍ^oê!¾SÁR,Ú‘0Y¾Q/­uÐâÊMš"û¢…ú–þSsb•=0@ƒz'kJ<Î΄O…ÍnP©Ç/4¥%0º;‰ô^aøBBîC÷-EKší7´uørG£”.#žŽãÔKŽ£Ô/ bu?Ñ”±#¡Å—* Ü9(×6ìc}iQ[0[*|°¦]Ù@Nª} ´UÒktn§ÉOc…ô‰Úö=œ.’+ý„Ø G©s QÔ +<àDKrøˆ– vWXØL[+(¨¼ôu i ùXN¸?<íW%fÁ;j`QsŽüÉZ’áÏQæ¥ ÚbG3¨4ÆÎÌògUã#•šF0ÃÔV`w]§öGŒhýÈ6B¿‚Úš$˜ÿ€Þ°ÁNXîIcFN+ùÙ´:¼¨HàõthEAС¬Ñ,ñ¡½^ɨ¤kd¡½?sÖBF—#Iâ*ÙµÎP› w—žÍñ›ƒÅ5›}}†ÁW¤¬Có$øÞK¤b2Î`ÂöŒüqø¨~k Áä6ÚB³=à*ÐØ¼Bg%Ÿô õßy”:í[Ú9Ú¿Z‡±“NÃ{N½¡ëÛ¼pœúµ6…y›–*§<ÆEØL¦|𨤀%8«ÁÆNN`oR]ª„Xlñ´3ã¯3ï÷ÞCÑÜa¬#æ¹S;…òù~ù²„­Î_‚Þª²¼­Eî€AAÑ^Í~?gãÜÔ‰æõ»Û÷……C9ü[¶7¬õ-Ë?ÄžUÎDÓ:C\–Å‘ Ä×…Xe +šcK&Ž5Ï¢=trPォ¦â·ñ7?U%q^ÿväŸìöí„8&]2ì¶&ÑûŸ5ó¨ð·J²Ä²…|±i…¶ª¶ÃÛáËùÝ? ¾­øÞyÿ;œ:·Ä6Ú~ÝïVŸ¿Ó¿Át®«6p½!#ð©TH¾öÌ}S€‚„2#ŠÚäQ×|`IûXÉÔ}’2pVÿæˆ>ivÁ“T¼,Ôü¢ß3qZ\eºà<×fgö“(ûÅmdgZ1Ón&uX#7›N+Sql΂œu 8Ê›Î|Ÿu;ñwí×Èmݰ‰”dh!\ +Fí¢– ¢ÇWB'u6ŠÑ—NÚƒtä£ÌÛ‡²ÞƒÃ­%=hð#,‡“úbç,ðÁ¶jî÷ÁˆØ¸ûn°å¢·ƒªÔc¢všŠåǯ†L¨ñ.ÁC;"&V‚”›W¤ÑÛj­Š] c%æ£ò'­Ê_+zOïIÏ©Þ[:£ÏÜü2}rÝåœ9ŸŸ=*n¬Ž³iÚ†{;Sîyw$zÈxkàª[шcFÅ1¡ŒR½Ô0Z;'iì+Æ G<¯B¤ñ´Yöª¨‡#†Ù”^°È;}xõJ)ÓêsÕÂB½ž||^$»(sþ ‹"—ôÝCâ1ôYçö¯=: žÜ³°Íƒî%]ÈVùñ;2Peê"å(ªDxš µ _ÆPAíËp”¼²`s|¢½`Èw‚ÓZE+t ÚSÈáçåù(ÝL„¶±+ÌÙ¾ØüΗFEÁ*™Ö0{cÓ@©!¹l¬"URû{‰óõ’²õA“P‰íðçê#SqVá7ÕlÇ 1՜Ԧòê°¥?6dØ>ÄD»~´ì!5âsCX6 k^o_¡Òö+Ù•_0—>ÁÓxÚ¼ÅÃHVƒMJ‹eGž  ?XeáuãÊÒú†ÓΤé“e¸¡¦^2ySn»½YùÅ'ÞæÀ\é!V*¸¼^É5z#2Á¼mÛXošŒìç´Szq/Šh8²èZDaýÖpóeÊ!±õàá’˜É>°¯®­;V5ÈD»~‹_céÍí“®õ؇$'”í"®qLì0—§—óû³ÌR,ubõn +ÅPÍ+‹§+d«òtŽ]Ò½þ³ÍoÑÈj)ƒû;[Sz’ÆO™æ³<˜´Á¡43H˜µ³é6˜8ç)—#¸[áÅôÓ}FJ7j–ŒŒžFA1ÎÊåªÁÖ~| t¸o­ WTd`^Wѧp|Ågºyß$ŠÍßbÌh²#Æ«„+o0Í&ÃhM|y:bIëDðâÜ>fÉ}çuÏÎZ_$Ø3Ä£"FÙ¶ÉœË;¯2ÐÌ ®>¦j¬ûª”Ö:ª‘ôÙ—ÅøUÔŒA®æø'Þd>Wç4ó•_U«¿ÊXo—³”yüpÖ.íˆÖbÂÅT~Å~=ˆeHïY2J)>ªB$¨Q¶¯Í*êˆF±¼ ;Ì=Ù&{%¼¢ºêšÞZ¶O‹9¶HbÖw¢•Už®p[-ÃÕÇëãò6ª†µÞÈ?µc¼nÜó“íZé¢ÂDÍS—ÿ{>e:Z¥u•ŽEb›Û+– …¶¡!’Ù’dÝ__9ÍY{;Ï®l­L9Lò5hBrÕ*]'†’ªÿ{ÅÛ­{ÿrØ£³æþäspÜó°‰Ö¨Wt!@TQq“;í©y€¥H®%ŽLP8.7Û„û‘±æÍMÔКûš6‘šÁ­¿›ƒí\óÔ|M$FÉ~p4×–šH*Y«Ù 2\qŒ¹YæZ:¿£"öú0¢„Hâõ…„YŽ"öæ—–EcÈSFÁ&Ä=¡0E7`wòHÿÄþ9ߢ®ö;ŸYL#·¯Ì³Ö„…gŠc¬ +Ô…Ö¹™ºãº?Éê‚ú„‰×®áþ¹,L'åò#j2ï4ê•ï7cAIúy´ocpàß¹*y¹¢T„†è==lï5¸§D1Âs¹Ÿ¯2Ê´8çh†Œ4¸²¶u‹BSê71ó°ãÜ „X—êyÉyJtèb‡ñ˜`1<]Î=ûÒ.ó`ô7HuŠeòW²OH:(kÑ….oa…^âÝܦ6ç£ÉWòƒøIˆF-Í–«ˆkÁsìü=ë2KÊ›`)Í.`î(/µ )y©Ôt¦,èœLà‡*·7õA[hDp·/ß.‚EÔ“V!P<é‰ÁÀ¿b» Š=£+m™Pµ?vÔ17’I Þ<®"! 7MV +úcd¸´fôwwX£l¾‡»C"žžá°Ó;Õ €Þ#§9ðñ’_7©Ÿ›K^¥ß÷[ŸŸ'}l«i3…ƒ–Œ—¨™ÎÏÑ¥û‡*eáÁÌ—F/S·ML¼Ó®)2_&àâ\Nujs4_}РEÜ‘*áq Å‰ÚiP¯|-²š§SÊG‹“¸`îK/¡K¶yÓ¡Ú~x°¦î¦Gp;·ï¤>«kñ#t-Š™;Ù¾÷wæ¹SxE”Ù c\‚ßh}U;Q ) 5›wðhى嬭¦“qƒÑÔõηé™õ¥g2qÄ¢G¿žÄihq­˜?Ŭةæó;‰À_ð_Ïáìà,ŸŽG(ÝFµ7Vç«w°»ã‡6"­’—‘¥c,MD%Ñ\Kˆ©Åq:?ÍuKÞ·$I{½ŽˆÊ¬¿=P±T&U‰0îvi|åJ#¸ŽEÂûCìKwã¾J o¤›ur¤'SÇÓN~8nØcqWòñjºøiY›¯#WÓ“!×Óß믬‡f•å}‡†XnÂcÀw²ñö|Öq\ƒnZ“E‘x!?ž‡¤‘PÂEl$Õ­.LÉ[—ά&ødcËL ‰ÉÁ.-îÀÊ-§3§ÝáET‰kõ*ºk·Èh¡¿=¯ìRñП`É‘.~Ë¥î1úA;ë7í©”q¨ï›ˆ±÷[G…¯L»f4‚Ö0›ŒaÆ6 ò9®6ÈÚ˜ëmRsA8«ÁŸ¨x›4Ax–¼¥êDÁ Yï@šð“Bi8«R}WJå,|kò»]—ý%¸0riZü¶»Þn G„­‘¾t Aý ’§,Xéa¯+ЊÅAHú…™¦T+ï&°À·Y=LˆL-0ÓÍ¢Ÿäû1ÒÕ®25c{wc |XîÛ¦J!{Ý$ ¼ 6Ô©q˜ Ô†ýO#ª«¤Aö³‘,§ïlx¿•G.†  'ÔÖÓøò´ *´PÃ(þb ûÕ°_œ~ÐRlÔùYœ?ÆX‰³Xá¡Bö—߀z'öÇøøðo’?²kCÊéÈÚP¢b’F Ì’2î“[Q…Î÷å]òÞqÖ‘(™gТFt +䦶°¬"oucZ^£¯»¥ï}¦ñ¸¸Ãÿ²§ñü³µÿ$4W—ötëœ}¹Åêèb„”ÖÇZË0%/î É`ó#“)±{¿ñÃ3Çî·}Žô„Ûá  +‰(&c¾! Sb4ôékå͵þ˜aåØò;ú€ £€ÿuÁÐh^314ÎjT+Ò2é·O­7<¦iz’2 ðÎ"ÃÌ™. ¤@q'¤esú–¼ÔÅxzäY~&¯÷óG5Á]5Et„Ç2·¬Ý€UŽÿË åÿ ü?!`a2ƒ¸:9˜AìP| ¨«äÿ§¡ü/åØÎŒendstream endobj -1060 0 obj << +1065 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2122 0 R +/Encoding 2143 0 R /FirstChar 2 /LastChar 151 -/Widths 2128 0 R -/BaseFont /RVSMMK+NimbusSanL-Regu -/FontDescriptor 1058 0 R +/Widths 2150 0 R +/BaseFont /JKZOOX+NimbusSanL-Regu +/FontDescriptor 1063 0 R >> endobj -1058 0 obj << +1063 0 obj << /Ascent 712 /CapHeight 712 /Descent -213 -/FontName /RVSMMK+NimbusSanL-Regu +/FontName /JKZOOX+NimbusSanL-Regu /ItalicAngle 0 /StemV 85 /XHeight 523 /FontBBox [-174 -285 1001 953] /Flags 4 -/CharSet (/fi/quoteright/parenleft/parenright/comma/hyphen/period/zero/one/two/three/five/eight/nine/semicolon/A/B/C/D/F/I/L/N/O/P/R/S/T/U/Y/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/endash/emdash) -/FontFile 1059 0 R +/CharSet (/fi/quoteright/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/five/seven/eight/nine/semicolon/A/B/C/D/E/F/H/I/L/N/O/P/R/S/T/U/W/Y/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/endash/emdash) +/FontFile 1064 0 R >> endobj -2128 0 obj -[500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 222 333 333 0 0 278 333 278 0 556 556 556 556 0 556 0 0 556 556 0 278 0 0 0 0 0 667 667 722 722 0 611 0 0 278 0 0 556 0 722 778 667 0 722 667 611 722 0 0 0 667 0 0 0 0 0 0 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 556 1000 ] +2150 0 obj +[500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 222 333 333 0 0 278 333 278 278 556 556 556 556 0 556 0 556 556 556 0 278 0 0 0 0 0 667 667 722 722 667 611 0 722 278 0 0 556 0 722 778 667 0 722 667 611 722 0 944 0 667 0 0 0 0 0 0 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 556 1000 ] endobj -1034 0 obj << +1039 0 obj << /Length1 1624 /Length2 8579 /Length3 532 @@ -9823,67 +9974,61 @@ endobj /Filter /FlateDecode >> stream -xÚíwePœë–.îîNCpwOpw‚{ 4ÖÐ4îî \Ü!h€`ÁÝ,÷$À½ï™3uîüš9¿nÝ®ê®ï]ÏZÏÒw}ÕŒtZ¯9¥m V ˆ Œ“—‹G  v¶òpW‡¸¨qÊ@œl4­œÀ€g@ƒ‘Q -ÂÀ9 $0Ùä@Ö>>¯¨¨(#@âêÛÙÃ,z:¬ììÿ”üQXùüy¶tÛ¹˜ž-·öìÀò?ë2׿¯Éÿ†ÿ[üoiïÿ®¹ÿÚ£ÿr‰ÿ·÷ù_©<œœ4€ÎÏð÷’Äþ|WØ^[ø -Y`Šù½'‡•”ò7;)uƒÉ5ð{yi¯ôlVÇtùаap™$=Ú¼| ¿Ã2¥ÔD$mCG75vܾU‘'Ÿ·^¨%Qëê>±Œ­v¤i¢œÆœ\DÅæ$Uyœrï…¹Š]îI“°pS{ÕZXÕkÝJ´ÎÈw\xTû ni¨ õà=7¶Yˆ}Mäo“ÊÊôA6'¨'qž1§?õýµuÞ†mŒ:‡Ë]”9š5ÒŒÚieÕ¶®ÎZúN¿‚ 4¶°ÀZ™hïøT£n q8ßÊM#ù}J¼ÆK/'œ­îküNáNñu”¬;Ïa¨t&+ã;&ÛTüøŽ}¯_ÙÎ/åP”Ì¥µbªhSúOMDC:C£ýquo*¶“Ȼʹ*ÊÕã Û ¯ò“»í6ãµXp— -C݆î°|Dƒn’l³Fs*™3DÛj^®.kmiM' -ýœêe#¥M ó£Yùìì"Fà4¨¬œÎq›Â邱Jë ß¡cùºj çÉ -¥!M"Uk×ӠѽDöþÄ®v¸é5¾›¿˜”ÖžÐvÆ{mÚDÍ[‚‚µYxë04ÆÃµáû™¼ã¡x¨`ï㢘ÿGÅŸl¿Þ‚¿M2[韷(ÿ<Æ%ÏúSÒKÜÖxóŒÐTÕÌK -Ê¢z4²ô+êŠBÆ=ø ÖYäæVwv \,‘Äçí0~¬94¤6ƒ M<5îº+® äÙmf!à­4‡¿•2SÁbVa=áî¡bLïW7ÖrïŒ7‡­4üþVG»!\èpÊŽ¥5ÒäG­o#V×#KR‰gû³p(-¢K餒|D5Á\ UïËb¥Ä¡ïÎÕ*8G‰mT±%vžIßOH°w“3Ö+ؽgß°)»œjÝ„¯~ÍÜŸkºôØœ°&k¨;™¯—Öì$‚Å— £ - -ûäаQoâIÒîGžaWŸ¨•h‰ˆx=}«Ïí“|ûؼ‡Ðé6ÙF£¹VàjÁÓllyÛÃüù5N†¹á±£LtÝ“¡‰>åìÉ÷¾ƒŽ´OT ôNó˜yûõ²ëáô—p£KTóÓ+±Áz’ÈÜ™ ªÌ@¼Îâü/Œœê}í“Xñ$R¨ÅኾÝë;toK’Ö~ÕŠç7~g¨ nX,ÿ\¡Žˆ/νtD¨scÓÐý#íã‹™%¦”ƒ~¥@Úë+“wZï34ÃŽ®ÔÚ^Ûz:d3 -Žš(nÛ¬³&XÈ{‰TXíþ¯FeS¡Ûï#Ʋ¯*ì3w4•O£µ=9;ç—SCoES«1SK{^âÚó½q÷yô»è˸j’˜ƒè"'Ýœì_~ÉW²„凒¿yZÙŒ|^©ìÂ=¯ù•PIÞk^z¯ ~½±NoT2Ž^ªt‡}‹8”›Ô"bÇ -oaguÊ!ÛçÜ…ÒŒ9dëÉ’¿Õš[»Ó7õ§aNLÉH•.‹ð·ä“q#t|%öuþÄRÓ¹+Ænvê–‘¦žh}í½B׫üsóø‚Õ9*«¼ª¡M‹E“½h|íøiG½¡^¨!¥®_œÍeÜŠáâuç±ýïQÎ`Ÿñ‘Eôï þ©¦%³u£:GPb²Ü"â ž$•Ç…t“3=òáüŒ€-ÚYlAòv½YŽ¿ÛAòàò›œjv¿mºF­$ÎàeKOÓÞ|±•”.ÔèÁºAu–>Ëé(gEp‰ÃˆbP3P-,œYàm™Y‡ä£5OhÓoÝüŠú˜ V{Ÿ*»” -ð„pÞõ¨©îñ{ª•[•#ZòPxéÞ¾‘ -NÝ^8Ü «3ëæmVšRrnÓ%B#mÝÅÛ - i"á4O%qD?=ú%äʪ£u #ë⌇)H7tΜno¤Œ]`æ«Ð/ƒ»Äêv.˜ŠNvÿn1W@XlˆW#³¦4õt N7•Èœkx"ò×:É[¦:/¦LVñè¶Ì;ß“ƒ‘ÉŠüÏ×èávÞ"RÝds¨ˆÕ?ãª<](t¡ÎGWŸ2Kk"Û ç)Ü^o|dH´}Š|f;?8ièxŠäÊ Žž¾ÎÊfÒ¥}ÉónPë±V|ý½˜(Ÿ2¾`¨hg®†IĸÛiˆ þ<ÑÀUðI ã¬Û²ÊU©óRÉçcXC¸%9‹ÿðÀ`IøÊÒFŒëËÑŒSòÈ!Ù>–»Ql†ÎJû-¢iD¦óî»Yø6±r„Lýµ½3…aFIq¹WVµIé¿ÚÉø( œ=>¡kÅä^ W°Y š,ý¤ B·ÞfIJUìY†ë¸¹á^¹œþ€zî’¬‡8z´$NúÒá”Væ“S¿ÆåŠ[PJK R´ÙÜ*rWsôcï"P‡kª ÅôÁË”-¿/˜á㈓ëÙ»ò_èCDýÙWþÝYXø ­Æ!vöÅçWÎdî¢~‹§õO´Fu2¥Ø]˜9úB«þ»:@ƒ„ÁøÓú$Š"¡uå£Ë”àkÓ•7Q~v£·ä” ”Šn -ýeë_|I'ýe²%É*”-:ŽOPÏÕë—|6DêFëÈ:Ý‚bšFãƒoi˜SŸÚÕ¶ù•LÁV¡ðáx{kð§WìãAøÁnË}é…Þ‹bäQ>irîåÏu×㯣 ‚9CMs{–=&SíFSNñ+cnç9ü“7Œ ¡ù_zµ’èh€Y?(8³X>× -°.àVجÛ4ñmJÉŒûwB´Û›Ì:3ÖºÐéÅ’ñ×Ñ-ÌŽ<̲×q!]¦½M#Ýò¢ÇèšEÙ),f)é±³Gk§ËùdIÙ(<Š*ñýLØ)8Ñ|©®iÄ.#w°³‘.Ìnøk›ýXþ‡¿U6ÿR¸Z¦å«~úɨíx>$Ž$w‰íqí°ð“j.¡9bDE߬õg»oÈêK2´ï¦Ë¡”’¤DõÙÏO$;ô¿c’2ßVª¦¼z(ƒA(iÀvnýkÇ—“ƒÑÚùó‰Ü<ÞwëãOÛæÛùõ˜z) - †ª¥ - cÎI­7ã*oTQ¹¾Í†Û‰…¾(϶jääiý¶[ÿ6ýMññ<«$e —8§Äk¡ág©’–ˆÕ¬€ªºa¶”U…¬L‡RÊÍï¨_û7¬G$Øö<¡ñÁãx)M"Mi<ÅDF='Dí¹ThßÉô=¤Ì]”:H闤߮«4~ØM\§®­˜Æ«HÌK½™¯#·áÇ)U%¸_°ƒÄçaB[ctN½çÒˆõ˜#dŸÛ+i(]Ê¢ðé}ÚI“¢ÓFƒOTåXi Ø9U¡Nr°4‚ø0ÑHpVXõ¾ÁMV¸Bv]ª -V¾%Fެ´~Tûù’én…ÕÞðd´ùñ}sBu‘ißÔf6…–âo§Ü/ÙÎ3Ô›n¼¦p±s¦J¡‰Az¯Š3sx”t¡Z‡8Vùë ³*ÅlX¨»ÎQ"Îõ4,èÑÂRj[È´,ÛÆwn®ÊÖ×*§ úG ѸWÕ–‹‹¼b‚éd5óyPL~bÞ@LøÀ†ú>Ãå¬PU~Æø­•ÁÙ{’nÌך/>Ìè²»¢#KY"÷yY-:¶ÔW²ÎU‚ h(³ã5^l¦vëÖš¢#©w8º1–ïŒø! öj¯g̽¹÷Ø‹‰øÚÊ€µ VAˆúƆgÐhÏtʱtÜÀÔ5w¬ëÉÊ(iµ.A„Ö%RÕiôŒÍz¿Ðº…}‹ZZv9úüT§¨Dã…,ïß ÅØg£ÙÍ…pBõ:—"aâ»7,ôdUÇÀ(®¸C·0`UÍüuƒÒ Îy”ìj–Å)”Ã8ÿ8õ–”3›FTÜ·Üü]ãúžc‚HTLã[?˜àä:AõUéC5¥´·$kl†2f-õ'»/`3_iªÞ‚Óe]ë¬G¢J“$áˆE㜦5¦q*=I³ý1„lï}¿èè×(ãËñ>¹Vž…¨ÛëwONÌ|$·“¨Ÿjçýr‹Ó¾ÞgÖ"h§'Óî›#«QèRêë_å…‘qh–õ&7è>«5•îùL=ݰã…p¸Èspïï>®é™çxÝ1• ìg‰²8çää}¤’/N\`ÑW¨­›¶n9‹+^–sÐq”m²(GTβŽ]±‡~í½¿=H¬`ô]ÛtËŠÖF´/SÈXÀaŠ>ú2ÍN:UÚ†¾tš¦÷ \bD–Ô»œ!„ÜŠ5ÿ.øDÌï_àùsŒñg7‹ŽŠ³Â;þ²jÓÃîŠÂv#z? ©mÌGޱՇsOß [Á®Øõ )¦cj”°ü.²¬–4«ë›xvU¶.yŠ6•+\þ!Û¯&l¥×‰+©T ”îì_«ü³!²IJü1PS˹7I={¢­ÂÔGÂÂ'‚‚˜HJmú¦4=­ô‘Ÿ¨ý˜,‘´úe5ß_‘T )FÚÍšÂÔîKÑð'׫£üt††Ðlgëžÿ™í-Mu×±|Ôõ}À}/é‰4¶OÛvGâEš~…sð¨ïª=/¸£bmæSÄ.È’”Ûˆm)Ê‚?^FáÔ|ó«»(úü&­¸¬lVkùîØœišYã­kïX­¹Us»P÷Íž_TÝ› µ3æÉžëMË€¾Ó醈`Žõ*cªüR5fí¤6uci&C±{’g>׺ÞüÓî·yÙܱ]ârA¡À„ ¢9ÉÍ|ŠH…:%9]ò¼ôåS”³xb¶Þ<'áRçÂe\¹$ă¾Já(-â›äc툣ôýˆu˜q‹nõÓ¥áÁrg)Æ<ôÄt0ôoôp›èÑ2å9Ð{ïÇ|óYaÝosó4cBù5Å«‘åÚBèoðï¸Ä·É{X. ¼yz¢2ïnQ‘6Ôð”D3¢èüÆ&4“ƾévÉ28àËá-=î•l)àÛÕ4xažœ ½”Ò{,·S#`áÐ_Ù—s²~a¥d⚺½+:.3R•;k?ú]±$—ÏÈÖ²Ö}™¬ý®Û—¤úëŠÖxùGôÝA zcZm€õM]Å)ü5òÜ÷Ô÷ΓòlÉÄç¶vr_ kbPwÎæZßýÞýæ X\¥U}®pðc#®~?ùö+Ãümå¶$WZTÎÚç¨_᥿ÉLËbàQg*'”qØw³†óq•Nyá¹ËM°¬h‡òzÆ['¿¥×"ôÅ¢±-9f)ûÈÂy1ù»œ‡U†°–b}¼fγũíÓUf9^¨,ສg(+:ÒvÏÐóò½ß؉ñΟicÑ&p!ÉÖ3ÇH«Ä]˜ù" î¿ôR3§†_ã’J­¬iÖ}3ÃJ§<œh„ 3À_4°çeÐ%HD fª‚ª‡&HTcÄgvpL†£ñ®Ä3m3‡TWµ†%ùÓBÊ}âú%I~Ä\áÌ&^ÎÐvTL• "TÕÖ GgpèÄ2Ò]á;þÀ)C‹ {Œ,ìY¹¦7è9–s -ö7n&„B¹š.p{%ø*\¸ %ßÖ˜8e•^4íã9m®RÊgAW?­•â«.oh76 ÐÉPXd™2{²nLÏXý®u8ÊÔ­ÙB¡2‡Ö­bÏuNç7ÖsÏ J~ü™äM•¦ióíF¬‡0Þ—ÉÕ¿ÈöÎ2«—l”nç“oú«6”|‡Ç Jr!˜ÊbÊ|øˆ¶“q2XõüðóäQã콿À¢ ®ÉáÁcl×Ï—Ý~ΔêJ¢1¯ª"…‘Ê Z¸ÆÐÃü¹\ÌKðÀ$5wÅ¡¦á‡ZJ4‘¥*4› -IÅD³H?4“ÂÜœJ“ƒ•›¿$%èY}e‰ŠÕÉ$L(¯ÝyI 2Uü$4ðUðú3ÿpXé%DmßþAלÊ Cšv&¢J%­ ZŸ¬Úõ8…b¤CÁÜ„±÷'Ë*šÓ‚®Õéxô¨w |D$Ø•8Ò->IÝ3?Z‰ŽÉu;–ò(Ð]'üMÇUàJ"ôUøúÕAƒÆy¡¼¿1>ÝèPx,õ)òat{³Ü׆(ÿ¶f­()è­ßš§W²P<ðIˆþ^òÉÓØNiÉÇ«ß$x abzî¸8j_, Ùböa’è¨Ï`KÔ«Âu+«Û·kc·­¹| -IÌÐI íßòÓÇi€39!5ÄäáÃ^,$)¿Û˜p©P]¾ÃRÛéòfû&Ú_Àå„ÿ"r¥–VkDqO½`D’Õ3 ÷üà‡x|ÚR¶¸òÝ/0Å4oÈ@ݤýûÀçp»¶ ĉS켘=ÛY¸ÛÄkánšqt¢úþPoBÉ6rÊ.Ô«‹´òÕÇÂÛ^*6I7õ4·áJøÐDë¶©»ö¨m~Íb½®G¥!$ @ž¨KÌU*Y±ÂA§lnw1P‚™ÿ$­cV¡¿Û;ûŒ—lׯN„Ho6ÐÄ¥‰QDÕâsÉ¢”µE»È„Ó=ºƒKÞÆb9…~vÞhö%Êüžæ;ý¡(3»í ´ýMïo<ùb±AvC‰ö¤úÅ^ýÎFÎE3y¹Ñ"Ã>ßRâµV£¢u(ï5ÙÐõ%§?*ßuGJ¯ ÌÑ/R˜pÁéÎoÄí…¸ Gf~ö}7Òc‡ª%)o9çqâ_wǾ|¿ò2ëBdØ2ºg¬‰MÜíáÔ(rñ$ÿRÅôja«•ËôCîÉ÷ƒþûTÔ÷µT.EÓØØ´ÊÝ‹—gon)QTsï¯æ©¹¡_9ýuÁæJO§T´6^Ö´<‘¥§³ù6x_Ç`X‹àVpÔYá®xèøãûŠ9Ÿa?…’¡ -0s¯ÿò×}+4šlØõ%7éì‰é.d·AAŠfõ>DÆc,+ÁÒɸYw - I³4sýõ;`°¦Öǧ‰žCͨÃE…ªÊÕˆ@ Òöà¸ÊĺÈþíØûz1Ó$Þâ†uFØä}ŸÙ†uõSÍA›²”ww›ž4s{+2‘'¡ð^®ý2ú;ú3tŽ—R¾¯EstÛS+NyswJ,˜Ó¡j”môÁì‡soá]¥LcÒýL “µ¨æ]°&üÌ0”¾™E"ðJøÐp-¤þâ'´•Üz‡™PM¬eà©Ò"qç}É‹‰-.¸ý/Éì‡$íp™^/‰¯‰4}ƒ!Âo7Ï¢pn|NŽòSÎýë¦4%ò]$w(K&›°Í>®™i+·>V’åb`ȼ®TÜšyšú*§41êCãÒ‰Æsõò7Œ4ýa -Q6‘TòÁØá§dÑß’1÷uÎT(6R_m]Ô1Iä›5·DÌTÚ[W”e$']ûyá¾Ü²AOê®5 -)“âgÊ7Mýæñ(xâ)—8¾°Ù¯&ªSNù¹_ªÈ¾„Ñ8þ‹†óê^u;Œ\¤ƒ€¡w óµUXÌ(fMF#ÂìûÕÃL7¡¾]ñž°…šâQEÿz•óM×ÐQÜýóšÒv¡eôâ Ôº¾ÊEÉ,Ï[J[&i]»y’œÎ3³ªÁÇ}+gµ~mŸSÁ ¯-$é%ó¶ }Å+j¢Ú›ú…ÞZ£Ðãæ¶¨Ã`=ÙbÁWŽ›íc?fº¨RßEXAúÊ*O‹Þ"bóʱœf׬J -:¥*j@þVÂ_&u.Ьçè<1­–øpåŠücÝ$<†³ÏãðÛ¿t!Þ!+·šFX;µ±÷Ñ›‚àbršïM0,M(×ÓT±ªzÙ ¦é‰ã¡`oßYÌÙ@qªÖq†‹þq¥mÜ7šqsU«£|6"”̈́ -?í(M<¸¤8ôCî@Æàú+—»Ò•#d“P{—¤ù¶‡Ög¯ù©7½lŒyçÂóé½c!sª²DFà–=÷WË\·Ú8ìû´eÏ/nÃBÙî&¡ô˜››uÍûä/L»}Á â…Í ,~ ¤”vbÂAèªÐeE»ÏÐ/ÁEÑÏæX¹Œâ-¢aëÍ¶îÆ¤´C³0Ù–,^Õþ”C,OkáÑßÑV *º[‰»¹Ò÷sç'¶±P™n¼ZÓ§€qé’:S·Ÿˆ˜QI •]žØ:h~ª¤Zoá@„¯-_¬N7,¬Š$J/’5i²S#*Þl¾.*zr¾È–Öþ)l,Œª;v`áiÏ-Dÿ¶•Ý»@%˜8…ÞB$ˆ«#O¿;Æ1‘ú#­Ç Ùa²:çu†ç‚†sž–ÿG3®áOpŒÓYáÚt1r¨Tü¼ÊÃÛYíÁ „BDùxµ»lûôY¿øÆw‹§™n¬XA{ -u‚jUãá(Õ6óü1ùõd…醨œ‚(øìyþÁ»&õgzYsNDu^$¯lÝsÓÚÙ¸¾GJÿ0¨“À{3†þíÇ|^/Õvyaq'°´¸ËPópnF3g=?!a;D+!}Æœ¸J[4=ËÁ‹¥Óa|_j´Ëˆìª«§mÊÎl¸?Êhl0|¬õ¼À†Ú5‹“UŽ÷5c3ê…b à ƒÖnœØ }Hdv*õ–ÀûŒ*±«àVVE,f–á b_Y,\þ#¶w"\¾ShÙ_½Gö¾’øì5D›™Õ3¬F·‚Êáwü¨«î¼mކÞ{ ôq¬pt‡!øÂ¼„?dؾ@¾ ×/)®óÌ›æ(Æ2S9Ä_jnzÿZylØÊŒÎ°ë&ôÞ\SËHôÕJgþ‡%>8”OIüi’&á’k{œ°Êêù% ·ã'L)ûúîºt¡zBÀκ),1³ž„føáÖFÅ2~½ ’—ÚpWš$€e]ã+ úYm-£Þ>ûBO˜™¨*³_C;>ò²[öMÈY©í;9ñ‡Ç\!ºÇÆ.îfÅ)>·À{?o&¦ÜV£D£K¹uŽB ó“Η’„ç7.Ö˜9<þ?Àñš&YŠ}PiäöTýŽ—)Ãô­,jäœvy\ª=B -ÁkVHÜW/¹¹Kefv?ù~‚I¬µÖ­êtKcuâŒ7´L-ø9è2Ìÿ&ÊÉ-¡ïþ!D°‡ú(jµ#Vo+¥ú1/±q”y¢Ì¸g yܲ ùN ¾æ‰ñpþÀhf%ǹD!a%Þ*kEty,ô/ÄéÀÛŰú{^N:•ã Õ#£BiØðÇT§¼÷NM‚N“œC jJc38'NZ÷mõ±4ký„bWTÞ?PPÐ}ȈŒG/óTô›!|±,dGXSú&ÓÉr~áíÔäÈÅŠw]|Þ’Ó„cÅR4•ÆÀôå¼ÿo•oh{{t«õª¨©Îm²á1hi·Íq’Ö“•Ùsâ—-!w$¹·)ËëŽÎè«¢ÅÌWøÌ$Q« ~–tTÐëZ>µØèkOÐÜç©Ç®1#m"v©F6`Ûj ÆdXzˆ—Ї+ûèD‹3½° [»Z{œ¬tùwNV]ÌÓ²ó,òÚ´nºBq#IMMPÄdÇûéTñK- «˜>“ÂÖFŸŸ”ePè’gÑq T6ìÙ @9y3·o»Y£ïrj—Á£è”ò*‰†³_þšš¥Ÿ©ÁÌÊ}¼ ‡yÚDþ8®}©{É+dQhÆõ·ø¶gN\Ïv¨ˆa¼)7Ü‘%8@l¶toúµÖ»¬É3í—ñHÛ]1vÑ£K•*õJÄlŒŸ©›€÷ÌýT´Zwýá¬A„vbCËø#´tñ6Áî–1©RvÂð!T{g†¢X_ô±íÉyþ—ŒÿOðÿµ…AœPGŒÿ_º*-endstream +xÚíwePœë–.îîNCpwM‚»Üh ±†¦qw'H°à’àA îî48A“Cö¾gÎÔ¹ókæüºu»ª»¾w=k=KßõU3Òi¾á”²†X‚ä!Î0N^.1€:ØÉÒÝM â¬Ê) q´Ö°tžA FF(Cœe0@d Yøø¼¢¢¢Œˆ‹7lk°èjë³²³süSòG`éýäÙÒ lë `z~ð9B\œ@ΰgŠÿ±á³lÀŽ €Œ†¦¡’º€EA] rAŽM÷çT¬ª`+³ˆ`ÿ>¬ ÎÖà?©¹q=sI¹€7øÙ äerùq\@P'°›Ûó3ì°…aÏ5€A`g+Gwë?<Ëm ä…´†8;z¬A6ÜêسKËÿ¬Ë\ÿ¾&ÿZüoið¿¥½ÿ»æþkþË%þßÞ祖wwtT:=ÀßKð¼e UÀŸ=ø³h\ÝAÿ— Ð ìèýßXý«¢>èïHÿý+¦>—CÊÙö¹%œ¼|\<‹Ánò`/µ&fe°:>Wë/¹®³5êv=wõ¯‚>ñðü ¦c¶rpþS~Á¿!³õ¿Æþܨ¿"çÖT“Ö7Ðeÿïvë_ššÏ3Óñvþ}5ˆõþðHKC¼¾œB¼N>a€ˆ@D˜×ÿ¿ñø ï?Ïj@ì0æáâáá<ÿþãûÏ“é¿ÐÈ9[A¬ÿÌÌÐÙúyÌþSð¶r‡BŸ»û×ÍNúç¿òYa,ÍC¬ÄÃì3²2aµ¤y£²Æ=ݼˆá.% :Å…AÕ®ÀŒ¨MÑ +‹ß5á\ãb­Þsß]v”Ùv»I™»Ò@§Tþ/X¿â¯1µ ³ï†p›•`géÇùžÍªn  ñèínji›}üB=ÞÎE;»e záQDÄpã‚`•^ÿ–¸¯Ž ¶èûSÊÁí sßÐ×þ® ä/;”ì¹oÑÅ=°™bƒ\s)%Œt+|£^Ë àcš¤HÓ¯øbD{ˆÂÓ®hå_ãO•Ñ8V§%Ål¢¾Æ3Ö`éT¤¼‚cØÄÍùÉDF͸wvÎ%™îåH%ãc×ÊÎrYÓÀfhجس_ Ë7åCüUœB>þ¾o¤²:ØÏ Ô÷¾î}'CL!Ôk‡»Pôë*/Ìò[! ­â‚Y?ËSR]¸½ní΄Ê~Åœ Ž #DiþqõÒi!Oï +ùÊaº5BOsö;5¤²nÛ®”‡1?ß×!¶Õ¼Fä›`¾EïÎf%¥üÍNJ]Ë`| ü^VÒ#5“Ù>U¶,lT*$A6 /WÍo¿D)9A[ßÞE»¯oOäÁçeˆbAÔ²²O,m£a’ «>+^¾1AU«Ôsi¦l›sÚ(,ÜØV¹ZùF§­#â=Õþ§‚[Fª½Ph7ÆM&âCo#ù»¤ø²ù2y=õ)êilºGôÙO=?-íw¡ë#Ž'a²—¥¦ 4#¶š™5-+3>S¯áŒÌͱæEÆÛÚ?W«EAì/6sRI~ߟ¯òÒË +g©ùX½—ÿˆN|)ãÆs"•AàÂøžÉ&?®}߳ݚÀG¦ãkx%cqµˆ*Ê„þs#Ñ öàH_líÛòþЭDò.SÍò2µ¸‚¶cô~r×Ý&¼¶aËnàbAˆëàö‘·hàm|¢MæHvsºhkõ«Õ‚%ÍÍsu¢©¤¡Ÿ“=l¤´É¡¾4Ë_œœÅ¨””Ò8n“91Vh½#àÛµ-ÞTöw?Y¢Ô§¾LÑÜõÐop+–¹?µ­ªEzƒïê'&éµ' ´™öZ2VõzIÁ¿Ò$¼yíîRÿ}LÎáPŠ3”×/”})WCÄç^<"Ô¾±®ïÚáÆHýôbºY‘)ù O1€öúÊø½:†æ‡tУ+ÕÖ7v†îv™€ôü£FŠÛV+àŒ1ò^@+œÙ³AÉDèöû°‘Ìër;…Œm ¥S…(-ÎŽ¹¥…”›Ñ”*Ì”’îWx€ÖÇÀD‰}œ>sWw슱›ž¹¦§ª%X]{­Óõ(ýÜø¾duʃÊ(­¨ëFÑbÑd-];|Þ–B¯¯ªBH®ígs³d¸|Síqb÷{„3HÄ{lxýû¼Úþõ‡¸€1»ßÌÚœ&^^0*Ò7w:è¨}eëvjg˜MaY‚Ð%U7Ξ¸ˆ1]ñÔÒò<‡ÕÉ‹!¾Ô«L¬5m÷2fmû<ãí?S¦çŽ ƒŒ×‚ëWÕ‘QÛ—6 ‚ø‡ã!­Ã©bVBÑËwEçòn9væUŸì« B÷sÅ[º'®SöÚ@+¥ïn85ÒýŸHb– +\F P2ç´¢•ácƒÑ‹Ù‘…rò‹'ŽÔZOêÞ£ÐËT5ù„–ämýÂÆ¡\ƒO¬nÎhY¯ÊT£˜(3‚'Iáq&ÝàL‹x¸8'`‹r›—¸]kãï²—8x¯ô6»ŠÝw‹®A3‘3hÉÂä'O,˜G9¹5j v@Í¥×b*’ÅIœOb?¬Ð ÔP M%gxWªIVÈ!ñhÅÒø['¯¼¿.:°ÅλÒ6ù€@š<.œ»M=b¢³G<Éžb©ÎV逖4–Hº·ïK¤ŒS»7àâĺq›™ª””Óx`Ð@[{ù®Hš€@8ÅïÏSAø²ýäʲ½e#óòœ‡)P'dÖŒno¸”]`ú›Ð/ý»„ª6.˜²;NVßn81—hL°g/#³†õ½T5N•È&œ#kXÒ·Z‰[¦ZO¦í Vñ¨ÖŒ[ŸÓƒá~‰ò¼/×èa¶î^"’]d³¨ˆU?c«<œ)´ NGWŸÓJª"Z!ÉÜžo½¥I´¼ ½g:>:ªk{ˆëçÈ Žœ}ÊÌbÒ¡}Åó~@ó±F|íƒ-˜(2.°p{¶šIĨËq þ"AßEðI ý¼Ë¢oÒE±ã‡¢÷§Ðú0 r¿¡þâ°åÅKŒh—W‡ÃégäËC²},7Øz íå¶[D“ð §Ý÷3ð­beÖz«ë{çòCŒⲯÍ-kÛÓ~µ‘ñQÔ;¹F׌~Z¯r[Ÿ¾ÖcOSô•Üše  O4CwT(„¨]§kfž—zëd̹:E.g3G5Õ_üIA…nµ>Ĉe! ªÐ½×~sýücê{?ê…s’.âÈÑ¢8é+û3FX©wvÝ*— n~ ,!PÁzc³ÐMÕÁ—=®“@ ®±&Ó/C¦ì>š#ö¥X÷Þ•ß|/"rÈÏÞJð‚WXhÕö13/¾¼v"sõ]8«{¢5¬•n/ÁîÄÌÖZñÛÕêÇDßõÓ'R +­)ýHF º6Y~Ûé»n{0òiSÖ^q _±ð¦ÀO¦îEþ‘”8¢±7_'š-CØ¢bùu]<ÉeA$o4¬ÒÌ)¦hÔ?úõt’†:öª^m™]IçoÅÙY?¿î(g‡$ ÀO Æs[ìKÍ÷\!xóI‘s/}©¥¸{•Äb’Ó½ä>‘b;’|†_};ËÈá—´nTÍûÚ£™HGÌ<¦à\0ÊdùR#À:[áo½fÝÈ·!)=æ×é×jk4íH_íD§KÂ_C77=r7ÍZÃ…tšŒ÷4wɉž\¢kf%³˜&§ÅÌù¯ž-}øå1(i-ïÿ(ªÈ÷3~;ÿTO𕚆!»´ìÁözš0»Á¯-ö¹c?Ë,þÅ0Õ ‹×}ô‘[qÎ|HÚí‰Þn$/?µÅ¶Á^ôÃO¨:‡øg‹îXéÍt ÞÕ§kÝM•.@)%H‰ê>±_œJ´ë}Ç$e¾!¬PH3èýP +ƒPÒ€m\ûVO~L DiåÍå¿Làæñº[{Ú2ÛÊ«ÃÔM–7P)‘uJl¹!{øXq£‚ʵ3f+ò¢,˲“§eg·î+lê šÂãEfqrqv±ç|ý{EMË5ƒ,IËrévÅä›ß‘¿öoXH°íxBâ‚Æð’ESyŠˆ »O‰Ú0r¨Ð¾/é¹Kš9+¶“Ò/J½[Snø¸›°F]Sç?…)Vž›r3WKn'ÂS¢Bp?o ‰ËÅ„¶DkŸxͦ;é›!dœ\Ø)ª+þAáÓý¼+I§…Ÿ Â1/ÒØO±}¦Lhoañf¢yÉYnÙó7XîÙu®DBÈ_ÞI‰^nù¤úóÓÝ2«Áé +hãÓ‡¦øªB“ÞÉ, +M…ߎ9_³œü§Ó©7\y9LàbfLý”Bãôžå˦fð(iÚB5ö±¬r/Ö@¦• +/ôÙ°úQw.#EœêhüYУ„%UÛ96‘iYÆ·ŒÌï\]”¬®)”ÏâõŽê£p¯ª, ¹ESIªfs èLü„Ü#€˜ð5õ|ºó XŠÜ´Ñ;1*ýó$]˜o4^|œÖarAG–´@îõ´\ph®«`­ë úÓPfÅ©¿ØHéÒ©1AGRkwpe,Ûö=B@íÑZKŸ}{ï¾þ­…k ­„õŽM£Ñžk—ai»Õƒ©9«ïX×’”PR!ª‚-‹¤*SèÉýu¾!µóûæ5´8 ì²ôyÅ$,¨Ž‘ Fõó™êß¿ ˆ±ÏD±› á7èv,FÀÄwoXèÉ*O€‘\±‡®¡ÀÊê¹ëzÅM:í¯r$(YU, “(‡±~±jÍõ(çÖ ¨¸ï¸Íù;Çô<F‘¨˜Æ6Ž™æád;@u•iƒÕ%´·$«lÒ¦Íu§»/`S{)ªž|‚³%«ÌGw¢ +ãDáð£ìÆU¦1*] ÓýQ„dl¯}ߨ¨7(cKqÞ9–ã¨[kwOŽÌ|ö$·¨íŸí«æ|sŠR¿ +ÞgÔ h¥%Ñî›!«RèPêé]å’qh”ö$Õk<©6–ìùŒ“=ݰãs8Ëqçsïï>®ê še{Þ1#ìgв8egç~¤’+J˜gÑ“¯©²j>-Z’µ×vi™4/CTÊ´Š]±‡|ë‰}¸=¼\Æè½,²è”®> ×kýH&«Ÿg9‡*xëI79j»Wj}üÚ1`’ÖÝÿc#¢¸Îù!øV¬éwþgb~½|Ÿ£Œ?»X´•äßó—V™ttõ—œ²Òû¾”ÜÂ|ä]y¸ðð·ìŒY»”d:¡F Íë$ëÇjNµ<`±ºé†gWa딣hU¾Âåï²ùfÌVr@±œBâAéÊúµÂ?,ѨÈ_­5±˜ÍÆq•е#Ú,HÉõuÜ¢y¤Ë›RÁ¶?âr6ÔŸ ­Œ7ª›§E¸lÛ6¿õô8¼¢ÈH‚yX&ÑÜÆåZ°·ñÓaÎ~ÂR +)¯…=ղ݆â &И2Ù‘)„j‘^ êK¡„4“°ÜD•.")M¸ îo[¨j´"¸ìcŸ8§q cø?ž\Ø—:mÀw +uHöó¾¤Ç|X(ÂÎiá—0åÁ¯ýî× ‡%ɸìÚƒ]~2¦ˆ8­¢3¤PBþã^äK,l<0‰”¡ÄºwRÃÃRù‰Ú—É I³OFAãÃI•B„íŒ Lõ¾ b­*ÒW{pͦa¦öùŸÙÞâdW-Ë'ŸÜH£û´Í`7$^¤©W‘8z.êЋü;*Ö&>0A̼ I™µØú‘‚ ø3àU$NõŽoíeá—·©E¥¥Ë°‹c¸3¦)fõwÖ.=£5f–MmB]7{¾ùP5/‚–Žè';n¬·ÍýòøŽ—D¤ë"‚ÙV+Œ)r‹U˜5ZV % En‰y\kºsóL£¸;s2¹c:ÅeCÜñ—D³Ùyò뵊²:ä¹iKg(Ç3æxb6^<§a’ êÂ¥\9$Ä>Ša(Íâä£mˆ#ô}ˆµ˜± ®uS%aéA²çÉF<ôÄt0côz¸ ô(é²Oè=wÈF£>yN¬F0‚®w9¹ê Ñ!ŒüâUȲ­Áô7ø÷ó\â‡[äÝ,—PÞ\]Qé÷·¨ÈŽëªxŠ¢é‘t¾£ã‰£ò;:2 öø²x‹{e@ +ø6Uu^˜ç|:¥ÔËíäð%X8ä—@ÖONÙ™¿° +SÒ±H]^åí?ÒS”:j>ù^±$•MËÔ°Ö~¨ù®Ó›¨òëŠÖhé¸Zêî @­!5“Ößꦶü þyö{¶=êÇ{§ 9¶$â [Ùo„5òѨÛç³ -ïoGóù/. ÈR+¿”Ûû²W }˜x÷aî¶bK‚+52gõK䯰’Oß󅤧d0ð¨3”âK9ìºXÃø¹Ê'=ñÜdÇY–µBø Üc‰­’ÞRNªzcÐØ2•¼eཙüœ/ŒB+‚YK°>]3çÚàÔô‰é(±œÌ×üq]ÔÒ•h»¦éyù>¬oG{åM\4Ù™§© ÌÔîå«îTäfo¢d¥SʆuÓµ‘´F”T/¤*ÜÄ"Úé‚&‘v”gH æÅBY+*z âÛ“kȺªñŒ¯W¾q ¶Nr1=æÁ{F ³N·>©)‡kêøW}À{×.¬´;UBòœ•$‡3/ïtwG¤òt$qËoGćâ·éçë][ +‘mv¿`€÷˜¶”¬d檥—ˆT®•¨U~Ì:¼dLTФo*`›ð=Csì„ :Ó‚$G£C‹*zÒÛüªˆÇzY]R?ާiÊ­6&ldr¹á}Ö¢ç2D’©cŽ–R޽4õ1@@Ü zå©jF ¿Ê%™RQݤóvš•7Vi4(Á¦¿ o-ÎË C +ÈŒ./–ûš¡`¥ßV¬åÅù=uësôŠæò‚~ÃñQß‹?{Ù*.z{ö­`!ŒOÍžE¡â‹ù'™ÏmQ5%ä,fÝOýjïøÃ–î—_e^Ь›GöŒ”"°‰»\ÃDnÂßCå^)›\íQ#l6 ²s™|lÄ=ý~Ðwÿ€Šú¡†Ê¹`Ê›V©káÇyùÛ[J•œû«9jn¨ûWN?°™âÓÕ#­µ§íGd©©,¾uÞ7ÑV"¸åµ–¸ËîÚ~ø>bNçØO!d¨ ÂÜk¿ütÞ $t~ÍI<bº ÞíÛŸ——¤Y¹–vÍŒ·…t0nÔžAƒS-L]~ýö¨®ñvÀi¤çPc3lwV¦ªt1¤ˆ´>8¬0±n!²ï|Ä»c_/dǙ߰N è5]·ªzЧ9¨eS’ôêöjUÄ“b.doA&ò 1Þ˱[RßbG}ÎRâ²QÊõ6kŒlyhÆ*môãîOŠqÚWް<˜;õ´ÞUH7$ÞO7#1Y‰jÜiÀOáA‰àûYT)®„ꯅÔ^ü„¶[m3#ªê!5÷?U˜'l(~1¾©Þ ·?lí)‘õ¨&Ýãùò[Mï@°ð»óH\Ç›xïÓ£¼äó¿ÚI—yÎ/vå)‹'±M?­šj)µ>Vå¢aȼ.íÜê9šº*ÇT÷QêƒcR F³ur7Œ4}¡ò‘ÖTrAØagdQ;I˜ûÚçÊõ)¯„6/k™^æ™65‡OWØY•—¦Ç“'^ûzâ¾Ú´FOìª1ô)•ägÊ3IÙq<õû!›0¶ä¿ѧ*ª]Fù¥O²Ð®˜Ñ(î«-†'óÊ^UŒ\¤€¡gó­µehôf'MzÂÌ[»•à W¡Þ]õ±îÐùꢿ:åd³a —Üý‹|š’6¡%kô¢@ÔÚÞŠ‰i,[J&im›Y¢¬ö03³Šþ§}õ+'Õ>-ï3ÁtÏM$©Eõ‹z¶K=ùkj¢š›ºùžÓ¦ÖÈà i]™"Á×m£ÇÓTH)ïÃ-!½¥g…ï °ùdYÎ2€«–Åù’åÕ ?Ká¯Ú—…V³ôö ˜–‹|¸²…~1®/‘ܳ.bñÛ¾v"Ü!+7‡Y;´~±wÑýᢳ›î1,Œ)×RU°*{Ø ¦è‰ã /Á^>3˜3â8T¬c —}ÁcŠ[¸o×5bgó+WFøÂ­E(šÍ…ÛåÚR»sIrèߌÀuWÎw%ËGÈÆ!~vΉs­-ÓNžs“o{Øs/„çÓzFƒgUdˆ ÁŸ,ºï¯–¸nµpØ÷iÍKŸ_0Ü2]BíèÑ77k÷I_™v{ƒêÅ šæY|ÕA‰ÉmÄ„Ðkm =ʲV¯o¼³ ¢¯õ‰R)Å;DG–›-õ )û&a²M¼ÊýIûlXžæü£=¾ƒ"Tt·wc¹)öçöO,lyb¡R8K´ÆÏþcRÅÓt&ò®?1#ã+:=°µÑ(|UH5ßÁßX¼X™ªŸ_¾,¹LÒ íÏJ /°ñ¦°ðÉé2KJë§°‘0ªÎd蹇·` ý»6Vv¯|å âdzs‘@®ö\½®h‡êO´îÇ@²Ã$5Îëtys §\MsþO¦\CŸá§2íôè¢íeQ©úùy”†¶2Ú‚@ñˆÆrqªwYvi3¾q ïÎ2\Y±÷ÚåkU+ÇÂPª¬çø£ýóêÈ +ÒÆ °9QðÙsý‚v9êÎu12g‰j=I^Û¸å<¦¶±q;~?”, +:Ö¯}‰÷v,}çx>¯‡j+’¼ ¨XRÔi q8;­‘½–„¿¬Ÿ6mF\©%šÆžéƒàÉÒi?6‡/9ÒiHö^Å’ÕÃ&y{&Ìe$66Úr‘oMí’ÉÉ*Ëû†± õR¡ð•Á¯k7Î[ì…$"+•zSàCz¥ØöUP‹µ;«3ËP:1Ž .ÿ Û{‘q.ŸI´¬o^Ã{ßH¼÷ê£LMëV¢Z@eð» ¾Ô•w^6'þƒ¼¾z9–9ºB|`žB_úÓ­_!_‘ëÖxæL²b‹¨Fíã®F46<Ç~­½:1haFgØu• ü`¦¡i$úf©=wl†åQž ‰ÿÁµ5FXéFõüÐÝö¦”ysw]2_5.`kÕšQGB3ôpk­l·–_ÁKm°+Eâϲ¦þý<“¶†QwŸ}¾»L‚LT™Ñ§®ñ£[æmðy‰Í{Yñ‡Ç!ºÇ†Nî&…ÉÞ·Àí{_/&¦œÃ|eDòkæf§¯$/nœ­0³yü~öƒã4Œ3z¡RÈm)zí¯Â“‡è[XTÉ9ms¹Tº…äƒV-‘¸¯^qs—,HOï~öù {¹ÚLZ»¢Ý%…IhØ3Vß<9ïk¯Ã0÷›(;§˜¾ëXˆ`õQÔr[¬4ÎFRåS^Bãóx©Q÷(ò˜E)ò"|õãáÜk€áÍr¶S±|ürœeæ²èÒhÈ[m^ +ˆÒ—³AÕ÷Üì4*‡ËGFO„’P°Áñd‡œ¾×vu¼v£¬}  J6J(c8'Nj×mÕ‰kݸBgdî?PPÐuȈŒG/ýTø›!ž|¹$dKX]ò6ÃÑb~þÝäÄðå²W/]\î¢ã¸;cùb•zÿÔ9¿ßÊÍ^Ð`ö¶¨«QíÛ$ÂÐ2Òn«Ã­+³Çø/Bîr/–YÖmí‘×… ¯ñ™I"Wâ}-è¨>¢×6n#°ÖÓ§Ë¿ÏT‹YeFÚ@ìT‰¨Ç¶&TGŒN·p/SòÖŽgzaN»zµú8#Xáü=ö6Œ¬ªˆ§)xû#YÄ)´9pÍd™"üF‚š¯€ÉŽ÷Ó±ü—j" F!m:™­•0./1S¿Àþ4×<¼ý@(°tÈ£^ž> endobj -1033 0 obj << +1038 0 obj << /Ascent 624 /CapHeight 552 /Descent -126 -/FontName /JWHHZP+NimbusMonL-BoldObli +/FontName /PMBWXU+NimbusMonL-BoldObli /ItalicAngle -12 /StemV 103 /XHeight 439 /FontBBox [-61 -278 840 871] /Flags 4 /CharSet (/numbersign/hyphen/period/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/r/s/t/u/v/w/x/y/z) -/FontFile 1034 0 R +/FontFile 1039 0 R >> endobj -2129 0 obj +2151 0 obj [600 0 0 0 0 0 0 0 0 0 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 ] endobj -1026 0 obj << +1031 0 obj << /Length1 1630 /Length2 10814 /Length3 532 @@ -9893,8 +10038,7 @@ endobj stream xÚíteT\ë–-w‚-Ü ®ÁÝ-h h…KáîîÜ¡p'H ¸;—àÜýqÎíîÛã¾þÕÝ¿Þx5Æ®±¿5ךKæÚ5¹Š:³¨©1PÊÎÌÌÆÂÊPÙ;;)ÚÙ*0«Í•­A€7€ ™šZÜhÙÙJü- )@h`g°ñññ!SÄíìÝAæ`†š=##Ó?-¹ŒÝÿy‹t™ÛhÞ^\€Övö6@[ðÅ;P€-€35 ®¬¢#«$  “VÒHmŽFÖç·VL  ­`fç°þÇ`bgk -ú«5'–7.Q'€ÀÉhz º™íÿ‚˜ö@G“ÓÛ;ä0w4²¿ÍlÙšX;›þUÀ›ÝÌîï‚ìíÞÿ©{#{{k÷¿£íþöú@`' µ 2û[Nð[ns-òÇ¿–EÖÖÌÀÆú»©³ý¿c.@Ç¿D÷×Îпadjgkí0š!T²¿¥Ðý÷TfùßùAâÿÿWäýŸ‰û¯ý§øú=ÿ+µ”³µµ’‘ÍÛüã’¼Ý2vÀ_÷Œµ‘#௻ÆÁø…Ù€¬Ýÿ‹ÀuÔþ£ØãûWXlô6Q[ó7a˜ÙØYXÿa9IÜ€¦* °‰ÀÌÈúmfÛ5lMŽÖ [à›¶õ-ˆ•õ_°Ï +Û¿Dàú´5ý×òßäú»øêš -š’JŒÿÕ û·§ÊÛ&€?»Ûÿ–FKÑÎô?ñˆ‰Ù¹<™¹ÙÌì<N/›÷‘ño¶žÀŽ 7ÀVVV6ÀÛÿ¿?ÿ<éÿ ¤­‰é_›£6²5}[¶ÿ0ü›8;:¾iü÷÷ÿÖô¿Ÿÿ^{ Ð h‚¼8gg"d™š‘®ÁÏ镸ÒÝÉÓl_\ÿ¹0߯ʮÃ75l¯Üð©:˜¥aœÿ¥Å}öÐþy[Žag°Ïš¶ãð$Ø›’¾+ÿý*M+ãNÀǯÅhiGZQž§3 +ú«5'–7.Q'€ÀÉhz º™íÿ‚˜ö@G“ÓÛ;ä0w4²¿ÍlÙšX;›þUÀ›ÝÌîï‚ìíÞÿ©{#{{k÷¿£íþöú@`' µ 2û[Nð[ns-òÇ¿–EÖÖÌÀÆú»©³ý¿c.@Ç¿D÷×Îпadjgkí0š!T²¿¥Ðý÷TfùßùAâÿÿWäýŸ‰û¯ý§øú=ÿ+µ”³µµ’‘ÍÛüã’¼Ý2vÀ_÷Œµ‘#௻ÆÁø…Ù€¬Ýÿ‹ÀuÔþ£ØãûWXlô6Q[ó7a˜ÙØYXÿa9IÜ€¦* °‰ÀÌÈúmfÛ5lMŽÖ [à›¶õ-ˆ•õ_°Ï +Û¿Dàú´5ý×òßäú»øZÚrZbŒÿÕ û·§ÊÛ&€?»Ûÿ–FKÑÎô?ñˆ‰Ù¹<™¹ÙÌì<N/›÷‘ño¶žÀŽ 7ÀVVV6ÀÛÿ¿?ÿ<éÿ ¤­‰é_›£6²5}[¶ÿ0ü›8;:¾iü÷÷ÿÖô¿Ÿÿ^{ Ð h‚¼8gg"d™š‘®ÁÏ镸ÒÝÉÓl_\ÿ¹0߯ʮÃ75l¯Üð©:˜¥aœÿ¥Å}öÐþy[Žag°Ïš¶ãð$Ø›’¾+ÿý*M+ãNÀǯÅhiGZQž§3 k°ºÜ¬š;£ªj_!Oð$ã­Žˆ§·ô~”.ù~8T7öè>&)u±¸m˜ PX5‡G4‰û·7´½Cý}çp]ÛDŒÙ±HÔ.°h4‘~ÙDºåžáŒ[ïjwÈbºr¸°ÌN¤î“ƒðÆüSgÊrUm4>_pû´e{eÊóÀ@’ªí!B¾^gYâ¶fˆ^FT{ônRçz[âœ5Zóì3ŠìŒ—*J–># sÁx§¼*o.á_g}wýœñl^îkÝŠÔ'Ø’(Mô{Ä'’WuçÙ>`·pòdèŸoR[ÌÒö! íë&XôÕFZü¦½ê>ì%Ü}g·û[˽æb6J¸uq ÖDP»}"ßžo«/2åKžxÊ$©ü&Ú6|I²k¢QᲪÖÒß(Fà"A=PÎ2íܘ??ý@²å·‡•Hki–óº‚i¦¢'¦ãfü¯êäœíe'×ijÞ ^ú«úò!,lÌ@Q“àx¹ ªy—3µ€ÖßDáµîÂôÄ©;bi¾©õZä7ôÛf]q?Žlcß?‹}…U´YFVg½\BšÃfÁOAœ¾Ý=ðÑP†>b*˜ª¦ ‰¯írß[îEÍÀo]æ7hÍO#Á]ö aOp£Ñ’ݬyÝGÜéÁK² ´dÝŽ½6[ Û#Ò¾ç‚u¨Öåºp³àž\¢4hS ©–Eéf< ¢sj`ß®›ÌFpï(üÊæú|k-è=‹ãEâï°ü‹üTvalÝ´X\0X¿Ù¦?˜|ew…­K£KòÉäÃïÚØ¬äÊŠíŒ]Ý: %¢˜~¡¨ç7GÊÎÉÃÄ} .Íâ¸M¸  ý¡$úu}ÞÕ*äW˹ÑwçQ ®ŽW_hi+yñ¸âÅ‹…† -ë‰f m…ÚÐJï¬ùÏ¥‹û ´¤ešÌiûFt& ß–³´Ó²ë“´›>Y`™å³{ëéÄ2 û“°dõ>sf gz s‘žI Ï¡¡Æá÷”êK“VeùÞÉÄ;NIN² -ÅêàÒ[xŽø?‹¬ !¼Ž”xí°åJ¦vY`™å³{ëéÄ2 û“°dõ>sf gz s‘žI Ï¡¡Æá÷”êK“VeùÞÉÄ;NIN² -ÅêàÒ[xŽø?‹¬ !¼Ž”xí°åJ¦v> endobj -1025 0 obj << +1030 0 obj << /Ascent 625 /CapHeight 557 /Descent -147 -/FontName /SVLVEN+NimbusMonL-ReguObli +/FontName /WXJWBU+NimbusMonL-ReguObli /ItalicAngle -12 /StemV 43 /XHeight 426 /FontBBox [-61 -237 774 811] /Flags 4 /CharSet (/quotedbl/numbersign/parenleft/parenright/plus/hyphen/period/four/six/colon/B/C/D/F/I/N/O/R/T/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z) -/FontFile 1026 0 R +/FontFile 1031 0 R >> endobj -2130 0 obj +2152 0 obj [600 600 0 0 0 0 600 600 0 600 0 600 600 0 0 0 0 0 600 0 600 0 0 0 600 0 0 0 0 0 0 0 600 600 600 0 600 0 0 600 0 0 0 0 600 600 0 0 600 0 600 0 0 0 0 0 0 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] endobj -949 0 obj << +954 0 obj << /Length1 1606 /Length2 17112 /Length3 532 @@ -9968,107 +10112,104 @@ xÚ¬ .†ÖF #['*€©#ÀúßÀÈÎÖØâŸÒœèÿb 9 Nö&F™¸™Øÿc¢Ø›8ÚX89ýýX8Ì lÿöÀÙ`akdíbüOõ¦vÿJÈÞÑÍ_Û_0;'g'#G {gÀߨ ¢bÿÎÓÙÜÀùŸØNÍ;Ó¿žÆvF.ÿ”ô/Û_˜¿Vg ['€³‰»ó?± MÆNöÖcÿ³w´øW.N¶fÿ•-ÀÑÄÌÀÑØÚÄÉé/Ì_ìºó_uþ·ê ìí­=þuÚî_^ÿ+ g'kSz&æ¿1œÿÆ6³°…aøgP$mMíLŒÿÖ»ØÿO›«‰ã¿DùÏÌPýMÂÀØÎÖÚ`lb à gçü7$€òÿŽeúÿ>’ÿ(þo!ø¿…Þÿ7rÿ“£ÿíÿ¿Þçÿ„s±¶–3°ù;ÿ^0€¿Æ øgÇüÿ| l,¬=þÞÿé¨fòï ÿO ’ÎÛ dkö— -FzÆ+-œÄ,ÜMŒ,œÌ¦Ö{ô/½Š­±‰£µ…­É_.ÿÕF#ãØ”Í-Œ¬lÿi:Û¿M&¶Æÿ™ù_zþ•7ÃQ9õ4ÿ¹Mÿå¥ð—ugeû¿‰ý:díŒÿ—ð†°°;À‹Ž•@ÇÌÁ `çdpr0ùü¢ý †é¿dYgG w€Öß’™þUøÿøþKÒù˜¶FvÆÿL‰’³­ñßÁú_ŠÌF.ŽŽùü×]ÿ[ðÿ”ÿ5â&&î&F0kËvF<Á–é¿2œë0sG&Eµú˜@GBìK•‹ -ükìzýÒÃw¹*õ?kC蛦¹¿Û=–Îí¿¥¨Æú0¬)zSM®óñ|H¨ú ·È;9hŽtKá3.Ô¢½nevÀ4ÙUö&ê–|BàOw²8BݼPù“¸ø£‘>Û#ø¥5Ä¡w!5¡Ôž_'¾}Û kZÿôóüwÎá\àèe"°µî€”PX™/,3"@<ÔSÂ{4ÂÑ3#­¶«i7.øÙ[ÓZ‹ ô­·6åÇ7«¯uÇeHfÕŽvl9‰® Åà.¿ÚCpôמ¹ï -ÕZŒ™ÓØANvŠ]Ïy–ãÅ{iGçý2ê-úA¢ÿ}ÛcÃ~~*æcd@Œ„8ÓÔÁ?W‘2,Åi|Z…È%sÒJ CÓº‰¼¬–‹C!ýñà Ä~0w‚—„L¨„ ‹¡=%¾,jl‘¡Þ‚Fø8;í¤JN DË·¯U7÷ôw¸àô‰¸gVáÆû)§ª!‘Neå~Žm­EGÂýqÊ¥ -â9þÝÌ_*nÿAv ÙSáýÀ°v€<÷ÁÀÉŠÅÜä±ÌWá ŠÞâÿ.±hMe”:X³Ï/=\“õ 8èOª~îTˆJ~^‡Ò¯(E>JA±Y|̼cæ¿çѰ>Pã}õÒ¾Õ*"SßRØM}ñ7•KŸa:uÖKúÝý HÒô D¹¿£„‹lű"ŒƒÎ¥Õ\ÏR°#_ñ1ò—ã.±¶•õ¦üã7JZ*|“P9 {Èñ\U-ã±°¶ -Ú¡QZ±¢›w¿‘•Üv7óŽ-ʇJѦ®!ÀçÜ…áÚó¬Ë9€FÿýÖì=|»KYg¨^BX³Ø€ÀþJk8»8—MzþòÎ&38S‡uìTÌoŽ $àǘ^zE—w#ÊÀˆd8ë;ãg]¬M,ýt’Ž{ÒÈ%Ñq%%mw„­Ãî@Jeâ_õðßsÞg¯`¦RÈ5EB† nDŸ¬‹Ÿ"8ïnx³E4 V;þ6Qh\„§Þ=½X ’þ“Gþòüåŷ싔셭bŸ§ç\EÏñ Â—°w#¡<ª˜Ûa·÷‹~uÔ›š9>kÕ`•–ÚX´nz«að|ÏǾävœ«Œ+=L6¾Møf"Hó²†ÖÚü‰Œ6ßñž? - ,ÐmÍŒ%²Ž¬î|ø"Õ?YHå¦õÆ]½ô!P!1):X·œø~R¯µËöÛÀï/ìº×Ø,‡°ñ·¢WÅýí`ôÐõ g¥°âtãÏ䱇sæ¼e³Î4MùGî>8¶»’d÷ºëFÛÆö¿®3 û°½i.ío±Ç|Í¥Z’2D3yˆPPjñÕfGüf0¾è<5éõ!S¾/!u¾ûµÀÓš -Ø:|‚¬·.¶–ó_Mv“ôacæ~ϼr²]‹Ë±¬ˆóÄa©Öbß:g× ¯ïëb¥-±÷#ƒP!»‚ŒCîîœbL ÓÞ˘]÷]¯* dÏÕ §„n˜"}x3< `C X‰ì4áJrÛBHõ“ÁÊ„edÔI¿Ì | `Zþ©Å 9;LgÇp™or¬øæ•šÀTʪµiÇõo²G3iØD‰ùÑ®äB·ÌeãÿBÖ’ G«¨¾7”2À#?Mš*í£gm¥côG=èÞ[|T^Êh¸Õ>w~õO¿þÜДr_Ï68È·R©¡XVÏ-‚˜$JÁÏBG×2E"ÏÈš×å=Ú¤2߬ '¢Fö‘bP©¿)‹ÐÞ Ç³Í~Èo´‰¯Ëd˜ž¨D¹²|§ƒ#!vµ’oÑý$WG+³…Íö÷—¶vËx‘’ÁT:UYà‘’ˆ”y€—øÞ¨ôû³b›3¶¦~"î ³Íþ i !ÝT=ŒªÐr/ 2çñÅÂâлHh:cA×ušÍ/[L€ˆ¸?´4~i-pL6‹¯¯g’^†æ -vß¶o…'siEI݇‚>TàM‚ ó.¥t§>À)— 7J®ò¶M¶"Wv,ð ò{ Ò~|oÄ$ï!½Ü¦ |ñõï˨²ͦBÇÓX¹2á{dåÖÔ ÈåuîæÙÓÜŒ¢± -åsõ´ÊåÐh?‘«åŒß¥éÂExÜ%8Û5µÃ³ÊóËoÁÒ¨§^RýÏjfrM¿Êí8Å޵xà„ˆ;“JÇÒéy.±\Gj×tP6;L` Ÿ6ìRØ#6C+9G÷`Xòñ/+?þ±ÔE²d n`ëæ/F»Ó y³¦s™N520üBoëÂ¥ÕTu¥X³W™ÓeBi¢±¡Ú€™nŒÆÕŠøÉ t¢Ë¨ûCØí ¹Í^„<ß™&ñ2Ý5’­*}¤ô/Šd²FЛØêZÁ?˜M‡þøËá̤( ’ Óü€þUÒ³Ën¾ê|*0¢¤ô;‚·èb€ÜøÕO1ñ÷¯‡¸ÀdñëxÜ\6€¡A©¼!r“›ÎWL¨ ³ •Ú ªí⯣nT“Û¸ ;¤ëÏDc¹B#e >ó—lê±õ2ô¦ÒPùi÷ ß±é1¢é¼½Y½ë—aÉu«Žœ.@’Ñ é¬ ºá)ÒK“b§úb¨‹’E{xaüá;ŸýIÒ®õnjgôO¸·ï•×_ÝÁ¬Ÿ -_Ë£Ý% }\RÖ:èJÞd­ÖX¶d–> /Ä,n’5¸r%£à²ºš–øŸmV$H‘Æql=ˆKZ»(‡ruP÷S™äR“Çчȵc;"+?Ócù†”•!kȼª6´ÊïÓ‡l¥ýá4Ç(A¦†K)-Ý’vÝéÏîÅ‘‚LÿJÊr ÷è½Úƒž ~g°Ç¿2c‘„$St[޼ì“[É]ø³1Vz¶ÞZè±J=£YR]5Þç9ðš|[EyŠEšÂ:4ÿx©â+*©æ>ØyDUÇêhÌÒ>I .­ö=ý1ý¥Òc@ßÇîìq㦒ÇRj¹z8¡v˜»7ÖEUß}-Hè2¸Â…÷ÇvV:¼:_ŠæDÙ¯ñ‚-§¡mé«VÎ#PÔü4QÖw×ï7`§¸o¢JžàFݪ<^ÌÓä9+²Ãóm%™¬vËYàQ¾`ƒáÁ¾uïÏi,gϽϱ«â_–ó®2 ¿^Ò–L€pi`J¶Ä =C‡ç&zM,¸M,<Ôy 1H†æ'vÛÕbù“nx…óÚ·ýKK*›¥,/6y#?H¯[M¥UŽÜÙX AçºF1~¯¡ŽÆŒÀç¾ÇýЗZ]aý\WÂ2ز»p׸ÌGáÜý¶žèuvßÀŽðucŒõʉ¬ËWÑeºwXSH±‡?Ï^–“\ŽÃï¥H×y0&ÓcÒIJVîÛÀ©×Û ê ïžÚï‚ù1E—Ì3ß®jf²ˆD]õz I퇹`ª¢Ö6pÛ 1ÚaTm‡Û™úß— Žd±*{Æ",T–]BÞÐoæ²V4ÚX>}Á+G C¦2ží-L¤JËÄÂ~º0¸3y©*¥#fç^ø¢(¦þ˜QËŒ¥m0ò˜&C–òŠˆ\ ‚ ·sTj‡¬A:&Ô¬XõDGi¬x~7ãJ/oìØ Ò—48é®Ì¨¤ðbÍå8m{|gòG—b2m˜êVüoidmçÑñþËÒ6ài;è<ҤϹ‚%lYãÍ¢xÌî—jzÈÙÉuLƒÚu_­\êæ»´åe¿÷|2Du\Ô`ÐTãE»+‡U>| -RÉ_‚!'zÍ”FøÔ”Vé†u# Žežà º°ÙOLSÀžeúíÖEx!#ãp Ê^0ˆ1üS¸à–lƒîÂC‰«„2í¸Ü}Ýóx(¿à -ξ.¼ÙúáäãD¾[ÙvÄ›)LH”k€Å!C¼…eHêtrƒ÷I/K‚ Ì'…&‡"Å‚u´ƒø.BˆJ½ÖÉ6Ï<ômJ®b2¢´Û}ArL®'îz“$ær,ýíæ%¾Ù£ÔYª„ G…&ûÖÙ9s_CÆKàöÐÊÝQ"K+‚M=2èy_*ê‘®VrÇbæ“–©|.()$Yám¥¥ÎWîw‚45…[ -Ý÷B#?ƒôúT×ϧxß :ÉÜápø»ß­Ó«§ Òµî2Ó­óƒ׌Èð“- „Z°è–¿ - cHì›R¤»°C\qbl -pïswóH -kç„¡ºØ-y*ÄmkYÙ>â2š¸’Ë»§ -À§i°~†Ò°ŸÝI}ƒÚi|ïóPãAùÖ /—™¬\µpe<­8M#¯š"’%+ŸÃ~ÖÕ -zAâ:Û—p¼!™^ŒúvAò£b<±¼«·ÏQždWŒøÍHŠãD*uK*½­:ÉíF~±1`gÇTÙŽÍ€2 úí¶­XšZeï§òA°´´oƒíÖü²™Í’h¯Ò3Î3{VslÆ.kîÛåÝÓU½jh•² gÇ?³ü‚:©’-“ûò–8HMÌ™Bnñ&Bý@|Sn'‘–½%T7ÜÙç–ÑN„ ›¼ãd_ÛC3®wÇú»²ñp–tjºHgîUŽUP°}Ö7þ€ÜI±ìrLEm° m×Ei—¿ú„V½ïÖR¿ŒÊ¶fn<›¼X*Yµçç¡4ò; Öor>Óqí¤sÒµ"…ñù·j§t‹¹ÒØ"⺋Ñq§º(±ËóˆþŠ -& SºY e H;Hÿ—q¤ðËêXæWiú@ã&kêoÄé"´%ËÚúWÅ;yfÅ -v«šÌóvI]ô« ;î÷÷¨¸F÷.Ù¢™ÁTÌï„`/ ¸˜˜­Ji‚>S,®#˜”‘Ž—õñMâ‘lL÷Š‹ïŒ®zöœçŸ¥z¯„Ú^Hì»8§jƒ9Ux,§}s'^­V‘Ÿ«¤ñ¾`<@\-ؘãûÄvžN‚ðüìAåqy|ª“™Ç>$’ïÒÍÇH¬ðù·ÆHÄUÇMXá –&£‰.BÍÓTøÐÙ̃DXÂ5ʼ$×Chë¹âG÷ MøÄ‚)¸ÕPk®GSJBc‰%»ÐXê›XÔò‚bcžëóBq3©‡É%øÂ8Ř½Ý·óÛV•‹,,n¨Àˆç“tQÌ¡úL;Ržˆ?úzGc£Wt›qØÄ±7¦¦„öµij6Cì';*8ûAŒ,XíüZ—ø[]ÔóÍä#S*Mͤ˜8µÃï}I‚(/´Íd:Ç€¾•[ăLMbT¾ˆý±û9<­þá⼨d2ʦ¯·Cj=’£¸@ýŸzv<“QÛ;úbñ¤ŸºË¹çd)m§™_h(ÂêÙ`¿ØÁ4t„0¨ ,ÀúR æ.bÞXôCMj‡î×ZüzÙîæaò3“æPgpÁc!Nn<—,ï”b^ÆM¬3‚Ëpü}ƒp:}|ô»DØâˆ]%'ÁTå¹:#›AÝÍF‚Vã0b0‹4pÏ‘Ï)hµaA+Ûz¿C¡è%mÜgªą ÉIßb{Á6‰wƒ´·T£Ò‡c–wºf -{{~D'ÛûÔ ð.$*>>¿¹1îmÌ›ÿ‰ó(¦Wýbš¥ìl6ÃÅ>-³øªd~R3ù -|hD +i^Dí£.(€ù«483R£ÁIJ“@¢t)­ü„ÔIm1iM?!+øM{äa÷]¢°A4àƒš$–O}÷™'ä§îÞ¬Ò[{/T|F¸óC}¥Œ±°sH|=OKRe©y”‚«Ÿ>¼O¡ì%œG“)Ä6<¦—rÔ¢þS,ÂHǮڇ‚‰¾Ì&%@¡™~j5¢ÐW¼Žã ­ÑçÖû:èµ{"ˆvfT!Æ„ï· yµºqIzÚ*˜mÖvÉ?5{T×0DÓ£ b9h¡ óòyÂ3–½è" -øvé硎ŸQ-\~X^Y<.ê /ŠÀ­1F0îñ­ßÀñ¨<ØøùJ]Rî9˜¹t›V¢6[8ýÍÉô½T5é]ý¢âì;÷¨:ÒB¸ájÛÑO7õ\CÉeáÌq.ªš¡èËŠH–»ªÛ©]ïd”Ò+>,ܼ`LšoXGØçv-seSÞd¯W†éɇ۞ 0§H[x— ô…Ì>„^¤ÁvJ• ð@FƒÞ„–ôÿ憉’étŒBžÑ ”ýÕ&!¶¢ªH*Z"¼ñG¦?€Ââ‘Ьg -R}¼nÜÎè-xâû1-ÿ;„&Y A½œ¥AçºxýˆK\ëS‡¾¨ b¥nGU/0´J·P›Ò(ïeߢ½œiñž¨Î»È’È g 1ë{"ÀÜ|¨G3+a/Lò·Ù¹–ß2çÓŠ,›»Á¨©âà ½F9¿¿#úSŠoxûCw|g¯óu`¶ªu¤MÔm†² D™×ô—|ë3Ž;Û•êú½W:Ùe¸Ìg-ö(ƒÀkЋ˜®5ü¥ìTlf²¤íiìØMO­3prN]ý -AAé/«®|ô‡ïm?‡ïŸý±jj2q¾4(æ²Øèð‹zQcaœ–çTýr.š­5Ùðþ~йc¢{ ¢HËœ…"$mæUËbJÑO£¸Œ ÿ 5ÙN…MÛ¡ -¾Ôáç†8˜¨±“EH•.¨ü‡ÐFM)ŽC‚†-‹QõYzö?·­l’KÂDжöŽ·­'÷!QiMùbƒìè÷ÌË¡k †ÜÛö -ò7ðሳÇW°tò>*4HN˜zú½á0 Ð\ìiüp?ØJ³)Ó'žÐêd<×ê`YæV .-Y#ÈåÜò/¥Ë(ì…ÕqÞÎx6¿ATK,rOÈ Ýœn¨åá¶4)š³m0½¼ˆ.Ó3Ãe¹+Îvûçg¨[ù§r©Ñk]x2ÙèÏ,Rè\žmê,†J ZFFx¾8ŸïÚu¶.!¥^R¿o}ø¶¶Ê—ºNy”ì1€XÑ0× yⳘÄû% -ý³[r]Ù'‡Ê’œÕV©_jÇÅqÛ4åÁŒ¢ð›ÚŠC.Xuÿ ûûÖÑ;exhhÞyvM¢*Š%`d#­˜~Ýi­4Y}ÏtRµ£åvíùÐèÂ0°îÁO.,ly9.<ÁøÙ+ÓƒÅÔgí+¨XÞ¿é^Côkë;“[QÎÀˆ2È7ü= „þ8ª§xuü¦HŽ(ßáèµÌ±mÈÇîçV»¼ös„-·ÝÅØ UÑ7êIàÌiΘ”*9óÅ“ „Rä¨+üJ^ôny -QhNÐúf.•“"©xÆbä!‹4ö|/8ôë©c©û¨Ö2_Uÿ9NF“¦‘˜8MæÕÁ -E$Í] 02vL¿1ý©â&ÉwxÝîÆ;|JWF³¡¥Ü_†>)27ê`Ú>µ ½| ëÔ©$@ôƒ -¢Xo× ¸çœ÷åõ¥|_wùät ø²jšç—¶:âlÁÕ*‚h#²°#Ò”‘g¿s$Hç’gñ&¥n!"ÖÝ3à T¦x›iã×/°…æ÷¥hüiXðꪽ1[„n” ÅT²µÖ·@Q Û’….nŒÈ‡0¶ÇfÆÑ8… ‰ŽÝÏsÓª°—yXæ[vlùðNðÏë­ûË$b71¹þy/pß-aÿEˆf¡¤b-~Kð’‘êçȃ¾>0°hü³OzyůƒÛ{´ -Ïg•¤ÔÒdkqQÛÓÑW_½æ·¦5ˆÞ°Ä-IL>Ä‹S¶?üD#èU‚¯ð&š¬\ Ãàb‡âÂÐèrÖX[nþ¯L^•S¿Øš1'¢/n–ÂÌò$µën/&glÑiø‡ÖÅæaCÀ^@×é4¾nï¹nIãÊ<÷I‚ŒÕÙzßËž€¤˜Zh‚q‚rŒ±^ZgÇî=D`ÁË¥ƒ†·ílâ2A³õ5(q:Ú0D~¸ø/ -úÀžºéâ9Bõ$ÚÀ +¢§0mA®ìR–¨öüBQÀ†9FJÐÔ ²õú ï™´Œ ¯¥µßªñ_['ˆ|zì·UÍcNiØ11žö¨É|Ú~iÔ(ÙRãÿJ T-~=ÝZÁBd´¹³õ(˜ßHK?ÄÍ‚™&Ð=¸LszŒ%:‘W^ßµwk-iéšRoº ÀSKd€{™W_Þm¹°Tk•3*TŒ5õ…ìÐh6¹qºÊœX+¿C²ç¸:ü€2–¿ýåX/ŸD»šÃu Y· ñíwEAM·ôå¡9ÿ®ëŧv[ŒÑ º.h¯l~gfíмiŒiºI&›“~l<´<},n_MWêznÏo{êt ¦™‰!ÞEâ37ÔC)jFC ;> ªÖ“UL¾Û5Ã1.Чr™v¦zß3¶îŒš8 î‰ük§{°pX2>}íRCçXñÒ@Þ4õT4_d„5wé´9¿ 5ŽoB¹ÐPªúÏŽ“=^šT&[¢« ™ -Ü ò6éx3¯¡œ)ÐlXÞ:Ø#kõ«!1ÌÍÝÞîv¢[m4ðg¥¸ð«AA07–JîºywÓ½ßñzHM_PQ =#Ñ4hŸÝžÏ%Éôúz ¹F˜'Ͼd|"óÖÊÃÃ?öÞ*Là¸4vô‘«ÁŸ‘dm±Ï@êcOò÷à&Tp0’“K}rÑ`fUx~kÍ[q€11Îâïc -àà·ÜÊèëTwAU!¾Í†¦vÆIˆ:#·¿âŠŸ?ò—´ù}’A„rÇ܈ÉL{@½j»<ø!Ñ«ŸÑªjH¶Ëpá• ž¦oHä7oáDžGÀ{{«žT«îÅÒ[Éh‰{Ø]åO]Ø•ýÌ1ù"Õ\³¢Î}Ї)õ»XÎ3«Â4oâ#Ä£Œ´9Ûõ4‰taÊüÔšU­q7Æ6y·ŸXDºoœy§]C¨£zLyX_°ÂÃé¨2ÿhfåϼäo¬E7ƒnÇWvV)(¦Gè¬[ƒHlÊõIÖ§;Z‰‰¥Ë©¾7"M8ßTÏ~«·—.~¥òN^Ël­ÕÞӷ* Iée„ìFòäoÄÍ´]P‹^m5YÀ IƒZ)·O„1™Î艕þC9ëü(+3®áИ7—Âgry#ïˆUƈYÀ¶5 DP í´û¸Ñ?‹ZK '¼Œ8±Ç!é‚ÜiúдÞZí‡Ù€b¾4šÛÆó3ð•Îg£ÆÍNt³d#8g¢¸R&ürzmÔ? ú‰¶ZûX(ŸBßv"Ù­~ìD ãÒú‹;71ÿw°—1dÒÒ~ikcFbY.Õh•/;§pÔÅ[˸ÛAp,-÷ƒ@b!4–mKß$iHR -„ŠèÄŒ®[1õŠSG›X*£ Ç|ÌonçþÌÎ`mKý‰—5µ°D®Y‡`´W¼ÆÊ;×!søß˜ïÈöZ1¯È O²­†‹òS6ÌbþÒìu¬í´‹à[,5a„y¬‹ÍæÝ÷§Bc/°½\ix½¿ñälñ`^¡œ" Z$6²ˆ¯µ3îMܦLñ¬ªš%KtÇ$]ˆe#/…¯*µÀ}ÙB\g˜°àYëû ‡ E)F^SZ¡ÁXRP€óæ7•q>Þ"û -%þ4MG9uÄbÝ{2ŽÐÞá?Ó˜·ñÂO‰t8ÔyÕx…ÇØmÛ‰¸Î@ -»3ç{i›TÔç¿ë bA!-¾9®œ¸ ¬Ër‡åÐÔu³a Ç|†bÍ8R¨ÖþŒ¡Ô:¹‰¶´Àx‚kÄÈÒF{†Í_^±ò"&‹3y˜fˆgÞÜæ(h^¡V˜%U -4½ÇZj,%·Þ,î§ ˆ¾O²àœ8[°mÍÑ ó„r¹yðUýF]O“/ñúó°6;^dï¾ ê'7zSí2¯N ,Ó$œ’*ÆÐru>‹ÔJ#*»"¦;ˆwá1Ô2nœ@f'=/M`AÕ÷ 9£ fqLwËÛ”Û.„­¶gReЛJZ^§í'~êúºÃÓ(ømawÇÃ2•ƒà.„¦n‡@¢.÷DVäý»±–dgÑõþ.ëßH±²9•P´G‘è&D1ÊnÕb"£B³¦˜ë*c°#•l'xýù¬†R™àD—Ý-掟TôË]]܃|6±ÿÝHŒ`Ÿ™qÞ7ø5â2NËl«„V.”l"Së [5 óI»8®ª"‚éhþ¹v¦$-?ò«<*:ÿzªÏ -ëÈ©ËèH§¦]1;ÿõˆVÜ}8gƒ³·*Õ€’`iíT¾Go!&Ó¯¨Š=Õ„¸eeWh×·I?¼‚!okuš‚6@ç0IhÁ¥¤*oNG‘Ü@‹“»aµ+2bü±À?MbŽJ‹Ÿ`û8”ÙpÁ`‚Ë(‹3]6ã‹]ËEÕ)pèŠ_ȕո…DGª³w1¢ëbï:ÖS<]±×# êP^Ö}?¯ÉDéè&wv™±jŠ2Ô’=C¿ã˜Åš{dŠ;aWPqæöqQôÄ×âÚ#¢.ò~]½¸]‹m·ÿãnP¼~gÀxáT‘úøî÷<ýÀžmúV1Ÿn…õïÌûOOa™’Sži3ÓÞæ.ºØÕ½\H›üS¦é=¯ÁFÔ ÂOÊu< yÞœ= Þ ðëƒóWZRw&.e™¨1àsÜðÊ1ÈX†Ã^99kà­£MÖKÿND4ßœ29V^[ uI[ÏèN«Ì¯·ƒíôñÛÅ¿§ U^~¸Lèk±±‚Ô—ÿÈ*Ž!UãÒR×õÚ‡ì‚îÎÇr^ D¿ÀÏs!ÙÅUŠ™ê€jlp0Âjžü#ª7&q¿ñ}æ6h´Â9èPå „˜ÊZíUß ËþËtÊà ÈvŠ«Îž÷޳ô)ã” ¨HÊPJ$šEù?#§«î ;ÌXHÖÝÔ£ìú¹ƒ¦Ûœà9QÀþĨ…Íc=?QUg•áN혈½›~Šô| V3­—E¤¬×C)œ9öMêÆ5Ëo£æ;l -;U–Vº'¿P@´ò~þ¢:Üi<8ô_¤;µ^D+ -SŠzªÛ'_P èc¦¹8*Mgí)ÿ®O "z¨¿™Œc),ó•S±:…ìÙ‚0U®f„,õMP QOAQ5‰r*Dû-+±E-JñÛ^k z¤î¼.xáeú¶¾£29ÆÀ•hÔ¿ãC\¯¥s‘úõÑ?õrãl×Ý^ŸÇ=s[í²«˜©áfoçô£?=Šß;ò4]·ÓóUµkÁ”^ÚÖfÊÜúìKZ=lÔíÓÅÙ¹¼f${¿ÊvR²ƒVõPhÜÊ¡Û'Í$4‹æb?Ý 0dLù#S&¬JokÒQjº‚õÚ#³½g™ÎÜlZtn›j‚zì(nÐG7€#ð,;YREj¹†D€}«ÿ9RÒ&ñJ4•À° €e͆¶µ…‚œò„ K -\=c¹²E®¾98wyÖP—Vg••ÄÌÀ÷ æy©é“ÜŠÎf´ÜÄ0pѼ!€Ÿ„üú†z·®Jn%ËAÈÐ=Ð -âÚ?ÆCÏz| þ±rèou¤¥J¡ð9`º · 5àñ û˜ä9X´É™¶”'÷ºœš¿=ÞrŠ2}òzåÄ0Š„ Ñq9pÉ»ô2|йÐûö ÆeNαðYÿð6ÒúátŒîîF̶*Dÿ{ÚF°€ÜÛ‹,T’«Mƒi½¢‰UÔ2÷•?Ã\~æ¿9«,¿>Ö~z×ÚÇ›?¼ø1èW?œ,ñQ ¾®Õìñ,¦íÚ_J= 鵬Ôvæi«®Æ ï3 -ßZbÔj­ÿ*»5ÊÁÝtŠc@u¤A®èÂY‰îLœ@º<·Â!SÍX¹gË[&IvU5+{˜¼šßéüš)ôK>Aq¡í†,¿èä¨û;©Fæjt‹nòúá¸ZðpÈ5—b»¬=æ„7Jq/kÔ÷d*ÏÒ“Ö¦k‚k¦$ƒ*@2ϳ’z¥ªëaµP…IV¦SWi«1a[C=Ë.D‚j/²¨•. -¡ñÍæ1V|wØÒ½Ý$çþЇJ_ùÞ$Sç8e‹‘1wÜ;ËÌ]>-‰D\6©O²mF±÷[¼ü:_­ýúc´ã²&Ò•üC«Ý W -¼Oíäwx%2Äk¾ýÄS(GQœü|sª\ÏìTäG¡ùƒOJý®Å1‹ñpqw ^¿±›±DdOuüÒ¶?Ü©Àô„í˜;†d×xˆ< ÂÓì‹ño½K­Ê%ÊLœX±[×ÚqA©Aw£-¬î2’5´ª2ŸÌœs°ÒvÔ©BòSº ã†^i:?)Mµuß“U@t®~PÉ#£ÊݤHè…¶eCcacÔ¨›l=bßS,Š˜&©§ÇžgVŸøÅ#m.fXí“NÖ{ )tO^¶|àéÂj8”ñ@‘eX€IÑa.²~SfÈá ay_èŸNWú-¬Þ7ºÒu<õÃà”µ}™î¸I ÁTðg Ãg´œä¥~%>Ðoë÷°"« q96.9 ÓNüÿcSd÷¾d&"µ7‰GâxœÝ´EþïñDµÔÝÒ–Ó~í4íLÅ…oÅßìx2b ÊS:_…´Ý·¿‚] £Âih£uÄØ¨‘³XKbâf¨üÚ½¼‚• X®O”­…ÿ5ÿ0¡Y8÷PÚ-ö¥¶÷ãtR× -DãäÈ¥1™ÈO¬=1ô'¦9ö‚ã²½m.6Ëš '{`ê¡8à^†ÎD(|s÷éz¡¹¯Gœ1nßNqø‰f*O‘[Ö\Lbî,‡–Íáó±up¹÷ž!º«hÆ8j"cÔóΨڢë¸Sô²—59Ø™ -*Ÿgj.[‹šœ²¶'iº`Ǿ‚+¤ª$›ì¨éƒ?Îy¤*ÓÌmx¾'˜|g'%ï\Äu,áºn–¿öÓfñQ‚[P0¶ãW~Ø0N(GC¦û|n•/—~ë:Æô¦c*»†eu¬:Õ@md•‡%óÍŒ“‡¾‹á7¥:å…Ù¹”£µº¹_ºÒˆJ)_"³ -3b\å}šzÓ JÜ\P?­ ±r jx¦ª¿Ñ’=‚N&ýòOj¥ú“÷qxKž9 iPŠ5­Ô¨×#é)y²k˜åñÀ…Ôi¾ ëk'ƒØ™{Ξ`Î숉 {é5züñ-à@¶–bo˜zP«uxÿâ/ëSôê„¢ k¸ÎCSx¤`ŠÇ]ÒdÛÎ’E[”kÏîéÉç[DÁ†8ºÒ’èû¸ŠÇ) á:{W†nî¿°¯ƒ†1eŒ“UÅw°l½ê{\A‡ZcÝZÝø™G!‹–¬Àü¤_›Ö†äW¡Ï*¯ÕŒã›hF &6l‘Gà}8¶ˆÝ×}@Ž<Ç_øÅ%“ï¸:Z›“Œp·¬Ñ¯Ó)rÙÂÕxÊ=BF@èFŠ’|ð!íQT…â›Ë.u9õ±Ê~r]Á*=o´Ø.ؤ‚jP -'|ã2žˆ»Y‘{‚vi6 pQó 9$¦û,ß’ƒäܾpŒnÔóß¼ñúføBó¶:'OÙŸxRF¹²úSÐÊ fH—ñÁjx¤Sân-~uGÚä3®»œàŽ‘?ö6õ–WËqMù.‘RÒ£Ú¢ÔÔI™/2U¶JC~ b>ÑëZ/î°’ž„OAf?aÅ H,Oþj¸nšfîÔ^ –QƒŽL èÀ°ãFp6 -áW©²`{£‹)H ÌÊÀ!{eêHÀð™”™V³ü"­)A˜Wô‡ÄgÕÞ}Ï"yþS¯rîªîzZΨnq¦]¢5z>×˹1Eî¸"öˆ=ªæÝ”>ùÀ†·»“÷ á+Öë1ÎjŠÏñLC~Û>ª‚-)0Ö?~AµœŸ"M)@o¢NœCh›çý>^ 6H•ªW¤mE¾ÊÊ(ËôG•LdbHk‰ï»z¶µŒ‰&2Ay”;!LöHs§é GŸ@ËyåG·~Sïýè‘$›„5•¨ÃG¸¦y'¼k/j–Ð@pÓ·Ø ðÆ*Іì ùú…«Éó=à1þì×nLº?ÜåÒ‚©N‹:üâ -JŽË‹&:ß’nd0‡}2·#^ÚÈíÞAW£Nb_̽Ø¥e»pw'Ö -Þ¨H,Ò”ž<1ˆ2,ÀÚ1BÞãÍМ†‡S\œ‰>ý~Ô±BºÐñNºÊÕ[Îõ½àBh’SÒoëÚcŽôT“ÉÕS?^X1µ^Y1ªfg/'¦gL¹L‚¢TïhŒ£‰HöIùT²=Ï ¼²ÏÊR‡Ø.²-é|ç™LÐs¢íˤ^¯Ë¬d»"EÏ¢Â4¹Ñ®2iÁæþ}oMÄáxéh-¢©Á·˜ -- |™Z¢Æënw(QîkÔ¨å ¯øh§HˆnïBºM}D«õÌVK`­ËÝ ±}]Ê}ë¼Â¤té\40PfÓ­³8<²ÀE ŒºßÏÉV>ÔKsê—ã¹x‡¨Æ^ì‚j6‘e;–Ì3–Šû´^_GÒ5÷£íD;õ?eú5²ãmÑKklÒ§Hƒgn]èB—ïü׊‘ã6ôß.hun?Æö_õ´Yå]»æ°0¬|Îr”±X¬g,©õq€ð¿/(ñ²¸ŠÁ÷ ËÏ~TxËò‚¶¢õ'V±¨½—(°§_û6çȼ® ÕV /ùïñ©0R¦8«K#K¥¹©ÑN»b¼ H'ÎÙE³ÖúŽ=¨)Ø´=ð7Ã!eÈr%­mái¤]“ðj&#‘LñCwµ"íˆø?w-¢…8/ ,d?œ3Ü9TpfR„ †\½Ò©GEÊÄàšz”õqMÌ_ö«6‰*›¬‹øŸ7sÇ$ÁG¡_îamï~¬)ÎÞÓÀÚ0¶»?­Z«Lf1v«|̉TÇ®27T 0$È‘–-ç3¦’„y!=lpn2^÷'z½;í§§LTÞÔî,¦ý˜ê4ºöŸŠ\Ç_†+˜æñÖDˆ§ã58ÿàZT²<g—hòâ«”ÄMHAw!—pµÃã¾Æ3ã“ê©´.‹|ÜllRTÁx’”¢,\S:¼ãÇe¨˜¯â^sù¡1mñ'ˆÊIÄg퉯‰çåD’ç~µ¶„R¶N~òIsjýB®cî[¸êyr‹¥g@øðhÝéGÔz.Ó]8ß½¨DN¨÷9ÔPÙ;ÐLtl=«ä‡Ûä…^íH”K)cÞ˜ôª)骙Sg qWY¹›òÁ—n«ëlte¯Ë•K~Ǿֶ«uVÔél“µûÄ„:MW`à [‚_J/9„Ô Q$ùþ,ÍÈò0„²xã^È6>r“¨Eèôèë•·!9Ñ b=’ïÇ)À^H¢Æ®R­úרµ‡ м.²:_C·ÒŸÜ¬!véÊ×M'–Ája–k>ä¶ -³úöèÓÒúáBå«òWw¯€3Z‘a–ΓÅ%#8ae\’M+!¯<Àê *÷A§ŒÐã]ËF„Híþ§޲[æ+ìpå#æ"”–Ý4#Yã͆²5~ô‚lÍ%K åo©†¯c=Ð/W9E׋f¤1`Yb¯ŽÑ¬ßìwré¬òîÙqxœuáHàÁm!°q8hE'ÖÔ£çÊÝï‰#·5z¨8©«ëD­ðžÕô{s’?ùú y‘s„aq¸Ùë6¬ˆá²Îïôò¸Õ3ëÛÊ¥=áØÕOx#U®Ù÷…ÅÉÊP|×ð1;Ò…\j1+‰zùkakÛŒ“|£Ã öËa?ªåå]íÉ ?çúåûÐlO3Ž6bذSøÐ0GGÄõB €bbƒèMˆáîÚì_âíÍ&u§,y´·n!\»ßßDg2¼ËªAሩ˜Ço1v(ÞÑŒZÍòË83šÕÍxAð3å<=]Í C}ÄõªPèÕ°…é<û,üH›Ïè¹S3‰ç¿ëßûù¶ZP+~®ÄQĩɺ3¿ ’2ÈxmÚ4‘­ùÝ">¥‘xÄÕð¥b¼0ûºþºo¯Ïè¿»ÜüS²\εoñ a瀸®+@G­ñ½8lçøFãqsëgCÝ`ª² §ò–§&˜WÆòôÛp6Û -cô|æ'`ÎÄS%Q 2ÃÜ &aÔð†Ó²YŒ½ ò…ûów‘Ž?£x…–Öê"WÛüy36h?¬‡jø^²iJkӮ߇կLgøÿ_;sþÏ„\ä^ž#g([Ž–Gæ1¹š£µ­ÜWåŠÍÇžÄcŽI³…ñœ³ÜÏ‘æX„ñœ†ž³ /rMåýï·÷yß?à»sÿâY#é» NØ3íY¶À:U ®[‰‚‘¶BàkÝz™=iïÒA• áÓ>8â„ÒXò¨Dƒv–ŸxÃSê^c6GÑÃeï©z¬.£Yÿ¸O£Ø0^¬7“Seã¬ô ˆˆMî«>Ý…¸4g䯓Z}:ͬÈòjùÚqynýKs*)oŠ .¬Èøœ–ò%Õú°: L/D~ -»»yÇ&Ķ1òþ‡ókÄCÆ)aº„íájÏ1¼AøZ -U¢´’™…ç"óWÇ ¿NãÐhŸgÈ –6¢À¡yX¬{fÜL:’Õ ³kÔ6n›'±u •Ÿ$E—Ò9ls+ª; ’†hNÍ2Ápƒoc&úFåÖ̭̈́‘P! -aÏOB&Ã~€Y°R0ˆ3¦ë+*Z–ä:_7‘ßÛ¿ 8ò~Bî¶Þúfë¾Ã2ˆ 1ý´óèhc4|yC¤1à”eP¥(¡†ûuF#õ`?wÜ<Œ•Ag ÏÙÔf -“ü½óMìcFæ/.ˆ›'A!¯™•Û[Q M£ð+hú#¾,¹¡.a£à#_°FÜÝ™rÍ”®Q‡læ tD³ÁoF•}àº}l£Iâ¼Ò›Ëñ UÝU>DM¦ž=:^颗fTAÅ–ú2iÁWÜ\£˜!@³ç°2‚ˆ™1ÈÝF‡ßjB™÷Ám(Dàkªl¶çõ‡OŽï ½Æì±ËTgÏTOmÌÆ~DÞ½ ÇWÿM>Xuw·Ûuò¾–çrï½JbYëçœd¨è8lxK#Z §Mé)>¦`eô_| N+Zõíêñâ^ÆÖŦÐåþW§® ÉD¥ÝžkÇ^'Z\‹…­)ýþ‰Ú% …­I–ëlÆ!ú¡ª#K27¶¹žÑphÚùqq&¥â*xõ³ÛòÏ£|yìÏŽ‚œx ÉPÔ4ç7lUðì,W`üm_p÷-¢1u¦Ó´5µY§J;¾÷QˆDŸ Á”H¦[uúÕŠ¡”I‚R–ÏVVÉ?¾§9Mö§­®sîa@0ö]Lo•£ör$ü? "ÁPŽZ©7t>ªn¬Ú½CPŠM( 4 Xi«—3ayýåäµ¥iu@Áåc -Õ¬²ãÎ]­¨€¢¦ b<Åwù.©D<ãçáĈ:Ïe]¿8%âÜY›>¸ØÚ¹8Èùß—’¿ï#6{†ç"L’îX¤¯ßî¹"V»³ãGZe &¿3óu_9û_fû^nlê -R ‹Ï¡ev,;è+c$?  âÍ{µázÊ*¯ì>èD5É'_›oa9Iyî¨áÆFÜæk$Uj‚×À$ì‰áÉRJDµ=%¤¥Z¥³Í’fLãŽaíORŠ>’|„AÝŸ…®Å©Tï Ⱥ៱ JòÊx €dUº|O¶ÖO±Ñ;~·”´ô¾Þ–]ÂÁQs\Íâ¤^Gš‡Rh÷8ú/‰ýü'¿ŸH|x¨Od°Ø?µo÷¡endstream +FzÆ+-œÄ,ÜMŒ,œÌ¦Ö{ô/½Š­±‰£µ…­É_.ÿÕF#ãØ”Í-Œ¬lÿi:Û¿M&¶Æÿ™ù_zþ•7ƒ¼ˆ¤¦”(ÍnÓy)üeÝYÙÃþobÿ£Y;ãÿ%üƒ!,lçð¢ceÐ1spØ9™œL>ÿ‡hÿ‚aú/YÖÀÙÑ õ·dF¦þ?¾ÿ’tþ懭‘ñ?S¢äl`küw°þ—ⳑ‹£ã_>ÿu×ÿü?帉‰»‰ÌÚ²O°eú¯ ç:ÌÜ‘IQ­>&БûÒFå¢ÿ»^¿ôð]®JýÏÚú¦iîïv¥sû¯C)꣱> kŠÞT“ë|<ªþä-òNš£@ÝRøŒ µh¯›E™0MvFÕ£½IÅŸº%ŸøÓ,ŽP7/Tþ$®þh¤Ïö¾Fi qè]HM@(u…çäI§/ÏC¿GG†{ïÀûqirâ Éx\ÁàÉ£ürp4U*½"¨—Ž3Ç'­1/ÍzG$91Ø7™Ây¶*GÜ|®1ïOåñ•`GíGˆ\.­=û“æúüq†;÷šLÉ»‰î«;¿ÐÄ“n\¤ÎõðÖYNùÜóÒ1àL—ëFb$]#b²ûób€aOžcxwK÷ ‘„%&B™‚ºo"ä¾²’UÏìU(­Ñdù?ç ‘îj\I‘näQÒ÷í9~5\ýYsÈ 4Õ;¯>ꪅª®c`r *§Ž¾í1I>T +Ð÷ª-KCºæì¢]•ß@e›‡á±Í R©e7ãÝ8æ¥X¼Ý ú^¯bª¿fiWã¦Ç6hé("ôæ?ü…$ØVS̓÷â¹-Àõæ}DJš2½œœ$~T’D™ˆ‡…:Nq®ó#5ßì" 󧈼ˆÎQჶL–­Èµðc“ÊçØ‰/WöýîŸX2ŸÈÈðxª©-“[¿F7žsWÆ{4B +pÇ€úâLV›‰¨ÛE°¼õ`K«Vá½Öž\ºÍªk:K?>1ÁÆy9ãd™5 @P2ƒ÷Ͱ]öþ6Í(9Ð`®¦ ~ Ì¢ß +¹9y´Æ¢]’ˆåþJ¿*ú¨ gÒöK“]?e’CÌ(m +D\ïN¤Ô´|˜Ǧ¡‹Uf¥—øŒÉïÀúÒáè +ûÙ £)¨Ž&‹"º–Qª86Æ…‡â9xV6jƒxlˆÊù†º’2–^ù +|Ò Ä;c g¯lt_´û•jP°– ¼ãT³mê=-ŽÙ + ËÖ /¨é?&§ Ã­¤oø +%Ñ]µÃ³V‹Éµ‡†#hižrX£2¾K±²Å?²©Ç‹t3V<«×üHl'}µ“œ7ÂnhJê¶ŒbuKÉ)O^Œ Z5‰OßöÚÖ?ý<ÿs88z™l­; %ÔVæ ËŒõ”ððßEôÌH«íjÚ ~öÖ´Öb}ë­MùñÍê+GÝq’Yµ£[N¢+C1¸Ë¯öýµgî;ƒBµÖcæ4vP“"d×sžåxñ^ÚÁ9O^jŒŸ»e: £$‰µåf~)Z–Tz=a“2¨ÕæSÐÞ»V›áçp"êcýK¹Wåã»/Íx=‹ +RÚ8Ýw>SÓ¯S®A˜Ç©ó-×;%¾À˜úeiH—faP$÷Då€ãCã&¢A†C ѾB&eQ/MN¯µÊQg¿NÊèÑ8o©­?²ËˆR(iæŽO¿Œz‹~€èßöذŸŸÊ€ù#!Î4uðÏU¤ KqŸV!rÉœt„Èä´n"/«åâPH<8±Ìà%!*áÂÇbhO‰†o‹›Cd¨· †Q>ÎN{©’ÑòíÀkÕÍ=ý.8}"Æî™Ux§ñ~Ê©jG¤SY¹Ÿc[kÑ‘pœr)h‹xŽ7ó—Š›Æ]BöTx¿0¬ÝcàÏ}0p²¢A17y,óUø‚‚¢·…ø¿K,ZS¥VÇìóK—Àd=ˆúÓ‡j €Ÿ;¢’Ÿ×¡ôã+J‘RPl3ï˜ùÆïy4¬Ôx_½´oõƒŠHÅÔ·vS_ü AåÒg˜Î_Ý„õ’~w?@’4ýQîï(á"[Eq¬ã si5׳¬ÄÈ—D|ÌŸ|çå¸K¬m@e½)ÿø’– +ß$TAÂrü—ÇDUËx,¬mCFË„vh”V¬èæÝod%·Ýͼc‹ò¡R´©kð97Aa¸ö<ër Ñ¿5{ßîRÖÀª—Öì6 °¿ÒÅŽð.Îe“ž¿|€³ÉŒÎ¤Àa;ó›c ø1憀^Ñå݈2ð#"ÎúÎøYkK?¤ãž4rIt\IIÛaë°†;ÒD™øÃW=ü÷œ÷YÅ+˜©rM‘!ˆÑ'ëâ§λ‡Þl è‡ÕŽ¿MZaÆ©wO/ˆ¤ÿä‘¿<y±Ç-û"å{a«Øçé¹WÑs<¨ðÀ%ìÝH(*ævØÃíý¢_õ¦fŽÏZ5X¥¥6­›Þj<ßó±/¹ç*£ÅJÏ“o“¾™ˆÒ¼¬¡µ6"£Í·@¼çÂKtÛF3c‰¬#«;¾HõOR¹éGA½qW/}gTHLЇÖ-'¾ŸÔkí2„}ÆÅ6ðû {î56Ë!l<À-€èÇUq;=t}ÃY)¬8Ýø3yìáœ9oÙìF€s#MSþ‘»Ží®@§$Ùýû(§îºÑ¶±ý¯ë È>loD‚K{à[ì1_s©–¤ ÑLâ”Z|µÙÿ‡L§/:OMz}ÈÔïKHï~-ð_Åt¦¶Ÿ ë­‹­åÁüW“Ý$ýAƘ¹ß3¯œl×âr,ëâ€y¥&0•²jmÚqý[„ìÑL6Qb~´+¹PÄ-sÙø¿µ$ÈÑ*ªï ¥ ðÈOÓ…¦JûèY[éýSækŒ¹©[üm}ÿ˜Ð6L÷èO³[²ò½¼ƒëÆÐNOp:„ùHïä7CĬ“ü]½yî´¶ïïÃ>Õ“·aý'×M½®qê äîbà_w– ž]4ðÚÀˆ²öÒøÞó¬n +: § Ìô 8û›cÑJR[2£mXÅw‹}y7ˆ×ÅLeD$ç,?Yh{³ÛÆBÅΙki¿ŽøÐš¿ Ø1ò°ºŸ;eó‚T›n|˜)94µ9uæÐ¥x´ ƒã½R +>ç³]æoM%„£¬ÎG)³‘4°ký‡ïbZ~ø ¼`_[hã»8ë<¾4²}$.îÁ³ÖÄ‚(¥ªæu†&ÿaÜÀ™y£Û2¤³‹Ô»¹T+ªJÀҙçÍÁØØJJ,šëò¾v\TP‚Êü´iÚõ pÃsùâäFáã!ÌnT)^”"²À±R'ºƒÀ q)J‡4`¿s]¼ÉZGâï”œÒ Òœƒ(BÖqˆú(““v&ø­3UÏ‚Bþñè› ™Œb‹Zˆüù Ir2Ÿվ ¾îÄ›7ïX)c¼5&•‚OϺ÷•—2nµÏÄGýÓ¯?74¥Ü׳ ޲ŭTj(–Eãs‹ &‰Rð³ÐѵL‘ˆÁ3²pæuy6©Ì7k‰¨‘}¤TêÄoÊ"´wÂñls ò­Eâë2¦'jQ®,ßéàHˆ]í„äÛct? ÁÕÑÊ,Ga³ýý¥­Ý2^¤d0•NUx¤$"e`à%~7*ýþ¬ØæŒ­©Ÿˆ{cÃl³?hZFCH7U£*´Ü‹Ç‚Ìy|±°8ô.šÎXAÐufóË ".Ä-_Z “MÄâë뙤—¡¹Â‡Ý÷í[áÉ\DZQR÷¡ x“à¼K)Ý)‚pÊåDÃ’«¼m“­HÁ• <¨üˆ´Ÿ_Ä1ÉðkH/·)(_|ýû2ª,B³i‡Ðñ4V®ÌCøY¹5õB2Ey»…yö47£h¬Bù\=m‡r94ÚOäjùãwiºð_w ÎvMíð¬òüò[°4ê©—Tÿ³š™\Ó¯r»N1†c-8!âΤұtzžK,בZÅ5…ÍCÅg€„ »öˆÍÐJÎÑ=–|üËÊ,u‘,Yƒغù‹ÑîÇôBÞ¬ƒé\¦SM„ L¿ÐÛºp`i5U])ÖìUæt™PÚŸhlA¨6`¦ãqµ"~g2è2êþ6d`{#Cn³W!Ïw¦I¼Lwdk J)ýK‡"™¬ô&¶ºV0ÀfÓ¡?þr83)J‚$È4?$ àE•´Åì²›¯:Ÿ +Œ(iýŽà-º 7~õSLcüýkÅ!.0Yü:7— `hPêoˆÜä¦ójÂlƒG¥v‚j»8Ç«Á¨›ÕäÅÆ6nÂN'éú3ÑX®ÐH¨Ïü%›zl½ ýƒ©´T~Ú}ÂwlzŒ(D:ooV¯Ãúe@Xrݪ#ç‡ d4C:«G‚nxŠôÒ¤Xç©þƒê¢dÑ^øÎg’´k½›Ú}Áîí{åÅÄõW·F°;ª¬ë§Â×òh`7d H—”µNº’7G«5–-™¥Ïà 1‹†d ®\É(¸¬®&Á€%þg› R¤q[â’ÖÀ.Ê¡\ÔýÔG&ùƒÔä1Gô!ríØŽHÀÊÏôØD¾!eeÈ2¯ª ­òûôÅ![é@8Í1J©áRJËÁE·¤]wú³{D1Â_¤ Ó¿’²\ýz¯ö §D‚ßìñ¯Ìd$!ÉÝ–#/û$ÅVrþlAŒÕ„ž­·:@¬RÏhV‡ƒTW÷ði¼&ßVQžb‘¦°$Í?^ªøŠJj ¹vQÕ±:³´FRƒK«}ÏGL©ôÐ÷±ûûAÜ8€)dä±”Z®N¨æîuQÕw_ ºLã®páý±•¯ŽÄ—¢9Qök¼`EËih[úª•³Á5?M”õÝãõû ØÃ)’'¸Q·*ó4yΊìðüC[I&«Ýrx”/Ø`x0…oÝûsËÙsïsìêƒø—弫Œ诗´% \˜Ò„-qBÏÐá¹ †^ n u^CE ’¡ù‰ÝĶAµXþ¤@á¼ömÿÒ’JÀf)Ë‹MÞÈRÁëVSi•#w6VBÐù£®QŒßk¨£1#ð9‚ïq?ô¥VAØAÿו° ¶ì.Ü5.óQøw¿­'zÁ7°…#|ÝX#c½r"ëòUt™îÖÔRìáϳ—åd—ã0Â{)ÒuŒÉô˜t’’•û6°Aêõvƒz»§ö»`~LÑ%óÌ·«š™,"QW½^CDDûa.˜ª¨ƒµ ÜöBŒvUÛaÀvæƒ~ç÷%ƒ#™D@¬Êž±H •e—„7tà›¹¬6–O_pãÊÑŸÀ)ÏÐ÷#lžtñôË.jLt•¤ÍÊv)nè>¡á˜T‚nü%´öª•K]^sõ'lÙ²k2]¿÷þ5#Ä®j@o^'Å|³ÂÎp?èÅyIß»7ç ¶ÞJ\pA·F¾#Û÷jYó\a@D‚Y>›‘Sa? +)‡¿ ÕÖÏéÛNÄD]*¾ÔŸæ›õ· ­‡.kÙõ£a ü:ræ\e·ûá&ÈÉDŽ¿Œ™%_$$3}9šü• Š8$½¬€È¢þàÎg×™„¿ZuÎÚ8רË=~³a#›L]gŽyiðÎ+.ÐÇå‹6{™jšSksÀ›ø¥qéD¾ ~Èͯõ{Ó·Æm'¤v;?«A%qÐ7ú"úpM°!(ïx[„Ô]Ä,…u‹0~‘—Ý›°ùot…ÿ‘vm¸oŸÓÔ/˜àyÝSÝñ}Ó"‡ÍÿImñ@üñ¥Çýawú™¿9Zôèý öI„÷,`¯ImJ /¿!UÕ†[ƒÒni$%µÖwjÂíÏ÷•y†’Úª? ü¸Ôî¿¥8«?—ÇÍá4êµq5‡g7¶}E¹l“lRŒg{ ©Ò2±°Ÿ. nÇL^ªJéˆYç¹¾‡(Š©?fÔ2ciÛŒ<¦É¥¼""—@ƒ Èí•Ú!kŽ 5+V=ÑÅQA+žß͸ÒË;vƒô% ÎFº+s*)¼Xs9NÛß™üÑ¥˜L¦ºÿ[YÛyt¼ÿ²ô„ xÚ:tés®` [Öx³(³û¥šrvrÓ vÝW+—ºù.myÙï=Ÿ†Ì†Q54ÕxÑîÊa•Ÿ‚T`ò—`È „^3¥>5¥UºaÝH‚c™'x‚.löÓ°g™~»uFˆÄÈ8ˆò€ b ÿ.¸%Û »ðPâ*¡L;.w_÷<Ê/¸‚óŸ‡o£ ov£~8ù8‘ïV¶qãf +åÚ`qÈoa’:Üà}ÒË’àóI¡ Å¡H±`í ¾‹¢R¯u²Í3}›’«˜Œ(-ž ŒßDÇîwëôêé‚t­»Ìt«Ã¯W¹4#UâRwXPƯY“4ìg·FRß vßû<ÔxP>†uÂËe&+W-\O+NcÓÈ«¦ˆdÉÊç°Ÿuµ‚^¸Îö%oH¦£¾]ü¨G,ïjçís”'Ù#~3’âø‘JÝ’J¯E«N²A»‘_l ØÙ1U¶c3  ˆ¾G»m+–¦VÙû©|¬-íÛ`»õ¿lf³$Ú«ôŒóÌžÕÅ›±Ëšûvy7ÅtU¯Z¥lÂÙñÏ,¿ Nªä@Ëäþ‡¼%NRs¦P†[¼‰P?ß”ÛI¤eo Õ wö¹¥@´!è&/Ä8Ù×öÐŒëÝñ‡þî…l<œ%š.Ò™{A•£@lŸA µÆ? wR,»SQ,H›ÀuQÚå¯>¡UAﻵÔ/£²­™Ï&/Ö…JVíù9@(üˆõ›œÏt\ F;éœt­Ha|þ­ZÇ)Ýb®4¶H„¸îbtÜ©. +Dì2Çüߢ¿¢‚IÔnèEYÒÒÇe)ü²:V ùUš>иɚúq:…mɲ¶þUñNžY±B§Ýêƒ&³Ã¼]Rý*ÃŽûý=*n…ѽKv„hf0ó;!ØÅ .&f«RÚ„ Ï‹ë&e¤ãe}|“x$Ó½ââ;£kgž=çyÅg©Þ+a…¶’û.Î)†Ú`NËiߜʼnW«Uäç*i¼/W 6æø>±§“ t6ó –p2/ÉõÚzî„øÑ=h>±` +n5TÁšëÑ”’ÐX"GEÉ.4–ú&µ¼ ØØ…'Àú|€PÜLêar ¾0N1fo÷í¼Á¶Uå" ‹*0âù$]s¨>ÓΆ”'â¾ÞÑØèÝf6qì©)¡}mZ€šÍûIÄN§ +Îþ@PD # V{¿Ö%þVõ|3ùÈ”JE3)&Níð{_’ Ê m3™Î1 oåñ S“•/bì~O«¸8/*™Œ²éëíZφä(.Pÿ§žÏdÔö¤¾X<é§îrî9YJÛ)Eæаz6Ø/v0 ¡ ªD °¾T㹋˜€7ýP“Ú¡ûµ¿^¶û°iDØF…ṳ̈9Ô\ðØDˆ“Ï%Ë;¥Ø—qëŒà2ß œNý.¶8bWÉI0Uy®ƒÎÈfPw³‘ Õ8ŒÌ" Çsäs +ZmØFÐÃʶÞïPhzI÷™ð€*qaBrÒ·Ø^ðƒMâÝàí-Õ¨ô¡À˜å®™ÂÞžÑÉö>u¼ ‰ŠÏãonŒ{óæâ<ŠéU¿˜f);›Íp±OË,¾†ª™ŸÔL~‡(ÂJšWQû¨ +`þ* ÎŒÔÀh0±ì$(]J+?!uR[LGÓOÁ +>DGÓyØ}—(l ø &‰åSß}fÄ †ù©»7«ôÖÞ •ŸÑ;!)îüP_©cEìì_Ï“Á’TYj¥àê§ïS({ çÑd +± éÇ¥µ¨ÿ‹0Ò±«ö¡`¢/³I Ph¦€ZhtDįcÅxBkô¹õ¾z힢Uˆ1áû-C^­î@\’ž¶Ê#f„†µ]òOÍÕ5 Ñôh‚˜CGÚc(hƼ<@žðŒe/ºˆ¾]úyèŸãgT —–B„W‹:ƒÅ‹"p+EŒŒûE|ë7p<*6~¾R—”{N f.]Æ&‡•è…MÀNsr'=d/UMzW¿¨8ûÎ=ªŽ´n¸ÚvDôÓM=×ArY8sœ‹ªf(ú²"’å®êvj×;¥ôŠË7/“æÖö¹]Ë\Ù”7Ùë•azgòá¶gÌ)RàÞ%H}!³¡i°Re<Ñ 7¡%ý¿¹a¢d:£gteµIˆ­¨*’ +‡–oü‘éO' °xd"뙂T¯·3z ^‡ø~LËÿ¡IÖBcP/giй.^ÿâ×úÔ¡/jƒX©ÛQÕ ­€ÒÆ-Ô¦4Ê{Ù·hïgZ¼'ªF§ó.²$2ÈÙB Æúž07êÅÌJFØ “|Àmv®å·Ìù´"Ëæn0jª8xB¯QÎïïˆþ”âÞþÐßÙ«À|˜­jiu›¡lQæ5ý%ßzÅŒãÎv¥ú…>GïÀ•Nv.óY‹=Šð ðô"¦k ¿E)û›™,$i{;vÓSë œ†œSW¿BPPúËj…+ýá{ÛÏáûg¬ššLœ/ +¹,6:üâƒ^ÔX'€å9U¿œ‹fkM6¼¿tî˜è^‚(Ò2g¡I›yÕ²˜RôÓ(.ãcÃÿBM¶SaÓv¨‚/uø¹!&jìdR¥ *ÿ!´BSJ‡ã !DË¢FT=B–žýÏm+›ä’…0Ñ¢­½ãmëIÆ}ÈATZS¾Ø ûú=óÀrèƒ!÷v§} ‚ü |8âìñ,¼ + ’¦ž~o8LÃć4»DÜ϶ÒlÊô‰'´:Y'ϵ:X–¹ȃKKÖr97…ü dé2 +{¡„Fuœ·3žÍÇoÕ‹Ü2C7§jy¸-Í@Šæ,dL//¢„Kàô̰FYîÊ„³Ýþ9Å™êVþ©\ªGôZמL6ú3‹:—g›:‹¡RB£–†‘ž/Îç»v­KH©—Ôï[¾­mÁò¥®S%{ D4ÌuBÞ…ø,&ñ~‰‚F?Âì–\WöÉ¡r€ägµUê—ÚqqÜ6Mgy0#Ï•`¯Ô&Â~Œ[¢é°ŒnÒ#u"%`£–ŠžÏr­çgäeùÝy£ç#HZ@#‰F•Xý”ÚèíTÃl’Ä’2”XÇQ[ľN1’ÔD͸©ØÎbÜÙ{òdEÿÍžó¦˜ßTŸß¯£Y4v̪ߔcƒ>´ã¦´ŸÆ½;åø³U>.Y'²–¹.NŸöLM-©Í•åÂ߈¾x6·w\uÂTõ *ÁtÛ©X„ø6‡{AFi íDñËèŒ}âýì¬pK?N2%-MK2{%¾,æ)ÝPÍh5WtK¼˜/ä%‹(ü¦„¶â VÝ?Èþ¾uôÎEšwž]“¨Jb $Ùd+¦_wZ+MVÇ3”Fíh¹ÝG{>ôº0 ¬{ðÀ“ [^Ž O0~öãÊô`1õYû +*–÷oz ×PýÚúŽÇä–G”30¢ ò ¡€?Žê)^¿)’£Êw8:B-sìFDò±û¹Õ.¯ýaËmwñ¶ÀBUôz8sš3&¥JÎ|ñ$¡9ê +¿’ƒ½[žBš´¾™Kåd H*ž±yÈ"ýƒß ýzêXê>ªµÌWÕŽ“Ѥi$&N“yu°BIsŒŒÓoLª¸IòD·»ñŸ’ÆãÇ•ÑlèE)÷—¡OŠÌ:˜¶O-h/_cÂ:u* ý ‚(ÖÛõî9ç}y}F)ß×]>9]¾¬šæù%†­Ž8[pµŠ Úˆììˆ4eAäÙoÀÄÜ# Ò¹äY¼I©[ˆˆu÷Ìp•)ÁæDÚøõ l¡ù})¼ºjoÌa %h1•l­õíP”Eöd¡‹#ò!Œí±Y‡q4NaB¢#@÷3ÁÜ´*ìåFÖ‡ù–[>¼üózëþ2‰ØMÌDn…Þ ÜwKØ¢Y(i£X‹ßüƒd¤ú9ò ¯L,ÿì“^^ñëàö­ÂóY%)µ4ÙZ\ÔötôÕW¯ù­i ¢7,qK“ñâ”-Ç?ÑúE@•àë#¼‰&+ƒÄ0¸Ø¡¸04ºœ5Ö–›ÿë“WåÔ/¶fLƉèß‹›¥0³Å¡u±yذÐu:¯Û{®[’ĸ2Ï}’ cu¶Þ÷²' )¦Z`‡`\… c¬—ÖÙ±{OÑØD°Çré ám;€¸LÐl} JÜ„Ž6 ‘nþ‹‚>°§nºxŽPc=‰6pÊè)L[‡+»†%ª}'¿P°aŽ‘45¨lG½>(ÅûE&-#Èkií·jEüÅ×Ö "ŸûmUó˜SvL „„§=ªA2Ÿ¶_5J¶Ôø¿ÒU‹‡_O·V°mîl= +æ7ÒÁÒq3‚`¦ t.Ó„c‰Nä•×wíÝZKGº¦Ô›.(ðÔà^æÕ—w[.,ÕZåŒ +cGM}!;4šÍCnœ®2'ÖÊïìù®? Œå¯@9ÖË'Ñ®æp]CÖ-C¼Dû]QPÓ-}yhÎëzqã©Ýcô‚®ËÚ+›ß™A;tocšn’Éæ¤-O‹ÛÃWÓ•ºžÛóÛž:]‚é#Â_fbȰg‘øÌÇ õPŠ€Ú†ÑPÅŽO£ªõdU “ï6dÍpŒ‹bçÆ©\¦©Þ÷Œ­;£&{"ÿÚé,–ŒO_»ÔÇÐ9V¼47M=ÍaÍ]:mÎïGAã›P.4”ªþ3€ãd—&•É–è*HfÅ„÷‚¼M:ÞÌk(g +4–·öÈZýjH sóG··»èV üY).üjcPÌ¥’»nÞÝtïw¼RÓTÔBÇA4MÚgw†çsI2½¾C®æÀɳ/™CŸÈ<€µƒòðð½·J'“8.}äjðg$Y[ì3úØ“ü=¸ ŒdÇäRŸ\4˜Y^ ßZóÖãD`LŒ³8äûX‡¸xã-·òú:Õ]PUˆo3‚¡©q¢ÎÈí¯¸âçü%­F~Ÿd¡Ü17br'ÓP¯Ú.~ÈFôêg´ªš’í2\x%ÃE…§é[#ùÍ[8‘çðÞÞª'Õª{±ôV2ZâvWùS×ve?sL¾d5׬¨sôßaJý.–óÌê0Í›øñ(#­FÎv}MD"]˜2?µfÕ_kÜ͇±MÞí'–‘nÇ[ gÞi×ê¨SÖ—¬€ðp:ªÌð/šEù3/ùkÑÍ Û1Æ•U +ŠéÑ:kÅÖ ›r}’õéŽVbbérªïHÎ7Õã³ßêí¥‹_©¼“×2[ëAõ°çô­JCRz!»‘<ùq3mÔ¢W[M0hÒ VÊíaL¦3zb¥ÿÐCNãú?O“lVŠšßÍÒ4Øë>Rj•·•ÛéD[÷87ž9(ÎÔ ëR„Ç?Jáf±;V¬32Ýy‚¢ÈÚ«òßü2ž°é: ;QU–8Ííx„µt¾n +vÚÑKâåÅíÍÓ¿½Í~¬?×§S§ÎªôÉžµè6.¤K±“H?R‡yþnv8Âax9™:¯¼&ýµêo<çßb%ðórÿDí;Ú%§1M–UΗUÈÁXÒ6G«NJ"€Ùíì£â%Àì”w¶ðtý—_7×¾`!—ø§‰×o>v²|îÁÈç™±ÈBu:ºXXv9’nn*Ç÷ÝŽ#*%)½—-“u¸3ôž¶ú¯?N ` +;ÜÆŠF¸*Cb&Znf]C¡ÈN‹×6Á.þÂÑ, èW91£ðà«iK;m+úbTèSpïGsÊuÊkÏ&ALH^Ö™FV{ð$ ÝkúÝMbxáñå6ÿa˜ƒØÅYå›a¹5°þ¦J0Ëšëö“©¾é™ý¡ +Ó†©"S—Ïz_¥¬Sþ@Î lÀ£ì†D/®¨÷þ¹B­c0ˆb( º +ƒËsˆŸ.ÍÏxP£þþ\ næèJµõN*·ƒ7A—^…¯f£èïnò˜Øc#ï|<ÐŒ¹a=íÂèœL¹Çt}N9@œí2ò“º¬ð;ŒÔ’`Ÿš瘓gÛ–» “(kw“Hˆ«fz# ü«TU5aQW.;ì§øtÁTK!bñ6Û¨Ú±A2®Èü„è-£þ|âáŒMÍU5j2~áúˆ^]i‘åe-·¨^žÿWeoÙ~äèžÞÊ„×Cô®ïw= ý² {ì}Åï÷šNå)àÒ„½\Š*‹Jò|±WŽMí¡±Òøòo- kÈ“èZ±Õ6"Ù™þ\W7ϧGÂ}VÁc§Úª4ØXoM7ùwÂá›P«cþÕ’Ûl{lY B‰©Ù/šÌÝÖíü¾ì–­˜T¡ÁÜ?ï°êšš+‰¾Å’Ñs­êŠGô†äv5¶ÈÍÌ?ÈÖ§éBÄ<wsÕÆØµŸ×ŒD¦¤9 ߥKòã_Ý»›’«á`Ž]} ‰µñnÃáhDÜÀÂ\É&*NNk…¤û0œ†»™¥ ›ýÔº˜Å9}­Q}lêœDª0ŸœÛj2wü“¯µJ÷‹¡œéÃvµvz¬,Æ}úè"öìijƒŠyñý›·î ’±¼cæOˆq¸Ìpãd:3ö¬Õ¹$c¿_W#ò4ºÑ1¬ç¥†Á z,8ÚÈÕD-æ h•’ö5Cº ͧáƒ_%wÒªu¿ â#¤Ç”g!]7¾ô/BŒ]eh©IKôŠ2¦WTŸuÊÊŒk84æÍ¥0Ç‚AÞÈ;b•1b°mÍH;í>nôÏ¢ÖR /#NìqHºà0gÚ…>tí°§Vûa¶ ˜/æöŸñü |¥sçYà¨q³Ý,ÙŽÆ™(®” ¿œ^õÏ‚~¢­Ö>ʧÐÃwHv«;ø´þâÎMÌÿ$ìe ™´´_ÚژтX–KµÆZåÀËÎ)\uñ–Ã2îvKËý XåEÛÒ7ÉG’”¡":1£ëV G½°â”ÀÑ&–Ê(è1ó›Û9‡?³3˜FÛRâåGcM-,‘kÖ!í¯±òÎuÈþ7æ;r…½VÌ+r“l«á¢ü” ³˜¿4{k{#í"øKMaëb³y÷ý©ÐØ l/W^ïo<9[<˜W(§H‚I§,âkíŒ{·)G<«ªfÉÝqIbÙÈKá«J-p_¶×&,xÖú~Ã!C‘FŠ‘Aã”Vh0–à¼ùMeœ·È¾„B‰?MÓQNqXA÷žŒ#´wøÏ4æm¼ðS"u^5^á1vÛv"®3P£ÂîƒÃ Âù^Ú&5ÄùïzFƒ@PD‹oŽ+'.ë²Üãa9…@4uÝlXÃÇ1ߟ¡X3Žª‡µ?c(µNn¢--0žà1ò†´Ñžácó—W¬¼ˆÉâL¦â™w ·9 +Ú…W¨•fI•M@ï±–KÉ­7‹û)Cc¢ïS`…,8'Îl[stÂ<¡\nc«¡T&8Ñew‹¹ƒã'}'ÅrW÷ ŸMì7#X1nfœ÷ ~¸ŒÓ2Û*¡U§ %›ˆÁÇ:èDMÂ|Ò.Ž«ªˆàc:š®)IËü*ŠÎ¿žê³Â:rê2:Ò©iWLÁÎ=¢wßÎÙàì­J5 d'XZ;UïÑ[ˆÉô+j£"dgO5!nYÙÚõmÒ/‡`ÈÛZ¦  Ã9LcZp)©Ê›ÓQ$7ÐâänX튌X,ðO“˜£Òâ'ؾe6\0˜`À2ÊâL— ÁøÁbÂrQu +ºâreA5n!Ñ…êì]Œ¨ÁºØ»‚õOWìõHƒ:Ô…—‡uÀÏk2Q:ú†Édf¬š¢ µ‡$EÏÐï8f±æ™€âNØÔ@Gœ¹}\=ñõ°¨öˆ¨‹¼_W/nÀÄbÛíÿ¸¯ß0^8U¤>¾û=O?°g›¾U̧[aý;óþÓSX¦ä”gÚLÁ´·¹‹.võ@/Ò&ÿ”i:dÏk0G£u¨ð“rÏBž7gO‚w üúàü•–”À‰KY&j øœ7¼r 2–á°WNÎxëh“õÒ¿Í7§LŽ„×VC@]ÒÖóºÁ*óë-Å ÃA;}üvñïiCU…—.úZl¬ õå?²ŠcHÕ¸´Ôu½ö!» »†ó±œW‚Ñ/ðó\Hvq•bf€úOÕy3¹;¾Ð¤ ² ÜŒ°š'ÿˆêIܯE|Ÿ¹ š­p:ÔC9èc!¦²VûCÕ7òÿ2]„2ø²âª³ç½ã,}Êø%(ê’r‡ɆfQþÏÈéª{ÃÅ3’u7õ(;†>Dî`…°éö'xN°?1jaóXDOÄOTÕYe¸S;&bïæ„Ÿ"=_ƒÕL+Æe)ëõP +gŽ}“ú£qÍòÛ¨ù›ÂN•¥•îÉ/­„¼Ÿ¿¨ÎwýéN­ъ”⃞êöÉ(ú˜i.ŽJÓY{Ê…ë߃ˆêo&ãX +Ë|åT¬N!{¶ L•„«a` K=ETBÔSEÐATMb§œ +Q‡Æ~ËJlQ‹Rü¶×ZB§©{g¯ ^x™‡¾m€ï¨LŽ1p%õïø×ké\¤~}ôO½Ü8Ûu·×çqÏÜV»ì*æGj¸ÙÛ9ýèOâ÷Žû’VuûtñCv.¯ÉÞ¯²”ì U=Ú·rèöI3 Í¢¹ØO7( S~ãÈ”‡ «ÒÛšt”š®`½öÈl/ÅY¦37›„Û¦š ;ŠôÑ à<‹ÆN–T‘Z.!`ßêã…”´I¼M%0,(`Y³¡mm¡ §&ymr¦-åɽ.§æo·œ¢ŒEŸ¼B91Œâƒ!ÈD4B\\ò.½ Ÿ†‡b.ô¾=ƒq™“s,|Ö?¼´~8£»»³­ +Ñÿž¶l ÷ö" •äjÓ`Zo…hbµÌ}åÏ0—ŸùoÎ*˯µŸÞµöñæ/~ úÕ'Kü@Tƒ¯k5{<‹i»ö—ROBz@-+µyÚª«1èûŒÂ·–µZë¿ÊnòEp7âPi«ú€pV¢;g.Oã­pÈTA3V.ÀÙòV…I’]UAÍÊ&¯æwú{¥,¿f +ý’OP\h{†!Ë/:9*ÁþNª‘À„y†Ý¢›¼~¸®<rÍ¥Ø.k¹áR\ÄKÀõ=™Ê³ô¤µéšàš)É  +Ìó¬¤^©êzX-Ta’•éÔUÚjLØ–‡ÁPϲ ‘ Ú €,j%‚‹Bè_|³yŒß]¶to7ɹ¿"Á¡ÒW¾7ÉÔ9NÙbdÌ÷Î2s—O‹D"—MêÓ†l›Ñc,Å=Æ/¿ÎWDk¿þ-ţø¬‰tF%ÿÐjwÕïS;ù^É£ ñšo?ñ +ÆQ'?ßœ†*×3;ùQhþà“R¿«A±FÌb<\gÜÝ@ƒ×oìfg,ÙS¿´íw*0=a{ æŽ!Ù5"OBŃð4ûbü[ïR«r‰2Ó'VìÖĵv\PjÐÝh «»Œd ­ªÌ'3çÜŸ¬ô£uªü”.ø¡×cšÎO +DSmÝ÷dU«TòȨr7)z¡mYÅÀX˜Ä5ê¦[Ø÷ËÅŸ"f ‰@êéqD„ç™Õ'~ñHA[€‹Vû¤“õ^C +ݓ׀-xú€°šNceŸ[å˥ߺŽ1½é˜Ê®aYÝ«ÀF5PYåaÉ|3ãä¡ïbøM@©Nyav.åh­nî×ņ®ô²¡RŠÅ—ȬŒWyŸ¦Þtƒ7×ÔÀOkB¬œC@ƒž©êo´dÏ “I¿ü“Z©þä}\žÅ’gÎBT…bM+5êõHzJžìfy®âq +C¸ÎÞ•¡‡›û/ìë aLãdU±Å,[g¯úWСÖX·V7~æQÈ¢%+ð?éצµ!ùUè³Êk5ãø&Z£Q‚É [äxŽ-b÷uP…#Ïñ¾†E@qIÀ$ä;®ŽVçæ$#ÜíkôëtJ€\¶p5žr„º‘¢€$|H{U¡øæòƒK]N}¬ò†Ÿ€E×D° +FÏ-¶ 6© †Â ߸ŒçânVä^… ]šMg\ÔKÇ·ä 9·/£‡õü7o¼¾¾Ð¼­ÎÉSö'ž”Q®¬þ´òB†‡Òe|°ià”¸[‹_Ý‘†6ùŒë.'¸cä½M½åÕr\S>‚K䃔t§C稶h5uREæ‹LU§­Òƒ˜Oôz VÇ‹;¬¤'áS™ÇOXñË€¿®›¦™;µWEƒeÔ #:0츜BøUª,ØÞèb +Òó…2pÈ^Ù†:0|&e¦Õ,?‚HFkJæU'ý!qÆYµwß³HžÿÔ«œ;…ª»ž–3ª[œé@—hžÏuãrnL‘;®ˆ=bªy7¥E>°áíîä=HøŠõzŒ³šâs|Óß¶ª`KA +Œõ_P-ç'„HS +Л¨'ÁÚæãy¿ˆ Re†êi[‘¯²2Ê2ýQ%™ÒZâû®žm-c¢‰LPe³o“=ÒÜi:èÑ'Ðr^ùÑ­ßÔ{?z$É&aM%*Æð®iÞ ïÚ‹š%4Üôí#6¼± +´!;h¾þGáÁj2Á|O¸D ‡?ûµ“îw¹´`ªÓ¢¿¸‚’cçÅò¢†‰‡Î·¤ÌaŸŒÄÆíˆ—62A»wÆÕ(†“Øs/A'viÙ.Ü]Á‰µ‚7*‹4¥'O ¢ °vŒ÷øF34§¡Æág¢O¿u¬.t¼“®rõ–s}/¸šä”ôÛºö˜#=ÕdrõÔVL­WVŒªÙÄKã‰éS.“ (Õ;ãh"’€}R>•lÏs¯ì³²Ô!¶‹lAËE:ßy&ôœh»Æ2©×Äë2+Ù®HѳÁŸ¨0An´ë‡Lš@°ƒy‡ß[q8^:ZËÄc hjð-¦B _¦–¨ñº€ÛJT§ûš5j9È«>Ú)¢Û»nSÑj=³ÕXër÷Hl_—rß:¯0)]F: ”Ùtë,,pQ£î÷s²•õÒœúåx.Þ!ª±…» šMdÙŽ%󌥢À>­×בtÍýh;ÑN}ÅO™~ìx[ôÒ[ ô)Ò`Ç™[z€Ð¥Ç;ÿµbä¸ ý· ZÛ±ýW=mVùD×®9, «Ÿ³e,ëKj}Ü üï J¼,®bðýÂò3Þ2¼ ­h=Á‰U,jï% +ìé×¾ Ä92¯kƒG`µÕÂKþ{|*Œ”)ÎêÒˆÁÄRéAîCêD´Ó®ïÒ‰svѬµ>cj +6müÍpHr£\Ik[xi×$¼šÉH$S<ÂÐ]­H;"þÏ] …h!ÎK Ùç wœÙƒaƒ!Wo§têQ‘21¸¦e}œDó—ýªM¢Ê&ëÅ"þçÍÜ1IpÅQè—{ØAÛ»kJ‡³÷4°6ŒíîO«Ö*“YŒÝ*³A"Õ±«Ì Õ r¤eKãùŒ©$a^Hœ›Œ×ý‰ÞFïNûé)•7µ»‹i?¦: ¤®ý§"×ñ—á +¦y¼5âéx Î?8€†,ÄÙ%š¼ø*%q$GÐ]È%\íðÀ¸¯±ÆLÆø¤z*­Ë"7›U0ž$¥¨ ×”€ïøq*櫸×\~ghL[ü ¢rñY{âkây9‘ä¹_­-¡„­“ߣ|ÒœZ¿€ë˜û.†zžÜbé>1aNÓßøÂ–à—ÒK!5hI¾?K3²< áŸ,ÞÅÁ¸²Ü$j:=úzåmÈ_N4ƒ˜Fäûq +°’胱«T«þÃ5jíaƒ"¯‹¬Î×Эô'7kˆ]ú†A§òuSà‰epÀƒZ˜%ÆÅ…¹­Â¬¾=úð¤´~¸Pù*€üÕÝ+àŒVd˜¥ódqɈÎEX—dÓJHÁ+°:ƒÊ}Ð)#ôø@ײ!R»ÿ©€£ì–ù +;\ùˆ¹¥e7ÍHÖx³¡l½ [sÉHù[êƒáëXôËUNÑõ¢i X–Ø«c4ë7û\Aº0«<{ Evg]8xp[lZщ5õè¹r÷ûGâÈm*Nêê:Q+|‡gµ}ÁÞ\d„äO¾>hžDä¡GXnöº +b¸¬óÇ;½tÛÓÆŒ£6lÄ”Å>4ÌÑÑ0a=‡ˆ …˜ØÃ zb¸»6û€x{³IÝ)KÞí­[×î÷7ÑÙ€ ï²jP8b*æñÛGŒŠw4£V³ü2ÎŒfu3^üL9OOW3èPq½*z5la:ÏÆ> ?Òæ3zîÔL¢Ãùïú÷~¾­ÔŠŸ+qqj²„îÌoƒ¤ 2^›6Mäck~·H‡Ogi$q5|©/̾®¿îÁÛë3úï.7ÿ”,—síÃ[|EØ9 ®+Á +ÐQk|/Û9¾ÑxÜÜúÙP7˜ªl©¼å© 敱<ý6œÍ¶Â=Ÿù …3ñTI‡@TƒÌ07ƒI`5¼áô‡lcoƒ|áþü]¤ãÏ(^¡¥µºÈÕ6ÿCÞŒ Ú롾—lšÒÚ´ë÷aµ1Óþÿ×Μÿ3¡¹—çÈÊ–#Ɔå‘yLî£æhm+÷U¹bó±'ñ˜#GÒ,Ga<ç,÷s¤„9a§¥|I@µ>¬Ó ‘ŸÂînÞñ ±mŒ¼?Áá¼ÃñqJ˜.áC{¸Ús oÐþƒ–B•(­dfá¹È|ÄÕñÂï„Ó84šÁç2ˆ¥(phëž7ÓŽd5ÈìDÀµ€ÛæIl]Bå'IÑ¥ôFÛ܊ꨤ!šFó…L`0\ÁàÛ˜‰¾Q¹u3!skA$TˆBØó“ɰ`¬ âŒéúŠƒŠ–%¹Î× Aä÷öoŽûŸ»­w‡¾ÙºïÁ° bCL?í<:Ú _Þi 8eT)ŠD¨á~ÑH½ØÏ7ceÐès6µ™Â$ï|ûŘ‘ùË âæIPÈkfåöVÔBÓ(ü +šþˆ/KnèEKØ(xÆÈìƒww¦\3¥kÔ!›ùÑÆlð›Qe8‚nÛh’8¯tãær|BUw•Q“)€gÏ£ŽWºè¥@Pñ„¥¾‡LZð7×(fÐlç9¬Œ bf r·Ñá·šPæ}p +øš*›íßyýá“ãûB/1;Aì2ÕÙ3ÕSs±‘woÃñÕ“VÝÝíßv¼¯å¹ÜÆ{¯’XcÇú9'*:ÞÒˆVÂ)BSzŠ)Xý_ƒÓŠÖpm{§z¼¸—±u±)ôc¹ÿÕ)€+H2Qi·'Âڱ׉×b@akÊE¿¢vÉÃBakR‡å:›ñ†‡Fˆ~¨êÈ’Ìm®g4šv~\œI©¸ +^ýì¶<[7Û-ú%çq´Å5mââËÊž¶t“Bdc;|WÝÚú7–xSyåÈ4ØÇÖv´¦×Åõ Q«´˜„2ã¹Rwr\Œ¨ÇÂCÀVD +­`Ú5øy÷»é@k"¢™5)Ï1·ØRù-DÒH Ö»¼ÍDdM†o3w»5Gv`LÐ2îä¯uÈoêb—r›[ˆv^Ð^P€ó]üQ¨‹ÔS^?¨Ïóè_û³£ 'C2T5ÍyÅ [<;ËÛÜ}‹hLé4mMmÖéҎ/À}"ÑçB0%’éVE~µb(e’ ”峕UòïiN“ýië€ëÜ„{X#Œ=dÓ[娽 ÿÆOƒHð”£Vê ªëvGJMGÚêåÄLX^9ymiZPpù˜B5«¬Âø#…sW+* ¨)¨OñD¾Ë_*Ïøy81¢ÎsY×/NI„8wÖ¦.¶v.rþ÷¥äïûˆÍžá¹ˆ“¤;éë7¤{®ÈEÕîÄìø‘VYƒÉïÌ|ÝWN`ÄþÅW‡Ù¾—›º‚ÔÂâsh™ËúÊIÆ(ˆxó^m¸ƒž²Ê+»O':QGrçÉ׿[XFRž;j¸±·ùI•šà5A0 {Ab8A²T†’QmO@ i©Vél³¤Ó¸£CX;䆔¢$ŸaP÷ga†kq*Õ{²…nøglƒ’¼2GÞ Y•.ß“­õSlôŽß-%-½¯·e—ppÔW³8©×‘fÅ¡Ú=ΆþKbÿÿ‰À/$À'ê,öw÷›endstream endobj -950 0 obj << +955 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2122 0 R +/Encoding 2143 0 R /FirstChar 34 /LastChar 125 -/Widths 2131 0 R -/BaseFont /EUDNXE+NimbusMonL-Bold -/FontDescriptor 948 0 R +/Widths 2153 0 R +/BaseFont /OCIZJD+NimbusMonL-Bold +/FontDescriptor 953 0 R >> endobj -948 0 obj << +953 0 obj << /Ascent 624 /CapHeight 552 /Descent -126 -/FontName /EUDNXE+NimbusMonL-Bold +/FontName /OCIZJD+NimbusMonL-Bold /ItalicAngle 0 /StemV 101 /XHeight 439 /FontBBox [-43 -278 681 871] /Flags 4 /CharSet (/quotedbl/numbersign/plus/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/semicolon/equal/at/A/B/C/D/E/F/G/H/I/K/M/N/O/R/S/T/W/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright) -/FontFile 949 0 R +/FontFile 954 0 R >> endobj -2131 0 obj +2153 0 obj [600 600 0 0 0 0 0 0 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 0 0 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 0 0 600 600 600 0 0 600 0 0 600 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] endobj -934 0 obj << +939 0 obj << /Length1 1612 /Length2 18760 /Length3 532 @@ -10077,116 +10218,121 @@ endobj >> stream xÚ¬·ctåßÖ&›£’Û¶mWœT²cÛ¶m§bÛ¶]±*¶­[ÿsºûíqnß/}ß{Œßšxæ3ç3×c“)ªÐ ÛþŠÛÚ8Ñ1Ñ3räÍ­:;ÊÙÚÈÒ)Mlpdd"@C's[QC' 7@h ˜™L\\\pd[;wsS3'¥š² íYþ ütÿŸž¿™Žæ¦6ò¿.@+[;k Ó_ˆÿëD àd˜˜[" -ŠšRòJ y5€Ðè`hPtþien57Ú8©&¶«F¶6Ææÿ´æHÿKÈ`p´™ÿMºíþqÑì€Ö掎¿æŽSC§¿3p²˜ÛY9ÿCà¯ÝÄö_„ìlÿFXÿõýS´utr4r0·sü­ª(*þožNf†NÿÔv4ÿëØšü4¶5rþ§¥ùþÂüõ:šÛ8œ€nNÿÔú ›;ÚYºÿ­ýÌÎÁü_4œÍmLÿ‹-Àhjè`lttü óûŸéüWŸ€ÿ­{C;;+÷eÛþ+êq0wrZ™ÐÃ11ÿ­iäô·¶©¹ Ã?‹"ecb `bü·ÝØÙîú\€ÿå?;Cõ—„¡±­•;ÀhÇ oëô·$€òÿNeúÿ>‘ÿ$þoø¿EÞÿâþ§FÿÛ%þÿ{ŸÿZÜÙÊJÞÐúïüûü}al²€Þ+C‡ÿW¸¡µ¹•ûÿ!á?5€ÿ&ùÿ#ådøwB6¦a¤gü·ÑÜQÜÜ h¬hîdd01´ú;©ÙÕlŒVæ6À¿Šþk˜:&FÆÿ𩚙YÚü3z¶»€6ÆÿIþ¯Hÿ¢Î §©%£®IóŸoê¿¢ÿjï¤ên÷—ØÿhEÎÖøþÁ¶uxÒý½tÌ,ö¿9™˜¼ÿÕþÃô_g9C's7€öß–™þÕøÿøý×I÷?`ÄlŒlÿÙ'Cã¿ëõ¿ ÿ¸œþªú¯ÿ·áÿyþ×¢n@#¸Õß¶Fö¥©F{1­(zR€—ùøÞ$T}¨›ä4 z%ˆégQžW‹²ÛZìŒê»“JÊzÅïPß§;X`®ž¨üH\ -üÐIí|ŒRëc1:QA¾Õžž‘'?=R Ž õÜ@öíãÑäÄÂ’ñ¸@ ’GúÙçà h©Ux†SA¥7!àÝ´_}jt{êå‘‘â’FX˾*šæ¯Ù´Ë¾'A¦· ð&Ê9H¶îWþÀ¼žŸŽäJœæšËýZw&sÄâmŸ -쿵$ œÉ„®'~»¦ìw 󬵮¦~íCÊ]™Qê,©wmÚ'c¤ w®Diµs$óÐY–1¾—f‡ÙÄ&>.jüäë賬9“5ÎÕu¨ÍÄV¤?m=Á8ib/4l¼˜’lºÖ’Ÿ$):Srïð¹ŒtéÇ#/sƒydŠü¡ _•vÏÐX¢ÖÙ"» ú”4Ú]Ô†Üf†·”-FêÕˆFG‚„ùs!kt> -j8+¼="HOló‰à|V”LôIŽÅ_y·1A‘T5dSoEy%|Dm3N†Á‡P¥{ú¼ÞÆÙˆ -šÔ0ã#¢DËFwˆ(¤ ÙÓ§~¾f%ž©Y·˜"<Ø™Él¶‹Ç¹ÿúä2Ý©²HˆîKöÿ¢Õê’2|Cu˜Äï4‡ÙbIYY`AýÝ«!ðc* w¡)óÊ~#†!åÌDйp¼šÖ™(bðÆ%łߪÇ4òsœ.劎^Ëú0ª†'> -dÇ$[ß4˜h3iï*#§†]Y·6_¡$l¥—\5Š´ -ÖƒGÒgÏt7êz \ÄØSÂèÑÝá Kz¬Å~»šF£¦s>y{­)ÕCóaÑýû²Ú7× Ý#ÓF¾o¯Q2v3äòÔן¼xÒ¾#x9s¬(ÃÇÊÒ÷öUX7Žqb‘ŠŒHö;QºÙö³ˆÊëí:²5p,sÍŠ˜VÚÜýXQý3j .jWô…¼¬[Ç2#oîä2’«²6¢£yé0O ÙÓËø8³)Kz¡l„ïzä^骟|‚gOH)àY îó¸¢e¾,Ùê›Ì,ðŒ‚þ²Êsźy&Ê⥄ñϤì*“@bKiyäúk@WÁ»¾/ÿë÷îÆ5 Ï##êáù@¹‡ŽRƒ;ÇË6ÈV|¶å9{<)¼ç QU+󨉬@"9ãå·¾9Ì-–†Æ¬»î³ØŽÈ³¼…„e†t Y.ž±áWËÔÀ;žš¹„PfÙWÐBNûŠX÷a|nÓd5ÕR©¡Ûo÷¿]fǧ_$¿å0[^ž‚IpƒVzrEÄsÜó^Á¤ÑÏJó„½Ë®Ïô—qŠž€3«Çþt¿ipôøÉ¼ïÆ/ÑøµÑ7d™§©M’°{<1†/ß{€"Ãg'”Dnnë«J0 VkÜ„},j6ä²6”ª ’nå'Ž`gâ[ö -õ Ò””d³3þˆA*ú<ì;»ãçëȈÏÞr‘U¦Ξƒ ¸R64yEIÝ#ب[@“4ÂS»Ð¯«±÷è(pÖg/ä/ÄX»ÐÖ@­Å»b¾äcŠÅIî n¿¿„îçç3Ã"çU=^ó»\XºwV¯”¡ûB:Ï‘ -[—ÒØ$ ´zEø}:µ`s(éHô‚Å+X—³÷¶*5Â^ÁmøÆÊ$¶ïÉéGH ->êò:Û†ç-àñwN‰ -3“7º]Ç }"}xt¿-i7Ÿè¹½‚• -üƉ¾ÏÑüІž@S&_#‰= ]Œ% ešPІ¼RŽ”oQÈJt{¸œñàº0ê8&ò½A"zXXª‰„^i$º@õÁh0škm}…“u­@îK/²OÊ\®zOóu#«"ùÈR.¯AÇ„ŠòÙôÐJ©4I°muþ`*?섨0­V2×~„/ŽZ.&òÂ×Ñ_ݼÇa)¼<¯l ‹¤ab˜wK¿ð[p…*¿–ªì˜F°_z¡>ôÿ-p¾þmQÌHtðFЇt½® ·Ð[Cr:Îæ'w|…ôSoñ;ÕdȇkM*a1eˆƒS¢ß%!¹J-¢¤tXäÖ’´–šBÎuÞ/ -p‡÷/ó¢nD(0ÂDã ,q®R5Î@¨)µŠ ö|÷ò¤ºÛ\{=÷5¯ãƒ8zB uyÚ£e4O랊u¼z.©2Êqi¼ûTœ°,³Õ¸¼[¡~o$n{Ìq³¦×·1åŠ|…²Ï!§-4`f‘ך¹ïPÛ¹Ui«í!3ÏpN"LnR‰ôAQ“!ÄùðíSÆŽËî1ÕÔ9PƒoHT7-÷dâz7/ÉÐ÷3¯vU~2‰áW3Ýk"XŸ&¾L;Ï´Ö¾s°˜9¿O'`u?‹¶Ôi„ØCBs®Q‘ô±…ñ"¯Ïæ˜L#ÈÝœÿì UüÒ¹ùeŸáS©Ù_§Ó¢ªîÑ _e(ò~ ¾áÚÈÙ¼ßÕt2ƒÄI]Õ× Éuûͺ›WV>{€º^7¬K·ƒ9@3¤uÜq¿¯ØŒM(ÕAfW$ùÑ>Ž¢róÕõ'Üt*®IkÒæ·&„óÎãÔ£yù„2¦§äº VБÇ/êÀp4¹‡èT›ïwnÚuŠêæÔgW«È$&¥é®&tÏ„ZgqÙÇCȇŒ† ßðéårüc­ŽMÔEÇ×çÔkâÓåLÁG1‹^­?z&É ¢2™"«….^R,• ÀÜ ndAU]l$þôº<¤q Já9 [Rèç+œ„$E˜b…†F΂dù#ÕÒéËYûV·"r†Š}cà’³$#QZ0 ãû‡H„f¡ª÷›v«±*øöç9êž§Ç)$¥!€4%J)Æ«B¡(kèè^«£ Œ¢K"ôŒÖIQ§.¾É°UDBó€â¼HÛHzõV¢’éç5柑&xã>fé.j/O§Î5$8žÔÎÅ òíʰ¿_ëqv–'´#zÑÚfs -[Õ%:P+t¦*5Gil@ÐvmY‘ ‚œÁ‰~¦S JÖjn5£ë—ðys¬Ø0ÒÉð¹¼tOC»¯‰æ÷­™ÄiÐDX¯ÐåpÖïÆÎl¶TS†ffe2·©iB>²ˆÜKmV3 ·ï¬I‰Àq>ü€~y ±z‘ô&VQ|!æ 쨯tàZ…)"¡ ?ëzÁ4%vïù2<€ºµ—ÊŠ¶ÍìA 6häæŒ‘ÿ>„ŒÔxZÜ5&R'!Ö§•gÜ…«¢ú½s’+ÔCÐ[ØÄx›)½ºo -Ù¿®;ªôŠD™r]9@èšÌˆ“ÖS|æ[Û, ('|f¤~}Ã!Ónëw¦©®n”Š\8ÖgK½Uz:'=*"Ô›%FWHO´­Ú³ÒèÒõÖDÐ_|ÌÎ\ê\Û -qá‚ú a¾ýGŸºî“•e -™âîÑ~)Ü“U‚™$¹ß“ñA=‡C“ü‘:³œW•Pv Æû§hbÖ¼ð»AàlmoÎUÁùË7…¹í \~3È -ÂÏå±äÑs‰TNŸ +Ã<ˆ•9O¶¥fÈËDˆF§‹ÑÉöY廙l›¸·°6¿33ïáð\1ôb° a÷ Á{ó|³m«é*Ê›}½"é?Yš,µÔ¹‹ e§úPh‹ŽŸXEô¸º\©çÜ[ëgøV3C^à ±çSø¥$š ƒÛáÃ:“É»®’´ ð¾ˆïÅ^ƒÑÁ´‹¶ù´ë¬†)à!jáìKøGR~ŽCkCœùŒBΔí!$ÐdÕˆV`¨­\ ©n¿»Gó§æHðnê Úïvœ&ëÌŠ":—íÞÕ^"Æ;bÊz³N¾0UÅÕ–ûÖ1ÃÁ,Ծ㢫|7ßoV};º:Mý³éØc£ôÂà¤=™MhüCÔgaì‘7¨²Âˆ±b®5_¡·¸/ H:L« >r>Õ²"™y£6o„Aù±RQ ¼“_;N\¾L©µá%7¸àÀ‘¾g$µc [ž Ü80›=~Øü.¥T¿†ñ¥™^šW`/ž$8¢%S>ô”æý XÞ$'ñ.ά¡¥„2Éÿoƒã;At«!Äò‚´žÖ&\Åžã™dn£˜kjÓ¥³< -YRç˜oiæUìÚÆ‘ÌY Kî%?ê5TXrz¶ë[È/¨£=gU0‰Ü„€UShW´1ûºzcw™>ÔXê1§†S\»²3Š‘ÎBaʉ@,ŒëÂ?/ßu3u¤ð;…®MXÛ;Í0¾z“ƒE9–T¨ÕÖ[x,ÐÏsô1Æ÷Ìó–Q£×©VNcÌ…ËrÖs,¨ ³“eeµ‚l€N0j—;î~÷–ê2›ZoºäÆ JR¸¬ Ý.nìÿ¦ÏR(šF½qqIéì{7¸–lƒ%Jåíi6.’±ñNJ„µ­~d¢Jă÷^Oß«Ñ É s!¨kgw%¼¤ó_†©ë -??zÜ…¤Ÿ'PìE¶e6¹-Vƒú£ò>áÂPe†–½Í•Gèf5©{AuÔ¦JÑø^V¡ÌP -:Ù‰4GÌCe*Z­:?ß"íÖŠS$`ë¾*~=QîFf†£¾d5 ?Užaú9v¢÷"“T!KÈ õð;[ùÛCµÛ²Ñä$|É•ÿ#]±·,ÄgåÂc>t- ƒôÏ/c!Ö’&,î—AØ$l‹ˆ4`¿Ì™é„G ‘9h{±I K­àôáî·3ÂF£Ýйô±Peûw - 8ø=ÇC¦ñÙ"ê®ÒL¨ì:0%»¸vÕ´HƒŒ?˜ø¾âù¢õ3™VF _?Òí)Û÷³qoTŒ²>ô£‚ùvî[±~á+Ó ñ¢øøhÂ…ª>çV©Ã{‰iÜÁɾ,ÓPhF°1J4‘÷Ò.’×l"üˆæ ¿D9TäÝ!°hjky~ÒHTòövd@X|A¼ —Õò/²áxxûfÙ z¸|ÁV§Om×¾SD*gi[‹4i p¯—ðƒ½ÐØv )ilPcΙŒ€~9¤Í^-P>½•Sø¢ªÖ_Ñ:v}¼ú‰ ø9#}hçp‘à;‡¾¢~¶&í@»Âªž$ûòYéØsE6ýPÈ¿Dpñˆò϶J úy·#“Ø'PG ‡ãŒY9ÇçzÖïIE ç©_¿+Pììk.Âî+çpnT+ ±µÇ1*#Xd4-.¹.f(܌̠n{Sš©|ãPtw90¿Ì§­ã=tÜr•xÿ’Yñ©Õa…@.i¾™?#E¬4*872lºGÝ›ü”òóÕƒ¹óšAúa§¢+lµh ›¹cÿ[ÅU‚·_Q'ï–íMÇ7&U6æØ‹{tÍ3_ŸÔ_óerˆ$q¿E½â>$zr,¾.ÄBËëDÒ‰ú@û‡ÍDü”Ä­wPL+w1xàKDTjã_žKU÷‡Š¿÷ðN€úè±=©C; ]‹‰ØÑ\z©r¸úÕ~ÈK*¼Æf:²}䥳ý]°¤Bu›B<+2¦ø¥Ø×Iÿ§½²¿S©ôûü¨·zM­<ƒïˆn1•ùu›Ó÷^Vú#:.æ?¿yÙž®ïµá§ðƒ£|`q^ Iš©åâ:kÓãZFMd§Í‡ˆ¨><…÷Å4I)'16TØÍ†Nß°`‹ð` [€r óz‡ÅÜl8±§ ’¹Ll[@Æh_ëí; Hk¢ÉjLÁf'‘Ö%З&så@µTýb[Ojöß 0®šm-Z‡µ<"ÂVç­wSp#H¸Í°ÿ,3L\g*±Ý¾–Ýçpg¡’^uІªH%a€ÃuQlàÎZK‡B£vHÕqe·lAW`¬úÑ–îxüFÁޏ“Õ7º¼Î IhB($y{³ÓËòMSô~¥ã # Z|Ѻ6Æ×c>ÁB’Y”ï‚*¤ÓµEkèið„ûܲ²ê6ë#¥ÊxNÛµqqŠ®k%:ЂÃÏý0{Â4Û¤8¿ŸJØTá‡ð~UâjçµDg,Vå|ÌÙ)îmÛ ÁÎ n$;ùâßÎWûË)6{ô2÷Å1§ßÿ2_Q.4ÓZxWG)ûqŠ·óGŠõ{RÜh¯ºÎW¦ãrzÞõÈÐKËDä]Üw¹Qöº¯G…\å# n—ë{aæÆŸð»Â¯U"¨k;`aEw}øŽ¦¢´Äætf µŒu &ßéæsÜk¶Qk¥pxNšnL’v’Ô(|)²FðcˆÇY£0c…‚Ø0cX{Ò}hƒ¸eÐúƒKŸ:†ohÁhdYÔ}îw¼Vj¾]½¹cû¦wní†PžQY@V)[7ôU5:Ò³ûÑ 7k"%W¥v3<ú[j¬ån–E¿kƒœm»ŠìŸ×—´[™Ý%I¤@DZrbÑll¯azQ?ÍüŽÂævFúµg. P³e†¼x€ÉôHý‚€#j(hôÄEÕÑ7z,œB-»§óÎ…5E«›}~i›“;e€b9i«À9úHðêùÚ§7~ Êã>OöᙯµÒ+7¿Ë„8Xu@HáÐG§6¤'Q{—ªß/R2§o´D^ÒEœ (¸ü,¯TcÏ©ÆìȽã‚Z]iÚXçKâ Ó«¦ŒÜ„Y¼ý}ÉkwïPï <{.ÏÓ™O .õÔ‚Äñ|Ÿoh£‹êÙÕ†4ü&Æ ÊÌŸ¢RÚ±¡™Hõš‰ wó½é2)B­…‹·†ª"Ú7cHЭŽ8º̧\tøºlg%Ijð«]R˼a\nÝ8†÷¿ú³à!V#RÎ96áw¥1K©DŠŒ?VäÃÍBD\w.UȇH·:Êæ·7Ä­‰ö‘gBrny)A½Á4k1H´?ëÉà$œNŲ!ÉZS†^0yVÖldlƒËä~~;Þ¿g;¡Ð\ÚaæôK¾L‚ùõÛÛ“½O’l»,© ¿™[§ -¢ðBîBZYø ¡QÚ÷¥Ä:_}ÒbeÚ*r³9ò”¯Ô¿åÏ{ݘéËáªÝ]1÷WšeÂ…5âo#”‰Nb… ¨ô>¶ïÓAÎì·¼žíÉzàá]M¸Q»„)ˆ'°&má"²‡8øg+Gž‹-¯ðJÁÙ¶(!‚d%šò÷F¨é’‹Íü0ÓK^žŒð §.Úf9Õºi"‚Bœ‘תÂh‚0æ£Þ·/Dž¿V™¹6j©Û̇‡o— -_0ß9ø™Ü®Á³@3&i ¯)BBD‚Òr8ª¯sÿ’¶þø¶6ù5EåÇÁ‡›3§ŸÒûišI©R«‹ª]S¯Ðeÿzý!KþãÑÑÛ7çÙ96@:áO´ˆE(Q`¡W¡ÐêgÉCIà¶ œ7·@ªÁ×N~ðOÎÏL ÔšîÑ„6t>æ€ñtFt&QòŒõk©ú¡Ì: ZBw˜0.•Ö -X˜DöBà矉uƒRá±êëŒãù³"‹‡»½øS,VëUgÈÓÑ×Hë‡ Ö•Ø®ôh3ßõ½@gYa°«¯ÃK}\)ÚÖ„èoô}7dÔ{Â+ä’רþ‘ǟúiæpC8[bk%u‘I0: ]¯úíŽI*]¬NꌕԲî<'âÌ€Dq¥1öYßþù4ˆù;4Ù´Ô˜¥^ðžöE›:ãZ”¢‡ÖãßhSÁÒ"”‘æeGq ¿¸ú‚Ò®ˆ÷ñ"‰v=}ç¾ÌÅ%ű;>RÕw´ºÊuú)DãPèñåVÂ-{ i¢87£rC ~zIu(a=/åÓ`éÇ -`JVæ€ÝM?Ë-*\šFì\q¬w÷4³Ç"Ây'LÜi æI²úвTxÝCxEåÇ7#Í=䬯šÐ]ÏÂ)9™šj^wpŸiuØ•°I/9c½šÙ;ˆ†YÂV%íÇ’:ðgEFÙÒ·O(–qS”•=ŽM.A¥ó¾5Æ·ôŸ·¸PF×/ *ÝXåï·Dê,oö°`ÐO„&ÄÓú1¢ç)ã”au§4‚x­¦"ô£šVKnþ?af¿½ðÒâº-©Þ(äM×4jý€‘âª[ Âx06Ä–3± ÊbV®gG¬$¨ˆX”£þÙ]0ML]B@! !k“ö'9iH„%7ØdÇýý³ê«VÂiH€ð‹Lêõº «§ÜTÉMÓ´1=1TäöÅ¢ÕæûH&LÏ5« "ŒúÞ¶jªÏa1¾5e‘ׯŠ9³dfƒC|—fS}½Á¢^3²Ry€!©ìcÊ^Ù±•CyÞ>æäŸGY›µöLˆ²Í+ðüw…¯‰‡›]E™†ÏIœº#½Á”“W¿ig/€¶0@hçnlÊäª5Áç®ýF6PI¥pKˆÈKUëqßoÁÎJôƒED=§É*óS½PlBø±a` -^ñ2Ý9á4GÌMdHä:a,h&y að;!Ù$õÖaÖ8|Z2ÃdÞ‹J‰Óc—…6‘Ñ}Äu"åÈÄ7)õ)ÚÞ”L#mõ0n—Ü^žÇl¡~c[øïz¡AèÖЕ–êÍ™qùÐEm)PF½÷¢xŠÔ–ŒisØ€ç³D6 &œ<ÝÍYï’Úl¥ç¬œs·ÚCò£ypKWFsš£jƒ“ÃÉs ÈÚË~ -¸š4?æ·q|CÇÂ[9ËÞnÑŽ¯U…”kCWvܾOøHB ÔfGpÊñ¦Ú™uw"£Û¬‘M+<ÂREÍœËâ`Ôщ) SßêÓk3—ÌŒÊy‰m:ãs‚êf“Bܲþà ĨÙþ†¨4ÃJ´§ ¹=µ¬l%Ž»Wa*ÂÎK6#º=\{œ˜{áÒBz[òaey}1i%œ1ˆpÊeDNi±`à6^¥ -“V-Á …ê©>Zw>î^’:ðëÖ£,AÎó=a¼PP?N}“­8s3zxC4-áÙ'Ð@¢¯Äa0½ÌåŠ&vù& Ê«¹jÐ-OB;ó¹bîAl/­äÝÈ»÷ #o«²#yÁ?.¶Üè© ®Ï² -sf"7íȘ'z½½Aܬù;˜-Ø„º5½ŸPoö’RnÃã—§cÄ­d>­Õ‚ëmOévXš}Ý…["äC»Îµš Ú·ñfº ?jÊ…Šs$!ϧmAb÷yg‘Õ3–ã¾ú©Ÿ™ì‰YÊIÚÓjû[«Òaî ë—e·Ù{/ûÀjÂé‰õÙÊZXÀüì˜à äa.ð–Ïæ\àß›¶üؼ¾~ ê¶Éþ¶ü5öZ š‘X’oJQ˜iOÎãÅ[=Z)é!³»&ç–ÃîIëBå\Ý;»"B7›§ c)Œ—†Þa%ó‡ŸTÚÅLn_´´i·‘c•udg/U†Å=7 -BÎA>ȨÅt»î„ÞñMt7¡Š:»ùœ=2>ï((Ÿ!{GÅo’8DiåGÍlœ ÊãVÍÒUŒÖº‘jÜ”Õíë -ÞÐõ)δ¨ŠP=¥ŠúçÇ ºÚiÓNRŠÓ€„™m:ô¹¾@1??¡– ­”x!MÕT•ÛŸAsË•-&I˜·ö@ãݪƒêE!F_Õç5²î´ÛT² «ô±.è-ó°{m”´YÐßžëÈC&ÐöºoÕ¬ìêW5iø·Š ¹Ž–ðûï~dÏFœöN{uÍUg¿a`BFtCÙ¾VØ-¯Vâe*ï@ì @uòQµ ä8L°4§2Ir©¶Ð“†¤o§¿Ù §¥ëÁIÆtPÕ'ÆiÎâsëŽÉÇTЃF`Þ™0Úu­5hJ»½ Ù‡,KíÜкÔP¡f|éO7§Hf|dÑr^kç Žß¼¥'@>¢íð@‘…„—Ä”ÄÄJÄÞ¿Ý>3„Œµ¬èZˆ›Ù¡R^XÚ9ÈÍjÕy0”Nš¯s„gA‚îWˆ™[Uú £™2õÞzבl‡KØ6`ñ -î†Å×°æËùß'™+¹O?àªH‡q@…ÑQœÙ–l.vk -3Ô+¸Gç Q@CX <¢â*î>Ö‰?7ëÝSY±ƒ°±÷a~ü¨=j ºíd„¾‚þÔ‘"Ød±ÊUU;•ÞÆrÝJéŒ$AøZ©uëÎñ³‰W´Bšgûû±wæp'Øbû5莵Ë#—½ë ¿É¥M!¹q¼V@«ßÂ=¼8жœÃñ!r1†À`^6]ÈÊü«o†c\'7 V;:šb˜€™Sì -…eȤ½øÛ ]Ûq};—¼¿ý%W[J¨÷¡¼–Þè aÁþ[Ò-@^ŸFðGH¿ ìÏÈܰ<·eÕ@wô¨‰Îy«(‘«xd;{”«‰U¸otÁªDÕL -˜ªˆÍ|Îóp—aÜ^§9Lî÷‹¥¨`=1OþLˆq‡p–*ÃsqÇwŸÚOuØÝã-ôõ•)D©Û¹(ÕDIÅ,$¬ßÌ÷!›xŠt¾+’V‚Zä\õ‰ØÑk‡¥ vÜå# âiÑò2œK³ÈÖ–ª·K ?žfÁ_ ž`á—À§,‡h@cÄÏÙ›‰„œ#¦å[àŒ‘æÈÝŒ‘IágWà^2/Œýäoö9œóê¹ÜüŒða yƒ?wR"”S;¦ÇG^ˆø3ðÙ»¥%3œj˺Ø&B–#vàXÂÃÇpçŽ7†.arï«ö •íWÓ~ j¤gb‹]ª6ɵvô±A` Û·ŽîB s8<«ò齓O`«ç( &»Rð¼ÕSÐó–=Ãê‘1ßì¼Û#ûžB6&L`¦­k7èT™7„,uxæ}ëåÊ{!,¯&šª‚i»FB6˜3=…ÎÀùÞþì…æe£Qµ5'ØŒ™Þ+ò@3îàœ•öÝÔÙÏ£’â»Ûö_:`n?ãô`}ò4 T躉l¶}™=aC,I‚#«&‘Ü÷Ó_rlïyÅ–$S—‡—8•í–æ æý©ŠV7Wo¿ßγœ'“éžÁ©Z [ÆN«éaîÓó'¨5ˆé´ìiU÷ç+3=;– ov –ç 8\ õäñ›V†Ã4¼@jãÖ)ãì±Ü>ÒíªO+^xN¼s—]Ž»(¿ïi¥™¡ì §±,¡ÝèAÒãÍúŸŽVjóºb,ÇnåCæWä¾E ±k‘ -^ú”ãh@RÄfíÁ•6—U -×qóp&+yPå°1¦àÙÂ¥å Xˆ|¿ð$6Uç»’ÄŽ¸%¼ûm'v»!†æ^™íç Åä.°¥6q2Œ\õº«CÛ7E.ÄÔ—¨lwBÂæ8=÷_so09Fµtéf²ÅoÊRaáÜJýèb;†xŸ)ォG œþW¤ÈùQw¤ØØV„K˜7µºy$•o5MåÐà,=²æ_³4¥ñ3ž•÷°Ÿ -áB«¦¨Û$EZk°`ë¥Y 5qÁ[œù¥ëÂF… :ÁƒN„´®jîܨ€›JV[‘ -ü™±8Ébº¢¾9àѲœ&Â&9 h°¼§!`Z„ù“½M$¨'Ì é·Ç ˆ‰b|ö]·[EÍ\çtHL”.=MSeî{F"ä(ËfIÜ -ˆ4ƬÆx»ák&ªˆü• “KѡڪƎ5soõUKæU6Û‹m™³Ó<{WûFgsü2‘“+tëÑɇ¡ˆ§Ç—–Fë¹mù¨ö9¥ûŒí¬ ( Q«¿˜?©Fß§$‹OÌr?ãZJŠM¿{m9ùœÄ1+ɰ‡!¨Ú‚§¨næòY:ŸAÈ‹Wv¿ ˜iq“~ˆRŠ:²«ª j½¤©Gc„ËZÐètúœùyF6¾K*Û[HzÒ§ib·I þhŠÕ‘¿tîÈøhbþàáDëÊ0Žñ/—Í• W L|õ)ä™Ê~¸Ã$|hæ¼)½ü'CZHsöfW^È¡µ „u™§™êÄð‰¼—9*ÙËŒÝÏO´Oý bDòÎ7޶³B ­DÖD3]‰xécFb\“4“ï› O`É@®0{”X«V%Üq7j·6Ç„ŒìÏõ¼Âør¶µ¦§@Üt,«"2ðÏǹ.Š­Ý§ã7‹ø£¯šr°>C;–wD72Ð AvIlU&m¡•˜E4Ù(`ý[wZQ3‡Ùµoœ'é†zDŒdØ'ü#mø Ͻç[Ü#ñ™‰.i¡®îñϲzåª}:K-òÐm(¤²“™º>ÍÝ0«l7á¯r†Ûì%óÙSï)?ú±ãR™Â—wv“iQ— øð`gcÜabO©_7d@ Óq¿" ™%qtÍGJ߃Ù56榑û¶5ù|[!Ä”L{ü÷ß_é$£½—zø[HŠëNκü-ÅÉEn4«Ržú˜‹¨ç£”v”bRŒiº& åõ8æz Ü®ºˆA¨.Ó}:pc“%„9¶³C@Ã×vt|jâ0òFóðÛqò¨|jùŠƒÊá~·l–‡kàVÞ5-¯$Ý3ð`z—º¨Ùû…>F½IÜÝJ² ? =q/ ØîAÏb“~Xc„\9+&•óEµ‡w)³SOS>}Sl´;#5(î=:·qøO\ᦦDø3ÖF@rTôÙoÈ'É@'áÛ¨9o;=Ò«M!±ë{2‡JÕöhU5ŒGÊÇÅúÔr–Ùèjšíê–uÀ@Ætáóå•­qW3gPÚž‘õ§/-‰Óî¨~%ŒŽòû‘„¿Fãk Óü§:(™aÿýœßL -íqÃoØ8\"ÉÄø‰m~'8 £Éùª¤\"~Ķº…puX‚8R±·ù;¤‡,qÞ\;1´L AÈ›œ>lϴʘƒš¶ü¸\UÆækèK¬ôó(29÷ðJ3ôûõrï˜O²âåMçÑñBu”ï§‚!þ*²‰ñØx“–ãfðÔƒªáFb6ä([N£+þe÷#Ìó,+CðÇUÓ3Mcf‘ÐAñn0Ja¸Þ.H”#ÓJ>U³ÂåbFµîV?4™;> -Û Ì_÷cvDMÄȺ„‘)˜3,fÅ·„@sž?X³¡˜ò\ªå$@Š$ÈW;ö=W!za(NGv È(èᇓÃY†CõdQ1”On?S9Ç>Oµ -dõ›#. -óÕu«ðaxÍ'¢T´Æ49¿} -„¹ƒ°yeàêÙÔSYãæœjî×]…)Å’ÀY¡vSWòÀ­¢ÒGÕîUê£ ãþh4× ¯DTÚè¢Ë ¾ŠŒ}dœœ'.ßñ»c)sùÂ4E©”€cr'L’q!2XdêFÒ±!NMi€âñ¢ÂdÖ |H—^ÉuÞõ“ù¦?aÈísNfBèÈ(û;Ÿ>§[Q-„- ï$àKor§ËûI’;G¸],˜úJâAžXÚ€àvÞ9g•0žh}[ü £Å‹—T€%/WHþî×Dªÿ~Å!¬„ŒµWJQ;dZUüÁˆo 7êU ‰iT†dGà!y×"?αLÛuº·Ô~¡šŒ{U#[Ö÷g_SÚ®s·ßñs=„Ñý}Ž´þ^W@ƒ¨IÙ9¼£ýè@‡}Ó$0_>)’¤Èz®Ep,—ðóõ覲üˆì£å"è`06déðµÃ•GѶ`DÅÄÑrß‹èGÃõ¶F´(øLIÓÓ2¨ÄhŒÑ¢syçw-[ý $SŠQévÂÙG0p•|õL ŸûŒM:2ßx¶åÊ®I÷ëžvH…¶ß]„,U5‰eÅæ°LX*º{Œ+—LÊjŸO}«nU²9¸ç\wýÓ/~cÝS4ƒRꩱT.&êò³Í66USQ–‘*·R°l"È÷è;/Z÷«ÁB5OmùǤA– -ÈïQš4Zl’€AÍMNÒ1B.NèL·YÏ¥£ÌÊ©“0d›±)š„¢«ëOØF'Í<I('Ó.DÁ=Œ”³‡pEd­ùØøõmQÜÛÓJ:ëÔs††¥[H3h™7Â6uaÂÈ4UgÊh {V†k|–¶ žd£å4A:kY’(‰®rŒ“JY55b¢L ï¾íV·œ2kÙzÙÛÌ9éúŒðlâÞõa÷xSkðJ–†µä{Út´çŽ[9¦3ñÇk4OÂK8­Ÿçå Û°¨oS3æÈàQÌà~i–¯³•úc"uË-ëe0¶Áÿ6µ¡ÉÞ†ÚÄÜøÊUƒÆï¼à쌪2ئ„T(™˜ž‚è ¡)ÙqìÔn»Fñ±Aò¼Œ -~z#ë6 å˜Mmné©^«ŠÒކy§×ù{?¤¾ó ÃN[„!H-Èâ–‘Ôyúê³Ból«nsªYòU4Mö¤ ©0lÕÜ´~µÇê½æ`¾ü™ñd™ÿÍ%ºŒ(„ïñÃpY0çh^zÑl™dɄ˱½ú¸çðG0Q'[9R3…m4cA¸Ôá÷¹öîY+x‡}Ê)¹ÕV¹„çþìm‚›sÞi -chô„, 3 ‹ ï‘“#•ÃùG ÖÑŠ9$5à »l|ëQλM}ž¥’>‚ÈÔ!¦}™n¿°B=…_½' qŠ=ò¼²D½JQ:|4ù "V&71¢‡»Ê´XGŽÌ˜Û6¸XÉLjðD^«Pìˆ,0ª°>«ÇŒzK „Uê• Á;ð# zJí™ÛG ÃLtåk ­' , 2ýòô™ÏªÍÑk|Õ[~>'}A–ž­h¦M$™O¤{É™™aý|Fo¾á¦›\basmç­‚‹ÝjM߃½€—RÚ·ޤ`W 5YC¶]Þœ}ËA… IñFÝi„—¤>4Å1 <ÏÜïQ»ÔäJ!¼@ïµ/g”ÆL…˦Xx2¹Z‰—L¤xó¨jZ‹¿•…< ËÍ(癵uèKvÝ%' ¹ä†¡&$XôÕÝevþŒÂ…--kZ"»À¤Kõ.C!5—ÔÖ² NɆ ÅŸ;DrR,çÖ‚ŒQŸ¥Hâ-A(wYœÐ% - ±(ø'E5 Í0Á{'­WÈÐÐlûù 4·Oÿæþk¨ÕÏÙ€œ“æ¬)Tlý¼SM¢ÌºtÙö:ʇOI[|¹,™á -¸} ³i¼<nU·ƒÊ'D†7Òz;%s}S°l<•’y°46Ê–TZ¹eÛ]DÕ\Y¹ñ}˜en|(xèn)<¸ËŒ¢G/Çê‚«þf$'„ƒ":èuë ìðx/’<€Â?‰CòSÁ064qcZŒz¸ÙÝü\! ;‰^ ¼·'PZÖ‰EvdŒ¢bòjGYþ=Ñh/«¹È´®ŸË $8éÈ'kê¼²à -%gsðùB§*÷Ä•TÝþô¶VÔ½~Þgÿ°s-Ãê¾ù¤‡I3ôÀâʨbŠÅ4ZŨǾdzçÏ—à Áç‰÷ø×³ŠX]"ïe‰¥?ÂÛjš…<®ÛsÒfÔAgV+¢ÔŸ8ýdÚ¥_ÜÌl:ɶ™q -L! … a¥,C-CŒ}M¾~šÞƒÔCzâë—ò '|;¦DÜ‹ Ž‹¼”ýû·NsŠŠô c‹Ð9T#qY%%ËGð 0Ù¥*÷f’® -.³ã׋ÏLH]DÒ.½Å¦œÈçûNcxï*ÿÍRŒõjHGmwr$Æ›~üzXÉõ½c7G9±fRpÂÔ›õñ`ç¾/ŽFöøÍ¡Sësöe‘Ä¡ûůjrv±K ±‚º‹—li¬@b Á̧òÓµ¬FÁ§”L¡s¾´_úm\9G›8+¥£XmK‰^γ³æ&„m©œtðÞì]ª_l„Š@O3º] q—ÃX;Ü3œåá› -kƒãåxÄüÁ‡¹C ¥"QPf¦CY_vŠÓÑô|‚ŸŽîdœîÃ: eФÛw‘éûe« VÑê–†P-o‰ ã¶*‚½—€:GçMøŸ¥ÀOr¿/CîlMk[6qÉŠP·eÙ0ÿ¸•Ëzý?TRÈõó·—Ï(ªå8“j$27BjߺÌèÖ–õ¦òãȹÿäâÌ-:N ^TüÚO`bŒvï ×o(<>yýeþðHó‚Tƒƒ2¸¹ÁíåÞ(å2Çæ¬9½³g¦F³Ù å’Ë?q…ÃNßJšPZØcš¹ÔiΑ88›ï…wäD&oô\<朕çÞ‡.'cve‰kÎþšØuôI¡]Èš‡þý+‡¨§Ä ~¸db D:{‹ÛÖq •¢j+˜ZÖ+·?ÜT±æ­ºŸÀÜÀ! -û:%é5¾¯åV¾çu™J°5Jòb´â"2jþä³àí=j¹ òüÅÍ·½OÖ±¼×Ñi¥Réqødoeל}½j(áIaRFT¼‡{°˜Të‰n°‹W÷'½y@,}H5»A¬8ÑLØÑ]ƒ5ævYÛÐD"ßïŽÊDʺ°z¡Ž »z}ð…ˆÇÄ_@ïO>s0<#gr¹ñ´»f!bºÛèÊ5ƒ¢Ã–x¦ÐJÚ./°A>x»! jm–²sÞ7vÁßC}AœíÁ÷}Žn4XìÅVÄés¡%›†¹¢{Pû< ´éÔ Ì7¹d±·ÝÖ.´?²s1‹t¯}¼;¯±Ý½’×Gû»{UÔ.!ó!T-ºž¸9Çݯ~_’*gûkèŽvª»¦$û¦ÝU‰ô¥5Sü¼‘i÷I´Ï(Ô_:$³^‹â»Ù…eÑ\ ¯eÈk#Ü¡ðï…Š íw¿ÆÚæ'È­ÏòãJk-Yc¿ö3A2ûW´ìßßUøäë/5^]ïèø×¢ òÁoÀ&ÇÀÍ/úŸNÜ&ÞÞè\:?Fîö…)«pÈ:RªB¹TŠP¶×ÒªA -¨ïÃÌ'l¿:¦ðè;{3¦Íäeµ—Ä;»¯McÕÒÚ-ÿXON´Â½²ùr0‘õC€ƒºÆ…L9ꉱSWËñÛÖþN2¼‹ÆvÃñ’ýÐ È*ö{ä•k^‡jogÊ"oØÊglÂóIüPÚ}tq(½Ÿ -QCm6õv;1w²ª‡Hk_Êx½xµ™\Q\5“`b?ÛÓE„ÝH¦æX­Ž…äš»^ÁqL]ÙPºÀ³A‚ä£h]hò(0ã»d68ýÀëÓQ/eÃ`Ü›i0ÐñXV£ξ0žzGïZUOdCZ4[J)é?°µDäé*}ï uÒÌ{QýÜÕ‚äÕ_x® -Ê’¸È˜”m€¿™»_–pÛD‹KÅ|iVWeeÀÀ«‰ „lÐÁôÿê4èT0Éëë]Ïd‹;PL¹£¥e!D*%)f­­Ð¾ì {ÄùíÐîòsÃÕ|0ŠLï-ûÈØÀªY‚èZ`ä<Üu´N!ìÆÂçaæ¨ÞôIJE OÕFÚØÙ‚™O¥ì鲟‹„œ*+aB5*êëˆYš0MŽŒ£>ÂãðSΚb¤³(=nìj‘·æÑ4W­ÁÂ-ÕÏ·­_ѱîíô‡Çº™·` î%âg›«ïW‘iІJmøª º¢Ô††ß‘$1½ÑØ“](snr…„L¹Rœ±¹UbµVfn3]ú‘ÛÀáˆÿ3È9ÆTÄk›“¯Bšž«µW¯ôoäˆ9u“lܲ‡vxvèô3Õ ÖÞlQ;, ÿ®w½ß,Öf9z ïï‹?ŽJ¬äl* +pË(ÑMÁ™ž eF×gº‡@‰<·5ð˜MêÍ jmòÏ °ñksŒ]VY:zÅPÆ]•a£¿u_d„‰ê`”]&6ú‚–2#³ëb…S–ä|_'UBÉ9ÇØÔ*+‹©´ËY[–µ²zŽ’w -Áë±(`°1BøÍéÑ÷kL»;B„/ˆ,à  G70“›(Y:¥ö -ùµi¸ŸÔ§îwX\Ÿy=rû„7"¬ˆiÝe6ÕÈý`Cõì¥oØ?g`ÍF朌‹ÀH‹†ò×ÓÕÏ‘`ñ» ‚ƒT~65Î.96,`³xõµôlë Ä\θ;&¦!kÇ×å ÆæÁJôV>ÓÛnQ3­‹c…8¤„½aGãÐ$îÉ(»çf†A*"CÛï}„:¾¹ Ìl{‹7nN^ÐÊ`„påƒå˘ÌV—Ûyþ2>÷{Ή =½"ž;ôl`¦GS=)ÅhhR:ê bÞ°ã}µ;íYÏHey~aN'¡¦o¦NQ»ð%`\ô?G°2™9×Á>ìSЬ7…¾»Ù6ò_qÛ§ÍȒΊŽ¤¦vغä.Ù#*Íõ¹²G-–à°Ã~3º½øÕNôdàÐH¬|ò€Ò>I6]ñs˜öüåÛ{ñ7cÌ a8d?‡ÉNV¦æWíûê^ÙŸ\W’é†;ˆwÒ`–v0zA…füA©‰õ§$=›Ò¥˜ÖÒGVöašMŒs*(±Ó8üì¹äô¶^d•àŒ1÷·»s®ÛCºDdq -I¢BŸîÙ¿¿²ÊXãÞLbÁcÔÅã‡Î0¸±hÿŸvæû -‡ðgl2²¹¯u¶¯}gï™™³;dsvÉÙãlBvg”y8;âì…²et)Þ?âýíý¼Ïð„Û!O:hÛDr@Q9Ul:Ø«Táa¯a ..4EÿBÜÖÑôŽŒn†éü -ïÔ2AÆìöâ©eîÛ›Ó¦;»ŠÞ¹‘°!¸„è`Ò]åU-YñÌëŸò¬ùM5ÁF³·&RGßw´+ùûè8šŒÁÈfïyFW OU£wÀº$¾¿@i¼ù9ºùr¹>ÒHÝÂö§õÆe¢Íw{˜¡Ù -,ùÌçÖ6ºþ‘ß‘—§ìä*ƒšA>SxÏå’ò§Oœ•Ãøjäwcâ]o¸‡´×ç?e•é%Iôm ßÞl)·œ?Þ4‹™æI¿´—.¦Äì Ê×AÖŒqh}Ä_J¬Qêõu‘¦ZX´y7³xÄ,i’¸«^飯\µ1) Ík„ÝÅ TÅ>¹Þðô3¥Ÿ¦õ1!}KGf³[ZdɦÚ^Ýs>¶ì¨¹…ç›ý˜“]û·çÁ ~V\Yƒ°ÕæÆÐ¥–tQrÿ=!ën¡¾5ó -b Ýmº¡ýŽþÒéÚŽëÁMyùAãýX W ÜKî(-ëß)¯Tà‰aß½ŸSñÖ*æHGÚàœ° \>|¢<ý(­³Ä¢­pš6>AÈ?!K•úÜû5wv")]mBßþsËäÖ»y¿ˆ~li¨c~Ÿ…Ýu¿û0Î_·÷§n¸>õã³@IIS¡å 0B}?)4ð“ìó ßùöìä]ϧmÍ|—Ýý2žÌÉuf ‹cHéwia3êêùçIRyïX”v*&äaëR¹r}"f>Kèbœ#òF¾¾R>ô•g*("¸AÄv%§U–ݹ°¾ tðî—´"wXÈD Kaë:¦Rô6½fFä’pìï8%/ÁB×lC«ÓùꉛAØ„‹ƒ™ÐȆpñ½ªWfÂDùtËÏÛƒ'qØV>“žÇëîä"9š#÷cõeŠÞ«øüt7–À“rELåÊ1<¯Z  ¡“gÌ^™7…fÖ¶†Î;xzÍ.—½°õ<µ@|˜¾÷º`ÜG¶ÁàÇ¡ÝQ‘ôÁö¥¿XmQ žh?ÝŠd„Zêภw–_ã÷ëÛ“ÌWsƒÚH ãØ´ðÕHPÎ#razoºÚ·¼§,ýÎ{=M¤LÅ;uD«&RVdz»Qò¿£Ài:ü:a‘Ѽr.<Ó!OÍÁãÏcL­ó*ó@ dbzâ2YÌóŒûäð<îº|¯t$âckÖvzÎÌfPW´ DSÄwÞqŸm¦DC\s+v¨ Ò~b¥æg¢=R8+’(%ÖTúL茜m8ÀjñÕ|"Òr˜ü¯C1Ÿt)u+ ºakPâ&2?Ân6ˆ=Aù¹ä?úZ¨içiõêØÛfÄ·âw|šûÚѲiC©ÔŒ€} -ogÓƒ1GC6E®Í]cdv®l}©µžÆÍE*û‚Xí øVr,À8è–>7%×5/ÔQz 6@^î$Æ -Ìkª¸â§hDlU¼v7X}ñÂúZ%fòb+†Î5ƒ;TÅHÿ$IÀÒR.X/+ùeÌö2¸Õ4•õ…6È(z¡ØîõÉìg,Í¢ÛäZ}~û JmÕg(±èe{u›"&Œ›Å?ci¸èàòÝþªxš» P1¡,›%7Ñ9¶£ÍCN„zD²O•EwŒöÐwAöº”\¼ ¥¶¥&†m—}É·åæ5FèHîñÁmÉæåwæµÃØ_ÁÆuIð*Š_7S§êö®B›¹æÑÜíä4žœ¹?B¸ivèÍÊ¢ûÙ‰Ð=ŠTgÜÍÎh QvUKœRŠ¡ÔÛ³=³·*ŸèÌ »ü ÔÚÕ$dno(Î*ˆÍ¥e[­¨þ¶5ÐÛóÁ2¿±¹™eTFXôÑïŽj_â|§Ç9Ú ÆxŽüP$ßB^àâG:ƒÊÊòÎJ£Iÿ—¢baDѦËvwi¬†¹Ã¥Ë•4{ÓÖÓ/mJûW2S‡êrÚS–V¸&•ˆàúZ(^S'2×ä‹’L3:5¨V}JC9ÜÖË”2Jî(>9c·aïj<Ü(ÎQC…6Ç­ X)sSl„öϲژÑ߬n -i¿5xÑ@>,Ïu> w?tiÓ¶0ûôIÏä#%(ù‰ö -©«ˆ|LO†D¨Å÷¦gîÑå¼Þ8vÉC÷I~®O–ÙÍ>mŒáõÞ¢‰‘}‚ -^hâŒð·¹ œ£“hZ™Í/øÅ_à7œÀ+P¸¸&&êåî$+Nȶp®Ô ~I(–»c¹ÚŸYªÓÅg¶%ø¥p%ö>­’H¾iL¿\ÚõÐß(¦µâ_«8Cƒ—R{‹ -޵rð¦ëØíû‹0Ê{‡˜ÊQê¸2‰«Zœa‰ƒ†*7Äc¹äJî„I›ÏüìÒ]©æÁ 1=Š¡å©òñS€MX¡¥GMøªéþP¢‹:*½ÙOT9†ÜD¨*ÀzÞÃ*Úž“¬ÿ°Ë_hg -‚œ«ê9ŸjˆŠ"J7Þ®(ðhT(ìâ ª¦¼ÜðÊ™§Ä‹V¬áÝq -oò]ç }£¯9B‘7õ· öœH{È­’ëæi`T&éVÇãs"¹‡‡ªÃßÛçVMo¼iá÷׈â{C„^×;¿_g¿`,·÷þ2 Ún“ R ɫǶ]ÅjÍuib°ƒãÏV!QÏÆ>²¦aO<ö”ñOÁxƒªH²$áófe°§Åû›ê¥úКxÇÑiêÅà>ò$­–Ìy"-Ú-ŵ ôý‰¤Ëq ¸ŠÖˆÕ"™[Ø m¥cA¸¶¹"t8Q+PK¥ìó÷Ñ”¶ëÛãh_“ ®$+ƒº‡¼S¾ÎúÜþµ$áØ™éezv~7EhÅZÞ‚¥ÓªãHÝåûm®Ý‘(ãŸÄ"Þïòwnúê›»ÉÕ”^«¦y$3î3i=+iÿWuÈæÔmâ’<£Ⱥ][±÷QgShSÝ»¤SñºïX±wû@`z>ÍÛòÈëB¶"Æ®.(ñôAàN¥Ã|³w®3¬ín1eqÞ¸XäL%­1;¹MÊ®¦*Åÿ^OìU©‘yo•½§ìRùùÑ© lå™Õº©RéÓåú’ØyšQÝÅêØÌ·XçY2‹†¸Ä¾ŒPñ+«Ö$ßo¼7SæDEÏ–GÙËËGªvË.¼–Õ£ª¾PH^ ÍuòñjzZ+3àÆ´¤Nc<ÃÃe™åGKB.þ/Qü?øŸÜ|Ý]ƒà~.>ÿèß2endstream +ŠšRòJ y5€Ðè`hPtþien57Ú8©&¶«F¶6Ææÿ´æHÿKÈ`p´™ÿMºíþqÑì€Ö掎¿æŽSC§¿3p²˜ÛY9ÿCà¯ÝÄö_„ìlÿFXÿõýS´utr4r0·sü­ª(*þožNf†NÿÔv4ÿëØšü4¶5rþ§¥ùþÂüõ:šÛ8œ€nNÿÔú ›;ÚYºÿ­ýÌÎÁü_4œÍmLÿ‹-Àhjè`lttü óûŸéüWŸ€ÿ­{C;;+÷eÛþ+êq0wrZ™ÐÃ11ÿ­iäô·¶©¹ Ã?‹"ecb `bü·ÝØÙîú\€ÿå?;Cõ—„¡±­•;ÀhÇ oëô·$€òÿNeúÿ>‘ÿ$þoø¿EÞÿâþ§FÿÛ%þÿ{ŸÿZÜÙÊJÞÐúïüûü}al²€Þ+C‡ÿW¸¡µ¹•ûÿ!á?5€ÿ&ùÿ#ådøwB6¦a¤gü·ÑÜQÜÜ h¬hîdd01´ú;©ÙÕlŒVæ6À¿Šþk˜:&FÆÿ𩚙YÚü3z¶»€6ÆÿIþ¯Hÿ¢Î ,§ª òƒæ?ßÔE)þÕÞIÕÝî/±ÿÑŠœ­ñÿ:üƒ!,lëð¤û{é˜Y8ì r21yÿªý †é¿Îr†Næní¿-32ý«ñÿñû¯“îÀˆÙÙÿ³+*N†6Æ×ëþq9;8üUõ_7þoÃÿóü¯EÝ€Fp«¿mx‚,Ò2Ój±r‡'Eµû{™À‡ƒíJTøUÛöø¦…ípU¼×Ó7Ns¶¹/Ú}ìKSŒöbZQô¤/óñ½I¨ú +P7É;8hôJÓÏ4¢<¯e·!´ØÕv'•”õŠß¡¾Ow°8À\=Qù‘¸ø¡“>Ú!ù¥ÖÇbt¢4‚|«-<=#O<~z¤ê¹ìÛǣɉ…%ãq@$ô³ÏÁÐR«ð §‚JoBÀ»i¿ú$ÔèöÔË##Å%°–}U4Í_³i—}O‚LoàM”slݯüy=?É+”8Í5—ûµîL&æˆÅÛ„?Ø;kI8“ ]O0üvMÙïæYk]MýÚ‡”»02£ÔYRïÚµOÆH7î\‰$ÒjçH桳,,c|/ͳ‰M|\ÔøÉ×Ñ;gYs&kœ«ëP›‰­HÚz‚qÒÄ^hØx#:0%;Øt­%?!IRt¦äÞáséÒG_æóÈùC¾*íž¡±D­³EvAõ)i´»¨ ¹Í o)([ŒÔ‡+!Œ4Ž óçBÖx¨ö×éÀQ†Û–Í·´Š“çALb¸Ù…B ß%5Vy>©•õ_C äåwÍO?Xjb¸ËRˆ¢kŠìßFÆW‘¦³Âxýùb1£ôB:^‘átlØèöÇóžˆ}† -ß´Ç-_†‘À=DMá¢y;3pîÜÇ£àí •"¢œÍ‰pGÄ/çk~ú’DÎv}û Î|è8|ÔpVx{DžØæÁù¬(™è“‹¿ònc‚"©jȦފòJøˆÚfœ ƒ¡J÷ôy¼5Œ³4©aÆGD‰–îQHA²;§Oý|ÍJÑs{+ø}Ÿ£ù-0  <¦L¾F{@ºK4@Ê84;/  y¥)ߢ•èöp9ãÁuaÔqLä z?‚Dô°°Tÿ ½ÒHt<êƒÑ`4×Úú +'ëZ;/€Ü –^dŸ”¹\ ô 0:ŸæëFVEò‘¥0\^ƒŽ å³Ý1wé¡•>Rh’`ÛêüÁT~Ø QaZ­d®ý:<_µ\Lä…5®£¿ºyÃRxy^Ù@I?ÂÄ0ï–~ÿà·à +U~-UÙ1`¿ôB}èÿ[à|ýÛ¢˜‘èþà éz]n¡·†ätœÍOîø +é+¦ÞâwªÉ"=ÖšTÂb.Ê;9§D¿KBr•ZDIé°É¬/$h-5…œë¼_àï_æE݈P`„‰ÆA/Xâ\¥$jœPSj9ìùîåIt·¹özîk^Çqô„êò´GËhžÖ=ëxõ\Se”ãÒx!÷©8aYf«qy·BýÞHÜö˜ãfM¯ocþÊù +eŸCN[hÀÌ"¯5sß¡¶s«ÒVÛBfžáœD(˜Ü¤胢&BˆóáÛ§Œ—=Ü9bª©s ß¨nZîÉÄõn^’¡ïg^í*ªüdïfº×D°>M*|™vži­}ç`1;s~ŸNÀê~m©Ó±‡„æ\£"éc ã9D^ŸÍ1ÿ˜,F»9ÿÙªø¥só=Ê>çR³¿N§EUÝ£¾ÊPäý60|õ‘³9& x¿«é:d=ˆ“ºª¯’!êö9šu96¯¬|öu½nX—n/:s€fHë¸ã~_±›PªƒÍ®Hò£}&Eåæ«ëO¸éT\“Ö¤ÍoMç9œÇ!©Góò eLOÉuA¬¡#_Ôáhr/Щ6ßïÜ:´ëÕͩϮ$V‘ILJÓ]Mèž µÎⲇ  @¾áÓË9äøÇZ›¨6ŠŽ¯7Ï©"Öħ1Ê™‚b½ZôL’ADe2EV ]¼¤X*Aþ8€?¸AÝÈ‚ªºØHüéuyHã”Âs *þ¶¤ÐÏW8=IŠ0Å + œÉò;Fª¥)Ò—³ö­nEä ûÆÀ%g5HF¢´`Æ÷‘1ÌBTï7íVcUðíÏsÔ5#LðÆ}Ì Ó]Ô^žNkHp<¨‹7äÛ!”a¿Ö9âì-OhGô¢µÍæ<¶ªKt VèLUjŽÒ:Ø€ íÚ²"A9ƒýL§@•­ÕÜjF×/áóæX±a¤“á…sy鞆v_Íï[3‰Ó ‰°^¡Ê-à¬ßŒ!œÙl7¨¦ ÍÌÊdnS;Ó>„|d¹—.Ú¬fnßY“ã|ø5ýòbõ"éM¬¢øBÍØ-P_éÀ'´ +S4DB~Öõ‚iJìÞóex1tk/•m›ÙƒlÐÈÍ#ÿ}7©ñ´¸jL¤NB¬O+ϸ WEõ{ç$3W¨† ·°‰ñ6Szuß²]wTé‰2åº +r€Ð5™'­§øÌ·¶YPNøÌHý ú†C¦ÝÖïLS]Ý(…3¹p¬Ï–z«ôtNzTD¨7KŒ:®žh[µg¥Ñ¤ë­‰ ¿ø˜¹Ô¹¶âÂõA?Â}û Ž>uÝ'9*Ë25 ÄÜ£ýR¹'«3Ir¿'ãƒz‡&ù#uf9¯*¡ì@ Œ÷OÑĬyáw‚ÀÙÚÞœ«‚ó—o +s%Ú¸üf„ŸËcÉ£ç ©œ>V† x*sžlKÍ?–‰N£“í³Þ;TÙ6qoam~gfÞÃá¹b:èÅ `Âî ƒ3öæùfÛVÓT”75"úzEÒ²4Yj©sÊNõ Ñ?±Šèqu""¸RϹ·ÖÏð­f†¼ÀA'bϧð!KI4 @·Ã‡u&“w]!&$ià}ßн£ƒimói×Y +RÀCÔÂÙ—ð¤ü‡Ö†8ó1…œ)ÛC0H Éª­ÀP[¹@SÝ~w0æOÍ‘àÝÔ´#Þ%ì8MÖ™E +t.Û½«½DŒ/vÄ”õf&|aªŠ«-÷­c†ƒY¨}ÇEWùn¾ß¬úvtÿtšúgÓ±ÇFé…ÁI{>2›Ðø‡¨ÏÂØ#7nPe…cÄ\k¾Boq_„t˜V/|å|ªeE2óFm<Þƒòc):¥¢@y'¿v4œ¸}!™RkÃKnpÁÿ"}ÏHj/Æ*.@¶B™¡áì8³h¨ûÂò0:z$X(q»®%ù9ÞÃX*´ŒEŸ|ÆB¬-$MXÜ/ƒ°I,Ø iÀ~™3Ó &"sÐöb“–ZÁéÃÝog„F#º¡séc¡Êöïpð{އLã³EÔ]¥™PÙu`Jvqíªi‘0ñ}ÅóEëg2!­Œ:¾~¤ÛS¶ïgãÞ¨e}èGóíÜ+¶býÂW¦âEñ%,ðÑ„ U |έR †÷Ó¸ ‚“7|Y0¦¡ÐŒ`c”h"ï¥]$¯ÙDøy–¢U”÷³*Ëö;•»°žˆž½X€Vºi<„#ÑÅÒ8ù³‰·5òNéK#Û”îËÏNï‘r®[nXôf$AO"Ý–¸SVµ¼7ê^Y´]VsBe÷ ´g¬KI^¹A5Çr &&# zK½q*Ø" ¥¸ÅS äVOlMš­åV:ìH™/*go¾ |¿Û^B´÷£sä™Í/‚¬¨+“`‡™Dì žº,Âe…9:Cf!3M¯ˆNïxnÀ>9ë·ÞxCaSB$È7{Od¤Ôt †ðˆÍŠcÅø»,Y™B‹áºoÛâUûà¸Í —¢§²Â‡W½`¢ñ"•oû›‹¶»í‹èoœSªÛ>¢UÍAÃo+«îÅ —6/¿es^“Y ?±Py2C™‹ -ÆŒEöÏ´óŸ{.Ô&fÓAÄVUþDØ×™ +´ÂØ÷þÞŒ4à…÷r Å› ‚$Œ¾£Q`ƒ-`¬×ðÇŽMéˆüyÀœJØ ò`’…hQý)*¡ $ˆY +5Ëñò­Àóv3.]”T'‘™×_ìÎ"ÀT'8±ìƒJÕ2,ί„q;§oék9ãñÙ^¼è½þ#±ª‘l VgÈDÝ/tHõÿ¨ÀQ—Œï±<=fYM[=€7 µ¡éPŰ¯qdt³a³´Ÿ¸®‰ViÉ}Í~‰r¨È ºC`%ÐÔÖòü¤‘ ¨ä=ìíÈ€°ø‚x.«å_dÃñð,öͲ ôpù‚­NŸÛ®}§ˆTÎÒ¶iÒà_/á z¡±íRÒ*Ø Æ 3ýrI›½Z }z+§ðEU-8¬¿¢u6ìú xõ+ðsFúÐÎ3à"Áw}EýlMÚv…U=Iö1ä³Ò±çŠ:lú¡‰àâåŸm•ôònG&±O4 ŽÇ³rŽÏõ¬ß’Š@Î%R¿~W Ø)Ø×\„Ý=VÎáܨVbkcà6æŒ#°ÅóŽùI4MœÑb¸ï=pû{níÒË%ˆfcY¨¬×¿þécaöyqÌÝ1¯Æ ì—n7 +4?äÀYÜéV“yö2RS¨àÆ`{š,#JiHÂâ-ý»€ëbú@ùðsºÄÙÙÇ5NJ;Îið’s7?†™YJÂ’F4TïËý´äb„RêK,k"z’t&¼pwÛkßò1^šDFO²ÌÂ>1Ñk3V¾îÈNŽD{¶æDJ™¼oæà”1•±ææ¯\ÒeÖ/žôG};;’%Ú¨A{½Eì–6¿nn† ê¢Î,%*îp5¤=¾š£Íi +Yت^éιAÈ•Ë5í +Ñaµ+Ë“º±\‹0ïdÅ C´Ð²(Ó©Öצpy§’éÛ …oû x#z–ÓŽú­iÅ6„_´'Æõœ¦?óØ&¢6ºT&V@t½E ­B:3ç|¡7›Ãù)èq‘ y#釪sfWZâH«abzTÆcóY!ë>=ä€Ë„—ö†ÅŒÎF1-Ùòò}\Ò|3GŠXi +TpndØtº7ù)åç«sç/4ƒ8ôÃNE#.VØjÑ6sÇþ·Šª,o¿¢N(Þ-Ú›:ŽoLªḻ9ö8èš?&f¾>©¾*æËäIâ~‹zÅ}HôäX|]ˆ…–5Ö‰¤õö3›‰ø/(‰[ï ˜Vîb6ðÀ—ˆ¨ÔÆ¿<—ªîïáõÑc{R‡vº±£¹ôRåpõ«ý—T6xÍtd=úÈKgû% º`I)„ê6…xVdLñK±¯“þO{e§Ré÷ù+Poõ šZyßÝb*óë6§ï½$¬ôG u\>Ì~ó²=]ÞkÃOáGùÀâ¼’þ4SËÅuÖ¦Ç5´ŒšÈN›Q;|8x +ï‹i’6RNbl¨°› (¾/`Á%àÁ¶åæõ‹¹ÙpbO$s™Ø¶€ŒÑ¾ÖÛw@‘ÖD“Õ˜‚ÍN"­K  &.MæÊj©úŶžÔì¿(`\5ÛZ µ2kyD„ ¬Î[ï*¦à"þFp›aÿ Xf˜¸ÎTb»}-» ÎáÎB%½ 8ê  U‘6J‡(ê¢ØÀµ–…Fíªãʜ؂¯ÀX-ô£-Ýñø>‚q'«o"ty’ЄP.Hòöf;¦—囦 +èýJÇF@´ø¢umŒ¯Æ8|‚…$³(ßUH§k‹ÖÐÓà ÷¹eeÕmÖGJ•#𠜶k%ââ];$ÖJt ‡Ÿû?`ö„i¶Iq~?•°©Âá/üªÄÕÎk‰ÎX¬Êù˜³SÜÛ¶‚ÜHvòÅ¿¯ö—Slöèeî‹*bN¿ÿe¾¢\h¦µð®ŽRöã +oçë÷¤¸Ñ^u¯LÇåô¼ë‘¡—–‰È/º¸ïr£ìu_ +¹ÊGÜ.×÷ÂÌ?áw…_«DP×vÀÊîúðMEi‰Í;èÌjêL¾ÓÍç¸×l£ÖJáðœ4ݘ$í$©QøRdàdzFaÆ +±aưö¤ûÐq#Ê õ;–>u ßЂÑȲ¨ûÜ î(x­Ô>|»zsÇöMïÜÚ ¡<£²€*¬R¶nè«jt¤g6ö!;¢nÖDJ®Jí¯/i·2»K’HŽc1äÄ¢):ÙØ^Ãô¢šù…Íí>ŒôkÏ\@¡fË yñ6“é‘úGÔPÐ艋ª£5nôXþ8…ZvOç kŠV7ûüÒ6'wÊÅrÒVrô‘àÔóµOoü@ ”Ç}žìÃ3_k¥Wn~— q°ê€Â¡NmHN¢ö.U¿_¤dNß9h‰¼¤‹8 @Qpù7Y^©Æž7RØ‘{ǵºÒ´±Î—ÄA¦WM¹ ³xûû’×*îÞ¡Þxö\(ž§/2Ÿ@\ꩉãù>#ÞÐFÕ³« iøMŒ”™?E¥´bC3%ê5îæ{ÓeR„Z )o UE4´oÆ :[qt ˜O¹èðuÙÎJ’ÔàW-º¤–yÃ*¸Ü,ºq ï7ô/fÁC¬F¤œslÂïJc–R‰¬È3†›…ˆ¸î*\ª‘nu”Íooˆ[í)0"Ï„äÜòR‚zƒi"ÖbhÖ“ ÀI8ŠeC’µ¦ ½`ò6¬¬ÙÈØ—Éýüv¼ÏvB¡¹†5ÃÌé—|5˜,óë··'{Ÿ$ÿ0Ø vYR~=2·NDá…Ü… ´²ðAC£´ïK‰ t¾ú¤ÅÊ´Uäfsä)_©ËŸ÷º1Ó—ÃU»»bî¯41Ê„ kÄßF(Ä +AQé}lß§‚>œ'Øoy=Û“õÀ!»šp£v SO`MÚ +ÂEdqðÏVŽ<[^/à•‚³mQB(ÉJ4åïPÓ%›ù5`¦—¼<áN]´ÍrªuÓD…8#¯U…ÑxšŒŸžþØë$@Ñrˆ ¥åpT_ç6þ3$$mýñmmòk ŠÊƒ!7gN?¥÷Ó +4“R¥VU»4¦^¡ËþõúB–üLJ#£·nγsl€tŸh‹P¢ÀB¯B¡1ÔÏ’‡’ÀmA8onTƒ¯üàŸœŸ™@©5Ý£ m>è|Ìãé$Œè8L¢äë×RõC™u´„î0a\*;­A° 0‰ì…ÀÏ?'ê=¤†CcÕ×ÇógEw{ñ§X<¬Ö«Î§¢¯‘Ö/¬+±]éÐf¾ë{Î"²Â.`W_‡—ú¸R2´  ¬ ÑßèûnȨ÷„W:È%¯Qý#?‡uÓÌá†8p¶ÄÖKê"“`t@ º^õÛ“TºXÔ+©eÝy,NÄ™‰âJcì³¾ýóiówh²i©1K½à#<í‹6uƵ(E +¬Ç¿Ñ¦‚¤E(#ÍËŽâ~qõ¥]ïãDí +zúÎ}™‹KŠcw|¤ªïhu•ëôSˆÆ¡ÐãË­„[ö:Ò-DqnFå†üô’êP>Âz^ʧÁÒÀ”¬Ì»›~–[T¸4عâXïîif%ŽE„óN˜¸þÒ:Í“dõ¡#d©ðº+†ðŠÊoFš{ÈY_5¡»$ž…Sr25Õ¼îà>Ó ë°+a“^r8Æz5³w ³„­JÚ%uàÏŠŒ²¥oŸP,ã¦8(+{(š\‚J)æ}kŒné?op¡Œ®_@U<º°4Êßo‰ÔYÞ<ìaÁ ŸMˆ§õcDÏSÆ)ÃêNiñZMEèG5­:—ÜüÂ.Ì{á¥Åu[R½Q0È›®iÔú#ÅU·@„ñ`lˆ-gb”Ŭ\ÏŽXIP'°(Gý³»`š˜º„€B@BÖ&íOrÒKn°Éއ{ûgÕ.V­„Ó á™ÔëuVO¹©’›¦ic{b¨þÈí‹5D«Í÷‘(L˜žkVADõ½mÕTŸÃb|kÊ"¯=^sfÉ̇ ø.Íþ¦úzƒ D?¼fd¥òCRØÇ”½²c+‡ò¼}ÌÉ? ޲69>jí™e›W"àùï +.^7=º6Š2#0 Ÿ“8uGzƒ)?&¯~Ó&Î^ma€ÐÎÝØ”ÉUk‚Ï]ûl ’4Já–‘—ªÖã¾ß‚•苈zN“Uæ§z¡Ø„ðcÃÀ4¼âeºsÂiŽ˜›ÈÈu"ÂXÐ MòÂàwB²Iê­Ã>¬qø´d†É¼•§Ç. m"£ûˆëDÊ!‘‰oRêS´½)™FÚêaÜ.¹½<ÙBý 2ƶðÞ+ôBƒÐ­¡+-Õ›3ãò¡5ŠÚR" :zïEñ>©-Óæ° Îg‰lL8y$º›³Þ%µÙJÏX9?ænµ‡äFóà–®Œæ4GÕ'‡“ç@µ-–ýp5i~Ìoãø†Ž…·r–½Ý¢_« +)׆þ®ì¸}Ÿð‘„¨ÍŽà”ÿâMµ3ëîDþþF·X#›Vx„¥Šš9—ÅÁ¨¢S@§¾Õ§+Öf.;™•óÛtÆçÕÍ&…¸eýÁˆQ³ý Qi†•hOr{jY%ÙJw¯ÂT„—lFt{¸ö81÷(Â¥…ô¶äÃÊòûb2ÒJ8cá”ˈÒbÁÀm¼J&­Z‚A +Õ!R3|´î|ܽ$uà×­GY‚œ æ{Âx¡  ~.œú&[qæfôð†hZ³O D_‰Ã`z™7ÊMìòMA•WsÕ [ž„væsÅÜ!ƒØ^ZÉ»‘wïFÞVeGò‚\l¹ÑS\Ÿeæ"þÌDnÚ‘15Nôz{ƒ¸Yów0[° ukz?¡Þì%¥ +Ü0†Ç/OLj[É|Z«×Ûž<Òí°4ûº ·Dɇvk5A´oã ÌtAÔ” +çHBžO+Ú‚ÄîóÎ"«g,Ç}õS?3Ù³”“´§+Ôö·V¥+ÂÜÖ/'Ên³÷^ö/€Õ…Óÿ곕µ°€ùÙ?"0ÁAÉÃ\(à-ŸÍ¹À/¾7mù±y}ýÔm“ýmùkìµ4#±$ß” +¢0ÓžœÇ‹·z´RÒCfwMÎ-‡Ý ’օʹºwvE:…n6OAÆR . ½Ã Kæÿ>©´‹™Ü¾hiÓn#Ç*ëÈÎ^ª ‹{n„œƒ|Q‹évÝ 5¼ã›ènB uv%ò9{d|ÞQP>CöŽŠß$qˆÒÊšÙ8”Ç­š¥«­u#Õ¸)«Û×¼¡ëSœiQ¡zJõÏA*tµÓ¦¤§ 3;Ûtès-|b~0~B-Z)ñBšª©*·?ƒæ–+[L’0o!ìÆ»UÕ‹B"Œ¾ªÏ5jdÝi·©dVéc]Ð[æa÷Ú(i³ ¿=ב;†L íu߆+YÙÔ¯jÒðoAs-á÷!Þ;ýÈž8íöêš«Î~à 0 À„ +Œè†²}­°[^­ÄÊ"+4´Ÿê°»Ç[èë+SˆR·sQª‰’ŠYHX¿™ïC6ñé|W$­µÈ¹ê1±£×Kì¸ËG4ÄÓ:£å9d8—f‘%¬-Uo—@~<Í‚¿<ÀÂ/OY„рƈŸ²7 9ÿFL!Ë·$À#Í‘»%#“ÂÏ®À!¼d^ûÉßì#r8ç7Ôs¹ùáÃ@óî¤D((§vL¼ñgà³wKKf8Õ–u±M„ ,GìÀ±„#†áÎ7n $\*Âä2Þ Ví/@3*Û¯¦"üÔHÏ Ä»Tm’k7ìècƒÀ¶oÝ…æpxVåÓ{'ŸÀVÏQ@Lv¥ày«§ ç-{†Õ#c¾Ùy·Gö=…lL˜ÀL[×nЩ2oY4êðÌûÖË•÷>BX^M4UÓvŒ„l0gz +ó½ýÙ ÍËF£jkN°3½WäfÜÁ)8+í':º/¨%²+žG%$Åw·í=¾tÀÜ~ÆéÁúäi*¨ÐuÙ>lû2{†X’GVM"¹ï§¿äØÞóŠ-I¦./q*#Ú-ÍÌûS­n®Þ~¿5f58O&Ó=ƒSµ@·ŒVÓÃܧçOPkÓÿ hÙ)&ÒªîÏWfzv,Þ6ì,Ïp¸êÉã7­ ‡ixÔÆ­SÆ;Øc¹}¤ÛUŸV¼ðœxç.»wQ~ßÓJ3CÙNcYB»Ñƒ¤3Æ›õ?­ÔæuÅXŽÝʇÌ®þÈ}‹b×"¼ô)ÿÆ;Ñ€¤ˆÍ +Ú‚+m.'ª®ãæáLVò ÊacL-À³…KË+@±ù~àI mªÎw3$‰/pKx÷ÛNìv þB ͽ2ÛÏA‹É]`Kmâd¹êuW‡¶oŠ\ˆ©/QÙî„„!'Ìqzî¿æÞ`rŒjéÒÍd‹ß”¥ +¹•úÑÅ0v ñ>R0Þ{W8ý34®H‘ó£îH±±­ +—0oj+tóH*ßj<šÊ¡ÁYzdÍ¿f1hJãg<+ïa??Â…VMQ·IŠ´Ö`ÁÖK)²jâ‚·8óK×… +t‚i]ÕܹQ7•¬¶">ø'2cq’ÅuE}sÀ£e9L&„MrÐ`yOCÀ´ó'{›HPO˜ÒoÅø8ì»n·Šš¹Î1è˜(]zš¦ÊÜ÷ŒDÈQ–Í’>¸iŒYñvÃ×LT%ù+0&—¢1BµUkæÞê«–Ì«l +¶Û2g§yö$®ö*Îæøe"'WèÖ£“C N1.-ÖsÛòQí5rJ÷ÛYAQ&¢V1R7Œ¾'NI,Ÿ*˜å~Ƶ”›~÷Úrò9!ˆcV†aCPµO;;PÝÌå³(t>ƒ ¯ì~0Óâ&ý¥tdW)T?&ÔzISÆ—µ Ñéô9óóŒl|—T¶·ô¤+NÓÄn“4üÑ«#éÜ‘ñÑÄüÁÉ֕aã_.›+A¯@™øêSÈ3•'üp‡IøÐÌySzùO ‡´æìÍ®¼Ck;ë2O3Ô‰áy/sT²—»ŸŸhŸúĈäomg…Zˆ­‰fº9ðþÒnjĹ.&i&ß7AŸÀ’\aö(±V­J¸ãnÔœm> ØŸ) þêy…ñålkMO¸éX8VEdàŸs][» NÆoñ3F_ 4å`}†v,ïˆnd ‚ì’ØªLÚB+;1‹h²QÀú·î´¢f)²kß8OÒ# õ:‰ɰ*NøG0Úðž{Ï·¸Gâ3]ÒB]ÝãŸeõÊUút–Zä¡ÛQ*He'3u}š&ºaVÙ0nÂ_å · Ø5Jæ³§Þ;R~&ôc5Æ¥:3…/ïì&Ó¢.AðáÁÎÆ¸ÃÄžR¿nÈ€¦ã~E2Kâèš”¾³klÌM"÷mkòù¶Bˆ)™öøï¿¿ÓIF{/õð·לuù[Š“‹ÜhV¥<õ!1QÏG)9ì(Å¥ ÒtM ËëqÌõþ¸]%tƒP]¦ûtàÆ&Ks:!lg‡€†)®7ì,èøÔ:Åaäæá·ãäQùÔò=•ÃýnÙ,×À­¼kZ^IºgàÁô.uQ³÷ },Œz“¸»•dA@{â^@±ÝƒžÅ&ýþ°Æ¹rVL*ç‹jïRf§ž¦|ú¦ØhwFjPÜ{tnã𠞸Â1LM‰ðg6þ>¬€ä¨è!³ßO’N·3PsÞvz¤' W›Bb×÷d•ª;ì;Ъ"j7Ž”‹98ô©å,³ÑÕ4ÛÕ-뀌éÂçË+[ã®fΠ´=5"ëO_Z§ÝQýJå÷# ;~Æ×:¦ùOuP2Ãþû9¿™Úã†ß°q¸D’!ˆñÛü"Np G“ó TI¹Düˆmu áê°q¤boówH/Xâ¼¹vbh™‚79}Øži• 0!5mù'p¸ªŒÍ-ÖЗXéçQdrîá•fè÷ëåÞ1ŸdŞΣã…ê(?ÞOCüUd;â±ñ.&- ÆÍ á©UÃ&ÄlÈQ¶œFWü ÊîG˜ç;!:XV†à Ž«¦g.šÆÌ" ƒâÝ`”Âp¼](G¦•|ªf?„ËÄŒjݬ~h2w|¶A™¿îÇ숚ˆ‘u #S0g0XÌŠo æ< ~°fC1å¹TËI€I¯v8ì{0®BôÂPœŽì>@;QÐÃ'‡³ †êÉ2$¢b(ŸÜ~¦r Ž}žjÈê 6G\æ«ëVáÃðšOD©h#Œir ~7úsaóÊÀ?Ô³©§²ÆÍ9Õܯ» +%*RŠ 8$ ²Bí¦®ä[D¥ªÝ«ÔGÆ;üÑh<®^‰¨´ÑE—@$|ûÈ89O\2¾ãw3ÆRæò…iŠR)ÇäN(˜$ âBd ±ÈÔ: ¤cCœšÒÅãE…É<¬)2@5ø.½’ë"¼ë'óMÂÛçœÌ„8 +БQöw>}N·>¢Z[@ß HÀ—ÞäN—÷“$wŽp»X0õ•ă<±´Áí¼sÎ*`<Ñú¶øAF‹/©=J^®üݯ‰TÿýŠCX k¯”¢vÈ´ªøƒßnÔ«Ó¨ ÉŽ:ÁCò®E~$œ-b™¶ëþto©ýB5÷ªF¶¬ïϾ¦´]çnÿ¾ãçz£û-&úiý½®€Q“²sxGûÑû¦I`¾|R$I‘õ\‹àX.áçëÑMdù ØGË7DÐÁ`lÈÒák‡)*¢mÁˆŠ‰£ä¾цëmhQ8ð™’¦;¦eP‰Ñ£EçòÎïZ¶úAI +¦£Ò턳`à*ùê™>÷)›td¾ñlË•]“î×=í +9l¿»YªjËŠÍa™°Tt÷W.™”Õ>/žú„ VݪdspÏ#¸îú§+^üƺ§h¥ÔS-b©\LÔåg› llª¦¢,#Un¥`ÙD2ïÑw^´îWƒ…jžÚòHƒ,ߣ4i´Ø$ƒšš4œ¤c„\œÐ9˜n³žK=F™•S'a&È6cS4 EV×#ž°Nšy’ QN¦]ˆ‚{4)gáŠÈZó±ñëÛ¢¸$¶§”tÖ©ç< K·fÐ2o„mê„‘iª:Ï”)Ðö¬ ×ø,m/@=ÉFËi‚tÖ²$Q."]å+&•²jjÄD™Þ}Û­n38e(Ö²õ²·™s,ÒõáÙĽëÃîñ¦Öà#” +, kÉ÷´éhÏ·.rLgâ×hž„—pZ??ÎË;@·aQÞ¦fÍ‘Á£˜ÁüÒ,_g+õÇDê–[ÖË`lƒÿmjC“½ µ‰¹ñ•«ßyÁÙUe°M ©P21=ÑAC6R²ãxÖ¢Ó»ÌiI˜µnþ¡twÙW|$Ø©Ýv;Œ4âcƒäy.,üôFÖm@Ë1›ÚÜÒS½V%¥ òN)®#ò÷~H}ç†/œ¶CDÞË>K†·Õ04 y\·ç¤Í¨ƒÎ¬VD©?qúÉ´K¿¸!˜Ù6t’m3ã˜B. +ÂJY†Z†ûš|ý4-¼©‡ôÄÖ/äNø&vL‰¸y)û÷oæéÆ¡s¨Fâ²JJ–à!`²K-TîÍ$\ \8fÇ®Ÿ™ºˆ¤]z‹9L9‘Ïÿö4ÆðÞ/Tþ&š¥ëÕŽÛîäHŒ7ýø1ô°’ë{ÇnŽrbÍ¤à„©7ëã!ÀÎ|#^ìñ›C§.Öçì1Ê"‰ >B÷‹=^Õäìb—bu/ÙÒXÄ‚™Oå§kY‚O)™:&Bç|i¿ôÚ¸rŽ:7q.8VJG±Ú–= +¼œggÍMÛR9éà½Ù»T¿Ø6žft»@ã.‡±v¸g8ËÃ7ÖÇËñˆùƒs‡@JE¢ ÌL‡²¾ì§£é-ø?ÝÉ8݇uÊ I·ï*"3 Ò÷ËVA¬¢Õ- ¡Z"ÞÆmU{/)tŽÎ›ð?KŸä~_†ÜÙš Ö¶lâ’¡n˲aþq+—ôú¨¤ë1æo/+žQTËq&ÕHdn„Ô¾u ˜Ñ­-ëMåÇ‘sÿÉÅ™[tœ¼¨øµŸÀÄíÞ®ßPx|òúËüá‘æ/¨-epsƒÛ;ʽQÊeŽÍYszgÏLf²Ê%—â +‡3¾•þ4¡´°Ç4s©Ó(œ#qp6ß ïȈLÞè¹xÌ9ÿ*Ͻ-+\NÆ"ìÊלý 4±ëè“B»5ýû/VQO‰Aüp ÈÄ@ˆtö·­ã*EÕV0µ¬7Vn¸¨bÍ[u?¹CöuJ4,Òk|_Ë­|Ïë2•`k”äÅhÅEdÔ<üÉgÁÛ{Ôrä5ø‹›o{Ÿ¬cy¯£ÓJ¥Ò/âðÉÞ28Ê8®9!úzÕP“¤¨x÷6`1©ÖÝ`¯îOzó€Xú8jvƒXq¢™°£»kÌí²¶¡‰2D¾ß•‰”uaôBAwõúà ‰¿ +€ÞŸ|æ`xFÎärãiwÍBÄt·Ñ9”kE‡-ñL¡•´]^`ƒ|ðv?B@ÕÚ,eç¼oì.9‚¿‡ú‚8ÛƒïûÝ +2h°Ø‹­ˆÓçBJ6 rD÷ öy@hÓ©A˜orÉbo»­]hdçb;é^ûxw^c»{$¯öw÷ª(:©]Bæ?0B¨Zt=qsŽ»_ý¾$UÎö×ÐíT! vMIöM»ªéKk¦øy"Óî“hŸQ¨¿tHg½Å#v³ Ë¢¹(^Ë×"F¸Cáß Úï~µÍO[ŸåÇ•ÖZ²Æ~!íg‚dö¯hÙ¿¿«ðÉ×_j¼ºÞÑñ¯EAåƒß€MŽ›_ô?¸M¼½Ñ¹t~ŒÜ+ì SVáu¤T…r©¡l®¥Uƒ0P;Þ‡™OØ~uLáÑwöÞ5gL›É+Êj/1ˆwv_›Æª¥µ[þ±žœh…{eóåa"ë‡u ™rÔc§®–ã¶­=üdxí†ã%û¡AUì÷È+×¼ Ô4ÞΔEÞ°•ÏØ„ç“ø¡´ûèâPz?¢†Ú mê"ìvbîdU‘Ö¾”ñzñj3¹¢¸j&ÁÄ~¶§‹»‘LͱZ +É5w½‚'☺²¡tg‚ÉGѺÐäQ`Æ9vÉlpúÿÖ§ÿ¢^ʆÁ.¸7%Ò` ã±¬Fœ}a<õŽÞµªž2Ȇ´h¶”RÒ`k‰ÉÓUúÞê¤/˜÷¢ú¹«É«¿ð\”)$q‘1)Ûÿ~3w¿,ᶉ:—ŠùÒ¬®ÊÊ€W6 Ù ƒé‡~ÕiЩ`’××»žÉ v ˜rGK/ÊBˆTJRÌZ[¡}ÙAöˆóÛ¡Ýå熫"ø`™Þ[þö‘±U1²ѵÀÈyþ¸ëhBØ…ÏÃÌQ)¼é‰e‹@Ÿª"´±³ÿ2ŸJÙÒe5> 9UV„ jTÔ׳4ašG}„Çá§œ5ÅHgQz>ÜØÕ"oÍ£i:,®Zƒ…[ªŸo[¿¢!cÝÛ)èu3oÁÜKÄÏ6W Þ¯"Ó  ”ÚðUAtE© ¿#Ibz£±'»PæÜä + !˜s¥8cs;ªÄj­ÌÜfºô#·Ãÿg:‘s2$Œ©ˆ×6'?^1„4=Wk¯^éßÈsê&Ù¸e;ìðìÐégªA¬½Ù¢vXþ]ïz¿Y¬ÍrôÞ= + Þ?”XÉÙTVà†Q¢›‚3=A(ÊŒ®?Ît??xnkà1›Ô›ÔÚ äŸA`ã×0滬²tôŠ¡Œ»*!ÂFë¾ÈÕÁ(»L lô-eFf×Å +§,Éù¾Nª„8’sޱ©U WSi—³¶,keõ%ï"‚×cQ:Á`c„†3p› Ò£ïט vv„_Y†)„A(@n`'7)$P²tJíòkÓp? ¨OÝï°¸>ózäö o"DXÓº3Êlª‘ûÁ†êÙKß±6ÎÀš9ŒÌ9‘ 寧«Ÿ#Áâw©üljœ]rlXÀfñêjéÙÖ ˆ¹œqwLLCÖŽ¯ËAŒÍƒ•è­0|¦·Ý¢fZ/Ç +qH {ÃŽÆ¡I<Ü“QvÏÍ ‚TD†¶ßûu|s˜ÙöoÜœ¼ •ÁáÊË—1™­.·óüe|î÷œzzEÝ³Ý U1d•1°Æ½™Ä<‚Ǩ‹Ç/œapbÑþ?íÌ÷?à3ÎÙdds_ël_ûÎÞ;33gwÈæì’³ÇÙ„ì2Î(ópvÄÙ+ +eËè2R¼ÄûÛûyŸ?à ·Cžtж‰ä€¢rªØt°W¨ÂÃ^Ã>\\hŠþ…¸­£éÝ ÓùÞ©e‚ & +ŒÙí?ÄSËÜ·7 ¦Mwv½ r#aCp ÑÁ¤»Ê«Z²â™×?åYó›j‚foM¤Ž¾ïhWò÷%Ñq.4ƒ5ÍÞóŒ®:žªFï€uI|Òxóstóår}¤‘(º…íOëËD›ïö0C³Xò™Ï­mtý#¿#/OÙÉU5ƒ|¦ðžË%åOŸ8+‡!ðÕÈïÆÄ»Þpi¯ÏÊ*ÓK(’èÛ¾½ÙR„n9 ½i3Í“~i/]L‰ÙA•+®ƒ¬-ãÐúˆ¿”X£Ôëë"M3µ°hónf;ñˆYþÒ$qW½ÒG_¹jcR2š×»‹7¨Š}r ¼áègJ?%Lë9bBú<–ŽÌ&f·´È’Mµ½>ºç|lÙQs- +Ï7û1'»öoσAü¬¸²a«Í¡K-é¢äþ{." xÊDï ùÐæI~˹G=Ö±?‚§>Èyüñ°“NÐ%îIß×µ¿è4É^)Oïä¥ç¾®ÁÉ’F°³¥1ŽžzÓ€SÚóJîi¸g_ ~`ñ›1E!ûޱÖ]Óhcotí¿AàçUpö„ß*&"-š{~gò&ú{ …rO]ÉOœ…È”[‰„î£-•;J×VAЊü$JJX&Ê×"é 5 +¼ØñÆV¼_±  ’™c€AÆ +€~g´¦™L#ZeöܬðrFVU +¨ì¿öžÓpÇ£†äH¶Õ2Señϵt(å¶õOÖt†Ò[ \„¢73}ñƒça-ø{û9…Ô8‚Ãõa8K<ªä-™£UÍZˆjzìɲ¦Omuã–‹ +|BÖÝB|kæZÄ@ºÛt7B5úÿü¥/Òµ׃1šòò‚Æû±®¸—ÜQZÖ¿S^©Àþz?§â7*¬UÌ‘Ž´Á9a¸|ø2DyúQZg‰?D[á4m|‚B–*õ¹÷kîìDRºÚ0„¾ýç–É­wó~ýØÒPÇü>? +»ë~÷aœ¿nïOÝp}ê#Æ)f’’¦„?BË`„ú ~R(hà'Ùç¾óì ØÉ»žOÛšù.»ûe<™“1êÌÇÒïÒÂfÔÕóÏ“¤òÞ!°(íTLÈÃÖ¥råúDÌ|–ÐÅ8Gä|}¥|è+ÏTPDpƒˆíJN5ª,»sa}èàÝ!/ÿhEî:±‰–ÂÖuL¥èmzÍŒÈ%áØß+pJ^‚…®Ù†V§óÕ7ƒ° 3¡‘ áâ9zU¯Ì…‰ò;é–Ÿ·(Nâ°­|&=×ÝÉEr4GîÇ4ê˽/Vñùén :,'劘ʕc(x^µ@$ÛL‰†¸æVìP¤ýÄJÍÏD{¤>pV$QJ¬©ô=˜Ð9 Úp€Õâ«ùD¤å0ù_‡b>éRêVtÃÖ ÄMd~„Ýl{‚òsÉÞ! 5õµPÓÎ!ÓêÕ±·ÍˆoÅï$ø4÷µ£e!Ó†R©û,ÞΦbކlŠ\›»ÆÈì\Ùú$Rk=›‹Tö° +Úð­,6äX€qÐ-}nJ®k^¨£ô@l€¼ÜI>Œ˜×TqÅOшتxín°úâ…õµ4JÌäÅV kw¨Š‘þI’€¥¤\°^0Vò˘íep«%"h* ê mQôB±Ýë“ÙÏXšEÿ¶Éµú0üöA•ÚªÏPbÑËöê6EL7‹:Æ6ÒpÑÁå»ý%Tñ4w bBY6Kn8¢slG›‡œ .ôˆdŸ*‹îí¡ï8‚ìu)+¸"xJmKM Û /û’oË3ÌkŒÐ‘ÜãƒÛ’ÍËïÌk‡;/°¿‚ë’àU¿n¦NÔí]…6sÍ£¹ÛÉi<9s„pÓ4ìЛ•E÷³¡{¨Î¸›Ñ(@£ìª–8¥C©·g{foU>Ñ™vù¨µ«IÈÜÞPœU›K)ʶZQýmk ·çƒe~cs3˨Œ°2è£ßÕ ¾ÄùNs´Añ,ù¡H¾…¼ÀÅt••å;: +œ•F“þ/Eň¢M—íîÒX =r‡K—+hö¦­y¢–éx>39+¥¸®¯k"½…Çl÷ÀJí„MÚÜ8ÁYËÜ&F¶”´Ñnýó'¶±_t¯…´²ÅÕÛ¥ ¼”žŸö8Gojü=ã6ÀçÞ}IP†C?äy¹l÷×MÜ 8ºSJ§Y´%$<-ãw¼S9ðJU&t ŽÞ[™#ÅÀ½5‘µc§O&QNðoMÂM/ …Ìþæ2¼`ÕE”n¼]QàѨPØÅA9TM;x¸á•3O‰­X»ãÞä»ÎúF_s„"oêoì9‘ö-Z%×/ÌÓÀ¨LÒ¬ŽÇçDrU‡¿ ¶Ï­š6ÞxÓÂï¯Å÷†½®w~¿Î~ÁX0nïýe´Ý&¤„’Wm»Š)Ôšë2ÒÄ`ÇŸ­B¢ž}dMÞ xì)㟂ñU‘dIÂçÍ Ê>`O‹5ö7ÕKõ 5ñŽ£ÓÔ‹Á}äIZ-™óDZ´[ŠkA,è3úI—ãq­«E2·:±AÚJÇ‚p9lrEèp¢V —2JÙçï£)m×·ÇѾ&\!H !Wuy§|õ ¸ýkI±3ÓËôì ünŠÐе¼J§UÇ‘º;Ë÷Û\»#QÆ>‰E¼ßå îÜôÕ7;w“«)½VM.òHfÜ7$fÒzVÒþ ®:ëÍ©Û"Ä%yF#u»¶b1:î£Î¦Ð¦ºwI§âtß±.bïö:Áô|š·!/ä‘×…lEŒ];\PâéƒÀJ-†ùfï\gX?ÚÝbÊâ¼q#°È™JZcvr›”)\MUŠÿ½žØ«R#óÞ*{OÙ¥òó£SØÊ3«uS¥Ò+¦Ë?:ô$±ó4£º‹Õ±™o °Î³d q‰ÿ|¡âWV¬I¾ßxo¦Ì=ˆ4Šž%,²——Tí–]x-«GU}¡:¼@šëäãÕô´:+VfÀiIÆx†‡Ë2Ë–„\ü_¢øð?¸ùº»Áý\}(þ=.ß%endstream endobj -935 0 obj << +940 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2122 0 R +/Encoding 2143 0 R /FirstChar 33 /LastChar 125 -/Widths 2132 0 R -/BaseFont /MYZKVY+NimbusMonL-Regu -/FontDescriptor 933 0 R +/Widths 2154 0 R +/BaseFont /RMTOSX+NimbusMonL-Regu +/FontDescriptor 938 0 R >> endobj -933 0 obj << +938 0 obj << /Ascent 625 /CapHeight 557 /Descent -147 -/FontName /MYZKVY+NimbusMonL-Regu +/FontName /RMTOSX+NimbusMonL-Regu /ItalicAngle 0 /StemV 41 /XHeight 426 /FontBBox [-12 -237 650 811] /Flags 4 /CharSet (/exclam/quotedbl/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright) -/FontFile 934 0 R +/FontFile 939 0 R >> endobj -2132 0 obj +2154 0 obj [600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] endobj -894 0 obj << +899 0 obj << /Length1 1620 /Length2 20127 /Length3 532 @@ -10194,7 +10340,7 @@ endobj /Filter /FlateDecode >> stream -xÚ¬ºct¤]·.Ûv*I§cul'[£b§bÛ¶mÛ¶­Ží¤cwý¼ï·÷>cŸóëœý£jÜk^s^×Zë5FQ’)ª0›Ø%ìlA ,ŒÌ<5e ECkkC ;Y)¡5௙’RÔh²°³3y@€Ðð퀅›› jgïîhafPÿå ¡££ÿ/Ë?.#÷ÿ@þF:Y˜Ù¾þ}pZÛÙÛmA)þ¯U€@È0µ°Dµ¤ä%Ô’òjI -ÐñoŠÎFÖÆY c ­`jç°þ÷`lgkbñOkNŒ¹„†'{ ±Åß0 ›1Ðþˆ`t´±prúû °p˜9Ú‚þÎd°°5¶v6ù§€¿vS»dïh÷×Ãæ/ö—LÑÎ ädìhaüͪ(&ñï:A憠r;Yü…v¦=MìŒÿié_Ø_š¿(ÈÐÂÖ ºþÉe˜X8Ù[ºÿÍý—ÌÞÑâ_e8;YØšýWôG ™¡£‰5ÐÉé/Í_î¦ó_}þ—î íí­Ýÿm÷/¯ÿ¬Áä´6eD`ùö7§1èon3 [¦¶Š”­©€…ùßvgûÿÀ\€Žÿõ?{†æo†&v¶Öî )“¼èoJõÿÊŒÿs"ÿHü?"ðÿˆ¼ÿoâþwþ—Cüÿzžÿ;µ„³µµ¼¡ ð_A€ÿ¸c²€. ãÿÍÝÐÆÂÚýÿðß=5€ÿ®RhælmèøßáÓ ÛšýU„›‘ýßV ' 7 ‰¢ÈØ`jhýwVÿ²«Ùš­-l5ý×8 ,ÌÌÿ S5·0¶²ýgøìÿ†€¶&ÿ½ü¿2ý«x&q5 UUIºÿý^ý—Ÿâ_ýAªîö@ÀÿŸDCÎÎä?ÿ°ˆˆØ¹<X8™ ¬ÌìÝ߃ÇÍÆâýÈø/"–ÿZË‚-ÜÚÌŒÌÌ,€¿ßÿñù¯•5¶3ùgǨ€ mMþn²ÿ4ü;;:þÕö_çþoÓÿ±þ×vÝ€Æë+vƼA–i™é :ÜÜ‘)1í>È‘`ûÒFÕ¢¿»^ß´°]îJƒÚ`ƦžßíîËçöŸ‡Ò´Gc}8ÖT½)Àë|"o +xÚ¬ºct¤]·.Ûv*I§cul'[£b§bÛ¶mÛ¶­Ží¤cwý¼ï·÷>cŸóëœý£jÜk^s^×Zë5FQ’)ª0›Ø%ìlA ,ŒÌ<5e ECkkC ;Y)¡5௙’RÔh²°³3y@€Ðð퀅›› jgïîhafPÿå ¡££ÿ/Ë?.#÷ÿ@þF:Y˜Ù¾þ}pZÛÙÛmA)þ¯U€@È0µ°Dµ¤ä%Ô’òjI -ÐñoŠÎFÖÆY c ­`jç°þ÷`lgkbñOkNŒ¹„†'{ ±Åß0 ›1Ðþˆ`t´±prúû °p˜9Ú‚þÎd°°5¶v6ù§€¿vS»dïh÷×Ãæ/ö—LÑÎ ädìhaüͪ(&ñï:A憠r;Yü…v¦=MìŒÿié_Ø_š¿(ÈÐÂÖ ºþÉe˜X8Ù[ºÿÍý—ÌÞÑâ_e8;YØšýWôG ™¡£‰5ÐÉé/Í_î¦ó_}þ—î íí­Ýÿm÷/¯ÿ¬Áä´6eD`ùö7§1èon3 [¦¶Š”­©€…ùßvgûÿÀ\€Žÿõ?{†æo†&v¶Öî )“¼èoJõÿÊŒÿs"ÿHü?"ðÿˆ¼ÿoâþwþ—Cüÿzžÿ;µ„³µµ¼¡ ð_A€ÿ¸c²€. ãÿÍÝÐÆÂÚýÿðß=5€ÿ®RhælmèøßáÓ ÛšýU„›‘ýßV ' 7 ‰¢ÈØ`jhýwVÿ²«Ùš­-l5ý×8 ,ÌÌÿ S5·0¶²ýgøìÿ†€¶&ÿ½ü¿2ý«x& UM%eºÿý^ý—Ÿâ_ýAªîö@ÀÿŸDCÎÎä?ÿ°ˆˆØ¹<X8™ ¬ÌìÝ߃ÇÍÆâýÈø/"–ÿZË‚-ÜÚÌŒÌÌ,€¿ßÿñù¯•5¶3ùgǨ€ mMþn²ÿ4ü;;:þÕö_çþoÓÿ±þ×vÝ€Æë+vƼA–i™é :ÜÜ‘)1í>È‘`ûÒFÕ¢¿»^ß´°]îJƒÚ`ƦžßíîËçöŸ‡Ò´Gc}8ÖT½)Àë|"o šþô­¯œtGLz¥ÈéQž7K²;P?8˜Õö¦””õJ>`ˆg:Yánžiü(\ ü°¾<Ù£ø§6Äbw¡5aÔž_|M<}~¢î½…î?$¤Ë‰…§äuBþéçC(øC­B¼ªùÕi{Ju ¡glŸÏÏìC(»ƒ¢ÈbÓËZÁçjð§fÌÁpC@¶VBjä+s^"ò“£œŸpÖj×Ñm¡HNZ¬¹Šù—;Ão{ô«OŠ—©š}¾ŽÈïqM gÀÁõ@‰Î @@ -10268,35 +10414,35 @@ K p÷†ÓºùáXk)iÇÝKqkùÈüÙ²ú´{Ô°!¢1µçsßÚ3‘à æý“B òÐ2t¦£ƒ% ]–Aþu²"ÉÜß2åº.Ó “ñx•s,õ)®k¾óÒ>hœýbyZÃ÷-ý$ËbÇ;¨´²* #Œ6^ÿ´Œ‹Ä*jj¾}5™üÊ­tÿg ›­ûá=)ìGõ™;RVÛÚ½wV*îM\ˆšhßn`ÇPÙºzÇ'I~©VŽ;&븙i—w âc3:™S‹åa¥40ÏZ: Moè¥Ø~ƒÐ#YcÑV„³IF^¸Övú¾&ÕÍBoªzôåÒ½¢šºˆ<è@Õ Ž!ÄVo£Cé·³s~íAãŸ)4°jsY™ÖÑÁ¤¤ÒøÉ‰ cxg4Hc=‰‚­|(—æ3§‘»Ñô¯ðÑqr1¥~tÓ™²süçŸVý;Ë}I†õ„=*š½Â!³ ®8¸²ù ¢Ÿ{J½ÅhJ$‘¹Í2ÕtKcÇZ=P¶)»ûøÔÂwË,û«øƒˆcÌm#ãdxÐu!^ Ú9ûi7ŸÙJcÔŒ]+µ jÆ»Ò_€[hI£YÉì0…òÇ*껪¦úݳj€í¨ž¨ß`Ù?8sGx9g3ÎîèñÙt÷:n:—SúluHx‹œ›ÍÉPo·«ÃJAüÕh€ß¾ÅW'ˆÃô´B ¶q…¡Jˆ`“ý kaæ®´bg>–MO”¶æB8uk—ÄþÙ7)Çê®Ü¿5GVQ(ë¿P­m-FG*åTA¸¡WK2z)· Ž×?3Ì›QOl s¹xŽ5WË–§zGϺß?ÁyËÇDóÛ8Þ6<,óyÊœ³%ɾŠaîjôër¤ôç ³L.¸!åeÖ&A—¯y!qíµ¸`Û®8 &ƒûCá°ˆ×P·KÄMZQƒñˆR“!»V¸x3ËßÀÃ'£l{…x|#”ÄÒ,ò9r&tã|¼ a¥ïéæ3sawÄø² Ã××ÿuåÝ™×Ãùv¦&R®É;Ƴo©5$rÇâ¯%ì»iÕav·4Ë EìØÔ;E6'µ…¹ïh;ž7\oqkÙñ*¯u¾+ÍNcýàÿOÃõÿû‚ÿ -¹ƒ%ÔÕÝÙêjýákáüendstream +¹ƒ%ÔÕÝÙêjýM>â endstream endobj -895 0 obj << +900 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2122 0 R +/Encoding 2143 0 R /FirstChar 2 /LastChar 151 -/Widths 2133 0 R -/BaseFont /EUFTTG+URWPalladioL-Ital -/FontDescriptor 893 0 R +/Widths 2155 0 R +/BaseFont /FKTXQR+URWPalladioL-Ital +/FontDescriptor 898 0 R >> endobj -893 0 obj << +898 0 obj << /Ascent 722 /CapHeight 693 /Descent -261 -/FontName /EUFTTG+URWPalladioL-Ital +/FontName /FKTXQR+URWPalladioL-Ital /ItalicAngle -9.5 /StemV 78 /XHeight 482 /FontBBox [-170 -305 1010 941] /Flags 4 /CharSet (/fi/fl/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/emdash) -/FontFile 894 0 R +/FontFile 899 0 R >> endobj -2133 0 obj +2155 0 obj [528 545 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 333 0 0 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 0 0 0 0 0 0 722 611 667 778 611 556 722 778 333 0 667 556 944 778 778 611 778 667 556 611 778 722 944 722 667 667 0 0 0 0 0 0 444 463 407 500 389 278 500 500 278 0 444 278 778 556 444 500 463 389 389 333 556 500 722 500 500 444 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1000 ] endobj -798 0 obj << +802 0 obj << /Length1 1630 /Length2 15892 /Length3 532 @@ -10307,7 +10453,7 @@ stream xÚ¬¹cx¥]³-Ûv¯ØfǶm¯$+6:ìØ¶“Žm;éØè°culãëç}ÏÞû\ûœ_çÛ¿Ö=kTªY£æ¼îûZ”¤ÊjŒ"æ¦@I{WFV&^€†ª–²‰­­‰9ÈAžQÕÁÎð×̉@I)æ 4q9Ø‹›¸yZ@s€8Ð ÀÆ`ýúõ+%@ÌÁÑËdiå  ùËAKOÏð_–\¦^ÿütYÚ¨þ>¸mí€ö®)þŸÕ€@€«`²Ä””ud¥4RŠ) =ÐÙÄ ìfj 2ȃ̀ö.@Z€…ƒ3Àöß €™ƒ½9蟭¹0ýåq˜\f ¿a@O3 ã?Àèlrqùû ¹,Mì]ÿöÀÕ²7³u3ÿ§€¿v ‡äèìð×Ãî/ö—LÙÁÅÕÅÌäè ø›UY\òßuºZ™¸þ“Ûô8Xüõ4w0sûgKÿÂþÒüE]M@ö.W §ë?¹Ls‹£­‰×ßÜÉAÿ*ÃÍdoù_0œ–&Îæ¶@—¿4¹ÿéÎíð¿íÞÄÑÑÖë_ÑÿòúÏ@®.@[ &V¶¿9Í\ÿæ¶Ù#0ÿ3*2öV–ÛÍÝÿs:ÿ«A4ÿÌ íß"LÌìm½æ@ fE׿)4ÿo*3ýωü? ñÿˆÀÿ#òþÿ÷¿kô¿âÿ¿çù¿SKºÙÚ*šØÿø; øç’±ÿ?¼Mì@¶^ÿ7ÿÿî©üw‘ÿWW“¿­±·ü+ãW&–¯ÿ@.’ O ¹2ÈÕÌ -`abû·Wÿ²kØ›mAöÀ¿šþ«FV–ÿ†©[Ìlìÿi>ç¿! ½ù¯ÿ¯LÿªžYI\F[R”þÿ¸WÕlÿΗ+÷¿#”ÿN‚«º—#ð¿Òi)8˜ÿçâ>QQO€7#+€‘‡ýïdc|å`÷ý¿äþë­L\Až=&Ö¿¤ÿü²ü“û? ƒÿF#aoæ`þÏ쨹šØ›ÿ·ÿ4ü›¹9;ÿUù_7ÀßíÿÇú_ƒzÍV9˜ñ[§ge¸Öáæ OŠë ô±B‡8–6ªÔ8ôú§‡o­4~« ajšæýh÷Z:q|ß—¥;íñ¥îM^ù’Óö¢ÿ¦êä¦?d6,EÎ8ÕŠö¾\”ß‚ÒåbÑ<Ø™TQ5,yƒ!žîdw†»|¤ w/ À¢xpDñ3KkˆÃîBkèûqrJ•tüø@=462ü³÷ºŸ>7ž’Ï +`abû·Wÿ²kØ›mAöÀ¿šþ«FV–ÿ†©[Ìlìÿi>ç¿! ½ù¯ÿ¯LÿªžYSD\ZB–þÿ¸WÕlÿΗ+÷¿#”ÿN‚«º—#ð¿Òi)8˜ÿçâ>QQO€7#+€‘‡ýïdc|å`÷ý¿äþë­L\Až=&Ö¿¤ÿü²ü“û? ƒÿF#aoæ`þÏ쨹šØ›ÿ·ÿ4ü›¹9;ÿUù_7ÀßíÿÇú_ƒzÍV9˜ñ[§ge¸Öáæ OŠë ô±B‡8–6ªÔ8ôú§‡o­4~« ajšæýh÷Z:q|ß—¥;íñ¥îM^ù’Óö¢ÿ¦êä¦?d6,EÎ8ÕŠö¾\”ß‚ÒåbÑ<Ø™TQ5,yƒ!žîdw†»|¤ w/ À¢xpDñ3KkˆÃîBkèûqrJ•tüø@=462ü³÷ºŸ>7ž’Ï ™**À)—PHW£B¢ªU³m·WÛÔOrí]VÉ• $«ùqyĤ"õÂzŒf<0ëûë£Îðf}/Ÿí¤>bêFè,VØUd‹ÕƒæÔJlNÍo’©+¬OXÏ1Ï-¼§c-NÂ1ipÝ›í\AÖµ?ªª…¹{G.ž'Þ½µ$5õü^oDÌÒ’j8Á¬R/ë‰yÝ࣑<Ì`½^ úêì`uvdé,RHžê$žkK‚>&Y ¤ºÛ”OØ&â„o™kâÆœm§Ù WëÙÉ ¨œ/û«Ð[BÒó´`Ûtä¯äÍN¿GfáĈHªýmVéDÇÏ“Ÿ”Ä÷¦Y_kÉóÍ+èü1pÇÒ¨åÁ³ñÂjD•jÊ @@ -10369,35 +10515,35 @@ MI ¿n$rÝ XðD˜t ÎõÓ…”2§—n„sÞmOÆ„ ˆ;²ÃßshuåU9ñÖ&;y-sõP~K*ªÅz4rnp´}ª÷œõ)RB—+«å—>¢cI£Ž¹w× éhz€Ì\mm £MúHþ×<×|Ìï­&‰ Ÿw³s£Üë+\?VË´<=yò‹ØH»M'²ñÑ67Cøoí+A5x5½·x¯'_Ë c!vÜ~óÓ4¶bIpµP]ãH^ŒúÀnkLßYßÙ„æÀ,•‰)tCœrÀ‘ Çi†Ï±m$hýÈn.ÿ¶»öO¿ªWÂ[–{OFChÓ'žWùÆ*6L‡1±’g^H]u Ââa3ð¸g@—TÕL_1@d7¾ùÁ“†µ‹Œ:…‘XF.ÿ§Òfb1\ÄñSÙ£Ö®TÁIS ÒŽã{9.´ v´ôPš_$ ƒºÃ™.T€Áj”¤RÚ.zàÂiXÎ^;-”ûkwå0HMKyÃûSc-‘tkâôk'a.*bí Û¶4ŠdÇ&ž*qÉŸX‡ÒÝÓä"c°4 *+9‚3£ cáE¢Lg%ãŸïÁó§KíÚï©=ëg‡~Q)œu‘Še7@ô`­¥¡c˜„s2¬ìe/ï´Ã÷5ØI*·[ÔrHîD4;"«hntRÉ´c¬¥ŸýÝ„u å{ÿÁØ }hë …x;³°çlqf—š “d79˜R€2õ¨)iµ†–Gö»€ê&‚—ÜÞ¨CšùŸeVò]ÏÓ~„ð¡T}îY¸dë`XÕìéÎ<òe JË»1ÒXê¤QáÀ#÷gX¹;«ÜÉà{}¤* ½lÈ»€~.ž©kÜõVÅÇ®þÒ€§ú‘7ã$o—#€àkص <Éâ{ -¯41¶{ºQµÚâl·Pãg;‹($@QQ~:ú4¥ /麞e„¼æª't“Ê>~œÍÆTÂ={š÷ÈcW ä­ë6Å͆ÇIjË‚¶{Al ¸¸ ²œís è¹”Lª £ÈàýÞùqœöÇ=*Y€þKTØ&§Ð9æ2ös³Ìü±×îªÊ›õäõ§=ìÌÉIx=ãç7åv[¿Céhw›«Ó(îl*ø®Ÿq ‰Ëb“ÛfÜèY àûYÚÿßRŸåÆ |)¶U-*ª[rᇻ……øw8me-PÍsóQîñúW™N‡vé¸î²”š{e³ã=öEëe>*­xQÿuò_­Rñ„çÒ˜ ¢þ«Iïç?d¯Y¹Æa½/Kz†Âc™›gZ6qæåØöì—3 p0, HÎIM,*ÉÏM,ÊæªlfŒendstream +¯41¶{ºQµÚâl·Pãg;‹($@QQ~:ú4¥ /麞e„¼æª't“Ê>~œÍÆTÂ={š÷ÈcW ä­ë6Å͆ÇIjË‚¶{Al ¸¸ ²œís è¹”Lª £ÈàýÞùqœöÇ=*Y€þKTØ&§Ð9æ2ös³Ìü±×îªÊ›õäõ§=ìÌÉIx=ãç7åv[¿Céhw›«Ó(îl*ø®Ÿq ‰Ëb“ÛfÜèY àûYÚÿßRŸåÆ |)¶U-*ª[rᇻ……øw8me-PÍsóQîñúW™N‡vé¸î²”š{e³ã=öEëe>*­xQÿuò_­Rñ„çÒ˜ ¢þ«Iïç?d¯Y¹Æa½/Kz†Âc™›gZ6qæåØöì—3 p0, HÎIM,*ÉÏM,Êæf‚endstream endobj -799 0 obj << +803 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2122 0 R +/Encoding 2143 0 R /FirstChar 40 /LastChar 90 -/Widths 2134 0 R -/BaseFont /ODIXFB+URWPalladioL-Roma-Slant_167 -/FontDescriptor 797 0 R +/Widths 2156 0 R +/BaseFont /VADHEJ+URWPalladioL-Roma-Slant_167 +/FontDescriptor 801 0 R >> endobj -797 0 obj << +801 0 obj << /Ascent 715 /CapHeight 680 /Descent -282 -/FontName /ODIXFB+URWPalladioL-Roma-Slant_167 +/FontName /VADHEJ+URWPalladioL-Roma-Slant_167 /ItalicAngle -9 /StemV 84 /XHeight 469 /FontBBox [-166 -283 1021 943] /Flags 4 /CharSet (/parenleft/parenright/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/X/Y/Z) -/FontFile 798 0 R +/FontFile 802 0 R >> endobj -2134 0 obj +2156 0 obj [333 333 0 0 0 333 250 0 500 500 500 500 500 500 500 500 500 500 0 0 0 0 0 0 0 778 611 709 774 611 556 763 832 337 0 726 611 946 831 786 604 786 668 525 613 778 722 0 667 667 667 ] endobj -736 0 obj << +740 0 obj << /Length1 862 /Length2 1251 /Length3 532 @@ -10406,46 +10552,45 @@ endobj >> stream xÚíUkTgnõJÀ+Å€€¸ -æ2%X$-wTP¤2$H20I0@¹,P ‚A…ÊE ÒJi½ ”‹ÁŠ‚§F„‚Ü4 -& X¹ê -ºè±KîþÚ³3æ}žç{¿gž÷;ç33ñô!8²‘ ØŠ ¤Nn>A2É833'†ÄràqçÖÉÚ¸¼ë;Y·î¹2=ñ"ç4sÇA;hš}„ àD(V^#Ž-wUÊ£úìùõéMþÒ'Æ©¦)fÏZ}Ê¥3i±†Ñ¿ß ÓÄßIË(žùÊC ×d̸6p[žt]IÊŒßÛhìjÔöКûrs›•»ì£`ò õª‹#µí!öÿ\¦¼Vin.‹}^…Ôäïyþ]ýιýøŒâÕ§>-­—kw×뺻îö:e¾(ÔrïÐH£¸I®ÌÊj¹ÇÇHøáq›ŽîÛ{KÆ ÞÓ1øö+¯€\†äüJ#£exðص0Š–©¬‹fdþå—ÌÕåkE%›D%ãÇéýGÁª]à}ÕxÆáœXæ$3M/7øjŒ#ÇÛUY6o”ÕéõÔœ‘ÉûtŒ5û•YQz -Y¥8Ç9­=›™žáàîå÷…FÜáæ¼¤€gjußóЧeÈ™c[Æ|ÕÉÌã­/'¬¦Dã>Úô‹]¥~)†æ‘ðÅ›™MÇò3ëUL’Ó~ƒáwa_·09›5•zö7ÓqƒL~·±(„ðc´åЄrÓ%{&nÄÍàD÷™Ò£Î¾ºÌØ„Øk7NKê ‰À9 ²¤våš'øÖ‡\îSŒÃ㲎„™xjèz”Ë.Ûk'$Ô\×-”…ÌîЉМV*¦…­FÔ=3À5½[wì™üPûR÷ÈÉ?ª)–’Öokö±ïOWïßô:óÀ³†~îG¡ÿÐõS¿ Ï›?2¬>¦òõÉ/áÞÏo”~/øãoC¥“áëó¯Þ”_• ­­ý7‹l©Š£&•×*¯InØ›ËHÊ[”ý §³Øþ¥y¾~P{D².«,U55öÔͧŠ »Šªéó(ç©óx…ýde©?ýS—_ã¨bÎ Ç翜$½Nì~®Q×*5*óeT¥LM—hµ¾Þê™Õ>ä1¨'›³²dPª×H\š @šÝî~Ã{8sç—Úµ¬÷U$FÛéx7:á,?ÔyòÓæÝ¯¸ùOiD§È‡‹øÄuþ÷T«TêSFaô{ò€Š1b]aÚù_Ýw*S’ç#¶ä]k¬Øu ÙìÓò€vlÃlÓËD Õ7™Už¦«‹ûJ*ƶábuÁÀ$ñö²·p}Â(5ñiQBCG¸çÀ\—$§!7!Ç]~9Šœù¸)ökµÑ)Ç÷D_uo€£ŒÚjnÿ=Õáh׺™;wáÔúBÙ˜«jU´fŸîNç²QÝÖ…Zöî–[£!CŽWµ$Aü6ÍŸd‡š@Â!ß¼tÍ› ‰ˆINzÀxwÁv}ÃuÙF{I¾?>¬iÿ˜ú`v«× íøT6Ý1¿é0S x}Î䇯£Ž¨Fü׆þÜ×¢¯ª«;rª³+Ù7ÖÕt®]šrZ9µqg{7áø®lGÌ}Ÿ3\OkôÏɵV'•Dz;Bêmиƒ’ž˜lo^·`m`onç=òøàþßà¢vuC¨@h(î_EÍþ}endstream +æ2@ Š&X4•;"(R’ $˜$ \(PÁ Bå"Pi¥´^€–‹ÁŠ‚g¹iL@°rÕtÐc—þÜýµggþÌû<Ï÷~Ï<ïwÎgfâáM ³‘ ØŠ ¤N®Þ‡@2É833'†ÄãM=çi,.-V^=!LJ*ô¿d9œÒE¯d¸¥5]¢{ñjZQ¹_V<µ‰ØãLL“­yme>Ê”‡<]ðÒÖ„>:ûí¶í½ÓÛâÚtαUŒÃç绵7Zz´4Ýl×{AsàÃMøÈ'['kãònìdMܾïÂôÀ‹œÓÌGí ihö1.€¡PXyŽÐ[î©”ÇôÙóëÝÓ›ü¥OSMSÌž·z—KgÒb £»¦‰¿›:–Q<󵻮ɘq}àŽ<醒”¿·ÑØÅ¨í‘5÷Õæ6+7Ù'ÁäAëU—Fj ÚCûüR¦¼Qin.‹}Q…Ôäïyþ}ýÎ9|F qõéCÏJëåÚÝõz î®{½N™/ µÜ:4Ò(®’«³²Zî‰1~xܦ£ûÎÞÒGñ‚t ¾ûÚ3 —á9¿ÖÈh<~=Œ¢e*ë²32ÿêà+æêòµ¢‹M¢’Kñc‰´þc`ÕÍÎ.ðj<ãHN,s’™¦—|-Æ‘ãí«,›7ÊêôzjÎÊä}:Æšýʬ(=…‰¬RÈãœÑžÍLÏðpóôÛ¯w¤9/)À=à¹ZÝ÷¢âYrvÇØ–„1_u2óDëËÁ «)Ѹ·6íRW©_Š¡y$|©ÁÑf¦@“^~v½Š©@rÚo2ü.èâ&gs£¦RÏýÃôeÜàï“ßo, +!üm94¡ÜÚ—=7âjp²Œû\é^çP]flBìµ·Kê ‰À9¢²¤våš§ø›Ö‡÷= ‡Çe 3ñÐÐu/—]qÐNH¨¹.[( ™Ý¡¡9ÿ¬TL [¨Ÿzd€kz·îØ3ù±ö寑S;~RS,%­ßÕ`>˜®öÙô&óàó†~î'¡ÓõS¿ +Ï›?:¬>®r—õÉ/ã>Ìo”þ øý/C¥“áëó¯Ý’_“ ­­ý·Šl©Šc'•×+oŒIn:˜ËHÊÛŸ„3YlÿÒ<ß‹?ªÝ#YWT«š{êæSE aÐ=EÕ§´y”óÌy¼Âa²²ÔŸö¹÷¾_ã¨bÎIú‹¿Ÿ"½Iì~¡Q×*5*óeT¥LM—hµ¾Ùê‘Õ>ä>¨'›³²dPª×Hö5€4ûÝý†;öpæ.ü&µoY7î«HŒ¶×ñ +ntÂY~¬óôç»Í»_sóŸ׈N‘1ð‰ëüï«V©Ô§Âh÷åcĺ´ ¿ºí*T¦$ÏGlɺÞX±ë`³Ù»å¡Ýñ ³M¯-TßfVy˜®6.î[(©Û†‹Õ‘ÄÛË\Ãõ £4ÖÄçE ás]’œ†Ü„7ù•(ræ“R¤Ø¯ÕF§_Ü}YÔ½Ž2j«i¸ó×TÇc]ëfîÞƒSë ec.ªUÑš}ºw;ËFu[jÙ»[n:† ѯiI‚ømš?/È7€„þyéš36“œô€ñî‚íú†ë²ö’8||XÓ<þ õáìVÏAÛñ©l=¿éS x}ÞäÇo¢ŽªFü׆þÒ×¢¯ª«;zº³+Ù7ÖÅt®]šrF9µqg{7áÄ®l÷ÇÌ“}_2\ÎhôÏɵV'•Dz;BêmиC’ž˜l/^·`m`onçòøàþßà¢vuC¨@h(î_Û-þRendstream endobj -737 0 obj << +741 0 obj << /Type /Font /Subtype /Type1 -/Encoding 2135 0 R +/Encoding 2157 0 R /FirstChar 13 /LastChar 110 -/Widths 2136 0 R -/BaseFont /QQRSYH+CMSY10 -/FontDescriptor 735 0 R +/Widths 2158 0 R +/BaseFont /BFRUCK+CMSY10 +/FontDescriptor 739 0 R >> endobj -735 0 obj << +739 0 obj << /Ascent 750 /CapHeight 683 /Descent -194 -/FontName /QQRSYH+CMSY10 +/FontName /BFRUCK+CMSY10 /ItalicAngle -14.035 /StemV 85 /XHeight 431 /FontBBox [-29 -960 1116 775] /Flags 4 /CharSet (/circlecopyrt/bullet/braceleft/braceright/bar/backslash) -/FontFile 736 0 R +/FontFile 740 0 R >> endobj -2136 0 obj +2158 0 obj [1000 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 0 0 278 0 0 0 500 ] endobj -2135 0 obj << +2157 0 obj << /Type /Encoding /Differences [ 0 /.notdef 13/circlecopyrt 14/.notdef 15/bullet 16/.notdef 102/braceleft/braceright 104/.notdef 106/bar 107/.notdef 110/backslash 111/.notdef] >> endobj -733 0 obj << +737 0 obj << /Length1 1616 /Length2 25334 /Length3 532 @@ -10453,7 +10598,7 @@ endobj /Filter /FlateDecode >> stream -xÚ¬ºc”¤]°%\]î²,Û¶mÛvuÙ¶mÛ¶m£ËU]¶í¯ß÷Î;ëÎüšo~äZωˆ³cGìsb­'3Iä•hŒí MDílhhé9*ŠjòÖÖÆvÒ4Šv6€¿f(!' ;[a'N€š‰1@ØÄÀÈ`ààà€"ÙÙ»;X˜™;ÈÿbPPQQÿ—埀¡ûzþît´0³þ}p1±¶³·1±uú ñ½QÉÄàdn0µ°6ÉÉkHÈŠÈÅdUb&¶&ÖygCk #€´…‘‰­£ ÀÔÎ`ý €‘­±Å?¥9ÒþÅpíMŒ,þn3q32±ÿÇE °7q°±ptüû °p˜9Ø:ýí“ÀÂÖÈÚÙøí¦vÿ²w°ûaó×÷LÞÎÑÉÑÈÁÂÞ ð7«¼°èðt27pú'·£Å_7ÀÎôo¤±‘ó?%ýëû ó×ëd`aëp2qsú'—¡ ÀØÂÑÞÚÀýoî¿`öÿÒpv´°5û/Ô3ckGÇ¿0±ÿéÎÕ ø_ª7°··vÿw·Ý¿Qÿ“ƒ…“£‰µ)-ãßœFNs›YØBÑýsT$lMí ôÿa7v¶ÿOŸ‹‰Ã¿ "ÿçÌPü%a`lgkí061…¢“µsú›@þ§2íÿ;‘ÿHüÿDàÿ'òþÿ÷¿kô¿\âÿ¿÷ù¿C‹:[[Ëؘü» ðŸ3 øgÈØþoÑ6Öîÿ§øÿ©fò$ÿ0N[!`köWzZúÿ0Z8ŠZ¸™Ë[8™L ¬ÿöé_»Š­±‰ƒµ…­É_=ÿm%€†žþ¿ù”Í-Œ¬lÿi<˸Llÿ;÷¿ýËœNLITBYŒêŸ©ÿÆÉÿÕÞIÙÝþ/µÿQŠŒñÿ\üƒ"(hçð¤a`eÐ0²3ý½rŒ f&ïÿCÆþk-càä`áÐú[6=ÿÅÿÏ­tþŒˆ­‘ñ?§EÉÉÀÖøïûŸ†ÜFÎuý÷Îÿ-ú?×ÿu7#¨µßvF\A–i™éNuè¹#SÂZ} #Áö¥ÊE~5v½¾ia8*õ?jƒi›f8¿ÚÝ—Ïì?$)ÇúЬÉzSL®òq¼‰(ú ·H;Ù¨ètKaÓÏÕ¢<¯—¤w@5YéUw§uK>Àqg:™ ¯Ÿ)üˆ\ +xÚ¬ºc”¤]°%\]î²,Û¶mÛvuÙ¶mÛ¶m£ËU]¶í¯ß÷Î;ëÎüšo~äZωˆ³cGìsb­'3Iä•hŒí MDílhhé9*ŠjòÖÖÆvÒ4Šv6€¿f(!' ;[a'N€š‰1@ØÄÀÈ`ààà€"ÙÙ»;X˜™;ÈÿbPPQQÿ—埀¡ûzþît´0³þ}p1±¶³·1±uú ñ½QÉÄàdn0µ°6ÉÉkHÈŠÈÅdUb&¶&ÖygCk #€´…‘‰­£ ÀÔÎ`ý €‘­±Å?¥9ÒþÅpíMŒ,þn3q32±ÿÇE °7q°±ptüû °p˜9Ø:ýí“ÀÂÖÈÚÙøí¦vÿ²w°ûaó×÷LÞÎÑÉÑÈÁÂÞ ð7«¼°èðt27pú'·£Å_7ÀÎôo¤±‘ó?%ýëû ó×ëd`aëp2qsú'—¡ ÀØÂÑÞÚÀýoî¿`öÿÒpv´°5û/Ô3ckGÇ¿0±ÿéÎÕ ø_ª7°··vÿw·Ý¿Qÿ“ƒ…“£‰µ)-ãßœFNs›YØBÑýsT$lMí ôÿa7v¶ÿOŸ‹‰Ã¿ "ÿçÌPü%a`lgkí061…¢“µsú›@þ§2íÿ;‘ÿHüÿDàÿ'òþÿ÷¿kô¿\âÿ¿÷ù¿C‹:[[Ëؘü» ðŸ3 øgÈØþoÑ6Öîÿ§øÿ©fò$ÿ0N[!`köWzZúÿ0Z8ŠZ¸™Ë[8™L ¬ÿöé_»Š­±‰ƒµ…­É_=ÿm%€†žþ¿ù”Í-Œ¬lÿi<˸Llÿ;÷¿ýËœNFAZXC꟩ÿÆÉÿÕÞIÙÝþ/µÿQŠŒñÿ\üƒ"(hçð¤a`eÐ0²3ý½rŒ f&ïÿCÆþk-càä`áÐú[6=ÿÅÿÏ­tþŒˆ­‘ñ?§EÉÉÀÖøïûŸ†ÜFÎuý÷Îÿ-ú?×ÿu7#¨µßvF\A–i™éNuè¹#SÂZ} #Áö¥ÊE~5v½¾ia8*õ?jƒi›f8¿ÚÝ—Ïì?$)ÇúЬÉzSL®òq¼‰(ú ·H;Ù¨ètKaÓÏÕ¢<¯—¤w@5YéUw§uK>Àqg:™ ¯Ÿ)üˆ\ üPˆŸìá|ŒRbQ»š€ê ÏÎIOžŸÈ†ÆGG†{oÁú°©rb’p¹€Â’FúýÊÁæÓT©©jUmÛëÕb3ô]ÿ””s Îl~^õ­H¹²çŸÈôÿbاÑÙ®ïå²žÒæNHÙ ™C ½‰h1R^iC«ÙÂ{»AùÖˆqwÛÁxyÒWcÁ·ÿ¡y÷'‡—ÁOéTñ´šŸ­wôêuòÓsPMTUËçýNÀ(5±†ÅÄ ö¶‘ÛMüc,‚¨×]EI[™Y… ¸îˆ0^ ÆMÏm}™× Ë 3ž@óÉ ª0öGƺ°>KÛyE‡“åÜTh6þÁØŸøÐJ¢w¢§æ_[c ³öB8xÕ¾Vk”Ô‚—I¯¿ä„÷gÞk‰òŒ+(}‘²Å+åýdä„P9Œ,U•äD¡&w("Z·´U¾D£|yÛ)Õ‚þ0ŽÖ)¹` Á6l¬NÒµ½žŒÍ&²˜ W WâãÆ[.¸N5ÈõëZS† @@ -10547,35 +10692,35 @@ A ­u|Ðí8t^ˆš/€‹MÝp­_’<{*ñ>Jn ÐÅ—6¹s²R¯aÆ‹úr×€]9ä¯:²(`\‰áÉlA7¾ĦK”ž·†9z8nb64Ë¢jE¢$µ1V|·ZBËÐöX#Y»ͪföWßqYûlf/ö»­8Fj…›ë_X1¡ÁèínÕ (N1©þ¢CÑð´ýÆ9(AÄEêÞ–«ôáÃÉ€ÖÜÑf}_¢£J¾:¤ íéJ$<ÂBÿˆSUÅöìMø›Yr¤˜¾ÃÈ×`Qíå?›Ù±VƒÝŽˆ½¸ÂˆÚÖñhÃÙƒXÔ‡7Ó¶,Í!Á•FÿÁEè^F ¸¯xÀÁ¦ÿàB*·ÛvªR&¤N<•ê`¢µ+çN¼é¬ g¤£Ê¾2f~mû„m}…i¶xÄãæužÙÆœ»‚ÙüÂx\Ôt{™C Àåò ›ËøýÈ·'5' ªzqvipd×kµ»¶j©@ƒæ…:Íw¾?bøàôVs,%ãIP¡ÍSÃ…„A³ô‰ìDª`Ïûñ,{r˜¦fY—AÀ˜EÏ¡+LNä^õ,¸¬Y¼B™¡9ÛœÐç†dbTC4è¿JLWl©0Âkž ^¸ùT›Úò«¾¦ét«§^Þí§/‡3SÄ蚇dQœv(CÜ쇵È%#¾j0Æ7›5pEZ‡ì—,í¼éÀOÇéÃõ¤¯(CæýéZb4üÁP”™Γ{5Þ…k`åùÃJÙãpÔféAvs,µp̈Õ.¨±g¸Ño¡µ°±P9:Ý,'c|Ì1eÁh†M~‘fQÞúûdú9’LÈúôÖN0–"/Ó|8׃ҿ]‰/ óûÚûس˜z$©Ôü³[<~q÷é#ƒä2 'óP4I×¥ŸÐ?`b¬FH. ÷R}ÿÀ#] «iÀAñ7FÌÐ5øùq6O‰ Ç/êúWbõÑFåq-¢´ð §]xžök%˜Ã–td˜¯‘ŒÎ¼r¿?qEµÀ¡Glq_åOÎ1ŠL$HülÓ‚|²ëÅ›:vÐ Ø›¨†À<¬è2ëg8„7ë%j ÅL/ARWˆŠmõƒÑ ±)Cðî&œ£Ò(q14ŒED;ÌjdW åqêÒÚ8ß'‡õt˜{r›`üz$¸~ЗV-ðr#QcªžÉ¹=H­EÍëCóIîÁÕŒ–aYÅuz8UG²þºÝ¡HJP+dGR]¤IؘNd'×DóN'é[ºqÆIÒĵF,·;Å—d•”©7•‘W­_ˆF®kô­é¢á£tΘ ~­ yTjænUÀNöÂߥ6”éŸì¶\e>:3‚t{ù^÷p*kõ!1ñÖ3«/¥tŒëÖÈ|æeWç¯ÛQ#`IbýÍÃ$ŒPÍXÉSKUŽž¡’` ËAÅžþ›m­%N©ò’÷Y ¥Ê¡K_º`ÕsYGõ¾ìŸö¨,4ƒ“³›¯HC'Ÿû89cá[ã Û2?ÆN¼ ü±ù#°¥ª0ägã¶,Š¢œ¡. éj”¿ê?ÉxG# Ò+“Å.ă-†cå-Yo¢UÄVõñÈö15Ò»æ¾Ýc@@íéíAŸ LüUÜêÏÉ…ÜÔ¿©ÿÌZÏ‚ñåÎSUn9“mbµf[‘€Š±ÑT8D1¿4г#hqÙך½E9É{Ь¶uîœb…M'­?/ÖGÐÿéε%¨˜Gš±Ñ3 ?hßó¤¸þa¶„çŽØyžÓ€’^`´ý×Þz\‹÷¶v«áP{ÑÑ•Ih~×`5»æ0ïfM…ÂÛ -ä&oH[œ¯A•9fÜË•ÿ+J†'¡1ê’ëyC \<†æ›îyʇfäiX.²¢¦ ËÅoöøA…°•#ó3ÆÎÑ—ï;¦ûÁ_;râw‚›ìĽÅzi“Ã+Yxh­ÀêÐÃz5xu¾5)sþ³py}Mµ~à óÿ¸ÿüŸ˜Øš9ÿv°3r¶ûG‚¹7endstream +ä&oH[œ¯A•9fÜË•ÿ+J†'¡1ê’ëyC \<†æ›îyʇfäiX.²¢¦ ËÅoöøA…°•#ó3ÆÎÑ—ï;¦ûÁ_;râw‚›ìĽÅzi“Ã+Yxh­ÀêÐÃz5xu¾5)sþ³py}Mµ~à óÿ¸ÿüŸ˜Øš9ÿv°3r¶ûE‡¹> endobj -732 0 obj << +736 0 obj << /Ascent 715 /CapHeight 680 /Descent -282 -/FontName /GSFITG+URWPalladioL-Roma +/FontName /MQLDYB+URWPalladioL-Roma /ItalicAngle 0 /StemV 84 /XHeight 469 /FontBBox [-166 -283 1021 943] /Flags 4 /CharSet (/fi/fl/exclam/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/circumflex/quotedblright/endash/emdash/Oslash) -/FontFile 733 0 R +/FontFile 737 0 R >> endobj -2137 0 obj +2159 0 obj [605 608 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 500 500 840 0 278 333 333 389 606 250 333 250 606 500 500 500 500 500 500 500 500 500 500 250 250 0 606 0 444 747 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 1000 667 667 667 333 0 333 0 0 278 500 553 444 611 479 333 556 582 291 234 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 500 0 500 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 833 ] endobj -709 0 obj << +713 0 obj << /Length1 1614 /Length2 24766 /Length3 532 @@ -10583,7 +10728,7 @@ endobj /Filter /FlateDecode >> stream -xÚ¬zSm]³eÙ¶]uʶmÛ¶mÛö)Û¶mÛæ)ó”«ëû¯:n÷S÷}Xkfæ92GÎ{G,RBy%c;CQ;[gZzNE5ykkc ;iA;kc‚3 )©£‰³…­°³ 'š‰1°‰##)½‡£…™¹3ùõYþ !0ôøÏÏN' 3[²ŸWk;{[çˆÿçJ&&Îæ&¦Ö&Brò²bäb²*b&¶&ŽÖò.†ÖFÒF&¶N&¦vŽÖÿ¶ 0²³5¶ø§4'Ú,''{#‹Ÿm&îF&öÿ¸¨ ìMm,œœ~Þ ,œÌ lzàlG`akdíbü»©Ý¿Ù;ÚýDØüø~Àä휜Œ-ì ~²Ê ‹þOgsçr;Yü¸ ìL"íŒ\þ)é_¾˜¯³…­³‰»ó?¹ MŒ-œì­ <~rÿ€Ù;Zü‹†‹“…­Ù1 &p413p4¶6qrúùÁþ§;ÿU'ÁÿV½½½µÇ¿vÛý+ê?9X8;™X›ÒB10þä4rþÉmfa E÷ϨHØšÚ0Ðÿ›ÝØÅþ?|®&Žÿjù?3CñCÂÀØÎÖÚƒÀØÄŠNÖÎù'%ùÿ›Ê´ÿs"ÿHü?"ðÿˆ¼ÿâþwþ·Cüÿ{žÿ;´¨‹µµ¬É¿6üÇC MðÏ%óØXX{üßÂÿ{¤šÉ¿qü¿¡H8ü4BÀÖìG zZú3Z8‰Z¸›Ë[8™˜Xÿté_v[cGk [“5ÿÕHzúÿæS6·0²²ý§í,ÿæ2±5þïÔúq:Me YuªÿóFýWœüòÎÊö?Ôþ½;ãÿ\üƒ"(hçNàEÃÀÂH@ÃDÏðsà~øp0±øü_2þ ˆá¿Ö2ÎŽîZ?eÿìü§øþk¥óß`DlìŒÿ™%g[ãŸñúOÃ?n#GÇUÿuâŠþõ¿ÝÄÄÝÄj}ÅΈ+Ø2ýw†szîÈ”°Ö@ðHˆ}i£rQ]¯_zøG¥þGmmÓ çW»ÇòûÏ#IÊã±>4ë_½©&×ù8>ÄýˆÛdlTÇtº¥°jÑ^7KÒ» š¬ôªÇûS +xÚ¬zSm]³eÙ¶]uʶmÛ¶mÛö)Û¶mÛæ)ó”«ëû¯:n÷S÷}Xkfæ92GÎ{G,RBy%c;CQ;[gZzNE5ykkc ;iA;kc‚3 )©£‰³…­°³ 'š‰1°‰##)½‡£…™¹3ùõYþ !0ôøÏÏN' 3[²ŸWk;{[çˆÿçJ&&Îæ&¦Ö&Brò²bäb²*b&¶&ŽÖò.†ÖFÒF&¶N&¦vŽÖÿ¶ 0²³5¶ø§4'Ú,''{#‹Ÿm&îF&öÿ¸¨ ìMm,œœ~Þ ,œÌ lzàlG`akdíbü»©Ý¿Ù;ÚýDØüø~Àä휜Œ-ì ~²Ê ‹þOgsçr;Yü¸ ìL"íŒ\þ)é_¾˜¯³…­³‰»ó?¹ MŒ-œì­ <~rÿ€Ù;Zü‹†‹“…­Ù1 &p413p4¶6qrúùÁþ§;ÿU'ÁÿV½½½µÇ¿vÛý+ê?9X8;™X›ÒB10þä4rþÉmfa E÷ϨHØšÚ0Ðÿ›ÝØÅþ?|®&Žÿjù?3CñCÂÀØÎÖÚƒÀØÄŠNÖÎù'%ùÿ›Ê´ÿs"ÿHü?"ðÿˆ¼ÿâþwþ·Cüÿ{žÿ;´¨‹µµ¬É¿6üÇC MðÏ%óØXX{üßÂÿ{¤šÉ¿qü¿¡H8ü4BÀÖìG zZú3Z8‰Z¸›Ë[8™˜Xÿté_v[cGk [“5ÿÕHzúÿæS6·0²²ý§í,ÿæ2±5þïÔúq:QqI%iiªÿóFýWœüòÎÊö?Ôþ½;ãÿ\üƒ"(hçNàEÃÀÂH@ÃDÏðsà~øp0±øü_2þ ˆá¿Ö2ÎŽîZ?eÿìü§øþk¥óß`DlìŒÿ™%g[ãŸñúOÃ?n#GÇUÿuâŠþõ¿ÝÄÄÝÄj}ÅΈ+Ø2ýw†szîÈ”°Ö@ðHˆ}i£rQ]¯_zøG¥þGmmÓ çW»ÇòûÏ#IÊã±>4ë_½©&×ù8>ÄýˆÛdlTÇtº¥°jÑ^7KÒ» š¬ôªÇûS Šº%`¸3LŽ7)ü‰] üQHžíá|ÒâP»šê ÿ\%ý}þ54>:2Ü{Ú„M•IÊå KåïƒÍ§©R!RÕDzÝžeÌ}øØ"œ³\ʤ!g?5íµ Îk“T $f}QìŒ}}œ7Ãë–aI­zQ£Ø`{1®ËÊ›¡9sõ‰ór5úË<#¤=ø…ˆ´±36…è4Ó+òŽÇ¾a‘Ïp:‰é"“|:[5P6“Ó#\2®˜Æíß»OÍß 6.â'¢ÿp$iÊíù2ŸÒ;LÛ–Oòá ±Fóyº)‘ùµ©ãà~ ¥ŸC¡ë­„aø ÅÑ«¨ÙûGæhg [&óâ<1—Xû²Âø{iª_“¸bf)¦Œ²§T˜ ÜÓ»GAe!ógF玦àUa!*ÚZ0Ÿðç/è a0¼€ž~£œ†äwÝo âïfŸJ³xÛw® ÞaÇL¿õ0 è^š `8¿Ú Ù4Ùç÷ Ï©4†V×"”]BÝ3pþà·½_) èIÞ\H$séåXŒ{Òb^Z,ÃÛ6ö©ÉÁ ¬–R2µCÇŠ‰t(£ˆOܲÓ7‚9òó`e€² ä@y%0júAÈëRÿ˜à˜~xƒ4wÖ5çíÂàÖ±åmÝÓ×â}=Ð’tRX[>͔ҞÐRÔ "çH³l/é•_r> endobj -708 0 obj << +712 0 obj << /Ascent 708 /CapHeight 672 /Descent -266 -/FontName /ZTEYNX+URWPalladioL-Bold +/FontName /FHJSLL+URWPalladioL-Bold /ItalicAngle 0 /StemV 123 /XHeight 471 /FontBBox [-152 -301 1000 935] /Flags 4 /CharSet (/fi/fl/exclam/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/question/at/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/emdash) -/FontFile 709 0 R +/FontFile 713 0 R >> endobj -2138 0 obj +2160 0 obj [611 611 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 0 500 889 0 278 333 333 444 606 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 250 0 0 0 444 747 778 667 722 833 611 556 833 833 389 0 778 611 1000 833 833 611 833 722 611 667 778 778 1000 667 667 667 333 0 333 0 0 0 500 611 444 611 500 389 556 611 333 333 611 333 889 611 556 611 611 389 444 333 611 556 833 500 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 1000 ] endobj -711 0 obj << +715 0 obj << /Type /Pages /Count 6 -/Parent 2139 0 R -/Kids [702 0 R 729 0 R 739 0 R 794 0 R 858 0 R 920 0 R] +/Parent 2161 0 R +/Kids [706 0 R 733 0 R 743 0 R 798 0 R 862 0 R 924 0 R] >> endobj -951 0 obj << +956 0 obj << /Type /Pages /Count 6 -/Parent 2139 0 R -/Kids [939 0 R 953 0 R 967 0 R 978 0 R 985 0 R 997 0 R] +/Parent 2161 0 R +/Kids [944 0 R 958 0 R 972 0 R 983 0 R 990 0 R 1002 0 R] >> endobj -1009 0 obj << +1014 0 obj << /Type /Pages /Count 6 -/Parent 2139 0 R -/Kids [1002 0 R 1011 0 R 1022 0 R 1030 0 R 1037 0 R 1043 0 R] +/Parent 2161 0 R +/Kids [1007 0 R 1016 0 R 1027 0 R 1035 0 R 1042 0 R 1048 0 R] >> endobj -1066 0 obj << +1071 0 obj << /Type /Pages /Count 6 -/Parent 2139 0 R -/Kids [1051 0 R 1073 0 R 1083 0 R 1088 0 R 1092 0 R 1099 0 R] +/Parent 2161 0 R +/Kids [1056 0 R 1078 0 R 1088 0 R 1093 0 R 1097 0 R 1104 0 R] >> endobj -1115 0 obj << +1120 0 obj << /Type /Pages /Count 6 -/Parent 2139 0 R -/Kids [1107 0 R 1118 0 R 1125 0 R 1130 0 R 1139 0 R 1146 0 R] +/Parent 2161 0 R +/Kids [1112 0 R 1123 0 R 1130 0 R 1135 0 R 1145 0 R 1151 0 R] >> endobj -1158 0 obj << +1161 0 obj << /Type /Pages /Count 6 -/Parent 2139 0 R -/Kids [1150 0 R 1161 0 R 1166 0 R 1174 0 R 1182 0 R 1191 0 R] +/Parent 2161 0 R +/Kids [1155 0 R 1163 0 R 1167 0 R 1177 0 R 1182 0 R 1190 0 R] >> endobj -1210 0 obj << +1206 0 obj << /Type /Pages /Count 6 -/Parent 2140 0 R -/Kids [1200 0 R 1212 0 R 1217 0 R 1223 0 R 1229 0 R 1233 0 R] +/Parent 2162 0 R +/Kids [1198 0 R 1208 0 R 1217 0 R 1228 0 R 1233 0 R 1239 0 R] >> endobj -1250 0 obj << +1248 0 obj << /Type /Pages /Count 6 -/Parent 2140 0 R -/Kids [1241 0 R 1252 0 R 1256 0 R 1260 0 R 1265 0 R 1271 0 R] +/Parent 2162 0 R +/Kids [1245 0 R 1250 0 R 1258 0 R 1268 0 R 1272 0 R 1276 0 R] >> endobj -1280 0 obj << +1285 0 obj << /Type /Pages /Count 6 -/Parent 2140 0 R -/Kids [1275 0 R 1282 0 R 1293 0 R 1297 0 R 1301 0 R 1311 0 R] +/Parent 2162 0 R +/Kids [1281 0 R 1288 0 R 1292 0 R 1298 0 R 1309 0 R 1313 0 R] >> endobj -1323 0 obj << +1325 0 obj << /Type /Pages /Count 6 -/Parent 2140 0 R -/Kids [1318 0 R 1325 0 R 1329 0 R 1333 0 R 1337 0 R 1345 0 R] +/Parent 2162 0 R +/Kids [1317 0 R 1328 0 R 1335 0 R 1340 0 R 1345 0 R 1349 0 R] >> endobj -1356 0 obj << +1359 0 obj << /Type /Pages /Count 6 -/Parent 2140 0 R -/Kids [1351 0 R 1358 0 R 1365 0 R 1372 0 R 1378 0 R 1390 0 R] +/Parent 2162 0 R +/Kids [1353 0 R 1361 0 R 1368 0 R 1374 0 R 1381 0 R 1388 0 R] >> endobj -1398 0 obj << +1401 0 obj << /Type /Pages /Count 6 -/Parent 2140 0 R -/Kids [1395 0 R 1400 0 R 1405 0 R 1413 0 R 1420 0 R 1425 0 R] +/Parent 2162 0 R +/Kids [1394 0 R 1404 0 R 1412 0 R 1416 0 R 1421 0 R 1428 0 R] >> endobj -1432 0 obj << +1440 0 obj << /Type /Pages /Count 6 -/Parent 2141 0 R -/Kids [1429 0 R 1434 0 R 1442 0 R 1449 0 R 1468 0 R 1482 0 R] +/Parent 2163 0 R +/Kids [1436 0 R 1442 0 R 1446 0 R 1450 0 R 1458 0 R 1465 0 R] >> endobj -1507 0 obj << +1497 0 obj << /Type /Pages /Count 6 -/Parent 2141 0 R -/Kids [1502 0 R 1509 0 R 1521 0 R 1525 0 R 1531 0 R 1541 0 R] +/Parent 2163 0 R +/Kids [1484 0 R 1499 0 R 1519 0 R 1525 0 R 1537 0 R 1541 0 R] >> endobj -1560 0 obj << +1556 0 obj << /Type /Pages /Count 6 -/Parent 2141 0 R -/Kids [1553 0 R 1562 0 R 1569 0 R 1577 0 R 1585 0 R 1594 0 R] +/Parent 2163 0 R +/Kids [1547 0 R 1558 0 R 1570 0 R 1578 0 R 1586 0 R 1593 0 R] >> endobj -1611 0 obj << +1609 0 obj << /Type /Pages /Count 6 -/Parent 2141 0 R -/Kids [1604 0 R 1613 0 R 1617 0 R 1623 0 R 1634 0 R 1638 0 R] +/Parent 2163 0 R +/Kids [1602 0 R 1612 0 R 1619 0 R 1630 0 R 1634 0 R 1640 0 R] >> endobj -1652 0 obj << +1654 0 obj << /Type /Pages /Count 6 -/Parent 2141 0 R -/Kids [1642 0 R 1654 0 R 1658 0 R 1665 0 R 1675 0 R 1734 0 R] +/Parent 2163 0 R +/Kids [1651 0 R 1656 0 R 1660 0 R 1671 0 R 1675 0 R 1682 0 R] >> endobj -1843 0 obj << +1750 0 obj << /Type /Pages /Count 6 -/Parent 2141 0 R -/Kids [1790 0 R 1845 0 R 1879 0 R 1888 0 R 1894 0 R 1899 0 R] +/Parent 2163 0 R +/Kids [1692 0 R 1752 0 R 1808 0 R 1862 0 R 1896 0 R 1905 0 R] >> endobj -1907 0 obj << +1915 0 obj << /Type /Pages /Count 6 -/Parent 2142 0 R -/Kids [1903 0 R 1909 0 R 1920 0 R 1925 0 R 1937 0 R 1948 0 R] +/Parent 2164 0 R +/Kids [1911 0 R 1917 0 R 1921 0 R 1926 0 R 1937 0 R 1942 0 R] >> endobj -1966 0 obj << +1964 0 obj << /Type /Pages /Count 6 -/Parent 2142 0 R -/Kids [1955 0 R 1968 0 R 1972 0 R 1983 0 R 1989 0 R 1993 0 R] +/Parent 2164 0 R +/Kids [1954 0 R 1966 0 R 1973 0 R 1985 0 R 1989 0 R 2000 0 R] >> endobj -2012 0 obj << +2009 0 obj << /Type /Pages /Count 6 -/Parent 2142 0 R -/Kids [2001 0 R 2014 0 R 2023 0 R 2027 0 R 2039 0 R 2043 0 R] +/Parent 2164 0 R +/Kids [2006 0 R 2011 0 R 2017 0 R 2030 0 R 2040 0 R 2044 0 R] >> endobj 2059 0 obj << /Type /Pages /Count 6 -/Parent 2142 0 R -/Kids [2050 0 R 2061 0 R 2066 0 R 2071 0 R 2081 0 R 2088 0 R] +/Parent 2164 0 R +/Kids [2056 0 R 2061 0 R 2067 0 R 2078 0 R 2083 0 R 2087 0 R] >> endobj -2102 0 obj << +2103 0 obj << /Type /Pages -/Count 3 -/Parent 2142 0 R -/Kids [2098 0 R 2104 0 R 2116 0 R] +/Count 6 +/Parent 2164 0 R +/Kids [2095 0 R 2105 0 R 2116 0 R 2121 0 R 2133 0 R 2139 0 R] >> endobj -2139 0 obj << +2161 0 obj << /Type /Pages /Count 36 -/Parent 2143 0 R -/Kids [711 0 R 951 0 R 1009 0 R 1066 0 R 1115 0 R 1158 0 R] +/Parent 2165 0 R +/Kids [715 0 R 956 0 R 1014 0 R 1071 0 R 1120 0 R 1161 0 R] >> endobj -2140 0 obj << +2162 0 obj << /Type /Pages /Count 36 -/Parent 2143 0 R -/Kids [1210 0 R 1250 0 R 1280 0 R 1323 0 R 1356 0 R 1398 0 R] +/Parent 2165 0 R +/Kids [1206 0 R 1248 0 R 1285 0 R 1325 0 R 1359 0 R 1401 0 R] >> endobj -2141 0 obj << +2163 0 obj << /Type /Pages /Count 36 -/Parent 2143 0 R -/Kids [1432 0 R 1507 0 R 1560 0 R 1611 0 R 1652 0 R 1843 0 R] +/Parent 2165 0 R +/Kids [1440 0 R 1497 0 R 1556 0 R 1609 0 R 1654 0 R 1750 0 R] >> endobj -2142 0 obj << +2164 0 obj << /Type /Pages -/Count 27 -/Parent 2143 0 R -/Kids [1907 0 R 1966 0 R 2012 0 R 2059 0 R 2102 0 R] +/Count 30 +/Parent 2165 0 R +/Kids [1915 0 R 1964 0 R 2009 0 R 2059 0 R 2103 0 R] >> endobj -2143 0 obj << +2165 0 obj << /Type /Pages -/Count 135 -/Kids [2139 0 R 2140 0 R 2141 0 R 2142 0 R] +/Count 138 +/Kids [2161 0 R 2162 0 R 2163 0 R 2164 0 R] >> endobj -2144 0 obj << +2166 0 obj << /Type /Outlines /First 7 0 R -/Last 647 0 R +/Last 651 0 R /Count 10 >> endobj +703 0 obj << +/Title 704 0 R +/A 701 0 R +/Parent 651 0 R +/Prev 699 0 R +>> endobj 699 0 obj << /Title 700 0 R /A 697 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 695 0 R +/Next 703 0 R >> endobj 695 0 obj << /Title 696 0 R /A 693 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 691 0 R /Next 699 0 R >> endobj 691 0 obj << /Title 692 0 R /A 689 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 687 0 R /Next 695 0 R >> endobj 687 0 obj << /Title 688 0 R /A 685 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 683 0 R /Next 691 0 R >> endobj 683 0 obj << /Title 684 0 R /A 681 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 679 0 R /Next 687 0 R >> endobj 679 0 obj << /Title 680 0 R /A 677 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 675 0 R /Next 683 0 R >> endobj 675 0 obj << /Title 676 0 R /A 673 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 671 0 R /Next 679 0 R >> endobj 671 0 obj << /Title 672 0 R /A 669 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 667 0 R /Next 675 0 R >> endobj 667 0 obj << /Title 668 0 R /A 665 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 663 0 R /Next 671 0 R >> endobj 663 0 obj << /Title 664 0 R /A 661 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 659 0 R /Next 667 0 R >> endobj 659 0 obj << /Title 660 0 R /A 657 0 R -/Parent 647 0 R +/Parent 651 0 R /Prev 655 0 R /Next 663 0 R >> endobj 655 0 obj << /Title 656 0 R /A 653 0 R -/Parent 647 0 R -/Prev 651 0 R +/Parent 651 0 R /Next 659 0 R >> endobj 651 0 obj << /Title 652 0 R /A 649 0 R -/Parent 647 0 R -/Next 655 0 R +/Parent 2166 0 R +/Prev 615 0 R +/First 655 0 R +/Last 703 0 R +/Count -13 >> endobj 647 0 obj << /Title 648 0 R /A 645 0 R -/Parent 2144 0 R -/Prev 611 0 R -/First 651 0 R -/Last 699 0 R -/Count -13 +/Parent 635 0 R +/Prev 643 0 R >> endobj 643 0 obj << /Title 644 0 R /A 641 0 R -/Parent 631 0 R +/Parent 635 0 R /Prev 639 0 R +/Next 647 0 R >> endobj 639 0 obj << /Title 640 0 R /A 637 0 R -/Parent 631 0 R -/Prev 635 0 R +/Parent 635 0 R /Next 643 0 R >> endobj 635 0 obj << /Title 636 0 R /A 633 0 R -/Parent 631 0 R -/Next 639 0 R +/Parent 615 0 R +/Prev 627 0 R +/First 639 0 R +/Last 647 0 R +/Count -3 >> endobj 631 0 obj << /Title 632 0 R /A 629 0 R -/Parent 611 0 R -/Prev 623 0 R -/First 635 0 R -/Last 643 0 R -/Count -3 +/Parent 627 0 R >> endobj 627 0 obj << /Title 628 0 R /A 625 0 R -/Parent 623 0 R +/Parent 615 0 R +/Prev 619 0 R +/Next 635 0 R +/First 631 0 R +/Last 631 0 R +/Count -1 >> endobj 623 0 obj << /Title 624 0 R /A 621 0 R -/Parent 611 0 R -/Prev 615 0 R -/Next 631 0 R -/First 627 0 R -/Last 627 0 R -/Count -1 +/Parent 619 0 R >> endobj 619 0 obj << /Title 620 0 R /A 617 0 R /Parent 615 0 R +/Next 627 0 R +/First 623 0 R +/Last 623 0 R +/Count -1 >> endobj 615 0 obj << /Title 616 0 R /A 613 0 R -/Parent 611 0 R -/Next 623 0 R +/Parent 2166 0 R +/Prev 595 0 R +/Next 651 0 R /First 619 0 R -/Last 619 0 R -/Count -1 +/Last 635 0 R +/Count -3 >> endobj 611 0 obj << /Title 612 0 R /A 609 0 R -/Parent 2144 0 R -/Prev 591 0 R -/Next 647 0 R -/First 615 0 R -/Last 631 0 R -/Count -3 +/Parent 595 0 R +/Prev 607 0 R >> endobj 607 0 obj << /Title 608 0 R /A 605 0 R -/Parent 591 0 R -/Prev 603 0 R +/Parent 595 0 R +/Prev 599 0 R +/Next 611 0 R >> endobj 603 0 obj << /Title 604 0 R /A 601 0 R -/Parent 591 0 R -/Prev 595 0 R -/Next 607 0 R +/Parent 599 0 R >> endobj 599 0 obj << /Title 600 0 R /A 597 0 R /Parent 595 0 R +/Next 607 0 R +/First 603 0 R +/Last 603 0 R +/Count -1 >> endobj 595 0 obj << /Title 596 0 R /A 593 0 R -/Parent 591 0 R -/Next 603 0 R +/Parent 2166 0 R +/Prev 571 0 R +/Next 615 0 R /First 599 0 R -/Last 599 0 R -/Count -1 +/Last 611 0 R +/Count -3 >> endobj 591 0 obj << /Title 592 0 R /A 589 0 R -/Parent 2144 0 R -/Prev 567 0 R -/Next 611 0 R -/First 595 0 R -/Last 607 0 R -/Count -3 +/Parent 571 0 R +/Prev 579 0 R >> endobj 587 0 obj << /Title 588 0 R /A 585 0 R -/Parent 567 0 R -/Prev 575 0 R +/Parent 579 0 R +/Prev 583 0 R >> endobj 583 0 obj << /Title 584 0 R /A 581 0 R -/Parent 575 0 R -/Prev 579 0 R +/Parent 579 0 R +/Next 587 0 R >> endobj 579 0 obj << /Title 580 0 R /A 577 0 R -/Parent 575 0 R -/Next 583 0 R +/Parent 571 0 R +/Prev 575 0 R +/Next 591 0 R +/First 583 0 R +/Last 587 0 R +/Count -2 >> endobj 575 0 obj << /Title 576 0 R /A 573 0 R -/Parent 567 0 R -/Prev 571 0 R -/Next 587 0 R -/First 579 0 R -/Last 583 0 R -/Count -2 +/Parent 571 0 R +/Next 579 0 R >> endobj 571 0 obj << /Title 572 0 R /A 569 0 R -/Parent 567 0 R -/Next 575 0 R +/Parent 2166 0 R +/Prev 243 0 R +/Next 595 0 R +/First 575 0 R +/Last 591 0 R +/Count -3 >> endobj 567 0 obj << /Title 568 0 R /A 565 0 R -/Parent 2144 0 R -/Prev 243 0 R -/Next 591 0 R -/First 571 0 R -/Last 587 0 R -/Count -3 +/Parent 547 0 R +/Prev 563 0 R >> endobj 563 0 obj << /Title 564 0 R /A 561 0 R -/Parent 543 0 R +/Parent 547 0 R /Prev 559 0 R +/Next 567 0 R >> endobj 559 0 obj << /Title 560 0 R /A 557 0 R -/Parent 543 0 R +/Parent 547 0 R /Prev 555 0 R /Next 563 0 R >> endobj 555 0 obj << /Title 556 0 R /A 553 0 R -/Parent 543 0 R +/Parent 547 0 R /Prev 551 0 R /Next 559 0 R >> endobj 551 0 obj << /Title 552 0 R /A 549 0 R -/Parent 543 0 R -/Prev 547 0 R +/Parent 547 0 R /Next 555 0 R >> endobj 547 0 obj << /Title 548 0 R /A 545 0 R -/Parent 543 0 R -/Next 551 0 R +/Parent 539 0 R +/Prev 543 0 R +/First 551 0 R +/Last 567 0 R +/Count -5 >> endobj 543 0 obj << /Title 544 0 R /A 541 0 R -/Parent 535 0 R -/Prev 539 0 R -/First 547 0 R -/Last 563 0 R -/Count -5 +/Parent 539 0 R +/Next 547 0 R >> endobj 539 0 obj << /Title 540 0 R /A 537 0 R -/Parent 535 0 R -/Next 543 0 R +/Parent 243 0 R +/Prev 483 0 R +/First 543 0 R +/Last 547 0 R +/Count -2 >> endobj 535 0 obj << /Title 536 0 R /A 533 0 R -/Parent 243 0 R -/Prev 483 0 R -/First 539 0 R -/Last 543 0 R -/Count -2 +/Parent 483 0 R +/Prev 531 0 R >> endobj 531 0 obj << /Title 532 0 R /A 529 0 R /Parent 483 0 R -/Prev 527 0 R +/Prev 511 0 R +/Next 535 0 R >> endobj 527 0 obj << /Title 528 0 R /A 525 0 R -/Parent 483 0 R -/Prev 511 0 R -/Next 531 0 R +/Parent 511 0 R +/Prev 523 0 R >> endobj 523 0 obj << /Title 524 0 R /A 521 0 R /Parent 511 0 R /Prev 519 0 R +/Next 527 0 R >> endobj 519 0 obj << /Title 520 0 R @@ -11223,10 +11375,10 @@ endobj /A 509 0 R /Parent 483 0 R /Prev 507 0 R -/Next 527 0 R +/Next 531 0 R /First 515 0 R -/Last 523 0 R -/Count -3 +/Last 527 0 R +/Count -4 >> endobj 507 0 obj << /Title 508 0 R @@ -11275,9 +11427,9 @@ endobj /A 481 0 R /Parent 243 0 R /Prev 275 0 R -/Next 535 0 R +/Next 539 0 R /First 487 0 R -/Last 531 0 R +/Last 535 0 R /Count -7 >> endobj 479 0 obj << @@ -11702,11 +11854,11 @@ endobj 243 0 obj << /Title 244 0 R /A 241 0 R -/Parent 2144 0 R +/Parent 2166 0 R /Prev 231 0 R -/Next 567 0 R +/Next 571 0 R /First 247 0 R -/Last 535 0 R +/Last 539 0 R /Count -4 >> endobj 239 0 obj << @@ -11724,7 +11876,7 @@ endobj 231 0 obj << /Title 232 0 R /A 229 0 R -/Parent 2144 0 R +/Parent 2166 0 R /Prev 131 0 R /Next 243 0 R /First 235 0 R @@ -11906,7 +12058,7 @@ endobj 131 0 obj << /Title 132 0 R /A 129 0 R -/Parent 2144 0 R +/Parent 2166 0 R /Prev 91 0 R /Next 231 0 R /First 135 0 R @@ -11980,7 +12132,7 @@ endobj 91 0 obj << /Title 92 0 R /A 89 0 R -/Parent 2144 0 R +/Parent 2166 0 R /Prev 67 0 R /Next 131 0 R /First 95 0 R @@ -12023,7 +12175,7 @@ endobj 67 0 obj << /Title 68 0 R /A 65 0 R -/Parent 2144 0 R +/Parent 2166 0 R /Prev 7 0 R /Next 91 0 R /First 71 0 R @@ -12132,1760 +12284,1731 @@ endobj 7 0 obj << /Title 8 0 R /A 5 0 R -/Parent 2144 0 R +/Parent 2166 0 R /Next 67 0 R /First 11 0 R /Last 23 0 R /Count -4 >> endobj -2145 0 obj << -/Names [(Access_Control_Lists) 1621 0 R (Bv9ARM.ch01) 942 0 R (Bv9ARM.ch02) 988 0 R (Bv9ARM.ch03) 1005 0 R (Bv9ARM.ch04) 1054 0 R (Bv9ARM.ch05) 1142 0 R (Bv9ARM.ch06) 1153 0 R (Bv9ARM.ch07) 1620 0 R (Bv9ARM.ch08) 1645 0 R (Bv9ARM.ch09) 1661 0 R (Bv9ARM.ch10) 1882 0 R (Configuration_File_Grammar) 1178 0 R (DNSSEC) 1121 0 R (Doc-Start) 707 0 R (Setting_TTLs) 1546 0 R (acache) 995 0 R (access_control) 1307 0 R (acl) 1186 0 R (address_match_lists) 1159 0 R (admin_tools) 1028 0 R (appendix.A) 610 0 R (appendix.B) 646 0 R (bibliography) 1669 0 R (boolean_options) 1070 0 R (builtin) 1385 0 R (chapter*.1) 742 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 230 0 R (chapter.6) 242 0 R (chapter.7) 566 0 R (chapter.8) 590 0 R (cite.RFC1033) 1796 0 R (cite.RFC1034) 1681 0 R (cite.RFC1035) 1683 0 R (cite.RFC1101) 1778 0 R (cite.RFC1123) 1780 0 R (cite.RFC1183) 1740 0 R (cite.RFC1464) 1818 0 R (cite.RFC1535) 1726 0 R (cite.RFC1536) 1728 0 R (cite.RFC1537) 1798 0 R (cite.RFC1591) 1782 0 R (cite.RFC1706) 1742 0 R (cite.RFC1712) 1838 0 R (cite.RFC1713) 1820 0 R (cite.RFC1794) 1822 0 R (cite.RFC1876) 1744 0 R (cite.RFC1912) 1800 0 R (cite.RFC1982) 1730 0 R (cite.RFC1995) 1688 0 R (cite.RFC1996) 1690 0 R (cite.RFC2010) 1802 0 R (cite.RFC2052) 1746 0 R (cite.RFC2065) 1851 0 R (cite.RFC2136) 1692 0 R (cite.RFC2137) 1853 0 R (cite.RFC2163) 1748 0 R (cite.RFC2168) 1750 0 R (cite.RFC2181) 1694 0 R (cite.RFC2219) 1804 0 R (cite.RFC2230) 1752 0 R (cite.RFC2240) 1824 0 R (cite.RFC2308) 1696 0 R (cite.RFC2317) 1784 0 R (cite.RFC2345) 1826 0 R (cite.RFC2352) 1828 0 R (cite.RFC2535) 1855 0 R (cite.RFC2536) 1754 0 R (cite.RFC2537) 1756 0 R (cite.RFC2538) 1758 0 R (cite.RFC2539) 1760 0 R (cite.RFC2540) 1762 0 R (cite.RFC2671) 1698 0 R (cite.RFC2672) 1700 0 R (cite.RFC2673) 1840 0 R (cite.RFC2782) 1764 0 R (cite.RFC2825) 1808 0 R (cite.RFC2826) 1786 0 R (cite.RFC2845) 1702 0 R (cite.RFC2874) 1842 0 R (cite.RFC2915) 1766 0 R (cite.RFC2929) 1788 0 R (cite.RFC2930) 1704 0 R (cite.RFC2931) 1706 0 R (cite.RFC3007) 1708 0 R (cite.RFC3008) 1857 0 R (cite.RFC3071) 1830 0 R (cite.RFC3090) 1859 0 R (cite.RFC3110) 1768 0 R (cite.RFC3123) 1770 0 R (cite.RFC3225) 1714 0 R (cite.RFC3258) 1832 0 R (cite.RFC3445) 1861 0 R (cite.RFC3490) 1810 0 R (cite.RFC3491) 1812 0 R (cite.RFC3492) 1814 0 R (cite.RFC3596) 1772 0 R (cite.RFC3597) 1774 0 R (cite.RFC3645) 1710 0 R (cite.RFC3655) 1863 0 R (cite.RFC3658) 1865 0 R (cite.RFC3755) 1867 0 R (cite.RFC3757) 1869 0 R (cite.RFC3833) 1716 0 R (cite.RFC3845) 1871 0 R (cite.RFC3901) 1834 0 R (cite.RFC4033) 1718 0 R (cite.RFC4034) 1720 0 R (cite.RFC4035) 1722 0 R (cite.RFC4074) 1732 0 R (cite.RFC974) 1685 0 R (cite.id2505777) 1876 0 R (clients-per-query) 1592 0 R (configuration_file_elements) 1154 0 R (controls_statement_definition_and_usage) 1041 0 R (diagnostic_tools) 976 0 R (dynamic_update) 1064 0 R (dynamic_update_policies) 1116 0 R (dynamic_update_security) 1316 0 R (empty) 1393 0 R (historical_dns_information) 1663 0 R (id2466552) 943 0 R (id2466576) 944 0 R (id2467534) 945 0 R (id2467544) 946 0 R (id2467716) 958 0 R (id2467737) 959 0 R (id2467771) 960 0 R (id2467856) 963 0 R (id2467948) 956 0 R (id2470253) 970 0 R (id2470277) 973 0 R (id2470375) 974 0 R (id2470396) 975 0 R (id2470426) 981 0 R (id2470530) 982 0 R (id2470556) 983 0 R (id2470590) 989 0 R (id2470617) 990 0 R (id2470630) 991 0 R (id2470724) 994 0 R (id2470734) 1000 0 R (id2470766) 1007 0 R (id2470782) 1008 0 R (id2470805) 1014 0 R (id2470822) 1015 0 R (id2471227) 1018 0 R (id2471233) 1019 0 R (id2473009) 1046 0 R (id2473020) 1047 0 R (id2473420) 1079 0 R (id2473438) 1080 0 R (id2473942) 1096 0 R (id2473959) 1097 0 R (id2473997) 1102 0 R (id2474016) 1103 0 R (id2474026) 1104 0 R (id2474069) 1105 0 R (id2474263) 1110 0 R (id2474311) 1112 0 R (id2474325) 1113 0 R (id2474374) 1114 0 R (id2474510) 1122 0 R (id2474589) 1123 0 R (id2474670) 1128 0 R (id2474953) 1133 0 R (id2475083) 1135 0 R (id2475105) 1136 0 R (id2475138) 1143 0 R (id2475285) 1155 0 R (id2476147) 1164 0 R (id2476174) 1169 0 R (id2476380) 1170 0 R (id2476395) 1171 0 R (id2476425) 1177 0 R (id2476500) 1179 0 R (id2477079) 1185 0 R (id2477122) 1187 0 R (id2477269) 1189 0 R (id2477629) 1196 0 R (id2477646) 1197 0 R (id2477806) 1203 0 R (id2477830) 1204 0 R (id2477921) 1208 0 R (id2478115) 1209 0 R (id2478167) 1215 0 R (id2478997) 1226 0 R (id2479731) 1236 0 R (id2479859) 1237 0 R (id2480244) 1239 0 R (id2480317) 1244 0 R (id2480381) 1247 0 R (id2480425) 1248 0 R (id2480440) 1249 0 R (id2482851) 1278 0 R (id2484684) 1304 0 R (id2484743) 1306 0 R (id2485249) 1321 0 R (id2486520) 1340 0 R (id2486580) 1342 0 R (id2486934) 1354 0 R (id2487436) 1369 0 R (id2489703) 1411 0 R (id2489789) 1416 0 R (id2489841) 1417 0 R (id2489923) 1423 0 R (id2491460) 1437 0 R (id2491467) 1438 0 R (id2491473) 1439 0 R (id2491963) 1446 0 R (id2491996) 1452 0 R (id2493692) 1505 0 R (id2494007) 1512 0 R (id2494025) 1513 0 R (id2494045) 1516 0 R (id2494282) 1518 0 R (id2495452) 1528 0 R (id2495580) 1534 0 R (id2495602) 1535 0 R (id2495964) 1537 0 R (id2496101) 1539 0 R (id2496119) 1544 0 R (id2496660) 1547 0 R (id2496785) 1549 0 R (id2496800) 1550 0 R (id2496980) 1556 0 R (id2497002) 1557 0 R (id2497063) 1558 0 R (id2497132) 1559 0 R (id2497169) 1565 0 R (id2497299) 1566 0 R (id2497798) 1573 0 R (id2498301) 1581 0 R (id2498307) 1582 0 R (id2499706) 1589 0 R (id2499713) 1590 0 R (id2500089) 1597 0 R (id2500094) 1598 0 R (id2501108) 1600 0 R (id2501140) 1601 0 R (id2501549) 1610 0 R (id2501792) 1630 0 R (id2501941) 1631 0 R (id2502069) 1632 0 R (id2502149) 1646 0 R (id2502154) 1647 0 R (id2502166) 1648 0 R (id2502251) 1649 0 R (id2502313) 1662 0 R (id2502485) 1668 0 R (id2502741) 1673 0 R (id2502743) 1679 0 R (id2502752) 1684 0 R (id2502775) 1680 0 R (id2502798) 1682 0 R (id2502835) 1693 0 R (id2502861) 1695 0 R (id2502887) 1687 0 R (id2502912) 1689 0 R (id2502935) 1691 0 R (id2502990) 1697 0 R (id2503017) 1699 0 R (id2503044) 1701 0 R (id2503106) 1703 0 R (id2503136) 1705 0 R (id2503165) 1707 0 R (id2503192) 1709 0 R (id2503267) 1712 0 R (id2503274) 1713 0 R (id2503301) 1715 0 R (id2503337) 1717 0 R (id2503402) 1719 0 R (id2503467) 1721 0 R (id2503532) 1724 0 R (id2503541) 1725 0 R (id2503635) 1727 0 R (id2503703) 1729 0 R (id2503738) 1731 0 R (id2503779) 1738 0 R (id2503784) 1739 0 R (id2503842) 1741 0 R (id2503879) 1749 0 R (id2503914) 1743 0 R (id2503969) 1745 0 R (id2504007) 1747 0 R (id2504033) 1751 0 R (id2504058) 1753 0 R (id2504085) 1755 0 R (id2504112) 1757 0 R (id2504151) 1759 0 R (id2504181) 1761 0 R (id2504211) 1763 0 R (id2504253) 1765 0 R (id2504286) 1767 0 R (id2504313) 1769 0 R (id2504337) 1771 0 R (id2504394) 1773 0 R (id2504419) 1776 0 R (id2504426) 1777 0 R (id2504452) 1779 0 R (id2504474) 1781 0 R (id2504498) 1783 0 R (id2504612) 1785 0 R (id2504635) 1787 0 R (id2504685) 1794 0 R (id2504693) 1795 0 R (id2504716) 1797 0 R (id2504743) 1799 0 R (id2504770) 1801 0 R (id2504806) 1803 0 R (id2504846) 1806 0 R (id2504852) 1807 0 R (id2504884) 1809 0 R (id2504930) 1811 0 R (id2504965) 1813 0 R (id2504992) 1816 0 R (id2505010) 1817 0 R (id2505032) 1819 0 R (id2505058) 1821 0 R (id2505083) 1823 0 R (id2505107) 1825 0 R (id2505153) 1827 0 R (id2505176) 1829 0 R (id2505203) 1831 0 R (id2505228) 1833 0 R (id2505266) 1836 0 R (id2505272) 1837 0 R (id2505330) 1839 0 R (id2505356) 1841 0 R (id2505393) 1849 0 R (id2505404) 1850 0 R (id2505444) 1852 0 R (id2505470) 1854 0 R (id2505500) 1856 0 R (id2505526) 1858 0 R (id2505553) 1860 0 R (id2505589) 1862 0 R (id2505625) 1864 0 R (id2505652) 1866 0 R (id2505678) 1868 0 R (id2505723) 1870 0 R (id2505765) 1873 0 R (id2505774) 1875 0 R (id2505777) 1877 0 R (incremental_zone_transfers) 1076 0 R (internet_drafts) 1872 0 R (ipv6addresses) 1137 0 R (journal) 1065 0 R (lwresd) 1144 0 R (man.dig) 1883 0 R (man.dnssec-dsfromkey) 1931 0 R (man.dnssec-keyfromlabel) 1945 0 R (man.dnssec-keygen) 1961 0 R (man.dnssec-signzone) 1979 0 R (man.host) 1916 0 R (man.named) 2033 0 R (man.named-checkconf) 2004 0 R (man.named-checkzone) 2017 0 R (man.nsupdate) 2055 0 R (man.rndc) 2077 0 R (man.rndc-confgen) 2110 0 R (man.rndc.conf) 2093 0 R (notify) 1055 0 R (options) 1263 0 R (page.1) 706 0 R (page.10) 980 0 R (page.100) 1667 0 R (page.101) 1677 0 R (page.102) 1736 0 R (page.103) 1792 0 R (page.104) 1847 0 R (page.105) 1881 0 R (page.106) 1890 0 R (page.107) 1896 0 R (page.108) 1901 0 R (page.109) 1905 0 R (page.11) 987 0 R (page.110) 1911 0 R (page.111) 1922 0 R (page.112) 1927 0 R (page.113) 1939 0 R (page.114) 1950 0 R (page.115) 1957 0 R (page.116) 1970 0 R (page.117) 1974 0 R (page.118) 1985 0 R (page.119) 1991 0 R (page.12) 999 0 R (page.120) 1995 0 R (page.121) 2003 0 R (page.122) 2016 0 R (page.123) 2025 0 R (page.124) 2029 0 R (page.125) 2041 0 R (page.126) 2045 0 R (page.127) 2052 0 R (page.128) 2063 0 R (page.129) 2068 0 R (page.13) 1004 0 R (page.130) 2073 0 R (page.131) 2083 0 R (page.132) 2090 0 R (page.133) 2100 0 R (page.134) 2106 0 R (page.135) 2118 0 R (page.14) 1013 0 R (page.15) 1024 0 R (page.16) 1032 0 R (page.17) 1039 0 R (page.18) 1045 0 R (page.19) 1053 0 R (page.2) 731 0 R (page.20) 1075 0 R (page.21) 1085 0 R (page.22) 1090 0 R (page.23) 1094 0 R (page.24) 1101 0 R (page.25) 1109 0 R (page.26) 1120 0 R (page.27) 1127 0 R (page.28) 1132 0 R (page.29) 1141 0 R (page.3) 741 0 R (page.30) 1148 0 R (page.31) 1152 0 R (page.32) 1163 0 R (page.33) 1168 0 R (page.34) 1176 0 R (page.35) 1184 0 R (page.36) 1193 0 R (page.37) 1202 0 R (page.38) 1214 0 R (page.39) 1219 0 R (page.4) 796 0 R (page.40) 1225 0 R (page.41) 1231 0 R (page.42) 1235 0 R (page.43) 1243 0 R (page.44) 1254 0 R (page.45) 1258 0 R (page.46) 1262 0 R (page.47) 1267 0 R (page.48) 1273 0 R (page.49) 1277 0 R (page.5) 860 0 R (page.50) 1284 0 R (page.51) 1295 0 R (page.52) 1299 0 R (page.53) 1303 0 R (page.54) 1313 0 R (page.55) 1320 0 R (page.56) 1327 0 R (page.57) 1331 0 R (page.58) 1335 0 R (page.59) 1339 0 R (page.6) 922 0 R (page.60) 1347 0 R (page.61) 1353 0 R (page.62) 1360 0 R (page.63) 1367 0 R (page.64) 1374 0 R (page.65) 1380 0 R (page.66) 1392 0 R (page.67) 1397 0 R (page.68) 1402 0 R (page.69) 1407 0 R (page.7) 941 0 R (page.70) 1415 0 R (page.71) 1422 0 R (page.72) 1427 0 R (page.73) 1431 0 R (page.74) 1436 0 R (page.75) 1444 0 R (page.76) 1451 0 R (page.77) 1470 0 R (page.78) 1484 0 R (page.79) 1504 0 R (page.8) 955 0 R (page.80) 1511 0 R (page.81) 1523 0 R (page.82) 1527 0 R (page.83) 1533 0 R (page.84) 1543 0 R (page.85) 1555 0 R (page.86) 1564 0 R (page.87) 1571 0 R (page.88) 1579 0 R (page.89) 1587 0 R (page.9) 969 0 R (page.90) 1596 0 R (page.91) 1606 0 R (page.92) 1615 0 R (page.93) 1619 0 R (page.94) 1625 0 R (page.95) 1636 0 R (page.96) 1640 0 R (page.97) 1644 0 R (page.98) 1656 0 R (page.99) 1660 0 R (proposed_standards) 1081 0 R (query_address) 1322 0 R (rfcs) 965 0 R (rndc) 1198 0 R (root_delegation_only) 1447 0 R (rrset_ordering) 1020 0 R (sample_configuration) 1006 0 R (section*.10) 1805 0 R (section*.100) 2091 0 R (section*.101) 2092 0 R (section*.102) 2094 0 R (section*.103) 2095 0 R (section*.104) 2096 0 R (section*.105) 2101 0 R (section*.106) 2107 0 R (section*.107) 2108 0 R (section*.108) 2109 0 R (section*.109) 2111 0 R (section*.11) 1815 0 R (section*.110) 2112 0 R (section*.111) 2113 0 R (section*.112) 2114 0 R (section*.113) 2119 0 R (section*.114) 2120 0 R (section*.115) 2121 0 R (section*.12) 1835 0 R (section*.13) 1848 0 R (section*.14) 1874 0 R (section*.15) 1884 0 R (section*.16) 1885 0 R (section*.17) 1886 0 R (section*.18) 1891 0 R (section*.19) 1892 0 R (section*.2) 1672 0 R (section*.20) 1897 0 R (section*.21) 1906 0 R (section*.22) 1912 0 R (section*.23) 1913 0 R (section*.24) 1914 0 R (section*.25) 1915 0 R (section*.26) 1917 0 R (section*.27) 1918 0 R (section*.28) 1923 0 R (section*.29) 1928 0 R (section*.3) 1678 0 R (section*.30) 1929 0 R (section*.31) 1930 0 R (section*.32) 1932 0 R (section*.33) 1933 0 R (section*.34) 1934 0 R (section*.35) 1935 0 R (section*.36) 1940 0 R (section*.37) 1941 0 R (section*.38) 1942 0 R (section*.39) 1943 0 R (section*.4) 1686 0 R (section*.40) 1944 0 R (section*.41) 1946 0 R (section*.42) 1951 0 R (section*.43) 1952 0 R (section*.44) 1953 0 R (section*.45) 1958 0 R (section*.46) 1959 0 R (section*.47) 1960 0 R (section*.48) 1962 0 R (section*.49) 1963 0 R (section*.5) 1711 0 R (section*.50) 1964 0 R (section*.51) 1965 0 R (section*.52) 1975 0 R (section*.53) 1976 0 R (section*.54) 1977 0 R (section*.55) 1978 0 R (section*.56) 1980 0 R (section*.57) 1981 0 R (section*.58) 1986 0 R (section*.59) 1987 0 R (section*.6) 1723 0 R (section*.60) 1996 0 R (section*.61) 1997 0 R (section*.62) 1998 0 R (section*.63) 1999 0 R (section*.64) 2005 0 R (section*.65) 2006 0 R (section*.66) 2007 0 R (section*.67) 2008 0 R (section*.68) 2009 0 R (section*.69) 2010 0 R (section*.7) 1737 0 R (section*.70) 2011 0 R (section*.71) 2018 0 R (section*.72) 2019 0 R (section*.73) 2020 0 R (section*.74) 2021 0 R (section*.75) 2030 0 R (section*.76) 2031 0 R (section*.77) 2032 0 R (section*.78) 2034 0 R (section*.79) 2035 0 R (section*.8) 1775 0 R (section*.80) 2036 0 R (section*.81) 2037 0 R (section*.82) 2046 0 R (section*.83) 2047 0 R (section*.84) 2048 0 R (section*.85) 2053 0 R (section*.86) 2054 0 R (section*.87) 2056 0 R (section*.88) 2057 0 R (section*.89) 2058 0 R (section*.9) 1793 0 R (section*.90) 2064 0 R (section*.91) 2069 0 R (section*.92) 2074 0 R (section*.93) 2075 0 R (section*.94) 2076 0 R (section*.95) 2078 0 R (section*.96) 2079 0 R (section*.97) 2084 0 R (section*.98) 2085 0 R (section*.99) 2086 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 234 0 R (section.5.2) 238 0 R (section.6.1) 246 0 R (section.6.2) 274 0 R (section.6.3) 482 0 R (section.6.4) 534 0 R (section.7.1) 570 0 R (section.7.2) 574 0 R (section.7.3) 586 0 R (section.8.1) 594 0 R (section.8.2) 602 0 R (section.8.3) 606 0 R (section.A.1) 614 0 R (section.A.2) 622 0 R (section.A.3) 630 0 R (section.B.1) 650 0 R (section.B.10) 686 0 R (section.B.11) 690 0 R (section.B.12) 694 0 R (section.B.13) 698 0 R (section.B.2) 654 0 R (section.B.3) 658 0 R (section.B.4) 662 0 R (section.B.5) 666 0 R (section.B.6) 670 0 R (section.B.7) 674 0 R (section.B.8) 678 0 R (section.B.9) 682 0 R (server_resource_limits) 1348 0 R (server_statement_definition_and_usage) 1291 0 R (server_statement_grammar) 1403 0 R (statistics) 1572 0 R (statistics_counters) 1580 0 R (statschannels) 1410 0 R (statsfile) 1269 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.2) 226 0 R (subsection.6.1.1) 250 0 R (subsection.6.1.2) 262 0 R (subsection.6.2.1) 278 0 R (subsection.6.2.10) 314 0 R (subsection.6.2.11) 330 0 R (subsection.6.2.12) 334 0 R (subsection.6.2.13) 338 0 R (subsection.6.2.14) 342 0 R (subsection.6.2.15) 346 0 R (subsection.6.2.16) 350 0 R (subsection.6.2.17) 426 0 R (subsection.6.2.18) 430 0 R (subsection.6.2.19) 434 0 R (subsection.6.2.2) 282 0 R (subsection.6.2.20) 438 0 R (subsection.6.2.21) 442 0 R (subsection.6.2.22) 446 0 R (subsection.6.2.23) 450 0 R (subsection.6.2.24) 454 0 R (subsection.6.2.25) 458 0 R (subsection.6.2.26) 462 0 R (subsection.6.2.3) 286 0 R (subsection.6.2.4) 290 0 R (subsection.6.2.5) 294 0 R (subsection.6.2.6) 298 0 R (subsection.6.2.7) 302 0 R (subsection.6.2.8) 306 0 R (subsection.6.2.9) 310 0 R (subsection.6.3.1) 486 0 R (subsection.6.3.2) 498 0 R (subsection.6.3.3) 502 0 R (subsection.6.3.4) 506 0 R (subsection.6.3.5) 510 0 R (subsection.6.3.6) 526 0 R (subsection.6.3.7) 530 0 R (subsection.6.4.1) 542 0 R (subsection.7.2.1) 578 0 R (subsection.7.2.2) 582 0 R (subsection.8.1.1) 598 0 R (subsection.A.1.1) 618 0 R (subsection.A.2.1) 626 0 R (subsection.A.3.1) 634 0 R (subsection.A.3.2) 638 0 R (subsection.A.3.3) 642 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 254 0 R (subsubsection.6.1.1.2) 258 0 R (subsubsection.6.1.2.1) 266 0 R (subsubsection.6.1.2.2) 270 0 R (subsubsection.6.2.10.1) 318 0 R (subsubsection.6.2.10.2) 322 0 R (subsubsection.6.2.10.3) 326 0 R (subsubsection.6.2.16.1) 354 0 R (subsubsection.6.2.16.10) 390 0 R (subsubsection.6.2.16.11) 394 0 R (subsubsection.6.2.16.12) 398 0 R (subsubsection.6.2.16.13) 402 0 R (subsubsection.6.2.16.14) 406 0 R (subsubsection.6.2.16.15) 410 0 R (subsubsection.6.2.16.16) 414 0 R (subsubsection.6.2.16.17) 418 0 R (subsubsection.6.2.16.18) 422 0 R (subsubsection.6.2.16.2) 358 0 R (subsubsection.6.2.16.3) 362 0 R (subsubsection.6.2.16.4) 366 0 R (subsubsection.6.2.16.5) 370 0 R (subsubsection.6.2.16.6) 374 0 R (subsubsection.6.2.16.7) 378 0 R (subsubsection.6.2.16.8) 382 0 R (subsubsection.6.2.16.9) 386 0 R (subsubsection.6.2.26.1) 466 0 R (subsubsection.6.2.26.2) 470 0 R (subsubsection.6.2.26.3) 474 0 R (subsubsection.6.2.26.4) 478 0 R (subsubsection.6.3.1.1) 490 0 R (subsubsection.6.3.1.2) 494 0 R (subsubsection.6.3.5.1) 514 0 R (subsubsection.6.3.5.2) 518 0 R (subsubsection.6.3.5.3) 522 0 R (subsubsection.6.4.0.1) 538 0 R (subsubsection.6.4.1.1) 546 0 R (subsubsection.6.4.1.2) 550 0 R (subsubsection.6.4.1.3) 554 0 R (subsubsection.6.4.1.4) 558 0 R (subsubsection.6.4.1.5) 562 0 R (table.1.1) 947 0 R (table.1.2) 957 0 R (table.3.1) 1016 0 R (table.3.2) 1048 0 R (table.6.1) 1156 0 R (table.6.10) 1517 0 R (table.6.11) 1519 0 R (table.6.12) 1529 0 R (table.6.13) 1536 0 R (table.6.14) 1538 0 R (table.6.15) 1545 0 R (table.6.16) 1548 0 R (table.6.17) 1551 0 R (table.6.18) 1567 0 R (table.6.19) 1574 0 R (table.6.2) 1180 0 R (table.6.20) 1583 0 R (table.6.21) 1591 0 R (table.6.22) 1599 0 R (table.6.23) 1602 0 R (table.6.3) 1188 0 R (table.6.4) 1227 0 R (table.6.5) 1238 0 R (table.6.6) 1279 0 R (table.6.7) 1370 0 R (table.6.8) 1440 0 R (table.6.9) 1506 0 R (the_category_phrase) 1221 0 R (the_sortlist_statement) 1361 0 R (topology) 1355 0 R (tsig) 1095 0 R (tuning) 1375 0 R (types_of_resource_records_and_when_to_use_them) 964 0 R (view_statement_grammar) 1388 0 R (zone_statement_grammar) 1309 0 R (zone_transfers) 1071 0 R (zonefile_format) 1387 0 R] +2167 0 obj << +/Names [(Access_Control_Lists) 1638 0 R (Bv9ARM.ch01) 947 0 R (Bv9ARM.ch02) 993 0 R (Bv9ARM.ch03) 1010 0 R (Bv9ARM.ch04) 1059 0 R (Bv9ARM.ch05) 1158 0 R (Bv9ARM.ch06) 1170 0 R (Bv9ARM.ch07) 1637 0 R (Bv9ARM.ch08) 1663 0 R (Bv9ARM.ch09) 1678 0 R (Bv9ARM.ch10) 1899 0 R (Configuration_File_Grammar) 1194 0 R (DNSSEC) 1126 0 R (Doc-Start) 711 0 R (Setting_TTLs) 1563 0 R (acache) 1000 0 R (access_control) 1323 0 R (acl) 1202 0 R (address_match_lists) 1175 0 R (admin_tools) 1033 0 R (appendix.A) 614 0 R (appendix.B) 650 0 R (bibliography) 1686 0 R (boolean_options) 1075 0 R (builtin) 1407 0 R (chapter*.1) 746 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 230 0 R (chapter.6) 242 0 R (chapter.7) 570 0 R (chapter.8) 594 0 R (cite.RFC1033) 1814 0 R (cite.RFC1034) 1698 0 R (cite.RFC1035) 1700 0 R (cite.RFC1101) 1796 0 R (cite.RFC1123) 1798 0 R (cite.RFC1183) 1758 0 R (cite.RFC1464) 1836 0 R (cite.RFC1535) 1743 0 R (cite.RFC1536) 1745 0 R (cite.RFC1537) 1816 0 R (cite.RFC1591) 1800 0 R (cite.RFC1706) 1760 0 R (cite.RFC1712) 1856 0 R (cite.RFC1713) 1838 0 R (cite.RFC1794) 1840 0 R (cite.RFC1876) 1762 0 R (cite.RFC1912) 1818 0 R (cite.RFC1982) 1747 0 R (cite.RFC1995) 1705 0 R (cite.RFC1996) 1707 0 R (cite.RFC2010) 1820 0 R (cite.RFC2052) 1764 0 R (cite.RFC2065) 1868 0 R (cite.RFC2136) 1709 0 R (cite.RFC2137) 1870 0 R (cite.RFC2163) 1766 0 R (cite.RFC2168) 1768 0 R (cite.RFC2181) 1711 0 R (cite.RFC2219) 1822 0 R (cite.RFC2230) 1770 0 R (cite.RFC2240) 1842 0 R (cite.RFC2308) 1713 0 R (cite.RFC2317) 1802 0 R (cite.RFC2345) 1844 0 R (cite.RFC2352) 1846 0 R (cite.RFC2535) 1872 0 R (cite.RFC2536) 1772 0 R (cite.RFC2537) 1774 0 R (cite.RFC2538) 1776 0 R (cite.RFC2539) 1778 0 R (cite.RFC2540) 1780 0 R (cite.RFC2671) 1715 0 R (cite.RFC2672) 1717 0 R (cite.RFC2673) 1858 0 R (cite.RFC2782) 1782 0 R (cite.RFC2825) 1826 0 R (cite.RFC2826) 1804 0 R (cite.RFC2845) 1719 0 R (cite.RFC2874) 1860 0 R (cite.RFC2915) 1784 0 R (cite.RFC2929) 1806 0 R (cite.RFC2930) 1721 0 R (cite.RFC2931) 1723 0 R (cite.RFC3007) 1725 0 R (cite.RFC3008) 1874 0 R (cite.RFC3071) 1848 0 R (cite.RFC3090) 1876 0 R (cite.RFC3110) 1786 0 R (cite.RFC3123) 1788 0 R (cite.RFC3225) 1731 0 R (cite.RFC3258) 1850 0 R (cite.RFC3445) 1878 0 R (cite.RFC3490) 1828 0 R (cite.RFC3491) 1830 0 R (cite.RFC3492) 1832 0 R (cite.RFC3596) 1790 0 R (cite.RFC3597) 1792 0 R (cite.RFC3645) 1727 0 R (cite.RFC3655) 1880 0 R (cite.RFC3658) 1882 0 R (cite.RFC3755) 1884 0 R (cite.RFC3757) 1886 0 R (cite.RFC3833) 1733 0 R (cite.RFC3845) 1888 0 R (cite.RFC3901) 1852 0 R (cite.RFC4033) 1735 0 R (cite.RFC4034) 1737 0 R (cite.RFC4035) 1739 0 R (cite.RFC4074) 1749 0 R (cite.RFC974) 1702 0 R (cite.id2506250) 1893 0 R (clients-per-query) 1610 0 R (configuration_file_elements) 1171 0 R (controls_statement_definition_and_usage) 1046 0 R (diagnostic_tools) 981 0 R (dynamic_update) 1069 0 R (dynamic_update_policies) 1121 0 R (dynamic_update_security) 1333 0 R (empty) 1409 0 R (historical_dns_information) 1680 0 R (id2466555) 948 0 R (id2466579) 949 0 R (id2467422) 1084 0 R (id2467441) 1085 0 R (id2467538) 950 0 R (id2467547) 951 0 R (id2467719) 963 0 R (id2467740) 964 0 R (id2467774) 965 0 R (id2467859) 968 0 R (id2467952) 961 0 R (id2470257) 975 0 R (id2470280) 978 0 R (id2470378) 979 0 R (id2470400) 980 0 R (id2470429) 986 0 R (id2470533) 987 0 R (id2470560) 988 0 R (id2470594) 994 0 R (id2470620) 995 0 R (id2470633) 996 0 R (id2470727) 999 0 R (id2470738) 1005 0 R (id2470770) 1012 0 R (id2470786) 1013 0 R (id2470808) 1019 0 R (id2470825) 1020 0 R (id2471230) 1023 0 R (id2471236) 1024 0 R (id2473012) 1051 0 R (id2473024) 1052 0 R (id2473610) 1101 0 R (id2473627) 1102 0 R (id2474417) 1107 0 R (id2474435) 1108 0 R (id2474445) 1109 0 R (id2474482) 1110 0 R (id2474676) 1115 0 R (id2474724) 1117 0 R (id2474738) 1118 0 R (id2474787) 1119 0 R (id2474855) 1127 0 R (id2475002) 1128 0 R (id2475083) 1133 0 R (id2475389) 1141 0 R (id2475520) 1148 0 R (id2475541) 1149 0 R (id2475574) 1159 0 R (id2475858) 1172 0 R (id2476720) 1180 0 R (id2476747) 1185 0 R (id2476953) 1186 0 R (id2476968) 1187 0 R (id2477066) 1193 0 R (id2477209) 1195 0 R (id2477652) 1201 0 R (id2477694) 1203 0 R (id2477842) 1205 0 R (id2478270) 1213 0 R (id2478288) 1214 0 R (id2478311) 1220 0 R (id2478334) 1221 0 R (id2478493) 1225 0 R (id2478619) 1226 0 R (id2478672) 1231 0 R (id2479433) 1242 0 R (id2480030) 1253 0 R (id2480158) 1254 0 R (id2480544) 1256 0 R (id2480617) 1261 0 R (id2480681) 1264 0 R (id2480725) 1265 0 R (id2480740) 1266 0 R (id2483226) 1295 0 R (id2484998) 1320 0 R (id2485057) 1322 0 R (id2485630) 1338 0 R (id2486902) 1356 0 R (id2486962) 1358 0 R (id2487316) 1371 0 R (id2487818) 1385 0 R (id2489952) 1431 0 R (id2490106) 1432 0 R (id2490157) 1433 0 R (id2490376) 1439 0 R (id2491781) 1453 0 R (id2491788) 1454 0 R (id2491794) 1455 0 R (id2492284) 1462 0 R (id2492317) 1468 0 R (id2494013) 1522 0 R (id2494328) 1528 0 R (id2494346) 1529 0 R (id2494366) 1532 0 R (id2494672) 1534 0 R (id2495773) 1544 0 R (id2495970) 1550 0 R (id2495991) 1551 0 R (id2496422) 1553 0 R (id2496558) 1555 0 R (id2496577) 1561 0 R (id2496981) 1564 0 R (id2497106) 1566 0 R (id2497121) 1567 0 R (id2497301) 1573 0 R (id2497323) 1574 0 R (id2497339) 1575 0 R (id2497468) 1576 0 R (id2497538) 1581 0 R (id2497574) 1582 0 R (id2497704) 1583 0 R (id2498203) 1590 0 R (id2498638) 1598 0 R (id2498644) 1599 0 R (id2500112) 1606 0 R (id2500118) 1607 0 R (id2500563) 1615 0 R (id2500568) 1616 0 R (id2501513) 1622 0 R (id2501545) 1623 0 R (id2502023) 1628 0 R (id2502197) 1647 0 R (id2502278) 1648 0 R (id2502406) 1649 0 R (id2502486) 1664 0 R (id2502491) 1665 0 R (id2502503) 1666 0 R (id2502520) 1667 0 R (id2502582) 1679 0 R (id2503027) 1685 0 R (id2503214) 1690 0 R (id2503217) 1696 0 R (id2503225) 1701 0 R (id2503249) 1697 0 R (id2503272) 1699 0 R (id2503308) 1710 0 R (id2503335) 1712 0 R (id2503361) 1704 0 R (id2503385) 1706 0 R (id2503409) 1708 0 R (id2503464) 1714 0 R (id2503491) 1716 0 R (id2503517) 1718 0 R (id2503579) 1720 0 R (id2503609) 1722 0 R (id2503639) 1724 0 R (id2503666) 1726 0 R (id2503740) 1729 0 R (id2503748) 1730 0 R (id2503774) 1732 0 R (id2503811) 1734 0 R (id2503876) 1736 0 R (id2503941) 1738 0 R (id2504006) 1741 0 R (id2504014) 1742 0 R (id2504040) 1744 0 R (id2504108) 1746 0 R (id2504144) 1748 0 R (id2504184) 1756 0 R (id2504189) 1757 0 R (id2504247) 1759 0 R (id2504284) 1767 0 R (id2504320) 1761 0 R (id2504374) 1763 0 R (id2504412) 1765 0 R (id2504438) 1769 0 R (id2504464) 1771 0 R (id2504490) 1773 0 R (id2504517) 1775 0 R (id2504556) 1777 0 R (id2504586) 1779 0 R (id2504616) 1781 0 R (id2504659) 1783 0 R (id2504692) 1785 0 R (id2504718) 1787 0 R (id2504742) 1789 0 R (id2504868) 1791 0 R (id2504892) 1794 0 R (id2504900) 1795 0 R (id2504925) 1797 0 R (id2504948) 1799 0 R (id2504971) 1801 0 R (id2505017) 1803 0 R (id2505041) 1805 0 R (id2505091) 1812 0 R (id2505098) 1813 0 R (id2505122) 1815 0 R (id2505148) 1817 0 R (id2505175) 1819 0 R (id2505211) 1821 0 R (id2505252) 1824 0 R (id2505257) 1825 0 R (id2505289) 1827 0 R (id2505335) 1829 0 R (id2505370) 1831 0 R (id2505397) 1834 0 R (id2505415) 1835 0 R (id2505437) 1837 0 R (id2505463) 1839 0 R (id2505489) 1841 0 R (id2505512) 1843 0 R (id2505558) 1845 0 R (id2505581) 1847 0 R (id2505608) 1849 0 R (id2505634) 1851 0 R (id2505671) 1854 0 R (id2505677) 1855 0 R (id2505735) 1857 0 R (id2505762) 1859 0 R (id2505798) 1866 0 R (id2505810) 1867 0 R (id2505849) 1869 0 R (id2505944) 1871 0 R (id2505974) 1873 0 R (id2506000) 1875 0 R (id2506026) 1877 0 R (id2506062) 1879 0 R (id2506099) 1881 0 R (id2506125) 1883 0 R (id2506152) 1885 0 R (id2506197) 1887 0 R (id2506238) 1890 0 R (id2506248) 1892 0 R (id2506250) 1894 0 R (incremental_zone_transfers) 1081 0 R (internet_drafts) 1889 0 R (ipv6addresses) 1143 0 R (journal) 1070 0 R (lwresd) 1160 0 R (man.dig) 1900 0 R (man.dnssec-dsfromkey) 1948 0 R (man.dnssec-keyfromlabel) 1962 0 R (man.dnssec-keygen) 1979 0 R (man.dnssec-signzone) 1996 0 R (man.host) 1933 0 R (man.named) 2050 0 R (man.named-checkconf) 2022 0 R (man.named-checkzone) 2034 0 R (man.nsupdate) 2073 0 R (man.rndc) 2098 0 R (man.rndc-confgen) 2127 0 R (man.rndc.conf) 2111 0 R (notify) 1060 0 R (options) 1279 0 R (page.1) 710 0 R (page.10) 985 0 R (page.100) 1673 0 R (page.101) 1677 0 R (page.102) 1684 0 R (page.103) 1694 0 R (page.104) 1754 0 R (page.105) 1810 0 R (page.106) 1864 0 R (page.107) 1898 0 R (page.108) 1907 0 R (page.109) 1913 0 R (page.11) 992 0 R (page.110) 1919 0 R (page.111) 1923 0 R (page.112) 1928 0 R (page.113) 1939 0 R (page.114) 1944 0 R (page.115) 1956 0 R (page.116) 1968 0 R (page.117) 1975 0 R (page.118) 1987 0 R (page.119) 1991 0 R (page.12) 1004 0 R (page.120) 2002 0 R (page.121) 2008 0 R (page.122) 2013 0 R (page.123) 2019 0 R (page.124) 2032 0 R (page.125) 2042 0 R (page.126) 2046 0 R (page.127) 2058 0 R (page.128) 2063 0 R (page.129) 2069 0 R (page.13) 1009 0 R (page.130) 2080 0 R (page.131) 2085 0 R (page.132) 2089 0 R (page.133) 2097 0 R (page.134) 2107 0 R (page.135) 2118 0 R (page.136) 2123 0 R (page.137) 2135 0 R (page.138) 2141 0 R (page.14) 1018 0 R (page.15) 1029 0 R (page.16) 1037 0 R (page.17) 1044 0 R (page.18) 1050 0 R (page.19) 1058 0 R (page.2) 735 0 R (page.20) 1080 0 R (page.21) 1090 0 R (page.22) 1095 0 R (page.23) 1099 0 R (page.24) 1106 0 R (page.25) 1114 0 R (page.26) 1125 0 R (page.27) 1132 0 R (page.28) 1137 0 R (page.29) 1147 0 R (page.3) 745 0 R (page.30) 1153 0 R (page.31) 1157 0 R (page.32) 1165 0 R (page.33) 1169 0 R (page.34) 1179 0 R (page.35) 1184 0 R (page.36) 1192 0 R (page.37) 1200 0 R (page.38) 1210 0 R (page.39) 1219 0 R (page.4) 800 0 R (page.40) 1230 0 R (page.41) 1235 0 R (page.42) 1241 0 R (page.43) 1247 0 R (page.44) 1252 0 R (page.45) 1260 0 R (page.46) 1270 0 R (page.47) 1274 0 R (page.48) 1278 0 R (page.49) 1283 0 R (page.5) 864 0 R (page.50) 1290 0 R (page.51) 1294 0 R (page.52) 1300 0 R (page.53) 1311 0 R (page.54) 1315 0 R (page.55) 1319 0 R (page.56) 1330 0 R (page.57) 1337 0 R (page.58) 1342 0 R (page.59) 1347 0 R (page.6) 926 0 R (page.60) 1351 0 R (page.61) 1355 0 R (page.62) 1363 0 R (page.63) 1370 0 R (page.64) 1376 0 R (page.65) 1383 0 R (page.66) 1390 0 R (page.67) 1396 0 R (page.68) 1406 0 R (page.69) 1414 0 R (page.7) 946 0 R (page.70) 1418 0 R (page.71) 1423 0 R (page.72) 1430 0 R (page.73) 1438 0 R (page.74) 1444 0 R (page.75) 1448 0 R (page.76) 1452 0 R (page.77) 1460 0 R (page.78) 1467 0 R (page.79) 1486 0 R (page.8) 960 0 R (page.80) 1501 0 R (page.81) 1521 0 R (page.82) 1527 0 R (page.83) 1539 0 R (page.84) 1543 0 R (page.85) 1549 0 R (page.86) 1560 0 R (page.87) 1572 0 R (page.88) 1580 0 R (page.89) 1588 0 R (page.9) 974 0 R (page.90) 1595 0 R (page.91) 1604 0 R (page.92) 1614 0 R (page.93) 1621 0 R (page.94) 1632 0 R (page.95) 1636 0 R (page.96) 1642 0 R (page.97) 1653 0 R (page.98) 1658 0 R (page.99) 1662 0 R (proposed_standards) 1086 0 R (query_address) 1343 0 R (rfcs) 970 0 R (rndc) 1215 0 R (root_delegation_only) 1463 0 R (rrset_ordering) 1025 0 R (sample_configuration) 1011 0 R (section*.10) 1823 0 R (section*.100) 2109 0 R (section*.101) 2110 0 R (section*.102) 2112 0 R (section*.103) 2113 0 R (section*.104) 2114 0 R (section*.105) 2119 0 R (section*.106) 2124 0 R (section*.107) 2125 0 R (section*.108) 2126 0 R (section*.109) 2128 0 R (section*.11) 1833 0 R (section*.110) 2129 0 R (section*.111) 2130 0 R (section*.112) 2131 0 R (section*.113) 2136 0 R (section*.114) 2137 0 R (section*.115) 2142 0 R (section*.12) 1853 0 R (section*.13) 1865 0 R (section*.14) 1891 0 R (section*.15) 1901 0 R (section*.16) 1902 0 R (section*.17) 1903 0 R (section*.18) 1908 0 R (section*.19) 1909 0 R (section*.2) 1689 0 R (section*.20) 1914 0 R (section*.21) 1924 0 R (section*.22) 1929 0 R (section*.23) 1930 0 R (section*.24) 1931 0 R (section*.25) 1932 0 R (section*.26) 1934 0 R (section*.27) 1935 0 R (section*.28) 1940 0 R (section*.29) 1945 0 R (section*.3) 1695 0 R (section*.30) 1946 0 R (section*.31) 1947 0 R (section*.32) 1949 0 R (section*.33) 1950 0 R (section*.34) 1951 0 R (section*.35) 1952 0 R (section*.36) 1957 0 R (section*.37) 1958 0 R (section*.38) 1959 0 R (section*.39) 1960 0 R (section*.4) 1703 0 R (section*.40) 1961 0 R (section*.41) 1963 0 R (section*.42) 1969 0 R (section*.43) 1970 0 R (section*.44) 1971 0 R (section*.45) 1976 0 R (section*.46) 1977 0 R (section*.47) 1978 0 R (section*.48) 1980 0 R (section*.49) 1981 0 R (section*.5) 1728 0 R (section*.50) 1982 0 R (section*.51) 1983 0 R (section*.52) 1992 0 R (section*.53) 1993 0 R (section*.54) 1994 0 R (section*.55) 1995 0 R (section*.56) 1997 0 R (section*.57) 1998 0 R (section*.58) 2003 0 R (section*.59) 2004 0 R (section*.6) 1740 0 R (section*.60) 2014 0 R (section*.61) 2015 0 R (section*.62) 2020 0 R (section*.63) 2021 0 R (section*.64) 2023 0 R (section*.65) 2024 0 R (section*.66) 2025 0 R (section*.67) 2026 0 R (section*.68) 2027 0 R (section*.69) 2028 0 R (section*.7) 1755 0 R (section*.70) 2033 0 R (section*.71) 2035 0 R (section*.72) 2036 0 R (section*.73) 2037 0 R (section*.74) 2038 0 R (section*.75) 2047 0 R (section*.76) 2048 0 R (section*.77) 2049 0 R (section*.78) 2051 0 R (section*.79) 2052 0 R (section*.8) 1793 0 R (section*.80) 2053 0 R (section*.81) 2054 0 R (section*.82) 2064 0 R (section*.83) 2065 0 R (section*.84) 2070 0 R (section*.85) 2071 0 R (section*.86) 2072 0 R (section*.87) 2074 0 R (section*.88) 2075 0 R (section*.89) 2076 0 R (section*.9) 1811 0 R (section*.90) 2081 0 R (section*.91) 2090 0 R (section*.92) 2091 0 R (section*.93) 2092 0 R (section*.94) 2093 0 R (section*.95) 2099 0 R (section*.96) 2100 0 R (section*.97) 2101 0 R (section*.98) 2102 0 R (section*.99) 2108 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 234 0 R (section.5.2) 238 0 R (section.6.1) 246 0 R (section.6.2) 274 0 R (section.6.3) 482 0 R (section.6.4) 538 0 R (section.7.1) 574 0 R (section.7.2) 578 0 R (section.7.3) 590 0 R (section.8.1) 598 0 R (section.8.2) 606 0 R (section.8.3) 610 0 R (section.A.1) 618 0 R (section.A.2) 626 0 R (section.A.3) 634 0 R (section.B.1) 654 0 R (section.B.10) 690 0 R (section.B.11) 694 0 R (section.B.12) 698 0 R (section.B.13) 702 0 R (section.B.2) 658 0 R (section.B.3) 662 0 R (section.B.4) 666 0 R (section.B.5) 670 0 R (section.B.6) 674 0 R (section.B.7) 678 0 R (section.B.8) 682 0 R (section.B.9) 686 0 R (server_resource_limits) 1365 0 R (server_statement_definition_and_usage) 1307 0 R (server_statement_grammar) 1419 0 R (statistics) 1589 0 R (statistics_counters) 1597 0 R (statschannels) 1426 0 R (statsfile) 1286 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.2) 226 0 R (subsection.6.1.1) 250 0 R (subsection.6.1.2) 262 0 R (subsection.6.2.1) 278 0 R (subsection.6.2.10) 314 0 R (subsection.6.2.11) 330 0 R (subsection.6.2.12) 334 0 R (subsection.6.2.13) 338 0 R (subsection.6.2.14) 342 0 R (subsection.6.2.15) 346 0 R (subsection.6.2.16) 350 0 R (subsection.6.2.17) 426 0 R (subsection.6.2.18) 430 0 R (subsection.6.2.19) 434 0 R (subsection.6.2.2) 282 0 R (subsection.6.2.20) 438 0 R (subsection.6.2.21) 442 0 R (subsection.6.2.22) 446 0 R (subsection.6.2.23) 450 0 R (subsection.6.2.24) 454 0 R (subsection.6.2.25) 458 0 R (subsection.6.2.26) 462 0 R (subsection.6.2.3) 286 0 R (subsection.6.2.4) 290 0 R (subsection.6.2.5) 294 0 R (subsection.6.2.6) 298 0 R (subsection.6.2.7) 302 0 R (subsection.6.2.8) 306 0 R (subsection.6.2.9) 310 0 R (subsection.6.3.1) 486 0 R (subsection.6.3.2) 498 0 R (subsection.6.3.3) 502 0 R (subsection.6.3.4) 506 0 R (subsection.6.3.5) 510 0 R (subsection.6.3.6) 530 0 R (subsection.6.3.7) 534 0 R (subsection.6.4.1) 546 0 R (subsection.7.2.1) 582 0 R (subsection.7.2.2) 586 0 R (subsection.8.1.1) 602 0 R (subsection.A.1.1) 622 0 R (subsection.A.2.1) 630 0 R (subsection.A.3.1) 638 0 R (subsection.A.3.2) 642 0 R (subsection.A.3.3) 646 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 254 0 R (subsubsection.6.1.1.2) 258 0 R (subsubsection.6.1.2.1) 266 0 R (subsubsection.6.1.2.2) 270 0 R (subsubsection.6.2.10.1) 318 0 R (subsubsection.6.2.10.2) 322 0 R (subsubsection.6.2.10.3) 326 0 R (subsubsection.6.2.16.1) 354 0 R (subsubsection.6.2.16.10) 390 0 R (subsubsection.6.2.16.11) 394 0 R (subsubsection.6.2.16.12) 398 0 R (subsubsection.6.2.16.13) 402 0 R (subsubsection.6.2.16.14) 406 0 R (subsubsection.6.2.16.15) 410 0 R (subsubsection.6.2.16.16) 414 0 R (subsubsection.6.2.16.17) 418 0 R (subsubsection.6.2.16.18) 422 0 R (subsubsection.6.2.16.2) 358 0 R (subsubsection.6.2.16.3) 362 0 R (subsubsection.6.2.16.4) 366 0 R (subsubsection.6.2.16.5) 370 0 R (subsubsection.6.2.16.6) 374 0 R (subsubsection.6.2.16.7) 378 0 R (subsubsection.6.2.16.8) 382 0 R (subsubsection.6.2.16.9) 386 0 R (subsubsection.6.2.26.1) 466 0 R (subsubsection.6.2.26.2) 470 0 R (subsubsection.6.2.26.3) 474 0 R (subsubsection.6.2.26.4) 478 0 R (subsubsection.6.3.1.1) 490 0 R (subsubsection.6.3.1.2) 494 0 R (subsubsection.6.3.5.1) 514 0 R (subsubsection.6.3.5.2) 518 0 R (subsubsection.6.3.5.3) 522 0 R (subsubsection.6.3.5.4) 526 0 R (subsubsection.6.4.0.1) 542 0 R (subsubsection.6.4.1.1) 550 0 R (subsubsection.6.4.1.2) 554 0 R (subsubsection.6.4.1.3) 558 0 R (subsubsection.6.4.1.4) 562 0 R (subsubsection.6.4.1.5) 566 0 R (table.1.1) 952 0 R (table.1.2) 962 0 R (table.3.1) 1021 0 R (table.3.2) 1053 0 R (table.6.1) 1173 0 R (table.6.10) 1533 0 R (table.6.11) 1535 0 R (table.6.12) 1545 0 R (table.6.13) 1552 0 R (table.6.14) 1554 0 R (table.6.15) 1562 0 R (table.6.16) 1565 0 R (table.6.17) 1568 0 R (table.6.18) 1584 0 R (table.6.19) 1591 0 R (table.6.2) 1196 0 R (table.6.20) 1600 0 R (table.6.21) 1608 0 R (table.6.22) 1617 0 R (table.6.23) 1624 0 R (table.6.3) 1204 0 R (table.6.4) 1243 0 R (table.6.5) 1255 0 R (table.6.6) 1296 0 R (table.6.7) 1386 0 R (table.6.8) 1456 0 R (table.6.9) 1523 0 R (the_category_phrase) 1237 0 R (the_sortlist_statement) 1377 0 R (topology) 1372 0 R (tsig) 1100 0 R (tuning) 1391 0 R (types_of_resource_records_and_when_to_use_them) 969 0 R (view_statement_grammar) 1410 0 R (zone_statement_grammar) 1326 0 R (zone_transfers) 1076 0 R (zonefile_format) 1402 0 R] /Limits [(Access_Control_Lists) (zonefile_format)] >> endobj -2146 0 obj << -/Kids [2145 0 R] +2168 0 obj << +/Kids [2167 0 R] >> endobj -2147 0 obj << -/Dests 2146 0 R +2169 0 obj << +/Dests 2168 0 R >> endobj -2148 0 obj << +2170 0 obj << /Type /Catalog -/Pages 2143 0 R -/Outlines 2144 0 R -/Names 2147 0 R +/Pages 2165 0 R +/Outlines 2166 0 R +/Names 2169 0 R /PageMode /UseOutlines -/OpenAction 701 0 R +/OpenAction 705 0 R >> endobj -2149 0 obj << +2171 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords() -/CreationDate (D:20091231231729Z) +/CreationDate (D:20100225121620Z) /PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4) >> endobj xref -0 2150 +0 2172 0000000001 65535 f 0000000002 00000 f 0000000003 00000 f 0000000004 00000 f 0000000000 00000 f 0000000009 00000 n -0000071459 00000 n -0000744619 00000 n +0000071778 00000 n +0000753335 00000 n 0000000054 00000 n 0000000086 00000 n -0000071583 00000 n -0000744547 00000 n +0000071902 00000 n +0000753263 00000 n 0000000133 00000 n 0000000173 00000 n -0000071708 00000 n -0000744461 00000 n +0000072027 00000 n +0000753177 00000 n 0000000221 00000 n 0000000273 00000 n -0000071833 00000 n -0000744375 00000 n +0000072152 00000 n +0000753091 00000 n 0000000321 00000 n 0000000377 00000 n -0000076158 00000 n -0000744265 00000 n +0000076477 00000 n +0000752981 00000 n 0000000425 00000 n 0000000478 00000 n -0000076282 00000 n -0000744191 00000 n +0000076601 00000 n +0000752907 00000 n 0000000531 00000 n 0000000572 00000 n -0000076407 00000 n -0000744104 00000 n +0000076726 00000 n +0000752820 00000 n 0000000625 00000 n 0000000674 00000 n -0000076531 00000 n -0000744017 00000 n +0000076850 00000 n +0000752733 00000 n 0000000727 00000 n 0000000757 00000 n -0000080810 00000 n -0000743893 00000 n +0000081129 00000 n +0000752609 00000 n 0000000810 00000 n 0000000861 00000 n -0000080935 00000 n -0000743819 00000 n +0000081254 00000 n +0000752535 00000 n 0000000919 00000 n 0000000964 00000 n -0000081060 00000 n -0000743732 00000 n +0000081379 00000 n +0000752448 00000 n 0000001022 00000 n 0000001062 00000 n -0000081185 00000 n -0000743658 00000 n +0000081504 00000 n +0000752374 00000 n 0000001120 00000 n 0000001162 00000 n -0000084157 00000 n -0000743534 00000 n +0000084476 00000 n +0000752250 00000 n 0000001215 00000 n 0000001260 00000 n -0000084282 00000 n -0000743473 00000 n +0000084601 00000 n +0000752189 00000 n 0000001318 00000 n 0000001355 00000 n -0000084407 00000 n -0000743399 00000 n +0000084726 00000 n +0000752115 00000 n 0000001408 00000 n 0000001463 00000 n -0000087335 00000 n -0000743274 00000 n +0000087654 00000 n +0000751990 00000 n 0000001509 00000 n 0000001556 00000 n -0000087460 00000 n -0000743200 00000 n +0000087779 00000 n +0000751916 00000 n 0000001604 00000 n 0000001648 00000 n -0000087585 00000 n -0000743113 00000 n +0000087904 00000 n +0000751829 00000 n 0000001696 00000 n 0000001735 00000 n -0000087710 00000 n -0000743026 00000 n +0000088029 00000 n +0000751742 00000 n 0000001783 00000 n 0000001825 00000 n -0000087834 00000 n -0000742939 00000 n +0000088153 00000 n +0000751655 00000 n 0000001873 00000 n 0000001936 00000 n -0000088914 00000 n -0000742865 00000 n +0000089239 00000 n +0000751581 00000 n 0000001984 00000 n 0000002034 00000 n -0000090625 00000 n -0000742737 00000 n +0000090953 00000 n +0000751453 00000 n 0000002080 00000 n 0000002126 00000 n -0000090752 00000 n -0000742624 00000 n +0000091080 00000 n +0000751340 00000 n 0000002174 00000 n 0000002218 00000 n -0000090880 00000 n -0000742548 00000 n +0000091208 00000 n +0000751264 00000 n 0000002271 00000 n 0000002323 00000 n -0000091008 00000 n -0000742471 00000 n +0000091336 00000 n +0000751187 00000 n 0000002377 00000 n 0000002436 00000 n -0000093550 00000 n -0000742380 00000 n +0000093878 00000 n +0000751096 00000 n 0000002485 00000 n 0000002523 00000 n -0000093809 00000 n -0000742263 00000 n +0000094137 00000 n +0000750979 00000 n 0000002572 00000 n 0000002618 00000 n -0000093938 00000 n -0000742145 00000 n +0000094266 00000 n +0000750861 00000 n 0000002672 00000 n 0000002739 00000 n -0000097170 00000 n -0000742066 00000 n +0000097498 00000 n +0000750782 00000 n 0000002798 00000 n 0000002842 00000 n -0000097298 00000 n -0000741987 00000 n +0000097626 00000 n +0000750703 00000 n 0000002901 00000 n 0000002949 00000 n -0000107947 00000 n -0000741908 00000 n +0000108275 00000 n +0000750624 00000 n 0000003003 00000 n 0000003036 00000 n -0000112966 00000 n -0000741776 00000 n +0000113294 00000 n +0000750492 00000 n 0000003083 00000 n 0000003126 00000 n -0000113095 00000 n -0000741697 00000 n +0000113423 00000 n +0000750413 00000 n 0000003175 00000 n 0000003205 00000 n -0000113224 00000 n -0000741565 00000 n +0000113552 00000 n +0000750281 00000 n 0000003254 00000 n 0000003292 00000 n -0000113353 00000 n -0000741500 00000 n +0000113681 00000 n +0000750216 00000 n 0000003346 00000 n 0000003388 00000 n -0000117615 00000 n -0000741407 00000 n +0000118088 00000 n +0000750123 00000 n 0000003437 00000 n 0000003496 00000 n -0000117744 00000 n -0000741275 00000 n +0000118217 00000 n +0000749991 00000 n 0000003545 00000 n 0000003578 00000 n -0000117873 00000 n -0000741210 00000 n +0000118346 00000 n +0000749926 00000 n 0000003632 00000 n 0000003681 00000 n -0000125183 00000 n -0000741078 00000 n +0000125674 00000 n +0000749794 00000 n 0000003730 00000 n 0000003758 00000 n -0000125312 00000 n -0000740960 00000 n +0000125803 00000 n +0000749676 00000 n 0000003812 00000 n 0000003881 00000 n -0000125441 00000 n -0000740881 00000 n +0000125932 00000 n +0000749597 00000 n 0000003940 00000 n 0000003988 00000 n -0000128293 00000 n -0000740802 00000 n +0000128724 00000 n +0000749518 00000 n 0000004047 00000 n 0000004092 00000 n -0000128422 00000 n -0000740709 00000 n +0000128853 00000 n +0000749425 00000 n 0000004146 00000 n 0000004214 00000 n -0000128551 00000 n -0000740616 00000 n +0000128982 00000 n +0000749332 00000 n 0000004268 00000 n 0000004338 00000 n -0000128680 00000 n -0000740523 00000 n +0000129111 00000 n +0000749239 00000 n 0000004392 00000 n 0000004455 00000 n -0000132601 00000 n -0000740430 00000 n +0000133032 00000 n +0000749146 00000 n 0000004509 00000 n 0000004564 00000 n -0000132730 00000 n -0000740351 00000 n +0000133161 00000 n +0000749067 00000 n 0000004618 00000 n 0000004650 00000 n -0000132859 00000 n -0000740258 00000 n +0000133290 00000 n +0000748974 00000 n 0000004699 00000 n 0000004727 00000 n -0000132988 00000 n -0000740165 00000 n +0000133419 00000 n +0000748881 00000 n 0000004776 00000 n 0000004808 00000 n -0000136765 00000 n -0000740033 00000 n +0000137196 00000 n +0000748749 00000 n 0000004857 00000 n 0000004887 00000 n -0000136894 00000 n -0000739954 00000 n +0000137325 00000 n +0000748670 00000 n 0000004941 00000 n 0000004982 00000 n -0000137023 00000 n -0000739861 00000 n +0000137454 00000 n +0000748577 00000 n 0000005036 00000 n 0000005078 00000 n -0000140484 00000 n -0000739782 00000 n +0000141049 00000 n +0000748498 00000 n 0000005132 00000 n 0000005177 00000 n -0000143559 00000 n -0000739664 00000 n +0000144495 00000 n +0000748380 00000 n 0000005226 00000 n 0000005272 00000 n -0000143688 00000 n -0000739585 00000 n +0000146096 00000 n +0000748301 00000 n 0000005326 00000 n 0000005386 00000 n -0000143816 00000 n -0000739506 00000 n +0000146225 00000 n +0000748222 00000 n 0000005440 00000 n 0000005509 00000 n -0000146298 00000 n -0000739373 00000 n +0000149032 00000 n +0000748089 00000 n 0000005556 00000 n 0000005609 00000 n -0000146427 00000 n -0000739294 00000 n +0000149161 00000 n +0000748010 00000 n 0000005658 00000 n 0000005714 00000 n -0000146556 00000 n -0000739215 00000 n +0000149290 00000 n +0000747931 00000 n 0000005763 00000 n 0000005812 00000 n -0000150740 00000 n -0000739082 00000 n +0000153474 00000 n +0000747798 00000 n 0000005859 00000 n 0000005911 00000 n -0000150869 00000 n -0000738964 00000 n +0000153603 00000 n +0000747680 00000 n 0000005960 00000 n 0000006011 00000 n -0000155559 00000 n -0000738846 00000 n +0000158293 00000 n +0000747562 00000 n 0000006065 00000 n 0000006110 00000 n -0000155687 00000 n -0000738767 00000 n +0000158421 00000 n +0000747483 00000 n 0000006169 00000 n 0000006203 00000 n -0000159308 00000 n -0000738688 00000 n +0000162042 00000 n +0000747404 00000 n 0000006262 00000 n 0000006310 00000 n -0000159436 00000 n -0000738570 00000 n +0000162170 00000 n +0000747286 00000 n 0000006364 00000 n 0000006404 00000 n -0000159565 00000 n -0000738491 00000 n +0000162299 00000 n +0000747207 00000 n 0000006463 00000 n 0000006497 00000 n -0000163504 00000 n -0000738412 00000 n +0000166238 00000 n +0000747128 00000 n 0000006556 00000 n 0000006604 00000 n -0000163633 00000 n -0000738279 00000 n +0000166367 00000 n +0000746995 00000 n 0000006653 00000 n 0000006703 00000 n -0000166453 00000 n -0000738200 00000 n +0000169187 00000 n +0000746916 00000 n 0000006757 00000 n 0000006804 00000 n -0000166581 00000 n -0000738107 00000 n +0000169315 00000 n +0000746823 00000 n 0000006858 00000 n 0000006918 00000 n -0000166840 00000 n -0000738014 00000 n +0000169574 00000 n +0000746730 00000 n 0000006972 00000 n 0000007024 00000 n -0000172189 00000 n -0000737921 00000 n +0000174923 00000 n +0000746637 00000 n 0000007078 00000 n 0000007143 00000 n -0000172318 00000 n -0000737828 00000 n +0000175052 00000 n +0000746544 00000 n 0000007197 00000 n 0000007248 00000 n -0000172447 00000 n -0000737735 00000 n +0000175181 00000 n +0000746451 00000 n 0000007302 00000 n 0000007366 00000 n -0000175899 00000 n -0000737642 00000 n +0000178633 00000 n +0000746358 00000 n 0000007420 00000 n 0000007467 00000 n -0000176028 00000 n -0000737549 00000 n +0000178762 00000 n +0000746265 00000 n 0000007521 00000 n 0000007581 00000 n -0000176157 00000 n -0000737456 00000 n +0000178891 00000 n +0000746172 00000 n 0000007635 00000 n 0000007686 00000 n -0000176286 00000 n -0000737324 00000 n +0000179020 00000 n +0000746040 00000 n 0000007741 00000 n 0000007806 00000 n -0000180517 00000 n -0000737245 00000 n +0000183251 00000 n +0000745961 00000 n 0000007866 00000 n 0000007913 00000 n -0000187075 00000 n -0000737152 00000 n +0000189809 00000 n +0000745868 00000 n 0000007973 00000 n 0000008021 00000 n -0000194627 00000 n -0000737073 00000 n +0000197361 00000 n +0000745789 00000 n 0000008081 00000 n 0000008135 00000 n -0000194886 00000 n -0000736980 00000 n +0000197620 00000 n +0000745696 00000 n 0000008190 00000 n 0000008240 00000 n -0000197709 00000 n -0000736887 00000 n +0000200443 00000 n +0000745603 00000 n 0000008295 00000 n 0000008358 00000 n -0000197838 00000 n -0000736794 00000 n +0000200572 00000 n +0000745510 00000 n 0000008413 00000 n 0000008465 00000 n -0000197967 00000 n -0000736701 00000 n +0000200701 00000 n +0000745417 00000 n 0000008520 00000 n 0000008585 00000 n -0000198096 00000 n -0000736608 00000 n +0000200830 00000 n +0000745324 00000 n 0000008640 00000 n 0000008692 00000 n -0000203976 00000 n -0000736475 00000 n +0000206840 00000 n +0000745191 00000 n 0000008747 00000 n 0000008812 00000 n -0000212370 00000 n -0000736396 00000 n +0000215241 00000 n +0000745112 00000 n 0000008872 00000 n 0000008916 00000 n -0000233628 00000 n -0000736303 00000 n +0000236497 00000 n +0000745019 00000 n 0000008976 00000 n 0000009015 00000 n -0000233757 00000 n -0000736210 00000 n +0000236626 00000 n +0000744926 00000 n 0000009075 00000 n 0000009122 00000 n -0000233886 00000 n -0000736117 00000 n +0000236755 00000 n +0000744833 00000 n 0000009182 00000 n 0000009225 00000 n -0000240979 00000 n -0000736024 00000 n +0000243668 00000 n +0000744740 00000 n 0000009285 00000 n 0000009324 00000 n -0000241107 00000 n -0000735931 00000 n +0000247184 00000 n +0000744647 00000 n 0000009384 00000 n 0000009426 00000 n -0000248082 00000 n -0000735838 00000 n +0000250363 00000 n +0000744554 00000 n 0000009486 00000 n 0000009529 00000 n -0000255955 00000 n -0000735745 00000 n +0000257930 00000 n +0000744461 00000 n 0000009589 00000 n 0000009632 00000 n -0000256084 00000 n -0000735652 00000 n +0000258059 00000 n +0000744368 00000 n 0000009692 00000 n 0000009753 00000 n -0000260235 00000 n -0000735559 00000 n +0000262252 00000 n +0000744275 00000 n 0000009814 00000 n 0000009866 00000 n -0000263744 00000 n -0000735466 00000 n +0000266146 00000 n +0000744182 00000 n 0000009927 00000 n 0000009980 00000 n -0000263873 00000 n -0000735373 00000 n +0000266275 00000 n +0000744089 00000 n 0000010041 00000 n 0000010079 00000 n -0000267780 00000 n -0000735280 00000 n +0000270312 00000 n +0000743996 00000 n 0000010140 00000 n 0000010192 00000 n -0000271179 00000 n -0000735187 00000 n +0000273468 00000 n +0000743903 00000 n 0000010253 00000 n 0000010297 00000 n -0000275345 00000 n -0000735094 00000 n +0000277408 00000 n +0000743810 00000 n 0000010358 00000 n 0000010394 00000 n -0000280135 00000 n -0000735001 00000 n +0000285781 00000 n +0000743717 00000 n 0000010455 00000 n 0000010518 00000 n -0000283544 00000 n -0000734908 00000 n +0000285910 00000 n +0000743624 00000 n 0000010579 00000 n 0000010629 00000 n -0000287237 00000 n -0000734829 00000 n +0000289666 00000 n +0000743545 00000 n 0000010690 00000 n 0000010746 00000 n -0000290642 00000 n -0000734736 00000 n +0000292910 00000 n +0000743452 00000 n 0000010801 00000 n 0000010852 00000 n -0000290771 00000 n -0000734643 00000 n +0000293039 00000 n +0000743359 00000 n 0000010907 00000 n 0000010971 00000 n -0000295142 00000 n -0000734550 00000 n +0000297800 00000 n +0000743266 00000 n 0000011026 00000 n 0000011090 00000 n -0000295271 00000 n -0000734457 00000 n +0000301569 00000 n +0000743173 00000 n 0000011145 00000 n 0000011222 00000 n -0000298928 00000 n -0000734364 00000 n +0000301698 00000 n +0000743080 00000 n 0000011277 00000 n 0000011334 00000 n -0000299057 00000 n -0000734271 00000 n +0000301827 00000 n +0000742987 00000 n 0000011389 00000 n 0000011459 00000 n -0000299186 00000 n -0000734178 00000 n +0000301956 00000 n +0000742894 00000 n 0000011514 00000 n 0000011563 00000 n -0000302629 00000 n -0000734085 00000 n +0000305399 00000 n +0000742801 00000 n 0000011618 00000 n 0000011680 00000 n -0000304248 00000 n -0000733992 00000 n +0000307024 00000 n +0000742708 00000 n 0000011735 00000 n 0000011784 00000 n -0000308427 00000 n -0000733874 00000 n +0000311203 00000 n +0000742590 00000 n 0000011839 00000 n 0000011901 00000 n -0000308556 00000 n -0000733795 00000 n +0000311332 00000 n +0000742511 00000 n 0000011961 00000 n 0000012000 00000 n -0000312881 00000 n -0000733702 00000 n +0000315657 00000 n +0000742418 00000 n 0000012060 00000 n 0000012094 00000 n -0000318771 00000 n -0000733609 00000 n +0000321547 00000 n +0000742325 00000 n 0000012154 00000 n 0000012195 00000 n -0000330157 00000 n -0000733530 00000 n +0000332933 00000 n +0000742246 00000 n 0000012255 00000 n 0000012307 00000 n -0000337397 00000 n -0000733398 00000 n +0000340173 00000 n +0000742114 00000 n 0000012356 00000 n 0000012389 00000 n -0000337526 00000 n -0000733280 00000 n +0000340302 00000 n +0000741996 00000 n 0000012443 00000 n 0000012515 00000 n -0000337654 00000 n -0000733201 00000 n +0000340430 00000 n +0000741917 00000 n 0000012574 00000 n 0000012618 00000 n -0000348444 00000 n -0000733122 00000 n +0000351220 00000 n +0000741838 00000 n 0000012677 00000 n 0000012730 00000 n -0000348831 00000 n -0000733029 00000 n +0000351607 00000 n +0000741745 00000 n 0000012784 00000 n 0000012834 00000 n -0000352195 00000 n -0000732936 00000 n +0000354971 00000 n +0000741652 00000 n 0000012888 00000 n 0000012926 00000 n -0000352454 00000 n -0000732843 00000 n +0000355230 00000 n +0000741559 00000 n 0000012980 00000 n 0000013029 00000 n -0000355319 00000 n -0000732711 00000 n +0000358315 00000 n +0000741427 00000 n 0000013083 00000 n 0000013135 00000 n -0000355447 00000 n -0000732632 00000 n +0000358444 00000 n +0000741348 00000 n 0000013194 00000 n -0000013246 00000 n -0000355576 00000 n -0000732539 00000 n -0000013305 00000 n -0000013358 00000 n -0000355705 00000 n -0000732460 00000 n -0000013417 00000 n -0000013466 00000 n -0000359352 00000 n -0000732367 00000 n -0000013520 00000 n -0000013600 00000 n -0000363488 00000 n -0000732288 00000 n -0000013654 00000 n -0000013703 00000 n -0000363617 00000 n -0000732170 00000 n -0000013752 00000 n -0000013792 00000 n -0000366917 00000 n -0000732091 00000 n -0000013851 00000 n -0000013898 00000 n -0000367046 00000 n -0000731973 00000 n -0000013952 00000 n -0000013997 00000 n -0000367175 00000 n -0000731894 00000 n +0000013239 00000 n +0000358573 00000 n +0000741255 00000 n +0000013298 00000 n +0000013350 00000 n +0000358702 00000 n +0000741162 00000 n +0000013409 00000 n +0000013462 00000 n +0000362349 00000 n +0000741083 00000 n +0000013521 00000 n +0000013570 00000 n +0000362477 00000 n +0000740990 00000 n +0000013624 00000 n +0000013704 00000 n +0000366241 00000 n +0000740911 00000 n +0000013758 00000 n +0000013807 00000 n +0000366370 00000 n +0000740793 00000 n +0000013856 00000 n +0000013896 00000 n +0000369810 00000 n +0000740714 00000 n +0000013955 00000 n +0000014002 00000 n +0000369939 00000 n +0000740596 00000 n 0000014056 00000 n -0000014115 00000 n -0000370864 00000 n -0000731801 00000 n -0000014174 00000 n -0000014238 00000 n -0000374585 00000 n -0000731708 00000 n -0000014297 00000 n -0000014353 00000 n -0000374843 00000 n -0000731615 00000 n -0000014412 00000 n -0000014470 00000 n -0000377514 00000 n -0000731536 00000 n -0000014529 00000 n -0000014591 00000 n -0000379759 00000 n -0000731403 00000 n -0000014638 00000 n -0000014690 00000 n -0000379888 00000 n -0000731324 00000 n -0000014739 00000 n -0000014783 00000 n -0000384086 00000 n -0000731192 00000 n -0000014832 00000 n -0000014873 00000 n -0000384215 00000 n -0000731113 00000 n -0000014927 00000 n -0000014975 00000 n -0000384343 00000 n -0000731034 00000 n -0000015029 00000 n -0000015080 00000 n -0000384472 00000 n -0000730955 00000 n -0000015129 00000 n -0000015176 00000 n -0000388739 00000 n -0000730822 00000 n -0000015223 00000 n -0000015260 00000 n -0000388868 00000 n -0000730704 00000 n -0000015309 00000 n -0000015348 00000 n -0000388997 00000 n -0000730639 00000 n -0000015402 00000 n -0000015480 00000 n -0000389126 00000 n -0000730546 00000 n -0000015529 00000 n -0000015596 00000 n -0000389255 00000 n -0000730467 00000 n -0000015645 00000 n -0000015690 00000 n -0000392694 00000 n -0000730334 00000 n -0000015738 00000 n -0000015770 00000 n -0000392823 00000 n -0000730216 00000 n -0000015819 00000 n -0000015858 00000 n -0000392952 00000 n -0000730151 00000 n -0000015912 00000 n -0000015973 00000 n -0000396633 00000 n -0000730019 00000 n -0000016022 00000 n -0000016079 00000 n -0000396762 00000 n -0000729954 00000 n -0000016133 00000 n -0000016182 00000 n -0000396891 00000 n -0000729836 00000 n -0000016231 00000 n -0000016293 00000 n -0000397020 00000 n -0000729757 00000 n -0000016347 00000 n -0000016402 00000 n -0000421042 00000 n -0000729664 00000 n -0000016456 00000 n -0000016497 00000 n -0000421171 00000 n -0000729585 00000 n -0000016551 00000 n -0000016603 00000 n -0000423902 00000 n -0000729465 00000 n -0000016651 00000 n -0000016685 00000 n -0000424031 00000 n -0000729386 00000 n -0000016734 00000 n -0000016761 00000 n -0000441854 00000 n -0000729293 00000 n -0000016810 00000 n +0000014101 00000 n +0000370068 00000 n +0000740517 00000 n +0000014160 00000 n +0000014219 00000 n +0000373824 00000 n +0000740424 00000 n +0000014278 00000 n +0000014342 00000 n +0000377291 00000 n +0000740331 00000 n +0000014401 00000 n +0000014457 00000 n +0000380308 00000 n +0000740238 00000 n +0000014516 00000 n +0000014574 00000 n +0000380566 00000 n +0000740159 00000 n +0000014633 00000 n +0000014695 00000 n +0000382811 00000 n +0000740026 00000 n +0000014742 00000 n +0000014794 00000 n +0000382940 00000 n +0000739947 00000 n +0000014843 00000 n +0000014887 00000 n +0000387139 00000 n +0000739815 00000 n +0000014936 00000 n +0000014977 00000 n +0000387268 00000 n +0000739736 00000 n +0000015031 00000 n +0000015079 00000 n +0000387396 00000 n +0000739657 00000 n +0000015133 00000 n +0000015184 00000 n +0000387525 00000 n +0000739578 00000 n +0000015233 00000 n +0000015280 00000 n +0000391792 00000 n +0000739445 00000 n +0000015327 00000 n +0000015364 00000 n +0000391921 00000 n +0000739327 00000 n +0000015413 00000 n +0000015452 00000 n +0000392050 00000 n +0000739262 00000 n +0000015506 00000 n +0000015584 00000 n +0000392179 00000 n +0000739169 00000 n +0000015633 00000 n +0000015700 00000 n +0000392308 00000 n +0000739090 00000 n +0000015749 00000 n +0000015794 00000 n +0000395748 00000 n +0000738957 00000 n +0000015842 00000 n +0000015874 00000 n +0000395877 00000 n +0000738839 00000 n +0000015923 00000 n +0000015962 00000 n +0000396006 00000 n +0000738774 00000 n +0000016016 00000 n +0000016077 00000 n +0000399687 00000 n +0000738642 00000 n +0000016126 00000 n +0000016183 00000 n +0000399816 00000 n +0000738577 00000 n +0000016237 00000 n +0000016286 00000 n +0000399945 00000 n +0000738459 00000 n +0000016335 00000 n +0000016397 00000 n +0000400074 00000 n +0000738380 00000 n +0000016451 00000 n +0000016506 00000 n +0000424096 00000 n +0000738287 00000 n +0000016560 00000 n +0000016601 00000 n +0000424225 00000 n +0000738208 00000 n +0000016655 00000 n +0000016707 00000 n +0000426956 00000 n +0000738088 00000 n +0000016755 00000 n +0000016789 00000 n +0000427085 00000 n +0000738009 00000 n 0000016838 00000 n -0000449343 00000 n -0000729200 00000 n -0000016887 00000 n -0000016927 00000 n -0000452138 00000 n -0000729107 00000 n -0000016976 00000 n -0000017019 00000 n -0000458062 00000 n -0000729014 00000 n -0000017068 00000 n -0000017105 00000 n -0000464564 00000 n -0000728921 00000 n -0000017154 00000 n -0000017193 00000 n -0000476717 00000 n -0000728828 00000 n -0000017242 00000 n -0000017281 00000 n -0000480140 00000 n -0000728735 00000 n -0000017330 00000 n -0000017369 00000 n -0000486583 00000 n -0000728642 00000 n -0000017418 00000 n -0000017447 00000 n -0000496757 00000 n -0000728549 00000 n -0000017497 00000 n -0000017530 00000 n -0000506693 00000 n -0000728456 00000 n -0000017580 00000 n -0000017609 00000 n -0000513987 00000 n -0000728363 00000 n -0000017659 00000 n -0000017693 00000 n -0000519675 00000 n -0000728284 00000 n -0000017743 00000 n -0000017780 00000 n -0000018149 00000 n -0000018271 00000 n -0000026100 00000 n -0000017833 00000 n -0000025974 00000 n -0000026037 00000 n -0000723763 00000 n -0000697820 00000 n -0000723589 00000 n -0000724788 00000 n -0000021134 00000 n -0000021351 00000 n -0000021420 00000 n -0000021489 00000 n -0000021557 00000 n -0000021625 00000 n -0000021674 00000 n -0000021721 00000 n -0000022054 00000 n -0000022076 00000 n -0000022244 00000 n -0000022409 00000 n -0000022578 00000 n -0000022757 00000 n -0000023066 00000 n -0000023226 00000 n -0000027466 00000 n -0000027281 00000 n -0000026200 00000 n -0000027403 00000 n -0000696599 00000 n -0000670078 00000 n -0000696425 00000 n -0000669393 00000 n -0000667249 00000 n -0000669229 00000 n -0000039173 00000 n -0000030522 00000 n -0000027551 00000 n -0000039047 00000 n -0000039110 00000 n -0000031056 00000 n -0000031210 00000 n -0000031367 00000 n -0000031524 00000 n -0000031680 00000 n -0000031837 00000 n -0000031999 00000 n -0000032160 00000 n -0000032321 00000 n -0000032483 00000 n -0000032650 00000 n -0000032817 00000 n -0000032982 00000 n -0000033144 00000 n -0000033310 00000 n -0000033471 00000 n -0000033626 00000 n -0000033783 00000 n -0000033939 00000 n -0000034096 00000 n -0000034253 00000 n -0000034410 00000 n -0000034564 00000 n -0000034720 00000 n -0000034882 00000 n -0000035044 00000 n -0000035200 00000 n -0000035357 00000 n -0000035519 00000 n -0000035686 00000 n -0000035852 00000 n -0000036013 00000 n -0000036168 00000 n -0000036325 00000 n -0000036482 00000 n -0000036644 00000 n -0000036801 00000 n -0000036958 00000 n -0000037120 00000 n -0000037277 00000 n -0000037439 00000 n -0000037606 00000 n -0000037772 00000 n -0000037934 00000 n -0000038096 00000 n -0000038258 00000 n -0000038420 00000 n -0000038582 00000 n -0000038737 00000 n -0000038892 00000 n -0000052547 00000 n -0000042497 00000 n -0000039258 00000 n -0000052484 00000 n -0000666698 00000 n -0000649617 00000 n -0000666514 00000 n -0000043087 00000 n -0000043250 00000 n -0000043412 00000 n -0000043575 00000 n -0000043733 00000 n -0000043896 00000 n -0000044059 00000 n -0000044214 00000 n -0000044372 00000 n -0000044530 00000 n -0000044686 00000 n -0000044844 00000 n -0000045007 00000 n -0000045175 00000 n -0000045343 00000 n -0000045506 00000 n -0000045674 00000 n -0000045842 00000 n -0000046000 00000 n -0000046163 00000 n -0000046326 00000 n -0000046488 00000 n -0000046650 00000 n -0000046813 00000 n -0000046975 00000 n -0000047137 00000 n -0000047300 00000 n -0000047463 00000 n -0000047626 00000 n -0000047795 00000 n -0000047964 00000 n -0000048133 00000 n -0000048296 00000 n -0000048460 00000 n -0000048624 00000 n -0000048787 00000 n -0000048951 00000 n -0000049115 00000 n -0000049283 00000 n -0000049452 00000 n -0000049621 00000 n -0000049790 00000 n -0000049959 00000 n -0000050128 00000 n -0000050297 00000 n -0000050466 00000 n -0000050635 00000 n -0000050805 00000 n -0000050975 00000 n -0000051145 00000 n -0000051315 00000 n -0000051485 00000 n -0000051655 00000 n -0000051824 00000 n -0000051994 00000 n -0000052161 00000 n -0000052322 00000 n -0000065709 00000 n -0000056176 00000 n -0000052645 00000 n -0000065646 00000 n -0000056750 00000 n -0000056913 00000 n -0000057076 00000 n -0000057239 00000 n -0000057402 00000 n -0000057565 00000 n -0000057728 00000 n -0000057890 00000 n -0000058051 00000 n -0000058218 00000 n -0000058386 00000 n -0000058554 00000 n -0000058722 00000 n -0000058879 00000 n -0000059039 00000 n -0000059205 00000 n -0000059372 00000 n -0000059534 00000 n -0000059696 00000 n -0000059858 00000 n -0000060019 00000 n -0000060185 00000 n -0000060352 00000 n -0000060519 00000 n -0000060681 00000 n -0000060843 00000 n -0000061000 00000 n -0000061167 00000 n -0000061329 00000 n -0000061496 00000 n -0000061663 00000 n -0000061830 00000 n -0000648728 00000 n -0000627397 00000 n -0000648554 00000 n -0000061997 00000 n -0000062164 00000 n -0000062318 00000 n -0000062475 00000 n -0000062632 00000 n -0000062794 00000 n -0000062956 00000 n -0000063113 00000 n -0000063268 00000 n -0000063425 00000 n -0000063587 00000 n -0000063744 00000 n -0000063901 00000 n -0000064057 00000 n -0000064214 00000 n -0000064376 00000 n -0000064533 00000 n -0000064695 00000 n -0000064852 00000 n -0000065014 00000 n -0000065176 00000 n -0000065337 00000 n -0000065491 00000 n -0000068921 00000 n -0000066744 00000 n -0000065820 00000 n -0000068858 00000 n -0000066974 00000 n -0000067131 00000 n -0000067288 00000 n -0000067444 00000 n -0000067601 00000 n -0000067758 00000 n -0000067915 00000 n -0000068072 00000 n -0000068229 00000 n -0000068385 00000 n -0000626431 00000 n -0000606464 00000 n -0000626258 00000 n -0000068543 00000 n -0000068700 00000 n -0000072084 00000 n -0000071274 00000 n +0000016865 00000 n +0000444909 00000 n +0000737916 00000 n +0000016914 00000 n +0000016942 00000 n +0000452398 00000 n +0000737823 00000 n +0000016991 00000 n +0000017031 00000 n +0000455193 00000 n +0000737730 00000 n +0000017080 00000 n +0000017123 00000 n +0000461374 00000 n +0000737637 00000 n +0000017172 00000 n +0000017209 00000 n +0000467999 00000 n +0000737544 00000 n +0000017258 00000 n +0000017297 00000 n +0000480380 00000 n +0000737451 00000 n +0000017346 00000 n +0000017385 00000 n +0000483476 00000 n +0000737358 00000 n +0000017434 00000 n +0000017473 00000 n +0000489756 00000 n +0000737265 00000 n +0000017522 00000 n +0000017551 00000 n +0000499567 00000 n +0000737172 00000 n +0000017601 00000 n +0000017634 00000 n +0000513869 00000 n +0000737079 00000 n +0000017684 00000 n +0000017713 00000 n +0000517096 00000 n +0000736986 00000 n +0000017763 00000 n +0000017797 00000 n +0000523004 00000 n +0000736907 00000 n +0000017847 00000 n +0000017884 00000 n +0000018253 00000 n +0000018375 00000 n +0000026204 00000 n +0000017937 00000 n +0000026078 00000 n +0000026141 00000 n +0000732358 00000 n +0000706415 00000 n +0000732184 00000 n +0000733383 00000 n +0000021238 00000 n +0000021455 00000 n +0000021524 00000 n +0000021593 00000 n +0000021661 00000 n +0000021729 00000 n +0000021778 00000 n +0000021825 00000 n +0000022158 00000 n +0000022180 00000 n +0000022348 00000 n +0000022513 00000 n +0000022682 00000 n +0000022861 00000 n +0000023170 00000 n +0000023330 00000 n +0000027570 00000 n +0000027385 00000 n +0000026304 00000 n +0000027507 00000 n +0000705194 00000 n +0000678673 00000 n +0000705020 00000 n +0000677988 00000 n +0000675844 00000 n +0000677824 00000 n +0000039277 00000 n +0000030626 00000 n +0000027655 00000 n +0000039151 00000 n +0000039214 00000 n +0000031160 00000 n +0000031314 00000 n +0000031471 00000 n +0000031628 00000 n +0000031784 00000 n +0000031941 00000 n +0000032103 00000 n +0000032264 00000 n +0000032425 00000 n +0000032587 00000 n +0000032754 00000 n +0000032921 00000 n +0000033086 00000 n +0000033248 00000 n +0000033414 00000 n +0000033575 00000 n +0000033730 00000 n +0000033887 00000 n +0000034043 00000 n +0000034200 00000 n +0000034357 00000 n +0000034514 00000 n +0000034668 00000 n +0000034824 00000 n +0000034986 00000 n +0000035148 00000 n +0000035304 00000 n +0000035461 00000 n +0000035623 00000 n +0000035790 00000 n +0000035956 00000 n +0000036117 00000 n +0000036272 00000 n +0000036429 00000 n +0000036586 00000 n +0000036748 00000 n +0000036905 00000 n +0000037062 00000 n +0000037224 00000 n +0000037381 00000 n +0000037543 00000 n +0000037710 00000 n +0000037876 00000 n +0000038038 00000 n +0000038200 00000 n +0000038362 00000 n +0000038524 00000 n +0000038686 00000 n +0000038841 00000 n +0000038996 00000 n +0000052649 00000 n +0000042603 00000 n +0000039362 00000 n +0000052586 00000 n +0000675293 00000 n +0000658212 00000 n +0000675109 00000 n +0000043193 00000 n +0000043356 00000 n +0000043518 00000 n +0000043681 00000 n +0000043839 00000 n +0000044002 00000 n +0000044165 00000 n +0000044320 00000 n +0000044478 00000 n +0000044636 00000 n +0000044792 00000 n +0000044950 00000 n +0000045113 00000 n +0000045281 00000 n +0000045449 00000 n +0000045612 00000 n +0000045780 00000 n +0000045948 00000 n +0000046105 00000 n +0000046268 00000 n +0000046431 00000 n +0000046593 00000 n +0000046755 00000 n +0000046918 00000 n +0000047080 00000 n +0000047242 00000 n +0000047405 00000 n +0000047568 00000 n +0000047731 00000 n +0000047899 00000 n +0000048068 00000 n +0000048237 00000 n +0000048400 00000 n +0000048564 00000 n +0000048728 00000 n +0000048891 00000 n +0000049055 00000 n +0000049219 00000 n +0000049388 00000 n +0000049557 00000 n +0000049726 00000 n +0000049895 00000 n +0000050064 00000 n +0000050233 00000 n +0000050402 00000 n +0000050571 00000 n +0000050740 00000 n +0000050910 00000 n +0000051080 00000 n +0000051249 00000 n +0000051419 00000 n +0000051589 00000 n +0000051757 00000 n +0000051926 00000 n +0000052096 00000 n +0000052263 00000 n +0000052424 00000 n +0000065826 00000 n +0000056283 00000 n +0000052747 00000 n +0000065763 00000 n +0000056857 00000 n +0000057020 00000 n +0000057183 00000 n +0000057346 00000 n +0000057509 00000 n +0000057672 00000 n +0000057835 00000 n +0000057997 00000 n +0000058160 00000 n +0000058328 00000 n +0000058496 00000 n +0000058664 00000 n +0000058832 00000 n +0000058989 00000 n +0000059149 00000 n +0000059315 00000 n +0000059482 00000 n +0000059644 00000 n +0000059806 00000 n +0000059967 00000 n +0000060128 00000 n +0000060294 00000 n +0000060461 00000 n +0000060628 00000 n +0000060795 00000 n +0000060957 00000 n +0000061119 00000 n +0000061276 00000 n +0000061443 00000 n +0000061605 00000 n +0000061772 00000 n +0000061939 00000 n +0000062106 00000 n +0000657323 00000 n +0000635992 00000 n +0000657149 00000 n +0000062273 00000 n +0000062439 00000 n +0000062594 00000 n +0000062750 00000 n +0000062906 00000 n +0000063068 00000 n +0000063230 00000 n +0000063387 00000 n +0000063542 00000 n +0000063699 00000 n +0000063861 00000 n +0000064018 00000 n +0000064175 00000 n +0000064331 00000 n +0000064488 00000 n +0000064650 00000 n +0000064807 00000 n +0000064969 00000 n +0000065126 00000 n +0000065288 00000 n +0000065449 00000 n +0000065609 00000 n +0000069240 00000 n +0000066898 00000 n +0000065937 00000 n +0000069177 00000 n +0000067136 00000 n +0000067293 00000 n +0000067450 00000 n +0000067605 00000 n +0000067762 00000 n +0000067919 00000 n +0000068076 00000 n +0000068233 00000 n +0000068390 00000 n +0000068546 00000 n +0000068704 00000 n +0000635026 00000 n +0000615059 00000 n +0000634853 00000 n +0000068861 00000 n 0000069019 00000 n -0000071396 00000 n -0000071520 00000 n -0000071645 00000 n -0000071770 00000 n -0000071895 00000 n -0000071958 00000 n -0000072021 00000 n -0000605670 00000 n -0000587353 00000 n -0000605497 00000 n -0000724906 00000 n -0000076655 00000 n -0000075475 00000 n -0000072208 00000 n -0000075969 00000 n -0000076032 00000 n -0000076095 00000 n -0000076219 00000 n -0000076344 00000 n -0000076469 00000 n -0000075625 00000 n -0000075818 00000 n -0000076592 00000 n -0000337590 00000 n -0000397084 00000 n -0000081310 00000 n -0000080274 00000 n -0000076779 00000 n -0000080747 00000 n -0000080872 00000 n -0000080424 00000 n -0000080586 00000 n -0000080997 00000 n -0000081122 00000 n -0000081247 00000 n -0000097234 00000 n -0000084532 00000 n -0000083972 00000 n -0000081434 00000 n -0000084094 00000 n -0000084219 00000 n -0000084344 00000 n -0000084469 00000 n -0000087959 00000 n -0000086818 00000 n -0000084643 00000 n -0000087272 00000 n -0000087397 00000 n -0000087522 00000 n -0000087647 00000 n -0000087772 00000 n -0000086968 00000 n -0000087120 00000 n -0000087896 00000 n -0000287301 00000 n -0000089040 00000 n -0000088729 00000 n -0000088044 00000 n -0000088851 00000 n -0000088976 00000 n -0000091137 00000 n -0000090434 00000 n -0000089138 00000 n -0000090560 00000 n -0000090688 00000 n -0000090815 00000 n -0000090943 00000 n -0000091072 00000 n -0000725024 00000 n -0000094066 00000 n -0000093177 00000 n -0000091236 00000 n -0000093485 00000 n -0000093614 00000 n -0000093679 00000 n -0000093744 00000 n -0000093324 00000 n -0000093873 00000 n -0000094002 00000 n -0000271243 00000 n -0000097427 00000 n -0000096979 00000 n -0000094178 00000 n -0000097105 00000 n -0000586678 00000 n -0000574689 00000 n -0000586499 00000 n -0000097362 00000 n -0000101249 00000 n -0000101058 00000 n -0000097553 00000 n -0000101184 00000 n -0000574148 00000 n -0000564404 00000 n -0000573969 00000 n -0000105860 00000 n -0000105461 00000 n -0000101415 00000 n -0000105795 00000 n -0000105608 00000 n -0000172253 00000 n -0000108206 00000 n -0000107756 00000 n -0000105999 00000 n -0000107882 00000 n -0000108011 00000 n -0000108076 00000 n -0000108141 00000 n -0000110935 00000 n -0000113482 00000 n -0000110779 00000 n -0000108331 00000 n -0000112901 00000 n -0000113030 00000 n -0000113159 00000 n -0000112578 00000 n -0000112740 00000 n -0000563534 00000 n -0000554114 00000 n -0000563360 00000 n -0000553550 00000 n -0000544464 00000 n -0000553375 00000 n -0000113288 00000 n -0000113417 00000 n -0000725149 00000 n -0000112407 00000 n -0000112465 00000 n -0000112555 00000 n -0000212434 00000 n -0000248146 00000 n -0000118002 00000 n -0000117067 00000 n -0000113638 00000 n -0000117550 00000 n -0000117679 00000 n -0000117223 00000 n -0000117388 00000 n -0000117808 00000 n -0000117937 00000 n -0000401111 00000 n -0000121616 00000 n -0000121236 00000 n -0000118154 00000 n -0000121551 00000 n -0000121383 00000 n -0000122866 00000 n -0000122675 00000 n -0000121741 00000 n -0000122801 00000 n -0000125569 00000 n -0000124992 00000 n -0000122965 00000 n -0000125118 00000 n -0000125247 00000 n -0000125376 00000 n -0000125505 00000 n -0000128809 00000 n -0000128102 00000 n -0000125707 00000 n -0000128228 00000 n -0000128357 00000 n -0000128486 00000 n -0000128615 00000 n -0000128744 00000 n -0000133116 00000 n -0000132218 00000 n -0000128934 00000 n -0000132536 00000 n -0000132665 00000 n -0000132365 00000 n -0000132794 00000 n -0000132923 00000 n -0000133051 00000 n -0000725274 00000 n -0000330221 00000 n -0000137152 00000 n -0000136574 00000 n -0000133241 00000 n -0000136700 00000 n -0000136829 00000 n -0000136958 00000 n -0000137087 00000 n -0000140613 00000 n -0000140293 00000 n -0000137290 00000 n -0000140419 00000 n -0000140548 00000 n -0000143945 00000 n -0000143186 00000 n -0000140725 00000 n -0000143494 00000 n -0000143623 00000 n -0000143333 00000 n -0000143752 00000 n -0000143880 00000 n -0000396826 00000 n -0000146685 00000 n -0000146107 00000 n -0000144113 00000 n -0000146233 00000 n -0000146362 00000 n -0000146491 00000 n -0000146620 00000 n -0000147125 00000 n -0000146934 00000 n -0000146784 00000 n -0000147060 00000 n -0000151127 00000 n -0000150361 00000 n -0000147167 00000 n -0000150675 00000 n -0000150804 00000 n -0000150932 00000 n -0000150997 00000 n -0000151062 00000 n -0000150508 00000 n -0000725399 00000 n -0000155623 00000 n -0000155815 00000 n -0000155368 00000 n -0000151226 00000 n -0000155494 00000 n -0000155750 00000 n -0000159694 00000 n -0000159117 00000 n -0000155940 00000 n -0000159243 00000 n -0000159371 00000 n -0000159500 00000 n -0000159629 00000 n -0000162513 00000 n -0000163892 00000 n -0000162387 00000 n -0000159832 00000 n -0000163439 00000 n -0000163568 00000 n -0000163697 00000 n -0000163762 00000 n -0000163827 00000 n -0000166969 00000 n -0000166262 00000 n -0000164047 00000 n -0000166388 00000 n -0000166517 00000 n -0000166645 00000 n -0000166710 00000 n -0000166775 00000 n -0000166904 00000 n -0000172576 00000 n -0000171658 00000 n -0000167081 00000 n -0000172124 00000 n -0000171814 00000 n -0000171965 00000 n -0000172382 00000 n -0000172511 00000 n -0000523089 00000 n -0000176415 00000 n -0000175144 00000 n -0000172714 00000 n -0000175834 00000 n -0000175963 00000 n -0000176092 00000 n -0000175309 00000 n -0000175461 00000 n -0000175647 00000 n -0000176221 00000 n -0000176350 00000 n -0000725524 00000 n -0000180646 00000 n -0000180326 00000 n -0000176541 00000 n -0000180452 00000 n -0000180581 00000 n -0000184122 00000 n -0000183743 00000 n -0000180771 00000 n -0000184057 00000 n -0000183890 00000 n -0000187139 00000 n -0000187334 00000 n -0000186884 00000 n -0000184234 00000 n -0000187010 00000 n -0000187204 00000 n -0000187269 00000 n -0000190703 00000 n -0000190512 00000 n -0000187446 00000 n -0000190638 00000 n -0000195014 00000 n -0000194436 00000 n -0000190815 00000 n -0000194562 00000 n -0000194691 00000 n -0000194756 00000 n -0000194821 00000 n -0000194950 00000 n -0000198225 00000 n -0000197183 00000 n -0000195126 00000 n -0000197644 00000 n -0000197773 00000 n -0000197339 00000 n -0000197491 00000 n -0000197902 00000 n -0000198031 00000 n -0000198160 00000 n -0000725649 00000 n -0000199777 00000 n -0000199586 00000 n -0000198337 00000 n -0000199712 00000 n -0000201300 00000 n -0000201109 00000 n -0000199876 00000 n -0000201235 00000 n -0000204105 00000 n -0000203785 00000 n -0000201399 00000 n -0000203911 00000 n -0000204040 00000 n -0000208528 00000 n -0000208159 00000 n -0000204243 00000 n -0000208463 00000 n -0000208306 00000 n -0000366981 00000 n -0000212499 00000 n -0000212179 00000 n -0000208640 00000 n -0000212305 00000 n -0000216337 00000 n -0000216017 00000 n -0000212624 00000 n -0000216143 00000 n -0000216208 00000 n -0000216272 00000 n -0000725774 00000 n -0000221633 00000 n -0000220341 00000 n -0000216462 00000 n -0000221568 00000 n -0000220533 00000 n -0000220687 00000 n -0000220842 00000 n -0000221027 00000 n -0000221201 00000 n -0000221386 00000 n -0000290835 00000 n -0000225939 00000 n -0000225748 00000 n -0000221814 00000 n -0000225874 00000 n -0000229702 00000 n -0000229511 00000 n -0000226064 00000 n -0000229637 00000 n -0000234015 00000 n -0000233073 00000 n -0000229814 00000 n -0000233563 00000 n -0000233692 00000 n -0000233229 00000 n -0000233821 00000 n -0000233950 00000 n -0000233397 00000 n -0000304312 00000 n -0000237811 00000 n -0000237249 00000 n -0000234127 00000 n -0000237746 00000 n -0000237405 00000 n -0000237576 00000 n -0000384536 00000 n -0000241235 00000 n -0000240788 00000 n -0000237980 00000 n -0000240914 00000 n -0000241042 00000 n -0000241171 00000 n -0000725899 00000 n -0000244802 00000 n -0000244611 00000 n -0000241360 00000 n -0000244737 00000 n -0000248211 00000 n -0000247891 00000 n -0000244971 00000 n -0000248017 00000 n -0000251891 00000 n -0000251700 00000 n -0000248367 00000 n -0000251826 00000 n -0000256213 00000 n -0000255399 00000 n -0000252060 00000 n -0000255890 00000 n -0000256019 00000 n -0000255555 00000 n -0000256148 00000 n -0000255715 00000 n -0000260364 00000 n -0000259868 00000 n -0000256368 00000 n -0000260170 00000 n -0000260299 00000 n -0000260015 00000 n -0000264002 00000 n -0000263553 00000 n -0000260489 00000 n -0000263679 00000 n -0000263808 00000 n -0000263937 00000 n -0000726024 00000 n -0000267909 00000 n -0000267242 00000 n -0000264157 00000 n -0000267715 00000 n -0000267844 00000 n -0000267398 00000 n -0000267560 00000 n -0000271438 00000 n -0000270798 00000 n -0000268078 00000 n -0000271114 00000 n -0000270945 00000 n -0000271308 00000 n -0000271373 00000 n -0000275474 00000 n -0000274971 00000 n -0000271621 00000 n -0000275280 00000 n -0000275409 00000 n -0000275118 00000 n -0000280264 00000 n -0000279585 00000 n -0000275642 00000 n -0000280070 00000 n -0000279741 00000 n -0000544109 00000 n -0000542110 00000 n -0000543944 00000 n -0000280199 00000 n -0000279902 00000 n -0000363552 00000 n -0000299250 00000 n -0000283673 00000 n -0000283353 00000 n -0000280390 00000 n -0000283479 00000 n -0000283608 00000 n -0000287365 00000 n -0000287046 00000 n -0000283798 00000 n -0000287172 00000 n -0000726149 00000 n -0000290900 00000 n -0000290451 00000 n -0000287507 00000 n -0000290577 00000 n -0000290706 00000 n -0000295399 00000 n -0000294607 00000 n -0000291012 00000 n -0000295077 00000 n -0000294763 00000 n -0000294915 00000 n -0000295206 00000 n -0000295335 00000 n -0000299315 00000 n -0000298562 00000 n -0000295511 00000 n -0000298863 00000 n -0000298992 00000 n -0000299121 00000 n -0000298709 00000 n -0000302758 00000 n -0000302438 00000 n -0000299427 00000 n -0000302564 00000 n -0000302693 00000 n -0000304377 00000 n -0000304057 00000 n -0000302870 00000 n -0000304183 00000 n -0000305902 00000 n -0000305711 00000 n -0000304489 00000 n -0000305837 00000 n -0000726274 00000 n -0000308815 00000 n -0000308236 00000 n -0000306001 00000 n -0000308362 00000 n -0000308491 00000 n -0000308620 00000 n -0000308685 00000 n -0000308750 00000 n -0000313010 00000 n -0000312501 00000 n -0000308927 00000 n -0000312816 00000 n -0000312648 00000 n -0000312945 00000 n -0000523056 00000 n -0000318900 00000 n -0000316165 00000 n -0000313122 00000 n -0000318706 00000 n -0000318835 00000 n -0000316429 00000 n -0000316591 00000 n -0000316753 00000 n -0000316914 00000 n -0000317074 00000 n -0000317236 00000 n -0000317407 00000 n -0000317569 00000 n -0000317731 00000 n -0000317894 00000 n -0000318057 00000 n -0000318220 00000 n -0000318383 00000 n -0000318546 00000 n -0000324121 00000 n -0000322204 00000 n -0000319012 00000 n -0000324056 00000 n -0000322432 00000 n -0000322595 00000 n -0000322762 00000 n -0000322931 00000 n -0000323093 00000 n -0000323254 00000 n -0000323416 00000 n -0000323577 00000 n -0000323740 00000 n -0000323893 00000 n -0000330286 00000 n -0000327279 00000 n -0000324246 00000 n -0000330092 00000 n -0000327561 00000 n -0000327714 00000 n -0000327868 00000 n -0000328019 00000 n -0000328173 00000 n -0000328334 00000 n -0000328496 00000 n -0000328658 00000 n -0000328820 00000 n -0000328982 00000 n -0000329144 00000 n -0000329306 00000 n -0000329458 00000 n -0000329621 00000 n -0000329776 00000 n -0000329938 00000 n -0000333816 00000 n -0000333495 00000 n -0000330398 00000 n -0000333621 00000 n -0000333686 00000 n -0000333751 00000 n -0000726399 00000 n -0000338041 00000 n -0000336845 00000 n -0000333985 00000 n -0000337332 00000 n -0000337461 00000 n -0000337718 00000 n -0000337001 00000 n -0000337171 00000 n -0000337783 00000 n -0000337848 00000 n -0000337913 00000 n -0000337977 00000 n -0000341388 00000 n -0000341197 00000 n -0000338223 00000 n -0000341323 00000 n -0000345128 00000 n -0000344807 00000 n -0000341474 00000 n -0000344933 00000 n -0000344998 00000 n -0000345063 00000 n -0000348960 00000 n -0000348253 00000 n -0000345240 00000 n -0000348379 00000 n -0000348508 00000 n -0000348571 00000 n -0000348636 00000 n -0000348701 00000 n -0000348766 00000 n -0000348895 00000 n -0000352712 00000 n -0000351874 00000 n -0000349072 00000 n -0000352000 00000 n -0000352065 00000 n -0000352130 00000 n -0000352259 00000 n -0000352324 00000 n -0000352389 00000 n -0000352518 00000 n -0000352583 00000 n -0000352647 00000 n -0000355833 00000 n -0000355128 00000 n -0000352837 00000 n -0000355254 00000 n -0000355382 00000 n -0000355511 00000 n -0000355640 00000 n -0000355769 00000 n -0000726524 00000 n -0000359611 00000 n -0000359161 00000 n -0000356030 00000 n -0000359287 00000 n -0000359416 00000 n -0000359481 00000 n -0000359546 00000 n -0000363876 00000 n -0000363118 00000 n -0000359750 00000 n -0000363423 00000 n -0000363681 00000 n -0000363746 00000 n -0000363811 00000 n -0000363265 00000 n -0000367434 00000 n -0000366726 00000 n -0000364001 00000 n -0000366852 00000 n -0000367110 00000 n -0000367239 00000 n -0000367304 00000 n -0000367369 00000 n -0000371121 00000 n -0000370487 00000 n -0000367546 00000 n -0000370799 00000 n -0000370634 00000 n -0000370928 00000 n -0000370992 00000 n -0000371056 00000 n -0000523023 00000 n -0000375100 00000 n -0000374394 00000 n -0000371233 00000 n -0000374520 00000 n -0000374648 00000 n -0000374713 00000 n -0000374778 00000 n -0000374907 00000 n -0000374972 00000 n -0000375036 00000 n -0000377643 00000 n -0000377323 00000 n -0000375226 00000 n -0000377449 00000 n -0000541829 00000 n -0000534545 00000 n -0000541649 00000 n -0000377578 00000 n -0000726649 00000 n -0000378124 00000 n -0000377933 00000 n -0000377783 00000 n -0000378059 00000 n -0000380016 00000 n -0000379568 00000 n -0000378166 00000 n -0000379694 00000 n -0000379823 00000 n -0000379952 00000 n -0000384601 00000 n -0000383658 00000 n -0000380128 00000 n -0000384021 00000 n -0000534224 00000 n -0000525011 00000 n -0000534038 00000 n -0000383805 00000 n -0000384150 00000 n -0000384278 00000 n -0000384407 00000 n -0000385643 00000 n -0000385452 00000 n -0000384838 00000 n -0000385578 00000 n -0000386070 00000 n -0000385879 00000 n -0000385729 00000 n -0000386005 00000 n -0000389383 00000 n -0000388157 00000 n -0000386112 00000 n -0000388674 00000 n -0000388803 00000 n +0000072403 00000 n +0000071593 00000 n +0000069338 00000 n +0000071715 00000 n +0000071839 00000 n +0000071964 00000 n +0000072089 00000 n +0000072214 00000 n +0000072277 00000 n +0000072340 00000 n +0000614265 00000 n +0000595948 00000 n +0000614092 00000 n +0000733501 00000 n +0000076974 00000 n +0000075794 00000 n +0000072527 00000 n +0000076288 00000 n +0000076351 00000 n +0000076414 00000 n +0000076538 00000 n +0000076663 00000 n +0000076788 00000 n +0000075944 00000 n +0000076137 00000 n +0000076911 00000 n +0000340366 00000 n +0000400138 00000 n +0000081629 00000 n +0000080593 00000 n +0000077098 00000 n +0000081066 00000 n +0000081191 00000 n +0000080743 00000 n +0000080905 00000 n +0000081316 00000 n +0000081441 00000 n +0000081566 00000 n +0000097562 00000 n +0000084851 00000 n +0000084291 00000 n +0000081753 00000 n +0000084413 00000 n +0000084538 00000 n +0000084663 00000 n +0000084788 00000 n +0000088278 00000 n +0000087137 00000 n +0000084962 00000 n +0000087591 00000 n +0000087716 00000 n +0000087841 00000 n +0000087966 00000 n +0000088091 00000 n +0000087287 00000 n +0000087439 00000 n +0000088215 00000 n +0000289730 00000 n +0000089367 00000 n +0000089049 00000 n +0000088363 00000 n +0000089174 00000 n +0000089302 00000 n +0000091465 00000 n +0000090762 00000 n +0000089466 00000 n +0000090888 00000 n +0000091016 00000 n +0000091143 00000 n +0000091271 00000 n +0000091400 00000 n +0000733620 00000 n +0000094394 00000 n +0000093505 00000 n +0000091564 00000 n +0000093813 00000 n +0000093942 00000 n +0000094007 00000 n +0000094072 00000 n +0000093652 00000 n +0000094201 00000 n +0000094330 00000 n +0000273532 00000 n +0000097755 00000 n +0000097307 00000 n +0000094506 00000 n +0000097433 00000 n +0000595273 00000 n +0000583284 00000 n +0000595094 00000 n +0000097690 00000 n +0000101577 00000 n +0000101386 00000 n +0000097881 00000 n +0000101512 00000 n +0000582743 00000 n +0000572999 00000 n +0000582564 00000 n +0000106188 00000 n +0000105789 00000 n +0000101743 00000 n +0000106123 00000 n +0000105936 00000 n +0000174987 00000 n +0000108534 00000 n +0000108084 00000 n +0000106327 00000 n +0000108210 00000 n +0000108339 00000 n +0000108404 00000 n +0000108469 00000 n +0000111263 00000 n +0000113810 00000 n +0000111107 00000 n +0000108659 00000 n +0000113229 00000 n +0000113358 00000 n +0000113487 00000 n +0000112906 00000 n +0000113068 00000 n +0000572101 00000 n +0000562305 00000 n +0000571927 00000 n +0000561741 00000 n +0000552655 00000 n +0000561566 00000 n +0000113616 00000 n +0000113745 00000 n +0000733745 00000 n +0000112735 00000 n +0000112793 00000 n +0000112883 00000 n +0000215305 00000 n +0000250427 00000 n +0000118474 00000 n +0000117539 00000 n +0000113966 00000 n +0000118023 00000 n +0000118152 00000 n +0000117695 00000 n +0000117861 00000 n +0000118281 00000 n +0000118410 00000 n +0000404165 00000 n +0000122133 00000 n +0000121753 00000 n +0000118626 00000 n +0000122068 00000 n +0000121900 00000 n +0000123358 00000 n +0000123167 00000 n +0000122258 00000 n +0000123293 00000 n +0000126061 00000 n +0000125483 00000 n +0000123457 00000 n +0000125609 00000 n +0000125738 00000 n +0000125867 00000 n +0000125996 00000 n +0000129240 00000 n +0000128533 00000 n +0000126199 00000 n +0000128659 00000 n +0000128788 00000 n +0000128917 00000 n +0000129046 00000 n +0000129175 00000 n +0000133547 00000 n +0000132649 00000 n +0000129365 00000 n +0000132967 00000 n +0000133096 00000 n +0000132796 00000 n +0000133225 00000 n +0000133354 00000 n +0000133482 00000 n +0000733870 00000 n +0000332997 00000 n +0000137583 00000 n +0000137005 00000 n +0000133672 00000 n +0000137131 00000 n +0000137260 00000 n +0000137389 00000 n +0000137518 00000 n +0000141178 00000 n +0000140858 00000 n +0000137721 00000 n +0000140984 00000 n +0000141113 00000 n +0000144624 00000 n +0000144124 00000 n +0000141290 00000 n +0000144430 00000 n +0000552380 00000 n +0000549022 00000 n +0000552201 00000 n +0000144559 00000 n +0000144271 00000 n +0000399880 00000 n +0000146352 00000 n +0000145905 00000 n +0000144806 00000 n +0000146031 00000 n +0000146160 00000 n +0000146287 00000 n +0000146805 00000 n +0000146614 00000 n +0000146464 00000 n +0000146740 00000 n +0000149419 00000 n +0000148841 00000 n +0000146847 00000 n +0000148967 00000 n +0000149096 00000 n +0000149225 00000 n +0000149354 00000 n +0000733995 00000 n +0000149859 00000 n +0000149668 00000 n +0000149518 00000 n +0000149794 00000 n +0000153861 00000 n +0000153095 00000 n +0000149901 00000 n +0000153409 00000 n +0000153538 00000 n +0000153666 00000 n +0000153731 00000 n +0000153796 00000 n +0000153242 00000 n +0000158357 00000 n +0000158549 00000 n +0000158102 00000 n +0000153960 00000 n +0000158228 00000 n +0000158484 00000 n +0000162428 00000 n +0000161851 00000 n +0000158674 00000 n +0000161977 00000 n +0000162105 00000 n +0000162234 00000 n +0000162363 00000 n +0000165247 00000 n +0000166626 00000 n +0000165121 00000 n +0000162566 00000 n +0000166173 00000 n +0000166302 00000 n +0000166431 00000 n +0000166496 00000 n +0000166561 00000 n +0000169703 00000 n +0000168996 00000 n +0000166781 00000 n +0000169122 00000 n +0000169251 00000 n +0000169379 00000 n +0000169444 00000 n +0000169509 00000 n +0000169638 00000 n +0000734120 00000 n +0000175310 00000 n +0000174392 00000 n +0000169815 00000 n +0000174858 00000 n +0000174548 00000 n +0000174699 00000 n +0000175116 00000 n +0000175245 00000 n +0000527648 00000 n +0000179149 00000 n +0000177878 00000 n +0000175448 00000 n +0000178568 00000 n +0000178697 00000 n +0000178826 00000 n +0000178043 00000 n +0000178195 00000 n +0000178381 00000 n +0000178955 00000 n +0000179084 00000 n +0000183380 00000 n +0000183060 00000 n +0000179275 00000 n +0000183186 00000 n +0000183315 00000 n +0000186856 00000 n +0000186477 00000 n +0000183505 00000 n +0000186791 00000 n +0000186624 00000 n +0000189873 00000 n +0000190068 00000 n +0000189618 00000 n +0000186968 00000 n +0000189744 00000 n +0000189938 00000 n +0000190003 00000 n +0000193437 00000 n +0000193246 00000 n +0000190180 00000 n +0000193372 00000 n +0000734245 00000 n +0000197748 00000 n +0000197170 00000 n +0000193549 00000 n +0000197296 00000 n +0000197425 00000 n +0000197490 00000 n +0000197555 00000 n +0000197684 00000 n +0000200959 00000 n +0000199917 00000 n +0000197860 00000 n +0000200378 00000 n +0000200507 00000 n +0000200073 00000 n +0000200225 00000 n +0000200636 00000 n +0000200765 00000 n +0000200894 00000 n +0000202511 00000 n +0000202320 00000 n +0000201071 00000 n +0000202446 00000 n +0000204046 00000 n +0000203855 00000 n +0000202610 00000 n +0000203981 00000 n +0000206969 00000 n +0000206649 00000 n +0000204145 00000 n +0000206775 00000 n +0000206904 00000 n +0000211399 00000 n +0000211030 00000 n +0000207107 00000 n +0000211334 00000 n +0000211177 00000 n +0000734370 00000 n +0000369874 00000 n +0000215370 00000 n +0000215050 00000 n +0000211511 00000 n +0000215176 00000 n +0000219208 00000 n +0000218888 00000 n +0000215495 00000 n +0000219014 00000 n +0000219079 00000 n +0000219143 00000 n +0000224504 00000 n +0000223212 00000 n +0000219333 00000 n +0000224439 00000 n +0000223404 00000 n +0000223558 00000 n +0000223713 00000 n +0000223898 00000 n +0000224072 00000 n +0000224257 00000 n +0000293103 00000 n +0000228807 00000 n +0000228616 00000 n +0000224685 00000 n +0000228742 00000 n +0000232570 00000 n +0000232379 00000 n +0000228932 00000 n +0000232505 00000 n +0000236884 00000 n +0000235941 00000 n +0000232682 00000 n +0000236432 00000 n +0000236561 00000 n +0000236097 00000 n +0000236690 00000 n +0000236819 00000 n +0000236266 00000 n +0000734495 00000 n +0000307088 00000 n +0000240544 00000 n +0000239982 00000 n +0000236996 00000 n +0000240479 00000 n +0000240138 00000 n +0000240309 00000 n +0000387589 00000 n +0000243797 00000 n +0000243477 00000 n +0000240713 00000 n +0000243603 00000 n +0000243732 00000 n +0000247313 00000 n +0000246993 00000 n +0000243922 00000 n +0000247119 00000 n +0000247248 00000 n +0000250492 00000 n +0000250172 00000 n +0000247425 00000 n +0000250298 00000 n +0000254305 00000 n +0000254114 00000 n +0000250648 00000 n +0000254240 00000 n +0000258187 00000 n +0000257558 00000 n +0000254460 00000 n +0000257865 00000 n +0000257994 00000 n +0000257705 00000 n +0000258123 00000 n +0000734620 00000 n +0000262381 00000 n +0000261702 00000 n +0000258356 00000 n +0000262187 00000 n +0000261858 00000 n +0000262316 00000 n +0000262032 00000 n +0000266404 00000 n +0000265955 00000 n +0000262493 00000 n +0000266081 00000 n +0000266210 00000 n +0000266339 00000 n +0000270440 00000 n +0000269774 00000 n +0000266559 00000 n +0000270247 00000 n +0000270376 00000 n +0000269930 00000 n +0000270092 00000 n +0000273727 00000 n +0000273088 00000 n +0000270609 00000 n +0000273403 00000 n +0000273235 00000 n +0000273597 00000 n +0000273662 00000 n +0000277537 00000 n +0000277034 00000 n +0000273853 00000 n +0000277343 00000 n +0000277472 00000 n +0000277181 00000 n +0000282138 00000 n +0000281764 00000 n +0000277719 00000 n +0000282073 00000 n +0000281911 00000 n +0000548667 00000 n +0000546669 00000 n +0000548502 00000 n +0000734745 00000 n +0000366305 00000 n +0000286039 00000 n +0000285403 00000 n +0000282264 00000 n +0000285716 00000 n +0000285845 00000 n +0000285550 00000 n +0000285974 00000 n +0000302020 00000 n +0000289795 00000 n +0000289475 00000 n +0000286164 00000 n +0000289601 00000 n +0000293168 00000 n +0000292719 00000 n +0000289950 00000 n +0000292845 00000 n +0000292974 00000 n +0000297929 00000 n +0000297265 00000 n +0000293280 00000 n +0000297735 00000 n +0000297421 00000 n +0000297573 00000 n +0000297864 00000 n +0000302085 00000 n +0000301204 00000 n +0000298041 00000 n +0000301504 00000 n +0000301633 00000 n +0000301762 00000 n +0000301891 00000 n +0000301351 00000 n +0000305528 00000 n +0000305208 00000 n +0000302197 00000 n +0000305334 00000 n +0000305463 00000 n +0000734870 00000 n +0000307153 00000 n +0000306833 00000 n +0000305640 00000 n +0000306959 00000 n +0000308678 00000 n +0000308487 00000 n +0000307265 00000 n +0000308613 00000 n +0000311591 00000 n +0000311012 00000 n +0000308777 00000 n +0000311138 00000 n +0000311267 00000 n +0000311396 00000 n +0000311461 00000 n +0000311526 00000 n +0000315786 00000 n +0000315277 00000 n +0000311703 00000 n +0000315592 00000 n +0000315424 00000 n +0000315721 00000 n +0000527615 00000 n +0000321676 00000 n +0000318941 00000 n +0000315898 00000 n +0000321482 00000 n +0000321611 00000 n +0000319205 00000 n +0000319367 00000 n +0000319529 00000 n +0000319690 00000 n +0000319850 00000 n +0000320012 00000 n +0000320183 00000 n +0000320345 00000 n +0000320507 00000 n +0000320670 00000 n +0000320833 00000 n +0000320996 00000 n +0000321159 00000 n +0000321322 00000 n +0000326897 00000 n +0000324980 00000 n +0000321788 00000 n +0000326832 00000 n +0000325208 00000 n +0000325371 00000 n +0000325538 00000 n +0000325707 00000 n +0000325869 00000 n +0000326030 00000 n +0000326192 00000 n +0000326353 00000 n +0000326516 00000 n +0000326669 00000 n +0000734995 00000 n +0000333062 00000 n +0000330055 00000 n +0000327022 00000 n +0000332868 00000 n +0000330337 00000 n +0000330490 00000 n +0000330644 00000 n +0000330795 00000 n +0000330949 00000 n +0000331110 00000 n +0000331272 00000 n +0000331434 00000 n +0000331596 00000 n +0000331758 00000 n +0000331920 00000 n +0000332082 00000 n +0000332234 00000 n +0000332397 00000 n +0000332552 00000 n +0000332714 00000 n +0000336592 00000 n +0000336271 00000 n +0000333174 00000 n +0000336397 00000 n +0000336462 00000 n +0000336527 00000 n +0000340817 00000 n +0000339621 00000 n +0000336761 00000 n +0000340108 00000 n +0000340237 00000 n +0000340494 00000 n +0000339777 00000 n +0000339947 00000 n +0000340559 00000 n +0000340624 00000 n +0000340689 00000 n +0000340753 00000 n +0000344164 00000 n +0000343973 00000 n +0000340999 00000 n +0000344099 00000 n +0000347904 00000 n +0000347583 00000 n +0000344250 00000 n +0000347709 00000 n +0000347774 00000 n +0000347839 00000 n +0000351736 00000 n +0000351029 00000 n +0000348016 00000 n +0000351155 00000 n +0000351284 00000 n +0000351347 00000 n +0000351412 00000 n +0000351477 00000 n +0000351542 00000 n +0000351671 00000 n +0000735120 00000 n +0000355488 00000 n +0000354650 00000 n +0000351848 00000 n +0000354776 00000 n +0000354841 00000 n +0000354906 00000 n +0000355035 00000 n +0000355100 00000 n +0000355165 00000 n +0000355294 00000 n +0000355359 00000 n +0000355423 00000 n +0000358831 00000 n +0000358124 00000 n +0000355613 00000 n +0000358250 00000 n +0000358379 00000 n +0000358508 00000 n +0000358637 00000 n +0000358766 00000 n +0000362736 00000 n +0000362158 00000 n +0000359028 00000 n +0000362284 00000 n +0000362413 00000 n +0000362541 00000 n +0000362606 00000 n +0000362671 00000 n +0000366629 00000 n +0000366050 00000 n +0000362875 00000 n +0000366176 00000 n +0000366434 00000 n +0000366499 00000 n +0000366564 00000 n +0000370327 00000 n +0000369438 00000 n +0000366754 00000 n +0000369745 00000 n +0000369585 00000 n +0000370003 00000 n +0000370132 00000 n +0000370197 00000 n +0000370262 00000 n +0000374079 00000 n +0000373447 00000 n +0000370439 00000 n +0000373759 00000 n +0000373594 00000 n +0000373888 00000 n +0000373951 00000 n +0000374014 00000 n +0000735245 00000 n +0000527582 00000 n +0000377549 00000 n +0000377100 00000 n +0000374191 00000 n +0000377226 00000 n +0000377354 00000 n +0000377419 00000 n +0000377484 00000 n +0000380695 00000 n +0000380117 00000 n +0000377661 00000 n +0000380243 00000 n +0000380372 00000 n +0000380437 00000 n +0000380501 00000 n +0000546388 00000 n +0000539104 00000 n +0000546208 00000 n +0000380630 00000 n +0000381176 00000 n +0000380985 00000 n +0000380835 00000 n +0000381111 00000 n +0000383068 00000 n +0000382620 00000 n +0000381218 00000 n +0000382746 00000 n +0000382875 00000 n +0000383004 00000 n +0000387654 00000 n +0000386711 00000 n +0000383180 00000 n +0000387074 00000 n +0000538783 00000 n +0000529570 00000 n +0000538597 00000 n +0000386858 00000 n +0000387203 00000 n +0000387331 00000 n +0000387460 00000 n +0000388696 00000 n +0000388505 00000 n +0000387891 00000 n +0000388631 00000 n +0000735370 00000 n +0000389123 00000 n 0000388932 00000 n -0000389061 00000 n -0000389190 00000 n -0000389319 00000 n -0000388313 00000 n -0000388485 00000 n -0000726774 00000 n -0000389837 00000 n -0000389646 00000 n -0000389496 00000 n -0000389772 00000 n -0000393081 00000 n -0000392503 00000 n -0000389879 00000 n -0000392629 00000 n -0000392758 00000 n -0000392887 00000 n -0000393016 00000 n -0000397276 00000 n -0000396058 00000 n -0000393167 00000 n -0000396568 00000 n -0000396697 00000 n -0000396955 00000 n -0000396214 00000 n -0000396393 00000 n -0000397148 00000 n -0000397212 00000 n -0000404163 00000 n -0000400335 00000 n -0000397429 00000 n -0000400461 00000 n -0000400526 00000 n -0000400591 00000 n -0000400656 00000 n -0000400721 00000 n -0000400786 00000 n -0000400851 00000 n -0000400916 00000 n -0000400981 00000 n -0000401046 00000 n -0000401176 00000 n -0000401241 00000 n -0000401306 00000 n -0000401371 00000 n -0000401436 00000 n -0000401501 00000 n -0000401566 00000 n -0000401631 00000 n -0000401696 00000 n -0000401761 00000 n -0000401826 00000 n -0000401891 00000 n -0000401956 00000 n -0000402021 00000 n -0000402086 00000 n -0000402151 00000 n -0000402216 00000 n -0000402281 00000 n -0000402346 00000 n -0000402411 00000 n -0000402476 00000 n -0000402541 00000 n -0000402606 00000 n -0000402671 00000 n -0000402735 00000 n -0000402800 00000 n -0000402865 00000 n -0000402930 00000 n -0000402995 00000 n -0000403060 00000 n -0000403125 00000 n -0000403190 00000 n -0000403255 00000 n -0000403320 00000 n -0000403385 00000 n -0000403450 00000 n +0000388782 00000 n +0000389058 00000 n +0000392436 00000 n +0000391210 00000 n +0000389165 00000 n +0000391727 00000 n +0000391856 00000 n +0000391985 00000 n +0000392114 00000 n +0000392243 00000 n +0000392372 00000 n +0000391366 00000 n +0000391538 00000 n +0000392890 00000 n +0000392699 00000 n +0000392549 00000 n +0000392825 00000 n +0000396135 00000 n +0000395557 00000 n +0000392932 00000 n +0000395683 00000 n +0000395812 00000 n +0000395941 00000 n +0000396070 00000 n +0000400330 00000 n +0000399112 00000 n +0000396221 00000 n +0000399622 00000 n +0000399751 00000 n +0000400009 00000 n +0000399268 00000 n +0000399447 00000 n +0000400202 00000 n +0000400266 00000 n +0000407217 00000 n +0000403389 00000 n +0000400483 00000 n 0000403515 00000 n 0000403580 00000 n 0000403645 00000 n @@ -13895,431 +14018,482 @@ xref 0000403905 00000 n 0000403970 00000 n 0000404035 00000 n -0000404099 00000 n -0000410809 00000 n -0000407245 00000 n -0000404275 00000 n -0000407371 00000 n -0000407436 00000 n -0000407501 00000 n -0000407566 00000 n -0000407631 00000 n -0000407696 00000 n -0000407761 00000 n -0000407826 00000 n -0000407891 00000 n -0000407956 00000 n -0000408021 00000 n -0000408086 00000 n -0000408150 00000 n -0000408215 00000 n -0000408280 00000 n -0000408345 00000 n -0000408410 00000 n -0000408475 00000 n -0000408540 00000 n -0000408605 00000 n -0000408670 00000 n -0000408735 00000 n -0000408800 00000 n -0000408865 00000 n -0000408929 00000 n -0000408994 00000 n -0000409059 00000 n -0000409124 00000 n -0000409189 00000 n -0000409254 00000 n -0000409319 00000 n -0000409384 00000 n -0000409449 00000 n -0000409514 00000 n -0000409579 00000 n -0000409644 00000 n -0000409709 00000 n -0000409774 00000 n -0000409839 00000 n -0000409904 00000 n -0000409968 00000 n -0000410032 00000 n -0000410096 00000 n -0000410161 00000 n -0000410226 00000 n -0000410291 00000 n -0000410356 00000 n -0000410421 00000 n -0000410486 00000 n -0000410551 00000 n -0000410616 00000 n -0000410681 00000 n -0000410745 00000 n -0000416982 00000 n -0000413544 00000 n -0000410921 00000 n +0000404100 00000 n +0000404230 00000 n +0000404295 00000 n +0000404360 00000 n +0000404425 00000 n +0000404490 00000 n +0000404555 00000 n +0000404620 00000 n +0000404685 00000 n +0000404750 00000 n +0000404815 00000 n +0000404880 00000 n +0000404945 00000 n +0000405010 00000 n +0000405075 00000 n +0000405140 00000 n +0000405205 00000 n +0000405270 00000 n +0000405335 00000 n +0000405400 00000 n +0000405465 00000 n +0000405530 00000 n +0000405595 00000 n +0000405660 00000 n +0000405725 00000 n +0000405789 00000 n +0000405854 00000 n +0000405919 00000 n +0000405984 00000 n +0000406049 00000 n +0000406114 00000 n +0000406179 00000 n +0000406244 00000 n +0000406309 00000 n +0000406374 00000 n +0000406439 00000 n +0000406504 00000 n +0000406569 00000 n +0000406634 00000 n +0000406699 00000 n +0000406764 00000 n +0000406829 00000 n +0000406894 00000 n +0000406959 00000 n +0000407024 00000 n +0000407089 00000 n +0000407153 00000 n +0000735495 00000 n +0000413863 00000 n +0000410299 00000 n +0000407329 00000 n +0000410425 00000 n +0000410490 00000 n +0000410555 00000 n +0000410620 00000 n +0000410685 00000 n +0000410750 00000 n +0000410815 00000 n +0000410880 00000 n +0000410945 00000 n +0000411010 00000 n +0000411075 00000 n +0000411140 00000 n +0000411204 00000 n +0000411269 00000 n +0000411334 00000 n +0000411399 00000 n +0000411464 00000 n +0000411529 00000 n +0000411594 00000 n +0000411659 00000 n +0000411724 00000 n +0000411789 00000 n +0000411854 00000 n +0000411919 00000 n +0000411983 00000 n +0000412048 00000 n +0000412113 00000 n +0000412178 00000 n +0000412243 00000 n +0000412308 00000 n +0000412373 00000 n +0000412438 00000 n +0000412503 00000 n +0000412568 00000 n +0000412633 00000 n +0000412698 00000 n +0000412763 00000 n +0000412828 00000 n +0000412893 00000 n +0000412958 00000 n +0000413022 00000 n +0000413086 00000 n +0000413150 00000 n +0000413215 00000 n +0000413280 00000 n +0000413345 00000 n +0000413410 00000 n +0000413475 00000 n +0000413540 00000 n +0000413605 00000 n 0000413670 00000 n 0000413735 00000 n -0000413800 00000 n -0000413865 00000 n -0000413930 00000 n -0000413995 00000 n -0000414060 00000 n -0000414125 00000 n -0000414190 00000 n -0000414255 00000 n -0000414320 00000 n -0000414385 00000 n -0000414450 00000 n -0000414515 00000 n -0000414580 00000 n -0000414645 00000 n -0000414710 00000 n -0000414775 00000 n -0000414840 00000 n -0000414905 00000 n -0000414970 00000 n -0000415035 00000 n -0000415100 00000 n -0000415165 00000 n -0000415230 00000 n -0000415295 00000 n -0000415360 00000 n -0000415425 00000 n -0000415490 00000 n -0000415555 00000 n -0000415620 00000 n -0000415685 00000 n -0000415750 00000 n -0000415815 00000 n -0000415879 00000 n -0000415944 00000 n -0000416009 00000 n -0000416074 00000 n -0000416139 00000 n -0000416204 00000 n -0000416269 00000 n -0000416334 00000 n -0000416399 00000 n -0000416464 00000 n -0000416529 00000 n -0000416594 00000 n -0000416659 00000 n +0000413799 00000 n +0000420036 00000 n +0000416598 00000 n +0000413975 00000 n 0000416724 00000 n 0000416789 00000 n 0000416854 00000 n -0000416918 00000 n -0000726899 00000 n -0000421560 00000 n -0000419296 00000 n -0000417094 00000 n -0000419422 00000 n -0000419487 00000 n -0000419552 00000 n -0000419617 00000 n -0000419682 00000 n -0000419747 00000 n -0000419812 00000 n -0000419877 00000 n -0000419942 00000 n -0000420007 00000 n -0000420072 00000 n -0000420137 00000 n -0000420202 00000 n -0000420267 00000 n -0000420329 00000 n -0000420393 00000 n -0000420458 00000 n -0000420522 00000 n -0000420587 00000 n -0000420652 00000 n -0000420717 00000 n -0000420782 00000 n -0000420847 00000 n -0000420912 00000 n -0000420977 00000 n -0000421106 00000 n -0000421235 00000 n -0000421300 00000 n -0000421365 00000 n -0000421430 00000 n -0000421495 00000 n -0000424355 00000 n -0000423711 00000 n -0000421685 00000 n -0000423837 00000 n +0000416919 00000 n +0000416984 00000 n +0000417049 00000 n +0000417114 00000 n +0000417179 00000 n +0000417244 00000 n +0000417309 00000 n +0000417374 00000 n +0000417439 00000 n +0000417504 00000 n +0000417569 00000 n +0000417634 00000 n +0000417699 00000 n +0000417764 00000 n +0000417829 00000 n +0000417894 00000 n +0000417959 00000 n +0000418024 00000 n +0000418089 00000 n +0000418154 00000 n +0000418219 00000 n +0000418284 00000 n +0000418349 00000 n +0000418414 00000 n +0000418479 00000 n +0000418544 00000 n +0000418609 00000 n +0000418674 00000 n +0000418739 00000 n +0000418804 00000 n +0000418869 00000 n +0000418933 00000 n +0000418998 00000 n +0000419063 00000 n +0000419128 00000 n +0000419193 00000 n +0000419258 00000 n +0000419323 00000 n +0000419388 00000 n +0000419453 00000 n +0000419518 00000 n +0000419583 00000 n +0000419648 00000 n +0000419713 00000 n +0000419778 00000 n +0000419843 00000 n +0000419908 00000 n +0000419972 00000 n +0000424614 00000 n +0000422350 00000 n +0000420148 00000 n +0000422476 00000 n +0000422541 00000 n +0000422606 00000 n +0000422671 00000 n +0000422736 00000 n +0000422801 00000 n +0000422866 00000 n +0000422931 00000 n +0000422996 00000 n +0000423061 00000 n +0000423126 00000 n +0000423191 00000 n +0000423256 00000 n +0000423321 00000 n +0000423383 00000 n +0000423447 00000 n +0000423512 00000 n +0000423576 00000 n +0000423641 00000 n +0000423706 00000 n +0000423771 00000 n +0000423836 00000 n +0000423901 00000 n 0000423966 00000 n -0000424095 00000 n +0000424031 00000 n 0000424160 00000 n -0000424225 00000 n -0000424290 00000 n -0000428694 00000 n -0000428374 00000 n -0000424468 00000 n -0000428500 00000 n -0000428565 00000 n -0000428630 00000 n -0000432294 00000 n -0000432039 00000 n -0000428847 00000 n -0000432165 00000 n -0000432230 00000 n -0000435543 00000 n -0000435352 00000 n -0000432433 00000 n -0000435478 00000 n -0000439271 00000 n -0000439015 00000 n -0000435669 00000 n -0000439141 00000 n -0000439206 00000 n -0000727024 00000 n -0000442111 00000 n -0000441403 00000 n -0000439410 00000 n -0000441529 00000 n -0000441594 00000 n -0000441659 00000 n -0000441724 00000 n -0000441789 00000 n -0000441918 00000 n -0000441983 00000 n -0000442047 00000 n -0000446779 00000 n -0000446523 00000 n -0000442250 00000 n -0000446649 00000 n -0000446714 00000 n -0000449730 00000 n -0000448957 00000 n -0000446905 00000 n -0000449083 00000 n -0000449148 00000 n -0000449213 00000 n -0000449278 00000 n -0000449407 00000 n -0000449472 00000 n -0000449535 00000 n -0000449600 00000 n -0000449665 00000 n -0000452331 00000 n -0000451622 00000 n -0000449883 00000 n -0000451748 00000 n -0000451813 00000 n -0000451878 00000 n -0000451943 00000 n -0000452008 00000 n -0000452073 00000 n -0000452202 00000 n -0000452267 00000 n -0000455355 00000 n -0000454970 00000 n -0000452483 00000 n -0000455096 00000 n -0000455161 00000 n -0000455225 00000 n -0000455290 00000 n -0000458450 00000 n -0000457676 00000 n -0000455495 00000 n -0000457802 00000 n -0000457867 00000 n -0000457932 00000 n -0000457997 00000 n -0000458126 00000 n -0000458191 00000 n -0000458256 00000 n -0000458320 00000 n -0000458385 00000 n -0000727149 00000 n -0000461723 00000 n -0000461532 00000 n -0000458616 00000 n -0000461658 00000 n -0000464823 00000 n -0000464113 00000 n -0000461849 00000 n -0000464239 00000 n -0000464304 00000 n -0000464369 00000 n -0000464434 00000 n -0000464499 00000 n -0000464628 00000 n -0000464693 00000 n -0000464758 00000 n -0000468481 00000 n -0000468162 00000 n -0000464988 00000 n -0000468288 00000 n -0000468353 00000 n -0000468417 00000 n -0000471857 00000 n -0000471666 00000 n -0000468607 00000 n -0000471792 00000 n -0000474868 00000 n -0000474418 00000 n -0000471997 00000 n -0000474544 00000 n -0000474609 00000 n -0000474674 00000 n -0000474739 00000 n -0000474804 00000 n -0000477300 00000 n -0000476526 00000 n -0000475006 00000 n -0000476652 00000 n -0000476781 00000 n -0000476846 00000 n -0000476911 00000 n -0000476976 00000 n -0000477041 00000 n -0000477106 00000 n -0000477171 00000 n -0000477236 00000 n -0000727274 00000 n -0000480529 00000 n -0000479949 00000 n -0000477453 00000 n -0000480075 00000 n -0000480204 00000 n -0000480269 00000 n -0000480334 00000 n -0000480399 00000 n -0000480464 00000 n -0000483987 00000 n -0000483796 00000 n -0000480669 00000 n -0000483922 00000 n -0000486972 00000 n -0000486197 00000 n -0000484113 00000 n -0000486323 00000 n -0000486388 00000 n -0000486453 00000 n -0000486518 00000 n -0000486647 00000 n -0000486712 00000 n -0000486777 00000 n -0000486842 00000 n -0000486907 00000 n -0000490279 00000 n -0000490088 00000 n -0000487125 00000 n -0000490214 00000 n -0000493070 00000 n -0000492684 00000 n -0000490490 00000 n -0000492810 00000 n -0000492875 00000 n -0000492940 00000 n -0000493005 00000 n -0000497081 00000 n -0000496436 00000 n -0000493307 00000 n -0000496562 00000 n -0000496627 00000 n -0000496692 00000 n -0000496821 00000 n -0000496886 00000 n -0000496951 00000 n -0000497016 00000 n -0000727399 00000 n -0000501017 00000 n -0000500761 00000 n -0000497220 00000 n -0000500887 00000 n -0000500952 00000 n -0000504237 00000 n -0000503981 00000 n -0000501143 00000 n -0000504107 00000 n -0000504172 00000 n -0000506951 00000 n -0000506307 00000 n -0000504363 00000 n -0000506433 00000 n -0000506498 00000 n -0000506563 00000 n -0000506628 00000 n -0000506757 00000 n -0000506822 00000 n -0000506887 00000 n -0000510720 00000 n -0000510335 00000 n -0000507103 00000 n -0000510461 00000 n -0000510526 00000 n -0000510590 00000 n -0000510655 00000 n -0000514311 00000 n -0000513666 00000 n -0000510860 00000 n -0000513792 00000 n -0000513857 00000 n -0000513922 00000 n -0000514051 00000 n -0000514116 00000 n -0000514181 00000 n -0000514246 00000 n -0000516582 00000 n -0000516326 00000 n -0000514463 00000 n -0000516452 00000 n -0000516517 00000 n -0000727524 00000 n -0000520063 00000 n -0000519289 00000 n -0000516721 00000 n -0000519415 00000 n -0000519480 00000 n -0000519545 00000 n -0000519610 00000 n -0000519738 00000 n -0000519803 00000 n -0000519868 00000 n -0000519933 00000 n -0000519998 00000 n -0000522871 00000 n -0000522485 00000 n -0000520216 00000 n -0000522611 00000 n -0000522676 00000 n -0000522741 00000 n -0000522806 00000 n -0000523122 00000 n -0000534466 00000 n -0000542055 00000 n -0000544356 00000 n -0000544325 00000 n -0000553849 00000 n -0000563962 00000 n -0000574436 00000 n -0000587060 00000 n -0000606125 00000 n -0000627012 00000 n -0000649155 00000 n -0000667050 00000 n -0000669880 00000 n -0000669650 00000 n -0000697187 00000 n -0000724298 00000 n -0000727622 00000 n -0000727746 00000 n -0000727872 00000 n -0000727998 00000 n -0000728115 00000 n -0000728207 00000 n -0000744729 00000 n -0000763926 00000 n -0000763967 00000 n -0000764007 00000 n -0000764141 00000 n +0000424289 00000 n +0000424354 00000 n +0000424419 00000 n +0000424484 00000 n +0000424549 00000 n +0000427409 00000 n +0000426765 00000 n +0000424739 00000 n +0000426891 00000 n +0000427020 00000 n +0000427149 00000 n +0000427214 00000 n +0000427279 00000 n +0000427344 00000 n +0000431747 00000 n +0000431427 00000 n +0000427522 00000 n +0000431553 00000 n +0000431618 00000 n +0000431683 00000 n +0000435347 00000 n +0000435092 00000 n +0000431900 00000 n +0000435218 00000 n +0000435283 00000 n +0000735620 00000 n +0000438595 00000 n +0000438404 00000 n +0000435486 00000 n +0000438530 00000 n +0000442326 00000 n +0000442070 00000 n +0000438721 00000 n +0000442196 00000 n +0000442261 00000 n +0000445166 00000 n +0000444458 00000 n +0000442465 00000 n +0000444584 00000 n +0000444649 00000 n +0000444714 00000 n +0000444779 00000 n +0000444844 00000 n +0000444973 00000 n +0000445038 00000 n +0000445102 00000 n +0000449834 00000 n +0000449578 00000 n +0000445305 00000 n +0000449704 00000 n +0000449769 00000 n +0000452785 00000 n +0000452012 00000 n +0000449960 00000 n +0000452138 00000 n +0000452203 00000 n +0000452268 00000 n +0000452333 00000 n +0000452462 00000 n +0000452527 00000 n +0000452590 00000 n +0000452655 00000 n +0000452720 00000 n +0000455386 00000 n +0000454677 00000 n +0000452938 00000 n +0000454803 00000 n +0000454868 00000 n +0000454933 00000 n +0000454998 00000 n +0000455063 00000 n +0000455128 00000 n +0000455257 00000 n +0000455322 00000 n +0000735745 00000 n +0000458629 00000 n +0000458243 00000 n +0000455538 00000 n +0000458369 00000 n +0000458434 00000 n +0000458499 00000 n +0000458564 00000 n +0000461762 00000 n +0000460989 00000 n +0000458769 00000 n +0000461115 00000 n +0000461180 00000 n +0000461245 00000 n +0000461309 00000 n +0000461437 00000 n +0000461502 00000 n +0000461567 00000 n +0000461632 00000 n +0000461697 00000 n +0000465149 00000 n +0000464958 00000 n +0000461928 00000 n +0000465084 00000 n +0000468258 00000 n +0000467548 00000 n +0000465275 00000 n +0000467674 00000 n +0000467739 00000 n +0000467804 00000 n +0000467869 00000 n +0000467934 00000 n +0000468063 00000 n +0000468128 00000 n +0000468193 00000 n +0000471809 00000 n +0000471488 00000 n +0000468423 00000 n +0000471614 00000 n +0000471679 00000 n +0000471744 00000 n +0000475255 00000 n +0000475064 00000 n +0000471935 00000 n +0000475190 00000 n +0000735870 00000 n +0000478326 00000 n +0000478007 00000 n +0000475381 00000 n +0000478133 00000 n +0000478198 00000 n +0000478262 00000 n +0000480897 00000 n +0000480059 00000 n +0000478479 00000 n +0000480185 00000 n +0000480250 00000 n +0000480315 00000 n +0000480444 00000 n +0000480509 00000 n +0000480574 00000 n +0000480639 00000 n +0000480704 00000 n +0000480768 00000 n +0000480833 00000 n +0000483864 00000 n +0000483220 00000 n +0000481050 00000 n +0000483346 00000 n +0000483411 00000 n +0000483540 00000 n +0000483605 00000 n +0000483669 00000 n +0000483734 00000 n +0000483799 00000 n +0000487337 00000 n +0000487146 00000 n +0000484004 00000 n +0000487272 00000 n +0000490144 00000 n +0000489370 00000 n +0000487463 00000 n +0000489496 00000 n +0000489561 00000 n +0000489626 00000 n +0000489691 00000 n +0000489820 00000 n +0000489885 00000 n +0000489950 00000 n +0000490014 00000 n +0000490079 00000 n +0000493547 00000 n +0000493356 00000 n +0000490297 00000 n +0000493482 00000 n +0000735995 00000 n +0000496582 00000 n +0000496262 00000 n +0000493758 00000 n +0000496388 00000 n +0000496453 00000 n +0000496518 00000 n +0000499891 00000 n +0000499182 00000 n +0000496806 00000 n +0000499308 00000 n +0000499373 00000 n +0000499438 00000 n +0000499502 00000 n +0000499631 00000 n +0000499696 00000 n +0000499761 00000 n +0000499826 00000 n +0000504307 00000 n +0000504051 00000 n +0000500043 00000 n +0000504177 00000 n +0000504242 00000 n +0000507840 00000 n +0000507649 00000 n +0000504433 00000 n +0000507775 00000 n +0000510426 00000 n +0000509976 00000 n +0000507966 00000 n +0000510102 00000 n +0000510167 00000 n +0000510232 00000 n +0000510297 00000 n +0000510362 00000 n +0000514258 00000 n +0000513678 00000 n +0000510564 00000 n +0000513804 00000 n +0000513933 00000 n +0000513998 00000 n +0000514063 00000 n +0000514128 00000 n +0000514193 00000 n +0000736120 00000 n +0000517420 00000 n +0000516710 00000 n +0000514398 00000 n +0000516836 00000 n +0000516901 00000 n +0000516966 00000 n +0000517031 00000 n +0000517160 00000 n +0000517225 00000 n +0000517290 00000 n +0000517355 00000 n +0000520137 00000 n +0000519881 00000 n +0000517572 00000 n +0000520007 00000 n +0000520072 00000 n +0000523391 00000 n +0000522618 00000 n +0000520263 00000 n +0000522744 00000 n +0000522809 00000 n +0000522874 00000 n +0000522939 00000 n +0000523068 00000 n +0000523133 00000 n +0000523198 00000 n +0000523262 00000 n +0000523327 00000 n +0000526677 00000 n +0000526358 00000 n +0000523543 00000 n +0000526484 00000 n +0000526549 00000 n +0000526614 00000 n +0000527483 00000 n +0000527227 00000 n +0000526829 00000 n +0000527353 00000 n +0000527418 00000 n +0000527681 00000 n +0000539025 00000 n +0000546614 00000 n +0000548914 00000 n +0000548883 00000 n +0000552600 00000 n +0000562040 00000 n +0000572547 00000 n +0000583031 00000 n +0000595655 00000 n +0000614720 00000 n +0000635607 00000 n +0000657750 00000 n +0000675645 00000 n +0000678475 00000 n +0000678245 00000 n +0000705782 00000 n +0000732893 00000 n +0000736245 00000 n +0000736369 00000 n +0000736495 00000 n +0000736621 00000 n +0000736738 00000 n +0000736830 00000 n +0000753445 00000 n +0000772757 00000 n +0000772798 00000 n +0000772838 00000 n +0000772972 00000 n trailer << -/Size 2150 -/Root 2148 0 R -/Info 2149 0 R -/ID [ ] +/Size 2172 +/Root 2170 0 R +/Info 2171 0 R +/ID [<5A3C18693D743104F54A9671E6A3E513> <5A3C18693D743104F54A9671E6A3E513>] >> startxref -764399 +773230 %%EOF diff --git a/contrib/bind9/doc/arm/man.dig.html b/contrib/bind9/doc/arm/man.dig.html index 2758a8f0713..bf39f83b80f 100644 --- a/contrib/bind9/doc/arm/man.dig.html +++ b/contrib/bind9/doc/arm/man.dig.html @@ -1,8 +1,8 @@ - + @@ -52,7 +52,7 @@

    dig [global-queryopt...] [query...]

    -

    DESCRIPTION

    +

    DESCRIPTION

    dig (domain information groper) is a flexible tool for interrogating DNS name servers. It performs DNS lookups and @@ -98,7 +98,7 @@

    -

    SIMPLE USAGE

    +

    SIMPLE USAGE

    A typical invocation of dig looks like:

    @@ -144,7 +144,7 @@

    -

    OPTIONS

    +

    OPTIONS

    The -b option sets the source IP address of the query to address. This must be a valid @@ -248,7 +248,7 @@

    -

    QUERY OPTIONS

    +

    QUERY OPTIONS

    dig provides a number of query options which affect the way in which lookups are made and the results displayed. Some of @@ -573,7 +573,7 @@

    -

    MULTIPLE QUERIES

    +

    MULTIPLE QUERIES

    The BIND 9 implementation of dig supports @@ -619,7 +619,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr

    -

    IDN SUPPORT

    +

    IDN SUPPORT

    If dig has been built with IDN (internationalized domain name) support, it can accept and display non-ASCII domain names. @@ -633,14 +633,14 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr

    -

    FILES

    +

    FILES

    /etc/resolv.conf

    ${HOME}/.digrc

    -

    SEE ALSO

    +

    SEE ALSO

    host(1), named(8), dnssec-keygen(8), @@ -648,7 +648,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr

    -

    BUGS

    +

    BUGS

    There are probably too many query options.

    diff --git a/contrib/bind9/doc/arm/man.dnssec-dsfromkey.html b/contrib/bind9/doc/arm/man.dnssec-dsfromkey.html index f9a20e36074..be8c7497494 100644 --- a/contrib/bind9/doc/arm/man.dnssec-dsfromkey.html +++ b/contrib/bind9/doc/arm/man.dnssec-dsfromkey.html @@ -1,8 +1,8 @@ - + @@ -51,14 +51,14 @@

    dnssec-dsfromkey {-s} [-v level] [-1] [-2] [-a alg] [-c class] [-d dir] {dnsname}

    -

    DESCRIPTION

    +

    DESCRIPTION

    dnssec-dsfromkey outputs the Delegation Signer (DS) resource record (RR), as defined in RFC 3658 and RFC 4509, for the given key(s).

    -

    OPTIONS

    +

    OPTIONS

    -1

    @@ -99,7 +99,7 @@

    -

    EXAMPLE

    +

    EXAMPLE

    To build the SHA-256 DS RR from the Kexample.com.+003+26160 @@ -114,7 +114,7 @@

    -

    FILES

    +

    FILES

    The keyfile can be designed by the key identification Knnnn.+aaa+iiiii or the full file name @@ -128,13 +128,13 @@

    -

    CAVEAT

    +

    CAVEAT

    A keyfile error can give a "file not found" even if the file exists.

    -

    SEE ALSO

    +

    SEE ALSO

    dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, @@ -143,7 +143,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html b/contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html index c885dbec1c6..849528ebcf0 100644 --- a/contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html +++ b/contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html @@ -1,8 +1,8 @@ - + @@ -50,7 +50,7 @@

    dnssec-keyfromlabel {-a algorithm} {-l label} [-c class] [-f flag] [-k] [-n nametype] [-p protocol] [-t type] [-v level] {name}

    -

    DESCRIPTION

    +

    DESCRIPTION

    dnssec-keyfromlabel gets keys with the given label from a crypto hardware and builds key files for DNSSEC (Secure DNS), as defined in RFC 2535 @@ -58,16 +58,24 @@

    -

    OPTIONS

    +

    OPTIONS

    -a algorithm

    Selects the cryptographic algorithm. The value of - algorithm must be one of RSAMD5 (RSA) - or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman). + algorithm must be one of RSAMD5, + RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, + RSASHA512 or DH (Diffie Hellman). These values are case insensitive.

    +

    + If no algorithm is specified, then RSASHA1 will be used by + default, unless the -3 option is specified, + in which case NSEC3RSASHA1 will be used instead. (If + -3 is used and an algorithm is specified, + that algorithm will be checked for compatibility with NSEC3.) +

    Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. @@ -131,7 +139,7 @@

    -

    GENERATED KEY FILES

    +

    GENERATED KEY FILES

    When dnssec-keyfromlabel completes successfully, @@ -172,17 +180,15 @@

    -

    SEE ALSO

    +

    SEE ALSO

    dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, - RFC 2539, - RFC 2845, - RFC 4033. + RFC 4034.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.dnssec-keygen.html b/contrib/bind9/doc/arm/man.dnssec-keygen.html index 17d08e2fd10..8c00bec6adb 100644 --- a/contrib/bind9/doc/arm/man.dnssec-keygen.html +++ b/contrib/bind9/doc/arm/man.dnssec-keygen.html @@ -1,8 +1,8 @@ - + @@ -50,23 +50,31 @@

    dnssec-keygen {-a algorithm} {-b keysize} {-n nametype} [-c class] [-e] [-f flag] [-g generator] [-h] [-k] [-p protocol] [-r randomdev] [-s strength] [-t type] [-v level] {name}

    -

    DESCRIPTION

    +

    DESCRIPTION

    dnssec-keygen generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845.

    +

    + The name of the key is specified on the command + line. For DNSSEC keys, this must match the name of the zone for + which the key is being generated. +

    -

    OPTIONS

    +

    OPTIONS

    -a algorithm

    - Selects the cryptographic algorithm. The value of - algorithm must be one of RSAMD5 (RSA) or RSASHA1, - DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC-MD5. - These values are case insensitive. + Selects the cryptographic algorithm. For DNSSEC keys, the value + of algorithm must be one of RSAMD5, RSASHA1, + DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. + For TSIG/TKEY, the value must + be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, + HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are + case insensitive.

    Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement @@ -80,11 +88,10 @@

    -b keysize

    Specifies the number of bits in the key. The choice of key - size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be - between - 512 and 2048 bits. Diffie Hellman keys must be between + size depends on the algorithm used. RSA keys must be + between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 - bits and an exact multiple of 64. HMAC-MD5 keys must be + bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits.

    -n nametype
    @@ -166,7 +173,7 @@
    -

    GENERATED KEYS

    +

    GENERATED KEYS

    When dnssec-keygen completes successfully, @@ -212,7 +219,7 @@

    -

    EXAMPLE

    +

    EXAMPLE

    To generate a 768-bit DSA key for the domain example.com, the following command would be @@ -233,16 +240,16 @@

    -

    SEE ALSO

    +

    SEE ALSO

    dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 2539, RFC 2845, - RFC 4033. + RFC 4034.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.dnssec-signzone.html b/contrib/bind9/doc/arm/man.dnssec-signzone.html index 40c09764bd1..5ecf0b8070f 100644 --- a/contrib/bind9/doc/arm/man.dnssec-signzone.html +++ b/contrib/bind9/doc/arm/man.dnssec-signzone.html @@ -1,8 +1,8 @@ - + @@ -47,21 +47,21 @@

    Synopsis

    -

    dnssec-signzone [-a] [-c class] [-d directory] [-e end-time] [-f output-file] [-g] [-h] [-k key] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-p] [-r randomdev] [-s start-time] [-t] [-v level] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

    +

    dnssec-signzone [-a] [-c class] [-d directory] [-e end-time] [-f output-file] [-g] [-h] [-k key] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-p] [-P] [-r randomdev] [-s start-time] [-t] [-v level] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

    -

    DESCRIPTION

    +

    DESCRIPTION

    dnssec-signzone signs a zone. It generates NSEC and RRSIG records and produces a signed version of the - zone. The security status of delegations from the signed zone - (that is, whether the child zones are secure or not) is - determined by the presence or absence of a - keyset file for each child zone. + zone. It also generates a keyset- file containing + the key-signing keys for the zone, and if signing a zone which + contains delegations, it can optionally generate DS records for + the child zones from their keyset- files.

    -

    OPTIONS

    +

    OPTIONS

    -a

    @@ -88,8 +88,10 @@

    -g

    - Generate DS records for child zones from keyset files. - Existing DS records will be removed. + If the zone contains any delegations, and there are + keyset- files for any of the child zones, + then DS records for the child zones will be generated from the + keys in those files. Existing DS records will be removed.

    -s start-time

    @@ -220,6 +222,19 @@ may be useful when signing large zones or when the entropy source is limited.

    +
    -P
    +
    +

    + Disable post sign verification tests. +

    +

    + The post sign verification test ensures that for each algorithm + in use there is at least one non revoked self signed KSK key, + that all revoked KSK keys are self signed, and that all records + in the zone are signed by the algorithm. + This option skips these tests. +

    +
    -r randomdev

    Specifies the source of randomness. If the operating @@ -276,7 +291,7 @@

    -

    EXAMPLE

    +

    EXAMPLE

    The following command signs the example.com zone with the DSA key generated by dnssec-keygen @@ -305,7 +320,7 @@ db.example.com.signed %

    -

    KNOWN BUGS

    +

    KNOWN BUGS

    dnssec-signzone was designed so that it could sign a zone partially, using only a subset of the DNSSEC keys @@ -330,14 +345,14 @@ db.example.com.signed

    -

    SEE ALSO

    +

    SEE ALSO

    dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 4033.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.host.html b/contrib/bind9/doc/arm/man.host.html index 22f6731dba1..7f9eeb9cae1 100644 --- a/contrib/bind9/doc/arm/man.host.html +++ b/contrib/bind9/doc/arm/man.host.html @@ -1,8 +1,8 @@ - + @@ -50,7 +50,7 @@

    host [-aCdlnrsTwv] [-c class] [-N ndots] [-R number] [-t type] [-W wait] [-m flag] [-4] [-6] {name} [server]

    -

    DESCRIPTION

    +

    DESCRIPTION

    host is a simple utility for performing DNS lookups. It is normally used to convert names to IP addresses and vice versa. @@ -202,7 +202,7 @@

    -

    IDN SUPPORT

    +

    IDN SUPPORT

    If host has been built with IDN (internationalized domain name) support, it can accept and display non-ASCII domain names. @@ -216,12 +216,12 @@

    -

    FILES

    +

    FILES

    /etc/resolv.conf

    -

    SEE ALSO

    +

    SEE ALSO

    dig(1), named(8).

    diff --git a/contrib/bind9/doc/arm/man.named-checkconf.html b/contrib/bind9/doc/arm/man.named-checkconf.html index 94c22f69c4f..9d4c0ed2ad0 100644 --- a/contrib/bind9/doc/arm/man.named-checkconf.html +++ b/contrib/bind9/doc/arm/man.named-checkconf.html @@ -1,8 +1,8 @@ - + @@ -50,14 +50,14 @@

    named-checkconf [-h] [-v] [-j] [-t directory] {filename} [-z]

    -

    DESCRIPTION

    +

    DESCRIPTION

    named-checkconf checks the syntax, but not the semantics, of a named configuration file.

    -

    OPTIONS

    +

    OPTIONS

    -h

    @@ -92,21 +92,21 @@

    -

    RETURN VALUES

    +

    RETURN VALUES

    named-checkconf returns an exit status of 1 if errors were detected and 0 otherwise.

    -

    SEE ALSO

    +

    SEE ALSO

    named(8), named-checkzone(8), BIND 9 Administrator Reference Manual.

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.named-checkzone.html b/contrib/bind9/doc/arm/man.named-checkzone.html index b187a1a7112..a44e59fb5a3 100644 --- a/contrib/bind9/doc/arm/man.named-checkzone.html +++ b/contrib/bind9/doc/arm/man.named-checkzone.html @@ -1,8 +1,8 @@ - + @@ -47,11 +47,11 @@

    Synopsis

    -

    named-checkzone [-d] [-h] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-o filename] [-s style] [-S mode] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

    -

    named-compilezone [-d] [-j] [-q] [-v] [-c class] [-C mode] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-n mode] [-o filename] [-s style] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

    +

    named-checkzone [-d] [-h] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-s style] [-S mode] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

    +

    named-compilezone [-d] [-j] [-q] [-v] [-c class] [-C mode] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-n mode] [-o filename] [-s style] [-t directory] [-w directory] [-D] [-W mode] {-o filename} {zonename} {filename}

    -

    DESCRIPTION

    +

    DESCRIPTION

    named-checkzone checks the syntax and integrity of a zone file. It performs the same checks as named does when loading a @@ -71,7 +71,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -d

    @@ -257,14 +257,14 @@

    -

    RETURN VALUES

    +

    RETURN VALUES

    named-checkzone returns an exit status of 1 if errors were detected and 0 otherwise.

    -

    SEE ALSO

    +

    SEE ALSO

    named(8), named-checkconf(8), RFC 1035, @@ -272,7 +272,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.named.html b/contrib/bind9/doc/arm/man.named.html index 2a440ce4b10..c3ba7fbd72e 100644 --- a/contrib/bind9/doc/arm/man.named.html +++ b/contrib/bind9/doc/arm/man.named.html @@ -1,8 +1,8 @@ - + @@ -50,7 +50,7 @@

    named [-4] [-6] [-c config-file] [-d debug-level] [-f] [-g] [-m flag] [-n #cpus] [-p port] [-s] [-S #max-socks] [-t directory] [-u user] [-v] [-V] [-x cache-file]

    -

    DESCRIPTION

    +

    DESCRIPTION

    named is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC. For more @@ -65,7 +65,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -4

    @@ -238,7 +238,7 @@

    -

    SIGNALS

    +

    SIGNALS

    In routine operation, signals should not be used to control the nameserver; rndc should be used @@ -259,16 +259,24 @@

    -

    CONFIGURATION

    +

    CONFIGURATION

    The named configuration file is too complex to describe in detail here. A complete description is provided in the BIND 9 Administrator Reference Manual.

    +

    + named inherits the umask + (file creation mode mask) from the parent process. If files + created by named, such as journal files, + need to have custom permissions, the umask + should be set explicitly in the script used to start the + named process. +

    -

    FILES

    +

    FILES

    /etc/named.conf

    @@ -281,7 +289,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    RFC 1033, RFC 1034, RFC 1035, @@ -294,7 +302,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.nsupdate.html b/contrib/bind9/doc/arm/man.nsupdate.html index eb3b7bec285..9ba954b803d 100644 --- a/contrib/bind9/doc/arm/man.nsupdate.html +++ b/contrib/bind9/doc/arm/man.nsupdate.html @@ -1,8 +1,8 @@ - + @@ -50,7 +50,7 @@

    nsupdate [-d] [-D] [[-g] | [-o] | [-y [hmac:]keyname:secret] | [-k keyfile]] [-t timeout] [-u udptimeout] [-r udpretries] [-R randomdev] [-v] [filename]

    -

    DESCRIPTION

    +

    DESCRIPTION

    nsupdate is used to submit Dynamic DNS Update requests as defined in RFC2136 to a name server. @@ -187,7 +187,7 @@

    -

    INPUT FORMAT

    +

    INPUT FORMAT

    nsupdate reads input from filename @@ -451,7 +451,7 @@

    -

    EXAMPLES

    +

    EXAMPLES

    The examples below show how nsupdate @@ -505,7 +505,7 @@

    -

    FILES

    +

    FILES

    /etc/resolv.conf

    @@ -524,7 +524,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    RFC2136, RFC3007, RFC2104, @@ -537,7 +537,7 @@

    -

    BUGS

    +

    BUGS

    The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library diff --git a/contrib/bind9/doc/arm/man.rndc-confgen.html b/contrib/bind9/doc/arm/man.rndc-confgen.html index cb59c2ed722..853b2501d64 100644 --- a/contrib/bind9/doc/arm/man.rndc-confgen.html +++ b/contrib/bind9/doc/arm/man.rndc-confgen.html @@ -1,8 +1,8 @@ - + @@ -48,7 +48,7 @@

    rndc-confgen [-a] [-b keysize] [-c keyfile] [-h] [-k keyname] [-p port] [-r randomfile] [-s address] [-t chrootdir] [-u user]

    -

    DESCRIPTION

    +

    DESCRIPTION

    rndc-confgen generates configuration files for rndc. It can be used as a @@ -64,7 +64,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -a
    @@ -171,7 +171,7 @@
    -

    EXAMPLES

    +

    EXAMPLES

    To allow rndc to be used with no manual configuration, run @@ -188,7 +188,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    rndc(8), rndc.conf(5), named(8), @@ -196,7 +196,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.rndc.conf.html b/contrib/bind9/doc/arm/man.rndc.conf.html index e8e86ba6b13..66dbe9341ff 100644 --- a/contrib/bind9/doc/arm/man.rndc.conf.html +++ b/contrib/bind9/doc/arm/man.rndc.conf.html @@ -1,8 +1,8 @@ - + @@ -50,7 +50,7 @@

    rndc.conf

    -

    DESCRIPTION

    +

    DESCRIPTION

    rndc.conf is the configuration file for rndc, the BIND 9 name server control utility. This file has a similar structure and syntax to @@ -135,7 +135,7 @@

    -

    EXAMPLE

    +

    EXAMPLE

           options {
             default-server  localhost;
    @@ -209,7 +209,7 @@
         

    -

    NAME SERVER CONFIGURATION

    +

    NAME SERVER CONFIGURATION

    The name server must be configured to accept rndc connections and to recognize the key specified in the rndc.conf @@ -219,7 +219,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    rndc(8), rndc-confgen(8), mmencode(1), @@ -227,7 +227,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/arm/man.rndc.html b/contrib/bind9/doc/arm/man.rndc.html index 36843bc145b..0bb30850ef5 100644 --- a/contrib/bind9/doc/arm/man.rndc.html +++ b/contrib/bind9/doc/arm/man.rndc.html @@ -1,8 +1,8 @@ - + @@ -50,7 +50,7 @@

    rndc [-b source-address] [-c config-file] [-k key-file] [-s server] [-p port] [-V] [-y key_id] {command}

    -

    DESCRIPTION

    +

    DESCRIPTION

    rndc controls the operation of a name server. It supersedes the ndc utility @@ -79,7 +79,7 @@

    -

    OPTIONS

    +

    OPTIONS

    -b source-address

    @@ -151,7 +151,7 @@

    -

    LIMITATIONS

    +

    LIMITATIONS

    rndc does not yet support all the commands of the BIND 8 ndc utility. @@ -165,7 +165,7 @@

    -

    SEE ALSO

    +

    SEE ALSO

    rndc.conf(5), rndc-confgen(8), named(8), @@ -175,7 +175,7 @@

    -

    AUTHOR

    +

    AUTHOR

    Internet Systems Consortium

    diff --git a/contrib/bind9/doc/misc/Makefile.in b/contrib/bind9/doc/misc/Makefile.in index 501e3befd52..24ef3bc96aa 100644 --- a/contrib/bind9/doc/misc/Makefile.in +++ b/contrib/bind9/doc/misc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.7 2007/09/24 04:21:59 marka Exp $ +# $Id: Makefile.in,v 1.7.252.2 2009/07/11 23:47:17 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -38,11 +38,13 @@ docclean manclean maintainer-clean:: CFG_TEST = ../../bin/tests/cfg_test options: FORCE - if test -x ${CFG_TEST} && \ - ${CFG_TEST} --named --grammar | \ - ${PERL} ${srcdir}/sort-options.pl | \ - ${PERL} ${srcdir}/format-options.pl >$@.new ; then \ + if test -x ${CFG_TEST} ; \ + then \ + ${CFG_TEST} --named --grammar > $@.raw ; \ + ${PERL} ${srcdir}/sort-options.pl < $@.raw > $@.sorted ; \ + ${PERL} ${srcdir}/format-options.pl < $@.sorted > $@.new ; \ mv -f $@.new $@ ; \ + rm -f $@.raw $@.sorted ; \ else \ - rm -f $@.new ; \ + rm -f $@.new $@.raw $@.sorted ; \ fi diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api index 4bcf883246c..4fc7eca838c 100644 --- a/contrib/bind9/lib/dns/api +++ b/contrib/bind9/lib/dns/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 53 +LIBINTERFACE = 56 LIBREVISION = 0 -LIBAGE = 0 +LIBAGE = 1 diff --git a/contrib/bind9/lib/dns/db.c b/contrib/bind9/lib/dns/db.c index a4c28641701..02ea6b596ec 100644 --- a/contrib/bind9/lib/dns/db.c +++ b/contrib/bind9/lib/dns/db.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.c,v 1.88 2008/09/24 02:46:22 marka Exp $ */ +/* $Id: db.c,v 1.88.50.2 2009/06/23 00:19:34 tbox Exp $ */ /*! \file */ @@ -854,12 +854,14 @@ dns_db_unregister(dns_dbimplementation_t **dbimp) { RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); imp = *dbimp; + *dbimp = NULL; RWLOCK(&implock, isc_rwlocktype_write); ISC_LIST_UNLINK(implementations, imp, link); mctx = imp->mctx; isc_mem_put(mctx, imp, sizeof(dns_dbimplementation_t)); isc_mem_detach(&mctx); RWUNLOCK(&implock, isc_rwlocktype_write); + ENSURE(*dbimp == NULL); } isc_result_t diff --git a/contrib/bind9/lib/dns/dispatch.c b/contrib/bind9/lib/dns/dispatch.c index 9b4e9685f40..1d04961277b 100644 --- a/contrib/bind9/lib/dns/dispatch.c +++ b/contrib/bind9/lib/dns/dispatch.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dispatch.c,v 1.155.12.7 2009/04/28 21:39:45 jinmei Exp $ */ +/* $Id: dispatch.c,v 1.155.12.11 2009/12/02 23:26:28 marka Exp $ */ /*! \file */ @@ -746,13 +746,19 @@ new_portentry(dns_dispatch_t *disp, in_port_t port) { return (portentry); } +/*% + * The caller must not hold the qid->lock. + */ static void deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { dispportentry_t *portentry = *portentryp; + dns_qid_t *qid; REQUIRE(disp->port_table != NULL); REQUIRE(portentry != NULL && portentry->refs > 0); + qid = DNS_QID(disp); + LOCK(&qid->lock); portentry->refs--; if (portentry->refs == 0) { ISC_LIST_UNLINK(disp->port_table[portentry->port % @@ -762,6 +768,7 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { } *portentryp = NULL; + UNLOCK(&qid->lock); } /*% @@ -779,8 +786,9 @@ socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port, dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]); while (dispsock != NULL) { - if (isc_sockaddr_equal(dest, &dispsock->host) && - dispsock->portentry->port == port) + if (dispsock->portentry != NULL && + dispsock->portentry->port == port && + isc_sockaddr_equal(dest, &dispsock->host)) return (dispsock); dispsock = ISC_LIST_NEXT(dispsock, blink); } @@ -2048,8 +2056,18 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr, /* Create or adjust buffer pool */ if (mgr->bpool != NULL) { - isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); - mgr->maxbuffers = maxbuffers; + /* + * We only increase the maxbuffers to avoid accidental buffer + * shortage. Ideally we'd separate the manager-wide maximum + * from per-dispatch limits and respect the latter within the + * global limit. But at this moment that's deemed to be + * overkilling and isn't worth additional implementation + * complexity. + */ + if (maxbuffers > mgr->maxbuffers) { + isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); + mgr->maxbuffers = maxbuffers; + } } else { result = isc_mempool_create(mgr->mctx, buffersize, &mgr->bpool); if (result != ISC_R_SUCCESS) { diff --git a/contrib/bind9/lib/dns/dnssec.c b/contrib/bind9/lib/dns/dnssec.c index baf3ec5b12e..8ae29bceee9 100644 --- a/contrib/bind9/lib/dns/dnssec.c +++ b/contrib/bind9/lib/dns/dnssec.c @@ -16,7 +16,7 @@ */ /* - * $Id: dnssec.c,v 1.93.12.4 2009/06/08 23:47:00 tbox Exp $ + * $Id: dnssec.c,v 1.93.12.6 2009/06/22 23:47:18 tbox Exp $ */ /*! \file */ @@ -93,6 +93,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, isc_result_t ret; int i = 0, n; dns_rdata_t *data; + dns_rdataset_t rdataset; n = dns_rdataset_count(set); @@ -100,8 +101,11 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, if (data == NULL) return (ISC_R_NOMEMORY); - ret = dns_rdataset_first(set); + dns_rdataset_init(&rdataset); + dns_rdataset_clone(set, &rdataset); + ret = dns_rdataset_first(&rdataset); if (ret != ISC_R_SUCCESS) { + dns_rdataset_disassociate(&rdataset); isc_mem_put(mctx, data, n * sizeof(dns_rdata_t)); return (ret); } @@ -111,8 +115,8 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, */ do { dns_rdata_init(&data[i]); - dns_rdataset_current(set, &data[i++]); - } while (dns_rdataset_next(set) == ISC_R_SUCCESS); + dns_rdataset_current(&rdataset, &data[i++]); + } while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS); /* * Sort the array. @@ -120,6 +124,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper); *rdata = data; *nrdata = n; + dns_rdataset_disassociate(&rdataset); return (ISC_R_SUCCESS); } @@ -890,3 +895,59 @@ failure: return (result); } + +/*% + * Does this key ('rdata') self sign the rrset ('rdataset')? + */ +isc_boolean_t +dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, + isc_boolean_t ignoretime, isc_mem_t *mctx) +{ + dst_key_t *dstkey = NULL; + dns_keytag_t keytag; + dns_rdata_dnskey_t key; + dns_rdata_rrsig_t sig; + dns_rdata_t sigrdata = DNS_RDATA_INIT; + isc_result_t result; + + INSIST(rdataset->type == dns_rdatatype_key || + rdataset->type == dns_rdatatype_dnskey); + if (rdataset->type == dns_rdatatype_key) { + INSIST(sigrdataset->type == dns_rdatatype_sig); + INSIST(sigrdataset->covers == dns_rdatatype_key); + } else { + INSIST(sigrdataset->type == dns_rdatatype_rrsig); + INSIST(sigrdataset->covers == dns_rdatatype_dnskey); + } + + result = dns_dnssec_keyfromrdata(name, rdata, mctx, &dstkey); + if (result != ISC_R_SUCCESS) + return (ISC_FALSE); + result = dns_rdata_tostruct(rdata, &key, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + keytag = dst_key_id(dstkey); + for (result = dns_rdataset_first(sigrdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(sigrdataset)) + { + dns_rdata_reset(&sigrdata); + dns_rdataset_current(sigrdataset, &sigrdata); + result = dns_rdata_tostruct(&sigrdata, &sig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + if (sig.algorithm == key.algorithm && + sig.keyid == keytag) { + result = dns_dnssec_verify2(name, rdataset, dstkey, + ignoretime, mctx, + &sigrdata, NULL); + if (result == ISC_R_SUCCESS) { + dst_key_free(&dstkey); + return (ISC_TRUE); + } + } + } + dst_key_free(&dstkey); + return (ISC_FALSE); +} diff --git a/contrib/bind9/lib/dns/dst_api.c b/contrib/bind9/lib/dns/dst_api.c index 144c685e108..bbb0a09cc3a 100644 --- a/contrib/bind9/lib/dns/dst_api.c +++ b/contrib/bind9/lib/dns/dst_api.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -31,7 +31,7 @@ /* * Principal Author: Brian Wellington - * $Id: dst_api.c,v 1.16.12.3 2009/03/02 02:00:34 marka Exp $ + * $Id: dst_api.c,v 1.16.12.10 2010/01/15 19:38:53 each Exp $ */ /*! \file */ @@ -183,9 +183,16 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) { RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512])); #ifdef OPENSSL RETERR(dst__openssl_init()); - RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5])); - RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1])); - RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1])); + RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5], + DST_ALG_RSAMD5)); + RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1], + DST_ALG_RSASHA1)); + RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1], + DST_ALG_NSEC3RSASHA1)); + RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA256], + DST_ALG_RSASHA256)); + RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA512], + DST_ALG_RSASHA512)); #ifdef HAVE_OPENSSL_DSA RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA])); RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); @@ -848,6 +855,8 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: + case DST_ALG_RSASHA256: + case DST_ALG_RSASHA512: *n = (key->key_size + 7) / 8; break; case DST_ALG_DSA: @@ -1017,6 +1026,9 @@ dst_key_read_public(const char *filename, int type, /* Read the next word: either TTL, class, or 'KEY' */ NEXTTOKEN(lex, opt, &token); + if (token.type != isc_tokentype_string) + BADTOKEN(); + /* If it's a TTL, read the next one */ result = dns_ttl_fromtext(&token.value.as_textregion, &ttl); if (result == ISC_R_SUCCESS) @@ -1072,6 +1084,8 @@ issymmetric(const dst_key_t *key) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: + case DST_ALG_RSASHA256: + case DST_ALG_RSASHA512: case DST_ALG_DSA: case DST_ALG_NSEC3DSA: case DST_ALG_DH: @@ -1152,7 +1166,7 @@ write_public_key(const dst_key_t *key, int type, const char *directory) { fprintf(fp, " "); isc_buffer_usedregion(&classb, &r); - fwrite(r.base, 1, r.length, fp); + isc_util_fwrite(r.base, 1, r.length, fp); if ((type & DST_TYPE_KEY) != 0) fprintf(fp, " KEY "); @@ -1160,7 +1174,7 @@ write_public_key(const dst_key_t *key, int type, const char *directory) { fprintf(fp, " DNSKEY "); isc_buffer_usedregion(&textb, &r); - fwrite(r.base, 1, r.length, fp); + isc_util_fwrite(r.base, 1, r.length, fp); fputc('\n', fp); fflush(fp); @@ -1275,7 +1289,8 @@ algorithm_status(unsigned int alg) { if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || alg == DST_ALG_DSA || alg == DST_ALG_DH || alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA || - alg == DST_ALG_NSEC3RSASHA1) + alg == DST_ALG_NSEC3RSASHA1 || + alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512) return (DST_R_NOCRYPTO); #endif return (DST_R_UNSUPPORTEDALG); @@ -1297,6 +1312,8 @@ addsuffix(char *filename, unsigned int len, const char *ofilename, n = snprintf(filename, len, "%.*s%s", olen, ofilename, suffix); if (n < 0) + return (ISC_R_FAILURE); + if ((unsigned int)n >= len) return (ISC_R_NOSPACE); return (ISC_R_SUCCESS); } @@ -1304,6 +1321,9 @@ addsuffix(char *filename, unsigned int len, const char *ofilename, isc_result_t dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) { unsigned int flags = dst_entropy_flags; + + if (len == 0) + return (ISC_R_SUCCESS); if (pseudo) flags &= ~ISC_ENTROPY_GOODONLY; return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags)); @@ -1311,5 +1331,22 @@ dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) { unsigned int dst__entropy_status(void) { +#ifdef GSSAPI + unsigned int flags = dst_entropy_flags; + isc_result_t ret; + unsigned char buf[32]; + static isc_boolean_t first = ISC_TRUE; + + if (first) { + /* Someone believes RAND_status() initializes the PRNG */ + flags &= ~ISC_ENTROPY_GOODONLY; + ret = isc_entropy_getdata(dst_entropy_pool, buf, + sizeof(buf), NULL, flags); + INSIST(ret == ISC_R_SUCCESS); + isc_entropy_putdata(dst_entropy_pool, buf, + sizeof(buf), 2 * sizeof(buf)); + first = ISC_FALSE; + } +#endif return (isc_entropy_status(dst_entropy_pool)); } diff --git a/contrib/bind9/lib/dns/dst_internal.h b/contrib/bind9/lib/dns/dst_internal.h index 0c1a71c2256..16696487bc4 100644 --- a/contrib/bind9/lib/dns/dst_internal.h +++ b/contrib/bind9/lib/dns/dst_internal.h @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst_internal.h,v 1.11 2008/04/01 23:47:10 tbox Exp $ */ +/* $Id: dst_internal.h,v 1.11.120.2 2010/01/15 23:47:33 tbox Exp $ */ #ifndef DST_DST_INTERNAL_H #define DST_DST_INTERNAL_H 1 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -97,7 +98,7 @@ struct dst_key { void *generic; gss_ctx_id_t gssctx; #ifdef OPENSSL -#if USE_EVP_RSA +#if !defined(USE_EVP) || !USE_EVP RSA *rsa; #endif DSA *dsa; @@ -124,6 +125,8 @@ struct dst_context { dst_gssapi_signverifyctx_t *gssctx; isc_md5_t *md5ctx; isc_sha1_t *sha1ctx; + isc_sha256_t *sha256ctx; + isc_sha512_t *sha512ctx; isc_hmacmd5_t *hmacmd5ctx; isc_hmacsha1_t *hmacsha1ctx; isc_hmacsha224_t *hmacsha224ctx; @@ -183,7 +186,8 @@ isc_result_t dst__hmacsha224_init(struct dst_func **funcp); isc_result_t dst__hmacsha256_init(struct dst_func **funcp); isc_result_t dst__hmacsha384_init(struct dst_func **funcp); isc_result_t dst__hmacsha512_init(struct dst_func **funcp); -isc_result_t dst__opensslrsa_init(struct dst_func **funcp); +isc_result_t dst__opensslrsa_init(struct dst_func **funcp, + unsigned char algorithm); isc_result_t dst__openssldsa_init(struct dst_func **funcp); isc_result_t dst__openssldh_init(struct dst_func **funcp); isc_result_t dst__gssapi_init(struct dst_func **funcp); diff --git a/contrib/bind9/lib/dns/dst_parse.c b/contrib/bind9/lib/dns/dst_parse.c index 2da72ae6415..e8ab34ff757 100644 --- a/contrib/bind9/lib/dns/dst_parse.c +++ b/contrib/bind9/lib/dns/dst_parse.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -31,7 +31,7 @@ /*% * Principal Author: Brian Wellington - * $Id: dst_parse.c,v 1.14.120.2 2009/03/02 23:47:11 tbox Exp $ + * $Id: dst_parse.c,v 1.14.120.6 2010/01/15 19:38:53 each Exp $ */ #include @@ -480,6 +480,18 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, case DST_ALG_RSASHA1: fprintf(fp, "(RSASHA1)\n"); break; + case DST_ALG_NSEC3DSA: + fprintf(fp, "(NSEC3DSA)\n"); + break; + case DST_ALG_NSEC3RSASHA1: + fprintf(fp, "(NSEC3RSASHA1)\n"); + break; + case DST_ALG_RSASHA256: + fprintf(fp, "(RSASHA256)\n"); + break; + case DST_ALG_RSASHA512: + fprintf(fp, "(RSASHA512)\n"); + break; case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; @@ -521,7 +533,7 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, isc_buffer_usedregion(&b, &r); fprintf(fp, "%s ", s); - fwrite(r.base, 1, r.length, fp); + isc_util_fwrite(r.base, 1, r.length, fp); fprintf(fp, "\n"); } diff --git a/contrib/bind9/lib/dns/include/dns/db.h b/contrib/bind9/lib/dns/include/dns/db.h index c75c774143f..9a1126d7084 100644 --- a/contrib/bind9/lib/dns/include/dns/db.h +++ b/contrib/bind9/lib/dns/include/dns/db.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.h,v 1.93.50.3.12.1 2009/12/31 21:44:37 each Exp $ */ +/* $Id: db.h,v 1.93.50.5 2009/11/25 23:48:42 tbox Exp $ */ #ifndef DNS_DB_H #define DNS_DB_H 1 @@ -695,6 +695,10 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * For cache databases, glue is any rdataset with a trust of * dns_trust_glue. * + * \li If 'options' does not have #DNS_DBFIND_ADDITIONALOK set, then no + * additional records will be returned. Only caches can have + * rdataset with trust dns_trust_additional. + * * \li If 'options' does not have #DNS_DBFIND_PENDINGOK set, then no * pending data will be returned. This option is only meaningful for * cache databases. diff --git a/contrib/bind9/lib/dns/include/dns/dnssec.h b/contrib/bind9/lib/dns/include/dns/dnssec.h index c5206be63bb..14462664a1e 100644 --- a/contrib/bind9/lib/dns/include/dns/dnssec.h +++ b/contrib/bind9/lib/dns/include/dns/dnssec.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec.h,v 1.32.332.4 2009/06/08 23:47:00 tbox Exp $ */ +/* $Id: dnssec.h,v 1.32.332.6 2009/06/22 23:47:18 tbox Exp $ */ #ifndef DNS_DNSSEC_H #define DNS_DNSSEC_H 1 @@ -178,6 +178,12 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, *\li DST_R_* */ +isc_boolean_t +dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, + isc_boolean_t ignoretime, isc_mem_t *mctx); + + ISC_LANG_ENDDECLS #endif /* DNS_DNSSEC_H */ diff --git a/contrib/bind9/lib/dns/include/dns/journal.h b/contrib/bind9/lib/dns/include/dns/journal.h index 3917d8db9a0..a1e16e44878 100644 --- a/contrib/bind9/lib/dns/include/dns/journal.h +++ b/contrib/bind9/lib/dns/include/dns/journal.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: journal.h,v 1.33.120.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: journal.h,v 1.33.120.4 2009/11/04 23:47:25 tbox Exp $ */ #ifndef DNS_JOURNAL_H #define DNS_JOURNAL_H 1 @@ -232,12 +232,19 @@ dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl, isc_result_t dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options, const char *filename); + +isc_result_t +dns_journal_rollforward2(isc_mem_t *mctx, dns_db_t *db, unsigned int options, + isc_uint32_t resign, const char *filename); /*%< * Roll forward (play back) the journal file "filename" into the * database "db". This should be called when the server starts - * after a shutdown or crash. + * after a shutdown or crash. 'resign' is how many seconds before + * a RRSIG is due to expire it should be scheduled to be regenerated. * * Requires: + *\li dns_journal_rollforward() requires that DNS_JOURNALOPT_RESIGN + * is not set. *\li 'mctx' is a valid memory context. *\li 'db' is a valid database which does not have a version * open for writing. diff --git a/contrib/bind9/lib/dns/include/dns/keyvalues.h b/contrib/bind9/lib/dns/include/dns/keyvalues.h index 7f509e6ef13..f4a50fa606f 100644 --- a/contrib/bind9/lib/dns/include/dns/keyvalues.h +++ b/contrib/bind9/lib/dns/include/dns/keyvalues.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: keyvalues.h,v 1.23.48.2 2009/06/04 02:56:14 tbox Exp $ */ +/* $Id: keyvalues.h,v 1.23.48.4 2010/01/15 23:47:33 tbox Exp $ */ #ifndef DNS_KEYVALUES_H #define DNS_KEYVALUES_H 1 @@ -69,6 +69,8 @@ #define DNS_KEYALG_ECC 4 #define DNS_KEYALG_RSASHA1 5 #define DNS_KEYALG_NSEC3RSASHA1 7 +#define DNS_KEYALG_RSASHA256 8 +#define DNS_KEYALG_RSASHA512 10 #define DNS_KEYALG_INDIRECT 252 #define DNS_KEYALG_PRIVATEDNS 253 #define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */ diff --git a/contrib/bind9/lib/dns/include/dns/name.h b/contrib/bind9/lib/dns/include/dns/name.h index 0149301dcfb..dc6e525c1c8 100644 --- a/contrib/bind9/lib/dns/include/dns/name.h +++ b/contrib/bind9/lib/dns/include/dns/name.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.h,v 1.126.332.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: name.h,v 1.126.332.3 2009/12/24 00:34:59 each Exp $ */ #ifndef DNS_NAME_H #define DNS_NAME_H 1 @@ -98,12 +98,6 @@ ISC_LANG_BEGINDECLS ***** as they are in the actual DNS wire protocol. *****/ -/*** - *** Compression pointer chaining limit - ***/ - -#define DNS_POINTER_MAXHOPS 16 - /*** *** Types ***/ diff --git a/contrib/bind9/lib/dns/include/dns/ncache.h b/contrib/bind9/lib/dns/include/dns/ncache.h index d61684df88c..0677211719e 100644 --- a/contrib/bind9/lib/dns/include/dns/ncache.h +++ b/contrib/bind9/lib/dns/include/dns/ncache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ncache.h,v 1.25.142.1 2009/12/31 20:29:21 each Exp $ */ +/* $Id: ncache.h,v 1.25.48.2 2009/12/30 23:47:31 tbox Exp $ */ #ifndef DNS_NCACHE_H #define DNS_NCACHE_H 1 diff --git a/contrib/bind9/lib/dns/include/dns/nsec3.h b/contrib/bind9/lib/dns/include/dns/nsec3.h index 2d6a8dde8a7..6243fdb10f2 100644 --- a/contrib/bind9/lib/dns/include/dns/nsec3.h +++ b/contrib/bind9/lib/dns/include/dns/nsec3.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsec3.h,v 1.5.48.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: nsec3.h,v 1.5.48.3 2009/10/06 21:20:18 each Exp $ */ #ifndef DNS_NSEC3_H #define DNS_NSEC3_H 1 @@ -28,6 +28,8 @@ #include #include +#define DNS_NSEC3_SALTSIZE 255 + /* * hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max) * hash length = 1, hash = 255 (max), bitmap = 8192 + 512 (max) diff --git a/contrib/bind9/lib/dns/include/dns/rbt.h b/contrib/bind9/lib/dns/include/dns/rbt.h index 6eea787af88..26155965c83 100644 --- a/contrib/bind9/lib/dns/include/dns/rbt.h +++ b/contrib/bind9/lib/dns/include/dns/rbt.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbt.h,v 1.71.48.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: rbt.h,v 1.71.48.3 2009/10/20 05:06:04 marka Exp $ */ #ifndef DNS_RBT_H #define DNS_RBT_H 1 @@ -105,11 +105,11 @@ struct dns_rbtnode { unsigned int is_root : 1; /*%< range is 0..1 */ unsigned int color : 1; /*%< range is 0..1 */ unsigned int find_callback : 1; /*%< range is 0..1 */ - unsigned int attributes : 3; /*%< range is 0..2 */ + unsigned int attributes : 4; /*%< range is 0..2 */ unsigned int nsec3 : 1; /*%< range is 0..1 */ unsigned int namelen : 8; /*%< range is 1..255 */ unsigned int offsetlen : 8; /*%< range is 1..128 */ - unsigned int padbytes : 9; /*%< range is 0..380 */ + unsigned int oldnamelen : 8; /*%< range is 1..255 */ /*@}*/ #ifdef DNS_RBT_USEHASH diff --git a/contrib/bind9/lib/dns/include/dns/rdataset.h b/contrib/bind9/lib/dns/include/dns/rdataset.h index baff146fcad..d435ed009d4 100644 --- a/contrib/bind9/lib/dns/include/dns/rdataset.h +++ b/contrib/bind9/lib/dns/include/dns/rdataset.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.h,v 1.65.50.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: rdataset.h,v 1.65.50.2.22.2 2010/02/25 10:57:12 tbox Exp $ */ #ifndef DNS_RDATASET_H #define DNS_RDATASET_H 1 @@ -110,6 +110,9 @@ typedef struct dns_rdatasetmethods { dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype); + void (*settrust)(dns_rdataset_t *rdataset, + dns_trust_t trust); + void (*expire)(dns_rdataset_t *rdataset); } dns_rdatasetmethods_t; #define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R') @@ -634,6 +637,19 @@ dns_rdataset_putadditional(dns_acache_t *acache, * information for 'rdataset.' */ +void +dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); +/*%< + * Set the trust of the 'rdataset' to trust in any in the backing database. + * The local trust level of 'rdataset' is also set. + */ + +void +dns_rdataset_expire(dns_rdataset_t *rdataset); +/*%< + * Mark the rdataset to be expired in the backing database. + */ + ISC_LANG_ENDDECLS #endif /* DNS_RDATASET_H */ diff --git a/contrib/bind9/lib/dns/include/dns/resolver.h b/contrib/bind9/lib/dns/include/dns/resolver.h index fa837c1de4d..8c7ad7254b0 100644 --- a/contrib/bind9/lib/dns/include/dns/resolver.h +++ b/contrib/bind9/lib/dns/include/dns/resolver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.h,v 1.60.56.3 2009/01/29 22:40:35 jinmei Exp $ */ +/* $Id: resolver.h,v 1.60.56.3.22.2 2010/02/25 10:57:12 tbox Exp $ */ #ifndef DNS_RESOLVER_H #define DNS_RESOLVER_H 1 @@ -508,6 +508,48 @@ dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state); unsigned int dns_resolver_getoptions(dns_resolver_t *resolver); +void +dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name, + dns_rdatatype_t type, isc_time_t *expire); +/*%< + * Add a entry to the bad cache for that will expire at 'expire'. + * + * Requires: + * \li resolver to be valid. + * \li name to be valid. + */ + +isc_boolean_t +dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name, + dns_rdatatype_t type, isc_time_t *now); +/*%< + * Check to see if there is a unexpired entry in the bad cache for + * . + * + * Requires: + * \li resolver to be valid. + * \li name to be valid. + */ + +void +dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name); +/*%< + * Flush the bad cache of all entries at 'name' if 'name' is non NULL. + * Flush the entire bad cache if 'name' is NULL. + * + * Requires: + * \li resolver to be valid. + */ + +void +dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp); +/*% + * Print out the contents of the bad cache to 'fp'. + * + * Requires: + * \li resolver to be valid. + */ + ISC_LANG_ENDDECLS #endif /* DNS_RESOLVER_H */ diff --git a/contrib/bind9/lib/dns/include/dns/result.h b/contrib/bind9/lib/dns/include/dns/result.h index ed29bcd5d3f..a1e7f535dee 100644 --- a/contrib/bind9/lib/dns/include/dns/result.h +++ b/contrib/bind9/lib/dns/include/dns/result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: result.h,v 1.116 2008/09/25 04:02:39 tbox Exp $ */ +/* $Id: result.h,v 1.116.226.2 2010/02/25 10:57:12 tbox Exp $ */ #ifndef DNS_RESULT_H #define DNS_RESULT_H 1 @@ -148,8 +148,10 @@ #define DNS_R_MXISADDRESS (ISC_RESULTCLASS_DNS + 102) #define DNS_R_DUPLICATE (ISC_RESULTCLASS_DNS + 103) #define DNS_R_INVALIDNSEC3 (ISC_RESULTCLASS_DNS + 104) +#define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105) +#define DNS_R_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106) -#define DNS_R_NRESULTS 105 /*%< Number of results */ +#define DNS_R_NRESULTS 107 /*%< Number of results */ /* * DNS wire format rcodes. diff --git a/contrib/bind9/lib/dns/include/dns/types.h b/contrib/bind9/lib/dns/include/dns/types.h index 525dd8d4892..10ce229ac97 100644 --- a/contrib/bind9/lib/dns/include/dns/types.h +++ b/contrib/bind9/lib/dns/include/dns/types.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.130.50.3.12.2 2009/12/31 20:29:21 each Exp $ */ +/* $Id: types.h,v 1.130.50.5 2009/12/30 08:34:30 jinmei Exp $ */ #ifndef DNS_TYPES_H #define DNS_TYPES_H 1 diff --git a/contrib/bind9/lib/dns/include/dns/validator.h b/contrib/bind9/lib/dns/include/dns/validator.h index 2555214b14c..1da4e0c4c39 100644 --- a/contrib/bind9/lib/dns/include/dns/validator.h +++ b/contrib/bind9/lib/dns/include/dns/validator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.h,v 1.41.48.3 2009/01/18 23:25:17 marka Exp $ */ +/* $Id: validator.h,v 1.41.48.3.22.2 2010/02/25 10:57:12 tbox Exp $ */ #ifndef DNS_VALIDATOR_H #define DNS_VALIDATOR_H 1 @@ -159,6 +159,8 @@ struct dns_validator { isc_boolean_t mustbesecure; unsigned int dlvlabels; unsigned int depth; + unsigned int authcount; + unsigned int authfail; }; /*% diff --git a/contrib/bind9/lib/dns/include/dns/zone.h b/contrib/bind9/lib/dns/include/dns/zone.h index e2859ae5bbb..746b43cdd6f 100644 --- a/contrib/bind9/lib/dns/include/dns/zone.h +++ b/contrib/bind9/lib/dns/include/dns/zone.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.160.50.4 2009/01/29 22:40:35 jinmei Exp $ */ +/* $Id: zone.h,v 1.160.50.6 2009/10/05 21:57:00 each Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -149,13 +149,24 @@ dns_zone_getclass(dns_zone_t *zone); *\li 'zone' to be a valid zone. */ +isc_result_t +dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp); + isc_uint32_t dns_zone_getserial(dns_zone_t *zone); /*%< - * Returns the current serial number of the zone. + * Returns the current serial number of the zone. On success, the SOA + * serial of the zone will be copied into '*serialp'. + * dns_zone_getserial() cannot catch failure cases and is deprecated by + * dns_zone_getserial2(). * * Requires: *\li 'zone' to be a valid zone. + *\li 'serialp' to be non NULL + * + * Returns: + *\li #ISC_R_SUCCESS + *\li #DNS_R_NOTLOADED zone DB is not loaded */ void @@ -256,6 +267,9 @@ dns_zone_load(dns_zone_t *zone); isc_result_t dns_zone_loadnew(dns_zone_t *zone); + +isc_result_t +dns_zone_loadandthaw(dns_zone_t *zone); /*%< * Cause the database to be loaded from its backing store. * Confirm that the minimum requirements for the zone type are @@ -264,6 +278,8 @@ dns_zone_loadnew(dns_zone_t *zone); * dns_zone_loadnew() only loads zones that are not yet loaded. * dns_zone_load() also loads zones that are already loaded and * and whose master file has changed since the last load. + * dns_zone_loadandthaw() is similar to dns_zone_load() but will + * also re-enable DNS UPDATEs when the load completes. * * Require: *\li 'zone' to be a valid zone. diff --git a/contrib/bind9/lib/dns/include/dst/dst.h b/contrib/bind9/lib/dns/include/dst/dst.h index 702ad719d21..de262bdafb1 100644 --- a/contrib/bind9/lib/dns/include/dst/dst.h +++ b/contrib/bind9/lib/dns/include/dst/dst.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst.h,v 1.12 2008/09/24 02:46:23 marka Exp $ */ +/* $Id: dst.h,v 1.12.50.2 2010/01/15 23:47:34 tbox Exp $ */ #ifndef DST_DST_H #define DST_DST_H 1 @@ -53,6 +53,8 @@ typedef struct dst_context dst_context_t; #define DST_ALG_RSASHA1 5 #define DST_ALG_NSEC3DSA 6 #define DST_ALG_NSEC3RSASHA1 7 +#define DST_ALG_RSASHA256 8 +#define DST_ALG_RSASHA512 10 #define DST_ALG_HMACMD5 157 #define DST_ALG_GSSAPI 160 #define DST_ALG_HMACSHA1 161 /* XXXMPA */ diff --git a/contrib/bind9/lib/dns/journal.c b/contrib/bind9/lib/dns/journal.c index 8c21f1ece34..638e64755b5 100644 --- a/contrib/bind9/lib/dns/journal.c +++ b/contrib/bind9/lib/dns/journal.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: journal.c,v 1.103.48.2 2009/01/18 23:47:37 tbox Exp $ */ +/* $Id: journal.c,v 1.103.48.6 2009/11/04 23:47:25 tbox Exp $ */ #include @@ -1218,7 +1218,9 @@ dns_journal_destroy(dns_journal_t **journalp) { /* XXX Share code with incoming IXFR? */ static isc_result_t -roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) { +roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options, + isc_uint32_t resign) +{ isc_buffer_t source; /* Transaction data from disk */ isc_buffer_t target; /* Ditto after _fromwire check */ isc_uint32_t db_serial; /* Database SOA serial */ @@ -1235,6 +1237,7 @@ roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) { REQUIRE(DNS_DB_VALID(db)); dns_diff_init(j->mctx, &diff); + diff.resign = resign; /* * Set up empty initial buffers for unchecked and checked @@ -1352,6 +1355,14 @@ roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) { isc_result_t dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options, const char *filename) +{ + REQUIRE((options & DNS_JOURNALOPT_RESIGN) == 0); + return (dns_journal_rollforward2(mctx, db, options, 0, filename)); +} + +isc_result_t +dns_journal_rollforward2(isc_mem_t *mctx, dns_db_t *db, unsigned int options, + isc_uint32_t resign, const char *filename) { dns_journal_t *j; isc_result_t result; @@ -1371,7 +1382,7 @@ dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, if (JOURNAL_EMPTY(&j->header)) result = DNS_R_UPTODATE; else - result = roll_forward(j, db, options); + result = roll_forward(j, db, options, resign); dns_journal_destroy(&j); @@ -1850,18 +1861,11 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { return (result); } -/* - * Compare the databases 'dba' and 'dbb' and generate a journal - * entry containing the changes to make 'dba' from 'dbb' (note - * the order). This journal entry will consist of a single, - * possibly very large transaction. - */ - -isc_result_t -dns_db_diff(isc_mem_t *mctx, - dns_db_t *dba, dns_dbversion_t *dbvera, - dns_db_t *dbb, dns_dbversion_t *dbverb, - const char *journal_filename) +static isc_result_t +diff_namespace(isc_mem_t *mctx, + dns_db_t *dba, dns_dbversion_t *dbvera, + dns_db_t *dbb, dns_dbversion_t *dbverb, + unsigned int options, dns_diff_t *resultdiff) { dns_db_t *db[2]; dns_dbversion_t *ver[2]; @@ -1869,30 +1873,24 @@ dns_db_diff(isc_mem_t *mctx, isc_boolean_t have[2] = { ISC_FALSE, ISC_FALSE }; dns_fixedname_t fixname[2]; isc_result_t result, itresult[2]; - dns_diff_t diff[2], resultdiff; + dns_diff_t diff[2]; int i, t; - dns_journal_t *journal = NULL; db[0] = dba, db[1] = dbb; ver[0] = dbvera, ver[1] = dbverb; dns_diff_init(mctx, &diff[0]); dns_diff_init(mctx, &diff[1]); - dns_diff_init(mctx, &resultdiff); dns_fixedname_init(&fixname[0]); dns_fixedname_init(&fixname[1]); - result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal); + result = dns_db_createiterator(db[0], options, &dbit[0]); if (result != ISC_R_SUCCESS) return (result); - - result = dns_db_createiterator(db[0], 0, &dbit[0]); + result = dns_db_createiterator(db[1], options, &dbit[1]); if (result != ISC_R_SUCCESS) - goto cleanup_journal; - result = dns_db_createiterator(db[1], 0, &dbit[1]); - if (result != ISC_R_SUCCESS) - goto cleanup_interator0; + goto cleanup_iterator; itresult[0] = dns_dbiterator_first(dbit[0]); itresult[1] = dns_dbiterator_first(dbit[1]); @@ -1919,7 +1917,7 @@ dns_db_diff(isc_mem_t *mctx, for (i = 0; i < 2; i++) { if (! have[!i]) { - ISC_LIST_APPENDLIST(resultdiff.tuples, + ISC_LIST_APPENDLIST(resultdiff->tuples, diff[i].tuples, link); INSIST(ISC_LIST_EMPTY(diff[i].tuples)); have[i] = ISC_FALSE; @@ -1930,21 +1928,21 @@ dns_db_diff(isc_mem_t *mctx, t = dns_name_compare(dns_fixedname_name(&fixname[0]), dns_fixedname_name(&fixname[1])); if (t < 0) { - ISC_LIST_APPENDLIST(resultdiff.tuples, + ISC_LIST_APPENDLIST(resultdiff->tuples, diff[0].tuples, link); INSIST(ISC_LIST_EMPTY(diff[0].tuples)); have[0] = ISC_FALSE; continue; } if (t > 0) { - ISC_LIST_APPENDLIST(resultdiff.tuples, + ISC_LIST_APPENDLIST(resultdiff->tuples, diff[1].tuples, link); INSIST(ISC_LIST_EMPTY(diff[1].tuples)); have[1] = ISC_FALSE; continue; } INSIST(t == 0); - CHECK(dns_diff_subtract(diff, &resultdiff)); + CHECK(dns_diff_subtract(diff, resultdiff)); INSIST(ISC_LIST_EMPTY(diff[0].tuples)); INSIST(ISC_LIST_EMPTY(diff[1].tuples)); have[0] = have[1] = ISC_FALSE; @@ -1955,20 +1953,49 @@ dns_db_diff(isc_mem_t *mctx, if (itresult[1] != ISC_R_NOMORE) FAIL(itresult[1]); + INSIST(ISC_LIST_EMPTY(diff[0].tuples)); + INSIST(ISC_LIST_EMPTY(diff[1].tuples)); + + failure: + dns_dbiterator_destroy(&dbit[1]); + cleanup_iterator: + dns_dbiterator_destroy(&dbit[0]); + return (result); +} + +/* + * Compare the databases 'dba' and 'dbb' and generate a journal + * entry containing the changes to make 'dba' from 'dbb' (note + * the order). This journal entry will consist of a single, + * possibly very large transaction. + */ +isc_result_t +dns_db_diff(isc_mem_t *mctx, + dns_db_t *dba, dns_dbversion_t *dbvera, + dns_db_t *dbb, dns_dbversion_t *dbverb, + const char *journal_filename) +{ + isc_result_t result; + dns_journal_t *journal = NULL; + dns_diff_t resultdiff; + + result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal); + if (result != ISC_R_SUCCESS) + return (result); + + dns_diff_init(mctx, &resultdiff); + + CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb, + DNS_DB_NONSEC3, &resultdiff)); + CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb, + DNS_DB_NSEC3ONLY, &resultdiff)); if (ISC_LIST_EMPTY(resultdiff.tuples)) { isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes"); } else { CHECK(dns_journal_write_transaction(journal, &resultdiff)); } - INSIST(ISC_LIST_EMPTY(diff[0].tuples)); - INSIST(ISC_LIST_EMPTY(diff[1].tuples)); - failure: dns_diff_clear(&resultdiff); - dns_dbiterator_destroy(&dbit[1]); - cleanup_interator0: - dns_dbiterator_destroy(&dbit[0]); - cleanup_journal: dns_journal_destroy(&journal); return (result); } diff --git a/contrib/bind9/lib/dns/masterdump.c b/contrib/bind9/lib/dns/masterdump.c index 1dbb1e615e8..314112ce5f1 100644 --- a/contrib/bind9/lib/dns/masterdump.c +++ b/contrib/bind9/lib/dns/masterdump.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: masterdump.c,v 1.94.50.2.12.1 2009/11/18 23:58:04 marka Exp $ */ +/* $Id: masterdump.c,v 1.94.50.3 2009/11/18 00:15:37 marka Exp $ */ /*! \file */ diff --git a/contrib/bind9/lib/dns/message.c b/contrib/bind9/lib/dns/message.c index b541635abf0..2e34120f3b9 100644 --- a/contrib/bind9/lib/dns/message.c +++ b/contrib/bind9/lib/dns/message.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: message.c,v 1.245.50.2 2009/01/18 23:47:40 tbox Exp $ */ +/* $Id: message.c,v 1.245.50.3 2009/11/24 03:25:53 marka Exp $ */ /*! \file */ @@ -1888,6 +1888,8 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, msg->counts[sectionid] += total; return (result); } + if (result == ISC_R_NOSPACE) + msg->flags |= DNS_MESSAGEFLAG_TC; if (result != ISC_R_SUCCESS) { INSIST(st.used < 65536); dns_compress_rollback(msg->cctx, diff --git a/contrib/bind9/lib/dns/ncache.c b/contrib/bind9/lib/dns/ncache.c index af0450b525d..733d138dda2 100644 --- a/contrib/bind9/lib/dns/ncache.c +++ b/contrib/bind9/lib/dns/ncache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ncache.c,v 1.43 2008/09/25 04:02:38 tbox Exp $ */ +/* $Id: ncache.c,v 1.43.334.2 2010/02/25 10:57:11 tbox Exp $ */ /*! \file */ @@ -519,6 +519,8 @@ static dns_rdatasetmethods_t rdataset_methods = { NULL, NULL, NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind9/lib/dns/nsec3.c b/contrib/bind9/lib/dns/nsec3.c index f9b8cad21a7..ea6546d9e60 100644 --- a/contrib/bind9/lib/dns/nsec3.c +++ b/contrib/bind9/lib/dns/nsec3.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsec3.c,v 1.6.12.2 2009/06/04 02:56:14 tbox Exp $ */ +/* $Id: nsec3.c,v 1.6.12.4 2009/11/03 23:47:46 tbox Exp $ */ #include @@ -87,6 +87,8 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, unsigned int i, window; int octet; isc_boolean_t found; + isc_boolean_t found_ns; + isc_boolean_t need_rrsig; unsigned char *nsec_bits, *bm; unsigned int max_type; @@ -140,7 +142,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); if (result != ISC_R_SUCCESS) return (result); - found = ISC_FALSE; + found = found_ns = need_rrsig = ISC_FALSE; for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) @@ -152,13 +154,26 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, if (rdataset.type > max_type) max_type = rdataset.type; set_bit(bm, rdataset.type, 1); - /* Don't set RRSIG for insecure delegation. */ - if (rdataset.type != dns_rdatatype_ns) + /* + * Work out if we need to set the RRSIG bit for + * this node. We set the RRSIG bit if either of + * the following conditions are met: + * 1) We have a SOA or DS then we need to set + * the RRSIG bit as both always will be signed. + * 2) We set the RRSIG bit if we don't have + * a NS record but do have other data. + */ + if (rdataset.type == dns_rdatatype_soa || + rdataset.type == dns_rdatatype_ds) + need_rrsig = ISC_TRUE; + else if (rdataset.type == dns_rdatatype_ns) + found_ns = ISC_TRUE; + else found = ISC_TRUE; } dns_rdataset_disassociate(&rdataset); } - if (found) { + if ((found && !found_ns) || need_rrsig) { if (dns_rdatatype_rrsig > max_type) max_type = dns_rdatatype_rrsig; set_bit(bm, dns_rdatatype_rrsig, 1); diff --git a/contrib/bind9/lib/dns/opensslrsa_link.c b/contrib/bind9/lib/dns/opensslrsa_link.c index d557c43db25..95095d1186b 100644 --- a/contrib/bind9/lib/dns/opensslrsa_link.c +++ b/contrib/bind9/lib/dns/opensslrsa_link.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -17,21 +17,23 @@ /* * Principal Author: Brian Wellington - * $Id: opensslrsa_link.c,v 1.20.50.3 2009/01/18 23:25:16 marka Exp $ + * $Id: opensslrsa_link.c,v 1.20.50.8 2010/01/22 02:36:49 marka Exp $ */ #ifdef OPENSSL +#include + #ifndef USE_EVP +#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA512) +#define USE_EVP 0 +#else #define USE_EVP 1 #endif -#if USE_EVP -#define USE_EVP_RSA 1 #endif -#include - #include #include #include +#include #include #include #include @@ -112,23 +114,42 @@ static isc_result_t opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { #if USE_EVP EVP_MD_CTX *evp_md_ctx; - const EVP_MD *type; + const EVP_MD *type = NULL; #endif UNUSED(key); REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1); + dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || + dctx->key->key_alg == DST_ALG_RSASHA256 || + dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP evp_md_ctx = EVP_MD_CTX_create(); if (evp_md_ctx == NULL) return (ISC_R_NOMEMORY); - if (dctx->key->key_alg == DST_ALG_RSAMD5) + switch (dctx->key->key_alg) { + case DST_ALG_RSAMD5: type = EVP_md5(); /* MD5 + RSA */ - else + break; + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: type = EVP_sha1(); /* SHA1 + RSA */ + break; +#ifdef HAVE_EVP_SHA256 + case DST_ALG_RSASHA256: + type = EVP_sha256(); /* SHA256 + RSA */ + break; +#endif +#ifdef HAVE_EVP_SHA512 + case DST_ALG_RSASHA512: + type = EVP_sha512(); + break; +#endif + default: + INSIST(0); + } if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); @@ -136,22 +157,56 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { } dctx->ctxdata.evp_md_ctx = evp_md_ctx; #else - if (dctx->key->key_alg == DST_ALG_RSAMD5) { - isc_md5_t *md5ctx; + switch (dctx->key->key_alg) { + case DST_ALG_RSAMD5: + { + isc_md5_t *md5ctx; - md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t)); - if (md5ctx == NULL) - return (ISC_R_NOMEMORY); - isc_md5_init(md5ctx); - dctx->ctxdata.md5ctx = md5ctx; - } else { - isc_sha1_t *sha1ctx; + md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t)); + if (md5ctx == NULL) + return (ISC_R_NOMEMORY); + isc_md5_init(md5ctx); + dctx->ctxdata.md5ctx = md5ctx; + } + break; + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + { + isc_sha1_t *sha1ctx; - sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t)); - if (sha1ctx == NULL) - return (ISC_R_NOMEMORY); - isc_sha1_init(sha1ctx); - dctx->ctxdata.sha1ctx = sha1ctx; + sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t)); + if (sha1ctx == NULL) + return (ISC_R_NOMEMORY); + isc_sha1_init(sha1ctx); + dctx->ctxdata.sha1ctx = sha1ctx; + } + break; + case DST_ALG_RSASHA256: + { + isc_sha256_t *sha256ctx; + + sha256ctx = isc_mem_get(dctx->mctx, + sizeof(isc_sha256_t)); + if (sha256ctx == NULL) + return (ISC_R_NOMEMORY); + isc_sha256_init(sha256ctx); + dctx->ctxdata.sha256ctx = sha256ctx; + } + break; + case DST_ALG_RSASHA512: + { + isc_sha512_t *sha512ctx; + + sha512ctx = isc_mem_get(dctx->mctx, + sizeof(isc_sha512_t)); + if (sha512ctx == NULL) + return (ISC_R_NOMEMORY); + isc_sha512_init(sha512ctx); + dctx->ctxdata.sha512ctx = sha512ctx; + } + break; + default: + INSIST(0); } #endif @@ -166,7 +221,9 @@ opensslrsa_destroyctx(dst_context_t *dctx) { REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1); + dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || + dctx->key->key_alg == DST_ALG_RSASHA256 || + dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP if (evp_md_ctx != NULL) { @@ -174,22 +231,58 @@ opensslrsa_destroyctx(dst_context_t *dctx) { dctx->ctxdata.evp_md_ctx = NULL; } #else - if (dctx->key->key_alg == DST_ALG_RSAMD5) { - isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; + switch (dctx->key->key_alg) { + case DST_ALG_RSAMD5: + { + isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; - if (md5ctx != NULL) { - isc_md5_invalidate(md5ctx); - isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t)); - dctx->ctxdata.md5ctx = NULL; + if (md5ctx != NULL) { + isc_md5_invalidate(md5ctx); + isc_mem_put(dctx->mctx, md5ctx, + sizeof(isc_md5_t)); + dctx->ctxdata.md5ctx = NULL; + } } - } else { - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; + break; + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + { + isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - if (sha1ctx != NULL) { - isc_sha1_invalidate(sha1ctx); - isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t)); - dctx->ctxdata.sha1ctx = NULL; + if (sha1ctx != NULL) { + isc_sha1_invalidate(sha1ctx); + isc_mem_put(dctx->mctx, sha1ctx, + sizeof(isc_sha1_t)); + dctx->ctxdata.sha1ctx = NULL; + } } + break; + case DST_ALG_RSASHA256: + { + isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; + + if (sha256ctx != NULL) { + isc_sha256_invalidate(sha256ctx); + isc_mem_put(dctx->mctx, sha256ctx, + sizeof(isc_sha256_t)); + dctx->ctxdata.sha256ctx = NULL; + } + } + break; + case DST_ALG_RSASHA512: + { + isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; + + if (sha512ctx != NULL) { + isc_sha512_invalidate(sha512ctx); + isc_mem_put(dctx->mctx, sha512ctx, + sizeof(isc_sha512_t)); + dctx->ctxdata.sha512ctx = NULL; + } + } + break; + default: + INSIST(0); } #endif } @@ -202,24 +295,67 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) { REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1); + dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || + dctx->key->key_alg == DST_ALG_RSASHA256 || + dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { return (ISC_R_FAILURE); } #else - if (dctx->key->key_alg == DST_ALG_RSAMD5) { - isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; - isc_md5_update(md5ctx, data->base, data->length); - } else { - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - isc_sha1_update(sha1ctx, data->base, data->length); + switch (dctx->key->key_alg) { + case DST_ALG_RSAMD5: + { + isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; + + isc_md5_update(md5ctx, data->base, data->length); + } + break; + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + { + isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; + + isc_sha1_update(sha1ctx, data->base, data->length); + } + break; + case DST_ALG_RSASHA256: + { + isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; + + isc_sha256_update(sha256ctx, data->base, data->length); + } + break; + case DST_ALG_RSASHA512: + { + isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; + + isc_sha512_update(sha512ctx, data->base, data->length); + } + break; + default: + INSIST(0); } #endif return (ISC_R_SUCCESS); } +#if ! USE_EVP && OPENSSL_VERSION_NUMBER < 0x00908000L +/* + * Digest prefixes from RFC 5702. + */ +static unsigned char sha256_prefix[] = + { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; +static unsigned char sha512_prefix[] = + { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; +#define PREFIXLEN sizeof(sha512_prefix) +#else +#define PREFIXLEN 0 +#endif + static isc_result_t opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; @@ -230,20 +366,26 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { EVP_PKEY *pkey = key->keydata.pkey; #else RSA *rsa = key->keydata.rsa; - /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */ - unsigned char digest[ISC_SHA1_DIGESTLENGTH]; - int status; - int type; - unsigned int digestlen; + /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */ + unsigned char digest[PREFIXLEN + ISC_SHA512_DIGESTLENGTH]; + int status = 0; + int type = 0; + unsigned int digestlen = 0; char *message; unsigned long err; const char* file; int line; +#if OPENSSL_VERSION_NUMBER < 0x00908000L + unsigned int prefixlen = 0; + const unsigned char *prefix = NULL; +#endif #endif REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1); + dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || + dctx->key->key_alg == DST_ALG_RSASHA256 || + dctx->key->key_alg == DST_ALG_RSASHA512); isc_buffer_availableregion(sig, &r); @@ -258,19 +400,92 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { if (r.length < (unsigned int) RSA_size(rsa)) return (ISC_R_NOSPACE); - if (dctx->key->key_alg == DST_ALG_RSAMD5) { - isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; - isc_md5_final(md5ctx, digest); - type = NID_md5; - digestlen = ISC_MD5_DIGESTLENGTH; - } else { - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - isc_sha1_final(sha1ctx, digest); - type = NID_sha1; - digestlen = ISC_SHA1_DIGESTLENGTH; + switch (dctx->key->key_alg) { + case DST_ALG_RSAMD5: + { + isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; + + isc_md5_final(md5ctx, digest); + type = NID_md5; + digestlen = ISC_MD5_DIGESTLENGTH; + } + break; + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + { + isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; + + isc_sha1_final(sha1ctx, digest); + type = NID_sha1; + digestlen = ISC_SHA1_DIGESTLENGTH; + } + break; + case DST_ALG_RSASHA256: + { + isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; + + isc_sha256_final(digest, sha256ctx); + digestlen = ISC_SHA256_DIGESTLENGTH; +#if OPENSSL_VERSION_NUMBER < 0x00908000L + prefix = sha256_prefix; + prefixlen = sizeof(sha256_prefix); +#else + type = NID_sha256; +#endif + } + break; + case DST_ALG_RSASHA512: + { + isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; + + isc_sha512_final(digest, sha512ctx); + digestlen = ISC_SHA512_DIGESTLENGTH; +#if OPENSSL_VERSION_NUMBER < 0x00908000L + prefix = sha512_prefix; + prefixlen = sizeof(sha512_prefix); +#else + type = NID_sha512; +#endif + } + break; + default: + INSIST(0); } +#if OPENSSL_VERSION_NUMBER < 0x00908000L + switch (dctx->key->key_alg) { + case DST_ALG_RSAMD5: + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + INSIST(type != 0); + status = RSA_sign(type, digest, digestlen, r.base, + &siglen, rsa); + break; + + case DST_ALG_RSASHA256: + case DST_ALG_RSASHA512: + INSIST(prefix != NULL); + INSIST(prefixlen != 0); + INSIST(prefixlen + digestlen <= sizeof(digest)); + + memmove(digest + prefixlen, digest, digestlen); + memcpy(digest, prefix, prefixlen); + status = RSA_private_encrypt(digestlen + prefixlen, + digest, r.base, rsa, + RSA_PKCS1_PADDING); + if (status < 0) + status = 0; + else + siglen = status; + break; + + default: + INSIST(0); + } +#else + INSIST(type != 0); status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); +#endif if (status == 0) { err = ERR_peek_error_line(&file, &line); if (err != 0U) { @@ -293,37 +508,129 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; #else - /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */ - unsigned char digest[ISC_SHA1_DIGESTLENGTH]; - int type; - unsigned int digestlen; + /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */ + unsigned char digest[ISC_SHA512_DIGESTLENGTH]; + int type = 0; + unsigned int digestlen = 0; RSA *rsa = key->keydata.rsa; +#if OPENSSL_VERSION_NUMBER < 0x00908000L + unsigned int prefixlen = 0; + const unsigned char *prefix = NULL; +#endif #endif REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1); + dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || + dctx->key->key_alg == DST_ALG_RSASHA256 || + dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); #else - if (dctx->key->key_alg == DST_ALG_RSAMD5) { - isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; - isc_md5_final(md5ctx, digest); - type = NID_md5; - digestlen = ISC_MD5_DIGESTLENGTH; - } else { - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - isc_sha1_final(sha1ctx, digest); - type = NID_sha1; - digestlen = ISC_SHA1_DIGESTLENGTH; + switch (dctx->key->key_alg) { + case DST_ALG_RSAMD5: + { + isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; + + isc_md5_final(md5ctx, digest); + type = NID_md5; + digestlen = ISC_MD5_DIGESTLENGTH; + } + break; + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + { + isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; + + isc_sha1_final(sha1ctx, digest); + type = NID_sha1; + digestlen = ISC_SHA1_DIGESTLENGTH; + } + break; + case DST_ALG_RSASHA256: + { + isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; + + isc_sha256_final(digest, sha256ctx); + digestlen = ISC_SHA256_DIGESTLENGTH; +#if OPENSSL_VERSION_NUMBER < 0x00908000L + prefix = sha256_prefix; + prefixlen = sizeof(sha256_prefix); +#else + type = NID_sha256; +#endif + } + break; + case DST_ALG_RSASHA512: + { + isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; + + isc_sha512_final(digest, sha512ctx); + digestlen = ISC_SHA512_DIGESTLENGTH; +#if OPENSSL_VERSION_NUMBER < 0x00908000L + prefix = sha512_prefix; + prefixlen = sizeof(sha512_prefix); +#else + type = NID_sha512; +#endif + } + break; + default: + INSIST(0); } - if (sig->length < (unsigned int) RSA_size(rsa)) + if (sig->length != (unsigned int) RSA_size(rsa)) return (DST_R_VERIFYFAILURE); +#if OPENSSL_VERSION_NUMBER < 0x00908000L + switch (dctx->key->key_alg) { + case DST_ALG_RSAMD5: + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + INSIST(type != 0); + status = RSA_verify(type, digest, digestlen, sig->base, + RSA_size(rsa), rsa); + break; + + case DST_ALG_RSASHA256: + case DST_ALG_RSASHA512: + { + /* + * 1024 is big enough for all valid RSA bit sizes + * for use with DNSSEC. + */ + unsigned char original[PREFIXLEN + 1024]; + + INSIST(prefix != NULL); + INSIST(prefixlen != 0U); + + if (RSA_size(rsa) > (int)sizeof(original)) + return (DST_R_VERIFYFAILURE); + + status = RSA_public_decrypt(sig->length, sig->base, + original, rsa, + RSA_PKCS1_PADDING); + if (status <= 0) + return (DST_R_VERIFYFAILURE); + if (status != (int)(prefixlen + digestlen)) + return (DST_R_VERIFYFAILURE); + if (memcmp(original, prefix, prefixlen)) + return (DST_R_VERIFYFAILURE); + if (memcmp(original + prefixlen, digest, digestlen)) + return (DST_R_VERIFYFAILURE); + status = 1; + } + break; + + default: + INSIST(0); + } +#else + INSIST(type != 0); status = RSA_verify(type, digest, digestlen, sig->base, - RSA_size(rsa), rsa); + RSA_size(rsa), rsa); +#endif #endif if (status != 1) return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); @@ -552,19 +859,20 @@ opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) { if (r.length < 1) DST_RET(ISC_R_NOSPACE); isc_buffer_putuint8(data, (isc_uint8_t) e_bytes); + isc_region_consume(&r, 1); } else { if (r.length < 3) DST_RET(ISC_R_NOSPACE); isc_buffer_putuint8(data, 0); isc_buffer_putuint16(data, (isc_uint16_t) e_bytes); + isc_region_consume(&r, 3); } if (r.length < e_bytes + mod_bytes) - return (ISC_R_NOSPACE); - isc_buffer_availableregion(data, &r); + DST_RET(ISC_R_NOSPACE); BN_bn2bin(rsa->e, r.base); - r.base += e_bytes; + isc_region_consume(&r, e_bytes); BN_bn2bin(rsa->n, r.base); isc_buffer_add(data, e_bytes + mod_bytes); @@ -805,8 +1113,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) { DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_private_key(e, label, NULL, NULL); if (pkey == NULL) { - ERR_print_errors_fp(stderr); - DST_RET(ISC_R_FAILURE); + /* ERR_print_errors_fp(stderr); */ + DST_RET(ISC_R_NOTFOUND); } key->engine = isc_mem_strdup(key->mctx, name); if (key->engine == NULL) @@ -924,7 +1232,7 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label, DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_private_key(e, label, NULL, NULL); if (pkey == NULL) - DST_RET(ISC_R_NOMEMORY); + DST_RET(ISC_R_NOTFOUND); key->engine = isc_mem_strdup(key->mctx, label); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); @@ -969,10 +1277,26 @@ static dst_func_t opensslrsa_functions = { }; isc_result_t -dst__opensslrsa_init(dst_func_t **funcp) { +dst__opensslrsa_init(dst_func_t **funcp, unsigned char algorithm) { REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &opensslrsa_functions; + + if (*funcp == NULL) { + switch (algorithm) { + case DST_ALG_RSASHA256: +#if defined(HAVE_EVP_SHA256) || !USE_EVP + *funcp = &opensslrsa_functions; +#endif + break; + case DST_ALG_RSASHA512: +#if defined(HAVE_EVP_SHA512) || !USE_EVP + *funcp = &opensslrsa_functions; +#endif + break; + default: + *funcp = &opensslrsa_functions; + break; + } + } return (ISC_R_SUCCESS); } diff --git a/contrib/bind9/lib/dns/rbt.c b/contrib/bind9/lib/dns/rbt.c index ff8b3a36e37..62a9e2b03bb 100644 --- a/contrib/bind9/lib/dns/rbt.c +++ b/contrib/bind9/lib/dns/rbt.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbt.c,v 1.142.50.2 2009/01/18 23:47:40 tbox Exp $ */ +/* $Id: rbt.c,v 1.142.50.3 2009/10/20 05:06:04 marka Exp $ */ /*! \file */ @@ -85,9 +85,9 @@ struct dns_rbt { #define HASHVAL(node) ((node)->hashval) #define COLOR(node) ((node)->color) #define NAMELEN(node) ((node)->namelen) +#define OLDNAMELEN(node) ((node)->oldnamelen) #define OFFSETLEN(node) ((node)->offsetlen) #define ATTRS(node) ((node)->attributes) -#define PADBYTES(node) ((node)->padbytes) #define IS_ROOT(node) ISC_TF((node)->is_root == 1) #define FINDCALLBACK(node) ISC_TF((node)->find_callback == 1) @@ -100,13 +100,23 @@ struct dns_rbt { #define LOCKNUM(node) ((node)->locknum) /*% - * The variable length stuff stored after the node. + * The variable length stuff stored after the node has the following + * structure. + * + * {1..255}{1}{1..128} + * + * contains the name of the node when it was created. + * contains the length of when the node was created. + * contains the offets into name for each label when the node was + * created. */ + #define NAME(node) ((unsigned char *)((node) + 1)) -#define OFFSETS(node) (NAME(node) + NAMELEN(node)) +#define OFFSETS(node) (NAME(node) + OLDNAMELEN(node) + 1) +#define OLDOFFSETLEN(node) (OFFSETS(node)[-1]) #define NODE_SIZE(node) (sizeof(*node) + \ - NAMELEN(node) + OFFSETLEN(node) + PADBYTES(node)) + OLDNAMELEN(node) + OLDOFFSETLEN(node) + 1) /*% * Color management. @@ -553,11 +563,6 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) { NAMELEN(current) = prefix->length; OFFSETLEN(current) = prefix->labels; - memcpy(OFFSETS(current), prefix->offsets, - prefix->labels); - PADBYTES(current) += - (current_name.length - prefix->length) + - (current_name.labels - prefix->labels); /* * Set up the new root of the next level. @@ -1423,7 +1428,7 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) { * Allocate space for the node structure, the name, and the offsets. */ node = (dns_rbtnode_t *)isc_mem_get(mctx, sizeof(*node) + - region.length + labels); + region.length + labels + 1); if (node == NULL) return (ISC_R_NOMEMORY); @@ -1460,10 +1465,12 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) { * The offsets table could be made smaller by eliminating the * first offset, which is always 0. This requires changes to * lib/dns/name.c. + * + * Note: OLDOFFSETLEN *must* be assigned *after* OLDNAMELEN is assigned + * as it uses OLDNAMELEN. */ - NAMELEN(node) = region.length; - PADBYTES(node) = 0; - OFFSETLEN(node) = labels; + OLDNAMELEN(node) = NAMELEN(node) = region.length; + OLDOFFSETLEN(node) = OFFSETLEN(node) = labels; ATTRS(node) = name->attributes; memcpy(NAME(node), region.base, region.length); diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c index d5b5b5c8194..df3a5f47e20 100644 --- a/contrib/bind9/lib/dns/rbtdb.c +++ b/contrib/bind9/lib/dns/rbtdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.270.12.6.10.2 2009/12/31 21:44:36 each Exp $ */ +/* $Id: rbtdb.c,v 1.270.12.16.8.3 2010/02/26 00:24:39 marka Exp $ */ /*! \file */ @@ -258,21 +258,8 @@ typedef struct rdatasetheader { dns_rbtnode_t *node; isc_stdtime_t last_used; - ISC_LINK(struct rdatasetheader) lru_link; - /*%< - * Used for LRU-based cache management. We should probably make - * these cache-DB specific. We might also make it a pointer and - * ensure only the top header has a valid link to save memory. - * The linked-list is locked by the rbtdb->lrulock. - */ + ISC_LINK(struct rdatasetheader) link; - /* - * It's possible this should not be here anymore, but instead - * referenced from the bucket's heap directly. - */ -#if 0 - isc_heap_t *heap; -#endif unsigned int heap_index; /*%< * Used for TTL-based cache cleaning. @@ -396,7 +383,7 @@ typedef struct rbtdb_version { isc_uint8_t flags; isc_uint16_t iterations; isc_uint8_t salt_length; - unsigned char salt[NSEC3_MAX_HASH_LENGTH]; + unsigned char salt[DNS_NSEC3_SALTSIZE]; } rbtdb_version_t; typedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t; @@ -534,6 +521,8 @@ static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader); static void prune_tree(isc_task_t *task, isc_event_t *event); +static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); +static void rdataset_expire(dns_rdataset_t *rdataset); static dns_rdatasetmethods_t rdataset_methods = { rdataset_disassociate, @@ -548,7 +537,9 @@ static dns_rdatasetmethods_t rdataset_methods = { rdataset_getclosest, rdataset_getadditional, rdataset_setadditional, - rdataset_putadditional + rdataset_putadditional, + rdataset_settrust, + rdataset_expire }; static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); @@ -1227,7 +1218,7 @@ free_noqname(isc_mem_t *mctx, struct noqname **noqname) { static inline void init_rdataset(dns_rbtdb_t *rbtdb, rdatasetheader_t *h) { - ISC_LINK_INIT(h, lru_link); + ISC_LINK_INIT(h, link); h->heap_index = 0; #if TRACE_HEADER @@ -1267,8 +1258,10 @@ free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset) } idx = rdataset->node->locknum; - if (ISC_LINK_LINKED(rdataset, lru_link)) - ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, lru_link); + if (ISC_LINK_LINKED(rdataset, link)) { + INSIST(IS_CACHE(rbtdb)); + ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, link); + } if (rdataset->heap_index != 0) isc_heap_delete(rbtdb->heaps[idx], rdataset->heap_index); rdataset->heap_index = 0; @@ -2075,8 +2068,6 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version, continue; #endif - INSIST(nsec3param.salt_length <= - sizeof(version->salt)); memcpy(version->salt, nsec3param.salt, nsec3param.salt_length); version->hash = nsec3param.hash; @@ -2284,17 +2275,18 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { for (header = HEAD(resigned_list); header != NULL; header = HEAD(resigned_list)) { - ISC_LIST_UNLINK(resigned_list, header, lru_link); - if (rollback) { - nodelock_t *lock; - lock = &rbtdb->node_locks[header->node->locknum].lock; - NODE_LOCK(lock, isc_rwlocktype_write); + nodelock_t *lock; + + ISC_LIST_UNLINK(resigned_list, header, link); + + lock = &rbtdb->node_locks[header->node->locknum].lock; + NODE_LOCK(lock, isc_rwlocktype_write); + if (rollback) resign_insert(rbtdb, header->node->locknum, header); - NODE_UNLOCK(lock, isc_rwlocktype_write); - } decrement_reference(rbtdb, header->node, least_serial, isc_rwlocktype_write, isc_rwlocktype_none, ISC_FALSE); + NODE_UNLOCK(lock, isc_rwlocktype_write); } if (!EMPTY(cleanup_list)) { @@ -3524,11 +3516,17 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, /* * The node may be a zone cut itself. If it might be one, * make sure we check for it later. + * + * DS records live above the zone cut in ordinary zone so + * we want to ignore any referral. + * + * Stub zones don't have anything "above" the delgation so + * we always return a referral. */ if (node->find_callback && - (node != search.rbtdb->origin_node || - IS_STUB(search.rbtdb)) && - !dns_rdatatype_atparent(type)) + ((node != search.rbtdb->origin_node && + !dns_rdatatype_atparent(type)) || + IS_STUB(search.rbtdb))) maybe_zonecut = ISC_TRUE; } @@ -3546,8 +3544,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * We now go looking for rdata... */ - NODE_LOCK(&(search.rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); + lock = &search.rbtdb->node_locks[node->locknum].lock; + NODE_LOCK(lock, isc_rwlocktype_read); found = NULL; foundsig = NULL; @@ -3625,8 +3623,10 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * we are using behave as if it isn't here. */ if (header->type == dns_rdatatype_nsec3 && - !matchparams(header, &search)) + !matchparams(header, &search)) { + NODE_UNLOCK(lock, isc_rwlocktype_read); goto partial_match; + } /* * If we found a type we were looking for, * remember it. @@ -3705,7 +3705,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * we really have a partial match. */ if (!wild) { - lock = &search.rbtdb->node_locks[node->locknum].lock; NODE_UNLOCK(lock, isc_rwlocktype_read); goto partial_match; } @@ -3722,7 +3721,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * * Return the delegation. */ - lock = &search.rbtdb->node_locks[node->locknum].lock; NODE_UNLOCK(lock, isc_rwlocktype_read); result = setup_delegation(&search, nodep, foundname, rdataset, sigrdataset); @@ -3744,7 +3742,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, goto node_exit; } - lock = &search.rbtdb->node_locks[node->locknum].lock; NODE_UNLOCK(lock, isc_rwlocktype_read); result = find_closest_nsec(&search, nodep, foundname, rdataset, sigrdataset, @@ -3829,7 +3826,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, if (result == DNS_R_GLUE && (search.options & DNS_DBFIND_VALIDATEGLUE) != 0 && !valid_glue(&search, foundname, type, node)) { - lock = &search.rbtdb->node_locks[node->locknum].lock; NODE_UNLOCK(lock, isc_rwlocktype_read); result = setup_delegation(&search, nodep, foundname, rdataset, sigrdataset); @@ -3861,8 +3857,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, foundname->attributes |= DNS_NAMEATTR_WILDCARD; node_exit: - NODE_UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); + NODE_UNLOCK(lock, isc_rwlocktype_read); tree_exit: RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); @@ -5408,8 +5403,10 @@ static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader) { isc_result_t result; + INSIST(!IS_CACHE(rbtdb)); INSIST(newheader->heap_index == 0); - INSIST(!ISC_LINK_LINKED(newheader, lru_link)); + INSIST(!ISC_LINK_LINKED(newheader, link)); + result = isc_heap_insert(rbtdb->heaps[idx], newheader); return (result); } @@ -5735,7 +5732,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, idx = newheader->node->locknum; if (IS_CACHE(rbtdb)) { ISC_LIST_PREPEND(rbtdb->rdatasets[idx], - newheader, lru_link); + newheader, link); /* * XXXMLG We don't check the return value * here. If it fails, we will not do TTL @@ -5794,7 +5791,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, idx = newheader->node->locknum; if (IS_CACHE(rbtdb)) { ISC_LIST_PREPEND(rbtdb->rdatasets[idx], - newheader, lru_link); + newheader, link); isc_heap_insert(rbtdb->heaps[idx], newheader); } else if (RESIGN(newheader)) { resign_insert(rbtdb, idx, newheader); @@ -6519,11 +6516,17 @@ static void delete_callback(void *data, void *arg) { dns_rbtdb_t *rbtdb = arg; rdatasetheader_t *current, *next; + unsigned int locknum; - for (current = data; current != NULL; current = next) { + current = data; + locknum = current->node->locknum; + NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); + while (current != NULL) { next = current->next; free_rdataset(rbtdb, rbtdb->common.mctx, current); + current = next; } + NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); } static isc_boolean_t @@ -6642,8 +6645,8 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash, if (rbtversion->havensec3) { if (hash != NULL) *hash = rbtversion->hash; - if (salt != NULL && salt_length != 0) { - REQUIRE(*salt_length > rbtversion->salt_length); + if (salt != NULL && salt_length != NULL) { + REQUIRE(*salt_length >= rbtversion->salt_length); memcpy(salt, rbtversion->salt, rbtversion->salt_length); } if (salt_length != NULL) @@ -6707,27 +6710,35 @@ getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, rdatasetheader_t *header = NULL, *this; unsigned int i; isc_result_t result = ISC_R_NOTFOUND; + unsigned int locknum; REQUIRE(VALID_RBTDB(rbtdb)); RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); for (i = 0; i < rbtdb->node_lock_count; i++) { + NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read); this = isc_heap_element(rbtdb->heaps[i], 1); - if (this == NULL) + if (this == NULL) { + NODE_UNLOCK(&rbtdb->node_locks[i].lock, + isc_rwlocktype_read); continue; + } if (header == NULL) header = this; - else if (isc_serial_lt(this->resign, header->resign)) + else if (isc_serial_lt(this->resign, header->resign)) { + locknum = header->node->locknum; + NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, + isc_rwlocktype_read); header = this; + } else + NODE_UNLOCK(&rbtdb->node_locks[i].lock, + isc_rwlocktype_read); } if (header == NULL) goto unlock; - NODE_LOCK(&rbtdb->node_locks[header->node->locknum].lock, - isc_rwlocktype_read); - bind_rdataset(rbtdb, header->node, header, 0, rdataset); if (foundname != NULL) @@ -6761,7 +6772,7 @@ resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version) header = rdataset->private3; header--; - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); NODE_LOCK(&rbtdb->node_locks[node->locknum].lock, isc_rwlocktype_write); /* @@ -6771,11 +6782,11 @@ resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version) new_reference(rbtdb, node); isc_heap_delete(rbtdb->heaps[node->locknum], header->heap_index); header->heap_index = 0; - ISC_LIST_APPEND(rbtversion->resigned_list, header, lru_link); + ISC_LIST_APPEND(rbtversion->resigned_list, header, link); NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, isc_rwlocktype_write); - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); } static dns_stats_t * @@ -7400,6 +7411,34 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, return (ISC_R_SUCCESS); } +static void +rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { + dns_rbtdb_t *rbtdb = rdataset->private1; + dns_rbtnode_t *rbtnode = rdataset->private2; + rdatasetheader_t *header = rdataset->private3; + + header--; + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); + header->trust = rdataset->trust = trust; + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); +} + +static void +rdataset_expire(dns_rdataset_t *rdataset) { + dns_rbtdb_t *rbtdb = rdataset->private1; + dns_rbtnode_t *rbtnode = rdataset->private2; + rdatasetheader_t *header = rdataset->private3; + + header--; + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); + expire_header(rbtdb, header, ISC_FALSE); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); +} + /* * Rdataset Iterator Methods */ @@ -8497,13 +8536,11 @@ update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, INSIST(IS_CACHE(rbtdb)); /* To be checked: can we really assume this? XXXMLG */ - INSIST(ISC_LINK_LINKED(header, lru_link)); + INSIST(ISC_LINK_LINKED(header, link)); - ISC_LIST_UNLINK(rbtdb->rdatasets[header->node->locknum], - header, lru_link); + ISC_LIST_UNLINK(rbtdb->rdatasets[header->node->locknum], header, link); header->last_used = now; - ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], - header, lru_link); + ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], header, link); } /*% @@ -8539,7 +8576,7 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]); header != NULL && purgecount > 0; header = header_prev) { - header_prev = ISC_LIST_PREV(header, lru_link); + header_prev = ISC_LIST_PREV(header, link); /* * Unlink the entry at this point to avoid checking it * again even if it's currently used someone else and @@ -8548,7 +8585,7 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, * TTL was reset to 0. */ ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header, - lru_link); + link); expire_header(rbtdb, header, tree_locked); purgecount--; } diff --git a/contrib/bind9/lib/dns/rcode.c b/contrib/bind9/lib/dns/rcode.c index 58ade8587e8..9feaeb07d9c 100644 --- a/contrib/bind9/lib/dns/rcode.c +++ b/contrib/bind9/lib/dns/rcode.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rcode.c,v 1.8 2008/09/25 04:02:38 tbox Exp $ */ +/* $Id: rcode.c,v 1.8.48.2 2010/01/15 23:47:33 tbox Exp $ */ #include #include @@ -100,6 +100,8 @@ { DNS_KEYALG_ECC, "ECC", 0 }, \ { DNS_KEYALG_RSASHA1, "RSASHA1", 0 }, \ { DNS_KEYALG_NSEC3RSASHA1, "NSEC3RSASHA1", 0 }, \ + { DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \ + { DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \ { DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \ { DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \ { DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \ diff --git a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c index bc2b4e889d4..6a58bc9bb4e 100644 --- a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c +++ b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ipseckey_45.c,v 1.4.332.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: ipseckey_45.c,v 1.4.332.3 2009/09/18 21:55:48 jinmei Exp $ */ #ifndef RDATA_GENERIC_IPSECKEY_45_C #define RDATA_GENERIC_IPSECKEY_45_C @@ -243,6 +243,7 @@ fromwire_ipseckey(ARGS_FROMWIRE) { isc_buffer_forward(source, 3); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); isc_buffer_activeregion(source, ®ion); + isc_buffer_forward(source, region.length); return(mem_tobuffer(target, region.base, region.length)); default: diff --git a/contrib/bind9/lib/dns/rdatalist.c b/contrib/bind9/lib/dns/rdatalist.c index d6f11ae64d3..d0726198964 100644 --- a/contrib/bind9/lib/dns/rdatalist.c +++ b/contrib/bind9/lib/dns/rdatalist.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatalist.c,v 1.36 2008/09/24 02:46:22 marka Exp $ */ +/* $Id: rdatalist.c,v 1.36.336.2 2010/02/25 10:57:12 tbox Exp $ */ /*! \file */ @@ -46,6 +46,8 @@ static dns_rdatasetmethods_t methods = { isc__rdatalist_getclosest, NULL, NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind9/lib/dns/rdataset.c b/contrib/bind9/lib/dns/rdataset.c index 6088a068ad2..946ec9ae9aa 100644 --- a/contrib/bind9/lib/dns/rdataset.c +++ b/contrib/bind9/lib/dns/rdataset.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.c,v 1.82.50.2 2009/01/18 23:47:40 tbox Exp $ */ +/* $Id: rdataset.c,v 1.82.50.2.22.2 2010/02/25 10:57:12 tbox Exp $ */ /*! \file */ @@ -182,6 +182,8 @@ static dns_rdatasetmethods_t question_methods = { NULL, NULL, NULL, + NULL, + NULL, NULL }; @@ -732,3 +734,22 @@ dns_rdataset_putadditional(dns_acache_t *acache, return (ISC_R_FAILURE); } +void +dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + + if (rdataset->methods->settrust != NULL) + (rdataset->methods->settrust)(rdataset, trust); + else + rdataset->trust = trust; +} + +void +dns_rdataset_expire(dns_rdataset_t *rdataset) { + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + + if (rdataset->methods->expire != NULL) + (rdataset->methods->expire)(rdataset); +} diff --git a/contrib/bind9/lib/dns/rdataslab.c b/contrib/bind9/lib/dns/rdataslab.c index b22868d6f21..4eadff9881e 100644 --- a/contrib/bind9/lib/dns/rdataslab.c +++ b/contrib/bind9/lib/dns/rdataslab.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataslab.c,v 1.48.50.2 2009/01/18 23:47:40 tbox Exp $ */ +/* $Id: rdataslab.c,v 1.48.50.2.22.2 2010/02/25 10:57:12 tbox Exp $ */ /*! \file */ @@ -436,6 +436,8 @@ static dns_rdatasetmethods_t rdataset_methods = { NULL, NULL, NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c index 1b4f407c87f..244718fb5db 100644 --- a/contrib/bind9/lib/dns/resolver.c +++ b/contrib/bind9/lib/dns/resolver.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.384.14.14.8.2 2010/01/07 17:17:19 each Exp $ */ +/* $Id: resolver.c,v 1.384.14.20.8.2 2010/02/25 10:57:12 tbox Exp $ */ /*! \file */ @@ -334,6 +334,18 @@ typedef struct alternate { ISC_LINK(struct alternate) link; } alternate_t; +typedef struct dns_badcache dns_badcache_t; +struct dns_badcache { + dns_badcache_t * next; + dns_rdatatype_t type; + isc_time_t expire; + unsigned int hashval; + dns_name_t name; +}; +#define DNS_BADCACHE_SIZE 1021 +#define DNS_BADCACHE_TTL(fctx) \ + (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30) + struct dns_resolver { /* Unlocked. */ unsigned int magic; @@ -380,6 +392,13 @@ struct dns_resolver { isc_boolean_t priming; unsigned int spillat; /* clients-per-query */ unsigned int nextdisp; + + /* Bad cache. */ + dns_badcache_t ** badcache; + unsigned int badcount; + unsigned int badhash; + unsigned int badsweep; + /* Locked by primelock. */ dns_fetch_t * primefetch; /* Locked by nlock. */ @@ -410,7 +429,8 @@ static void empty_bucket(dns_resolver_t *res); static isc_result_t resquery_send(resquery_t *query); static void resquery_response(isc_task_t *task, isc_event_t *event); static void resquery_connected(isc_task_t *task, isc_event_t *event); -static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying); +static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, + isc_boolean_t badcache); static isc_boolean_t fctx_destroy(fetchctx_t *fctx); static isc_result_t ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, @@ -1169,7 +1189,7 @@ process_sendevent(resquery_t *query, isc_event_t *event) { if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); } } @@ -2071,7 +2091,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) { if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); } } @@ -2133,7 +2153,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) { dns_adb_destroyfind(&find); if (want_try) - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); else if (want_done) fctx_done(fctx, ISC_R_FAILURE, __LINE__); else if (bucket_empty) @@ -2534,8 +2554,18 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, } } +static isc_boolean_t +isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) { + int order; + unsigned int nlabels; + dns_namereln_t namereln; + + namereln = dns_name_fullcompare(name1, name2, &order, &nlabels); + return (ISC_TF(namereln == dns_namereln_subdomain)); +} + static isc_result_t -fctx_getaddresses(fetchctx_t *fctx) { +fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dns_resolver_t *res; @@ -2579,23 +2609,40 @@ fctx_getaddresses(fetchctx_t *fctx) { dns_name_t *name = &fctx->name; dns_name_t suffix; unsigned int labels; + dns_fixedname_t fixed; + dns_name_t *domain; /* * DS records are found in the parent server. * Strip label to get the correct forwarder (if any). */ - if (fctx->type == dns_rdatatype_ds && + if (dns_rdatatype_atparent(fctx->type) && dns_name_countlabels(name) > 1) { dns_name_init(&suffix, NULL); labels = dns_name_countlabels(name); dns_name_getlabelsequence(name, 1, labels - 1, &suffix); name = &suffix; } - result = dns_fwdtable_find(fctx->res->view->fwdtable, name, - &forwarders); + + dns_fixedname_init(&fixed); + domain = dns_fixedname_name(&fixed); + result = dns_fwdtable_find2(fctx->res->view->fwdtable, name, + domain, &forwarders); if (result == ISC_R_SUCCESS) { sa = ISC_LIST_HEAD(forwarders->addrs); fctx->fwdpolicy = forwarders->fwdpolicy; + if (fctx->fwdpolicy == dns_fwdpolicy_only && + isstrictsubdomain(domain, &fctx->domain)) { + isc_mem_t *mctx; + + mctx = res->buckets[fctx->bucketnum].mctx; + dns_name_free(&fctx->domain, mctx); + dns_name_init(&fctx->domain, NULL); + result = dns_name_dup(domain, mctx, + &fctx->domain); + if (result != ISC_R_SUCCESS) + return (result); + } } } @@ -2737,12 +2784,24 @@ fctx_getaddresses(fetchctx_t *fctx) { */ result = DNS_R_WAIT; } else { + isc_time_t expire; + isc_interval_t i; /* * We've lost completely. We don't know any * addresses, and the ADB has told us it can't get * them. */ FCTXTRACE("no addresses"); + isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0); + result = isc_time_nowplusinterval(&expire, &i); + if (badcache && + (fctx->type == dns_rdatatype_dnskey || + fctx->type == dns_rdatatype_dlv || + fctx->type == dns_rdatatype_ds) && + result == ISC_R_SUCCESS) + dns_resolver_addbadcache(fctx->res, + &fctx->name, + fctx->type, &expire); result = ISC_R_FAILURE; } } else { @@ -2965,7 +3024,7 @@ fctx_nextaddress(fetchctx_t *fctx) { } static void -fctx_try(fetchctx_t *fctx, isc_boolean_t retrying) { +fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) { isc_result_t result; dns_adbaddrinfo_t *addrinfo; @@ -2983,7 +3042,7 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying) { fctx_cleanupaltfinds(fctx); fctx_cleanupforwaddrs(fctx); fctx_cleanupaltaddrs(fctx); - result = fctx_getaddresses(fctx); + result = fctx_getaddresses(fctx, badcache); if (result == DNS_R_WAIT) { /* * Sleep waiting for addresses. @@ -3148,7 +3207,7 @@ fctx_timeout(isc_task_t *task, isc_event_t *event) { /* * Keep trying. */ - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); } isc_event_free(&event); @@ -3318,7 +3377,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) { if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else - fctx_try(fctx, ISC_FALSE); + fctx_try(fctx, ISC_FALSE, ISC_FALSE); } else if (bucket_empty) empty_bucket(res); } @@ -3477,21 +3536,22 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, if (domain == NULL) { dns_forwarders_t *forwarders = NULL; unsigned int labels; + dns_name_t *fwdname = name; /* * DS records are found in the parent server. * Strip label to get the correct forwarder (if any). */ - if (fctx->type == dns_rdatatype_ds && + if (dns_rdatatype_atparent(fctx->type) && dns_name_countlabels(name) > 1) { dns_name_init(&suffix, NULL); labels = dns_name_countlabels(name); dns_name_getlabelsequence(name, 1, labels - 1, &suffix); - name = &suffix; + fwdname = &suffix; } dns_fixedname_init(&fixed); domain = dns_fixedname_name(&fixed); - result = dns_fwdtable_find2(fctx->res->view->fwdtable, name, + result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname, domain, &forwarders); if (result == ISC_R_SUCCESS) fctx->fwdpolicy = forwarders->fwdpolicy; @@ -3502,7 +3562,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, * nameservers, and we're not in forward-only mode, * so find the best nameservers to use. */ - if (dns_rdatatype_atparent(type)) + if (dns_rdatatype_atparent(fctx->type)) findoptions |= DNS_DBFIND_NOEXACT; result = dns_view_findzonecut(res->view, name, domain, 0, findoptions, ISC_TRUE, @@ -3895,6 +3955,8 @@ validated(isc_task_t *task, isc_event_t *event) { LOCK(&fctx->res->buckets[fctx->bucketnum].lock); + isc_stdtime_get(&now); + /* * If chaining, we need to make sure that the right result code is * returned, and that the rdatasets are bound. @@ -3941,35 +4003,80 @@ validated(isc_task_t *task, isc_event_t *event) { inc_stats(fctx->res, dns_resstatscounter_valfail); fctx->valfail++; fctx->vresult = vevent->result; - result = ISC_R_NOTFOUND; - if (vevent->rdataset != NULL) - result = dns_db_findnode(fctx->cache, vevent->name, - ISC_TRUE, &node); - if (result == ISC_R_SUCCESS) - (void)dns_db_deleterdataset(fctx->cache, node, NULL, - vevent->type, 0); - if (result == ISC_R_SUCCESS && vevent->sigrdataset != NULL) - (void)dns_db_deleterdataset(fctx->cache, node, NULL, - dns_rdatatype_rrsig, - vevent->type); - if (result == ISC_R_SUCCESS) - dns_db_detachnode(fctx->cache, &node); - result = vevent->result; + if (fctx->vresult != DNS_R_BROKENCHAIN) { + result = ISC_R_NOTFOUND; + if (vevent->rdataset != NULL) + result = dns_db_findnode(fctx->cache, + vevent->name, + ISC_TRUE, &node); + if (result == ISC_R_SUCCESS) + (void)dns_db_deleterdataset(fctx->cache, node, + NULL, + vevent->type, 0); + if (result == ISC_R_SUCCESS && + vevent->sigrdataset != NULL) + (void)dns_db_deleterdataset(fctx->cache, node, + NULL, + dns_rdatatype_rrsig, + vevent->type); + if (result == ISC_R_SUCCESS) + dns_db_detachnode(fctx->cache, &node); + } + if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) { + /* + * Cache the data as pending for later validation. + */ + result = ISC_R_NOTFOUND; + if (vevent->rdataset != NULL) + result = dns_db_findnode(fctx->cache, + vevent->name, + ISC_TRUE, &node); + if (result == ISC_R_SUCCESS) { + (void)dns_db_addrdataset(fctx->cache, node, + NULL, now, + vevent->rdataset, 0, + NULL); + } + if (result == ISC_R_SUCCESS && + vevent->sigrdataset != NULL) + (void)dns_db_addrdataset(fctx->cache, node, + NULL, now, + vevent->sigrdataset, + 0, NULL); + if (result == ISC_R_SUCCESS) + dns_db_detachnode(fctx->cache, &node); + } + result = fctx->vresult; add_bad(fctx, addrinfo, result, badns_validation); isc_event_free(&event); UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); INSIST(fctx->validator == NULL); fctx->validator = ISC_LIST_HEAD(fctx->validators); - if (fctx->validator != NULL) { + if (fctx->validator != NULL) dns_validator_send(fctx->validator); - } else if (sentresponse) + else if (sentresponse) fctx_done(fctx, result, __LINE__); /* Locks bucket. */ - else - fctx_try(fctx, ISC_TRUE); /* Locks bucket. */ + else if (result == DNS_R_BROKENCHAIN) { + isc_result_t tresult; + isc_time_t expire; + isc_interval_t i; + + isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0); + tresult = isc_time_nowplusinterval(&expire, &i); + if (negative && + (fctx->type == dns_rdatatype_dnskey || + fctx->type == dns_rdatatype_dlv || + fctx->type == dns_rdatatype_ds) && + tresult == ISC_R_SUCCESS) + dns_resolver_addbadcache(fctx->res, + &fctx->name, + fctx->type, &expire); + fctx_done(fctx, result, __LINE__); /* Locks bucket. */ + } else + fctx_try(fctx, ISC_TRUE, ISC_TRUE); /* Locks bucket. */ return; } - isc_stdtime_get(&now); if (negative) { dns_rdatatype_t covers; @@ -5762,7 +5869,7 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { /* * Try again. */ - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); } else { unsigned int n; dns_rdataset_t *nsrdataset = NULL; @@ -6601,7 +6708,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) { /* * Try again. */ - fctx_try(fctx, !get_nameservers); + fctx_try(fctx, !get_nameservers, ISC_FALSE); } else if (resend) { /* * Resend (probably with changed options). @@ -6663,6 +6770,27 @@ resquery_response(isc_task_t *task, isc_event_t *event) { /*** *** Resolver Methods ***/ +static void +destroy_badcache(dns_resolver_t *res) { + dns_badcache_t *bad, *next; + unsigned int i; + + if (res->badcache != NULL) { + for (i = 0; i < res->badhash; i++) + for (bad = res->badcache[i]; bad != NULL; + bad = next) { + next = bad->next; + isc_mem_put(res->mctx, bad, sizeof(*bad) + + bad->name.length); + res->badcount--; + } + isc_mem_put(res->mctx, res->badcache, + sizeof(*res->badcache) * res->badhash); + res->badcache = NULL; + res->badhash = 0; + INSIST(res->badcount == 0); + } +} static void destroy(dns_resolver_t *res) { @@ -6700,6 +6828,7 @@ destroy(dns_resolver_t *res) { isc_mem_put(res->mctx, a, sizeof(*a)); } dns_resolver_reset_algorithms(res); + destroy_badcache(res); dns_resolver_resetmustbesecure(res); #if USE_ALGLOCK isc_rwlock_destroy(&res->alglock); @@ -6823,6 +6952,10 @@ dns_resolver_create(dns_view_t *view, ISC_LIST_INIT(res->alternates); res->udpsize = RECV_BUFFER_SIZE; res->algorithms = NULL; + res->badcache = NULL; + res->badcount = 0; + res->badhash = 0; + res->badsweep = 0; res->mustbesecure = NULL; res->spillatmin = res->spillat = 10; res->spillatmax = 100; @@ -7664,6 +7797,256 @@ dns_resolver_getudpsize(dns_resolver_t *resolver) { return (resolver->udpsize); } +void +dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) { + unsigned int i; + dns_badcache_t *bad, *prev, *next; + + REQUIRE(VALID_RESOLVER(resolver)); + + LOCK(&resolver->lock); + if (resolver->badcache == NULL) + goto unlock; + + if (name != NULL) { + isc_time_t now; + isc_result_t result; + result = isc_time_now(&now); + if (result != ISC_R_SUCCESS) + isc_time_settoepoch(&now); + i = dns_name_hash(name, ISC_FALSE) % resolver->badhash; + prev = NULL; + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + int n; + next = bad->next; + n = isc_time_compare(&bad->expire, &now); + if (n < 0 || dns_name_equal(name, &bad->name)) { + if (prev == NULL) + resolver->badcache[i] = bad->next; + else + prev->next = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + } else + prev = bad; + } + } else + destroy_badcache(resolver); + + unlock: + UNLOCK(&resolver->lock); + +} + +static void +resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) { + unsigned int newsize; + dns_badcache_t **new, *bad, *next; + unsigned int i; + + if (grow) + newsize = resolver->badhash * 2 + 1; + else + newsize = (resolver->badhash - 1) / 2; + + new = isc_mem_get(resolver->mctx, + sizeof(*resolver->badcache) * newsize); + if (new == NULL) + return; + memset(new, 0, sizeof(*resolver->badcache) * newsize); + for (i = 0; i < resolver->badhash; i++) { + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + next = bad->next; + if (isc_time_compare(&bad->expire, now) < 0) { + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + } else { + bad->next = new[bad->hashval % newsize]; + new[bad->hashval % newsize] = bad; + } + } + } + isc_mem_put(resolver->mctx, resolver->badcache, + sizeof(*resolver->badcache) * resolver->badhash); + resolver->badhash = newsize; + resolver->badcache = new; +} + +void +dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name, + dns_rdatatype_t type, isc_time_t *expire) +{ + isc_time_t now; + isc_result_t result = ISC_R_SUCCESS; + unsigned int i, hashval; + dns_badcache_t *bad, *prev, *next; + + REQUIRE(VALID_RESOLVER(resolver)); + + LOCK(&resolver->lock); + if (resolver->badcache == NULL) { + resolver->badcache = isc_mem_get(resolver->mctx, + sizeof(*resolver->badcache) * + DNS_BADCACHE_SIZE); + if (resolver->badcache == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + resolver->badhash = DNS_BADCACHE_SIZE; + memset(resolver->badcache, 0, sizeof(*resolver->badcache) * + resolver->badhash); + } + + result = isc_time_now(&now); + if (result != ISC_R_SUCCESS) + isc_time_settoepoch(&now); + hashval = dns_name_hash(name, ISC_FALSE); + i = hashval % resolver->badhash; + prev = NULL; + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + next = bad->next; + if (bad->type == type && dns_name_equal(name, &bad->name)) + break; + if (isc_time_compare(&bad->expire, &now) < 0) { + if (prev == NULL) + resolver->badcache[i] = bad->next; + else + prev->next = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + } else + prev = bad; + } + if (bad == NULL) { + isc_buffer_t buffer; + bad = isc_mem_get(resolver->mctx, sizeof(*bad) + name->length); + if (bad == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + bad->type = type; + bad->hashval = hashval; + isc_buffer_init(&buffer, bad + 1, name->length); + dns_name_init(&bad->name, NULL); + dns_name_copy(name, &bad->name, &buffer); + bad->next = resolver->badcache[i]; + resolver->badcache[i] = bad; + resolver->badcount++; + if (resolver->badcount > resolver->badhash * 8) + resizehash(resolver, &now, ISC_TRUE); + if (resolver->badcount < resolver->badhash * 2 && + resolver->badhash > DNS_BADCACHE_SIZE) + resizehash(resolver, &now, ISC_FALSE); + } + bad->expire = *expire; + cleanup: + UNLOCK(&resolver->lock); +} + +isc_boolean_t +dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name, + dns_rdatatype_t type, isc_time_t *now) +{ + dns_badcache_t *bad, *prev, *next; + isc_boolean_t answer = ISC_FALSE; + unsigned int i; + + REQUIRE(VALID_RESOLVER(resolver)); + + LOCK(&resolver->lock); + if (resolver->badcache == NULL) + goto unlock; + + i = dns_name_hash(name, ISC_FALSE) % resolver->badhash; + prev = NULL; + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + next = bad->next; + /* + * Search the hash list. Clean out expired records as we go. + */ + if (isc_time_compare(&bad->expire, now) < 0) { + if (prev != NULL) + prev->next = bad->next; + else + resolver->badcache[i] = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + continue; + } + if (bad->type == type && dns_name_equal(name, &bad->name)) { + answer = ISC_TRUE; + break; + } + prev = bad; + } + + /* + * Slow sweep to clean out stale records. + */ + i = resolver->badsweep++ % resolver->badhash; + bad = resolver->badcache[i]; + if (bad != NULL && isc_time_compare(&bad->expire, now) < 0) { + resolver->badcache[i] = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + } + + unlock: + UNLOCK(&resolver->lock); + return (answer); +} + +void +dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp) { + char namebuf[DNS_NAME_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; + dns_badcache_t *bad, *next, *prev; + isc_time_t now; + unsigned int i; + isc_uint64_t t; + + LOCK(&resolver->lock); + fprintf(fp, ";\n; Bad cache\n;\n"); + + if (resolver->badcache == NULL) + goto unlock; + + TIME_NOW(&now); + for (i = 0; i < resolver->badhash; i++) { + prev = NULL; + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + next = bad->next; + if (isc_time_compare(&bad->expire, &now) < 0) { + if (prev != NULL) + prev->next = bad->next; + else + resolver->badcache[i] = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + continue; + } + prev = bad; + dns_name_format(&bad->name, namebuf, sizeof(namebuf)); + dns_rdatatype_format(bad->type, typebuf, + sizeof(typebuf)); + t = isc_time_microdiff(&bad->expire, &now); + t /= 1000; + fprintf(fp, "; %s/%s [ttl " + "%" ISC_PLATFORM_QUADFORMAT "u]\n", + namebuf, typebuf, t); + } + } + + unlock: + UNLOCK(&resolver->lock); +} + static void free_algorithm(void *node, void *arg) { unsigned char *algorithms = node; diff --git a/contrib/bind9/lib/dns/result.c b/contrib/bind9/lib/dns/result.c index 54c70e0e908..e3361975823 100644 --- a/contrib/bind9/lib/dns/result.c +++ b/contrib/bind9/lib/dns/result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: result.c,v 1.125 2008/09/25 04:02:38 tbox Exp $ */ +/* $Id: result.c,v 1.125.122.2 2010/02/25 10:57:12 tbox Exp $ */ /*! \file */ @@ -157,6 +157,9 @@ static const char *text[DNS_R_NRESULTS] = { "MX is an address", /*%< 102 DNS_R_MXISADDRESS */ "duplicate query", /*%< 103 DNS_R_DUPLICATE */ "invalid NSEC3 owner name (wildcard)", /*%< 104 DNS_R_INVALIDNSEC3 */ + + "not master", /*%< 105 DNS_R_NOTMASTER */ + "broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */ }; static const char *rcode_text[DNS_R_NRCODERESULTS] = { diff --git a/contrib/bind9/lib/dns/sdb.c b/contrib/bind9/lib/dns/sdb.c index 03fca9ed63e..e0c8786b213 100644 --- a/contrib/bind9/lib/dns/sdb.c +++ b/contrib/bind9/lib/dns/sdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.c,v 1.66.48.2 2009/04/21 23:47:18 tbox Exp $ */ +/* $Id: sdb.c,v 1.66.48.3.8.2 2010/02/25 10:57:12 tbox Exp $ */ /*! \file */ @@ -1387,6 +1387,8 @@ static dns_rdatasetmethods_t methods = { NULL, NULL, NULL, + NULL, + NULL, NULL }; @@ -1458,9 +1460,11 @@ dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); - while (sdbiter->current != NULL) + while (sdbiter->current != NULL) { if (dns_name_equal(sdbiter->current->name, name)) return (ISC_R_SUCCESS); + sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); + } return (ISC_R_NOTFOUND); } diff --git a/contrib/bind9/lib/dns/sdlz.c b/contrib/bind9/lib/dns/sdlz.c index 89cd0eea2a7..caf71b5af7c 100644 --- a/contrib/bind9/lib/dns/sdlz.c +++ b/contrib/bind9/lib/dns/sdlz.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2005-2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2005-2010 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -50,7 +50,7 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdlz.c,v 1.18.50.2 2009/04/21 23:47:18 tbox Exp $ */ +/* $Id: sdlz.c,v 1.18.50.3.8.2 2010/02/25 10:57:12 tbox Exp $ */ /*! \file */ @@ -1117,9 +1117,11 @@ dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist); - while (sdlziter->current != NULL) + while (sdlziter->current != NULL) { if (dns_name_equal(sdlziter->current->name, name)) return (ISC_R_SUCCESS); + sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link); + } return (ISC_R_NOTFOUND); } @@ -1209,6 +1211,8 @@ static dns_rdatasetmethods_t rdataset_methods = { NULL, NULL, NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind9/lib/dns/spnego.c b/contrib/bind9/lib/dns/spnego.c index 0ae6ea233c0..6c94e51baee 100644 --- a/contrib/bind9/lib/dns/spnego.c +++ b/contrib/bind9/lib/dns/spnego.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: spnego.c,v 1.8.118.2 2009/01/18 23:47:40 tbox Exp $ */ +/* $Id: spnego.c,v 1.8.118.4 2009/07/21 07:27:13 marka Exp $ */ /*! \file * \brief @@ -265,8 +265,7 @@ decode_oid(const unsigned char *p, size_t len, oid * k, size_t * size); static int -decode_enumerated(const unsigned char *p, size_t len, - unsigned *num, size_t *size); +decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size); static int decode_octet_string(const unsigned char *, size_t, octet_string *, size_t *); @@ -291,8 +290,7 @@ der_put_length_and_tag(unsigned char *, size_t, size_t, Der_class, Der_type, int, size_t *); static int -encode_enumerated(unsigned char *p, size_t len, - const unsigned *data, size_t *); +encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *); static int encode_octet_string(unsigned char *p, size_t len, @@ -622,7 +620,7 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status, } for (i = 0; !found && i < init_token.mechTypes.len; ++i) { - char mechbuf[17]; + unsigned char mechbuf[17]; size_t mech_len; ret = der_put_oid(mechbuf + sizeof(mechbuf) - 1, @@ -956,8 +954,7 @@ der_match_tag_and_length(const unsigned char *p, size_t len, } static int -decode_enumerated(const unsigned char *p, size_t len, - unsigned *num, size_t *size) +decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size) { size_t ret = 0; size_t l, reallen; @@ -1269,10 +1266,9 @@ der_put_length_and_tag(unsigned char *p, size_t len, size_t len_val, } static int -encode_enumerated(unsigned char *p, size_t len, const unsigned *data, - size_t *size) +encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *size) { - unsigned num = *data; + unsigned num = *(const unsigned *)data; size_t ret = 0; size_t l; int e; diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c index ce49daf2eb1..0ccdc41980c 100644 --- a/contrib/bind9/lib/dns/validator.c +++ b/contrib/bind9/lib/dns/validator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.164.12.9.8.2 2009/12/31 20:29:21 each Exp $ */ +/* $Id: validator.c,v 1.164.12.11.8.2 2010/02/25 10:57:12 tbox Exp $ */ #include @@ -177,9 +177,16 @@ static inline void markanswer(dns_validator_t *val) { validator_log(val, ISC_LOG_DEBUG(3), "marking as answer"); if (val->event->rdataset != NULL) - val->event->rdataset->trust = dns_trust_answer; + dns_rdataset_settrust(val->event->rdataset, dns_trust_answer); if (val->event->sigrdataset != NULL) - val->event->sigrdataset->trust = dns_trust_answer; + dns_rdataset_settrust(val->event->sigrdataset, + dns_trust_answer); +} + +static inline void +marksecure(dns_validatorevent_t *event) { + dns_rdataset_settrust(event->rdataset, dns_trust_secure); + dns_rdataset_settrust(event->sigrdataset, dns_trust_secure); } static void @@ -425,7 +432,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { if (eresult == ISC_R_CANCELED) validator_done(val, eresult); else - validator_done(val, DNS_R_NOVALIDKEY); + validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); @@ -495,7 +502,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) { if (eresult == ISC_R_CANCELED) validator_done(val, eresult); else - validator_done(val, DNS_R_NOVALIDDS); + validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); @@ -635,10 +642,16 @@ keyvalidated(isc_task_t *task, isc_event_t *event) { if (result != DNS_R_WAIT) validator_done(val, result); } else { + if (eresult != DNS_R_BROKENCHAIN) { + if (dns_rdataset_isassociated(&val->frdataset)) + dns_rdataset_expire(&val->frdataset); + if (dns_rdataset_isassociated(&val->fsigrdataset)) + dns_rdataset_expire(&val->fsigrdataset); + } validator_log(val, ISC_LOG_DEBUG(3), "keyvalidated: got %s", isc_result_totext(eresult)); - validator_done(val, eresult); + validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); @@ -685,10 +698,16 @@ dsvalidated(isc_task_t *task, isc_event_t *event) { if (result != DNS_R_WAIT) validator_done(val, result); } else { + if (eresult != DNS_R_BROKENCHAIN) { + if (dns_rdataset_isassociated(&val->frdataset)) + dns_rdataset_expire(&val->frdataset); + if (dns_rdataset_isassociated(&val->fsigrdataset)) + dns_rdataset_expire(&val->fsigrdataset); + } validator_log(val, ISC_LOG_DEBUG(3), "dsvalidated: got %s", isc_result_totext(eresult)); - validator_done(val, eresult); + validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); @@ -1199,6 +1218,8 @@ authvalidated(isc_task_t *task, isc_event_t *event) { validator_log(val, ISC_LOG_DEBUG(3), "authvalidated: got %s", isc_result_totext(result)); + if (result == DNS_R_BROKENCHAIN) + val->authfail++; if (result == ISC_R_CANCELED) validator_done(val, result); else { @@ -1271,6 +1292,7 @@ authvalidated(isc_task_t *task, isc_event_t *event) { * \li DNS_R_NCACHENXRRSET * \li DNS_R_NXRRSET * \li DNS_R_NXDOMAIN + * \li DNS_R_BROKENCHAIN */ static inline isc_result_t view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { @@ -1280,9 +1302,12 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; unsigned int options; + isc_time_t now; char buf1[DNS_NAME_FORMATSIZE]; char buf2[DNS_NAME_FORMATSIZE]; char buf3[DNS_NAME_FORMATSIZE]; + char namebuf[DNS_NAME_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); @@ -1292,6 +1317,16 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { if (val->view->zonetable == NULL) return (ISC_R_CANCELED); + if (isc_time_now(&now) == ISC_R_SUCCESS && + dns_resolver_getbadcache(val->view->resolver, name, type, &now)) { + + dns_name_format(name, namebuf, sizeof(namebuf)); + dns_rdatatype_format(type, typebuf, sizeof(typebuf)); + validator_log(val, ISC_LOG_INFO, "bad cache hit (%s/%s)", + namebuf, typebuf); + return (DNS_R_BROKENCHAIN); + } + options = DNS_DBFIND_PENDINGOK; if (type == dns_rdatatype_dlv) options |= DNS_DBFIND_COVERINGNSEC; @@ -1300,6 +1335,7 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { result = dns_view_find(val->view, name, type, 0, options, ISC_FALSE, NULL, NULL, foundname, &val->frdataset, &val->fsigrdataset); + if (result == DNS_R_NXDOMAIN) { if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); @@ -1656,7 +1692,8 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) { /* * We don't know anything about this key. */ - result = create_fetch(val, &siginfo->signer, dns_rdatatype_dnskey, + result = create_fetch(val, &siginfo->signer, + dns_rdatatype_dnskey, fetch_callback_validator, "get_key"); if (result != ISC_R_SUCCESS) return (result); @@ -1671,7 +1708,8 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) { * This key doesn't exist. */ result = DNS_R_CONTINUE; - } + } else if (result == DNS_R_BROKENCHAIN) + return (result); if (dns_rdataset_isassociated(&val->frdataset) && val->keyset != &val->frdataset) @@ -1919,8 +1957,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) { "looking for noqname proof"); return (nsecvalidate(val, ISC_FALSE)); } else if (result == ISC_R_SUCCESS) { - event->rdataset->trust = dns_trust_secure; - event->sigrdataset->trust = dns_trust_secure; + marksecure(event); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); return (result); @@ -2096,8 +2133,7 @@ dlv_validatezonekey(dns_validator_t *val) { "no RRSIG matching DLV key"); } if (result == ISC_R_SUCCESS) { - val->event->rdataset->trust = dns_trust_secure; - val->event->sigrdataset->trust = dns_trust_secure; + marksecure(val->event); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); return (result); } else if (result == ISC_R_NOMORE && !supported_algorithm) { @@ -2198,8 +2234,7 @@ validatezonekey(dns_validator_t *val) { keynode = nextnode; } if (result == ISC_R_SUCCESS) { - event->rdataset->trust = dns_trust_secure; - event->sigrdataset->trust = dns_trust_secure; + marksecure(event); validator_log(val, ISC_LOG_DEBUG(3), "signed by trusted key; " "marking as secure"); @@ -2226,11 +2261,14 @@ validatezonekey(dns_validator_t *val) { */ dns_name_format(val->event->name, namebuf, sizeof(namebuf)); - validator_log(val, ISC_LOG_DEBUG(2), + validator_log(val, ISC_LOG_NOTICE, "unable to find a DNSKEY which verifies " "the DNSKEY RRset and also matches one " "of specified trusted-keys for '%s'", namebuf); + validator_log(val, ISC_LOG_NOTICE, + "please check the 'trusted-keys' for " + "'%s' in named.conf.", namebuf); return (DNS_R_NOVALIDKEY); } @@ -2291,7 +2329,8 @@ validatezonekey(dns_validator_t *val) { dns_rdataset_disassociate(&val->fsigrdataset); validator_log(val, ISC_LOG_DEBUG(2), "no DS record"); return (DNS_R_NOVALIDSIG); - } + } else if (result == DNS_R_BROKENCHAIN) + return (result); } /* @@ -2440,8 +2479,7 @@ validatezonekey(dns_validator_t *val) { "no RRSIG matching DS key"); } if (result == ISC_R_SUCCESS) { - event->rdataset->trust = dns_trust_secure; - event->sigrdataset->trust = dns_trust_secure; + marksecure(event); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); return (result); } else if (result == ISC_R_NOMORE && !supported_algorithm) { @@ -2844,6 +2882,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { "nsecvalidate"); if (result != ISC_R_SUCCESS) return (result); + val->authcount++; return (DNS_R_WAIT); } @@ -2868,8 +2907,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { "noqname proof found"); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); - val->event->rdataset->trust = dns_trust_secure; - val->event->sigrdataset->trust = dns_trust_secure; + marksecure(val->event); return (ISC_R_SUCCESS); } else if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0 && dns_name_countlabels(dns_fixedname_name(&val->wild)) @@ -2923,6 +2961,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { } findnsec3proofs(val); + if (val->authcount == val->authfail) + return (DNS_R_BROKENCHAIN); validator_log(val, ISC_LOG_DEBUG(3), "nonexistence proof(s) not found"); val->attributes |= VALATTR_INSECURITY; @@ -2954,6 +2994,58 @@ check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) { return (ISC_FALSE); } +static void +dlvvalidated(isc_task_t *task, isc_event_t *event) { + dns_validatorevent_t *devent; + dns_validator_t *val; + isc_result_t eresult; + isc_boolean_t want_destroy; + + UNUSED(task); + INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); + + devent = (dns_validatorevent_t *)event; + val = devent->ev_arg; + eresult = devent->result; + + isc_event_free(&event); + dns_validator_destroy(&val->subvalidator); + + INSIST(val->event != NULL); + + validator_log(val, ISC_LOG_DEBUG(3), "in dlvvalidated"); + LOCK(&val->lock); + if (CANCELED(val)) { + validator_done(val, ISC_R_CANCELED); + } else if (eresult == ISC_R_SUCCESS) { + validator_log(val, ISC_LOG_DEBUG(3), + "dlvset with trust %d", val->frdataset.trust); + dns_rdataset_clone(&val->frdataset, &val->dlv); + val->havedlvsep = ISC_TRUE; + if (dlv_algorithm_supported(val)) + dlv_validator_start(val); + else { + markanswer(val); + validator_done(val, ISC_R_SUCCESS); + } + } else { + if (eresult != DNS_R_BROKENCHAIN) { + if (dns_rdataset_isassociated(&val->frdataset)) + dns_rdataset_expire(&val->frdataset); + if (dns_rdataset_isassociated(&val->fsigrdataset)) + dns_rdataset_expire(&val->fsigrdataset); + } + validator_log(val, ISC_LOG_DEBUG(3), + "dlvvalidated: got %s", + isc_result_totext(eresult)); + validator_done(val, DNS_R_BROKENCHAIN); + } + want_destroy = exit_check(val); + UNLOCK(&val->lock); + if (want_destroy) + destroy(val); +} + /*% * Callback from fetching a DLV record. * @@ -3173,6 +3265,24 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) { namebuf); result = view_find(val, dlvname, dns_rdatatype_dlv); if (result == ISC_R_SUCCESS) { + if (DNS_TRUST_PENDING(val->frdataset.trust) && + dns_rdataset_isassociated(&val->fsigrdataset)) + { + dns_fixedname_init(&val->fname); + dns_name_copy(dlvname, + dns_fixedname_name(&val->fname), + NULL); + result = create_validator(val, + dns_fixedname_name(&val->fname), + dns_rdatatype_dlv, + &val->frdataset, + &val->fsigrdataset, + dlvvalidated, + "finddlvsep"); + if (result != ISC_R_SUCCESS) + return (result); + return (DNS_R_WAIT); + } if (val->frdataset.trust < dns_trust_secure) return (DNS_R_NOVALIDSIG); val->havedlvsep = ISC_TRUE; @@ -3223,6 +3333,7 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) { * \li DNS_R_NOVALIDSIG * \li DNS_R_NOVALIDNSEC * \li DNS_R_NOTINSECURE + * \li DNS_R_BROKENCHAIN */ static isc_result_t proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume) @@ -3465,7 +3576,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume) if (result != ISC_R_SUCCESS) goto out; return (DNS_R_WAIT); - } + } else if (result == DNS_R_BROKENCHAIN) + return (result); } /* @@ -3682,6 +3794,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, val->seensig = ISC_FALSE; val->havedlvsep = ISC_FALSE; val->depth = 0; + val->authcount = 0; + val->authfail = 0; val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name); dns_rdataset_init(&val->frdataset); dns_rdataset_init(&val->fsigrdataset); diff --git a/contrib/bind9/lib/dns/view.c b/contrib/bind9/lib/dns/view.c index 5f1447ae06e..72163b4ab89 100644 --- a/contrib/bind9/lib/dns/view.c +++ b/contrib/bind9/lib/dns/view.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.c,v 1.150.84.2 2009/01/29 23:47:44 tbox Exp $ */ +/* $Id: view.c,v 1.150.84.3.8.2 2010/02/25 10:57:12 tbox Exp $ */ /*! \file */ @@ -1250,7 +1250,8 @@ dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, if (result != ISC_R_SUCCESS) return (result); - return (dns_view_gettsig(view, keyname, keyp)); + result = dns_view_gettsig(view, keyname, keyp); + return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result); } isc_result_t @@ -1270,10 +1271,11 @@ dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name); result = dns_master_dumptostream(view->mctx, view->cachedb, NULL, - &dns_master_style_cache, fp); + &dns_master_style_cache, fp); if (result != ISC_R_SUCCESS) return (result); dns_adb_dump(view->adb, fp); + dns_resolver_printbadcache(view->resolver, fp); return (ISC_R_SUCCESS); } @@ -1294,6 +1296,8 @@ dns_view_flushcache(dns_view_t *view) { dns_cache_attachdb(view->cache, &view->cachedb); if (view->acache != NULL) dns_acache_setdb(view->acache, view->cachedb); + if (view->resolver != NULL) + dns_resolver_flushbadcache(view->resolver, NULL); dns_adb_flush(view->adb); return (ISC_R_SUCCESS); @@ -1308,6 +1312,8 @@ dns_view_flushname(dns_view_t *view, dns_name_t *name) { dns_adb_flushname(view->adb, name); if (view->cache == NULL) return (ISC_R_SUCCESS); + if (view->resolver != NULL) + dns_resolver_flushbadcache(view->resolver, name); return (dns_cache_flushname(view->cache, name)); } diff --git a/contrib/bind9/lib/dns/zone.c b/contrib/bind9/lib/dns/zone.c index 423b0057872..c21b1f05b11 100644 --- a/contrib/bind9/lib/dns/zone.c +++ b/contrib/bind9/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.483.36.6 2009/03/26 22:57:07 marka Exp $ */ +/* $Id: zone.c,v 1.483.36.17 2009/12/21 04:32:42 marka Exp $ */ /*! \file */ @@ -200,7 +200,6 @@ struct dns_zone { isc_time_t keywarntime; isc_time_t signingtime; isc_time_t nsec3chaintime; - isc_uint32_t serial; isc_uint32_t refresh; isc_uint32_t retry; isc_uint32_t expire; @@ -351,11 +350,15 @@ struct dns_zone { #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U +#define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */ +#define DNS_ZONEFLG_THAW 0x08000000U #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0) /* Flags for zone_load() */ #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */ +#define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful + load. */ #define UNREACH_CHACHE_SIZE 10U #define UNREACH_HOLD_TIME 600 /* 10 minutes */ @@ -718,7 +721,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { isc_time_settoepoch(&zone->keywarntime); isc_time_settoepoch(&zone->signingtime); isc_time_settoepoch(&zone->nsec3chaintime); - zone->serial = 0; zone->refresh = DNS_ZONE_DEFAULTREFRESH; zone->retry = DNS_ZONE_DEFAULTRETRY; zone->expire = 0; @@ -967,16 +969,35 @@ dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { UNLOCK_ZONE(zone); } -isc_uint32_t -dns_zone_getserial(dns_zone_t *zone) { - isc_uint32_t serial; +isc_result_t +dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { + isc_result_t result; REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(serialp != NULL); LOCK_ZONE(zone); - serial = zone->serial; + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) { + result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp, + NULL, NULL, NULL, NULL, NULL); + } else + result = DNS_R_NOTLOADED; + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); + return (result); +} + +isc_uint32_t +dns_zone_getserial(dns_zone_t *zone) { + isc_result_t result; + isc_uint32_t serial; + + result = dns_zone_getserial2(zone, &serial); + if (result != ISC_R_SUCCESS) + serial = 0; /* XXX: not really correct, but no other choice */ + return (serial); } @@ -1314,7 +1335,9 @@ zone_load(dns_zone_t *zone, unsigned int flags) { INSIST(zone->type != dns_zone_none); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { - result = ISC_R_SUCCESS; + if ((flags & DNS_ZONELOADFLAG_THAW) != 0) + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); + result = DNS_R_CONTINUE; goto cleanup; } @@ -1448,6 +1471,8 @@ zone_load(dns_zone_t *zone, unsigned int flags) { if (result == DNS_R_CONTINUE) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); + if ((flags & DNS_ZONELOADFLAG_THAW) != 0) + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); goto cleanup; } @@ -1470,6 +1495,30 @@ dns_zone_loadnew(dns_zone_t *zone) { return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT)); } +isc_result_t +dns_zone_loadandthaw(dns_zone_t *zone) { + isc_result_t result; + + result = zone_load(zone, DNS_ZONELOADFLAG_THAW); + switch (result) { + case DNS_R_CONTINUE: + /* Deferred thaw. */ + break; + case ISC_R_SUCCESS: + case DNS_R_UPTODATE: + case DNS_R_SEENINCLUDE: + zone->update_disabled = ISC_FALSE; + break; + case DNS_R_NOMASTERFILE: + zone->update_disabled = ISC_FALSE; + break; + default: + /* Error, remain in disabled state. */ + break; + } + return (result); +} + static unsigned int get_master_options(dns_zone_t *zone) { unsigned int options; @@ -2148,7 +2197,8 @@ resume_signingwithkey(dns_zone_t *zone) { } result = zone_signwithkey(zone, rdata.data[0], - (rdata.data[1] << 8) | rdata.data[2], ISC_TF(rdata.data[3])); + (rdata.data[1] << 8) | rdata.data[2], + ISC_TF(rdata.data[3])); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: %s", @@ -2291,7 +2341,6 @@ static void set_resigntime(dns_zone_t *zone) { dns_rdataset_t rdataset; dns_fixedname_t fixed; - char namebuf[DNS_NAME_FORMATSIZE]; unsigned int resign; isc_result_t result; isc_uint32_t nanosecs; @@ -2305,7 +2354,6 @@ set_resigntime(dns_zone_t *zone) { return; } resign = rdataset.resign; - dns_name_format(dns_fixedname_name(&fixed), namebuf, sizeof(namebuf)); dns_rdataset_disassociate(&rdataset); isc_random_get(&nanosecs); nanosecs %= 1000000000; @@ -2409,7 +2457,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, unsigned int soacount = 0; unsigned int nscount = 0; unsigned int errors = 0; - isc_uint32_t serial, refresh, retry, expire, minimum; + isc_uint32_t serial, oldserial, refresh, retry, expire, minimum; isc_time_t now; isc_boolean_t needdump = ISC_FALSE; isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); @@ -2463,8 +2511,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, options = DNS_JOURNALOPT_RESIGN; else options = 0; - result = dns_journal_rollforward(zone->mctx, db, options, - zone->journal); + result = dns_journal_rollforward2(zone->mctx, db, options, + zone->sigresigninginterval, + zone->journal); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND && result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL && result != ISC_R_RANGE) { @@ -2544,14 +2593,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, * This is checked in zone_replacedb() for slave zones * as they don't reload from disk. */ + result = zone_get_from_db(zone, zone->db, NULL, NULL, + &oldserial, NULL, NULL, NULL, + NULL, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && - !isc_serial_gt(serial, zone->serial)) { + !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; INSIST(zone->type == dns_zone_master); - serialmin = (zone->serial + 1) & 0xffffffffU; - serialmax = (zone->serial + 0x7fffffffU) & + serialmin = (oldserial + 1) & 0xffffffffU; + serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; dns_zone_log(zone, ISC_LOG_ERROR, "ixfr-from-differences: " @@ -2560,10 +2613,10 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, serialmax); result = DNS_R_BADZONE; goto cleanup; - } else if (!isc_serial_ge(serial, zone->serial)) + } else if (!isc_serial_ge(serial, oldserial)) dns_zone_log(zone, ISC_LOG_ERROR, "zone serial has gone backwards"); - else if (serial == zone->serial && !hasinclude) + else if (serial == oldserial && !hasinclude) dns_zone_log(zone, ISC_LOG_ERROR, "zone serial unchanged. " "zone may fail to transfer " @@ -2580,7 +2633,6 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, "3 * refresh."); } - zone->serial = serial; zone->refresh = RANGE(refresh, zone->minrefresh, zone->maxrefresh); zone->retry = RANGE(retry, @@ -2664,8 +2716,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, } if (! dns_db_ispersistent(db)) - dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", - zone->serial, + dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial, dns_db_issecure(db) ? " (signed)" : ""); return (result); @@ -2683,7 +2734,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, if (zone->task != NULL) zone_settimer(zone, &now); result = ISC_R_SUCCESS; - } + } else if (zone->type == dns_zone_master) + dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors."); return (result); } @@ -4374,7 +4426,8 @@ updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version, seen_done = ISC_TRUE; else CHECK(update_one_rr(signing->db, version, diff, - DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata)); + DNS_DIFFOP_DEL, name, + rdataset.ttl, &rdata)); dns_rdata_reset(&rdata); } if (result == ISC_R_NOMORE) @@ -5458,6 +5511,7 @@ zone_sign(dns_zone_t *zone) { dst_key_t *zone_keys[MAXZONEKEYS]; isc_int32_t signatures; isc_boolean_t check_ksk, is_ksk; + isc_boolean_t commit = ISC_FALSE; isc_boolean_t delegation; isc_boolean_t finishedakey = ISC_FALSE; isc_boolean_t secureupdated = ISC_FALSE; @@ -5745,6 +5799,7 @@ zone_sign(dns_zone_t *zone) { goto failure; } } + if (finishedakey) { /* * We have changed the RRset above so we need to update @@ -5770,6 +5825,15 @@ zone_sign(dns_zone_t *zone) { goto failure; } } + + /* + * Have we changed anything? + */ + if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) + goto pauseall; + + commit = ISC_TRUE; + result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, &sig_diff, zone_keys, nkeys, now); if (result != ISC_R_SUCCESS) { @@ -5801,6 +5865,9 @@ zone_sign(dns_zone_t *zone) { goto failure; } + /* + * Write changes to journal file. + */ journalfile = dns_zone_getjournal(zone); if (journalfile != NULL) { dns_journal_t *journal = NULL; @@ -5823,7 +5890,7 @@ zone_sign(dns_zone_t *zone) { } } - + pauseall: /* * Pause all iterators so that dns_db_closeversion() can succeed. */ @@ -5840,7 +5907,7 @@ zone_sign(dns_zone_t *zone) { /* * Everything has succeeded. Commit the changes. */ - dns_db_closeversion(db, &version, ISC_TRUE); + dns_db_closeversion(db, &version, commit); /* * Everything succeeded so we can clean these up now. @@ -5856,9 +5923,11 @@ zone_sign(dns_zone_t *zone) { set_resigntime(zone); - LOCK_ZONE(zone); - zone_needdump(zone, DNS_DUMP_DELAY); - UNLOCK_ZONE(zone); + if (commit) { + LOCK_ZONE(zone); + zone_needdump(zone, DNS_DUMP_DELAY); + UNLOCK_ZONE(zone); + } failure: /* @@ -6498,6 +6567,7 @@ notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { isc_sockaddr_t any; isc_boolean_t isself; isc_netaddr_t dstaddr; + isc_result_t result; if (zone->view == NULL || zone->isself == NULL) return (ISC_FALSE); @@ -6523,7 +6593,9 @@ notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { src = *dst; isc_netaddr_fromsockaddr(&dstaddr, dst); - (void)dns_view_getpeertsig(zone->view, &dstaddr, &key); + result = dns_view_getpeertsig(zone->view, &dstaddr, &key); + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) + return (ISC_FALSE); isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, zone->isselfarg); if (key != NULL) @@ -6725,9 +6797,14 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { goto cleanup; isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); - (void)dns_view_getpeertsig(notify->zone->view, &dstip, &key); - isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); + result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { + notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not " + "sent. Peer TSIG key lookup failure.", addrbuf); + goto cleanup_message; + } + notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s", addrbuf); if (notify->zone->view->peers != NULL) { @@ -6774,6 +6851,7 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { cleanup_key: if (key != NULL) dns_tsigkey_detach(&key); + cleanup_message: dns_message_destroy(&message); cleanup: UNLOCK_ZONE(notify->zone); @@ -7386,7 +7464,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_soa_t soa; isc_result_t result; - isc_uint32_t serial; + isc_uint32_t serial, oldserial; unsigned int j; zone = revent->ev_arg; @@ -7609,12 +7687,17 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { RUNTIME_CHECK(result == ISC_R_SUCCESS); serial = soa.serial; - - zone_debuglog(zone, me, 1, "serial: new %u, old %u", - serial, zone->serial); + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { + result = dns_zone_getserial2(zone, &oldserial); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + zone_debuglog(zone, me, 1, "serial: new %u, old %u", + serial, oldserial); + } else + zone_debuglog(zone, me, 1, "serial: new %u, old not loaded", + serial); if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || - isc_serial_gt(serial, zone->serial)) { + isc_serial_gt(serial, oldserial)) { if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, &zone->sourceaddr, &now)) { dns_zone_log(zone, ISC_LOG_INFO, @@ -7638,7 +7721,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { } if (msg != NULL) dns_message_destroy(&msg); - } else if (isc_serial_eq(soa.serial, zone->serial)) { + } else if (isc_serial_eq(soa.serial, oldserial)) { if (zone->masterfile != NULL) { result = ISC_R_FAILURE; if (zone->journal != NULL) @@ -7671,7 +7754,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) " "received from master %s < ours (%u)", - soa.serial, master, zone->serial); + soa.serial, master, oldserial); else zone_debuglog(zone, me, 1, "ahead"); zone->mastersok[zone->curmaster] = ISC_TRUE; @@ -7965,10 +8048,19 @@ soa_query(isc_task_t *task, isc_event_t *event) { dns_name_format(keyname, namebuf, sizeof(namebuf)); dns_zone_log(zone, ISC_LOG_ERROR, "unable to find key: %s", namebuf); + goto skip_master; + } + } + if (key == NULL) { + result = dns_view_getpeertsig(zone->view, &masterip, &key); + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { + char addrbuf[ISC_NETADDR_FORMATSIZE]; + isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf)); + dns_zone_log(zone, ISC_LOG_ERROR, + "unable to find TSIG key for %s", addrbuf); + goto skip_master; } } - if (key == NULL) - (void)dns_view_getpeertsig(zone->view, &masterip, &key); have_xfrsource = ISC_FALSE; reqnsid = zone->view->requestnsid; @@ -8789,13 +8881,21 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, if (result == ISC_R_SUCCESS) result = dns_rdataset_first(rdataset); if (result == ISC_R_SUCCESS) { - isc_uint32_t serial = 0; + isc_uint32_t serial = 0, oldserial; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &soa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); serial = soa.serial; - if (isc_serial_le(serial, zone->serial)) { + /* + * The following should safely be performed without DB + * lock and succeed in this context. + */ + result = zone_get_from_db(zone, zone->db, NULL, NULL, + &oldserial, NULL, NULL, NULL, + NULL, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + if (isc_serial_le(serial, oldserial)) { dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: " "zone is up to date", @@ -9473,7 +9573,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { if (zone->db != NULL && zone->journal != NULL && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { - isc_uint32_t serial; + isc_uint32_t serial, oldserial; dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); @@ -9488,11 +9588,15 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { /* * This is checked in zone_postload() for master zones. */ + result = zone_get_from_db(zone, zone->db, NULL, NULL, + &oldserial, NULL, NULL, NULL, NULL, + NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (zone->type == dns_zone_slave && - !isc_serial_gt(serial, zone->serial)) { + !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; - serialmin = (zone->serial + 1) & 0xffffffffU; - serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU; + serialmin = (oldserial + 1) & 0xffffffffU; + serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; dns_zone_log(zone, ISC_LOG_ERROR, "ixfr-from-differences: failed: " "new serial (%u) out of range [%u - %u]", @@ -9685,7 +9789,6 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { zone_unload(zone); goto next_master; } - zone->serial = serial; zone->refresh = RANGE(refresh, zone->minrefresh, zone->maxrefresh); zone->retry = RANGE(retry, zone->minretry, @@ -9723,7 +9826,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { buf[0] = '\0'; dns_zone_log(zone, ISC_LOG_INFO, "transferred serial %u%s", - zone->serial, buf); + serial, buf); } /* @@ -9873,6 +9976,13 @@ zone_loaddone(void *arg, isc_result_t result) { (void)zone_postload(load->zone, load->db, load->loadtime, result); zonemgr_putio(&load->zone->readio); DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING); + /* + * Leave the zone frozen if the reload fails. + */ + if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && + DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW)) + zone->update_disabled = ISC_FALSE; + DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW); UNLOCK_ZONE(load->zone); load->magic = 0; @@ -11508,7 +11618,8 @@ zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, cleanup: if (signing != NULL) { - dns_db_detach(&signing->db); + if (signing->db != NULL) + dns_db_detach(&signing->db); if (signing->dbiterator != NULL) dns_dbiterator_destroy(&signing->dbiterator); isc_mem_put(zone->mctx, signing, sizeof *signing); diff --git a/contrib/bind9/lib/isc/api b/contrib/bind9/lib/isc/api index 5ef8dc035a3..e55996b2690 100644 --- a/contrib/bind9/lib/isc/api +++ b/contrib/bind9/lib/isc/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 51 +LIBINTERFACE = 52 LIBREVISION = 1 -LIBAGE = 1 +LIBAGE = 2 diff --git a/contrib/bind9/lib/isc/base32.c b/contrib/bind9/lib/isc/base32.c index 3000a84f2da..d324da9760a 100644 --- a/contrib/bind9/lib/isc/base32.c +++ b/contrib/bind9/lib/isc/base32.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: base32.c,v 1.3.116.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: base32.c,v 1.3.116.3 2009/10/21 01:22:47 each Exp $ */ /*! \file */ @@ -112,6 +112,8 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, RETERR(str_totext(wordbreak, target)); } } + if (source->length > 0) + isc_region_consume(source, source->length); return (ISC_R_SUCCESS); } diff --git a/contrib/bind9/lib/isc/base64.c b/contrib/bind9/lib/isc/base64.c index 13ed6b5c5c1..4844a4bf75b 100644 --- a/contrib/bind9/lib/isc/base64.c +++ b/contrib/bind9/lib/isc/base64.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: base64.c,v 1.32 2007/06/19 23:47:17 tbox Exp $ */ +/* $Id: base64.c,v 1.32.332.2 2009/10/21 23:47:20 tbox Exp $ */ /*! \file */ @@ -85,11 +85,13 @@ isc_base64_totext(isc_region_t *source, int wordlength, buf[2] = base64[((source->base[1]<<2)&0x3c)]; buf[3] = '='; RETERR(str_totext(buf, target)); + isc_region_consume(source, 2); } else if (source->length == 1) { buf[0] = base64[(source->base[0]>>2)&0x3f]; buf[1] = base64[((source->base[0]<<4)&0x30)]; buf[2] = buf[3] = '='; RETERR(str_totext(buf, target)); + isc_region_consume(source, 1); } return (ISC_R_SUCCESS); } @@ -217,7 +219,7 @@ isc_base64_decodestring(const char *cstr, isc_buffer_t *target) { continue; RETERR(base64_decode_char(&ctx, c)); } - RETERR(base64_decode_finish(&ctx)); + RETERR(base64_decode_finish(&ctx)); return (ISC_R_SUCCESS); } diff --git a/contrib/bind9/lib/isc/heap.c b/contrib/bind9/lib/isc/heap.c index 91d78c06d46..dc32100d2f1 100644 --- a/contrib/bind9/lib/isc/heap.c +++ b/contrib/bind9/lib/isc/heap.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: heap.c,v 1.37 2007/10/19 17:15:53 explorer Exp $ */ +/* $Id: heap.c,v 1.37.240.3 2010/02/04 23:47:46 tbox Exp $ */ /*! \file * Heap implementation of priority queues adapted from the following: @@ -186,15 +186,17 @@ sink_down(isc_heap_t *heap, unsigned int i, void *elt) { isc_result_t isc_heap_insert(isc_heap_t *heap, void *elt) { - unsigned int i; + unsigned int new_last; REQUIRE(VALID_HEAP(heap)); - i = ++heap->last; - if (heap->last >= heap->size && !resize(heap)) + new_last = heap->last + 1; + RUNTIME_CHECK(new_last > 0); /* overflow check */ + if (new_last >= heap->size && !resize(heap)) return (ISC_R_NOMEMORY); + heap->last = new_last; - float_up(heap, i, elt); + float_up(heap, new_last, elt); return (ISC_R_SUCCESS); } diff --git a/contrib/bind9/lib/isc/httpd.c b/contrib/bind9/lib/isc/httpd.c index fa313253b3e..066939d1f41 100644 --- a/contrib/bind9/lib/isc/httpd.c +++ b/contrib/bind9/lib/isc/httpd.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2006-2008, 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: httpd.c,v 1.16 2008/08/08 05:06:49 marka Exp $ */ +/* $Id: httpd.c,v 1.16.64.2 2010/02/04 23:47:46 tbox Exp $ */ /*! \file */ @@ -151,6 +151,7 @@ struct isc_httpdmgr { ISC_LIST(isc_httpdurl_t) urls; /*%< urls we manage */ isc_httpdaction_t *render_404; + isc_httpdaction_t *render_500; }; /*% @@ -221,6 +222,11 @@ static isc_result_t render_404(const char *, const char *, unsigned int *, const char **, const char **, isc_buffer_t *, isc_httpdfree_t **, void **); +static isc_result_t render_500(const char *, const char *, + void *, + unsigned int *, const char **, + const char **, isc_buffer_t *, + isc_httpdfree_t **, void **); static void destroy_client(isc_httpd_t **httpdp) @@ -300,6 +306,7 @@ isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task, goto cleanup; httpd->render_404 = render_404; + httpd->render_500 = render_500; *httpdp = httpd; return (ISC_R_SUCCESS); @@ -623,6 +630,30 @@ render_404(const char *url, const char *querystring, return (ISC_R_SUCCESS); } +static isc_result_t +render_500(const char *url, const char *querystring, + void *arg, + unsigned int *retcode, const char **retmsg, + const char **mimetype, isc_buffer_t *b, + isc_httpdfree_t **freecb, void **freecb_args) +{ + static char msg[] = "Internal server failure."; + + UNUSED(url); + UNUSED(querystring); + UNUSED(arg); + + *retcode = 500; + *retmsg = "Internal server failure"; + *mimetype = "text/plain"; + isc_buffer_reinit(b, msg, strlen(msg)); + isc_buffer_add(b, strlen(msg)); + *freecb = NULL; + *freecb_args = NULL; + + return (ISC_R_SUCCESS); +} + static void isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) { @@ -691,8 +722,14 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) &httpd->mimetype, &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); if (result != ISC_R_SUCCESS) { - destroy_client(&httpd); - goto out; + result = httpd->mgr->render_500(httpd->url, httpd->querystring, + NULL, + &httpd->retcode, + &httpd->retmsg, + &httpd->mimetype, + &httpd->bodybuffer, + &httpd->freecb, + &httpd->freecb_arg); } isc_httpd_response(httpd); diff --git a/contrib/bind9/lib/isc/ia64/include/isc/atomic.h b/contrib/bind9/lib/isc/ia64/include/isc/atomic.h index 0fac76f3be2..5d7c366965d 100644 --- a/contrib/bind9/lib/isc/ia64/include/isc/atomic.h +++ b/contrib/bind9/lib/isc/ia64/include/isc/atomic.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: atomic.h,v 1.4.326.2 2009/02/06 23:47:11 tbox Exp $ */ +/* $Id: atomic.h,v 1.4.326.3 2009/06/24 02:21:28 marka Exp $ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 diff --git a/contrib/bind9/lib/isc/include/isc/entropy.h b/contrib/bind9/lib/isc/include/isc/entropy.h index e9e59c49514..125669ca856 100644 --- a/contrib/bind9/lib/isc/include/isc/entropy.h +++ b/contrib/bind9/lib/isc/include/isc/entropy.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: entropy.h,v 1.32.332.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: entropy.h,v 1.32.332.3 2009/10/19 02:46:07 marka Exp $ */ #ifndef ISC_ENTROPY_H #define ISC_ENTROPY_H 1 @@ -182,8 +182,8 @@ isc_result_t isc_entropy_createsamplesource(isc_entropy_t *ent, isc_entropysource_t **sourcep); /*!< - * \brief Create an entropy source that consists of samples. Each sample is added - * to the source via isc_entropy_addsamples(), below. + * \brief Create an entropy source that consists of samples. Each sample is + * added to the source via isc_entropy_addsamples(), below. */ isc_result_t @@ -254,11 +254,11 @@ void isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length, isc_uint32_t entropy); /*!< - * \brief Add "length" bytes in "data" to the entropy pool, incrementing the pool's - * entropy count by "entropy." + * \brief Add "length" bytes in "data" to the entropy pool, incrementing the + * pool's entropy count by "entropy." * - * These bytes will prime the pseudorandom portion even no entropy is actually - * added. + * These bytes will prime the pseudorandom portion even if no entropy is + * actually added. */ void diff --git a/contrib/bind9/lib/isc/include/isc/netscope.h b/contrib/bind9/lib/isc/include/isc/netscope.h index ba4e792a40a..0883140acdb 100644 --- a/contrib/bind9/lib/isc/include/isc/netscope.h +++ b/contrib/bind9/lib/isc/include/isc/netscope.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: netscope.h,v 1.11 2007/06/19 23:47:18 tbox Exp $ */ +/* $Id: netscope.h,v 1.11.332.2 2009/06/25 23:47:24 tbox Exp $ */ #ifndef ISC_NETSCOPE_H #define ISC_NETSCOPE_H 1 @@ -40,4 +40,4 @@ isc_netscope_pton(int af, char *scopename, void *addr, isc_uint32_t *zoneid); ISC_LANG_ENDDECLS -#endif /* ISC_NETADDR_H */ +#endif /* ISC_NETSCOPE_H */ diff --git a/contrib/bind9/lib/isc/include/isc/portset.h b/contrib/bind9/lib/isc/include/isc/portset.h index dc1f85616ea..a7ad3d69532 100644 --- a/contrib/bind9/lib/isc/include/isc/portset.h +++ b/contrib/bind9/lib/isc/include/isc/portset.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: portset.h,v 1.3.90.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: portset.h,v 1.3.90.3 2009/06/25 05:31:51 marka Exp $ */ /*! \file isc/portset.h * \brief Transport Protocol Port Manipulation Module @@ -138,4 +138,4 @@ isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo, ISC_LANG_ENDDECLS -#endif /* ISC_NETADDR_H */ +#endif /* ISC_PORTSET_H */ diff --git a/contrib/bind9/lib/isc/include/isc/sha2.h b/contrib/bind9/lib/isc/include/isc/sha2.h index 211e25505a9..edafa611bc2 100644 --- a/contrib/bind9/lib/isc/include/isc/sha2.h +++ b/contrib/bind9/lib/isc/include/isc/sha2.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2005-2007, 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sha2.h,v 1.9 2007/06/19 23:47:18 tbox Exp $ */ +/* $Id: sha2.h,v 1.9.332.2 2010/01/15 23:47:34 tbox Exp $ */ /* $FreeBSD$ */ /* $KAME: sha2.h,v 1.3 2001/03/12 08:27:48 itojun Exp $ */ @@ -39,7 +39,7 @@ * 3. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -104,24 +104,28 @@ typedef isc_sha512_t isc_sha384_t; /*** SHA-224/256/384/512 Function Prototypes ******************************/ void isc_sha224_init (isc_sha224_t *); +void isc_sha224_invalidate (isc_sha224_t *); void isc_sha224_update (isc_sha224_t *, const isc_uint8_t *, size_t); void isc_sha224_final (isc_uint8_t[ISC_SHA224_DIGESTLENGTH], isc_sha224_t *); char *isc_sha224_end (isc_sha224_t *, char[ISC_SHA224_DIGESTSTRINGLENGTH]); char *isc_sha224_data (const isc_uint8_t *, size_t, char[ISC_SHA224_DIGESTSTRINGLENGTH]); void isc_sha256_init (isc_sha256_t *); +void isc_sha256_invalidate (isc_sha256_t *); void isc_sha256_update (isc_sha256_t *, const isc_uint8_t *, size_t); void isc_sha256_final (isc_uint8_t[ISC_SHA256_DIGESTLENGTH], isc_sha256_t *); char *isc_sha256_end (isc_sha256_t *, char[ISC_SHA256_DIGESTSTRINGLENGTH]); char *isc_sha256_data (const isc_uint8_t *, size_t, char[ISC_SHA256_DIGESTSTRINGLENGTH]); void isc_sha384_init (isc_sha384_t *); +void isc_sha384_invalidate (isc_sha384_t *); void isc_sha384_update (isc_sha384_t *, const isc_uint8_t *, size_t); void isc_sha384_final (isc_uint8_t[ISC_SHA384_DIGESTLENGTH], isc_sha384_t *); char *isc_sha384_end (isc_sha384_t *, char[ISC_SHA384_DIGESTSTRINGLENGTH]); char *isc_sha384_data (const isc_uint8_t *, size_t, char[ISC_SHA384_DIGESTSTRINGLENGTH]); void isc_sha512_init (isc_sha512_t *); +void isc_sha512_invalidate (isc_sha512_t *); void isc_sha512_update (isc_sha512_t *, const isc_uint8_t *, size_t); void isc_sha512_final (isc_uint8_t[ISC_SHA512_DIGESTLENGTH], isc_sha512_t *); char *isc_sha512_end (isc_sha512_t *, char[ISC_SHA512_DIGESTSTRINGLENGTH]); diff --git a/contrib/bind9/lib/isc/include/isc/util.h b/contrib/bind9/lib/isc/include/isc/util.h index 8a3b95d9da3..85846b6e807 100644 --- a/contrib/bind9/lib/isc/include/isc/util.h +++ b/contrib/bind9/lib/isc/include/isc/util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: util.h,v 1.30 2007/06/19 23:47:18 tbox Exp $ */ +/* $Id: util.h,v 1.30.332.2 2010/01/11 23:47:22 tbox Exp $ */ #ifndef ISC_UTIL_H #define ISC_UTIL_H 1 @@ -230,4 +230,14 @@ */ #define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS) +/*% + * Prevent Linux spurious warnings + */ +#if defined(__GNUC__) && (__GNUC__ > 3) +#define isc_util_fwrite(a, b, c, d) \ + __builtin_expect(fwrite((a), (b), (c), (d)), (c)) +#else +#define isc_util_fwrite(a, b, c, d) fwrite((a), (b), (c), (d)) +#endif + #endif /* ISC_UTIL_H */ diff --git a/contrib/bind9/lib/isc/inet_ntop.c b/contrib/bind9/lib/isc/inet_ntop.c index dc053ededfb..c37be5c0b5b 100644 --- a/contrib/bind9/lib/isc/inet_ntop.c +++ b/contrib/bind9/lib/isc/inet_ntop.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -19,7 +19,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static char rcsid[] = - "$Id: inet_ntop.c,v 1.19 2007/06/19 23:47:17 tbox Exp $"; + "$Id: inet_ntop.c,v 1.19.332.2 2009/07/18 23:47:25 tbox Exp $"; #endif /* LIBC_SCCS and not lint */ #include @@ -52,7 +52,7 @@ static const char *inet_ntop6(const unsigned char *src, char *dst, * convert a network format address to presentation format. * \return * pointer to presentation format address (`dst'), or NULL (see errno). - * \author + * \author * Paul Vixie, 1996. */ const char * @@ -169,8 +169,9 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (i == 6 && best.base == 0 && (best.len == 6 || + (best.len == 7 && words[7] != 0x0001) || + (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) return (NULL); diff --git a/contrib/bind9/lib/isc/powerpc/include/isc/atomic.h b/contrib/bind9/lib/isc/powerpc/include/isc/atomic.h index 765cb6d72a8..2114767b361 100644 --- a/contrib/bind9/lib/isc/powerpc/include/isc/atomic.h +++ b/contrib/bind9/lib/isc/powerpc/include/isc/atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: atomic.h,v 1.6 2007/06/18 23:47:47 tbox Exp $ */ +/* $Id: atomic.h,v 1.6.332.2 2009/10/14 23:47:14 tbox Exp $ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 @@ -46,25 +46,56 @@ #include -#define isc_atomic_xadd(p, v) fetch_and_add(p, v) #define isc_atomic_store(p, v) _clear_lock(p, v) +#ifdef __GNUC__ +static inline isc_int32_t +#else +static isc_int32_t +#endif +isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { + int ret; + +#ifdef __GNUC__ + asm("ics"); +#else + __isync(); +#endif + + ret = fetch_and_add((atomic_p)p, (int)val); + +#ifdef __GNUC__ + asm("ics"); +#else + __isync(); +#endif + + return (ret); +} + #ifdef __GNUC__ static inline int #else static int #endif isc_atomic_cmpxchg(atomic_p p, int old, int new) { - int orig = old; + int orig = old; #ifdef __GNUC__ - asm("ics"); + asm("ics"); #else - __isync(); + __isync(); #endif - if (compare_and_swap(p, &orig, new)) - return (old); - return (orig); + if (compare_and_swap(p, &orig, new)) + orig = old; + +#ifdef __GNUC__ + asm("ics"); +#else + __isync(); +#endif + + return (orig); } #elif defined(ISC_PLATFORM_USEGCCASM) || defined(ISC_PLATFORM_USEMACASM) @@ -76,14 +107,14 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { #ifdef ISC_PLATFORM_USEMACASM "1:" "lwarx r6, 0, %1\n" - "mr %0, r6\n" + "mr %0, r6\n" "add r6, r6, %2\n" "stwcx. r6, 0, %1\n" "bne- 1b" #else "1:" "lwarx 6, 0, %1\n" - "mr %0, 6\n" + "mr %0, 6\n" "add 6, 6, %2\n" "stwcx. 6, 0, %1\n" "bne- 1b" diff --git a/contrib/bind9/lib/isc/random.c b/contrib/bind9/lib/isc/random.c index 0329abde72b..84ba6a0daab 100644 --- a/contrib/bind9/lib/isc/random.c +++ b/contrib/bind9/lib/isc/random.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: random.c,v 1.25 2007/06/19 23:47:17 tbox Exp $ */ +/* $Id: random.c,v 1.25.332.2 2009/07/16 23:47:17 tbox Exp $ */ /*! \file */ @@ -43,7 +43,7 @@ initialize_rand(void) { #ifndef HAVE_ARC4RANDOM unsigned int pid = getpid(); - + /* * The low bits of pid generally change faster. * Xor them with the high bits of time which change slowly. @@ -84,7 +84,16 @@ isc_random_get(isc_uint32_t *val) * rand()'s lower bits are not random. * rand()'s upper bit is zero. */ +#if RAND_MAX >= 0xfffff + /* We have at least 20 bits. Use lower 16 excluding lower most 4 */ *val = ((rand() >> 4) & 0xffff) | ((rand() << 12) & 0xffff0000); +#elif RAND_MAX >= 0x7fff + /* We have at least 15 bits. Use lower 10/11 excluding lower most 4 */ + *val = ((rand() >> 4) & 0x000007ff) | ((rand() << 7) & 0x003ff800) | + ((rand() << 18) & 0xffc00000); +#else +#error RAND_MAX is too small +#endif #else *val = arc4random(); #endif @@ -92,13 +101,13 @@ isc_random_get(isc_uint32_t *val) isc_uint32_t isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter) { + isc_uint32_t rnd; + REQUIRE(jitter < max); + if (jitter == 0) return (max); - else -#ifndef HAVE_ARC4RANDOM - return (max - rand() % jitter); -#else - return (max - arc4random() % jitter); -#endif + + isc_random_get(&rnd); + return (max - rnd % jitter); } diff --git a/contrib/bind9/lib/isc/sha2.c b/contrib/bind9/lib/isc/sha2.c index 70eea4f9670..ff19274837a 100644 --- a/contrib/bind9/lib/isc/sha2.c +++ b/contrib/bind9/lib/isc/sha2.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2005-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sha2.c,v 1.13.332.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: sha2.c,v 1.13.332.4 2010/01/15 23:47:34 tbox Exp $ */ /* $FreeBSD$ */ /* $KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $ */ @@ -414,6 +414,11 @@ isc_sha224_init(isc_sha224_t *context) { context->bitcount = 0; } +void +isc_sha224_invalidate(isc_sha224_t *context) { + memset(context, 0, sizeof(isc_sha224_t)); +} + void isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) { isc_sha256_update((isc_sha256_t *)context, data, len); @@ -650,6 +655,11 @@ isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) { #endif /* ISC_SHA2_UNROLL_TRANSFORM */ +void +isc_sha256_invalidate(isc_sha256_t *context) { + memset(context, 0, sizeof(isc_sha256_t)); +} + void isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) { unsigned int freespace, usedspace; @@ -990,7 +1000,13 @@ isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) { #endif /* ISC_SHA2_UNROLL_TRANSFORM */ -void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) { +void +isc_sha512_invalidate(isc_sha512_t *context) { + memset(context, 0, sizeof(isc_sha512_t)); +} + +void +isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) { unsigned int freespace, usedspace; if (len == 0U) { @@ -1163,6 +1179,11 @@ isc_sha384_init(isc_sha384_t *context) { context->bitcount[0] = context->bitcount[1] = 0; } +void +isc_sha384_invalidate(isc_sha384_t *context) { + memset(context, 0, sizeof(isc_sha384_t)); +} + void isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) { isc_sha512_update((isc_sha512_t *)context, data, len); diff --git a/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c b/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c index b576d4632fb..87ef9ba7f50 100644 --- a/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c +++ b/contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ifiter_getifaddrs.c,v 1.11 2008/03/20 23:47:00 tbox Exp $ */ +/* $Id: ifiter_getifaddrs.c,v 1.11.120.2 2009/09/24 23:47:34 tbox Exp $ */ /*! \file * \brief @@ -181,7 +181,7 @@ internal_current(isc_interfaceiter_t *iter) { ifa->ifa_name); if (ifa->ifa_dstaddr != NULL && - (iter->current.flags & IFF_POINTOPOINT) != 0) + (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) get_addr(family, &iter->current.dstaddress, ifa->ifa_dstaddr, ifa->ifa_name); diff --git a/contrib/bind9/lib/isc/unix/socket.c b/contrib/bind9/lib/isc/unix/socket.c index d09fe51ab57..004a038a3a8 100644 --- a/contrib/bind9/lib/isc/unix/socket.c +++ b/contrib/bind9/lib/isc/unix/socket.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.308.12.8 2009/04/18 01:29:26 jinmei Exp $ */ +/* $Id: socket.c,v 1.308.12.12 2010/01/31 23:47:31 tbox Exp $ */ /*! \file */ @@ -1520,12 +1520,22 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) { } /* - * On TCP, zero length reads indicate EOF, while on - * UDP, zero length reads are perfectly valid, although - * strange. + * On TCP and UNIX sockets, zero length reads indicate EOF, + * while on UDP sockets, zero length reads are perfectly valid, + * although strange. */ - if ((sock->type == isc_sockettype_tcp) && (cc == 0)) - return (DOIO_EOF); + switch (sock->type) { + case isc_sockettype_tcp: + case isc_sockettype_unix: + if (cc == 0) + return (DOIO_EOF); + break; + case isc_sockettype_udp: + break; + case isc_sockettype_fdwatch: + default: + INSIST(0); + } if (sock->type == isc_sockettype_udp) { dev->address.length = msghdr.msg_namelen; @@ -3645,7 +3655,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) { manager->maxsocks); if (manager->fdpollinfo == NULL) { isc_mem_put(mctx, manager->events, - sizeof(pollinfo_t) * manager->maxsocks); + sizeof(struct pollfd) * manager->nevents); return (ISC_R_NOMEMORY); } memset(manager->fdpollinfo, 0, sizeof(pollinfo_t) * manager->maxsocks); @@ -4851,6 +4861,7 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_socketmgr_t *manager; int cc; char strbuf[ISC_STRERRORSIZE]; + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; REQUIRE(VALID_SOCKET(sock)); REQUIRE(addr != NULL); @@ -4919,7 +4930,9 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, sock->connected = 0; isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, "%d/%s", errno, strbuf); + isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, "connect(%s) %d/%s", + addrbuf, errno, strbuf); UNLOCK(&sock->lock); inc_stats(sock->manager->stats, diff --git a/contrib/bind9/lib/isccc/api b/contrib/bind9/lib/isccc/api index 8459d4239fc..2240cdda3ac 100644 --- a/contrib/bind9/lib/isccc/api +++ b/contrib/bind9/lib/isccc/api @@ -1,3 +1,3 @@ LIBINTERFACE = 50 -LIBREVISION = 0 +LIBREVISION = 1 LIBAGE = 0 diff --git a/contrib/bind9/lib/isccfg/aclconf.c b/contrib/bind9/lib/isccfg/aclconf.c index ad3d58e2c14..92839e4d77f 100644 --- a/contrib/bind9/lib/isccfg/aclconf.c +++ b/contrib/bind9/lib/isccfg/aclconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: aclconf.c,v 1.22.34.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id: aclconf.c,v 1.22.34.4 2009/10/01 23:47:17 tbox Exp $ */ #include @@ -168,26 +168,36 @@ convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx, * parent. */ static int -count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx) +count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx, + isc_boolean_t *has_negative) { const cfg_listelt_t *elt; const cfg_obj_t *cacl = NULL; isc_result_t result; int n = 0; + if (has_negative != NULL) + *has_negative = ISC_FALSE; + for (elt = cfg_list_first(caml); elt != NULL; elt = cfg_list_next(elt)) { const cfg_obj_t *ce = cfg_listelt_value(elt); /* negated element; just get the value. */ - if (cfg_obj_istuple(ce)) + if (cfg_obj_istuple(ce)) { ce = cfg_tuple_get(ce, "value"); + if (has_negative != NULL) + *has_negative = ISC_TRUE; + } if (cfg_obj_istype(ce, &cfg_type_keyref)) { n++; } else if (cfg_obj_islist(ce)) { - n += count_acl_elements(ce, cctx); + isc_boolean_t negative; + n += count_acl_elements(ce, cctx, &negative); + if (negative) + n++; } else if (cfg_obj_isstring(ce)) { const char *name = cfg_obj_asstring(ce); if (strcasecmp(name, "localhost") == 0 || @@ -197,7 +207,8 @@ count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx) strcasecmp(name, "none") != 0) { result = get_acl_def(cctx, name, &cacl); if (result == ISC_R_SUCCESS) - n += count_acl_elements(cacl, cctx) + 1; + n += count_acl_elements(cacl, cctx, + NULL) + 1; } } } @@ -246,7 +257,7 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, int nelem; if (nest_level == 0) - nelem = count_acl_elements(caml, cctx); + nelem = count_acl_elements(caml, cctx, NULL); else nelem = cfg_list_length(caml, ISC_FALSE); diff --git a/contrib/bind9/lib/isccfg/api b/contrib/bind9/lib/isccfg/api index 8459d4239fc..2240cdda3ac 100644 --- a/contrib/bind9/lib/isccfg/api +++ b/contrib/bind9/lib/isccfg/api @@ -1,3 +1,3 @@ LIBINTERFACE = 50 -LIBREVISION = 0 +LIBREVISION = 1 LIBAGE = 0 diff --git a/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h b/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h index 9689a2ae7bd..55c5a81813a 100644 --- a/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h +++ b/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.h,v 1.9 2007/06/19 23:47:22 tbox Exp $ */ +/* $Id: namedconf.h,v 1.9.332.2 2009/06/25 23:47:28 tbox Exp $ */ #ifndef ISCCFG_NAMEDCONF_H #define ISCCFG_NAMEDCONF_H 1 @@ -42,4 +42,4 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndckey; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref; /*%< A key reference, used as an ACL element */ -#endif /* ISCCFG_CFG_H */ +#endif /* ISCCFG_NAMEDCONF_H */ diff --git a/contrib/bind9/lib/lwres/api b/contrib/bind9/lib/lwres/api index 39934b4fbd2..fbbf923b532 100644 --- a/contrib/bind9/lib/lwres/api +++ b/contrib/bind9/lib/lwres/api @@ -1,3 +1,3 @@ LIBINTERFACE = 50 -LIBREVISION = 2 +LIBREVISION = 3 LIBAGE = 0 diff --git a/contrib/bind9/lib/lwres/context.c b/contrib/bind9/lib/lwres/context.c index 464a2cf9f2d..d042c87271d 100644 --- a/contrib/bind9/lib/lwres/context.c +++ b/contrib/bind9/lib/lwres/context.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: context.c,v 1.50.332.2 2008/12/30 23:46:49 tbox Exp $ */ +/* $Id: context.c,v 1.50.332.5 2009/09/01 23:47:05 tbox Exp $ */ /*! \file context.c lwres_context_create() creates a #lwres_context_t structure for use in @@ -471,6 +471,17 @@ lwres_context_sendrecv(lwres_context_t *ctx, result = lwres_context_send(ctx, sendbase, sendlen); if (result != LWRES_R_SUCCESS) return (result); + + /* + * If this is not checked, select() can overflow, + * causing corruption elsewhere. + */ + if (ctx->sock >= (int)FD_SETSIZE) { + close(ctx->sock); + ctx->sock = -1; + return (LWRES_R_IOERROR); + } + again: FD_ZERO(&readfds); FD_SET(ctx->sock, &readfds); diff --git a/contrib/bind9/lib/lwres/getipnode.c b/contrib/bind9/lib/lwres/getipnode.c index a6c50c28b80..4331638bcf0 100644 --- a/contrib/bind9/lib/lwres/getipnode.c +++ b/contrib/bind9/lib/lwres/getipnode.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: getipnode.c,v 1.42 2007/06/18 23:47:51 tbox Exp $ */ +/* $Id: getipnode.c,v 1.42.332.5 2009/09/01 23:47:05 tbox Exp $ */ /*! \file */ @@ -23,7 +23,7 @@ * These functions perform thread safe, protocol independent * nodename-to-address and address-to-nodename translation as defined in * RFC2553. This use a struct hostent which is defined in namedb.h: - * + * * \code * struct hostent { * char *h_name; // official name of host @@ -34,90 +34,90 @@ * }; * #define h_addr h_addr_list[0] // address, for backward compatibility * \endcode - * + * * The members of this structure are: - * + * * \li h_name: * The official (canonical) name of the host. - * + * * \li h_aliases: * A NULL-terminated array of alternate names (nicknames) for the * host. - * + * * \li h_addrtype: * The type of address being returned - usually PF_INET or * PF_INET6. - * + * * \li h_length: * The length of the address in bytes. - * + * * \li h_addr_list: * A NULL terminated array of network addresses for the host. Host * addresses are returned in network byte order. - * + * * lwres_getipnodebyname() looks up addresses of protocol family af for * the hostname name. The flags parameter contains ORed flag bits to * specify the types of addresses that are searched for, and the types of * addresses that are returned. The flag bits are: - * + * * \li #AI_V4MAPPED: * This is used with an af of #AF_INET6, and causes IPv4 addresses * to be returned as IPv4-mapped IPv6 addresses. - * + * * \li #AI_ALL: * This is used with an af of #AF_INET6, and causes all known * addresses (IPv6 and IPv4) to be returned. If #AI_V4MAPPED is * also set, the IPv4 addresses are return as mapped IPv6 * addresses. - * + * * \li #AI_ADDRCONFIG: * Only return an IPv6 or IPv4 address if here is an active * network interface of that type. This is not currently * implemented in the BIND 9 lightweight resolver, and the flag is * ignored. - * + * * \li #AI_DEFAULT: * This default sets the #AI_V4MAPPED and #AI_ADDRCONFIG flag bits. - * + * * lwres_getipnodebyaddr() performs a reverse lookup of address src which * is len bytes long. af denotes the protocol family, typically PF_INET * or PF_INET6. - * + * * lwres_freehostent() releases all the memory associated with the struct * hostent pointer. Any memory allocated for the h_name, h_addr_list * and h_aliases is freed, as is the memory for the hostent structure * itself. - * + * * \section getipnode_return Return Values - * + * * If an error occurs, lwres_getipnodebyname() and * lwres_getipnodebyaddr() set *error_num to an appropriate error code * and the function returns a NULL pointer. The error codes and their * meanings are defined in \link netdb.h \endlink: - * + * * \li #HOST_NOT_FOUND: * No such host is known. - * + * * \li #NO_ADDRESS: * The server recognised the request and the name but no address * is available. Another type of request to the name server for * the domain might return an answer. - * + * * \li #TRY_AGAIN: * A temporary and possibly transient error occurred, such as a * failure of a server to respond. The request may succeed if * retried. - * + * * \li #NO_RECOVERY: * An unexpected failure occurred, and retrying the request is * pointless. - * + * * lwres_hstrerror() translates these error codes to suitable error * messages. - * + * * \section getipnode_see See Also - * - * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553 + * + * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553 */ #include @@ -146,21 +146,21 @@ LIBLWRES_EXTERNAL_DATA const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; #ifndef IN6_IS_ADDR_V4COMPAT static const unsigned char in6addr_compat[12] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \ - ((x)->s6_addr[12] != 0 || \ - (x)->s6_addr[13] != 0 || \ - (x)->s6_addr[14] != 0 || \ - ((x)->s6_addr[15] != 0 && \ - (x)->s6_addr[15] != 1))) + ((x)->s6_addr[12] != 0 || \ + (x)->s6_addr[13] != 0 || \ + (x)->s6_addr[14] != 0 || \ + ((x)->s6_addr[15] != 0 && \ + (x)->s6_addr[15] != 1))) #endif #ifndef IN6_IS_ADDR_V4MAPPED #define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12)) #endif static const unsigned char in6addr_mapped[12] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; /*** @@ -202,7 +202,7 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { struct in6_addr in6; struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL; int v4 = 0, v6 = 0; - int tmp_err; + int tmp_err = 0; lwres_context_t *lwrctx = NULL; lwres_gabnresponse_t *by = NULL; int n; @@ -275,7 +275,6 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); tmp_err = NO_RECOVERY; if (have_v6 && af == AF_INET6) { - n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by); if (n == 0) { he1 = hostfromname(by, AF_INET6); @@ -285,7 +284,12 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { goto cleanup; } } else { - tmp_err = HOST_NOT_FOUND; + if (n == LWRES_R_NOTFOUND) + tmp_err = HOST_NOT_FOUND; + else { + *error_num = NO_RECOVERY; + goto cleanup; + } } } @@ -437,9 +441,15 @@ lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) { if (n != 0) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); - *error_num = HOST_NOT_FOUND; + + if (n == LWRES_R_NOTFOUND) + *error_num = HOST_NOT_FOUND; + else + *error_num = NO_RECOVERY; + return (NULL); } + he1 = hostfromaddr(by, AF_INET6, src); lwres_gnbaresponse_free(lwrctx, &by); if (he1 == NULL) @@ -492,7 +502,7 @@ lwres_freehostent(struct hostent *he) { */ #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \ - !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) + !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) #ifdef __hpux #define lifc_len iflc_len @@ -504,7 +514,7 @@ lwres_freehostent(struct hostent *he) { #define ISC_HAVE_LIFC_FLAGS 1 #define LIFCONF lifconf #endif - + #ifdef __hpux #define lifr_addr iflr_addr #define lifr_name iflr_name @@ -557,7 +567,7 @@ scan_interfaces6(int *have_v4, int *have_v6) { /* * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small - * to fit all the interfaces in. If + * to fit all the interfaces in. If * lifc.lifc_len is too near to the end of the * buffer we will grow it just in case and * retry. @@ -619,13 +629,13 @@ scan_interfaces6(int *have_v4, int *have_v6) { if ((lifreq.lifr_flags & IFF_UP) == 0) break; *have_v4 = 1; - } + } break; case AF_INET6: if (*have_v6 == 0) { memcpy(&in6, &((struct sockaddr_in6 *) - &lifreq.lifr_addr)->sin6_addr, + &lifreq.lifr_addr)->sin6_addr, sizeof(in6)); if (memcmp(&in6, &in6addr_any, sizeof(in6)) == 0) @@ -675,7 +685,7 @@ scan_interfaces(int *have_v4, int *have_v6) { InitSockets(); #endif #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \ - !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) + !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) /* * Try to scan the interfaces using IPv6 ioctls(). */ @@ -721,7 +731,7 @@ scan_interfaces(int *have_v4, int *have_v6) { /* * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small - * to fit all the interfaces in. If + * to fit all the interfaces in. If * ifc.ifc_len is too near to the end of the * buffer we will grow it just in case and * retry. @@ -786,7 +796,7 @@ scan_interfaces(int *have_v4, int *have_v6) { if ((u.ifreq.ifr_flags & IFF_UP) == 0) break; *have_v4 = 1; - } + } break; case AF_INET6: if (*have_v6 == 0) { diff --git a/contrib/bind9/lib/lwres/man/lwres.3 b/contrib/bind9/lib/lwres/man/lwres.3 index e1f87936f37..14c719adb37 100644 --- a/contrib/bind9/lib/lwres/man/lwres.3 +++ b/contrib/bind9/lib/lwres/man/lwres.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres.3,v 1.28 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres.html b/contrib/bind9/lib/lwres/man/lwres.html index 986918a8cf7..465b8765900 100644 --- a/contrib/bind9/lib/lwres/man/lwres.html +++ b/contrib/bind9/lib/lwres/man/lwres.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_buffer.3 b/contrib/bind9/lib/lwres/man/lwres_buffer.3 index cc0959d8908..e8fe6313aeb 100644 --- a/contrib/bind9/lib/lwres/man/lwres_buffer.3 +++ b/contrib/bind9/lib/lwres/man/lwres_buffer.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_buffer.3,v 1.26 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_buffer.3,v 1.26.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_buffer.html b/contrib/bind9/lib/lwres/man/lwres_buffer.html index 7ed5407c53a..80fd383e3b7 100644 --- a/contrib/bind9/lib/lwres/man/lwres_buffer.html +++ b/contrib/bind9/lib/lwres/man/lwres_buffer.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_config.3 b/contrib/bind9/lib/lwres/man/lwres_config.3 index 6184cb23827..2d3b8137e12 100644 --- a/contrib/bind9/lib/lwres/man/lwres_config.3 +++ b/contrib/bind9/lib/lwres/man/lwres_config.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_config.3,v 1.26 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_config.3,v 1.26.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_config.html b/contrib/bind9/lib/lwres/man/lwres_config.html index 050fd5de361..055ae911da7 100644 --- a/contrib/bind9/lib/lwres/man/lwres_config.html +++ b/contrib/bind9/lib/lwres/man/lwres_config.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_context.3 b/contrib/bind9/lib/lwres/man/lwres_context.3 index b1022d86099..dae7ee5313d 100644 --- a/contrib/bind9/lib/lwres/man/lwres_context.3 +++ b/contrib/bind9/lib/lwres/man/lwres_context.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_context.3,v 1.28 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_context.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_context.html b/contrib/bind9/lib/lwres/man/lwres_context.html index d6fada9b918..d86e508eea9 100644 --- a/contrib/bind9/lib/lwres/man/lwres_context.html +++ b/contrib/bind9/lib/lwres/man/lwres_context.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001, 2003 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_gabn.3 b/contrib/bind9/lib/lwres/man/lwres_gabn.3 index 0c143847559..64846d1846e 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gabn.3 +++ b/contrib/bind9/lib/lwres/man/lwres_gabn.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_gabn.3,v 1.27 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_gabn.3,v 1.27.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_gabn.html b/contrib/bind9/lib/lwres/man/lwres_gabn.html index efb152a381d..91734ddc634 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gabn.html +++ b/contrib/bind9/lib/lwres/man/lwres_gabn.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.3 b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.3 index e412b8f89d2..46b54c0f7d3 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.3 +++ b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_gai_strerror.3,v 1.27 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_gai_strerror.3,v 1.27.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html index aeb0967e3e0..03b67b8caec 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html +++ b/contrib/bind9/lib/lwres/man/lwres_gai_strerror.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3 b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3 index 7a1b5d76a81..edac0516ee5 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3 +++ b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_getaddrinfo.3,v 1.31 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_getaddrinfo.3,v 1.31.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html index ec0083952a2..5d02f4b46dd 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html +++ b/contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001, 2003 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_gethostent.3 b/contrib/bind9/lib/lwres/man/lwres_gethostent.3 index 847d8824338..688c618d9ae 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gethostent.3 +++ b/contrib/bind9/lib/lwres/man/lwres_gethostent.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_gethostent.3,v 1.29 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_gethostent.3,v 1.29.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_gethostent.html b/contrib/bind9/lib/lwres/man/lwres_gethostent.html index 9465440bd51..576c8d96e94 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gethostent.html +++ b/contrib/bind9/lib/lwres/man/lwres_gethostent.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_getipnode.3 b/contrib/bind9/lib/lwres/man/lwres_getipnode.3 index e5c51a999cc..b74b342e337 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getipnode.3 +++ b/contrib/bind9/lib/lwres/man/lwres_getipnode.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_getipnode.3,v 1.28 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_getipnode.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_getipnode.html b/contrib/bind9/lib/lwres/man/lwres_getipnode.html index c92c51cb280..9acc616b0cc 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getipnode.html +++ b/contrib/bind9/lib/lwres/man/lwres_getipnode.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001, 2003 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.3 b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.3 index c477f7982a3..d77776b6c2a 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.3 +++ b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_getnameinfo.3,v 1.29 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_getnameinfo.3,v 1.29.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html index 7730131cfda..8b84397bcca 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html +++ b/contrib/bind9/lib/lwres/man/lwres_getnameinfo.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3 b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3 index 8419fff3608..bda5aa21565 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3 +++ b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_getrrsetbyname.3,v 1.25 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_getrrsetbyname.3,v 1.25.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html index 15bfb82dc64..14f1e65b0f7 100644 --- a/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html +++ b/contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_gnba.3 b/contrib/bind9/lib/lwres/man/lwres_gnba.3 index 39a1b9d278f..e04fa8f3ba1 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gnba.3 +++ b/contrib/bind9/lib/lwres/man/lwres_gnba.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_gnba.3,v 1.27 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_gnba.3,v 1.27.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_gnba.html b/contrib/bind9/lib/lwres/man/lwres_gnba.html index 80c909ec212..368a8487dec 100644 --- a/contrib/bind9/lib/lwres/man/lwres_gnba.html +++ b/contrib/bind9/lib/lwres/man/lwres_gnba.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_hstrerror.3 b/contrib/bind9/lib/lwres/man/lwres_hstrerror.3 index 5998238e7b6..badb5fed58b 100644 --- a/contrib/bind9/lib/lwres/man/lwres_hstrerror.3 +++ b/contrib/bind9/lib/lwres/man/lwres_hstrerror.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_hstrerror.3,v 1.27 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_hstrerror.3,v 1.27.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_hstrerror.html b/contrib/bind9/lib/lwres/man/lwres_hstrerror.html index b166e3d7780..1ca798db276 100644 --- a/contrib/bind9/lib/lwres/man/lwres_hstrerror.html +++ b/contrib/bind9/lib/lwres/man/lwres_hstrerror.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_inetntop.3 b/contrib/bind9/lib/lwres/man/lwres_inetntop.3 index c7d3d126326..1f9e097479e 100644 --- a/contrib/bind9/lib/lwres/man/lwres_inetntop.3 +++ b/contrib/bind9/lib/lwres/man/lwres_inetntop.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_inetntop.3,v 1.26 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_inetntop.3,v 1.26.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_inetntop.html b/contrib/bind9/lib/lwres/man/lwres_inetntop.html index 3522a1dc191..9535c35bde0 100644 --- a/contrib/bind9/lib/lwres/man/lwres_inetntop.html +++ b/contrib/bind9/lib/lwres/man/lwres_inetntop.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_noop.3 b/contrib/bind9/lib/lwres/man/lwres_noop.3 index 0e4ed719472..6c39ce6fdf3 100644 --- a/contrib/bind9/lib/lwres/man/lwres_noop.3 +++ b/contrib/bind9/lib/lwres/man/lwres_noop.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_noop.3,v 1.28 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_noop.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_noop.html b/contrib/bind9/lib/lwres/man/lwres_noop.html index 18a41fa0a54..43539ad56e8 100644 --- a/contrib/bind9/lib/lwres/man/lwres_noop.html +++ b/contrib/bind9/lib/lwres/man/lwres_noop.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_packet.3 b/contrib/bind9/lib/lwres/man/lwres_packet.3 index 1e1f98fe9b9..068d24105c5 100644 --- a/contrib/bind9/lib/lwres/man/lwres_packet.3 +++ b/contrib/bind9/lib/lwres/man/lwres_packet.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_packet.3,v 1.29 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_packet.3,v 1.29.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_packet.html b/contrib/bind9/lib/lwres/man/lwres_packet.html index 11601e86b12..985e5f6c548 100644 --- a/contrib/bind9/lib/lwres/man/lwres_packet.html +++ b/contrib/bind9/lib/lwres/man/lwres_packet.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/lib/lwres/man/lwres_resutil.3 b/contrib/bind9/lib/lwres/man/lwres_resutil.3 index d26f77c5253..2297cb73956 100644 --- a/contrib/bind9/lib/lwres/man/lwres_resutil.3 +++ b/contrib/bind9/lib/lwres/man/lwres_resutil.3 @@ -1,7 +1,7 @@ .\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" -.\" Permission to use, copy, modify, and distribute this software for any +.\" 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. .\" @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: lwres_resutil.3,v 1.28 2007/01/30 00:24:59 marka Exp $ +.\" $Id: lwres_resutil.3,v 1.28.418.1 2009/07/11 01:55:21 tbox Exp $ .\" .hy 0 .ad l diff --git a/contrib/bind9/lib/lwres/man/lwres_resutil.html b/contrib/bind9/lib/lwres/man/lwres_resutil.html index e67ac0aa796..e11aa6f44bf 100644 --- a/contrib/bind9/lib/lwres/man/lwres_resutil.html +++ b/contrib/bind9/lib/lwres/man/lwres_resutil.html @@ -2,7 +2,7 @@ - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000, 2001 Internet Software Consortium. - - - Permission to use, copy, modify, and distribute this software for any + - 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. - @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> - + diff --git a/contrib/bind9/version b/contrib/bind9/version index c6fcc3fdeb6..79bbd493946 100644 --- a/contrib/bind9/version +++ b/contrib/bind9/version @@ -1,10 +1,10 @@ -# $Id: version,v 1.43.12.5.8.3 2009/12/31 20:29:20 each Exp $ +# $Id: version,v 1.43.12.8.2.3 2010/03/04 00:08:28 marka Exp $ # # This file must follow /bin/sh rules. It is imported directly via # configure. # MAJORVER=9 MINORVER=6 -PATCHVER=1 +PATCHVER=2 RELEASETYPE=-P -RELEASEVER=3 +RELEASEVER=1 diff --git a/lib/bind/config.h b/lib/bind/config.h index 1d68450eafb..3038b5b0d30 100644 --- a/lib/bind/config.h +++ b/lib/bind/config.h @@ -166,6 +166,12 @@ int sigwait(const unsigned int *set, int *sig); /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 +/* Define to 1 if you have the `EVP_sha256' function. */ +#define HAVE_EVP_SHA256 1 + +/* Define to 1 if you have the `EVP_sha512' function. */ +#define HAVE_EVP_SHA512 1 + /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 From 44a4e1d8fb8f69863493cc375bf5668976622dff Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Mon, 29 Mar 2010 06:55:38 +0000 Subject: [PATCH 1742/2592] MFC r205694: Handling SIGPIPE will cause deadlock/crash. Return an error immediatly in case of hard shutdown. --- sys/dev/hwpmc/hwpmc_logging.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c index 055433da4b3..633c6f953b6 100644 --- a/sys/dev/hwpmc/hwpmc_logging.c +++ b/sys/dev/hwpmc/hwpmc_logging.c @@ -298,7 +298,6 @@ pmclog_loop(void *arg) mtx_unlock(&pmc_kthread_mtx); -sigpipe_retry: /* process the request */ PMCDBG(LOG,WRI,2, "po=%p base=%p ptr=%p", po, lb->plb_base, lb->plb_ptr); @@ -322,9 +321,6 @@ sigpipe_retry: if (error) { /* XXX some errors are recoverable */ - if (error == EPIPE) - goto sigpipe_retry; - /* send a SIGIO to the owner and exit */ PROC_LOCK(p); psignal(p, SIGIO); From 2efccbe06d51ec2b58ea1d0c12e537ba07227d2c Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Mon, 29 Mar 2010 06:57:43 +0000 Subject: [PATCH 1743/2592] MFC r205693: Do not overflow the term in the case of multi-line display. --- usr.sbin/pmcstat/pmcpl_calltree.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/usr.sbin/pmcstat/pmcpl_calltree.c b/usr.sbin/pmcstat/pmcpl_calltree.c index 404653ebd7c..aac7913c92b 100644 --- a/usr.sbin/pmcstat/pmcpl_calltree.c +++ b/usr.sbin/pmcstat/pmcpl_calltree.c @@ -366,7 +366,7 @@ pmcpl_ct_node_cleartag(void) static int pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct, - struct pmcpl_ct_sample *rsamples, int x, int *y) + struct pmcpl_ct_sample *rsamples, int x, int *y, int maxy) { int i; @@ -387,7 +387,7 @@ pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct, if (ct->pct_narc == 0) { pmcpl_ct_topscreen[x+1][*y] = NULL; if (*y >= PMCPL_CT_MAXLINE || - *y >= pmcstat_displayheight) + *y >= maxy) return 1; *y = *y + 1; for (i=0; i < x; i++) @@ -407,7 +407,7 @@ pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct, &ct->pct_arc[i].pcta_samples) > pmcstat_threshold) { if (pmcpl_ct_node_dumptop(pmcin, ct->pct_arc[i].pcta_child, - rsamples, x+1, y)) + rsamples, x+1, y, maxy)) return 1; } } @@ -472,6 +472,9 @@ pmcpl_ct_node_printtop(struct pmcpl_ct_sample *rsamples, int pmcin, int maxy) /* Check for line wrap. */ width += ns_len + is_len + vs_len + 1; if (width >= pmcstat_displaywidth) { + maxy--; + if (y >= maxy) + break; PMCSTAT_PRINTW("\n%*s", indentwidth, space); width = indentwidth + ns_len + is_len + vs_len; } @@ -515,7 +518,7 @@ pmcpl_ct_topdisplay(void) for (i = 0; i < pmcpl_ct_root->pct_narc; i++) { if (pmcpl_ct_node_dumptop(pmcin, pmcpl_ct_root->pct_arc[i].pcta_child, - &rsamples, x, &y)) { + &rsamples, x, &y, pmcstat_displayheight - 2)) { break; } } From 0d3003c0c8a796bfd526514485f77e8bb3e3307c Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Mon, 29 Mar 2010 12:29:34 +0000 Subject: [PATCH 1744/2592] remove a leftover debugging message --- sys/netinet/ipfw/ip_dn_io.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/netinet/ipfw/ip_dn_io.c b/sys/netinet/ipfw/ip_dn_io.c index ae168ce86b9..eab9d9e0375 100644 --- a/sys/netinet/ipfw/ip_dn_io.c +++ b/sys/netinet/ipfw/ip_dn_io.c @@ -731,7 +731,6 @@ dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa) goto dropit; } if (fs->sched->fp->enqueue(si, q, m)) { - printf("%s dropped by enqueue\n", __FUNCTION__); /* packet was dropped by enqueue() */ m = *m0 = NULL; goto dropit; From d15984d46ed884d60304fef64500aeb458ec27ce Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Mon, 29 Mar 2010 12:32:16 +0000 Subject: [PATCH 1745/2592] mfc 205830: fixes to rule set handling (including potential kernel panics) --- sys/netinet/ipfw/ip_fw_sockopt.c | 59 +++++++++++++++++++------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/sys/netinet/ipfw/ip_fw_sockopt.c b/sys/netinet/ipfw/ip_fw_sockopt.c index e25b960e640..d04b00b56ce 100644 --- a/sys/netinet/ipfw/ip_fw_sockopt.c +++ b/sys/netinet/ipfw/ip_fw_sockopt.c @@ -270,23 +270,24 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg) return EINVAL; } - IPFW_UH_WLOCK(chain); /* prevent conflicts among the writers */ + IPFW_UH_WLOCK(chain); /* arbitrate writers */ chain->reap = NULL; /* prepare for deletions */ switch (cmd) { - case 0: /* delete rules with given number (0 is special means all) */ - case 1: /* delete all rules with given set number, rule->set == rulenum */ - case 5: /* delete rules with given number and with given set number. - * rulenum - given rule number; - * new_set - given set number. - */ - /* locate first rule to delete (start), the one after the - * last one (end), and count how many rules to delete (n) + case 0: /* delete rules number N (N == 0 means all) */ + case 1: /* delete all rules in set N */ + case 5: /* delete rules with number N and set "new_set". */ + + /* + * Locate first rule to delete (start), the rule after + * the last one to delete (end), and count how many + * rules to delete (n) */ n = 0; if (cmd == 1) { /* look for a specific set, must scan all */ + new_set = rulenum; for (start = -1, i = 0; i < chain->n_rules; i++) { - if (chain->map[start]->set != rulenum) + if (chain->map[i]->set != rulenum) continue; if (start < 0) start = i; @@ -314,32 +315,42 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg) error = EINVAL; break; } - /* copy the initial part of the map */ + /* + * bcopy the initial part of the map, then individually + * copy all matching entries between start and end, + * and then bcopy the final part. + * Once we are done we can swap maps and clean up the + * deleted rules (unfortunately we need to repeat a + * convoluted test). + */ if (start > 0) bcopy(chain->map, map, start * sizeof(struct ip_fw *)); - /* copy active rules between start and end */ for (i = ofs = start; i < end; i++) { rule = chain->map[i]; - if (!(rule->set != RESVD_SET && - (cmd == 0 || rule->set == new_set) )) + if (rule->set == RESVD_SET || cmd == 0 || + (rule->set == new_set && + (cmd == 1 || rule->rulenum == rulenum))) map[ofs++] = chain->map[i]; } - /* finally the tail */ bcopy(chain->map + end, map + ofs, (chain->n_rules - end) * sizeof(struct ip_fw *)); + map = swap_map(chain, map, chain->n_rules - n); /* now remove the rules deleted */ for (i = start; i < end; i++) { + int l; rule = map[i]; - if (rule->set != RESVD_SET && - (cmd == 0 || rule->set == new_set) ) { - int l = RULESIZE(rule); + /* same test as above */ + if (rule->set == RESVD_SET || cmd == 0 || + (rule->set == new_set && + (cmd == 1 || rule->rulenum == rulenum))) + continue; - chain->static_len -= l; - ipfw_remove_dyn_children(rule); - rule->x_next = chain->reap; - chain->reap = rule; - } + l = RULESIZE(rule); + chain->static_len -= l; + ipfw_remove_dyn_children(rule); + rule->x_next = chain->reap; + chain->reap = rule; } break; @@ -446,7 +457,7 @@ zero_entry(struct ip_fw_chain *chain, u_int32_t arg, int log_only) break; } if (!cleared) { /* we did not find any matching rules */ - IPFW_WUNLOCK(chain); + IPFW_UH_RUNLOCK(chain); return (EINVAL); } msg = log_only ? "logging count reset" : "cleared"; From 7dd1fd87e8a7902be86613cb222d3bb7a1b364a0 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Mon, 29 Mar 2010 15:39:17 +0000 Subject: [PATCH 1746/2592] MFC r199852, r202387, r202441, r202534: Handling all the three clocks with the LAPIC may lead to aliasing for softclock and profclock. Revert the change when the LAPIC started taking charge of all three of them. Sponsored by: Sandvine Incorporated --- sys/amd64/amd64/local_apic.c | 71 +++++++++++++++++++------------- sys/amd64/include/apicvar.h | 8 +++- sys/amd64/isa/clock.c | 15 +++---- sys/conf/files.pc98 | 4 +- sys/conf/options.i386 | 1 + sys/conf/options.pc98 | 1 + sys/i386/i386/local_apic.c | 79 +++++++++++++++++++++++------------- sys/i386/include/apicvar.h | 8 +++- sys/i386/isa/clock.c | 17 ++++---- sys/i386/xen/exception.s | 4 -- sys/pc98/cbus/clock.c | 11 +++-- sys/pc98/conf/DEFAULTS | 3 ++ 12 files changed, 135 insertions(+), 87 deletions(-) diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c index 98ed4df8307..0d04bbd4a69 100644 --- a/sys/amd64/amd64/local_apic.c +++ b/sys/amd64/amd64/local_apic.c @@ -160,6 +160,9 @@ static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value); struct pic lapic_pic = { .pic_resume = lapic_resume }; +static int lapic_allclocks; +TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks); + static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value) { @@ -415,10 +418,11 @@ lapic_disable_pmc(void) /* * Called by cpu_initclocks() on the BSP to setup the local APIC timer so * that it can drive hardclock, statclock, and profclock. This function - * returns true if it is able to use the local APIC timer to drive the - * clocks and false if it is not able. + * returns a positive integer if it is convenient to use the local APIC + * for all the clocks, a negative integer if it is convenient to use the + * local APIC only for the hardclock and 0 if none of them can be handled. */ -int +enum lapic_clock lapic_setup_clock(void) { u_long value; @@ -426,10 +430,10 @@ lapic_setup_clock(void) /* Can't drive the timer without a local APIC. */ if (lapic == NULL) - return (0); + return (LAPIC_CLOCK_NONE); if (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0) - return (0); + return (LAPIC_CLOCK_NONE); /* Start off with a divisor of 2 (power on reset default). */ lapic_timer_divisor = 2; @@ -461,19 +465,27 @@ lapic_setup_clock(void) * (and profhz) run at hz. If 'hz' is below 1500 but above * 750, then we let the lapic timer run at 2 * 'hz'. If 'hz' * is below 750 then we let the lapic timer run at 4 * 'hz'. + * + * Please note that stathz and profhz are set only if all the + * clocks are handled through the local APIC. */ - if (hz >= 1500) + if (lapic_allclocks != 0) { + if (hz >= 1500) + lapic_timer_hz = hz; + else if (hz >= 750) + lapic_timer_hz = hz * 2; + else + lapic_timer_hz = hz * 4; + } else lapic_timer_hz = hz; - else if (hz >= 750) - lapic_timer_hz = hz * 2; - else - lapic_timer_hz = hz * 4; - if (lapic_timer_hz < 128) - stathz = lapic_timer_hz; - else - stathz = lapic_timer_hz / (lapic_timer_hz / 128); - profhz = lapic_timer_hz; lapic_timer_period = value / lapic_timer_hz; + if (lapic_allclocks != 0) { + if (lapic_timer_hz < 128) + stathz = lapic_timer_hz; + else + stathz = lapic_timer_hz / (lapic_timer_hz / 128); + profhz = lapic_timer_hz; + } /* * Start up the timer on the BSP. The APs will kick off their @@ -481,7 +493,7 @@ lapic_setup_clock(void) */ lapic_timer_periodic(lapic_timer_period); lapic_timer_enable_intr(); - return (1); + return (lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL); } void @@ -784,20 +796,23 @@ lapic_handle_timer(struct trapframe *frame) else hardclock_cpu(TRAPF_USERMODE(frame)); } + if (lapic_allclocks != 0) { - /* Fire statclock at stathz. */ - la->la_stat_ticks += stathz; - if (la->la_stat_ticks >= lapic_timer_hz) { - la->la_stat_ticks -= lapic_timer_hz; - statclock(TRAPF_USERMODE(frame)); - } + /* Fire statclock at stathz. */ + la->la_stat_ticks += stathz; + if (la->la_stat_ticks >= lapic_timer_hz) { + la->la_stat_ticks -= lapic_timer_hz; + statclock(TRAPF_USERMODE(frame)); + } - /* Fire profclock at profhz, but only when needed. */ - la->la_prof_ticks += profhz; - if (la->la_prof_ticks >= lapic_timer_hz) { - la->la_prof_ticks -= lapic_timer_hz; - if (profprocs != 0) - profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); + /* Fire profclock at profhz, but only when needed. */ + la->la_prof_ticks += profhz; + if (la->la_prof_ticks >= lapic_timer_hz) { + la->la_prof_ticks -= lapic_timer_hz; + if (profprocs != 0) + profclock(TRAPF_USERMODE(frame), + TRAPF_PC(frame)); + } } critical_exit(); } diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h index 9d6d538de1d..8f15d84a1ac 100644 --- a/sys/amd64/include/apicvar.h +++ b/sys/amd64/include/apicvar.h @@ -157,6 +157,12 @@ #define APIC_BUS_PCI 2 #define APIC_BUS_MAX APIC_BUS_PCI +enum lapic_clock { + LAPIC_CLOCK_NONE, + LAPIC_CLOCK_HARDCLOCK, + LAPIC_CLOCK_ALL +}; + /* * An APIC enumerator is a psuedo bus driver that enumerates APIC's including * CPU's and I/O APIC's. @@ -224,7 +230,7 @@ int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger); void lapic_set_tpr(u_int vector); void lapic_setup(int boot); -int lapic_setup_clock(void); +enum lapic_clock lapic_setup_clock(void); #endif /* !LOCORE */ #endif /* _MACHINE_APICVAR_H_ */ diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index adc17435895..bf379f3287e 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -91,7 +91,7 @@ static u_int32_t i8254_offset; static int (*i8254_pending)(struct intsrc *); static int i8254_ticked; static int using_atrtc_timer; -static int using_lapic_timer; +static enum lapic_clock using_lapic_timer = LAPIC_CLOCK_NONE; /* Values for timerX_state: */ #define RELEASED 0 @@ -160,7 +160,8 @@ clkintr(struct trapframe *frame) clkintr_pending = 0; mtx_unlock_spin(&clock_lock); } - KASSERT(!using_lapic_timer, ("clk interrupt enabled with lapic timer")); + KASSERT(using_lapic_timer == LAPIC_CLOCK_NONE, + ("clk interrupt enabled with lapic timer")); if (using_atrtc_timer) { #ifdef SMP @@ -422,7 +423,7 @@ set_i8254_freq(u_int freq, int intr_freq) i8254_timecounter.tc_frequency = freq; mtx_lock_spin(&clock_lock); i8254_freq = freq; - if (using_lapic_timer) + if (using_lapic_timer != LAPIC_CLOCK_NONE) new_i8254_real_max_count = 0x10000; else new_i8254_real_max_count = TIMER_DIV(intr_freq); @@ -485,7 +486,7 @@ cpu_initclocks() * that it can drive hardclock(). Otherwise, change the 8254 * timecounter to user a simpler algorithm. */ - if (!using_lapic_timer) { + if (using_lapic_timer == LAPIC_CLOCK_NONE) { intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL, NULL, INTR_TYPE_CLK, NULL); i8254_intsrc = intr_lookup_source(0); @@ -508,7 +509,7 @@ cpu_initclocks() * kernel clocks, then setup the RTC to periodically interrupt to * drive statclock() and profclock(). */ - if (!using_lapic_timer) { + if (using_lapic_timer != LAPIC_CLOCK_ALL) { using_atrtc_timer = atrtc_setup_clock(); if (using_atrtc_timer) { /* Enable periodic interrupts from the RTC. */ @@ -532,7 +533,7 @@ void cpu_startprofclock(void) { - if (using_lapic_timer || !using_atrtc_timer) + if (using_lapic_timer == LAPIC_CLOCK_ALL || !using_atrtc_timer) return; atrtc_rate(RTCSA_PROF); psdiv = pscnt = psratio; @@ -542,7 +543,7 @@ void cpu_stopprofclock(void) { - if (using_lapic_timer || !using_atrtc_timer) + if (using_lapic_timer == LAPIC_CLOCK_ALL || !using_atrtc_timer) return; atrtc_rate(RTCSA_NOPROF); psdiv = pscnt = 1; diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 002cf86d39a..b4e171dfdc1 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -194,7 +194,7 @@ i386/ibcs2/ibcs2_util.c optional ibcs2 i386/ibcs2/ibcs2_xenix.c optional ibcs2 i386/ibcs2/ibcs2_xenix_sysent.c optional ibcs2 i386/ibcs2/imgact_coff.c optional ibcs2 -i386/isa/atpic.c standard +i386/isa/atpic.c optional atpic #i386/isa/atpic_vector.s standard i386/isa/elink.c optional ep | ie i386/isa/isa.c optional isa @@ -240,7 +240,7 @@ pc98/cbus/gdc.c optional gdc pc98/cbus/nmi.c standard pc98/cbus/olpt.c optional olpt pc98/cbus/pckbd.c optional pckbd -pc98/cbus/pcrtc.c standard +pc98/cbus/pcrtc.c optional atpic pc98/cbus/pmc.c optional pmc pc98/cbus/scgdcrndr.c optional sc gdc pc98/cbus/scterm-sck.c optional sc diff --git a/sys/conf/options.i386 b/sys/conf/options.i386 index a8e40e1462d..333ec6a8dfb 100644 --- a/sys/conf/options.i386 +++ b/sys/conf/options.i386 @@ -106,6 +106,7 @@ NETGRAPH_CRONYX opt_ng_cronyx.h # Device options DEV_APIC opt_apic.h +DEV_ATPIC opt_atpic.h DEV_NPX opt_npx.h ASR_COMPAT opt_asr.h diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98 index dca3d694ae7..a10737be767 100644 --- a/sys/conf/options.pc98 +++ b/sys/conf/options.pc98 @@ -90,6 +90,7 @@ PC98 opt_global.h # Device options DEV_APIC opt_apic.h +DEV_ATPIC opt_atpic.h DEV_MECIA opt_mecia.h DEV_NPX opt_npx.h diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c index 1451ec808e3..e0049c8cf5b 100644 --- a/sys/i386/i386/local_apic.c +++ b/sys/i386/i386/local_apic.c @@ -34,6 +34,7 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_atpic.h" #include "opt_hwpmc_hooks.h" #include "opt_kdtrace.h" @@ -160,6 +161,17 @@ static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value); struct pic lapic_pic = { .pic_resume = lapic_resume }; +/* + * The atrtc device is compiled in only if atpic is present. + * If it is not, force lapic to take care of all the clocks. + */ +#ifdef DEV_ATPIC +static int lapic_allclocks; +TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks); +#else +static int lapic_allclocks = 1; +#endif + static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value) { @@ -416,11 +428,9 @@ lapic_disable_pmc(void) /* * Called by cpu_initclocks() on the BSP to setup the local APIC timer so - * that it can drive hardclock, statclock, and profclock. This function - * returns true if it is able to use the local APIC timer to drive the - * clocks and false if it is not able. + * that it can drive hardclock, statclock, and profclock. */ -int +enum lapic_clock lapic_setup_clock(void) { u_long value; @@ -428,10 +438,10 @@ lapic_setup_clock(void) /* Can't drive the timer without a local APIC. */ if (lapic == NULL) - return (0); + return (LAPIC_CLOCK_NONE); if (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0) - return (0); + return (LAPIC_CLOCK_NONE); /* Start off with a divisor of 2 (power on reset default). */ lapic_timer_divisor = 2; @@ -463,19 +473,27 @@ lapic_setup_clock(void) * (and profhz) run at hz. If 'hz' is below 1500 but above * 750, then we let the lapic timer run at 2 * 'hz'. If 'hz' * is below 750 then we let the lapic timer run at 4 * 'hz'. + * + * Please note that stathz and profhz are set only if all the + * clocks are handled through the local APIC. */ - if (hz >= 1500) + if (lapic_allclocks != 0) { + if (hz >= 1500) + lapic_timer_hz = hz; + else if (hz >= 750) + lapic_timer_hz = hz * 2; + else + lapic_timer_hz = hz * 4; + } else lapic_timer_hz = hz; - else if (hz >= 750) - lapic_timer_hz = hz * 2; - else - lapic_timer_hz = hz * 4; - if (lapic_timer_hz < 128) - stathz = lapic_timer_hz; - else - stathz = lapic_timer_hz / (lapic_timer_hz / 128); - profhz = lapic_timer_hz; lapic_timer_period = value / lapic_timer_hz; + if (lapic_allclocks != 0) { + if (lapic_timer_hz < 128) + stathz = lapic_timer_hz; + else + stathz = lapic_timer_hz / (lapic_timer_hz / 128); + profhz = lapic_timer_hz; + } /* * Start up the timer on the BSP. The APs will kick off their @@ -483,7 +501,7 @@ lapic_setup_clock(void) */ lapic_timer_periodic(lapic_timer_period); lapic_timer_enable_intr(); - return (1); + return (lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL); } void @@ -786,20 +804,23 @@ lapic_handle_timer(struct trapframe *frame) else hardclock_cpu(TRAPF_USERMODE(frame)); } + if (lapic_allclocks != 0) { - /* Fire statclock at stathz. */ - la->la_stat_ticks += stathz; - if (la->la_stat_ticks >= lapic_timer_hz) { - la->la_stat_ticks -= lapic_timer_hz; - statclock(TRAPF_USERMODE(frame)); - } + /* Fire statclock at stathz. */ + la->la_stat_ticks += stathz; + if (la->la_stat_ticks >= lapic_timer_hz) { + la->la_stat_ticks -= lapic_timer_hz; + statclock(TRAPF_USERMODE(frame)); + } - /* Fire profclock at profhz, but only when needed. */ - la->la_prof_ticks += profhz; - if (la->la_prof_ticks >= lapic_timer_hz) { - la->la_prof_ticks -= lapic_timer_hz; - if (profprocs != 0) - profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); + /* Fire profclock at profhz, but only when needed. */ + la->la_prof_ticks += profhz; + if (la->la_prof_ticks >= lapic_timer_hz) { + la->la_prof_ticks -= lapic_timer_hz; + if (profprocs != 0) + profclock(TRAPF_USERMODE(frame), + TRAPF_PC(frame)); + } } critical_exit(); } diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h index b15452b1d81..2f8e716089d 100644 --- a/sys/i386/include/apicvar.h +++ b/sys/i386/include/apicvar.h @@ -186,6 +186,12 @@ #define APIC_BUS_PCI 2 #define APIC_BUS_MAX APIC_BUS_PCI +enum lapic_clock { + LAPIC_CLOCK_NONE, + LAPIC_CLOCK_HARDCLOCK, + LAPIC_CLOCK_ALL +}; + /* * An APIC enumerator is a psuedo bus driver that enumerates APIC's including * CPU's and I/O APIC's. @@ -253,7 +259,7 @@ int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger); void lapic_set_tpr(u_int vector); void lapic_setup(int boot); -int lapic_setup_clock(void); +enum lapic_clock lapic_setup_clock(void); #endif /* !LOCORE */ #endif /* _MACHINE_APICVAR_H_ */ diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index 12e76e4b7ea..e999b5619dd 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -65,9 +65,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef DEV_APIC #include -#endif #include #include #include @@ -106,7 +104,7 @@ static u_int32_t i8254_offset; static int (*i8254_pending)(struct intsrc *); static int i8254_ticked; static int using_atrtc_timer; -static int using_lapic_timer; +static enum lapic_clock using_lapic_timer = LAPIC_CLOCK_NONE; /* Values for timerX_state: */ #define RELEASED 0 @@ -175,7 +173,8 @@ clkintr(struct trapframe *frame) clkintr_pending = 0; mtx_unlock_spin(&clock_lock); } - KASSERT(!using_lapic_timer, ("clk interrupt enabled with lapic timer")); + KASSERT(using_lapic_timer == LAPIC_CLOCK_NONE, + ("clk interrupt enabled with lapic timer")); #ifdef KDTRACE_HOOKS /* @@ -453,7 +452,7 @@ set_i8254_freq(u_int freq, int intr_freq) i8254_timecounter.tc_frequency = freq; mtx_lock_spin(&clock_lock); i8254_freq = freq; - if (using_lapic_timer) + if (using_lapic_timer != LAPIC_CLOCK_NONE) new_i8254_real_max_count = 0x10000; else new_i8254_real_max_count = TIMER_DIV(intr_freq); @@ -533,7 +532,7 @@ cpu_initclocks() * that it can drive hardclock(). Otherwise, change the 8254 * timecounter to user a simpler algorithm. */ - if (!using_lapic_timer) { + if (using_lapic_timer == LAPIC_CLOCK_NONE) { intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL, NULL, INTR_TYPE_CLK, NULL); i8254_intsrc = intr_lookup_source(0); @@ -556,7 +555,7 @@ cpu_initclocks() * kernel clocks, then setup the RTC to periodically interrupt to * drive statclock() and profclock(). */ - if (!using_lapic_timer) { + if (using_lapic_timer != LAPIC_CLOCK_ALL) { using_atrtc_timer = atrtc_setup_clock(); if (using_atrtc_timer) { /* Enable periodic interrupts from the RTC. */ @@ -580,7 +579,7 @@ void cpu_startprofclock(void) { - if (using_lapic_timer || !using_atrtc_timer) + if (using_lapic_timer == LAPIC_CLOCK_ALL || !using_atrtc_timer) return; atrtc_rate(RTCSA_PROF); psdiv = pscnt = psratio; @@ -590,7 +589,7 @@ void cpu_stopprofclock(void) { - if (using_lapic_timer || !using_atrtc_timer) + if (using_lapic_timer == LAPIC_CLOCK_ALL || !using_atrtc_timer) return; atrtc_rate(RTCSA_NOPROF); psdiv = pscnt = 1; diff --git a/sys/i386/xen/exception.s b/sys/i386/xen/exception.s index 607f96a46b2..e965ffd026d 100644 --- a/sys/i386/xen/exception.s +++ b/sys/i386/xen/exception.s @@ -295,10 +295,6 @@ ENTRY(fork_trampoline) SUPERALIGN_TEXT MCOUNT_LABEL(bintr) -#ifdef DEV_ATPIC -#include -#endif - #ifdef DEV_APIC .data .p2align 4 diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c index bb651bdc3a6..10b25986813 100644 --- a/sys/pc98/cbus/clock.c +++ b/sys/pc98/cbus/clock.c @@ -67,9 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef DEV_APIC #include -#endif #include #include #include @@ -101,7 +99,7 @@ static u_int32_t i8254_lastcount; static u_int32_t i8254_offset; static int (*i8254_pending)(struct intsrc *); static int i8254_ticked; -static int using_lapic_timer; +static enum lapic_clock using_lapic_timer = LAPIC_CLOCK_NONE; /* Values for timerX_state: */ #define RELEASED 0 @@ -164,7 +162,8 @@ clkintr(struct trapframe *frame) clkintr_pending = 0; mtx_unlock_spin(&clock_lock); } - KASSERT(!using_lapic_timer, ("clk interrupt enabled with lapic timer")); + KASSERT(using_lapic_timer == LAPIC_CLOCK_NONE, + ("clk interrupt enabled with lapic timer")); #ifdef KDTRACE_HOOKS /* @@ -360,7 +359,7 @@ set_i8254_freq(u_int freq, int intr_freq) i8254_timecounter.tc_frequency = freq; mtx_lock_spin(&clock_lock); i8254_freq = freq; - if (using_lapic_timer) + if (using_lapic_timer != LAPIC_CLOCK_NONE) new_i8254_real_max_count = 0x10000; else new_i8254_real_max_count = TIMER_DIV(intr_freq); @@ -443,7 +442,7 @@ cpu_initclocks() * that it can drive hardclock(). Otherwise, change the 8254 * timecounter to user a simpler algorithm. */ - if (!using_lapic_timer) { + if (using_lapic_timer == LAPIC_CLOCK_NONE) { intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL, NULL, INTR_TYPE_CLK, NULL); i8254_intsrc = intr_lookup_source(0); diff --git a/sys/pc98/conf/DEFAULTS b/sys/pc98/conf/DEFAULTS index 0002cf0a30c..f30501e44ac 100644 --- a/sys/pc98/conf/DEFAULTS +++ b/sys/pc98/conf/DEFAULTS @@ -24,3 +24,6 @@ device uart_ns8250 # Default partitioning schemes options GEOM_PART_BSD options GEOM_PART_PC98 + +# enable support for native hardware +device atpic From ac39796e383e89da522f963c85a266e615b10e6d Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 29 Mar 2010 15:59:37 +0000 Subject: [PATCH 1747/2592] MFC: r205647 Fix stupid typos. Some VESA BIOSes directly call BIOS interrupt handlers within the VBE interrupt handler. Unfortunately it was causing real mode page faults because we were fetching instructions from bogus addresses. PR: kern/144654 --- sys/compat/x86bios/x86bios.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/compat/x86bios/x86bios.c b/sys/compat/x86bios/x86bios.c index 34da07c3d40..e7b79f7ea8b 100644 --- a/sys/compat/x86bios/x86bios.c +++ b/sys/compat/x86bios/x86bios.c @@ -267,8 +267,8 @@ x86bios_emu_get_intr(struct x86emu *emu, int intno) 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_IP = iv & 0xffff; + emu->x86.R_CS = (iv >> 16) & 0xffff; emu->x86.R_FLG &= ~(F_IF | F_TF); } From 92fc47574f4d3801c5ce32d88c37c1f90109e17b Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 29 Mar 2010 18:24:08 +0000 Subject: [PATCH 1748/2592] MFC r205702: Remove GNU cpio after fix of CVE-2010-0624. Note that this is actually a no-op for most users, as this GNU cpio was broken on -HEAD and 8-STABLE since last March until the recent fix. FreeBSD 8.0+ uses BSD cpio by default and the code is being actively maintained. --- ObsoleteFiles.inc | 4 + contrib/cpio/ABOUT-NLS | 1101 ------------ contrib/cpio/AUTHORS | 6 - contrib/cpio/COPYING | 340 ---- contrib/cpio/ChangeLog | 1781 -------------------- contrib/cpio/FREEBSD-upgrade | 29 - contrib/cpio/INSTALL | 234 --- contrib/cpio/NEWS | 155 -- contrib/cpio/README | 71 - contrib/cpio/THANKS | 20 - contrib/cpio/TODO | 159 -- contrib/cpio/doc/cpio.1 | 41 - contrib/cpio/doc/cpio.texi | 602 ------- contrib/cpio/doc/version.texi | 4 - contrib/cpio/lib/alloca_.h | 54 - contrib/cpio/lib/argp-ba.c | 25 - contrib/cpio/lib/argp-eexst.c | 31 - contrib/cpio/lib/argp-fmtstream.c | 435 ----- contrib/cpio/lib/argp-fmtstream.h | 301 ---- contrib/cpio/lib/argp-fs-xinl.c | 43 - contrib/cpio/lib/argp-help.c | 1954 ---------------------- contrib/cpio/lib/argp-namefrob.h | 158 -- contrib/cpio/lib/argp-parse.c | 953 ----------- contrib/cpio/lib/argp-pin.c | 28 - contrib/cpio/lib/argp-pv.c | 24 - contrib/cpio/lib/argp-pvh.c | 31 - contrib/cpio/lib/argp-xinl.c | 43 - contrib/cpio/lib/argp.h | 624 ------- contrib/cpio/lib/basename.c | 129 -- contrib/cpio/lib/dirname.c | 85 - contrib/cpio/lib/dirname.h | 70 - contrib/cpio/lib/error.c | 338 ---- contrib/cpio/lib/error.h | 66 - contrib/cpio/lib/exitfail.c | 26 - contrib/cpio/lib/exitfail.h | 20 - contrib/cpio/lib/fatal.c | 27 - contrib/cpio/lib/full-write.c | 81 - contrib/cpio/lib/full-write.h | 35 - contrib/cpio/lib/getopt.c | 1191 ------------- contrib/cpio/lib/getopt1.c | 171 -- contrib/cpio/lib/getopt_.h | 226 --- contrib/cpio/lib/getopt_int.h | 131 -- contrib/cpio/lib/gettext.h | 270 --- contrib/cpio/lib/hash.c | 1048 ------------ contrib/cpio/lib/hash.h | 88 - contrib/cpio/lib/intprops.h | 78 - contrib/cpio/lib/inttostr.c | 51 - contrib/cpio/lib/inttostr.h | 30 - contrib/cpio/lib/mempcpy.c | 29 - contrib/cpio/lib/paxerror.c | 365 ---- contrib/cpio/lib/paxexit.c | 28 - contrib/cpio/lib/paxlib.h | 115 -- contrib/cpio/lib/paxnames.c | 156 -- contrib/cpio/lib/quote.c | 41 - contrib/cpio/lib/quote.h | 22 - contrib/cpio/lib/quotearg.c | 697 -------- contrib/cpio/lib/quotearg.h | 140 -- contrib/cpio/lib/rmt-command.h | 4 - contrib/cpio/lib/rmt.h | 99 -- contrib/cpio/lib/rtapelib.c | 741 -------- contrib/cpio/lib/safe-read.c | 78 - contrib/cpio/lib/safe-read.h | 35 - contrib/cpio/lib/safe-write.c | 19 - contrib/cpio/lib/safe-write.h | 25 - contrib/cpio/lib/savedir.c | 137 -- contrib/cpio/lib/savedir.h | 27 - contrib/cpio/lib/strchrnul.c | 32 - contrib/cpio/lib/stripslash.c | 45 - contrib/cpio/lib/strndup.c | 37 - contrib/cpio/lib/strnlen.c | 31 - contrib/cpio/lib/system-ioctl.h | 55 - contrib/cpio/lib/system.h | 475 ------ contrib/cpio/lib/umaxtostr.c | 3 - contrib/cpio/lib/unlocked-io.h | 137 -- contrib/cpio/lib/utimens.c | 189 --- contrib/cpio/lib/utimens.h | 3 - contrib/cpio/lib/xalloc-die.c | 42 - contrib/cpio/lib/xalloc.h | 271 --- contrib/cpio/lib/xmalloc.c | 123 -- contrib/cpio/lib/xstrndup.c | 37 - contrib/cpio/lib/xstrndup.h | 24 - contrib/cpio/src/copyin.c | 1644 ------------------ contrib/cpio/src/copyout.c | 1010 ----------- contrib/cpio/src/copypass.c | 443 ----- contrib/cpio/src/cpio.h | 72 - contrib/cpio/src/cpiohdr.h | 106 -- contrib/cpio/src/defer.c | 43 - contrib/cpio/src/defer.h | 26 - contrib/cpio/src/dstring.c | 103 -- contrib/cpio/src/dstring.h | 50 - contrib/cpio/src/extern.h | 221 --- contrib/cpio/src/filemode.c | 243 --- contrib/cpio/src/filetypes.h | 85 - contrib/cpio/src/global.c | 201 --- contrib/cpio/src/idcache.c | 207 --- contrib/cpio/src/main.c | 804 --------- contrib/cpio/src/makepath.c | 267 --- contrib/cpio/src/safe-stat.h | 1 - contrib/cpio/src/tar.c | 494 ------ contrib/cpio/src/tar.h | 112 -- contrib/cpio/src/tarhdr.h | 63 - contrib/cpio/src/userspec.c | 261 --- contrib/cpio/src/util.c | 1344 --------------- gnu/usr.bin/Makefile | 5 - gnu/usr.bin/cpio/Makefile | 80 - gnu/usr.bin/cpio/config.h | 1001 ----------- gnu/usr.bin/cpio/doc/Makefile | 15 - share/man/man5/src.conf.5 | 9 +- share/mk/bsd.own.mk | 1 - tools/build/mk/OptionalObsoleteFiles.inc | 6 - tools/build/options/WITH_GNU_CPIO | 6 - usr.bin/cpio/Makefile | 2 - 112 files changed, 5 insertions(+), 26594 deletions(-) delete mode 100644 contrib/cpio/ABOUT-NLS delete mode 100644 contrib/cpio/AUTHORS delete mode 100644 contrib/cpio/COPYING delete mode 100644 contrib/cpio/ChangeLog delete mode 100644 contrib/cpio/FREEBSD-upgrade delete mode 100644 contrib/cpio/INSTALL delete mode 100644 contrib/cpio/NEWS delete mode 100644 contrib/cpio/README delete mode 100644 contrib/cpio/THANKS delete mode 100644 contrib/cpio/TODO delete mode 100644 contrib/cpio/doc/cpio.1 delete mode 100644 contrib/cpio/doc/cpio.texi delete mode 100644 contrib/cpio/doc/version.texi delete mode 100644 contrib/cpio/lib/alloca_.h delete mode 100644 contrib/cpio/lib/argp-ba.c delete mode 100644 contrib/cpio/lib/argp-eexst.c delete mode 100644 contrib/cpio/lib/argp-fmtstream.c delete mode 100644 contrib/cpio/lib/argp-fmtstream.h delete mode 100644 contrib/cpio/lib/argp-fs-xinl.c delete mode 100644 contrib/cpio/lib/argp-help.c delete mode 100644 contrib/cpio/lib/argp-namefrob.h delete mode 100644 contrib/cpio/lib/argp-parse.c delete mode 100644 contrib/cpio/lib/argp-pin.c delete mode 100644 contrib/cpio/lib/argp-pv.c delete mode 100644 contrib/cpio/lib/argp-pvh.c delete mode 100644 contrib/cpio/lib/argp-xinl.c delete mode 100644 contrib/cpio/lib/argp.h delete mode 100644 contrib/cpio/lib/basename.c delete mode 100644 contrib/cpio/lib/dirname.c delete mode 100644 contrib/cpio/lib/dirname.h delete mode 100644 contrib/cpio/lib/error.c delete mode 100644 contrib/cpio/lib/error.h delete mode 100644 contrib/cpio/lib/exitfail.c delete mode 100644 contrib/cpio/lib/exitfail.h delete mode 100644 contrib/cpio/lib/fatal.c delete mode 100644 contrib/cpio/lib/full-write.c delete mode 100644 contrib/cpio/lib/full-write.h delete mode 100644 contrib/cpio/lib/getopt.c delete mode 100644 contrib/cpio/lib/getopt1.c delete mode 100644 contrib/cpio/lib/getopt_.h delete mode 100644 contrib/cpio/lib/getopt_int.h delete mode 100644 contrib/cpio/lib/gettext.h delete mode 100644 contrib/cpio/lib/hash.c delete mode 100644 contrib/cpio/lib/hash.h delete mode 100644 contrib/cpio/lib/intprops.h delete mode 100644 contrib/cpio/lib/inttostr.c delete mode 100644 contrib/cpio/lib/inttostr.h delete mode 100644 contrib/cpio/lib/mempcpy.c delete mode 100644 contrib/cpio/lib/paxerror.c delete mode 100644 contrib/cpio/lib/paxexit.c delete mode 100644 contrib/cpio/lib/paxlib.h delete mode 100644 contrib/cpio/lib/paxnames.c delete mode 100644 contrib/cpio/lib/quote.c delete mode 100644 contrib/cpio/lib/quote.h delete mode 100644 contrib/cpio/lib/quotearg.c delete mode 100644 contrib/cpio/lib/quotearg.h delete mode 100644 contrib/cpio/lib/rmt-command.h delete mode 100644 contrib/cpio/lib/rmt.h delete mode 100644 contrib/cpio/lib/rtapelib.c delete mode 100644 contrib/cpio/lib/safe-read.c delete mode 100644 contrib/cpio/lib/safe-read.h delete mode 100644 contrib/cpio/lib/safe-write.c delete mode 100644 contrib/cpio/lib/safe-write.h delete mode 100644 contrib/cpio/lib/savedir.c delete mode 100644 contrib/cpio/lib/savedir.h delete mode 100644 contrib/cpio/lib/strchrnul.c delete mode 100644 contrib/cpio/lib/stripslash.c delete mode 100644 contrib/cpio/lib/strndup.c delete mode 100644 contrib/cpio/lib/strnlen.c delete mode 100644 contrib/cpio/lib/system-ioctl.h delete mode 100644 contrib/cpio/lib/system.h delete mode 100644 contrib/cpio/lib/umaxtostr.c delete mode 100644 contrib/cpio/lib/unlocked-io.h delete mode 100644 contrib/cpio/lib/utimens.c delete mode 100644 contrib/cpio/lib/utimens.h delete mode 100644 contrib/cpio/lib/xalloc-die.c delete mode 100644 contrib/cpio/lib/xalloc.h delete mode 100644 contrib/cpio/lib/xmalloc.c delete mode 100644 contrib/cpio/lib/xstrndup.c delete mode 100644 contrib/cpio/lib/xstrndup.h delete mode 100644 contrib/cpio/src/copyin.c delete mode 100644 contrib/cpio/src/copyout.c delete mode 100644 contrib/cpio/src/copypass.c delete mode 100644 contrib/cpio/src/cpio.h delete mode 100644 contrib/cpio/src/cpiohdr.h delete mode 100644 contrib/cpio/src/defer.c delete mode 100644 contrib/cpio/src/defer.h delete mode 100644 contrib/cpio/src/dstring.c delete mode 100644 contrib/cpio/src/dstring.h delete mode 100644 contrib/cpio/src/extern.h delete mode 100644 contrib/cpio/src/filemode.c delete mode 100644 contrib/cpio/src/filetypes.h delete mode 100644 contrib/cpio/src/global.c delete mode 100644 contrib/cpio/src/idcache.c delete mode 100644 contrib/cpio/src/main.c delete mode 100644 contrib/cpio/src/makepath.c delete mode 100644 contrib/cpio/src/safe-stat.h delete mode 100644 contrib/cpio/src/tar.c delete mode 100644 contrib/cpio/src/tar.h delete mode 100644 contrib/cpio/src/tarhdr.h delete mode 100644 contrib/cpio/src/userspec.c delete mode 100644 contrib/cpio/src/util.c delete mode 100644 gnu/usr.bin/cpio/Makefile delete mode 100644 gnu/usr.bin/cpio/config.h delete mode 100644 gnu/usr.bin/cpio/doc/Makefile delete mode 100644 tools/build/options/WITH_GNU_CPIO diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 25e43bab28c..0b29f98634e 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -14,6 +14,10 @@ # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last. # +# 20100329: gcpio removal +OLD_FILES+=usr/bin/gcpio +OLD_FILES+=usr/share/info/cpio.info.gz +OLD_FILES+=usr/share/man/man1/gcpio.1.gz # 20100301: 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 diff --git a/contrib/cpio/ABOUT-NLS b/contrib/cpio/ABOUT-NLS deleted file mode 100644 index ec20977e060..00000000000 --- a/contrib/cpio/ABOUT-NLS +++ /dev/null @@ -1,1101 +0,0 @@ -1 Notes on the Free Translation Project -*************************************** - -Free software is going international! The Free Translation Project is -a way to get maintainers of free software, translators, and users all -together, so that free software will gradually become able to speak many -languages. A few packages already provide translations for their -messages. - - If you found this `ABOUT-NLS' file inside a distribution, you may -assume that the distributed package does use GNU `gettext' internally, -itself available at your nearest GNU archive site. But you do _not_ -need to install GNU `gettext' prior to configuring, installing or using -this package with messages translated. - - Installers will find here some useful hints. These notes also -explain how users should proceed for getting the programs to use the -available translations. They tell how people wanting to contribute and -work on translations can contact the appropriate team. - - When reporting bugs in the `intl/' directory or bugs which may be -related to internationalization, you should tell about the version of -`gettext' which is used. The information can be found in the -`intl/VERSION' file, in internationalized packages. - -1.1 Quick configuration advice -============================== - -If you want to exploit the full power of internationalization, you -should configure it using - - ./configure --with-included-gettext - -to force usage of internationalizing routines provided within this -package, despite the existence of internationalizing capabilities in the -operating system where this package is being installed. So far, only -the `gettext' implementation in the GNU C library version 2 provides as -many features (such as locale alias, message inheritance, automatic -charset conversion or plural form handling) as the implementation here. -It is also not possible to offer this additional functionality on top -of a `catgets' implementation. Future versions of GNU `gettext' will -very likely convey even more functionality. So it might be a good idea -to change to GNU `gettext' as soon as possible. - - So you need _not_ provide this option if you are using GNU libc 2 or -you have installed a recent copy of the GNU gettext package with the -included `libintl'. - -1.2 INSTALL Matters -=================== - -Some packages are "localizable" when properly installed; the programs -they contain can be made to speak your own native language. Most such -packages use GNU `gettext'. Other packages have their own ways to -internationalization, predating GNU `gettext'. - - By default, this package will be installed to allow translation of -messages. It will automatically detect whether the system already -provides the GNU `gettext' functions. If not, the included GNU -`gettext' library will be used. This library is wholly contained -within this package, usually in the `intl/' subdirectory, so prior -installation of the GNU `gettext' package is _not_ required. -Installers may use special options at configuration time for changing -the default behaviour. The commands: - - ./configure --with-included-gettext - ./configure --disable-nls - -will, respectively, bypass any pre-existing `gettext' to use the -internationalizing routines provided within this package, or else, -_totally_ disable translation of messages. - - When you already have GNU `gettext' installed on your system and run -configure without an option for your new package, `configure' will -probably detect the previously built and installed `libintl.a' file and -will decide to use this. This might not be desirable. You should use -the more recent version of the GNU `gettext' library. I.e. if the file -`intl/VERSION' shows that the library which comes with this package is -more recent, you should use - - ./configure --with-included-gettext - -to prevent auto-detection. - - The configuration process will not test for the `catgets' function -and therefore it will not be used. The reason is that even an -emulation of `gettext' on top of `catgets' could not provide all the -extensions of the GNU `gettext' library. - - Internationalized packages usually have many `po/LL.po' files, where -LL gives an ISO 639 two-letter code identifying the language. Unless -translations have been forbidden at `configure' time by using the -`--disable-nls' switch, all available translations are installed -together with the package. However, the environment variable `LINGUAS' -may be set, prior to configuration, to limit the installed set. -`LINGUAS' should then contain a space separated list of two-letter -codes, stating which languages are allowed. - -1.3 Using This Package -====================== - -As a user, if your language has been installed for this package, you -only have to set the `LANG' environment variable to the appropriate -`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, -and `CC' is an ISO 3166 two-letter country code. For example, let's -suppose that you speak German and live in Germany. At the shell -prompt, merely execute `setenv LANG de_DE' (in `csh'), -`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). -This can be done from your `.login' or `.profile' file, once and for -all. - - You might think that the country code specification is redundant. -But in fact, some languages have dialects in different countries. For -example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The -country code serves to distinguish the dialects. - - The locale naming convention of `LL_CC', with `LL' denoting the -language and `CC' denoting the country, is the one use on systems based -on GNU libc. On other systems, some variations of this scheme are -used, such as `LL' or `LL_CC.ENCODING'. You can get the list of -locales supported by your system for your language by running the -command `locale -a | grep '^LL''. - - Not all programs have translations for all languages. By default, an -English message is shown in place of a nonexistent translation. If you -understand other languages, you can set up a priority list of languages. -This is done through a different environment variable, called -`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' -for the purpose of message handling, but you still need to have `LANG' -set to the primary language; this is required by other parts of the -system libraries. For example, some Swedish users who would rather -read translations in German than English for when Swedish is not -available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. - - Special advice for Norwegian users: The language code for Norwegian -bokma*l changed from `no' to `nb' recently (in 2003). During the -transition period, while some message catalogs for this language are -installed under `nb' and some older ones under `no', it's recommended -for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and -older translations are used. - - In the `LANGUAGE' environment variable, but not in the `LANG' -environment variable, `LL_CC' combinations can be abbreviated as `LL' -to denote the language's main dialect. For example, `de' is equivalent -to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' -(Portuguese as spoken in Portugal) in this context. - -1.4 Translating Teams -===================== - -For the Free Translation Project to be a success, we need interested -people who like their own language and write it well, and who are also -able to synergize with other translators speaking the same language. -Each translation team has its own mailing list. The up-to-date list of -teams can be found at the Free Translation Project's homepage, -`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" -area. - - If you'd like to volunteer to _work_ at translating messages, you -should become a member of the translating team for your own language. -The subscribing address is _not_ the same as the list itself, it has -`-request' appended. For example, speakers of Swedish can send a -message to `sv-request@li.org', having this message body: - - subscribe - - Keep in mind that team members are expected to participate -_actively_ in translations, or at solving translational difficulties, -rather than merely lurking around. If your team does not exist yet and -you want to start one, or if you are unsure about what to do or how to -get started, please write to `translation@iro.umontreal.ca' to reach the -coordinator for all translator teams. - - The English team is special. It works at improving and uniformizing -the terminology in use. Proven linguistic skills are praised more than -programming skills, here. - -1.5 Available Packages -====================== - -Languages are not equally supported in all packages. The following -matrix shows the current state of internationalization, as of October -2006. The matrix shows, in regard of each package, for which languages -PO files have been submitted to translation coordination, with a -translation percentage of at least 50%. - - Ready PO files af am ar az be bg bs ca cs cy da de el en en_GB eo - +----------------------------------------------------+ - GNUnet | [] | - a2ps | [] [] [] [] [] | - aegis | () | - ant-phone | () | - anubis | [] | - ap-utils | | - aspell | [] [] [] [] [] | - bash | [] [] [] | - batchelor | [] | - bfd | | - bibshelf | [] | - binutils | [] | - bison | [] [] | - bison-runtime | | - bluez-pin | [] [] [] [] [] | - cflow | [] | - clisp | [] [] | - console-tools | [] [] | - coreutils | [] [] [] | - cpio | | - cpplib | [] [] [] | - cryptonit | [] | - darkstat | [] () [] | - dialog | [] [] [] [] [] [] | - diffutils | [] [] [] [] [] [] | - doodle | [] | - e2fsprogs | [] [] | - enscript | [] [] [] [] | - error | [] [] [] [] | - fetchmail | [] [] () [] | - fileutils | [] [] | - findutils | [] [] [] | - flex | [] [] [] | - fslint | [] | - gas | | - gawk | [] [] [] | - gbiff | [] | - gcal | [] | - gcc | [] | - gettext-examples | [] [] [] [] [] | - gettext-runtime | [] [] [] [] [] | - gettext-tools | [] [] | - gimp-print | [] [] [] [] | - gip | [] | - gliv | [] | - glunarclock | [] | - gmult | [] [] | - gnubiff | () | - gnucash | () () [] | - gnucash-glossary | [] () | - gnuedu | | - gnulib | [] [] [] [] [] [] | - gnunet-gtk | | - gnutls | | - gpe-aerial | [] [] | - gpe-beam | [] [] | - gpe-calendar | | - gpe-clock | [] [] | - gpe-conf | [] [] | - gpe-contacts | | - gpe-edit | [] | - gpe-filemanager | | - gpe-go | [] | - gpe-login | [] [] | - gpe-ownerinfo | [] [] | - gpe-package | | - gpe-sketchbook | [] [] | - gpe-su | [] [] | - gpe-taskmanager | [] [] | - gpe-timesheet | [] | - gpe-today | [] [] | - gpe-todo | | - gphoto2 | [] [] [] [] | - gprof | [] [] | - gpsdrive | () () | - gramadoir | [] [] | - grep | [] [] [] [] [] [] | - gretl | | - gsasl | | - gss | | - gst-plugins | [] [] [] [] | - gst-plugins-base | [] [] [] | - gst-plugins-good | [] [] [] [] [] [] [] | - gstreamer | [] [] [] [] [] [] [] | - gtick | () | - gtkam | [] [] [] | - gtkorphan | [] [] | - gtkspell | [] [] [] [] | - gutenprint | [] | - hello | [] [] [] [] [] | - id-utils | [] [] | - impost | | - indent | [] [] [] | - iso_3166 | [] [] | - iso_3166_2 | | - iso_4217 | [] | - iso_639 | [] [] | - jpilot | [] | - jtag | | - jwhois | | - kbd | [] [] [] [] | - keytouch | | - keytouch-editor | | - keytouch-keyboa... | | - latrine | () | - ld | [] | - leafpad | [] [] [] [] [] | - libc | [] [] [] [] [] | - libexif | [] | - libextractor | [] | - libgpewidget | [] [] [] | - libgpg-error | [] | - libgphoto2 | [] [] | - libgphoto2_port | [] [] | - libgsasl | | - libiconv | [] [] | - libidn | [] [] | - lifelines | [] () | - lilypond | [] | - lingoteach | | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | [] | - make | [] [] | - man-db | [] () [] [] | - minicom | [] [] [] | - mysecretdiary | [] [] | - nano | [] [] [] | - nano_1_0 | [] () [] [] | - opcodes | [] | - parted | | - pilot-qof | [] | - psmisc | [] | - pwdutils | | - python | | - qof | | - radius | [] | - recode | [] [] [] [] [] [] | - rpm | [] [] | - screem | | - scrollkeeper | [] [] [] [] [] [] [] [] | - sed | [] [] [] | - sh-utils | [] [] | - shared-mime-info | [] [] [] [] | - sharutils | [] [] [] [] [] [] | - shishi | | - silky | | - skencil | [] () | - sketch | [] () | - solfege | | - soundtracker | [] [] | - sp | [] | - stardict | [] | - system-tools-ba... | [] [] [] [] [] [] [] [] [] | - tar | [] | - texinfo | [] [] [] | - textutils | [] [] [] | - tin | () () | - tp-robot | [] | - tuxpaint | [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | | - util-linux | [] [] [] [] | - vorbis-tools | [] [] [] [] | - wastesedge | () | - wdiff | [] [] [] [] | - wget | [] [] | - xchat | [] [] [] [] [] [] | - xkeyboard-config | | - xpad | [] [] | - +----------------------------------------------------+ - af am ar az be bg bs ca cs cy da de el en en_GB eo - 10 0 1 2 9 22 1 42 41 2 60 95 16 1 17 16 - - es et eu fa fi fr ga gl gu he hi hr hu id is it - +--------------------------------------------------+ - GNUnet | | - a2ps | [] [] [] () | - aegis | | - ant-phone | [] | - anubis | [] | - ap-utils | [] [] | - aspell | [] [] [] | - bash | [] [] [] | - batchelor | [] [] | - bfd | [] | - bibshelf | [] [] [] | - binutils | [] [] [] | - bison | [] [] [] [] [] [] | - bison-runtime | [] [] [] [] [] | - bluez-pin | [] [] [] [] [] | - cflow | [] | - clisp | [] [] | - console-tools | | - coreutils | [] [] [] [] [] [] | - cpio | [] [] [] | - cpplib | [] [] | - cryptonit | [] | - darkstat | [] () [] [] [] | - dialog | [] [] [] [] [] [] [] [] | - diffutils | [] [] [] [] [] [] [] [] [] | - doodle | [] [] | - e2fsprogs | [] [] [] | - enscript | [] [] [] | - error | [] [] [] [] [] | - fetchmail | [] | - fileutils | [] [] [] [] [] [] | - findutils | [] [] [] [] | - flex | [] [] [] | - fslint | [] | - gas | [] [] | - gawk | [] [] [] [] | - gbiff | [] | - gcal | [] [] | - gcc | [] | - gettext-examples | [] [] [] [] [] [] | - gettext-runtime | [] [] [] [] [] [] | - gettext-tools | [] [] [] | - gimp-print | [] [] | - gip | [] [] [] | - gliv | () | - glunarclock | [] [] [] | - gmult | [] [] [] | - gnubiff | () () | - gnucash | () () () | - gnucash-glossary | [] [] | - gnuedu | [] | - gnulib | [] [] [] [] [] [] [] [] | - gnunet-gtk | | - gnutls | | - gpe-aerial | [] [] | - gpe-beam | [] [] | - gpe-calendar | | - gpe-clock | [] [] [] [] | - gpe-conf | [] | - gpe-contacts | [] [] | - gpe-edit | [] [] [] [] | - gpe-filemanager | [] | - gpe-go | [] [] [] | - gpe-login | [] [] [] | - gpe-ownerinfo | [] [] [] [] [] | - gpe-package | [] | - gpe-sketchbook | [] [] | - gpe-su | [] [] [] [] | - gpe-taskmanager | [] [] [] | - gpe-timesheet | [] [] [] [] | - gpe-today | [] [] [] [] | - gpe-todo | [] | - gphoto2 | [] [] [] [] [] | - gprof | [] [] [] [] | - gpsdrive | () () [] () | - gramadoir | [] [] | - grep | [] [] [] [] [] [] [] [] [] [] [] [] | - gretl | [] [] [] | - gsasl | [] [] | - gss | [] | - gst-plugins | [] [] [] | - gst-plugins-base | [] [] | - gst-plugins-good | [] [] [] | - gstreamer | [] [] [] | - gtick | [] | - gtkam | [] [] [] [] | - gtkorphan | [] [] | - gtkspell | [] [] [] [] [] [] | - gutenprint | [] | - hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] [] [] | - impost | [] [] | - indent | [] [] [] [] [] [] [] [] [] [] | - iso_3166 | [] [] [] | - iso_3166_2 | [] | - iso_4217 | [] [] [] [] | - iso_639 | [] [] [] [] [] | - jpilot | [] [] | - jtag | [] | - jwhois | [] [] [] [] [] | - kbd | [] [] | - keytouch | [] | - keytouch-editor | [] | - keytouch-keyboa... | [] | - latrine | [] [] [] | - ld | [] [] | - leafpad | [] [] [] [] [] [] | - libc | [] [] [] [] [] | - libexif | [] | - libextractor | [] | - libgpewidget | [] [] [] [] [] | - libgpg-error | | - libgphoto2 | [] [] [] | - libgphoto2_port | [] [] | - libgsasl | [] [] | - libiconv | [] [] | - libidn | [] [] | - lifelines | () | - lilypond | [] | - lingoteach | [] [] [] | - lynx | [] [] [] | - m4 | [] [] [] [] | - mailutils | [] [] | - make | [] [] [] [] [] [] [] [] | - man-db | () | - minicom | [] [] [] [] | - mysecretdiary | [] [] [] | - nano | [] [] [] [] [] [] | - nano_1_0 | [] [] [] [] [] | - opcodes | [] [] [] [] | - parted | [] [] [] [] | - pilot-qof | | - psmisc | [] [] [] | - pwdutils | | - python | | - qof | [] | - radius | [] [] | - recode | [] [] [] [] [] [] [] [] | - rpm | [] [] | - screem | | - scrollkeeper | [] [] [] | - sed | [] [] [] [] [] | - sh-utils | [] [] [] [] [] [] [] | - shared-mime-info | [] [] [] [] [] [] | - sharutils | [] [] [] [] [] [] [] [] | - shishi | | - silky | [] | - skencil | [] [] | - sketch | [] [] | - solfege | [] | - soundtracker | [] [] [] | - sp | [] | - stardict | [] | - system-tools-ba... | [] [] [] [] [] [] [] [] | - tar | [] [] [] [] [] [] [] | - texinfo | [] [] | - textutils | [] [] [] [] [] | - tin | [] () | - tp-robot | [] [] [] [] | - tuxpaint | [] [] | - unicode-han-tra... | | - unicode-transla... | [] [] | - util-linux | [] [] [] [] [] [] [] | - vorbis-tools | [] [] | - wastesedge | () | - wdiff | [] [] [] [] [] [] [] [] | - wget | [] [] [] [] [] [] [] [] | - xchat | [] [] [] [] [] [] [] [] | - xkeyboard-config | [] [] [] [] | - xpad | [] [] [] | - +--------------------------------------------------+ - es et eu fa fi fr ga gl gu he hi hr hu id is it - 88 22 14 2 40 115 61 14 1 8 1 6 59 31 0 52 - - ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no - +-------------------------------------------------+ - GNUnet | | - a2ps | () [] [] () | - aegis | () | - ant-phone | [] | - anubis | [] [] [] | - ap-utils | [] | - aspell | [] [] | - bash | [] | - batchelor | [] [] | - bfd | | - bibshelf | [] | - binutils | | - bison | [] [] [] | - bison-runtime | [] [] [] | - bluez-pin | [] [] [] | - cflow | | - clisp | [] | - console-tools | | - coreutils | [] | - cpio | | - cpplib | [] | - cryptonit | [] | - darkstat | [] [] | - dialog | [] [] | - diffutils | [] [] [] | - doodle | | - e2fsprogs | [] | - enscript | [] | - error | [] | - fetchmail | [] [] | - fileutils | [] [] | - findutils | [] | - flex | [] [] | - fslint | [] [] | - gas | | - gawk | [] [] | - gbiff | [] | - gcal | | - gcc | | - gettext-examples | [] [] | - gettext-runtime | [] [] [] | - gettext-tools | [] [] | - gimp-print | [] [] | - gip | [] [] | - gliv | [] | - glunarclock | [] [] | - gmult | [] [] | - gnubiff | | - gnucash | () () | - gnucash-glossary | [] | - gnuedu | | - gnulib | [] [] [] [] | - gnunet-gtk | | - gnutls | | - gpe-aerial | [] | - gpe-beam | [] | - gpe-calendar | [] | - gpe-clock | [] [] [] | - gpe-conf | [] [] | - gpe-contacts | [] | - gpe-edit | [] [] [] | - gpe-filemanager | [] [] | - gpe-go | [] [] [] | - gpe-login | [] [] [] | - gpe-ownerinfo | [] [] | - gpe-package | [] [] | - gpe-sketchbook | [] [] | - gpe-su | [] [] [] | - gpe-taskmanager | [] [] [] [] | - gpe-timesheet | [] | - gpe-today | [] [] | - gpe-todo | [] | - gphoto2 | [] [] | - gprof | | - gpsdrive | () () () | - gramadoir | () | - grep | [] [] [] [] | - gretl | | - gsasl | [] | - gss | | - gst-plugins | [] | - gst-plugins-base | | - gst-plugins-good | [] | - gstreamer | [] | - gtick | | - gtkam | [] | - gtkorphan | [] | - gtkspell | [] [] | - gutenprint | | - hello | [] [] [] [] [] [] | - id-utils | [] | - impost | | - indent | [] [] | - iso_3166 | [] | - iso_3166_2 | [] | - iso_4217 | [] [] [] | - iso_639 | [] [] | - jpilot | () () () | - jtag | | - jwhois | [] | - kbd | [] | - keytouch | [] | - keytouch-editor | | - keytouch-keyboa... | | - latrine | [] | - ld | | - leafpad | [] [] | - libc | [] [] [] [] [] | - libexif | | - libextractor | | - libgpewidget | [] | - libgpg-error | | - libgphoto2 | [] | - libgphoto2_port | [] | - libgsasl | [] | - libiconv | | - libidn | [] [] | - lifelines | [] | - lilypond | | - lingoteach | [] | - lynx | [] [] | - m4 | [] [] | - mailutils | | - make | [] [] [] | - man-db | () | - minicom | [] | - mysecretdiary | [] | - nano | [] [] [] | - nano_1_0 | [] [] [] | - opcodes | [] | - parted | [] [] | - pilot-qof | | - psmisc | [] [] [] | - pwdutils | | - python | | - qof | | - radius | | - recode | [] | - rpm | [] [] | - screem | [] | - scrollkeeper | [] [] [] [] | - sed | [] [] | - sh-utils | [] [] | - shared-mime-info | [] [] [] [] [] | - sharutils | [] [] | - shishi | | - silky | [] | - skencil | | - sketch | | - solfege | | - soundtracker | | - sp | () | - stardict | [] [] | - system-tools-ba... | [] [] [] [] | - tar | [] [] [] | - texinfo | [] [] [] | - textutils | [] [] [] | - tin | | - tp-robot | [] | - tuxpaint | [] | - unicode-han-tra... | | - unicode-transla... | | - util-linux | [] [] | - vorbis-tools | [] | - wastesedge | [] | - wdiff | [] [] | - wget | [] [] | - xchat | [] [] [] [] | - xkeyboard-config | [] | - xpad | [] [] [] | - +-------------------------------------------------+ - ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no - 52 24 2 2 1 3 0 2 3 21 0 15 1 97 5 1 - - nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta - +------------------------------------------------------+ - GNUnet | | - a2ps | () [] [] [] [] [] [] | - aegis | () () | - ant-phone | [] [] | - anubis | [] [] [] | - ap-utils | () | - aspell | [] [] | - bash | [] [] [] | - batchelor | [] [] | - bfd | | - bibshelf | [] | - binutils | [] [] | - bison | [] [] [] [] [] | - bison-runtime | [] [] [] [] | - bluez-pin | [] [] [] [] [] [] [] [] [] | - cflow | [] | - clisp | [] | - console-tools | [] | - coreutils | [] [] [] [] | - cpio | [] [] [] | - cpplib | [] | - cryptonit | [] [] | - darkstat | [] [] [] [] [] [] | - dialog | [] [] [] [] [] [] [] [] [] | - diffutils | [] [] [] [] [] [] | - doodle | [] [] | - e2fsprogs | [] [] | - enscript | [] [] [] [] [] | - error | [] [] [] [] | - fetchmail | [] [] [] | - fileutils | [] [] [] [] [] | - findutils | [] [] [] [] [] [] | - flex | [] [] [] [] [] | - fslint | [] [] [] [] | - gas | | - gawk | [] [] [] [] | - gbiff | [] | - gcal | [] | - gcc | [] | - gettext-examples | [] [] [] [] [] [] [] [] | - gettext-runtime | [] [] [] [] [] [] [] [] | - gettext-tools | [] [] [] [] [] [] [] | - gimp-print | [] [] | - gip | [] [] [] [] | - gliv | [] [] [] [] | - glunarclock | [] [] [] [] [] [] | - gmult | [] [] [] [] | - gnubiff | () | - gnucash | () [] | - gnucash-glossary | [] [] [] | - gnuedu | | - gnulib | [] [] [] [] [] | - gnunet-gtk | [] | - gnutls | [] [] | - gpe-aerial | [] [] [] [] [] [] [] | - gpe-beam | [] [] [] [] [] [] [] | - gpe-calendar | [] | - gpe-clock | [] [] [] [] [] [] [] [] | - gpe-conf | [] [] [] [] [] [] [] | - gpe-contacts | [] [] [] [] [] | - gpe-edit | [] [] [] [] [] [] [] [] | - gpe-filemanager | [] [] | - gpe-go | [] [] [] [] [] [] | - gpe-login | [] [] [] [] [] [] [] [] | - gpe-ownerinfo | [] [] [] [] [] [] [] [] | - gpe-package | [] [] | - gpe-sketchbook | [] [] [] [] [] [] [] [] | - gpe-su | [] [] [] [] [] [] [] [] | - gpe-taskmanager | [] [] [] [] [] [] [] [] | - gpe-timesheet | [] [] [] [] [] [] [] [] | - gpe-today | [] [] [] [] [] [] [] [] | - gpe-todo | [] [] [] [] | - gphoto2 | [] [] [] [] [] | - gprof | [] [] [] | - gpsdrive | [] [] [] | - gramadoir | [] [] | - grep | [] [] [] [] [] [] [] [] | - gretl | [] | - gsasl | [] [] [] | - gss | [] [] [] | - gst-plugins | [] [] [] [] | - gst-plugins-base | [] | - gst-plugins-good | [] [] [] [] | - gstreamer | [] [] [] | - gtick | [] | - gtkam | [] [] [] [] | - gtkorphan | [] | - gtkspell | [] [] [] [] [] [] [] [] | - gutenprint | [] | - hello | [] [] [] [] [] [] [] [] | - id-utils | [] [] [] [] | - impost | [] | - indent | [] [] [] [] [] [] | - iso_3166 | [] [] [] [] [] [] | - iso_3166_2 | | - iso_4217 | [] [] [] [] | - iso_639 | [] [] [] [] | - jpilot | | - jtag | [] | - jwhois | [] [] [] [] | - kbd | [] [] [] | - keytouch | [] | - keytouch-editor | [] | - keytouch-keyboa... | [] | - latrine | [] [] | - ld | [] | - leafpad | [] [] [] [] [] [] | - libc | [] [] [] [] [] | - libexif | [] | - libextractor | [] [] | - libgpewidget | [] [] [] [] [] [] [] | - libgpg-error | [] [] | - libgphoto2 | [] | - libgphoto2_port | [] [] [] | - libgsasl | [] [] [] [] | - libiconv | [] [] | - libidn | [] [] () | - lifelines | [] [] | - lilypond | | - lingoteach | [] | - lynx | [] [] [] | - m4 | [] [] [] [] [] | - mailutils | [] [] [] [] | - make | [] [] [] [] | - man-db | [] [] | - minicom | [] [] [] [] [] | - mysecretdiary | [] [] [] [] | - nano | [] [] [] | - nano_1_0 | [] [] [] [] | - opcodes | [] [] | - parted | [] | - pilot-qof | [] | - psmisc | [] [] | - pwdutils | [] [] | - python | | - qof | [] [] | - radius | [] [] | - recode | [] [] [] [] [] [] [] | - rpm | [] [] [] [] | - screem | | - scrollkeeper | [] [] [] [] [] [] [] | - sed | [] [] [] [] [] [] [] [] [] | - sh-utils | [] [] [] | - shared-mime-info | [] [] [] [] [] | - sharutils | [] [] [] [] | - shishi | [] | - silky | [] | - skencil | [] [] [] | - sketch | [] [] [] | - solfege | [] | - soundtracker | [] [] | - sp | | - stardict | [] [] [] | - system-tools-ba... | [] [] [] [] [] [] [] [] [] | - tar | [] [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] [] | - tin | () | - tp-robot | [] | - tuxpaint | [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | | - util-linux | [] [] [] [] | - vorbis-tools | [] [] | - wastesedge | | - wdiff | [] [] [] [] [] [] | - wget | [] [] [] [] | - xchat | [] [] [] [] [] [] [] | - xkeyboard-config | [] [] | - xpad | [] [] [] | - +------------------------------------------------------+ - nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta - 0 2 3 58 30 54 5 73 72 4 40 46 11 50 128 2 - - tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu - +---------------------------------------------------+ - GNUnet | [] | 2 - a2ps | [] [] [] | 19 - aegis | | 0 - ant-phone | [] [] | 6 - anubis | [] [] [] | 11 - ap-utils | () [] | 4 - aspell | [] [] [] | 15 - bash | [] | 11 - batchelor | [] [] | 9 - bfd | | 1 - bibshelf | [] | 7 - binutils | [] [] [] | 9 - bison | [] [] [] | 19 - bison-runtime | [] [] [] | 15 - bluez-pin | [] [] [] [] [] [] | 28 - cflow | [] [] | 5 - clisp | | 6 - console-tools | [] [] | 5 - coreutils | [] [] | 16 - cpio | [] [] [] | 9 - cpplib | [] [] [] [] | 11 - cryptonit | | 5 - darkstat | [] () () | 15 - dialog | [] [] [] [] [] | 30 - diffutils | [] [] [] [] | 28 - doodle | [] | 6 - e2fsprogs | [] [] | 10 - enscript | [] [] [] | 16 - error | [] [] [] [] | 18 - fetchmail | [] [] | 12 - fileutils | [] [] [] | 18 - findutils | [] [] [] | 17 - flex | [] [] | 15 - fslint | [] | 9 - gas | [] | 3 - gawk | [] [] | 15 - gbiff | [] | 5 - gcal | [] | 5 - gcc | [] [] [] | 6 - gettext-examples | [] [] [] [] [] [] | 27 - gettext-runtime | [] [] [] [] [] [] | 28 - gettext-tools | [] [] [] [] [] | 19 - gimp-print | [] [] | 12 - gip | [] [] | 12 - gliv | [] [] | 8 - glunarclock | [] [] [] | 15 - gmult | [] [] [] [] | 15 - gnubiff | [] | 1 - gnucash | () | 2 - gnucash-glossary | [] [] | 9 - gnuedu | [] | 2 - gnulib | [] [] [] [] [] | 28 - gnunet-gtk | | 1 - gnutls | | 2 - gpe-aerial | [] [] | 14 - gpe-beam | [] [] | 14 - gpe-calendar | [] | 3 - gpe-clock | [] [] [] [] | 21 - gpe-conf | [] [] | 14 - gpe-contacts | [] [] | 10 - gpe-edit | [] [] [] [] | 20 - gpe-filemanager | [] | 6 - gpe-go | [] [] | 15 - gpe-login | [] [] [] [] [] | 21 - gpe-ownerinfo | [] [] [] [] | 21 - gpe-package | [] | 6 - gpe-sketchbook | [] [] | 16 - gpe-su | [] [] [] | 20 - gpe-taskmanager | [] [] [] | 20 - gpe-timesheet | [] [] [] [] | 18 - gpe-today | [] [] [] [] [] | 21 - gpe-todo | [] | 7 - gphoto2 | [] [] [] [] | 20 - gprof | [] [] | 11 - gpsdrive | | 4 - gramadoir | [] | 7 - grep | [] [] [] [] | 34 - gretl | | 4 - gsasl | [] [] | 8 - gss | [] | 5 - gst-plugins | [] [] [] | 15 - gst-plugins-base | [] [] [] | 9 - gst-plugins-good | [] [] [] [] [] | 20 - gstreamer | [] [] [] | 17 - gtick | [] | 3 - gtkam | [] | 13 - gtkorphan | [] | 7 - gtkspell | [] [] [] [] [] [] | 26 - gutenprint | | 3 - hello | [] [] [] [] [] | 37 - id-utils | [] [] | 14 - impost | [] | 4 - indent | [] [] [] [] | 25 - iso_3166 | [] [] [] [] | 16 - iso_3166_2 | | 2 - iso_4217 | [] [] | 14 - iso_639 | [] | 14 - jpilot | [] [] [] [] | 7 - jtag | [] | 3 - jwhois | [] [] [] | 13 - kbd | [] [] | 12 - keytouch | [] | 4 - keytouch-editor | | 2 - keytouch-keyboa... | [] | 3 - latrine | [] [] | 8 - ld | [] [] [] [] | 8 - leafpad | [] [] [] [] | 23 - libc | [] [] [] | 23 - libexif | [] | 4 - libextractor | [] | 5 - libgpewidget | [] [] [] | 19 - libgpg-error | [] | 4 - libgphoto2 | [] | 8 - libgphoto2_port | [] [] [] | 11 - libgsasl | [] | 8 - libiconv | [] | 7 - libidn | [] [] | 10 - lifelines | | 4 - lilypond | | 2 - lingoteach | [] | 6 - lynx | [] [] [] | 15 - m4 | [] [] [] | 18 - mailutils | [] | 8 - make | [] [] [] | 20 - man-db | [] | 6 - minicom | [] | 14 - mysecretdiary | [] [] | 12 - nano | [] [] | 17 - nano_1_0 | [] [] [] | 18 - opcodes | [] [] | 10 - parted | [] [] [] | 10 - pilot-qof | [] | 3 - psmisc | [] | 10 - pwdutils | [] | 3 - python | | 0 - qof | [] | 4 - radius | [] | 6 - recode | [] [] [] | 25 - rpm | [] [] [] [] | 14 - screem | [] | 2 - scrollkeeper | [] [] [] [] | 26 - sed | [] [] [] | 22 - sh-utils | [] | 15 - shared-mime-info | [] [] [] [] | 24 - sharutils | [] [] [] | 23 - shishi | | 1 - silky | [] | 4 - skencil | [] | 7 - sketch | | 6 - solfege | | 2 - soundtracker | [] [] | 9 - sp | [] | 3 - stardict | [] [] [] [] | 11 - system-tools-ba... | [] [] [] [] [] [] [] | 37 - tar | [] [] [] [] | 20 - texinfo | [] [] [] | 15 - textutils | [] [] [] | 17 - tin | | 1 - tp-robot | [] [] [] | 10 - tuxpaint | [] [] [] | 16 - unicode-han-tra... | | 0 - unicode-transla... | | 2 - util-linux | [] [] [] | 20 - vorbis-tools | [] [] | 11 - wastesedge | | 1 - wdiff | [] [] | 22 - wget | [] [] [] | 19 - xchat | [] [] [] [] | 29 - xkeyboard-config | [] [] [] [] | 11 - xpad | [] [] [] | 14 - +---------------------------------------------------+ - 77 teams tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu - 170 domains 0 1 1 77 39 0 136 10 1 48 5 54 0 2028 - - Some counters in the preceding matrix are higher than the number of -visible blocks let us expect. This is because a few extra PO files are -used for implementing regional variants of languages, or language -dialects. - - For a PO file in the matrix above to be effective, the package to -which it applies should also have been internationalized and -distributed as such by its maintainer. There might be an observable -lag between the mere existence a PO file and its wide availability in a -distribution. - - If October 2006 seems to be old, you may fetch a more recent copy of -this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date -matrix with full percentage details can be found at -`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. - -1.6 Using `gettext' in new packages -=================================== - -If you are writing a freely available program and want to -internationalize it you are welcome to use GNU `gettext' in your -package. Of course you have to respect the GNU Library General Public -License which covers the use of the GNU `gettext' library. This means -in particular that even non-free programs can use `libintl' as a shared -library, whereas only free software can use `libintl' as a static -library or use modified versions of `libintl'. - - Once the sources are changed appropriately and the setup can handle -the use of `gettext' the only thing missing are the translations. The -Free Translation Project is also available for packages which are not -developed inside the GNU project. Therefore the information given above -applies also for every other Free Software Project. Contact -`translation@iro.umontreal.ca' to make the `.pot' files available to -the translation teams. - diff --git a/contrib/cpio/AUTHORS b/contrib/cpio/AUTHORS deleted file mode 100644 index 980c8f397b8..00000000000 --- a/contrib/cpio/AUTHORS +++ /dev/null @@ -1,6 +0,0 @@ -Authors of GNU cpio - -Phil Nelson -David MacKenzie -John Oleynick -Sergey Poznyakoff \ No newline at end of file diff --git a/contrib/cpio/COPYING b/contrib/cpio/COPYING deleted file mode 100644 index 5c95a60a711..00000000000 --- a/contrib/cpio/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/contrib/cpio/ChangeLog b/contrib/cpio/ChangeLog deleted file mode 100644 index 1307353cba8..00000000000 --- a/contrib/cpio/ChangeLog +++ /dev/null @@ -1,1781 +0,0 @@ -2007-06-08 Sergey Poznyakoff - - * configure.ac, NEWS: Version number 2.8 - * bootstrap.conf: Update - -2007-06-07 Sergey Poznyakoff - - * NEWS: Update - * configure.ac: Raise version to 2.7.90 - * doc/cpio.texi: Update - * src/extern.h (set_perms, set_file_times): Take file descriptor - as the first argument. - * src/util.c (set_perms): Take file descriptor - as the first argument and use fchmod/fchown if available. Fixes - CAN-2005-1111. - * src/copyin.c, src/copyout.c, src/copypass.c: Update calls to - set_perms. - * src/makepath.c: Remove useless includes. - - * src/util.c (set_perms, stat_to_cpio): Use CPIO_UID and CPIO_GID - macros to set uid and gid - * src/main.c (process_args): Allow to use --owner in copy-out mode. - * THANKS: Add Mike Frysinger - -2007-05-18 Sergey Poznyakoff - - * bootstrap: Update from tar repository - * doc/cpio.texi: Fix typo - * src/copyin.c (from_ascii): Bugfix: allow for empty fields - * src/copyout.c (process_copy_out): Fix memory leaks on - orig_file_name. - * src/copypass.c (process_copy_pass): symlink_error takes two - arguments. - * src/extern.h: Add missing includes. - -2006-12-18 Sergey Poznyakoff - - * README-cvs: New file - * lib/Makefile.tmpl, lib/bcopy.c, lib/mkdir.c, lib/strdup.c, - lib/strerror.c, lib/.cvsignore, po/.cvsignore, - po/Makevars: Removed - * lib/Makefile.am: New file - * po/POTFILES.in: Update - * bootstrap: Synch with tar. - * configure.ac: Update - * gnulib.modules: Add lchown, strerror - * src/Makefile.am: Update - * src/main.c, src/mt.c: Include rmt-command.h instead of localedir.h - * .cvsignore, doc/.cvsignore: Sort - - * src/util.c (sparse_write): Static. Provide a forward - declaration. Define enum sparse_write_states inside the function. - - * src/copyin.c (long_format): Use PRIuMAX for printing file size - * src/copyout.c (write_out_binary_header): Fix size conversion - * src/extern.h (tape_toss_input, warn_if_file_changed): Last - argument is off_t - * src/util.c (tape_toss_input, warn_if_file_changed): Last - argument is off_t - (warn_if_file_changed): Use ngettext - -2006-11-15 Sergey Poznyakoff - - * src/copypass.c: Fix setting output file permissions - -2006-11-13 Sergey Poznyakoff - - * doc/cpio.texi: Consistently use @option{} for displaying command - line options. - Fix formatting in "Invoking `cpio'" section - * src/main.c (process_args): Fix usage error diagnostics in - copy-pass mode. - -2006-10-24 Sergey Poznyakoff - - * src/copyout.c (process_copy_out): Add terminating zero to the - link_name. - - * tests/symlink.at: New testcase - * tests/Makefile.am: New test symlink.at - * tests/inout.at: Add keywords - * tests/testsuite.at (AT_SKIP_TEST): New macro - New test symlink.at - -2006-10-21 Sergey Poznyakoff - - * configure.ac, NEWS: Version 2.7 - * gnulib.modules: Add stdint - * src/util.c: Use STRINGIFY_BIGINT to display num_bytes - -2006-09-27 Sergey Poznyakoff - - * TODO: Update - * README-alpha: Update - * bootstrap: Imported from tar - * configure.ac: Require autoconf 2.59 and gettext 1.15 - * gnulib.modules: add inttypes - * doc/cpio.texi: Minor fixes - * po/Makevars: Remove automatically generated file - * po/.cvsignore: Add Makevars - * lib/.cvsignore: Update - * src/copyin.c, src/copyout.c, src/copypass.c, src/cpio.h, - src/cpiohdr.h, src/defer.c, src/defer.h, src/extern.h, - src/global.c, src/main.c, src/makepath.c, src/tar.c, - src/util.c: Update copyright year. - -2006-07-04 Sergey Poznyakoff - - * bootstrap (update_po): Fix single translation update - * lib/Makefile.tmpl: Initialize AM_CPPFLAGS - (noinst_HEADERS): Add system-ioctl.h - - Start rewriting using a better suited internal representation for - the file meta-data. - - * src/cpiohdr.h (struct old_cpio_header): Remove unused fields - c_mtime, c_filesize and c_name. - (struct old_ascii_header): New data type - (struct new_ascii_header): New data type. Describes the header - structure, not its internal representation. - (struct cpio_file_stat): New data type. Describes internal - representation of a file metadata - - * src/copyin.c (from_ascii): New function - Use cpio_file_stat for internal header representation. - * src/copyout.c: Use cpio_file_stat for internal header - representation. Among other things this fixes bug reported by - Peter Vrabec on Mar 2, 2006 - (http://lists.gnu.org/archive/html/bug-cpio/2006-03/msg00000.html) - * src/copypass.c: Use cpio_file_stat for internal header - representation. - * src/tar.c: Likewise - * src/util.c: Likewise - * src/defer.c: Likewise - * src/defer.h: Likewise - * src/extern.h: Likewise - (from_ascii): New prototype - (LG_8,LG_16,FROM_OCTAL,FROM_HEX): New defines - * src/main.c: New command line option --HANG (hidden) - -2006-03-12 Sergey Poznyakoff - - * tests/Makefile.am (AM_CPPFLAGS): Define LOCALEDIR - -2006-02-18 Sergey Poznyakoff - - * gnulib.modules: Add stpcpy. Thanks Benigno B. Junior for - reporting. - * THANKS: Add Benigno B. Junior - * src/makepath.c: Fix indentation. - -2005-11-16 Sergey Poznyakoff - - * src/copyout.c (process_copy_out): Fix typo. - -2005-11-12 Sergey Poznyakoff - - * bootstrap: Minor fix - * src/copyout.c (write_out_header): Rewritten using separate - functions for each file format. Use to_ascii to convert numbers to - ascii representation. Check for overflows and report them if - appropriate. Return 0 if it is OK to proceed with archiving this - file, 1 otherwise. All callers updated. - * src/extern.h (write_out_header): Return int. - -2005-10-28 Sergey Poznyakoff - - * src/util.c: Include paxlib. - * bootstrap: If file `.bootstrap' exists in the cwd and is - readable, prepend its contents to the command line. - - Fix Debian bug 335580: - - * src/copyout.c (read_for_checksum,write_out_header): CRC is a - 32-bit unsigned value. Patch proposed by Jim Castleberry and - Peter Vrabec. - * src/extern.h (crc): Change declaration - * src/global.c: Likewise - * src/tar.c (tar_checksum): Return unsigned int - - * THANKS: Add Jim Castleberry - * NEWS: Updated - -2005-09-30 Sergey Poznyakoff - - * src/copyout.c (process_copy_out): Discern between original and - (eventually fixed) file name (in tar terminology, `file name' - vs. `member name'. - -2005-09-08 Sergey Poznyakoff - - * gnulib.modules: Add utimens - * src/util.c (cpio_safer_name_suffix): Preserve ./ no matter what - the value of strip_leading_dots is. - (set_file_times): New function - * src/extern.h (set_file_times): New function - * src/copyin.c: Use set_file_times() to update file atime/mtime - * src/copyout.c: Likewise. - * src/copypass.c: Likewise. - -2005-05-25 Sergey Poznyakoff - - * src/copyin.c: Use cpio_safer_name_suffix() and CPIO_TRAILER_NAME - define instead of hardcoding the trailer file name. - * src/copyout.c: Likewise. - * src/cpio.h (CPIO_TRAILER_NAME): New define - * src/extern.h (cpio_safer_name_suffix): New proto - * src/tar.c: Use CPIO_TRAILER_NAME define instead of hardcoding - the trailer file name. - * src/util.c (cpio_safer_name_suffix): New function - (add_cdf_double_slashes): Add FIXME warning. - - * lib/fatal.c: New file - * lib/Makefile.tmpl (libcpio_a_SOURCES): Add fatal.c - * src/copyout.c: Use error reporting functions from paxlib - * src/makepath.c: Likewise - * src/mt.c: Likewise - * src/main.c (fatal_exit): Moved to lib/fatal.c - -2005-05-24 Sergey Poznyakoff - - * src/copyin.c (process_copy_in): Use safer_name_suffix no matter - what the value of no_abs_paths_flag. The function knows better - what to do in any case. - * src/copyout.c (process_copy_out): Honor no_abs_paths_flag. - * src/main.c (options): Minor fixes. - -2005-05-23 Sergey Poznyakoff - - * bootstrap (copy_files): Create destination directory if it does - not exist. - Preserve longlong.m4 as longlong_gl.m4 - * src/main.c: Include paxlib.h - -2005-05-22 Sergey Poznyakoff - - * lib/.cvsignore: Updated - * gnulib.modules: Add hash - * doc/cpio.texi (Reports): New chapter - * lib/Makefile.tmpl: Add new paxutils files. - * po/POTFILES.in: Likewise - * src/copyin.c [!HAVE_LCHOWN] (lchown): Define to 0 to avoid - changing ownership of the target file. - (process_copy_in): Use safer_name_suffix() - * src/main.c (parse_opt): Handle new --absolute-filenames option. - (process_args): Updated - * src/util.c: Rewrite inode lookup/insertion functions using hash - module. - -u2005-05-20 Sergey Poznyakoff - - * configure.ac: Raised version number to 2.6.90 - * NEWS: Updated - * src/copyin.c: Use set_perms. - * src/copypass.c: Likewise. - * src/copyout.c (process_copy_out): Use stat_to_cpio() to convert - struct stat to struct new_cpio_header. - * src/defer.h: Remove legacy P_() stuff. - * src/dstring.c: Likewise - * src/extern.h: Likewise - * src/util.c (stat_to_cpio,set_perms): New functions - * doc/.cvsignore: Updated - * lib/.cvsignore: Updated - * tests/.cvsignore: Updated - * .cvsignore: Updated - * COPYING: Added to the repository - -2005-05-19 Sergey Poznyakoff - - * po/POTFILES.in: Add paxerror.c paxexit.c paxconvert.c - - * bootstrap (copy_files): Accept optional third argument: a prefix - to be appended to destination file names. - Import paxutils/paxlib files. - * lib/Makefile.tmpl (libcpio_a_SOURCES): Add paxerror.c paxexit.c - paxconvert.c - * src/copyin.c: Use paxutils error reporting functions - * src/copyout.c: Likewise - * src/copypass.c: Likewise - * src/util.c: Likewise. Add missing includes - * src/main.c (USAGE_ERROR): Removed - (CHECK_USAGE,parse_opt,process_args): Use error() instead of USAGE_ERROR - (fatal_exit): New function - * src/tar.c (is_tar_filename_too_long): Removed unused variable - - * Makefile.am, configure.ac, doc/Makefile.am, - doc/cpio.texi, doc/gendocs_template, headers/Makefile.am, - headers/fnmatch.h, lib/Makefile.tmpl, lib/mkdir.c, - lib/strdup.c, lib/strerror.c, src/Makefile.am, - src/copyin.c, src/copyout.c, src/copypass.c, src/cpio.h, - src/cpiohdr.h, src/defer.c, src/defer.h, src/dstring.c, - src/dstring.h, src/extern.h, src/filemode.c, - src/filetypes.h, src/global.c, src/idcache.c, - src/main.c, src/makepath.c, src/mt.c, src/tar.c, - src/tar.h, src/tarhdr.h, src/userspec.c, src/util.c, - tests/Makefile.am, tests/inout.at, tests/testsuite.at, - tests/version.at: Updated FSF postal mail address. - - * bootstrap: Port recent changes from tar bootstrap. - * gnulib.modules: New file - * tests/Makefile.am (genfile_SOURCES,LDADD): Updated - - * THANKS: Updated - * configure.ac: Remove check for gethostname, it is never used. - Remove check for setsockopt, it is provided by paxutils. - - Fix LFS support issues. Proposed by Peter Vrabec and Dmitry V. Levin - - * src/extern.h (copy_files_tape_to_disk, copy_files_disk_to_tape, - copy_files_disk_to_disk): Change num_bytes argument type from - long to off_t. - * src/util.c (copy_files_tape_to_disk, copy_files_disk_to_tape, - copy_files_disk_to_disk, disk_fill_input_buffer, - write_nuls_to_file): Likewise. - (write_nuls_to_file, copy_files_disk_to_tape, - copy_files_disk_to_disk): Handle `off_t num_bytes' properly. - - * src/util.c (find_inode_file): Fix typos causing function to - occasionally miss inodes and, therefore, to copy out the same - (hard-linked) file several times to archive. Proposed by Brian - Mays. - -2005-03-24 Sergey Poznyakoff - - * src/main.c (process_args): Fixed discrepancy I have been - overlooking so far: cpio still does not handle --sparse option - the same way tar is handling it. --sparse is allowed in copy-in - and copy-pass modes, just as docs say it. Thanks Dmitry Levin. - * THANKS: Updated - -2005-03-21 Sergey Poznyakoff - - * src/util.c (disk_buffered_write): Fix typo introduced - 2005-01-11. - * src/main.c (process_args): Fixed error message - -2005-01-31 Sergey Poznyakoff - - * src/main.c (main): Remove umask(0). Fixes CAN-1999-1572. - [__TURBOC__,__EMX__]: Removed - * src/copypass.c (process_copy_pass): Set umask 0 - * src/copyin.c (process_copy_in): Likewise - * src/util.c (open_archive): Use MODE_RW. - -2005-01-11 Sergey Poznyakoff - - * doc/gendocs_template: Template file for gendocs.sh. - * doc/Makefile.am: Use gendocs.sh to generate webdocs. - * doc/cpio.texi: Updated. - - * src/copyin.c: Use memset instead of bzero, memmove - (or memcpy, if appropriate), instead of bcopy, and - strchr/strrchr instead of index/rindex. - * src/copypass.c: Likewise. - * src/main.c: Likewise. - * src/makepath.c: Likewise. - * src/tar.c: Likewise. - * src/util.c: Likewise. - (write_nuls_to_file): Made extern. All callers updated - - * src/copyout.c: Likewise. Use write_nuls_to_file instead - of explicitely accessing zeros_512 - * src/userspec.c: Likewise. - Rename isnumber to isnumber_p. Proposed by - Albert Chin - * src/extern.h (zeros_512): Removed - (write_nuls_to_file): New function - * src/global.c (zeros_512): Removed - -2005-01-06 Sergey Poznyakoff - - * bootstrap: Add 'fileblocks' gnulib module - Create paxutils.m4 - * configure.ac: Call cpio_PAXUTILS - * src/main.c: Remove ifdef around setlocale - * src/mt.c: Likewise - -2004-12-21 Sergey Poznyakoff - - * configure.ac: New option --enable-mt - Check for locale.h - * doc/cpio.info: Removed - * src/mt.c (main): Use argmatch_invalid() - -2004-12-20 Sergey Poznyakoff - - Released version 2.6. Sources up to this point are tagged - release_2_6. - - * configure.ac: Raised version number to 2.6 - * NEWS: Likewise - * bootstrap (update_po): Give -r to wget. Always remove index.html - Ignore alloca-opt module (it duplicates alloca) - -2004-11-23 Sergey Poznyakoff - - * src/main.c (enum cpio_options): Bugfix: Initialize first enum - value to 256. - * bootstrap: Add unlocked-io - * headers/argp.h: Removed - * headers/getopt.h: Removed - * headers/Makefile.am: Updated - -2004-10-14 Sergey Poznyakoff - - * src/copyout.c: Add trailing slash to directory names in - ustar format. - * src/makepath.c: Removed redeclaration of error(). - * src/tar.c: Fixed deviations from POSIX.1-1988: - Properly split long file names. Fill in octal fields with zeros, - not spaces. Save only protection modes, not the whole mode. - - * NEWS: Updated - -2004-09-08 Sergey Poznyakoff - - * NEWS: Updated - * TODO: Updated - * bootstrap: Install po files by default - * po/LINGUAS: Removed. File is generated automatically - * po/.cvsignore: Updated - * src/copyin.c: Implemented --to-stdout option - * src/copyout.c: Display the annoying 'truncating inode number' - message only if the user wishes it. - * src/extern.h: Added new globals. - * src/global.c: Likewise. - - * src/main.c: Added support for --to-stdout and --warning options - * src/tar.c (read_in_tar_header): Use warn_junk_bytes() - * src/util.c (create_all_directories): Use dir_name. - - * configure.ac: Added support for the test suite - * Makefile.am: Likewise - - * tests: New directory - * tests/.cvsignore: New file - * tests/Makefile.am: New file - * tests/testsuite.at: New file - * tests/inout.at: New file - * tests/version.at: New file - * tests/atlocal.in: New file - -2004-09-07 Sergey Poznyakoff - - * src/main.c (process_args): Bugfix. Allow extra arguments - in copy_in mode. - * src/util.c (write_nuls_to_file): Use buffered I/O. All - callers changed. Thanks Matthew Braithwaite - for noticing. - Bugfix: extra_bytes was mistakenly used instead of blocks. - * THANKS: Added Matthew Braithwaite. - -2004-09-06 Sergey Poznyakoff - - Started merging with tar into paxutils. Sources before - this point are tagged alpha-2_50_90. - - * bootstrap: New file - * autogen.sh: Removed - * Makefile.am: Updated - * NEWS: Updated - * README-alpha: Updated - * configure.ac: Updated - * doc/cpio.1: Updated - * po/POTFILES.in: Updated - - * src/Makefile.am: Updated - * src/error.c: Removed - * src/dirname.c: Likewise - * src/xmalloc.c: Likewise - * src/stripslash.c: Likewise - * src/xstrdup.c - * src/gettext.h: Likewise - * src/system.h: Likewise - * src/rmt.h: Likewise - * src/getopt.c: Likewise - * src/getopt1.c: Likewise - * src/bcopy.c: Likewise - * src/fnmatch.c: Likewise - * src/mkdir.c: Likewise - * src/strdup.c: Likewise - * src/argp-ba.c: Likewise - * src/argp-eexst.c: Likewise - * src/argp-fmtstream.c: Likewise - * src/argp-fs-xinl.c: Likewise - * src/argp-help.c: Likewise - * src/argp-parse.c: Likewise - * src/argp-pv.c: Likewise - * src/argp-pvh.c: Likewise - * src/argp-xinl.c: Likewise - * src/pin.c: Likewise - * src/alloca.c: Likewise - * src/argmatch.c: Likewise - * src/rmt.c: Likewise - * src/rtapelib.c: Likewise - * src/strerror.c: Likewise - - * src/copyin.c: Switched to ANSI C (sigh) - * src/copyout.c: Likewise - * src/copypass.c: Likewise - * src/defer.c: Likewise - * src/defer.h: Likewise - * src/dstring.c: Likewise - * src/dstring.h: Likewise - * src/extern.h: Likewise - * src/filemode.c: Likewise - * src/global.c: Likewise - * src/idcache.c: Likewise - * src/main.c: Likewise - * src/makepath.c: Likewise - * src/mt.c: Likewise - * src/tar.c: Likewise - * src/userspec.c: Likewise - * src/util.c: Likewise - - * lib: New directory - * lib/Makefile.tmpl: New file - * lib/bcopy.c: Moved from ../src - * lib/mkdir.c: Likewise. - * lib/strdup.c: Likewise. - * lib/strerror.c: Likewise. - -2004-08-30 Sergey Poznyakoff - - * Makefile.am: Added headers to SUBDIRS. - * configure.ac: Check for AC_SYS_LARGEFILE. - Use AC_CONFIG_LINKS to provide for fnmatch.h and getopt.h on - the systems where these are missing - Check for argp and replace it if necessary. - * src/Makefile.am: Updated - * src/fnmatch.h: Moved to headers/ - * src/getopt.h: Likewise. - * src/main.c: Option parsing rewritten using argp. Improved - option consistency checking. - * src/rmt.c: Include getopt.h - - * src/argp-ba.c: New file - * src/argp-eexst.c: New file - * src/argp-fmtstream.c: New file - * src/argp-fs-xinl.c: New file - * src/argp-help.c: New file - * src/argp-parse.c: New file - * src/argp-pv.c: New file - * src/argp-pvh.c: New file - * src/argp-xinl.c: New file - * src/pin.c: New file - - * headers: New directory - * headers/Makefile.am: New file - * headers/getopt.h: New file - * headers/argp.h: New file - * headers/fnmatch.h: New file - * headers/.cvsignore: New file - -2004-03-02 Sergey Poznyakoff - - * src/util.c (copy_files_disk_to_disk): Bugfix. If a file - grew n bytes in copy-pass mode, these n bytes got prepended - to the contents of all subsequent files. Fix provided by - Holger Fleischmann - * THANKS: Added Holger Fleischmann. - -2004-02-27 Sergey Poznyakoff - - * src/makepath.c: Remove unneded typedefs - - * src/copyin.c: Remove __MSDOS__ conditionals - * src/copyout.c: Likewise - * src/copypass.c: Likewise - * src/main.c: Likewise - * src/tar.c: Likewise - * src/util.c: Likewise - -2004-02-27 Sergey Poznyakoff - - Changed from flat to deep package layout. Added the framework - for NLS support. - - * .cvsignore: Updated - * Makefile.am: Updated - * configure.ac: Updated - * NEWS: Updated - * README-alpha: Updated - * THANKS: Updated - - * autogen.sh: New file - - * alloca.c: Moved to src - * argmatch.c: Likewise - * bcopy.c: Likewise - * dstring.h: Likewise - * copyin.c: Likewise - * copyout.c: Likewise - * copypass.c: Likewise - * cpio.h: Likewise - * cpiohdr.h: Likewise - * defer.c: Likewise - * defer.h: Likewise - * dirname.c: Likewise - * dstring.c: Likewise - * dstring.h: Likewise - * error.c: Likewise - * extern.h: Likewise - * filemode.c: Likewise - * filetypes.h: Likewise - * fnmatch.c: Likewise - * fnmatch.h: Likewise - * getopt.c: Likewise - * getopt.h: Likewise - * getopt1.c: Likewise - * global.c: Likewise - * idcache.c: Likewise - * main.c: Likewise - * makepath.c: Likewise - * mkdir.c: Likewise - * mt.c: Likewise - * rmt.c: Likewise - * rmt.h: Likewise - * rtapelib.c: Likewise - * safe-stat.h: Likewise - * strdup.c: Likewise - * strerror.c: Likewise - * stripslash.c: Likewise - * system.h: Likewise - * tar.c: Likewise - * tar.h: Likewise - * tarhdr.h: Likewise - * userspec.c: Likewise - * util.c: Likewise - * xmalloc.c: Likewise - * xstrdup.c: Likewise - - * cpio.1: Moved to doc - * cpio.texi: Likewise - * mt.1: Likewise - - * src: New directory - * src/.cvsignore: New file - * src/Makefile.am: Likewise - * src/alloca.c: Likewise - * src/argmatch.c: Likewise - * src/bcopy.c: Likewise - * src/copyin.c: Likewise - * src/copyout.c: Likewise - * src/copypass.c: Likewise - * src/cpio.h: Likewise - * src/cpiohdr.h: Likewise - * src/defer.c: Likewise - * src/defer.h: Likewise - * src/dirname.c: Likewise - * src/dstring.c: Likewise - * src/dstring.h: Likewise - * src/error.c: Likewise - * src/extern.h: Likewise - * src/filemode.c: Likewise - * src/filetypes.h: Likewise - * src/fnmatch.c: Likewise - * src/fnmatch.h: Likewise - * src/getopt.c: Likewise - * src/getopt.h: Likewise - * src/getopt1.c: Likewise - * src/gettext.h: Likewise - * src/global.c: Likewise - * src/idcache.c: Likewise - * src/main.c: Likewise - * src/makepath.c: Likewise - * src/mkdir.c: Likewise - * src/mt.c: Likewise - * src/rmt.c: Likewise - * src/rmt.h: Likewise - * src/rtapelib.c: Likewise - * src/safe-stat.h: Likewise - * src/strdup.c: Likewise - * src/strerror.c: Likewise - * src/stripslash.c: Likewise - * src/system.h: Likewise - * src/tar.c: Likewise - * src/tar.h: Likewise - * src/tarhdr.h: Likewise - * src/userspec.c: Likewise - * src/util.c: Likewise - * src/xmalloc.c: Likewise - * src/xstrdup.c: Likewise - - * doc: New directory - * doc/.cvsignore: New file - * doc/Makefile.am: New file - * doc/cpio.1: New file - * doc/cpio.info: New file - * doc/cpio.texi: New file - * doc/mt.1: New file - - * po: New directory - * po/.cvsignore: New file - * po/LINGUAS: New file - * po/Makevars: New file - * po/POTFILES.in: New file - -2003-11-28 Sergey Poznyakoff - - * configure.ac: Added various checks - * Makefile.am (rmt_LDADD): Added. - * error.c: Updated - * rmt.c: Removed useless private_errstring - * system.h: Updated - * userspec.c: Changed the way of handling declared vs. undeclared - system calls. - * strerror.c: New file. Borrowed from GNU Radius. - - * copyin.c: Removed kludgy declaration of delayed_seek_count. - * copypass.c: Likewise - * extern.h: Declare delayed_seek_count. - * mkdir.c: Fixed handling of undeclared errno - * mt.c: Likewise - * util.c: Likewise - * rtapelib.c: Likewise - -2003-11-28 Sergey Poznyakoff - - * TODO: New file - - * README-alpha: New file - * Makefile.am: Require at least version 1.7.1 - * configure.ac: Check for locale.h - * main.c (main): Call setlocale. Thanks - Mitsuru Chinen for the patch. - * THANKS: Updated - -2003-11-21 Sergey Poznyakoff - - * configure.ac: Added to the repository - * Makefile.am: Likewise - * NEWS: Likewise - * README: Likewise - * AUTHORS: Likewise - * .cvsignore: Likewise - - * configure.in: Removed - * Makefile.in: Removed - * makefile.pc: Removed - * configure: Removed - - * alloca.c: Added to the repository - * argmatch.c: Likewise - * bcopy.c: Likewise - * cpio.h: Likewise - * cpiohdr.h: Likewise - * defer.c: Likewise - * defer.h: Likewise - * dirname.c: Likewise - * dstring.c: Likewise - * dstring.h: Likewise - * error.c: Likewise - * filemode.c: Likewise - * filetypes.h: Likewise - * fnmatch.c: Likewise - * fnmatch.h: Likewise - * getopt.c: Likewise - * getopt.h: Likewise - * getopt1.c: Likewise - * idcache.c: Likewise - * mkdir.c: Likewise - * rmt.h: Likewise - * rtapelib.c: Likewise - * safe-stat.h: Likewise - * strdup.c: Likewise - * stripslash.c: Likewise - * tar.c: Likewise - * tar.h: Likewise - * tarhdr.h: Likewise - * xmalloc.c: Likewise - * xstrdup.c: Likewise - - * makepath.c: Updated - * mt.c: Likewise. - * rmt.c: Likewise. - * util.c: Likewise. - * copyin.c: Likewise. - * copyout.c: Likewise. - * copypass.c: Likewise. - * global.c: Likewise. - * main.c: Likewise. - -Thu Jun 13 20:14:48 2002 John Oleynick (juo@gnu.org) - * copyin.c: Strip leading / on absolute filenames after - comparing to the list of files specified on the command line - (instead of before). Problem reported by Jeff Holt. - * Version 2.5 released. - -Thu Jun 13 00:20:30 2002 John Oleynick (juo@gnu.org) - * Makefile.in: Fixed problem of looking in srcdir for info files. - Bug reported by Mike Castle. - * cpio.texi: Fixed typo. Problem reported by Fabrice Bauzac. - -Sun Jan 13 18:45:02 2002 John Oleynick (juo@gnu.org) - * copyin.c: Fixed a problem skipping files with multiple links - in a newc or CRC format archive. If the file with the shared copy - of the data was skipped, but other links were not skipped, the - other links were created as empty files. Bug reported by - Hendrik-Jan Thomassen. - -Thu Dec 6 20:05:10 2001 John Oleynick (juo@gnu.org) - * mt.c, mt.1: Merged Debian --rsh-command option and -V fix. - * copyout.c, copypass.c, util.c, extern.h: Modified to warn - if a file grows or its mtime is changed while it is being - copied. - -Wed Dec 6 00:02:04 2001 John Oleynick (juo@gnu.org) - * Many files: Updated FSF's address in copyright notices. - -Wed Aug 29 23:57:05 2001 John Oleynick (juo@gnu.org) - * Many files: Numerous fixes from Debian, Red Hat and SuSE - GNU/Linux distributions. - -Tue Jan 16 19:03:05 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * util.c: An I/O error reading a file would cause the last byte - of the next file to be corrupted in the archive. Thanks to a - buggy NT NFS server for pointing out this problem. - * Version 2.4.2 released. - -Tue Jan 9 23:19:37 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * copyout.c: missed 1 part of last bug fix. - -Mon Jan 8 16:49:01 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * copyout.c, copypass.c: Use result of readlink() as length - of link name instead of size from lstat(). On some OS's lstat() - doesn't return the true length in size. Bug reported by - Robert Joop (rj@rainbow.IN-berlin.DE). - -Wed Dec 20 10:52:56 1995 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * rmt.c: Added temporary kludge so make rmt will work on Linux. - * configure.in: Only define HAVE_UTIME_H if utime.h declares - struct utimbuf. - * Makefile.in: Change prefix, exec_prefix and bindir to get their - values from configure. Added cpio.info to DISTFILES. - * cpio.texi: Added INFO-DIR-ENTRY. - * Version 2.4.1 released. - -Wed Nov 22 19:37:05 1995 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * cpio.texi: Updated release date and FSF's address. - * NEWS: Listed major new features for 2.4. - * mt.c, mt.1: Added seek and fsfm commands. - * Version 2.4 released. - -Tue Jun 27 19:14:27 1995 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * configure.in: fixed for new autoconf. Added check to make - sure fnmatch() works. - * Makefile.in: changed realclean to maintainer-clean. Added - support to handle fnmatch separate from other LIBOBJS. - * cpio.texi: More changes for 2.4. - -Wed Dec 14 16:14:27 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * copypass.h: When given the -a option, set the access time of - the copy to be the access time of the original (instead of the - modification time of the original). Reported by - karney@pppl.gov (Charles Karney). - * cpio.texi: Updated with changes for 2.4. - -Wed Nov 3 18:18:07 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * safe-stat.h, Makefile.in: New file used by mkdir.c. This will go - away when we get the real safe-xstat.[ch]in for mkdir.c. - * main.c: Don't mention [--null] twice in -p's usage message. - Changed --no-absolute-paths to --no-absolute-filenames. - * cpio.1: Updated man page with new features. - * cpio.texi, texinfo.tex, Makefile.in: Added texi documentation - from Robert Carleton (rbc@gnu.ai.mit.edu). - -Mon Oct 3 00:46:30 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * makefile.pc, system.h: Changes to compile with Borland C++ 4.0. - -Thu Sep 29 22:15:50 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * makepath.c: Don't #define index if it is already #defined. - - * mt.c: Check for __hpux defined instead of __hpux__. Reported - by ericb@lsid.hp.com (Eric Backus). - -Thu Sep 29 11:21:31 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * extern.h, util.c, copyout.c, copypass.c, main.c, global.c: - Never mind --ignore-disk-input-errors flag, we'll just always - do that, like tar. - - * global.c, extern.h, main.c, copyin.c, copyout.c, copypass.c: - Added --quiet flag to supress printing number of blocks copied. - - * global.c, extern.h: If compiled with gcc, make input_bytes - and output_bytes `long long' instead of `long'. We need more - than 32 bits to keep track of the number of bytes copied to - and from tape drives that hold more than 4Gbytes. - - * util.c, copyin.c, main.c, global.c, extern.h: Added - --only-verify-crc flag to read a CRC format archive and verify - its contents' CRCs. - - * copyout.c: Fixed problem with creating oldc format archives - on machines with 16 bit ints. Reported by mpoole@cix.compulink.co.uk - (Martin Poole). - - * mt.c: Need to open tape WR_ONLY for erase command (and probably - others?). Reported by robert@hst.e.technik.uni-kl.de (Robert - Vogelgesan). Accept `eject' as a synonym for `offline'. Accept - `-t' as a synonym for `-f' (to be compatible with HPUX mt, which - only accepts `-t'). - -Wed Sep 28 12:01:55 1994 John Oleynick (juo@wombat.gnu.ai.mit.edu) - * extern.h, global.c, main.c, util.c: only write sparse files - when given --sparse flag. - * extern.h, util.c, copyout.c, copypass.c, main.c, global.c: - Added support for --ignore-disk-input-errors flag. - -Wed Aug 24 12:55:38 1994 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu) - - * configure.in: Replace calls to AC_REMOTE_TAPE and AC_RSH - with equivalent code, since those macros are going away. - -Sun Feb 13 00:56:48 1994 John Oleynick (juo@goldman.gnu.ai.mit.edu) - * extern.h, global.c, main.c, util.c: Added code to - tape_buffered_peek() to properly handle large, corrutped - archives, without overrunning the allocated buffer and - dumping core. Also changed the way the input and output - buffers are allocated in initialize_buffers(). - -Tue Jan 25 01:04:32 1994 John Oleynick (juo@goldman.gnu.ai.mit.edu) - * copyin.c, copyout.c, copypass.c, extern.h, main.c, tar.c, util.c: - Redid i/o buffer code. Previously, the same routines buffered input and - output for accessing the archive and the filesystem. Now there are - separate routines for buffering input and output and for buffering the - archive and the filesystem. This simplifies much of the buffer code - (e.g., only input from the archive has to check for end of tape and - allow the tape to be changed, only output to the filesystem has to - handle byte and word swapping, etc.; previously one routine had to - handle all of these special cases) This is how the routines got split - and renamed (old name -> new name): - - clear_rest_of_block -> tape_clear_rest_of_block - copy_files -> copy_files_tape_to_disk - " -> copy_files_disk_to_disk - " -> copy_files_disk_to_tape - copy_buf_out -> disk_buffered_write - " -> tape_buffered_write - copy_in_buf -> tape_buffered_read - empty_output_buffer -> tape_empty_output_buffer - " -> disk_empty_output_buffer - fill_input_buffer -> tape_fill_input_buffer - " -> disk_fill_input_buffer - pad_output -> tape_pad_output - peek_in_buf -> tape_buffered_peek - skip_padding -> tape_skip_padding - toss_input -> tape_toss_input - - * extern.h, global.c, main.c, util.c: Added support for - writing sparse files. - -Tue Dec 28 23:01:36 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu) - * util.c, system.h, makepath.c, extern.h: don't define chown() - and don't typedef uid_t and gid_t if we are being compiled - by DJGPP. - - * copyin.c, extern.h, global.c, main.c: Added support for - --rename-batch-file. - - * copyin.c, copyout.c, extern.h: Cleaned up to pass gcc -Wall. - -Wed Dec 22 02:17:44 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu) - - * makepath.c, copypass.c, copyin.c: If cpio was creating a - directory that contained `.' in the pathname (e.g. `foo/./bar'), - it would complain that it could not create `.', since it already - exists. From schwab@issan.informatik.uni-dortmund.de (Andreas - Schwab). - - * mt.c: Added "eject" as a synonym for "offline". - - * util.c: Slight modification to when we lseek with - BROKEN_LONG_TAPE_DRIVER (do it every 1Gb, instead - of every 2Gb). - - * copyin.c, global.c, extern.h: Added --no-absolute-paths option, - to ignore absolute paths in archives. - -Tue Dec 21 01:30:59 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu) - - * util.c: Fix for copying new_media_message_after_number. From - Christian.Kuehnke@arbi.informatik.uni-oldenburg.de (Christian - Kuehnke). - -Thu Jul 29 20:35:57 1993 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu) - - * Makefile.in (config.status): Run config.status --recheck, not - configure, to get the right args passed. - -Mon Jul 19 23:01:00 1993 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu) - - * Makefile.in (libdir): Use standard GNU value -- - $(exec_prefix)/lib, not /etc. - (.c.o): Put CFLAGS last. - -Thu Jul 8 19:43:39 1993 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) - - * Makefile.in: Add rules for remaking Makefile, configure, - config.status. - -Mon Jul 5 14:54:08 1993 John Oleynick (juo@spiff.gnu.ai.mit.edu) - - * cpio.1: Updated man page for 2.3. - * Makefile.in: Create distribution with .gz extension, instead of .z. - -Tue Jun 29 18:54:37 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu) - - * Makefile.in: Added installdirs target (using mkinstalldirs). - * Added mkinstalldirs script. - * main.c, mt.c: Added --help option. Changed usage() to - take a stream and exit value (so --help can print on stdout - and return a 0 exit status). - * extern.h: Removed usage()'s prototype (it was out of date, - and only used in main.c). - -Thu May 6 00:22:22 1993 John Oleynick (juo@hal.gnu.ai.mit.edu) - - * cpio.1: Added hpbin and hpodc. - -Tue May 4 00:32:29 1993 John Oleynick (juo@hal.gnu.ai.mit.edu) - - * copyin.c (process_copy_in), copypass.c (process_copy_pass): When - deleting an existing file, if the file is a directory, use rmdir() - instead of unlink(). - -Thu Apr 29 14:43:56 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu) - - * tar.c (read_in_tar_header): Clear non-protection bits from - mode, in case tar has left some device bits in there. - -Wed Apr 28 10:36:53 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu) - - * util.c: Added code to try and work around broken tape drivers - that have problems with tapes > 2Gb. - - * copyout.c (process_copy_out): Pass file_hdr to - writeout_other_defers() and add_link_defer() by reference, - not by value. - - * copyin.c (process_copy_in): Pass file_hdr to defer_copyin() - and create_defered_links() by reference, not by value. - - * defer.c: include (to build on BSD 4.3 on HP300) - -Fri Apr 16 18:01:17 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu) - - * mt.c, util.c: Include if HAVE_SYS_MTIO_H is - defined, not HAVE_MTIO_H. - -Wed Apr 14 17:37:46 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu) - - * util.c: Include if HAVE_SYS_IO_TRIOCTL_H - is defined. - - * mt.c: Only include if HAVE_SYS_MTIO_H is defined. - -Fri Apr 2 13:09:11 1993 John Oleynick (juo@goldman.gnu.ai.mit.edu) - - * configure.in: Added fnmatch to AC_REPLACE_FUNCS. Added - sys/io/trioctl.h to AC_HAVE_HEADERS. - - * Makefile.in: Removed fnmatch.o from OBJS. - - * copyin.c: Only include "fnmatch.h" if FNM_PATHNAME isn't - defined yet. - - * mt.c: Include if HAVE_SYS_IO_TRIOCTL_H is - defined. - -Mon Mar 29 17:04:06 1993 John Oleynick (juo@hal.gnu.ai.mit.edu) - - * Many changes for supporting HPUX Context Dependent Files; - also some bug fixes to fix problems with multiply (hard) linked - device files; minor changes to support HPUX format archives - (slightly broken?) System V.4 posix tar archives and HPUX - posix tar archives. - - * Makefile.in: New files defer.o, defer,c and defer.h; added - -DSYMLINK_USES_UMASK and -DHPUX_CDF comments; changed dist rule - to use gzip with tar, instead of compress. - - * copyin.c: changes for new arf_hpbinary and arf_hpascii formats; - HPUX CDF's; DEBUG_CPIO; fixes to properly handle multiple - links in newc and crc format archives (new routines defer_copyin(), - create_defered_links(), create_final_defers()); move most - multiple (hard) link code to new routines link_name() and - link_to_maj_min_ino(); use new macro UMASKED_SYMLINK instead of - symlink(). - - * copyout.c: fixes to properly handle multiple links in newc - and crc format archives (new routines last_link(), - count_defered_links_to_dev_ino(), add_link_defer(), - writeout_other_defers(), writeout_final_defers(), - writeout_defered_file()); support for new arf_hpbinary and - arf_hpascii formats; support for HPUX CDF's. - - * copypass.c: move most multiple link code to new routines - link_name() and link_to_maj_min_ino(); use new macro UMASKED_SYMLINK - instead of symlink(); support for HPUX CDF's. - - * extern.h: added arf_hpascii and arf_hpbinary archive enum types; - added debug_flag. - - * global.c: added debug_flag. - - * main.c: added debug_flag; support for hpodc and hpbin formats. - - * makepath.c: split from standard makpath.c to add support - for HPUX CDF's. - - * mt.c: added !defined(__osf__) (from Andrew Marquis - ). - - * system.h: new macro UMASKED_SYMLINK - - * tar.c: minor changes to read (slightly broken?) System V.4 posix - tar archives and HPUX posix tar archives. - - * util.c: HPUX CDF support (including new routines - add_cdf_double_slashes() and islasparentcdf()); new routine - umasked_symlink(). - -Sun Mar 14 23:00:14 1993 Jim Meyering (meyering@comco.com) - - * copypass.c (process_copy_pass): Use <=, not just <, when comparing - mtimes. From Pieter Bowman . - -Fri Jan 15 14:35:37 1993 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu) - - * copyin.c: Move include of fnmatch.h to get right FNM* macros. - -Tue Nov 24 08:45:32 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) - - * Version 2.2. - - * copyout.c (process_copy_out): Add parens for gcc -Wall. - From Jim Meyering. - - * system.h: Use HAVE_FCNTL_H, not USG. - - * dstring.c, mt.c, system.h: Use HAVE_STRING_H, not USG. - -Fri Nov 20 22:47:18 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) - - * copyin.c (read_in_binary): Copy the dev and ino that are - already in `file_hdr' into `short_hdr'. - From dao@abars.att.com (David A Oshinsky). - - * system.h [!_POSIX_VERSION]: Declare lseek as off_t, not long. - From Karl Berry. - -Wed Oct 14 13:53:41 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) - - * Version 2.1. - -Tue Oct 13 22:51:34 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) - - * main.c: Add --swap equivalent to -b. - - * mt.c: Add f_force_local variable and -V --version option. - -Fri Oct 2 18:42:27 1992 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu) - - * main.c (long_opts, usage): Add --force-local option. - -Thu Oct 1 23:23:43 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) - - * main.c (process_args) [__MSDOS__]: Don't call geteuid. - - * copyin.c (read_in_{old,new}_ascii): Use `l' for sscanf into longs. - * copyout.c (write_out_header): Ditto for sprintf. - * global.c, extern.h: Make input_size and output_size long. - -Thu Sep 10 23:39:30 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu) - - * global.c, extern.h: Add new var f_force_local to work with - rmt.h change from tar. - -Sun Aug 23 00:18:20 1992 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu) - - * Version 2.0. - - * tar.c (otoa): Compute value in an unsigned long, not an int. - * copyout.c (write_out_header) [__MSDOS__]: Don't use dev_t. - - * main.c (process_args): By default, don't chown for non-root users. - -Sat Aug 22 14:17:54 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu) - - * global.c, extern.h: Use uid_t and gid_t. - - * main.c (main) [__EMX__]: Expand wildcards. - * system.h [__EMX__]: Alias some error names. From Kai Uwe Rommel. - - * extern.h [__STDC__]: Use prototypes. - - * copyin.c (process_copy_in), copyout.c (process_copy_out), - copypass.c (process_copy_pass): Open all files with O_BINARY. - Add cast to chmod call. - * util.c: Add cast to bcopy calls. Make hash_insert static. - From Kai Uwe Rommel. - -Thu Aug 20 22:03:49 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu) - - * util.c (peek_in_buf): Don't print "end of file" before - getting the next reel of medium. - - * copyin.c (read_in_old_ascii): Allocate space for NUL terminator. - Print newline for dot line when done, even if appending. - -Thu Jul 23 16:34:53 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu) - - * tar.c (write_out_tar_header, read_in_tar_header) - [__MSDOS__]: Don't try to get user and group names. - * extern.h: Don't declare the functions to do it (need uid_t). - - * main.c [__MSDOS__]: Ignore the -R option. - - * system.h: Define makedev if defining major and minor. - - * copyin.c, copyout.c [__MSDOS__]: setmode on archive_des, not - 0 and 1. - -Sat Jul 18 14:30:55 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu) - - * tar.c, stripslash.c, userspec.c, cpiohdr.h, tar.h, tarhdr.h, - system.h: New files. - * Move portability stuff from various files to system.h. - * cpio.h: Rename header structure and members, and add - new structure for SVR4 format. - * copyin.c, copyout.c: Use the new structure internally, the - old one only for I/O in the old formats. - * copyin.c (read_in_header): Recognize the new archive formats. - (read_in_new_ascii, read_pattern_file, skip_padding): New functions. - (swab_array): Do the swapping using char pointers instead of - bitwise arithmetic. - (process_copy_in): Handle byte and halfword swapping and new formats. - Ok if a directory we want to make already exists, but set its perms. - Do chmod after chown to fix any set[ug]id bits. - Use `struct utimbuf' instead of a long array. - * copyout.c (write_out_header): Handle new formats. - (process_copy_out): Use `struct utimbuf'. - Handle appending and new formats. - Remove any leading `./' from filenames. - (read_for_checksum, clear_rest_of_block, pad_output): New functions. - * copypass.c (process_copy_pass): Use `struct utimbuf'. - Ok if a directory we want to make already exists, but set its perms. - Do chmod after chown to fix any set[ug]id bits. - Don't change perms of `.'. - * extern.h, global.c: Replace the separate format flags with - one variable. Add new variables for the new options. - * main.c: Add new options -A --append, -H --format, -C --io-size, - -M --message, --no-preserve-owner, -R --owner, -E --pattern-file, - -V --dot, -s --swap-bytes, -S --swap-halfwords, -b, -I, -k, -O. - (usage): Document them. - (process_args): Recognize them. Use open_archive. - (initialize_buffers): Allow room for tar archives and double buffers. - * util.c (empty_output_buffer_swap): New function. - (empty_output_buffer): Call it if swapping current file. - Check additional end of media indicators. - (swahw_array, peek_in_buf, prepare_append, open_archive, - set_new_media_message): New functions. - (fill_input_buffer): Don't print error message if end of media. - (toss_input): Don't seek, always read. - (copy_files): Update crc if needed. - (find_inode_file, add_inode): Check major and minor numbers as - well as dev. - (get_next_reel): Prompt user if archive name is unknown. - Print fancy messages. - Close the archive and reopen it. - - Above primarily from John Oleynick . - - * util.c (find_inode_file): Use modulus when computing initial - loop index. - (add_inode): Zero out new entry. - From scott@sctc.com (Scott Hammond). - - * cpio.h, copyin.c, copyout.c: Rename `struct cpio_header' - members from h_foo to c_foo. - -Wed May 20 00:09:26 1992 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu) - - * copyin.c: If we include a header file specifically to get - major et al., assume we have them. - -Mon Mar 9 19:29:20 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu) - - * mt.c (main): rmtclose the tape file descriptor. - - * main.c (main): rmtclose the archive, if not in copy-pass mode. - - * util.c (create_all_directories): Don't print a message when - creating a directory, for UNIX compat. - - * copyin.c (process_copy_in), copypass.c (process_copy_pass): - Skip file if it has the same timestamp as existing file, not just - if it is older than existing file, for UNIX compat. - -Tue Mar 3 12:06:58 1992 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu) - - * main.c, mt.c (usage): Document long options as starting with - -- instead of +. - - * extern.h: Only declare lseek if not _POSIX_VERSION. - -Tue Dec 24 00:19:45 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu) - - * copyin.c: Use MAJOR_IN_MKDEV and MAJOR_IN_SYSMACROS instead - of USG and _POSIX_VERSION to find major and minor macros. - - * mt.c: Use unistd.h and stdlib.h if available. - - * copyin.c, copyout.c, copypass.c, util.c, extern.h: Change - POSIX ifdefs to HAVE_UNISTD_H and _POSIX_VERSION. - -Sun Aug 25 06:31:08 1991 David J. MacKenzie (djm at apple-gunkies) - - * Version 1.5. - - * bcopy.c: New file (moved from util.c). - - * mt.c (print_status): Not all hpux machines have mt_fileno - and mt_blkno; rather than trying to track HP's product line, - just assume none of them have them. - - * util.c (copy_buf_out, copy_in_buf): Use more efficient - copying technique for a big speedup. - -Fri Aug 2 04:06:45 1991 David J. MacKenzie (djm at apple-gunkies) - - * configure: Support +srcdir. Create config.status. - Remove it and Makefile if interrupted while creating them. - -Thu Jul 18 09:43:40 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu) - - * Many files: use __MSDOS__ instead of MSDOS. - - * util.c, configure: Use NO_MTIO instead of HAVE_MTIO, to keep - up with tar and rtapelib.c. - -Mon Jul 15 13:45:30 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu) - - * configure: Also look in sys/signal.h for signal decl. - -Thu Jul 11 01:50:32 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu) - - * Version 1.4. - - * configure: Remove /etc and /usr/etc from PATH to avoid - finding /etc/install. - -Wed Jul 10 01:40:07 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu) - - * makefile.pc: Rewrite for Turbo C 2.0. - * util.c [__TURBOC__] (utime): New function. - * alloca.c, tcexparg.c: New files. - - * extern.h [STDC_HEADERS]: Don't declare malloc and realloc. - - * main.c [MSDOS]: Make binary mode the default. - * copyin.c, copyout.c: Make stdin or stdout binary mode as - appropriate (so cpio archives don't get corrupted). - - * Many files: Use if STDC_HEADERS as well as if USG. - - * configure, Makefile.in: $(INSTALLPROG) -> $(INSTALL), - $(INSTALLTEXT) -> $(INSTALLDATA). - -Mon Jul 8 23:18:28 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu) - - * configure: For some library functions that might be missing, - conditionally add the .o files to Makefile instead of - defining func_MISSING. - * mkdir.c: Renamed from mkrmdir.c. - -Sat Jul 6 02:27:22 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu) - - * configure: echo messages to stdout, not stderr. - Use a test program to see if alloca needs -lPW. - -Thu Jun 27 16:15:15 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu) - - * copyin.c (process_copy_in), copyout.c (process_copy_out), - copypass.c (process_copy_pass): Check close return value for - delayed error notification because of NFS. - -Thu Jun 20 02:43:33 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu) - - * configure: Include $DEFS when compiling test programs. - - * util.c: Only declare getpwuid and getgrgid if not POSIX. - - * Version 1.3. - - * copyin.c: Use time_t, not long, for time values. - - * mt.c (print_status): Special cases for HP-UX and Ultrix. - - * util.c: Compile bcopy if USG or STDC_HEADERS, not BCOPY_MISSING. - -Tue Jun 11 16:40:02 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu) - - * copyin.c: Don't include sys/sysmacros.h if _POSIX_SOURCE. - - * copyin.c, copyout.c, copypass.c: Don't include sys/file.h if POSIX. - - * util.c: Include sys/types.h before, not after, pwd.h and grp.h. - - * configure: New shell script to aid configuration and create - Makefile from Makefile.in. - - * copyin.c (process_copy_in): Use POSIX.2 fnmatch instead of - glob_match. - -Mon Jun 10 22:11:19 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu) - - * global.c, extern.h: New variable, name_end. - * main.c (process_args, usage): Add -0 +null option to set it. - * copypass.c (process_copy_pass), copyout.c (process_copy_out): - Use it. - - * dstring.c (ds_fgetstr): New function made from ds_fgets. - (ds_fgets, ds_fgetname): Implement as front ends to ds_fgetstr. - -Sun Jun 2 15:45:24 1991 David J. MacKenzie (djm at wheat-chex) - - * most files: use GPL version 2. - -Sat May 18 11:39:22 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu) - - * copyin.c, copypass.c: Take out #ifdef MSDOS around chown. - * util.c [MSDOS]: Provide dummy chown. - -Fri May 17 21:29:05 1991 David J. MacKenzie (djm at churchy.gnu.ai.mit.edu) - - * Version 1.2. - - * makefile.pc, cpio.cs: Update for new source and object files. - -Fri Mar 15 05:48:36 1991 David J. MacKenzie (djm at geech.ai.mit.edu) - - * global.c, extern.h: New variable `archive_desc'. - * main.c (process_args): Set it. - * copyout.c (process_copy_out), copyin.c (process_copy_in): - Use it. - - * copyout.c (process_copy_out), copyin.c (process_copy_in): - Remote tapes are special and not seekable; don't fstat them. - - * main.c (main, usage): Add -F, +file option. Use rmtopen. - (main): Exit after printing version number. - * util.c (empty_output_buffer): Use rmtwrite instead of write. - (fill_input_buffer): Use rmtread instead of read. - (tape_offline): Use rmtioctl instead of ioctl. - Test HAVE_MTIO instead of MTIO_MISSING, for tar compatibility. - -Thu Mar 14 17:49:57 1991 David J. MacKenzie (djm at geech.ai.mit.edu) - - * util.c (create_all_directories): Use make_path to do the work. - -Sat Jan 12 15:32:15 1991 David J. MacKenzie (djm at geech.ai.mit.edu) - - * copyin.c, copyout.c, copypass.c, util.c: Only declare - `errno' if not MSDOS. Some Unix errno.h do, some don't . . . . - - * global.c, extern.h: Make `input_size' and `output_size' - unsigned, for 16 bit machines. - - * copyin.c (print_name_with_quoting): All non-ctrl chars are - printable on MS-DOS. - - * util.c (empty_output_buffer): Never make sparse files; - can create unrunnable executables. - * copyin.c, copyout.c, copypass.c: Callers changed. - * util.c (finish_output_file): Function removed. - -Tue Nov 6 15:47:16 1990 David J. MacKenzie (djm at apple-gunkies) - - * copyin.c, util.c, extern.h: Rename copystring to xstrdup. - -Mon Oct 29 02:24:41 1990 David J. MacKenzie (djm at apple-gunkies) - - * util.c (empty_output_buffer): Only make sparse files if - NO_SPARSE_FILES is undefined, to accomodate dumb kernels. - -Wed Jul 25 18:48:35 1990 David J. MacKenzie (djm at albert.ai.mit.edu) - - * util.c (getuser, getgroup): Make uid and gid unsigned short, - not int. - -Sat Jul 21 00:44:44 1990 David J. MacKenzie (djm at apple-gunkies) - - * copyin.c, copyout.c, copypass.c, util.c, cpio.h: Add ifdefs - for MSDOS. - -Sun Jul 15 23:51:48 1990 David J. MacKenzie (djm at albert.ai.mit.edu) - - * copyin.c, copyout.c, copypass.c, global.c, extern.h, util.c: - Use longs where appropriate, for 16 bit machines. - -Sun Jul 8 22:58:06 1990 David J. MacKenzie (djm at apple-gunkies) - - * main.c (process_args, usage): Change -b option to -O (old), to - allow adding byte swapping later. - -Sat Jul 7 14:48:35 1990 David J. MacKenzie (dave at edfmd) - - * Version 1.1. - - * cpio.h: Make `mtime' and `filesize' unsigned long. - * copyin.c (read_in_binary), copyout.c (write_out_header): - High short-word of `mtime' and `filesize' always comes first. - - * (read_in_ascii, read_in_binary): New functions, from code in - read_in_header. - (read_in_header): Search for valid magic number, then fill in - rest of header using read_in_ascii and read_in_binary. - * global.c, extern.h: New variable, `binary_flag'. - * main.c (process_args): Recognize new -b +binary option. - * util.c [BCOPY_MISSING] (bcopy): New function. - -Wed Jul 4 00:40:58 1990 David J. MacKenzie (djm at apple-gunkies) - - * main.c (process_args): Add local pointers to functions to - work around a pcc bug found on a Convex. - - * copyin.c (process_copy_in), util.c (toss_input, - create_all_directories, add_inode): Don't use `index' as a - variable name. - -Tue Jul 3 02:33:36 1990 David J. MacKenzie (djm at apple-gunkies) - - * version 1.0. - -Mon Jul 2 23:18:56 1990 David J. MacKenzie (djm at twiddle) - - * copyin.c (process_copy_in), copyout.c (process_copy_out), - copypass.c (process_copy_pass): Print "1 block", not "1 blocks". - - * copyin.c (process_copy_in), copypass.c (process_copy_pass): - Unlink existing dest. file unless either it is newer and - not unconditional, or it is a directory. - -Mon Jul 2 03:57:41 1990 David J. MacKenzie (dave at edfmd) - - * util.c (xrealloc): New function. - * dstring.c (ds_resize): Use xrealloc instead of free and - xmalloc. Never shrink the string. - - * copypass.c (process_copy_pass): More efficient - string handling while constructing output filename. - - * global.c, extern.h, main.c, cpio.h: Change from an enum, - `copy_command', to a pointer to a void function, `copy_function'. - - * cpio.h (struct cpio_header): Make most fields unsigned. - Rename h_filesize to h_filesizes and h_mtime to h_mtimes, and - add new `long' fields with the old names at the end of the - structure. - * copyin.c (read_in_header): Set the long fields from the - short arrays, making sure longs are aligned properly. - (process_copy_in, long_format): Use the long fields. - * copyout.c (write_out_header): Set the short arrays from the - long fields, making sure longs are aligned properly. - (process_copy_out): Use the long fields. - - * global.c, extern.h: New variable `output_is_seekable'. - * util.c (empty_output_buffer): If output_is_seekable, use - lseek to write blocks of zeros. - (finish_output_file): New function. - * copyin.c (process_copy_in), copyout.c (process_copy_out), - copypass.c (process_copy_pass): Set `output_is_seekable' - correctly and call finish_output_file. - * main.c (initialize_buffers): Allocate space for sentinel in - `output_buffer'. - - * global.c, extern.h: New variable `numeric_uid'. - * main.c (process_args): Accept -n +numeric-uid-gid option, like ls. - * copyin.c (long_format): Use numeric_uid. - - * copyin.c (process_copy_in), copyout.c (process_copy_out), - copypass.c (process_copy_pass): Don't (for verbose) print the - names of files that are not copied because of errors. Try to - create missing directories for all file types. Free temporary - buffers on error. - -Sat Jun 30 14:28:45 1990 David J. MacKenzie (djm at apple-gunkies) - - * version.c: New file. - * main.c: Add -V, +version option. - * Makefile [dist]: Extract version number from version.c. - -Sat Jun 30 12:44:47 1990 David J. MacKenzie (dave at edfmd) - - * global.c, extern.h, copyin.c, copyout.c, util.c: Rename - `{input,output}_is_regular' to `{input,output}_is_special' and - reverse the truth value. - - * global.c, extern.h: New variable `input_is_seekable' to - control whether to skip data with lseek or read. - * copyin.c (process_copy_in): Set it. - * util.c (toss_input): Use it. - - * global.c, extern.h: New variable `xstat' that selects stat - or lstat for input files. - * main.c (process_args): New option -L, +dereference to set - xstat to stat instead of lstat. - (usage): Document it. - * copyout.c (process_copy_out), copypass.c - (process_copy_pass): Use *xstat on input file. - -Sat Jun 30 01:53:12 1990 David J. MacKenzie (dave at edfmd) - - * dstring.c (ds_init): Return void because return value was - never used. - (ds_resize): Ditto, and free old value instead of new one. - - * util.c (empty_output_buffer, fill_input_buffer, - copy_out_buf, copy_in_buf, toss_input, copy_files): Return - void instead of an error value and make errors fatal - immediately instead of several levels up, to prevent printing - of multiple error messages by different levels of functions. - - * copyin.c (read_in_header): Return void, because the error - handling all happens at lower levels. - (print_name_with_quoting): New function. - (long_format): Call print_name_with_quoting. Take additional - arg for name of linked-to file, and print it if nonzero. - (process_copy_in): For verbose listing of symlinks, read in - the linkname and pass it to long_format. - - * extern.h: Declare some more functions. - -Thu Jun 28 16:07:15 1990 David J. MacKenzie (dave at edfmd) - - * copypass.c (process_copy_pass): Warn about unknown file types. - - * copyout.c (process_copy_out): Check fstat return for error. - Record filesize of 0 for special files. Warn about unknown - file types. - - * copyin.c (process_copy_in): Warn about unknown file types. - (read_in_header): Warn about byte-reversed binary headers. - -Sat Jun 23 22:50:45 1990 David J. MacKenzie (dave at edfmd) - - * main.c (main): Set umask to 0 so permissions of created - files are preserved. - - * copyin.c, copyout.c, copypass.c, util.c: Pass file - descriptors as ints, not pointers to ints. - Cast file timestamps and sizes to long *, not int *, for 16 - bit machines. - Use lstat instead of stat, if available. - Handle FIFO's, sockets, and symlinks, if supported by O.S. - - * copyin.c (process_copy_in), copyout.c (process_copy_out): - Don't consider FIFO'S, sockets, etc. to be possible tape drives. - - * util.c (create_all_directories): Fix incorrect loop - termination check. Only copy string if it contains slashes. - Don't check whether directory "" exists. - (tape_offline): Code moved from get_next_reel. - (get_next_reel): Print message before taking tape offline. - Read a line of arbitrary length. - - * copyout.c, copyin.c, copypass.c: Always use utime, not utimes. - - * copyin.c (swab_short): New macro. - (swab_array): New function. - (read_in_header): In binary mode, if a byte-swapped header is - read, swap the bytes back. - (process_copy_in, process_copy_pass): Don't stat each file to - create unless !unconditional_flag. Create device files correctly. - Don't temporarily allow files being created to be read by - other users. Don't unnecessarily chmod special files. - -Thu May 31 20:51:43 1990 David J. MacKenzie (djm at albert.ai.mit.edu) - - * copyin.c (long_format): Use mode_string to format - file protections instead of doing it ourselves. - (protections): Function removed. - -Sat Apr 14 02:31:01 1990 David J. MacKenzie (djm at albert.ai.mit.edu) - - * cpio.h (struct cpio_header): Make inode, mode, uid, gid - fields unsigned. - - * util.c (getgroup): New function. - * copyin.c (long_format): Print group name of files. - Print file size, etc. as unsigned integers, not signed. - - * main.c (process_args): If -t is given and neither -i, -o, or - -p is given, assume -i. - - * Add -f, +nonmatching option. - * main.c: Rename +out to +create, +in to +extract, - +modification-time to +preserve-modification-time, - +pass to +pass-through. - - * copyin.c (process_copy_in), copypass.c (process_copy_pass): - Don't complain in chown fails because the user doesn't have - permission. - -Fri Apr 13 13:53:20 1990 David J. MacKenzie (djm at albert.ai.mit.edu) - - * Add ifdefs for USG/Xenix. - * util.c (cpio_error): Function removed. - * Use error instead of cpio_error, so system error messages - will be included. - * cpio.h: Rename 'hdr_struct' to 'struct cpio_header'. - * Move definition of xmalloc from dstring.c to util.c. - * global.c, extern.c: Add global `program_name'. - * main.c (main): Set program_name. - (process_args): Rename +reset-atime to +reset-access-time, - +table to +list. - Have +block-size take an argument. - -Thu Apr 12 13:33:32 1990 David J. MacKenzie (djm at rice-chex) - - * util.c (find_inode_file): Make inode an int, not a short. - - * Make functions that don't return a value have type void. - Add some casts to function calls. - -Wed Apr 11 14:55:28 1990 David J. MacKenzie (djm at albert.ai.mit.edu) - - * main.c (process_args): -i, -o, and -p don't take arguments. - - * main.c (process_args): Get the non-option args from the - correct elements of argv. - -Tue Apr 10 00:20:26 1990 David J. MacKenzie (djm at albert.ai.mit.edu) - - * Indent source code and update copyrights. - - * cpio.c (usage): Change `collection' to `archive' in message. - -Thu Dec 28 03:03:55 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu) - - * dstring.c (xmalloc): Don't return a null pointer if size is 0, - on the assumption that trying to allocate 0 bytes is a bug that - should be trapped. - -Wed Dec 20 03:24:48 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu) - - * All files: Change from GNU CPIO General Public License to - GNU General Public License. - -Mon Dec 18 13:18:36 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu) - - * Makefile: Add clean target and defines for CC and LDFLAGS. - Add dist target and SRCS, DISTFILES macros. Add tags and TAGS targets. - * dstring.c (ds_fgets): Read characters into an int, not char. - (xmalloc): New function. - (out_of_memory): Function removed. - Global: use xmalloc instead of malloc and out_of_memory. - * extern.h, global.c: Make flag variables ints instead of chars for - compatibility with getopt_long. - * extern.h: Declare more functions. - * main.c (usage): Put the whole usage message into a single string - and fix errors. - * util.c (create_all_directories): Remove unused variable. - (get_next_reel): Ditto. - * dstring.h: Declare function. - -Sat Dec 2 13:22:37 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu) - - * main.c: Change +copy-pass option to +pass, +copy-in to +in, - +copy-out to +out, and +mkdir to +make-directories, and add null - option to terminate table. - (process_args): Use the same code to handle long and short named - options. - (usage): Mention long options in message. - -Local Variables: -mode: change-log -version-control: never -End: diff --git a/contrib/cpio/FREEBSD-upgrade b/contrib/cpio/FREEBSD-upgrade deleted file mode 100644 index a3e31a0592e..00000000000 --- a/contrib/cpio/FREEBSD-upgrade +++ /dev/null @@ -1,29 +0,0 @@ -$FreeBSD$ - -GNU cpio: - - Originals can be found at: ftp://ftp.gnu.org/pub/gnu/cpio - -Configure by: - - ./configure --disable-nls --without-libiconv-prefix \ - --without-libintl-prefix - -Trim by: - - rm Makefile.am Makefile.in aclocal.m4 config.h.in configure \ - configure.ac - rm -r headers m4 rmt tests scripts po - rm doc/Makefile.am doc/Makefile.in doc/mt.1 doc/cpio.info - rm src/Makefile.am src/Makefile.in - rm src/mt.c - rm lib/Makefile.am lib/Makefile.in lib/Makefile.tmpl lib/alloca.c \ - lib/argmatch.[ch] lib/bcopy.c lib/fnmatch.c lib/fnmatch_.h \ - lib/fnmatch_loop.c lib/mkdir.c lib/quote.[ch] \ - lib/quotearg.[ch] lib/stdbool_.h lib/strcasecmp.c \ - lib/strdup.c lib/strerror.c lib/strncasecmp.c lib/sysexit_.h - -Import by: - - cvs import -m "Import GNU cpio 2.6 (trimmed)" src/contrib/cpio \ - GNU v2_6 diff --git a/contrib/cpio/INSTALL b/contrib/cpio/INSTALL deleted file mode 100644 index 5458714e1e2..00000000000 --- a/contrib/cpio/INSTALL +++ /dev/null @@ -1,234 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006 Free Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - -Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/contrib/cpio/NEWS b/contrib/cpio/NEWS deleted file mode 100644 index 857ae89ff1a..00000000000 --- a/contrib/cpio/NEWS +++ /dev/null @@ -1,155 +0,0 @@ -GNU cpio NEWS -- history of user-visible changes. 2007-06-08 -Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. -See the end of file for copying conditions. - -Please send cpio bug reports to . - -Version 2.8 - Sergey Poznyakoff, 2007-06-08 - -* Option --owner can be used in copy-out mode, allowing to uniformly override -ownership of the files being added to the archive. - -* Bugfixes: - -** Symlinks were handled incorrectly in copy-out mode. -** Fix handling of large files. -** Fix setting the file permissions in copy-out mode. -** Fix CAN-2005-1111 - - -Version 2.7 - Sergey Poznyakoff, 2006-10-21 - -* Improved error checking and diagnostics - -* Bugfixes -** Fixed CAN-1999-1572 -** Allow to use --sparse in both copy-in and copy-pass. -** Fix bug that eventually caused copying out the same hard-linked -file several times to archive. -** Fix several LFS-related issues. -** Fix Debian bug 335580. - - -Version 2.6 - Sergey Poznyakoff, 2004-12-20 - -* Added NLS support - -* Improved configure script - -* Improved invocation consistency checking and help output - -* Printing warning about truncation of inode numbers is suppressed by -default. See below. - -* New option --warning (-W) controls the level of output warnings: - - -Wnone Disables all warnings - -Wtruncate Enable warning about truncation of the inode number - -Wall Enables all warnings - - To disable a particular warning, prefix its name with 'no-', just - like in gcc. - -* New option --to-stdout extracts files to standard output. - -* The output of `cpio --help' is largely improved. - -* Bugfixes: -** If a file grew n bytes in copy-pass mode, these n bytes got prepended -to the contents of all subsequent files. -** Padding the archive with zero bytes upon truncation of the file being -archived was broken. - - -Major changes in version 2.5: - -* bug fixes from Debian, Red Hat, and SuSE GNU/Linux Distribution patches -* --rsh-command option - -Major changes in version 2.4: - -* new texinfo documentation -* --sparse option to write sparse files -* --only-verify-crc option to verify a CRC format archive -* --no-absolute-paths option to ignore absolute paths -* --quiet option to supress printing number of blocks copied -* handle disk input errors more gracefully - -Major changes in version 2.3: - -* in newc and crc format archives, only store 1 copy of multiply linked files -* handle multiply linked devices properly -* handle multiply linked files with cpio -pl even when the source and - destination are on different file systems -* support HPUX Context Dependent Files -* read and write HPUX cpio archives -* read System V.4 POSIX tar archives and HPUX POSIX tar archives -* use rmdir, instead of unlink, to delete existing directories - -Major changes in version 2.2: - -* handle link counts correctly when reading binary cpio archives -* configure checks for some libraries that SVR4 needs - -Major changes in version 2.1: - -* cpio can access remote non-device files as well as remote devices -* fix bugs in the MS-DOS port -* add --swap equivalent to -b option - -Version 2.0 adds the following features: - -Support for the SVR4 cpio formats, which can store inodes >65535, and -for traditional and POSIX tar archives. Also adds these options: - --A --append append to instead of replacing the archive --V --dot print a dot for each file processed --H --format select archive format --C --io-size select I/O block size in bytes --M --message print a message at end of media volumes ---no-preserve-owner don't change files' owners when extracting --R --owner set files' owners when extracting --E --pattern-file list of shell filename patterns to process --s --swap-bytes handle byte-order differences when extracting files --S --swap-halfwords ditto --b like -sS --I input archive filename --k recognize corrupted archives (we alawys do it, though) --O output archive filename - -Some options of previous versions have been renamed in 2.0: - ---binary was replaced by --format=bin ---portability was replaced by --format=odc - -Some options have changed meaning in 2.0, for SVR4 compatibility: - --O used to select the binary archive format, now selects the output file --V used to print the version number, now prints a dot for each file - -Version 2.0 also fixes several bugs in the handling of files with -multiple links and of multi-volume archives on floppy disks. - ----------------------------------------------------------------------- -Copyright information: - -Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - - Permission is granted to anyone to make or distribute verbatim copies - of this document as received, in any medium, provided that the - copyright notice and this permission notice are preserved, - thus giving the recipient permission to redistribute in turn. - - Permission is granted to distribute modified versions - of this document, or of portions of it, - under the above conditions, provided also that they - carry prominent notices stating who last changed them. - -Local variables: -mode: outline -paragraph-separate: "[ ]*$" -eval: (add-hook 'write-file-hooks 'time-stamp) -time-stamp-start: "changes. " -time-stamp-format: "%:y-%02m-%02d" -time-stamp-end: "\n" -end: diff --git a/contrib/cpio/README b/contrib/cpio/README deleted file mode 100644 index fafff13881e..00000000000 --- a/contrib/cpio/README +++ /dev/null @@ -1,71 +0,0 @@ -This is GNU cpio, a program to manage archives of files. -As of version 2.0, it supports the features of the System V release 4 -cpio, including support for tar archives. - -This package also includes rmt, the remote tape server, and mt, a tape -drive control program; these two programs will only be compiled if -your system supports remote command execution, and tape drive control -operations, respectively. - -See the file INSTALL for compilation and installation instructions for Unix. - -For non-Unix systems [ Note: The non-Unix makefiles have not been tested - for this release ] - -makefile.pc is a makefile for Turbo C or C++ or Borland C++ on MS-DOS. - -makefile.os2 is a makefile for MS C and GNU C (emx/gcc) on OS/2. -cpio.def is a linker definition file for the MS C OS/2 version. - - -The main advantages of GNU cpio over Unix versions are: - -* It can access tape drives on other hosts using TCP/IP. - -* `-o' and `-p' can copy symbolic links either as symbolic links or, -with `-L', as the files they point to. - -* `-i' automatically recognizes the archive format and tries to -recover from corrupted archives. - -* The output of '-itv' looks like 'ls -l'. - -* It accepts long-named options as well as traditional -single-character options. - -A few features of other versions of cpio are missing from GNU cpio, including: - -* The `-6' option to support Sixth Edition Unix cpio archives with `-i'. - -* An option to limit volume size, like afio -s. - - -GNU cpio supports the POSIX.1 "ustar" tar format. GNU tar supports a -somewhat different, early draft of that format. That draft format has -a slightly different magic number in the tar header and doesn't -include the path prefix part of the header, which allows storing file -names that are longer than 100 characters. GNU cpio knows to -recognize the nonstandard GNU tar "ustar" archives. - -The following patch to GNU tar 1.11.1 makes GNU tar recognize standard -"ustar" archives, such as GNU cpio produces, except that it won't use -the path prefix. Without this patch, GNU tar thinks that standard -"ustar" archives are old-format tar archives and can not use the extra -information that "ustar" format contains. If you use this patch, -remember that you will lose the beginnings of paths that are longer -than 100 characters. That's why it's not an official part of GNU tar. -(Adding support for the path prefix to GNU tar is not trivial.) - ---- list.c.orig Mon Sep 14 17:04:03 1992 -+++ list.c Wed Oct 14 14:02:28 1992 -@@ -439,7 +439,7 @@ - st->st_ctime = from_oct(1+12, header->header.ctime); - } - -- if (0==strcmp(header->header.magic, TMAGIC)) { -+ if (0==strncmp(header->header.magic, TMAGIC, 5)) { - /* Unix Standard tar archive */ - *stdp = 1; - if (wantug) { - -Mail suggestions and bug reports for GNU cpio to bug-cpio@gnu.org. diff --git a/contrib/cpio/THANKS b/contrib/cpio/THANKS deleted file mode 100644 index 393de057c2a..00000000000 --- a/contrib/cpio/THANKS +++ /dev/null @@ -1,20 +0,0 @@ -GNU cpio THANKS file - -GNU cpio has originally been written by Phil Nelson -and David MacKenzie . It was further modified -by John Oleynick and Sergey Poznyakoff -who currently maintains it. - -The following is a list of people who contributed to GNU cpio by -reporting problems, suggesting various improvements or submitting actual -code. Help us keep it complete and exempt of errors. - -Benigno B. Junior -Brian Mays -Dmitry V. Levin -Jim Castleberry -Holger Fleischmann -Matthew Braithwaite -Mike Frysinger -Mitsuru Chinen -Peter Vrabec diff --git a/contrib/cpio/TODO b/contrib/cpio/TODO deleted file mode 100644 index ffd63d5fd96..00000000000 --- a/contrib/cpio/TODO +++ /dev/null @@ -1,159 +0,0 @@ -Following is the list of cpio-related reports to bug-gnu-utils. -Many of them appear to be fixed, but quite a number of them is -probably still waiting for being handled. The list is divided -into two parts, the messages are in somehow arbitrary order. - -* Bug reports --------------- - -** cpio -d bug (fwd) (score: 47) - Author: Christian Smith - Date: Wed, 14 Nov 2001 02:06:46 +0000 (GMT) - This was bounced from bug-cpio@bogus.example.com I guess that - isn't set up yet. -- /"\ \ / ASCII RIBBON CAMPAIGN - AGAINST - HTML MAIL X - AGAINST MS ATTACHMENTS / \ $ cpio --version GNU - cpio version 2 - /archive/html/bug-gnu-utils/2001-11/msg00170.html (4,548 bytes) - -** bug in cpio with tapechange in copy-in-mode (score: 34) - Author: Bernd =?ISO-8859-1?Q?Sch=FCler?= - - Date: 05 Aug 2002 18:37:56 +0200 - Hello, last i made a restore from tape, and no request for next - tape happend, only an read-error occured. Here is an quick - patch, please verify the problem and the patch-code. I'm not - sure, if the pr - /archive/html/bug-gnu-utils/2002-08/msg00122.html (4,518 bytes) - -** Re: bug in cpio? (score: 40) - Author: kasal@matsrv.math.cas.cz (Stepan Kasal) - Date: Thu, 13 Jun 2002 07:44:14 +0000 (UTC) - Hallo, the following option should help: -d, --make-directories - Create leading directories where needed. Details: cpio won't - create the directory for the file. Observe: kasal$ echo - /home/kasal/tmp/db - /archive/html/bug-gnu-utils/2002-06/msg00306.html (4,862 bytes) - -** cpio 2.4.2 bug? (score: 40) - Author: "H.J. Thomassen" - Date: Thu, 10 Jan 2002 18:09:10 +0100 (CET) - Hello, We use GNU-cpio 2.4.2 and have the following problem: - Short: Assume I have a directory with two filenames, which are - hardlinks to the same i-node. I make a crc-cpio archive with - both files; th - /archive/html/bug-gnu-utils/2002-01/msg00161.html (5,624 bytes) - -** These two seem to be related: -*** cpio copy-in and multiply-linked files (score: 35) - Author: Chris Jaeger - Date: Tue, 07 Aug 2001 23:46:04 -0700 - Hi, I was wondering whether it was a bug or a feature that GNU - cpio, while in copy-in mode, will create a multiply-linked set - of files all of size 0 if the last linked file is not copied in - due to th - /archive/html/bug-gnu-utils/2001-08/msg00074.html (4,142 bytes) - -*** (no subject) (score: 2) - Author: brian@debian.org (Brian Mays) - Date: Sat, 07 Jul 2001 16:35:13 -0400 - When hard-linked files (along with many other files) are - archived to a cpio ustar format archive, the files are _not_ - all archived as hard links to each other in the archive. When - the same set of fil - /archive/html/bug-gnu-utils/2001-07/msg00080.html (5,666 bytes) - -** These too: - -*** Re: minor problems with slackware-current (score: 7) - Author: Cezary Sliwa - Date: Wed, 1 Aug 2001 10:43:37 +0200 - "cpio --sparse" corrupts data. A fix attached. C.S. Attachment: - cpio-2.4.2-sparse.diff Description: Text document - /archive/html/bug-gnu-utils/2001-08/msg00000.html (3,989 bytes) - -*** cpio --sparse (score: 34) - Author: Cezary Sliwa - Date: Mon, 26 Mar 2001 10:43:34 +0200 (CEST) - the '--sparse' option of gnu cpio causes data corruption - (blocks of zeros are lost or appended to other files). C.S. - /archive/html/bug-gnu-utils/2001-03/msg00235.html (3,671 bytes) - -** And these too -*** cpio-2.4.2: data corruption bug (score: 35) - Author: Todd Kelley - Date: Fri, 09 Feb 2001 17:00:06 -0500 - Hello, Recently at OEone we fixed a bug in GNU cpio-2.4.2: When - a file over about 0.5 megabyes grows while it is being - archived, it and all files following it in the archive are - corrupted. The crc do - /archive/html/bug-gnu-utils/2001-02/msg00062.html (4,297 bytes) - -*** cpio pass-through can corrupt files (score: 36) - Author: "Parrott, Jeff" - Date: Mon, 16 Oct 2000 13:32:57 -0400 - I have seen corrupted files as a result of using the - pass-through option in cpio. The corruption occurs when - active/in-use (and growing) files are being copied. The problem - is that the file size has - /archive/html/bug-gnu-utils/2000-10/msg00087.html (4,974 bytes) - -** cpio 2.4.2 unconditionally takes the tape drive offline (score: - 39) - Author: Scott Larson - Date: Thu, 11 Jan 2001 13:15:52 -0800 - We have been copying multiple volumes to a single tape with the - System 5 version of cpio. The gnu version of cpio doesn't - support this since it takes the tape offline (i.e. ejects the - tape) after rea - /archive/html/bug-gnu-utils/2001-01/msg00087.html (4,264 bytes) - -** cpio -t can see international filenames, find -ls also suffers - (score: 35) - Author: "Dan Jacobson" - Date: Tue, 26 Dec 2000 07:38:53 +0800 - GNU cpio version 2.4.2 with cpio -t I can see Chinese [big5] - filenames. with -tv, they become \267\247 etc Just like what - happens with find . -print vs. find . -ls -- - http://www.geocities.com/jidanni - /archive/html/bug-gnu-utils/2000-12/msg00143.html (4,084 bytes) - -* Suggestions -------------- - -** GNU cpio suggestion (score: 42) - Author: "H.J.Thomassen" - Date: Mon, 17 Dec 2001 11:27:11 +0100 - Re: suggestion for GNU-cpio extension (plus reference - implementation) We use cpio for our backup purposes. The backup - is started automatically in the middle of the night. To chase - away all users we d - /archive/html/bug-gnu-utils/2001-12/msg00244.html (7,474 bytes) - -** cpio suggestion + patch (score: 38) - Author: Taylor Gautier - Date: Fri, 20 Apr 2001 09:40:05 -0700 - I have a suggestion for cpio. The suggestion is to make it copy - files into a temporary name and then rename the file as the - last operation. Since UNIX filesystems are supposed to - gaurantee atomicity - /archive/html/bug-gnu-utils/2001-04/msg00169.html (10,674 - bytes) - -** [cpio] man page enhancement: a Example section ? (score: 5) - Author: Yannick Patois - Date: Wed, 24 Oct 2001 12:48:33 +0200 (CEST) - Hello, I seldom use cpio (as I think many people) and only had - to use it once or twice. IMHA, would be good to have a small - section with an example of most often performed actions - (creating an archiv - /archive/html/bug-gnu-utils/2001-10/msg00270.html (4,336 bytes) - -** Patch to cpio to enable verbose *skipping* of files (score: 40) - Author: Tomas Pospisek - Date: Mon, 8 Oct 2001 13:54:14 +0200 (CEST) - This patch enables cpio to be verbose about the files that it - does not copy, which is very handy for seeing cpio's progress - through a tape or simply for debuging. The patch along with a - Debian packag - /archive/html/bug-gnu-utils/2001-10/msg00083.html (4,548 bytes) - diff --git a/contrib/cpio/doc/cpio.1 b/contrib/cpio/doc/cpio.1 deleted file mode 100644 index a59094aa0c3..00000000000 --- a/contrib/cpio/doc/cpio.1 +++ /dev/null @@ -1,41 +0,0 @@ -.TH CPIO 1L \" -*- nroff -*- -.SH NAME -cpio \- copy files to and from archives -.SH SYNOPSIS -.B cpio -{\-o|\-\-create} [\-0acvABLV] [\-C bytes] [\-H format] [\-M message] -[\-O [[user@]host:]archive] [\-F [[user@]host:]archive] -[\-\-file=[[user@]host:]archive] [\-\-format=format] [\-\-message=message] -[\-\-null] [\-\-reset-access-time] [\-\-verbose] [\-\-dot] [\-\-append] -[\-\-block-size=blocks] [\-\-dereference] [\-\-io-size=bytes] [\-\-quiet] -[\-\-force\-local] [\-\-rsh-command=command] [\-\-help] [\-\-version] -< name-list [> archive] - -.B cpio -{\-i|\-\-extract} [\-bcdfmnrtsuvBSV] [\-C bytes] [\-E file] [\-H format] -[\-M message] [\-R [user][:.][group]] [\-I [[user@]host:]archive] -[\-F [[user@]host:]archive] [\-\-file=[[user@]host:]archive] -[\-\-make-directories] [\-\-nonmatching] [\-\-preserve-modification-time] -[\-\-numeric-uid-gid] [\-\-rename] [\-t|\-\-list] [\-\-swap-bytes] [\-\-swap] [\-\-dot] -[\-\-unconditional] [\-\-verbose] [\-\-block-size=blocks] [\-\-swap-halfwords] -[\-\-io-size=bytes] [\-\-pattern-file=file] [\-\-format=format] -[\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message] -[\-\-force\-local] [\-\-absolute\-filenames] [\-\-sparse] -[\-\-only\-verify\-crc] [\-\-quiet] [\-\-rsh-command=command] [\-\-help] -[\-\-version] [pattern...] [< archive] - -.B cpio -{\-p|\-\-pass-through} [\-0adlmuvLV] [\-R [user][:.][group]] -[\-\-null] [\-\-reset-access-time] [\-\-make-directories] [\-\-link] [\-\-quiet] -[\-\-preserve-modification-time] [\-\-unconditional] [\-\-verbose] [\-\-dot] -[\-\-dereference] [\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] -[\-\-sparse] [\-\-help] [\-\-version] destination-directory < name-list -.SH DESCRIPTION -GNU cpio is fully documented in the texinfo documentation. To access the -help from your command line, type -.PP -\fBinfo cpio -.PP -The online copy of the documentation is available at the following address: -.PP -http://www.gnu.org/software/cpio/manual diff --git a/contrib/cpio/doc/cpio.texi b/contrib/cpio/doc/cpio.texi deleted file mode 100644 index 8bf4ddebb77..00000000000 --- a/contrib/cpio/doc/cpio.texi +++ /dev/null @@ -1,602 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename cpio.info -@settitle cpio -@setchapternewpage off -@c %**end of header - -@dircategory Archiving -@direntry -* Cpio: (cpio). Copy-in-copy-out archiver to tape or disk. -@end direntry - -@include version.texi - -@copying -This manual documents GNU cpio (version @value{VERSION}, @value{UPDATED}). - -Copyright @copyright{} 1995, 2001, 2002, 2004 Free Software Foundation, Inc. -@sp 1 -@quotation -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.2 or -any later version published by the Free Software Foundation; with no -Invariant Sections, with the Front-Cover texts being ``A GNU Manual'', -and with the Back-Cover Texts as in (a) below. A copy of the license -is included in the section entitled ``GNU Free Documentation License''. - -(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify -this GNU Manual, like GNU software. Copies published by the Free -Software Foundation raise funds for GNU development.'' -@end quotation -@end copying - -@titlepage -@title GNU CPIO -@subtitle @value{VERSION} @value{UPDATED} -@author by Robert Carleton -@c copyright page -@page -@vskip 0pt plus 1filll -@insertcopying -@sp 2 -Published by the Free Software Foundation @* -51 Franklin Street, Fifth Floor, @* -Boston, MA 02110-1301, USA @* -@end titlepage - -@node Top, Introduction, (dir), (dir) -@comment node-name, next, previous, up - -@ifinfo -@top - -GNU cpio is a tool for creating and extracting archives, or copying -files from one place to another. It handles a number of cpio formats as -well as reading and writing tar files. This is the first edition of the -GNU cpio documentation and is consistent with @value{VERSION}. - -@end ifinfo - -@menu -* Introduction:: -* Tutorial:: Getting started. -* Invoking cpio:: How to invoke @command{cpio}. -* Media:: Using tapes and other archive media. -* Reports:: Reporting bugs or suggestions -* Concept Index:: Concept index. - -@detailmenu - --- The Detailed Node Listing --- - -Invoking cpio - -* Copy-out mode:: -* Copy-in mode:: -* Copy-pass mode:: -* Options:: - -@end detailmenu -@end menu - -@node Introduction, Tutorial, Top, Top -@comment node-name, next, previous, up -@chapter Introduction - -GNU cpio copies files into or out of a cpio or tar archive, The archive -can be another file on the disk, a magnetic tape, or a pipe. - -GNU cpio supports the following archive formats: binary, old ASCII, new -ASCII, crc, HPUX binary, HPUX old ASCII, old tar, and POSIX.1 tar. The -tar format is provided for compatibility with the tar program. By -default, cpio creates binary format archives, for compatibility with -older cpio programs. When extracting from archives, cpio automatically -recognizes which kind of archive it is reading and can read archives -created on machines with a different byte-order. - -@node Tutorial, Invoking cpio, Introduction, Top -@comment node-name, next, previous, up -@chapter Tutorial -@cindex creating a cpio archive -@cindex extracting a cpio archive -@cindex copying directory structures -@cindex passing directory structures - - -GNU cpio performs three primary functions. Copying files to an -archive, Extracting files from an archive, and passing files to another -directory tree. An archive can be a file on disk, one or more floppy -disks, or one or more tapes. - -When creating an archive, cpio takes the list of files to be processed -from the standard input, and then sends the archive to the standard -output, or to the device defined by the @option{-F} option. -@xref{Copy-out mode}. Usually find or ls is used to provide this list -to the standard input. In the following example you can see the -possibilities for archiving the contents of a single directory. - - -@example -@cartouche -% ls | cpio -ov > directory.cpio -@end cartouche -@end example - -The @option{-o} option creates the archive, and the @option{-v} option -prints the names of the files archived as they are added. Notice that -the options can be put together after a single @option{-} or can be placed -separately on the command line. The @samp{>} redirects the cpio output -to the file @samp{directory.cpio}. - - -If you wanted to archive an entire directory tree, the find command can -provide the file list to cpio: - - -@example -@cartouche -% find . -print -depth | cpio -ov > tree.cpio -@end cartouche -@end example - - -This will take all the files in the current directory, the directories -below and place them in the archive tree.cpio. Again the @option{-o} -creates an archive, and the @option{-v} option shows you the name of the -files as they are archived. @xref{Copy-out mode}. Using the @samp{.} in the -find statement will give you more flexibility when doing restores, as it -will save file names with a relative path vice a hard wired, absolute -path. The @option{-depth} option forces @samp{find} to print of the -entries in a directory before printing the directory itself. This -limits the effects of restrictive directory permissions by printing the -directory entries in a directory before the directory name itself. - - - - -Extracting an archive requires a bit more thought because cpio will not -create directories by default. Another characteristic, is it will not -overwrite existing files unless you tell it to. - - -@example -@cartouche -% cpio -iv < directory.cpio -@end cartouche -@end example - -This will retrieve the files archived in the file directory.cpio and -place them in the present directory. The @option{-i} option extracts the -archive and the @option{-v} shows the file names as they are extracted. -If you are dealing with an archived directory tree, you need to use the -@option{-d} option to create directories as necessary, something like: - -@example -@cartouche -% cpio -idv < tree.cpio -@end cartouche -@end example - -This will take the contents of the archive tree.cpio and extract it to -the current directory. If you try to extract the files on top of files -of the same name that already exist (and have the same or later -modification time) cpio will not extract the file unless told to do so -by the -u option. @xref{Copy-in mode}. - - -In copy-pass mode, cpio copies files from one directory tree to another, -combining the copy-out and copy-in steps without actually using an -archive. It reads the list of files to copy from the standard input; -the directory into which it will copy them is given as a non-option -argument. @xref{Copy-pass mode}. - -@example -@cartouche -% find . -depth -print0 | cpio --null -pvd new-dir -@end cartouche -@end example - - -The example shows copying the files of the present directory, and -sub-directories to a new directory called new-dir. Some new options are -the @option{-print0} available with GNU find, combined with the -@option{--null} option of cpio. These two options act together to send -file names between find and cpio, even if special characters are -embedded in the file names. Another is @option{-p}, which tells cpio to -pass the files it finds to the directory @samp{new-dir}. - -@node Invoking cpio, Media, Tutorial, Top -@comment node-name, next, previous, up -@chapter Invoking cpio -@cindex invoking cpio -@cindex command line options - -@menu -* Copy-out mode:: -* Copy-in mode:: -* Copy-pass mode:: -* Options:: -@end menu - -@node Copy-out mode, Copy-in mode, Invoking cpio, Invoking cpio -@comment node-name, next, previous, up -@section Copy-out mode - -In copy-out mode, cpio copies files into an archive. It reads a list -of filenames, one per line, on the standard input, and writes the -archive onto the standard output. A typical way to generate the list -of filenames is with the find command; you should give find the -depth -option to minimize problems with permissions on directories that are -unreadable. -@xref{Options}. - -@example -cpio @{-o|--create@} [-0acvABLV] [-C bytes] [-H format] -[-M message] [-O [[user@@]host:]archive] [-F [[user@@]host:]archive] -[--file=[[user@@]host:]archive] [--format=format] -[--message=message][--null] [--reset-access-time] [--verbose] -[--dot] [--append] [--block-size=blocks] [--dereference] -[--io-size=bytes] [--rsh-command=command] [--help] [--version] -< name-list [> archive] -@end example - -@node Copy-in mode, Copy-pass mode, Copy-out mode, Invoking cpio -@comment node-name, next, previous, up -@section Copy-in mode - -In copy-in mode, cpio copies files out of an archive or lists the -archive contents. It reads the archive from the standard input. Any -non-option command line arguments are shell globbing patterns; only -files in the archive whose names match one or more of those patterns are -copied from the archive. Unlike in the shell, an initial @samp{.} in a -filename does match a wildcard at the start of a pattern, and a @samp{/} in a -filename can match wildcards. If no patterns are given, all files are -extracted. @xref{Options}. - -@example -cpio @{-i|--extract@} [-bcdfmnrtsuvBSV] [-C bytes] [-E file] -[-H format] [-M message] [-R [user][:.][group]] -[-I [[user@@]host:]archive] [-F [[user@@]host:]archive] -[--file=[[user@@]host:]archive] [--make-directories] -[--nonmatching] [--preserve-modification-time] -[--numeric-uid-gid] [--rename] [--list] [--swap-bytes] [--swap] -[--dot] [--unconditional] [--verbose] [--block-size=blocks] -[--swap-halfwords] [--io-size=bytes] [--pattern-file=file] -[--format=format] [--owner=[user][:.][group]] -[--no-preserve-owner] [--message=message] [--help] [--version] -[--absolute-filenames] [--sparse] [-only-verify-crc] [-quiet] -[--rsh-command=command] [pattern...] [< archive] -@end example - -@node Copy-pass mode, Options, Copy-in mode, Invoking cpio -@comment node-name, next, previous, up -@section Copy-pass mode - -In copy-pass mode, cpio copies files from one directory tree to -another, combining the copy-out and copy-in steps without actually -using an archive. It reads the list of files to copy from the -standard input; the directory into which it will copy them is given as -a non-option argument. -@xref{Options}. - -@example -cpio @{-p|--pass-through@} [-0adlmuvLV] [-R [user][:.][group]] -[--null] [--reset-access-time] [--make-directories] [--link] -[--preserve-modification-time] [--unconditional] [--verbose] -[--dot] [--dereference] [--owner=[user][:.][group]] [--sparse] -[--no-preserve-owner] [--help] [--version] destination-directory -< name-list -@end example - - - -@node Options, , Copy-pass mode, Invoking cpio -@comment node-name, next, previous, up -@section Options - - -@table @code - - -@item -0 -@itemx --null -Read a list of filenames terminated by a null character, instead of a -newline, so that files whose names contain newlines can be archived. -GNU find is one way to produce a list of null-terminated filenames. -This option may be used in copy-out and copy-pass modes. - -@item -a -@itemx --reset-access-time -Reset the access times of files after reading them, so -that it does not look like they have just been read. - -@item -A -@itemx --append -Append to an existing archive. Only works in copy-out -mode. The archive must be a disk file specified with -the @option{-O} or @option{-F} (@option{--file}) option. - -@item -b -@itemx --swap -Swap both halfwords of words and bytes of halfwords in the data. -Equivalent to -sS. This option may be used in copy-in mode. Use this -option to convert 32-bit integers between big-endian and little-endian -machines. - -@item -B -Set the I/O block size to 5120 bytes. Initially the -block size is 512 bytes. - -@item --block-size=@var{block-size} -Set the I/O block size to @var{block-size} * 512 bytes. - -@item -c -Use the old portable (ASCII) archive format. - -@item -C @var{io-size} -@itemx --io-size=@var{io-size} -Set the I/O block size to @var{io-size} bytes. - -@item -d -@itemx --make-directories -Create leading directories where needed. - -@item -E @var{file} -@itemx --pattern-file=@var{file} -Read additional patterns specifying filenames to extract or list from -@var{file}. The lines of @var{file} are treated as if they had been non-option -arguments to cpio. This option is used in copy-in mode, - -@item -f -@itemx --nonmatching -Only copy files that do not match any of the given -patterns. - -@item -F @var{archive} -@itemx --file=@var{archive} -Archive filename to use instead of standard input or output. To use a -tape drive on another machine as the archive, use a filename that starts -with @samp{@var{hostname}:}, where @var{hostname} is the name or IP -address of the machine. The hostname can be preceded by a username and an -@samp{@@} to access the remote tape drive as that user, if you have -permission to do so (typically an entry in that user's @file{~/.rhosts} -file). - -@item --force-local -With @option{-F}, @option{-I}, or @option{-O}, take the archive file name to be a -local file even if it contains a colon, which would -ordinarily indicate a remote host name. - -@item -H @var{format} -@itemx --format=@var{format} -Use archive format @var{format}. The valid formats are listed below; the same -names are also recognized in all-caps. The default in copy-in mode is -to automatically detect the archive format, and in copy-out mode is -@samp{bin}. - -@table @samp -@item bin -The obsolete binary format. - -@item odc -The old (POSIX.1) portable format. - -@item newc -The new (SVR4) portable format, which supports file systems having more -than 65536 i-nodes. - -@item crc -The new (SVR4) portable format with a checksum added. - -@item tar -The old tar format. - -@item ustar -The POSIX.1 tar format. Also recognizes GNU tar archives, which are -similar but not identical. - -@item hpbin -The obsolete binary format used by HPUX's cpio (which stores device -files differently). - -@item hpodc -The portable format used by HPUX's cpio (which stores device files -differently). -@end table - -@item -i -@itemx --extract -Run in copy-in mode. -@xref{Copy-in mode}. - -@item -I @var{archive} -Archive filename to use instead of standard input. To use a tape drive -on another machine as the archive, use a filename that starts with -@samp{@var{hostname}:}, where @var{hostname} is the name or IP address -of the remote host. The hostname can be preceded by a username and an @samp{@@} to -access the remote tape drive as that user, if you have permission to do -so (typically an entry in that user's @file{~/.rhosts} file). - -@item -k -Ignored; for compatibility with other versions of cpio. - -@item -l -@itemx --link -Link files instead of copying them, when possible. - -@item -L -@itemx --dereference -Copy the file that a symbolic link points to, rather than the symbolic -link itself. - -@item -m -@itemx --preserve-modification-time -Retain previous file modification times when creating files. - -@item -M @var{message} -@itemx --message=@var{message} -Print @var{message} when the end of a volume of the backup media (such as a -tape or a floppy disk) is reached, to prompt the user to insert a new -volume. If @var{message} contains the string @samp{%d}, it is replaced by the -current volume number (starting at 1). - -@item -n -@itemx --numeric-uid-gid -Show numeric UID and GID instead of translating them into names when using the -@option{--verbose} option. - -@item --absolute-filenames -Do not strip leading file name components that contain ".." and -leading slashes from file names in copy-in mode - -@item --no-preserve-owner -Do not change the ownership of the files; leave them owned by the user -extracting them. This is the default for non-root users, so that users -on System V don't inadvertantly give away files. This option can be -used in copy-in mode and copy-pass mode - -@item -o -@itemx --create -Run in copy-out mode. -@xref{Copy-out mode}. - -@item -O @var{archive} -Archive filename to use instead of standard output. To use a tape drive -on another machine as the archive, use a filename that starts with -@samp{@var{hostname}:}, where @var{hostname} is the name or IP address -of the machine. The hostname can be preceded by a username and an @samp{@@} to -access the remote tape drive as that user, if you have permission to do -so (typically an entry in that user's @file{~/.rhosts} file). - -@item --only-verify-crc -Verify the CRC's of each file in the archive, when reading a CRC format -archive. Don't actually extract the files. - -@item -p -@itemx --pass-through -Run in copy-pass mode. -@xref{Copy-pass mode}. - -@item --quiet -Do not print the number of blocks copied. - -@item -r -@itemx --rename -Interactively rename files. - -@item -R @var{owner} -@itemx --owner @var{owner} - -In copy-in and copy-pass mode, set the ownership of all files created -to the specified @var{owner} (this operation is allowed only for the -super-user). In copy-out mode, store the supplied owner information in -the archive. - -The argument can be either the user name or the user name -and group name, separated by a dot or a colon, or the group name, -preceeded by a dot or a colon, as shown in the examples below: - -@smallexample -@group -cpio --owner smith -cpio --owner smith: -cpio --owner smith:users -cpio --owner :users -@end group -@end smallexample - -@noindent -If the group is omitted but the @samp{:} or @samp{.} separator is -given, as in the second example. the given user's login group will be -used. - -@item --rsh-command=@var{command} -Notifies cpio that is should use @var{command} to communicate with remote -devices. - -@item -s -@itemx --swap-bytes -Swap the bytes of each halfword (pair of bytes) in the files. This option -can be used in copy-in mode. - -@item -S -@itemx --swap-halfwords -Swap the halfwords of each word (4 bytes) in the files. This option may -be used in copy-in mode. - -@item --sparse -Write files with large blocks of zeros as sparse files. This option is -used in copy-in and copy-pass modes. - -@item -t -@itemx --list -Print a table of contents of the input. - -@item -u -@itemx --unconditional -Replace all files, without asking whether to replace -existing newer files with older files. - -@item -v -@itemx --verbose -List the files processed, or with @option{-t}, give an @samp{ls -l} style -table of contents listing. In a verbose table of contents of a ustar -archive, user and group names in the archive that do not exist on the -local system are replaced by the names that correspond locally to the -numeric UID and GID stored in the archive. - -@item -V -@itemx --dot -Print a @samp{.} for each file processed. - -@item --version -Print the cpio program version number and exit. -@end table - - -@node Media, Reports, Invoking cpio, Top -@comment node-name, next, previous, up -@chapter Magnetic Media -@cindex magnetic media - -Archives are usually written on removable media--tape cartridges, mag -tapes, or floppy disks. - -The amount of data a tape or disk holds depends not only on its size, -but also on how it is formatted. A 2400 foot long reel of mag tape -holds 40 megabytes of data when formated at 1600 bits per inch. The -physically smaller EXABYTE tape cartridge holds 2.3 gigabytes. - -Magnetic media are re-usable--once the archive on a tape is no longer -needed, the archive can be erased and the tape or disk used over. Media -quality does deteriorate with use, however. Most tapes or disks should -be disgarded when they begin to produce data errors. - -Magnetic media are written and erased using magnetic fields, and should -be protected from such fields to avoid damage to stored data. Sticking -a floppy disk to a filing cabinet using a magnet is probably not a good -idea. - -@node Reports, Concept Index, Media, Top -@chapter Reporting bugs or suggestions - -It is possible you will encounter a bug in @command{cpio}. -If this happens, we would like to hear about it. As the purpose of bug -reporting is to improve software, please be sure to include maximum -information when reporting a bug. The information needed is: - -@itemize @bullet -@item Version of the package you are using. -@item Compilation options used when configuring the package. -@item Conditions under which the bug appears. -@end itemize - -Send your report to . Allow us a couple of -days to answer. - -@node Concept Index, , Reports, Top -@comment node-name, next, previous, up -@unnumbered Concept Index -@printindex cp -@contents -@bye diff --git a/contrib/cpio/doc/version.texi b/contrib/cpio/doc/version.texi deleted file mode 100644 index c20cd8cc39c..00000000000 --- a/contrib/cpio/doc/version.texi +++ /dev/null @@ -1,4 +0,0 @@ -@set UPDATED 7 June 2007 -@set UPDATED-MONTH June 2007 -@set EDITION 2.8 -@set VERSION 2.8 diff --git a/contrib/cpio/lib/alloca_.h b/contrib/cpio/lib/alloca_.h deleted file mode 100644 index af274b9e753..00000000000 --- a/contrib/cpio/lib/alloca_.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Memory allocation on the stack. - - Copyright (C) 1995, 1999, 2001-2004, 2006-2007 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H - means there is a real alloca function. */ -#ifndef _GL_ALLOCA_H -#define _GL_ALLOCA_H - -/* alloca (N) returns a pointer to N bytes of memory - allocated on the stack, which will last until the function returns. - Use of alloca should be avoided: - - inside arguments of function calls - undefined behaviour, - - in inline functions - the allocation may actually last until the - calling function returns, - - for huge N (say, N >= 65536) - you never know how large (or small) - the stack is, and when the stack cannot fulfill the memory allocation - request, the program just crashes. - */ - -#ifndef alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# else -# include -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#endif /* _GL_ALLOCA_H */ diff --git a/contrib/cpio/lib/argp-ba.c b/contrib/cpio/lib/argp-ba.c deleted file mode 100644 index 8bb7309fdec..00000000000 --- a/contrib/cpio/lib/argp-ba.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Default definition for ARGP_PROGRAM_BUG_ADDRESS. - Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* If set by the user program, it should point to string that is the - bug-reporting address for the program. It will be printed by argp_help if - the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help - messages), embedded in a sentence that says something like `Report bugs to - ADDR.'. */ -const char *argp_program_bug_address; diff --git a/contrib/cpio/lib/argp-eexst.c b/contrib/cpio/lib/argp-eexst.c deleted file mode 100644 index bcab1c0c17f..00000000000 --- a/contrib/cpio/lib/argp-eexst.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Default definition for ARGP_ERR_EXIT_STATUS - Copyright (C) 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "argp.h" - -/* The exit status that argp will use when exiting due to a parsing error. - If not defined or set by the user program, this defaults to EX_USAGE from - . */ -error_t argp_err_exit_status = EX_USAGE; diff --git a/contrib/cpio/lib/argp-fmtstream.c b/contrib/cpio/lib/argp-fmtstream.c deleted file mode 100644 index 0dd9256f570..00000000000 --- a/contrib/cpio/lib/argp-fmtstream.c +++ /dev/null @@ -1,435 +0,0 @@ -/* Word-wrapping and line-truncating streams - Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This package emulates glibc `line_wrap_stream' semantics for systems that - don't have that. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include - -#include "argp-fmtstream.h" -#include "argp-namefrob.h" - -#ifndef ARGP_FMTSTREAM_USE_LINEWRAP - -#ifndef isblank -#define isblank(ch) ((ch)==' ' || (ch)=='\t') -#endif - -#if defined _LIBC && defined USE_IN_LIBIO -# include -# include -# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) -#endif - -#define INIT_BUF_SIZE 200 -#define PRINTF_SIZE_GUESS 150 - -/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines - written on it with LMARGIN spaces and limits them to RMARGIN columns - total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by - replacing the whitespace before them with a newline and WMARGIN spaces. - Otherwise, chars beyond RMARGIN are simply dropped until a newline. - Returns NULL if there was an error. */ -argp_fmtstream_t -__argp_make_fmtstream (FILE *stream, - size_t lmargin, size_t rmargin, ssize_t wmargin) -{ - argp_fmtstream_t fs; - - fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream)); - if (fs != NULL) - { - fs->stream = stream; - - fs->lmargin = lmargin; - fs->rmargin = rmargin; - fs->wmargin = wmargin; - fs->point_col = 0; - fs->point_offs = 0; - - fs->buf = (char *) malloc (INIT_BUF_SIZE); - if (! fs->buf) - { - free (fs); - fs = 0; - } - else - { - fs->p = fs->buf; - fs->end = fs->buf + INIT_BUF_SIZE; - } - } - - return fs; -} -#if 0 -/* Not exported. */ -#ifdef weak_alias -weak_alias (__argp_make_fmtstream, argp_make_fmtstream) -#endif -#endif - -/* Flush FS to its stream, and free it (but don't close the stream). */ -void -__argp_fmtstream_free (argp_fmtstream_t fs) -{ - __argp_fmtstream_update (fs); - if (fs->p > fs->buf) - { -#ifdef USE_IN_LIBIO - __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); -#else - fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); -#endif - } - free (fs->buf); - free (fs); -} -#if 0 -/* Not exported. */ -#ifdef weak_alias -weak_alias (__argp_fmtstream_free, argp_fmtstream_free) -#endif -#endif - -/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the - end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ -void -__argp_fmtstream_update (argp_fmtstream_t fs) -{ - char *buf, *nl; - size_t len; - - /* Scan the buffer for newlines. */ - buf = fs->buf + fs->point_offs; - while (buf < fs->p) - { - size_t r; - - if (fs->point_col == 0 && fs->lmargin != 0) - { - /* We are starting a new line. Print spaces to the left margin. */ - const size_t pad = fs->lmargin; - if (fs->p + pad < fs->end) - { - /* We can fit in them in the buffer by moving the - buffer text up and filling in the beginning. */ - memmove (buf + pad, buf, fs->p - buf); - fs->p += pad; /* Compensate for bigger buffer. */ - memset (buf, ' ', pad); /* Fill in the spaces. */ - buf += pad; /* Don't bother searching them. */ - } - else - { - /* No buffer space for spaces. Must flush. */ - size_t i; - for (i = 0; i < pad; i++) - { -#ifdef USE_IN_LIBIO - if (_IO_fwide (fs->stream, 0) > 0) - putwc_unlocked (L' ', fs->stream); - else -#endif - putc_unlocked (' ', fs->stream); - } - } - fs->point_col = pad; - } - - len = fs->p - buf; - nl = memchr (buf, '\n', len); - - if (fs->point_col < 0) - fs->point_col = 0; - - if (!nl) - { - /* The buffer ends in a partial line. */ - - if (fs->point_col + len < fs->rmargin) - { - /* The remaining buffer text is a partial line and fits - within the maximum line width. Advance point for the - characters to be written and stop scanning. */ - fs->point_col += len; - break; - } - else - /* Set the end-of-line pointer for the code below to - the end of the buffer. */ - nl = fs->p; - } - else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin) - { - /* The buffer contains a full line that fits within the maximum - line width. Reset point and scan the next line. */ - fs->point_col = 0; - buf = nl + 1; - continue; - } - - /* This line is too long. */ - r = fs->rmargin - 1; - - if (fs->wmargin < 0) - { - /* Truncate the line by overwriting the excess with the - newline and anything after it in the buffer. */ - if (nl < fs->p) - { - memmove (buf + (r - fs->point_col), nl, fs->p - nl); - fs->p -= buf + (r - fs->point_col) - nl; - /* Reset point for the next line and start scanning it. */ - fs->point_col = 0; - buf += r + 1; /* Skip full line plus \n. */ - } - else - { - /* The buffer ends with a partial line that is beyond the - maximum line width. Advance point for the characters - written, and discard those past the max from the buffer. */ - fs->point_col += len; - fs->p -= fs->point_col - r; - break; - } - } - else - { - /* Do word wrap. Go to the column just past the maximum line - width and scan back for the beginning of the word there. - Then insert a line break. */ - - char *p, *nextline; - int i; - - p = buf + (r + 1 - fs->point_col); - while (p >= buf && !isblank (*p)) - --p; - nextline = p + 1; /* This will begin the next line. */ - - if (nextline > buf) - { - /* Swallow separating blanks. */ - if (p >= buf) - do - --p; - while (p >= buf && isblank (*p)); - nl = p + 1; /* The newline will replace the first blank. */ - } - else - { - /* A single word that is greater than the maximum line width. - Oh well. Put it on an overlong line by itself. */ - p = buf + (r + 1 - fs->point_col); - /* Find the end of the long word. */ - if (p < nl) - do - ++p; - while (p < nl && !isblank (*p)); - if (p == nl) - { - /* It already ends a line. No fussing required. */ - fs->point_col = 0; - buf = nl + 1; - continue; - } - /* We will move the newline to replace the first blank. */ - nl = p; - /* Swallow separating blanks. */ - do - ++p; - while (isblank (*p)); - /* The next line will start here. */ - nextline = p; - } - - /* Note: There are a bunch of tests below for - NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall - at the end of the buffer, and NEXTLINE is in fact empty (and so - we need not be careful to maintain its contents). */ - - if ((nextline == buf + len + 1 - ? fs->end - nl < fs->wmargin + 1 - : nextline - (nl + 1) < fs->wmargin) - && fs->p > nextline) - { - /* The margin needs more blanks than we removed. */ - if (fs->end - fs->p > fs->wmargin + 1) - /* Make some space for them. */ - { - size_t mv = fs->p - nextline; - memmove (nl + 1 + fs->wmargin, nextline, mv); - nextline = nl + 1 + fs->wmargin; - len = nextline + mv - buf; - *nl++ = '\n'; - } - else - /* Output the first line so we can use the space. */ - { -#ifdef _LIBC - __fxprintf (fs->stream, "%.*s\n", - (int) (nl - fs->buf), fs->buf); -#else - if (nl > fs->buf) - fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream); - putc_unlocked ('\n', fs->stream); -#endif - - len += buf - fs->buf; - nl = buf = fs->buf; - } - } - else - /* We can fit the newline and blanks in before - the next word. */ - *nl++ = '\n'; - - if (nextline - nl >= fs->wmargin - || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin)) - /* Add blanks up to the wrap margin column. */ - for (i = 0; i < fs->wmargin; ++i) - *nl++ = ' '; - else - for (i = 0; i < fs->wmargin; ++i) -#ifdef USE_IN_LIBIO - if (_IO_fwide (fs->stream, 0) > 0) - putwc_unlocked (L' ', fs->stream); - else -#endif - putc_unlocked (' ', fs->stream); - - /* Copy the tail of the original buffer into the current buffer - position. */ - if (nl < nextline) - memmove (nl, nextline, buf + len - nextline); - len -= nextline - buf; - - /* Continue the scan on the remaining lines in the buffer. */ - buf = nl; - - /* Restore bufp to include all the remaining text. */ - fs->p = nl + len; - - /* Reset the counter of what has been output this line. If wmargin - is 0, we want to avoid the lmargin getting added, so we set - point_col to a magic value of -1 in that case. */ - fs->point_col = fs->wmargin ? fs->wmargin : -1; - } - } - - /* Remember that we've scanned as far as the end of the buffer. */ - fs->point_offs = fs->p - fs->buf; -} - -/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by - growing the buffer, or by flushing it. True is returned iff we succeed. */ -int -__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount) -{ - if ((size_t) (fs->end - fs->p) < amount) - { - ssize_t wrote; - - /* Flush FS's buffer. */ - __argp_fmtstream_update (fs); - -#ifdef _LIBC - __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); - wrote = fs->p - fs->buf; -#else - wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); -#endif - if (wrote == fs->p - fs->buf) - { - fs->p = fs->buf; - fs->point_offs = 0; - } - else - { - fs->p -= wrote; - fs->point_offs -= wrote; - memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf); - return 0; - } - - if ((size_t) (fs->end - fs->buf) < amount) - /* Gotta grow the buffer. */ - { - size_t old_size = fs->end - fs->buf; - size_t new_size = old_size + amount; - char *new_buf; - - if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size))) - { - __set_errno (ENOMEM); - return 0; - } - - fs->buf = new_buf; - fs->end = new_buf + new_size; - fs->p = fs->buf; - } - } - - return 1; -} - -ssize_t -__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) -{ - int out; - size_t avail; - size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */ - - do - { - va_list args; - - if (! __argp_fmtstream_ensure (fs, size_guess)) - return -1; - - va_start (args, fmt); - avail = fs->end - fs->p; - out = __vsnprintf (fs->p, avail, fmt, args); - va_end (args); - if ((size_t) out >= avail) - size_guess = out + 1; - } - while ((size_t) out >= avail); - - fs->p += out; - - return out; -} -#if 0 -/* Not exported. */ -#ifdef weak_alias -weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) -#endif -#endif - -#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ diff --git a/contrib/cpio/lib/argp-fmtstream.h b/contrib/cpio/lib/argp-fmtstream.h deleted file mode 100644 index e045a723da4..00000000000 --- a/contrib/cpio/lib/argp-fmtstream.h +++ /dev/null @@ -1,301 +0,0 @@ -/* Word-wrapping and line-truncating streams. - Copyright (C) 1997, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This package emulates glibc `line_wrap_stream' semantics for systems that - don't have that. If the system does have it, it is just a wrapper for - that. This header file is only used internally while compiling argp, and - shouldn't be installed. */ - -#ifndef _ARGP_FMTSTREAM_H -#define _ARGP_FMTSTREAM_H - -#include -#include -#include - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__ -# define __format__ format -# define __printf__ printf -# endif -#endif - -#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \ - || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)) -/* line_wrap_stream is available, so use that. */ -#define ARGP_FMTSTREAM_USE_LINEWRAP -#endif - -#ifdef ARGP_FMTSTREAM_USE_LINEWRAP -/* Just be a simple wrapper for line_wrap_stream; the semantics are - *slightly* different, as line_wrap_stream doesn't actually make a new - object, it just modifies the given stream (reversibly) to do - line-wrapping. Since we control who uses this code, it doesn't matter. */ - -#include - -typedef FILE *argp_fmtstream_t; - -#define argp_make_fmtstream line_wrap_stream -#define __argp_make_fmtstream line_wrap_stream -#define argp_fmtstream_free line_unwrap_stream -#define __argp_fmtstream_free line_unwrap_stream - -#define __argp_fmtstream_putc(fs,ch) putc(ch,fs) -#define argp_fmtstream_putc(fs,ch) putc(ch,fs) -#define __argp_fmtstream_puts(fs,str) fputs(str,fs) -#define argp_fmtstream_puts(fs,str) fputs(str,fs) -#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) -#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) -#define __argp_fmtstream_printf fprintf -#define argp_fmtstream_printf fprintf - -#define __argp_fmtstream_lmargin line_wrap_lmargin -#define argp_fmtstream_lmargin line_wrap_lmargin -#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin -#define argp_fmtstream_set_lmargin line_wrap_set_lmargin -#define __argp_fmtstream_rmargin line_wrap_rmargin -#define argp_fmtstream_rmargin line_wrap_rmargin -#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin -#define argp_fmtstream_set_rmargin line_wrap_set_rmargin -#define __argp_fmtstream_wmargin line_wrap_wmargin -#define argp_fmtstream_wmargin line_wrap_wmargin -#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin -#define argp_fmtstream_set_wmargin line_wrap_set_wmargin -#define __argp_fmtstream_point line_wrap_point -#define argp_fmtstream_point line_wrap_point - -#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */ -/* Guess we have to define our own version. */ - -struct argp_fmtstream -{ - FILE *stream; /* The stream we're outputting to. */ - - size_t lmargin, rmargin; /* Left and right margins. */ - ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */ - - /* Point in buffer to which we've processed for wrapping, but not output. */ - size_t point_offs; - /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */ - ssize_t point_col; - - char *buf; /* Output buffer. */ - char *p; /* Current end of text in BUF. */ - char *end; /* Absolute end of BUF. */ -}; - -typedef struct argp_fmtstream *argp_fmtstream_t; - -/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines - written on it with LMARGIN spaces and limits them to RMARGIN columns - total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by - replacing the whitespace before them with a newline and WMARGIN spaces. - Otherwise, chars beyond RMARGIN are simply dropped until a newline. - Returns NULL if there was an error. */ -extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream, - size_t __lmargin, - size_t __rmargin, - ssize_t __wmargin); -extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream, - size_t __lmargin, - size_t __rmargin, - ssize_t __wmargin); - -/* Flush __FS to its stream, and free it (but don't close the stream). */ -extern void __argp_fmtstream_free (argp_fmtstream_t __fs); -extern void argp_fmtstream_free (argp_fmtstream_t __fs); - -extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs, - const char *__fmt, ...) - __attribute__ ((__format__ (printf, 2, 3))); -extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, - const char *__fmt, ...) - __attribute__ ((__format__ (printf, 2, 3))); - -extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); -extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); - -extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); -extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); - -extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs, - const char *__str, size_t __len); -extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, - const char *__str, size_t __len); - -/* Access macros for various bits of state. */ -#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) -#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin) -#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin) -#define __argp_fmtstream_lmargin argp_fmtstream_lmargin -#define __argp_fmtstream_rmargin argp_fmtstream_rmargin -#define __argp_fmtstream_wmargin argp_fmtstream_wmargin - -/* Set __FS's left margin to LMARGIN and return the old value. */ -extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, - size_t __lmargin); -extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, - size_t __lmargin); - -/* Set __FS's right margin to __RMARGIN and return the old value. */ -extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, - size_t __rmargin); -extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, - size_t __rmargin); - -/* Set __FS's wrap margin to __WMARGIN and return the old value. */ -extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, - size_t __wmargin); -extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, - size_t __wmargin); - -/* Return the column number of the current output point in __FS. */ -extern size_t argp_fmtstream_point (argp_fmtstream_t __fs); -extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs); - -/* Internal routines. */ -extern void _argp_fmtstream_update (argp_fmtstream_t __fs); -extern void __argp_fmtstream_update (argp_fmtstream_t __fs); -extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); -extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); - -#ifdef __OPTIMIZE__ -/* Inline versions of above routines. */ - -#if !_LIBC -#define __argp_fmtstream_putc argp_fmtstream_putc -#define __argp_fmtstream_puts argp_fmtstream_puts -#define __argp_fmtstream_write argp_fmtstream_write -#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin -#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin -#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin -#define __argp_fmtstream_point argp_fmtstream_point -#define __argp_fmtstream_update _argp_fmtstream_update -#define __argp_fmtstream_ensure _argp_fmtstream_ensure -#endif - -#ifndef ARGP_FS_EI -#define ARGP_FS_EI extern inline -#endif - -ARGP_FS_EI size_t -__argp_fmtstream_write (argp_fmtstream_t __fs, - const char *__str, size_t __len) -{ - if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) - { - memcpy (__fs->p, __str, __len); - __fs->p += __len; - return __len; - } - else - return 0; -} - -ARGP_FS_EI int -__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str) -{ - size_t __len = strlen (__str); - if (__len) - { - size_t __wrote = __argp_fmtstream_write (__fs, __str, __len); - return __wrote == __len ? 0 : -1; - } - else - return 0; -} - -ARGP_FS_EI int -__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch) -{ - if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1)) - return *__fs->p++ = __ch; - else - return EOF; -} - -/* Set __FS's left margin to __LMARGIN and return the old value. */ -ARGP_FS_EI size_t -__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin) -{ - size_t __old; - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - __old = __fs->lmargin; - __fs->lmargin = __lmargin; - return __old; -} - -/* Set __FS's right margin to __RMARGIN and return the old value. */ -ARGP_FS_EI size_t -__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin) -{ - size_t __old; - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - __old = __fs->rmargin; - __fs->rmargin = __rmargin; - return __old; -} - -/* Set FS's wrap margin to __WMARGIN and return the old value. */ -ARGP_FS_EI size_t -__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin) -{ - size_t __old; - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - __old = __fs->wmargin; - __fs->wmargin = __wmargin; - return __old; -} - -/* Return the column number of the current output point in __FS. */ -ARGP_FS_EI size_t -__argp_fmtstream_point (argp_fmtstream_t __fs) -{ - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - return __fs->point_col >= 0 ? __fs->point_col : 0; -} - -#if !_LIBC -#undef __argp_fmtstream_putc -#undef __argp_fmtstream_puts -#undef __argp_fmtstream_write -#undef __argp_fmtstream_set_lmargin -#undef __argp_fmtstream_set_rmargin -#undef __argp_fmtstream_set_wmargin -#undef __argp_fmtstream_point -#undef __argp_fmtstream_update -#undef __argp_fmtstream_ensure -#endif - -#endif /* __OPTIMIZE__ */ - -#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */ - -#endif /* argp-fmtstream.h */ diff --git a/contrib/cpio/lib/argp-fs-xinl.c b/contrib/cpio/lib/argp-fs-xinl.c deleted file mode 100644 index 3b4c917e020..00000000000 --- a/contrib/cpio/lib/argp-fs-xinl.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Real definitions for extern inline functions in argp-fmtstream.h - Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#define ARGP_FS_EI -#undef __OPTIMIZE__ -#define __OPTIMIZE__ 1 -#include "argp-fmtstream.h" - -#if 0 -/* Not exported. */ -/* Add weak aliases. */ -#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias) - -weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc) -weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts) -weak_alias (__argp_fmtstream_write, argp_fmtstream_write) -weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin) -weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin) -weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin) -weak_alias (__argp_fmtstream_point, argp_fmtstream_point) - -#endif -#endif diff --git a/contrib/cpio/lib/argp-help.c b/contrib/cpio/lib/argp-help.c deleted file mode 100644 index 396e73326f9..00000000000 --- a/contrib/cpio/lib/argp-help.c +++ /dev/null @@ -1,1954 +0,0 @@ -/* Hierarchial argument parsing help output - Copyright (C) 1995-2005, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_IN_LIBIO -# include -#endif - -#ifdef _LIBC -# include -# undef dgettext -# define dgettext(domain, msgid) \ - INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) -#else -# include "gettext.h" -#endif - -#include "argp.h" -#include "argp-fmtstream.h" -#include "argp-namefrob.h" - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* User-selectable (using an environment variable) formatting parameters. - - These may be specified in an environment variable called `ARGP_HELP_FMT', - with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2 - Where VALn must be a positive integer. The list of variables is in the - UPARAM_NAMES vector, below. */ - -/* Default parameters. */ -#define DUP_ARGS 0 /* True if option argument can be duplicated. */ -#define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */ -#define SHORT_OPT_COL 2 /* column in which short options start */ -#define LONG_OPT_COL 6 /* column in which long options start */ -#define DOC_OPT_COL 2 /* column in which doc options start */ -#define OPT_DOC_COL 29 /* column in which option text starts */ -#define HEADER_COL 1 /* column in which group headers are printed */ -#define USAGE_INDENT 12 /* indentation of wrapped usage lines */ -#define RMARGIN 79 /* right margin used for wrapping */ - -/* User-selectable (using an environment variable) formatting parameters. - They must all be of type `int' for the parsing code to work. */ -struct uparams -{ - /* If true, arguments for an option are shown with both short and long - options, even when a given option has both, e.g. `-x ARG, --longx=ARG'. - If false, then if an option has both, the argument is only shown with - the long one, e.g., `-x, --longx=ARG', and a message indicating that - this really means both is printed below the options. */ - int dup_args; - - /* This is true if when DUP_ARGS is false, and some duplicate arguments have - been suppressed, an explanatory message should be printed. */ - int dup_args_note; - - /* Various output columns. */ - int short_opt_col; /* column in which short options start */ - int long_opt_col; /* column in which long options start */ - int doc_opt_col; /* column in which doc options start */ - int opt_doc_col; /* column in which option text starts */ - int header_col; /* column in which group headers are printed */ - int usage_indent; /* indentation of wrapped usage lines */ - int rmargin; /* right margin used for wrapping */ - - int valid; /* True when the values in here are valid. */ -}; - -/* This is a global variable, as user options are only ever read once. */ -static struct uparams uparams = { - DUP_ARGS, DUP_ARGS_NOTE, - SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL, - USAGE_INDENT, RMARGIN, - 0 -}; - -/* A particular uparam, and what the user name is. */ -struct uparam_name -{ - const char *name; /* User name. */ - int is_bool; /* Whether it's `boolean'. */ - size_t uparams_offs; /* Location of the (int) field in UPARAMS. */ -}; - -/* The name-field mappings we know about. */ -static const struct uparam_name uparam_names[] = -{ - { "dup-args", 1, offsetof (struct uparams, dup_args) }, - { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) }, - { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) }, - { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) }, - { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) }, - { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) }, - { "header-col", 0, offsetof (struct uparams, header_col) }, - { "usage-indent", 0, offsetof (struct uparams, usage_indent) }, - { "rmargin", 0, offsetof (struct uparams, rmargin) }, - { 0 } -}; - -static void -validate_uparams (const struct argp_state *state, struct uparams *upptr) -{ - const struct uparam_name *up; - - for (up = uparam_names; up->name; up++) - { - if (up->is_bool - || up->uparams_offs == offsetof (struct uparams, rmargin)) - continue; - if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) - { - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "\ -ARGP_HELP_FMT: %s value is less than or equal to %s"), - "rmargin", up->name); - return; - } - } - uparams = *upptr; - uparams.valid = 1; -} - -/* Read user options from the environment, and fill in UPARAMS appropiately. */ -static void -fill_in_uparams (const struct argp_state *state) -{ - const char *var = getenv ("ARGP_HELP_FMT"); - struct uparams new_params = uparams; - -#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0); - - if (var) - { - /* Parse var. */ - while (*var) - { - SKIPWS (var); - - if (isalpha ((unsigned char) *var)) - { - size_t var_len; - const struct uparam_name *un; - int unspec = 0, val = 0; - const char *arg = var; - - while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_') - arg++; - var_len = arg - var; - - SKIPWS (arg); - - if (*arg == '\0' || *arg == ',') - unspec = 1; - else if (*arg == '=') - { - arg++; - SKIPWS (arg); - } - - if (unspec) - { - if (var[0] == 'n' && var[1] == 'o' && var[2] == '-') - { - val = 0; - var += 3; - var_len -= 3; - } - else - val = 1; - } - else if (isdigit ((unsigned char) *arg)) - { - val = atoi (arg); - while (isdigit ((unsigned char) *arg)) - arg++; - SKIPWS (arg); - } - - for (un = uparam_names; un->name; un++) - if (strlen (un->name) == var_len - && strncmp (var, un->name, var_len) == 0) - { - if (unspec && !un->is_bool) - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "\ -%.*s: ARGP_HELP_FMT parameter requires a value"), - (int) var_len, var); - else if (val < 0) - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "\ -%.*s: ARGP_HELP_FMT parameter must be positive"), - (int) var_len, var); - else - *(int *)((char *)&new_params + un->uparams_offs) = val; - break; - } - if (! un->name) - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, "\ -%.*s: Unknown ARGP_HELP_FMT parameter"), - (int) var_len, var); - - var = arg; - if (*var == ',') - var++; - } - else if (*var) - { - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "Garbage in ARGP_HELP_FMT: %s"), var); - break; - } - } - validate_uparams (state, &new_params); - } -} - -/* Returns true if OPT hasn't been marked invisible. Visibility only affects - whether OPT is displayed or used in sorting, not option shadowing. */ -#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN)) - -/* Returns true if OPT is an alias for an earlier option. */ -#define oalias(opt) ((opt)->flags & OPTION_ALIAS) - -/* Returns true if OPT is an documentation-only entry. */ -#define odoc(opt) ((opt)->flags & OPTION_DOC) - -/* Returns true if OPT should not be translated */ -#define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS) - -/* Returns true if OPT is the end-of-list marker for a list of options. */ -#define oend(opt) __option_is_end (opt) - -/* Returns true if OPT has a short option. */ -#define oshort(opt) __option_is_short (opt) - -/* - The help format for a particular option is like: - - -xARG, -yARG, --long1=ARG, --long2=ARG Documentation... - - Where ARG will be omitted if there's no argument, for this option, or - will be surrounded by "[" and "]" appropiately if the argument is - optional. The documentation string is word-wrapped appropiately, and if - the list of options is long enough, it will be started on a separate line. - If there are no short options for a given option, the first long option is - indented slighly in a way that's supposed to make most long options appear - to be in a separate column. - - For example, the following output (from ps): - - -p PID, --pid=PID List the process PID - --pgrp=PGRP List processes in the process group PGRP - -P, -x, --no-parent Include processes without parents - -Q, --all-fields Don't elide unusable fields (normally if there's - some reason ps can't print a field for any - process, it's removed from the output entirely) - -r, --reverse, --gratuitously-long-reverse-option - Reverse the order of any sort - --session[=SID] Add the processes from the session SID (which - defaults to the sid of the current process) - - Here are some more options: - -f ZOT, --foonly=ZOT Glork a foonly - -z, --zaza Snit a zar - - -?, --help Give this help list - --usage Give a short usage message - -V, --version Print program version - - The struct argp_option array for the above could look like: - - { - {"pid", 'p', "PID", 0, "List the process PID"}, - {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"}, - {"no-parent", 'P', 0, 0, "Include processes without parents"}, - {0, 'x', 0, OPTION_ALIAS}, - {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally" - " if there's some reason ps can't" - " print a field for any process, it's" - " removed from the output entirely)" }, - {"reverse", 'r', 0, 0, "Reverse the order of any sort"}, - {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS}, - {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL, - "Add the processes from the session" - " SID (which defaults to the sid of" - " the current process)" }, - - {0,0,0,0, "Here are some more options:"}, - {"foonly", 'f', "ZOT", 0, "Glork a foonly"}, - {"zaza", 'z', 0, 0, "Snit a zar"}, - - {0} - } - - Note that the last three options are automatically supplied by argp_parse, - unless you tell it not to with ARGP_NO_HELP. - -*/ - -/* Returns true if CH occurs between BEG and END. */ -static int -find_char (char ch, char *beg, char *end) -{ - while (beg < end) - if (*beg == ch) - return 1; - else - beg++; - return 0; -} - -struct hol_cluster; /* fwd decl */ - -struct hol_entry -{ - /* First option. */ - const struct argp_option *opt; - /* Number of options (including aliases). */ - unsigned num; - - /* A pointers into the HOL's short_options field, to the first short option - letter for this entry. The order of the characters following this point - corresponds to the order of options pointed to by OPT, and there are at - most NUM. A short option recorded in a option following OPT is only - valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's - probably been shadowed by some other entry). */ - char *short_options; - - /* Entries are sorted by their group first, in the order: - 1, 2, ..., n, 0, -m, ..., -2, -1 - and then alphabetically within each group. The default is 0. */ - int group; - - /* The cluster of options this entry belongs to, or 0 if none. */ - struct hol_cluster *cluster; - - /* The argp from which this option came. */ - const struct argp *argp; - - /* Position in the array */ - unsigned ord; -}; - -/* A cluster of entries to reflect the argp tree structure. */ -struct hol_cluster -{ - /* A descriptive header printed before options in this cluster. */ - const char *header; - - /* Used to order clusters within the same group with the same parent, - according to the order in which they occurred in the parent argp's child - list. */ - int index; - - /* How to sort this cluster with respect to options and other clusters at the - same depth (clusters always follow options in the same group). */ - int group; - - /* The cluster to which this cluster belongs, or 0 if it's at the base - level. */ - struct hol_cluster *parent; - - /* The argp from which this cluster is (eventually) derived. */ - const struct argp *argp; - - /* The distance this cluster is from the root. */ - int depth; - - /* Clusters in a given hol are kept in a linked list, to make freeing them - possible. */ - struct hol_cluster *next; -}; - -/* A list of options for help. */ -struct hol -{ - /* An array of hol_entry's. */ - struct hol_entry *entries; - /* The number of entries in this hol. If this field is zero, the others - are undefined. */ - unsigned num_entries; - - /* A string containing all short options in this HOL. Each entry contains - pointers into this string, so the order can't be messed with blindly. */ - char *short_options; - - /* Clusters of entries in this hol. */ - struct hol_cluster *clusters; -}; - -/* Create a struct hol from the options in ARGP. CLUSTER is the - hol_cluster in which these entries occur, or 0, if at the root. */ -static struct hol * -make_hol (const struct argp *argp, struct hol_cluster *cluster) -{ - char *so; - const struct argp_option *o; - const struct argp_option *opts = argp->options; - struct hol_entry *entry; - unsigned num_short_options = 0; - struct hol *hol = malloc (sizeof (struct hol)); - - assert (hol); - - hol->num_entries = 0; - hol->clusters = 0; - - if (opts) - { - int cur_group = 0; - - /* The first option must not be an alias. */ - assert (! oalias (opts)); - - /* Calculate the space needed. */ - for (o = opts; ! oend (o); o++) - { - if (! oalias (o)) - hol->num_entries++; - if (oshort (o)) - num_short_options++; /* This is an upper bound. */ - } - - hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries); - hol->short_options = malloc (num_short_options + 1); - - assert (hol->entries && hol->short_options); - if (SIZE_MAX <= UINT_MAX) - assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry)); - - /* Fill in the entries. */ - so = hol->short_options; - for (o = opts, entry = hol->entries; ! oend (o); entry++) - { - entry->opt = o; - entry->num = 0; - entry->short_options = so; - entry->group = cur_group = - o->group - ? o->group - : ((!o->name && !o->key) - ? cur_group + 1 - : cur_group); - entry->cluster = cluster; - entry->argp = argp; - - do - { - entry->num++; - if (oshort (o) && ! find_char (o->key, hol->short_options, so)) - /* O has a valid short option which hasn't already been used.*/ - *so++ = o->key; - o++; - } - while (! oend (o) && oalias (o)); - } - *so = '\0'; /* null terminated so we can find the length */ - } - - return hol; -} - -/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the - associated argp child list entry), INDEX, and PARENT, and return a pointer - to it. ARGP is the argp that this cluster results from. */ -static struct hol_cluster * -hol_add_cluster (struct hol *hol, int group, const char *header, int index, - struct hol_cluster *parent, const struct argp *argp) -{ - struct hol_cluster *cl = malloc (sizeof (struct hol_cluster)); - if (cl) - { - cl->group = group; - cl->header = header; - - cl->index = index; - cl->parent = parent; - cl->argp = argp; - cl->depth = parent ? parent->depth + 1 : 0; - - cl->next = hol->clusters; - hol->clusters = cl; - } - return cl; -} - -/* Free HOL and any resources it uses. */ -static void -hol_free (struct hol *hol) -{ - struct hol_cluster *cl = hol->clusters; - - while (cl) - { - struct hol_cluster *next = cl->next; - free (cl); - cl = next; - } - - if (hol->num_entries > 0) - { - free (hol->entries); - free (hol->short_options); - } - - free (hol); -} - -static int -hol_entry_short_iterate (const struct hol_entry *entry, - int (*func)(const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie), - const char *domain, void *cookie) -{ - unsigned nopts; - int val = 0; - const struct argp_option *opt, *real = entry->opt; - char *so = entry->short_options; - - for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) - if (oshort (opt) && *so == opt->key) - { - if (!oalias (opt)) - real = opt; - if (ovisible (opt)) - val = (*func)(opt, real, domain, cookie); - so++; - } - - return val; -} - -static inline int -__attribute__ ((always_inline)) -hol_entry_long_iterate (const struct hol_entry *entry, - int (*func)(const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie), - const char *domain, void *cookie) -{ - unsigned nopts; - int val = 0; - const struct argp_option *opt, *real = entry->opt; - - for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) - if (opt->name) - { - if (!oalias (opt)) - real = opt; - if (ovisible (opt)) - val = (*func)(opt, real, domain, cookie); - } - - return val; -} - -/* Iterator that returns true for the first short option. */ -static inline int -until_short (const struct argp_option *opt, const struct argp_option *real, - const char *domain, void *cookie) -{ - return oshort (opt) ? opt->key : 0; -} - -/* Returns the first valid short option in ENTRY, or 0 if there is none. */ -static char -hol_entry_first_short (const struct hol_entry *entry) -{ - return hol_entry_short_iterate (entry, until_short, - entry->argp->argp_domain, 0); -} - -/* Returns the first valid long option in ENTRY, or 0 if there is none. */ -static const char * -hol_entry_first_long (const struct hol_entry *entry) -{ - const struct argp_option *opt; - unsigned num; - for (opt = entry->opt, num = entry->num; num > 0; opt++, num--) - if (opt->name && ovisible (opt)) - return opt->name; - return 0; -} - -/* Returns the entry in HOL with the long option name NAME, or 0 if there is - none. */ -static struct hol_entry * -hol_find_entry (struct hol *hol, const char *name) -{ - struct hol_entry *entry = hol->entries; - unsigned num_entries = hol->num_entries; - - while (num_entries-- > 0) - { - const struct argp_option *opt = entry->opt; - unsigned num_opts = entry->num; - - while (num_opts-- > 0) - if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0) - return entry; - else - opt++; - - entry++; - } - - return 0; -} - -/* If an entry with the long option NAME occurs in HOL, set it's special - sort position to GROUP. */ -static void -hol_set_group (struct hol *hol, const char *name, int group) -{ - struct hol_entry *entry = hol_find_entry (hol, name); - if (entry) - entry->group = group; -} - -/* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1. - EQ is what to return if GROUP1 and GROUP2 are the same. */ -static int -group_cmp (int group1, int group2, int eq) -{ - if (group1 == group2) - return eq; - else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0)) - return group1 - group2; - else - return group2 - group1; -} - -/* Compare clusters CL1 & CL2 by the order that they should appear in - output. */ -static int -hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2) -{ - /* If one cluster is deeper than the other, use its ancestor at the same - level, so that finding the common ancestor is straightforward. - - clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */ - while (cl1->depth > cl2->depth) - cl1 = cl1->parent; - while (cl2->depth > cl1->depth) - cl2 = cl2->parent; - - /* Now reduce both clusters to their ancestors at the point where both have - a common parent; these can be directly compared. */ - while (cl1->parent != cl2->parent) - cl1 = cl1->parent, cl2 = cl2->parent; - - return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index); -} - -/* Return the ancestor of CL that's just below the root (i.e., has a parent - of 0). */ -static struct hol_cluster * -hol_cluster_base (struct hol_cluster *cl) -{ - while (cl->parent) - cl = cl->parent; - return cl; -} - -/* Return true if CL1 is a child of CL2. */ -static int -hol_cluster_is_child (const struct hol_cluster *cl1, - const struct hol_cluster *cl2) -{ - while (cl1 && cl1 != cl2) - cl1 = cl1->parent; - return cl1 == cl2; -} - -/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail - that should be used for comparisons, and returns true iff it should be - treated as a non-option. */ -static int -canon_doc_option (const char **name) -{ - int non_opt; - - if (!*name) - non_opt = 1; - else - { - /* Skip initial whitespace. */ - while (isspace ((unsigned char) **name)) - (*name)++; - /* Decide whether this looks like an option (leading `-') or not. */ - non_opt = (**name != '-'); - /* Skip until part of name used for sorting. */ - while (**name && !isalnum ((unsigned char) **name)) - (*name)++; - } - return non_opt; -} - -#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1) - -/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help - listing. */ -static int -hol_entry_cmp (const struct hol_entry *entry1, - const struct hol_entry *entry2) -{ - /* The group numbers by which the entries should be ordered; if either is - in a cluster, then this is just the group within the cluster. */ - int group1 = entry1->group, group2 = entry2->group; - int rc; - - if (entry1->cluster != entry2->cluster) - { - /* The entries are not within the same cluster, so we can't compare them - directly, we have to use the appropiate clustering level too. */ - if (! entry1->cluster) - /* ENTRY1 is at the `base level', not in a cluster, so we have to - compare it's group number with that of the base cluster in which - ENTRY2 resides. Note that if they're in the same group, the - clustered option always comes laster. */ - return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1); - else if (! entry2->cluster) - /* Likewise, but ENTRY2's not in a cluster. */ - return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1); - else - /* Both entries are in clusters, we can just compare the clusters. */ - return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ? - rc : HOL_ENTRY_PTRCMP(entry1, entry2); - } - else if (group1 == group2) - /* The entries are both in the same cluster and group, so compare them - alphabetically. */ - { - int short1 = hol_entry_first_short (entry1); - int short2 = hol_entry_first_short (entry2); - int doc1 = odoc (entry1->opt); - int doc2 = odoc (entry2->opt); - const char *long1 = hol_entry_first_long (entry1); - const char *long2 = hol_entry_first_long (entry2); - - if (doc1) - doc1 = canon_doc_option (&long1); - if (doc2) - doc2 = canon_doc_option (&long2); - - if (doc1 != doc2) - /* `documentation' options always follow normal options (or - documentation options that *look* like normal options). */ - return doc1 - doc2; - else if (!short1 && !short2 && long1 && long2) - /* Only long options. */ - return (rc = __strcasecmp (long1, long2)) ? - rc : HOL_ENTRY_PTRCMP(entry1, entry2); - else - /* Compare short/short, long/short, short/long, using the first - character of long options. Entries without *any* valid - options (such as options with OPTION_HIDDEN set) will be put - first, but as they're not displayed, it doesn't matter where - they are. */ - { - char first1 = short1 ? short1 : long1 ? *long1 : 0; - char first2 = short2 ? short2 : long2 ? *long2 : 0; -#ifdef _tolower - int lower_cmp = _tolower (first1) - _tolower (first2); -#else - int lower_cmp = tolower (first1) - tolower (first2); -#endif - /* Compare ignoring case, except when the options are both the - same letter, in which case lower-case always comes first. */ - return lower_cmp ? lower_cmp : - (rc = first2 - first1) ? - rc : HOL_ENTRY_PTRCMP(entry1, entry2); - } - } - else - /* Within the same cluster, but not the same group, so just compare - groups. */ - return group_cmp (group1, group2, HOL_ENTRY_PTRCMP(entry1, entry2)); -} - -/* Version of hol_entry_cmp with correct signature for qsort. */ -static int -hol_entry_qcmp (const void *entry1_v, const void *entry2_v) -{ - return hol_entry_cmp (entry1_v, entry2_v); -} - -/* Sort HOL by group and alphabetically by option name (with short options - taking precedence over long). Since the sorting is for display purposes - only, the shadowing of options isn't effected. */ -static void -hol_sort (struct hol *hol) -{ - if (hol->num_entries > 0) - { - unsigned i; - struct hol_entry *e; - for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++) - e->ord = i; - qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry), - hol_entry_qcmp); - } -} - -/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow - any in MORE with the same name. */ -static void -hol_append (struct hol *hol, struct hol *more) -{ - struct hol_cluster **cl_end = &hol->clusters; - - /* Steal MORE's cluster list, and add it to the end of HOL's. */ - while (*cl_end) - cl_end = &(*cl_end)->next; - *cl_end = more->clusters; - more->clusters = 0; - - /* Merge entries. */ - if (more->num_entries > 0) - { - if (hol->num_entries == 0) - { - hol->num_entries = more->num_entries; - hol->entries = more->entries; - hol->short_options = more->short_options; - more->num_entries = 0; /* Mark MORE's fields as invalid. */ - } - else - /* Append the entries in MORE to those in HOL, taking care to only add - non-shadowed SHORT_OPTIONS values. */ - { - unsigned left; - char *so, *more_so; - struct hol_entry *e; - unsigned num_entries = hol->num_entries + more->num_entries; - struct hol_entry *entries = - malloc (num_entries * sizeof (struct hol_entry)); - unsigned hol_so_len = strlen (hol->short_options); - char *short_options = - malloc (hol_so_len + strlen (more->short_options) + 1); - - assert (entries && short_options); - if (SIZE_MAX <= UINT_MAX) - assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry)); - - __mempcpy (__mempcpy (entries, hol->entries, - hol->num_entries * sizeof (struct hol_entry)), - more->entries, - more->num_entries * sizeof (struct hol_entry)); - - __mempcpy (short_options, hol->short_options, hol_so_len); - - /* Fix up the short options pointers from HOL. */ - for (e = entries, left = hol->num_entries; left > 0; e++, left--) - e->short_options += (short_options - hol->short_options); - - /* Now add the short options from MORE, fixing up its entries - too. */ - so = short_options + hol_so_len; - more_so = more->short_options; - for (left = more->num_entries; left > 0; e++, left--) - { - int opts_left; - const struct argp_option *opt; - - e->short_options = so; - - for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--) - { - int ch = *more_so; - if (oshort (opt) && ch == opt->key) - /* The next short option in MORE_SO, CH, is from OPT. */ - { - if (! find_char (ch, short_options, - short_options + hol_so_len)) - /* The short option CH isn't shadowed by HOL's options, - so add it to the sum. */ - *so++ = ch; - more_so++; - } - } - } - - *so = '\0'; - - free (hol->entries); - free (hol->short_options); - - hol->entries = entries; - hol->num_entries = num_entries; - hol->short_options = short_options; - } - } - - hol_free (more); -} - -/* Inserts enough spaces to make sure STREAM is at column COL. */ -static void -indent_to (argp_fmtstream_t stream, unsigned col) -{ - int needed = col - __argp_fmtstream_point (stream); - while (needed-- > 0) - __argp_fmtstream_putc (stream, ' '); -} - -/* Output to STREAM either a space, or a newline if there isn't room for at - least ENSURE characters before the right margin. */ -static void -space (argp_fmtstream_t stream, size_t ensure) -{ - if (__argp_fmtstream_point (stream) + ensure - >= __argp_fmtstream_rmargin (stream)) - __argp_fmtstream_putc (stream, '\n'); - else - __argp_fmtstream_putc (stream, ' '); -} - -/* If the option REAL has an argument, we print it in using the printf - format REQ_FMT or OPT_FMT depending on whether it's a required or - optional argument. */ -static void -arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt, - const char *domain, argp_fmtstream_t stream) -{ - if (real->arg) - { - if (real->flags & OPTION_ARG_OPTIONAL) - __argp_fmtstream_printf (stream, opt_fmt, - dgettext (domain, real->arg)); - else - __argp_fmtstream_printf (stream, req_fmt, - dgettext (domain, real->arg)); - } -} - -/* Helper functions for hol_entry_help. */ - -/* State used during the execution of hol_help. */ -struct hol_help_state -{ - /* PREV_ENTRY should contain the previous entry printed, or 0. */ - struct hol_entry *prev_entry; - - /* If an entry is in a different group from the previous one, and SEP_GROUPS - is true, then a blank line will be printed before any output. */ - int sep_groups; - - /* True if a duplicate option argument was suppressed (only ever set if - UPARAMS.dup_args is false). */ - int suppressed_dup_arg; -}; - -/* Some state used while printing a help entry (used to communicate with - helper functions). See the doc for hol_entry_help for more info, as most - of the fields are copied from its arguments. */ -struct pentry_state -{ - const struct hol_entry *entry; - argp_fmtstream_t stream; - struct hol_help_state *hhstate; - - /* True if nothing's been printed so far. */ - int first; - - /* If non-zero, the state that was used to print this help. */ - const struct argp_state *state; -}; - -/* If a user doc filter should be applied to DOC, do so. */ -static const char * -filter_doc (const char *doc, int key, const struct argp *argp, - const struct argp_state *state) -{ - if (argp->help_filter) - /* We must apply a user filter to this output. */ - { - void *input = __argp_input (argp, state); - return (*argp->help_filter) (key, doc, input); - } - else - /* No filter. */ - return doc; -} - -/* Prints STR as a header line, with the margin lines set appropiately, and - notes the fact that groups should be separated with a blank line. ARGP is - the argp that should dictate any user doc filtering to take place. Note - that the previous wrap margin isn't restored, but the left margin is reset - to 0. */ -static void -print_header (const char *str, const struct argp *argp, - struct pentry_state *pest) -{ - const char *tstr = dgettext (argp->argp_domain, str); - const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state); - - if (fstr) - { - if (*fstr) - { - if (pest->hhstate->prev_entry) - /* Precede with a blank line. */ - __argp_fmtstream_putc (pest->stream, '\n'); - indent_to (pest->stream, uparams.header_col); - __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col); - __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col); - __argp_fmtstream_puts (pest->stream, fstr); - __argp_fmtstream_set_lmargin (pest->stream, 0); - __argp_fmtstream_putc (pest->stream, '\n'); - } - - pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */ - } - - if (fstr != tstr) - free ((char *) fstr); -} - -/* Inserts a comma if this isn't the first item on the line, and then makes - sure we're at least to column COL. If this *is* the first item on a line, - prints any pending whitespace/headers that should precede this line. Also - clears FIRST. */ -static void -comma (unsigned col, struct pentry_state *pest) -{ - if (pest->first) - { - const struct hol_entry *pe = pest->hhstate->prev_entry; - const struct hol_cluster *cl = pest->entry->cluster; - - if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group) - __argp_fmtstream_putc (pest->stream, '\n'); - - if (cl && cl->header && *cl->header - && (!pe - || (pe->cluster != cl - && !hol_cluster_is_child (pe->cluster, cl)))) - /* If we're changing clusters, then this must be the start of the - ENTRY's cluster unless that is an ancestor of the previous one - (in which case we had just popped into a sub-cluster for a bit). - If so, then print the cluster's header line. */ - { - int old_wm = __argp_fmtstream_wmargin (pest->stream); - print_header (cl->header, cl->argp, pest); - __argp_fmtstream_set_wmargin (pest->stream, old_wm); - } - - pest->first = 0; - } - else - __argp_fmtstream_puts (pest->stream, ", "); - - indent_to (pest->stream, col); -} - -/* Print help for ENTRY to STREAM. */ -static void -hol_entry_help (struct hol_entry *entry, const struct argp_state *state, - argp_fmtstream_t stream, struct hol_help_state *hhstate) -{ - unsigned num; - const struct argp_option *real = entry->opt, *opt; - char *so = entry->short_options; - int have_long_opt = 0; /* We have any long options. */ - /* Saved margins. */ - int old_lm = __argp_fmtstream_set_lmargin (stream, 0); - int old_wm = __argp_fmtstream_wmargin (stream); - /* PEST is a state block holding some of our variables that we'd like to - share with helper functions. */ - struct pentry_state pest; - - pest.entry = entry; - pest.stream = stream; - pest.hhstate = hhstate; - pest.first = 1; - pest.state = state; - - if (! odoc (real)) - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (opt->name && ovisible (opt)) - { - have_long_opt = 1; - break; - } - - /* First emit short options. */ - __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */ - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (oshort (opt) && opt->key == *so) - /* OPT has a valid (non shadowed) short option. */ - { - if (ovisible (opt)) - { - comma (uparams.short_opt_col, &pest); - __argp_fmtstream_putc (stream, '-'); - __argp_fmtstream_putc (stream, *so); - if (!have_long_opt || uparams.dup_args) - arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream); - else if (real->arg) - hhstate->suppressed_dup_arg = 1; - } - so++; - } - - /* Now, long options. */ - if (odoc (real)) - /* A `documentation' option. */ - { - __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col); - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (opt->name && *opt->name && ovisible (opt)) - { - comma (uparams.doc_opt_col, &pest); - /* Calling dgettext here isn't quite right, since sorting will - have been done on the original; but documentation options - should be pretty rare anyway... */ - __argp_fmtstream_puts (stream, - onotrans (opt) ? - opt->name : - dgettext (state->root_argp->argp_domain, - opt->name)); - } - } - else - /* A real long option. */ - { - int first_long_opt = 1; - - __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col); - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (opt->name && ovisible (opt)) - { - comma (uparams.long_opt_col, &pest); - __argp_fmtstream_printf (stream, "--%s", opt->name); - if (first_long_opt || uparams.dup_args) - arg (real, "=%s", "[=%s]", state->root_argp->argp_domain, - stream); - else if (real->arg) - hhstate->suppressed_dup_arg = 1; - } - } - - /* Next, documentation strings. */ - __argp_fmtstream_set_lmargin (stream, 0); - - if (pest.first) - { - /* Didn't print any switches, what's up? */ - if (!oshort (real) && !real->name) - /* This is a group header, print it nicely. */ - print_header (real->doc, entry->argp, &pest); - else - /* Just a totally shadowed option or null header; print nothing. */ - goto cleanup; /* Just return, after cleaning up. */ - } - else - { - const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain, - real->doc) : 0; - const char *fstr = filter_doc (tstr, real->key, entry->argp, state); - if (fstr && *fstr) - { - unsigned int col = __argp_fmtstream_point (stream); - - __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col); - __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col); - - if (col > (unsigned int) (uparams.opt_doc_col + 3)) - __argp_fmtstream_putc (stream, '\n'); - else if (col >= (unsigned int) uparams.opt_doc_col) - __argp_fmtstream_puts (stream, " "); - else - indent_to (stream, uparams.opt_doc_col); - - __argp_fmtstream_puts (stream, fstr); - } - if (fstr && fstr != tstr) - free ((char *) fstr); - - /* Reset the left margin. */ - __argp_fmtstream_set_lmargin (stream, 0); - __argp_fmtstream_putc (stream, '\n'); - } - - hhstate->prev_entry = entry; - -cleanup: - __argp_fmtstream_set_lmargin (stream, old_lm); - __argp_fmtstream_set_wmargin (stream, old_wm); -} - -/* Output a long help message about the options in HOL to STREAM. */ -static void -hol_help (struct hol *hol, const struct argp_state *state, - argp_fmtstream_t stream) -{ - unsigned num; - struct hol_entry *entry; - struct hol_help_state hhstate = { 0, 0, 0 }; - - for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--) - hol_entry_help (entry, state, stream, &hhstate); - - if (hhstate.suppressed_dup_arg && uparams.dup_args_note) - { - const char *tstr = dgettext (state->root_argp->argp_domain, "\ -Mandatory or optional arguments to long options are also mandatory or \ -optional for any corresponding short options."); - const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE, - state ? state->root_argp : 0, state); - if (fstr && *fstr) - { - __argp_fmtstream_putc (stream, '\n'); - __argp_fmtstream_puts (stream, fstr); - __argp_fmtstream_putc (stream, '\n'); - } - if (fstr && fstr != tstr) - free ((char *) fstr); - } -} - -/* Helper functions for hol_usage. */ - -/* If OPT is a short option without an arg, append its key to the string - pointer pointer to by COOKIE, and advance the pointer. */ -static int -add_argless_short_opt (const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie) -{ - char **snao_end = cookie; - if (!(opt->arg || real->arg) - && !((opt->flags | real->flags) & OPTION_NO_USAGE)) - *(*snao_end)++ = opt->key; - return 0; -} - -/* If OPT is a short option with an arg, output a usage entry for it to the - stream pointed at by COOKIE. */ -static int -usage_argful_short_opt (const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie) -{ - argp_fmtstream_t stream = cookie; - const char *arg = opt->arg; - int flags = opt->flags | real->flags; - - if (! arg) - arg = real->arg; - - if (arg && !(flags & OPTION_NO_USAGE)) - { - arg = dgettext (domain, arg); - - if (flags & OPTION_ARG_OPTIONAL) - __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg); - else - { - /* Manually do line wrapping so that it (probably) won't - get wrapped at the embedded space. */ - space (stream, 6 + strlen (arg)); - __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg); - } - } - - return 0; -} - -/* Output a usage entry for the long option opt to the stream pointed at by - COOKIE. */ -static int -usage_long_opt (const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie) -{ - argp_fmtstream_t stream = cookie; - const char *arg = opt->arg; - int flags = opt->flags | real->flags; - - if (! arg) - arg = real->arg; - - if (! (flags & OPTION_NO_USAGE) && !odoc (opt)) - { - if (arg) - { - arg = dgettext (domain, arg); - if (flags & OPTION_ARG_OPTIONAL) - __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg); - else - __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg); - } - else - __argp_fmtstream_printf (stream, " [--%s]", opt->name); - } - - return 0; -} - -/* Print a short usage description for the arguments in HOL to STREAM. */ -static void -hol_usage (struct hol *hol, argp_fmtstream_t stream) -{ - if (hol->num_entries > 0) - { - unsigned nentries; - struct hol_entry *entry; - char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1); - char *snao_end = short_no_arg_opts; - - /* First we put a list of short options without arguments. */ - for (entry = hol->entries, nentries = hol->num_entries - ; nentries > 0 - ; entry++, nentries--) - hol_entry_short_iterate (entry, add_argless_short_opt, - entry->argp->argp_domain, &snao_end); - if (snao_end > short_no_arg_opts) - { - *snao_end++ = 0; - __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts); - } - - /* Now a list of short options *with* arguments. */ - for (entry = hol->entries, nentries = hol->num_entries - ; nentries > 0 - ; entry++, nentries--) - hol_entry_short_iterate (entry, usage_argful_short_opt, - entry->argp->argp_domain, stream); - - /* Finally, a list of long options (whew!). */ - for (entry = hol->entries, nentries = hol->num_entries - ; nentries > 0 - ; entry++, nentries--) - hol_entry_long_iterate (entry, usage_long_opt, - entry->argp->argp_domain, stream); - } -} - -/* Make a HOL containing all levels of options in ARGP. CLUSTER is the - cluster in which ARGP's entries should be clustered, or 0. */ -static struct hol * -argp_hol (const struct argp *argp, struct hol_cluster *cluster) -{ - const struct argp_child *child = argp->children; - struct hol *hol = make_hol (argp, cluster); - if (child) - while (child->argp) - { - struct hol_cluster *child_cluster = - ((child->group || child->header) - /* Put CHILD->argp within its own cluster. */ - ? hol_add_cluster (hol, child->group, child->header, - child - argp->children, cluster, argp) - /* Just merge it into the parent's cluster. */ - : cluster); - hol_append (hol, argp_hol (child->argp, child_cluster)) ; - child++; - } - return hol; -} - -/* Calculate how many different levels with alternative args strings exist in - ARGP. */ -static size_t -argp_args_levels (const struct argp *argp) -{ - size_t levels = 0; - const struct argp_child *child = argp->children; - - if (argp->args_doc && strchr (argp->args_doc, '\n')) - levels++; - - if (child) - while (child->argp) - levels += argp_args_levels ((child++)->argp); - - return levels; -} - -/* Print all the non-option args documented in ARGP to STREAM. Any output is - preceded by a space. LEVELS is a pointer to a byte vector the length - returned by argp_args_levels; it should be initialized to zero, and - updated by this routine for the next call if ADVANCE is true. True is - returned as long as there are more patterns to output. */ -static int -argp_args_usage (const struct argp *argp, const struct argp_state *state, - char **levels, int advance, argp_fmtstream_t stream) -{ - char *our_level = *levels; - int multiple = 0; - const struct argp_child *child = argp->children; - const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0; - const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state); - - if (fdoc) - { - const char *cp = fdoc; - nl = __strchrnul (cp, '\n'); - if (*nl != '\0') - /* This is a `multi-level' args doc; advance to the correct position - as determined by our state in LEVELS, and update LEVELS. */ - { - int i; - multiple = 1; - for (i = 0; i < *our_level; i++) - cp = nl + 1, nl = __strchrnul (cp, '\n'); - (*levels)++; - } - - /* Manually do line wrapping so that it (probably) won't get wrapped at - any embedded spaces. */ - space (stream, 1 + nl - cp); - - __argp_fmtstream_write (stream, cp, nl - cp); - } - if (fdoc && fdoc != tdoc) - free ((char *)fdoc); /* Free user's modified doc string. */ - - if (child) - while (child->argp) - advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream); - - if (advance && multiple) - { - /* Need to increment our level. */ - if (*nl) - /* There's more we can do here. */ - { - (*our_level)++; - advance = 0; /* Our parent shouldn't advance also. */ - } - else if (*our_level > 0) - /* We had multiple levels, but used them up; reset to zero. */ - *our_level = 0; - } - - return !advance; -} - -/* Print the documentation for ARGP to STREAM; if POST is false, then - everything preceeding a `\v' character in the documentation strings (or - the whole string, for those with none) is printed, otherwise, everything - following the `\v' character (nothing for strings without). Each separate - bit of documentation is separated a blank line, and if PRE_BLANK is true, - then the first is as well. If FIRST_ONLY is true, only the first - occurrence is output. Returns true if anything was output. */ -static int -argp_doc (const struct argp *argp, const struct argp_state *state, - int post, int pre_blank, int first_only, - argp_fmtstream_t stream) -{ - const char *text; - const char *inp_text; - size_t inp_text_len = 0; - const char *trans_text; - void *input = 0; - int anything = 0; - const struct argp_child *child = argp->children; - - if (argp->doc) - { - char *vt = strchr (argp->doc, '\v'); - if (vt) - { - if (post) - inp_text = vt + 1; - else - { - inp_text_len = vt - argp->doc; - inp_text = __strndup (argp->doc, inp_text_len); - } - } - else - inp_text = post ? 0 : argp->doc; - trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL; - } - else - trans_text = inp_text = 0; - - if (argp->help_filter) - /* We have to filter the doc strings. */ - { - input = __argp_input (argp, state); - text = - (*argp->help_filter) (post - ? ARGP_KEY_HELP_POST_DOC - : ARGP_KEY_HELP_PRE_DOC, - trans_text, input); - } - else - text = (const char *) trans_text; - - if (text) - { - if (pre_blank) - __argp_fmtstream_putc (stream, '\n'); - - __argp_fmtstream_puts (stream, text); - - if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream)) - __argp_fmtstream_putc (stream, '\n'); - - anything = 1; - } - - if (text && text != trans_text) - free ((char *) text); /* Free TEXT returned from the help filter. */ - - if (inp_text && inp_text_len) - free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */ - - if (post && argp->help_filter) - /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */ - { - text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input); - if (text) - { - if (anything || pre_blank) - __argp_fmtstream_putc (stream, '\n'); - __argp_fmtstream_puts (stream, text); - free ((char *) text); - if (__argp_fmtstream_point (stream) - > __argp_fmtstream_lmargin (stream)) - __argp_fmtstream_putc (stream, '\n'); - anything = 1; - } - } - - if (child) - while (child->argp && !(first_only && anything)) - anything |= - argp_doc ((child++)->argp, state, - post, anything || pre_blank, first_only, - stream); - - return anything; -} - -/* Output a usage message for ARGP to STREAM. If called from - argp_state_help, STATE is the relevent parsing state. FLAGS are from the - set ARGP_HELP_*. NAME is what to use wherever a `program name' is - needed. */ -static void -_help (const struct argp *argp, const struct argp_state *state, FILE *stream, - unsigned flags, char *name) -{ - int anything = 0; /* Whether we've output anything. */ - struct hol *hol = 0; - argp_fmtstream_t fs; - - if (! stream) - return; - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __flockfile (stream); -#endif - - if (! uparams.valid) - fill_in_uparams (state); - - fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0); - if (! fs) - { -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - return; - } - - if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG)) - { - hol = argp_hol (argp, 0); - - /* If present, these options always come last. */ - hol_set_group (hol, "help", -1); - hol_set_group (hol, "version", -1); - - hol_sort (hol); - } - - if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE)) - /* Print a short `Usage:' message. */ - { - int first_pattern = 1, more_patterns; - size_t num_pattern_levels = argp_args_levels (argp); - char *pattern_levels = alloca (num_pattern_levels); - - memset (pattern_levels, 0, num_pattern_levels); - - do - { - int old_lm; - int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent); - char *levels = pattern_levels; - - if (first_pattern) - __argp_fmtstream_printf (fs, "%s %s", - dgettext (argp->argp_domain, "Usage:"), - name); - else - __argp_fmtstream_printf (fs, "%s %s", - dgettext (argp->argp_domain, " or: "), - name); - - /* We set the lmargin as well as the wmargin, because hol_usage - manually wraps options with newline to avoid annoying breaks. */ - old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent); - - if (flags & ARGP_HELP_SHORT_USAGE) - /* Just show where the options go. */ - { - if (hol->num_entries > 0) - __argp_fmtstream_puts (fs, dgettext (argp->argp_domain, - " [OPTION...]")); - } - else - /* Actually print the options. */ - { - hol_usage (hol, fs); - flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */ - } - - more_patterns = argp_args_usage (argp, state, &levels, 1, fs); - - __argp_fmtstream_set_wmargin (fs, old_wm); - __argp_fmtstream_set_lmargin (fs, old_lm); - - __argp_fmtstream_putc (fs, '\n'); - anything = 1; - - first_pattern = 0; - } - while (more_patterns); - } - - if (flags & ARGP_HELP_PRE_DOC) - anything |= argp_doc (argp, state, 0, 0, 1, fs); - - if (flags & ARGP_HELP_SEE) - { - __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\ -Try `%s --help' or `%s --usage' for more information.\n"), - name, name); - anything = 1; - } - - if (flags & ARGP_HELP_LONG) - /* Print a long, detailed help message. */ - { - /* Print info about all the options. */ - if (hol->num_entries > 0) - { - if (anything) - __argp_fmtstream_putc (fs, '\n'); - hol_help (hol, state, fs); - anything = 1; - } - } - - if (flags & ARGP_HELP_POST_DOC) - /* Print any documentation strings at the end. */ - anything |= argp_doc (argp, state, 1, anything, 0, fs); - - if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address) - { - if (anything) - __argp_fmtstream_putc (fs, '\n'); - __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, - "Report bugs to %s.\n"), - argp_program_bug_address); - anything = 1; - } - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - - if (hol) - hol_free (hol); - - __argp_fmtstream_free (fs); -} - -/* Output a usage message for ARGP to STREAM. FLAGS are from the set - ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */ -void __argp_help (const struct argp *argp, FILE *stream, - unsigned flags, char *name) -{ - struct argp_state state; - memset (&state, 0, sizeof state); - state.root_argp = argp; - _help (argp, &state, stream, flags, name); -} -#ifdef weak_alias -weak_alias (__argp_help, argp_help) -#endif - -#if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME) -char * -__argp_short_program_name (void) -{ -# if HAVE_DECL_PROGRAM_INVOCATION_NAME - return __argp_base_name (program_invocation_name); -# else - /* FIXME: What now? Miles suggests that it is better to use NULL, - but currently the value is passed on directly to fputs_unlocked, - so that requires more changes. */ -# if __GNUC__ -# warning No reasonable value to return -# endif /* __GNUC__ */ - return ""; -# endif -} -#endif - -/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are - from the set ARGP_HELP_*. */ -void -__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags) -{ - if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream) - { - if (state && (state->flags & ARGP_LONG_ONLY)) - flags |= ARGP_HELP_LONG_ONLY; - - _help (state ? state->root_argp : 0, state, stream, flags, - state ? state->name : __argp_short_program_name ()); - - if (!state || ! (state->flags & ARGP_NO_EXIT)) - { - if (flags & ARGP_HELP_EXIT_ERR) - exit (argp_err_exit_status); - if (flags & ARGP_HELP_EXIT_OK) - exit (0); - } - } -} -#ifdef weak_alias -weak_alias (__argp_state_help, argp_state_help) -#endif - -/* If appropriate, print the printf string FMT and following args, preceded - by the program name and `:', to stderr, and followed by a `Try ... --help' - message, then exit (1). */ -void -__argp_error (const struct argp_state *state, const char *fmt, ...) -{ - if (!state || !(state->flags & ARGP_NO_ERRS)) - { - FILE *stream = state ? state->err_stream : stderr; - - if (stream) - { - va_list ap; - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __flockfile (stream); -#endif - - va_start (ap, fmt); - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - { - char *buf; - - if (__asprintf (&buf, fmt, ap) < 0) - buf = NULL; - - __fwprintf (stream, L"%s: %s\n", - state ? state->name : __argp_short_program_name (), - buf); - - free (buf); - } - else -#endif - { - fputs_unlocked (state - ? state->name : __argp_short_program_name (), - stream); - putc_unlocked (':', stream); - putc_unlocked (' ', stream); - - vfprintf (stream, fmt, ap); - - putc_unlocked ('\n', stream); - } - - __argp_state_help (state, stream, ARGP_HELP_STD_ERR); - - va_end (ap); - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - } - } -} -#ifdef weak_alias -weak_alias (__argp_error, argp_error) -#endif - -/* Similar to the standard gnu error-reporting function error(), but will - respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print - to STATE->err_stream. This is useful for argument parsing code that is - shared between program startup (when exiting is desired) and runtime - option parsing (when typically an error code is returned instead). The - difference between this function and argp_error is that the latter is for - *parsing errors*, and the former is for other problems that occur during - parsing but don't reflect a (syntactic) problem with the input. */ -void -__argp_failure (const struct argp_state *state, int status, int errnum, - const char *fmt, ...) -{ - if (!state || !(state->flags & ARGP_NO_ERRS)) - { - FILE *stream = state ? state->err_stream : stderr; - - if (stream) - { -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __flockfile (stream); -#endif - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - __fwprintf (stream, L"%s", - state ? state->name : __argp_short_program_name ()); - else -#endif - fputs_unlocked (state - ? state->name : __argp_short_program_name (), - stream); - - if (fmt) - { - va_list ap; - - va_start (ap, fmt); -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - { - char *buf; - - if (__asprintf (&buf, fmt, ap) < 0) - buf = NULL; - - __fwprintf (stream, L": %s", buf); - - free (buf); - } - else -#endif - { - putc_unlocked (':', stream); - putc_unlocked (' ', stream); - - vfprintf (stream, fmt, ap); - } - - va_end (ap); - } - - if (errnum) - { - char buf[200]; - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - __fwprintf (stream, L": %s", - __strerror_r (errnum, buf, sizeof (buf))); - else -#endif - { - char const *s = NULL; - putc_unlocked (':', stream); - putc_unlocked (' ', stream); -#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P) - s = __strerror_r (errnum, buf, sizeof buf); -#elif HAVE_DECL_STRERROR_R - if (__strerror_r (errnum, buf, sizeof buf) == 0) - s = buf; -#endif -#if !_LIBC - if (! s && ! (s = strerror (errnum))) - s = dgettext (state->root_argp->argp_domain, - "Unknown system error"); -#endif - fputs (s, stream); - } - } - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - putwc_unlocked (L'\n', stream); - else -#endif - putc_unlocked ('\n', stream); - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - - if (status && (!state || !(state->flags & ARGP_NO_EXIT))) - exit (status); - } - } -} -#ifdef weak_alias -weak_alias (__argp_failure, argp_failure) -#endif diff --git a/contrib/cpio/lib/argp-namefrob.h b/contrib/cpio/lib/argp-namefrob.h deleted file mode 100644 index 6fe99cd7aaf..00000000000 --- a/contrib/cpio/lib/argp-namefrob.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Name frobnication for compiling argp outside of glibc - Copyright (C) 1997, 2003, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if !_LIBC -/* This code is written for inclusion in gnu-libc, and uses names in the - namespace reserved for libc. If we're not compiling in libc, define those - names to be the normal ones instead. */ - -/* argp-parse functions */ -#undef __argp_parse -#define __argp_parse argp_parse -#undef __option_is_end -#define __option_is_end _option_is_end -#undef __option_is_short -#define __option_is_short _option_is_short -#undef __argp_input -#define __argp_input _argp_input - -/* argp-help functions */ -#undef __argp_help -#define __argp_help argp_help -#undef __argp_error -#define __argp_error argp_error -#undef __argp_failure -#define __argp_failure argp_failure -#undef __argp_state_help -#define __argp_state_help argp_state_help -#undef __argp_usage -#define __argp_usage argp_usage - -/* argp-fmtstream functions */ -#undef __argp_make_fmtstream -#define __argp_make_fmtstream argp_make_fmtstream -#undef __argp_fmtstream_free -#define __argp_fmtstream_free argp_fmtstream_free -#undef __argp_fmtstream_putc -#define __argp_fmtstream_putc argp_fmtstream_putc -#undef __argp_fmtstream_puts -#define __argp_fmtstream_puts argp_fmtstream_puts -#undef __argp_fmtstream_write -#define __argp_fmtstream_write argp_fmtstream_write -#undef __argp_fmtstream_printf -#define __argp_fmtstream_printf argp_fmtstream_printf -#undef __argp_fmtstream_set_lmargin -#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin -#undef __argp_fmtstream_set_rmargin -#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin -#undef __argp_fmtstream_set_wmargin -#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin -#undef __argp_fmtstream_point -#define __argp_fmtstream_point argp_fmtstream_point -#undef __argp_fmtstream_update -#define __argp_fmtstream_update _argp_fmtstream_update -#undef __argp_fmtstream_ensure -#define __argp_fmtstream_ensure _argp_fmtstream_ensure -#undef __argp_fmtstream_lmargin -#define __argp_fmtstream_lmargin argp_fmtstream_lmargin -#undef __argp_fmtstream_rmargin -#define __argp_fmtstream_rmargin argp_fmtstream_rmargin -#undef __argp_fmtstream_wmargin -#define __argp_fmtstream_wmargin argp_fmtstream_wmargin - -/* normal libc functions we call */ -#undef __flockfile -#define __flockfile flockfile -#undef __funlockfile -#define __funlockfile funlockfile -#undef __mempcpy -#define __mempcpy mempcpy -#undef __sleep -#define __sleep sleep -#undef __strcasecmp -#define __strcasecmp strcasecmp -#undef __strchrnul -#define __strchrnul strchrnul -#undef __strerror_r -#define __strerror_r strerror_r -#undef __strndup -#define __strndup strndup -#undef __vsnprintf -#define __vsnprintf vsnprintf - -#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED -# define clearerr_unlocked(x) clearerr (x) -#endif -#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED -# define feof_unlocked(x) feof (x) -# endif -#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED -# define ferror_unlocked(x) ferror (x) -# endif -#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED -# define fflush_unlocked(x) fflush (x) -# endif -#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED -# define fgets_unlocked(x,y,z) fgets (x,y,z) -# endif -#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED -# define fputc_unlocked(x,y) fputc (x,y) -# endif -#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED -# define fputs_unlocked(x,y) fputs (x,y) -# endif -#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED -# define fread_unlocked(w,x,y,z) fread (w,x,y,z) -# endif -#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED -# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) -# endif -#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED -# define getc_unlocked(x) getc (x) -# endif -#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED -# define getchar_unlocked() getchar () -# endif -#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED -# define putc_unlocked(x,y) putc (x,y) -# endif -#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED -# define putchar_unlocked(x) putchar (x) -# endif - -#endif /* !_LIBC */ - -#ifndef __set_errno -#define __set_errno(e) (errno = (e)) -#endif - -#if defined GNULIB_ARGP_DISABLE_DIRNAME -# define __argp_base_name(arg) arg -#elif defined GNULIB_ARGP_EXTERN_BASENAME -extern char *__argp_base_name(const char *arg); -#else -# include "dirname.h" -# define __argp_base_name base_name -#endif - -#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME -# define __argp_short_program_name() (program_invocation_short_name) -#else -extern char *__argp_short_program_name (void); -#endif diff --git a/contrib/cpio/lib/argp-parse.c b/contrib/cpio/lib/argp-parse.c deleted file mode 100644 index a7de72902aa..00000000000 --- a/contrib/cpio/lib/argp-parse.c +++ /dev/null @@ -1,953 +0,0 @@ -/* Hierarchial argument parsing, layered over getopt - Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _LIBC -# include -# undef dgettext -# define dgettext(domain, msgid) \ - INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) -#else -# include "gettext.h" -#endif -#define N_(msgid) msgid - -#include "argp.h" -#include "argp-namefrob.h" - -#define alignof(type) offsetof (struct { char c; type x; }, x) -#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d)) - -/* Getopt return values. */ -#define KEY_END (-1) /* The end of the options. */ -#define KEY_ARG 1 /* A non-option argument. */ -#define KEY_ERR '?' /* An error parsing the options. */ - -/* The meta-argument used to prevent any further arguments being interpreted - as options. */ -#define QUOTE "--" - -/* The number of bits we steal in a long-option value for our own use. */ -#define GROUP_BITS CHAR_BIT - -/* The number of bits available for the user value. */ -#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS) -#define USER_MASK ((1 << USER_BITS) - 1) - -/* EZ alias for ARGP_ERR_UNKNOWN. */ -#define EBADKEY ARGP_ERR_UNKNOWN - -/* Default options. */ - -/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep - for one second intervals, decrementing _ARGP_HANG until it's zero. Thus - you can force the program to continue by attaching a debugger and setting - it to 0 yourself. */ -static volatile int _argp_hang; - -#define OPT_PROGNAME -2 -#define OPT_USAGE -3 -#define OPT_HANG -4 - -static const struct argp_option argp_default_options[] = -{ - {"help", '?', 0, 0, N_("give this help list"), -1}, - {"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0}, - {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0}, - {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN, - N_("hang for SECS seconds (default 3600)"), 0}, - {NULL, 0, 0, 0, NULL, 0} -}; - -static error_t -argp_default_parser (int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case '?': - __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP); - break; - case OPT_USAGE: - __argp_state_help (state, state->out_stream, - ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); - break; - - case OPT_PROGNAME: /* Set the program name. */ -#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME - program_invocation_name = arg; -#endif - /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka - __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined - to be that, so we have to be a bit careful here.] */ - - /* Update what we use for messages. */ - state->name = __argp_base_name (arg); - -#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME - program_invocation_short_name = state->name; -#endif - - if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) - == ARGP_PARSE_ARGV0) - /* Update what getopt uses too. */ - state->argv[0] = arg; - - break; - - case OPT_HANG: - _argp_hang = atoi (arg ? arg : "3600"); - while (_argp_hang-- > 0) - __sleep (1); - break; - - default: - return EBADKEY; - } - return 0; -} - -static const struct argp argp_default_argp = - {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"}; - - -static const struct argp_option argp_version_options[] = -{ - {"version", 'V', 0, 0, N_("print program version"), -1}, - {NULL, 0, 0, 0, NULL, 0} -}; - -static error_t -argp_version_parser (int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case 'V': - if (argp_program_version_hook) - (*argp_program_version_hook) (state->out_stream, state); - else if (argp_program_version) - fprintf (state->out_stream, "%s\n", argp_program_version); - else - __argp_error (state, dgettext (state->root_argp->argp_domain, - "(PROGRAM ERROR) No version known!?")); - if (! (state->flags & ARGP_NO_EXIT)) - exit (0); - break; - default: - return EBADKEY; - } - return 0; -} - -static const struct argp argp_version_argp = - {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"}; - -/* Returns the offset into the getopt long options array LONG_OPTIONS of a - long option with called NAME, or -1 if none is found. Passing NULL as - NAME will return the number of options. */ -static int -find_long_option (struct option *long_options, const char *name) -{ - struct option *l = long_options; - while (l->name != NULL) - if (name != NULL && strcmp (l->name, name) == 0) - return l - long_options; - else - l++; - if (name == NULL) - return l - long_options; - else - return -1; -} - - -/* The state of a `group' during parsing. Each group corresponds to a - particular argp structure from the tree of such descending from the top - level argp passed to argp_parse. */ -struct group -{ - /* This group's parsing function. */ - argp_parser_t parser; - - /* Which argp this group is from. */ - const struct argp *argp; - - /* Points to the point in SHORT_OPTS corresponding to the end of the short - options for this group. We use it to determine from which group a - particular short options is from. */ - char *short_end; - - /* The number of non-option args sucessfully handled by this parser. */ - unsigned args_processed; - - /* This group's parser's parent's group. */ - struct group *parent; - unsigned parent_index; /* And the our position in the parent. */ - - /* These fields are swapped into and out of the state structure when - calling this group's parser. */ - void *input, **child_inputs; - void *hook; -}; - -/* Call GROUP's parser with KEY and ARG, swapping any group-specific info - from STATE before calling, and back into state afterwards. If GROUP has - no parser, EBADKEY is returned. */ -static error_t -group_parse (struct group *group, struct argp_state *state, int key, char *arg) -{ - if (group->parser) - { - error_t err; - state->hook = group->hook; - state->input = group->input; - state->child_inputs = group->child_inputs; - state->arg_num = group->args_processed; - err = (*group->parser)(key, arg, state); - group->hook = state->hook; - return err; - } - else - return EBADKEY; -} - -struct parser -{ - const struct argp *argp; - - /* SHORT_OPTS is the getopt short options string for the union of all the - groups of options. */ - char *short_opts; - /* LONG_OPTS is the array of getop long option structures for the union of - all the groups of options. */ - struct option *long_opts; - /* OPT_DATA is the getopt data used for the re-entrant getopt. */ - struct _getopt_data opt_data; - - /* States of the various parsing groups. */ - struct group *groups; - /* The end of the GROUPS array. */ - struct group *egroup; - /* An vector containing storage for the CHILD_INPUTS field in all groups. */ - void **child_inputs; - - /* True if we think using getopt is still useful; if false, then - remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is - cleared whenever getopt returns KEY_END, but may be set again if the user - moves the next argument pointer backwards. */ - int try_getopt; - - /* State block supplied to parsing routines. */ - struct argp_state state; - - /* Memory used by this parser. */ - void *storage; -}; - -/* The next usable entries in the various parser tables being filled in by - convert_options. */ -struct parser_convert_state -{ - struct parser *parser; - char *short_end; - struct option *long_end; - void **child_inputs_end; -}; - -/* Converts all options in ARGP (which is put in GROUP) and ancestors - into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and - CVT->LONG_END are the points at which new options are added. Returns the - next unused group entry. CVT holds state used during the conversion. */ -static struct group * -convert_options (const struct argp *argp, - struct group *parent, unsigned parent_index, - struct group *group, struct parser_convert_state *cvt) -{ - /* REAL is the most recent non-alias value of OPT. */ - const struct argp_option *real = argp->options; - const struct argp_child *children = argp->children; - - if (real || argp->parser) - { - const struct argp_option *opt; - - if (real) - for (opt = real; !__option_is_end (opt); opt++) - { - if (! (opt->flags & OPTION_ALIAS)) - /* OPT isn't an alias, so we can use values from it. */ - real = opt; - - if (! (real->flags & OPTION_DOC)) - /* A real option (not just documentation). */ - { - if (__option_is_short (opt)) - /* OPT can be used as a short option. */ - { - *cvt->short_end++ = opt->key; - if (real->arg) - { - *cvt->short_end++ = ':'; - if (real->flags & OPTION_ARG_OPTIONAL) - *cvt->short_end++ = ':'; - } - *cvt->short_end = '\0'; /* keep 0 terminated */ - } - - if (opt->name - && find_long_option (cvt->parser->long_opts, opt->name) < 0) - /* OPT can be used as a long option. */ - { - cvt->long_end->name = opt->name; - cvt->long_end->has_arg = - (real->arg - ? (real->flags & OPTION_ARG_OPTIONAL - ? optional_argument - : required_argument) - : no_argument); - cvt->long_end->flag = 0; - /* we add a disambiguating code to all the user's - values (which is removed before we actually call - the function to parse the value); this means that - the user loses use of the high 8 bits in all his - values (the sign of the lower bits is preserved - however)... */ - cvt->long_end->val = - ((opt->key | real->key) & USER_MASK) - + (((group - cvt->parser->groups) + 1) << USER_BITS); - - /* Keep the LONG_OPTS list terminated. */ - (++cvt->long_end)->name = NULL; - } - } - } - - group->parser = argp->parser; - group->argp = argp; - group->short_end = cvt->short_end; - group->args_processed = 0; - group->parent = parent; - group->parent_index = parent_index; - group->input = 0; - group->hook = 0; - group->child_inputs = 0; - - if (children) - /* Assign GROUP's CHILD_INPUTS field some space from - CVT->child_inputs_end.*/ - { - unsigned num_children = 0; - while (children[num_children].argp) - num_children++; - group->child_inputs = cvt->child_inputs_end; - cvt->child_inputs_end += num_children; - } - - parent = group++; - } - else - parent = 0; - - if (children) - { - unsigned index = 0; - while (children->argp) - group = - convert_options (children++->argp, parent, index++, group, cvt); - } - - return group; -} - -/* Find the merged set of getopt options, with keys appropiately prefixed. */ -static void -parser_convert (struct parser *parser, const struct argp *argp, int flags) -{ - struct parser_convert_state cvt; - - cvt.parser = parser; - cvt.short_end = parser->short_opts; - cvt.long_end = parser->long_opts; - cvt.child_inputs_end = parser->child_inputs; - - if (flags & ARGP_IN_ORDER) - *cvt.short_end++ = '-'; - else if (flags & ARGP_NO_ARGS) - *cvt.short_end++ = '+'; - *cvt.short_end = '\0'; - - cvt.long_end->name = NULL; - - parser->argp = argp; - - if (argp) - parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt); - else - parser->egroup = parser->groups; /* No parsers at all! */ -} - -/* Lengths of various parser fields which we will allocated. */ -struct parser_sizes -{ - size_t short_len; /* Getopt short options string. */ - size_t long_len; /* Getopt long options vector. */ - size_t num_groups; /* Group structures we allocate. */ - size_t num_child_inputs; /* Child input slots. */ -}; - -/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of - argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by - the maximum lengths of the resulting merged getopt short options string and - long-options array, respectively. */ -static void -calc_sizes (const struct argp *argp, struct parser_sizes *szs) -{ - const struct argp_child *child = argp->children; - const struct argp_option *opt = argp->options; - - if (opt || argp->parser) - { - szs->num_groups++; - if (opt) - { - int num_opts = 0; - while (!__option_is_end (opt++)) - num_opts++; - szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */ - szs->long_len += num_opts; - } - } - - if (child) - while (child->argp) - { - calc_sizes ((child++)->argp, szs); - szs->num_child_inputs++; - } -} - -/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */ -static error_t -parser_init (struct parser *parser, const struct argp *argp, - int argc, char **argv, int flags, void *input) -{ - error_t err = 0; - struct group *group; - struct parser_sizes szs; - struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER; - char *storage; - size_t glen, gsum; - size_t clen, csum; - size_t llen, lsum; - size_t slen, ssum; - - szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1; - szs.long_len = 0; - szs.num_groups = 0; - szs.num_child_inputs = 0; - - if (argp) - calc_sizes (argp, &szs); - - /* Lengths of the various bits of storage used by PARSER. */ - glen = (szs.num_groups + 1) * sizeof (struct group); - clen = szs.num_child_inputs * sizeof (void *); - llen = (szs.long_len + 1) * sizeof (struct option); - slen = szs.short_len + 1; - - /* Sums of previous lengths, properly aligned. There's no need to - align gsum, since struct group is aligned at least as strictly as - void * (since it contains a void * member). And there's no need - to align lsum, since struct option is aligned at least as - strictly as char. */ - gsum = glen; - csum = alignto (gsum + clen, alignof (struct option)); - lsum = csum + llen; - ssum = lsum + slen; - - parser->storage = malloc (ssum); - if (! parser->storage) - return ENOMEM; - - storage = parser->storage; - parser->groups = parser->storage; - parser->child_inputs = (void **) (storage + gsum); - parser->long_opts = (struct option *) (storage + csum); - parser->short_opts = storage + lsum; - parser->opt_data = opt_data; - - memset (parser->child_inputs, 0, clen); - parser_convert (parser, argp, flags); - - memset (&parser->state, 0, sizeof (struct argp_state)); - parser->state.root_argp = parser->argp; - parser->state.argc = argc; - parser->state.argv = argv; - parser->state.flags = flags; - parser->state.err_stream = stderr; - parser->state.out_stream = stdout; - parser->state.next = 0; /* Tell getopt to initialize. */ - parser->state.pstate = parser; - - parser->try_getopt = 1; - - /* Call each parser for the first time, giving it a chance to propagate - values to child parsers. */ - if (parser->groups < parser->egroup) - parser->groups->input = input; - for (group = parser->groups; - group < parser->egroup && (!err || err == EBADKEY); - group++) - { - if (group->parent) - /* If a child parser, get the initial input value from the parent. */ - group->input = group->parent->child_inputs[group->parent_index]; - - if (!group->parser - && group->argp->children && group->argp->children->argp) - /* For the special case where no parsing function is supplied for an - argp, propagate its input to its first child, if any (this just - makes very simple wrapper argps more convenient). */ - group->child_inputs[0] = group->input; - - err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); - } - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - - if (err) - return err; - - if (parser->state.flags & ARGP_NO_ERRS) - { - parser->opt_data.opterr = 0; - if (parser->state.flags & ARGP_PARSE_ARGV0) - /* getopt always skips ARGV[0], so we have to fake it out. As long - as OPTERR is 0, then it shouldn't actually try to access it. */ - parser->state.argv--, parser->state.argc++; - } - else - parser->opt_data.opterr = 1; /* Print error messages. */ - - if (parser->state.argv == argv && argv[0]) - /* There's an argv[0]; use it for messages. */ - parser->state.name = __argp_base_name (argv[0]); - else - parser->state.name = __argp_short_program_name (); - - return 0; -} - -/* Free any storage consumed by PARSER (but not PARSER itself). */ -static error_t -parser_finalize (struct parser *parser, - error_t err, int arg_ebadkey, int *end_index) -{ - struct group *group; - - if (err == EBADKEY && arg_ebadkey) - /* Suppress errors generated by unparsed arguments. */ - err = 0; - - if (! err) - { - if (parser->state.next == parser->state.argc) - /* We successfully parsed all arguments! Call all the parsers again, - just a few more times... */ - { - for (group = parser->groups; - group < parser->egroup && (!err || err==EBADKEY); - group++) - if (group->args_processed == 0) - err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); - for (group = parser->egroup - 1; - group >= parser->groups && (!err || err==EBADKEY); - group--) - err = group_parse (group, &parser->state, ARGP_KEY_END, 0); - - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - - /* Tell the user that all arguments are parsed. */ - if (end_index) - *end_index = parser->state.next; - } - else if (end_index) - /* Return any remaining arguments to the user. */ - *end_index = parser->state.next; - else - /* No way to return the remaining arguments, they must be bogus. */ - { - if (!(parser->state.flags & ARGP_NO_ERRS) - && parser->state.err_stream) - fprintf (parser->state.err_stream, - dgettext (parser->argp->argp_domain, - "%s: Too many arguments\n"), - parser->state.name); - err = EBADKEY; - } - } - - /* Okay, we're all done, with either an error or success; call the parsers - to indicate which one. */ - - if (err) - { - /* Maybe print an error message. */ - if (err == EBADKEY) - /* An appropriate message describing what the error was should have - been printed earlier. */ - __argp_state_help (&parser->state, parser->state.err_stream, - ARGP_HELP_STD_ERR); - - /* Since we didn't exit, give each parser an error indication. */ - for (group = parser->groups; group < parser->egroup; group++) - group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); - } - else - /* Notify parsers of success, and propagate back values from parsers. */ - { - /* We pass over the groups in reverse order so that child groups are - given a chance to do there processing before passing back a value to - the parent. */ - for (group = parser->egroup - 1 - ; group >= parser->groups && (!err || err == EBADKEY) - ; group--) - err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - } - - /* Call parsers once more, to do any final cleanup. Errors are ignored. */ - for (group = parser->egroup - 1; group >= parser->groups; group--) - group_parse (group, &parser->state, ARGP_KEY_FINI, 0); - - if (err == EBADKEY) - err = EINVAL; - - free (parser->storage); - - return err; -} - -/* Call the user parsers to parse the non-option argument VAL, at the current - position, returning any error. The state NEXT pointer is assumed to have - been adjusted (by getopt) to point after this argument; this function will - adjust it correctly to reflect however many args actually end up being - consumed. */ -static error_t -parser_parse_arg (struct parser *parser, char *val) -{ - /* Save the starting value of NEXT, first adjusting it so that the arg - we're parsing is again the front of the arg vector. */ - int index = --parser->state.next; - error_t err = EBADKEY; - struct group *group; - int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ - - /* Try to parse the argument in each parser. */ - for (group = parser->groups - ; group < parser->egroup && err == EBADKEY - ; group++) - { - parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ - key = ARGP_KEY_ARG; - err = group_parse (group, &parser->state, key, val); - - if (err == EBADKEY) - /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ - { - parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ - key = ARGP_KEY_ARGS; - err = group_parse (group, &parser->state, key, 0); - } - } - - if (! err) - { - if (key == ARGP_KEY_ARGS) - /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't - changed by the user, *all* arguments should be considered - consumed. */ - parser->state.next = parser->state.argc; - - if (parser->state.next > index) - /* Remember that we successfully processed a non-option - argument -- but only if the user hasn't gotten tricky and set - the clock back. */ - (--group)->args_processed += (parser->state.next - index); - else - /* The user wants to reparse some args, give getopt another try. */ - parser->try_getopt = 1; - } - - return err; -} - -/* Call the user parsers to parse the option OPT, with argument VAL, at the - current position, returning any error. */ -static error_t -parser_parse_opt (struct parser *parser, int opt, char *val) -{ - /* The group key encoded in the high bits; 0 for short opts or - group_number + 1 for long opts. */ - int group_key = opt >> USER_BITS; - error_t err = EBADKEY; - - if (group_key == 0) - /* A short option. By comparing OPT's position in SHORT_OPTS to the - various starting positions in each group's SHORT_END field, we can - determine which group OPT came from. */ - { - struct group *group; - char *short_index = strchr (parser->short_opts, opt); - - if (short_index) - for (group = parser->groups; group < parser->egroup; group++) - if (group->short_end > short_index) - { - err = group_parse (group, &parser->state, opt, - parser->opt_data.optarg); - break; - } - } - else - /* A long option. We use shifts instead of masking for extracting - the user value in order to preserve the sign. */ - err = - group_parse (&parser->groups[group_key - 1], &parser->state, - (opt << GROUP_BITS) >> GROUP_BITS, - parser->opt_data.optarg); - - if (err == EBADKEY) - /* At least currently, an option not recognized is an error in the - parser, because we pre-compute which parser is supposed to deal - with each option. */ - { - static const char bad_key_err[] = - N_("(PROGRAM ERROR) Option should have been recognized!?"); - if (group_key == 0) - __argp_error (&parser->state, "-%c: %s", opt, - dgettext (parser->argp->argp_domain, bad_key_err)); - else - { - struct option *long_opt = parser->long_opts; - while (long_opt->val != opt && long_opt->name) - long_opt++; - __argp_error (&parser->state, "--%s: %s", - long_opt->name ? long_opt->name : "???", - dgettext (parser->argp->argp_domain, bad_key_err)); - } - } - - return err; -} - -/* Parse the next argument in PARSER (as indicated by PARSER->state.next). - Any error from the parsers is returned, and *ARGP_EBADKEY indicates - whether a value of EBADKEY is due to an unrecognized argument (which is - generally not fatal). */ -static error_t -parser_parse_next (struct parser *parser, int *arg_ebadkey) -{ - int opt; - error_t err = 0; - - if (parser->state.quoted && parser->state.next < parser->state.quoted) - /* The next argument pointer has been moved to before the quoted - region, so pretend we never saw the quoting `--', and give getopt - another chance. If the user hasn't removed it, getopt will just - process it again. */ - parser->state.quoted = 0; - - if (parser->try_getopt && !parser->state.quoted) - /* Give getopt a chance to parse this. */ - { - /* Put it back in OPTIND for getopt. */ - parser->opt_data.optind = parser->state.next; - /* Distinguish KEY_ERR from a real option. */ - parser->opt_data.optopt = KEY_END; - if (parser->state.flags & ARGP_LONG_ONLY) - opt = _getopt_long_only_r (parser->state.argc, parser->state.argv, - parser->short_opts, parser->long_opts, 0, - &parser->opt_data); - else - opt = _getopt_long_r (parser->state.argc, parser->state.argv, - parser->short_opts, parser->long_opts, 0, - &parser->opt_data); - /* And see what getopt did. */ - parser->state.next = parser->opt_data.optind; - - if (opt == KEY_END) - /* Getopt says there are no more options, so stop using - getopt; we'll continue if necessary on our own. */ - { - parser->try_getopt = 0; - if (parser->state.next > 1 - && strcmp (parser->state.argv[parser->state.next - 1], QUOTE) - == 0) - /* Not only is this the end of the options, but it's a - `quoted' region, which may have args that *look* like - options, so we definitely shouldn't try to use getopt past - here, whatever happens. */ - parser->state.quoted = parser->state.next; - } - else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END) - /* KEY_ERR can have the same value as a valid user short - option, but in the case of a real error, getopt sets OPTOPT - to the offending character, which can never be KEY_END. */ - { - *arg_ebadkey = 0; - return EBADKEY; - } - } - else - opt = KEY_END; - - if (opt == KEY_END) - { - /* We're past what getopt considers the options. */ - if (parser->state.next >= parser->state.argc - || (parser->state.flags & ARGP_NO_ARGS)) - /* Indicate that we're done. */ - { - *arg_ebadkey = 1; - return EBADKEY; - } - else - /* A non-option arg; simulate what getopt might have done. */ - { - opt = KEY_ARG; - parser->opt_data.optarg = parser->state.argv[parser->state.next++]; - } - } - - if (opt == KEY_ARG) - /* A non-option argument; try each parser in turn. */ - err = parser_parse_arg (parser, parser->opt_data.optarg); - else - err = parser_parse_opt (parser, opt, parser->opt_data.optarg); - - if (err == EBADKEY) - *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG); - - return err; -} - -/* Parse the options strings in ARGC & ARGV according to the argp in ARGP. - FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the - index in ARGV of the first unparsed option is returned in it. If an - unknown option is present, EINVAL is returned; if some parser routine - returned a non-zero value, it is returned; otherwise 0 is returned. */ -error_t -__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, - int *end_index, void *input) -{ - error_t err; - struct parser parser; - - /* If true, then err == EBADKEY is a result of a non-option argument failing - to be parsed (which in some cases isn't actually an error). */ - int arg_ebadkey = 0; - -#ifndef _LIBC - if (!(flags & ARGP_PARSE_ARGV0)) - { -#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME - if (!program_invocation_name) - program_invocation_name = argv[0]; -#endif -#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME - if (!program_invocation_short_name) - program_invocation_short_name = __argp_base_name (argv[0]); -#endif - } -#endif - - if (! (flags & ARGP_NO_HELP)) - /* Add our own options. */ - { - struct argp_child *child = alloca (4 * sizeof (struct argp_child)); - struct argp *top_argp = alloca (sizeof (struct argp)); - - /* TOP_ARGP has no options, it just serves to group the user & default - argps. */ - memset (top_argp, 0, sizeof (*top_argp)); - top_argp->children = child; - - memset (child, 0, 4 * sizeof (struct argp_child)); - - if (argp) - (child++)->argp = argp; - (child++)->argp = &argp_default_argp; - if (argp_program_version || argp_program_version_hook) - (child++)->argp = &argp_version_argp; - child->argp = 0; - - argp = top_argp; - } - - /* Construct a parser for these arguments. */ - err = parser_init (&parser, argp, argc, argv, flags, input); - - if (! err) - /* Parse! */ - { - while (! err) - err = parser_parse_next (&parser, &arg_ebadkey); - err = parser_finalize (&parser, err, arg_ebadkey, end_index); - } - - return err; -} -#ifdef weak_alias -weak_alias (__argp_parse, argp_parse) -#endif - -/* Return the input field for ARGP in the parser corresponding to STATE; used - by the help routines. */ -void * -__argp_input (const struct argp *argp, const struct argp_state *state) -{ - if (state) - { - struct group *group; - struct parser *parser = state->pstate; - - for (group = parser->groups; group < parser->egroup; group++) - if (group->argp == argp) - return group->input; - } - - return 0; -} -#ifdef weak_alias -weak_alias (__argp_input, _argp_input) -#endif diff --git a/contrib/cpio/lib/argp-pin.c b/contrib/cpio/lib/argp-pin.c deleted file mode 100644 index 852c6d6d938..00000000000 --- a/contrib/cpio/lib/argp-pin.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Full and short program names for argp module - Copyright (C) 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME -char *program_invocation_short_name = 0; -#endif -#ifndef HAVE_PROGRAM_INVOCATION_NAME -char *program_invocation_name = 0; -#endif - diff --git a/contrib/cpio/lib/argp-pv.c b/contrib/cpio/lib/argp-pv.c deleted file mode 100644 index a11298bfabd..00000000000 --- a/contrib/cpio/lib/argp-pv.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Default definition for ARGP_PROGRAM_VERSION. - Copyright (C) 1996, 1997, 1999, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* If set by the user program to a non-zero value, then a default option - --version is added (unless the ARGP_NO_HELP flag is used), which will - print this string followed by a newline and exit (unless the - ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ -const char *argp_program_version; diff --git a/contrib/cpio/lib/argp-pvh.c b/contrib/cpio/lib/argp-pvh.c deleted file mode 100644 index 6bf7c49b814..00000000000 --- a/contrib/cpio/lib/argp-pvh.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Default definition for ARGP_PROGRAM_VERSION_HOOK. - Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "argp.h" - -/* If set by the user program to a non-zero value, then a default option - --version is added (unless the ARGP_NO_HELP flag is used), which calls - this function with a stream to print the version to and a pointer to the - current parsing state, and then exits (unless the ARGP_NO_EXIT flag is - used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ -void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL; diff --git a/contrib/cpio/lib/argp-xinl.c b/contrib/cpio/lib/argp-xinl.c deleted file mode 100644 index a6afb1f739a..00000000000 --- a/contrib/cpio/lib/argp-xinl.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Real definitions for extern inline functions in argp.h - Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if defined _LIBC || defined HAVE_FEATURES_H -# include -#endif - -#ifndef __USE_EXTERN_INLINES -# define __USE_EXTERN_INLINES 1 -#endif -#define ARGP_EI -#undef __OPTIMIZE__ -#define __OPTIMIZE__ 1 -#include "argp.h" - -/* Add weak aliases. */ -#if _LIBC - 0 && defined (weak_alias) - -weak_alias (__argp_usage, argp_usage) -weak_alias (__option_is_short, _option_is_short) -weak_alias (__option_is_end, _option_is_end) - -#endif diff --git a/contrib/cpio/lib/argp.h b/contrib/cpio/lib/argp.h deleted file mode 100644 index b5aadcfcac5..00000000000 --- a/contrib/cpio/lib/argp.h +++ /dev/null @@ -1,624 +0,0 @@ -/* $FreeBSD$ */ - -/* Hierarchial argument parsing, layered over getopt. - Copyright (C) 1995-1999,2003-2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _ARGP_H -#define _ARGP_H - -#include -#include -#include -#include - -#define __need_error_t -#include - -#ifndef __THROW -# define __THROW -#endif -#ifndef __NTH -# define __NTH(fct) fct __THROW -#endif - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__ -# define __format__ format -# define __printf__ printf -# endif -#endif - -/* GCC 2.95 and later have "__restrict"; C99 compilers have - "restrict", and "configure" may have defined "restrict". - Other compilers use __restrict, __restrict__, and _Restrict, and - 'configure' might #define 'restrict' to those words. */ -#ifndef __restrict -# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) -# if 199901L <= __STDC_VERSION__ -# define __restrict restrict -# else -# define __restrict -# endif -# endif -#endif - -#ifndef __error_t_defined -typedef int error_t; -# define __error_t_defined -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* A description of a particular option. A pointer to an array of - these is passed in the OPTIONS field of an argp structure. Each option - entry can correspond to one long option and/or one short option; more - names for the same option can be added by following an entry in an option - array with options having the OPTION_ALIAS flag set. */ -struct argp_option -{ - /* The long option name. For more than one name for the same option, you - can use following options with the OPTION_ALIAS flag set. */ - const char *name; - - /* What key is returned for this option. If > 0 and printable, then it's - also accepted as a short option. */ - int key; - - /* If non-NULL, this is the name of the argument associated with this - option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */ - const char *arg; - - /* OPTION_ flags. */ - int flags; - - /* The doc string for this option. If both NAME and KEY are 0, This string - will be printed outdented from the normal option column, making it - useful as a group header (it will be the first thing printed in its - group); in this usage, it's conventional to end the string with a `:'. - - Write the initial value as N_("TEXT") if you want xgettext to collect - it into a POT file. */ - const char *doc; - - /* The group this option is in. In a long help message, options are sorted - alphabetically within each group, and the groups presented in the order - 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with - if this field 0 will inherit the group number of the previous entry, or - zero if it's the first one, unless its a group header (NAME and KEY both - 0), in which case, the previous entry + 1 is the default. Automagic - options such as --help are put into group -1. */ - int group; -}; - -/* The argument associated with this option is optional. */ -#define OPTION_ARG_OPTIONAL 0x1 - -/* This option isn't displayed in any help messages. */ -#define OPTION_HIDDEN 0x2 - -/* This option is an alias for the closest previous non-alias option. This - means that it will be displayed in the same help entry, and will inherit - fields other than NAME and KEY from the aliased option. */ -#define OPTION_ALIAS 0x4 - -/* This option isn't actually an option (and so should be ignored by the - actual option parser), but rather an arbitrary piece of documentation that - should be displayed in much the same manner as the options. If this flag - is set, then the option NAME field is displayed unmodified (e.g., no `--' - prefix is added) at the left-margin (where a *short* option would normally - be displayed), and the documentation string in the normal place. The NAME - field will be translated using gettext, unless OPTION_NO_TRANS is set (see - below). For purposes of sorting, any leading whitespace and punctuation is - ignored, except that if the first non-whitespace character is not `-', this - entry is displayed after all options (and OPTION_DOC entries with a leading - `-') in the same group. */ -#define OPTION_DOC 0x8 - -/* This option shouldn't be included in `long' usage messages (but is still - included in help messages). This is mainly intended for options that are - completely documented in an argp's ARGS_DOC field, in which case including - the option in the generic usage list would be redundant. For instance, - if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to - distinguish these two cases, -x should probably be marked - OPTION_NO_USAGE. */ -#define OPTION_NO_USAGE 0x10 - -/* Valid only in conjunction with OPTION_DOC. This option disables translation - of option name. */ -#define OPTION_NO_TRANS 0x20 - - -struct argp; /* fwd declare this type */ -struct argp_state; /* " */ -struct argp_child; /* " */ - -/* The type of a pointer to an argp parsing function. */ -typedef error_t (*argp_parser_t) (int key, char *arg, - struct argp_state *state); - -/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such - returns will simply be ignored. For user keys, this error will be turned - into EINVAL (if the call to argp_parse is such that errors are propagated - back to the user instead of exiting); returning EINVAL itself would result - in an immediate stop to parsing in *all* cases. */ -#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */ - -/* Special values for the KEY argument to an argument parsing function. - ARGP_ERR_UNKNOWN should be returned if they aren't understood. - - The sequence of keys to a parsing function is either (where each - uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key): - - INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all - or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed - or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized - - The third case is where every parser returned ARGP_KEY_UNKNOWN for an - argument, in which case parsing stops at that argument (returning the - unparsed arguments to the caller of argp_parse if requested, or stopping - with an error message if not). - - If an error occurs (either detected by argp, or because the parsing - function returned an error value), then the parser is called with - ARGP_KEY_ERROR, and no further calls are made. */ - -/* This is not an option at all, but rather a command line argument. If a - parser receiving this key returns success, the fact is recorded, and the - ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the - argument, a parser function decrements the NEXT field of the state it's - passed, the option won't be considered processed; this is to allow you to - actually modify the argument (perhaps into an option), and have it - processed again. */ -#define ARGP_KEY_ARG 0 -/* There are remaining arguments not parsed by any parser, which may be found - starting at (STATE->argv + STATE->next). If success is returned, but - STATE->next left untouched, it's assumed that all arguments were consume, - otherwise, the parser should adjust STATE->next to reflect any arguments - consumed. */ -#define ARGP_KEY_ARGS 0x1000006 -/* There are no more command line arguments at all. */ -#define ARGP_KEY_END 0x1000001 -/* Because it's common to want to do some special processing if there aren't - any non-option args, user parsers are called with this key if they didn't - successfully process any non-option arguments. Called just before - ARGP_KEY_END (where more general validity checks on previously parsed - arguments can take place). */ -#define ARGP_KEY_NO_ARGS 0x1000002 -/* Passed in before any parsing is done. Afterwards, the values of each - element of the CHILD_INPUT field, if any, in the state structure is - copied to each child's state to be the initial value of the INPUT field. */ -#define ARGP_KEY_INIT 0x1000003 -/* Use after all other keys, including SUCCESS & END. */ -#define ARGP_KEY_FINI 0x1000007 -/* Passed in when parsing has successfully been completed (even if there are - still arguments remaining). */ -#define ARGP_KEY_SUCCESS 0x1000004 -/* Passed in if an error occurs. */ -#define ARGP_KEY_ERROR 0x1000005 - -/* An argp structure contains a set of options declarations, a function to - deal with parsing one, documentation string, a possible vector of child - argp's, and perhaps a function to filter help output. When actually - parsing options, getopt is called with the union of all the argp - structures chained together through their CHILD pointers, with conflicts - being resolved in favor of the first occurrence in the chain. */ -struct argp -{ - /* An array of argp_option structures, terminated by an entry with both - NAME and KEY having a value of 0. */ - const struct argp_option *options; - - /* What to do with an option from this structure. KEY is the key - associated with the option, and ARG is any associated argument (NULL if - none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be - returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then - parsing is stopped immediately, and that value is returned from - argp_parse(). For special (non-user-supplied) values of KEY, see the - ARGP_KEY_ definitions below. */ - argp_parser_t parser; - - /* A string describing what other arguments are wanted by this program. It - is only used by argp_usage to print the `Usage:' message. If it - contains newlines, the strings separated by them are considered - alternative usage patterns, and printed on separate lines (lines after - the first are prefix by ` or: ' instead of `Usage:'). */ - const char *args_doc; - - /* If non-NULL, a string containing extra text to be printed before and - after the options in a long help message (separated by a vertical tab - `\v' character). - Write the initial value as N_("BEFORE-TEXT") "\v" N_("AFTER-TEXT") if - you want xgettext to collect the two pieces of text into a POT file. */ - const char *doc; - - /* A vector of argp_children structures, terminated by a member with a 0 - argp field, pointing to child argps should be parsed with this one. Any - conflicts are resolved in favor of this argp, or early argps in the - CHILDREN list. This field is useful if you use libraries that supply - their own argp structure, which you want to use in conjunction with your - own. */ - const struct argp_child *children; - - /* If non-zero, this should be a function to filter the output of help - messages. KEY is either a key from an option, in which case TEXT is - that option's help text, or a special key from the ARGP_KEY_HELP_ - defines, below, describing which other help text TEXT is. The function - should return either TEXT, if it should be used as-is, a replacement - string, which should be malloced, and will be freed by argp, or NULL, - meaning `print nothing'. The value for TEXT is *after* any translation - has been done, so if any of the replacement text also needs translation, - that should be done by the filter function. INPUT is either the input - supplied to argp_parse, or NULL, if argp_help was called directly. */ - char *(*help_filter) (int __key, const char *__text, void *__input); - - /* If non-zero the strings used in the argp library are translated using - the domain described by this string. Otherwise the currently installed - default domain is used. */ - const char *argp_domain; -}; - -/* Possible KEY arguments to a help filter function. */ -#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */ -#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */ -#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */ -#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation; - TEXT is NULL for this key. */ -/* Explanatory note emitted when duplicate option arguments have been - suppressed. */ -#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 -#define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */ - -/* When an argp has a non-zero CHILDREN field, it should point to a vector of - argp_child structures, each of which describes a subsidiary argp. */ -struct argp_child -{ - /* The child parser. */ - const struct argp *argp; - - /* Flags for this child. */ - int flags; - - /* If non-zero, an optional header to be printed in help output before the - child options. As a side-effect, a non-zero value forces the child - options to be grouped together; to achieve this effect without actually - printing a header string, use a value of "". */ - const char *header; - - /* Where to group the child options relative to the other (`consolidated') - options in the parent argp; the values are the same as the GROUP field - in argp_option structs, but all child-groupings follow parent options at - a particular group level. If both this field and HEADER are zero, then - they aren't grouped at all, but rather merged with the parent options - (merging the child's grouping levels with the parents). */ - int group; -}; - -/* Parsing state. This is provided to parsing functions called by argp, - which may examine and, as noted, modify fields. */ -struct argp_state -{ - /* The top level ARGP being parsed. */ - const struct argp *root_argp; - - /* The argument vector being parsed. May be modified. */ - int argc; - char **argv; - - /* The index in ARGV of the next arg that to be parsed. May be modified. */ - int next; - - /* The flags supplied to argp_parse. May be modified. */ - unsigned flags; - - /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the - number of the current arg, starting at zero, and incremented after each - such call returns. At all other times, this is the number of such - arguments that have been processed. */ - unsigned arg_num; - - /* If non-zero, the index in ARGV of the first argument following a special - `--' argument (which prevents anything following being interpreted as an - option). Only set once argument parsing has proceeded past this point. */ - int quoted; - - /* An arbitrary pointer passed in from the user. */ - void *input; - /* Values to pass to child parsers. This vector will be the same length as - the number of children for the current parser. */ - void **child_inputs; - - /* For the parser's use. Initialized to 0. */ - void *hook; - - /* The name used when printing messages. This is initialized to ARGV[0], - or PROGRAM_INVOCATION_NAME if that is unavailable. */ - char *name; - - /* Streams used when argp prints something. */ - FILE *err_stream; /* For errors; initialized to stderr. */ - FILE *out_stream; /* For information; initialized to stdout. */ - - void *pstate; /* Private, for use by argp. */ -}; - -/* Flags for argp_parse (note that the defaults are those that are - convenient for program command line parsing): */ - -/* Don't ignore the first element of ARGV. Normally (and always unless - ARGP_NO_ERRS is set) the first element of the argument vector is - skipped for option parsing purposes, as it corresponds to the program name - in a command line. */ -#define ARGP_PARSE_ARGV0 0x01 - -/* Don't print error messages for unknown options to stderr; unless this flag - is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program - name in the error messages. This flag implies ARGP_NO_EXIT (on the - assumption that silent exiting upon errors is bad behaviour). */ -#define ARGP_NO_ERRS 0x02 - -/* Don't parse any non-option args. Normally non-option args are parsed by - calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg - as the value. Since it's impossible to know which parse function wants to - handle it, each one is called in turn, until one returns 0 or an error - other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the - argp_parse returns prematurely (but with a return value of 0). If all - args have been parsed without error, all parsing functions are called one - last time with a key of ARGP_KEY_END. This flag needn't normally be set, - as the normal behavior is to stop parsing as soon as some argument can't - be handled. */ -#define ARGP_NO_ARGS 0x04 - -/* Parse options and arguments in the same order they occur on the command - line -- normally they're rearranged so that all options come first. */ -#define ARGP_IN_ORDER 0x08 - -/* Don't provide the standard long option --help, which causes usage and - option help information to be output to stdout, and exit (0) called. */ -#define ARGP_NO_HELP 0x10 - -/* Don't exit on errors (they may still result in error messages). */ -#define ARGP_NO_EXIT 0x20 - -/* Use the gnu getopt `long-only' rules for parsing arguments. */ -#define ARGP_LONG_ONLY 0x40 - -/* Turns off any message-printing/exiting options. */ -#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP) - -/* Parse the options strings in ARGC & ARGV according to the options in ARGP. - FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the - index in ARGV of the first unparsed option is returned in it. If an - unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser - routine returned a non-zero value, it is returned; otherwise 0 is - returned. This function may also call exit unless the ARGP_NO_HELP flag - is set. INPUT is a pointer to a value to be passed in to the parser. */ -extern error_t argp_parse (const struct argp *__restrict __argp, - int /*argc*/, char **__restrict /*argv*/, - unsigned __flags, int *__restrict __arg_index, - void *__restrict __input); -extern error_t __argp_parse (const struct argp *__restrict __argp, - int /*argc*/, char **__restrict /*argv*/, - unsigned __flags, int *__restrict __arg_index, - void *__restrict __input); - -/* Global variables. */ - -/* GNULIB makes sure both program_invocation_name and - program_invocation_short_name are available */ -#ifdef GNULIB_PROGRAM_INVOCATION_NAME -extern char *program_invocation_name; -# undef HAVE_DECL_PROGRAM_INVOCATION_NAME -# define HAVE_DECL_PROGRAM_INVOCATION_NAME 1 -#endif - -#ifdef GNULIB_PROGRAM_INVOCATION_SHORT_NAME -extern char *program_invocation_short_name; -# undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME -# define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1 -#endif - -/* If defined or set by the user program to a non-zero value, then a default - option --version is added (unless the ARGP_NO_HELP flag is used), which - will print this string followed by a newline and exit (unless the - ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ -extern const char *argp_program_version; - -/* If defined or set by the user program to a non-zero value, then a default - option --version is added (unless the ARGP_NO_HELP flag is used), which - calls this function with a stream to print the version to and a pointer to - the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is - used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ -extern void (*argp_program_version_hook) (FILE *__restrict __stream, - struct argp_state *__restrict - __state); - -/* If defined or set by the user program, it should point to string that is - the bug-reporting address for the program. It will be printed by - argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various - standard help messages), embedded in a sentence that says something like - `Report bugs to ADDR.'. */ -extern const char *argp_program_bug_address; - -/* The exit status that argp will use when exiting due to a parsing error. - If not defined or set by the user program, this defaults to EX_USAGE from - . */ -extern error_t argp_err_exit_status; - -/* Flags for argp_help. */ -#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */ -#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */ -#define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */ -#define ARGP_HELP_LONG 0x08 /* a long help message. */ -#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */ -#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */ -#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC) -#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */ -#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to - reflect ARGP_LONG_ONLY mode. */ - -/* These ARGP_HELP flags are only understood by argp_state_help. */ -#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */ -#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */ - -/* The standard thing to do after a program command line parsing error, if an - error message has already been printed. */ -#define ARGP_HELP_STD_ERR \ - (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) -/* The standard thing to do after a program command line parsing error, if no - more specific error message has been printed. */ -#define ARGP_HELP_STD_USAGE \ - (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) -/* The standard thing to do in response to a --help option. */ -#define ARGP_HELP_STD_HELP \ - (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \ - | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR) - -/* Output a usage message for ARGP to STREAM. FLAGS are from the set - ARGP_HELP_*. */ -extern void argp_help (const struct argp *__restrict __argp, - FILE *__restrict __stream, - unsigned __flags, char *__restrict __name); -extern void __argp_help (const struct argp *__restrict __argp, - FILE *__restrict __stream, unsigned __flags, - char *__name); - -/* The following routines are intended to be called from within an argp - parsing routine (thus taking an argp_state structure as the first - argument). They may or may not print an error message and exit, depending - on the flags in STATE -- in any case, the caller should be prepared for - them *not* to exit, and should return an appropiate error after calling - them. [argp_usage & argp_error should probably be called argp_state_..., - but they're used often enough that they should be short] */ - -/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are - from the set ARGP_HELP_*. */ -extern void argp_state_help (const struct argp_state *__restrict __state, - FILE *__restrict __stream, - unsigned int __flags); -extern void __argp_state_help (const struct argp_state *__restrict __state, - FILE *__restrict __stream, - unsigned int __flags); - -/* Possibly output the standard usage message for ARGP to stderr and exit. */ -extern void argp_usage (const struct argp_state *__state); -extern void __argp_usage (const struct argp_state *__state); - -/* If appropriate, print the printf string FMT and following args, preceded - by the program name and `:', to stderr, and followed by a `Try ... --help' - message, then exit (1). */ -extern void argp_error (const struct argp_state *__restrict __state, - const char *__restrict __fmt, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); -extern void __argp_error (const struct argp_state *__restrict __state, - const char *__restrict __fmt, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - -/* Similar to the standard gnu error-reporting function error(), but will - respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print - to STATE->err_stream. This is useful for argument parsing code that is - shared between program startup (when exiting is desired) and runtime - option parsing (when typically an error code is returned instead). The - difference between this function and argp_error is that the latter is for - *parsing errors*, and the former is for other problems that occur during - parsing but don't reflect a (syntactic) problem with the input. */ -extern void argp_failure (const struct argp_state *__restrict __state, - int __status, int __errnum, - const char *__restrict __fmt, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); -extern void __argp_failure (const struct argp_state *__restrict __state, - int __status, int __errnum, - const char *__restrict __fmt, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); - -/* Returns true if the option OPT is a valid short option. */ -extern int _option_is_short (const struct argp_option *__opt) __THROW; -extern int __option_is_short (const struct argp_option *__opt) __THROW; - -/* Returns true if the option OPT is in fact the last (unused) entry in an - options array. */ -extern int _option_is_end (const struct argp_option *__opt) __THROW; -extern int __option_is_end (const struct argp_option *__opt) __THROW; - -/* Return the input field for ARGP in the parser corresponding to STATE; used - by the help routines. */ -extern void *_argp_input (const struct argp *__restrict __argp, - const struct argp_state *__restrict __state) - __THROW; -extern void *__argp_input (const struct argp *__restrict __argp, - const struct argp_state *__restrict __state) - __THROW; - -#ifdef __USE_EXTERN_INLINES - -# if !_LIBC -# define __argp_usage argp_usage -# define __argp_state_help argp_state_help -# define __option_is_short _option_is_short -# define __option_is_end _option_is_end -# endif - -# ifndef ARGP_EI -# define ARGP_EI extern __inline__ -# endif - -ARGP_EI void -__argp_usage (const struct argp_state *__state) -{ - __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE); -} - -ARGP_EI int -__NTH (__option_is_short (const struct argp_option *__opt)) -{ - if (__opt->flags & OPTION_DOC) - return 0; - else - { - int __key = __opt->key; - return __key > 0 && __key <= UCHAR_MAX && isprint (__key); - } -} - -ARGP_EI int -__NTH (__option_is_end (const struct argp_option *__opt)) -{ - return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; -} - -# if !_LIBC -# undef __argp_usage -# undef __argp_state_help -# undef __option_is_short -# undef __option_is_end -# endif -#endif /* Use extern inlines. */ - -#ifdef __cplusplus -} -#endif - -#endif /* argp.h */ diff --git a/contrib/cpio/lib/basename.c b/contrib/cpio/lib/basename.c deleted file mode 100644 index fbe17ff910c..00000000000 --- a/contrib/cpio/lib/basename.c +++ /dev/null @@ -1,129 +0,0 @@ -/* basename.c -- return the last element in a file name - - Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 Free - Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "dirname.h" - -#include -#include "xalloc.h" -#include "xstrndup.h" - -/* Return the address of the last file name component of NAME. If - NAME has no relative file name components because it is a file - system root, return the empty string. */ - -char * -last_component (char const *name) -{ - char const *base = name + FILE_SYSTEM_PREFIX_LEN (name); - char const *p; - bool saw_slash = false; - - while (ISSLASH (*base)) - base++; - - for (p = base; *p; p++) - { - if (ISSLASH (*p)) - saw_slash = true; - else if (saw_slash) - { - base = p; - saw_slash = false; - } - } - - return (char *) base; -} - - -/* In general, we can't use the builtin `basename' function if available, - since it has different meanings in different environments. - In some environments the builtin `basename' modifies its argument. - - Return the last file name component of NAME, allocated with - xmalloc. On systems with drive letters, a leading "./" - distinguishes relative names that would otherwise look like a drive - letter. Unlike POSIX basename(), NAME cannot be NULL, - base_name("") returns "", and the first trailing slash is not - stripped. - - If lstat (NAME) would succeed, then { chdir (dir_name (NAME)); - lstat (base_name (NAME)); } will access the same file. Likewise, - if the sequence { chdir (dir_name (NAME)); - rename (base_name (NAME), "foo"); } succeeds, you have renamed NAME - to "foo" in the same directory NAME was in. */ - -char * -base_name (char const *name) -{ - char const *base = last_component (name); - size_t length; - - /* If there is no last component, then name is a file system root or the - empty string. */ - if (! *base) - return xstrndup (name, base_len (name)); - - /* Collapse a sequence of trailing slashes into one. */ - length = base_len (base); - if (ISSLASH (base[length])) - length++; - - /* On systems with drive letters, `a/b:c' must return `./b:c' rather - than `b:c' to avoid confusion with a drive letter. On systems - with pure POSIX semantics, this is not an issue. */ - if (FILE_SYSTEM_PREFIX_LEN (base)) - { - char *p = xmalloc (length + 3); - p[0] = '.'; - p[1] = '/'; - memcpy (p + 2, base, length); - p[length + 2] = '\0'; - return p; - } - - /* Finally, copy the basename. */ - return xstrndup (base, length); -} - -/* Return the length of the basename NAME. Typically NAME is the - value returned by base_name or last_component. Act like strlen - (NAME), except omit all trailing slashes. */ - -size_t -base_len (char const *name) -{ - size_t len; - size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name); - - for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--) - continue; - - if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1 - && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2]) - return 2; - - if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len - && len == prefix_len && ISSLASH (name[prefix_len])) - return prefix_len + 1; - - return len; -} diff --git a/contrib/cpio/lib/dirname.c b/contrib/cpio/lib/dirname.c deleted file mode 100644 index 16552c64d2a..00000000000 --- a/contrib/cpio/lib/dirname.c +++ /dev/null @@ -1,85 +0,0 @@ -/* dirname.c -- return all but the last element in a file name - - Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005, 2006 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "dirname.h" - -#include -#include "xalloc.h" - -/* Return the length of the prefix of FILE that will be used by - dir_name. If FILE is in the working directory, this returns zero - even though `dir_name (FILE)' will return ".". Works properly even - if there are trailing slashes (by effectively ignoring them). */ - -size_t -dir_len (char const *file) -{ - size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file); - size_t length; - - /* Advance prefix_length beyond important leading slashes. */ - prefix_length += (prefix_length != 0 - ? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE - && ISSLASH (file[prefix_length])) - : (ISSLASH (file[0]) - ? ((DOUBLE_SLASH_IS_DISTINCT_ROOT - && ISSLASH (file[1]) && ! ISSLASH (file[2]) - ? 2 : 1)) - : 0)); - - /* Strip the basename and any redundant slashes before it. */ - for (length = last_component (file) - file; - prefix_length < length; length--) - if (! ISSLASH (file[length - 1])) - break; - return length; -} - - -/* In general, we can't use the builtin `dirname' function if available, - since it has different meanings in different environments. - In some environments the builtin `dirname' modifies its argument. - - Return the leading directories part of FILE, allocated with xmalloc. - Works properly even if there are trailing slashes (by effectively - ignoring them). Unlike POSIX dirname(), FILE cannot be NULL. - - If lstat (FILE) would succeed, then { chdir (dir_name (FILE)); - lstat (base_name (FILE)); } will access the same file. Likewise, - if the sequence { chdir (dir_name (FILE)); - rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE - to "foo" in the same directory FILE was in. */ - -char * -dir_name (char const *file) -{ - size_t length = dir_len (file); - bool append_dot = (length == 0 - || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE - && length == FILE_SYSTEM_PREFIX_LEN (file) - && file[2] != '\0' && ! ISSLASH (file[2]))); - char *dir = xmalloc (length + append_dot + 1); - memcpy (dir, file, length); - if (append_dot) - dir[length++] = '.'; - dir[length] = '\0'; - return dir; -} diff --git a/contrib/cpio/lib/dirname.h b/contrib/cpio/lib/dirname.h deleted file mode 100644 index 91e7ed33666..00000000000 --- a/contrib/cpio/lib/dirname.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Take file names apart into directory and base names. - - Copyright (C) 1998, 2001, 2003-2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef DIRNAME_H_ -# define DIRNAME_H_ 1 - -# include -# include - -# ifndef DIRECTORY_SEPARATOR -# define DIRECTORY_SEPARATOR '/' -# endif - -# ifndef ISSLASH -# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) -# endif - -# ifndef FILE_SYSTEM_PREFIX_LEN -# if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX - /* This internal macro assumes ASCII, but all hosts that support drive - letters use ASCII. */ -# define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \ - <= 'z' - 'a') -# define FILE_SYSTEM_PREFIX_LEN(Filename) \ - (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0) -# else -# define FILE_SYSTEM_PREFIX_LEN(Filename) 0 -# endif -# endif - -# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE -# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 -# endif - -# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT -# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 -# endif - -# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE -# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) -# else -# define IS_ABSOLUTE_FILE_NAME(F) \ - (ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F)) -# endif -# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) - -char *base_name (char const *file); -char *dir_name (char const *file); -size_t base_len (char const *file); -size_t dir_len (char const *file); -char *last_component (char const *file); - -bool strip_trailing_slashes (char *file); - -#endif /* not DIRNAME_H_ */ diff --git a/contrib/cpio/lib/error.c b/contrib/cpio/lib/error.c deleted file mode 100644 index cf863433202..00000000000 --- a/contrib/cpio/lib/error.c +++ /dev/null @@ -1,338 +0,0 @@ -/* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000-2005, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by David MacKenzie . */ - -#if !_LIBC -# include -#endif - -#include "error.h" - -#include -#include -#include -#include - -#if !_LIBC && ENABLE_NLS -# include "gettext.h" -#endif - -#ifdef _LIBC -# include -# include -# include -# include -# define mbsrtowcs __mbsrtowcs -#endif - -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - -#ifndef _ -# define _(String) String -#endif - -/* If NULL, error will flush stdout, then print on stderr the program - name, a colon and a space. Otherwise, error will call this - function without parameters instead. */ -void (*error_print_progname) (void); - -/* This variable is incremented each time `error' is called. */ -unsigned int error_message_count; - -#ifdef _LIBC -/* In the GNU C library, there is a predefined variable for this. */ - -# define program_name program_invocation_name -# include -# include -# include - -/* In GNU libc we want do not want to use the common name `error' directly. - Instead make it a weak alias. */ -extern void __error (int status, int errnum, const char *message, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); -extern void __error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, - ...) - __attribute__ ((__format__ (__printf__, 5, 6)));; -# define error __error -# define error_at_line __error_at_line - -# include -# define fflush(s) INTUSE(_IO_fflush) (s) -# undef putc -# define putc(c, fp) INTUSE(_IO_putc) (c, fp) - -# include - -#else /* not _LIBC */ - -# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P -# ifndef HAVE_DECL_STRERROR_R -"this configure-time declaration test was not run" -# endif -char *strerror_r (); -# endif - -/* The calling program should define program_name and set it to the - name of the executing program. */ -extern char *program_name; - -# if HAVE_STRERROR_R || defined strerror_r -# define __strerror_r strerror_r -# endif /* HAVE_STRERROR_R || defined strerror_r */ -#endif /* not _LIBC */ - -static void -print_errno_message (int errnum) -{ - char const *s; - -#if defined HAVE_STRERROR_R || _LIBC - char errbuf[1024]; -# if STRERROR_R_CHAR_P || _LIBC - s = __strerror_r (errnum, errbuf, sizeof errbuf); -# else - if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) - s = errbuf; - else - s = 0; -# endif -#else - s = strerror (errnum); -#endif - -#if !_LIBC - if (! s) - s = _("Unknown system error"); -#endif - -#if _LIBC - __fxprintf (NULL, ": %s", s); -#else - fprintf (stderr, ": %s", s); -#endif -} - -static void -error_tail (int status, int errnum, const char *message, va_list args) -{ -#if _LIBC - if (_IO_fwide (stderr, 0) > 0) - { -# define ALLOCA_LIMIT 2000 - size_t len = strlen (message) + 1; - wchar_t *wmessage = NULL; - mbstate_t st; - size_t res; - const char *tmp; - bool use_malloc = false; - - while (1) - { - if (__libc_use_alloca (len * sizeof (wchar_t))) - wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); - else - { - if (!use_malloc) - wmessage = NULL; - - wchar_t *p = (wchar_t *) realloc (wmessage, - len * sizeof (wchar_t)); - if (p == NULL) - { - free (wmessage); - fputws_unlocked (L"out of memory\n", stderr); - return; - } - wmessage = p; - use_malloc = true; - } - - memset (&st, '\0', sizeof (st)); - tmp = message; - - res = mbsrtowcs (wmessage, &tmp, len, &st); - if (res != len) - break; - - if (__builtin_expect (len >= SIZE_MAX / 2, 0)) - { - /* This really should not happen if everything is fine. */ - res = (size_t) -1; - break; - } - - len *= 2; - } - - if (res == (size_t) -1) - { - /* The string cannot be converted. */ - if (use_malloc) - { - free (wmessage); - use_malloc = false; - } - wmessage = (wchar_t *) L"???"; - } - - __vfwprintf (stderr, wmessage, args); - - if (use_malloc) - free (wmessage); - } - else -#endif - vfprintf (stderr, message, args); - va_end (args); - - ++error_message_count; - if (errnum) - print_errno_message (errnum); -#if _LIBC - __fxprintf (NULL, "\n"); -#else - putc ('\n', stderr); -#endif - fflush (stderr); - if (status) - exit (status); -} - - -/* Print the program name and error message MESSAGE, which is a printf-style - format string with optional args. - If ERRNUM is nonzero, print its corresponding system error message. - Exit with status STATUS if it is nonzero. */ -void -error (int status, int errnum, const char *message, ...) -{ - va_list args; - -#if defined _LIBC && defined __libc_ptf_call - /* We do not want this call to be cut short by a thread - cancellation. Therefore disable cancellation for now. */ - int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); -#endif - - fflush (stdout); -#ifdef _LIBC - _IO_flockfile (stderr); -#endif - if (error_print_progname) - (*error_print_progname) (); - else - { -#if _LIBC - __fxprintf (NULL, "%s: ", program_name); -#else - fprintf (stderr, "%s: ", program_name); -#endif - } - - va_start (args, message); - error_tail (status, errnum, message, args); - -#ifdef _LIBC - _IO_funlockfile (stderr); -# ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); -# endif -#endif -} - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -int error_one_per_line; - -void -error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, ...) -{ - va_list args; - - if (error_one_per_line) - { - static const char *old_file_name; - static unsigned int old_line_number; - - if (old_line_number == line_number - && (file_name == old_file_name - || strcmp (old_file_name, file_name) == 0)) - /* Simply return and print nothing. */ - return; - - old_file_name = file_name; - old_line_number = line_number; - } - -#if defined _LIBC && defined __libc_ptf_call - /* We do not want this call to be cut short by a thread - cancellation. Therefore disable cancellation for now. */ - int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); -#endif - - fflush (stdout); -#ifdef _LIBC - _IO_flockfile (stderr); -#endif - if (error_print_progname) - (*error_print_progname) (); - else - { -#if _LIBC - __fxprintf (NULL, "%s:", program_name); -#else - fprintf (stderr, "%s:", program_name); -#endif - } - -#if _LIBC - __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ", - file_name, line_number); -#else - fprintf (stderr, file_name != NULL ? "%s:%d: " : " ", - file_name, line_number); -#endif - - va_start (args, message); - error_tail (status, errnum, message, args); - -#ifdef _LIBC - _IO_funlockfile (stderr); -# ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); -# endif -#endif -} - -#ifdef _LIBC -/* Make the weak alias. */ -# undef error -# undef error_at_line -weak_alias (__error, error) -weak_alias (__error_at_line, error_at_line) -#endif diff --git a/contrib/cpio/lib/error.h b/contrib/cpio/lib/error.h deleted file mode 100644 index 5a5f2476583..00000000000 --- a/contrib/cpio/lib/error.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Declaration for error-reporting function - Copyright (C) 1995, 1996, 1997, 2003, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _ERROR_H -#define _ERROR_H 1 - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Print a message with `fprintf (stderr, FORMAT, ...)'; - if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). - If STATUS is nonzero, terminate the program with `exit (STATUS)'. */ - -extern void error (int __status, int __errnum, const char *__format, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -extern void error_at_line (int __status, int __errnum, const char *__fname, - unsigned int __lineno, const char *__format, ...) - __attribute__ ((__format__ (__printf__, 5, 6))); - -/* If NULL, error will flush stdout, then print on stderr the program - name, a colon and a space. Otherwise, error will call this - function without parameters instead. */ -extern void (*error_print_progname) (void); - -/* This variable is incremented each time `error' is called. */ -extern unsigned int error_message_count; - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -extern int error_one_per_line; - -#ifdef __cplusplus -} -#endif - -#endif /* error.h */ diff --git a/contrib/cpio/lib/exitfail.c b/contrib/cpio/lib/exitfail.c deleted file mode 100644 index 373d325c5ad..00000000000 --- a/contrib/cpio/lib/exitfail.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Failure exit status - - Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "exitfail.h" - -#include - -int volatile exit_failure = EXIT_FAILURE; diff --git a/contrib/cpio/lib/exitfail.h b/contrib/cpio/lib/exitfail.h deleted file mode 100644 index e46cf9c1665..00000000000 --- a/contrib/cpio/lib/exitfail.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Failure exit status - - Copyright (C) 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -extern int volatile exit_failure; diff --git a/contrib/cpio/lib/fatal.c b/contrib/cpio/lib/fatal.c deleted file mode 100644 index bcce42c090a..00000000000 --- a/contrib/cpio/lib/fatal.c +++ /dev/null @@ -1,27 +0,0 @@ -/* This file is part of GNU cpio. - Copyright (C) 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#include -#include - -void -fatal_exit () -{ - exit (PAXEXIT_FAILURE); -} - diff --git a/contrib/cpio/lib/full-write.c b/contrib/cpio/lib/full-write.c deleted file mode 100644 index cc168720eae..00000000000 --- a/contrib/cpio/lib/full-write.c +++ /dev/null @@ -1,81 +0,0 @@ -/* An interface to read and write that retries (if necessary) until complete. - - Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#ifdef FULL_READ -# include "full-read.h" -#else -# include "full-write.h" -#endif - -#include - -#ifdef FULL_READ -# include "safe-read.h" -# define safe_rw safe_read -# define full_rw full_read -# undef const -# define const /* empty */ -#else -# include "safe-write.h" -# define safe_rw safe_write -# define full_rw full_write -#endif - -#ifdef FULL_READ -/* Set errno to zero upon EOF. */ -# define ZERO_BYTE_TRANSFER_ERRNO 0 -#else -/* Some buggy drivers return 0 when one tries to write beyond - a device's end. (Example: Linux 1.2.13 on /dev/fd0.) - Set errno to ENOSPC so they get a sensible diagnostic. */ -# define ZERO_BYTE_TRANSFER_ERRNO ENOSPC -#endif - -/* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if - interrupted or if a partial write(read) occurs. Return the number - of bytes transferred. - When writing, set errno if fewer than COUNT bytes are written. - When reading, if fewer than COUNT bytes are read, you must examine - errno to distinguish failure from EOF (errno == 0). */ -size_t -full_rw (int fd, const void *buf, size_t count) -{ - size_t total = 0; - const char *ptr = (const char *) buf; - - while (count > 0) - { - size_t n_rw = safe_rw (fd, ptr, count); - if (n_rw == (size_t) -1) - break; - if (n_rw == 0) - { - errno = ZERO_BYTE_TRANSFER_ERRNO; - break; - } - total += n_rw; - ptr += n_rw; - count -= n_rw; - } - - return total; -} diff --git a/contrib/cpio/lib/full-write.h b/contrib/cpio/lib/full-write.h deleted file mode 100644 index d20d2fe4abd..00000000000 --- a/contrib/cpio/lib/full-write.h +++ /dev/null @@ -1,35 +0,0 @@ -/* An interface to write() that writes all it is asked to write. - - Copyright (C) 2002-2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Write COUNT bytes at BUF to descriptor FD, retrying if interrupted - or if partial writes occur. Return the number of bytes successfully - written, setting errno if that is less than COUNT. */ -extern size_t full_write (int fd, const void *buf, size_t count); - - -#ifdef __cplusplus -} -#endif diff --git a/contrib/cpio/lib/getopt.c b/contrib/cpio/lib/getopt.c deleted file mode 100644 index 3580ad825c6..00000000000 --- a/contrib/cpio/lib/getopt.c +++ /dev/null @@ -1,1191 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to drepper@gnu.org - before changing it! - Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004,2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _LIBC -# include -#endif - -#include "getopt.h" - -#include -#include -#include -#include - -#ifdef __VMS -# include -#endif - -#ifdef _LIBC -# include -#else -# include "gettext.h" -# define _(msgid) gettext (msgid) -#endif - -#if defined _LIBC && defined USE_IN_LIBIO -# include -#endif - -#ifndef attribute_hidden -# define attribute_hidden -#endif - -/* Unlike standard Unix `getopt', functions like `getopt_long' - let the user intersperse the options with the other arguments. - - As `getopt_long' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Using `getopt' or setting the environment variable POSIXLY_CORRECT - disables permutation. - Then the application's behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt_int.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* 1003.2 says this must be 1 before any call. */ -int optind = 1; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; - -/* Keep a global copy of all internal members of getopt_data. */ - -static struct _getopt_data getopt_data; - - -#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV -extern char *getenv (); -#endif - -#ifdef _LIBC -/* Stored original parameters. - XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ -extern int __libc_argc; -extern char **__libc_argv; - -/* Bash 2.0 gives us an environment variable containing flags - indicating ARGV elements that should not be considered arguments. */ - -# ifdef USE_NONOPTION_FLAGS -/* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; -# endif - -# ifdef USE_NONOPTION_FLAGS -# define SWAP_FLAGS(ch1, ch2) \ - if (d->__nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -# else -# define SWAP_FLAGS(ch1, ch2) -# endif -#else /* !_LIBC */ -# define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -static void -exchange (char **argv, struct _getopt_data *d) -{ - int bottom = d->__first_nonopt; - int middle = d->__last_nonopt; - int top = d->optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - /* First make sure the handling of the `__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; - else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - d->__nonoption_flags_max_len), - '\0', top + 1 - d->__nonoption_flags_max_len); - d->__nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } -#endif - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - d->__first_nonopt += (d->optind - d->__last_nonopt); - d->__last_nonopt = d->optind; -} - -/* Initialize the internal data when the first call is made. */ - -static const char * -_getopt_initialize (int argc, char **argv, const char *optstring, - int posixly_correct, struct _getopt_data *d) -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - d->__first_nonopt = d->__last_nonopt = d->optind; - - d->__nextchar = NULL; - - d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - d->__ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - d->__ordering = REQUIRE_ORDER; - ++optstring; - } - else if (d->__posixly_correct) - d->__ordering = REQUIRE_ORDER; - else - d->__ordering = PERMUTE; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - if (!d->__posixly_correct - && argc == __libc_argc && argv == __libc_argv) - { - if (d->__nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - d->__nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = d->__nonoption_flags_max_len = strlen (orig_str); - if (d->__nonoption_flags_max_len < argc) - d->__nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (d->__nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - d->__nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', d->__nonoption_flags_max_len - len); - } - } - d->__nonoption_flags_len = d->__nonoption_flags_max_len; - } - else - d->__nonoption_flags_len = 0; -#endif - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns -1. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. - - If POSIXLY_CORRECT is nonzero, behave as if the POSIXLY_CORRECT - environment variable were set. */ - -int -_getopt_internal_r (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, - int long_only, int posixly_correct, struct _getopt_data *d) -{ - int print_errors = d->opterr; - if (optstring[0] == ':') - print_errors = 0; - - if (argc < 1) - return -1; - - d->optarg = NULL; - - if (d->optind == 0 || !d->__initialized) - { - if (d->optind == 0) - d->optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring, - posixly_correct, d); - d->__initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#if defined _LIBC && defined USE_NONOPTION_FLAGS -# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ - || (d->optind < d->__nonoption_flags_len \ - && __getopt_nonoption_flags[d->optind] == '1')) -#else -# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') -#endif - - if (d->__nextchar == NULL || *d->__nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (d->__last_nonopt > d->optind) - d->__last_nonopt = d->optind; - if (d->__first_nonopt > d->optind) - d->__first_nonopt = d->optind; - - if (d->__ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__last_nonopt != d->optind) - d->__first_nonopt = d->optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (d->optind < argc && NONOPTION_P) - d->optind++; - d->__last_nonopt = d->optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (d->optind != argc && !strcmp (argv[d->optind], "--")) - { - d->optind++; - - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__first_nonopt == d->__last_nonopt) - d->__first_nonopt = d->optind; - d->__last_nonopt = argc; - - d->optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (d->optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (d->__first_nonopt != d->__last_nonopt) - d->optind = d->__first_nonopt; - return -1; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (d->__ordering == REQUIRE_ORDER) - return -1; - d->optarg = argv[d->optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - d->__nextchar = (argv[d->optind] + 1 - + (longopts != NULL && argv[d->optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[d->optind][1] == '-' - || (long_only && (argv[d->optind][2] - || !strchr (optstring, argv[d->optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) - { - if ((unsigned int) (nameend - d->__nextchar) - == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[d->optind]) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[d->optind]); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - d->optopt = 0; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - d->optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - d->optarg = nameend + 1; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (argv[d->optind - 1][1] == '-') - { - /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#else - fprintf (stderr, _("\ -%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } - else - { - /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#else - fprintf (stderr, _("\ -%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - - d->__nextchar += strlen (d->__nextchar); - - d->optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->__nextchar += strlen (d->__nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[d->optind][1] == '-' - || strchr (optstring, *d->__nextchar) == NULL) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (argv[d->optind][1] == '-') - { - /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"), - argv[0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], d->__nextchar); -#endif - } - else - { - /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - d->__nextchar = (char *) ""; - d->optind++; - d->optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *d->__nextchar++; - char *temp = strchr (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*d->__nextchar == '\0') - ++d->optind; - - if (temp == NULL || c == ':') - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (d->__posixly_correct) - { - /* 1003.2 specifies the format of this message. */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: illegal option -- %c\n"), - argv[0], c); -#else - fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); -#endif - } - else - { -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: invalid option -- %c\n"), - argv[0], c); -#else - fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - d->optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, - _("%s: option requires an argument -- %c\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); -#endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `d->optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; - nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) - { - if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[d->optind]) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[d->optind]); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - d->optarg = nameend + 1; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } - - d->__nextchar += strlen (d->__nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]); -#endif - } - d->__nextchar += strlen (d->__nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - d->__nextchar += strlen (d->__nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - d->__nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - d->optind++; - } - else - d->optarg = NULL; - d->__nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option requires an argument -- %c\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); -#endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; - d->__nextchar = NULL; - } - } - return c; - } -} - -int -_getopt_internal (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, - int long_only, int posixly_correct) -{ - int result; - - getopt_data.optind = optind; - getopt_data.opterr = opterr; - - result = _getopt_internal_r (argc, argv, optstring, longopts, longind, - long_only, posixly_correct, &getopt_data); - - optind = getopt_data.optind; - optarg = getopt_data.optarg; - optopt = getopt_data.optopt; - - return result; -} - -/* glibc gets a LSB-compliant getopt. - Standalone applications get a POSIX-compliant getopt. */ -#if _LIBC -enum { POSIXLY_CORRECT = 0 }; -#else -enum { POSIXLY_CORRECT = 1 }; -#endif - -int -getopt (int argc, char *const *argv, const char *optstring) -{ - return _getopt_internal (argc, (char **) argv, optstring, NULL, NULL, 0, - POSIXLY_CORRECT); -} - - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (int argc, char **argv) -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == -1) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/contrib/cpio/lib/getopt1.c b/contrib/cpio/lib/getopt1.c deleted file mode 100644 index cc0746ea43c..00000000000 --- a/contrib/cpio/lib/getopt1.c +++ /dev/null @@ -1,171 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef _LIBC -# include -#else -# include -# include "getopt.h" -#endif -#include "getopt_int.h" - -#include - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (int argc, char *__getopt_argv_const *argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 0, 0); -} - -int -_getopt_long_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) -{ - return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 0, 0, d); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (int argc, char *__getopt_argv_const *argv, - const char *options, - const struct option *long_options, int *opt_index) -{ - return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 1, 0); -} - -int -_getopt_long_only_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) -{ - return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 1, 0, d); -} - - -#ifdef TEST - -#include - -int -main (int argc, char **argv) -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == -1) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/contrib/cpio/lib/getopt_.h b/contrib/cpio/lib/getopt_.h deleted file mode 100644 index 615ef9a3b6f..00000000000 --- a/contrib/cpio/lib/getopt_.h +++ /dev/null @@ -1,226 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GETOPT_H - -#ifndef __need_getopt -# define _GETOPT_H 1 -#endif - -/* Standalone applications should #define __GETOPT_PREFIX to an - identifier that prefixes the external functions and variables - defined in this header. When this happens, include the - headers that might declare getopt so that they will not cause - confusion if included after this file. Then systematically rename - identifiers so that they do not collide with the system functions - and variables. Renaming avoids problems with some compilers and - linkers. */ -#if defined __GETOPT_PREFIX && !defined __need_getopt -# include -# include -# include -# undef __need_getopt -# undef getopt -# undef getopt_long -# undef getopt_long_only -# undef optarg -# undef opterr -# undef optind -# undef optopt -# define __GETOPT_CONCAT(x, y) x ## y -# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) -# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) -# define getopt __GETOPT_ID (getopt) -# define getopt_long __GETOPT_ID (getopt_long) -# define getopt_long_only __GETOPT_ID (getopt_long_only) -# define optarg __GETOPT_ID (optarg) -# define opterr __GETOPT_ID (opterr) -# define optind __GETOPT_ID (optind) -# define optopt __GETOPT_ID (optopt) -#endif - -/* Standalone applications get correct prototypes for getopt_long and - getopt_long_only; they declare "char **argv". libc uses prototypes - with "char *const *argv" that are incorrect because getopt_long and - getopt_long_only can permute argv; this is required for backward - compatibility (e.g., for LSB 2.0.1). - - This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt', - but it caused redefinition warnings if both unistd.h and getopt.h were - included, since unistd.h includes getopt.h having previously defined - __need_getopt. - - The only place where __getopt_argv_const is used is in definitions - of getopt_long and getopt_long_only below, but these are visible - only if __need_getopt is not defined, so it is quite safe to rewrite - the conditional as follows: -*/ -#if !defined __need_getopt -# if defined __GETOPT_PREFIX -# define __getopt_argv_const /* empty */ -# else -# define __getopt_argv_const const -# endif -#endif - -/* If __GNU_LIBRARY__ is not already defined, either we are being used - standalone, or this is the first header included in the source file. - If we are being used with glibc, we need to include , but - that does not exist if we are standalone. So: if __GNU_LIBRARY__ is - not defined, include , which will pull in for us - if it's from glibc. (Why ctype.h? It's guaranteed to exist and it - doesn't flood the namespace with stuff the way some other headers do.) */ -#if !defined __GNU_LIBRARY__ -# include -#endif - -#ifndef __THROW -# ifndef __GNUC_PREREQ -# define __GNUC_PREREQ(maj, min) (0) -# endif -# if defined __cplusplus && __GNUC_PREREQ (2,8) -# define __THROW throw () -# else -# define __THROW -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -#ifndef __need_getopt -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ - - -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, `optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in `optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU `getopt'. - - The argument `--' causes premature termination of argument - scanning, explicitly telling `getopt' that there are no more - options. - - If OPTS begins with `-', then non-option arguments are treated as - arguments to the option '\1'. This behavior is specific to the GNU - `getopt'. If OPTS begins with `+', or POSIXLY_CORRECT is set in - the environment, then do not permute arguments. */ - -extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) - __THROW; - -#ifndef __need_getopt -extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW; -extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW; - -#endif - -#ifdef __cplusplus -} -#endif - -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* getopt.h */ diff --git a/contrib/cpio/lib/getopt_int.h b/contrib/cpio/lib/getopt_int.h deleted file mode 100644 index 401579fd289..00000000000 --- a/contrib/cpio/lib/getopt_int.h +++ /dev/null @@ -1,131 +0,0 @@ -/* Internal declarations for getopt. - Copyright (C) 1989-1994,1996-1999,2001,2003,2004 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GETOPT_INT_H -#define _GETOPT_INT_H 1 - -extern int _getopt_internal (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, int __posixly_correct); - - -/* Reentrant versions which can handle parsing multiple argument - vectors at the same time. */ - -/* Data type for reentrant functions. */ -struct _getopt_data -{ - /* These have exactly the same meaning as the corresponding global - variables, except that they are used for the reentrant - versions of getopt. */ - int optind; - int opterr; - int optopt; - char *optarg; - - /* Internal members. */ - - /* True if the internal members have been initialized. */ - int __initialized; - - /* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - char *__nextchar; - - /* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters, or by calling getopt. - - PERMUTE is the default. We permute the contents of ARGV as we - scan, so that eventually all the non-options are at the end. - This allows options to be given in any order, even with programs - that were not written to expect this. - - RETURN_IN_ORDER is an option available to programs that were - written to expect options and other ARGV-elements in any order - and that care about the ordering of the two. We describe each - non-option ARGV-element as if it were the argument of an option - with character code 1. Using `-' as the first character of the - list of option characters selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return -1 with `optind' != ARGC. */ - - enum - { - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER - } __ordering; - - /* If the POSIXLY_CORRECT environment variable is set - or getopt was called. */ - int __posixly_correct; - - - /* Handle permutation of arguments. */ - - /* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first - of them; `last_nonopt' is the index after the last of them. */ - - int __first_nonopt; - int __last_nonopt; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - int __nonoption_flags_max_len; - int __nonoption_flags_len; -# endif -}; - -/* The initializer is necessary to set OPTIND and OPTERR to their - default values and to clear the initialization flag. */ -#define _GETOPT_DATA_INITIALIZER { 1, 1 } - -extern int _getopt_internal_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, int __posixly_correct, - struct _getopt_data *__data); - -extern int _getopt_long_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - struct _getopt_data *__data); - -extern int _getopt_long_only_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, - int *__longind, - struct _getopt_data *__data); - -#endif /* getopt_int.h */ diff --git a/contrib/cpio/lib/gettext.h b/contrib/cpio/lib/gettext.h deleted file mode 100644 index 9d76ec9afcc..00000000000 --- a/contrib/cpio/lib/gettext.h +++ /dev/null @@ -1,270 +0,0 @@ -/* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _LIBGETTEXT_H -#define _LIBGETTEXT_H 1 - -/* NLS can be disabled through the configure --disable-nls option. */ -#if ENABLE_NLS - -/* Get declarations of GNU message catalog functions. */ -# include - -/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by - the gettext() and ngettext() macros. This is an alternative to calling - textdomain(), and is useful for libraries. */ -# ifdef DEFAULT_TEXT_DOMAIN -# undef gettext -# define gettext(Msgid) \ - dgettext (DEFAULT_TEXT_DOMAIN, Msgid) -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) -# endif - -#else - -/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which - chokes if dcgettext is defined as a macro. So include it now, to make - later inclusions of a NOP. We don't include - as well because people using "gettext.h" will not include , - and also including would fail on SunOS 4, whereas - is OK. */ -#if defined(__sun) -# include -#endif - -/* Many header files from the libstdc++ coming with g++ 3.3 or newer include - , which chokes if dcgettext is defined as a macro. So include - it now, to make later inclusions of a NOP. */ -#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) -# include -# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H -# include -# endif -#endif - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# define gettext(Msgid) ((const char *) (Msgid)) -# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) -# define dcgettext(Domainname, Msgid, Category) \ - ((void) (Category), dgettext (Domainname, Msgid)) -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 \ - ? ((void) (Msgid2), (const char *) (Msgid1)) \ - : ((void) (Msgid1), (const char *) (Msgid2))) -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) -# define textdomain(Domainname) ((const char *) (Domainname)) -# define bindtextdomain(Domainname, Dirname) \ - ((void) (Domainname), (const char *) (Dirname)) -# define bind_textdomain_codeset(Domainname, Codeset) \ - ((void) (Domainname), (const char *) (Codeset)) - -#endif - -/* A pseudo function call that serves as a marker for the automated - extraction of messages, but does not call gettext(). The run-time - translation is done at a different place in the code. - The argument, String, should be a literal string. Concatenated strings - and other string expressions won't work. - The macro's expansion is not parenthesized, so that it is suitable as - initializer for static 'char[]' or 'const char[]' variables. */ -#define gettext_noop(String) String - -/* The separator between msgctxt and msgid in a .mo file. */ -#define GETTEXT_CONTEXT_GLUE "\004" - -/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a - MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be - short and rarely need to change. - The letter 'p' stands for 'particular' or 'special'. */ -#ifdef DEFAULT_TEXT_DOMAIN -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#else -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#endif -#define dpgettext(Domainname, Msgctxt, Msgid) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) -#ifdef DEFAULT_TEXT_DOMAIN -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#else -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#endif -#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -pgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - int category) -{ - const char *translation = dcgettext (domain, msg_ctxt_id, category); - if (translation == msg_ctxt_id) - return msgid; - else - return translation; -} - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -npgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - const char *translation = - dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); - if (translation == msg_ctxt_id || translation == msgid_plural) - return (n == 1 ? msgid : msgid_plural); - else - return translation; -} - -/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID - can be arbitrary expressions. But for string literals these macros are - less efficient than those above. */ - -#include - -#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ - (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ - /* || __STDC_VERSION__ >= 199901L */ ) - -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS -#include -#endif - -#define pgettext_expr(Msgctxt, Msgid) \ - dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) -#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ - dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcgettext (domain, msg_ctxt_id, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (translation != msg_ctxt_id) - return translation; - } - return msgid; -} - -#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcnpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (!(translation == msg_ctxt_id || translation == msgid_plural)) - return translation; - } - return (n == 1 ? msgid : msgid_plural); -} - -#endif /* _LIBGETTEXT_H */ diff --git a/contrib/cpio/lib/hash.c b/contrib/cpio/lib/hash.c deleted file mode 100644 index f4ab12f487d..00000000000 --- a/contrib/cpio/lib/hash.c +++ /dev/null @@ -1,1048 +0,0 @@ -/* hash - hashing table processing. - - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 Free - Software Foundation, Inc. - - Written by Jim Meyering, 1992. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* A generic hash table package. */ - -/* Define USE_OBSTACK to 1 if you want the allocator to use obstacks instead - of malloc. If you change USE_OBSTACK, you have to recompile! */ - -#include - -#include "hash.h" -#include "xalloc.h" - -#include -#include -#include - -#if USE_OBSTACK -# include "obstack.h" -# ifndef obstack_chunk_alloc -# define obstack_chunk_alloc malloc -# endif -# ifndef obstack_chunk_free -# define obstack_chunk_free free -# endif -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -struct hash_table - { - /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1, - for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets - are not empty, there are N_ENTRIES active entries in the table. */ - struct hash_entry *bucket; - struct hash_entry const *bucket_limit; - size_t n_buckets; - size_t n_buckets_used; - size_t n_entries; - - /* Tuning arguments, kept in a physicaly separate structure. */ - const Hash_tuning *tuning; - - /* Three functions are given to `hash_initialize', see the documentation - block for this function. In a word, HASHER randomizes a user entry - into a number up from 0 up to some maximum minus 1; COMPARATOR returns - true if two user entries compare equally; and DATA_FREER is the cleanup - function for a user entry. */ - Hash_hasher hasher; - Hash_comparator comparator; - Hash_data_freer data_freer; - - /* A linked list of freed struct hash_entry structs. */ - struct hash_entry *free_entry_list; - -#if USE_OBSTACK - /* Whenever obstacks are used, it is possible to allocate all overflowed - entries into a single stack, so they all can be freed in a single - operation. It is not clear if the speedup is worth the trouble. */ - struct obstack entry_stack; -#endif - }; - -/* A hash table contains many internal entries, each holding a pointer to - some user provided data (also called a user entry). An entry indistinctly - refers to both the internal entry and its associated user entry. A user - entry contents may be hashed by a randomization function (the hashing - function, or just `hasher' for short) into a number (or `slot') between 0 - and the current table size. At each slot position in the hash table, - starts a linked chain of entries for which the user data all hash to this - slot. A bucket is the collection of all entries hashing to the same slot. - - A good `hasher' function will distribute entries rather evenly in buckets. - In the ideal case, the length of each bucket is roughly the number of - entries divided by the table size. Finding the slot for a data is usually - done in constant time by the `hasher', and the later finding of a precise - entry is linear in time with the size of the bucket. Consequently, a - larger hash table size (that is, a larger number of buckets) is prone to - yielding shorter chains, *given* the `hasher' function behaves properly. - - Long buckets slow down the lookup algorithm. One might use big hash table - sizes in hope to reduce the average length of buckets, but this might - become inordinate, as unused slots in the hash table take some space. The - best bet is to make sure you are using a good `hasher' function (beware - that those are not that easy to write! :-), and to use a table size - larger than the actual number of entries. */ - -/* If an insertion makes the ratio of nonempty buckets to table size larger - than the growth threshold (a number between 0.0 and 1.0), then increase - the table size by multiplying by the growth factor (a number greater than - 1.0). The growth threshold defaults to 0.8, and the growth factor - defaults to 1.414, meaning that the table will have doubled its size - every second time 80% of the buckets get used. */ -#define DEFAULT_GROWTH_THRESHOLD 0.8 -#define DEFAULT_GROWTH_FACTOR 1.414 - -/* If a deletion empties a bucket and causes the ratio of used buckets to - table size to become smaller than the shrink threshold (a number between - 0.0 and 1.0), then shrink the table by multiplying by the shrink factor (a - number greater than the shrink threshold but smaller than 1.0). The shrink - threshold and factor default to 0.0 and 1.0, meaning that the table never - shrinks. */ -#define DEFAULT_SHRINK_THRESHOLD 0.0 -#define DEFAULT_SHRINK_FACTOR 1.0 - -/* Use this to initialize or reset a TUNING structure to - some sensible values. */ -static const Hash_tuning default_tuning = - { - DEFAULT_SHRINK_THRESHOLD, - DEFAULT_SHRINK_FACTOR, - DEFAULT_GROWTH_THRESHOLD, - DEFAULT_GROWTH_FACTOR, - false - }; - -/* Information and lookup. */ - -/* The following few functions provide information about the overall hash - table organization: the number of entries, number of buckets and maximum - length of buckets. */ - -/* Return the number of buckets in the hash table. The table size, the total - number of buckets (used plus unused), or the maximum number of slots, are - the same quantity. */ - -size_t -hash_get_n_buckets (const Hash_table *table) -{ - return table->n_buckets; -} - -/* Return the number of slots in use (non-empty buckets). */ - -size_t -hash_get_n_buckets_used (const Hash_table *table) -{ - return table->n_buckets_used; -} - -/* Return the number of active entries. */ - -size_t -hash_get_n_entries (const Hash_table *table) -{ - return table->n_entries; -} - -/* Return the length of the longest chain (bucket). */ - -size_t -hash_get_max_bucket_length (const Hash_table *table) -{ - struct hash_entry const *bucket; - size_t max_bucket_length = 0; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - struct hash_entry const *cursor = bucket; - size_t bucket_length = 1; - - while (cursor = cursor->next, cursor) - bucket_length++; - - if (bucket_length > max_bucket_length) - max_bucket_length = bucket_length; - } - } - - return max_bucket_length; -} - -/* Do a mild validation of a hash table, by traversing it and checking two - statistics. */ - -bool -hash_table_ok (const Hash_table *table) -{ - struct hash_entry const *bucket; - size_t n_buckets_used = 0; - size_t n_entries = 0; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - struct hash_entry const *cursor = bucket; - - /* Count bucket head. */ - n_buckets_used++; - n_entries++; - - /* Count bucket overflow. */ - while (cursor = cursor->next, cursor) - n_entries++; - } - } - - if (n_buckets_used == table->n_buckets_used && n_entries == table->n_entries) - return true; - - return false; -} - -void -hash_print_statistics (const Hash_table *table, FILE *stream) -{ - size_t n_entries = hash_get_n_entries (table); - size_t n_buckets = hash_get_n_buckets (table); - size_t n_buckets_used = hash_get_n_buckets_used (table); - size_t max_bucket_length = hash_get_max_bucket_length (table); - - fprintf (stream, "# entries: %lu\n", (unsigned long int) n_entries); - fprintf (stream, "# buckets: %lu\n", (unsigned long int) n_buckets); - fprintf (stream, "# buckets used: %lu (%.2f%%)\n", - (unsigned long int) n_buckets_used, - (100.0 * n_buckets_used) / n_buckets); - fprintf (stream, "max bucket length: %lu\n", - (unsigned long int) max_bucket_length); -} - -/* If ENTRY matches an entry already in the hash table, return the - entry from the table. Otherwise, return NULL. */ - -void * -hash_lookup (const Hash_table *table, const void *entry) -{ - struct hash_entry const *bucket - = table->bucket + table->hasher (entry, table->n_buckets); - struct hash_entry const *cursor; - - if (! (bucket < table->bucket_limit)) - abort (); - - if (bucket->data == NULL) - return NULL; - - for (cursor = bucket; cursor; cursor = cursor->next) - if (table->comparator (entry, cursor->data)) - return cursor->data; - - return NULL; -} - -/* Walking. */ - -/* The functions in this page traverse the hash table and process the - contained entries. For the traversal to work properly, the hash table - should not be resized nor modified while any particular entry is being - processed. In particular, entries should not be added or removed. */ - -/* Return the first data in the table, or NULL if the table is empty. */ - -void * -hash_get_first (const Hash_table *table) -{ - struct hash_entry const *bucket; - - if (table->n_entries == 0) - return NULL; - - for (bucket = table->bucket; ; bucket++) - if (! (bucket < table->bucket_limit)) - abort (); - else if (bucket->data) - return bucket->data; -} - -/* Return the user data for the entry following ENTRY, where ENTRY has been - returned by a previous call to either `hash_get_first' or `hash_get_next'. - Return NULL if there are no more entries. */ - -void * -hash_get_next (const Hash_table *table, const void *entry) -{ - struct hash_entry const *bucket - = table->bucket + table->hasher (entry, table->n_buckets); - struct hash_entry const *cursor; - - if (! (bucket < table->bucket_limit)) - abort (); - - /* Find next entry in the same bucket. */ - for (cursor = bucket; cursor; cursor = cursor->next) - if (cursor->data == entry && cursor->next) - return cursor->next->data; - - /* Find first entry in any subsequent bucket. */ - while (++bucket < table->bucket_limit) - if (bucket->data) - return bucket->data; - - /* None found. */ - return NULL; -} - -/* Fill BUFFER with pointers to active user entries in the hash table, then - return the number of pointers copied. Do not copy more than BUFFER_SIZE - pointers. */ - -size_t -hash_get_entries (const Hash_table *table, void **buffer, - size_t buffer_size) -{ - size_t counter = 0; - struct hash_entry const *bucket; - struct hash_entry const *cursor; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - for (cursor = bucket; cursor; cursor = cursor->next) - { - if (counter >= buffer_size) - return counter; - buffer[counter++] = cursor->data; - } - } - } - - return counter; -} - -/* Call a PROCESSOR function for each entry of a hash table, and return the - number of entries for which the processor function returned success. A - pointer to some PROCESSOR_DATA which will be made available to each call to - the processor function. The PROCESSOR accepts two arguments: the first is - the user entry being walked into, the second is the value of PROCESSOR_DATA - as received. The walking continue for as long as the PROCESSOR function - returns nonzero. When it returns zero, the walking is interrupted. */ - -size_t -hash_do_for_each (const Hash_table *table, Hash_processor processor, - void *processor_data) -{ - size_t counter = 0; - struct hash_entry const *bucket; - struct hash_entry const *cursor; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - for (cursor = bucket; cursor; cursor = cursor->next) - { - if (!(*processor) (cursor->data, processor_data)) - return counter; - counter++; - } - } - } - - return counter; -} - -/* Allocation and clean-up. */ - -/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1. - This is a convenience routine for constructing other hashing functions. */ - -#if USE_DIFF_HASH - -/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see - B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm, - Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash - algorithms tend to be domain-specific, so what's good for [diffutils'] io.c - may not be good for your application." */ - -size_t -hash_string (const char *string, size_t n_buckets) -{ -# define ROTATE_LEFT(Value, Shift) \ - ((Value) << (Shift) | (Value) >> ((sizeof (size_t) * CHAR_BIT) - (Shift))) -# define HASH_ONE_CHAR(Value, Byte) \ - ((Byte) + ROTATE_LEFT (Value, 7)) - - size_t value = 0; - unsigned char ch; - - for (; (ch = *string); string++) - value = HASH_ONE_CHAR (value, ch); - return value % n_buckets; - -# undef ROTATE_LEFT -# undef HASH_ONE_CHAR -} - -#else /* not USE_DIFF_HASH */ - -/* This one comes from `recode', and performs a bit better than the above as - per a few experiments. It is inspired from a hashing routine found in the - very old Cyber `snoop', itself written in typical Greg Mansfield style. - (By the way, what happened to this excellent man? Is he still alive?) */ - -size_t -hash_string (const char *string, size_t n_buckets) -{ - size_t value = 0; - unsigned char ch; - - for (; (ch = *string); string++) - value = (value * 31 + ch) % n_buckets; - return value; -} - -#endif /* not USE_DIFF_HASH */ - -/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd - number at least equal to 11. */ - -static bool -is_prime (size_t candidate) -{ - size_t divisor = 3; - size_t square = divisor * divisor; - - while (square < candidate && (candidate % divisor)) - { - divisor++; - square += 4 * divisor; - divisor++; - } - - return (candidate % divisor ? true : false); -} - -/* Round a given CANDIDATE number up to the nearest prime, and return that - prime. Primes lower than 10 are merely skipped. */ - -static size_t -next_prime (size_t candidate) -{ - /* Skip small primes. */ - if (candidate < 10) - candidate = 10; - - /* Make it definitely odd. */ - candidate |= 1; - - while (!is_prime (candidate)) - candidate += 2; - - return candidate; -} - -void -hash_reset_tuning (Hash_tuning *tuning) -{ - *tuning = default_tuning; -} - -/* For the given hash TABLE, check the user supplied tuning structure for - reasonable values, and return true if there is no gross error with it. - Otherwise, definitively reset the TUNING field to some acceptable default - in the hash table (that is, the user loses the right of further modifying - tuning arguments), and return false. */ - -static bool -check_tuning (Hash_table *table) -{ - const Hash_tuning *tuning = table->tuning; - - /* Be a bit stricter than mathematics would require, so that - rounding errors in size calculations do not cause allocations to - fail to grow or shrink as they should. The smallest allocation - is 11 (due to next_prime's algorithm), so an epsilon of 0.1 - should be good enough. */ - float epsilon = 0.1f; - - if (epsilon < tuning->growth_threshold - && tuning->growth_threshold < 1 - epsilon - && 1 + epsilon < tuning->growth_factor - && 0 <= tuning->shrink_threshold - && tuning->shrink_threshold + epsilon < tuning->shrink_factor - && tuning->shrink_factor <= 1 - && tuning->shrink_threshold + epsilon < tuning->growth_threshold) - return true; - - table->tuning = &default_tuning; - return false; -} - -/* Allocate and return a new hash table, or NULL upon failure. The initial - number of buckets is automatically selected so as to _guarantee_ that you - may insert at least CANDIDATE different user entries before any growth of - the hash table size occurs. So, if have a reasonably tight a-priori upper - bound on the number of entries you intend to insert in the hash table, you - may save some table memory and insertion time, by specifying it here. If - the IS_N_BUCKETS field of the TUNING structure is true, the CANDIDATE - argument has its meaning changed to the wanted number of buckets. - - TUNING points to a structure of user-supplied values, in case some fine - tuning is wanted over the default behavior of the hasher. If TUNING is - NULL, the default tuning parameters are used instead. - - The user-supplied HASHER function should be provided. It accepts two - arguments ENTRY and TABLE_SIZE. It computes, by hashing ENTRY contents, a - slot number for that entry which should be in the range 0..TABLE_SIZE-1. - This slot number is then returned. - - The user-supplied COMPARATOR function should be provided. It accepts two - arguments pointing to user data, it then returns true for a pair of entries - that compare equal, or false otherwise. This function is internally called - on entries which are already known to hash to the same bucket index. - - The user-supplied DATA_FREER function, when not NULL, may be later called - with the user data as an argument, just before the entry containing the - data gets freed. This happens from within `hash_free' or `hash_clear'. - You should specify this function only if you want these functions to free - all of your `data' data. This is typically the case when your data is - simply an auxiliary struct that you have malloc'd to aggregate several - values. */ - -Hash_table * -hash_initialize (size_t candidate, const Hash_tuning *tuning, - Hash_hasher hasher, Hash_comparator comparator, - Hash_data_freer data_freer) -{ - Hash_table *table; - - if (hasher == NULL || comparator == NULL) - return NULL; - - table = malloc (sizeof *table); - if (table == NULL) - return NULL; - - if (!tuning) - tuning = &default_tuning; - table->tuning = tuning; - if (!check_tuning (table)) - { - /* Fail if the tuning options are invalid. This is the only occasion - when the user gets some feedback about it. Once the table is created, - if the user provides invalid tuning options, we silently revert to - using the defaults, and ignore further request to change the tuning - options. */ - goto fail; - } - - if (!tuning->is_n_buckets) - { - float new_candidate = candidate / tuning->growth_threshold; - if (SIZE_MAX <= new_candidate) - goto fail; - candidate = new_candidate; - } - - if (xalloc_oversized (candidate, sizeof *table->bucket)) - goto fail; - table->n_buckets = next_prime (candidate); - if (xalloc_oversized (table->n_buckets, sizeof *table->bucket)) - goto fail; - - table->bucket = calloc (table->n_buckets, sizeof *table->bucket); - table->bucket_limit = table->bucket + table->n_buckets; - table->n_buckets_used = 0; - table->n_entries = 0; - - table->hasher = hasher; - table->comparator = comparator; - table->data_freer = data_freer; - - table->free_entry_list = NULL; -#if USE_OBSTACK - obstack_init (&table->entry_stack); -#endif - return table; - - fail: - free (table); - return NULL; -} - -/* Make all buckets empty, placing any chained entries on the free list. - Apply the user-specified function data_freer (if any) to the datas of any - affected entries. */ - -void -hash_clear (Hash_table *table) -{ - struct hash_entry *bucket; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - struct hash_entry *cursor; - struct hash_entry *next; - - /* Free the bucket overflow. */ - for (cursor = bucket->next; cursor; cursor = next) - { - if (table->data_freer) - (*table->data_freer) (cursor->data); - cursor->data = NULL; - - next = cursor->next; - /* Relinking is done one entry at a time, as it is to be expected - that overflows are either rare or short. */ - cursor->next = table->free_entry_list; - table->free_entry_list = cursor; - } - - /* Free the bucket head. */ - if (table->data_freer) - (*table->data_freer) (bucket->data); - bucket->data = NULL; - bucket->next = NULL; - } - } - - table->n_buckets_used = 0; - table->n_entries = 0; -} - -/* Reclaim all storage associated with a hash table. If a data_freer - function has been supplied by the user when the hash table was created, - this function applies it to the data of each entry before freeing that - entry. */ - -void -hash_free (Hash_table *table) -{ - struct hash_entry *bucket; - struct hash_entry *cursor; - struct hash_entry *next; - - /* Call the user data_freer function. */ - if (table->data_freer && table->n_entries) - { - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - for (cursor = bucket; cursor; cursor = cursor->next) - { - (*table->data_freer) (cursor->data); - } - } - } - } - -#if USE_OBSTACK - - obstack_free (&table->entry_stack, NULL); - -#else - - /* Free all bucket overflowed entries. */ - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - for (cursor = bucket->next; cursor; cursor = next) - { - next = cursor->next; - free (cursor); - } - } - - /* Also reclaim the internal list of previously freed entries. */ - for (cursor = table->free_entry_list; cursor; cursor = next) - { - next = cursor->next; - free (cursor); - } - -#endif - - /* Free the remainder of the hash table structure. */ - free (table->bucket); - free (table); -} - -/* Insertion and deletion. */ - -/* Get a new hash entry for a bucket overflow, possibly by reclying a - previously freed one. If this is not possible, allocate a new one. */ - -static struct hash_entry * -allocate_entry (Hash_table *table) -{ - struct hash_entry *new; - - if (table->free_entry_list) - { - new = table->free_entry_list; - table->free_entry_list = new->next; - } - else - { -#if USE_OBSTACK - new = obstack_alloc (&table->entry_stack, sizeof *new); -#else - new = malloc (sizeof *new); -#endif - } - - return new; -} - -/* Free a hash entry which was part of some bucket overflow, - saving it for later recycling. */ - -static void -free_entry (Hash_table *table, struct hash_entry *entry) -{ - entry->data = NULL; - entry->next = table->free_entry_list; - table->free_entry_list = entry; -} - -/* This private function is used to help with insertion and deletion. When - ENTRY matches an entry in the table, return a pointer to the corresponding - user data and set *BUCKET_HEAD to the head of the selected bucket. - Otherwise, return NULL. When DELETE is true and ENTRY matches an entry in - the table, unlink the matching entry. */ - -static void * -hash_find_entry (Hash_table *table, const void *entry, - struct hash_entry **bucket_head, bool delete) -{ - struct hash_entry *bucket - = table->bucket + table->hasher (entry, table->n_buckets); - struct hash_entry *cursor; - - if (! (bucket < table->bucket_limit)) - abort (); - - *bucket_head = bucket; - - /* Test for empty bucket. */ - if (bucket->data == NULL) - return NULL; - - /* See if the entry is the first in the bucket. */ - if ((*table->comparator) (entry, bucket->data)) - { - void *data = bucket->data; - - if (delete) - { - if (bucket->next) - { - struct hash_entry *next = bucket->next; - - /* Bump the first overflow entry into the bucket head, then save - the previous first overflow entry for later recycling. */ - *bucket = *next; - free_entry (table, next); - } - else - { - bucket->data = NULL; - } - } - - return data; - } - - /* Scan the bucket overflow. */ - for (cursor = bucket; cursor->next; cursor = cursor->next) - { - if ((*table->comparator) (entry, cursor->next->data)) - { - void *data = cursor->next->data; - - if (delete) - { - struct hash_entry *next = cursor->next; - - /* Unlink the entry to delete, then save the freed entry for later - recycling. */ - cursor->next = next->next; - free_entry (table, next); - } - - return data; - } - } - - /* No entry found. */ - return NULL; -} - -/* For an already existing hash table, change the number of buckets through - specifying CANDIDATE. The contents of the hash table are preserved. The - new number of buckets is automatically selected so as to _guarantee_ that - the table may receive at least CANDIDATE different user entries, including - those already in the table, before any other growth of the hash table size - occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the - exact number of buckets desired. */ - -bool -hash_rehash (Hash_table *table, size_t candidate) -{ - Hash_table *new_table; - struct hash_entry *bucket; - struct hash_entry *cursor; - struct hash_entry *next; - - new_table = hash_initialize (candidate, table->tuning, table->hasher, - table->comparator, table->data_freer); - if (new_table == NULL) - return false; - - /* Merely reuse the extra old space into the new table. */ -#if USE_OBSTACK - obstack_free (&new_table->entry_stack, NULL); - new_table->entry_stack = table->entry_stack; -#endif - new_table->free_entry_list = table->free_entry_list; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - if (bucket->data) - for (cursor = bucket; cursor; cursor = next) - { - void *data = cursor->data; - struct hash_entry *new_bucket - = (new_table->bucket - + new_table->hasher (data, new_table->n_buckets)); - - if (! (new_bucket < new_table->bucket_limit)) - abort (); - - next = cursor->next; - - if (new_bucket->data) - { - if (cursor == bucket) - { - /* Allocate or recycle an entry, when moving from a bucket - header into a bucket overflow. */ - struct hash_entry *new_entry = allocate_entry (new_table); - - if (new_entry == NULL) - return false; - - new_entry->data = data; - new_entry->next = new_bucket->next; - new_bucket->next = new_entry; - } - else - { - /* Merely relink an existing entry, when moving from a - bucket overflow into a bucket overflow. */ - cursor->next = new_bucket->next; - new_bucket->next = cursor; - } - } - else - { - /* Free an existing entry, when moving from a bucket - overflow into a bucket header. Also take care of the - simple case of moving from a bucket header into a bucket - header. */ - new_bucket->data = data; - new_table->n_buckets_used++; - if (cursor != bucket) - free_entry (new_table, cursor); - } - } - - free (table->bucket); - table->bucket = new_table->bucket; - table->bucket_limit = new_table->bucket_limit; - table->n_buckets = new_table->n_buckets; - table->n_buckets_used = new_table->n_buckets_used; - table->free_entry_list = new_table->free_entry_list; - /* table->n_entries already holds its value. */ -#if USE_OBSTACK - table->entry_stack = new_table->entry_stack; -#endif - free (new_table); - - return true; -} - -/* If ENTRY matches an entry already in the hash table, return the pointer - to the entry from the table. Otherwise, insert ENTRY and return ENTRY. - Return NULL if the storage required for insertion cannot be allocated. */ - -void * -hash_insert (Hash_table *table, const void *entry) -{ - void *data; - struct hash_entry *bucket; - - /* The caller cannot insert a NULL entry. */ - if (! entry) - abort (); - - /* If there's a matching entry already in the table, return that. */ - if ((data = hash_find_entry (table, entry, &bucket, false)) != NULL) - return data; - - /* ENTRY is not matched, it should be inserted. */ - - if (bucket->data) - { - struct hash_entry *new_entry = allocate_entry (table); - - if (new_entry == NULL) - return NULL; - - /* Add ENTRY in the overflow of the bucket. */ - - new_entry->data = (void *) entry; - new_entry->next = bucket->next; - bucket->next = new_entry; - table->n_entries++; - return (void *) entry; - } - - /* Add ENTRY right in the bucket head. */ - - bucket->data = (void *) entry; - table->n_entries++; - table->n_buckets_used++; - - /* If the growth threshold of the buckets in use has been reached, increase - the table size and rehash. There's no point in checking the number of - entries: if the hashing function is ill-conditioned, rehashing is not - likely to improve it. */ - - if (table->n_buckets_used - > table->tuning->growth_threshold * table->n_buckets) - { - /* Check more fully, before starting real work. If tuning arguments - became invalid, the second check will rely on proper defaults. */ - check_tuning (table); - if (table->n_buckets_used - > table->tuning->growth_threshold * table->n_buckets) - { - const Hash_tuning *tuning = table->tuning; - float candidate = - (tuning->is_n_buckets - ? (table->n_buckets * tuning->growth_factor) - : (table->n_buckets * tuning->growth_factor - * tuning->growth_threshold)); - - if (SIZE_MAX <= candidate) - return NULL; - - /* If the rehash fails, arrange to return NULL. */ - if (!hash_rehash (table, candidate)) - entry = NULL; - } - } - - return (void *) entry; -} - -/* If ENTRY is already in the table, remove it and return the just-deleted - data (the user may want to deallocate its storage). If ENTRY is not in the - table, don't modify the table and return NULL. */ - -void * -hash_delete (Hash_table *table, const void *entry) -{ - void *data; - struct hash_entry *bucket; - - data = hash_find_entry (table, entry, &bucket, true); - if (!data) - return NULL; - - table->n_entries--; - if (!bucket->data) - { - table->n_buckets_used--; - - /* If the shrink threshold of the buckets in use has been reached, - rehash into a smaller table. */ - - if (table->n_buckets_used - < table->tuning->shrink_threshold * table->n_buckets) - { - /* Check more fully, before starting real work. If tuning arguments - became invalid, the second check will rely on proper defaults. */ - check_tuning (table); - if (table->n_buckets_used - < table->tuning->shrink_threshold * table->n_buckets) - { - const Hash_tuning *tuning = table->tuning; - size_t candidate = - (tuning->is_n_buckets - ? table->n_buckets * tuning->shrink_factor - : (table->n_buckets * tuning->shrink_factor - * tuning->growth_threshold)); - - hash_rehash (table, candidate); - } - } - } - - return data; -} - -/* Testing. */ - -#if TESTING - -void -hash_print (const Hash_table *table) -{ - struct hash_entry const *bucket; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - struct hash_entry *cursor; - - if (bucket) - printf ("%lu:\n", (unsigned long int) (bucket - table->bucket)); - - for (cursor = bucket; cursor; cursor = cursor->next) - { - char const *s = cursor->data; - /* FIXME */ - if (s) - printf (" %s\n", s); - } - } -} - -#endif /* TESTING */ diff --git a/contrib/cpio/lib/hash.h b/contrib/cpio/lib/hash.h deleted file mode 100644 index ab63a863fd0..00000000000 --- a/contrib/cpio/lib/hash.h +++ /dev/null @@ -1,88 +0,0 @@ -/* hash - hashing table processing. - Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation, Inc. - Written by Jim Meyering , 1998. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* A generic hash table package. */ - -/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use - obstacks instead of malloc, and recompile `hash.c' with same setting. */ - -#ifndef HASH_H_ -# define HASH_H_ - -# include -# include - -typedef size_t (*Hash_hasher) (const void *, size_t); -typedef bool (*Hash_comparator) (const void *, const void *); -typedef void (*Hash_data_freer) (void *); -typedef bool (*Hash_processor) (void *, void *); - -struct hash_entry - { - void *data; - struct hash_entry *next; - }; - -struct hash_tuning - { - /* This structure is mainly used for `hash_initialize', see the block - documentation of `hash_reset_tuning' for more complete comments. */ - - float shrink_threshold; /* ratio of used buckets to trigger a shrink */ - float shrink_factor; /* ratio of new smaller size to original size */ - float growth_threshold; /* ratio of used buckets to trigger a growth */ - float growth_factor; /* ratio of new bigger size to original size */ - bool is_n_buckets; /* if CANDIDATE really means table size */ - }; - -typedef struct hash_tuning Hash_tuning; - -struct hash_table; - -typedef struct hash_table Hash_table; - -/* Information and lookup. */ -size_t hash_get_n_buckets (const Hash_table *); -size_t hash_get_n_buckets_used (const Hash_table *); -size_t hash_get_n_entries (const Hash_table *); -size_t hash_get_max_bucket_length (const Hash_table *); -bool hash_table_ok (const Hash_table *); -void hash_print_statistics (const Hash_table *, FILE *); -void *hash_lookup (const Hash_table *, const void *); - -/* Walking. */ -void *hash_get_first (const Hash_table *); -void *hash_get_next (const Hash_table *, const void *); -size_t hash_get_entries (const Hash_table *, void **, size_t); -size_t hash_do_for_each (const Hash_table *, Hash_processor, void *); - -/* Allocation and clean-up. */ -size_t hash_string (const char *, size_t); -void hash_reset_tuning (Hash_tuning *); -Hash_table *hash_initialize (size_t, const Hash_tuning *, - Hash_hasher, Hash_comparator, - Hash_data_freer); -void hash_clear (Hash_table *); -void hash_free (Hash_table *); - -/* Insertion and deletion. */ -bool hash_rehash (Hash_table *, size_t); -void *hash_insert (Hash_table *, const void *); -void *hash_delete (Hash_table *, const void *); - -#endif diff --git a/contrib/cpio/lib/intprops.h b/contrib/cpio/lib/intprops.h deleted file mode 100644 index 34f971cbaad..00000000000 --- a/contrib/cpio/lib/intprops.h +++ /dev/null @@ -1,78 +0,0 @@ -/* intprops.h -- properties of integer types - - Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -/* The extra casts in the following macros work around compiler bugs, - e.g., in Cray C 5.0.3.0. */ - -/* True if the arithmetic type T is an integer type. bool counts as - an integer. */ -#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) - -/* True if negative values of the signed integer type T use two's - complement, ones' complement, or signed magnitude representation, - respectively. Much GNU code assumes two's complement, but some - people like to be portable to all possible C hosts. */ -#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) -#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) -#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) - -/* True if the arithmetic type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - -/* The maximum and minimum values for the integer type T. These - macros have undefined behavior if T is signed and has padding bits. - If this is a problem for you, please let us know how to fix it for - your host. */ -#define TYPE_MINIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) 0 \ - : TYPE_SIGNED_MAGNITUDE (t) \ - ? ~ (t) 0 \ - : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) -#define TYPE_MAXIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) -1 \ - : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) - -/* Return zero if T can be determined to be an unsigned type. - Otherwise, return 1. - When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a - tighter bound. Otherwise, it overestimates the true bound by one byte - when applied to unsigned types of size 2, 4, 16, ... bytes. - The symbol signed_type_or_expr__ is private to this header file. */ -#if __GNUC__ >= 2 -# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t)) -#else -# define signed_type_or_expr__(t) 1 -#endif - -/* Bound on length of the string representing an integer type or expression T. - Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485; - add 1 for integer division truncation; add 1 more for a minus sign - if needed. */ -#define INT_STRLEN_BOUND(t) \ - ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \ - + signed_type_or_expr__ (t) + 1) - -/* Bound on buffer size needed to represent an integer type or expression T, - including the terminating null. */ -#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) diff --git a/contrib/cpio/lib/inttostr.c b/contrib/cpio/lib/inttostr.c deleted file mode 100644 index 246d6583507..00000000000 --- a/contrib/cpio/lib/inttostr.c +++ /dev/null @@ -1,51 +0,0 @@ -/* inttostr.c -- convert integers to printable strings - - Copyright (C) 2001, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#include - -#include "inttostr.h" - -/* Convert I to a printable string in BUF, which must be at least - INT_BUFSIZE_BOUND (INTTYPE) bytes long. Return the address of the - printable string, which need not start at BUF. */ - -char * -inttostr (inttype i, char *buf) -{ - char *p = buf + INT_STRLEN_BOUND (inttype); - *p = 0; - - if (i < 0) - { - do - *--p = '0' - i % 10; - while ((i /= 10) != 0); - - *--p = '-'; - } - else - { - do - *--p = '0' + i % 10; - while ((i /= 10) != 0); - } - - return p; -} diff --git a/contrib/cpio/lib/inttostr.h b/contrib/cpio/lib/inttostr.h deleted file mode 100644 index 31258cad35b..00000000000 --- a/contrib/cpio/lib/inttostr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* inttostr.h -- convert integers to printable strings - - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#include -#include - -#include "intprops.h" - -char *offtostr (off_t, char *); -char *imaxtostr (intmax_t, char *); -char *umaxtostr (uintmax_t, char *); -char *uinttostr (unsigned int, char *); diff --git a/contrib/cpio/lib/mempcpy.c b/contrib/cpio/lib/mempcpy.c deleted file mode 100644 index 1c702c7f4cb..00000000000 --- a/contrib/cpio/lib/mempcpy.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Copy memory area and return pointer after last written byte. - Copyright (C) 2003, 2007 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -/* Copy N bytes of SRC to DEST, return pointer to bytes after the - last written byte. */ -void * -mempcpy (void *dest, const void *src, size_t n) -{ - return (char *) memcpy (dest, src, n) + n; -} diff --git a/contrib/cpio/lib/paxerror.c b/contrib/cpio/lib/paxerror.c deleted file mode 100644 index 000d9e44981..00000000000 --- a/contrib/cpio/lib/paxerror.c +++ /dev/null @@ -1,365 +0,0 @@ -/* Miscellaneous error functions - - Copyright (C) 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include -#include - -/* Decode MODE from its binary form in a stat structure, and encode it - into a 9-byte string STRING, terminated with a NUL. */ - -void -pax_decode_mode (mode_t mode, char *string) -{ - *string++ = mode & S_IRUSR ? 'r' : '-'; - *string++ = mode & S_IWUSR ? 'w' : '-'; - *string++ = (mode & S_ISUID - ? (mode & S_IXUSR ? 's' : 'S') - : (mode & S_IXUSR ? 'x' : '-')); - *string++ = mode & S_IRGRP ? 'r' : '-'; - *string++ = mode & S_IWGRP ? 'w' : '-'; - *string++ = (mode & S_ISGID - ? (mode & S_IXGRP ? 's' : 'S') - : (mode & S_IXGRP ? 'x' : '-')); - *string++ = mode & S_IROTH ? 'r' : '-'; - *string++ = mode & S_IWOTH ? 'w' : '-'; - *string++ = (mode & S_ISVTX - ? (mode & S_IXOTH ? 't' : 'T') - : (mode & S_IXOTH ? 'x' : '-')); - *string = '\0'; -} - -/* Report an error associated with the system call CALL and the - optional name NAME. */ -void -call_arg_error (char const *call, char const *name) -{ - int e = errno; - /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'. - Directly translating this to another language will not work, first because - %s itself is not translated. - Translate it as `%s: Function %s failed'. */ - ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call)); -} - -/* Report a fatal error associated with the system call CALL and - the optional file name NAME. */ -void -call_arg_fatal (char const *call, char const *name) -{ - int e = errno; - /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'. - Directly translating this to another language will not work, first because - %s itself is not translated. - Translate it as `%s: Function %s failed'. */ - FATAL_ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call)); -} - -/* Report a warning associated with the system call CALL and - the optional file name NAME. */ -void -call_arg_warn (char const *call, char const *name) -{ - int e = errno; - /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'. - Directly translating this to another language will not work, first because - %s itself is not translated. - Translate it as `%s: Function %s failed'. */ - WARN ((0, e, _("%s: Warning: Cannot %s"), quotearg_colon (name), call)); -} - -void -chmod_error_details (char const *name, mode_t mode) -{ - int e = errno; - char buf[10]; - pax_decode_mode (mode, buf); - ERROR ((0, e, _("%s: Cannot change mode to %s"), - quotearg_colon (name), buf)); -} - -void -chown_error_details (char const *name, uid_t uid, gid_t gid) -{ - int e = errno; - ERROR ((0, e, _("%s: Cannot change ownership to uid %lu, gid %lu"), - quotearg_colon (name), (unsigned long) uid, (unsigned long) gid)); -} - -void -close_error (char const *name) -{ - call_arg_error ("close", name); -} - -void -close_warn (char const *name) -{ - call_arg_warn ("close", name); -} - -void -exec_fatal (char const *name) -{ - call_arg_fatal ("exec", name); -} - -void -link_error (char const *target, char const *source) -{ - int e = errno; - ERROR ((0, e, _("%s: Cannot hard link to %s"), - quotearg_colon (source), quote_n (1, target))); -} - -void -mkdir_error (char const *name) -{ - call_arg_error ("mkdir", name); -} - -void -mkfifo_error (char const *name) -{ - call_arg_error ("mkfifo", name); -} - -void -mknod_error (char const *name) -{ - call_arg_error ("mknod", name); -} - -void -open_error (char const *name) -{ - call_arg_error ("open", name); -} - -void -open_fatal (char const *name) -{ - call_arg_fatal ("open", name); -} - -void -open_warn (char const *name) -{ - call_arg_warn ("open", name); -} - -void -read_error (char const *name) -{ - call_arg_error ("read", name); -} - -void -read_error_details (char const *name, off_t offset, size_t size) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - ERROR ((0, e, - ngettext ("%s: Read error at byte %s, while reading %lu byte", - "%s: Read error at byte %s, while reading %lu bytes", - size), - quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), - (unsigned long) size)); -} - -void -read_warn_details (char const *name, off_t offset, size_t size) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - WARN ((0, e, - ngettext ("%s: Warning: Read error at byte %s, while reading %lu byte", - "%s: Warning: Read error at byte %s, while reading %lu bytes", - size), - quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), - (unsigned long) size)); -} - -void -read_fatal (char const *name) -{ - call_arg_fatal ("read", name); -} - -void -read_fatal_details (char const *name, off_t offset, size_t size) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - FATAL_ERROR ((0, e, - ngettext ("%s: Read error at byte %s, while reading %lu byte", - "%s: Read error at byte %s, while reading %lu bytes", - size), - quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), - (unsigned long) size)); -} - -void -readlink_error (char const *name) -{ - call_arg_error ("readlink", name); -} - -void -readlink_warn (char const *name) -{ - call_arg_warn ("readlink", name); -} - -void -rmdir_error (char const *name) -{ - call_arg_error ("rmdir", name); -} - -void -savedir_error (char const *name) -{ - call_arg_error ("savedir", name); -} - -void -savedir_warn (char const *name) -{ - call_arg_warn ("savedir", name); -} - -void -seek_error (char const *name) -{ - call_arg_error ("seek", name); -} - -void -seek_error_details (char const *name, off_t offset) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - ERROR ((0, e, _("%s: Cannot seek to %s"), - quotearg_colon (name), - STRINGIFY_BIGINT (offset, buf))); -} - -void -seek_warn (char const *name) -{ - call_arg_warn ("seek", name); -} - -void -seek_warn_details (char const *name, off_t offset) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - WARN ((0, e, _("%s: Warning: Cannot seek to %s"), - quotearg_colon (name), - STRINGIFY_BIGINT (offset, buf))); -} - -void -symlink_error (char const *contents, char const *name) -{ - int e = errno; - ERROR ((0, e, _("%s: Cannot create symlink to %s"), - quotearg_colon (name), quote_n (1, contents))); -} - -void -stat_fatal (char const *name) -{ - call_arg_fatal ("stat", name); -} - -void -stat_error (char const *name) -{ - call_arg_error ("stat", name); -} - -void -stat_warn (char const *name) -{ - call_arg_warn ("stat", name); -} - -void -truncate_error (char const *name) -{ - call_arg_error ("truncate", name); -} - -void -truncate_warn (char const *name) -{ - call_arg_warn ("truncate", name); -} - -void -unlink_error (char const *name) -{ - call_arg_error ("unlink", name); -} - -void -utime_error (char const *name) -{ - call_arg_error ("utime", name); -} - -void -waitpid_error (char const *name) -{ - call_arg_error ("waitpid", name); -} - -void -write_error (char const *name) -{ - call_arg_error ("write", name); -} - -void -write_error_details (char const *name, size_t status, size_t size) -{ - if (status == 0) - write_error (name); - else - ERROR ((0, 0, - ngettext ("%s: Wrote only %lu of %lu byte", - "%s: Wrote only %lu of %lu bytes", - size), - name, (unsigned long int) status, (unsigned long int) size)); -} - -void -write_fatal (char const *name) -{ - call_arg_fatal ("write", name); -} - -void -chdir_fatal (char const *name) -{ - call_arg_fatal ("chdir", name); -} diff --git a/contrib/cpio/lib/paxexit.c b/contrib/cpio/lib/paxexit.c deleted file mode 100644 index a511f79cf17..00000000000 --- a/contrib/cpio/lib/paxexit.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Miscellaneous error functions - - Copyright (C) 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include - -int exit_status = PAXEXIT_SUCCESS; - -void -pax_exit () -{ - exit (exit_status); -} diff --git a/contrib/cpio/lib/paxlib.h b/contrib/cpio/lib/paxlib.h deleted file mode 100644 index 381c4c70299..00000000000 --- a/contrib/cpio/lib/paxlib.h +++ /dev/null @@ -1,115 +0,0 @@ -/* This file is part of GNU paxutils - - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, - 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef _paxlib_h_ -#define _paxlib_h_ - -#include -#include - -/* Error reporting functions and definitions */ - -/* Exit status for paxutils app. Let's try to keep this list as simple as - possible. tar -d option strongly invites a status different for unequal - comparison and other errors. */ -#define PAXEXIT_SUCCESS 0 -#define PAXEXIT_DIFFERS 1 -#define PAXEXIT_FAILURE 2 - -/* Both WARN and ERROR write a message on stderr and continue processing, - however ERROR manages so tar will exit unsuccessfully. FATAL_ERROR - writes a message on stderr and aborts immediately, with another message - line telling so. USAGE_ERROR works like FATAL_ERROR except that the - other message line suggests trying --help. All four macros accept a - single argument of the form ((0, errno, _("FORMAT"), Args...)). errno - is zero when the error is not being detected by the system. */ - -#define WARN(Args) \ - error Args -#define ERROR(Args) \ - (error Args, exit_status = PAXEXIT_FAILURE) -#define FATAL_ERROR(Args) \ - (error Args, fatal_exit ()) -#define USAGE_ERROR(Args) \ - (error Args, usage (PAXEXIT_FAILURE)) - -extern int exit_status; - -void pax_decode_mode (mode_t mode, char *string); -void call_arg_error (char const *call, char const *name); -void call_arg_fatal (char const *call, char const *name) __attribute__ ((noreturn)); -void call_arg_warn (char const *call, char const *name); -void chmod_error_details (char const *name, mode_t mode); -void chown_error_details (char const *name, uid_t uid, gid_t gid); - -void decode_mode (mode_t, char *); - -void chdir_fatal (char const *) __attribute__ ((noreturn)); -void chmod_error_details (char const *, mode_t); -void chown_error_details (char const *, uid_t, gid_t); -void close_error (char const *); -void close_warn (char const *); -void exec_fatal (char const *) __attribute__ ((noreturn)); -void link_error (char const *, char const *); -void mkdir_error (char const *); -void mkfifo_error (char const *); -void mknod_error (char const *); -void open_error (char const *); -void open_fatal (char const *) __attribute__ ((noreturn)); -void open_warn (char const *); -void read_error (char const *); -void read_error_details (char const *, off_t, size_t); -void read_fatal (char const *) __attribute__ ((noreturn)); -void read_fatal_details (char const *, off_t, size_t) __attribute__ ((noreturn)); -void read_warn_details (char const *, off_t, size_t); -void readlink_error (char const *); -void readlink_warn (char const *); -void rmdir_error (char const *); -void savedir_error (char const *); -void savedir_warn (char const *); -void seek_error (char const *); -void seek_error_details (char const *, off_t); -void seek_warn (char const *); -void seek_warn_details (char const *, off_t); -void stat_fatal (char const *); -void stat_error (char const *); -void stat_warn (char const *); -void symlink_error (char const *, char const *); -void truncate_error (char const *); -void truncate_warn (char const *); -void unlink_error (char const *); -void utime_error (char const *); -void waitpid_error (char const *); -void write_error (char const *); - -void pax_exit (void); -void fatal_exit (void) __attribute__ ((noreturn)); - -#define STRINGIFY_BIGINT(i, b) umaxtostr (i, b) - - -/* Name-related functions */ -bool hash_string_insert (Hash_table **table, char const *string); -bool hash_string_lookup (Hash_table const *table, char const *string); - -bool removed_prefixes_p (void); -char *safer_name_suffix (char const *file_name, bool link_target, bool absolute_names); - -#endif diff --git a/contrib/cpio/lib/paxnames.c b/contrib/cpio/lib/paxnames.c deleted file mode 100644 index 3ca8bfaa7f9..00000000000 --- a/contrib/cpio/lib/paxnames.c +++ /dev/null @@ -1,156 +0,0 @@ -/* This file is part of GNU paxutils - Copyright (C) 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include - - -/* Hash tables of strings. */ - -/* Calculate the hash of a string. */ -static size_t -hash_string_hasher (void const *name, size_t n_buckets) -{ - return hash_string (name, n_buckets); -} - -/* Compare two strings for equality. */ -static bool -hash_string_compare (void const *name1, void const *name2) -{ - return strcmp (name1, name2) == 0; -} - -/* Return zero if TABLE contains a copy of STRING; otherwise, insert a - copy of STRING to TABLE and return 1. */ -bool -hash_string_insert (Hash_table **table, char const *string) -{ - Hash_table *t = *table; - char *s = xstrdup (string); - char *e; - - if (! ((t - || (*table = t = hash_initialize (0, 0, hash_string_hasher, - hash_string_compare, 0))) - && (e = hash_insert (t, s)))) - xalloc_die (); - - if (e == s) - return 1; - else - { - free (s); - return 0; - } -} - -/* Return 1 if TABLE contains STRING. */ -bool -hash_string_lookup (Hash_table const *table, char const *string) -{ - return table && hash_lookup (table, string); -} - - -static Hash_table *prefix_table[2]; - -/* Return true if file names of some members in the archive were stripped off - their leading components. We could have used - return prefix_table[0] || prefix_table[1] - but the following seems to be safer: */ -bool -removed_prefixes_p (void) -{ - return (prefix_table[0] && hash_get_n_entries (prefix_table[0]) != 0) - || (prefix_table[1] && hash_get_n_entries (prefix_table[1]) != 0); -} - -/* Return a safer suffix of FILE_NAME, or "." if it has no safer - suffix. Check for fully specified file names and other atrocities. - Warn the user if we do not return NAME. If LINK_TARGET is 1, - FILE_NAME is the target of a hard link, not a member name. - If ABSOLUTE_NAMES is 0, strip filesystem prefix from the file name. */ - -char * -safer_name_suffix (char const *file_name, bool link_target, bool absolute_names) -{ - char const *p; - - if (absolute_names) - p = file_name; - else - { - /* Skip file system prefixes, leading file name components that contain - "..", and leading slashes. */ - - size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name); - - for (p = file_name + prefix_len; *p; ) - { - if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2])) - prefix_len = p + 2 - file_name; - - do - { - char c = *p++; - if (ISSLASH (c)) - break; - } - while (*p); - } - - for (p = file_name + prefix_len; ISSLASH (*p); p++) - continue; - prefix_len = p - file_name; - - if (prefix_len) - { - char *prefix = alloca (prefix_len + 1); - memcpy (prefix, file_name, prefix_len); - prefix[prefix_len] = '\0'; - - if (hash_string_insert (&prefix_table[link_target], prefix)) - { - static char const *const diagnostic[] = - { - N_("Removing leading `%s' from member names"), - N_("Removing leading `%s' from hard link targets") - }; - WARN ((0, 0, _(diagnostic[link_target]), prefix)); - } - } - } - - if (! *p) - { - if (p == file_name) - { - static char const *const diagnostic[] = - { - N_("Substituting `.' for empty member name"), - N_("Substituting `.' for empty hard link target") - }; - WARN ((0, 0, "%s", _(diagnostic[link_target]))); - } - - p = "."; - } - - return (char *) p; -} diff --git a/contrib/cpio/lib/quote.c b/contrib/cpio/lib/quote.c deleted file mode 100644 index 119be72ae0a..00000000000 --- a/contrib/cpio/lib/quote.c +++ /dev/null @@ -1,41 +0,0 @@ -/* quote.c - quote arguments for output - - Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 Free - Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#include - -#include "quotearg.h" -#include "quote.h" - -/* Return an unambiguous printable representation of NAME, - allocated in slot N, suitable for diagnostics. */ -char const * -quote_n (int n, char const *name) -{ - return quotearg_n_style (n, locale_quoting_style, name); -} - -/* Return an unambiguous printable representation of NAME, - suitable for diagnostics. */ -char const * -quote (char const *name) -{ - return quote_n (0, name); -} diff --git a/contrib/cpio/lib/quote.h b/contrib/cpio/lib/quote.h deleted file mode 100644 index 5400eadb657..00000000000 --- a/contrib/cpio/lib/quote.h +++ /dev/null @@ -1,22 +0,0 @@ -/* quote.h - prototypes for quote.c - - Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - - -char const *quote_n (int n, char const *name); -char const *quote (char const *name); diff --git a/contrib/cpio/lib/quotearg.c b/contrib/cpio/lib/quotearg.c deleted file mode 100644 index f7f326ac501..00000000000 --- a/contrib/cpio/lib/quotearg.c +++ /dev/null @@ -1,697 +0,0 @@ -/* quotearg.c - quote arguments for output - - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 Free - Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#include - -#include "quotearg.h" - -#include "xalloc.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gettext.h" -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - -#if !HAVE_MBRTOWC -/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the - other macros are defined only for documentation and to satisfy C - syntax. */ -# undef MB_CUR_MAX -# define MB_CUR_MAX 1 -# undef mbstate_t -# define mbstate_t int -# define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0) -# define iswprint(wc) isprint ((unsigned char) (wc)) -# undef HAVE_MBSINIT -#endif - -#if !defined mbsinit && !HAVE_MBSINIT -# define mbsinit(ps) 1 -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -#define INT_BITS (sizeof (int) * CHAR_BIT) - -struct quoting_options -{ - /* Basic quoting style. */ - enum quoting_style style; - - /* Quote the characters indicated by this bit vector even if the - quoting style would not normally require them to be quoted. */ - unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1]; -}; - -/* Names of quoting styles. */ -char const *const quoting_style_args[] = -{ - "literal", - "shell", - "shell-always", - "c", - "escape", - "locale", - "clocale", - 0 -}; - -/* Correspondences to quoting style names. */ -enum quoting_style const quoting_style_vals[] = -{ - literal_quoting_style, - shell_quoting_style, - shell_always_quoting_style, - c_quoting_style, - escape_quoting_style, - locale_quoting_style, - clocale_quoting_style -}; - -/* The default quoting options. */ -static struct quoting_options default_quoting_options; - -/* Allocate a new set of quoting options, with contents initially identical - to O if O is not null, or to the default if O is null. - It is the caller's responsibility to free the result. */ -struct quoting_options * -clone_quoting_options (struct quoting_options *o) -{ - int e = errno; - struct quoting_options *p = xmemdup (o ? o : &default_quoting_options, - sizeof *o); - errno = e; - return p; -} - -/* Get the value of O's quoting style. If O is null, use the default. */ -enum quoting_style -get_quoting_style (struct quoting_options *o) -{ - return (o ? o : &default_quoting_options)->style; -} - -/* In O (or in the default if O is null), - set the value of the quoting style to S. */ -void -set_quoting_style (struct quoting_options *o, enum quoting_style s) -{ - (o ? o : &default_quoting_options)->style = s; -} - -/* In O (or in the default if O is null), - set the value of the quoting options for character C to I. - Return the old value. Currently, the only values defined for I are - 0 (the default) and 1 (which means to quote the character even if - it would not otherwise be quoted). */ -int -set_char_quoting (struct quoting_options *o, char c, int i) -{ - unsigned char uc = c; - unsigned int *p = - (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; - int shift = uc % INT_BITS; - int r = (*p >> shift) & 1; - *p ^= ((i & 1) ^ r) << shift; - return r; -} - -/* MSGID approximates a quotation mark. Return its translation if it - has one; otherwise, return either it or "\"", depending on S. */ -static char const * -gettext_quote (char const *msgid, enum quoting_style s) -{ - char const *translation = _(msgid); - if (translation == msgid && s == clocale_quoting_style) - translation = "\""; - return translation; -} - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using QUOTING_STYLE and the - non-quoting-style part of O to control quoting. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE. - - This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG, - ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting - style specified by O, and O may not be null. */ - -static size_t -quotearg_buffer_restyled (char *buffer, size_t buffersize, - char const *arg, size_t argsize, - enum quoting_style quoting_style, - struct quoting_options const *o) -{ - size_t i; - size_t len = 0; - char const *quote_string = 0; - size_t quote_string_len = 0; - bool backslash_escapes = false; - bool unibyte_locale = MB_CUR_MAX == 1; - -#define STORE(c) \ - do \ - { \ - if (len < buffersize) \ - buffer[len] = (c); \ - len++; \ - } \ - while (0) - - switch (quoting_style) - { - case c_quoting_style: - STORE ('"'); - backslash_escapes = true; - quote_string = "\""; - quote_string_len = 1; - break; - - case escape_quoting_style: - backslash_escapes = true; - break; - - case locale_quoting_style: - case clocale_quoting_style: - { - /* TRANSLATORS: - Get translations for open and closing quotation marks. - - The message catalog should translate "`" to a left - quotation mark suitable for the locale, and similarly for - "'". If the catalog has no translation, - locale_quoting_style quotes `like this', and - clocale_quoting_style quotes "like this". - - For example, an American English Unicode locale should - translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and - should translate "'" to U+201D (RIGHT DOUBLE QUOTATION - MARK). A British English Unicode locale should instead - translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and - U+2019 (RIGHT SINGLE QUOTATION MARK), respectively. - - If you don't know what to put here, please see - - and use glyphs suitable for your language. */ - - char const *left = gettext_quote (N_("`"), quoting_style); - char const *right = gettext_quote (N_("'"), quoting_style); - for (quote_string = left; *quote_string; quote_string++) - STORE (*quote_string); - backslash_escapes = true; - quote_string = right; - quote_string_len = strlen (quote_string); - } - break; - - case shell_always_quoting_style: - STORE ('\''); - quote_string = "'"; - quote_string_len = 1; - break; - - default: - break; - } - - for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++) - { - unsigned char c; - unsigned char esc; - - if (backslash_escapes - && quote_string_len - && i + quote_string_len <= argsize - && memcmp (arg + i, quote_string, quote_string_len) == 0) - STORE ('\\'); - - c = arg[i]; - switch (c) - { - case '\0': - if (backslash_escapes) - { - STORE ('\\'); - STORE ('0'); - STORE ('0'); - c = '0'; - } - break; - - case '?': - switch (quoting_style) - { - case shell_quoting_style: - goto use_shell_always_quoting_style; - - case c_quoting_style: - if (i + 2 < argsize && arg[i + 1] == '?') - switch (arg[i + 2]) - { - case '!': case '\'': - case '(': case ')': case '-': case '/': - case '<': case '=': case '>': - /* Escape the second '?' in what would otherwise be - a trigraph. */ - c = arg[i + 2]; - i += 2; - STORE ('?'); - STORE ('\\'); - STORE ('?'); - break; - - default: - break; - } - break; - - default: - break; - } - break; - - case '\a': esc = 'a'; goto c_escape; - case '\b': esc = 'b'; goto c_escape; - case '\f': esc = 'f'; goto c_escape; - case '\n': esc = 'n'; goto c_and_shell_escape; - case '\r': esc = 'r'; goto c_and_shell_escape; - case '\t': esc = 't'; goto c_and_shell_escape; - case '\v': esc = 'v'; goto c_escape; - case '\\': esc = c; goto c_and_shell_escape; - - c_and_shell_escape: - if (quoting_style == shell_quoting_style) - goto use_shell_always_quoting_style; - c_escape: - if (backslash_escapes) - { - c = esc; - goto store_escape; - } - break; - - case '{': case '}': /* sometimes special if isolated */ - if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1)) - break; - /* Fall through. */ - case '#': case '~': - if (i != 0) - break; - /* Fall through. */ - case ' ': - case '!': /* special in bash */ - case '"': case '$': case '&': - case '(': case ')': case '*': case ';': - case '<': - case '=': /* sometimes special in 0th or (with "set -k") later args */ - case '>': case '[': - case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */ - case '`': case '|': - /* A shell special character. In theory, '$' and '`' could - be the first bytes of multibyte characters, which means - we should check them with mbrtowc, but in practice this - doesn't happen so it's not worth worrying about. */ - if (quoting_style == shell_quoting_style) - goto use_shell_always_quoting_style; - break; - - case '\'': - switch (quoting_style) - { - case shell_quoting_style: - goto use_shell_always_quoting_style; - - case shell_always_quoting_style: - STORE ('\''); - STORE ('\\'); - STORE ('\''); - break; - - default: - break; - } - break; - - case '%': case '+': case ',': case '-': case '.': case '/': - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case ':': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': case ']': case '_': case 'a': case 'b': - case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': - case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': - case 'o': case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': - /* These characters don't cause problems, no matter what the - quoting style is. They cannot start multibyte sequences. */ - break; - - default: - /* If we have a multibyte sequence, copy it until we reach - its end, find an error, or come back to the initial shift - state. For C-like styles, if the sequence has - unprintable characters, escape the whole sequence, since - we can't easily escape single characters within it. */ - { - /* Length of multibyte sequence found so far. */ - size_t m; - - bool printable; - - if (unibyte_locale) - { - m = 1; - printable = isprint (c) != 0; - } - else - { - mbstate_t mbstate; - memset (&mbstate, 0, sizeof mbstate); - - m = 0; - printable = true; - if (argsize == SIZE_MAX) - argsize = strlen (arg); - - do - { - wchar_t w; - size_t bytes = mbrtowc (&w, &arg[i + m], - argsize - (i + m), &mbstate); - if (bytes == 0) - break; - else if (bytes == (size_t) -1) - { - printable = false; - break; - } - else if (bytes == (size_t) -2) - { - printable = false; - while (i + m < argsize && arg[i + m]) - m++; - break; - } - else - { - /* Work around a bug with older shells that "see" a '\' - that is really the 2nd byte of a multibyte character. - In practice the problem is limited to ASCII - chars >= '@' that are shell special chars. */ - if ('[' == 0x5b && quoting_style == shell_quoting_style) - { - size_t j; - for (j = 1; j < bytes; j++) - switch (arg[i + m + j]) - { - case '[': case '\\': case '^': - case '`': case '|': - goto use_shell_always_quoting_style; - - default: - break; - } - } - - if (! iswprint (w)) - printable = false; - m += bytes; - } - } - while (! mbsinit (&mbstate)); - } - - if (1 < m || (backslash_escapes && ! printable)) - { - /* Output a multibyte sequence, or an escaped - unprintable unibyte character. */ - size_t ilim = i + m; - - for (;;) - { - if (backslash_escapes && ! printable) - { - STORE ('\\'); - STORE ('0' + (c >> 6)); - STORE ('0' + ((c >> 3) & 7)); - c = '0' + (c & 7); - } - if (ilim <= i + 1) - break; - STORE (c); - c = arg[++i]; - } - - goto store_c; - } - } - } - - if (! (backslash_escapes - && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))) - goto store_c; - - store_escape: - STORE ('\\'); - - store_c: - STORE (c); - } - - if (i == 0 && quoting_style == shell_quoting_style) - goto use_shell_always_quoting_style; - - if (quote_string) - for (; *quote_string; quote_string++) - STORE (*quote_string); - - if (len < buffersize) - buffer[len] = '\0'; - return len; - - use_shell_always_quoting_style: - return quotearg_buffer_restyled (buffer, buffersize, arg, argsize, - shell_always_quoting_style, o); -} - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using O to control quoting. - If O is null, use the default. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is SIZE_MAX, use the string length of the argument for - ARGSIZE. */ -size_t -quotearg_buffer (char *buffer, size_t buffersize, - char const *arg, size_t argsize, - struct quoting_options const *o) -{ - struct quoting_options const *p = o ? o : &default_quoting_options; - int e = errno; - size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize, - p->style, p); - errno = e; - return r; -} - -/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly - allocated storage containing the quoted string. */ -char * -quotearg_alloc (char const *arg, size_t argsize, - struct quoting_options const *o) -{ - int e = errno; - size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1; - char *buf = xcharalloc (bufsize); - quotearg_buffer (buf, bufsize, arg, argsize, o); - errno = e; - return buf; -} - -/* A storage slot with size and pointer to a value. */ -struct slotvec -{ - size_t size; - char *val; -}; - -/* Preallocate a slot 0 buffer, so that the caller can always quote - one small component of a "memory exhausted" message in slot 0. */ -static char slot0[256]; -static unsigned int nslots = 1; -static struct slotvec slotvec0 = {sizeof slot0, slot0}; -static struct slotvec *slotvec = &slotvec0; - -void -quotearg_free (void) -{ - struct slotvec *sv = slotvec; - unsigned int i; - for (i = 1; i < nslots; i++) - free (sv[i].val); - if (sv[0].val != slot0) - { - free (sv[0].val); - slotvec0.size = sizeof slot0; - slotvec0.val = slot0; - } - if (sv != &slotvec0) - { - free (sv); - slotvec = &slotvec0; - } - nslots = 1; -} - -/* Use storage slot N to return a quoted version of argument ARG. - ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a - null-terminated string. - OPTIONS specifies the quoting options. - The returned value points to static storage that can be - reused by the next call to this function with the same value of N. - N must be nonnegative. N is deliberately declared with type "int" - to allow for future extensions (using negative values). */ -static char * -quotearg_n_options (int n, char const *arg, size_t argsize, - struct quoting_options const *options) -{ - int e = errno; - - unsigned int n0 = n; - struct slotvec *sv = slotvec; - - if (n < 0) - abort (); - - if (nslots <= n0) - { - /* FIXME: technically, the type of n1 should be `unsigned int', - but that evokes an unsuppressible warning from gcc-4.0.1 and - older. If gcc ever provides an option to suppress that warning, - revert to the original type, so that the test in xalloc_oversized - is once again performed only at compile time. */ - size_t n1 = n0 + 1; - bool preallocated = (sv == &slotvec0); - - if (xalloc_oversized (n1, sizeof *sv)) - xalloc_die (); - - slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv); - if (preallocated) - *sv = slotvec0; - memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv); - nslots = n1; - } - - { - size_t size = sv[n].size; - char *val = sv[n].val; - size_t qsize = quotearg_buffer (val, size, arg, argsize, options); - - if (size <= qsize) - { - sv[n].size = size = qsize + 1; - if (val != slot0) - free (val); - sv[n].val = val = xcharalloc (size); - quotearg_buffer (val, size, arg, argsize, options); - } - - errno = e; - return val; - } -} - -char * -quotearg_n (int n, char const *arg) -{ - return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options); -} - -char * -quotearg (char const *arg) -{ - return quotearg_n (0, arg); -} - -/* Return quoting options for STYLE, with no extra quoting. */ -static struct quoting_options -quoting_options_from_style (enum quoting_style style) -{ - struct quoting_options o; - o.style = style; - memset (o.quote_these_too, 0, sizeof o.quote_these_too); - return o; -} - -char * -quotearg_n_style (int n, enum quoting_style s, char const *arg) -{ - struct quoting_options const o = quoting_options_from_style (s); - return quotearg_n_options (n, arg, SIZE_MAX, &o); -} - -char * -quotearg_n_style_mem (int n, enum quoting_style s, - char const *arg, size_t argsize) -{ - struct quoting_options const o = quoting_options_from_style (s); - return quotearg_n_options (n, arg, argsize, &o); -} - -char * -quotearg_style (enum quoting_style s, char const *arg) -{ - return quotearg_n_style (0, s, arg); -} - -char * -quotearg_char (char const *arg, char ch) -{ - struct quoting_options options; - options = default_quoting_options; - set_char_quoting (&options, ch, 1); - return quotearg_n_options (0, arg, SIZE_MAX, &options); -} - -char * -quotearg_colon (char const *arg) -{ - return quotearg_char (arg, ':'); -} diff --git a/contrib/cpio/lib/quotearg.h b/contrib/cpio/lib/quotearg.h deleted file mode 100644 index 4887df3b6d5..00000000000 --- a/contrib/cpio/lib/quotearg.h +++ /dev/null @@ -1,140 +0,0 @@ -/* quotearg.h - quote arguments for output - - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Free - Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#ifndef QUOTEARG_H_ -# define QUOTEARG_H_ 1 - -# include - -/* Basic quoting styles. */ -enum quoting_style - { - /* Output names as-is (ls --quoting-style=literal). */ - literal_quoting_style, - - /* Quote names for the shell if they contain shell metacharacters - or would cause ambiguous output (ls --quoting-style=shell). */ - shell_quoting_style, - - /* Quote names for the shell, even if they would normally not - require quoting (ls --quoting-style=shell-always). */ - shell_always_quoting_style, - - /* Quote names as for a C language string (ls --quoting-style=c). */ - c_quoting_style, - - /* Like c_quoting_style except omit the surrounding double-quote - characters (ls --quoting-style=escape). */ - escape_quoting_style, - - /* Like clocale_quoting_style, but quote `like this' instead of - "like this" in the default C locale (ls --quoting-style=locale). */ - locale_quoting_style, - - /* Like c_quoting_style except use quotation marks appropriate for - the locale (ls --quoting-style=clocale). */ - clocale_quoting_style - }; - -/* For now, --quoting-style=literal is the default, but this may change. */ -# ifndef DEFAULT_QUOTING_STYLE -# define DEFAULT_QUOTING_STYLE literal_quoting_style -# endif - -/* Names of quoting styles and their corresponding values. */ -extern char const *const quoting_style_args[]; -extern enum quoting_style const quoting_style_vals[]; - -struct quoting_options; - -/* The functions listed below set and use a hidden variable - that contains the default quoting style options. */ - -/* Allocate a new set of quoting options, with contents initially identical - to O if O is not null, or to the default if O is null. - It is the caller's responsibility to free the result. */ -struct quoting_options *clone_quoting_options (struct quoting_options *o); - -/* Get the value of O's quoting style. If O is null, use the default. */ -enum quoting_style get_quoting_style (struct quoting_options *o); - -/* In O (or in the default if O is null), - set the value of the quoting style to S. */ -void set_quoting_style (struct quoting_options *o, enum quoting_style s); - -/* In O (or in the default if O is null), - set the value of the quoting options for character C to I. - Return the old value. Currently, the only values defined for I are - 0 (the default) and 1 (which means to quote the character even if - it would not otherwise be quoted). */ -int set_char_quoting (struct quoting_options *o, char c, int i); - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using O to control quoting. - If O is null, use the default. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */ -size_t quotearg_buffer (char *buffer, size_t buffersize, - char const *arg, size_t argsize, - struct quoting_options const *o); - -/* Like quotearg_buffer, except return the result in a newly allocated - buffer. It is the caller's responsibility to free the result. */ -char *quotearg_alloc (char const *arg, size_t argsize, - struct quoting_options const *o); - -/* Use storage slot N to return a quoted version of the string ARG. - Use the default quoting options. - The returned value points to static storage that can be - reused by the next call to this function with the same value of N. - N must be nonnegative. */ -char *quotearg_n (int n, char const *arg); - -/* Equivalent to quotearg_n (0, ARG). */ -char *quotearg (char const *arg); - -/* Use style S and storage slot N to return a quoted version of the string ARG. - This is like quotearg_n (N, ARG), except that it uses S with no other - options to specify the quoting method. */ -char *quotearg_n_style (int n, enum quoting_style s, char const *arg); - -/* Use style S and storage slot N to return a quoted version of the - argument ARG of size ARGSIZE. This is like quotearg_n_style - (N, S, ARG), except it can quote null bytes. */ -char *quotearg_n_style_mem (int n, enum quoting_style s, - char const *arg, size_t argsize); - -/* Equivalent to quotearg_n_style (0, S, ARG). */ -char *quotearg_style (enum quoting_style s, char const *arg); - -/* Like quotearg (ARG), except also quote any instances of CH. */ -char *quotearg_char (char const *arg, char ch); - -/* Equivalent to quotearg_char (ARG, ':'). */ -char *quotearg_colon (char const *arg); - -/* Free any dynamically allocated memory. */ -void quotearg_free (void); - -#endif /* !QUOTEARG_H_ */ diff --git a/contrib/cpio/lib/rmt-command.h b/contrib/cpio/lib/rmt-command.h deleted file mode 100644 index 7460e6fc962..00000000000 --- a/contrib/cpio/lib/rmt-command.h +++ /dev/null @@ -1,4 +0,0 @@ -#define LOCALEDIR "/usr/local/share/locale" -#ifndef DEFAULT_RMT_COMMAND -# define DEFAULT_RMT_COMMAND "/usr/local/libexec/rmt" -#endif diff --git a/contrib/cpio/lib/rmt.h b/contrib/cpio/lib/rmt.h deleted file mode 100644 index 9f96cdb9b5f..00000000000 --- a/contrib/cpio/lib/rmt.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Definitions for communicating with a remote tape drive. - - Copyright (C) 1988, 1992, 1996, 1997, 2001, 2003, 2004 Free - Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -extern char *rmt_command; -extern char *rmt_dev_name__; - -int rmt_open__ (const char *, int, int, const char *); -int rmt_close__ (int); -size_t rmt_read__ (int, char *, size_t); -size_t rmt_write__ (int, char *, size_t); -off_t rmt_lseek__ (int, off_t, int); -int rmt_ioctl__ (int, int, char *); - -extern bool force_local_option; - -/* A filename is remote if it contains a colon not preceded by a slash, - to take care of `/:/' which is a shorthand for `/...//fs' - on machines running OSF's Distributing Computing Environment (DCE) and - Distributed File System (DFS). However, when --force-local, a - filename is never remote. */ - -#define _remdev(dev_name) \ - (!force_local_option && (rmt_dev_name__ = strchr (dev_name, ':')) \ - && rmt_dev_name__ > (dev_name) \ - && ! memchr (dev_name, '/', rmt_dev_name__ - (dev_name))) - -#define _isrmt(fd) \ - ((fd) >= __REM_BIAS) - -#define __REM_BIAS (1 << 30) - -#ifndef O_CREAT -# define O_CREAT 01000 -#endif - -#define rmtopen(dev_name, oflag, mode, command) \ - (_remdev (dev_name) ? rmt_open__ (dev_name, oflag, __REM_BIAS, command) \ - : open (dev_name, oflag, mode)) - -#define rmtaccess(dev_name, amode) \ - (_remdev (dev_name) ? 0 : access (dev_name, amode)) - -#define rmtstat(dev_name, buffer) \ - (_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : stat (dev_name, buffer)) - -#define rmtcreat(dev_name, mode, command) \ - (_remdev (dev_name) \ - ? rmt_open__ (dev_name, 1 | O_CREAT, __REM_BIAS, command) \ - : creat (dev_name, mode)) - -#define rmtlstat(dev_name, muffer) \ - (_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : lstat (dev_name, buffer)) - -#define rmtread(fd, buffer, length) \ - (_isrmt (fd) ? rmt_read__ (fd - __REM_BIAS, buffer, length) \ - : safe_read (fd, buffer, length)) - -#define rmtwrite(fd, buffer, length) \ - (_isrmt (fd) ? rmt_write__ (fd - __REM_BIAS, buffer, length) \ - : full_write (fd, buffer, length)) - -#define rmtlseek(fd, offset, where) \ - (_isrmt (fd) ? rmt_lseek__ (fd - __REM_BIAS, offset, where) \ - : lseek (fd, offset, where)) - -#define rmtclose(fd) \ - (_isrmt (fd) ? rmt_close__ (fd - __REM_BIAS) : close (fd)) - -#define rmtioctl(fd, request, argument) \ - (_isrmt (fd) ? rmt_ioctl__ (fd - __REM_BIAS, request, argument) \ - : ioctl (fd, request, argument)) - -#define rmtdup(fd) \ - (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : dup (fd)) - -#define rmtfstat(fd, buffer) \ - (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fstat (fd, buffer)) - -#define rmtfcntl(cd, command, argument) \ - (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fcntl (fd, command, argument)) - -#define rmtisatty(fd) \ - (_isrmt (fd) ? 0 : isatty (fd)) diff --git a/contrib/cpio/lib/rtapelib.c b/contrib/cpio/lib/rtapelib.c deleted file mode 100644 index d73d1364e84..00000000000 --- a/contrib/cpio/lib/rtapelib.c +++ /dev/null @@ -1,741 +0,0 @@ -/* Functions for communicating with a remote tape drive. - - Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004, - 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* The man page rmt(8) for /etc/rmt documents the remote mag tape protocol - which rdump and rrestore use. Unfortunately, the man page is *WRONG*. - The author of the routines I'm including originally wrote his code just - based on the man page, and it didn't work, so he went to the rdump source - to figure out why. The only thing he had to change was to check for the - 'F' return code in addition to the 'E', and to separate the various - arguments with \n instead of a space. I personally don't think that this - is much of a problem, but I wanted to point it out. -- Arnold Robbins - - Originally written by Jeff Lee, modified some by Arnold Robbins. Redone - as a library that can replace open, read, write, etc., by Fred Fish, with - some additional work by Arnold Robbins. Modified to make all rmt* calls - into macros for speed by Jay Fenlason. Use -DWITH_REXEC for rexec - code, courtesy of Dan Kegel. */ - -#include "system.h" -#include "system-ioctl.h" - -#include -#include - -/* Try hard to get EOPNOTSUPP defined. 486/ISC has it in net/errno.h, - 3B2/SVR3 has it in sys/inet.h. Otherwise, like on MSDOS, use EINVAL. */ - -#ifndef EOPNOTSUPP -# if HAVE_NET_ERRNO_H -# include -# endif -# if HAVE_SYS_INET_H -# include -# endif -# ifndef EOPNOTSUPP -# define EOPNOTSUPP EINVAL -# endif -#endif - -#include - -#if HAVE_NETDB_H -# include -#endif - -#include -#include - -/* Exit status if exec errors. */ -#define EXIT_ON_EXEC_ERROR 128 - -/* FIXME: Size of buffers for reading and writing commands to rmt. */ -#define COMMAND_BUFFER_SIZE 64 - -#ifndef RETSIGTYPE -# define RETSIGTYPE void -#endif - -/* FIXME: Maximum number of simultaneous remote tape connections. */ -#define MAXUNIT 4 - -#define PREAD 0 /* read file descriptor from pipe() */ -#define PWRITE 1 /* write file descriptor from pipe() */ - -/* Return the parent's read side of remote tape connection Fd. */ -#define READ_SIDE(Fd) (from_remote[Fd][PREAD]) - -/* Return the parent's write side of remote tape connection Fd. */ -#define WRITE_SIDE(Fd) (to_remote[Fd][PWRITE]) - -/* The pipes for receiving data from remote tape drives. */ -static int from_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; - -/* The pipes for sending data to remote tape drives. */ -static int to_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; - -char *rmt_command = DEFAULT_RMT_COMMAND; - -/* Temporary variable used by macros in rmt.h. */ -char *rmt_dev_name__; - -/* If true, always consider file names to be local, even if they contain - colons */ -bool force_local_option; - - - -/* Close remote tape connection HANDLE, and reset errno to ERRNO_VALUE. */ -static void -_rmt_shutdown (int handle, int errno_value) -{ - close (READ_SIDE (handle)); - close (WRITE_SIDE (handle)); - READ_SIDE (handle) = -1; - WRITE_SIDE (handle) = -1; - errno = errno_value; -} - -/* Attempt to perform the remote tape command specified in BUFFER on - remote tape connection HANDLE. Return 0 if successful, -1 on - error. */ -static int -do_command (int handle, const char *buffer) -{ - /* Save the current pipe handler and try to make the request. */ - - size_t length = strlen (buffer); - RETSIGTYPE (*pipe_handler) () = signal (SIGPIPE, SIG_IGN); - ssize_t written = full_write (WRITE_SIDE (handle), buffer, length); - signal (SIGPIPE, pipe_handler); - - if (written == length) - return 0; - - /* Something went wrong. Close down and go home. */ - - _rmt_shutdown (handle, EIO); - return -1; -} - -static char * -get_status_string (int handle, char *command_buffer) -{ - char *cursor; - int counter; - - /* Read the reply command line. */ - - for (counter = 0, cursor = command_buffer; - counter < COMMAND_BUFFER_SIZE; - counter++, cursor++) - { - if (safe_read (READ_SIDE (handle), cursor, 1) != 1) - { - _rmt_shutdown (handle, EIO); - return 0; - } - if (*cursor == '\n') - { - *cursor = '\0'; - break; - } - } - - if (counter == COMMAND_BUFFER_SIZE) - { - _rmt_shutdown (handle, EIO); - return 0; - } - - /* Check the return status. */ - - for (cursor = command_buffer; *cursor; cursor++) - if (*cursor != ' ') - break; - - if (*cursor == 'E' || *cursor == 'F') - { - /* Skip the error message line. */ - - /* FIXME: there is better to do than merely ignoring error messages - coming from the remote end. Translate them, too... */ - - { - char character; - - while (safe_read (READ_SIDE (handle), &character, 1) == 1) - if (character == '\n') - break; - } - - errno = atoi (cursor + 1); - - if (*cursor == 'F') - _rmt_shutdown (handle, errno); - - return 0; - } - - /* Check for mis-synced pipes. */ - - if (*cursor != 'A') - { - _rmt_shutdown (handle, EIO); - return 0; - } - - /* Got an `A' (success) response. */ - - return cursor + 1; -} - -/* Read and return the status from remote tape connection HANDLE. If - an error occurred, return -1 and set errno. */ -static long int -get_status (int handle) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - const char *status = get_status_string (handle, command_buffer); - if (status) - { - long int result = atol (status); - if (0 <= result) - return result; - errno = EIO; - } - return -1; -} - -static off_t -get_status_off (int handle) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - const char *status = get_status_string (handle, command_buffer); - - if (! status) - return -1; - else - { - /* Parse status, taking care to check for overflow. - We can't use standard functions, - since off_t might be longer than long. */ - - off_t count = 0; - int negative; - - for (; *status == ' ' || *status == '\t'; status++) - continue; - - negative = *status == '-'; - status += negative || *status == '+'; - - for (;;) - { - int digit = *status++ - '0'; - if (9 < (unsigned) digit) - break; - else - { - off_t c10 = 10 * count; - off_t nc = negative ? c10 - digit : c10 + digit; - if (c10 / 10 != count || (negative ? c10 < nc : nc < c10)) - return -1; - count = nc; - } - } - - return count; - } -} - -#if WITH_REXEC - -/* Execute /etc/rmt as user USER on remote system HOST using rexec. - Return a file descriptor of a bidirectional socket for stdin and - stdout. If USER is zero, use the current username. - - By default, this code is not used, since it requires that the user - have a .netrc file in his/her home directory, or that the - application designer be willing to have rexec prompt for login and - password info. This may be unacceptable, and .rhosts files for use - with rsh are much more common on BSD systems. */ -static int -_rmt_rexec (char *host, char *user) -{ - int saved_stdin = dup (STDIN_FILENO); - int saved_stdout = dup (STDOUT_FILENO); - struct servent *rexecserv; - int result; - - /* When using cpio -o < filename, stdin is no longer the tty. But the - rexec subroutine reads the login and the passwd on stdin, to allow - remote execution of the command. So, reopen stdin and stdout on - /dev/tty before the rexec and give them back their original value - after. */ - - if (! freopen ("/dev/tty", "r", stdin)) - freopen ("/dev/null", "r", stdin); - if (! freopen ("/dev/tty", "w", stdout)) - freopen ("/dev/null", "w", stdout); - - if (rexecserv = getservbyname ("exec", "tcp"), !rexecserv) - error (EXIT_ON_EXEC_ERROR, 0, _("exec/tcp: Service not available")); - - result = rexec (&host, rexecserv->s_port, user, 0, rmt_command, 0); - if (fclose (stdin) == EOF) - error (0, errno, _("stdin")); - fdopen (saved_stdin, "r"); - if (fclose (stdout) == EOF) - error (0, errno, _("stdout")); - fdopen (saved_stdout, "w"); - - return result; -} - -#endif /* WITH_REXEC */ - -/* Place into BUF a string representing OFLAG, which must be suitable - as argument 2 of `open'. BUF must be large enough to hold the - result. This function should generate a string that decode_oflag - can parse. */ -static void -encode_oflag (char *buf, int oflag) -{ - sprintf (buf, "%d ", oflag); - - switch (oflag & O_ACCMODE) - { - case O_RDONLY: strcat (buf, "O_RDONLY"); break; - case O_RDWR: strcat (buf, "O_RDWR"); break; - case O_WRONLY: strcat (buf, "O_WRONLY"); break; - default: abort (); - } - -#ifdef O_APPEND - if (oflag & O_APPEND) strcat (buf, "|O_APPEND"); -#endif - if (oflag & O_CREAT) strcat (buf, "|O_CREAT"); -#ifdef O_DSYNC - if (oflag & O_DSYNC) strcat (buf, "|O_DSYNC"); -#endif - if (oflag & O_EXCL) strcat (buf, "|O_EXCL"); -#ifdef O_LARGEFILE - if (oflag & O_LARGEFILE) strcat (buf, "|O_LARGEFILE"); -#endif -#ifdef O_NOCTTY - if (oflag & O_NOCTTY) strcat (buf, "|O_NOCTTY"); -#endif - if (oflag & O_NONBLOCK) strcat (buf, "|O_NONBLOCK"); -#ifdef O_RSYNC - if (oflag & O_RSYNC) strcat (buf, "|O_RSYNC"); -#endif -#ifdef O_SYNC - if (oflag & O_SYNC) strcat (buf, "|O_SYNC"); -#endif - if (oflag & O_TRUNC) strcat (buf, "|O_TRUNC"); -} - -/* Open a file (a magnetic tape device?) on the system specified in - FILE_NAME, as the given user. FILE_NAME has the form `[USER@]HOST:FILE'. - OPEN_MODE is O_RDONLY, O_WRONLY, etc. If successful, return the - remote pipe number plus BIAS. REMOTE_SHELL may be overridden. On - error, return -1. */ -int -rmt_open__ (const char *file_name, int open_mode, int bias, - const char *remote_shell) -{ - int remote_pipe_number; /* pseudo, biased file descriptor */ - char *file_name_copy; /* copy of file_name string */ - char *remote_host; /* remote host name */ - char *remote_file; /* remote file name (often a device) */ - char *remote_user; /* remote user name */ - - /* Find an unused pair of file descriptors. */ - - for (remote_pipe_number = 0; - remote_pipe_number < MAXUNIT; - remote_pipe_number++) - if (READ_SIDE (remote_pipe_number) == -1 - && WRITE_SIDE (remote_pipe_number) == -1) - break; - - if (remote_pipe_number == MAXUNIT) - { - errno = EMFILE; - return -1; - } - - /* Pull apart the system and device, and optional user. */ - - { - char *cursor; - - file_name_copy = xstrdup (file_name); - remote_host = file_name_copy; - remote_user = 0; - remote_file = 0; - - for (cursor = file_name_copy; *cursor; cursor++) - switch (*cursor) - { - default: - break; - - case '\n': - /* Do not allow newlines in the file_name, since the protocol - uses newline delimiters. */ - free (file_name_copy); - errno = ENOENT; - return -1; - - case '@': - if (!remote_user) - { - remote_user = remote_host; - *cursor = '\0'; - remote_host = cursor + 1; - } - break; - - case ':': - if (!remote_file) - { - *cursor = '\0'; - remote_file = cursor + 1; - } - break; - } - } - - /* FIXME: Should somewhat validate the decoding, here. */ - - if (remote_user && *remote_user == '\0') - remote_user = 0; - -#if WITH_REXEC - - /* Execute the remote command using rexec. */ - - READ_SIDE (remote_pipe_number) = _rmt_rexec (remote_host, remote_user); - if (READ_SIDE (remote_pipe_number) < 0) - { - int e = errno; - free (file_name_copy); - errno = e; - return -1; - } - - WRITE_SIDE (remote_pipe_number) = READ_SIDE (remote_pipe_number); - -#else /* not WITH_REXEC */ - { - const char *remote_shell_basename; - pid_t status; - - /* Identify the remote command to be executed. */ - - if (!remote_shell) - { -#ifdef REMOTE_SHELL - remote_shell = REMOTE_SHELL; -#else - free (file_name_copy); - errno = EIO; - return -1; -#endif - } - remote_shell_basename = base_name (remote_shell); - - /* Set up the pipes for the `rsh' command, and fork. */ - - if (pipe (to_remote[remote_pipe_number]) == -1 - || pipe (from_remote[remote_pipe_number]) == -1) - { - int e = errno; - free (file_name_copy); - errno = e; - return -1; - } - - status = fork (); - if (status == -1) - { - int e = errno; - free (file_name_copy); - errno = e; - return -1; - } - - if (status == 0) - { - /* Child. */ - - close (STDIN_FILENO); - dup (to_remote[remote_pipe_number][PREAD]); - close (to_remote[remote_pipe_number][PREAD]); - close (to_remote[remote_pipe_number][PWRITE]); - - close (STDOUT_FILENO); - dup (from_remote[remote_pipe_number][PWRITE]); - close (from_remote[remote_pipe_number][PREAD]); - close (from_remote[remote_pipe_number][PWRITE]); - - sys_reset_uid_gid (); - - if (remote_user) - execl (remote_shell, remote_shell_basename, remote_host, - "-l", remote_user, rmt_command, (char *) 0); - else - execl (remote_shell, remote_shell_basename, remote_host, - rmt_command, (char *) 0); - - /* Bad problems if we get here. */ - - /* In a previous version, _exit was used here instead of exit. */ - error (EXIT_ON_EXEC_ERROR, errno, _("Cannot execute remote shell")); - } - - /* Parent. */ - - close (from_remote[remote_pipe_number][PWRITE]); - close (to_remote[remote_pipe_number][PREAD]); - } -#endif /* not WITH_REXEC */ - - /* Attempt to open the tape device. */ - - { - size_t remote_file_len = strlen (remote_file); - char *command_buffer = xmalloc (remote_file_len + 1000); - sprintf (command_buffer, "O%s\n", remote_file); - encode_oflag (command_buffer + remote_file_len + 2, open_mode); - strcat (command_buffer, "\n"); - if (do_command (remote_pipe_number, command_buffer) == -1 - || get_status (remote_pipe_number) == -1) - { - int e = errno; - free (command_buffer); - free (file_name_copy); - _rmt_shutdown (remote_pipe_number, e); - return -1; - } - free (command_buffer); - } - - free (file_name_copy); - return remote_pipe_number + bias; -} - -/* Close remote tape connection HANDLE and shut down. Return 0 if - successful, -1 on error. */ -int -rmt_close__ (int handle) -{ - long int status; - - if (do_command (handle, "C\n") == -1) - return -1; - - status = get_status (handle); - _rmt_shutdown (handle, errno); - return status; -} - -/* Read up to LENGTH bytes into BUFFER from remote tape connection HANDLE. - Return the number of bytes read on success, SAFE_READ_ERROR on error. */ -size_t -rmt_read__ (int handle, char *buffer, size_t length) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - size_t status; - size_t rlen; - size_t counter; - - sprintf (command_buffer, "R%lu\n", (unsigned long) length); - if (do_command (handle, command_buffer) == -1 - || (status = get_status (handle)) == SAFE_READ_ERROR - || status > length) - return SAFE_READ_ERROR; - - for (counter = 0; counter < status; counter += rlen, buffer += rlen) - { - rlen = safe_read (READ_SIDE (handle), buffer, status - counter); - if (rlen == SAFE_READ_ERROR || rlen == 0) - { - _rmt_shutdown (handle, EIO); - return SAFE_READ_ERROR; - } - } - - return status; -} - -/* Write LENGTH bytes from BUFFER to remote tape connection HANDLE. - Return the number of bytes written. */ -size_t -rmt_write__ (int handle, char *buffer, size_t length) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - RETSIGTYPE (*pipe_handler) (); - size_t written; - - sprintf (command_buffer, "W%lu\n", (unsigned long) length); - if (do_command (handle, command_buffer) == -1) - return 0; - - pipe_handler = signal (SIGPIPE, SIG_IGN); - written = full_write (WRITE_SIDE (handle), buffer, length); - signal (SIGPIPE, pipe_handler); - if (written == length) - { - long int r = get_status (handle); - if (r < 0) - return 0; - if (r == length) - return length; - written = r; - } - - /* Write error. */ - - _rmt_shutdown (handle, EIO); - return written; -} - -/* Perform an imitation lseek operation on remote tape connection - HANDLE. Return the new file offset if successful, -1 if on error. */ -off_t -rmt_lseek__ (int handle, off_t offset, int whence) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - char operand_buffer[UINTMAX_STRSIZE_BOUND]; - uintmax_t u = offset < 0 ? - (uintmax_t) offset : (uintmax_t) offset; - char *p = operand_buffer + sizeof operand_buffer; - - *--p = 0; - do - *--p = '0' + (int) (u % 10); - while ((u /= 10) != 0); - if (offset < 0) - *--p = '-'; - - switch (whence) - { - case SEEK_SET: whence = 0; break; - case SEEK_CUR: whence = 1; break; - case SEEK_END: whence = 2; break; - default: abort (); - } - - sprintf (command_buffer, "L%s\n%d\n", p, whence); - - if (do_command (handle, command_buffer) == -1) - return -1; - - return get_status_off (handle); -} - -/* Perform a raw tape operation on remote tape connection HANDLE. - Return the results of the ioctl, or -1 on error. */ -int -rmt_ioctl__ (int handle, int operation, char *argument) -{ - switch (operation) - { - default: - errno = EOPNOTSUPP; - return -1; - -#ifdef MTIOCTOP - case MTIOCTOP: - { - char command_buffer[COMMAND_BUFFER_SIZE]; - char operand_buffer[UINTMAX_STRSIZE_BOUND]; - uintmax_t u = (((struct mtop *) argument)->mt_count < 0 - ? - (uintmax_t) ((struct mtop *) argument)->mt_count - : (uintmax_t) ((struct mtop *) argument)->mt_count); - char *p = operand_buffer + sizeof operand_buffer; - - *--p = 0; - do - *--p = '0' + (int) (u % 10); - while ((u /= 10) != 0); - if (((struct mtop *) argument)->mt_count < 0) - *--p = '-'; - - /* MTIOCTOP is the easy one. Nothing is transferred in binary. */ - - sprintf (command_buffer, "I%d\n%s\n", - ((struct mtop *) argument)->mt_op, p); - if (do_command (handle, command_buffer) == -1) - return -1; - - return get_status (handle); - } -#endif /* MTIOCTOP */ - -#ifdef MTIOCGET - case MTIOCGET: - { - ssize_t status; - size_t counter; - - /* Grab the status and read it directly into the structure. This - assumes that the status buffer is not padded and that 2 shorts - fit in a long without any word alignment problems; i.e., the - whole struct is contiguous. NOTE - this is probably NOT a good - assumption. */ - - if (do_command (handle, "S") == -1 - || (status = get_status (handle), status == -1)) - return -1; - - for (; status > 0; status -= counter, argument += counter) - { - counter = safe_read (READ_SIDE (handle), argument, status); - if (counter == SAFE_READ_ERROR || counter == 0) - { - _rmt_shutdown (handle, EIO); - return -1; - } - } - - /* Check for byte position. mt_type (or mt_model) is a small integer - field (normally) so we will check its magnitude. If it is larger - than 256, we will assume that the bytes are swapped and go through - and reverse all the bytes. */ - - if (((struct mtget *) argument)->MTIO_CHECK_FIELD < 256) - return 0; - - for (counter = 0; counter < status; counter += 2) - { - char copy = argument[counter]; - - argument[counter] = argument[counter + 1]; - argument[counter + 1] = copy; - } - - return 0; - } -#endif /* MTIOCGET */ - - } -} diff --git a/contrib/cpio/lib/safe-read.c b/contrib/cpio/lib/safe-read.c deleted file mode 100644 index b7bf1d5cd60..00000000000 --- a/contrib/cpio/lib/safe-read.c +++ /dev/null @@ -1,78 +0,0 @@ -/* An interface to read and write that retries after interrupts. - - Copyright (C) 1993, 1994, 1998, 2002, 2003, 2004, 2005, 2006 Free - Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#ifdef SAFE_WRITE -# include "safe-write.h" -#else -# include "safe-read.h" -#endif - -/* Get ssize_t. */ -#include -#include - -#include - -#ifdef EINTR -# define IS_EINTR(x) ((x) == EINTR) -#else -# define IS_EINTR(x) 0 -#endif - -#include - -#ifdef SAFE_WRITE -# define safe_rw safe_write -# define rw write -#else -# define safe_rw safe_read -# define rw read -# undef const -# define const /* empty */ -#endif - -/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if - interrupted. Return the actual number of bytes read(written), zero for EOF, - or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */ -size_t -safe_rw (int fd, void const *buf, size_t count) -{ - /* Work around a bug in Tru64 5.1. Attempting to read more than - INT_MAX bytes fails with errno == EINVAL. See - . - When decreasing COUNT, keep it block-aligned. */ - enum { BUGGY_READ_MAXIMUM = INT_MAX & ~8191 }; - - for (;;) - { - ssize_t result = rw (fd, buf, count); - - if (0 <= result) - return result; - else if (IS_EINTR (errno)) - continue; - else if (errno == EINVAL && BUGGY_READ_MAXIMUM < count) - count = BUGGY_READ_MAXIMUM; - else - return result; - } -} diff --git a/contrib/cpio/lib/safe-read.h b/contrib/cpio/lib/safe-read.h deleted file mode 100644 index 3451955ad4f..00000000000 --- a/contrib/cpio/lib/safe-read.h +++ /dev/null @@ -1,35 +0,0 @@ -/* An interface to read() that retries after interrupts. - Copyright (C) 2002, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define SAFE_READ_ERROR ((size_t) -1) - -/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted. - Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR - upon error. */ -extern size_t safe_read (int fd, void *buf, size_t count); - - -#ifdef __cplusplus -} -#endif diff --git a/contrib/cpio/lib/safe-write.c b/contrib/cpio/lib/safe-write.c deleted file mode 100644 index 4c375a6ca19..00000000000 --- a/contrib/cpio/lib/safe-write.c +++ /dev/null @@ -1,19 +0,0 @@ -/* An interface to write that retries after interrupts. - Copyright (C) 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#define SAFE_WRITE -#include "safe-read.c" diff --git a/contrib/cpio/lib/safe-write.h b/contrib/cpio/lib/safe-write.h deleted file mode 100644 index c194636209f..00000000000 --- a/contrib/cpio/lib/safe-write.h +++ /dev/null @@ -1,25 +0,0 @@ -/* An interface to write() that retries after interrupts. - Copyright (C) 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#define SAFE_WRITE_ERROR ((size_t) -1) - -/* Write up to COUNT bytes at BUF to descriptor FD, retrying if interrupted. - Return the actual number of bytes written, zero for EOF, or SAFE_WRITE_ERROR - upon error. */ -extern size_t safe_write (int fd, const void *buf, size_t count); diff --git a/contrib/cpio/lib/savedir.c b/contrib/cpio/lib/savedir.c deleted file mode 100644 index d930fb4af27..00000000000 --- a/contrib/cpio/lib/savedir.c +++ /dev/null @@ -1,137 +0,0 @@ -/* savedir.c -- save the list of files in a directory in a string - - Copyright (C) 1990, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, - 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by David MacKenzie . */ - -#include - -#include "savedir.h" - -#include - -#include - -#include -#ifndef _D_EXACT_NAMLEN -# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name) -#endif - -#include -#include -#include - -#include "openat.h" -#include "xalloc.h" - -#ifndef NAME_SIZE_DEFAULT -# define NAME_SIZE_DEFAULT 512 -#endif - -/* The results of opendir() in this file are not used with dirfd and fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef opendir -#undef closedir - -/* Return a freshly allocated string containing the file names - in directory DIRP, separated by '\0' characters; - the end is marked by two '\0' characters in a row. - Return NULL (setting errno) if DIRP cannot be read or closed. - If DIRP is NULL, return NULL without affecting errno. */ - -static char * -savedirstream (DIR *dirp) -{ - char *name_space; - size_t allocated = NAME_SIZE_DEFAULT; - size_t used = 0; - int save_errno; - - if (dirp == NULL) - return NULL; - - name_space = xmalloc (allocated); - - for (;;) - { - struct dirent const *dp; - char const *entry; - - errno = 0; - dp = readdir (dirp); - if (! dp) - break; - - /* Skip "", ".", and "..". "" is returned by at least one buggy - implementation: Solaris 2.4 readdir on NFS file systems. */ - entry = dp->d_name; - if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0') - { - size_t entry_size = _D_EXACT_NAMLEN (dp) + 1; - if (used + entry_size < used) - xalloc_die (); - if (allocated <= used + entry_size) - { - do - { - if (2 * allocated < allocated) - xalloc_die (); - allocated *= 2; - } - while (allocated <= used + entry_size); - - name_space = xrealloc (name_space, allocated); - } - memcpy (name_space + used, entry, entry_size); - used += entry_size; - } - } - name_space[used] = '\0'; - save_errno = errno; - if (closedir (dirp) != 0) - save_errno = errno; - if (save_errno != 0) - { - free (name_space); - errno = save_errno; - return NULL; - } - return name_space; -} - -/* Return a freshly allocated string containing the file names - in directory DIR, separated by '\0' characters; - the end is marked by two '\0' characters in a row. - Return NULL (setting errno) if DIR cannot be opened, read, or closed. */ - -char * -savedir (char const *dir) -{ - return savedirstream (opendir (dir)); -} - -/* Return a freshly allocated string containing the file names - in directory FD, separated by '\0' characters; - the end is marked by two '\0' characters in a row. - Return NULL (setting errno) if FD cannot be read or closed. */ - -char * -fdsavedir (int fd) -{ - return savedirstream (fdopendir (fd)); -} diff --git a/contrib/cpio/lib/savedir.h b/contrib/cpio/lib/savedir.h deleted file mode 100644 index 5b7bef97134..00000000000 --- a/contrib/cpio/lib/savedir.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Save the list of files in a directory in a string. - - Copyright (C) 1997, 1999, 2001, 2003, 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by David MacKenzie . */ - -#if !defined SAVEDIR_H_ -# define SAVEDIR_H_ - -char *savedir (char const *dir); -char *fdsavedir (int fd); - -#endif diff --git a/contrib/cpio/lib/strchrnul.c b/contrib/cpio/lib/strchrnul.c deleted file mode 100644 index 07014be17af..00000000000 --- a/contrib/cpio/lib/strchrnul.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Searching in a string. - Copyright (C) 2003, 2007 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -/* Find the first occurrence of C in S or the final NUL byte. */ -char * -strchrnul (const char *s, int c_in) -{ - char c = c_in; - while (*s && (*s != c)) - s++; - - return (char *) s; -} diff --git a/contrib/cpio/lib/stripslash.c b/contrib/cpio/lib/stripslash.c deleted file mode 100644 index 342d497c899..00000000000 --- a/contrib/cpio/lib/stripslash.c +++ /dev/null @@ -1,45 +0,0 @@ -/* stripslash.c -- remove redundant trailing slashes from a file name - - Copyright (C) 1990, 2001, 2003-2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "dirname.h" - -/* Remove trailing slashes from FILE. Return true if a trailing slash - was removed. This is useful when using file name completion from a - shell that adds a "/" after directory names (such as tcsh and - bash), because on symlinks to directories, several system calls - have different semantics according to whether a trailing slash is - present. */ - -bool -strip_trailing_slashes (char *file) -{ - char *base = last_component (file); - char *base_lim; - bool had_slash; - - /* last_component returns "" for file system roots, but we need to turn - `///' into `/'. */ - if (! *base) - base = file; - base_lim = base + base_len (base); - had_slash = (*base_lim != '\0'); - *base_lim = '\0'; - return had_slash; -} diff --git a/contrib/cpio/lib/strndup.c b/contrib/cpio/lib/strndup.c deleted file mode 100644 index 3a1b0eae2e0..00000000000 --- a/contrib/cpio/lib/strndup.c +++ /dev/null @@ -1,37 +0,0 @@ -/* A replacement function, for systems that lack strndup. - - Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2005, 2006, 2007 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include - -#include - -char * -strndup (char const *s, size_t n) -{ - size_t len = strnlen (s, n); - char *new = malloc (len + 1); - - if (new == NULL) - return NULL; - - new[len] = '\0'; - return memcpy (new, s, len); -} diff --git a/contrib/cpio/lib/strnlen.c b/contrib/cpio/lib/strnlen.c deleted file mode 100644 index d346d3272c2..00000000000 --- a/contrib/cpio/lib/strnlen.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Find the length of STRING, but scan at most MAXLEN characters. - Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. - Written by Simon Josefsson. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include - -/* Find the length of STRING, but scan at most MAXLEN characters. - If no '\0' terminator is found in that many characters, return MAXLEN. */ - -size_t -strnlen (const char *string, size_t maxlen) -{ - const char *end = memchr (string, '\0', maxlen); - return end ? (size_t) (end - string) : maxlen; -} diff --git a/contrib/cpio/lib/system-ioctl.h b/contrib/cpio/lib/system-ioctl.h deleted file mode 100644 index a61c5fdfb01..00000000000 --- a/contrib/cpio/lib/system-ioctl.h +++ /dev/null @@ -1,55 +0,0 @@ -/* System dependent definitions for GNU tar's use of ioctl macros. - - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, - 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This is a real challenge to properly get MTIO* symbols :-(. ISC uses - . SCO and BSDi uses ; BSDi also requires - and for defining tp_dev and tpr_t. It - seems that the rest use , which itself requires other files, - depending on systems. Pyramid defines _IOW in , for example. */ - -#if HAVE_SYS_GENTAPE_H -# include -#else -# if HAVE_SYS_TAPE_H -# if HAVE_SYS_DEVICE_H -# include -# endif -# if HAVE_SYS_PARAM_H -# include -# endif -# if HAVE_SYS_BUF_H -# include -# endif -# if HAVE_SYS_TPRINTF_H -# include -# endif -# include -# else -# if HAVE_SYS_MTIO_H -# include -# if HAVE_SGTTY_H -# include -# endif -# if HAVE_SYS_IO_TRIOCTL_H -# include -# endif -# include -# endif -# endif -#endif diff --git a/contrib/cpio/lib/system.h b/contrib/cpio/lib/system.h deleted file mode 100644 index 7602263f139..00000000000 --- a/contrib/cpio/lib/system.h +++ /dev/null @@ -1,475 +0,0 @@ -/* System dependent definitions for GNU tar. - - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, - 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if HAVE_CONFIG_H -# include -#endif - -#include - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(spec) /* empty */ -# endif -#endif - -#include -#include - -/* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given - as an argument to macros like `isspace'. */ -#if STDC_HEADERS -# define IN_CTYPE_DOMAIN(c) 1 -#else -# define IN_CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177) -#endif - -#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) -#define ISODIGIT(c) ((unsigned) (c) - '0' <= 7) -#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) -#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) - -/* Declare string and memory handling routines. Take care that an ANSI - string.h and pre-ANSI memory.h might conflict, and that memory.h and - strings.h conflict on some systems. */ - -#if STDC_HEADERS || HAVE_STRING_H -# include -# if !STDC_HEADERS && HAVE_MEMORY_H -# include -# endif -#else -# include -# ifndef strchr -# define strchr index -# endif -# ifndef strrchr -# define strrchr rindex -# endif -# ifndef memcpy -# define memcpy(d, s, n) bcopy ((char const *) (s), (char *) (d), n) -# endif -# ifndef memcmp -# define memcmp(a, b, n) bcmp ((char const *) (a), (char const *) (b), n) -# endif -#endif - -/* Declare errno. */ - -#include -#ifndef errno -extern int errno; -#endif - -/* Declare open parameters. */ - -#if HAVE_FCNTL_H -# include -#else -# include -#endif - /* Pick only one of the next three: */ -#ifndef O_RDONLY -# define O_RDONLY 0 /* only allow read */ -#endif -#ifndef O_WRONLY -# define O_WRONLY 1 /* only allow write */ -#endif -#ifndef O_RDWR -# define O_RDWR 2 /* both are allowed */ -#endif -#ifndef O_ACCMODE -# define O_ACCMODE (O_RDONLY | O_RDWR | O_WRONLY) -#endif - /* The rest can be OR-ed in to the above: */ -#ifndef O_CREAT -# define O_CREAT 8 /* create file if needed */ -#endif -#ifndef O_EXCL -# define O_EXCL 16 /* file cannot already exist */ -#endif -#ifndef O_TRUNC -# define O_TRUNC 32 /* truncate file on open */ -#endif - -#ifndef O_BINARY -# define O_BINARY 0 -#endif -#ifndef O_DIRECTORY -# define O_DIRECTORY 0 -#endif -#ifndef O_NOATIME -# define O_NOATIME 0 -#endif -#ifndef O_NONBLOCK -# define O_NONBLOCK 0 -#endif - -/* Declare file status routines and bits. */ - -#include - -#if !HAVE_LSTAT && !defined lstat -# define lstat stat -#endif - -#if STX_HIDDEN && !_LARGE_FILES /* AIX */ -# ifdef stat -# undef stat -# endif -# define stat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN) -# ifdef lstat -# undef lstat -# endif -# define lstat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN | STX_LINK) -#endif - -#if STAT_MACROS_BROKEN -# undef S_ISBLK -# undef S_ISCHR -# undef S_ISCTG -# undef S_ISDIR -# undef S_ISFIFO -# undef S_ISLNK -# undef S_ISREG -# undef S_ISSOCK -#endif - -/* On MSDOS, there are missing things from . */ -#if MSDOS -# define S_ISUID 0 -# define S_ISGID 0 -# define S_ISVTX 0 -#endif - -#ifndef S_ISDIR -# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#endif -#ifndef S_ISREG -# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif - -#ifndef S_ISBLK -# ifdef S_IFBLK -# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) -# else -# define S_ISBLK(mode) 0 -# endif -#endif -#ifndef S_ISCHR -# ifdef S_IFCHR -# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) -# else -# define S_ISCHR(mode) 0 -# endif -#endif -#ifndef S_ISCTG -# ifdef S_IFCTG -# define S_ISCTG(mode) (((mode) & S_IFMT) == S_IFCTG) -# else -# define S_ISCTG(mode) 0 -# endif -#endif -#ifndef S_ISDOOR -# define S_ISDOOR(mode) 0 -#endif -#ifndef S_ISFIFO -# ifdef S_IFIFO -# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) -# else -# define S_ISFIFO(mode) 0 -# endif -#endif -#ifndef S_ISLNK -# ifdef S_IFLNK -# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) -# else -# define S_ISLNK(mode) 0 -# endif -#endif -#ifndef S_ISSOCK -# ifdef S_IFSOCK -# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(mode) 0 -# endif -#endif - -#if !HAVE_MKFIFO && !defined mkfifo && defined S_IFIFO -# define mkfifo(file_name, mode) (mknod (file_name, (mode) | S_IFIFO, 0)) -#endif - -#ifndef S_ISUID -# define S_ISUID 0004000 -#endif -#ifndef S_ISGID -# define S_ISGID 0002000 -#endif -#ifndef S_ISVTX -# define S_ISVTX 0001000 -#endif -#ifndef S_IRUSR -# define S_IRUSR 0000400 -#endif -#ifndef S_IWUSR -# define S_IWUSR 0000200 -#endif -#ifndef S_IXUSR -# define S_IXUSR 0000100 -#endif -#ifndef S_IRGRP -# define S_IRGRP 0000040 -#endif -#ifndef S_IWGRP -# define S_IWGRP 0000020 -#endif -#ifndef S_IXGRP -# define S_IXGRP 0000010 -#endif -#ifndef S_IROTH -# define S_IROTH 0000004 -#endif -#ifndef S_IWOTH -# define S_IWOTH 0000002 -#endif -#ifndef S_IXOTH -# define S_IXOTH 0000001 -#endif - -#define MODE_WXUSR (S_IWUSR | S_IXUSR) -#define MODE_R (S_IRUSR | S_IRGRP | S_IROTH) -#define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R) -#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW) -#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX) - -/* Include before any preprocessor test of _POSIX_VERSION. */ -#include - -#ifndef SEEK_SET -# define SEEK_SET 0 -#endif -#ifndef SEEK_CUR -# define SEEK_CUR 1 -#endif -#ifndef SEEK_END -# define SEEK_END 2 -#endif - -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -# define STDOUT_FILENO 1 -#endif -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif - -/* Declare make device, major and minor. Since major is a function on - SVR4, we have to resort to GOT_MAJOR instead of just testing if - major is #define'd. */ - -#if MAJOR_IN_MKDEV -# include -# if !defined(makedev) && defined(mkdev) -# define makedev(a,b) mkdev((a),(b)) -# endif -# define GOT_MAJOR -#endif - -#if MAJOR_IN_SYSMACROS -# include -# define GOT_MAJOR -#endif - -/* Some defines the macros. */ -#ifdef major -# define GOT_MAJOR -#endif - -#ifndef GOT_MAJOR -# if MSDOS -# define major(device) (device) -# define minor(device) (device) -# define makedev(major, minor) (((major) << 8) | (minor)) -# define GOT_MAJOR -# endif -#endif - -/* For HP-UX before HP-UX 8, major/minor are not in . */ -#ifndef GOT_MAJOR -# if defined(hpux) || defined(__hpux__) || defined(__hpux) -# include -# define GOT_MAJOR -# endif -#endif - -#ifndef GOT_MAJOR -# define major(device) (((device) >> 8) & 0xff) -# define minor(device) ((device) & 0xff) -# define makedev(major, minor) (((major) << 8) | (minor)) -#endif - -#undef GOT_MAJOR - -/* Declare wait status. */ - -#if HAVE_SYS_WAIT_H -# include -#endif -#ifndef WEXITSTATUS -# define WEXITSTATUS(s) (((s) >> 8) & 0xff) -#endif -#ifndef WIFSIGNALED -# define WIFSIGNALED(s) (((s) & 0xffff) - 1 < (unsigned) 0xff) -#endif -#ifndef WTERMSIG -# define WTERMSIG(s) ((s) & 0x7f) -#endif - -/* FIXME: It is wrong to use BLOCKSIZE for buffers when the logical block - size is greater than 512 bytes; so ST_BLKSIZE code below, in preparation - for some cleanup in this area, later. */ - -/* Extract or fake data from a `struct stat'. ST_BLKSIZE gives the - optimal I/O blocksize for the file, in bytes. Some systems, like - Sequents, return st_blksize of 0 on pipes. */ - -#define DEFAULT_ST_BLKSIZE 512 - -#if !HAVE_ST_BLKSIZE -# define ST_BLKSIZE(statbuf) DEFAULT_ST_BLKSIZE -#else -# define ST_BLKSIZE(statbuf) \ - ((statbuf).st_blksize > 0 ? (statbuf).st_blksize : DEFAULT_ST_BLKSIZE) -#endif - -/* Extract or fake data from a `struct stat'. ST_NBLOCKS gives the - number of ST_NBLOCKSIZE-byte blocks in the file (including indirect blocks). - HP-UX counts st_blocks in 1024-byte units, - this loses when mixing HP-UX and BSD filesystems with NFS. AIX PS/2 - counts st_blocks in 4K units. */ - -#if !HAVE_ST_BLOCKS -# if defined(_POSIX_SOURCE) || !defined(BSIZE) -# define ST_NBLOCKS(statbuf) ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0)) -# else - off_t st_blocks (); -# define ST_NBLOCKS(statbuf) (st_blocks ((statbuf).st_size)) -# endif -#else -# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks) -# if defined(hpux) || defined(__hpux__) || defined(__hpux) -# define ST_NBLOCKSIZE 1024 -# else -# if defined(_AIX) && defined(_I386) -# define ST_NBLOCKSIZE (4 * 1024) -# endif -# endif -#endif - -#ifndef ST_NBLOCKSIZE -# define ST_NBLOCKSIZE 512 -#endif - -#define ST_IS_SPARSE(st) \ - (ST_NBLOCKS (st) \ - < ((st).st_size / ST_NBLOCKSIZE + ((st).st_size % ST_NBLOCKSIZE != 0))) - -/* Declare standard functions. */ - -#if STDC_HEADERS -# include -#else -void *malloc (); -char *getenv (); -#endif - -#include -#include - -#include -#if !defined _POSIX_VERSION && MSDOS -# include -#endif - -#if WITH_DMALLOC -# define DMALLOC_FUNC_CHECK -# include -#endif - -#include - -#ifndef MB_LEN_MAX -# define MB_LEN_MAX 1 -#endif - -#include - -#include - -#define UINTMAX_STRSIZE_BOUND INT_BUFSIZE_BOUND (uintmax_t) - -/* Prototypes for external functions. */ - -#if HAVE_LOCALE_H -# include -#endif -#if !HAVE_SETLOCALE -# define setlocale(category, locale) /* empty */ -#endif - -#include -#ifdef TIME_WITH_SYS_TIME -# include -#endif - -/* Library modules. */ - -#include -#include -#include -#include -#include - -#include -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - -#if MSDOS -# include -# define SET_BINARY_MODE(arc) setmode(arc, O_BINARY) -# define ERRNO_IS_EACCES errno == EACCES -# define mkdir(file, mode) (mkdir) (file) -# define TTY_NAME "con" -# define sys_reset_uid_gid() -#else -# include -# include -# define SET_BINARY_MODE(arc) -# define ERRNO_IS_EACCES 0 -# define TTY_NAME "/dev/tty" -# define sys_reset_uid_gid() \ - do { setuid (getuid ()); setgid (getgid ()); } while (0) -#endif - -#if XENIX -# include -#endif diff --git a/contrib/cpio/lib/umaxtostr.c b/contrib/cpio/lib/umaxtostr.c deleted file mode 100644 index 4f49a7f8ddd..00000000000 --- a/contrib/cpio/lib/umaxtostr.c +++ /dev/null @@ -1,3 +0,0 @@ -#define inttostr umaxtostr -#define inttype uintmax_t -#include "inttostr.c" diff --git a/contrib/cpio/lib/unlocked-io.h b/contrib/cpio/lib/unlocked-io.h deleted file mode 100644 index d00930361c2..00000000000 --- a/contrib/cpio/lib/unlocked-io.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Prefer faster, non-thread-safe stdio functions if available. - - Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#ifndef UNLOCKED_IO_H -# define UNLOCKED_IO_H 1 - -/* These are wrappers for functions/macros from the GNU C library, and - from other C libraries supporting POSIX's optional thread-safe functions. - - The standard I/O functions are thread-safe. These *_unlocked ones are - more efficient but not thread-safe. That they're not thread-safe is - fine since all of the applications in this package are single threaded. - - Also, some code that is shared with the GNU C library may invoke - the *_unlocked functions directly. On hosts that lack those - functions, invoke the non-thread-safe versions instead. */ - -# include - -# if HAVE_DECL_CLEARERR_UNLOCKED -# undef clearerr -# define clearerr(x) clearerr_unlocked (x) -# else -# define clearerr_unlocked(x) clearerr (x) -# endif - -# if HAVE_DECL_FEOF_UNLOCKED -# undef feof -# define feof(x) feof_unlocked (x) -# else -# define feof_unlocked(x) feof (x) -# endif - -# if HAVE_DECL_FERROR_UNLOCKED -# undef ferror -# define ferror(x) ferror_unlocked (x) -# else -# define ferror_unlocked(x) ferror (x) -# endif - -# if HAVE_DECL_FFLUSH_UNLOCKED -# undef fflush -# define fflush(x) fflush_unlocked (x) -# else -# define fflush_unlocked(x) fflush (x) -# endif - -# if HAVE_DECL_FGETS_UNLOCKED -# undef fgets -# define fgets(x,y,z) fgets_unlocked (x,y,z) -# else -# define fgets_unlocked(x,y,z) fgets (x,y,z) -# endif - -# if HAVE_DECL_FPUTC_UNLOCKED -# undef fputc -# define fputc(x,y) fputc_unlocked (x,y) -# else -# define fputc_unlocked(x,y) fputc (x,y) -# endif - -# if HAVE_DECL_FPUTS_UNLOCKED -# undef fputs -# define fputs(x,y) fputs_unlocked (x,y) -# else -# define fputs_unlocked(x,y) fputs (x,y) -# endif - -# if HAVE_DECL_FREAD_UNLOCKED -# undef fread -# define fread(w,x,y,z) fread_unlocked (w,x,y,z) -# else -# define fread_unlocked(w,x,y,z) fread (w,x,y,z) -# endif - -# if HAVE_DECL_FWRITE_UNLOCKED -# undef fwrite -# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z) -# else -# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) -# endif - -# if HAVE_DECL_GETC_UNLOCKED -# undef getc -# define getc(x) getc_unlocked (x) -# else -# define getc_unlocked(x) getc (x) -# endif - -# if HAVE_DECL_GETCHAR_UNLOCKED -# undef getchar -# define getchar() getchar_unlocked () -# else -# define getchar_unlocked() getchar () -# endif - -# if HAVE_DECL_PUTC_UNLOCKED -# undef putc -# define putc(x,y) putc_unlocked (x,y) -# else -# define putc_unlocked(x,y) putc (x,y) -# endif - -# if HAVE_DECL_PUTCHAR_UNLOCKED -# undef putchar -# define putchar(x) putchar_unlocked (x) -# else -# define putchar_unlocked(x) putchar (x) -# endif - -# undef flockfile -# define flockfile(x) ((void) 0) - -# undef ftrylockfile -# define ftrylockfile(x) 0 - -# undef funlockfile -# define funlockfile(x) ((void) 0) - -#endif /* UNLOCKED_IO_H */ diff --git a/contrib/cpio/lib/utimens.c b/contrib/cpio/lib/utimens.c deleted file mode 100644 index 7e3175a4951..00000000000 --- a/contrib/cpio/lib/utimens.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Set file access and modification times. - - Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -/* derived from a function in touch.c */ - -#include - -#include "utimens.h" - -#include -#include -#include -#include - -#if HAVE_UTIME_H -# include -#endif - -/* Some systems (even some that do have ) don't declare this - structure anywhere. */ -#ifndef HAVE_STRUCT_UTIMBUF -struct utimbuf -{ - long actime; - long modtime; -}; -#endif - -/* Some systems don't have ENOSYS. */ -#ifndef ENOSYS -# ifdef ENOTSUP -# define ENOSYS ENOTSUP -# else -/* Some systems don't have ENOTSUP either. */ -# define ENOSYS EINVAL -# endif -#endif - -#ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) -# endif -#endif - -#ifndef ATTRIBUTE_UNUSED -# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif - -/* Set the access and modification time stamps of FD (a.k.a. FILE) to be - TIMESPEC[0] and TIMESPEC[1], respectively. - FD must be either negative -- in which case it is ignored -- - or a file descriptor that is open on FILE. - If FD is nonnegative, then FILE can be NULL, which means - use just futimes (or equivalent) instead of utimes (or equivalent), - and fail if on an old system without futimes (or equivalent). - If TIMESPEC is null, set the time stamps to the current time. - Return 0 on success, -1 (setting errno) on failure. */ - -int -gl_futimens (int fd ATTRIBUTE_UNUSED, - char const *file, struct timespec const timespec[2]) -{ - /* Some Linux-based NFS clients are buggy, and mishandle time stamps - of files in NFS file systems in some cases. We have no - configure-time test for this, but please see - for references to - some of the problems with Linux 2.6.16. If this affects you, - compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to - help in some cases, albeit at a cost in performance. But you - really should upgrade your kernel to a fixed version, since the - problem affects many applications. */ - -#if HAVE_BUGGY_NFS_TIME_STAMPS - if (fd < 0) - sync (); - else - fsync (fd); -#endif - - /* There's currently no interface to set file timestamps with - nanosecond resolution, so do the best we can, discarding any - fractional part of the timestamp. */ -#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES - struct timeval timeval[2]; - struct timeval const *t; - if (timespec) - { - timeval[0].tv_sec = timespec[0].tv_sec; - timeval[0].tv_usec = timespec[0].tv_nsec / 1000; - timeval[1].tv_sec = timespec[1].tv_sec; - timeval[1].tv_usec = timespec[1].tv_nsec / 1000; - t = timeval; - } - else - t = NULL; - - - if (fd < 0) - { -# if HAVE_FUTIMESAT - return futimesat (AT_FDCWD, file, t); -# endif - } - else - { - /* If futimesat or futimes fails here, don't try to speed things - up by returning right away. glibc can incorrectly fail with - errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0 - in high security mode doesn't allow ordinary users to read - /proc/self, so glibc incorrectly fails with errno == EACCES. - If errno == EIO, EPERM, or EROFS, it's probably safe to fail - right away, but these cases are rare enough that they're not - worth optimizing, and who knows what other messed-up systems - are out there? So play it safe and fall back on the code - below. */ -# if HAVE_FUTIMESAT - if (futimesat (fd, NULL, t) == 0) - return 0; -# elif HAVE_FUTIMES - if (futimes (fd, t) == 0) - return 0; -# endif - } -#endif - - if (!file) - { -#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) - errno = ENOSYS; -#endif - - /* Prefer EBADF to ENOSYS if both error numbers apply. */ - if (errno == ENOSYS) - { - int fd2 = dup (fd); - int dup_errno = errno; - if (0 <= fd2) - close (fd2); - errno = (fd2 < 0 && dup_errno == EBADF ? EBADF : ENOSYS); - } - - return -1; - } - -#if HAVE_WORKING_UTIMES - return utimes (file, t); -#else - { - struct utimbuf utimbuf; - struct utimbuf const *ut; - if (timespec) - { - utimbuf.actime = timespec[0].tv_sec; - utimbuf.modtime = timespec[1].tv_sec; - ut = &utimbuf; - } - else - ut = NULL; - - return utime (file, ut); - } -#endif -} - -/* Set the access and modification time stamps of FILE to be - TIMESPEC[0] and TIMESPEC[1], respectively. */ -int -utimens (char const *file, struct timespec const timespec[2]) -{ - return gl_futimens (-1, file, timespec); -} diff --git a/contrib/cpio/lib/utimens.h b/contrib/cpio/lib/utimens.h deleted file mode 100644 index 169521da73a..00000000000 --- a/contrib/cpio/lib/utimens.h +++ /dev/null @@ -1,3 +0,0 @@ -#include -int gl_futimens (int, char const *, struct timespec const [2]); -int utimens (char const *, struct timespec const [2]); diff --git a/contrib/cpio/lib/xalloc-die.c b/contrib/cpio/lib/xalloc-die.c deleted file mode 100644 index 090f060df78..00000000000 --- a/contrib/cpio/lib/xalloc-die.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Report a memory allocation failure and exit. - - Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2006 Free - Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "xalloc.h" - -#include - -#include "error.h" -#include "exitfail.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -void -xalloc_die (void) -{ - error (exit_failure, 0, "%s", _("memory exhausted")); - - /* The `noreturn' cannot be given to error, since it may return if - its first argument is 0. To help compilers understand the - xalloc_die does not return, call abort. Also, the abort is a - safety feature if exit_failure is 0 (which shouldn't happen). */ - abort (); -} diff --git a/contrib/cpio/lib/xalloc.h b/contrib/cpio/lib/xalloc.h deleted file mode 100644 index 0c6d8dcf508..00000000000 --- a/contrib/cpio/lib/xalloc.h +++ /dev/null @@ -1,271 +0,0 @@ -/* xalloc.h -- malloc with out-of-memory checking - - Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef XALLOC_H_ -# define XALLOC_H_ - -# include - - -# ifdef __cplusplus -extern "C" { -# endif - - -# ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) -# endif -# endif - -# ifndef ATTRIBUTE_NORETURN -# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) -# endif - -/* This function is always triggered when memory is exhausted. - It must be defined by the application, either explicitly - or by using gnulib's xalloc-die module. This is the - function to call when one wants the program to die because of a - memory allocation failure. */ -extern void xalloc_die (void) ATTRIBUTE_NORETURN; - -void *xmalloc (size_t s); -void *xzalloc (size_t s); -void *xcalloc (size_t n, size_t s); -void *xrealloc (void *p, size_t s); -void *x2realloc (void *p, size_t *pn); -void *xmemdup (void const *p, size_t s); -char *xstrdup (char const *str); - -/* Return 1 if an array of N objects, each of size S, cannot exist due - to size arithmetic overflow. S must be positive and N must be - nonnegative. This is a macro, not an inline function, so that it - works correctly even when SIZE_MAX < N. - - By gnulib convention, SIZE_MAX represents overflow in size - calculations, so the conservative dividend to use here is - SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value. - However, malloc (SIZE_MAX) fails on all known hosts where - sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for - exactly-SIZE_MAX allocations on such hosts; this avoids a test and - branch when S is known to be 1. */ -# define xalloc_oversized(n, s) \ - ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) - - -/* In the following macros, T must be an elementary or structure/union or - typedef'ed type, or a pointer to such a type. To apply one of the - following macros to a function pointer or array type, you need to typedef - it first and use the typedef name. */ - -/* Allocate an object of type T dynamically, with error checking. */ -/* extern t *XMALLOC (typename t); */ -# define XMALLOC(t) ((t *) xmalloc (sizeof (t))) - -/* Allocate memory for N elements of type T, with error checking. */ -/* extern t *XNMALLOC (size_t n, typename t); */ -# define XNMALLOC(n, t) \ - ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))) - -/* Allocate an object of type T dynamically, with error checking, - and zero it. */ -/* extern t *XZALLOC (typename t); */ -# define XZALLOC(t) ((t *) xzalloc (sizeof (t))) - -/* Allocate memory for N elements of type T, with error checking, - and zero it. */ -/* extern t *XCALLOC (size_t n, typename t); */ -# define XCALLOC(n, t) \ - ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) - - -# if HAVE_INLINE -# define static_inline static inline -# else - void *xnmalloc (size_t n, size_t s); - void *xnrealloc (void *p, size_t n, size_t s); - void *x2nrealloc (void *p, size_t *pn, size_t s); - char *xcharalloc (size_t n); -# endif - -# ifdef static_inline - -/* Allocate an array of N objects, each with S bytes of memory, - dynamically, with error checking. S must be nonzero. */ - -static_inline void * -xnmalloc (size_t n, size_t s) -{ - if (xalloc_oversized (n, s)) - xalloc_die (); - return xmalloc (n * s); -} - -/* Change the size of an allocated block of memory P to an array of N - objects each of S bytes, with error checking. S must be nonzero. */ - -static_inline void * -xnrealloc (void *p, size_t n, size_t s) -{ - if (xalloc_oversized (n, s)) - xalloc_die (); - return xrealloc (p, n * s); -} - -/* If P is null, allocate a block of at least *PN such objects; - otherwise, reallocate P so that it contains more than *PN objects - each of S bytes. *PN must be nonzero unless P is null, and S must - be nonzero. Set *PN to the new number of objects, and return the - pointer to the new block. *PN is never set to zero, and the - returned pointer is never null. - - Repeated reallocations are guaranteed to make progress, either by - allocating an initial block with a nonzero size, or by allocating a - larger block. - - In the following implementation, nonzero sizes are increased by a - factor of approximately 1.5 so that repeated reallocations have - O(N) overall cost rather than O(N**2) cost, but the - specification for this function does not guarantee that rate. - - Here is an example of use: - - int *p = NULL; - size_t used = 0; - size_t allocated = 0; - - void - append_int (int value) - { - if (used == allocated) - p = x2nrealloc (p, &allocated, sizeof *p); - p[used++] = value; - } - - This causes x2nrealloc to allocate a block of some nonzero size the - first time it is called. - - To have finer-grained control over the initial size, set *PN to a - nonzero value before calling this function with P == NULL. For - example: - - int *p = NULL; - size_t used = 0; - size_t allocated = 0; - size_t allocated1 = 1000; - - void - append_int (int value) - { - if (used == allocated) - { - p = x2nrealloc (p, &allocated1, sizeof *p); - allocated = allocated1; - } - p[used++] = value; - } - - */ - -static_inline void * -x2nrealloc (void *p, size_t *pn, size_t s) -{ - size_t n = *pn; - - if (! p) - { - if (! n) - { - /* The approximate size to use for initial small allocation - requests, when the invoking code specifies an old size of - zero. 64 bytes is the largest "small" request for the - GNU C library malloc. */ - enum { DEFAULT_MXFAST = 64 }; - - n = DEFAULT_MXFAST / s; - n += !n; - } - } - else - { - /* Set N = ceil (1.5 * N) so that progress is made if N == 1. - Check for overflow, so that N * S stays in size_t range. - The check is slightly conservative, but an exact check isn't - worth the trouble. */ - if ((size_t) -1 / 3 * 2 / s <= n) - xalloc_die (); - n += (n + 1) / 2; - } - - *pn = n; - return xrealloc (p, n * s); -} - -/* Return a pointer to a new buffer of N bytes. This is like xmalloc, - except it returns char *. */ - -static_inline char * -xcharalloc (size_t n) -{ - return XNMALLOC (n, char); -} - -# endif - -# ifdef __cplusplus -} - -/* C++ does not allow conversions from void * to other pointer types - without a cast. Use templates to work around the problem when - possible. */ - -template inline T * -xrealloc (T *p, size_t s) -{ - return (T *) xrealloc ((void *) p, s); -} - -template inline T * -xnrealloc (T *p, size_t n, size_t s) -{ - return (T *) xnrealloc ((void *) p, n, s); -} - -template inline T * -x2realloc (T *p, size_t *pn) -{ - return (T *) x2realloc ((void *) p, pn); -} - -template inline T * -x2nrealloc (T *p, size_t *pn, size_t s) -{ - return (T *) x2nrealloc ((void *) p, pn, s); -} - -template inline T * -xmemdup (T const *p, size_t s) -{ - return (T *) xmemdup ((void const *) p, s); -} - -# endif - - -#endif /* !XALLOC_H_ */ diff --git a/contrib/cpio/lib/xmalloc.c b/contrib/cpio/lib/xmalloc.c deleted file mode 100644 index 318e0ddb5a7..00000000000 --- a/contrib/cpio/lib/xmalloc.c +++ /dev/null @@ -1,123 +0,0 @@ -/* xmalloc.c -- malloc with out of memory checking - - Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, - Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#if ! HAVE_INLINE -# define static_inline -#endif -#include "xalloc.h" -#undef static_inline - -#include -#include - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* 1 if calloc is known to be compatible with GNU calloc. This - matters if we are not also using the calloc module, which defines - HAVE_CALLOC and supports the GNU API even on non-GNU platforms. */ -#if defined HAVE_CALLOC || defined __GLIBC__ -enum { HAVE_GNU_CALLOC = 1 }; -#else -enum { HAVE_GNU_CALLOC = 0 }; -#endif - -/* Allocate N bytes of memory dynamically, with error checking. */ - -void * -xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p && n != 0) - xalloc_die (); - return p; -} - -/* Change the size of an allocated block of memory P to N bytes, - with error checking. */ - -void * -xrealloc (void *p, size_t n) -{ - p = realloc (p, n); - if (!p && n != 0) - xalloc_die (); - return p; -} - -/* If P is null, allocate a block of at least *PN bytes; otherwise, - reallocate P so that it contains more than *PN bytes. *PN must be - nonzero unless P is null. Set *PN to the new block's size, and - return the pointer to the new block. *PN is never set to zero, and - the returned pointer is never null. */ - -void * -x2realloc (void *p, size_t *pn) -{ - return x2nrealloc (p, pn, 1); -} - -/* Allocate S bytes of zeroed memory dynamically, with error checking. - There's no need for xnzalloc (N, S), since it would be equivalent - to xcalloc (N, S). */ - -void * -xzalloc (size_t s) -{ - return memset (xmalloc (s), 0, s); -} - -/* Allocate zeroed memory for N elements of S bytes, with error - checking. S must be nonzero. */ - -void * -xcalloc (size_t n, size_t s) -{ - void *p; - /* Test for overflow, since some calloc implementations don't have - proper overflow checks. But omit overflow and size-zero tests if - HAVE_GNU_CALLOC, since GNU calloc catches overflow and never - returns NULL if successful. */ - if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s)) - || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0))) - xalloc_die (); - return p; -} - -/* Clone an object P of size S, with error checking. There's no need - for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any - need for an arithmetic overflow check. */ - -void * -xmemdup (void const *p, size_t s) -{ - return memcpy (xmalloc (s), p, s); -} - -/* Clone STRING. */ - -char * -xstrdup (char const *string) -{ - return xmemdup (string, strlen (string) + 1); -} diff --git a/contrib/cpio/lib/xstrndup.c b/contrib/cpio/lib/xstrndup.c deleted file mode 100644 index 7ccefd798a0..00000000000 --- a/contrib/cpio/lib/xstrndup.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Duplicate a bounded initial segment of a string, with out-of-memory - checking. - Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include "xstrndup.h" - -#include -#include "xalloc.h" - -/* Return a newly allocated copy of at most N bytes of STRING. - In other words, return a copy of the initial segment of length N of - STRING. */ -char * -xstrndup (const char *string, size_t n) -{ - char *s = strndup (string, n); - if (! s) - xalloc_die (); - return s; -} diff --git a/contrib/cpio/lib/xstrndup.h b/contrib/cpio/lib/xstrndup.h deleted file mode 100644 index 88354cfd43a..00000000000 --- a/contrib/cpio/lib/xstrndup.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Duplicate a bounded initial segment of a string, with out-of-memory - checking. - Copyright (C) 2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Return a newly allocated copy of at most N bytes of STRING. - In other words, return a copy of the initial segment of length N of - STRING. */ -extern char *xstrndup (const char *string, size_t n); diff --git a/contrib/cpio/src/copyin.c b/contrib/cpio/src/copyin.c deleted file mode 100644 index 56591362325..00000000000 --- a/contrib/cpio/src/copyin.c +++ /dev/null @@ -1,1644 +0,0 @@ -/* $FreeBSD$ */ - -/* copyin.c - extract or list a cpio archive - Copyright (C) 1990,1991,1992,2001,2002,2003,2004, - 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#include - -#include -#include -#include -#include "filetypes.h" -#include "cpiohdr.h" -#include "dstring.h" -#include "extern.h" -#include "defer.h" -#include "dirname.h" -#include -#ifndef FNM_PATHNAME -# include -#endif -#include - -#ifndef HAVE_LCHOWN -# define lchown(f,u,g) 0 -#endif - -static void copyin_regular_file(struct cpio_file_stat* file_hdr, - int in_file_des); - -void -warn_junk_bytes (long bytes_skipped) -{ - error (0, 0, ngettext ("warning: skipped %ld byte of junk", - "warning: skipped %ld bytes of junk", bytes_skipped), - bytes_skipped); -} - - -static int -query_rename(struct cpio_file_stat* file_hdr, FILE *tty_in, FILE *tty_out, - FILE *rename_in) -{ - char *str_res; /* Result for string function. */ - static dynamic_string new_name; /* New file name for rename option. */ - static int initialized_new_name = false; - if (!initialized_new_name) - { - ds_init (&new_name, 128); - initialized_new_name = true; - } - - if (rename_flag) - { - fprintf (tty_out, _("rename %s -> "), file_hdr->c_name); - fflush (tty_out); - str_res = ds_fgets (tty_in, &new_name); - } - else - { - str_res = ds_fgetstr (rename_in, &new_name, '\n'); - } - if (str_res == NULL || str_res[0] == 0) - { - return -1; - } - else - /* Debian hack: file_hrd.c_name is sometimes set to - point to static memory by code in tar.c. This - causes a segfault. This has been fixed and an - additional check to ensure that the file name - is not too long has been added. (Reported by - Horst Knobloch.) This bug has been reported to - "bug-gnu-utils@prep.ai.mit.edu". (99/1/6) -BEM */ - { - if (archive_format != arf_tar && archive_format != arf_ustar) - { - free (file_hdr->c_name); - file_hdr->c_name = xstrdup (new_name.ds_string); - } - else - { - if (is_tar_filename_too_long (new_name.ds_string)) - error (0, 0, _("%s: file name too long"), - new_name.ds_string); - else - strcpy (file_hdr->c_name, new_name.ds_string); - } - } - return 0; -} - -/* Skip the padding on IN_FILE_DES after a header or file, - up to the next header. - The number of bytes skipped is based on OFFSET -- the current offset - from the last start of a header (or file) -- and the current - header type. */ - -static void -tape_skip_padding (int in_file_des, int offset) -{ - int pad; - - if (archive_format == arf_crcascii || archive_format == arf_newascii) - pad = (4 - (offset % 4)) % 4; - else if (archive_format == arf_binary || archive_format == arf_hpbinary) - pad = (2 - (offset % 2)) % 2; - else if (archive_format == arf_tar || archive_format == arf_ustar) - pad = (512 - (offset % 512)) % 512; - else - pad = 0; - - if (pad != 0) - tape_toss_input (in_file_des, pad); -} - - -static void -list_file(struct cpio_file_stat* file_hdr, int in_file_des) -{ - if (verbose_flag) - { -#ifdef CP_IFLNK - if ((file_hdr->c_mode & CP_IFMT) == CP_IFLNK) - { - if (archive_format != arf_tar && archive_format != arf_ustar) - { - char *link_name = NULL; /* Name of hard and symbolic links. */ - - link_name = (char *) xmalloc ((unsigned int) file_hdr->c_filesize + 1); - link_name[file_hdr->c_filesize] = '\0'; - tape_buffered_read (link_name, in_file_des, file_hdr->c_filesize); - long_format (file_hdr, link_name); - free (link_name); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - return; - } - else - { - long_format (file_hdr, file_hdr->c_tar_linkname); - return; - } - } - else -#endif - long_format (file_hdr, (char *) 0); - } - else - { - /* Debian hack: Modified to print a list of filenames - terminiated by a null character when the -t and -0 - flags are used. This has been submitted as a - suggestion to "bug-gnu-utils@prep.ai.mit.edu". -BEM */ - printf ("%s%c", file_hdr->c_name, name_end); - } - - crc = 0; - tape_toss_input (in_file_des, file_hdr->c_filesize); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - if (only_verify_crc_flag) - { -#ifdef CP_IFLNK - if ((file_hdr->c_mode & CP_IFMT) == CP_IFLNK) - { - return; /* links don't have a checksum */ - } -#endif - if (crc != file_hdr->c_chksum) - { - error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"), - file_hdr->c_name, crc, file_hdr->c_chksum); - } - } -} - -static int -try_existing_file (struct cpio_file_stat* file_hdr, int in_file_des, - int *existing_dir) -{ - struct stat file_stat; - - *existing_dir = false; - if (lstat (file_hdr->c_name, &file_stat) == 0) - { - if (S_ISDIR (file_stat.st_mode) - && ((file_hdr->c_mode & CP_IFMT) == CP_IFDIR)) - { - /* If there is already a directory there that - we are trying to create, don't complain about - it. */ - *existing_dir = true; - return 0; - } - else if (!unconditional_flag - && file_hdr->c_mtime <= file_stat.st_mtime) - { - error (0, 0, _("%s not created: newer or same age version exists"), - file_hdr->c_name); - tape_toss_input (in_file_des, file_hdr->c_filesize); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - return -1; /* Go to the next file. */ - } - else if (S_ISDIR (file_stat.st_mode) - ? rmdir (file_hdr->c_name) - : unlink (file_hdr->c_name)) - { - error (0, errno, _("cannot remove current %s"), - file_hdr->c_name); - tape_toss_input (in_file_des, file_hdr->c_filesize); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - return -1; /* Go to the next file. */ - } - } - return 0; -} - -/* The newc and crc formats store multiply linked copies of the same file - in the archive only once. The actual data is attached to the last link - in the archive, and the other links all have a filesize of 0. When a - file in the archive has multiple links and a filesize of 0, its data is - probably "attatched" to another file in the archive, so we can't create - it right away. We have to "defer" creating it until we have created - the file that has the data "attatched" to it. We keep a list of the - "defered" links on deferments. */ - -struct deferment *deferments = NULL; - -/* Add a file header to the deferments list. For now they all just - go on one list, although we could optimize this if necessary. */ - -static void -defer_copyin (struct cpio_file_stat *file_hdr) -{ - struct deferment *d; - d = create_deferment (file_hdr); - d->next = deferments; - deferments = d; - return; -} - -/* We just created a file that (probably) has some other links to it - which have been defered. Go through all of the links on the deferments - list and create any which are links to this file. */ - -static void -create_defered_links (struct cpio_file_stat *file_hdr) -{ - struct deferment *d; - struct deferment *d_prev; - int ino; - int maj; - int min; - int link_res; - ino = file_hdr->c_ino; - maj = file_hdr->c_dev_maj; - min = file_hdr->c_dev_min; - d = deferments; - d_prev = NULL; - while (d != NULL) - { - if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj) - && (d->header.c_dev_min == min) ) - { - struct deferment *d_free; - link_res = link_to_name (d->header.c_name, file_hdr->c_name); - if (link_res < 0) - { - error (0, errno, _("cannot link %s to %s"), - d->header.c_name, file_hdr->c_name); - } - if (d_prev != NULL) - d_prev->next = d->next; - else - deferments = d->next; - d_free = d; - d = d->next; - free_deferment (d_free); - } - else - { - d_prev = d; - d = d->next; - } - } -} - -/* We are skipping a file but there might be other links to it that we - did not skip, so we have to copy its data for the other links. Find - the first link that we didn't skip and try to create that. That will - then create the other deferred links. */ - -static int -create_defered_links_to_skipped (struct cpio_file_stat *file_hdr, - int in_file_des) -{ - struct deferment *d; - struct deferment *d_prev; - int ino; - int maj; - int min; - if (file_hdr->c_filesize == 0) - { - /* The file doesn't have any data attached to it so we don't have - to bother. */ - return -1; - } - ino = file_hdr->c_ino; - maj = file_hdr->c_dev_maj; - min = file_hdr->c_dev_min; - d = deferments; - d_prev = NULL; - while (d != NULL) - { - if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj) - && (d->header.c_dev_min == min) ) - { - if (d_prev != NULL) - d_prev->next = d->next; - else - deferments = d->next; - free (file_hdr->c_name); - file_hdr->c_name = xstrdup(d->header.c_name); - free_deferment (d); - copyin_regular_file(file_hdr, in_file_des); - return 0; - } - else - { - d_prev = d; - d = d->next; - } - } - return -1; -} - -/* If we had a multiply linked file that really was empty then we would - have defered all of its links, since we never found any with data - "attached", and they will still be on the deferment list even when - we are done reading the whole archive. Write out all of these - empty links that are still on the deferments list. */ - -static void -create_final_defers () -{ - struct deferment *d; - int link_res; - int out_file_des; - - for (d = deferments; d != NULL; d = d->next) - { - /* Debian hack: A line, which could cause an endless loop, was - removed (97/1/2). It was reported by Ronald F. Guilmette to - the upstream maintainers. -BEM */ - /* Debian hack: This was reported by Horst Knobloch. This bug has - been reported to "bug-gnu-utils@prep.ai.mit.edu". (99/1/6) -BEM - */ - link_res = link_to_maj_min_ino (d->header.c_name, - d->header.c_dev_maj, d->header.c_dev_min, - d->header.c_ino); - if (link_res == 0) - { - continue; - } - out_file_des = open (d->header.c_name, - O_CREAT | O_WRONLY | O_BINARY, 0600); - if (out_file_des < 0 && create_dir_flag) - { - create_all_directories (d->header.c_name); - out_file_des = open (d->header.c_name, - O_CREAT | O_WRONLY | O_BINARY, - 0600); - } - if (out_file_des < 0) - { - open_error (d->header.c_name); - continue; - } - - set_perms (out_file_des, &d->header); - - if (close (out_file_des) < 0) - close_error (d->header.c_name); - - } -} - -static void -copyin_regular_file (struct cpio_file_stat* file_hdr, int in_file_des) -{ - int out_file_des; /* Output file descriptor. */ - - if (to_stdout_option) - out_file_des = STDOUT_FILENO; - else - { - /* Can the current file be linked to a previously copied file? */ - if (file_hdr->c_nlink > 1 - && (archive_format == arf_newascii - || archive_format == arf_crcascii) ) - { - int link_res; - if (file_hdr->c_filesize == 0) - { - /* The newc and crc formats store multiply linked copies - of the same file in the archive only once. The - actual data is attached to the last link in the - archive, and the other links all have a filesize - of 0. Since this file has multiple links and a - filesize of 0, its data is probably attatched to - another file in the archive. Save the link, and - process it later when we get the actual data. We - can't just create it with length 0 and add the - data later, in case the file is readonly. We still - lose if its parent directory is readonly (and we aren't - running as root), but there's nothing we can do about - that. */ - defer_copyin (file_hdr); - tape_toss_input (in_file_des, file_hdr->c_filesize); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - return; - } - /* If the file has data (filesize != 0), then presumably - any other links have already been defer_copyin'ed(), - but GNU cpio version 2.0-2.2 didn't do that, so we - still have to check for links here (and also in case - the archive was created and later appeneded to). */ - /* Debian hack: (97/1/2) This was reported by Ronald - F. Guilmette to the upstream maintainers. -BEM */ - link_res = link_to_maj_min_ino (file_hdr->c_name, - file_hdr->c_dev_maj, file_hdr->c_dev_min, - file_hdr->c_ino); - if (link_res == 0) - { - tape_toss_input (in_file_des, file_hdr->c_filesize); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - return; - } - } - else if (file_hdr->c_nlink > 1 - && archive_format != arf_tar - && archive_format != arf_ustar) - { - int link_res; - /* Debian hack: (97/1/2) This was reported by Ronald - F. Guilmette to the upstream maintainers. -BEM */ - link_res = link_to_maj_min_ino (file_hdr->c_name, - file_hdr->c_dev_maj, - file_hdr->c_dev_min, - file_hdr->c_ino); - if (link_res == 0) - { - tape_toss_input (in_file_des, file_hdr->c_filesize); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - return; - } - } - else if ((archive_format == arf_tar || archive_format == arf_ustar) - && file_hdr->c_tar_linkname - && file_hdr->c_tar_linkname[0] != '\0') - { - int link_res; - link_res = link_to_name (file_hdr->c_name, file_hdr->c_tar_linkname); - if (link_res < 0) - { - error (0, errno, _("cannot link %s to %s"), - file_hdr->c_tar_linkname, file_hdr->c_name); - } - return; - } - - /* If not linked, copy the contents of the file. */ - out_file_des = open (file_hdr->c_name, - O_CREAT | O_WRONLY | O_BINARY, 0600); - - if (out_file_des < 0 && create_dir_flag) - { - create_all_directories (file_hdr->c_name); - out_file_des = open (file_hdr->c_name, - O_CREAT | O_WRONLY | O_BINARY, - 0600); - } - - if (out_file_des < 0) - { - open_error (file_hdr->c_name); - tape_toss_input (in_file_des, file_hdr->c_filesize); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - return; - } - } - - crc = 0; - if (swap_halfwords_flag) - { - if ((file_hdr->c_filesize % 4) == 0) - swapping_halfwords = true; - else - error (0, 0, _("cannot swap halfwords of %s: odd number of halfwords"), - file_hdr->c_name); - } - if (swap_bytes_flag) - { - if ((file_hdr->c_filesize % 2) == 0) - swapping_bytes = true; - else - error (0, 0, _("cannot swap bytes of %s: odd number of bytes"), - file_hdr->c_name); - } - copy_files_tape_to_disk (in_file_des, out_file_des, file_hdr->c_filesize); - disk_empty_output_buffer (out_file_des); - - if (to_stdout_option) - { - if (archive_format == arf_crcascii) - { - if (crc != file_hdr->c_chksum) - error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"), - file_hdr->c_name, crc, file_hdr->c_chksum); - } - tape_skip_padding (in_file_des, file_hdr->c_filesize); - return; - } - - /* Debian hack to fix a bug in the --sparse option. - This bug has been reported to - "bug-gnu-utils@prep.ai.mit.edu". (96/7/10) -BEM */ - if (delayed_seek_count > 0) - { - lseek (out_file_des, delayed_seek_count-1, SEEK_CUR); - write (out_file_des, "", 1); - delayed_seek_count = 0; - } - - set_perms (out_file_des, file_hdr); - - if (close (out_file_des) < 0) - close_error (file_hdr->c_name); - - if (archive_format == arf_crcascii) - { - if (crc != file_hdr->c_chksum) - error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"), - file_hdr->c_name, crc, file_hdr->c_chksum); - } - - tape_skip_padding (in_file_des, file_hdr->c_filesize); - if (file_hdr->c_nlink > 1 - && (archive_format == arf_newascii || archive_format == arf_crcascii) ) - { - /* (see comment above for how the newc and crc formats - store multiple links). Now that we have the data - for this file, create any other links to it which - we defered. */ - create_defered_links (file_hdr); - } -} - -static void -copyin_directory (struct cpio_file_stat *file_hdr, int existing_dir) -{ - int res; /* Result of various function calls. */ -#ifdef HPUX_CDF - int cdf_flag; /* True if file is a CDF. */ - int cdf_char; /* Index of `+' char indicating a CDF. */ -#endif - - if (to_stdout_option) - return; - - /* Strip any trailing `/'s off the filename; tar puts - them on. We might as well do it here in case anybody - else does too, since they cause strange things to happen. */ - strip_trailing_slashes (file_hdr->c_name); - - /* Ignore the current directory. It must already exist, - and we don't want to change its permission, ownership - or time. */ - if (file_hdr->c_name[0] == '.' && file_hdr->c_name[1] == '\0') - { - return; - } - -#ifdef HPUX_CDF - cdf_flag = 0; -#endif - if (!existing_dir) - - { -#ifdef HPUX_CDF - /* If the directory name ends in a + and is SUID, - then it is a CDF. Strip the trailing + from - the name before creating it. */ - cdf_char = strlen (file_hdr->c_name) - 1; - if ( (cdf_char > 0) && - (file_hdr->c_mode & 04000) && - (file_hdr->c_name [cdf_char] == '+') ) - { - file_hdr->c_name [cdf_char] = '\0'; - cdf_flag = 1; - } -#endif - res = mkdir (file_hdr->c_name, file_hdr->c_mode); - } - else - res = 0; - if (res < 0 && create_dir_flag) - { - create_all_directories (file_hdr->c_name); - res = mkdir (file_hdr->c_name, file_hdr->c_mode); - } - if (res < 0) - { - /* In some odd cases where the file_hdr->c_name includes `.', - the directory may have actually been created by - create_all_directories(), so the mkdir will fail - because the directory exists. If that's the case, - don't complain about it. */ - struct stat file_stat; - if (errno != EEXIST) - { - mkdir_error (file_hdr->c_name); - return; - } - if (lstat (file_hdr->c_name, &file_stat)) - { - stat_error (file_hdr->c_name); - return; - } - if (!(S_ISDIR (file_stat.st_mode))) - { - error (0, 0, _("%s is not a directory"), - quotearg_colon (file_hdr->c_name)); - return; - } - } - - set_perms (-1, file_hdr); -} - -static void -copyin_device (struct cpio_file_stat* file_hdr) -{ - int res; /* Result of various function calls. */ - - if (to_stdout_option) - return; - - if (file_hdr->c_nlink > 1 && archive_format != arf_tar - && archive_format != arf_ustar) - { - int link_res; - /* Debian hack: This was reported by Horst - Knobloch. This bug has been reported to - "bug-gnu-utils@prep.ai.mit.edu". (99/1/6) -BEM */ - link_res = link_to_maj_min_ino (file_hdr->c_name, - file_hdr->c_dev_maj, file_hdr->c_dev_min, - file_hdr->c_ino); - if (link_res == 0) - { - return; - } - } - else if (archive_format == arf_ustar && - file_hdr->c_tar_linkname && - file_hdr->c_tar_linkname [0] != '\0') - { - int link_res; - link_res = link_to_name (file_hdr->c_name, - file_hdr->c_tar_linkname); - if (link_res < 0) - { - error (0, errno, _("cannot link %s to %s"), - file_hdr->c_tar_linkname, file_hdr->c_name); - /* Something must be wrong, because we couldn't - find the file to link to. But can we assume - that the device maj/min numbers are correct - and fall through to the mknod? It's probably - safer to just return, rather than possibly - creating a bogus device file. */ - } - return; - } - -#ifdef CP_IFIFO - if ((file_hdr->c_mode & CP_IFMT) == CP_IFIFO) - res = mkfifo (file_hdr->c_name, file_hdr->c_mode); - else -#endif - res = mknod (file_hdr->c_name, file_hdr->c_mode, - makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min)); - if (res < 0 && create_dir_flag) - { - create_all_directories (file_hdr->c_name); -#ifdef CP_IFIFO - if ((file_hdr->c_mode & CP_IFMT) == CP_IFIFO) - res = mkfifo (file_hdr->c_name, file_hdr->c_mode); - else -#endif - res = mknod (file_hdr->c_name, file_hdr->c_mode, - makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min)); - } - if (res < 0) - { - mknod_error (file_hdr->c_name); - return; - } - if (!no_chown_flag) - { - uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid; - gid_t gid = set_group_flag ? set_group : file_hdr->c_gid; - if ((chown (file_hdr->c_name, uid, gid) < 0) - && errno != EPERM) - chown_error_details (file_hdr->c_name, uid, gid); - } - /* chown may have turned off some permissions we wanted. */ - if (chmod (file_hdr->c_name, file_hdr->c_mode) < 0) - chmod_error_details (file_hdr->c_name, file_hdr->c_mode); - if (retain_time_flag) - set_file_times (-1, file_hdr->c_name, file_hdr->c_mtime, - file_hdr->c_mtime); -} - -static void -copyin_link(struct cpio_file_stat *file_hdr, int in_file_des) -{ - char *link_name = NULL; /* Name of hard and symbolic links. */ - int res; /* Result of various function calls. */ - - if (to_stdout_option) - return; - - if (archive_format != arf_tar && archive_format != arf_ustar) - { - link_name = (char *) xmalloc ((unsigned int) file_hdr->c_filesize + 1); - link_name[file_hdr->c_filesize] = '\0'; - tape_buffered_read (link_name, in_file_des, file_hdr->c_filesize); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - } - else - { - link_name = xstrdup (file_hdr->c_tar_linkname); - } - - res = UMASKED_SYMLINK (link_name, file_hdr->c_name, - file_hdr->c_mode); - if (res < 0 && create_dir_flag) - { - create_all_directories (file_hdr->c_name); - res = UMASKED_SYMLINK (link_name, file_hdr->c_name, - file_hdr->c_mode); - } - if (res < 0) - { - error (0, errno, _("%s: Cannot symlink to %s"), - quotearg_colon (link_name), quote_n (1, file_hdr->c_name)); - free (link_name); - return; - } - if (!no_chown_flag) - { - uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid; - gid_t gid = set_group_flag ? set_group : file_hdr->c_gid; - if ((lchown (file_hdr->c_name, uid, gid) < 0) - && errno != EPERM) - chown_error_details (file_hdr->c_name, uid, gid); - } - free (link_name); -} - -static void -copyin_file (struct cpio_file_stat* file_hdr, int in_file_des) -{ - int existing_dir; - - if (!to_stdout_option - && try_existing_file (file_hdr, in_file_des, &existing_dir) < 0) - return; - - /* Do the real copy or link. */ - switch (file_hdr->c_mode & CP_IFMT) - { - case CP_IFREG: - copyin_regular_file (file_hdr, in_file_des); - break; - - case CP_IFDIR: - copyin_directory (file_hdr, existing_dir); - break; - - case CP_IFCHR: - case CP_IFBLK: -#ifdef CP_IFSOCK - case CP_IFSOCK: -#endif -#ifdef CP_IFIFO - case CP_IFIFO: -#endif - copyin_device (file_hdr); - break; - -#ifdef CP_IFLNK - case CP_IFLNK: - copyin_link (file_hdr, in_file_des); - break; -#endif - - default: - error (0, 0, _("%s: unknown file type"), file_hdr->c_name); - tape_toss_input (in_file_des, file_hdr->c_filesize); - tape_skip_padding (in_file_des, file_hdr->c_filesize); - } -} - - -/* Current time for verbose table. */ -static time_t current_time; - - -/* Print the file described by FILE_HDR in long format. - If LINK_NAME is nonzero, it is the name of the file that - this file is a symbolic link to. */ - -void -long_format (struct cpio_file_stat *file_hdr, char *link_name) -{ - char mbuf[11]; - char tbuf[40]; - time_t when; - char *ptbuf; - static int d_first = -1; - - mode_string (file_hdr->c_mode, mbuf); - mbuf[10] = '\0'; - - /* Get time values ready to print. */ - when = file_hdr->c_mtime; - if (d_first < 0) - d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); - if (current_time - when > 6L * 30L * 24L * 60L * 60L - || current_time - when < 0L) - ptbuf = d_first ? "%e %b %Y" : "%b %e %Y"; - else - ptbuf = d_first ? "%e %b %R" : "%b %e %R"; - strftime(tbuf, sizeof(tbuf), ptbuf, localtime(&when)); - ptbuf = tbuf; - - printf ("%s %3lu ", mbuf, file_hdr->c_nlink); - - if (numeric_uid) - printf ("%-8u %-8u ", (unsigned int) file_hdr->c_uid, - (unsigned int) file_hdr->c_gid); - else - printf ("%-8.8s %-8.8s ", getuser (file_hdr->c_uid), - getgroup (file_hdr->c_gid)); - - if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR - || (file_hdr->c_mode & CP_IFMT) == CP_IFBLK) - printf ("%3lu, %3lu ", file_hdr->c_rdev_maj, - file_hdr->c_rdev_min); - else - printf ("%8"PRIuMAX" ", (uintmax_t) file_hdr->c_filesize); - - printf ("%s ", ptbuf); - - print_name_with_quoting (file_hdr->c_name); - if (link_name) - { - printf (" -> "); - print_name_with_quoting (link_name); - } - putc ('\n', stdout); -} - -void -print_name_with_quoting (register char *p) -{ - register unsigned char c; - - while ( (c = *p++) ) - { - switch (c) - { - case '\\': - printf ("\\\\"); - break; - - case '\n': - printf ("\\n"); - break; - - case '\b': - printf ("\\b"); - break; - - case '\r': - printf ("\\r"); - break; - - case '\t': - printf ("\\t"); - break; - - case '\f': - printf ("\\f"); - break; - - case ' ': - printf ("\\ "); - break; - - case '"': - printf ("\\\""); - break; - - default: - if (isprint (c)) - putchar (c); - else - printf ("\\%03o", (unsigned int) c); - } - } -} - -/* Read a pattern file (for the -E option). Put a list of - `num_patterns' elements in `save_patterns'. Any patterns that were - already in `save_patterns' (from the command line) are preserved. */ - -static void -read_pattern_file () -{ - int max_new_patterns; - char **new_save_patterns; - int new_num_patterns; - int i; - dynamic_string pattern_name; - FILE *pattern_fp; - - if (num_patterns < 0) - num_patterns = 0; - max_new_patterns = 1 + num_patterns; - new_save_patterns = (char **) xmalloc (max_new_patterns * sizeof (char *)); - new_num_patterns = num_patterns; - ds_init (&pattern_name, 128); - - pattern_fp = fopen (pattern_file_name, "r"); - if (pattern_fp == NULL) - open_error (pattern_file_name); - while (ds_fgetstr (pattern_fp, &pattern_name, '\n') != NULL) - { - if (new_num_patterns >= max_new_patterns) - { - max_new_patterns += 1; - new_save_patterns = (char **) - xrealloc ((char *) new_save_patterns, - max_new_patterns * sizeof (char *)); - } - new_save_patterns[new_num_patterns] = xstrdup (pattern_name.ds_string); - ++new_num_patterns; - } - if (ferror (pattern_fp) || fclose (pattern_fp) == EOF) - close_error (pattern_file_name); - - for (i = 0; i < num_patterns; ++i) - new_save_patterns[i] = save_patterns[i]; - - save_patterns = new_save_patterns; - num_patterns = new_num_patterns; -} - - -uintmax_t -from_ascii (char const *where, size_t digs, unsigned logbase) -{ - uintmax_t value = 0; - char const *buf = where; - char const *end = buf + digs; - int overflow = 0; - static char codetab[] = "0123456789ABCDEF"; - - for (; *buf == ' '; buf++) - { - if (buf == end) - return 0; - } - - if (buf == end || *buf == 0) - return 0; - while (1) - { - unsigned d; - - char *p = strchr (codetab, toupper (*buf)); - if (!p) - { - error (0, 0, _("Malformed number %.*s"), digs, where); - break; - } - - d = p - codetab; - if ((d >> logbase) > 1) - { - error (0, 0, _("Malformed number %.*s"), digs, where); - break; - } - value += d; - if (++buf == end || *buf == 0) - break; - overflow |= value ^ (value << logbase >> logbase); - value <<= logbase; - } - if (overflow) - error (0, 0, _("Archive value %.*s is out of range"), - digs, where); - return value; -} - - - -/* Return 16-bit integer I with the bytes swapped. */ -#define swab_short(i) ((((i) << 8) & 0xff00) | (((i) >> 8) & 0x00ff)) - -/* Read the header, including the name of the file, from file - descriptor IN_DES into FILE_HDR. */ - -void -read_in_header (struct cpio_file_stat *file_hdr, int in_des) -{ - union { - char str[6]; - unsigned short num; - struct old_cpio_header old_header; - } magic; - long bytes_skipped = 0; /* Bytes of junk found before magic number. */ - - /* Search for a valid magic number. */ - - if (archive_format == arf_unknown) - { - char tmpbuf[512]; - int check_tar; - int peeked_bytes; - - while (archive_format == arf_unknown) - { - peeked_bytes = tape_buffered_peek (tmpbuf, in_des, 512); - if (peeked_bytes < 6) - error (1, 0, _("premature end of archive")); - - if (!strncmp (tmpbuf, "070701", 6)) - archive_format = arf_newascii; - else if (!strncmp (tmpbuf, "070707", 6)) - archive_format = arf_oldascii; - else if (!strncmp (tmpbuf, "070702", 6)) - { - archive_format = arf_crcascii; - crc_i_flag = true; - } - else if ((*((unsigned short *) tmpbuf) == 070707) || - (*((unsigned short *) tmpbuf) == swab_short ((unsigned short) 070707))) - archive_format = arf_binary; - else if (peeked_bytes >= 512 - && (check_tar = is_tar_header (tmpbuf))) - { - if (check_tar == 2) - archive_format = arf_ustar; - else - archive_format = arf_tar; - } - else - { - tape_buffered_read ((char *) tmpbuf, in_des, 1L); - ++bytes_skipped; - } - } - } - - if (archive_format == arf_tar || archive_format == arf_ustar) - { - if (append_flag) - last_header_start = input_bytes - io_block_size + - (in_buff - input_buffer); - if (bytes_skipped > 0) - warn_junk_bytes (bytes_skipped); - - read_in_tar_header (file_hdr, in_des); - return; - } - - file_hdr->c_tar_linkname = NULL; - - tape_buffered_read (magic.str, in_des, 6L); - while (1) - { - if (append_flag) - last_header_start = input_bytes - io_block_size - + (in_buff - input_buffer) - 6; - if (archive_format == arf_newascii - && !strncmp (magic.str, "070701", 6)) - { - if (bytes_skipped > 0) - warn_junk_bytes (bytes_skipped); - file_hdr->c_magic = 070701; - read_in_new_ascii (file_hdr, in_des); - break; - } - if (archive_format == arf_crcascii - && !strncmp (magic.str, "070702", 6)) - { - if (bytes_skipped > 0) - warn_junk_bytes (bytes_skipped); - file_hdr->c_magic = 070702; - read_in_new_ascii (file_hdr, in_des); - break; - } - if ( (archive_format == arf_oldascii || archive_format == arf_hpoldascii) - && !strncmp (magic.str, "070707", 6)) - { - if (bytes_skipped > 0) - warn_junk_bytes (bytes_skipped); - file_hdr->c_magic = 070707; - read_in_old_ascii (file_hdr, in_des); - break; - } - if ( (archive_format == arf_binary || archive_format == arf_hpbinary) - && (magic.num == 070707 - || magic.num == swab_short ((unsigned short) 070707))) - { - /* Having to skip 1 byte because of word alignment is normal. */ - if (bytes_skipped > 0) - warn_junk_bytes (bytes_skipped); - file_hdr->c_magic = 070707; - read_in_binary (file_hdr, &magic.old_header, in_des); - break; - } - bytes_skipped++; - memmove (magic.str, magic.str + 1, 5); - tape_buffered_read (magic.str, in_des, 1L); - } -} - -/* Fill in FILE_HDR by reading an old-format ASCII format cpio header from - file descriptor IN_DES, except for the magic number, which is - already filled in. */ - -void -read_in_old_ascii (struct cpio_file_stat *file_hdr, int in_des) -{ - struct old_ascii_header ascii_header; - unsigned long dev; - - tape_buffered_read (ascii_header.c_dev, in_des, - sizeof ascii_header - sizeof ascii_header.c_magic); - dev = FROM_OCTAL (ascii_header.c_dev); - file_hdr->c_dev_maj = major (dev); - file_hdr->c_dev_min = minor (dev); - - file_hdr->c_ino = FROM_OCTAL (ascii_header.c_ino); - file_hdr->c_mode = FROM_OCTAL (ascii_header.c_mode); - file_hdr->c_uid = FROM_OCTAL (ascii_header.c_uid); - file_hdr->c_gid = FROM_OCTAL (ascii_header.c_gid); - file_hdr->c_nlink = FROM_OCTAL (ascii_header.c_nlink); - dev = FROM_OCTAL (ascii_header.c_rdev); - file_hdr->c_rdev_maj = major (dev); - file_hdr->c_rdev_min = minor (dev); - - file_hdr->c_mtime = FROM_OCTAL (ascii_header.c_mtime); - file_hdr->c_namesize = FROM_OCTAL (ascii_header.c_namesize); - file_hdr->c_filesize = FROM_OCTAL (ascii_header.c_filesize); - - /* Read file name from input. */ - if (file_hdr->c_name != NULL) - free (file_hdr->c_name); - file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize + 1); - tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize); - - /* HP/UX cpio creates archives that look just like ordinary archives, - but for devices it sets major = 0, minor = 1, and puts the - actual major/minor number in the filesize field. See if this - is an HP/UX cpio archive, and if so fix it. We have to do this - here because process_copy_in() assumes filesize is always 0 - for devices. */ - switch (file_hdr->c_mode & CP_IFMT) - { - case CP_IFCHR: - case CP_IFBLK: -#ifdef CP_IFSOCK - case CP_IFSOCK: -#endif -#ifdef CP_IFIFO - case CP_IFIFO: -#endif - if (file_hdr->c_filesize != 0 - && file_hdr->c_rdev_maj == 0 - && file_hdr->c_rdev_min == 1) - { - file_hdr->c_rdev_maj = major (file_hdr->c_filesize); - file_hdr->c_rdev_min = minor (file_hdr->c_filesize); - file_hdr->c_filesize = 0; - } - break; - default: - break; - } -} - -/* Fill in FILE_HDR by reading a new-format ASCII format cpio header from - file descriptor IN_DES, except for the magic number, which is - already filled in. */ - -void -read_in_new_ascii (struct cpio_file_stat *file_hdr, int in_des) -{ - struct new_ascii_header ascii_header; - - tape_buffered_read (ascii_header.c_ino, in_des, - sizeof ascii_header - sizeof ascii_header.c_magic); - - file_hdr->c_ino = FROM_HEX (ascii_header.c_ino); - file_hdr->c_mode = FROM_HEX (ascii_header.c_mode); - file_hdr->c_uid = FROM_HEX (ascii_header.c_uid); - file_hdr->c_gid = FROM_HEX (ascii_header.c_gid); - file_hdr->c_nlink = FROM_HEX (ascii_header.c_nlink); - file_hdr->c_mtime = FROM_HEX (ascii_header.c_mtime); - file_hdr->c_filesize = FROM_HEX (ascii_header.c_filesize); - file_hdr->c_dev_maj = FROM_HEX (ascii_header.c_dev_maj); - file_hdr->c_dev_min = FROM_HEX (ascii_header.c_dev_min); - file_hdr->c_rdev_maj = FROM_HEX (ascii_header.c_rdev_maj); - file_hdr->c_rdev_min = FROM_HEX (ascii_header.c_rdev_min); - file_hdr->c_namesize = FROM_HEX (ascii_header.c_namesize); - file_hdr->c_chksum = FROM_HEX (ascii_header.c_chksum); - - /* Read file name from input. */ - if (file_hdr->c_name != NULL) - free (file_hdr->c_name); - file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize); - tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize); - - /* In SVR4 ASCII format, the amount of space allocated for the header - is rounded up to the next long-word, so we might need to drop - 1-3 bytes. */ - tape_skip_padding (in_des, file_hdr->c_namesize + 110); -} - -/* Fill in FILE_HDR by reading a binary format cpio header from - file descriptor IN_DES, except for the first 6 bytes (the magic - number, device, and inode number), which are already filled in. */ - -void -read_in_binary (struct cpio_file_stat *file_hdr, - struct old_cpio_header *short_hdr, - int in_des) -{ - file_hdr->c_magic = short_hdr->c_magic; - - tape_buffered_read (((char *) short_hdr) + 6, in_des, - sizeof *short_hdr - 6 /* = 20 */); - - /* If the magic number is byte swapped, fix the header. */ - if (file_hdr->c_magic == swab_short ((unsigned short) 070707)) - { - static int warned = 0; - - /* Alert the user that they might have to do byte swapping on - the file contents. */ - if (warned == 0) - { - error (0, 0, _("warning: archive header has reverse byte-order")); - warned = 1; - } - swab_array ((char *) &short_hdr, 13); - } - - file_hdr->c_dev_maj = major (short_hdr->c_dev); - file_hdr->c_dev_min = minor (short_hdr->c_dev); - file_hdr->c_ino = short_hdr->c_ino; - file_hdr->c_mode = short_hdr->c_mode; - file_hdr->c_uid = short_hdr->c_uid; - file_hdr->c_gid = short_hdr->c_gid; - file_hdr->c_nlink = short_hdr->c_nlink; - file_hdr->c_rdev_maj = major (short_hdr->c_rdev); - file_hdr->c_rdev_min = minor (short_hdr->c_rdev); - file_hdr->c_mtime = (unsigned long) short_hdr->c_mtimes[0] << 16 - | short_hdr->c_mtimes[1]; - - file_hdr->c_namesize = short_hdr->c_namesize; - file_hdr->c_filesize = (unsigned long) short_hdr->c_filesizes[0] << 16 - | short_hdr->c_filesizes[1]; - - /* Read file name from input. */ - if (file_hdr->c_name != NULL) - free (file_hdr->c_name); - file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize); - tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize); - - /* In binary mode, the amount of space allocated in the header for - the filename is `c_namesize' rounded up to the next short-word, - so we might need to drop a byte. */ - if (file_hdr->c_namesize % 2) - tape_toss_input (in_des, 1L); - - /* HP/UX cpio creates archives that look just like ordinary archives, - but for devices it sets major = 0, minor = 1, and puts the - actual major/minor number in the filesize field. See if this - is an HP/UX cpio archive, and if so fix it. We have to do this - here because process_copy_in() assumes filesize is always 0 - for devices. */ - switch (file_hdr->c_mode & CP_IFMT) - { - case CP_IFCHR: - case CP_IFBLK: -#ifdef CP_IFSOCK - case CP_IFSOCK: -#endif -#ifdef CP_IFIFO - case CP_IFIFO: -#endif - if (file_hdr->c_filesize != 0 - && file_hdr->c_rdev_maj == 0 - && file_hdr->c_rdev_min == 1) - { - file_hdr->c_rdev_maj = major (file_hdr->c_filesize); - file_hdr->c_rdev_min = minor (file_hdr->c_filesize); - file_hdr->c_filesize = 0; - } - break; - default: - break; - } -} - -/* Exchange the bytes of each element of the array of COUNT shorts - starting at PTR. */ - -void -swab_array (char *ptr, int count) -{ - char tmp; - - while (count-- > 0) - { - tmp = *ptr; - *ptr = *(ptr + 1); - ++ptr; - *ptr = tmp; - ++ptr; - } -} - -#if 0 /* Now in util.c, but different */ -/* Return a safer suffix of FILE_NAME, or "." if it has no safer - suffix. Check for fully specified file names and other atrocities. */ - -static const char * -safer_name_suffix (char const *file_name) -{ - char const *p; - - /* Skip file system prefixes, leading file name components that contain - "..", and leading slashes. */ - - size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name); - - for (p = file_name + prefix_len; *p;) - { - if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2])) - prefix_len = p + 2 - file_name; - - do - { - char c = *p++; - if (ISSLASH (c)) - break; - } - while (*p); - } - - for (p = file_name + prefix_len; ISSLASH (*p); p++) - continue; - prefix_len = p - file_name; - - if (prefix_len) - { - char *prefix = alloca (prefix_len + 1); - memcpy (prefix, file_name, prefix_len); - prefix[prefix_len] = '\0'; - - - error (0, 0, _("Removing leading `%s' from member names"), prefix); - } - - if (!*p) - p = "."; - - return p; -} -#endif - -/* Read the collection from standard input and create files - in the file system. */ - -void -process_copy_in () -{ - char done = false; /* True if trailer reached. */ - FILE *tty_in = NULL; /* Interactive file for rename option. */ - FILE *tty_out = NULL; /* Interactive file for rename option. */ - FILE *rename_in = NULL; /* Batch file for rename option. */ - struct stat file_stat; /* Output file stat record. */ - struct cpio_file_stat file_hdr; /* Output header information. */ - int in_file_des; /* Input file descriptor. */ - char skip_file; /* Flag for use with patterns. */ - int i; /* Loop index variable. */ - - umask (0); /* Reset umask to preserve modes of - created files */ - - /* Initialize the copy in. */ - if (pattern_file_name) - { - read_pattern_file (); - } - file_hdr.c_name = NULL; - - if (rename_batch_file) - { - rename_in = fopen (rename_batch_file, "r"); - if (rename_in == NULL) - { - error (2, errno, TTY_NAME); - } - } - else if (rename_flag) - { - /* Open interactive file pair for rename operation. */ - tty_in = fopen (TTY_NAME, "r"); - if (tty_in == NULL) - { - error (2, errno, TTY_NAME); - } - tty_out = fopen (TTY_NAME, "w"); - if (tty_out == NULL) - { - error (2, errno, TTY_NAME); - } - } - - /* Get date and time if needed for processing the table option. */ - if (table_flag && verbose_flag) - { - time (¤t_time); - } - - /* Check whether the input file might be a tape. */ - in_file_des = archive_des; - if (_isrmt (in_file_des)) - { - input_is_special = 1; - input_is_seekable = 0; - } - else - { - if (fstat (in_file_des, &file_stat)) - error (1, errno, _("standard input is closed")); - input_is_special = -#ifdef S_ISBLK - S_ISBLK (file_stat.st_mode) || -#endif - S_ISCHR (file_stat.st_mode); - input_is_seekable = S_ISREG (file_stat.st_mode); - } - output_is_seekable = true; - - /* While there is more input in the collection, process the input. */ - while (!done) - { - swapping_halfwords = swapping_bytes = false; - - /* Start processing the next file by reading the header. */ - read_in_header (&file_hdr, in_file_des); - -#ifdef DEBUG_CPIO - if (debug_flag) - { - struct cpio_file_stat *h; - h = &file_hdr; - fprintf (stderr, - "magic = 0%o, ino = %d, mode = 0%o, uid = %d, gid = %d\n", - h->c_magic, h->c_ino, h->c_mode, h->c_uid, h->c_gid); - fprintf (stderr, - "nlink = %d, mtime = %d, filesize = %d, dev_maj = 0x%x\n", - h->c_nlink, h->c_mtime, h->c_filesize, h->c_dev_maj); - fprintf (stderr, - "dev_min = 0x%x, rdev_maj = 0x%x, rdev_min = 0x%x, namesize = %d\n", - h->c_dev_min, h->c_rdev_maj, h->c_rdev_min, h->c_namesize); - fprintf (stderr, - "chksum = %d, name = \"%s\", tar_linkname = \"%s\"\n", - h->c_chksum, h->c_name, - h->c_tar_linkname ? h->c_tar_linkname : "(null)" ); - - } -#endif - /* Is this the header for the TRAILER file? */ - if (strcmp (CPIO_TRAILER_NAME, file_hdr.c_name) == 0) - { - done = true; - break; - } - - cpio_safer_name_suffix (file_hdr.c_name, false, abs_paths_flag, - false); - - /* Does the file name match one of the given patterns? */ - if (num_patterns <= 0) - skip_file = false; - else - { - skip_file = copy_matching_files; - for (i = 0; i < num_patterns - && skip_file == copy_matching_files; i++) - { - if (fnmatch (save_patterns[i], file_hdr.c_name, 0) == 0) - skip_file = !copy_matching_files; - } - } - - if (skip_file) - { - /* If we're skipping a file with links, there might be other - links that we didn't skip, and this file might have the - data for the links. If it does, we'll copy in the data - to the links, but not to this file. */ - if (file_hdr.c_nlink > 1 && (archive_format == arf_newascii - || archive_format == arf_crcascii) ) - { - if (create_defered_links_to_skipped(&file_hdr, in_file_des) < 0) - { - tape_toss_input (in_file_des, file_hdr.c_filesize); - tape_skip_padding (in_file_des, file_hdr.c_filesize); - } - } - else - { - tape_toss_input (in_file_des, file_hdr.c_filesize); - tape_skip_padding (in_file_des, file_hdr.c_filesize); - } - } - else if (table_flag) - { - list_file(&file_hdr, in_file_des); - } - else if (append_flag) - { - tape_toss_input (in_file_des, file_hdr.c_filesize); - tape_skip_padding (in_file_des, file_hdr.c_filesize); - } - else if (only_verify_crc_flag) - { -#ifdef CP_IFLNK - if ((file_hdr.c_mode & CP_IFMT) == CP_IFLNK) - { - if (archive_format != arf_tar && archive_format != arf_ustar) - { - tape_toss_input (in_file_des, file_hdr.c_filesize); - tape_skip_padding (in_file_des, file_hdr.c_filesize); - continue; - } - } -#endif - crc = 0; - tape_toss_input (in_file_des, file_hdr.c_filesize); - tape_skip_padding (in_file_des, file_hdr.c_filesize); - if (crc != file_hdr.c_chksum) - { - error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"), - file_hdr.c_name, crc, file_hdr.c_chksum); - } - /* Debian hack: -v and -V now work with --only-verify-crc. - (99/11/10) -BEM */ - if (verbose_flag) - { - fprintf (stderr, "%s\n", file_hdr.c_name); - } - if (dot_flag) - { - fputc ('.', stderr); - } - } - else - { - /* Copy the input file into the directory structure. */ - - /* Do we need to rename the file? */ - if (rename_flag || rename_batch_file) - { - if (query_rename(&file_hdr, tty_in, tty_out, rename_in) < 0) - { - tape_toss_input (in_file_des, file_hdr.c_filesize); - tape_skip_padding (in_file_des, file_hdr.c_filesize); - continue; - } - } - - copyin_file(&file_hdr, in_file_des); - - if (verbose_flag) - fprintf (stderr, "%s\n", file_hdr.c_name); - if (dot_flag) - fputc ('.', stderr); - } - } - - if (dot_flag) - fputc ('\n', stderr); - - if (append_flag) - return; - - if (archive_format == arf_newascii || archive_format == arf_crcascii) - { - create_final_defers (); - } - if (!quiet_flag) - { - int blocks; - blocks = (input_bytes + io_block_size - 1) / io_block_size; - fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", blocks), blocks); - } -} - diff --git a/contrib/cpio/src/copyout.c b/contrib/cpio/src/copyout.c deleted file mode 100644 index 5e429faa9da..00000000000 --- a/contrib/cpio/src/copyout.c +++ /dev/null @@ -1,1010 +0,0 @@ -/* $FreeBSD$ */ - -/* copyout.c - create a cpio archive - Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004, - 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#include - -#include -#include -#include -#include "filetypes.h" -#include "cpiohdr.h" -#include "dstring.h" -#include "extern.h" -#include "defer.h" -#include -#include - -static int check_rdev (); - -/* Read FILE_SIZE bytes of FILE_NAME from IN_FILE_DES and - compute and return a checksum for them. */ - -static unsigned int -read_for_checksum (int in_file_des, int file_size, char *file_name) -{ - unsigned int crc; - char buf[BUFSIZ]; - int bytes_left; - int bytes_read; - int i; - - crc = 0; - - for (bytes_left = file_size; bytes_left > 0; bytes_left -= bytes_read) - { - bytes_read = read (in_file_des, buf, BUFSIZ); - if (bytes_read < 0) - error (1, errno, _("cannot read checksum for %s"), file_name); - if (bytes_read == 0) - break; - if (bytes_left < bytes_read) - bytes_read = bytes_left; - for (i = 0; i < bytes_read; ++i) - crc += buf[i] & 0xff; - } - if (lseek (in_file_des, 0L, SEEK_SET)) - error (1, errno, _("cannot read checksum for %s"), file_name); - - return crc; -} - -/* Write out NULs to fill out the rest of the current block on - OUT_FILE_DES. */ - -static void -tape_clear_rest_of_block (int out_file_des) -{ - write_nuls_to_file (io_block_size - output_size, out_file_des, - tape_buffered_write); -} - -/* Write NULs on OUT_FILE_DES to move from OFFSET (the current location) - to the end of the header. */ - -static void -tape_pad_output (int out_file_des, int offset) -{ - size_t pad; - - if (archive_format == arf_newascii || archive_format == arf_crcascii) - pad = (4 - (offset % 4)) % 4; - else if (archive_format == arf_tar || archive_format == arf_ustar) - pad = (512 - (offset % 512)) % 512; - else if (archive_format != arf_oldascii && archive_format != arf_hpoldascii) - pad = (2 - (offset % 2)) % 2; - else - pad = 0; - - if (pad != 0) - write_nuls_to_file (pad, out_file_des, tape_buffered_write); -} - - -/* When creating newc and crc archives if a file has multiple (hard) - links, we don't put any of them into the archive until we have seen - all of them (or until we get to the end of the list of files that - are going into the archive and know that we have seen all of the links - to the file that we will see). We keep these "defered" files on - this list. */ - -struct deferment *deferouts = NULL; - -/* Count the number of other (hard) links to this file that have - already been defered. */ - -static int -count_defered_links_to_dev_ino (struct cpio_file_stat *file_hdr) -{ - struct deferment *d; - int ino; - int maj; - int min; - int count; - ino = file_hdr->c_ino; - maj = file_hdr->c_dev_maj; - min = file_hdr->c_dev_min; - count = 0; - for (d = deferouts; d != NULL; d = d->next) - { - if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj) - && (d->header.c_dev_min == min) ) - ++count; - } - return count; -} - -/* Is this file_hdr the last (hard) link to a file? I.e., have - we already seen and defered all of the other links? */ - -static int -last_link (struct cpio_file_stat *file_hdr) -{ - int other_files_sofar; - - other_files_sofar = count_defered_links_to_dev_ino (file_hdr); - if (file_hdr->c_nlink == (other_files_sofar + 1) ) - { - return 1; - } - return 0; -} - - -/* Add the file header for a link that is being defered to the deferouts - list. */ - -static void -add_link_defer (struct cpio_file_stat *file_hdr) -{ - struct deferment *d; - d = create_deferment (file_hdr); - d->next = deferouts; - deferouts = d; -} - -/* We are about to put a file into a newc or crc archive that is - multiply linked. We have already seen and deferred all of the - other links to the file but haven't written them into the archive. - Write the other links into the archive, and remove them from the - deferouts list. */ - -static void -writeout_other_defers (struct cpio_file_stat *file_hdr, int out_des) -{ - struct deferment *d; - struct deferment *d_prev; - int ino; - int maj; - int min; - ino = file_hdr->c_ino; - maj = file_hdr->c_dev_maj; - min = file_hdr->c_dev_min; - d_prev = NULL; - d = deferouts; - while (d != NULL) - { - if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj) - && (d->header.c_dev_min == min) ) - { - struct deferment *d_free; - d->header.c_filesize = 0; - write_out_header (&d->header, out_des); - if (d_prev != NULL) - d_prev->next = d->next; - else - deferouts = d->next; - d_free = d; - d = d->next; - free_deferment (d_free); - } - else - { - d_prev = d; - d = d->next; - } - } - return; -} - -/* Write a file into the archive. This code is the same as - the code in process_copy_out(), but we need it here too - for writeout_final_defers() to call. */ - -static void -writeout_defered_file (struct cpio_file_stat *header, int out_file_des) -{ - int in_file_des; - struct cpio_file_stat file_hdr; - - file_hdr = *header; - - - in_file_des = open (header->c_name, - O_RDONLY | O_BINARY, 0); - if (in_file_des < 0) - { - open_error (header->c_name); - return; - } - - if (archive_format == arf_crcascii) - file_hdr.c_chksum = read_for_checksum (in_file_des, - file_hdr.c_filesize, - header->c_name); - - if (write_out_header (&file_hdr, out_file_des)) - return; - copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, - header->c_name); - warn_if_file_changed(header->c_name, file_hdr.c_filesize, file_hdr.c_mtime); - - if (archive_format == arf_tar || archive_format == arf_ustar) - add_inode (file_hdr.c_ino, file_hdr.c_name, file_hdr.c_dev_maj, - file_hdr.c_dev_min); - - tape_pad_output (out_file_des, file_hdr.c_filesize); - - if (reset_time_flag) - set_file_times (in_file_des, file_hdr.c_name, file_hdr.c_mtime, - file_hdr.c_mtime); - if (close (in_file_des) < 0) - close_error (header->c_name); -} - -/* When writing newc and crc format archives we defer multiply linked - files until we have seen all of the links to the file. If a file - has links to it that aren't going into the archive, then we will - never see the "last" link to the file, so at the end we just write - all of the leftover defered files into the archive. */ - -static void -writeout_final_defers (int out_des) -{ - struct deferment *d; - int other_count; - while (deferouts != NULL) - { - d = deferouts; - other_count = count_defered_links_to_dev_ino (&d->header); - if (other_count == 1) - { - writeout_defered_file (&d->header, out_des); - } - else - { - struct cpio_file_stat file_hdr; - file_hdr = d->header; - file_hdr.c_filesize = 0; - write_out_header (&file_hdr, out_des); - } - deferouts = deferouts->next; - } -} - -/* FIXME: to_ascii could be used instead of to_oct() and to_octal() from tar, - so it should be moved to paxutils too. - Allowed values for logbase are: 1 (binary), 2, 3 (octal), 4 (hex) */ -int -to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase) -{ - static char codetab[] = "0123456789ABCDEF"; - int i = digits; - - do - { - where[--i] = codetab[(v & ((1 << logbase) - 1))]; - v >>= logbase; - } - while (i); - - return v != 0; -} - -static void -field_width_error (const char *filename, const char *fieldname) -{ - error (0, 0, _("%s: field width not sufficient for storing %s"), - filename, fieldname); -} - -static void -field_width_warning (const char *filename, const char *fieldname) -{ - if (warn_option & CPIO_WARN_TRUNCATE) - error (0, 0, _("%s: truncating %s"), filename, fieldname); -} - -void -to_ascii_or_warn (char *where, uintmax_t n, size_t digits, - unsigned logbase, - const char *filename, const char *fieldname) -{ - if (to_ascii (where, n, digits, logbase)) - field_width_warning (filename, fieldname); -} - -int -to_ascii_or_error (char *where, uintmax_t n, size_t digits, - unsigned logbase, - const char *filename, const char *fieldname) -{ - if (to_ascii (where, n, digits, logbase)) - { - field_width_error (filename, fieldname); - return 1; - } - return 0; -} - - -int -write_out_new_ascii_header (const char *magic_string, - struct cpio_file_stat *file_hdr, int out_des) -{ - char ascii_header[110]; - char *p; - - p = stpcpy (ascii_header, magic_string); - to_ascii_or_warn (p, file_hdr->c_ino, 8, LG_16, - file_hdr->c_name, _("inode number")); - p += 8; - to_ascii_or_warn (p, file_hdr->c_mode, 8, LG_16, file_hdr->c_name, - _("file mode")); - p += 8; - to_ascii_or_warn (p, file_hdr->c_uid, 8, LG_16, file_hdr->c_name, - _("uid")); - p += 8; - to_ascii_or_warn (p, file_hdr->c_gid, 8, LG_16, file_hdr->c_name, - _("gid")); - p += 8; - to_ascii_or_warn (p, file_hdr->c_nlink, 8, LG_16, file_hdr->c_name, - _("number of links")); - p += 8; - to_ascii_or_warn (p, file_hdr->c_mtime, 8, LG_16, file_hdr->c_name, - _("modification time")); - p += 8; - if (to_ascii_or_error (p, file_hdr->c_filesize, 8, LG_16, file_hdr->c_name, - _("file size"))) - return 1; - p += 8; - if (to_ascii_or_error (p, file_hdr->c_dev_maj, 8, LG_16, file_hdr->c_name, - _("device major number"))) - return 1; - p += 8; - if (to_ascii_or_error (p, file_hdr->c_dev_min, 8, LG_16, file_hdr->c_name, - _("device minor number"))) - return 1; - p += 8; - if (to_ascii_or_error (p, file_hdr->c_rdev_maj, 8, LG_16, file_hdr->c_name, - _("rdev major"))) - return 1; - p += 8; - if (to_ascii_or_error (p, file_hdr->c_rdev_min, 8, LG_16, file_hdr->c_name, - _("rdev minor"))) - return 1; - p += 8; - if (to_ascii_or_error (p, file_hdr->c_namesize, 8, LG_16, file_hdr->c_name, - _("name size"))) - return 1; - p += 8; - to_ascii (p, file_hdr->c_chksum & 0xffffffff, 8, LG_16); - - tape_buffered_write (ascii_header, out_des, sizeof ascii_header); - - /* Write file name to output. */ - tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize); - tape_pad_output (out_des, file_hdr->c_namesize + sizeof ascii_header); - return 0; -} - -int -write_out_old_ascii_header (dev_t dev, dev_t rdev, - struct cpio_file_stat *file_hdr, int out_des) -{ - char ascii_header[76]; - char *p = ascii_header; - - to_ascii (p, file_hdr->c_magic, 6, LG_8); - p += 6; - to_ascii_or_warn (p, dev, 6, LG_8, file_hdr->c_name, _("device number")); - p += 6; - to_ascii_or_warn (p, file_hdr->c_ino, 6, LG_8, file_hdr->c_name, - _("inode number")); - p += 6; - to_ascii_or_warn (p, file_hdr->c_mode, 6, LG_8, file_hdr->c_name, - _("file mode")); - p += 6; - to_ascii_or_warn (p, file_hdr->c_uid, 6, LG_8, file_hdr->c_name, _("uid")); - p += 6; - to_ascii_or_warn (p, file_hdr->c_gid, 6, LG_8, file_hdr->c_name, _("gid")); - p += 6; - to_ascii_or_warn (p, file_hdr->c_nlink, 6, LG_8, file_hdr->c_name, - _("number of links")); - p += 6; - to_ascii_or_warn (p, rdev, 6, LG_8, file_hdr->c_name, _("rdev")); - p += 6; - to_ascii_or_warn (p, file_hdr->c_mtime, 11, LG_8, file_hdr->c_name, - _("modification time")); - p += 11; - if (to_ascii_or_error (p, file_hdr->c_namesize, 6, LG_8, file_hdr->c_name, - _("name size"))) - return 1; - p += 6; - if (to_ascii_or_error (p, file_hdr->c_filesize, 11, LG_8, file_hdr->c_name, - _("file size"))) - return 1; - - tape_buffered_write (ascii_header, out_des, sizeof ascii_header); - - /* Write file name to output. */ - tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize); - return 0; -} - -void -hp_compute_dev (struct cpio_file_stat *file_hdr, dev_t *pdev, dev_t *prdev) -{ - /* HP/UX cpio creates archives that look just like ordinary archives, - but for devices it sets major = 0, minor = 1, and puts the - actual major/minor number in the filesize field. */ - switch (file_hdr->c_mode & CP_IFMT) - { - case CP_IFCHR: - case CP_IFBLK: -#ifdef CP_IFSOCK - case CP_IFSOCK: -#endif -#ifdef CP_IFIFO - case CP_IFIFO: -#endif - file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj, - file_hdr->c_rdev_min); - *pdev = *prdev = makedev (0, 1); - break; - - default: - *pdev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min); - *prdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min); - break; - } -} - -int -write_out_binary_header (dev_t rdev, - struct cpio_file_stat *file_hdr, int out_des) -{ - struct old_cpio_header short_hdr; - - short_hdr.c_magic = 070707; - short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min); - - if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0) - error (0, 0, _("%s: truncating inode number"), file_hdr->c_name); - - short_hdr.c_ino = file_hdr->c_ino & 0xFFFF; - if (short_hdr.c_ino != file_hdr->c_ino) - field_width_warning (file_hdr->c_name, _("inode number")); - - short_hdr.c_mode = file_hdr->c_mode & 0xFFFF; - if (short_hdr.c_mode != file_hdr->c_mode) - field_width_warning (file_hdr->c_name, _("file mode")); - - short_hdr.c_uid = file_hdr->c_uid & 0xFFFF; - if (short_hdr.c_uid != file_hdr->c_uid) - field_width_warning (file_hdr->c_name, _("uid")); - - short_hdr.c_gid = file_hdr->c_gid & 0xFFFF; - if (short_hdr.c_gid != file_hdr->c_gid) - field_width_warning (file_hdr->c_name, _("gid")); - - short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF; - if (short_hdr.c_nlink != file_hdr->c_nlink) - field_width_warning (file_hdr->c_name, _("number of links")); - - short_hdr.c_rdev = rdev; - short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16; - short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF; - - short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF; - if (short_hdr.c_namesize != file_hdr->c_namesize) - { - field_width_error (file_hdr->c_name, _("name size")); - return 1; - } - - short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16; - short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF; - - if (((off_t)short_hdr.c_filesizes[0] << 16) + short_hdr.c_filesizes[1] - != file_hdr->c_filesize) - { - field_width_error (file_hdr->c_name, _("file size")); - return 1; - } - - /* Output the file header. */ - tape_buffered_write ((char *) &short_hdr, out_des, 26); - - /* Write file name to output. */ - tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize); - - tape_pad_output (out_des, file_hdr->c_namesize + 26); - return 0; -} - - -/* Write out header FILE_HDR, including the file name, to file - descriptor OUT_DES. */ - -int -write_out_header (struct cpio_file_stat *file_hdr, int out_des) -{ - dev_t dev; - dev_t rdev; - - switch (archive_format) - { - case arf_newascii: - return write_out_new_ascii_header ("070701", file_hdr, out_des); - - case arf_crcascii: - return write_out_new_ascii_header ("070702", file_hdr, out_des); - - case arf_oldascii: - return write_out_old_ascii_header (makedev (file_hdr->c_dev_maj, - file_hdr->c_dev_min), - makedev (file_hdr->c_rdev_maj, - file_hdr->c_rdev_min), - file_hdr, out_des); - - case arf_hpoldascii: - hp_compute_dev (file_hdr, &dev, &rdev); - return write_out_old_ascii_header (dev, rdev, file_hdr, out_des); - - case arf_tar: - case arf_ustar: - if (is_tar_filename_too_long (file_hdr->c_name)) - { - error (0, 0, _("%s: file name too long"), file_hdr->c_name); - return 1; - } - write_out_tar_header (file_hdr, out_des); /* FIXME: No error checking */ - return 0; - - case arf_binary: - return write_out_binary_header (makedev (file_hdr->c_rdev_maj, - file_hdr->c_rdev_min), - file_hdr, out_des); - - case arf_hpbinary: - hp_compute_dev (file_hdr, &dev, &rdev); - /* FIXME: dev ignored. Should it be? */ - return write_out_binary_header (rdev, file_hdr, out_des); - - default: - abort (); - } -} - -static void -assign_string (char **pvar, char *value) -{ - char *p = xrealloc (*pvar, strlen (value) + 1); - strcpy (p, value); - *pvar = p; -} - -/* Read a list of file names from the standard input - and write a cpio collection on the standard output. - The format of the header depends on the compatibility (-c) flag. */ - -void -process_copy_out () -{ - int res; /* Result of functions. */ - dynamic_string input_name; /* Name of file read from stdin. */ - struct stat file_stat; /* Stat record for file. */ - struct cpio_file_stat file_hdr; /* Output header information. */ - int in_file_des; /* Source file descriptor. */ - int out_file_des; /* Output file descriptor. */ - char *orig_file_name = NULL; - - /* Initialize the copy out. */ - ds_init (&input_name, 128); - file_hdr.c_magic = 070707; - - /* Check whether the output file might be a tape. */ - out_file_des = archive_des; - if (_isrmt (out_file_des)) - { - output_is_special = 1; - output_is_seekable = 0; - } - else - { - if (fstat (out_file_des, &file_stat)) - error (1, errno, _("standard output is closed")); - output_is_special = -#ifdef S_ISBLK - S_ISBLK (file_stat.st_mode) || -#endif - S_ISCHR (file_stat.st_mode); - output_is_seekable = S_ISREG (file_stat.st_mode); - } - - if (append_flag) - { - process_copy_in (); - prepare_append (out_file_des); - } - - /* Copy files with names read from stdin. */ - while (ds_fgetstr (stdin, &input_name, name_end) != NULL) - { - /* Check for blank line. */ - if (input_name.ds_string[0] == 0) - { - error (0, 0, _("blank line ignored")); - continue; - } - - /* Process next file. */ - if ((*xstat) (input_name.ds_string, &file_stat) < 0) - stat_error (input_name.ds_string); - else - { - /* Set values in output header. */ - stat_to_cpio (&file_hdr, &file_stat); - - if (archive_format == arf_tar || archive_format == arf_ustar) - { - if (file_hdr.c_mode & CP_IFDIR) - { - int len = strlen (input_name.ds_string); - /* Make sure the name ends with a slash */ - if (input_name.ds_string[len-1] != '/') - { - ds_resize (&input_name, len + 2); - input_name.ds_string[len] = '/'; - input_name.ds_string[len+1] = 0; - } - } - } - - switch (check_rdev (&file_hdr)) - { - case 1: - error (0, 0, "%s not dumped: major number would be truncated", - file_hdr.c_name); - continue; - case 2: - error (0, 0, "%s not dumped: minor number would be truncated", - file_hdr.c_name); - continue; - case 4: - error (0, 0, "%s not dumped: device number would be truncated", - file_hdr.c_name); - continue; - } - - assign_string (&orig_file_name, input_name.ds_string); - cpio_safer_name_suffix (input_name.ds_string, false, - abs_paths_flag, true); -#ifndef HPUX_CDF - file_hdr.c_name = input_name.ds_string; - file_hdr.c_namesize = strlen (input_name.ds_string) + 1; -#else - if ( (archive_format != arf_tar) && (archive_format != arf_ustar) ) - { - /* We mark CDF's in cpio files by adding a 2nd `/' after the - "hidden" directory name. We need to do this so we can - properly recreate the directory as hidden (in case the - files of a directory go into the archive before the - directory itself (e.g from "find ... -depth ... | cpio")). */ - file_hdr.c_name = add_cdf_double_slashes (input_name.ds_string); - file_hdr.c_namesize = strlen (file_hdr.c_name) + 1; - } - else - { - /* We don't mark CDF's in tar files. We assume the "hidden" - directory will always go into the archive before any of - its files. */ - file_hdr.c_name = input_name.ds_string; - file_hdr.c_namesize = strlen (input_name.ds_string) + 1; - } -#endif - - /* Copy the named file to the output. */ - switch (file_hdr.c_mode & CP_IFMT) - { - case CP_IFREG: - if (archive_format == arf_tar || archive_format == arf_ustar) - { - char *otherfile; - if ((otherfile = find_inode_file (file_hdr.c_ino, - file_hdr.c_dev_maj, - file_hdr.c_dev_min))) - { - file_hdr.c_tar_linkname = otherfile; - if (write_out_header (&file_hdr, out_file_des)) - continue; - break; - } - } - if ( (archive_format == arf_newascii || archive_format == arf_crcascii) - && (file_hdr.c_nlink > 1) ) - { - if (last_link (&file_hdr) ) - { - writeout_other_defers (&file_hdr, out_file_des); - } - else - { - add_link_defer (&file_hdr); - break; - } - } - in_file_des = open (orig_file_name, - O_RDONLY | O_BINARY, 0); - if (in_file_des < 0) - { - open_error (orig_file_name); - continue; - } - - if (archive_format == arf_crcascii) - file_hdr.c_chksum = read_for_checksum (in_file_des, - file_hdr.c_filesize, - orig_file_name); - - if (write_out_header (&file_hdr, out_file_des)) - continue; - copy_files_disk_to_tape (in_file_des, - out_file_des, file_hdr.c_filesize, - orig_file_name); - warn_if_file_changed(orig_file_name, file_hdr.c_filesize, - file_hdr.c_mtime); - - if (archive_format == arf_tar || archive_format == arf_ustar) - add_inode (file_hdr.c_ino, orig_file_name, file_hdr.c_dev_maj, - file_hdr.c_dev_min); - - tape_pad_output (out_file_des, file_hdr.c_filesize); - - if (reset_time_flag) - set_file_times (in_file_des, - orig_file_name, - file_stat.st_atime, file_stat.st_mtime); - if (close (in_file_des) < 0) - close_error (orig_file_name); - break; - - case CP_IFDIR: - file_hdr.c_filesize = 0; - if (write_out_header (&file_hdr, out_file_des)) - continue; - break; - - case CP_IFCHR: - case CP_IFBLK: -#ifdef CP_IFSOCK - case CP_IFSOCK: -#endif -#ifdef CP_IFIFO - case CP_IFIFO: -#endif - if (archive_format == arf_tar) - { - error (0, 0, _("%s not dumped: not a regular file"), - orig_file_name); - continue; - } - else if (archive_format == arf_ustar) - { - char *otherfile; - if ((otherfile = find_inode_file (file_hdr.c_ino, - file_hdr.c_dev_maj, - file_hdr.c_dev_min))) - { - /* This file is linked to another file already in the - archive, so write it out as a hard link. */ - file_hdr.c_mode = (file_stat.st_mode & 07777); - file_hdr.c_mode |= CP_IFREG; - file_hdr.c_tar_linkname = otherfile; - if (write_out_header (&file_hdr, out_file_des)) - continue; - break; - } - add_inode (file_hdr.c_ino, orig_file_name, - file_hdr.c_dev_maj, file_hdr.c_dev_min); - } - file_hdr.c_filesize = 0; - if (write_out_header (&file_hdr, out_file_des)) - continue; - break; - -#ifdef CP_IFLNK - case CP_IFLNK: - { - char *link_name = (char *) xmalloc (file_stat.st_size + 1); - int link_size; - - link_size = readlink (orig_file_name, link_name, - file_stat.st_size); - if (link_size < 0) - { - readlink_warn (orig_file_name); - free (link_name); - continue; - } - link_name[link_size] = 0; - cpio_safer_name_suffix (link_name, false, - abs_paths_flag, true); - link_size = strlen (link_name); - file_hdr.c_filesize = link_size; - if (archive_format == arf_tar || archive_format == arf_ustar) - { - if (link_size + 1 > 100) - { - error (0, 0, _("%s: symbolic link too long"), - file_hdr.c_name); - } - else - { - link_name[link_size] = '\0'; - file_hdr.c_tar_linkname = link_name; - if (write_out_header (&file_hdr, out_file_des)) - continue; - } - } - else - { - if (write_out_header (&file_hdr, out_file_des)) - continue; - tape_buffered_write (link_name, out_file_des, link_size); - tape_pad_output (out_file_des, link_size); - } - free (link_name); - } - break; -#endif - - default: - error (0, 0, _("%s: unknown file type"), orig_file_name); - } - - if (verbose_flag) - fprintf (stderr, "%s\n", orig_file_name); - if (dot_flag) - fputc ('.', stderr); - } - } - - free (orig_file_name); - - writeout_final_defers(out_file_des); - /* The collection is complete; append the trailer. */ - file_hdr.c_ino = 0; - file_hdr.c_mode = 0; - file_hdr.c_uid = 0; - file_hdr.c_gid = 0; - file_hdr.c_nlink = 1; /* Must be 1 for crc format. */ - file_hdr.c_dev_maj = 0; - file_hdr.c_dev_min = 0; - file_hdr.c_rdev_maj = 0; - file_hdr.c_rdev_min = 0; - file_hdr.c_mtime = 0; - file_hdr.c_chksum = 0; - - file_hdr.c_filesize = 0; - file_hdr.c_namesize = 11; - file_hdr.c_name = CPIO_TRAILER_NAME; - if (archive_format != arf_tar && archive_format != arf_ustar) - write_out_header (&file_hdr, out_file_des); - else - write_nuls_to_file (1024, out_file_des, tape_buffered_write); - - /* Fill up the output block. */ - tape_clear_rest_of_block (out_file_des); - tape_empty_output_buffer (out_file_des); - if (dot_flag) - fputc ('\n', stderr); - if (!quiet_flag) - { - res = (output_bytes + io_block_size - 1) / io_block_size; - fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", res), res); - } -} - -static int -check_rdev (file_hdr) - struct cpio_file_stat *file_hdr; -{ - if (archive_format == arf_newascii || archive_format == arf_crcascii) - { - if ((file_hdr->c_rdev_maj & 0xFFFFFFFF) != file_hdr->c_rdev_maj) - return 1; - if ((file_hdr->c_rdev_min & 0xFFFFFFFF) != file_hdr->c_rdev_min) - return 2; - } - else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii) - { -#ifndef __MSDOS__ - dev_t rdev; - - rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min); - if (archive_format == arf_oldascii) - { - if ((rdev & 0xFFFF) != rdev) - return 4; - } - else - { - switch (file_hdr->c_mode & CP_IFMT) - { - case CP_IFCHR: - case CP_IFBLK: -#ifdef CP_IFSOCK - case CP_IFSOCK: -#endif -#ifdef CP_IFIFO - case CP_IFIFO: -#endif - /* We could handle one more bit if longs are >= 33 bits. */ - if ((rdev & 037777777777) != rdev) - return 4; - break; - default: - if ((rdev & 0xFFFF) != rdev) - return 4; - break; - } - } -#endif - } - else if (archive_format == arf_tar || archive_format == arf_ustar) - { - /* The major and minor formats are limited to 7 octal digits in ustar - format, and to_oct () adds a gratuitous trailing blank to further - limit the format to 6 octal digits. */ - if ((file_hdr->c_rdev_maj & 0777777) != file_hdr->c_rdev_maj) - return 1; - if ((file_hdr->c_rdev_min & 0777777) != file_hdr->c_rdev_min) - return 2; - } - else - { -#ifndef __MSDOS__ - dev_t rdev; - - rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min); - if (archive_format != arf_hpbinary) - { - if ((rdev & 0xFFFF) != rdev) - return 4; - } - else - { - switch (file_hdr->c_mode & CP_IFMT) - { - case CP_IFCHR: - case CP_IFBLK: -#ifdef CP_IFSOCK - case CP_IFSOCK: -#endif -#ifdef CP_IFIFO - case CP_IFIFO: -#endif - if ((rdev & 0xFFFFFFFF) != rdev) - return 4; - file_hdr->c_filesize = rdev; - rdev = makedev (0, 1); - break; - default: - if ((rdev & 0xFFFF) != rdev) - return 4; - break; - } - } -#endif - } - return 0; -} diff --git a/contrib/cpio/src/copypass.c b/contrib/cpio/src/copypass.c deleted file mode 100644 index bdcbbeba740..00000000000 --- a/contrib/cpio/src/copypass.c +++ /dev/null @@ -1,443 +0,0 @@ -/* $FreeBSD$ */ - -/* copypass.c - cpio copy pass sub-function. - Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004, - 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#include - -#include -#include -#include -#include "filetypes.h" -#include "cpiohdr.h" -#include "dstring.h" -#include "extern.h" -#include "paxlib.h" - -#ifndef HAVE_LCHOWN -# define lchown chown -#endif - - -/* A wrapper around set_perms using another set of arguments */ -static void -set_copypass_perms (int fd, const char *name, struct stat *st) -{ - struct cpio_file_stat header; - header.c_name = name; - stat_to_cpio (&header, st); - set_perms (fd, &header); -} - -/* Copy files listed on the standard input into directory `directory_name'. - If `link_flag', link instead of copying. */ - -void -process_copy_pass () -{ - dynamic_string input_name; /* Name of file from stdin. */ - dynamic_string output_name; /* Name of new file. */ - int dirname_len; /* Length of `directory_name'. */ - int res; /* Result of functions. */ - char *slash; /* For moving past slashes in input name. */ - struct stat in_file_stat; /* Stat record for input file. */ - struct stat out_file_stat; /* Stat record for output file. */ - int in_file_des; /* Input file descriptor. */ - int out_file_des; /* Output file descriptor. */ - int existing_dir; /* True if file is a dir & already exists. */ -#ifdef HPUX_CDF - int cdf_flag; - int cdf_char; -#endif - - umask (0); /* Reset umask to preserve modes of - created files */ - - /* Initialize the copy pass. */ - dirname_len = strlen (directory_name); - ds_init (&input_name, 128); - ds_init (&output_name, dirname_len + 2); - strcpy (output_name.ds_string, directory_name); - output_name.ds_string[dirname_len] = '/'; - output_is_seekable = true; - - /* Copy files with names read from stdin. */ - while (ds_fgetstr (stdin, &input_name, name_end) != NULL) - { - int link_res = -1; - - /* Check for blank line and ignore it if found. */ - if (input_name.ds_string[0] == '\0') - { - error (0, 0, _("blank line ignored")); - continue; - } - - /* Check for current directory and ignore it if found. */ - if (input_name.ds_string[0] == '.' - && (input_name.ds_string[1] == '\0' - || (input_name.ds_string[1] == '/' - && input_name.ds_string[2] == '\0'))) - continue; - - if ((*xstat) (input_name.ds_string, &in_file_stat) < 0) - { - stat_error (input_name.ds_string); - continue; - } - - /* Make the name of the new file. */ - for (slash = input_name.ds_string; *slash == '/'; ++slash) - ; -#ifdef HPUX_CDF - /* For CDF's we add a 2nd `/' after all "hidden" directories. - This kind of a kludge, but it's what we do when creating - archives, and it's easier to do this than to separately - keep track of which directories in a path are "hidden". */ - slash = add_cdf_double_slashes (slash); -#endif - ds_resize (&output_name, dirname_len + strlen (slash) + 2); - strcpy (output_name.ds_string + dirname_len + 1, slash); - - existing_dir = false; - if (lstat (output_name.ds_string, &out_file_stat) == 0) - { - if (S_ISDIR (out_file_stat.st_mode) - && S_ISDIR (in_file_stat.st_mode)) - { - /* If there is already a directory there that - we are trying to create, don't complain about it. */ - existing_dir = true; - } - else if (!unconditional_flag - && in_file_stat.st_mtime <= out_file_stat.st_mtime) - { - error (0, 0, _("%s not created: newer or same age version exists"), - output_name.ds_string); - continue; /* Go to the next file. */ - } - else if (S_ISDIR (out_file_stat.st_mode) - ? rmdir (output_name.ds_string) - : unlink (output_name.ds_string)) - { - error (0, errno, _("cannot remove current %s"), - output_name.ds_string); - continue; /* Go to the next file. */ - } - } - - /* Do the real copy or link. */ - if (S_ISREG (in_file_stat.st_mode)) - { - /* Can the current file be linked to a another file? - Set link_name to the original file name. */ - if (link_flag) - /* User said to link it if possible. Try and link to - the original copy. If that fails we'll still try - and link to a copy we've already made. */ - link_res = link_to_name (output_name.ds_string, - input_name.ds_string); - if ( (link_res < 0) && (in_file_stat.st_nlink > 1) ) - link_res = link_to_maj_min_ino (output_name.ds_string, - major (in_file_stat.st_dev), - minor (in_file_stat.st_dev), - in_file_stat.st_ino); - - /* If the file was not linked, copy contents of file. */ - if (link_res < 0) - { - in_file_des = open (input_name.ds_string, - O_RDONLY | O_BINARY, 0); - if (in_file_des < 0) - { - open_error (input_name.ds_string); - continue; - } - out_file_des = open (output_name.ds_string, - O_CREAT | O_WRONLY | O_BINARY, 0600); - if (out_file_des < 0 && create_dir_flag) - { - create_all_directories (output_name.ds_string); - out_file_des = open (output_name.ds_string, - O_CREAT | O_WRONLY | O_BINARY, 0600); - } - if (out_file_des < 0) - { - open_error (output_name.ds_string); - close (in_file_des); - continue; - } - - copy_files_disk_to_disk (in_file_des, out_file_des, in_file_stat.st_size, input_name.ds_string); - disk_empty_output_buffer (out_file_des); - /* Debian hack to fix a bug in the --sparse option. - This bug has been reported to - "bug-gnu-utils@prep.ai.mit.edu". (96/7/10) -BEM */ - if (delayed_seek_count > 0) - { - lseek (out_file_des, delayed_seek_count-1, SEEK_CUR); - write (out_file_des, "", 1); - delayed_seek_count = 0; - } - - set_copypass_perms (out_file_des, - output_name.ds_string, &in_file_stat); - - if (reset_time_flag) - { - set_file_times (in_file_des, - input_name.ds_string, - in_file_stat.st_atime, - in_file_stat.st_mtime); - set_file_times (out_file_des, - output_name.ds_string, - in_file_stat.st_atime, - in_file_stat.st_mtime); - } - - if (close (in_file_des) < 0) - close_error (input_name.ds_string); - - if (close (out_file_des) < 0) - close_error (output_name.ds_string); - - warn_if_file_changed(input_name.ds_string, in_file_stat.st_size, - in_file_stat.st_mtime); - } - } - else if (S_ISDIR (in_file_stat.st_mode)) - { -#ifdef HPUX_CDF - cdf_flag = 0; -#endif - if (!existing_dir) - { -#ifdef HPUX_CDF - /* If the directory name ends in a + and is SUID, - then it is a CDF. Strip the trailing + from the name - before creating it. */ - cdf_char = strlen (output_name.ds_string) - 1; - if ( (cdf_char > 0) && - (in_file_stat.st_mode & 04000) && - (output_name.ds_string [cdf_char] == '+') ) - { - output_name.ds_string [cdf_char] = '\0'; - cdf_flag = 1; - } -#endif - res = mkdir (output_name.ds_string, in_file_stat.st_mode); - - } - else - res = 0; - if (res < 0 && create_dir_flag) - { - create_all_directories (output_name.ds_string); - res = mkdir (output_name.ds_string, in_file_stat.st_mode); - } - if (res < 0) - { - /* In some odd cases where the output_name includes `.', - the directory may have actually been created by - create_all_directories(), so the mkdir will fail - because the directory exists. If that's the case, - don't complain about it. */ - if ( (errno != EEXIST) || - (lstat (output_name.ds_string, &out_file_stat) != 0) || - !(S_ISDIR (out_file_stat.st_mode) ) ) - { - stat_error (output_name.ds_string); - continue; - } - } - set_copypass_perms (-1, output_name.ds_string, &in_file_stat); - } - else if (S_ISCHR (in_file_stat.st_mode) || - S_ISBLK (in_file_stat.st_mode) || -#ifdef S_ISFIFO - S_ISFIFO (in_file_stat.st_mode) || -#endif -#ifdef S_ISSOCK - S_ISSOCK (in_file_stat.st_mode) || -#endif - 0) - { - /* Can the current file be linked to a another file? - Set link_name to the original file name. */ - if (link_flag) - /* User said to link it if possible. */ - link_res = link_to_name (output_name.ds_string, - input_name.ds_string); - if ( (link_res < 0) && (in_file_stat.st_nlink > 1) ) - link_res = link_to_maj_min_ino (output_name.ds_string, - major (in_file_stat.st_dev), - minor (in_file_stat.st_dev), - in_file_stat.st_ino); - - if (link_res < 0) - { -#ifdef S_ISFIFO - if (S_ISFIFO (in_file_stat.st_mode)) - res = mkfifo (output_name.ds_string, in_file_stat.st_mode); - else -#endif - res = mknod (output_name.ds_string, in_file_stat.st_mode, - in_file_stat.st_rdev); - if (res < 0 && create_dir_flag) - { - create_all_directories (output_name.ds_string); -#ifdef S_ISFIFO - if (S_ISFIFO (in_file_stat.st_mode)) - res = mkfifo (output_name.ds_string, in_file_stat.st_mode); - else -#endif - res = mknod (output_name.ds_string, in_file_stat.st_mode, - in_file_stat.st_rdev); - } - if (res < 0) - { - mknod_error (output_name.ds_string); - continue; - } - set_copypass_perms (-1, output_name.ds_string, &in_file_stat); - } - } - -#ifdef S_ISLNK - else if (S_ISLNK (in_file_stat.st_mode)) - { - char *link_name; - int link_size; - link_name = (char *) xmalloc ((unsigned int) in_file_stat.st_size + 1); - - link_size = readlink (input_name.ds_string, link_name, - in_file_stat.st_size); - if (link_size < 0) - { - readlink_error (input_name.ds_string); - free (link_name); - continue; - } - link_name[link_size] = '\0'; - - res = UMASKED_SYMLINK (link_name, output_name.ds_string, - in_file_stat.st_mode); - if (res < 0 && create_dir_flag) - { - create_all_directories (output_name.ds_string); - res = UMASKED_SYMLINK (link_name, output_name.ds_string, - in_file_stat.st_mode); - } - if (res < 0) - { - symlink_error (output_name.ds_string, link_name); - free (link_name); - continue; - } - - /* Set the attributes of the new link. */ - if (!no_chown_flag) - { - uid_t uid = set_owner_flag ? set_owner : in_file_stat.st_uid; - gid_t gid = set_group_flag ? set_group : in_file_stat.st_gid; - if ((lchown (output_name.ds_string, uid, gid) < 0) - && errno != EPERM) - chown_error_details (output_name.ds_string, uid, gid); - } - free (link_name); - } -#endif - else - { - error (0, 0, _("%s: unknown file type"), input_name.ds_string); - } - - if (verbose_flag) - fprintf (stderr, "%s\n", output_name.ds_string); - if (dot_flag) - fputc ('.', stderr); - } - - if (dot_flag) - fputc ('\n', stderr); - if (!quiet_flag) - { - res = (output_bytes + io_block_size - 1) / io_block_size; - fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", res), res); - } -} - -/* Try and create a hard link from FILE_NAME to another file - with the given major/minor device number and inode. If no other - file with the same major/minor/inode numbers is known, add this file - to the list of known files and associated major/minor/inode numbers - and return -1. If another file with the same major/minor/inode - numbers is found, try and create another link to it using - link_to_name, and return 0 for success and -1 for failure. */ - -int -link_to_maj_min_ino (char *file_name, int st_dev_maj, int st_dev_min, - int st_ino) -{ - int link_res; - char *link_name; - link_res = -1; - /* Is the file a link to a previously copied file? */ - link_name = find_inode_file (st_ino, - st_dev_maj, - st_dev_min); - if (link_name == NULL) - add_inode (st_ino, file_name, - st_dev_maj, - st_dev_min); - else - link_res = link_to_name (file_name, link_name); - return link_res; -} - -/* Try and create a hard link from LINK_NAME to LINK_TARGET. If - `create_dir_flag' is set, any non-existent (parent) directories - needed by LINK_NAME will be created. If the link is successfully - created and `verbose_flag' is set, print "LINK_TARGET linked to LINK_NAME\n". - If the link can not be created and `link_flag' is set, print - "cannot link LINK_TARGET to LINK_NAME\n". Return 0 if the link - is created, -1 otherwise. */ - -int -link_to_name (char *link_name, char *link_target) -{ - int res = link (link_target, link_name); - if (res < 0 && create_dir_flag) - { - create_all_directories (link_name); - res = link (link_target, link_name); - } - if (res == 0) - { - if (verbose_flag) - error (0, 0, _("%s linked to %s"), - link_target, link_name); - } - else if (link_flag) - { - error (0, errno, _("cannot link %s to %s (will copy instead)"), - link_target, link_name); - } - return res; -} diff --git a/contrib/cpio/src/cpio.h b/contrib/cpio/src/cpio.h deleted file mode 100644 index 34d1cf10e40..00000000000 --- a/contrib/cpio/src/cpio.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Extended cpio format from POSIX.1. - Copyright (C) 1992, 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#ifndef _CPIO_H - -#define _CPIO_H 1 - -/* A cpio archive consists of a sequence of files. - Each file has a 76 byte header, - a variable length, NUL terminated filename, - and variable length file data. - A header for a filename "TRAILER!!!" indicates the end of the archive. */ - -#define CPIO_TRAILER_NAME "TRAILER!!!" - -/* All the fields in the header are ISO 646 (approximately ASCII) strings - of octal numbers, left padded, not NUL terminated. - - Field Name Length in Bytes Notes - c_magic 6 must be "070707" - c_dev 6 - c_ino 6 - c_mode 6 see below for value - c_uid 6 - c_gid 6 - c_nlink 6 - c_rdev 6 only valid for chr and blk special files - c_mtime 11 - c_namesize 6 count includes terminating NUL in pathname - c_filesize 11 must be 0 for FIFOs and directories */ - -/* Values for c_mode, OR'd together: */ - -#define C_IRUSR 000400 -#define C_IWUSR 000200 -#define C_IXUSR 000100 -#define C_IRGRP 000040 -#define C_IWGRP 000020 -#define C_IXGRP 000010 -#define C_IROTH 000004 -#define C_IWOTH 000002 -#define C_IXOTH 000001 - -#define C_ISUID 004000 -#define C_ISGID 002000 -#define C_ISVTX 001000 - -#define C_ISBLK 060000 -#define C_ISCHR 020000 -#define C_ISDIR 040000 -#define C_ISFIFO 010000 -#define C_ISSOCK 0140000 -#define C_ISLNK 0120000 -#define C_ISCTG 0110000 -#define C_ISREG 0100000 - -#endif /* cpio.h */ diff --git a/contrib/cpio/src/cpiohdr.h b/contrib/cpio/src/cpiohdr.h deleted file mode 100644 index 503563f8440..00000000000 --- a/contrib/cpio/src/cpiohdr.h +++ /dev/null @@ -1,106 +0,0 @@ -/* Extended cpio header from POSIX.1. - Copyright (C) 1992, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#ifndef _CPIOHDR_H - -#define _CPIOHDR_H 1 - -#include - -struct old_cpio_header -{ - unsigned short c_magic; - short c_dev; - unsigned short c_ino; - unsigned short c_mode; - unsigned short c_uid; - unsigned short c_gid; - unsigned short c_nlink; - short c_rdev; - unsigned short c_mtimes[2]; - unsigned short c_namesize; - unsigned short c_filesizes[2]; -}; - -struct old_ascii_header -{ - char c_magic[6]; - char c_dev[6]; - char c_ino[6]; - char c_mode[6]; - char c_uid[6]; - char c_gid[6]; - char c_nlink[6]; - char c_rdev[6]; - char c_mtime[11]; - char c_namesize[6]; - char c_filesize[11]; -}; - -/* "New" portable format and CRC format: - - Each file has a 110 byte header, - a variable length, NUL terminated filename, - and variable length file data. - A header for a filename "TRAILER!!!" indicates the end of the archive. */ - -/* All the fields in the header are ISO 646 (approximately ASCII) strings - of hexadecimal numbers, left padded, not NUL terminated: */ - -struct new_ascii_header -{ - char c_magic[6]; /* "070701" for "new" portable format - "070702" for CRC format */ - char c_ino[8]; - char c_mode[8]; - char c_uid[8]; - char c_gid[8]; - char c_nlink[8]; - char c_mtime[8]; - char c_filesize[8]; /* must be 0 for FIFOs and directories */ - char c_dev_maj[8]; - char c_dev_min[8]; - char c_rdev_maj[8]; /* only valid for chr and blk special files */ - char c_rdev_min[8]; /* only valid for chr and blk special files */ - char c_namesize[8]; /* count includes terminating NUL in pathname */ - char c_chksum[8]; /* 0 for "new" portable format; for CRC format - the sum of all the bytes in the file */ -}; - -struct cpio_file_stat /* Internal representation of a CPIO header */ -{ - unsigned short c_magic; - ino_t c_ino; - mode_t c_mode; - uid_t c_uid; - gid_t c_gid; - size_t c_nlink; - time_t c_mtime; - off_t c_filesize; - long c_dev_maj; - long c_dev_min; - long c_rdev_maj; - long c_rdev_min; - size_t c_namesize; - unsigned long c_chksum; - char *c_name; - char *c_tar_linkname; -}; - - -#endif /* cpiohdr.h */ diff --git a/contrib/cpio/src/defer.c b/contrib/cpio/src/defer.c deleted file mode 100644 index 83e15dd7c3d..00000000000 --- a/contrib/cpio/src/defer.c +++ /dev/null @@ -1,43 +0,0 @@ -/* defer.c - handle "defered" links in newc and crc archives - Copyright (C) 1993, 2003, 2004, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#include - -#include -#include -#include "cpiohdr.h" -#include "extern.h" -#include "defer.h" - -struct deferment * -create_deferment (struct cpio_file_stat *file_hdr) -{ - struct deferment *d; - d = (struct deferment *) xmalloc (sizeof (struct deferment) ); - d->header = *file_hdr; - d->header.c_name = (char *) xmalloc (strlen (file_hdr->c_name) + 1); - strcpy (d->header.c_name, file_hdr->c_name); - return d; -} - -void -free_deferment (struct deferment *d) -{ - free (d->header.c_name); - free (d); -} diff --git a/contrib/cpio/src/defer.h b/contrib/cpio/src/defer.h deleted file mode 100644 index 00aafecc01b..00000000000 --- a/contrib/cpio/src/defer.h +++ /dev/null @@ -1,26 +0,0 @@ -/* defer.h - Copyright (C) 1993, 2001, 2004, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -struct deferment - { - struct deferment *next; - struct cpio_file_stat header; - }; - -struct deferment *create_deferment (struct cpio_file_stat *file_hdr); -void free_deferment (struct deferment *d); diff --git a/contrib/cpio/src/dstring.c b/contrib/cpio/src/dstring.c deleted file mode 100644 index aefeab88ce8..00000000000 --- a/contrib/cpio/src/dstring.c +++ /dev/null @@ -1,103 +0,0 @@ -/* dstring.c - The dynamic string handling routines used by cpio. - Copyright (C) 1990, 1991, 1992, 2004 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#if defined(HAVE_CONFIG_H) -# include -#endif - -#include -#if defined(HAVE_STRING_H) || defined(STDC_HEADERS) -#include -#else -#include -#endif -#include "dstring.h" - -char *xmalloc (unsigned n); -char *xrealloc (char *p, unsigned n); - -/* Initialiaze dynamic string STRING with space for SIZE characters. */ - -void -ds_init (dynamic_string *string, int size) -{ - string->ds_length = size; - string->ds_string = (char *) xmalloc (size); -} - -/* Expand dynamic string STRING, if necessary, to hold SIZE characters. */ - -void -ds_resize (dynamic_string *string, int size) -{ - if (size > string->ds_length) - { - string->ds_length = size; - string->ds_string = (char *) xrealloc ((char *) string->ds_string, size); - } -} - -/* Dynamic string S gets a string terminated by the EOS character - (which is removed) from file F. S will increase - in size during the function if the string from F is longer than - the current size of S. - Return NULL if end of file is detected. Otherwise, - Return a pointer to the null-terminated string in S. */ - -char * -ds_fgetstr (FILE *f, dynamic_string *s, char eos) -{ - int insize; /* Amount needed for line. */ - int strsize; /* Amount allocated for S. */ - int next_ch; - - /* Initialize. */ - insize = 0; - strsize = s->ds_length; - - /* Read the input string. */ - next_ch = getc (f); - while (next_ch != eos && next_ch != EOF) - { - if (insize >= strsize - 1) - { - ds_resize (s, strsize * 2 + 2); - strsize = s->ds_length; - } - s->ds_string[insize++] = next_ch; - next_ch = getc (f); - } - s->ds_string[insize++] = '\0'; - - if (insize == 1 && next_ch == EOF) - return NULL; - else - return s->ds_string; -} - -char * -ds_fgets (FILE *f, dynamic_string *s) -{ - return ds_fgetstr (f, s, '\n'); -} - -char * -ds_fgetname (FILE *f, dynamic_string *s) -{ - return ds_fgetstr (f, s, '\0'); -} diff --git a/contrib/cpio/src/dstring.h b/contrib/cpio/src/dstring.h deleted file mode 100644 index 3628b99b3f6..00000000000 --- a/contrib/cpio/src/dstring.h +++ /dev/null @@ -1,50 +0,0 @@ -/* dstring.h - Dynamic string handling include file. Requires strings.h. - Copyright (C) 1990, 1991, 1992, 2004 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#ifndef NULL -#define NULL 0 -#endif - -/* A dynamic string consists of record that records the size of an - allocated string and the pointer to that string. The actual string - is a normal zero byte terminated string that can be used with the - usual string functions. The major difference is that the - dynamic_string routines know how to get more space if it is needed - by allocating new space and copying the current string. */ - -typedef struct -{ - int ds_length; /* Actual amount of storage allocated. */ - char *ds_string; /* String. */ -} dynamic_string; - - -/* Macros that look similar to the original string functions. - WARNING: These macros work only on pointers to dynamic string records. - If used with a real record, an "&" must be used to get the pointer. */ -#define ds_strlen(s) strlen ((s)->ds_string) -#define ds_strcmp(s1, s2) strcmp ((s1)->ds_string, (s2)->ds_string) -#define ds_strncmp(s1, s2, n) strncmp ((s1)->ds_string, (s2)->ds_string, n) -#define ds_index(s, c) index ((s)->ds_string, c) -#define ds_rindex(s, c) rindex ((s)->ds_string, c) - -void ds_init (dynamic_string *string, int size); -void ds_resize (dynamic_string *string, int size); -char *ds_fgetname (FILE *f, dynamic_string *s); -char *ds_fgets (FILE *f, dynamic_string *s); -char *ds_fgetstr (FILE *f, dynamic_string *s, char eos); diff --git a/contrib/cpio/src/extern.h b/contrib/cpio/src/extern.h deleted file mode 100644 index cc5bf89f12e..00000000000 --- a/contrib/cpio/src/extern.h +++ /dev/null @@ -1,221 +0,0 @@ -/* extern.h - External declarations for cpio. Requires system.h. - Copyright (C) 1990, 1991, 1992, 2001, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#include "paxlib.h" -#include "quotearg.h" -#include "quote.h" - -enum archive_format -{ - arf_unknown, arf_binary, arf_oldascii, arf_newascii, arf_crcascii, - arf_tar, arf_ustar, arf_hpoldascii, arf_hpbinary -}; - -extern enum archive_format archive_format; -extern int reset_time_flag; -extern int io_block_size; -extern int create_dir_flag; -extern int rename_flag; -extern char *rename_batch_file; -extern int table_flag; -extern int unconditional_flag; -extern int verbose_flag; -extern int dot_flag; -extern int link_flag; -extern int retain_time_flag; -extern int crc_i_flag; -extern int append_flag; -extern int swap_bytes_flag; -extern int swap_halfwords_flag; -extern int swapping_bytes; -extern int swapping_halfwords; -extern int set_owner_flag; -extern uid_t set_owner; -extern int set_group_flag; -extern gid_t set_group; -extern int no_chown_flag; -extern int sparse_flag; -extern int quiet_flag; -extern int only_verify_crc_flag; -extern int abs_paths_flag; -extern unsigned int warn_option; - -/* Values for warn_option */ -#define CPIO_WARN_NONE 0 -#define CPIO_WARN_TRUNCATE 0x01 -#define CPIO_WARN_ALL (unsigned int)-1 - -extern bool to_stdout_option; - -extern int last_header_start; -extern int copy_matching_files; -extern int numeric_uid; -extern char *pattern_file_name; -extern char *new_media_message; -extern char *new_media_message_with_number; -extern char *new_media_message_after_number; -extern int archive_des; -extern char *archive_name; -extern char *rsh_command_option; -extern unsigned int crc; -extern int delayed_seek_count; -#ifdef DEBUG_CPIO -extern int debug_flag; -#endif - -extern char *input_buffer, *output_buffer; -extern char *in_buff, *out_buff; -extern long input_buffer_size; -extern long input_size, output_size; -#ifdef __GNUC__ -extern long long input_bytes, output_bytes; -#else -extern long input_bytes, output_bytes; -#endif -extern char *directory_name; -extern char **save_patterns; -extern int num_patterns; -extern char name_end; -extern char input_is_special; -extern char output_is_special; -extern char input_is_seekable; -extern char output_is_seekable; -extern char *program_name; -extern int (*xstat) (); -extern void (*copy_function) (); - - -/* copyin.c */ -void warn_junk_bytes (long bytes_skipped); -/* FIXME: make read_* static in copyin.c */ -void read_in_header (struct cpio_file_stat *file_hdr, int in_des); -void read_in_old_ascii (struct cpio_file_stat *file_hdr, int in_des); -void read_in_new_ascii (struct cpio_file_stat *file_hdr, int in_des); -void read_in_binary (struct cpio_file_stat *file_hdr, - struct old_cpio_header *short_hdr, int in_des); -void swab_array (char *arg, int count); -void process_copy_in (void); -void long_format (struct cpio_file_stat *file_hdr, char *link_name); -void print_name_with_quoting (char *p); - -/* copyout.c */ -int write_out_header (struct cpio_file_stat *file_hdr, int out_des); -void process_copy_out (void); - -/* copypass.c */ -void process_copy_pass (void); -int link_to_maj_min_ino (char *file_name, int st_dev_maj, - int st_dev_min, int st_ino); -int link_to_name (char *link_name, char *link_target); - -/* dirname.c */ -char *dirname (char *path); - -/* filemode.c */ -void mode_string (unsigned int mode, char *str); - -/* idcache.c */ -#ifndef __MSDOS__ -char *getgroup (); -char *getuser (); -uid_t *getuidbyname (); -gid_t *getgidbyname (); -#endif - -/* main.c */ -void process_args (int argc, char *argv[]); -void initialize_buffers (void); - -/* makepath.c */ -int make_path (char *argpath, int mode, int parent_mode, - uid_t owner, gid_t group, char *verbose_fmt_string); - -/* tar.c */ -void write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des); -int null_block (long *block, int size); -void read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des); -int otoa (char *s, unsigned long *n); -int is_tar_header (char *buf); -int is_tar_filename_too_long (char *name); - -/* userspec.c */ -#ifndef __MSDOS__ -char *parse_user_spec (char *name, uid_t *uid, gid_t *gid, - char **username, char **groupname); -#endif - -/* util.c */ -void tape_empty_output_buffer (int out_des); -void disk_empty_output_buffer (int out_des); -void swahw_array (char *ptr, int count); -void tape_buffered_write (char *in_buf, int out_des, off_t num_bytes); -void tape_buffered_read (char *in_buf, int in_des, off_t num_bytes); -int tape_buffered_peek (char *peek_buf, int in_des, int num_bytes); -void tape_toss_input (int in_des, off_t num_bytes); -void copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes); -void copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes, char *filename); -void copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes, char *filename); -void warn_if_file_changed (char *file_name, unsigned long old_file_size, - off_t old_file_mtime); -void create_all_directories (char *name); -void prepare_append (int out_file_des); -char *find_inode_file (unsigned long node_num, - unsigned long major_num, unsigned long minor_num); -void add_inode (unsigned long node_num, char *file_name, - unsigned long major_num, unsigned long minor_num); -int open_archive (char *file); -void tape_offline (int tape_des); -void get_next_reel (int tape_des); -void set_new_media_message (char *message); -#if defined(__MSDOS__) && !defined(__GNUC__) -int chown (char *path, int owner, int group); -#endif -#ifdef __TURBOC__ -int utime (char *filename, struct utimbuf *utb); -#endif -#ifdef HPUX_CDF -char *add_cdf_double_slashes (char *filename); -#endif -void write_nuls_to_file (off_t num_bytes, int out_des, - void (*writer) (char *in_buf, - int out_des, off_t num_bytes)); -#define DISK_IO_BLOCK_SIZE 512 - -/* FIXME: Move to system.h? */ -#ifndef SYMLINK_USES_UMASK -# define UMASKED_SYMLINK(name1,name2,mode) symlink(name1,name2) -#else -# define UMASKED_SYMLINK(name1,name2,mode) umasked_symlink(name1,name2,mode) -#endif /* SYMLINK_USES_UMASK */ - -void set_perms (int fd, struct cpio_file_stat *header); -void set_file_times (int fd, const char *name, unsigned long atime, - unsigned long mtime); -void stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st); -void cpio_safer_name_suffix (char *name, bool link_target, - bool absolute_names, bool strip_leading_dots); - -/* FIXME: These two defines should be defined in paxutils */ -#define LG_8 3 -#define LG_16 4 - -uintmax_t from_ascii (char const *where, size_t digs, unsigned logbase); - -#define FROM_OCTAL(f) from_ascii (f, sizeof f, LG_8) -#define FROM_HEX(f) from_ascii (f, sizeof f, LG_16) - diff --git a/contrib/cpio/src/filemode.c b/contrib/cpio/src/filemode.c deleted file mode 100644 index 98f281370dd..00000000000 --- a/contrib/cpio/src/filemode.c +++ /dev/null @@ -1,243 +0,0 @@ -/* filemode.c -- make a string describing file modes - Copyright (C) 1985, 1990, 1993, 2004 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#if !S_IRUSR -# if S_IREAD -# define S_IRUSR S_IREAD -# else -# define S_IRUSR 00400 -# endif -#endif - -#if !S_IWUSR -# if S_IWRITE -# define S_IWUSR S_IWRITE -# else -# define S_IWUSR 00200 -# endif -#endif - -#if !S_IXUSR -# if S_IEXEC -# define S_IXUSR S_IEXEC -# else -# define S_IXUSR 00100 -# endif -#endif - -#ifdef STAT_MACROS_BROKEN -#undef S_ISBLK -#undef S_ISCHR -#undef S_ISDIR -#undef S_ISFIFO -#undef S_ISLNK -#undef S_ISMPB -#undef S_ISMPC -#undef S_ISNWK -#undef S_ISREG -#undef S_ISSOCK -#endif /* STAT_MACROS_BROKEN. */ - -#if !defined(S_ISBLK) && defined(S_IFBLK) -#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -#endif -#if !defined(S_ISCHR) && defined(S_IFCHR) -#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -#endif -#if !defined(S_ISDIR) && defined(S_IFDIR) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif -#if !defined(S_ISREG) && defined(S_IFREG) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif -#if !defined(S_ISFIFO) && defined(S_IFIFO) -#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -#endif -#if !defined(S_ISLNK) && defined(S_IFLNK) -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#if !defined(S_ISSOCK) && defined(S_IFSOCK) -#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -#endif -#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */ -#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) -#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) -#endif -#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */ -#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) -#endif - -/* Return a character indicating the type of file described by - file mode BITS: - 'd' for directories - 'b' for block special files - 'c' for character special files - 'm' for multiplexor files - 'l' for symbolic links - 's' for sockets - 'p' for fifos - '-' for regular files - '?' for any other file type. */ - -static char -ftypelet (long bits) -{ -#ifdef S_ISBLK - if (S_ISBLK (bits)) - return 'b'; -#endif - if (S_ISCHR (bits)) - return 'c'; - if (S_ISDIR (bits)) - return 'd'; - if (S_ISREG (bits)) - return '-'; -#ifdef S_ISFIFO - if (S_ISFIFO (bits)) - return 'p'; -#endif -#ifdef S_ISLNK - if (S_ISLNK (bits)) - return 'l'; -#endif -#ifdef S_ISSOCK - if (S_ISSOCK (bits)) - return 's'; -#endif -#ifdef S_ISMPC - if (S_ISMPC (bits)) - return 'm'; -#endif -#ifdef S_ISNWK - if (S_ISNWK (bits)) - return 'n'; -#endif - return '?'; -} - -/* Look at read, write, and execute bits in BITS and set - flags in CHARS accordingly. */ - -static void -rwx (unsigned short bits, char *chars) -{ - chars[0] = (bits & S_IRUSR) ? 'r' : '-'; - chars[1] = (bits & S_IWUSR) ? 'w' : '-'; - chars[2] = (bits & S_IXUSR) ? 'x' : '-'; -} - -/* Set the 's' and 't' flags in file attributes string CHARS, - according to the file mode BITS. */ - -static void -setst (unsigned short bits, char *chars) -{ -#ifdef S_ISUID - if (bits & S_ISUID) - { - if (chars[3] != 'x') - /* Set-uid, but not executable by owner. */ - chars[3] = 'S'; - else - chars[3] = 's'; - } -#endif -#ifdef S_ISGID - if (bits & S_ISGID) - { - if (chars[6] != 'x') - /* Set-gid, but not executable by group. */ - chars[6] = 'S'; - else - chars[6] = 's'; - } -#endif -#ifdef S_ISVTX - if (bits & S_ISVTX) - { - if (chars[9] != 'x') - /* Sticky, but not executable by others. */ - chars[9] = 'T'; - else - chars[9] = 't'; - } -#endif -} - -/* Like filemodestring (see below), but only the relevant part of the - `struct stat' is given as an argument. */ - -void -mode_string (unsigned short mode, char *str) -{ - str[0] = ftypelet ((long) mode); - rwx ((mode & 0700) << 0, &str[1]); - rwx ((mode & 0070) << 3, &str[4]); - rwx ((mode & 0007) << 6, &str[7]); - setst (mode, str); -} - -/* filemodestring - fill in string STR with an ls-style ASCII - representation of the st_mode field of file stats block STATP. - 10 characters are stored in STR; no terminating null is added. - The characters stored in STR are: - - 0 File type. 'd' for directory, 'c' for character - special, 'b' for block special, 'm' for multiplex, - 'l' for symbolic link, 's' for socket, 'p' for fifo, - '-' for regular, '?' for any other file type - - 1 'r' if the owner may read, '-' otherwise. - - 2 'w' if the owner may write, '-' otherwise. - - 3 'x' if the owner may execute, 's' if the file is - set-user-id, '-' otherwise. - 'S' if the file is set-user-id, but the execute - bit isn't set. - - 4 'r' if group members may read, '-' otherwise. - - 5 'w' if group members may write, '-' otherwise. - - 6 'x' if group members may execute, 's' if the file is - set-group-id, '-' otherwise. - 'S' if it is set-group-id but not executable. - - 7 'r' if any user may read, '-' otherwise. - - 8 'w' if any user may write, '-' otherwise. - - 9 'x' if any user may execute, 't' if the file is "sticky" - (will be retained in swap space after execution), '-' - otherwise. - 'T' if the file is sticky but not executable. */ - -void -filemodestring (struct stat *statp, char *str) -{ - mode_string (statp->st_mode, str); -} - diff --git a/contrib/cpio/src/filetypes.h b/contrib/cpio/src/filetypes.h deleted file mode 100644 index de6d77f6284..00000000000 --- a/contrib/cpio/src/filetypes.h +++ /dev/null @@ -1,85 +0,0 @@ -/* filetypes.h - deal with POSIX annoyances - Copyright (C) 1991 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -/* Include sys/types.h and sys/stat.h before this file. */ - -#ifndef S_ISREG /* Doesn't have POSIX.1 stat stuff. */ -#define mode_t unsigned short -#endif - -/* Define the POSIX macros for systems that lack them. */ -#if !defined(S_ISBLK) && defined(S_IFBLK) -#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -#endif -#if !defined(S_ISCHR) && defined(S_IFCHR) -#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -#endif -#if !defined(S_ISDIR) && defined(S_IFDIR) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif -#if !defined(S_ISREG) && defined(S_IFREG) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif -#if !defined(S_ISFIFO) && defined(S_IFIFO) -#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -#endif -#if !defined(S_ISLNK) && defined(S_IFLNK) -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#if !defined(S_ISSOCK) && defined(S_IFSOCK) -#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -#endif -#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX network special */ -#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) -#endif - -/* Define the file type bits used in cpio archives. - They have the same values as the S_IF bits in traditional Unix. */ - -#define CP_IFMT 0170000 /* Mask for all file type bits. */ - -#if defined(S_ISBLK) -#define CP_IFBLK 0060000 -#endif -#if defined(S_ISCHR) -#define CP_IFCHR 0020000 -#endif -#if defined(S_ISDIR) -#define CP_IFDIR 0040000 -#endif -#if defined(S_ISREG) -#define CP_IFREG 0100000 -#endif -#if defined(S_ISFIFO) -#define CP_IFIFO 0010000 -#endif -#if defined(S_ISLNK) -#define CP_IFLNK 0120000 -#endif -#if defined(S_ISSOCK) -#define CP_IFSOCK 0140000 -#endif -#if defined(S_ISNWK) -#define CP_IFNWK 0110000 -#endif - -#ifndef S_ISLNK -#define lstat stat -#endif -int lstat (); -int stat (); diff --git a/contrib/cpio/src/global.c b/contrib/cpio/src/global.c deleted file mode 100644 index fdee7be34d7..00000000000 --- a/contrib/cpio/src/global.c +++ /dev/null @@ -1,201 +0,0 @@ -/* global.c - global variables and initial values for cpio. - Copyright (C) 1990, 1991, 1992, 2001, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#include - -#include -#include "cpiohdr.h" -#include "dstring.h" -#include "extern.h" - -/* If true, reset access times after reading files (-a). */ -int reset_time_flag = false; - -/* Block size value, initially 512. -B sets to 5120. */ -int io_block_size = 512; - -/* The header format to recognize and produce. */ -enum archive_format archive_format = arf_unknown; - -/* If true, create directories as needed. (-d with -i or -p) */ -int create_dir_flag = false; - -/* If true, interactively rename files. (-r) */ -int rename_flag = false; - -/* If non-NULL, the name of a file that will be read to - rename all of the files in the archive. --rename-batch-file. */ -char *rename_batch_file = NULL; - -/* If true, print a table of contents of input. (-t) */ -int table_flag = false; - -/* If true, copy unconditionally (older replaces newer). (-u) */ -int unconditional_flag = false; - -/* If true, list the files processed, or ls -l style output with -t. (-v) */ -int verbose_flag = false; - -/* If true, print a . for each file processed. (-V) */ -int dot_flag = false; - -/* If true, link files whenever possible. Used with -p option. (-l) */ -int link_flag = false; - -/* If true, retain previous file modification time. (-m) */ -int retain_time_flag = false; - -/* Set true if crc_flag is true and we are doing a cpio -i. Used - by copy_files so it knows whether to compute the crc. */ -int crc_i_flag = false; - -/* If true, append to end of archive. (-A) */ -int append_flag = false; - -/* If true, swap bytes of each file during cpio -i. */ -int swap_bytes_flag = false; - -/* If true, swap halfwords of each file during cpio -i. */ -int swap_halfwords_flag = false; - -/* If true, we are swapping halfwords on the current file. */ -int swapping_halfwords = false; - -/* If true, we are swapping bytes on the current file. */ -int swapping_bytes = false; - -/* If true, set ownership of all files to UID `set_owner'. */ -int set_owner_flag = false; -uid_t set_owner; - -/* If true, set group ownership of all files to GID `set_group'. */ -int set_group_flag = false; -gid_t set_group; - -/* If true, do not chown the files. */ -int no_chown_flag = false; - -/* If true, try to write sparse ("holey") files. */ -int sparse_flag = false; - -/* If true, don't report number of blocks copied. */ -int quiet_flag = false; - -/* If true, only read the archive and verify the files' CRC's, don't - actually extract the files. */ -int only_verify_crc_flag = false; - -/* If true, don't use any absolute paths, prefix them by `./'. */ -int abs_paths_flag = false; - -#ifdef DEBUG_CPIO -/* If true, print debugging information. */ -int debug_flag = false; -#endif - -/* File position of last header read. Only used during -A to determine - where the old TRAILER!!! record started. */ -int last_header_start = 0; - -/* With -i; if true, copy only files that match any of the given patterns; - if false, copy only files that do not match any of the patterns. (-f) */ -int copy_matching_files = true; - -/* With -itv; if true, list numeric uid and gid instead of translating them - into names. */ -int numeric_uid = false; - -/* Name of file containing additional patterns (-E). */ -char *pattern_file_name = NULL; - -/* Message to print when end of medium is reached (-M). */ -char *new_media_message = NULL; - -/* With -M with %d, message to print when end of medium is reached. */ -char *new_media_message_with_number = NULL; -char *new_media_message_after_number = NULL; - -/* File descriptor containing the archive. */ -int archive_des; - -/* Name of file containing the archive, if known; NULL if stdin/out. */ -char *archive_name = NULL; - -/* Name of the remote shell command, if known; NULL otherwise. */ -char *rsh_command_option = NULL; - -/* CRC checksum. */ -unsigned int crc; - -/* Input and output buffers. */ -char *input_buffer, *output_buffer; - -/* The size of the input buffer. */ -long input_buffer_size; - -/* Current locations in `input_buffer' and `output_buffer'. */ -char *in_buff, *out_buff; - -/* Current number of bytes stored at `input_buff' and `output_buff'. */ -long input_size, output_size; - -/* Total number of bytes read and written for all files. - Now that many tape drives hold more than 4Gb we need more than 32 - bits to hold input_bytes and output_bytes. But it's not worth - the trouble of adding special multi-precision arithmetic if the - compiler doesn't support 64 bit ints since input_bytes and - output_bytes are only used to print the number of blocks copied. */ -#ifdef __GNUC__ -long long input_bytes, output_bytes; -#else -long input_bytes, output_bytes; -#endif - -/* Saving of argument values for later reference. */ -char *directory_name = NULL; -char **save_patterns; -int num_patterns; - -/* Character that terminates file names read from stdin. */ -char name_end = '\n'; - -/* true if input (cpio -i) or output (cpio -o) is a device node. */ -char input_is_special = false; -char output_is_special = false; - -/* true if lseek works on the input. */ -char input_is_seekable = false; - -/* true if lseek works on the output. */ -char output_is_seekable = false; - -/* Print extra warning messages */ -unsigned int warn_option = 0; - -/* Extract to standard output? */ -bool to_stdout_option = false; - -/* The name this program was run with. */ -char *program_name; - -/* A pointer to either lstat or stat, depending on whether - dereferencing of symlinks is done for input files. */ -int (*xstat) (); - -/* Which copy operation to perform. (-i, -o, -p) */ -void (*copy_function) () = 0; diff --git a/contrib/cpio/src/idcache.c b/contrib/cpio/src/idcache.c deleted file mode 100644 index 17fcc04e238..00000000000 --- a/contrib/cpio/src/idcache.c +++ /dev/null @@ -1,207 +0,0 @@ -/* idcache.c -- map user and group IDs, cached for speed - Copyright (C) 1985, 1988, 1989, 1990, 2004 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#if defined(STDC_HEADERS) || defined(HAVE_STRING_H) -#include -#else -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif -#ifndef _POSIX_VERSION -struct passwd *getpwuid (); -struct passwd *getpwnam (); -struct group *getgrgid (); -struct group *getgrnam (); -#endif - -char *xmalloc (); -char *xstrdup (); - -struct userid -{ - union - { - uid_t u; - gid_t g; - } id; - char *name; - struct userid *next; -}; - -static struct userid *user_alist; - -/* The members of this list have names not in the local passwd file. */ -static struct userid *nouser_alist; - -/* Translate UID to a login name or a stringified number, - with cache. */ - -char * -getuser (uid_t uid) -{ - register struct userid *tail; - struct passwd *pwent; - char usernum_string[20]; - - for (tail = user_alist; tail; tail = tail->next) - if (tail->id.u == uid) - return tail->name; - - pwent = getpwuid (uid); - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->id.u = uid; - if (pwent == 0) - { - sprintf (usernum_string, "%u", (unsigned) uid); - tail->name = xstrdup (usernum_string); - } - else - tail->name = xstrdup (pwent->pw_name); - - /* Add to the head of the list, so most recently used is first. */ - tail->next = user_alist; - user_alist = tail; - return tail->name; -} - -/* Translate USER to a UID, with cache. - Return NULL if there is no such user. - (We also cache which user names have no passwd entry, - so we don't keep looking them up.) */ - -uid_t * -getuidbyname (char *user) -{ - register struct userid *tail; - struct passwd *pwent; - - for (tail = user_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *user && !strcmp (tail->name, user)) - return &tail->id.u; - - for (tail = nouser_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *user && !strcmp (tail->name, user)) - return 0; - - pwent = getpwnam (user); - - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->name = xstrdup (user); - - /* Add to the head of the list, so most recently used is first. */ - if (pwent) - { - tail->id.u = pwent->pw_uid; - tail->next = user_alist; - user_alist = tail; - return &tail->id.u; - } - - tail->next = nouser_alist; - nouser_alist = tail; - return 0; -} - -/* Use the same struct as for userids. */ -static struct userid *group_alist; -static struct userid *nogroup_alist; - -/* Translate GID to a group name or a stringified number, - with cache. */ - -char * -getgroup (gid_t gid) -{ - register struct userid *tail; - struct group *grent; - char groupnum_string[20]; - - for (tail = group_alist; tail; tail = tail->next) - if (tail->id.g == gid) - return tail->name; - - grent = getgrgid (gid); - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->id.g = gid; - if (grent == 0) - { - sprintf (groupnum_string, "%u", (unsigned int) gid); - tail->name = xstrdup (groupnum_string); - } - else - tail->name = xstrdup (grent->gr_name); - - /* Add to the head of the list, so most recently used is first. */ - tail->next = group_alist; - group_alist = tail; - return tail->name; -} - -/* Translate GROUP to a UID, with cache. - Return NULL if there is no such group. - (We also cache which group names have no group entry, - so we don't keep looking them up.) */ - -gid_t * -getgidbyname (char *group) -{ - register struct userid *tail; - struct group *grent; - - for (tail = group_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *group && !strcmp (tail->name, group)) - return &tail->id.g; - - for (tail = nogroup_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *group && !strcmp (tail->name, group)) - return 0; - - grent = getgrnam (group); - - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->name = xstrdup (group); - - /* Add to the head of the list, so most recently used is first. */ - if (grent) - { - tail->id.g = grent->gr_gid; - tail->next = group_alist; - group_alist = tail; - return &tail->id.g; - } - - tail->next = nogroup_alist; - nogroup_alist = tail; - return 0; -} diff --git a/contrib/cpio/src/main.c b/contrib/cpio/src/main.c deleted file mode 100644 index 675f61e1820..00000000000 --- a/contrib/cpio/src/main.c +++ /dev/null @@ -1,804 +0,0 @@ -/* $FreeBSD$ */ - -/* main.c - main program and argument processing for cpio. - Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -/* Written by Phil Nelson , - David MacKenzie , - John Oleynick , - and Sergey Poznyakoff */ - -#include -#include - -#include -#include -#include -#include -#include - -#ifdef HAVE_LOCALE_H -# include -#endif - -#include "filetypes.h" -#include "cpiohdr.h" -#include "dstring.h" -#include "extern.h" -#include -#include - -enum cpio_options { - NO_ABSOLUTE_FILENAMES_OPTION=256, - ABSOLUTE_FILENAMES_OPTION, - NO_PRESERVE_OWNER_OPTION, - ONLY_VERIFY_CRC_OPTION, - RENAME_BATCH_FILE_OPTION, - RSH_COMMAND_OPTION, - QUIET_OPTION, - SPARSE_OPTION, - FORCE_LOCAL_OPTION, - DEBUG_OPTION, - BLOCK_SIZE_OPTION, - TO_STDOUT_OPTION, - - HANG_OPTION, - USAGE_OPTION, - LICENSE_OPTION, - VERSION_OPTION -}; - -const char *argp_program_version = "cpio (" PACKAGE_NAME ") " VERSION; -const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; -static char doc[] = N_("GNU `cpio' copies files to and from archives\n\ -\n\ -Examples:\n\ - # Copy files named in name-list to the archive\n\ - cpio -o < name-list [> archive]\n\ - # Extract files from the archive\n\ - cpio -i [< archive]\n\ - # Copy files named in name-list to destination-directory\n\ - cpio -p destination-directory < name-list\n"); - -/* Print usage error message and exit with error. */ - -#define CHECK_USAGE(cond, opt, mode_opt) \ - if (cond) \ - ERROR((PAXEXIT_FAILURE, 0, _("%s is meaningless with %s"), opt, mode_opt)); - -static struct argp_option options[] = { - /* ********** */ -#define GRID 10 - {NULL, 0, NULL, 0, - N_("Main operation mode:"), GRID }, - {"create", 'o', 0, 0, - N_("Create the archive (run in copy-out mode)"), GRID }, - {"extract", 'i', 0, 0, - N_("Extract files from an archive (run in copy-in mode)"), GRID }, - {"pass-through", 'p', 0, 0, - N_("Run in copy-pass mode"), GRID }, - {"list", 't', 0, 0, - N_("Print a table of contents of the input"), GRID }, -#undef GRID - - /* ********** */ -#define GRID 100 - {NULL, 0, NULL, 0, - N_("Operation modifiers valid in any mode:"), GRID }, - - {"file", 'F', N_("[[USER@]HOST:]FILE-NAME"), 0, - N_("Use this FILE-NAME instead of standard input or output. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 }, - {"force-local", FORCE_LOCAL_OPTION, 0, 0, - N_("Archive file is local, even if its name contains colons"), GRID+1 }, - {"format", 'H', N_("FORMAT"), 0, - N_("Use given archive FORMAT"), GRID+1 }, - {NULL, 'B', NULL, 0, - N_("Set the I/O block size to 5120 bytes"), GRID+1 }, - {"block-size", BLOCK_SIZE_OPTION, N_("BLOCK-SIZE"), 0, - N_("Set the I/O block size to BLOCK-SIZE * 512 bytes"), GRID+1 }, - {NULL, 'c', NULL, 0, - N_("Use the old portable (ASCII) archive format"), GRID+1 }, - {"dot", 'V', NULL, 0, - N_("Print a \".\" for each file processed"), GRID+1 }, - {"io-size", 'C', N_("NUMBER"), 0, - N_("Set the I/O block size to the given NUMBER of bytes"), GRID+1 }, - {"message", 'M', N_("STRING"), 0, - N_("Print STRING when the end of a volume of the backup media is reached"), - GRID+1 }, - {"nonmatching", 'f', 0, 0, - N_("Only copy files that do not match any of the given patterns"), GRID+1 }, - {"numeric-uid-gid", 'n', 0, 0, - N_("In the verbose table of contents listing, show numeric UID and GID"), - GRID+1 }, - {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0, - N_("Use remote COMMAND instead of rsh"), GRID+1 }, - {"quiet", QUIET_OPTION, NULL, 0, - N_("Do not print the number of blocks copied"), GRID+1 }, - {"verbose", 'v', NULL, 0, - N_("Verbosely list the files processed"), GRID+1 }, -#ifdef DEBUG_CPIO - {"debug", DEBUG_OPTION, NULL, 0, - N_("Enable debugging info"), GRID+1 }, -#endif - {"warning", 'W', N_("FLAG"), 0, - N_("Control warning display. Currently FLAG is one of 'none', 'truncate', 'all'. Multiple options accumulate."), GRID+1 }, -#undef GRID - - /* ********** */ -#define GRID 200 - {NULL, 0, NULL, 0, - N_("Operation modifiers valid only in copy-in mode:"), GRID }, - {"pattern-file", 'E', N_("FILE"), 0, - N_("Read additional patterns specifying filenames to extract or list from FILE"), 210}, - {"absolute-filenames", ABSOLUTE_FILENAMES_OPTION, 0, 0, - N_("do not strip leading file name components that contain \"..\" and leading slashes from file names"), 210}, - {"only-verify-crc", ONLY_VERIFY_CRC_OPTION, 0, 0, - N_("When reading a CRC format archive, only verify the CRC's of each file in the archive, don't actually extract the files"), 210}, - {"rename", 'r', 0, 0, - N_("Interactively rename files"), GRID+1 }, - {"rename-batch-file", RENAME_BATCH_FILE_OPTION, N_("FILE"), OPTION_HIDDEN, - "", GRID+1 }, - {"swap", 'b', NULL, 0, - N_("Swap both halfwords of words and bytes of halfwords in the data. Equivalent to -sS"), GRID+1 }, - {"swap-bytes", 's', NULL, 0, - N_("Swap the bytes of each halfword in the files"), GRID+1 }, - {"swap-halfwords", 'S', NULL, 0, - N_("Swap the halfwords of each word (4 bytes) in the files"), - GRID+1 }, - {"to-stdout", TO_STDOUT_OPTION, NULL, 0, - N_("Extract files to standard output"), GRID+1 }, -#undef GRID - - /* ********** */ -#define GRID 300 - {NULL, 0, NULL, 0, - N_("Operation modifiers valid only in copy-out mode:"), GRID }, - {"append", 'A', 0, 0, - N_("Append to an existing archive."), GRID+1 }, - {NULL, 'O', N_("[[USER@]HOST:]FILE-NAME"), 0, - N_("Archive filename to use instead of standard output. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 }, -#undef GRID - - /* ********** */ -#define GRID 400 - {NULL, 0, NULL, 0, - N_("Operation modifiers valid only in copy-pass mode:"), GRID}, - {"link", 'l', 0, 0, - N_("Link files instead of copying them, when possible"), GRID+1 }, - -#undef GRID - - /* ********** */ -#define GRID 500 - {NULL, 0, NULL, 0, - N_("Operation modifiers valid in copy-in and copy-out modes:"), GRID }, - {"absolute-filenames", ABSOLUTE_FILENAMES_OPTION, 0, 0, - N_("Do not strip file system prefix components from the file names"), - GRID+1 }, - {"no-absolute-filenames", NO_ABSOLUTE_FILENAMES_OPTION, 0, 0, - N_("Create all files relative to the current directory"), GRID+1 }, -#undef GRID - /* ********** */ -#define GRID 600 - {NULL, 0, NULL, 0, - N_("Operation modifiers valid in copy-out and copy-pass modes:"), GRID }, - {"null", '0', 0, 0, - N_("A list of filenames is terminated by a null character instead of a newline"), GRID+1 }, - {NULL, 'I', N_("[[USER@]HOST:]FILE-NAME"), 0, - N_("Archive filename to use instead of standard input. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 }, - {"dereference", 'L', 0, 0, - N_("Dereference symbolic links (copy the files that they point to instead of copying the links)."), GRID+1 }, - {"owner", 'R', N_("[USER][:.][GROUP]"), 0, - N_("Set the ownership of all files created to the specified USER and/or GROUP"), GRID+1 }, - {"reset-access-time", 'a', NULL, 0, - N_("Reset the access times of files after reading them"), GRID+1 }, - -#undef GRID - /* ********** */ -#define GRID 700 - {NULL, 0, NULL, 0, - N_("Operation modifiers valid in copy-in and copy-pass modes:"), GRID }, - {"preserve-modification-time", 'm', 0, 0, - N_("Retain previous file modification times when creating files"), GRID+1 }, - {"make-directories", 'd', 0, 0, - N_("Create leading directories where needed"), GRID+1 }, - {"no-preserve-owner", NO_PRESERVE_OWNER_OPTION, 0, 0, - N_("Do not change the ownership of the files"), GRID+1 }, - {"unconditional", 'u', NULL, 0, - N_("Replace all files unconditionally"), GRID+1 }, - {"sparse", SPARSE_OPTION, NULL, 0, - N_("Write files with large blocks of zeros as sparse files"), GRID+1 }, -#undef GRID - - /* ********** */ -#define GRID 800 - {NULL, 0, NULL, 0, - N_("Informative options:"), GRID }, - - {"help", '?', 0, 0, N_("Give this help list"), -1}, - {"usage", USAGE_OPTION, 0, 0, N_("Give a short usage message"), -1}, - {"license", LICENSE_OPTION, 0, 0, N_("Print license and exit"), -1}, - {"version", VERSION_OPTION, 0, 0, N_("Print program version"), -1}, - /* FIXME -V (--dot) conflicts with the default short option for - --version */ - {"HANG", HANG_OPTION, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN, - N_("hang for SECS seconds (default 3600)"), 0}, -#undef GRID - {0, 0, 0, 0} -}; - -static char *input_archive_name = 0; -static char *output_archive_name = 0; - -static void -license () -{ - printf ("%s (%s) %s\n%s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION, - "Copyright (C) 2004 Free Software Foundation, Inc.\n"); - printf (_(" GNU cpio is free software; you can redistribute it and/or modify\n" - " it under the terms of the GNU General Public License as published by\n" - " the Free Software Foundation; either version 2 of the License, or\n" - " (at your option) any later version.\n" - "\n" - " GNU cpio is distributed in the hope that it will be useful,\n" - " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - " GNU General Public License for more details.\n" - "\n" - " You should have received a copy of the GNU General Public License\n" - " along with GNU cpio; if not, write to the Free Software Foundation,\n" - " Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n")); - exit (0); -} - -static int -warn_control (char *arg) -{ - static struct warn_tab { - char *name; - int flag; - } warn_tab[] = { - { "none", CPIO_WARN_ALL }, - { "truncate", CPIO_WARN_TRUNCATE }, - { "all", CPIO_WARN_ALL }, - { NULL } - }; - struct warn_tab *wt; - int offset = 0; - - if (strcmp (arg, "none") == 0) - { - warn_option = 0; - return 0; - } - - if (strlen (arg) > 2 && memcmp (arg, "no-", 3) == 0) - offset = 3; - - for (wt = warn_tab; wt->name; wt++) - if (strcmp (arg + offset, wt->name) == 0) - { - if (offset) - warn_option &= ~wt->flag; - else - warn_option |= wt->flag; - return 0; - } - - return 1; -} - -static error_t -parse_opt (int key, char *arg, struct argp_state *state) -{ - static volatile int _argp_hang; - switch (key) - { - case '0': /* Read null-terminated filenames. */ - name_end = '\0'; - break; - - case 'a': /* Reset access times. */ - reset_time_flag = true; - break; - - case 'A': /* Append to the archive. */ - append_flag = true; - break; - - case 'b': /* Swap bytes and halfwords. */ - swap_bytes_flag = true; - swap_halfwords_flag = true; - break; - - case 'B': /* Set block size to 5120. */ - io_block_size = 5120; - break; - - case BLOCK_SIZE_OPTION: /* --block-size */ - io_block_size = atoi (arg); - if (io_block_size < 1) - error (2, 0, _("invalid block size")); - io_block_size *= 512; - break; - - case 'c': /* Use the old portable ASCII format. */ - if (archive_format != arf_unknown) - error (0, EXIT_FAILURE, _("Archive format multiply defined")); -#ifdef SVR4_COMPAT - archive_format = arf_newascii; /* -H newc. */ -#else - archive_format = arf_oldascii; /* -H odc. */ -#endif - break; - - case 'C': /* Block size. */ - io_block_size = atoi (arg); - if (io_block_size < 1) - error (2, 0, _("invalid block size")); - break; - - case 'd': /* Create directories where needed. */ - create_dir_flag = true; - break; - - case 'f': /* Only copy files not matching patterns. */ - copy_matching_files = false; - break; - - case 'E': /* Pattern file name. */ - pattern_file_name = arg; - break; - - case 'F': /* Archive file name. */ - archive_name = arg; - break; - - case 'H': /* Header format name. */ - if (archive_format != arf_unknown) - error (PAXEXIT_FAILURE, 0, _("Archive format multiply defined")); - if (!strcasecmp (arg, "crc")) - archive_format = arf_crcascii; - else if (!strcasecmp (arg, "newc")) - archive_format = arf_newascii; - else if (!strcasecmp (arg, "odc")) - archive_format = arf_oldascii; - else if (!strcasecmp (arg, "bin")) - archive_format = arf_binary; - else if (!strcasecmp (arg, "ustar")) - archive_format = arf_ustar; - else if (!strcasecmp (arg, "tar")) - archive_format = arf_tar; - else if (!strcasecmp (arg, "hpodc")) - archive_format = arf_hpoldascii; - else if (!strcasecmp (arg, "hpbin")) - archive_format = arf_hpbinary; - else - error (2, 0, _("\ -invalid archive format `%s'; valid formats are:\n\ -crc newc odc bin ustar tar (all-caps also recognized)"), arg); - break; - - case 'i': /* Copy-in mode. */ - if (copy_function != 0) - error (PAXEXIT_FAILURE, 0, _("Mode already defined")); - copy_function = process_copy_in; - break; - - case 'I': /* Input archive file name. */ - input_archive_name = arg; - break; - - case 'k': /* Handle corrupted archives. We always handle - corrupted archives, but recognize this - option for compatability. */ - break; - - case 'l': /* Link files when possible. */ - link_flag = true; - break; - - case 'L': /* Dereference symbolic links. */ - xstat = stat; - break; - - case 'm': /* Retain previous file modify times. */ - retain_time_flag = true; - break; - - case 'M': /* New media message. */ - set_new_media_message (arg); - break; - - case 'n': /* Long list owner and group as numbers. */ - numeric_uid = true; - break; - - case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */ - abs_paths_flag = false; - break; - - case ABSOLUTE_FILENAMES_OPTION: /* --absolute-filenames */ - abs_paths_flag = true; - break; - - case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */ - if (set_owner_flag || set_group_flag) - error (PAXEXIT_FAILURE, 0, - _("--no-preserve-owner cannot be used with --owner")); - no_chown_flag = true; - break; - - case 'o': /* Copy-out mode. */ - if (copy_function != 0) - error (PAXEXIT_FAILURE, 0, _("Mode already defined")); - copy_function = process_copy_out; - break; - - case 'O': /* Output archive file name. */ - output_archive_name = arg; - break; - - case ONLY_VERIFY_CRC_OPTION: - only_verify_crc_flag = true; - break; - - case 'p': /* Copy-pass mode. */ - if (copy_function != 0) - error (PAXEXIT_FAILURE, 0, _("Mode already defined")); - copy_function = process_copy_pass; - break; - - case RSH_COMMAND_OPTION: - rsh_command_option = arg; - break; - - case 'r': /* Interactively rename. */ - rename_flag = true; - break; - - case RENAME_BATCH_FILE_OPTION: - rename_batch_file = arg; - break; - - case QUIET_OPTION: - quiet_flag = true; - break; - - case 'R': /* Set the owner. */ - if (no_chown_flag) - error (PAXEXIT_FAILURE, 0, - _("--owner cannot be used with --no-preserve-owner")); - else - { - char *e, *u, *g; - - e = parse_user_spec (arg, &set_owner, &set_group, &u, &g); - if (e) - error (PAXEXIT_FAILURE, 0, "%s: %s", arg, e); - if (u) - { - free (u); - set_owner_flag = true; - } - if (g) - { - free (g); - set_group_flag = true; - } - } - break; - - case 's': /* Swap bytes. */ - swap_bytes_flag = true; - break; - - case 'S': /* Swap halfwords. */ - swap_halfwords_flag = true; - break; - - case 't': /* Only print a list. */ - table_flag = true; - break; - - case 'u': /* Replace all! Unconditionally! */ - unconditional_flag = true; - break; - - case 'v': /* Verbose! */ - verbose_flag = true; - break; - - case 'V': /* Print `.' for each file. */ - dot_flag = true; - break; - - case 'W': - if (warn_control (arg)) - argp_error (state, _("Invalid value for --warning option: %s"), arg); - break; - - case SPARSE_OPTION: - sparse_flag = true; - break; - - case FORCE_LOCAL_OPTION: - force_local_option = 1; - break; - -#ifdef DEBUG_CPIO - case DEBUG_OPTION: - debug_flag = true; - break; -#endif - - case TO_STDOUT_OPTION: - to_stdout_option = true; - break; - - case HANG_OPTION: - _argp_hang = atoi (arg ? arg : "3600"); - while (_argp_hang-- > 0) - sleep (1); - break; - - case '?': - argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP); - break; - - case USAGE_OPTION: - argp_state_help (state, state->out_stream, - ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); - break; - - case VERSION_OPTION: - fprintf (state->out_stream, "%s\n", argp_program_version); - exit (0); - - case LICENSE_OPTION: - license (); - break; - - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static struct argp argp = { - options, - parse_opt, - N_("[destination-directory]"), - doc, - NULL, - NULL, - NULL -}; - -/* Process the arguments. Set all options and set up the copy pass - directory or the copy in patterns. */ - -void -process_args (int argc, char *argv[]) -{ - void (*copy_in) (); /* Work around for pcc bug. */ - void (*copy_out) (); - int index; - - if (argc < 2) - error (PAXEXIT_FAILURE, 0, - _("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"), - program_name, program_name); - - xstat = lstat; - - if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP, &index, NULL)) - exit (1); - - /* Do error checking and look at other args. */ - - if (copy_function == 0) - { - if (table_flag) - copy_function = process_copy_in; - else - error (PAXEXIT_FAILURE, 0, - _("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"), - program_name, program_name); - } - - /* Work around for pcc bug. */ - copy_in = process_copy_in; - copy_out = process_copy_out; - - if (copy_function == copy_in) - { - archive_des = 0; - CHECK_USAGE(link_flag, "--link", "--extract"); - CHECK_USAGE(reset_time_flag, "--reset", "--extract"); - CHECK_USAGE(xstat != lstat, "--dereference", "--extract"); - CHECK_USAGE(append_flag, "--append", "--extract"); - CHECK_USAGE(output_archive_name, "-O", "--extract"); - if (to_stdout_option) - { - CHECK_USAGE(create_dir_flag, "--make-directories", "--to-stdout"); - CHECK_USAGE(rename_flag, "--rename", "--to-stdout"); - CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--to-stdout"); - CHECK_USAGE(set_owner_flag||set_group_flag, "--owner", "--to-stdout"); - CHECK_USAGE(retain_time_flag, "--preserve-modification-time", - "--to-stdout"); - } - - if (archive_name && input_archive_name) - error (PAXEXIT_FAILURE, 0, - _("Both -I and -F are used in copy-in mode")); - - if (archive_format == arf_crcascii) - crc_i_flag = true; - num_patterns = argc - index; - save_patterns = &argv[index]; - if (input_archive_name) - archive_name = input_archive_name; - } - else if (copy_function == copy_out) - { - if (index != argc) - error (PAXEXIT_FAILURE, 0, _("Too many arguments")); - - archive_des = 1; - CHECK_USAGE(create_dir_flag, "--make-directories", "--create"); - CHECK_USAGE(rename_flag, "--rename", "--create"); - CHECK_USAGE(table_flag, "--list", "--create"); - CHECK_USAGE(unconditional_flag, "--unconditional", "--create"); - CHECK_USAGE(link_flag, "--link", "--create"); - CHECK_USAGE(sparse_flag, "--sparse", "--create"); - CHECK_USAGE(retain_time_flag, "--preserve-modification-time", - "--create"); - CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--create"); - CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--create"); - CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)", - "--create"); - CHECK_USAGE(to_stdout_option, "--to-stdout", "--create"); - - if (append_flag && !(archive_name || output_archive_name)) - error (PAXEXIT_FAILURE, 0, - _("--append is used but no archive file name is given (use -F or -O options)")); - - CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create"); - CHECK_USAGE(abs_paths_flag, "--absolute-pathnames", "--create"); - CHECK_USAGE(input_archive_name, "-I", "--create"); - if (archive_name && output_archive_name) - error (PAXEXIT_FAILURE, 0, - _("Both -O and -F are used in copy-out mode")); - - if (archive_format == arf_unknown) - archive_format = arf_binary; - if (output_archive_name) - archive_name = output_archive_name; - } - else - { - /* Copy pass. */ - if (index < argc - 1) - error (PAXEXIT_FAILURE, 0, _("Too many arguments")); - else if (index > argc - 1) - error (PAXEXIT_FAILURE, 0, _("Not enough arguments")); - - if (archive_format != arf_unknown) - error (PAXEXIT_FAILURE, 0, - _("Archive format is not specified in copy-pass mode (use --format option)")); - - CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--pass-through"); - CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)", - "--pass-through"); - CHECK_USAGE(table_flag, "--list", "--pass-through"); - CHECK_USAGE(rename_flag, "--rename", "--pass-through"); - CHECK_USAGE(append_flag, "--append", "--pass-through"); - CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through"); - CHECK_USAGE(abs_paths_flag, "--absolute-pathnames", - "--pass-through"); - CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through"); - - directory_name = argv[index]; - } - - if (archive_name) - { - if (copy_function != copy_in && copy_function != copy_out) - error (PAXEXIT_FAILURE, 0, - _("-F can be used only with --create or --extract")); - archive_des = open_archive (archive_name); - if (archive_des < 0) - error (PAXEXIT_FAILURE, errno, _("Cannot open %s"), - quotearg_colon (archive_name)); - } - - /* Prevent SysV non-root users from giving away files inadvertantly. - This happens automatically on BSD, where only root can give - away files. */ - if (set_owner_flag == false && set_group_flag == false && geteuid ()) - no_chown_flag = true; -} - -/* Initialize the input and output buffers to their proper size and - initialize all variables associated with the input and output - buffers. */ - -void -initialize_buffers () -{ - int in_buf_size, out_buf_size; - - if (copy_function == process_copy_in) - { - /* Make sure the input buffer can always hold 2 blocks and that it - is big enough to hold 1 tar record (512 bytes) even if it - is not aligned on a block boundary. The extra buffer space - is needed by process_copyin and peek_in_buf to automatically - figure out what kind of archive it is reading. */ - if (io_block_size >= 512) - in_buf_size = 2 * io_block_size; - else - in_buf_size = 1024; - out_buf_size = DISK_IO_BLOCK_SIZE; - } - else if (copy_function == process_copy_out) - { - in_buf_size = DISK_IO_BLOCK_SIZE; - out_buf_size = io_block_size; - } - else - { - in_buf_size = DISK_IO_BLOCK_SIZE; - out_buf_size = DISK_IO_BLOCK_SIZE; - } - - input_buffer = (char *) xmalloc (in_buf_size); - in_buff = input_buffer; - input_buffer_size = in_buf_size; - input_size = 0; - input_bytes = 0; - - output_buffer = (char *) xmalloc (out_buf_size); - out_buff = output_buffer; - output_size = 0; - output_bytes = 0; -} - -int -main (int argc, char *argv[]) -{ - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - program_name = argv[0]; - - process_args (argc, argv); - umask (0); - - initialize_buffers (); - - (*copy_function) (); - - if (archive_des >= 0 && rmtclose (archive_des) == -1) - error (1, errno, _("error closing archive")); - - exit (0); -} diff --git a/contrib/cpio/src/makepath.c b/contrib/cpio/src/makepath.c deleted file mode 100644 index ff4c25f72c8..00000000000 --- a/contrib/cpio/src/makepath.c +++ /dev/null @@ -1,267 +0,0 @@ -/* makepath.c -- Ensure that a directory path exists. - Copyright (C) 1990, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -/* Written by David MacKenzie and - Jim Meyering . */ - -/* This copy of makepath is almost like the fileutils one, but has - changes for HPUX CDF's. Maybe the 2 versions of makepath can - come together again in the future. */ - -#include -#include - -#include -#include -#include - -/* Ensure that the directory ARGPATH exists. - Remove any trailing slashes from ARGPATH before calling this function. - - Make any leading directories that don't already exist, with - permissions PARENT_MODE. - If the last element of ARGPATH does not exist, create it as - a new directory with permissions MODE. - If OWNER and GROUP are non-negative, make them the UID and GID of - created directories. - If VERBOSE_FMT_STRING is nonzero, use it as a printf format - string for printing a message after successfully making a directory, - with the name of the directory that was just made as an argument. - - Return 0 if ARGPATH exists as a directory with the proper - ownership and permissions when done, otherwise 1. */ - -int -make_path (char *argpath, - int mode, - int parent_mode, - uid_t owner, - gid_t group, - char *verbose_fmt_string) -{ - char *dirpath; /* A copy we can scribble NULs on. */ - struct stat stats; - int retval = 0; - int oldmask = umask (0); - dirpath = alloca (strlen (argpath) + 1); - strcpy (dirpath, argpath); - - if (stat (dirpath, &stats)) - { - char *slash; - int tmp_mode; /* Initial perms for leading dirs. */ - int re_protect; /* Should leading dirs be unwritable? */ - struct ptr_list - { - char *dirname_end; - struct ptr_list *next; - }; - struct ptr_list *p, *leading_dirs = NULL; - - /* If leading directories shouldn't be writable or executable, - or should have set[ug]id or sticky bits set and we are setting - their owners, we need to fix their permissions after making them. */ - if (((parent_mode & 0300) != 0300) - || (owner != (uid_t) -1 && group != (gid_t) -1 - && (parent_mode & 07000) != 0)) - { - tmp_mode = 0700; - re_protect = 1; - } - else - { - tmp_mode = parent_mode; - re_protect = 0; - } - - slash = dirpath; - while (*slash == '/') - slash++; - while ((slash = strchr (slash, '/'))) - { -#ifdef HPUX_CDF - int iscdf; - iscdf = 0; -#endif - *slash = '\0'; - if (stat (dirpath, &stats)) - { -#ifdef HPUX_CDF - /* If this component of the pathname ends in `+' and is - followed by 2 `/'s, then this is a CDF. We remove the - `+' from the name and create the directory. Later - we will "hide" the directory. */ - if ( (*(slash +1) == '/') && (*(slash -1) == '+') ) - { - iscdf = 1; - *(slash -1) = '\0'; - } -#endif - if (mkdir (dirpath, tmp_mode)) - { - error (0, errno, _("cannot make directory `%s'"), dirpath); - umask (oldmask); - return 1; - } - else - { - if (verbose_fmt_string != NULL) - error (0, 0, verbose_fmt_string, dirpath); - - if (owner != (uid_t) -1 && group != (gid_t) -1 - && chown (dirpath, owner, group) -#ifdef AFS - && errno != EPERM -#endif - ) - { - chown_error_details (dirpath, owner, group); - retval = 1; - } - if (re_protect) - { - struct ptr_list *new = (struct ptr_list *) - alloca (sizeof (struct ptr_list)); - new->dirname_end = slash; - new->next = leading_dirs; - leading_dirs = new; - } -#ifdef HPUX_CDF - if (iscdf) - { - /* If this is a CDF, "hide" the directory by setting - its hidden/setuid bit. Also add the `+' back to - its name (since once it's "hidden" we must refer - to as `name+' instead of `name'). */ - chmod (dirpath, 04700); - *(slash - 1) = '+'; - } -#endif - } - } - else if (!S_ISDIR (stats.st_mode)) - { - error (0, 0, _("`%s' exists but is not a directory"), dirpath); - umask (oldmask); - return 1; - } - - *slash++ = '/'; - - /* Avoid unnecessary calls to `stat' when given - pathnames containing multiple adjacent slashes. */ - while (*slash == '/') - slash++; - } - - /* We're done making leading directories. - Make the final component of the path. */ - - if (mkdir (dirpath, mode)) - { - /* In some cases, if the final component in dirpath was `.' then we - just got an EEXIST error from that last mkdir(). If that's - the case, ignore it. */ - if ( (errno != EEXIST) || - (stat (dirpath, &stats) != 0) || - (!S_ISDIR (stats.st_mode) ) ) - { - error (0, errno, _("cannot make directory `%s'"), dirpath); - umask (oldmask); - return 1; - } - } - if (verbose_fmt_string != NULL) - error (0, 0, verbose_fmt_string, dirpath); - - if (owner != (uid_t) -1 && group != (gid_t) -1) - { - if (chown (dirpath, owner, group) -#ifdef AFS - && errno != EPERM -#endif - ) - { - chown_error_details (dirpath, owner, group); - retval = 1; - } - } - /* chown may have turned off some permission bits we wanted. */ - if ((mode & 07000) != 0 && chmod (dirpath, mode)) - { - chmod_error_details (dirpath, mode); - retval = 1; - } - - /* If the mode for leading directories didn't include owner "wx" - privileges, we have to reset their protections to the correct - value. */ - for (p = leading_dirs; p != NULL; p = p->next) - { - *p->dirname_end = '\0'; -#if 0 - /* cpio always calls make_path with parent mode 0700, so - we don't have to do this. If we ever do have to do this, - we have to stat the directory first to get the setuid - bit so we don't break HP CDF's. */ - if (chmod (dirpath, parent_mode)) - { - chmod_error_details (dirpath, parent_mode); - retval = 1; - } -#endif - - } - } - else - { - /* We get here if the entire path already exists. */ - - if (!S_ISDIR (stats.st_mode)) - { - error (0, 0, _("`%s' exists but is not a directory"), dirpath); - umask (oldmask); - return 1; - } - - /* chown must precede chmod because on some systems, - chown clears the set[ug]id bits for non-superusers, - resulting in incorrect permissions. - On System V, users can give away files with chown and then not - be able to chmod them. So don't give files away. */ - - if (owner != (uid_t) -1 && group != (gid_t) -1 - && chown (dirpath, owner, group) -#ifdef AFS - && errno != EPERM -#endif - ) - { - chown_error_details (dirpath, owner, group); - retval = 1; - } - if (chmod (dirpath, mode)) - { - chmod_error_details (dirpath, mode); - retval = 1; - } - } - - umask (oldmask); - return retval; -} diff --git a/contrib/cpio/src/safe-stat.h b/contrib/cpio/src/safe-stat.h deleted file mode 100644 index 3a379703cf6..00000000000 --- a/contrib/cpio/src/safe-stat.h +++ /dev/null @@ -1 +0,0 @@ -#define SAFE_STAT(path,pbuf) stat(path,pbuf) diff --git a/contrib/cpio/src/tar.c b/contrib/cpio/src/tar.c deleted file mode 100644 index 9340372807e..00000000000 --- a/contrib/cpio/src/tar.c +++ /dev/null @@ -1,494 +0,0 @@ -/* $FreeBSD$ */ - -/* tar.c - read in write tar headers for cpio - Copyright (C) 1992, 2001, 2004, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#include - -#include -#include -#include -#include "filetypes.h" -#include "cpiohdr.h" -#include "dstring.h" -#include "extern.h" -#include -#include "tarhdr.h" - -/* Stash the tar linkname in static storage. */ - -static char * -stash_tar_linkname (char *linkname) -{ - static char hold_tar_linkname[TARLINKNAMESIZE + 1]; - - strncpy (hold_tar_linkname, linkname, TARLINKNAMESIZE); - hold_tar_linkname[TARLINKNAMESIZE] = '\0'; - return hold_tar_linkname; -} - -/* Try to split a long file name into prefix and suffix parts separated - by a slash. Return the length of the prefix (not counting the slash). */ - -static size_t -split_long_name (const char *name, size_t length) -{ - size_t i; - - if (length > TARPREFIXSIZE) - length = TARPREFIXSIZE+2; - for (i = length - 1; i > 0; i--) - if (name[i] == '/') - break; - return i; -} - -/* Stash the tar filename and optional prefix in static storage. */ - -static char * -stash_tar_filename (char *prefix, char *filename) -{ - static char hold_tar_filename[TARNAMESIZE + TARPREFIXSIZE + 2]; - if (prefix == NULL || *prefix == '\0') - { - strncpy (hold_tar_filename, filename, TARNAMESIZE); - hold_tar_filename[TARNAMESIZE] = '\0'; - } - else - { - strncpy (hold_tar_filename, prefix, TARPREFIXSIZE); - hold_tar_filename[TARPREFIXSIZE] = '\0'; - strcat (hold_tar_filename, "/"); - strncat (hold_tar_filename, filename, TARNAMESIZE); - hold_tar_filename[TARPREFIXSIZE + TARNAMESIZE] = '\0'; - } - return hold_tar_filename; -} - -/* Convert a number into a string of octal digits. - Convert long VALUE into a DIGITS-digit field at WHERE, - including a trailing space and room for a NUL. DIGITS==3 means - 1 digit, a space, and room for a NUL. - - We assume the trailing NUL is already there and don't fill it in. - This fact is used by start_header and finish_header, so don't change it! - - This is be equivalent to: - sprintf (where, "%*lo ", digits - 2, value); - except that sprintf fills in the trailing NUL and we don't. */ - -static void -to_oct (register long value, register int digits, register char *where) -{ - --digits; /* Leave the trailing NUL slot alone. */ - - /* Produce the digits -- at least one. */ - do - { - where[--digits] = '0' + (char) (value & 7); /* One octal digit. */ - value >>= 3; - } - while (digits > 0 && value != 0); - - /* Add leading zeroes, if necessary. */ - while (digits > 0) - where[--digits] = '0'; -} - - - -/* Compute and return a checksum for TAR_HDR, - counting the checksum bytes as if they were spaces. */ - -unsigned int -tar_checksum (struct tar_header *tar_hdr) -{ - unsigned int sum = 0; - char *p = (char *) tar_hdr; - char *q = p + TARRECORDSIZE; - int i; - - while (p < tar_hdr->chksum) - sum += *p++ & 0xff; - for (i = 0; i < 8; ++i) - { - sum += ' '; - ++p; - } - while (p < q) - sum += *p++ & 0xff; - return sum; -} - -/* Write out header FILE_HDR, including the file name, to file - descriptor OUT_DES. */ - -void -write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des) -{ - int name_len; - union tar_record tar_rec; - struct tar_header *tar_hdr = (struct tar_header *) &tar_rec; - - memset (&tar_rec, 0, sizeof tar_rec); - - /* process_copy_out must ensure that file_hdr->c_name is short enough, - or we will lose here. */ - - name_len = strlen (file_hdr->c_name); - if (name_len <= TARNAMESIZE) - { - strncpy (tar_hdr->name, file_hdr->c_name, name_len); - } - else - { - /* Fit as much as we can into `name', the rest into `prefix'. */ - int prefix_len = split_long_name (file_hdr->c_name, name_len); - - strncpy (tar_hdr->prefix, file_hdr->c_name, prefix_len); - strncpy (tar_hdr->name, file_hdr->c_name + prefix_len + 1, - name_len - prefix_len - 1); - } - - /* Ustar standard (POSIX.1-1988) requires the mode to contain only 3 octal - digits */ - to_oct (file_hdr->c_mode & MODE_ALL, 8, tar_hdr->mode); - to_oct (file_hdr->c_uid, 8, tar_hdr->uid); - to_oct (file_hdr->c_gid, 8, tar_hdr->gid); - to_oct (file_hdr->c_filesize, 12, tar_hdr->size); - to_oct (file_hdr->c_mtime, 12, tar_hdr->mtime); - - switch (file_hdr->c_mode & CP_IFMT) - { - case CP_IFREG: - if (file_hdr->c_tar_linkname) - { - /* process_copy_out makes sure that c_tar_linkname is shorter - than TARLINKNAMESIZE. */ - strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname, - TARLINKNAMESIZE); - tar_hdr->typeflag = LNKTYPE; - to_oct (0, 12, tar_hdr->size); - } - else - tar_hdr->typeflag = REGTYPE; - break; - case CP_IFDIR: - tar_hdr->typeflag = DIRTYPE; - break; - case CP_IFCHR: - tar_hdr->typeflag = CHRTYPE; - break; - case CP_IFBLK: - tar_hdr->typeflag = BLKTYPE; - break; -#ifdef CP_IFIFO - case CP_IFIFO: - tar_hdr->typeflag = FIFOTYPE; - break; -#endif /* CP_IFIFO */ -#ifdef CP_IFLNK - case CP_IFLNK: - tar_hdr->typeflag = SYMTYPE; - /* process_copy_out makes sure that c_tar_linkname is shorter - than TARLINKNAMESIZE. */ - strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname, - TARLINKNAMESIZE); - to_oct (0, 12, tar_hdr->size); - break; -#endif /* CP_IFLNK */ - } - - if (archive_format == arf_ustar) - { - char *name; - - strncpy (tar_hdr->magic, TMAGIC, TMAGLEN); - strncpy (tar_hdr->magic + TMAGLEN, TVERSION, TVERSLEN); - - name = getuser (file_hdr->c_uid); - if (name) - strcpy (tar_hdr->uname, name); - name = getgroup (file_hdr->c_gid); - if (name) - strcpy (tar_hdr->gname, name); - - to_oct (file_hdr->c_rdev_maj, 8, tar_hdr->devmajor); - to_oct (file_hdr->c_rdev_min, 8, tar_hdr->devminor); - } - - to_oct (tar_checksum (tar_hdr), 8, tar_hdr->chksum); - - tape_buffered_write ((char *) &tar_rec, out_des, TARRECORDSIZE); -} - -/* Return nonzero iff all the bytes in BLOCK are NUL. - SIZE is the number of bytes to check in BLOCK; it must be a - multiple of sizeof (long). */ - -int -null_block (long *block, int size) -{ - register long *p = block; - register int i = size / sizeof (long); - - while (i--) - if (*p++) - return 0; - return 1; -} - -/* Read a tar header, including the file name, from file descriptor IN_DES - into FILE_HDR. */ - -void -read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des) -{ - long bytes_skipped = 0; - int warned = false; - union tar_record tar_rec; - struct tar_header *tar_hdr = (struct tar_header *) &tar_rec; - uid_t *uidp; - gid_t *gidp; - - tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE); - - /* Check for a block of 0's. */ - if (null_block ((long *) &tar_rec, TARRECORDSIZE)) - { -#if 0 - /* Found one block of 512 0's. If the next block is also all 0's - then this is the end of the archive. If not, assume the - previous block was all corruption and continue reading - the archive. */ - /* Commented out because GNU tar sometimes creates archives with - only one block of 0's at the end. This happened for the - cpio 2.0 distribution! */ - tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE); - if (null_block ((long *) &tar_rec, TARRECORDSIZE)) -#endif - { - file_hdr->c_name = CPIO_TRAILER_NAME; - return; - } -#if 0 - bytes_skipped = TARRECORDSIZE; -#endif - } - - while (1) - { - file_hdr->c_chksum = FROM_OCTAL (tar_hdr->chksum); - - if (file_hdr->c_chksum != tar_checksum (tar_hdr)) - { - /* If the checksum is bad, skip 1 byte and try again. When - we try again we do not look for an EOF record (all zeros), - because when we start skipping bytes in a corrupted archive - the chances are pretty good that we might stumble across - 2 blocks of 512 zeros (that probably is not really the last - record) and it is better to miss the EOF and give the user - a "premature EOF" error than to give up too soon on a corrupted - archive. */ - if (!warned) - { - error (0, 0, _("invalid header: checksum error")); - warned = true; - } - memmove (&tar_rec, ((char *) &tar_rec) + 1, TARRECORDSIZE - 1); - tape_buffered_read (((char *) &tar_rec) + (TARRECORDSIZE - 1), in_des, 1); - ++bytes_skipped; - continue; - } - - if (archive_format != arf_ustar) - file_hdr->c_name = stash_tar_filename (NULL, tar_hdr->name); - else - file_hdr->c_name = stash_tar_filename (tar_hdr->prefix, tar_hdr->name); - file_hdr->c_nlink = 1; - file_hdr->c_mode = FROM_OCTAL (tar_hdr->mode); - file_hdr->c_mode = file_hdr->c_mode & 07777; - /* Debian hack: This version of cpio uses the -n flag also to extract - tar archives using the numeric UID/GID instead of the user/group - names in /etc/passwd and /etc/groups. (98/10/15) -BEM */ - if (archive_format == arf_ustar && !numeric_uid - && (uidp = getuidbyname (tar_hdr->uname))) - file_hdr->c_uid = *uidp; - else - file_hdr->c_uid = FROM_OCTAL (tar_hdr->uid); - - if (archive_format == arf_ustar && !numeric_uid - && (gidp = getgidbyname (tar_hdr->gname))) - file_hdr->c_gid = *gidp; - else - file_hdr->c_gid = FROM_OCTAL (tar_hdr->gid); - file_hdr->c_filesize = FROM_OCTAL (tar_hdr->size); - file_hdr->c_mtime = FROM_OCTAL (tar_hdr->mtime); - file_hdr->c_rdev_maj = FROM_OCTAL (tar_hdr->devmajor); - file_hdr->c_rdev_min = FROM_OCTAL (tar_hdr->devminor); - file_hdr->c_tar_linkname = NULL; - - switch (tar_hdr->typeflag) - { - case REGTYPE: - case CONTTYPE: /* For now, punt. */ - default: - file_hdr->c_mode |= CP_IFREG; - break; - case DIRTYPE: - file_hdr->c_mode |= CP_IFDIR; - break; - case CHRTYPE: - file_hdr->c_mode |= CP_IFCHR; - /* If a POSIX tar header has a valid linkname it's always supposed - to set typeflag to be LNKTYPE. System V.4 tar seems to - be broken, and for device files with multiple links it - puts the name of the link into linkname, but leaves typeflag - as CHRTYPE, BLKTYPE, FIFOTYPE, etc. */ - file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname); - - /* Does POSIX say that the filesize must be 0 for devices? We - assume so, but HPUX's POSIX tar sets it to be 1 which causes - us problems (when reading an archive we assume we can always - skip to the next file by skipping filesize bytes). For - now at least, it's easier to clear filesize for devices, - rather than check everywhere we skip in copyin.c. */ - file_hdr->c_filesize = 0; - break; - case BLKTYPE: - file_hdr->c_mode |= CP_IFBLK; - file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname); - file_hdr->c_filesize = 0; - break; -#ifdef CP_IFIFO - case FIFOTYPE: - file_hdr->c_mode |= CP_IFIFO; - file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname); - file_hdr->c_filesize = 0; - break; -#endif - case SYMTYPE: -#ifdef CP_IFLNK - file_hdr->c_mode |= CP_IFLNK; - file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname); - file_hdr->c_filesize = 0; - break; - /* Else fall through. */ -#endif - case LNKTYPE: - file_hdr->c_mode |= CP_IFREG; - file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname); - file_hdr->c_filesize = 0; - break; - - case AREGTYPE: - /* Old tar format; if the last char in filename is '/' then it is - a directory, otherwise it's a regular file. */ - if (file_hdr->c_name[strlen (file_hdr->c_name) - 1] == '/') - file_hdr->c_mode |= CP_IFDIR; - else - file_hdr->c_mode |= CP_IFREG; - break; - case 'x': case 'g': - /* Ignore pax 'x' and 'g' extension entries. */ - /* Skip body of this entry. */ - while (file_hdr->c_filesize > 0) { - tape_buffered_read(((char *) &tar_rec), in_des, TARRECORDSIZE); - if (file_hdr->c_filesize > TARRECORDSIZE) - file_hdr->c_filesize -= TARRECORDSIZE; - else - file_hdr->c_filesize = 0; - } - /* Read next header and return that instead. */ - read_in_tar_header(file_hdr, in_des); - break; - } - break; - } - if (bytes_skipped > 0) - warn_junk_bytes (bytes_skipped); -} - -/* Return - 2 if BUF is a valid POSIX tar header (the checksum is correct - and it has the "ustar" magic string), - 1 if BUF is a valid old tar header (the checksum is correct), - 0 otherwise. */ - -int -is_tar_header (char *buf) -{ - struct tar_header *tar_hdr = (struct tar_header *) buf; - unsigned long chksum; - - chksum = FROM_OCTAL (tar_hdr->chksum); - - if (chksum != tar_checksum (tar_hdr)) - return 0; - - /* GNU tar 1.10 and previous set the magic field to be "ustar " instead - of "ustar\0". Only look at the first 5 characters of the magic - field so we can recognize old GNU tar ustar archives. */ - if (!strncmp (tar_hdr->magic, TMAGIC, TMAGLEN - 1)) - return 2; - return 1; -} - -/* Return true if the filename is too long to fit in a tar header. - For old tar headers, if the filename's length is less than or equal - to 100 then it will fit, otherwise it will not. For POSIX tar headers, - if the filename's length is less than or equal to 100 then it - will definitely fit, and if it is greater than 256 then it - will definitely not fit. If the length is between 100 and 256, - then the filename will fit only if it is possible to break it - into a 155 character "prefix" and 100 character "name". There - must be a slash between the "prefix" and the "name", although - the slash is not stored or counted in either the "prefix" or - the "name", and there must be at least one character in both - the "prefix" and the "name". If it is not possible to break down - the filename like this then it will not fit. */ - -int -is_tar_filename_too_long (char *name) -{ - int whole_name_len; - int prefix_name_len; - - whole_name_len = strlen (name); - if (whole_name_len <= TARNAMESIZE) - return false; - - if (archive_format != arf_ustar) - return true; - - if (whole_name_len > TARNAMESIZE + TARPREFIXSIZE + 1) - return true; - - /* See whether we can split up the name into acceptably-sized - `prefix' and `name' (`p') pieces. */ - prefix_name_len = split_long_name (name, whole_name_len); - - /* Interestingly, a name consisting of a slash followed by - TARNAMESIZE characters can't be stored, because the prefix - would be empty, and thus ignored. */ - if (prefix_name_len == 0 - || whole_name_len - prefix_name_len - 1 > TARNAMESIZE) - return true; - - return false; -} diff --git a/contrib/cpio/src/tar.h b/contrib/cpio/src/tar.h deleted file mode 100644 index 7b27e86a56f..00000000000 --- a/contrib/cpio/src/tar.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Extended tar format from POSIX.1. - Copyright (C) 1992 Free Software Foundation, Inc. - Written by David J. MacKenzie. - -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General -Public License along with this library; see the file COPYING.LIB. -If not, write to the Free Software Foundation, Inc., 51 Franklin -Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - -#ifndef _TAR_H - -#define _TAR_H 1 - - -/* A tar archive consists of 512-byte blocks. - Each file in the archive has a header block followed by 0+ data blocks. - Two blocks of NUL bytes indicate the end of the archive. */ - -/* The fields of header blocks: - All strings are stored as ISO 646 (approximately ASCII) strings. - - Fields are numeric unless otherwise noted below; numbers are ISO 646 - representations of octal numbers, with leading zeros as needed. - - linkname is only valid when typeflag==LNKTYPE. It doesn't use prefix; - files that are links to pathnames >100 chars long can not be stored - in a tar archive. - - If typeflag=={LNKTYPE,SYMTYPE,DIRTYPE} then size must be 0. - - devmajor and devminor are only valid for typeflag=={BLKTYPE,CHRTYPE}. - - chksum contains the sum of all 512 bytes in the header block, - treating each byte as an 8-bit unsigned value and treating the - 8 bytes of chksum as blank characters. - - uname and gname are used in preference to uid and gid, if those - names exist locally. - - Field Name Byte Offset Length in Bytes Field Type - name 0 100 NUL-terminated if NUL fits - mode 100 8 - uid 108 8 - gid 116 8 - size 124 12 - mtime 136 12 - chksum 148 8 - typeflag 156 1 see below - linkname 157 100 NUL-terminated if NUL fits - magic 257 6 must be TMAGIC (NUL term.) - version 263 2 must be TVERSION - uname 265 32 NUL-terminated - gname 297 32 NUL-terminated - devmajor 329 8 - devminor 337 8 - prefix 345 155 NUL-terminated if NUL fits - - If the first character of prefix is '\0', the file name is name; - otherwise, it is prefix/name. Files whose pathnames don't fit in that - length can not be stored in a tar archive. */ - -/* The bits in mode: */ -#define TSUID 04000 -#define TSGID 02000 -#define TSVTX 01000 -#define TUREAD 00400 -#define TUWRITE 00200 -#define TUEXEC 00100 -#define TGREAD 00040 -#define TGWRITE 00020 -#define TGEXEC 00010 -#define TOREAD 00004 -#define TOWRITE 00002 -#define TOEXEC 00001 - -/* The values for typeflag: - Values 'A'-'Z' are reserved for custom implementations. - All other values are reserved for future POSIX.1 revisions. */ - -#define REGTYPE '0' /* Regular file (preferred code). */ -#define AREGTYPE '\0' /* Regular file (alternate code). */ -#define LNKTYPE '1' /* Hard link. */ -#define SYMTYPE '2' /* Symbolic link (hard if not supported). */ -#define CHRTYPE '3' /* Character special. */ -#define BLKTYPE '4' /* Block special. */ -#define DIRTYPE '5' /* Directory. */ -#define FIFOTYPE '6' /* Named pipe. */ -#define CONTTYPE '7' /* Contiguous file */ - /* (regular file if not supported). */ - -/* Contents of magic field and its length. */ -#define TMAGIC "ustar" -#define TMAGLEN 6 - -/* Contents of the version field and its length. */ -#define TVERSION "00" -#define TVERSLEN 2 - - -#endif /* tar.h */ diff --git a/contrib/cpio/src/tarhdr.h b/contrib/cpio/src/tarhdr.h deleted file mode 100644 index b901739c19c..00000000000 --- a/contrib/cpio/src/tarhdr.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Extended tar header from POSIX.1. - Copyright (C) 1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#ifndef _TARHDR_H - -#define _TARHDR_H 1 - -#include - -/* Size of `name' field. */ -#define TARNAMESIZE 100 - -/* Size of `linkname' field. */ -#define TARLINKNAMESIZE 100 - -/* Size of `prefix' field. */ -#define TARPREFIXSIZE 155 - -/* Size of entire tar header. */ -#define TARRECORDSIZE 512 - -struct tar_header -{ - char name[TARNAMESIZE]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char chksum[8]; - char typeflag; - char linkname[TARLINKNAMESIZE]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char prefix[TARPREFIXSIZE]; -}; - -union tar_record -{ - struct tar_header header; - char buffer[TARRECORDSIZE]; -}; - -#endif /* tarhdr.h */ diff --git a/contrib/cpio/src/userspec.c b/contrib/cpio/src/userspec.c deleted file mode 100644 index c33d6e2c21d..00000000000 --- a/contrib/cpio/src/userspec.c +++ /dev/null @@ -1,261 +0,0 @@ -/* $FreeBSD$ */ - -/* userspec.c -- Parse a user and group string. - Copyright (C) 1989, 1990, 1991, 1992, 2001, - 2004, 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -/* Written by David MacKenzie . */ - -#include - -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else -#ifdef HAVE_ALLOCA_H -#include -#else -#ifdef _AIX - #pragma alloca -#else -char *alloca (); -#endif -#endif -#endif - -#include -#include -#include -#include -#include - -#if !HAVE_DECL_GETPWNAM -extern struct passwd *getpwnam (const char *name); -#endif -#if !HAVE_DECL_GETGRNAM -extern struct group *getgrnam (const char *name); -#endif -#if !HAVE_DECL_GETGRGID -extern struct group *getgrgid (gid_t gid); -#endif - -#ifndef HAVE_ENDPWENT -# define endpwent() -#endif -#ifndef HAVE_ENDGRENT -# define endgrent() -#endif - -/* Perform the equivalent of the statement `dest = strdup (src);', - but obtaining storage via alloca instead of from the heap. */ - -#define V_STRDUP(dest, src) \ - do \ - { \ - int _len = strlen ((src)); \ - (dest) = (char *) alloca (_len + 1); \ - strcpy (dest, src); \ - } \ - while (0) - -/* Return nonzero if STR represents an unsigned decimal integer, - otherwise return 0. */ - -static int -isnumber_p (const char *str) -{ - for (; *str; str++) - if (!isdigit (*str)) - return 0; - return 1; -} - -/* Extract from NAME, which has the form "[user][:.][group]", - a USERNAME, UID U, GROUPNAME, and GID G. - Either user or group, or both, must be present. - If the group is omitted but the ":" or "." separator is given, - use the given user's login group. - - USERNAME and GROUPNAME will be in newly malloc'd memory. - Either one might be NULL instead, indicating that it was not - given and the corresponding numeric ID was left unchanged. - - Return NULL if successful, a static error message string if not. */ - -const char * -parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid, - char **username_arg, char **groupname_arg) -{ - static const char *tired = "virtual memory exhausted"; - const char *error_msg; - char *spec; /* A copy we can write on. */ - struct passwd *pwd; - struct group *grp; - char *g, *u, *separator; - char *groupname; - - error_msg = NULL; - *username_arg = *groupname_arg = NULL; - groupname = NULL; - - V_STRDUP (spec, spec_arg); - - /* Find the separator if there is one. */ - separator = strchr (spec, ':'); - if (separator == NULL) - separator = strchr (spec, '.'); - - /* Replace separator with a NUL. */ - if (separator != NULL) - *separator = '\0'; - - /* Set U and G to non-zero length strings corresponding to user and - group specifiers or to NULL. */ - u = (*spec == '\0' ? NULL : spec); - - g = (separator == NULL || *(separator + 1) == '\0' - ? NULL - : separator + 1); - - if (u == NULL && g == NULL) - return "can not omit both user and group"; - - if (u != NULL) - { - pwd = getpwnam (u); - if (pwd == NULL) - { - - if (!isnumber_p (u)) - error_msg = _("invalid user"); - else - { - int use_login_group; - use_login_group = (separator != NULL && g == NULL); - if (use_login_group) - error_msg = _("cannot get the login group of a numeric UID"); - else - *uid = atoi (u); - } - } - else - { - *uid = pwd->pw_uid; - if (g == NULL && separator != NULL) - { - /* A separator was given, but a group was not specified, - so get the login group. */ - *gid = pwd->pw_gid; - grp = getgrgid (pwd->pw_gid); - if (grp == NULL) - { - /* This is enough room to hold the unsigned decimal - representation of any 32-bit quantity and the trailing - zero byte. */ - char uint_buf[21]; - sprintf (uint_buf, "%u", (unsigned) (pwd->pw_gid)); - V_STRDUP (groupname, uint_buf); - } - else - { - V_STRDUP (groupname, grp->gr_name); - } - endgrent (); - } - } - endpwent (); - } - - if (g != NULL && error_msg == NULL) - { - /* Explicit group. */ - grp = getgrnam (g); - if (grp == NULL) - { - if (!isnumber_p (g)) - error_msg = _("invalid group"); - else - *gid = atoi (g); - } - else - *gid = grp->gr_gid; - endgrent (); /* Save a file descriptor. */ - - if (error_msg == NULL) - V_STRDUP (groupname, g); - } - - if (error_msg == NULL) - { - if (u != NULL) - { - *username_arg = strdup (u); - if (*username_arg == NULL) - error_msg = tired; - } - - if (groupname != NULL && error_msg == NULL) - { - *groupname_arg = strdup (groupname); - if (*groupname_arg == NULL) - { - if (*username_arg != NULL) - { - free (*username_arg); - *username_arg = NULL; - } - error_msg = tired; - } - } - } - - return error_msg; -} - -#ifdef TEST - -#define NULL_CHECK(s) ((s) == NULL ? "(null)" : (s)) - -int -main (int argc, char **argv) -{ - int i; - - for (i = 1; i < argc; i++) - { - const char *e; - char *username, *groupname; - uid_t uid; - gid_t gid; - char *tmp; - - tmp = strdup (argv[i]); - e = parse_user_spec (tmp, &uid, &gid, &username, &groupname); - free (tmp); - printf ("%s: %u %u %s %s %s\n", - argv[i], - (unsigned int) uid, - (unsigned int) gid, - NULL_CHECK (username), - NULL_CHECK (groupname), - NULL_CHECK (e)); - } - - exit (0); -} - -#endif diff --git a/contrib/cpio/src/util.c b/contrib/cpio/src/util.c deleted file mode 100644 index 8773f7521ac..00000000000 --- a/contrib/cpio/src/util.c +++ /dev/null @@ -1,1344 +0,0 @@ -/* $FreeBSD$ */ - -/* util.c - Several utility routines for cpio. - Copyright (C) 1990, 1991, 1992, 2001, 2004, - 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA. */ - -#include - -#include -#include -#include -#include "cpiohdr.h" -#include "dstring.h" -#include "extern.h" -#include -#include "filetypes.h" -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_SYS_MTIO_H -# ifdef HAVE_SYS_IO_TRIOCTL_H -# include -# endif -# include -#endif - -#if !HAVE_DECL_ERRNO -extern int errno; -#endif - -/* Write `output_size' bytes of `output_buffer' to file - descriptor OUT_DES and reset `output_size' and `out_buff'. */ - -void -tape_empty_output_buffer (int out_des) -{ - int bytes_written; - -#ifdef BROKEN_LONG_TAPE_DRIVER - static long output_bytes_before_lseek = 0; - - /* Some tape drivers seem to have a signed internal seek pointer and - they lose if it overflows and becomes negative (e.g. when writing - tapes > 2Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the - seek pointer and prevent it from overflowing. */ - if (output_is_special - && ( (output_bytes_before_lseek += output_size) >= 1073741824L) ) - { - lseek(out_des, 0L, SEEK_SET); - output_bytes_before_lseek = 0; - } -#endif - - bytes_written = rmtwrite (out_des, output_buffer, output_size); - if (bytes_written != output_size) - { - int rest_bytes_written; - int rest_output_size; - - if (output_is_special - && (bytes_written >= 0 - || (bytes_written < 0 - && (errno == ENOSPC || errno == EIO || errno == ENXIO)))) - { - get_next_reel (out_des); - if (bytes_written > 0) - rest_output_size = output_size - bytes_written; - else - rest_output_size = output_size; - rest_bytes_written = rmtwrite (out_des, output_buffer, - rest_output_size); - if (rest_bytes_written != rest_output_size) - error (1, errno, _("write error")); - } - else - error (1, errno, _("write error")); - } - output_bytes += output_size; - out_buff = output_buffer; - output_size = 0; -} - -static int sparse_write (int fildes, char *buf, unsigned int nbyte); - -/* Write `output_size' bytes of `output_buffer' to file - descriptor OUT_DES and reset `output_size' and `out_buff'. - If `swapping_halfwords' or `swapping_bytes' is set, - do the appropriate swapping first. Our callers have - to make sure to only set these flags if `output_size' - is appropriate (a multiple of 4 for `swapping_halfwords', - 2 for `swapping_bytes'). The fact that DISK_IO_BLOCK_SIZE - must always be a multiple of 4 helps us (and our callers) - insure this. */ - -void -disk_empty_output_buffer (int out_des) -{ - int bytes_written; - - if (swapping_halfwords || swapping_bytes) - { - if (swapping_halfwords) - { - int complete_words; - complete_words = output_size / 4; - swahw_array (output_buffer, complete_words); - if (swapping_bytes) - swab_array (output_buffer, 2 * complete_words); - } - else - { - int complete_halfwords; - complete_halfwords = output_size /2; - swab_array (output_buffer, complete_halfwords); - } - } - - if (sparse_flag) - bytes_written = sparse_write (out_des, output_buffer, output_size); - else - bytes_written = write (out_des, output_buffer, output_size); - - if (bytes_written != output_size) - { - error (1, errno, _("write error")); - } - output_bytes += output_size; - out_buff = output_buffer; - output_size = 0; -} - -/* Exchange the halfwords of each element of the array of COUNT longs - starting at PTR. PTR does not have to be aligned at a word - boundary. */ - -void -swahw_array (char *ptr, int count) -{ - char tmp; - - for (; count > 0; --count) - { - tmp = *ptr; - *ptr = *(ptr + 2); - *(ptr + 2) = tmp; - ++ptr; - tmp = *ptr; - *ptr = *(ptr + 2); - *(ptr + 2) = tmp; - ptr += 3; - } -} - -/* Read at most NUM_BYTES or `io_block_size' bytes, whichever is smaller, - into the start of `input_buffer' from file descriptor IN_DES. - Set `input_size' to the number of bytes read and reset `in_buff'. - Exit with an error if end of file is reached. */ - -#ifdef BROKEN_LONG_TAPE_DRIVER -static long input_bytes_before_lseek = 0; -#endif - -static void -tape_fill_input_buffer (int in_des, int num_bytes) -{ -#ifdef BROKEN_LONG_TAPE_DRIVER - /* Some tape drivers seem to have a signed internal seek pointer and - they lose if it overflows and becomes negative (e.g. when writing - tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the - seek pointer and prevent it from overflowing. */ - if (input_is_special - && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) ) - { - lseek(in_des, 0L, SEEK_SET); - input_bytes_before_lseek = 0; - } -#endif - in_buff = input_buffer; - num_bytes = (num_bytes < io_block_size) ? num_bytes : io_block_size; - input_size = rmtread (in_des, input_buffer, num_bytes); - if (input_size == 0 && input_is_special) - { - get_next_reel (in_des); - input_size = rmtread (in_des, input_buffer, num_bytes); - } - if (input_size < 0) - error (1, errno, _("read error")); - if (input_size == 0) - { - error (0, 0, _("premature end of file")); - exit (1); - } - input_bytes += input_size; -} - -/* Read at most NUM_BYTES or `DISK_IO_BLOCK_SIZE' bytes, whichever is smaller, - into the start of `input_buffer' from file descriptor IN_DES. - Set `input_size' to the number of bytes read and reset `in_buff'. - Exit with an error if end of file is reached. */ - -static int -disk_fill_input_buffer (int in_des, off_t num_bytes) -{ - in_buff = input_buffer; - num_bytes = (num_bytes < DISK_IO_BLOCK_SIZE) ? num_bytes : DISK_IO_BLOCK_SIZE; - input_size = read (in_des, input_buffer, num_bytes); - if (input_size < 0) - { - input_size = 0; - return (-1); - } - else if (input_size == 0) - return (1); - input_bytes += input_size; - return (0); -} - -/* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full. - When `out_buff' fills up, flush it to file descriptor OUT_DES. */ - -void -tape_buffered_write (char *in_buf, int out_des, off_t num_bytes) -{ - off_t bytes_left = num_bytes; /* Bytes needing to be copied. */ - off_t space_left; /* Room left in output buffer. */ - - while (bytes_left > 0) - { - space_left = io_block_size - output_size; - if (space_left == 0) - tape_empty_output_buffer (out_des); - else - { - if (bytes_left < space_left) - space_left = bytes_left; - memcpy (out_buff, in_buf, (unsigned) space_left); - out_buff += space_left; - output_size += space_left; - in_buf += space_left; - bytes_left -= space_left; - } - } -} - -/* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full. - When `out_buff' fills up, flush it to file descriptor OUT_DES. */ - -void -disk_buffered_write (char *in_buf, int out_des, off_t num_bytes) -{ - off_t bytes_left = num_bytes; /* Bytes needing to be copied. */ - off_t space_left; /* Room left in output buffer. */ - - while (bytes_left > 0) - { - space_left = DISK_IO_BLOCK_SIZE - output_size; - if (space_left == 0) - disk_empty_output_buffer (out_des); - else - { - if (bytes_left < space_left) - space_left = bytes_left; - memcpy (out_buff, in_buf, (unsigned) space_left); - out_buff += space_left; - output_size += space_left; - in_buf += space_left; - bytes_left -= space_left; - } - } -} - -/* Copy NUM_BYTES of buffer `in_buff' into IN_BUF. - `in_buff' may be partly full. - When `in_buff' is exhausted, refill it from file descriptor IN_DES. */ - -void -tape_buffered_read (char *in_buf, int in_des, off_t num_bytes) -{ - off_t bytes_left = num_bytes; /* Bytes needing to be copied. */ - off_t space_left; /* Bytes to copy from input buffer. */ - - while (bytes_left > 0) - { - if (input_size == 0) - tape_fill_input_buffer (in_des, io_block_size); - if (bytes_left < input_size) - space_left = bytes_left; - else - space_left = input_size; - memcpy (in_buf, in_buff, (unsigned) space_left); - in_buff += space_left; - in_buf += space_left; - input_size -= space_left; - bytes_left -= space_left; - } -} - -/* Copy the the next NUM_BYTES bytes of `input_buffer' into PEEK_BUF. - If NUM_BYTES bytes are not available, read the next `io_block_size' bytes - into the end of `input_buffer' and update `input_size'. - - Return the number of bytes copied into PEEK_BUF. - If the number of bytes returned is less than NUM_BYTES, - then EOF has been reached. */ - -int -tape_buffered_peek (char *peek_buf, int in_des, int num_bytes) -{ - long tmp_input_size; - long got_bytes; - char *append_buf; - -#ifdef BROKEN_LONG_TAPE_DRIVER - /* Some tape drivers seem to have a signed internal seek pointer and - they lose if it overflows and becomes negative (e.g. when writing - tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the - seek pointer and prevent it from overflowing. */ - if (input_is_special - && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) ) - { - lseek(in_des, 0L, SEEK_SET); - input_bytes_before_lseek = 0; - } -#endif - - while (input_size < num_bytes) - { - append_buf = in_buff + input_size; - if ( (append_buf - input_buffer) >= input_buffer_size) - { - /* We can keep up to 2 "blocks" (either the physical block size - or 512 bytes(the size of a tar record), which ever is - larger) in the input buffer when we are peeking. We - assume that our caller will never be interested in peeking - ahead at more than 512 bytes, so we know that by the time - we need a 3rd "block" in the buffer we can throw away the - first block to make room. */ - int half; - half = input_buffer_size / 2; - memmove (input_buffer, input_buffer + half, half); - in_buff = in_buff - half; - append_buf = append_buf - half; - } - tmp_input_size = rmtread (in_des, append_buf, io_block_size); - if (tmp_input_size == 0) - { - if (input_is_special) - { - get_next_reel (in_des); - tmp_input_size = rmtread (in_des, append_buf, io_block_size); - } - else - break; - } - if (tmp_input_size < 0) - error (1, errno, _("read error")); - input_bytes += tmp_input_size; - input_size += tmp_input_size; - } - if (num_bytes <= input_size) - got_bytes = num_bytes; - else - got_bytes = input_size; - memcpy (peek_buf, in_buff, (unsigned) got_bytes); - return got_bytes; -} - -/* Skip the next NUM_BYTES bytes of file descriptor IN_DES. */ - -void -tape_toss_input (int in_des, off_t num_bytes) -{ - off_t bytes_left = num_bytes; /* Bytes needing to be copied. */ - off_t space_left; /* Bytes to copy from input buffer. */ - - while (bytes_left > 0) - { - if (input_size == 0) - tape_fill_input_buffer (in_des, io_block_size); - if (bytes_left < input_size) - space_left = bytes_left; - else - space_left = input_size; - - if (crc_i_flag && only_verify_crc_flag) - { - int k; - for (k = 0; k < space_left; ++k) - crc += in_buff[k] & 0xff; - } - - in_buff += space_left; - input_size -= space_left; - bytes_left -= space_left; - } -} - -void -write_nuls_to_file (off_t num_bytes, int out_des, - void (*writer) (char *in_buf, int out_des, off_t num_bytes)) -{ - off_t blocks; - off_t extra_bytes; - off_t i; - static char zeros_512[512]; - - blocks = num_bytes / sizeof zeros_512; - extra_bytes = num_bytes % sizeof zeros_512; - for (i = 0; i < blocks; ++i) - writer (zeros_512, out_des, sizeof zeros_512); - if (extra_bytes) - writer (zeros_512, out_des, extra_bytes); -} - -/* Copy a file using the input and output buffers, which may start out - partly full. After the copy, the files are not closed nor the last - block flushed to output, and the input buffer may still be partly - full. If `crc_i_flag' is set, add each byte to `crc'. - IN_DES is the file descriptor for input; - OUT_DES is the file descriptor for output; - NUM_BYTES is the number of bytes to copy. */ - -void -copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes) -{ - long size; - long k; - - while (num_bytes > 0) - { - if (input_size == 0) - tape_fill_input_buffer (in_des, io_block_size); - size = (input_size < num_bytes) ? input_size : num_bytes; - if (crc_i_flag) - { - for (k = 0; k < size; ++k) - crc += in_buff[k] & 0xff; - } - disk_buffered_write (in_buff, out_des, size); - num_bytes -= size; - input_size -= size; - in_buff += size; - } -} -/* Copy a file using the input and output buffers, which may start out - partly full. After the copy, the files are not closed nor the last - block flushed to output, and the input buffer may still be partly - full. If `crc_i_flag' is set, add each byte to `crc'. - IN_DES is the file descriptor for input; - OUT_DES is the file descriptor for output; - NUM_BYTES is the number of bytes to copy. */ - -void -copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes, - char *filename) -{ - long size; - long k; - int rc; - off_t original_num_bytes; - - original_num_bytes = num_bytes; - - while (num_bytes > 0) - { - if (input_size == 0) - if (rc = disk_fill_input_buffer (in_des, - num_bytes < DISK_IO_BLOCK_SIZE ? - num_bytes : DISK_IO_BLOCK_SIZE)) - { - if (rc > 0) - { - char buf[UINTMAX_STRSIZE_BOUND]; - error (0, 0, - ngettext ("File %s shrunk by %s byte, padding with zeros", - "File %s shrunk by %s bytes, padding with zeros", - num_bytes), - filename, STRINGIFY_BIGINT (num_bytes, buf)); - } - else - error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"), - original_num_bytes - num_bytes, filename); - write_nuls_to_file (num_bytes, out_des, tape_buffered_write); - break; - } - size = (input_size < num_bytes) ? input_size : num_bytes; - if (crc_i_flag) - { - for (k = 0; k < size; ++k) - crc += in_buff[k] & 0xff; - } - tape_buffered_write (in_buff, out_des, size); - num_bytes -= size; - input_size -= size; - in_buff += size; - } -} -/* Copy a file using the input and output buffers, which may start out - partly full. After the copy, the files are not closed nor the last - block flushed to output, and the input buffer may still be partly - full. If `crc_i_flag' is set, add each byte to `crc'. - IN_DES is the file descriptor for input; - OUT_DES is the file descriptor for output; - NUM_BYTES is the number of bytes to copy. */ - -void -copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes, - char *filename) -{ - long size; - long k; - off_t original_num_bytes; - int rc; - - original_num_bytes = num_bytes; - while (num_bytes > 0) - { - if (input_size == 0) - if (rc = disk_fill_input_buffer (in_des, num_bytes)) - { - if (rc > 0) - { - char buf[UINTMAX_STRSIZE_BOUND]; - error (0, 0, - ngettext ("File %s shrunk by %s byte, padding with zeros", - "File %s shrunk by %s bytes, padding with zeros", - num_bytes), - filename, STRINGIFY_BIGINT (num_bytes, buf)); - } - else - error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"), - original_num_bytes - num_bytes, filename); - write_nuls_to_file (num_bytes, out_des, disk_buffered_write); - break; - } - size = (input_size < num_bytes) ? input_size : num_bytes; - if (crc_i_flag) - { - for (k = 0; k < size; ++k) - crc += in_buff[k] & 0xff; - } - disk_buffered_write (in_buff, out_des, size); - num_bytes -= size; - input_size -= size; - in_buff += size; - } -} - -/* Warn if file changed while it was being copied. */ - -void -warn_if_file_changed (char *file_name, unsigned long old_file_size, - off_t old_file_mtime) -{ - struct stat new_file_stat; - if ((*xstat) (file_name, &new_file_stat) < 0) - { - stat_error (file_name); - return; - } - - /* Only check growth, shrinkage detected in copy_files_disk_to_{disk,tape}() - */ - if (new_file_stat.st_size > old_file_size) - error (0, 0, - ngettext ("File %s grew, %"PRIuMAX" new byte not copied", - "File %s grew, %"PRIuMAX" new bytes not copied", - (long)(new_file_stat.st_size - old_file_size)), - file_name, (uintmax_t) (new_file_stat.st_size - old_file_size)); - - else if (new_file_stat.st_mtime != old_file_mtime) - error (0, 0, _("File %s was modified while being copied"), file_name); -} - -/* Create all directories up to but not including the last part of NAME. - Do not destroy any nondirectories while creating directories. */ - -void -create_all_directories (char *name) -{ - char *dir; - int mode; -#ifdef HPUX_CDF - int cdf; -#endif - - dir = dir_name (name); - mode = 0700; -#ifdef HPUX_CDF - cdf = islastparentcdf (name); - if (cdf) - { - dir [strlen (dir) - 1] = '\0'; /* remove final + */ - mode = 04700; - } - -#endif - - if (dir == NULL) - error (2, 0, _("virtual memory exhausted")); - - if (dir[0] != '.' || dir[1] != '\0') - make_path (dir, mode, 0700, -1, -1, (char *) NULL); - - free (dir); -} - -/* Prepare to append to an archive. We have been in - process_copy_in, keeping track of the position where - the last header started in `last_header_start'. Now we - have the starting position of the last header (the TRAILER!!! - header, or blank record for tar archives) and we want to start - writing (appending) over the last header. The last header may - be in the middle of a block, so to keep the buffering in sync - we lseek back to the start of the block, read everything up - to but not including the last header, lseek back to the start - of the block, and then do a copy_buf_out of what we read. - Actually, we probably don't have to worry so much about keeping the - buffering perfect since you can only append to archives that - are disk files. */ - -void -prepare_append (int out_file_des) -{ - int start_of_header; - int start_of_block; - int useful_bytes_in_block; - char *tmp_buf; - - start_of_header = last_header_start; - /* Figure out how many bytes we will rewrite, and where they start. */ - useful_bytes_in_block = start_of_header % io_block_size; - start_of_block = start_of_header - useful_bytes_in_block; - - if (lseek (out_file_des, start_of_block, SEEK_SET) < 0) - error (1, errno, _("cannot seek on output")); - if (useful_bytes_in_block > 0) - { - tmp_buf = (char *) xmalloc (useful_bytes_in_block); - read (out_file_des, tmp_buf, useful_bytes_in_block); - if (lseek (out_file_des, start_of_block, SEEK_SET) < 0) - error (1, errno, _("cannot seek on output")); - /* fix juo -- is this copy_tape_buf_out? or copy_disk? */ - tape_buffered_write (tmp_buf, out_file_des, useful_bytes_in_block); - free (tmp_buf); - } - - /* We are done reading the archive, so clear these since they - will now be used for reading in files that we are appending - to the archive. */ - input_size = 0; - input_bytes = 0; - in_buff = input_buffer; -} - -/* Support for remembering inodes with multiple links. Used in the - "copy in" and "copy pass" modes for making links instead of copying - the file. */ - -struct inode_val -{ - unsigned long inode; - unsigned long major_num; - unsigned long minor_num; - char *file_name; -}; - -/* Inode hash table. Allocated by first call to add_inode. */ -static Hash_table *hash_table = NULL; - -static size_t -inode_val_hasher (const void *val, size_t n_buckets) -{ - const struct inode_val *ival = val; - return ival->inode % n_buckets; -} - -static bool -inode_val_compare (const void *val1, const void *val2) -{ - const struct inode_val *ival1 = val1; - const struct inode_val *ival2 = val2; - return ival1->inode == ival2->inode - && ival1->major_num == ival2->major_num - && ival1->minor_num == ival2->minor_num; -} - -char * -find_inode_file (unsigned long node_num, unsigned long major_num, - unsigned long minor_num) -{ - struct inode_val sample; - struct inode_val *ival; - - if (!hash_table) - return NULL; - - sample.inode = node_num; - sample.major_num = major_num; - sample.minor_num = minor_num; - ival = hash_lookup (hash_table, &sample); - return ival ? ival->file_name : NULL; -} - -/* Associate FILE_NAME with the inode NODE_NUM. (Insert into hash table.) */ - -void -add_inode (unsigned long node_num, char *file_name, unsigned long major_num, - unsigned long minor_num) -{ - struct inode_val *temp; - struct inode_val *e; - - /* Create new inode record. */ - temp = (struct inode_val *) xmalloc (sizeof (struct inode_val)); - temp->inode = node_num; - temp->major_num = major_num; - temp->minor_num = minor_num; - temp->file_name = xstrdup (file_name); - - if (!((hash_table - || (hash_table = hash_initialize (0, 0, inode_val_hasher, - inode_val_compare, 0))) - && (e = hash_insert (hash_table, temp)))) - xalloc_die (); - /* FIXME: e is not used */ -} - - -/* Open FILE in the mode specified by the command line options - and return an open file descriptor for it, - or -1 if it can't be opened. */ - -int -open_archive (char *file) -{ - int fd; - void (*copy_in) (); /* Workaround for pcc bug. */ - - copy_in = process_copy_in; - - if (copy_function == copy_in) - fd = rmtopen (file, O_RDONLY | O_BINARY, MODE_RW, rsh_command_option); - else - { - if (!append_flag) - fd = rmtopen (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, MODE_RW, - rsh_command_option); - else - fd = rmtopen (file, O_RDWR | O_BINARY, MODE_RW, rsh_command_option); - } - - return fd; -} - -/* Attempt to rewind the tape drive on file descriptor TAPE_DES - and take it offline. */ - -void -tape_offline (int tape_des) -{ -#if defined(MTIOCTOP) && defined(MTOFFL) - struct mtop control; - - control.mt_op = MTOFFL; - control.mt_count = 1; - rmtioctl (tape_des, MTIOCTOP, (char*) &control); /* Don't care if it fails. */ -#endif -} - -/* The file on file descriptor TAPE_DES is assumed to be magnetic tape - (or floppy disk or other device) and the end of the medium - has been reached. Ask the user for to mount a new "tape" to continue - the processing. If the user specified the device name on the - command line (with the -I, -O, -F or --file options), then we can - automatically re-open the same device to use the next medium. If the - user did not specify the device name, then we have to ask them which - device to use. */ - -void -get_next_reel (int tape_des) -{ - static int reel_number = 1; - FILE *tty_in; /* File for interacting with user. */ - FILE *tty_out; /* File for interacting with user. */ - int old_tape_des; - char *next_archive_name; - dynamic_string new_name; - char *str_res; - - ds_init (&new_name, 128); - - /* Open files for interactive communication. */ - tty_in = fopen (TTY_NAME, "r"); - if (tty_in == NULL) - error (2, errno, TTY_NAME); - tty_out = fopen (TTY_NAME, "w"); - if (tty_out == NULL) - error (2, errno, TTY_NAME); - - old_tape_des = tape_des; - tape_offline (tape_des); - rmtclose (tape_des); - - /* Give message and wait for carrage return. User should hit carrage return - only after loading the next tape. */ - ++reel_number; - if (new_media_message) - fprintf (tty_out, "%s", new_media_message); - else if (new_media_message_with_number) - fprintf (tty_out, "%s%d%s", new_media_message_with_number, reel_number, - new_media_message_after_number); - else if (archive_name) - fprintf (tty_out, _("Found end of volume. Load next volume and press RETURN. ")); - else - fprintf (tty_out, _("Found end of volume. To continue, type device/file name when ready.\n")); - - fflush (tty_out); - - if (archive_name) - { - int c; - - do - c = getc (tty_in); - while (c != EOF && c != '\n'); - - tape_des = open_archive (archive_name); - if (tape_des == -1) - open_error (archive_name); - } - else - { - do - { - if (tape_des < 0) - { - fprintf (tty_out, - _("To continue, type device/file name when ready.\n")); - fflush (tty_out); - } - - str_res = ds_fgets (tty_in, &new_name); - if (str_res == NULL || str_res[0] == '\0') - exit (1); - next_archive_name = str_res; - - tape_des = open_archive (next_archive_name); - if (tape_des == -1) - open_error (next_archive_name); - } - while (tape_des < 0); - } - - /* We have to make sure that `tape_des' has not changed its value even - though we closed it and reopened it, since there are local - copies of it in other routines. This works fine on Unix (even with - rmtread and rmtwrite) since open will always return the lowest - available file descriptor and we haven't closed any files (e.g., - stdin, stdout or stderr) that were opened before we originally opened - the archive. */ - - if (tape_des != old_tape_des) - error (1, 0, _("internal error: tape descriptor changed from %d to %d"), - old_tape_des, tape_des); - - free (new_name.ds_string); - fclose (tty_in); - fclose (tty_out); -} - -/* If MESSAGE does not contain the string "%d", make `new_media_message' - a copy of MESSAGE. If MESSAGES does contain the string "%d", make - `new_media_message_with_number' a copy of MESSAGE up to, but - not including, the string "%d", and make `new_media_message_after_number' - a copy of MESSAGE after the string "%d". */ - -void -set_new_media_message (char *message) -{ - char *p; - int prev_was_percent; - - p = message; - prev_was_percent = 0; - while (*p != '\0') - { - if (*p == 'd' && prev_was_percent) - break; - prev_was_percent = (*p == '%'); - ++p; - } - if (*p == '\0') - { - new_media_message = xstrdup (message); - } - else - { - int length = p - message - 1; - - new_media_message_with_number = xmalloc (length + 1); - strncpy (new_media_message_with_number, message, length); - new_media_message_with_number[length] = '\0'; - length = strlen (p + 1); - new_media_message_after_number = xmalloc (length + 1); - strcpy (new_media_message_after_number, p + 1); - } -} - -#ifdef SYMLINK_USES_UMASK -/* Most machines always create symlinks with rwxrwxrwx protection, - but some (HP/UX 8.07; maybe DEC's OSF on MIPS, too?) use the - umask when creating symlinks, so if your umask is 022 you end - up with rwxr-xr-x symlinks (although HP/UX seems to completely - ignore the protection). There doesn't seem to be any way to - manipulate the modes once the symlinks are created (e.g. - a hypothetical "lchmod"), so to create them with the right - modes we have to set the umask first. */ - -int -umasked_symlink (char *name1, char *name2, int mode) -{ - int old_umask; - int rc; - mode = ~(mode & 0777) & 0777; - old_umask = umask (mode); - rc = symlink (name1, name2); - umask (old_umask); - return rc; -} -#endif /* SYMLINK_USES_UMASK */ - -#ifdef HPUX_CDF -/* When we create a cpio archive we mark CDF's by putting an extra `/' - after their component name so we can distinguish the CDF's when we - extract the archive (in case the "hidden" directory's files appear - in the archive before the directory itself). E.g., in the path - "a/b+/c", if b+ is a CDF, we will write this path as "a/b+//c" in - the archive so when we extract the archive we will know that b+ - is actually a CDF, and not an ordinary directory whose name happens - to end in `+'. We also do the same thing internally in copypass.c. */ - - -/* Take an input pathname and check it for CDF's. Insert an extra - `/' in the pathname after each "hidden" directory. If we add - any `/'s, return a malloced string instead of the original input - string. - FIXME: This creates a memory leak. -*/ - -char * -add_cdf_double_slashes (char *input_name) -{ - static char *ret_name = NULL; /* re-usuable return buffer (malloc'ed) */ - static int ret_size = -1; /* size of return buffer. */ - char *p; - char *q; - int n; - struct stat dir_stat; - - /* Search for a `/' preceeded by a `+'. */ - - for (p = input_name; *p != '\0'; ++p) - { - if ( (*p == '+') && (*(p + 1) == '/') ) - break; - } - - /* If we didn't find a `/' preceeded by a `+' then there are - no CDF's in this pathname. Return the original pathname. */ - - if (*p == '\0') - return input_name; - - /* There was a `/' preceeded by a `+' in the pathname. If it is a CDF - then we will need to copy the input pathname to our return - buffer so we can insert the extra `/'s. Since we can't tell - yet whether or not it is a CDF we will just always copy the - string to the return buffer. First we have to make sure the - buffer is large enough to hold the string and any number of - extra `/'s we might add. */ - - n = 2 * (strlen (input_name) + 1); - if (n >= ret_size) - { - if (ret_size < 0) - ret_name = (char *) malloc (n); - else - ret_name = (char *)realloc (ret_name, n); - ret_size = n; - } - - /* Clear the `/' after this component, so we can stat the pathname - up to and including this component. */ - ++p; - *p = '\0'; - if ((*xstat) (input_name, &dir_stat) < 0) - { - stat_error (input_name); - return input_name; - } - - /* Now put back the `/' after this component and copy the pathname up to - and including this component and its trailing `/' to the return - buffer. */ - *p++ = '/'; - strncpy (ret_name, input_name, p - input_name); - q = ret_name + (p - input_name); - - /* If it was a CDF, add another `/'. */ - if (S_ISDIR (dir_stat.st_mode) && (dir_stat.st_mode & 04000) ) - *q++ = '/'; - - /* Go through the rest of the input pathname, copying it to the - return buffer, and adding an extra `/' after each CDF. */ - while (*p != '\0') - { - if ( (*p == '+') && (*(p + 1) == '/') ) - { - *q++ = *p++; - - *p = '\0'; - if ((*xstat) (input_name, &dir_stat) < 0) - { - stat_error (input_name); - return input_name; - } - *p = '/'; - - if (S_ISDIR (dir_stat.st_mode) && (dir_stat.st_mode & 04000) ) - *q++ = '/'; - } - *q++ = *p++; - } - *q = '\0'; - - return ret_name; -} - -/* Is the last parent directory (e.g., c in a/b/c/d) a CDF? If the - directory name ends in `+' and is followed by 2 `/'s instead of 1 - then it is. This is only the case for cpio archives, but we don't - have to worry about tar because tar always has the directory before - its files (or else we lose). */ -int -islastparentcdf (char *path) -{ - char *newpath; - char *slash; - int slash_count; - int length; /* Length of result, not including NUL. */ - - slash = strrchr (path, '/'); - if (slash == 0) - return 0; - else - { - slash_count = 0; - while (slash > path && *slash == '/') - { - ++slash_count; - --slash; - } - - - if ( (*slash == '+') && (slash_count >= 2) ) - return 1; - } - return 0; -} -#endif - -#define DISKBLOCKSIZE (512) - -static int -buf_all_zeros (char *buf, int bufsize) -{ - int i; - for (i = 0; i < bufsize; ++i) - { - if (*buf++ != '\0') - return 0; - } - return 1; -} - -int delayed_seek_count = 0; - -/* Write NBYTE bytes from BUF to remote tape connection FILDES. - Return the number of bytes written on success, -1 on error. */ - -static int -sparse_write (int fildes, char *buf, unsigned int nbyte) -{ - int complete_block_count; - int leftover_bytes_count; - int seek_count; - int write_count; - char *cur_write_start; - int lseek_rc; - int write_rc; - int i; - enum { begin, in_zeros, not_in_zeros } state; - - complete_block_count = nbyte / DISKBLOCKSIZE; - leftover_bytes_count = nbyte % DISKBLOCKSIZE; - - if (delayed_seek_count != 0) - state = in_zeros; - else - state = begin; - - seek_count = delayed_seek_count; - - for (i = 0; i < complete_block_count; ++i) - { - switch (state) - { - case begin : - if (buf_all_zeros (buf, DISKBLOCKSIZE)) - { - seek_count = DISKBLOCKSIZE; - state = in_zeros; - } - else - { - cur_write_start = buf; - write_count = DISKBLOCKSIZE; - state = not_in_zeros; - } - buf += DISKBLOCKSIZE; - break; - - case in_zeros : - if (buf_all_zeros (buf, DISKBLOCKSIZE)) - { - seek_count += DISKBLOCKSIZE; - } - else - { - lseek (fildes, seek_count, SEEK_CUR); - cur_write_start = buf; - write_count = DISKBLOCKSIZE; - state = not_in_zeros; - } - buf += DISKBLOCKSIZE; - break; - - case not_in_zeros : - if (buf_all_zeros (buf, DISKBLOCKSIZE)) - { - write_rc = write (fildes, cur_write_start, write_count); - seek_count = DISKBLOCKSIZE; - state = in_zeros; - } - else - { - write_count += DISKBLOCKSIZE; - } - buf += DISKBLOCKSIZE; - break; - } - } - - switch (state) - { - case begin : - case in_zeros : - delayed_seek_count = seek_count; - break; - - case not_in_zeros : - write_rc = write (fildes, cur_write_start, write_count); - delayed_seek_count = 0; - break; - } - - if (leftover_bytes_count != 0) - { - if (delayed_seek_count != 0) - { - lseek_rc = lseek (fildes, delayed_seek_count, SEEK_CUR); - delayed_seek_count = 0; - } - write_rc = write (fildes, buf, leftover_bytes_count); - } - return nbyte; -} - -#define CPIO_UID(uid) (set_owner_flag ? set_owner : (uid)) -#define CPIO_GID(gid) (set_group_flag ? set_group : (gid)) - -void -stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st) -{ - hdr->c_dev_maj = major (st->st_dev); - hdr->c_dev_min = minor (st->st_dev); - hdr->c_ino = st->st_ino; - /* For POSIX systems that don't define the S_IF macros, - we can't assume that S_ISfoo means the standard Unix - S_IFfoo bit(s) are set. So do it manually, with a - different name. Bleah. */ - hdr->c_mode = (st->st_mode & 07777); - if (S_ISREG (st->st_mode)) - hdr->c_mode |= CP_IFREG; - else if (S_ISDIR (st->st_mode)) - hdr->c_mode |= CP_IFDIR; -#ifdef S_ISBLK - else if (S_ISBLK (st->st_mode)) - hdr->c_mode |= CP_IFBLK; -#endif -#ifdef S_ISCHR - else if (S_ISCHR (st->st_mode)) - hdr->c_mode |= CP_IFCHR; -#endif -#ifdef S_ISFIFO - else if (S_ISFIFO (st->st_mode)) - hdr->c_mode |= CP_IFIFO; -#endif -#ifdef S_ISLNK - else if (S_ISLNK (st->st_mode)) - hdr->c_mode |= CP_IFLNK; -#endif -#ifdef S_ISSOCK - else if (S_ISSOCK (st->st_mode)) - hdr->c_mode |= CP_IFSOCK; -#endif -#ifdef S_ISNWK - else if (S_ISNWK (st->st_mode)) - hdr->c_mode |= CP_IFNWK; -#endif - hdr->c_uid = CPIO_UID (st->st_uid); - hdr->c_gid = CPIO_GID (st->st_gid); - hdr->c_nlink = st->st_nlink; - hdr->c_rdev_maj = major (st->st_rdev); - hdr->c_rdev_min = minor (st->st_rdev); - hdr->c_mtime = st->st_mtime; - hdr->c_filesize = st->st_size; - hdr->c_chksum = 0; - hdr->c_tar_linkname = NULL; -} - -#ifndef HAVE_FCHOWN -# define fchown(fd, uid, gid) (-1) -#endif - -int -fchown_or_chown (int fd, const char *name, uid_t uid, uid_t gid) -{ - if (HAVE_FCHOWN && fd != -1) - return fchown (fd, uid, gid); - else - return chown (name, uid, gid); -} - -int -fchmod_or_chmod (int fd, const char *name, mode_t mode) -{ - if (HAVE_FCHMOD && fd != -1) - return fchmod (fd, mode); - else - return chmod(name, mode); -} - -void -set_perms (int fd, struct cpio_file_stat *header) -{ - if (!no_chown_flag) - { - uid_t uid = CPIO_UID (header->c_uid); - gid_t gid = CPIO_GID (header->c_gid); - if ((fchown_or_chown (fd, header->c_name, uid, gid) < 0) - && errno != EPERM) - chown_error_details (header->c_name, uid, gid); - } - /* chown may have turned off some permissions we wanted. */ - if (fchmod_or_chmod (fd, header->c_name, header->c_mode) < 0) - chmod_error_details (header->c_name, header->c_mode); -#ifdef HPUX_CDF - if ((header->c_mode & CP_IFMT) && cdf_flag) - /* Once we "hide" the directory with the chmod(), - we have to refer to it using name+ instead of name. */ - file_hdr->c_name [cdf_char] = '+'; -#endif - if (retain_time_flag) - set_file_times (fd, header->c_name, header->c_mtime, header->c_mtime); -} - -void -set_file_times (int fd, - const char *name, unsigned long atime, unsigned long mtime) -{ - struct timespec ts[2]; - - memset (&ts, 0, sizeof ts); - - ts[0].tv_sec = atime; - ts[1].tv_sec = mtime; - - /* Silently ignore EROFS because reading the file won't have upset its - timestamp if it's on a read-only filesystem. */ - if (gl_futimens (fd, name, ts) < 0 && errno != EROFS) - utime_error (name); -} - -/* Do we have to ignore absolute paths, and if so, does the filename - have an absolute path? */ -void -cpio_safer_name_suffix (char *name, bool link_target, bool absolute_names, - bool strip_leading_dots) -{ - char *p = safer_name_suffix (name, link_target, absolute_names); - if (strip_leading_dots && strcmp (p, "./")) - /* strip leading `./' from the filename. */ - while (*p == '.' && *(p + 1) == '/') - { - ++p; - while (*p == '/') - ++p; - } - if (p != name) - memmove (name, p, (size_t)(strlen (p) + 1)); -} - diff --git a/gnu/usr.bin/Makefile b/gnu/usr.bin/Makefile index 82792df3bf9..c300b333480 100644 --- a/gnu/usr.bin/Makefile +++ b/gnu/usr.bin/Makefile @@ -5,7 +5,6 @@ SUBDIR= bc \ ${_binutils} \ ${_cc} \ - ${_cpio} \ ${_cvs} \ dc \ dialog \ @@ -34,10 +33,6 @@ _groff= groff .endif .endif -.if ${MK_GNU_CPIO} == "yes" -_cpio= cpio -.endif - .if ${MK_CVS} != "no" _cvs= cvs .endif diff --git a/gnu/usr.bin/cpio/Makefile b/gnu/usr.bin/cpio/Makefile deleted file mode 100644 index c31527be94a..00000000000 --- a/gnu/usr.bin/cpio/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -# $FreeBSD$ - -CPIODIR= ${.CURDIR}/../../../contrib/cpio -.PATH: ${CPIODIR}/lib ${CPIODIR}/src ${CPIODIR}/doc - -SUBDIR= doc - -PROG= gcpio -SRCS= copyin.c \ - copyout.c \ - copypass.c \ - defer.c \ - dstring.c \ - filemode.c \ - global.c \ - idcache.c \ - main.c \ - makepath.c \ - tar.c \ - userspec.c \ - util.c \ - argp-ba.c \ - argp-eexst.c \ - argp-fmtstream.c \ - argp-fs-xinl.c \ - argp-help.c \ - argp-parse.c \ - argp-pin.c \ - argp-pv.c \ - argp-pvh.c \ - argp-xinl.c \ - basename.c \ - dirname.c \ - error.c \ - exitfail.c \ - fatal.c \ - full-write.c \ - getopt.c \ - getopt1.c \ - hash.c \ - mempcpy.c \ - paxerror.c \ - paxexit.c \ - paxnames.c \ - quote.c \ - quotearg.c \ - rtapelib.c \ - safe-read.c \ - safe-write.c \ - strchrnul.c \ - stripslash.c \ - strndup.c \ - strnlen.c \ - umaxtostr.c \ - utimens.c \ - xalloc-die.c \ - xmalloc.c \ - xstrndup.c \ - alloca.h \ - getopt.h -CSTD=gnu89 - -CLEANFILES+= alloca.h getopt.h - -getopt.h: getopt_.h - ln -fs ${.ALLSRC} ${.TARGET} - -alloca.h: alloca_.h - ln -fs ${.ALLSRC} ${.TARGET} - -CFLAGS+=-I${.OBJDIR} -I${.CURDIR} -I${CPIODIR}/lib -I${CPIODIR}/src \ - -DHAVE_CONFIG_H -DHAVE_MKFIFO -DHAVE_SETLOCALE -DHAVE_LSTAT - -gcpio.1: ${CPIODIR}/doc/cpio.1 - cat ${CPIODIR}/doc/cpio.1 >gcpio.1 - -SYMLINKS=gcpio ${BINDIR}/cpio -MLINKS=gcpio.1 cpio.1 - -.include diff --git a/gnu/usr.bin/cpio/config.h b/gnu/usr.bin/cpio/config.h deleted file mode 100644 index 36a88f0a72c..00000000000 --- a/gnu/usr.bin/cpio/config.h +++ /dev/null @@ -1,1001 +0,0 @@ -/* $FreeBSD$ */ - -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define this to an absolute name of . */ -/* #undef ABSOLUTE_DIRENT_H */ - -/* Define this to an absolute name of . */ -#define ABSOLUTE_FCNTL_H "///usr/include/fcntl.h" - -/* Define this to an absolute name of . */ -/* #undef ABSOLUTE_FLOAT_H */ - -/* Define this to an absolute name of . */ -#define ABSOLUTE_INTTYPES_H "///usr/include/inttypes.h" - -/* Define this to an absolute name of . */ -#define ABSOLUTE_STDINT_H "///usr/include/stdint.h" - -/* Define this to an absolute name of . */ -#define ABSOLUTE_STDIO_H "///usr/include/stdio.h" - -/* Define this to an absolute name of . */ -#define ABSOLUTE_STDLIB_H "///usr/include/stdlib.h" - -/* Define this to an absolute name of . */ -#define ABSOLUTE_STRING_H "///usr/include/string.h" - -/* Define this to an absolute name of . */ -#define ABSOLUTE_SYSEXITS_H "///usr/include/sysexits.h" - -/* Define this to an absolute name of . */ -#define ABSOLUTE_SYS_STAT_H "///usr/include/sys/stat.h" - -/* Define this to an absolute name of . */ -#define ABSOLUTE_SYS_TIME_H "///usr/include/sys/time.h" - -/* Define this to an absolute name of . */ -#define ABSOLUTE_TIME_H "///usr/include/time.h" - -/* Define this to an absolute name of . */ -#define ABSOLUTE_UNISTD_H "///usr/include/unistd.h" - -/* Define this to an absolute name of . */ -/* #undef ABSOLUTE_WCHAR_H */ - -/* Define this to an absolute name of . */ -#define ABSOLUTE_WCTYPE_H "///usr/include/wctype.h" - -/* Define to the number of bits in type 'ptrdiff_t'. */ -/* #undef BITSIZEOF_PTRDIFF_T */ - -/* Define to the number of bits in type 'sig_atomic_t'. */ -/* #undef BITSIZEOF_SIG_ATOMIC_T */ - -/* Define to the number of bits in type 'size_t'. */ -/* #undef BITSIZEOF_SIZE_T */ - -/* Define to the number of bits in type 'wchar_t'. */ -/* #undef BITSIZEOF_WCHAR_T */ - -/* Define to the number of bits in type 'wint_t'. */ -/* #undef BITSIZEOF_WINT_T */ - -/* Define if chown is not POSIX compliant regarding IDs of -1. */ -/* #undef CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE */ - -/* Define if chown modifies symlinks. */ -/* #undef CHOWN_MODIFIES_SYMLINK */ - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. - */ -/* #undef CRAY_STACKSEG_END */ - -/* Define to 1 if using `alloca.c'. */ -/* #undef C_ALLOCA */ - -/* Define full file name of rmt program. */ -#define DEFAULT_RMT_COMMAND "/etc/rmt" - -/* the name of the file descriptor member of DIR */ -/* #undef DIR_FD_MEMBER_NAME */ - -#ifdef DIR_FD_MEMBER_NAME -# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME) -#else -# define DIR_TO_FD(Dir_p) -1 -#endif - - -/* Define to 1 if // is a file system root distinct from /. */ -/* #undef DOUBLE_SLASH_IS_DISTINCT_ROOT */ - -/* Define if struct dirent has a member d_ino that actually works. */ -#define D_INO_IN_DIRENT 1 - -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -/* #undef ENABLE_NLS */ - -/* Define as good substitute value for EOVERFLOW. */ -/* #undef EOVERFLOW */ - -/* Define if gnulib's fchdir() replacement is used. */ -/* #undef FCHDIR_REPLACEMENT */ - -/* Define on systems for which file names may have a so-called `drive letter' - prefix, define this to compute the length of that prefix, including the - colon. */ -#define FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX 0 - -/* Define if the backslash character may also serve as a file name component - separator. */ -#define FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR 0 - -/* Define if a drive letter prefix denotes a relative path if it is not - followed by a file name component separator. */ -#define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 - -/* Define if gettimeofday clobbers the localtime buffer. */ -/* #undef GETTIMEOFDAY_CLOBBERS_LOCALTIME */ - -/* Define to 1 when using the gnulib module close-stream. */ -#define GNULIB_CLOSE_STREAM 1 - -/* Define to 1 when using the gnulib module fcntl-safer. */ -#define GNULIB_FCNTL_SAFER 1 - -/* Define to 1 to add extern declaration of program_invocation_name to argp.h - */ -#define GNULIB_PROGRAM_INVOCATION_NAME 1 - -/* Define to 1 to add extern declaration of program_invocation_short_name to - argp.h */ -#define GNULIB_PROGRAM_INVOCATION_SHORT_NAME 1 - -/* Define to 1 if you have the `alarm' function. */ -#define HAVE_ALARM 1 - -/* Define to 1 if you have 'alloca' after including , a header that - may be supplied by this distribution. */ -#define HAVE_ALLOCA 1 - -/* Define HAVE_ALLOCA_H for backward compatibility with older code that - includes only if HAVE_ALLOCA_H is defined. */ -#define HAVE_ALLOCA_H 1 - -/* Define to 1 if you have the `btowc' function. */ -#define HAVE_BTOWC 1 - -/* Define to 1 if you have the `canonicalize_file_name' function. */ -/* #undef HAVE_CANONICALIZE_FILE_NAME */ - -/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the - CoreFoundation framework. */ -/* #undef HAVE_CFLOCALECOPYCURRENT */ - -/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in - the CoreFoundation framework. */ -/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ - -/* Define to 1 if your system has a working `chown' function. */ -#define HAVE_CHOWN 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -#define HAVE_CLOCK_GETTIME 1 - -/* Define to 1 if you have the `clock_settime' function. */ -#define HAVE_CLOCK_SETTIME 1 - -/* Define if you have compound literals. */ -/* #undef HAVE_COMPOUND_LITERALS */ - -/* Define if the GNU dcgettext() function is already present or preinstalled. - */ -/* #undef HAVE_DCGETTEXT */ - -/* Define to 1 if you have the declaration of `atoi', and to 0 if you don't. - */ -#define HAVE_DECL_ATOI 1 - -/* Define to 1 if you have the declaration of `canonicalize_file_name', and to - 0 if you don't. */ -#define HAVE_DECL_CANONICALIZE_FILE_NAME 0 - -/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_CLEARERR_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `dirfd', and to 0 if you don't. - */ -#define HAVE_DECL_DIRFD 1 - -/* Define to 1 if you have the declaration of `errno', and to 0 if you don't. - */ -#define HAVE_DECL_ERRNO 1 - -/* Define to 1 if you have the declaration of `exit', and to 0 if you don't. - */ -#define HAVE_DECL_EXIT 1 - -/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you - don't. */ -#define HAVE_DECL_FEOF_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FERROR_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FFLUSH_UNLOCKED 0 - -/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FGETS_UNLOCKED 0 - -/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FPUTC_UNLOCKED 0 - -/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FPUTS_UNLOCKED 0 - -/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FREAD_UNLOCKED 0 - -/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FWRITE_UNLOCKED 0 - -/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_GETCHAR_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `getcwd', and to 0 if you don't. - */ -#define HAVE_DECL_GETCWD 1 - -/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you - don't. */ -#define HAVE_DECL_GETC_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't. - */ -#define HAVE_DECL_GETENV 1 - -/* Define to 1 if you have the declaration of `getgrgid', and to 0 if you - don't. */ -#define HAVE_DECL_GETGRGID 1 - -/* Define to 1 if you have the declaration of `getgrnam', and to 0 if you - don't. */ -#define HAVE_DECL_GETGRNAM 1 - -/* Define to 1 if you have the declaration of `getpwnam', and to 0 if you - don't. */ -#define HAVE_DECL_GETPWNAM 1 - -/* Define to 1 if you have the declaration of `imaxabs', and to 0 if you - don't. */ -#define HAVE_DECL_IMAXABS 1 - -/* Define to 1 if you have the declaration of `imaxdiv', and to 0 if you - don't. */ -#define HAVE_DECL_IMAXDIV 1 - -/* Define to 1 if you have the declaration of `isblank', and to 0 if you - don't. */ -#define HAVE_DECL_ISBLANK 1 - -/* Define to 1 if you have the declaration of `lchown', and to 0 if you don't. - */ -#define HAVE_DECL_LCHOWN 1 - -/* Define to 1 if you have the declaration of `memrchr', and to 0 if you - don't. */ -#define HAVE_DECL_MEMRCHR 0 - -/* Define to 1 if you have the declaration of `mkdir', and to 0 if you don't. - */ -#define HAVE_DECL_MKDIR 1 - -/* Define if program_invocation_name is declared */ -/* #undef HAVE_DECL_PROGRAM_INVOCATION_NAME */ - -/* Define if program_invocation_short_name is declared */ -/* #undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME */ - -/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_PUTCHAR_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you - don't. */ -#define HAVE_DECL_PUTC_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `strdup', and to 0 if you don't. - */ -#define HAVE_DECL_STRDUP 1 - -/* Define to 1 if you have the declaration of `strerror', and to 0 if you - don't. */ -#define HAVE_DECL_STRERROR 1 - -/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you - don't. */ -#define HAVE_DECL_STRERROR_R 1 - -/* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you - don't. */ -#define HAVE_DECL_STRNCASECMP 1 - -/* Define to 1 if you have the declaration of `strndup', and to 0 if you - don't. */ -#define HAVE_DECL_STRNDUP 0 - -/* Define to 1 if you have the declaration of `strnlen', and to 0 if you - don't. */ -#define HAVE_DECL_STRNLEN 0 - -/* Define to 1 if you have the declaration of `strtoimax', and to 0 if you - don't. */ -#define HAVE_DECL_STRTOIMAX 1 - -/* Define to 1 if you have the declaration of `strtoumax', and to 0 if you - don't. */ -#define HAVE_DECL_STRTOUMAX 1 - -/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. - */ -/* #undef HAVE_DECL_TZNAME */ - -/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you - don't. */ -#define HAVE_DECL_VSNPRINTF 1 - -/* Define to 1 if you have the declaration of `__fpending', and to 0 if you - don't. */ -#define HAVE_DECL___FPENDING 0 - -/* Define to 1 if you have the header file. */ -#define HAVE_DIRENT_H 1 - -/* Define to 1 if you have the `dirfd' function. */ -/* #undef HAVE_DIRFD */ - -/* Define to 1 if you have the `dup2' function. */ -#define HAVE_DUP2 1 - -/* Define if you have the declaration of environ. */ -/* #undef HAVE_ENVIRON_DECL */ - -/* Define to 1 if you have the `fchdir' function. */ -#define HAVE_FCHDIR 1 - -/* Define to 1 if you have the `fchmod' function. */ -#define HAVE_FCHMOD 1 - -/* Define to 1 if you have the `fchmodat' function. */ -/* #undef HAVE_FCHMODAT */ - -/* Define to 1 if you have the `fchown' function. */ -#define HAVE_FCHOWN 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `fdopendir' function. */ -/* #undef HAVE_FDOPENDIR */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_FEATURES_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FLOAT_H 1 - -/* Define to 1 if you have the `flockfile' function. */ -#define HAVE_FLOCKFILE 1 - -/* Define to 1 if you have the `funlockfile' function. */ -#define HAVE_FUNLOCKFILE 1 - -/* Define to 1 if you have the `futimes' function. */ -#define HAVE_FUTIMES 1 - -/* Define to 1 if you have the `futimesat' function. */ -/* #undef HAVE_FUTIMESAT */ - -/* Define to 1 if you have the `getcwd' function. */ -#define HAVE_GETCWD 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_GETOPT_H 1 - -/* Define to 1 if you have the `getopt_long_only' function. */ -#define HAVE_GETOPT_LONG_ONLY 1 - -/* Define to 1 if you have the `getpagesize' function. */ -#define HAVE_GETPAGESIZE 1 - -/* Define if the GNU gettext() function is already present or preinstalled. */ -/* #undef HAVE_GETTEXT */ - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define if you have the iconv() function and it works. */ -/* #undef HAVE_ICONV */ - -/* Define to 1 if the compiler supports one of the keywords 'inline', - '__inline__', '__inline' and effectively inlines functions marked as such. - */ -#define HAVE_INLINE 1 - -/* Define if you have the 'intmax_t' type in or . */ -#define HAVE_INTMAX_T 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define if exists, doesn't clash with , and - declares uintmax_t. */ -#define HAVE_INTTYPES_H_WITH_UINTMAX 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IO_H */ - -/* Define to 1 if you have the `iswcntrl' function. */ -#define HAVE_ISWCNTRL 1 - -/* Define to 1 if you have the `iswctype' function. */ -#define HAVE_ISWCTYPE 1 - -/* Define to 1 if you have the `lchmod' function. */ -#define HAVE_LCHMOD 1 - -/* Define to 1 if you have the `lchown' function. */ -#define HAVE_LCHOWN 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LIBINTL_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LINEWRAP_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define if you have the 'long long' type. */ -#define HAVE_LONG_LONG 1 - -/* Define to 1 if the system has the type `long long int'. */ -#define HAVE_LONG_LONG_INT 1 - -/* Define to 1 if you have the `lstat' function. */ -#define HAVE_LSTAT 1 - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#define HAVE_MALLOC 1 - -/* Define to 1 if mbrtowc and mbstate_t are properly declared. */ -#define HAVE_MBRTOWC 1 - -/* Define to 1 if you have the `mbsinit' function. */ -#define HAVE_MBSINIT 1 - -/* Define to 1 if you have the `mbsrtowcs' function. */ -#define HAVE_MBSRTOWCS 1 - -/* Define to 1 if declares mbstate_t. */ -#define HAVE_MBSTATE_T 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mempcpy' function. */ -/* #undef HAVE_MEMPCPY */ - -/* Define to 1 if you have the `memrchr' function. */ -/* #undef HAVE_MEMRCHR */ - -/* Define to 1 if you have the `mkdirat' function. */ -/* #undef HAVE_MKDIRAT */ - -/* Define to 1 if you have the `mkfifo' function. */ -#define HAVE_MKFIFO 1 - -/* Define to 1 if you have the `nanotime' function. */ -/* #undef HAVE_NANOTIME */ - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -/* #undef HAVE_NDIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NET_ERRNO_H */ - -/* Define to 1 if libc includes obstacks. */ -/* #undef HAVE_OBSTACK */ - -/* Define to 1 if you have the `openat' function. */ -/* #undef HAVE_OPENAT */ - -/* Define to 1 if getcwd works, except it sometimes fails when it shouldn't, - setting errno to ERANGE, ENAMETOOLONG, or ENOENT. If __GETCWD_PREFIX is not - defined, it doesn't matter whether HAVE_PARTLY_WORKING_GETCWD is defined. - */ -#define HAVE_PARTLY_WORKING_GETCWD 1 - -/* Define to 1 if you have the `pipe' function. */ -#define HAVE_PIPE 1 - -/* Define if program_invocation_name is defined */ -/* #undef HAVE_PROGRAM_INVOCATION_NAME */ - -/* Define if program_invocation_short_name is defined */ -/* #undef HAVE_PROGRAM_INVOCATION_SHORT_NAME */ - -/* Define to 1 if the system has the type `ptrdiff_t'. */ -#define HAVE_PTRDIFF_T 1 - -/* Define to 1 if you have the `readlink' function. */ -#define HAVE_READLINK 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SEARCH_H */ - -/* Define to 1 if you have the `setenv' function. */ -#define HAVE_SETENV 1 - -/* Define to 1 if you have the `setlocale' function. */ -#define HAVE_SETLOCALE 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SGTTY_H */ - -/* Define to 1 if 'sig_atomic_t' is a signed integer type. */ -/* #undef HAVE_SIGNED_SIG_ATOMIC_T */ - -/* Define to 1 if 'wchar_t' is a signed integer type. */ -/* #undef HAVE_SIGNED_WCHAR_T */ - -/* Define to 1 if 'wint_t' is a signed integer type. */ -/* #undef HAVE_SIGNED_WINT_T */ - -/* Define to 1 if you have the `sleep' function. */ -#define HAVE_SLEEP 1 - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if stdbool.h conforms to C99. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define if exists, doesn't clash with , and declares - uintmax_t. */ -#define HAVE_STDINT_H_WITH_UINTMAX 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STDIO_EXT_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `stpcpy' function. */ -#define HAVE_STPCPY 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the `strchrnul' function. */ -/* #undef HAVE_STRCHRNUL */ - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strncasecmp' function. */ -#define HAVE_STRNCASECMP 1 - -/* Define if you have the strndup() function and it works. */ -/* #undef HAVE_STRNDUP */ - -/* Define to 1 if you have the `strtol' function. */ -#define HAVE_STRTOL 1 - -/* Define to 1 if `st_blksize' is member of `struct stat'. */ -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 - -/* Define to 1 if `st_blocks' is member of `struct stat'. */ -#define HAVE_STRUCT_STAT_ST_BLOCKS 1 - -/* Define to 1 if `tm_zone' is member of `struct tm'. */ -#define HAVE_STRUCT_TM_TM_ZONE 1 - -/* Define if struct utimbuf is declared -- usually in . Some systems - have utime.h but don't declare the struct anywhere. */ -#define HAVE_STRUCT_UTIMBUF 1 - -/* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use - `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */ -#define HAVE_ST_BLKSIZE 1 - -/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use - `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */ -#define HAVE_ST_BLOCKS 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYSEXITS_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_BITYPES_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_BUF_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_DEVICE_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define if your system has sys_errlist global variable */ -#define HAVE_SYS_ERRLIST 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_GENTAPE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_INET_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_INTTYPES_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_IO_TRIOCTL_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_MTIO_H 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TAPE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TIMEB_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TPRINTF_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define if struct tm has the tm_gmtoff member. */ -#define HAVE_TM_GMTOFF 1 - -/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use - `HAVE_STRUCT_TM_TM_ZONE' instead. */ -#define HAVE_TM_ZONE 1 - -/* Define to 1 if you have the `tsearch' function. */ -/* #undef HAVE_TSEARCH */ - -/* Define to 1 if you don't have `tm_zone' but do have the external array - `tzname'. */ -/* #undef HAVE_TZNAME */ - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `unsetenv' function. */ -#define HAVE_UNSETENV 1 - -/* Define to 1 if the system has the type `unsigned long long int'. */ -#define HAVE_UNSIGNED_LONG_LONG_INT 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UTMP_H 1 - -/* Define to 1 if you have the `vasnprintf' function. */ -/* #undef HAVE_VASNPRINTF */ - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WCHAR_H 1 - -/* Define if you have the 'wchar_t' type. */ -#define HAVE_WCHAR_T 1 - -/* Define to 1 if you have the `wcslen' function. */ -#define HAVE_WCSLEN 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WCTYPE_H 1 - -/* Define if you have the 'wint_t' type. */ -#define HAVE_WINT_T 1 - -/* Define to 1 if you have the `wmemchr' function. */ -#define HAVE_WMEMCHR 1 - -/* Define to 1 if you have the `wmemcpy' function. */ -#define HAVE_WMEMCPY 1 - -/* Define to 1 if you have the `wmempcpy' function. */ -/* #undef HAVE_WMEMPCPY */ - -/* Define to 1 if O_NOATIME works. */ -#define HAVE_WORKING_O_NOATIME 0 - -/* Define to 1 if O_NOFOLLOW works. */ -#define HAVE_WORKING_O_NOFOLLOW 1 - -/* Define if utimes works properly. */ -#define HAVE_WORKING_UTIMES 1 - -/* Define to 1 if the system has the type `_Bool'. */ -#define HAVE__BOOL 1 - -/* Define to 1 if you have the `_ftime' function. */ -/* #undef HAVE__FTIME */ - -/* Define to 1 if you have the `__fpending' function. */ -/* #undef HAVE___FPENDING */ - -#if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -#else -# define ISSLASH(C) ((C) == '/') -#endif - -/* Define to 1 if `lstat' dereferences a symlink specified with a trailing - slash. */ -/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */ - -/* Define to 1 if `major', `minor', and `makedev' are declared in . - */ -/* #undef MAJOR_IN_MKDEV */ - -/* Define to 1 if `major', `minor', and `makedev' are declared in - . */ -/* #undef MAJOR_IN_SYSMACROS */ - -/* If malloc(0) is != NULL, define this to 1. Otherwise define this to 0. */ -#define MALLOC_0_IS_NONNULL 1 - -/* Define to mt_model (v.g., for DG/UX), else to mt_type. */ -#define MTIO_CHECK_FIELD mt_type - -/* Name of package */ -#define PACKAGE "cpio" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "bug-cpio@gnu.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "GNU cpio" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "GNU cpio 2.8-FreeBSD" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "cpio" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "2.8-FreeBSD" - -/* the number of pending output bytes on stream `fp' */ -#define PENDING_OUTPUT_N_BYTES fp->_p - fp->_bf._base - -/* Define if exists and defines unusable PRI* macros. */ -/* #undef PRI_MACROS_BROKEN */ - -/* Define to 1 if the C compiler supports function prototypes. */ -#define PROTOTYPES 1 - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'ptrdiff_t'. */ -/* #undef PTRDIFF_T_SUFFIX */ - -/* Define if vasnprintf exists but is overridden by gnulib. */ -/* #undef REPLACE_VASNPRINTF */ - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'sig_atomic_t'. */ -/* #undef SIG_ATOMIC_T_SUFFIX */ - -/* Define as the maximum value of type 'size_t', if the system doesn't define - it. */ -/* #undef SIZE_MAX */ - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'size_t'. */ -/* #undef SIZE_T_SUFFIX */ - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at runtime. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -/* #undef STACK_DIRECTION */ - -/* Define to 1 if the `S_IS*' macros in do not work properly. */ -/* #undef STAT_MACROS_BROKEN */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if strerror_r returns char *. */ -/* #undef STRERROR_R_CHAR_P */ - -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Define to 1 if your declares `struct tm'. */ -/* #undef TM_IN_SYS_TIME */ - -/* Define to 1 if you want getc etc. to use unlocked I/O if available. - Unlocked I/O can improve performance in unithreaded apps, but it is not - safe for multithreaded apps. */ -#define USE_UNLOCKED_IO 1 - -/* Version number of package */ -#define VERSION "2.8-FreeBSD" - -/* Define if unsetenv() returns void, not int. */ -/* #undef VOID_UNSETENV */ - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'wchar_t'. */ -/* #undef WCHAR_T_SUFFIX */ - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'wint_t'. */ -/* #undef WINT_T_SUFFIX */ - -/* Define to 1 if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* # undef _ALL_SOURCE */ -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Enable extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif - -/* Define to rpl_ if the getopt replacement functions and variables should be - used. */ -#define __GETOPT_PREFIX rpl_ - -/* Define to rpl_ if the openat replacement function should be used. */ -#define __OPENAT_PREFIX rpl_ - -/* Define like PROTOTYPES; this can be used by system headers. */ -#define __PROTOTYPES 1 - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to rpl_fchownat if the replacement function should be used. */ -#define fchownat rpl_fchownat - -/* Define to a replacement function name for fnmatch(). */ -/* #define fnmatch gnu_fnmatch */ - -/* Define to `int' if does not define. */ -/* #undef gid_t */ - -/* A replacement for va_copy, if needed. */ -#define gl_va_copy(a,b) ((a) = (b)) - -/* Define to rpl_gmtime if the replacement function should be used. */ -/* #undef gmtime */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to long or long long if and don't define. */ -/* #undef intmax_t */ - -/* Define to rpl_localtime if the replacement function should be used. */ -/* #undef localtime */ - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define to a type if does not define. */ -/* #undef mbstate_t */ - -/* Define to rpl_mktime if the replacement function should be used. */ -#define mktime rpl_mktime - -/* Define to `long int' if does not define. */ -/* #undef off_t */ - -/* Define to a replacement function name for realpath(). */ -#define realpath rpl_realpath - -/* Define to equivalent of C99 restrict keyword, or to nothing if this is not - supported. Do not define if restrict is supported directly. */ -/* #undef restrict */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define as a signed type of the same size as size_t. */ -/* #undef ssize_t */ - -/* Define to rpl_strnlen if the replacement function should be used. */ -#define strnlen rpl_strnlen - -/* Define to `int' if doesn't define. */ -/* #undef uid_t */ - -/* Define as a macro for copying va_list variables. */ -/* #undef va_copy */ diff --git a/gnu/usr.bin/cpio/doc/Makefile b/gnu/usr.bin/cpio/doc/Makefile deleted file mode 100644 index 220de5fdf82..00000000000 --- a/gnu/usr.bin/cpio/doc/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# Note that this files is under a "BSD" copyright (c) by David O'Brien 1997, -# even though it may live in src/gnu/... - -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../../../contrib/cpio/doc - -INFO = cpio - -INFOSECTION= "Cpio Documentation" -INFOENTRY_cpio="* CPIO: (cpio). Making tape (or disk) archives." - -SRCDIR= ${.CURDIR}/../../../../contrib/cpio/doc - -.include diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 8c53f160765..2d06d44f75f 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,7 +1,7 @@ .\" DO NOT EDIT-- this file is automatically generated. .\" from FreeBSD: stable/8/tools/build/options/makeman 188848 2009-02-20 11:09:55Z mtm .\" $FreeBSD$ -.Dd January 30, 2010 +.Dd March 29, 2010 .Dt SRC.CONF 5 .Os .Sh NAME @@ -339,13 +339,6 @@ When set, it also enforces the following options: .It .Va WITHOUT_GNU_SUPPORT .El -.It Va WITH_GNU_CPIO -.\" from FreeBSD: stable/8/tools/build/options/WITH_GNU_CPIO 179813 2008-06-16 05:48:15Z dougb -Set to build GNU cpio as a part of the base system, -and symlink -.Pa /usr/bin/cpio -to this version. -(This will override the symlink to the BSD version.) .It Va WITHOUT_GNU_GREP .\" from FreeBSD: stable/8/tools/build/options/WITHOUT_GNU_GREP 179813 2008-06-16 05:48:15Z dougb Set to not build GNU grep as a part of the base system. diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index 84ae433b16b..777ff3634a7 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -407,7 +407,6 @@ MK_${var}:= yes BIND_LIBS \ BIND_SIGCHASE \ BIND_XML \ - GNU_CPIO \ HESIOD \ IDEA .if defined(WITH_${var}) && defined(WITHOUT_${var}) diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index e8c1f1f11bb..2ac84a74d12 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -394,12 +394,6 @@ OLD_FILES+=usr/share/man/man1/gcov.1.gz # to be filled in #.endif -.if ${MK_GNU_CPIO} == no -OLD_FILES+=usr/bin/gcpio -OLD_FILES+=usr/share/info/cpio.info.gz -OLD_FILES+=usr/share/man/man1/gcpio.1.gz -.endif - #.if ${MK_GPIB} == no # none #.endif diff --git a/tools/build/options/WITH_GNU_CPIO b/tools/build/options/WITH_GNU_CPIO deleted file mode 100644 index b4e756ae18b..00000000000 --- a/tools/build/options/WITH_GNU_CPIO +++ /dev/null @@ -1,6 +0,0 @@ -.\" $FreeBSD$ -Set to build GNU cpio as a part of the base system, -and symlink -.Pa /usr/bin/cpio -to this version. -(This will override the symlink to the BSD version.) diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile index c64ab6c6a04..f2fe632f3d3 100644 --- a/usr.bin/cpio/Makefile +++ b/usr.bin/cpio/Makefile @@ -19,10 +19,8 @@ LDADD+= -larchive -lz -lbz2 -lmd LDADD+= -lcrypto .endif -.if ${MK_GNU_CPIO} != "yes" SYMLINKS=bsdcpio ${BINDIR}/cpio MLINKS= bsdcpio.1 cpio.1 -.endif .PHONY: check test From 608413892c9a045e72a54df200e4d2942f7d7fb7 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 29 Mar 2010 22:52:51 +0000 Subject: [PATCH 1749/2592] MFC r204383: Add several necessary .El's --- share/man/man9/BUF_ISLOCKED.9 | 1 + share/man/man9/BUF_RECURSED.9 | 1 + share/man/man9/DEVICE_PROBE.9 | 1 + share/man/man9/VOP_LOCK.9 | 1 + share/man/man9/devfs_set_cdevpriv.9 | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/share/man/man9/BUF_ISLOCKED.9 b/share/man/man9/BUF_ISLOCKED.9 index 7344869f6db..d55f2f5d005 100644 --- a/share/man/man9/BUF_ISLOCKED.9 +++ b/share/man/man9/BUF_ISLOCKED.9 @@ -57,6 +57,7 @@ An exclusive lock is held by someone other than curthread A shared lock is held. .It Li 0 The lock is not held by anyone. +.El .Sh SEE ALSO .Xr lockstatus 9 , .Xr buf 9 , diff --git a/share/man/man9/BUF_RECURSED.9 b/share/man/man9/BUF_RECURSED.9 index dfe818f1c4a..2e369ea69e0 100644 --- a/share/man/man9/BUF_RECURSED.9 +++ b/share/man/man9/BUF_RECURSED.9 @@ -54,6 +54,7 @@ The buffer linked to the lock. See .Xr lockmgr_recursed 9 for details. +.El .Sh SEE ALSO .Xr buf 9 , .Xr BUF_LOCK 9 , diff --git a/share/man/man9/DEVICE_PROBE.9 b/share/man/man9/DEVICE_PROBE.9 index b159fd22206..7b400e7fd60 100644 --- a/share/man/man9/DEVICE_PROBE.9 +++ b/share/man/man9/DEVICE_PROBE.9 @@ -127,6 +127,7 @@ The driver expects its parent to tell it which children to manage and no probing is really done. The device only matches if its parent bus specifically said to use this driver. +.El .Sh SEE ALSO .Xr device 9 , .Xr DEVICE_ATTACH 9 , diff --git a/share/man/man9/VOP_LOCK.9 b/share/man/man9/VOP_LOCK.9 index cdf1714fed5..6c54a38df5b 100644 --- a/share/man/man9/VOP_LOCK.9 +++ b/share/man/man9/VOP_LOCK.9 @@ -114,6 +114,7 @@ directly. .Fn vn_lock also does not want a thread specified as argument but it assumes curthread to be used. +.El .Sh RETURN VALUES Zero is returned on success, otherwise an error is returned. .Sh SEE ALSO diff --git a/share/man/man9/devfs_set_cdevpriv.9 b/share/man/man9/devfs_set_cdevpriv.9 index 934e4947f75..0896d4de081 100644 --- a/share/man/man9/devfs_set_cdevpriv.9 +++ b/share/man/man9/devfs_set_cdevpriv.9 @@ -108,7 +108,7 @@ The private driver data was not associated with current filedescriptor, or .Fn devfs_clear_cdevpriv was called. -.Pp +.El .Sh SEE ALSO .Xr open 2 , .Xr close 2 , From acde5c5d1d2a803eda14c4d5afa83b5055099923 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Tue, 30 Mar 2010 11:19:29 +0000 Subject: [PATCH 1750/2592] MFC r204641, r204753: Improving the clocks auto-tunning by firstly checking if the atrtc may be correctly initialized and just then assign to softclock/profclock. Sponsored by: Sandvine Incorporated --- sys/amd64/amd64/local_apic.c | 28 +++++++++++++++------------- sys/amd64/include/apicvar.h | 2 +- sys/amd64/isa/clock.c | 24 +++++++++++++++++++----- sys/i386/i386/local_apic.c | 36 +++++++++++++++--------------------- sys/i386/include/apicvar.h | 2 +- sys/i386/isa/clock.c | 27 +++++++++++++++++++++------ sys/pc98/cbus/clock.c | 9 +++++++-- 7 files changed, 79 insertions(+), 49 deletions(-) diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c index 0d04bbd4a69..c27463182a7 100644 --- a/sys/amd64/amd64/local_apic.c +++ b/sys/amd64/amd64/local_apic.c @@ -149,6 +149,7 @@ extern inthand_t IDTVEC(rsvd); volatile lapic_t *lapic; vm_paddr_t lapic_paddr; static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz; +static enum lapic_clock clockcoverage; static void lapic_enable(void); static void lapic_resume(struct pic *pic); @@ -160,9 +161,6 @@ static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value); struct pic lapic_pic = { .pic_resume = lapic_resume }; -static int lapic_allclocks; -TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks); - static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value) { @@ -423,17 +421,20 @@ lapic_disable_pmc(void) * local APIC only for the hardclock and 0 if none of them can be handled. */ enum lapic_clock -lapic_setup_clock(void) +lapic_setup_clock(enum lapic_clock srcsdes) { u_long value; int i; - /* Can't drive the timer without a local APIC. */ - if (lapic == NULL) - return (LAPIC_CLOCK_NONE); + /* lapic_setup_clock() should not be called with LAPIC_CLOCK_NONE. */ + MPASS(srcsdes != LAPIC_CLOCK_NONE); - if (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0) - return (LAPIC_CLOCK_NONE); + /* Can't drive the timer without a local APIC. */ + if (lapic == NULL || + (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)) { + clockcoverage = LAPIC_CLOCK_NONE; + return (clockcoverage); + } /* Start off with a divisor of 2 (power on reset default). */ lapic_timer_divisor = 2; @@ -469,7 +470,7 @@ lapic_setup_clock(void) * Please note that stathz and profhz are set only if all the * clocks are handled through the local APIC. */ - if (lapic_allclocks != 0) { + if (srcsdes == LAPIC_CLOCK_ALL) { if (hz >= 1500) lapic_timer_hz = hz; else if (hz >= 750) @@ -479,7 +480,7 @@ lapic_setup_clock(void) } else lapic_timer_hz = hz; lapic_timer_period = value / lapic_timer_hz; - if (lapic_allclocks != 0) { + if (srcsdes == LAPIC_CLOCK_ALL) { if (lapic_timer_hz < 128) stathz = lapic_timer_hz; else @@ -493,7 +494,8 @@ lapic_setup_clock(void) */ lapic_timer_periodic(lapic_timer_period); lapic_timer_enable_intr(); - return (lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL); + clockcoverage = srcsdes; + return (srcsdes); } void @@ -796,7 +798,7 @@ lapic_handle_timer(struct trapframe *frame) else hardclock_cpu(TRAPF_USERMODE(frame)); } - if (lapic_allclocks != 0) { + if (clockcoverage == LAPIC_CLOCK_ALL) { /* Fire statclock at stathz. */ la->la_stat_ticks += stathz; diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h index 8f15d84a1ac..110ce814317 100644 --- a/sys/amd64/include/apicvar.h +++ b/sys/amd64/include/apicvar.h @@ -230,7 +230,7 @@ int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger); void lapic_set_tpr(u_int vector); void lapic_setup(int boot); -enum lapic_clock lapic_setup_clock(void); +enum lapic_clock lapic_setup_clock(enum lapic_clock srcsdes); #endif /* !LOCORE */ #endif /* _MACHINE_APICVAR_H_ */ diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index bf379f3287e..e5c27d1bbaf 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -84,6 +84,9 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq); int i8254_max_count; static int i8254_real_max_count; +static int lapic_allclocks; +TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks); + struct mtx clock_lock; static struct intsrc *i8254_intsrc; static u_int32_t i8254_lastcount; @@ -478,8 +481,22 @@ startrtclock() void cpu_initclocks() { + enum lapic_clock tlsca; + int tasc; + + /* Initialize RTC. */ + atrtc_start(); + tasc = atrtc_setup_clock(); + + /* + * If the atrtc successfully initialized and the users didn't force + * otherwise use the LAPIC in order to cater hardclock only, otherwise + * take in charge all the clock sources. + */ + tlsca = (lapic_allclocks == 0 && tasc != 0) ? LAPIC_CLOCK_HARDCLOCK : + LAPIC_CLOCK_ALL; + using_lapic_timer = lapic_setup_clock(tlsca); - using_lapic_timer = lapic_setup_clock(); /* * If we aren't using the local APIC timer to drive the kernel * clocks, setup the interrupt handler for the 8254 timer 0 so @@ -500,9 +517,6 @@ cpu_initclocks() set_i8254_freq(i8254_freq, hz); } - /* Initialize RTC. */ - atrtc_start(); - /* * If the separate statistics clock hasn't been explicility disabled * and we aren't already using the local APIC timer to drive the @@ -510,7 +524,7 @@ cpu_initclocks() * drive statclock() and profclock(). */ if (using_lapic_timer != LAPIC_CLOCK_ALL) { - using_atrtc_timer = atrtc_setup_clock(); + using_atrtc_timer = tasc; if (using_atrtc_timer) { /* Enable periodic interrupts from the RTC. */ intr_add_handler("rtc", 8, diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c index e0049c8cf5b..6c6220022b9 100644 --- a/sys/i386/i386/local_apic.c +++ b/sys/i386/i386/local_apic.c @@ -150,6 +150,7 @@ extern inthand_t IDTVEC(rsvd); volatile lapic_t *lapic; vm_paddr_t lapic_paddr; static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz; +static enum lapic_clock clockcoverage; static void lapic_enable(void); static void lapic_resume(struct pic *pic); @@ -161,17 +162,6 @@ static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value); struct pic lapic_pic = { .pic_resume = lapic_resume }; -/* - * The atrtc device is compiled in only if atpic is present. - * If it is not, force lapic to take care of all the clocks. - */ -#ifdef DEV_ATPIC -static int lapic_allclocks; -TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks); -#else -static int lapic_allclocks = 1; -#endif - static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value) { @@ -431,17 +421,20 @@ lapic_disable_pmc(void) * that it can drive hardclock, statclock, and profclock. */ enum lapic_clock -lapic_setup_clock(void) +lapic_setup_clock(enum lapic_clock srcsdes) { u_long value; int i; - /* Can't drive the timer without a local APIC. */ - if (lapic == NULL) - return (LAPIC_CLOCK_NONE); + /* lapic_setup_clock() should not be called with LAPIC_CLOCK_NONE. */ + MPASS(srcsdes != LAPIC_CLOCK_NONE); - if (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0) - return (LAPIC_CLOCK_NONE); + /* Can't drive the timer without a local APIC. */ + if (lapic == NULL || + (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)) { + clockcoverage = LAPIC_CLOCK_NONE; + return (clockcoverage); + } /* Start off with a divisor of 2 (power on reset default). */ lapic_timer_divisor = 2; @@ -477,7 +470,7 @@ lapic_setup_clock(void) * Please note that stathz and profhz are set only if all the * clocks are handled through the local APIC. */ - if (lapic_allclocks != 0) { + if (srcsdes == LAPIC_CLOCK_ALL) { if (hz >= 1500) lapic_timer_hz = hz; else if (hz >= 750) @@ -487,7 +480,7 @@ lapic_setup_clock(void) } else lapic_timer_hz = hz; lapic_timer_period = value / lapic_timer_hz; - if (lapic_allclocks != 0) { + if (srcsdes == LAPIC_CLOCK_ALL) { if (lapic_timer_hz < 128) stathz = lapic_timer_hz; else @@ -501,7 +494,8 @@ lapic_setup_clock(void) */ lapic_timer_periodic(lapic_timer_period); lapic_timer_enable_intr(); - return (lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL); + clockcoverage = srcsdes; + return (srcsdes); } void @@ -804,7 +798,7 @@ lapic_handle_timer(struct trapframe *frame) else hardclock_cpu(TRAPF_USERMODE(frame)); } - if (lapic_allclocks != 0) { + if (clockcoverage == LAPIC_CLOCK_ALL) { /* Fire statclock at stathz. */ la->la_stat_ticks += stathz; diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h index 2f8e716089d..208ffb53302 100644 --- a/sys/i386/include/apicvar.h +++ b/sys/i386/include/apicvar.h @@ -259,7 +259,7 @@ int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger); void lapic_set_tpr(u_int vector); void lapic_setup(int boot); -enum lapic_clock lapic_setup_clock(void); +enum lapic_clock lapic_setup_clock(enum lapic_clock srcsdes); #endif /* !LOCORE */ #endif /* _MACHINE_APICVAR_H_ */ diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index e999b5619dd..04f74418504 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -97,6 +97,9 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq); int i8254_max_count; static int i8254_real_max_count; +static int lapic_allclocks; +TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks); + struct mtx clock_lock; static struct intsrc *i8254_intsrc; static u_int32_t i8254_lastcount; @@ -522,9 +525,24 @@ startrtclock() void cpu_initclocks() { - #ifdef DEV_APIC - using_lapic_timer = lapic_setup_clock(); + enum lapic_clock tlsca; +#endif + int tasc; + + /* Initialize RTC. */ + atrtc_start(); + tasc = atrtc_setup_clock(); + + /* + * If the atrtc successfully initialized and the users didn't force + * otherwise use the LAPIC in order to cater hardclock only, otherwise + * take in charge all the clock sources. + */ +#ifdef DEV_APIC + tlsca = (lapic_allclocks == 0 && tasc != 0) ? LAPIC_CLOCK_HARDCLOCK : + LAPIC_CLOCK_ALL; + using_lapic_timer = lapic_setup_clock(tlsca); #endif /* * If we aren't using the local APIC timer to drive the kernel @@ -546,9 +564,6 @@ cpu_initclocks() set_i8254_freq(i8254_freq, hz); } - /* Initialize RTC. */ - atrtc_start(); - /* * If the separate statistics clock hasn't been explicility disabled * and we aren't already using the local APIC timer to drive the @@ -556,7 +571,7 @@ cpu_initclocks() * drive statclock() and profclock(). */ if (using_lapic_timer != LAPIC_CLOCK_ALL) { - using_atrtc_timer = atrtc_setup_clock(); + using_atrtc_timer = tasc; if (using_atrtc_timer) { /* Enable periodic interrupts from the RTC. */ intr_add_handler("rtc", 8, diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c index 10b25986813..22ed8a5f5c9 100644 --- a/sys/pc98/cbus/clock.c +++ b/sys/pc98/cbus/clock.c @@ -93,6 +93,9 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq); int i8254_max_count; static int i8254_real_max_count; +static int lapic_allclocks; +TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks); + static struct mtx clock_lock; static struct intsrc *i8254_intsrc; static u_int32_t i8254_lastcount; @@ -432,9 +435,11 @@ startrtclock() void cpu_initclocks() { +#if defined(DEV_APIC) + enum lapic_clock tlsca; -#ifdef DEV_APIC - using_lapic_timer = lapic_setup_clock(); + tlsca = lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL; + using_lapic_timer = lapic_setup_clock(tlsca); #endif /* * If we aren't using the local APIC timer to drive the kernel From 58c7715bb08c7fbb60cbfc5b4ba8c0f350c21ff7 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Tue, 30 Mar 2010 11:46:43 +0000 Subject: [PATCH 1751/2592] MFC r205160: Checkin a facility for specifying a passthrough FIB from userland. arcconf tool by Adaptec already seems to use for identifying the Serial Number of the devices. Sponsored by: Sandvine Incorporated --- sys/dev/aac/aac.c | 142 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 1 deletion(-) diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 3d9ae7223d0..903ae75c022 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -3063,7 +3063,147 @@ out: static int aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg) { - return (EINVAL); + struct aac_command *cm; + struct aac_event *event; + struct aac_fib *fib; + struct aac_srb *srbcmd, *user_srb; + struct aac_sg_entry *sge; + struct aac_sg_entry64 *sge64; + void *srb_sg_address, *ureply; + uint32_t fibsize, srb_sg_bytecount; + int error, transfer_data; + + fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); + + cm = NULL; + transfer_data = 0; + fibsize = 0; + user_srb = (struct aac_srb *)arg; + + mtx_lock(&sc->aac_io_lock); + if (aac_alloc_command(sc, &cm)) { + event = malloc(sizeof(struct aac_event), M_AACBUF, + M_NOWAIT | M_ZERO); + if (event == NULL) { + error = EBUSY; + mtx_unlock(&sc->aac_io_lock); + goto out; + } + event->ev_type = AAC_EVENT_CMFREE; + event->ev_callback = aac_ioctl_event; + event->ev_arg = &cm; + aac_add_event(sc, event); + msleep(cm, &sc->aac_io_lock, 0, "aacraw", 0); + } + mtx_unlock(&sc->aac_io_lock); + + cm->cm_data = NULL; + fib = cm->cm_fib; + srbcmd = (struct aac_srb *)fib->data; + error = copyin(&user_srb->data_len, &fibsize, sizeof(uint32_t)); + if (error != 0) + goto out; + if (fibsize > (sc->aac_max_fib_size - sizeof(struct aac_fib_header))) { + error = EINVAL; + goto out; + } + error = copyin(user_srb, srbcmd, fibsize); + if (error != 0) + goto out; + srbcmd->function = 0; + srbcmd->retry_limit = 0; + if (srbcmd->sg_map.SgCount > 1) { + error = EINVAL; + goto out; + } + + /* Retrieve correct SG entries. */ + if (fibsize == (sizeof(struct aac_srb) + + srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) { + sge = srbcmd->sg_map.SgEntry; + sge64 = NULL; + srb_sg_bytecount = sge->SgByteCount; +#ifdef __amd64__ + srb_sg_address = (void *)(uint64_t)sge->SgAddress; +#else + srb_sg_address = (void *)sge->SgAddress; +#endif + } +#ifdef __amd64__ + else if (fibsize == (sizeof(struct aac_srb) + + srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) { + sge = NULL; + sge64 = (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry; + srb_sg_bytecount = sge64->SgByteCount; + srb_sg_address = (void *)sge64->SgAddress; + if (sge64->SgAddress > 0xffffffffull && + (sc->flags & AAC_FLAGS_SG_64BIT) == 0) { + error = EINVAL; + goto out; + } + } +#endif + else { + error = EINVAL; + goto out; + } + ureply = (char *)arg + fibsize; + srbcmd->data_len = srb_sg_bytecount; + if (srbcmd->sg_map.SgCount == 1) + transfer_data = 1; + + cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map; + if (transfer_data) { + cm->cm_datalen = srb_sg_bytecount; + cm->cm_data = malloc(cm->cm_datalen, M_AACBUF, M_NOWAIT); + if (cm->cm_data == NULL) { + error = ENOMEM; + goto out; + } + if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) + cm->cm_flags |= AAC_CMD_DATAIN; + if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) { + cm->cm_flags |= AAC_CMD_DATAOUT; + error = copyin(srb_sg_address, cm->cm_data, + cm->cm_datalen); + if (error != 0) + goto out; + } + } + + fib->Header.Size = sizeof(struct aac_fib_header) + + sizeof(struct aac_srb); + fib->Header.XferState = + AAC_FIBSTATE_HOSTOWNED | + AAC_FIBSTATE_INITIALISED | + AAC_FIBSTATE_EMPTY | + AAC_FIBSTATE_FROMHOST | + AAC_FIBSTATE_REXPECTED | + AAC_FIBSTATE_NORM | + AAC_FIBSTATE_ASYNC | + AAC_FIBSTATE_FAST_RESPONSE; + fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) != 0 ? + ScsiPortCommandU64 : ScsiPortCommand; + + mtx_lock(&sc->aac_io_lock); + aac_wait_command(cm); + mtx_unlock(&sc->aac_io_lock); + + if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) != 0) { + error = copyout(cm->cm_data, srb_sg_address, cm->cm_datalen); + if (error != 0) + goto out; + } + error = copyout(fib->data, ureply, sizeof(struct aac_srb_response)); +out: + if (cm != NULL) { + if (cm->cm_data != NULL) + free(cm->cm_data, M_AACBUF); + mtx_lock(&sc->aac_io_lock); + aac_release_command(cm); + mtx_unlock(&sc->aac_io_lock); + } + return(error); } /* From 6f1f54906a450bb866476cb3936a148858cdc620 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Tue, 30 Mar 2010 12:06:18 +0000 Subject: [PATCH 1752/2592] MFC r205167: Make the code more readable and compiling on 64-bits arch different than amd64. Sponsored by: Sandvine Incorporated --- sys/dev/aac/aac.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 903ae75c022..50507be83bc 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -3123,11 +3123,7 @@ aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg) sge = srbcmd->sg_map.SgEntry; sge64 = NULL; srb_sg_bytecount = sge->SgByteCount; -#ifdef __amd64__ - srb_sg_address = (void *)(uint64_t)sge->SgAddress; -#else - srb_sg_address = (void *)sge->SgAddress; -#endif + srb_sg_address = (void *)(uintptr_t)sge->SgAddress; } #ifdef __amd64__ else if (fibsize == (sizeof(struct aac_srb) + From c3342f65363c4301adb9da1880a6749b35565058 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 18:58:07 +0000 Subject: [PATCH 1753/2592] MFC: r205393 - Remove a bogus forward declaration. - Fix whitespace. --- lib/libc/sparc64/fpu/fpu_extern.h | 7 +++---- lib/libc/sparc64/fpu/fpu_implode.c | 3 --- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/libc/sparc64/fpu/fpu_extern.h b/lib/libc/sparc64/fpu/fpu_extern.h index f22c46300a5..0de30fcfedb 100644 --- a/lib/libc/sparc64/fpu/fpu_extern.h +++ b/lib/libc/sparc64/fpu/fpu_extern.h @@ -41,7 +41,6 @@ #define _SPARC64_FPU_FPU_EXTERN_H_ struct utrapframe; -union instr; struct fpemu; struct fpn; @@ -61,9 +60,9 @@ struct fpn *__fpu_div(struct fpemu *); int __fpu_itof(struct fpn *, u_int); int __fpu_xtof(struct fpn *, u_int64_t); int __fpu_stof(struct fpn *, u_int); -int __fpu_dtof(struct fpn *, u_int, u_int ); -int __fpu_qtof(struct fpn *, u_int, u_int , u_int , u_int ); -void __fpu_explode(struct fpemu *, struct fpn *, int, int ); +int __fpu_dtof(struct fpn *, u_int, u_int); +int __fpu_qtof(struct fpn *, u_int, u_int, u_int, u_int); +void __fpu_explode(struct fpemu *, struct fpn *, int, int); /* fpu_implode.c */ u_int __fpu_ftoi(struct fpemu *, struct fpn *); diff --git a/lib/libc/sparc64/fpu/fpu_implode.c b/lib/libc/sparc64/fpu/fpu_implode.c index 5287d2ba23c..32a0e7ccb90 100644 --- a/lib/libc/sparc64/fpu/fpu_implode.c +++ b/lib/libc/sparc64/fpu/fpu_implode.c @@ -198,7 +198,6 @@ __fpu_ftoi(fe, fp) sign = fp->fp_sign; switch (fp->fp_class) { - case FPC_ZERO: return (0); @@ -248,7 +247,6 @@ __fpu_ftox(fe, fp, res) sign = fp->fp_sign; switch (fp->fp_class) { - case FPC_ZERO: res[1] = 0; return (0); @@ -504,7 +502,6 @@ __fpu_implode(fe, fp, type, space) { switch (type) { - case FTYPE_LNG: space[0] = __fpu_ftox(fe, fp, space); break; From 3f6c7d0307fe898632522c28102f9646bae24485 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 19:03:26 +0000 Subject: [PATCH 1754/2592] MFC: r205394 Ensure that __fpu_ftox() both returns the high bits and res[1] contains the low bits also in the default case. PR: 144900 Obtained from: OpenBSD --- lib/libc/sparc64/fpu/fpu_implode.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/libc/sparc64/fpu/fpu_implode.c b/lib/libc/sparc64/fpu/fpu_implode.c index 32a0e7ccb90..91e40c1c567 100644 --- a/lib/libc/sparc64/fpu/fpu_implode.c +++ b/lib/libc/sparc64/fpu/fpu_implode.c @@ -248,8 +248,8 @@ __fpu_ftox(fe, fp, res) sign = fp->fp_sign; switch (fp->fp_class) { case FPC_ZERO: - res[1] = 0; - return (0); + i = 0; + goto done; case FPC_NUM: /* @@ -273,15 +273,17 @@ __fpu_ftox(fe, fp, res) break; if (sign) i = -i; - res[1] = (int)i; - return (i >> 32); + goto done; default: /* Inf, qNaN, sNaN */ break; } /* overflow: replace any inexact exception with invalid */ fe->fe_cx = (fe->fe_cx & ~FSR_NX) | FSR_NV; - return (0x7fffffffffffffffLL + sign); + i = 0x7fffffffffffffffLL + sign; +done: + res[1] = i & 0xffffffff; + return (i >> 32); } /* From 35cbfc2ca060c44e84f1da025feec2f011d5f371 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 19:05:08 +0000 Subject: [PATCH 1755/2592] MFC: r205395 FPU_DEBUG requires . PR: 144900 Submitted by: Peter Jeremy --- lib/libc/sparc64/fpu/fpu.c | 5 ++++- lib/libc/sparc64/fpu/fpu_explode.c | 4 ++++ lib/libc/sparc64/fpu/fpu_implode.c | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/libc/sparc64/fpu/fpu.c b/lib/libc/sparc64/fpu/fpu.c index 7c8a3a96739..4e92788114d 100644 --- a/lib/libc/sparc64/fpu/fpu.c +++ b/lib/libc/sparc64/fpu/fpu.c @@ -69,9 +69,12 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include -#include #include +#ifdef FPU_DEBUG +#include +#endif #include +#include #include "un-namespace.h" #include "libc_private.h" diff --git a/lib/libc/sparc64/fpu/fpu_explode.c b/lib/libc/sparc64/fpu/fpu_explode.c index 09cfd5a59bb..12c8802f435 100644 --- a/lib/libc/sparc64/fpu/fpu_explode.c +++ b/lib/libc/sparc64/fpu/fpu_explode.c @@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$"); #include +#ifdef FPU_DEBUG +#include +#endif + #include #include #include diff --git a/lib/libc/sparc64/fpu/fpu_implode.c b/lib/libc/sparc64/fpu/fpu_implode.c index 91e40c1c567..82a8460b5dd 100644 --- a/lib/libc/sparc64/fpu/fpu_implode.c +++ b/lib/libc/sparc64/fpu/fpu_implode.c @@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$"); #include +#ifdef FPU_DEBUG +#include +#endif + #include #include #include From fa38e6334c5f1ee48f441e01d63118139044ee63 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 19:06:31 +0000 Subject: [PATCH 1756/2592] MFC: r205396 Division should take both arguments' signs into account when the the dividend is infinity or zero and the divisor is not the same. PR: 144900 Submitted by: Peter Jeremy --- lib/libc/sparc64/fpu/fpu_div.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/libc/sparc64/fpu/fpu_div.c b/lib/libc/sparc64/fpu/fpu_div.c index c4b8ef6121f..4748daf40bc 100644 --- a/lib/libc/sparc64/fpu/fpu_div.c +++ b/lib/libc/sparc64/fpu/fpu_div.c @@ -167,14 +167,16 @@ __fpu_div(fe) * return it. Otherwise we have the following cases: * * Inf / Inf = NaN, plus NV exception - * Inf / num = Inf [i.e., return x] - * Inf / 0 = Inf [i.e., return x] - * 0 / Inf = 0 [i.e., return x] - * 0 / num = 0 [i.e., return x] + * Inf / num = Inf [i.e., return x #] + * Inf / 0 = Inf [i.e., return x #] + * 0 / Inf = 0 [i.e., return x #] + * 0 / num = 0 [i.e., return x #] * 0 / 0 = NaN, plus NV exception - * num / Inf = 0 + * num / Inf = 0 # * num / num = num (do the divide) - * num / 0 = Inf, plus DZ exception + * num / 0 = Inf #, plus DZ exception + * + * # Sign of result is XOR of operand signs. */ if (ISNAN(x) || ISNAN(y)) { ORDER(x, y); @@ -183,10 +185,10 @@ __fpu_div(fe) if (ISINF(x) || ISZERO(x)) { if (x->fp_class == y->fp_class) return (__fpu_newnan(fe)); + x->fp_sign ^= y->fp_sign; return (x); } - /* all results at this point use XOR of operand signs */ x->fp_sign ^= y->fp_sign; if (ISINF(y)) { x->fp_class = FPC_ZERO; From 1185606b8c35df451f295e7756f29d3c9cb718b5 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 19:08:02 +0000 Subject: [PATCH 1757/2592] MFC: r205397 - While SPARC V9 allows tininess to be detected either before or after rounding (impl. dep. #55), the SPARC JPS1 responsible for SPARC64 and UltraSPARC processors defines that in all cases tinyness is detected before rounding, therefore rounding up to the smallest normalised number should set the underflow flag. - If an infinite result is rounded down, the result should have an exponent 1 less than the value for infinity. PR: 144900 Submitted by: Peter Jeremy --- lib/libc/sparc64/fpu/fpu_implode.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/libc/sparc64/fpu/fpu_implode.c b/lib/libc/sparc64/fpu/fpu_implode.c index 82a8460b5dd..2a2a9d0be74 100644 --- a/lib/libc/sparc64/fpu/fpu_implode.c +++ b/lib/libc/sparc64/fpu/fpu_implode.c @@ -329,8 +329,9 @@ __fpu_ftos(fe, fp) * right to introduce leading zeroes. Rounding then acts * differently for normals and subnormals: the largest subnormal * may round to the smallest normal (1.0 x 2^minexp), or may - * remain subnormal. In the latter case, signal an underflow - * if the result was inexact or if underflow traps are enabled. + * remain subnormal. A number that is subnormal before rounding + * will signal an underflow if the result is inexact or if underflow + * traps are enabled. * * Rounding a normal, on the other hand, always produces another * normal (although either way the result might be too big for @@ -345,8 +346,10 @@ __fpu_ftos(fe, fp) if ((exp = fp->fp_exp + SNG_EXP_BIAS) <= 0) { /* subnormal */ /* -NG for g,r; -SNG_FRACBITS-exp for fraction */ (void) __fpu_shr(fp, FP_NMANT - FP_NG - SNG_FRACBITS - exp); - if (fpround(fe, fp) && fp->fp_mant[3] == SNG_EXP(1)) + if (fpround(fe, fp) && fp->fp_mant[3] == SNG_EXP(1)) { + fe->fe_cx |= FSR_UF; return (sign | SNG_EXP(1) | 0); + } if ((fe->fe_cx & FSR_NX) || (fe->fe_fsr & (FSR_UF << FSR_TEM_SHIFT))) fe->fe_cx |= FSR_UF; @@ -407,6 +410,7 @@ zero: res[1] = 0; if ((exp = fp->fp_exp + DBL_EXP_BIAS) <= 0) { (void) __fpu_shr(fp, FP_NMANT - FP_NG - DBL_FRACBITS - exp); if (fpround(fe, fp) && fp->fp_mant[2] == DBL_EXP(1)) { + fe->fe_cx |= FSR_UF; res[1] = 0; return (sign | DBL_EXP(1) | 0); } @@ -426,7 +430,7 @@ zero: res[1] = 0; return (sign | DBL_EXP(DBL_EXP_INFNAN) | 0); } res[1] = ~0; - return (sign | DBL_EXP(DBL_EXP_INFNAN) | DBL_MASK); + return (sign | DBL_EXP(DBL_EXP_INFNAN - 1) | DBL_MASK); } done: res[1] = fp->fp_mant[3]; @@ -468,6 +472,7 @@ zero: res[1] = res[2] = res[3] = 0; if ((exp = fp->fp_exp + EXT_EXP_BIAS) <= 0) { (void) __fpu_shr(fp, FP_NMANT - FP_NG - EXT_FRACBITS - exp); if (fpround(fe, fp) && fp->fp_mant[0] == EXT_EXP(1)) { + fe->fe_cx |= FSR_UF; res[1] = res[2] = res[3] = 0; return (sign | EXT_EXP(1) | 0); } @@ -487,7 +492,7 @@ zero: res[1] = res[2] = res[3] = 0; return (sign | EXT_EXP(EXT_EXP_INFNAN) | 0); } res[1] = res[2] = res[3] = ~0; - return (sign | EXT_EXP(EXT_EXP_INFNAN) | EXT_MASK); + return (sign | EXT_EXP(EXT_EXP_INFNAN - 1) | EXT_MASK); } done: res[1] = fp->fp_mant[1]; From aa1750167b909f58934197ee8551994bb440a44c Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 19:13:37 +0000 Subject: [PATCH 1758/2592] MFC: r205410 Avoid aliasing which leads to incorrect results when compiling with the default strict aliasing rules. PR: 144900 Submitted by: Peter Jeremy --- lib/libc/sparc64/fpu/fpu_explode.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/libc/sparc64/fpu/fpu_explode.c b/lib/libc/sparc64/fpu/fpu_explode.c index 12c8802f435..474e0dfc7d6 100644 --- a/lib/libc/sparc64/fpu/fpu_explode.c +++ b/lib/libc/sparc64/fpu/fpu_explode.c @@ -139,9 +139,9 @@ __fpu_xtof(fp, i) * a signed or unsigned entity. */ if (fp->fp_sign && (int64_t)i < 0) - *((int64_t*)fp->fp_mant) = -i; + *((int64_t *)fp->fp_mant) = -i; else - *((int64_t*)fp->fp_mant) = i; + *((int64_t *)fp->fp_mant) = i; fp->fp_mant[2] = 0; fp->fp_mant[3] = 0; __fpu_norm(fp); @@ -262,14 +262,12 @@ __fpu_explode(fe, fp, type, reg) struct fpn *fp; int type, reg; { - u_int32_t s, *sp; - u_int64_t l[2]; - void *vl = l; + u_int64_t l0, l1; + u_int32_t s; if (type == FTYPE_LNG || type == FTYPE_DBL || type == FTYPE_EXT) { - l[0] = __fpu_getreg64(reg & ~1); - sp = vl; - fp->fp_sign = sp[0] >> 31; + l0 = __fpu_getreg64(reg & ~1); + fp->fp_sign = l0 >> 63; } else { s = __fpu_getreg(reg); fp->fp_sign = s >> 31; @@ -277,7 +275,7 @@ __fpu_explode(fe, fp, type, reg) fp->fp_sticky = 0; switch (type) { case FTYPE_LNG: - s = __fpu_xtof(fp, l[0]); + s = __fpu_xtof(fp, l0); break; case FTYPE_INT: @@ -289,12 +287,13 @@ __fpu_explode(fe, fp, type, reg) break; case FTYPE_DBL: - s = __fpu_dtof(fp, sp[0], sp[1]); + s = __fpu_dtof(fp, l0 >> 32, l0 & 0xffffffff); break; case FTYPE_EXT: - l[1] = __fpu_getreg64((reg & ~1) + 2); - s = __fpu_qtof(fp, sp[0], sp[1], sp[2], sp[3]); + l1 = __fpu_getreg64((reg & ~1) + 2); + s = __fpu_qtof(fp, l0 >> 32, l0 & 0xffffffff, l1 >> 32, + l1 & 0xffffffff); break; default: From e18f909f8d58210c9be685e66b4a1f600e27c4e6 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 19:33:09 +0000 Subject: [PATCH 1759/2592] MFC: r203334 Sync with the other archs and declare the memory location referenced by the address argument of the bus_space_write_multi_*() familiy as const. --- sys/sun4v/include/bus.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/sun4v/include/bus.h b/sys/sun4v/include/bus.h index 27901df65c5..a1e3050f557 100644 --- a/sys/sun4v/include/bus.h +++ b/sys/sun4v/include/bus.h @@ -316,7 +316,7 @@ bus_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, static __inline void bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - uint8_t *a, size_t c) + const uint8_t *a, size_t c) { while (c-- > 0) @@ -325,7 +325,7 @@ bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, static __inline void bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - uint16_t *a, size_t c) + const uint16_t *a, size_t c) { while (c-- > 0) @@ -334,7 +334,7 @@ bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, static __inline void bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - uint32_t *a, size_t c) + const uint32_t *a, size_t c) { while (c-- > 0) @@ -343,7 +343,7 @@ bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, static __inline void bus_space_write_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - uint64_t *a, size_t c) + const uint64_t *a, size_t c) { while (c-- > 0) From 592227a6e8405f46d54554104f94620e2196fbb6 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 19:36:00 +0000 Subject: [PATCH 1760/2592] MFC: r203335 - Const'ify the bus_stream_asi and bus_type_asi arrays. - Replace hard-coded functions names missed in bus_machdep.c with __func__. - Break some long lines. --- sys/sun4v/include/bus.h | 4 ++-- sys/sun4v/sun4v/bus_machdep.c | 23 +++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/sys/sun4v/include/bus.h b/sys/sun4v/include/bus.h index a1e3050f557..2838859a991 100644 --- a/sys/sun4v/include/bus.h +++ b/sys/sun4v/include/bus.h @@ -96,8 +96,8 @@ #define PCI_MEMORY_BUS_SPACE 4 #define LAST_BUS_SPACE 5 -extern int bus_type_asi[]; -extern int bus_stream_asi[]; +extern const int bus_type_asi[]; +extern const int bus_stream_asi[]; #define __BUS_SPACE_HAS_STREAM_METHODS 1 diff --git a/sys/sun4v/sun4v/bus_machdep.c b/sys/sun4v/sun4v/bus_machdep.c index 0c76feeaedf..1282b0e79b9 100644 --- a/sys/sun4v/sun4v/bus_machdep.c +++ b/sys/sun4v/sun4v/bus_machdep.c @@ -95,7 +95,7 @@ * from: @(#)machdep.c 8.6 (Berkeley) 1/14/94 * from: NetBSD: machdep.c,v 1.111 2001/09/15 07:13:40 eeh Exp * and - * from: FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.24 2001/08/15 + * from: FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.24 2001/08/15 */ #include @@ -129,8 +129,8 @@ __FBSDID("$FreeBSD$"); static void nexus_bus_barrier(bus_space_tag_t, bus_space_handle_t, bus_size_t, bus_size_t, int); -/* ASI's for bus access. */ -int bus_type_asi[] = { +/* ASIs for bus access */ +const int bus_type_asi[] = { ASI_REAL_IO, /* nexus */ ASI_REAL_IO, /* SBus */ ASI_REAL_IO_L, /* PCI configuration space */ @@ -139,7 +139,7 @@ int bus_type_asi[] = { 0 }; -int bus_stream_asi[] = { +const int bus_stream_asi[] = { ASI_REAL_IO, /* nexus */ ASI_REAL_IO, /* SBus */ ASI_REAL_IO, /* PCI configuration space */ @@ -249,7 +249,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, newtag->dt_segments = NULL; - /* Take into account any restrictions imposed by our parent tag */ + /* Take into account any restrictions imposed by our parent tag. */ if (parent != NULL) { newtag->dt_lowaddr = ulmin(parent->dt_lowaddr, newtag->dt_lowaddr); @@ -551,8 +551,7 @@ nexus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, if (uio->uio_segflg == UIO_USERSPACE) { td = uio->uio_td; - KASSERT(td != NULL, - ("nexus_dmamap_load_uio: USERSPACE but no proc")); + KASSERT(td != NULL, ("%s: USERSPACE but no proc", __func__)); } nsegs = 0; @@ -652,9 +651,9 @@ nexus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags, *vaddr = malloc(dmat->dt_maxsize, M_DEVBUF, mflags); } else { /* - * XXX: Use contigmalloc until it is merged into this facility - * and handles multi-seg allocations. Nobody is doing multi-seg - * allocations yet though. + * XXX use contigmalloc until it is merged into this + * facility and handles multi-seg allocations. Nobody + * is doing multi-seg allocations yet though. */ *vaddr = contigmalloc(dmat->dt_maxsize, M_DEVBUF, mflags, 0ul, dmat->dt_lowaddr, @@ -795,8 +794,8 @@ sparc64_bus_mem_unmap(void *bh, bus_size_t size) } /* - * Fake up a bus tag, for use by console drivers in early boot when the regular - * means to allocate resources are not yet available. + * Fake up a bus tag, for use by console drivers in early boot when the + * regular means to allocate resources are not yet available. * Addr is the physical address of the desired start of the handle. */ bus_space_handle_t From e73d23dad80512af12dfa782887dc86e92bf70ed Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 19:37:47 +0000 Subject: [PATCH 1761/2592] MFC: r203341 - Remove the BUS_HANDLE_MIN checking in the __BUS_DEBUG_ACCESS macro; for UPA it should have fulfilled its purpose by now and Fireplane- and JBus-based machines are way to messy in organization to implement something equivalent. - Fix a bunch of style(9) bugs. --- sys/sun4v/include/bus.h | 171 +++++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 81 deletions(-) diff --git a/sys/sun4v/include/bus.h b/sys/sun4v/include/bus.h index 2838859a991..02fa6345a8d 100644 --- a/sys/sun4v/include/bus.h +++ b/sys/sun4v/include/bus.h @@ -81,7 +81,6 @@ #include #include -#include /* * Nexus and SBus spaces are non-cached and big endian @@ -99,27 +98,24 @@ extern const int bus_type_asi[]; extern const int bus_stream_asi[]; -#define __BUS_SPACE_HAS_STREAM_METHODS 1 +#define __BUS_SPACE_HAS_STREAM_METHODS 1 -#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF -#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF -#define BUS_SPACE_MAXSIZE 0xFFFFFFFFFFFFFFFF -#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF -#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF -#define BUS_SPACE_MAXADDR 0xFFFFFFFF +#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF +#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF +#define BUS_SPACE_MAXSIZE 0xFFFFFFFFFFFFFFFF +#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF +#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF +#define BUS_SPACE_MAXADDR 0xFFFFFFFF -#define BUS_SPACE_UNRESTRICTED (~0) +#define BUS_SPACE_UNRESTRICTED (~0) -/* - * Access methods for bus resources and address space. - */ struct bus_space_tag { void *bst_cookie; bus_space_tag_t bst_parent; int bst_type; void (*bst_bus_barrier)(bus_space_tag_t, bus_space_handle_t, - bus_size_t, bus_size_t, int); + bus_size_t, bus_size_t, int); }; /* @@ -135,13 +131,11 @@ static int bus_space_subregion(bus_space_tag_t, bus_space_handle_t, */ static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr, - bus_size_t size, int flags, - bus_space_handle_t *bshp); + bus_size_t size, int flags, bus_space_handle_t *bshp); static __inline int bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr, - bus_size_t size __unused, int flags __unused, - bus_space_handle_t *bshp) + bus_size_t size __unused, int flags __unused, bus_space_handle_t *bshp) { *bshp = addr; @@ -152,24 +146,26 @@ bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr, * Unmap a region of device bus space. */ static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, - bus_size_t size); + bus_size_t size); static __inline void bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused, - bus_size_t size __unused) + bus_size_t size __unused) { + } /* This macro finds the first "upstream" implementation of method `f' */ -#define _BS_CALL(t,f) \ +#define _BS_CALL(t,f) \ while (t->f == NULL) \ - t = t->bst_parent; \ + t = t->bst_parent; \ return (*(t)->f) static __inline void bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_size_t s, int f) { + _BS_CALL(t, bst_bus_barrier)(t, h, o, s, f); } @@ -177,20 +173,21 @@ static __inline int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, bus_size_t s, bus_space_handle_t *hp) { + *hp = h + o; return (0); } /* flags for bus space map functions */ -#define BUS_SPACE_MAP_CACHEABLE 0x0001 -#define BUS_SPACE_MAP_LINEAR 0x0002 -#define BUS_SPACE_MAP_READONLY 0x0004 -#define BUS_SPACE_MAP_PREFETCHABLE 0x0008 +#define BUS_SPACE_MAP_CACHEABLE 0x0001 +#define BUS_SPACE_MAP_LINEAR 0x0002 +#define BUS_SPACE_MAP_READONLY 0x0004 +#define BUS_SPACE_MAP_PREFETCHABLE 0x0008 /* placeholders for bus functions... */ -#define BUS_SPACE_MAP_BUS1 0x0100 -#define BUS_SPACE_MAP_BUS2 0x0200 -#define BUS_SPACE_MAP_BUS3 0x0400 -#define BUS_SPACE_MAP_BUS4 0x0800 +#define BUS_SPACE_MAP_BUS1 0x0100 +#define BUS_SPACE_MAP_BUS2 0x0200 +#define BUS_SPACE_MAP_BUS3 0x0400 +#define BUS_SPACE_MAP_BUS4 0x0800 /* flags for bus_space_barrier() */ #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ @@ -198,13 +195,9 @@ bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, #ifdef BUS_SPACE_DEBUG #define KTR_BUS KTR_CT2 -#define BUS_HANDLE_MIN UPA_MEMSTART #define __BUS_DEBUG_ACCESS(h, o, desc, sz) do { \ CTR4(KTR_BUS, "bus space: %s %d: handle %#lx, offset %#lx", \ (desc), (sz), (h), (o)); \ - if ((h) + (o) < BUS_HANDLE_MIN) \ - panic("bus space access at %#lx out of range", \ - (h) + (o)); \ } while (0) #else #define __BUS_DEBUG_ACCESS(h, o, desc, sz) @@ -388,97 +381,109 @@ bus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, static __inline void bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - u_int8_t *a, bus_size_t c) + uint8_t *a, bus_size_t c) { + for (; c; a++, c--, o++) *a = bus_space_read_1(t, h, o); } static __inline void bus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - u_int16_t *a, bus_size_t c) + uint16_t *a, bus_size_t c) { - for (; c; a++, c--, o+=2) + + for (; c; a++, c--, o += 2) *a = bus_space_read_2(t, h, o); } static __inline void bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - u_int32_t *a, bus_size_t c) + uint32_t *a, bus_size_t c) { - for (; c; a++, c--, o+=4) + + for (; c; a++, c--, o += 4) *a = bus_space_read_4(t, h, o); } static __inline void bus_space_read_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - u_int64_t *a, bus_size_t c) + uint64_t *a, bus_size_t c) { - for (; c; a++, c--, o+=8) + + for (; c; a++, c--, o += 8) *a = bus_space_read_8(t, h, o); } static __inline void bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - const u_int8_t *a, bus_size_t c) + const uint8_t *a, bus_size_t c) { + for (; c; a++, c--, o++) bus_space_write_1(t, h, o, *a); } static __inline void bus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - const u_int16_t *a, bus_size_t c) + const uint16_t *a, bus_size_t c) { - for (; c; a++, c--, o+=2) + + for (; c; a++, c--, o += 2) bus_space_write_2(t, h, o, *a); } static __inline void bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - const u_int32_t *a, bus_size_t c) + const uint32_t *a, bus_size_t c) { - for (; c; a++, c--, o+=4) + + for (; c; a++, c--, o += 4) bus_space_write_4(t, h, o, *a); } static __inline void bus_space_write_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - const u_int64_t *a, bus_size_t c) + const uint64_t *a, bus_size_t c) { - for (; c; a++, c--, o+=8) + + for (; c; a++, c--, o += 8) bus_space_write_8(t, h, o, *a); } static __inline void bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - const u_int8_t v, bus_size_t c) + const uint8_t v, bus_size_t c) { + for (; c; c--, o++) bus_space_write_1(t, h, o, v); } static __inline void bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - const u_int16_t v, bus_size_t c) + const uint16_t v, bus_size_t c) { - for (; c; c--, o+=2) + + for (; c; c--, o += 2) bus_space_write_2(t, h, o, v); } static __inline void bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - const u_int32_t v, bus_size_t c) + const uint32_t v, bus_size_t c) { - for (; c; c--, o+=4) + + for (; c; c--, o += 4) bus_space_write_4(t, h, o, v); } static __inline void bus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, - const u_int64_t v, bus_size_t c) + const uint64_t v, bus_size_t c) { - for (; c; c--, o+=8) + + for (; c; c--, o += 8) bus_space_write_8(t, h, o, v); } @@ -486,6 +491,7 @@ static __inline void bus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) { + for (; c; c--, o1++, o2++) bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2)); } @@ -494,7 +500,8 @@ static __inline void bus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) { - for (; c; c--, o1+=2, o2+=2) + + for (; c; c--, o1 += 2, o2 += 2) bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2)); } @@ -502,7 +509,8 @@ static __inline void bus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) { - for (; c; c--, o1+=4, o2+=4) + + for (; c; c--, o1 += 4, o2 += 4) bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2)); } @@ -510,7 +518,8 @@ static __inline void bus_space_copy_region_8(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) { - for (; c; c--, o1+=8, o2+=8) + + for (; c; c--, o1 += 8, o2 += 8) bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2)); } @@ -692,7 +701,7 @@ bus_space_set_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h, static __inline void bus_space_read_region_stream_1(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, u_int8_t *a, bus_size_t c) + bus_size_t o, uint8_t *a, bus_size_t c) { for (; c; a++, c--, o++) @@ -701,34 +710,34 @@ bus_space_read_region_stream_1(bus_space_tag_t t, bus_space_handle_t h, static __inline void bus_space_read_region_stream_2(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, u_int16_t *a, bus_size_t c) + bus_size_t o, uint16_t *a, bus_size_t c) { - for (; c; a++, c--, o+=2) + for (; c; a++, c--, o += 2) *a = bus_space_read_stream_2(t, h, o); } static __inline void bus_space_read_region_stream_4(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, u_int32_t *a, bus_size_t c) + bus_size_t o, uint32_t *a, bus_size_t c) { - for (; c; a++, c--, o+=4) + for (; c; a++, c--, o += 4) *a = bus_space_read_stream_4(t, h, o); } static __inline void bus_space_read_region_stream_8(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, u_int64_t *a, bus_size_t c) + bus_size_t o, uint64_t *a, bus_size_t c) { - for (; c; a++, c--, o+=8) + for (; c; a++, c--, o += 8) *a = bus_space_read_stream_8(t, h, o); } static __inline void bus_space_write_region_stream_1(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, const u_int8_t *a, bus_size_t c) + bus_size_t o, const uint8_t *a, bus_size_t c) { for (; c; a++, c--, o++) @@ -737,34 +746,34 @@ bus_space_write_region_stream_1(bus_space_tag_t t, bus_space_handle_t h, static __inline void bus_space_write_region_stream_2(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, const u_int16_t *a, bus_size_t c) + bus_size_t o, const uint16_t *a, bus_size_t c) { - for (; c; a++, c--, o+=2) + for (; c; a++, c--, o += 2) bus_space_write_stream_2(t, h, o, *a); } static __inline void bus_space_write_region_stream_4(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, const u_int32_t *a, bus_size_t c) + bus_size_t o, const uint32_t *a, bus_size_t c) { - for (; c; a++, c--, o+=4) + for (; c; a++, c--, o += 4) bus_space_write_stream_4(t, h, o, *a); } static __inline void bus_space_write_region_stream_8(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, const u_int64_t *a, bus_size_t c) + bus_size_t o, const uint64_t *a, bus_size_t c) { - for (; c; a++, c--, o+=8) + for (; c; a++, c--, o += 8) bus_space_write_stream_8(t, h, o, *a); } static __inline void bus_space_set_region_stream_1(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, const u_int8_t v, bus_size_t c) + bus_size_t o, const uint8_t v, bus_size_t c) { for (; c; c--, o++) @@ -773,28 +782,28 @@ bus_space_set_region_stream_1(bus_space_tag_t t, bus_space_handle_t h, static __inline void bus_space_set_region_stream_2(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, const u_int16_t v, bus_size_t c) + bus_size_t o, const uint16_t v, bus_size_t c) { - for (; c; c--, o+=2) + for (; c; c--, o += 2) bus_space_write_stream_2(t, h, o, v); } static __inline void bus_space_set_region_stream_4(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, const u_int32_t v, bus_size_t c) + bus_size_t o, const uint32_t v, bus_size_t c) { - for (; c; c--, o+=4) + for (; c; c--, o += 4) bus_space_write_stream_4(t, h, o, v); } static __inline void bus_space_set_region_stream_8(bus_space_tag_t t, bus_space_handle_t h, - bus_size_t o, const u_int64_t v, bus_size_t c) + bus_size_t o, const uint64_t v, bus_size_t c) { - for (; c; c--, o+=8) + for (; c; c--, o += 8) bus_space_write_stream_8(t, h, o, v); } @@ -813,7 +822,7 @@ bus_space_copy_region_stream_2(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) { - for (; c; c--, o1+=2, o2+=2) + for (; c; c--, o1 += 2, o2 += 2) bus_space_write_stream_2(t, h1, o1, bus_space_read_stream_2(t, h2, o2)); } @@ -823,7 +832,7 @@ bus_space_copy_region_stream_4(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) { - for (; c; c--, o1+=4, o2+=4) + for (; c; c--, o1 += 4, o2 += 4) bus_space_write_stream_4(t, h1, o1, bus_space_read_stream_4(t, h2, o2)); } @@ -833,7 +842,7 @@ bus_space_copy_region_stream_8(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) { - for (; c; c--, o1+=8, o2+=8) + for (; c; c--, o1 += 8, o2 += 8) bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2)); } From 4139c876fa8ffd91fdb72aa51f05ab37973d2c2a Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 19:52:45 +0000 Subject: [PATCH 1762/2592] MFC: r203731 Some style(9) fixes --- sys/nfs/nfs_common.c | 43 ++++++++-------- sys/nfs/nfs_common.h | 3 +- sys/nfsclient/nfs_krpc.c | 103 +++++++++++++++++++-------------------- 3 files changed, 75 insertions(+), 74 deletions(-) diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c index fc767c16f6a..c56f31f9331 100644 --- a/sys/nfs/nfs_common.c +++ b/sys/nfs/nfs_common.c @@ -37,7 +37,7 @@ __FBSDID("$FreeBSD$"); /* * These functions support the macros and help fiddle mbuf chains for - * the nfs op functions. They do things like create the rpc header and + * the nfs op functions. They do things like create the rpc header and * copy data between mbuf chains and uio lists. */ @@ -77,7 +77,8 @@ nfstype nfsv3_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, NFSOCK, NFFIFO, NFNON }; -static void *nfsm_dissect_xx_sub(int s, struct mbuf **md, caddr_t *dpos, int how); +static void *nfsm_dissect_xx_sub(int s, struct mbuf **md, caddr_t *dpos, + int how); SYSCTL_NODE(_vfs, OID_AUTO, nfs_common, CTLFLAG_RD, 0, "NFS common support"); @@ -90,7 +91,7 @@ SYSCTL_INT(_vfs_nfs_common, OID_AUTO, realign_count, CTLFLAG_RD, &nfs_realign_count, 0, "Number of mbuf realignments done"); u_quad_t -nfs_curusec(void) +nfs_curusec(void) { struct timeval tv; @@ -188,7 +189,7 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how) while (left == 0) { *mdp = mp = mp->m_next; if (mp == NULL) - return NULL; + return (NULL); left = mp->m_len; *dposp = mtod(mp, caddr_t); } @@ -196,13 +197,13 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how) ret = *dposp; *dposp += siz; } else if (mp->m_next == NULL) { - return NULL; + return (NULL); } else if (siz > MHLEN) { panic("nfs S too big"); } else { MGET(mp2, how, MT_DATA); if (mp2 == NULL) - return NULL; + return (NULL); mp2->m_len = siz; mp2->m_next = mp->m_next; mp->m_next = mp2; @@ -218,7 +219,7 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how) /* Loop around copying up the siz2 bytes */ while (siz2 > 0) { if (mp2 == NULL) - return NULL; + return (NULL); xfer = (siz2 > mp2->m_len) ? mp2->m_len : siz2; if (xfer > 0) { bcopy(mtod(mp2, caddr_t), ptr, xfer); @@ -241,7 +242,7 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how) *dposp = npos; } } - return ret; + return (ret); } /* @@ -285,19 +286,21 @@ nfsm_build_xx(int s, struct mbuf **mb, caddr_t *bpos) ret = *bpos; (*mb)->m_len += s; *bpos += s; - return ret; + return (ret); } void * nfsm_dissect_xx(int s, struct mbuf **md, caddr_t *dpos) { - return nfsm_dissect_xx_sub(s, md, dpos, M_WAIT); + + return (nfsm_dissect_xx_sub(s, md, dpos, M_WAIT)); } void * nfsm_dissect_xx_nonblock(int s, struct mbuf **md, caddr_t *dpos) { - return nfsm_dissect_xx_sub(s, md, dpos, M_DONTWAIT); + + return (nfsm_dissect_xx_sub(s, md, dpos, M_DONTWAIT)); } static void * @@ -311,10 +314,10 @@ nfsm_dissect_xx_sub(int s, struct mbuf **md, caddr_t *dpos, int how) if (t1 >= s) { ret = *dpos; *dpos += s; - return ret; + return (ret); } - cp2 = nfsm_disct(md, dpos, s, t1, how); - return cp2; + cp2 = nfsm_disct(md, dpos, s, t1, how); + return (cp2); } int @@ -324,11 +327,11 @@ nfsm_strsiz_xx(int *s, int m, struct mbuf **mb, caddr_t *bpos) tl = nfsm_dissect_xx(NFSX_UNSIGNED, mb, bpos); if (tl == NULL) - return EBADRPC; + return (EBADRPC); *s = fxdr_unsigned(int32_t, *tl); if (*s > m) - return EBADRPC; - return 0; + return (EBADRPC); + return (0); } int @@ -339,12 +342,12 @@ nfsm_adv_xx(int s, struct mbuf **md, caddr_t *dpos) t1 = mtod(*md, caddr_t) + (*md)->m_len - *dpos; if (t1 >= s) { *dpos += s; - return 0; + return (0); } t1 = nfs_adv(md, dpos, s, t1); if (t1) - return t1; - return 0; + return (t1); + return (0); } /* diff --git a/sys/nfs/nfs_common.h b/sys/nfs/nfs_common.h index 97b8c5ffea3..1c0b3159411 100644 --- a/sys/nfs/nfs_common.h +++ b/sys/nfs/nfs_common.h @@ -33,7 +33,6 @@ * $FreeBSD$ */ - #ifndef _NFS_NFS_COMMON_H_ #define _NFS_NFS_COMMON_H_ @@ -87,7 +86,7 @@ do { \ goto nfsmout; \ } \ } while (0) - + #define nfsm_dissect(c, s) \ ({ \ void *ret; \ diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c index 43bfe640945..bfb1ea177ef 100644 --- a/sys/nfsclient/nfs_krpc.c +++ b/sys/nfsclient/nfs_krpc.c @@ -99,9 +99,11 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0, "Buffer reservation size 2 < x < 64"); SYSCTL_INT(_vfs_nfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0, "Number of times the nfs client has had to reconnect"); -SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs3_jukebox_delay, CTLFLAG_RW, &nfs3_jukebox_delay, 0, +SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs3_jukebox_delay, CTLFLAG_RW, + &nfs3_jukebox_delay, 0, "Number of seconds to delay a retry after receiving EJUKEBOX"); -SYSCTL_INT(_vfs_nfs, OID_AUTO, skip_wcc_data_onerr, CTLFLAG_RW, &nfs_skip_wcc_data_onerr, 0, +SYSCTL_INT(_vfs_nfs, OID_AUTO, skip_wcc_data_onerr, CTLFLAG_RW, + &nfs_skip_wcc_data_onerr, 0, "Disable weak cache consistency checking when server returns an error"); static void nfs_down(struct nfsmount *, struct thread *, const char *, @@ -154,7 +156,8 @@ static enum nfs_rto_timer_t nfs_proct[NFS_NPROCS] = { static inline enum nfs_rto_timer_t nfs_rto_timer(u_int32_t procnum) { - return nfs_proct[procnum]; + + return (nfs_proct[procnum]); } /* @@ -219,7 +222,7 @@ nfs_connect(struct nfsmount *nmp) nconf = getnetconfigent("udp6"); else nconf = getnetconfigent("tcp6"); - + /* * Get buffer reservation size from sysctl, but impose reasonable * limits. @@ -267,9 +270,8 @@ nfs_connect(struct nfsmount *nmp) * Someone else already connected. */ CLNT_RELEASE(client); - } else { + } else nmp->nm_client = client; - } /* * Protocols that do not require connections may be optionally left @@ -278,22 +280,21 @@ nfs_connect(struct nfsmount *nmp) if (!(nmp->nm_flag & NFSMNT_NOCONN)) { mtx_unlock(&nmp->nm_mtx); CLNT_CONTROL(client, CLSET_CONNECT, &one); - } else { + } else mtx_unlock(&nmp->nm_mtx); - } /* Restore current thread's credentials. */ td->td_ucred = origcred; mtx_lock(&nmp->nm_mtx); - /* Initialize other non-zero congestion variables */ + /* Initialize other non-zero congestion variables. */ nfs_init_rtt(nmp); mtx_unlock(&nmp->nm_mtx); return (0); } /* - * NFS disconnect. Clean up and unlink. + * NFS disconnect. Clean up and unlink. */ void nfs_disconnect(struct nfsmount *nmp) @@ -310,9 +311,8 @@ nfs_disconnect(struct nfsmount *nmp) #endif CLNT_CLOSE(client); CLNT_RELEASE(client); - } else { + } else mtx_unlock(&nmp->nm_mtx); - } } void @@ -335,11 +335,10 @@ nfs_getauth(struct nfsmount *nmp, struct ucred *cred) case RPCSEC_GSS_KRB5: case RPCSEC_GSS_KRB5I: case RPCSEC_GSS_KRB5P: - if (!nmp->nm_mech_oid) { + if (!nmp->nm_mech_oid) if (!rpc_gss_mech_to_oid("kerberosv5", - &nmp->nm_mech_oid)) + &nmp->nm_mech_oid)) return (NULL); - } if (nmp->nm_secflavor == RPCSEC_GSS_KRB5) svc = rpc_gss_svc_none; else if (nmp->nm_secflavor == RPCSEC_GSS_KRB5I) @@ -438,10 +437,10 @@ nfs_request(struct vnode *vp, struct mbuf *mreq, int procnum, nf.nf_td = td; getmicrouptime(&now); nf.nf_lastmsg = now.tv_sec - - ((nmp->nm_tprintf_delay) - (nmp->nm_tprintf_initial_delay)); + ((nmp->nm_tprintf_delay) - (nmp->nm_tprintf_initial_delay)); /* - * XXX if not already connected call nfs_connect now. Longer + * XXX if not already connected call nfs_connect now. Longer * term, change nfs_mount to call nfs_connect unconditionally * and let clnt_reconnect_create handle reconnects. */ @@ -461,18 +460,17 @@ nfs_request(struct vnode *vp, struct mbuf *mreq, int procnum, /* * Use a conservative timeout for RPCs other than getattr, - * lookup, read or write. The justification for doing "other" + * lookup, read or write. The justification for doing "other" * this way is that these RPCs happen so infrequently that * timer est. would probably be stale. Also, since many of * these RPCs are non-idempotent, a conservative timeout is * desired. */ timer = nfs_rto_timer(procnum); - if (timer != NFS_DEFAULT_TIMER) { + if (timer != NFS_DEFAULT_TIMER) ext.rc_timers = &nmp->nm_timers[timer - 1]; - } else { + else ext.rc_timers = NULL; - } #ifdef KDTRACE_HOOKS if (dtrace_nfsclient_nfs23_start_probe != NULL) { @@ -505,17 +503,16 @@ tryagain: * If there was a successful reply and a tprintf msg. * tprintf a response. */ - if (stat == RPC_SUCCESS) { + if (stat == RPC_SUCCESS) error = 0; - } else if (stat == RPC_TIMEDOUT) { + else if (stat == RPC_TIMEDOUT) error = ETIMEDOUT; - } else if (stat == RPC_VERSMISMATCH) { + else if (stat == RPC_VERSMISMATCH) error = EOPNOTSUPP; - } else if (stat == RPC_PROGVERSMISMATCH) { + else if (stat == RPC_PROGVERSMISMATCH) error = EPROTONOSUPPORT; - } else { + else error = EACCES; - } if (error) goto nfsmout; @@ -544,9 +541,9 @@ tryagain: m_freem(mrep); error = 0; waituntil = time_second + nfs3_jukebox_delay; - while (time_second < waituntil) { - (void) tsleep(&fake_wchan, PSOCK, "nqnfstry", hz); - } + while (time_second < waituntil) + (void)tsleep(&fake_wchan, PSOCK, "nqnfstry", + hz); goto tryagain; } @@ -557,12 +554,13 @@ tryagain: if (error == ESTALE) nfs_purgecache(vp); /* - * Skip wcc data on NFS errors for now. NetApp filers + * Skip wcc data on NFS errors for now. NetApp filers * return corrupt postop attrs in the wcc data for NFS - * err EROFS. Not sure if they could return corrupt + * err EROFS. Not sure if they could return corrupt * postop attrs for others errors. */ - if ((nmp->nm_flag & NFSMNT_NFSV3) && !nfs_skip_wcc_data_onerr) { + if ((nmp->nm_flag & NFSMNT_NFSV3) && + !nfs_skip_wcc_data_onerr) { *mrp = mrep; *mdp = md; *dposp = dpos; @@ -624,7 +622,7 @@ nfsmout: /* * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and - * wait for all requests to complete. This is used by forced unmounts + * wait for all requests to complete. This is used by forced unmounts * to terminate any outstanding RPCs. */ int @@ -638,7 +636,7 @@ nfs_nmcancelreqs(struct nfsmount *nmp) /* * Any signal that can interrupt an NFS operation in an intr mount - * should be added to this set. SIGSTOP and SIGKILL cannot be masked. + * should be added to this set. SIGSTOP and SIGKILL cannot be masked. */ int nfs_sig_set[] = { SIGINT, @@ -657,16 +655,16 @@ static int nfs_sig_pending(sigset_t set) { int i; - + for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) if (SIGISMEMBER(set, nfs_sig_set[i])) return (1); return (0); } - + /* * The set/restore sigmask functions are used to (temporarily) overwrite - * the process p_sigmask during an RPC call (for example). These are also + * the process p_sigmask during an RPC call (for example). These are also * used in other places in the NFS client that might tsleep(). */ void @@ -675,18 +673,18 @@ nfs_set_sigmask(struct thread *td, sigset_t *oldset) sigset_t newset; int i; struct proc *p; - + SIGFILLSET(newset); if (td == NULL) td = curthread; /* XXX */ p = td->td_proc; - /* Remove the NFS set of signals from newset */ + /* Remove the NFS set of signals from newset. */ PROC_LOCK(p); mtx_lock(&p->p_sigacts->ps_mtx); for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) { /* * But make sure we leave the ones already masked - * by the process, ie. remove the signal from the + * by the process, i.e. remove the signal from the * temporary signalmask only if it wasn't already * in p_sigmask. */ @@ -712,12 +710,13 @@ nfs_restore_sigmask(struct thread *td, sigset_t *set) * old one after msleep() returns. */ int -nfs_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority, char *wmesg, int timo) +nfs_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority, + char *wmesg, int timo) { sigset_t oldset; int error; struct proc *p; - + if ((priority & PCATCH) == 0) return msleep(ident, mtx, priority, wmesg, timo); if (td == NULL) @@ -738,7 +737,7 @@ nfs_sigintr(struct nfsmount *nmp, struct thread *td) { struct proc *p; sigset_t tmpset; - + /* Terminate all requests while attempting a forced unmount. */ if (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF) return (EIO); @@ -769,12 +768,11 @@ nfs_msg(struct thread *td, const char *server, const char *msg, int error) struct proc *p; p = td ? td->td_proc : NULL; - if (error) { + if (error) tprintf(p, LOG_INFO, "nfs server %s: %s, error %d\n", server, msg, error); - } else { + else tprintf(p, LOG_INFO, "nfs server %s: %s\n", server, msg); - } return (0); } @@ -793,7 +791,8 @@ nfs_down(struct nfsmount *nmp, struct thread *td, const char *msg, } else mtx_unlock(&nmp->nm_mtx); mtx_lock(&nmp->nm_mtx); - if ((flags & NFSSTA_LOCKTIMEO) && !(nmp->nm_state & NFSSTA_LOCKTIMEO)) { + if ((flags & NFSSTA_LOCKTIMEO) && + !(nmp->nm_state & NFSSTA_LOCKTIMEO)) { nmp->nm_state |= NFSSTA_LOCKTIMEO; mtx_unlock(&nmp->nm_mtx); vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, @@ -809,9 +808,8 @@ nfs_up(struct nfsmount *nmp, struct thread *td, const char *msg, { if (nmp == NULL) return; - if (tprintfmsg) { + if (tprintfmsg) nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, 0); - } mtx_lock(&nmp->nm_mtx); if ((flags & NFSSTA_TIMEO) && (nmp->nm_state & NFSSTA_TIMEO)) { @@ -821,9 +819,10 @@ nfs_up(struct nfsmount *nmp, struct thread *td, const char *msg, VQ_NOTRESP, 1); } else mtx_unlock(&nmp->nm_mtx); - + mtx_lock(&nmp->nm_mtx); - if ((flags & NFSSTA_LOCKTIMEO) && (nmp->nm_state & NFSSTA_LOCKTIMEO)) { + if ((flags & NFSSTA_LOCKTIMEO) && + (nmp->nm_state & NFSSTA_LOCKTIMEO)) { nmp->nm_state &= ~NFSSTA_LOCKTIMEO; mtx_unlock(&nmp->nm_mtx); vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, From 0a1e6ecc1f3c748e933f93db4839a5a523f99241 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 20:02:26 +0000 Subject: [PATCH 1763/2592] MFC: r203829 - Assert that HEAPSZ is a multiple of PAGE_SIZE as at least the firmware of Sun Fire V1280 doesn't round up the size itself but instead lets claiming of non page-sized amounts of memory fail. - Change parameters and variables related to the TLB slots to unsigned which is more appropriate. - Search the whole OFW device tree instead of only the children of the root nexus device for the BSP as starting with UltraSPARC IV the 'cpu' nodes hang off of from 'cmp' (chip multi-threading processor) or 'core' or combinations thereof. Also in large UltraSPARC III based machines the 'cpu' nodes hang off of 'ssm' (scalable shared memory) nodes which group snooping-coherency domains together instead of directly from the nexus. - Add support for UltraSPARC IV and IV+ BSPs. Due to the fact that these are multi-core each CPU has two Fireplane config registers and thus the module/target ID has to be determined differently so the one specific to a certain core is used. Similarly, starting with UltraSPARC IV the individual cores use a different property in the OFW device tree to indicate the CPU/core ID as it no longer is in coincidence with the shared slot/socket ID. While at it additionally distinguish between CPUs with Fireplane and JBus interconnects as these also use slightly different sizes for the JBus/agent/module/target IDs. - Check the return value of init_heap(). This requires moving it after cons_probe() so we can panic when appropriate. This should be fine as the PowerPC OFW loader uses that order for quite some time now. --- sys/boot/sparc64/loader/main.c | 149 ++++++++++++++++++++++++-------- sys/sparc64/include/asi.h | 20 +++-- sys/sparc64/include/cmt.h | 39 +++++++++ sys/sparc64/include/fireplane.h | 40 +++++++++ sys/sparc64/include/jbus.h | 39 +++++++++ sys/sun4v/include/asi.h | 7 ++ sys/sun4v/include/cmt.h | 7 ++ sys/sun4v/include/fireplane.h | 7 ++ sys/sun4v/include/jbus.h | 7 ++ 9 files changed, 275 insertions(+), 40 deletions(-) create mode 100644 sys/sparc64/include/cmt.h create mode 100644 sys/sparc64/include/fireplane.h create mode 100644 sys/sparc64/include/jbus.h create mode 100644 sys/sun4v/include/cmt.h create mode 100644 sys/sun4v/include/fireplane.h create mode 100644 sys/sun4v/include/jbus.h diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c index 604e792445d..4c869dae67c 100644 --- a/sys/boot/sparc64/loader/main.c +++ b/sys/boot/sparc64/loader/main.c @@ -46,16 +46,19 @@ __FBSDID("$FreeBSD$"); */ #include -#include #include -#include +#include #include +#include #include #include #include +#include #include #include +#include +#include #include #include #include @@ -68,6 +71,12 @@ __FBSDID("$FreeBSD$"); #include "libofw.h" #include "dev_net.h" +#ifndef CTASSERT +#define CTASSERT(x) _CTASSERT(x, __LINE__) +#define _CTASSERT(x, y) __CTASSERT(x, y) +#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] +#endif + extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; enum { @@ -76,6 +85,9 @@ enum { LOADSZ = 0x1000000 /* for kernel and modules */ }; +/* At least Sun Fire V1280 require page sized allocations to be claimed. */ +CTASSERT(HEAPSZ % PAGE_SIZE == 0); + static struct mmu_ops { void (*tlb_init)(void); int (*mmu_mapin)(vm_offset_t va, vm_size_t len); @@ -84,11 +96,11 @@ static struct mmu_ops { typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, void *openfirmware); -static inline u_long dtlb_get_data_sun4u(int slot); -static void dtlb_enter_sun4u(u_long vpn, u_long data); +static inline u_long dtlb_get_data_sun4u(u_int); +static void dtlb_enter_sun4u(u_long, u_long); static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t); -static inline u_long itlb_get_data_sun4u(int slot); -static void itlb_enter_sun4u(u_long vpn, u_long data); +static inline u_long itlb_get_data_sun4u(u_int); +static void itlb_enter_sun4u(u_long, u_long); static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t); static void itlb_relocate_locked0_sun4u(void); extern vm_offset_t md_load(char *, vm_offset_t *); @@ -104,6 +116,9 @@ static int __elfN(exec)(struct preloaded_file *); static int mmu_mapin_sun4u(vm_offset_t, vm_size_t); static int mmu_mapin_sun4v(vm_offset_t, vm_size_t); static vm_offset_t init_heap(void); +static phandle_t find_bsp_sun4u(phandle_t, uint32_t); +const char *cpu_cpuid_prop_sun4u(void); +uint32_t cpu_get_mid_sun4u(void); static void tlb_init_sun4u(void); static void tlb_init_sun4v(void); @@ -120,11 +135,11 @@ static struct mmu_ops mmu_ops_sun4v = { tlb_init_sun4v, mmu_mapin_sun4v }; /* sun4u */ struct tlb_entry *dtlb_store; struct tlb_entry *itlb_store; -int dtlb_slot; -int itlb_slot; +u_int dtlb_slot; +u_int itlb_slot; int cpu_impl; -static int dtlb_slot_max; -static int itlb_slot_max; +static u_int dtlb_slot_max; +static u_int itlb_slot_max; /* sun4v */ static struct tlb_entry *tlb_store; @@ -398,7 +413,7 @@ __elfN(exec)(struct preloaded_file *fp) } static inline u_long -dtlb_get_data_sun4u(int slot) +dtlb_get_data_sun4u(u_int slot) { /* @@ -410,7 +425,7 @@ dtlb_get_data_sun4u(int slot) } static inline u_long -itlb_get_data_sun4u(int slot) +itlb_get_data_sun4u(u_int slot) { /* @@ -668,33 +683,98 @@ init_heap(void) return (heapva); } +static phandle_t +find_bsp_sun4u(phandle_t node, uint32_t bspid) +{ + char type[sizeof("cpu")]; + phandle_t child; + uint32_t cpuid; + + for (; node > 0; node = OF_peer(node)) { + child = OF_child(node); + if (child > 0) { + child = find_bsp_sun4u(child, bspid); + if (child > 0) + return (child); + } else { + if (OF_getprop(node, "device_type", type, + sizeof(type)) <= 0) + continue; + if (strcmp(type, "cpu") != 0) + continue; + if (OF_getprop(node, cpu_cpuid_prop_sun4u(), &cpuid, + sizeof(cpuid)) <= 0) + continue; + if (cpuid == bspid) + return (node); + } + } + return (0); +} + +const char * +cpu_cpuid_prop_sun4u(void) +{ + + switch (cpu_impl) { + case CPU_IMPL_SPARC64: + case CPU_IMPL_ULTRASPARCI: + case CPU_IMPL_ULTRASPARCII: + case CPU_IMPL_ULTRASPARCIIi: + case CPU_IMPL_ULTRASPARCIIe: + return ("upa-portid"); + case CPU_IMPL_ULTRASPARCIII: + case CPU_IMPL_ULTRASPARCIIIp: + case CPU_IMPL_ULTRASPARCIIIi: + case CPU_IMPL_ULTRASPARCIIIip: + return ("portid"); + case CPU_IMPL_ULTRASPARCIV: + case CPU_IMPL_ULTRASPARCIVp: + return ("cpuid"); + default: + return (""); + } +} + +uint32_t +cpu_get_mid_sun4u(void) +{ + + switch (cpu_impl) { + case CPU_IMPL_SPARC64: + case CPU_IMPL_ULTRASPARCI: + case CPU_IMPL_ULTRASPARCII: + case CPU_IMPL_ULTRASPARCIIi: + case CPU_IMPL_ULTRASPARCIIe: + return (UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG))); + case CPU_IMPL_ULTRASPARCIII: + case CPU_IMPL_ULTRASPARCIIIp: + return (FIREPLANE_CR_GET_AID(ldxa(AA_FIREPLANE_CONFIG, + ASI_FIREPLANE_CONFIG_REG))); + case CPU_IMPL_ULTRASPARCIIIi: + case CPU_IMPL_ULTRASPARCIIIip: + return (JBUS_CR_GET_JID(ldxa(0, ASI_JBUS_CONFIG_REG))); + case CPU_IMPL_ULTRASPARCIV: + case CPU_IMPL_ULTRASPARCIVp: + return (INTR_ID_GET_ID(ldxa(AA_INTR_ID, ASI_INTR_ID))); + default: + return (0); + } +} + static void tlb_init_sun4u(void) { - phandle_t child; - char buf[128]; - u_int bootcpu; - u_int cpu; + phandle_t bsp; cpu_impl = VER_IMPL(rdpr(ver)); - bootcpu = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); - for (child = OF_child(root); child != 0; child = OF_peer(child)) { - if (OF_getprop(child, "device_type", buf, sizeof(buf)) <= 0) - continue; - if (strcmp(buf, "cpu") != 0) - continue; - if (OF_getprop(child, cpu_impl < CPU_IMPL_ULTRASPARCIII ? - "upa-portid" : "portid", &cpu, sizeof(cpu)) <= 0) - continue; - if (cpu == bootcpu) - break; - } - if (cpu != bootcpu) + bsp = find_bsp_sun4u(OF_child(root), cpu_get_mid_sun4u()); + if (bsp == 0) panic("%s: no node for bootcpu?!?!", __func__); - if (OF_getprop(child, "#dtlb-entries", &dtlb_slot_max, + if (OF_getprop(bsp, "#dtlb-entries", &dtlb_slot_max, sizeof(dtlb_slot_max)) == -1 || - OF_getprop(child, "#itlb-entries", &itlb_slot_max, + OF_getprop(bsp, "#itlb-entries", &itlb_slot_max, sizeof(itlb_slot_max)) == -1) panic("%s: can't get TLB slot max.", __func__); @@ -749,14 +829,15 @@ main(int (*openfirm)(void *)) archsw.arch_autoload = sparc64_autoload; archsw.arch_maphint = sparc64_maphint; - init_heap(); - setheap((void *)heapva, (void *)(heapva + HEAPSZ)); - /* * Probe for a console. */ cons_probe(); + if (init_heap() == (vm_offset_t)-1) + panic("%s: can't claim heap", __func__); + setheap((void *)heapva, (void *)(heapva + HEAPSZ)); + if ((root = OF_peer(0)) == -1) panic("%s: can't get root phandle", __func__); OF_getprop(root, "compatible", compatible, sizeof(compatible)); diff --git a/sys/sparc64/include/asi.h b/sys/sparc64/include/asi.h index 93713783011..90dc3f394e1 100644 --- a/sys/sparc64/include/asi.h +++ b/sys/sparc64/include/asi.h @@ -33,7 +33,7 @@ #define _MACHINE_ASI_H_ /* - * Standard v9 asis + * Standard v9 ASIs */ #define ASI_N 0x4 #define ASI_NL 0xc @@ -51,7 +51,7 @@ #define ASI_SNFL 0x8b /* - * UltraSPARC extensions. ASIs limited to a certain family are annotated. + * UltraSPARC extensions - ASIs limited to a certain family are annotated. */ #define ASI_PHYS_USE_EC 0x14 #define ASI_PHYS_BYPASS_EC_WITH_EBIT 0x15 @@ -91,9 +91,12 @@ #define ASI_INTR_RECEIVE 0x49 #define ASI_UPA_CONFIG_REG 0x4a /* US-I, II */ -#define ASI_FIREPLANE_CONFIG_REG 0x4a /* US-III Cu */ -#define AA_FIREPLANE_CONFIG 0x0 /* US-III Cu */ -#define AA_FIREPLANE_ADDRESS 0x8 /* US-III Cu */ +#define ASI_FIREPLANE_CONFIG_REG 0x4a /* US-III{,+}, IV{,+} */ +#define AA_FIREPLANE_CONFIG 0x0 /* US-III{,+}, IV{,+} */ +#define AA_FIREPLANE_ADDRESS 0x8 /* US-III{,+}, IV{,+} */ +#define AA_FIREPLANE_CONFIG_2 0x10 /* US-IV{,+} */ + +#define ASI_JBUS_CONFIG_REG 0x4a /* US-IIIi{,+} */ #define ASI_ESTATE_ERROR_EN_REG 0x4b #define AA_ESTATE_CEEN 0x1 @@ -153,6 +156,11 @@ #define ASI_IIU_INST_TRAP 0x60 /* US-III family */ +#define ASI_INTR_ID 0x63 /* US-IV{,+} */ +#define AA_INTR_ID 0x0 /* US-IV{,+} */ +#define AA_CORE_ID 0x10 /* US-IV{,+} */ +#define AA_CESR_ID 0x40 /* US-IV{,+} */ + #define ASI_ICACHE_INSTR 0x66 #define ASI_ICACHE_TAG 0x67 #define ASI_ICACHE_SNOOP_TAG 0x68 /* US-III family */ @@ -179,7 +187,7 @@ /* * With the advent of the US-III, the numbering has changed, as additional - * registers were inserted in between. We retain the original ordering for + * registers were inserted in between. We retain the original ordering for * now, and append an A to the inserted registers. * Exceptions are AA_SDB_INTR_D6 and AA_SDB_INTR_D7, which were appended * at the end. diff --git a/sys/sparc64/include/cmt.h b/sys/sparc64/include/cmt.h new file mode 100644 index 00000000000..cdeed29c61c --- /dev/null +++ b/sys/sparc64/include/cmt.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2010 Marius Strobl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_CMT_H_ +#define _MACHINE_CMT_H_ + +#define INTR_ID_ID_SHIFT (0) +#define INTR_ID_ID_SIZE (10) +#define INTR_ID_ID_MASK \ + (((1 << INTR_ID_ID_SIZE) - 1) << INTR_ID_ID_SHIFT) + +#define INTR_ID_GET_ID(cr) ((cr & INTR_ID_ID_MASK) >> INTR_ID_ID_SHIFT) + +#endif /* _MACHINE_CMT_H_ */ diff --git a/sys/sparc64/include/fireplane.h b/sys/sparc64/include/fireplane.h new file mode 100644 index 00000000000..83489545d40 --- /dev/null +++ b/sys/sparc64/include/fireplane.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2010 Marius Strobl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_FIREPLANE_H_ +#define _MACHINE_FIREPLANE_H_ + +#define FIREPLANE_CR_AID_SHIFT (17) +#define FIREPLANE_CR_AID_SIZE (10) +#define FIREPLANE_CR_AID_MASK \ + (((1 << FIREPLANE_CR_AID_SIZE) - 1) << FIREPLANE_CR_AID_SHIFT) + +#define FIREPLANE_CR_GET_AID(cr) \ + ((cr & FIREPLANE_CR_AID_MASK) >> FIREPLANE_CR_AID_SHIFT) + +#endif /* _MACHINE_FIREPLANE_H_ */ diff --git a/sys/sparc64/include/jbus.h b/sys/sparc64/include/jbus.h new file mode 100644 index 00000000000..09c93b4c635 --- /dev/null +++ b/sys/sparc64/include/jbus.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2010 Marius Strobl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_JBUS_H_ +#define _MACHINE_JBUS_H_ + +#define JBUS_CR_JID_SHIFT (17) +#define JBUS_CR_JID_SIZE (3) +#define JBUS_CR_JID_MASK \ + (((1 << JBUS_CR_JID_SIZE) - 1) << JBUS_CR_JID_SHIFT) + +#define JBUS_CR_GET_JID(cr) ((cr & JBUS_CR_JID_MASK) >> JBUS_CR_JID_SHIFT) + +#endif /* _MACHINE_JBUS_H_ */ diff --git a/sys/sun4v/include/asi.h b/sys/sun4v/include/asi.h index 07b097b9338..e37785993c0 100644 --- a/sys/sun4v/include/asi.h +++ b/sys/sun4v/include/asi.h @@ -158,6 +158,11 @@ #define AA_DMMU_TAR 0x30 #define ASI_UPA_CONFIG_REG 0x4a /* US-I, II */ +#define ASI_FIREPLANE_CONFIG_REG 0x4a /* US-III{,+}, IV{,+} */ +#define AA_FIREPLANE_CONFIG 0x0 /* US-III{,+}, IV{,+} */ +#define AA_FIREPLANE_ADDRESS 0x8 /* US-III{,+}, IV{,+} */ +#define AA_FIREPLANE_CONFIG_2 0x10 /* US-IV{,+} */ +#define ASI_JBUS_CONFIG_REG 0x4a /* US-IIIi{,+} */ #define ASI_IMMU 0x50 #define ASI_ITLB_DATA_IN_REG 0x54 #define ASI_ITLB_DATA_ACCESS_REG 0x55 @@ -167,5 +172,7 @@ #define ASI_DTLB_DATA_IN_REG 0x5c #define ASI_DTLB_DATA_ACCESS_REG 0x5d #define ASI_DTLB_TAG_READ_REG 0x5e +#define ASI_INTR_ID 0x63 /* US-IV{,+} */ +#define AA_INTR_ID 0x0 /* US-IV{,+} */ #endif /* !_MACHINE_ASI_H_ */ diff --git a/sys/sun4v/include/cmt.h b/sys/sun4v/include/cmt.h new file mode 100644 index 00000000000..4fddc63d21f --- /dev/null +++ b/sys/sun4v/include/cmt.h @@ -0,0 +1,7 @@ +/*- + * This file is in the public domain. + * + * $FreeBSD$ + */ + +#include diff --git a/sys/sun4v/include/fireplane.h b/sys/sun4v/include/fireplane.h new file mode 100644 index 00000000000..7c81412db3e --- /dev/null +++ b/sys/sun4v/include/fireplane.h @@ -0,0 +1,7 @@ +/*- + * This file is in the public domain. + * + * $FreeBSD$ + */ + +#include diff --git a/sys/sun4v/include/jbus.h b/sys/sun4v/include/jbus.h new file mode 100644 index 00000000000..502f7851e40 --- /dev/null +++ b/sys/sun4v/include/jbus.h @@ -0,0 +1,7 @@ +/*- + * This file is in the public domain. + * + * $FreeBSD$ + */ + +#include From 935f345ea42a5241d43e3cd4dffc83a25732daee Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 20:05:20 +0000 Subject: [PATCH 1764/2592] MFC: r203830, r203831 Use the SUNW,{d,i}tlb-load methods for entering locked TLB entries like OpenBSD and OpenSolaris do instead of fiddling with the MMUs ourselves. Unlike direct access the firmware methods don't automatically use the next free (?) TLB slot, instead the slot to be used has to be specified. We allocate the TLB slots for the kernel top-down as OpenSolaris suggests that the firmware will always allocate the ones for its own use bottom-up. Besides being simpler, according to OpenBSD using the firmware methods is required to allow booting on Sun Fire E10K with multi-systemboard domains. --- sys/boot/sparc64/loader/main.c | 74 ++++++++++++---------------------- 1 file changed, 26 insertions(+), 48 deletions(-) diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c index 4c869dae67c..72041694f01 100644 --- a/sys/boot/sparc64/loader/main.c +++ b/sys/boot/sparc64/loader/main.c @@ -97,10 +97,10 @@ typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, void *openfirmware); static inline u_long dtlb_get_data_sun4u(u_int); -static void dtlb_enter_sun4u(u_long, u_long); +static int dtlb_enter_sun4u(u_int, u_long data, vm_offset_t); static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t); static inline u_long itlb_get_data_sun4u(u_int); -static void itlb_enter_sun4u(u_long, u_long); +static int itlb_enter_sun4u(u_int, u_long data, vm_offset_t); static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t); static void itlb_relocate_locked0_sun4u(void); extern vm_offset_t md_load(char *, vm_offset_t *); @@ -482,55 +482,24 @@ itlb_va_to_pa_sun4u(vm_offset_t va) return (-1); } -static void -dtlb_enter_sun4u(u_long vpn, u_long data) +static int +dtlb_enter_sun4u(u_int index, u_long data, vm_offset_t virt) { - u_long reg; - reg = rdpr(pstate); - wrpr(pstate, reg & ~PSTATE_IE, 0); - stxa(AA_DMMU_TAR, ASI_DMMU, - TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); - stxa(0, ASI_DTLB_DATA_IN_REG, data); - membar(Sync); - wrpr(pstate, reg, 0); + return (OF_call_method("SUNW,dtlb-load", mmu, 3, 0, index, data, + virt)); } -static void -itlb_enter_sun4u(u_long vpn, u_long data) +static int +itlb_enter_sun4u(u_int index, u_long data, vm_offset_t virt) { - u_long reg; - int i; - reg = rdpr(pstate); - wrpr(pstate, reg & ~PSTATE_IE, 0); - - if (cpu_impl == CPU_IMPL_ULTRASPARCIIIp) { - /* - * Search an unused slot != 0 and explicitly enter the data - * and tag there in order to avoid Cheetah+ erratum 34. - */ - for (i = 1; i < itlb_slot_max; i++) { - if ((itlb_get_data_sun4u(i) & TD_V) != 0) - continue; - - stxa(AA_IMMU_TAR, ASI_IMMU, - TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); - stxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG, data); - flush(PROMBASE); - break; - } - wrpr(pstate, reg, 0); - if (i == itlb_slot_max) - panic("%s: could not find an unused slot", __func__); - return; - } - - stxa(AA_IMMU_TAR, ASI_IMMU, - TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); - stxa(0, ASI_ITLB_DATA_IN_REG, data); - flush(PROMBASE); - wrpr(pstate, reg, 0); + if (cpu_impl == CPU_IMPL_ULTRASPARCIIIp && index == 0 && + (data & TD_L) != 0) + panic("%s: won't enter locked TLB entry at index 0 on USIII+", + __func__); + return (OF_call_method("SUNW,itlb-load", mmu, 3, 0, index, data, + virt)); } static void @@ -580,6 +549,7 @@ mmu_mapin_sun4u(vm_offset_t va, vm_size_t len) { vm_offset_t pa, mva; u_long data; + u_int index; if (va + len > curkva) curkva = va + len; @@ -617,12 +587,20 @@ mmu_mapin_sun4u(vm_offset_t va, vm_size_t len) TD_CV | TD_P | TD_W; dtlb_store[dtlb_slot].te_pa = pa; dtlb_store[dtlb_slot].te_va = va; + index = dtlb_slot_max - dtlb_slot - 1; + if (dtlb_enter_sun4u(index, data, va) < 0) + panic("%s: can't enter dTLB slot %d data " + "%#lx va %#lx", __func__, index, data, + va); + dtlb_slot++; itlb_store[itlb_slot].te_pa = pa; itlb_store[itlb_slot].te_va = va; - dtlb_slot++; + index = itlb_slot_max - itlb_slot - 1; + if (itlb_enter_sun4u(index, data, va) < 0) + panic("%s: can't enter iTLB slot %d data " + "%#lx va %#lxd", __func__, index, data, + va); itlb_slot++; - dtlb_enter_sun4u(va, data); - itlb_enter_sun4u(va, data); pa = (vm_offset_t)-1; } len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len; From c4adffba57a107166bdf28a7cf4f544e8534882d Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 20:12:42 +0000 Subject: [PATCH 1765/2592] MFC: r203833 - At least the trap table of the Sun Fire V1280 firmware apparently has no cleanwindows handler so just remove trying to trigger it from _start and the AP trampoline code as that leads to a crash there. This should be okay as leaking data from the OFW via the CPU registers on start of the kernel should be no real concern. - Make the comments of _start and the AP trampoline code regarding the initializations they perform match each other and reality. - Make the comments of the AP trampoline code regarding iTLB accesses refer to the right macro. --- sys/sparc64/sparc64/locore.S | 8 +++++--- sys/sparc64/sparc64/mp_locore.S | 16 +++++++++------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/sys/sparc64/sparc64/locore.S b/sys/sparc64/sparc64/locore.S index 8c1043e406f..ac6659b5c97 100644 --- a/sys/sparc64/sparc64/locore.S +++ b/sys/sparc64/sparc64/locore.S @@ -46,12 +46,14 @@ ENTRY(btext) ENTRY(_start) /* * Initialize misc. state to known values: interrupts disabled, normal - * globals, windows flushed (cr = 0, cs = nwindows - 1), no clean - * windows, pil 0, and floating point disabled. + * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL 0 and + * floating point disabled. + * Note that some firmware versions don't implement a clean window + * trap handler so we unfortunately can't clear the windows by setting + * %cleanwin to zero here. */ wrpr %g0, PSTATE_NORMAL, %pstate flushw - wrpr %g0, 0, %cleanwin wrpr %g0, 0, %pil wr %g0, 0, %fprs diff --git a/sys/sparc64/sparc64/mp_locore.S b/sys/sparc64/sparc64/mp_locore.S index e8b2a952633..b089a2ba9cf 100644 --- a/sys/sparc64/sparc64/mp_locore.S +++ b/sys/sparc64/sparc64/mp_locore.S @@ -44,12 +44,14 @@ __FBSDID("$FreeBSD$"); .text _ALIGN_TEXT /* - * Initialize misc. state to known values: interrupts disabled, - * normal globals, no clean windows, PIL 0, and floating point - * disabled. + * Initialize misc. state to known values: interrupts disabled, normal + * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL 0 and + * floating point disabled. + * Note that some firmware versions don't implement a clean window + * trap handler so we unfortunately can't clear the windows by setting + * %cleanwin to zero here. */ 1: wrpr %g0, PSTATE_NORMAL, %pstate - wrpr %g0, 0, %cleanwin wrpr %g0, 0, %pil wr %g0, 0, %fprs @@ -68,7 +70,7 @@ __FBSDID("$FreeBSD$"); setx TD_V | TD_L, %l1, %l0 /* - * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work + * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work * around errata of USIII and beyond. */ ldxa [%g0] ASI_ITLB_DATA_ACCESS_REG, %g0 @@ -94,7 +96,7 @@ __FBSDID("$FreeBSD$"); mov (1 << TLB_DAR_SLOT_SHIFT), %l4 setx TD_V, %l1, %l0 /* - * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work + * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work * around errata of USIII and beyond. */ 2: ldxa [%l4] ASI_ITLB_DATA_ACCESS_REG, %g0 @@ -136,7 +138,7 @@ __FBSDID("$FreeBSD$"); mov (1 << TLB_DAR_SLOT_SHIFT), %l0 setx TD_V, %o1, %o0 /* - * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work + * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work * around errata of USIII and beyond. */ 5: ldxa [%l0] ASI_ITLB_DATA_ACCESS_REG, %g0 From 96046876636eadb9e91fa96bf9a90fb9b5c6099f Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 20:29:45 +0000 Subject: [PATCH 1766/2592] MFC: r203838 - Search the whole OFW device tree instead of only the children of the root nexus device for the CPUs as starting with UltraSPARC IV the 'cpu' nodes hang off of from 'cmp' (chip multi-threading processor) or 'core' or combinations thereof. Also in large UltraSPARC III based machines the 'cpu' nodes hang off of 'ssm' (scalable shared memory) nodes which group snooping-coherency domains together instead of directly from the nexus. It would be great if we could use newbus to deal with the different ways the 'cpu' devices can hang off of pseudo ones but unfortunately both cpu_mp_setmaxid() and sparc64_init() have to work prior to regular device probing. - Add support for UltraSPARC IV and IV+ CPUs. Due to the fact that these are multi-core each CPU has two Fireplane config registers and thus the module/target ID has to be determined differently so the one specific to a certain core is used. Similarly, starting with UltraSPARC IV the individual cores use a different property in the OFW device tree to indicate the CPU/core ID as it no longer is in coincidence with the shared slot/socket ID. This involves changing the MD KTR code to not directly read the UPA module ID either. We use the MID stored in the per-CPU data instead of calling cpu_get_mid() as a replacement in order prevent clobbering any registers as side-effect in the assembler version. This requires CATR() invocations from mp_startup() prior to mapping the per-CPU pages to be removed though. While at it additionally distinguish between CPUs with Fireplane and JBus interconnects as these also use slightly different sizes for the JBus/agent/module/target IDs. - Make sparc64_shutdown_final() static as it's not used outside of machdep.c. --- sys/sparc64/include/ktr.h | 8 +- sys/sparc64/include/md_var.h | 2 + sys/sparc64/include/upa.h | 13 +-- sys/sparc64/sparc64/machdep.c | 111 ++++++++++++++++---- sys/sparc64/sparc64/mp_locore.S | 20 +--- sys/sparc64/sparc64/mp_machdep.c | 175 ++++++++++++++++++------------- 6 files changed, 201 insertions(+), 128 deletions(-) diff --git a/sys/sparc64/include/ktr.h b/sys/sparc64/include/ktr.h index 0b7e96a50ee..5948ba29fb3 100644 --- a/sys/sparc64/include/ktr.h +++ b/sys/sparc64/include/ktr.h @@ -34,11 +34,9 @@ #include -#include - #ifndef LOCORE -#define KTR_CPU UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)) +#define KTR_CPU PCPU_GET(mid) #else @@ -74,7 +72,7 @@ l2: add r2, 1, r3 ; \ add r1, r2, r1 ; \ rd %tick, r2 ; \ stx r2, [r1 + KTR_TIMESTAMP] ; \ - UPA_GET_MID(r2) ; \ + lduw [PCPU(MID)], r2 ; \ stw r2, [r1 + KTR_CPU] ; \ stw %g0, [r1 + KTR_LINE] ; \ stx %g0, [r1 + KTR_FILE] ; \ @@ -84,7 +82,7 @@ l2: add r2, 1, r3 ; \ #define CATR(mask, desc, r1, r2, r3, l1, l2, l3) \ set mask, r1 ; \ TEST(ktr_mask, r1, r2, r2, l3) ; \ - UPA_GET_MID(r1) ; \ + lduw [PCPU(MID)], r1 ; \ mov 1, r2 ; \ sllx r2, r1, r1 ; \ TEST(ktr_cpumask, r1, r2, r3, l3) ; \ diff --git a/sys/sparc64/include/md_var.h b/sys/sparc64/include/md_var.h index 69c6d698c5f..592d980f317 100644 --- a/sys/sparc64/include/md_var.h +++ b/sys/sparc64/include/md_var.h @@ -47,6 +47,8 @@ extern vm_paddr_t kstack0_phys; struct pcpu; struct md_utrap; +const char *cpu_cpuid_prop(void); +uint32_t cpu_get_mid(void); void cpu_identify(u_long vers, u_int clock, u_int id); void cpu_setregs(struct pcpu *pc); int is_physical_memory(vm_paddr_t addr); diff --git a/sys/sparc64/include/upa.h b/sys/sparc64/include/upa.h index 3e56917b638..43531cf6331 100644 --- a/sys/sparc64/include/upa.h +++ b/sys/sparc64/include/upa.h @@ -26,25 +26,16 @@ */ #ifndef _MACHINE_UPA_H_ -#define _MACHINE_UPA_H_ +#define _MACHINE_UPA_H_ #define UPA_MEMSTART 0x1c000000000UL #define UPA_MEMEND 0x1ffffffffffUL #define UPA_CR_MID_SHIFT (17) #define UPA_CR_MID_SIZE (5) -#define UPA_CR_MID_MASK \ +#define UPA_CR_MID_MASK \ (((1 << UPA_CR_MID_SIZE) - 1) << UPA_CR_MID_SHIFT) #define UPA_CR_GET_MID(cr) ((cr & UPA_CR_MID_MASK) >> UPA_CR_MID_SHIFT) -#ifdef LOCORE - -#define UPA_GET_MID(r1) \ - ldxa [%g0] ASI_UPA_CONFIG_REG, r1 ; \ - srlx r1, UPA_CR_MID_SHIFT, r1 ; \ - and r1, (1 << UPA_CR_MID_SIZE) - 1, r1 - -#endif - #endif /* _MACHINE_UPA_H_ */ diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index 06f6ebca8eb..eed7db8b3bb 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -89,10 +89,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include #include +#include #include #include #include @@ -143,11 +146,12 @@ static int cpu_use_vis = 1; cpu_block_copy_t *cpu_block_copy; cpu_block_zero_t *cpu_block_zero; +static phandle_t find_bsp(phandle_t node, uint32_t bspid); void sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec); -void sparc64_shutdown_final(void *dummy, int howto); +static void sparc64_shutdown_final(void *dummy, int howto); -static void cpu_startup(void *); +static void cpu_startup(void *arg); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); CTASSERT((1 << INT_SHIFT) == sizeof(int)); @@ -236,18 +240,94 @@ spinlock_exit(void) wrpr(pil, td->td_md.md_saved_pil, 0); } +static phandle_t +find_bsp(phandle_t node, uint32_t bspid) +{ + char type[sizeof("cpu")]; + phandle_t child; + uint32_t cpuid; + + for (; node != 0; node = OF_peer(node)) { + child = OF_child(node); + if (child > 0) { + child = find_bsp(child, bspid); + if (child > 0) + return (child); + } else { + if (OF_getprop(node, "device_type", type, + sizeof(type)) <= 0) + continue; + if (strcmp(type, "cpu") != 0) + continue; + if (OF_getprop(node, cpu_cpuid_prop(), &cpuid, + sizeof(cpuid)) <= 0) + continue; + if (cpuid == bspid) + return (node); + } + } + return (0); +} + +const char * +cpu_cpuid_prop(void) +{ + + switch (cpu_impl) { + case CPU_IMPL_SPARC64: + case CPU_IMPL_ULTRASPARCI: + case CPU_IMPL_ULTRASPARCII: + case CPU_IMPL_ULTRASPARCIIi: + case CPU_IMPL_ULTRASPARCIIe: + return ("upa-portid"); + case CPU_IMPL_ULTRASPARCIII: + case CPU_IMPL_ULTRASPARCIIIp: + case CPU_IMPL_ULTRASPARCIIIi: + case CPU_IMPL_ULTRASPARCIIIip: + return ("portid"); + case CPU_IMPL_ULTRASPARCIV: + case CPU_IMPL_ULTRASPARCIVp: + return ("cpuid"); + default: + return (""); + } +} + +uint32_t +cpu_get_mid(void) +{ + + switch (cpu_impl) { + case CPU_IMPL_SPARC64: + case CPU_IMPL_ULTRASPARCI: + case CPU_IMPL_ULTRASPARCII: + case CPU_IMPL_ULTRASPARCIIi: + case CPU_IMPL_ULTRASPARCIIe: + return (UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG))); + case CPU_IMPL_ULTRASPARCIII: + case CPU_IMPL_ULTRASPARCIIIp: + return (FIREPLANE_CR_GET_AID(ldxa(AA_FIREPLANE_CONFIG, + ASI_FIREPLANE_CONFIG_REG))); + case CPU_IMPL_ULTRASPARCIIIi: + case CPU_IMPL_ULTRASPARCIIIip: + return (JBUS_CR_GET_JID(ldxa(0, ASI_JBUS_CONFIG_REG))); + case CPU_IMPL_ULTRASPARCIV: + case CPU_IMPL_ULTRASPARCIVp: + return (INTR_ID_GET_ID(ldxa(AA_INTR_ID, ASI_INTR_ID))); + default: + return (0); + } +} + void sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) { - char type[8]; char *env; struct pcpu *pc; vm_offset_t end; vm_offset_t va; caddr_t kmdp; - phandle_t child; phandle_t root; - uint32_t portid; end = 0; kmdp = NULL; @@ -319,7 +399,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) pc = (struct pcpu *)(pcpu0 + (PCPU_PAGES * PAGE_SIZE)) - 1; pcpu_init(pc, 0, sizeof(struct pcpu)); pc->pc_addr = (vm_offset_t)pcpu0; - pc->pc_mid = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); + pc->pc_mid = cpu_get_mid(); pc->pc_tlb_ctx = TLB_CTX_USER_MIN; pc->pc_tlb_ctx_min = TLB_CTX_USER_MIN; pc->pc_tlb_ctx_max = TLB_CTX_USER_MAX; @@ -328,24 +408,11 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) * Determine the OFW node and frequency of the BSP (and ensure the * BSP is in the device tree in the first place). */ - pc->pc_node = 0; root = OF_peer(0); - for (child = OF_child(root); child != 0; child = OF_peer(child)) { - if (OF_getprop(child, "device_type", type, sizeof(type)) <= 0) - continue; - if (strcmp(type, "cpu") != 0) - continue; - if (OF_getprop(child, cpu_impl < CPU_IMPL_ULTRASPARCIII ? - "upa-portid" : "portid", &portid, sizeof(portid)) <= 0) - continue; - if (portid == pc->pc_mid) { - pc->pc_node = child; - break; - } - } + pc->pc_node = find_bsp(root, pc->pc_mid); if (pc->pc_node == 0) OF_exit(); - if (OF_getprop(child, "clock-frequency", &pc->pc_clock, + if (OF_getprop(pc->pc_node, "clock-frequency", &pc->pc_clock, sizeof(pc->pc_clock)) <= 0) OF_exit(); @@ -838,7 +905,7 @@ cpu_halt(void) cpu_shutdown(&args); } -void +static void sparc64_shutdown_final(void *dummy, int howto) { static struct { diff --git a/sys/sparc64/sparc64/mp_locore.S b/sys/sparc64/sparc64/mp_locore.S index b089a2ba9cf..96239d5bca0 100644 --- a/sys/sparc64/sparc64/mp_locore.S +++ b/sys/sparc64/sparc64/mp_locore.S @@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include "assym.s" @@ -212,14 +211,8 @@ ENTRY(mp_startup) nop wr %l1, 0, %asr24 -3: UPA_GET_MID(%o0) - -#if KTR_COMPILE & KTR_SMP - CATR(KTR_SMP, "mp_start: CPU %d entered kernel" - , %g1, %g2, %g3, 7, 8, 9) - stx %o0, [%g1 + KTR_PARM1] -9: -#endif +3: call cpu_get_mid + nop /* * Inform the boot processor we have inited. @@ -236,13 +229,6 @@ ENTRY(mp_startup) bne %xcc, 4b nop -#if KTR_COMPILE & KTR_SMP - CATR(KTR_SMP, "_mp_start: CPU %d got start signal" - , %g1, %g2, %g3, 7, 8, 9) - stx %o0, [%g1 + KTR_PARM1] -9: -#endif - add %l0, CSA_TTES, %l1 clr %l2 @@ -283,7 +269,7 @@ ENTRY(mp_startup) #if KTR_COMPILE & KTR_SMP CATR(KTR_SMP, - "_mp_start: bootstrap cpuid=%d mid=%d pcpu=%#lx data=%#lx sp=%#lx" + "mp_startup: bootstrap cpuid=%d mid=%d pcpu=%#lx data=%#lx sp=%#lx" , %g1, %g2, %g3, 7, 8, 9) lduw [%l1 + PC_CPUID], %g2 stx %g2, [%g1 + KTR_PARM1] diff --git a/sys/sparc64/sparc64/mp_machdep.c b/sys/sparc64/sparc64/mp_machdep.c index 997f0a4195e..8e9f9e1baa6 100644 --- a/sys/sparc64/sparc64/mp_machdep.c +++ b/sys/sparc64/sparc64/mp_machdep.c @@ -119,7 +119,11 @@ static u_int cpuid_to_mid[MAXCPU]; static int isjbus; static volatile u_int shutdown_cpus; +static void ap_count(phandle_t node, u_int mid); +static void ap_start(phandle_t node, u_int mid); static void cpu_mp_unleash(void *v); +static void foreach_ap(phandle_t node, void (*func)(phandle_t node, + u_int mid)); static void spitfire_ipi_send(u_int mid, u_long d0, u_long d1, u_long d2); static void sun4u_startcpu(phandle_t cpu, void *func, u_long arg); @@ -166,25 +170,56 @@ mp_init(void) cpu_ipi_selected = spitfire_ipi_selected; } +static void +foreach_ap(phandle_t node, void (*func)(phandle_t node, u_int mid)) +{ + char type[sizeof("cpu")]; + phandle_t child; + u_int cpuid; + + /* There's no need to traverse the whole OFW tree twice. */ + if (mp_maxid > 0 && mp_ncpus >= mp_maxid + 1) + return; + + for (; node != 0; node = OF_peer(node)) { + child = OF_child(node); + if (child > 0) + foreach_ap(child, func); + else { + if (OF_getprop(node, "device_type", type, + sizeof(type)) <= 0) + continue; + if (strcmp(type, "cpu") != 0) + continue; + if (OF_getprop(node, cpu_cpuid_prop(), &cpuid, + sizeof(cpuid)) <= 0) + panic("%s: can't get module ID", __func__); + if (cpuid == PCPU_GET(mid)) + continue; + (*func)(node, cpuid); + } + } +} + /* * Probe for other CPUs. */ void -cpu_mp_setmaxid(void) +cpu_mp_setmaxid() { - char buf[128]; - phandle_t child; - u_int cpus; all_cpus = 1 << curcpu; mp_ncpus = 1; + mp_maxid = 0; - cpus = 0; - for (child = OF_child(OF_peer(0)); child != 0; child = OF_peer(child)) - if (OF_getprop(child, "device_type", buf, sizeof(buf)) > 0 && - strcmp(buf, "cpu") == 0) - cpus++; - mp_maxid = cpus - 1; + foreach_ap(OF_child(OF_peer(0)), ap_count); +} + +static void +ap_count(phandle_t node __unused, u_int mid __unused) +{ + + mp_maxid++; } int @@ -228,15 +263,6 @@ sun4u_startcpu(phandle_t cpu, void *func, u_long arg) void cpu_mp_start(void) { - char buf[128]; - volatile struct cpu_start_args *csa; - struct pcpu *pc; - register_t s; - vm_offset_t va; - phandle_t child; - u_int mid; - u_int clock; - u_int cpuid; mtx_init(&ipi_mtx, "ipi", NULL, MTX_SPIN); @@ -248,60 +274,7 @@ cpu_mp_start(void) cpuid_to_mid[curcpu] = PCPU_GET(mid); - csa = &cpu_start_args; - for (child = OF_child(OF_peer(0)); child != 0 && mp_ncpus <= MAXCPU; - child = OF_peer(child)) { - if (OF_getprop(child, "device_type", buf, sizeof(buf)) <= 0 || - strcmp(buf, "cpu") != 0) - continue; - if (OF_getprop(child, cpu_impl < CPU_IMPL_ULTRASPARCIII ? - "upa-portid" : "portid", &mid, sizeof(mid)) <= 0) - panic("%s: can't get module ID", __func__); - if (mid == PCPU_GET(mid)) - continue; - if (OF_getprop(child, "clock-frequency", &clock, - sizeof(clock)) <= 0) - panic("%s: can't get clock", __func__); - if (clock != PCPU_GET(clock)) - hardclock_use_stick = 1; - - csa->csa_state = 0; - sun4u_startcpu(child, (void *)mp_tramp, 0); - s = intr_disable(); - while (csa->csa_state != CPU_TICKSYNC) - ; - membar(StoreLoad); - csa->csa_tick = rd(tick); - if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) { - while (csa->csa_state != CPU_STICKSYNC) - ; - membar(StoreLoad); - csa->csa_stick = rdstick(); - } - while (csa->csa_state != CPU_INIT) - ; - csa->csa_tick = csa->csa_stick = 0; - intr_restore(s); - - cpuid = mp_ncpus++; - cpuid_to_mid[cpuid] = mid; - cpu_identify(csa->csa_ver, clock, cpuid); - - va = kmem_alloc(kernel_map, PCPU_PAGES * PAGE_SIZE); - pc = (struct pcpu *)(va + (PCPU_PAGES * PAGE_SIZE)) - 1; - pcpu_init(pc, cpuid, sizeof(*pc)); - dpcpu_init((void *)kmem_alloc(kernel_map, DPCPU_SIZE), - cpuid); - pc->pc_addr = va; - pc->pc_clock = clock; - pc->pc_mid = mid; - pc->pc_node = child; - - cache_init(pc); - - all_cpus |= 1 << cpuid; - intr_add_cpu(cpuid); - } + foreach_ap(OF_child(OF_peer(0)), ap_start); KASSERT(!isjbus || mp_ncpus <= IDR_JALAPENO_MAX_BN_PAIRS, ("%s: can only IPI a maximum of %d JBus-CPUs", __func__, IDR_JALAPENO_MAX_BN_PAIRS)); @@ -309,6 +282,62 @@ cpu_mp_start(void) smp_active = 1; } +static void +ap_start(phandle_t node, u_int mid) +{ + volatile struct cpu_start_args *csa; + struct pcpu *pc; + register_t s; + vm_offset_t va; + u_int clock; + u_int cpuid; + + if (mp_ncpus > MAXCPU) + return; + + if (OF_getprop(node, "clock-frequency", &clock, sizeof(clock)) <= 0) + panic("%s: can't get clock", __func__); + if (clock != PCPU_GET(clock)) + hardclock_use_stick = 1; + + csa = &cpu_start_args; + csa->csa_state = 0; + sun4u_startcpu(node, (void *)mp_tramp, 0); + s = intr_disable(); + while (csa->csa_state != CPU_TICKSYNC) + ; + membar(StoreLoad); + csa->csa_tick = rd(tick); + if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) { + while (csa->csa_state != CPU_STICKSYNC) + ; + membar(StoreLoad); + csa->csa_stick = rdstick(); + } + while (csa->csa_state != CPU_INIT) + ; + csa->csa_tick = csa->csa_stick = 0; + intr_restore(s); + + cpuid = mp_ncpus++; + cpuid_to_mid[cpuid] = mid; + cpu_identify(csa->csa_ver, clock, cpuid); + + va = kmem_alloc(kernel_map, PCPU_PAGES * PAGE_SIZE); + pc = (struct pcpu *)(va + (PCPU_PAGES * PAGE_SIZE)) - 1; + pcpu_init(pc, cpuid, sizeof(*pc)); + dpcpu_init((void *)kmem_alloc(kernel_map, DPCPU_SIZE), cpuid); + pc->pc_addr = va; + pc->pc_clock = clock; + pc->pc_mid = mid; + pc->pc_node = node; + + cache_init(pc); + + all_cpus |= 1 << cpuid; + intr_add_cpu(cpuid); +} + void cpu_mp_announce(void) { From ceaf6ad0fa3d4bcbeab65d4e5af12828f840a889 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 20:38:18 +0000 Subject: [PATCH 1767/2592] MFC: r203839 Style fixes --- sys/sparc64/sparc64/pmap.c | 42 ++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index 664a856d6ad..bc2d4a1b14b 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -241,6 +241,7 @@ PMAP_STATS_VAR(pmap_nnew_thread_oc); */ static int mr_cmp(const void *a, const void *b); static int om_cmp(const void *a, const void *b); + static int mr_cmp(const void *a, const void *b) { @@ -256,6 +257,7 @@ mr_cmp(const void *a, const void *b) else return (0); } + static int om_cmp(const void *a, const void *b) { @@ -1111,10 +1113,9 @@ pmap_release(pmap_t pm) * to a kernel thread, leaving the pmap pointer unchanged. */ mtx_lock_spin(&sched_lock); - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) if (pc->pc_pmap == pm) pc->pc_pmap = NULL; - } mtx_unlock_spin(&sched_lock); obj = pm->pm_tsb_obj; @@ -1150,7 +1151,7 @@ pmap_growkernel(vm_offset_t addr) int pmap_remove_tte(struct pmap *pm, struct pmap *pm2, struct tte *tp, - vm_offset_t va) + vm_offset_t va) { vm_page_t m; u_long data; @@ -1198,12 +1199,10 @@ pmap_remove(pmap_t pm, vm_offset_t start, vm_offset_t end) tsb_foreach(pm, NULL, start, end, pmap_remove_tte); tlb_context_demap(pm); } else { - for (va = start; va < end; va += PAGE_SIZE) { - if ((tp = tsb_tte_lookup(pm, va)) != NULL) { - if (!pmap_remove_tte(pm, NULL, tp, va)) - break; - } - } + for (va = start; va < end; va += PAGE_SIZE) + if ((tp = tsb_tte_lookup(pm, va)) != NULL && + !pmap_remove_tte(pm, NULL, tp, va)) + break; tlb_range_demap(pm, start, end - 1); } PMAP_UNLOCK(pm); @@ -1245,7 +1244,7 @@ pmap_remove_all(vm_page_t m) int pmap_protect_tte(struct pmap *pm, struct pmap *pm2, struct tte *tp, - vm_offset_t va) + vm_offset_t va) { u_long data; vm_page_t m; @@ -1287,10 +1286,9 @@ pmap_protect(pmap_t pm, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) tsb_foreach(pm, NULL, sva, eva, pmap_protect_tte); tlb_context_demap(pm); } else { - for (va = sva; va < eva; va += PAGE_SIZE) { + for (va = sva; va < eva; va += PAGE_SIZE) if ((tp = tsb_tte_lookup(pm, va)) != NULL) pmap_protect_tte(pm, NULL, tp, va); - } tlb_range_demap(pm, sva, eva - 1); } PMAP_UNLOCK(pm); @@ -1386,21 +1384,18 @@ pmap_enter_locked(pmap_t pm, vm_offset_t va, vm_page_t m, vm_prot_t prot, */ if ((prot & VM_PROT_WRITE) != 0) { tp->tte_data |= TD_SW; - if (wired) { + if (wired) tp->tte_data |= TD_W; - } vm_page_flag_set(m, PG_WRITEABLE); - } else if ((data & TD_W) != 0) { + } else if ((data & TD_W) != 0) vm_page_dirty(m); - } /* * If we're turning on execute permissions, flush the icache. */ if ((prot & VM_PROT_EXECUTE) != 0) { - if ((data & TD_EXEC) == 0) { + if ((data & TD_EXEC) == 0) icache_page_inval(pa); - } tp->tte_data |= TD_EXEC; } @@ -1495,7 +1490,7 @@ pmap_enter_quick(pmap_t pm, vm_offset_t va, vm_page_t m, vm_prot_t prot) void pmap_object_init_pt(pmap_t pm, vm_offset_t addr, vm_object_t object, - vm_pindex_t pindex, vm_size_t size) + vm_pindex_t pindex, vm_size_t size) { VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); @@ -1529,7 +1524,8 @@ pmap_change_wiring(pmap_t pm, vm_offset_t va, boolean_t wired) } static int -pmap_copy_tte(pmap_t src_pmap, pmap_t dst_pmap, struct tte *tp, vm_offset_t va) +pmap_copy_tte(pmap_t src_pmap, pmap_t dst_pmap, struct tte *tp, + vm_offset_t va) { vm_page_t m; u_long data; @@ -1567,10 +1563,9 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, pmap_copy_tte); tlb_context_demap(dst_pmap); } else { - for (va = src_addr; va < src_addr + len; va += PAGE_SIZE) { + for (va = src_addr; va < src_addr + len; va += PAGE_SIZE) if ((tp = tsb_tte_lookup(src_pmap, va)) != NULL) pmap_copy_tte(src_pmap, dst_pmap, tp, va); - } tlb_range_demap(dst_pmap, src_addr, src_addr + len - 1); } vm_page_unlock_queues(); @@ -1823,10 +1818,9 @@ pmap_page_is_mapped(vm_page_t m) if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0) return (FALSE); mtx_assert(&vm_page_queue_mtx, MA_OWNED); - TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) { + TAILQ_FOREACH(tp, &m->md.tte_list, tte_link) if ((tp->tte_data & TD_PV) != 0) return (TRUE); - } return (FALSE); } From 306d372fa5279caba771a9e65ceb4565873413ee Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 20:39:47 +0000 Subject: [PATCH 1768/2592] MFC: r203843 Resurrect nexusvar.h from r167307. --- sys/sparc64/include/nexusvar.h | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 sys/sparc64/include/nexusvar.h diff --git a/sys/sparc64/include/nexusvar.h b/sys/sparc64/include/nexusvar.h new file mode 100644 index 00000000000..dd8ebfc73c3 --- /dev/null +++ b/sys/sparc64/include/nexusvar.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2001 by Thomas Moestl . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR 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 _MACHINE_NEXUSVAR_H_ +#define _MACHINE_NEXUSVAR_H_ + +enum nexus_ivars { + NEXUS_IVAR_NODE, + NEXUS_IVAR_NAME, + NEXUS_IVAR_DEVICE_TYPE, + NEXUS_IVAR_MODEL, + NEXUS_IVAR_REG, + NEXUS_IVAR_NREG, + NEXUS_IVAR_INTERRUPTS, + NEXUS_IVAR_NINTERRUPTS, + NEXUS_IVAR_DMATAG, +}; + +#define NEXUS_ACCESSOR(var, ivar, type) \ + __BUS_ACCESSOR(nexus, var, NEXUS, ivar, type) + +NEXUS_ACCESSOR(node, NODE, phandle_t) +NEXUS_ACCESSOR(name, NAME, char *) +NEXUS_ACCESSOR(device_type, DEVICE_TYPE, char *) +NEXUS_ACCESSOR(model, MODEL, char *) +NEXUS_ACCESSOR(reg, REG, struct upa_regs *) +NEXUS_ACCESSOR(nreg, NREG, int) +NEXUS_ACCESSOR(interrupts, INTERRUPTS, u_int *) +NEXUS_ACCESSOR(ninterrupts, NINTERRUPTS, int) +NEXUS_ACCESSOR(dmatag, DMATAG, bus_dma_tag_t) + +#undef NEXUS_ACCESSOR + +#endif /* _MACHINE_NEXUSVAR_H_ */ From 411fea736dc14be6e4bdd8207266c5604e1cd964 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 20:44:04 +0000 Subject: [PATCH 1769/2592] MFC: r203845 - Add the 'cmp' and 'core' pseudo-busses which are used to group CPU cores to the exclusion lists as the CPU nodes aren't handled as regular devices either. Also add the pseudo-devices found in Sun Fire V1280. - Allow nexus_attach() and nexus_alloc_resource() to be used by drivers derived from nexus(4) for subordinate busses. - Don't add the zero-sized memory resources of glue devices to the resource lists. --- sys/sparc64/include/nexusvar.h | 52 +++++++++------------------------- sys/sparc64/sparc64/nexus.c | 48 ++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 54 deletions(-) diff --git a/sys/sparc64/include/nexusvar.h b/sys/sparc64/include/nexusvar.h index dd8ebfc73c3..94c770c5650 100644 --- a/sys/sparc64/include/nexusvar.h +++ b/sys/sparc64/include/nexusvar.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2001 by Thomas Moestl . + * Copyright (c) 2010 Marius Strobl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,48 +11,24 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR OR 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. + * 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 _MACHINE_NEXUSVAR_H_ -#define _MACHINE_NEXUSVAR_H_ +#define _MACHINE_NEXUSVAR_H_ -enum nexus_ivars { - NEXUS_IVAR_NODE, - NEXUS_IVAR_NAME, - NEXUS_IVAR_DEVICE_TYPE, - NEXUS_IVAR_MODEL, - NEXUS_IVAR_REG, - NEXUS_IVAR_NREG, - NEXUS_IVAR_INTERRUPTS, - NEXUS_IVAR_NINTERRUPTS, - NEXUS_IVAR_DMATAG, -}; - -#define NEXUS_ACCESSOR(var, ivar, type) \ - __BUS_ACCESSOR(nexus, var, NEXUS, ivar, type) - -NEXUS_ACCESSOR(node, NODE, phandle_t) -NEXUS_ACCESSOR(name, NAME, char *) -NEXUS_ACCESSOR(device_type, DEVICE_TYPE, char *) -NEXUS_ACCESSOR(model, MODEL, char *) -NEXUS_ACCESSOR(reg, REG, struct upa_regs *) -NEXUS_ACCESSOR(nreg, NREG, int) -NEXUS_ACCESSOR(interrupts, INTERRUPTS, u_int *) -NEXUS_ACCESSOR(ninterrupts, NINTERRUPTS, int) -NEXUS_ACCESSOR(dmatag, DMATAG, bus_dma_tag_t) - -#undef NEXUS_ACCESSOR +DECLARE_CLASS(nexus_driver); #endif /* _MACHINE_NEXUSVAR_H_ */ diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c index 0f96a2101d3..6a88fa6872e 100644 --- a/sys/sparc64/sparc64/nexus.c +++ b/sys/sparc64/sparc64/nexus.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -154,17 +155,22 @@ static const char *const nexus_excl_name[] = { "aliases", "associations", "chosen", + "cmp", "counter-timer", /* No separate device; handled by psycho/sbus */ + "failsafe", "memory", "openprom", "options", "packages", "rsc", + "sgcn", + "todsg", "virtual-memory", NULL }; static const char *const nexus_excl_type[] = { + "core", "cpu", NULL }; @@ -206,20 +212,24 @@ nexus_attach(device_t dev) device_t cdev; phandle_t node; - node = OF_peer(0); - if (node == -1) - panic("%s: OF_peer failed.", __func__); + if (strcmp(device_get_name(device_get_parent(dev)), "root") == 0) { + node = OF_peer(0); + if (node == -1) + panic("%s: OF_peer failed.", __func__); - sc = device_get_softc(dev); - sc->sc_intr_rman.rm_type = RMAN_ARRAY; - sc->sc_intr_rman.rm_descr = "Interrupts"; - sc->sc_mem_rman.rm_type = RMAN_ARRAY; - sc->sc_mem_rman.rm_descr = "Device Memory"; - if (rman_init(&sc->sc_intr_rman) != 0 || - rman_init(&sc->sc_mem_rman) != 0 || - rman_manage_region(&sc->sc_intr_rman, 0, IV_MAX - 1) != 0 || - rman_manage_region(&sc->sc_mem_rman, 0ULL, ~0ULL) != 0) - panic("%s: failed to set up rmans.", __func__); + sc = device_get_softc(dev); + sc->sc_intr_rman.rm_type = RMAN_ARRAY; + sc->sc_intr_rman.rm_descr = "Interrupts"; + sc->sc_mem_rman.rm_type = RMAN_ARRAY; + sc->sc_mem_rman.rm_descr = "Device Memory"; + if (rman_init(&sc->sc_intr_rman) != 0 || + rman_init(&sc->sc_mem_rman) != 0 || + rman_manage_region(&sc->sc_intr_rman, 0, + IV_MAX - 1) != 0 || + rman_manage_region(&sc->sc_mem_rman, 0ULL, ~0ULL) != 0) + panic("%s: failed to set up rmans.", __func__); + } else + node = ofw_bus_get_node(dev); /* * Allow devices to identify. @@ -347,12 +357,16 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, struct rman *rm; struct resource *rv; struct resource_list_entry *rle; + device_t nexus; int isdefault, needactivate, passthrough; isdefault = (start == 0UL && end == ~0UL); needactivate = flags & RF_ACTIVE; passthrough = (device_get_parent(child) != bus); - sc = device_get_softc(bus); + nexus = bus; + while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0) + nexus = device_get_parent(nexus); + sc = device_get_softc(nexus); rle = NULL; if (!passthrough) { @@ -498,8 +512,10 @@ nexus_setup_dinfo(device_t dev, phandle_t node) for (i = 0; i < nreg; i++) { phys = NEXUS_REG_PHYS(®[i]); size = NEXUS_REG_SIZE(®[i]); - resource_list_add(&ndi->ndi_rl, SYS_RES_MEMORY, i, phys, - phys + size - 1, size); + /* Skip the dummy reg property of glue devices like ssm(4). */ + if (size != 0) + resource_list_add(&ndi->ndi_rl, SYS_RES_MEMORY, i, + phys, phys + size - 1, size); } free(reg, M_OFWPROP); From 8fcbb37733aa56d929aff5adad2976cdcb0bed0d Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 30 Mar 2010 20:46:10 +0000 Subject: [PATCH 1770/2592] MFC: r203846 Predict KASSERTs to be true. --- sys/sparc64/include/asmacros.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sparc64/include/asmacros.h b/sys/sparc64/include/asmacros.h index a0e317b218e..6d19a097f61 100644 --- a/sys/sparc64/include/asmacros.h +++ b/sys/sparc64/include/asmacros.h @@ -107,7 +107,7 @@ #ifdef INVARIANTS #define KASSERT(r1, msg) \ - brnz r1, 8f ; \ + brnz,pt r1, 8f ; \ nop ; \ PANIC(msg, r1) ; \ 8: From 73a0004b9d74e0d1d564787c119c8b3aca02defd Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 31 Mar 2010 00:41:32 +0000 Subject: [PATCH 1771/2592] MFC r204533: Add PCI ID for MCS9901. Submitted by: gcooper PR: kern/144397 --- sys/dev/uart/uart_bus_pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c index 06c6138b4af..9cad7bea7ef 100644 --- a/sys/dev/uart/uart_bus_pci.c +++ b/sys/dev/uart/uart_bus_pci.c @@ -112,6 +112,8 @@ static struct pci_id pci_ns8250_ids[] = { { 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 }, { 0x9710, 0x9835, 0x1000, 1, "NetMos NM9835 Serial Port", 0x10 }, { 0x9710, 0x9865, 0xa000, 0x1000, "NetMos NM9865 Serial Port", 0x10 }, +{ 0x9710, 0x9901, 0xa000, 0x1000, + "MosChip MCS9901 PCIe to Peripheral Controller", 0x10 }, { 0xdeaf, 0x9051, 0xffff, 0, "Middle Digital PC Weasel Serial Port", 0x10 }, { 0xffff, 0, 0xffff, 0, NULL, 0, 0} }; From 353be771388cfc4d47d5d58bd0b355343ec29619 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Wed, 31 Mar 2010 01:51:08 +0000 Subject: [PATCH 1772/2592] A last-minute change in the previous commit broke rule deletion, so i am fixing it, this time with a more detailed description of what the code is supposed to do. --- sys/netinet/ipfw/ip_fw_sockopt.c | 35 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/sys/netinet/ipfw/ip_fw_sockopt.c b/sys/netinet/ipfw/ip_fw_sockopt.c index d04b00b56ce..5f203eae6c6 100644 --- a/sys/netinet/ipfw/ip_fw_sockopt.c +++ b/sys/netinet/ipfw/ip_fw_sockopt.c @@ -239,12 +239,12 @@ ipfw_reap_rules(struct ip_fw *head) * The argument is an u_int32_t. The low 16 bit are the rule or set number, * the next 8 bits are the new set, the top 8 bits are the command: * - * 0 delete rules with given number - * 1 delete rules with given set number - * 2 move rules with given number to new set - * 3 move rules with given set number to new set - * 4 swap sets with given numbers - * 5 delete rules with given number and with given set number + * 0 delete rules numbered "rulenum" + * 1 delete rules in set "rulenum" + * 2 move rules "rulenum" to set "new_set" + * 3 move rules from set "rulenum" to set "new_set" + * 4 swap sets "rulenum" and "new_set" + * 5 delete rules "rulenum" and set "new_set" */ static int del_entry(struct ip_fw_chain *chain, u_int32_t arg) @@ -274,7 +274,7 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg) chain->reap = NULL; /* prepare for deletions */ switch (cmd) { - case 0: /* delete rules number N (N == 0 means all) */ + case 0: /* delete rules "rulenum" (rulenum == 0 matches all) */ case 1: /* delete all rules in set N */ case 5: /* delete rules with number N and set "new_set". */ @@ -287,7 +287,7 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg) if (cmd == 1) { /* look for a specific set, must scan all */ new_set = rulenum; for (start = -1, i = 0; i < chain->n_rules; i++) { - if (chain->map[i]->set != rulenum) + if (chain->map[i]->set != new_set) continue; if (start < 0) start = i; @@ -321,16 +321,21 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg) * and then bcopy the final part. * Once we are done we can swap maps and clean up the * deleted rules (unfortunately we need to repeat a - * convoluted test). + * convoluted test). Rules to keep are + * (set == RESVD_SET || !match_set || !match_rule) + * where + * match_set ::= (cmd == 0 || rule->set == new_set) + * match_rule ::= (cmd == 1 || rule->rulenum == rulenum) */ if (start > 0) bcopy(chain->map, map, start * sizeof(struct ip_fw *)); for (i = ofs = start; i < end; i++) { rule = chain->map[i]; - if (rule->set == RESVD_SET || cmd == 0 || - (rule->set == new_set && - (cmd == 1 || rule->rulenum == rulenum))) + if (rule->set == RESVD_SET || + !(cmd == 0 || rule->set == new_set) || + !(cmd == 1 || rule->rulenum == rulenum) ) { map[ofs++] = chain->map[i]; + } } bcopy(chain->map + end, map + ofs, (chain->n_rules - end) * sizeof(struct ip_fw *)); @@ -341,9 +346,9 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg) int l; rule = map[i]; /* same test as above */ - if (rule->set == RESVD_SET || cmd == 0 || - (rule->set == new_set && - (cmd == 1 || rule->rulenum == rulenum))) + if (rule->set == RESVD_SET || + !(cmd == 0 || rule->set == new_set) || + !(cmd == 1 || rule->rulenum == rulenum) ) continue; l = RULESIZE(rule); From dfeca18773e2496197aba82520375552c78b7800 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 31 Mar 2010 02:43:58 +0000 Subject: [PATCH 1773/2592] MFC rev 198341 and 198342: 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). --- sys/amd64/amd64/pmap.c | 5 ++ sys/arm/arm/pmap.c | 10 +++- 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 +++ 19 files changed, 195 insertions(+), 73 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 0935506c7d7..5ff527f1a02 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -4756,6 +4756,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 9df07d9a352..03a92a449b6 100644 --- a/sys/arm/arm/pmap.c +++ b/sys/arm/arm/pmap.c @@ -2869,14 +2869,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 { @@ -4573,6 +4573,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/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 06dd8f4d904..d4dea040d58 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 5de5a32ab7b..1b4345f07e9 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 06aad4a1674..f8297462a12 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -2263,6 +2263,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 313167ddbc8..4f2569d1860 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -341,6 +341,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 dfa80516c22..8357929e4f2 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 } }; @@ -2361,12 +2361,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 @@ -2426,3 +2420,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 9d04a023914..4e9717785a0 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -362,7 +362,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); /* @@ -403,7 +403,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), @@ -430,6 +430,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), @@ -444,7 +445,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 } }; @@ -1256,12 +1256,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) { /* @@ -1278,16 +1278,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); } @@ -1803,8 +1803,9 @@ moea64_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva, pvo->pvo_pmap, PVO_VADDR(pvo)); 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(); @@ -2431,12 +2432,6 @@ moea64_dev_direct_mapped(mmu_t mmu, vm_offset_t pa, vm_size_t size) return (error); } -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 @@ -2479,3 +2474,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 ab47292666e..13e637ce603 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 bc2d4a1b14b..ee1204d7f0d 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -1995,6 +1995,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 e9fa42544e3f2e19b8b0cdc6c8792c73d7f5bbf2 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 31 Mar 2010 03:14:40 +0000 Subject: [PATCH 1774/2592] MFC rev 198431: Have the early USB takeover only enabled for i386 and amd64 by default. This also avoids a panic on PowerPC. --- 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 650e2141b70..40b54995b17 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 3559a7713ae6e1c92493b7556055528a8284d4d3 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 31 Mar 2010 03:20:14 +0000 Subject: [PATCH 1775/2592] MFC revs 199502, 199566 and 199574: Add a seatbelt to the Nested TLB Fault handler to give us a chance to panic when we have an unexpected TLB fault while interrupt collection is disabled. --- sys/ia64/ia64/db_machdep.c | 2 +- sys/ia64/ia64/exception.S | 77 +++++++++++++++++++++++++++----------- sys/ia64/ia64/trap.c | 8 ++-- 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/sys/ia64/ia64/db_machdep.c b/sys/ia64/ia64/db_machdep.c index cdd60ab03c6..d1163cbd050 100644 --- a/sys/ia64/ia64/db_machdep.c +++ b/sys/ia64/ia64/db_machdep.c @@ -29,7 +29,7 @@ #include __FBSDID("$FreeBSD$"); -#include +#include "opt_xtrace.h" #include #include diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S index 2cf3aaf4411..1a5fa32eacd 100644 --- a/sys/ia64/ia64/exception.S +++ b/sys/ia64/ia64/exception.S @@ -28,11 +28,19 @@ #include __FBSDID("$FreeBSD$"); -#include +#include "opt_xtrace.h" #include #include +/* + * Nested TLB restart tokens. These are used by the + * nested TLB handler for jumping back to the code + * where the nested TLB was caused. + */ +#define NTLBRT_SAVE 0x12c12c +#define NTLBRT_RESTORE 0x12c12d + /* * ar.k7 = kernel memory stack * ar.k6 = kernel register stack @@ -140,9 +148,10 @@ ENTRY_NOPROFILE(exception_save, 0) add r31=8,r30 ;; } -{ .mlx +{ .mib mov r22=cr.iip - movl r26=exception_save_restart + addl r29=NTLBRT_SAVE,r0 // 22-bit restart token. + nop 0 ;; } @@ -157,7 +166,7 @@ ENTRY_NOPROFILE(exception_save, 0) * that are currently alive: * r16,r17=arguments * r18=pr, r19=length, r20=unat, r21=rsc, r22=iip, r23=TOS - * r26=restart point + * r29=restart point * r30,r31=trapframe pointers * p14,p15=memory stack switch */ @@ -543,7 +552,7 @@ ENTRY_NOPROFILE(exception_restore, 0) ld8 r21=[r31],24 // rnat mov ar.pfs=r28 ;; - ld8.fill r29=[r30],16 // tp + ld8.fill r26=[r30],16 // tp ld8 r22=[r31],16 // rsc ;; { .mmi @@ -554,21 +563,21 @@ ENTRY_NOPROFILE(exception_restore, 0) } { .mmi ld8.fill r1=[r30],16 // gp - ld8 r25=[r31],16 // ndirty + ld8 r27=[r31],16 // ndirty cmp.le p14,p15=5,r28 ;; } { .mmb - ld8 r26=[r30] // cfm + ld8 r25=[r30] // cfm ld8 r19=[r31] // ip nop 0 ;; } -{ .mib +{ .mii // Switch register stack alloc r30=ar.pfs,0,0,0,0 // discard current frame - shl r31=r25,16 // value for ar.rsc - nop 0 + shl r31=r27,16 // value for ar.rsc +(p15) mov r13=r26 ;; } // The loadrs can fault if the backing store is not currently @@ -579,7 +588,7 @@ ENTRY_NOPROFILE(exception_restore, 0) { .mmi mov ar.rsc=r31 // setup for loadrs mov ar.k7=r16 -(p15) mov r13=r29 + addl r29=NTLBRT_RESTORE,r0 // 22-bit restart token ;; } exception_restore_restart: @@ -610,7 +619,7 @@ exception_restore_restart: } { .mmi mov cr.ipsr=r24 - mov cr.ifs=r26 + mov cr.ifs=r25 mov pr=r18,0x1ffff ;; } @@ -943,7 +952,7 @@ IVT_ENTRY(Data_Nested_TLB, 0x1400) } { .mii ld8 r27=[r27] // dir L0 page - extr.u r29=r30,2*PAGE_SHIFT-5, PAGE_SHIFT-3 // dir L1 index + extr.u r26=r30,2*PAGE_SHIFT-5, PAGE_SHIFT-3 // dir L1 index ;; dep r27=0,r27,61,3 ;; @@ -956,16 +965,16 @@ IVT_ENTRY(Data_Nested_TLB, 0x1400) ;; } { .mmi - shladd r27=r29,3,r27 + shladd r27=r26,3,r27 ;; - mov r29=rr[r30] + mov r26=rr[r30] dep r27=0,r27,61,3 ;; } { .mii ld8 r27=[r27] // pte page shl r28=r28,5 - dep r29=0,r29,0,2 + dep r26=0,r26,0,2 ;; } { .mmi @@ -978,28 +987,54 @@ IVT_ENTRY(Data_Nested_TLB, 0x1400) { .mmi ld8 r28=[r27] // pte ;; - mov cr.itir=r29 + mov cr.itir=r26 or r28=PTE_DIRTY+PTE_ACCESSED,r28 ;; } -{ .mlx +{ .mmi st8 [r27]=r28 - movl r29=exception_save_restart ;; + addl r26=NTLBRT_SAVE,r0 + addl r27=NTLBRT_RESTORE,r0 } { .mmi itc.d r28 ;; ssm psr.dt - cmp.eq p12,p13=r26,r29 + cmp.eq p12,p0=r29,r26 ;; } -{ .mbb +{ .mib srlz.d + cmp.eq p13,p0=r29,r27 (p12) br.sptk exception_save_restart + ;; +} +{ .mib + nop 0 + nop 0 (p13) br.sptk exception_restore_restart ;; } +{ .mlx + mov r26=ar.bsp + movl r27=kstack + ;; +} +{ .mib + mov r28=sp + addl r27=KSTACK_PAGES*PAGE_SIZE-16,r0 + nop 0 + ;; +} +{ .mmi + mov sp=r27 + ;; + mov r27=ar.bspstore + nop 0 + ;; +} + CALL(trap, 5, r30) IVT_END(Data_Nested_TLB) IVT_ENTRY(Instruction_Key_Miss, 0x1800) diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c index 2a4dca83a9f..c966f0aaef1 100644 --- a/sys/ia64/ia64/trap.c +++ b/sys/ia64/ia64/trap.c @@ -414,11 +414,9 @@ trap(int vector, struct trapframe *tf) case IA64_VEC_NESTED_DTLB: /* - * We never call trap() with this vector. We may want to - * do that in the future in case the nested TLB handler - * could not find the translation it needs. In that case - * we could switch to a special (hardwired) stack and - * come here to produce a nice panic(). + * When the nested TLB handler encounters an unexpected + * condition, it'll switch to the backup stack and transfer + * here. All we need to do is panic. */ trap_panic(vector, tf); break; From 419ee98298e28a947e010b908b6976610e4c7782 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 31 Mar 2010 05:05:28 +0000 Subject: [PATCH 1776/2592] MFC rev 199727, 200888, 201031, 202904, 203054, 203106, 203572, 203884, 204183, 204184, 204185, 204425, 204904, 204905, 205172, 205234, 205357, 205428, 205429, 205431, 205432, 205433, 205434, 205435, 205454, 205665, 205713, 205723, 205726 and 205727: Bring ia64 machine-dependent changes from 9-current to 8-stable. --- .../common/atomic/ia64/opensolaris_atomic.S | 2 +- sys/conf/files.ia64 | 2 - sys/ia64/conf/GENERIC | 62 ++- sys/ia64/ia64/autoconf.c | 19 +- sys/ia64/ia64/clock.c | 112 +++- sys/ia64/ia64/context.S | 16 +- sys/ia64/ia64/db_machdep.c | 7 + sys/ia64/ia64/exception.S | 44 +- sys/ia64/ia64/highfp.c | 4 +- sys/ia64/ia64/interrupt.c | 504 +++++++++--------- sys/ia64/ia64/locore.S | 31 +- sys/ia64/ia64/machdep.c | 51 +- sys/ia64/ia64/mp_machdep.c | 129 +++-- sys/ia64/ia64/nexus.c | 107 +--- sys/ia64/ia64/pmap.c | 77 +-- sys/ia64/ia64/sal.c | 69 +-- sys/ia64/ia64/sapic.c | 179 +++++-- sys/ia64/ia64/support.S | 28 +- sys/ia64/ia64/syscall.S | 20 +- sys/ia64/ia64/trap.c | 15 +- sys/ia64/ia64/vm_machdep.c | 4 +- sys/ia64/include/acpica_machdep.h | 4 +- sys/ia64/include/clock.h | 8 - sys/ia64/include/cpufunc.h | 9 +- sys/ia64/include/frame.h | 2 + sys/ia64/include/intr.h | 46 +- sys/ia64/include/intrcnt.h | 6 +- sys/ia64/include/mca.h | 1 + sys/ia64/include/nexusvar.h | 43 -- sys/ia64/include/pcb.h | 2 + sys/ia64/include/pci_cfgreg.h | 14 +- sys/ia64/include/pcpu.h | 12 +- sys/ia64/include/sapicreg.h | 48 -- sys/ia64/include/sapicvar.h | 65 --- sys/ia64/include/smp.h | 32 +- sys/ia64/pci/pci_cfgreg.c | 70 ++- sys/modules/Makefile | 11 +- 37 files changed, 933 insertions(+), 922 deletions(-) delete mode 100644 sys/ia64/include/nexusvar.h delete mode 100644 sys/ia64/include/sapicreg.h delete mode 100644 sys/ia64/include/sapicvar.h diff --git a/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S index 409d759b784..1b7c580c3b2 100644 --- a/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S +++ b/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S @@ -76,7 +76,7 @@ ENTRY(atomic_or_8_nv, 2) END(atomic_or_8_nv) ENTRY(membar_producer, 0) - mf.a + mf ;; br.ret.sptk rp END(membar_producer) diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64 index d3fb6100faa..17673317904 100644 --- a/sys/conf/files.ia64 +++ b/sys/conf/files.ia64 @@ -45,8 +45,6 @@ contrib/ia64/libuwx/src/uwx_uinfo.c standard contrib/ia64/libuwx/src/uwx_utable.c standard crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec | netsmb -dev/advansys/adv_isa.c optional adv isa -dev/aic/aic_isa.c optional aic isa dev/atkbdc/atkbd.c optional atkbd atkbdc dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc dev/atkbdc/atkbdc.c optional atkbdc diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC index 6b7411e51fe..e0e739da290 100644 --- a/sys/ia64/conf/GENERIC +++ b/sys/ia64/conf/GENERIC @@ -20,7 +20,7 @@ # # $FreeBSD$ -cpu ITANIUM +cpu ITANIUM2 ident GENERIC makeoptions DEBUG=-g # Build kernel with debug information. @@ -28,10 +28,12 @@ makeoptions DEBUG=-g # Build kernel with debug information. options AUDIT # Security event auditing options CD9660 # ISO 9660 Filesystem options COMPAT_43TTY # BSD 4.3 TTY compat (sgtty) -options COMPAT_FREEBSD6 # Compatible with FreeBSD6 options COMPAT_FREEBSD7 # Compatible with FreeBSD7 options FFS # Berkeley Fast Filesystem +options FLOWTABLE # per-cpu routing cache +options GDB # Support remote GDB options GEOM_LABEL # Provides labelization +options INCLUDE_CONFIG_FILE # Include this file in kernel options INET # InterNETworking options INET6 # IPv6 communications protocols options INVARIANTS # Enable calls of extra sanity checking @@ -41,9 +43,11 @@ 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 NFSSERVER # Network Filesystem Server options NFS_ROOT # NFS usable as root device +options P1003_1B_SEMAPHORES # POSIX-style semaphores +options PREEMPTION # Enable kernel thread preemption options PRINTF_BUFR_SIZE=128 # Printf buffering to limit interspersion options PROCFS # Process filesystem (/proc) options PSEUDOFS # Pseudo-filesystem framework @@ -56,13 +60,10 @@ options STACK # stack(9) support options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options SYSVSHM # SYSV-style shared memory -options P1003_1B_SEMAPHORES # POSIX-style semaphores options UFS_ACL # Support for access control lists options UFS_DIRHASH # Hash-based directory lookup scheme options UFS_GJOURNAL # Enable gjournal-based UFS journaling options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B RT extensions -options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) -options INCLUDE_CONFIG_FILE # Include this file in kernel # Various "busses" device firewire # FireWire bus code @@ -76,20 +77,25 @@ device ata # ATA controller device atadisk # ATA disk drives device atapicd # ATAPI CDROM drives device atapifd # ATAPI floppy drives +device atapist # ATAPI tape drives device ataraid # ATA RAID drives # SCSI Controllers device ahc # AHA2940 and AIC7xxx devices device ahd # AHA39320/29320 and AIC79xx devices +device hptiop # Highpoint RocketRaid 3xxx series device isp # Qlogic family device mpt # LSI-Logic MPT-Fusion device sym # NCR/Symbios Logic # RAID controllers interfaced to the SCSI subsystem +device amr # AMI MegaRAID device ciss # Compaq Smart RAID 5* device dpt # DPT Smartcache III, IV device iir # Intel Integrated RAID +device ips # IBM (Adaptec) ServeRAID device mly # Mylex AcceleRAID/eXtremeRAID +device twa # 3ware 9000 series PATA/SATA RAID # SCSI peripherals device cd # CD-ROM, DVD-ROM etc. @@ -102,7 +108,6 @@ device ses # Environmental Services (and SAF-TE) # RAID controllers device aac # Adaptec FSA RAID device aacp # SCSI passthrough for aac (requires CAM) -device amr # AMI MegaRAID device ida # Compaq Smart RAID device mlx # Mylex DAC960 family @@ -118,34 +123,58 @@ device ums # Mouse # PCI Ethernet NICs. device de # DEC/Intel DC21x4x (``Tulip'') -device em # Intel PRO/1000 adapter Gigabit Ethernet Card -device le # AMD Am7900 LANCE and Am79C9xx PCnet +device em # Intel PRO/1000 Gigabit Ethernet Family +device igb # Intel PRO/1000 PCIE Server Gigabit Family +device ixgbe # Intel PRO/10GbE PCIE Ethernet Family device txp # 3Com 3cR990 (``Typhoon'') -device vx # 3Com 3c590, 3c595 (``Vortex'') # PCI Ethernet NICs that use the common MII bus controller code. +device ae # Attansic/Atheros L2 FastEthernet +device age # Attansic/Atheros L1 Gigabit Ethernet +device alc # Atheros AR8131/AR8132 Ethernet +device ale # Atheros AR8121/AR8113/AR8114 Ethernet +device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet +device bfe # Broadcom BCM440x 10/100 Ethernet device bge # Broadcom BCM570xx Gigabit Ethernet -device dc # DEC/Intel 21143 and various workalikes +device et # Agere ET1310 10/100/Gigabit Ethernet +device jme # JMicron JMC250 Gigabit/JMC260 Fast Ethernet +device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet +device nge # NatSemi DP83820 gigabit Ethernet device fxp # Intel EtherExpress PRO/100B (82557, 82558) -device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') device re # RealTek 8139C+/8169/8169S/8110S -device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (``Starfire'') -device sis # Silicon Integrated Systems SiS 900/SiS 7016 +device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet +device ste # Sundance ST201 (D-Link DFE-550TX) +device stge # Sundance/Tamarack TC9021 gigabit Ethernet +device tx # SMC EtherPower II (83c170 ``EPIC'') +device vge # VIA VT612x gigabit Ethernet device xl # 3Com 3c90x ("Boomerang", "Cyclone") # USB Ethernet device aue # ADMtek USB Ethernet +device axe # ASIX Electronics USB Ethernet 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 # Davicom DM9601E USB + +# USB Serial +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 # FireWire support -#device sbp # SCSI over FireWire (need scbus & da) +device fwip # IP over FireWire (RFC 2734,3146) +device sbp # SCSI over FireWire (need scbus & da) # Various (pseudo) devices device ether # Ethernet support -device vlan # 802.1Q VLAN support device faith # IPv6-to-IPv4 relaying (translation) device gif # IPv6 and IPv4 tunneling device loop # Network loopback @@ -155,6 +184,7 @@ device puc # Multi I/O cards and multi-channel UARTs device random # Entropy device device tun # Packet tunnel. device uart # Serial port (UART) +device vlan # 802.1Q VLAN support device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. diff --git a/sys/ia64/ia64/autoconf.c b/sys/ia64/ia64/autoconf.c index 5a380516320..cf073c83509 100644 --- a/sys/ia64/ia64/autoconf.c +++ b/sys/ia64/ia64/autoconf.c @@ -39,15 +39,9 @@ #include #include -#include #include - -#include -#include -#include -#include -#include -#include +#include +#include static void configure_first(void *); static void configure(void *); @@ -97,12 +91,9 @@ static void configure_final(void *dummy) { - /* - * Now we're ready to handle (pending) interrupts. - * XXX this is slightly misplaced. - */ - enable_intr(); - cninit_finish(); + + ia64_enable_intr(); + cold = 0; } diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c index a9c39fce359..33dbb2e3c1e 100644 --- a/sys/ia64/ia64/clock.c +++ b/sys/ia64/ia64/clock.c @@ -29,19 +29,42 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include +#include #include #include #include -#include #include #include -#include #include #include +#include +#include #include +#include -uint64_t ia64_clock_reload; +SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics"); + +static int adjust_edges = 0; +SYSCTL_INT(_debug_clock, OID_AUTO, adjust_edges, CTLFLAG_RD, + &adjust_edges, 0, "Number of times ITC got more than 12.5% behind"); + +static int adjust_excess = 0; +SYSCTL_INT(_debug_clock, OID_AUTO, adjust_excess, CTLFLAG_RD, + &adjust_excess, 0, "Total number of ignored ITC interrupts"); + +static int adjust_lost = 0; +SYSCTL_INT(_debug_clock, OID_AUTO, adjust_lost, CTLFLAG_RD, + &adjust_lost, 0, "Total number of lost ITC interrupts"); + +static int adjust_ticks = 0; +SYSCTL_INT(_debug_clock, OID_AUTO, adjust_ticks, CTLFLAG_RD, + &adjust_ticks, 0, "Total number of ITC interrupts with adjustment"); + +static u_int ia64_clock_xiv; +static uint64_t ia64_clock_reload; #ifndef SMP static timecounter_get_t ia64_get_timecount; @@ -54,26 +77,80 @@ static struct timecounter ia64_timecounter = { "ITC" /* name */ }; -static unsigned +static u_int ia64_get_timecount(struct timecounter* tc) { return ia64_get_itc(); } #endif -void -pcpu_initclock(void) +static u_int +ia64_ih_clock(struct thread *td, u_int xiv, struct trapframe *tf) { + uint64_t adj, clk, itc; + int64_t delta; + int count; - PCPU_SET(md.clockadj, 0); - PCPU_SET(md.clock, ia64_get_itc()); - ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload); - ia64_set_itv(CLOCK_VECTOR); /* highest priority class */ - ia64_srlz_d(); + PCPU_INC(md.stats.pcs_nclks); + + if (PCPU_GET(cpuid) == 0) { + /* + * Clock processing on the BSP. + */ + intrcnt[INTRCNT_CLOCK]++; + + itc = ia64_get_itc(); + + adj = PCPU_GET(md.clockadj); + clk = PCPU_GET(md.clock); + + delta = itc - clk; + count = 0; + while (delta >= ia64_clock_reload) { +#ifdef SMP + ipi_all_but_self(ia64_clock_xiv); +#endif + hardclock(TRAPF_USERMODE(tf), TRAPF_PC(tf)); + if (profprocs != 0) + profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf)); + statclock(TRAPF_USERMODE(tf)); + delta -= ia64_clock_reload; + clk += ia64_clock_reload; + if (adj != 0) + adjust_ticks++; + count++; + } + ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj); + ia64_srlz_d(); + if (count > 0) { + adjust_lost += count - 1; + if (delta > (ia64_clock_reload >> 3)) { + if (adj == 0) + adjust_edges++; + adj = ia64_clock_reload >> 4; + } else + adj = 0; + } else { + adj = 0; + adjust_excess++; + } + PCPU_SET(md.clock, clk); + PCPU_SET(md.clockadj, adj); + } else { + /* + * Clock processing on the BSP. + */ + hardclock_cpu(TRAPF_USERMODE(tf)); + if (profprocs != 0) + profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf)); + statclock(TRAPF_USERMODE(tf)); + } + + return (0); } /* - * Start the real-time and statistics clocks. We use cr.itc and cr.itm + * Start the real-time and statistics clocks. We use ar.itc and cr.itm * to implement a 1000hz clock. */ void @@ -81,6 +158,11 @@ cpu_initclocks() { u_long itc_freq; + ia64_clock_xiv = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IPI, + ia64_ih_clock); + if (ia64_clock_xiv == 0) + panic("No XIV for clock interrupts"); + itc_freq = (u_long)ia64_itc_freq() * 1000000ul; stathz = hz; @@ -91,7 +173,11 @@ cpu_initclocks() tc_init(&ia64_timecounter); #endif - pcpu_initclock(); + PCPU_SET(md.clockadj, 0); + PCPU_SET(md.clock, ia64_get_itc()); + ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload); + ia64_set_itv(ia64_clock_xiv); + ia64_srlz_d(); } void diff --git a/sys/ia64/ia64/context.S b/sys/ia64/ia64/context.S index 77a1821f789..84d8fd1ccc5 100644 --- a/sys/ia64/ia64/context.S +++ b/sys/ia64/ia64/context.S @@ -86,18 +86,18 @@ ENTRY(restorectx, 1) { .mmi ld8.fill r6=[r14],16 // r6 ld8.fill r7=[r15],16 // r7 - nop 1 + nop 0 ;; } { .mmi mov ar.unat=r16 mov ar.rsc=3 - nop 2 + nop 0 } { .mmi ld8 r17=[r14],16 // b1 ld8 r18=[r15],16 // b2 - nop 3 + nop 0 ;; } { .mmi @@ -286,7 +286,7 @@ ENTRY(swapctx, 2) (p15) br.ret.sptk rp ;; } -{ .mfb +{ .mib mov r32=r33 nop 0 br.sptk restorectx @@ -338,10 +338,10 @@ ENTRY(save_callee_saved, 1) mov r17=b5 ;; } -{ .mfi +{ .mii st8 [r14]=r17,16 // b5 - nop 0 mov r16=ar.lc + nop 0 ;; } { .mmb @@ -363,13 +363,13 @@ ENTRY(restore_callee_saved, 1) add r31=-8,r32 ;; } -{ .mmb +{ .mmi ld8.fill r4=[r31],16 // r4 ld8.fill r5=[r32],16 // r5 nop 0 ;; } -{ .mmb +{ .mmi ld8.fill r6=[r31],16 // r6 ld8.fill r7=[r32],16 // r7 nop 0 diff --git a/sys/ia64/ia64/db_machdep.c b/sys/ia64/ia64/db_machdep.c index d1163cbd050..2684bfea55c 100644 --- a/sys/ia64/ia64/db_machdep.c +++ b/sys/ia64/ia64/db_machdep.c @@ -577,6 +577,13 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data) void db_show_mdpcpu(struct pcpu *pc) { + struct pcpu_md *md = &pc->pc_md; + + db_printf("MD: vhpt = %#lx\n", md->vhpt); + db_printf("MD: lid = %#lx\n", md->lid); + db_printf("MD: clock = %#lx/%#lx\n", md->clock, md->clockadj); + db_printf("MD: stats = %p\n", &md->stats); + db_printf("MD: pmap = %p\n", md->current_pmap); } void diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S index 1a5fa32eacd..755a467d745 100644 --- a/sys/ia64/ia64/exception.S +++ b/sys/ia64/ia64/exception.S @@ -89,10 +89,10 @@ xhead: data8 xtrace addl r29=1024*5*8,r0 ;; \ (p15) sub r27=r28,r29 ;; \ } ; \ -{ .mib ; \ +{ .mmi ; \ st8 [r28]=r27 ; \ - mov pr=r25,0x1ffff ; \ - nop 0 ;; \ + nop 0 ; \ + mov pr=r25,0x1ffff ;; \ } #else @@ -148,10 +148,10 @@ ENTRY_NOPROFILE(exception_save, 0) add r31=8,r30 ;; } -{ .mib +{ .mmi mov r22=cr.iip - addl r29=NTLBRT_SAVE,r0 // 22-bit restart token. nop 0 + addl r29=NTLBRT_SAVE,r0 // 22-bit restart token. ;; } @@ -235,7 +235,7 @@ exception_save_restart: nop 0 ;; } -{ .mmb +{ .mmi (p13) mov ar.rnat=r19 mov r18=ar.bsp nop 0 @@ -248,7 +248,7 @@ exception_save_restart: ;; } // r19=ifs, r22=iip -{ .mmb +{ .mmi st8 [r31]=r18,16 // ndirty st8 [r30]=r19,16 // cfm nop 0 @@ -260,7 +260,7 @@ exception_save_restart: add r29=16,r30 ;; } -{ .mmb +{ .mmi st8 [r30]=r17,24 // ifa st8 [r31]=r18,24 // isr nop 0 @@ -407,7 +407,7 @@ exception_save_restart: movl gp=__gp ;; } -{ .mfb +{ .mib srlz.d nop 0 br.sptk b7 @@ -567,7 +567,7 @@ ENTRY_NOPROFILE(exception_restore, 0) cmp.le p14,p15=5,r28 ;; } -{ .mmb +{ .mmi ld8 r25=[r30] // cfm ld8 r19=[r31] // ip nop 0 @@ -606,13 +606,13 @@ exception_restore_restart: dep r31=0,r31,0,13 // 8KB aligned ;; } -{ .mmb +{ .mmi mov ar.k6=r31 mov ar.rnat=r21 nop 0 ;; } -{ .mmb +{ .mmi mov ar.unat=r17 mov cr.iip=r19 nop 0 @@ -656,7 +656,7 @@ END(exception_restore) add out1=16,sp ; \ br.call.sptk rp=_func_ ;; \ } ; \ -{ .mfb ; \ +{ .mib ; \ nop 0 ; \ nop 0 ; \ br.sptk exception_restore ;; \ @@ -1021,10 +1021,10 @@ IVT_ENTRY(Data_Nested_TLB, 0x1400) movl r27=kstack ;; } -{ .mib +{ .mmi mov r28=sp - addl r27=KSTACK_PAGES*PAGE_SIZE-16,r0 nop 0 + addl r27=KSTACK_PAGES*PAGE_SIZE-16,r0 ;; } { .mmi @@ -1287,13 +1287,13 @@ IVT_ENTRY(Break_Instruction, 0x2c00) (p11) srlz.d add out1=16,sp } -{ .mfb +{ .mib nop 0 nop 0 br.call.sptk rp=trap ;; } -{ .mfb +{ .mib nop 0 nop 0 br.sptk exception_restore @@ -1303,24 +1303,24 @@ IVT_END(Break_Instruction) IVT_ENTRY(External_Interrupt, 0x3000) { .mib - mov r17=cr.ivr // Put the vector in the trap frame. + mov r17=ar.itc // Put the ITC in the trapframe. mov r16=ip br.sptk exception_save ;; } -{ .mfb +{ .mmi alloc r15=ar.pfs,0,0,1,0 nop 0 nop 0 ;; } -{ .mfb +{ .mib add out0=16,sp nop 0 - br.call.sptk rp=interrupt + br.call.sptk rp=ia64_handle_intr ;; } -{ .mfb +{ .mib nop 0 nop 0 br.sptk exception_restore diff --git a/sys/ia64/ia64/highfp.c b/sys/ia64/ia64/highfp.c index 145ee488ba6..f18773bdb56 100644 --- a/sys/ia64/ia64/highfp.c +++ b/sys/ia64/ia64/highfp.c @@ -53,7 +53,7 @@ ia64_highfp_ipi(struct pcpu *cpu) { int error; - ipi_send(cpu, IPI_HIGH_FP); + ipi_send(cpu, ia64_ipi_highfp); error = msleep_spin(&cpu->pc_fpcurthread, &ia64_highfp_mtx, "High FP", 0); return (error); @@ -92,8 +92,6 @@ ia64_highfp_enable(struct thread *td, struct trapframe *tf) 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) { diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index 64b04ebca41..adb16ece9d5 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -52,204 +53,20 @@ #include #include -#include #include #include #include #include +#include #include #include #include -#include #include -#ifdef EVCNT_COUNTERS -struct evcnt clock_intr_evcnt; /* event counter for clock intrs. */ -#else -#include -#include -#endif - #ifdef DDB #include #endif -static void ia64_dispatch_intr(void *, u_int); - -static void -dummy_perf(unsigned long vector, struct trapframe *tf) -{ - printf("performance interrupt!\n"); -} - -void (*perf_irq)(unsigned long, struct trapframe *) = dummy_perf; - -SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics"); - -static int adjust_edges = 0; -SYSCTL_INT(_debug_clock, OID_AUTO, adjust_edges, CTLFLAG_RD, - &adjust_edges, 0, "Number of times ITC got more than 12.5% behind"); - -static int adjust_excess = 0; -SYSCTL_INT(_debug_clock, OID_AUTO, adjust_excess, CTLFLAG_RD, - &adjust_excess, 0, "Total number of ignored ITC interrupts"); - -static int adjust_lost = 0; -SYSCTL_INT(_debug_clock, OID_AUTO, adjust_lost, CTLFLAG_RD, - &adjust_lost, 0, "Total number of lost ITC interrupts"); - -static int adjust_ticks = 0; -SYSCTL_INT(_debug_clock, OID_AUTO, adjust_ticks, CTLFLAG_RD, - &adjust_ticks, 0, "Total number of ITC interrupts with adjustment"); - -void -interrupt(struct trapframe *tf) -{ - struct thread *td; - uint64_t adj, clk, itc; - int64_t delta; - u_int vector; - int count; - uint8_t inta; - - ia64_set_fpsr(IA64_FPSR_DEFAULT); - - td = curthread; - - PCPU_INC(cnt.v_intr); - - vector = tf->tf_special.ifa; - - next: - /* - * Handle ExtINT interrupts by generating an INTA cycle to - * read the vector. - * IPI_STOP_HARD is mapped to IPI_STOP so it is not necessary - * to add it to this switch-like construct. - */ - if (vector == 0) { - PCPU_INC(md.stats.pcs_nextints); - inta = ia64_ld1(&ia64_pib->ib_inta); - if (inta == 15) { - PCPU_INC(md.stats.pcs_nstrays); - __asm __volatile("mov cr.eoi = r0;; srlz.d"); - goto stray; - } - vector = (int)inta; - } else if (vector == 15) { - PCPU_INC(md.stats.pcs_nstrays); - goto stray; - } - - if (vector == CLOCK_VECTOR) {/* clock interrupt */ - /* CTR0(KTR_INTR, "clock interrupt"); */ - - itc = ia64_get_itc(); - - PCPU_INC(md.stats.pcs_nclks); -#ifdef EVCNT_COUNTERS - clock_intr_evcnt.ev_count++; -#else - intrcnt[INTRCNT_CLOCK]++; -#endif - - critical_enter(); - - adj = PCPU_GET(md.clockadj); - clk = PCPU_GET(md.clock); - delta = itc - clk; - count = 0; - while (delta >= ia64_clock_reload) { - /* Only the BSP runs the real clock */ - if (PCPU_GET(cpuid) == 0) - hardclock(TRAPF_USERMODE(tf), TRAPF_PC(tf)); - else - hardclock_cpu(TRAPF_USERMODE(tf)); - if (profprocs != 0) - profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf)); - statclock(TRAPF_USERMODE(tf)); - delta -= ia64_clock_reload; - clk += ia64_clock_reload; - if (adj != 0) - adjust_ticks++; - count++; - } - ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj); - if (count > 0) { - adjust_lost += count - 1; - if (delta > (ia64_clock_reload >> 3)) { - if (adj == 0) - adjust_edges++; - adj = ia64_clock_reload >> 4; - } else - adj = 0; - } else { - adj = 0; - adjust_excess++; - } - PCPU_SET(md.clock, clk); - PCPU_SET(md.clockadj, adj); - critical_exit(); - ia64_srlz_d(); - -#ifdef SMP - } else if (vector == ipi_vector[IPI_AST]) { - PCPU_INC(md.stats.pcs_nasts); - CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid)); - } else if (vector == ipi_vector[IPI_HIGH_FP]) { - PCPU_INC(md.stats.pcs_nhighfps); - ia64_highfp_save_ipi(); - } else if (vector == ipi_vector[IPI_RENDEZVOUS]) { - PCPU_INC(md.stats.pcs_nrdvs); - CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid)); - enable_intr(); - smp_rendezvous_action(); - disable_intr(); - } else if (vector == ipi_vector[IPI_STOP]) { - PCPU_INC(md.stats.pcs_nstops); - cpumask_t mybit = PCPU_GET(cpumask); - - savectx(PCPU_PTR(md.pcb)); - atomic_set_int(&stopped_cpus, mybit); - while ((started_cpus & mybit) == 0) - cpu_spinwait(); - atomic_clear_int(&started_cpus, mybit); - atomic_clear_int(&stopped_cpus, mybit); - } else if (vector == ipi_vector[IPI_PREEMPT]) { - PCPU_INC(md.stats.pcs_npreempts); - CTR1(KTR_SMP, "IPI_PREEMPT, cpuid=%d", PCPU_GET(cpuid)); - __asm __volatile("mov cr.eoi = r0;; srlz.d"); - enable_intr(); - sched_preempt(curthread); - disable_intr(); - goto stray; -#endif - } else { - PCPU_INC(md.stats.pcs_nhwints); - atomic_add_int(&td->td_intr_nesting_level, 1); - ia64_dispatch_intr(tf, vector); - atomic_subtract_int(&td->td_intr_nesting_level, 1); - } - - __asm __volatile("mov cr.eoi = r0;; srlz.d"); - vector = ia64_get_ivr(); - if (vector != 15) - goto next; - -stray: - if (TRAPF_USERMODE(tf)) { - enable_intr(); - userret(td, tf); - mtx_assert(&Giant, MA_NOTOWNED); - do_ast(tf); - } -} - -/* - * Hardware irqs have vectors starting at this offset. - */ -#define IA64_HARDWARE_IRQ_BASE 0x20 - struct ia64_intr { struct intr_event *event; /* interrupt event */ volatile long *cntp; /* interrupt counter */ @@ -257,41 +74,120 @@ struct ia64_intr { u_int irq; }; -static struct ia64_intr *ia64_intrs[256]; +ia64_ihtype *ia64_handler[IA64_NXIVS]; + +static enum ia64_xiv_use ia64_xiv[IA64_NXIVS]; +static struct ia64_intr *ia64_intrs[IA64_NXIVS]; + +static ia64_ihtype ia64_ih_invalid; +static ia64_ihtype ia64_ih_irq; + +void +ia64_xiv_init(void) +{ + u_int xiv; + + for (xiv = 0; xiv < IA64_NXIVS; xiv++) { + ia64_handler[xiv] = ia64_ih_invalid; + ia64_xiv[xiv] = IA64_XIV_FREE; + ia64_intrs[xiv] = NULL; + } + (void)ia64_xiv_reserve(15, IA64_XIV_ARCH, NULL); +} + +int +ia64_xiv_free(u_int xiv, enum ia64_xiv_use what) +{ + + if (xiv >= IA64_NXIVS) + return (EINVAL); + if (what == IA64_XIV_FREE || what == IA64_XIV_ARCH) + return (EINVAL); + if (ia64_xiv[xiv] != what) + return (ENXIO); + ia64_xiv[xiv] = IA64_XIV_FREE; + ia64_handler[xiv] = ia64_ih_invalid; + return (0); +} + +int +ia64_xiv_reserve(u_int xiv, enum ia64_xiv_use what, ia64_ihtype ih) +{ + + if (xiv >= IA64_NXIVS) + return (EINVAL); + if (what == IA64_XIV_FREE) + return (EINVAL); + if (ia64_xiv[xiv] != IA64_XIV_FREE) + return (EBUSY); + ia64_xiv[xiv] = what; + ia64_handler[xiv] = (ih == NULL) ? ia64_ih_invalid: ih; + if (bootverbose) + printf("XIV %u: use=%u, IH=%p\n", xiv, what, ih); + return (0); +} + +u_int +ia64_xiv_alloc(u_int prio, enum ia64_xiv_use what, ia64_ihtype ih) +{ + u_int hwprio; + u_int xiv0, xiv; + + hwprio = prio >> 2; + if (hwprio > IA64_MAX_HWPRIO) + hwprio = IA64_MAX_HWPRIO; + + xiv0 = IA64_NXIVS - (hwprio + 1) * 16; + + KASSERT(xiv0 >= IA64_MIN_XIV, ("%s: min XIV", __func__)); + KASSERT(xiv0 < IA64_NXIVS, ("%s: max XIV", __func__)); + + xiv = xiv0; + while (xiv < IA64_NXIVS && ia64_xiv_reserve(xiv, what, ih)) + xiv++; + + if (xiv < IA64_NXIVS) + return (xiv); + + xiv = xiv0; + while (xiv >= IA64_MIN_XIV && ia64_xiv_reserve(xiv, what, ih)) + xiv--; + + return ((xiv >= IA64_MIN_XIV) ? xiv : 0); +} static void ia64_intr_eoi(void *arg) { - u_int vector = (uintptr_t)arg; + u_int xiv = (uintptr_t)arg; struct ia64_intr *i; - i = ia64_intrs[vector]; - if (i != NULL) - sapic_eoi(i->sapic, vector); + i = ia64_intrs[xiv]; + KASSERT(i != NULL, ("%s", __func__)); + sapic_eoi(i->sapic, xiv); } static void ia64_intr_mask(void *arg) { - u_int vector = (uintptr_t)arg; + u_int xiv = (uintptr_t)arg; struct ia64_intr *i; - i = ia64_intrs[vector]; - if (i != NULL) { - sapic_mask(i->sapic, i->irq); - sapic_eoi(i->sapic, vector); - } + i = ia64_intrs[xiv]; + KASSERT(i != NULL, ("%s", __func__)); + sapic_mask(i->sapic, i->irq); + sapic_eoi(i->sapic, xiv); } static void ia64_intr_unmask(void *arg) { - u_int vector = (uintptr_t)arg; + u_int xiv = (uintptr_t)arg; struct ia64_intr *i; - i = ia64_intrs[vector]; - if (i != NULL) - sapic_unmask(i->sapic, i->irq); + i = ia64_intrs[xiv]; + KASSERT(i != NULL, ("%s", __func__)); + sapic_unmask(i->sapic, i->irq); } int @@ -301,57 +197,79 @@ ia64_setup_intr(const char *name, int irq, driver_filter_t filter, struct ia64_intr *i; struct sapic *sa; char *intrname; - u_int vector; + u_int prio, xiv; int error; - /* Get the I/O SAPIC that corresponds to the IRQ. */ - sa = sapic_lookup(irq); - if (sa == NULL) + prio = intr_priority(flags); + if (prio > PRI_MAX_ITHD) return (EINVAL); + /* XXX lock */ + + /* Get the I/O SAPIC and XIV that corresponds to the IRQ. */ + sa = sapic_lookup(irq, &xiv); + if (sa == NULL) { + /* XXX unlock */ + return (EINVAL); + } + + if (xiv == 0) { + /* XXX unlock */ + i = malloc(sizeof(struct ia64_intr), M_DEVBUF, + M_ZERO | M_WAITOK); + /* XXX lock */ + sa = sapic_lookup(irq, &xiv); + KASSERT(sa != NULL, ("sapic_lookup")); + if (xiv != 0) + free(i, M_DEVBUF); + } + /* - * XXX - There's a priority implied by the choice of vector. - * We should therefore relate the vector to the interrupt type. + * If the IRQ has no XIV assigned to it yet, assign one based + * on the priority. */ - vector = irq + IA64_HARDWARE_IRQ_BASE; + if (xiv == 0) { + xiv = ia64_xiv_alloc(prio, IA64_XIV_IRQ, ia64_ih_irq); + if (xiv == 0) { + /* XXX unlock */ + free(i, M_DEVBUF); + return (ENOSPC); + } - i = ia64_intrs[vector]; - if (i == NULL) { - i = malloc(sizeof(struct ia64_intr), M_DEVBUF, M_NOWAIT); - if (i == NULL) - return (ENOMEM); - - error = intr_event_create(&i->event, (void *)(uintptr_t)vector, + error = intr_event_create(&i->event, (void *)(uintptr_t)xiv, 0, irq, ia64_intr_mask, ia64_intr_unmask, ia64_intr_eoi, NULL, "irq%u:", irq); if (error) { + ia64_xiv_free(xiv, IA64_XIV_IRQ); + /* XXX unlock */ free(i, M_DEVBUF); return (error); } - if (!atomic_cmpset_ptr(&ia64_intrs[vector], NULL, i)) { - intr_event_destroy(i->event); - free(i, M_DEVBUF); - i = ia64_intrs[vector]; - } else { - i->sapic = sa; - i->irq = irq; + i->sapic = sa; + i->irq = irq; + i->cntp = intrcnt + xiv; + ia64_intrs[xiv] = i; - i->cntp = intrcnt + irq + INTRCNT_ISA_IRQ; - if (name != NULL && *name != '\0') { - /* XXX needs abstraction. Too error prone. */ - intrname = intrnames + - (irq + INTRCNT_ISA_IRQ) * INTRNAME_LEN; - memset(intrname, ' ', INTRNAME_LEN - 1); - bcopy(name, intrname, strlen(name)); - } + /* XXX unlock */ - sapic_enable(i->sapic, irq, vector); + sapic_enable(sa, irq, xiv); + + if (name != NULL && *name != '\0') { + /* XXX needs abstraction. Too error prone. */ + intrname = intrnames + xiv * INTRNAME_LEN; + memset(intrname, ' ', INTRNAME_LEN - 1); + bcopy(name, intrname, strlen(name)); } + } else { + i = ia64_intrs[xiv]; + /* XXX unlock */ } + KASSERT(i != NULL, ("XIV mapping bug")); + error = intr_event_add_handler(i->event, name, filter, handler, arg, - intr_priority(flags), flags, cookiep); + prio, flags, cookiep); return (error); } @@ -362,62 +280,134 @@ ia64_teardown_intr(void *cookie) return (intr_event_remove_handler(cookie)); } -static void -ia64_dispatch_intr(void *frame, u_int vector) +void +ia64_bind_intr(void) +{ + struct ia64_intr *i; + struct pcpu *pc; + u_int xiv; + int cpu; + + cpu = MAXCPU; + for (xiv = IA64_NXIVS - 1; xiv >= IA64_MIN_XIV; xiv--) { + if (ia64_xiv[xiv] != IA64_XIV_IRQ) + continue; + i = ia64_intrs[xiv]; + do { + cpu = (cpu == 0) ? MAXCPU - 1 : cpu - 1; + pc = cpuid_to_pcpu[cpu]; + } while (pc == NULL || !pc->pc_md.awake); + sapic_bind_intr(i->irq, pc); + } +} + +/* + * Interrupt handlers. + */ + +void +ia64_handle_intr(struct trapframe *tf) +{ + struct thread *td; + u_int xiv; + + td = curthread; + ia64_set_fpsr(IA64_FPSR_DEFAULT); + PCPU_INC(cnt.v_intr); + + xiv = ia64_get_ivr(); + ia64_srlz_d(); + if (xiv == 15) { + PCPU_INC(md.stats.pcs_nstrays); + goto out; + } + + critical_enter(); + + do { + CTR2(KTR_INTR, "INTR: ITC=%u, XIV=%u", + (u_int)tf->tf_special.ifa, xiv); + (ia64_handler[xiv])(td, xiv, tf); + ia64_set_eoi(0); + ia64_srlz_d(); + xiv = ia64_get_ivr(); + ia64_srlz_d(); + } while (xiv != 15); + + critical_exit(); + + out: + if (TRAPF_USERMODE(tf)) { + while (td->td_flags & (TDF_ASTPENDING|TDF_NEEDRESCHED)) { + ia64_enable_intr(); + ast(tf); + ia64_disable_intr(); + } + } +} + +static u_int +ia64_ih_invalid(struct thread *td, u_int xiv, struct trapframe *tf) +{ + + panic("invalid XIV: %u", xiv); + return (0); +} + +static u_int +ia64_ih_irq(struct thread *td, u_int xiv, struct trapframe *tf) { struct ia64_intr *i; struct intr_event *ie; /* our interrupt event */ - /* - * Find the interrupt thread for this vector. - */ - i = ia64_intrs[vector]; - KASSERT(i != NULL, ("%s: unassigned vector", __func__)); + PCPU_INC(md.stats.pcs_nhwints); + + /* Find the interrupt thread for this XIV. */ + i = ia64_intrs[xiv]; + KASSERT(i != NULL, ("%s: unassigned XIV", __func__)); (*i->cntp)++; ie = i->event; KASSERT(ie != NULL, ("%s: interrupt without event", __func__)); - if (intr_event_handle(ie, frame) != 0) { - /* - * XXX: The pre-INTR_FILTER code didn't mask stray - * interrupts. - */ - ia64_intr_mask((void *)(uintptr_t)vector); + if (intr_event_handle(ie, tf) != 0) { + ia64_intr_mask((void *)(uintptr_t)xiv); log(LOG_ERR, "stray irq%u\n", i->irq); } + + return (0); } #ifdef DDB static void -db_print_vector(u_int vector, int always) +db_print_xiv(u_int xiv, int always) { struct ia64_intr *i; - i = ia64_intrs[vector]; + i = ia64_intrs[xiv]; if (i != NULL) { - db_printf("vector %u (%p): ", vector, i); + db_printf("XIV %u (%p): ", xiv, i); sapic_print(i->sapic, i->irq); } else if (always) - db_printf("vector %u: unassigned\n", vector); + db_printf("XIV %u: unassigned\n", xiv); } -DB_SHOW_COMMAND(vector, db_show_vector) +DB_SHOW_COMMAND(xiv, db_show_xiv) { - u_int vector; + u_int xiv; if (have_addr) { - vector = ((addr >> 4) % 16) * 10 + (addr % 16); - if (vector >= 256) - db_printf("error: vector %u not in range [0..255]\n", - vector); + xiv = ((addr >> 4) % 16) * 10 + (addr % 16); + if (xiv >= IA64_NXIVS) + db_printf("error: XIV %u not in range [0..%u]\n", + xiv, IA64_NXIVS - 1); else - db_print_vector(vector, 1); + db_print_xiv(xiv, 1); } else { - for (vector = 0; vector < 256; vector++) - db_print_vector(vector, 0); + for (xiv = 0; xiv < IA64_NXIVS; xiv++) + db_print_xiv(xiv, 0); } } diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S index 6b1d8f15399..ce66dcacec6 100644 --- a/sys/ia64/ia64/locore.S +++ b/sys/ia64/ia64/locore.S @@ -26,16 +26,13 @@ * $FreeBSD$ */ +#include #include #include -#include -#include -#include - -#ifndef EVCNT_COUNTERS -#define _LOCORE #include -#endif +#include +#include +#include .section .data.proc0,"aw" .global kstack @@ -98,13 +95,13 @@ ENTRY_NOPROFILE(__start, 1) mov out0=r0 // we are linked at the right address ;; // we just need to process fptrs } -{ .bbb +{ .mib nop 0 nop 0 br.call.sptk.many rp=_reloc ;; } -{ .bbb +{ .mib nop 0 nop 0 br.call.sptk.many rp=ia64_init @@ -112,21 +109,21 @@ ENTRY_NOPROFILE(__start, 1) } // We have the new bspstore in r8 and the new sp in r9. // Switch onto the new stack and call mi_startup(). -{ +{ .mmi mov ar.rsc = 0 ;; mov ar.bspstore = r8 mov sp = r9 ;; } -{ +{ .mmi loadrs ;; mov ar.rsc = 3 nop 0 ;; } -{ +{ .mib nop 0 nop 0 br.call.sptk.many rp=mi_startup @@ -163,7 +160,7 @@ ENTRY(fork_trampoline, 0) ld8 out1=[r16] nop 0 } -{ .mfb +{ .mib add out2=16,sp nop 0 br.call.sptk rp=fork_exit @@ -174,7 +171,7 @@ ENTRY(fork_trampoline, 0) .global enter_userland .type enter_userland, @function enter_userland: -{ .mfb +{ .mib nop 0 nop 0 br.sptk epc_syscall_return @@ -282,7 +279,7 @@ ENTRY_NOPROFILE(os_boot_rendez,0) add sp = r18, r16 ;; } -{ .mfb +{ .mib mov ar.rsc = 3 nop 0 br.call.sptk.few rp = ia64_ap_startup @@ -290,7 +287,7 @@ ENTRY_NOPROFILE(os_boot_rendez,0) } /* NOT REACHED */ 9: -{ .mfb +{ .mib nop 0 nop 0 br.sptk 9b @@ -310,7 +307,7 @@ EXPORT(intrnames) .ascii "clock" .fill INTRNAME_LEN - 5 - 1, 1, ' ' .byte 0 -intr_n = 0 +intr_n = 1 .rept INTRCNT_COUNT - 1 .ascii "#" .byte intr_n / 100 + '0' diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index c3e7654589e..e2e9f9141d9 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -80,7 +80,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include @@ -100,8 +99,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - SYSCTL_NODE(_hw, OID_AUTO, freq, CTLFLAG_RD, 0, ""); SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RD, 0, ""); @@ -374,18 +371,11 @@ cpu_startup(void *dummy) SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx, SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO, "nstrays", CTLFLAG_RD, &pcs->pcs_nstrays, - "Number of stray vectors"); + "Number of stray interrupts"); } } SYSINIT(cpu_startup, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); -void -cpu_boot(int howto) -{ - - efi_reset_system(); -} - void cpu_flush_dcache(void *ptr, size_t len) { @@ -441,7 +431,7 @@ void cpu_reset() { - cpu_boot(0); + efi_reset_system(); } void @@ -456,19 +446,23 @@ cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx) if (PCPU_GET(fpcurthread) == old) old->td_frame->tf_special.psr |= IA64_PSR_DFH; if (!savectx(oldpcb)) { - old->td_lock = mtx; -#if defined(SCHED_ULE) && defined(SMP) - /* td_lock is volatile */ - while (new->td_lock == &blocked_lock) - ; -#endif + atomic_store_rel_ptr(&old->td_lock, mtx); + newpcb = new->td_pcb; oldpcb->pcb_current_pmap = pmap_switch(newpcb->pcb_current_pmap); + +#if defined(SCHED_ULE) && defined(SMP) + while (atomic_load_acq_ptr(&new->td_lock) == &blocked_lock) + cpu_spinwait(); +#endif + PCPU_SET(curthread, new); + #ifdef COMPAT_IA32 ia32_restorectx(newpcb); #endif + if (PCPU_GET(fpcurthread) == new) new->td_frame->tf_special.psr &= ~IA64_PSR_DFH; restorectx(newpcb); @@ -485,10 +479,18 @@ cpu_throw(struct thread *old __unused, struct thread *new) newpcb = new->td_pcb; (void)pmap_switch(newpcb->pcb_current_pmap); + +#if defined(SCHED_ULE) && defined(SMP) + while (atomic_load_acq_ptr(&new->td_lock) == &blocked_lock) + cpu_spinwait(); +#endif + PCPU_SET(curthread, new); + #ifdef COMPAT_IA32 ia32_restorectx(newpcb); #endif + restorectx(newpcb); /* We should not get here. */ panic("cpu_throw: restorectx() returned"); @@ -716,16 +718,6 @@ ia64_init(void) */ boothowto = bootinfo.bi_boothowto; - /* - * Catch case of boot_verbose set in environment. - */ - if ((p = getenv("boot_verbose")) != NULL) { - if (strcmp(p, "yes") == 0 || strcmp(p, "YES") == 0) { - boothowto |= RB_VERBOSE; - } - freeenv(p); - } - if (boothowto & RB_VERBOSE) bootverbose = 1; @@ -779,6 +771,7 @@ ia64_init(void) */ map_pal_code(); efi_boot_minimal(bootinfo.bi_systab); + ia64_xiv_init(); ia64_sal_init(); calculate_frequencies(); @@ -793,7 +786,7 @@ ia64_init(void) init_param1(); p = getenv("kernelname"); - if (p) { + if (p != NULL) { strncpy(kernelname, p, sizeof(kernelname) - 1); freeenv(p); } diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index c5ed48f501d..600803a74b4 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -46,11 +46,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include -#include - #include #include #include @@ -59,10 +54,13 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include -#include + +#include +#include +#include +#include MALLOC_DEFINE(M_SMP, "SMP", "SMP related allocations"); @@ -81,7 +79,68 @@ volatile int ap_delay; volatile int ap_awake; volatile int ap_spin; -static void cpu_mp_unleash(void *); +int ia64_ipi_ast; +int ia64_ipi_highfp; +int ia64_ipi_nmi; +int ia64_ipi_preempt; +int ia64_ipi_rndzvs; +int ia64_ipi_stop; + +static u_int +ia64_ih_ast(struct thread *td, u_int xiv, struct trapframe *tf) +{ + + PCPU_INC(md.stats.pcs_nasts); + CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid)); + return (0); +} + +static u_int +ia64_ih_highfp(struct thread *td, u_int xiv, struct trapframe *tf) +{ + + PCPU_INC(md.stats.pcs_nhighfps); + ia64_highfp_save_ipi(); + return (0); +} + +static u_int +ia64_ih_preempt(struct thread *td, u_int xiv, struct trapframe *tf) +{ + + PCPU_INC(md.stats.pcs_npreempts); + CTR1(KTR_SMP, "IPI_PREEMPT, cpuid=%d", PCPU_GET(cpuid)); + sched_preempt(curthread); + return (0); +} + +static u_int +ia64_ih_rndzvs(struct thread *td, u_int xiv, struct trapframe *tf) +{ + + PCPU_INC(md.stats.pcs_nrdvs); + CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid)); + smp_rendezvous_action(); + return (0); +} + +static u_int +ia64_ih_stop(struct thread *td, u_int xiv, struct trapframe *tf) +{ + cpumask_t mybit; + + PCPU_INC(md.stats.pcs_nstops); + mybit = PCPU_GET(cpumask); + + savectx(PCPU_PTR(md.pcb)); + + atomic_set_int(&stopped_cpus, mybit); + while ((started_cpus & mybit) == 0) + cpu_spinwait(); + atomic_clear_int(&started_cpus, mybit); + atomic_clear_int(&stopped_cpus, mybit); + return (0); +} struct cpu_group * cpu_topo(void) @@ -116,7 +175,6 @@ void ia64_ap_startup(void) { uint64_t vhpt; - int vector; pcpup = ap_pcpu; ia64_set_k4((intptr_t)pcpup); @@ -148,24 +206,11 @@ ia64_ap_startup(void) CTR1(KTR_SMP, "SMP: cpu%d launched", PCPU_GET(cpuid)); - /* Acknowledge and EOI all interrupts. */ - vector = ia64_get_ivr(); - while (vector != 15) { - ia64_srlz_d(); - if (vector == 0) - vector = (int)ia64_ld1(&ia64_pib->ib_inta); - ia64_set_eoi(0); - ia64_srlz_d(); - vector = ia64_get_ivr(); - } - ia64_srlz_d(); - - /* kick off the clock on this AP */ - pcpu_initclock(); - + /* Mask interval timer interrupts on APs. */ + ia64_set_itv(0x10000); ia64_set_tpr(0); ia64_srlz_d(); - enable_intr(); + ia64_enable_intr(); sched_throw(NULL); /* NOTREACHED */ @@ -200,7 +245,7 @@ cpu_mp_probe(void) * case we can have multiple processors, but we simply can't wake * them up... */ - return (mp_ncpus > 1 && ipi_vector[IPI_AP_WAKEUP] != 0); + return (mp_ncpus > 1 && ia64_ipi_wakeup != 0); } void @@ -276,7 +321,7 @@ cpu_mp_start() if (bootverbose) printf("SMP: waking up cpu%d\n", pc->pc_cpuid); - ipi_send(pc, IPI_AP_WAKEUP); + ipi_send(pc, ia64_ipi_wakeup); do { DELAY(1000); @@ -300,6 +345,18 @@ cpu_mp_unleash(void *dummy) if (mp_ncpus <= 1) return; + /* Allocate XIVs for IPIs */ + ia64_ipi_ast = ia64_xiv_alloc(PI_DULL, IA64_XIV_IPI, ia64_ih_ast); + ia64_ipi_highfp = ia64_xiv_alloc(PI_AV, IA64_XIV_IPI, ia64_ih_highfp); + ia64_ipi_preempt = ia64_xiv_alloc(PI_SOFT, IA64_XIV_IPI, + ia64_ih_preempt); + ia64_ipi_rndzvs = ia64_xiv_alloc(PI_AV, IA64_XIV_IPI, ia64_ih_rndzvs); + ia64_ipi_stop = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IPI, ia64_ih_stop); + + /* Reserve the NMI vector for IPI_STOP_HARD if possible */ + ia64_ipi_nmi = (ia64_xiv_reserve(2, IA64_XIV_IPI, ia64_ih_stop) != 0) + ? ia64_ipi_stop : 0x400; /* DM=NMI, Vector=n/a */ + cpus = 0; smp_cpus = 0; SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { @@ -325,6 +382,12 @@ cpu_mp_unleash(void *dummy) smp_active = 1; smp_started = 1; + + /* + * Now that all CPUs are up and running, bind interrupts to each of + * them. + */ + ia64_bind_intr(); } /* @@ -361,20 +424,18 @@ ipi_all_but_self(int ipi) * fields are used here. */ void -ipi_send(struct pcpu *cpu, int ipi) +ipi_send(struct pcpu *cpu, int xiv) { u_int lid; - uint8_t vector; + + KASSERT(xiv != 0, ("ipi_send")); lid = LID_SAPIC(cpu->pc_md.lid); - vector = ipi_vector[ipi]; - KASSERT(vector != 0, ("IPI %d is not assigned a vector", ipi)); ia64_mf(); - ia64_st8(&(ia64_pib->ib_ipi[lid][0]), vector); + ia64_st8(&(ia64_pib->ib_ipi[lid][0]), xiv); ia64_mf_a(); - CTR4(KTR_SMP, "ipi_send(%p, %ld): cpuid=%d, vector=%u", cpu, ipi, - PCPU_GET(cpuid), vector); + CTR3(KTR_SMP, "ipi_send(%p, %d): cpuid=%d", cpu, xiv, PCPU_GET(cpuid)); } SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, cpu_mp_unleash, NULL); diff --git a/sys/ia64/ia64/nexus.c b/sys/ia64/ia64/nexus.c index 5ce4731eb8f..9885b747aa2 100644 --- a/sys/ia64/ia64/nexus.c +++ b/sys/ia64/ia64/nexus.c @@ -50,16 +50,15 @@ #include #include #include +#include #include #include #include #include -#include #include #include -#include #include #include @@ -74,12 +73,11 @@ static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); struct nexus_device { struct resource_list nx_resources; - int nx_pcibus; }; #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) -static struct rman irq_rman, drq_rman, port_rman, mem_rman; +static struct rman irq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static int nexus_attach(device_t); @@ -88,8 +86,6 @@ static device_t nexus_add_child(device_t bus, int order, const char *name, int unit); static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); -static int nexus_read_ivar(device_t, device_t, int, uintptr_t *); -static int nexus_write_ivar(device_t, device_t, int, uintptr_t); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); static int nexus_deactivate_resource(device_t, device_t, int, int, @@ -106,6 +102,7 @@ static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long); static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *); static void nexus_delete_resource(device_t, device_t, int, int); +static int nexus_bind_intr(device_t, device_t, struct resource *, int); static int nexus_config_intr(device_t, int, enum intr_trigger, enum intr_polarity); @@ -124,8 +121,6 @@ static device_method_t nexus_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, nexus_print_child), DEVMETHOD(bus_add_child, nexus_add_child), - DEVMETHOD(bus_read_ivar, nexus_read_ivar), - DEVMETHOD(bus_write_ivar, nexus_write_ivar), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_release_resource, nexus_release_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), @@ -136,6 +131,7 @@ static device_method_t nexus_methods[] = { DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_get_resource, nexus_get_resource), DEVMETHOD(bus_delete_resource, nexus_delete_resource), + DEVMETHOD(bus_bind_intr, nexus_bind_intr), DEVMETHOD(bus_config_intr, nexus_config_intr), /* Clock interface */ @@ -160,56 +156,15 @@ nexus_probe(device_t dev) device_quiet(dev); /* suppress attach message for neatness */ - /* - * XXX working notes: - * - * - IRQ resource creation should be moved to the PIC/APIC driver. - * - DRQ resource creation should be moved to the DMAC driver. - * - The above should be sorted to probe earlier than any child busses. - * - * - Leave I/O and memory creation here, as child probes may need them. - * (especially eg. ACPI) - */ - - /* - * IRQ's are on the mainboard on old systems, but on the ISA part - * of PCI->ISA bridges. There would be multiple sets of IRQs on - * multi-ISA-bus systems. PCI interrupts are routed to the ISA - * component, so in a way, PCI can be a partial child of an ISA bus(!). - * APIC interrupts are global though. - * - * XXX We depend on the AT PIC driver correctly claiming IRQ 2 - * to prevent its reuse elsewhere in the !APIC_IO case. - */ - irq_rman.rm_start = 0; irq_rman.rm_type = RMAN_ARRAY; irq_rman.rm_descr = "Interrupt request lines"; - irq_rman.rm_end = 255; + irq_rman.rm_start = 0; + irq_rman.rm_end = IA64_NXIVS - 1; if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, irq_rman.rm_start, irq_rman.rm_end)) panic("nexus_probe irq_rman"); - /* - * ISA DMA on PCI systems is implemented in the ISA part of each - * PCI->ISA bridge and the channels can be duplicated if there are - * multiple bridges. (eg: laptops with docking stations) - */ - drq_rman.rm_start = 0; - drq_rman.rm_end = 7; - drq_rman.rm_type = RMAN_ARRAY; - drq_rman.rm_descr = "DMA request lines"; - /* XXX drq 0 not available on some machines */ - if (rman_init(&drq_rman) - || rman_manage_region(&drq_rman, - drq_rman.rm_start, drq_rman.rm_end)) - panic("nexus_probe drq_rman"); - - /* - * However, IO ports and Memory truely are global at this level, - * as are APIC interrupts (however many IO APICS there turn out - * to be on large systems..) - */ port_rman.rm_start = 0; port_rman.rm_end = 0xffff; port_rman.rm_type = RMAN_ARRAY; @@ -257,8 +212,6 @@ nexus_print_child(device_t bus, device_t child) retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx"); retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#lx"); retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); - if (ndev->nx_pcibus != -1) - retval += printf(" pcibus %d", ndev->nx_pcibus); if (device_get_flags(child)) retval += printf(" flags %#x", device_get_flags(child)); retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */ @@ -276,7 +229,6 @@ nexus_add_child(device_t bus, int order, const char *name, int unit) if (!ndev) return(0); resource_list_init(&ndev->nx_resources); - ndev->nx_pcibus = -1; child = device_add_child_ordered(bus, order, name, unit); @@ -286,37 +238,6 @@ nexus_add_child(device_t bus, int order, const char *name, int unit) return(child); } -static int -nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) -{ - struct nexus_device *ndev = DEVTONX(child); - - switch (which) { - case NEXUS_IVAR_PCIBUS: - *result = ndev->nx_pcibus; - break; - default: - return ENOENT; - } - return 0; -} - - -static int -nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) -{ - struct nexus_device *ndev = DEVTONX(child); - - switch (which) { - case NEXUS_IVAR_PCIBUS: - ndev->nx_pcibus = value; - break; - default: - return ENOENT; - } - return 0; -} - /* * Allocate a resource on behalf of child. NB: child is usually going to be a @@ -356,10 +277,6 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, rm = &irq_rman; break; - case SYS_RES_DRQ: - rm = &drq_rman; - break; - case SYS_RES_IOPORT: rm = &port_rman; break; @@ -547,6 +464,17 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, return (sapic_config_intr(irq, trig, pol)); } +static int +nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu) +{ + struct pcpu *pc; + + pc = cpuid_to_pcpu[cpu]; + if (pc == NULL) + return (EINVAL); + return (sapic_bind_intr(rman_get_start(irq), pc)); +} + static int nexus_gettime(device_t dev, struct timespec *ts) { @@ -592,4 +520,3 @@ nexus_settime(device_t dev, struct timespec *ts) tm.tm_mday = ct.day; return (efi_set_time(&tm)); } - diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index f8297462a12..6fe4cdf987e 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -238,7 +238,7 @@ static pv_entry_t get_pv_entry(pmap_t locked_pmap); static void pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot); static void pmap_free_pte(struct ia64_lpte *pte, vm_offset_t va); -static void pmap_invalidate_all(pmap_t pmap); +static void pmap_invalidate_all(void); static int pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte, vm_offset_t va, pv_entry_t pv, int freepte); static int pmap_remove_vhpt(vm_offset_t va); @@ -475,7 +475,7 @@ pmap_bootstrap() /* * Clear out any random TLB entries left over from booting. */ - pmap_invalidate_all(kernel_pmap); + pmap_invalidate_all(); map_gateway_page(); } @@ -536,21 +536,19 @@ pmap_init(void) ***************************************************/ static void -pmap_invalidate_page(pmap_t pmap, vm_offset_t va) +pmap_invalidate_page(vm_offset_t va) { struct ia64_lpte *pte; struct pcpu *pc; + uint64_t tag; u_int vhpt_ofs; - KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)), - ("invalidating TLB for non-current pmap")); - - vhpt_ofs = ia64_thash(va) - PCPU_GET(md.vhpt); critical_enter(); + vhpt_ofs = ia64_thash(va) - PCPU_GET(md.vhpt); + tag = ia64_ttag(va); SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { pte = (struct ia64_lpte *)(pc->pc_md.vhpt + vhpt_ofs); - if (pte->tag == ia64_ttag(va)) - pte->tag = 1UL << 63; + atomic_cmpset_64(&pte->tag, tag, 1UL << 63); } critical_exit(); mtx_lock_spin(&pmap_ptcmutex); @@ -577,16 +575,14 @@ pmap_invalidate_all_1(void *arg) } static void -pmap_invalidate_all(pmap_t pmap) +pmap_invalidate_all(void) { - KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)), - ("invalidating TLB for non-current pmap")); - #ifdef SMP - if (mp_ncpus > 1) + if (mp_ncpus > 1) { smp_rendezvous(NULL, pmap_invalidate_all_1, NULL, NULL); - else + return; + } #endif pmap_invalidate_all_1(NULL); } @@ -794,7 +790,7 @@ retry: pte = pmap_find_vhpt(va); KASSERT(pte != NULL, ("pte")); pmap_remove_vhpt(va); - pmap_invalidate_page(pmap, va); + pmap_invalidate_page(va); pmap_switch(oldpmap); if (pmap_accessed(pte)) vm_page_flag_set(m, PG_REFERENCED); @@ -1160,9 +1156,6 @@ pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte, vm_offset_t va, int error; vm_page_t m; - KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)), - ("removing pte for non-current pmap")); - /* * First remove from the VHPT. */ @@ -1170,7 +1163,7 @@ pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte, vm_offset_t va, if (error) return (error); - pmap_invalidate_page(pmap, va); + pmap_invalidate_page(va); if (pmap_wired(pte)) pmap->pm_stats.wired_count -= 1; @@ -1238,7 +1231,7 @@ pmap_qenter(vm_offset_t va, vm_page_t *m, int count) for (i = 0; i < count; i++) { pte = pmap_find_kpte(va); if (pmap_present(pte)) - pmap_invalidate_page(kernel_pmap, va); + pmap_invalidate_page(va); else pmap_enter_vhpt(pte, va); pmap_pte_prot(kernel_pmap, pte, VM_PROT_ALL); @@ -1261,7 +1254,7 @@ pmap_qremove(vm_offset_t va, int count) pte = pmap_find_kpte(va); if (pmap_present(pte)) { pmap_remove_vhpt(va); - pmap_invalidate_page(kernel_pmap, va); + pmap_invalidate_page(va); pmap_clear_present(pte); } va += PAGE_SIZE; @@ -1279,7 +1272,7 @@ pmap_kenter(vm_offset_t va, vm_offset_t pa) pte = pmap_find_kpte(va); if (pmap_present(pte)) - pmap_invalidate_page(kernel_pmap, va); + pmap_invalidate_page(va); else pmap_enter_vhpt(pte, va); pmap_pte_prot(kernel_pmap, pte, VM_PROT_ALL); @@ -1297,7 +1290,7 @@ pmap_kremove(vm_offset_t va) pte = pmap_find_kpte(va); if (pmap_present(pte)) { pmap_remove_vhpt(va); - pmap_invalidate_page(kernel_pmap, va); + pmap_invalidate_page(va); pmap_clear_present(pte); } } @@ -1320,23 +1313,6 @@ pmap_map(vm_offset_t *virt, vm_offset_t start, vm_offset_t end, int prot) return IA64_PHYS_TO_RR7(start); } -/* - * Remove a single page from a process address space - */ -static void -pmap_remove_page(pmap_t pmap, vm_offset_t va) -{ - struct ia64_lpte *pte; - - KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)), - ("removing page for non-current pmap")); - - pte = pmap_find_vhpt(va); - if (pte != NULL) - pmap_remove_pte(pmap, pte, va, 0, 1); - return; -} - /* * Remove the given range of addresses from the specified map. * @@ -1364,7 +1340,9 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) * code. */ if (sva + PAGE_SIZE == eva) { - pmap_remove_page(pmap, sva); + pte = pmap_find_vhpt(sva); + if (pte != NULL) + pmap_remove_pte(pmap, pte, sva, 0, 1); goto out; } @@ -1491,7 +1469,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) ia64_sync_icache(sva, PAGE_SIZE); pmap_pte_prot(pmap, pte, prot); - pmap_invalidate_page(pmap, sva); + pmap_invalidate_page(sva); } vm_page_unlock_queues(); pmap_switch(oldpmap); @@ -1582,7 +1560,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m, else if (pmap_exec(&origpte)) icache_inval = FALSE; - pmap_invalidate_page(pmap, va); + pmap_invalidate_page(va); goto validate; } @@ -1929,7 +1907,8 @@ pmap_remove_pages(pmap_t pmap) pv_entry_t pv, npv; if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace)) { - printf("warning: pmap_remove_pages called with non-current pmap\n"); + printf("warning: %s called with non-current pmap\n", + __func__); return; } @@ -1984,7 +1963,7 @@ pmap_ts_referenced(vm_page_t m) if (pmap_accessed(pte)) { count++; pmap_clear_accessed(pte); - pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + pmap_invalidate_page(pv->pv_va); } pmap_switch(oldpmap); PMAP_UNLOCK(pv->pv_pmap); @@ -2063,7 +2042,7 @@ pmap_clear_modify(vm_page_t m) KASSERT(pte != NULL, ("pte")); if (pmap_dirty(pte)) { pmap_clear_dirty(pte); - pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + pmap_invalidate_page(pv->pv_va); } pmap_switch(oldpmap); PMAP_UNLOCK(pv->pv_pmap); @@ -2092,7 +2071,7 @@ pmap_clear_reference(vm_page_t m) KASSERT(pte != NULL, ("pte")); if (pmap_accessed(pte)) { pmap_clear_accessed(pte); - pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + pmap_invalidate_page(pv->pv_va); } pmap_switch(oldpmap); PMAP_UNLOCK(pv->pv_pmap); @@ -2128,7 +2107,7 @@ pmap_remove_write(vm_page_t m) } prot &= ~VM_PROT_WRITE; pmap_pte_prot(pmap, pte, prot); - pmap_invalidate_page(pmap, pv->pv_va); + pmap_invalidate_page(pv->pv_va); } pmap_switch(oldpmap); PMAP_UNLOCK(pmap); diff --git a/sys/ia64/ia64/sal.c b/sys/ia64/ia64/sal.c index 4f46d652b02..6f081be8601 100644 --- a/sys/ia64/ia64/sal.c +++ b/sys/ia64/ia64/sal.c @@ -29,21 +29,18 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include #include #include +#include #include #include #include -/* - * IPIs are used more genericly than only - * for inter-processor interrupts. Don't - * make it a SMP specific thing... - */ -int ipi_vector[IPI_COUNT]; +int ia64_ipi_wakeup; static struct ia64_fdesc sal_fdesc; static sal_entry_t fake_sal; @@ -66,22 +63,6 @@ fake_sal(u_int64_t a1, u_int64_t a2, u_int64_t a3, u_int64_t a4, return res; } -static void -setup_ipi_vectors(int ceil) -{ - int ipi; - - ipi_vector[IPI_MCA_RENDEZ] = ceil - 0x10; - - ipi = IPI_AST; /* First generic IPI. */ - ceil -= 0x20; /* First vector in group. */ - while (ipi < IPI_COUNT) - ipi_vector[ipi++] = ceil++; - - ipi_vector[IPI_HIGH_FP] = ceil - 0x30; - ipi_vector[IPI_MCA_CMCV] = ceil - 0x30 + 1; -} - void ia64_sal_init(void) { @@ -89,7 +70,7 @@ ia64_sal_init(void) 48, 32, 16, 32, 16, 16 }; u_int8_t *p; - int i; + int error, i; sal_systbl = efi_get_table(&sal_table); if (sal_systbl == NULL) @@ -132,36 +113,19 @@ ia64_sal_init(void) break; } - if (dp->sale_vector < 0x10 || dp->sale_vector > 0xff) { - printf("SAL: invalid AP wake-up vector " - "(0x%lx)\n", dp->sale_vector); - break; - } - - /* - * SAL documents that the wake-up vector should be - * high (close to 255). The MCA rendezvous vector - * should be less than the wake-up vector, but still - * "high". We use the following priority assignment: - * Wake-up: priority of the sale_vector - * Rendezvous: priority-1 - * Generic IPIs: priority-2 - * Special IPIs: priority-3 - * Consequently, the wake-up priority should be at - * least 4 (ie vector >= 0x40). - */ - if (dp->sale_vector < 0x40) { - printf("SAL: AP wake-up vector too low " - "(0x%lx)\n", dp->sale_vector); - break; - } - - if (bootverbose) - printf("SAL: AP wake-up vector: 0x%lx\n", + /* Reserve the XIV so that we won't use it. */ + error = ia64_xiv_reserve(dp->sale_vector, + IA64_XIV_PLAT, NULL); + if (error) { + printf("SAL: invalid AP wake-up XIV (%#lx)\n", dp->sale_vector); + break; + } - ipi_vector[IPI_AP_WAKEUP] = dp->sale_vector; - setup_ipi_vectors(dp->sale_vector & 0xf0); + ia64_ipi_wakeup = dp->sale_vector; + if (bootverbose) + printf("SAL: AP wake-up XIV: %#x\n", + ia64_ipi_wakeup); #ifdef SMP fd = (struct ia64_fdesc *) os_boot_rendez; @@ -175,7 +139,4 @@ ia64_sal_init(void) } p += sizes[*p]; } - - if (ipi_vector[IPI_AP_WAKEUP] == 0) - setup_ipi_vectors(0xf0); } diff --git a/sys/ia64/ia64/sapic.c b/sys/ia64/ia64/sapic.c index 88bd0139872..5aa14493e77 100644 --- a/sys/ia64/ia64/sapic.c +++ b/sys/ia64/ia64/sapic.c @@ -35,81 +35,105 @@ #include #include #include +#include #include #include #include -#include -#include #include #include -static MALLOC_DEFINE(M_SAPIC, "sapic", "I/O SAPIC devices"); +/* + * Offsets from the SAPIC base in memory. Most registers are accessed + * by indexing using the SAPIC_IO_SELECT register. + */ +#define SAPIC_IO_SELECT 0x00 +#define SAPIC_IO_WINDOW 0x10 +#define SAPIC_APIC_EOI 0x40 + +/* + * Indexed registers. + */ +#define SAPIC_ID 0x00 +#define SAPIC_VERSION 0x01 +#define SAPIC_ARBITRATION_ID 0x02 +#define SAPIC_RTE_BASE 0x10 + +/* Interrupt polarity. */ +#define SAPIC_POLARITY_HIGH 0 +#define SAPIC_POLARITY_LOW 1 + +/* Interrupt trigger. */ +#define SAPIC_TRIGGER_EDGE 0 +#define SAPIC_TRIGGER_LEVEL 1 + +/* Interrupt delivery mode. */ +#define SAPIC_DELMODE_FIXED 0 +#define SAPIC_DELMODE_LOWPRI 1 +#define SAPIC_DELMODE_PMI 2 +#define SAPIC_DELMODE_NMI 4 +#define SAPIC_DELMODE_INIT 5 +#define SAPIC_DELMODE_EXTINT 7 + +struct sapic { + struct mtx sa_mtx; + uint64_t sa_registers; /* virtual address of sapic */ + u_int sa_id; /* I/O SAPIC Id */ + u_int sa_base; /* ACPI vector base */ + u_int sa_limit; /* last ACPI vector handled here */ +}; + +struct sapic_rte { + uint64_t rte_vector :8; + uint64_t rte_delivery_mode :3; + uint64_t rte_destination_mode :1; + uint64_t rte_delivery_status :1; + uint64_t rte_polarity :1; + uint64_t rte_rirr :1; + uint64_t rte_trigger_mode :1; + uint64_t rte_mask :1; + uint64_t rte_flushen :1; + uint64_t rte_reserved :30; + uint64_t rte_destination_eid :8; + uint64_t rte_destination_id :8; +}; + +MALLOC_DEFINE(M_SAPIC, "sapic", "I/O SAPIC devices"); + +struct sapic *ia64_sapics[16]; /* XXX make this resizable */ +int ia64_sapic_count; static int sysctl_machdep_apic(SYSCTL_HANDLER_ARGS); SYSCTL_OID(_machdep, OID_AUTO, apic, CTLTYPE_STRING|CTLFLAG_RD, NULL, 0, sysctl_machdep_apic, "A", "(x)APIC redirection table entries"); -struct sapic *ia64_sapics[16]; /* XXX make this resizable */ -int ia64_sapic_count; - -struct sapic_rte { - u_int64_t rte_vector :8; - u_int64_t rte_delivery_mode :3; - u_int64_t rte_destination_mode :1; - u_int64_t rte_delivery_status :1; - u_int64_t rte_polarity :1; - u_int64_t rte_rirr :1; - u_int64_t rte_trigger_mode :1; - u_int64_t rte_mask :1; - u_int64_t rte_flushen :1; - u_int64_t rte_reserved :30; - u_int64_t rte_destination_eid :8; - u_int64_t rte_destination_id :8; -}; - -struct sapic * -sapic_lookup(u_int irq) -{ - struct sapic *sa; - int i; - - for (i = 0; i < ia64_sapic_count; i++) { - sa = ia64_sapics[i]; - if (irq >= sa->sa_base && irq <= sa->sa_limit) - return (sa); - } - - return (NULL); -} - -static __inline u_int32_t +static __inline uint32_t sapic_read(struct sapic *sa, int which) { - vm_offset_t reg = sa->sa_registers; + uint32_t value; - *(volatile u_int32_t *) (reg + SAPIC_IO_SELECT) = which; - ia64_mf(); - return *(volatile u_int32_t *) (reg + SAPIC_IO_WINDOW); + ia64_st4((void *)(sa->sa_registers + SAPIC_IO_SELECT), which); + ia64_mf_a(); + value = ia64_ld4((void *)(sa->sa_registers + SAPIC_IO_WINDOW)); + return (value); } static __inline void -sapic_write(struct sapic *sa, int which, u_int32_t value) +sapic_write(struct sapic *sa, int which, uint32_t value) { - vm_offset_t reg = sa->sa_registers; - *(volatile u_int32_t *) (reg + SAPIC_IO_SELECT) = which; - ia64_mf(); - *(volatile u_int32_t *) (reg + SAPIC_IO_WINDOW) = value; - ia64_mf(); + ia64_st4((void *)(sa->sa_registers + SAPIC_IO_SELECT), which); + ia64_mf_a(); + ia64_st4((void *)(sa->sa_registers + SAPIC_IO_WINDOW), value); + ia64_mf_a(); } static __inline void sapic_read_rte(struct sapic *sa, int which, struct sapic_rte *rte) { - u_int32_t *p = (u_int32_t *) rte; + uint32_t *p = (uint32_t *) rte; p[0] = sapic_read(sa, SAPIC_RTE_BASE + 2 * which); p[1] = sapic_read(sa, SAPIC_RTE_BASE + 2 * which + 1); @@ -118,10 +142,54 @@ sapic_read_rte(struct sapic *sa, int which, struct sapic_rte *rte) static __inline void sapic_write_rte(struct sapic *sa, int which, struct sapic_rte *rte) { - u_int32_t *p = (u_int32_t *) rte; + uint32_t *p = (uint32_t *) rte; - sapic_write(sa, SAPIC_RTE_BASE + 2 *which, p[0]); - sapic_write(sa, SAPIC_RTE_BASE + 2 *which + 1, p[1]); + sapic_write(sa, SAPIC_RTE_BASE + 2 * which, p[0]); + sapic_write(sa, SAPIC_RTE_BASE + 2 * which + 1, p[1]); +} + +struct sapic * +sapic_lookup(u_int irq, u_int *vecp) +{ + struct sapic_rte rte; + struct sapic *sa; + int i; + + for (i = 0; i < ia64_sapic_count; i++) { + sa = ia64_sapics[i]; + if (irq >= sa->sa_base && irq <= sa->sa_limit) { + if (vecp != NULL) { + mtx_lock_spin(&sa->sa_mtx); + sapic_read_rte(sa, irq - sa->sa_base, &rte); + mtx_unlock_spin(&sa->sa_mtx); + *vecp = rte.rte_vector; + } + return (sa); + } + } + + return (NULL); +} + + +int +sapic_bind_intr(u_int irq, struct pcpu *pc) +{ + struct sapic_rte rte; + struct sapic *sa; + + sa = sapic_lookup(irq, NULL); + if (sa == NULL) + return (EINVAL); + + mtx_lock_spin(&sa->sa_mtx); + sapic_read_rte(sa, irq - sa->sa_base, &rte); + rte.rte_destination_id = (pc->pc_md.lid >> 24) & 255; + rte.rte_destination_eid = (pc->pc_md.lid >> 16) & 255; + rte.rte_delivery_mode = SAPIC_DELMODE_FIXED; + sapic_write_rte(sa, irq - sa->sa_base, &rte); + mtx_unlock_spin(&sa->sa_mtx); + return (0); } int @@ -130,7 +198,7 @@ sapic_config_intr(u_int irq, enum intr_trigger trig, enum intr_polarity pol) struct sapic_rte rte; struct sapic *sa; - sa = sapic_lookup(irq); + sa = sapic_lookup(irq, NULL); if (sa == NULL) return (EINVAL); @@ -154,7 +222,7 @@ sapic_config_intr(u_int irq, enum intr_trigger trig, enum intr_polarity pol) } struct sapic * -sapic_create(u_int id, u_int base, u_int64_t address) +sapic_create(u_int id, u_int base, uint64_t address) { struct sapic_rte rte; struct sapic *sa; @@ -214,10 +282,9 @@ sapic_enable(struct sapic *sa, u_int irq, u_int vector) void sapic_eoi(struct sapic *sa, u_int vector) { - vm_offset_t reg = sa->sa_registers; - *(volatile u_int32_t *)(reg + SAPIC_APIC_EOI) = vector; - ia64_mf(); + ia64_st4((void *)(sa->sa_registers + SAPIC_APIC_EOI), vector); + ia64_mf_a(); } /* Expected to be called with interrupts disabled. */ diff --git a/sys/ia64/ia64/support.S b/sys/ia64/ia64/support.S index ea04276e9ec..1a82dd6391e 100644 --- a/sys/ia64/ia64/support.S +++ b/sys/ia64/ia64/support.S @@ -227,14 +227,14 @@ ENTRY(casuword, 3) nop 0 ;; } -{ .mfb +{ .mib st8.rel [r15]=r0 // Clear onfault nop 0 br.ret.sptk rp ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -277,14 +277,14 @@ ENTRY(casuword32, 3) nop 0 ;; } -{ .mfb +{ .mib st8.rel [r15]=r0 // Clear onfault nop 0 br.ret.sptk rp ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -338,7 +338,7 @@ ENTRY(subyte, 2) ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -384,7 +384,7 @@ ENTRY(suword16, 2) ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -430,7 +430,7 @@ ENTRY(suword32, 2) ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -477,7 +477,7 @@ XENTRY(suword) ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -531,7 +531,7 @@ ENTRY(fubyte, 1) ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -577,7 +577,7 @@ ENTRY(fuword16, 2) ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -623,7 +623,7 @@ ENTRY(fuword32, 2) ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -670,7 +670,7 @@ XENTRY(fuword) ;; } 1: -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -684,7 +684,7 @@ END(fuword64) */ ENTRY(fuswintr, 1) -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp @@ -693,7 +693,7 @@ ENTRY(fuswintr, 1) END(fuswintr) ENTRY(suswintr, 0) -{ .mfb +{ .mib add ret0=-1,r0 nop 0 br.ret.sptk rp diff --git a/sys/ia64/ia64/syscall.S b/sys/ia64/ia64/syscall.S index 73f8da67b83..b35523a66be 100644 --- a/sys/ia64/ia64/syscall.S +++ b/sys/ia64/ia64/syscall.S @@ -102,13 +102,13 @@ gw_ret: ;; } gw_ret_ia32: -{ .mfb +{ .mmi flushrs nop 0 nop 0 ;; } -{ .mfb +{ .mib nop 0 nop 0 br.ia.sptk b6 @@ -193,7 +193,7 @@ ENTRY_NOPROFILE(epc_sigtramp, 0) mov b7=r16 ;; } -{ .mmb +{ .mmi alloc r14=ar.pfs, 0, 0, 3, 0 mov ar.rsc=15 nop 0 @@ -204,7 +204,7 @@ ENTRY_NOPROFILE(epc_sigtramp, 0) mov out0=r8 mov out1=r9 } -{ .mfb +{ .mib add out2=16,sp nop 0 br.call.sptk rp=b7 @@ -257,7 +257,7 @@ ENTRY_NOPROFILE(epc_syscall, 8) add r31=8,r30 ;; } -{ .mib +{ .mii mov r22=ar.fpsr sub r29=r14,r30 nop 0 @@ -380,7 +380,7 @@ ENTRY_NOPROFILE(epc_syscall, 8) } .global epc_syscall_return epc_syscall_return: -{ .mfb +{ .mib add out0=16,sp nop 0 br.call.sptk rp=do_ast @@ -392,7 +392,7 @@ epc_syscall_return: (p15) br.spnt 1b // restart syscall ;; } -{ .mfb +{ .mmi ld8 r14=[r14] // tf_flags nop 0 nop 0 @@ -422,7 +422,7 @@ epc_syscall_return: add r31=r31,sp ;; } -{ .mmb +{ .mmi ld8 r19=[r15],16 // pr ld8 r20=[r14],16 // pfs (syscall caller) nop 0 @@ -434,7 +434,7 @@ epc_syscall_return: mov pr=r19,0x1fffe ;; } -{ .mmb +{ .mmi ld8 r23=[r15],16 // tp ld8 r24=[r14],16 // rsc nop 0 @@ -488,7 +488,7 @@ epc_syscall_return: dep r30=0,r30,0,13 // 8KB aligned. ;; } -{ .mib +{ .mii mov ar.k6=r30 mov r13=r23 nop 0 diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c index c966f0aaef1..2e59d7532a8 100644 --- a/sys/ia64/ia64/trap.c +++ b/sys/ia64/ia64/trap.c @@ -334,11 +334,11 @@ int do_ast(struct trapframe *tf) { - disable_intr(); + ia64_disable_intr(); while (curthread->td_flags & (TDF_ASTPENDING|TDF_NEEDRESCHED)) { - enable_intr(); + ia64_enable_intr(); ast(tf); - disable_intr(); + ia64_disable_intr(); } /* * Keep interrupts disabled. We return r10 as a favor to the EPC @@ -804,7 +804,7 @@ trap(int vector, struct trapframe *tf) * out of the gateway page we'll get back into the kernel * and then we enable single stepping. * Since this a rather round-about way of enabling single - * stepping, don't make things complicated even more by + * stepping, don't make things even more complicated by * calling userret() and do_ast(). We do that later... */ tf->tf_special.psr &= ~IA64_PSR_LP; @@ -815,13 +815,14 @@ trap(int vector, struct trapframe *tf) /* * Don't assume there aren't any branches other than the * branch that takes us out of the gateway page. Check the - * iip and raise SIGTRAP only when it's an user address. + * iip and enable single stepping only when it's an user + * address. */ if (tf->tf_special.iip >= VM_MAX_ADDRESS) return; tf->tf_special.psr &= ~IA64_PSR_TB; - sig = SIGTRAP; - break; + tf->tf_special.psr |= IA64_PSR_SS; + return; case IA64_VEC_IA32_EXCEPTION: case IA64_VEC_IA32_INTERCEPT: diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c index 37af94b081c..6222d3382af 100644 --- a/sys/ia64/ia64/vm_machdep.c +++ b/sys/ia64/ia64/vm_machdep.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -89,14 +90,11 @@ #include #include -#include #include #include #include #include -#include - void cpu_thread_exit(struct thread *td) { diff --git a/sys/ia64/include/acpica_machdep.h b/sys/ia64/include/acpica_machdep.h index 26191c0a527..38efffdfd79 100644 --- a/sys/ia64/include/acpica_machdep.h +++ b/sys/ia64/include/acpica_machdep.h @@ -56,8 +56,8 @@ #define ACPI_ASM_MACROS #define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() disable_intr() -#define ACPI_ENABLE_IRQS() enable_intr() +#define ACPI_DISABLE_IRQS() ia64_disable_intr() +#define ACPI_ENABLE_IRQS() ia64_enable_intr() #define ACPI_FLUSH_CPU_CACHE() /* XXX ia64_fc()? */ diff --git a/sys/ia64/include/clock.h b/sys/ia64/include/clock.h index 772fc2a29ed..6b87a89f9ed 100644 --- a/sys/ia64/include/clock.h +++ b/sys/ia64/include/clock.h @@ -9,12 +9,4 @@ #ifndef _MACHINE_CLOCK_H_ #define _MACHINE_CLOCK_H_ -#ifdef _KERNEL - -#define CLOCK_VECTOR 254 - -extern uint64_t ia64_clock_reload; - -#endif - #endif /* !_MACHINE_CLOCK_H_ */ diff --git a/sys/ia64/include/cpufunc.h b/sys/ia64/include/cpufunc.h index 9ae06a2253d..925d4bafa4a 100644 --- a/sys/ia64/include/cpufunc.h +++ b/sys/ia64/include/cpufunc.h @@ -56,13 +56,13 @@ breakpoint(void) static __inline void -disable_intr(void) +ia64_disable_intr(void) { __asm __volatile ("rsm psr.i"); } static __inline void -enable_intr(void) +ia64_enable_intr(void) { __asm __volatile ("ssm psr.i;; srlz.d"); } @@ -71,8 +71,9 @@ static __inline register_t intr_disable(void) { register_t psr; + __asm __volatile ("mov %0=psr;;" : "=r"(psr)); - disable_intr(); + ia64_disable_intr(); return ((psr & IA64_PSR_I) ? 1 : 0); } @@ -80,7 +81,7 @@ static __inline void intr_restore(register_t ie) { if (ie) - enable_intr(); + ia64_enable_intr(); } #endif /* __GNUCLIKE_ASM */ diff --git a/sys/ia64/include/frame.h b/sys/ia64/include/frame.h index 262a8bfd645..683d1644642 100644 --- a/sys/ia64/include/frame.h +++ b/sys/ia64/include/frame.h @@ -29,7 +29,9 @@ #ifndef _MACHINE_FRAME_H_ #define _MACHINE_FRAME_H_ +#ifndef _MACHINE_REGSET_H_ #include +#endif /* * Software trap, exception, and syscall frame. diff --git a/sys/ia64/include/intr.h b/sys/ia64/include/intr.h index 8651fdad110..81603cfabfd 100644 --- a/sys/ia64/include/intr.h +++ b/sys/ia64/include/intr.h @@ -30,6 +30,16 @@ #ifndef _MACHINE_INTR_H_ #define _MACHINE_INTR_H_ +#define IA64_NXIVS 256 /* External Interrupt Vectors */ +#define IA64_MIN_XIV 16 + +#define IA64_MAX_HWPRIO 14 + +struct pcpu; +struct sapic; +struct thread; +struct trapframe; + /* * Layout of the Processor Interrupt Block. */ @@ -44,10 +54,40 @@ struct ia64_pib uint8_t _rsvd4[0x1fff0]; }; +enum ia64_xiv_use { + IA64_XIV_FREE, + IA64_XIV_ARCH, /* Architecturally defined. */ + IA64_XIV_PLAT, /* Platform defined. */ + IA64_XIV_IPI, /* Used for IPIs. */ + IA64_XIV_IRQ /* Used for external interrupts. */ +}; + +typedef u_int (ia64_ihtype)(struct thread *, u_int, struct trapframe *); + extern struct ia64_pib *ia64_pib; -int ia64_setup_intr(const char *name, int irq, driver_filter_t filter, - driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep); -int ia64_teardown_intr(void *cookie); +void ia64_bind_intr(void); +void ia64_handle_intr(struct trapframe *); +int ia64_setup_intr(const char *, int, driver_filter_t, driver_intr_t, + void *, enum intr_type, void **); +int ia64_teardown_intr(void *); + +void ia64_xiv_init(void); +u_int ia64_xiv_alloc(u_int, enum ia64_xiv_use, ia64_ihtype); +int ia64_xiv_free(u_int, enum ia64_xiv_use); +int ia64_xiv_reserve(u_int, enum ia64_xiv_use, ia64_ihtype); + +int sapic_bind_intr(u_int, struct pcpu *); +int sapic_config_intr(u_int, enum intr_trigger, enum intr_polarity); +struct sapic *sapic_create(u_int, u_int, uint64_t); +int sapic_enable(struct sapic *, u_int, u_int); +void sapic_eoi(struct sapic *, u_int); +struct sapic *sapic_lookup(u_int, u_int *); +void sapic_mask(struct sapic *, u_int); +void sapic_unmask(struct sapic *, u_int); + +#ifdef DDB +void sapic_print(struct sapic *, u_int); +#endif #endif /* !_MACHINE_INTR_H_ */ diff --git a/sys/ia64/include/intrcnt.h b/sys/ia64/include/intrcnt.h index c4f73c01430..5e165ea75ef 100644 --- a/sys/ia64/include/intrcnt.h +++ b/sys/ia64/include/intrcnt.h @@ -29,11 +29,7 @@ */ #define INTRCNT_CLOCK 0 -#define INTRCNT_ISA_IRQ (INTRCNT_CLOCK + 1) -#define INTRCNT_ISA_IRQ_LEN 16 -#define INTRCNT_OTHER_BASE (INTRCNT_ISA_IRQ + INTRCNT_ISA_IRQ_LEN) -#define INTRCNT_OTHER_LEN 240 -#define INTRCNT_COUNT (INTRCNT_OTHER_BASE + INTRCNT_OTHER_LEN) +#define INTRCNT_COUNT 256 /* * Maximum name length in intrnames table (including terminating '\0'. diff --git a/sys/ia64/include/mca.h b/sys/ia64/include/mca.h index 75831c76ceb..94926d16915 100644 --- a/sys/ia64/include/mca.h +++ b/sys/ia64/include/mca.h @@ -39,6 +39,7 @@ struct mca_record_header { #define MCA_RH_ERROR_CORRECTED 2 uint8_t rh_flags; #define MCA_RH_FLAGS_PLATFORM_ID 0x01 /* Platform_id present. */ +#define MCA_RH_FLAGS_TIME_STAMP 0x02 /* Timestamp invalid. */ uint32_t rh_length; /* Size including header. */ uint8_t rh_time[8]; #define MCA_RH_TIME_SEC 0 diff --git a/sys/ia64/include/nexusvar.h b/sys/ia64/include/nexusvar.h deleted file mode 100644 index be38f33a075..00000000000 --- a/sys/ia64/include/nexusvar.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2000 Peter Wemm - * 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 _MACHINE_NEXUSVAR_H_ -#define _MACHINE_NEXUSVAR_H_ 1 - -enum nexus_device_ivars { - NEXUS_IVAR_PCIBUS -}; - -#define NEXUS_ACCESSOR(var, ivar, type) \ - __BUS_ACCESSOR(nexus, var, NEXUS, ivar, type) - -NEXUS_ACCESSOR(pcibus, PCIBUS, u_int32_t) - -#undef NEXUS_ACCESSOR - -#endif /* !_MACHINE_NEXUSVAR_H_ */ diff --git a/sys/ia64/include/pcb.h b/sys/ia64/include/pcb.h index 5d250bfeefd..59334bfa5d8 100644 --- a/sys/ia64/include/pcb.h +++ b/sys/ia64/include/pcb.h @@ -30,7 +30,9 @@ #ifndef _MACHINE_PCB_H_ #define _MACHINE_PCB_H_ +#ifndef _MACHINE_REGSET_H_ #include +#endif /* * PCB: process control block diff --git a/sys/ia64/include/pci_cfgreg.h b/sys/ia64/include/pci_cfgreg.h index b4d2702b54e..a0bc6e1f9b5 100644 --- a/sys/ia64/include/pci_cfgreg.h +++ b/sys/ia64/include/pci_cfgreg.h @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2010 Marcel Moolenaar * Copyright (c) 1997, Stefan Esser * All rights reserved. * @@ -24,9 +25,14 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ - * */ -extern int pci_cfgregopen(void); -extern u_int32_t pci_cfgregread(int bus, int slot, int func, int reg, int bytes); -extern void pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes); +#ifndef _MACHINE_PCI_CFGREG_H_ +#define _MACHINE_PCI_CFGREG_H_ + +int pci_cfgregopen(void); +uint32_t pci_cfgregread(int bus, int slot, int func, int reg, int len); +void pci_cfgregwrite(int bus, int slot, int func, int reg, uint32_t data, + int bytes); + +#endif /* _MACHINE_PCI_CFGREG_H_ */ diff --git a/sys/ia64/include/pcpu.h b/sys/ia64/include/pcpu.h index bc9fe0813d7..3c6e6a762af 100644 --- a/sys/ia64/include/pcpu.h +++ b/sys/ia64/include/pcpu.h @@ -70,6 +70,16 @@ struct pcpu; register struct pcpu *pcpup __asm__("r13"); +static __inline struct thread * +__curthread(void) +{ + struct thread *td; + + __asm __volatile("ld8.acq %0=[r13]" : "=r"(td)); + return (td); +} +#define curthread (__curthread()) + #define PCPU_GET(member) (pcpup->pc_ ## member) /* @@ -81,8 +91,6 @@ register struct pcpu *pcpup __asm__("r13"); #define PCPU_PTR(member) (&pcpup->pc_ ## member) #define PCPU_SET(member,value) (pcpup->pc_ ## member = (value)) -void pcpu_initclock(void); - #endif /* _KERNEL */ #endif /* !_MACHINE_PCPU_H_ */ diff --git a/sys/ia64/include/sapicreg.h b/sys/ia64/include/sapicreg.h deleted file mode 100644 index 8f7dfbd34a2..00000000000 --- a/sys/ia64/include/sapicreg.h +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2001 Doug Rabson - * 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 _MACHINE_SAPICREG_H_ -#define _MACHINE_SAPICREG_H_ - -/* - * Offsets from the SAPIC base in memory. Most registers are accessed - * by indexing using the SAPIC_IO_SELECT register. - */ -#define SAPIC_IO_SELECT 0x00 -#define SAPIC_IO_WINDOW 0x10 -#define SAPIC_APIC_EOI 0x40 - -/* - * Indexed registers. - */ -#define SAPIC_ID 0x00 -#define SAPIC_VERSION 0x01 -#define SAPIC_ARBITRATION_ID 0x02 -#define SAPIC_RTE_BASE 0x10 - -#endif /* ! _MACHINE_SAPICREG_H_ */ diff --git a/sys/ia64/include/sapicvar.h b/sys/ia64/include/sapicvar.h deleted file mode 100644 index 30a353cb6dd..00000000000 --- a/sys/ia64/include/sapicvar.h +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 2001 Doug Rabson - * 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 _MACHINE_SAPICVAR_H_ -#define _MACHINE_SAPICVAR_H_ - -struct sapic { - struct mtx sa_mtx; - vm_offset_t sa_registers; /* virtual address of sapic */ - u_int sa_id; /* I/O SAPIC Id */ - u_int sa_base; /* ACPI vector base */ - u_int sa_limit; /* last ACPI vector handled here */ -}; - -#define SAPIC_TRIGGER_EDGE 0 -#define SAPIC_TRIGGER_LEVEL 1 - -#define SAPIC_POLARITY_HIGH 0 -#define SAPIC_POLARITY_LOW 1 - -#define SAPIC_DELMODE_FIXED 0 -#define SAPIC_DELMODE_LOWPRI 1 -#define SAPIC_DELMODE_PMI 2 -#define SAPIC_DELMODE_NMI 4 -#define SAPIC_DELMODE_INIT 5 -#define SAPIC_DELMODE_EXTINT 7 - -int sapic_config_intr(u_int irq, enum intr_trigger, enum intr_polarity); -struct sapic *sapic_create(u_int id, u_int base, uint64_t address); -int sapic_enable(struct sapic *sa, u_int irq, u_int vector); -void sapic_eoi(struct sapic *sa, u_int vector); -struct sapic *sapic_lookup(u_int irq); -void sapic_mask(struct sapic *sa, u_int irq); -void sapic_unmask(struct sapic *sa, u_int irq); - -#ifdef DDB -void sapic_print(struct sapic *sa, u_int irq); -#endif - -#endif /* ! _MACHINE_SAPICVAR_H_ */ diff --git a/sys/ia64/include/smp.h b/sys/ia64/include/smp.h index 4eddf7434fe..9f976dec597 100644 --- a/sys/ia64/include/smp.h +++ b/sys/ia64/include/smp.h @@ -6,31 +6,23 @@ #ifdef _KERNEL -/* - * Interprocessor interrupts for SMP. The following values are indices - * into the IPI vector table. The SAL gives us the vector used for AP - * wake-up. We base the other vectors on that. Keep IPI_AP_WAKEUP at - * index 0. See sal.c for details. - */ -/* Architecture specific IPIs. */ -#define IPI_AP_WAKEUP 0 -#define IPI_HIGH_FP 1 -#define IPI_MCA_CMCV 2 -#define IPI_MCA_RENDEZ 3 -/* Machine independent IPIs. */ -#define IPI_AST 4 -#define IPI_RENDEZVOUS 5 -#define IPI_STOP 6 -#define IPI_STOP_HARD 6 -#define IPI_PREEMPT 7 - -#define IPI_COUNT 8 +#define IPI_AST ia64_ipi_ast +#define IPI_PREEMPT ia64_ipi_preempt +#define IPI_RENDEZVOUS ia64_ipi_rndzvs +#define IPI_STOP ia64_ipi_stop +#define IPI_STOP_HARD ia64_ipi_nmi #ifndef LOCORE struct pcpu; -extern int ipi_vector[]; +extern int ia64_ipi_ast; +extern int ia64_ipi_highfp; +extern int ia64_ipi_nmi; +extern int ia64_ipi_preempt; +extern int ia64_ipi_rndzvs; +extern int ia64_ipi_stop; +extern int ia64_ipi_wakeup; void ipi_all_but_self(int ipi); void ipi_selected(cpumask_t cpus, int ipi); diff --git a/sys/ia64/pci/pci_cfgreg.c b/sys/ia64/pci/pci_cfgreg.c index cef743b89f7..00d8397a18e 100644 --- a/sys/ia64/pci/pci_cfgreg.c +++ b/sys/ia64/pci/pci_cfgreg.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2010 Marcel Moolenaar * Copyright (c) 2001 Doug Rabson * All rights reserved. * @@ -27,38 +28,77 @@ */ #include +#include #include #include -#define SAL_PCI_ADDRESS(bus, slot, func, reg) \ - (((bus) << 16) | ((slot) << 11) | ((func) << 8) | (reg)) +static u_long +pci_sal_address(int dom, int bus, int slot, int func, int reg) +{ + u_long addr; + + addr = ~0ul; + if (dom >= 0 && dom <= 255 && bus >= 0 && bus <= 255 && + slot >= 0 && slot <= 31 && func >= 0 && func <= 7 && + reg >= 0 && reg <= 255) { + addr = ((u_long)dom << 24) | ((u_long)bus << 16) | + ((u_long)slot << 11) | ((u_long)func << 8) | (u_long)reg; + } + return (addr); +} + +static int +pci_valid_access(int reg, int len) +{ + int ok; + + ok = ((len == 1 || len == 2 || len == 4) && (reg & (len - 1)) == 0) + ? 1 : 0; + return (ok); +} int pci_cfgregopen(void) { - return 1; + return (1); } -u_int32_t -pci_cfgregread(int bus, int slot, int func, int reg, int bytes) +uint32_t +pci_cfgregread(int bus, int slot, int func, int reg, int len) { struct ia64_sal_result res; + register_t is; + u_long addr; - res = ia64_sal_entry(SAL_PCI_CONFIG_READ, - SAL_PCI_ADDRESS(bus, slot, func, reg), - bytes, 0, 0, 0, 0, 0); - if (res.sal_status < 0) + addr = pci_sal_address(0, bus, slot, func, reg); + if (addr == ~0ul) return (~0); - else - return (res.sal_result[0]); + + if (!pci_valid_access(reg, len)) + return (~0); + + is = intr_disable(); + res = ia64_sal_entry(SAL_PCI_CONFIG_READ, addr, len, 0, 0, 0, 0, 0); + intr_restore(is); + + return ((res.sal_status < 0) ? ~0 : res.sal_result[0]); } void -pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes) +pci_cfgregwrite(int bus, int slot, int func, int reg, uint32_t data, int len) { struct ia64_sal_result res; + register_t is; + u_long addr; - res = ia64_sal_entry(SAL_PCI_CONFIG_WRITE, - SAL_PCI_ADDRESS(bus, slot, func, reg), - bytes, data, 0, 0, 0, 0); + addr = pci_sal_address(0, bus, slot, func, reg); + if (addr == ~0ul) + return; + + if (!pci_valid_access(reg, len)) + return; + + is = intr_disable(); + res = ia64_sal_entry(SAL_PCI_CONFIG_WRITE, addr, len, data, 0, 0, 0, 0); + intr_restore(is); } diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 9b7d5504c8b..cad745dcc59 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -562,10 +562,7 @@ _zfs= zfs .endif .if ${MACHINE_ARCH} == "ia64" -# Modules not enabled on ia64 (as compared to i386) include: -# aac acpi aout apm atspeaker drm ibcs2 linprocfs linux ncv -# nsp s3 sbni stg vesa -# acpi is not enabled because it is broken as a module on ia64 +_aac= aac _aic= aic _an= an _arcnet= arcnet @@ -578,12 +575,17 @@ _cm= cm _cmx= cmx _coff= coff _cpufreq= cpufreq +_dpt= dpt _em= em _ep= ep +_et= et _exca= exca _fe= fe +_hptiop= hptiop +_ida= ida _igb= igb _iir= iir +_ips= ips _mly= mly _pccard= pccard _scsi_low= scsi_low @@ -592,6 +594,7 @@ _sound= sound _splash= splash _sppp= sppp _streams= streams +_twa= twa _wi= wi _xe= xe .endif From 1462deea8bcecaa8429d93c68a663c02edaa4cbb Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 31 Mar 2010 05:23:35 +0000 Subject: [PATCH 1777/2592] , and removed on ia64. --- ObsoleteFiles.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 0b29f98634e..faeee6bcc10 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -14,6 +14,12 @@ # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last. # +# 20100330: [ia64] Sync with 9-current +.if ${TARGET_ARCH} == "ia64" +OLD_FILES+=usr/include/machine/nexusvar.h +OLD_FILES+=usr/include/machine/sapicreg.h +OLD_FILES+=usr/include/machine/sapicvar.h +.endif # 20100329: gcpio removal OLD_FILES+=usr/bin/gcpio OLD_FILES+=usr/share/info/cpio.info.gz From 59c32a3bfe109e7a190428fd1a55aa651ee1a4b6 Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Wed, 31 Mar 2010 07:10:40 +0000 Subject: [PATCH 1778/2592] MFC r205809: Wait for pmc name in the log before displaying data. This will solve an abort in case of low throughput PMCs. --- usr.sbin/pmcstat/pmcstat_log.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c index fc26001a592..9b524ff7275 100644 --- a/usr.sbin/pmcstat/pmcstat_log.c +++ b/usr.sbin/pmcstat/pmcstat_log.c @@ -1049,7 +1049,6 @@ pmcstat_pmcindex_to_name(int pmcin) if (pr->pr_pmcin == pmcin) return pmcstat_string_unintern(pr->pr_pmcname); - err(EX_SOFTWARE, "ERROR: cannot find pmcid name"); return NULL; } @@ -1789,19 +1788,23 @@ static void pmcstat_refresh_top(void) { char pmcname[40]; + const char *s; /* If in pause mode do not refresh display. */ if (pmcstat_pause) return; + /* Wait until PMC pop in the log. */ + s = pmcstat_pmcindex_to_name(pmcstat_pmcinfilter); + if (s == NULL) + return; + /* Format PMC name. */ if (pmcstat_mergepmc) - snprintf(pmcname, sizeof(pmcname), "[%s]", - pmcstat_pmcindex_to_name(pmcstat_pmcinfilter)); + snprintf(pmcname, sizeof(pmcname), "[%s]", s); else snprintf(pmcname, sizeof(pmcname), "%s.%d", - pmcstat_pmcindex_to_name(pmcstat_pmcinfilter), - pmcstat_pmcinfilter); + s, pmcstat_pmcinfilter); PMCSTAT_PRINTBEGIN(); PMCSTAT_PRINTW("PMC: %s Samples: %u processed, %u invalid\n\n", From 3015ec2db6f4a46dff592ca7ed97ac2f8be8d007 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 31 Mar 2010 07:49:59 +0000 Subject: [PATCH 1779/2592] MFC r205074: Mask disk_idx to avoid panic because of extra bits set. PR: kern/102211 Submitted by: yoichi --- sys/dev/ata/ata-raid.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index 1e976078f61..a3b1e78a78b 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -2544,22 +2544,24 @@ ata_raid_intel_read_meta(device_t dev, struct ar_softc **raidp) /* clear out any old info */ for (disk = 0; disk < raid->total_disks; disk++) { + u_int disk_idx = map->disk_idx[disk] & 0xffff; + raid->disks[disk].dev = NULL; - bcopy(meta->disk[map->disk_idx[disk]].serial, + bcopy(meta->disk[disk_idx].serial, raid->disks[disk].serial, sizeof(raid->disks[disk].serial)); raid->disks[disk].sectors = - meta->disk[map->disk_idx[disk]].sectors; + meta->disk[disk_idx].sectors; raid->disks[disk].flags = 0; - if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_ONLINE) + if (meta->disk[disk_idx].flags & INTEL_F_ONLINE) raid->disks[disk].flags |= AR_DF_ONLINE; - if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_ASSIGNED) + if (meta->disk[disk_idx].flags & INTEL_F_ASSIGNED) raid->disks[disk].flags |= AR_DF_ASSIGNED; - if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_SPARE) { + if (meta->disk[disk_idx].flags & INTEL_F_SPARE) { raid->disks[disk].flags &= ~(AR_DF_ONLINE | AR_DF_ASSIGNED); raid->disks[disk].flags |= AR_DF_SPARE; } - if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_DOWN) + if (meta->disk[disk_idx].flags & INTEL_F_DOWN) raid->disks[disk].flags &= ~AR_DF_ONLINE; } } From 80ebd5b05987e33a9218dcf3ccc9847f9faadb82 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 31 Mar 2010 07:56:32 +0000 Subject: [PATCH 1780/2592] MFC r205422: - Spec tells that CCC interrupt is edge triggered. Acknowledge it as such. - Do not try to enable CCC if it is not supported. --- sys/dev/ahci/ahci.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 4e1797edf77..14c72db0c77 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -66,6 +66,7 @@ static void ahci_ch_pm(void *arg); static void ahci_ch_intr_locked(void *data); static void ahci_ch_intr(void *data); static int ahci_ctlr_reset(device_t dev); +static int ahci_ctlr_setup(device_t dev); static void ahci_begin_transaction(device_t dev, union ccb *ccb); static void ahci_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error); static void ahci_execute_transaction(struct ahci_slot *slot); @@ -372,6 +373,9 @@ ahci_attach(device_t dev) ctlr->caps &= ~AHCI_CAP_SPM; if (ctlr->quirks & AHCI_Q_NONCQ) ctlr->caps &= ~AHCI_CAP_SNCQ; + if ((ctlr->caps & AHCI_CAP_CCCS) == 0) + ctlr->ccc = 0; + ahci_ctlr_setup(dev); /* Setup interrupts. */ if (ahci_setup_interrupt(dev)) { bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); @@ -501,6 +505,13 @@ ahci_ctlr_reset(device_t dev) } /* Reenable AHCI mode */ ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE); + return (0); +} + +static int +ahci_ctlr_setup(device_t dev) +{ + struct ahci_controller *ctlr = device_get_softc(dev); /* Clear interrupts */ ATA_OUTL(ctlr->r_mem, AHCI_IS, ATA_INL(ctlr->r_mem, AHCI_IS)); /* Configure CCC */ @@ -543,6 +554,7 @@ ahci_resume(device_t dev) if ((res = ahci_ctlr_reset(dev)) != 0) return (res); + ahci_ctlr_setup(dev); return (bus_generic_resume(dev)); } @@ -609,7 +621,7 @@ ahci_intr(void *data) { struct ahci_controller_irq *irq = data; struct ahci_controller *ctlr = irq->ctlr; - u_int32_t is; + u_int32_t is, ise = 0; void *arg; int unit; @@ -623,9 +635,14 @@ ahci_intr(void *data) unit = irq->r_irq_rid - 1; is = ATA_INL(ctlr->r_mem, AHCI_IS); } + /* CCC interrupt is edge triggered. */ + if (ctlr->ccc) + ise = 1 << ctlr->cccv; /* Some controllers have edge triggered IS. */ if (ctlr->quirks & AHCI_Q_EDGEIS) - ATA_OUTL(ctlr->r_mem, AHCI_IS, is); + ise |= is; + if (ise != 0) + ATA_OUTL(ctlr->r_mem, AHCI_IS, ise); for (; unit < ctlr->channels; unit++) { if ((is & (1 << unit)) != 0 && (arg = ctlr->interrupt[unit].argument)) { From e30013ae5c39217e01e8f1b1ff97c1632cf815bc Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 31 Mar 2010 08:02:16 +0000 Subject: [PATCH 1781/2592] MFC r205413: Add some more codec IDs. --- sys/dev/sound/pci/hda/hdac.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 06815686660..7717ff4800a 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -619,10 +619,14 @@ static const struct { #define HDA_CODEC_ALC267 HDA_CODEC_CONSTRUCT(REALTEK, 0x0267) #define HDA_CODEC_ALC268 HDA_CODEC_CONSTRUCT(REALTEK, 0x0268) #define HDA_CODEC_ALC269 HDA_CODEC_CONSTRUCT(REALTEK, 0x0269) +#define HDA_CODEC_ALC270 HDA_CODEC_CONSTRUCT(REALTEK, 0x0270) #define HDA_CODEC_ALC272 HDA_CODEC_CONSTRUCT(REALTEK, 0x0272) +#define HDA_CODEC_ALC273 HDA_CODEC_CONSTRUCT(REALTEK, 0x0273) +#define HDA_CODEC_ALC275 HDA_CODEC_CONSTRUCT(REALTEK, 0x0275) #define HDA_CODEC_ALC660 HDA_CODEC_CONSTRUCT(REALTEK, 0x0660) #define HDA_CODEC_ALC662 HDA_CODEC_CONSTRUCT(REALTEK, 0x0662) #define HDA_CODEC_ALC663 HDA_CODEC_CONSTRUCT(REALTEK, 0x0663) +#define HDA_CODEC_ALC665 HDA_CODEC_CONSTRUCT(REALTEK, 0x0665) #define HDA_CODEC_ALC861 HDA_CODEC_CONSTRUCT(REALTEK, 0x0861) #define HDA_CODEC_ALC861VD HDA_CODEC_CONSTRUCT(REALTEK, 0x0862) #define HDA_CODEC_ALC880 HDA_CODEC_CONSTRUCT(REALTEK, 0x0880) @@ -632,6 +636,7 @@ static const struct { #define HDA_CODEC_ALC887 HDA_CODEC_CONSTRUCT(REALTEK, 0x0887) #define HDA_CODEC_ALC888 HDA_CODEC_CONSTRUCT(REALTEK, 0x0888) #define HDA_CODEC_ALC889 HDA_CODEC_CONSTRUCT(REALTEK, 0x0889) +#define HDA_CODEC_ALC892 HDA_CODEC_CONSTRUCT(REALTEK, 0x0892) #define HDA_CODEC_ALCXXXX HDA_CODEC_CONSTRUCT(REALTEK, 0xffff) /* Analog Devices */ @@ -735,6 +740,7 @@ static const struct { #define HDA_CODEC_CX20551 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5047) #define HDA_CODEC_CX20561 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5051) #define HDA_CODEC_CX20582 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5066) +#define HDA_CODEC_CX20583 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5067) #define HDA_CODEC_CXXXXX HDA_CODEC_CONSTRUCT(CONEXANT, 0xffff) /* VIA */ @@ -805,7 +811,8 @@ static const struct { #define HDA_CODEC_INTELG45_1 HDA_CODEC_CONSTRUCT(INTEL, 0x2801) #define HDA_CODEC_INTELG45_2 HDA_CODEC_CONSTRUCT(INTEL, 0x2802) #define HDA_CODEC_INTELG45_3 HDA_CODEC_CONSTRUCT(INTEL, 0x2803) -#define HDA_CODEC_INTELG45_4 HDA_CODEC_CONSTRUCT(INTEL, 0x29fb) +#define HDA_CODEC_INTELG45_4 HDA_CODEC_CONSTRUCT(INTEL, 0x2804) +#define HDA_CODEC_INTELG45_5 HDA_CODEC_CONSTRUCT(INTEL, 0x29fb) #define HDA_CODEC_INTELQ57 HDA_CODEC_CONSTRUCT(INTEL, 0x0054) #define HDA_CODEC_INTELXXXX HDA_CODEC_CONSTRUCT(INTEL, 0xffff) @@ -821,10 +828,14 @@ static const struct { { HDA_CODEC_ALC267, "Realtek ALC267" }, { HDA_CODEC_ALC268, "Realtek ALC268" }, { HDA_CODEC_ALC269, "Realtek ALC269" }, + { HDA_CODEC_ALC270, "Realtek ALC270" }, { HDA_CODEC_ALC272, "Realtek ALC272" }, + { HDA_CODEC_ALC273, "Realtek ALC273" }, + { HDA_CODEC_ALC275, "Realtek ALC275" }, { HDA_CODEC_ALC660, "Realtek ALC660" }, { HDA_CODEC_ALC662, "Realtek ALC662" }, { HDA_CODEC_ALC663, "Realtek ALC663" }, + { HDA_CODEC_ALC665, "Realtek ALC665" }, { HDA_CODEC_ALC861, "Realtek ALC861" }, { HDA_CODEC_ALC861VD, "Realtek ALC861-VD" }, { HDA_CODEC_ALC880, "Realtek ALC880" }, @@ -834,6 +845,7 @@ static const struct { { HDA_CODEC_ALC887, "Realtek ALC887" }, { HDA_CODEC_ALC888, "Realtek ALC888" }, { HDA_CODEC_ALC889, "Realtek ALC889" }, + { HDA_CODEC_ALC892, "Realtek ALC892" }, { HDA_CODEC_AD1882, "Analog Devices AD1882" }, { HDA_CODEC_AD1882A, "Analog Devices AD1882A" }, { HDA_CODEC_AD1883, "Analog Devices AD1883" }, @@ -907,6 +919,7 @@ static const struct { { HDA_CODEC_CX20551, "Conexant CX20551 (Waikiki)" }, { HDA_CODEC_CX20561, "Conexant CX20561 (Hermosa)" }, { HDA_CODEC_CX20582, "Conexant CX20582 (Pebble)" }, + { HDA_CODEC_CX20583, "Conexant CX20583 (Pebble HSF)" }, { HDA_CODEC_VT1708_8, "VIA VT1708_8" }, { HDA_CODEC_VT1708_9, "VIA VT1708_9" }, { HDA_CODEC_VT1708_A, "VIA VT1708_A" }, @@ -966,6 +979,7 @@ static const struct { { HDA_CODEC_INTELG45_2, "Intel G45 HDMI" }, { HDA_CODEC_INTELG45_3, "Intel G45 HDMI" }, { HDA_CODEC_INTELG45_4, "Intel G45 HDMI" }, + { HDA_CODEC_INTELG45_5, "Intel G45 HDMI" }, { HDA_CODEC_INTELQ57, "Intel Q57 HDMI" }, { HDA_CODEC_SII1390, "Silicon Image SiI1390 HDMI" }, { HDA_CODEC_SII1392, "Silicon Image SiI1392 HDMI" }, From 72208ab4baa0934bc9b2fdc637e0d016f7631b5a Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 31 Mar 2010 08:03:49 +0000 Subject: [PATCH 1782/2592] MFC r205734: Fix lock leakage. PR: kern/145081 --- sys/dev/sound/pcm/dsp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 54c165fa67a..b3d21cf609a 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -1071,6 +1071,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, if (IOCGROUP(cmd) == 'M') { if (cmd == OSS_GETVERSION) { *arg_i = SOUND_VERSION; + PCM_GIANT_EXIT(d); return (0); } ret = dsp_ioctl_channel(i_dev, PCM_VOLCH(i_dev), cmd, arg); From f13f3ec7551f7ac14bdbd568e25fbb61c8910f62 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 31 Mar 2010 08:12:22 +0000 Subject: [PATCH 1783/2592] MFC r204655: Add some more supported controllers. Crosslink with CAM ATA man pages. --- share/man/man4/ata.4 | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/share/man/man4/ata.4 b/share/man/man4/ata.4 index 303e63291bb..3e5c5c1b47b 100644 --- a/share/man/man4/ata.4 +++ b/share/man/man4/ata.4 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 23, 2009 +.Dd March 3, 2010 .Dt ATA 4 .Os .Sh NAME @@ -81,6 +81,13 @@ To support ATAPI floppy drives: To support ATAPI tape drives: .Cd device atapist .Pp +To turn +.Xr ata 4 +subsystem controller drivers into cam(4) interface modules (disables all native +.Xr ata 4 +APIs and periperal drivers): +.Cd options ATA_CAM +.Pp The following tunables are settable from the loader: .Bl -ohang .It Va hw.ata.ata_dma @@ -125,7 +132,7 @@ The currently supported ATA/SATA controller chips are: .It Acard: ATP850P, ATP860A, ATP860R, ATP865A, ATP865R. .It ALI: -M5229, M5281, M5287, M5288, M5289. +M5228, M5229, M5281, M5283, M5287, M5288, M5289. .It AMD: AMD756, AMD766, AMD768, AMD8111, CS5536. .It ATI: @@ -139,7 +146,8 @@ Cyrix 5530. .It HighPoint: HPT302, HPT366, HPT368, HPT370, HPT371, HPT372, HPT372N, HPT374. .It Intel: -6300ESB, 31244, PIIX, PIIX3, PIIX4, ESB2, ICH, ICH0, ICH2, ICH3, ICH4, ICH5, ICH6, ICH7, ICH8, ICH9, ICH10. +6300ESB, 31244, PIIX, PIIX3, PIIX4, ESB2, ICH, ICH0, ICH2, ICH3, ICH4, ICH5, +ICH6, ICH7, ICH8, ICH9, ICH10, SCH, PCH. .It ITE: IT8211F, IT8212F, IT8213F. .It JMicron: @@ -163,7 +171,9 @@ SiI0680, SiI3112, SiI3114, SiI3124, SiI3132, SiI3512. .It SiS: SIS180, SIS181, SIS182, SIS5513, SIS530, SIS540, SIS550, SIS620, SIS630, SIS630S, SIS633, SIS635, SIS730, SIS733, SIS735, SIS745, SIS961, SIS962, SIS963, SIS964, SIS965. .It VIA: -VT6410, VT6420, VT6421, VT82C586, VT82C586B, VT82C596, VT82C596B, VT82C686, VT82C686A, VT82C686B, VT8231, VT8233, VT8233A, VT8233C, VT8235, VT8237, VT8237A, VT8237S, VT8251. +VT6410, VT6420, VT6421, VT82C586, VT82C586B, VT82C596, VT82C596B, VT82C686, +VT82C686A, VT82C686B, VT8231, VT8233, VT8233A, VT8233C, VT8235, VT8237, +VT8237A, VT8237S, VT8251, CX700, VX800, VX855. .El .Pp Unknown ATA chipsets are supported in PIO modes, and if the standard @@ -246,9 +256,12 @@ and not depend on attach order. .Pp Native Command Queuing (NCQ) on SATA drives is not yet supported. .Sh SEE ALSO +.Xr ahci 4 , +.Xr cam 4 , .Xr ataraid 4 , .Xr atacontrol 8 , -.Xr burncd 8 +.Xr burncd 8 , +.Xr siis 4 .Sh HISTORY The .Nm From 22c395522661e45cf7e28349ae1c5e3a22209382 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 31 Mar 2010 08:14:07 +0000 Subject: [PATCH 1784/2592] MFC r204704: Reflect added CAM ATA support. --- share/man/man4/scsi.4 | 79 ++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/share/man/man4/scsi.4 b/share/man/man4/scsi.4 index fccb9358f75..ad52663c070 100644 --- a/share/man/man4/scsi.4 +++ b/share/man/man4/scsi.4 @@ -24,15 +24,15 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd October 15, 1998 -.Dt SCSI 4 +.Dd March 4, 2010 +.Dt CAM 4 .Os .Sh NAME -.Nm SCSI , .Nm CAM -.Nd CAM SCSI subsystem +.Nd Common Access Method SCSI/ATA subsystem .Sh SYNOPSIS .Cd "device scbus" +.Cd "device ada" .Cd "device cd" .Cd "device ch" .Cd "device da" @@ -49,31 +49,32 @@ .Cd "options SCSI_NO_OP_STRINGS" .Cd "options SCSI_DELAY=8000" .Sh DESCRIPTION -The CAM -.Tn SCSI +The +.Nm subsystem provides a uniform and modular system for the implementation of drivers to control various .Tn SCSI +and +.Tn ATA devices, and to utilize different .Tn SCSI +and +.Tn ATA host adapters through host adapter drivers. -When the system probes the -.Tn SCSI -busses, it attaches any devices it finds to the appropriate -drivers. +When the system probes busses, it attaches any devices it finds to the +appropriate drivers. The .Xr pass 4 -driver, if it is configured in the kernel, will attach to all -.Tn SCSI -devices. +driver, if it is configured in the kernel, will attach to all devices. .Sh KERNEL CONFIGURATION There are a number of generic kernel configuration options for the -CAM -.Tn SCSI +.Nm subsystem: .Bl -tag -width SCSI_NO_SENSE_STRINGS .It Dv CAMDEBUG -This option enables the CAM debugging printf code. +This option enables the +.Nm +debugging printf code. This will not actually cause any debugging information to be printed out when included by itself. Enabling printouts requires additional configuration. @@ -82,12 +83,11 @@ See below for details. This sets the maximum allowable number of concurrent "high power" commands. A "high power" command is a command that takes more electrical power than most to complete. -An example of this (and the only command currently -tagged as "high power") is the +An example of this is the .Tn SCSI START UNIT command. -Starting a SCSI disk often takes significantly more -electrical power than normal operation of the disk. +Starting a disk often takes significantly more electrical power than normal +operation. This option allows the user to specify how many concurrent high power commands may be outstanding without overloading the power supply on his computer. @@ -120,7 +120,9 @@ problems. This is the .Tn SCSI "bus settle delay." -In CAM, it is specified in +In +.Nm , +it is specified in .Em milliseconds , not seconds like the old .Tn SCSI @@ -148,7 +150,7 @@ In that case, the will be reset to 100ms. .El .Pp -All devices and the SCSI busses support boot time allocation so that +All devices and busses support dynamic allocation so that an upper number of devices and controllers does not need to be configured; .Cd "device da" will suffice for any number of disk drivers. @@ -204,7 +206,9 @@ hint.da.0.unit="0" This assigns .Em da0 to target 0, unit (lun) 0 of scbus 0. -Omitting the target or unit hints will instruct CAM to treat them as wildcards +Omitting the target or unit hints will instruct +.Nm +to treat them as wildcards and use the first respective counted instances. These examples can be combined together to allow a peripheral device to be wired to any particular controller, bus, target, and/or unit instance. @@ -221,7 +225,9 @@ The system allows common device drivers to work through many different types of adapters. The adapters take requests from the upper layers and do all IO between the -.Em SCSI +.Tn SCSI +or +.Tn ATA bus and the system. The maximum size of a transfer is governed by the adapter. @@ -233,7 +239,8 @@ Some adapters support in which the system is capable of operating as a device, responding to operations initiated by another system. Target mode is supported for -some adapters, but is not yet complete for this version of the CAM +some adapters, but is not yet complete for this version of the +.Nm .Tn SCSI subsystem. .Sh FILES @@ -278,7 +285,9 @@ Users can enable debugging from their kernel config file, by using the following kernel config options: .Bl -tag -width CAM_DEBUG_TARGET .It Dv CAMDEBUG -This enables CAM debugging. +This enables +.Nm +debugging. Without this option, users will not even be able to turn on debugging from userland via .Xr camcontrol 8 . @@ -313,9 +322,12 @@ See .Xr camcontrol 8 for details. .Sh SEE ALSO +.Xr ada 4 , .Xr aha 4 , .Xr ahb 4 , .Xr ahc 4 , +.Xr ahci 4 , +.Xr ata 4 , .Xr bt 4 , .Xr cd 4 , .Xr ch 4 , @@ -326,15 +338,26 @@ for details. .Xr xpt 4 , .Xr camcontrol 8 .Sh HISTORY -The CAM +The +.Nm .Tn SCSI subsystem first appeared in .Fx 3.0 . +The +.Nm +ATA support was added in +.Fx 8.0 . .Sh AUTHORS .An -nosplit -The CAM +The +.Nm .Tn SCSI subsystem was written by .An Justin Gibbs and .An Kenneth Merry . +The +.Nm +.Tn ATA +support was added by +.An Alexander Motin Aq mav@FreeBSD.org . From 307ec4826c2606bc323f0d47f21dd0ab8823dbed Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 31 Mar 2010 08:15:32 +0000 Subject: [PATCH 1785/2592] MFC r204565: Some style and language improvements. Submitted by: ru --- share/man/man4/ahci.4 | 28 ++++++++++++++++------------ share/man/man4/siis.4 | 28 ++++++++++++++++------------ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/share/man/man4/ahci.4 b/share/man/man4/ahci.4 index b3d2e23bdaa..675bab65bf6 100644 --- a/share/man/man4/ahci.4 +++ b/share/man/man4/ahci.4 @@ -48,9 +48,10 @@ module at boot time, place the following line in ahci_load="YES" .Ed .Pp -The following tunables are settable from the loader: +The following tunables are settable from the +.Xr loader 8 : .Bl -ohang -.It Va hint.ahci.X.msi +.It Va hint.ahci. Ns Ar X Ns Va .msi controls Message Signaled Interrupts (MSI) usage by the specified controller .Bl -tag -compact .It 0 @@ -60,15 +61,15 @@ single MSI vector used, if supported (default); .It 2 multiple MSI vectors used, if supported; .El -.It Va hint.ahci.X.ccc +.It Va hint.ahci. Ns Ar X Ns Va .ccc controls Command Completion Coalescing (CCC) usage by the specified controller. Non-zero value enables CCC and defines maximum time (in ms), request can wait for interrupt, if there are some more requests present on controller queue. CCC reduces number of context switches on systems with many parallel requests, but it can decrease disk performance on some workloads due to additional command latency. -.It Va hint.ahcich.X.pm_level -controls SATA interface Power Management for specified channel, +.It Va hint.ahcich. Ns Ar X Ns Va .pm_level +controls SATA interface Power Management for the specified channel, allowing some power to be saved at the cost of additional command latency. Possible values: @@ -92,18 +93,20 @@ Because of artificial entering latency, performance degradation in modes .Pp Note that interface Power Management is not compatible with device presence detection. -You will have to reset bus manually on device hot-plug. -.It Va hint.ahcich.X.sata_rev +A manual bus reset is needed on device hot-plug. +.It Va hint.ahcich. Ns Ar X Ns Va .sata_rev setting to nonzero value limits maximum SATA revision (speed). Values 1, 2 and 3 are respectively 1.5, 3 and 6Gbps. .El .Sh DESCRIPTION -This driver provides the CAM subsystem with native access to the +This driver provides the +.Xr CAM 4 +subsystem with native access to the .Tn SATA ports of AHCI-compatible controllers. Each SATA port found is represented to CAM as a separate bus with one target, or, if HBA supports Port Multipliers, 16 targets. -Most of the bus-management details are handled by the SATA-specific +Most of the bus-management details are handled by the SATA-specific transport of CAM. Connected ATA disks are handled by the ATA protocol disk peripheral driver .Xr ada 4 . @@ -121,7 +124,8 @@ and Message Signaled Interrupts. .Pp AHCI hardware is also supported by ataahci driver from .Xr ata 4 -subsystem. If both drivers are loaded at the same time, this one will be +subsystem. +If both drivers are loaded at the same time, this one will be given precedence as the more functional of the two. .Sh HARDWARE The @@ -134,11 +138,11 @@ it supports AHCI part of legacy-PATA + AHCI-SATA combined controllers, such as JMicron JMB36x and Marvell 88SX61xx. .Sh SEE ALSO .Xr ada 4 , +.Xr ata 4 , .Xr cd 4 , .Xr da 4 , .Xr sa 4 , -.Xr scsi 4 , -.Xr ata 4 +.Xr scsi 4 .Sh HISTORY The .Nm diff --git a/share/man/man4/siis.4 b/share/man/man4/siis.4 index ab67cbca4c6..8f70839492f 100644 --- a/share/man/man4/siis.4 +++ b/share/man/man4/siis.4 @@ -48,12 +48,13 @@ module at boot time, place the following line in siis_load="YES" .Ed .Pp -The following tunables are settable from the loader: +The following tunables are settable from the +.Xr loader 8 : .Bl -ohang -.It Va hint.siis.X.msi +.It Va hint.siis. Ns Ar X Ns Va .msi controls Message Signaled Interrupts (MSI) usage by the specified controller. -.It Va hint.siisch.X.pm_level -controls SATA interface Power Management for specified channel, +.It Va hint.siisch. Ns Ar X Ns Va .pm_level +controls SATA interface Power Management for the specified channel, allowing some power to be saved at the cost of additional command latency. Possible values: @@ -65,13 +66,15 @@ device is allowed to initiate PM state change, host is passive. .El Note that interface Power Management is not compatible with device presence detection. -You will have to reset bus manually on device hot-plug. -.It Va hint.siisch.X.sata_rev +A manual bus reset is needed on device hot-plug. +.It Va hint.siisch. Ns Ar X Ns Va .sata_rev setting to nonzero value limits maximum SATA revision (speed). Values 1, 2 and 3 are respectively 1.5, 3 and 6Gbps. .El .Sh DESCRIPTION -This driver provides the CAM subsystem native access to the +This driver provides the +.Xr CAM 4 +subsystem with native access to the .Tn SATA ports of controller. Each SATA port is represented to CAM as a separate bus with 16 targets. @@ -90,14 +93,15 @@ Port Multipliers (including FIS-based switching), hardware command queues (31 command per port), Native Command Queuing, SATA interface Power Management, device hot-plug and Message Signaled Interrupts. .Pp -Same hardware is also supported by atasiliconimage driver from +Same hardware is also supported by the atasiliconimage driver from .Xr ata 4 -subsystem. If both drivers are loaded at the same time, this one will be +subsystem. +If both drivers are loaded at the same time, this one will be given precedence as the more functional of the two. .Sh HARDWARE The .Nm -driver supports following controllers: +driver supports the following controllers: .Bl -bullet -compact .It SiI3124 @@ -108,11 +112,11 @@ SiI3531 .El .Sh SEE ALSO .Xr ada 4 , +.Xr ata 4 , .Xr cd 4 , .Xr da 4 , .Xr sa 4 , -.Xr scsi 4 , -.Xr ata 4 +.Xr scsi 4 .Sh HISTORY The .Nm From 174479969c7d57df090f959b3b835d99fcc7b65c Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 31 Mar 2010 08:17:32 +0000 Subject: [PATCH 1786/2592] MFC r204705: Add links to cam(4). --- share/man/man4/ada.4 | 1 + share/man/man4/ahci.4 | 4 ++-- share/man/man4/cd.4 | 2 +- share/man/man4/ch.4 | 1 + share/man/man4/da.4 | 1 + share/man/man4/pass.4 | 1 + share/man/man4/pt.4 | 2 +- share/man/man4/sa.4 | 4 ++-- share/man/man4/siis.4 | 4 ++-- 9 files changed, 12 insertions(+), 8 deletions(-) diff --git a/share/man/man4/ada.4 b/share/man/man4/ada.4 index 65cd53fc699..cba892b03c4 100644 --- a/share/man/man4/ada.4 +++ b/share/man/man4/ada.4 @@ -127,6 +127,7 @@ ATA device nodes .Sh SEE ALSO .Xr ad 4 , .Xr ahci 4 , +.Xr cam 4 , .Xr da 4 , .Xr siis 4 .Sh HISTORY diff --git a/share/man/man4/ahci.4 b/share/man/man4/ahci.4 index 675bab65bf6..e2799639d9b 100644 --- a/share/man/man4/ahci.4 +++ b/share/man/man4/ahci.4 @@ -139,10 +139,10 @@ such as JMicron JMB36x and Marvell 88SX61xx. .Sh SEE ALSO .Xr ada 4 , .Xr ata 4 , +.Xr cam 4 , .Xr cd 4 , .Xr da 4 , -.Xr sa 4 , -.Xr scsi 4 +.Xr sa 4 .Sh HISTORY The .Nm diff --git a/share/man/man4/cd.4 b/share/man/man4/cd.4 index ec16751c6f1..ed885353961 100644 --- a/share/man/man4/cd.4 +++ b/share/man/man4/cd.4 @@ -496,8 +496,8 @@ devices .Sh DIAGNOSTICS None. .Sh SEE ALSO +.Xr cam 4 , .Xr da 4 , -.Xr scsi 4 , .Xr disklabel 5 , .Xr disklabel 8 , .Xr cd 9 diff --git a/share/man/man4/ch.4 b/share/man/man4/ch.4 index 03e293a7128..6bd2df40d0a 100644 --- a/share/man/man4/ch.4 +++ b/share/man/man4/ch.4 @@ -325,6 +325,7 @@ If the media changer does not support features requested by the driver, it will produce both console error messages and failure return codes to the ioctls described here. .Sh SEE ALSO +.Xr cam 4 , .Xr chio 1 , .Xr cd 4 , .Xr da 4 , diff --git a/share/man/man4/da.4 b/share/man/man4/da.4 index 2ba80965e97..cf5693484ff 100644 --- a/share/man/man4/da.4 +++ b/share/man/man4/da.4 @@ -196,6 +196,7 @@ SCSI disk device nodes None. .Sh SEE ALSO .Xr ad 4 , +.Xr cam 4 , .Xr geom 4 , .Xr bsdlabel 8 , .Xr fdisk 8 diff --git a/share/man/man4/pass.4 b/share/man/man4/pass.4 index b96d6ba7283..7819ea369b8 100644 --- a/share/man/man4/pass.4 +++ b/share/man/man4/pass.4 @@ -104,6 +104,7 @@ CAM subsystem. None. .Sh SEE ALSO .Xr cam 3 , +.Xr cam 4 , .Xr cam_cdbparse 3 , .Xr xpt 4 , .Xr camcontrol 8 diff --git a/share/man/man4/pt.4 b/share/man/man4/pt.4 index 170956e7ff1..b45ae5ab649 100644 --- a/share/man/man4/pt.4 +++ b/share/man/man4/pt.4 @@ -84,7 +84,7 @@ the .Ar N Ns th processor device. .El .Sh SEE ALSO -.Xr scsi 4 +.Xr cam 4 .Sh HISTORY The .Nm diff --git a/share/man/man4/sa.4 b/share/man/man4/sa.4 index 0a6da7c50dc..eae3bf5b1fd 100644 --- a/share/man/man4/sa.4 +++ b/share/man/man4/sa.4 @@ -200,8 +200,8 @@ accessing the device, e.g.). .Sh DIAGNOSTICS None. .Sh SEE ALSO -.Xr mt 1 , -.Xr scsi 4 +.Xr cam 4 , +.Xr mt 1 .Sh AUTHORS .An -nosplit The diff --git a/share/man/man4/siis.4 b/share/man/man4/siis.4 index 8f70839492f..7480f70bfdd 100644 --- a/share/man/man4/siis.4 +++ b/share/man/man4/siis.4 @@ -113,10 +113,10 @@ SiI3531 .Sh SEE ALSO .Xr ada 4 , .Xr ata 4 , +.Xr cam 4 , .Xr cd 4 , .Xr da 4 , -.Xr sa 4 , -.Xr scsi 4 +.Xr sa 4 .Sh HISTORY The .Nm From 28f9173691cbb583bef70707dff1a027f2eb7afb Mon Sep 17 00:00:00 2001 From: Pietro Cerutti Date: Wed, 31 Mar 2010 13:51:31 +0000 Subject: [PATCH 1787/2592] MFC r205606 Remove const'ness from dlerror(3) prototype, for consistency with POSIX. Approved by: cognet --- include/dlfcn.h | 3 +-- lib/libc/gen/dlfcn.c | 4 ++-- lib/libc/gen/dlopen.3 | 2 +- libexec/rtld-elf/rtld.c | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/dlfcn.h b/include/dlfcn.h index b1a97386747..a019e062284 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -117,8 +117,7 @@ typedef struct dl_serinfo { __BEGIN_DECLS /* XSI functions first. */ int dlclose(void *); -const char * - dlerror(void); +char *dlerror(void); void *dlopen(const char *, int); void *dlsym(void * __restrict, const char * __restrict); diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c index 4be88475a91..a1ca29daceb 100644 --- a/lib/libc/gen/dlfcn.c +++ b/lib/libc/gen/dlfcn.c @@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include -static const char sorry[] = "Service unavailable"; +static char sorry[] = "Service unavailable"; /* * For ELF, the dynamic linker directly resolves references to its @@ -69,7 +69,7 @@ dlclose(void *handle) } #pragma weak dlerror -const char * +char * dlerror(void) { return sorry; diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3 index 6488befeeb5..d4b111a1002 100644 --- a/lib/libc/gen/dlopen.3 +++ b/lib/libc/gen/dlopen.3 @@ -52,7 +52,7 @@ .Fn dlsym "void * restrict handle" "const char * restrict symbol" .Ft dlfunc_t .Fn dlfunc "void * restrict handle" "const char * restrict symbol" -.Ft const char * +.Ft char * .Fn dlerror "void" .Ft int .Fn dlclose "void *handle" diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index cab8c87d86f..481cc1349eb 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -1961,7 +1961,7 @@ dlclose(void *handle) return 0; } -const char * +char * dlerror(void) { char *msg = error_message; From 824d100ff7d3d3ef50963478cac2721315010f1c Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 31 Mar 2010 15:32:36 +0000 Subject: [PATCH 1788/2592] MFC: r205297, r205347, r205452, r205455, r205649, r205650 Sync. x86bios with HEAD. - Detect illegal access to unmapped memory within real mode emulator. - Map EBDA if available and support memory wraparound above 1MB as VM86 does. - Set initial %ds to 0x40 as X.org int10 handler does. - Print the initial memory map when bootverbose is set. - Optimize real mode page table lookup. - Add strictly aligned memory access for distant future. - Update copyright date. --- sys/compat/x86bios/x86bios.c | 148 +++++++++++++++++++++++++++++------ 1 file changed, 125 insertions(+), 23 deletions(-) diff --git a/sys/compat/x86bios/x86bios.c b/sys/compat/x86bios/x86bios.c index e7b79f7ea8b..d5512fc43f3 100644 --- a/sys/compat/x86bios/x86bios.c +++ b/sys/compat/x86bios/x86bios.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2009 Alex Keda - * Copyright (c) 2009 Jung-uk Kim + * Copyright (c) 2009-2010 Jung-uk Kim * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,9 +60,9 @@ __FBSDID("$FreeBSD$"); #define X86BIOS_IVT_BASE 0x00000000 #define X86BIOS_RAM_BASE 0x00001000 -#define X86BIOS_ROM_BASE 0x000a0000 /* XXX EBDA? */ +#define X86BIOS_ROM_BASE 0x000a0000 -#define X86BIOS_ROM_SIZE (X86BIOS_MEM_SIZE - X86BIOS_ROM_BASE) +#define X86BIOS_ROM_SIZE (X86BIOS_MEM_SIZE - (uint32_t)x86bios_rom_phys) #define X86BIOS_PAGES (X86BIOS_MEM_SIZE / X86BIOS_PAGE_SIZE) @@ -79,8 +79,14 @@ static void *x86bios_seg; static vm_offset_t *x86bios_map; +static vm_paddr_t x86bios_rom_phys; static vm_paddr_t x86bios_seg_phys; +static int x86bios_fault; +static uint32_t x86bios_fault_addr; +static uint16_t x86bios_fault_cs; +static uint16_t x86bios_fault_ip; + SYSCTL_NODE(_debug, OID_AUTO, x86bios, CTLFLAG_RD, NULL, "x86bios debugging"); static int x86bios_trace_call; TUNABLE_INT("debug.x86bios.call", &x86bios_trace_call); @@ -91,18 +97,30 @@ TUNABLE_INT("debug.x86bios.int", &x86bios_trace_int); SYSCTL_INT(_debug_x86bios, OID_AUTO, int, CTLFLAG_RW, &x86bios_trace_int, 0, "Trace software interrupt handlers"); +static void +x86bios_set_fault(struct x86emu *emu, uint32_t addr) +{ + + x86bios_fault = 1; + x86bios_fault_addr = addr; + x86bios_fault_cs = emu->x86.R_CS; + x86bios_fault_ip = emu->x86.R_IP; + x86emu_halt_sys(emu); +} + static void * x86bios_get_pages(uint32_t offset, size_t size) { - int i; + vm_offset_t page; - if (offset + size > X86BIOS_MEM_SIZE) + if (offset + size > X86BIOS_MEM_SIZE + X86BIOS_IVT_SIZE) return (NULL); - i = offset / X86BIOS_PAGE_SIZE; - if (x86bios_map[i] != 0) - return ((void *)(x86bios_map[i] + offset - - i * X86BIOS_PAGE_SIZE)); + if (offset >= X86BIOS_MEM_SIZE) + offset -= X86BIOS_MEM_SIZE; + page = x86bios_map[offset / X86BIOS_PAGE_SIZE]; + if (page != 0) + return ((void *)(page + offset % X86BIOS_PAGE_SIZE)); return (NULL); } @@ -124,7 +142,7 @@ x86bios_emu_rdb(struct x86emu *emu, uint32_t addr) va = x86bios_get_pages(addr, sizeof(*va)); if (va == NULL) - x86emu_halt_sys(emu); + x86bios_set_fault(emu, addr); return (*va); } @@ -136,8 +154,13 @@ x86bios_emu_rdw(struct x86emu *emu, uint32_t addr) va = x86bios_get_pages(addr, sizeof(*va)); if (va == NULL) - x86emu_halt_sys(emu); + x86bios_set_fault(emu, addr); +#ifndef __NO_STRICT_ALIGNMENT + if ((addr & 1) != 0) + return (le16dec(va)); + else +#endif return (le16toh(*va)); } @@ -148,8 +171,13 @@ x86bios_emu_rdl(struct x86emu *emu, uint32_t addr) va = x86bios_get_pages(addr, sizeof(*va)); if (va == NULL) - x86emu_halt_sys(emu); + x86bios_set_fault(emu, addr); +#ifndef __NO_STRICT_ALIGNMENT + if ((addr & 3) != 0) + return (le32dec(va)); + else +#endif return (le32toh(*va)); } @@ -160,7 +188,7 @@ x86bios_emu_wrb(struct x86emu *emu, uint32_t addr, uint8_t val) va = x86bios_get_pages(addr, sizeof(*va)); if (va == NULL) - x86emu_halt_sys(emu); + x86bios_set_fault(emu, addr); *va = val; } @@ -172,8 +200,13 @@ x86bios_emu_wrw(struct x86emu *emu, uint32_t addr, uint16_t val) va = x86bios_get_pages(addr, sizeof(*va)); if (va == NULL) - x86emu_halt_sys(emu); + x86bios_set_fault(emu, addr); +#ifndef __NO_STRICT_ALIGNMENT + if ((addr & 1) != 0) + le16enc(va, val); + else +#endif *va = htole16(val); } @@ -184,8 +217,13 @@ x86bios_emu_wrl(struct x86emu *emu, uint32_t addr, uint32_t val) va = x86bios_get_pages(addr, sizeof(*va)); if (va == NULL) - x86emu_halt_sys(emu); + x86bios_set_fault(emu, addr); +#ifndef __NO_STRICT_ALIGNMENT + if ((addr & 3) != 0) + le32enc(va, val); + else +#endif *va = htole32(val); } @@ -281,7 +319,7 @@ x86bios_alloc(uint32_t *offset, size_t size) return (NULL); vaddr = contigmalloc(size, M_DEVBUF, M_NOWAIT, X86BIOS_RAM_BASE, - X86BIOS_ROM_BASE, X86BIOS_PAGE_SIZE, 0); + x86bios_rom_phys, X86BIOS_PAGE_SIZE, 0); if (vaddr != NULL) { *offset = vtophys(vaddr); x86bios_set_pages((vm_offset_t)vaddr, *offset, size); @@ -299,7 +337,7 @@ x86bios_free(void *addr, size_t size) return; paddr = vtophys(addr); - if (paddr < X86BIOS_RAM_BASE || paddr >= X86BIOS_ROM_BASE || + if (paddr < X86BIOS_RAM_BASE || paddr >= x86bios_rom_phys || paddr % X86BIOS_PAGE_SIZE != 0) return; @@ -313,7 +351,8 @@ x86bios_init_regs(struct x86regs *regs) { bzero(regs, sizeof(*regs)); - regs->X86BIOS_R_DS = regs->X86BIOS_R_SS = x86bios_seg_phys >> 4; + regs->X86BIOS_R_DS = 0x40; + regs->X86BIOS_R_SS = x86bios_seg_phys >> 4; } void @@ -331,15 +370,21 @@ x86bios_call(struct x86regs *regs, uint16_t seg, uint16_t off) mtx_lock_spin(&x86bios_lock); memcpy(&x86bios_emu.x86, regs, sizeof(*regs)); + x86bios_fault = 0; x86emu_exec_call(&x86bios_emu, seg, off); memcpy(regs, &x86bios_emu.x86, sizeof(*regs)); mtx_unlock_spin(&x86bios_lock); - if (x86bios_trace_call) + if (x86bios_trace_call) { 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); + if (x86bios_fault) + printf("Page fault at 0x%05x from 0x%04x:0x%04x.\n", + x86bios_fault_addr, x86bios_fault_cs, + x86bios_fault_ip); + } } uint32_t @@ -370,15 +415,21 @@ x86bios_intr(struct x86regs *regs, int intno) mtx_lock_spin(&x86bios_lock); memcpy(&x86bios_emu.x86, regs, sizeof(*regs)); + x86bios_fault = 0; x86emu_exec_intr(&x86bios_emu, intno); memcpy(regs, &x86bios_emu.x86, sizeof(*regs)); mtx_unlock_spin(&x86bios_lock); - if (x86bios_trace_int) + if (x86bios_trace_int) { printf("Exiting int 0x%x (ax=0x%04x bx=0x%04x " "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n", intno, regs->R_AX, regs->R_BX, regs->R_CX, regs->R_DX, regs->R_ES, regs->R_DI); + if (x86bios_fault) + printf("Page fault at 0x%05x from 0x%04x:0x%04x.\n", + x86bios_fault_addr, x86bios_fault_cs, + x86bios_fault_ip); + } } void * @@ -433,6 +484,12 @@ x86bios_match_device(uint32_t offset, device_t dev) return (1); } +#if defined(__amd64__) || (defined(__i386__) && !defined(PC98)) +#define PROBE_EBDA 1 +#else +#define PROBE_EBDA 0 +#endif + static __inline int x86bios_map_mem(void) { @@ -440,18 +497,63 @@ x86bios_map_mem(void) 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); + +#if PROBE_EBDA + /* Probe EBDA via BDA. */ + x86bios_rom_phys = *(uint16_t *)((vm_offset_t)x86bios_ivt + 0x40e); + x86bios_rom_phys = le16toh(x86bios_rom_phys) << 4; + if (x86bios_rom_phys != 0 && x86bios_rom_phys < X86BIOS_ROM_BASE && + X86BIOS_ROM_BASE - x86bios_rom_phys <= 128 * 1024) + x86bios_rom_phys = + rounddown(x86bios_rom_phys, X86BIOS_PAGE_SIZE); + else +#endif + x86bios_rom_phys = X86BIOS_ROM_BASE; + x86bios_rom = pmap_mapdev(x86bios_rom_phys, X86BIOS_ROM_SIZE); if (x86bios_rom == NULL) { pmap_unmapdev((vm_offset_t)x86bios_ivt, X86BIOS_IVT_SIZE); return (1); } +#if PROBE_EBDA + /* Change attribute for EBDA. */ + if (x86bios_rom_phys < X86BIOS_ROM_BASE && + pmap_change_attr((vm_offset_t)x86bios_rom, + X86BIOS_ROM_BASE - x86bios_rom_phys, PAT_WRITE_BACK) != 0) { + pmap_unmapdev((vm_offset_t)x86bios_ivt, X86BIOS_IVT_SIZE); + pmap_unmapdev((vm_offset_t)x86bios_rom, X86BIOS_ROM_SIZE); + return (1); + } +#endif + x86bios_seg = contigmalloc(X86BIOS_SEG_SIZE, M_DEVBUF, M_WAITOK, - X86BIOS_RAM_BASE, X86BIOS_ROM_BASE, X86BIOS_PAGE_SIZE, 0); + X86BIOS_RAM_BASE, x86bios_rom_phys, X86BIOS_PAGE_SIZE, 0); x86bios_seg_phys = vtophys(x86bios_seg); + if (bootverbose) { + printf("x86bios: IVT 0x%06x-0x%06x at %p\n", + X86BIOS_IVT_BASE, X86BIOS_IVT_SIZE + X86BIOS_IVT_BASE - 1, + x86bios_ivt); + printf("x86bios: SSEG 0x%06x-0x%06x at %p\n", + (uint32_t)x86bios_seg_phys, + X86BIOS_SEG_SIZE + (uint32_t)x86bios_seg_phys - 1, + x86bios_seg); +#if PROBE_EBDA + if (x86bios_rom_phys < X86BIOS_ROM_BASE) + printf("x86bios: EBDA 0x%06x-0x%06x at %p\n", + (uint32_t)x86bios_rom_phys, X86BIOS_ROM_BASE - 1, + x86bios_rom); +#endif + printf("x86bios: ROM 0x%06x-0x%06x at %p\n", + X86BIOS_ROM_BASE, X86BIOS_MEM_SIZE - X86BIOS_SEG_SIZE - 1, + (void *)((vm_offset_t)x86bios_rom + X86BIOS_ROM_BASE - + (vm_offset_t)x86bios_rom_phys)); + } + return (0); } +#undef PROBE_EBDA + static __inline void x86bios_unmap_mem(void) { @@ -475,7 +577,7 @@ x86bios_init(void *arg __unused) 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_set_pages((vm_offset_t)x86bios_rom, x86bios_rom_phys, X86BIOS_ROM_SIZE); x86bios_set_pages((vm_offset_t)x86bios_seg, x86bios_seg_phys, X86BIOS_SEG_SIZE); From 86a2d033e46170f119c7a04cf6136669a8af7940 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 31 Mar 2010 15:39:46 +0000 Subject: [PATCH 1789/2592] MFC: r205550, r205605, r205865 Sync. pixel mode support for syscons(4) with HEAD. - Separate 24-bit pixel draw from 32-bit case. Although it is slower, we do not want to write a useless zero to inaccessible memory region. - We only want the dummy palette for direct color mode. --- sys/dev/syscons/scvgarndr.c | 10 +++++++++- sys/dev/syscons/scvidctl.c | 4 ++-- sys/dev/syscons/syscons.c | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c index fd823ce434b..dbee6f200d4 100644 --- a/sys/dev/syscons/scvgarndr.c +++ b/sys/dev/syscons/scvgarndr.c @@ -181,9 +181,17 @@ static u_short mouse_or_mask[16] = { #define vga_drawpxl(pos, color) \ switch (scp->sc->adp->va_info.vi_depth) { \ case 32: \ - case 24: \ writel(pos, vga_palette32[color]); \ break; \ + case 24: \ + if (((pos) & 1) == 0) { \ + writew(pos, vga_palette32[color]); \ + writeb(pos + 2, vga_palette32[color] >> 16);\ + } else { \ + writeb(pos, vga_palette32[color]); \ + writew(pos + 1, vga_palette32[color] >> 8);\ + } \ + break; \ case 16: \ if (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)\ writew(pos, vga_palette15[color]); \ diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c index 0f55499bac7..5c3dc8e3979 100644 --- a/sys/dev/syscons/scvidctl.c +++ b/sys/dev/syscons/scvidctl.c @@ -741,7 +741,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) #ifndef SC_NO_PALETTE_LOADING #ifdef SC_PIXEL_MODE - if ((adp->va_flags & V_ADP_DAC8) != 0) + if (adp->va_info.vi_mem_model == V_INFO_MM_DIRECT) vidd_load_palette(adp, scp->sc->palette2); else #endif @@ -802,7 +802,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) if (scp == scp->sc->cur_scp) { set_mode(scp); #ifndef SC_NO_PALETTE_LOADING - if ((adp->va_flags & V_ADP_DAC8) != 0) + if (adp->va_info.vi_mem_model == V_INFO_MM_DIRECT) vidd_load_palette(adp, scp->sc->palette2); else vidd_load_palette(adp, scp->sc->palette); diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 8dffe5cd538..1819225b366 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -2127,7 +2127,7 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode) if (set_mode(scp) == 0) { #ifndef SC_NO_PALETTE_LOADING #ifdef SC_PIXEL_MODE - if ((scp->sc->adp->va_flags & V_ADP_DAC8) != 0) + if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT) vidd_load_palette(scp->sc->adp, scp->sc->palette2); else #endif @@ -2536,7 +2536,7 @@ exchange_scr(sc_softc_t *sc) #ifndef SC_NO_PALETTE_LOADING if (ISGRAPHSC(sc->old_scp)) { #ifdef SC_PIXEL_MODE - if ((sc->adp->va_flags & V_ADP_DAC8) != 0) + if (sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT) vidd_load_palette(sc->adp, sc->palette2); else #endif From 7058bb70ff5a47f95f13f7fb843ede73b959166d Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 31 Mar 2010 15:45:11 +0000 Subject: [PATCH 1790/2592] MFC: r205557, r205558, r205564, r205566, r205604, r205653 Sync. pixel mode support for VESA and VGA frame buffers with HEAD. - Map entire video memory again. Although we do not use them all directly, it seems VGA renderer may access unmapped memory region and cause kernel panic. - Fall back to VGA palette functions if VESA function failed and DAC is still in 6-bit mode. Although we have to check non-VGA compatibility bit here, it seems there are too many broken VESA BIOSes out to rely on it. - Be careful when we determine bytes per scan line information. We compare mode table data against minimum value. If the mode table does not make sense, we set the minimum in the mode info. - Teach VGA framebuffer about 8-bit palette format for VESA. - Add my copyright here. --- sys/dev/fb/vesa.c | 93 +++++++++++++++++++++++++++++++++++------------ sys/dev/fb/vga.c | 24 ++++++++---- 2 files changed, 86 insertions(+), 31 deletions(-) diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c index df0dc1e65be..911f3a39c7f 100644 --- a/sys/dev/fb/vesa.c +++ b/sys/dev/fb/vesa.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 1998 Kazutaka YOKOTA and Michael Smith + * Copyright (c) 2009-2010 Jung-uk Kim * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -188,7 +189,7 @@ static int vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, #define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG) static ssize_t vesa_bios_state_buf_size(void); static int vesa_bios_save_restore(int code, void *p, size_t size); -#if 0 +#ifdef MODE_TABLE_BROKEN static int vesa_bios_get_line_length(void); #endif static int vesa_bios_set_line_length(int pixel, int *bytes, int *lines); @@ -199,6 +200,7 @@ static int vesa_bios_set_start(int x, int y); static int vesa_map_gen_mode_num(int type, int color, int mode); static int vesa_translate_flags(u_int16_t vflags); static int vesa_translate_mmodel(u_int8_t vmodel); +static int vesa_get_bpscanline(struct vesa_mode *vmode); static int vesa_bios_init(void); static void vesa_clear_modes(video_info_t *info, int color); @@ -558,7 +560,7 @@ vesa_bios_save_restore(int code, void *p, size_t size) return (regs.R_AX != 0x004f); } -#if 0 +#ifdef MODE_TABLE_BROKEN static int vesa_bios_get_line_length(void) { @@ -709,6 +711,43 @@ vesa_translate_mmodel(u_int8_t vmodel) return (V_INFO_MM_OTHER); } +static int +vesa_get_bpscanline(struct vesa_mode *vmode) +{ + int bpsl; + + if ((vmode->v_modeattr & V_MODEGRAPHICS) != 0) { + /* Find the minimum length. */ + switch (vmode->v_bpp / vmode->v_planes) { + case 1: + bpsl = vmode->v_width / 8; + break; + case 2: + bpsl = vmode->v_width / 4; + break; + case 4: + bpsl = vmode->v_width / 2; + break; + default: + bpsl = vmode->v_width * ((vmode->v_bpp + 7) / 8); + bpsl /= vmode->v_planes; + break; + } + + /* Use VBE 3.0 information if it looks sane. */ + if ((vmode->v_modeattr & V_MODELFB) != 0 && + vesa_adp_info->v_version >= 0x0300 && + vmode->v_linbpscanline > bpsl) + return (vmode->v_linbpscanline); + + /* Return the minimum if the mode table looks absurd. */ + if (vmode->v_bpscanline < bpsl) + return (bpsl); + } + + return (vmode->v_bpscanline); +} + #define VESA_MAXSTR 256 #define VESA_STRCPY(dst, src) do { \ @@ -733,7 +772,6 @@ vesa_bios_init(void) void *vmbuf; uint32_t offs; uint16_t vers; - int bpsl; int is_via_cle266; int modes; int i; @@ -858,9 +896,7 @@ vesa_bios_init(void) } #endif - bpsl = (vmode.v_modeattr & V_MODELFB) != 0 && vers >= 0x0300 ? - vmode.v_linbpscanline : vmode.v_bpscanline; - bsize = bpsl * vmode.v_height; + bsize = vesa_get_bpscanline(&vmode) * vmode.v_height; if ((vmode.v_modeattr & V_MODEGRAPHICS) != 0) bsize *= vmode.v_planes; @@ -1209,7 +1245,7 @@ vesa_set_mode(video_adapter_t *adp, int mode) int10_set_mode(adp->va_initial_bios_mode); if (adp->va_info.vi_flags & V_INFO_LINEAR) pmap_unmapdev(adp->va_buffer, - adp->va_buffer_size); + vesa_adp_info->v_memsize * 64 * 1024); /* * Once (*prevvidsw->get_info)() succeeded, * (*prevvidsw->set_mode)() below won't fail... @@ -1241,12 +1277,12 @@ vesa_set_mode(video_adapter_t *adp, int mode) if ((vesa_adp_info->v_flags & V_DAC8) != 0 && (info.vi_flags & V_INFO_GRAPHICS) != 0 && - (info.vi_flags & V_INFO_NONVGA) != 0 && vesa_bios_set_dac(8) > 6) adp->va_flags |= V_ADP_DAC8; if (adp->va_info.vi_flags & V_INFO_LINEAR) - pmap_unmapdev(adp->va_buffer, adp->va_buffer_size); + pmap_unmapdev(adp->va_buffer, + vesa_adp_info->v_memsize * 64 * 1024); #if VESA_DEBUG > 0 printf("VESA: mode set!\n"); @@ -1257,13 +1293,31 @@ vesa_set_mode(video_adapter_t *adp, int mode) (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0; vesa_adp->va_crtc_addr = (vesa_adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC; + + vesa_adp->va_line_width = info.vi_buffer_size / info.vi_height; + if ((info.vi_flags & V_INFO_GRAPHICS) != 0) + vesa_adp->va_line_width /= info.vi_planes; + +#ifdef MODE_TABLE_BROKEN + /* If VBE function returns bigger bytes per scan line, use it. */ + { + int bpsl = vesa_bios_get_line_length(); + if (bpsl > vesa_adp->va_line_width) { + vesa_adp->va_line_width = bpsl; + info.vi_buffer_size = bpsl * info.vi_height; + if ((info.vi_flags & V_INFO_GRAPHICS) != 0) + info.vi_buffer_size *= info.vi_planes; + } + } +#endif + if (info.vi_flags & V_INFO_LINEAR) { #if VESA_DEBUG > 1 printf("VESA: setting up LFB\n"); #endif vesa_adp->va_buffer = (vm_offset_t)pmap_mapdev_attr(info.vi_buffer, - info.vi_buffer_size, PAT_WRITE_COMBINING); + vesa_adp_info->v_memsize * 64 * 1024, PAT_WRITE_COMBINING); vesa_adp->va_window = vesa_adp->va_buffer; vesa_adp->va_window_size = info.vi_buffer_size / info.vi_planes; vesa_adp->va_window_gran = info.vi_buffer_size / info.vi_planes; @@ -1275,9 +1329,6 @@ vesa_set_mode(video_adapter_t *adp, int mode) } vesa_adp->va_buffer_size = info.vi_buffer_size; vesa_adp->va_window_orig = 0; - vesa_adp->va_line_width = info.vi_buffer_size / info.vi_height; - if ((info.vi_flags & V_INFO_GRAPHICS) != 0) - vesa_adp->va_line_width /= info.vi_planes; vesa_adp->va_disp_start.x = 0; vesa_adp->va_disp_start.y = 0; #if VESA_DEBUG > 0 @@ -1322,10 +1373,10 @@ vesa_save_palette(video_adapter_t *adp, u_char *palette) { int bits; - if (adp == vesa_adp && VESA_MODE(adp->va_mode) && - (adp->va_info.vi_flags & V_INFO_NONVGA) != 0) { + if (adp == vesa_adp && VESA_MODE(adp->va_mode)) { bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6; - return (vesa_bios_save_palette(0, 256, palette, bits)); + if (vesa_bios_save_palette(0, 256, palette, bits) == 0) + return (0); } return ((*prevvidsw->save_palette)(adp, palette)); @@ -1336,10 +1387,10 @@ vesa_load_palette(video_adapter_t *adp, u_char *palette) { int bits; - if (adp == vesa_adp && VESA_MODE(adp->va_mode) && - (adp->va_info.vi_flags & V_INFO_NONVGA) != 0) { + if (adp == vesa_adp && VESA_MODE(adp->va_mode)) { bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6; - return (vesa_bios_load_palette(0, 256, palette, bits)); + if (vesa_bios_load_palette(0, 256, palette, bits) == 0) + return (0); } return ((*prevvidsw->load_palette)(adp, palette)); @@ -1544,8 +1595,6 @@ get_palette(video_adapter_t *adp, int base, int count, return (1); if (!VESA_MODE(adp->va_mode)) return (1); - if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0) - return (1); bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6; r = malloc(count * 3, M_DEVBUF, M_WAITOK); @@ -1582,8 +1631,6 @@ set_palette(video_adapter_t *adp, int base, int count, return (1); if (!VESA_MODE(adp->va_mode)) return (1); - if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0) - return (1); bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6; r = malloc(count * 3, M_DEVBUF, M_WAITOK); diff --git a/sys/dev/fb/vga.c b/sys/dev/fb/vga.c index a2e99f2b24e..bd215fbeed6 100644 --- a/sys/dev/fb/vga.c +++ b/sys/dev/fb/vga.c @@ -1979,6 +1979,7 @@ vga_show_font(video_adapter_t *adp, int page) static int vga_save_palette(video_adapter_t *adp, u_char *palette) { + int bits; int i; prologue(adp, V_ADP_PALETTE, ENODEV); @@ -1988,8 +1989,9 @@ vga_save_palette(video_adapter_t *adp, u_char *palette) * VGA has 6 bit DAC . */ outb(PALRADR, 0x00); + bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2; for (i = 0; i < 256*3; ++i) - palette[i] = inb(PALDATA) << 2; + palette[i] = inb(PALDATA) << bits; inb(adp->va_crtc_addr + 6); /* reset flip/flop */ return 0; } @@ -1998,15 +2000,17 @@ static int vga_save_palette2(video_adapter_t *adp, int base, int count, u_char *r, u_char *g, u_char *b) { + int bits; int i; prologue(adp, V_ADP_PALETTE, ENODEV); outb(PALRADR, base); + bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2; for (i = 0; i < count; ++i) { - r[i] = inb(PALDATA) << 2; - g[i] = inb(PALDATA) << 2; - b[i] = inb(PALDATA) << 2; + r[i] = inb(PALDATA) << bits; + g[i] = inb(PALDATA) << bits; + b[i] = inb(PALDATA) << bits; } inb(adp->va_crtc_addr + 6); /* reset flip/flop */ return 0; @@ -2021,14 +2025,16 @@ vga_save_palette2(video_adapter_t *adp, int base, int count, static int vga_load_palette(video_adapter_t *adp, u_char *palette) { + int bits; int i; prologue(adp, V_ADP_PALETTE, ENODEV); outb(PIXMASK, 0xff); /* no pixelmask */ outb(PALWADR, 0x00); + bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2; for (i = 0; i < 256*3; ++i) - outb(PALDATA, palette[i] >> 2); + outb(PALDATA, palette[i] >> bits); inb(adp->va_crtc_addr + 6); /* reset flip/flop */ outb(ATC, 0x20); /* enable palette */ return 0; @@ -2038,16 +2044,18 @@ static int vga_load_palette2(video_adapter_t *adp, int base, int count, u_char *r, u_char *g, u_char *b) { + int bits; int i; prologue(adp, V_ADP_PALETTE, ENODEV); outb(PIXMASK, 0xff); /* no pixelmask */ outb(PALWADR, base); + bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2; for (i = 0; i < count; ++i) { - outb(PALDATA, r[i] >> 2); - outb(PALDATA, g[i] >> 2); - outb(PALDATA, b[i] >> 2); + outb(PALDATA, r[i] >> bits); + outb(PALDATA, g[i] >> bits); + outb(PALDATA, b[i] >> bits); } inb(adp->va_crtc_addr + 6); /* reset flip/flop */ outb(ATC, 0x20); /* enable palette */ From 516a153f9853fc059d1d991ae457a75caf8ed35c Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 31 Mar 2010 15:49:10 +0000 Subject: [PATCH 1791/2592] MFC: r197185 Enable BIOS modes on amd64. --- sys/dev/fb/vga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/fb/vga.c b/sys/dev/fb/vga.c index bd215fbeed6..14f890c9eba 100644 --- a/sys/dev/fb/vga.c +++ b/sys/dev/fb/vga.c @@ -177,7 +177,7 @@ vga_mmap(struct cdev *dev, vga_softc_t *sc, vm_offset_t offset, vm_offset_t *pad #endif /* architecture dependent option */ -#ifndef __i386__ +#if !defined(__i386__) && !defined(__amd64__) #define VGA_NO_BIOS 1 #endif From 3a0a3e0496d34c197a0ae5b7359c68688310ee9d Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 31 Mar 2010 16:01:48 +0000 Subject: [PATCH 1792/2592] MFC: r205855 Print memory model of the video mode except for planar memory model. 'P', 'D', 'C', 'H', and 'V' mean packed pixel, direct color, CGA, Hercules, and VGA X memory models respectively where they have fixed number of planes. --- usr.sbin/vidcontrol/vidcontrol.c | 37 +++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/usr.sbin/vidcontrol/vidcontrol.c b/usr.sbin/vidcontrol/vidcontrol.c index 847ff3e6e23..c419c144a59 100644 --- a/usr.sbin/vidcontrol/vidcontrol.c +++ b/usr.sbin/vidcontrol/vidcontrol.c @@ -950,10 +950,11 @@ show_adapter_info(void) static void show_mode_info(void) { - struct video_info _info; char buf[80]; - int mode; + struct video_info _info; int c; + int mm; + int mode; printf(" mode# flags type size " "font window linear buffer\n"); @@ -972,9 +973,35 @@ show_mode_info(void) if (_info.vi_flags & V_INFO_GRAPHICS) { c = 'G'; - snprintf(buf, sizeof(buf), "%dx%dx%d %d", - _info.vi_width, _info.vi_height, - _info.vi_depth, _info.vi_planes); + if (_info.vi_mem_model == V_INFO_MM_PLANAR) + snprintf(buf, sizeof(buf), "%dx%dx%d %d", + _info.vi_width, _info.vi_height, + _info.vi_depth, _info.vi_planes); + else { + switch (_info.vi_mem_model) { + case V_INFO_MM_PACKED: + mm = 'P'; + break; + case V_INFO_MM_DIRECT: + mm = 'D'; + break; + case V_INFO_MM_CGA: + mm = 'C'; + break; + case V_INFO_MM_HGC: + mm = 'H'; + break; + case V_INFO_MM_VGAX: + mm = 'V'; + break; + default: + mm = ' '; + break; + } + snprintf(buf, sizeof(buf), "%dx%dx%d %c", + _info.vi_width, _info.vi_height, + _info.vi_depth, mm); + } } else { c = 'T'; From bd742eaf9ca23c7bc0a0092c3b53640a7718c760 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Wed, 31 Mar 2010 21:32:52 +0000 Subject: [PATCH 1793/2592] MFC: r204152, r204164 Some machines can not only consist of CPUs running at different speeds but also of different types, f.e. Sun Fire V890 can be equipped with a mix of UltraSPARC IV and IV+ CPUs, requiring different MMU initialization and different workarounds for model specific errata. Therefore move the CPU implementation number from a global variable to the per-CPU data. Functions which are called before the latter is available are passed the implementation number as a parameter now. --- sys/boot/sparc64/loader/main.c | 2 +- sys/sparc64/include/cache.h | 2 +- sys/sparc64/include/cpu.h | 2 +- sys/sparc64/include/md_var.h | 4 ++-- sys/sparc64/include/pcpu.h | 1 + sys/sparc64/include/pmap.h | 2 +- sys/sparc64/include/smp.h | 2 +- sys/sparc64/include/tick.h | 4 ++-- sys/sparc64/include/ver.h | 26 ++++++++++++--------- sys/sparc64/sparc64/cache.c | 2 +- sys/sparc64/sparc64/cheetah.c | 4 ++-- sys/sparc64/sparc64/identcpu.c | 3 --- sys/sparc64/sparc64/iommu.c | 3 ++- sys/sparc64/sparc64/machdep.c | 30 +++++++++++++----------- sys/sparc64/sparc64/mp_locore.S | 12 +++++----- sys/sparc64/sparc64/mp_machdep.c | 40 +++++++++++++++++++------------- sys/sparc64/sparc64/nexus.c | 3 ++- sys/sparc64/sparc64/pmap.c | 5 ++-- sys/sparc64/sparc64/spitfire.c | 2 +- sys/sparc64/sparc64/tick.c | 6 ++--- sys/sparc64/sparc64/trap.c | 3 ++- 21 files changed, 87 insertions(+), 71 deletions(-) diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c index 72041694f01..2afbfeeb75e 100644 --- a/sys/boot/sparc64/loader/main.c +++ b/sys/boot/sparc64/loader/main.c @@ -137,7 +137,7 @@ struct tlb_entry *dtlb_store; struct tlb_entry *itlb_store; u_int dtlb_slot; u_int itlb_slot; -int cpu_impl; +static int cpu_impl; static u_int dtlb_slot_max; static u_int itlb_slot_max; diff --git a/sys/sparc64/include/cache.h b/sys/sparc64/include/cache.h index 9dd71914a1b..9c4804b9776 100644 --- a/sys/sparc64/include/cache.h +++ b/sys/sparc64/include/cache.h @@ -91,7 +91,7 @@ struct cacheinfo { struct pcpu; -typedef void cache_enable_t(void); +typedef void cache_enable_t(u_int cpu_impl); typedef void cache_flush_t(void); typedef void dcache_page_inval_t(vm_paddr_t pa); typedef void icache_page_inval_t(vm_paddr_t pa); diff --git a/sys/sparc64/include/cpu.h b/sys/sparc64/include/cpu.h index b593f13ce9b..c0845a0771b 100644 --- a/sys/sparc64/include/cpu.h +++ b/sys/sparc64/include/cpu.h @@ -52,7 +52,7 @@ extern char btext[]; extern char etext[]; -void cheetah_init(void); +void cheetah_init(u_int cpu_impl); void cpu_halt(void); void cpu_reset(void); void fork_trampoline(void); diff --git a/sys/sparc64/include/md_var.h b/sys/sparc64/include/md_var.h index 592d980f317..a1f39807b8c 100644 --- a/sys/sparc64/include/md_var.h +++ b/sys/sparc64/include/md_var.h @@ -47,8 +47,8 @@ extern vm_paddr_t kstack0_phys; struct pcpu; struct md_utrap; -const char *cpu_cpuid_prop(void); -uint32_t cpu_get_mid(void); +const char *cpu_cpuid_prop(u_int cpu_impl); +uint32_t cpu_get_mid(u_int cpu_impl); void cpu_identify(u_long vers, u_int clock, u_int id); void cpu_setregs(struct pcpu *pc); int is_physical_memory(vm_paddr_t addr); diff --git a/sys/sparc64/include/pcpu.h b/sys/sparc64/include/pcpu.h index 7d2f5a023fc..f5735bf4801 100644 --- a/sys/sparc64/include/pcpu.h +++ b/sys/sparc64/include/pcpu.h @@ -54,6 +54,7 @@ struct pmap; u_long pc_tickref; \ u_long pc_tickadj; \ u_int pc_clock; \ + u_int pc_impl; \ u_int pc_mid; \ u_int pc_node; \ u_int pc_tlb_ctx; \ diff --git a/sys/sparc64/include/pmap.h b/sys/sparc64/include/pmap.h index 91c2a51eb64..83c81904b50 100644 --- a/sys/sparc64/include/pmap.h +++ b/sys/sparc64/include/pmap.h @@ -80,7 +80,7 @@ struct pmap { #define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT #define pmap_page_set_memattr(m, ma) (void)0 -void pmap_bootstrap(void); +void pmap_bootstrap(u_int cpu_impl); vm_paddr_t pmap_kextract(vm_offset_t va); void pmap_kenter(vm_offset_t va, vm_page_t m); void pmap_kremove(vm_offset_t); diff --git a/sys/sparc64/include/smp.h b/sys/sparc64/include/smp.h index 87355430ca3..467c6b63911 100644 --- a/sys/sparc64/include/smp.h +++ b/sys/sparc64/include/smp.h @@ -94,7 +94,7 @@ void cpu_mp_shutdown(void); typedef void cpu_ipi_selected_t(u_int, u_long, u_long, u_long); extern cpu_ipi_selected_t *cpu_ipi_selected; -void mp_init(void); +void mp_init(u_int cpu_impl); extern struct mtx ipi_mtx; extern struct ipi_cache_args ipi_cache_args; diff --git a/sys/sparc64/include/tick.h b/sys/sparc64/include/tick.h index 9182cb405b5..ae80d53c501 100644 --- a/sys/sparc64/include/tick.h +++ b/sys/sparc64/include/tick.h @@ -31,8 +31,8 @@ extern u_int hardclock_use_stick; -void tick_clear(void); +void tick_clear(u_int cpu_impl); void tick_start(void); -void tick_stop(void); +void tick_stop(u_int cpu_impl); #endif diff --git a/sys/sparc64/include/ver.h b/sys/sparc64/include/ver.h index 0fb7933f0bc..ad6841bd9ad 100644 --- a/sys/sparc64/include/ver.h +++ b/sys/sparc64/include/ver.h @@ -43,24 +43,28 @@ #ifndef LOCORE -#define VER_MANUF_MASK (((1L<> VER_MANUF_SHIFT) -#define VER_IMPL(ver) \ +#define VER_IMPL(ver) \ (((ver) & VER_IMPL_MASK) >> VER_IMPL_SHIFT) -#define VER_MASK(ver) \ +#define VER_MASK(ver) \ (((ver) & VER_MASK_MASK) >> VER_MASK_SHIFT) -#define VER_MAXTL(ver) \ +#define VER_MAXTL(ver) \ (((ver) & VER_MAXTL_MASK) >> VER_MAXTL_SHIFT) -#define VER_MAXWIN(ver) \ +#define VER_MAXWIN(ver) \ (((ver) & VER_MAXWIN_MASK) >> VER_MAXWIN_SHIFT) -extern int cpu_impl; extern char sparc64_model[]; #endif /* !LOCORE */ diff --git a/sys/sparc64/sparc64/cache.c b/sys/sparc64/sparc64/cache.c index 8dd933e4ecb..d558bf21024 100644 --- a/sys/sparc64/sparc64/cache.c +++ b/sys/sparc64/sparc64/cache.c @@ -130,7 +130,7 @@ cache_init(struct pcpu *pcpu) if ((set & ~(1UL << (ffs(set) - 1))) != 0) panic("cache_init: E$ set size not a power of 2"); - if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) { + if (pcpu->pc_impl >= CPU_IMPL_ULTRASPARCIII) { cache_enable = cheetah_cache_enable; cache_flush = cheetah_cache_flush; dcache_page_inval = cheetah_dcache_page_inval; diff --git a/sys/sparc64/sparc64/cheetah.c b/sys/sparc64/sparc64/cheetah.c index e2dc7144048..ae24744c9ed 100644 --- a/sys/sparc64/sparc64/cheetah.c +++ b/sys/sparc64/sparc64/cheetah.c @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$"); * CPU-specific initialization */ void -cheetah_init(void) +cheetah_init(u_int cpu_impl) { register_t s; @@ -119,7 +119,7 @@ cheetah_init(void) * Enable level 1 caches. */ void -cheetah_cache_enable(void) +cheetah_cache_enable(u_int cpu_impl) { u_long lsu; diff --git a/sys/sparc64/sparc64/identcpu.c b/sys/sparc64/sparc64/identcpu.c index cdb09e65806..0b731515f16 100644 --- a/sys/sparc64/sparc64/identcpu.c +++ b/sys/sparc64/sparc64/identcpu.c @@ -15,7 +15,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include @@ -34,8 +33,6 @@ static u_int cpu_freq; SYSCTL_UINT(_hw_freq, OID_AUTO, cpu, CTLFLAG_RD, &cpu_freq, 0, "CPU clock frequency"); -int cpu_impl; - void cpu_identify(u_long vers, u_int freq, u_int id) { diff --git a/sys/sparc64/sparc64/iommu.c b/sys/sparc64/sparc64/iommu.c index b5f24dbb2ab..9d31303c673 100644 --- a/sys/sparc64/sparc64/iommu.c +++ b/sys/sparc64/sparc64/iommu.c @@ -130,6 +130,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -377,7 +378,7 @@ iommu_init(const char *name, struct iommu_state *is, u_int tsbsize, printf("%s: PROM IOTSB size: %d (%d entries)\n", name, obptsbsize, obptsbentries); if ((is->is_flags & IOMMU_PRESERVE_PROM) != 0 && - !(cpu_impl == CPU_IMPL_ULTRASPARCIIi && obptsbsize == 7)) { + !(PCPU_GET(impl) == CPU_IMPL_ULTRASPARCIIi && obptsbsize == 7)) { if (obptsbentries > tsbentries) panic("%s: PROM IOTSB entries exceed kernel", __func__); diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index eed7db8b3bb..c5b08eea518 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -146,7 +146,7 @@ static int cpu_use_vis = 1; cpu_block_copy_t *cpu_block_copy; cpu_block_zero_t *cpu_block_zero; -static phandle_t find_bsp(phandle_t node, uint32_t bspid); +static phandle_t find_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl); void sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec); static void sparc64_shutdown_final(void *dummy, int howto); @@ -241,7 +241,7 @@ spinlock_exit(void) } static phandle_t -find_bsp(phandle_t node, uint32_t bspid) +find_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl) { char type[sizeof("cpu")]; phandle_t child; @@ -250,7 +250,7 @@ find_bsp(phandle_t node, uint32_t bspid) for (; node != 0; node = OF_peer(node)) { child = OF_child(node); if (child > 0) { - child = find_bsp(child, bspid); + child = find_bsp(child, bspid, cpu_impl); if (child > 0) return (child); } else { @@ -259,7 +259,7 @@ find_bsp(phandle_t node, uint32_t bspid) continue; if (strcmp(type, "cpu") != 0) continue; - if (OF_getprop(node, cpu_cpuid_prop(), &cpuid, + if (OF_getprop(node, cpu_cpuid_prop(cpu_impl), &cpuid, sizeof(cpuid)) <= 0) continue; if (cpuid == bspid) @@ -270,7 +270,7 @@ find_bsp(phandle_t node, uint32_t bspid) } const char * -cpu_cpuid_prop(void) +cpu_cpuid_prop(u_int cpu_impl) { switch (cpu_impl) { @@ -294,7 +294,7 @@ cpu_cpuid_prop(void) } uint32_t -cpu_get_mid(void) +cpu_get_mid(u_int cpu_impl) { switch (cpu_impl) { @@ -328,6 +328,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) vm_offset_t va; caddr_t kmdp; phandle_t root; + u_int cpu_impl; end = 0; kmdp = NULL; @@ -342,12 +343,12 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) * Do CPU-specific Initialization. */ if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) - cheetah_init(); + cheetah_init(cpu_impl); /* * Clear (S)TICK timer (including NPT). */ - tick_clear(); + tick_clear(cpu_impl); /* * UltraSparc II[e,i] based systems come up with the tick interrupt @@ -357,7 +358,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) * enabled, causing an interrupt storm on startup since they are not * handled. */ - tick_stop(); + tick_stop(cpu_impl); /* * Set up Open Firmware entry points. @@ -399,7 +400,8 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) pc = (struct pcpu *)(pcpu0 + (PCPU_PAGES * PAGE_SIZE)) - 1; pcpu_init(pc, 0, sizeof(struct pcpu)); pc->pc_addr = (vm_offset_t)pcpu0; - pc->pc_mid = cpu_get_mid(); + pc->pc_impl = cpu_impl; + pc->pc_mid = cpu_get_mid(cpu_impl); pc->pc_tlb_ctx = TLB_CTX_USER_MIN; pc->pc_tlb_ctx_min = TLB_CTX_USER_MIN; pc->pc_tlb_ctx_max = TLB_CTX_USER_MAX; @@ -409,7 +411,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) * BSP is in the device tree in the first place). */ root = OF_peer(0); - pc->pc_node = find_bsp(root, pc->pc_mid); + pc->pc_node = find_bsp(root, pc->pc_mid, cpu_impl); if (pc->pc_node == 0) OF_exit(); if (OF_getprop(pc->pc_node, "clock-frequency", &pc->pc_clock, @@ -475,7 +477,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) panic("sparc64_init: cannot determine number of iTLB slots"); cache_init(pc); - cache_enable(); + cache_enable(cpu_impl); uma_set_align(pc->pc_cache.dc_linesize - 1); cpu_block_copy = bcopy; @@ -501,13 +503,13 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) } #ifdef SMP - mp_init(); + mp_init(cpu_impl); #endif /* * Initialize virtual memory and calculate physmem. */ - pmap_bootstrap(); + pmap_bootstrap(cpu_impl); /* * Initialize tunables. diff --git a/sys/sparc64/sparc64/mp_locore.S b/sys/sparc64/sparc64/mp_locore.S index 96239d5bca0..17dc444c7d9 100644 --- a/sys/sparc64/sparc64/mp_locore.S +++ b/sys/sparc64/sparc64/mp_locore.S @@ -202,17 +202,17 @@ ENTRY(mp_startup) cmp %l1, CPU_IMPL_ULTRASPARCIII bl %icc, 3f nop - mov CPU_STICKSYNC, %l1 + mov CPU_STICKSYNC, %l2 membar #StoreLoad - stw %l1, [%l0 + CSA_STATE] + stw %l2, [%l0 + CSA_STATE] -2: ldx [%l0 + CSA_STICK], %l1 - brz %l1, 2b +2: ldx [%l0 + CSA_STICK], %l2 + brz %l2, 2b nop - wr %l1, 0, %asr24 + wr %l2, 0, %asr24 3: call cpu_get_mid - nop + mov %l1, %o0 /* * Inform the boot processor we have inited. diff --git a/sys/sparc64/sparc64/mp_machdep.c b/sys/sparc64/sparc64/mp_machdep.c index 8e9f9e1baa6..8ea72f3954a 100644 --- a/sys/sparc64/sparc64/mp_machdep.c +++ b/sys/sparc64/sparc64/mp_machdep.c @@ -119,11 +119,11 @@ static u_int cpuid_to_mid[MAXCPU]; static int isjbus; static volatile u_int shutdown_cpus; -static void ap_count(phandle_t node, u_int mid); -static void ap_start(phandle_t node, u_int mid); +static void ap_count(phandle_t node, u_int mid, u_int cpu_impl); +static void ap_start(phandle_t node, u_int mid, u_int cpu_impl); static void cpu_mp_unleash(void *v); static void foreach_ap(phandle_t node, void (*func)(phandle_t node, - u_int mid)); + u_int mid, u_int cpu_impl)); static void spitfire_ipi_send(u_int mid, u_long d0, u_long d1, u_long d2); static void sun4u_startcpu(phandle_t cpu, void *func, u_long arg); @@ -137,7 +137,7 @@ CTASSERT(MAXCPU <= sizeof(u_int) * NBBY); CTASSERT(MAXCPU <= sizeof(int) * NBBY); void -mp_init(void) +mp_init(u_int cpu_impl) { struct tte *tp; int i; @@ -171,11 +171,13 @@ mp_init(void) } static void -foreach_ap(phandle_t node, void (*func)(phandle_t node, u_int mid)) +foreach_ap(phandle_t node, void (*func)(phandle_t node, u_int mid, + u_int cpu_impl)) { char type[sizeof("cpu")]; phandle_t child; u_int cpuid; + uint32_t cpu_impl; /* There's no need to traverse the whole OFW tree twice. */ if (mp_maxid > 0 && mp_ncpus >= mp_maxid + 1) @@ -191,12 +193,17 @@ foreach_ap(phandle_t node, void (*func)(phandle_t node, u_int mid)) continue; if (strcmp(type, "cpu") != 0) continue; - if (OF_getprop(node, cpu_cpuid_prop(), &cpuid, - sizeof(cpuid)) <= 0) - panic("%s: can't get module ID", __func__); + if (OF_getprop(node, "implementation#", &cpu_impl, + sizeof(cpu_impl)) <= 0) + panic("%s: couldn't determine CPU " + "implementation", __func__); + if (OF_getprop(node, cpu_cpuid_prop(cpu_impl), &cpuid, + sizeof(cpuid)) <= 0) + panic("%s: couldn't determine CPU module ID", + __func__); if (cpuid == PCPU_GET(mid)) continue; - (*func)(node, cpuid); + (*func)(node, cpuid, cpu_impl); } } } @@ -216,7 +223,7 @@ cpu_mp_setmaxid() } static void -ap_count(phandle_t node __unused, u_int mid __unused) +ap_count(phandle_t node __unused, u_int mid __unused, u_int cpu_impl __unused) { mp_maxid++; @@ -283,20 +290,20 @@ cpu_mp_start(void) } static void -ap_start(phandle_t node, u_int mid) +ap_start(phandle_t node, u_int mid, u_int cpu_impl) { volatile struct cpu_start_args *csa; struct pcpu *pc; register_t s; vm_offset_t va; - u_int clock; u_int cpuid; + uint32_t clock; if (mp_ncpus > MAXCPU) return; if (OF_getprop(node, "clock-frequency", &clock, sizeof(clock)) <= 0) - panic("%s: can't get clock", __func__); + panic("%s: couldn't determine CPU frequency", __func__); if (clock != PCPU_GET(clock)) hardclock_use_stick = 1; @@ -329,6 +336,7 @@ ap_start(phandle_t node, u_int mid) dpcpu_init((void *)kmem_alloc(kernel_map, DPCPU_SIZE), cpuid); pc->pc_addr = va; pc->pc_clock = clock; + pc->pc_impl = cpu_impl; pc->pc_mid = mid; pc->pc_node = node; @@ -401,9 +409,9 @@ cpu_mp_bootstrap(struct pcpu *pc) volatile struct cpu_start_args *csa; csa = &cpu_start_args; - if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) - cheetah_init(); - cache_enable(); + if (pc->pc_impl >= CPU_IMPL_ULTRASPARCIII) + cheetah_init(pc->pc_impl); + cache_enable(pc->pc_impl); pmap_map_tsb(); /* * Flush all non-locked TLB entries possibly left over by the diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c index 6a88fa6872e..ee01aa86ae0 100644 --- a/sys/sparc64/sparc64/nexus.c +++ b/sys/sparc64/sparc64/nexus.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -522,7 +523,7 @@ nexus_setup_dinfo(device_t dev, phandle_t node) nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intr), (void **)&intr); if (nintr > 0) { - if (OF_getprop(node, cpu_impl < CPU_IMPL_ULTRASPARCIII ? + if (OF_getprop(node, PCPU_GET(impl) < CPU_IMPL_ULTRASPARCIII ? "upa-portid" : "portid", &ign, sizeof(ign)) <= 0) { device_printf(dev, "<%s>: could not determine portid\n", ndi->ndi_obdinfo.obd_name); diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index ee1204d7f0d..5ebc6ff3129 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -278,7 +278,7 @@ om_cmp(const void *a, const void *b) * Bootstrap the system enough to run with virtual memory. */ void -pmap_bootstrap(void) +pmap_bootstrap(u_int cpu_impl) { struct pmap *pm; struct tte *tp; @@ -1543,7 +1543,7 @@ pmap_copy_tte(pmap_t src_pmap, pmap_t dst_pmap, struct tte *tp, void pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, - vm_size_t len, vm_offset_t src_addr) + vm_size_t len, vm_offset_t src_addr) { struct tte *tp; vm_offset_t va; @@ -1998,6 +1998,7 @@ pmap_activate(struct thread *td) void pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz) { + } /* diff --git a/sys/sparc64/sparc64/spitfire.c b/sys/sparc64/sparc64/spitfire.c index 5a8c4eca070..d6e25b970b7 100644 --- a/sys/sparc64/sparc64/spitfire.c +++ b/sys/sparc64/sparc64/spitfire.c @@ -56,7 +56,7 @@ PMAP_STATS_VAR(spitfire_icache_npage_inval_match); * Enable the level 1 caches. */ void -spitfire_cache_enable(void) +spitfire_cache_enable(u_int cpu_impl __unused) { u_long lsu; diff --git a/sys/sparc64/sparc64/tick.c b/sys/sparc64/sparc64/tick.c index 97472286168..1a38013e884 100644 --- a/sys/sparc64/sparc64/tick.c +++ b/sys/sparc64/sparc64/tick.c @@ -120,7 +120,7 @@ cpu_initclocks(void) */ } else { clock = PCPU_GET(clock); - intr_setup(PIL_TICK, cpu_impl < CPU_IMPL_ULTRASPARCIII ? + intr_setup(PIL_TICK, PCPU_GET(impl) < CPU_IMPL_ULTRASPARCIII ? tick_hardclock_bbwar : tick_hardclock, -1, NULL, NULL); set_cputicker(tick_cputicks, clock, 0); } @@ -322,7 +322,7 @@ tick_start(void) } void -tick_clear(void) +tick_clear(u_int cpu_impl) { if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) @@ -331,7 +331,7 @@ tick_clear(void) } void -tick_stop(void) +tick_stop(u_int cpu_impl) { if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c index 30a40f013b9..e8650385708 100644 --- a/sys/sparc64/sparc64/trap.c +++ b/sys/sparc64/sparc64/trap.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -391,7 +392,7 @@ trap(struct trapframe *tf) if (tf->tf_tpc > (u_long)fas_nofault_begin && tf->tf_tpc < (u_long)fas_nofault_end) { cache_flush(); - cache_enable(); + cache_enable(PCPU_GET(impl)); tf->tf_tpc = (u_long)fas_fault; tf->tf_tnpc = tf->tf_tpc + 4; error = 0; From 94118d287110ad8bed853a94a5481c3685fab7a0 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Wed, 31 Mar 2010 21:41:00 +0000 Subject: [PATCH 1794/2592] MFC: r204153 Starting with UltraSPARC IV CPUs the CPU caches are described with different OFW properties. --- sys/sparc64/sparc64/cache.c | 56 ++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/sys/sparc64/sparc64/cache.c b/sys/sparc64/sparc64/cache.c index d558bf21024..8cb8dee8a20 100644 --- a/sys/sparc64/sparc64/cache.c +++ b/sys/sparc64/sparc64/cache.c @@ -43,6 +43,7 @@ */ /*- * Copyright (c) 2001 by Thomas Moestl . + * Copyright (c) 2008, 2010 Marius Strobl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,32 +90,49 @@ icache_page_inval_t *icache_page_inval; #define OF_GET(h, n, v) OF_getprop((h), (n), &(v), sizeof(v)) +static u_int cache_new_prop(u_int cpu_impl); + +static u_int +cache_new_prop(u_int cpu_impl) +{ + + switch (cpu_impl) { + case CPU_IMPL_ULTRASPARCIV: + case CPU_IMPL_ULTRASPARCIVp: + return (1); + default: + return (0); + } +} + /* - * Fill in the cache parameters using the cpu node. + * Fill in the cache parameters using the CPU node. */ void cache_init(struct pcpu *pcpu) { u_long set; + u_int use_new_prop; - if (OF_GET(pcpu->pc_node, "icache-size", - pcpu->pc_cache.ic_size) == -1 || - OF_GET(pcpu->pc_node, "icache-line-size", - pcpu->pc_cache.ic_linesize) == -1 || - OF_GET(pcpu->pc_node, "icache-associativity", - pcpu->pc_cache.ic_assoc) == -1 || - OF_GET(pcpu->pc_node, "dcache-size", - pcpu->pc_cache.dc_size) == -1 || - OF_GET(pcpu->pc_node, "dcache-line-size", - pcpu->pc_cache.dc_linesize) == -1 || - OF_GET(pcpu->pc_node, "dcache-associativity", - pcpu->pc_cache.dc_assoc) == -1 || - OF_GET(pcpu->pc_node, "ecache-size", - pcpu->pc_cache.ec_size) == -1 || - OF_GET(pcpu->pc_node, "ecache-line-size", - pcpu->pc_cache.ec_linesize) == -1 || - OF_GET(pcpu->pc_node, "ecache-associativity", - pcpu->pc_cache.ec_assoc) == -1) + use_new_prop = cache_new_prop(pcpu->pc_impl); + if (OF_GET(pcpu->pc_node, !use_new_prop ? "icache-size" : + "l1-icache-size", pcpu->pc_cache.ic_size) == -1 || + OF_GET(pcpu->pc_node, !use_new_prop ? "icache-line-size" : + "l1-icache-line-size", pcpu->pc_cache.ic_linesize) == -1 || + OF_GET(pcpu->pc_node, !use_new_prop ? "icache-associativity" : + "l1-icache-associativity", pcpu->pc_cache.ic_assoc) == -1 || + OF_GET(pcpu->pc_node, !use_new_prop ? "dcache-size" : + "l1-dcache-size", pcpu->pc_cache.dc_size) == -1 || + OF_GET(pcpu->pc_node, !use_new_prop ? "dcache-line-size" : + "l1-dcache-line-size", pcpu->pc_cache.dc_linesize) == -1 || + OF_GET(pcpu->pc_node, !use_new_prop ? "dcache-associativity" : + "l1-dcache-associativity", pcpu->pc_cache.dc_assoc) == -1 || + OF_GET(pcpu->pc_node, !use_new_prop ? "ecache-size" : + "l2-cache-size", pcpu->pc_cache.ec_size) == -1 || + OF_GET(pcpu->pc_node, !use_new_prop ? "ecache-line-size" : + "l2-cache-line-size", pcpu->pc_cache.ec_linesize) == -1 || + OF_GET(pcpu->pc_node, !use_new_prop ? "ecache-associativity" : + "l2-cache-associativity", pcpu->pc_cache.ec_assoc) == -1) panic("cache_init: could not retrieve cache parameters"); set = pcpu->pc_cache.ic_size / pcpu->pc_cache.ic_assoc; From c65c70f0f4fec6a7911c8a57b7ee818f2698381c Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Wed, 31 Mar 2010 21:57:48 +0000 Subject: [PATCH 1795/2592] MFC: r205258 - Add TTE and context register bits for the additional page sizes supported by UltraSparc-IV and -IV+ as well as SPARC64 V, VI, VII and VIIIfx CPUs. - Replace TLB_PCXR_PGSZ_MASK and TLB_SCXR_PGSZ_MASK with TLB_CXR_PGSZ_MASK which just is the complement of TLB_CXR_CTX_MASK instead of trying to assemble it from the page size bits which vary across CPUs. - Add macros for the remainder of the SFSR bits, which are useful for at least debugging purposes. --- sys/sparc64/include/tlb.h | 38 +++++++++++++------- sys/sparc64/include/tte.h | 63 +++++++++++++++++++++++++--------- sys/sparc64/sparc64/genassym.c | 2 +- sys/sparc64/sparc64/pmap.c | 4 +-- sys/sparc64/sparc64/swtch.S | 2 +- 5 files changed, 75 insertions(+), 34 deletions(-) diff --git a/sys/sparc64/include/tlb.h b/sys/sparc64/include/tlb.h index f0a4a7bc42d..b813b0fe28f 100644 --- a/sys/sparc64/include/tlb.h +++ b/sys/sparc64/include/tlb.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2001 Jake Burkholder. + * Copyright (c) 2008, 2010 Marius Strobl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,11 +36,11 @@ #define TLB_DIRECT_ADDRESS_MASK ((1UL << TLB_DIRECT_ADDRESS_BITS) - 1) #define TLB_DIRECT_PAGE_MASK ((1UL << TLB_DIRECT_PAGE_BITS) - 1) -#define TLB_PHYS_TO_DIRECT(pa) \ +#define TLB_PHYS_TO_DIRECT(pa) \ ((pa) | VM_MIN_DIRECT_ADDRESS) -#define TLB_DIRECT_TO_PHYS(va) \ +#define TLB_DIRECT_TO_PHYS(va) \ ((va) & TLB_DIRECT_ADDRESS_MASK) -#define TLB_DIRECT_TO_TTE_MASK \ +#define TLB_DIRECT_TO_TTE_MASK \ (TD_V | TD_4M | (TLB_DIRECT_ADDRESS_MASK - TLB_DIRECT_PAGE_MASK)) #define TLB_DAR_SLOT_SHIFT (3) @@ -56,18 +57,21 @@ (((1UL << TLB_CXR_CTX_BITS) - 1) << TLB_CXR_CTX_SHIFT) #define TLB_CXR_CTX_SHIFT (0) #define TLB_CXR_PGSZ_BITS (3) -#define TLB_PCXR_PGSZ_MASK \ - ((((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_N_PGSZ0_SHIFT) | \ - (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_N_PGSZ1_SHIFT) | \ - (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_P_PGSZ0_SHIFT) | \ - (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_P_PGSZ1_SHIFT)) +#define TLB_CXR_PGSZ_MASK (~TLB_CXR_CTX_MASK) +#define TLB_PCXR_N_IPGSZ0_SHIFT (53) /* SPARC64 VI, VII, VIIIfx */ +#define TLB_PCXR_N_IPGSZ1_SHIFT (50) /* SPARC64 VI, VII, VIIIfx */ #define TLB_PCXR_N_PGSZ0_SHIFT (61) #define TLB_PCXR_N_PGSZ1_SHIFT (58) +#define TLB_PCXR_N_PGSZ_I_SHIFT (55) /* US-IV+ */ +#define TLB_PCXR_P_IPGSZ0_SHIFT (24) /* SPARC64 VI, VII, VIIIfx */ +#define TLB_PCXR_P_IPGSZ1_SHIFT (27) /* SPARC64 VI, VII, VIIIfx */ #define TLB_PCXR_P_PGSZ0_SHIFT (16) #define TLB_PCXR_P_PGSZ1_SHIFT (19) -#define TLB_SCXR_PGSZ_MASK \ - ((((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_SCXR_S_PGSZ0_SHIFT) | \ - (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_SCXR_S_PGSZ1_SHIFT)) +/* + * Note that the US-IV+ documentation appears to have TLB_PCXR_P_PGSZ_I_SHIFT + * and TLB_PCXR_P_PGSZ0_SHIFT erroneously inverted. + */ +#define TLB_PCXR_P_PGSZ_I_SHIFT (22) /* US-IV+ */ #define TLB_SCXR_S_PGSZ1_SHIFT (19) #define TLB_SCXR_S_PGSZ0_SHIFT (16) @@ -87,7 +91,7 @@ #define TLB_DEMAP_TYPE_SHIFT (6) #define TLB_DEMAP_TYPE_PAGE (0) #define TLB_DEMAP_TYPE_CONTEXT (1) -#define TLB_DEMAP_TYPE_ALL (2) /* USIII and beyond only */ +#define TLB_DEMAP_TYPE_ALL (2) /* US-III and beyond only */ #define TLB_DEMAP_VA(va) ((va) & ~PAGE_MASK) #define TLB_DEMAP_ID(id) ((id) << TLB_DEMAP_ID_SHIFT) @@ -118,9 +122,17 @@ #define MMU_SFSR_FT_SIZE (6) #define MMU_SFSR_CT_SIZE (2) -#define MMU_SFSR_GET_ASI(sfsr) \ +#define MMU_SFSR_GET_ASI(sfsr) \ (((sfsr) >> MMU_SFSR_ASI_SHIFT) & ((1UL << MMU_SFSR_ASI_SIZE) - 1)) +#define MMU_SFSR_GET_FT(sfsr) \ + (((sfsr) >> MMU_SFSR_FT_SHIFT) & ((1UL << MMU_SFSR_FT_SIZE) - 1)) +#define MMU_SFSR_GET_CT(sfsr) \ + (((sfsr) >> MMU_SFSR_CT_SHIFT) & ((1UL << MMU_SFSR_CT_SIZE) - 1)) + +#define MMU_SFSR_E (1UL << MMU_SFSR_E_SHIFT) +#define MMU_SFSR_PR (1UL << MMU_SFSR_PR_SHIFT) #define MMU_SFSR_W (1UL << MMU_SFSR_W_SHIFT) +#define MMU_SFSR_OW (1UL << MMU_SFSR_OW_SHIFT) #define MMU_SFSR_FV (1UL << MMU_SFSR_FV_SHIFT) typedef void tlb_flush_nonlocked_t(void); diff --git a/sys/sparc64/include/tte.h b/sys/sparc64/include/tte.h index 421bc169e10..ff60342c741 100644 --- a/sys/sparc64/include/tte.h +++ b/sys/sparc64/include/tte.h @@ -36,25 +36,42 @@ #define TD_SIZE_SHIFT (61) #define TD_SOFT2_SHIFT (50) +#define TD_RSVD2_SHIFT (49) +#define TD_SIZE2_SHIFT (48) #define TD_DIAG_SF_SHIFT (41) #define TD_RSVD_CH_SHIFT (43) +#define TD_RSVD_OC_SHIFT (47) +#define TD_RSVD_PT_SHIFT TD_RSVD_CH_SHIFT +#define TD_RSVD_VE_SHIFT (41) #define TD_PA_SHIFT (13) #define TD_SOFT_SHIFT (7) #define TD_SIZE_BITS (2) #define TD_SOFT2_BITS (9) -#define TD_DIAG_SF_BITS (9) -#define TD_RSVD_CH_BITS (7) -#define TD_PA_CH_BITS (30) -#define TD_PA_SF_BITS (28) +#define TD_RSVD2_BITS (1) /* US-IV+, SPARC64 VI, VII, VIIIfx */ +#define TD_SIZE2_BITS (1) /* US-IV+, SPARC64 VI, VII, VIIIfx */ +#define TD_DIAG_SF_BITS (9) /* US-I, II{,e,i} */ +#define TD_RSVD_CH_BITS (7) /* US-III{,i,+}, US-IV, SPARC64 V */ +#define TD_RSVD_OC_BITS (1) /* SPARC64 VI, VII */ +#define TD_RSVD_PT_BITS (5) /* US-IV+, SPARC64 VI, VII */ +#define TD_RSVD_VE_BITS (7) /* SPARC64 VIIIfx */ +#define TD_PA_CH_BITS (30) /* US-III{,i,+}, US-IV{,+}, SPARC64 V */ +#define TD_PA_OC_BITS (34) /* SPARC64 VI, VII */ +#define TD_PA_SF_BITS (28) /* US-I, II{,e,i}, SPARC64 VIIIfx */ #define TD_PA_BITS TD_PA_CH_BITS #define TD_SOFT_BITS (6) #define TD_SIZE_MASK ((1UL << TD_SIZE_BITS) - 1) #define TD_SOFT2_MASK ((1UL << TD_SOFT2_BITS) - 1) +#define TD_RSVD2_MASK ((1UL << TD_RSVD2_BITS) - 1) +#define TD_SIZE2_MASK ((1UL << TD_SIZE2_BITS) - 1) #define TD_DIAG_SF_MASK ((1UL << TD_DIAG_SF_BITS) - 1) #define TD_RSVD_CH_MASK ((1UL << TD_RSVD_CH_BITS) - 1) +#define TD_RSVD_OC_MASK ((1UL << TD_RSVD_OC_BITS) - 1) +#define TD_RSVD_PT_MASK ((1UL << TD_RSVD_PT_BITS) - 1) +#define TD_RSVD_VE_MASK ((1UL << TD_RSVD_VE_BITS) - 1) #define TD_PA_CH_MASK ((1UL << TD_PA_CH_BITS) - 1) +#define TD_PA_OC_MASK ((1UL << TD_PA_OC_BITS) - 1) #define TD_PA_SF_MASK ((1UL << TD_PA_SF_BITS) - 1) #define TD_PA_MASK ((1UL << TD_PA_BITS) - 1) #define TD_SOFT_MASK ((1UL << TD_SOFT_BITS) - 1) @@ -63,6 +80,9 @@ #define TS_64K (1UL) #define TS_512K (2UL) #define TS_4M (3UL) +#define TS_32M (4UL) /* US-IV+, SPARC64 VI, VII only */ +#define TS_256M (5UL) /* US-IV+, SPARC64 VI, VII only */ +#define TS_2G (6UL) /* SPARC64 VIIIfx only */ #define TS_MIN TS_8K #define TS_MAX TS_4M @@ -72,6 +92,15 @@ #define TD_64K (TS_64K << TD_SIZE_SHIFT) #define TD_512K (TS_512K << TD_SIZE_SHIFT) #define TD_4M (TS_4M << TD_SIZE_SHIFT) +#define TD_32M \ + (((TS_32M & TD_SIZE_MASK) << TD_SIZE_SHIFT) | \ + (TD_SIZE2_MASK << TD_SIZE2_SHIFT)) +#define TD_256M \ + (((TS_256M & TD_SIZE_MASK) << TD_SIZE_SHIFT) | \ + (TD_SIZE2_MASK << TD_SIZE2_SHIFT)) +#define TD_2G \ + (((TS_2G & TD_SIZE_MASK) << TD_SIZE_SHIFT) | \ + (TD_SIZE2_MASK << TD_SIZE2_SHIFT)) #define TD_NFO (1UL << 60) #define TD_IE (1UL << 59) #define TD_PA(pa) ((pa) & (TD_PA_MASK << TD_PA_SHIFT)) @@ -94,29 +123,28 @@ #define TV_VPN(va, sz) ((((va) >> TTE_PAGE_SHIFT(sz)) << TV_SIZE_BITS) | sz) #define TTE_SIZE_SPREAD (3) -#define TTE_PAGE_SHIFT(sz) \ +#define TTE_PAGE_SHIFT(sz) \ (PAGE_SHIFT + ((sz) * TTE_SIZE_SPREAD)) -#define TTE_GET_SIZE(tp) \ +#define TTE_GET_SIZE(tp) \ (((tp)->tte_data >> TD_SIZE_SHIFT) & TD_SIZE_MASK) -#define TTE_GET_PAGE_SHIFT(tp) \ +#define TTE_GET_PAGE_SHIFT(tp) \ TTE_PAGE_SHIFT(TTE_GET_SIZE(tp)) -#define TTE_GET_PAGE_SIZE(tp) \ +#define TTE_GET_PAGE_SIZE(tp) \ (1 << TTE_GET_PAGE_SHIFT(tp)) -#define TTE_GET_PAGE_MASK(tp) \ +#define TTE_GET_PAGE_MASK(tp) \ (TTE_GET_PAGE_SIZE(tp) - 1) -#define TTE_GET_PA(tp) \ +#define TTE_GET_PA(tp) \ ((tp)->tte_data & (TD_PA_MASK << TD_PA_SHIFT)) -#define TTE_GET_VPN(tp) \ +#define TTE_GET_VPN(tp) \ ((tp)->tte_vpn >> TV_SIZE_BITS) -#define TTE_GET_VA(tp) \ +#define TTE_GET_VA(tp) \ (TTE_GET_VPN(tp) << TTE_GET_PAGE_SHIFT(tp)) -#define TTE_GET_PMAP(tp) \ - (((tp)->tte_data & TD_P) != 0 ? \ - (kernel_pmap) : \ - (PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)(tp)))->md.pmap)) -#define TTE_ZERO(tp) \ +#define TTE_GET_PMAP(tp) \ + (((tp)->tte_data & TD_P) != 0 ? (kernel_pmap) : \ + (PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)(tp)))->md.pmap)) +#define TTE_ZERO(tp) \ memset(tp, 0, sizeof(*tp)) struct pmap; @@ -130,6 +158,7 @@ struct tte { static __inline int tte_match(struct tte *tp, vm_offset_t va) { + return (((tp->tte_data & TD_V) != 0) && (tp->tte_vpn == TV_VPN(va, TTE_GET_SIZE(tp)))); } diff --git a/sys/sparc64/sparc64/genassym.c b/sys/sparc64/sparc64/genassym.c index 9efaa74883c..f8cd6a2fb3f 100644 --- a/sys/sparc64/sparc64/genassym.c +++ b/sys/sparc64/sparc64/genassym.c @@ -139,7 +139,7 @@ ASSYM(TD_W, TD_W); ASSYM(TS_MIN, TS_MIN); ASSYM(TS_MAX, TS_MAX); ASSYM(TLB_DAR_SLOT_SHIFT, TLB_DAR_SLOT_SHIFT); -ASSYM(TLB_PCXR_PGSZ_MASK, TLB_PCXR_PGSZ_MASK); +ASSYM(TLB_CXR_PGSZ_MASK, TLB_CXR_PGSZ_MASK); ASSYM(TLB_DIRECT_TO_TTE_MASK, TLB_DIRECT_TO_TTE_MASK); ASSYM(TV_SIZE_BITS, TV_SIZE_BITS); #endif diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index 5ebc6ff3129..a1f4da024ad 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -572,7 +572,7 @@ pmap_map_tsb(void) * FP block operations in the kernel). */ stxa(AA_DMMU_SCXR, ASI_DMMU, (ldxa(AA_DMMU_SCXR, ASI_DMMU) & - TLB_SCXR_PGSZ_MASK) | TLB_CTX_KERNEL); + TLB_CXR_PGSZ_MASK) | TLB_CTX_KERNEL); flush(KERNBASE); intr_restore(s); @@ -1989,7 +1989,7 @@ pmap_activate(struct thread *td) stxa(AA_DMMU_TSB, ASI_DMMU, pm->pm_tsb); stxa(AA_IMMU_TSB, ASI_IMMU, pm->pm_tsb); stxa(AA_DMMU_PCXR, ASI_DMMU, (ldxa(AA_DMMU_PCXR, ASI_DMMU) & - TLB_PCXR_PGSZ_MASK) | context); + TLB_CXR_PGSZ_MASK) | context); flush(KERNBASE); mtx_unlock_spin(&sched_lock); diff --git a/sys/sparc64/sparc64/swtch.S b/sys/sparc64/sparc64/swtch.S index af0531627aa..ea13779c46e 100644 --- a/sys/sparc64/sparc64/swtch.S +++ b/sys/sparc64/sparc64/swtch.S @@ -237,7 +237,7 @@ ENTRY(cpu_switch) stxa %i4, [%i5] ASI_DMMU mov AA_IMMU_TSB, %i5 stxa %i4, [%i5] ASI_IMMU - setx TLB_PCXR_PGSZ_MASK, %i5, %i4 + setx TLB_CXR_PGSZ_MASK, %i5, %i4 mov AA_DMMU_PCXR, %i5 ldxa [%i5] ASI_DMMU, %l1 and %l1, %i4, %l1 From 265f3f76423d0d150d3ccedba29d8c31bea48155 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Wed, 31 Mar 2010 22:00:22 +0000 Subject: [PATCH 1796/2592] MFC: r205263 Add macros for the VER.impl of SPARC64 II to VIIIfx. --- sys/sparc64/include/ver.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/sparc64/include/ver.h b/sys/sparc64/include/ver.h index ad6841bd9ad..19547ba9fb4 100644 --- a/sys/sparc64/include/ver.h +++ b/sys/sparc64/include/ver.h @@ -69,8 +69,15 @@ extern char sparc64_model[]; #endif /* !LOCORE */ -/* Known implementations. */ +/* Known implementations */ #define CPU_IMPL_SPARC64 0x01 +#define CPU_IMPL_SPARC64II 0x02 +#define CPU_IMPL_SPARC64III 0x03 +#define CPU_IMPL_SPARC64IV 0x04 +#define CPU_IMPL_SPARC64V 0x05 +#define CPU_IMPL_SPARC64VI 0x06 +#define CPU_IMPL_SPARC64VII 0x07 +#define CPU_IMPL_SPARC64VIIIfx 0x08 #define CPU_IMPL_ULTRASPARCI 0x10 #define CPU_IMPL_ULTRASPARCII 0x11 #define CPU_IMPL_ULTRASPARCIIi 0x12 From 39c9b5507ee505c8953965e0e5c77fb6ba2729d5 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Wed, 31 Mar 2010 22:05:49 +0000 Subject: [PATCH 1797/2592] MFC: r205399 Improve the KVA space sizing of r186682; on machines with large dTLBs we can actually use all of the available lockable entries of the tiny dTLB for the kernel TSB. With this change the KVA space sizing happens to be more in line with the MI one so up to at least 24GB machines KVA doesn't need to be limited manually. This is just another stopgap though, the real solution is to take advantage of ASI_ATOMIC_QUAD_LDD_PHYS on CPUs providing it so we don't need to lock the kernel TSB pages into the dTLB in the first place. --- sys/sparc64/sparc64/pmap.c | 44 +++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index a1f4da024ad..e46455915c2 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -236,6 +236,8 @@ PMAP_STATS_VAR(pmap_ncopy_page_soc); PMAP_STATS_VAR(pmap_nnew_thread); PMAP_STATS_VAR(pmap_nnew_thread_oc); +static inline u_long dtlb_get_data(u_int slot); + /* * Quick sort callout for comparing memory regions */ @@ -274,6 +276,18 @@ om_cmp(const void *a, const void *b) return (0); } +static inline u_long +dtlb_get_data(u_int slot) +{ + + /* + * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work + * around errata of USIII and beyond. + */ + (void)ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG); + return (ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG)); +} + /* * Bootstrap the system enough to run with virtual memory. */ @@ -287,11 +301,13 @@ pmap_bootstrap(u_int cpu_impl) vm_paddr_t pa; vm_size_t physsz; vm_size_t virtsz; + u_long data; phandle_t pmem; phandle_t vmem; - int sz; + u_int dtlb_slots_avail; int i; int j; + int sz; /* * Find out what physical memory is available from the PROM and @@ -336,22 +352,30 @@ pmap_bootstrap(u_int cpu_impl) /* * Calculate the size of kernel virtual memory, and the size and mask * for the kernel TSB based on the phsyical memory size but limited - * by letting the kernel TSB take up no more than half of the dTLB - * slots available for locked entries. + * by the amount of dTLB slots available for locked entries (given + * that for spitfire-class CPUs all of the dt64 slots can hold locked + * entries but there is no large dTLB for unlocked ones, we don't use + * more than half of it for locked entries). */ + dtlb_slots_avail = 0; + for (i = 0; i < dtlb_slots; i++) { + data = dtlb_get_data(i); + if ((data & (TD_V | TD_L)) != (TD_V | TD_L)) + dtlb_slots_avail++; + } +#ifdef SMP + dtlb_slots_avail -= PCPU_PAGES; +#endif + if (cpu_impl >= CPU_IMPL_ULTRASPARCI && + cpu_impl < CPU_IMPL_ULTRASPARCIII) + dtlb_slots_avail /= 2; virtsz = roundup(physsz, PAGE_SIZE_4M << (PAGE_SHIFT - TTE_SHIFT)); virtsz = MIN(virtsz, - (dtlb_slots / 2 * PAGE_SIZE_4M) << (PAGE_SHIFT - TTE_SHIFT)); + (dtlb_slots_avail * PAGE_SIZE_4M) << (PAGE_SHIFT - TTE_SHIFT)); vm_max_kernel_address = VM_MIN_KERNEL_ADDRESS + virtsz; tsb_kernel_size = virtsz >> (PAGE_SHIFT - TTE_SHIFT); tsb_kernel_mask = (tsb_kernel_size >> TTE_SHIFT) - 1; - if (kernel_tlb_slots + PCPU_PAGES + tsb_kernel_size / PAGE_SIZE_4M + - 1 /* PROM page */ + 1 /* spare */ > dtlb_slots) - panic("pmap_bootstrap: insufficient dTLB entries"); - if (kernel_tlb_slots + 1 /* PROM page */ + 1 /* spare */ > itlb_slots) - panic("pmap_bootstrap: insufficient iTLB entries"); - /* * Allocate the kernel TSB and lock it in the TLB. */ From e952596a10a17d33ddaf86c916bcc3b1c08da597 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 1 Apr 2010 00:36:40 +0000 Subject: [PATCH 1798/2592] MFC 205066, 205069, 205093, 205097, 205488: r205066: Log: - restructure flowtable to support ipv6 - add a name argument to flowtable_alloc for printing with ddb commands - extend ddb commands to print destination address or 4-tuples - don't parse ports in ulp header if FL_HASH_ALL is not passed - add kern_flowtable_insert to enable more generic use of flowtable (e.g. system calls for adding entries) - don't hash loopback addresses - cleanup whitespace - keep statistics per-cpu for per-cpu flowtables to avoid cache line contention - add sysctls to accumulate stats and report aggregate r205069: Log: fix stats reporting sysctl r205093: Log: re-update copyright to 2010 pointed out by danfe@ r205097: Log: flowtable_get_hashkey is only used by a DDB function - move under #ifdef DDB pointed out by jkim@ r205488: Log: - boot-time size the ipv4 flowtable and the maximum number of flows - increase flow cleaning frequency and decrease flow caching time when near the flow limit - stop allocating new flows when within 3% of maxflows don't start allocating again until below 12.5% --- sys/net/flowtable.c | 969 ++++++++++++++++++++++++++++++++-------- sys/net/flowtable.h | 35 +- sys/net/if_llatbl.c | 4 +- sys/net/if_llatbl.h | 2 +- sys/netinet/ip_input.c | 18 +- sys/netinet/ip_output.c | 22 +- 6 files changed, 855 insertions(+), 195 deletions(-) diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index ab42e685d5f..cbdb8e584ca 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -1,6 +1,6 @@ /************************************************************************** -Copyright (c) 2008-2009, BitGravity Inc. +Copyright (c) 2008-2010, BitGravity Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,6 +30,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "opt_route.h" #include "opt_mpath.h" #include "opt_ddb.h" +#include "opt_inet.h" +#include "opt_inet6.h" #include __FBSDID("$FreeBSD$"); @@ -45,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -63,6 +66,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef INET6 +#include +#endif #include #include #include @@ -140,31 +146,42 @@ union flentryp { struct flentry **pcpu[MAXCPU]; }; +struct flowtable_stats { + uint64_t ft_collisions; + uint64_t ft_allocated; + uint64_t ft_misses; + uint64_t ft_max_depth; + uint64_t ft_free_checks; + uint64_t ft_frees; + uint64_t ft_hits; + uint64_t ft_lookups; +} __aligned(CACHE_LINE_SIZE); + struct flowtable { + struct flowtable_stats ft_stats[MAXCPU]; int ft_size; int ft_lock_count; uint32_t ft_flags; - uint32_t ft_collisions; - uint32_t ft_allocated; - uint32_t ft_misses; - uint64_t ft_hits; - - uint32_t ft_udp_idle; - uint32_t ft_fin_wait_idle; - uint32_t ft_syn_idle; - uint32_t ft_tcp_idle; - + char *ft_name; fl_lock_t *ft_lock; fl_lock_t *ft_unlock; fl_rtalloc_t *ft_rtalloc; + /* + * XXX need to pad out + */ struct mtx *ft_locks; - - union flentryp ft_table; bitstr_t *ft_masks[MAXCPU]; bitstr_t *ft_tmpmask; struct flowtable *ft_next; -}; + + uint32_t ft_count __aligned(CACHE_LINE_SIZE); + uint32_t ft_udp_idle __aligned(CACHE_LINE_SIZE); + uint32_t ft_fin_wait_idle; + uint32_t ft_syn_idle; + uint32_t ft_tcp_idle; + boolean_t ft_full; +} __aligned(CACHE_LINE_SIZE); static struct proc *flowcleanerproc; static VNET_DEFINE(struct flowtable *, flow_list_head); @@ -177,16 +194,30 @@ static VNET_DEFINE(uma_zone_t, flow_ipv6_zone); #define V_flow_ipv4_zone VNET(flow_ipv4_zone) #define V_flow_ipv6_zone VNET(flow_ipv6_zone) + static struct cv flowclean_cv; static struct mtx flowclean_lock; static uint32_t flowclean_cycles; +static uint32_t flowclean_freq; + +#ifdef FLOWTABLE_DEBUG +#define FLDPRINTF(ft, flags, fmt, ...) \ +do { \ + if ((ft)->ft_flags & (flags)) \ + printf((fmt), __VA_ARGS__); \ +} while (0); \ + +#else +#define FLDPRINTF(ft, flags, fmt, ...) + +#endif + /* * TODO: * - Make flowtable stats per-cpu, aggregated at sysctl call time, * to avoid extra cache evictions caused by incrementing a shared * counter - * - add IPv6 support to flow lookup * - add sysctls to resize && flush flow tables * - Add per flowtable sysctls for statistics and configuring timeouts * - add saturation counter to rtentry to support per-packet load-balancing @@ -200,29 +231,15 @@ static uint32_t flowclean_cycles; */ VNET_DEFINE(int, flowtable_enable) = 1; static VNET_DEFINE(int, flowtable_debug); -static VNET_DEFINE(int, flowtable_hits); -static VNET_DEFINE(int, flowtable_lookups); -static VNET_DEFINE(int, flowtable_misses); -static VNET_DEFINE(int, flowtable_frees); -static VNET_DEFINE(int, flowtable_free_checks); -static VNET_DEFINE(int, flowtable_max_depth); -static VNET_DEFINE(int, flowtable_collisions); static VNET_DEFINE(int, flowtable_syn_expire) = SYN_IDLE; static VNET_DEFINE(int, flowtable_udp_expire) = UDP_IDLE; static VNET_DEFINE(int, flowtable_fin_wait_expire) = FIN_WAIT_IDLE; static VNET_DEFINE(int, flowtable_tcp_expire) = TCP_IDLE; -static VNET_DEFINE(int, flowtable_nmbflows) = 4096; +static VNET_DEFINE(int, flowtable_nmbflows); static VNET_DEFINE(int, flowtable_ready) = 0; #define V_flowtable_enable VNET(flowtable_enable) #define V_flowtable_debug VNET(flowtable_debug) -#define V_flowtable_hits VNET(flowtable_hits) -#define V_flowtable_lookups VNET(flowtable_lookups) -#define V_flowtable_misses VNET(flowtable_misses) -#define V_flowtable_frees VNET(flowtable_frees) -#define V_flowtable_free_checks VNET(flowtable_free_checks) -#define V_flowtable_max_depth VNET(flowtable_max_depth) -#define V_flowtable_collisions VNET(flowtable_collisions) #define V_flowtable_syn_expire VNET(flowtable_syn_expire) #define V_flowtable_udp_expire VNET(flowtable_udp_expire) #define V_flowtable_fin_wait_expire VNET(flowtable_fin_wait_expire) @@ -235,20 +252,6 @@ SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, debug, CTLFLAG_RW, &VNET_NAME(flowtable_debug), 0, "print debug info."); SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, enable, CTLFLAG_RW, &VNET_NAME(flowtable_enable), 0, "enable flowtable caching."); -SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, hits, CTLFLAG_RD, - &VNET_NAME(flowtable_hits), 0, "# flowtable hits."); -SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, lookups, CTLFLAG_RD, - &VNET_NAME(flowtable_lookups), 0, "# flowtable lookups."); -SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, misses, CTLFLAG_RD, - &VNET_NAME(flowtable_misses), 0, "#flowtable misses."); -SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, frees, CTLFLAG_RD, - &VNET_NAME(flowtable_frees), 0, "#flows freed."); -SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, free_checks, CTLFLAG_RD, - &VNET_NAME(flowtable_free_checks), 0, "#flows free checks."); -SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, max_depth, CTLFLAG_RD, - &VNET_NAME(flowtable_max_depth), 0, "max collision list length."); -SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, collisions, CTLFLAG_RD, - &VNET_NAME(flowtable_collisions), 0, "#flowtable collisions."); /* * XXX This does not end up updating timeouts at runtime @@ -298,6 +301,77 @@ SYSCTL_VNET_PROC(_net_inet_flowtable, OID_AUTO, nmbflows, CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_nmbflows, "IU", "Maximum number of flows allowed"); + + +#define FS_PRINT(sb, field) sbuf_printf((sb), "\t%s: %jd\n", #field, fs->ft_##field) + +static void +fs_print(struct sbuf *sb, struct flowtable_stats *fs) +{ + + FS_PRINT(sb, collisions); + FS_PRINT(sb, allocated); + FS_PRINT(sb, misses); + FS_PRINT(sb, max_depth); + FS_PRINT(sb, free_checks); + FS_PRINT(sb, frees); + FS_PRINT(sb, hits); + FS_PRINT(sb, lookups); +} + +static void +flowtable_show_stats(struct sbuf *sb, struct flowtable *ft) +{ + int i; + struct flowtable_stats fs, *pfs; + + if (ft->ft_flags & FL_PCPU) { + bzero(&fs, sizeof(fs)); + pfs = &fs; + for (i = 0; i <= mp_maxid; i++) { + if (CPU_ABSENT(i)) + continue; + pfs->ft_collisions += ft->ft_stats[i].ft_collisions; + pfs->ft_allocated += ft->ft_stats[i].ft_allocated; + pfs->ft_misses += ft->ft_stats[i].ft_misses; + pfs->ft_free_checks += ft->ft_stats[i].ft_free_checks; + pfs->ft_frees += ft->ft_stats[i].ft_frees; + pfs->ft_hits += ft->ft_stats[i].ft_hits; + pfs->ft_lookups += ft->ft_stats[i].ft_lookups; + if (ft->ft_stats[i].ft_max_depth > pfs->ft_max_depth) + pfs->ft_max_depth = ft->ft_stats[i].ft_max_depth; + } + } else { + pfs = &ft->ft_stats[0]; + } + fs_print(sb, pfs); +} + +static int +sysctl_flowtable_stats(SYSCTL_HANDLER_ARGS) +{ + struct flowtable *ft; + struct sbuf *sb; + int error; + + sb = sbuf_new(NULL, NULL, 64*1024, SBUF_FIXEDLEN); + + ft = V_flow_list_head; + while (ft != NULL) { + sbuf_printf(sb, "\ntable name: %s\n", ft->ft_name); + flowtable_show_stats(sb, ft); + ft = ft->ft_next; + } + sbuf_finish(sb); + error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); + sbuf_delete(sb); + + return (error); +} +SYSCTL_VNET_PROC(_net_inet_flowtable, OID_AUTO, stats, CTLTYPE_STRING|CTLFLAG_RD, + NULL, 0, sysctl_flowtable_stats, "A", "flowtable statistics"); + + #ifndef RADIX_MPATH static void in_rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fibnum) @@ -342,52 +416,122 @@ flowtable_pcpu_unlock(struct flowtable *table, uint32_t hash) #define FL_ENTRY_LOCK(table, hash) (table)->ft_lock((table), (hash)) #define FL_ENTRY_UNLOCK(table, hash) (table)->ft_unlock((table), (hash)) -#define FL_STALE (1<<8) -#define FL_IPV6 (1<<9) +#define FL_STALE (1<<8) +#define FL_IPV6 (1<<9) +#define FL_OVERWRITE (1<<10) -static uint32_t -ipv4_flow_lookup_hash_internal(struct mbuf *m, struct route *ro, - uint32_t *key, uint16_t *flags, uint8_t *protop) +void +flow_invalidate(struct flentry *fle) { - uint16_t sport = 0, dport = 0; - struct ip *ip = NULL; - uint8_t proto = 0; + + fle->f_flags |= FL_STALE; +} + +static __inline int +proto_to_flags(uint8_t proto) +{ + int flag; + + switch (proto) { + case IPPROTO_TCP: + flag = FL_TCP; + break; + case IPPROTO_SCTP: + flag = FL_SCTP; + break; + case IPPROTO_UDP: + flag = FL_UDP; + break; + default: + flag = 0; + break; + } + + return (flag); +} + +static __inline int +flags_to_proto(int flags) +{ + int proto, protoflags; + + protoflags = flags & (FL_TCP|FL_SCTP|FL_UDP); + switch (protoflags) { + case FL_TCP: + proto = IPPROTO_TCP; + break; + case FL_SCTP: + proto = IPPROTO_SCTP; + break; + case FL_UDP: + proto = IPPROTO_UDP; + break; + default: + proto = 0; + break; + } + return (proto); +} + +#ifdef INET +#ifdef FLOWTABLE_DEBUG +static void +ipv4_flow_print_tuple(int flags, int proto, struct sockaddr_in *ssin, + struct sockaddr_in *dsin) +{ + char saddr[4*sizeof "123"], daddr[4*sizeof "123"]; + + if (flags & FL_HASH_ALL) { + inet_ntoa_r(ssin->sin_addr, saddr); + inet_ntoa_r(dsin->sin_addr, daddr); + printf("proto=%d %s:%d->%s:%d\n", + proto, saddr, ntohs(ssin->sin_port), daddr, + ntohs(dsin->sin_port)); + } else { + inet_ntoa_r(*(struct in_addr *) &dsin->sin_addr, daddr); + printf("proto=%d %s\n", proto, daddr); + } + +} +#endif + +static int +ipv4_mbuf_demarshal(struct flowtable *ft, struct mbuf *m, + struct sockaddr_in *ssin, struct sockaddr_in *dsin, uint16_t *flags) +{ + struct ip *ip; + uint8_t proto; int iphlen; - uint32_t hash; - struct sockaddr_in *sin; struct tcphdr *th; struct udphdr *uh; struct sctphdr *sh; + uint16_t sport, dport; - if ((V_flowtable_enable == 0) || (V_flowtable_ready == 0)) - return (0); - - key[1] = key[0] = 0; - sin = (struct sockaddr_in *)&ro->ro_dst; - if (m != NULL) { - ip = mtod(m, struct ip *); - sin->sin_family = AF_INET; - sin->sin_len = sizeof(*sin); - sin->sin_addr = ip->ip_dst; - } else - *flags &= ~FL_HASH_PORTS; - - key[2] = sin->sin_addr.s_addr; - - if ((*flags & FL_HASH_PORTS) == 0) - goto skipports; + proto = sport = dport = 0; + ip = mtod(m, struct ip *); + dsin->sin_family = AF_INET; + dsin->sin_len = sizeof(*dsin); + dsin->sin_addr = ip->ip_dst; + ssin->sin_family = AF_INET; + ssin->sin_len = sizeof(*ssin); + ssin->sin_addr = ip->ip_src; proto = ip->ip_p; + if ((*flags & FL_HASH_ALL) == 0) { + FLDPRINTF(ft, FL_DEBUG_ALL, "skip port check flags=0x%x ", + *flags); + goto skipports; + } + iphlen = ip->ip_hl << 2; /* XXX options? */ - key[1] = ip->ip_src.s_addr; - + switch (proto) { case IPPROTO_TCP: th = (struct tcphdr *)((caddr_t)ip + iphlen); - sport = ntohs(th->th_sport); - dport = ntohs(th->th_dport); - *flags |= th->th_flags; - if (*flags & TH_RST) + sport = th->th_sport; + dport = th->th_dport; + if ((*flags & FL_HASH_ALL) && + (th->th_flags & (TH_RST|TH_FIN))) *flags |= FL_STALE; break; case IPPROTO_UDP: @@ -401,38 +545,288 @@ ipv4_flow_lookup_hash_internal(struct mbuf *m, struct route *ro, dport = sh->dest_port; break; default: - if (*flags & FL_HASH_PORTS) - goto noop; + FLDPRINTF(ft, FL_DEBUG_ALL, "proto=0x%x not supported\n", proto); + return (ENOTSUP); /* no port - hence not a protocol we care about */ break; } - *protop = proto; - - /* - * If this is a transmit route cache then - * hash all flows to a given destination to - * the same bucket - */ - if ((*flags & FL_HASH_PORTS) == 0) - proto = sport = dport = 0; - - ((uint16_t *)key)[0] = sport; - ((uint16_t *)key)[1] = dport; skipports: - hash = jenkins_hashword(key, 3, V_flow_hashjitter + proto); - if (m != NULL && (m->m_flags & M_FLOWID) == 0) { - m->m_flags |= M_FLOWID; - m->m_pkthdr.flowid = hash; - } - - return (hash); -noop: - *protop = proto; + *flags |= proto_to_flags(proto); + ssin->sin_port = sport; + dsin->sin_port = dport; return (0); } +static uint32_t +ipv4_flow_lookup_hash_internal( + struct sockaddr_in *ssin, struct sockaddr_in *dsin, + uint32_t *key, uint16_t flags) +{ + uint16_t sport, dport; + uint8_t proto; + int offset = 0; + + if ((V_flowtable_enable == 0) || (V_flowtable_ready == 0)) + return (0); + proto = flags_to_proto(flags); + sport = dport = key[2] = key[1] = key[0] = 0; + if ((ssin != NULL) && (flags & FL_HASH_ALL)) { + key[1] = ssin->sin_addr.s_addr; + sport = ssin->sin_port; + } + if (dsin != NULL) { + key[2] = dsin->sin_addr.s_addr; + dport = dsin->sin_port; + } + if (flags & FL_HASH_ALL) { + ((uint16_t *)key)[0] = sport; + ((uint16_t *)key)[1] = dport; + } else + offset = V_flow_hashjitter + proto; + + return (jenkins_hashword(key, 3, offset)); +} + +static struct flentry * +flowtable_lookup_mbuf4(struct flowtable *ft, struct mbuf *m) +{ + struct sockaddr_storage ssa, dsa; + uint16_t flags; + struct sockaddr_in *dsin, *ssin; + + dsin = (struct sockaddr_in *)&dsa; + ssin = (struct sockaddr_in *)&ssa; + flags = ft->ft_flags; + if (ipv4_mbuf_demarshal(ft, m, ssin, dsin, &flags) != 0) + return (NULL); + + return (flowtable_lookup(ft, &ssa, &dsa, M_GETFIB(m), flags)); +} + +void +flow_to_route(struct flentry *fle, struct route *ro) +{ + uint32_t *hashkey = NULL; + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)&ro->ro_dst; + sin->sin_family = AF_INET; + sin->sin_len = sizeof(*sin); + hashkey = ((struct flentry_v4 *)fle)->fl_flow.ipf_key; + sin->sin_addr.s_addr = hashkey[2]; + ro->ro_rt = __DEVOLATILE(struct rtentry *, fle->f_rt); + ro->ro_lle = __DEVOLATILE(struct llentry *, fle->f_lle); +} +#endif /* INET */ + +#ifdef INET6 +/* + * PULLUP_TO(len, p, T) makes sure that len + sizeof(T) is contiguous, + * then it sets p to point at the offset "len" in the mbuf. WARNING: the + * pointer might become stale after other pullups (but we never use it + * this way). + */ +#define PULLUP_TO(_len, p, T) \ +do { \ + int x = (_len) + sizeof(T); \ + if ((m)->m_len < x) { \ + goto receive_failed; \ + } \ + p = (mtod(m, char *) + (_len)); \ +} while (0) + +#define TCP(p) ((struct tcphdr *)(p)) +#define SCTP(p) ((struct sctphdr *)(p)) +#define UDP(p) ((struct udphdr *)(p)) + +static int +ipv6_mbuf_demarshal(struct flowtable *ft, struct mbuf *m, + struct sockaddr_in6 *ssin6, struct sockaddr_in6 *dsin6, uint16_t *flags) +{ + struct ip6_hdr *ip6; + uint8_t proto; + int hlen; + uint16_t src_port, dst_port; + u_short offset; + void *ulp; + + offset = hlen = src_port = dst_port = 0; + ulp = NULL; + ip6 = mtod(m, struct ip6_hdr *); + hlen = sizeof(struct ip6_hdr); + proto = ip6->ip6_nxt; + + if ((*flags & FL_HASH_ALL) == 0) + goto skipports; + + while (ulp == NULL) { + switch (proto) { + case IPPROTO_ICMPV6: + case IPPROTO_OSPFIGP: + case IPPROTO_PIM: + case IPPROTO_CARP: + case IPPROTO_ESP: + case IPPROTO_NONE: + ulp = ip6; + break; + case IPPROTO_TCP: + PULLUP_TO(hlen, ulp, struct tcphdr); + dst_port = TCP(ulp)->th_dport; + src_port = TCP(ulp)->th_sport; + if ((*flags & FL_HASH_ALL) && + (TCP(ulp)->th_flags & (TH_RST|TH_FIN))) + *flags |= FL_STALE; + break; + case IPPROTO_SCTP: + PULLUP_TO(hlen, ulp, struct sctphdr); + src_port = SCTP(ulp)->src_port; + dst_port = SCTP(ulp)->dest_port; + break; + case IPPROTO_UDP: + PULLUP_TO(hlen, ulp, struct udphdr); + dst_port = UDP(ulp)->uh_dport; + src_port = UDP(ulp)->uh_sport; + break; + case IPPROTO_HOPOPTS: /* RFC 2460 */ + PULLUP_TO(hlen, ulp, struct ip6_hbh); + hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3; + proto = ((struct ip6_hbh *)ulp)->ip6h_nxt; + ulp = NULL; + break; + case IPPROTO_ROUTING: /* RFC 2460 */ + PULLUP_TO(hlen, ulp, struct ip6_rthdr); + hlen += (((struct ip6_rthdr *)ulp)->ip6r_len + 1) << 3; + proto = ((struct ip6_rthdr *)ulp)->ip6r_nxt; + ulp = NULL; + break; + case IPPROTO_FRAGMENT: /* RFC 2460 */ + PULLUP_TO(hlen, ulp, struct ip6_frag); + hlen += sizeof (struct ip6_frag); + proto = ((struct ip6_frag *)ulp)->ip6f_nxt; + offset = ((struct ip6_frag *)ulp)->ip6f_offlg & + IP6F_OFF_MASK; + ulp = NULL; + break; + case IPPROTO_DSTOPTS: /* RFC 2460 */ + PULLUP_TO(hlen, ulp, struct ip6_hbh); + hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3; + proto = ((struct ip6_hbh *)ulp)->ip6h_nxt; + ulp = NULL; + break; + case IPPROTO_AH: /* RFC 2402 */ + PULLUP_TO(hlen, ulp, struct ip6_ext); + hlen += (((struct ip6_ext *)ulp)->ip6e_len + 2) << 2; + proto = ((struct ip6_ext *)ulp)->ip6e_nxt; + ulp = NULL; + break; + default: + PULLUP_TO(hlen, ulp, struct ip6_ext); + break; + } + } + + if (src_port == 0) { + receive_failed: + return (ENOTSUP); + } + +skipports: + dsin6->sin6_family = AF_INET6; + dsin6->sin6_len = sizeof(*dsin6); + dsin6->sin6_port = dst_port; + memcpy(&dsin6->sin6_addr, &ip6->ip6_dst, sizeof(struct in6_addr)); + + ssin6->sin6_family = AF_INET6; + ssin6->sin6_len = sizeof(*ssin6); + ssin6->sin6_port = src_port; + memcpy(&ssin6->sin6_addr, &ip6->ip6_src, sizeof(struct in6_addr)); + *flags |= proto_to_flags(proto); + + return (0); +} + +#define zero_key(key) \ +do { \ + key[0] = 0; \ + key[1] = 0; \ + key[2] = 0; \ + key[3] = 0; \ + key[4] = 0; \ + key[5] = 0; \ + key[6] = 0; \ + key[7] = 0; \ + key[8] = 0; \ +} while (0) + +static uint32_t +ipv6_flow_lookup_hash_internal( + struct sockaddr_in6 *ssin6, struct sockaddr_in6 *dsin6, + uint32_t *key, uint16_t flags) +{ + uint16_t sport, dport; + uint8_t proto; + int offset = 0; + + if ((V_flowtable_enable == 0) || (V_flowtable_ready == 0)) + return (0); + + proto = flags_to_proto(flags); + zero_key(key); + sport = dport = 0; + if (dsin6 != NULL) { + memcpy(&key[1], &dsin6->sin6_addr, sizeof(struct in6_addr)); + dport = dsin6->sin6_port; + } + if ((ssin6 != NULL) && (flags & FL_HASH_ALL)) { + memcpy(&key[5], &ssin6->sin6_addr, sizeof(struct in6_addr)); + sport = ssin6->sin6_port; + } + if (flags & FL_HASH_ALL) { + ((uint16_t *)key)[0] = sport; + ((uint16_t *)key)[1] = dport; + } else + offset = V_flow_hashjitter + proto; + + return (jenkins_hashword(key, 9, offset)); +} + +static struct flentry * +flowtable_lookup_mbuf6(struct flowtable *ft, struct mbuf *m) +{ + struct sockaddr_storage ssa, dsa; + struct sockaddr_in6 *dsin6, *ssin6; + uint16_t flags; + + dsin6 = (struct sockaddr_in6 *)&dsa; + ssin6 = (struct sockaddr_in6 *)&ssa; + flags = ft->ft_flags; + + if (ipv6_mbuf_demarshal(ft, m, ssin6, dsin6, &flags) != 0) + return (NULL); + + return (flowtable_lookup(ft, &ssa, &dsa, M_GETFIB(m), flags)); +} + +void +flow_to_route_in6(struct flentry *fle, struct route_in6 *ro) +{ + uint32_t *hashkey = NULL; + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)&ro->ro_dst; + + sin6->sin6_family = AF_INET6; + sin6->sin6_len = sizeof(*sin6); + hashkey = ((struct flentry_v6 *)fle)->fl_flow.ipf_key; + memcpy(&sin6->sin6_addr, &hashkey[5], sizeof (struct in6_addr)); + ro->ro_rt = __DEVOLATILE(struct rtentry *, fle->f_rt); + ro->ro_lle = __DEVOLATILE(struct llentry *, fle->f_lle); + +} +#endif /* INET6 */ + static bitstr_t * flowtable_mask(struct flowtable *ft) { @@ -511,22 +905,78 @@ flowtable_set_hashkey(struct flentry *fle, uint32_t *key) hashkey[i] = key[i]; } +static struct flentry * +flow_alloc(struct flowtable *ft) +{ + struct flentry *newfle; + uma_zone_t zone; + + newfle = NULL; + zone = (ft->ft_flags & FL_IPV6) ? V_flow_ipv6_zone : V_flow_ipv4_zone; + + newfle = uma_zalloc(zone, M_NOWAIT | M_ZERO); + if (newfle != NULL) + atomic_add_int(&ft->ft_count, 1); + return (newfle); +} + +static void +flow_free(struct flentry *fle, struct flowtable *ft) +{ + uma_zone_t zone; + + zone = (ft->ft_flags & FL_IPV6) ? V_flow_ipv6_zone : V_flow_ipv4_zone; + atomic_add_int(&ft->ft_count, -1); + uma_zfree(zone, fle); +} + +static int +flow_full(struct flowtable *ft) +{ + boolean_t full; + uint32_t count; + + full = ft->ft_full; + count = ft->ft_count; + + if (full && (count < (V_flowtable_nmbflows - (V_flowtable_nmbflows >> 3)))) + ft->ft_full = FALSE; + else if (!full && (count > (V_flowtable_nmbflows - (V_flowtable_nmbflows >> 5)))) + ft->ft_full = TRUE; + + if (full && !ft->ft_full) { + flowclean_freq = 4*hz; + if ((ft->ft_flags & FL_HASH_ALL) == 0) + ft->ft_udp_idle = ft->ft_fin_wait_idle = + ft->ft_syn_idle = ft->ft_tcp_idle = 5; + cv_broadcast(&flowclean_cv); + } else if (!full && ft->ft_full) { + flowclean_freq = 20*hz; + if ((ft->ft_flags & FL_HASH_ALL) == 0) + ft->ft_udp_idle = ft->ft_fin_wait_idle = + ft->ft_syn_idle = ft->ft_tcp_idle = 30; + } + + return (ft->ft_full); +} + static int flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key, - uint8_t proto, uint32_t fibnum, struct route *ro, uint16_t flags) + uint32_t fibnum, struct route *ro, uint16_t flags) { struct flentry *fle, *fletail, *newfle, **flep; + struct flowtable_stats *fs = &ft->ft_stats[curcpu]; int depth; - uma_zone_t flezone; bitstr_t *mask; + uint8_t proto; - flezone = (flags & FL_IPV6) ? V_flow_ipv6_zone : V_flow_ipv4_zone; - newfle = uma_zalloc(flezone, M_NOWAIT | M_ZERO); + newfle = flow_alloc(ft); if (newfle == NULL) return (ENOMEM); newfle->f_flags |= (flags & FL_IPV6); - + proto = flags_to_proto(flags); + FL_ENTRY_LOCK(ft, hash); mask = flowtable_mask(ft); flep = flowtable_entry(ft, hash); @@ -539,7 +989,7 @@ flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key, } depth = 0; - V_flowtable_collisions++; + fs->ft_collisions++; /* * find end of list and make sure that we were not * preempted by another thread handling this flow @@ -551,8 +1001,10 @@ flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key, * or we lost a race to insert */ FL_ENTRY_UNLOCK(ft, hash); - uma_zfree((newfle->f_flags & FL_IPV6) ? - V_flow_ipv6_zone : V_flow_ipv4_zone, newfle); + flow_free(newfle, ft); + + if (flags & FL_OVERWRITE) + goto skip; return (EEXIST); } /* @@ -565,8 +1017,8 @@ flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key, fle = fle->f_next; } - if (depth > V_flowtable_max_depth) - V_flowtable_max_depth = depth; + if (depth > fs->ft_max_depth) + fs->ft_max_depth = depth; fletail->f_next = newfle; fle = newfle; skip: @@ -582,6 +1034,35 @@ skip: return (0); } +int +kern_flowtable_insert(struct flowtable *ft, + struct sockaddr_storage *ssa, struct sockaddr_storage *dsa, + struct route *ro, uint32_t fibnum, int flags) +{ + uint32_t key[9], hash; + + flags = (ft->ft_flags | flags | FL_OVERWRITE); + hash = 0; + +#ifdef INET + if (ssa->ss_family == AF_INET) + hash = ipv4_flow_lookup_hash_internal((struct sockaddr_in *)ssa, + (struct sockaddr_in *)dsa, key, flags); +#endif +#ifdef INET6 + if (ssa->ss_family == AF_INET6) + hash = ipv6_flow_lookup_hash_internal((struct sockaddr_in6 *)ssa, + (struct sockaddr_in6 *)dsa, key, flags); +#endif + if (ro->ro_rt == NULL || ro->ro_lle == NULL) + return (EINVAL); + + FLDPRINTF(ft, FL_DEBUG, + "kern_flowtable_insert: key=%x:%x:%x hash=%x fibnum=%d flags=%x\n", + key[0], key[1], key[2], hash, fibnum, flags); + return (flowtable_insert(ft, hash, key, fibnum, ro, flags)); +} + static int flowtable_key_equal(struct flentry *fle, uint32_t *key) { @@ -595,7 +1076,7 @@ flowtable_key_equal(struct flentry *fle, uint32_t *key) nwords = 3; hashkey = ((struct flentry_v6 *)fle)->fl_flow.ipf_key; } - + for (i = 0; i < nwords; i++) if (hashkey[i] != key[i]) return (0); @@ -603,44 +1084,86 @@ flowtable_key_equal(struct flentry *fle, uint32_t *key) return (1); } -int -flowtable_lookup(struct flowtable *ft, struct mbuf *m, struct route *ro, uint32_t fibnum) +struct flentry * +flowtable_lookup_mbuf(struct flowtable *ft, struct mbuf *m, int af) +{ + struct flentry *fle = NULL; + +#ifdef INET + if (af == AF_INET) + fle = flowtable_lookup_mbuf4(ft, m); +#endif +#ifdef INET6 + if (af == AF_INET6) + fle = flowtable_lookup_mbuf6(ft, m); +#endif + if (fle != NULL && m != NULL && (m->m_flags & M_FLOWID) == 0) { + m->m_flags |= M_FLOWID; + m->m_pkthdr.flowid = fle->f_fhash; + } + return (fle); +} + +struct flentry * +flowtable_lookup(struct flowtable *ft, struct sockaddr_storage *ssa, + struct sockaddr_storage *dsa, uint32_t fibnum, int flags) { uint32_t key[9], hash; struct flentry *fle; - uint16_t flags; + struct flowtable_stats *fs = &ft->ft_stats[curcpu]; uint8_t proto = 0; int error = 0; struct rtentry *rt; struct llentry *lle; + struct route sro, *ro; + struct route_in6 sro6; - flags = ft->ft_flags; - ro->ro_rt = NULL; - ro->ro_lle = NULL; + sro.ro_rt = sro6.ro_rt = NULL; + sro.ro_lle = sro6.ro_lle = NULL; + ro = NULL; + hash = 0; + flags |= ft->ft_flags; + proto = flags_to_proto(flags); +#ifdef INET + if (ssa->ss_family == AF_INET) { + struct sockaddr_in *ssin, *dsin; - /* - * The internal hash lookup is the only IPv4 specific bit - * remaining - * - * XXX BZ: to add IPv6 support just add a check for the - * address type in m and ro and an equivalent ipv6 lookup - * function - the rest of the code should automatically - * handle an ipv6 flow (note that m can be NULL in which - * case ro will be set) - */ - hash = ipv4_flow_lookup_hash_internal(m, ro, key, - &flags, &proto); + ro = &sro; + memcpy(&ro->ro_dst, dsa, sizeof(struct sockaddr_in)); + dsin = (struct sockaddr_in *)dsa; + ssin = (struct sockaddr_in *)ssa; + if ((dsin->sin_addr.s_addr == ssin->sin_addr.s_addr) || + (ntohl(dsin->sin_addr.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || + (ntohl(ssin->sin_addr.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) + return (NULL); + hash = ipv4_flow_lookup_hash_internal(ssin, dsin, key, flags); + } +#endif +#ifdef INET6 + if (ssa->ss_family == AF_INET6) { + struct sockaddr_in6 *ssin6, *dsin6; + + ro = (struct route *)&sro6; + memcpy(&sro6.ro_dst, dsa, + sizeof(struct sockaddr_in6)); + dsin6 = (struct sockaddr_in6 *)dsa; + ssin6 = (struct sockaddr_in6 *)ssa; + + flags |= FL_IPV6; + hash = ipv6_flow_lookup_hash_internal(ssin6, dsin6, key, flags); + } +#endif /* * Ports are zero and this isn't a transmit cache * - thus not a protocol for which we need to keep * state - * FL_HASH_PORTS => key[0] != 0 for TCP || UDP || SCTP + * FL_HASH_ALL => key[0] != 0 for TCP || UDP || SCTP */ - if (hash == 0 || (key[0] == 0 && (ft->ft_flags & FL_HASH_PORTS))) - return (ENOENT); + if (hash == 0 || (key[0] == 0 && (ft->ft_flags & FL_HASH_ALL))) + return (NULL); - V_flowtable_lookups++; + fs->ft_lookups++; FL_ENTRY_LOCK(ft, hash); if ((fle = FL_ENTRY(ft, hash)) == NULL) { FL_ENTRY_UNLOCK(ft, hash); @@ -656,21 +1179,21 @@ keycheck: && (fibnum == fle->f_fibnum) && (rt->rt_flags & RTF_UP) && (rt->rt_ifp != NULL)) { - V_flowtable_hits++; + fs->ft_hits++; fle->f_uptime = time_uptime; fle->f_flags |= flags; - ro->ro_rt = rt; - ro->ro_lle = lle; FL_ENTRY_UNLOCK(ft, hash); - return (0); + return (fle); } else if (fle->f_next != NULL) { fle = fle->f_next; goto keycheck; } FL_ENTRY_UNLOCK(ft, hash); - uncached: - V_flowtable_misses++; + if (flags & FL_NOAUTO || flow_full(ft)) + return (NULL); + + fs->ft_misses++; /* * This bit of code ends up locking the * same route 3 times (just like ip_output + ether_output) @@ -683,36 +1206,64 @@ uncached: * receive the route locked */ +#ifdef INVARIANTS + if ((ro->ro_dst.sa_family != AF_INET) && + (ro->ro_dst.sa_family != AF_INET6)) + panic("sa_family == %d\n", ro->ro_dst.sa_family); +#endif + ft->ft_rtalloc(ro, hash, fibnum); if (ro->ro_rt == NULL) error = ENETUNREACH; else { struct llentry *lle = NULL; - struct sockaddr *l3addr; + struct sockaddr_storage *l3addr; struct rtentry *rt = ro->ro_rt; struct ifnet *ifp = rt->rt_ifp; if (ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) { RTFREE(rt); ro->ro_rt = NULL; - return (ENOENT); + return (NULL); } +#ifdef INET6 + if (ssa->ss_family == AF_INET6) { + struct sockaddr_in6 *dsin6; - if (rt->rt_flags & RTF_GATEWAY) - l3addr = rt->rt_gateway; - else - l3addr = &ro->ro_dst; - llentry_update(&lle, LLTABLE(ifp), l3addr, ifp); + dsin6 = (struct sockaddr_in6 *)dsa; + if (in6_localaddr(&dsin6->sin6_addr)) { + RTFREE(rt); + ro->ro_rt = NULL; + return (NULL); + } + + if (rt->rt_flags & RTF_GATEWAY) + l3addr = (struct sockaddr_storage *)rt->rt_gateway; + + else + l3addr = (struct sockaddr_storage *)&ro->ro_dst; + llentry_update(&lle, LLTABLE6(ifp), l3addr, ifp); + } +#endif +#ifdef INET + if (ssa->ss_family == AF_INET) { + if (rt->rt_flags & RTF_GATEWAY) + l3addr = (struct sockaddr_storage *)rt->rt_gateway; + else + l3addr = (struct sockaddr_storage *)&ro->ro_dst; + llentry_update(&lle, LLTABLE(ifp), l3addr, ifp); + } + +#endif ro->ro_lle = lle; if (lle == NULL) { RTFREE(rt); ro->ro_rt = NULL; - return (ENOENT); + return (NULL); } - error = flowtable_insert(ft, hash, key, proto, fibnum, - ro, flags); - + error = flowtable_insert(ft, hash, key, fibnum, ro, flags); + if (error) { RTFREE(rt); LLE_FREE(lle); @@ -721,7 +1272,7 @@ uncached: } } - return (error); + return ((error) ? NULL : fle); } /* @@ -730,7 +1281,7 @@ uncached: #define calloc(count, size) malloc((count)*(size), M_DEVBUF, M_WAITOK|M_ZERO) struct flowtable * -flowtable_alloc(int nentry, int flags) +flowtable_alloc(char *name, int nentry, int flags) { struct flowtable *ft, *fttail; int i; @@ -742,7 +1293,8 @@ flowtable_alloc(int nentry, int flags) ft = malloc(sizeof(struct flowtable), M_RTABLE, M_WAITOK | M_ZERO); - + + ft->ft_name = name; ft->ft_flags = flags; ft->ft_size = nentry; #ifdef RADIX_MPATH @@ -783,7 +1335,7 @@ flowtable_alloc(int nentry, int flags) * just a cache - so everything is eligible for * replacement after 5s of non-use */ - if (flags & FL_HASH_PORTS) { + if (flags & FL_HASH_ALL) { ft->ft_udp_idle = V_flowtable_udp_expire; ft->ft_syn_idle = V_flowtable_syn_expire; ft->ft_fin_wait_idle = V_flowtable_fin_wait_expire; @@ -816,7 +1368,7 @@ flowtable_alloc(int nentry, int flags) * */ static void -fle_free(struct flentry *fle) +fle_free(struct flentry *fle, struct flowtable *ft) { struct rtentry *rt; struct llentry *lle; @@ -825,8 +1377,7 @@ fle_free(struct flentry *fle) lle = __DEVOLATILE(struct llentry *, fle->f_lle); RTFREE(rt); LLE_FREE(lle); - uma_zfree((fle->f_flags & FL_IPV6) ? - V_flow_ipv6_zone : V_flow_ipv4_zone, fle); + flow_free(fle, ft); } static void @@ -836,7 +1387,8 @@ flowtable_free_stale(struct flowtable *ft, struct rtentry *rt) struct flentry *fle, **flehead, *fleprev; struct flentry *flefreehead, *flefreetail, *fletmp; bitstr_t *mask, *tmpmask; - + struct flowtable_stats *fs = &ft->ft_stats[curcpu]; + flefreehead = flefreetail = NULL; mask = flowtable_mask(ft); tmpmask = ft->ft_tmpmask; @@ -853,12 +1405,12 @@ flowtable_free_stale(struct flowtable *ft, struct rtentry *rt) curbit); break; } - + FL_ENTRY_LOCK(ft, curbit); flehead = flowtable_entry(ft, curbit); fle = fleprev = *flehead; - V_flowtable_free_checks++; + fs->ft_free_checks++; #ifdef DIAGNOSTIC if (fle == NULL && curbit > 0) { log(LOG_ALERT, @@ -896,7 +1448,7 @@ flowtable_free_stale(struct flowtable *ft, struct rtentry *rt) fleprev->f_next = fle->f_next; fle = fleprev->f_next; } - + if (flefreehead == NULL) flefreehead = flefreetail = fletmp; else { @@ -915,8 +1467,8 @@ flowtable_free_stale(struct flowtable *ft, struct rtentry *rt) while ((fle = flefreehead) != NULL) { flefreehead = fle->f_next; count++; - V_flowtable_frees++; - fle_free(fle); + fs->ft_frees++; + fle_free(fle, ft); } if (V_flowtable_debug && count) log(LOG_DEBUG, "freed %d flow entries\n", count); @@ -926,6 +1478,7 @@ void flowtable_route_flush(struct flowtable *ft, struct rtentry *rt) { int i; + if (ft->ft_flags & FL_PCPU) { for (i = 0; i <= mp_maxid; i++) { if (CPU_ABSENT(i)) @@ -1007,7 +1560,7 @@ flowtable_cleaner(void) */ mtx_lock(&flowclean_lock); cv_broadcast(&flowclean_cv); - cv_timedwait(&flowclean_cv, &flowclean_lock, 10*hz); + cv_timedwait(&flowclean_cv, &flowclean_lock, flowclean_freq); mtx_unlock(&flowclean_lock); } } @@ -1016,7 +1569,7 @@ static void flowtable_flush(void *unused __unused) { uint64_t start; - + mtx_lock(&flowclean_lock); start = flowclean_cycles; while (start == flowclean_cycles) { @@ -1037,6 +1590,7 @@ static void flowtable_init_vnet(const void *unused __unused) { + V_flowtable_nmbflows = 1024 + maxusers * 64 * mp_ncpus; V_flow_ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4), NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET); V_flow_ipv6_zone = uma_zcreate("ip6flow", sizeof(struct flentry_v6), @@ -1045,7 +1599,7 @@ flowtable_init_vnet(const void *unused __unused) uma_zone_set_max(V_flow_ipv6_zone, V_flowtable_nmbflows); V_flowtable_ready = 1; } -VNET_SYSINIT(flowtable_init_vnet, SI_SUB_KTHREAD_INIT, SI_ORDER_MIDDLE, +VNET_SYSINIT(flowtable_init_vnet, SI_SUB_SMP, SI_ORDER_ANY, flowtable_init_vnet, NULL); static void @@ -1056,8 +1610,9 @@ flowtable_init(const void *unused __unused) mtx_init(&flowclean_lock, "flowclean lock", NULL, MTX_DEF); EVENTHANDLER_REGISTER(ifnet_departure_event, flowtable_flush, NULL, EVENTHANDLER_PRI_ANY); + flowclean_freq = 20*hz; } -SYSINIT(flowtable_init, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, +SYSINIT(flowtable_init, SI_SUB_SMP, SI_ORDER_MIDDLE, flowtable_init, NULL); @@ -1076,6 +1631,19 @@ VNET_SYSUNINIT(flowtable_uninit, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, #endif #ifdef DDB +static uint32_t * +flowtable_get_hashkey(struct flentry *fle) +{ + uint32_t *hashkey; + + if (fle->f_flags & FL_IPV6) + hashkey = ((struct flentry_v4 *)fle)->fl_flow.ipf_key; + else + hashkey = ((struct flentry_v6 *)fle)->fl_flow.ipf_key; + + return (hashkey); +} + static bitstr_t * flowtable_mask_pcpu(struct flowtable *ft, int cpuid) { @@ -1108,17 +1676,64 @@ static void flow_show(struct flowtable *ft, struct flentry *fle) { int idle_time; - int rt_valid; + int rt_valid, ifp_valid; + uint16_t sport, dport; + uint32_t *hashkey; + char saddr[4*sizeof "123"], daddr[4*sizeof "123"]; + volatile struct rtentry *rt; + struct ifnet *ifp = NULL; idle_time = (int)(time_uptime - fle->f_uptime); - rt_valid = fle->f_rt != NULL; - db_printf("hash=0x%08x idle_time=%03d rt=%p ifp=%p", - fle->f_fhash, idle_time, - fle->f_rt, rt_valid ? fle->f_rt->rt_ifp : NULL); - if (rt_valid && (fle->f_rt->rt_flags & RTF_UP)) - db_printf(" RTF_UP "); + rt = fle->f_rt; + rt_valid = rt != NULL; + if (rt_valid) + ifp = rt->rt_ifp; + ifp_valid = ifp != NULL; + hashkey = flowtable_get_hashkey(fle); + if (fle->f_flags & FL_IPV6) + goto skipaddr; + + inet_ntoa_r(*(struct in_addr *) &hashkey[2], daddr); + if (ft->ft_flags & FL_HASH_ALL) { + inet_ntoa_r(*(struct in_addr *) &hashkey[1], saddr); + sport = ntohs(((uint16_t *)hashkey)[0]); + dport = ntohs(((uint16_t *)hashkey)[1]); + db_printf("%s:%d->%s:%d", + saddr, sport, daddr, + dport); + } else + db_printf("%s ", daddr); + +skipaddr: if (fle->f_flags & FL_STALE) db_printf(" FL_STALE "); + if (fle->f_flags & FL_TCP) + db_printf(" FL_TCP "); + if (fle->f_flags & FL_UDP) + db_printf(" FL_UDP "); + if (rt_valid) { + if (rt->rt_flags & RTF_UP) + db_printf(" RTF_UP "); + } + if (ifp_valid) { + if (ifp->if_flags & IFF_LOOPBACK) + db_printf(" IFF_LOOPBACK "); + if (ifp->if_flags & IFF_UP) + db_printf(" IFF_UP "); + if (ifp->if_flags & IFF_POINTOPOINT) + db_printf(" IFF_POINTOPOINT "); + } + if (fle->f_flags & FL_IPV6) + db_printf("\n\tkey=%08x:%08x:%08x%08x:%08x:%08x%08x:%08x:%08x", + hashkey[0], hashkey[1], hashkey[2], + hashkey[3], hashkey[4], hashkey[5], + hashkey[6], hashkey[7], hashkey[8]); + else + db_printf("\n\tkey=%08x:%08x:%08x ", + hashkey[0], hashkey[1], hashkey[2]); + db_printf("hash=%08x idle_time=%03d" + "\n\tfibnum=%02d rt=%p", + fle->f_fhash, idle_time, fle->f_fibnum, fle->f_rt); db_printf("\n"); } @@ -1129,7 +1744,8 @@ flowtable_show(struct flowtable *ft, int cpuid) struct flentry *fle, **flehead; bitstr_t *mask, *tmpmask; - db_printf("cpu: %d\n", cpuid); + if (cpuid != -1) + db_printf("cpu: %d\n", cpuid); mask = flowtable_mask_pcpu(ft, cpuid); tmpmask = ft->ft_tmpmask; memcpy(tmpmask, mask, ft->ft_size/8); @@ -1166,6 +1782,7 @@ flowtable_show_vnet(void) ft = V_flow_list_head; while (ft != NULL) { + printf("name: %s\n", ft->ft_name); if (ft->ft_flags & FL_PCPU) { for (i = 0; i <= mp_maxid; i++) { if (CPU_ABSENT(i)) @@ -1173,7 +1790,7 @@ flowtable_show_vnet(void) flowtable_show(ft, i); } } else { - flowtable_show(ft, 0); + flowtable_show(ft, -1); } ft = ft->ft_next; } diff --git a/sys/net/flowtable.h b/sys/net/flowtable.h index 7d7abdfad15..6e79a3cfe93 100644 --- a/sys/net/flowtable.h +++ b/sys/net/flowtable.h @@ -1,6 +1,6 @@ /************************************************************************** -Copyright (c) 2008-2009, BitGravity Inc. +Copyright (c) 2008-2010, BitGravity Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -34,24 +34,49 @@ $FreeBSD$ #ifdef _KERNEL -#define FL_HASH_PORTS (1<<0) /* hash 4-tuple + protocol */ +#define FL_HASH_ALL (1<<0) /* hash 4-tuple + protocol */ #define FL_PCPU (1<<1) /* pcpu cache */ +#define FL_NOAUTO (1<<2) /* don't automatically add flentry on miss */ + +#define FL_TCP (1<<11) +#define FL_SCTP (1<<12) +#define FL_UDP (1<<13) +#define FL_DEBUG (1<<14) +#define FL_DEBUG_ALL (1<<15) struct flowtable; +struct flentry; +struct route; +struct route_in6; + VNET_DECLARE(struct flowtable *, ip_ft); #define V_ip_ft VNET(ip_ft) -struct flowtable *flowtable_alloc(int nentry, int flags); +VNET_DECLARE(struct flowtable *, ip6_ft); +#define V_ip6_ft VNET(ip6_ft) + +struct flowtable *flowtable_alloc(char *name, int nentry, int flags); /* * Given a flow table, look up the L3 and L2 information and * return it in the route. * */ -int flowtable_lookup(struct flowtable *ft, struct mbuf *m, - struct route *ro, uint32_t fibnum); +struct flentry *flowtable_lookup_mbuf(struct flowtable *ft, struct mbuf *m, int af); +struct flentry *flowtable_lookup(struct flowtable *ft, struct sockaddr_storage *ssa, + struct sockaddr_storage *dsa, uint32_t fibnum, int flags); + +int kern_flowtable_insert(struct flowtable *ft, struct sockaddr_storage *ssa, + struct sockaddr_storage *dsa, struct route *ro, uint32_t fibnum, int flags); + +void flow_invalidate(struct flentry *fl); void flowtable_route_flush(struct flowtable *ft, struct rtentry *rt); +void flow_to_route(struct flentry *fl, struct route *ro); + +void flow_to_route_in6(struct flentry *fl, struct route_in6 *ro); + + #endif /* _KERNEL */ #endif diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index 52d73db863e..f934af5d675 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -116,13 +116,13 @@ llentry_free(struct llentry *lle) /* * Update an llentry for address dst (equivalent to rtalloc for new-arp) - * Caller must pass in a valid struct llentry * + * Caller must pass in a valid struct llentry * (or NULL) * * if found the llentry * is returned referenced and unlocked */ int llentry_update(struct llentry **llep, struct lltable *lt, - struct sockaddr *dst, struct ifnet *ifp) + struct sockaddr_storage *dst, struct ifnet *ifp) { struct llentry *la; diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h index 21357ebaef6..debb416ca06 100644 --- a/sys/net/if_llatbl.h +++ b/sys/net/if_llatbl.h @@ -191,7 +191,7 @@ int lltable_sysctl_dumparp(int, struct sysctl_req *); void llentry_free(struct llentry *); int llentry_update(struct llentry **, struct lltable *, - struct sockaddr *, struct ifnet *); + struct sockaddr_storage *, struct ifnet *); /* * Generic link layer address lookup function. diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 084bac06955..8be51fb992d 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -327,9 +327,21 @@ ip_init(void) "error %d\n", __func__, i); #ifdef FLOWTABLE - TUNABLE_INT_FETCH("net.inet.ip.output_flowtable_size", - &V_ip_output_flowtable_size); - V_ip_ft = flowtable_alloc(V_ip_output_flowtable_size, FL_PCPU); + if (TUNABLE_INT_FETCH("net.inet.ip.output_flowtable_size", + &V_ip_output_flowtable_size)) { + if (V_ip_output_flowtable_size < 256) + V_ip_output_flowtable_size = 256; + if (!powerof2(V_ip_output_flowtable_size)) { + printf("flowtable must be power of 2 size\n"); + V_ip_output_flowtable_size = 2048; + } + } else { + /* + * round up to the next power of 2 + */ + V_ip_output_flowtable_size = 1 << fls((1024 + maxusers * 64)-1); + } + V_ip_ft = flowtable_alloc("ipv4", V_ip_output_flowtable_size, FL_PCPU); #endif /* Skip initialization of globals for non-default instances. */ diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index b5be6fd1e1f..2f4a356ed78 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -151,14 +151,20 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, bzero(ro, sizeof (*ro)); #ifdef FLOWTABLE - /* - * The flow table returns route entries valid for up to 30 - * seconds; we rely on the remainder of ip_output() taking no - * longer than that long for the stability of ro_rt. The - * flow ID assignment must have happened before this point. - */ - if (flowtable_lookup(V_ip_ft, m, ro, M_GETFIB(m)) == 0) - nortfree = 1; + { + struct flentry *fle; + + /* + * The flow table returns route entries valid for up to 30 + * seconds; we rely on the remainder of ip_output() taking no + * longer than that long for the stability of ro_rt. The + * flow ID assignment must have happened before this point. + */ + if ((fle = flowtable_lookup_mbuf(V_ip_ft, m, AF_INET)) != NULL) { + flow_to_route(fle, ro); + nortfree = 1; + } + } #endif } From 4018626f75a16eecaec42faabb55b3c483600570 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 1 Apr 2010 00:38:38 +0000 Subject: [PATCH 1799/2592] MFC r205656: Check that gl_pathc is bigger than zero before derefencing gl_pathv. When gl_pathc == 0, the content of gl_pathv is undefined. PR: bin/144761 Submitted by: David BERARD Obtained from: OpenBSD --- libexec/ftpd/popen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libexec/ftpd/popen.c b/libexec/ftpd/popen.c index 3c187b94daf..8a739dc2ffe 100644 --- a/libexec/ftpd/popen.c +++ b/libexec/ftpd/popen.c @@ -110,10 +110,11 @@ ftpd_popen(char *program, char *type) flags |= GLOB_LIMIT; if (glob(argv[argc], flags, NULL, &gl)) gargv[gargc++] = strdup(argv[argc]); - else + else if (gl.gl_pathc > 0) { for (pop = gl.gl_pathv; *pop && gargc < (MAXGLOBARGS-1); pop++) gargv[gargc++] = strdup(*pop); + } globfree(&gl); } gargv[gargc] = NULL; From e55b9df7b370f3f1c243a960ce951733ab79312e Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Apr 2010 02:03:28 +0000 Subject: [PATCH 1800/2592] MFC: r197542: - When we run our trap cleanup handler, echo that we are running this handler to make it more clear why we are 'suddenly' running df, umount, and mdconfig. - Remove trap handler again after we have unconfigured the memory device etc. Before we could end up running the trap handler if a later stage failed, which was a bit confusing and not really useful. MFC after: 2 weeks --- tools/tools/nanobsd/nanobsd.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh index d476ff89392..10d8f78b6c9 100644 --- a/tools/tools/nanobsd/nanobsd.sh +++ b/tools/tools/nanobsd/nanobsd.sh @@ -439,7 +439,7 @@ create_i386_diskimage ( ) ( -y ${NANO_HEADS}` fi - trap "df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT + trap "echo 'Running exit trap code' ; df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT fdisk -i -f ${NANO_OBJ}/_.fdisk ${MD} fdisk ${MD} @@ -491,6 +491,9 @@ create_i386_diskimage ( ) ( echo "Writing out _.disk.image..." dd if=/dev/${MD}s1 of=${NANO_DISKIMGDIR}/_.disk.image bs=64k mdconfig -d -u $MD + + trap - 1 2 15 EXIT + ) > ${NANO_OBJ}/_.di 2>&1 ) From 56a526f031776639bbc2fcfb263f6846e61daf15 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 1 Apr 2010 02:41:50 +0000 Subject: [PATCH 1801/2592] MFC rev 199602, 200739, 203177, 203350, 203352, 205495, 205527, 205535 and 205569: Sync MPC85xx/Book-E with 9-current. --- sys/powerpc/booke/clock.c | 9 +-- sys/powerpc/booke/interrupt.c | 2 + sys/powerpc/booke/machdep.c | 16 ++---- sys/powerpc/booke/trap_subr.S | 1 + sys/powerpc/mpc85xx/ocpbus.c | 15 ++++- sys/powerpc/mpc85xx/ocpbus.h | 2 + sys/powerpc/mpc85xx/pci_ocp.c | 104 +++++++++++++++++++--------------- sys/powerpc/powerpc/cpu.c | 7 +++ 8 files changed, 90 insertions(+), 66 deletions(-) diff --git a/sys/powerpc/booke/clock.c b/sys/powerpc/booke/clock.c index 1d9043ebbed..74f7d7490c2 100644 --- a/sys/powerpc/booke/clock.c +++ b/sys/powerpc/booke/clock.c @@ -197,15 +197,8 @@ DELAY(int n) { u_quad_t start, end, now; -#define USECS_IN_SEC 1000000ULL - - if (n > USECS_IN_SEC) { - printf("WARNING: %s(%d) called from %p", __func__, n, - __builtin_return_address(0)); - } - start = mftb(); - end = start + (u_quad_t)ticks_per_sec / (USECS_IN_SEC / n); + end = start + (u_quad_t)ticks_per_sec / (1000000ULL / n); do { now = mftb(); } while (now < end || (now > start && end < start)); diff --git a/sys/powerpc/booke/interrupt.c b/sys/powerpc/booke/interrupt.c index 2367bf94b33..91ceeb7bf1d 100644 --- a/sys/powerpc/booke/interrupt.c +++ b/sys/powerpc/booke/interrupt.c @@ -123,6 +123,7 @@ powerpc_decr_interrupt(struct trapframe *framep) decr_intr(framep); atomic_subtract_int(&td->td_intr_nesting_level, 1); critical_exit(); + framep->srr1 &= ~PSL_WE; } /* @@ -135,4 +136,5 @@ powerpc_extr_interrupt(struct trapframe *framep) critical_enter(); PIC_DISPATCH(pic, framep); critical_exit(); + framep->srr1 &= ~PSL_WE; } diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index d2e25e79ded..e9a0099497c 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -706,6 +706,7 @@ cpu_idle (int busy) register_t msr; msr = mfmsr(); + #ifdef INVARIANTS if ((msr & PSL_EE) != PSL_EE) { struct thread *td = curthread; @@ -713,19 +714,10 @@ cpu_idle (int busy) panic("ints disabled in idleproc!"); } #endif -#if 0 - /* - * Freescale E500 core RM section 6.4.1 - */ - msr = msr | PSL_WE; - __asm__(" msync;" - " mtmsr %0;" - " isync;" - "loop: b loop" : - /* no output */ : - "r" (msr)); -#endif + /* Freescale E500 core RM section 6.4.1. */ + msr = msr | PSL_WE; + __asm __volatile("msync; mtmsr %0; isync" :: "r" (msr)); } int diff --git a/sys/powerpc/booke/trap_subr.S b/sys/powerpc/booke/trap_subr.S index 2e67725dc4f..b71f4bdb790 100644 --- a/sys/powerpc/booke/trap_subr.S +++ b/sys/powerpc/booke/trap_subr.S @@ -441,6 +441,7 @@ INTERRUPT(int_instr_storage) INTERRUPT(int_external_input) STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1) FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_EXI) + addi %r3, %r1, 8 bl CNAME(powerpc_extr_interrupt) b trapexit diff --git a/sys/powerpc/mpc85xx/ocpbus.c b/sys/powerpc/mpc85xx/ocpbus.c index 2adec47b25b..6c6515e4be6 100644 --- a/sys/powerpc/mpc85xx/ocpbus.c +++ b/sys/powerpc/mpc85xx/ocpbus.c @@ -152,6 +152,10 @@ ocpbus_write_law(int trgt, int type, u_long *startp, u_long *countp) addr = 0xA0000000; size = 0x10000000; break; + case OCP85XX_TGTIF_PCI3: + addr = 0xB0000000; + size = 0x10000000; + break; default: return (EINVAL); } @@ -170,6 +174,10 @@ ocpbus_write_law(int trgt, int type, u_long *startp, u_long *countp) addr = 0xfee20000; size = 0x00010000; break; + case OCP85XX_TGTIF_PCI3: + addr = 0xfee30000; + size = 0x00010000; + break; default: return (EINVAL); } @@ -188,7 +196,7 @@ static int ocpbus_probe(device_t dev) { - device_set_desc(dev, "On-Chip Peripherals bus"); + device_set_desc(dev, "Freescale on-chip peripherals bus"); return (BUS_PROBE_DEFAULT); } @@ -210,6 +218,7 @@ ocpbus_attach(device_t dev) ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 0); ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 1); ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 2); + ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 3); ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 0); ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 1); ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 2); @@ -338,6 +347,10 @@ const struct ocp_resource mpc8555_resources[] = { OCP85XX_PCI_SIZE}, {OCPBUS_DEVTYPE_PCIB, 2, SYS_RES_MEMORY, 1, 0, OCP85XX_TGTIF_PCI2}, {OCPBUS_DEVTYPE_PCIB, 2, SYS_RES_IOPORT, 1, 0, OCP85XX_TGTIF_PCI2}, + {OCPBUS_DEVTYPE_PCIB, 3, SYS_RES_MEMORY, 0, OCP85XX_PCI3_OFF, + OCP85XX_PCI_SIZE}, + {OCPBUS_DEVTYPE_PCIB, 3, SYS_RES_MEMORY, 1, 0, OCP85XX_TGTIF_PCI3}, + {OCPBUS_DEVTYPE_PCIB, 3, SYS_RES_IOPORT, 1, 0, OCP85XX_TGTIF_PCI3}, {OCPBUS_DEVTYPE_LBC, 0, SYS_RES_MEMORY, 0, OCP85XX_LBC_OFF, OCP85XX_LBC_SIZE}, diff --git a/sys/powerpc/mpc85xx/ocpbus.h b/sys/powerpc/mpc85xx/ocpbus.h index 6aa6de3b063..fb715da5af1 100644 --- a/sys/powerpc/mpc85xx/ocpbus.h +++ b/sys/powerpc/mpc85xx/ocpbus.h @@ -50,6 +50,7 @@ #define OCP85XX_TGTIF_PCI0 0 #define OCP85XX_TGTIF_PCI1 1 #define OCP85XX_TGTIF_PCI2 2 +#define OCP85XX_TGTIF_PCI3 3 #define OCP85XX_TGTIF_LBC 4 #define OCP85XX_TGTIF_RAM_INTL 11 #define OCP85XX_TGTIF_RIO 12 @@ -86,6 +87,7 @@ #define OCP85XX_PCI0_OFF 0x08000 #define OCP85XX_PCI1_OFF 0x09000 #define OCP85XX_PCI2_OFF 0x0A000 +#define OCP85XX_PCI3_OFF 0x0B000 #define OCP85XX_PCI_SIZE 0x1000 #define OCP85XX_TSEC0_OFF 0x24000 #define OCP85XX_TSEC1_OFF 0x25000 diff --git a/sys/powerpc/mpc85xx/pci_ocp.c b/sys/powerpc/mpc85xx/pci_ocp.c index b98f62c7e90..cdcf986b940 100644 --- a/sys/powerpc/mpc85xx/pci_ocp.c +++ b/sys/powerpc/mpc85xx/pci_ocp.c @@ -76,6 +76,9 @@ __FBSDID("$FreeBSD$"); #define REG_PIWBEAR(n) (0x0e0c - 0x20 * (n)) #define REG_PIWAR(n) (0x0e10 - 0x20 * (n)) +#define PCIR_FSL_LTSSM 0x404 +#define FSL_LTSSM_L0 0x16 + #define DEVFN(b, s, f) ((b << 16) | (s << 8) | f) struct pci_ocp_softc { @@ -94,7 +97,7 @@ struct pci_ocp_softc { int sc_rid; int sc_busnr; - int sc_pcie:1; + uint8_t sc_pcie_cap; /* Devices that need special attention. */ int sc_devfn_tundra; @@ -168,7 +171,7 @@ pci_ocp_cfgread(struct pci_ocp_softc *sc, u_int bus, u_int slot, u_int func, addr |= (slot & 0x1f) << 11; addr |= (func & 0x7) << 8; addr |= reg & 0xfc; - if (sc->sc_pcie) + if (sc->sc_pcie_cap) addr |= (reg & 0xf00) << 16; bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_CFG_ADDR, addr); @@ -206,7 +209,7 @@ pci_ocp_cfgwrite(struct pci_ocp_softc *sc, u_int bus, u_int slot, u_int func, addr |= (slot & 0x1f) << 11; addr |= (func & 0x7) << 8; addr |= reg & 0xfc; - if (sc->sc_pcie) + if (sc->sc_pcie_cap) addr |= (reg & 0xf00) << 16; bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_CFG_ADDR, addr); @@ -261,7 +264,7 @@ pci_ocp_maxslots(device_t dev) { struct pci_ocp_softc *sc = device_get_softc(dev); - return ((sc->sc_pcie) ? 0 : 30); + return ((sc->sc_pcie_cap) ? 0 : 31); } static uint32_t @@ -271,9 +274,21 @@ pci_ocp_read_config(device_t dev, u_int bus, u_int slot, u_int func, struct pci_ocp_softc *sc = device_get_softc(dev); u_int devfn; - if (bus == sc->sc_busnr && !sc->sc_pcie && slot < 10) + if (bus == sc->sc_busnr && !sc->sc_pcie_cap && slot < 10) return (~0); devfn = DEVFN(bus, slot, func); + /* + * For the host controller itself, pretend to be a standard + * PCI bridge, rather than a PowerPC processor. That way the + * generic PCI code will enumerate all subordinate busses + * and devices as usual. + */ + if (sc->sc_pcie_cap && devfn == 0) { + if (reg == PCIR_CLASS && bytes == 1) + return (PCIC_BRIDGE); + if (reg == PCIR_SUBCLASS && bytes == 1) + return (PCIS_BRIDGE_PCI); + } if (devfn == sc->sc_devfn_tundra) return (~0); if (devfn == sc->sc_devfn_via_ide && reg == PCIR_INTPIN) @@ -287,7 +302,7 @@ pci_ocp_write_config(device_t dev, u_int bus, u_int slot, u_int func, { struct pci_ocp_softc *sc = device_get_softc(dev); - if (bus == sc->sc_busnr && !sc->sc_pcie && slot < 10) + if (bus == sc->sc_busnr && !sc->sc_pcie_cap && slot < 10) return; pci_ocp_cfgwrite(sc, bus, slot, func, reg, val, bytes); } @@ -297,11 +312,12 @@ pci_ocp_probe(device_t dev) { char buf[128]; struct pci_ocp_softc *sc; - const char *mpcid, *type; + const char *type; device_t parent; u_long start, size; uintptr_t devtype; uint32_t cfgreg; + uint8_t capptr; int error; parent = device_get_parent(dev); @@ -312,6 +328,7 @@ pci_ocp_probe(device_t dev) return (ENXIO); sc = device_get_softc(dev); + sc->sc_dev = dev; sc->sc_rid = 0; sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid, @@ -327,48 +344,33 @@ pci_ocp_probe(device_t dev) cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, PCIR_VENDOR, 2); if (cfgreg != 0x1057 && cfgreg != 0x1957) goto out; - cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, PCIR_DEVICE, 2); - switch (cfgreg) { - case 0x000a: - mpcid = "8555E"; - break; - case 0x0012: - mpcid = "8548E"; - break; - case 0x0013: - mpcid = "8548"; - break; - /* - * Documentation from Freescale is incorrect. - * Use right values after documentation is corrected. - */ - case 0x0030: - mpcid = "8544E"; - break; - case 0x0031: - mpcid = "8544"; - break; - case 0x0032: - mpcid = "8544"; - break; - default: + + cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, PCIR_CLASS, 1); + if (cfgreg != PCIC_PROCESSOR) + goto out; + + cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, PCIR_SUBCLASS, 1); + if (cfgreg != PCIS_PROCESSOR_POWERPC) + goto out; + + cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, PCIR_PROGIF, 1); + if (cfgreg != 0) /* RC mode = 0, EP mode = 1 */ goto out; - } type = "PCI"; - cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, PCIR_CAP_PTR, 1); - while (cfgreg != 0) { - cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, cfgreg, 2); + capptr = pci_ocp_cfgread(sc, 0, 0, 0, PCIR_CAP_PTR, 1); + while (capptr != 0) { + cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, capptr, 2); switch (cfgreg & 0xff) { case PCIY_PCIX: /* PCI-X */ type = "PCI-X"; break; case PCIY_EXPRESS: /* PCI Express */ type = "PCI Express"; - sc->sc_pcie = 1; + sc->sc_pcie_cap = capptr; break; } - cfgreg = (cfgreg >> 8) & 0xff; + capptr = (cfgreg >> 8) & 0xff; } error = bus_get_resource(dev, SYS_RES_MEMORY, 1, &start, &size); @@ -376,7 +378,7 @@ pci_ocp_probe(device_t dev) goto out; snprintf(buf, sizeof(buf), - "Freescale MPC%s %s host controller", mpcid, type); + "Freescale on-chip %s host controller", type); device_set_desc_copy(dev, buf); error = BUS_PROBE_DEFAULT; @@ -491,7 +493,7 @@ pci_ocp_route_int(struct pci_ocp_softc *sc, u_int bus, u_int slot, u_int func, } static int -pci_ocp_init(struct pci_ocp_softc *sc, int bus, int maxslot) +pci_ocp_init(struct pci_ocp_softc *sc, int bus, int nslots) { int secbus, slot; int func, maxfunc; @@ -501,7 +503,7 @@ pci_ocp_init(struct pci_ocp_softc *sc, int bus, int maxslot) uint8_t intline, intpin; secbus = bus; - for (slot = 0; slot < maxslot; slot++) { + for (slot = 0; slot < nslots; slot++) { maxfunc = 0; for (func = 0; func <= maxfunc; func++) { hdrtype = pci_ocp_read_config(sc->sc_dev, bus, slot, @@ -598,7 +600,7 @@ pci_ocp_init(struct pci_ocp_softc *sc, int bus, int maxslot) PCIR_SUBBUS_1, 0xff, 1); secbus = pci_ocp_init(sc, secbus, - (subclass == PCIS_BRIDGE_PCI) ? 31 : 1); + (subclass == PCIS_BRIDGE_PCI) ? 32 : 1); pci_ocp_write_config(sc->sc_dev, bus, slot, func, PCIR_SUBBUS_1, secbus, 1); @@ -720,7 +722,7 @@ pci_ocp_attach(device_t dev) { struct pci_ocp_softc *sc; uint32_t cfgreg; - int error, maxslot; + int error, nslots; sc = device_get_softc(dev); sc->sc_dev = dev; @@ -753,8 +755,19 @@ pci_ocp_attach(device_t dev) sc->sc_devfn_tundra = -1; sc->sc_devfn_via_ide = -1; - maxslot = (sc->sc_pcie) ? 1 : 31; - pci_ocp_init(sc, sc->sc_busnr, maxslot); + /* + * PCI Express host controllers require a link. We don't + * fail the attach if there's no link, but we also don't + * create a child pci(4) device. + */ + if (sc->sc_pcie_cap) { + cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, PCIR_FSL_LTSSM, 4); + if (cfgreg < FSL_LTSSM_L0) + return (0); + } + + nslots = (sc->sc_pcie_cap) ? 1 : 32; + pci_ocp_init(sc, sc->sc_busnr, nslots); device_add_child(dev, "pci", -1); return (bus_generic_attach(dev)); @@ -783,6 +796,7 @@ pci_ocp_alloc_resource(device_t dev, device_t child, int type, int *rid, device_printf(dev, "%s requested ISA interrupt %lu\n", device_get_nameunit(child), start); } + flags |= RF_SHAREABLE; return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); default: diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c index ebf36ee161b..b49b1af5f62 100644 --- a/sys/powerpc/powerpc/cpu.c +++ b/sys/powerpc/powerpc/cpu.c @@ -433,6 +433,13 @@ cpu_e500_setup(int cpuid, uint16_t vers) register_t hid0; hid0 = mfspr(SPR_HID0); + + /* Programe power-management mode. */ + hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP); + hid0 |= HID0_DOZE; + + mtspr(SPR_HID0, hid0); + printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, HID0_E500_BITMASK); } From 894197990702f6934582bffae3a359258858f2a2 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 1 Apr 2010 13:21:04 +0000 Subject: [PATCH 1802/2592] MFC r205163: Fix two small bugs. The PowerPC 970 does not support non-coherent memory access, and reflects this by autonomously writing LPTE_M into PTE entries. As such, we should not panic if LPTE_M changes by itself. While here, fix a harmless typo in moea64_sync_icache(). --- sys/powerpc/aim/mmu_oea64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 4e9717785a0..21aceb3d066 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -2246,7 +2246,7 @@ moea64_pvo_to_pte(const struct pvo_entry *pvo, int pteidx) } if (((pt->pte_lo ^ pvo->pvo_pte.lpte.pte_lo) & - ~(LPTE_CHG|LPTE_REF)) != 0) { + ~(LPTE_M|LPTE_CHG|LPTE_REF)) != 0) { panic("moea64_pvo_to_pte: pvo %p pte does not match " "pte %p in moea64_pteg_table difference is %#x", pvo, pt, @@ -2488,7 +2488,7 @@ moea64_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz) 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) | + pa = (pvo->pvo_pte.pte.pte_lo & LPTE_RPGN) | (va & ADDR_POFF); moea64_syncicache(pm, va, pa, len); } From 3c7ec531af323e21586d0b05c9fc35676b5d7eae Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 1 Apr 2010 13:27:27 +0000 Subject: [PATCH 1803/2592] MFC r204694,204719,205370 Update the page table locking for the 64-bit PMAP. One of these revisions largely reverted the other, so there is a small amount of churn and the addition of some mtx_assert()s. --- sys/powerpc/aim/mmu_oea64.c | 70 +++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 21aceb3d066..79763b63b00 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -327,7 +327,6 @@ SYSCTL_INT(_machdep, OID_AUTO, moea64_pvo_remove_calls, CTLFLAG_RD, &moea64_pvo_remove_calls, 0, ""); vm_offset_t moea64_scratchpage_va[2]; -struct pvo_entry *moea64_scratchpage_pvo[2]; struct lpte *moea64_scratchpage_pte[2]; struct mtx moea64_scratchpage_mtx; @@ -965,22 +964,36 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernele PMAP_UNLOCK(kernel_pmap); /* - * Allocate some things for page zeroing + * Allocate some things for page zeroing. We put this directly + * in the page table, marked with LPTE_LOCKED, to avoid any + * of the PVO book-keeping or other parts of the VM system + * from even knowing that this hack exists. */ mtx_init(&moea64_scratchpage_mtx, "pvo zero page", NULL, MTX_DEF); for (i = 0; i < 2; i++) { + struct lpte pt; + uint64_t vsid; + int pteidx, ptegidx; + moea64_scratchpage_va[i] = (virtual_end+1) - PAGE_SIZE; virtual_end -= PAGE_SIZE; - moea64_kenter(mmup,moea64_scratchpage_va[i],0); - LOCK_TABLE(); - moea64_scratchpage_pvo[i] = moea64_pvo_find_va(kernel_pmap, - moea64_scratchpage_va[i],&j); - moea64_scratchpage_pte[i] = moea64_pvo_to_pte( - moea64_scratchpage_pvo[i],j); - moea64_scratchpage_pte[i]->pte_hi |= LPTE_LOCKED; + + vsid = va_to_vsid(kernel_pmap, moea64_scratchpage_va[i]); + moea64_pte_create(&pt, vsid, moea64_scratchpage_va[i], + LPTE_NOEXEC); + pt.pte_hi |= LPTE_LOCKED; + + ptegidx = va_to_pteg(vsid, moea64_scratchpage_va[i]); + pteidx = moea64_pte_insert(ptegidx, &pt); + if (pt.pte_hi & LPTE_HID) + ptegidx ^= moea64_pteg_mask; + + moea64_scratchpage_pte[i] = + &moea64_pteg_table[ptegidx].pt[pteidx]; + UNLOCK_TABLE(); } @@ -1088,18 +1101,16 @@ moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired) static __inline void moea64_set_scratchpage_pa(int which, vm_offset_t pa) { - mtx_assert(&moea64_scratchpage_mtx, MA_OWNED); - moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo &= - ~(LPTE_WIMG | LPTE_RPGN); - moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo |= - moea64_calc_wimg(pa) | (uint64_t)pa; + mtx_assert(&moea64_scratchpage_mtx, MA_OWNED); moea64_scratchpage_pte[which]->pte_hi &= ~LPTE_VALID; TLBIE(kernel_pmap, moea64_scratchpage_va[which]); - moea64_scratchpage_pte[which]->pte_lo = - moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo; + moea64_scratchpage_pte[which]->pte_lo &= + ~(LPTE_WIMG | LPTE_RPGN); + moea64_scratchpage_pte[which]->pte_lo |= + moea64_calc_wimg(pa) | (uint64_t)pa; EIEIO(); moea64_scratchpage_pte[which]->pte_hi |= LPTE_VALID; @@ -1498,8 +1509,8 @@ moea64_remove_write(mmu_t mmu, vm_page_t m) LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) { pmap = pvo->pvo_pmap; PMAP_LOCK(pmap); + LOCK_TABLE(); if ((pvo->pvo_pte.lpte.pte_lo & LPTE_PP) != LPTE_BR) { - LOCK_TABLE(); pt = moea64_pvo_to_pte(pvo, -1); pvo->pvo_pte.lpte.pte_lo &= ~LPTE_PP; pvo->pvo_pte.lpte.pte_lo |= LPTE_BR; @@ -1510,8 +1521,8 @@ moea64_remove_write(mmu_t mmu, vm_page_t m) moea64_pte_change(pt, &pvo->pvo_pte.lpte, pvo->pvo_pmap, PVO_VADDR(pvo)); } - UNLOCK_TABLE(); } + UNLOCK_TABLE(); PMAP_UNLOCK(pmap); } if ((lo & LPTE_CHG) != 0) { @@ -1592,6 +1603,13 @@ moea64_kextract(mmu_t mmu, vm_offset_t va) struct pvo_entry *pvo; vm_paddr_t pa; + /* + * Shortcut the direct-mapped case when applicable. We never put + * anything but 1:1 mappings below VM_MIN_KERNEL_ADDRESS. + */ + if (va < VM_MIN_KERNEL_ADDRESS) + return (va); + PMAP_LOCK(kernel_pmap); pvo = moea64_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL); KASSERT(pvo != NULL, ("moea64_kextract: no addr found")); @@ -1649,9 +1667,11 @@ moea64_page_exists_quick(mmu_t mmu, pmap_t pmap, vm_page_t m) if (!moea64_initialized || (m->flags & PG_FICTITIOUS)) return FALSE; + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + loops = 0; LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) { - if (pvo->pvo_pmap == pmap) + if (pvo->pvo_pmap == pmap) return (TRUE); if (++loops >= 16) break; @@ -2045,7 +2065,7 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head, bootstrap = 1; } else { /* - * Note: drop the table around the UMA allocation in + * Note: drop the table lock 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. @@ -2129,7 +2149,6 @@ moea64_pvo_remove(struct pvo_entry *pvo, int pteidx) } else { moea64_pte_overflow--; } - UNLOCK_TABLE(); /* * Update our statistics. @@ -2161,9 +2180,12 @@ moea64_pvo_remove(struct pvo_entry *pvo, int pteidx) * if we aren't going to reuse it. */ LIST_REMOVE(pvo, pvo_olink); + UNLOCK_TABLE(); + if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP)) uma_zfree((pvo->pvo_vaddr & PVO_MANAGED) ? moea64_mpvo_zone : moea64_upvo_zone, pvo); + moea64_pvo_entries--; moea64_pvo_remove_calls++; } @@ -2312,6 +2334,8 @@ moea64_query_bit(vm_page_t m, u_int64_t ptebit) if (moea64_attr_fetch(m) & ptebit) return (TRUE); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) { MOEA_PVO_CHECK(pvo); /* sanity check */ @@ -2366,6 +2390,8 @@ moea64_clear_bit(vm_page_t m, u_int64_t ptebit, u_int64_t *origbit) struct lpte *pt; uint64_t rv; + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + /* * Clear the cached value. */ @@ -2398,10 +2424,10 @@ moea64_clear_bit(vm_page_t m, u_int64_t ptebit, u_int64_t *origbit) moea64_pte_clear(pt, pvo->pvo_pmap, PVO_VADDR(pvo), ptebit); } } - UNLOCK_TABLE(); rv |= pvo->pvo_pte.lpte.pte_lo; pvo->pvo_pte.lpte.pte_lo &= ~ptebit; MOEA_PVO_CHECK(pvo); /* sanity check */ + UNLOCK_TABLE(); } if (origbit != NULL) { From 618de50c3ffaa2f411010b8aba71b9648ed37c38 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Thu, 1 Apr 2010 15:17:50 +0000 Subject: [PATCH 1804/2592] MFC: r205409 - The firmware of Sun Fire V1280 has a misfeature of setting %wstate to 7 which corresponds to WSTATE_KMIX in OpenSolaris whenever calling into it which totally screws us even when restoring %wstate afterwards as spill/fill traps can happen while in OFW. The rather hackish OpenBSD approach of just setting the equivalent of WSTATE_KERNEL to 7 also is no option as we treat %wstate as a bit field. So in order to deal with this problem actually implement spill/fill handlers for %wstate 7 which just act as the WSTATE_KERNEL ones except of theoretically also handling 32-bit, turn off interrupts completely so we don't even take IPIs while in OFW which should ensure we only take spill/fill traps at most and restore %wstate after calling into OFW once we have taken over the trap table. While at it, actually set WSTATE_{,PROM}_KMIX before calling into OFW just like OpenSolaris does, which should at least help testing this change on non-V1280. - Remove comments referring to the %wstate usage in BSD/OS. - Remove the no longer used RSF_ALIGN_RETRY macro. - Correct some trap table addresses in comments. - Ensure %wstate is set to WSTATE_KERNEL when taking over the trap table. - Ensure PSTATE_AM is off when entering or exiting to OFW as well as that interrupts are also completely off when exiting to OFW as the firmware trap table shouldn't be used to handle our interrupts. --- sys/sparc64/include/wstate.h | 35 ++++------------------ sys/sparc64/sparc64/exception.S | 52 +++++++++++++++++++++++---------- sys/sparc64/sparc64/locore.S | 5 ++++ sys/sparc64/sparc64/machdep.c | 3 +- sys/sparc64/sparc64/support.S | 25 ++++++++++++---- 5 files changed, 69 insertions(+), 51 deletions(-) diff --git a/sys/sparc64/include/wstate.h b/sys/sparc64/include/wstate.h index 7ce0a495d5d..aae2fda9848 100644 --- a/sys/sparc64/include/wstate.h +++ b/sys/sparc64/include/wstate.h @@ -33,7 +33,7 @@ #define _MACHINE_WSTATE_H_ /* - * Window state register bits. + * Window state register bits * * There really are no bits per se, just the two fields WSTATE.NORMAL * and WSTATE.OTHER. The rest is up to software. @@ -42,37 +42,8 @@ * (whichever is currently in effect) and WSTATE_OTHER to represent * user mode saves (only). * - * We use the low bit to suggest 32-bit mode, with the next bit set - * once we succeed in saving in some mode. That is, if the WSTATE_ASSUME - * bit is set, the spill or fill handler we use will be one that makes - * an assumption about the proper window-save mode. If the spill or - * fill fails with an alignment fault, the spill or fill op should - * take the `assume' bit away retry the instruction that caused the - * spill or fill. This will use the new %wstate, which will test for - * which mode to use. The alignment fault code helps us out here by - * resuming the spill vector at offset +70, where we are allowed to - * execute two instructions (i.e., write to %wstate and RETRY). - * - * If the ASSUME bit is not set when the alignment fault occurs, the - * given stack pointer is hopelessly wrong (and the spill, if it is a - * spill, should be done as a sort of "panic spill") -- so those two - * instructions will be a branch sequence. - * * Note that locore.s assumes this same bit layout (since the translation * from "bits" to "{spill,fill}_N_{normal,other}" is done in hardware). - * - * The value 0 is preferred for unknown to make it easy to start in - * unknown state and continue in whichever state unknown succeeds in -- - * a successful "other" save, for instance, can just set %wstate to - * ASSUMExx << USERSHIFT and thus leave the kernel state "unknown". - * - * We also need values for managing the somewhat tricky transition from - * user to kernel and back, so we use the one remaining free bit to mean - * "although this looks like kernel mode, the window(s) involved are - * user windows and should be saved ASI_AIUP". Everything else is - * otherwise the same, but we need not bother with assumptions in this - * mode (we expect it to apply to at most one window spill or fill), - * i.e., WSTATE_TRANSITION can ignore WSTATE_ASSUME if it likes. */ #define WSTATE_NORMAL_MASK 1 /* wstate normal minus transition */ @@ -88,4 +59,8 @@ #define WSTATE_NESTED /* if set, spill must not fault */ \ (WSTATE_TRANSITION << WSTATE_OTHER_SHIFT) +/* Values used by the PROM and (Open)Solaris */ +#define WSTATE_PROM_KMIX 7 +#define WSTATE_PROM_MASK 7 + #endif /* !_MACHINE_WSTATE_H_ */ diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S index 5f81c0402af..a0f6f6ef842 100644 --- a/sys/sparc64/sparc64/exception.S +++ b/sys/sparc64/sparc64/exception.S @@ -315,15 +315,6 @@ END(tl1_kstack_fault) */ #define RSF_FILL_INC tl0_ret_fill_end - tl0_ret_fill -/* - * Retry a spill or fill with a different wstate due to an alignment fault. - * We may just be using the wrong stack offset. - */ -#define RSF_ALIGN_RETRY(ws) \ - wrpr %g0, (ws), %wstate ; \ - retry ; \ - .align 16 - /* * Generate a T_SPILL or T_FILL trap if the window operation fails. */ @@ -1716,6 +1707,19 @@ END(tl1_dmmu_prot_trap) RSF_SPILL_TOPCB .endm + .macro tl1_spill_7_n + btst 1, %sp + bnz,a,pn %xcc, tl1_spill_0_n + nop + srl %sp, 0, %sp + SPILL(stw, %sp, 4, EMPTY) + saved + retry + .align 32 + RSF_FATAL(T_SPILL) + RSF_FATAL(T_SPILL) + .endm + .macro tl1_spill_0_o wr %g0, ASI_AIUP, %asi SPILL(stxa, %sp + SPOFF, 8, %asi) @@ -1770,6 +1774,19 @@ END(tl1_dmmu_prot_trap) RSF_FILL_MAGIC .endm + .macro tl1_fill_7_n + btst 1, %sp + bnz,a,pt %xcc, tl1_fill_0_n + nop + srl %sp, 0, %sp + FILL(lduw, %sp, 4, EMPTY) + restored + retry + .align 32 + RSF_FATAL(T_FILL) + RSF_FATAL(T_FILL) + .endm + /* * This is used to spill windows that are still occupied with user * data on kernel entry to the pcb. @@ -2016,8 +2033,10 @@ tl1_spill_0_n: tl1_spill_2_n: tl1_spill_2_n ! 0x288 tl1_spill_3_n: - tl1_spill_3_n ! 0x29c - tl1_spill_bad 4 ! 0x290-0x29f + tl1_spill_3_n ! 0x28c + tl1_spill_bad 3 ! 0x290-0x29b +tl1_spill_7_n: + tl1_spill_7_n ! 0x29c tl1_spill_0_o: tl1_spill_0_o ! 0x2a0 tl1_spill_1_o: @@ -2029,10 +2048,13 @@ tl1_fill_0_n: tl1_fill_0_n ! 0x2c0 tl1_fill_bad 1 ! 0x2c4 tl1_fill_2_n: - tl1_fill_2_n ! 0x2d0 + tl1_fill_2_n ! 0x2c8 tl1_fill_3_n: - tl1_fill_3_n ! 0x2d4 - tl1_fill_bad 12 ! 0x2d8-0x2ff + tl1_fill_3_n ! 0x2cc + tl1_fill_bad 3 ! 0x2d0-0x2db +tl1_fill_7_n: + tl1_fill_7_n ! 0x2dc + tl1_fill_bad 8 ! 0x2e0-0x2ff tl1_reserved 1 ! 0x300 tl1_breakpoint: tl1_gen T_BREAKPOINT ! 0x301 @@ -2649,7 +2671,7 @@ END(tl0_ret) * Kernel trap entry point * * void tl1_trap(u_int type, u_long o1, u_long o2, u_long tar, u_long sfar, - * u_int sfsr) + * u_int sfsr) * * This is easy because the stack is already setup and the windows don't need * to be split. We build a trapframe and call trap(), the same as above, but diff --git a/sys/sparc64/sparc64/locore.S b/sys/sparc64/sparc64/locore.S index ac6659b5c97..a084a3884d2 100644 --- a/sys/sparc64/sparc64/locore.S +++ b/sys/sparc64/sparc64/locore.S @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "assym.s" @@ -139,8 +140,12 @@ ENTRY(cpu_setregs) * Force trap level 1 and take over the trap table. */ SET(tl0_base, %o2, %o1) + SET(tba_taken_over, %o3, %o2) + mov 1, %o3 + wrpr %g0, WSTATE_KERNEL, %wstate wrpr %g0, 1, %tl wrpr %o1, 0, %tba + stw %o3, [%o2] /* * Re-enable interrupts. diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index c5b08eea518..9eab20fce39 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -138,6 +138,7 @@ struct kva_md_info kmi; u_long ofw_vec; u_long ofw_tba; +u_int tba_taken_over; char sparc64_model[32]; @@ -466,7 +467,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) /* * Determine the TLB slot maxima, which are expected to be * equal across all CPUs. - * NB: for Cheetah-class CPUs, these properties only refer + * NB: for cheetah-class CPUs, these properties only refer * to the t16s. */ if (OF_getprop(pc->pc_node, "#dtlb-entries", &dtlb_slots, diff --git a/sys/sparc64/sparc64/support.S b/sys/sparc64/sparc64/support.S index 821e694f06e..d4ca5d332e8 100644 --- a/sys/sparc64/sparc64/support.S +++ b/sys/sparc64/sparc64/support.S @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "assym.s" @@ -751,11 +752,20 @@ ENTRY(ofw_entry) save %sp, -CCFSZ, %sp SET(ofw_vec, %l7, %l6) ldx [%l6], %l6 - rdpr %pil, %l7 - wrpr %g0, PIL_TICK, %pil - call %l6 + rdpr %pstate, %l7 + andn %l7, PSTATE_AM | PSTATE_IE, %l5 + wrpr %l5, 0, %pstate + SET(tba_taken_over, %l5, %l4) + brz,pn %l4, 1f + rdpr %wstate, %l5 + andn %l5, WSTATE_PROM_MASK, %l3 + wrpr %l3, WSTATE_PROM_KMIX, %wstate +1: call %l6 mov %i0, %o0 - wrpr %l7, 0, %pil + brz,pn %l4, 1f + nop + wrpr %g0, %l5, %wstate +1: wrpr %l7, 0, %pstate ret restore %o0, %g0, %o0 END(ofw_entry) @@ -766,9 +776,14 @@ END(ofw_entry) ENTRY(ofw_exit) save %sp, -CCFSZ, %sp flushw - wrpr %g0, PIL_TICK, %pil SET(ofw_tba, %l7, %l5) ldx [%l5], %l5 + rdpr %pstate, %l7 + andn %l7, PSTATE_AM | PSTATE_IE, %l7 + wrpr %l7, 0, %pstate + rdpr %wstate, %l7 + andn %l7, WSTATE_PROM_MASK, %l7 + wrpr %l7, WSTATE_PROM_KMIX, %wstate wrpr %l5, 0, %tba ! restore the OFW trap table SET(ofw_vec, %l7, %l6) ldx [%l6], %l6 From 01104d862b4b0a3232ab7094b005a9a14e36e559 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Thu, 1 Apr 2010 20:23:43 +0000 Subject: [PATCH 1805/2592] MFC 205077 The flow-table module retrieves the destination and source address as well as the transport protocol port information from the outbound packets. The routing code is generic and compares every byte in the given sockaddr object. Therefore the temporary sockaddr objects must be cleared due to padding bytes. In addition, the port information must be stripped or the route search will either fail or return the incorrect route entry. Unit testing is done using OpenVPN over the if_tun interface. --- sys/net/flowtable.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index cbdb8e584ca..0ad8a66788c 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -598,6 +598,8 @@ flowtable_lookup_mbuf4(struct flowtable *ft, struct mbuf *m) dsin = (struct sockaddr_in *)&dsa; ssin = (struct sockaddr_in *)&ssa; + bzero(dsin, sizeof(*dsin)); + bzero(ssin, sizeof(*ssin)); flags = ft->ft_flags; if (ipv4_mbuf_demarshal(ft, m, ssin, dsin, &flags) != 0) return (NULL); @@ -801,6 +803,8 @@ flowtable_lookup_mbuf6(struct flowtable *ft, struct mbuf *m) dsin6 = (struct sockaddr_in6 *)&dsa; ssin6 = (struct sockaddr_in6 *)&ssa; + bzero(dsin6, sizeof(*dsin6)); + bzero(ssin6, sizeof(*ssin6)); flags = ft->ft_flags; if (ipv6_mbuf_demarshal(ft, m, ssin6, dsin6, &flags) != 0) @@ -1130,6 +1134,14 @@ flowtable_lookup(struct flowtable *ft, struct sockaddr_storage *ssa, ro = &sro; memcpy(&ro->ro_dst, dsa, sizeof(struct sockaddr_in)); + /* + * The harvested source and destination addresses + * may contain port information if the packet is + * from a transport protocol (e.g. TCP/UDP). The + * port field must be cleared before performing + * a route lookup. + */ + ((struct sockaddr_in *)&ro->ro_dst)->sin_port = 0; dsin = (struct sockaddr_in *)dsa; ssin = (struct sockaddr_in *)ssa; if ((dsin->sin_addr.s_addr == ssin->sin_addr.s_addr) || @@ -1147,6 +1159,7 @@ flowtable_lookup(struct flowtable *ft, struct sockaddr_storage *ssa, ro = (struct route *)&sro6; memcpy(&sro6.ro_dst, dsa, sizeof(struct sockaddr_in6)); + ((struct sockaddr_in6 *)&ro->ro_dst)->sin6_port = 0; dsin6 = (struct sockaddr_in6 *)dsa; ssin6 = (struct sockaddr_in6 *)ssa; From ca2d42b2a1bb8cefb1c2bf163b67a0f2a062d4b2 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Fri, 2 Apr 2010 04:58:17 +0000 Subject: [PATCH 1806/2592] MFC 201131 introduce a local variable rte acting as a cache of ro->ro_rt within ip_output, achieving (in random order of importance): - a reduction of the number of 'r's in the source code; - improved legibility; - a reduction of 64 bytes in the .text --- sys/netinet/ip_output.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 2f4a356ed78..b665bc09330 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -128,6 +128,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, struct in_ifaddr *ia = NULL; int isbroadcast, sw_csum; struct route iproute; + struct rtentry *rte; /* cache for ro->ro_rt */ struct in_addr odst; #ifdef IPFIREWALL_FORWARD struct m_tag *fwd_tag = NULL; @@ -205,18 +206,19 @@ again: * The address family should also be checked in case of sharing the * cache with IPv6. */ - if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || + rte = ro->ro_rt; + if (rte && ((rte->rt_flags & RTF_UP) == 0 || dst->sin_family != AF_INET || dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { if (!nortfree) - RTFREE(ro->ro_rt); - ro->ro_rt = (struct rtentry *)NULL; + RTFREE(rte); + rte = ro->ro_rt = (struct rtentry *)NULL; ro->ro_lle = (struct llentry *)NULL; } #ifdef IPFIREWALL_FORWARD - if (ro->ro_rt == NULL && fwd_tag == NULL) { + if (rte == NULL && fwd_tag == NULL) { #else - if (ro->ro_rt == NULL) { + if (rte == NULL) { #endif bzero(dst, sizeof(*dst)); dst->sin_family = AF_INET; @@ -266,7 +268,7 @@ again: * as this is probably required in all cases for correct * operation (as it is for ARP). */ - if (ro->ro_rt == NULL) + if (rte == NULL) { #ifdef RADIX_MPATH rtalloc_mpath_fib(ro, ntohl(ip->ip_src.s_addr ^ ip->ip_dst.s_addr), @@ -275,7 +277,9 @@ again: in_rtalloc_ign(ro, 0, inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m)); #endif - if (ro->ro_rt == NULL) { + rte = ro->ro_rt; + } + if (rte == NULL) { #ifdef IPSEC /* * There is no route for this packet, but it is @@ -289,14 +293,14 @@ again: error = EHOSTUNREACH; goto bad; } - ia = ifatoia(ro->ro_rt->rt_ifa); + ia = ifatoia(rte->rt_ifa); ifa_ref(&ia->ia_ifa); - ifp = ro->ro_rt->rt_ifp; - ro->ro_rt->rt_rmx.rmx_pksent++; - if (ro->ro_rt->rt_flags & RTF_GATEWAY) - dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway; - if (ro->ro_rt->rt_flags & RTF_HOST) - isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST); + ifp = rte->rt_ifp; + rte->rt_rmx.rmx_pksent++; + if (rte->rt_flags & RTF_GATEWAY) + dst = (struct sockaddr_in *)rte->rt_gateway; + if (rte->rt_flags & RTF_HOST) + isbroadcast = (rte->rt_flags & RTF_BROADCAST); else isbroadcast = in_broadcast(dst->sin_addr, ifp); } @@ -304,7 +308,7 @@ again: * Calculate MTU. If we have a route that is up, use that, * otherwise use the interface's MTU. */ - if (ro->ro_rt != NULL && (ro->ro_rt->rt_flags & (RTF_UP|RTF_HOST))) { + if (rte != NULL && (rte->rt_flags & (RTF_UP|RTF_HOST))) { /* * This case can happen if the user changed the MTU * of an interface after enabling IP on it. Because @@ -312,9 +316,9 @@ again: * them, there is no way for one to update all its * routes when the MTU is changed. */ - if (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu) - ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu; - mtu = ro->ro_rt->rt_rmx.rmx_mtu; + if (rte->rt_rmx.rmx_mtu > ifp->if_mtu) + rte->rt_rmx.rmx_mtu = ifp->if_mtu; + mtu = rte->rt_rmx.rmx_mtu; } else { mtu = ifp->if_mtu; } From c951da56b4f19a637c7fdf734fc500560a9555de Mon Sep 17 00:00:00 2001 From: Qing Li Date: Fri, 2 Apr 2010 05:02:50 +0000 Subject: [PATCH 1807/2592] MFC 204902 One of the advantages of enabling ECMP (a.k.a RADIX_MPATH) is to allow for connection load balancing across interfaces. Currently the address alias handling method is colliding with the ECMP code. For example, when two interfaces are configured on the same prefix, only one prefix route is installed. So connection load balancing among the available interfaces is not possible. The other advantage of ECMP is for failover. The issue with the current code, is that the interface link-state is not reflected in the route entry. For example, if there are two interfaces on the same prefix, the cable on one interface is unplugged, new and existing connections should switch over to the other interface. This is not done today and packets go into a black hole. Also, there is a small bug in the kernel where deleting ECMP routes in the userland will always return an error even though the command is successfully executed. --- sys/net/flowtable.c | 3 ++- sys/net/radix.c | 2 ++ sys/net/radix_mpath.c | 3 ++- sys/net/route.c | 38 ++++++++++++++++++++++++++++++-------- sys/net/route.h | 2 ++ sys/netinet/in.c | 8 ++++++++ sys/netinet/ip_output.c | 6 +++++- 7 files changed, 51 insertions(+), 11 deletions(-) diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index 0ad8a66788c..39b6b40a996 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -870,7 +870,8 @@ flow_stale(struct flowtable *ft, struct flentry *fle) || ((fle->f_rt->rt_flags & RTF_HOST) && ((fle->f_rt->rt_flags & (RTF_UP)) != (RTF_UP))) - || (fle->f_rt->rt_ifp == NULL)) + || (fle->f_rt->rt_ifp == NULL) + || !RT_LINK_IS_UP(fle->f_rt->rt_ifp)) return (1); idle_time = time_uptime - fle->f_uptime; diff --git a/sys/net/radix.c b/sys/net/radix.c index 9f2383d7c7c..33fcf828a24 100644 --- a/sys/net/radix.c +++ b/sys/net/radix.c @@ -761,8 +761,10 @@ on2: if (m->rm_flags & RNF_NORMAL) { mmask = m->rm_leaf->rn_mask; if (tt->rn_flags & RNF_NORMAL) { +#if !defined(RADIX_MPATH) log(LOG_ERR, "Non-unique normal route, mask not entered\n"); +#endif return tt; } } else diff --git a/sys/net/radix_mpath.c b/sys/net/radix_mpath.c index 9be01d2fe3c..ea84e5ce228 100644 --- a/sys/net/radix_mpath.c +++ b/sys/net/radix_mpath.c @@ -270,7 +270,8 @@ rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum) * XXX we don't attempt to lookup cached route again; what should * be done for sendto(3) case? */ - if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP)) + if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP) + && RT_LINK_IS_UP(ro->ro_rt->rt_ifp)) return; ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, 0, fibnum); diff --git a/sys/net/route.c b/sys/net/route.c index a938c9c1b7f..e500ed13033 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -830,7 +830,13 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum) int rtexpunge(struct rtentry *rt) { +#if !defined(RADIX_MPATH) struct radix_node *rn; +#else + struct rt_addrinfo info; + int fib; + struct rtentry *rt0; +#endif struct radix_node_head *rnh; struct ifaddr *ifa; int error = 0; @@ -843,14 +849,26 @@ rtexpunge(struct rtentry *rt) if (rnh == NULL) return (EAFNOSUPPORT); RADIX_NODE_HEAD_LOCK_ASSERT(rnh); -#if 0 - /* - * We cannot assume anything about the reference count - * because protocols call us in many situations; often - * before unwinding references to the table entry. - */ - KASSERT(rt->rt_refcnt <= 1, ("bogus refcnt %ld", rt->rt_refcnt)); -#endif + +#ifdef RADIX_MPATH + fib = rt->rt_fibnum; + bzero(&info, sizeof(info)); + info.rti_ifp = rt->rt_ifp; + info.rti_flags = RTF_RNH_LOCKED; + info.rti_info[RTAX_DST] = rt_key(rt); + info.rti_info[RTAX_GATEWAY] = rt->rt_ifa->ifa_addr; + + RT_UNLOCK(rt); + error = rtrequest1_fib(RTM_DELETE, &info, &rt0, fib); + + if (error == 0 && rt0 != NULL) { + rt = rt0; + RT_LOCK(rt); + } else if (error != 0) { + RT_LOCK(rt); + return (error); + } +#else /* * Remove the item from the tree; it should be there, * but when callers invoke us blindly it may not (sigh). @@ -864,6 +882,7 @@ rtexpunge(struct rtentry *rt) ("unexpected flags 0x%x", rn->rn_flags)); KASSERT(rt == RNTORT(rn), ("lookup mismatch, rt %p rn %p", rt, rn)); +#endif /* RADIX_MPATH */ rt->rt_flags &= ~RTF_UP; @@ -886,7 +905,9 @@ rtexpunge(struct rtentry *rt) * linked to the routing table. */ V_rttrash++; +#if !defined(RADIX_MPATH) bad: +#endif return (error); } @@ -1044,6 +1065,7 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, */ if (error != ENOENT) goto bad; + error = 0; } #endif /* diff --git a/sys/net/route.h b/sys/net/route.h index 4cf8a816466..6857cb3473d 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -319,6 +319,8 @@ struct rt_addrinfo { #ifdef _KERNEL +#define RT_LINK_IS_UP(ifp) ((ifp)->if_link_state == LINK_STATE_UP) + #define RT_LOCK_INIT(_rt) \ mtx_init(&(_rt)->rt_mtx, "rtentry", NULL, MTX_DEF | MTX_DUPOK) #define RT_LOCK(_rt) mtx_lock(&(_rt)->rt_mtx) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 91de6332ab4..c50a13fb2b4 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include "opt_carp.h" +#include "opt_mpath.h" #include #include @@ -1040,6 +1041,13 @@ in_addprefix(struct in_ifaddr *target, int flags) * interface address, we are done here. */ if (ia->ia_flags & IFA_ROUTE) { +#ifdef RADIX_MPATH + if (ia->ia_addr.sin_addr.s_addr == + target->ia_addr.sin_addr.s_addr) + return (EEXIST); + else + break; +#endif if (V_sameprefixcarponly && target->ia_ifp->if_type != IFT_CARP && ia->ia_ifp->if_type != IFT_CARP) { diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index b665bc09330..00c3c3ceacf 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -208,6 +208,8 @@ again: */ rte = ro->ro_rt; if (rte && ((rte->rt_flags & RTF_UP) == 0 || + rte->rt_ifp == NULL || + !RT_LINK_IS_UP(rte->rt_ifp) || dst->sin_family != AF_INET || dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { if (!nortfree) @@ -279,7 +281,9 @@ again: #endif rte = ro->ro_rt; } - if (rte == NULL) { + if (rte == NULL || + rte->rt_ifp == NULL || + !RT_LINK_IS_UP(rte->rt_ifp)) { #ifdef IPSEC /* * There is no route for this packet, but it is From 243785f92f3510b8e7115b3775e82bb0f4dd4da7 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Fri, 2 Apr 2010 05:05:51 +0000 Subject: [PATCH 1808/2592] MFC 205024 The if_tap interface is of IFT_ETHERNET type, but it does not set or update the if_link_state variable. As such RT_LINK_IS_UP() fails for the if_tap interface. Also, the RT_LINK_IS_UP() needs to bypass all loopback interfaces because loopback interfaces are considered up logically as long as the system is running. This patch fixes the above issues by setting and updating the if_link_state variable when the tap interface is opened or closed respectively. Similary approach is already done in the if_tun device. --- sys/net/if_tap.c | 2 ++ sys/net/route.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c index 93801f10412..9123e8c85aa 100644 --- a/sys/net/if_tap.c +++ b/sys/net/if_tap.c @@ -502,6 +502,7 @@ tapopen(struct cdev *dev, int flag, int mode, struct thread *td) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; if (tapuponopen) ifp->if_flags |= IFF_UP; + if_link_state_change(ifp, LINK_STATE_UP); splx(s); TAPDEBUG("%s is open. minor = %#x\n", ifp->if_xname, dev2unit(dev)); @@ -547,6 +548,7 @@ tapclose(struct cdev *dev, int foo, int bar, struct thread *td) } else mtx_unlock(&tp->tap_mtx); + if_link_state_change(ifp, LINK_STATE_DOWN); funsetown(&tp->tap_sigio); selwakeuppri(&tp->tap_rsel, PZERO+1); KNOTE_UNLOCKED(&tp->tap_rsel.si_note, 0); diff --git a/sys/net/route.h b/sys/net/route.h index 6857cb3473d..66f56b7c93c 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -319,7 +319,9 @@ struct rt_addrinfo { #ifdef _KERNEL -#define RT_LINK_IS_UP(ifp) ((ifp)->if_link_state == LINK_STATE_UP) +#define RT_LINK_IS_UP(ifp) (((ifp)->if_flags & \ + (IFF_LOOPBACK | IFF_POINTOPOINT)) \ + || (ifp)->if_link_state == LINK_STATE_UP) #define RT_LOCK_INIT(_rt) \ mtx_init(&(_rt)->rt_mtx, "rtentry", NULL, MTX_DEF | MTX_DUPOK) From 94190b3925795b145fbd1fbc39df0841ef52f5d5 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Fri, 2 Apr 2010 05:12:46 +0000 Subject: [PATCH 1809/2592] MFC 205222 Verify interface up status using its link state only if the interface has such capability. The interface capability flag indicates whether such capability exists. This approach is much more backward compatible. Physical device driver changes will be part of another commit. Also updated the ifconfig utility to show the LINKSTATE capability if present. Reviewed by: rwatson, imp, juli --- sbin/ifconfig/ifconfig.c | 2 +- sys/net/if.h | 1 + sys/net/if_tap.c | 2 ++ sys/net/if_tun.c | 2 ++ sys/net/route.h | 3 +-- 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 45c6d40e047..e46dcdb873d 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -865,7 +865,7 @@ unsetifdescr(const char *val, int value, int s, const struct afswtch *afp) #define IFCAPBITS \ "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \ "\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \ -"\21VLAN_HWFILTER\23VLAN_HWTSO" +"\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE" /* * Print the status of the interface. If an address family was diff --git a/sys/net/if.h b/sys/net/if.h index e226654b34b..ae0daf5b639 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -219,6 +219,7 @@ struct if_data { #define IFCAP_VLAN_HWFILTER 0x10000 /* interface hw can filter vlan tag */ #define IFCAP_POLLING_NOCOUNT 0x20000 /* polling ticks cannot be fragmented */ #define IFCAP_VLAN_HWTSO 0x40000 /* can do IFCAP_TSO on VLANs */ +#define IFCAP_LINKSTATE 0x80000 /* the runtime link state is dynamic */ #define IFCAP_HWCSUM (IFCAP_RXCSUM | IFCAP_TXCSUM) #define IFCAP_TSO (IFCAP_TSO4 | IFCAP_TSO6) diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c index 9123e8c85aa..eb81e816dd9 100644 --- a/sys/net/if_tap.c +++ b/sys/net/if_tap.c @@ -443,6 +443,8 @@ tapcreate(struct cdev *dev) ifp->if_mtu = ETHERMTU; ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); ifp->if_snd.ifq_maxlen = ifqmaxlen; + ifp->if_capabilities |= IFCAP_LINKSTATE; + ifp->if_capenable |= IFCAP_LINKSTATE; dev->si_drv1 = tp; tp->tap_dev = dev; diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index 1fa02ac9f11..1da63ba3765 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -386,6 +386,8 @@ tuncreate(const char *name, struct cdev *dev) ifp->if_snd.ifq_drv_maxlen = 0; IFQ_SET_READY(&ifp->if_snd); knlist_init_mtx(&sc->tun_rsel.si_note, NULL); + ifp->if_capabilities |= IFCAP_LINKSTATE; + ifp->if_capenable |= IFCAP_LINKSTATE; if_attach(ifp); bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); diff --git a/sys/net/route.h b/sys/net/route.h index 66f56b7c93c..4014b3f64dd 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -319,8 +319,7 @@ struct rt_addrinfo { #ifdef _KERNEL -#define RT_LINK_IS_UP(ifp) (((ifp)->if_flags & \ - (IFF_LOOPBACK | IFF_POINTOPOINT)) \ +#define RT_LINK_IS_UP(ifp) (!((ifp)->if_capabilities & IFCAP_LINKSTATE) \ || (ifp)->if_link_state == LINK_STATE_UP) #define RT_LOCK_INIT(_rt) \ From f3939d3288738bb2cb5ed779a0939878f569dabd Mon Sep 17 00:00:00 2001 From: Qing Li Date: Fri, 2 Apr 2010 05:15:27 +0000 Subject: [PATCH 1810/2592] MFC 205268 Set the device capabilities to include dynamic link-state for those modern drivers. Reviewed by: imp (and suggested by imp) --- sys/dev/mii/mii.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/mii/mii.c b/sys/dev/mii/mii.c index 065bc5de4f1..311fb464585 100644 --- a/sys/dev/mii/mii.c +++ b/sys/dev/mii/mii.c @@ -180,6 +180,8 @@ miibus_attach(device_t dev) * XXX: EVIL HACK! */ mii->mii_ifp = *(struct ifnet**)device_get_softc(device_get_parent(dev)); + mii->mii_ifp->if_capabilities |= IFCAP_LINKSTATE; + mii->mii_ifp->if_capenable |= IFCAP_LINKSTATE; ivars = device_get_ivars(dev); ifmedia_init(&mii->mii_media, IFM_IMASK, ivars->ifmedia_upd, ivars->ifmedia_sts); From 033a5be7fa5f2de760ce40e5c2557eaf683f6531 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 2 Apr 2010 11:07:55 +0000 Subject: [PATCH 1811/2592] Merge r205082, r205083 that fix 'netstat -f netgraph' functionality. --- sys/netgraph/ng_socket.c | 21 +++++++++++++++++++++ sys/netgraph/ng_socketvar.h | 1 + usr.bin/netstat/netgraph.c | 6 +++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index af68c636d9b..28e4f0e2248 100644 --- a/sys/netgraph/ng_socket.c +++ b/sys/netgraph/ng_socket.c @@ -156,6 +156,11 @@ static u_long ngpdg_recvspace = 20 * 1024; SYSCTL_INT(_net_graph, OID_AUTO, recvspace, CTLFLAG_RW, &ngpdg_recvspace , 0, "Maximum space for incoming Netgraph datagrams"); +/* List of all sockets (for netstat -f netgraph) */ +static LIST_HEAD(, ngpcb) ngsocklist; + +static struct mtx ngsocketlist_mtx; + #define sotongpcb(so) ((struct ngpcb *)(so)->so_pcb) /* If getting unexplained errors returned, set this to "kdb_enter("X"); */ @@ -547,6 +552,9 @@ ng_attach_cntl(struct socket *so) return (error); } + /* Store a hint for netstat(1). */ + priv->node_id = priv->node->nd_ID; + /* Link the node and the private data. */ NG_NODE_SET_PRIVATE(priv->node, priv); NG_NODE_REF(priv->node); @@ -584,6 +592,10 @@ ng_attach_common(struct socket *so, int type) so->so_pcb = (caddr_t)pcbp; pcbp->ng_socket = so; + /* Add the socket to linked list */ + mtx_lock(&ngsocketlist_mtx); + LIST_INSERT_HEAD(&ngsocklist, pcbp, socks); + mtx_unlock(&ngsocketlist_mtx); return (0); } @@ -617,6 +629,9 @@ ng_detach_common(struct ngpcb *pcbp, int which) } pcbp->ng_socket->so_pcb = NULL; + mtx_lock(&ngsocketlist_mtx); + LIST_REMOVE(pcbp, socks); + mtx_unlock(&ngsocketlist_mtx); free(pcbp, M_PCB); } @@ -1115,8 +1130,14 @@ ngs_mod_event(module_t mod, int event, void *data) switch (event) { case MOD_LOAD: + mtx_init(&ngsocketlist_mtx, "ng_socketlist", NULL, MTX_DEF); break; case MOD_UNLOAD: + /* Ensure there are no open netgraph sockets. */ + if (!LIST_EMPTY(&ngsocklist)) { + error = EBUSY; + break; + } #ifdef NOTYET /* Unregister protocol domain XXX can't do this yet.. */ #endif diff --git a/sys/netgraph/ng_socketvar.h b/sys/netgraph/ng_socketvar.h index 3cf81035541..c1e59dcf8a2 100644 --- a/sys/netgraph/ng_socketvar.h +++ b/sys/netgraph/ng_socketvar.h @@ -61,6 +61,7 @@ struct ngsock { int refs; struct mtx mtx; /* mtx to wait on */ int error; /* place to store error */ + ng_ID_t node_id; /* a hint for netstat(1) to find the node */ }; #define NGS_FLAG_NOLINGER 1 /* close with last hook */ diff --git a/usr.bin/netstat/netgraph.c b/usr.bin/netstat/netgraph.c index c4dd647eb6f..d51041446ec 100644 --- a/usr.bin/netstat/netgraph.c +++ b/usr.bin/netstat/netgraph.c @@ -166,14 +166,14 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused, name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); /* Get ngsock structure */ - if (ngpcb.sockdata == 0) /* unconnected data socket */ + if (ngpcb.sockdata == NULL) /* unconnected data socket */ goto finish; kread((u_long)ngpcb.sockdata, (char *)&info, sizeof(info)); /* Get info on associated node */ - if (info.node == 0 || csock == -1) + if (info.node_id == 0 || csock == -1) goto finish; - snprintf(path, sizeof(path), "[%lx]:", (u_long) info.node); + snprintf(path, sizeof(path), "[%x]:", info.node_id); if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0) goto finish; From 131e8de2daa52358886fbb09e47bd9bbf76297f4 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 2 Apr 2010 13:39:30 +0000 Subject: [PATCH 1812/2592] MFC r205316: Fix two style issues. --- sys/kern/uipc_syscalls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index a4857ced2d7..a809be9b0c8 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -2528,7 +2528,7 @@ sctp_generic_sendmsg_iov(td, uap) goto sctp_bad; #endif /* MAC */ - auio.uio_iov = iov; + auio.uio_iov = iov; auio.uio_iovcnt = uap->iovlen; auio.uio_segflg = UIO_USERSPACE; auio.uio_rw = UIO_WRITE; @@ -2638,7 +2638,7 @@ sctp_generic_recvmsg(td, uap) } else { fromlen = 0; } - if(uap->msg_flags) { + if (uap->msg_flags) { error = copyin(uap->msg_flags, &msg_flags, sizeof (int)); if (error) { goto out; From 003465f5f10d759736e0523592d0a9927ef36442 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 2 Apr 2010 13:43:16 +0000 Subject: [PATCH 1813/2592] MFC r205317: Remove dead statement. --- sys/kern/uipc_syscalls.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index a809be9b0c8..093107fad0f 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -2625,7 +2625,6 @@ sctp_generic_recvmsg(td, uap) error = mac_socket_check_receive(td->td_ucred, so); if (error) { goto out; - return (error); } #endif /* MAC */ From 32a9ef6d336ea36e67b09755676dc782eb4ec0af Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Fri, 2 Apr 2010 15:33:24 +0000 Subject: [PATCH 1814/2592] MFC r205854: calendar.freebsd: add my entry --- 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 6d56e5f37d9..54d17af4275 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -205,6 +205,7 @@ 07/23 Sergey A. Osokin born in Krasnogorsky, Stepnogorsk, Akmolinskaya region, Kazakhstan, 1972 07/24 Alexander Nedotsukov born in Ulyanovsk, Russian Federation, 1974 07/24 Alberto Villa born in Vercelli, Italy, 1987 +07/27 Andriy Gapon born in Kyrykivka, Sumy region, Ukraine, 1976 07/28 Jim Mock born in Bethlehem, Pennsylvania, United States, 1974 07/28 Tom Hukins born in Manchester, United Kingdom, 1976 07/29 Dirk Meyer born in Kassel, Hessen, Germany, 1965 From ac28297bcea1608c1c81628874c5766007fb2d0a Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 2 Apr 2010 17:48:01 +0000 Subject: [PATCH 1815/2592] MFC r205789: When tearing down IPsec as part of a (virtual) network stack, do not try to free the same list twice but free both the acquiring list and the security policy acquiring list. Reviewed by: anchie --- sys/netipsec/key.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 99dce21b2f2..5d08c9cd6f0 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -7787,7 +7787,8 @@ void key_destroy(void) { struct secpolicy *sp, *nextsp; - struct secspacq *acq, *nextacq; + struct secacq *acq, *nextacq; + struct secspacq *spacq, *nextspacq; struct secashead *sah, *nextsah; struct secreg *reg; int i; @@ -7828,7 +7829,7 @@ key_destroy(void) REGTREE_UNLOCK(); ACQ_LOCK(); - for (acq = LIST_FIRST(&V_spacqtree); acq != NULL; acq = nextacq) { + for (acq = LIST_FIRST(&V_acqtree); acq != NULL; acq = nextacq) { nextacq = LIST_NEXT(acq, chain); if (__LIST_CHAINED(acq)) { LIST_REMOVE(acq, chain); @@ -7838,11 +7839,12 @@ key_destroy(void) ACQ_UNLOCK(); SPACQ_LOCK(); - for (acq = LIST_FIRST(&V_spacqtree); acq != NULL; acq = nextacq) { - nextacq = LIST_NEXT(acq, chain); - if (__LIST_CHAINED(acq)) { - LIST_REMOVE(acq, chain); - free(acq, M_IPSEC_SAQ); + for (spacq = LIST_FIRST(&V_spacqtree); spacq != NULL; + spacq = nextspacq) { + nextspacq = LIST_NEXT(spacq, chain); + if (__LIST_CHAINED(spacq)) { + LIST_REMOVE(spacq, chain); + free(spacq, M_IPSEC_SAQ); } } SPACQ_UNLOCK(); From 22177b727962bdbbf719ed05a07a09886df31b26 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 2 Apr 2010 17:52:50 +0000 Subject: [PATCH 1816/2592] MFC r205637: We are holding a write lock here so avoid aquiring it twice calling the "locked" version rather than the wrapper function. --- 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 4c941da2c77..488a60abbc8 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1167,7 +1167,7 @@ nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force) ln->ln_state = ND6_LLINFO_REACHABLE; if (!ND6_LLINFO_PERMANENT(ln)) { - nd6_llinfo_settimer(ln, + nd6_llinfo_settimer_locked(ln, (long)ND_IFINFO(rt->rt_ifp)->reachable * hz); } done: From caa4eaacd7858f5474c336539b168f306989a002 Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Sat, 3 Apr 2010 07:12:35 +0000 Subject: [PATCH 1817/2592] MFC r205998: If there is multiple PMCs for the same interrupt ignore new post. This will indirectly fix a bug where the thread will be pinned forever if the assert is not compiled. --- sys/dev/hwpmc/hwpmc_mod.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index f35e11da872..2ecebefa65b 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -3972,9 +3972,11 @@ pmc_post_callchain_callback(void) td = curthread; - KASSERT((td->td_pflags & TDP_CALLCHAIN) == 0, - ("[pmc,%d] thread %p already marked for callchain capture", - __LINE__, (void *) td)); + /* + * If there is multiple PMCs for the same interrupt ignore new post + */ + if (td->td_pflags & TDP_CALLCHAIN) + return; /* * Mark this thread as needing callchain capture. From c7014073a8247f6dccb1dedc421e2ed5d881b1c2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 3 Apr 2010 15:43:28 +0000 Subject: [PATCH 1818/2592] MFC r205652 A ptrace(2) by one process may trigger a page size promotion in the address space of another process. Modify pmap_promote_pde() to handle this. --- sys/i386/i386/pmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index d4dea040d58..5248aca95ae 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -2999,7 +2999,7 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) * either invalid, unused, or does not map the first 4KB physical page * within a 2- or 4MB page. */ - firstpte = vtopte(trunc_4mpage(va)); + firstpte = pmap_pte_quick(pmap, trunc_4mpage(va)); setpde: newpde = *firstpte; if ((newpde & ((PG_FRAME & PDRMASK) | PG_A | PG_V)) != (PG_A | PG_V)) { From cdf8665e67ce92d1b60f9a4310dbadc0deeef1df Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sun, 4 Apr 2010 14:57:46 +0000 Subject: [PATCH 1819/2592] MFC: r205269 o Add support for UltraSparc-IV+: - Swap the configuration of the first and second large dTLB as with US-IV+ these can only hold entries of certain page sizes each, which we happened to chose the non-working way around. - Additionally ensure that the large iTLB is set up to hold 8k pages (currently this happens to be a NOP though). - Add a workaround for US-IV+ erratum #2. - Turn off dTLB parity error reporting as otherwise we get seemingly false positives when copying in the user window by simulating a fill trap on return to usermode. Given that these parity errors can be avoided by disabling multi issue mode and the problem could be reproduced with a second machine this appears to be a silicon bug of some sort. - Add a membar #Sync also before the stores to ASI_DCACHE_TAG. While at it, turn of interrupts across the whole cheetah_cache_flush() for simplicity instead of around every flush. This should have next to no impact as for cheetah-class machines we typically only need to flush the caches a few times during boot when recovering from peeking/poking non-existent PCI devices, if at all. - Just use KERNBASE for FLUSH as we also do elsewhere as the US-IV+ documentation doesn't seem to mention that these CPUs also ignore the address like previous cheetah-class CPUs do. Again the code changing LSU_IC is executed seldom enough that the negligible optimization of using %g0 instead should have no real impact. With these changes FreeBSD runs stable on V890 equipped with US-IV+ and -j128 buildworlds in a loop for days are no problem. Unfortunately, the performance isn't were it should be as a buildworld on a 4x1.5GHz US-IV+ V890 takes nearly 3h while on a V440 with (theoretically) less powerfull 4x1.5GHz US-IIIi it takes just over 1h. It's unclear whether this is related to the supposed silicon bug mentioned above or due to another issue. The documentation (which contains a sever bug in the description of the bits added to the context registers though) at least doesn't mention any requirements for changes in the CPU handling besides those implemented and the cache as well as the TLB configurations and handling look fine. o Re-arrange cheetah_init() so it's easier to add support for SPARC64 V up to VIIIfx CPUs, which only require parts of this initialization. Committed from: EH2010 --- sys/sparc64/include/dcr.h | 4 ++ sys/sparc64/sparc64/cheetah.c | 107 +++++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 34 deletions(-) diff --git a/sys/sparc64/include/dcr.h b/sys/sparc64/include/dcr.h index a885d050fb9..b1f993a0609 100644 --- a/sys/sparc64/include/dcr.h +++ b/sys/sparc64/include/dcr.h @@ -57,6 +57,10 @@ #define DCR_BPM_BITS 2 #define DCR_BPM_MASK \ (((1UL << DCR_BPM_BITS) - 1) << DCR_BPM_SHIFT) +#define DCR_BPM_1HIST_GSHARE (0UL << DCR_BPM_SHIFT) +#define DCR_BPM_2HIST_GSHARE (1UL << DCR_BPM_SHIFT) +#define DCR_BPM_PC (2UL << DCR_BPM_SHIFT) +#define DCR_BPM_2HIST_MIXED (3UL << DCR_BPM_SHIFT) #define DCR_JPE (1UL << 15) #define DCR_ITPE (1UL << 16) diff --git a/sys/sparc64/sparc64/cheetah.c b/sys/sparc64/sparc64/cheetah.c index ae24744c9ed..a99a70ca39b 100644 --- a/sys/sparc64/sparc64/cheetah.c +++ b/sys/sparc64/sparc64/cheetah.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2003 Jake Burkholder. - * Copyright (c) 2005, 2008 Marius Strobl + * Copyright (c) 2005, 2008, 2010 Marius Strobl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,9 +49,6 @@ __FBSDID("$FreeBSD$"); #include #include -/* A FLUSH is required after changing LSU_IC (the address is ignored). */ -#define CHEETAH_FLUSH_LSU_IC() __asm __volatile("flush %%g0" : :) - #define CHEETAH_ICACHE_TAG_LOWER 0x30 /* @@ -60,6 +57,7 @@ __FBSDID("$FreeBSD$"); void cheetah_init(u_int cpu_impl) { + u_long val; register_t s; /* @@ -68,14 +66,6 @@ cheetah_init(u_int cpu_impl) */ s = intr_disable(); - /* - * Ensure DCR_IFPOE is disabled as long as we haven't implemented - * support for it (if ever) as most if not all firmware versions - * apparently turn it on. Not making use of DCR_IFPOE should also - * avoid Cheetah erratum #109. - */ - wr(asr18, rd(asr18) & ~DCR_IFPOE, 0); - /* Ensure the TSB Extension Registers hold 0 as TSB_Base. */ stxa(AA_DMMU_TSB_PEXT_REG, ASI_DMMU, 0); @@ -93,25 +83,58 @@ cheetah_init(u_int cpu_impl) membar(Sync); /* - * Ensure that the dt512_0 is set to hold 8k pages for all three - * contexts and configure the dt512_1 to hold 4MB pages for them - * (e.g. for direct mappings). - * NB: according to documentation, this requires a contex demap - * _before_ changing the corresponding page size, but we hardly - * can flush our locked pages here, so we use a demap all instead. + * Configure the first large dTLB to hold 4MB pages (e.g. for direct + * mappings) for all three contexts and ensure the second one is set + * up to hold 8k pages for them. Note that this is constraint by + * US-IV+, whose large dTLBs can only hold entries of certain page + * sizes each. + * For US-IV+, additionally ensure that the large iTLB is set up to + * hold 8k pages for nucleus and primary context (still no secondary + * iMMU context. + * NB: according to documentation, changing the page size of the same + * context requires a context demap before changing the corresponding + * page size, but we hardly can flush our locked pages here, so we use + * a demap all instead. */ stxa(TLB_DEMAP_ALL, ASI_DMMU_DEMAP, 0); membar(Sync); - stxa(AA_DMMU_PCXR, ASI_DMMU, - (TS_8K << TLB_PCXR_N_PGSZ0_SHIFT) | - (TS_4M << TLB_PCXR_N_PGSZ1_SHIFT) | - (TS_8K << TLB_PCXR_P_PGSZ0_SHIFT) | - (TS_4M << TLB_PCXR_P_PGSZ1_SHIFT)); - stxa(AA_DMMU_SCXR, ASI_DMMU, - (TS_8K << TLB_SCXR_S_PGSZ0_SHIFT) | - (TS_4M << TLB_SCXR_S_PGSZ1_SHIFT)); + val = (TS_4M << TLB_PCXR_N_PGSZ0_SHIFT) | + (TS_8K << TLB_PCXR_N_PGSZ1_SHIFT) | + (TS_4M << TLB_PCXR_P_PGSZ0_SHIFT) | + (TS_8K << TLB_PCXR_P_PGSZ1_SHIFT); + if (cpu_impl == CPU_IMPL_ULTRASPARCIVp) + val |= (TS_8K << TLB_PCXR_N_PGSZ_I_SHIFT) | + (TS_8K << TLB_PCXR_P_PGSZ_I_SHIFT); + stxa(AA_DMMU_PCXR, ASI_DMMU, val); + val = (TS_4M << TLB_SCXR_S_PGSZ0_SHIFT) | + (TS_8K << TLB_SCXR_S_PGSZ1_SHIFT); + stxa(AA_DMMU_SCXR, ASI_DMMU, val); flush(KERNBASE); + /* + * Ensure DCR_IFPOE is disabled as long as we haven't implemented + * support for it (if ever) as most if not all firmware versions + * apparently turn it on. Not making use of DCR_IFPOE should also + * avoid Cheetah erratum #109. + */ + val = rd(asr18) & ~DCR_IFPOE; + if (cpu_impl == CPU_IMPL_ULTRASPARCIVp) { + /* + * Ensure the branch prediction mode is set to PC indexing + * in order to work around US-IV+ erratum #2. + */ + val = (val & ~DCR_BPM_MASK) | DCR_BPM_PC; + /* + * XXX disable dTLB parity error reporting as otherwise we + * get seemingly false positives when copying in the user + * window by simulating a fill trap on return to usermode in + * case single issue is disabled, which thus appears to be + * a CPU bug. + */ + val &= ~DCR_DTPE; + } + wr(asr18, val, 0); + intr_restore(s); } @@ -125,11 +148,11 @@ cheetah_cache_enable(u_int cpu_impl) lsu = ldxa(0, ASI_LSU_CTL_REG); if (cpu_impl == CPU_IMPL_ULTRASPARCIII) { - /* Disable P$ due to Cheetah erratum #18. */ + /* Disable P$ due to US-III erratum #18. */ lsu &= ~LSU_PE; } stxa(0, ASI_LSU_CTL_REG, lsu | LSU_IC | LSU_DC); - CHEETAH_FLUSH_LSU_IC(); + flush(KERNBASE); } /* @@ -139,21 +162,35 @@ void cheetah_cache_flush(void) { u_long addr, lsu; + register_t s; + s = intr_disable(); for (addr = 0; addr < PCPU_GET(cache.dc_size); addr += PCPU_GET(cache.dc_linesize)) - stxa_sync(addr, ASI_DCACHE_TAG, 0); + /* + * Note that US-IV+ additionally require a membar #Sync before + * a load or store to ASI_DCACHE_TAG. + */ + __asm __volatile( + "membar #Sync;" + "stxa %%g0, [%0] %1;" + "membar #Sync" + : : "r" (addr), "n" (ASI_DCACHE_TAG)); /* The I$ must be disabled when flushing it so ensure it's off. */ lsu = ldxa(0, ASI_LSU_CTL_REG); stxa(0, ASI_LSU_CTL_REG, lsu & ~(LSU_IC)); - CHEETAH_FLUSH_LSU_IC(); + flush(KERNBASE); for (addr = CHEETAH_ICACHE_TAG_LOWER; addr < PCPU_GET(cache.ic_size) * 2; addr += PCPU_GET(cache.ic_linesize) * 2) - stxa_sync(addr, ASI_ICACHE_TAG, 0); + __asm __volatile( + "stxa %%g0, [%0] %1;" + "membar #Sync" + : : "r" (addr), "n" (ASI_ICACHE_TAG)); stxa(0, ASI_LSU_CTL_REG, lsu); - CHEETAH_FLUSH_LSU_IC(); + flush(KERNBASE); + intr_restore(s); } /* @@ -165,9 +202,11 @@ cheetah_dcache_page_inval(vm_paddr_t spa) vm_paddr_t pa; void *cookie; - KASSERT((spa & PAGE_MASK) == 0, ("%s: pa not page aligned", __func__)); + KASSERT((spa & PAGE_MASK) == 0, + ("%s: pa not page aligned", __func__)); cookie = ipi_dcache_page_inval(tl_ipi_cheetah_dcache_page_inval, spa); - for (pa = spa; pa < spa + PAGE_SIZE; pa += PCPU_GET(cache.dc_linesize)) + for (pa = spa; pa < spa + PAGE_SIZE; + pa += PCPU_GET(cache.dc_linesize)) stxa_sync(pa, ASI_DCACHE_INVALIDATE, 0); ipi_wait(cookie); } From 707a9a4c19e9a397437017cde5ee082e59d6b430 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 4 Apr 2010 15:37:47 +0000 Subject: [PATCH 1820/2592] MFC r205096, r205102 Add AGP support for Intel Pineview and Ironlake chipsets. --- sys/dev/agp/agp_i810.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/sys/dev/agp/agp_i810.c b/sys/dev/agp/agp_i810.c index 943244dc06f..e72fbf0b217 100644 --- a/sys/dev/agp/agp_i810.c +++ b/sys/dev/agp/agp_i810.c @@ -70,6 +70,7 @@ enum { CHIP_I915, /* 915G/915GM */ CHIP_I965, /* G965 */ CHIP_G33, /* G33/Q33/Q35 */ + CHIP_IGD, /* Pineview */ CHIP_G4X, /* G45/Q45 */ }; @@ -163,6 +164,10 @@ static const struct agp_i810_match { "Intel G33 SVGA controller"}, {0x29D28086, CHIP_G33, 0x00020000, "Intel Q33 SVGA controller"}, + {0xA0018086, CHIP_IGD, 0x00010000, + "Intel Pineview SVGA controller"}, + {0xA0118086, CHIP_IGD, 0x00010000, + "Intel Pineview (M) SVGA controller"}, {0x2A028086, CHIP_I965, 0x00020000, "Intel GM965 SVGA controller"}, {0x2A128086, CHIP_I965, 0x00020000, @@ -170,13 +175,17 @@ static const struct agp_i810_match { {0x2A428086, CHIP_G4X, 0x00020000, "Intel GM45 SVGA controller"}, {0x2E028086, CHIP_G4X, 0x00020000, - "Intel 4 Series SVGA controller"}, + "Intel Eaglelake SVGA controller"}, {0x2E128086, CHIP_G4X, 0x00020000, "Intel Q45 SVGA controller"}, {0x2E228086, CHIP_G4X, 0x00020000, "Intel G45 SVGA controller"}, {0x2E328086, CHIP_G4X, 0x00020000, "Intel G41 SVGA controller"}, + {0x00428086, CHIP_G4X, 0x00020000, + "Intel Ironlake (D) SVGA controller"}, + {0x00468086, CHIP_G4X, 0x00020000, + "Intel Ironlake (M) SVGA controller"}, {0, 0, 0, NULL} }; @@ -286,6 +295,7 @@ agp_i810_probe(device_t dev) case CHIP_I915: case CHIP_I965: case CHIP_G33: + case CHIP_IGD: case CHIP_G4X: deven = pci_read_config(bdev, AGP_I915_DEVEN, 4); if ((deven & AGP_I915_DEVEN_D2F0) == @@ -351,6 +361,7 @@ agp_i810_dump_regs(device_t dev) case CHIP_I915: case CHIP_I965: case CHIP_G33: + case CHIP_IGD: case CHIP_G4X: device_printf(dev, "AGP_I855_GCC1: 0x%02x\n", pci_read_config(sc->bdev, AGP_I855_GCC1, 1)); @@ -386,6 +397,7 @@ agp_i810_attach(device_t dev) break; case CHIP_I915: case CHIP_G33: + case CHIP_IGD: sc->sc_res_spec = agp_i915_res_spec; agp_set_aperture_resource(dev, AGP_I915_GMADR); break; @@ -401,7 +413,8 @@ agp_i810_attach(device_t dev) return error; if (sc->chiptype != CHIP_I965 && sc->chiptype != CHIP_G33 && - sc->chiptype != CHIP_G4X && ptoa((vm_paddr_t)Maxmem) > 0xfffffffful) + sc->chiptype != CHIP_IGD && sc->chiptype != CHIP_G4X && + ptoa((vm_paddr_t)Maxmem) > 0xfffffffful) { device_printf(dev, "agp_i810.c does not support physical " "memory above 4GB.\n"); @@ -491,7 +504,7 @@ agp_i810_attach(device_t dev) gatt->ag_physical = pgtblctl & ~1; } else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915 || sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 || - sc->chiptype == CHIP_G4X) { + sc->chiptype == CHIP_IGD || sc->chiptype == CHIP_G4X) { unsigned int gcc1, pgtblctl, stolen, gtt_size; /* Stolen memory is set up at the beginning of the aperture by @@ -553,6 +566,7 @@ agp_i810_attach(device_t dev) return EINVAL; } break; + case CHIP_IGD: case CHIP_G4X: gtt_size = 0; break; @@ -587,6 +601,7 @@ agp_i810_attach(device_t dev) if (sc->chiptype == CHIP_I915 || sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 || + sc->chiptype == CHIP_IGD || sc->chiptype == CHIP_G4X) { stolen = 48 * 1024; } else { @@ -597,6 +612,7 @@ agp_i810_attach(device_t dev) if (sc->chiptype == CHIP_I915 || sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 || + sc->chiptype == CHIP_IGD || sc->chiptype == CHIP_G4X) { stolen = 64 * 1024; } else { @@ -606,6 +622,7 @@ agp_i810_attach(device_t dev) case AGP_G33_GCC1_GMS_STOLEN_128M: if (sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 || + sc->chiptype == CHIP_IGD || sc->chiptype == CHIP_G4X) { stolen = 128 * 1024; } else { @@ -615,6 +632,7 @@ agp_i810_attach(device_t dev) case AGP_G33_GCC1_GMS_STOLEN_256M: if (sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 || + sc->chiptype == CHIP_IGD || sc->chiptype == CHIP_G4X) { stolen = 256 * 1024; } else { @@ -783,6 +801,7 @@ agp_i810_set_aperture(device_t dev, u_int32_t aperture) case CHIP_I915: case CHIP_I965: case CHIP_G33: + case CHIP_IGD: case CHIP_G4X: return agp_generic_set_aperture(dev, aperture); } @@ -803,7 +822,7 @@ agp_i810_write_gtt_entry(device_t dev, int offset, vm_offset_t physical, pte = (u_int32_t)physical | 1; if (sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 || - sc->chiptype == CHIP_G4X) { + sc->chiptype == CHIP_IGD || sc->chiptype == CHIP_G4X) { pte |= (physical & 0x0000000f00000000ull) >> 28; } else { /* If we do actually have memory above 4GB on an older system, @@ -823,6 +842,7 @@ agp_i810_write_gtt_entry(device_t dev, int offset, vm_offset_t physical, break; case CHIP_I915: case CHIP_G33: + case CHIP_IGD: bus_write_4(sc->sc_res[1], (offset >> AGP_PAGE_SHIFT) * 4, pte); break; From 616641e98727f26832ccb273dd6c72ecc67a07ee Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 4 Apr 2010 15:42:52 +0000 Subject: [PATCH 1821/2592] MFC r203289,r203367 Enable MTRR on all VIA CPUs that claim support --- sys/amd64/amd64/amd64_mem.c | 5 +---- sys/i386/i386/i686_mem.c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/sys/amd64/amd64/amd64_mem.c b/sys/amd64/amd64/amd64_mem.c index d7959fd45fb..e50d3e72828 100644 --- a/sys/amd64/amd64/amd64_mem.c +++ b/sys/amd64/amd64/amd64_mem.c @@ -707,11 +707,8 @@ amd64_mem_drvinit(void *unused) switch (cpu_vendor_id) { case CPU_VENDOR_INTEL: case CPU_VENDOR_AMD: - break; case CPU_VENDOR_CENTAUR: - if (cpu_exthigh >= 0x80000008) - break; - /* FALLTHROUGH */ + break; default: return; } diff --git a/sys/i386/i386/i686_mem.c b/sys/i386/i386/i686_mem.c index fe229cc3be2..cc6f300617a 100644 --- a/sys/i386/i386/i686_mem.c +++ b/sys/i386/i386/i686_mem.c @@ -707,11 +707,8 @@ i686_mem_drvinit(void *unused) switch (cpu_vendor_id) { case CPU_VENDOR_INTEL: case CPU_VENDOR_AMD: - break; case CPU_VENDOR_CENTAUR: - if (cpu_exthigh >= 0x80000008) - break; - /* FALLTHROUGH */ + break; default: return; } From ca23c899777728bb761ed49497d1b2817bd836a0 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sun, 4 Apr 2010 15:46:46 +0000 Subject: [PATCH 1822/2592] MFC r205120,r205126 Add drm support for Intel Pineview chips. --- sys/dev/drm/drm_pciids.h | 4 +++- sys/dev/drm/i915_drv.h | 10 ++++++++-- sys/dev/drm/i915_reg.h | 4 ++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sys/dev/drm/drm_pciids.h b/sys/dev/drm/drm_pciids.h index acebad4e002..a7575f2c202 100644 --- a/sys/dev/drm/drm_pciids.h +++ b/sys/dev/drm/drm_pciids.h @@ -549,7 +549,9 @@ {0x8086, 0x29B2, CHIP_I9XX|CHIP_I915, "Intel Q35"}, \ {0x8086, 0x29D2, CHIP_I9XX|CHIP_I915, "Intel Q33"}, \ {0x8086, 0x2A42, CHIP_I9XX|CHIP_I965, "Mobile Intel® GM45 Express Chipset"}, \ - {0x8086, 0x2E02, CHIP_I9XX|CHIP_I965, "Intel Integrated Graphics Device"}, \ + {0x8086, 0x2E02, CHIP_I9XX|CHIP_I965, "Intel Eaglelake"}, \ + {0x8086, 0xA001, CHIP_I9XX|CHIP_I965, "Intel Pineview"}, \ + {0x8086, 0xA011, CHIP_I9XX|CHIP_I965, "Intel Pineview (M)"}, \ {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"}, \ diff --git a/sys/dev/drm/i915_drv.h b/sys/dev/drm/i915_drv.h index 38ae374b341..8e293be4d6b 100644 --- a/sys/dev/drm/i915_drv.h +++ b/sys/dev/drm/i915_drv.h @@ -657,15 +657,21 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); (dev)->pci_device == 0x2E32 || \ IS_GM45(dev)) +#define IS_IGDG(dev) ((dev)->pci_device == 0xa001) +#define IS_IGDGM(dev) ((dev)->pci_device == 0xa011) +#define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev)) + #define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ (dev)->pci_device == 0x29B2 || \ - (dev)->pci_device == 0x29D2) + (dev)->pci_device == 0x29D2 || \ + IS_IGD(dev)) #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ - IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev)) + IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \ + IS_IGD(dev)) #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev)) diff --git a/sys/dev/drm/i915_reg.h b/sys/dev/drm/i915_reg.h index 1a32c5f9be5..fce9992f3d9 100644 --- a/sys/dev/drm/i915_reg.h +++ b/sys/dev/drm/i915_reg.h @@ -362,6 +362,7 @@ __FBSDID("$FreeBSD$"); #define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +#define DPLL_FPA01_P1_POST_DIV_MASK_IGD 0x00ff8000 /* IGD */ #define I915_FIFO_UNDERRUN_STATUS (1UL<<31) #define I915_CRC_ERROR_ENABLE (1UL<<29) @@ -438,6 +439,7 @@ __FBSDID("$FreeBSD$"); */ #define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 #define DPLL_FPA01_P1_POST_DIV_SHIFT 16 +#define DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15 /* i830, required in DVO non-gang */ #define PLL_P2_DIVIDE_BY_4 (1 << 23) #define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ @@ -504,10 +506,12 @@ __FBSDID("$FreeBSD$"); #define FPB0 0x06048 #define FPB1 0x0604c #define FP_N_DIV_MASK 0x003f0000 +#define FP_N_IGD_DIV_MASK 0x00ff0000 #define FP_N_DIV_SHIFT 16 #define FP_M1_DIV_MASK 0x00003f00 #define FP_M1_DIV_SHIFT 8 #define FP_M2_DIV_MASK 0x0000003f +#define FP_M2_IGD_DIV_MASK 0x000000ff #define FP_M2_DIV_SHIFT 0 #define DPLL_TEST 0x606c #define DPLLB_TEST_SDVO_DIV_1 (0 << 22) From 9b355dc71db34bf8e6cc3fedce993de749225200 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 5 Apr 2010 13:33:54 +0000 Subject: [PATCH 1823/2592] MFC of 204670: ------------------------- sched_getparam was just plain broke for time-share processes. It did not return an error but instead just let garbage be passed back. This I fix so it actually properly translates the priority the process is at to a posix's high means more priority. I also fix it so that if the ULE scheduler has bumped it up to a realtime process you get back a sane value i.e. the highest priority (63 for time-share). sched_setscheduler() had the setting of the timeshare class priority disabled. With some notes about rejecting the posix high numbers is greater priority and use nice instead. This fix also adjusts that to work, with the cavet that a t-s process may well get bumped up or down i.e. the setscheduler() will NOT change the nice value only the current priority. I think this is reasonable considering if the user wants to play with nice then he can. At least all the posix'ish interfaces now respond sanely. ----------------------- --- sys/kern/kern_resource.c | 10 ++++++++-- sys/kern/ksched.c | 27 +++++++++++++++++++-------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 81a03ef0afd..f8678395904 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -471,14 +471,20 @@ rtp_to_pri(struct rtprio *rtp, struct thread *td) u_char newpri; u_char oldpri; - if (rtp->prio > RTP_PRIO_MAX) - return (EINVAL); thread_lock(td); switch (RTP_PRIO_BASE(rtp->type)) { case RTP_PRIO_REALTIME: + if (rtp->prio > RTP_PRIO_MAX) { + thread_unlock(td); + return (EINVAL); + } newpri = PRI_MIN_REALTIME + rtp->prio; break; case RTP_PRIO_NORMAL: + if (rtp->prio > (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE)) { + thread_unlock(td); + return (EINVAL); + } newpri = PRI_MIN_TIMESHARE + rtp->prio; break; case RTP_PRIO_IDLE: diff --git a/sys/kern/ksched.c b/sys/kern/ksched.c index 192034fec9c..2d11363c94a 100644 --- a/sys/kern/ksched.c +++ b/sys/kern/ksched.c @@ -81,9 +81,8 @@ ksched_detach(struct ksched *ks) * higher priority. It also permits sched_setparam to be * implementation defined for SCHED_OTHER. I don't like * the notion of inverted priorites for normal processes when - * you can use "setpriority" for that. + * you can use "setpriority" for that. * - * I'm rejecting sched_setparam for SCHED_OTHER with EINVAL. */ /* Macros to convert between the unix (lower numerically is higher priority) @@ -93,6 +92,9 @@ ksched_detach(struct ksched *ks) #define p4prio_to_rtpprio(P) (RTP_PRIO_MAX - (P)) #define rtpprio_to_p4prio(P) (RTP_PRIO_MAX - (P)) +#define p4prio_to_tsprio(P) ((PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE) - (P)) +#define tsprio_to_p4prio(P) ((PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE) - (P)) + /* These improve readability a bit for me: */ #define P1B_PRIO_MIN rtpprio_to_p4prio(RTP_PRIO_MAX) @@ -134,9 +136,6 @@ ksched_setparam(struct ksched *ksched, if (e == 0) { - if (policy == SCHED_OTHER) - e = EINVAL; - else e = ksched_setscheduler(ksched, td, policy, param); } @@ -152,7 +151,16 @@ ksched_getparam(struct ksched *ksched, pri_to_rtp(td, &rtp); if (RTP_PRIO_IS_REALTIME(rtp.type)) param->sched_priority = rtpprio_to_p4prio(rtp.prio); - + else { + if (PRI_MIN_TIMESHARE < rtp.prio) + /* + * The interactive score has it to min realtime + * so we must show max (64 most likely + */ + param->sched_priority = (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE); + else + param->sched_priority = tsprio_to_p4prio(rtp.prio); + } return 0; } @@ -191,11 +199,14 @@ ksched_setscheduler(struct ksched *ksched, break; case SCHED_OTHER: - { + if (param->sched_priority >= 0 && + param->sched_priority <= (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE)) { rtp.type = RTP_PRIO_NORMAL; rtp.prio = p4prio_to_rtpprio(param->sched_priority); rtp_to_pri(&rtp, td); - } + } else + e = EINVAL; + break; default: From 54bb41671a18fdf3b5d0715ac1d986b397b2c43c Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 5 Apr 2010 13:48:23 +0000 Subject: [PATCH 1824/2592] MFC of 2 items to fix the csum for v6 issue: Revision 205075 and 205104: ---------205075---------- With the recent change of the sctp checksum to support offload, no delayed checksum was added to the ip6 output code. This causes cards that do not support SCTP checksum offload to have SCTP packets that are IPv6 NOT have the sctp checksum performed. Thus you could not communicate with a peer. This adds the missing bits to make the checksum happen for these cards. ------------------------- ---------205104---------- The proper fix for the delayed SCTP checksum is to have the delayed function take an argument as to the offset to the SCTP header. This allows it to work for V4 and V6. This of course means changing all callers of the function to either pass the header len, if they have it, or create it (ip_hl << 2 or sizeof(ip6_hdr)). ------------------------- PR: 144529 --- sys/dev/xen/netback/netback.c | 2 +- sys/netinet/ip_divert.c | 2 +- sys/netinet/ip_ipsec.c | 2 +- sys/netinet/ip_output.c | 4 ++-- sys/netinet/sctp_crc32.c | 4 +--- sys/netinet/sctp_crc32.h | 2 +- sys/netinet6/ip6_output.c | 19 +++++++++++++++++++ 7 files changed, 26 insertions(+), 9 deletions(-) diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c index a6111e265f5..3088ecbdd12 100644 --- a/sys/dev/xen/netback/netback.c +++ b/sys/dev/xen/netback/netback.c @@ -302,7 +302,7 @@ fixup_checksum(struct mbuf *m) m->m_pkthdr.csum_flags &= ~CSUM_TCP; #ifdef SCTP } else if (sw_csum & CSUM_SCTP) { - sctp_delayed_cksum(m); + sctp_delayed_cksum(m, iphlen); sw_csum &= ~CSUM_SCTP; #endif } else { diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index a2caef54a30..6c48b5b89d6 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -234,7 +234,7 @@ divert_packet(struct mbuf *m, int incoming) #ifdef SCTP if (m->m_pkthdr.csum_flags & CSUM_SCTP) { ip->ip_len = ntohs(ip->ip_len); - sctp_delayed_cksum(m); + sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); m->m_pkthdr.csum_flags &= ~CSUM_SCTP; ip->ip_len = htons(ip->ip_len); } diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index 0eb4673a038..65ec49eb5a4 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -343,7 +343,7 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error, } #ifdef SCTP if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP) { - sctp_delayed_cksum(*m); + sctp_delayed_cksum(*m, (uint32_t)(ip->ip_hl << 2)); (*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP; } #endif diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 00c3c3ceacf..a10976a06b6 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -589,7 +589,7 @@ passout: } #ifdef SCTP if (sw_csum & CSUM_SCTP) { - sctp_delayed_cksum(m); + sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); sw_csum &= ~CSUM_SCTP; } #endif @@ -731,7 +731,7 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, #ifdef SCTP if (m0->m_pkthdr.csum_flags & CSUM_SCTP && (if_hwassist_flags & CSUM_IP_FRAGS) == 0) { - sctp_delayed_cksum(m0); + sctp_delayed_cksum(m0, hlen); m0->m_pkthdr.csum_flags &= ~CSUM_SCTP; } #endif diff --git a/sys/netinet/sctp_crc32.c b/sys/netinet/sctp_crc32.c index aeb97153855..d9ae238835f 100644 --- a/sys/netinet/sctp_crc32.c +++ b/sys/netinet/sctp_crc32.c @@ -127,14 +127,12 @@ sctp_calculate_cksum(struct mbuf *m, uint32_t offset) void -sctp_delayed_cksum(struct mbuf *m) +sctp_delayed_cksum(struct mbuf *m, uint32_t offset) { struct ip *ip; uint32_t checksum; - uint32_t offset; ip = mtod(m, struct ip *); - offset = ip->ip_hl << 2; checksum = sctp_calculate_cksum(m, offset); SCTP_STAT_DECR(sctps_sendhwcrc); SCTP_STAT_INCR(sctps_sendswcrc); diff --git a/sys/netinet/sctp_crc32.h b/sys/netinet/sctp_crc32.h index 44196b16abe..e66815ee517 100644 --- a/sys/netinet/sctp_crc32.h +++ b/sys/netinet/sctp_crc32.h @@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$"); #if defined(_KERNEL) || defined(__Userspace__) uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t); -void sctp_delayed_cksum(struct mbuf *); +void sctp_delayed_cksum(struct mbuf *, uint32_t offset); #endif /* _KERNEL */ diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index c2ec49aa350..a878aacf79f 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" +#include "opt_sctp.h" #include #include @@ -102,6 +103,10 @@ __FBSDID("$FreeBSD$"); #include #include #endif /* IPSEC */ +#ifdef SCTP +#include +#include +#endif #include #include @@ -208,6 +213,9 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, struct route_in6 *ro_pmtu = NULL; int hdrsplit = 0; int needipsec = 0; +#ifdef SCTP + int sw_csum; +#endif #ifdef IPSEC struct ipsec_output_state state; struct ip6_rthdr *rh = NULL; @@ -829,6 +837,10 @@ again: } m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED | CSUM_IP_VALID; +#ifdef SCTP + if (m->m_pkthdr.csum_flags & CSUM_SCTP) + m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; +#endif error = netisr_queue(NETISR_IPV6, m); goto done; } else @@ -857,6 +869,13 @@ passout: * 4: if dontfrag == 1 && alwaysfrag == 1 * error, as we cannot handle this conflicting request */ +#ifdef SCTP + sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist; + if (sw_csum & CSUM_SCTP) { + sctp_delayed_cksum(m, sizeof(struct ip6_hdr)); + sw_csum &= ~CSUM_SCTP; + } +#endif tlen = m->m_pkthdr.len; if (opt && (opt->ip6po_flags & IP6PO_DONTFRAG)) From 02b5123ee38b2501f7a31f3a13a2d66e1c074df3 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 5 Apr 2010 16:11:42 +0000 Subject: [PATCH 1825/2592] MFC r204907, r204913, r205402, r205573, r205573 Implement AMD's recommended workaround for Erratum 383 on Family 10h processors. Enable machine check exceptions by default. --- sys/amd64/amd64/mca.c | 35 ++++- sys/amd64/amd64/pmap.c | 134 +++++++++++++++++- sys/amd64/include/md_var.h | 1 + sys/amd64/include/specialreg.h | 1 + sys/i386/i386/mca.c | 35 ++++- sys/i386/i386/pmap.c | 243 ++++++++++++++++++++++++++------- sys/i386/include/md_var.h | 1 + sys/i386/include/specialreg.h | 1 + 8 files changed, 389 insertions(+), 62 deletions(-) diff --git a/sys/amd64/amd64/mca.c b/sys/amd64/amd64/mca.c index 76bee77a061..ccbab1757c6 100644 --- a/sys/amd64/amd64/mca.c +++ b/sys/amd64/amd64/mca.c @@ -60,11 +60,20 @@ static int mca_count; /* Number of records stored. */ SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RD, NULL, "Machine Check Architecture"); -static int mca_enabled = 0; +static int mca_enabled = 1; TUNABLE_INT("hw.mca.enabled", &mca_enabled); SYSCTL_INT(_hw_mca, OID_AUTO, enabled, CTLFLAG_RDTUN, &mca_enabled, 0, "Administrative toggle for machine check support"); +static int amd10h_L1TP = 1; +TUNABLE_INT("hw.mca.amd10h_L1TP", &amd10h_L1TP); +SYSCTL_INT(_hw_mca, OID_AUTO, amd10h_L1TP, CTLFLAG_RDTUN, &amd10h_L1TP, 0, + "Administrative toggle for logging of level one TLB parity (L1TP) errors"); + +int workaround_erratum383; +SYSCTL_INT(_hw_mca, OID_AUTO, erratum383, CTLFLAG_RD, &workaround_erratum383, 0, + "Is the workaround for Erratum 383 on AMD Family 10h processors enabled?"); + static STAILQ_HEAD(, mca_internal) mca_records; static struct callout mca_timer; static int mca_ticks = 3600; /* Check hourly by default. */ @@ -527,7 +536,7 @@ void mca_init(void) { uint64_t mcg_cap; - uint64_t ctl; + uint64_t ctl, mask; int skip; int i; @@ -535,6 +544,15 @@ mca_init(void) if (!mca_enabled || !(cpu_feature & CPUID_MCE)) return; + /* + * On AMD Family 10h processors, unless logging of level one TLB + * parity (L1TP) errors is disabled, enable the recommended workaround + * for Erratum 383. + */ + if (cpu_vendor_id == CPU_VENDOR_AMD && + CPUID_TO_FAMILY(cpu_id) == 0x10 && amd10h_L1TP) + workaround_erratum383 = 1; + if (cpu_feature & CPUID_MCA) { if (PCPU_GET(cpuid) == 0) mca_setup(); @@ -545,6 +563,19 @@ mca_init(void) /* Enable MCA features. */ wrmsr(MSR_MCG_CTL, MCG_CTL_ENABLE); + /* + * Disable logging of level one TLB parity (L1TP) errors by + * the data cache as an alternative workaround for AMD Family + * 10h Erratum 383. Unlike the recommended workaround, there + * is no performance penalty to this workaround. However, + * L1TP errors will go unreported. + */ + if (cpu_vendor_id == CPU_VENDOR_AMD && + CPUID_TO_FAMILY(cpu_id) == 0x10 && !amd10h_L1TP) { + mask = rdmsr(MSR_MC0_CTL_MASK); + if ((mask & (1UL << 5)) == 0) + wrmsr(MSR_MC0_CTL_MASK, mask | (1UL << 5)); + } for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { /* By default enable logging of all errors. */ ctl = 0xffffffffffffffffUL; diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 5ff527f1a02..516048d5a45 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -7,7 +7,7 @@ * All rights reserved. * Copyright (c) 2003 Peter Wemm * All rights reserved. - * Copyright (c) 2005-2008 Alan L. Cox + * Copyright (c) 2005-2010 Alan L. Cox * All rights reserved. * * This code is derived from software contributed to Berkeley by @@ -252,6 +252,9 @@ static void pmap_remove_entry(struct pmap *pmap, vm_page_t m, static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); +static void pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, + pd_entry_t newpde); +static void pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde); static vm_page_t pmap_allocpde(pmap_t pmap, vm_offset_t va, int flags); static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags); @@ -654,13 +657,13 @@ pmap_init(void) pv_entry_high_water = 9 * (pv_entry_max / 10); /* - * Disable large page mappings by default if the kernel is running in - * a virtual machine on an AMD Family 10h processor. This is a work- - * around for Erratum 383. + * If the kernel is running in a virtual machine on an AMD Family 10h + * processor, then it must assume that MCA is enabled by the virtual + * machine monitor. */ if (vm_guest == VM_GUEST_VM && cpu_vendor_id == CPU_VENDOR_AMD && CPUID_TO_FAMILY(cpu_id) == 0x10) - pg_ps_enabled = 0; + workaround_erratum383 = 1; /* * Are large page mappings enabled? @@ -795,6 +798,45 @@ pmap_cache_bits(int mode, boolean_t is_pde) cache_bits |= PG_NC_PWT; return (cache_bits); } + +/* + * After changing the page size for the specified virtual address in the page + * table, flush the corresponding entries from the processor's TLB. Only the + * calling processor's TLB is affected. + * + * The calling thread must be pinned to a processor. + */ +static void +pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde) +{ + u_long cr4; + + if ((newpde & PG_PS) == 0) + /* Demotion: flush a specific 2MB page mapping. */ + invlpg(va); + else if ((newpde & PG_G) == 0) + /* + * Promotion: flush every 4KB page mapping from the TLB + * because there are too many to flush individually. + */ + invltlb(); + else { + /* + * Promotion: flush every 4KB page mapping from the TLB, + * including any global (PG_G) mappings. + */ + cr4 = rcr4(); + load_cr4(cr4 & ~CR4_PGE); + /* + * Although preemption at this point could be detrimental to + * performance, it would not lead to an error. PG_G is simply + * ignored if CR4.PGE is clear. Moreover, in case this block + * is re-entered, the load_cr4() either above or below will + * modify CR4.PGE flushing the TLB. + */ + load_cr4(cr4 | CR4_PGE); + } +} #ifdef SMP /* * For SMP, these functions have to use the IPI mechanism for coherence. @@ -891,6 +933,69 @@ pmap_invalidate_cache(void) smp_cache_flush(); sched_unpin(); } + +struct pde_action { + cpumask_t store; /* processor that updates the PDE */ + cpumask_t invalidate; /* processors that invalidate their TLB */ + vm_offset_t va; + pd_entry_t *pde; + pd_entry_t newpde; +}; + +static void +pmap_update_pde_action(void *arg) +{ + struct pde_action *act = arg; + + if (act->store == PCPU_GET(cpumask)) + pde_store(act->pde, act->newpde); +} + +static void +pmap_update_pde_teardown(void *arg) +{ + struct pde_action *act = arg; + + if ((act->invalidate & PCPU_GET(cpumask)) != 0) + pmap_update_pde_invalidate(act->va, act->newpde); +} + +/* + * Change the page size for the specified virtual address in a way that + * prevents any possibility of the TLB ever having two entries that map the + * same virtual address using different page sizes. This is the recommended + * workaround for Erratum 383 on AMD Family 10h processors. It prevents a + * machine check exception for a TLB state that is improperly diagnosed as a + * hardware error. + */ +static void +pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde) +{ + struct pde_action act; + cpumask_t active, cpumask; + + sched_pin(); + cpumask = PCPU_GET(cpumask); + if (pmap == kernel_pmap) + active = all_cpus; + else + active = pmap->pm_active; + if ((active & PCPU_GET(other_cpus)) != 0) { + act.store = cpumask; + act.invalidate = active; + act.va = va; + act.pde = pde; + act.newpde = newpde; + smp_rendezvous_cpus(cpumask | active, + smp_no_rendevous_barrier, pmap_update_pde_action, + pmap_update_pde_teardown, &act); + } else { + pde_store(pde, newpde); + if ((active & cpumask) != 0) + pmap_update_pde_invalidate(va, newpde); + } + sched_unpin(); +} #else /* !SMP */ /* * Normal, non-SMP, invalidation functions. @@ -928,6 +1033,15 @@ pmap_invalidate_cache(void) wbinvd(); } + +static void +pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde) +{ + + pde_store(pde, newpde); + if (pmap == kernel_pmap || pmap->pm_active) + pmap_update_pde_invalidate(va, newpde); +} #endif /* !SMP */ static void @@ -2310,7 +2424,10 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) * processor changing the setting of PG_A and/or PG_M between * the read above and the store below. */ - pde_store(pde, newpde); + if (workaround_erratum383) + pmap_update_pde(pmap, va, pde, newpde); + else + pde_store(pde, newpde); /* * Invalidate a stale recursive mapping of the page table page. @@ -2926,7 +3043,10 @@ setpte: /* * Map the superpage. */ - pde_store(pde, PG_PS | newpde); + if (workaround_erratum383) + pmap_update_pde(pmap, va, pde, PG_PS | newpde); + else + pde_store(pde, PG_PS | newpde); pmap_pde_promotions++; CTR2(KTR_PMAP, "pmap_promote_pde: success for va %#lx" diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h index 15df851ee31..2b43b37cc18 100644 --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -61,6 +61,7 @@ extern char sigcode[]; extern int szsigcode; extern uint64_t *vm_page_dump; extern int vm_page_dump_size; +extern int workaround_erratum383; extern int _udatasel; extern int _ucodesel; extern int _ucode32sel; diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h index 925346297cb..86a08cec931 100644 --- a/sys/amd64/include/specialreg.h +++ b/sys/amd64/include/specialreg.h @@ -506,6 +506,7 @@ #define MSR_TOP_MEM 0xc001001a /* boundary for ram below 4G */ #define MSR_TOP_MEM2 0xc001001d /* boundary for ram above 4G */ #define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */ +#define MSR_MC0_CTL_MASK 0xc0010044 /* VIA ACE crypto featureset: for via_feature_rng */ #define VIA_HAS_RNG 1 /* cpu has RNG */ diff --git a/sys/i386/i386/mca.c b/sys/i386/i386/mca.c index 9b9f9451597..8d33b51b96e 100644 --- a/sys/i386/i386/mca.c +++ b/sys/i386/i386/mca.c @@ -60,11 +60,20 @@ static int mca_count; /* Number of records stored. */ SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RD, NULL, "Machine Check Architecture"); -static int mca_enabled = 0; +static int mca_enabled = 1; TUNABLE_INT("hw.mca.enabled", &mca_enabled); SYSCTL_INT(_hw_mca, OID_AUTO, enabled, CTLFLAG_RDTUN, &mca_enabled, 0, "Administrative toggle for machine check support"); +static int amd10h_L1TP = 1; +TUNABLE_INT("hw.mca.amd10h_L1TP", &amd10h_L1TP); +SYSCTL_INT(_hw_mca, OID_AUTO, amd10h_L1TP, CTLFLAG_RDTUN, &amd10h_L1TP, 0, + "Administrative toggle for logging of level one TLB parity (L1TP) errors"); + +int workaround_erratum383; +SYSCTL_INT(_hw_mca, OID_AUTO, erratum383, CTLFLAG_RD, &workaround_erratum383, 0, + "Is the workaround for Erratum 383 on AMD Family 10h processors enabled?"); + static STAILQ_HEAD(, mca_internal) mca_records; static struct callout mca_timer; static int mca_ticks = 3600; /* Check hourly by default. */ @@ -527,7 +536,7 @@ void mca_init(void) { uint64_t mcg_cap; - uint64_t ctl; + uint64_t ctl, mask; int skip; int i; @@ -535,6 +544,15 @@ mca_init(void) if (!mca_enabled || !(cpu_feature & CPUID_MCE)) return; + /* + * On AMD Family 10h processors, unless logging of level one TLB + * parity (L1TP) errors is disabled, enable the recommended workaround + * for Erratum 383. + */ + if (cpu_vendor_id == CPU_VENDOR_AMD && + CPUID_TO_FAMILY(cpu_id) == 0x10 && amd10h_L1TP) + workaround_erratum383 = 1; + if (cpu_feature & CPUID_MCA) { if (PCPU_GET(cpuid) == 0) mca_setup(); @@ -545,6 +563,19 @@ mca_init(void) /* Enable MCA features. */ wrmsr(MSR_MCG_CTL, MCG_CTL_ENABLE); + /* + * Disable logging of level one TLB parity (L1TP) errors by + * the data cache as an alternative workaround for AMD Family + * 10h Erratum 383. Unlike the recommended workaround, there + * is no performance penalty to this workaround. However, + * L1TP errors will go unreported. + */ + if (cpu_vendor_id == CPU_VENDOR_AMD && + CPUID_TO_FAMILY(cpu_id) == 0x10 && !amd10h_L1TP) { + mask = rdmsr(MSR_MC0_CTL_MASK); + if ((mask & (1UL << 5)) == 0) + wrmsr(MSR_MC0_CTL_MASK, mask | (1UL << 5)); + } for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { /* By default enable logging of all errors. */ ctl = 0xffffffffffffffffUL; diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 5248aca95ae..fff77ad077a 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -5,7 +5,7 @@ * All rights reserved. * Copyright (c) 1994 David Greenman * All rights reserved. - * Copyright (c) 2005-2008 Alan L. Cox + * Copyright (c) 2005-2010 Alan L. Cox * All rights reserved. * * This code is derived from software contributed to Berkeley by @@ -293,6 +293,7 @@ static void pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); static boolean_t pmap_is_modified_pvh(struct md_page *pvh); static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); +static void pmap_kenter_pde(vm_offset_t va, pd_entry_t newpde); static vm_page_t pmap_lookup_pt_page(pmap_t pmap, vm_offset_t va); static void pmap_pde_attr(pd_entry_t *pde, int cache_bits); static void pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); @@ -311,6 +312,9 @@ static void pmap_remove_entry(struct pmap *pmap, vm_page_t m, static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); +static void pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, + pd_entry_t newpde); +static void pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde); static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags); @@ -395,6 +399,13 @@ pmap_bootstrap(vm_paddr_t firstaddr) kernel_pmap->pm_active = -1; /* don't allow deactivation */ TAILQ_INIT(&kernel_pmap->pm_pvchunk); LIST_INIT(&allpmaps); + + /* + * Request a spin mutex so that changes to allpmaps cannot be + * preempted by smp_rendezvous_cpus(). Otherwise, + * pmap_update_pde_kernel() could access allpmaps while it is + * being changed. + */ mtx_init(&allpmaps_lock, "allpmaps", NULL, MTX_SPIN); mtx_lock_spin(&allpmaps_lock); LIST_INSERT_HEAD(&allpmaps, kernel_pmap, pm_list); @@ -678,19 +689,21 @@ pmap_init(void) pv_entry_high_water = 9 * (pv_entry_max / 10); /* - * Disable large page mappings by default if the kernel is running in - * a virtual machine on an AMD Family 10h processor. This is a work- - * around for Erratum 383. + * If the kernel is running in a virtual machine on an AMD Family 10h + * processor, then it must assume that MCA is enabled by the virtual + * machine monitor. */ if (vm_guest == VM_GUEST_VM && cpu_vendor_id == CPU_VENDOR_AMD && CPUID_TO_FAMILY(cpu_id) == 0x10) - pg_ps_enabled = 0; + workaround_erratum383 = 1; /* - * Are large page mappings enabled? + * Are large page mappings supported and enabled? */ TUNABLE_INT_FETCH("vm.pmap.pg_ps_enabled", &pg_ps_enabled); - if (pg_ps_enabled) { + if (pseflag == 0) + pg_ps_enabled = 0; + else if (pg_ps_enabled) { KASSERT(MAXPAGESIZES > 1 && pagesizes[1] == 0, ("pmap_init: can't assign to pagesizes[1]")); pagesizes[1] = NBPDR; @@ -836,6 +849,69 @@ pmap_cache_bits(int mode, boolean_t is_pde) cache_bits |= PG_NC_PWT; return (cache_bits); } + +/* + * The caller is responsible for maintaining TLB consistency. + */ +static void +pmap_kenter_pde(vm_offset_t va, pd_entry_t newpde) +{ + pd_entry_t *pde; + pmap_t pmap; + boolean_t PTD_updated; + + PTD_updated = FALSE; + mtx_lock_spin(&allpmaps_lock); + LIST_FOREACH(pmap, &allpmaps, pm_list) { + if ((pmap->pm_pdir[PTDPTDI] & PG_FRAME) == (PTDpde[0] & + PG_FRAME)) + PTD_updated = TRUE; + pde = pmap_pde(pmap, va); + pde_store(pde, newpde); + } + mtx_unlock_spin(&allpmaps_lock); + KASSERT(PTD_updated, + ("pmap_kenter_pde: current page table is not in allpmaps")); +} + +/* + * After changing the page size for the specified virtual address in the page + * table, flush the corresponding entries from the processor's TLB. Only the + * calling processor's TLB is affected. + * + * The calling thread must be pinned to a processor. + */ +static void +pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde) +{ + u_long cr4; + + if ((newpde & PG_PS) == 0) + /* Demotion: flush a specific 2MB page mapping. */ + invlpg(va); + else if ((newpde & PG_G) == 0) + /* + * Promotion: flush every 4KB page mapping from the TLB + * because there are too many to flush individually. + */ + invltlb(); + else { + /* + * Promotion: flush every 4KB page mapping from the TLB, + * including any global (PG_G) mappings. + */ + cr4 = rcr4(); + load_cr4(cr4 & ~CR4_PGE); + /* + * Although preemption at this point could be detrimental to + * performance, it would not lead to an error. PG_G is simply + * ignored if CR4.PGE is clear. Moreover, in case this block + * is re-entered, the load_cr4() either above or below will + * modify CR4.PGE flushing the TLB. + */ + load_cr4(cr4 | CR4_PGE); + } +} #ifdef SMP /* * For SMP, these functions have to use the IPI mechanism for coherence. @@ -932,6 +1008,92 @@ pmap_invalidate_cache(void) smp_cache_flush(); sched_unpin(); } + +struct pde_action { + cpumask_t store; /* processor that updates the PDE */ + cpumask_t invalidate; /* processors that invalidate their TLB */ + vm_offset_t va; + pd_entry_t *pde; + pd_entry_t newpde; +}; + +static void +pmap_update_pde_kernel(void *arg) +{ + struct pde_action *act = arg; + pd_entry_t *pde; + pmap_t pmap; + + if (act->store == PCPU_GET(cpumask)) + /* + * Elsewhere, this operation requires allpmaps_lock for + * synchronization. Here, it does not because it is being + * performed in the context of an all_cpus rendezvous. + */ + LIST_FOREACH(pmap, &allpmaps, pm_list) { + pde = pmap_pde(pmap, act->va); + pde_store(pde, act->newpde); + } +} + +static void +pmap_update_pde_user(void *arg) +{ + struct pde_action *act = arg; + + if (act->store == PCPU_GET(cpumask)) + pde_store(act->pde, act->newpde); +} + +static void +pmap_update_pde_teardown(void *arg) +{ + struct pde_action *act = arg; + + if ((act->invalidate & PCPU_GET(cpumask)) != 0) + pmap_update_pde_invalidate(act->va, act->newpde); +} + +/* + * Change the page size for the specified virtual address in a way that + * prevents any possibility of the TLB ever having two entries that map the + * same virtual address using different page sizes. This is the recommended + * workaround for Erratum 383 on AMD Family 10h processors. It prevents a + * machine check exception for a TLB state that is improperly diagnosed as a + * hardware error. + */ +static void +pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde) +{ + struct pde_action act; + cpumask_t active, cpumask; + + sched_pin(); + cpumask = PCPU_GET(cpumask); + if (pmap == kernel_pmap) + active = all_cpus; + else + active = pmap->pm_active; + if ((active & PCPU_GET(other_cpus)) != 0) { + act.store = cpumask; + act.invalidate = active; + act.va = va; + act.pde = pde; + act.newpde = newpde; + smp_rendezvous_cpus(cpumask | active, + smp_no_rendevous_barrier, pmap == kernel_pmap ? + pmap_update_pde_kernel : pmap_update_pde_user, + pmap_update_pde_teardown, &act); + } else { + if (pmap == kernel_pmap) + pmap_kenter_pde(va, newpde); + else + pde_store(pde, newpde); + if ((active & cpumask) != 0) + pmap_update_pde_invalidate(va, newpde); + } + sched_unpin(); +} #else /* !SMP */ /* * Normal, non-SMP, 486+ invalidation functions. @@ -969,6 +1131,18 @@ pmap_invalidate_cache(void) wbinvd(); } + +static void +pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde) +{ + + if (pmap == kernel_pmap) + pmap_kenter_pde(va, newpde); + else + pde_store(pde, newpde); + if (pmap == kernel_pmap || pmap->pm_active) + pmap_update_pde_invalidate(va, newpde); +} #endif /* !SMP */ void @@ -1842,12 +2016,9 @@ SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG|CTLFLAG_RD, void pmap_growkernel(vm_offset_t addr) { - struct pmap *pmap; vm_paddr_t ptppaddr; vm_page_t nkpg; pd_entry_t newpdir; - pt_entry_t *pde; - boolean_t updated_PTD; mtx_assert(&kernel_map->system_mtx, MA_OWNED); if (kernel_vm_end == 0) { @@ -1889,18 +2060,7 @@ pmap_growkernel(vm_offset_t addr) newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M); pdir_pde(KPTD, kernel_vm_end) = pgeflag | newpdir; - updated_PTD = FALSE; - mtx_lock_spin(&allpmaps_lock); - LIST_FOREACH(pmap, &allpmaps, pm_list) { - if ((pmap->pm_pdir[PTDPTDI] & PG_FRAME) == (PTDpde[0] & - PG_FRAME)) - updated_PTD = TRUE; - pde = pmap_pde(pmap, kernel_vm_end); - pde_store(pde, newpdir); - } - mtx_unlock_spin(&allpmaps_lock); - KASSERT(updated_PTD, - ("pmap_growkernel: current page table is not in allpmaps")); + pmap_kenter_pde(kernel_vm_end, newpdir); kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1); if (kernel_vm_end - 1 >= kernel_map->max_offset) { kernel_vm_end = kernel_map->max_offset; @@ -2344,7 +2504,6 @@ static boolean_t pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) { pd_entry_t newpde, oldpde; - pmap_t allpmaps_entry; pt_entry_t *firstpte, newpte; vm_paddr_t mptepa; vm_page_t free, mpte; @@ -2450,25 +2609,11 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) * processor changing the setting of PG_A and/or PG_M between * the read above and the store below. */ - if (pmap == kernel_pmap) { - /* - * A harmless race exists between this loop and the bcopy() - * in pmap_pinit() that initializes the kernel segment of - * the new page table directory. Specifically, that bcopy() - * may copy the new PDE from the PTD to the new page table - * before this loop updates that new page table. - */ - mtx_lock_spin(&allpmaps_lock); - LIST_FOREACH(allpmaps_entry, &allpmaps, pm_list) { - pde = pmap_pde(allpmaps_entry, va); - KASSERT(*pde == newpde || (*pde & PG_PTE_PROMOTE) == - (oldpde & PG_PTE_PROMOTE), - ("pmap_demote_pde: pde was %#jx, expected %#jx", - (uintmax_t)*pde, (uintmax_t)oldpde)); - pde_store(pde, newpde); - } - mtx_unlock_spin(&allpmaps_lock); - } else + if (workaround_erratum383) + pmap_update_pde(pmap, va, pde, newpde); + else if (pmap == kernel_pmap) + pmap_kenter_pde(va, newpde); + else pde_store(pde, newpde); if (firstpte == PADDR2) mtx_unlock(&PMAP2mutex); @@ -2987,7 +3132,6 @@ static void pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) { pd_entry_t newpde; - pmap_t allpmaps_entry; pt_entry_t *firstpte, oldpte, pa, *pte; vm_offset_t oldpteva; vm_page_t mpte; @@ -3091,14 +3235,11 @@ setpte: /* * Map the superpage. */ - if (pmap == kernel_pmap) { - mtx_lock_spin(&allpmaps_lock); - LIST_FOREACH(allpmaps_entry, &allpmaps, pm_list) { - pde = pmap_pde(allpmaps_entry, va); - pde_store(pde, PG_PS | newpde); - } - mtx_unlock_spin(&allpmaps_lock); - } else + if (workaround_erratum383) + pmap_update_pde(pmap, va, pde, PG_PS | newpde); + else if (pmap == kernel_pmap) + pmap_kenter_pde(va, PG_PS | newpde); + else pde_store(pde, PG_PS | newpde); pmap_pde_promotions++; diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h index e2968e9d4fc..44eb8a6e2ab 100644 --- a/sys/i386/include/md_var.h +++ b/sys/i386/include/md_var.h @@ -73,6 +73,7 @@ extern int szosigcode; #endif extern uint32_t *vm_page_dump; extern int vm_page_dump_size; +extern int workaround_erratum383; typedef void alias_for_inthand_t(u_int cs, u_int ef, u_int esp, u_int ss); struct thread; diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h index 64a55350391..d2494c72100 100644 --- a/sys/i386/include/specialreg.h +++ b/sys/i386/include/specialreg.h @@ -551,6 +551,7 @@ /* AMD64 MSR's */ #define MSR_EFER 0xc0000080 /* extended features */ #define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */ +#define MSR_MC0_CTL_MASK 0xc0010044 /* VIA ACE crypto featureset: for via_feature_rng */ #define VIA_HAS_RNG 1 /* cpu has RNG */ From 7493cc345aceefdf3a4356705a9994b3e1472598 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 5 Apr 2010 17:32:49 +0000 Subject: [PATCH 1826/2592] MFC: r205858 Check the pointer to JIT binary filter before its de-allocation. --- sys/net/bpf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index fcac33d44dc..0d34e1f157a 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -1865,13 +1865,14 @@ bpf_freed(struct bpf_d *d) * free. */ bpf_free(d); - if (d->bd_rfilter) { + if (d->bd_rfilter != NULL) { free((caddr_t)d->bd_rfilter, M_BPF); #ifdef BPF_JITTER - bpf_destroy_jit_filter(d->bd_bfilter); + if (d->bd_bfilter != NULL) + bpf_destroy_jit_filter(d->bd_bfilter); #endif } - if (d->bd_wfilter) + if (d->bd_wfilter != NULL) free((caddr_t)d->bd_wfilter, M_BPF); mtx_destroy(&d->bd_mtx); } From 29f7dafb4cc10c7ebb2d6b911fd3a47ff02175b2 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 5 Apr 2010 17:37:35 +0000 Subject: [PATCH 1827/2592] MFC: r205095 Fix a style(9) nit. --- sys/net/bpf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 0d34e1f157a..51bb1d03c37 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -1577,8 +1577,7 @@ filt_bpfread(struct knote *kn, long hint) kn->kn_data = d->bd_slen; if (d->bd_hbuf) kn->kn_data += d->bd_hlen; - } - else if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) { + } else if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) { callout_reset(&d->bd_callout, d->bd_rtout, bpf_timed_out, d); d->bd_state = BPF_WAITING; From ceb8e6f3504832829a901c37a09ea5609a38eda2 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Mon, 5 Apr 2010 17:56:40 +0000 Subject: [PATCH 1828/2592] MFC: r206018 - Take advantage of the INTCLR_* macros. - Right-justify the backslashes as per style(9). --- sys/sparc64/fhc/fhc.c | 4 ++-- sys/sparc64/pci/psycho.c | 12 ++++++------ sys/sparc64/pci/schizo.c | 24 ++++++++++++------------ sys/sparc64/sbus/sbus.c | 6 +++--- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c index 6aefffa1a6f..2b15e5e3adc 100644 --- a/sys/sparc64/fhc/fhc.c +++ b/sys/sparc64/fhc/fhc.c @@ -208,7 +208,7 @@ fhc_attach(device_t dev) printf("model unknown\n"); for (i = FHC_FANFAIL; i <= FHC_TOD; i++) { - bus_write_4(sc->sc_memres[i], FHC_ICLR, 0x0); + bus_write_4(sc->sc_memres[i], FHC_ICLR, INTCLR_IDLE); (void)bus_read_4(sc->sc_memres[i], FHC_ICLR); } @@ -391,7 +391,7 @@ fhc_intr_clear(void *arg) struct intr_vector *iv = arg; struct fhc_icarg *fica = iv->iv_icarg; - bus_write_4(fica->fica_memres, FHC_ICLR, 0x0); + bus_write_4(fica->fica_memres, FHC_ICLR, INTCLR_IDLE); (void)bus_read_4(fica->fica_memres, FHC_ICLR); } diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index 486136a4600..3cc8ed0da3a 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -188,13 +188,13 @@ struct psycho_dma_sync { uint8_t pds_func; /* func. of farest PCI dev. */ }; -#define PSYCHO_READ8(sc, off) \ +#define PSYCHO_READ8(sc, off) \ bus_read_8((sc)->sc_mem_res, (off)) -#define PSYCHO_WRITE8(sc, off, v) \ +#define PSYCHO_WRITE8(sc, off, v) \ bus_write_8((sc)->sc_mem_res, (off), (v)) -#define PCICTL_READ8(sc, off) \ +#define PCICTL_READ8(sc, off) \ PSYCHO_READ8((sc), (sc)->sc_pcictl + (off)) -#define PCICTL_WRITE8(sc, off, v) \ +#define PCICTL_WRITE8(sc, off, v) \ PSYCHO_WRITE8((sc), (sc)->sc_pcictl + (off), (v)) /* @@ -523,7 +523,7 @@ psycho_attach(device_t dev) (u_long)intrmap, (u_long)PSYCHO_READ8(sc, intrmap), (u_long)intrclr); PSYCHO_WRITE8(sc, intrmap, INTMAP_VEC(sc->sc_ign, i)); - PSYCHO_WRITE8(sc, intrclr, 0); + PSYCHO_WRITE8(sc, intrclr, INTCLR_IDLE); PSYCHO_WRITE8(sc, intrmap, INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, i), PCPU_GET(mid))); @@ -1137,7 +1137,7 @@ psycho_intr_clear(void *arg) struct intr_vector *iv = arg; struct psycho_icarg *pica = iv->iv_icarg; - PSYCHO_WRITE8(pica->pica_sc, pica->pica_clr, 0); + PSYCHO_WRITE8(pica->pica_sc, pica->pica_clr, INTCLR_IDLE); } static int diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c index f783b23f1c4..7de51880789 100644 --- a/sys/sparc64/pci/schizo.c +++ b/sys/sparc64/pci/schizo.c @@ -189,26 +189,26 @@ struct schizo_dma_sync { #define SCHIZO_PERF_CNT_QLTY 100 -#define SCHIZO_SPC_READ_8(spc, sc, offs) \ +#define SCHIZO_SPC_READ_8(spc, sc, offs) \ bus_read_8((sc)->sc_mem_res[(spc)], (offs)) -#define SCHIZO_SPC_WRITE_8(spc, sc, offs, v) \ +#define SCHIZO_SPC_WRITE_8(spc, sc, offs, v) \ bus_write_8((sc)->sc_mem_res[(spc)], (offs), (v)) -#define SCHIZO_PCI_READ_8(sc, offs) \ +#define SCHIZO_PCI_READ_8(sc, offs) \ SCHIZO_SPC_READ_8(STX_PCI, (sc), (offs)) -#define SCHIZO_PCI_WRITE_8(sc, offs, v) \ +#define SCHIZO_PCI_WRITE_8(sc, offs, v) \ SCHIZO_SPC_WRITE_8(STX_PCI, (sc), (offs), (v)) -#define SCHIZO_CTRL_READ_8(sc, offs) \ +#define SCHIZO_CTRL_READ_8(sc, offs) \ SCHIZO_SPC_READ_8(STX_CTRL, (sc), (offs)) -#define SCHIZO_CTRL_WRITE_8(sc, offs, v) \ +#define SCHIZO_CTRL_WRITE_8(sc, offs, v) \ SCHIZO_SPC_WRITE_8(STX_CTRL, (sc), (offs), (v)) -#define SCHIZO_PCICFG_READ_8(sc, offs) \ +#define SCHIZO_PCICFG_READ_8(sc, offs) \ SCHIZO_SPC_READ_8(STX_PCICFG, (sc), (offs)) -#define SCHIZO_PCICFG_WRITE_8(sc, offs, v) \ +#define SCHIZO_PCICFG_WRITE_8(sc, offs, v) \ SCHIZO_SPC_WRITE_8(STX_PCICFG, (sc), (offs), (v)) -#define SCHIZO_ICON_READ_8(sc, offs) \ +#define SCHIZO_ICON_READ_8(sc, offs) \ SCHIZO_SPC_READ_8(STX_ICON, (sc), (offs)) -#define SCHIZO_ICON_WRITE_8(sc, offs, v) \ +#define SCHIZO_ICON_WRITE_8(sc, offs, v) \ SCHIZO_SPC_WRITE_8(STX_ICON, (sc), (offs), (v)) struct schizo_desc { @@ -1054,7 +1054,7 @@ schizo_dma_sync_stub(void *arg) for (; atomic_cmpset_acq_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_DONE, SCHIZO_CDMA_STATE_PENDING) == 0;) ; - SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, 1); + SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, INTCLR_RECEIVED); microuptime(&cur); end.tv_sec = 1; end.tv_usec = 0; @@ -1139,7 +1139,7 @@ schizo_intr_clear(void *arg) struct intr_vector *iv = arg; struct schizo_icarg *sica = iv->iv_icarg; - SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_clr, 0); + SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_clr, INTCLR_IDLE); } static int diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c index 0c4b509e508..597d382a813 100644 --- a/sys/sparc64/sbus/sbus.c +++ b/sys/sparc64/sbus/sbus.c @@ -171,9 +171,9 @@ struct sbus_softc { void *sc_pf_ihand; }; -#define SYSIO_READ8(sc, off) \ +#define SYSIO_READ8(sc, off) \ bus_read_8((sc)->sc_sysio_res, (off)) -#define SYSIO_WRITE8(sc, off, v) \ +#define SYSIO_WRITE8(sc, off, v) \ bus_write_8((sc)->sc_sysio_res, (off), (v)) static device_probe_t sbus_probe; @@ -697,7 +697,7 @@ sbus_intr_clear(void *arg) struct intr_vector *iv = arg; struct sbus_icarg *sica = iv->iv_icarg; - SYSIO_WRITE8(sica->sica_sc, sica->sica_clr, 0); + SYSIO_WRITE8(sica->sica_sc, sica->sica_clr, INTCLR_IDLE); } static int From 1592a77552b2bc032f823381220a4ad50791ca68 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Mon, 5 Apr 2010 17:58:47 +0000 Subject: [PATCH 1829/2592] MFC: r206019 Don't re-implement device_get_nameunit(9). --- sys/sparc64/pci/apb.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/sys/sparc64/pci/apb.c b/sys/sparc64/pci/apb.c index 2f4932e2c1c..098e191f463 100644 --- a/sys/sparc64/pci/apb.c +++ b/sys/sparc64/pci/apb.c @@ -223,8 +223,7 @@ apb_alloc_resource(device_t dev, device_t child, int type, int *rid, */ if (start == 0 && end == ~0) { device_printf(dev, "can't decode default resource id %d for " - "%s%d, bypassing\n", *rid, device_get_name(child), - device_get_unit(child)); + "%s, bypassing\n", *rid, device_get_nameunit(child)); goto passup; } @@ -236,31 +235,28 @@ apb_alloc_resource(device_t dev, device_t child, int type, int *rid, switch (type) { case SYS_RES_IOPORT: if (!apb_checkrange(sc->sc_iomap, APB_IO_SCALE, start, end)) { - device_printf(dev, "device %s%d requested unsupported " - "I/O range 0x%lx-0x%lx\n", device_get_name(child), - device_get_unit(child), start, end); + device_printf(dev, "device %s requested unsupported " + "I/O range 0x%lx-0x%lx\n", + device_get_nameunit(child), start, end); return (NULL); } if (bootverbose) device_printf(sc->sc_bsc.ops_pcib_sc.dev, "device " - "%s%d requested decoded I/O range 0x%lx-0x%lx\n", - device_get_name(child), device_get_unit(child), - start, end); + "%s requested decoded I/O range 0x%lx-0x%lx\n", + device_get_nameunit(child), start, end); break; case SYS_RES_MEMORY: if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start, end)) { - device_printf(dev, "device %s%d requested unsupported " + device_printf(dev, "device %s requested unsupported " "memory range 0x%lx-0x%lx\n", - device_get_name(child), device_get_unit(child), - start, end); + device_get_nameunit(child), start, end); return (NULL); } if (bootverbose) device_printf(sc->sc_bsc.ops_pcib_sc.dev, "device " - "%s%d requested decoded memory range 0x%lx-0x%lx\n", - device_get_name(child), device_get_unit(child), - start, end); + "%s requested decoded memory range 0x%lx-0x%lx\n", + device_get_nameunit(child), start, end); break; default: From bd7099bd198760cc91eabc4663123aed39c42942 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Mon, 5 Apr 2010 18:04:01 +0000 Subject: [PATCH 1830/2592] MFC: r206020 Use device_get_nameunit(9) rather than device_get_name(9) so one can identify the reporting bridge in machines with multiple PCI domains. --- sys/sparc64/pci/psycho.c | 4 ++-- sys/sparc64/pci/schizo.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index 3cc8ed0da3a..28933f5f6c1 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -808,7 +808,7 @@ psycho_ue(void *arg) if ((afsr & UEAFSR_P_DTE) != 0) iommu_decode_fault(sc->sc_is, afar); panic("%s: uncorrectable DMA error AFAR %#lx AFSR %#lx", - device_get_name(sc->sc_dev), (u_long)afar, (u_long)afsr); + device_get_nameunit(sc->sc_dev), (u_long)afar, (u_long)afsr); return (FILTER_HANDLED); } @@ -838,7 +838,7 @@ psycho_pci_bus(void *arg) afar = PCICTL_READ8(sc, PCR_AFA); afsr = PCICTL_READ8(sc, PCR_AFS); panic("%s: PCI bus %c error AFAR %#lx AFSR %#lx", - device_get_name(sc->sc_dev), 'A' + sc->sc_half, (u_long)afar, + device_get_nameunit(sc->sc_dev), 'A' + sc->sc_half, (u_long)afar, (u_long)afsr); return (FILTER_HANDLED); } diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c index 7de51880789..865b0c4f254 100644 --- a/sys/sparc64/pci/schizo.c +++ b/sys/sparc64/pci/schizo.c @@ -803,7 +803,7 @@ schizo_pci_bus(void *arg) } panic("%s: PCI bus %c error AFAR %#llx AFSR %#llx PCI CSR %#llx " - "IOMMU %#llx STATUS %#llx", device_get_name(sc->sc_dev), + "IOMMU %#llx STATUS %#llx", device_get_nameunit(sc->sc_dev), 'A' + sc->sc_half, (unsigned long long)afar, (unsigned long long)afsr, (unsigned long long)csr, (unsigned long long)iommu, (unsigned long long)status); @@ -838,7 +838,7 @@ schizo_ue(void *arg) break; mtx_unlock_spin(sc->sc_mtx); panic("%s: uncorrectable DMA error AFAR %#llx AFSR %#llx", - device_get_name(sc->sc_dev), (unsigned long long)afar, + device_get_nameunit(sc->sc_dev), (unsigned long long)afar, (unsigned long long)afsr); return (FILTER_HANDLED); } @@ -872,7 +872,7 @@ schizo_host_bus(void *arg) uint64_t errlog; errlog = SCHIZO_CTRL_READ_8(sc, STX_CTRL_BUS_ERRLOG); - panic("%s: %s error %#llx", device_get_name(sc->sc_dev), + panic("%s: %s error %#llx", device_get_nameunit(sc->sc_dev), sc->sc_mode == SCHIZO_MODE_TOM ? "JBus" : "Safari", (unsigned long long)errlog); return (FILTER_HANDLED); From 59a8fbd20867bb3c7e00c229650a7ee1392beef8 Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Mon, 5 Apr 2010 18:22:42 +0000 Subject: [PATCH 1831/2592] This is an MFC of 205698 Clean up some printing stuff so that we can have a bit finer control on debug output. Add a new platform function requirement to allow for printing based upon the ITL nexus instead of the isp unit plus channel, target and lun. This allows some printouts and error messages from the core code to appear in the same format as the platform's subsystem (in FreeBSD's case, CAM path). --- sys/dev/isp/isp.c | 221 +++++++++++++------------------------- sys/dev/isp/isp_freebsd.c | 14 +++ sys/dev/isp/isp_freebsd.h | 5 +- sys/dev/isp/ispvar.h | 10 +- 4 files changed, 100 insertions(+), 150 deletions(-) diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index b05496ca797..0d00bb4a31e 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -74,14 +74,9 @@ __FBSDID("$FreeBSD$"); */ static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)"; static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d"; -static const char xact1[] = "HBA attempted queued transaction with disconnect not set for %d.%d.%d"; -static const char xact2[] = "HBA attempted queued transaction to target routine %d on target %d bus %d"; -static const char xact3[] = "HBA attempted queued cmd for %d.%d.%d when queueing disabled"; -static const char pskip[] = "SCSI phase skipped for target %d.%d.%d"; static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'"; -static const char finmsg[] = "%d.%d.%d: FIN dl%d resid %ld STS 0x%x SKEY %c XS_ERR=0x%x"; static const char sc4[] = "NVRAM"; -static const char bun[] = "bad underrun for %d.%d (count %d, resid %d, status %s)"; +static const char bun[] = "bad underrun (count %d, resid %d, status %s)"; static const char lipd[] = "Chan %d LIP destroyed %d active commands"; static const char sacq[] = "unable to acquire scratch area"; @@ -107,6 +102,7 @@ static const uint8_t alpa_map[] = { /* * Local function prototypes. */ +static void isp_prt_endcmd(ispsoftc_t *, XS_T *); static int isp_parse_async(ispsoftc_t *, uint16_t); static int isp_parse_async_fc(ispsoftc_t *, uint16_t); static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *); @@ -1431,10 +1427,8 @@ isp_scsi_channel_init(ispsoftc_t *isp, int chan) (sdp->isp_devparam[tgt].goal_offset << 8) | (sdp->isp_devparam[tgt].goal_period); } - isp_prt(isp, ISP_LOGDEBUG0, - "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x", - chan, tgt, mbs.param[2], mbs.param[3] >> 8, - mbs.param[3] & 0xff); + isp_prt(isp, ISP_LOGDEBUG0, "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x", + chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { sdf = DPARM_SAFE_DFLT; @@ -1705,8 +1699,7 @@ isp_fibre_init(ispsoftc_t *isp) isp_prt(isp, ISP_LOGERR, sacq); return; } - isp_prt(isp, ISP_LOGDEBUG0, - "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x", + isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x", icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions); isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch); @@ -4432,7 +4425,7 @@ isp_start(XS_T *xs) */ return (dmaresult); } - isp_prt(isp, ISP_LOGDEBUG0, "START cmd for %d.%d.%d cmd 0x%x datalen %ld", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0], (long) XS_XFRLEN(xs)); + isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs)); isp->isp_nactive++; return (CMD_QUEUED); } @@ -5245,7 +5238,7 @@ again: } else { ptr = rnames[resp[FCP_RSPNS_CODE_OFFSET]]; } - isp_prt(isp, ISP_LOGWARN, "%d.%d.%d FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), rlen, ptr, XS_CDBP(xs)[0] & 0xff); + isp_xs_prt(isp, xs, ISP_LOGWARN, "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", rlen, ptr, XS_CDBP(xs)[0] & 0xff); if (resp[FCP_RSPNS_CODE_OFFSET] != 0) { XS_SETERR(xs, HBA_BOTCH); } @@ -5322,25 +5315,9 @@ again: isp_destroy_handle(isp, sp->req_handle); if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) || - ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) || - (*XS_STSP(xs) != SCSI_GOOD)))) { - char skey; - if (req_state_flags & RQSF_GOT_SENSE) { - skey = XS_SNSKEY(xs) & 0xf; - if (skey < 10) - skey += '0'; - else - skey += 'a' - 10; - } else if (*XS_STSP(xs) == SCSI_CHECK) { - skey = '?'; - } else { - skey = '.'; - } - isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs), - XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), (long) XS_GET_RESID(xs), - *XS_STSP(xs), skey, XS_ERR(xs)); + ((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) { + isp_prt_endcmd(isp, xs); } - if (isp->isp_nactive > 0) { isp->isp_nactive--; } @@ -5390,6 +5367,25 @@ out: * Support routines. */ +static void +isp_prt_endcmd(ispsoftc_t *isp, XS_T *xs) +{ + char cdbstr[16 * 5 + 1]; + int i, lim; + + lim = XS_CDBLEN(xs) > 16? 16 : XS_CDBLEN(xs); + ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "0x%02x ", XS_CDBP(xs)[0]); + for (i = 1; i < lim; i++) { + ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "%s0x%02x ", cdbstr, XS_CDBP(xs)[i]); + } + if (XS_SENSE_VALID(xs)) { + isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s KEY/ASC/ASCQ=0x%02x/0x%02x/0x%02x", + XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, XS_SNSKEY(xs), XS_SNSASC(xs), XS_SNSASCQ(xs)); + } else { + isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s STS 0x%x XS_ERR=0x%x", XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, *XS_STSP(xs), XS_ERR(xs)); + } +} + /* * Parse an ASYNC mailbox complete * @@ -5934,8 +5930,7 @@ isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox) */ static int -isp_handle_other_response(ispsoftc_t *isp, int type, - isphdr_t *hp, uint32_t *optrp) +isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp) { switch (type) { case RQSTYPE_STATUS_CONT: @@ -6007,24 +6002,18 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) case RQCS_INCOMPLETE: if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) { - isp_prt(isp, ISP_LOGDEBUG1, - "Selection Timeout for %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGDEBUG1, "Selection Timeout"); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_SELTIMEOUT); *rp = XS_XFRLEN(xs); } return; } - isp_prt(isp, ISP_LOGERR, - "command incomplete for %d.%d.%d, state 0x%x", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), - sp->req_state_flags); + isp_xs_prt(isp, xs, ISP_LOGERR, "Command Incomplete, state 0x%x", sp->req_state_flags); break; case RQCS_DMA_ERROR: - isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "DMA Error"); *rp = XS_XFRLEN(xs); break; @@ -6078,18 +6067,14 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) if (sp->req_status_flags & RQSTF_NEGOTIATION) { ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf); } - isp_prt(isp, ISP_LOGERR, "%s", buf); - isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf); + isp_xs_prt(isp, xs, ISP_LOGERR, "Transport Error: %s", buf); *rp = XS_XFRLEN(xs); break; } case RQCS_RESET_OCCURRED: { int chan; - isp_prt(isp, ISP_LOGWARN, - "bus reset destroyed command for %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGWARN, "Bus Reset destroyed command"); for (chan = 0; chan < isp->isp_nchan; chan++) { FCPARAM(isp, chan)->sendmarker = 1; } @@ -6100,8 +6085,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) return; } case RQCS_ABORTED: - isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted"); ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_ABORTED); @@ -6109,8 +6093,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) return; case RQCS_TIMEOUT: - isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGWARN, "Command timed out"); /* * XXX: Check to see if we logged out of the device. */ @@ -6121,83 +6104,62 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) case RQCS_DATA_OVERRUN: XS_SET_RESID(xs, sp->req_resid); - isp_prt(isp, ISP_LOGERR, "data overrun (%ld) for command on %d.%d.%d", - (long) XS_GET_RESID(xs), XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "data overrun (%ld)", (long) XS_GET_RESID(xs)); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_DATAOVR); } return; case RQCS_COMMAND_OVERRUN: - isp_prt(isp, ISP_LOGERR, - "command overrun for command on %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "command overrun"); break; case RQCS_STATUS_OVERRUN: - isp_prt(isp, ISP_LOGERR, - "status overrun for command on %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "status overrun"); break; case RQCS_BAD_MESSAGE: - isp_prt(isp, ISP_LOGERR, - "msg not COMMAND COMPLETE after status %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "msg not COMMAND COMPLETE after status"); break; case RQCS_NO_MESSAGE_OUT: - isp_prt(isp, ISP_LOGERR, - "No MESSAGE OUT phase after selection on %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "No MESSAGE OUT phase after selection"); break; case RQCS_EXT_ID_FAILED: - isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "EXTENDED IDENTIFY failed"); break; case RQCS_IDE_MSG_FAILED: - isp_prt(isp, ISP_LOGERR, - "INITIATOR DETECTED ERROR rejected by %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "INITIATOR DETECTED ERROR rejected"); break; case RQCS_ABORT_MSG_FAILED: - isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "ABORT OPERATION rejected"); break; case RQCS_REJECT_MSG_FAILED: - isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE REJECT rejected"); break; case RQCS_NOP_MSG_FAILED: - isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "NOP rejected"); break; case RQCS_PARITY_ERROR_MSG_FAILED: - isp_prt(isp, ISP_LOGERR, - "MESSAGE PARITY ERROR rejected by %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE PARITY ERROR rejected"); break; case RQCS_DEVICE_RESET_MSG_FAILED: - isp_prt(isp, ISP_LOGWARN, - "BUS DEVICE RESET rejected by %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGWARN, "BUS DEVICE RESET rejected"); break; case RQCS_ID_MSG_FAILED: - isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "IDENTIFY rejected"); break; case RQCS_UNEXP_BUS_FREE: - isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "Unexpected Bus Free"); break; case RQCS_DATA_UNDERRUN: @@ -6205,9 +6167,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) if (IS_FC(isp)) { int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0; if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) { - isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs), - XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid, - (ru_marked)? "marked" : "not marked"); + isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked"); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_BOTCH); } @@ -6222,18 +6182,15 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) } case RQCS_XACT_ERR1: - isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs), - XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction with disconnect not set"); break; case RQCS_XACT_ERR2: - isp_prt(isp, ISP_LOGERR, xact2, - XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction to target routine %d", XS_LUN(xs)); break; case RQCS_XACT_ERR3: - isp_prt(isp, ISP_LOGERR, xact3, - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued cmd when queueing disabled"); break; case RQCS_BAD_ENTRY: @@ -6241,9 +6198,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) break; case RQCS_QUEUE_FULL: - isp_prt(isp, ISP_LOGDEBUG0, - "internal queues full for %d.%d.%d status 0x%x", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs)); + isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "internal queues full status 0x%x", *XS_STSP(xs)); /* * If QFULL or some other status byte is set, then this @@ -6267,23 +6222,18 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) return; case RQCS_PHASE_SKIPPED: - isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs), - XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "SCSI phase skipped"); break; case RQCS_ARQS_FAILED: - isp_prt(isp, ISP_LOGERR, - "Auto Request Sense failed for %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "Auto Request Sense Failed"); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_ARQFAIL); } return; case RQCS_WIDE_FAILED: - isp_prt(isp, ISP_LOGERR, - "Wide Negotiation failed for %d.%d.%d", - XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "Wide Negotiation Failed"); if (IS_SCSI(isp)) { sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs)); sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE; @@ -6296,9 +6246,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) return; case RQCS_SYNCXFER_FAILED: - isp_prt(isp, ISP_LOGERR, - "SDTR Message failed for target %d.%d.%d", - XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "SDTR Message Failed"); if (IS_SCSI(isp)) { sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs)); sdp += XS_CHANNEL(xs); @@ -6309,9 +6257,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) break; case RQCS_LVD_BUSERR: - isp_prt(isp, ISP_LOGERR, - "Bad LVD condition while talking to %d.%d.%d", - XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "Bad LVD condition"); break; case RQCS_PORT_UNAVAILABLE: @@ -6381,8 +6327,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) } static void -isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, - XS_T *xs, long *rp) +isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, long *rp) { int ru_marked, sv_marked; int chan = XS_CHANNEL(xs); @@ -6395,19 +6340,15 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, return; case RQCS_DMA_ERROR: - isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error"); break; case RQCS_TRANSPORT_ERROR: - isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "Transport Error"); break; case RQCS_RESET_OCCURRED: - isp_prt(isp, ISP_LOGWARN, - "reset destroyed command for %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command"); FCPARAM(isp, chan)->sendmarker = 1; if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_BUSRESET); @@ -6415,8 +6356,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, return; case RQCS_ABORTED: - isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted"); FCPARAM(isp, chan)->sendmarker = 1; if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_ABORTED); @@ -6424,8 +6364,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, return; case RQCS_TIMEOUT: - isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out"); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_CMDTIMEOUT); } @@ -6433,9 +6372,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, case RQCS_DATA_OVERRUN: XS_SET_RESID(xs, sp->req_resid); - isp_prt(isp, ISP_LOGERR, - "data overrun for command on %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun"); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_DATAOVR); } @@ -6468,19 +6405,14 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0; if ((ru_marked == 0 && sv_marked == 0) || (sp->req_resid > XS_XFRLEN(xs))) { - isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs), - XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid, - (ru_marked)? "marked" : "not marked"); + isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked"); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_BOTCH); } return; } XS_SET_RESID(xs, sp->req_resid); - isp_prt(isp, ISP_LOGDEBUG0, - "%d.%d.%d data underrun (%d) for command 0x%x", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), - sp->req_resid, XS_CDBP(xs)[0] & 0xff); + isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_NOERROR); } @@ -7381,8 +7313,7 @@ isp_spi_update(ispsoftc_t *isp, int chan) if (sdp->isp_devparam[tgt].dev_enable == 0) { sdp->isp_devparam[tgt].dev_update = 0; sdp->isp_devparam[tgt].dev_refresh = 0; - isp_prt(isp, ISP_LOGDEBUG0, - "skipping target %d bus %d update", tgt, chan); + isp_prt(isp, ISP_LOGDEBUG0, "skipping target %d bus %d update", tgt, chan); continue; } /* @@ -7438,10 +7369,8 @@ isp_spi_update(ispsoftc_t *isp, int chan) sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING; sdp->isp_devparam[tgt].actv_flags |= (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING); - isp_prt(isp, ISP_LOGDEBUG0, - "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x", - chan, tgt, mbs.param[2], mbs.param[3] >> 8, - mbs.param[3] & 0xff); + isp_prt(isp, ISP_LOGDEBUG0, "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x", + chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff); get = 0; } else { continue; @@ -7775,8 +7704,7 @@ isp_read_nvram(ispsoftc_t *isp, int bus) nvram_data[2] != 'P') { if (isp->isp_bustype != ISP_BT_SBUS) { isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header"); - isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", - nvram_data[0], nvram_data[1], nvram_data[2]); + isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", nvram_data[0], nvram_data[1], nvram_data[2]); } retval = -1; goto out; @@ -8291,8 +8219,7 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data) ISP2100_NVRAM_TOV(nvram_data)); fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data); fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data); - isp_prt(isp, ISP_LOGDEBUG0, - "xfwoptions 0x%x zfw options 0x%x", + isp_prt(isp, ISP_LOGDEBUG0, "xfwoptions 0x%x zfw options 0x%x", ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data)); } diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index da03aea9652..8e1d07b6f38 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -5420,6 +5420,20 @@ isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...) printf("\n"); } +void +isp_xs_prt(ispsoftc_t *isp, XS_T *xs, int level, const char *fmt, ...) +{ + va_list ap; + if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) { + return; + } + xpt_print_path(xs->ccb_h.path); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("\n"); +} + uint64_t isp_nanotime_sub(struct timespec *b, struct timespec *a) { diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h index 29425940c05..e1d7a87cadf 100644 --- a/sys/dev/isp/isp_freebsd.h +++ b/sys/dev/isp/isp_freebsd.h @@ -424,6 +424,8 @@ default: \ imin((sizeof((ccb)->sense_data)), ccb->sense_len) #define XS_SNSKEY(ccb) ((ccb)->sense_data.flags & 0xf) +#define XS_SNSASC(ccb) ((ccb)->sense_data.add_sense_code) +#define XS_SNSASCQ(ccb) ((ccb)->sense_data.add_sense_code_qual) #define XS_TAG_P(ccb) \ (((ccb)->ccb_h.flags & CAM_TAG_ACTION_VALID) && \ (ccb)->tag_action != CAM_TAG_ACTION_NONE) @@ -461,7 +463,7 @@ default: \ (xs)->ccb_h.status |= CAM_AUTOSNS_VALID; \ memcpy(&(xs)->sense_data, sense_ptr, imin(XS_SNSLEN(xs), sense_len)) -#define XS_SET_STATE_STAT(a, b, c) +#define XS_SENSE_VALID(xs) (((xs)->ccb_h.status & CAM_AUTOSNS_VALID) != 0) #define DEFAULT_FRAMESIZE(isp) isp->isp_osinfo.framesize #define DEFAULT_EXEC_THROTTLE(isp) isp->isp_osinfo.exec_throttle @@ -593,6 +595,7 @@ extern int isp_autoconfig; * Platform Library Functions */ void isp_prt(ispsoftc_t *, int level, const char *, ...) __printflike(3, 4); +void isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...) __printflike(4, 5); uint64_t isp_nanotime_sub(struct timespec *, struct timespec *); int isp_mbox_acquire(ispsoftc_t *); void isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *); diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index 5c8508c87c4..e4bf8698670 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -954,12 +954,13 @@ void isp_async(ispsoftc_t *, ispasync_t, ...); /* * Platform Dependent Error and Debug Printout * - * Generally this is: + * Two required functions for each platform must be provided: * * void isp_prt(ispsoftc_t *, int level, const char *, ...) + * void isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...) * * but due to compiler differences on different platforms this won't be - * formally done here. Instead, it goes in each platform definition file. + * formally defined here. Instead, they go in each platform definition file. */ #define ISP_LOGALL 0x0 /* log always */ @@ -972,6 +973,7 @@ void isp_async(ispsoftc_t *, ispasync_t, ...); #define ISP_LOGDEBUG2 0x40 /* log most debug messages */ #define ISP_LOGDEBUG3 0x80 /* log high frequency debug messages */ #define ISP_LOGSANCFG 0x100 /* log SAN configuration */ +#define ISP_LOG_CWARN 0x200 /* log SCSI command "warnings" (e.g., check conditions) */ #define ISP_LOGTINFO 0x1000 /* log informational messages (target mode) */ #define ISP_LOGTDEBUG0 0x2000 /* log simple debug messages (target mode) */ #define ISP_LOGTDEBUG1 0x4000 /* log intermediate debug messages (target) */ @@ -1045,6 +1047,8 @@ void isp_async(ispsoftc_t *, ispasync_t, ...); * XS_SNSP(xs) gets a pointer to the associate sense data * XS_SNSLEN(xs) gets the length of sense data storage * XS_SNSKEY(xs) dereferences XS_SNSP to get the current stored Sense Key + * XS_SNSASC(xs) dereferences XS_SNSP to get the current stored Additional Sense Code + * XS_SNSASCQ(xs) dereferences XS_SNSP to get the current stored Additional Sense Code Qualifier * XS_TAG_P(xs) predicate of whether this command should be tagged * XS_TAG_TYPE(xs) which type of tag to use * XS_SETERR(xs) set error state @@ -1065,6 +1069,8 @@ void isp_async(ispsoftc_t *, ispasync_t, ...); * * XS_SAVE_SENSE(xs, sp, len) save sense data * + * XS_SENSE_VALID(xs) indicates whether sense is valid + * * DEFAULT_FRAMESIZE(ispsoftc_t *) Default Frame Size * DEFAULT_EXEC_THROTTLE(ispsoftc_t *) Default Execution Throttle * From 3d9988b326bfb446aa420ab760bb7f58bf3ae6e8 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Mon, 5 Apr 2010 18:25:30 +0000 Subject: [PATCH 1832/2592] MFC: r206086 - Try do deal gracefully with correctable ECC errors. - Improve the reporting of unhandled kernel and user traps. --- sys/sparc64/sparc64/trap.c | 58 ++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c index e8650385708..c451907f358 100644 --- a/sys/sparc64/sparc64/trap.c +++ b/sys/sparc64/sparc64/trap.c @@ -106,6 +106,7 @@ void trap(struct trapframe *tf); void syscall(struct trapframe *tf); static int fetch_syscall_args(struct thread *td, struct syscall_args *sa); +static int trap_cecc(void); static int trap_pfault(struct thread *td, struct trapframe *tf); extern char copy_fault[]; @@ -240,6 +241,10 @@ int debugger_on_signal = 0; SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW, &debugger_on_signal, 0, ""); +u_int corrected_ecc = 0; +SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0, + "corrected ECC errors"); + /* * SUNW,set-trap-table allows to take over %tba from the PROM, which * will turn off interrupts and handle outstanding ones while doing so, @@ -308,10 +313,16 @@ trap(struct trapframe *tf) case T_SPILL: sig = rwindow_save(td); break; + case T_CORRECTED_ECC_ERROR: + sig = trap_cecc(); + break; default: - if (tf->tf_type < 0 || tf->tf_type >= T_MAX || - trap_sig[tf->tf_type] == -1) - panic("trap: bad trap type"); + if (tf->tf_type < 0 || tf->tf_type >= T_MAX) + panic("trap: bad trap type %#lx (user)", + tf->tf_type); + else if (trap_sig[tf->tf_type] == -1) + panic("trap: %s (user)", + trap_msg[tf->tf_type]); sig = trap_sig[tf->tf_type]; break; } @@ -400,17 +411,52 @@ trap(struct trapframe *tf) } error = 1; break; + case T_CORRECTED_ECC_ERROR: + error = trap_cecc(); + break; default: error = 1; break; } - if (error != 0) - panic("trap: %s", trap_msg[tf->tf_type & ~T_KERNEL]); + if (error != 0) { + tf->tf_type &= ~T_KERNEL; + if (tf->tf_type < 0 || tf->tf_type >= T_MAX) + panic("trap: bad trap type %#lx (kernel)", + tf->tf_type); + else if (trap_sig[tf->tf_type] == -1) + panic("trap: %s (kernel)", + trap_msg[tf->tf_type]); + } } CTR1(KTR_TRAP, "trap: td=%p return", td); } +static int +trap_cecc(void) +{ + u_long eee; + + /* + * Turn off (non-)correctable error reporting while we're dealing + * with the error. + */ + eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG); + stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN | + AA_ESTATE_CEEN)); + /* Flush the caches in order ensure no corrupt data got installed. */ + cache_flush(); + /* Ensure the caches are still turned on (should be). */ + cache_enable(PCPU_GET(impl)); + /* Clear the the error from the AFSR. */ + stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR)); + corrected_ecc++; + printf("corrected ECC error\n"); + /* Turn (non-)correctable error reporting back on. */ + stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee); + return (0); +} + static int trap_pfault(struct thread *td, struct trapframe *tf) { @@ -667,7 +713,7 @@ syscall(struct trapframe *tf) */ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? - syscallnames[sa.code] : "???"); + syscallnames[sa.code] : "???"); KASSERT(td->td_critnest == 0, ("System call %s returning in a critical section", (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ? From be5d0cf41323e4db4b6912fdd8b5cfd35958766c Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Mon, 5 Apr 2010 18:36:47 +0000 Subject: [PATCH 1833/2592] This is an MFC of 205712. D'oh- isp_handle_index' logic was reversed (not used in FreeBSD). --- sys/dev/isp/isp_library.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c index 43c161d2782..020193394d9 100644 --- a/sys/dev/isp/isp_library.c +++ b/sys/dev/isp/isp_library.c @@ -294,10 +294,10 @@ uint32_t isp_handle_index(ispsoftc_t *isp, uint32_t handle) { if (!ISP_VALID_HANDLE(isp, handle)) { - return (handle & ISP_HANDLE_CMD_MASK); - } else { isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle); return (ISP_BAD_HANDLE_INDEX); + } else { + return (handle & ISP_HANDLE_CMD_MASK); } } From d4e2e2a53f013f49b53afe5785c9eba0cab99712 Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Mon, 5 Apr 2010 18:46:29 +0000 Subject: [PATCH 1834/2592] MFC of version 2.1.7 of the ixgbe driver. --- sys/dev/ixgbe/LICENSE | 2 +- sys/dev/ixgbe/ixgbe.c | 2372 +++++++++++++++++----------------- sys/dev/ixgbe/ixgbe.h | 214 +-- sys/dev/ixgbe/ixgbe_82598.c | 302 ++++- sys/dev/ixgbe/ixgbe_82599.c | 1043 ++++++--------- sys/dev/ixgbe/ixgbe_api.c | 61 +- sys/dev/ixgbe/ixgbe_api.h | 10 +- sys/dev/ixgbe/ixgbe_common.c | 1067 +++++++++++++-- sys/dev/ixgbe/ixgbe_common.h | 27 +- sys/dev/ixgbe/ixgbe_osdep.h | 10 + sys/dev/ixgbe/ixgbe_phy.c | 355 ++++- sys/dev/ixgbe/ixgbe_phy.h | 13 +- sys/dev/ixgbe/ixgbe_type.h | 196 ++- 13 files changed, 3495 insertions(+), 2177 deletions(-) diff --git a/sys/dev/ixgbe/LICENSE b/sys/dev/ixgbe/LICENSE index 39264e087be..0cf44c8581e 100644 --- a/sys/dev/ixgbe/LICENSE +++ b/sys/dev/ixgbe/LICENSE @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index b9fdab516de..f8338e9aee4 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ int ixgbe_display_debug_stats = 0; /********************************************************************* * Driver version *********************************************************************/ -char ixgbe_driver_version[] = "1.8.9"; +char ixgbe_driver_version[] = "2.1.7"; /********************************************************************* * PCI Device ID Table @@ -64,16 +64,20 @@ static ixgbe_vendor_info_t ixgbe_vendor_info_array[] = {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AF_SINGLE_PORT, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_CX4, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT2, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_DA_DUAL_PORT, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_CX4_DUAL_PORT, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_XF_LR, 0, 0, 0}, - {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_SFP_LOM, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KX4, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KX4_MEZZ, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_XAUI_LOM, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_CX4, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_T3_LOM, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_COMBO_BACKPLANE, 0, 0, 0}, /* required last entry */ {0, 0, 0, 0, 0} }; @@ -102,9 +106,8 @@ static int ixgbe_mq_start_locked(struct ifnet *, static void ixgbe_qflush(struct ifnet *); #endif static int ixgbe_ioctl(struct ifnet *, u_long, caddr_t); -static void ixgbe_watchdog(struct adapter *); -static void ixgbe_init(void *); -static void ixgbe_init_locked(struct adapter *); +static void ixgbe_init(void *); +static int ixgbe_init_locked(struct adapter *); static void ixgbe_stop(void *); static void ixgbe_media_status(struct ifnet *, struct ifmediareq *); static int ixgbe_media_change(struct ifnet *); @@ -116,8 +119,8 @@ static int ixgbe_allocate_queues(struct adapter *); static int ixgbe_setup_msix(struct adapter *); static void ixgbe_free_pci_resources(struct adapter *); static void ixgbe_local_timer(void *); -static int ixgbe_hardware_init(struct adapter *); static void ixgbe_setup_interface(device_t, struct adapter *); +static void ixgbe_config_link(struct adapter *); static int ixgbe_allocate_transmit_buffers(struct tx_ring *); static int ixgbe_setup_transmit_structures(struct adapter *); @@ -132,21 +135,21 @@ static int ixgbe_setup_receive_ring(struct rx_ring *); static void ixgbe_initialize_receive_units(struct adapter *); static void ixgbe_free_receive_structures(struct adapter *); static void ixgbe_free_receive_buffers(struct rx_ring *); +static void ixgbe_setup_hw_rsc(struct rx_ring *); -static void ixgbe_init_moderation(struct adapter *); static void ixgbe_enable_intr(struct adapter *); static void ixgbe_disable_intr(struct adapter *); static void ixgbe_update_stats_counters(struct adapter *); static bool ixgbe_txeof(struct tx_ring *); -static bool ixgbe_rxeof(struct rx_ring *, int); -static void ixgbe_rx_checksum(u32, struct mbuf *); +static bool ixgbe_rxeof(struct ix_queue *, int); +static void ixgbe_rx_checksum(u32, struct mbuf *, u32); static void ixgbe_set_promisc(struct adapter *); static void ixgbe_disable_promisc(struct adapter *); static void ixgbe_set_multi(struct adapter *); static void ixgbe_print_hw_stats(struct adapter *); static void ixgbe_print_debug_info(struct adapter *); static void ixgbe_update_link_status(struct adapter *); -static int ixgbe_get_buf(struct rx_ring *, int, u8); +static void ixgbe_refresh_mbufs(struct rx_ring *, int); static int ixgbe_xmit(struct tx_ring *, struct mbuf **); static int ixgbe_sysctl_stats(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_debug(SYSCTL_HANDLER_ARGS); @@ -166,7 +169,9 @@ static void ixgbe_setup_vlan_hw_support(struct adapter *); static void ixgbe_register_vlan(void *, struct ifnet *, u16); static void ixgbe_unregister_vlan(void *, struct ifnet *, u16); -static void ixgbe_update_aim(struct rx_ring *); +static __inline void ixgbe_rx_discard(struct rx_ring *, int); +static __inline void ixgbe_rx_input(struct rx_ring *, struct ifnet *, + struct mbuf *, u32); /* Support for pluggable optic modules */ static bool ixgbe_sfp_probe(struct adapter *); @@ -175,17 +180,19 @@ static bool ixgbe_sfp_probe(struct adapter *); static void ixgbe_legacy_irq(void *); /* The MSI/X Interrupt handlers */ -static void ixgbe_msix_tx(void *); -static void ixgbe_msix_rx(void *); +static void ixgbe_msix_que(void *); static void ixgbe_msix_link(void *); /* Deferred interrupt tasklets */ -static void ixgbe_handle_tx(void *, int); -static void ixgbe_handle_rx(void *, int); +static void ixgbe_handle_que(void *, int); static void ixgbe_handle_link(void *, int); static void ixgbe_handle_msf(void *, int); static void ixgbe_handle_mod(void *, int); +#ifdef IXGBE_FDIR +static void ixgbe_atr(struct tx_ring *, struct mbuf *); +static void ixgbe_reinit_fdir(void *, int); +#endif /********************************************************************* * FreeBSD Device Interface Entry Points @@ -215,29 +222,31 @@ MODULE_DEPEND(ixgbe, ether, 1, 1, 1); */ /* -** These parameters are used in Adaptive -** Interrupt Moderation. The value is set -** into EITR and controls the interrupt -** frequency. They can be modified but -** be careful in tuning them. +** AIM: Adaptive Interrupt Moderation +** which means that the interrupt rate +** is varied over time based on the +** traffic for that interrupt vector */ static int ixgbe_enable_aim = TRUE; TUNABLE_INT("hw.ixgbe.enable_aim", &ixgbe_enable_aim); -static int ixgbe_low_latency = IXGBE_LOW_LATENCY; -TUNABLE_INT("hw.ixgbe.low_latency", &ixgbe_low_latency); -static int ixgbe_ave_latency = IXGBE_AVE_LATENCY; -TUNABLE_INT("hw.ixgbe.ave_latency", &ixgbe_ave_latency); -static int ixgbe_bulk_latency = IXGBE_BULK_LATENCY; -TUNABLE_INT("hw.ixgbe.bulk_latency", &ixgbe_bulk_latency); /* How many packets rxeof tries to clean at a time */ -static int ixgbe_rx_process_limit = 100; +static int ixgbe_rx_process_limit = 128; TUNABLE_INT("hw.ixgbe.rx_process_limit", &ixgbe_rx_process_limit); /* Flow control setting, default to full */ static int ixgbe_flow_control = ixgbe_fc_full; TUNABLE_INT("hw.ixgbe.flow_control", &ixgbe_flow_control); +/* +** Smart speed setting, default to on +** this only works as a compile option +** right now as its during attach, set +** this to 'ixgbe_smart_speed_off' to +** disable. +*/ +static int ixgbe_smart_speed = ixgbe_smart_speed_on; + /* * MSIX should be the default for best performance, * but this allows it to be forced off for testing. @@ -255,23 +264,27 @@ static bool ixgbe_header_split = TRUE; TUNABLE_INT("hw.ixgbe.hdr_split", &ixgbe_header_split); /* - * Number of Queues, should normally - * be left at 0, it then autoconfigures to - * the number of cpus. Each queue is a pair - * of RX and TX rings with a dedicated interrupt + * Number of Queues, can be set to 0, + * it then autoconfigures based on the + * number of cpus. Each queue is a pair + * of RX and TX rings with a msix vector */ static int ixgbe_num_queues = 0; TUNABLE_INT("hw.ixgbe.num_queues", &ixgbe_num_queues); -/* Number of TX descriptors per ring */ -static int ixgbe_txd = DEFAULT_TXD; +/* +** Number of TX descriptors per ring, +** setting higher than RX as this seems +** the better performing choice. +*/ +static int ixgbe_txd = PERFORM_TXD; TUNABLE_INT("hw.ixgbe.txd", &ixgbe_txd); /* Number of RX descriptors per ring */ -static int ixgbe_rxd = DEFAULT_RXD; +static int ixgbe_rxd = PERFORM_RXD; TUNABLE_INT("hw.ixgbe.rxd", &ixgbe_rxd); -/* Total number of Interfaces - need for config sanity check */ +/* Keep running tab on them for sanity check */ static int ixgbe_total_ports; /* @@ -288,6 +301,27 @@ static u32 ixgbe_shadow_vfta[IXGBE_VFTA_SIZE]; */ static int ixgbe_num_segs = IXGBE_82598_SCATTER; +#ifdef IXGBE_FDIR +/* +** For Flow Director: this is the +** number of TX packets we sample +** for the filter pool, this means +** every 20th packet will be probed. +** +** This feature can be disabled by +** setting this to 0. +*/ +static int atr_sample_rate = 20; +/* +** Flow Director actually 'steals' +** part of the packet buffer as its +** filter pool, this variable controls +** how much it uses: +** 0 = 64K, 1 = 128K, 2 = 256K +*/ +static int fdir_pballoc = 1; +#endif + /********************************************************************* * Device identification routine * @@ -356,7 +390,7 @@ ixgbe_attach(device_t dev) struct adapter *adapter; struct ixgbe_hw *hw; int error = 0; - u16 pci_device_id; + u16 pci_device_id, csum; u32 ctrl_ext; INIT_DEBUGOUT("ixgbe_attach: begin"); @@ -376,12 +410,18 @@ ixgbe_attach(device_t dev) case IXGBE_DEV_ID_82598EB_CX4 : adapter->optics = IFM_10G_CX4; break; + case IXGBE_DEV_ID_82598 : case IXGBE_DEV_ID_82598AF_DUAL_PORT : case IXGBE_DEV_ID_82598_DA_DUAL_PORT : case IXGBE_DEV_ID_82598AF_SINGLE_PORT : + case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM : + case IXGBE_DEV_ID_82598EB_SFP_LOM : case IXGBE_DEV_ID_82598AT : adapter->optics = IFM_10G_SR; break; + case IXGBE_DEV_ID_82598AT2 : + adapter->optics = IFM_10G_T; + break; case IXGBE_DEV_ID_82598EB_XF_LR : adapter->optics = IFM_10G_LR; break; @@ -390,11 +430,18 @@ ixgbe_attach(device_t dev) ixgbe_num_segs = IXGBE_82599_SCATTER; break; case IXGBE_DEV_ID_82599_KX4 : + case IXGBE_DEV_ID_82599_KX4_MEZZ: + case IXGBE_DEV_ID_82599_CX4 : adapter->optics = IFM_10G_CX4; ixgbe_num_segs = IXGBE_82599_SCATTER; break; case IXGBE_DEV_ID_82599_XAUI_LOM : + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE : ixgbe_num_segs = IXGBE_82599_SCATTER; + break; + case IXGBE_DEV_ID_82599_T3_LOM: + ixgbe_num_segs = IXGBE_82599_SCATTER; + adapter->optics = IFM_10G_T; default: break; } @@ -420,21 +467,6 @@ ixgbe_attach(device_t dev) OID_AUTO, "enable_aim", CTLTYPE_INT|CTLFLAG_RW, &ixgbe_enable_aim, 1, "Interrupt Moderation"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "low_latency", CTLTYPE_INT|CTLFLAG_RW, - &ixgbe_low_latency, 1, "Low Latency"); - - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "ave_latency", CTLTYPE_INT|CTLFLAG_RW, - &ixgbe_ave_latency, 1, "Average Latency"); - - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "bulk_latency", CTLTYPE_INT|CTLFLAG_RW, - &ixgbe_bulk_latency, 1, "Bulk Latency"); - /* Set up the timer callout */ callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); @@ -504,13 +536,40 @@ ixgbe_attach(device_t dev) goto err_late; } - /* Initialize the hardware */ - if (ixgbe_hardware_init(adapter)) { - device_printf(dev,"Unable to initialize the hardware\n"); + /* Make sure we have a good EEPROM before we read from it */ + if (ixgbe_validate_eeprom_checksum(&adapter->hw, &csum) < 0) { + device_printf(dev,"The EEPROM Checksum Is Not Valid\n"); error = EIO; goto err_late; } + /* Pick up the smart speed setting */ + if (hw->mac.type == ixgbe_mac_82599EB) + hw->phy.smart_speed = ixgbe_smart_speed; + + /* Get Hardware Flow Control setting */ + hw->fc.requested_mode = ixgbe_fc_full; + hw->fc.pause_time = IXGBE_FC_PAUSE; + hw->fc.low_water = IXGBE_FC_LO; + hw->fc.high_water = IXGBE_FC_HI; + hw->fc.send_xon = TRUE; + + error = ixgbe_init_hw(hw); + if (error == IXGBE_ERR_EEPROM_VERSION) { + device_printf(dev, "This device is a pre-production adapter/" + "LOM. Please be aware there may be issues associated " + "with your hardware.\n If you are experiencing problems " + "please contact your Intel or hardware representative " + "who provided you with this hardware.\n"); + } else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED) + device_printf(dev,"Unsupported SFP+ Module\n"); + + if (error) { + error = EIO; + device_printf(dev,"Hardware Initialization Failure\n"); + goto err_late; + } + if ((adapter->msix > 1) && (ixgbe_enable_msix)) error = ixgbe_allocate_msix(adapter); else @@ -521,22 +580,6 @@ ixgbe_attach(device_t dev) /* Setup OS specific network interface */ ixgbe_setup_interface(dev, adapter); -#ifdef IXGBE_IEEE1588 - /* - ** Setup the timer: IEEE 1588 support - */ - adapter->cycles.read = ixgbe_read_clock; - adapter->cycles.mask = (u64)-1; - adapter->cycles.mult = 1; - adapter->cycles.shift = IXGBE_TSYNC_SHIFT; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TIMINCA, (1<<24) | - IXGBE_TSYNC_CYCLE_TIME * IXGBE_TSYNC_SHIFT); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_SYSTIML, 0x00000000); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_SYSTIMH, 0xFF800000); - - // JFV - this is not complete yet -#endif - /* Sysctl for limiting the amount of work done in the taskqueue */ ixgbe_add_rx_process_limit(adapter, "rx_processing_limit", "max number of rx packets to process", &adapter->rx_process_limit, @@ -551,6 +594,25 @@ ixgbe_attach(device_t dev) adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, ixgbe_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); + /* Print PCIE bus type/speed/width info */ + ixgbe_get_bus_info(hw); + device_printf(dev,"PCI Express Bus: Speed %s %s\n", + ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s": + (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5Gb/s":"Unknown"), + (hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" : + (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" : + (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" : + ("Unknown")); + + if ((hw->bus.width <= ixgbe_bus_width_pcie_x4) && + (hw->bus.speed == ixgbe_bus_speed_2500)) { + device_printf(dev, "PCI-Express bandwidth available" + " for this card\n is not sufficient for" + " optimal performance.\n"); + device_printf(dev, "For optimal performance a x8 " + "PCIE, or x4 PCIE 2 slot is required.\n"); + } + /* let hardware know driver is loaded */ ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD; @@ -581,8 +643,7 @@ static int ixgbe_detach(device_t dev) { struct adapter *adapter = device_get_softc(dev); - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; + struct ix_queue *que = adapter->queues; u32 ctrl_ext; INIT_DEBUGOUT("ixgbe_detach: begin"); @@ -597,17 +658,10 @@ ixgbe_detach(device_t dev) ixgbe_stop(adapter); IXGBE_CORE_UNLOCK(adapter); - for (int i = 0; i < adapter->num_queues; i++, txr++) { - if (txr->tq) { - taskqueue_drain(txr->tq, &txr->tx_task); - taskqueue_free(txr->tq); - } - } - - for (int i = 0; i < adapter->num_queues; i++, rxr++) { - if (rxr->tq) { - taskqueue_drain(rxr->tq, &rxr->rx_task); - taskqueue_free(rxr->tq); + for (int i = 0; i < adapter->num_queues; i++, que++) { + if (que->tq) { + taskqueue_drain(que->tq, &que->que_task); + taskqueue_free(que->tq); } } @@ -616,6 +670,9 @@ ixgbe_detach(device_t dev) taskqueue_drain(adapter->tq, &adapter->link_task); taskqueue_drain(adapter->tq, &adapter->mod_task); taskqueue_drain(adapter->tq, &adapter->msf_task); +#ifdef IXGBE_FDIR + taskqueue_drain(adapter->tq, &adapter->fdir_task); +#endif taskqueue_free(adapter->tq); } @@ -700,8 +757,8 @@ ixgbe_start_locked(struct tx_ring *txr, struct ifnet * ifp) /* Send a copy of the frame to the BPF listener */ ETHER_BPF_MTAP(ifp, m_head); - /* Set timeout in case hardware has problems transmitting */ - txr->watchdog_timer = IXGBE_TX_TIMEOUT; + /* Set watchdog on */ + txr->watchdog_check = TRUE; } return; @@ -741,6 +798,9 @@ ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m) /* Which queue to use */ if ((m->m_flags & M_FLOWID) != 0) i = m->m_pkthdr.flowid % adapter->num_queues; + else /* use the cpu we're on */ + i = curcpu % adapter->num_queues; + txr = &adapter->tx_rings[i]; if (IXGBE_TX_TRYLOCK(txr)) { @@ -757,53 +817,47 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) { struct adapter *adapter = txr->adapter; struct mbuf *next; - int err = 0; + int enqueued, err = 0; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - err = drbr_enqueue(ifp, txr->br, m); + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING || adapter->link_active == 0) { + if (m != NULL) + err = drbr_enqueue(ifp, txr->br, m); return (err); } - if (m == NULL) /* Called by tasklet */ - goto process; - - /* If nothing queued go right to xmit */ - if (!drbr_needs_enqueue(ifp, txr->br)) { - if (ixgbe_xmit(txr, &m)) { - if (m && (err = drbr_enqueue(ifp, txr->br, m)) != 0) - return (err); - } else { - /* Success, update stats */ - drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags); - /* Send a copy of the frame to the BPF listener */ - ETHER_BPF_MTAP(ifp, m); - /* Set the watchdog */ - txr->watchdog_timer = IXGBE_TX_TIMEOUT; - } - - } else if ((err = drbr_enqueue(ifp, txr->br, m)) != 0) - return (err); - -process: - if (drbr_empty(ifp, txr->br)) - return (err); + enqueued = 0; + if (m == NULL) { + next = drbr_dequeue(ifp, txr->br); + } else if (drbr_needs_enqueue(ifp, txr->br)) { + if ((err = drbr_enqueue(ifp, txr->br, m)) != 0) + return (err); + next = drbr_dequeue(ifp, txr->br); + } else + next = m; /* Process the queue */ - while (TRUE) { + while (next != NULL) { + if ((err = ixgbe_xmit(txr, &next)) != 0) { + if (next != NULL) + err = drbr_enqueue(ifp, txr->br, next); + break; + } + enqueued++; + drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags); + /* Send a copy of the frame to the BPF listener */ + ETHER_BPF_MTAP(ifp, next); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) break; + if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } next = drbr_dequeue(ifp, txr->br); - if (next == NULL) - break; - if (ixgbe_xmit(txr, &next)) - break; - ETHER_BPF_MTAP(ifp, next); - /* Set the watchdog */ - txr->watchdog_timer = IXGBE_TX_TIMEOUT; } - - if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + + if (enqueued > 0) + txr->watchdog_check = TRUE; return (err); } @@ -840,29 +894,12 @@ ixgbe_qflush(struct ifnet *ifp) static int ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) { - struct adapter *adapter = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *) data; -#ifdef INET - struct ifaddr *ifa = (struct ifaddr *) data; -#endif + struct adapter *adapter = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *) data; int error = 0; switch (command) { - case SIOCSIFADDR: -#ifdef INET - IOCTL_DEBUGOUT("ioctl: SIOCxIFADDR (Get/Set Interface Addr)"); - if (ifa->ifa_addr->sa_family == AF_INET) { - ifp->if_flags |= IFF_UP; - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - IXGBE_CORE_LOCK(adapter); - ixgbe_init_locked(adapter); - IXGBE_CORE_UNLOCK(adapter); - } - arp_ifinit(ifp, ifa); - } else -#endif - ether_ioctl(ifp, command, data); - break; + case SIOCSIFMTU: IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)"); if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - ETHER_HDR_LEN) { @@ -872,7 +909,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) ifp->if_mtu = ifr->ifr_mtu; adapter->max_frame_size = ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; - ixgbe_init_locked(adapter); + error = ixgbe_init_locked(adapter); IXGBE_CORE_UNLOCK(adapter); } break; @@ -887,7 +924,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) ixgbe_set_promisc(adapter); } } else - ixgbe_init_locked(adapter); + error = ixgbe_init_locked(adapter); } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) ixgbe_stop(adapter); @@ -922,21 +959,15 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) ifp->if_capenable ^= IFCAP_LRO; if (mask & IFCAP_VLAN_HWTAGGING) ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ixgbe_init(adapter); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + IXGBE_CORE_LOCK(adapter); + error = ixgbe_init_locked(adapter); + IXGBE_CORE_UNLOCK(adapter); + } VLAN_CAPABILITIES(ifp); break; } -#ifdef IXGBE_IEEE1588 - /* - ** IOCTL support for Precision Time (IEEE 1588) Support - */ - case SIOCSHWTSTAMP: - error = ixgbe_hwtstamp_ioctl(adapter, ifp); - break; -#endif - default: IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)\n", (int)command); error = ether_ioctl(ifp, command, data); @@ -946,84 +977,6 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) return (error); } -/********************************************************************* - * Watchdog entry point - * - * This routine is called by the local timer - * to detect hardware hangs . - * - **********************************************************************/ - -static void -ixgbe_watchdog(struct adapter *adapter) -{ - device_t dev = adapter->dev; - struct tx_ring *txr = adapter->tx_rings; - struct ixgbe_hw *hw = &adapter->hw; - bool tx_hang = FALSE; - - IXGBE_CORE_LOCK_ASSERT(adapter); - - /* - * The timer is set to 5 every time ixgbe_start() queues a packet. - * Then ixgbe_txeof() keeps resetting to 5 as long as it cleans at - * least one descriptor. - * Finally, anytime all descriptors are clean the timer is - * set to 0. - */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { - u32 head, tail; - - IXGBE_TX_LOCK(txr); - if (txr->watchdog_timer == 0 || --txr->watchdog_timer) { - IXGBE_TX_UNLOCK(txr); - continue; - } else { - head = IXGBE_READ_REG(hw, IXGBE_TDH(i)); - tail = IXGBE_READ_REG(hw, IXGBE_TDT(i)); - if (head == tail) { /* last minute check */ - IXGBE_TX_UNLOCK(txr); - continue; - } - /* Well, seems something is really hung */ - tx_hang = TRUE; - IXGBE_TX_UNLOCK(txr); - break; - } - } - if (tx_hang == FALSE) - return; - - /* - * If we are in this routine because of pause frames, then don't - * reset the hardware. - */ - if (IXGBE_READ_REG(hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF) { - txr = adapter->tx_rings; /* reset pointer */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { - IXGBE_TX_LOCK(txr); - txr->watchdog_timer = IXGBE_TX_TIMEOUT; - IXGBE_TX_UNLOCK(txr); - } - return; - } - - - device_printf(adapter->dev, "Watchdog timeout -- resetting\n"); - for (int i = 0; i < adapter->num_queues; i++, txr++) { - device_printf(dev,"Queue(%d) tdh = %d, hw tdt = %d\n", i, - IXGBE_READ_REG(hw, IXGBE_TDH(i)), - IXGBE_READ_REG(hw, IXGBE_TDT(i))); - device_printf(dev,"TX(%d) desc avail = %d," - "Next TX to Clean = %d\n", - i, txr->tx_avail, txr->next_tx_to_clean); - } - adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - adapter->watchdog_events++; - - ixgbe_init_locked(adapter); -} - /********************************************************************* * Init entry point * @@ -1036,42 +989,39 @@ ixgbe_watchdog(struct adapter *adapter) **********************************************************************/ #define IXGBE_MHADD_MFS_SHIFT 16 -static void +static int ixgbe_init_locked(struct adapter *adapter) { struct ifnet *ifp = adapter->ifp; device_t dev = adapter->dev; - struct ixgbe_hw *hw; + struct ixgbe_hw *hw = &adapter->hw; u32 k, txdctl, mhadd, gpie; u32 rxdctl, rxctrl; - int err; - INIT_DEBUGOUT("ixgbe_init: begin"); - - hw = &adapter->hw; mtx_assert(&adapter->core_mtx, MA_OWNED); + INIT_DEBUGOUT("ixgbe_init: begin"); + ixgbe_reset_hw(hw); + hw->adapter_stopped = FALSE; + ixgbe_stop_adapter(hw); + callout_stop(&adapter->timer); - ixgbe_stop(adapter); + /* reprogram the RAR[0] in case user changed it. */ + ixgbe_set_rar(hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV); /* Get the latest mac address, User can use a LAA */ - bcopy(IF_LLADDR(adapter->ifp), adapter->hw.mac.addr, + bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr, IXGBE_ETH_LENGTH_OF_ADDRESS); - ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, 1); - adapter->hw.addr_ctrl.rar_used_count = 1; - - /* Initialize the hardware */ - if (ixgbe_hardware_init(adapter)) { - device_printf(dev, "Unable to initialize the hardware\n"); - return; - } + ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1); + hw->addr_ctrl.rar_used_count = 1; /* Prepare transmit descriptors and buffers */ if (ixgbe_setup_transmit_structures(adapter)) { device_printf(dev,"Could not setup transmit structures\n"); ixgbe_stop(adapter); - return; + return (ENOMEM); } + ixgbe_init_hw(hw); ixgbe_initialize_transmit_units(adapter); /* Setup Multicast table */ @@ -1090,18 +1040,15 @@ ixgbe_init_locked(struct adapter *adapter) if (ixgbe_setup_receive_structures(adapter)) { device_printf(dev,"Could not setup receive structures\n"); ixgbe_stop(adapter); - return; + return (ENOMEM); } /* Configure RX settings */ ixgbe_initialize_receive_units(adapter); - /* Configure Interrupt Moderation */ - ixgbe_init_moderation(adapter); - gpie = IXGBE_READ_REG(&adapter->hw, IXGBE_GPIE); - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + if (hw->mac.type == ixgbe_mac_82599EB) { gpie |= IXGBE_SDP1_GPIEN; gpie |= IXGBE_SDP2_GPIEN; } @@ -1116,39 +1063,49 @@ ixgbe_init_locked(struct adapter *adapter) gpie |= IXGBE_GPIE_EIAME | IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD; } - IXGBE_WRITE_REG(&adapter->hw, IXGBE_GPIE, gpie); + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); /* Set the various hardware offload abilities */ ifp->if_hwassist = 0; if (ifp->if_capenable & IFCAP_TSO4) ifp->if_hwassist |= CSUM_TSO; if (ifp->if_capenable & IFCAP_TXCSUM) - ifp->if_hwassist = (CSUM_TCP | CSUM_UDP); - + ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); +#if __FreeBSD_version >= 800000 + if (hw->mac.type == ixgbe_mac_82599EB) + ifp->if_hwassist |= CSUM_SCTP; +#endif /* Set MTU size */ if (ifp->if_mtu > ETHERMTU) { - mhadd = IXGBE_READ_REG(&adapter->hw, IXGBE_MHADD); + mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); mhadd &= ~IXGBE_MHADD_MFS_MASK; mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_MHADD, mhadd); + IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); } /* Now enable all the queues */ for (int i = 0; i < adapter->num_queues; i++) { - txdctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(i)); + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i)); txdctl |= IXGBE_TXDCTL_ENABLE; /* Set WTHRESH to 8, burst writeback */ txdctl |= (8 << 16); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(i), txdctl); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), txdctl); } for (int i = 0; i < adapter->num_queues; i++) { - rxdctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(i)); - /* PTHRESH set to 32 */ - rxdctl |= 0x0020; + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)); + if (hw->mac.type == ixgbe_mac_82598EB) { + /* + ** PTHRESH = 21 + ** HTHRESH = 4 + ** WTHRESH = 8 + */ + rxdctl &= ~0x3FFFFF; + rxdctl |= 0x080420; + } rxdctl |= IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(i), rxdctl); + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), rxdctl); for (k = 0; k < 10; k++) { if (IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)) & IXGBE_RXDCTL_ENABLE) @@ -1165,10 +1122,10 @@ ixgbe_init_locked(struct adapter *adapter) /* Enable Receive engine */ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); - if (adapter->hw.mac.type == ixgbe_mac_82598EB) + if (hw->mac.type == ixgbe_mac_82598EB) rxctrl |= IXGBE_RXCTRL_DMBYPS; rxctrl |= IXGBE_RXCTRL_RXEN; - IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl); + ixgbe_enable_rx_dma(hw, rxctrl); callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter); @@ -1180,33 +1137,36 @@ ixgbe_init_locked(struct adapter *adapter) ixgbe_set_ivar(adapter, 0, 0, 1); } - ixgbe_enable_intr(adapter); +#ifdef IXGBE_FDIR + /* Init Flow director */ + if (hw->mac.type == ixgbe_mac_82599EB) + ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc); +#endif /* ** Check on any SFP devices that ** need to be kick-started */ - err = hw->phy.ops.identify(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - device_printf(dev, - "Unsupported SFP+ module type was detected.\n"); - ixgbe_detach(dev); - return; - } - if (ixgbe_is_sfp(hw)) { - if (hw->phy.multispeed_fiber) { - hw->mac.ops.setup_sfp(hw); - taskqueue_enqueue(adapter->tq, &adapter->msf_task); - } else - taskqueue_enqueue(adapter->tq, &adapter->mod_task); - } else - taskqueue_enqueue(adapter->tq, &adapter->link_task); + if (hw->phy.type == ixgbe_phy_none) { + int err = hw->phy.ops.identify(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + device_printf(dev, + "Unsupported SFP+ module type was detected.\n"); + return (EIO); + } + } + + /* Config/Enable Link */ + ixgbe_config_link(adapter); + + /* And now turn on interrupts */ + ixgbe_enable_intr(adapter); /* Now inform the stack we're ready */ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - return; + return (0); } static void @@ -1268,7 +1228,7 @@ ixgbe_disable_queue(struct adapter *adapter, u32 vector) } static inline void -ixgbe_rearm_rx_queues(struct adapter *adapter, u64 queues) +ixgbe_rearm_queues(struct adapter *adapter, u64 queues) { u32 mask; @@ -1283,34 +1243,22 @@ ixgbe_rearm_rx_queues(struct adapter *adapter, u64 queues) } } -static void -ixgbe_handle_rx(void *context, int pending) -{ - struct rx_ring *rxr = context; - struct adapter *adapter = rxr->adapter; - u32 loop = MAX_LOOP; - bool more; - - do { - more = ixgbe_rxeof(rxr, -1); - } while (loop-- && more); - /* Reenable this interrupt */ - ixgbe_enable_queue(adapter, rxr->msix); -} static void -ixgbe_handle_tx(void *context, int pending) +ixgbe_handle_que(void *context, int pending) { - struct tx_ring *txr = context; - struct adapter *adapter = txr->adapter; + struct ix_queue *que = context; + struct adapter *adapter = que->adapter; + struct tx_ring *txr = que->txr; struct ifnet *ifp = adapter->ifp; u32 loop = MAX_LOOP; - bool more; + bool more_rx, more_tx; IXGBE_TX_LOCK(txr); do { - more = ixgbe_txeof(txr); - } while (loop-- && more); + more_rx = ixgbe_rxeof(que, adapter->rx_process_limit); + more_tx = ixgbe_txeof(txr); + } while (loop-- && (more_rx || more_tx)); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { #if __FreeBSD_version >= 800000 @@ -1324,7 +1272,7 @@ ixgbe_handle_tx(void *context, int pending) IXGBE_TX_UNLOCK(txr); /* Reenable this interrupt */ - ixgbe_enable_queue(adapter, txr->msix); + ixgbe_enable_queue(adapter, que->msix); } @@ -1337,33 +1285,32 @@ ixgbe_handle_tx(void *context, int pending) static void ixgbe_legacy_irq(void *arg) { - struct adapter *adapter = arg; + struct ix_queue *que = arg; + struct adapter *adapter = que->adapter; struct ixgbe_hw *hw = &adapter->hw; struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; - bool more; + bool more_tx, more_rx; u32 reg_eicr, loop = MAX_LOOP; reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICR); + ++que->irqs; if (reg_eicr == 0) { ixgbe_enable_intr(adapter); return; } - if (ixgbe_rxeof(rxr, adapter->rx_process_limit)) - taskqueue_enqueue(rxr->tq, &rxr->rx_task); + more_rx = ixgbe_rxeof(que, adapter->rx_process_limit); IXGBE_TX_LOCK(txr); - ++txr->tx_irq; do { - more = ixgbe_txeof(txr); - } while (loop-- && more); + more_tx = ixgbe_txeof(txr); + } while (loop-- && more_tx); IXGBE_TX_UNLOCK(txr); - if (more) - taskqueue_enqueue(txr->tq, &txr->tx_task); + if (more_rx || more_tx) + taskqueue_enqueue(que->tq, &que->que_task); /* Check for fan failure */ if ((hw->phy.media_type == ixgbe_media_type_copper) && @@ -1374,15 +1321,8 @@ ixgbe_legacy_irq(void *arg) } /* Link status change */ - if (reg_eicr & IXGBE_EICR_LSC) { - ixgbe_check_link(&adapter->hw, - &adapter->link_speed, &adapter->link_up, 0); - ixgbe_update_link_status(adapter); - } - - /* Update interrupt rate */ - if (ixgbe_enable_aim == TRUE) - ixgbe_update_aim(rxr); + if (reg_eicr & IXGBE_EICR_LSC) + taskqueue_enqueue(adapter->tq, &adapter->link_task); ixgbe_enable_intr(adapter); return; @@ -1391,55 +1331,85 @@ ixgbe_legacy_irq(void *arg) /********************************************************************* * - * MSI TX Interrupt Service routine + * MSI Queue Interrupt Service routine * **********************************************************************/ void -ixgbe_msix_tx(void *arg) +ixgbe_msix_que(void *arg) { - struct tx_ring *txr = arg; - struct adapter *adapter = txr->adapter; - bool more; + struct ix_queue *que = arg; + struct adapter *adapter = que->adapter; + struct tx_ring *txr = que->txr; + struct rx_ring *rxr = que->rxr; + bool more_tx, more_rx; + u32 newitr = 0; - ixgbe_disable_queue(adapter, txr->msix); + ixgbe_disable_queue(adapter, que->msix); + ++que->irqs; + + more_rx = ixgbe_rxeof(que, adapter->rx_process_limit); IXGBE_TX_LOCK(txr); - ++txr->tx_irq; - more = ixgbe_txeof(txr); + more_tx = ixgbe_txeof(txr); IXGBE_TX_UNLOCK(txr); - if (more) - taskqueue_enqueue(txr->tq, &txr->tx_task); - else /* Reenable this interrupt */ - ixgbe_enable_queue(adapter, txr->msix); - return; -} + more_rx = ixgbe_rxeof(que, adapter->rx_process_limit); -/********************************************************************* - * - * MSIX RX Interrupt Service routine - * - **********************************************************************/ -static void -ixgbe_msix_rx(void *arg) -{ - struct rx_ring *rxr = arg; - struct adapter *adapter = rxr->adapter; - bool more; + /* Do AIM now? */ - ixgbe_disable_queue(adapter, rxr->msix); + if (ixgbe_enable_aim == FALSE) + goto no_calc; + /* + ** Do Adaptive Interrupt Moderation: + ** - Write out last calculated setting + ** - Calculate based on average size over + ** the last interval. + */ + if (que->eitr_setting) + IXGBE_WRITE_REG(&adapter->hw, + IXGBE_EITR(que->msix), que->eitr_setting); + + que->eitr_setting = 0; - ++rxr->rx_irq; - more = ixgbe_rxeof(rxr, adapter->rx_process_limit); + /* Idle, do nothing */ + if ((txr->bytes == 0) && (rxr->bytes == 0)) + goto no_calc; + + if ((txr->bytes) && (txr->packets)) + newitr = txr->bytes/txr->packets; + if ((rxr->bytes) && (rxr->packets)) + newitr = max(newitr, + (rxr->bytes / rxr->packets)); + newitr += 24; /* account for hardware frame, crc */ - /* Update interrupt rate */ - if (ixgbe_enable_aim == TRUE) - ixgbe_update_aim(rxr); + /* set an upper boundary */ + newitr = min(newitr, 3000); - if (more) - taskqueue_enqueue(rxr->tq, &rxr->rx_task); + /* Be nice to the mid range */ + if ((newitr > 300) && (newitr < 1200)) + newitr = (newitr / 3); else - ixgbe_enable_queue(adapter, rxr->msix); + newitr = (newitr / 2); + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + newitr |= newitr << 16; + else + newitr |= IXGBE_EITR_CNT_WDIS; + + /* save for next interrupt */ + que->eitr_setting = newitr; + + /* Reset state */ + txr->bytes = 0; + txr->packets = 0; + rxr->bytes = 0; + rxr->packets = 0; + +no_calc: + if (more_tx || more_rx) + taskqueue_enqueue(que->tq, &que->que_task); + else /* Reenable this interrupt */ + ixgbe_enable_queue(adapter, que->msix); return; } @@ -1463,11 +1433,25 @@ ixgbe_msix_link(void *arg) taskqueue_enqueue(adapter->tq, &adapter->link_task); if (adapter->hw.mac.type == ixgbe_mac_82599EB) { +#ifdef IXGBE_FDIR + if (reg_eicr & IXGBE_EICR_FLOW_DIR) { + /* This is probably overkill :) */ + if (!atomic_cmpset_int(&adapter->fdir_reinit, 0, 1)) + return; + /* Clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR); + /* Turn off the interface */ + adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + taskqueue_enqueue(adapter->tq, &adapter->fdir_task); + } else +#endif if (reg_eicr & IXGBE_EICR_ECC) { device_printf(adapter->dev, "\nCRITICAL: ECC ERROR!! " "Please Reboot!!\n"); IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); - } else if (reg_eicr & IXGBE_EICR_GPI_SDP1) { + } else + + if (reg_eicr & IXGBE_EICR_GPI_SDP1) { /* Clear the interrupt */ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); taskqueue_enqueue(adapter->tq, &adapter->msf_task); @@ -1490,86 +1474,6 @@ ixgbe_msix_link(void *arg) return; } -/* -** Routine to do adjust the RX EITR value based on traffic, -** its a simple three state model, but seems to help. -** -** Note that the three EITR values are tuneable using -** sysctl in real time. The feature can be effectively -** nullified by setting them equal. -*/ -#define BULK_THRESHOLD 10000 -#define AVE_THRESHOLD 1600 - -static void -ixgbe_update_aim(struct rx_ring *rxr) -{ - struct adapter *adapter = rxr->adapter; - u32 olditr, newitr; - - /* Update interrupt moderation based on traffic */ - olditr = rxr->eitr_setting; - newitr = olditr; - - /* Idle, don't change setting */ - if (rxr->bytes == 0) - return; - - if (olditr == ixgbe_low_latency) { - if (rxr->bytes > AVE_THRESHOLD) - newitr = ixgbe_ave_latency; - } else if (olditr == ixgbe_ave_latency) { - if (rxr->bytes < AVE_THRESHOLD) - newitr = ixgbe_low_latency; - else if (rxr->bytes > BULK_THRESHOLD) - newitr = ixgbe_bulk_latency; - } else if (olditr == ixgbe_bulk_latency) { - if (rxr->bytes < BULK_THRESHOLD) - newitr = ixgbe_ave_latency; - } - - if (olditr != newitr) { - /* Change interrupt rate */ - rxr->eitr_setting = newitr; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(rxr->me), - newitr | (newitr << 16)); - } - - rxr->bytes = 0; - return; -} - -static void -ixgbe_init_moderation(struct adapter *adapter) -{ - struct rx_ring *rxr = adapter->rx_rings; - struct tx_ring *txr = adapter->tx_rings; - - /* Single interrupt - MSI or Legacy? */ - if (adapter->msix < 2) { - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(0), 100); - return; - } - - /* TX irq moderation rate is fixed */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_EITR(txr->msix), ixgbe_ave_latency); - txr->watchdog_timer = FALSE; - } - - /* RX moderation will be adapted over time, set default */ - for (int i = 0; i < adapter->num_queues; i++, rxr++) { - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_EITR(rxr->msix), ixgbe_low_latency); - } - - /* Set Link moderation */ - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_EITR(adapter->linkvec), IXGBE_LINK_ITR); - -} - /********************************************************************* * * Media Ioctl callback @@ -1632,7 +1536,6 @@ ixgbe_media_change(struct ifnet * ifp) switch (IFM_SUBTYPE(ifm->ifm_media)) { case IFM_AUTO: - adapter->hw.mac.autoneg = TRUE; adapter->hw.phy.autoneg_advertised = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_10GB_FULL; break; @@ -1646,11 +1549,10 @@ ixgbe_media_change(struct ifnet * ifp) /********************************************************************* * - * This routine maps the mbufs to tx descriptors. - * WARNING: while this code is using an MQ style infrastructure, - * it would NOT work as is with more than 1 queue. + * This routine maps the mbufs to tx descriptors, allowing the + * TX engine to transmit the packets. + * - return 0 on success, positive on failure * - * return 0 on success, positive on failure **********************************************************************/ static int @@ -1676,20 +1578,12 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) if (m_head->m_flags & M_VLANTAG) cmd_type_len |= IXGBE_ADVTXD_DCMD_VLE; - /* Do a clean if descriptors are low */ - if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD) { - ixgbe_txeof(txr); - /* Now do we at least have a minimal? */ - if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD) - return (ENOBUFS); - } - /* * Important to capture the first descriptor * used because it will contain the index of * the one we tell the hardware to report back */ - first = txr->next_avail_tx_desc; + first = txr->next_avail_desc; txbuf = &txr->tx_buffers[first]; txbuf_mapped = txbuf; map = txbuf->map; @@ -1737,7 +1631,7 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) /* Make certain there are enough descriptors */ if (nsegs > txr->tx_avail - 2) { - txr->no_tx_desc_avail++; + txr->no_desc_avail++; error = ENOBUFS; goto xmit_fail; } @@ -1766,12 +1660,22 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) cmd_type_len |= IXGBE_ADVTXD_MAC_TSTAMP; #endif +#ifdef IXGBE_FDIR + /* Do the flow director magic */ + if ((txr->atr_sample) && (!adapter->fdir_reinit)) { + ++txr->atr_count; + if (txr->atr_count >= atr_sample_rate) { + ixgbe_atr(txr, m_head); + txr->atr_count = 0; + } + } +#endif /* Record payload length */ if (paylen == 0) olinfo_status |= m_head->m_pkthdr.len << IXGBE_ADVTXD_PAYLEN_SHIFT; - i = txr->next_avail_tx_desc; + i = txr->next_avail_desc; for (j = 0; j < nsegs; j++) { bus_size_t seglen; bus_addr_t segaddr; @@ -1785,7 +1689,7 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) txd->read.cmd_type_len = htole32(txr->txd_cmd | cmd_type_len |seglen); txd->read.olinfo_status = htole32(olinfo_status); - last = i; /* Next descriptor that will get completed */ + last = i; /* descriptor that will get completion IRQ */ if (++i == adapter->num_tx_desc) i = 0; @@ -1797,7 +1701,7 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) txd->read.cmd_type_len |= htole32(IXGBE_TXD_CMD_EOP | IXGBE_TXD_CMD_RS); txr->tx_avail -= nsegs; - txr->next_avail_tx_desc = i; + txr->next_avail_desc = i; txbuf->m_head = m_head; txbuf->map = map; @@ -1814,7 +1718,13 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) * hardware that this frame is available to transmit. */ ++txr->total_packets; + txr->watchdog_time = ticks; IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(txr->me), i); + + /* Do a clean if descriptors are low */ + if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD) + ixgbe_txeof(txr); + return (0); xmit_fail: @@ -1938,7 +1848,7 @@ ixgbe_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq) * Timer routine * * This routine checks for link status,updates statistics, - * and runs the watchdog timer. + * and runs the watchdog check. * **********************************************************************/ @@ -1947,6 +1857,8 @@ ixgbe_local_timer(void *arg) { struct adapter *adapter = arg; struct ifnet *ifp = adapter->ifp; + device_t dev = adapter->dev; + struct tx_ring *txr = adapter->tx_rings; mtx_assert(&adapter->core_mtx, MA_OWNED); @@ -1957,20 +1869,47 @@ ixgbe_local_timer(void *arg) ixgbe_update_link_status(adapter); ixgbe_update_stats_counters(adapter); - if (ixgbe_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) { + + /* Debug display */ + if (ixgbe_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) ixgbe_print_hw_stats(adapter); - } + /* - * Each tick we check the watchdog - * to protect against hardware hangs. + * If the interface has been paused + * then don't do the watchdog check */ - ixgbe_watchdog(adapter); - + if (IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF) + goto out; + /* + ** Check for time since any descriptor was cleaned + */ + for (int i = 0; i < adapter->num_queues; i++, txr++) { + IXGBE_TX_LOCK(txr); + if (txr->watchdog_check == FALSE) { + IXGBE_TX_UNLOCK(txr); + continue; + } + if ((ticks - txr->watchdog_time) > IXGBE_WATCHDOG) + goto hung; + IXGBE_TX_UNLOCK(txr); + } out: - /* Trigger an RX interrupt on all queues */ - ixgbe_rearm_rx_queues(adapter, adapter->rx_mask); - + ixgbe_rearm_queues(adapter, adapter->que_mask); callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter); + return; + +hung: + device_printf(adapter->dev, "Watchdog timeout -- resetting\n"); + device_printf(dev,"Queue(%d) tdh = %d, hw tdt = %d\n", txr->me, + IXGBE_READ_REG(&adapter->hw, IXGBE_TDH(txr->me)), + IXGBE_READ_REG(&adapter->hw, IXGBE_TDT(txr->me))); + device_printf(dev,"TX(%d) desc avail = %d," + "Next TX to Clean = %d\n", + txr->me, txr->tx_avail, txr->next_to_clean); + adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + adapter->watchdog_events++; + IXGBE_TX_UNLOCK(txr); + ixgbe_init_locked(adapter); } /* @@ -2003,7 +1942,7 @@ ixgbe_update_link_status(struct adapter *adapter) adapter->link_active = FALSE; for (int i = 0; i < adapter->num_queues; i++, txr++) - txr->watchdog_timer = FALSE; + txr->watchdog_check = FALSE; } } @@ -2076,8 +2015,7 @@ static int ixgbe_allocate_legacy(struct adapter *adapter) { device_t dev = adapter->dev; - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; + struct ix_queue *que = adapter->queues; int error, rid = 0; /* MSI RID at 1 */ @@ -2097,21 +2035,19 @@ ixgbe_allocate_legacy(struct adapter *adapter) * Try allocating a fast interrupt and the associated deferred * processing contexts. */ - TASK_INIT(&txr->tx_task, 0, ixgbe_handle_tx, txr); - TASK_INIT(&rxr->rx_task, 0, ixgbe_handle_rx, rxr); - txr->tq = taskqueue_create_fast("ixgbe_txq", M_NOWAIT, - taskqueue_thread_enqueue, &txr->tq); - rxr->tq = taskqueue_create_fast("ixgbe_rxq", M_NOWAIT, - taskqueue_thread_enqueue, &rxr->tq); - taskqueue_start_threads(&txr->tq, 1, PI_NET, "%s txq", - device_get_nameunit(adapter->dev)); - taskqueue_start_threads(&rxr->tq, 1, PI_NET, "%s rxq", + TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que); + que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT, + taskqueue_thread_enqueue, &que->tq); + taskqueue_start_threads(&que->tq, 1, PI_NET, "%s ixq", device_get_nameunit(adapter->dev)); /* Tasklets for Link, SFP and Multispeed Fiber */ TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter); TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter); TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter); +#ifdef IXGBE_FDIR + TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter); +#endif adapter->tq = taskqueue_create_fast("ixgbe_link", M_NOWAIT, taskqueue_thread_enqueue, &adapter->tq); taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq", @@ -2119,15 +2055,17 @@ ixgbe_allocate_legacy(struct adapter *adapter) if ((error = bus_setup_intr(dev, adapter->res, INTR_TYPE_NET | INTR_MPSAFE, NULL, ixgbe_legacy_irq, - adapter, &adapter->tag)) != 0) { + que, &adapter->tag)) != 0) { device_printf(dev, "Failed to register fast interrupt " "handler: %d\n", error); - taskqueue_free(txr->tq); - taskqueue_free(rxr->tq); - txr->tq = NULL; - rxr->tq = NULL; + taskqueue_free(que->tq); + taskqueue_free(adapter->tq); + que->tq = NULL; + adapter->tq = NULL; return (error); } + /* For simplicity in the handlers */ + adapter->que_mask = IXGBE_EIMS_ENABLE_MASK; return (0); } @@ -2142,83 +2080,44 @@ static int ixgbe_allocate_msix(struct adapter *adapter) { device_t dev = adapter->dev; - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; + struct ix_queue *que = adapter->queues; int error, rid, vector = 0; - /* TX setup: the code is here for multi tx, - there are other parts of the driver not ready for it */ - for (int i = 0; i < adapter->num_queues; i++, vector++, txr++) { + for (int i = 0; i < adapter->num_queues; i++, vector++, que++) { rid = vector + 1; - txr->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); - if (!txr->res) { + if (que->res == NULL) { device_printf(dev,"Unable to allocate" - " bus resource: tx interrupt [%d]\n", vector); + " bus resource: que interrupt [%d]\n", vector); return (ENXIO); } /* Set the handler function */ - error = bus_setup_intr(dev, txr->res, + error = bus_setup_intr(dev, que->res, INTR_TYPE_NET | INTR_MPSAFE, NULL, - ixgbe_msix_tx, txr, &txr->tag); + ixgbe_msix_que, que, &que->tag); if (error) { - txr->res = NULL; - device_printf(dev, "Failed to register TX handler"); + que->res = NULL; + device_printf(dev, "Failed to register QUE handler"); return (error); } - txr->msix = vector; + que->msix = vector; + adapter->que_mask |= (u64)(1 << que->msix); /* ** Bind the msix vector, and thus the ** ring to the corresponding cpu. */ if (adapter->num_queues > 1) - bus_bind_intr(dev, txr->res, i); + bus_bind_intr(dev, que->res, i); - TASK_INIT(&txr->tx_task, 0, ixgbe_handle_tx, txr); - txr->tq = taskqueue_create_fast("ixgbe_txq", M_NOWAIT, - taskqueue_thread_enqueue, &txr->tq); - taskqueue_start_threads(&txr->tq, 1, PI_NET, "%s txq", + TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que); + que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT, + taskqueue_thread_enqueue, &que->tq); + taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", device_get_nameunit(adapter->dev)); } - /* RX setup */ - for (int i = 0; i < adapter->num_queues; i++, vector++, rxr++) { - rid = vector + 1; - rxr->res = bus_alloc_resource_any(dev, - SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); - if (!rxr->res) { - device_printf(dev,"Unable to allocate" - " bus resource: rx interrupt [%d]," - "rid = %d\n", i, rid); - return (ENXIO); - } - /* Set the handler function */ - error = bus_setup_intr(dev, rxr->res, - INTR_TYPE_NET | INTR_MPSAFE, NULL, - ixgbe_msix_rx, rxr, &rxr->tag); - if (error) { - rxr->res = NULL; - device_printf(dev, "Failed to register RX handler"); - return (error); - } - rxr->msix = vector; - /* used in local timer */ - adapter->rx_mask |= (u64)(1 << vector); - /* - ** Bind the msix vector, and thus the - ** ring to the corresponding cpu. - */ - if (adapter->num_queues > 1) - bus_bind_intr(dev, rxr->res, i); - - TASK_INIT(&rxr->rx_task, 0, ixgbe_handle_rx, rxr); - rxr->tq = taskqueue_create_fast("ixgbe_rxq", M_NOWAIT, - taskqueue_thread_enqueue, &rxr->tq); - taskqueue_start_threads(&rxr->tq, 1, PI_NET, "%s rxq", - device_get_nameunit(adapter->dev)); - } - - /* Now for Link changes */ + /* and Link */ rid = vector + 1; adapter->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); @@ -2241,6 +2140,9 @@ ixgbe_allocate_msix(struct adapter *adapter) TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter); TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter); TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter); +#ifdef IXGBE_FDIR + TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter); +#endif adapter->tq = taskqueue_create_fast("ixgbe_link", M_NOWAIT, taskqueue_thread_enqueue, &adapter->tq); taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq", @@ -2287,15 +2189,15 @@ ixgbe_setup_msix(struct adapter *adapter) } /* Figure out a reasonable auto config value */ - queues = (mp_ncpus > ((msgs-1)/2)) ? (msgs-1)/2 : mp_ncpus; + queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus; if (ixgbe_num_queues == 0) ixgbe_num_queues = queues; /* - ** Want two vectors (RX/TX) per queue + ** Want one vector (RX/TX pair) per queue ** plus an additional for Link. */ - want = (ixgbe_num_queues * 2) + 1; + want = ixgbe_num_queues + 1; if (msgs >= want) msgs = want; else { @@ -2356,8 +2258,7 @@ ixgbe_allocate_pci_resources(struct adapter *adapter) static void ixgbe_free_pci_resources(struct adapter * adapter) { - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; + struct ix_queue *que = adapter->queues; device_t dev = adapter->dev; int rid, memrid; @@ -2378,29 +2279,18 @@ ixgbe_free_pci_resources(struct adapter * adapter) goto mem; /* - ** Release all the interrupt resources: - ** notice this is harmless for Legacy or - ** MSI since pointers will always be NULL + ** Release all msix queue resources: */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { - rid = txr->msix + 1; - if (txr->tag != NULL) { - bus_teardown_intr(dev, txr->res, txr->tag); - txr->tag = NULL; + for (int i = 0; i < adapter->num_queues; i++, que++) { + rid = que->msix + 1; + if (que->tag != NULL) { + bus_teardown_intr(dev, que->res, que->tag); + que->tag = NULL; } - if (txr->res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, rid, txr->res); + if (que->res != NULL) + bus_release_resource(dev, SYS_RES_IRQ, rid, que->res); } - for (int i = 0; i < adapter->num_queues; i++, rxr++) { - rid = rxr->msix + 1; - if (rxr->tag != NULL) { - bus_teardown_intr(dev, rxr->res, rxr->tag); - rxr->tag = NULL; - } - if (rxr->res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, rid, rxr->res); - } /* Clean the Legacy or Link interrupt last */ if (adapter->linkvec) /* we are doing MSIX */ @@ -2414,6 +2304,7 @@ ixgbe_free_pci_resources(struct adapter * adapter) } if (adapter->res != NULL) bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res); + mem: if (adapter->msix) pci_release_msi(dev); @@ -2429,57 +2320,6 @@ mem: return; } -/********************************************************************* - * - * Initialize the hardware to a configuration as specified by the - * adapter structure. The controller is reset, the EEPROM is - * verified, the MAC address is set, then the shared initialization - * routines are called. - * - **********************************************************************/ -static int -ixgbe_hardware_init(struct adapter *adapter) -{ - device_t dev = adapter->dev; - u32 ret; - u16 csum; - - csum = 0; - /* Issue a global reset */ - adapter->hw.adapter_stopped = FALSE; - ixgbe_stop_adapter(&adapter->hw); - - /* Make sure we have a good EEPROM before we read from it */ - if (ixgbe_validate_eeprom_checksum(&adapter->hw, &csum) < 0) { - device_printf(dev,"The EEPROM Checksum Is Not Valid\n"); - return (EIO); - } - - /* Get Hardware Flow Control setting */ - adapter->hw.fc.requested_mode = ixgbe_fc_full; - adapter->hw.fc.pause_time = IXGBE_FC_PAUSE; - adapter->hw.fc.low_water = IXGBE_FC_LO; - adapter->hw.fc.high_water = IXGBE_FC_HI; - adapter->hw.fc.send_xon = TRUE; - - ret = ixgbe_init_hw(&adapter->hw); - if (ret == IXGBE_ERR_EEPROM_VERSION) { - device_printf(dev, "This device is a pre-production adapter/" - "LOM. Please be aware there may be issues associated " - "with your hardware.\n If you are experiencing problems " - "please contact your Intel or hardware representative " - "who provided you with this hardware.\n"); - } else if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { - device_printf(dev,"Unsupported SFP+ Module\n"); - return (EIO); - } else if (ret != 0 ) { - device_printf(dev,"Hardware Initialization Failure\n"); - return (EIO); - } - - return (0); -} - /********************************************************************* * * Setup networking device structure and register an interface. @@ -2488,8 +2328,9 @@ ixgbe_hardware_init(struct adapter *adapter) static void ixgbe_setup_interface(device_t dev, struct adapter *adapter) { - struct ifnet *ifp; struct ixgbe_hw *hw = &adapter->hw; + struct ifnet *ifp; + INIT_DEBUGOUT("ixgbe_setup_interface: begin"); ifp = adapter->ifp = if_alloc(IFT_ETHER); @@ -2507,8 +2348,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); @@ -2527,13 +2366,6 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter) ifp->if_capenable = ifp->if_capabilities; - if (hw->device_id == IXGBE_DEV_ID_82598AT) - ixgbe_setup_link_speed(hw, (IXGBE_LINK_SPEED_10GB_FULL | - IXGBE_LINK_SPEED_1GB_FULL), TRUE, TRUE); - else - ixgbe_setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, - TRUE, FALSE); - /* * Specify the media types supported by this adapter and register * callbacks to update media and link information @@ -2554,6 +2386,41 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter) return; } +static void +ixgbe_config_link(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 autoneg, err = 0; + bool sfp, negotiate; + + sfp = ixgbe_is_sfp(hw); + + if (sfp) { + if (hw->phy.multispeed_fiber) { + hw->mac.ops.setup_sfp(hw); + taskqueue_enqueue(adapter->tq, &adapter->msf_task); + } else + taskqueue_enqueue(adapter->tq, &adapter->mod_task); + } else { + if (hw->mac.ops.check_link) + err = ixgbe_check_link(hw, &autoneg, + &adapter->link_up, FALSE); + if (err) + goto out; + autoneg = hw->phy.autoneg_advertised; + if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) + err = hw->mac.ops.get_link_capabilities(hw, + &autoneg, &negotiate); + if (err) + goto out; + if (hw->mac.ops.setup_link) + err = hw->mac.ops.setup_link(hw, autoneg, + negotiate, adapter->link_up); + } +out: + return; +} + /******************************************************************** * Manage DMA'able memory. *******************************************************************/ @@ -2573,8 +2440,8 @@ ixgbe_dma_malloc(struct adapter *adapter, bus_size_t size, device_t dev = adapter->dev; int r; - r = bus_dma_tag_create(NULL, /* parent */ - 1, 0, /* alignment, bounds */ + r = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */ + DBA_ALIGN, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ @@ -2639,21 +2506,30 @@ ixgbe_dma_free(struct adapter *adapter, struct ixgbe_dma_alloc *dma) static int ixgbe_allocate_queues(struct adapter *adapter) { - device_t dev = adapter->dev; - struct tx_ring *txr; - struct rx_ring *rxr; + device_t dev = adapter->dev; + struct ix_queue *que; + struct tx_ring *txr; + struct rx_ring *rxr; int rsize, tsize, error = IXGBE_SUCCESS; int txconf = 0, rxconf = 0; + /* First allocate the top level queue structs */ + if (!(adapter->queues = + (struct ix_queue *) malloc(sizeof(struct ix_queue) * + adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { + device_printf(dev, "Unable to allocate queue memory\n"); + error = ENOMEM; + goto fail; + } + /* First allocate the TX ring struct memory */ if (!(adapter->tx_rings = (struct tx_ring *) malloc(sizeof(struct tx_ring) * adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { device_printf(dev, "Unable to allocate TX ring memory\n"); error = ENOMEM; - goto fail; + goto tx_fail; } - txr = adapter->tx_rings; /* Next allocate the RX */ if (!(adapter->rx_rings = @@ -2663,11 +2539,10 @@ ixgbe_allocate_queues(struct adapter *adapter) error = ENOMEM; goto rx_fail; } - rxr = adapter->rx_rings; /* For the ring itself */ tsize = roundup2(adapter->num_tx_desc * - sizeof(union ixgbe_adv_tx_desc), 4096); + sizeof(union ixgbe_adv_tx_desc), DBA_ALIGN); /* * Now set up the TX queues, txconf is needed to handle the @@ -2706,6 +2581,12 @@ ixgbe_allocate_queues(struct adapter *adapter) /* Allocate a buf ring */ txr->br = buf_ring_alloc(IXGBE_BR_SIZE, M_DEVBUF, M_WAITOK, &txr->tx_mtx); + if (txr->br == NULL) { + device_printf(dev, + "Critical Failure setting up buf ring\n"); + error = ENOMEM; + goto err_tx_desc; + } #endif } @@ -2713,7 +2594,7 @@ ixgbe_allocate_queues(struct adapter *adapter) * Next the RX queues... */ rsize = roundup2(adapter->num_rx_desc * - sizeof(union ixgbe_adv_rx_desc), 4096); + sizeof(union ixgbe_adv_rx_desc), DBA_ALIGN); for (int i = 0; i < adapter->num_queues; i++, rxconf++) { rxr = &adapter->rx_rings[i]; /* Set up some basics */ @@ -2744,6 +2625,16 @@ ixgbe_allocate_queues(struct adapter *adapter) } } + /* + ** Finally set up the queue holding structs + */ + for (int i = 0; i < adapter->num_queues; i++) { + que = &adapter->queues[i]; + que->adapter = adapter; + que->txr = &adapter->tx_rings[i]; + que->rxr = &adapter->rx_rings[i]; + } + return (0); err_rx_desc: @@ -2755,6 +2646,8 @@ err_tx_desc: free(adapter->rx_rings, M_DEVBUF); rx_fail: free(adapter->tx_rings, M_DEVBUF); +tx_fail: + free(adapter->queues, M_DEVBUF); fail: return (error); } @@ -2831,11 +2724,12 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr) int i; /* Clear the old ring contents */ + IXGBE_TX_LOCK(txr); bzero((void *)txr->tx_base, (sizeof(union ixgbe_adv_tx_desc)) * adapter->num_tx_desc); /* Reset indices */ - txr->next_avail_tx_desc = 0; - txr->next_tx_to_clean = 0; + txr->next_avail_desc = 0; + txr->next_to_clean = 0; /* Free any existing tx buffers. */ txbuf = txr->tx_buffers; @@ -2851,11 +2745,18 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr) txbuf->eop_index = -1; } +#ifdef IXGBE_FDIR + /* Set the rate at which we sample packets */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + txr->atr_sample = atr_sample_rate; +#endif + /* Set number of descriptors available */ txr->tx_avail = adapter->num_tx_desc; bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + IXGBE_TX_UNLOCK(txr); } /********************************************************************* @@ -2889,6 +2790,7 @@ ixgbe_initialize_transmit_units(struct adapter *adapter) for (int i = 0; i < adapter->num_queues; i++, txr++) { u64 tdba = txr->txdma.dma_paddr; + u32 txctrl; IXGBE_WRITE_REG(hw, IXGBE_TDBAL(i), (tdba & 0x00000000ffffffffULL)); @@ -2902,15 +2804,43 @@ ixgbe_initialize_transmit_units(struct adapter *adapter) /* Setup Transmit Descriptor Cmd Settings */ txr->txd_cmd = IXGBE_TXD_CMD_IFCS; + txr->watchdog_check = FALSE; + + /* Disable Head Writeback */ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); + break; + case ixgbe_mac_82599EB: + default: + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); + break; + } + txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl); + break; + case ixgbe_mac_82599EB: + default: + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), txctrl); + break; + } - txr->watchdog_timer = 0; } if (hw->mac.type == ixgbe_mac_82599EB) { - u32 dmatxctl; + u32 dmatxctl, rttdcs; dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); dmatxctl |= IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); + /* Disable arbiter to set MTQC */ + rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS); + rttdcs |= IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); + IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB); + rttdcs &= ~IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); } return; @@ -3010,7 +2940,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) u16 etype; u8 ipproto = 0; bool offload = TRUE; - int ctxd = txr->next_avail_tx_desc; + int ctxd = txr->next_avail_desc; u16 vtag = 0; @@ -3083,6 +3013,12 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP; break; +#if __FreeBSD_version >= 800000 + case IPPROTO_SCTP: + if (mp->m_pkthdr.csum_flags & CSUM_SCTP) + type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; + break; +#endif default: offload = FALSE; break; @@ -3100,7 +3036,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) /* We've consumed the first desc, adjust counters */ if (++ctxd == adapter->num_tx_desc) ctxd = 0; - txr->next_avail_tx_desc = ctxd; + txr->next_avail_desc = ctxd; --txr->tx_avail; return (offload); @@ -3141,7 +3077,7 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen) if (mp->m_len < ehdrlen + sizeof(struct ip) + sizeof(struct tcphdr)) return FALSE; - ctxd = txr->next_avail_tx_desc; + ctxd = txr->next_avail_desc; tx_buffer = &txr->tx_buffers[ctxd]; TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd]; @@ -3189,10 +3125,90 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen) ctxd = 0; txr->tx_avail--; - txr->next_avail_tx_desc = ctxd; + txr->next_avail_desc = ctxd; return TRUE; } +#ifdef IXGBE_FDIR +/* +** This routine parses packet headers so that Flow +** Director can make a hashed filter table entry +** allowing traffic flows to be identified and kept +** on the same cpu. This would be a performance +** hit, but we only do it at IXGBE_FDIR_RATE of +** packets. +*/ +static void +ixgbe_atr(struct tx_ring *txr, struct mbuf *mp) +{ + struct adapter *adapter = txr->adapter; + struct ix_queue *que; + struct ixgbe_atr_input atr_input; + struct ip *ip; + struct tcphdr *th; + struct udphdr *uh; + struct ether_vlan_header *eh; + int ehdrlen, ip_hlen; + u16 etype, vlan_id, src_port, dst_port, flex_bytes; + u32 src_ipv4_addr, dst_ipv4_addr; + u8 l4type = 0, ipproto = 0; + + eh = mtod(mp, struct ether_vlan_header *); + if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) + ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; + else + ehdrlen = ETHER_HDR_LEN; + etype = ntohs(eh->evl_proto); + + /* Only handling IPv4 */ + if (etype != ETHERTYPE_IP) + return; + + ip = (struct ip *)(mp->m_data + ehdrlen); + ipproto = ip->ip_p; + ip_hlen = ip->ip_hl << 2; + src_port = dst_port = 0; + + /* check if we're UDP or TCP */ + switch (ipproto) { + case IPPROTO_TCP: + th = (struct tcphdr *)((caddr_t)ip + ip_hlen); + src_port = th->th_sport; + dst_port = th->th_dport; + l4type |= IXGBE_ATR_L4TYPE_TCP; + break; + case IPPROTO_UDP: + uh = (struct udphdr *)((caddr_t)ip + ip_hlen); + src_port = uh->uh_sport; + dst_port = uh->uh_dport; + l4type |= IXGBE_ATR_L4TYPE_UDP; + break; + default: + return; + } + + memset(&atr_input, 0, sizeof(struct ixgbe_atr_input)); + + vlan_id = htole16(mp->m_pkthdr.ether_vtag); + src_ipv4_addr = ip->ip_src.s_addr; + dst_ipv4_addr = ip->ip_dst.s_addr; + flex_bytes = etype; + que = &adapter->queues[txr->me]; + + ixgbe_atr_set_vlan_id_82599(&atr_input, vlan_id); + ixgbe_atr_set_src_port_82599(&atr_input, dst_port); + ixgbe_atr_set_dst_port_82599(&atr_input, src_port); + ixgbe_atr_set_flex_byte_82599(&atr_input, flex_bytes); + ixgbe_atr_set_l4type_82599(&atr_input, l4type); + /* src and dst are inverted, think how the receiver sees them */ + ixgbe_atr_set_src_ipv4_82599(&atr_input, dst_ipv4_addr); + ixgbe_atr_set_dst_ipv4_82599(&atr_input, src_ipv4_addr); + + /* This assumes the Rx queue and Tx queue are bound to the same CPU */ + ixgbe_fdir_add_signature_filter_82599(&adapter->hw, + &atr_input, que->msix); +} +#endif /********************************************************************** * @@ -3204,10 +3220,9 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen) static boolean_t ixgbe_txeof(struct tx_ring *txr) { - struct adapter * adapter = txr->adapter; + struct adapter *adapter = txr->adapter; struct ifnet *ifp = adapter->ifp; - u32 first, last, done, num_avail; - u32 cleaned = 0; + u32 first, last, done; struct ixgbe_tx_buf *tx_buffer; struct ixgbe_legacy_tx_desc *tx_desc, *eop_desc; @@ -3216,17 +3231,15 @@ ixgbe_txeof(struct tx_ring *txr) if (txr->tx_avail == adapter->num_tx_desc) return FALSE; - num_avail = txr->tx_avail; - first = txr->next_tx_to_clean; - + first = txr->next_to_clean; tx_buffer = &txr->tx_buffers[first]; /* For cleanup we just use legacy struct */ tx_desc = (struct ixgbe_legacy_tx_desc *)&txr->tx_base[first]; last = tx_buffer->eop_index; if (last == -1) return FALSE; - eop_desc = (struct ixgbe_legacy_tx_desc *)&txr->tx_base[last]; + /* ** Get the index of the first descriptor ** BEYOND the EOP and call that 'done'. @@ -3248,10 +3261,11 @@ ixgbe_txeof(struct tx_ring *txr) tx_desc->upper.data = 0; tx_desc->lower.data = 0; tx_desc->buffer_addr = 0; - num_avail++; cleaned++; + ++txr->tx_avail; if (tx_buffer->m_head) { - ifp->if_opackets++; + txr->bytes += + tx_buffer->m_head->m_pkthdr.len; bus_dmamap_sync(txr->txtag, tx_buffer->map, BUS_DMASYNC_POSTWRITE); @@ -3262,6 +3276,7 @@ ixgbe_txeof(struct tx_ring *txr) tx_buffer->map = NULL; } tx_buffer->eop_index = -1; + txr->watchdog_time = ticks; if (++first == adapter->num_tx_desc) first = 0; @@ -3270,6 +3285,8 @@ ixgbe_txeof(struct tx_ring *txr) tx_desc = (struct ixgbe_legacy_tx_desc *)&txr->tx_base[first]; } + ++txr->packets; + ++ifp->if_opackets; /* See if there is more work now */ last = tx_buffer->eop_index; if (last != -1) { @@ -3284,7 +3301,7 @@ ixgbe_txeof(struct tx_ring *txr) bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - txr->next_tx_to_clean = first; + txr->next_to_clean = first; /* * If we have enough room, clear IFF_DRV_OACTIVE to tell the stack that @@ -3292,130 +3309,108 @@ ixgbe_txeof(struct tx_ring *txr) * clear the timeout. Otherwise, if some descriptors have been freed, * restart the timeout. */ - if (num_avail > IXGBE_TX_CLEANUP_THRESHOLD) { + if (txr->tx_avail > IXGBE_TX_CLEANUP_THRESHOLD) { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - /* If all are clean turn off the timer */ - if (num_avail == adapter->num_tx_desc) { - txr->watchdog_timer = 0; - txr->tx_avail = num_avail; + if (txr->tx_avail == adapter->num_tx_desc) { + txr->watchdog_check = FALSE; return FALSE; } } - /* Some were cleaned, so reset timer */ - if (cleaned) - txr->watchdog_timer = IXGBE_TX_TIMEOUT; - txr->tx_avail = num_avail; return TRUE; } /********************************************************************* * - * Get a buffer from system mbuf buffer pool. + * Refresh mbuf buffers for RX descriptor rings + * - now keeps its own state so discards due to resource + * exhaustion are unnecessary, if an mbuf cannot be obtained + * it just returns, keeping its placeholder, thus it can simply + * be recalled to try again. * **********************************************************************/ -static int -ixgbe_get_buf(struct rx_ring *rxr, int i, u8 clean) +static void +ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit) { struct adapter *adapter = rxr->adapter; bus_dma_segment_t seg[2]; struct ixgbe_rx_buf *rxbuf; struct mbuf *mh, *mp; bus_dmamap_t map; - int nsegs, error; - int merr = 0; + int i, nsegs, error, cleaned; + i = rxr->next_to_refresh; + cleaned = -1; /* Signify no completions */ + while (i != limit) { + rxbuf = &rxr->rx_buffers[i]; - rxbuf = &rxr->rx_buffers[i]; + if (rxbuf->m_head == NULL) { + mh = m_gethdr(M_DONTWAIT, MT_DATA); + if (mh == NULL) + goto update; + } else /* reuse */ + mh = rxbuf->m_head; - /* First get our header and payload mbuf */ - if (clean & IXGBE_CLEAN_HDR) { - mh = m_gethdr(M_DONTWAIT, MT_DATA); - if (mh == NULL) - goto remap; - } else /* reuse */ - mh = rxr->rx_buffers[i].m_head; + mh->m_len = MHLEN; + mh->m_flags |= M_PKTHDR; - mh->m_len = MHLEN; - mh->m_flags |= M_PKTHDR; + if (rxbuf->m_pack == NULL) { + mp = m_getjcl(M_DONTWAIT, MT_DATA, + M_PKTHDR, adapter->rx_mbuf_sz); + if (mp == NULL) + goto update; + mp->m_len = adapter->rx_mbuf_sz; + mp->m_flags &= ~M_PKTHDR; + } else { /* reusing */ + mp = rxbuf->m_pack; + mp->m_len = adapter->rx_mbuf_sz; + mp->m_flags &= ~M_PKTHDR; + mp->m_next = NULL; + } - if (clean & IXGBE_CLEAN_PKT) { - mp = m_getjcl(M_DONTWAIT, MT_DATA, - M_PKTHDR, adapter->rx_mbuf_sz); - if (mp == NULL) - goto remap; - mp->m_len = adapter->rx_mbuf_sz; - mp->m_flags &= ~M_PKTHDR; - } else { /* reusing */ - mp = rxr->rx_buffers[i].m_pack; - mp->m_len = adapter->rx_mbuf_sz; - mp->m_flags &= ~M_PKTHDR; + /* + ** Need to create a chain for the following + ** dmamap call at this point. + */ + mh->m_next = mp; + mh->m_pkthdr.len = mh->m_len + mp->m_len; + + /* Get the memory mapping */ + error = bus_dmamap_load_mbuf_sg(rxr->rxtag, + rxr->spare_map, mh, seg, &nsegs, BUS_DMA_NOWAIT); + if (error != 0) { + printf("GET BUF: dmamap load failure - %d\n", error); + m_free(mh); + goto update; + } + + /* Unload old mapping and update buffer struct */ + if (rxbuf->m_head != NULL) + bus_dmamap_unload(rxr->rxtag, rxbuf->map); + map = rxbuf->map; + rxbuf->map = rxr->spare_map; + rxr->spare_map = map; + rxbuf->m_head = mh; + rxbuf->m_pack = mp; + bus_dmamap_sync(rxr->rxtag, + rxbuf->map, BUS_DMASYNC_PREREAD); + + /* Update descriptor */ + rxr->rx_base[i].read.hdr_addr = htole64(seg[0].ds_addr); + rxr->rx_base[i].read.pkt_addr = htole64(seg[1].ds_addr); + + cleaned = i; + /* Calculate next index */ + if (++i == adapter->num_rx_desc) + i = 0; + /* This is the work marker for refresh */ + rxr->next_to_refresh = i; } - /* - ** Need to create a chain for the following - ** dmamap call at this point. - */ - mh->m_next = mp; - mh->m_pkthdr.len = mh->m_len + mp->m_len; +update: + if (cleaned != -1) /* If we refreshed some, bump tail */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(rxr->me), cleaned); - /* Get the memory mapping */ - error = bus_dmamap_load_mbuf_sg(rxr->rxtag, - rxr->spare_map, mh, seg, &nsegs, BUS_DMA_NOWAIT); - if (error != 0) { - printf("GET BUF: dmamap load failure - %d\n", error); - m_free(mh); - return (error); - } - - /* Unload old mapping and update buffer struct */ - if (rxbuf->m_head != NULL) - bus_dmamap_unload(rxr->rxtag, rxbuf->map); - map = rxbuf->map; - rxbuf->map = rxr->spare_map; - rxr->spare_map = map; - rxbuf->m_head = mh; - rxbuf->m_pack = mp; - bus_dmamap_sync(rxr->rxtag, - rxbuf->map, BUS_DMASYNC_PREREAD); - - /* Update descriptor */ - rxr->rx_base[i].read.hdr_addr = htole64(seg[0].ds_addr); - rxr->rx_base[i].read.pkt_addr = htole64(seg[1].ds_addr); - - return (0); - - /* - ** If we get here, we have an mbuf resource - ** issue, so we discard the incoming packet - ** and attempt to reuse existing mbufs next - ** pass thru the ring, but to do so we must - ** fix up the descriptor which had the address - ** clobbered with writeback info. - */ -remap: - adapter->mbuf_header_failed++; - merr = ENOBUFS; - /* Is there a reusable buffer? */ - mh = rxr->rx_buffers[i].m_head; - if (mh == NULL) /* Nope, init error */ - return (merr); - mp = rxr->rx_buffers[i].m_pack; - if (mp == NULL) /* Nope, init error */ - return (merr); - /* Get our old mapping */ - rxbuf = &rxr->rx_buffers[i]; - error = bus_dmamap_load_mbuf_sg(rxr->rxtag, - rxbuf->map, mh, seg, &nsegs, BUS_DMA_NOWAIT); - if (error != 0) { - /* We really have a problem */ - m_free(mh); - return (error); - } - /* Now fix the descriptor as needed */ - rxr->rx_base[i].read.hdr_addr = htole64(seg[0].ds_addr); - rxr->rx_base[i].read.pkt_addr = htole64(seg[1].ds_addr); - - return (merr); + return; } @@ -3449,7 +3444,7 @@ ixgbe_allocate_receive_buffers(struct rx_ring *rxr) ** with packet split (hence the two segments, even though ** it may not always use this. */ - if ((error = bus_dma_tag_create(NULL, /* parent */ + if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -3492,6 +3487,62 @@ fail: return (error); } +/* +** Used to detect a descriptor that has +** been merged by Hardware RSC. +*/ +static inline u32 +ixgbe_rsc_count(union ixgbe_adv_rx_desc *rx) +{ + return (le32toh(rx->wb.lower.lo_dword.data) & + IXGBE_RXDADV_RSCCNT_MASK) >> IXGBE_RXDADV_RSCCNT_SHIFT; +} + +/********************************************************************* + * + * Initialize Hardware RSC (LRO) feature on 82599 + * for an RX ring, this is toggled by the LRO capability + * even though it is transparent to the stack. + * + **********************************************************************/ +static void +ixgbe_setup_hw_rsc(struct rx_ring *rxr) +{ + struct adapter *adapter = rxr->adapter; + struct ixgbe_hw *hw = &adapter->hw; + u32 rscctrl, rdrxctl; + + rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; + rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; + rdrxctl |= IXGBE_RDRXCTL_RSCACKC; + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); + + rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(rxr->me)); + rscctrl |= IXGBE_RSCCTL_RSCEN; + /* + ** Limit the total number of descriptors that + ** can be combined, so it does not exceed 64K + */ + if (adapter->rx_mbuf_sz == MCLBYTES) + rscctrl |= IXGBE_RSCCTL_MAXDESC_16; + else /* using 4K clusters */ + rscctrl |= IXGBE_RSCCTL_MAXDESC_8; + IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(rxr->me), rscctrl); + + /* Enable TCP header recognition */ + IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), + (IXGBE_READ_REG(hw, IXGBE_PSRTYPE(0)) | + IXGBE_PSRTYPE_TCPHDR)); + + /* Disable RSC for ACK packets */ + IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, + (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); + + rxr->hw_rsc = TRUE; +} + + /********************************************************************* * * Initialize a receive ring and its buffers. @@ -3504,14 +3555,16 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) struct ifnet *ifp; device_t dev; struct ixgbe_rx_buf *rxbuf; + bus_dma_segment_t seg[2]; struct lro_ctrl *lro = &rxr->lro; - int j, rsize; + int rsize, nsegs, error; adapter = rxr->adapter; ifp = adapter->ifp; dev = adapter->dev; /* Clear the ring contents */ + IXGBE_RX_LOCK(rxr); rsize = roundup2(adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc), DBA_ALIGN); bzero((void *)rxr->rx_base, rsize); @@ -3534,20 +3587,43 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) } } - /* Now refresh the mbufs */ - for (j = 0; j < adapter->num_rx_desc; j++) { - if (ixgbe_get_buf(rxr, j, IXGBE_CLEAN_ALL) == ENOBUFS) { - rxr->rx_buffers[j].m_head = NULL; - rxr->rx_buffers[j].m_pack = NULL; - rxr->rx_base[j].read.hdr_addr = 0; - rxr->rx_base[j].read.pkt_addr = 0; - goto fail; - } + /* Now replenish the mbufs */ + for (int j = 0; j != adapter->num_rx_desc; ++j) { + + rxbuf = &rxr->rx_buffers[j]; + rxbuf->m_head = m_gethdr(M_DONTWAIT, MT_DATA); + if (rxbuf->m_head == NULL) + panic("RX ring hdr initialization failed!\n"); + rxbuf->m_head->m_len = MHLEN; + rxbuf->m_head->m_flags |= M_PKTHDR; + rxbuf->m_head->m_pkthdr.len = rxbuf->m_head->m_len; + + rxbuf->m_pack = m_getjcl(M_DONTWAIT, MT_DATA, + M_PKTHDR, adapter->rx_mbuf_sz); + if (rxbuf->m_pack == NULL) + panic("RX ring pkt initialization failed!\n"); + rxbuf->m_pack->m_len = adapter->rx_mbuf_sz; + rxbuf->m_head->m_next = rxbuf->m_pack; + rxbuf->m_head->m_pkthdr.len += rxbuf->m_pack->m_len; + + /* Get the memory mapping */ + error = bus_dmamap_load_mbuf_sg(rxr->rxtag, + rxbuf->map, rxbuf->m_head, seg, + &nsegs, BUS_DMA_NOWAIT); + if (error != 0) + panic("RX ring dma initialization failed!\n"); + bus_dmamap_sync(rxr->rxtag, + rxbuf->map, BUS_DMASYNC_PREREAD); + + /* Update descriptor */ + rxr->rx_base[j].read.hdr_addr = htole64(seg[0].ds_addr); + rxr->rx_base[j].read.pkt_addr = htole64(seg[1].ds_addr); } + /* Setup our descriptor indices */ rxr->next_to_check = 0; - rxr->last_cleaned = 0; + rxr->next_to_refresh = 0; rxr->lro_enabled = FALSE; /* Use header split if configured */ @@ -3558,40 +3634,27 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr) BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* - ** Now set up the LRO interface, we - ** also only do head split when LRO - ** is enabled, since so often they - ** are undesireable in similar setups. + ** Now set up the LRO interface: + ** 82598 uses software LRO, the + ** 82599 additionally uses a + ** hardware assist. + ** + ** Disable RSC when RXCSUM is off */ - if (ifp->if_capenable & IFCAP_LRO) { + if ((adapter->hw.mac.type == ixgbe_mac_82599EB) && + (ifp->if_capenable & IFCAP_RXCSUM)) + ixgbe_setup_hw_rsc(rxr); + else if (ifp->if_capenable & IFCAP_LRO) { int err = tcp_lro_init(lro); - if (err) { - INIT_DEBUGOUT("LRO Initialization failed!\n"); - goto fail; - } - INIT_DEBUGOUT("RX LRO Initialized\n"); + if (err) + panic("LRO Initialization failed!\n"); + INIT_DEBUGOUT("RX Soft LRO Initialized\n"); rxr->lro_enabled = TRUE; lro->ifp = adapter->ifp; } + IXGBE_RX_UNLOCK(rxr); return (0); - -fail: - /* - * We need to clean up any buffers allocated - * so far, 'j' is the failing index. - */ - for (int i = 0; i < j; i++) { - rxbuf = &rxr->rx_buffers[i]; - if (rxbuf->m_head != NULL) { - bus_dmamap_sync(rxr->rxtag, rxbuf->map, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(rxr->rxtag, rxbuf->map); - m_freem(rxbuf->m_head); - rxbuf->m_head = NULL; - } - } - return (ENOBUFS); } /********************************************************************* @@ -3787,6 +3850,7 @@ ixgbe_free_receive_structures(struct adapter *adapter) free(adapter->rx_rings, M_DEVBUF); } + /********************************************************************* * * Free receive ring data structures @@ -3827,6 +3891,61 @@ ixgbe_free_receive_buffers(struct rx_ring *rxr) return; } +static __inline void +ixgbe_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype) +{ + + /* + * ATM LRO is only for IPv4/TCP packets and TCP checksum of the packet + * should be computed by hardware. Also it should not have VLAN tag in + * ethernet header. + */ + if (rxr->lro_enabled && + (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 && + (ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 && + (ptype & (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)) == + (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP) && + (m->m_pkthdr.csum_flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) == + (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) { + /* + * Send to the stack if: + ** - LRO not enabled, or + ** - no LRO resources, or + ** - lro enqueue fails + */ + if (rxr->lro.lro_cnt != 0) + if (tcp_lro_rx(&rxr->lro, m, 0) == 0) + return; + } + (*ifp->if_input)(ifp, m); +} + +static __inline void +ixgbe_rx_discard(struct rx_ring *rxr, int i) +{ + struct adapter *adapter = rxr->adapter; + struct ixgbe_rx_buf *rbuf; + struct mbuf *mh, *mp; + + rbuf = &rxr->rx_buffers[i]; + if (rbuf->fmp != NULL) /* Partial chain ? */ + m_freem(rbuf->fmp); + + mh = rbuf->m_head; + mp = rbuf->m_pack; + + /* Reuse loaded DMA map and just update mbuf chain */ + mh->m_len = MHLEN; + mh->m_flags |= M_PKTHDR; + mh->m_next = NULL; + + mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz; + mp->m_data = mp->m_ext.ext_buf; + mp->m_next = NULL; + return; +} + + /********************************************************************* * * This routine executes in interrupt context. It replenishes @@ -3839,247 +3958,239 @@ ixgbe_free_receive_buffers(struct rx_ring *rxr) * Return TRUE for more work, FALSE for all clean. *********************************************************************/ static bool -ixgbe_rxeof(struct rx_ring *rxr, int count) +ixgbe_rxeof(struct ix_queue *que, int count) { - struct adapter *adapter = rxr->adapter; - struct ifnet *ifp = adapter->ifp; + struct adapter *adapter = que->adapter; + struct rx_ring *rxr = que->rxr; + struct ifnet *ifp = adapter->ifp; struct lro_ctrl *lro = &rxr->lro; struct lro_entry *queued; - int i; - u32 staterr; + int i, nextp, processed = 0; + u32 staterr = 0; union ixgbe_adv_rx_desc *cur; - + struct ixgbe_rx_buf *rbuf, *nbuf; IXGBE_RX_LOCK(rxr); - i = rxr->next_to_check; - cur = &rxr->rx_base[i]; - staterr = cur->wb.upper.status_error; - if (!(staterr & IXGBE_RXD_STAT_DD)) { - IXGBE_RX_UNLOCK(rxr); - return FALSE; - } - - /* Sync the ring */ + /* Sync the ring. */ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, - BUS_DMASYNC_POSTREAD); + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - while ((staterr & IXGBE_RXD_STAT_DD) && (count != 0) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) { + for (i = rxr->next_to_check; count != 0;) { struct mbuf *sendmp, *mh, *mp; - u16 hlen, plen, hdr, vtag; - u8 dopayload, accept_frame, eop; + u32 rsc, ptype; + u16 hlen, plen, hdr, vtag; + bool eop; + + cur = &rxr->rx_base[i]; + staterr = le32toh(cur->wb.upper.status_error); + if ((staterr & IXGBE_RXD_STAT_DD) == 0) + break; + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; - accept_frame = 1; - hlen = plen = vtag = 0; - sendmp = mh = mp = NULL; + count--; + sendmp = NULL; + nbuf = NULL; + rsc = 0; + cur->wb.upper.status_error = 0; + rbuf = &rxr->rx_buffers[i]; + mh = rbuf->m_head; + mp = rbuf->m_pack; - /* Sync the buffers */ - bus_dmamap_sync(rxr->rxtag, rxr->rx_buffers[i].map, - BUS_DMASYNC_POSTREAD); + plen = le16toh(cur->wb.upper.length); + ptype = le32toh(cur->wb.lower.lo_dword.data) & + IXGBE_RXDADV_PKTTYPE_MASK; + hdr = le16toh(cur->wb.lower.lo_dword.hs_rss.hdr_info); + vtag = le16toh(cur->wb.upper.vlan); + eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0); + + /* Make sure all parts of a bad packet are discarded */ + if (((staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) || + (rxr->discard)) { + ifp->if_ierrors++; + rxr->rx_discarded++; + if (!eop) + rxr->discard = TRUE; + else + rxr->discard = FALSE; + ixgbe_rx_discard(rxr, i); + goto next_desc; + } /* - ** The way the hardware is configured to - ** split, it will ONLY use the header buffer - ** when header split is enabled, otherwise we - ** get normal behavior, ie, both header and - ** payload are DMA'd into the payload buffer. - ** - ** The fmp test is to catch the case where a - ** packet spans multiple descriptors, in that - ** case only the first header is valid. + ** On 82599 which supports a hardware + ** LRO (called HW RSC), packets need + ** not be fragmented across sequential + ** descriptors, rather the next descriptor + ** is indicated in bits of the descriptor. + ** This also means that we might proceses + ** more than one packet at a time, something + ** that has never been true before, it + ** required eliminating global chain pointers + ** in favor of what we are doing here. -jfv */ - if ((rxr->hdr_split) && (rxr->fmp == NULL)){ - hdr = le16toh(cur-> - wb.lower.lo_dword.hs_rss.hdr_info); + if (!eop) { + /* + ** Figure out the next descriptor + ** of this frame. + */ + if (rxr->hw_rsc == TRUE) { + rsc = ixgbe_rsc_count(cur); + rxr->rsc_num += (rsc - 1); + } + if (rsc) { /* Get hardware index */ + nextp = ((staterr & + IXGBE_RXDADV_NEXTP_MASK) >> + IXGBE_RXDADV_NEXTP_SHIFT); + } else { /* Just sequential */ + nextp = i + 1; + if (nextp == adapter->num_rx_desc) + nextp = 0; + } + nbuf = &rxr->rx_buffers[nextp]; + prefetch(nbuf); + } + /* + ** The header mbuf is ONLY used when header + ** split is enabled, otherwise we get normal + ** behavior, ie, both header and payload + ** are DMA'd into the payload buffer. + ** + ** Rather than using the fmp/lmp global pointers + ** we now keep the head of a packet chain in the + ** buffer struct and pass this along from one + ** descriptor to the next, until we get EOP. + */ + if (rxr->hdr_split && (rbuf->fmp == NULL)) { + /* This must be an initial descriptor */ hlen = (hdr & IXGBE_RXDADV_HDRBUFLEN_MASK) >> IXGBE_RXDADV_HDRBUFLEN_SHIFT; if (hlen > IXGBE_RX_HDR) hlen = IXGBE_RX_HDR; - plen = le16toh(cur->wb.upper.length); - /* Handle the header mbuf */ - mh = rxr->rx_buffers[i].m_head; mh->m_len = hlen; - dopayload = IXGBE_CLEAN_HDR; + mh->m_flags |= M_PKTHDR; + mh->m_next = NULL; + mh->m_pkthdr.len = mh->m_len; + /* Null buf pointer so it is refreshed */ + rbuf->m_head = NULL; /* - ** Get the payload length, this + ** Check the payload length, this ** could be zero if its a small ** packet. */ - if (plen) { - mp = rxr->rx_buffers[i].m_pack; + if (plen > 0) { mp->m_len = plen; mp->m_next = NULL; mp->m_flags &= ~M_PKTHDR; mh->m_next = mp; - mh->m_flags |= M_PKTHDR; - dopayload = IXGBE_CLEAN_ALL; + mh->m_pkthdr.len += mp->m_len; + /* Null buf pointer so it is refreshed */ + rbuf->m_pack = NULL; rxr->rx_split_packets++; - } else { /* small packets */ - mh->m_flags &= ~M_PKTHDR; - mh->m_next = NULL; } + /* + ** Now create the forward + ** chain so when complete + ** we wont have to. + */ + if (eop == 0) { + /* stash the chain head */ + nbuf->fmp = mh; + /* Make forward chain */ + if (plen) + mp->m_next = nbuf->m_pack; + else + mh->m_next = nbuf->m_pack; + } else { + /* Singlet, prepare to send */ + sendmp = mh; + if (staterr & IXGBE_RXD_STAT_VP) { + sendmp->m_pkthdr.ether_vtag = vtag; + sendmp->m_flags |= M_VLANTAG; + } + } } else { /* ** Either no header split, or a ** secondary piece of a fragmented ** split packet. */ - mh = rxr->rx_buffers[i].m_pack; - mh->m_flags |= M_PKTHDR; - mh->m_len = le16toh(cur->wb.upper.length); - dopayload = IXGBE_CLEAN_PKT; - } - - if (staterr & IXGBE_RXD_STAT_EOP) { - count--; - eop = 1; - } else - eop = 0; - -#ifdef IXGBE_IEEE1588 - This code needs to be converted to work here - ----------------------------------------------------- - if (unlikely(staterr & IXGBE_RXD_STAT_TS)) { - u64 regval; - u64 ns; -// Create an mtag and set it up - struct skb_shared_hwtstamps *shhwtstamps = - skb_hwtstamps(skb); - - rd32(IXGBE_TSYNCRXCTL) & IXGBE_TSYNCRXCTL_VALID), - "igb: no RX time stamp available for time stamped packet"); - regval = rd32(IXGBE_RXSTMPL); - regval |= (u64)rd32(IXGBE_RXSTMPH) << 32; -// Do time conversion from the register - ns = timecounter_cyc2time(&adapter->clock, regval); - clocksync_update(&adapter->sync, ns); - memset(shhwtstamps, 0, sizeof(*shhwtstamps)); - shhwtstamps->hwtstamp = ns_to_ktime(ns); - shhwtstamps->syststamp = - clocksync_hw2sys(&adapter->sync, ns); - } -#endif - - if (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) - accept_frame = 0; - - if (accept_frame) { + mp->m_len = plen; /* - ** Save the vlan id, because get_buf will - ** clobber the writeback descriptor... + ** See if there is a stored head + ** that determines what we are */ - vtag = le16toh(cur->wb.upper.vlan); - if (ixgbe_get_buf(rxr, i, dopayload) != 0) { - ifp->if_iqdrops++; - goto discard; - } - /* Initial frame - setup */ - if (rxr->fmp == NULL) { - mh->m_flags |= M_PKTHDR; - mh->m_pkthdr.len = mh->m_len; - rxr->fmp = mh; /* Store the first mbuf */ - rxr->lmp = mh; - if (mp) { /* Add payload if split */ - mh->m_pkthdr.len += mp->m_len; - rxr->lmp = mh->m_next; - } - } else { - /* Chain mbuf's together */ - mh->m_flags &= ~M_PKTHDR; - rxr->lmp->m_next = mh; - rxr->lmp = rxr->lmp->m_next; - rxr->fmp->m_pkthdr.len += mh->m_len; - } + sendmp = rbuf->fmp; + rbuf->m_pack = rbuf->fmp = NULL; - if (eop) { - rxr->fmp->m_pkthdr.rcvif = ifp; - ifp->if_ipackets++; - rxr->rx_packets++; - /* capture data for AIM */ - rxr->bytes += rxr->fmp->m_pkthdr.len; - rxr->rx_bytes += rxr->bytes; - if (ifp->if_capenable & IFCAP_RXCSUM) - ixgbe_rx_checksum(staterr, rxr->fmp); - else - rxr->fmp->m_pkthdr.csum_flags = 0; + if (sendmp != NULL) /* secondary frag */ + sendmp->m_pkthdr.len += mp->m_len; + else { + /* first desc of a non-ps chain */ + sendmp = mp; + sendmp->m_flags |= M_PKTHDR; + sendmp->m_pkthdr.len = mp->m_len; if (staterr & IXGBE_RXD_STAT_VP) { - rxr->fmp->m_pkthdr.ether_vtag = vtag; - rxr->fmp->m_flags |= M_VLANTAG; + sendmp->m_pkthdr.ether_vtag = vtag; + sendmp->m_flags |= M_VLANTAG; } -#if __FreeBSD_version >= 800000 - rxr->fmp->m_pkthdr.flowid = curcpu; - rxr->fmp->m_flags |= M_FLOWID; -#endif - sendmp = rxr->fmp; - rxr->fmp = NULL; - rxr->lmp = NULL; + } + /* Pass the head pointer on */ + if (eop == 0) { + nbuf->fmp = sendmp; + sendmp = NULL; + mp->m_next = nbuf->m_pack; } - } else { - ifp->if_ierrors++; -discard: - /* Reuse loaded DMA map and just update mbuf chain */ - if (hlen) { - mh = rxr->rx_buffers[i].m_head; - mh->m_len = MHLEN; - mh->m_next = NULL; - } - mp = rxr->rx_buffers[i].m_pack; - mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz; - mp->m_data = mp->m_ext.ext_buf; - mp->m_next = NULL; - if (adapter->max_frame_size <= - (MCLBYTES - ETHER_ALIGN)) - m_adj(mp, ETHER_ALIGN); - if (rxr->fmp != NULL) { - /* handles the whole chain */ - m_freem(rxr->fmp); - rxr->fmp = NULL; - rxr->lmp = NULL; - } - sendmp = NULL; } + ++processed; + /* Sending this frame? */ + if (eop) { + sendmp->m_pkthdr.rcvif = ifp; + ifp->if_ipackets++; + rxr->rx_packets++; + /* capture data for AIM */ + rxr->bytes += sendmp->m_pkthdr.len; + rxr->rx_bytes += sendmp->m_pkthdr.len; + if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) + ixgbe_rx_checksum(staterr, sendmp, ptype); +#if __FreeBSD_version >= 800000 + sendmp->m_pkthdr.flowid = que->msix; + sendmp->m_flags |= M_FLOWID; +#endif + } +next_desc: bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - rxr->last_cleaned = i; /* for updating tail */ - + /* Advance our pointers to the next descriptor. */ if (++i == adapter->num_rx_desc) i = 0; - /* - ** Now send up to the stack, - ** note the the value of next_to_check - ** is safe because we keep the RX lock - ** thru this call. - */ - if (sendmp != NULL) { - /* - ** Send to the stack if: - ** - LRO not enabled, or - ** - no LRO resources, or - ** - lro enqueue fails - */ - if ((!rxr->lro_enabled) || - ((!lro->lro_cnt) || (tcp_lro_rx(lro, sendmp, 0)))) - (*ifp->if_input)(ifp, sendmp); - } + /* Now send to the stack or do LRO */ + if (sendmp != NULL) + ixgbe_rx_input(rxr, ifp, sendmp, ptype); - /* Get next descriptor */ - cur = &rxr->rx_base[i]; - staterr = cur->wb.upper.status_error; + /* Every 8 descriptors we go to refresh mbufs */ + if (processed == 8) { + ixgbe_refresh_mbufs(rxr, i); + processed = 0; + } } - rxr->next_to_check = i; - /* Advance the IXGB's Receive Queue "Tail Pointer" */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(rxr->me), rxr->last_cleaned); + /* Refresh any remaining buf structs */ + if (processed != 0) { + ixgbe_refresh_mbufs(rxr, i); + processed = 0; + } + + rxr->next_to_check = i; /* * Flush any outstanding LRO work */ - while (!SLIST_EMPTY(&lro->lro_active)) { - queued = SLIST_FIRST(&lro->lro_active); + while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) { SLIST_REMOVE_HEAD(&lro->lro_active, next); tcp_lro_flush(lro, queued); } @@ -4087,17 +4198,18 @@ discard: IXGBE_RX_UNLOCK(rxr); /* - ** Leaving with more to clean? - ** then schedule another interrupt. + ** We still have cleaning to do? + ** Schedule another interrupt if so. */ - if (staterr & IXGBE_RXD_STAT_DD) { - ixgbe_rearm_rx_queues(adapter, (u64)(1 << rxr->msix)); - return TRUE; + if ((staterr & IXGBE_RXD_STAT_DD) != 0) { + ixgbe_rearm_queues(adapter, (u64)(1 << que->msix)); + return (TRUE); } - return FALSE; + return (FALSE); } + /********************************************************************* * * Verify that the hardware indicated that the checksum is valid. @@ -4106,13 +4218,17 @@ discard: * *********************************************************************/ static void -ixgbe_rx_checksum(u32 staterr, struct mbuf * mp) +ixgbe_rx_checksum(u32 staterr, struct mbuf * mp, u32 ptype) { - u16 status = (u16) staterr; - u8 errors = (u8) (staterr >> 24); + u16 status = (u16) staterr; + u8 errors = (u8) (staterr >> 24); + bool sctp = FALSE; + + if ((ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 && + (ptype & IXGBE_RXDADV_PKTTYPE_SCTP) != 0) + sctp = TRUE; if (status & IXGBE_RXD_STAT_IPCS) { - /* Did it pass? */ if (!(errors & IXGBE_RXD_ERR_IPE)) { /* IP Checksum Good */ mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED; @@ -4122,11 +4238,15 @@ ixgbe_rx_checksum(u32 staterr, struct mbuf * mp) mp->m_pkthdr.csum_flags = 0; } if (status & IXGBE_RXD_STAT_L4CS) { - /* Did it pass? */ + u16 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); +#if __FreeBSD_version >= 800000 + if (sctp) + type = CSUM_SCTP_VALID; +#endif if (!(errors & IXGBE_RXD_ERR_TCPE)) { - mp->m_pkthdr.csum_flags |= - (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); - mp->m_pkthdr.csum_data = htons(0xffff); + mp->m_pkthdr.csum_flags |= type; + if (!sctp) + mp->m_pkthdr.csum_data = htons(0xffff); } } return; @@ -4231,8 +4351,7 @@ static void ixgbe_enable_intr(struct adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; + struct ix_queue *que = adapter->queues; u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); @@ -4245,6 +4364,9 @@ ixgbe_enable_intr(struct adapter *adapter) mask |= IXGBE_EIMS_ECC; mask |= IXGBE_EIMS_GPI_SDP1; mask |= IXGBE_EIMS_GPI_SDP2; +#ifdef IXGBE_FDIR + mask |= IXGBE_EIMS_FLOW_DIR; +#endif } IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask); @@ -4263,10 +4385,8 @@ ixgbe_enable_intr(struct adapter *adapter) ** allow for handling the extended (beyond 32) MSIX ** vectors that can be used by 82599 */ - for (int i = 0; i < adapter->num_queues; i++, rxr++) - ixgbe_enable_queue(adapter, rxr->msix); - for (int i = 0; i < adapter->num_queues; i++, txr++) - ixgbe_enable_queue(adapter, txr->msix); + for (int i = 0; i < adapter->num_queues; i++, que++) + ixgbe_enable_queue(adapter, que->msix); IXGBE_WRITE_FLUSH(hw); @@ -4361,14 +4481,17 @@ ixgbe_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type) static void ixgbe_configure_ivars(struct adapter *adapter) { - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; + struct ix_queue *que = adapter->queues; - for (int i = 0; i < adapter->num_queues; i++, rxr++) - ixgbe_set_ivar(adapter, i, rxr->msix, 0); - - for (int i = 0; i < adapter->num_queues; i++, txr++) - ixgbe_set_ivar(adapter, i, txr->msix, 1); + for (int i = 0; i < adapter->num_queues; i++, que++) { + /* First the RX queue entry */ + ixgbe_set_ivar(adapter, i, que->msix, 0); + /* ... and the TX */ + ixgbe_set_ivar(adapter, i, que->msix, 1); + /* Set an Initial EITR value */ + IXGBE_WRITE_REG(&adapter->hw, + IXGBE_EITR(que->msix), IXGBE_LOW_LATENCY); + } /* For the Link interrupt */ ixgbe_set_ivar(adapter, 1, adapter->linkvec, -1); @@ -4436,7 +4559,12 @@ ixgbe_handle_mod(void *context, int pending) "Unsupported SFP+ module type was detected.\n"); return; } - hw->mac.ops.setup_sfp(hw); + err = hw->mac.ops.setup_sfp(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + device_printf(dev, + "Setup failure - unsupported SFP+ module type.\n"); + return; + } taskqueue_enqueue(adapter->tq, &adapter->msf_task); return; } @@ -4451,15 +4579,17 @@ ixgbe_handle_msf(void *context, int pending) struct adapter *adapter = context; struct ixgbe_hw *hw = &adapter->hw; u32 autoneg; + bool negotiate; - if (hw->mac.ops.get_link_capabilities) - hw->mac.ops.get_link_capabilities(hw, &autoneg, - &hw->mac.autoneg); - if (hw->mac.ops.setup_link_speed) - hw->mac.ops.setup_link_speed(hw, autoneg, TRUE, TRUE); - ixgbe_check_link(&adapter->hw, - &adapter->link_speed, &adapter->link_up, 0); + autoneg = hw->phy.autoneg_advertised; + if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) + hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiate); + if (hw->mac.ops.setup_link) + hw->mac.ops.setup_link(hw, autoneg, negotiate, TRUE); +#if 0 + ixgbe_check_link(&adapter->hw, &speed, &adapter->link_up, 0); ixgbe_update_link_status(adapter); +#endif return; } @@ -4499,14 +4629,16 @@ ixgbe_update_stats_counters(struct adapter *adapter) adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); for (int i = 0; i < 8; i++) { + u32 mp; + mp = IXGBE_READ_REG(hw, IXGBE_MPC(i)); /* missed_rx tallies misses for the gprc workaround */ - missed_rx += IXGBE_READ_REG(hw, IXGBE_MPC(i)); - adapter->stats.mpc[i] += missed_rx; + missed_rx += mp; + /* global total per queue */ + adapter->stats.mpc[i] += mp; /* Running comprehensive total for stats display */ total_missed_rx += adapter->stats.mpc[i]; if (hw->mac.type == ixgbe_mac_82598EB) - adapter->stats.rnbc[i] += - IXGBE_READ_REG(hw, IXGBE_RNBC(i)); + adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i)); } /* Hardware workaround, gprc counts missed packets */ @@ -4648,42 +4780,43 @@ static void ixgbe_print_debug_info(struct adapter *adapter) { device_t dev = adapter->dev; - struct rx_ring *rxr = adapter->rx_rings; - struct tx_ring *txr = adapter->tx_rings; - struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_hw *hw = &adapter->hw; + struct ix_queue *que = adapter->queues; + struct rx_ring *rxr; + struct tx_ring *txr; + struct lro_ctrl *lro; device_printf(dev,"Error Byte Count = %u \n", IXGBE_READ_REG(hw, IXGBE_ERRBC)); - for (int i = 0; i < adapter->num_queues; i++, rxr++) { - struct lro_ctrl *lro = &rxr->lro; - device_printf(dev,"Queue[%d]: rdh = %d, hw rdt = %d\n", + for (int i = 0; i < adapter->num_queues; i++, que++) { + txr = que->txr; + rxr = que->rxr; + lro = &rxr->lro; + device_printf(dev,"QUE(%d) IRQs Handled: %lu\n", + que->msix, (long)que->irqs); + device_printf(dev,"RX[%d]: rdh = %d, hw rdt = %d\n", i, IXGBE_READ_REG(hw, IXGBE_RDH(i)), IXGBE_READ_REG(hw, IXGBE_RDT(i))); + device_printf(dev,"TX[%d] tdh = %d, hw tdt = %d\n", i, + IXGBE_READ_REG(hw, IXGBE_TDH(i)), + IXGBE_READ_REG(hw, IXGBE_TDT(i))); device_printf(dev,"RX(%d) Packets Received: %lld\n", rxr->me, (long long)rxr->rx_packets); device_printf(dev,"RX(%d) Split RX Packets: %lld\n", rxr->me, (long long)rxr->rx_split_packets); device_printf(dev,"RX(%d) Bytes Received: %lu\n", rxr->me, (long)rxr->rx_bytes); - device_printf(dev,"RX(%d) IRQ Handled: %lu\n", - rxr->me, (long)rxr->rx_irq); device_printf(dev,"RX(%d) LRO Queued= %d\n", rxr->me, lro->lro_queued); device_printf(dev,"RX(%d) LRO Flushed= %d\n", rxr->me, lro->lro_flushed); - } - - for (int i = 0; i < adapter->num_queues; i++, txr++) { - device_printf(dev,"Queue(%d) tdh = %d, hw tdt = %d\n", i, - IXGBE_READ_REG(hw, IXGBE_TDH(i)), - IXGBE_READ_REG(hw, IXGBE_TDT(i))); + device_printf(dev,"RX(%d) HW LRO Merges= %lu\n", + rxr->me, (long)rxr->rsc_num); device_printf(dev,"TX(%d) Packets Sent: %lu\n", txr->me, (long)txr->total_packets); - device_printf(dev,"TX(%d) IRQ Handled: %lu\n", - txr->me, (long)txr->tx_irq); device_printf(dev,"TX(%d) NO Desc Avail: %lu\n", - txr->me, (long)txr->no_tx_desc_avail); + txr->me, (long)txr->no_desc_avail); } device_printf(dev,"Link IRQ Handled: %lu\n", @@ -4774,174 +4907,3 @@ ixgbe_add_rx_process_limit(struct adapter *adapter, const char *name, SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); } - -#ifdef IXGBE_IEEE1588 - -/* -** ixgbe_hwtstamp_ioctl - control hardware time stamping -** -** Outgoing time stamping can be enabled and disabled. Play nice and -** disable it when requested, although it shouldn't case any overhead -** when no packet needs it. At most one packet in the queue may be -** marked for time stamping, otherwise it would be impossible to tell -** for sure to which packet the hardware time stamp belongs. -** -** Incoming time stamping has to be configured via the hardware -** filters. Not all combinations are supported, in particular event -** type has to be specified. Matching the kind of event packet is -** not supported, with the exception of "all V2 events regardless of -** level 2 or 4". -** -*/ -static int -ixgbe_hwtstamp_ioctl(struct adapter *adapter, struct ifreq *ifr) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct hwtstamp_ctrl *config; - u32 tsync_tx_ctl_bit = IXGBE_TSYNCTXCTL_ENABLED; - u32 tsync_rx_ctl_bit = IXGBE_TSYNCRXCTL_ENABLED; - u32 tsync_rx_ctl_type = 0; - u32 tsync_rx_cfg = 0; - int is_l4 = 0; - int is_l2 = 0; - u16 port = 319; /* PTP */ - u32 regval; - - config = (struct hwtstamp_ctrl *) ifr->ifr_data; - - /* reserved for future extensions */ - if (config->flags) - return (EINVAL); - - switch (config->tx_type) { - case HWTSTAMP_TX_OFF: - tsync_tx_ctl_bit = 0; - break; - case HWTSTAMP_TX_ON: - tsync_tx_ctl_bit = IXGBE_TSYNCTXCTL_ENABLED; - break; - default: - return (ERANGE); - } - - switch (config->rx_filter) { - case HWTSTAMP_FILTER_NONE: - tsync_rx_ctl_bit = 0; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: - case HWTSTAMP_FILTER_ALL: - /* - * register TSYNCRXCFG must be set, therefore it is not - * possible to time stamp both Sync and Delay_Req messages - * => fall back to time stamping all packets - */ - tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_ALL; - config->rx_filter = HWTSTAMP_FILTER_ALL; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: - tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_L4_V1; - tsync_rx_cfg = IXGBE_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE; - is_l4 = 1; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: - tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_L4_V1; - tsync_rx_cfg = IXGBE_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE; - is_l4 = 1; - break; - case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: - tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2; - tsync_rx_cfg = IXGBE_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE; - is_l2 = 1; - is_l4 = 1; - config->rx_filter = HWTSTAMP_FILTER_SOME; - break; - case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: - case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: - tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2; - tsync_rx_cfg = IXGBE_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE; - is_l2 = 1; - is_l4 = 1; - config->rx_filter = HWTSTAMP_FILTER_SOME; - break; - case HWTSTAMP_FILTER_PTP_V2_EVENT: - case HWTSTAMP_FILTER_PTP_V2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: - tsync_rx_ctl_type = IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; - config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; - is_l2 = 1; - break; - default: - return -ERANGE; - } - - /* enable/disable TX */ - regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); - regval = (regval & ~IXGBE_TSYNCTXCTL_ENABLED) | tsync_tx_ctl_bit; - IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, regval); - - /* enable/disable RX, define which PTP packets are time stamped */ - regval = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); - regval = (regval & ~IXGBE_TSYNCRXCTL_ENABLED) | tsync_rx_ctl_bit; - regval = (regval & ~0xE) | tsync_rx_ctl_type; - IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, regval); - IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCFG, tsync_rx_cfg); - - /* - * Ethertype Filter Queue Filter[0][15:0] = 0x88F7 - * (Ethertype to filter on) - * Ethertype Filter Queue Filter[0][26] = 0x1 (Enable filter) - * Ethertype Filter Queue Filter[0][30] = 0x1 (Enable Timestamping) - */ - IXGBE_WRITE_REG(hw, IXGBE_ETQF0, is_l2 ? 0x440088f7 : 0); - - /* L4 Queue Filter[0]: only filter by source and destination port */ - IXGBE_WRITE_REG(hw, IXGBE_SPQF0, htons(port)); - IXGBE_WRITE_REG(hw, IXGBE_IMIREXT(0), is_l4 ? - ((1<<12) | (1<<19) /* bypass size and control flags */) : 0); - IXGBE_WRITE_REG(hw, IXGBE_IMIR(0), is_l4 ? - (htons(port) - | (0<<16) /* immediate interrupt disabled */ - | 0 /* (1<<17) bit cleared: do not bypass - destination port check */) - : 0); - IXGBE_WRITE_REG(hw, IXGBE_FTQF0, is_l4 ? - (0x11 /* UDP */ - | (1<<15) /* VF not compared */ - | (1<<27) /* Enable Timestamping */ - | (7<<28) /* only source port filter enabled, - source/target address and protocol - masked */) - : ((1<<15) | (15<<28) /* all mask bits set = filter not - enabled */)); - - wrfl(); - - adapter->hwtstamp_ctrl = config; - - /* clear TX/RX time stamp registers, just to be sure */ - regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH); - regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH); - - return (error); -} - -/* -** ixgbe_read_clock - read raw cycle counter (to be used by time counter) -*/ -static cycle_t ixgbe_read_clock(const struct cyclecounter *tc) -{ - struct adapter *adapter = - container_of(tc, struct igb_adapter, cycles); - struct ixgbe_hw *hw = &adapter->hw; - u64 stamp; - - stamp = IXGBE_READ_REG(hw, IXGBE_SYSTIML); - stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32ULL; - - return (stamp); -} - -#endif /* IXGBE_IEEE1588 */ diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h index 848820a8e95..f598b8f2b62 100644 --- a/sys/dev/ixgbe/ixgbe.h +++ b/sys/dev/ixgbe/ixgbe.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -134,9 +134,11 @@ #define MAX_LOOP 10 /* - * This parameter controls the duration of transmit watchdog timer. + * This is the max watchdog interval, ie. the time that can + * pass between any two TX clean operations, such only happening + * when the TX hardware is functioning. */ -#define IXGBE_TX_TIMEOUT 5 /* set to 5 seconds */ +#define IXGBE_WATCHDOG (10 * hz) /* * This parameters control when the driver calls the routine to reclaim @@ -148,7 +150,7 @@ #define IXGBE_MAX_FRAME_SIZE 0x3F00 /* Flow control constants */ -#define IXGBE_FC_PAUSE 0x680 +#define IXGBE_FC_PAUSE 0xFFFF #define IXGBE_FC_HI 0x20000 #define IXGBE_FC_LO 0x10000 @@ -177,7 +179,13 @@ #define IXGBE_RX_HDR 128 #define IXGBE_VFTA_SIZE 128 #define IXGBE_BR_SIZE 4096 -#define CSUM_OFFLOAD 7 /* Bits in csum flags */ + +/* Offload bits in mbuf flag */ +#if __FreeBSD_version >= 800000 +#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP|CSUM_SCTP) +#else +#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP) +#endif /* For 6.X code compatibility */ #if !defined(ETHER_BPF_MTAP) @@ -229,6 +237,7 @@ struct ixgbe_tx_buf { struct ixgbe_rx_buf { struct mbuf *m_head; struct mbuf *m_pack; + struct mbuf *fmp; bus_dmamap_t map; }; @@ -246,21 +255,36 @@ struct ixgbe_dma_alloc { }; /* - * The transmit ring, one per tx queue +** Driver queue struct: this is the interrupt container +** for the associated tx and rx ring. +*/ +struct ix_queue { + struct adapter *adapter; + u32 msix; /* This queue's MSIX vector */ + u32 eims; /* This queue's EIMS bit */ + u32 eitr_setting; + struct resource *res; + void *tag; + struct tx_ring *txr; + struct rx_ring *rxr; + struct task que_task; + struct taskqueue *tq; + u64 irqs; +}; + +/* + * The transmit ring, one per queue */ struct tx_ring { struct adapter *adapter; struct mtx tx_mtx; u32 me; - u32 msix; - u32 watchdog_timer; + bool watchdog_check; + int watchdog_time; union ixgbe_adv_tx_desc *tx_base; - volatile u32 tx_hwb; struct ixgbe_dma_alloc txdma; - struct task tx_task; - struct taskqueue *tq; - u32 next_avail_tx_desc; - u32 next_tx_to_clean; + u32 next_avail_desc; + u32 next_to_clean; struct ixgbe_tx_buf *tx_buffers; volatile u16 tx_avail; u32 txd_cmd; @@ -269,14 +293,14 @@ struct tx_ring { #if __FreeBSD_version >= 800000 struct buf_ring *br; #endif - /* Interrupt resources */ - void *tag; - struct resource *res; - +#ifdef IXGBE_FDIR + u16 atr_sample; + u16 atr_count; +#endif + u32 bytes; /* used for AIM */ + u32 packets; /* Soft Stats */ - u32 no_tx_desc_avail; - u32 no_tx_desc_late; - u64 tx_irq; + u64 no_desc_avail; u64 total_packets; }; @@ -288,129 +312,125 @@ struct rx_ring { struct adapter *adapter; struct mtx rx_mtx; u32 me; - u32 msix; - u32 payload; - struct task rx_task; - struct taskqueue *tq; union ixgbe_adv_rx_desc *rx_base; struct ixgbe_dma_alloc rxdma; struct lro_ctrl lro; bool lro_enabled; bool hdr_split; - unsigned int last_cleaned; - unsigned int next_to_check; + bool hw_rsc; + bool discard; + u32 next_to_refresh; + u32 next_to_check; + char mtx_name[16]; struct ixgbe_rx_buf *rx_buffers; bus_dma_tag_t rxtag; bus_dmamap_t spare_map; - struct mbuf *fmp; - struct mbuf *lmp; - char mtx_name[16]; u32 bytes; /* Used for AIM calc */ - u32 eitr_setting; - - /* Interrupt resources */ - void *tag; - struct resource *res; + u32 packets; /* Soft stats */ u64 rx_irq; u64 rx_split_packets; u64 rx_packets; u64 rx_bytes; + u64 rx_discarded; + u64 rsc_num; +#ifdef IXGBE_FDIR + u64 flm; +#endif }; /* Our adapter structure */ struct adapter { - struct ifnet *ifp; - struct ixgbe_hw hw; + struct ifnet *ifp; + struct ixgbe_hw hw; struct ixgbe_osdep osdep; - struct device *dev; + struct device *dev; - struct resource *pci_mem; - struct resource *msix_mem; + struct resource *pci_mem; + struct resource *msix_mem; /* * Interrupt resources: this set is * either used for legacy, or for Link * when doing MSIX */ - void *tag; - struct resource *res; + void *tag; + struct resource *res; - struct ifmedia media; - struct callout timer; - int msix; - int if_flags; + struct ifmedia media; + struct callout timer; + int msix; + int if_flags; - struct mtx core_mtx; + struct mtx core_mtx; - eventhandler_tag vlan_attach; - eventhandler_tag vlan_detach; + eventhandler_tag vlan_attach; + eventhandler_tag vlan_detach; - u32 num_vlans; - u16 num_queues; + u16 num_vlans; + u16 num_queues; /* Info about the board itself */ - u32 part_num; - u32 optics; - bool link_active; - u16 max_frame_size; - u32 link_speed; - bool link_up; - u32 linkvec; - u32 tx_int_delay; - u32 tx_abs_int_delay; - u32 rx_int_delay; - u32 rx_abs_int_delay; + u32 optics; + bool link_active; + u16 max_frame_size; + u32 link_speed; + bool link_up; + u32 linkvec; /* Mbuf cluster size */ - u32 rx_mbuf_sz; + u32 rx_mbuf_sz; /* Support for pluggable optics */ - bool sfp_probe; - struct task link_task; /* Link tasklet */ - struct task mod_task; /* SFP tasklet */ - struct task msf_task; /* Multispeed Fiber tasklet */ + bool sfp_probe; + struct task link_task; /* Link tasklet */ + struct task mod_task; /* SFP tasklet */ + struct task msf_task; /* Multispeed Fiber */ +#ifdef IXGBE_FDIR + int fdir_reinit; + struct task fdir_task; +#endif struct taskqueue *tq; + /* + ** Queues: + ** This is the irq holder, it has + ** and RX/TX pair or rings associated + ** with it. + */ + struct ix_queue *queues; + /* * Transmit rings: * Allocated at run time, an array of rings. */ - struct tx_ring *tx_rings; - int num_tx_desc; + struct tx_ring *tx_rings; + int num_tx_desc; /* * Receive rings: * Allocated at run time, an array of rings. */ - struct rx_ring *rx_rings; - int num_rx_desc; - u64 rx_mask; - u32 rx_process_limit; - -#ifdef IXGBE_IEEE1588 - /* IEEE 1588 precision time support */ - struct cyclecounter cycles; - struct nettimer clock; - struct nettime_compare compare; - struct hwtstamp_ctrl hwtstamp; -#endif + struct rx_ring *rx_rings; + int num_rx_desc; + u64 que_mask; + u32 rx_process_limit; /* Misc stats maintained by the driver */ - unsigned long dropped_pkts; - unsigned long mbuf_defrag_failed; - unsigned long mbuf_header_failed; - unsigned long mbuf_packet_failed; - unsigned long no_tx_map_avail; - unsigned long no_tx_dma_setup; - unsigned long watchdog_events; - unsigned long tso_tx; - unsigned long link_irq; + unsigned long dropped_pkts; + unsigned long mbuf_defrag_failed; + unsigned long mbuf_header_failed; + unsigned long mbuf_packet_failed; + unsigned long no_tx_map_avail; + unsigned long no_tx_dma_setup; + unsigned long watchdog_events; + unsigned long tso_tx; + unsigned long link_irq; - struct ixgbe_hw_stats stats; + struct ixgbe_hw_stats stats; }; /* Precision Time Sync (IEEE 1588) defines */ @@ -423,12 +443,12 @@ struct adapter { #define IXGBE_CORE_LOCK_INIT(_sc, _name) \ mtx_init(&(_sc)->core_mtx, _name, "IXGBE Core Lock", MTX_DEF) #define IXGBE_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx) -#define IXGBE_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx) -#define IXGBE_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx) +#define IXGBE_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx) +#define IXGBE_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx) #define IXGBE_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx) -#define IXGBE_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) -#define IXGBE_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx) -#define IXGBE_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx) +#define IXGBE_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) +#define IXGBE_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx) +#define IXGBE_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx) #define IXGBE_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx) #define IXGBE_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) #define IXGBE_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx) @@ -444,8 +464,8 @@ ixgbe_is_sfp(struct ixgbe_hw *hw) case ixgbe_phy_sfp_ftl: case ixgbe_phy_sfp_intel: case ixgbe_phy_sfp_unknown: - case ixgbe_phy_tw_tyco: - case ixgbe_phy_tw_unknown: + case ixgbe_phy_sfp_passive_tyco: + case ixgbe_phy_sfp_passive_unknown: return TRUE; default: return FALSE; diff --git a/sys/dev/ixgbe/ixgbe_82598.c b/sys/dev/ixgbe/ixgbe_82598.c index fb711c621ad..0570aa5c588 100644 --- a/sys/dev/ixgbe/ixgbe_82598.c +++ b/sys/dev/ixgbe/ixgbe_82598.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -44,20 +44,22 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, bool *autoneg); static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw); s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num); -static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw); +static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete); static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete); -static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, +static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); -static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw); -static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, +static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); +s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw); +void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw); s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, @@ -70,7 +72,50 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw); s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw); void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw); +void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw); +static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw); +/** + * ixgbe_set_pcie_completion_timeout - set pci-e completion timeout + * @hw: pointer to the HW structure + * + * The defaults for 82598 should be in the range of 50us to 50ms, + * however the hardware default for these parts is 500us to 1ms which is less + * than the 10ms recommended by the pci-e spec. To address this we need to + * increase the value to either 10ms to 250ms for capability version 1 config, + * or 16ms to 55ms for version 2. + **/ +void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw) +{ + u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR); + u16 pcie_devctl2; + + /* only take action if timeout value is defaulted to 0 */ + if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK) + goto out; + + /* + * if capababilities version is type 1 we can write the + * timeout of 10ms to 250ms through the GCR register + */ + if (!(gcr & IXGBE_GCR_CAP_VER2)) { + gcr |= IXGBE_GCR_CMPL_TMOUT_10ms; + goto out; + } + + /* + * for version 2 capabilities we need to write the config space + * directly in order to set the completion timeout value for + * 16ms to 55ms + */ + pcie_devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2); + pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms; + IXGBE_WRITE_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2); +out: + /* disable completion timeout resend */ + gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND; + IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr); +} /** * ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count @@ -83,6 +128,8 @@ u32 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw) { u32 msix_count = 18; + DEBUGFUNC("ixgbe_get_pcie_msix_count_82598"); + if (hw->mac.msix_vectors_from_pcie) { msix_count = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCIE_MSIX_82598_CAPS); @@ -108,6 +155,8 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw) struct ixgbe_phy_info *phy = &hw->phy; s32 ret_val; + DEBUGFUNC("ixgbe_init_ops_82598"); + ret_val = ixgbe_init_phy_ops_generic(hw); ret_val = ixgbe_init_ops_generic(hw); @@ -115,6 +164,8 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw) phy->ops.init = &ixgbe_init_phy_ops_82598; /* MAC */ + mac->ops.start_hw = &ixgbe_start_hw_82598; + mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_82598; mac->ops.reset_hw = &ixgbe_reset_hw_82598; mac->ops.get_media_type = &ixgbe_get_media_type_82598; mac->ops.get_supported_physical_layer = @@ -145,7 +196,6 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw) /* Link */ mac->ops.check_link = &ixgbe_check_mac_link_82598; mac->ops.setup_link = &ixgbe_setup_mac_link_82598; - mac->ops.setup_link_speed = &ixgbe_setup_mac_link_speed_82598; mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82598; @@ -168,6 +218,7 @@ s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) s32 ret_val = IXGBE_SUCCESS; u16 list_offset, data_offset; + DEBUGFUNC("ixgbe_init_phy_ops_82598"); /* Identify the PHY */ phy->ops.identify(hw); @@ -175,21 +226,20 @@ s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) /* Overwrite the link function pointers if copper PHY */ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { mac->ops.setup_link = &ixgbe_setup_copper_link_82598; - mac->ops.setup_link_speed = - &ixgbe_setup_copper_link_speed_82598; mac->ops.get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic; } switch (hw->phy.type) { case ixgbe_phy_tn: + phy->ops.setup_link = &ixgbe_setup_phy_link_tnx; phy->ops.check_link = &ixgbe_check_phy_link_tnx; phy->ops.get_firmware_version = &ixgbe_get_phy_firmware_version_tnx; break; case ixgbe_phy_aq: phy->ops.get_firmware_version = - &ixgbe_get_phy_firmware_version_aq; + &ixgbe_get_phy_firmware_version_generic; break; case ixgbe_phy_nl: phy->ops.reset = &ixgbe_reset_phy_nl; @@ -220,6 +270,47 @@ out: return ret_val; } +/** + * ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx + * @hw: pointer to hardware structure + * + * Starts the hardware using the generic start_hw function. + * Disables relaxed ordering Then set pcie completion timeout + * + **/ +s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) +{ + u32 regval; + u32 i; + s32 ret_val = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_start_hw_82598"); + + ret_val = ixgbe_start_hw_generic(hw); + + /* Disable relaxed ordering */ + for (i = 0; ((i < hw->mac.max_tx_queues) && + (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); + regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval); + } + + for (i = 0; ((i < hw->mac.max_rx_queues) && + (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); + regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); + } + + /* set the completion timeout for interface */ + if (ret_val == IXGBE_SUCCESS) + ixgbe_set_pcie_completion_timeout(hw); + + return ret_val; +} + /** * ixgbe_get_link_capabilities_82598 - Determines link capabilities * @hw: pointer to hardware structure @@ -235,6 +326,8 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, s32 status = IXGBE_SUCCESS; u32 autoc = 0; + DEBUGFUNC("ixgbe_get_link_capabilities_82598"); + /* * Determine link capabilities based on the stored value of AUTOC, * which represents EEPROM defaults. If AUTOC value has not been @@ -289,6 +382,8 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) { enum ixgbe_media_type media_type; + DEBUGFUNC("ixgbe_get_media_type_82598"); + /* Detect if there is a copper PHY attached. */ if (hw->phy.type == ixgbe_phy_cu_unknown || hw->phy.type == ixgbe_phy_tn || @@ -306,15 +401,18 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) break; case IXGBE_DEV_ID_82598AF_DUAL_PORT: case IXGBE_DEV_ID_82598AF_SINGLE_PORT: - case IXGBE_DEV_ID_82598EB_CX4: - case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: case IXGBE_DEV_ID_82598_DA_DUAL_PORT: case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: case IXGBE_DEV_ID_82598EB_XF_LR: case IXGBE_DEV_ID_82598EB_SFP_LOM: media_type = ixgbe_media_type_fiber; break; + case IXGBE_DEV_ID_82598EB_CX4: + case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: + media_type = ixgbe_media_type_cx4; + break; case IXGBE_DEV_ID_82598AT: + case IXGBE_DEV_ID_82598AT2: media_type = ixgbe_media_type_copper; break; default: @@ -338,9 +436,31 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) u32 fctrl_reg; u32 rmcs_reg; u32 reg; + u32 link_speed = 0; + bool link_up; DEBUGFUNC("ixgbe_fc_enable_82598"); + /* + * On 82598 having Rx FC on causes resets while doing 1G + * so if it's on turn it off once we know link_speed. For + * more details see 82598 Specification update. + */ + hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE); + if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) { + switch (hw->fc.requested_mode) { + case ixgbe_fc_full: + hw->fc.requested_mode = ixgbe_fc_tx_pause; + break; + case ixgbe_fc_rx_pause: + hw->fc.requested_mode = ixgbe_fc_none; + break; + default: + /* no change */ + break; + } + } + /* Negotiate the fc mode to use */ ret_val = ixgbe_fc_autoneg(hw); if (ret_val) @@ -394,7 +514,7 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) break; default: DEBUGOUT("Flow control param set incorrectly\n"); - ret_val = -IXGBE_ERR_CONFIG; + ret_val = IXGBE_ERR_CONFIG; goto out; break; } @@ -433,26 +553,29 @@ out: } /** - * ixgbe_setup_mac_link_82598 - Configures MAC link settings + * ixgbe_start_mac_link_82598 - Configures MAC link settings * @hw: pointer to hardware structure * * Configures link settings based on values in the ixgbe_hw struct. * Restarts the link. Performs autonegotiation if needed. **/ -static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) +static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete) { u32 autoc_reg; u32 links_reg; u32 i; s32 status = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_start_mac_link_82598"); + /* Restart link */ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); autoc_reg |= IXGBE_AUTOC_AN_RESTART; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); /* Only poll for autoneg to complete if specified to do so */ - if (hw->phy.autoneg_wait_to_complete) { + if (autoneg_wait_to_complete) { if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == IXGBE_AUTOC_LMS_KX4_AN || (autoc_reg & IXGBE_AUTOC_LMS_MASK) == @@ -494,6 +617,8 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 i; u16 link_reg, adapt_comp_reg; + DEBUGFUNC("ixgbe_check_mac_link_82598"); + /* * SERDES PHY requires us to read link status from undocumented * register 0xC79F. Bit 0 set indicates link is up/ready; clear @@ -558,17 +683,22 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, else *speed = IXGBE_LINK_SPEED_1GB_FULL; + if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == TRUE) && + (ixgbe_validate_link_ready(hw) != IXGBE_SUCCESS)) + *link_up = FALSE; + /* if link is down, zero out the current_mode */ if (*link_up == FALSE) { hw->fc.current_mode = ixgbe_fc_none; hw->fc.fc_was_autonegged = FALSE; } + out: return IXGBE_SUCCESS; } /** - * ixgbe_setup_mac_link_speed_82598 - Set MAC link speed + * ixgbe_setup_mac_link_82598 - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed * @autoneg: TRUE if autonegotiation enabled @@ -576,7 +706,7 @@ out: * * Set the link speed in the AUTOC register and restarts link. **/ -static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, +static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { @@ -586,6 +716,8 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 autoc = curr_autoc; u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK; + DEBUGFUNC("ixgbe_setup_mac_link_82598"); + /* Check to see if speed passed in is supported. */ ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg); speed &= link_capabilities; @@ -606,14 +738,13 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, } if (status == IXGBE_SUCCESS) { - hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete; - /* * Setup and restart the link based on the new values in * ixgbe_hw This will write the AUTOC register based on the new * stored values */ - status = ixgbe_setup_mac_link_82598(hw); + status = ixgbe_start_mac_link_82598(hw, + autoneg_wait_to_complete); } return status; @@ -621,29 +752,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, /** - * ixgbe_setup_copper_link_82598 - Setup copper link settings - * @hw: pointer to hardware structure - * - * Configures link settings based on values in the ixgbe_hw struct. - * Restarts the link. Performs autonegotiation if needed. Restart - * phy and wait for autonegotiate to finish. Then synchronize the - * MAC and PHY. - **/ -static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw) -{ - s32 status; - - /* Restart autonegotiation on PHY */ - status = hw->phy.ops.setup_link(hw); - - /* Set up MAC */ - ixgbe_setup_mac_link_82598(hw); - - return status; -} - -/** - * ixgbe_setup_copper_link_speed_82598 - Set the PHY autoneg advertised field + * ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field * @hw: pointer to hardware structure * @speed: new link speed * @autoneg: TRUE if autonegotiation enabled @@ -651,18 +760,20 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw) * * Sets the link speed in the AUTOC register in the MAC and restarts link. **/ -static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, +static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { s32 status; + DEBUGFUNC("ixgbe_setup_copper_link_82598"); + /* Setup the PHY according to input speed */ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, autoneg_wait_to_complete); /* Set up MAC */ - ixgbe_setup_mac_link_82598(hw); + ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete); return status; } @@ -685,6 +796,8 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) u32 autoc; u8 analog_val; + DEBUGFUNC("ixgbe_reset_hw_82598"); + /* Call adapter stop to disable tx/rx and clear interrupts */ hw->mac.ops.stop_adapter(hw); @@ -740,12 +853,9 @@ no_phy_reset: * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset */ - status = ixgbe_disable_pcie_master(hw); - if (status != IXGBE_SUCCESS) { - status = IXGBE_ERR_MASTER_REQUESTS_PENDING; - DEBUGOUT("PCI-E Master disable polling has failed.\n"); - } + ixgbe_disable_pcie_master(hw); +mac_reset_top: /* * Issue global reset to the MAC. This needs to be a SW reset. * If link reset is used, it might reset the MAC when mng is using it @@ -766,6 +876,19 @@ no_phy_reset: DEBUGOUT("Reset polling failed to complete.\n"); } + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to allow time + * for any pending HW events to complete. We use 1usec since that is + * what is needed for ixgbe_disable_pcie_master(). The second reset + * then clears out any effects of those events. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + usec_delay(1); + goto mac_reset_top; + } + msec_delay(50); gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR); @@ -811,6 +934,8 @@ s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) { u32 rar_high; + DEBUGFUNC("ixgbe_set_vmdq_82598"); + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); rar_high &= ~IXGBE_RAH_VIND_MASK; rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK); @@ -861,6 +986,8 @@ s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, u32 bits; u32 vftabyte; + DEBUGFUNC("ixgbe_set_vfta_82598"); + if (vlan > 4095) return IXGBE_ERR_PARAM; @@ -903,6 +1030,8 @@ static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw) u32 offset; u32 vlanbyte; + DEBUGFUNC("ixgbe_clear_vfta_82598"); + for (offset = 0; offset < hw->mac.vft_size; offset++) IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); @@ -926,6 +1055,8 @@ s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val) { u32 atlas_ctl; + DEBUGFUNC("ixgbe_read_analog_reg8_82598"); + IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, IXGBE_ATLASCTL_WRITE_CMD | (reg << 8)); IXGBE_WRITE_FLUSH(hw); @@ -948,6 +1079,8 @@ s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val) { u32 atlas_ctl; + DEBUGFUNC("ixgbe_write_analog_reg8_82598"); + atlas_ctl = (reg << 8) | val; IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl); IXGBE_WRITE_FLUSH(hw); @@ -973,6 +1106,8 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, u16 sfp_stat = 0; u32 i; + DEBUGFUNC("ixgbe_read_i2c_eeprom_82598"); + if (hw->phy.type == ixgbe_phy_nl) { /* * NetLogic phy SDA/SCL registers are at addresses 0xC30A to @@ -1032,6 +1167,8 @@ u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; u16 ext_ability = 0; + DEBUGFUNC("ixgbe_get_supported_physical_layer_82598"); + hw->phy.ops.identify(hw); /* Copper PHY must be checked before AUTOC LMS to determine correct @@ -1128,6 +1265,8 @@ void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw) struct ixgbe_bus_info *bus = &hw->bus; u16 pci_gen, pci_ctrl2; + DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie_82598"); + ixgbe_set_lan_id_multi_port_pcie(hw); /* check if LAN0 is disabled */ @@ -1146,4 +1285,67 @@ void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw) } } +/** + * ixgbe_validate_link_ready - Function looks for phy link + * @hw: pointer to hardware structure + * + * Function indicates success when phy link is available. If phy is not ready + * within 5 seconds of MAC indicating link, the function returns error. + **/ +static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw) +{ + u32 timeout; + u16 an_reg; + if (hw->device_id != IXGBE_DEV_ID_82598AT2) + return IXGBE_SUCCESS; + + for (timeout = 0; + timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) { + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg); + + if ((an_reg & IXGBE_MII_AUTONEG_COMPLETE) && + (an_reg & IXGBE_MII_AUTONEG_LINK_UP)) + break; + + msec_delay(100); + } + + if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) { + DEBUGOUT("Link was indicated but link is down\n"); + return IXGBE_ERR_LINK_SETUP; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_enable_relaxed_ordering_82598 - enable relaxed ordering + * @hw: pointer to hardware structure + * + **/ +void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw) +{ + u32 regval; + u32 i; + + DEBUGFUNC("ixgbe_enable_relaxed_ordering_82598"); + + /* Enable relaxed ordering */ + for (i = 0; ((i < hw->mac.max_tx_queues) && + (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); + regval |= IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval); + } + + for (i = 0; ((i < hw->mac.max_rx_queues) && + (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); + regval |= (IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); + } + +} diff --git a/sys/dev/ixgbe/ixgbe_82599.c b/sys/dev/ixgbe/ixgbe_82599.c index c3d23afde55..8c5ff21200d 100644 --- a/sys/dev/ixgbe/ixgbe_82599.c +++ b/sys/dev/ixgbe/ixgbe_82599.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -37,54 +37,41 @@ #include "ixgbe_common.h" #include "ixgbe_phy.h" -u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw); s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw); s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *autoneg); enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw); -s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw); -s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, +s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); -s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw); -s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *link_up, bool link_up_wait_to_complete); -s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, +s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, + ixgbe_link_speed speed, bool autoneg, + bool autoneg_wait_to_complete); +s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete); +s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); -static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw); -static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw, +static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw); void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw); s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw); -s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq); -s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq); -s32 ixgbe_insert_mac_addr_82599(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); -s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, - u32 vind, bool vlan_on); -s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw); -s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw); s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val); s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val); s32 ixgbe_start_hw_rev_1_82599(struct ixgbe_hw *hw); +void ixgbe_enable_relaxed_ordering_82599(struct ixgbe_hw *hw); s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw); s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw); u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw); s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval); -s32 ixgbe_get_san_mac_addr_offset_82599(struct ixgbe_hw *hw, - u16 *san_mac_offset); -s32 ixgbe_get_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr); -s32 ixgbe_set_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr); s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps); static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); - void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) { struct ixgbe_mac_info *mac = &hw->mac; @@ -93,15 +80,14 @@ void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) if (hw->phy.multispeed_fiber) { /* Set up dual speed SFP+ support */ - mac->ops.setup_link = - &ixgbe_setup_mac_link_multispeed_fiber; - mac->ops.setup_link_speed = - &ixgbe_setup_mac_link_speed_multispeed_fiber; + mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; } else { - mac->ops.setup_link = - &ixgbe_setup_mac_link_82599; - mac->ops.setup_link_speed = - &ixgbe_setup_mac_link_speed_82599; + if ((ixgbe_get_media_type(hw) == ixgbe_media_type_backplane) && + (hw->phy.smart_speed == ixgbe_smart_speed_auto || + hw->phy.smart_speed == ixgbe_smart_speed_on)) + mac->ops.setup_link = &ixgbe_setup_mac_link_smartspeed; + else + mac->ops.setup_link = &ixgbe_setup_mac_link_82599; } } @@ -135,8 +121,6 @@ s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) /* If copper media, overwrite with copper function pointers */ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { mac->ops.setup_link = &ixgbe_setup_copper_link_82599; - mac->ops.setup_link_speed = - &ixgbe_setup_copper_link_speed_82599; mac->ops.get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic; } @@ -144,13 +128,14 @@ s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) /* Set necessary function pointers based on phy type */ switch (hw->phy.type) { case ixgbe_phy_tn: + phy->ops.setup_link = &ixgbe_setup_phy_link_tnx; phy->ops.check_link = &ixgbe_check_phy_link_tnx; phy->ops.get_firmware_version = &ixgbe_get_phy_firmware_version_tnx; break; case ixgbe_phy_aq: phy->ops.get_firmware_version = - &ixgbe_get_phy_firmware_version_aq; + &ixgbe_get_phy_firmware_version_generic; break; default: break; @@ -203,30 +188,6 @@ setup_sfp_out: return ret_val; } -/** - * ixgbe_get_pcie_msix_count_82599 - Gets MSI-X vector count - * @hw: pointer to hardware structure - * - * Read PCIe configuration space, and get the MSI-X vector count from - * the capabilities table. - **/ -u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw) -{ - u32 msix_count = 64; - - if (hw->mac.msix_vectors_from_pcie) { - msix_count = IXGBE_READ_PCIE_WORD(hw, - IXGBE_PCIE_MSIX_82599_CAPS); - msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; - - /* MSI-X count is zero-based in HW, so increment to give - * proper value */ - msix_count++; - } - - return msix_count; -} - /** * ixgbe_init_ops_82599 - Inits func ptrs and MAC type * @hw: pointer to hardware structure @@ -241,6 +202,8 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) struct ixgbe_phy_info *phy = &hw->phy; s32 ret_val; + DEBUGFUNC("ixgbe_init_ops_82599"); + ret_val = ixgbe_init_phy_ops_generic(hw); ret_val = ixgbe_init_ops_generic(hw); @@ -257,23 +220,24 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82599; mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82599; mac->ops.start_hw = &ixgbe_start_hw_rev_1_82599; - mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_82599; - mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_82599; + mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic; + mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_generic; mac->ops.get_device_caps = &ixgbe_get_device_caps_82599; + mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic; /* RAR, Multicast, VLAN */ - mac->ops.set_vmdq = &ixgbe_set_vmdq_82599; - mac->ops.clear_vmdq = &ixgbe_clear_vmdq_82599; - mac->ops.insert_mac_addr = &ixgbe_insert_mac_addr_82599; + mac->ops.set_vmdq = &ixgbe_set_vmdq_generic; + mac->ops.clear_vmdq = &ixgbe_clear_vmdq_generic; + mac->ops.insert_mac_addr = &ixgbe_insert_mac_addr_generic; mac->rar_highwater = 1; - mac->ops.set_vfta = &ixgbe_set_vfta_82599; - mac->ops.clear_vfta = &ixgbe_clear_vfta_82599; - mac->ops.init_uta_tables = &ixgbe_init_uta_tables_82599; + mac->ops.set_vfta = &ixgbe_set_vfta_generic; + mac->ops.clear_vfta = &ixgbe_clear_vfta_generic; + mac->ops.init_uta_tables = &ixgbe_init_uta_tables_generic; mac->ops.setup_sfp = &ixgbe_setup_sfp_modules_82599; /* Link */ mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82599; - mac->ops.check_link = &ixgbe_check_mac_link_82599; + mac->ops.check_link = &ixgbe_check_mac_link_generic; ixgbe_init_mac_link_ops_82599(hw); mac->mcft_size = 128; @@ -281,7 +245,7 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) mac->num_rar_entries = 128; mac->max_tx_queues = 128; mac->max_rx_queues = 128; - mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw); + mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); return ret_val; @@ -302,6 +266,10 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, s32 status = IXGBE_SUCCESS; u32 autoc = 0; + DEBUGFUNC("ixgbe_get_link_capabilities_82599"); + + + /* * Determine link capabilities based on the stored value of AUTOC, * which represents EEPROM defaults. If AUTOC value has not @@ -387,6 +355,8 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) { enum ixgbe_media_type media_type; + DEBUGFUNC("ixgbe_get_media_type_82599"); + /* Detect if there is a copper PHY attached. */ if (hw->phy.type == ixgbe_phy_cu_unknown || hw->phy.type == ixgbe_phy_tn || @@ -397,6 +367,8 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) switch (hw->device_id) { case IXGBE_DEV_ID_82599_KX4: + case IXGBE_DEV_ID_82599_KX4_MEZZ: + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: case IXGBE_DEV_ID_82599_XAUI_LOM: /* Default device ID is mezzanine card KX/KX4 */ media_type = ixgbe_media_type_backplane; @@ -405,7 +377,7 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) media_type = ixgbe_media_type_fiber; break; case IXGBE_DEV_ID_82599_CX4: - media_type = ixgbe_media_type_fiber; + media_type = ixgbe_media_type_cx4; break; default: media_type = ixgbe_media_type_unknown; @@ -416,19 +388,22 @@ out: } /** - * ixgbe_setup_mac_link_82599 - Setup MAC link settings + * ixgbe_start_mac_link_82599 - Setup MAC link settings * @hw: pointer to hardware structure * * Configures link settings based on values in the ixgbe_hw struct. * Restarts the link. Performs autonegotiation if needed. **/ -s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw) +s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete) { u32 autoc_reg; u32 links_reg; u32 i; s32 status = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_start_mac_link_82599"); + /* Restart link */ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); @@ -436,7 +411,7 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); /* Only poll for autoneg to complete if specified to do so */ - if (hw->phy.autoneg_wait_to_complete) { + if (autoneg_wait_to_complete) { if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == IXGBE_AUTOC_LMS_KX4_KX_KR || (autoc_reg & IXGBE_AUTOC_LMS_MASK) == @@ -464,27 +439,7 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw) } /** - * ixgbe_setup_mac_link_multispeed_fiber - Setup MAC link settings - * @hw: pointer to hardware structure - * - * Configures link settings based on values in the ixgbe_hw struct. - * Restarts the link for multi-speed fiber at 1G speed, if link - * fails at 10G. - * Performs autonegotiation if needed. - **/ -s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw) -{ - s32 status = IXGBE_SUCCESS; - ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_82599_AUTONEG; - DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber"); - - status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw, - link_speed, TRUE, true); - return status; -} - -/** - * ixgbe_setup_mac_link_speed_multispeed_fiber - Set MAC link speed + * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed * @autoneg: TRUE if autonegotiation enabled @@ -492,7 +447,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw) * * Set the link speed in the AUTOC register and restarts link. **/ -s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, +s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { @@ -505,22 +460,15 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, bool link_up = FALSE; bool negotiation; + DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber"); + /* Mask off requested but non-supported speeds */ status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation); if (status != IXGBE_SUCCESS) - goto out; + return status; speed &= link_speed; - /* Set autoneg_advertised value based on input link speed */ - hw->phy.autoneg_advertised = 0; - - if (speed & IXGBE_LINK_SPEED_10GB_FULL) - hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; - - if (speed & IXGBE_LINK_SPEED_1GB_FULL) - hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; - /* * When the driver changes the link speeds that it can support, * it sets autotry_restart to TRUE to indicate that we need to @@ -542,7 +490,7 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, /* If we already have link at this speed, just jump out */ status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE); if (status != IXGBE_SUCCESS) - goto out; + return status; if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up) goto out; @@ -554,11 +502,11 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, /* Allow module to change analog characteristics (1G->10G) */ msec_delay(40); - status = ixgbe_setup_mac_link_speed_82599( + status = ixgbe_setup_mac_link_82599( hw, IXGBE_LINK_SPEED_10GB_FULL, autoneg, autoneg_wait_to_complete); if (status != IXGBE_SUCCESS) - goto out; + return status; /* Flap the tx laser if it has not already been done */ if (hw->mac.autotry_restart) { @@ -575,7 +523,11 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, hw->mac.autotry_restart = FALSE; } - /* The controller may take up to 500ms at 10g to acquire link */ + /* + * Wait for the controller to acquire link. Per IEEE 802.3ap, + * Section 73.10.2, we may have to wait up to 500ms if KR is + * attempted. 82599 uses the same timing for 10g SFI. + */ for (i = 0; i < 5; i++) { /* Wait for the link partner to also set speed */ msec_delay(100); @@ -584,7 +536,7 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE); if (status != IXGBE_SUCCESS) - goto out; + return status; if (link_up) goto out; @@ -599,7 +551,7 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, /* If we already have link at this speed, just jump out */ status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE); if (status != IXGBE_SUCCESS) - goto out; + return status; if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up) goto out; @@ -612,11 +564,11 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, /* Allow module to change analog characteristics (10G->1G) */ msec_delay(40); - status = ixgbe_setup_mac_link_speed_82599( + status = ixgbe_setup_mac_link_82599( hw, IXGBE_LINK_SPEED_1GB_FULL, autoneg, autoneg_wait_to_complete); if (status != IXGBE_SUCCESS) - goto out; + return status; /* Flap the tx laser if it has not already been done */ if (hw->mac.autotry_restart) { @@ -639,7 +591,7 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, /* If we have link, just jump out */ status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE); if (status != IXGBE_SUCCESS) - goto out; + return status; if (link_up) goto out; @@ -651,67 +603,134 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, * single highest speed that the user requested. */ if (speedcnt > 1) - status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw, + status = ixgbe_setup_mac_link_multispeed_fiber(hw, highest_link_speed, autoneg, autoneg_wait_to_complete); +out: + /* Set autoneg_advertised value based on input link speed */ + hw->phy.autoneg_advertised = 0; + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; + + return status; +} + +/** + * ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg: TRUE if autonegotiation enabled + * @autoneg_wait_to_complete: TRUE when waiting for completion is needed + * + * Implements the Intel SmartSpeed algorithm. + **/ +s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, + ixgbe_link_speed speed, bool autoneg, + bool autoneg_wait_to_complete) +{ + s32 status = IXGBE_SUCCESS; + ixgbe_link_speed link_speed; + s32 i, j; + bool link_up = FALSE; + u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + + DEBUGFUNC("ixgbe_setup_mac_link_smartspeed"); + + /* Set autoneg_advertised value based on input link speed */ + hw->phy.autoneg_advertised = 0; + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; + + if (speed & IXGBE_LINK_SPEED_100_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL; + + /* + * Implement Intel SmartSpeed algorithm. SmartSpeed will reduce the + * autoneg advertisement if link is unable to be established at the + * highest negotiated rate. This can sometimes happen due to integrity + * issues with the physical media connection. + */ + + /* First, try to get link with full advertisement */ + hw->phy.smart_speed_active = FALSE; + for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) { + status = ixgbe_setup_mac_link_82599(hw, speed, autoneg, + autoneg_wait_to_complete); + if (status != IXGBE_SUCCESS) + goto out; + + /* + * Wait for the controller to acquire link. Per IEEE 802.3ap, + * Section 73.10.2, we may have to wait up to 500ms if KR is + * attempted, or 200ms if KX/KX4/BX/BX4 is attempted, per + * Table 9 in the AN MAS. + */ + for (i = 0; i < 5; i++) { + msec_delay(100); + + /* If we have link, just jump out */ + status = ixgbe_check_link(hw, &link_speed, &link_up, + FALSE); + if (status != IXGBE_SUCCESS) + goto out; + + if (link_up) + goto out; + } + } + + /* + * We didn't get link. If we advertised KR plus one of KX4/KX + * (or BX4/BX), then disable KR and try again. + */ + if (((autoc_reg & IXGBE_AUTOC_KR_SUPP) == 0) || + ((autoc_reg & IXGBE_AUTOC_KX4_KX_SUPP_MASK) == 0)) + goto out; + + /* Turn SmartSpeed on to disable KR support */ + hw->phy.smart_speed_active = TRUE; + status = ixgbe_setup_mac_link_82599(hw, speed, autoneg, + autoneg_wait_to_complete); + if (status != IXGBE_SUCCESS) + goto out; + + /* + * Wait for the controller to acquire link. 600ms will allow for + * the AN link_fail_inhibit_timer as well for multiple cycles of + * parallel detect, both 10g and 1g. This allows for the maximum + * connect attempts as defined in the AN MAS table 73-7. + */ + for (i = 0; i < 6; i++) { + msec_delay(100); + + /* If we have link, just jump out */ + status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE); + if (status != IXGBE_SUCCESS) + goto out; + + if (link_up) + goto out; + } + + /* We didn't get link. Turn SmartSpeed back off. */ + hw->phy.smart_speed_active = FALSE; + status = ixgbe_setup_mac_link_82599(hw, speed, autoneg, + autoneg_wait_to_complete); + out: return status; } /** - * ixgbe_check_mac_link_82599 - Determine link and speed status - * @hw: pointer to hardware structure - * @speed: pointer to link speed - * @link_up: TRUE when link is up - * @link_up_wait_to_complete: bool used to wait for link up or not - * - * Reads the links register to determine if link is up and the current speed - **/ -s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed, - bool *link_up, bool link_up_wait_to_complete) -{ - u32 links_reg; - u32 i; - - links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); - if (link_up_wait_to_complete) { - for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { - if (links_reg & IXGBE_LINKS_UP) { - *link_up = TRUE; - break; - } else { - *link_up = FALSE; - } - msec_delay(100); - links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); - } - } else { - if (links_reg & IXGBE_LINKS_UP) - *link_up = TRUE; - else - *link_up = FALSE; - } - - if ((links_reg & IXGBE_LINKS_SPEED_82599) == - IXGBE_LINKS_SPEED_10G_82599) - *speed = IXGBE_LINK_SPEED_10GB_FULL; - else if ((links_reg & IXGBE_LINKS_SPEED_82599) == - IXGBE_LINKS_SPEED_1G_82599) - *speed = IXGBE_LINK_SPEED_1GB_FULL; - else - *speed = IXGBE_LINK_SPEED_100_FULL; - - /* if link is down, zero out the current_mode */ - if (*link_up == FALSE) { - hw->fc.current_mode = ixgbe_fc_none; - hw->fc.fc_was_autonegged = FALSE; - } - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_setup_mac_link_speed_82599 - Set MAC link speed + * ixgbe_setup_mac_link_82599 - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed * @autoneg: TRUE if autonegotiation enabled @@ -719,7 +738,7 @@ s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed, * * Set the link speed in the AUTOC register and restarts link. **/ -s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, +s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { @@ -735,6 +754,8 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, u32 i; ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; + DEBUGFUNC("ixgbe_setup_mac_link_82599"); + /* Check to see if speed passed in is supported. */ status = ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg); if (status != IXGBE_SUCCESS) @@ -761,7 +782,8 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, if (speed & IXGBE_LINK_SPEED_10GB_FULL) if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) autoc |= IXGBE_AUTOC_KX4_SUPP; - if (orig_autoc & IXGBE_AUTOC_KR_SUPP) + if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) && + (hw->phy.smart_speed_active == FALSE)) autoc |= IXGBE_AUTOC_KR_SUPP; if (speed & IXGBE_LINK_SPEED_1GB_FULL) autoc |= IXGBE_AUTOC_KX_SUPP; @@ -823,26 +845,7 @@ out: } /** - * ixgbe_setup_copper_link_82599 - Setup copper link settings - * @hw: pointer to hardware structure - * - * Restarts the link on PHY and then MAC. Performs autonegotiation if needed. - **/ -static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw) -{ - s32 status; - - /* Restart autonegotiation on PHY */ - status = hw->phy.ops.setup_link(hw); - - /* Set up MAC */ - ixgbe_setup_mac_link_82599(hw); - - return status; -} - -/** - * ixgbe_setup_copper_link_speed_82599 - Set the PHY autoneg advertised field + * ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field * @hw: pointer to hardware structure * @speed: new link speed * @autoneg: TRUE if autonegotiation enabled @@ -850,18 +853,20 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw) * * Restarts link on PHY and MAC based on settings passed in. **/ -static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw, +static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { s32 status; + DEBUGFUNC("ixgbe_setup_copper_link_82599"); + /* Setup the PHY according to input speed */ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, autoneg_wait_to_complete); /* Set up MAC */ - ixgbe_setup_mac_link_82599(hw); + ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete); return status; } @@ -876,11 +881,13 @@ static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw, s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) { s32 status = IXGBE_SUCCESS; - u32 ctrl, ctrl_ext; + u32 ctrl; u32 i; u32 autoc; u32 autoc2; + DEBUGFUNC("ixgbe_reset_hw_82599"); + /* Call adapter stop to disable tx/rx and clear interrupts */ hw->mac.ops.stop_adapter(hw); @@ -892,7 +899,6 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) goto reset_hw_out; - /* Setup SFP module if there is one present. */ if (hw->phy.sfp_setup_needed) { status = hw->mac.ops.setup_sfp(hw); @@ -910,12 +916,9 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset */ - status = ixgbe_disable_pcie_master(hw); - if (status != IXGBE_SUCCESS) { - status = IXGBE_ERR_MASTER_REQUESTS_PENDING; - DEBUGOUT("PCI-E Master disable polling has failed.\n"); - } + ixgbe_disable_pcie_master(hw); +mac_reset_top: /* * Issue global reset to the MAC. This needs to be a SW reset. * If link reset is used, it might reset the MAC when mng is using it @@ -935,15 +938,22 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) status = IXGBE_ERR_RESET_FAILED; DEBUGOUT("Reset polling failed to complete.\n"); } - /* Clear PF Reset Done bit so PF/VF Mail Ops can work */ - ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); - ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; - IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to allow time + * for any pending HW events to complete. We use 1usec since that is + * what is needed for ixgbe_disable_pcie_master(). The second reset + * then clears out any effects of those events. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + usec_delay(1); + goto mac_reset_top; + } msec_delay(50); - - /* * Store the original AUTOC/AUTOC2 values if they have not been * stored off yet. Otherwise restore the stored original @@ -980,8 +990,6 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) hw->mac.num_rar_entries = 128; hw->mac.ops.init_rx_addrs(hw); - - /* Store the permanent SAN mac address */ hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); @@ -994,310 +1002,14 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) hw->mac.num_rar_entries--; } + /* Store the alternative WWNN/WWPN prefix */ + hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, + &hw->mac.wwpn_prefix); + reset_hw_out: return status; } -/** - * ixgbe_insert_mac_addr_82599 - Find a RAR for this mac address - * @hw: pointer to hardware structure - * @addr: Address to put into receive address register - * @vmdq: VMDq pool to assign - * - * Puts an ethernet address into a receive address register, or - * finds the rar that it is aleady in; adds to the pool list - **/ -s32 ixgbe_insert_mac_addr_82599(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) -{ - static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF; - u32 first_empty_rar = NO_EMPTY_RAR_FOUND; - u32 rar; - u32 rar_low, rar_high; - u32 addr_low, addr_high; - - /* swap bytes for HW little endian */ - addr_low = addr[0] | (addr[1] << 8) - | (addr[2] << 16) - | (addr[3] << 24); - addr_high = addr[4] | (addr[5] << 8); - - /* - * Either find the mac_id in rar or find the first empty space. - * rar_highwater points to just after the highest currently used - * rar in order to shorten the search. It grows when we add a new - * rar to the top. - */ - for (rar = 0; rar < hw->mac.rar_highwater; rar++) { - rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); - - if (((IXGBE_RAH_AV & rar_high) == 0) - && first_empty_rar == NO_EMPTY_RAR_FOUND) { - first_empty_rar = rar; - } else if ((rar_high & 0xFFFF) == addr_high) { - rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar)); - if (rar_low == addr_low) - break; /* found it already in the rars */ - } - } - - if (rar < hw->mac.rar_highwater) { - /* already there so just add to the pool bits */ - ixgbe_set_vmdq(hw, rar, vmdq); - } else if (first_empty_rar != NO_EMPTY_RAR_FOUND) { - /* stick it into first empty RAR slot we found */ - rar = first_empty_rar; - ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); - } else if (rar == hw->mac.rar_highwater) { - /* add it to the top of the list and inc the highwater mark */ - ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); - hw->mac.rar_highwater++; - } else if (rar >= hw->mac.num_rar_entries) { - return IXGBE_ERR_INVALID_MAC_ADDR; - } - - /* - * If we found rar[0], make sure the default pool bit (we use pool 0) - * remains cleared to be sure default pool packets will get delivered - */ - if (rar == 0) - ixgbe_clear_vmdq(hw, rar, 0); - - return rar; -} - -/** - * ixgbe_clear_vmdq_82599 - Disassociate a VMDq pool index from a rx address - * @hw: pointer to hardware struct - * @rar: receive address register index to disassociate - * @vmdq: VMDq pool index to remove from the rar - **/ -s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq) -{ - u32 mpsar_lo, mpsar_hi; - u32 rar_entries = hw->mac.num_rar_entries; - - if (rar < rar_entries) { - mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); - mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); - - if (!mpsar_lo && !mpsar_hi) - goto done; - - if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { - if (mpsar_lo) { - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); - mpsar_lo = 0; - } - if (mpsar_hi) { - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); - mpsar_hi = 0; - } - } else if (vmdq < 32) { - mpsar_lo &= ~(1 << vmdq); - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); - } else { - mpsar_hi &= ~(1 << (vmdq - 32)); - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); - } - - /* was that the last pool using this rar? */ - if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) - hw->mac.ops.clear_rar(hw, rar); - } else { - DEBUGOUT1("RAR index %d is out of range.\n", rar); - } - -done: - return IXGBE_SUCCESS; -} - -/** - * ixgbe_set_vmdq_82599 - Associate a VMDq pool index with a rx address - * @hw: pointer to hardware struct - * @rar: receive address register index to associate with a VMDq index - * @vmdq: VMDq pool index - **/ -s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq) -{ - u32 mpsar; - u32 rar_entries = hw->mac.num_rar_entries; - - if (rar < rar_entries) { - if (vmdq < 32) { - mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); - mpsar |= 1 << vmdq; - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar); - } else { - mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); - mpsar |= 1 << (vmdq - 32); - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar); - } - } else { - DEBUGOUT1("RAR index %d is out of range.\n", rar); - } - return IXGBE_SUCCESS; -} - -/** - * ixgbe_set_vfta_82599 - Set VLAN filter table - * @hw: pointer to hardware structure - * @vlan: VLAN id to write to VLAN filter - * @vind: VMDq output index that maps queue to VLAN id in VFVFB - * @vlan_on: boolean flag to turn on/off VLAN in VFVF - * - * Turn on/off specified VLAN in the VLAN filter table. - **/ -s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind, - bool vlan_on) -{ - u32 regindex; - u32 bitindex; - u32 bits; - u32 first_empty_slot; - u32 vt; - - if (vlan > 4095) - return IXGBE_ERR_PARAM; - - /* - * this is a 2 part operation - first the VFTA, then the - * VLVF and VLVFB if VT Mode is set - */ - - /* Part 1 - * The VFTA is a bitstring made up of 128 32-bit registers - * that enable the particular VLAN id, much like the MTA: - * bits[11-5]: which register - * bits[4-0]: which bit in the register - */ - regindex = (vlan >> 5) & 0x7F; - bitindex = vlan & 0x1F; - bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); - if (vlan_on) - bits |= (1 << bitindex); - else - bits &= ~(1 << bitindex); - IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits); - - - /* Part 2 - * If VT Mode is set - * Either vlan_on - * make sure the vlan is in VLVF - * set the vind bit in the matching VLVFB - * Or !vlan_on - * clear the pool bit and possibly the vind - */ - vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL); - if (vt & IXGBE_VT_CTL_VT_ENABLE) { - /* find the vlanid or the first empty slot */ - first_empty_slot = 0; - - for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { - bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); - if (!bits && !first_empty_slot) - first_empty_slot = regindex; - else if ((bits & 0x0FFF) == vlan) - break; - } - - if (regindex >= IXGBE_VLVF_ENTRIES) { - if (first_empty_slot) - regindex = first_empty_slot; - else { - DEBUGOUT("No space in VLVF.\n"); - goto out; - } - } - - - if (vlan_on) { - /* set the pool bit */ - if (vind < 32) { - bits = IXGBE_READ_REG(hw, - IXGBE_VLVFB(regindex*2)); - bits |= (1 << vind); - IXGBE_WRITE_REG(hw, - IXGBE_VLVFB(regindex*2), - bits); - } else { - bits = IXGBE_READ_REG(hw, - IXGBE_VLVFB((regindex*2)+1)); - bits |= (1 << vind); - IXGBE_WRITE_REG(hw, - IXGBE_VLVFB((regindex*2)+1), - bits); - } - } else { - /* clear the pool bit */ - if (vind < 32) { - bits = IXGBE_READ_REG(hw, - IXGBE_VLVFB(regindex*2)); - bits &= ~(1 << vind); - IXGBE_WRITE_REG(hw, - IXGBE_VLVFB(regindex*2), - bits); - bits |= IXGBE_READ_REG(hw, - IXGBE_VLVFB((regindex*2)+1)); - } else { - bits = IXGBE_READ_REG(hw, - IXGBE_VLVFB((regindex*2)+1)); - bits &= ~(1 << vind); - IXGBE_WRITE_REG(hw, - IXGBE_VLVFB((regindex*2)+1), - bits); - bits |= IXGBE_READ_REG(hw, - IXGBE_VLVFB(regindex*2)); - } - } - - if (bits) - IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), - (IXGBE_VLVF_VIEN | vlan)); - else - IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0); - } -out: - return IXGBE_SUCCESS; -} - -/** - * ixgbe_clear_vfta_82599 - Clear VLAN filter table - * @hw: pointer to hardware structure - * - * Clears the VLAN filer table, and the VMDq index associated with the filter - **/ -s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw) -{ - u32 offset; - - for (offset = 0; offset < hw->mac.vft_size; offset++) - IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); - - for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { - IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); - IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0); - IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0); - } - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array - * @hw: pointer to hardware structure - **/ -s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw) -{ - int i; - DEBUGOUT(" Clearing UTA\n"); - - for (i = 0; i < 128; i++) - IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0); - - return IXGBE_SUCCESS; -} - /** * ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables. * @hw: pointer to hardware structure @@ -1308,6 +1020,8 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw) u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL); fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE; + DEBUGFUNC("ixgbe_reinit_fdir_tables_82599"); + /* * Before starting reinitialization process, * FDIRCMD.CMD must be zero. @@ -1384,6 +1098,8 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) u32 pbsize; int i; + DEBUGFUNC("ixgbe_init_fdir_signature_82599"); + /* * Before enabling Flow Director, the Rx Packet Buffer size * must be reduced. The new value is the current size minus @@ -1474,6 +1190,8 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) u32 pbsize; int i; + DEBUGFUNC("ixgbe_init_fdir_perfect_82599"); + /* * Before enabling Flow Director, the Rx Packet Buffer size * must be reduced. The new value is the current size minus @@ -1496,6 +1214,9 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) /* Send interrupt when 64 filters are left */ fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; + /* Initialize the drop queue to Rx queue 127 */ + fdirctrl |= (127 << IXGBE_FDIRCTRL_DROP_Q_SHIFT); + switch (pballoc) { case IXGBE_FDIR_PBALLOC_64K: /* 2k - 1 perfect filters */ @@ -1609,6 +1330,8 @@ u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input, u32 key) u16 hash_result = 0; int i, j, k, h; + DEBUGFUNC("ixgbe_atr_compute_hash_82599"); + /* * Initialize the fill member to prevent warnings * on some compilers @@ -1687,6 +1410,8 @@ u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input, u32 key) **/ s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan) { + DEBUGFUNC("ixgbe_atr_set_vlan_id_82599"); + input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] = vlan >> 8; input->byte_stream[IXGBE_ATR_VLAN_OFFSET] = vlan & 0xff; @@ -1700,6 +1425,8 @@ s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan) **/ s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr) { + DEBUGFUNC("ixgbe_atr_set_src_ipv4_82599"); + input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] = src_addr >> 24; input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] = (src_addr >> 16) & 0xff; @@ -1717,6 +1444,8 @@ s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr) **/ s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr) { + DEBUGFUNC("ixgbe_atr_set_dst_ipv4_82599"); + input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] = dst_addr >> 24; input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] = (dst_addr >> 16) & 0xff; @@ -1739,6 +1468,8 @@ s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, u32 src_addr_1, u32 src_addr_2, u32 src_addr_3, u32 src_addr_4) { + DEBUGFUNC("ixgbe_atr_set_src_ipv6_82599"); + input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff; input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] = (src_addr_4 >> 8) & 0xff; @@ -1782,6 +1513,8 @@ s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, u32 dst_addr_1, u32 dst_addr_2, u32 dst_addr_3, u32 dst_addr_4) { + DEBUGFUNC("ixgbe_atr_set_dst_ipv6_82599"); + input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff; input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] = (dst_addr_4 >> 8) & 0xff; @@ -1820,6 +1553,8 @@ s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, **/ s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port) { + DEBUGFUNC("ixgbe_atr_set_src_port_82599"); + input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1] = src_port >> 8; input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] = src_port & 0xff; @@ -1833,6 +1568,8 @@ s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port) **/ s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port) { + DEBUGFUNC("ixgbe_atr_set_dst_port_82599"); + input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1] = dst_port >> 8; input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] = dst_port & 0xff; @@ -1846,6 +1583,8 @@ s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port) **/ s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte) { + DEBUGFUNC("ixgbe_atr_set_flex_byte_82599"); + input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] = flex_byte >> 8; input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET] = flex_byte & 0xff; @@ -1859,6 +1598,8 @@ s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte) **/ s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool) { + DEBUGFUNC("ixgbe_atr_set_vm_pool_82599"); + input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool; return IXGBE_SUCCESS; @@ -1871,6 +1612,8 @@ s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool) **/ s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type) { + DEBUGFUNC("ixgbe_atr_set_l4type_82599"); + input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET] = l4type; return IXGBE_SUCCESS; @@ -1883,6 +1626,8 @@ s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type) **/ s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan) { + DEBUGFUNC("ixgbe_atr_get_vlan_id_82599"); + *vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET]; *vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8; @@ -1896,6 +1641,8 @@ s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan) **/ s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr) { + DEBUGFUNC("ixgbe_atr_get_src_ipv4_82599"); + *src_addr = input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET]; *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] << 8; *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] << 16; @@ -1911,6 +1658,8 @@ s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr) **/ s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr) { + DEBUGFUNC("ixgbe_atr_get_dst_ipv4_82599"); + *dst_addr = input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET]; *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] << 8; *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] << 16; @@ -1931,6 +1680,8 @@ s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, u32 *src_addr_1, u32 *src_addr_2, u32 *src_addr_3, u32 *src_addr_4) { + DEBUGFUNC("ixgbe_atr_get_src_ipv6_82599"); + *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12]; *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] << 8; *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] << 16; @@ -1966,6 +1717,8 @@ s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, u32 *dst_addr_1, u32 *dst_addr_2, u32 *dst_addr_3, u32 *dst_addr_4) { + DEBUGFUNC("ixgbe_atr_get_dst_ipv6_82599"); + *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12]; *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8; *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] << 16; @@ -2001,6 +1754,8 @@ s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, **/ s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port) { + DEBUGFUNC("ixgbe_atr_get_src_port_82599"); + *src_port = input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] << 8; *src_port |= input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1]; @@ -2019,6 +1774,8 @@ s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port) **/ s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port) { + DEBUGFUNC("ixgbe_atr_get_dst_port_82599"); + *dst_port = input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] << 8; *dst_port |= input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1]; @@ -2032,6 +1789,8 @@ s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port) **/ s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, u16 *flex_byte) { + DEBUGFUNC("ixgbe_atr_get_flex_byte_82599"); + *flex_byte = input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET]; *flex_byte |= input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] << 8; @@ -2045,6 +1804,8 @@ s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, u16 *flex_byte) **/ s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool) { + DEBUGFUNC("ixgbe_atr_get_vm_pool_82599"); + *vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET]; return IXGBE_SUCCESS; @@ -2057,6 +1818,8 @@ s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool) **/ s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type) { + DEBUGFUNC("ixgbe_atr_get_l4type__82599"); + *l4type = input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET]; return IXGBE_SUCCESS; @@ -2078,6 +1841,8 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, u16 bucket_hash, sig_hash; u8 l4type; + DEBUGFUNC("ixgbe_fdir_add_signature_filter_82599"); + bucket_hash = ixgbe_atr_compute_hash_82599(input, IXGBE_ATR_BUCKET_HASH_KEY); @@ -2131,23 +1896,28 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter * @hw: pointer to hardware structure * @input: input bitstream + * @input_masks: masks for the input bitstream + * @soft_id: software index for the filters * @queue: queue index to direct traffic to * * Note that the caller to this function must lock before calling, since the * hardware writes must be protected from one another. **/ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, - struct ixgbe_atr_input *input, - u16 soft_id, - u8 queue) + struct ixgbe_atr_input *input, + struct ixgbe_atr_input_masks *input_masks, + u16 soft_id, u8 queue) { u32 fdircmd = 0; u32 fdirhash; - u32 src_ipv4, dst_ipv4; + u32 src_ipv4 = 0, dst_ipv4 = 0; u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4; u16 src_port, dst_port, vlan_id, flex_bytes; u16 bucket_hash; u8 l4type; + u8 fdirm = 0; + + DEBUGFUNC("ixgbe_fdir_add_perfect_filter_82599"); /* Get our input values */ ixgbe_atr_get_l4type_82599(input, &l4type); @@ -2202,7 +1972,6 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, /* IPv4 */ ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4); IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4); - } ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4); @@ -2211,7 +1980,78 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id | (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT))); IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port | - (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); + (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); + + /* + * Program the relevant mask registers. If src/dst_port or src/dst_addr + * are zero, then assume a full mask for that field. Also assume that + * a VLAN of 0 is unspecified, so mask that out as well. L4type + * cannot be masked out in this implementation. + * + * This also assumes IPv4 only. IPv6 masking isn't supported at this + * point in time. + */ + if (src_ipv4 == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, 0xffffffff); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask); + + if (dst_ipv4 == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, 0xffffffff); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask); + + switch (l4type & IXGBE_ATR_L4TYPE_MASK) { + case IXGBE_ATR_L4TYPE_TCP: + if (src_port == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xffff); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, + input_masks->src_port_mask); + + if (dst_port == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | + (0xffff << 16))); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | + (input_masks->dst_port_mask << 16))); + break; + case IXGBE_ATR_L4TYPE_UDP: + if (src_port == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xffff); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, + input_masks->src_port_mask); + + if (dst_port == 0) + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | + (0xffff << 16))); + else + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | + (input_masks->src_port_mask << 16))); + break; + default: + /* this already would have failed above */ + break; + } + + /* Program the last mask register, FDIRM */ + if (input_masks->vlan_id_mask || !vlan_id) + /* Mask both VLAN and VLANP - bits 0 and 1 */ + fdirm |= (IXGBE_FDIRM_VLANID | IXGBE_FDIRM_VLANP); + + if (input_masks->data_mask || !flex_bytes) + /* Flex bytes need masking, so mask the whole thing - bit 4 */ + fdirm |= IXGBE_FDIRM_FLEX; + + /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ + fdirm |= (IXGBE_FDIRM_POOL | IXGBE_FDIRM_DIPv6); + + IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm); fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW; fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE; @@ -2237,6 +2077,8 @@ s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val) { u32 core_ctl; + DEBUGFUNC("ixgbe_read_analog_reg8_82599"); + IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD | (reg << 8)); IXGBE_WRITE_FLUSH(hw); @@ -2259,6 +2101,8 @@ s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val) { u32 core_ctl; + DEBUGFUNC("ixgbe_write_analog_reg8_82599"); + core_ctl = (reg << 8) | val; IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl); IXGBE_WRITE_FLUSH(hw); @@ -2277,18 +2121,35 @@ s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val) **/ s32 ixgbe_start_hw_rev_1_82599(struct ixgbe_hw *hw) { - u32 q_num; + u32 i; + u32 regval; s32 ret_val = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_start_hw_rev_1__82599"); + ret_val = ixgbe_start_hw_generic(hw); /* Clear the rate limiters */ - for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) { - IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num); + for (i = 0; i < hw->mac.max_tx_queues; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i); IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0); } IXGBE_WRITE_FLUSH(hw); + /* Disable relaxed ordering */ + for (i = 0; i < hw->mac.max_tx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); + regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); + } + + for (i = 0; i < hw->mac.max_rx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); + regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); + } + /* We need to run link autotry after the driver loads */ hw->mac.autotry_restart = TRUE; @@ -2309,6 +2170,8 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_PHY_ADDR_INVALID; + DEBUGFUNC("ixgbe_identify_phy_82599"); + /* Detect PHY if not unknown - returns success if already detected. */ status = ixgbe_identify_phy_generic(hw); if (status != IXGBE_SUCCESS) @@ -2343,6 +2206,8 @@ u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) u16 ext_ability = 0; u8 comp_codes_10g = 0; + DEBUGFUNC("ixgbe_get_support_physical_layer_82599"); + hw->phy.ops.identify(hw); if (hw->phy.type == ixgbe_phy_tn || @@ -2410,10 +2275,14 @@ sfp_check: goto out; switch (hw->phy.type) { - case ixgbe_phy_tw_tyco: - case ixgbe_phy_tw_unknown: + case ixgbe_phy_sfp_passive_tyco: + case ixgbe_phy_sfp_passive_unknown: physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; break; + case ixgbe_phy_sfp_ftl_active: + case ixgbe_phy_sfp_active_unknown: + physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA; + break; case ixgbe_phy_sfp_avago: case ixgbe_phy_sfp_ftl: case ixgbe_phy_sfp_intel: @@ -2446,6 +2315,8 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval) int i; int secrxreg; + DEBUGFUNC("ixgbe_enable_rx_dma_82599"); + /* * Workaround for 82599 silicon errata when enabling the Rx datapath. * If traffic is incoming before we enable the Rx unit, it could hang @@ -2488,118 +2359,13 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval) **/ s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps) { + DEBUGFUNC("ixgbe_get_device_caps_82599"); + hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps); return IXGBE_SUCCESS; } -/** - * ixgbe_get_san_mac_addr_offset_82599 - SAN MAC address offset for 82599 - * @hw: pointer to hardware structure - * @san_mac_offset: SAN MAC address offset - * - * This function will read the EEPROM location for the SAN MAC address - * pointer, and returns the value at that location. This is used in both - * get and set mac_addr routines. - **/ -s32 ixgbe_get_san_mac_addr_offset_82599(struct ixgbe_hw *hw, - u16 *san_mac_offset) -{ - /* - * First read the EEPROM pointer to see if the MAC addresses are - * available. - */ - hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset); - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_get_san_mac_addr_82599 - SAN MAC address retrieval for 82599 - * @hw: pointer to hardware structure - * @san_mac_addr: SAN MAC address - * - * Reads the SAN MAC address from the EEPROM, if it's available. This is - * per-port, so set_lan_id() must be called before reading the addresses. - * set_lan_id() is called by identify_sfp(), but this cannot be relied - * upon for non-SFP connections, so we must call it here. - **/ -s32 ixgbe_get_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr) -{ - u16 san_mac_data, san_mac_offset; - u8 i; - - /* - * First read the EEPROM pointer to see if the MAC addresses are - * available. If they're not, no point in calling set_lan_id() here. - */ - ixgbe_get_san_mac_addr_offset_82599(hw, &san_mac_offset); - - if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { - /* - * No addresses available in this EEPROM. It's not an - * error though, so just wipe the local address and return. - */ - for (i = 0; i < 6; i++) - san_mac_addr[i] = 0xFF; - - goto san_mac_addr_out; - } - - /* make sure we know which port we need to program */ - hw->mac.ops.set_lan_id(hw); - /* apply the port offset to the address offset */ - (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : - (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); - for (i = 0; i < 3; i++) { - hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data); - san_mac_addr[i * 2] = (u8)(san_mac_data); - san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8); - san_mac_offset++; - } - -san_mac_addr_out: - return IXGBE_SUCCESS; -} - -/** - * ixgbe_set_san_mac_addr_82599 - Write the SAN MAC address to the EEPROM - * @hw: pointer to hardware structure - * @san_mac_addr: SAN MAC address - * - * Write a SAN MAC address to the EEPROM. - **/ -s32 ixgbe_set_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr) -{ - s32 status = IXGBE_SUCCESS; - u16 san_mac_data, san_mac_offset; - u8 i; - - /* Look for SAN mac address pointer. If not defined, return */ - ixgbe_get_san_mac_addr_offset_82599(hw, &san_mac_offset); - - if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { - status = IXGBE_ERR_NO_SAN_ADDR_PTR; - goto san_mac_addr_out; - } - - /* Make sure we know which port we need to write */ - hw->mac.ops.set_lan_id(hw); - /* Apply the port offset to the address offset */ - (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : - (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); - - for (i = 0; i < 3; i++) { - san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8); - san_mac_data |= (u16)(san_mac_addr[i * 2]); - hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data); - san_mac_offset++; - } - -san_mac_addr_out: - return status; -} - /** * ixgbe_verify_fw_version_82599 - verify fw version for 82599 * @hw: pointer to hardware structure @@ -2616,6 +2382,8 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) u16 fw_offset, fw_ptp_cfg_offset; u16 fw_version = 0; + DEBUGFUNC("ixgbe_verify_fw_version_82599"); + /* firmware check is only necessary for SFI devices */ if (hw->phy.media_type != ixgbe_media_type_fiber) { status = IXGBE_SUCCESS; @@ -2647,3 +2415,30 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) fw_version_out: return status; } +/** + * ixgbe_enable_relaxed_ordering_82599 - Enable relaxed ordering + * @hw: pointer to hardware structure + * + **/ +void ixgbe_enable_relaxed_ordering_82599(struct ixgbe_hw *hw) +{ + u32 regval; + u32 i; + + DEBUGFUNC("ixgbe_enable_relaxed_ordering_82599"); + + /* Enable relaxed ordering */ + for (i = 0; i < hw->mac.max_tx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); + regval |= IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); + } + + for (i = 0; i < hw->mac.max_rx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); + regval |= (IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); + } + +} diff --git a/sys/dev/ixgbe/ixgbe_api.c b/sys/dev/ixgbe/ixgbe_api.c index 9c3356fff59..a65686e29f2 100644 --- a/sys/dev/ixgbe/ixgbe_api.c +++ b/sys/dev/ixgbe/ixgbe_api.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -54,6 +54,8 @@ s32 ixgbe_init_shared_code(struct ixgbe_hw *hw) { s32 status; + DEBUGFUNC("ixgbe_init_shared_code"); + /* * Set the mac type */ @@ -94,6 +96,7 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82598AF_SINGLE_PORT: case IXGBE_DEV_ID_82598AF_DUAL_PORT: case IXGBE_DEV_ID_82598AT: + case IXGBE_DEV_ID_82598AT2: case IXGBE_DEV_ID_82598EB_CX4: case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: case IXGBE_DEV_ID_82598_DA_DUAL_PORT: @@ -103,9 +106,12 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) hw->mac.type = ixgbe_mac_82598EB; break; case IXGBE_DEV_ID_82599_KX4: + case IXGBE_DEV_ID_82599_KX4_MEZZ: case IXGBE_DEV_ID_82599_XAUI_LOM: + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: case IXGBE_DEV_ID_82599_SFP: case IXGBE_DEV_ID_82599_CX4: + case IXGBE_DEV_ID_82599_T3_LOM: hw->mac.type = ixgbe_mac_82599EB; break; default: @@ -162,6 +168,20 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw) IXGBE_NOT_IMPLEMENTED); } +/** + * ixgbe_enable_relaxed_ordering - Enables tx relaxed ordering, + * which is disabled by default in ixgbe_start_hw(); + * + * @hw: pointer to hardware structure + * + * Enable relaxed ordering; + **/ +void ixgbe_enable_relaxed_ordering(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.enable_relaxed_ordering) + hw->mac.ops.enable_relaxed_ordering(hw); +} + /** * ixgbe_clear_hw_cntrs - Clear hardware counters * @hw: pointer to hardware structure @@ -243,6 +263,23 @@ s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps) (hw, device_caps), IXGBE_NOT_IMPLEMENTED); } +/** + * ixgbe_get_wwn_prefix - Get alternative WWNN/WWPN prefix from the EEPROM + * @hw: pointer to hardware structure + * @wwnn_prefix: the alternative WWNN prefix + * @wwpn_prefix: the alternative WWPN prefix + * + * This function will read the EEPROM from the alternative SAN MAC address + * block to check the support for the alternative WWNN/WWPN prefix support. + **/ +s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_wwn_prefix, + (hw, wwnn_prefix, wwpn_prefix), + IXGBE_NOT_IMPLEMENTED); +} + /** * ixgbe_get_bus_info - Set PCI bus info * @hw: pointer to hardware structure @@ -438,19 +475,6 @@ s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed, IXGBE_NOT_IMPLEMENTED); } -/** - * ixgbe_setup_link - Configure link settings - * @hw: pointer to hardware structure - * - * Configures link settings based on values in the ixgbe_hw struct. - * Restarts the link. Performs autonegotiation if needed. - **/ -s32 ixgbe_setup_link(struct ixgbe_hw *hw) -{ - return ixgbe_call_func(hw, hw->mac.ops.setup_link, (hw), - IXGBE_NOT_IMPLEMENTED); -} - /** * ixgbe_check_link - Get link and speed status * @hw: pointer to hardware structure @@ -466,18 +490,19 @@ s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, } /** - * ixgbe_setup_link_speed - Set link speed + * ixgbe_setup_link - Set link speed * @hw: pointer to hardware structure * @speed: new link speed * @autoneg: TRUE if autonegotiation enabled * - * Set the link speed and restarts the link. + * Configures link settings. Restarts the link. + * Performs autonegotiation if needed. **/ -s32 ixgbe_setup_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed, +s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { - return ixgbe_call_func(hw, hw->mac.ops.setup_link_speed, (hw, speed, + return ixgbe_call_func(hw, hw->mac.ops.setup_link, (hw, speed, autoneg, autoneg_wait_to_complete), IXGBE_NOT_IMPLEMENTED); } diff --git a/sys/dev/ixgbe/ixgbe_api.h b/sys/dev/ixgbe/ixgbe_api.h index 654f22f6c32..48c523c1897 100644 --- a/sys/dev/ixgbe/ixgbe_api.h +++ b/sys/dev/ixgbe/ixgbe_api.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -43,6 +43,7 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw); s32 ixgbe_init_hw(struct ixgbe_hw *hw); s32 ixgbe_reset_hw(struct ixgbe_hw *hw); s32 ixgbe_start_hw(struct ixgbe_hw *hw); +void ixgbe_enable_relaxed_ordering(struct ixgbe_hw *hw); s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw); enum ixgbe_media_type ixgbe_get_media_type(struct ixgbe_hw *hw); s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr); @@ -67,8 +68,7 @@ s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); -s32 ixgbe_setup_link(struct ixgbe_hw *hw); -s32 ixgbe_setup_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed, +s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete); @@ -97,6 +97,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list, u32 addr_count, ixgbe_mc_addr_itr func); s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, ixgbe_mc_addr_itr func); +void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr_list, u32 vmdq); s32 ixgbe_enable_mc(struct ixgbe_hw *hw); s32 ixgbe_disable_mc(struct ixgbe_hw *hw); s32 ixgbe_clear_vfta(struct ixgbe_hw *hw); @@ -122,6 +123,7 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, u8 queue); s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, struct ixgbe_atr_input *input, + struct ixgbe_atr_input_masks *masks, u16 soft_id, u8 queue); u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key); @@ -164,6 +166,8 @@ s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr); s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps); s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u16 mask); void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u16 mask); +s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix); #endif /* _IXGBE_API_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c index 30c372d8a9b..217c477a6c6 100644 --- a/sys/dev/ixgbe/ixgbe_common.c +++ b/sys/dev/ixgbe/ixgbe_common.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -35,7 +35,6 @@ #include "ixgbe_common.h" #include "ixgbe_api.h" -static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw); static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw); static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw); @@ -47,9 +46,11 @@ static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count); static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_release_eeprom(struct ixgbe_hw *hw); -static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); +static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, + u16 *san_mac_offset); +s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan); /** * ixgbe_init_ops_generic - Inits function ptrs @@ -63,17 +64,20 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) struct ixgbe_mac_info *mac = &hw->mac; u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC); + DEBUGFUNC("ixgbe_init_ops_generic"); + /* EEPROM */ eeprom->ops.init_params = &ixgbe_init_eeprom_params_generic; /* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */ if (eec & (1 << 8)) - eeprom->ops.read = &ixgbe_read_eeprom_generic; + eeprom->ops.read = &ixgbe_read_eerd_generic; else eeprom->ops.read = &ixgbe_read_eeprom_bit_bang_generic; eeprom->ops.write = &ixgbe_write_eeprom_generic; eeprom->ops.validate_checksum = &ixgbe_validate_eeprom_checksum_generic; eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_generic; + eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_generic; /* MAC */ mac->ops.init_hw = &ixgbe_init_hw_generic; @@ -117,7 +121,6 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) /* Link */ mac->ops.get_link_capabilities = NULL; mac->ops.setup_link = NULL; - mac->ops.setup_link_speed = NULL; mac->ops.check_link = NULL; return IXGBE_SUCCESS; @@ -137,6 +140,8 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) u32 ctrl_ext; s32 ret_val = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_start_hw_generic"); + /* Set the media type */ hw->phy.media_type = hw->mac.ops.get_media_type(hw); @@ -177,6 +182,8 @@ s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) { s32 status = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_init_hw_generic"); + /* Reset the hardware */ status = hw->mac.ops.reset_hw(hw); @@ -199,6 +206,8 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) { u16 i = 0; + DEBUGFUNC("ixgbe_clear_hw_cntrs_generic"); + IXGBE_READ_REG(hw, IXGBE_CRCERRS); IXGBE_READ_REG(hw, IXGBE_ILLERRC); IXGBE_READ_REG(hw, IXGBE_ERRBC); @@ -324,6 +333,8 @@ s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr) u32 rar_low; u16 i; + DEBUGFUNC("ixgbe_get_mac_addr_generic"); + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0)); rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0)); @@ -347,6 +358,8 @@ s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) struct ixgbe_mac_info *mac = &hw->mac; u16 link_status; + DEBUGFUNC("ixgbe_get_bus_info_generic"); + hw->bus.type = ixgbe_bus_type_pci_express; /* Get the negotiated link width and speed from PCI config space */ @@ -399,6 +412,8 @@ void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) struct ixgbe_bus_info *bus = &hw->bus; u32 reg; + DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie"); + reg = IXGBE_READ_REG(hw, IXGBE_STATUS); bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; bus->lan_id = bus->func; @@ -424,6 +439,8 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) u32 reg_val; u16 i; + DEBUGFUNC("ixgbe_stop_adapter_generic"); + /* * Set the adapter_stopped flag so other driver functions stop touching * the hardware @@ -457,8 +474,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests */ - if (ixgbe_disable_pcie_master(hw) != IXGBE_SUCCESS) - DEBUGOUT("PCI-E Master disable polling has failed.\n"); + ixgbe_disable_pcie_master(hw); return IXGBE_SUCCESS; } @@ -472,6 +488,8 @@ s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) { u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + DEBUGFUNC("ixgbe_led_on_generic"); + /* To turn on the LED, set mode to ON. */ led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); @@ -490,6 +508,8 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) { u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + DEBUGFUNC("ixgbe_led_off_generic"); + /* To turn off the LED, set mode to OFF. */ led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); @@ -512,6 +532,8 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) u32 eec; u16 eeprom_size; + DEBUGFUNC("ixgbe_init_eeprom_params_generic"); + if (eeprom->type == ixgbe_eeprom_uninitialized) { eeprom->type = ixgbe_eeprom_none; /* Set default semaphore delay to 10ms which is a well @@ -533,7 +555,7 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> IXGBE_EEC_SIZE_SHIFT); eeprom->word_size = 1 << (eeprom_size + - IXGBE_EEPROM_WORD_SIZE_SHIFT); + IXGBE_EEPROM_WORD_SIZE_BASE_SHIFT); } if (eec & IXGBE_EEC_ADDR_SIZE) @@ -562,6 +584,8 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) s32 status; u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI; + DEBUGFUNC("ixgbe_write_eeprom_generic"); + hw->eeprom.ops.init_params(hw); if (offset >= hw->eeprom.word_size) { @@ -629,6 +653,8 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, u16 word_in; u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI; + DEBUGFUNC("ixgbe_read_eeprom_bit_bang_generic"); + hw->eeprom.ops.init_params(hw); if (offset >= hw->eeprom.word_size) { @@ -675,18 +701,20 @@ out: } /** - * ixgbe_read_eeprom_generic - Read EEPROM word using EERD + * ixgbe_read_eerd_generic - Read EEPROM word using EERD * @hw: pointer to hardware structure * @offset: offset of word in the EEPROM to read * @data: word read from the EEPROM * * Reads a 16 bit word from the EEPROM using the EERD register. **/ -s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) +s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) { u32 eerd; s32 status; + DEBUGFUNC("ixgbe_read_eerd_generic"); + hw->eeprom.ops.init_params(hw); if (offset >= hw->eeprom.word_size) { @@ -694,15 +722,15 @@ s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) goto out; } - eerd = (offset << IXGBE_EEPROM_READ_ADDR_SHIFT) + - IXGBE_EEPROM_READ_REG_START; + eerd = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) + + IXGBE_EEPROM_RW_REG_START; IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd); - status = ixgbe_poll_eeprom_eerd_done(hw); + status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ); if (status == IXGBE_SUCCESS) *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >> - IXGBE_EEPROM_READ_REG_DATA); + IXGBE_EEPROM_RW_REG_DATA); else DEBUGOUT("Eeprom read timed out\n"); @@ -711,20 +739,28 @@ out: } /** - * ixgbe_poll_eeprom_eerd_done - Poll EERD status + * ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status * @hw: pointer to hardware structure + * @ee_reg: EEPROM flag for polling * - * Polls the status bit (bit 1) of the EERD to determine when the read is done. + * Polls the status bit (bit 1) of the EERD or EEWR to determine when the + * read or write is done respectively. **/ -static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw) +s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) { u32 i; u32 reg; s32 status = IXGBE_ERR_EEPROM; - for (i = 0; i < IXGBE_EERD_ATTEMPTS; i++) { - reg = IXGBE_READ_REG(hw, IXGBE_EERD); - if (reg & IXGBE_EEPROM_READ_REG_DONE) { + DEBUGFUNC("ixgbe_poll_eerd_eewr_done"); + + for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) { + if (ee_reg == IXGBE_NVM_POLL_READ) + reg = IXGBE_READ_REG(hw, IXGBE_EERD); + else + reg = IXGBE_READ_REG(hw, IXGBE_EEWR); + + if (reg & IXGBE_EEPROM_RW_REG_DONE) { status = IXGBE_SUCCESS; break; } @@ -746,6 +782,8 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) u32 eec; u32 i; + DEBUGFUNC("ixgbe_acquire_eeprom"); + if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != IXGBE_SUCCESS) status = IXGBE_ERR_SWFW_SYNC; @@ -798,6 +836,8 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) u32 i; u32 swsm; + DEBUGFUNC("ixgbe_get_eeprom_semaphore"); + /* Get SMBI software semaphore between device drivers first */ for (i = 0; i < timeout; i++) { /* @@ -860,6 +900,8 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw) { u32 swsm; + DEBUGFUNC("ixgbe_release_eeprom_semaphore"); + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */ @@ -878,6 +920,8 @@ static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) u16 i; u8 spi_stat_reg; + DEBUGFUNC("ixgbe_ready_eeprom"); + /* * Read "Status Register" repeatedly until the LSB is cleared. The * EEPROM will signal that the command has been completed by clearing @@ -915,6 +959,8 @@ static void ixgbe_standby_eeprom(struct ixgbe_hw *hw) { u32 eec; + DEBUGFUNC("ixgbe_standby_eeprom"); + eec = IXGBE_READ_REG(hw, IXGBE_EEC); /* Toggle CS to flush commands */ @@ -941,6 +987,8 @@ static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, u32 mask; u32 i; + DEBUGFUNC("ixgbe_shift_out_eeprom_bits"); + eec = IXGBE_READ_REG(hw, IXGBE_EEC); /* @@ -993,6 +1041,8 @@ static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) u32 i; u16 data = 0; + DEBUGFUNC("ixgbe_shift_in_eeprom_bits"); + /* * In order to read a register from the EEPROM, we need to shift * 'count' bits in from the EEPROM. Bits are "shifted in" by raising @@ -1027,6 +1077,8 @@ static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) **/ static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) { + DEBUGFUNC("ixgbe_raise_eeprom_clk"); + /* * Raise the clock input to the EEPROM * (setting the SK bit), then delay @@ -1044,6 +1096,8 @@ static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) **/ static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) { + DEBUGFUNC("ixgbe_lower_eeprom_clk"); + /* * Lower the clock input to the EEPROM (clearing the SK bit), then * delay @@ -1062,6 +1116,8 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw) { u32 eec; + DEBUGFUNC("ixgbe_release_eeprom"); + eec = IXGBE_READ_REG(hw, IXGBE_EEC); eec |= IXGBE_EEC_CS; /* Pull CS high */ @@ -1083,10 +1139,10 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw) } /** - * ixgbe_calc_eeprom_checksum - Calculates and returns the checksum + * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum * @hw: pointer to hardware structure **/ -static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw) +u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) { u16 i; u16 j; @@ -1095,6 +1151,8 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw) u16 pointer = 0; u16 word = 0; + DEBUGFUNC("ixgbe_calc_eeprom_checksum_generic"); + /* Include 0x0-0x3F in the checksum */ for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { if (hw->eeprom.ops.read(hw, i, &word) != IXGBE_SUCCESS) { @@ -1141,6 +1199,8 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, u16 checksum; u16 read_checksum = 0; + DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic"); + /* * Read the first word from the EEPROM. If this times out or fails, do * not continue or we could be in for a very long wait while every @@ -1149,7 +1209,7 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, status = hw->eeprom.ops.read(hw, 0, &checksum); if (status == IXGBE_SUCCESS) { - checksum = ixgbe_calc_eeprom_checksum(hw); + checksum = hw->eeprom.ops.calc_checksum(hw); hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); @@ -1179,6 +1239,8 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) s32 status; u16 checksum; + DEBUGFUNC("ixgbe_update_eeprom_checksum_generic"); + /* * Read the first word from the EEPROM. If this times out or fails, do * not continue or we could be in for a very long wait while every @@ -1187,7 +1249,7 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) status = hw->eeprom.ops.read(hw, 0, &checksum); if (status == IXGBE_SUCCESS) { - checksum = ixgbe_calc_eeprom_checksum(hw); + checksum = hw->eeprom.ops.calc_checksum(hw); status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum); } else { @@ -1207,6 +1269,8 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr) { s32 status = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_validate_mac_addr"); + /* Make sure it is not a multicast address */ if (IXGBE_IS_MULTICAST(mac_addr)) { DEBUGOUT("MAC address is multicast\n"); @@ -1240,6 +1304,8 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 rar_low, rar_high; u32 rar_entries = hw->mac.num_rar_entries; + DEBUGFUNC("ixgbe_set_rar_generic"); + /* setup VMDq pool selection before this RAR gets enabled */ hw->mac.ops.set_vmdq(hw, index, vmdq); @@ -1286,6 +1352,8 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) u32 rar_high; u32 rar_entries = hw->mac.num_rar_entries; + DEBUGFUNC("ixgbe_clear_rar_generic"); + /* Make sure we are using a valid rar index range */ if (index < rar_entries) { /* @@ -1321,6 +1389,8 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) u32 i; u32 rar_entries = hw->mac.num_rar_entries; + DEBUGFUNC("ixgbe_init_rx_addrs_generic"); + /* * If the current mac address is valid, assume it is a software override * to the permanent address. @@ -1383,6 +1453,8 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) u32 rar_entries = hw->mac.num_rar_entries; u32 rar; + DEBUGFUNC("ixgbe_add_uc_addr"); + DEBUGOUT6(" UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); @@ -1426,6 +1498,8 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, u32 fctrl; u32 vmdq; + DEBUGFUNC("ixgbe_update_uc_addr_list_generic"); + /* * Clear accounting of old secondary address list, * don't count RAR[0] @@ -1435,10 +1509,10 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, hw->addr_ctrl.overflow_promisc = 0; /* Zero out the other receive addresses */ - DEBUGOUT1("Clearing RAR[1-%d]\n", hw->addr_ctrl.rar_used_count); - for (i = 1; i <= hw->addr_ctrl.rar_used_count; i++) { - IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); - IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); + DEBUGOUT1("Clearing RAR[1-%d]\n", uc_addr_in_use+1); + for (i = 0; i < uc_addr_in_use; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0); + IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0); } /* Add the new addresses */ @@ -1486,6 +1560,8 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) { u32 vector = 0; + DEBUGFUNC("ixgbe_mta_vector"); + switch (hw->mac.mc_filter_type) { case 0: /* use bits [47:36] of the address */ vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); @@ -1524,6 +1600,8 @@ void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) u32 vector_reg; u32 mta_reg; + DEBUGFUNC("ixgbe_set_mta"); + hw->addr_ctrl.mta_in_use++; vector = ixgbe_mta_vector(hw, mc_addr); @@ -1563,6 +1641,8 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, u32 i; u32 vmdq; + DEBUGFUNC("ixgbe_update_mc_addr_list_generic"); + /* * Set the new number of MC addresses that we are being requested to * use. @@ -1600,6 +1680,8 @@ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) { struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; + DEBUGFUNC("ixgbe_enable_mc_generic"); + if (a->mta_in_use > 0) IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); @@ -1617,6 +1699,8 @@ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) { struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; + DEBUGFUNC("ixgbe_disable_mc_generic"); + if (a->mta_in_use > 0) IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); @@ -1692,7 +1776,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) break; default: DEBUGOUT("Flow control param set incorrectly\n"); - ret_val = -IXGBE_ERR_CONFIG; + ret_val = IXGBE_ERR_CONFIG; goto out; break; } @@ -1761,6 +1845,7 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) s32 ret_val = IXGBE_SUCCESS; ixgbe_link_speed speed; u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; + u32 links2, anlp1_reg, autoc_reg, links; bool link_up; DEBUGFUNC("ixgbe_fc_autoneg"); @@ -1769,27 +1854,68 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) * AN should have completed when the cable was plugged in. * Look for reasons to bail out. Bail out if: * - FC autoneg is disabled, or if - * - we don't have multispeed fiber, or if - * - we're not running at 1G, or if - * - link is not up, or if - * - link is up but AN did not complete, or if - * - link is up and AN completed but timed out + * - link is not up. * - * Since we're being called from an LSC, link is already know to be up. + * Since we're being called from an LSC, link is already known to be up. * So use link_up_wait_to_complete=FALSE. */ hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); - linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); - if (hw->fc.disable_fc_autoneg || - !hw->phy.multispeed_fiber || - (speed != IXGBE_LINK_SPEED_1GB_FULL) || - !link_up || - ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || - ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { + if (hw->fc.disable_fc_autoneg || (!link_up)) { + hw->fc.fc_was_autonegged = FALSE; + hw->fc.current_mode = hw->fc.requested_mode; + goto out; + } + + /* + * On backplane, bail out if + * - backplane autoneg was not completed, or if + * - we are 82599 and link partner is not AN enabled + */ + if (hw->phy.media_type == ixgbe_media_type_backplane) { + links = IXGBE_READ_REG(hw, IXGBE_LINKS); + if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { + hw->fc.fc_was_autonegged = FALSE; + hw->fc.current_mode = hw->fc.requested_mode; + goto out; + } + + if (hw->mac.type == ixgbe_mac_82599EB) { + links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); + if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { + hw->fc.fc_was_autonegged = FALSE; + hw->fc.current_mode = hw->fc.requested_mode; + goto out; + } + } + } + + /* + * On multispeed fiber at 1g, bail out if + * - link is up but AN did not complete, or if + * - link is up and AN completed but timed out + */ + if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) { + linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); + if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || + ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { + hw->fc.fc_was_autonegged = FALSE; + hw->fc.current_mode = hw->fc.requested_mode; + goto out; + } + } + + /* + * Bail out on + * - copper or CX4 adapters + * - fiber adapters running at 10gig + */ + if ((hw->phy.media_type == ixgbe_media_type_copper) || + (hw->phy.media_type == ixgbe_media_type_cx4) || + ((hw->phy.media_type == ixgbe_media_type_fiber) && + (speed == IXGBE_LINK_SPEED_10GB_FULL))) { hw->fc.fc_was_autonegged = FALSE; hw->fc.current_mode = hw->fc.requested_mode; - DEBUGOUT("Autoneg FC was skipped.\n"); goto out; } @@ -1797,41 +1923,85 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) * Read the AN advertisement and LP ability registers and resolve * local flow control settings accordingly */ - pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); - pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); - if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) { - /* - * Now we need to check if the user selected Rx ONLY - * of pause frames. In this case, we had to advertise - * FULL flow control because we could not advertise RX - * ONLY. Hence, we must now check to see if we need to - * turn OFF the TRANSMISSION of PAUSE frames. - */ - if (hw->fc.requested_mode == ixgbe_fc_full) { - hw->fc.current_mode = ixgbe_fc_full; - DEBUGOUT("Flow Control = FULL.\n"); - } else { + if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && + (hw->phy.media_type != ixgbe_media_type_backplane)) { + pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); + if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && + (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) { + /* + * Now we need to check if the user selected Rx ONLY + * of pause frames. In this case, we had to advertise + * FULL flow control because we could not advertise RX + * ONLY. Hence, we must now check to see if we need to + * turn OFF the TRANSMISSION of PAUSE frames. + */ + if (hw->fc.requested_mode == ixgbe_fc_full) { + hw->fc.current_mode = ixgbe_fc_full; + DEBUGOUT("Flow Control = FULL.\n"); + } else { + hw->fc.current_mode = ixgbe_fc_rx_pause; + DEBUGOUT("Flow Control=RX PAUSE frames only\n"); + } + } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && + (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && + (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && + (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { + hw->fc.current_mode = ixgbe_fc_tx_pause; + DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); + } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && + (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && + !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && + (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { hw->fc.current_mode = ixgbe_fc_rx_pause; DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); + } else { + hw->fc.current_mode = ixgbe_fc_none; + DEBUGOUT("Flow Control = NONE.\n"); } - } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_tx_pause; - DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); - } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && - !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_rx_pause; - DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); - } else { - hw->fc.current_mode = ixgbe_fc_none; - DEBUGOUT("Flow Control = NONE.\n"); } + if (hw->phy.media_type == ixgbe_media_type_backplane) { + /* + * Read the 10g AN autoc and LP ability registers and resolve + * local flow control settings accordingly + */ + autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); + + if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && + (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE)) { + /* + * Now we need to check if the user selected Rx ONLY + * of pause frames. In this case, we had to advertise + * FULL flow control because we could not advertise RX + * ONLY. Hence, we must now check to see if we need to + * turn OFF the TRANSMISSION of PAUSE frames. + */ + if (hw->fc.requested_mode == ixgbe_fc_full) { + hw->fc.current_mode = ixgbe_fc_full; + DEBUGOUT("Flow Control = FULL.\n"); + } else { + hw->fc.current_mode = ixgbe_fc_rx_pause; + DEBUGOUT("Flow Control=RX PAUSE frames only\n"); + } + } else if (!(autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && + (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) && + (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) && + (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) { + hw->fc.current_mode = ixgbe_fc_tx_pause; + DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); + } else if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && + (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) && + !(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) && + (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) { + hw->fc.current_mode = ixgbe_fc_rx_pause; + DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); + } else { + hw->fc.current_mode = ixgbe_fc_none; + DEBUGOUT("Flow Control = NONE.\n"); + } + } /* Record that current_mode is the result of a successful autoneg */ hw->fc.fc_was_autonegged = TRUE; @@ -1850,6 +2020,8 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) s32 ret_val = IXGBE_SUCCESS; u32 reg; + DEBUGFUNC("ixgbe_setup_fc"); + /* Validate the packetbuf configuration */ if (packetbuf_num < 0 || packetbuf_num > 7) { @@ -1933,7 +2105,7 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) break; default: DEBUGOUT("Flow control param set incorrectly\n"); - ret_val = -IXGBE_ERR_CONFIG; + ret_val = IXGBE_ERR_CONFIG; goto out; break; } @@ -1941,9 +2113,6 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); - /* Enable and restart autoneg to inform the link partner */ - reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART; - /* Disable AN timeout */ if (hw->fc.strict_ieee) reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; @@ -1951,6 +2120,65 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg); + /* + * Set up the 10G flow control advertisement registers so the HW + * can do fc autoneg once the cable is plugged in. If we end up + * using 1g instead, this is harmless. + */ + reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + + /* + * The possible values of fc.requested_mode are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but + * we do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + * other: Invalid. + */ + switch (hw->fc.requested_mode) { + case ixgbe_fc_none: + /* Flow control completely disabled by software override. */ + reg &= ~(IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); + break; + case ixgbe_fc_rx_pause: + /* + * Rx Flow control is enabled and Tx Flow control is + * disabled by software override. Since there really + * isn't a way to advertise that we are capable of RX + * Pause ONLY, we will advertise that we support both + * symmetric and asymmetric Rx PAUSE. Later, we will + * disable the adapter's ability to send PAUSE frames. + */ + reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); + break; + case ixgbe_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is + * disabled by software override. + */ + reg |= (IXGBE_AUTOC_ASM_PAUSE); + reg &= ~(IXGBE_AUTOC_SYM_PAUSE); + break; + case ixgbe_fc_full: + /* Flow control (both Rx and Tx) is enabled by SW override. */ + reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); + break; + default: + DEBUGOUT("Flow control param set incorrectly\n"); + ret_val = IXGBE_ERR_CONFIG; + goto out; + break; + } + /* + * AUTOC restart handles negotiation of 1G and 10G. There is + * no need to set the PCS1GCTL register. + */ + reg |= IXGBE_AUTOC_AN_RESTART; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg); + DEBUGOUT1("Set up FC; IXGBE_AUTOC = 0x%08X\n", reg); + out: return ret_val; } @@ -1969,7 +2197,13 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) u32 i; u32 reg_val; u32 number_of_queues; - s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING; + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_disable_pcie_master"); + + /* Just jump out if bus mastering is already disabled */ + if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) + goto out; /* Disable the receive unit by stopping each queue */ number_of_queues = hw->mac.max_rx_queues; @@ -1986,13 +2220,42 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val); for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { - if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) { - status = IXGBE_SUCCESS; - break; - } + if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) + goto out; usec_delay(100); } + DEBUGOUT("GIO Master Disable bit didn't clear - requesting resets\n"); + status = IXGBE_ERR_MASTER_REQUESTS_PENDING; + + /* + * The GIO Master Disable bit didn't clear. There are multiple reasons + * for this listed in the datasheet 5.2.5.3.2 Master Disable, and they + * all require a double reset to recover from. Before proceeding, we + * first wait a little more to try to ensure that, at a minimum, the + * PCIe block has no transactions pending. + */ + for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { + if (!(IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS) & + IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) + break; + usec_delay(100); + } + + if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT) + DEBUGOUT("PCIe transaction pending bit also did not clear.\n"); + + /* + * Two consecutive resets are required via CTRL.RST per datasheet + * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine + * of this need. The first reset prevents new master requests from + * being issued by our device. We then must wait 1usec for any + * remaining completions from the PCIe bus to trickle in, and then reset + * again to clear out any effects they may have had on our device. + */ + hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + +out: return status; } @@ -2012,13 +2275,15 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) u32 fwmask = mask << 5; s32 timeout = 200; + DEBUGFUNC("ixgbe_acquire_swfw_sync"); + while (timeout) { /* * SW EEPROM semaphore bit is used for access to all * SW_FW_SYNC/GSSR bits (not just EEPROM) */ if (ixgbe_get_eeprom_semaphore(hw)) - return -IXGBE_ERR_SWFW_SYNC; + return IXGBE_ERR_SWFW_SYNC; gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); if (!(gssr & (fwmask | swmask))) @@ -2035,7 +2300,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) if (!timeout) { DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); - return -IXGBE_ERR_SWFW_SYNC; + return IXGBE_ERR_SWFW_SYNC; } gssr |= swmask; @@ -2058,6 +2323,8 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) u32 gssr; u32 swmask = mask; + DEBUGFUNC("ixgbe_release_swfw_sync"); + ixgbe_get_eeprom_semaphore(hw); gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); @@ -2076,6 +2343,8 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) **/ s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) { + DEBUGFUNC("ixgbe_enable_rx_dma_generic"); + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval); return IXGBE_SUCCESS; @@ -2093,6 +2362,8 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + DEBUGFUNC("ixgbe_blink_led_start_generic"); + /* * Link must be up to auto-blink the LEDs; * Force it if link is down. @@ -2125,6 +2396,8 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + DEBUGFUNC("ixgbe_blink_led_stop_generic"); + autoc_reg &= ~IXGBE_AUTOC_FLU; autoc_reg |= IXGBE_AUTOC_AN_RESTART; @@ -2139,3 +2412,629 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) return IXGBE_SUCCESS; } +/** + * ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM + * @hw: pointer to hardware structure + * @san_mac_offset: SAN MAC address offset + * + * This function will read the EEPROM location for the SAN MAC address + * pointer, and returns the value at that location. This is used in both + * get and set mac_addr routines. + **/ +static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, + u16 *san_mac_offset) +{ + DEBUGFUNC("ixgbe_get_san_mac_addr_offset"); + + /* + * First read the EEPROM pointer to see if the MAC addresses are + * available. + */ + hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM + * @hw: pointer to hardware structure + * @san_mac_addr: SAN MAC address + * + * Reads the SAN MAC address from the EEPROM, if it's available. This is + * per-port, so set_lan_id() must be called before reading the addresses. + * set_lan_id() is called by identify_sfp(), but this cannot be relied + * upon for non-SFP connections, so we must call it here. + **/ +s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) +{ + u16 san_mac_data, san_mac_offset; + u8 i; + + DEBUGFUNC("ixgbe_get_san_mac_addr_generic"); + + /* + * First read the EEPROM pointer to see if the MAC addresses are + * available. If they're not, no point in calling set_lan_id() here. + */ + ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); + + if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { + /* + * No addresses available in this EEPROM. It's not an + * error though, so just wipe the local address and return. + */ + for (i = 0; i < 6; i++) + san_mac_addr[i] = 0xFF; + + goto san_mac_addr_out; + } + + /* make sure we know which port we need to program */ + hw->mac.ops.set_lan_id(hw); + /* apply the port offset to the address offset */ + (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : + (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); + for (i = 0; i < 3; i++) { + hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data); + san_mac_addr[i * 2] = (u8)(san_mac_data); + san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8); + san_mac_offset++; + } + +san_mac_addr_out: + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM + * @hw: pointer to hardware structure + * @san_mac_addr: SAN MAC address + * + * Write a SAN MAC address to the EEPROM. + **/ +s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) +{ + s32 status = IXGBE_SUCCESS; + u16 san_mac_data, san_mac_offset; + u8 i; + + DEBUGFUNC("ixgbe_set_san_mac_addr_generic"); + + /* Look for SAN mac address pointer. If not defined, return */ + ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); + + if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { + status = IXGBE_ERR_NO_SAN_ADDR_PTR; + goto san_mac_addr_out; + } + + /* Make sure we know which port we need to write */ + hw->mac.ops.set_lan_id(hw); + /* Apply the port offset to the address offset */ + (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : + (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); + + for (i = 0; i < 3; i++) { + san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8); + san_mac_data |= (u16)(san_mac_addr[i * 2]); + hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data); + san_mac_offset++; + } + +san_mac_addr_out: + return status; +} + +/** + * ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count + * @hw: pointer to hardware structure + * + * Read PCIe configuration space, and get the MSI-X vector count from + * the capabilities table. + **/ +u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) +{ + u32 msix_count = 64; + + DEBUGFUNC("ixgbe_get_pcie_msix_count_generic"); + if (hw->mac.msix_vectors_from_pcie) { + msix_count = IXGBE_READ_PCIE_WORD(hw, + IXGBE_PCIE_MSIX_82599_CAPS); + msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; + + /* MSI-X count is zero-based in HW, so increment to give + * proper value */ + msix_count++; + } + + return msix_count; +} + +/** + * ixgbe_insert_mac_addr_generic - Find a RAR for this mac address + * @hw: pointer to hardware structure + * @addr: Address to put into receive address register + * @vmdq: VMDq pool to assign + * + * Puts an ethernet address into a receive address register, or + * finds the rar that it is aleady in; adds to the pool list + **/ +s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) +{ + static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF; + u32 first_empty_rar = NO_EMPTY_RAR_FOUND; + u32 rar; + u32 rar_low, rar_high; + u32 addr_low, addr_high; + + DEBUGFUNC("ixgbe_insert_mac_addr_generic"); + + /* swap bytes for HW little endian */ + addr_low = addr[0] | (addr[1] << 8) + | (addr[2] << 16) + | (addr[3] << 24); + addr_high = addr[4] | (addr[5] << 8); + + /* + * Either find the mac_id in rar or find the first empty space. + * rar_highwater points to just after the highest currently used + * rar in order to shorten the search. It grows when we add a new + * rar to the top. + */ + for (rar = 0; rar < hw->mac.rar_highwater; rar++) { + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); + + if (((IXGBE_RAH_AV & rar_high) == 0) + && first_empty_rar == NO_EMPTY_RAR_FOUND) { + first_empty_rar = rar; + } else if ((rar_high & 0xFFFF) == addr_high) { + rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar)); + if (rar_low == addr_low) + break; /* found it already in the rars */ + } + } + + if (rar < hw->mac.rar_highwater) { + /* already there so just add to the pool bits */ + ixgbe_set_vmdq(hw, rar, vmdq); + } else if (first_empty_rar != NO_EMPTY_RAR_FOUND) { + /* stick it into first empty RAR slot we found */ + rar = first_empty_rar; + ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); + } else if (rar == hw->mac.rar_highwater) { + /* add it to the top of the list and inc the highwater mark */ + ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); + hw->mac.rar_highwater++; + } else if (rar >= hw->mac.num_rar_entries) { + return IXGBE_ERR_INVALID_MAC_ADDR; + } + + /* + * If we found rar[0], make sure the default pool bit (we use pool 0) + * remains cleared to be sure default pool packets will get delivered + */ + if (rar == 0) + ixgbe_clear_vmdq(hw, rar, 0); + + return rar; +} + +/** + * ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to disassociate + * @vmdq: VMDq pool index to remove from the rar + **/ +s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 mpsar_lo, mpsar_hi; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ixgbe_clear_vmdq_generic"); + + if (rar < rar_entries) { + mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); + mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); + + if (!mpsar_lo && !mpsar_hi) + goto done; + + if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { + if (mpsar_lo) { + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); + mpsar_lo = 0; + } + if (mpsar_hi) { + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); + mpsar_hi = 0; + } + } else if (vmdq < 32) { + mpsar_lo &= ~(1 << vmdq); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); + } else { + mpsar_hi &= ~(1 << (vmdq - 32)); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); + } + + /* was that the last pool using this rar? */ + if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) + hw->mac.ops.clear_rar(hw, rar); + } else { + DEBUGOUT1("RAR index %d is out of range.\n", rar); + } + +done: + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to associate with a VMDq index + * @vmdq: VMDq pool index + **/ +s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 mpsar; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ixgbe_set_vmdq_generic"); + + if (rar < rar_entries) { + if (vmdq < 32) { + mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); + mpsar |= 1 << vmdq; + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar); + } else { + mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); + mpsar |= 1 << (vmdq - 32); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar); + } + } else { + DEBUGOUT1("RAR index %d is out of range.\n", rar); + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array + * @hw: pointer to hardware structure + **/ +s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) +{ + int i; + + DEBUGFUNC("ixgbe_init_uta_tables_generic"); + DEBUGOUT(" Clearing UTA\n"); + + for (i = 0; i < 128; i++) + IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_find_vlvf_slot - find the vlanid or the first empty slot + * @hw: pointer to hardware structure + * @vlan: VLAN id to write to VLAN filter + * + * return the VLVF index where this VLAN id should be placed + * + **/ +s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) +{ + u32 bits = 0; + u32 first_empty_slot = 0; + s32 regindex; + + /* short cut the special case */ + if (vlan == 0) + return 0; + + /* + * Search for the vlan id in the VLVF entries. Save off the first empty + * slot found along the way + */ + for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { + bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); + if (!bits && !(first_empty_slot)) + first_empty_slot = regindex; + else if ((bits & 0x0FFF) == vlan) + break; + } + + /* + * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan + * in the VLVF. Else use the first empty VLVF register for this + * vlan id. + */ + if (regindex >= IXGBE_VLVF_ENTRIES) { + if (first_empty_slot) + regindex = first_empty_slot; + else { + DEBUGOUT("No space in VLVF.\n"); + regindex = IXGBE_ERR_NO_SPACE; + } + } + + return regindex; +} + +/** + * ixgbe_set_vfta_generic - Set VLAN filter table + * @hw: pointer to hardware structure + * @vlan: VLAN id to write to VLAN filter + * @vind: VMDq output index that maps queue to VLAN id in VFVFB + * @vlan_on: boolean flag to turn on/off VLAN in VFVF + * + * Turn on/off specified VLAN in the VLAN filter table. + **/ +s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, + bool vlan_on) +{ + s32 regindex; + u32 bitindex; + u32 vfta; + u32 bits; + u32 vt; + u32 targetbit; + bool vfta_changed = FALSE; + + DEBUGFUNC("ixgbe_set_vfta_generic"); + + if (vlan > 4095) + return IXGBE_ERR_PARAM; + + /* + * this is a 2 part operation - first the VFTA, then the + * VLVF and VLVFB if VT Mode is set + * We don't write the VFTA until we know the VLVF part succeeded. + */ + + /* Part 1 + * The VFTA is a bitstring made up of 128 32-bit registers + * that enable the particular VLAN id, much like the MTA: + * bits[11-5]: which register + * bits[4-0]: which bit in the register + */ + regindex = (vlan >> 5) & 0x7F; + bitindex = vlan & 0x1F; + targetbit = (1 << bitindex); + vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); + + if (vlan_on) { + if (!(vfta & targetbit)) { + vfta |= targetbit; + vfta_changed = TRUE; + } + } else { + if ((vfta & targetbit)) { + vfta &= ~targetbit; + vfta_changed = TRUE; + } + } + + /* Part 2 + * If VT Mode is set + * Either vlan_on + * make sure the vlan is in VLVF + * set the vind bit in the matching VLVFB + * Or !vlan_on + * clear the pool bit and possibly the vind + */ + vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL); + if (vt & IXGBE_VT_CTL_VT_ENABLE) { + s32 vlvf_index; + + vlvf_index = ixgbe_find_vlvf_slot(hw, vlan); + if (vlvf_index < 0) + return vlvf_index; + + if (vlan_on) { + /* set the pool bit */ + if (vind < 32) { + bits = IXGBE_READ_REG(hw, + IXGBE_VLVFB(vlvf_index*2)); + bits |= (1 << vind); + IXGBE_WRITE_REG(hw, + IXGBE_VLVFB(vlvf_index*2), + bits); + } else { + bits = IXGBE_READ_REG(hw, + IXGBE_VLVFB((vlvf_index*2)+1)); + bits |= (1 << (vind-32)); + IXGBE_WRITE_REG(hw, + IXGBE_VLVFB((vlvf_index*2)+1), + bits); + } + } else { + /* clear the pool bit */ + if (vind < 32) { + bits = IXGBE_READ_REG(hw, + IXGBE_VLVFB(vlvf_index*2)); + bits &= ~(1 << vind); + IXGBE_WRITE_REG(hw, + IXGBE_VLVFB(vlvf_index*2), + bits); + bits |= IXGBE_READ_REG(hw, + IXGBE_VLVFB((vlvf_index*2)+1)); + } else { + bits = IXGBE_READ_REG(hw, + IXGBE_VLVFB((vlvf_index*2)+1)); + bits &= ~(1 << (vind-32)); + IXGBE_WRITE_REG(hw, + IXGBE_VLVFB((vlvf_index*2)+1), + bits); + bits |= IXGBE_READ_REG(hw, + IXGBE_VLVFB(vlvf_index*2)); + } + } + + /* + * If there are still bits set in the VLVFB registers + * for the VLAN ID indicated we need to see if the + * caller is requesting that we clear the VFTA entry bit. + * If the caller has requested that we clear the VFTA + * entry bit but there are still pools/VFs using this VLAN + * ID entry then ignore the request. We're not worried + * about the case where we're turning the VFTA VLAN ID + * entry bit on, only when requested to turn it off as + * there may be multiple pools and/or VFs using the + * VLAN ID entry. In that case we cannot clear the + * VFTA bit until all pools/VFs using that VLAN ID have also + * been cleared. This will be indicated by "bits" being + * zero. + */ + if (bits) { + IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), + (IXGBE_VLVF_VIEN | vlan)); + if (!vlan_on) { + /* someone wants to clear the vfta entry + * but some pools/VFs are still using it. + * Ignore it. */ + vfta_changed = FALSE; + } + } + else + IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); + } + + if (vfta_changed) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_clear_vfta_generic - Clear VLAN filter table + * @hw: pointer to hardware structure + * + * Clears the VLAN filer table, and the VMDq index associated with the filter + **/ +s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) +{ + u32 offset; + + DEBUGFUNC("ixgbe_clear_vfta_generic"); + + for (offset = 0; offset < hw->mac.vft_size; offset++) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); + + for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { + IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0); + IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_check_mac_link_generic - Determine link and speed status + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @link_up: TRUE when link is up + * @link_up_wait_to_complete: bool used to wait for link up or not + * + * Reads the links register to determine if link is up and the current speed + **/ +s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete) +{ + u32 links_reg, links_orig; + u32 i; + + DEBUGFUNC("ixgbe_check_mac_link_generic"); + + /* clear the old state */ + links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); + + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + + if (links_orig != links_reg) { + DEBUGOUT2("LINKS changed from %08X to %08X\n", + links_orig, links_reg); + } + + if (link_up_wait_to_complete) { + for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { + if (links_reg & IXGBE_LINKS_UP) { + *link_up = TRUE; + break; + } else { + *link_up = FALSE; + } + msec_delay(100); + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + } + } else { + if (links_reg & IXGBE_LINKS_UP) + *link_up = TRUE; + else + *link_up = FALSE; + } + + if ((links_reg & IXGBE_LINKS_SPEED_82599) == + IXGBE_LINKS_SPEED_10G_82599) + *speed = IXGBE_LINK_SPEED_10GB_FULL; + else if ((links_reg & IXGBE_LINKS_SPEED_82599) == + IXGBE_LINKS_SPEED_1G_82599) + *speed = IXGBE_LINK_SPEED_1GB_FULL; + else + *speed = IXGBE_LINK_SPEED_100_FULL; + + /* if link is down, zero out the current_mode */ + if (*link_up == FALSE) { + hw->fc.current_mode = ixgbe_fc_none; + hw->fc.fc_was_autonegged = FALSE; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from + * the EEPROM + * @hw: pointer to hardware structure + * @wwnn_prefix: the alternative WWNN prefix + * @wwpn_prefix: the alternative WWPN prefix + * + * This function will read the EEPROM from the alternative SAN MAC address + * block to check the support for the alternative WWNN/WWPN prefix support. + **/ +s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix) +{ + u16 offset, caps; + u16 alt_san_mac_blk_offset; + + DEBUGFUNC("ixgbe_get_wwn_prefix_generic"); + + /* clear output first */ + *wwnn_prefix = 0xFFFF; + *wwpn_prefix = 0xFFFF; + + /* check if alternative SAN MAC is supported */ + hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, + &alt_san_mac_blk_offset); + + if ((alt_san_mac_blk_offset == 0) || + (alt_san_mac_blk_offset == 0xFFFF)) + goto wwn_prefix_out; + + /* check capability in alternative san mac address block */ + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; + hw->eeprom.ops.read(hw, offset, &caps); + if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) + goto wwn_prefix_out; + + /* get the corresponding prefix for WWNN/WWPN */ + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; + hw->eeprom.ops.read(hw, offset, wwnn_prefix); + + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; + hw->eeprom.ops.read(hw, offset, wwpn_prefix); + +wwn_prefix_out: + return IXGBE_SUCCESS; +} diff --git a/sys/dev/ixgbe/ixgbe_common.h b/sys/dev/ixgbe/ixgbe_common.h index 0c535751880..f0707e21a2e 100644 --- a/sys/dev/ixgbe/ixgbe_common.h +++ b/sys/dev/ixgbe/ixgbe_common.h @@ -42,6 +42,8 @@ IXGBE_WRITE_REG(hw, reg + 4, (u32) (value >> 32)); \ } while (0) +u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw); + s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw); s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw); s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw); @@ -57,12 +59,14 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index); s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw); s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data); -s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); +s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); +u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw); s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, u16 *checksum_val); s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); +s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); @@ -73,7 +77,6 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, ixgbe_mc_addr_itr func); s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, u32 addr_count, ixgbe_mc_addr_itr func); -void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw); s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw); s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval); @@ -87,9 +90,25 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask); void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask); s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw); -s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val); -s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val); s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index); s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr); +s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr); + +s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq); +s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq); +s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); +s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw); +s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, + u32 vind, bool vlan_on); +s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw); + +s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete); + +s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix); + #endif /* IXGBE_COMMON */ diff --git a/sys/dev/ixgbe/ixgbe_osdep.h b/sys/dev/ixgbe/ixgbe_osdep.h index e1bbce08602..151e63ff1f6 100644 --- a/sys/dev/ixgbe/ixgbe_osdep.h +++ b/sys/dev/ixgbe/ixgbe_osdep.h @@ -110,6 +110,16 @@ typedef boolean_t bool; #endif #endif +#if defined(__i386__) || defined(__amd64__) +static __inline +void prefetch(void *x) +{ + __asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x)); +} +#else +#define prefetch(x) +#endif + struct ixgbe_osdep { bus_space_tag_t mem_bus_space_tag; diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c index daa37d91000..7ec2981d4c2 100644 --- a/sys/dev/ixgbe/ixgbe_phy.c +++ b/sys/dev/ixgbe/ixgbe_phy.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -59,6 +59,8 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw) { struct ixgbe_phy_info *phy = &hw->phy; + DEBUGFUNC("ixgbe_init_phy_ops_generic"); + /* PHY */ phy->ops.identify = &ixgbe_identify_phy_generic; phy->ops.reset = &ixgbe_reset_phy_generic; @@ -67,7 +69,7 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw) phy->ops.setup_link = &ixgbe_setup_phy_link_generic; phy->ops.setup_link_speed = &ixgbe_setup_phy_link_speed_generic; phy->ops.check_link = NULL; - phy->ops.get_firmware_version = NULL; + phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_generic; phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_generic; phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_generic; phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic; @@ -75,7 +77,8 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw) phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear; phy->ops.identify_sfp = &ixgbe_identify_sfp_module_generic; phy->sfp_type = ixgbe_sfp_type_unknown; - + phy->ops.check_overtemp = &ixgbe_tn_check_overtemp; + phy->ops.set_low_power_state = &ixgbe_tn_set_low_power_state; return IXGBE_SUCCESS; } @@ -91,6 +94,8 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) u32 phy_addr; u16 ext_ability = 0; + DEBUGFUNC("ixgbe_identify_phy_generic"); + if (hw->phy.type == ixgbe_phy_unknown) { for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { if (ixgbe_validate_phy_addr(hw, phy_addr)) { @@ -138,6 +143,8 @@ bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr) u16 phy_id = 0; bool valid = FALSE; + DEBUGFUNC("ixgbe_validate_phy_addr"); + hw->phy.addr = phy_addr; hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id); @@ -159,6 +166,8 @@ s32 ixgbe_get_phy_id(struct ixgbe_hw *hw) u16 phy_id_high = 0; u16 phy_id_low = 0; + DEBUGFUNC("ixgbe_get_phy_id"); + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id_high); @@ -183,6 +192,8 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) { enum ixgbe_phy_type phy_type; + DEBUGFUNC("ixgbe_get_phy_type_from_id"); + switch (phy_id) { case TN1010_PHY_ID: phy_type = ixgbe_phy_tn; @@ -215,6 +226,8 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) u16 ctrl = 0; s32 status = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_reset_phy_generic"); + if (hw->phy.type == ixgbe_phy_unknown) status = ixgbe_identify_phy_generic(hw); @@ -229,13 +242,19 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) IXGBE_MDIO_PHY_XS_DEV_TYPE, IXGBE_MDIO_PHY_XS_RESET); - /* Poll for reset bit to self-clear indicating reset is complete */ - for (i = 0; i < 500; i++) { - msec_delay(1); + /* + * Poll for reset bit to self-clear indicating reset is complete. + * Some PHYs could take up to 3 seconds to complete and need about + * 1.7 usec delay after the reset is complete. + */ + for (i = 0; i < 30; i++) { + msec_delay(100); hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl); - if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) + if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) { + usec_delay(2); break; + } } if (ctrl & IXGBE_MDIO_PHY_XS_RESET) { @@ -262,6 +281,8 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, s32 status = IXGBE_SUCCESS; u16 gssr; + DEBUGFUNC("ixgbe_read_phy_reg_generic"); + if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) gssr = IXGBE_GSSR_PHY1_SM; else @@ -359,6 +380,8 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, s32 status = IXGBE_SUCCESS; u16 gssr; + DEBUGFUNC("ixgbe_write_phy_reg_generic"); + if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) gssr = IXGBE_GSSR_PHY1_SM; else @@ -437,10 +460,10 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, } /** - * ixgbe_setup_phy_link_generic - Set and restart autoneg - * @hw: pointer to hardware structure + * ixgbe_setup_phy_link_generic - Set and restart autoneg + * @hw: pointer to hardware structure * - * Restart autonegotiation and PHY and waits for completion. + * Restart autonegotiation and PHY and waits for completion. **/ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) { @@ -448,23 +471,59 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) u32 time_out; u32 max_time_out = 10; u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; + bool autoneg = FALSE; + ixgbe_link_speed speed; - /* - * Set advertisement settings in PHY based on autoneg_advertised - * settings. If autoneg_advertised = 0, then advertise default values - * tnx devices cannot be "forced" to a autoneg 10G and fail. But can - * for a 1G. - */ - hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); + DEBUGFUNC("ixgbe_setup_phy_link_generic"); - if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL) - autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */ - else - autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */ + ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); - hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); + if (speed & IXGBE_LINK_SPEED_10GB_FULL) { + /* Set or unset auto-negotiation 10G advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) + autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) { + /* Set or unset auto-negotiation 1G advertisement */ + hw->phy.ops.read_reg(hw, + IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) + autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, + IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_100_FULL) { + /* Set or unset auto-negotiation 100M advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_100BASE_T_ADVERTISE; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) + autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + } /* Restart PHY autonegotiation and wait for completion */ hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, @@ -489,8 +548,10 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) } } - if (time_out == max_time_out) + if (time_out == max_time_out) { status = IXGBE_ERR_LINK_SETUP; + DEBUGOUT("ixgbe_setup_phy_link_generic: time out"); + } return status; } @@ -509,6 +570,8 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, UNREFERENCED_PARAMETER(autoneg); UNREFERENCED_PARAMETER(autoneg_wait_to_complete); + DEBUGFUNC("ixgbe_setup_phy_link_speed_generic"); + /* * Clear autoneg_advertised and set new values based on input link * speed. @@ -545,6 +608,8 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, s32 status = IXGBE_ERR_LINK_SETUP; u16 speed_ability; + DEBUGFUNC("ixgbe_get_copper_link_capabilities_generic"); + *speed = 0; *autoneg = TRUE; @@ -581,6 +646,8 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, u16 phy_speed = 0; u16 phy_data = 0; + DEBUGFUNC("ixgbe_check_phy_link_tnx"); + /* Initialize speed and link to default case */ *link_up = FALSE; *speed = IXGBE_LINK_SPEED_10GB_FULL; @@ -612,6 +679,102 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, return status; } +/** + * ixgbe_setup_phy_link_tnx - Set and restart autoneg + * @hw: pointer to hardware structure + * + * Restart autonegotiation and PHY and waits for completion. + **/ +s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u32 time_out; + u32 max_time_out = 10; + u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; + bool autoneg = FALSE; + ixgbe_link_speed speed; + + DEBUGFUNC("ixgbe_setup_phy_link_tnx"); + + ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) { + /* Set or unset auto-negotiation 10G advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) + autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) { + /* Set or unset auto-negotiation 1G advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) + autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX; + + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_100_FULL) { + /* Set or unset auto-negotiation 100M advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_100BASE_T_ADVERTISE; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) + autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + } + + /* Restart PHY autonegotiation and wait for completion */ + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); + + autoneg_reg |= IXGBE_MII_RESTART; + + hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); + + /* Wait for autonegotiation to finish */ + for (time_out = 0; time_out < max_time_out; time_out++) { + usec_delay(10); + /* Restart PHY autonegotiation and wait for completion */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE; + if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) { + break; + } + } + + if (time_out == max_time_out) { + status = IXGBE_ERR_LINK_SETUP; + DEBUGOUT("ixgbe_setup_phy_link_tnx: time out"); + } + + return status; +} + + /** * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version * @hw: pointer to hardware structure @@ -622,6 +785,8 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, { s32 status = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_get_phy_firmware_version_tnx"); + status = hw->phy.ops.read_reg(hw, TNX_FW_REV, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, firmware_version); @@ -631,15 +796,17 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, /** - * ixgbe_get_phy_firmware_version_aq - Gets the PHY Firmware Version + * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version * @hw: pointer to hardware structure * @firmware_version: pointer to the PHY Firmware Version **/ -s32 ixgbe_get_phy_firmware_version_aq(struct ixgbe_hw *hw, +s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, u16 *firmware_version) { s32 status = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_get_phy_firmware_version_generic"); + status = hw->phy.ops.read_reg(hw, AQ_FW_REV, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, firmware_version); @@ -660,6 +827,8 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) s32 ret_val = IXGBE_SUCCESS; u32 i; + DEBUGFUNC("ixgbe_reset_phy_nl"); + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); @@ -760,8 +929,11 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) u8 comp_codes_10g = 0; u8 oui_bytes[3] = {0, 0, 0}; u8 cable_tech = 0; + u8 cable_spec = 0; u16 enforce_sfp = 0; + DEBUGFUNC("ixgbe_identify_sfp_module_generic"); + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) { hw->phy.sfp_type = ixgbe_sfp_type_not_present; status = IXGBE_ERR_SFP_NOT_PRESENT; @@ -804,6 +976,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) * 4 SFP_DA_CORE1 - 82599-specific * 5 SFP_SR/LR_CORE0 - 82599-specific * 6 SFP_SR/LR_CORE1 - 82599-specific + * 7 SFP_act_lmt_DA_CORE0 - 82599-specific + * 8 SFP_act_lmt_DA_CORE1 - 82599-specific */ if (hw->mac.type == ixgbe_mac_82598EB) { if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) @@ -815,29 +989,40 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) else hw->phy.sfp_type = ixgbe_sfp_type_unknown; } else if (hw->mac.type == ixgbe_mac_82599EB) { - if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) + if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) { if (hw->bus.lan_id == 0) hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core0; else hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core1; - else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) + } else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) { + hw->phy.ops.read_i2c_eeprom( + hw, IXGBE_SFF_CABLE_SPEC_COMP, + &cable_spec); + if (cable_spec & + IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_da_act_lmt_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_da_act_lmt_core1; + } else + hw->phy.sfp_type = + ixgbe_sfp_type_unknown; + } else if (comp_codes_10g & + (IXGBE_SFF_10GBASESR_CAPABLE | + IXGBE_SFF_10GBASELR_CAPABLE)) { if (hw->bus.lan_id == 0) hw->phy.sfp_type = ixgbe_sfp_type_srlr_core0; else hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1; - else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) - if (hw->bus.lan_id == 0) - hw->phy.sfp_type = - ixgbe_sfp_type_srlr_core0; - else - hw->phy.sfp_type = - ixgbe_sfp_type_srlr_core1; - else + } else { hw->phy.sfp_type = ixgbe_sfp_type_unknown; + } } if (hw->phy.sfp_type != stored_sfp_type) @@ -850,6 +1035,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) && (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE))) hw->phy.multispeed_fiber = TRUE; + /* Determine PHY vendor */ if (hw->phy.type != ixgbe_phy_nl) { hw->phy.id = identifier; @@ -871,10 +1057,14 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) switch (vendor_oui) { case IXGBE_SFF_VENDOR_OUI_TYCO: if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) - hw->phy.type = ixgbe_phy_tw_tyco; + hw->phy.type = + ixgbe_phy_sfp_passive_tyco; break; case IXGBE_SFF_VENDOR_OUI_FTL: - hw->phy.type = ixgbe_phy_sfp_ftl; + if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) + hw->phy.type = ixgbe_phy_sfp_ftl_active; + else + hw->phy.type = ixgbe_phy_sfp_ftl; break; case IXGBE_SFF_VENDOR_OUI_AVAGO: hw->phy.type = ixgbe_phy_sfp_avago; @@ -884,15 +1074,20 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) break; default: if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) - hw->phy.type = ixgbe_phy_tw_unknown; + hw->phy.type = + ixgbe_phy_sfp_passive_unknown; + else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) + hw->phy.type = + ixgbe_phy_sfp_active_unknown; else hw->phy.type = ixgbe_phy_sfp_unknown; break; } } - /* All passive DA cables are supported */ - if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) { + /* Allow any DA cable vendor */ + if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE | + IXGBE_SFF_DA_ACTIVE_CABLE)) { status = IXGBE_SUCCESS; goto out; } @@ -943,6 +1138,9 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *data_offset) { u16 sfp_id; + u16 sfp_type = hw->phy.sfp_type; + + DEBUGFUNC("ixgbe_get_sfp_init_sequence_offsets"); if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) return IXGBE_ERR_SFP_NOT_SUPPORTED; @@ -954,6 +1152,12 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, (hw->phy.sfp_type == ixgbe_sfp_type_da_cu)) return IXGBE_ERR_SFP_NOT_SUPPORTED; + /* Limiting active cables must be initialized as SR modules */ + if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0) + sfp_type = ixgbe_sfp_type_srlr_core0; + else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1) + sfp_type = ixgbe_sfp_type_srlr_core1; + /* Read offset to PHY init contents */ hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset); @@ -970,7 +1174,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, hw->eeprom.ops.read(hw, *list_offset, &sfp_id); while (sfp_id != IXGBE_PHY_INIT_END_NL) { - if (sfp_id == hw->phy.sfp_type) { + if (sfp_id == sfp_type) { (*list_offset)++; hw->eeprom.ops.read(hw, *list_offset, data_offset); if ((!*data_offset) || (*data_offset == 0xFFFF)) { @@ -1370,6 +1574,8 @@ static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data) s32 status; u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + DEBUGFUNC("ixgbe_clock_in_i2c_bit"); + status = ixgbe_raise_i2c_clk(hw, &i2cctl); /* Minimum high period of clock is 4us */ @@ -1398,6 +1604,8 @@ static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data) s32 status; u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + DEBUGFUNC("ixgbe_clock_out_i2c_bit"); + status = ixgbe_set_i2c_data(hw, &i2cctl, data); if (status == IXGBE_SUCCESS) { status = ixgbe_raise_i2c_clk(hw, &i2cctl); @@ -1429,6 +1637,8 @@ static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) { s32 status = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_raise_i2c_clk"); + *i2cctl |= IXGBE_I2C_CLK_OUT; IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); @@ -1449,6 +1659,8 @@ static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) { + DEBUGFUNC("ixgbe_lower_i2c_clk"); + *i2cctl &= ~IXGBE_I2C_CLK_OUT; IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); @@ -1469,6 +1681,8 @@ static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data) { s32 status = IXGBE_SUCCESS; + DEBUGFUNC("ixgbe_set_i2c_data"); + if (data) *i2cctl |= IXGBE_I2C_DATA_OUT; else @@ -1500,6 +1714,8 @@ static bool ixgbe_get_i2c_data(u32 *i2cctl) { bool data; + DEBUGFUNC("ixgbe_get_i2c_data"); + if (*i2cctl & IXGBE_I2C_DATA_IN) data = 1; else @@ -1543,3 +1759,56 @@ void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) /* Put the i2c bus back to default state */ ixgbe_i2c_stop(hw); } + +/** + * ixgbe_check_overtemp - Checks if an overtemp occured. + * @hw: pointer to hardware structure + * + * Checks if the LASI temp alarm status was triggered due to overtemp + **/ +s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u16 phy_data = 0; + + DEBUGFUNC("ixgbe_tn_check_overtemp"); + + if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM) + goto out; + + /* Check that the LASI temp alarm status was triggered */ + hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data); + + if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM)) + goto out; + + status = IXGBE_ERR_OVERTEMP; +out: + return status; +} + + +/** + * ixgbe_set_tn_low_power_state - Sets the teranetics phy into low power state + * @hw: pointer to hardware structure + * + * Sets the phy into low power mode when LASI temp alarm status is triggered + **/ +s32 ixgbe_tn_set_low_power_state(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u16 phy_data = 0; + + DEBUGFUNC("ixgbe_set_tn_low_power_state"); + + /* Set the phy into low power mode */ + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_CONTROL_ADDR, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data); + phy_data |= IXGBE_MDIO_PHY_LOW_POWER_MODE; + hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_PMD_CONTROL_ADDR, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, phy_data); + + return status; +} + diff --git a/sys/dev/ixgbe/ixgbe_phy.h b/sys/dev/ixgbe/ixgbe_phy.h index bfe73de25b1..8f49aa83e8f 100644 --- a/sys/dev/ixgbe/ixgbe_phy.h +++ b/sys/dev/ixgbe/ixgbe_phy.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -47,9 +47,12 @@ #define IXGBE_SFF_1GBE_COMP_CODES 0x6 #define IXGBE_SFF_10GBE_COMP_CODES 0x3 #define IXGBE_SFF_CABLE_TECHNOLOGY 0x8 +#define IXGBE_SFF_CABLE_SPEC_COMP 0x3C /* Bitmasks */ #define IXGBE_SFF_DA_PASSIVE_CABLE 0x4 +#define IXGBE_SFF_DA_ACTIVE_CABLE 0x8 +#define IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING 0x4 #define IXGBE_SFF_1GBASESX_CAPABLE 0x1 #define IXGBE_SFF_1GBASELX_CAPABLE 0x2 #define IXGBE_SFF_10GBASESR_CAPABLE 0x10 @@ -84,6 +87,9 @@ #define IXGBE_I2C_T_SU_STO 4 #define IXGBE_I2C_T_BUF 5 +#define IXGBE_TN_LASI_STATUS_REG 0x9005 +#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008 + s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw); bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr); @@ -108,9 +114,10 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up); +s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw); s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, u16 *firmware_version); -s32 ixgbe_get_phy_firmware_version_aq(struct ixgbe_hw *hw, +s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, u16 *firmware_version); s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); @@ -118,6 +125,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *list_offset, u16 *data_offset); +s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); +s32 ixgbe_tn_set_low_power_state(struct ixgbe_hw *hw); s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data); s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h index 50345f4c2c1..2e1f0623b42 100644 --- a/sys/dev/ixgbe/ixgbe_type.h +++ b/sys/dev/ixgbe/ixgbe_type.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ #define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7 #define IXGBE_DEV_ID_82598AT 0x10C8 +#define IXGBE_DEV_ID_82598AT2 0x150B #define IXGBE_DEV_ID_82598EB_SFP_LOM 0x10DB #define IXGBE_DEV_ID_82598EB_CX4 0x10DD #define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC @@ -54,9 +55,13 @@ #define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1 #define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4 #define IXGBE_DEV_ID_82599_KX4 0x10F7 +#define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514 +#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 +#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C #define IXGBE_DEV_ID_82599_CX4 0x10F9 #define IXGBE_DEV_ID_82599_SFP 0x10FB #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC +#define IXGBE_DEV_ID_82599_T3_LOM 0x151C /* General Registers */ #define IXGBE_CTRL 0x00000 @@ -74,6 +79,7 @@ /* NVM Registers */ #define IXGBE_EEC 0x10010 #define IXGBE_EERD 0x10014 +#define IXGBE_EEWR 0x10018 #define IXGBE_FLA 0x1001C #define IXGBE_EEMNGCTL 0x10110 #define IXGBE_EEMNGDATA 0x10114 @@ -85,7 +91,7 @@ /* General Receive Control */ #define IXGBE_GRC_MNG 0x00000001 /* Manageability Enable */ -#define IXGBE_GRC_APME 0x00000002 /* Advanced Power Management Enable */ +#define IXGBE_GRC_APME 0x00000002 /* APM enabled in EEPROM */ #define IXGBE_VPDDIAG0 0x10204 #define IXGBE_VPDDIAG1 0x10208 @@ -194,6 +200,7 @@ #define IXGBE_RFCTL 0x05008 #define IXGBE_DRECCCTL 0x02F08 #define IXGBE_DRECCCTL_DISABLE 0 + /* Multicast Table Array - 128 entries */ #define IXGBE_MTA(_i) (0x05200 + ((_i) * 4)) #define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \ @@ -330,7 +337,7 @@ /* Wake Up Control */ #define IXGBE_WUC_PME_EN 0x00000002 /* PME Enable */ #define IXGBE_WUC_PME_STATUS 0x00000004 /* PME Status */ -#define IXGBE_WUC_ADVD3WUC 0x00000010 /* D3Cold wake up cap. enable*/ +#define IXGBE_WUC_WKEN 0x00000010 /* Enable PE_WAKE_N pin assertion */ /* Wake Up Filter Control */ #define IXGBE_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ @@ -352,7 +359,7 @@ #define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */ #define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */ #define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000 /* Mask for Ext. flex filters */ -#define IXGBE_WUFC_ALL_FILTERS 0x003F00FF /* Mask for all 6 wakeup filters*/ +#define IXGBE_WUFC_ALL_FILTERS 0x003F00FF /* Mask for all wakeup filters */ #define IXGBE_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */ /* Wake Up Status */ @@ -703,6 +710,7 @@ #define IXGBE_MREVID 0x11064 #define IXGBE_DCA_ID 0x11070 #define IXGBE_DCA_CTRL 0x11074 +#define IXGBE_SWFW_SYNC IXGBE_GSSR /* PCI-E registers 82599-Specific */ #define IXGBE_GCR_EXT 0x11050 @@ -725,6 +733,18 @@ #define IXGBE_ECC_STATUS_82599 0x110E0 #define IXGBE_BAR_CTRL_82599 0x110F4 +/* PCI Express Control */ +#define IXGBE_GCR_CMPL_TMOUT_MASK 0x0000F000 +#define IXGBE_GCR_CMPL_TMOUT_10ms 0x00001000 +#define IXGBE_GCR_CMPL_TMOUT_RESEND 0x00010000 +#define IXGBE_GCR_CAP_VER2 0x00040000 + +#define IXGBE_GCR_EXT_MSIX_EN 0x80000000 +#define IXGBE_GCR_EXT_VT_MODE_16 0x00000001 +#define IXGBE_GCR_EXT_VT_MODE_32 0x00000002 +#define IXGBE_GCR_EXT_VT_MODE_64 0x00000003 +#define IXGBE_GCR_EXT_SRIOV (IXGBE_GCR_EXT_MSIX_EN | \ + IXGBE_GCR_EXT_VT_MODE_64) /* Time Sync Registers */ #define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */ #define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */ @@ -848,12 +868,16 @@ #define IXGBE_MPVC 0x04318 #define IXGBE_SGMIIC 0x04314 +/* Copper Pond 2 link timeout */ +#define IXGBE_VALIDATE_LINK_READY_TIMEOUT 50 + /* Omer CORECTL */ #define IXGBE_CORECTL 0x014F00 /* BARCTRL */ -#define IXGBE_BARCTRL 0x110F4 -#define IXGBE_BARCTRL_FLSIZE 0x0700 -#define IXGBE_BARCTRL_CSRSIZE 0x2000 +#define IXGBE_BARCTRL 0x110F4 +#define IXGBE_BARCTRL_FLSIZE 0x0700 +#define IXGBE_BARCTRL_FLSIZE_SHIFT 8 +#define IXGBE_BARCTRL_CSRSIZE 0x2000 /* RSCCTL Bit Masks */ #define IXGBE_RSCCTL_RSCEN 0x01 @@ -874,6 +898,8 @@ #define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */ #define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000 /* RSC First packet size */ #define IXGBE_RDRXCTL_RSCLLIDIS 0x00800000 /* Disable RSC compl on LLI */ +#define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC enabled */ +#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC enabled */ /* RQTC Bit Masks and Shifts */ #define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4) @@ -1005,7 +1031,9 @@ #define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */ #define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */ #define IXGBE_MDIO_PHY_100BASETX_ABILITY 0x0080 /* 100BaseTX capable */ +#define IXGBE_MDIO_PHY_SET_LOW_POWER_MODE 0x0800 /* Set low power mode */ +#define IXGBE_MDIO_PMA_PMD_CONTROL_ADDR 0x0000 /* PMA/PMD Control Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */ @@ -1013,10 +1041,18 @@ /* MII clause 22/28 definitions */ #define IXGBE_MDIO_PHY_LOW_POWER_MODE 0x0800 -#define IXGBE_MII_SPEED_SELECTION_REG 0x10 -#define IXGBE_MII_RESTART 0x200 -#define IXGBE_MII_AUTONEG_COMPLETE 0x20 -#define IXGBE_MII_AUTONEG_REG 0x0 +#define IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG 0x20 /* 10G Control Reg */ +#define IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG 0xC400 /* 1G Provisioning 1 */ +#define IXGBE_MII_AUTONEG_XNP_TX_REG 0x17 /* 1G XNP Transmit */ +#define IXGBE_MII_AUTONEG_ADVERTISE_REG 0x10 /* 100M Advertisement */ +#define IXGBE_MII_10GBASE_T_ADVERTISE 0x1000 /* full duplex, bit:12*/ +#define IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX 0x4000 /* full duplex, bit:14*/ +#define IXGBE_MII_1GBASE_T_ADVERTISE 0x8000 /* full duplex, bit:15*/ +#define IXGBE_MII_100BASE_T_ADVERTISE 0x0100 /* full duplex, bit:8 */ +#define IXGBE_MII_RESTART 0x200 +#define IXGBE_MII_AUTONEG_COMPLETE 0x20 +#define IXGBE_MII_AUTONEG_LINK_UP 0x04 +#define IXGBE_MII_AUTONEG_REG 0x0 #define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0 #define IXGBE_MAX_PHY_ADDR 32 @@ -1346,10 +1382,12 @@ * EAPOL 802.1x (0x888e): Filter 0 * FCoE (0x8906): Filter 2 * 1588 (0x88f7): Filter 3 + * FIP (0x8914): Filter 4 */ #define IXGBE_ETQF_FILTER_EAPOL 0 #define IXGBE_ETQF_FILTER_FCOE 2 #define IXGBE_ETQF_FILTER_1588 3 +#define IXGBE_ETQF_FILTER_FIP 4 /* VLAN Control Bit Masks */ #define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */ #define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */ @@ -1408,6 +1446,8 @@ #define IXGBE_AUTOC_KX4_SUPP 0x80000000 #define IXGBE_AUTOC_KX_SUPP 0x40000000 #define IXGBE_AUTOC_PAUSE 0x30000000 +#define IXGBE_AUTOC_ASM_PAUSE 0x20000000 +#define IXGBE_AUTOC_SYM_PAUSE 0x10000000 #define IXGBE_AUTOC_RF 0x08000000 #define IXGBE_AUTOC_PD_TMR 0x06000000 #define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000 @@ -1451,6 +1491,7 @@ #define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) #define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) + /* LINKS Bit Masks */ #define IXGBE_LINKS_KX_AN_COMP 0x80000000 #define IXGBE_LINKS_UP 0x40000000 @@ -1476,6 +1517,8 @@ #define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ #define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ +#define IXGBE_LINKS2_AN_SUPPORTED 0x00000040 + /* PCS1GLSTA Bit Masks */ #define IXGBE_PCS1GLSTA_LINK_OK 1 #define IXGBE_PCS1GLSTA_SYNK_OK 0x10 @@ -1496,12 +1539,18 @@ #define IXGBE_PCS1GLCTL_AN_ENABLE 0x10000 #define IXGBE_PCS1GLCTL_AN_RESTART 0x20000 +/* ANLP1 Bit Masks */ +#define IXGBE_ANLP1_PAUSE 0x0C00 +#define IXGBE_ANLP1_SYM_PAUSE 0x0400 +#define IXGBE_ANLP1_ASM_PAUSE 0x0800 + /* SW Semaphore Register bitmasks */ #define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ #define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ #define IXGBE_SWSM_WMNG 0x00000004 /* Wake MNG Clock */ +#define IXGBE_SWFW_REGSMP 0x80000000 /* Register Semaphore bit 31 */ -/* GSSR definitions */ +/* SW_FW_SYNC/GSSR definitions */ #define IXGBE_GSSR_EEP_SM 0x0001 #define IXGBE_GSSR_PHY0_SM 0x0002 #define IXGBE_GSSR_PHY1_SM 0x0004 @@ -1521,20 +1570,24 @@ #define IXGBE_EEC_GNT 0x00000080 /* EEPROM Access Grant */ #define IXGBE_EEC_PRES 0x00000100 /* EEPROM Present */ #define IXGBE_EEC_ARD 0x00000200 /* EEPROM Auto Read Done */ +#define IXGBE_EEC_FLUP 0x00800000 /* Flash update command */ +#define IXGBE_EEC_FLUDONE 0x04000000 /* Flash update done */ /* EEPROM Addressing bits based on type (0-small, 1-large) */ #define IXGBE_EEC_ADDR_SIZE 0x00000400 #define IXGBE_EEC_SIZE 0x00007800 /* EEPROM Size */ -#define IXGBE_EEC_SIZE_SHIFT 11 -#define IXGBE_EEPROM_WORD_SIZE_SHIFT 6 -#define IXGBE_EEPROM_OPCODE_BITS 8 +#define IXGBE_EEC_SIZE_SHIFT 11 +#define IXGBE_EEPROM_WORD_SIZE_BASE_SHIFT 6 +#define IXGBE_EEPROM_OPCODE_BITS 8 /* Checksum and EEPROM pointers */ #define IXGBE_EEPROM_CHECKSUM 0x3F #define IXGBE_EEPROM_SUM 0xBABA #define IXGBE_PCIE_ANALOG_PTR 0x03 #define IXGBE_ATLAS0_CONFIG_PTR 0x04 +#define IXGBE_PHY_PTR 0x04 #define IXGBE_ATLAS1_CONFIG_PTR 0x05 +#define IXGBE_OPTION_ROM_PTR 0x05 #define IXGBE_PCIE_GENERAL_PTR 0x06 #define IXGBE_PCIE_CONFIG0_PTR 0x07 #define IXGBE_PCIE_CONFIG1_PTR 0x08 @@ -1577,10 +1630,12 @@ #define IXGBE_EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */ /* EEPROM Read Register */ -#define IXGBE_EEPROM_READ_REG_DATA 16 /* data offset in EEPROM read reg */ -#define IXGBE_EEPROM_READ_REG_DONE 2 /* Offset to READ done bit */ -#define IXGBE_EEPROM_READ_REG_START 1 /* First bit to start operation */ -#define IXGBE_EEPROM_READ_ADDR_SHIFT 2 /* Shift to the address bits */ +#define IXGBE_EEPROM_RW_REG_DATA 16 /* data offset in EEPROM read reg */ +#define IXGBE_EEPROM_RW_REG_DONE 2 /* Offset to READ done bit */ +#define IXGBE_EEPROM_RW_REG_START 1 /* First bit to start operation */ +#define IXGBE_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ +#define IXGBE_NVM_POLL_WRITE 1 /* Flag for polling for write complete */ +#define IXGBE_NVM_POLL_READ 0 /* Flag for polling for read complete */ #define IXGBE_ETH_LENGTH_OF_ADDRESS 6 @@ -1588,10 +1643,12 @@ #define IXGBE_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */ #endif -#ifndef IXGBE_EERD_ATTEMPTS -/* Number of 5 microseconds we wait for EERD read to complete */ -#define IXGBE_EERD_ATTEMPTS 100000 -#endif +/* Number of 5 microseconds we wait for EERD read and + * EERW write to complete */ +#define IXGBE_EERD_EEWR_ATTEMPTS 100000 + +/* # attempts we wait for flush update to complete */ +#define IXGBE_FLUDONE_ATTEMPTS 20000 #define IXGBE_PCIE_CTRL2 0x5 /* PCIe Control 2 Offset */ #define IXGBE_PCIE_CTRL2_DUMMY_ENABLE 0x8 /* Dummy Function Enable */ @@ -1604,9 +1661,20 @@ #define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2 #define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4 #define IXGBE_FW_PATCH_VERSION_4 0x7 +#define IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR 0x27 /* Alt. SAN MAC block */ +#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET 0x0 /* Alt. SAN MAC capability */ +#define IXGBE_ALT_SAN_MAC_ADDR_PORT0_OFFSET 0x1 /* Alt. SAN MAC 0 offset */ +#define IXGBE_ALT_SAN_MAC_ADDR_PORT1_OFFSET 0x4 /* Alt. SAN MAC 1 offset */ +#define IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET 0x7 /* Alt. WWNN prefix offset */ +#define IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET 0x8 /* Alt. WWPN prefix offset */ +#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_SANMAC 0x0 /* Alt. SAN MAC exists */ +#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN 0x1 /* Alt. WWN base exists */ /* PCI Bus Info */ +#define IXGBE_PCI_DEVICE_STATUS 0xAA +#define IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING 0x0020 #define IXGBE_PCI_LINK_STATUS 0xB2 +#define IXGBE_PCI_DEVICE_CONTROL2 0xC8 #define IXGBE_PCI_LINK_WIDTH 0x3F0 #define IXGBE_PCI_LINK_WIDTH_1 0x10 #define IXGBE_PCI_LINK_WIDTH_2 0x20 @@ -1617,6 +1685,7 @@ #define IXGBE_PCI_LINK_SPEED_5000 0x2 #define IXGBE_PCI_HEADER_TYPE_REGISTER 0x0E #define IXGBE_PCI_HEADER_TYPE_MULTIFUNC 0x80 +#define IXGBE_PCI_DEVICE_CONTROL2_16ms 0x0005 /* Number of 100 microseconds we wait for PCI Express master disable */ #define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800 @@ -1736,6 +1805,7 @@ #define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */ #define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */ #define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */ +#define IXGBE_MTQC_4TC_4TQ 0x8 /* 4 TC if RT_ENA and VT_ENA */ #define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */ /* Receive Descriptor bit definitions */ @@ -1949,10 +2019,9 @@ enum ixgbe_fdir_pballoc_type { #define IXGBE_FDIRM_VLANID 0x00000001 #define IXGBE_FDIRM_VLANP 0x00000002 #define IXGBE_FDIRM_POOL 0x00000004 -#define IXGBE_FDIRM_L3P 0x00000008 -#define IXGBE_FDIRM_L4P 0x00000010 -#define IXGBE_FDIRM_FLEX 0x00000020 -#define IXGBE_FDIRM_DIPv6 0x00000040 +#define IXGBE_FDIRM_L4P 0x00000008 +#define IXGBE_FDIRM_FLEX 0x00000010 +#define IXGBE_FDIRM_DIPv6 0x00000020 #define IXGBE_FDIRFREE_FREE_MASK 0xFFFF #define IXGBE_FDIRFREE_FREE_SHIFT 0 @@ -2167,6 +2236,8 @@ typedef u32 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400 #define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800 #define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000 +#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000 + /* Software ATR hash keys */ #define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D @@ -2207,9 +2278,19 @@ struct ixgbe_atr_input { u8 byte_stream[42]; }; +struct ixgbe_atr_input_masks { + u32 src_ip_mask; + u32 dst_ip_mask; + u16 src_port_mask; + u16 dst_port_mask; + u16 vlan_id_mask; + u16 data_mask; +}; + enum ixgbe_eeprom_type { ixgbe_eeprom_uninitialized = 0, ixgbe_eeprom_spi, + ixgbe_flash, ixgbe_eeprom_none /* No NVM support */ }; @@ -2229,10 +2310,12 @@ enum ixgbe_phy_type { ixgbe_phy_qt, ixgbe_phy_xaui, ixgbe_phy_nl, - ixgbe_phy_tw_tyco, - ixgbe_phy_tw_unknown, + ixgbe_phy_sfp_passive_tyco, + ixgbe_phy_sfp_passive_unknown, + ixgbe_phy_sfp_active_unknown, ixgbe_phy_sfp_avago, ixgbe_phy_sfp_ftl, + ixgbe_phy_sfp_ftl_active, ixgbe_phy_sfp_unknown, ixgbe_phy_sfp_intel, ixgbe_phy_sfp_unsupported, /*Enforce bit set with unsupported module*/ @@ -2260,6 +2343,8 @@ enum ixgbe_sfp_type { ixgbe_sfp_type_da_cu_core1 = 4, ixgbe_sfp_type_srlr_core0 = 5, ixgbe_sfp_type_srlr_core1 = 6, + ixgbe_sfp_type_da_act_lmt_core0 = 7, + ixgbe_sfp_type_da_act_lmt_core1 = 8, ixgbe_sfp_type_not_present = 0xFFFE, ixgbe_sfp_type_unknown = 0xFFFF }; @@ -2269,6 +2354,7 @@ enum ixgbe_media_type { ixgbe_media_type_fiber, ixgbe_media_type_copper, ixgbe_media_type_backplane, + ixgbe_media_type_cx4, ixgbe_media_type_virtual }; @@ -2281,6 +2367,14 @@ enum ixgbe_fc_mode { ixgbe_fc_default }; +/* Smart Speed Settings */ +#define IXGBE_SMARTSPEED_MAX_RETRIES 3 +enum ixgbe_smart_speed { + ixgbe_smart_speed_auto = 0, + ixgbe_smart_speed_on, + ixgbe_smart_speed_off +}; + /* PCI bus types */ enum ixgbe_bus_type { ixgbe_bus_type_unknown = 0, @@ -2293,25 +2387,25 @@ enum ixgbe_bus_type { /* PCI bus speeds */ enum ixgbe_bus_speed { ixgbe_bus_speed_unknown = 0, - ixgbe_bus_speed_33, - ixgbe_bus_speed_66, - ixgbe_bus_speed_100, - ixgbe_bus_speed_120, - ixgbe_bus_speed_133, - ixgbe_bus_speed_2500, - ixgbe_bus_speed_5000, + ixgbe_bus_speed_33 = 33, + ixgbe_bus_speed_66 = 66, + ixgbe_bus_speed_100 = 100, + ixgbe_bus_speed_120 = 120, + ixgbe_bus_speed_133 = 133, + ixgbe_bus_speed_2500 = 2500, + ixgbe_bus_speed_5000 = 5000, ixgbe_bus_speed_reserved }; /* PCI bus widths */ enum ixgbe_bus_width { ixgbe_bus_width_unknown = 0, - ixgbe_bus_width_pcie_x1, - ixgbe_bus_width_pcie_x2, + ixgbe_bus_width_pcie_x1 = 1, + ixgbe_bus_width_pcie_x2 = 2, ixgbe_bus_width_pcie_x4 = 4, ixgbe_bus_width_pcie_x8 = 8, - ixgbe_bus_width_32, - ixgbe_bus_width_64, + ixgbe_bus_width_32 = 32, + ixgbe_bus_width_64 = 64, ixgbe_bus_width_reserved }; @@ -2434,6 +2528,7 @@ struct ixgbe_eeprom_operations { s32 (*write)(struct ixgbe_hw *, u16, u16); s32 (*validate_checksum)(struct ixgbe_hw *, u16 *); s32 (*update_checksum)(struct ixgbe_hw *); + u16 (*calc_checksum)(struct ixgbe_hw *); }; struct ixgbe_mac_operations { @@ -2441,12 +2536,14 @@ struct ixgbe_mac_operations { s32 (*reset_hw)(struct ixgbe_hw *); s32 (*start_hw)(struct ixgbe_hw *); s32 (*clear_hw_cntrs)(struct ixgbe_hw *); + void (*enable_relaxed_ordering)(struct ixgbe_hw *); enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); u32 (*get_supported_physical_layer)(struct ixgbe_hw *); s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *); s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *); s32 (*set_san_mac_addr)(struct ixgbe_hw *, u8 *); s32 (*get_device_caps)(struct ixgbe_hw *, u16 *); + s32 (*get_wwn_prefix)(struct ixgbe_hw *, u16 *, u16 *); s32 (*stop_adapter)(struct ixgbe_hw *); s32 (*get_bus_info)(struct ixgbe_hw *); void (*set_lan_id)(struct ixgbe_hw *); @@ -2458,9 +2555,7 @@ struct ixgbe_mac_operations { void (*release_swfw_sync)(struct ixgbe_hw *, u16); /* Link */ - s32 (*setup_link)(struct ixgbe_hw *); - s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool, - bool); + s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool); s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, bool *); @@ -2509,6 +2604,8 @@ struct ixgbe_phy_operations { s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); void (*i2c_bus_clear)(struct ixgbe_hw *); + s32 (*check_overtemp)(struct ixgbe_hw *); + s32 (*set_low_power_state)(struct ixgbe_hw *); }; struct ixgbe_eeprom_info { @@ -2519,12 +2616,17 @@ struct ixgbe_eeprom_info { u16 address_bits; }; +#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01 struct ixgbe_mac_info { struct ixgbe_mac_operations ops; enum ixgbe_mac_type type; u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; u8 san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; + /* prefix for World Wide Node Name (WWNN) */ + u16 wwnn_prefix; + /* prefix for World Wide Port Name (WWPN) */ + u16 wwpn_prefix; s32 mc_filter_type; u32 mcft_size; u32 vft_size; @@ -2537,9 +2639,8 @@ struct ixgbe_mac_info { u32 orig_autoc; u32 orig_autoc2; bool orig_link_settings_stored; - bool autoneg; - bool autoneg_succeeded; bool autotry_restart; + u8 flags; }; struct ixgbe_phy_info { @@ -2553,7 +2654,8 @@ struct ixgbe_phy_info { enum ixgbe_media_type media_type; bool reset_disable; ixgbe_autoneg_advertised autoneg_advertised; - bool autoneg_wait_to_complete; + enum ixgbe_smart_speed smart_speed; + bool smart_speed_active; bool multispeed_fiber; }; @@ -2604,6 +2706,8 @@ struct ixgbe_hw { #define IXGBE_ERR_NO_SAN_ADDR_PTR -22 #define IXGBE_ERR_FDIR_REINIT_FAILED -23 #define IXGBE_ERR_EEPROM_VERSION -24 +#define IXGBE_ERR_NO_SPACE -25 +#define IXGBE_ERR_OVERTEMP -26 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF From d05b20c60cbb95d7ca1748de74c18e404a2b0475 Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Mon, 5 Apr 2010 20:39:44 +0000 Subject: [PATCH 1835/2592] MFC of the em/igb drivers --- sys/conf/files | 2 + sys/dev/e1000/LICENSE | 2 +- sys/dev/e1000/e1000_80003es2lan.c | 278 +- sys/dev/e1000/e1000_80003es2lan.h | 12 +- sys/dev/e1000/e1000_82540.c | 4 +- sys/dev/e1000/e1000_82541.c | 39 +- sys/dev/e1000/e1000_82542.c | 4 +- sys/dev/e1000/e1000_82543.c | 86 +- sys/dev/e1000/e1000_82571.c | 236 +- sys/dev/e1000/e1000_82575.c | 790 +++-- sys/dev/e1000/e1000_82575.h | 84 +- sys/dev/e1000/e1000_api.c | 38 +- sys/dev/e1000/e1000_api.h | 4 +- sys/dev/e1000/e1000_defines.h | 113 +- sys/dev/e1000/e1000_hw.h | 32 +- sys/dev/e1000/e1000_ich8lan.c | 1039 +++++-- sys/dev/e1000/e1000_ich8lan.h | 38 +- sys/dev/e1000/e1000_mac.c | 127 +- sys/dev/e1000/e1000_mac.h | 4 +- sys/dev/e1000/e1000_manage.c | 70 +- sys/dev/e1000/e1000_osdep.h | 43 +- sys/dev/e1000/e1000_phy.c | 890 ++++-- sys/dev/e1000/e1000_phy.h | 24 +- sys/dev/e1000/e1000_regs.h | 57 +- sys/dev/e1000/if_em.c | 3632 ++++++++++------------ sys/dev/e1000/if_em.h | 240 +- sys/dev/e1000/if_igb.c | 2424 ++++++++------- sys/dev/e1000/if_igb.h | 131 +- sys/dev/e1000/if_lem.c | 4706 +++++++++++++++++++++++++++++ sys/dev/e1000/if_lem.h | 481 +++ 30 files changed, 10816 insertions(+), 4814 deletions(-) create mode 100644 sys/dev/e1000/if_lem.c create mode 100644 sys/dev/e1000/if_lem.h diff --git a/sys/conf/files b/sys/conf/files index d4de3668a10..86e9d472152 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -899,6 +899,8 @@ dev/eisa/eisa_if.m standard dev/eisa/eisaconf.c optional eisa dev/e1000/if_em.c optional em inet \ compile-with "${NORMAL_C} -I$S/dev/e1000" +dev/e1000/if_lem.c optional em inet \ + compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/if_igb.c optional igb inet \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_80003es2lan.c optional em | igb \ diff --git a/sys/dev/e1000/LICENSE b/sys/dev/e1000/LICENSE index d3f8bf5f367..f70a7cbd4a1 100644 --- a/sys/dev/e1000/LICENSE +++ b/sys/dev/e1000/LICENSE @@ -1,6 +1,6 @@ $FreeBSD$ - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/e1000/e1000_80003es2lan.c b/sys/dev/e1000/e1000_80003es2lan.c index 5c060869cf9..af32ee0f1fc 100644 --- a/sys/dev/e1000/e1000_80003es2lan.c +++ b/sys/dev/e1000/e1000_80003es2lan.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -171,7 +171,7 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) break; } - nvm->type = e1000_nvm_eeprom_spi; + nvm->type = e1000_nvm_eeprom_spi; size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); @@ -206,17 +206,22 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_mac_params_80003es2lan"); - /* Set media type */ + /* Set media type and media-dependent function pointers */ switch (hw->device_id) { case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: hw->phy.media_type = e1000_media_type_internal_serdes; + mac->ops.check_for_link = e1000_check_for_serdes_link_generic; + mac->ops.setup_physical_interface = + e1000_setup_fiber_serdes_link_generic; break; default: hw->phy.media_type = e1000_media_type_copper; + mac->ops.check_for_link = e1000_check_for_copper_link_generic; + mac->ops.setup_physical_interface = + e1000_setup_copper_link_80003es2lan; break; } @@ -226,10 +231,14 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) mac->rar_entry_count = E1000_RAR_ENTRIES; /* Set if part includes ASF firmware */ mac->asf_firmware_present = TRUE; - /* Set if manageability features are enabled. */ + /* FWSM register */ + mac->has_fwsm = TRUE; + /* ARC supported; valid only if manageability features are enabled. */ mac->arc_subsystem_valid = (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK) ? TRUE : FALSE; + /* Adaptive IFS not supported */ + mac->adaptive_ifs = FALSE; /* Function pointers */ @@ -241,27 +250,6 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) mac->ops.init_hw = e1000_init_hw_80003es2lan; /* link setup */ mac->ops.setup_link = e1000_setup_link_generic; - /* physical interface link setup */ - mac->ops.setup_physical_interface = - (hw->phy.media_type == e1000_media_type_copper) - ? e1000_setup_copper_link_80003es2lan - : e1000_setup_fiber_serdes_link_generic; - /* check for link */ - switch (hw->phy.media_type) { - case e1000_media_type_copper: - mac->ops.check_for_link = e1000_check_for_copper_link_generic; - break; - case e1000_media_type_fiber: - mac->ops.check_for_link = e1000_check_for_fiber_link_generic; - break; - case e1000_media_type_internal_serdes: - mac->ops.check_for_link = e1000_check_for_serdes_link_generic; - break; - default: - ret_val = -E1000_ERR_CONFIG; - goto out; - break; - } /* check management mode */ mac->ops.check_mng_mode = e1000_check_mng_mode_generic; /* multicast address update */ @@ -270,8 +258,6 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; /* read mac address */ mac->ops.read_mac_addr = e1000_read_mac_addr_80003es2lan; /* ID LED init */ @@ -290,8 +276,10 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) /* link info */ mac->ops.get_link_up_info = e1000_get_link_up_info_80003es2lan; -out: - return ret_val; + /* set lan id for port to determine which phy lock to use */ + hw->mac.ops.set_lan_id(hw); + + return E1000_SUCCESS; } /** @@ -307,7 +295,6 @@ void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) hw->mac.ops.init_params = e1000_init_mac_params_80003es2lan; hw->nvm.ops.init_params = e1000_init_nvm_params_80003es2lan; hw->phy.ops.init_params = e1000_init_phy_params_80003es2lan; - e1000_get_bus_info_pcie_generic(hw); } /** @@ -342,7 +329,6 @@ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw) e1000_release_swfw_sync_80003es2lan(hw, mask); } - /** * e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register * @hw: pointer to the HW structure @@ -532,28 +518,36 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, goto out; } - /* - * The "ready" bit in the MDIC register may be incorrectly set - * before the device has completed the "Page Select" MDI - * transaction. So we wait 200us after each MDI command... - */ - usec_delay(200); + if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) { + /* + * The "ready" bit in the MDIC register may be incorrectly set + * before the device has completed the "Page Select" MDI + * transaction. So we wait 200us after each MDI command... + */ + usec_delay(200); - /* ...and verify the command was successful. */ - ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); + /* ...and verify the command was successful. */ + ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); - if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { - ret_val = -E1000_ERR_PHY; - e1000_release_phy_80003es2lan(hw); - goto out; + if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { + ret_val = -E1000_ERR_PHY; + e1000_release_phy_80003es2lan(hw); + goto out; + } + + usec_delay(200); + + ret_val = e1000_read_phy_reg_mdic(hw, + MAX_PHY_REG_ADDRESS & offset, + data); + + usec_delay(200); + } else { + ret_val = e1000_read_phy_reg_mdic(hw, + MAX_PHY_REG_ADDRESS & offset, + data); } - usec_delay(200); - - ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); - - usec_delay(200); e1000_release_phy_80003es2lan(hw); out: @@ -599,29 +593,36 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, goto out; } + if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) { + /* + * The "ready" bit in the MDIC register may be incorrectly set + * before the device has completed the "Page Select" MDI + * transaction. So we wait 200us after each MDI command... + */ + usec_delay(200); - /* - * The "ready" bit in the MDIC register may be incorrectly set - * before the device has completed the "Page Select" MDI - * transaction. So we wait 200us after each MDI command... - */ - usec_delay(200); + /* ...and verify the command was successful. */ + ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); - /* ...and verify the command was successful. */ - ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); + if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { + ret_val = -E1000_ERR_PHY; + e1000_release_phy_80003es2lan(hw); + goto out; + } - if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { - ret_val = -E1000_ERR_PHY; - e1000_release_phy_80003es2lan(hw); - goto out; + usec_delay(200); + + ret_val = e1000_write_phy_reg_mdic(hw, + MAX_PHY_REG_ADDRESS & offset, + data); + + usec_delay(200); + } else { + ret_val = e1000_write_phy_reg_mdic(hw, + MAX_PHY_REG_ADDRESS & offset, + data); } - usec_delay(200); - - ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); - - usec_delay(200); e1000_release_phy_80003es2lan(hw); out: @@ -802,13 +803,13 @@ static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) index = phy_data & GG82563_DSPD_CABLE_LENGTH; - if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE + 5) { - ret_val = E1000_ERR_PHY; + if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) { + ret_val = -E1000_ERR_PHY; goto out; } phy->min_cable_length = e1000_gg82563_cable_length_table[index]; - phy->max_cable_length = e1000_gg82563_cable_length_table[index+5]; + phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5]; phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; @@ -916,10 +917,9 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* Initialize identification LED */ ret_val = mac->ops.id_led_init(hw); - if (ret_val) { + if (ret_val) DEBUGOUT("Error initializing identification LED\n"); /* This is not fatal and we should not stop init due to this */ - } /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); @@ -969,6 +969,19 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) reg_data &= ~0x00100000; E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data); + /* default to TRUE to enable the MDIC W/A */ + hw->dev_spec._80003es2lan.mdic_wa_enable = TRUE; + + ret_val = e1000_read_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET >> + E1000_KMRNCTRLSTA_OFFSET_SHIFT, + &i); + if (!ret_val) { + if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) == + E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO) + hw->dev_spec._80003es2lan.mdic_wa_enable = FALSE; + } + /* * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link @@ -1035,72 +1048,73 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan"); - if (!phy->reset_disable) { - ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, - &data); - if (ret_val) - goto out; + if (phy->reset_disable) + goto skip_reset; - data |= GG82563_MSCR_ASSERT_CRS_ON_TX; - /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ - data |= GG82563_MSCR_TX_CLK_1000MBPS_25; + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, + &data); + if (ret_val) + goto out; - ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, - data); - if (ret_val) - goto out; + data |= GG82563_MSCR_ASSERT_CRS_ON_TX; + /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ + data |= GG82563_MSCR_TX_CLK_1000MBPS_25; - /* - * Options: - * MDI/MDI-X = 0 (default) - * 0 - Auto for all speeds - * 1 - MDI mode - * 2 - MDI-X mode - * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) - */ - ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data); - if (ret_val) - goto out; + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, + data); + if (ret_val) + goto out; - data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; + /* + * Options: + * MDI/MDI-X = 0 (default) + * 0 - Auto for all speeds + * 1 - MDI mode + * 2 - MDI-X mode + * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) + */ + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data); + if (ret_val) + goto out; - switch (phy->mdix) { - case 1: - data |= GG82563_PSCR_CROSSOVER_MODE_MDI; - break; - case 2: - data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; - break; - case 0: - default: - data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; - break; - } - - /* - * Options: - * disable_polarity_correction = 0 (default) - * Automatic Correction for Reversed Cable Polarity - * 0 - Disabled - * 1 - Enabled - */ - data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - if (phy->disable_polarity_correction) - data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - - ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data); - if (ret_val) - goto out; - - /* SW Reset the PHY so all changes take effect */ - ret_val = hw->phy.ops.commit(hw); - if (ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - goto out; - } + data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; + switch (phy->mdix) { + case 1: + data |= GG82563_PSCR_CROSSOVER_MODE_MDI; + break; + case 2: + data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; + break; + case 0: + default: + data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; + break; } + /* + * Options: + * disable_polarity_correction = 0 (default) + * Automatic Correction for Reversed Cable Polarity + * 0 - Disabled + * 1 - Enabled + */ + data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; + if (phy->disable_polarity_correction) + data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; + + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data); + if (ret_val) + goto out; + + /* SW Reset the PHY so all changes take effect */ + ret_val = hw->phy.ops.commit(hw); + if (ret_val) { + DEBUGOUT("Error Resetting the PHY\n"); + goto out; + } + +skip_reset: /* Bypass Rx and Tx FIFO's */ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL, @@ -1303,7 +1317,6 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN; E1000_WRITE_REG(hw, E1000_TIPG, tipg); - do { ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); @@ -1357,7 +1370,6 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; E1000_WRITE_REG(hw, E1000_TIPG, tipg); - do { ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); diff --git a/sys/dev/e1000/e1000_80003es2lan.h b/sys/dev/e1000/e1000_80003es2lan.h index 7bf8d9d5436..3ab1ec9d04e 100644 --- a/sys/dev/e1000/e1000_80003es2lan.h +++ b/sys/dev/e1000/e1000_80003es2lan.h @@ -1,6 +1,6 @@ -/******************************************************************************* +/****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _E1000_80003ES2LAN_H_ #define _E1000_80003ES2LAN_H_ @@ -49,6 +48,9 @@ #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 #define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 +#define E1000_KMRNCTRLSTA_OPMODE_MASK 0x000C +#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO 0x0004 + #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 diff --git a/sys/dev/e1000/e1000_82540.c b/sys/dev/e1000/e1000_82540.c index 14dcbb3e35d..80a5877725c 100644 --- a/sys/dev/e1000/e1000_82540.c +++ b/sys/dev/e1000/e1000_82540.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -228,8 +228,6 @@ static s32 e1000_init_mac_params_82540(struct e1000_hw *hw) mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; /* read mac address */ mac->ops.read_mac_addr = e1000_read_mac_addr_82540; /* ID LED init */ diff --git a/sys/dev/e1000/e1000_82541.c b/sys/dev/e1000/e1000_82541.c index 68d1b05a07b..fd8d8ebbe74 100644 --- a/sys/dev/e1000/e1000_82541.c +++ b/sys/dev/e1000/e1000_82541.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -59,6 +59,7 @@ static s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, static s32 e1000_setup_led_82541(struct e1000_hw *hw); static s32 e1000_cleanup_led_82541(struct e1000_hw *hw); static void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw); +static s32 e1000_read_mac_addr_82541(struct e1000_hw *hw); static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, bool link_up); static s32 e1000_phy_init_script_82541(struct e1000_hw *hw); @@ -259,8 +260,8 @@ static s32 e1000_init_mac_params_82541(struct e1000_hw *hw) mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; + /* read mac address */ + mac->ops.read_mac_addr = e1000_read_mac_addr_82541; /* ID LED init */ mac->ops.id_led_init = e1000_id_led_init_generic; /* setup LED */ @@ -1292,3 +1293,35 @@ static void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw) E1000_READ_REG(hw, E1000_MGTPDC); E1000_READ_REG(hw, E1000_MGTPTC); } + +/** + * e1000_read_mac_addr_82541 - Read device MAC address + * @hw: pointer to the HW structure + * + * Reads the device MAC address from the EEPROM and stores the value. + **/ +static s32 e1000_read_mac_addr_82541(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + u16 offset, nvm_data, i; + + DEBUGFUNC("e1000_read_mac_addr"); + + for (i = 0; i < ETH_ADDR_LEN; i += 2) { + offset = i >> 1; + ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); + if (ret_val) { + DEBUGOUT("NVM Read Error\n"); + goto out; + } + hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); + hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); + } + + for (i = 0; i < ETH_ADDR_LEN; i++) + hw->mac.addr[i] = hw->mac.perm_addr[i]; + +out: + return ret_val; +} + diff --git a/sys/dev/e1000/e1000_82542.c b/sys/dev/e1000/e1000_82542.c index 46ef66a0a51..282814bb893 100644 --- a/sys/dev/e1000/e1000_82542.c +++ b/sys/dev/e1000/e1000_82542.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -134,8 +134,6 @@ static s32 e1000_init_mac_params_82542(struct e1000_hw *hw) mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; /* read mac address */ mac->ops.read_mac_addr = e1000_read_mac_addr_82542; /* set RAR */ diff --git a/sys/dev/e1000/e1000_82543.c b/sys/dev/e1000/e1000_82543.c index 97c7f3b2044..4bb0cbdd5c3 100644 --- a/sys/dev/e1000/e1000_82543.c +++ b/sys/dev/e1000/e1000_82543.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -63,7 +63,6 @@ static s32 e1000_led_on_82543(struct e1000_hw *hw); static s32 e1000_led_off_82543(struct e1000_hw *hw); static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value); -static void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value); static void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw); static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw); static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw); @@ -75,6 +74,8 @@ static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data, u16 count); static bool e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw); static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state); +static s32 e1000_read_mac_addr_82543(struct e1000_hw *hw); + /** * e1000_init_phy_params_82543 - Init PHY func ptrs. @@ -244,8 +245,8 @@ static s32 e1000_init_mac_params_82543(struct e1000_hw *hw) mac->ops.write_vfta = e1000_write_vfta_82543; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_82543; + /* read mac address */ + mac->ops.read_mac_addr = e1000_read_mac_addr_82543; /* turn on/off LED */ mac->ops.led_on = e1000_led_on_82543; mac->ops.led_off = e1000_led_off_82543; @@ -1476,45 +1477,6 @@ static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value) } } -/** - * e1000_mta_set_82543 - Set multicast filter table address - * @hw: pointer to the HW structure - * @hash_value: determines the MTA register and bit to set - * - * The multicast table address is a register array of 32-bit registers. - * The hash_value is used to determine what register the bit is in, the - * current value is read, the new bit is OR'd in and the new value is - * written back into the register. - **/ -static void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value) -{ - u32 hash_bit, hash_reg, mta, temp; - - DEBUGFUNC("e1000_mta_set_82543"); - - hash_reg = (hash_value >> 5); - - /* - * If we are on an 82544 and we are trying to write an odd offset - * in the MTA, save off the previous entry before writing and - * restore the old value after writing. - */ - if ((hw->mac.type == e1000_82544) && (hash_reg & 1)) { - hash_reg &= (hw->mac.mta_reg_count - 1); - hash_bit = hash_value & 0x1F; - mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg); - mta |= (1 << hash_bit); - temp = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg - 1); - - E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta); - E1000_WRITE_FLUSH(hw); - E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg - 1, temp); - E1000_WRITE_FLUSH(hw); - } else { - e1000_mta_set_generic(hw, hash_value); - } -} - /** * e1000_led_on_82543 - Turn on SW controllable LED * @hw: pointer to the HW structure @@ -1600,3 +1562,41 @@ static void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw) E1000_READ_REG(hw, E1000_TSCTC); E1000_READ_REG(hw, E1000_TSCTFC); } + +/** + * e1000_read_mac_addr_82543 - Read device MAC address + * @hw: pointer to the HW structure + * + * Reads the device MAC address from the EEPROM and stores the value. + * Since devices with two ports use the same EEPROM, we increment the + * last bit in the MAC address for the second port. + * + **/ +s32 e1000_read_mac_addr_82543(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + u16 offset, nvm_data, i; + + DEBUGFUNC("e1000_read_mac_addr"); + + for (i = 0; i < ETH_ADDR_LEN; i += 2) { + offset = i >> 1; + ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); + if (ret_val) { + DEBUGOUT("NVM Read Error\n"); + goto out; + } + hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); + hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); + } + + /* Flip last bit of mac address if we're on second port */ + if (hw->bus.func == E1000_FUNC_1) + hw->mac.perm_addr[5] ^= 1; + + for (i = 0; i < ETH_ADDR_LEN; i++) + hw->mac.addr[i] = hw->mac.perm_addr[i]; + +out: + return ret_val; +} diff --git a/sys/dev/e1000/e1000_82571.c b/sys/dev/e1000/e1000_82571.c index 18fe745b14a..afeb1a05e5c 100644 --- a/sys/dev/e1000/e1000_82571.c +++ b/sys/dev/e1000/e1000_82571.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -46,7 +46,6 @@ * 82573E Gigabit Ethernet Controller (Copper) * 82573L Gigabit Ethernet Controller * 82574L Gigabit Network Connection - * 82574L Gigabit Network Connection * 82583V Gigabit Network Connection */ @@ -106,7 +105,6 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) phy->reset_delay_us = 100; phy->ops.acquire = e1000_get_hw_semaphore_82571; - phy->ops.check_polarity = e1000_check_polarity_igp; phy->ops.check_reset_block = e1000_check_reset_block_generic; phy->ops.release = e1000_put_hw_semaphore_82571; phy->ops.reset = e1000_phy_hw_reset_generic; @@ -121,6 +119,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) phy->type = e1000_phy_igp_2; phy->ops.get_cfg_done = e1000_get_cfg_done_82571; phy->ops.get_info = e1000_get_phy_info_igp; + phy->ops.check_polarity = e1000_check_polarity_igp; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp; phy->ops.get_cable_length = e1000_get_cable_length_igp_2; phy->ops.read_reg = e1000_read_phy_reg_igp; @@ -132,6 +131,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) /* Verify PHY ID */ if (phy->id != IGP01E1000_I_PHY_ID) { ret_val = -E1000_ERR_PHY; + DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id); goto out; } break; @@ -139,6 +139,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) phy->type = e1000_phy_m88; phy->ops.get_cfg_done = e1000_get_cfg_done_generic; phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.check_polarity = e1000_check_polarity_m88; phy->ops.commit = e1000_phy_sw_reset_generic; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; phy->ops.get_cable_length = e1000_get_cable_length_m88; @@ -155,11 +156,12 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) goto out; } break; - case e1000_82583: case e1000_82574: + case e1000_82583: phy->type = e1000_phy_bm; phy->ops.get_cfg_done = e1000_get_cfg_done_generic; phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.check_polarity = e1000_check_polarity_m88; phy->ops.commit = e1000_phy_sw_reset_generic; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; phy->ops.get_cable_length = e1000_get_cable_length_m88; @@ -266,28 +268,42 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) static s32 e1000_init_mac_params_82571(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - s32 ret_val = E1000_SUCCESS; u32 swsm = 0; u32 swsm2 = 0; bool force_clear_smbi = FALSE; DEBUGFUNC("e1000_init_mac_params_82571"); - /* Set media type */ + /* Set media type and media-dependent function pointers */ switch (hw->device_id) { case E1000_DEV_ID_82571EB_FIBER: case E1000_DEV_ID_82572EI_FIBER: case E1000_DEV_ID_82571EB_QUAD_FIBER: hw->phy.media_type = e1000_media_type_fiber; + mac->ops.setup_physical_interface = + e1000_setup_fiber_serdes_link_82571; + mac->ops.check_for_link = e1000_check_for_fiber_link_generic; + mac->ops.get_link_up_info = + e1000_get_speed_and_duplex_fiber_serdes_generic; break; case E1000_DEV_ID_82571EB_SERDES: case E1000_DEV_ID_82571EB_SERDES_DUAL: case E1000_DEV_ID_82571EB_SERDES_QUAD: case E1000_DEV_ID_82572EI_SERDES: hw->phy.media_type = e1000_media_type_internal_serdes; + mac->ops.setup_physical_interface = + e1000_setup_fiber_serdes_link_82571; + mac->ops.check_for_link = e1000_check_for_serdes_link_82571; + mac->ops.get_link_up_info = + e1000_get_speed_and_duplex_fiber_serdes_generic; break; default: hw->phy.media_type = e1000_media_type_copper; + mac->ops.setup_physical_interface = + e1000_setup_copper_link_82571; + mac->ops.check_for_link = e1000_check_for_copper_link_generic; + mac->ops.get_link_up_info = + e1000_get_speed_and_duplex_copper_generic; break; } @@ -297,70 +313,25 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw) mac->rar_entry_count = E1000_RAR_ENTRIES; /* Set if part includes ASF firmware */ mac->asf_firmware_present = TRUE; - /* Set if manageability features are enabled. */ - mac->arc_subsystem_valid = - (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK) - ? TRUE : FALSE; + /* Adaptive IFS supported */ + mac->adaptive_ifs = TRUE; /* Function pointers */ /* bus type/speed/width */ mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic; - /* function id */ - switch (hw->mac.type) { - case e1000_82573: - case e1000_82574: - case e1000_82583: - mac->ops.set_lan_id = e1000_set_lan_id_single_port; - break; - default: - break; - } /* reset */ mac->ops.reset_hw = e1000_reset_hw_82571; /* hw initialization */ mac->ops.init_hw = e1000_init_hw_82571; /* link setup */ mac->ops.setup_link = e1000_setup_link_82571; - /* physical interface link setup */ - mac->ops.setup_physical_interface = - (hw->phy.media_type == e1000_media_type_copper) - ? e1000_setup_copper_link_82571 - : e1000_setup_fiber_serdes_link_82571; - /* check for link */ - switch (hw->phy.media_type) { - case e1000_media_type_copper: - mac->ops.check_for_link = e1000_check_for_copper_link_generic; - break; - case e1000_media_type_fiber: - mac->ops.check_for_link = e1000_check_for_fiber_link_generic; - break; - case e1000_media_type_internal_serdes: - mac->ops.check_for_link = e1000_check_for_serdes_link_82571; - break; - default: - ret_val = -E1000_ERR_CONFIG; - goto out; - break; - } - /* check management mode */ - switch (hw->mac.type) { - case e1000_82574: - case e1000_82583: - mac->ops.check_mng_mode = e1000_check_mng_mode_82574; - break; - default: - mac->ops.check_mng_mode = e1000_check_mng_mode_generic; - break; - } /* multicast address update */ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_82571; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; /* read mac address */ mac->ops.read_mac_addr = e1000_read_mac_addr_82571; /* ID LED init */ @@ -371,24 +342,42 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw) mac->ops.setup_led = e1000_setup_led_generic; /* cleanup LED */ mac->ops.cleanup_led = e1000_cleanup_led_generic; - /* turn on/off LED */ - switch (hw->mac.type) { - case e1000_82574: - case e1000_82583: - mac->ops.led_on = e1000_led_on_82574; - break; - default: - mac->ops.led_on = e1000_led_on_generic; - break; - } + /* turn off LED */ mac->ops.led_off = e1000_led_off_generic; /* clear hardware counters */ mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82571; - /* link info */ - mac->ops.get_link_up_info = - (hw->phy.media_type == e1000_media_type_copper) - ? e1000_get_speed_and_duplex_copper_generic - : e1000_get_speed_and_duplex_fiber_serdes_generic; + + /* MAC-specific function pointers */ + switch (hw->mac.type) { + case e1000_82573: + mac->ops.set_lan_id = e1000_set_lan_id_single_port; + mac->ops.check_mng_mode = e1000_check_mng_mode_generic; + mac->ops.led_on = e1000_led_on_generic; + + /* FWSM register */ + mac->has_fwsm = TRUE; + /* + * ARC supported; valid only if manageability features are + * enabled. + */ + mac->arc_subsystem_valid = + (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK) + ? TRUE : FALSE; + break; + case e1000_82574: + case e1000_82583: + mac->ops.set_lan_id = e1000_set_lan_id_single_port; + mac->ops.check_mng_mode = e1000_check_mng_mode_82574; + mac->ops.led_on = e1000_led_on_82574; + break; + default: + mac->ops.check_mng_mode = e1000_check_mng_mode_generic; + mac->ops.led_on = e1000_led_on_generic; + + /* FWSM register */ + mac->has_fwsm = TRUE; + break; + } /* * Ensure that the inter-port SWSM.SMBI lock bit is clear before @@ -434,8 +423,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw) */ hw->dev_spec._82571.smb_counter = 0; -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -501,7 +489,6 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) ret_val = -E1000_ERR_PHY; break; } - out: return ret_val; } @@ -512,7 +499,7 @@ out: * * Acquire the HW semaphore to access the PHY or NVM **/ -s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) +static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) { u32 swsm; s32 ret_val = E1000_SUCCESS; @@ -577,7 +564,7 @@ out: * * Release hardware semaphore used to access the PHY or NVM **/ -void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) +static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) { u32 swsm; @@ -610,9 +597,9 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) goto out; switch (hw->mac.type) { + case e1000_82573: case e1000_82574: case e1000_82583: - case e1000_82573: break; default: ret_val = e1000_acquire_nvm_generic(hw); @@ -831,7 +818,8 @@ static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) DEBUGFUNC("e1000_get_cfg_done_82571"); while (timeout) { - if (E1000_READ_REG(hw, E1000_EEMNGCTL) & E1000_NVM_CFG_DONE_PORT_0) + if (E1000_READ_REG(hw, E1000_EEMNGCTL) & + E1000_NVM_CFG_DONE_PORT_0) break; msec_delay(1); timeout--; @@ -966,9 +954,9 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) * Ownership defaults to firmware after a reset. */ switch (hw->mac.type) { + case e1000_82573: case e1000_82574: case e1000_82583: - case e1000_82573: extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; @@ -1014,9 +1002,9 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) */ switch (hw->mac.type) { + case e1000_82573: case e1000_82574: case e1000_82583: - case e1000_82573: msec_delay(25); break; default: @@ -1061,10 +1049,9 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) /* Initialize identification LED */ ret_val = mac->ops.id_led_init(hw); - if (ret_val) { + if (ret_val) DEBUGOUT("Error initializing identification LED\n"); /* This is not fatal and we should not stop init due to this */ - } /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); @@ -1097,10 +1084,11 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) /* ...for both queues. */ switch (mac->type) { - case e1000_82574: - case e1000_82583: case e1000_82573: e1000_enable_tx_pkt_filtering_generic(hw); + /* fall through */ + case e1000_82574: + case e1000_82583: reg_data = E1000_READ_REG(hw, E1000_GCR); reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; E1000_WRITE_REG(hw, E1000_GCR, reg_data); @@ -1108,8 +1096,8 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) default: reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | - E1000_TXDCTL_COUNT_DESC; + E1000_TXDCTL_FULL_TX_DESC_WB | + E1000_TXDCTL_COUNT_DESC; E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data); break; } @@ -1178,11 +1166,10 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) } /* Device Control */ - switch (hw->mac.type) { + case e1000_82573: case e1000_82574: case e1000_82583: - case e1000_82573: reg = E1000_READ_REG(hw, E1000_CTRL); reg &= ~(1 << 29); E1000_WRITE_REG(hw, E1000_CTRL, reg); @@ -1193,9 +1180,9 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) /* Extended Device Control */ switch (hw->mac.type) { + case e1000_82573: case e1000_82574: case e1000_82583: - case e1000_82573: reg = E1000_READ_REG(hw, E1000_CTRL_EXT); reg &= ~(1 << 23); reg |= (1 << 22); @@ -1205,7 +1192,6 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) break; } - if (hw->mac.type == e1000_82571) { reg = E1000_READ_REG(hw, E1000_PBA_ECC); reg |= E1000_PBA_ECC_CORR_EN; @@ -1216,7 +1202,6 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) * Workaround for hardware errata. * Ensure that DMA Dynamic Clock gating is disabled on 82571 and 82572 */ - if ((hw->mac.type == e1000_82571) || (hw->mac.type == e1000_82572)) { reg = E1000_READ_REG(hw, E1000_CTRL_EXT); @@ -1225,13 +1210,13 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) } /* PCI-Ex Control Registers */ - switch (hw->mac.type) { case e1000_82574: case e1000_82583: reg = E1000_READ_REG(hw, E1000_GCR); reg |= (1 << 22); E1000_WRITE_REG(hw, E1000_GCR, reg); + /* * Workaround for hardware errata. * apply workaround for hardware errata documented in errata @@ -1267,39 +1252,36 @@ static void e1000_clear_vfta_82571(struct e1000_hw *hw) DEBUGFUNC("e1000_clear_vfta_82571"); switch (hw->mac.type) { + case e1000_82573: case e1000_82574: case e1000_82583: - case e1000_82573: if (hw->mng_cookie.vlan_id != 0) { /* - *The VFTA is a 4096b bit-field, each identifying - *a single VLAN ID. The following operations - *determine which 32b entry (i.e. offset) into the - *array we want to set the VLAN ID (i.e. bit) of - *the manageability unit. - */ + * The VFTA is a 4096b bit-field, each identifying + * a single VLAN ID. The following operations + * determine which 32b entry (i.e. offset) into the + * array we want to set the VLAN ID (i.e. bit) of + * the manageability unit. + */ vfta_offset = (hw->mng_cookie.vlan_id >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK; vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id & E1000_VFTA_ENTRY_BIT_SHIFT_MASK); } - - for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { - /* - *If the offset we want to clear is the same offset of - *the manageability VLAN ID, then clear all bits except - *that of the manageability unit - */ - vfta_value = (offset == vfta_offset) ? - vfta_bit_in_reg : 0; - E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, - vfta_value); - E1000_WRITE_FLUSH(hw); - } break; default: break; } + for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { + /* + * If the offset we want to clear is the same offset of the + * manageability VLAN ID, then clear all bits except that of + * the manageability unit. + */ + vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0; + E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, vfta_value); + E1000_WRITE_FLUSH(hw); + } } /** @@ -1369,9 +1351,9 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw) * set it to full. */ switch (hw->mac.type) { + case e1000_82573: case e1000_82574: case e1000_82583: - case e1000_82573: if (hw->fc.requested_mode == e1000_fc_default) hw->fc.requested_mode = e1000_fc_full; break; @@ -1392,7 +1374,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw) static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) { u32 ctrl; - s32 ret_val; + s32 ret_val; DEBUGFUNC("e1000_setup_copper_link_82571"); @@ -1460,7 +1442,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) * Reports the link state as up or down. * * If autonegotiation is supported by the link partner, the link state is - * determined by the result of autongotiation. This is the most likely case. + * determined by the result of autonegotiation. This is the most likely case. * If autonegotiation is not supported by the link partner, and the link * has a valid signal, force the link up. * @@ -1472,7 +1454,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) * 4) forced_up (the link has been forced up, it did not autonegotiate) * **/ -s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) +static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 rxcw; @@ -1524,9 +1506,10 @@ s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) case e1000_serdes_link_autoneg_progress: if (rxcw & E1000_RXCW_C) { - /* We received /C/ ordered sets, meaning the + /* + * We received /C/ ordered sets, meaning the * link partner has autonegotiated, and we can - * trust the Link Up (LU) status bit + * trust the Link Up (LU) status bit. */ if (status & E1000_STATUS_LU) { mac->serdes_link_state = @@ -1534,13 +1517,14 @@ s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) DEBUGOUT("AN_PROG -> AN_UP\n"); mac->serdes_has_link = TRUE; } else { - /* Autoneg completed, but failed */ + /* Autoneg completed, but failed. */ mac->serdes_link_state = e1000_serdes_link_down; DEBUGOUT("AN_PROG -> DOWN\n"); } } else { - /* The link partner did not autoneg. + /* + * The link partner did not autoneg. * Force link up and full duplex, and change * state to forced. */ @@ -1565,9 +1549,11 @@ s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) case e1000_serdes_link_down: default: - /* The link was down but the receiver has now gained + /* + * The link was down but the receiver has now gained * valid sync, so lets see if we can bring the link - * up. */ + * up. + */ E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw); E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU)); @@ -1583,9 +1569,9 @@ s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) DEBUGOUT("ANYSTATE -> DOWN\n"); } else { /* - * We have sync, and can tolerate one - * invalid (IV) codeword before declaring - * link down, so reread to look again + * We have sync, and can tolerate one invalid (IV) + * codeword before declaring link down, so reread + * to look again. */ usec_delay(10); rxcw = E1000_READ_REG(hw, E1000_RXCW); @@ -1621,15 +1607,15 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) } switch (hw->mac.type) { + case e1000_82573: case e1000_82574: case e1000_82583: - case e1000_82573: - if(*data == ID_LED_RESERVED_F746) + if (*data == ID_LED_RESERVED_F746) *data = ID_LED_DEFAULT_82573; break; default: if (*data == ID_LED_RESERVED_0000 || - *data == ID_LED_RESERVED_FFFF) + *data == ID_LED_RESERVED_FFFF) *data = ID_LED_DEFAULT; break; } diff --git a/sys/dev/e1000/e1000_82575.c b/sys/dev/e1000/e1000_82575.c index 2f8e8ed31ed..65b3ce47a41 100644 --- a/sys/dev/e1000/e1000_82575.c +++ b/sys/dev/e1000/e1000_82575.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -59,16 +59,20 @@ static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw); static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 *data); static s32 e1000_reset_hw_82575(struct e1000_hw *hw); +static s32 e1000_reset_hw_82580(struct e1000_hw *hw); +static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw, + u32 offset, u16 *data); +static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, + u32 offset, u16 data); static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active); static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw); -static s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw); +static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw); static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data); static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 data); static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw); static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask); -static s32 e1000_configure_pcs_link_82575(struct e1000_hw *hw); static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, u16 *duplex); static s32 e1000_get_phy_id_82575(struct e1000_hw *hw); @@ -76,10 +80,18 @@ static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask); static bool e1000_sgmii_active_82575(struct e1000_hw *hw); static s32 e1000_reset_init_script_82575(struct e1000_hw *hw); static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw); +static void e1000_config_collision_dist_82575(struct e1000_hw *hw); static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw); -void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw); +static void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw); +static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw); static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw); +static const u16 e1000_82580_rxpbs_table[] = + { 36, 72, 144, 1, 2, 4, 8, 16, + 35, 70, 140 }; +#define E1000_82580_RXPBS_TABLE_SIZE \ + (sizeof(e1000_82580_rxpbs_table)/sizeof(u16)) + /** * e1000_init_phy_params_82575 - Init PHY func ptrs. * @hw: pointer to the HW structure @@ -94,11 +106,11 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) if (hw->phy.media_type != e1000_media_type_copper) { phy->type = e1000_phy_none; goto out; - } else { - phy->ops.power_up = e1000_power_up_phy_copper; - phy->ops.power_down = e1000_power_down_phy_copper_82575; } + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_82575; + phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; phy->reset_delay_us = 100; @@ -112,6 +124,10 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) phy->ops.reset = e1000_phy_hw_reset_sgmii_82575; phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575; phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575; + } else if (hw->mac.type >= e1000_82580) { + phy->ops.reset = e1000_phy_hw_reset_generic; + phy->ops.read_reg = e1000_read_phy_reg_82580; + phy->ops.write_reg = e1000_write_phy_reg_82580; } else { phy->ops.reset = e1000_phy_hw_reset_generic; phy->ops.read_reg = e1000_read_phy_reg_igp; @@ -140,6 +156,13 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575; phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; break; + case I82580_I_PHY_ID: + phy->type = e1000_phy_82580; + phy->ops.check_polarity = e1000_check_polarity_82577; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_82577; + phy->ops.get_cable_length = e1000_get_cable_length_82577; + phy->ops.get_info = e1000_get_phy_info_82577; + break; default: ret_val = -E1000_ERR_PHY; goto out; @@ -192,7 +215,7 @@ static s32 e1000_init_nvm_params_82575(struct e1000_hw *hw) /* EEPROM access above 16k is unsupported */ if (size > 14) size = 14; - nvm->word_size = 1 << size; + nvm->word_size = 1 << size; /* Function Pointers */ nvm->ops.acquire = e1000_acquire_nvm_82575; @@ -230,27 +253,45 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) dev_spec->sgmii_active = FALSE; ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); - if ((ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) == - E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES) { - hw->phy.media_type = e1000_media_type_internal_serdes; - ctrl_ext |= E1000_CTRL_I2C_ENA; - } else if (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII) { + switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) { + case E1000_CTRL_EXT_LINK_MODE_SGMII: dev_spec->sgmii_active = TRUE; ctrl_ext |= E1000_CTRL_I2C_ENA; - } else { + break; + case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: + case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: + hw->phy.media_type = e1000_media_type_internal_serdes; + ctrl_ext |= E1000_CTRL_I2C_ENA; + break; + default: ctrl_ext &= ~E1000_CTRL_I2C_ENA; + break; } + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); + /* + * if using i2c make certain the MDICNFG register is cleared to prevent + * communications from being misrouted to the mdic registers + */ + if ((ctrl_ext & E1000_CTRL_I2C_ENA) && (hw->mac.type == e1000_82580)) + E1000_WRITE_REG(hw, E1000_MDICNFG, 0); + /* Set mta register count */ mac->mta_reg_count = 128; + /* Set uta register count */ + mac->uta_reg_count = (hw->mac.type == e1000_82575) ? 0 : 128; /* Set rar entry count */ mac->rar_entry_count = E1000_RAR_ENTRIES_82575; if (mac->type == e1000_82576) mac->rar_entry_count = E1000_RAR_ENTRIES_82576; + if (mac->type == e1000_82580) + mac->rar_entry_count = E1000_RAR_ENTRIES_82580; /* Set if part includes ASF firmware */ mac->asf_firmware_present = TRUE; - /* Set if manageability features are enabled. */ + /* FWSM register */ + mac->has_fwsm = TRUE; + /* ARC supported; valid only if manageability features are enabled. */ mac->arc_subsystem_valid = (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK) ? TRUE : FALSE; @@ -260,6 +301,9 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) /* bus type/speed/width */ mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic; /* reset */ + if (mac->type >= e1000_82580) + mac->ops.reset_hw = e1000_reset_hw_82580; + else mac->ops.reset_hw = e1000_reset_hw_82575; /* hw initialization */ mac->ops.init_hw = e1000_init_hw_82575; @@ -269,23 +313,25 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_82575 - : e1000_setup_fiber_serdes_link_82575; + : e1000_setup_serdes_link_82575; /* physical interface shutdown */ - mac->ops.shutdown_serdes = e1000_shutdown_fiber_serdes_link_82575; + mac->ops.shutdown_serdes = e1000_shutdown_serdes_link_82575; + /* physical interface power up */ + mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575; /* check for link */ mac->ops.check_for_link = e1000_check_for_link_82575; /* receive address register setting */ mac->ops.rar_set = e1000_rar_set_generic; /* read mac address */ mac->ops.read_mac_addr = e1000_read_mac_addr_82575; + /* configure collision distance */ + mac->ops.config_collision_dist = e1000_config_collision_dist_82575; /* multicast address update */ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; /* ID LED init */ mac->ops.id_led_init = e1000_id_led_init_generic; /* blink LED */ @@ -302,6 +348,9 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) /* link info */ mac->ops.get_link_up_info = e1000_get_link_up_info_82575; + /* set lan id for port to determine which phy lock to use */ + hw->mac.ops.set_lan_id(hw); + return E1000_SUCCESS; } @@ -334,6 +383,10 @@ static s32 e1000_acquire_phy_82575(struct e1000_hw *hw) if (hw->bus.func == E1000_FUNC_1) mask = E1000_SWFW_PHY1_SM; + else if (hw->bus.func == E1000_FUNC_2) + mask = E1000_SWFW_PHY2_SM; + else if (hw->bus.func == E1000_FUNC_3) + mask = E1000_SWFW_PHY3_SM; return e1000_acquire_swfw_sync_82575(hw, mask); } @@ -352,6 +405,10 @@ static void e1000_release_phy_82575(struct e1000_hw *hw) if (hw->bus.func == E1000_FUNC_1) mask = E1000_SWFW_PHY1_SM; + else if (hw->bus.func == E1000_FUNC_2) + mask = E1000_SWFW_PHY2_SM; + else if (hw->bus.func == E1000_FUNC_3) + mask = E1000_SWFW_PHY3_SM; e1000_release_swfw_sync_82575(hw, mask); } @@ -368,47 +425,25 @@ static void e1000_release_phy_82575(struct e1000_hw *hw) static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 *data) { - struct e1000_phy_info *phy = &hw->phy; - u32 i, i2ccmd = 0; + s32 ret_val = -E1000_ERR_PARAM; DEBUGFUNC("e1000_read_phy_reg_sgmii_82575"); if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) { DEBUGOUT1("PHY Address %u is out of range\n", offset); - return -E1000_ERR_PARAM; + goto out; } - /* - * Set up Op-code, Phy Address, and register address in the I2CCMD - * register. The MAC will take care of interfacing with the - * PHY to retrieve the desired data. - */ - i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | - (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | - (E1000_I2CCMD_OPCODE_READ)); + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; - E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); + ret_val = e1000_read_phy_reg_i2c(hw, offset, data); - /* Poll the ready bit to see if the I2C read completed */ - for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { - usec_delay(50); - i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD); - if (i2ccmd & E1000_I2CCMD_READY) - break; - } - if (!(i2ccmd & E1000_I2CCMD_READY)) { - DEBUGOUT("I2CCMD Read did not complete\n"); - return -E1000_ERR_PHY; - } - if (i2ccmd & E1000_I2CCMD_ERROR) { - DEBUGOUT("I2CCMD Error bit set\n"); - return -E1000_ERR_PHY; - } + hw->phy.ops.release(hw); - /* Need to byte-swap the 16-bit value. */ - *data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00); - - return E1000_SUCCESS; +out: + return ret_val; } /** @@ -423,49 +458,25 @@ static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 data) { - struct e1000_phy_info *phy = &hw->phy; - u32 i, i2ccmd = 0; - u16 phy_data_swapped; + s32 ret_val = -E1000_ERR_PARAM; DEBUGFUNC("e1000_write_phy_reg_sgmii_82575"); if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) { DEBUGOUT1("PHY Address %d is out of range\n", offset); - return -E1000_ERR_PARAM; + goto out; } - /* Swap the data bytes for the I2C interface */ - phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00); + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; - /* - * Set up Op-code, Phy Address, and register address in the I2CCMD - * register. The MAC will take care of interfacing with the - * PHY to retrieve the desired data. - */ - i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | - (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | - E1000_I2CCMD_OPCODE_WRITE | - phy_data_swapped); + ret_val = e1000_write_phy_reg_i2c(hw, offset, data); - E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); + hw->phy.ops.release(hw); - /* Poll the ready bit to see if the I2C read completed */ - for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { - usec_delay(50); - i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD); - if (i2ccmd & E1000_I2CCMD_READY) - break; - } - if (!(i2ccmd & E1000_I2CCMD_READY)) { - DEBUGOUT("I2CCMD Write did not complete\n"); - return -E1000_ERR_PHY; - } - if (i2ccmd & E1000_I2CCMD_ERROR) { - DEBUGOUT("I2CCMD Error bit set\n"); - return -E1000_ERR_PHY; - } - - return E1000_SUCCESS; +out: + return ret_val; } /** @@ -480,6 +491,7 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; u16 phy_id; + u32 ctrl_ext; DEBUGFUNC("e1000_get_phy_id_82575"); @@ -490,12 +502,19 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) * work. The result of this function should mean phy->phy_addr * and phy->id are set correctly. */ - if (!(e1000_sgmii_active_82575(hw))) { + if (!e1000_sgmii_active_82575(hw)) { phy->addr = 1; ret_val = e1000_get_phy_id(hw); goto out; } + /* Power on sgmii phy if it is disabled */ + ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); + E1000_WRITE_REG(hw, E1000_CTRL_EXT, + ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); + E1000_WRITE_FLUSH(hw); + msec_delay(300); + /* * The address field in the I2CCMD register is 3 bits and 0 is invalid. * Therefore, we need to test 1-7 @@ -522,10 +541,12 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) if (phy->addr == 8) { phy->addr = 0; ret_val = -E1000_ERR_PHY; - goto out; + } else { + ret_val = e1000_get_phy_id(hw); } - ret_val = e1000_get_phy_id(hw); + /* restore previous sfp cage power state */ + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); out: return ret_val; @@ -792,21 +813,23 @@ static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw) if (hw->bus.func == E1000_FUNC_1) mask = E1000_NVM_CFG_DONE_PORT_1; + else if (hw->bus.func == E1000_FUNC_2) + mask = E1000_NVM_CFG_DONE_PORT_2; + else if (hw->bus.func == E1000_FUNC_3) + mask = E1000_NVM_CFG_DONE_PORT_3; while (timeout) { if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask) break; msec_delay(1); timeout--; } - if (!timeout) { + if (!timeout) DEBUGOUT("MNG configuration cycle has not completed.\n"); - } /* If EEPROM is not marked present, init the PHY manually */ if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) && - (hw->phy.type == e1000_phy_igp_3)) { + (hw->phy.type == e1000_phy_igp_3)) e1000_phy_init_script_igp3(hw); - } return ret_val; } @@ -828,14 +851,12 @@ static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, DEBUGFUNC("e1000_get_link_up_info_82575"); - if (hw->phy.media_type != e1000_media_type_copper || - e1000_sgmii_active_82575(hw)) { + if (hw->phy.media_type != e1000_media_type_copper) ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, speed, duplex); - } else { + else ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, duplex); - } return ret_val; } @@ -854,9 +875,7 @@ static s32 e1000_check_for_link_82575(struct e1000_hw *hw) DEBUGFUNC("e1000_check_for_link_82575"); - /* SGMII link check is done through the PCS register. */ - if ((hw->phy.media_type != e1000_media_type_copper) || - (e1000_sgmii_active_82575(hw))) { + if (hw->phy.media_type != e1000_media_type_copper) { ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed, &duplex); /* @@ -872,6 +891,35 @@ static s32 e1000_check_for_link_82575(struct e1000_hw *hw) return ret_val; } +/** + * e1000_power_up_serdes_link_82575 - Power up the serdes link after shutdown + * @hw: pointer to the HW structure + **/ +static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw) +{ + u32 reg; + + DEBUGFUNC("e1000_power_up_serdes_link_82575"); + + if ((hw->phy.media_type != e1000_media_type_internal_serdes) && + !e1000_sgmii_active_82575(hw)) + return; + + /* Enable PCS to turn on link */ + reg = E1000_READ_REG(hw, E1000_PCS_CFG0); + reg |= E1000_PCS_CFG_PCS_EN; + E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg); + + /* Power up the laser */ + reg = E1000_READ_REG(hw, E1000_CTRL_EXT); + reg &= ~E1000_CTRL_EXT_SDP3_DATA; + E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); + + /* flush the write to verify completion */ + E1000_WRITE_FLUSH(hw); + msec_delay(1); +} + /** * e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex * @hw: pointer to the HW structure @@ -930,31 +978,23 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, } /** - * e1000_shutdown_fiber_serdes_link_82575 - Remove link during power down + * e1000_shutdown_serdes_link_82575 - Remove link during power down * @hw: pointer to the HW structure * - * In the case of fiber serdes shut down optics and PCS on driver unload + * In the case of serdes shut down sfp and PCS on driver unload * when management pass thru is not enabled. **/ -void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw) +void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw) { u32 reg; - u16 eeprom_data = 0; - if (hw->phy.media_type != e1000_media_type_internal_serdes) + DEBUGFUNC("e1000_shutdown_serdes_link_82575"); + + if ((hw->phy.media_type != e1000_media_type_internal_serdes) && + !e1000_sgmii_active_82575(hw)) return; - if (hw->bus.func == E1000_FUNC_0) - hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); - else if (hw->bus.func == E1000_FUNC_1) - hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); - - /* - * If APM is not enabled in the EEPROM and management interface is - * not enabled, then power down. - */ - if (!(eeprom_data & E1000_NVM_APME_82575) && - !e1000_enable_mng_pass_thru(hw)) { + if (!e1000_enable_mng_pass_thru(hw)) { /* Disable PCS to turn off link */ reg = E1000_READ_REG(hw, E1000_PCS_CFG0); reg &= ~E1000_PCS_CFG_PCS_EN; @@ -962,10 +1002,10 @@ void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw) /* shutdown the laser */ reg = E1000_READ_REG(hw, E1000_CTRL_EXT); - reg |= E1000_CTRL_EXT_SDP7_DATA; + reg |= E1000_CTRL_EXT_SDP3_DATA; E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); - /* flush the write to verfiy completion */ + /* flush the write to verify completion */ E1000_WRITE_FLUSH(hw); msec_delay(1); } @@ -973,45 +1013,6 @@ void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw) return; } -/** - * e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback - * @hw: pointer to the HW structure - * @enable: state to enter, either enabled or disabled - * - * enables/disables L2 switch loopback functionality - **/ -void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable) -{ - u32 reg; - - reg = E1000_READ_REG(hw, E1000_DTXSWC); - if (enable) - reg |= E1000_DTXSWC_VMDQ_LOOPBACK_EN; - else - reg &= ~(E1000_DTXSWC_VMDQ_LOOPBACK_EN); - E1000_WRITE_REG(hw, E1000_DTXSWC, reg); -} - -/** - * e1000_vmdq_set_replication_pf - enable or disable vmdq replication - * @hw: pointer to the HW structure - * @enable: state to enter, either enabled or disabled - * - * enables/disables replication of packets across multiple pools - **/ -void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable) -{ - u32 reg; - - reg = E1000_READ_REG(hw, E1000_VT_CTL); - if (enable) - reg |= E1000_VT_CTL_VM_REPL_EN; - else - reg &= ~(E1000_VT_CTL_VM_REPL_EN); - - E1000_WRITE_REG(hw, E1000_VT_CTL, reg); -} - /** * e1000_reset_hw_82575 - Reset hardware * @hw: pointer to the HW structure @@ -1111,6 +1112,11 @@ static s32 e1000_init_hw_82575(struct e1000_hw *hw) for (i = 0; i < mac->mta_reg_count; i++) E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); + /* Zero out the Unicast HASH table */ + DEBUGOUT("Zeroing the UTA\n"); + for (i = 0; i < mac->uta_reg_count; i++) + E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0); + /* Setup link and flow control */ ret_val = mac->ops.setup_link(hw); @@ -1137,7 +1143,6 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; - bool link; DEBUGFUNC("e1000_setup_copper_link_82575"); @@ -1146,6 +1151,20 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); E1000_WRITE_REG(hw, E1000_CTRL, ctrl); + ret_val = e1000_setup_serdes_link_82575(hw); + if (ret_val) + goto out; + + if (e1000_sgmii_active_82575(hw) && !hw->phy.reset_disable) { + /* allow time for SFP cage time to power up phy */ + msec_delay(300); + + ret_val = hw->phy.ops.reset(hw); + if (ret_val) { + DEBUGOUT("Error resetting the PHY.\n"); + goto out; + } + } switch (hw->phy.type) { case e1000_phy_m88: ret_val = e1000_copper_link_setup_m88(hw); @@ -1153,6 +1172,9 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) case e1000_phy_igp_3: ret_val = e1000_copper_link_setup_igp(hw); break; + case e1000_phy_82580: + ret_val = e1000_copper_link_setup_82577(hw); + break; default: ret_val = -E1000_ERR_PHY; break; @@ -1161,66 +1183,30 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) if (ret_val) goto out; - if (hw->mac.autoneg) { - /* - * Setup autoneg and flow control advertisement - * and perform autonegotiation. - */ - ret_val = e1000_copper_link_autoneg(hw); - if (ret_val) - goto out; - } else { - /* - * PHY will be set to 10H, 10F, 100H or 100F - * depending on user settings. - */ - DEBUGOUT("Forcing Speed and Duplex\n"); - ret_val = hw->phy.ops.force_speed_duplex(hw); - if (ret_val) { - DEBUGOUT("Error Forcing Speed and Duplex\n"); - goto out; - } - } - - ret_val = e1000_configure_pcs_link_82575(hw); - if (ret_val) - goto out; - - /* - * Check link status. Wait up to 100 microseconds for link to become - * valid. - */ - ret_val = e1000_phy_has_link_generic(hw, - COPPER_LINK_UP_LIMIT, - 10, - &link); - if (ret_val) - goto out; - - if (link) { - DEBUGOUT("Valid link established!!!\n"); - /* Config the MAC and PHY after link is up */ - e1000_config_collision_dist_generic(hw); - ret_val = e1000_config_fc_after_link_up_generic(hw); - } else { - DEBUGOUT("Unable to establish link!!!\n"); - } - + ret_val = e1000_setup_copper_link_generic(hw); out: return ret_val; } /** - * e1000_setup_fiber_serdes_link_82575 - Setup link for fiber/serdes + * e1000_setup_serdes_link_82575 - Setup link for serdes * @hw: pointer to the HW structure * - * Configures speed and duplex for fiber and serdes links. + * Configure the physical coding sub-layer (PCS) link. The PCS link is + * used on copper connections where the serialized gigabit media independent + * interface (sgmii), or serdes fiber is being used. Configures the link + * for auto-negotiation or forces speed/duplex. **/ -static s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw) +static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw) { - u32 reg; + u32 ctrl_ext, ctrl_reg, reg; + bool pcs_autoneg; - DEBUGFUNC("e1000_setup_fiber_serdes_link_82575"); + DEBUGFUNC("e1000_setup_serdes_link_82575"); + + if ((hw->phy.media_type != e1000_media_type_internal_serdes) && + !e1000_sgmii_active_82575(hw)) + return E1000_SUCCESS; /* * On the 82575, SerDes loopback mode persists until it is @@ -1230,25 +1216,48 @@ static s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw) */ E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK); - /* Force link up, set 1gb */ - reg = E1000_READ_REG(hw, E1000_CTRL); - reg |= E1000_CTRL_SLU | E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD; - if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) { - /* set both sw defined pins */ - reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1; - } - E1000_WRITE_REG(hw, E1000_CTRL, reg); - /* Power on phy for 82576 fiber adapters */ - if (hw->mac.type == e1000_82576) { - reg = E1000_READ_REG(hw, E1000_CTRL_EXT); - reg &= ~E1000_CTRL_EXT_SDP7_DATA; - E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); + /* power on the sfp cage if present */ + ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); + ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA; + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); + + ctrl_reg = E1000_READ_REG(hw, E1000_CTRL); + ctrl_reg |= E1000_CTRL_SLU; + + /* set both sw defined pins on 82575/82576*/ + if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) + ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1; + + reg = E1000_READ_REG(hw, E1000_PCS_LCTL); + + /* default pcs_autoneg to the same setting as mac autoneg */ + pcs_autoneg = hw->mac.autoneg; + + switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) { + case E1000_CTRL_EXT_LINK_MODE_SGMII: + /* sgmii mode lets the phy handle forcing speed/duplex */ + pcs_autoneg = TRUE; + /* autoneg time out should be disabled for SGMII mode */ + reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT); + break; + case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: + /* disable PCS autoneg and support parallel detect only */ + pcs_autoneg = FALSE; + default: + /* + * non-SGMII modes only supports a speed of 1000/Full for the + * link so it is best to just force the MAC and let the pcs + * link either autoneg or be forced to 1000/Full + */ + ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD | + E1000_CTRL_FD | E1000_CTRL_FRCDPX; + + /* set speed of 1000/Full if speed/duplex is forced */ + reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL; + break; } - /* Set switch control to serdes energy detect */ - reg = E1000_READ_REG(hw, E1000_CONNSW); - reg |= E1000_CONNSW_ENRGSRC; - E1000_WRITE_REG(hw, E1000_CONNSW, reg); + E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg); /* * New SerDes mode allows for forcing speed or autonegotiating speed @@ -1256,35 +1265,31 @@ static s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw) * mode that will be compatible with older link partners and switches. * However, both are supported by the hardware and some drivers/tools. */ - reg = E1000_READ_REG(hw, E1000_PCS_LCTL); - reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP | - E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); + E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); - if (hw->mac.autoneg) { + /* + * We force flow control to prevent the CTRL register values from being + * overwritten by the autonegotiated flow control values + */ + reg |= E1000_PCS_LCTL_FORCE_FCTRL; + + if (pcs_autoneg) { /* Set PCS register for autoneg */ - reg |= E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */ - E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */ - E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */ - E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */ - DEBUGOUT1("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg); + reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */ + E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */ + DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); } else { - /* Set PCS register for forced speed */ - reg |= E1000_PCS_LCTL_FLV_LINK_UP | /* Force link up */ - E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */ - E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */ - E1000_PCS_LCTL_FSD | /* Force Speed */ - E1000_PCS_LCTL_FORCE_LINK; /* Force Link */ - DEBUGOUT1("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg); - } - - if (hw->mac.type == e1000_82576) { - reg |= E1000_PCS_LCTL_FORCE_FCTRL; - e1000_force_mac_fc_generic(hw); + /* Set PCS register for forced link */ + reg |= E1000_PCS_LCTL_FSD; /* Force Speed */ + DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); } E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg); + if (!e1000_sgmii_active_82575(hw)) + e1000_force_mac_fc_generic(hw); + return E1000_SUCCESS; } @@ -1323,72 +1328,6 @@ out: return ret_val; } -/** - * e1000_configure_pcs_link_82575 - Configure PCS link - * @hw: pointer to the HW structure - * - * Configure the physical coding sub-layer (PCS) link. The PCS link is - * only used on copper connections where the serialized gigabit media - * independent interface (sgmii) is being used. Configures the link - * for auto-negotiation or forces speed/duplex. - **/ -static s32 e1000_configure_pcs_link_82575(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 reg = 0; - - DEBUGFUNC("e1000_configure_pcs_link_82575"); - - if (hw->phy.media_type != e1000_media_type_copper || - !(e1000_sgmii_active_82575(hw))) - goto out; - - /* For SGMII, we need to issue a PCS autoneg restart */ - reg = E1000_READ_REG(hw, E1000_PCS_LCTL); - - /* AN time out should be disabled for SGMII mode */ - reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT); - - if (mac->autoneg) { - /* Make sure forced speed and force link are not set */ - reg &= ~(E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); - - /* - * The PHY should be setup prior to calling this function. - * All we need to do is restart autoneg and enable autoneg. - */ - reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE; - } else { - /* Set PCS register for forced speed */ - - /* Turn off bits for full duplex, speed, and autoneg */ - reg &= ~(E1000_PCS_LCTL_FSV_1000 | - E1000_PCS_LCTL_FSV_100 | - E1000_PCS_LCTL_FDV_FULL | - E1000_PCS_LCTL_AN_ENABLE); - - /* Check for duplex first */ - if (mac->forced_speed_duplex & E1000_ALL_FULL_DUPLEX) - reg |= E1000_PCS_LCTL_FDV_FULL; - - /* Now set speed */ - if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) - reg |= E1000_PCS_LCTL_FSV_100; - - /* Force speed and force link */ - reg |= E1000_PCS_LCTL_FSD | - E1000_PCS_LCTL_FORCE_LINK | - E1000_PCS_LCTL_FLV_LINK_UP; - - DEBUGOUT1("Wrote 0x%08X to PCS_LCTL to configure forced link\n", - reg); - } - E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg); - -out: - return E1000_SUCCESS; -} - /** * e1000_sgmii_active_82575 - Return sgmii state * @hw: pointer to the HW structure @@ -1466,6 +1405,28 @@ out: return ret_val; } +/** + * e1000_config_collision_dist_82575 - Configure collision distance + * @hw: pointer to the HW structure + * + * Configures the collision distance to the default value and is used + * during link setup. + **/ +static void e1000_config_collision_dist_82575(struct e1000_hw *hw) +{ + u32 tctl_ext; + + DEBUGFUNC("e1000_config_collision_dist_82575"); + + tctl_ext = E1000_READ_REG(hw, E1000_TCTL_EXT); + + tctl_ext &= ~E1000_TCTL_EXT_COLD; + tctl_ext |= E1000_COLLISION_DISTANCE << E1000_TCTL_EXT_COLD_SHIFT; + + E1000_WRITE_REG(hw, E1000_TCTL_EXT, tctl_ext); + E1000_WRITE_FLUSH(hw); +} + /** * e1000_power_down_phy_copper_82575 - Remove link during PHY power down * @hw: pointer to the HW structure @@ -1476,13 +1437,12 @@ out: static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - struct e1000_mac_info *mac = &hw->mac; if (!(phy->ops.check_reset_block)) return; /* If the management interface is not enabled, then power down */ - if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw))) + if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw))) e1000_power_down_phy_copper(hw); return; @@ -1548,7 +1508,8 @@ static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw) E1000_READ_REG(hw, E1000_LENERRS); /* This register should not be read in copper configurations */ - if (hw->phy.media_type == e1000_media_type_internal_serdes) + if ((hw->phy.media_type == e1000_media_type_internal_serdes) || + e1000_sgmii_active_82575(hw)) E1000_READ_REG(hw, E1000_SCVPC); } @@ -1677,3 +1638,208 @@ out: return ret_val; } +/** + * e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback + * @hw: pointer to the hardware struct + * @enable: state to enter, either enabled or disabled + * + * enables/disables L2 switch loopback functionality. + **/ +void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable) +{ + u32 dtxswc; + + switch (hw->mac.type) { + case e1000_82576: + dtxswc = E1000_READ_REG(hw, E1000_DTXSWC); + if (enable) + dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN; + else + dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN; + E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc); + break; + default: + /* Currently no other hardware supports loopback */ + break; + } + + +} + +/** + * e1000_vmdq_set_replication_pf - enable or disable vmdq replication + * @hw: pointer to the hardware struct + * @enable: state to enter, either enabled or disabled + * + * enables/disables replication of packets across multiple pools. + **/ +void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable) +{ + u32 vt_ctl = E1000_READ_REG(hw, E1000_VT_CTL); + + if (enable) + vt_ctl |= E1000_VT_CTL_VM_REPL_EN; + else + vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN; + + E1000_WRITE_REG(hw, E1000_VT_CTL, vt_ctl); +} + +/** + * e1000_read_phy_reg_82580 - Read 82580 MDI control register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Reads the MDI control register in the PHY at offset and stores the + * information read to data. + **/ +static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data) +{ + s32 ret_val; + + DEBUGFUNC("e1000_read_phy_reg_82580"); + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + + ret_val = e1000_read_phy_reg_mdic(hw, offset, data); + + hw->phy.ops.release(hw); + +out: + return ret_val; +} + +/** + * e1000_write_phy_reg_82580 - Write 82580 MDI control register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write to register at offset + * + * Writes data to MDI control register in the PHY at offset. + **/ +static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data) +{ + s32 ret_val; + + DEBUGFUNC("e1000_write_phy_reg_82580"); + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + + ret_val = e1000_write_phy_reg_mdic(hw, offset, data); + + hw->phy.ops.release(hw); + +out: + return ret_val; +} + +/** + * e1000_reset_hw_82580 - Reset hardware + * @hw: pointer to the HW structure + * + * This resets function or entire device (all ports, etc.) + * to a known state. + **/ +static s32 e1000_reset_hw_82580(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + /* BH SW mailbox bit in SW_FW_SYNC */ + u16 swmbsw_mask = E1000_SW_SYNCH_MB; + u32 ctrl, icr; + bool global_device_reset = hw->dev_spec._82575.global_device_reset; + + DEBUGFUNC("e1000_reset_hw_82580"); + + hw->dev_spec._82575.global_device_reset = FALSE; + + /* Get current control state. */ + ctrl = E1000_READ_REG(hw, E1000_CTRL); + + /* + * Prevent the PCI-E bus from sticking if there is no TLP connection + * on the last TLP read/write transaction when MAC is reset. + */ + ret_val = e1000_disable_pcie_master_generic(hw); + if (ret_val) + DEBUGOUT("PCI-E Master disable polling has failed.\n"); + + DEBUGOUT("Masking off all interrupts\n"); + E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); + E1000_WRITE_REG(hw, E1000_RCTL, 0); + E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); + E1000_WRITE_FLUSH(hw); + + msec_delay(10); + + /* Determine whether or not a global dev reset is requested */ + if (global_device_reset && + e1000_acquire_swfw_sync_82575(hw, swmbsw_mask)) + global_device_reset = FALSE; + + if (global_device_reset && + !(E1000_READ_REG(hw, E1000_STATUS) & E1000_STAT_DEV_RST_SET)) + ctrl |= E1000_CTRL_DEV_RST; + else + ctrl |= E1000_CTRL_RST; + + E1000_WRITE_REG(hw, E1000_CTRL, ctrl); + + /* Add delay to insure DEV_RST has time to complete */ + if (global_device_reset) + msec_delay(5); + + ret_val = e1000_get_auto_rd_done_generic(hw); + if (ret_val) { + /* + * When auto config read does not complete, do not + * return with an error. This can happen in situations + * where there is no eeprom and prevents getting link. + */ + DEBUGOUT("Auto Read Done did not complete\n"); + } + + /* If EEPROM is not present, run manual init scripts */ + if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) + e1000_reset_init_script_82575(hw); + + /* clear global device reset status bit */ + E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET); + + /* Clear any pending interrupt events. */ + E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); + icr = E1000_READ_REG(hw, E1000_ICR); + + /* Install any alternate MAC address into RAR0 */ + ret_val = e1000_check_alt_mac_addr_generic(hw); + + /* Release semaphore */ + if (global_device_reset) + e1000_release_swfw_sync_82575(hw, swmbsw_mask); + + return ret_val; +} + +/** + * e1000_rxpbs_adjust_82580 - adjust RXPBS value to reflect actual RX PBA size + * @data: data received by reading RXPBS register + * + * The 82580 uses a table based approach for packet buffer allocation sizes. + * This function converts the retrieved value into the correct table value + * 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 + * 0x0 36 72 144 1 2 4 8 16 + * 0x8 35 70 140 rsv rsv rsv rsv rsv + */ +u16 e1000_rxpbs_adjust_82580(u32 data) +{ + u16 ret_val = 0; + + if (data < E1000_82580_RXPBS_TABLE_SIZE) + ret_val = e1000_82580_rxpbs_table[data]; + + return ret_val; +} diff --git a/sys/dev/e1000/e1000_82575.h b/sys/dev/e1000/e1000_82575.h index 34e0d29398f..1fc7e26dd59 100644 --- a/sys/dev/e1000/e1000_82575.h +++ b/sys/dev/e1000/e1000_82575.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -49,12 +49,16 @@ * For 82576, there are an additional set of RARs that begin at an offset * separate from the first set of RARs. */ -#define E1000_RAR_ENTRIES_82575 16 -#define E1000_RAR_ENTRIES_82576 24 +#define E1000_RAR_ENTRIES_82575 16 +#define E1000_RAR_ENTRIES_82576 24 +#define E1000_RAR_ENTRIES_82580 24 +#define E1000_SW_SYNCH_MB 0x00000100 +#define E1000_STAT_DEV_RST_SET 0x00100000 +#define E1000_CTRL_DEV_RST 0x20000000 #ifdef E1000_BIT_FIELDS struct e1000_adv_data_desc { - u64 buffer_addr; /* Address of the descriptor's data buffer */ + __le64 buffer_addr; /* Address of the descriptor's data buffer */ union { u32 data; struct { @@ -128,6 +132,7 @@ struct e1000_adv_context_desc { #define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000 #define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000 #define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000 +#define E1000_SRRCTL_TIMESTAMP 0x40000000 #define E1000_SRRCTL_DROP_EN 0x80000000 #define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F @@ -142,6 +147,7 @@ struct e1000_adv_context_desc { #define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 #define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 #define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000 +#define E1000_MRQC_ENABLE_RSS_8Q 0x00000002 #define E1000_VMRCTL_MIRROR_PORT_SHIFT 8 #define E1000_VMRCTL_MIRROR_DSTPORT_MASK (7 << E1000_VMRCTL_MIRROR_PORT_SHIFT) @@ -185,31 +191,31 @@ struct e1000_adv_context_desc { /* Receive Descriptor - Advanced */ union e1000_adv_rx_desc { struct { - u64 pkt_addr; /* Packet buffer address */ - u64 hdr_addr; /* Header buffer address */ + __le64 pkt_addr; /* Packet buffer address */ + __le64 hdr_addr; /* Header buffer address */ } read; struct { struct { union { - u32 data; + __le32 data; struct { - u16 pkt_info; /* RSS type, Packet type */ - u16 hdr_info; /* Split Header, - * header buffer length */ + __le16 pkt_info; /*RSS type, Pkt type*/ + __le16 hdr_info; /* Split Header, + * header buffer len*/ } hs_rss; } lo_dword; union { - u32 rss; /* RSS Hash */ + __le32 rss; /* RSS Hash */ struct { - u16 ip_id; /* IP id */ - u16 csum; /* Packet Checksum */ + __le16 ip_id; /* IP id */ + __le16 csum; /* Packet Checksum */ } csum_ip; } hi_dword; } lower; struct { - u32 status_error; /* ext status/error */ - u16 length; /* Packet length */ - u16 vlan; /* VLAN tag */ + __le32 status_error; /* ext status/error */ + __le16 length; /* Packet length */ + __le16 vlan; /* VLAN tag */ } upper; } wb; /* writeback */ }; @@ -220,6 +226,8 @@ union e1000_adv_rx_desc { #define E1000_RXDADV_HDRBUFLEN_SHIFT 5 #define E1000_RXDADV_SPLITHEADER_EN 0x00001000 #define E1000_RXDADV_SPH 0x8000 +#define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */ +#define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */ #define E1000_RXDADV_ERR_HBO 0x00800000 /* RSS Hash results */ @@ -269,14 +277,14 @@ union e1000_adv_rx_desc { /* Transmit Descriptor - Advanced */ union e1000_adv_tx_desc { struct { - u64 buffer_addr; /* Address of descriptor's data buf */ - u32 cmd_type_len; - u32 olinfo_status; + __le64 buffer_addr; /* Address of descriptor's data buf */ + __le32 cmd_type_len; + __le32 olinfo_status; } read; struct { - u64 rsvd; /* Reserved */ - u32 nxtseq_seed; - u32 status; + __le64 rsvd; /* Reserved */ + __le32 nxtseq_seed; + __le32 status; } wb; }; @@ -303,10 +311,10 @@ union e1000_adv_tx_desc { /* Context descriptors */ struct e1000_adv_tx_context_desc { - u32 vlan_macip_lens; - u32 seqnum_seed; - u32 type_tucmd_mlhl; - u32 mss_l4len_idx; + __le32 vlan_macip_lens; + __le32 seqnum_seed; + __le32 type_tucmd_mlhl; + __le32 mss_l4len_idx; }; #define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ @@ -378,6 +386,14 @@ struct e1000_adv_tx_context_desc { */ #define E1000_ETQF_FILTER_EAPOL 0 +#define E1000_FTQF_VF_BP 0x00008000 +#define E1000_FTQF_1588_TIME_STAMP 0x08000000 +#define E1000_FTQF_MASK 0xF0000000 +#define E1000_FTQF_MASK_PROTO_BP 0x10000000 +#define E1000_FTQF_MASK_SOURCE_ADDR_BP 0x20000000 +#define E1000_FTQF_MASK_DEST_ADDR_BP 0x40000000 +#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000 + #define E1000_NVM_APME_82575 0x0400 #define MAX_NUM_VFS 8 @@ -409,6 +425,7 @@ struct e1000_adv_tx_context_desc { #define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */ #define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */ + #define E1000_VLVF_ARRAY_SIZE 32 #define E1000_VLVF_VLANID_MASK 0x00000FFF #define E1000_VLVF_POOLSEL_SHIFT 12 @@ -416,6 +433,9 @@ struct e1000_adv_tx_context_desc { #define E1000_VLVF_LVLAN 0x00100000 #define E1000_VLVF_VLANID_ENABLE 0x80000000 +#define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */ +#define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */ + #define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */ #define E1000_IOVCTL 0x05BBC @@ -424,8 +444,20 @@ struct e1000_adv_tx_context_desc { #define E1000_RPLOLR_STRVLAN 0x40000000 #define E1000_RPLOLR_STRCRC 0x80000000 +#define E1000_TCTL_EXT_COLD 0x000FFC00 +#define E1000_TCTL_EXT_COLD_SHIFT 10 + +#define E1000_DTXCTL_8023LL 0x0004 +#define E1000_DTXCTL_VLAN_ADDED 0x0008 +#define E1000_DTXCTL_OOS_ENABLE 0x0010 +#define E1000_DTXCTL_MDP_EN 0x0020 +#define E1000_DTXCTL_SPOOF_INT 0x0040 + #define ALL_QUEUES 0xFFFF +/* RX packet buffer size defines */ +#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable); void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable); +u16 e1000_rxpbs_adjust_82580(u32 data); #endif /* _E1000_82575_H_ */ diff --git a/sys/dev/e1000/e1000_api.c b/sys/dev/e1000/e1000_api.c index 8188658d6bb..bf9fa2abb90 100644 --- a/sys/dev/e1000/e1000_api.c +++ b/sys/dev/e1000/e1000_api.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -232,6 +232,7 @@ s32 e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_ICH8_IGP_M_AMT: case E1000_DEV_ID_ICH8_IGP_AMT: case E1000_DEV_ID_ICH8_IGP_C: + case E1000_DEV_ID_ICH8_82567V_3: mac->type = e1000_ich8lan; break; case E1000_DEV_ID_ICH9_IFE: @@ -269,9 +270,17 @@ s32 e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82576_SERDES: case E1000_DEV_ID_82576_QUAD_COPPER: case E1000_DEV_ID_82576_NS: + case E1000_DEV_ID_82576_NS_SERDES: case E1000_DEV_ID_82576_SERDES_QUAD: mac->type = e1000_82576; break; + case E1000_DEV_ID_82580_COPPER: + case E1000_DEV_ID_82580_FIBER: + case E1000_DEV_ID_82580_SERDES: + case E1000_DEV_ID_82580_SGMII: + case E1000_DEV_ID_82580_COPPER_DUAL: + mac->type = e1000_82580; + break; default: /* Should never have loaded on this device */ ret_val = -E1000_ERR_MAC_INIT; @@ -362,6 +371,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device) break; case e1000_82575: case e1000_82576: + case e1000_82580: e1000_init_function_pointers_82575(hw); break; default: @@ -744,20 +754,6 @@ s32 e1000_validate_mdi_setting(struct e1000_hw *hw) return E1000_SUCCESS; } -/** - * e1000_mta_set - Sets multicast table bit - * @hw: pointer to the HW structure - * @hash_value: Multicast hash value. - * - * This sets the bit in the multicast table corresponding to the - * hash value. This is a function pointer entry point called by drivers. - **/ -void e1000_mta_set(struct e1000_hw *hw, u32 hash_value) -{ - if (hw->mac.ops.mta_set) - hw->mac.ops.mta_set(hw, hash_value); -} - /** * e1000_hash_mc_addr - Determines address location in multicast table * @hw: pointer to the HW structure @@ -1236,6 +1232,18 @@ void e1000_power_down_phy(struct e1000_hw *hw) hw->phy.ops.power_down(hw); } +/** + * e1000_power_up_fiber_serdes_link - Power up serdes link + * @hw: pointer to the HW structure + * + * Power on the optics and PCS. + **/ +void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw) +{ + if (hw->mac.ops.power_up_serdes) + hw->mac.ops.power_up_serdes(hw); +} + /** * e1000_shutdown_fiber_serdes_link - Remove link during power down * @hw: pointer to the HW structure diff --git a/sys/dev/e1000/e1000_api.h b/sys/dev/e1000/e1000_api.h index b492e577b1a..b7bc14c8f31 100644 --- a/sys/dev/e1000/e1000_api.h +++ b/sys/dev/e1000/e1000_api.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ extern void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw); extern void e1000_init_function_pointers_82575(struct e1000_hw *hw); extern void e1000_rx_fifo_flush_82575(struct e1000_hw *hw); extern void e1000_init_function_pointers_vf(struct e1000_hw *hw); +extern void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw); extern void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw); s32 e1000_set_mac_type(struct e1000_hw *hw); @@ -67,7 +68,6 @@ s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, s32 e1000_disable_pcie_master(struct e1000_hw *hw); void e1000_config_collision_dist(struct e1000_hw *hw); void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); -void e1000_mta_set(struct e1000_hw *hw, u32 hash_value); u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr); void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count); diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h index d845fb23dc6..7ac5d8b8b1d 100644 --- a/sys/dev/e1000/e1000_defines.h +++ b/sys/dev/e1000/e1000_defines.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -146,12 +146,12 @@ #define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Definable Pin 5 */ #define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA #define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Definable Pin 6 */ -#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */ +#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */ /* SDP 4/5 (bits 8,9) are reserved in >= 82575 */ #define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */ #define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */ #define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */ -#define E1000_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7 0=in 1=out */ +#define E1000_CTRL_EXT_SDP3_DIR 0x00000800 /* Direction of SDP3 0=in 1=out */ #define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ #define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */ @@ -161,6 +161,8 @@ #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ #define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */ #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 +#define E1000_CTRL_EXT_LINK_MODE_82580_MASK 0x01C00000 /*82580 bit 24:22*/ +#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000 #define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000 #define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000 #define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000 @@ -312,6 +314,11 @@ #define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ #define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ +#define E1000_MANC2H_PORT_623 0x00000020 /* Port 0x26f */ +#define E1000_MANC2H_PORT_664 0x00000040 /* Port 0x298 */ +#define E1000_MDEF_PORT_623 0x00000800 /* Port 0x26f */ +#define E1000_MDEF_PORT_664 0x00000400 /* Port 0x298 */ + /* Receive Control */ #define E1000_RCTL_RST 0x00000001 /* Software reset */ #define E1000_RCTL_EN 0x00000002 /* enable */ @@ -386,6 +393,8 @@ #define E1000_SWFW_PHY0_SM 0x02 #define E1000_SWFW_PHY1_SM 0x04 #define E1000_SWFW_CSR_SM 0x08 +#define E1000_SWFW_PHY2_SM 0x20 +#define E1000_SWFW_PHY3_SM 0x40 /* FACTPS Definitions */ #define E1000_FACTPS_LFS 0x40000000 /* LAN Function Select */ @@ -414,6 +423,8 @@ * PHYRST_N pin */ #define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external * LINK_0 and LINK_1 pins */ +#define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */ +#define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */ #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ #define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ @@ -697,6 +708,7 @@ /* Extended Configuration Control and Size */ #define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 #define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 +#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008 #define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 #define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 @@ -769,6 +781,7 @@ #define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */ #define E1000_ICR_MNG 0x00040000 /* Manageability event */ #define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */ +#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */ #define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver * should claim the interrupt */ #define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* Q0 Rx desc FIFO parity error */ @@ -789,6 +802,7 @@ #define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ #define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ #define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ +#define E1000_ICR_FER 0x00400000 /* Fatal Error */ /* PBA ECC Register */ #define E1000_PBA_ECC_COUNTER_MASK 0xFFF00000 /* ECC counter mask */ @@ -860,6 +874,7 @@ #define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */ #define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */ #define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */ +#define E1000_IMS_DRSTA E1000_ICR_DRSTA /* Device Reset Asserted */ #define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* Q0 Rx desc FIFO * parity error */ #define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* Q0 Tx desc FIFO @@ -881,6 +896,7 @@ #define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ #define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */ #define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupts */ +#define E1000_IMS_FER E1000_ICR_FER /* Fatal Error */ /* Extended Interrupt Mask Set */ #define E1000_EIMS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */ @@ -913,6 +929,7 @@ #define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */ #define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */ #define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */ +#define E1000_ICS_DRSTA E1000_ICR_DRSTA /* Device Reset Aserted */ #define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* Q0 Rx desc FIFO * parity error */ #define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* Q0 Tx desc FIFO @@ -943,6 +960,8 @@ #define E1000_EICS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */ #define E1000_EITR_ITR_INT_MASK 0x0000FFFF +/* E1000_EITR_CNT_IGNR is only for 82576 and newer */ +#define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on write */ /* Transmit Descriptor Control */ #define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ @@ -1036,6 +1055,56 @@ #define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */ #define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */ +#define E1000_TSYNCTXCTL_VALID 0x00000001 /* tx timestamp valid */ +#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable tx timestampping */ + +#define E1000_TSYNCRXCTL_VALID 0x00000001 /* rx timestamp valid */ +#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* rx type mask */ +#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00 +#define E1000_TSYNCRXCTL_TYPE_L4_V1 0x02 +#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2 0x04 +#define E1000_TSYNCRXCTL_TYPE_ALL 0x08 +#define E1000_TSYNCRXCTL_TYPE_EVENT_V2 0x0A +#define E1000_TSYNCRXCTL_ENABLED 0x00000010 /* enable rx timestampping */ + +#define E1000_TSYNCRXCFG_PTP_V1_CTRLT_MASK 0x000000FF +#define E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE 0x00 +#define E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE 0x01 +#define E1000_TSYNCRXCFG_PTP_V1_FOLLOWUP_MESSAGE 0x02 +#define E1000_TSYNCRXCFG_PTP_V1_DELAY_RESP_MESSAGE 0x03 +#define E1000_TSYNCRXCFG_PTP_V1_MANAGEMENT_MESSAGE 0x04 + +#define E1000_TSYNCRXCFG_PTP_V2_MSGID_MASK 0x00000F00 +#define E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE 0x0000 +#define E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE 0x0100 +#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_REQ_MESSAGE 0x0200 +#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_RESP_MESSAGE 0x0300 +#define E1000_TSYNCRXCFG_PTP_V2_FOLLOWUP_MESSAGE 0x0800 +#define E1000_TSYNCRXCFG_PTP_V2_DELAY_RESP_MESSAGE 0x0900 +#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_FOLLOWUP_MESSAGE 0x0A00 +#define E1000_TSYNCRXCFG_PTP_V2_ANNOUNCE_MESSAGE 0x0B00 +#define E1000_TSYNCRXCFG_PTP_V2_SIGNALLING_MESSAGE 0x0C00 +#define E1000_TSYNCRXCFG_PTP_V2_MANAGEMENT_MESSAGE 0x0D00 + +#define E1000_TIMINCA_16NS_SHIFT 24 +/* TUPLE Filtering Configuration */ +#define E1000_TTQF_DISABLE_MASK 0xF0008000 /* TTQF Disable Mask */ +#define E1000_TTQF_QUEUE_ENABLE 0x100 /* TTQF Queue Enable Bit */ +#define E1000_TTQF_PROTOCOL_MASK 0xFF /* TTQF Protocol Mask */ +/* TTQF TCP Bit, shift with E1000_TTQF_PROTOCOL SHIFT */ +#define E1000_TTQF_PROTOCOL_TCP 0x0 +/* TTQF UDP Bit, shift with E1000_TTQF_PROTOCOL_SHIFT */ +#define E1000_TTQF_PROTOCOL_UDP 0x1 +/* TTQF SCTP Bit, shift with E1000_TTQF_PROTOCOL_SHIFT */ +#define E1000_TTQF_PROTOCOL_SCTP 0x2 +#define E1000_TTQF_PROTOCOL_SHIFT 5 /* TTQF Protocol Shift */ +#define E1000_TTQF_QUEUE_SHIFT 16 /* TTQF Queue Shfit */ +#define E1000_TTQF_RX_QUEUE_MASK 0x70000 /* TTQF Queue Mask */ +#define E1000_TTQF_MASK_ENABLE 0x10000000 /* TTQF Mask Enable Bit */ +#define E1000_IMIR_CLEAR_MASK 0xF001FFFF /* IMIR Reg Clear Mask */ +#define E1000_IMIR_PORT_BYPASS 0x20000 /* IMIR Port Bypass Bit */ +#define E1000_IMIR_PRIORITY_SHIFT 29 /* IMIR Priority Shift */ +#define E1000_IMIREXT_CLEAR_MASK 0x7FFFF /* IMIREXT Reg Clear Mask */ /* PCI Express Control */ #define E1000_GCR_RXD_NO_SNOOP 0x00000001 @@ -1227,6 +1296,10 @@ #define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ #define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ +#define E1000_NVM_CFG_DONE_PORT_2 0x100000 /* ...for third port */ +#define E1000_NVM_CFG_DONE_PORT_3 0x200000 /* ...for fourth port */ + +#define NVM_82580_LAN_FUNC_OFFSET(a) (a ? (0x40 + (0x40 * a)) : 0) /* Mask bits for fields in Word 0x0f of the NVM */ #define NVM_WORD0F_PAUSE_MASK 0x3000 @@ -1316,6 +1389,9 @@ #define PCI_HEADER_TYPE_MULTIFUNC 0x80 #define PCIE_LINK_WIDTH_MASK 0x3F0 #define PCIE_LINK_WIDTH_SHIFT 4 +#define PCIE_LINK_SPEED_MASK 0x0F +#define PCIE_LINK_SPEED_2500 0x01 +#define PCIE_LINK_SPEED_5000 0x02 #define PCIE_DEVICE_CONTROL2_16ms 0x0005 #ifndef ETH_ADDR_LEN @@ -1346,6 +1422,7 @@ #define BME1000_E_PHY_ID_R2 0x01410CB1 #define I82577_E_PHY_ID 0x01540050 #define I82578_E_PHY_ID 0x004DD040 +#define I82580_I_PHY_ID 0x015403A0 #define IGP04E1000_E_PHY_ID 0x02A80391 #define M88_VENDOR 0x0141 @@ -1442,6 +1519,7 @@ #define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */ #define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */ + /* M88EC018 Rev 2 specific DownShift settings */ #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X 0x0000 @@ -1575,5 +1653,34 @@ #define E1000_LSECRXCTRL_RSV_MASK 0xFFFFFF33 +/* DMA Coalescing register fields */ +#define E1000_DMACR_DMACWT_MASK 0x00003FFF /* DMA Coalescing + * Watchdog Timer */ +#define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coalescing Receive + * Threshold */ +#define E1000_DMACR_DMACTHR_SHIFT 16 +#define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe + * transactions */ +#define E1000_DMACR_DMAC_LX_SHIFT 28 +#define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */ + +#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit + * Threshold */ + +#define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */ + +#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Receive Traffic Rate + * Threshold */ +#define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rcv packet rate in + * current window */ + +#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rcv Traffic + * Current Cnt */ + +#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rcv Threshold + * High val */ +#define E1000_FCRTC_RTH_COAL_SHIFT 4 +#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision based + on DMA coal */ #endif /* _E1000_DEFINES_H_ */ diff --git a/sys/dev/e1000/e1000_hw.h b/sys/dev/e1000/e1000_hw.h index 6afa4fbb8bd..ce5dffdd67d 100644 --- a/sys/dev/e1000/e1000_hw.h +++ b/sys/dev/e1000/e1000_hw.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -100,6 +100,7 @@ struct e1000_hw; #define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 #define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA #define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB +#define E1000_DEV_ID_ICH8_82567V_3 0x1501 #define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 #define E1000_DEV_ID_ICH8_IGP_AMT 0x104A #define E1000_DEV_ID_ICH8_IGP_C 0x104B @@ -121,6 +122,7 @@ struct e1000_hw; #define E1000_DEV_ID_ICH10_R_BM_V 0x10CE #define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE #define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF + #define E1000_DEV_ID_PCH_M_HV_LM 0x10EA #define E1000_DEV_ID_PCH_M_HV_LC 0x10EB #define E1000_DEV_ID_PCH_D_HV_DM 0x10EF @@ -130,11 +132,17 @@ struct e1000_hw; #define E1000_DEV_ID_82576_SERDES 0x10E7 #define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8 #define E1000_DEV_ID_82576_NS 0x150A -#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D +#define E1000_DEV_ID_82576_NS_SERDES 0x1518 +#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D #define E1000_DEV_ID_82575EB_COPPER 0x10A7 #define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9 #define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6 #define E1000_DEV_ID_82575GB_QUAD_COPPER_PM 0x10E2 +#define E1000_DEV_ID_82580_COPPER 0x150E +#define E1000_DEV_ID_82580_FIBER 0x150F +#define E1000_DEV_ID_82580_SERDES 0x1510 +#define E1000_DEV_ID_82580_SGMII 0x1511 +#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516 #define E1000_REVISION_0 0 #define E1000_REVISION_1 1 #define E1000_REVISION_2 2 @@ -143,9 +151,13 @@ struct e1000_hw; #define E1000_FUNC_0 0 #define E1000_FUNC_1 1 +#define E1000_FUNC_2 2 +#define E1000_FUNC_3 3 #define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0 #define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN2 6 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN3 9 enum e1000_mac_type { e1000_undefined = 0, @@ -173,6 +185,7 @@ enum e1000_mac_type { e1000_pchlan, e1000_82575, e1000_82576, + e1000_82580, e1000_num_macs /* List is 1-based, so subtract 1 for TRUE count. */ }; @@ -213,6 +226,7 @@ enum e1000_phy_type { e1000_phy_bm, e1000_phy_82578, e1000_phy_82577, + e1000_phy_82580, e1000_phy_vf, }; @@ -587,11 +601,11 @@ struct e1000_mac_operations { s32 (*reset_hw)(struct e1000_hw *); s32 (*init_hw)(struct e1000_hw *); void (*shutdown_serdes)(struct e1000_hw *); + void (*power_up_serdes)(struct e1000_hw *); s32 (*setup_link)(struct e1000_hw *); s32 (*setup_physical_interface)(struct e1000_hw *); s32 (*setup_led)(struct e1000_hw *); void (*write_vfta)(struct e1000_hw *, u32, u32); - void (*mta_set)(struct e1000_hw *, u32); void (*config_collision_dist)(struct e1000_hw *); void (*rar_set)(struct e1000_hw *, u8*, u32); s32 (*read_mac_addr)(struct e1000_hw *); @@ -615,11 +629,13 @@ struct e1000_phy_operations { s32 (*get_cable_length)(struct e1000_hw *); s32 (*get_info)(struct e1000_hw *); s32 (*read_reg)(struct e1000_hw *, u32, u16 *); + s32 (*read_reg_locked)(struct e1000_hw *, u32, u16 *); void (*release)(struct e1000_hw *); s32 (*reset)(struct e1000_hw *); s32 (*set_d0_lplu_state)(struct e1000_hw *, bool); s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); s32 (*write_reg)(struct e1000_hw *, u32, u16); + s32 (*write_reg_locked)(struct e1000_hw *, u32, u16); void (*power_up)(struct e1000_hw *); void (*power_down)(struct e1000_hw *); }; @@ -657,6 +673,7 @@ struct e1000_mac_info { u16 ifs_ratio; u16 ifs_step_size; u16 mta_reg_count; + u16 uta_reg_count; /* Maximum size of the MTA register table in all supported adapters */ #define MAX_MTA_REG 128 @@ -666,6 +683,7 @@ struct e1000_mac_info { u8 forced_speed_duplex; bool adaptive_ifs; + bool has_fwsm; bool arc_subsystem_valid; bool asf_firmware_present; bool autoneg; @@ -768,6 +786,10 @@ struct e1000_dev_spec_82571 { u32 smb_counter; }; +struct e1000_dev_spec_80003es2lan { + bool mdic_wa_enable; +}; + struct e1000_shadow_ram { u16 value; bool modified; @@ -778,6 +800,9 @@ struct e1000_shadow_ram { struct e1000_dev_spec_ich8lan { bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_SHADOW_RAM_WORDS]; + E1000_MUTEX nvm_mutex; + E1000_MUTEX swflag_mutex; + bool nvm_k1_enabled; }; struct e1000_dev_spec_82575 { @@ -810,6 +835,7 @@ struct e1000_hw { struct e1000_dev_spec_82542 _82542; struct e1000_dev_spec_82543 _82543; struct e1000_dev_spec_82571 _82571; + struct e1000_dev_spec_80003es2lan _80003es2lan; struct e1000_dev_spec_ich8lan ich8lan; struct e1000_dev_spec_82575 _82575; struct e1000_dev_spec_vf vf; diff --git a/sys/dev/e1000/e1000_ich8lan.c b/sys/dev/e1000/e1000_ich8lan.c index a80955a5a36..6b3c25d8218 100644 --- a/sys/dev/e1000/e1000_ich8lan.c +++ b/sys/dev/e1000/e1000_ich8lan.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -68,10 +68,12 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw); static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw); static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw); static void e1000_release_swflag_ich8lan(struct e1000_hw *hw); +static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw); +static void e1000_release_nvm_ich8lan(struct e1000_hw *hw); static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw); static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw); -static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw); +static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active); static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, @@ -95,6 +97,7 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); static s32 e1000_led_on_ich8lan(struct e1000_hw *hw); static s32 e1000_led_off_ich8lan(struct e1000_hw *hw); +static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); static s32 e1000_setup_led_pchlan(struct e1000_hw *hw); static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw); static s32 e1000_led_on_pchlan(struct e1000_hw *hw); @@ -103,7 +106,6 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout); static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw); -static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw); static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, @@ -120,6 +122,10 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, u8 size, u16 data); static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); +static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw); +static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); +static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw); +static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ @@ -171,6 +177,7 @@ union ich8_hws_flash_regacc { static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; + u32 ctrl; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_phy_params_pchlan"); @@ -179,35 +186,88 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->reset_delay_us = 100; phy->ops.acquire = e1000_acquire_swflag_ich8lan; - phy->ops.check_polarity = e1000_check_polarity_ife; phy->ops.check_reset_block = e1000_check_reset_block_ich8lan; - phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife; - phy->ops.get_cable_length = e1000_get_cable_length_igp_2; phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan; - phy->ops.get_info = e1000_get_phy_info_ich8lan; phy->ops.read_reg = e1000_read_phy_reg_hv; + phy->ops.read_reg_locked = e1000_read_phy_reg_hv_locked; phy->ops.release = e1000_release_swflag_ich8lan; phy->ops.reset = e1000_phy_hw_reset_ich8lan; - phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan; - phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan; + phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan; + phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan; phy->ops.write_reg = e1000_write_phy_reg_hv; + phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked; phy->ops.power_up = e1000_power_up_phy_copper; phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + if ((hw->mac.type == e1000_pchlan) && + (!(E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID))) { + + /* + * The MAC-PHY interconnect may still be in SMBus mode + * after Sx->S0. Toggle the LANPHYPC Value bit to force + * the interconnect to PCIe mode, but only if there is no + * firmware present otherwise firmware will have done it. + */ + ctrl = E1000_READ_REG(hw, E1000_CTRL); + ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; + ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; + E1000_WRITE_REG(hw, E1000_CTRL, ctrl); + usec_delay(10); + ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; + E1000_WRITE_REG(hw, E1000_CTRL, ctrl); + msec_delay(50); + } + + /* + * Reset the PHY before any acccess to it. Doing so, ensures that + * the PHY is in a known good state before we read/write PHY registers. + * The generic reset is sufficient here, because we haven't determined + * the PHY type yet. + */ + ret_val = e1000_phy_hw_reset_generic(hw); + if (ret_val) + goto out; + phy->id = e1000_phy_unknown; - e1000_get_phy_id(hw); + ret_val = e1000_get_phy_id(hw); + if (ret_val) + goto out; + if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) { + /* + * In case the PHY needs to be in mdio slow mode (eg. 82577), + * set slow mode and try to get the PHY id again. + */ + ret_val = e1000_set_mdio_slow_mode_hv(hw); + if (ret_val) + goto out; + ret_val = e1000_get_phy_id(hw); + if (ret_val) + goto out; + } phy->type = e1000_get_phy_type_from_id(phy->id); - if (phy->type == e1000_phy_82577) { + switch (phy->type) { + case e1000_phy_82577: phy->ops.check_polarity = e1000_check_polarity_82577; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_82577; - phy->ops.get_cable_length = e1000_get_cable_length_82577; + phy->ops.get_cable_length = e1000_get_cable_length_82577; phy->ops.get_info = e1000_get_phy_info_82577; phy->ops.commit = e1000_phy_sw_reset_generic; + break; + case e1000_phy_82578: + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; + phy->ops.get_cable_length = e1000_get_cable_length_m88; + phy->ops.get_info = e1000_get_phy_info_m88; + break; + default: + ret_val = -E1000_ERR_PHY; + break; } +out: return ret_val; } @@ -229,12 +289,9 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) phy->reset_delay_us = 100; phy->ops.acquire = e1000_acquire_swflag_ich8lan; - phy->ops.check_polarity = e1000_check_polarity_ife; phy->ops.check_reset_block = e1000_check_reset_block_ich8lan; - phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife; phy->ops.get_cable_length = e1000_get_cable_length_igp_2; phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan; - phy->ops.get_info = e1000_get_phy_info_ich8lan; phy->ops.read_reg = e1000_read_phy_reg_igp; phy->ops.release = e1000_release_swflag_ich8lan; phy->ops.reset = e1000_phy_hw_reset_ich8lan; @@ -273,12 +330,20 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) case IGP03E1000_E_PHY_ID: phy->type = e1000_phy_igp_3; phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->ops.read_reg_locked = e1000_read_phy_reg_igp_locked; + phy->ops.write_reg_locked = e1000_write_phy_reg_igp_locked; + phy->ops.get_info = e1000_get_phy_info_igp; + phy->ops.check_polarity = e1000_check_polarity_igp; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp; break; case IFE_E_PHY_ID: case IFE_PLUS_E_PHY_ID: case IFE_C_E_PHY_ID: phy->type = e1000_phy_ife; phy->autoneg_mask = E1000_ALL_NOT_GIG; + phy->ops.get_info = e1000_get_phy_info_ife; + phy->ops.check_polarity = e1000_check_polarity_ife; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife; break; case BME1000_E_PHY_ID: phy->type = e1000_phy_bm; @@ -286,6 +351,9 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) phy->ops.read_reg = e1000_read_phy_reg_bm; phy->ops.write_reg = e1000_write_phy_reg_bm; phy->ops.commit = e1000_phy_sw_reset_generic; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; break; default: ret_val = -E1000_ERR_PHY; @@ -353,10 +421,13 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) dev_spec->shadow_ram[i].value = 0xFFFF; } + E1000_MUTEX_INIT(&dev_spec->nvm_mutex); + E1000_MUTEX_INIT(&dev_spec->swflag_mutex); + /* Function Pointers */ - nvm->ops.acquire = e1000_acquire_swflag_ich8lan; + nvm->ops.acquire = e1000_acquire_nvm_ich8lan; + nvm->ops.release = e1000_release_nvm_ich8lan; nvm->ops.read = e1000_read_nvm_ich8lan; - nvm->ops.release = e1000_release_swflag_ich8lan; nvm->ops.update = e1000_update_nvm_checksum_ich8lan; nvm->ops.valid_led_default = e1000_valid_led_default_ich8lan; nvm->ops.validate = e1000_validate_nvm_checksum_ich8lan; @@ -391,8 +462,12 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) mac->rar_entry_count--; /* Set if part includes ASF firmware */ mac->asf_firmware_present = TRUE; - /* Set if manageability features are enabled. */ - mac->arc_subsystem_valid = TRUE; + /* FWSM register */ + mac->has_fwsm = TRUE; + /* ARC subsystem not supported */ + mac->arc_subsystem_valid = FALSE; + /* Adaptive IFS supported */ + mac->adaptive_ifs = TRUE; /* Function pointers */ @@ -409,15 +484,13 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) /* physical interface setup */ mac->ops.setup_physical_interface = e1000_setup_copper_link_ich8lan; /* check for link */ - mac->ops.check_for_link = e1000_check_for_copper_link_generic; + mac->ops.check_for_link = e1000_check_for_copper_link_ich8lan; /* check management mode */ mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan; /* link info */ mac->ops.get_link_up_info = e1000_get_link_up_info_ich8lan; /* multicast address update */ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; /* clear hardware counters */ mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan; @@ -460,10 +533,98 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) if (mac->type == e1000_ich8lan) e1000_set_kmrn_lock_loss_workaround_ich8lan(hw, TRUE); - return E1000_SUCCESS; } +/** + * e1000_check_for_copper_link_ich8lan - Check for link (Copper) + * @hw: pointer to the HW structure + * + * Checks to see of the link status of the hardware has changed. If a + * change in link status has been detected, then we read the PHY registers + * to get the current speed/duplex if link exists. + **/ +static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + s32 ret_val; + bool link; + + DEBUGFUNC("e1000_check_for_copper_link_ich8lan"); + + /* + * We only want to go out to the PHY registers to see if Auto-Neg + * has completed and/or if our link status has changed. The + * get_link_status flag is set upon receiving a Link Status + * Change or Rx Sequence Error interrupt. + */ + if (!mac->get_link_status) { + ret_val = E1000_SUCCESS; + goto out; + } + + /* + * First we want to see if the MII Status Register reports + * link. If so, then we want to get the current speed/duplex + * of the PHY. + */ + ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); + if (ret_val) + goto out; + + if (hw->mac.type == e1000_pchlan) { + ret_val = e1000_k1_gig_workaround_hv(hw, link); + if (ret_val) + goto out; + } + + if (!link) + goto out; /* No link detected */ + + mac->get_link_status = FALSE; + + if (hw->phy.type == e1000_phy_82578) { + ret_val = e1000_link_stall_workaround_hv(hw); + if (ret_val) + goto out; + } + + /* + * Check if there was DownShift, must be checked + * immediately after link-up + */ + e1000_check_downshift_generic(hw); + + /* + * If we are forcing speed/duplex, then we simply return since + * we have already determined whether we have link or not. + */ + if (!mac->autoneg) { + ret_val = -E1000_ERR_CONFIG; + goto out; + } + + /* + * Auto-Neg is enabled. Auto Speed Detection takes care + * of MAC speed/duplex configuration. So we only need to + * configure Collision Distance in the MAC. + */ + e1000_config_collision_dist_generic(hw); + + /* + * Configure Flow Control now that Auto-Neg has completed. + * First, we need to restore the desired flow control + * settings because we may have had to re-autoneg with a + * different link partner. + */ + ret_val = e1000_config_fc_after_link_up_generic(hw); + if (ret_val) + DEBUGOUT("Error configuring flow control\n"); + +out: + return ret_val; +} + /** * e1000_init_function_pointers_ich8lan - Initialize ICH8 function pointers * @hw: pointer to the HW structure @@ -490,13 +651,42 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) } } +/** + * e1000_acquire_nvm_ich8lan - Acquire NVM mutex + * @hw: pointer to the HW structure + * + * Acquires the mutex for performing NVM operations. + **/ +static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_acquire_nvm_ich8lan"); + + E1000_MUTEX_LOCK(&hw->dev_spec.ich8lan.nvm_mutex); + + return E1000_SUCCESS; +} + +/** + * e1000_release_nvm_ich8lan - Release NVM mutex + * @hw: pointer to the HW structure + * + * Releases the mutex used while performing NVM operations. + **/ +static void e1000_release_nvm_ich8lan(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_release_nvm_ich8lan"); + + E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.nvm_mutex); + + return; +} + /** * e1000_acquire_swflag_ich8lan - Acquire software control flag * @hw: pointer to the HW structure * - * Acquires the software control flag for performing NVM and PHY - * operations. This is a function pointer entry point only called by - * read/write routines for the PHY and NVM parts. + * Acquires the software control flag for performing PHY and select + * MAC CSR accesses. **/ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) { @@ -505,23 +695,39 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) DEBUGFUNC("e1000_acquire_swflag_ich8lan"); + E1000_MUTEX_LOCK(&hw->dev_spec.ich8lan.swflag_mutex); + while (timeout) { extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); + if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) + break; - if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) { - extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; - E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); - - extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); - if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) - break; - } msec_delay_irq(1); timeout--; } if (!timeout) { DEBUGOUT("SW/FW/HW has locked the resource for too long.\n"); + ret_val = -E1000_ERR_CONFIG; + goto out; + } + + timeout = SW_FLAG_TIMEOUT; + + extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; + E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); + + while (timeout) { + extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); + if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) + break; + + msec_delay_irq(1); + timeout--; + } + + if (!timeout) { + DEBUGOUT("Failed to acquire the semaphore.\n"); extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); ret_val = -E1000_ERR_CONFIG; @@ -529,6 +735,9 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) } out: + if (ret_val) + E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex); + return ret_val; } @@ -536,9 +745,8 @@ out: * e1000_release_swflag_ich8lan - Release software control flag * @hw: pointer to the HW structure * - * Releases the software control flag for performing NVM and PHY operations. - * This is a function pointer entry point only called by read/write - * routines for the PHY and NVM parts. + * Releases the software control flag for performing PHY and select + * MAC CSR accesses. **/ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) { @@ -550,6 +758,8 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); + E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex); + return; } @@ -587,12 +797,333 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) DEBUGFUNC("e1000_check_reset_block_ich8lan"); + if (hw->phy.reset_disable) + return E1000_BLK_PHY_RESET; + fwsm = E1000_READ_REG(hw, E1000_FWSM); return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? E1000_SUCCESS : E1000_BLK_PHY_RESET; } +/** + * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration + * @hw: pointer to the HW structure + * + * SW should configure the LCD from the NVM extended configuration region + * as a workaround for certain parts. + **/ +static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; + s32 ret_val = E1000_SUCCESS; + u16 word_addr, reg_data, reg_addr, phy_page = 0; + + if (!(hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) && + !(hw->mac.type == e1000_pchlan)) + return ret_val; + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + + /* + * Initialize the PHY from the NVM on ICH platforms. This + * is needed due to an issue where the NVM configuration is + * not properly autoloaded after power transitions. + * Therefore, after each PHY reset, we will load the + * configuration data out of the NVM manually. + */ + if ((hw->device_id == E1000_DEV_ID_ICH8_IGP_M_AMT) || + (hw->device_id == E1000_DEV_ID_ICH8_IGP_M) || + (hw->mac.type == e1000_pchlan)) + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; + else + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; + + data = E1000_READ_REG(hw, E1000_FEXTNVM); + if (!(data & sw_cfg_mask)) + goto out; + + /* Wait for basic configuration completes before proceeding */ + e1000_lan_init_done_ich8lan(hw); + + /* + * Make sure HW does not configure LCD from PHY + * extended configuration before SW configuration + */ + data = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); + if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) + goto out; + + cnf_size = E1000_READ_REG(hw, E1000_EXTCNF_SIZE); + cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; + cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; + if (!cnf_size) + goto out; + + cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; + cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; + + if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && + (hw->mac.type == e1000_pchlan)) { + /* + * HW configures the SMBus address and LEDs when the + * OEM and LCD Write Enable bits are set in the NVM. + * When both NVM bits are cleared, SW will configure + * them instead. + */ + data = E1000_READ_REG(hw, E1000_STRAP); + data &= E1000_STRAP_SMBUS_ADDRESS_MASK; + reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; + reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; + ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, + reg_data); + if (ret_val) + goto out; + + data = E1000_READ_REG(hw, E1000_LEDCTL); + ret_val = e1000_write_phy_reg_hv_locked(hw, HV_LED_CONFIG, + (u16)data); + if (ret_val) + goto out; + } + + /* Configure LCD from extended configuration region. */ + + /* cnf_base_addr is in DWORD */ + word_addr = (u16)(cnf_base_addr << 1); + + for (i = 0; i < cnf_size; i++) { + ret_val = hw->nvm.ops.read(hw, (word_addr + i * 2), 1, + ®_data); + if (ret_val) + goto out; + + ret_val = hw->nvm.ops.read(hw, (word_addr + i * 2 + 1), + 1, ®_addr); + if (ret_val) + goto out; + + /* Save off the PHY page for future writes. */ + if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { + phy_page = reg_data; + continue; + } + + reg_addr &= PHY_REG_MASK; + reg_addr |= phy_page; + + ret_val = phy->ops.write_reg_locked(hw, (u32)reg_addr, + reg_data); + if (ret_val) + goto out; + } + +out: + hw->phy.ops.release(hw); + return ret_val; +} + +/** + * e1000_k1_gig_workaround_hv - K1 Si workaround + * @hw: pointer to the HW structure + * @link: link up bool flag + * + * If K1 is enabled for 1Gbps, the MAC might stall when transitioning + * from a lower speed. This workaround disables K1 whenever link is at 1Gig + * If link is down, the function will restore the default K1 setting located + * in the NVM. + **/ +static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) +{ + s32 ret_val = E1000_SUCCESS; + u16 status_reg = 0; + bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled; + + DEBUGFUNC("e1000_k1_gig_workaround_hv"); + + if (hw->mac.type != e1000_pchlan) + goto out; + + /* Wrap the whole flow with the sw flag */ + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + + /* Disable K1 when link is 1Gbps, otherwise use the NVM setting */ + if (link) { + if (hw->phy.type == e1000_phy_82578) { + ret_val = hw->phy.ops.read_reg_locked(hw, BM_CS_STATUS, + &status_reg); + if (ret_val) + goto release; + + status_reg &= BM_CS_STATUS_LINK_UP | + BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_MASK; + + if (status_reg == (BM_CS_STATUS_LINK_UP | + BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_1000)) + k1_enable = FALSE; + } + + if (hw->phy.type == e1000_phy_82577) { + ret_val = hw->phy.ops.read_reg_locked(hw, HV_M_STATUS, + &status_reg); + if (ret_val) + goto release; + + status_reg &= HV_M_STATUS_LINK_UP | + HV_M_STATUS_AUTONEG_COMPLETE | + HV_M_STATUS_SPEED_MASK; + + if (status_reg == (HV_M_STATUS_LINK_UP | + HV_M_STATUS_AUTONEG_COMPLETE | + HV_M_STATUS_SPEED_1000)) + k1_enable = FALSE; + } + + /* Link stall fix for link up */ + ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19), + 0x0100); + if (ret_val) + goto release; + + } else { + /* Link stall fix for link down */ + ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19), + 0x4100); + if (ret_val) + goto release; + } + + ret_val = e1000_configure_k1_ich8lan(hw, k1_enable); + +release: + hw->phy.ops.release(hw); +out: + return ret_val; +} + +/** + * e1000_configure_k1_ich8lan - Configure K1 power state + * @hw: pointer to the HW structure + * @enable: K1 state to configure + * + * Configure the K1 power state based on the provided parameter. + * Assumes semaphore already acquired. + * + * Success returns 0, Failure returns -E1000_ERR_PHY (-2) + **/ +s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) +{ + s32 ret_val = E1000_SUCCESS; + u32 ctrl_reg = 0; + u32 ctrl_ext = 0; + u32 reg = 0; + u16 kmrn_reg = 0; + + ret_val = e1000_read_kmrn_reg_locked(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + &kmrn_reg); + if (ret_val) + goto out; + + if (k1_enable) + kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE; + else + kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE; + + ret_val = e1000_write_kmrn_reg_locked(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + kmrn_reg); + if (ret_val) + goto out; + + usec_delay(20); + ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); + ctrl_reg = E1000_READ_REG(hw, E1000_CTRL); + + reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); + reg |= E1000_CTRL_FRCSPD; + E1000_WRITE_REG(hw, E1000_CTRL, reg); + + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS); + usec_delay(20); + E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg); + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); + usec_delay(20); + +out: + return ret_val; +} + +/** + * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration + * @hw: pointer to the HW structure + * @d0_state: boolean if entering d0 or d3 device state + * + * SW will configure Gbe Disable and LPLU based on the NVM. The four bits are + * collectively called OEM bits. The OEM Write Enable bit and SW Config bit + * in NVM determines whether HW should configure LPLU and Gbe Disable. + **/ +s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) +{ + s32 ret_val = 0; + u32 mac_reg; + u16 oem_reg; + + if (hw->mac.type != e1000_pchlan) + return ret_val; + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + + mac_reg = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); + if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) + goto out; + + mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM); + if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M)) + goto out; + + mac_reg = E1000_READ_REG(hw, E1000_PHY_CTRL); + + ret_val = hw->phy.ops.read_reg_locked(hw, HV_OEM_BITS, &oem_reg); + if (ret_val) + goto out; + + oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU); + + if (d0_state) { + if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE) + oem_reg |= HV_OEM_BITS_GBE_DIS; + + if (mac_reg & E1000_PHY_CTRL_D0A_LPLU) + oem_reg |= HV_OEM_BITS_LPLU; + } else { + if (mac_reg & E1000_PHY_CTRL_NOND0A_GBE_DISABLE) + oem_reg |= HV_OEM_BITS_GBE_DIS; + + if (mac_reg & E1000_PHY_CTRL_NOND0A_LPLU) + oem_reg |= HV_OEM_BITS_LPLU; + } + /* Restart auto-neg to activate the bits */ + if (!hw->phy.ops.check_reset_block(hw)) + oem_reg |= HV_OEM_BITS_RESTART_AN; + ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg); + +out: + hw->phy.ops.release(hw); + + return ret_val; +} + + /** * e1000_hv_phy_powerdown_workaround_ich8lan - Power down workaround on Sx * @hw: pointer to the HW structure @@ -605,6 +1136,26 @@ s32 e1000_hv_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) return hw->phy.ops.write_reg(hw, PHY_REG(768, 25), 0x0444); } +/** + * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode + * @hw: pointer to the HW structure + **/ +static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw) +{ + s32 ret_val; + u16 data; + + ret_val = hw->phy.ops.read_reg(hw, HV_KMRN_MODE_CTRL, &data); + if (ret_val) + return ret_val; + + data |= HV_KMRN_MDIO_SLOW; + + ret_val = hw->phy.ops.write_reg(hw, HV_KMRN_MODE_CTRL, data); + + return ret_val; +} + /** * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be * done after every PHY reset. @@ -612,9 +1163,17 @@ s32 e1000_hv_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; + u16 phy_data; if (hw->mac.type != e1000_pchlan) - return ret_val; + goto out; + + /* Set MDIO slow mode before any other MDIO access */ + if (hw->phy.type == e1000_phy_82577) { + ret_val = e1000_set_mdio_slow_mode_hv(hw); + if (ret_val) + goto out; + } /* Hanksville M Phy init for IEEE. */ if ((hw->revision_id == 2) && @@ -648,12 +1207,12 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) /* Disable generation of early preamble */ ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 25), 0x4431); if (ret_val) - return ret_val; + goto out; /* Preamble tuning for SSC */ ret_val = hw->phy.ops.write_reg(hw, PHY_REG(770, 16), 0xA204); if (ret_val) - return ret_val; + goto out; } if (hw->phy.type == e1000_phy_82578) { @@ -662,13 +1221,13 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) ret_val = hw->phy.ops.write_reg(hw, (1 << 6) | 0x29, 0x66C0); if (ret_val) - return ret_val; + goto out; /* PHY config */ ret_val = hw->phy.ops.write_reg(hw, (1 << 6) | 0x1E, 0xFFFF); if (ret_val) - return ret_val; + goto out; } /* @@ -691,20 +1250,46 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) */ ret_val = hw->phy.ops.write_reg(hw, PHY_REG(768, 25), 0x0400); if (ret_val) - return ret_val; + goto out; ret_val = hw->phy.ops.write_reg(hw, PHY_REG(768, 25), 0x0400); if (ret_val) - return ret_val; + goto out; } /* Select page 0 */ ret_val = hw->phy.ops.acquire(hw); if (ret_val) - return ret_val; - hw->phy.addr = 1; - e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); - hw->phy.ops.release(hw); + goto out; + hw->phy.addr = 1; + ret_val = e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); + hw->phy.ops.release(hw); + if (ret_val) + goto out; + + /* + * Configure the K1 Si workaround during phy reset assuming there is + * link so that it disables K1 if link is in 1Gbps. + */ + ret_val = e1000_k1_gig_workaround_hv(hw, TRUE); + if (ret_val) + goto out; + + /* Workaround for link disconnects on a busy hub in half duplex */ + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + ret_val = hw->phy.ops.read_reg_locked(hw, + PHY_REG(BM_PORT_CTRL_PAGE, 17), + &phy_data); + if (ret_val) + goto release; + ret_val = hw->phy.ops.write_reg_locked(hw, + PHY_REG(BM_PORT_CTRL_PAGE, 17), + phy_data & 0x00FF); +release: + hw->phy.ops.release(hw); +out: return ret_val; } @@ -752,10 +1337,8 @@ static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) { - struct e1000_phy_info *phy = &hw->phy; - u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; - s32 ret_val; - u16 word_addr, reg_data, reg_addr, phy_page = 0; + s32 ret_val = E1000_SUCCESS; + u16 reg; DEBUGFUNC("e1000_phy_hw_reset_ich8lan"); @@ -766,168 +1349,62 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) /* Allow time for h/w to get to a quiescent state after reset */ msec_delay(10); - if (hw->mac.type == e1000_pchlan) { + /* Perform any necessary post-reset workarounds */ + switch (hw->mac.type) { + case e1000_pchlan: ret_val = e1000_hv_phy_workarounds_ich8lan(hw); if (ret_val) goto out; + break; + default: + break; } - /* - * Initialize the PHY from the NVM on ICH platforms. This - * is needed due to an issue where the NVM configuration is - * not properly autoloaded after power transitions. - * Therefore, after each PHY reset, we will load the - * configuration data out of the NVM manually. - */ - if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) { - /* Check if SW needs configure the PHY */ - if ((hw->device_id == E1000_DEV_ID_ICH8_IGP_M_AMT) || - (hw->device_id == E1000_DEV_ID_ICH8_IGP_M)) - sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; - else - sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; + /* Dummy read to clear the phy wakeup bit after lcd reset */ + if (hw->mac.type == e1000_pchlan) + hw->phy.ops.read_reg(hw, BM_WUC, ®); - data = E1000_READ_REG(hw, E1000_FEXTNVM); - if (!(data & sw_cfg_mask)) - goto out; + /* Configure the LCD with the extended configuration region in NVM */ + ret_val = e1000_sw_lcd_config_ich8lan(hw); + if (ret_val) + goto out; - /* Wait for basic configuration completes before proceeding */ - e1000_lan_init_done_ich8lan(hw); - - /* - * Make sure HW does not configure LCD from PHY - * extended configuration before SW configuration - */ - data = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); - if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) - goto out; - - cnf_size = E1000_READ_REG(hw, E1000_EXTCNF_SIZE); - cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; - cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; - if (!cnf_size) - goto out; - - cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; - cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; - - /* Configure LCD from extended configuration region. */ - - /* cnf_base_addr is in DWORD */ - word_addr = (u16)(cnf_base_addr << 1); - - for (i = 0; i < cnf_size; i++) { - ret_val = hw->nvm.ops.read(hw, (word_addr + i * 2), 1, - ®_data); - if (ret_val) - goto out; - - ret_val = hw->nvm.ops.read(hw, (word_addr + i * 2 + 1), - 1, ®_addr); - if (ret_val) - goto out; - - /* Save off the PHY page for future writes. */ - if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { - phy_page = reg_data; - continue; - } - - reg_addr |= phy_page; - - ret_val = phy->ops.write_reg(hw, (u32)reg_addr, reg_data); - if (ret_val) - goto out; - } - } + /* Configure the LCD with the OEM bits in NVM */ + ret_val = e1000_oem_bits_config_ich8lan(hw, TRUE); out: return ret_val; } /** - * e1000_get_phy_info_ich8lan - Calls appropriate PHY type get_phy_info + * e1000_set_lplu_state_pchlan - Set Low Power Link Up state * @hw: pointer to the HW structure + * @active: TRUE to enable LPLU, FALSE to disable * - * Wrapper for calling the get_phy_info routines for the appropriate phy type. + * Sets the LPLU state according to the active flag. For PCH, if OEM write + * bit are disabled in the NVM, writing the LPLU bits in the MAC will not set + * the phy speed. This function will manually set the LPLU bit and restart + * auto-neg as hw would do. D3 and D0 LPLU will call the same function + * since it configures the same bit. **/ -static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) +static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active) { - s32 ret_val = -E1000_ERR_PHY_TYPE; + s32 ret_val = E1000_SUCCESS; + u16 oem_reg; - DEBUGFUNC("e1000_get_phy_info_ich8lan"); + DEBUGFUNC("e1000_set_lplu_state_pchlan"); - switch (hw->phy.type) { - case e1000_phy_ife: - ret_val = e1000_get_phy_info_ife_ich8lan(hw); - break; - case e1000_phy_igp_3: - case e1000_phy_bm: - case e1000_phy_82578: - case e1000_phy_82577: - ret_val = e1000_get_phy_info_igp(hw); - break; - default: - break; - } - - return ret_val; -} - -/** - * e1000_get_phy_info_ife_ich8lan - Retrieves various IFE PHY states - * @hw: pointer to the HW structure - * - * Populates "phy" structure with various feature states. - * This function is only called by other family-specific - * routines. - **/ -static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; - u16 data; - bool link; - - DEBUGFUNC("e1000_get_phy_info_ife_ich8lan"); - - ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); + ret_val = hw->phy.ops.read_reg(hw, HV_OEM_BITS, &oem_reg); if (ret_val) goto out; - if (!link) { - DEBUGOUT("Phy info is only valid if link is up\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; - } + if (active) + oem_reg |= HV_OEM_BITS_LPLU; + else + oem_reg &= ~HV_OEM_BITS_LPLU; - ret_val = phy->ops.read_reg(hw, IFE_PHY_SPECIAL_CONTROL, &data); - if (ret_val) - goto out; - phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE) - ? FALSE : TRUE; - - if (phy->polarity_correction) { - ret_val = e1000_check_polarity_ife(hw); - if (ret_val) - goto out; - } else { - /* Polarity is forced */ - phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; - } - - ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); - if (ret_val) - goto out; - - phy->is_mdix = (data & IFE_PMC_MDIX_STATUS) ? TRUE : FALSE; - - /* The following parameters are undefined for 10/100 operation. */ - phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; - phy->local_rx = e1000_1000t_rx_status_undefined; - phy->remote_rx = e1000_1000t_rx_status_undefined; + oem_reg |= HV_OEM_BITS_RESTART_AN; + ret_val = hw->phy.ops.write_reg(hw, HV_OEM_BITS, oem_reg); out: return ret_val; @@ -1170,7 +1647,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) if (ret_val) goto out; if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == - E1000_ICH_NVM_SIG_VALUE) { + E1000_ICH_NVM_SIG_VALUE) { *bank = 0; goto out; } @@ -1178,11 +1655,11 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) /* Check bank 1 */ ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset + bank1_offset, - &sig_byte); + &sig_byte); if (ret_val) goto out; if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == - E1000_ICH_NVM_SIG_VALUE) { + E1000_ICH_NVM_SIG_VALUE) { *bank = 1; goto out; } @@ -1223,17 +1700,18 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, goto out; } - ret_val = nvm->ops.acquire(hw); - if (ret_val) - goto out; + nvm->ops.acquire(hw); ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); - if (ret_val != E1000_SUCCESS) - goto release; + if (ret_val != E1000_SUCCESS) { + DEBUGOUT("Could not detect valid bank, assuming bank 0\n"); + bank = 0; + } act_offset = (bank) ? nvm->flash_bank_size : 0; act_offset += offset; + ret_val = E1000_SUCCESS; for (i = 0; i < words; i++) { if ((dev_spec->shadow_ram) && (dev_spec->shadow_ram[offset+i].modified)) { @@ -1248,7 +1726,6 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, } } -release: nvm->ops.release(hw); out: @@ -1534,9 +2011,7 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, goto out; } - ret_val = nvm->ops.acquire(hw); - if (ret_val) - goto out; + nvm->ops.acquire(hw); for (i = 0; i < words; i++) { dev_spec->shadow_ram[offset+i].modified = TRUE; @@ -1577,9 +2052,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) if (nvm->type != e1000_nvm_flash_sw) goto out; - ret_val = nvm->ops.acquire(hw); - if (ret_val) - goto out; + nvm->ops.acquire(hw); /* * We're writing to the opposite bank so if we're on bank 1, @@ -1588,26 +2061,22 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) */ ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); if (ret_val != E1000_SUCCESS) { - nvm->ops.release(hw); - goto out; + DEBUGOUT("Could not detect valid bank, assuming bank 0\n"); + bank = 0; } if (bank == 0) { new_bank_offset = nvm->flash_bank_size; old_bank_offset = 0; ret_val = e1000_erase_flash_bank_ich8lan(hw, 1); - if (ret_val) { - nvm->ops.release(hw); - goto out; - } + if (ret_val) + goto release; } else { old_bank_offset = nvm->flash_bank_size; new_bank_offset = 0; ret_val = e1000_erase_flash_bank_ich8lan(hw, 0); - if (ret_val) { - nvm->ops.release(hw); - goto out; - } + if (ret_val) + goto release; } for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { @@ -1662,8 +2131,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) */ if (ret_val) { DEBUGOUT("Flash commit failed.\n"); - nvm->ops.release(hw); - goto out; + goto release; } /* @@ -1674,18 +2142,15 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) */ act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data); - if (ret_val) { - nvm->ops.release(hw); - goto out; - } + if (ret_val) + goto release; + data &= 0xBFFF; ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset * 2 + 1, (u8)(data >> 8)); - if (ret_val) { - nvm->ops.release(hw); - goto out; - } + if (ret_val) + goto release; /* * And invalidate the previously valid segment by setting @@ -1695,10 +2160,8 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) */ act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); - if (ret_val) { - nvm->ops.release(hw); - goto out; - } + if (ret_val) + goto release; /* Great! Everything worked, we can now clear the cached entries. */ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { @@ -1706,14 +2169,17 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) dev_spec->shadow_ram[i].value = 0xFFFF; } +release: nvm->ops.release(hw); /* * Reload the EEPROM, or else modifications will not appear * until after the next adapter reset. */ - nvm->ops.reload(hw); - msec_delay(10); + if (!ret_val) { + nvm->ops.reload(hw); + msec_delay(10); + } out: if (ret_val) @@ -1829,10 +2295,10 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, * try...ICH_FLASH_CYCLE_REPEAT_COUNT times. */ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); - if (hsfsts.hsf_status.flcerr == 1) { + if (hsfsts.hsf_status.flcerr == 1) /* Repeat for some time before giving up. */ continue; - } else if (hsfsts.hsf_status.flcdone == 0) { + if (hsfsts.hsf_status.flcdone == 0) { DEBUGOUT("Timeout error - flash cycle " "did not complete."); break; @@ -1960,7 +2426,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) /* Start with the base address, then add the sector offset. */ flash_linear_addr = hw->nvm.flash_base_addr; - flash_linear_addr += (bank) ? (sector_size * iteration) : 0; + flash_linear_addr += (bank) ? flash_bank_size : 0; for (j = 0; j < iteration ; j++) { do { @@ -2153,6 +2619,8 @@ static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) { + struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; + u16 reg; u32 ctrl, icr, kab; s32 ret_val; @@ -2188,6 +2656,18 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_PBS, E1000_PBS_16K); } + if (hw->mac.type == e1000_pchlan) { + /* Save the NVM K1 bit setting*/ + ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, ®); + if (ret_val) + return ret_val; + + if (reg & E1000_NVM_K1_ENABLE) + dev_spec->nvm_k1_enabled = TRUE; + else + dev_spec->nvm_k1_enabled = FALSE; + } + ctrl = E1000_READ_REG(hw, E1000_CTRL); if (!hw->phy.ops.check_reset_block(hw) && !hw->phy.reset_disable) { @@ -2213,6 +2693,17 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) if (!ret_val) e1000_release_swflag_ich8lan(hw); + /* Perform any necessary post-reset workarounds */ + switch (hw->mac.type) { + case e1000_pchlan: + ret_val = e1000_hv_phy_workarounds_ich8lan(hw); + if (ret_val) + goto out; + break; + default: + break; + } + if (ctrl & E1000_CTRL_PHY_RST) ret_val = hw->phy.ops.get_cfg_done(hw); @@ -2229,6 +2720,24 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) DEBUGOUT("Auto Read Done did not complete\n"); } } + /* Dummy read to clear the phy wakeup bit after lcd reset */ + if (hw->mac.type == e1000_pchlan) + hw->phy.ops.read_reg(hw, BM_WUC, ®); + + ret_val = e1000_sw_lcd_config_ich8lan(hw); + if (ret_val) + goto out; + + ret_val = e1000_oem_bits_config_ich8lan(hw, TRUE); + if (ret_val) + goto out; + /* + * For PCH, this write will make sure that any noise + * will be detected as a CRC error and be dropped rather than show up + * as a bad packet to the DMA engine. + */ + if (hw->mac.type == e1000_pchlan) + E1000_WRITE_REG(hw, E1000_CRC_OFFSET, 0x65656565); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); icr = E1000_READ_REG(hw, E1000_ICR); @@ -2237,9 +2746,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) kab |= E1000_KABGTXD_BGSQLBIAS; E1000_WRITE_REG(hw, E1000_KABGTXD, kab); - if (hw->mac.type == e1000_pchlan) - ret_val = e1000_hv_phy_workarounds_ich8lan(hw); - +out: return ret_val; } @@ -2269,8 +2776,8 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) /* Initialize identification LED */ ret_val = mac->ops.id_led_init(hw); if (ret_val) - /* This is not fatal and we should not stop init due to this */ DEBUGOUT("Error initializing identification LED\n"); + /* This is not fatal and we should not stop init due to this */ /* Setup the receive address. */ e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); @@ -2316,7 +2823,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) if (mac->type == e1000_ich8lan) snoop = PCIE_ICH8_SNOOP_ALL; else - snoop = (u32)~(PCIE_NO_SNOOP_ALL); + snoop = (u32) ~(PCIE_NO_SNOOP_ALL); e1000_set_pcie_no_snoop_generic(hw, snoop); ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); @@ -2387,6 +2894,14 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_STATUS, reg); } + /* + * work-around descriptor data corruption issue during nfs v2 udp + * traffic, just disable the nfs filtering capability + */ + reg = E1000_READ_REG(hw, E1000_RFCTL); + reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS); + E1000_WRITE_REG(hw, E1000_RFCTL, reg); + return; } @@ -2473,8 +2988,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) * and increase the max iterations when polling the phy; * this fixes erroneous timeouts at 10Mbps. */ - ret_val = e1000_write_kmrn_reg_generic(hw, - E1000_KMRNCTRLSTA_TIMEOUTS, + ret_val = e1000_write_kmrn_reg_generic(hw, E1000_KMRNCTRLSTA_TIMEOUTS, 0xFFFF); if (ret_val) goto out; @@ -2788,6 +3302,7 @@ void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw) u32 phy_ctrl; switch (hw->mac.type) { + case e1000_ich8lan: case e1000_ich9lan: case e1000_ich10lan: case e1000_pchlan: @@ -2796,9 +3311,8 @@ void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw) E1000_PHY_CTRL_GBE_DISABLE; E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); - /* Workaround SWFLAG unexpectedly set during S0->Sx */ if (hw->mac.type == e1000_pchlan) - usec_delay(500); + e1000_phy_hw_reset_ich8lan(hw); default: break; } @@ -2814,17 +3328,14 @@ void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; - DEBUGFUNC("e1000_cleanup_led_ich8lan"); if (hw->phy.type == e1000_phy_ife) - ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, - 0); - else - E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default); + return hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, + 0); - return ret_val; + E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default); + return E1000_SUCCESS; } /** @@ -2835,17 +3346,14 @@ static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; - DEBUGFUNC("e1000_led_on_ich8lan"); if (hw->phy.type == e1000_phy_ife) - ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, + return hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON)); - else - E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode2); - return ret_val; + E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode2); + return E1000_SUCCESS; } /** @@ -2856,18 +3364,14 @@ static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; - DEBUGFUNC("e1000_led_off_ich8lan"); if (hw->phy.type == e1000_phy_ife) - ret_val = hw->phy.ops.write_reg(hw, - IFE_PHY_SPECIAL_CONTROL_LED, + return hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF)); - else - E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1); - return ret_val; + E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1); + return E1000_SUCCESS; } /** @@ -2982,18 +3486,17 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) if (hw->mac.type >= e1000_pchlan) { u32 status = E1000_READ_REG(hw, E1000_STATUS); - if (status & E1000_STATUS_PHYRA) { + if (status & E1000_STATUS_PHYRA) E1000_WRITE_REG(hw, E1000_STATUS, status & ~E1000_STATUS_PHYRA); - } else + else DEBUGOUT("PHY Reset Asserted not set - needs delay\n"); } e1000_get_cfg_done_generic(hw); /* If EEPROM is not marked present, init the IGP 3 PHY manually */ - if ((hw->mac.type != e1000_ich10lan) && - (hw->mac.type != e1000_pchlan)) { + if (hw->mac.type <= e1000_ich9lan) { if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) && (hw->phy.type == e1000_phy_igp_3)) { e1000_phy_init_script_igp3(hw); diff --git a/sys/dev/e1000/e1000_ich8lan.h b/sys/dev/e1000/e1000_ich8lan.h index 5416eeb72b2..f26b7b9f70a 100644 --- a/sys/dev/e1000/e1000_ich8lan.h +++ b/sys/dev/e1000/e1000_ich8lan.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -140,6 +140,38 @@ #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ #define HV_TNCRS_LOWER PHY_REG(778, 30) +#define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */ + +#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ +#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ + +/* SMBus Address Phy Register */ +#define HV_SMB_ADDR PHY_REG(768, 26) +#define HV_SMB_ADDR_PEC_EN 0x0200 +#define HV_SMB_ADDR_VALID 0x0080 + +/* Strapping Option Register - RO */ +#define E1000_STRAP 0x0000C +#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 +#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17 + +/* OEM Bits Phy Register */ +#define HV_OEM_BITS PHY_REG(768, 25) +#define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */ +#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */ +#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */ + +#define LCD_CFG_PHY_ADDR_BIT 0x0020 /* Phy address bit from LCD Config word */ + +/* KMRN Mode Control */ +#define HV_KMRN_MODE_CTRL PHY_REG(769, 16) +#define HV_KMRN_MDIO_SLOW 0x0400 + +/* PHY Power Management Control */ +#define HV_PM_CTRL PHY_REG(770, 17) + +#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */ + /* * Additional interrupts need to be handled for ICH family: * DSW = The FW changed the status of the DISSW bit in FWSM @@ -163,12 +195,12 @@ #define E1000_RXDEXT_LINKSEC_ERROR_REPLAY_ERROR 0x40000000 #define E1000_RXDEXT_LINKSEC_ERROR_BAD_SIG 0x60000000 - void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, bool state); void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw); +s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable); +s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_config); s32 e1000_hv_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); - #endif diff --git a/sys/dev/e1000/e1000_mac.c b/sys/dev/e1000/e1000_mac.c index db6e5f52e08..d4d2bec27bd 100644 --- a/sys/dev/e1000/e1000_mac.c +++ b/sys/dev/e1000/e1000_mac.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -78,7 +78,6 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw) mac->ops.update_mc_addr_list = e1000_null_update_mc; mac->ops.clear_vfta = e1000_null_mac_generic; mac->ops.write_vfta = e1000_null_write_vfta; - mac->ops.mta_set = e1000_null_mta_set; mac->ops.rar_set = e1000_rar_set_generic; mac->ops.validate_mdi_setting = e1000_validate_mdi_setting_generic; } @@ -143,16 +142,6 @@ void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b) return; } -/** - * e1000_null_set_mta - No-op function, return void - * @hw: pointer to the HW structure - **/ -void e1000_null_mta_set(struct e1000_hw *hw, u32 a) -{ - DEBUGFUNC("e1000_null_mta_set"); - return; -} - /** * e1000_null_rar_set - No-op function, return void * @hw: pointer to the HW structure @@ -230,24 +219,36 @@ s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_bus_info *bus = &hw->bus; - s32 ret_val; u16 pcie_link_status; DEBUGFUNC("e1000_get_bus_info_pcie_generic"); bus->type = e1000_bus_type_pci_express; - bus->speed = e1000_bus_speed_2500; ret_val = e1000_read_pcie_cap_reg(hw, PCIE_LINK_STATUS, &pcie_link_status); - if (ret_val) + if (ret_val) { bus->width = e1000_bus_width_unknown; - else + bus->speed = e1000_bus_speed_unknown; + } else { + switch (pcie_link_status & PCIE_LINK_SPEED_MASK) { + case PCIE_LINK_SPEED_2500: + bus->speed = e1000_bus_speed_2500; + break; + case PCIE_LINK_SPEED_5000: + bus->speed = e1000_bus_speed_5000; + break; + default: + bus->speed = e1000_bus_speed_unknown; + break; + } + bus->width = (enum e1000_bus_width)((pcie_link_status & PCIE_LINK_WIDTH_MASK) >> PCIE_LINK_WIDTH_SHIFT); + } mac->ops.set_lan_id(hw); @@ -408,6 +409,11 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) if (hw->bus.func == E1000_FUNC_1) nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; + if (hw->bus.func == E1000_FUNC_2) + nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN2; + + if (hw->bus.func == E1000_FUNC_3) + nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN3; for (i = 0; i < ETH_ADDR_LEN; i += 2) { offset = nvm_alt_mac_addr_offset + (i >> 1); ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); @@ -477,42 +483,6 @@ void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) E1000_WRITE_FLUSH(hw); } -/** - * e1000_mta_set_generic - Set multicast filter table address - * @hw: pointer to the HW structure - * @hash_value: determines the MTA register and bit to set - * - * The multicast table address is a register array of 32-bit registers. - * The hash_value is used to determine what register the bit is in, the - * current value is read, the new bit is OR'd in and the new value is - * written back into the register. - **/ -void e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value) -{ - u32 hash_bit, hash_reg, mta; - - DEBUGFUNC("e1000_mta_set_generic"); - /* - * The MTA is a register array of 32-bit registers. It is - * treated like an array of (32*mta_reg_count) bits. We want to - * set bit BitArray[hash_value]. So we figure out what register - * the bit is in, read it, OR in the new bit, then write - * back the new value. The (hw->mac.mta_reg_count - 1) serves as a - * mask to bits 31:5 of the hash value which gives us the - * register we're modifying. The hash bit within that register - * is determined by the lower 5 bits of the hash value. - */ - hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); - hash_bit = hash_value & 0x1F; - - mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg); - - mta |= (1 << hash_bit); - - E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta); - E1000_WRITE_FLUSH(hw); -} - /** * e1000_update_mc_addr_list_generic - Update Multicast addresses * @hw: pointer to the HW structure @@ -556,8 +526,7 @@ void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, * @mc_addr: pointer to a multicast address * * Generates a multicast address hash value which is used to determine - * the multicast filter table array address and new table value. See - * e1000_mta_set_generic() + * the multicast filter table array address and new table value. **/ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr) { @@ -750,12 +719,6 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw) mac->get_link_status = FALSE; - if (hw->phy.type == e1000_phy_82578) { - ret_val = e1000_link_stall_workaround_hv(hw); - if (ret_val) - goto out; - } - /* * Check if there was DownShift, must be checked * immediately after link-up @@ -776,7 +739,7 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw) * of MAC speed/duplex configuration. So we only need to * configure Collision Distance in the MAC. */ - e1000_config_collision_dist_generic(hw); + mac->ops.config_collision_dist(hw); /* * Configure Flow Control now that Auto-Neg has completed. @@ -994,9 +957,8 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw) * In the case of the phy reset being blocked, we already have a link. * We do not need to set it up again. */ - if (hw->phy.ops.check_reset_block) - if (hw->phy.ops.check_reset_block(hw)) - goto out; + if (e1000_check_reset_block(hw)) + goto out; /* * If requested flow control is set to default, set flow control @@ -1050,6 +1012,7 @@ out: **/ s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw) { + struct e1000_mac_info *mac = &hw->mac; u32 ctrl; s32 ret_val = E1000_SUCCESS; @@ -1060,7 +1023,7 @@ s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw) /* Take the link out of reset */ ctrl &= ~E1000_CTRL_LRST; - e1000_config_collision_dist_generic(hw); + mac->ops.config_collision_dist(hw); ret_val = e1000_commit_fc_settings_generic(hw); if (ret_val) @@ -1100,8 +1063,7 @@ out: * @hw: pointer to the HW structure * * Configures the collision distance to the default value and is used - * during link setup. Currently no func pointer exists and all - * implementations are handled in the generic version of this function. + * during link setup. **/ void e1000_config_collision_dist_generic(struct e1000_hw *hw) { @@ -1155,7 +1117,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) * link up if we detect a signal. This will allow us to * communicate with non-autonegotiating link partners. */ - ret_val = hw->mac.ops.check_for_link(hw); + ret_val = mac->ops.check_for_link(hw); if (ret_val) { DEBUGOUT("Error while checking for link\n"); goto out; @@ -1212,7 +1174,7 @@ s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) * Rx Flow control is enabled and Tx Flow control is disabled * by a software over-ride. Since there really isn't a way to * advertise that we are capable of Rx Pause ONLY, we will - * advertise that we support both symmetric and asymmetric RX + * advertise that we support both symmetric and asymmetric Rx * PAUSE. Later, we will disable the adapter's ability to send * PAUSE frames. */ @@ -1256,7 +1218,6 @@ out: **/ s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; u32 fcrtl = 0, fcrth = 0; DEBUGFUNC("e1000_set_fc_watermarks_generic"); @@ -1283,7 +1244,7 @@ s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_FCRTL, fcrtl); E1000_WRITE_REG(hw, E1000_FCRTH, fcrth); - return ret_val; + return E1000_SUCCESS; } /** @@ -1512,7 +1473,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) /* * Now we need to check if the user selected Rx ONLY * of pause frames. In this case, we had to advertise - * FULL flow control because we could not advertise RX + * FULL flow control because we could not advertise Rx * ONLY. Hence, we must now check to see if we need to * turn OFF the TRANSMISSION of PAUSE frames. */ @@ -1522,7 +1483,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) } else { hw->fc.current_mode = e1000_fc_rx_pause; DEBUGOUT("Flow Control = " - "RX PAUSE frames only.\r\n"); + "Rx PAUSE frames only.\r\n"); } } /* @@ -1538,7 +1499,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc.current_mode = e1000_fc_tx_pause; - DEBUGOUT("Flow Control = TX PAUSE frames only.\r\n"); + DEBUGOUT("Flow Control = Tx PAUSE frames only.\r\n"); } /* * For transmitting PAUSE frames ONLY. @@ -1553,7 +1514,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc.current_mode = e1000_fc_rx_pause; - DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n"); + DEBUGOUT("Flow Control = Rx PAUSE frames only.\r\n"); } else { /* * Per the IEEE spec, at this point flow control @@ -1895,19 +1856,10 @@ out: **/ s32 e1000_cleanup_led_generic(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; - DEBUGFUNC("e1000_cleanup_led_generic"); - if (hw->mac.ops.cleanup_led != e1000_cleanup_led_generic) { - ret_val = -E1000_ERR_CONFIG; - goto out; - } - E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default); - -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -2033,7 +1985,7 @@ out: * e1000_disable_pcie_master_generic - Disables PCI-express master access * @hw: pointer to the HW structure * - * Returns 0 (E1000_SUCCESS) if successful, else returns -10 + * Returns E1000_SUCCESS if successful, else returns -10 * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused * the master requests to be disabled. * @@ -2066,7 +2018,6 @@ s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw) if (!timeout) { DEBUGOUT("Master requests are pending.\n"); ret_val = -E1000_ERR_MASTER_REQUESTS_PENDING; - goto out; } out: @@ -2151,7 +2102,7 @@ out: * Verify that when not using auto-negotiation that MDI/MDIx is correctly * set, which is forced to MDI mode only. **/ -s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw) +static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; diff --git a/sys/dev/e1000/e1000_mac.h b/sys/dev/e1000/e1000_mac.h index b7a5b2c5ecb..348d660f973 100644 --- a/sys/dev/e1000/e1000_mac.h +++ b/sys/dev/e1000/e1000_mac.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -46,7 +46,6 @@ s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d); bool e1000_null_mng_mode(struct e1000_hw *hw); void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a); void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b); -void e1000_null_mta_set(struct e1000_hw *hw, u32 a); void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a); s32 e1000_blink_led_generic(struct e1000_hw *hw); s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw); @@ -87,7 +86,6 @@ void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw); void e1000_clear_vfta_generic(struct e1000_hw *hw); void e1000_config_collision_dist_generic(struct e1000_hw *hw); void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count); -void e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value); void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw); void e1000_put_hw_semaphore_generic(struct e1000_hw *hw); void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index); diff --git a/sys/dev/e1000/e1000_manage.c b/sys/dev/e1000/e1000_manage.c index b1f6541ad0c..0b295f8d384 100644 --- a/sys/dev/e1000/e1000_manage.c +++ b/sys/dev/e1000/e1000_manage.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -74,10 +74,16 @@ s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw) { u32 hicr; s32 ret_val = E1000_SUCCESS; - u8 i; + u8 i; DEBUGFUNC("e1000_mng_enable_host_if_generic"); + if (!(hw->mac.arc_subsystem_valid)) { + DEBUGOUT("ARC subsystem not valid.\n"); + ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; + goto out; + } + /* Check that the host interface is enabled. */ hicr = E1000_READ_REG(hw, E1000_HICR); if ((hicr & E1000_HICR_EN) == 0) { @@ -112,18 +118,17 @@ out: **/ bool e1000_check_mng_mode_generic(struct e1000_hw *hw) { - u32 fwsm; + u32 fwsm = E1000_READ_REG(hw, E1000_FWSM); DEBUGFUNC("e1000_check_mng_mode_generic"); - fwsm = E1000_READ_REG(hw, E1000_FWSM); return (fwsm & E1000_FWSM_MODE_MASK) == (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); } /** - * e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on TX + * e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on Tx * @hw: pointer to the HW structure * * Enables packet filtering on transmit packets if manageability is enabled @@ -136,13 +141,14 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) u32 offset; s32 ret_val, hdr_csum, csum; u8 i, len; - bool tx_filter = TRUE; DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic"); + hw->mac.tx_pkt_filtering = TRUE; + /* No manageability, no filtering */ if (!hw->mac.ops.check_mng_mode(hw)) { - tx_filter = FALSE; + hw->mac.tx_pkt_filtering = FALSE; goto out; } @@ -152,18 +158,16 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) */ ret_val = hw->mac.ops.mng_enable_host_if(hw); if (ret_val != E1000_SUCCESS) { - tx_filter = FALSE; + hw->mac.tx_pkt_filtering = FALSE; goto out; } /* Read in the header. Length and offset are in dwords. */ len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; - for (i = 0; i < len; i++) { - *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, - E1000_HOST_IF, + for (i = 0; i < len; i++) + *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i); - } hdr_csum = hdr->checksum; hdr->checksum = 0; csum = e1000_calculate_checksum((u8 *)hdr, @@ -173,18 +177,19 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) * the cookie area isn't considered valid, in which case we * take the safe route of assuming Tx filtering is enabled. */ - if (hdr_csum != csum) - goto out; - if (hdr->signature != E1000_IAMT_SIGNATURE) + if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { + hw->mac.tx_pkt_filtering = TRUE; goto out; + } /* Cookie area is valid, make the final check for filtering. */ - if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) - tx_filter = FALSE; + if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { + hw->mac.tx_pkt_filtering = FALSE; + goto out; + } out: - hw->mac.tx_pkt_filtering = tx_filter; - return tx_filter; + return hw->mac.tx_pkt_filtering; } /** @@ -344,10 +349,11 @@ out: } /** - * e1000_enable_mng_pass_thru - Enable processing of ARP's + * e1000_enable_mng_pass_thru - Check if management passthrough is needed * @hw: pointer to the HW structure * - * Verifies the hardware needs to allow ARPs to be processed by the host. + * Verifies the hardware needs to leave interface enabled so that frames can + * be directed to and from the management interface. **/ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) { @@ -362,11 +368,10 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) manc = E1000_READ_REG(hw, E1000_MANC); - if (!(manc & E1000_MANC_RCV_TCO_EN) || - !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) + if (!(manc & E1000_MANC_RCV_TCO_EN)) goto out; - if (hw->mac.arc_subsystem_valid) { + if (hw->mac.has_fwsm) { fwsm = E1000_READ_REG(hw, E1000_FWSM); factps = E1000_READ_REG(hw, E1000_FACTPS); @@ -376,12 +381,23 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) ret_val = TRUE; goto out; } - } else { - if ((manc & E1000_MANC_SMBUS_EN) && - !(manc & E1000_MANC_ASF_EN)) { + } else if ((hw->mac.type == e1000_82574) || + (hw->mac.type == e1000_82583)) { + u16 data; + + factps = E1000_READ_REG(hw, E1000_FACTPS); + e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); + + if (!(factps & E1000_FACTPS_MNGCG) && + ((data & E1000_NVM_INIT_CTRL2_MNGM) == + (e1000_mng_mode_pt << 13))) { ret_val = TRUE; goto out; } + } else if ((manc & E1000_MANC_SMBUS_EN) && + !(manc & E1000_MANC_ASF_EN)) { + ret_val = TRUE; + goto out; } out: diff --git a/sys/dev/e1000/e1000_osdep.h b/sys/dev/e1000/e1000_osdep.h index b478f29fb0f..ff505cc19ca 100644 --- a/sys/dev/e1000/e1000_osdep.h +++ b/sys/dev/e1000/e1000_osdep.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include #include @@ -57,10 +59,8 @@ #define ASSERT(x) if(!(x)) panic("EM: x") -/* The happy-fun DELAY macro is defined in /usr/src/sys/i386/include/clock.h */ #define usec_delay(x) DELAY(x) #define msec_delay(x) DELAY(1000*(x)) -/* TODO: Should we be paranoid about delaying in interrupt context? */ #define msec_delay_irq(x) DELAY(1000*(x)) #define MSGOUT(S, A, B) printf(S "\n", A, B) @@ -73,16 +73,21 @@ #define STATIC static #define FALSE 0 -#define false FALSE /* shared code stupidity */ +#define false FALSE #define TRUE 1 #define true TRUE #define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */ #define PCI_COMMAND_REGISTER PCIR_COMMAND -/* -** These typedefs are necessary due to the new -** shared code, they are native to Linux. -*/ +/* Mutex used in the shared code */ +#define E1000_MUTEX struct mtx +#define E1000_MUTEX_INIT(mutex) mtx_init((mutex), #mutex, \ + MTX_NETWORK_LOCK, MTX_DEF) +#define E1000_MUTEX_DESTROY(mutex) mtx_destroy(mutex) +#define E1000_MUTEX_LOCK(mutex) mtx_lock(mutex) +#define E1000_MUTEX_TRYLOCK(mutex) mtx_trylock(mutex) +#define E1000_MUTEX_UNLOCK(mutex) mtx_unlock(mutex) + typedef uint64_t u64; typedef uint32_t u32; typedef uint16_t u16; @@ -97,6 +102,28 @@ typedef boolean_t bool; #define __le32 u32 #define __le64 u64 +#if __FreeBSD_version < 800000 /* Now in HEAD */ +#if defined(__i386__) || defined(__amd64__) +#define mb() __asm volatile("mfence" ::: "memory") +#define wmb() __asm volatile("sfence" ::: "memory") +#define rmb() __asm volatile("lfence" ::: "memory") +#else +#define mb() +#define rmb() +#define wmb() +#endif +#endif /*__FreeBSD_version < 800000 */ + +#if defined(__i386__) || defined(__amd64__) +static __inline +void prefetch(void *x) +{ + __asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x)); +} +#else +#define prefetch(x) +#endif + struct e1000_osdep { bus_space_tag_t mem_bus_space_tag; diff --git a/sys/dev/e1000/e1000_phy.c b/sys/dev/e1000/e1000_phy.c index 513f2e67fb4..24ca36f6ebb 100644 --- a/sys/dev/e1000/e1000_phy.c +++ b/sys/dev/e1000/e1000_phy.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -83,11 +83,13 @@ void e1000_init_phy_ops_generic(struct e1000_hw *hw) phy->ops.get_cable_length = e1000_null_ops_generic; phy->ops.get_info = e1000_null_ops_generic; phy->ops.read_reg = e1000_null_read_reg; + phy->ops.read_reg_locked = e1000_null_read_reg; phy->ops.release = e1000_null_phy_generic; phy->ops.reset = e1000_null_ops_generic; phy->ops.set_d0_lplu_state = e1000_null_lplu_state; phy->ops.set_d3_lplu_state = e1000_null_lplu_state; phy->ops.write_reg = e1000_null_write_reg; + phy->ops.write_reg_locked = e1000_null_write_reg; phy->ops.power_up = e1000_null_phy_generic; phy->ops.power_down = e1000_null_phy_generic; phy->ops.cfg_on_link_up = e1000_null_ops_generic; @@ -189,22 +191,9 @@ s32 e1000_get_phy_id(struct e1000_hw *hw) if (phy->id != 0 && phy->id != PHY_REVISION_MASK) goto out; - /* - * If the PHY ID is still unknown, we may have an 82577 without link. - * We will try again after setting Slow MDIC mode. No harm in trying - * again in this case since the PHY ID is unknown at this point anyway - */ - ret_val = e1000_set_mdio_slow_mode_hv(hw, TRUE); - if (ret_val) - goto out; - retry_count++; } out: - /* Revert to MDIO fast mode, if applicable */ - if (retry_count) - ret_val = e1000_set_mdio_slow_mode_hv(hw, FALSE); - return ret_val; } @@ -250,6 +239,11 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) DEBUGFUNC("e1000_read_phy_reg_mdic"); + if (offset > MAX_PHY_REG_ADDRESS) { + DEBUGOUT1("PHY Address %d is out of range\n", offset); + return -E1000_ERR_PARAM; + } + /* * Set up Op-code, Phy Address, and register offset in the MDI * Control register. The MAC will take care of interfacing with the @@ -308,6 +302,11 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) DEBUGFUNC("e1000_write_phy_reg_mdic"); + if (offset > MAX_PHY_REG_ADDRESS) { + DEBUGOUT1("PHY Address %d is out of range\n", offset); + return -E1000_ERR_PARAM; + } + /* * Set up Op-code, Phy Address, and register offset in the MDI * Control register. The MAC will take care of interfacing with the @@ -350,6 +349,105 @@ out: return ret_val; } +/** + * e1000_read_phy_reg_i2c - Read PHY register using i2c + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Reads the PHY register at offset using the i2c interface and stores the + * retrieved information in data. + **/ +s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data) +{ + struct e1000_phy_info *phy = &hw->phy; + u32 i, i2ccmd = 0; + + DEBUGFUNC("e1000_read_phy_reg_i2c"); + + /* + * Set up Op-code, Phy Address, and register address in the I2CCMD + * register. The MAC will take care of interfacing with the + * PHY to retrieve the desired data. + */ + i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | + (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | + (E1000_I2CCMD_OPCODE_READ)); + + E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); + + /* Poll the ready bit to see if the I2C read completed */ + for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { + usec_delay(50); + i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD); + if (i2ccmd & E1000_I2CCMD_READY) + break; + } + if (!(i2ccmd & E1000_I2CCMD_READY)) { + DEBUGOUT("I2CCMD Read did not complete\n"); + return -E1000_ERR_PHY; + } + if (i2ccmd & E1000_I2CCMD_ERROR) { + DEBUGOUT("I2CCMD Error bit set\n"); + return -E1000_ERR_PHY; + } + + /* Need to byte-swap the 16-bit value. */ + *data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00); + + return E1000_SUCCESS; +} + +/** + * e1000_write_phy_reg_i2c - Write PHY register using i2c + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Writes the data to PHY register at the offset using the i2c interface. + **/ +s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data) +{ + struct e1000_phy_info *phy = &hw->phy; + u32 i, i2ccmd = 0; + u16 phy_data_swapped; + + DEBUGFUNC("e1000_write_phy_reg_i2c"); + + /* Swap the data bytes for the I2C interface */ + phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00); + + /* + * Set up Op-code, Phy Address, and register address in the I2CCMD + * register. The MAC will take care of interfacing with the + * PHY to retrieve the desired data. + */ + i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | + (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | + E1000_I2CCMD_OPCODE_WRITE | + phy_data_swapped); + + E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); + + /* Poll the ready bit to see if the I2C read completed */ + for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { + usec_delay(50); + i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD); + if (i2ccmd & E1000_I2CCMD_READY) + break; + } + if (!(i2ccmd & E1000_I2CCMD_READY)) { + DEBUGOUT("I2CCMD Write did not complete\n"); + return -E1000_ERR_PHY; + } + if (i2ccmd & E1000_I2CCMD_ERROR) { + DEBUGOUT("I2CCMD Error bit set\n"); + return -E1000_ERR_PHY; + } + + return E1000_SUCCESS; +} + /** * e1000_read_phy_reg_m88 - Read m88 PHY register * @hw: pointer to the HW structure @@ -414,42 +512,119 @@ out: } /** - * e1000_read_phy_reg_igp - Read igp PHY register + * __e1000_read_phy_reg_igp - Read igp PHY register * @hw: pointer to the HW structure * @offset: register offset to be read * @data: pointer to the read data + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retrieved information in data. Release any acquired + * and stores the retrieved information in data. Release any acquired * semaphores before exiting. **/ -s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) +static s32 __e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data, + bool locked) { s32 ret_val = E1000_SUCCESS; - DEBUGFUNC("e1000_read_phy_reg_igp"); + DEBUGFUNC("__e1000_read_phy_reg_igp"); - if (!(hw->phy.ops.acquire)) - goto out; + if (!locked) { + if (!(hw->phy.ops.acquire)) + goto out; - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + } if (offset > MAX_PHY_MULTI_PAGE_REG) { ret_val = e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, (u16)offset); - if (ret_val) { - hw->phy.ops.release(hw); - goto out; - } + if (ret_val) + goto release; } ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - hw->phy.ops.release(hw); +release: + if (!locked) + hw->phy.ops.release(hw); +out: + return ret_val; +} + +/** + * e1000_read_phy_reg_igp - Read igp PHY register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Acquires semaphore then reads the PHY register at offset and stores the + * retrieved information in data. + * Release the acquired semaphore before exiting. + **/ +s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_phy_reg_igp(hw, offset, data, FALSE); +} + +/** + * e1000_read_phy_reg_igp_locked - Read igp PHY register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Reads the PHY register at offset and stores the retrieved information + * in data. Assumes semaphore already acquired. + **/ +s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_phy_reg_igp(hw, offset, data, TRUE); +} + +/** + * e1000_write_phy_reg_igp - Write igp PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * @locked: semaphore has already been acquired or not + * + * Acquires semaphore, if necessary, then writes the data to PHY register + * at the offset. Release any acquired semaphores before exiting. + **/ +static s32 __e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data, + bool locked) +{ + s32 ret_val = E1000_SUCCESS; + + DEBUGFUNC("e1000_write_phy_reg_igp"); + + if (!locked) { + if (!(hw->phy.ops.acquire)) + goto out; + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + } + + if (offset > MAX_PHY_MULTI_PAGE_REG) { + ret_val = e1000_write_phy_reg_mdic(hw, + IGP01E1000_PHY_PAGE_SELECT, + (u16)offset); + if (ret_val) + goto release; + } + + ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, + data); + +release: + if (!locked) + hw->phy.ops.release(hw); out: return ret_val; @@ -461,64 +636,55 @@ out: * @offset: register offset to write to * @data: data to write at register offset * - * Acquires semaphore, if necessary, then writes the data to PHY register + * Acquires semaphore then writes the data to PHY register * at the offset. Release any acquired semaphores before exiting. **/ s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) { - s32 ret_val = E1000_SUCCESS; - - DEBUGFUNC("e1000_write_phy_reg_igp"); - - if (!(hw->phy.ops.acquire)) - goto out; - - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; - - if (offset > MAX_PHY_MULTI_PAGE_REG) { - ret_val = e1000_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (u16)offset); - if (ret_val) { - hw->phy.ops.release(hw); - goto out; - } - } - - ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); - - hw->phy.ops.release(hw); - -out: - return ret_val; + return __e1000_write_phy_reg_igp(hw, offset, data, FALSE); } /** - * e1000_read_kmrn_reg_generic - Read kumeran register + * e1000_write_phy_reg_igp_locked - Write igp PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Writes the data to PHY register at the offset. + * Assumes semaphore already acquired. + **/ +s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_phy_reg_igp(hw, offset, data, TRUE); +} + +/** + * __e1000_read_kmrn_reg - Read kumeran register * @hw: pointer to the HW structure * @offset: register offset to be read * @data: pointer to the read data + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary. Then reads the PHY register at offset * using the kumeran interface. The information retrieved is stored in data. * Release any acquired semaphores before exiting. **/ -s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data) +static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data, + bool locked) { u32 kmrnctrlsta; s32 ret_val = E1000_SUCCESS; - DEBUGFUNC("e1000_read_kmrn_reg_generic"); + DEBUGFUNC("__e1000_read_kmrn_reg"); - if (!(hw->phy.ops.acquire)) - goto out; + if (!locked) { + if (!(hw->phy.ops.acquire)) + goto out; - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + } kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; @@ -529,47 +695,112 @@ s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data) kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA); *data = (u16)kmrnctrlsta; - hw->phy.ops.release(hw); + if (!locked) + hw->phy.ops.release(hw); out: return ret_val; } /** - * e1000_write_kmrn_reg_generic - Write kumeran register + * e1000_read_kmrn_reg_generic - Read kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Acquires semaphore then reads the PHY register at offset using the + * kumeran interface. The information retrieved is stored in data. + * Release the acquired semaphore before exiting. + **/ +s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_kmrn_reg(hw, offset, data, FALSE); +} + +/** + * e1000_read_kmrn_reg_locked - Read kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Reads the PHY register at offset using the kumeran interface. The + * information retrieved is stored in data. + * Assumes semaphore already acquired. + **/ +s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_kmrn_reg(hw, offset, data, TRUE); +} + +/** + * __e1000_write_kmrn_reg - Write kumeran register * @hw: pointer to the HW structure * @offset: register offset to write to * @data: data to write at register offset + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary. Then write the data to PHY register * at the offset using the kumeran interface. Release any acquired semaphores * before exiting. **/ -s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data) +static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data, + bool locked) { u32 kmrnctrlsta; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_write_kmrn_reg_generic"); - if (!(hw->phy.ops.acquire)) - goto out; + if (!locked) { + if (!(hw->phy.ops.acquire)) + goto out; - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + } kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | data; E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); usec_delay(2); - hw->phy.ops.release(hw); + + if (!locked) + hw->phy.ops.release(hw); out: return ret_val; } +/** + * e1000_write_kmrn_reg_generic - Write kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Acquires semaphore then writes the data to the PHY register at the offset + * using the kumeran interface. Release the acquired semaphore before exiting. + **/ +s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_kmrn_reg(hw, offset, data, FALSE); +} + +/** + * e1000_write_kmrn_reg_locked - Write kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Write the data to PHY register at the offset using the kumeran interface. + * Assumes semaphore already acquired. + **/ +s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_kmrn_reg(hw, offset, data, TRUE); +} + /** * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link * @hw: pointer to the HW structure @@ -578,19 +809,26 @@ out: **/ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) { - struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 phy_data; DEBUGFUNC("e1000_copper_link_setup_82577"); - if (phy->reset_disable) { + if (hw->phy.reset_disable) { ret_val = E1000_SUCCESS; goto out; } + if (hw->phy.type == e1000_phy_82580) { + ret_val = hw->phy.ops.reset(hw); + if (ret_val) { + DEBUGOUT("Error resetting the PHY.\n"); + goto out; + } + } + /* Enable CRS on TX. This must be set for half-duplex operation. */ - ret_val = phy->ops.read_reg(hw, I82577_CFG_REG, &phy_data); + ret_val = hw->phy.ops.read_reg(hw, I82577_CFG_REG, &phy_data); if (ret_val) goto out; @@ -599,16 +837,7 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) /* Enable downshift */ phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; - ret_val = phy->ops.write_reg(hw, I82577_CFG_REG, phy_data); - if (ret_val) - goto out; - - /* Set number of link attempts before downshift */ - ret_val = phy->ops.read_reg(hw, I82577_CTRL_REG, &phy_data); - if (ret_val) - goto out; - phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK; - ret_val = phy->ops.write_reg(hw, I82577_CTRL_REG, phy_data); + ret_val = hw->phy.ops.write_reg(hw, I82577_CFG_REG, phy_data); out: return ret_val; @@ -634,7 +863,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) goto out; } - /* Enable CRS on TX. This must be set for half-duplex operation. */ + /* Enable CRS on Tx. This must be set for half-duplex operation. */ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; @@ -1326,18 +1555,22 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) goto out; if (!link) { - /* - * We didn't get link. - * Reset the DSP and cross our fingers. - */ - ret_val = phy->ops.write_reg(hw, - M88E1000_PHY_PAGE_SELECT, - 0x001d); - if (ret_val) - goto out; - ret_val = e1000_phy_reset_dsp_generic(hw); - if (ret_val) - goto out; + if (hw->phy.type != e1000_phy_m88) { + DEBUGOUT("Link taking longer than expected.\n"); + } else { + /* + * We didn't get link. + * Reset the DSP and cross our fingers. + */ + ret_val = phy->ops.write_reg(hw, + M88E1000_PHY_PAGE_SELECT, + 0x001d); + if (ret_val) + goto out; + ret_val = e1000_phy_reset_dsp_generic(hw); + if (ret_val) + goto out; + } } /* Try once more */ @@ -1347,6 +1580,9 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) goto out; } + if (hw->phy.type != e1000_phy_m88) + goto out; + ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; @@ -1393,11 +1629,6 @@ s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw) DEBUGFUNC("e1000_phy_force_speed_duplex_ife"); - if (phy->type != e1000_phy_ife) { - ret_val = e1000_phy_force_speed_duplex_igp(hw); - goto out; - } - ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data); if (ret_val) goto out; @@ -1625,12 +1856,11 @@ s32 e1000_check_downshift_generic(struct e1000_hw *hw) case e1000_phy_gg82563: case e1000_phy_bm: case e1000_phy_82578: - case e1000_phy_82577: offset = M88E1000_PHY_SPEC_STATUS; mask = M88E1000_PSSR_DOWNSHIFT; break; - case e1000_phy_igp_2: case e1000_phy_igp: + case e1000_phy_igp_2: case e1000_phy_igp_3: offset = IGP01E1000_PHY_LINK_HEALTH; mask = IGP01E1000_PLHR_SS_DOWNGRADE; @@ -1825,16 +2055,14 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, * it across the board. */ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); - if (ret_val) { + if (ret_val) /* * If the first read fails, another entity may have * ownership of the resources, wait and try again to * see if they have relinquished the resources yet. */ usec_delay(usec_interval); - ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, - &phy_status); - } + ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); if (ret_val) break; if (phy_status & MII_SR_LINK_STATUS) @@ -1879,13 +2107,13 @@ s32 e1000_get_cable_length_m88(struct e1000_hw *hw) index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> M88E1000_PSSR_CABLE_LENGTH_SHIFT; - if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE + 1) { - ret_val = E1000_ERR_PHY; + if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) { + ret_val = -E1000_ERR_PHY; goto out; } phy->min_cable_length = e1000_m88_cable_length_table[index]; - phy->max_cable_length = e1000_m88_cable_length_table[index+1]; + phy->max_cable_length = e1000_m88_cable_length_table[index + 1]; phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; @@ -1986,7 +2214,7 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw) DEBUGFUNC("e1000_get_phy_info_m88"); - if (hw->phy.media_type != e1000_media_type_copper) { + if (phy->media_type != e1000_media_type_copper) { DEBUGOUT("Phy info is only valid for copper media\n"); ret_val = -E1000_ERR_CONFIG; goto out; @@ -2088,7 +2316,7 @@ s32 e1000_get_phy_info_igp(struct e1000_hw *hw) if ((data & IGP01E1000_PSSR_SPEED_MASK) == IGP01E1000_PSSR_SPEED_1000MBPS) { - ret_val = hw->phy.ops.get_cable_length(hw); + ret_val = phy->ops.get_cable_length(hw); if (ret_val) goto out; @@ -2113,6 +2341,63 @@ out: return ret_val; } +/** + * e1000_get_phy_info_ife - Retrieves various IFE PHY states + * @hw: pointer to the HW structure + * + * Populates "phy" structure with various feature states. + **/ +s32 e1000_get_phy_info_ife(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 data; + bool link; + + DEBUGFUNC("e1000_get_phy_info_ife"); + + ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); + if (ret_val) + goto out; + + if (!link) { + DEBUGOUT("Phy info is only valid if link is up\n"); + ret_val = -E1000_ERR_CONFIG; + goto out; + } + + ret_val = phy->ops.read_reg(hw, IFE_PHY_SPECIAL_CONTROL, &data); + if (ret_val) + goto out; + phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE) + ? FALSE : TRUE; + + if (phy->polarity_correction) { + ret_val = e1000_check_polarity_ife(hw); + if (ret_val) + goto out; + } else { + /* Polarity is forced */ + phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal; + } + + ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); + if (ret_val) + goto out; + + phy->is_mdix = (data & IFE_PMC_MDIX_STATUS) ? TRUE : FALSE; + + /* The following parameters are undefined for 10/100 operation. */ + phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; + phy->local_rx = e1000_1000t_rx_status_undefined; + phy->remote_rx = e1000_1000t_rx_status_undefined; + +out: + return ret_val; +} + /** * e1000_phy_sw_reset_generic - PHY software reset * @hw: pointer to the HW structure @@ -2302,7 +2587,7 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id) { enum e1000_phy_type phy_type = e1000_phy_unknown; - switch (phy_id) { + switch (phy_id) { case M88E1000_I_PHY_ID: case M88E1000_E_PHY_ID: case M88E1111_I_PHY_ID: @@ -2333,6 +2618,9 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id) case I82577_E_PHY_ID: phy_type = e1000_phy_82577; break; + case I82580_I_PHY_ID: + phy_type = e1000_phy_82580; + break; default: phy_type = e1000_phy_unknown; break; @@ -2416,6 +2704,10 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) DEBUGFUNC("e1000_write_phy_reg_bm"); + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, @@ -2423,10 +2715,6 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) goto out; } - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; - hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); if (offset > MAX_PHY_MULTI_PAGE_REG) { @@ -2446,18 +2734,15 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000_write_phy_reg_mdic(hw, page_select, (page << page_shift)); - if (ret_val) { - hw->phy.ops.release(hw); + if (ret_val) goto out; - } } ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - hw->phy.ops.release(hw); - out: + hw->phy.ops.release(hw); return ret_val; } @@ -2480,6 +2765,10 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) DEBUGFUNC("e1000_read_phy_reg_bm"); + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, @@ -2487,10 +2776,6 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) goto out; } - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; - hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); if (offset > MAX_PHY_MULTI_PAGE_REG) { @@ -2510,17 +2795,14 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000_write_phy_reg_mdic(hw, page_select, (page << page_shift)); - if (ret_val) { - hw->phy.ops.release(hw); + if (ret_val) goto out; - } } ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - hw->phy.ops.release(hw); - out: + hw->phy.ops.release(hw); return ret_val; } @@ -2541,6 +2823,10 @@ s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) DEBUGFUNC("e1000_write_phy_reg_bm2"); + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, @@ -2548,10 +2834,6 @@ s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) goto out; } - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; - hw->phy.addr = 1; if (offset > MAX_PHY_MULTI_PAGE_REG) { @@ -2560,17 +2842,14 @@ s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, page); - if (ret_val) { - hw->phy.ops.release(hw); + if (ret_val) goto out; - } } ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - hw->phy.ops.release(hw); - out: + hw->phy.ops.release(hw); return ret_val; } @@ -2590,6 +2869,10 @@ s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) DEBUGFUNC("e1000_write_phy_reg_bm2"); + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, @@ -2597,10 +2880,6 @@ s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) goto out; } - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; - hw->phy.addr = 1; if (offset > MAX_PHY_MULTI_PAGE_REG) { @@ -2608,18 +2887,15 @@ s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, page); - if (ret_val) { - hw->phy.ops.release(hw); + if (ret_val) goto out; - } } ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - hw->phy.ops.release(hw); - out: + hw->phy.ops.release(hw); return ret_val; } @@ -2639,6 +2915,8 @@ out: * 3) Write the address using the address opcode (0x11) * 4) Read or write the data using the data opcode (0x12) * 5) Restore 769_17.2 to its original value + * + * Assumes semaphore already acquired. **/ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data, bool read) @@ -2646,7 +2924,6 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, s32 ret_val; u16 reg = BM_PHY_REG_NUM(offset); u16 phy_reg = 0; - u8 phy_acquired = 1; DEBUGFUNC("e1000_access_phy_wakeup_reg_bm"); @@ -2655,13 +2932,6 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, (!(E1000_READ_REG(hw, E1000_PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) DEBUGOUT("Attempting to access page 800 while gig enabled.\n"); - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) { - DEBUGOUT("Could not acquire PHY\n"); - phy_acquired = 0; - goto out; - } - /* All operations in this function are phy address 1 */ hw->phy.addr = 1; @@ -2733,8 +3003,6 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, } out: - if (phy_acquired == 1) - hw->phy.ops.release(hw); return ret_val; } @@ -2775,31 +3043,70 @@ void e1000_power_down_phy_copper(struct e1000_hw *hw) msec_delay(1); } -s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) +/** + * __e1000_read_phy_reg_hv - Read HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * @locked: semaphore has already been acquired or not + * + * Acquires semaphore, if necessary, then reads the PHY register at offset + * and stores the retrieved information in data. Release any acquired + * semaphore before exiting. + **/ +static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, + bool locked) { - s32 ret_val = E1000_SUCCESS; - u16 data = 0; + s32 ret_val; + u16 page = BM_PHY_REG_PAGE(offset); + u16 reg = BM_PHY_REG_NUM(offset); - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - return ret_val; + DEBUGFUNC("__e1000_read_phy_reg_hv"); - /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */ - hw->phy.addr = 1; - ret_val = e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); - if (ret_val) { - hw->phy.ops.release(hw); - return ret_val; + if (!locked) { + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; } - ret_val = e1000_write_phy_reg_mdic(hw, BM_CS_CTRL1, - (0x2180 | (slow << 10))); - /* dummy read when reverting to fast mode - throw away result */ - if (!slow) - e1000_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); + /* Page 800 works differently than the rest so it has its own func */ + if (page == BM_WUC_PAGE) { + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, + data, TRUE); + goto out; + } - hw->phy.ops.release(hw); + if (page > 0 && page < HV_INTC_FC_PAGE_START) { + ret_val = e1000_access_phy_debug_regs_hv(hw, offset, + data, TRUE); + goto out; + } + + hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); + + if (page == HV_INTC_FC_PAGE_START) + page = 0; + + if (reg > MAX_PHY_MULTI_PAGE_REG) { + u32 phy_addr = hw->phy.addr; + + hw->phy.addr = 1; + + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000_write_phy_reg_mdic(hw, + IGP01E1000_PHY_PAGE_SELECT, + (page << IGP_PAGE_SHIFT)); + hw->phy.addr = phy_addr; + + if (ret_val) + goto out; + } + + ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, + data); +out: + if (!locked) + hw->phy.ops.release(hw); return ret_val; } @@ -2810,109 +3117,52 @@ s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) * @offset: register offset to be read * @data: pointer to the read data * - * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retrieved information in data. Release any acquired - * semaphore before exiting. + * Acquires semaphore then reads the PHY register at offset and stores + * the retrieved information in data. Release the acquired semaphore + * before exiting. **/ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) { - s32 ret_val; - u16 page = BM_PHY_REG_PAGE(offset); - u16 reg = BM_PHY_REG_NUM(offset); - bool in_slow_mode = FALSE; - - DEBUGFUNC("e1000_read_phy_reg_hv"); - - /* Workaround failure in MDIO access while cable is disconnected */ - if ((hw->phy.type == e1000_phy_82577) && - !(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) { - ret_val = e1000_set_mdio_slow_mode_hv(hw, TRUE); - if (ret_val) - goto out; - - in_slow_mode = TRUE; - } - - /* Page 800 works differently than the rest so it has its own func */ - if (page == BM_WUC_PAGE) { - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, - data, TRUE); - goto out; - } - - if (page > 0 && page < HV_INTC_FC_PAGE_START) { - ret_val = e1000_access_phy_debug_regs_hv(hw, offset, - data, TRUE); - goto out; - } - - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; - - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); - - if (page == HV_INTC_FC_PAGE_START) - page = 0; - - if (reg > MAX_PHY_MULTI_PAGE_REG) { - if ((hw->phy.type != e1000_phy_82578) || - ((reg != I82578_ADDR_REG) && - (reg != I82578_ADDR_REG + 1))) { - u32 phy_addr = hw->phy.addr; - - hw->phy.addr = 1; - - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - if (ret_val) { - hw->phy.ops.release(hw); - goto out; - } - hw->phy.addr = phy_addr; - } - } - - ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, - data); - hw->phy.ops.release(hw); - -out: - /* Revert to MDIO fast mode, if applicable */ - if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val = e1000_set_mdio_slow_mode_hv(hw, FALSE); - - return ret_val; + return __e1000_read_phy_reg_hv(hw, offset, data, FALSE); } /** - * e1000_write_phy_reg_hv - Write HV PHY register + * e1000_read_phy_reg_hv_locked - Read HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Reads the PHY register at offset and stores the retrieved information + * in data. Assumes semaphore already acquired. + **/ +s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_phy_reg_hv(hw, offset, data, TRUE); +} + +/** + * __e1000_write_phy_reg_hv - Write HV PHY register * @hw: pointer to the HW structure * @offset: register offset to write to * @data: data to write at register offset + * @locked: semaphore has already been acquired or not * * Acquires semaphore, if necessary, then writes the data to PHY register * at the offset. Release any acquired semaphores before exiting. **/ -s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) +static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, + bool locked) { s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); - bool in_slow_mode = FALSE; - DEBUGFUNC("e1000_write_phy_reg_hv"); + DEBUGFUNC("__e1000_write_phy_reg_hv"); - /* Workaround failure in MDIO access while cable is disconnected */ - if ((hw->phy.type == e1000_phy_82577) && - !(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) { - ret_val = e1000_set_mdio_slow_mode_hv(hw, TRUE); + if (!locked) { + ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; - - in_slow_mode = TRUE; + return ret_val; } /* Page 800 works differently than the rest so it has its own func */ @@ -2928,10 +3178,6 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) goto out; } - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); if (page == HV_INTC_FC_PAGE_START) @@ -2947,49 +3193,65 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) ((MAX_PHY_REG_ADDRESS & reg) == 0) && (data & (1 << 11))) { u16 data2 = 0x7EFF; - hw->phy.ops.release(hw); ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3, &data2, FALSE); if (ret_val) goto out; - - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - goto out; } if (reg > MAX_PHY_MULTI_PAGE_REG) { - if ((hw->phy.type != e1000_phy_82578) || - ((reg != I82578_ADDR_REG) && - (reg != I82578_ADDR_REG + 1))) { - u32 phy_addr = hw->phy.addr; + u32 phy_addr = hw->phy.addr; - hw->phy.addr = 1; + hw->phy.addr = 1; - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - if (ret_val) { - hw->phy.ops.release(hw); - goto out; - } - hw->phy.addr = phy_addr; - } + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000_write_phy_reg_mdic(hw, + IGP01E1000_PHY_PAGE_SELECT, + (page << IGP_PAGE_SHIFT)); + hw->phy.addr = phy_addr; + + if (ret_val) + goto out; } ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, data); - hw->phy.ops.release(hw); out: - /* Revert to MDIO fast mode, if applicable */ - if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val = e1000_set_mdio_slow_mode_hv(hw, FALSE); + if (!locked) + hw->phy.ops.release(hw); return ret_val; } +/** + * e1000_write_phy_reg_hv - Write HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Acquires semaphore then writes the data to PHY register at the offset. + * Release the acquired semaphores before exiting. + **/ +s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_phy_reg_hv(hw, offset, data, FALSE); +} + +/** + * e1000_write_phy_reg_hv_locked - Write HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Writes the data to PHY register at the offset. Assumes semaphore + * already acquired. + **/ +s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_phy_reg_hv(hw, offset, data, TRUE); +} + /** * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page * @page: page to be accessed @@ -3011,10 +3273,9 @@ static u32 e1000_get_phy_addr_for_hv_page(u32 page) * @data: pointer to the data to be read or written * @read: determines if operation is read or written * - * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retreived information in data. Release any acquired - * semaphores before exiting. Note that the procedure to read these regs - * uses the address port and data port to read/write. + * Reads the PHY register at offset and stores the retreived information + * in data. Assumes semaphore already acquired. Note that the procedure + * to read these regs uses the address port and data port to read/write. **/ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, u16 *data, bool read) @@ -3022,7 +3283,6 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, s32 ret_val; u32 addr_reg = 0; u32 data_reg = 0; - u8 phy_acquired = 1; DEBUGFUNC("e1000_access_phy_debug_regs_hv"); @@ -3031,13 +3291,6 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, I82578_ADDR_REG : I82577_ADDR_REG; data_reg = addr_reg + 1; - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) { - DEBUGOUT("Could not acquire PHY\n"); - phy_acquired = 0; - goto out; - } - /* All operations in this function are phy address 2 */ hw->phy.addr = 2; @@ -3060,8 +3313,6 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, } out: - if (phy_acquired == 1) - hw->phy.ops.release(hw); return ret_val; } @@ -3090,7 +3341,7 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw) hw->phy.ops.read_reg(hw, PHY_CONTROL, &data); if (data & PHY_CONTROL_LB) goto out; - + /* check if link is up and at 1Gbps */ ret_val = hw->phy.ops.read_reg(hw, BM_CS_STATUS, &data); if (ret_val) @@ -3151,9 +3402,7 @@ s32 e1000_check_polarity_82577(struct e1000_hw *hw) * e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY * @hw: pointer to the HW structure * - * Calls the PHY setup function to force speed and duplex. Clears the - * auto-crossover to force MDI manually. Waits for link and returns - * successful if link up is successful, else -E1000_ERR_PHY (-2). + * Calls the PHY setup function to force speed and duplex. **/ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw) { @@ -3174,23 +3423,6 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw) if (ret_val) goto out; - /* - * Clear Auto-Crossover to force MDI manually. 82577 requires MDI - * forced whenever speed and duplex are forced. - */ - ret_val = phy->ops.read_reg(hw, I82577_PHY_CTRL_2, &phy_data); - if (ret_val) - goto out; - - phy_data &= ~I82577_PHY_CTRL2_AUTO_MDIX; - phy_data &= ~I82577_PHY_CTRL2_FORCE_MDI_MDIX; - - ret_val = phy->ops.write_reg(hw, I82577_PHY_CTRL_2, phy_data); - if (ret_val) - goto out; - - DEBUGOUT1("I82577_PHY_CTRL_2: %X\n", phy_data); - usec_delay(1); if (phy->autoneg_wait_to_complete) { @@ -3309,7 +3541,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw) I82577_DSTATUS_CABLE_LENGTH_SHIFT; if (length == E1000_CABLE_LENGTH_UNDEFINED) - ret_val = E1000_ERR_PHY; + ret_val = -E1000_ERR_PHY; phy->cable_length = length; diff --git a/sys/dev/e1000/e1000_phy.h b/sys/dev/e1000/e1000_phy.h index 28ed0c15852..692cbaa91eb 100644 --- a/sys/dev/e1000/e1000_phy.h +++ b/sys/dev/e1000/e1000_phy.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -45,6 +45,7 @@ s32 e1000_check_polarity_m88(struct e1000_hw *hw); s32 e1000_check_polarity_igp(struct e1000_hw *hw); s32 e1000_check_polarity_ife(struct e1000_hw *hw); s32 e1000_check_reset_block_generic(struct e1000_hw *hw); +s32 e1000_phy_setup_autoneg(struct e1000_hw *hw); s32 e1000_copper_link_autoneg(struct e1000_hw *hw); s32 e1000_copper_link_setup_igp(struct e1000_hw *hw); s32 e1000_copper_link_setup_m88(struct e1000_hw *hw); @@ -57,19 +58,23 @@ s32 e1000_get_cfg_done_generic(struct e1000_hw *hw); s32 e1000_get_phy_id(struct e1000_hw *hw); s32 e1000_get_phy_info_igp(struct e1000_hw *hw); s32 e1000_get_phy_info_m88(struct e1000_hw *hw); +s32 e1000_get_phy_info_ife(struct e1000_hw *hw); s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw); void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw); s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw); -s32 e1000_phy_setup_autoneg(struct e1000_hw *hw); s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data); +s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); +s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active); s32 e1000_setup_copper_link_generic(struct e1000_hw *hw); s32 e1000_wait_autoneg_generic(struct e1000_hw *hw); s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data); +s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data); +s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_phy_reset_dsp(struct e1000_hw *hw); s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, @@ -85,9 +90,12 @@ void e1000_power_up_phy_copper(struct e1000_hw *hw); void e1000_power_down_phy_copper(struct e1000_hw *hw); s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); +s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data); +s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data); +s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); -s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow); +s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); s32 e1000_check_polarity_82577(struct e1000_hw *hw); @@ -140,7 +148,6 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw); #define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) #define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ #define I82577_CTRL_REG 23 -#define I82577_CTRL_DOWNSHIFT_MASK (7 << 10) /* 82577 specific PHY registers */ #define I82577_PHY_CTRL_2 18 @@ -175,6 +182,13 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw); #define BM_CS_STATUS_SPEED_MASK 0xC000 #define BM_CS_STATUS_SPEED_1000 0x8000 +/* 82577 Mobile Phy Status Register */ +#define HV_M_STATUS 26 +#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 +#define HV_M_STATUS_SPEED_MASK 0x0300 +#define HV_M_STATUS_SPEED_1000 0x0200 +#define HV_M_STATUS_LINK_UP 0x0040 + #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 #define IGP01E1000_PHY_POLARITY_MASK 0x0078 @@ -220,6 +234,8 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw); #define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */ #define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */ #define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ +#define E1000_KMRNCTRLSTA_K1_CONFIG 0x7 +#define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 #define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 #define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */ diff --git a/sys/dev/e1000/e1000_regs.h b/sys/dev/e1000/e1000_regs.h index 3a62d0a61a3..b2a477e8234 100644 --- a/sys/dev/e1000/e1000_regs.h +++ b/sys/dev/e1000/e1000_regs.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -43,6 +43,12 @@ #define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ #define E1000_FLA 0x0001C /* Flash Access - RW */ #define E1000_MDIC 0x00020 /* MDI Control - RW */ +#define E1000_MDICNFG 0x00E04 /* MDI Config - RW */ +#define E1000_REGISTER_SET_SIZE 0x20000 /* CSR Size */ +#define E1000_EEPROM_INIT_CTRL_WORD_2 0x0F /* EEPROM Init Ctrl Word 2 */ +#define E1000_BARCTRL 0x5BBC /* BAR ctrl reg */ +#define E1000_BARCTRL_FLSIZE 0x0700 /* BAR ctrl Flsize */ +#define E1000_BARCTRL_CSRSIZE 0x2000 /* BAR ctrl CSR size */ #define E1000_SCTL 0x00024 /* SerDes Control - RW */ #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ #define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ @@ -59,7 +65,7 @@ #define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */ #define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */ #define E1000_SVCR 0x000F0 -#define E1000_SVT 0x000F4 +#define E1000_SVT 0x000F4 #define E1000_RCTL 0x00100 /* Rx Control - RW */ #define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ #define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */ @@ -121,11 +127,7 @@ #define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */ #define E1000_PBDIAG 0x02458 /* Packet Buffer Diagnostic - RW */ #define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */ -#define E1000_RXCTL(_n) (0x0C014 + (0x40 * (_n))) -#define E1000_RQDPC(_n) (0x0C030 + (0x40 * (_n))) -#define E1000_TXCTL(_n) (0x0E014 + (0x40 * (_n))) -#define E1000_RXCTL(_n) (0x0C014 + (0x40 * (_n))) -#define E1000_RQDPC(_n) (0x0C030 + (0x40 * (_n))) +#define E1000_IRPBS 0x02404 /* Same as RXPBS, renamed for newer adapters - RW */ #define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */ #define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */ /* @@ -146,10 +148,15 @@ (0x0C00C + ((_n) * 0x40))) #define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \ (0x0C010 + ((_n) * 0x40))) +#define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \ + (0x0C014 + ((_n) * 0x40))) +#define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n) #define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \ (0x0C018 + ((_n) * 0x40))) #define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \ (0x0C028 + ((_n) * 0x40))) +#define E1000_RQDPC(_n) ((_n) < 4 ? (0x02830 + ((_n) * 0x100)) : \ + (0x0C030 + ((_n) * 0x40))) #define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \ (0x0E000 + ((_n) * 0x40))) #define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \ @@ -158,17 +165,18 @@ (0x0E008 + ((_n) * 0x40))) #define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \ (0x0E010 + ((_n) * 0x40))) +#define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \ + (0x0E014 + ((_n) * 0x40))) +#define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n) #define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \ (0x0E018 + ((_n) * 0x40))) #define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \ (0x0E028 + ((_n) * 0x40))) -#define E1000_TARC(_n) (0x03840 + (_n << 8)) -#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8)) -#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8)) #define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) : \ (0x0E038 + ((_n) * 0x40))) #define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) : \ (0x0E03C + ((_n) * 0x40))) +#define E1000_TARC(_n) (0x03840 + ((_n) * 0x100)) #define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */ #define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */ #define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */ @@ -187,6 +195,7 @@ #define E1000_PBSLAC 0x03100 /* Packet Buffer Slave Access Control */ #define E1000_PBSLAD(_n) (0x03110 + (0x4 * (_n))) /* Packet Buffer DWORD (_n) */ #define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */ +#define E1000_ITPBS 0x03404 /* Same as TXPBS, renamed for newer adpaters - RW */ #define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */ #define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */ #define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */ @@ -271,6 +280,18 @@ #define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */ #define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */ #define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */ +#define E1000_CRC_OFFSET 0x05F50 /* CRC Offset register */ + +/* Virtualization statistical counters */ +#define E1000_PFVFGPRC(_n) (0x010010 + (0x100 * (_n))) +#define E1000_PFVFGPTC(_n) (0x010014 + (0x100 * (_n))) +#define E1000_PFVFGORC(_n) (0x010018 + (0x100 * (_n))) +#define E1000_PFVFGOTC(_n) (0x010034 + (0x100 * (_n))) +#define E1000_PFVFMPRC(_n) (0x010038 + (0x100 * (_n))) +#define E1000_PFVFGPRLBC(_n) (0x010040 + (0x100 * (_n))) +#define E1000_PFVFGPTLBC(_n) (0x010044 + (0x100 * (_n))) +#define E1000_PFVFGORLBC(_n) (0x010048 + (0x100 * (_n))) +#define E1000_PFVFGOTLBC(_n) (0x010050 + (0x100 * (_n))) #define E1000_LSECTXUT 0x04300 /* LinkSec Tx Untagged Packet Count - OutPktsUntagged */ #define E1000_LSECTXPKTE 0x04304 /* LinkSec Encrypted Tx Packets Count - OutPktsEncrypted */ @@ -376,6 +397,7 @@ #define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */ #define E1000_MDPHYA 0x0003C /* PHY address - RW */ #define E1000_MANC2H 0x05860 /* Management Control To Host - RW */ +#define E1000_MDEF(_n) (0x05890 + (4 * (_n))) /* Mngmt Decision Filters */ #define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */ #define E1000_CCMCTL 0x05B48 /* CCM Control Register */ #define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */ @@ -392,6 +414,7 @@ #define E1000_SWSM2 0x05B58 /* Driver-only SW semaphore (not used by BOOT agents) */ #define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */ #define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */ +#define E1000_UFUSE 0x05B78 /* UFUSE - RO */ #define E1000_FFLT_DBG 0x05F04 /* Debug Register */ #define E1000_HICR 0x08F00 /* Host Interface Control */ @@ -437,6 +460,7 @@ #define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n))) #define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine * Filter - RW */ +#define E1000_VMVIR(_n) (0x03700 + (4 * (_n))) /* Time Sync */ #define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */ #define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */ @@ -450,6 +474,8 @@ #define E1000_SYSTIML 0x0B600 /* System time register Low - RO */ #define E1000_SYSTIMH 0x0B604 /* System time register High - RO */ #define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */ +#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */ +#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */ #define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */ #define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */ @@ -493,4 +519,15 @@ #define E1000_RTTBCNACH 0x0B214 /* Tx BCN Control High */ #define E1000_RTTBCNACL 0x0B210 /* Tx BCN Control Low */ +/* DMA Coalescing registers */ +#define E1000_DMACR 0x02508 /* Control Register */ +#define E1000_DMCTXTH 0x03550 /* Transmit Threshold */ +#define E1000_DMCTLX 0x02514 /* Time to Lx Request */ +#define E1000_DMCRTRH 0x05DD0 /* Receive Packet Rate Threshold */ +#define E1000_DMCCNT 0x05DD4 /* Current RX Count */ +#define E1000_FCRTC 0x02170 /* Flow Control Rx high watermark */ +#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */ + +/* PCIe Parity Status Register */ +#define E1000_PCIEERRSTS 0x05BA8 #endif diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 96d0788c377..f8329f89663 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -54,9 +54,7 @@ #include #include #include -#if __FreeBSD_version >= 700029 #include -#endif #include #include @@ -79,6 +77,7 @@ #include #include +#include #include #include @@ -94,7 +93,7 @@ int em_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] = "6.9.14"; +char em_driver_version[] = "7.0.0"; /********************************************************************* @@ -110,51 +109,6 @@ char em_driver_version[] = "6.9.14"; static em_vendor_info_t em_vendor_info_array[] = { /* Intel(R) PRO/1000 Network Connection */ - { 0x8086, E1000_DEV_ID_82540EM, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82540EM_LOM, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82540EP, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82540EP_LOM, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82540EP_LP, PCI_ANY_ID, PCI_ANY_ID, 0}, - - { 0x8086, E1000_DEV_ID_82541EI, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82541ER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82541ER_LOM, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82541EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82541GI, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82541GI_LF, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82541GI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0}, - - { 0x8086, E1000_DEV_ID_82542, PCI_ANY_ID, PCI_ANY_ID, 0}, - - { 0x8086, E1000_DEV_ID_82543GC_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82543GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - - { 0x8086, E1000_DEV_ID_82544EI_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82544EI_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82544GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82544GC_LOM, PCI_ANY_ID, PCI_ANY_ID, 0}, - - { 0x8086, E1000_DEV_ID_82545EM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82545EM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82545GM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82545GM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82545GM_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, - - { 0x8086, E1000_DEV_ID_82546EB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82546EB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82546EB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82546GB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82546GB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82546GB_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82546GB_PCIE, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3, - PCI_ANY_ID, PCI_ANY_ID, 0}, - - { 0x8086, E1000_DEV_ID_82547EI, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82547EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82547GI, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82571EB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82571EB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82571EB_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, @@ -194,7 +148,7 @@ static em_vendor_info_t em_vendor_info_array[] = { 0x8086, E1000_DEV_ID_ICH8_IFE_GT, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_ICH8_IFE_G, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_ICH8_IGP_M, PCI_ANY_ID, PCI_ANY_ID, 0}, - + { 0x8086, E1000_DEV_ID_ICH8_82567V_3, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_ICH9_IGP_M_AMT, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_ICH9_IGP_AMT, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_ICH9_IGP_C, PCI_ANY_ID, PCI_ANY_ID, 0}, @@ -211,6 +165,10 @@ static em_vendor_info_t em_vendor_info_array[] = { 0x8086, E1000_DEV_ID_ICH10_R_BM_V, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_ICH10_D_BM_LM, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_ICH10_D_BM_LF, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_PCH_M_HV_LM, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_PCH_M_HV_LC, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_PCH_D_HV_DM, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_PCH_D_HV_DC, PCI_ANY_ID, PCI_ANY_ID, 0}, /* required last entry */ { 0, 0, 0, 0, 0} }; @@ -233,14 +191,14 @@ static int em_shutdown(device_t); static int em_suspend(device_t); static int em_resume(device_t); static void em_start(struct ifnet *); -static void em_start_locked(struct ifnet *ifp); +static void em_start_locked(struct ifnet *, struct tx_ring *); #if __FreeBSD_version >= 800000 static int em_mq_start(struct ifnet *, struct mbuf *); -static int em_mq_start_locked(struct ifnet *, struct mbuf *); +static int em_mq_start_locked(struct ifnet *, + struct tx_ring *, struct mbuf *); static void em_qflush(struct ifnet *); #endif static int em_ioctl(struct ifnet *, u_long, caddr_t); -static void em_watchdog(struct adapter *); static void em_init(void *); static void em_init_locked(struct adapter *); static void em_stop(void *); @@ -248,55 +206,49 @@ static void em_media_status(struct ifnet *, struct ifmediareq *); static int em_media_change(struct ifnet *); static void em_identify_hardware(struct adapter *); static int em_allocate_pci_resources(struct adapter *); -static int em_allocate_legacy(struct adapter *adapter); -static int em_allocate_msix(struct adapter *adapter); +static int em_allocate_legacy(struct adapter *); +static int em_allocate_msix(struct adapter *); +static int em_allocate_queues(struct adapter *); static int em_setup_msix(struct adapter *); static void em_free_pci_resources(struct adapter *); static void em_local_timer(void *); -static int em_hardware_init(struct adapter *); +static void em_reset(struct adapter *); static void em_setup_interface(device_t, struct adapter *); + static void em_setup_transmit_structures(struct adapter *); static void em_initialize_transmit_unit(struct adapter *); +static int em_allocate_transmit_buffers(struct tx_ring *); +static void em_free_transmit_structures(struct adapter *); +static void em_free_transmit_buffers(struct tx_ring *); + static int em_setup_receive_structures(struct adapter *); +static int em_allocate_receive_buffers(struct rx_ring *); static void em_initialize_receive_unit(struct adapter *); +static void em_free_receive_structures(struct adapter *); +static void em_free_receive_buffers(struct rx_ring *); + static void em_enable_intr(struct adapter *); static void em_disable_intr(struct adapter *); -static void em_free_transmit_structures(struct adapter *); -static void em_free_receive_structures(struct adapter *); static void em_update_stats_counters(struct adapter *); -static void em_txeof(struct adapter *); -static void em_tx_purge(struct adapter *); -static int em_allocate_receive_structures(struct adapter *); -static int em_allocate_transmit_structures(struct adapter *); -static int em_rxeof(struct adapter *, int); +static bool em_txeof(struct tx_ring *); +static int em_rxeof(struct rx_ring *, int); #ifndef __NO_STRICT_ALIGNMENT -static int em_fixup_rx(struct adapter *); +static int em_fixup_rx(struct rx_ring *); #endif -static void em_receive_checksum(struct adapter *, struct e1000_rx_desc *, - struct mbuf *); -static void em_transmit_checksum_setup(struct adapter *, struct mbuf *, +static void em_receive_checksum(struct e1000_rx_desc *, struct mbuf *); +static void em_transmit_checksum_setup(struct tx_ring *, struct mbuf *, u32 *, u32 *); -#if __FreeBSD_version >= 700000 -static bool em_tso_setup(struct adapter *, struct mbuf *, - u32 *, u32 *); -#endif /* FreeBSD_version >= 700000 */ +static bool em_tso_setup(struct tx_ring *, struct mbuf *, u32 *, u32 *); static void em_set_promisc(struct adapter *); static void em_disable_promisc(struct adapter *); static void em_set_multi(struct adapter *); static void em_print_hw_stats(struct adapter *); static void em_update_link_status(struct adapter *); -static int em_get_buf(struct adapter *, int); -#if __FreeBSD_version >= 700029 +static void em_refresh_mbufs(struct rx_ring *, int); static void em_register_vlan(void *, struct ifnet *, u16); static void em_unregister_vlan(void *, struct ifnet *, u16); static void em_setup_vlan_hw_support(struct adapter *); -#endif -static int em_xmit(struct adapter *, struct mbuf **); -static void em_smartspeed(struct adapter *); -static int em_82547_fifo_workaround(struct adapter *, int); -static void em_82547_update_fifo_head(struct adapter *, int); -static int em_82547_tx_fifo_reset(struct adapter *); -static void em_82547_move_tail(void *); +static int em_xmit(struct tx_ring *, struct mbuf **); static int em_dma_malloc(struct adapter *, bus_size_t, struct em_dma_alloc *, int); static void em_dma_free(struct adapter *, struct em_dma_alloc *); @@ -305,8 +257,6 @@ static void em_print_nvm_info(struct adapter *); static int em_is_valid_ether_addr(u8 *); static int em_sysctl_stats(SYSCTL_HANDLER_ARGS); static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS); -static u32 em_fill_descriptors (bus_addr_t address, u32 length, - PDESC_ARRAY desc_array); static int em_sysctl_int_delay(SYSCTL_HANDLER_ARGS); static void em_add_int_delay_sysctl(struct adapter *, const char *, const char *, struct em_int_delay_info *, int, int); @@ -315,29 +265,23 @@ static void em_init_manageability(struct adapter *); static void em_release_manageability(struct adapter *); static void em_get_hw_control(struct adapter *); static void em_release_hw_control(struct adapter *); +static void em_get_wakeup(device_t); static void em_enable_wakeup(device_t); +static int em_enable_phy_wakeup(struct adapter *); +static void em_led_func(void *, int); -#ifdef EM_LEGACY_IRQ -static void em_intr(void *); -#else /* FAST IRQ */ -#if __FreeBSD_version < 700000 -static void em_irq_fast(void *); -#else static int em_irq_fast(void *); -#endif /* MSIX handlers */ static void em_msix_tx(void *); static void em_msix_rx(void *); static void em_msix_link(void *); -static void em_handle_rx(void *context, int pending); static void em_handle_tx(void *context, int pending); - -static void em_handle_rxtx(void *context, int pending); +static void em_handle_rx(void *context, int pending); static void em_handle_link(void *context, int pending); + static void em_add_rx_process_limit(struct adapter *, const char *, const char *, int *, int); -#endif /* ~EM_LEGACY_IRQ */ #ifdef DEVICE_POLLING static poll_handler_t em_poll; @@ -362,7 +306,7 @@ static driver_t em_driver = { "em", em_methods, sizeof(struct adapter), }; -static devclass_t em_devclass; +devclass_t em_devclass; DRIVER_MODULE(em, pci, em_driver, em_devclass, 0, 0); MODULE_DEPEND(em, pci, 1, 1, 1); MODULE_DEPEND(em, ether, 1, 1, 1); @@ -382,31 +326,35 @@ MODULE_DEPEND(em, ether, 1, 1, 1); static int em_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV); static int em_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR); -static int em_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV); -static int em_rx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_RADV); -static int em_rxd = EM_DEFAULT_RXD; -static int em_txd = EM_DEFAULT_TXD; -static int em_smart_pwr_down = FALSE; -/* Controls whether promiscuous also shows bad packets */ -static int em_debug_sbp = FALSE; -/* Local switch for MSI/MSIX */ -static int em_enable_msi = TRUE; - TUNABLE_INT("hw.em.tx_int_delay", &em_tx_int_delay_dflt); TUNABLE_INT("hw.em.rx_int_delay", &em_rx_int_delay_dflt); + +static int em_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV); +static int em_rx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_RADV); TUNABLE_INT("hw.em.tx_abs_int_delay", &em_tx_abs_int_delay_dflt); TUNABLE_INT("hw.em.rx_abs_int_delay", &em_rx_abs_int_delay_dflt); + +static int em_rxd = EM_DEFAULT_RXD; +static int em_txd = EM_DEFAULT_TXD; TUNABLE_INT("hw.em.rxd", &em_rxd); TUNABLE_INT("hw.em.txd", &em_txd); -TUNABLE_INT("hw.em.smart_pwr_down", &em_smart_pwr_down); -TUNABLE_INT("hw.em.sbp", &em_debug_sbp); -TUNABLE_INT("hw.em.enable_msi", &em_enable_msi); -#ifndef EM_LEGACY_IRQ +static int em_smart_pwr_down = FALSE; +TUNABLE_INT("hw.em.smart_pwr_down", &em_smart_pwr_down); + +/* Controls whether promiscuous also shows bad packets */ +static int em_debug_sbp = FALSE; +TUNABLE_INT("hw.em.sbp", &em_debug_sbp); + +/* Local controls for MSI/MSIX */ +static int em_enable_msix = TRUE; +static int em_msix_queues = 2; /* for 82574, can be 1 or 2 */ +TUNABLE_INT("hw.em.enable_msix", &em_enable_msix); +TUNABLE_INT("hw.em.msix_queues", &em_msix_queues); + /* How many packets rxeof tries to clean at a time */ static int em_rx_process_limit = 100; TUNABLE_INT("hw.em.rx_process_limit", &em_rx_process_limit); -#endif /* Flow control setting - default to FULL */ static int em_fc_setting = e1000_fc_full; @@ -488,17 +436,13 @@ static int em_attach(device_t dev) { struct adapter *adapter; - int tsize, rsize; int error = 0; - u16 eeprom_data, device_id; INIT_DEBUGOUT("em_attach: begin"); adapter = device_get_softc(dev); adapter->dev = adapter->osdep.dev = dev; EM_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); - EM_TX_LOCK_INIT(adapter, device_get_nameunit(dev)); - EM_RX_LOCK_INIT(adapter, device_get_nameunit(dev)); /* SYSCTL stuff */ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), @@ -512,7 +456,6 @@ em_attach(device_t dev) em_sysctl_stats, "I", "Statistics"); callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); - callout_init_mtx(&adapter->tx_fifo_timer, &adapter->tx_mtx, 0); /* Determine hardware and mac info */ em_identify_hardware(adapter); @@ -531,6 +474,7 @@ em_attach(device_t dev) ** identified */ if ((adapter->hw.mac.type == e1000_ich8lan) || + (adapter->hw.mac.type == e1000_pchlan) || (adapter->hw.mac.type == e1000_ich9lan) || (adapter->hw.mac.type == e1000_ich10lan)) { int rid = EM_BAR_TYPE_FLASH; @@ -565,25 +509,21 @@ em_attach(device_t dev) em_add_int_delay_sysctl(adapter, "tx_int_delay", "transmit interrupt delay in usecs", &adapter->tx_int_delay, E1000_REGISTER(&adapter->hw, E1000_TIDV), em_tx_int_delay_dflt); - if (adapter->hw.mac.type >= e1000_82540) { - em_add_int_delay_sysctl(adapter, "rx_abs_int_delay", - "receive interrupt delay limit in usecs", - &adapter->rx_abs_int_delay, - E1000_REGISTER(&adapter->hw, E1000_RADV), - em_rx_abs_int_delay_dflt); - em_add_int_delay_sysctl(adapter, "tx_abs_int_delay", - "transmit interrupt delay limit in usecs", - &adapter->tx_abs_int_delay, - E1000_REGISTER(&adapter->hw, E1000_TADV), - em_tx_abs_int_delay_dflt); - } + em_add_int_delay_sysctl(adapter, "rx_abs_int_delay", + "receive interrupt delay limit in usecs", + &adapter->rx_abs_int_delay, + E1000_REGISTER(&adapter->hw, E1000_RADV), + em_rx_abs_int_delay_dflt); + em_add_int_delay_sysctl(adapter, "tx_abs_int_delay", + "transmit interrupt delay limit in usecs", + &adapter->tx_abs_int_delay, + E1000_REGISTER(&adapter->hw, E1000_TADV), + em_tx_abs_int_delay_dflt); -#ifndef EM_LEGACY_IRQ /* Sysctls for limiting the amount of work done in the taskqueue */ em_add_rx_process_limit(adapter, "rx_processing_limit", "max number of rx packets to process", &adapter->rx_process_limit, em_rx_process_limit); -#endif /* * Validate number of transmit and receive descriptors. It @@ -591,18 +531,15 @@ em_attach(device_t dev) * of E1000_DBA_ALIGN. */ if (((em_txd * sizeof(struct e1000_tx_desc)) % EM_DBA_ALIGN) != 0 || - (adapter->hw.mac.type >= e1000_82544 && em_txd > EM_MAX_TXD) || - (adapter->hw.mac.type < e1000_82544 && em_txd > EM_MAX_TXD_82543) || - (em_txd < EM_MIN_TXD)) { + (em_txd > EM_MAX_TXD) || (em_txd < EM_MIN_TXD)) { device_printf(dev, "Using %d TX descriptors instead of %d!\n", EM_DEFAULT_TXD, em_txd); adapter->num_tx_desc = EM_DEFAULT_TXD; } else adapter->num_tx_desc = em_txd; + if (((em_rxd * sizeof(struct e1000_rx_desc)) % EM_DBA_ALIGN) != 0 || - (adapter->hw.mac.type >= e1000_82544 && em_rxd > EM_MAX_RXD) || - (adapter->hw.mac.type < e1000_82544 && em_rxd > EM_MAX_RXD_82543) || - (em_rxd < EM_MIN_RXD)) { + (em_rxd > EM_MAX_RXD) || (em_rxd < EM_MIN_RXD)) { device_printf(dev, "Using %d RX descriptors instead of %d!\n", EM_DEFAULT_RXD, em_rxd); adapter->num_rx_desc = EM_DEFAULT_RXD; @@ -612,10 +549,6 @@ em_attach(device_t dev) adapter->hw.mac.autoneg = DO_AUTO_NEG; adapter->hw.phy.autoneg_wait_to_complete = FALSE; adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT; - adapter->rx_buffer_len = 2048; - - e1000_init_script_state_82541(&adapter->hw, TRUE); - e1000_set_tbi_compatibility_82543(&adapter->hw, TRUE); /* Copper options */ if (adapter->hw.phy.media_type == e1000_media_type_copper) { @@ -637,29 +570,13 @@ em_attach(device_t dev) */ adapter->hw.mac.report_tx_early = 1; - tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc), - EM_DBA_ALIGN); - - /* Allocate Transmit Descriptor ring */ - if (em_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) { - device_printf(dev, "Unable to allocate tx_desc memory\n"); + /* + ** Get queue/ring memory + */ + if (em_allocate_queues(adapter)) { error = ENOMEM; - goto err_tx_desc; + goto err_pci; } - adapter->tx_desc_base = - (struct e1000_tx_desc *)adapter->txdma.dma_vaddr; - - rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc), - EM_DBA_ALIGN); - - /* Allocate Receive Descriptor ring */ - if (em_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) { - device_printf(dev, "Unable to allocate rx_desc memory\n"); - error = ENOMEM; - goto err_rx_desc; - } - adapter->rx_desc_base = - (struct e1000_rx_desc *)adapter->rxdma.dma_vaddr; /* ** Start from a known state, this is @@ -679,7 +596,7 @@ em_attach(device_t dev) device_printf(dev, "The EEPROM Checksum Is Not Valid\n"); error = EIO; - goto err_hw_init; + goto err_late; } } @@ -688,49 +605,35 @@ em_attach(device_t dev) device_printf(dev, "EEPROM read error while reading MAC" " address\n"); error = EIO; - goto err_hw_init; + goto err_late; } if (!em_is_valid_ether_addr(adapter->hw.mac.addr)) { device_printf(dev, "Invalid MAC address\n"); error = EIO; - goto err_hw_init; - } - - /* Initialize the hardware */ - if (em_hardware_init(adapter)) { - device_printf(dev, "Unable to initialize the hardware\n"); - error = EIO; - goto err_hw_init; - } - - /* Allocate transmit descriptors and buffers */ - if (em_allocate_transmit_structures(adapter)) { - device_printf(dev, "Could not setup transmit structures\n"); - error = ENOMEM; - goto err_tx_struct; - } - - /* Allocate receive descriptors and buffers */ - if (em_allocate_receive_structures(adapter)) { - device_printf(dev, "Could not setup receive structures\n"); - error = ENOMEM; - goto err_rx_struct; + goto err_late; } /* ** Do interrupt configuration */ - if (adapter->msi > 1) /* Do MSI/X */ + if (adapter->msix > 1) /* Do MSIX */ error = em_allocate_msix(adapter); else /* MSI or Legacy */ error = em_allocate_legacy(adapter); if (error) - goto err_rx_struct; + goto err_late; + + /* + * Get Wake-on-Lan and Management info for later use + */ + em_get_wakeup(dev); /* Setup OS specific network interface */ em_setup_interface(dev, adapter); + em_reset(adapter); + /* Initialize statistics */ em_update_stats_counters(adapter); @@ -742,104 +645,32 @@ em_attach(device_t dev) device_printf(dev, "PHY reset is blocked due to SOL/IDER session.\n"); - /* Determine if we have to control management hardware */ - adapter->has_manage = e1000_enable_mng_pass_thru(&adapter->hw); - - /* - * Setup Wake-on-Lan - */ - switch (adapter->hw.mac.type) { - - case e1000_82542: - case e1000_82543: - break; - case e1000_82546: - case e1000_82546_rev_3: - case e1000_82571: - case e1000_80003es2lan: - if (adapter->hw.bus.func == 1) - e1000_read_nvm(&adapter->hw, - NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); - else - e1000_read_nvm(&adapter->hw, - NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); - eeprom_data &= EM_EEPROM_APME; - break; - default: - /* APME bit in EEPROM is mapped to WUC.APME */ - eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC) & - E1000_WUC_APME; - break; - } - if (eeprom_data) - adapter->wol = E1000_WUFC_MAG; - /* - * We have the eeprom settings, now apply the special cases - * where the eeprom may be wrong or the board won't support - * wake on lan on a particular port - */ - device_id = pci_get_device(dev); - switch (device_id) { - case E1000_DEV_ID_82546GB_PCIE: - adapter->wol = 0; - break; - case E1000_DEV_ID_82546EB_FIBER: - case E1000_DEV_ID_82546GB_FIBER: - case E1000_DEV_ID_82571EB_FIBER: - /* Wake events only supported on port A for dual fiber - * regardless of eeprom setting */ - if (E1000_READ_REG(&adapter->hw, E1000_STATUS) & - E1000_STATUS_FUNC_1) - adapter->wol = 0; - break; - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - case E1000_DEV_ID_82571EB_QUAD_COPPER: - case E1000_DEV_ID_82571EB_QUAD_FIBER: - case E1000_DEV_ID_82571EB_QUAD_COPPER_LP: - /* if quad port adapter, disable WoL on all but port A */ - if (global_quad_port_a != 0) - adapter->wol = 0; - /* Reset for multiple quad port adapters */ - if (++global_quad_port_a == 4) - global_quad_port_a = 0; - break; - } - - /* Do we need workaround for 82544 PCI-X adapter? */ - if (adapter->hw.bus.type == e1000_bus_type_pcix && - adapter->hw.mac.type == e1000_82544) - adapter->pcix_82544 = TRUE; - else - adapter->pcix_82544 = FALSE; - -#if __FreeBSD_version >= 700029 /* Register for VLAN events */ adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, em_register_vlan, adapter, EVENTHANDLER_PRI_FIRST); adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, em_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); -#endif + + /* Non-AMT based hardware can now take control from firmware */ + if (adapter->has_manage && !adapter->has_amt) + em_get_hw_control(adapter); /* Tell the stack that the interface is not active */ adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + adapter->led_dev = led_create(em_led_func, adapter, + device_get_nameunit(dev)); + INIT_DEBUGOUT("em_attach: end"); return (0); -err_rx_struct: +err_late: em_free_transmit_structures(adapter); -err_tx_struct: -err_hw_init: + em_free_receive_structures(adapter); em_release_hw_control(adapter); - em_dma_free(adapter, &adapter->rxdma); -err_rx_desc: - em_dma_free(adapter, &adapter->txdma); -err_tx_desc: err_pci: em_free_pci_resources(adapter); - EM_TX_LOCK_DESTROY(adapter); - EM_RX_LOCK_DESTROY(adapter); EM_CORE_LOCK_DESTROY(adapter); return (error); @@ -864,11 +695,7 @@ em_detach(device_t dev) INIT_DEBUGOUT("em_detach: begin"); /* Make sure VLANS are not using driver */ -#if __FreeBSD_version >= 700000 if (adapter->ifp->if_vlantrunk != NULL) { -#else - if (adapter->ifp->if_nvlans != 0) { -#endif device_printf(dev,"Vlan in use, detach first\n"); return (EBUSY); } @@ -879,41 +706,24 @@ em_detach(device_t dev) #endif EM_CORE_LOCK(adapter); - EM_TX_LOCK(adapter); adapter->in_detach = 1; em_stop(adapter); + EM_CORE_UNLOCK(adapter); + EM_CORE_LOCK_DESTROY(adapter); + e1000_phy_hw_reset(&adapter->hw); em_release_manageability(adapter); + em_release_hw_control(adapter); - if (((adapter->hw.mac.type == e1000_82573) || - (adapter->hw.mac.type == e1000_82583) || - (adapter->hw.mac.type == e1000_ich8lan) || - (adapter->hw.mac.type == e1000_ich10lan) || - (adapter->hw.mac.type == e1000_ich9lan)) && - e1000_check_mng_mode(&adapter->hw)) - em_release_hw_control(adapter); - - if (adapter->wol) { - E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN); - E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol); - em_enable_wakeup(dev); - } - - EM_TX_UNLOCK(adapter); - EM_CORE_UNLOCK(adapter); - -#if __FreeBSD_version >= 700029 /* Unregister VLAN events */ if (adapter->vlan_attach != NULL) EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach); if (adapter->vlan_detach != NULL) EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach); -#endif ether_ifdetach(adapter->ifp); callout_drain(&adapter->timer); - callout_drain(&adapter->tx_fifo_timer); em_free_pci_resources(adapter); bus_generic_detach(dev); @@ -922,21 +732,7 @@ em_detach(device_t dev) em_free_transmit_structures(adapter); em_free_receive_structures(adapter); - /* Free Transmit Descriptor ring */ - if (adapter->tx_desc_base) { - em_dma_free(adapter, &adapter->txdma); - adapter->tx_desc_base = NULL; - } - - /* Free Receive Descriptor ring */ - if (adapter->rx_desc_base) { - em_dma_free(adapter, &adapter->rxdma); - adapter->rx_desc_base = NULL; - } - - EM_TX_LOCK_DESTROY(adapter); - EM_RX_LOCK_DESTROY(adapter); - EM_CORE_LOCK_DESTROY(adapter); + em_release_hw_control(adapter); return (0); } @@ -963,25 +759,9 @@ em_suspend(device_t dev) EM_CORE_LOCK(adapter); - EM_TX_LOCK(adapter); - em_stop(adapter); - EM_TX_UNLOCK(adapter); - em_release_manageability(adapter); - - if (((adapter->hw.mac.type == e1000_82573) || - (adapter->hw.mac.type == e1000_82583) || - (adapter->hw.mac.type == e1000_ich8lan) || - (adapter->hw.mac.type == e1000_ich10lan) || - (adapter->hw.mac.type == e1000_ich9lan)) && - e1000_check_mng_mode(&adapter->hw)) - em_release_hw_control(adapter); - - if (adapter->wol) { - E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN); - E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol); - em_enable_wakeup(dev); - } + em_release_hw_control(adapter); + em_enable_wakeup(dev); EM_CORE_UNLOCK(adapter); @@ -994,6 +774,9 @@ em_resume(device_t dev) struct adapter *adapter = device_get_softc(dev); struct ifnet *ifp = adapter->ifp; + if (adapter->led_dev != NULL) + led_destroy(adapter->led_dev); + EM_CORE_LOCK(adapter); em_init_locked(adapter); em_init_manageability(adapter); @@ -1016,69 +799,45 @@ em_resume(device_t dev) #if __FreeBSD_version >= 800000 static int -em_mq_start_locked(struct ifnet *ifp, struct mbuf *m) +em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) { - struct adapter *adapter = ifp->if_softc; - struct mbuf *next; - int error = E1000_SUCCESS; + struct adapter *adapter = txr->adapter; + struct mbuf *next; + int err = 0, enq = 0; - EM_TX_LOCK_ASSERT(adapter); - /* To allow being called from a tasklet */ + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING || adapter->link_active == 0) { + if (m != NULL) + err = drbr_enqueue(ifp, txr->br, m); + return (err); + } + + enq = 0; if (m == NULL) - goto process; + next = drbr_dequeue(ifp, txr->br); + else + next = m; - if (((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING) - || (!adapter->link_active)) { - error = drbr_enqueue(ifp, adapter->br, m); - return (error); - } else if (!drbr_needs_enqueue(ifp, adapter->br) && - (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) { - if ((error = em_xmit(adapter, &m)) != 0) { - if (m != NULL) - error = drbr_enqueue(ifp, adapter->br, m); - return (error); - } else { - /* - * We've bypassed the buf ring so we need to update - * ifp directly - */ - drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags); - /* - ** Send a copy of the frame to the BPF - ** listener and set the watchdog on. - */ - ETHER_BPF_MTAP(ifp, m); - adapter->watchdog_timer = EM_TX_TIMEOUT; - } - } else if ((error = drbr_enqueue(ifp, adapter->br, m)) != 0) - return (error); - -process: - if (drbr_empty(ifp, adapter->br)) - return(error); - /* Process the queue */ - while (TRUE) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - break; - next = drbr_dequeue(ifp, adapter->br); - if (next == NULL) - break; - if ((error = em_xmit(adapter, &next)) != 0) { - if (next != NULL) - error = drbr_enqueue(ifp, adapter->br, next); + /* Process the queue */ + while (next != NULL) { + if ((err = em_xmit(txr, &next)) != 0) { + if (next != NULL) + err = drbr_enqueue(ifp, txr->br, next); break; } + enq++; drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags); - ETHER_BPF_MTAP(ifp, next); + ETHER_BPF_MTAP(ifp, next); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; + next = drbr_dequeue(ifp, txr->br); + } + + if (enq > 0) { /* Set the watchdog */ - adapter->watchdog_timer = EM_TX_TIMEOUT; - } - - if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - return (error); + txr->watchdog_check = TRUE; + } + return (err); } /* @@ -1088,45 +847,61 @@ process: static int em_mq_start(struct ifnet *ifp, struct mbuf *m) { - - struct adapter *adapter = ifp->if_softc; - int error = 0; + struct adapter *adapter = ifp->if_softc; + struct tx_ring *txr; + int i, error = 0; - if (EM_TX_TRYLOCK(adapter)) { + /* Which queue to use */ + if ((m->m_flags & M_FLOWID) != 0) + i = m->m_pkthdr.flowid % adapter->num_queues; + else + i = curcpu % adapter->num_queues; + + txr = &adapter->tx_rings[i]; + + if (EM_TX_TRYLOCK(txr)) { if (ifp->if_drv_flags & IFF_DRV_RUNNING) - error = em_mq_start_locked(ifp, m); - EM_TX_UNLOCK(adapter); + error = em_mq_start_locked(ifp, txr, m); + EM_TX_UNLOCK(txr); } else - error = drbr_enqueue(ifp, adapter->br, m); + error = drbr_enqueue(ifp, txr->br, m); return (error); } +/* +** Flush all ring buffers +*/ static void em_qflush(struct ifnet *ifp) { - struct mbuf *m; - struct adapter *adapter = (struct adapter *)ifp->if_softc; + struct adapter *adapter = ifp->if_softc; + struct tx_ring *txr = adapter->tx_rings; + struct mbuf *m; - EM_TX_LOCK(adapter); - while ((m = buf_ring_dequeue_sc(adapter->br)) != NULL) - m_freem(m); + for (int i = 0; i < adapter->num_queues; i++, txr++) { + EM_TX_LOCK(txr); + while ((m = buf_ring_dequeue_sc(txr->br)) != NULL) + m_freem(m); + EM_TX_UNLOCK(txr); + } if_qflush(ifp); - EM_TX_UNLOCK(adapter); } + #endif /* FreeBSD_version */ static void -em_start_locked(struct ifnet *ifp) +em_start_locked(struct ifnet *ifp, struct tx_ring *txr) { struct adapter *adapter = ifp->if_softc; struct mbuf *m_head; - EM_TX_LOCK_ASSERT(adapter); + EM_TX_LOCK_ASSERT(txr); if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) return; + if (!adapter->link_active) return; @@ -1139,7 +914,7 @@ em_start_locked(struct ifnet *ifp) * Encapsulation can modify our pointer, and or make it * NULL on failure. In that event, we can't requeue. */ - if (em_xmit(adapter, &m_head)) { + if (em_xmit(txr, &m_head)) { if (m_head == NULL) break; ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -1151,10 +926,8 @@ em_start_locked(struct ifnet *ifp) ETHER_BPF_MTAP(ifp, m_head); /* Set timeout in case hardware has problems transmitting. */ - adapter->watchdog_timer = EM_TX_TIMEOUT; + txr->watchdog_check = TRUE; } - if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; return; } @@ -1162,12 +935,15 @@ em_start_locked(struct ifnet *ifp) static void em_start(struct ifnet *ifp) { - struct adapter *adapter = ifp->if_softc; + struct adapter *adapter = ifp->if_softc; + struct tx_ring *txr = adapter->tx_rings; - EM_TX_LOCK(adapter); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - em_start_locked(ifp); - EM_TX_UNLOCK(adapter); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + EM_TX_LOCK(txr); + em_start_locked(ifp, txr); + EM_TX_UNLOCK(txr); + } + return; } /********************************************************************* @@ -1209,8 +985,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) em_init_locked(adapter); EM_CORE_UNLOCK(adapter); } - if (!(ifp->if_flags & IFF_NOARP)) - arp_ifinit(ifp, ifa); + arp_ifinit(ifp, ifa); } else #endif error = ether_ioctl(ifp, command, data); @@ -1218,34 +993,23 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCSIFMTU: { int max_frame_size; - u16 eeprom_data = 0; IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)"); EM_CORE_LOCK(adapter); switch (adapter->hw.mac.type) { - case e1000_82573: - /* - * 82573 only supports jumbo frames - * if ASPM is disabled. - */ - e1000_read_nvm(&adapter->hw, - NVM_INIT_3GIO_3, 1, &eeprom_data); - if (eeprom_data & NVM_WORD1A_ASPM_MASK) { - max_frame_size = ETHER_MAX_LEN; - break; - } - /* Allow Jumbo frames - fall thru */ case e1000_82571: case e1000_82572: case e1000_ich9lan: case e1000_ich10lan: case e1000_82574: - case e1000_80003es2lan: /* Limit Jumbo Frame size */ + case e1000_80003es2lan: /* 9K Jumbo Frame size */ max_frame_size = 9234; break; + case e1000_pchlan: + max_frame_size = 4096; + break; /* Adapters that do not support jumbo frames */ - case e1000_82542: case e1000_82583: case e1000_ich8lan: max_frame_size = ETHER_MAX_LEN; @@ -1281,11 +1045,8 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } else em_init_locked(adapter); } else - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - EM_TX_LOCK(adapter); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) em_stop(adapter); - EM_TX_UNLOCK(adapter); - } adapter->if_flags = ifp->if_flags; EM_CORE_UNLOCK(adapter); break; @@ -1296,10 +1057,6 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) EM_CORE_LOCK(adapter); em_disable_intr(adapter); em_set_multi(adapter); - if (adapter->hw.mac.type == e1000_82542 && - adapter->hw.revision_id == E1000_REVISION_2) { - em_initialize_receive_unit(adapter); - } #ifdef DEVICE_POLLING if (!(ifp->if_capenable & IFCAP_POLLING)) #endif @@ -1353,22 +1110,24 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ifp->if_capenable ^= IFCAP_HWCSUM; reinit = 1; } -#if __FreeBSD_version >= 700000 if (mask & IFCAP_TSO4) { ifp->if_capenable ^= IFCAP_TSO4; reinit = 1; } -#endif - if (mask & IFCAP_VLAN_HWTAGGING) { ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; reinit = 1; } + if ((mask & IFCAP_WOL) && + (ifp->if_capabilities & IFCAP_WOL) != 0) { + if (mask & IFCAP_WOL_MCAST) + ifp->if_capenable ^= IFCAP_WOL_MCAST; + if (mask & IFCAP_WOL_MAGIC) + ifp->if_capenable ^= IFCAP_WOL_MAGIC; + } if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) em_init(adapter); -#if __FreeBSD_version >= 700000 VLAN_CAPABILITIES(ifp); -#endif break; } @@ -1380,53 +1139,6 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) return (error); } -/********************************************************************* - * Watchdog timer: - * - * This routine is called from the local timer every second. - * As long as transmit descriptors are being cleaned the value - * is non-zero and we do nothing. Reaching 0 indicates a tx hang - * and we then reset the device. - * - **********************************************************************/ - -static void -em_watchdog(struct adapter *adapter) -{ - - EM_CORE_LOCK_ASSERT(adapter); - - /* - ** The timer is set to 5 every time start queues a packet. - ** Then txeof keeps resetting it as long as it cleans at - ** least one descriptor. - ** Finally, anytime all descriptors are clean the timer is - ** set to 0. - */ - EM_TX_LOCK(adapter); - if ((adapter->watchdog_timer == 0) || (--adapter->watchdog_timer)) { - EM_TX_UNLOCK(adapter); - return; - } - - /* If we are in this routine because of pause frames, then - * don't reset the hardware. - */ - if (E1000_READ_REG(&adapter->hw, E1000_STATUS) & - E1000_STATUS_TXOFF) { - adapter->watchdog_timer = EM_TX_TIMEOUT; - EM_TX_UNLOCK(adapter); - return; - } - - if (e1000_check_for_link(&adapter->hw) == 0) - device_printf(adapter->dev, "watchdog timeout -- resetting\n"); - adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - adapter->watchdog_events++; - EM_TX_UNLOCK(adapter); - - em_init_locked(adapter); -} /********************************************************************* * Init entry point @@ -1450,33 +1162,15 @@ em_init_locked(struct adapter *adapter) EM_CORE_LOCK_ASSERT(adapter); - EM_TX_LOCK(adapter); - em_stop(adapter); - EM_TX_UNLOCK(adapter); + em_disable_intr(adapter); + callout_stop(&adapter->timer); /* * Packet Buffer Allocation (PBA) * Writing PBA sets the receive portion of the buffer * the remainder is used for the transmit buffer. - * - * Devices before the 82547 had a Packet Buffer of 64K. - * Default allocation: PBA=48K for Rx, leaving 16K for Tx. - * After the 82547 the buffer was reduced to 40K. - * Default allocation: PBA=30K for Rx, leaving 10K for Tx. - * Note: default does not leave enough room for Jumbo Frame >10k. */ switch (adapter->hw.mac.type) { - case e1000_82547: - case e1000_82547_rev_2: /* 82547: Total Packet Buffer is 40K */ - if (adapter->max_frame_size > 8192) - pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */ - else - pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */ - adapter->tx_fifo_head = 0; - adapter->tx_head_addr = pba << EM_TX_HEAD_ADDR_SHIFT; - adapter->tx_fifo_size = - (E1000_PBA_40K - pba) << EM_PBA_BYTES_SHIFT; - break; /* Total Packet Buffer on these is 48K */ case e1000_82571: case e1000_82572: @@ -1492,11 +1186,13 @@ em_init_locked(struct adapter *adapter) break; case e1000_ich9lan: case e1000_ich10lan: + case e1000_pchlan: + pba = E1000_PBA_10K; + break; case e1000_ich8lan: pba = E1000_PBA_8K; break; default: - /* Devices before 82547 had a Packet Buffer of 64K. */ if (adapter->max_frame_size > 8192) pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ else @@ -1526,37 +1222,21 @@ em_init_locked(struct adapter *adapter) } /* Initialize the hardware */ - if (em_hardware_init(adapter)) { - device_printf(dev, "Unable to initialize the hardware\n"); - return; - } + em_reset(adapter); em_update_link_status(adapter); /* Setup VLAN support, basic and offload if available */ E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); -#if __FreeBSD_version < 700029 - if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) { - u32 ctrl; - ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL); - ctrl |= E1000_CTRL_VME; - E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); - } -#else /* Use real VLAN Filter support */ em_setup_vlan_hw_support(adapter); -#endif /* Set hardware offload abilities */ ifp->if_hwassist = 0; - if (adapter->hw.mac.type >= e1000_82543) { - if (ifp->if_capenable & IFCAP_TXCSUM) - ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); -#if __FreeBSD_version >= 700000 - if (ifp->if_capenable & IFCAP_TSO4) - ifp->if_hwassist |= CSUM_TSO; -#endif - } + if (ifp->if_capenable & IFCAP_TXCSUM) + ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); + if (ifp->if_capenable & IFCAP_TSO4) + ifp->if_hwassist |= CSUM_TSO; /* Configure for OS presence */ em_init_manageability(adapter); @@ -1571,9 +1251,7 @@ em_init_locked(struct adapter *adapter) /* Prepare receive descriptors and buffers */ if (em_setup_receive_structures(adapter)) { device_printf(dev, "Could not setup receive structures\n"); - EM_TX_LOCK(adapter); em_stop(adapter); - EM_TX_UNLOCK(adapter); return; } em_initialize_receive_unit(adapter); @@ -1593,14 +1271,8 @@ em_init_locked(struct adapter *adapter) tmp = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); tmp |= E1000_CTRL_EXT_PBA_CLR; E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, tmp); - /* - ** Set the IVAR - interrupt vector routing. - ** Each nibble represents a vector, high bit - ** is enable, other 3 bits are the MSIX table - ** entry, we map RXQ0 to 0, TXQ0 to 1, and - ** Link (other) to 2, hence the magic number. - */ - E1000_WRITE_REG(&adapter->hw, E1000_IVAR, 0x800A0908); + /* Set the IVAR - interrupt vector routing. */ + E1000_WRITE_REG(&adapter->hw, E1000_IVAR, adapter->ivars); } #ifdef DEVICE_POLLING @@ -1614,6 +1286,10 @@ em_init_locked(struct adapter *adapter) #endif /* DEVICE_POLLING */ em_enable_intr(adapter); + /* AMT based hardware can now take control from firmware */ + if (adapter->has_manage && adapter->has_amt) + em_get_hw_control(adapter); + /* Don't reset the phy next time init gets called */ adapter->hw.phy.reset_disable = TRUE; } @@ -1632,13 +1308,15 @@ em_init(void *arg) #ifdef DEVICE_POLLING /********************************************************************* * - * Legacy polling routine + * Legacy polling routine: note this only works with single queue * *********************************************************************/ static int em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct adapter *adapter = ifp->if_softc; + struct tx_ring *txr = adapter->tx_rings; + struct rx_ring *rxr = adapter->rx_rings; u32 reg_icr, rx_done = 0; EM_CORE_LOCK(adapter); @@ -1659,137 +1337,30 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } EM_CORE_UNLOCK(adapter); - rx_done = em_rxeof(adapter, count); + rx_done = em_rxeof(rxr, count); - EM_TX_LOCK(adapter); - em_txeof(adapter); + EM_TX_LOCK(txr); + em_txeof(txr); #if __FreeBSD_version >= 800000 - if (!drbr_empty(ifp, adapter->br)) - em_mq_start_locked(ifp, NULL); + if (!drbr_empty(ifp, txr->br)) + em_mq_start_locked(ifp, txr, NULL); #else - if (!IFQ_DRV_IS_EMPTY(&ifp->snd)) - em_start_locked(ifp); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp, txr); #endif - EM_TX_UNLOCK(adapter); + EM_TX_UNLOCK(txr); + return (rx_done); } #endif /* DEVICE_POLLING */ -#ifdef EM_LEGACY_IRQ -/********************************************************************* - * - * Legacy Interrupt Service routine - * - *********************************************************************/ - -static void -em_intr(void *arg) -{ - struct adapter *adapter = arg; - struct ifnet *ifp = adapter->ifp; - u32 reg_icr; - - - if (ifp->if_capenable & IFCAP_POLLING) - return; - - EM_CORE_LOCK(adapter); - reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); - if (reg_icr & E1000_ICR_RXO) - adapter->rx_overruns++; - if ((reg_icr == 0xffffffff) || (reg_icr == 0)|| - (adapter->hw.mac.type >= e1000_82571 && - (reg_icr & E1000_ICR_INT_ASSERTED) == 0)) - goto out; - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - goto out; - - if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - callout_stop(&adapter->timer); - adapter->hw.mac.get_link_status = 1; - em_update_link_status(adapter); - /* Deal with TX cruft when link lost */ - em_tx_purge(adapter); - callout_reset(&adapter->timer, hz, - em_local_timer, adapter); - goto out; - } - - EM_TX_LOCK(adapter); - em_txeof(adapter); - em_rxeof(adapter, -1); - em_txeof(adapter); - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - em_start_locked(ifp); - EM_TX_UNLOCK(adapter); - -out: - EM_CORE_UNLOCK(adapter); - return; -} - -#else /* EM_FAST_IRQ, then fast interrupt routines only */ - -static void -em_handle_link(void *context, int pending) -{ - struct adapter *adapter = context; - struct ifnet *ifp = adapter->ifp; - - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - return; - - EM_CORE_LOCK(adapter); - callout_stop(&adapter->timer); - em_update_link_status(adapter); - /* Deal with TX cruft when link lost */ - em_tx_purge(adapter); - callout_reset(&adapter->timer, hz, em_local_timer, adapter); - EM_CORE_UNLOCK(adapter); -} - - -/* Combined RX/TX handler, used by Legacy and MSI */ -static void -em_handle_rxtx(void *context, int pending) -{ - struct adapter *adapter = context; - struct ifnet *ifp = adapter->ifp; - - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if (em_rxeof(adapter, adapter->rx_process_limit) != 0) - taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); - EM_TX_LOCK(adapter); - em_txeof(adapter); - -#if __FreeBSD_version >= 800000 - if (!drbr_empty(ifp, adapter->br)) - em_mq_start_locked(ifp, NULL); -#else - if (!IFQ_DRV_IS_EMPTY(&ifp->snd)) - em_start_locked(ifp); -#endif - EM_TX_UNLOCK(adapter); - } - - em_enable_intr(adapter); -} /********************************************************************* * * Fast Legacy/MSI Combined Interrupt Service routine * *********************************************************************/ -#if __FreeBSD_version < 700000 -#define FILTER_STRAY -#define FILTER_HANDLED -static void -#else static int -#endif em_irq_fast(void *arg) { struct adapter *adapter = arg; @@ -1816,13 +1387,8 @@ em_irq_fast(void *arg) (reg_icr & E1000_ICR_INT_ASSERTED) == 0) return FILTER_STRAY; - /* - * Mask interrupts until the taskqueue is finished running. This is - * cheap, just assume that it is needed. This also works around the - * MSI message reordering errata on certain systems. - */ em_disable_intr(adapter); - taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); + taskqueue_enqueue(adapter->tq, &adapter->que_task); /* Link status change */ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { @@ -1835,30 +1401,64 @@ em_irq_fast(void *arg) return FILTER_HANDLED; } +/* Combined RX/TX handler, used by Legacy and MSI */ +static void +em_handle_que(void *context, int pending) +{ + struct adapter *adapter = context; + struct ifnet *ifp = adapter->ifp; + struct tx_ring *txr = adapter->tx_rings; + struct rx_ring *rxr = adapter->rx_rings; + u32 loop = EM_MAX_LOOP; + bool more_rx, more_tx; + + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + EM_TX_LOCK(txr); + do { + more_rx = em_rxeof(rxr, adapter->rx_process_limit); + more_tx = em_txeof(txr); + } while (loop-- && (more_rx || more_tx)); + +#if __FreeBSD_version >= 800000 + if (!drbr_empty(ifp, txr->br)) + em_mq_start_locked(ifp, txr, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp, txr); +#endif + if (more_rx || more_tx) + taskqueue_enqueue(adapter->tq, &adapter->que_task); + + EM_TX_UNLOCK(txr); + } + + em_enable_intr(adapter); + return; +} + + /********************************************************************* * * MSIX Interrupt Service Routines * **********************************************************************/ -#define EM_MSIX_TX 0x00040000 -#define EM_MSIX_RX 0x00010000 -#define EM_MSIX_LINK 0x00100000 - static void em_msix_tx(void *arg) { - struct adapter *adapter = arg; - struct ifnet *ifp = adapter->ifp; + struct tx_ring *txr = arg; + struct adapter *adapter = txr->adapter; + bool more; - ++adapter->tx_irq; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - EM_TX_LOCK(adapter); - em_txeof(adapter); - EM_TX_UNLOCK(adapter); - taskqueue_enqueue(adapter->tq, &adapter->tx_task); - } - /* Reenable this interrupt */ - E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_TX); + ++txr->tx_irq; + EM_TX_LOCK(txr); + more = em_txeof(txr); + EM_TX_UNLOCK(txr); + if (more) + taskqueue_enqueue(txr->tq, &txr->tx_task); + else + /* Reenable this interrupt */ + E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); return; } @@ -1871,15 +1471,17 @@ em_msix_tx(void *arg) static void em_msix_rx(void *arg) { - struct adapter *adapter = arg; - struct ifnet *ifp = adapter->ifp; + struct rx_ring *rxr = arg; + struct adapter *adapter = rxr->adapter; + bool more; - ++adapter->rx_irq; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && - (em_rxeof(adapter, adapter->rx_process_limit) != 0)) - taskqueue_enqueue(adapter->tq, &adapter->rx_task); - /* Reenable this interrupt */ - E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_RX); + ++rxr->rx_irq; + more = em_rxeof(rxr, adapter->rx_process_limit); + if (more) + taskqueue_enqueue(rxr->tq, &rxr->rx_task); + else + /* Reenable this interrupt */ + E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims); return; } @@ -1888,7 +1490,6 @@ em_msix_rx(void *arg) * MSIX Link Fast Interrupt Service routine * **********************************************************************/ - static void em_msix_link(void *arg) { @@ -1901,45 +1502,71 @@ em_msix_link(void *arg) if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { adapter->hw.mac.get_link_status = 1; taskqueue_enqueue(taskqueue_fast, &adapter->link_task); - } - E1000_WRITE_REG(&adapter->hw, E1000_IMS, - EM_MSIX_LINK | E1000_IMS_LSC); + } else + E1000_WRITE_REG(&adapter->hw, E1000_IMS, + EM_MSIX_LINK | E1000_IMS_LSC); return; } static void em_handle_rx(void *context, int pending) { - struct adapter *adapter = context; - struct ifnet *ifp = adapter->ifp; - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && - (em_rxeof(adapter, adapter->rx_process_limit) != 0)) - taskqueue_enqueue(adapter->tq, &adapter->rx_task); + struct rx_ring *rxr = context; + struct adapter *adapter = rxr->adapter; + u32 loop = EM_MAX_LOOP; + bool more; + do { + more = em_rxeof(rxr, adapter->rx_process_limit); + } while (loop-- && more); + /* Reenable this interrupt */ + E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims); } static void em_handle_tx(void *context, int pending) { - struct adapter *adapter = context; + struct tx_ring *txr = context; + struct adapter *adapter = txr->adapter; struct ifnet *ifp = adapter->ifp; + u32 loop = EM_MAX_LOOP; + bool more; + + if (!EM_TX_TRYLOCK(txr)) + return; + do { + more = em_txeof(txr); + } while (loop-- && more); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if (!EM_TX_TRYLOCK(adapter)) - return; - em_txeof(adapter); #if __FreeBSD_version >= 800000 - if (!drbr_empty(ifp, adapter->br)) - em_mq_start_locked(ifp, NULL); + if (!drbr_empty(ifp, txr->br)) + em_mq_start_locked(ifp, txr, NULL); #else - if (!IFQ_DRV_IS_EMPTY(&ifp->snd)) - em_start_locked(ifp); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp, txr); #endif - EM_TX_UNLOCK(adapter); - } + E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); + EM_TX_UNLOCK(txr); } -#endif /* EM_FAST_IRQ */ + +static void +em_handle_link(void *context, int pending) +{ + struct adapter *adapter = context; + struct ifnet *ifp = adapter->ifp; + + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + return; + + EM_CORE_LOCK(adapter); + callout_stop(&adapter->timer); + em_update_link_status(adapter); + callout_reset(&adapter->timer, hz, em_local_timer, adapter); + E1000_WRITE_REG(&adapter->hw, E1000_IMS, + EM_MSIX_LINK | E1000_IMS_LSC); + EM_CORE_UNLOCK(adapter); +} + /********************************************************************* * @@ -1972,8 +1599,6 @@ em_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) if ((adapter->hw.phy.media_type == e1000_media_type_fiber) || (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) { - if (adapter->hw.mac.type == e1000_82545) - fiber_type = IFM_1000_LX; ifmr->ifm_active |= fiber_type | IFM_FDX; } else { switch (adapter->link_speed) { @@ -2065,8 +1690,9 @@ em_media_change(struct ifnet *ifp) **********************************************************************/ static int -em_xmit(struct adapter *adapter, struct mbuf **m_headp) +em_xmit(struct tx_ring *txr, struct mbuf **m_headp) { + struct adapter *adapter = txr->adapter; bus_dma_segment_t segs[EM_MAX_SCATTER]; bus_dmamap_t map; struct em_buffer *tx_buffer, *tx_buffer_mapped; @@ -2075,31 +1701,17 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp) u32 txd_upper, txd_lower, txd_used, txd_saved; int nsegs, i, j, first, last = 0; int error, do_tso, tso_desc = 0; -#if __FreeBSD_version < 700000 - struct m_tag *mtag; -#endif + m_head = *m_headp; txd_upper = txd_lower = txd_used = txd_saved = 0; - -#if __FreeBSD_version >= 700000 do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0); -#else - do_tso = 0; -#endif /* * Force a cleanup if number of TX descriptors * available hits the threshold */ - if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) { - em_txeof(adapter); - /* Now do we at least have a minimal? */ - if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) { - adapter->no_tx_desc_avail1++; - return (ENOBUFS); - } - } - + if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD) + em_txeof(txr); /* * TSO workaround: @@ -2121,12 +1733,12 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp) * of the EOP which is the only one that * now gets a DONE bit writeback. */ - first = adapter->next_avail_tx_desc; - tx_buffer = &adapter->tx_buffer_area[first]; + first = txr->next_avail_desc; + tx_buffer = &txr->tx_buffers[first]; tx_buffer_mapped = tx_buffer; map = tx_buffer->map; - error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, + error = bus_dmamap_load_mbuf_sg(txr->txtag, map, *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); /* @@ -2151,7 +1763,7 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp) *m_headp = m; /* Try it again */ - error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, + error = bus_dmamap_load_mbuf_sg(txr->txtag, map, *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); if (error) { @@ -2171,15 +1783,15 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp) * it follows a TSO burst, then we need to add a * sentinel descriptor to prevent premature writeback. */ - if ((do_tso == 0) && (adapter->tx_tso == TRUE)) { + if ((do_tso == 0) && (txr->tx_tso == TRUE)) { if (nsegs == 1) tso_desc = TRUE; - adapter->tx_tso = FALSE; + txr->tx_tso = FALSE; } - if (nsegs > (adapter->num_tx_desc_avail - 2)) { - adapter->no_tx_desc_avail2++; - bus_dmamap_unload(adapter->txtag, map); + if (nsegs > (txr->tx_avail - 2)) { + txr->no_desc_avail++; + bus_dmamap_unload(txr->txtag, map); return (ENOBUFS); } m_head = *m_headp; @@ -2187,7 +1799,7 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp) /* Do hardware assists */ #if __FreeBSD_version >= 700000 if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { - error = em_tso_setup(adapter, m_head, &txd_upper, &txd_lower); + error = em_tso_setup(txr, m_head, &txd_upper, &txd_lower); if (error != TRUE) return (ENXIO); /* something foobar */ /* we need to make a final sentinel transmit desc */ @@ -2195,123 +1807,70 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp) } else #endif if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) - em_transmit_checksum_setup(adapter, m_head, + em_transmit_checksum_setup(txr, m_head, &txd_upper, &txd_lower); - i = adapter->next_avail_tx_desc; - if (adapter->pcix_82544) - txd_saved = i; + i = txr->next_avail_desc; /* Set up our transmit descriptors */ for (j = 0; j < nsegs; j++) { bus_size_t seg_len; bus_addr_t seg_addr; - /* If adapter is 82544 and on PCIX bus */ - if(adapter->pcix_82544) { - DESC_ARRAY desc_array; - u32 array_elements, counter; - /* - * Check the Address and Length combination and - * split the data accordingly - */ - array_elements = em_fill_descriptors(segs[j].ds_addr, - segs[j].ds_len, &desc_array); - for (counter = 0; counter < array_elements; counter++) { - if (txd_used == adapter->num_tx_desc_avail) { - adapter->next_avail_tx_desc = txd_saved; - adapter->no_tx_desc_avail2++; - bus_dmamap_unload(adapter->txtag, map); - return (ENOBUFS); - } - tx_buffer = &adapter->tx_buffer_area[i]; - ctxd = &adapter->tx_desc_base[i]; - ctxd->buffer_addr = htole64( - desc_array.descriptor[counter].address); - ctxd->lower.data = htole32( - (adapter->txd_cmd | txd_lower | (u16) - desc_array.descriptor[counter].length)); - ctxd->upper.data = - htole32((txd_upper)); - last = i; - if (++i == adapter->num_tx_desc) - i = 0; - tx_buffer->m_head = NULL; - tx_buffer->next_eop = -1; - txd_used++; - } + + tx_buffer = &txr->tx_buffers[i]; + ctxd = &txr->tx_base[i]; + seg_addr = segs[j].ds_addr; + seg_len = segs[j].ds_len; + /* + ** TSO Workaround: + ** If this is the last descriptor, we want to + ** split it so we have a small final sentinel + */ + if (tso_desc && (j == (nsegs -1)) && (seg_len > 8)) { + seg_len -= 4; + ctxd->buffer_addr = htole64(seg_addr); + ctxd->lower.data = htole32( + adapter->txd_cmd | txd_lower | seg_len); + ctxd->upper.data = + htole32(txd_upper); + if (++i == adapter->num_tx_desc) + i = 0; + /* Now make the sentinel */ + ++txd_used; /* using an extra txd */ + ctxd = &txr->tx_base[i]; + tx_buffer = &txr->tx_buffers[i]; + ctxd->buffer_addr = + htole64(seg_addr + seg_len); + ctxd->lower.data = htole32( + adapter->txd_cmd | txd_lower | 4); + ctxd->upper.data = + htole32(txd_upper); + last = i; + if (++i == adapter->num_tx_desc) + i = 0; } else { - tx_buffer = &adapter->tx_buffer_area[i]; - ctxd = &adapter->tx_desc_base[i]; - seg_addr = segs[j].ds_addr; - seg_len = segs[j].ds_len; - /* - ** TSO Workaround: - ** If this is the last descriptor, we want to - ** split it so we have a small final sentinel - */ - if (tso_desc && (j == (nsegs -1)) && (seg_len > 8)) { - seg_len -= 4; - ctxd->buffer_addr = htole64(seg_addr); - ctxd->lower.data = htole32( - adapter->txd_cmd | txd_lower | seg_len); - ctxd->upper.data = - htole32(txd_upper); - if (++i == adapter->num_tx_desc) - i = 0; - /* Now make the sentinel */ - ++txd_used; /* using an extra txd */ - ctxd = &adapter->tx_desc_base[i]; - tx_buffer = &adapter->tx_buffer_area[i]; - ctxd->buffer_addr = - htole64(seg_addr + seg_len); - ctxd->lower.data = htole32( - adapter->txd_cmd | txd_lower | 4); - ctxd->upper.data = - htole32(txd_upper); - last = i; - if (++i == adapter->num_tx_desc) - i = 0; - } else { - ctxd->buffer_addr = htole64(seg_addr); - ctxd->lower.data = htole32( - adapter->txd_cmd | txd_lower | seg_len); - ctxd->upper.data = - htole32(txd_upper); - last = i; - if (++i == adapter->num_tx_desc) - i = 0; - } - tx_buffer->m_head = NULL; - tx_buffer->next_eop = -1; + ctxd->buffer_addr = htole64(seg_addr); + ctxd->lower.data = htole32( + adapter->txd_cmd | txd_lower | seg_len); + ctxd->upper.data = + htole32(txd_upper); + last = i; + if (++i == adapter->num_tx_desc) + i = 0; } + tx_buffer->m_head = NULL; + tx_buffer->next_eop = -1; } - adapter->next_avail_tx_desc = i; - if (adapter->pcix_82544) - adapter->num_tx_desc_avail -= txd_used; - else { - adapter->num_tx_desc_avail -= nsegs; - if (tso_desc) /* TSO used an extra for sentinel */ - adapter->num_tx_desc_avail -= txd_used; - } + txr->next_avail_desc = i; + txr->tx_avail -= nsegs; + if (tso_desc) /* TSO used an extra for sentinel */ + txr->tx_avail -= txd_used; - /* - ** Handle VLAN tag, this is the - ** biggest difference between - ** 6.x and 7 - */ -#if __FreeBSD_version < 700000 - /* Find out if we are in vlan mode. */ - mtag = VLAN_OUTPUT_TAG(ifp, m_head); - if (mtag != NULL) { - ctxd->upper.fields.special = - htole16(VLAN_TAG_VALUE(mtag)); -#else /* FreeBSD 7 */ if (m_head->m_flags & M_VLANTAG) { /* Set the vlan id. */ ctxd->upper.fields.special = htole16(m_head->m_pkthdr.ether_vtag); -#endif /* Tell hardware to add tag */ ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE); } @@ -2319,7 +1878,7 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp) tx_buffer->m_head = m_head; tx_buffer_mapped->map = tx_buffer->map; tx_buffer->map = map; - bus_dmamap_sync(adapter->txtag, map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE); /* * Last Descriptor of Packet @@ -2332,145 +1891,20 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp) * Keep track in the first buffer which * descriptor will be written back */ - tx_buffer = &adapter->tx_buffer_area[first]; + tx_buffer = &txr->tx_buffers[first]; tx_buffer->next_eop = last; /* * Advance the Transmit Descriptor Tail (TDT), this tells the E1000 * that this frame is available to transmit. */ - bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - if (adapter->hw.mac.type == e1000_82547 && - adapter->link_duplex == HALF_DUPLEX) - em_82547_move_tail(adapter); - else { - E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), i); - if (adapter->hw.mac.type == e1000_82547) - em_82547_update_fifo_head(adapter, - m_head->m_pkthdr.len); - } + E1000_WRITE_REG(&adapter->hw, E1000_TDT(txr->me), i); return (0); } -/********************************************************************* - * - * 82547 workaround to avoid controller hang in half-duplex environment. - * The workaround is to avoid queuing a large packet that would span - * the internal Tx FIFO ring boundary. We need to reset the FIFO pointers - * in this case. We do that only when FIFO is quiescent. - * - **********************************************************************/ -static void -em_82547_move_tail(void *arg) -{ - struct adapter *adapter = arg; - struct e1000_tx_desc *tx_desc; - u16 hw_tdt, sw_tdt, length = 0; - bool eop = 0; - - EM_TX_LOCK_ASSERT(adapter); - - hw_tdt = E1000_READ_REG(&adapter->hw, E1000_TDT(0)); - sw_tdt = adapter->next_avail_tx_desc; - - while (hw_tdt != sw_tdt) { - tx_desc = &adapter->tx_desc_base[hw_tdt]; - length += tx_desc->lower.flags.length; - eop = tx_desc->lower.data & E1000_TXD_CMD_EOP; - if (++hw_tdt == adapter->num_tx_desc) - hw_tdt = 0; - - if (eop) { - if (em_82547_fifo_workaround(adapter, length)) { - adapter->tx_fifo_wrk_cnt++; - callout_reset(&adapter->tx_fifo_timer, 1, - em_82547_move_tail, adapter); - break; - } - E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), hw_tdt); - em_82547_update_fifo_head(adapter, length); - length = 0; - } - } -} - -static int -em_82547_fifo_workaround(struct adapter *adapter, int len) -{ - int fifo_space, fifo_pkt_len; - - fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR); - - if (adapter->link_duplex == HALF_DUPLEX) { - fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head; - - if (fifo_pkt_len >= (EM_82547_PKT_THRESH + fifo_space)) { - if (em_82547_tx_fifo_reset(adapter)) - return (0); - else - return (1); - } - } - - return (0); -} - -static void -em_82547_update_fifo_head(struct adapter *adapter, int len) -{ - int fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR); - - /* tx_fifo_head is always 16 byte aligned */ - adapter->tx_fifo_head += fifo_pkt_len; - if (adapter->tx_fifo_head >= adapter->tx_fifo_size) { - adapter->tx_fifo_head -= adapter->tx_fifo_size; - } -} - - -static int -em_82547_tx_fifo_reset(struct adapter *adapter) -{ - u32 tctl; - - if ((E1000_READ_REG(&adapter->hw, E1000_TDT(0)) == - E1000_READ_REG(&adapter->hw, E1000_TDH(0))) && - (E1000_READ_REG(&adapter->hw, E1000_TDFT) == - E1000_READ_REG(&adapter->hw, E1000_TDFH)) && - (E1000_READ_REG(&adapter->hw, E1000_TDFTS) == - E1000_READ_REG(&adapter->hw, E1000_TDFHS)) && - (E1000_READ_REG(&adapter->hw, E1000_TDFPC) == 0)) { - /* Disable TX unit */ - tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL); - E1000_WRITE_REG(&adapter->hw, E1000_TCTL, - tctl & ~E1000_TCTL_EN); - - /* Reset FIFO pointers */ - E1000_WRITE_REG(&adapter->hw, E1000_TDFT, - adapter->tx_head_addr); - E1000_WRITE_REG(&adapter->hw, E1000_TDFH, - adapter->tx_head_addr); - E1000_WRITE_REG(&adapter->hw, E1000_TDFTS, - adapter->tx_head_addr); - E1000_WRITE_REG(&adapter->hw, E1000_TDFHS, - adapter->tx_head_addr); - - /* Re-enable TX unit */ - E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl); - E1000_WRITE_FLUSH(&adapter->hw); - - adapter->tx_fifo_head = 0; - adapter->tx_fifo_reset_cnt++; - - return (TRUE); - } - else { - return (FALSE); - } -} - static void em_set_promisc(struct adapter *adapter) { @@ -2541,7 +1975,11 @@ em_set_multi(struct adapter *adapter) if (mta == NULL) panic("em_set_multi memory failure\n"); +#if __FreeBSD_version < 800000 + IF_ADDR_LOCK(ifp); +#else if_maddr_rlock(ifp); +#endif TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -2553,8 +1991,11 @@ em_set_multi(struct adapter *adapter) &mta[mcnt * ETH_ADDR_LEN], ETH_ADDR_LEN); mcnt++; } +#if __FreeBSD_version < 800000 + IF_ADDR_UNLOCK(ifp); +#else if_maddr_runlock(ifp); - +#endif if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) { reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); reg_rctl |= E1000_RCTL_MPE; @@ -2587,11 +2028,10 @@ em_local_timer(void *arg) { struct adapter *adapter = arg; struct ifnet *ifp = adapter->ifp; + struct tx_ring *txr = adapter->tx_rings; EM_CORE_LOCK_ASSERT(adapter); - taskqueue_enqueue(adapter->tq, - &adapter->rxtx_task); em_update_link_status(adapter); em_update_stats_counters(adapter); @@ -2602,18 +2042,31 @@ em_local_timer(void *arg) if (em_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) em_print_hw_stats(adapter); - em_smartspeed(adapter); - /* - * Each second we check the watchdog to - * protect against hardware hangs. - */ - em_watchdog(adapter); + ** Check for time since any descriptor was cleaned + */ + for (int i = 0; i < adapter->num_queues; i++, txr++) { + EM_TX_LOCK(txr); + if (txr->watchdog_check == FALSE) { + EM_TX_UNLOCK(txr); + continue; + } + if ((ticks - txr->watchdog_time) > EM_WATCHDOG) + goto hung; + EM_TX_UNLOCK(txr); + } callout_reset(&adapter->timer, hz, em_local_timer, adapter); - + return; +hung: + device_printf(adapter->dev, "Watchdog timeout -- resetting\n"); + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + adapter->watchdog_events++; + EM_TX_UNLOCK(txr); + em_init_locked(adapter); } + static void em_update_link_status(struct adapter *adapter) { @@ -2677,7 +2130,8 @@ em_update_link_status(struct adapter *adapter) device_printf(dev, "Link is Down\n"); adapter->link_active = 0; /* Link down, disable watchdog */ - adapter->watchdog_timer = FALSE; + // JFV change later + //adapter->watchdog_check = FALSE; if_link_state_change(ifp, LINK_STATE_DOWN); } } @@ -2696,22 +2150,30 @@ em_stop(void *arg) { struct adapter *adapter = arg; struct ifnet *ifp = adapter->ifp; + struct tx_ring *txr = adapter->tx_rings; EM_CORE_LOCK_ASSERT(adapter); - EM_TX_LOCK_ASSERT(adapter); INIT_DEBUGOUT("em_stop: begin"); em_disable_intr(adapter); callout_stop(&adapter->timer); - callout_stop(&adapter->tx_fifo_timer); /* Tell the stack that the interface is no longer active */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + /* Unarm watchdog timer. */ + for (int i = 0; i < adapter->num_queues; i++, txr++) { + EM_TX_LOCK(txr); + txr->watchdog_check = FALSE; + EM_TX_UNLOCK(txr); + } + e1000_reset_hw(&adapter->hw); - if (adapter->hw.mac.type >= e1000_82544) - E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0); + E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0); + + e1000_led_off(&adapter->hw); + e1000_cleanup_led(&adapter->hw); } @@ -2757,7 +2219,7 @@ static int em_allocate_pci_resources(struct adapter *adapter) { device_t dev = adapter->dev; - int val, rid, error = E1000_SUCCESS; + int rid; rid = PCIR_BAR(0); adapter->memory = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -2772,58 +2234,17 @@ em_allocate_pci_resources(struct adapter *adapter) rman_get_bushandle(adapter->memory); adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle; - /* Only older adapters use IO mapping */ - if ((adapter->hw.mac.type > e1000_82543) && - (adapter->hw.mac.type < e1000_82571)) { - /* Figure our where our IO BAR is ? */ - for (rid = PCIR_BAR(0); rid < PCIR_CIS;) { - val = pci_read_config(dev, rid, 4); - if (EM_BAR_TYPE(val) == EM_BAR_TYPE_IO) { - adapter->io_rid = rid; - break; - } - rid += 4; - /* check for 64bit BAR */ - if (EM_BAR_MEM_TYPE(val) == EM_BAR_MEM_TYPE_64BIT) - rid += 4; - } - if (rid >= PCIR_CIS) { - device_printf(dev, "Unable to locate IO BAR\n"); - return (ENXIO); - } - adapter->ioport = bus_alloc_resource_any(dev, - SYS_RES_IOPORT, &adapter->io_rid, RF_ACTIVE); - if (adapter->ioport == NULL) { - device_printf(dev, "Unable to allocate bus resource: " - "ioport\n"); - return (ENXIO); - } - adapter->hw.io_base = 0; - adapter->osdep.io_bus_space_tag = - rman_get_bustag(adapter->ioport); - adapter->osdep.io_bus_space_handle = - rman_get_bushandle(adapter->ioport); - } - - /* - ** Init the resource arrays - ** used by MSIX setup - */ - for (int i = 0; i < 3; i++) { - adapter->rid[i] = i + 1; /* MSI/X RID starts at 1 */ - adapter->tag[i] = NULL; - adapter->res[i] = NULL; - } + /* Default to a single queue */ + adapter->num_queues = 1; /* * Setup MSI/X or MSI if PCI Express */ - if (em_enable_msi) - adapter->msi = em_setup_msix(adapter); + adapter->msix = em_setup_msix(adapter); adapter->hw.back = &adapter->osdep; - return (error); + return (0); } /********************************************************************* @@ -2835,63 +2256,40 @@ int em_allocate_legacy(struct adapter *adapter) { device_t dev = adapter->dev; - int error; + int error, rid = 0; /* Manually turn off all interrupts */ E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff); - /* Legacy RID is 0 */ - if (adapter->msi == 0) - adapter->rid[0] = 0; - + if (adapter->msix == 1) /* using MSI */ + rid = 1; /* We allocate a single interrupt resource */ - adapter->res[0] = bus_alloc_resource_any(dev, - SYS_RES_IRQ, &adapter->rid[0], RF_SHAREABLE | RF_ACTIVE); - if (adapter->res[0] == NULL) { + adapter->res = bus_alloc_resource_any(dev, + SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); + if (adapter->res == NULL) { device_printf(dev, "Unable to allocate bus resource: " "interrupt\n"); return (ENXIO); } -#ifdef EM_LEGACY_IRQ - /* We do Legacy setup */ - if ((error = bus_setup_intr(dev, adapter->res[0], -#if __FreeBSD_version > 700000 - INTR_TYPE_NET | INTR_MPSAFE, NULL, em_intr, adapter, -#else /* 6.X */ - INTR_TYPE_NET | INTR_MPSAFE, em_intr, adapter, -#endif - &adapter->tag[0])) != 0) { - device_printf(dev, "Failed to register interrupt handler"); - return (error); - } - -#else /* FAST_IRQ */ /* - * Try allocating a fast interrupt and the associated deferred - * processing contexts. + * Allocate a fast interrupt and the associated + * deferred processing contexts. */ - TASK_INIT(&adapter->rxtx_task, 0, em_handle_rxtx, adapter); + TASK_INIT(&adapter->que_task, 0, em_handle_que, adapter); TASK_INIT(&adapter->link_task, 0, em_handle_link, adapter); adapter->tq = taskqueue_create_fast("em_taskq", M_NOWAIT, taskqueue_thread_enqueue, &adapter->tq); taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq", device_get_nameunit(adapter->dev)); -#if __FreeBSD_version < 700000 - if ((error = bus_setup_intr(dev, adapter->res[0], - INTR_TYPE_NET | INTR_FAST, em_irq_fast, adapter, -#else - if ((error = bus_setup_intr(dev, adapter->res[0], - INTR_TYPE_NET, em_irq_fast, NULL, adapter, -#endif - &adapter->tag[0])) != 0) { + if ((error = bus_setup_intr(dev, adapter->res, INTR_TYPE_NET, + em_irq_fast, NULL, adapter, &adapter->tag)) != 0) { device_printf(dev, "Failed to register fast interrupt " "handler: %d\n", error); taskqueue_free(adapter->tq); adapter->tq = NULL; return (error); } -#endif /* EM_LEGACY_IRQ */ return (0); } @@ -2906,80 +2304,109 @@ em_allocate_legacy(struct adapter *adapter) int em_allocate_msix(struct adapter *adapter) { - device_t dev = adapter->dev; - int error; + device_t dev = adapter->dev; + struct tx_ring *txr = adapter->tx_rings; + struct rx_ring *rxr = adapter->rx_rings; + int error, rid, vector = 0; + /* Make sure all interrupts are disabled */ E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff); - /* First get the resources */ - for (int i = 0; i < adapter->msi; i++) { - adapter->res[i] = bus_alloc_resource_any(dev, - SYS_RES_IRQ, &adapter->rid[i], RF_ACTIVE); - if (adapter->res[i] == NULL) { + /* First set up ring resources */ + for (int i = 0; i < adapter->num_queues; i++, txr++, rxr++) { + + /* RX ring */ + rid = vector + 1; + + rxr->res = bus_alloc_resource_any(dev, + SYS_RES_IRQ, &rid, RF_ACTIVE); + if (rxr->res == NULL) { device_printf(dev, "Unable to allocate bus resource: " - "MSIX Interrupt\n"); + "RX MSIX Interrupt %d\n", i); return (ENXIO); } + if ((error = bus_setup_intr(dev, rxr->res, + INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_rx, + rxr, &rxr->tag)) != 0) { + device_printf(dev, "Failed to register RX handler"); + return (error); + } + rxr->msix = vector++; /* NOTE increment vector for TX */ + TASK_INIT(&rxr->rx_task, 0, em_handle_rx, rxr); + rxr->tq = taskqueue_create_fast("em_rxq", M_NOWAIT, + taskqueue_thread_enqueue, &rxr->tq); + taskqueue_start_threads(&rxr->tq, 1, PI_NET, "%s rxq", + device_get_nameunit(adapter->dev)); + /* + ** Set the bit to enable interrupt + ** in E1000_IMS -- bits 20 and 21 + ** are for RX0 and RX1, note this has + ** NOTHING to do with the MSIX vector + */ + rxr->ims = 1 << (20 + i); + adapter->ivars |= (8 | rxr->msix) << (i * 4); + + /* TX ring */ + rid = vector + 1; + txr->res = bus_alloc_resource_any(dev, + SYS_RES_IRQ, &rid, RF_ACTIVE); + if (txr->res == NULL) { + device_printf(dev, + "Unable to allocate bus resource: " + "TX MSIX Interrupt %d\n", i); + return (ENXIO); + } + if ((error = bus_setup_intr(dev, txr->res, + INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_tx, + txr, &txr->tag)) != 0) { + device_printf(dev, "Failed to register TX handler"); + return (error); + } + txr->msix = vector++; /* Increment vector for next pass */ + TASK_INIT(&txr->tx_task, 0, em_handle_tx, txr); + txr->tq = taskqueue_create_fast("em_txq", M_NOWAIT, + taskqueue_thread_enqueue, &txr->tq); + taskqueue_start_threads(&txr->tq, 1, PI_NET, "%s txq", + device_get_nameunit(adapter->dev)); + /* + ** Set the bit to enable interrupt + ** in E1000_IMS -- bits 22 and 23 + ** are for TX0 and TX1, note this has + ** NOTHING to do with the MSIX vector + */ + txr->ims = 1 << (22 + i); + adapter->ivars |= (8 | txr->msix) << (8 + (i * 4)); } - /* - * Now allocate deferred processing contexts. - */ - TASK_INIT(&adapter->rx_task, 0, em_handle_rx, adapter); - TASK_INIT(&adapter->tx_task, 0, em_handle_tx, adapter); - /* - * Handle compatibility for msi case for deferral due to - * trylock failure - */ - TASK_INIT(&adapter->rxtx_task, 0, em_handle_tx, adapter); + /* Link interrupt */ + ++rid; + adapter->res = bus_alloc_resource_any(dev, + SYS_RES_IRQ, &rid, RF_ACTIVE); + if (!adapter->res) { + device_printf(dev,"Unable to allocate " + "bus resource: Link interrupt [%d]\n", rid); + return (ENXIO); + } + /* Set the link handler function */ + error = bus_setup_intr(dev, adapter->res, + INTR_TYPE_NET | INTR_MPSAFE, NULL, + em_msix_link, adapter, &adapter->tag); + if (error) { + adapter->res = NULL; + device_printf(dev, "Failed to register LINK handler"); + return (error); + } + adapter->linkvec = vector; + adapter->ivars |= (8 | vector) << 16; + adapter->ivars |= 0x80000000; TASK_INIT(&adapter->link_task, 0, em_handle_link, adapter); - adapter->tq = taskqueue_create_fast("em_taskq", M_NOWAIT, + adapter->tq = taskqueue_create_fast("em_link", M_NOWAIT, taskqueue_thread_enqueue, &adapter->tq); - taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq", + taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq", device_get_nameunit(adapter->dev)); - /* - * And setup the interrupt handlers - */ - - /* First slot to RX */ - if ((error = bus_setup_intr(dev, adapter->res[0], -#if __FreeBSD_version > 700000 - INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_rx, adapter, -#else /* 6.X */ - INTR_TYPE_NET | INTR_MPSAFE, em_msix_rx, adapter, -#endif - &adapter->tag[0])) != 0) { - device_printf(dev, "Failed to register RX handler"); - return (error); - } - - /* Next TX */ - if ((error = bus_setup_intr(dev, adapter->res[1], -#if __FreeBSD_version > 700000 - INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_tx, adapter, -#else /* 6.X */ - INTR_TYPE_NET | INTR_MPSAFE, em_msix_tx, adapter, -#endif - &adapter->tag[1])) != 0) { - device_printf(dev, "Failed to register TX handler"); - return (error); - } - - /* And Link */ - if ((error = bus_setup_intr(dev, adapter->res[2], -#if __FreeBSD_version > 700000 - INTR_TYPE_NET | INTR_MPSAFE, NULL, em_msix_link, adapter, -#else /* 6.X */ - INTR_TYPE_NET | INTR_MPSAFE, em_msix_link, adapter, -#endif - &adapter->tag[2])) != 0) { - device_printf(dev, "Failed to register TX handler"); - return (error); - } - return (0); } @@ -2987,36 +2414,56 @@ em_allocate_msix(struct adapter *adapter) static void em_free_pci_resources(struct adapter *adapter) { - device_t dev = adapter->dev; + device_t dev = adapter->dev; + struct tx_ring *txr; + struct rx_ring *rxr; + int rid; - /* Make sure the for loop below runs once */ - if (adapter->msi == 0) - adapter->msi = 1; /* - * First release all the interrupt resources: - * notice that since these are just kept - * in an array we can do the same logic - * whether its MSIX or just legacy. - */ - for (int i = 0; i < adapter->msi; i++) { - if (adapter->tag[i] != NULL) { - bus_teardown_intr(dev, adapter->res[i], - adapter->tag[i]); - adapter->tag[i] = NULL; + ** Release all the queue interrupt resources: + */ + for (int i = 0; i < adapter->num_queues; i++) { + txr = &adapter->tx_rings[i]; + rxr = &adapter->rx_rings[i]; + rid = txr->msix +1; + if (txr->tag != NULL) { + bus_teardown_intr(dev, txr->res, txr->tag); + txr->tag = NULL; } - if (adapter->res[i] != NULL) { + if (txr->res != NULL) bus_release_resource(dev, SYS_RES_IRQ, - adapter->rid[i], adapter->res[i]); + rid, txr->res); + rid = rxr->msix +1; + if (rxr->tag != NULL) { + bus_teardown_intr(dev, rxr->res, rxr->tag); + rxr->tag = NULL; } + if (rxr->res != NULL) + bus_release_resource(dev, SYS_RES_IRQ, + rid, rxr->res); } - if (adapter->msi) + if (adapter->linkvec) /* we are doing MSIX */ + rid = adapter->linkvec + 1; + else + (adapter->msix != 0) ? (rid = 1):(rid = 0); + + if (adapter->tag != NULL) { + bus_teardown_intr(dev, adapter->res, adapter->tag); + adapter->tag = NULL; + } + + if (adapter->res != NULL) + bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res); + + + if (adapter->msix) pci_release_msi(dev); - if (adapter->msix != NULL) + if (adapter->msix_mem != NULL) bus_release_resource(dev, SYS_RES_MEMORY, - PCIR_BAR(EM_MSIX_BAR), adapter->msix); + PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem); if (adapter->memory != NULL) bus_release_resource(dev, SYS_RES_MEMORY, @@ -3025,10 +2472,6 @@ em_free_pci_resources(struct adapter *adapter) if (adapter->flash != NULL) bus_release_resource(dev, SYS_RES_MEMORY, EM_FLASH, adapter->flash); - - if (adapter->ioport != NULL) - bus_release_resource(dev, SYS_RES_IOPORT, - adapter->io_rid, adapter->ioport); } /* @@ -3040,82 +2483,81 @@ em_setup_msix(struct adapter *adapter) device_t dev = adapter->dev; int val = 0; - if (adapter->hw.mac.type < e1000_82571) - return (0); /* Setup MSI/X for Hartwell */ - if (adapter->hw.mac.type == e1000_82574) { + if ((adapter->hw.mac.type == e1000_82574) && + (em_enable_msix == TRUE)) { /* Map the MSIX BAR */ int rid = PCIR_BAR(EM_MSIX_BAR); - adapter->msix = bus_alloc_resource_any(dev, + adapter->msix_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (!adapter->msix) { + if (!adapter->msix_mem) { /* May not be enabled */ device_printf(adapter->dev, "Unable to map MSIX table \n"); goto msi; } val = pci_msix_count(dev); - /* - ** 82574 can be configured for 5 but - ** we limit use to 3. - */ - if (val > 3) val = 3; - if ((val) && pci_alloc_msix(dev, &val) == 0) { - device_printf(adapter->dev,"Using MSIX interrupts\n"); - return (val); + if (val != 5) { + bus_release_resource(dev, SYS_RES_MEMORY, + PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem); + adapter->msix_mem = NULL; + device_printf(adapter->dev, + "MSIX vectors wrong, using MSI \n"); + goto msi; } + if (em_msix_queues == 2) { + val = 5; + adapter->num_queues = 2; + } else { + val = 3; + adapter->num_queues = 1; + } + if (pci_alloc_msix(dev, &val) == 0) { + device_printf(adapter->dev, + "Using MSIX interrupts " + "with %d vectors\n", val); + } + + return (val); } msi: val = pci_msi_count(dev); if (val == 1 && pci_alloc_msi(dev, &val) == 0) { - adapter->msi = 1; + adapter->msix = 1; device_printf(adapter->dev,"Using MSI interrupt\n"); return (val); } + /* Should only happen due to manual invention */ + device_printf(adapter->dev,"Setup MSIX failure\n"); return (0); } + /********************************************************************* * * Initialize the hardware to a configuration * as specified by the adapter structure. * **********************************************************************/ -static int -em_hardware_init(struct adapter *adapter) +static void +em_reset(struct adapter *adapter) { - device_t dev = adapter->dev; - u16 rx_buffer_size; + device_t dev = adapter->dev; + struct e1000_hw *hw = &adapter->hw; + u16 rx_buffer_size; - INIT_DEBUGOUT("em_hardware_init: begin"); - - /* Issue a global reset */ - e1000_reset_hw(&adapter->hw); - - /* Get control from any management/hw control */ - if (((adapter->hw.mac.type == e1000_82573) || - (adapter->hw.mac.type == e1000_82583) || - (adapter->hw.mac.type == e1000_ich8lan) || - (adapter->hw.mac.type == e1000_ich10lan) || - (adapter->hw.mac.type == e1000_ich9lan)) && - e1000_check_mng_mode(&adapter->hw)) - em_get_hw_control(adapter); - - /* When hardware is reset, fifo_head is also reset */ - adapter->tx_fifo_head = 0; + INIT_DEBUGOUT("em_reset: begin"); /* Set up smart power down as default off on newer adapters. */ - if (!em_smart_pwr_down && (adapter->hw.mac.type == e1000_82571 || - adapter->hw.mac.type == e1000_82572)) { + if (!em_smart_pwr_down && (hw->mac.type == e1000_82571 || + hw->mac.type == e1000_82572)) { u16 phy_tmp = 0; /* Speed up time to link by disabling smart power down. */ - e1000_read_phy_reg(&adapter->hw, - IGP02E1000_PHY_POWER_MGMT, &phy_tmp); + e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_tmp); phy_tmp &= ~IGP02E1000_PM_SPD; - e1000_write_phy_reg(&adapter->hw, - IGP02E1000_PHY_POWER_MGMT, phy_tmp); + e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_tmp); } /* @@ -3132,34 +2574,42 @@ em_hardware_init(struct adapter *adapter) * by 1500. * - The pause time is fairly large at 1000 x 512ns = 512 usec. */ - rx_buffer_size = ((E1000_READ_REG(&adapter->hw, E1000_PBA) & - 0xffff) << 10 ); + rx_buffer_size = ((E1000_READ_REG(hw, E1000_PBA) & 0xffff) << 10 ); - adapter->hw.fc.high_water = rx_buffer_size - + hw->fc.high_water = rx_buffer_size - roundup2(adapter->max_frame_size, 1024); - adapter->hw.fc.low_water = adapter->hw.fc.high_water - 1500; + hw->fc.low_water = hw->fc.high_water - 1500; - if (adapter->hw.mac.type == e1000_80003es2lan) - adapter->hw.fc.pause_time = 0xFFFF; + if (hw->mac.type == e1000_80003es2lan) + hw->fc.pause_time = 0xFFFF; else - adapter->hw.fc.pause_time = EM_FC_PAUSE_TIME; - adapter->hw.fc.send_xon = TRUE; + hw->fc.pause_time = EM_FC_PAUSE_TIME; + + hw->fc.send_xon = TRUE; /* Set Flow control, use the tunable location if sane */ if ((em_fc_setting >= 0) || (em_fc_setting < 4)) - adapter->hw.fc.requested_mode = em_fc_setting; - else - adapter->hw.fc.requested_mode = e1000_fc_none; + hw->fc.requested_mode = em_fc_setting; + else + hw->fc.requested_mode = e1000_fc_none; + /* Override - workaround for PCHLAN issue */ + if (hw->mac.type == e1000_pchlan) + hw->fc.requested_mode = e1000_fc_rx_pause; - if (e1000_init_hw(&adapter->hw) < 0) { + /* Issue a global reset */ + e1000_reset_hw(hw); + E1000_WRITE_REG(hw, E1000_WUC, 0); + + if (e1000_init_hw(hw) < 0) { device_printf(dev, "Hardware Initialization Failed\n"); - return (EIO); + return; } - e1000_check_for_link(&adapter->hw); - - return (0); + E1000_WRITE_REG(hw, E1000_VET, ETHERTYPE_VLAN); + e1000_get_phy_info(hw); + e1000_check_for_link(hw); + return; } /********************************************************************* @@ -3196,31 +2646,14 @@ em_setup_interface(device_t dev, struct adapter *adapter) /* Multiqueue tx functions */ ifp->if_transmit = em_mq_start; ifp->if_qflush = em_qflush; - adapter->br = buf_ring_alloc(4096, M_DEVBUF, M_WAITOK, &adapter->tx_mtx); #endif - if (adapter->hw.mac.type >= e1000_82543) { - int version_cap; -#if __FreeBSD_version < 700000 - version_cap = IFCAP_HWCSUM; -#else - version_cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; -#endif - ifp->if_capabilities |= version_cap; - ifp->if_capenable |= version_cap; - } -#if __FreeBSD_version >= 700000 - /* Identify TSO capable adapters */ - if ((adapter->hw.mac.type > e1000_82544) && - (adapter->hw.mac.type != e1000_82547)) - ifp->if_capabilities |= IFCAP_TSO4; - /* - * By default only enable on PCI-E, this - * can be overriden by ifconfig. - */ - if (adapter->hw.mac.type >= e1000_82571) - ifp->if_capenable |= IFCAP_TSO4; -#endif + ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; + ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; + + /* Enable TSO by default, can disable with ifconfig */ + ifp->if_capabilities |= IFCAP_TSO4; + ifp->if_capenable |= IFCAP_TSO4; /* * Tell the upper layer(s) we support long frames. @@ -3233,6 +2666,12 @@ em_setup_interface(device_t dev, struct adapter *adapter) ifp->if_capabilities |= IFCAP_POLLING; #endif + /* Enable All WOL methods by default */ + if (adapter->wol) { + ifp->if_capabilities |= IFCAP_WOL; + ifp->if_capenable |= IFCAP_WOL; + } + /* * Specify the media types supported by this adapter and register * callbacks to update media and link information @@ -3243,8 +2682,6 @@ em_setup_interface(device_t dev, struct adapter *adapter) (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) { u_char fiber_type = IFM_1000_SX; /* default type */ - if (adapter->hw.mac.type == e1000_82545) - fiber_type = IFM_1000_LX; ifmedia_add(&adapter->media, IFM_ETHER | fiber_type | IFM_FDX, 0, NULL); ifmedia_add(&adapter->media, IFM_ETHER | fiber_type, 0, NULL); @@ -3268,67 +2705,6 @@ em_setup_interface(device_t dev, struct adapter *adapter) } -/********************************************************************* - * - * Workaround for SmartSpeed on 82541 and 82547 controllers - * - **********************************************************************/ -static void -em_smartspeed(struct adapter *adapter) -{ - u16 phy_tmp; - - if (adapter->link_active || (adapter->hw.phy.type != e1000_phy_igp) || - adapter->hw.mac.autoneg == 0 || - (adapter->hw.phy.autoneg_advertised & ADVERTISE_1000_FULL) == 0) - return; - - if (adapter->smartspeed == 0) { - /* If Master/Slave config fault is asserted twice, - * we assume back-to-back */ - e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp); - if (!(phy_tmp & SR_1000T_MS_CONFIG_FAULT)) - return; - e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp); - if (phy_tmp & SR_1000T_MS_CONFIG_FAULT) { - e1000_read_phy_reg(&adapter->hw, - PHY_1000T_CTRL, &phy_tmp); - if(phy_tmp & CR_1000T_MS_ENABLE) { - phy_tmp &= ~CR_1000T_MS_ENABLE; - e1000_write_phy_reg(&adapter->hw, - PHY_1000T_CTRL, phy_tmp); - adapter->smartspeed++; - if(adapter->hw.mac.autoneg && - !e1000_phy_setup_autoneg(&adapter->hw) && - !e1000_read_phy_reg(&adapter->hw, - PHY_CONTROL, &phy_tmp)) { - phy_tmp |= (MII_CR_AUTO_NEG_EN | - MII_CR_RESTART_AUTO_NEG); - e1000_write_phy_reg(&adapter->hw, - PHY_CONTROL, phy_tmp); - } - } - } - return; - } else if(adapter->smartspeed == EM_SMARTSPEED_DOWNSHIFT) { - /* If still no link, perhaps using 2/3 pair cable */ - e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_tmp); - phy_tmp |= CR_1000T_MS_ENABLE; - e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_tmp); - if(adapter->hw.mac.autoneg && - !e1000_phy_setup_autoneg(&adapter->hw) && - !e1000_read_phy_reg(&adapter->hw, PHY_CONTROL, &phy_tmp)) { - phy_tmp |= (MII_CR_AUTO_NEG_EN | - MII_CR_RESTART_AUTO_NEG); - e1000_write_phy_reg(&adapter->hw, PHY_CONTROL, phy_tmp); - } - } - /* Restart process after EM_SMARTSPEED_MAX iterations */ - if(adapter->smartspeed++ == EM_SMARTSPEED_MAX) - adapter->smartspeed = 0; -} - - /* * Manage DMA'able memory. */ @@ -3346,11 +2722,7 @@ em_dma_malloc(struct adapter *adapter, bus_size_t size, { int error; -#if __FreeBSD_version >= 700000 error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */ -#else - error = bus_dma_tag_create(NULL, /* parent */ -#endif EM_DBA_ALIGN, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -3421,97 +2793,243 @@ em_dma_free(struct adapter *adapter, struct em_dma_alloc *dma) /********************************************************************* * - * Allocate memory for tx_buffer structures. The tx_buffer stores all - * the information needed to transmit a packet on the wire. + * Allocate memory for the transmit and receive rings, and then + * the descriptors associated with each, called only once at attach. * **********************************************************************/ static int -em_allocate_transmit_structures(struct adapter *adapter) +em_allocate_queues(struct adapter *adapter) { - device_t dev = adapter->dev; - struct em_buffer *tx_buffer; - int error; + device_t dev = adapter->dev; + struct tx_ring *txr = NULL; + struct rx_ring *rxr = NULL; + int rsize, tsize, error = E1000_SUCCESS; + int txconf = 0, rxconf = 0; - /* - * Create DMA tags for tx descriptors - */ -#if __FreeBSD_version >= 700000 - if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ -#else - if ((error = bus_dma_tag_create(NULL, /* parent */ -#endif - 1, 0, /* alignment, bounds */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - EM_TSO_SIZE, /* maxsize */ - EM_MAX_SCATTER, /* nsegments */ - EM_TSO_SEG_SIZE, /* maxsegsize */ - 0, /* flags */ - NULL, /* lockfunc */ - NULL, /* lockarg */ - &adapter->txtag)) != 0) { - device_printf(dev, "Unable to allocate TX DMA tag\n"); + + /* Allocate the TX ring struct memory */ + if (!(adapter->tx_rings = + (struct tx_ring *) malloc(sizeof(struct tx_ring) * + adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { + device_printf(dev, "Unable to allocate TX ring memory\n"); + error = ENOMEM; goto fail; } - adapter->tx_buffer_area = malloc(sizeof(struct em_buffer) * - adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO); - if (adapter->tx_buffer_area == NULL) { + /* Now allocate the RX */ + if (!(adapter->rx_rings = + (struct rx_ring *) malloc(sizeof(struct rx_ring) * + adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { + device_printf(dev, "Unable to allocate RX ring memory\n"); + error = ENOMEM; + goto rx_fail; + } + + tsize = roundup2(adapter->num_tx_desc * + sizeof(struct e1000_tx_desc), EM_DBA_ALIGN); + /* + * Now set up the TX queues, txconf is needed to handle the + * possibility that things fail midcourse and we need to + * undo memory gracefully + */ + for (int i = 0; i < adapter->num_queues; i++, txconf++) { + /* Set up some basics */ + txr = &adapter->tx_rings[i]; + txr->adapter = adapter; + txr->me = i; + + /* Initialize the TX lock */ + snprintf(txr->mtx_name, sizeof(txr->mtx_name), "%s:tx(%d)", + device_get_nameunit(dev), txr->me); + mtx_init(&txr->tx_mtx, txr->mtx_name, NULL, MTX_DEF); + + if (em_dma_malloc(adapter, tsize, + &txr->txdma, BUS_DMA_NOWAIT)) { + device_printf(dev, + "Unable to allocate TX Descriptor memory\n"); + error = ENOMEM; + goto err_tx_desc; + } + txr->tx_base = (struct e1000_tx_desc *)txr->txdma.dma_vaddr; + bzero((void *)txr->tx_base, tsize); + + if (em_allocate_transmit_buffers(txr)) { + device_printf(dev, + "Critical Failure setting up transmit buffers\n"); + error = ENOMEM; + goto err_tx_desc; + } +#if __FreeBSD_version >= 800000 + /* Allocate a buf ring */ + txr->br = buf_ring_alloc(4096, M_DEVBUF, + M_WAITOK, &txr->tx_mtx); +#endif + } + + /* + * Next the RX queues... + */ + rsize = roundup2(adapter->num_rx_desc * + sizeof(struct e1000_rx_desc), EM_DBA_ALIGN); + for (int i = 0; i < adapter->num_queues; i++, rxconf++) { + rxr = &adapter->rx_rings[i]; + rxr->adapter = adapter; + rxr->me = i; + + /* Initialize the RX lock */ + snprintf(rxr->mtx_name, sizeof(rxr->mtx_name), "%s:rx(%d)", + device_get_nameunit(dev), txr->me); + mtx_init(&rxr->rx_mtx, rxr->mtx_name, NULL, MTX_DEF); + + if (em_dma_malloc(adapter, rsize, + &rxr->rxdma, BUS_DMA_NOWAIT)) { + device_printf(dev, + "Unable to allocate RxDescriptor memory\n"); + error = ENOMEM; + goto err_rx_desc; + } + rxr->rx_base = (struct e1000_rx_desc *)rxr->rxdma.dma_vaddr; + bzero((void *)rxr->rx_base, rsize); + + /* Allocate receive buffers for the ring*/ + if (em_allocate_receive_buffers(rxr)) { + device_printf(dev, + "Critical Failure setting up receive buffers\n"); + error = ENOMEM; + goto err_rx_desc; + } + } + + return (0); + +err_rx_desc: + for (rxr = adapter->rx_rings; rxconf > 0; rxr++, rxconf--) + em_dma_free(adapter, &rxr->rxdma); +err_tx_desc: + for (txr = adapter->tx_rings; txconf > 0; txr++, txconf--) + em_dma_free(adapter, &txr->txdma); + free(adapter->rx_rings, M_DEVBUF); +rx_fail: + buf_ring_free(txr->br, M_DEVBUF); + free(adapter->tx_rings, M_DEVBUF); +fail: + return (error); +} + + +/********************************************************************* + * + * Allocate memory for tx_buffer structures. The tx_buffer stores all + * the information needed to transmit a packet on the wire. This is + * called only once at attach, setup is done every reset. + * + **********************************************************************/ +static int +em_allocate_transmit_buffers(struct tx_ring *txr) +{ + struct adapter *adapter = txr->adapter; + device_t dev = adapter->dev; + struct em_buffer *txbuf; + int error, i; + + /* + * Setup DMA descriptor areas. + */ + if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), + 1, 0, /* alignment, bounds */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + EM_TSO_SIZE, /* maxsize */ + EM_MAX_SCATTER, /* nsegments */ + PAGE_SIZE, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockfuncarg */ + &txr->txtag))) { + device_printf(dev,"Unable to allocate TX DMA tag\n"); + goto fail; + } + + if (!(txr->tx_buffers = + (struct em_buffer *) malloc(sizeof(struct em_buffer) * + adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO))) { device_printf(dev, "Unable to allocate tx_buffer memory\n"); error = ENOMEM; goto fail; } - /* Create the descriptor buffer dma maps */ - for (int i = 0; i < adapter->num_tx_desc; i++) { - tx_buffer = &adapter->tx_buffer_area[i]; - error = bus_dmamap_create(adapter->txtag, 0, &tx_buffer->map); + /* Create the descriptor buffer dma maps */ + txbuf = txr->tx_buffers; + for (i = 0; i < adapter->num_tx_desc; i++, txbuf++) { + error = bus_dmamap_create(txr->txtag, 0, &txbuf->map); if (error != 0) { device_printf(dev, "Unable to create TX DMA map\n"); goto fail; } - tx_buffer->next_eop = -1; } - return (0); + return 0; fail: + /* We free all, it handles case where we are in the middle */ em_free_transmit_structures(adapter); return (error); } /********************************************************************* * - * (Re)Initialize transmit structures. + * Initialize a transmit ring. + * + **********************************************************************/ +static void +em_setup_transmit_ring(struct tx_ring *txr) +{ + struct adapter *adapter = txr->adapter; + struct em_buffer *txbuf; + int i; + + /* Clear the old descriptor contents */ + EM_TX_LOCK(txr); + bzero((void *)txr->tx_base, + (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc); + /* Reset indices */ + txr->next_avail_desc = 0; + txr->next_to_clean = 0; + + /* Free any existing tx buffers. */ + txbuf = txr->tx_buffers; + for (i = 0; i < adapter->num_tx_desc; i++, txbuf++) { + if (txbuf->m_head != NULL) { + bus_dmamap_sync(txr->txtag, txbuf->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(txr->txtag, txbuf->map); + m_freem(txbuf->m_head); + txbuf->m_head = NULL; + } + /* clear the watch index */ + txbuf->next_eop = -1; + } + + /* Set number of descriptors available */ + txr->tx_avail = adapter->num_tx_desc; + + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + EM_TX_UNLOCK(txr); +} + +/********************************************************************* + * + * Initialize all transmit rings. * **********************************************************************/ static void em_setup_transmit_structures(struct adapter *adapter) { - struct em_buffer *tx_buffer; + struct tx_ring *txr = adapter->tx_rings; - /* Clear the old ring contents */ - bzero(adapter->tx_desc_base, - (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc); - - /* Free any existing TX buffers */ - for (int i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) { - tx_buffer = &adapter->tx_buffer_area[i]; - bus_dmamap_sync(adapter->txtag, tx_buffer->map, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(adapter->txtag, tx_buffer->map); - m_freem(tx_buffer->m_head); - tx_buffer->m_head = NULL; - tx_buffer->next_eop = -1; - } - - /* Reset state */ - adapter->next_avail_tx_desc = 0; - adapter->next_tx_to_clean = 0; - adapter->num_tx_desc_avail = adapter->num_tx_desc; - - bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + for (int i = 0; i < adapter->num_queues; i++, txr++) + em_setup_transmit_ring(txr); return; } @@ -3524,25 +3042,31 @@ em_setup_transmit_structures(struct adapter *adapter) static void em_initialize_transmit_unit(struct adapter *adapter) { + struct tx_ring *txr = adapter->tx_rings; + struct e1000_hw *hw = &adapter->hw; u32 tctl, tarc, tipg = 0; - u64 bus_addr; INIT_DEBUGOUT("em_initialize_transmit_unit: begin"); - /* Setup the Base and Length of the Tx Descriptor Ring */ - bus_addr = adapter->txdma.dma_paddr; - E1000_WRITE_REG(&adapter->hw, E1000_TDLEN(0), - adapter->num_tx_desc * sizeof(struct e1000_tx_desc)); - E1000_WRITE_REG(&adapter->hw, E1000_TDBAH(0), - (u32)(bus_addr >> 32)); - E1000_WRITE_REG(&adapter->hw, E1000_TDBAL(0), - (u32)bus_addr); - /* Setup the HW Tx Head and Tail descriptor pointers */ - E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), 0); - E1000_WRITE_REG(&adapter->hw, E1000_TDH(0), 0); - HW_DEBUGOUT2("Base = %x, Length = %x\n", - E1000_READ_REG(&adapter->hw, E1000_TDBAL(0)), - E1000_READ_REG(&adapter->hw, E1000_TDLEN(0))); + for (int i = 0; i < adapter->num_queues; i++, txr++) { + u64 bus_addr = txr->txdma.dma_paddr; + /* Base and Len of TX Ring */ + E1000_WRITE_REG(hw, E1000_TDLEN(i), + adapter->num_tx_desc * sizeof(struct e1000_tx_desc)); + E1000_WRITE_REG(hw, E1000_TDBAH(i), + (u32)(bus_addr >> 32)); + E1000_WRITE_REG(hw, E1000_TDBAL(i), + (u32)bus_addr); + /* Init the HEAD/TAIL indices */ + E1000_WRITE_REG(hw, E1000_TDT(i), 0); + E1000_WRITE_REG(hw, E1000_TDH(i), 0); + + HW_DEBUGOUT2("Base = %x, Length = %x\n", + E1000_READ_REG(&adapter->hw, E1000_TDBAL(i)), + E1000_READ_REG(&adapter->hw, E1000_TDLEN(i))); + + txr->watchdog_check = FALSE; + } /* Set the default values for the Tx Inter Packet Gap timer */ switch (adapter->hw.mac.type) { @@ -3569,6 +3093,7 @@ em_initialize_transmit_unit(struct adapter *adapter) E1000_WRITE_REG(&adapter->hw, E1000_TIPG, tipg); E1000_WRITE_REG(&adapter->hw, E1000_TIDV, adapter->tx_int_delay.value); + if(adapter->hw.mac.type >= e1000_82540) E1000_WRITE_REG(&adapter->hw, E1000_TADV, adapter->tx_abs_int_delay.value); @@ -3587,6 +3112,10 @@ em_initialize_transmit_unit(struct adapter *adapter) E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc); } + adapter->txd_cmd = E1000_TXD_CMD_IFCS; + if (adapter->tx_int_delay.value > 0) + adapter->txd_cmd |= E1000_TXD_CMD_IDE; + /* Program the Transmit Control Register */ tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL); tctl &= ~E1000_TCTL_CT; @@ -3599,59 +3128,84 @@ em_initialize_transmit_unit(struct adapter *adapter) /* This write will effectively turn on the transmit unit. */ E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl); - /* Setup Transmit Descriptor Base Settings */ - adapter->txd_cmd = E1000_TXD_CMD_IFCS; - - if (adapter->tx_int_delay.value > 0) - adapter->txd_cmd |= E1000_TXD_CMD_IDE; } + /********************************************************************* * - * Free all transmit related data structures. + * Free all transmit rings. * **********************************************************************/ static void em_free_transmit_structures(struct adapter *adapter) { - struct em_buffer *tx_buffer; + struct tx_ring *txr = adapter->tx_rings; - INIT_DEBUGOUT("free_transmit_structures: begin"); + for (int i = 0; i < adapter->num_queues; i++, txr++) { + EM_TX_LOCK(txr); + em_free_transmit_buffers(txr); + em_dma_free(adapter, &txr->txdma); + EM_TX_UNLOCK(txr); + EM_TX_LOCK_DESTROY(txr); + } - if (adapter->tx_buffer_area != NULL) { - for (int i = 0; i < adapter->num_tx_desc; i++) { - tx_buffer = &adapter->tx_buffer_area[i]; - if (tx_buffer->m_head != NULL) { - bus_dmamap_sync(adapter->txtag, tx_buffer->map, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(adapter->txtag, - tx_buffer->map); - m_freem(tx_buffer->m_head); - tx_buffer->m_head = NULL; - } else if (tx_buffer->map != NULL) - bus_dmamap_unload(adapter->txtag, - tx_buffer->map); - if (tx_buffer->map != NULL) { - bus_dmamap_destroy(adapter->txtag, - tx_buffer->map); - tx_buffer->map = NULL; + free(adapter->tx_rings, M_DEVBUF); +} + +/********************************************************************* + * + * Free transmit ring related data structures. + * + **********************************************************************/ +static void +em_free_transmit_buffers(struct tx_ring *txr) +{ + struct adapter *adapter = txr->adapter; + struct em_buffer *txbuf; + + INIT_DEBUGOUT("free_transmit_ring: begin"); + + if (txr->tx_buffers == NULL) + return; + + for (int i = 0; i < adapter->num_tx_desc; i++) { + txbuf = &txr->tx_buffers[i]; + if (txbuf->m_head != NULL) { + bus_dmamap_sync(txr->txtag, txbuf->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(txr->txtag, + txbuf->map); + m_freem(txbuf->m_head); + txbuf->m_head = NULL; + if (txbuf->map != NULL) { + bus_dmamap_destroy(txr->txtag, + txbuf->map); + txbuf->map = NULL; } + } else if (txbuf->map != NULL) { + bus_dmamap_unload(txr->txtag, + txbuf->map); + bus_dmamap_destroy(txr->txtag, + txbuf->map); + txbuf->map = NULL; } } - if (adapter->tx_buffer_area != NULL) { - free(adapter->tx_buffer_area, M_DEVBUF); - adapter->tx_buffer_area = NULL; - } - if (adapter->txtag != NULL) { - bus_dma_tag_destroy(adapter->txtag); - adapter->txtag = NULL; - } #if __FreeBSD_version >= 800000 - if (adapter->br != NULL) - buf_ring_free(adapter->br, M_DEVBUF); + if (txr->br != NULL) + buf_ring_free(txr->br, M_DEVBUF); #endif + if (txr->tx_buffers != NULL) { + free(txr->tx_buffers, M_DEVBUF); + txr->tx_buffers = NULL; + } + if (txr->txtag != NULL) { + bus_dma_tag_destroy(txr->txtag); + txr->txtag = NULL; + } + return; } + /********************************************************************* * * The offload context needs to be set when we transfer the first @@ -3663,22 +3217,23 @@ em_free_transmit_structures(struct adapter *adapter) * big performance win. -jfv **********************************************************************/ static void -em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp, +em_transmit_checksum_setup(struct tx_ring *txr, struct mbuf *mp, u32 *txd_upper, u32 *txd_lower) { - struct e1000_context_desc *TXD = NULL; + struct adapter *adapter = txr->adapter; + struct e1000_context_desc *TXD = NULL; struct em_buffer *tx_buffer; struct ether_vlan_header *eh; struct ip *ip = NULL; struct ip6_hdr *ip6; - int curr_txd, ehdrlen; + int cur, ehdrlen; u32 cmd, hdr_len, ip_hlen; u16 etype; u8 ipproto; cmd = hdr_len = ipproto = 0; - curr_txd = adapter->next_avail_tx_desc; + cur = txr->next_avail_desc; /* * Determine where frame payload starts. @@ -3711,7 +3266,7 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp, * Offset of place to put the checksum. */ TXD = (struct e1000_context_desc *) - &adapter->tx_desc_base[curr_txd]; + &txr->tx_base[cur]; TXD->lower_setup.ip_fields.ipcss = ehdrlen; TXD->lower_setup.ip_fields.ipcse = htole16(ehdrlen + ip_hlen); @@ -3753,16 +3308,16 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp, *txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D; *txd_upper |= E1000_TXD_POPTS_TXSM << 8; /* no need for context if already set */ - if (adapter->last_hw_offload == CSUM_TCP) + if (txr->last_hw_offload == CSUM_TCP) return; - adapter->last_hw_offload = CSUM_TCP; + txr->last_hw_offload = CSUM_TCP; /* * Start offset for payload checksum calculation. * End offset for payload checksum calculation. * Offset of place to put the checksum. */ TXD = (struct e1000_context_desc *) - &adapter->tx_desc_base[curr_txd]; + &txr->tx_base[cur]; TXD->upper_setup.tcp_fields.tucss = hdr_len; TXD->upper_setup.tcp_fields.tucse = htole16(0); TXD->upper_setup.tcp_fields.tucso = @@ -3776,16 +3331,16 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp, *txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D; *txd_upper |= E1000_TXD_POPTS_TXSM << 8; /* no need for context if already set */ - if (adapter->last_hw_offload == CSUM_UDP) + if (txr->last_hw_offload == CSUM_UDP) return; - adapter->last_hw_offload = CSUM_UDP; + txr->last_hw_offload = CSUM_UDP; /* * Start offset for header checksum calculation. * End offset for header checksum calculation. * Offset of place to put the checksum. */ TXD = (struct e1000_context_desc *) - &adapter->tx_desc_base[curr_txd]; + &txr->tx_base[cur]; TXD->upper_setup.tcp_fields.tucss = hdr_len; TXD->upper_setup.tcp_fields.tucse = htole16(0); TXD->upper_setup.tcp_fields.tucso = @@ -3800,35 +3355,35 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp, TXD->tcp_seg_setup.data = htole32(0); TXD->cmd_and_length = htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | cmd); - tx_buffer = &adapter->tx_buffer_area[curr_txd]; + tx_buffer = &txr->tx_buffers[cur]; tx_buffer->m_head = NULL; tx_buffer->next_eop = -1; - if (++curr_txd == adapter->num_tx_desc) - curr_txd = 0; + if (++cur == adapter->num_tx_desc) + cur = 0; - adapter->num_tx_desc_avail--; - adapter->next_avail_tx_desc = curr_txd; + txr->tx_avail--; + txr->next_avail_desc = cur; } -#if __FreeBSD_version >= 700000 /********************************************************************** * * Setup work for hardware segmentation offload (TSO) * **********************************************************************/ static bool -em_tso_setup(struct adapter *adapter, struct mbuf *mp, u32 *txd_upper, +em_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *txd_upper, u32 *txd_lower) { - struct e1000_context_desc *TXD; - struct em_buffer *tx_buffer; - struct ether_vlan_header *eh; - struct ip *ip; - struct ip6_hdr *ip6; - struct tcphdr *th; - int curr_txd, ehdrlen, hdr_len, ip_hlen, isip6; + struct adapter *adapter = txr->adapter; + struct e1000_context_desc *TXD; + struct em_buffer *tx_buffer; + struct ether_vlan_header *eh; + struct ip *ip; + struct ip6_hdr *ip6; + struct tcphdr *th; + int cur, ehdrlen, hdr_len, ip_hlen, isip6; u16 etype; /* @@ -3908,9 +3463,9 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp, u32 *txd_upper, *txd_upper = ((isip6 ? 0 : E1000_TXD_POPTS_IXSM) | E1000_TXD_POPTS_TXSM) << 8; - curr_txd = adapter->next_avail_tx_desc; - tx_buffer = &adapter->tx_buffer_area[curr_txd]; - TXD = (struct e1000_context_desc *) &adapter->tx_desc_base[curr_txd]; + cur = txr->next_avail_desc; + tx_buffer = &txr->tx_buffers[cur]; + TXD = (struct e1000_context_desc *) &txr->tx_base[cur]; /* IPv6 doesn't have a header checksum. */ if (!isip6) { @@ -3945,24 +3500,23 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp, u32 *txd_upper, TXD->cmd_and_length = htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | /* Extended descr */ E1000_TXD_CMD_TSE | /* TSE context */ - (isip6 ? 0 : E1000_TXD_CMD_IP) | /* Do IP csum */ + (isip6 ? 0 : E1000_TXD_CMD_IP) | E1000_TXD_CMD_TCP | /* Do TCP checksum */ (mp->m_pkthdr.len - (hdr_len))); /* Total len */ tx_buffer->m_head = NULL; tx_buffer->next_eop = -1; - if (++curr_txd == adapter->num_tx_desc) - curr_txd = 0; + if (++cur == adapter->num_tx_desc) + cur = 0; - adapter->num_tx_desc_avail--; - adapter->next_avail_tx_desc = curr_txd; - adapter->tx_tso = TRUE; + txr->tx_avail--; + txr->next_avail_desc = cur; + txr->tx_tso = TRUE; return TRUE; } -#endif /* __FreeBSD_version >= 700000 */ /********************************************************************** * @@ -3971,26 +3525,26 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp, u32 *txd_upper, * tx_buffer is put back on the free queue. * **********************************************************************/ -static void -em_txeof(struct adapter *adapter) +static bool +em_txeof(struct tx_ring *txr) { + struct adapter *adapter = txr->adapter; int first, last, done, num_avail; - u32 cleaned = 0; struct em_buffer *tx_buffer; struct e1000_tx_desc *tx_desc, *eop_desc; struct ifnet *ifp = adapter->ifp; - EM_TX_LOCK_ASSERT(adapter); + EM_TX_LOCK_ASSERT(txr); - if (adapter->num_tx_desc_avail == adapter->num_tx_desc) - return; + if (txr->tx_avail == adapter->num_tx_desc) + return (FALSE); - num_avail = adapter->num_tx_desc_avail; - first = adapter->next_tx_to_clean; - tx_desc = &adapter->tx_desc_base[first]; - tx_buffer = &adapter->tx_buffer_area[first]; + num_avail = txr->tx_avail; + first = txr->next_to_clean; + tx_desc = &txr->tx_base[first]; + tx_buffer = &txr->tx_buffers[first]; last = tx_buffer->next_eop; - eop_desc = &adapter->tx_desc_base[last]; + eop_desc = &txr->tx_base[last]; /* * What this does is get the index of the @@ -4002,7 +3556,7 @@ em_txeof(struct adapter *adapter) last = 0; done = last; - bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_POSTREAD); while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) { @@ -4011,137 +3565,130 @@ em_txeof(struct adapter *adapter) tx_desc->upper.data = 0; tx_desc->lower.data = 0; tx_desc->buffer_addr = 0; - ++num_avail; ++cleaned; + ++num_avail; if (tx_buffer->m_head) { ifp->if_opackets++; - bus_dmamap_sync(adapter->txtag, + bus_dmamap_sync(txr->txtag, tx_buffer->map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(adapter->txtag, + bus_dmamap_unload(txr->txtag, tx_buffer->map); m_freem(tx_buffer->m_head); tx_buffer->m_head = NULL; } tx_buffer->next_eop = -1; + txr->watchdog_time = ticks; if (++first == adapter->num_tx_desc) first = 0; - tx_buffer = &adapter->tx_buffer_area[first]; - tx_desc = &adapter->tx_desc_base[first]; + tx_buffer = &txr->tx_buffers[first]; + tx_desc = &txr->tx_base[first]; } /* See if we can continue to the next packet */ last = tx_buffer->next_eop; if (last != -1) { - eop_desc = &adapter->tx_desc_base[last]; + eop_desc = &txr->tx_base[last]; /* Get new done point */ if (++last == adapter->num_tx_desc) last = 0; done = last; } else break; } - bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - adapter->next_tx_to_clean = first; + txr->next_to_clean = first; /* * If we have enough room, clear IFF_DRV_OACTIVE to * tell the stack that it is OK to send packets. - * If there are no pending descriptors, clear the timeout. + * If there are no pending descriptors, clear the watchdog. */ if (num_avail > EM_TX_CLEANUP_THRESHOLD) { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; if (num_avail == adapter->num_tx_desc) { - adapter->watchdog_timer = 0; - adapter->num_tx_desc_avail = num_avail; - return; + txr->watchdog_check = FALSE; + txr->tx_avail = num_avail; + return (FALSE); } } - /* If any descriptors cleaned, reset the watchdog */ - if (cleaned) - adapter->watchdog_timer = EM_TX_TIMEOUT; - adapter->num_tx_desc_avail = num_avail; - return; + txr->tx_avail = num_avail; + return (TRUE); } + /********************************************************************* * - * When Link is lost sometimes there is work still in the TX ring - * which will result in a watchdog, rather than allow that do an - * attempted cleanup and then reinit here. Note that this has been - * seens mostly with fiber adapters. + * Refresh RX descriptor mbufs from system mbuf buffer pool. * **********************************************************************/ static void -em_tx_purge(struct adapter *adapter) -{ - if ((!adapter->link_active) && (adapter->watchdog_timer)) { - EM_TX_LOCK(adapter); - em_txeof(adapter); - EM_TX_UNLOCK(adapter); - if (adapter->watchdog_timer) { /* Still not clean? */ - adapter->watchdog_timer = 0; - em_init_locked(adapter); - } - } -} - -/********************************************************************* - * - * Get a buffer from system mbuf buffer pool. - * - **********************************************************************/ -static int -em_get_buf(struct adapter *adapter, int i) +em_refresh_mbufs(struct rx_ring *rxr, int limit) { + struct adapter *adapter = rxr->adapter; struct mbuf *m; bus_dma_segment_t segs[1]; bus_dmamap_t map; - struct em_buffer *rx_buffer; - int error, nsegs; + struct em_buffer *rxbuf; + int i, error, nsegs, cleaned; - m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (m == NULL) { - adapter->mbuf_cluster_failed++; - return (ENOBUFS); + i = rxr->next_to_refresh; + cleaned = -1; + while (i != limit) { + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) + goto update; + m->m_len = m->m_pkthdr.len = MCLBYTES; + + if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN)) + m_adj(m, ETHER_ALIGN); + + /* + * Using memory from the mbuf cluster pool, invoke the + * bus_dma machinery to arrange the memory mapping. + */ + error = bus_dmamap_load_mbuf_sg(rxr->rxtag, rxr->rx_sparemap, + m, segs, &nsegs, BUS_DMA_NOWAIT); + if (error != 0) { + m_free(m); + goto update; + } + + /* If nsegs is wrong then the stack is corrupt. */ + KASSERT(nsegs == 1, ("Too many segments returned!")); + + rxbuf = &rxr->rx_buffers[i]; + if (rxbuf->m_head != NULL) + bus_dmamap_unload(rxr->rxtag, rxbuf->map); + + map = rxbuf->map; + rxbuf->map = rxr->rx_sparemap; + rxr->rx_sparemap = map; + bus_dmamap_sync(rxr->rxtag, + rxbuf->map, BUS_DMASYNC_PREREAD); + rxbuf->m_head = m; + rxr->rx_base[i].buffer_addr = htole64(segs[0].ds_addr); + + cleaned = i; + /* Calculate next index */ + if (++i == adapter->num_rx_desc) + i = 0; + /* This is the work marker for refresh */ + rxr->next_to_refresh = i; } - m->m_len = m->m_pkthdr.len = MCLBYTES; +update: + if (cleaned != -1) /* Update tail index */ + E1000_WRITE_REG(&adapter->hw, + E1000_RDT(rxr->me), cleaned); - if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN)) - m_adj(m, ETHER_ALIGN); - - /* - * Using memory from the mbuf cluster pool, invoke the - * bus_dma machinery to arrange the memory mapping. - */ - error = bus_dmamap_load_mbuf_sg(adapter->rxtag, - adapter->rx_sparemap, m, segs, &nsegs, BUS_DMA_NOWAIT); - if (error != 0) { - m_free(m); - return (error); - } - - /* If nsegs is wrong then the stack is corrupt. */ - KASSERT(nsegs == 1, ("Too many segments returned!")); - - rx_buffer = &adapter->rx_buffer_area[i]; - if (rx_buffer->m_head != NULL) - bus_dmamap_unload(adapter->rxtag, rx_buffer->map); - - map = rx_buffer->map; - rx_buffer->map = adapter->rx_sparemap; - adapter->rx_sparemap = map; - bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD); - rx_buffer->m_head = m; - - adapter->rx_desc_base[i].buffer_addr = htole64(segs[0].ds_addr); - return (0); + return; } + /********************************************************************* * * Allocate memory for rx_buffer structures. Since we use one @@ -4151,24 +3698,21 @@ em_get_buf(struct adapter *adapter, int i) * **********************************************************************/ static int -em_allocate_receive_structures(struct adapter *adapter) +em_allocate_receive_buffers(struct rx_ring *rxr) { - device_t dev = adapter->dev; - struct em_buffer *rx_buffer; - int i, error; + struct adapter *adapter = rxr->adapter; + device_t dev = adapter->dev; + struct em_buffer *rxbuf; + int error; - adapter->rx_buffer_area = malloc(sizeof(struct em_buffer) * + rxr->rx_buffers = malloc(sizeof(struct em_buffer) * adapter->num_rx_desc, M_DEVBUF, M_NOWAIT | M_ZERO); - if (adapter->rx_buffer_area == NULL) { + if (rxr->rx_buffers == NULL) { device_printf(dev, "Unable to allocate rx_buffer memory\n"); return (ENOMEM); } -#if __FreeBSD_version >= 700000 error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ -#else - error = bus_dma_tag_create(NULL, /* parent */ -#endif 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -4179,7 +3723,7 @@ em_allocate_receive_structures(struct adapter *adapter) 0, /* flags */ NULL, /* lockfunc */ NULL, /* lockarg */ - &adapter->rxtag); + &rxr->rxtag); if (error) { device_printf(dev, "%s: bus_dma_tag_create failed %d\n", __func__, error); @@ -4187,18 +3731,19 @@ em_allocate_receive_structures(struct adapter *adapter) } /* Create the spare map (used by getbuf) */ - error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT, - &adapter->rx_sparemap); + error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT, + &rxr->rx_sparemap); if (error) { device_printf(dev, "%s: bus_dmamap_create failed: %d\n", __func__, error); goto fail; } - rx_buffer = adapter->rx_buffer_area; - for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) { - error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT, - &rx_buffer->map); + rxbuf = rxr->rx_buffers; + for (int i = 0; i < adapter->num_rx_desc; i++, rxbuf++) { + rxbuf = &rxr->rx_buffers[i]; + error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT, + &rxbuf->map); if (error) { device_printf(dev, "%s: bus_dmamap_create failed: %d\n", __func__, error); @@ -4213,48 +3758,182 @@ fail: return (error); } + /********************************************************************* * - * (Re)initialize receive structures. + * Initialize a receive ring and its buffers. + * + **********************************************************************/ +static int +em_setup_receive_ring(struct rx_ring *rxr) +{ + struct adapter *adapter = rxr->adapter; + struct em_buffer *rxbuf; + bus_dma_segment_t seg[1]; + int rsize, nsegs, error; + + + /* Clear the ring contents */ + EM_RX_LOCK(rxr); + rsize = roundup2(adapter->num_rx_desc * + sizeof(struct e1000_rx_desc), EM_DBA_ALIGN); + bzero((void *)rxr->rx_base, rsize); + + /* + ** Free current RX buffer structs and their mbufs + */ + for (int i = 0; i < adapter->num_rx_desc; i++) { + rxbuf = &rxr->rx_buffers[i]; + if (rxbuf->m_head != NULL) { + bus_dmamap_sync(rxr->rxtag, rxbuf->map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(rxr->rxtag, rxbuf->map); + m_freem(rxbuf->m_head); + } + } + + /* Now replenish the mbufs */ + for (int j = 0; j != adapter->num_rx_desc; ++j) { + + rxbuf = &rxr->rx_buffers[j]; + rxbuf->m_head = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (rxbuf->m_head == NULL) + panic("RX ring hdr initialization failed!\n"); + rxbuf->m_head->m_len = MCLBYTES; + rxbuf->m_head->m_flags &= ~M_HASFCS; /* we strip it */ + rxbuf->m_head->m_pkthdr.len = MCLBYTES; + + /* Get the memory mapping */ + error = bus_dmamap_load_mbuf_sg(rxr->rxtag, + rxbuf->map, rxbuf->m_head, seg, + &nsegs, BUS_DMA_NOWAIT); + if (error != 0) + panic("RX ring dma initialization failed!\n"); + bus_dmamap_sync(rxr->rxtag, + rxbuf->map, BUS_DMASYNC_PREREAD); + + /* Update descriptor */ + rxr->rx_base[j].buffer_addr = htole64(seg[0].ds_addr); + } + + + /* Setup our descriptor indices */ + rxr->next_to_check = 0; + rxr->next_to_refresh = 0; + + bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + EM_RX_UNLOCK(rxr); + return (0); +} + +/********************************************************************* + * + * Initialize all receive rings. * **********************************************************************/ static int em_setup_receive_structures(struct adapter *adapter) { - struct em_buffer *rx_buffer; - int i, error; + struct rx_ring *rxr = adapter->rx_rings; + int j; - /* Reset descriptor ring */ - bzero(adapter->rx_desc_base, - (sizeof(struct e1000_rx_desc)) * adapter->num_rx_desc); - - /* Free current RX buffers. */ - rx_buffer = adapter->rx_buffer_area; - for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) { - if (rx_buffer->m_head != NULL) { - bus_dmamap_sync(adapter->rxtag, rx_buffer->map, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(adapter->rxtag, rx_buffer->map); - m_freem(rx_buffer->m_head); - rx_buffer->m_head = NULL; - } - } - - /* Allocate new ones. */ - for (i = 0; i < adapter->num_rx_desc; i++) { - error = em_get_buf(adapter, i); - if (error) - return (error); - } - - /* Setup our descriptor pointers */ - adapter->next_rx_desc_to_check = 0; - bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + for (j = 0; j < adapter->num_queues; j++, rxr++) + if (em_setup_receive_ring(rxr)) + goto fail; return (0); +fail: + /* + * Free RX buffers allocated so far, we will only handle + * the rings that completed, the failing case will have + * cleaned up for itself. 'j' failed, so its the terminus. + */ + for (int i = 0; i < j; ++i) { + rxr = &adapter->rx_rings[i]; + for (int n = 0; n < adapter->num_rx_desc; n++) { + struct em_buffer *rxbuf; + rxbuf = &rxr->rx_buffers[n]; + if (rxbuf->m_head != NULL) { + bus_dmamap_sync(rxr->rxtag, rxbuf->map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(rxr->rxtag, rxbuf->map); + m_freem(rxbuf->m_head); + rxbuf->m_head = NULL; + } + } + } + + return (ENOBUFS); } +/********************************************************************* + * + * Free all receive rings. + * + **********************************************************************/ +static void +em_free_receive_structures(struct adapter *adapter) +{ + struct rx_ring *rxr = adapter->rx_rings; + + for (int i = 0; i < adapter->num_queues; i++, rxr++) { + em_free_receive_buffers(rxr); + /* Free the ring memory as well */ + em_dma_free(adapter, &rxr->rxdma); + EM_RX_LOCK_DESTROY(rxr); + } + + free(adapter->rx_rings, M_DEVBUF); +} + + +/********************************************************************* + * + * Free receive ring data structures + * + **********************************************************************/ +static void +em_free_receive_buffers(struct rx_ring *rxr) +{ + struct adapter *adapter = rxr->adapter; + struct em_buffer *rxbuf = NULL; + + INIT_DEBUGOUT("free_receive_buffers: begin"); + + if (rxr->rx_sparemap) { + bus_dmamap_destroy(rxr->rxtag, rxr->rx_sparemap); + rxr->rx_sparemap = NULL; + } + + if (rxr->rx_buffers != NULL) { + for (int i = 0; i < adapter->num_rx_desc; i++) { + rxbuf = &rxr->rx_buffers[i]; + if (rxbuf->map != NULL) { + bus_dmamap_sync(rxr->rxtag, rxbuf->map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(rxr->rxtag, rxbuf->map); + bus_dmamap_destroy(rxr->rxtag, rxbuf->map); + } + if (rxbuf->m_head != NULL) { + m_freem(rxbuf->m_head); + rxbuf->m_head = NULL; + } + } + free(rxr->rx_buffers, M_DEVBUF); + rxr->rx_buffers = NULL; + } + + if (rxr->rxtag != NULL) { + bus_dma_tag_destroy(rxr->rxtag); + rxr->rxtag = NULL; + } + + return; +} + + /********************************************************************* * * Enable receive unit. @@ -4266,28 +3945,28 @@ em_setup_receive_structures(struct adapter *adapter) static void em_initialize_receive_unit(struct adapter *adapter) { + struct rx_ring *rxr = adapter->rx_rings; struct ifnet *ifp = adapter->ifp; + struct e1000_hw *hw = &adapter->hw; u64 bus_addr; u32 rctl, rxcsum; - INIT_DEBUGOUT("em_initialize_receive_unit: begin"); + INIT_DEBUGOUT("em_initialize_receive_units: begin"); /* * Make sure receives are disabled while setting * up the descriptor ring */ - rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); + rctl = E1000_READ_REG(hw, E1000_RCTL); + E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); - if (adapter->hw.mac.type >= e1000_82540) { - E1000_WRITE_REG(&adapter->hw, E1000_RADV, - adapter->rx_abs_int_delay.value); - /* - * Set the interrupt throttling rate. Value is calculated - * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) - */ - E1000_WRITE_REG(&adapter->hw, E1000_ITR, DEFAULT_ITR); - } + E1000_WRITE_REG(&adapter->hw, E1000_RADV, + adapter->rx_abs_int_delay.value); + /* + * Set the interrupt throttling rate. Value is calculated + * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) + */ + E1000_WRITE_REG(hw, E1000_ITR, DEFAULT_ITR); /* ** When using MSIX interrupts we need to throttle @@ -4295,67 +3974,17 @@ em_initialize_receive_unit(struct adapter *adapter) */ if (adapter->msix) for (int i = 0; i < 4; i++) - E1000_WRITE_REG(&adapter->hw, - E1000_EITR_82574(i), DEFAULT_ITR); + E1000_WRITE_REG(hw, E1000_EITR_82574(i), + DEFAULT_ITR); /* Disable accelerated ackknowledge */ if (adapter->hw.mac.type == e1000_82574) - E1000_WRITE_REG(&adapter->hw, - E1000_RFCTL, E1000_RFCTL_ACK_DIS); + E1000_WRITE_REG(hw, E1000_RFCTL, E1000_RFCTL_ACK_DIS); - /* Setup the Base and Length of the Rx Descriptor Ring */ - bus_addr = adapter->rxdma.dma_paddr; - E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0), - adapter->num_rx_desc * sizeof(struct e1000_rx_desc)); - E1000_WRITE_REG(&adapter->hw, E1000_RDBAH(0), - (u32)(bus_addr >> 32)); - E1000_WRITE_REG(&adapter->hw, E1000_RDBAL(0), - (u32)bus_addr); - - /* Setup the Receive Control Register */ - rctl &= ~(3 << E1000_RCTL_MO_SHIFT); - rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | - E1000_RCTL_RDMTS_HALF | - (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); - - /* Make sure VLAN Filters are off */ - rctl &= ~E1000_RCTL_VFE; - - if (e1000_tbi_sbp_enabled_82543(&adapter->hw)) - rctl |= E1000_RCTL_SBP; - else - rctl &= ~E1000_RCTL_SBP; - - switch (adapter->rx_buffer_len) { - default: - case 2048: - rctl |= E1000_RCTL_SZ_2048; - break; - case 4096: - rctl |= E1000_RCTL_SZ_4096 | - E1000_RCTL_BSEX | E1000_RCTL_LPE; - break; - case 8192: - rctl |= E1000_RCTL_SZ_8192 | - E1000_RCTL_BSEX | E1000_RCTL_LPE; - break; - case 16384: - rctl |= E1000_RCTL_SZ_16384 | - E1000_RCTL_BSEX | E1000_RCTL_LPE; - break; - } - - if (ifp->if_mtu > ETHERMTU) - rctl |= E1000_RCTL_LPE; - else - rctl &= ~E1000_RCTL_LPE; - - /* Enable 82543 Receive Checksum Offload for TCP and UDP */ - if ((adapter->hw.mac.type >= e1000_82543) && - (ifp->if_capenable & IFCAP_RXCSUM)) { - rxcsum = E1000_READ_REG(&adapter->hw, E1000_RXCSUM); + if (ifp->if_capenable & IFCAP_RXCSUM) { + rxcsum = E1000_READ_REG(hw, E1000_RXCSUM); rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL); - E1000_WRITE_REG(&adapter->hw, E1000_RXCSUM, rxcsum); + E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum); } /* @@ -4365,72 +3994,42 @@ em_initialize_receive_unit(struct adapter *adapter) ** values in RDTR is a known source of problems on other ** platforms another solution is being sought. */ - if (adapter->hw.mac.type == e1000_82573) - E1000_WRITE_REG(&adapter->hw, E1000_RDTR, 0x20); + if (hw->mac.type == e1000_82573) + E1000_WRITE_REG(hw, E1000_RDTR, 0x20); - /* Enable Receives */ - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl); + for (int i = 0; i < adapter->num_queues; i++, rxr++) { + /* Setup the Base and Length of the Rx Descriptor Ring */ + bus_addr = rxr->rxdma.dma_paddr; + E1000_WRITE_REG(hw, E1000_RDLEN(i), + adapter->num_rx_desc * sizeof(struct e1000_rx_desc)); + E1000_WRITE_REG(hw, E1000_RDBAH(i), (u32)(bus_addr >> 32)); + E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr); + /* Setup the Head and Tail Descriptor Pointers */ + E1000_WRITE_REG(hw, E1000_RDH(i), 0); + E1000_WRITE_REG(hw, E1000_RDT(i), adapter->num_rx_desc - 1); + } - /* - * Setup the HW Rx Head and - * Tail Descriptor Pointers - */ - E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0); - E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), adapter->num_rx_desc - 1); + /* Setup the Receive Control Register */ + rctl &= ~(3 << E1000_RCTL_MO_SHIFT); + rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | + E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | + (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT); + + /* Make sure VLAN Filters are off */ + rctl &= ~E1000_RCTL_VFE; + rctl &= ~E1000_RCTL_SBP; + rctl |= E1000_RCTL_SZ_2048; + if (ifp->if_mtu > ETHERMTU) + rctl |= E1000_RCTL_LPE; + else + rctl &= ~E1000_RCTL_LPE; + + /* Write out the settings */ + E1000_WRITE_REG(hw, E1000_RCTL, rctl); return; } -/********************************************************************* - * - * Free receive related data structures. - * - **********************************************************************/ -static void -em_free_receive_structures(struct adapter *adapter) -{ - struct em_buffer *rx_buffer; - int i; - - INIT_DEBUGOUT("free_receive_structures: begin"); - - if (adapter->rx_sparemap) { - bus_dmamap_destroy(adapter->rxtag, adapter->rx_sparemap); - adapter->rx_sparemap = NULL; - } - - /* Cleanup any existing buffers */ - if (adapter->rx_buffer_area != NULL) { - rx_buffer = adapter->rx_buffer_area; - for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) { - if (rx_buffer->m_head != NULL) { - bus_dmamap_sync(adapter->rxtag, rx_buffer->map, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(adapter->rxtag, - rx_buffer->map); - m_freem(rx_buffer->m_head); - rx_buffer->m_head = NULL; - } else if (rx_buffer->map != NULL) - bus_dmamap_unload(adapter->rxtag, - rx_buffer->map); - if (rx_buffer->map != NULL) { - bus_dmamap_destroy(adapter->rxtag, - rx_buffer->map); - rx_buffer->map = NULL; - } - } - } - - if (adapter->rx_buffer_area != NULL) { - free(adapter->rx_buffer_area, M_DEVBUF); - adapter->rx_buffer_area = NULL; - } - - if (adapter->rxtag != NULL) { - bus_dma_tag_destroy(adapter->rxtag); - adapter->rxtag = NULL; - } -} /********************************************************************* * @@ -4444,184 +4043,127 @@ em_free_receive_structures(struct adapter *adapter) * For polling we also now return the number of cleaned packets *********************************************************************/ static int -em_rxeof(struct adapter *adapter, int count) +em_rxeof(struct rx_ring *rxr, int count) { - struct ifnet *ifp = adapter->ifp; - struct mbuf *mp; - u8 status, accept_frame = 0, eop = 0; - u16 len, desc_len, prev_len_adj; - int i, rx_sent = 0; - struct e1000_rx_desc *current_desc; + struct adapter *adapter = rxr->adapter; + struct ifnet *ifp = adapter->ifp;; + struct mbuf *mp, *sendmp; + u8 status; + u16 len; + int i, processed, rxdone = 0; + bool eop; + struct e1000_rx_desc *cur; - EM_RX_LOCK(adapter); - i = adapter->next_rx_desc_to_check; - current_desc = &adapter->rx_desc_base[i]; - bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, - BUS_DMASYNC_POSTREAD); + EM_RX_LOCK(rxr); - if (!((current_desc->status) & E1000_RXD_STAT_DD)) { - EM_RX_UNLOCK(adapter); - return (rx_sent); - } + for (i = rxr->next_to_check, processed = 0; count != 0;) { - while ((current_desc->status & E1000_RXD_STAT_DD) && - (count != 0) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) { - struct mbuf *m = NULL; + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; - mp = adapter->rx_buffer_area[i].m_head; - /* - * Can't defer bus_dmamap_sync(9) because TBI_ACCEPT - * needs to access the last received byte in the mbuf. - */ - bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map, - BUS_DMASYNC_POSTREAD); + bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - accept_frame = 1; - prev_len_adj = 0; - desc_len = le16toh(current_desc->length); - status = current_desc->status; - if (status & E1000_RXD_STAT_EOP) { - count--; - eop = 1; - if (desc_len < ETHER_CRC_LEN) { - len = 0; - prev_len_adj = ETHER_CRC_LEN - desc_len; - } else - len = desc_len - ETHER_CRC_LEN; - } else { - eop = 0; - len = desc_len; - } + cur = &rxr->rx_base[i]; + status = cur->status; + mp = sendmp = NULL; - if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) { - u8 last_byte; - u32 pkt_len = desc_len; + if ((status & E1000_RXD_STAT_DD) == 0) + break; - if (adapter->fmp != NULL) - pkt_len += adapter->fmp->m_pkthdr.len; + len = le16toh(cur->length); + eop = (status & E1000_RXD_STAT_EOP) != 0; + count--; - last_byte = *(mtod(mp, caddr_t) + desc_len - 1); - if (TBI_ACCEPT(&adapter->hw, status, - current_desc->errors, pkt_len, last_byte, - adapter->min_frame_size, adapter->max_frame_size)) { - e1000_tbi_adjust_stats_82543(&adapter->hw, - &adapter->stats, pkt_len, - adapter->hw.mac.addr, - adapter->max_frame_size); - if (len > 0) - len--; - } else - accept_frame = 0; - } - - if (accept_frame) { - if (em_get_buf(adapter, i) != 0) { - ifp->if_iqdrops++; - goto discard; - } + if ((cur->errors & E1000_RXD_ERR_FRAME_ERR_MASK) == 0) { /* Assign correct length to the current fragment */ + mp = rxr->rx_buffers[i].m_head; mp->m_len = len; - if (adapter->fmp == NULL) { + if (rxr->fmp == NULL) { mp->m_pkthdr.len = len; - adapter->fmp = mp; /* Store the first mbuf */ - adapter->lmp = mp; + rxr->fmp = mp; /* Store the first mbuf */ + rxr->lmp = mp; } else { /* Chain mbuf's together */ mp->m_flags &= ~M_PKTHDR; - /* - * Adjust length of previous mbuf in chain if - * we received less than 4 bytes in the last - * descriptor. - */ - if (prev_len_adj > 0) { - adapter->lmp->m_len -= prev_len_adj; - adapter->fmp->m_pkthdr.len -= - prev_len_adj; - } - adapter->lmp->m_next = mp; - adapter->lmp = adapter->lmp->m_next; - adapter->fmp->m_pkthdr.len += len; + rxr->lmp->m_next = mp; + rxr->lmp = rxr->lmp->m_next; + rxr->fmp->m_pkthdr.len += len; } if (eop) { - adapter->fmp->m_pkthdr.rcvif = ifp; + rxr->fmp->m_pkthdr.rcvif = ifp; ifp->if_ipackets++; - em_receive_checksum(adapter, current_desc, - adapter->fmp); + em_receive_checksum(cur, rxr->fmp); #ifndef __NO_STRICT_ALIGNMENT if (adapter->max_frame_size > (MCLBYTES - ETHER_ALIGN) && - em_fixup_rx(adapter) != 0) + em_fixup_rx(rxr) != 0) goto skip; #endif if (status & E1000_RXD_STAT_VP) { -#if __FreeBSD_version < 700000 - VLAN_INPUT_TAG_NEW(ifp, adapter->fmp, - (le16toh(current_desc->special) & - E1000_RXD_SPC_VLAN_MASK)); -#else - adapter->fmp->m_pkthdr.ether_vtag = - (le16toh(current_desc->special) & + rxr->fmp->m_pkthdr.ether_vtag = + (le16toh(cur->special) & E1000_RXD_SPC_VLAN_MASK); - adapter->fmp->m_flags |= M_VLANTAG; -#endif + rxr->fmp->m_flags |= M_VLANTAG; } #ifndef __NO_STRICT_ALIGNMENT skip: #endif - m = adapter->fmp; - adapter->fmp = NULL; - adapter->lmp = NULL; + sendmp = rxr->fmp; + rxr->fmp = NULL; + rxr->lmp = NULL; } } else { ifp->if_ierrors++; -discard: /* Reuse loaded DMA map and just update mbuf chain */ - mp = adapter->rx_buffer_area[i].m_head; + mp = rxr->rx_buffers[i].m_head; mp->m_len = mp->m_pkthdr.len = MCLBYTES; mp->m_data = mp->m_ext.ext_buf; mp->m_next = NULL; if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN)) m_adj(mp, ETHER_ALIGN); - if (adapter->fmp != NULL) { - m_freem(adapter->fmp); - adapter->fmp = NULL; - adapter->lmp = NULL; + if (rxr->fmp != NULL) { + m_freem(rxr->fmp); + rxr->fmp = NULL; + rxr->lmp = NULL; } - m = NULL; + sendmp = NULL; } /* Zero out the receive descriptors status. */ - current_desc->status = 0; - bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + cur->status = 0; + ++rxdone; /* cumulative for POLL */ + ++processed; /* Advance our pointers to the next descriptor. */ if (++i == adapter->num_rx_desc) i = 0; - /* Call into the stack */ - if (m != NULL) { - adapter->next_rx_desc_to_check = i; - EM_RX_UNLOCK(adapter); - (*ifp->if_input)(ifp, m); - EM_RX_LOCK(adapter); - rx_sent++; - i = adapter->next_rx_desc_to_check; - } - current_desc = &adapter->rx_desc_base[i]; - } - adapter->next_rx_desc_to_check = i; - /* Advance the E1000's Receive Queue #0 "Tail Pointer". */ - if (--i < 0) - i = adapter->num_rx_desc - 1; - E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i); - EM_RX_UNLOCK(adapter); - return (rx_sent); + /* Send to the stack */ + if (sendmp != NULL) + (*ifp->if_input)(ifp, sendmp); + + /* Only refresh mbufs every 8 descriptors */ + if (processed == 8) { + em_refresh_mbufs(rxr, i); + processed = 0; + } + } + + /* Catch any remaining refresh work */ + if (processed != 0) { + em_refresh_mbufs(rxr, i); + processed = 0; + } + + rxr->next_to_check = i; + + EM_RX_UNLOCK(rxr); + return (rxdone); } #ifndef __NO_STRICT_ALIGNMENT @@ -4640,13 +4182,14 @@ discard: * not used at all on architectures with strict alignment. */ static int -em_fixup_rx(struct adapter *adapter) +em_fixup_rx(struct rx_ring *rxr) { + struct adapter *adapter = rxr->adapter; struct mbuf *m, *n; int error; error = 0; - m = adapter->fmp; + m = rxr->fmp; if (m->m_len <= (MCLBYTES - ETHER_HDR_LEN)) { bcopy(m->m_data, m->m_data + ETHER_HDR_LEN, m->m_len); m->m_data += ETHER_HDR_LEN; @@ -4659,11 +4202,11 @@ em_fixup_rx(struct adapter *adapter) n->m_len = ETHER_HDR_LEN; M_MOVE_PKTHDR(n, m); n->m_next = m; - adapter->fmp = n; + rxr->fmp = n; } else { adapter->dropped_pkts++; - m_freem(adapter->fmp); - adapter->fmp = NULL; + m_freem(rxr->fmp); + rxr->fmp = NULL; error = ENOMEM; } } @@ -4680,13 +4223,10 @@ em_fixup_rx(struct adapter *adapter) * *********************************************************************/ static void -em_receive_checksum(struct adapter *adapter, - struct e1000_rx_desc *rx_desc, struct mbuf *mp) +em_receive_checksum(struct e1000_rx_desc *rx_desc, struct mbuf *mp) { - /* 82543 or newer only */ - if ((adapter->hw.mac.type < e1000_82543) || - /* Ignore Checksum bit is set */ - (rx_desc->status & E1000_RXD_STAT_IXSM)) { + /* Ignore Checksum bit is set */ + if (rx_desc->status & E1000_RXD_STAT_IXSM) { mp->m_pkthdr.csum_flags = 0; return; } @@ -4713,7 +4253,6 @@ em_receive_checksum(struct adapter *adapter, } } -#if __FreeBSD_version >= 700029 /* * This routine is run via an vlan * config EVENT @@ -4800,7 +4339,6 @@ em_setup_vlan_hw_support(struct adapter *adapter) E1000_WRITE_REG(&adapter->hw, E1000_RLPML, adapter->max_frame_size + VLAN_TAG_SIZE); } -#endif static void em_enable_intr(struct adapter *adapter) @@ -4843,15 +4381,12 @@ em_init_manageability(struct adapter *adapter) manc &= ~(E1000_MANC_ARP_EN); /* enable receiving management packets to the host */ - if (adapter->hw.mac.type >= e1000_82571) { - manc |= E1000_MANC_EN_MNG2HOST; + manc |= E1000_MANC_EN_MNG2HOST; #define E1000_MNG2HOST_PORT_623 (1 << 5) #define E1000_MNG2HOST_PORT_664 (1 << 6) - manc2h |= E1000_MNG2HOST_PORT_623; - manc2h |= E1000_MNG2HOST_PORT_664; - E1000_WRITE_REG(&adapter->hw, E1000_MANC2H, manc2h); - } - + manc2h |= E1000_MNG2HOST_PORT_623; + manc2h |= E1000_MNG2HOST_PORT_664; + E1000_WRITE_REG(&adapter->hw, E1000_MANC2H, manc2h); E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc); } } @@ -4868,81 +4403,61 @@ em_release_manageability(struct adapter *adapter) /* re-enable hardware interception of ARP */ manc |= E1000_MANC_ARP_EN; - - if (adapter->hw.mac.type >= e1000_82571) - manc &= ~E1000_MANC_EN_MNG2HOST; + manc &= ~E1000_MANC_EN_MNG2HOST; E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc); } } /* - * em_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit. - * For ASF and Pass Through versions of f/w this means that - * the driver is loaded. For AMT version (only with 82573) - * of the f/w this means that the network i/f is open. - * + * em_get_hw_control sets the {CTRL_EXT|FWSM}:DRV_LOAD bit. + * For ASF and Pass Through versions of f/w this means + * that the driver is loaded. For AMT version type f/w + * this means that the network i/f is open. */ static void em_get_hw_control(struct adapter *adapter) { u32 ctrl_ext, swsm; - /* Let firmware know the driver has taken over */ - switch (adapter->hw.mac.type) { - case e1000_82573: + if (adapter->hw.mac.type == e1000_82573) { swsm = E1000_READ_REG(&adapter->hw, E1000_SWSM); E1000_WRITE_REG(&adapter->hw, E1000_SWSM, swsm | E1000_SWSM_DRV_LOAD); - break; - case e1000_82571: - case e1000_82572: - case e1000_80003es2lan: - case e1000_ich8lan: - case e1000_ich9lan: - case e1000_ich10lan: - ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); - E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, - ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); - break; - default: - break; + return; } + /* else */ + ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); + E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, + ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); + return; } /* * em_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit. - * For ASF and Pass Through versions of f/w this means that the - * driver is no longer loaded. For AMT version (only with 82573) i - * of the f/w this means that the network i/f is closed. - * + * For ASF and Pass Through versions of f/w this means that + * the driver is no longer loaded. For AMT versions of the + * f/w this means that the network i/f is closed. */ static void em_release_hw_control(struct adapter *adapter) { u32 ctrl_ext, swsm; - /* Let firmware taken over control of h/w */ - switch (adapter->hw.mac.type) { - case e1000_82573: + if (!adapter->has_manage) + return; + + if (adapter->hw.mac.type == e1000_82573) { swsm = E1000_READ_REG(&adapter->hw, E1000_SWSM); E1000_WRITE_REG(&adapter->hw, E1000_SWSM, swsm & ~E1000_SWSM_DRV_LOAD); - break; - case e1000_82571: - case e1000_82572: - case e1000_80003es2lan: - case e1000_ich8lan: - case e1000_ich9lan: - case e1000_ich10lan: - ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); - E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, - ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD); - break; - default: - break; - + return; } + /* else */ + ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); + E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, + ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD); + return; } static int @@ -4958,83 +4473,248 @@ em_is_valid_ether_addr(u8 *addr) } /* - * Enable PCI Wake On Lan capability - */ -void -em_enable_wakeup(device_t dev) +** Parse the interface capabilities with regard +** to both system management and wake-on-lan for +** later use. +*/ +static void +em_get_wakeup(device_t dev) { - u16 cap, status; - u8 id; + struct adapter *adapter = device_get_softc(dev); + u16 eeprom_data = 0, device_id, apme_mask; - /* First find the capabilities pointer*/ - cap = pci_read_config(dev, PCIR_CAP_PTR, 2); - /* Read the PM Capabilities */ - id = pci_read_config(dev, cap, 1); - if (id != PCIY_PMG) /* Something wrong */ - return; - /* OK, we have the power capabilities, so - now get the status register */ - cap += PCIR_POWER_STATUS; - status = pci_read_config(dev, cap, 2); - status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; - pci_write_config(dev, cap, status, 2); + adapter->has_manage = e1000_enable_mng_pass_thru(&adapter->hw); + apme_mask = EM_EEPROM_APME; + + switch (adapter->hw.mac.type) { + case e1000_82573: + case e1000_82583: + adapter->has_amt = TRUE; + /* Falls thru */ + case e1000_82571: + case e1000_82572: + case e1000_80003es2lan: + if (adapter->hw.bus.func == 1) { + e1000_read_nvm(&adapter->hw, + NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); + break; + } else + e1000_read_nvm(&adapter->hw, + NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); + break; + case e1000_ich8lan: + case e1000_ich9lan: + case e1000_ich10lan: + case e1000_pchlan: + apme_mask = E1000_WUC_APME; + adapter->has_amt = TRUE; + eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC); + break; + default: + e1000_read_nvm(&adapter->hw, + NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); + break; + } + if (eeprom_data & apme_mask) + adapter->wol = (E1000_WUFC_MAG | E1000_WUFC_MC); + /* + * We have the eeprom settings, now apply the special cases + * where the eeprom may be wrong or the board won't support + * wake on lan on a particular port + */ + device_id = pci_get_device(dev); + switch (device_id) { + case E1000_DEV_ID_82571EB_FIBER: + /* Wake events only supported on port A for dual fiber + * regardless of eeprom setting */ + if (E1000_READ_REG(&adapter->hw, E1000_STATUS) & + E1000_STATUS_FUNC_1) + adapter->wol = 0; + break; + case E1000_DEV_ID_82571EB_QUAD_COPPER: + case E1000_DEV_ID_82571EB_QUAD_FIBER: + case E1000_DEV_ID_82571EB_QUAD_COPPER_LP: + /* if quad port adapter, disable WoL on all but port A */ + if (global_quad_port_a != 0) + adapter->wol = 0; + /* Reset for multiple quad port adapters */ + if (++global_quad_port_a == 4) + global_quad_port_a = 0; + break; + } return; } -/********************************************************************* -* 82544 Coexistence issue workaround. -* There are 2 issues. -* 1. Transmit Hang issue. -* To detect this issue, following equation can be used... -* SIZE[3:0] + ADDR[2:0] = SUM[3:0]. -* If SUM[3:0] is in between 1 to 4, we will have this issue. -* -* 2. DAC issue. -* To detect this issue, following equation can be used... -* SIZE[3:0] + ADDR[2:0] = SUM[3:0]. -* If SUM[3:0] is in between 9 to c, we will have this issue. -* -* -* WORKAROUND: -* Make sure we do not have ending address -* as 1,2,3,4(Hang) or 9,a,b,c (DAC) -* -*************************************************************************/ -static u32 -em_fill_descriptors (bus_addr_t address, u32 length, - PDESC_ARRAY desc_array) +/* + * Enable PCI Wake On Lan capability + */ +static void +em_enable_wakeup(device_t dev) { - u32 safe_terminator; + struct adapter *adapter = device_get_softc(dev); + struct ifnet *ifp = adapter->ifp; + u32 pmc, ctrl, ctrl_ext, rctl; + u16 status; - /* Since issue is sensitive to length and address.*/ - /* Let us first check the address...*/ - if (length <= 4) { - desc_array->descriptor[0].address = address; - desc_array->descriptor[0].length = length; - desc_array->elements = 1; - return (desc_array->elements); - } - safe_terminator = (u32)((((u32)address & 0x7) + - (length & 0xF)) & 0xF); - /* if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then return */ - if (safe_terminator == 0 || - (safe_terminator > 4 && - safe_terminator < 9) || - (safe_terminator > 0xC && - safe_terminator <= 0xF)) { - desc_array->descriptor[0].address = address; - desc_array->descriptor[0].length = length; - desc_array->elements = 1; - return (desc_array->elements); + if ((pci_find_extcap(dev, PCIY_PMG, &pmc) != 0)) + return; + + /* Advertise the wakeup capability */ + ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL); + ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3); + E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); + E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN); + + if ((adapter->hw.mac.type == e1000_ich8lan) || + (adapter->hw.mac.type == e1000_pchlan) || + (adapter->hw.mac.type == e1000_ich9lan) || + (adapter->hw.mac.type == e1000_ich10lan)) { + e1000_disable_gig_wol_ich8lan(&adapter->hw); + e1000_hv_phy_powerdown_workaround_ich8lan(&adapter->hw); } - desc_array->descriptor[0].address = address; - desc_array->descriptor[0].length = length - 4; - desc_array->descriptor[1].address = address + (length - 4); - desc_array->descriptor[1].length = 4; - desc_array->elements = 2; - return (desc_array->elements); + /* Keep the laser running on Fiber adapters */ + if (adapter->hw.phy.media_type == e1000_media_type_fiber || + adapter->hw.phy.media_type == e1000_media_type_internal_serdes) { + ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); + ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA; + E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext); + } + + /* + ** Determine type of Wakeup: note that wol + ** is set with all bits on by default. + */ + if ((ifp->if_capenable & IFCAP_WOL_MAGIC) == 0) + adapter->wol &= ~E1000_WUFC_MAG; + + if ((ifp->if_capenable & IFCAP_WOL_MCAST) == 0) + adapter->wol &= ~E1000_WUFC_MC; + else { + rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + rctl |= E1000_RCTL_MPE; + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl); + } + + if (adapter->hw.mac.type == e1000_pchlan) { + if (em_enable_phy_wakeup(adapter)) + return; + } else { + E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN); + E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol); + } + + if (adapter->hw.phy.type == e1000_phy_igp_3) + e1000_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); + + /* Request PME */ + status = pci_read_config(dev, pmc + PCIR_POWER_STATUS, 2); + status &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE); + if (ifp->if_capenable & IFCAP_WOL) + status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; + pci_write_config(dev, pmc + PCIR_POWER_STATUS, status, 2); + + return; +} + +/* +** WOL in the newer chipset interfaces (pchlan) +** require thing to be copied into the phy +*/ +static int +em_enable_phy_wakeup(struct adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 mreg, ret = 0; + u16 preg; + + /* copy MAC RARs to PHY RARs */ + for (int i = 0; i < adapter->hw.mac.rar_entry_count; i++) { + mreg = E1000_READ_REG(hw, E1000_RAL(i)); + e1000_write_phy_reg(hw, BM_RAR_L(i), (u16)(mreg & 0xFFFF)); + e1000_write_phy_reg(hw, BM_RAR_M(i), + (u16)((mreg >> 16) & 0xFFFF)); + mreg = E1000_READ_REG(hw, E1000_RAH(i)); + e1000_write_phy_reg(hw, BM_RAR_H(i), (u16)(mreg & 0xFFFF)); + e1000_write_phy_reg(hw, BM_RAR_CTRL(i), + (u16)((mreg >> 16) & 0xFFFF)); + } + + /* copy MAC MTA to PHY MTA */ + for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) { + mreg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i); + e1000_write_phy_reg(hw, BM_MTA(i), (u16)(mreg & 0xFFFF)); + e1000_write_phy_reg(hw, BM_MTA(i) + 1, + (u16)((mreg >> 16) & 0xFFFF)); + } + + /* configure PHY Rx Control register */ + e1000_read_phy_reg(&adapter->hw, BM_RCTL, &preg); + mreg = E1000_READ_REG(hw, E1000_RCTL); + if (mreg & E1000_RCTL_UPE) + preg |= BM_RCTL_UPE; + if (mreg & E1000_RCTL_MPE) + preg |= BM_RCTL_MPE; + preg &= ~(BM_RCTL_MO_MASK); + if (mreg & E1000_RCTL_MO_3) + preg |= (((mreg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT) + << BM_RCTL_MO_SHIFT); + if (mreg & E1000_RCTL_BAM) + preg |= BM_RCTL_BAM; + if (mreg & E1000_RCTL_PMCF) + preg |= BM_RCTL_PMCF; + mreg = E1000_READ_REG(hw, E1000_CTRL); + if (mreg & E1000_CTRL_RFCE) + preg |= BM_RCTL_RFCE; + e1000_write_phy_reg(&adapter->hw, BM_RCTL, preg); + + /* enable PHY wakeup in MAC register */ + E1000_WRITE_REG(hw, E1000_WUC, + E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN); + E1000_WRITE_REG(hw, E1000_WUFC, adapter->wol); + + /* configure and enable PHY wakeup in PHY registers */ + e1000_write_phy_reg(&adapter->hw, BM_WUFC, adapter->wol); + e1000_write_phy_reg(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); + + /* activate PHY wakeup */ + ret = hw->phy.ops.acquire(hw); + if (ret) { + printf("Could not acquire PHY\n"); + return ret; + } + e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, + (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); + ret = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &preg); + if (ret) { + printf("Could not read PHY page 769\n"); + goto out; + } + preg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; + ret = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, preg); + if (ret) + printf("Could not set PHY Host Wakeup bit\n"); +out: + hw->phy.ops.release(hw); + + return ret; +} + +static void +em_led_func(void *arg, int onoff) +{ + struct adapter *adapter = arg; + + EM_CORE_LOCK(adapter); + if (onoff) { + e1000_setup_led(&adapter->hw); + e1000_led_on(&adapter->hw); + } else { + e1000_led_off(&adapter->hw); + e1000_cleanup_led(&adapter->hw); + } + EM_CORE_UNLOCK(adapter); } /********************************************************************** @@ -5146,6 +4826,8 @@ em_print_debug_info(struct adapter *adapter) { device_t dev = adapter->dev; u8 *hw_addr = adapter->hw.hw_addr; + struct rx_ring *rxr = adapter->rx_rings; + struct tx_ring *txr = adapter->tx_rings; device_printf(dev, "Adapter hardware address = %p \n", hw_addr); device_printf(dev, "CTRL = 0x%x RCTL = 0x%x \n", @@ -5163,29 +4845,33 @@ em_print_debug_info(struct adapter *adapter) device_printf(dev, "rx_int_delay = %d, rx_abs_int_delay = %d\n", E1000_READ_REG(&adapter->hw, E1000_RDTR), E1000_READ_REG(&adapter->hw, E1000_RADV)); - device_printf(dev, "fifo workaround = %lld, fifo_reset_count = %lld\n", - (long long)adapter->tx_fifo_wrk_cnt, - (long long)adapter->tx_fifo_reset_cnt); - device_printf(dev, "hw tdh = %d, hw tdt = %d\n", - E1000_READ_REG(&adapter->hw, E1000_TDH(0)), - E1000_READ_REG(&adapter->hw, E1000_TDT(0))); - device_printf(dev, "hw rdh = %d, hw rdt = %d\n", - E1000_READ_REG(&adapter->hw, E1000_RDH(0)), - E1000_READ_REG(&adapter->hw, E1000_RDT(0))); - device_printf(dev, "Num Tx descriptors avail = %d\n", - adapter->num_tx_desc_avail); - device_printf(dev, "Tx Descriptors not avail1 = %ld\n", - adapter->no_tx_desc_avail1); - device_printf(dev, "Tx Descriptors not avail2 = %ld\n", - adapter->no_tx_desc_avail2); + + for (int i = 0; i < adapter->num_queues; i++, txr++) { + device_printf(dev, "Queue(%d) tdh = %d, tdt = %d\n", i, + E1000_READ_REG(&adapter->hw, E1000_TDH(i)), + E1000_READ_REG(&adapter->hw, E1000_TDT(i))); + device_printf(dev, "TX(%d) no descriptors avail event = %ld\n", + txr->me, txr->no_desc_avail); + device_printf(dev, "TX(%d) MSIX IRQ Handled = %ld\n", + txr->me, txr->tx_irq); + device_printf(dev, "Num Tx descriptors avail = %d\n", + txr->tx_avail); + device_printf(dev, "Tx Descriptors not avail1 = %ld\n", + txr->no_desc_avail); + } + for (int i = 0; i < adapter->num_queues; i++, rxr++) { + device_printf(dev, "RX(%d) MSIX IRQ Handled = %ld\n", + rxr->me, rxr->rx_irq); + device_printf(dev, "hw rdh = %d, hw rdt = %d\n", + E1000_READ_REG(&adapter->hw, E1000_RDH(i)), + E1000_READ_REG(&adapter->hw, E1000_RDT(i))); + } device_printf(dev, "Std mbuf failed = %ld\n", adapter->mbuf_alloc_failed); device_printf(dev, "Std mbuf cluster failed = %ld\n", adapter->mbuf_cluster_failed); device_printf(dev, "Driver dropped packets = %ld\n", adapter->dropped_pkts); - device_printf(dev, "Driver tx dma failure in encap = %ld\n", - adapter->no_tx_dma_setup); } static void @@ -5218,12 +4904,8 @@ em_print_hw_stats(struct adapter *adapter) (long long)adapter->stats.algnerrc); device_printf(dev, "Collision/Carrier extension errors = %lld\n", (long long)adapter->stats.cexterr); - device_printf(dev, "RX overruns = %ld\n", adapter->rx_overruns); device_printf(dev, "watchdog timeouts = %ld\n", adapter->watchdog_events); - device_printf(dev, "RX MSIX IRQ = %ld TX MSIX IRQ = %ld" - " LINK MSIX IRQ = %ld\n", adapter->rx_irq, - adapter->tx_irq , adapter->link_irq); device_printf(dev, "XON Rcvd = %lld\n", (long long)adapter->stats.xonrxc); device_printf(dev, "XON Xmtd = %lld\n", @@ -5327,9 +5009,7 @@ em_sysctl_int_delay(SYSCTL_HANDLER_ARGS) struct em_int_delay_info *info; struct adapter *adapter; u32 regval; - int error; - int usecs; - int ticks; + int error, usecs, ticks; info = (struct em_int_delay_info *)arg1; usecs = info->value; @@ -5378,7 +5058,6 @@ em_add_int_delay_sysctl(struct adapter *adapter, const char *name, info, 0, em_sysctl_int_delay, "I", description); } -#ifndef EM_LEGACY_IRQ static void em_add_rx_process_limit(struct adapter *adapter, const char *name, const char *description, int *limit, int value) @@ -5388,6 +5067,5 @@ em_add_rx_process_limit(struct adapter *adapter, const char *name, SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); } -#endif diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index 7487a89e0d0..96d217b420d 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -52,9 +52,8 @@ * (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0 */ #define EM_MIN_TXD 80 -#define EM_MAX_TXD_82543 256 #define EM_MAX_TXD 4096 -#define EM_DEFAULT_TXD EM_MAX_TXD_82543 +#define EM_DEFAULT_TXD 1024 /* * EM_RXD - Maximum number of receive Descriptors @@ -70,9 +69,8 @@ * (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0 */ #define EM_MIN_RXD 80 -#define EM_MAX_RXD_82543 256 #define EM_MAX_RXD 4096 -#define EM_DEFAULT_RXD EM_MAX_RXD_82543 +#define EM_DEFAULT_RXD 1024 /* * EM_TIDV - Transmit Interrupt Delay Value @@ -135,16 +133,15 @@ #define EM_RADV 64 /* - * This parameter controls the duration of transmit watchdog timer. + * This parameter controls the max duration of transmit watchdog. */ -#define EM_TX_TIMEOUT 5 +#define EM_WATCHDOG (10 * hz) /* * This parameter controls when the driver calls the routine to reclaim * transmit descriptors. */ #define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8) -#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32) /* * This parameter controls whether or not autonegotation is enabled. @@ -182,18 +179,14 @@ #define EM_DEFAULT_PBA 0x00000030 #define EM_SMARTSPEED_DOWNSHIFT 3 #define EM_SMARTSPEED_MAX 15 -#define EM_MAX_INTR 10 +#define EM_MAX_LOOP 10 #define MAX_NUM_MULTICAST_ADDRESSES 128 #define PCI_ANY_ID (~0U) #define ETHER_ALIGN 2 #define EM_FC_PAUSE_TIME 0x0680 #define EM_EEPROM_APME 0x400; - -/* Code compatilbility between 6 and 7 */ -#ifndef ETHER_BPF_MTAP -#define ETHER_BPF_MTAP BPF_MTAP -#endif +#define EM_82544_APME 0x0004; /* * TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be @@ -208,7 +201,6 @@ #define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK) #define EM_BAR_TYPE_MASK 0x00000001 #define EM_BAR_TYPE_MMEM 0x00000000 -#define EM_BAR_TYPE_IO 0x00000001 #define EM_BAR_TYPE_FLASH 0x0014 #define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK) #define EM_BAR_MEM_TYPE_MASK 0x00000006 @@ -236,6 +228,7 @@ #define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header)) #define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */ #define EM_MSIX_MASK 0x01F00000 /* For 82574 use */ +#define EM_MSIX_LINK 0x01000000 /* For 82574 use */ #define ETH_ZLEN 60 #define ETH_ADDR_LEN 6 #define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */ @@ -248,18 +241,6 @@ */ #define EM_EIAC 0x000DC -/* Used in for 82547 10Mb Half workaround */ -#define EM_PBA_BYTES_SHIFT 0xA -#define EM_TX_HEAD_ADDR_SHIFT 7 -#define EM_PBA_TX_MASK 0xFFFF0000 -#define EM_FIFO_HDR 0x10 -#define EM_82547_PKT_THRESH 0x3e0 - -/* Precision Time Sync (IEEE 1588) defines */ -#define ETHERTYPE_IEEE1588 0x88F7 -#define PICOSECS_PER_TICK 20833 -#define TSYNC_PORT 319 /* UDP port for the protocol */ - /* * Bus dma allocation structure used by * e1000_dma_malloc and e1000_dma_free. @@ -281,59 +262,134 @@ struct em_int_delay_info { int value; /* Current value in usecs */ }; +/* + * The transmit ring, one per tx queue + */ +struct tx_ring { + struct adapter *adapter; + struct mtx tx_mtx; + char mtx_name[16]; + u32 me; + u32 msix; + u32 ims; + bool watchdog_check; + int watchdog_time; + struct em_dma_alloc txdma; + struct e1000_tx_desc *tx_base; + struct task tx_task; + struct taskqueue *tq; + u32 next_avail_desc; + u32 next_to_clean; + struct em_buffer *tx_buffers; + volatile u16 tx_avail; + u32 tx_tso; /* last tx was tso */ + u16 last_hw_offload; +#if __FreeBSD_version >= 800000 + struct buf_ring *br; +#endif + /* Interrupt resources */ + bus_dma_tag_t txtag; + void *tag; + struct resource *res; + unsigned long tx_irq; + unsigned long no_desc_avail; +}; + +/* + * The Receive ring, one per rx queue + */ +struct rx_ring { + struct adapter *adapter; + u32 me; + u32 msix; + u32 ims; + struct mtx rx_mtx; + char mtx_name[16]; + u32 payload; + struct task rx_task; + struct taskqueue *tq; + struct e1000_rx_desc *rx_base; + struct em_dma_alloc rxdma; + u32 next_to_refresh; + u32 next_to_check; + struct em_buffer *rx_buffers; + struct mbuf *fmp; + struct mbuf *lmp; + + /* Interrupt resources */ + void *tag; + struct resource *res; + bus_dma_tag_t rxtag; + bus_dmamap_t rx_sparemap; + + /* Soft stats */ + unsigned long rx_irq; + unsigned long rx_packets; + unsigned long rx_bytes; +}; + + /* Our adapter structure */ struct adapter { struct ifnet *ifp; -#if __FreeBSD_version >= 800000 - struct buf_ring *br; -#endif struct e1000_hw hw; /* FreeBSD operating-system-specific structures. */ struct e1000_osdep osdep; struct device *dev; + struct cdev *led_dev; struct resource *memory; struct resource *flash; - struct resource *msix; + struct resource *msix_mem; - struct resource *ioport; - int io_rid; - - /* 82574 may use 3 int vectors */ - struct resource *res[3]; - void *tag[3]; - int rid[3]; + struct resource *res; + void *tag; + u32 linkvec; + u32 ivars; struct ifmedia media; struct callout timer; - struct callout tx_fifo_timer; - int watchdog_timer; - int msi; + int msix; int if_flags; int max_frame_size; int min_frame_size; struct mtx core_mtx; - struct mtx tx_mtx; - struct mtx rx_mtx; int em_insert_vlan_header; + u32 ims; + bool in_detach; /* Task for FAST handling */ struct task link_task; - struct task rxtx_task; - struct task rx_task; - struct task tx_task; + struct task que_task; struct taskqueue *tq; /* private task queue */ -#if __FreeBSD_version >= 700029 eventhandler_tag vlan_attach; eventhandler_tag vlan_detach; - u32 num_vlans; -#endif + + u16 num_vlans; + u16 num_queues; + + /* + * Transmit rings: + * Allocated at run time, an array of rings. + */ + struct tx_ring *tx_rings; + int num_tx_desc; + u32 txd_cmd; + + /* + * Receive rings: + * Allocated at run time, an array of rings. + */ + struct rx_ring *rx_rings; + int num_rx_desc; + u32 rx_process_limit; /* Management and WOL features */ - int wol; - int has_manage; + u32 wol; + bool has_manage; + bool has_amt; /* Info about the board itself */ uint8_t link_active; @@ -345,89 +401,26 @@ struct adapter { struct em_int_delay_info rx_int_delay; struct em_int_delay_info rx_abs_int_delay; - /* - * Transmit definitions - * - * We have an array of num_tx_desc descriptors (handled - * by the controller) paired with an array of tx_buffers - * (at tx_buffer_area). - * The index of the next available descriptor is next_avail_tx_desc. - * The number of remaining tx_desc is num_tx_desc_avail. - */ - struct em_dma_alloc txdma; /* bus_dma glue for tx desc */ - struct e1000_tx_desc *tx_desc_base; - uint32_t next_avail_tx_desc; - uint32_t next_tx_to_clean; - volatile uint16_t num_tx_desc_avail; - uint16_t num_tx_desc; - uint16_t last_hw_offload; - uint32_t txd_cmd; - struct em_buffer *tx_buffer_area; - bus_dma_tag_t txtag; /* dma tag for tx */ - uint32_t tx_tso; /* last tx was tso */ - - /* - * Receive definitions - * - * we have an array of num_rx_desc rx_desc (handled by the - * controller), and paired with an array of rx_buffers - * (at rx_buffer_area). - * The next pair to check on receive is at offset next_rx_desc_to_check - */ - struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */ - struct e1000_rx_desc *rx_desc_base; - uint32_t next_rx_desc_to_check; - uint32_t rx_buffer_len; - uint16_t num_rx_desc; - int rx_process_limit; - struct em_buffer *rx_buffer_area; - bus_dma_tag_t rxtag; - bus_dmamap_t rx_sparemap; - - /* - * First/last mbuf pointers, for - * collecting multisegment RX packets. - */ - struct mbuf *fmp; - struct mbuf *lmp; - /* Misc stats maintained by the driver */ unsigned long dropped_pkts; unsigned long mbuf_alloc_failed; unsigned long mbuf_cluster_failed; - unsigned long no_tx_desc_avail1; - unsigned long no_tx_desc_avail2; unsigned long no_tx_map_avail; unsigned long no_tx_dma_setup; - unsigned long watchdog_events; unsigned long rx_overruns; - unsigned long rx_irq; - unsigned long tx_irq; + unsigned long watchdog_events; unsigned long link_irq; - /* 82547 workaround */ - uint32_t tx_fifo_size; - uint32_t tx_fifo_head; - uint32_t tx_fifo_head_addr; - uint64_t tx_fifo_reset_cnt; - uint64_t tx_fifo_wrk_cnt; - uint32_t tx_head_addr; - - /* For 82544 PCIX Workaround */ - boolean_t pcix_82544; - boolean_t in_detach; - - struct e1000_hw_stats stats; }; -/* ****************************************************************************** +/******************************************************************************** * vendor_info_array * * This array contains the list of Subvendor/Subdevice IDs on which the driver * should load. * - * ******************************************************************************/ + ********************************************************************************/ typedef struct _em_vendor_info_t { unsigned int vendor_id; unsigned int device_id; @@ -442,19 +435,6 @@ struct em_buffer { bus_dmamap_t map; /* bus_dma map for packet */ }; -/* For 82544 PCIX Workaround */ -typedef struct _ADDRESS_LENGTH_PAIR -{ - uint64_t address; - uint32_t length; -} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR; - -typedef struct _DESCRIPTOR_PAIR -{ - ADDRESS_LENGTH_PAIR descriptor[4]; - uint32_t elements; -} DESC_ARRAY, *PDESC_ARRAY; - #define EM_CORE_LOCK_INIT(_sc, _name) \ mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF) #define EM_TX_LOCK_INIT(_sc, _name) \ diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index 8b3290a3f77..5fdd52c163b 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,6 +36,7 @@ #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_device_polling.h" #include "opt_inet.h" +#include "opt_altq.h" #endif #include @@ -62,10 +63,6 @@ #include #include -#ifdef IGB_IEEE1588 -#include -#endif - #include #include #include @@ -86,6 +83,7 @@ #include #include +#include #include #include @@ -101,7 +99,7 @@ int igb_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char igb_driver_version[] = "version - 1.7.3"; +char igb_driver_version[] = "version - 1.9.3"; /********************************************************************* @@ -123,12 +121,19 @@ static igb_vendor_info_t igb_vendor_info_array[] = PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82576, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82576_NS, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82576_NS_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82576_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82576_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82576_SERDES_QUAD, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82576_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82580_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82580_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82580_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82580_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82580_COPPER_DUAL, + PCI_ANY_ID, PCI_ANY_ID, 0}, /* required last entry */ { 0, 0, 0, 0, 0} }; @@ -159,7 +164,6 @@ static int igb_mq_start_locked(struct ifnet *, static void igb_qflush(struct ifnet *); #endif static int igb_ioctl(struct ifnet *, u_long, caddr_t); -static void igb_watchdog(struct adapter *); static void igb_init(void *); static void igb_init_locked(struct adapter *); static void igb_stop(void *); @@ -172,7 +176,7 @@ static int igb_allocate_legacy(struct adapter *); static int igb_setup_msix(struct adapter *); static void igb_free_pci_resources(struct adapter *); static void igb_local_timer(void *); -static int igb_hardware_init(struct adapter *); +static void igb_reset(struct adapter *); static void igb_setup_interface(device_t, struct adapter *); static int igb_allocate_queues(struct adapter *); static void igb_configure_queues(struct adapter *); @@ -190,13 +194,19 @@ static int igb_setup_receive_ring(struct rx_ring *); static void igb_initialize_receive_units(struct adapter *); static void igb_free_receive_structures(struct adapter *); static void igb_free_receive_buffers(struct rx_ring *); +static void igb_free_receive_ring(struct rx_ring *); static void igb_enable_intr(struct adapter *); static void igb_disable_intr(struct adapter *); static void igb_update_stats_counters(struct adapter *); static bool igb_txeof(struct tx_ring *); -static bool igb_rxeof(struct rx_ring *, int); -static void igb_rx_checksum(u32, struct mbuf *, bool); + +static __inline void igb_rx_discard(struct rx_ring *, int); +static __inline void igb_rx_input(struct rx_ring *, + struct ifnet *, struct mbuf *, u32); + +static bool igb_rxeof(struct igb_queue *, int); +static void igb_rx_checksum(u32, struct mbuf *, u32); static int igb_tx_ctx_setup(struct tx_ring *, struct mbuf *); static bool igb_tso_setup(struct tx_ring *, struct mbuf *, u32 *); static void igb_set_promisc(struct adapter *); @@ -204,7 +214,7 @@ static void igb_disable_promisc(struct adapter *); static void igb_set_multi(struct adapter *); static void igb_print_hw_stats(struct adapter *); static void igb_update_link_status(struct adapter *); -static int igb_get_buf(struct rx_ring *, int, u8); +static void igb_refresh_mbufs(struct rx_ring *, int); static void igb_register_vlan(void *, struct ifnet *, u16); static void igb_unregister_vlan(void *, struct ifnet *, u16); @@ -225,21 +235,22 @@ static void igb_release_manageability(struct adapter *); static void igb_get_hw_control(struct adapter *); static void igb_release_hw_control(struct adapter *); static void igb_enable_wakeup(device_t); +static void igb_led_func(void *, int); static int igb_irq_fast(void *); static void igb_add_rx_process_limit(struct adapter *, const char *, const char *, int *, int); static void igb_handle_rxtx(void *context, int pending); -static void igb_handle_tx(void *context, int pending); -static void igb_handle_rx(void *context, int pending); +static void igb_handle_que(void *context, int pending); +static void igb_handle_link(void *context, int pending); /* These are MSIX only irq handlers */ -static void igb_msix_rx(void *); -static void igb_msix_tx(void *); +static void igb_msix_que(void *); static void igb_msix_link(void *); -/* Adaptive Interrupt Moderation */ -static void igb_update_aim(struct rx_ring *); +#ifdef DEVICE_POLLING +static poll_handler_t igb_poll; +#endif /* POLLING */ /********************************************************************* * FreeBSD Device Interface Entry Points @@ -276,31 +287,35 @@ TUNABLE_INT("hw.igb.rxd", &igb_rxd); TUNABLE_INT("hw.igb.txd", &igb_txd); /* -** These parameters are used in Adaptive -** Interrupt Moderation. The value is set -** into EITR and controls the interrupt -** frequency. A variable static scheme can -** be created by changing the assigned value -** of igb_ave_latency to the desired value, -** and then set igb_enable_aim to FALSE. -** This will result in all EITR registers -** getting set to that value statically. +** AIM: Adaptive Interrupt Moderation +** which means that the interrupt rate +** is varied over time based on the +** traffic for that interrupt vector */ static int igb_enable_aim = TRUE; TUNABLE_INT("hw.igb.enable_aim", &igb_enable_aim); -static int igb_low_latency = IGB_LOW_LATENCY; -TUNABLE_INT("hw.igb.low_latency", &igb_low_latency); -static int igb_ave_latency = IGB_AVE_LATENCY; -TUNABLE_INT("hw.igb.ave_latency", &igb_ave_latency); -static int igb_bulk_latency = IGB_BULK_LATENCY; -TUNABLE_INT("hw.igb.bulk_latency", &igb_bulk_latency); - + /* -** This will autoconfigure based on the number -** of CPUs if set to 0. Only a matched pair of -** TX and RX rings are allowed. + * MSIX should be the default for best performance, + * but this allows it to be forced off for testing. + */ +static int igb_enable_msix = 1; +TUNABLE_INT("hw.igb.enable_msix", &igb_enable_msix); + +/* + * Header split has seemed to be beneficial in + * many circumstances tested, however there have + * been some stability issues, so the default is + * off. + */ +static bool igb_header_split = FALSE; +TUNABLE_INT("hw.igb.hdr_split", &igb_header_split); + +/* +** This will autoconfigure based on +** the number of CPUs if left at 0. */ -static int igb_num_queues = 1; +static int igb_num_queues = 0; TUNABLE_INT("hw.igb.num_queues", &igb_num_queues); /* How many packets rxeof tries to clean at a time */ @@ -415,21 +430,6 @@ igb_attach(device_t dev) OID_AUTO, "enable_aim", CTLTYPE_INT|CTLFLAG_RW, &igb_enable_aim, 1, "Interrupt Moderation"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "low_latency", CTLTYPE_INT|CTLFLAG_RW, - &igb_low_latency, 1, "Low Latency"); - - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "ave_latency", CTLTYPE_INT|CTLFLAG_RW, - &igb_ave_latency, 1, "Average Latency"); - - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "bulk_latency", CTLTYPE_INT|CTLFLAG_RW, - &igb_bulk_latency, 1, "Bulk Latency"); - callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); /* Determine hardware and mac info */ @@ -540,17 +540,10 @@ igb_attach(device_t dev) goto err_late; } - /* Now Initialize the hardware */ - if (igb_hardware_init(adapter)) { - device_printf(dev, "Unable to initialize the hardware\n"); - error = EIO; - goto err_late; - } - /* ** Configure Interrupts */ - if (adapter->msix > 1) /* MSIX */ + if ((adapter->msix > 1) && (igb_enable_msix)) error = igb_allocate_msix(adapter); else /* MSI or Legacy */ error = igb_allocate_legacy(adapter); @@ -560,21 +553,8 @@ igb_attach(device_t dev) /* Setup OS specific network interface */ igb_setup_interface(dev, adapter); -#ifdef IGB_IEEE1588 - /* - ** Setup the timer: IEEE 1588 support - */ - adapter->cycles.read = igb_read_clock; - adapter->cycles.mask = (u64)-1; - adapter->cycles.mult = 1; - adapter->cycles.shift = IGB_TSYNC_SHIFT; - E1000_WRITE_REG(&adapter->hw, E1000_TIMINCA, (1<<24) | - IGB_TSYNC_CYCLE_TIME * IGB_TSYNC_SHIFT); - E1000_WRITE_REG(&adapter->hw, E1000_SYSTIML, 0x00000000); - E1000_WRITE_REG(&adapter->hw, E1000_SYSTIMH, 0xFF800000); - - // JFV - this is not complete yet -#endif + /* Now get a good starting state */ + igb_reset(adapter); /* Initialize statistics */ igb_update_stats_counters(adapter); @@ -607,6 +587,9 @@ igb_attach(device_t dev) /* Tell the stack that the interface is not active */ adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + adapter->led_dev = led_create(igb_led_func, adapter, + device_get_nameunit(dev)); + INIT_DEBUGOUT("igb_attach: end"); return (0); @@ -646,6 +629,14 @@ igb_detach(device_t dev) return (EBUSY); } + if (adapter->led_dev != NULL) + led_destroy(adapter->led_dev); + +#ifdef DEVICE_POLLING + if (ifp->if_capenable & IFCAP_POLLING) + ether_poll_deregister(ifp); +#endif + IGB_CORE_LOCK(adapter); adapter->in_detach = 1; igb_stop(adapter); @@ -787,8 +778,8 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp) /* Send a copy of the frame to the BPF listener */ ETHER_BPF_MTAP(ifp, m_head); - /* Set timeout in case hardware has problems transmitting. */ - txr->watchdog_timer = IGB_TX_TIMEOUT; + /* Set watchdog on */ + txr->watchdog_check = TRUE; } } @@ -826,6 +817,9 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m) /* Which queue to use */ if ((m->m_flags & M_FLOWID) != 0) i = m->m_pkthdr.flowid % adapter->num_queues; + else + i = curcpu % adapter->num_queues; + txr = &adapter->tx_rings[i]; if (IGB_TX_TRYLOCK(txr)) { @@ -842,59 +836,48 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) { struct adapter *adapter = txr->adapter; struct mbuf *next; - int err = 0; + int err = 0, enq; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - err = drbr_enqueue(ifp, txr->br, m); + IGB_TX_LOCK_ASSERT(txr); + + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING || adapter->link_active == 0) { + if (m != NULL) + err = drbr_enqueue(ifp, txr->br, m); return (err); } - if (m == NULL) /* Called by tasklet */ - goto process; - - /* If nothing queued go right to xmit */ - if (!drbr_needs_enqueue(ifp, txr->br)) { - if ((err = igb_xmit(txr, &m)) != 0) { - if (m != NULL) - err = drbr_enqueue(ifp, txr->br, m); - return (err); - } else { - /* Success, update stats */ - drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags); - /* Send a copy of the frame to the BPF listener */ - ETHER_BPF_MTAP(ifp, m); - /* Set the watchdog */ - txr->watchdog_timer = IGB_TX_TIMEOUT; - } - - } else if ((err = drbr_enqueue(ifp, txr->br, m)) != 0) - return (err); - -process: - if (drbr_empty(ifp, txr->br)) - return (err); - - /* Process the queue */ - while (TRUE) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - break; + enq = 0; + if (m == NULL) { next = drbr_dequeue(ifp, txr->br); - if (next == NULL) - break; + } else if (drbr_needs_enqueue(ifp, txr->br)) { + if ((err = drbr_enqueue(ifp, txr->br, m)) != 0) + return (err); + next = drbr_dequeue(ifp, txr->br); + } else + next = m; + /* Process the queue */ + while (next != NULL) { if ((err = igb_xmit(txr, &next)) != 0) { if (next != NULL) err = drbr_enqueue(ifp, txr->br, next); break; } + enq++; drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags); ETHER_BPF_MTAP(ifp, next); - /* Set the watchdog */ - txr->watchdog_timer = IGB_TX_TIMEOUT; + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; + if (txr->tx_avail <= IGB_TX_OP_THRESHOLD) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + next = drbr_dequeue(ifp, txr->br); + } + if (enq > 0) { + /* Set the watchdog */ + txr->watchdog_check = TRUE; } - - if (txr->tx_avail <= IGB_TX_OP_THRESHOLD) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return (err); } @@ -1011,6 +994,9 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data) IGB_CORE_LOCK(adapter); igb_disable_intr(adapter); igb_set_multi(adapter); +#ifdef DEVICE_POLLING + if (!(ifp->if_capenable & IFCAP_POLLING)) +#endif igb_enable_intr(adapter); IGB_CORE_UNLOCK(adapter); } @@ -1037,6 +1023,26 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data) IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)"); reinit = 0; mask = ifr->ifr_reqcap ^ ifp->if_capenable; +#ifdef DEVICE_POLLING + if (mask & IFCAP_POLLING) { + if (ifr->ifr_reqcap & IFCAP_POLLING) { + error = ether_poll_register(igb_poll, ifp); + if (error) + return (error); + IGB_CORE_LOCK(adapter); + igb_disable_intr(adapter); + ifp->if_capenable |= IFCAP_POLLING; + IGB_CORE_UNLOCK(adapter); + } else { + error = ether_poll_deregister(ifp); + /* Enable interrupt even in error case */ + IGB_CORE_LOCK(adapter); + igb_enable_intr(adapter); + ifp->if_capenable &= ~IFCAP_POLLING; + IGB_CORE_UNLOCK(adapter); + } + } +#endif if (mask & IFCAP_HWCSUM) { ifp->if_capenable ^= IFCAP_HWCSUM; reinit = 1; @@ -1059,15 +1065,6 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; } -#ifdef IGB_IEEE1588 - /* - ** IOCTL support for Precision Time (IEEE 1588) Support - */ - case SIOCSHWTSTAMP: - error = igb_hwtstamp_ioctl(adapter, ifp); - break; -#endif - default: error = ether_ioctl(ifp, command, data); break; @@ -1076,80 +1073,6 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data) return (error); } -/********************************************************************* - * Watchdog timer: - * - * This routine is called from the local timer every second. - * As long as transmit descriptors are being cleaned the value - * is non-zero and we do nothing. Reaching 0 indicates a tx hang - * and we then reset the device. - * - **********************************************************************/ - -static void -igb_watchdog(struct adapter *adapter) -{ - struct tx_ring *txr = adapter->tx_rings; - bool tx_hang = FALSE; - - IGB_CORE_LOCK_ASSERT(adapter); - - /* - ** The timer is set to 5 every time start() queues a packet. - ** Then txeof keeps resetting it as long as it cleans at - ** least one descriptor. - ** Finally, anytime all descriptors are clean the timer is - ** set to 0. - ** - ** With TX Multiqueue we need to check every queue's timer, - ** if any time out we do the reset. - */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { - IGB_TX_LOCK(txr); - if (txr->watchdog_timer == 0 || - (--txr->watchdog_timer)) { - IGB_TX_UNLOCK(txr); - continue; - } else { - tx_hang = TRUE; - IGB_TX_UNLOCK(txr); - break; - } - } - if (tx_hang == FALSE) - return; - - /* If we are in this routine because of pause frames, then - * don't reset the hardware. - */ - if (E1000_READ_REG(&adapter->hw, E1000_STATUS) & - E1000_STATUS_TXOFF) { - txr = adapter->tx_rings; /* reset pointer */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { - IGB_TX_LOCK(txr); - txr->watchdog_timer = IGB_TX_TIMEOUT; - IGB_TX_UNLOCK(txr); - } - return; - } - - if (e1000_check_for_link(&adapter->hw) == 0) - device_printf(adapter->dev, "watchdog timeout -- resetting\n"); - - for (int i = 0; i < adapter->num_queues; i++, txr++) { - device_printf(adapter->dev, "Queue(%d) tdh = %d, tdt = %d\n", - i, E1000_READ_REG(&adapter->hw, E1000_TDH(i)), - E1000_READ_REG(&adapter->hw, E1000_TDT(i))); - device_printf(adapter->dev, "Queue(%d) desc avail = %d," - " Next Desc to Clean = %d\n", i, txr->tx_avail, - txr->next_to_clean); - } - - adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - adapter->watchdog_events++; - - igb_init_locked(adapter); -} /********************************************************************* * Init entry point @@ -1165,29 +1088,16 @@ igb_watchdog(struct adapter *adapter) static void igb_init_locked(struct adapter *adapter) { - struct rx_ring *rxr = adapter->rx_rings; - struct tx_ring *txr = adapter->tx_rings; struct ifnet *ifp = adapter->ifp; device_t dev = adapter->dev; - u32 pba = 0; INIT_DEBUGOUT("igb_init: begin"); IGB_CORE_LOCK_ASSERT(adapter); - igb_stop(adapter); + igb_disable_intr(adapter); + callout_stop(&adapter->timer); - /* - * Packet Buffer Allocation (PBA) - * Writing PBA sets the receive portion of the buffer - * the remainder is used for the transmit buffer. - */ - if (adapter->hw.mac.type == e1000_82575) { - INIT_DEBUGOUT1("igb_init: pba=%dK",pba); - pba = E1000_PBA_32K; /* 32K for Rx, 16K for Tx */ - E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba); - } - /* Get the latest mac address, User can use a LAA */ bcopy(IF_LLADDR(adapter->ifp), adapter->hw.mac.addr, ETHER_ADDR_LEN); @@ -1195,11 +1105,7 @@ igb_init_locked(struct adapter *adapter) /* Put the address into the Receive Address Array */ e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); - /* Initialize the hardware */ - if (igb_hardware_init(adapter)) { - device_printf(dev, "Unable to initialize the hardware\n"); - return; - } + igb_reset(adapter); igb_update_link_status(adapter); E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); @@ -1239,7 +1145,6 @@ igb_init_locked(struct adapter *adapter) /* Prepare receive descriptors and buffers */ if (igb_setup_receive_structures(adapter)) { device_printf(dev, "Could not setup receive structures\n"); - igb_stop(adapter); return; } igb_initialize_receive_units(adapter); @@ -1259,25 +1164,20 @@ igb_init_locked(struct adapter *adapter) /* Set up VLAN tag offload and filter */ igb_setup_vlan_hw_support(adapter); - /* Set default RX interrupt moderation */ - for (int i = 0; i < adapter->num_queues; i++, rxr++) { - E1000_WRITE_REG(&adapter->hw, - E1000_EITR(rxr->msix), igb_ave_latency); - rxr->eitr_setting = igb_ave_latency; - } - - /* Set TX interrupt rate & reset TX watchdog */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { - E1000_WRITE_REG(&adapter->hw, - E1000_EITR(txr->msix), igb_ave_latency); - txr->watchdog_timer = FALSE; - } - + /* this clears any pending interrupts */ + E1000_READ_REG(&adapter->hw, E1000_ICR); +#ifdef DEVICE_POLLING + /* + * Only enable interrupts if we are not polling, make sure + * they are off otherwise. + */ + if (ifp->if_capenable & IFCAP_POLLING) + igb_disable_intr(adapter); + else +#endif /* DEVICE_POLLING */ { - /* this clears any pending interrupts */ - E1000_READ_REG(&adapter->hw, E1000_ICR); - igb_enable_intr(adapter); - E1000_WRITE_REG(&adapter->hw, E1000_ICS, E1000_ICS_LSC); + igb_enable_intr(adapter); + E1000_WRITE_REG(&adapter->hw, E1000_ICS, E1000_ICS_LSC); } /* Don't reset the phy next time init gets called */ @@ -1298,15 +1198,15 @@ igb_init(void *arg) static void igb_handle_rxtx(void *context, int pending) { - struct adapter *adapter = context; - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; - struct ifnet *ifp; + struct igb_queue *que = context; + struct adapter *adapter = que->adapter; + struct tx_ring *txr = adapter->tx_rings; + struct ifnet *ifp; ifp = adapter->ifp; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if (igb_rxeof(rxr, adapter->rx_process_limit)) + if (igb_rxeof(que, adapter->rx_process_limit)) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); IGB_TX_LOCK(txr); igb_txeof(txr); @@ -1325,40 +1225,50 @@ igb_handle_rxtx(void *context, int pending) } static void -igb_handle_rx(void *context, int pending) +igb_handle_que(void *context, int pending) { - struct rx_ring *rxr = context; - struct adapter *adapter = rxr->adapter; - struct ifnet *ifp = adapter->ifp; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - if (igb_rxeof(rxr, adapter->rx_process_limit) != 0) - /* More to clean, schedule another task */ - taskqueue_enqueue(adapter->tq, &rxr->rx_task); - -} + struct igb_queue *que = context; + struct adapter *adapter = que->adapter; + struct tx_ring *txr = que->txr; + struct ifnet *ifp = adapter->ifp; + u32 loop = IGB_MAX_LOOP; + bool more; -static void -igb_handle_tx(void *context, int pending) -{ - struct tx_ring *txr = context; - struct adapter *adapter = txr->adapter; - struct ifnet *ifp = adapter->ifp; + /* RX first */ + do { + more = igb_rxeof(que, -1); + } while (loop-- && more); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - IGB_TX_LOCK(txr); - igb_txeof(txr); + if (IGB_TX_TRYLOCK(txr)) { + loop = IGB_MAX_LOOP; + do { + more = igb_txeof(txr); + } while (loop-- && more); #if __FreeBSD_version >= 800000 - if (!drbr_empty(ifp, txr->br)) - igb_mq_start_locked(ifp, txr, NULL); + igb_mq_start_locked(ifp, txr, NULL); #else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) igb_start_locked(txr, ifp); #endif IGB_TX_UNLOCK(txr); } + + /* Reenable this interrupt */ +#ifdef DEVICE_POLLING + if (!(ifp->if_capenable & IFCAP_POLLING)) +#endif + E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims); } +/* Deal with link in a sleepable context */ +static void +igb_handle_link(void *context, int pending) +{ + struct adapter *adapter = context; + + adapter->hw.mac.get_link_status = 1; + igb_update_link_status(adapter); +} /********************************************************************* * @@ -1395,16 +1305,72 @@ igb_irq_fast(void *arg) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); /* Link status change */ - if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - adapter->hw.mac.get_link_status = 1; - igb_update_link_status(adapter); - } + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) + taskqueue_enqueue(adapter->tq, &adapter->link_task); if (reg_icr & E1000_ICR_RXO) adapter->rx_overruns++; return FILTER_HANDLED; } +#ifdef DEVICE_POLLING +/********************************************************************* + * + * Legacy polling routine : if using this code you MUST be sure that + * multiqueue is not defined, ie, set igb_num_queues to 1. + * + *********************************************************************/ +#if __FreeBSD_version >= 800000 +#define POLL_RETURN_COUNT(a) (a) +static int +#else +#define POLL_RETURN_COUNT(a) +static void +#endif +igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct adapter *adapter = ifp->if_softc; + struct igb_queue *que = adapter->queues; + struct tx_ring *txr = adapter->tx_rings; + u32 reg_icr, rx_done = 0; + u32 loop = IGB_MAX_LOOP; + bool more; + + IGB_CORE_LOCK(adapter); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + IGB_CORE_UNLOCK(adapter); + return POLL_RETURN_COUNT(rx_done); + } + + if (cmd == POLL_AND_CHECK_STATUS) { + reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); + /* Link status change */ + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) + taskqueue_enqueue(adapter->tq, &adapter->link_task); + + if (reg_icr & E1000_ICR_RXO) + adapter->rx_overruns++; + } + IGB_CORE_UNLOCK(adapter); + + /* TODO: rx_count */ + rx_done = igb_rxeof(que, count) ? 1 : 0; + + IGB_TX_LOCK(txr); + do { + more = igb_txeof(txr); + } while (loop-- && more); +#if __FreeBSD_version >= 800000 + if (!drbr_empty(ifp, txr->br)) + igb_mq_start_locked(ifp, txr, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + igb_start_locked(txr, ifp); +#endif + IGB_TX_UNLOCK(txr); + return POLL_RETURN_COUNT(rx_done); +} +#endif /* DEVICE_POLLING */ /********************************************************************* * @@ -1412,58 +1378,82 @@ igb_irq_fast(void *arg) * **********************************************************************/ static void -igb_msix_tx(void *arg) +igb_msix_que(void *arg) { - struct tx_ring *txr = arg; - struct adapter *adapter = txr->adapter; - u32 loop = IGB_MAX_LOOP; - bool more; + struct igb_queue *que = arg; + struct adapter *adapter = que->adapter; + struct tx_ring *txr = que->txr; + struct rx_ring *rxr = que->rxr; + u32 newitr = 0; + bool more_tx, more_rx; + + E1000_WRITE_REG(&adapter->hw, E1000_EIMC, que->eims); + ++que->irqs; - ++txr->tx_irq; IGB_TX_LOCK(txr); - - do { - more = igb_txeof(txr); - } while (loop-- && more); - + more_tx = igb_txeof(txr); IGB_TX_UNLOCK(txr); - /* Schedule a clean task */ - taskqueue_enqueue(adapter->tq, &txr->tx_task); + more_rx = igb_rxeof(que, adapter->rx_process_limit); - /* Reenable this interrupt */ - E1000_WRITE_REG(&adapter->hw, E1000_EIMS, txr->eims); - return; -} + if (igb_enable_aim == FALSE) + goto no_calc; + /* + ** Do Adaptive Interrupt Moderation: + ** - Write out last calculated setting + ** - Calculate based on average size over + ** the last interval. + */ + if (que->eitr_setting) + E1000_WRITE_REG(&adapter->hw, + E1000_EITR(que->msix), que->eitr_setting); + + que->eitr_setting = 0; -/********************************************************************* - * - * MSIX RX Interrupt Service routine - * - **********************************************************************/ + /* Idle, do nothing */ + if ((txr->bytes == 0) && (rxr->bytes == 0)) + goto no_calc; + + /* Used half Default if sub-gig */ + if (adapter->link_speed != 1000) + newitr = IGB_DEFAULT_ITR / 2; + else { + if ((txr->bytes) && (txr->packets)) + newitr = txr->bytes/txr->packets; + if ((rxr->bytes) && (rxr->packets)) + newitr = max(newitr, + (rxr->bytes / rxr->packets)); + newitr += 24; /* account for hardware frame, crc */ + /* set an upper boundary */ + newitr = min(newitr, 3000); + /* Be nice to the mid range */ + if ((newitr > 300) && (newitr < 1200)) + newitr = (newitr / 3); + else + newitr = (newitr / 2); + } + newitr &= 0x7FFC; /* Mask invalid bits */ + if (adapter->hw.mac.type == e1000_82575) + newitr |= newitr << 16; + else + newitr |= 0x8000000; + + /* save for next interrupt */ + que->eitr_setting = newitr; -static void -igb_msix_rx(void *arg) -{ - struct rx_ring *rxr = arg; - struct adapter *adapter = rxr->adapter; - u32 loop = IGB_MAX_LOOP; - bool more; + /* Reset state */ + txr->bytes = 0; + txr->packets = 0; + rxr->bytes = 0; + rxr->packets = 0; - ++rxr->rx_irq; - do { - more = igb_rxeof(rxr, adapter->rx_process_limit); - } while (loop-- && more); - - /* Update interrupt rate */ - if (igb_enable_aim == TRUE) - igb_update_aim(rxr); - - /* Schedule another clean */ - taskqueue_enqueue(adapter->tq, &rxr->rx_task); - - /* Reenable this interrupt */ - E1000_WRITE_REG(&adapter->hw, E1000_EIMS, rxr->eims); +no_calc: + /* Schedule a clean task if needed*/ + if (more_tx || more_rx) + taskqueue_enqueue(que->tq, &que->que_task); + else + /* Reenable this interrupt */ + E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims); return; } @@ -1484,8 +1474,7 @@ igb_msix_link(void *arg) icr = E1000_READ_REG(&adapter->hw, E1000_ICR); if (!(icr & E1000_ICR_LSC)) goto spurious; - adapter->hw.mac.get_link_status = 1; - igb_update_link_status(adapter); + taskqueue_enqueue(adapter->tq, &adapter->link_task); spurious: /* Rearm */ @@ -1495,59 +1484,6 @@ spurious: } -/* -** Routine to adjust the RX EITR value based on traffic, -** its a simple three state model, but seems to help. -** -** Note that the three EITR values are tuneable using -** sysctl in real time. The feature can be effectively -** nullified by setting them equal. -*/ -#define BULK_THRESHOLD 10000 -#define AVE_THRESHOLD 1600 - -static void -igb_update_aim(struct rx_ring *rxr) -{ - struct adapter *adapter = rxr->adapter; - u32 olditr, newitr; - - /* Update interrupt moderation based on traffic */ - olditr = rxr->eitr_setting; - newitr = olditr; - - /* Idle, don't change setting */ - if (rxr->bytes == 0) - return; - - if (olditr == igb_low_latency) { - if (rxr->bytes > AVE_THRESHOLD) - newitr = igb_ave_latency; - } else if (olditr == igb_ave_latency) { - if (rxr->bytes < AVE_THRESHOLD) - newitr = igb_low_latency; - else if (rxr->bytes > BULK_THRESHOLD) - newitr = igb_bulk_latency; - } else if (olditr == igb_bulk_latency) { - if (rxr->bytes < BULK_THRESHOLD) - newitr = igb_ave_latency; - } - - if (olditr != newitr) { - /* Change interrupt rate */ - rxr->eitr_setting = newitr; - if (adapter->hw.mac.type == e1000_82575) - newitr |= newitr << 16; - else - newitr |= 0x8000000; - E1000_WRITE_REG(&adapter->hw, E1000_EITR(rxr->me), newitr); - } - - rxr->bytes = 0; - return; -} - - /********************************************************************* * * Media Ioctl callback @@ -1780,15 +1716,14 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) } else if (igb_tx_ctx_setup(txr, m_head)) olinfo_status |= E1000_TXD_POPTS_TXSM << 8; -#ifdef IGB_IEEE1588 - /* This is changing soon to an mtag detection */ - if (we detect this mbuf has a TSTAMP mtag) - cmd_type_len |= E1000_ADVTXD_MAC_TSTAMP; -#endif /* Calculate payload length */ olinfo_status |= ((m_head->m_pkthdr.len - hdrlen) << E1000_ADVTXD_PAYLEN_SHIFT); + /* 82575 needs the queue index added */ + if (adapter->hw.mac.type == e1000_82575) + olinfo_status |= txr->me << 4; + /* Set up our transmit descriptors */ i = txr->next_avail_desc; for (j = 0; j < nsegs; j++) { @@ -1801,8 +1736,7 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) seg_len = segs[j].ds_len; txd->read.buffer_addr = htole64(seg_addr); - txd->read.cmd_type_len = htole32( - adapter->txd_cmd | cmd_type_len | seg_len); + txd->read.cmd_type_len = htole32(cmd_type_len | seg_len); txd->read.olinfo_status = htole32(olinfo_status); last = i; if (++i == adapter->num_tx_desc) @@ -1825,13 +1759,14 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) * and Report Status (RS) */ txd->read.cmd_type_len |= - htole32(E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS); + htole32(E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS); /* * Keep track in the first buffer which * descriptor will be written back */ tx_buffer = &txr->tx_buffers[first]; tx_buffer->next_eop = last; + txr->watchdog_time = ticks; /* * Advance the Transmit Descriptor Tail (TDT), this tells the E1000 @@ -1896,7 +1831,11 @@ igb_set_multi(struct adapter *adapter) IOCTL_DEBUGOUT("igb_set_multi: begin"); +#if __FreeBSD_version < 800000 + IF_ADDR_LOCK(ifp); +#else if_maddr_rlock(ifp); +#endif TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1908,7 +1847,11 @@ igb_set_multi(struct adapter *adapter) &mta[mcnt * ETH_ADDR_LEN], ETH_ADDR_LEN); mcnt++; } +#if __FreeBSD_version < 800000 + IF_ADDR_UNLOCK(ifp); +#else if_maddr_runlock(ifp); +#endif if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) { reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); @@ -1920,17 +1863,20 @@ igb_set_multi(struct adapter *adapter) /********************************************************************* - * Timer routine - * - * This routine checks for link status and updates statistics. + * Timer routine: + * This routine checks for link status, + * updates statistics, and does the watchdog. * **********************************************************************/ static void igb_local_timer(void *arg) { - struct adapter *adapter = arg; - struct ifnet *ifp = adapter->ifp; + struct adapter *adapter = arg; + struct ifnet *ifp = adapter->ifp; + device_t dev = adapter->dev; + struct tx_ring *txr = adapter->tx_rings; + IGB_CORE_LOCK_ASSERT(adapter); @@ -1940,17 +1886,35 @@ igb_local_timer(void *arg) if (igb_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) igb_print_hw_stats(adapter); - /* - * Each second we check the watchdog to - * protect against hardware hangs. - */ - igb_watchdog(adapter); + /* + ** Watchdog: check for time since any descriptor was cleaned + */ + for (int i = 0; i < adapter->num_queues; i++, txr++) { + if (txr->watchdog_check == FALSE) + continue; + if ((ticks - txr->watchdog_time) > IGB_WATCHDOG) + goto timeout; + } /* Trigger an RX interrupt on all queues */ +#ifdef DEVICE_POLLING + if (!(ifp->if_capenable & IFCAP_POLLING)) +#endif E1000_WRITE_REG(&adapter->hw, E1000_EICS, adapter->rx_mask); - callout_reset(&adapter->timer, hz, igb_local_timer, adapter); + return; +timeout: + device_printf(adapter->dev, "Watchdog timeout -- resetting\n"); + device_printf(dev,"Queue(%d) tdh = %d, hw tdt = %d\n", txr->me, + E1000_READ_REG(&adapter->hw, E1000_TDH(txr->me)), + E1000_READ_REG(&adapter->hw, E1000_TDT(txr->me))); + device_printf(dev,"TX(%d) desc avail = %d," + "Next TX to Clean = %d\n", + txr->me, txr->tx_avail, txr->next_to_clean); + adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + adapter->watchdog_events++; + igb_init_locked(adapter); } static void @@ -1997,6 +1961,7 @@ igb_update_link_status(struct adapter *adapter) "Full Duplex" : "Half Duplex")); adapter->link_active = 1; ifp->if_baudrate = adapter->link_speed * 1000000; + /* This can sleep */ if_link_state_change(ifp, LINK_STATE_UP); } else if (!link_check && (adapter->link_active == 1)) { ifp->if_baudrate = adapter->link_speed = 0; @@ -2004,10 +1969,11 @@ igb_update_link_status(struct adapter *adapter) if (bootverbose) device_printf(dev, "Link is Down\n"); adapter->link_active = 0; + /* This can sleep */ if_link_state_change(ifp, LINK_STATE_DOWN); /* Turn off watchdogs */ for (int i = 0; i < adapter->num_queues; i++, txr++) - txr->watchdog_timer = FALSE; + txr->watchdog_check = FALSE; } } @@ -2023,6 +1989,7 @@ igb_stop(void *arg) { struct adapter *adapter = arg; struct ifnet *ifp = adapter->ifp; + struct tx_ring *txr = adapter->tx_rings; IGB_CORE_LOCK_ASSERT(adapter); @@ -2035,8 +2002,18 @@ igb_stop(void *arg) /* Tell the stack that the interface is no longer active */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + /* Unarm watchdog timer. */ + for (int i = 0; i < adapter->num_queues; i++, txr++) { + IGB_TX_LOCK(txr); + txr->watchdog_check = FALSE; + IGB_TX_UNLOCK(txr); + } + e1000_reset_hw(&adapter->hw); E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0); + + e1000_led_off(&adapter->hw); + e1000_cleanup_led(&adapter->hw); } @@ -2114,8 +2091,9 @@ igb_allocate_pci_resources(struct adapter *adapter) static int igb_allocate_legacy(struct adapter *adapter) { - device_t dev = adapter->dev; - int error, rid = 0; + device_t dev = adapter->dev; + struct igb_queue *que = adapter->queues; + int error, rid = 0; /* Turn off all interrupts */ E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff); @@ -2137,7 +2115,9 @@ igb_allocate_legacy(struct adapter *adapter) * Try allocating a fast interrupt and the associated deferred * processing contexts. */ - TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, adapter); + TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, que); + /* Make tasklet for deferred link handling */ + TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter); adapter->tq = taskqueue_create_fast("igb_taskq", M_NOWAIT, taskqueue_thread_enqueue, &adapter->tq); taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq", @@ -2158,96 +2138,56 @@ igb_allocate_legacy(struct adapter *adapter) /********************************************************************* * - * Setup the MSIX Interrupt handlers: + * Setup the MSIX Queue Interrupt handlers: * **********************************************************************/ static int igb_allocate_msix(struct adapter *adapter) { - device_t dev = adapter->dev; - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; - int error, rid, vector = 0; + device_t dev = adapter->dev; + struct igb_queue *que = adapter->queues; + int error, rid, vector = 0; - /* - * Setup the interrupt handlers - */ - /* TX Setup */ - for (int i = 0; i < adapter->num_queues; i++, vector++, txr++) { + for (int i = 0; i < adapter->num_queues; i++, vector++, que++) { rid = vector +1; - txr->res = bus_alloc_resource_any(dev, + que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); - if (txr->res == NULL) { + if (que->res == NULL) { device_printf(dev, "Unable to allocate bus resource: " - "MSIX TX Interrupt\n"); + "MSIX Queue Interrupt\n"); return (ENXIO); } - error = bus_setup_intr(dev, txr->res, + error = bus_setup_intr(dev, que->res, INTR_TYPE_NET | INTR_MPSAFE, NULL, - igb_msix_tx, txr, &txr->tag); + igb_msix_que, que, &que->tag); if (error) { - txr->res = NULL; - device_printf(dev, "Failed to register TX handler"); + que->res = NULL; + device_printf(dev, "Failed to register Queue handler"); return (error); } - /* Make tasklet for deferred handling - one per queue */ - TASK_INIT(&txr->tx_task, 0, igb_handle_tx, txr); - txr->msix = vector; + que->msix = vector; if (adapter->hw.mac.type == e1000_82575) - txr->eims = E1000_EICR_TX_QUEUE0 << i; + que->eims = E1000_EICR_TX_QUEUE0 << i; else - txr->eims = 1 << vector; + que->eims = 1 << vector; /* ** Bind the msix vector, and thus the - ** ring to the corresponding cpu. + ** rings to the corresponding cpu. */ if (adapter->num_queues > 1) - bus_bind_intr(dev, txr->res, i); - } - - /* RX Setup */ - for (int i = 0; i < adapter->num_queues; i++, vector++, rxr++) { - rid = vector +1; - rxr->res = bus_alloc_resource_any(dev, - SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); - if (rxr->res == NULL) { - device_printf(dev, - "Unable to allocate bus resource: " - "MSIX RX Interrupt\n"); - return (ENXIO); - } - error = bus_setup_intr(dev, rxr->res, - INTR_TYPE_NET | INTR_MPSAFE, NULL, - igb_msix_rx, rxr, &rxr->tag); - if (error) { - rxr->res = NULL; - device_printf(dev, "Failed to register RX handler"); - return (error); - } - /* Make tasklet for deferred handling - one per queue */ - TASK_INIT(&rxr->rx_task, 0, igb_handle_rx, rxr); - rxr->msix = vector; - if (adapter->hw.mac.type == e1000_82575) - rxr->eims = E1000_EICR_RX_QUEUE0 << i; - else - rxr->eims = 1 << vector; - /* Get a mask for local timer */ - adapter->rx_mask |= rxr->eims; - /* - ** Bind the msix vector, and thus the - ** ring to the corresponding cpu. - ** Notice that this makes an RX/TX pair - ** bound to each CPU, limited by the MSIX - ** vectors. - */ - if (adapter->num_queues > 1) - bus_bind_intr(dev, rxr->res, i); + bus_bind_intr(dev, que->res, i); + /* Make tasklet for deferred handling */ + TASK_INIT(&que->que_task, 0, igb_handle_que, que); + que->tq = taskqueue_create_fast("igb_que", M_NOWAIT, + taskqueue_thread_enqueue, &que->tq); + taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", + device_get_nameunit(adapter->dev)); } /* And Link */ - rid = vector +1; + rid = vector + 1; adapter->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (adapter->res == NULL) { @@ -2263,9 +2203,12 @@ igb_allocate_msix(struct adapter *adapter) return (error); } adapter->linkvec = vector; - adapter->tq = taskqueue_create_fast("igb_taskq", M_NOWAIT, + + /* Make tasklet for deferred handling */ + TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter); + adapter->tq = taskqueue_create_fast("igb_link", M_NOWAIT, taskqueue_thread_enqueue, &adapter->tq); - taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq", + taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s link", device_get_nameunit(adapter->dev)); return (0); @@ -2275,52 +2218,48 @@ igb_allocate_msix(struct adapter *adapter) static void igb_configure_queues(struct adapter *adapter) { - struct e1000_hw *hw = &adapter->hw; - struct tx_ring *txr; - struct rx_ring *rxr; + struct e1000_hw *hw = &adapter->hw; + struct igb_queue *que; + u32 tmp, ivar = 0; + u32 newitr = IGB_DEFAULT_ITR; + + /* First turn on RSS capability */ + if (adapter->hw.mac.type > e1000_82575) + E1000_WRITE_REG(hw, E1000_GPIE, + E1000_GPIE_MSIX_MODE | E1000_GPIE_EIAME | + E1000_GPIE_PBA | E1000_GPIE_NSICR); /* Turn on MSIX */ - /* - ** 82576 uses IVARs to route MSI/X - ** interrupts, its not very intuitive, - ** study the code carefully :) - */ - if (adapter->hw.mac.type == e1000_82576) { - u32 ivar = 0; - /* First turn on the capability */ - E1000_WRITE_REG(hw, E1000_GPIE, - E1000_GPIE_MSIX_MODE | - E1000_GPIE_EIAME | - E1000_GPIE_PBA | E1000_GPIE_NSICR); - /* RX */ + switch (adapter->hw.mac.type) { + case e1000_82580: + /* RX entries */ for (int i = 0; i < adapter->num_queues; i++) { - u32 index = i & 0x7; /* Each IVAR has two entries */ + u32 index = i >> 1; ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); - rxr = &adapter->rx_rings[i]; - if (i < 8) { - ivar &= 0xFFFFFF00; - ivar |= rxr->msix | E1000_IVAR_VALID; - } else { + que = &adapter->queues[i]; + if (i & 1) { ivar &= 0xFF00FFFF; - ivar |= (rxr->msix | E1000_IVAR_VALID) << 16; - } - E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar); - adapter->eims_mask |= rxr->eims; - } - /* TX */ - for (int i = 0; i < adapter->num_queues; i++) { - u32 index = i & 0x7; /* Each IVAR has two entries */ - ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); - txr = &adapter->tx_rings[i]; - if (i < 8) { - ivar &= 0xFFFF00FF; - ivar |= (txr->msix | E1000_IVAR_VALID) << 8; + ivar |= (que->msix | E1000_IVAR_VALID) << 16; } else { - ivar &= 0x00FFFFFF; - ivar |= (txr->msix | E1000_IVAR_VALID) << 24; + ivar &= 0xFFFFFF00; + ivar |= que->msix | E1000_IVAR_VALID; } E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar); - adapter->eims_mask |= txr->eims; + } + /* TX entries */ + for (int i = 0; i < adapter->num_queues; i++) { + u32 index = i >> 1; + ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + que = &adapter->queues[i]; + if (i & 1) { + ivar &= 0x00FFFFFF; + ivar |= (que->msix | E1000_IVAR_VALID) << 24; + } else { + ivar &= 0xFFFF00FF; + ivar |= (que->msix | E1000_IVAR_VALID) << 8; + } + E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar); + adapter->eims_mask |= que->eims; } /* And for the link interrupt */ @@ -2328,11 +2267,48 @@ igb_configure_queues(struct adapter *adapter) adapter->link_mask = 1 << adapter->linkvec; adapter->eims_mask |= adapter->link_mask; E1000_WRITE_REG(hw, E1000_IVAR_MISC, ivar); - } else - { /* 82575 */ - int tmp; + break; + case e1000_82576: + /* RX entries */ + for (int i = 0; i < adapter->num_queues; i++) { + u32 index = i & 0x7; /* Each IVAR has two entries */ + ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + que = &adapter->queues[i]; + if (i < 8) { + ivar &= 0xFFFFFF00; + ivar |= que->msix | E1000_IVAR_VALID; + } else { + ivar &= 0xFF00FFFF; + ivar |= (que->msix | E1000_IVAR_VALID) << 16; + } + E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar); + adapter->eims_mask |= que->eims; + } + /* TX entries */ + for (int i = 0; i < adapter->num_queues; i++) { + u32 index = i & 0x7; /* Each IVAR has two entries */ + ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + que = &adapter->queues[i]; + if (i < 8) { + ivar &= 0xFFFF00FF; + ivar |= (que->msix | E1000_IVAR_VALID) << 8; + } else { + ivar &= 0x00FFFFFF; + ivar |= (que->msix | E1000_IVAR_VALID) << 24; + } + E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar); + adapter->eims_mask |= que->eims; + } - /* enable MSI-X PBA support*/ + /* And for the link interrupt */ + ivar = (adapter->linkvec | E1000_IVAR_VALID) << 8; + adapter->link_mask = 1 << adapter->linkvec; + adapter->eims_mask |= adapter->link_mask; + E1000_WRITE_REG(hw, E1000_IVAR_MISC, ivar); + break; + + case e1000_82575: + /* enable MSI-X support*/ tmp = E1000_READ_REG(hw, E1000_CTRL_EXT); tmp |= E1000_CTRL_EXT_PBA_CLR; /* Auto-Mask interrupts upon ICR read. */ @@ -2340,20 +2316,15 @@ igb_configure_queues(struct adapter *adapter) tmp |= E1000_CTRL_EXT_IRCA; E1000_WRITE_REG(hw, E1000_CTRL_EXT, tmp); - /* TX */ + /* Queues */ for (int i = 0; i < adapter->num_queues; i++) { - txr = &adapter->tx_rings[i]; - E1000_WRITE_REG(hw, E1000_MSIXBM(txr->msix), - txr->eims); - adapter->eims_mask |= txr->eims; - } - - /* RX */ - for (int i = 0; i < adapter->num_queues; i++) { - rxr = &adapter->rx_rings[i]; - E1000_WRITE_REG(hw, E1000_MSIXBM(rxr->msix), - rxr->eims); - adapter->eims_mask |= rxr->eims; + que = &adapter->queues[i]; + tmp = E1000_EICR_RX_QUEUE0 << i; + tmp |= E1000_EICR_TX_QUEUE0 << i; + que->eims = tmp; + E1000_WRITE_REG_ARRAY(hw, E1000_MSIXBM(0), + i, que->eims); + adapter->eims_mask |= que->eims; } /* Link */ @@ -2361,7 +2332,21 @@ igb_configure_queues(struct adapter *adapter) E1000_EIMS_OTHER); adapter->link_mask |= E1000_EIMS_OTHER; adapter->eims_mask |= adapter->link_mask; + default: + break; } + + /* Set the starting interrupt rate */ + if (hw->mac.type == e1000_82575) + newitr |= newitr << 16; + else + newitr |= 0x8000000; + + for (int i = 0; i < adapter->num_queues; i++) { + que = &adapter->queues[i]; + E1000_WRITE_REG(hw, E1000_EITR(que->msix), newitr); + } + return; } @@ -2369,8 +2354,7 @@ igb_configure_queues(struct adapter *adapter) static void igb_free_pci_resources(struct adapter *adapter) { - struct tx_ring *txr = adapter->tx_rings; - struct rx_ring *rxr = adapter->rx_rings; + struct igb_queue *que = adapter->queues; device_t dev = adapter->dev; int rid; @@ -2386,26 +2370,17 @@ igb_free_pci_resources(struct adapter *adapter) goto mem; /* - * First release all the TX/RX interrupt resources: + * First release all the interrupt resources: */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { - rid = txr->msix + 1; - if (txr->tag != NULL) { - bus_teardown_intr(dev, txr->res, txr->tag); - txr->tag = NULL; + for (int i = 0; i < adapter->num_queues; i++, que++) { + rid = que->msix + 1; + if (que->tag != NULL) { + bus_teardown_intr(dev, que->res, que->tag); + que->tag = NULL; } - if (txr->res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, rid, txr->res); - } - - for (int i = 0; i < adapter->num_queues; i++, rxr++) { - rid = rxr->msix + 1; - if (rxr->tag != NULL) { - bus_teardown_intr(dev, rxr->res, rxr->tag); - rxr->tag = NULL; - } - if (rxr->res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, rid, rxr->res); + if (que->res != NULL) + bus_release_resource(dev, + SYS_RES_IRQ, rid, que->res); } /* Clean the Legacy or Link interrupt last */ @@ -2444,6 +2419,10 @@ igb_setup_msix(struct adapter *adapter) device_t dev = adapter->dev; int rid, want, queues, msgs; + /* tuneable override */ + if (igb_enable_msix == 0) + goto msi; + /* First try MSI/X */ rid = PCIR_BAR(IGB_MSIX_BAR); adapter->msix_mem = bus_alloc_resource_any(dev, @@ -2464,15 +2443,21 @@ igb_setup_msix(struct adapter *adapter) } /* Figure out a reasonable auto config value */ - queues = (mp_ncpus > ((msgs-1)/2)) ? (msgs-1)/2 : mp_ncpus; + queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus; + + /* Manual override */ + if (igb_num_queues != 0) + queues = igb_num_queues; + + /* Can have max of 4 queues on 82575 */ + if ((adapter->hw.mac.type == e1000_82575) && (queues > 4)) + queues = 4; - if (igb_num_queues == 0) - igb_num_queues = queues; /* - ** Two vectors (RX/TX pair) per queue + ** One vector (RX/TX pair) per queue ** plus an additional for Link interrupt */ - want = (igb_num_queues * 2) + 1; + want = queues + 1; if (msgs >= want) msgs = want; else { @@ -2485,7 +2470,7 @@ igb_setup_msix(struct adapter *adapter) if ((msgs) && pci_alloc_msix(dev, &msgs) == 0) { device_printf(adapter->dev, "Using MSIX interrupts with %d vectors\n", msgs); - adapter->num_queues = igb_num_queues; + adapter->num_queues = queues; return (msgs); } msi: @@ -2497,24 +2482,70 @@ msi: /********************************************************************* * - * Initialize the hardware to a configuration - * as specified by the adapter structure. + * Set up an fresh starting state * **********************************************************************/ -static int -igb_hardware_init(struct adapter *adapter) +static void +igb_reset(struct adapter *adapter) { device_t dev = adapter->dev; - u32 rx_buffer_size; + struct e1000_hw *hw = &adapter->hw; + struct e1000_fc_info *fc = &hw->fc; + struct ifnet *ifp = adapter->ifp; + u32 pba = 0; + u16 hwm; - INIT_DEBUGOUT("igb_hardware_init: begin"); - - /* Issue a global reset */ - e1000_reset_hw(&adapter->hw); + INIT_DEBUGOUT("igb_reset: begin"); /* Let the firmware know the OS is in control */ igb_get_hw_control(adapter); + /* + * Packet Buffer Allocation (PBA) + * Writing PBA sets the receive portion of the buffer + * the remainder is used for the transmit buffer. + */ + switch (hw->mac.type) { + case e1000_82575: + pba = E1000_PBA_32K; + break; + case e1000_82576: + pba = E1000_PBA_64K; + break; + case e1000_82580: + pba = E1000_PBA_35K; + default: + break; + } + + /* Special needs in case of Jumbo frames */ + if ((hw->mac.type == e1000_82575) && (ifp->if_mtu > ETHERMTU)) { + u32 tx_space, min_tx, min_rx; + pba = E1000_READ_REG(hw, E1000_PBA); + tx_space = pba >> 16; + pba &= 0xffff; + min_tx = (adapter->max_frame_size + + sizeof(struct e1000_tx_desc) - ETHERNET_FCS_SIZE) * 2; + min_tx = roundup2(min_tx, 1024); + min_tx >>= 10; + min_rx = adapter->max_frame_size; + min_rx = roundup2(min_rx, 1024); + min_rx >>= 10; + if (tx_space < min_tx && + ((min_tx - tx_space) < pba)) { + pba = pba - (min_tx - tx_space); + /* + * if short on rx space, rx wins + * and must trump tx adjustment + */ + if (pba < min_rx) + pba = min_rx; + } + E1000_WRITE_REG(hw, E1000_PBA, pba); + } + + INIT_DEBUGOUT1("igb_init: pba=%dK",pba); + /* * These parameters control the automatic generation (Tx) and * response (Rx) to Ethernet PAUSE frames. @@ -2522,41 +2553,74 @@ igb_hardware_init(struct adapter *adapter) * received after sending an XOFF. * - Low water mark works best when it is very near the high water mark. * This allows the receiver to restart by sending XON when it has - * drained a bit. Here we use an arbitary value of 1500 which will - * restart after one full frame is pulled from the buffer. There - * could be several smaller frames in the buffer and if so they will - * not trigger the XON until their total number reduces the buffer - * by 1500. - * - The pause time is fairly large at 1000 x 512ns = 512 usec. + * drained a bit. */ - if (adapter->hw.mac.type == e1000_82576) - rx_buffer_size = ((E1000_READ_REG(&adapter->hw, - E1000_RXPBS) & 0xffff) << 10 ); - else - rx_buffer_size = ((E1000_READ_REG(&adapter->hw, - E1000_PBA) & 0xffff) << 10 ); + hwm = min(((pba << 10) * 9 / 10), + ((pba << 10) - 2 * adapter->max_frame_size)); - adapter->hw.fc.high_water = rx_buffer_size - - roundup2(adapter->max_frame_size, 1024); - adapter->hw.fc.low_water = adapter->hw.fc.high_water - 1500; + if (hw->mac.type < e1000_82576) { + fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */ + fc->low_water = fc->high_water - 8; + } else { + fc->high_water = hwm & 0xFFF0; /* 16-byte granularity */ + fc->low_water = fc->high_water - 16; + } - adapter->hw.fc.pause_time = IGB_FC_PAUSE_TIME; - adapter->hw.fc.send_xon = TRUE; + fc->pause_time = IGB_FC_PAUSE_TIME; + fc->send_xon = TRUE; /* Set Flow control, use the tunable location if sane */ if ((igb_fc_setting >= 0) || (igb_fc_setting < 4)) - adapter->hw.fc.requested_mode = igb_fc_setting; + fc->requested_mode = igb_fc_setting; else - adapter->hw.fc.requested_mode = e1000_fc_none; + fc->requested_mode = e1000_fc_none; - if (e1000_init_hw(&adapter->hw) < 0) { + fc->current_mode = fc->requested_mode; + + /* Issue a global reset */ + e1000_reset_hw(hw); + E1000_WRITE_REG(hw, E1000_WUC, 0); + + if (e1000_init_hw(hw) < 0) device_printf(dev, "Hardware Initialization Failed\n"); - return (EIO); + + if (hw->mac.type == e1000_82580) { + u32 reg; + + hwm = (pba << 10) - (2 * adapter->max_frame_size); + /* + * 0x80000000 - enable DMA COAL + * 0x10000000 - use L0s as low power + * 0x20000000 - use L1 as low power + * X << 16 - exit dma coal when rx data exceeds X kB + * Y - upper limit to stay in dma coal in units of 32usecs + */ + E1000_WRITE_REG(hw, E1000_DMACR, + 0xA0000006 | ((hwm << 6) & 0x00FF0000)); + + /* set hwm to PBA - 2 * max frame size */ + E1000_WRITE_REG(hw, E1000_FCRTC, hwm); + /* + * This sets the time to wait before requesting transition to + * low power state to number of usecs needed to receive 1 512 + * byte frame at gigabit line rate + */ + E1000_WRITE_REG(hw, E1000_DMCTLX, 4); + + /* free space in tx packet buffer to wake from DMA coal */ + E1000_WRITE_REG(hw, E1000_DMCTXTH, + (20480 - (2 * adapter->max_frame_size)) >> 6); + + /* make low power state decision controlled by DMA coal */ + reg = E1000_READ_REG(hw, E1000_PCIEMISC); + E1000_WRITE_REG(hw, E1000_PCIEMISC, + reg | E1000_PCIEMISC_LX_DECISION); } - e1000_check_for_link(&adapter->hw); - - return (0); + E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); + e1000_get_phy_info(hw); + e1000_check_for_link(hw); + return; } /********************************************************************* @@ -2596,7 +2660,13 @@ igb_setup_interface(device_t dev, struct adapter *adapter) ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_MTU; ifp->if_capabilities |= IFCAP_TSO4; ifp->if_capabilities |= IFCAP_JUMBO_MTU; + if (igb_header_split) + ifp->if_capabilities |= IFCAP_LRO; + ifp->if_capenable = ifp->if_capabilities; +#ifdef DEVICE_POLLING + ifp->if_capabilities |= IFCAP_POLLING; +#endif /* * Tell the upper layer(s) we support long frames. @@ -2654,7 +2724,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 */ - 1, 0, /* alignment, bounds */ + IGB_DBA_ALIGN, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ @@ -2732,22 +2802,31 @@ static int igb_allocate_queues(struct adapter *adapter) { device_t dev = adapter->dev; - struct tx_ring *txr; - struct rx_ring *rxr; + struct igb_queue *que = NULL; + struct tx_ring *txr = NULL; + struct rx_ring *rxr = NULL; int rsize, tsize, error = E1000_SUCCESS; int txconf = 0, rxconf = 0; - /* First allocate the TX ring struct memory */ + /* First allocate the top level queue structs */ + if (!(adapter->queues = + (struct igb_queue *) malloc(sizeof(struct igb_queue) * + adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { + device_printf(dev, "Unable to allocate queue memory\n"); + error = ENOMEM; + goto fail; + } + + /* Next allocate the TX ring struct memory */ if (!(adapter->tx_rings = (struct tx_ring *) malloc(sizeof(struct tx_ring) * adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { device_printf(dev, "Unable to allocate TX ring memory\n"); error = ENOMEM; - goto fail; + goto tx_fail; } - txr = adapter->tx_rings; - /* Next allocate the RX */ + /* Now allocate the RX */ if (!(adapter->rx_rings = (struct rx_ring *) malloc(sizeof(struct rx_ring) * adapter->num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) { @@ -2755,7 +2834,6 @@ igb_allocate_queues(struct adapter *adapter) error = ENOMEM; goto rx_fail; } - rxr = adapter->rx_rings; tsize = roundup2(adapter->num_tx_desc * sizeof(union e1000_adv_tx_desc), IGB_DBA_ALIGN); @@ -2833,6 +2911,16 @@ igb_allocate_queues(struct adapter *adapter) } } + /* + ** Finally set up the queue holding structs + */ + for (int i = 0; i < adapter->num_queues; i++) { + que = &adapter->queues[i]; + que->adapter = adapter; + que->txr = &adapter->tx_rings[i]; + que->rxr = &adapter->rx_rings[i]; + } + return (0); err_rx_desc: @@ -2843,7 +2931,10 @@ err_tx_desc: igb_dma_free(adapter, &txr->txdma); free(adapter->rx_rings, M_DEVBUF); rx_fail: + buf_ring_free(txr->br, M_DEVBUF); free(adapter->tx_rings, M_DEVBUF); +tx_fail: + free(adapter->queues, M_DEVBUF); fail: return (error); } @@ -2866,7 +2957,7 @@ igb_allocate_transmit_buffers(struct tx_ring *txr) /* * Setup DMA descriptor areas. */ - if ((error = bus_dma_tag_create(NULL, /* parent */ + if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -2920,6 +3011,7 @@ igb_setup_transmit_ring(struct tx_ring *txr) int i; /* Clear the old descriptor contents */ + IGB_TX_LOCK(txr); bzero((void *)txr->tx_base, (sizeof(union e1000_adv_tx_desc)) * adapter->num_tx_desc); /* Reset indices */ @@ -2945,7 +3037,7 @@ igb_setup_transmit_ring(struct tx_ring *txr) bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - + IGB_TX_UNLOCK(txr); } /********************************************************************* @@ -2973,48 +3065,50 @@ static void igb_initialize_transmit_units(struct adapter *adapter) { struct tx_ring *txr = adapter->tx_rings; + struct e1000_hw *hw = &adapter->hw; u32 tctl, txdctl; INIT_DEBUGOUT("igb_initialize_transmit_units: begin"); - /* Setup the Base and Length of the Tx Descriptor Rings */ + /* Setup the Tx Descriptor Rings */ for (int i = 0; i < adapter->num_queues; i++, txr++) { u64 bus_addr = txr->txdma.dma_paddr; - E1000_WRITE_REG(&adapter->hw, E1000_TDLEN(i), + E1000_WRITE_REG(hw, E1000_TDLEN(i), adapter->num_tx_desc * sizeof(struct e1000_tx_desc)); - E1000_WRITE_REG(&adapter->hw, E1000_TDBAH(i), + E1000_WRITE_REG(hw, E1000_TDBAH(i), (uint32_t)(bus_addr >> 32)); - E1000_WRITE_REG(&adapter->hw, E1000_TDBAL(i), + E1000_WRITE_REG(hw, E1000_TDBAL(i), (uint32_t)bus_addr); /* Setup the HW Tx Head and Tail descriptor pointers */ - E1000_WRITE_REG(&adapter->hw, E1000_TDT(i), 0); - E1000_WRITE_REG(&adapter->hw, E1000_TDH(i), 0); + E1000_WRITE_REG(hw, E1000_TDT(i), 0); + E1000_WRITE_REG(hw, E1000_TDH(i), 0); HW_DEBUGOUT2("Base = %x, Length = %x\n", - E1000_READ_REG(&adapter->hw, E1000_TDBAL(i)), - E1000_READ_REG(&adapter->hw, E1000_TDLEN(i))); + E1000_READ_REG(hw, E1000_TDBAL(i)), + E1000_READ_REG(hw, E1000_TDLEN(i))); - /* Setup Transmit Descriptor Base Settings */ - adapter->txd_cmd = E1000_TXD_CMD_IFCS; + txr->watchdog_check = FALSE; - txdctl = E1000_READ_REG(&adapter->hw, E1000_TXDCTL(i)); + txdctl = E1000_READ_REG(hw, E1000_TXDCTL(i)); + txdctl |= IGB_TX_PTHRESH; + txdctl |= IGB_TX_HTHRESH << 8; + txdctl |= IGB_TX_WTHRESH << 16; txdctl |= E1000_TXDCTL_QUEUE_ENABLE; - E1000_WRITE_REG(&adapter->hw, E1000_TXDCTL(i), txdctl); + E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl); } /* Program the Transmit Control Register */ - tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL); + tctl = E1000_READ_REG(hw, E1000_TCTL); tctl &= ~E1000_TCTL_CT; tctl |= (E1000_TCTL_PSP | E1000_TCTL_RTLC | E1000_TCTL_EN | (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT)); - e1000_config_collision_dist(&adapter->hw); + e1000_config_collision_dist(hw); /* This write will effectively turn on the transmit unit. */ - E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl); - + E1000_WRITE_REG(hw, E1000_TCTL, tctl); } /********************************************************************* @@ -3093,8 +3187,7 @@ igb_free_transmit_buffers(struct tx_ring *txr) /********************************************************************** * - * Setup work for hardware segmentation offload (TSO) on - * adapters using advanced tx descriptors (82575) + * Setup work for hardware segmentation offload (TSO) * **********************************************************************/ static boolean_t @@ -3165,6 +3258,9 @@ igb_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *hdrlen) /* MSS L4LEN IDX */ mss_l4len_idx |= (mp->m_pkthdr.tso_segsz << E1000_ADVTXD_MSS_SHIFT); mss_l4len_idx |= (tcp_hlen << E1000_ADVTXD_L4LEN_SHIFT); + /* 82575 needs the queue index added */ + if (adapter->hw.mac.type == e1000_82575) + mss_l4len_idx |= txr->me << 4; TXD->mss_l4len_idx = htole32(mss_l4len_idx); TXD->seqnum_seed = htole32(0); @@ -3192,7 +3288,7 @@ igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) struct adapter *adapter = txr->adapter; struct e1000_adv_tx_context_desc *TXD; struct igb_tx_buffer *tx_buffer; - uint32_t vlan_macip_lens = 0, type_tucmd_mlhl = 0; + u32 vlan_macip_lens, type_tucmd_mlhl, mss_l4len_idx; struct ether_vlan_header *eh; struct ip *ip = NULL; struct ip6_hdr *ip6; @@ -3204,6 +3300,7 @@ igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) if ((mp->m_pkthdr.csum_flags & CSUM_OFFLOAD) == 0) offload = FALSE; + vlan_macip_lens = type_tucmd_mlhl = mss_l4len_idx = 0; ctxd = txr->next_avail_desc; tx_buffer = &txr->tx_buffers[ctxd]; TXD = (struct e1000_adv_tx_context_desc *) &txr->tx_base[ctxd]; @@ -3283,11 +3380,15 @@ igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) break; } + /* 82575 needs the queue index added */ + if (adapter->hw.mac.type == e1000_82575) + mss_l4len_idx = txr->me << 4; + /* Now copy bits into descriptor */ TXD->vlan_macip_lens |= htole32(vlan_macip_lens); TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl); TXD->seqnum_seed = htole32(0); - TXD->mss_l4len_idx = htole32(0); + TXD->mss_l4len_idx = htole32(mss_l4len_idx); tx_buffer->m_head = NULL; tx_buffer->next_eop = -1; @@ -3314,8 +3415,7 @@ static bool igb_txeof(struct tx_ring *txr) { struct adapter *adapter = txr->adapter; - int first, last, done, num_avail; - u32 cleaned = 0; + int first, last, done; struct igb_tx_buffer *tx_buffer; struct e1000_tx_desc *tx_desc, *eop_desc; struct ifnet *ifp = adapter->ifp; @@ -3325,7 +3425,6 @@ igb_txeof(struct tx_ring *txr) if (txr->tx_avail == adapter->num_tx_desc) return FALSE; - num_avail = txr->tx_avail; first = txr->next_to_clean; tx_desc = &txr->tx_base[first]; tx_buffer = &txr->tx_buffers[first]; @@ -3343,7 +3442,7 @@ igb_txeof(struct tx_ring *txr) done = last; bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, - BUS_DMASYNC_POSTREAD); + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) { /* We clean the range of the packet */ @@ -3351,10 +3450,11 @@ igb_txeof(struct tx_ring *txr) tx_desc->upper.data = 0; tx_desc->lower.data = 0; tx_desc->buffer_addr = 0; - ++num_avail; ++cleaned; + ++txr->tx_avail; if (tx_buffer->m_head) { - ifp->if_opackets++; + txr->bytes += + tx_buffer->m_head->m_pkthdr.len; bus_dmamap_sync(txr->txtag, tx_buffer->map, BUS_DMASYNC_POSTWRITE); @@ -3365,6 +3465,7 @@ igb_txeof(struct tx_ring *txr) tx_buffer->m_head = NULL; } tx_buffer->next_eop = -1; + txr->watchdog_time = ticks; if (++first == adapter->num_tx_desc) first = 0; @@ -3372,6 +3473,8 @@ igb_txeof(struct tx_ring *txr) tx_buffer = &txr->tx_buffers[first]; tx_desc = &txr->tx_base[first]; } + ++txr->packets; + ++ifp->if_opackets; /* See if we can continue to the next packet */ last = tx_buffer->next_eop; if (last != -1) { @@ -3388,138 +3491,103 @@ igb_txeof(struct tx_ring *txr) txr->next_to_clean = first; /* - * If we have enough room, clear IFF_DRV_OACTIVE to tell the stack - * that it is OK to send packets. - * If there are no pending descriptors, clear the timeout. Otherwise, - * if some descriptors have been freed, restart the timeout. + * If we have enough room, clear IFF_DRV_OACTIVE + * to tell the stack that it is OK to send packets. */ - if (num_avail > IGB_TX_CLEANUP_THRESHOLD) { + if (txr->tx_avail > IGB_TX_CLEANUP_THRESHOLD) { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - /* All clean, turn off the timer */ - if (num_avail == adapter->num_tx_desc) { - txr->watchdog_timer = 0; - txr->tx_avail = num_avail; + /* All clean, turn off the watchdog */ + if (txr->tx_avail == adapter->num_tx_desc) { + txr->watchdog_check = FALSE; return FALSE; } } - /* Some cleaned, reset the timer */ - if (cleaned) - txr->watchdog_timer = IGB_TX_TIMEOUT; - txr->tx_avail = num_avail; - return TRUE; + return (TRUE); } /********************************************************************* * - * Setup descriptor buffer(s) from system mbuf buffer pools. - * i - designates the ring index - * clean - tells the function whether to update - * the header, the packet buffer, or both. + * Refresh mbuf buffers for RX descriptor rings + * - now keeps its own state so discards due to resource + * exhaustion are unnecessary, if an mbuf cannot be obtained + * it just returns, keeping its placeholder, thus it can simply + * be recalled to try again. * **********************************************************************/ -static int -igb_get_buf(struct rx_ring *rxr, int i, u8 clean) +static void +igb_refresh_mbufs(struct rx_ring *rxr, int limit) { struct adapter *adapter = rxr->adapter; + bus_dma_segment_t hseg[1]; + bus_dma_segment_t pseg[1]; + struct igb_rx_buf *rxbuf; struct mbuf *mh, *mp; - bus_dma_segment_t seg[2]; - bus_dmamap_t map; - struct igb_rx_buffer *rx_buffer; - int error, nsegs; - int merr = 0; + int i, nsegs, error, cleaned; + i = rxr->next_to_refresh; + cleaned = -1; /* Signify no completions */ + while (i != limit) { + rxbuf = &rxr->rx_buffers[i]; + if (rxbuf->m_head == NULL) { + mh = m_gethdr(M_DONTWAIT, MT_DATA); + if (mh == NULL) + goto update; + mh->m_pkthdr.len = mh->m_len = MHLEN; + mh->m_len = MHLEN; + mh->m_flags |= M_PKTHDR; + m_adj(mh, ETHER_ALIGN); + /* Get the memory mapping */ + error = bus_dmamap_load_mbuf_sg(rxr->htag, + rxbuf->hmap, mh, hseg, &nsegs, BUS_DMA_NOWAIT); + if (error != 0) { + printf("GET BUF: dmamap load" + " failure - %d\n", error); + m_free(mh); + goto update; + } + rxbuf->m_head = mh; + bus_dmamap_sync(rxr->htag, rxbuf->hmap, + BUS_DMASYNC_PREREAD); + rxr->rx_base[i].read.hdr_addr = + htole64(hseg[0].ds_addr); + } - rx_buffer = &rxr->rx_buffers[i]; + if (rxbuf->m_pack == NULL) { + mp = m_getjcl(M_DONTWAIT, MT_DATA, + M_PKTHDR, adapter->rx_mbuf_sz); + if (mp == NULL) + goto update; + mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz; + /* Get the memory mapping */ + error = bus_dmamap_load_mbuf_sg(rxr->ptag, + rxbuf->pmap, mp, pseg, &nsegs, BUS_DMA_NOWAIT); + if (error != 0) { + printf("GET BUF: dmamap load" + " failure - %d\n", error); + m_free(mp); + goto update; + } + rxbuf->m_pack = mp; + bus_dmamap_sync(rxr->ptag, rxbuf->pmap, + BUS_DMASYNC_PREREAD); + rxr->rx_base[i].read.pkt_addr = + htole64(pseg[0].ds_addr); + } - /* First get our header and payload mbuf */ - if (clean & IGB_CLEAN_HEADER) { - mh = m_gethdr(M_DONTWAIT, MT_DATA); - if (mh == NULL) - goto remap; - } else /* reuse */ - mh = rxr->rx_buffers[i].m_head; - - mh->m_len = MHLEN; - mh->m_flags |= M_PKTHDR; - - if (clean & IGB_CLEAN_PAYLOAD) { - mp = m_getjcl(M_DONTWAIT, MT_DATA, - M_PKTHDR, adapter->rx_mbuf_sz); - if (mp == NULL) - goto remap; - mp->m_len = adapter->rx_mbuf_sz; - mp->m_flags &= ~M_PKTHDR; - } else { /* reusing */ - mp = rxr->rx_buffers[i].m_pack; - mp->m_len = adapter->rx_mbuf_sz; - mp->m_flags &= ~M_PKTHDR; + cleaned = i; + /* Calculate next index */ + if (++i == adapter->num_rx_desc) + i = 0; + /* This is the work marker for refresh */ + rxr->next_to_refresh = i; } - /* - ** Need to create a chain for the following - ** dmamap call at this point. - */ - mh->m_next = mp; - mh->m_pkthdr.len = mh->m_len + mp->m_len; - - /* Get the memory mapping */ - error = bus_dmamap_load_mbuf_sg(rxr->rxtag, - rxr->rx_spare_map, mh, seg, &nsegs, BUS_DMA_NOWAIT); - if (error != 0) { - printf("GET BUF: dmamap load failure - %d\n", error); - m_free(mh); - return (error); - } - - /* Unload old mapping and update buffer struct */ - if (rx_buffer->m_head != NULL) - bus_dmamap_unload(rxr->rxtag, rx_buffer->map); - map = rx_buffer->map; - rx_buffer->map = rxr->rx_spare_map; - rxr->rx_spare_map = map; - rx_buffer->m_head = mh; - rx_buffer->m_pack = mp; - bus_dmamap_sync(rxr->rxtag, - rx_buffer->map, BUS_DMASYNC_PREREAD); - - /* Update descriptor */ - rxr->rx_base[i].read.hdr_addr = htole64(seg[0].ds_addr); - rxr->rx_base[i].read.pkt_addr = htole64(seg[1].ds_addr); - - return (0); - - /* - ** If we get here, we have an mbuf resource - ** issue, so we discard the incoming packet - ** and attempt to reuse existing mbufs next - ** pass thru the ring, but to do so we must - ** fix up the descriptor which had the address - ** clobbered with writeback info. - */ -remap: - adapter->mbuf_header_failed++; - merr = ENOBUFS; - /* Is there a reusable buffer? */ - mh = rxr->rx_buffers[i].m_head; - if (mh == NULL) /* Nope, init error */ - return (merr); - mp = rxr->rx_buffers[i].m_pack; - if (mp == NULL) /* Nope, init error */ - return (merr); - /* Get our old mapping */ - rx_buffer = &rxr->rx_buffers[i]; - error = bus_dmamap_load_mbuf_sg(rxr->rxtag, - rx_buffer->map, mh, seg, &nsegs, BUS_DMA_NOWAIT); - if (error != 0) { - /* We really have a problem */ - m_free(mh); - return (error); - } - /* Now fix the descriptor as needed */ - rxr->rx_base[i].read.hdr_addr = htole64(seg[0].ds_addr); - rxr->rx_base[i].read.pkt_addr = htole64(seg[1].ds_addr); - return (merr); +update: + if (cleaned != -1) /* If we refreshed some, bump tail */ + E1000_WRITE_REG(&adapter->hw, + E1000_RDT(rxr->me), cleaned); + return; } @@ -3536,55 +3604,64 @@ igb_allocate_receive_buffers(struct rx_ring *rxr) { struct adapter *adapter = rxr->adapter; device_t dev = adapter->dev; - struct igb_rx_buffer *rxbuf; + struct igb_rx_buf *rxbuf; int i, bsize, error; - bsize = sizeof(struct igb_rx_buffer) * adapter->num_rx_desc; + bsize = sizeof(struct igb_rx_buf) * adapter->num_rx_desc; if (!(rxr->rx_buffers = - (struct igb_rx_buffer *) malloc(bsize, + (struct igb_rx_buf *) malloc(bsize, M_DEVBUF, M_NOWAIT | M_ZERO))) { device_printf(dev, "Unable to allocate rx_buffer memory\n"); error = ENOMEM; goto fail; } - /* - ** The tag is made to accomodate the largest buffer size - ** with packet split (hence the two segments, even though - ** it may not always use this. - */ - if ((error = bus_dma_tag_create(NULL, /* parent */ + if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - MJUM16BYTES, /* maxsize */ - 2, /* nsegments */ - MJUMPAGESIZE, /* maxsegsize */ + MSIZE, /* maxsize */ + 1, /* nsegments */ + MSIZE, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ NULL, /* lockfuncarg */ - &rxr->rxtag))) { + &rxr->htag))) { device_printf(dev, "Unable to create RX DMA tag\n"); goto fail; } - /* Create the spare map (used by getbuf) */ - error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT, - &rxr->rx_spare_map); - if (error) { - device_printf(dev, - "%s: bus_dmamap_create header spare failed: %d\n", - __func__, error); + if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), + 1, 0, /* alignment, bounds */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + MJUMPAGESIZE, /* maxsize */ + 1, /* nsegments */ + MJUMPAGESIZE, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockfuncarg */ + &rxr->ptag))) { + device_printf(dev, "Unable to create RX payload DMA tag\n"); goto fail; } - for (i = 0; i < adapter->num_rx_desc; i++, rxbuf++) { + for (i = 0; i < adapter->num_rx_desc; i++) { rxbuf = &rxr->rx_buffers[i]; - error = bus_dmamap_create(rxr->rxtag, - BUS_DMA_NOWAIT, &rxbuf->map); + error = bus_dmamap_create(rxr->htag, + BUS_DMA_NOWAIT, &rxbuf->hmap); if (error) { - device_printf(dev, "Unable to create RX DMA maps\n"); + device_printf(dev, + "Unable to create RX head DMA maps\n"); + goto fail; + } + error = bus_dmamap_create(rxr->ptag, + BUS_DMA_NOWAIT, &rxbuf->pmap); + if (error) { + device_printf(dev, + "Unable to create RX packet DMA maps\n"); goto fail; } } @@ -3597,6 +3674,37 @@ fail: return (error); } + +static void +igb_free_receive_ring(struct rx_ring *rxr) +{ + struct adapter *adapter; + struct igb_rx_buf *rxbuf; + int i; + + adapter = rxr->adapter; + for (i = 0; i < adapter->num_rx_desc; i++) { + rxbuf = &rxr->rx_buffers[i]; + if (rxbuf->m_head != NULL) { + bus_dmamap_sync(rxr->htag, rxbuf->hmap, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(rxr->htag, rxbuf->hmap); + rxbuf->m_head->m_flags |= M_PKTHDR; + m_freem(rxbuf->m_head); + } + if (rxbuf->m_pack != NULL) { + bus_dmamap_sync(rxr->ptag, rxbuf->pmap, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(rxr->ptag, rxbuf->pmap); + rxbuf->m_pack->m_flags |= M_PKTHDR; + m_freem(rxbuf->m_pack); + } + rxbuf->m_head = NULL; + rxbuf->m_pack = NULL; + } +} + + /********************************************************************* * * Initialize a receive ring and its buffers. @@ -3608,17 +3716,17 @@ igb_setup_receive_ring(struct rx_ring *rxr) struct adapter *adapter; struct ifnet *ifp; device_t dev; - struct igb_rx_buffer *rxbuf; + struct igb_rx_buf *rxbuf; + bus_dma_segment_t pseg[1], hseg[1]; struct lro_ctrl *lro = &rxr->lro; - int j, rsize; + int rsize, nsegs, error = 0; adapter = rxr->adapter; dev = adapter->dev; ifp = adapter->ifp; - rxr->lro_enabled = FALSE; - rxr->hdr_split = FALSE; /* Clear the ring contents */ + IGB_RX_LOCK(rxr); rsize = roundup2(adapter->num_rx_desc * sizeof(union e1000_adv_rx_desc), IGB_DBA_ALIGN); bzero((void *)rxr->rx_base, rsize); @@ -3626,33 +3734,62 @@ igb_setup_receive_ring(struct rx_ring *rxr) /* ** Free current RX buffer structures and their mbufs */ - for (int i = 0; i < adapter->num_rx_desc; i++) { - rxbuf = &rxr->rx_buffers[i]; - bus_dmamap_sync(rxr->rxtag, rxbuf->map, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(rxr->rxtag, rxbuf->map); - if (rxbuf->m_head) { - rxbuf->m_head->m_next = rxbuf->m_pack; - m_freem(rxbuf->m_head); - } - rxbuf->m_head = NULL; - rxbuf->m_pack = NULL; - } + igb_free_receive_ring(rxr); - /* Next replenish the ring */ - for (j = 0; j < adapter->num_rx_desc; j++) { - if (igb_get_buf(rxr, j, IGB_CLEAN_BOTH) == ENOBUFS) { - rxr->rx_buffers[j].m_head = NULL; - rxr->rx_buffers[j].m_pack = NULL; - rxr->rx_base[j].read.hdr_addr = 0; - rxr->rx_base[j].read.pkt_addr = 0; - goto fail; - } - } + /* Now replenish the ring mbufs */ + for (int j = 0; j != adapter->num_rx_desc; ++j) { + struct mbuf *mh, *mp; - /* Setup our descriptor indices */ - rxr->next_to_check = 0; - rxr->last_cleaned = 0; + rxbuf = &rxr->rx_buffers[j]; + + /* First the header */ + rxbuf->m_head = m_gethdr(M_DONTWAIT, MT_DATA); + if (rxbuf->m_head == NULL) + goto fail; + m_adj(rxbuf->m_head, ETHER_ALIGN); + mh = rxbuf->m_head; + mh->m_len = mh->m_pkthdr.len = MHLEN; + mh->m_flags |= M_PKTHDR; + /* Get the memory mapping */ + error = bus_dmamap_load_mbuf_sg(rxr->htag, + rxbuf->hmap, rxbuf->m_head, hseg, + &nsegs, BUS_DMA_NOWAIT); + if (error != 0) /* Nothing elegant to do here */ + goto fail; + bus_dmamap_sync(rxr->htag, + rxbuf->hmap, BUS_DMASYNC_PREREAD); + /* Update descriptor */ + rxr->rx_base[j].read.hdr_addr = htole64(hseg[0].ds_addr); + + /* Now the payload cluster */ + rxbuf->m_pack = m_getjcl(M_DONTWAIT, MT_DATA, + M_PKTHDR, adapter->rx_mbuf_sz); + if (rxbuf->m_pack == NULL) + goto fail; + mp = rxbuf->m_pack; + mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz; + /* Get the memory mapping */ + error = bus_dmamap_load_mbuf_sg(rxr->ptag, + rxbuf->pmap, mp, pseg, + &nsegs, BUS_DMA_NOWAIT); + if (error != 0) + goto fail; + bus_dmamap_sync(rxr->ptag, + rxbuf->pmap, BUS_DMASYNC_PREREAD); + /* Update descriptor */ + rxr->rx_base[j].read.pkt_addr = htole64(pseg[0].ds_addr); + } + rxr->next_to_refresh = 0; + rxr->lro_enabled = FALSE; + + if (igb_header_split) + rxr->hdr_split = TRUE; + else + ifp->if_capabilities &= ~IFCAP_LRO; + + rxr->fmp = NULL; + rxr->lmp = NULL; + rxr->discard = FALSE; bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -3666,32 +3803,21 @@ igb_setup_receive_ring(struct rx_ring *rxr) if (ifp->if_capenable & IFCAP_LRO) { int err = tcp_lro_init(lro); if (err) { - device_printf(dev,"LRO Initialization failed!\n"); + device_printf(dev, "LRO Initialization failed!\n"); goto fail; } INIT_DEBUGOUT("RX LRO Initialized\n"); rxr->lro_enabled = TRUE; - rxr->hdr_split = TRUE; lro->ifp = adapter->ifp; } + IGB_RX_UNLOCK(rxr); return (0); + fail: - /* - * We need to clean up any buffers allocated - * so far, 'j' is the failing index. - */ - for (int i = 0; i < j; i++) { - rxbuf = &rxr->rx_buffers[i]; - if (rxbuf->m_head != NULL) { - bus_dmamap_sync(rxr->rxtag, rxbuf->map, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(rxr->rxtag, rxbuf->map); - m_freem(rxbuf->m_head); - rxbuf->m_head = NULL; - } - } - return (ENOBUFS); + igb_free_receive_ring(rxr); + IGB_RX_UNLOCK(rxr); + return (error); } /********************************************************************* @@ -3719,17 +3845,8 @@ fail: */ rxr = adapter->rx_rings; for (--i; i > 0; i--, rxr++) { - for (j = 0; j < adapter->num_rx_desc; j++) { - struct igb_rx_buffer *rxbuf; - rxbuf = &rxr->rx_buffers[j]; - if (rxbuf->m_head != NULL) { - bus_dmamap_sync(rxr->rxtag, rxbuf->map, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(rxr->rxtag, rxbuf->map); - m_freem(rxbuf->m_head); - rxbuf->m_head = NULL; - } - } + for (j = 0; j < adapter->num_rx_desc; j++) + igb_free_receive_ring(rxr); } return (ENOBUFS); @@ -3745,6 +3862,7 @@ igb_initialize_receive_units(struct adapter *adapter) { struct rx_ring *rxr = adapter->rx_rings; struct ifnet *ifp = adapter->ifp; + struct e1000_hw *hw = &adapter->hw; u32 rctl, rxcsum, psize, srrctl = 0; INIT_DEBUGOUT("igb_initialize_receive_unit: begin"); @@ -3753,8 +3871,8 @@ igb_initialize_receive_units(struct adapter *adapter) * Make sure receives are disabled while setting * up the descriptor ring */ - rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); + rctl = E1000_READ_REG(hw, E1000_RCTL); + E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); /* ** Set up for header split @@ -3791,27 +3909,27 @@ igb_initialize_receive_units(struct adapter *adapter) u64 bus_addr = rxr->rxdma.dma_paddr; u32 rxdctl; - E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(i), + E1000_WRITE_REG(hw, E1000_RDLEN(i), adapter->num_rx_desc * sizeof(struct e1000_rx_desc)); - E1000_WRITE_REG(&adapter->hw, E1000_RDBAH(i), + E1000_WRITE_REG(hw, E1000_RDBAH(i), (uint32_t)(bus_addr >> 32)); - E1000_WRITE_REG(&adapter->hw, E1000_RDBAL(i), + E1000_WRITE_REG(hw, E1000_RDBAL(i), (uint32_t)bus_addr); - E1000_WRITE_REG(&adapter->hw, E1000_SRRCTL(i), srrctl); + E1000_WRITE_REG(hw, E1000_SRRCTL(i), srrctl); /* Enable this Queue */ - rxdctl = E1000_READ_REG(&adapter->hw, E1000_RXDCTL(i)); + rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(i)); rxdctl |= E1000_RXDCTL_QUEUE_ENABLE; rxdctl &= 0xFFF00000; rxdctl |= IGB_RX_PTHRESH; rxdctl |= IGB_RX_HTHRESH << 8; rxdctl |= IGB_RX_WTHRESH << 16; - E1000_WRITE_REG(&adapter->hw, E1000_RXDCTL(i), rxdctl); + E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl); } /* ** Setup for RX MultiQueue */ - rxcsum = E1000_READ_REG(&adapter->hw, E1000_RXCSUM); + rxcsum = E1000_READ_REG(hw, E1000_RXCSUM); if (adapter->num_queues >1) { u32 random[10], mrqc, shift = 0; union igb_reta { @@ -3827,13 +3945,13 @@ igb_initialize_receive_units(struct adapter *adapter) reta.bytes[i & 3] = (i % adapter->num_queues) << shift; if ((i & 3) == 3) - E1000_WRITE_REG(&adapter->hw, + E1000_WRITE_REG(hw, E1000_RETA(i >> 2), reta.dword); } /* Now fill in hash table */ mrqc = E1000_MRQC_ENABLE_RSS_4Q; for (int i = 0; i < 10; i++) - E1000_WRITE_REG_ARRAY(&adapter->hw, + E1000_WRITE_REG_ARRAY(hw, E1000_RSSRK(0), i, random[i]); mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 | @@ -3845,7 +3963,7 @@ igb_initialize_receive_units(struct adapter *adapter) mrqc |=( E1000_MRQC_RSS_FIELD_IPV6_UDP_EX | E1000_MRQC_RSS_FIELD_IPV6_TCP_EX); - E1000_WRITE_REG(&adapter->hw, E1000_MRQC, mrqc); + E1000_WRITE_REG(hw, E1000_MRQC, mrqc); /* ** NOTE: Receive Full-Packet Checksum Offload @@ -3856,7 +3974,7 @@ igb_initialize_receive_units(struct adapter *adapter) rxcsum |= E1000_RXCSUM_PCSD; #if __FreeBSD_version >= 800000 /* For SCTP Offload */ - if ((adapter->hw.mac.type == e1000_82576) + if ((hw->mac.type == e1000_82576) && (ifp->if_capenable & IFCAP_RXCSUM)) rxcsum |= E1000_RXCSUM_CRCOFL; #endif @@ -3871,29 +3989,30 @@ igb_initialize_receive_units(struct adapter *adapter) } else rxcsum &= ~E1000_RXCSUM_TUOFL; } - E1000_WRITE_REG(&adapter->hw, E1000_RXCSUM, rxcsum); + E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum); /* Setup the Receive Control Register */ rctl &= ~(3 << E1000_RCTL_MO_SHIFT); rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | - (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); - + (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT); + /* Strip CRC bytes. */ + rctl |= E1000_RCTL_SECRC; /* Make sure VLAN Filters are off */ rctl &= ~E1000_RCTL_VFE; /* Don't store bad packets */ rctl &= ~E1000_RCTL_SBP; /* Enable Receives */ - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl); + E1000_WRITE_REG(hw, E1000_RCTL, rctl); /* * Setup the HW Rx Head and Tail Descriptor Pointers * - needs to be after enable */ for (int i = 0; i < adapter->num_queues; i++) { - E1000_WRITE_REG(&adapter->hw, E1000_RDH(i), 0); - E1000_WRITE_REG(&adapter->hw, E1000_RDT(i), + E1000_WRITE_REG(hw, E1000_RDH(i), 0); + E1000_WRITE_REG(hw, E1000_RDT(i), adapter->num_rx_desc - 1); } return; @@ -3927,48 +4046,115 @@ igb_free_receive_structures(struct adapter *adapter) static void igb_free_receive_buffers(struct rx_ring *rxr) { - struct adapter *adapter = rxr->adapter; - struct igb_rx_buffer *rx_buffer; + struct adapter *adapter = rxr->adapter; + struct igb_rx_buf *rxbuf; + int i; INIT_DEBUGOUT("free_receive_structures: begin"); - if (rxr->rx_spare_map) { - bus_dmamap_destroy(rxr->rxtag, rxr->rx_spare_map); - rxr->rx_spare_map = NULL; - } - /* Cleanup any existing buffers */ if (rxr->rx_buffers != NULL) { - rx_buffer = &rxr->rx_buffers[0]; - for (int i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) { - if (rx_buffer->m_head != NULL) { - bus_dmamap_sync(rxr->rxtag, rx_buffer->map, + for (i = 0; i < adapter->num_rx_desc; i++) { + rxbuf = &rxr->rx_buffers[i]; + if (rxbuf->m_head != NULL) { + bus_dmamap_sync(rxr->htag, rxbuf->hmap, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(rxr->rxtag, - rx_buffer->map); - m_freem(rx_buffer->m_head); - rx_buffer->m_head = NULL; - } else if (rx_buffer->map != NULL) - bus_dmamap_unload(rxr->rxtag, - rx_buffer->map); - if (rx_buffer->map != NULL) { - bus_dmamap_destroy(rxr->rxtag, - rx_buffer->map); - rx_buffer->map = NULL; + bus_dmamap_unload(rxr->htag, rxbuf->hmap); + rxbuf->m_head->m_flags |= M_PKTHDR; + m_freem(rxbuf->m_head); } + if (rxbuf->m_pack != NULL) { + bus_dmamap_sync(rxr->ptag, rxbuf->pmap, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(rxr->ptag, rxbuf->pmap); + rxbuf->m_pack->m_flags |= M_PKTHDR; + m_freem(rxbuf->m_pack); + } + rxbuf->m_head = NULL; + rxbuf->m_pack = NULL; + if (rxbuf->hmap != NULL) { + bus_dmamap_destroy(rxr->htag, rxbuf->hmap); + rxbuf->hmap = NULL; + } + if (rxbuf->pmap != NULL) { + bus_dmamap_destroy(rxr->ptag, rxbuf->pmap); + rxbuf->pmap = NULL; + } + } + if (rxr->rx_buffers != NULL) { + free(rxr->rx_buffers, M_DEVBUF); + rxr->rx_buffers = NULL; } } - if (rxr->rx_buffers != NULL) { - free(rxr->rx_buffers, M_DEVBUF); - rxr->rx_buffers = NULL; + if (rxr->htag != NULL) { + bus_dma_tag_destroy(rxr->htag); + rxr->htag = NULL; } - - if (rxr->rxtag != NULL) { - bus_dma_tag_destroy(rxr->rxtag); - rxr->rxtag = NULL; + if (rxr->ptag != NULL) { + bus_dma_tag_destroy(rxr->ptag); + rxr->ptag = NULL; } } + +static __inline void +igb_rx_discard(struct rx_ring *rxr, int i) +{ + struct adapter *adapter = rxr->adapter; + struct igb_rx_buf *rbuf; + struct mbuf *mh, *mp; + + rbuf = &rxr->rx_buffers[i]; + if (rxr->fmp != NULL) { + rxr->fmp->m_flags |= M_PKTHDR; + m_freem(rxr->fmp); + rxr->fmp = NULL; + rxr->lmp = NULL; + } + + mh = rbuf->m_head; + mp = rbuf->m_pack; + + /* Reuse loaded DMA map and just update mbuf chain */ + mh->m_len = MHLEN; + mh->m_flags |= M_PKTHDR; + mh->m_next = NULL; + + mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz; + mp->m_data = mp->m_ext.ext_buf; + mp->m_next = NULL; + return; +} + +static __inline void +igb_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype) +{ + + /* + * ATM LRO is only for IPv4/TCP packets and TCP checksum of the packet + * should be computed by hardware. Also it should not have VLAN tag in + * ethernet header. + */ + if (rxr->lro_enabled && + (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 && + (ptype & E1000_RXDADV_PKTTYPE_ETQF) == 0 && + (ptype & (E1000_RXDADV_PKTTYPE_IPV4 | E1000_RXDADV_PKTTYPE_TCP)) == + (E1000_RXDADV_PKTTYPE_IPV4 | E1000_RXDADV_PKTTYPE_TCP) && + (m->m_pkthdr.csum_flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) == + (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) { + /* + * Send to the stack if: + ** - LRO not enabled, or + ** - no LRO resources, or + ** - lro enqueue fails + */ + if (rxr->lro.lro_cnt != 0) + if (tcp_lro_rx(&rxr->lro, m, 0) == 0) + return; + } + (*ifp->if_input)(ifp, m); +} + /********************************************************************* * * This routine executes in interrupt context. It replenishes @@ -3981,48 +4167,57 @@ igb_free_receive_buffers(struct rx_ring *rxr) * Return TRUE if more to clean, FALSE otherwise *********************************************************************/ static bool -igb_rxeof(struct rx_ring *rxr, int count) +igb_rxeof(struct igb_queue *que, int count) { - struct adapter *adapter = rxr->adapter; - struct ifnet *ifp; + struct adapter *adapter = que->adapter; + struct rx_ring *rxr = que->rxr; + struct ifnet *ifp = adapter->ifp; struct lro_ctrl *lro = &rxr->lro; struct lro_entry *queued; - int i; - u32 staterr; + int i, processed = 0; + u32 ptype, staterr = 0; union e1000_adv_rx_desc *cur; - IGB_RX_LOCK(rxr); - ifp = adapter->ifp; - i = rxr->next_to_check; - cur = &rxr->rx_base[i]; - staterr = cur->wb.upper.status_error; - - if (!(staterr & E1000_RXD_STAT_DD)) { - IGB_RX_UNLOCK(rxr); - return FALSE; - } - - /* Sync the ring */ + /* Sync the ring. */ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, - BUS_DMASYNC_POSTREAD); + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); /* Main clean loop */ - while ((staterr & E1000_RXD_STAT_DD) && - (count != 0) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) { - struct mbuf *sendmp, *mh, *mp; - u16 hlen, plen, hdr, ptype, len_adj, vtag; - u8 dopayload, accept_frame, eop; + for (i = rxr->next_to_check; count != 0;) { + struct mbuf *sendmp, *mh, *mp; + struct igb_rx_buf *rxbuf; + u16 hlen, plen, hdr, vtag; + bool eop = FALSE; - accept_frame = 1; - hlen = plen = len_adj = vtag = 0; + cur = &rxr->rx_base[i]; + staterr = le32toh(cur->wb.upper.status_error); + if ((staterr & E1000_RXD_STAT_DD) == 0) + break; + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; + count--; sendmp = mh = mp = NULL; - ptype = (u16)(cur->wb.lower.lo_dword.data >> 4); + cur->wb.upper.status_error = 0; + rxbuf = &rxr->rx_buffers[i]; + plen = le16toh(cur->wb.upper.length); + ptype = le32toh(cur->wb.lower.lo_dword.data) & IGB_PKTTYPE_MASK; + vtag = le16toh(cur->wb.upper.vlan); + hdr = le16toh(cur->wb.lower.lo_dword.hs_rss.hdr_info); + eop = ((staterr & E1000_RXD_STAT_EOP) == E1000_RXD_STAT_EOP); - /* Sync the buffers */ - bus_dmamap_sync(rxr->rxtag, rxr->rx_buffers[i].map, - BUS_DMASYNC_POSTREAD); + /* Make sure all segments of a bad packet are discarded */ + if (((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) != 0) || + (rxr->discard)) { + ifp->if_ierrors++; + ++rxr->rx_discarded; + if (!eop) /* Catch subsequent segs */ + rxr->discard = TRUE; + else + rxr->discard = FALSE; + igb_rx_discard(rxr, i); + goto next_desc; + } /* ** The way the hardware is configured to @@ -4035,35 +4230,28 @@ igb_rxeof(struct rx_ring *rxr, int count) ** packet spans multiple descriptors, in that ** case only the first header is valid. */ - if ((rxr->hdr_split) && (rxr->fmp == NULL)){ - hdr = le16toh(cur-> - wb.lower.lo_dword.hs_rss.hdr_info); + if (rxr->hdr_split && rxr->fmp == NULL) { hlen = (hdr & E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT; if (hlen > IGB_HDR_BUF) hlen = IGB_HDR_BUF; - plen = le16toh(cur->wb.upper.length); /* Handle the header mbuf */ mh = rxr->rx_buffers[i].m_head; mh->m_len = hlen; - dopayload = IGB_CLEAN_HEADER; + /* clear buf info for refresh */ + rxbuf->m_head = NULL; /* ** Get the payload length, this ** could be zero if its a small ** packet. */ - if (plen) { + if (plen > 0) { mp = rxr->rx_buffers[i].m_pack; mp->m_len = plen; - mp->m_next = NULL; - mp->m_flags &= ~M_PKTHDR; mh->m_next = mp; - mh->m_flags |= M_PKTHDR; - dopayload = IGB_CLEAN_BOTH; + /* clear buf info for refresh */ + rxbuf->m_pack = NULL; rxr->rx_split_packets++; - } else { /* small packets */ - mh->m_flags &= ~M_PKTHDR; - mh->m_next = NULL; } } else { /* @@ -4072,179 +4260,91 @@ igb_rxeof(struct rx_ring *rxr, int count) ** split packet. */ mh = rxr->rx_buffers[i].m_pack; - mh->m_flags |= M_PKTHDR; - mh->m_len = le16toh(cur->wb.upper.length); - dopayload = IGB_CLEAN_PAYLOAD; + mh->m_len = plen; + /* clear buf info for refresh */ + rxbuf->m_pack = NULL; } - if (staterr & E1000_RXD_STAT_EOP) { - count--; - eop = 1; - /* - ** Strip CRC and account for frag - */ - if (mp) { - if (mp->m_len < ETHER_CRC_LEN) { - /* a frag, how much is left? */ - len_adj = ETHER_CRC_LEN - mp->m_len; - mp->m_len = 0; - } else - mp->m_len -= ETHER_CRC_LEN; - } else { /* not split */ - if (mh->m_len < ETHER_CRC_LEN) { - len_adj = ETHER_CRC_LEN - mh->m_len; - mh->m_len = 0; - } else - mh->m_len -= ETHER_CRC_LEN; - } - } else - eop = 0; + ++processed; /* So we know when to refresh */ - if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) - accept_frame = 0; -#ifdef IGB_IEEE1588 - This linux code needs to be converted to work here - ----------------------------------------------------- - if (unlikely(staterr & E1000_RXD_STAT_TS)) { - u64 regval; - u64 ns; -// Create an mtag and set it up - struct skb_shared_hwtstamps *shhwtstamps = - skb_hwtstamps(skb); - - rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID), - "igb: no RX time stamp available for time stamped packet"); - regval = rd32(E1000_RXSTMPL); - regval |= (u64)rd32(E1000_RXSTMPH) << 32; -// Do time conversion from the register - ns = timecounter_cyc2time(&adapter->clock, regval); - clocksync_update(&adapter->sync, ns); - memset(shhwtstamps, 0, sizeof(*shhwtstamps)); - shhwtstamps->hwtstamp = ns_to_ktime(ns); - shhwtstamps->syststamp = - clocksync_hw2sys(&adapter->sync, ns); - } -#endif - if (accept_frame) { - /* - ** get_buf will overwrite the writeback - ** descriptor so save the VLAN tag now. - */ - vtag = le16toh(cur->wb.upper.vlan); - if (igb_get_buf(rxr, i, dopayload) != 0) { - ifp->if_iqdrops++; - goto discard; - } - /* Initial frame - setup */ - if (rxr->fmp == NULL) { - mh->m_flags |= M_PKTHDR; - mh->m_pkthdr.len = mh->m_len; - rxr->fmp = mh; /* Store the first mbuf */ - rxr->lmp = mh; - if (mp) { /* Add payload if split */ - mh->m_pkthdr.len += mp->m_len; - rxr->lmp = mh->m_next; - } - } else { - /* Chain mbuf's together */ - mh->m_flags &= ~M_PKTHDR; - rxr->lmp->m_next = mh; - rxr->lmp = rxr->lmp->m_next; - rxr->fmp->m_pkthdr.len += mh->m_len; - /* Adjust for CRC frag */ - if (len_adj) { - rxr->lmp->m_len -= len_adj; - rxr->fmp->m_pkthdr.len -= len_adj; - } - } - - if (eop) { - bool sctp = ((ptype & 0x40) != 0); - rxr->fmp->m_pkthdr.rcvif = ifp; - ifp->if_ipackets++; - rxr->rx_packets++; - /* capture data for AIM */ - rxr->bytes += rxr->fmp->m_pkthdr.len; - rxr->rx_bytes += rxr->fmp->m_pkthdr.len; - - igb_rx_checksum(staterr, rxr->fmp, sctp); - if (staterr & E1000_RXD_STAT_VP) { - rxr->fmp->m_pkthdr.ether_vtag = vtag; - rxr->fmp->m_flags |= M_VLANTAG; - } -#if __FreeBSD_version >= 800000 - rxr->fmp->m_pkthdr.flowid = curcpu; - rxr->fmp->m_flags |= M_FLOWID; -#endif - sendmp = rxr->fmp; - rxr->fmp = NULL; - rxr->lmp = NULL; + /* Initial frame - setup */ + if (rxr->fmp == NULL) { + mh->m_pkthdr.len = mh->m_len; + /* Store the first mbuf */ + rxr->fmp = mh; + rxr->lmp = mh; + if (mp != NULL) { + /* Add payload if split */ + mh->m_pkthdr.len += mp->m_len; + rxr->lmp = mh->m_next; } } else { - ifp->if_ierrors++; -discard: - /* Reuse loaded DMA map and just update mbuf chain */ - if (hlen) { - mh = rxr->rx_buffers[i].m_head; - mh->m_len = MHLEN; - mh->m_next = NULL; - } - mp = rxr->rx_buffers[i].m_pack; - mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz; - mp->m_data = mp->m_ext.ext_buf; - mp->m_next = NULL; - if (adapter->max_frame_size <= - (MCLBYTES - ETHER_ALIGN)) - m_adj(mp, ETHER_ALIGN); - if (rxr->fmp != NULL) { - /* handles the whole chain */ - m_freem(rxr->fmp); - rxr->fmp = NULL; - rxr->lmp = NULL; - } - sendmp = NULL; + /* Chain mbuf's together */ + rxr->lmp->m_next = mh; + rxr->lmp = rxr->lmp->m_next; + rxr->fmp->m_pkthdr.len += mh->m_len; } + if (eop) { + rxr->fmp->m_pkthdr.rcvif = ifp; + ifp->if_ipackets++; + rxr->rx_packets++; + /* capture data for AIM */ + rxr->packets++; + rxr->bytes += rxr->fmp->m_pkthdr.len; + rxr->rx_bytes += rxr->fmp->m_pkthdr.len; + + if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) + igb_rx_checksum(staterr, rxr->fmp, ptype); + + if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 && + (staterr & E1000_RXD_STAT_VP) != 0) { + rxr->fmp->m_pkthdr.ether_vtag = vtag; + rxr->fmp->m_flags |= M_VLANTAG; + } +#if __FreeBSD_version >= 800000 + rxr->fmp->m_pkthdr.flowid = que->msix; + rxr->fmp->m_flags |= M_FLOWID; +#endif + sendmp = rxr->fmp; + /* Make sure to set M_PKTHDR. */ + sendmp->m_flags |= M_PKTHDR; + rxr->fmp = NULL; + rxr->lmp = NULL; + } + +next_desc: bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - rxr->last_cleaned = i; /* For updating tail */ - /* Advance our pointers to the next descriptor. */ if (++i == adapter->num_rx_desc) i = 0; - /* - ** Note that we hold the RX lock thru - ** the following call so this ring's - ** next_to_check is not gonna change. + ** Send to the stack or LRO */ - if (sendmp != NULL) { - /* - ** Send to the stack if: - ** - LRO not enabled, or - ** - no LRO resources, or - ** - lro enqueue fails - */ - if ((!rxr->lro_enabled) || - ((!lro->lro_cnt) || (tcp_lro_rx(lro, sendmp, 0)))) - (*ifp->if_input)(ifp, sendmp); - } + if (sendmp != NULL) + igb_rx_input(rxr, ifp, sendmp, ptype); - /* Get the next descriptor */ - cur = &rxr->rx_base[i]; - staterr = cur->wb.upper.status_error; + /* Every 8 descriptors we go to refresh mbufs */ + if (processed == 8) { + igb_refresh_mbufs(rxr, i); + processed = 0; + } } - rxr->next_to_check = i; - /* Advance the E1000's Receive Queue #0 "Tail Pointer". */ - E1000_WRITE_REG(&adapter->hw, E1000_RDT(rxr->me), rxr->last_cleaned); + /* Catch any remainders */ + if (processed != 0) { + igb_refresh_mbufs(rxr, i); + processed = 0; + } + + rxr->next_to_check = i; /* * Flush any outstanding LRO work */ - while (!SLIST_EMPTY(&lro->lro_active)) { - queued = SLIST_FIRST(&lro->lro_active); + while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) { SLIST_REMOVE_HEAD(&lro->lro_active, next); tcp_lro_flush(lro, queued); } @@ -4255,15 +4355,12 @@ discard: ** We still have cleaning to do? ** Schedule another interrupt if so. */ - if (staterr & E1000_RXD_STAT_DD) { - E1000_WRITE_REG(&adapter->hw, E1000_EICS, rxr->eims); - return TRUE; - } + if ((staterr & E1000_RXD_STAT_DD) != 0) + return (TRUE); - return FALSE; + return (FALSE); } - /********************************************************************* * * Verify that the hardware indicated that the checksum is valid. @@ -4272,10 +4369,11 @@ discard: * *********************************************************************/ static void -igb_rx_checksum(u32 staterr, struct mbuf *mp, bool sctp) +igb_rx_checksum(u32 staterr, struct mbuf *mp, u32 ptype) { u16 status = (u16)staterr; u8 errors = (u8) (staterr >> 24); + int sctp; /* Ignore Checksum bit is set */ if (status & E1000_RXD_STAT_IXSM) { @@ -4283,6 +4381,11 @@ igb_rx_checksum(u32 staterr, struct mbuf *mp, bool sctp) return; } + if ((ptype & E1000_RXDADV_PKTTYPE_ETQF) == 0 && + (ptype & E1000_RXDADV_PKTTYPE_SCTP) != 0) + sctp = 1; + else + sctp = 0; if (status & E1000_RXD_STAT_IPCS) { /* Did it pass? */ if (!(errors & E1000_RXD_ERR_IPE)) { @@ -4302,7 +4405,7 @@ igb_rx_checksum(u32 staterr, struct mbuf *mp, bool sctp) /* Did it pass? */ if (!(errors & E1000_RXD_ERR_TCPE)) { mp->m_pkthdr.csum_flags |= type; - if (!sctp) + if (sctp == 0) mp->m_pkthdr.csum_data = htons(0xffff); } } @@ -4522,7 +4625,7 @@ igb_is_valid_ether_addr(uint8_t *addr) /* * Enable PCI Wake On Lan capability */ -void +static void igb_enable_wakeup(device_t dev) { u16 cap, status; @@ -4543,6 +4646,21 @@ igb_enable_wakeup(device_t dev) return; } +static void +igb_led_func(void *arg, int onoff) +{ + struct adapter *adapter = arg; + + IGB_CORE_LOCK(adapter); + if (onoff) { + e1000_setup_led(&adapter->hw); + e1000_led_on(&adapter->hw); + } else { + e1000_led_off(&adapter->hw); + e1000_cleanup_led(&adapter->hw); + } + IGB_CORE_UNLOCK(adapter); +} /********************************************************************** * @@ -4650,6 +4768,7 @@ static void igb_print_debug_info(struct adapter *adapter) { device_t dev = adapter->dev; + struct igb_queue *que = adapter->queues; struct rx_ring *rxr = adapter->rx_rings; struct tx_ring *txr = adapter->tx_rings; uint8_t *hw_addr = adapter->hw.hw_addr; @@ -4672,16 +4791,19 @@ igb_print_debug_info(struct adapter *adapter) adapter->hw.fc.high_water, adapter->hw.fc.low_water); - for (int i = 0; i < adapter->num_queues; i++, txr++) { - device_printf(dev, "Queue(%d) tdh = %d, tdt = %d\n", i, + for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) { + device_printf(dev, "Queue(%d) tdh = %d, tdt = %d ", i, E1000_READ_REG(&adapter->hw, E1000_TDH(i)), E1000_READ_REG(&adapter->hw, E1000_TDT(i))); + device_printf(dev, "rdh = %d, rdt = %d\n", + E1000_READ_REG(&adapter->hw, E1000_RDH(i)), + E1000_READ_REG(&adapter->hw, E1000_RDT(i))); device_printf(dev, "TX(%d) no descriptors avail event = %lld\n", txr->me, (long long)txr->no_desc_avail); - device_printf(dev, "TX(%d) MSIX IRQ Handled = %lld\n", txr->me, - (long long)txr->tx_irq); - device_printf(dev, "TX(%d) Packets sent = %lld\n", txr->me, - (long long)txr->tx_packets); + device_printf(dev, "TX(%d) Packets sent = %lld\n", + txr->me, (long long)txr->tx_packets); + device_printf(dev, "RX(%d) Packets received = %lld ", + rxr->me, (long long)rxr->rx_packets); } for (int i = 0; i < adapter->num_queues; i++, rxr++) { @@ -4691,20 +4813,20 @@ igb_print_debug_info(struct adapter *adapter) E1000_READ_REG(&adapter->hw, E1000_RDT(i))); device_printf(dev, "RX(%d) Packets received = %lld\n", rxr->me, (long long)rxr->rx_packets); - device_printf(dev, "RX(%d) Split Packets = %lld\n", rxr->me, + device_printf(dev, " Split Packets = %lld ", (long long)rxr->rx_split_packets); - device_printf(dev, "RX(%d) Byte count = %lld\n", rxr->me, + device_printf(dev, " Byte count = %lld\n", (long long)rxr->rx_bytes); - device_printf(dev, "RX(%d) MSIX IRQ Handled = %lld\n", rxr->me, - (long long)rxr->rx_irq); - device_printf(dev,"RX(%d) LRO Queued= %d\n", - rxr->me, lro->lro_queued); - device_printf(dev,"RX(%d) LRO Flushed= %d\n", - rxr->me, lro->lro_flushed); + device_printf(dev,"RX(%d) LRO Queued= %d ", + i, lro->lro_queued); + device_printf(dev,"LRO Flushed= %d\n",lro->lro_flushed); } - device_printf(dev, "LINK MSIX IRQ Handled = %u\n", adapter->link_irq); + for (int i = 0; i < adapter->num_queues; i++, que++) + device_printf(dev,"QUE(%d) IRQs = %llx\n", + i, (long long)que->irqs); + device_printf(dev, "LINK MSIX IRQ Handled = %u\n", adapter->link_irq); device_printf(dev, "Mbuf defrag failed = %ld\n", adapter->mbuf_defrag_failed); device_printf(dev, "Std mbuf header failed = %ld\n", @@ -4857,173 +4979,3 @@ igb_add_rx_process_limit(struct adapter *adapter, const char *name, SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); } - -#ifdef IGB_IEEE1588 -/* -** igb_hwtstamp_ioctl - control hardware time stamping -** -** Outgoing time stamping can be enabled and disabled. Play nice and -** disable it when requested, although it shouldn't case any overhead -** when no packet needs it. At most one packet in the queue may be -** marked for time stamping, otherwise it would be impossible to tell -** for sure to which packet the hardware time stamp belongs. -** -** Incoming time stamping has to be configured via the hardware -** filters. Not all combinations are supported, in particular event -** type has to be specified. Matching the kind of event packet is -** not supported, with the exception of "all V2 events regardless of -** level 2 or 4". -** -*/ -static int -igb_hwtstamp_ioctl(struct adapter *adapter, struct ifreq *ifr) -{ - struct e1000_hw *hw = &adapter->hw; - struct hwtstamp_ctrl *config; - u32 tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED; - u32 tsync_rx_ctl_bit = E1000_TSYNCRXCTL_ENABLED; - u32 tsync_rx_ctl_type = 0; - u32 tsync_rx_cfg = 0; - int is_l4 = 0; - int is_l2 = 0; - u16 port = 319; /* PTP */ - u32 regval; - - config = (struct hwtstamp_ctrl *) ifr->ifr_data; - - /* reserved for future extensions */ - if (config->flags) - return (EINVAL); - - switch (config->tx_type) { - case HWTSTAMP_TX_OFF: - tsync_tx_ctl_bit = 0; - break; - case HWTSTAMP_TX_ON: - tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED; - break; - default: - return (ERANGE); - } - - switch (config->rx_filter) { - case HWTSTAMP_FILTER_NONE: - tsync_rx_ctl_bit = 0; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: - case HWTSTAMP_FILTER_ALL: - /* - * register TSYNCRXCFG must be set, therefore it is not - * possible to time stamp both Sync and Delay_Req messages - * => fall back to time stamping all packets - */ - tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_ALL; - config->rx_filter = HWTSTAMP_FILTER_ALL; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: - tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1; - tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE; - is_l4 = 1; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: - tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1; - tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE; - is_l4 = 1; - break; - case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: - tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2; - tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE; - is_l2 = 1; - is_l4 = 1; - config->rx_filter = HWTSTAMP_FILTER_SOME; - break; - case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: - case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: - tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2; - tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE; - is_l2 = 1; - is_l4 = 1; - config->rx_filter = HWTSTAMP_FILTER_SOME; - break; - case HWTSTAMP_FILTER_PTP_V2_EVENT: - case HWTSTAMP_FILTER_PTP_V2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: - tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_EVENT_V2; - config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; - is_l2 = 1; - break; - default: - return -ERANGE; - } - - /* enable/disable TX */ - regval = E1000_READ_REG(hw, E1000_TSYNCTXCTL); - regval = (regval & ~E1000_TSYNCTXCTL_ENABLED) | tsync_tx_ctl_bit; - E1000_WRITE_REG(hw, E1000_TSYNCTXCTL, regval); - - /* enable/disable RX, define which PTP packets are time stamped */ - regval = E1000_READ_REG(hw, E1000_TSYNCRXCTL); - regval = (regval & ~E1000_TSYNCRXCTL_ENABLED) | tsync_rx_ctl_bit; - regval = (regval & ~0xE) | tsync_rx_ctl_type; - E1000_WRITE_REG(hw, E1000_TSYNCRXCTL, regval); - E1000_WRITE_REG(hw, E1000_TSYNCRXCFG, tsync_rx_cfg); - - /* - * Ethertype Filter Queue Filter[0][15:0] = 0x88F7 - * (Ethertype to filter on) - * Ethertype Filter Queue Filter[0][26] = 0x1 (Enable filter) - * Ethertype Filter Queue Filter[0][30] = 0x1 (Enable Timestamping) - */ - E1000_WRITE_REG(hw, E1000_ETQF0, is_l2 ? 0x440088f7 : 0); - - /* L4 Queue Filter[0]: only filter by source and destination port */ - E1000_WRITE_REG(hw, E1000_SPQF0, htons(port)); - E1000_WRITE_REG(hw, E1000_IMIREXT(0), is_l4 ? - ((1<<12) | (1<<19) /* bypass size and control flags */) : 0); - E1000_WRITE_REG(hw, E1000_IMIR(0), is_l4 ? - (htons(port) - | (0<<16) /* immediate interrupt disabled */ - | 0 /* (1<<17) bit cleared: do not bypass - destination port check */) - : 0); - E1000_WRITE_REG(hw, E1000_FTQF0, is_l4 ? - (0x11 /* UDP */ - | (1<<15) /* VF not compared */ - | (1<<27) /* Enable Timestamping */ - | (7<<28) /* only source port filter enabled, - source/target address and protocol - masked */) - : ((1<<15) | (15<<28) /* all mask bits set = filter not - enabled */)); - - wrfl(); - - adapter->hwtstamp_ctrl = config; - - /* clear TX/RX time stamp registers, just to be sure */ - regval = E1000_READ_REG(hw, E1000_TXSTMPH); - regval = E1000_READ_REG(hw, E1000_RXSTMPH); - - return (error); -} - -/* -** igb_read_clock - read raw cycle counter (to be used by time counter) -*/ -static cycle_t igb_read_clock(const struct cyclecounter *tc) -{ - struct igb_adapter *adapter = - container_of(tc, struct igb_adapter, cycles); - struct e1000_hw *hw = &adapter->hw; - u64 stamp; - - stamp = E1000_READ_REG(hw, E1000_SYSTIML); - stamp |= (u64)E1000_READ_REG(hw, E1000_SYSTIMH) << 32ULL; - - return (stamp); -} - -#endif /* IGB_IEEE1588 */ diff --git a/sys/dev/e1000/if_igb.h b/sys/dev/e1000/if_igb.h index ddc4d8ae9e6..28bcc91caa0 100644 --- a/sys/dev/e1000/if_igb.h +++ b/sys/dev/e1000/if_igb.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2009, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -47,8 +47,8 @@ * desscriptors should meet the following condition. * (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0 */ -#define IGB_MIN_TXD 80 -#define IGB_DEFAULT_TXD 256 +#define IGB_MIN_TXD 256 +#define IGB_DEFAULT_TXD 1024 #define IGB_MAX_TXD 4096 /* @@ -62,8 +62,8 @@ * desscriptors should meet the following condition. * (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0 */ -#define IGB_MIN_RXD 80 -#define IGB_DEFAULT_RXD 256 +#define IGB_MIN_RXD 256 +#define IGB_DEFAULT_RXD 1024 #define IGB_MAX_RXD 4096 /* @@ -128,7 +128,7 @@ /* * This parameter controls the duration of transmit watchdog timer. */ -#define IGB_TX_TIMEOUT 5 /* set to 5 seconds */ +#define IGB_WATCHDOG (10 * hz) /* * This parameter controls when the driver calls the routine to reclaim @@ -173,10 +173,16 @@ #define IGB_SMARTSPEED_DOWNSHIFT 3 #define IGB_SMARTSPEED_MAX 15 #define IGB_MAX_LOOP 10 -#define IGB_RX_PTHRESH 16 + +#define IGB_RX_PTHRESH (hw->mac.type <= e1000_82576 ? 16 : 8) #define IGB_RX_HTHRESH 8 #define IGB_RX_WTHRESH 1 +#define IGB_TX_PTHRESH 8 +#define IGB_TX_HTHRESH 1 +#define IGB_TX_WTHRESH ((hw->mac.type == e1000_82576 && \ + adapter->msix_mem) ? 1 : 16) + #define MAX_NUM_MULTICAST_ADDRESSES 128 #define PCI_ANY_ID (~0U) #define ETHER_ALIGN 2 @@ -225,6 +231,7 @@ #define IGB_TSO_SIZE (65535 + sizeof(struct ether_vlan_header)) #define IGB_TSO_SEG_SIZE 4096 /* Max dma segment size */ #define IGB_HDR_BUF 128 +#define IGB_PKTTYPE_MASK 0x0000FFF0 #define ETH_ZLEN 60 #define ETH_ADDR_LEN 6 @@ -235,17 +242,16 @@ #define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP) #endif -/* Header split codes for get_buf */ -#define IGB_CLEAN_HEADER 1 -#define IGB_CLEAN_PAYLOAD 2 -#define IGB_CLEAN_BOTH 3 +/* Define the starting Interrupt rate per Queue */ +#define IGB_INTS_PER_SEC 8000 +#define IGB_DEFAULT_ITR 1000000000/(IGB_INTS_PER_SEC * 256) + + +/* Header split codes for get_buf */ +#define IGB_CLEAN_HEADER 0x01 +#define IGB_CLEAN_PAYLOAD 0x02 +#define IGB_CLEAN_BOTH (IGB_CLEAN_HEADER | IGB_CLEAN_PAYLOAD) -/* - * Interrupt Moderation parameters - */ -#define IGB_LOW_LATENCY 128 -#define IGB_AVE_LATENCY 450 -#define IGB_BULK_LATENCY 1200 #define IGB_LINK_ITR 2000 /* Precision Time Sync (IEEE 1588) defines */ @@ -268,18 +274,33 @@ struct igb_dma_alloc { /* - * Transmit ring: one per tx queue +** Driver queue struct: this is the interrupt container +** for the associated tx and rx ring. +*/ +struct igb_queue { + struct adapter *adapter; + u32 msix; /* This queue's MSIX vector */ + u32 eims; /* This queue's EIMS bit */ + u32 eitr_setting; + struct resource *res; + void *tag; + struct tx_ring *txr; + struct rx_ring *rxr; + struct task que_task; + struct taskqueue *tq; + u64 irqs; +}; + +/* + * Transmit ring: one per queue */ struct tx_ring { struct adapter *adapter; u32 me; - u32 msix; /* This ring's MSIX vector */ - u32 eims; /* This ring's EIMS bit */ struct mtx tx_mtx; char mtx_name[16]; - struct igb_dma_alloc txdma; /* bus_dma glue for tx desc */ + struct igb_dma_alloc txdma; struct e1000_tx_desc *tx_base; - struct task tx_task; /* cleanup tasklet */ u32 next_avail_desc; u32 next_to_clean; volatile u16 tx_avail; @@ -287,37 +308,36 @@ struct tx_ring { #if __FreeBSD_version >= 800000 struct buf_ring *br; #endif - bus_dma_tag_t txtag; /* dma tag for tx */ - struct resource *res; - void *tag; + bus_dma_tag_t txtag; - u32 watchdog_timer; + u32 bytes; + u32 packets; + + bool watchdog_check; + int watchdog_time; u64 no_desc_avail; - u64 tx_irq; u64 tx_packets; }; /* - * Receive ring: one per rx queue + * Receive ring: one per queue */ struct rx_ring { struct adapter *adapter; u32 me; - u32 msix; /* This ring's MSIX vector */ - u32 eims; /* This ring's EIMS bit */ - struct igb_dma_alloc rxdma; /* bus_dma glue for tx desc */ + struct igb_dma_alloc rxdma; union e1000_adv_rx_desc *rx_base; struct lro_ctrl lro; bool lro_enabled; bool hdr_split; - struct task rx_task; /* cleanup tasklet */ + bool discard; struct mtx rx_mtx; char mtx_name[16]; - u32 last_cleaned; + u32 next_to_refresh; u32 next_to_check; - struct igb_rx_buffer *rx_buffers; - bus_dma_tag_t rxtag; /* dma tag for tx */ - bus_dmamap_t rx_spare_map; + struct igb_rx_buf *rx_buffers; + bus_dma_tag_t htag; /* dma tag for rx head */ + bus_dma_tag_t ptag; /* dma tag for rx packet */ /* * First/last mbuf pointers, for * collecting multisegment RX packets. @@ -326,14 +346,11 @@ struct rx_ring { struct mbuf *lmp; u32 bytes; - u32 eitr_setting; - - struct resource *res; - void *tag; + u32 packets; /* Soft stats */ - u64 rx_irq; u64 rx_split_packets; + u64 rx_discarded; u64 rx_packets; u64 rx_bytes; }; @@ -342,9 +359,9 @@ struct adapter { struct ifnet *ifp; struct e1000_hw hw; - /* FreeBSD operating-system-specific structures. */ struct e1000_osdep osdep; struct device *dev; + struct cdev *led_dev; struct resource *pci_mem; struct resource *msix_mem; @@ -354,6 +371,7 @@ struct adapter { int linkvec; int link_mask; + struct task link_task; int link_irq; struct ifmedia media; @@ -364,9 +382,8 @@ struct adapter { int min_frame_size; struct mtx core_mtx; int igb_insert_vlan_header; - struct task link_task; struct task rxtx_task; - struct taskqueue *tq; /* private task queue */ + struct taskqueue *tq; /* adapter task queue */ u16 num_queues; eventhandler_tag vlan_attach; @@ -383,12 +400,14 @@ struct adapter { u16 link_duplex; u32 smartspeed; + /* Interface queues */ + struct igb_queue *queues; + /* * Transmit rings */ struct tx_ring *tx_rings; u16 num_tx_desc; - u32 txd_cmd; /* * Receive rings @@ -445,25 +464,29 @@ struct igb_tx_buffer { bus_dmamap_t map; /* bus_dma map for packet */ }; -struct igb_rx_buffer { +struct igb_rx_buf { struct mbuf *m_head; struct mbuf *m_pack; - bus_dmamap_t map; /* bus_dma map for packet */ + bus_dmamap_t hmap; /* bus_dma map for header */ + bus_dmamap_t pmap; /* bus_dma map for packet */ }; #define IGB_CORE_LOCK_INIT(_sc, _name) \ mtx_init(&(_sc)->core_mtx, _name, "IGB Core Lock", MTX_DEF) #define IGB_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx) -#define IGB_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx) -#define IGB_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx) #define IGB_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx) -#define IGB_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) -#define IGB_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx) -#define IGB_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx) #define IGB_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx) -#define IGB_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) -#define IGB_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx) #define IGB_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED) + +#define IGB_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx) +#define IGB_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) +#define IGB_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) +#define IGB_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx) +#define IGB_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED) + +#define IGB_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx) +#define IGB_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx) +#define IGB_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx) #define IGB_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED) #endif /* _IGB_H_DEFINED_ */ diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c new file mode 100644 index 00000000000..cf71f2bb74b --- /dev/null +++ b/sys/dev/e1000/if_lem.c @@ -0,0 +1,4706 @@ +/****************************************************************************** + + Copyright (c) 2001-2010, Intel Corporation + 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. + + 3. Neither the name of the Intel 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. + +******************************************************************************/ +/*$FreeBSD$*/ + +#ifdef HAVE_KERNEL_OPTION_HEADERS +#include "opt_device_polling.h" +#include "opt_inet.h" +#endif + +#include +#include +#if __FreeBSD_version >= 800000 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if __FreeBSD_version >= 700029 +#include +#endif +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "e1000_api.h" +#include "if_lem.h" + +/********************************************************************* + * Set this to one to display debug statistics + *********************************************************************/ +int lem_display_debug_stats = 0; + +/********************************************************************* + * Legacy Em Driver version: + *********************************************************************/ +char lem_driver_version[] = "1.0.0"; + + +/********************************************************************* + * PCI Device ID Table + * + * Used by probe to select devices to load on + * Last field stores an index into e1000_strings + * Last entry must be all 0s + * + * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index } + *********************************************************************/ + +static em_vendor_info_t lem_vendor_info_array[] = +{ + /* Intel(R) PRO/1000 Network Connection */ + { 0x8086, E1000_DEV_ID_82540EM, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82540EM_LOM, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82540EP, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82540EP_LOM, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82540EP_LP, PCI_ANY_ID, PCI_ANY_ID, 0}, + + { 0x8086, E1000_DEV_ID_82541EI, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82541ER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82541ER_LOM, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82541EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82541GI, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82541GI_LF, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82541GI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0}, + + { 0x8086, E1000_DEV_ID_82542, PCI_ANY_ID, PCI_ANY_ID, 0}, + + { 0x8086, E1000_DEV_ID_82543GC_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82543GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + + { 0x8086, E1000_DEV_ID_82544EI_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82544EI_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82544GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82544GC_LOM, PCI_ANY_ID, PCI_ANY_ID, 0}, + + { 0x8086, E1000_DEV_ID_82545EM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82545EM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82545GM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82545GM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82545GM_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, + + { 0x8086, E1000_DEV_ID_82546EB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82546EB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82546EB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82546GB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82546GB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82546GB_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82546GB_PCIE, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3, + PCI_ANY_ID, PCI_ANY_ID, 0}, + + { 0x8086, E1000_DEV_ID_82547EI, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82547EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82547GI, PCI_ANY_ID, PCI_ANY_ID, 0}, + /* required last entry */ + { 0, 0, 0, 0, 0} +}; + +/********************************************************************* + * Table of branding strings for all supported NICs. + *********************************************************************/ + +static char *lem_strings[] = { + "Intel(R) PRO/1000 Legacy Network Connection" +}; + +/********************************************************************* + * Function prototypes + *********************************************************************/ +static int lem_probe(device_t); +static int lem_attach(device_t); +static int lem_detach(device_t); +static int lem_shutdown(device_t); +static int lem_suspend(device_t); +static int lem_resume(device_t); +static void lem_start(struct ifnet *); +static void lem_start_locked(struct ifnet *ifp); +#if __FreeBSD_version >= 800000 +static int lem_mq_start(struct ifnet *, struct mbuf *); +static int lem_mq_start_locked(struct ifnet *, struct mbuf *); +static void lem_qflush(struct ifnet *); +#endif +static int lem_ioctl(struct ifnet *, u_long, caddr_t); +static void lem_init(void *); +static void lem_init_locked(struct adapter *); +static void lem_stop(void *); +static void lem_media_status(struct ifnet *, struct ifmediareq *); +static int lem_media_change(struct ifnet *); +static void lem_identify_hardware(struct adapter *); +static int lem_allocate_pci_resources(struct adapter *); +static int lem_allocate_irq(struct adapter *adapter); +static void lem_free_pci_resources(struct adapter *); +static void lem_local_timer(void *); +static int lem_hardware_init(struct adapter *); +static void lem_setup_interface(device_t, struct adapter *); +static void lem_setup_transmit_structures(struct adapter *); +static void lem_initialize_transmit_unit(struct adapter *); +static int lem_setup_receive_structures(struct adapter *); +static void lem_initialize_receive_unit(struct adapter *); +static void lem_enable_intr(struct adapter *); +static void lem_disable_intr(struct adapter *); +static void lem_free_transmit_structures(struct adapter *); +static void lem_free_receive_structures(struct adapter *); +static void lem_update_stats_counters(struct adapter *); +static void lem_txeof(struct adapter *); +static void lem_tx_purge(struct adapter *); +static int lem_allocate_receive_structures(struct adapter *); +static int lem_allocate_transmit_structures(struct adapter *); +static int lem_rxeof(struct adapter *, int); +#ifndef __NO_STRICT_ALIGNMENT +static int lem_fixup_rx(struct adapter *); +#endif +static void lem_receive_checksum(struct adapter *, struct e1000_rx_desc *, + struct mbuf *); +static void lem_transmit_checksum_setup(struct adapter *, struct mbuf *, + u32 *, u32 *); +static void lem_set_promisc(struct adapter *); +static void lem_disable_promisc(struct adapter *); +static void lem_set_multi(struct adapter *); +static void lem_print_hw_stats(struct adapter *); +static void lem_update_link_status(struct adapter *); +static int lem_get_buf(struct adapter *, int); +#if __FreeBSD_version >= 700029 +static void lem_register_vlan(void *, struct ifnet *, u16); +static void lem_unregister_vlan(void *, struct ifnet *, u16); +static void lem_setup_vlan_hw_support(struct adapter *); +#endif +static int lem_xmit(struct adapter *, struct mbuf **); +static void lem_smartspeed(struct adapter *); +static int lem_82547_fifo_workaround(struct adapter *, int); +static void lem_82547_update_fifo_head(struct adapter *, int); +static int lem_82547_tx_fifo_reset(struct adapter *); +static void lem_82547_move_tail(void *); +static int lem_dma_malloc(struct adapter *, bus_size_t, + struct em_dma_alloc *, int); +static void lem_dma_free(struct adapter *, struct em_dma_alloc *); +static void lem_print_debug_info(struct adapter *); +static void lem_print_nvm_info(struct adapter *); +static int lem_is_valid_ether_addr(u8 *); +static int lem_sysctl_stats(SYSCTL_HANDLER_ARGS); +static int lem_sysctl_debug_info(SYSCTL_HANDLER_ARGS); +static u32 lem_fill_descriptors (bus_addr_t address, u32 length, + PDESC_ARRAY desc_array); +static int lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS); +static void lem_add_int_delay_sysctl(struct adapter *, const char *, + const char *, struct em_int_delay_info *, int, int); +/* Management and WOL Support */ +static void lem_init_manageability(struct adapter *); +static void lem_release_manageability(struct adapter *); +static void lem_get_hw_control(struct adapter *); +static void lem_release_hw_control(struct adapter *); +static void lem_get_wakeup(device_t); +static void lem_enable_wakeup(device_t); +static int lem_enable_phy_wakeup(struct adapter *); +static void lem_led_func(void *, int); + +#ifdef EM_LEGACY_IRQ +static void lem_intr(void *); +#else /* FAST IRQ */ +#if __FreeBSD_version < 700000 +static void lem_irq_fast(void *); +#else +static int lem_irq_fast(void *); +#endif +static void lem_handle_rxtx(void *context, int pending); +static void lem_handle_link(void *context, int pending); +static void lem_add_rx_process_limit(struct adapter *, const char *, + const char *, int *, int); +#endif /* ~EM_LEGACY_IRQ */ + +#ifdef DEVICE_POLLING +static poll_handler_t lem_poll; +#endif /* POLLING */ + +/********************************************************************* + * FreeBSD Device Interface Entry Points + *********************************************************************/ + +static device_method_t lem_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, lem_probe), + DEVMETHOD(device_attach, lem_attach), + DEVMETHOD(device_detach, lem_detach), + DEVMETHOD(device_shutdown, lem_shutdown), + DEVMETHOD(device_suspend, lem_suspend), + DEVMETHOD(device_resume, lem_resume), + {0, 0} +}; + +static driver_t lem_driver = { + "em", lem_methods, sizeof(struct adapter), +}; + +extern devclass_t em_devclass; +DRIVER_MODULE(lem, pci, lem_driver, em_devclass, 0, 0); +MODULE_DEPEND(lem, pci, 1, 1, 1); +MODULE_DEPEND(lem, ether, 1, 1, 1); + +/********************************************************************* + * Tunable default values. + *********************************************************************/ + +#define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000) +#define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024) +#define M_TSO_LEN 66 + +/* Allow common code without TSO */ +#ifndef CSUM_TSO +#define CSUM_TSO 0 +#endif + +static int lem_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV); +static int lem_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR); +static int lem_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV); +static int lem_rx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_RADV); +static int lem_rxd = EM_DEFAULT_RXD; +static int lem_txd = EM_DEFAULT_TXD; +static int lem_smart_pwr_down = FALSE; + +/* Controls whether promiscuous also shows bad packets */ +static int lem_debug_sbp = FALSE; + +TUNABLE_INT("hw.em.tx_int_delay", &lem_tx_int_delay_dflt); +TUNABLE_INT("hw.em.rx_int_delay", &lem_rx_int_delay_dflt); +TUNABLE_INT("hw.em.tx_abs_int_delay", &lem_tx_abs_int_delay_dflt); +TUNABLE_INT("hw.em.rx_abs_int_delay", &lem_rx_abs_int_delay_dflt); +TUNABLE_INT("hw.em.rxd", &lem_rxd); +TUNABLE_INT("hw.em.txd", &lem_txd); +TUNABLE_INT("hw.em.smart_pwr_down", &lem_smart_pwr_down); +TUNABLE_INT("hw.em.sbp", &lem_debug_sbp); + +#ifndef EM_LEGACY_IRQ +/* How many packets rxeof tries to clean at a time */ +static int lem_rx_process_limit = 100; +TUNABLE_INT("hw.em.rx_process_limit", &lem_rx_process_limit); +#endif + +/* Flow control setting - default to FULL */ +static int lem_fc_setting = e1000_fc_full; +TUNABLE_INT("hw.em.fc_setting", &lem_fc_setting); + +/* +** Shadow VFTA table, this is needed because +** the real vlan filter table gets cleared during +** a soft reset and the driver needs to be able +** to repopulate it. +*/ +static u32 lem_shadow_vfta[EM_VFTA_SIZE]; + +/* Global used in WOL setup with multiport cards */ +static int global_quad_port_a = 0; + +/********************************************************************* + * Device identification routine + * + * em_probe determines if the driver should be loaded on + * adapter based on PCI vendor/device id of the adapter. + * + * return BUS_PROBE_DEFAULT on success, positive on failure + *********************************************************************/ + +static int +lem_probe(device_t dev) +{ + char adapter_name[60]; + u16 pci_vendor_id = 0; + u16 pci_device_id = 0; + u16 pci_subvendor_id = 0; + u16 pci_subdevice_id = 0; + em_vendor_info_t *ent; + + INIT_DEBUGOUT("em_probe: begin"); + + pci_vendor_id = pci_get_vendor(dev); + if (pci_vendor_id != EM_VENDOR_ID) + return (ENXIO); + + pci_device_id = pci_get_device(dev); + pci_subvendor_id = pci_get_subvendor(dev); + pci_subdevice_id = pci_get_subdevice(dev); + + ent = lem_vendor_info_array; + while (ent->vendor_id != 0) { + if ((pci_vendor_id == ent->vendor_id) && + (pci_device_id == ent->device_id) && + + ((pci_subvendor_id == ent->subvendor_id) || + (ent->subvendor_id == PCI_ANY_ID)) && + + ((pci_subdevice_id == ent->subdevice_id) || + (ent->subdevice_id == PCI_ANY_ID))) { + sprintf(adapter_name, "%s %s", + lem_strings[ent->index], + lem_driver_version); + device_set_desc_copy(dev, adapter_name); + return (BUS_PROBE_DEFAULT); + } + ent++; + } + + return (ENXIO); +} + +/********************************************************************* + * Device initialization routine + * + * The attach entry point is called when the driver is being loaded. + * This routine identifies the type of hardware, allocates all resources + * and initializes the hardware. + * + * return 0 on success, positive on failure + *********************************************************************/ + +static int +lem_attach(device_t dev) +{ + struct adapter *adapter; + int tsize, rsize; + int error = 0; + + INIT_DEBUGOUT("lem_attach: begin"); + + adapter = device_get_softc(dev); + adapter->dev = adapter->osdep.dev = dev; + EM_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); + EM_TX_LOCK_INIT(adapter, device_get_nameunit(dev)); + EM_RX_LOCK_INIT(adapter, device_get_nameunit(dev)); + + /* SYSCTL stuff */ + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, + lem_sysctl_debug_info, "I", "Debug Information"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "stats", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, + lem_sysctl_stats, "I", "Statistics"); + + callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); + callout_init_mtx(&adapter->tx_fifo_timer, &adapter->tx_mtx, 0); + + /* Determine hardware and mac info */ + lem_identify_hardware(adapter); + + /* Setup PCI resources */ + if (lem_allocate_pci_resources(adapter)) { + device_printf(dev, "Allocation of PCI resources failed\n"); + error = ENXIO; + goto err_pci; + } + + /* Do Shared Code initialization */ + if (e1000_setup_init_funcs(&adapter->hw, TRUE)) { + device_printf(dev, "Setup of Shared code failed\n"); + error = ENXIO; + goto err_pci; + } + + e1000_get_bus_info(&adapter->hw); + + /* Set up some sysctls for the tunable interrupt delays */ + lem_add_int_delay_sysctl(adapter, "rx_int_delay", + "receive interrupt delay in usecs", &adapter->rx_int_delay, + E1000_REGISTER(&adapter->hw, E1000_RDTR), lem_rx_int_delay_dflt); + lem_add_int_delay_sysctl(adapter, "tx_int_delay", + "transmit interrupt delay in usecs", &adapter->tx_int_delay, + E1000_REGISTER(&adapter->hw, E1000_TIDV), lem_tx_int_delay_dflt); + if (adapter->hw.mac.type >= e1000_82540) { + lem_add_int_delay_sysctl(adapter, "rx_abs_int_delay", + "receive interrupt delay limit in usecs", + &adapter->rx_abs_int_delay, + E1000_REGISTER(&adapter->hw, E1000_RADV), + lem_rx_abs_int_delay_dflt); + lem_add_int_delay_sysctl(adapter, "tx_abs_int_delay", + "transmit interrupt delay limit in usecs", + &adapter->tx_abs_int_delay, + E1000_REGISTER(&adapter->hw, E1000_TADV), + lem_tx_abs_int_delay_dflt); + } + +#ifndef EM_LEGACY_IRQ + /* Sysctls for limiting the amount of work done in the taskqueue */ + lem_add_rx_process_limit(adapter, "rx_processing_limit", + "max number of rx packets to process", &adapter->rx_process_limit, + lem_rx_process_limit); +#endif + + /* + * Validate number of transmit and receive descriptors. It + * must not exceed hardware maximum, and must be multiple + * of E1000_DBA_ALIGN. + */ + if (((lem_txd * sizeof(struct e1000_tx_desc)) % EM_DBA_ALIGN) != 0 || + (adapter->hw.mac.type >= e1000_82544 && lem_txd > EM_MAX_TXD) || + (adapter->hw.mac.type < e1000_82544 && lem_txd > EM_MAX_TXD_82543) || + (lem_txd < EM_MIN_TXD)) { + device_printf(dev, "Using %d TX descriptors instead of %d!\n", + EM_DEFAULT_TXD, lem_txd); + adapter->num_tx_desc = EM_DEFAULT_TXD; + } else + adapter->num_tx_desc = lem_txd; + if (((lem_rxd * sizeof(struct e1000_rx_desc)) % EM_DBA_ALIGN) != 0 || + (adapter->hw.mac.type >= e1000_82544 && lem_rxd > EM_MAX_RXD) || + (adapter->hw.mac.type < e1000_82544 && lem_rxd > EM_MAX_RXD_82543) || + (lem_rxd < EM_MIN_RXD)) { + device_printf(dev, "Using %d RX descriptors instead of %d!\n", + EM_DEFAULT_RXD, lem_rxd); + adapter->num_rx_desc = EM_DEFAULT_RXD; + } else + adapter->num_rx_desc = lem_rxd; + + adapter->hw.mac.autoneg = DO_AUTO_NEG; + adapter->hw.phy.autoneg_wait_to_complete = FALSE; + adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT; + adapter->rx_buffer_len = 2048; + + e1000_init_script_state_82541(&adapter->hw, TRUE); + e1000_set_tbi_compatibility_82543(&adapter->hw, TRUE); + + /* Copper options */ + if (adapter->hw.phy.media_type == e1000_media_type_copper) { + adapter->hw.phy.mdix = AUTO_ALL_MODES; + adapter->hw.phy.disable_polarity_correction = FALSE; + adapter->hw.phy.ms_type = EM_MASTER_SLAVE; + } + + /* + * Set the frame limits assuming + * standard ethernet sized frames. + */ + adapter->max_frame_size = ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE; + adapter->min_frame_size = ETH_ZLEN + ETHERNET_FCS_SIZE; + + /* + * This controls when hardware reports transmit completion + * status. + */ + adapter->hw.mac.report_tx_early = 1; + + tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc), + EM_DBA_ALIGN); + + /* Allocate Transmit Descriptor ring */ + if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) { + device_printf(dev, "Unable to allocate tx_desc memory\n"); + error = ENOMEM; + goto err_tx_desc; + } + adapter->tx_desc_base = + (struct e1000_tx_desc *)adapter->txdma.dma_vaddr; + + rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc), + EM_DBA_ALIGN); + + /* Allocate Receive Descriptor ring */ + if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) { + device_printf(dev, "Unable to allocate rx_desc memory\n"); + error = ENOMEM; + goto err_rx_desc; + } + adapter->rx_desc_base = + (struct e1000_rx_desc *)adapter->rxdma.dma_vaddr; + + /* + ** Start from a known state, this is + ** important in reading the nvm and + ** mac from that. + */ + e1000_reset_hw(&adapter->hw); + + /* Make sure we have a good EEPROM before we read from it */ + if (e1000_validate_nvm_checksum(&adapter->hw) < 0) { + /* + ** Some PCI-E parts fail the first check due to + ** the link being in sleep state, call it again, + ** if it fails a second time its a real issue. + */ + if (e1000_validate_nvm_checksum(&adapter->hw) < 0) { + device_printf(dev, + "The EEPROM Checksum Is Not Valid\n"); + error = EIO; + goto err_hw_init; + } + } + + /* Copy the permanent MAC address out of the EEPROM */ + if (e1000_read_mac_addr(&adapter->hw) < 0) { + device_printf(dev, "EEPROM read error while reading MAC" + " address\n"); + error = EIO; + goto err_hw_init; + } + + if (!lem_is_valid_ether_addr(adapter->hw.mac.addr)) { + device_printf(dev, "Invalid MAC address\n"); + error = EIO; + goto err_hw_init; + } + + /* Initialize the hardware */ + if (lem_hardware_init(adapter)) { + device_printf(dev, "Unable to initialize the hardware\n"); + error = EIO; + goto err_hw_init; + } + + /* Allocate transmit descriptors and buffers */ + if (lem_allocate_transmit_structures(adapter)) { + device_printf(dev, "Could not setup transmit structures\n"); + error = ENOMEM; + goto err_tx_struct; + } + + /* Allocate receive descriptors and buffers */ + if (lem_allocate_receive_structures(adapter)) { + device_printf(dev, "Could not setup receive structures\n"); + error = ENOMEM; + goto err_rx_struct; + } + + /* + ** Do interrupt configuration + */ + error = lem_allocate_irq(adapter); + if (error) + goto err_rx_struct; + + /* + * Get Wake-on-Lan and Management info for later use + */ + lem_get_wakeup(dev); + + /* Setup OS specific network interface */ + lem_setup_interface(dev, adapter); + + /* Initialize statistics */ + lem_update_stats_counters(adapter); + + adapter->hw.mac.get_link_status = 1; + lem_update_link_status(adapter); + + /* Indicate SOL/IDER usage */ + if (e1000_check_reset_block(&adapter->hw)) + device_printf(dev, + "PHY reset is blocked due to SOL/IDER session.\n"); + + /* Do we need workaround for 82544 PCI-X adapter? */ + if (adapter->hw.bus.type == e1000_bus_type_pcix && + adapter->hw.mac.type == e1000_82544) + adapter->pcix_82544 = TRUE; + else + adapter->pcix_82544 = FALSE; + +#if __FreeBSD_version >= 700029 + /* Register for VLAN events */ + adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, + lem_register_vlan, adapter, EVENTHANDLER_PRI_FIRST); + adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, + lem_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); +#endif + + /* Non-AMT based hardware can now take control from firmware */ + if (adapter->has_manage && !adapter->has_amt) + lem_get_hw_control(adapter); + + /* Tell the stack that the interface is not active */ + adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + + adapter->led_dev = led_create(lem_led_func, adapter, + device_get_nameunit(dev)); + + INIT_DEBUGOUT("lem_attach: end"); + + return (0); + +err_rx_struct: + lem_free_transmit_structures(adapter); +err_tx_struct: +err_hw_init: + lem_release_hw_control(adapter); + lem_dma_free(adapter, &adapter->rxdma); +err_rx_desc: + lem_dma_free(adapter, &adapter->txdma); +err_tx_desc: +err_pci: + lem_free_pci_resources(adapter); + EM_TX_LOCK_DESTROY(adapter); + EM_RX_LOCK_DESTROY(adapter); + EM_CORE_LOCK_DESTROY(adapter); + + return (error); +} + +/********************************************************************* + * Device removal routine + * + * The detach entry point is called when the driver is being removed. + * This routine stops the adapter and deallocates all the resources + * that were allocated for driver operation. + * + * return 0 on success, positive on failure + *********************************************************************/ + +static int +lem_detach(device_t dev) +{ + struct adapter *adapter = device_get_softc(dev); + struct ifnet *ifp = adapter->ifp; + + INIT_DEBUGOUT("em_detach: begin"); + + /* Make sure VLANS are not using driver */ +#if __FreeBSD_version >= 700000 + if (adapter->ifp->if_vlantrunk != NULL) { +#else + if (adapter->ifp->if_nvlans != 0) { +#endif + device_printf(dev,"Vlan in use, detach first\n"); + return (EBUSY); + } + +#ifdef DEVICE_POLLING + if (ifp->if_capenable & IFCAP_POLLING) + ether_poll_deregister(ifp); +#endif + + if (adapter->led_dev != NULL) + led_destroy(adapter->led_dev); + + EM_CORE_LOCK(adapter); + EM_TX_LOCK(adapter); + adapter->in_detach = 1; + lem_stop(adapter); + e1000_phy_hw_reset(&adapter->hw); + + lem_release_manageability(adapter); + + EM_TX_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); + +#if __FreeBSD_version >= 700029 + /* Unregister VLAN events */ + if (adapter->vlan_attach != NULL) + EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach); + if (adapter->vlan_detach != NULL) + EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach); +#endif + + ether_ifdetach(adapter->ifp); + callout_drain(&adapter->timer); + callout_drain(&adapter->tx_fifo_timer); + + lem_free_pci_resources(adapter); + bus_generic_detach(dev); + if_free(ifp); + + lem_free_transmit_structures(adapter); + lem_free_receive_structures(adapter); + + /* Free Transmit Descriptor ring */ + if (adapter->tx_desc_base) { + lem_dma_free(adapter, &adapter->txdma); + adapter->tx_desc_base = NULL; + } + + /* Free Receive Descriptor ring */ + if (adapter->rx_desc_base) { + lem_dma_free(adapter, &adapter->rxdma); + adapter->rx_desc_base = NULL; + } + + lem_release_hw_control(adapter); + EM_TX_LOCK_DESTROY(adapter); + EM_RX_LOCK_DESTROY(adapter); + EM_CORE_LOCK_DESTROY(adapter); + + return (0); +} + +/********************************************************************* + * + * Shutdown entry point + * + **********************************************************************/ + +static int +lem_shutdown(device_t dev) +{ + return lem_suspend(dev); +} + +/* + * Suspend/resume device methods. + */ +static int +lem_suspend(device_t dev) +{ + struct adapter *adapter = device_get_softc(dev); + + EM_CORE_LOCK(adapter); + + lem_release_manageability(adapter); + lem_release_hw_control(adapter); + lem_enable_wakeup(dev); + + EM_CORE_UNLOCK(adapter); + + return bus_generic_suspend(dev); +} + +static int +lem_resume(device_t dev) +{ + struct adapter *adapter = device_get_softc(dev); + struct ifnet *ifp = adapter->ifp; + + EM_CORE_LOCK(adapter); + lem_init_locked(adapter); + lem_init_manageability(adapter); + EM_CORE_UNLOCK(adapter); + lem_start(ifp); + + return bus_generic_resume(dev); +} + + +/********************************************************************* + * Transmit entry point + * + * em_start is called by the stack to initiate a transmit. + * The driver will remain in this routine as long as there are + * packets to transmit and transmit resources are available. + * In case resources are not available stack is notified and + * the packet is requeued. + **********************************************************************/ + +#if __FreeBSD_version >= 800000 +static int +lem_mq_start_locked(struct ifnet *ifp, struct mbuf *m) +{ + struct adapter *adapter = ifp->if_softc; + struct mbuf *next; + int error = E1000_SUCCESS; + + EM_TX_LOCK_ASSERT(adapter); + /* To allow being called from a tasklet */ + if (m == NULL) + goto process; + + if (((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING) + || (!adapter->link_active)) { + error = drbr_enqueue(ifp, adapter->br, m); + return (error); + } else if (drbr_empty(ifp, adapter->br) && + (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) { + if ((error = lem_xmit(adapter, &m)) != 0) { + if (m) + error = drbr_enqueue(ifp, adapter->br, m); + return (error); + } else { + /* + * We've bypassed the buf ring so we need to update + * ifp directly + */ + drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags); + /* + ** Send a copy of the frame to the BPF + ** listener and set the watchdog on. + */ + ETHER_BPF_MTAP(ifp, m); + adapter->watchdog_check = TRUE; + } + } else if ((error = drbr_enqueue(ifp, adapter->br, m)) != 0) + return (error); + +process: + if (drbr_empty(ifp, adapter->br)) + return(error); + /* Process the queue */ + while (TRUE) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; + next = drbr_dequeue(ifp, adapter->br); + if (next == NULL) + break; + if ((error = lem_xmit(adapter, &next)) != 0) { + if (next != NULL) + error = drbr_enqueue(ifp, adapter->br, next); + break; + } + drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags); + ETHER_BPF_MTAP(ifp, next); + /* Set the watchdog */ + adapter->watchdog_check = TRUE; + } + + if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + + return (error); +} + +/* +** Multiqueue capable stack interface, this is not +** yet truely multiqueue, but that is coming... +*/ +static int +lem_mq_start(struct ifnet *ifp, struct mbuf *m) +{ + + struct adapter *adapter = ifp->if_softc; + int error = 0; + + if (EM_TX_TRYLOCK(adapter)) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + error = lem_mq_start_locked(ifp, m); + EM_TX_UNLOCK(adapter); + } else + error = drbr_enqueue(ifp, adapter->br, m); + + return (error); +} + +static void +lem_qflush(struct ifnet *ifp) +{ + struct mbuf *m; + struct adapter *adapter = (struct adapter *)ifp->if_softc; + + EM_TX_LOCK(adapter); + while ((m = buf_ring_dequeue_sc(adapter->br)) != NULL) + m_freem(m); + if_qflush(ifp); + EM_TX_UNLOCK(adapter); +} +#endif /* FreeBSD_version */ + +static void +lem_start_locked(struct ifnet *ifp) +{ + struct adapter *adapter = ifp->if_softc; + struct mbuf *m_head; + + EM_TX_LOCK_ASSERT(adapter); + + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING) + return; + if (!adapter->link_active) + return; + + while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + + IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); + if (m_head == NULL) + break; + /* + * Encapsulation can modify our pointer, and or make it + * NULL on failure. In that event, we can't requeue. + */ + if (lem_xmit(adapter, &m_head)) { + if (m_head == NULL) + break; + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + break; + } + + /* Send a copy of the frame to the BPF listener */ + ETHER_BPF_MTAP(ifp, m_head); + + /* Set timeout in case hardware has problems transmitting. */ + adapter->watchdog_check = TRUE; + } + if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + + return; +} + +static void +lem_start(struct ifnet *ifp) +{ + struct adapter *adapter = ifp->if_softc; + + EM_TX_LOCK(adapter); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + lem_start_locked(ifp); + EM_TX_UNLOCK(adapter); +} + +/********************************************************************* + * Ioctl entry point + * + * em_ioctl is called when the user wants to configure the + * interface. + * + * return 0 on success, positive on failure + **********************************************************************/ + +static int +lem_ioctl(struct ifnet *ifp, u_long command, caddr_t data) +{ + struct adapter *adapter = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *)data; +#ifdef INET + struct ifaddr *ifa = (struct ifaddr *)data; +#endif + int error = 0; + + if (adapter->in_detach) + return (error); + + switch (command) { + case SIOCSIFADDR: +#ifdef INET + if (ifa->ifa_addr->sa_family == AF_INET) { + /* + * XXX + * Since resetting hardware takes a very long time + * and results in link renegotiation we only + * initialize the hardware only when it is absolutely + * required. + */ + ifp->if_flags |= IFF_UP; + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + EM_CORE_LOCK(adapter); + lem_init_locked(adapter); + EM_CORE_UNLOCK(adapter); + } + arp_ifinit(ifp, ifa); + } else +#endif + error = ether_ioctl(ifp, command, data); + break; + case SIOCSIFMTU: + { + int max_frame_size; + + IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)"); + + EM_CORE_LOCK(adapter); + switch (adapter->hw.mac.type) { + case e1000_82542: + max_frame_size = ETHER_MAX_LEN; + break; + default: + max_frame_size = MAX_JUMBO_FRAME_SIZE; + } + if (ifr->ifr_mtu > max_frame_size - ETHER_HDR_LEN - + ETHER_CRC_LEN) { + EM_CORE_UNLOCK(adapter); + error = EINVAL; + break; + } + + ifp->if_mtu = ifr->ifr_mtu; + adapter->max_frame_size = + ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; + lem_init_locked(adapter); + EM_CORE_UNLOCK(adapter); + break; + } + case SIOCSIFFLAGS: + IOCTL_DEBUGOUT("ioctl rcv'd:\ + SIOCSIFFLAGS (Set Interface Flags)"); + EM_CORE_LOCK(adapter); + if (ifp->if_flags & IFF_UP) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if ((ifp->if_flags ^ adapter->if_flags) & + (IFF_PROMISC | IFF_ALLMULTI)) { + lem_disable_promisc(adapter); + lem_set_promisc(adapter); + } + } else + lem_init_locked(adapter); + } else + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + EM_TX_LOCK(adapter); + lem_stop(adapter); + EM_TX_UNLOCK(adapter); + } + adapter->if_flags = ifp->if_flags; + EM_CORE_UNLOCK(adapter); + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI"); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + EM_CORE_LOCK(adapter); + lem_disable_intr(adapter); + lem_set_multi(adapter); + if (adapter->hw.mac.type == e1000_82542 && + adapter->hw.revision_id == E1000_REVISION_2) { + lem_initialize_receive_unit(adapter); + } +#ifdef DEVICE_POLLING + if (!(ifp->if_capenable & IFCAP_POLLING)) +#endif + lem_enable_intr(adapter); + EM_CORE_UNLOCK(adapter); + } + break; + case SIOCSIFMEDIA: + /* Check SOL/IDER usage */ + EM_CORE_LOCK(adapter); + if (e1000_check_reset_block(&adapter->hw)) { + EM_CORE_UNLOCK(adapter); + device_printf(adapter->dev, "Media change is" + " blocked due to SOL/IDER session.\n"); + break; + } + EM_CORE_UNLOCK(adapter); + case SIOCGIFMEDIA: + IOCTL_DEBUGOUT("ioctl rcv'd: \ + SIOCxIFMEDIA (Get/Set Interface Media)"); + error = ifmedia_ioctl(ifp, ifr, &adapter->media, command); + break; + case SIOCSIFCAP: + { + int mask, reinit; + + IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)"); + reinit = 0; + mask = ifr->ifr_reqcap ^ ifp->if_capenable; +#ifdef DEVICE_POLLING + if (mask & IFCAP_POLLING) { + if (ifr->ifr_reqcap & IFCAP_POLLING) { + error = ether_poll_register(lem_poll, ifp); + if (error) + return (error); + EM_CORE_LOCK(adapter); + lem_disable_intr(adapter); + ifp->if_capenable |= IFCAP_POLLING; + EM_CORE_UNLOCK(adapter); + } else { + error = ether_poll_deregister(ifp); + /* Enable interrupt even in error case */ + EM_CORE_LOCK(adapter); + lem_enable_intr(adapter); + ifp->if_capenable &= ~IFCAP_POLLING; + EM_CORE_UNLOCK(adapter); + } + } +#endif + if (mask & IFCAP_HWCSUM) { + ifp->if_capenable ^= IFCAP_HWCSUM; + reinit = 1; + } +#if __FreeBSD_version >= 700000 + if (mask & IFCAP_TSO4) { + ifp->if_capenable ^= IFCAP_TSO4; + reinit = 1; + } +#endif + if (mask & IFCAP_VLAN_HWTAGGING) { + ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; + reinit = 1; + } + if ((mask & IFCAP_WOL) && + (ifp->if_capabilities & IFCAP_WOL) != 0) { + if (mask & IFCAP_WOL_MCAST) + ifp->if_capenable ^= IFCAP_WOL_MCAST; + if (mask & IFCAP_WOL_MAGIC) + ifp->if_capenable ^= IFCAP_WOL_MAGIC; + } + if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) + lem_init(adapter); +#if __FreeBSD_version >= 700000 + VLAN_CAPABILITIES(ifp); +#endif + break; + } + + default: + error = ether_ioctl(ifp, command, data); + break; + } + + return (error); +} + + +/********************************************************************* + * Init entry point + * + * This routine is used in two ways. It is used by the stack as + * init entry point in network interface structure. It is also used + * by the driver as a hw/sw initialization routine to get to a + * consistent state. + * + * return 0 on success, positive on failure + **********************************************************************/ + +static void +lem_init_locked(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; + device_t dev = adapter->dev; + u32 pba; + + INIT_DEBUGOUT("lem_init: begin"); + + EM_CORE_LOCK_ASSERT(adapter); + + EM_TX_LOCK(adapter); + lem_stop(adapter); + EM_TX_UNLOCK(adapter); + + /* + * Packet Buffer Allocation (PBA) + * Writing PBA sets the receive portion of the buffer + * the remainder is used for the transmit buffer. + * + * Devices before the 82547 had a Packet Buffer of 64K. + * Default allocation: PBA=48K for Rx, leaving 16K for Tx. + * After the 82547 the buffer was reduced to 40K. + * Default allocation: PBA=30K for Rx, leaving 10K for Tx. + * Note: default does not leave enough room for Jumbo Frame >10k. + */ + switch (adapter->hw.mac.type) { + case e1000_82547: + case e1000_82547_rev_2: /* 82547: Total Packet Buffer is 40K */ + if (adapter->max_frame_size > 8192) + pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */ + else + pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */ + adapter->tx_fifo_head = 0; + adapter->tx_head_addr = pba << EM_TX_HEAD_ADDR_SHIFT; + adapter->tx_fifo_size = + (E1000_PBA_40K - pba) << EM_PBA_BYTES_SHIFT; + break; + default: + /* Devices before 82547 had a Packet Buffer of 64K. */ + if (adapter->max_frame_size > 8192) + pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ + else + pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */ + } + + INIT_DEBUGOUT1("lem_init: pba=%dK",pba); + E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba); + + /* Get the latest mac address, User can use a LAA */ + bcopy(IF_LLADDR(adapter->ifp), adapter->hw.mac.addr, + ETHER_ADDR_LEN); + + /* Put the address into the Receive Address Array */ + e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); + + /* Initialize the hardware */ + if (lem_hardware_init(adapter)) { + device_printf(dev, "Unable to initialize the hardware\n"); + return; + } + lem_update_link_status(adapter); + + /* Setup VLAN support, basic and offload if available */ + E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); + +#if __FreeBSD_version < 700029 + if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) { + u32 ctrl; + ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL); + ctrl |= E1000_CTRL_VME; + E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); + } +#else + /* Use real VLAN Filter support */ + lem_setup_vlan_hw_support(adapter); +#endif + + /* Set hardware offload abilities */ + ifp->if_hwassist = 0; + if (adapter->hw.mac.type >= e1000_82543) { + if (ifp->if_capenable & IFCAP_TXCSUM) + ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); +#if __FreeBSD_version >= 700000 + if (ifp->if_capenable & IFCAP_TSO4) + ifp->if_hwassist |= CSUM_TSO; +#endif + } + + /* Configure for OS presence */ + lem_init_manageability(adapter); + + /* Prepare transmit descriptors and buffers */ + lem_setup_transmit_structures(adapter); + lem_initialize_transmit_unit(adapter); + + /* Setup Multicast table */ + lem_set_multi(adapter); + + /* Prepare receive descriptors and buffers */ + if (lem_setup_receive_structures(adapter)) { + device_printf(dev, "Could not setup receive structures\n"); + EM_TX_LOCK(adapter); + lem_stop(adapter); + EM_TX_UNLOCK(adapter); + return; + } + lem_initialize_receive_unit(adapter); + + /* Don't lose promiscuous settings */ + lem_set_promisc(adapter); + + ifp->if_drv_flags |= IFF_DRV_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + callout_reset(&adapter->timer, hz, lem_local_timer, adapter); + e1000_clear_hw_cntrs_base_generic(&adapter->hw); + + /* MSI/X configuration for 82574 */ + if (adapter->hw.mac.type == e1000_82574) { + int tmp; + tmp = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); + tmp |= E1000_CTRL_EXT_PBA_CLR; + E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, tmp); + /* + ** Set the IVAR - interrupt vector routing. + ** Each nibble represents a vector, high bit + ** is enable, other 3 bits are the MSIX table + ** entry, we map RXQ0 to 0, TXQ0 to 1, and + ** Link (other) to 2, hence the magic number. + */ + E1000_WRITE_REG(&adapter->hw, E1000_IVAR, 0x800A0908); + } + +#ifdef DEVICE_POLLING + /* + * Only enable interrupts if we are not polling, make sure + * they are off otherwise. + */ + if (ifp->if_capenable & IFCAP_POLLING) + lem_disable_intr(adapter); + else +#endif /* DEVICE_POLLING */ + lem_enable_intr(adapter); + + /* AMT based hardware can now take control from firmware */ + if (adapter->has_manage && adapter->has_amt) + lem_get_hw_control(adapter); + + /* Don't reset the phy next time init gets called */ + adapter->hw.phy.reset_disable = TRUE; +} + +static void +lem_init(void *arg) +{ + struct adapter *adapter = arg; + + EM_CORE_LOCK(adapter); + lem_init_locked(adapter); + EM_CORE_UNLOCK(adapter); +} + + +#ifdef DEVICE_POLLING +/********************************************************************* + * + * Legacy polling routine + * + *********************************************************************/ +static int +lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct adapter *adapter = ifp->if_softc; + u32 reg_icr, rx_done = 0; + + EM_CORE_LOCK(adapter); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + EM_CORE_UNLOCK(adapter); + return (rx_done); + } + + if (cmd == POLL_AND_CHECK_STATUS) { + reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + callout_stop(&adapter->timer); + adapter->hw.mac.get_link_status = 1; + lem_update_link_status(adapter); + callout_reset(&adapter->timer, hz, + lem_local_timer, adapter); + } + } + EM_CORE_UNLOCK(adapter); + + rx_done = lem_rxeof(adapter, count); + + EM_TX_LOCK(adapter); + lem_txeof(adapter); +#if __FreeBSD_version >= 800000 + if (!drbr_empty(ifp, adapter->br)) + lem_mq_start_locked(ifp, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + lem_start_locked(ifp); +#endif + EM_TX_UNLOCK(adapter); + return (rx_done); +} +#endif /* DEVICE_POLLING */ + +#ifdef EM_LEGACY_IRQ +/********************************************************************* + * + * Legacy Interrupt Service routine + * + *********************************************************************/ + +static void +lem_intr(void *arg) +{ + struct adapter *adapter = arg; + struct ifnet *ifp = adapter->ifp; + u32 reg_icr; + + + if (ifp->if_capenable & IFCAP_POLLING) + return; + + EM_CORE_LOCK(adapter); + reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); + if (reg_icr & E1000_ICR_RXO) + adapter->rx_overruns++; + + if ((reg_icr == 0xffffffff) || (reg_icr == 0)) + goto out; + + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + goto out; + + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + callout_stop(&adapter->timer); + adapter->hw.mac.get_link_status = 1; + lem_update_link_status(adapter); + /* Deal with TX cruft when link lost */ + lem_tx_purge(adapter); + callout_reset(&adapter->timer, hz, + lem_local_timer, adapter); + goto out; + } + + EM_TX_LOCK(adapter); + lem_txeof(adapter); + lem_rxeof(adapter, -1); + lem_txeof(adapter); + if (ifp->if_drv_flags & IFF_DRV_RUNNING && + !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + lem_start_locked(ifp); + EM_TX_UNLOCK(adapter); + +out: + EM_CORE_UNLOCK(adapter); + return; +} + +#else /* EM_FAST_IRQ, then fast interrupt routines only */ + +static void +lem_handle_link(void *context, int pending) +{ + struct adapter *adapter = context; + struct ifnet *ifp = adapter->ifp; + + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + return; + + EM_CORE_LOCK(adapter); + callout_stop(&adapter->timer); + lem_update_link_status(adapter); + /* Deal with TX cruft when link lost */ + lem_tx_purge(adapter); + callout_reset(&adapter->timer, hz, lem_local_timer, adapter); + EM_CORE_UNLOCK(adapter); +} + + +/* Combined RX/TX handler, used by Legacy and MSI */ +static void +lem_handle_rxtx(void *context, int pending) +{ + struct adapter *adapter = context; + struct ifnet *ifp = adapter->ifp; + + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (lem_rxeof(adapter, adapter->rx_process_limit) != 0) + taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); + EM_TX_LOCK(adapter); + lem_txeof(adapter); + +#if __FreeBSD_version >= 800000 + if (!drbr_empty(ifp, adapter->br)) + lem_mq_start_locked(ifp, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + lem_start_locked(ifp); +#endif + EM_TX_UNLOCK(adapter); + } + + lem_enable_intr(adapter); +} + +/********************************************************************* + * + * Fast Legacy/MSI Combined Interrupt Service routine + * + *********************************************************************/ +#if __FreeBSD_version < 700000 +#define FILTER_STRAY +#define FILTER_HANDLED +static void +#else +static int +#endif +lem_irq_fast(void *arg) +{ + struct adapter *adapter = arg; + struct ifnet *ifp; + u32 reg_icr; + + ifp = adapter->ifp; + + reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); + + /* Hot eject? */ + if (reg_icr == 0xffffffff) + return FILTER_STRAY; + + /* Definitely not our interrupt. */ + if (reg_icr == 0x0) + return FILTER_STRAY; + + /* + * Mask interrupts until the taskqueue is finished running. This is + * cheap, just assume that it is needed. This also works around the + * MSI message reordering errata on certain systems. + */ + lem_disable_intr(adapter); + taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); + + /* Link status change */ + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + adapter->hw.mac.get_link_status = 1; + taskqueue_enqueue(taskqueue_fast, &adapter->link_task); + } + + if (reg_icr & E1000_ICR_RXO) + adapter->rx_overruns++; + return FILTER_HANDLED; +} +#endif /* ~EM_LEGACY_IRQ */ + + +/********************************************************************* + * + * Media Ioctl callback + * + * This routine is called whenever the user queries the status of + * the interface using ifconfig. + * + **********************************************************************/ +static void +lem_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct adapter *adapter = ifp->if_softc; + u_char fiber_type = IFM_1000_SX; + + INIT_DEBUGOUT("lem_media_status: begin"); + + EM_CORE_LOCK(adapter); + lem_update_link_status(adapter); + + ifmr->ifm_status = IFM_AVALID; + ifmr->ifm_active = IFM_ETHER; + + if (!adapter->link_active) { + EM_CORE_UNLOCK(adapter); + return; + } + + ifmr->ifm_status |= IFM_ACTIVE; + + if ((adapter->hw.phy.media_type == e1000_media_type_fiber) || + (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) { + if (adapter->hw.mac.type == e1000_82545) + fiber_type = IFM_1000_LX; + ifmr->ifm_active |= fiber_type | IFM_FDX; + } else { + switch (adapter->link_speed) { + case 10: + ifmr->ifm_active |= IFM_10_T; + break; + case 100: + ifmr->ifm_active |= IFM_100_TX; + break; + case 1000: + ifmr->ifm_active |= IFM_1000_T; + break; + } + if (adapter->link_duplex == FULL_DUPLEX) + ifmr->ifm_active |= IFM_FDX; + else + ifmr->ifm_active |= IFM_HDX; + } + EM_CORE_UNLOCK(adapter); +} + +/********************************************************************* + * + * Media Ioctl callback + * + * This routine is called when the user changes speed/duplex using + * media/mediopt option with ifconfig. + * + **********************************************************************/ +static int +lem_media_change(struct ifnet *ifp) +{ + struct adapter *adapter = ifp->if_softc; + struct ifmedia *ifm = &adapter->media; + + INIT_DEBUGOUT("lem_media_change: begin"); + + if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) + return (EINVAL); + + EM_CORE_LOCK(adapter); + switch (IFM_SUBTYPE(ifm->ifm_media)) { + case IFM_AUTO: + adapter->hw.mac.autoneg = DO_AUTO_NEG; + adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT; + break; + case IFM_1000_LX: + case IFM_1000_SX: + case IFM_1000_T: + adapter->hw.mac.autoneg = DO_AUTO_NEG; + adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL; + break; + case IFM_100_TX: + adapter->hw.mac.autoneg = FALSE; + adapter->hw.phy.autoneg_advertised = 0; + if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) + adapter->hw.mac.forced_speed_duplex = ADVERTISE_100_FULL; + else + adapter->hw.mac.forced_speed_duplex = ADVERTISE_100_HALF; + break; + case IFM_10_T: + adapter->hw.mac.autoneg = FALSE; + adapter->hw.phy.autoneg_advertised = 0; + if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) + adapter->hw.mac.forced_speed_duplex = ADVERTISE_10_FULL; + else + adapter->hw.mac.forced_speed_duplex = ADVERTISE_10_HALF; + break; + default: + device_printf(adapter->dev, "Unsupported media type\n"); + } + + /* As the speed/duplex settings my have changed we need to + * reset the PHY. + */ + adapter->hw.phy.reset_disable = FALSE; + + lem_init_locked(adapter); + EM_CORE_UNLOCK(adapter); + + return (0); +} + +/********************************************************************* + * + * This routine maps the mbufs to tx descriptors. + * + * return 0 on success, positive on failure + **********************************************************************/ + +static int +lem_xmit(struct adapter *adapter, struct mbuf **m_headp) +{ + bus_dma_segment_t segs[EM_MAX_SCATTER]; + bus_dmamap_t map; + struct em_buffer *tx_buffer, *tx_buffer_mapped; + struct e1000_tx_desc *ctxd = NULL; + struct mbuf *m_head; + u32 txd_upper, txd_lower, txd_used, txd_saved; + int error, nsegs, i, j, first, last = 0; +#if __FreeBSD_version < 700000 + struct m_tag *mtag; +#endif + m_head = *m_headp; + txd_upper = txd_lower = txd_used = txd_saved = 0; + + /* + * Force a cleanup if number of TX descriptors + * available hits the threshold + */ + if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) { + lem_txeof(adapter); + /* Now do we at least have a minimal? */ + if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) { + adapter->no_tx_desc_avail1++; + return (ENOBUFS); + } + } + + /* + * Map the packet for DMA + * + * Capture the first descriptor index, + * this descriptor will have the index + * of the EOP which is the only one that + * now gets a DONE bit writeback. + */ + first = adapter->next_avail_tx_desc; + tx_buffer = &adapter->tx_buffer_area[first]; + tx_buffer_mapped = tx_buffer; + map = tx_buffer->map; + + error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, + *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); + + /* + * There are two types of errors we can (try) to handle: + * - EFBIG means the mbuf chain was too long and bus_dma ran + * out of segments. Defragment the mbuf chain and try again. + * - ENOMEM means bus_dma could not obtain enough bounce buffers + * at this point in time. Defer sending and try again later. + * All other errors, in particular EINVAL, are fatal and prevent the + * mbuf chain from ever going through. Drop it and report error. + */ + if (error == EFBIG) { + struct mbuf *m; + + m = m_defrag(*m_headp, M_DONTWAIT); + if (m == NULL) { + adapter->mbuf_alloc_failed++; + m_freem(*m_headp); + *m_headp = NULL; + return (ENOBUFS); + } + *m_headp = m; + + /* Try it again */ + error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, + *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); + + if (error) { + adapter->no_tx_dma_setup++; + m_freem(*m_headp); + *m_headp = NULL; + return (error); + } + } else if (error != 0) { + adapter->no_tx_dma_setup++; + return (error); + } + + if (nsegs > (adapter->num_tx_desc_avail - 2)) { + adapter->no_tx_desc_avail2++; + bus_dmamap_unload(adapter->txtag, map); + return (ENOBUFS); + } + m_head = *m_headp; + + /* Do hardware assists */ + if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) + lem_transmit_checksum_setup(adapter, m_head, + &txd_upper, &txd_lower); + + i = adapter->next_avail_tx_desc; + if (adapter->pcix_82544) + txd_saved = i; + + /* Set up our transmit descriptors */ + for (j = 0; j < nsegs; j++) { + bus_size_t seg_len; + bus_addr_t seg_addr; + /* If adapter is 82544 and on PCIX bus */ + if(adapter->pcix_82544) { + DESC_ARRAY desc_array; + u32 array_elements, counter; + /* + * Check the Address and Length combination and + * split the data accordingly + */ + array_elements = lem_fill_descriptors(segs[j].ds_addr, + segs[j].ds_len, &desc_array); + for (counter = 0; counter < array_elements; counter++) { + if (txd_used == adapter->num_tx_desc_avail) { + adapter->next_avail_tx_desc = txd_saved; + adapter->no_tx_desc_avail2++; + bus_dmamap_unload(adapter->txtag, map); + return (ENOBUFS); + } + tx_buffer = &adapter->tx_buffer_area[i]; + ctxd = &adapter->tx_desc_base[i]; + ctxd->buffer_addr = htole64( + desc_array.descriptor[counter].address); + ctxd->lower.data = htole32( + (adapter->txd_cmd | txd_lower | (u16) + desc_array.descriptor[counter].length)); + ctxd->upper.data = + htole32((txd_upper)); + last = i; + if (++i == adapter->num_tx_desc) + i = 0; + tx_buffer->m_head = NULL; + tx_buffer->next_eop = -1; + txd_used++; + } + } else { + tx_buffer = &adapter->tx_buffer_area[i]; + ctxd = &adapter->tx_desc_base[i]; + seg_addr = segs[j].ds_addr; + seg_len = segs[j].ds_len; + ctxd->buffer_addr = htole64(seg_addr); + ctxd->lower.data = htole32( + adapter->txd_cmd | txd_lower | seg_len); + ctxd->upper.data = + htole32(txd_upper); + last = i; + if (++i == adapter->num_tx_desc) + i = 0; + tx_buffer->m_head = NULL; + tx_buffer->next_eop = -1; + } + } + + adapter->next_avail_tx_desc = i; + + if (adapter->pcix_82544) + adapter->num_tx_desc_avail -= txd_used; + else + adapter->num_tx_desc_avail -= nsegs; + + /* + ** Handle VLAN tag, this is the + ** biggest difference between + ** 6.x and 7 + */ +#if __FreeBSD_version < 700000 + /* Find out if we are in vlan mode. */ + mtag = VLAN_OUTPUT_TAG(ifp, m_head); + if (mtag != NULL) { + ctxd->upper.fields.special = + htole16(VLAN_TAG_VALUE(mtag)); +#else /* FreeBSD 7 */ + if (m_head->m_flags & M_VLANTAG) { + /* Set the vlan id. */ + ctxd->upper.fields.special = + htole16(m_head->m_pkthdr.ether_vtag); +#endif + /* Tell hardware to add tag */ + ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE); + } + + tx_buffer->m_head = m_head; + tx_buffer_mapped->map = tx_buffer->map; + tx_buffer->map = map; + bus_dmamap_sync(adapter->txtag, map, BUS_DMASYNC_PREWRITE); + + /* + * Last Descriptor of Packet + * needs End Of Packet (EOP) + * and Report Status (RS) + */ + ctxd->lower.data |= + htole32(E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS); + /* + * Keep track in the first buffer which + * descriptor will be written back + */ + tx_buffer = &adapter->tx_buffer_area[first]; + tx_buffer->next_eop = last; + + /* + * Advance the Transmit Descriptor Tail (TDT), this tells the E1000 + * that this frame is available to transmit. + */ + bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + if (adapter->hw.mac.type == e1000_82547 && + adapter->link_duplex == HALF_DUPLEX) + lem_82547_move_tail(adapter); + else { + E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), i); + if (adapter->hw.mac.type == e1000_82547) + lem_82547_update_fifo_head(adapter, + m_head->m_pkthdr.len); + } + + return (0); +} + +/********************************************************************* + * + * 82547 workaround to avoid controller hang in half-duplex environment. + * The workaround is to avoid queuing a large packet that would span + * the internal Tx FIFO ring boundary. We need to reset the FIFO pointers + * in this case. We do that only when FIFO is quiescent. + * + **********************************************************************/ +static void +lem_82547_move_tail(void *arg) +{ + struct adapter *adapter = arg; + struct e1000_tx_desc *tx_desc; + u16 hw_tdt, sw_tdt, length = 0; + bool eop = 0; + + EM_TX_LOCK_ASSERT(adapter); + + hw_tdt = E1000_READ_REG(&adapter->hw, E1000_TDT(0)); + sw_tdt = adapter->next_avail_tx_desc; + + while (hw_tdt != sw_tdt) { + tx_desc = &adapter->tx_desc_base[hw_tdt]; + length += tx_desc->lower.flags.length; + eop = tx_desc->lower.data & E1000_TXD_CMD_EOP; + if (++hw_tdt == adapter->num_tx_desc) + hw_tdt = 0; + + if (eop) { + if (lem_82547_fifo_workaround(adapter, length)) { + adapter->tx_fifo_wrk_cnt++; + callout_reset(&adapter->tx_fifo_timer, 1, + lem_82547_move_tail, adapter); + break; + } + E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), hw_tdt); + lem_82547_update_fifo_head(adapter, length); + length = 0; + } + } +} + +static int +lem_82547_fifo_workaround(struct adapter *adapter, int len) +{ + int fifo_space, fifo_pkt_len; + + fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR); + + if (adapter->link_duplex == HALF_DUPLEX) { + fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head; + + if (fifo_pkt_len >= (EM_82547_PKT_THRESH + fifo_space)) { + if (lem_82547_tx_fifo_reset(adapter)) + return (0); + else + return (1); + } + } + + return (0); +} + +static void +lem_82547_update_fifo_head(struct adapter *adapter, int len) +{ + int fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR); + + /* tx_fifo_head is always 16 byte aligned */ + adapter->tx_fifo_head += fifo_pkt_len; + if (adapter->tx_fifo_head >= adapter->tx_fifo_size) { + adapter->tx_fifo_head -= adapter->tx_fifo_size; + } +} + + +static int +lem_82547_tx_fifo_reset(struct adapter *adapter) +{ + u32 tctl; + + if ((E1000_READ_REG(&adapter->hw, E1000_TDT(0)) == + E1000_READ_REG(&adapter->hw, E1000_TDH(0))) && + (E1000_READ_REG(&adapter->hw, E1000_TDFT) == + E1000_READ_REG(&adapter->hw, E1000_TDFH)) && + (E1000_READ_REG(&adapter->hw, E1000_TDFTS) == + E1000_READ_REG(&adapter->hw, E1000_TDFHS)) && + (E1000_READ_REG(&adapter->hw, E1000_TDFPC) == 0)) { + /* Disable TX unit */ + tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL); + E1000_WRITE_REG(&adapter->hw, E1000_TCTL, + tctl & ~E1000_TCTL_EN); + + /* Reset FIFO pointers */ + E1000_WRITE_REG(&adapter->hw, E1000_TDFT, + adapter->tx_head_addr); + E1000_WRITE_REG(&adapter->hw, E1000_TDFH, + adapter->tx_head_addr); + E1000_WRITE_REG(&adapter->hw, E1000_TDFTS, + adapter->tx_head_addr); + E1000_WRITE_REG(&adapter->hw, E1000_TDFHS, + adapter->tx_head_addr); + + /* Re-enable TX unit */ + E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl); + E1000_WRITE_FLUSH(&adapter->hw); + + adapter->tx_fifo_head = 0; + adapter->tx_fifo_reset_cnt++; + + return (TRUE); + } + else { + return (FALSE); + } +} + +static void +lem_set_promisc(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; + u32 reg_rctl; + + reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + + if (ifp->if_flags & IFF_PROMISC) { + reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); + /* Turn this on if you want to see bad packets */ + if (lem_debug_sbp) + reg_rctl |= E1000_RCTL_SBP; + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); + } else if (ifp->if_flags & IFF_ALLMULTI) { + reg_rctl |= E1000_RCTL_MPE; + reg_rctl &= ~E1000_RCTL_UPE; + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); + } +} + +static void +lem_disable_promisc(struct adapter *adapter) +{ + u32 reg_rctl; + + reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + + reg_rctl &= (~E1000_RCTL_UPE); + reg_rctl &= (~E1000_RCTL_MPE); + reg_rctl &= (~E1000_RCTL_SBP); + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); +} + + +/********************************************************************* + * Multicast Update + * + * This routine is called whenever multicast address list is updated. + * + **********************************************************************/ + +static void +lem_set_multi(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; + struct ifmultiaddr *ifma; + u32 reg_rctl = 0; + u8 *mta; /* Multicast array memory */ + int mcnt = 0; + + IOCTL_DEBUGOUT("lem_set_multi: begin"); + + if (adapter->hw.mac.type == e1000_82542 && + adapter->hw.revision_id == E1000_REVISION_2) { + reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE) + e1000_pci_clear_mwi(&adapter->hw); + reg_rctl |= E1000_RCTL_RST; + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); + msec_delay(5); + } + + /* Allocate temporary memory to setup array */ + mta = malloc(sizeof(u8) * + (ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES), + M_DEVBUF, M_NOWAIT | M_ZERO); + if (mta == NULL) + panic("lem_set_multi memory failure\n"); + +#if __FreeBSD_version < 800000 + IF_ADDR_LOCK(ifp); +#else + if_maddr_rlock(ifp); +#endif + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + + if (mcnt == MAX_NUM_MULTICAST_ADDRESSES) + break; + + bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), + &mta[mcnt * ETH_ADDR_LEN], ETH_ADDR_LEN); + mcnt++; + } +#if __FreeBSD_version < 800000 + IF_ADDR_UNLOCK(ifp); +#else + if_maddr_runlock(ifp); +#endif + if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) { + reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + reg_rctl |= E1000_RCTL_MPE; + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); + } else + e1000_update_mc_addr_list(&adapter->hw, mta, mcnt); + + if (adapter->hw.mac.type == e1000_82542 && + adapter->hw.revision_id == E1000_REVISION_2) { + reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + reg_rctl &= ~E1000_RCTL_RST; + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); + msec_delay(5); + if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE) + e1000_pci_set_mwi(&adapter->hw); + } + free(mta, M_DEVBUF); +} + + +/********************************************************************* + * Timer routine + * + * This routine checks for link status and updates statistics. + * + **********************************************************************/ + +static void +lem_local_timer(void *arg) +{ + struct adapter *adapter = arg; + struct ifnet *ifp = adapter->ifp; + + EM_CORE_LOCK_ASSERT(adapter); + + taskqueue_enqueue(adapter->tq, + &adapter->rxtx_task); + lem_update_link_status(adapter); + lem_update_stats_counters(adapter); + + if (lem_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) + lem_print_hw_stats(adapter); + + lem_smartspeed(adapter); + + /* + * We check the watchdog: the time since + * the last TX descriptor was cleaned. + * This implies a functional TX engine. + */ + if ((adapter->watchdog_check == TRUE) && + (ticks - adapter->watchdog_time > EM_WATCHDOG)) + goto hung; + + callout_reset(&adapter->timer, hz, lem_local_timer, adapter); + return; +hung: + device_printf(adapter->dev, "Watchdog timeout -- resetting\n"); + adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + adapter->watchdog_events++; + lem_init_locked(adapter); +} + +static void +lem_update_link_status(struct adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + struct ifnet *ifp = adapter->ifp; + device_t dev = adapter->dev; + u32 link_check = 0; + + /* Get the cached link value or read phy for real */ + switch (hw->phy.media_type) { + case e1000_media_type_copper: + if (hw->mac.get_link_status) { + /* Do the work to read phy */ + e1000_check_for_link(hw); + link_check = !hw->mac.get_link_status; + if (link_check) /* ESB2 fix */ + e1000_cfg_on_link_up(hw); + } else + link_check = TRUE; + break; + case e1000_media_type_fiber: + e1000_check_for_link(hw); + link_check = (E1000_READ_REG(hw, E1000_STATUS) & + E1000_STATUS_LU); + break; + case e1000_media_type_internal_serdes: + e1000_check_for_link(hw); + link_check = adapter->hw.mac.serdes_has_link; + break; + default: + case e1000_media_type_unknown: + break; + } + + /* Now check for a transition */ + if (link_check && (adapter->link_active == 0)) { + e1000_get_speed_and_duplex(hw, &adapter->link_speed, + &adapter->link_duplex); + if (bootverbose) + device_printf(dev, "Link is up %d Mbps %s\n", + adapter->link_speed, + ((adapter->link_duplex == FULL_DUPLEX) ? + "Full Duplex" : "Half Duplex")); + adapter->link_active = 1; + adapter->smartspeed = 0; + ifp->if_baudrate = adapter->link_speed * 1000000; + if_link_state_change(ifp, LINK_STATE_UP); + } else if (!link_check && (adapter->link_active == 1)) { + ifp->if_baudrate = adapter->link_speed = 0; + adapter->link_duplex = 0; + if (bootverbose) + device_printf(dev, "Link is Down\n"); + adapter->link_active = 0; + /* Link down, disable watchdog */ + adapter->watchdog_check = FALSE; + if_link_state_change(ifp, LINK_STATE_DOWN); + } +} + +/********************************************************************* + * + * This routine disables all traffic on the adapter by issuing a + * global reset on the MAC and deallocates TX/RX buffers. + * + * This routine should always be called with BOTH the CORE + * and TX locks. + **********************************************************************/ + +static void +lem_stop(void *arg) +{ + struct adapter *adapter = arg; + struct ifnet *ifp = adapter->ifp; + + EM_CORE_LOCK_ASSERT(adapter); + EM_TX_LOCK_ASSERT(adapter); + + INIT_DEBUGOUT("lem_stop: begin"); + + lem_disable_intr(adapter); + callout_stop(&adapter->timer); + callout_stop(&adapter->tx_fifo_timer); + + /* Tell the stack that the interface is no longer active */ + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + + e1000_reset_hw(&adapter->hw); + if (adapter->hw.mac.type >= e1000_82544) + E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0); + + e1000_led_off(&adapter->hw); + e1000_cleanup_led(&adapter->hw); +} + + +/********************************************************************* + * + * Determine hardware revision. + * + **********************************************************************/ +static void +lem_identify_hardware(struct adapter *adapter) +{ + device_t dev = adapter->dev; + + /* Make sure our PCI config space has the necessary stuff set */ + adapter->hw.bus.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2); + if (!((adapter->hw.bus.pci_cmd_word & PCIM_CMD_BUSMASTEREN) && + (adapter->hw.bus.pci_cmd_word & PCIM_CMD_MEMEN))) { + device_printf(dev, "Memory Access and/or Bus Master bits " + "were not set!\n"); + adapter->hw.bus.pci_cmd_word |= + (PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN); + pci_write_config(dev, PCIR_COMMAND, + adapter->hw.bus.pci_cmd_word, 2); + } + + /* Save off the information about this board */ + adapter->hw.vendor_id = pci_get_vendor(dev); + adapter->hw.device_id = pci_get_device(dev); + adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1); + adapter->hw.subsystem_vendor_id = + pci_read_config(dev, PCIR_SUBVEND_0, 2); + adapter->hw.subsystem_device_id = + pci_read_config(dev, PCIR_SUBDEV_0, 2); + + /* Do Shared Code Init and Setup */ + if (e1000_set_mac_type(&adapter->hw)) { + device_printf(dev, "Setup init failure\n"); + return; + } +} + +static int +lem_allocate_pci_resources(struct adapter *adapter) +{ + device_t dev = adapter->dev; + int val, rid, error = E1000_SUCCESS; + + rid = PCIR_BAR(0); + adapter->memory = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE); + if (adapter->memory == NULL) { + device_printf(dev, "Unable to allocate bus resource: memory\n"); + return (ENXIO); + } + adapter->osdep.mem_bus_space_tag = + rman_get_bustag(adapter->memory); + adapter->osdep.mem_bus_space_handle = + rman_get_bushandle(adapter->memory); + adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle; + + /* Only older adapters use IO mapping */ + if (adapter->hw.mac.type > e1000_82543) { + /* Figure our where our IO BAR is ? */ + for (rid = PCIR_BAR(0); rid < PCIR_CIS;) { + val = pci_read_config(dev, rid, 4); + if (EM_BAR_TYPE(val) == EM_BAR_TYPE_IO) { + adapter->io_rid = rid; + break; + } + rid += 4; + /* check for 64bit BAR */ + if (EM_BAR_MEM_TYPE(val) == EM_BAR_MEM_TYPE_64BIT) + rid += 4; + } + if (rid >= PCIR_CIS) { + device_printf(dev, "Unable to locate IO BAR\n"); + return (ENXIO); + } + adapter->ioport = bus_alloc_resource_any(dev, + SYS_RES_IOPORT, &adapter->io_rid, RF_ACTIVE); + if (adapter->ioport == NULL) { + device_printf(dev, "Unable to allocate bus resource: " + "ioport\n"); + return (ENXIO); + } + adapter->hw.io_base = 0; + adapter->osdep.io_bus_space_tag = + rman_get_bustag(adapter->ioport); + adapter->osdep.io_bus_space_handle = + rman_get_bushandle(adapter->ioport); + } + + adapter->hw.back = &adapter->osdep; + + return (error); +} + +/********************************************************************* + * + * Setup the Legacy or MSI Interrupt handler + * + **********************************************************************/ +int +lem_allocate_irq(struct adapter *adapter) +{ + device_t dev = adapter->dev; + int error, rid = 0; + + /* Manually turn off all interrupts */ + E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff); + + /* We allocate a single interrupt resource */ + adapter->res[0] = bus_alloc_resource_any(dev, + SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); + if (adapter->res[0] == NULL) { + device_printf(dev, "Unable to allocate bus resource: " + "interrupt\n"); + return (ENXIO); + } + +#ifdef EM_LEGACY_IRQ + /* We do Legacy setup */ + if ((error = bus_setup_intr(dev, adapter->res[0], +#if __FreeBSD_version > 700000 + INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter, +#else /* 6.X */ + INTR_TYPE_NET | INTR_MPSAFE, lem_intr, adapter, +#endif + &adapter->tag[0])) != 0) { + device_printf(dev, "Failed to register interrupt handler"); + return (error); + } + +#else /* FAST_IRQ */ + /* + * Try allocating a fast interrupt and the associated deferred + * processing contexts. + */ + TASK_INIT(&adapter->rxtx_task, 0, lem_handle_rxtx, adapter); + TASK_INIT(&adapter->link_task, 0, lem_handle_link, adapter); + adapter->tq = taskqueue_create_fast("lem_taskq", M_NOWAIT, + taskqueue_thread_enqueue, &adapter->tq); + taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq", + device_get_nameunit(adapter->dev)); +#if __FreeBSD_version < 700000 + if ((error = bus_setup_intr(dev, adapter->res[0], + INTR_TYPE_NET | INTR_FAST, lem_irq_fast, adapter, +#else + if ((error = bus_setup_intr(dev, adapter->res[0], + INTR_TYPE_NET, lem_irq_fast, NULL, adapter, +#endif + &adapter->tag[0])) != 0) { + device_printf(dev, "Failed to register fast interrupt " + "handler: %d\n", error); + taskqueue_free(adapter->tq); + adapter->tq = NULL; + return (error); + } +#endif /* EM_LEGACY_IRQ */ + + return (0); +} + + +static void +lem_free_pci_resources(struct adapter *adapter) +{ + device_t dev = adapter->dev; + + + if (adapter->tag[0] != NULL) { + bus_teardown_intr(dev, adapter->res[0], + adapter->tag[0]); + adapter->tag[0] = NULL; + } + + if (adapter->res[0] != NULL) { + bus_release_resource(dev, SYS_RES_IRQ, + 0, adapter->res[0]); + } + + if (adapter->memory != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, + PCIR_BAR(0), adapter->memory); + + if (adapter->ioport != NULL) + bus_release_resource(dev, SYS_RES_IOPORT, + adapter->io_rid, adapter->ioport); +} + + +/********************************************************************* + * + * Initialize the hardware to a configuration + * as specified by the adapter structure. + * + **********************************************************************/ +static int +lem_hardware_init(struct adapter *adapter) +{ + device_t dev = adapter->dev; + u16 rx_buffer_size; + + INIT_DEBUGOUT("lem_hardware_init: begin"); + + /* Issue a global reset */ + e1000_reset_hw(&adapter->hw); + + /* When hardware is reset, fifo_head is also reset */ + adapter->tx_fifo_head = 0; + + /* + * These parameters control the automatic generation (Tx) and + * response (Rx) to Ethernet PAUSE frames. + * - High water mark should allow for at least two frames to be + * received after sending an XOFF. + * - Low water mark works best when it is very near the high water mark. + * This allows the receiver to restart by sending XON when it has + * drained a bit. Here we use an arbitary value of 1500 which will + * restart after one full frame is pulled from the buffer. There + * could be several smaller frames in the buffer and if so they will + * not trigger the XON until their total number reduces the buffer + * by 1500. + * - The pause time is fairly large at 1000 x 512ns = 512 usec. + */ + rx_buffer_size = ((E1000_READ_REG(&adapter->hw, E1000_PBA) & + 0xffff) << 10 ); + + adapter->hw.fc.high_water = rx_buffer_size - + roundup2(adapter->max_frame_size, 1024); + adapter->hw.fc.low_water = adapter->hw.fc.high_water - 1500; + + adapter->hw.fc.pause_time = EM_FC_PAUSE_TIME; + adapter->hw.fc.send_xon = TRUE; + + /* Set Flow control, use the tunable location if sane */ + if ((lem_fc_setting >= 0) || (lem_fc_setting < 4)) + adapter->hw.fc.requested_mode = lem_fc_setting; + else + adapter->hw.fc.requested_mode = e1000_fc_none; + + if (e1000_init_hw(&adapter->hw) < 0) { + device_printf(dev, "Hardware Initialization Failed\n"); + return (EIO); + } + + e1000_check_for_link(&adapter->hw); + + return (0); +} + +/********************************************************************* + * + * Setup networking device structure and register an interface. + * + **********************************************************************/ +static void +lem_setup_interface(device_t dev, struct adapter *adapter) +{ + struct ifnet *ifp; + + INIT_DEBUGOUT("lem_setup_interface: begin"); + + ifp = adapter->ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) + panic("%s: can not if_alloc()", device_get_nameunit(dev)); + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_mtu = ETHERMTU; + ifp->if_init = lem_init; + ifp->if_softc = adapter; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = lem_ioctl; + ifp->if_start = lem_start; + IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 1); + ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 1; + IFQ_SET_READY(&ifp->if_snd); + + ether_ifattach(ifp, adapter->hw.mac.addr); + + ifp->if_capabilities = ifp->if_capenable = 0; + +#if __FreeBSD_version >= 800000 + /* Multiqueue tx functions */ + ifp->if_transmit = lem_mq_start; + ifp->if_qflush = lem_qflush; + adapter->br = buf_ring_alloc(4096, M_DEVBUF, M_WAITOK, &adapter->tx_mtx); +#endif + if (adapter->hw.mac.type >= e1000_82543) { + int version_cap; +#if __FreeBSD_version < 700000 + version_cap = IFCAP_HWCSUM; +#else + version_cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; +#endif + ifp->if_capabilities |= version_cap; + ifp->if_capenable |= version_cap; + } + + /* + * Tell the upper layer(s) we support long frames. + */ + ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); + ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; + ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; + +#ifdef DEVICE_POLLING + ifp->if_capabilities |= IFCAP_POLLING; +#endif + + /* Enable All WOL methods by default */ + if (adapter->wol) { + ifp->if_capabilities |= IFCAP_WOL; + ifp->if_capenable |= IFCAP_WOL; + } + + /* + * Specify the media types supported by this adapter and register + * callbacks to update media and link information + */ + ifmedia_init(&adapter->media, IFM_IMASK, + lem_media_change, lem_media_status); + if ((adapter->hw.phy.media_type == e1000_media_type_fiber) || + (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) { + u_char fiber_type = IFM_1000_SX; /* default type */ + + if (adapter->hw.mac.type == e1000_82545) + fiber_type = IFM_1000_LX; + ifmedia_add(&adapter->media, IFM_ETHER | fiber_type | IFM_FDX, + 0, NULL); + ifmedia_add(&adapter->media, IFM_ETHER | fiber_type, 0, NULL); + } else { + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T, 0, NULL); + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T | IFM_FDX, + 0, NULL); + ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX, + 0, NULL); + ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX | IFM_FDX, + 0, NULL); + if (adapter->hw.phy.type != e1000_phy_ife) { + ifmedia_add(&adapter->media, + IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL); + ifmedia_add(&adapter->media, + IFM_ETHER | IFM_1000_T, 0, NULL); + } + } + ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL); + ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); +} + + +/********************************************************************* + * + * Workaround for SmartSpeed on 82541 and 82547 controllers + * + **********************************************************************/ +static void +lem_smartspeed(struct adapter *adapter) +{ + u16 phy_tmp; + + if (adapter->link_active || (adapter->hw.phy.type != e1000_phy_igp) || + adapter->hw.mac.autoneg == 0 || + (adapter->hw.phy.autoneg_advertised & ADVERTISE_1000_FULL) == 0) + return; + + if (adapter->smartspeed == 0) { + /* If Master/Slave config fault is asserted twice, + * we assume back-to-back */ + e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp); + if (!(phy_tmp & SR_1000T_MS_CONFIG_FAULT)) + return; + e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp); + if (phy_tmp & SR_1000T_MS_CONFIG_FAULT) { + e1000_read_phy_reg(&adapter->hw, + PHY_1000T_CTRL, &phy_tmp); + if(phy_tmp & CR_1000T_MS_ENABLE) { + phy_tmp &= ~CR_1000T_MS_ENABLE; + e1000_write_phy_reg(&adapter->hw, + PHY_1000T_CTRL, phy_tmp); + adapter->smartspeed++; + if(adapter->hw.mac.autoneg && + !e1000_copper_link_autoneg(&adapter->hw) && + !e1000_read_phy_reg(&adapter->hw, + PHY_CONTROL, &phy_tmp)) { + phy_tmp |= (MII_CR_AUTO_NEG_EN | + MII_CR_RESTART_AUTO_NEG); + e1000_write_phy_reg(&adapter->hw, + PHY_CONTROL, phy_tmp); + } + } + } + return; + } else if(adapter->smartspeed == EM_SMARTSPEED_DOWNSHIFT) { + /* If still no link, perhaps using 2/3 pair cable */ + e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_tmp); + phy_tmp |= CR_1000T_MS_ENABLE; + e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_tmp); + if(adapter->hw.mac.autoneg && + !e1000_copper_link_autoneg(&adapter->hw) && + !e1000_read_phy_reg(&adapter->hw, PHY_CONTROL, &phy_tmp)) { + phy_tmp |= (MII_CR_AUTO_NEG_EN | + MII_CR_RESTART_AUTO_NEG); + e1000_write_phy_reg(&adapter->hw, PHY_CONTROL, phy_tmp); + } + } + /* Restart process after EM_SMARTSPEED_MAX iterations */ + if(adapter->smartspeed++ == EM_SMARTSPEED_MAX) + adapter->smartspeed = 0; +} + + +/* + * Manage DMA'able memory. + */ +static void +lem_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + if (error) + return; + *(bus_addr_t *) arg = segs[0].ds_addr; +} + +static int +lem_dma_malloc(struct adapter *adapter, bus_size_t size, + struct em_dma_alloc *dma, int mapflags) +{ + int error; + +#if __FreeBSD_version >= 700000 + error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */ +#else + error = bus_dma_tag_create(NULL, /* parent */ +#endif + EM_DBA_ALIGN, 0, /* alignment, bounds */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + size, /* maxsize */ + 1, /* nsegments */ + size, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockarg */ + &dma->dma_tag); + if (error) { + device_printf(adapter->dev, + "%s: bus_dma_tag_create failed: %d\n", + __func__, error); + goto fail_0; + } + + error = bus_dmamem_alloc(dma->dma_tag, (void**) &dma->dma_vaddr, + BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dma->dma_map); + if (error) { + device_printf(adapter->dev, + "%s: bus_dmamem_alloc(%ju) failed: %d\n", + __func__, (uintmax_t)size, error); + goto fail_2; + } + + dma->dma_paddr = 0; + error = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr, + size, lem_dmamap_cb, &dma->dma_paddr, mapflags | BUS_DMA_NOWAIT); + if (error || dma->dma_paddr == 0) { + device_printf(adapter->dev, + "%s: bus_dmamap_load failed: %d\n", + __func__, error); + goto fail_3; + } + + return (0); + +fail_3: + bus_dmamap_unload(dma->dma_tag, dma->dma_map); +fail_2: + bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map); + bus_dma_tag_destroy(dma->dma_tag); +fail_0: + dma->dma_map = NULL; + dma->dma_tag = NULL; + + return (error); +} + +static void +lem_dma_free(struct adapter *adapter, struct em_dma_alloc *dma) +{ + if (dma->dma_tag == NULL) + return; + if (dma->dma_map != NULL) { + bus_dmamap_sync(dma->dma_tag, dma->dma_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(dma->dma_tag, dma->dma_map); + bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map); + dma->dma_map = NULL; + } + bus_dma_tag_destroy(dma->dma_tag); + dma->dma_tag = NULL; +} + + +/********************************************************************* + * + * Allocate memory for tx_buffer structures. The tx_buffer stores all + * the information needed to transmit a packet on the wire. + * + **********************************************************************/ +static int +lem_allocate_transmit_structures(struct adapter *adapter) +{ + device_t dev = adapter->dev; + struct em_buffer *tx_buffer; + int error; + + /* + * Create DMA tags for tx descriptors + */ +#if __FreeBSD_version >= 700000 + if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ +#else + if ((error = bus_dma_tag_create(NULL, /* parent */ +#endif + 1, 0, /* alignment, bounds */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + EM_TSO_SIZE, /* maxsize */ + EM_MAX_SCATTER, /* nsegments */ + EM_TSO_SEG_SIZE, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockarg */ + &adapter->txtag)) != 0) { + device_printf(dev, "Unable to allocate TX DMA tag\n"); + goto fail; + } + + adapter->tx_buffer_area = malloc(sizeof(struct em_buffer) * + adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO); + if (adapter->tx_buffer_area == NULL) { + device_printf(dev, "Unable to allocate tx_buffer memory\n"); + error = ENOMEM; + goto fail; + } + + /* Create the descriptor buffer dma maps */ + for (int i = 0; i < adapter->num_tx_desc; i++) { + tx_buffer = &adapter->tx_buffer_area[i]; + error = bus_dmamap_create(adapter->txtag, 0, &tx_buffer->map); + if (error != 0) { + device_printf(dev, "Unable to create TX DMA map\n"); + goto fail; + } + tx_buffer->next_eop = -1; + } + + return (0); +fail: + lem_free_transmit_structures(adapter); + return (error); +} + +/********************************************************************* + * + * (Re)Initialize transmit structures. + * + **********************************************************************/ +static void +lem_setup_transmit_structures(struct adapter *adapter) +{ + struct em_buffer *tx_buffer; + + /* Clear the old ring contents */ + bzero(adapter->tx_desc_base, + (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc); + + /* Free any existing TX buffers */ + for (int i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) { + tx_buffer = &adapter->tx_buffer_area[i]; + bus_dmamap_sync(adapter->txtag, tx_buffer->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(adapter->txtag, tx_buffer->map); + m_freem(tx_buffer->m_head); + tx_buffer->m_head = NULL; + tx_buffer->next_eop = -1; + } + + /* Reset state */ + adapter->next_avail_tx_desc = 0; + adapter->next_tx_to_clean = 0; + adapter->num_tx_desc_avail = adapter->num_tx_desc; + + bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + return; +} + +/********************************************************************* + * + * Enable transmit unit. + * + **********************************************************************/ +static void +lem_initialize_transmit_unit(struct adapter *adapter) +{ + u32 tctl, tipg = 0; + u64 bus_addr; + + INIT_DEBUGOUT("lem_initialize_transmit_unit: begin"); + /* Setup the Base and Length of the Tx Descriptor Ring */ + bus_addr = adapter->txdma.dma_paddr; + E1000_WRITE_REG(&adapter->hw, E1000_TDLEN(0), + adapter->num_tx_desc * sizeof(struct e1000_tx_desc)); + E1000_WRITE_REG(&adapter->hw, E1000_TDBAH(0), + (u32)(bus_addr >> 32)); + E1000_WRITE_REG(&adapter->hw, E1000_TDBAL(0), + (u32)bus_addr); + /* Setup the HW Tx Head and Tail descriptor pointers */ + E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), 0); + E1000_WRITE_REG(&adapter->hw, E1000_TDH(0), 0); + + HW_DEBUGOUT2("Base = %x, Length = %x\n", + E1000_READ_REG(&adapter->hw, E1000_TDBAL(0)), + E1000_READ_REG(&adapter->hw, E1000_TDLEN(0))); + + /* Set the default values for the Tx Inter Packet Gap timer */ + switch (adapter->hw.mac.type) { + case e1000_82542: + tipg = DEFAULT_82542_TIPG_IPGT; + tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; + tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; + break; + default: + if ((adapter->hw.phy.media_type == e1000_media_type_fiber) || + (adapter->hw.phy.media_type == + e1000_media_type_internal_serdes)) + tipg = DEFAULT_82543_TIPG_IPGT_FIBER; + else + tipg = DEFAULT_82543_TIPG_IPGT_COPPER; + tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; + tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; + } + + E1000_WRITE_REG(&adapter->hw, E1000_TIPG, tipg); + E1000_WRITE_REG(&adapter->hw, E1000_TIDV, adapter->tx_int_delay.value); + if(adapter->hw.mac.type >= e1000_82540) + E1000_WRITE_REG(&adapter->hw, E1000_TADV, + adapter->tx_abs_int_delay.value); + + /* Program the Transmit Control Register */ + tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL); + tctl &= ~E1000_TCTL_CT; + tctl |= (E1000_TCTL_PSP | E1000_TCTL_RTLC | E1000_TCTL_EN | + (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT)); + + /* This write will effectively turn on the transmit unit. */ + E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl); + + /* Setup Transmit Descriptor Base Settings */ + adapter->txd_cmd = E1000_TXD_CMD_IFCS; + + if (adapter->tx_int_delay.value > 0) + adapter->txd_cmd |= E1000_TXD_CMD_IDE; +} + +/********************************************************************* + * + * Free all transmit related data structures. + * + **********************************************************************/ +static void +lem_free_transmit_structures(struct adapter *adapter) +{ + struct em_buffer *tx_buffer; + + INIT_DEBUGOUT("free_transmit_structures: begin"); + + if (adapter->tx_buffer_area != NULL) { + for (int i = 0; i < adapter->num_tx_desc; i++) { + tx_buffer = &adapter->tx_buffer_area[i]; + if (tx_buffer->m_head != NULL) { + bus_dmamap_sync(adapter->txtag, tx_buffer->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(adapter->txtag, + tx_buffer->map); + m_freem(tx_buffer->m_head); + tx_buffer->m_head = NULL; + } else if (tx_buffer->map != NULL) + bus_dmamap_unload(adapter->txtag, + tx_buffer->map); + if (tx_buffer->map != NULL) { + bus_dmamap_destroy(adapter->txtag, + tx_buffer->map); + tx_buffer->map = NULL; + } + } + } + if (adapter->tx_buffer_area != NULL) { + free(adapter->tx_buffer_area, M_DEVBUF); + adapter->tx_buffer_area = NULL; + } + if (adapter->txtag != NULL) { + bus_dma_tag_destroy(adapter->txtag); + adapter->txtag = NULL; + } +#if __FreeBSD_version >= 800000 + if (adapter->br != NULL) + buf_ring_free(adapter->br, M_DEVBUF); +#endif +} + +/********************************************************************* + * + * The offload context needs to be set when we transfer the first + * packet of a particular protocol (TCP/UDP). This routine has been + * enhanced to deal with inserted VLAN headers, and IPV6 (not complete) + * + * Added back the old method of keeping the current context type + * and not setting if unnecessary, as this is reported to be a + * big performance win. -jfv + **********************************************************************/ +static void +lem_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp, + u32 *txd_upper, u32 *txd_lower) +{ + struct e1000_context_desc *TXD = NULL; + struct em_buffer *tx_buffer; + struct ether_vlan_header *eh; + struct ip *ip = NULL; + struct ip6_hdr *ip6; + int curr_txd, ehdrlen; + u32 cmd, hdr_len, ip_hlen; + u16 etype; + u8 ipproto; + + + cmd = hdr_len = ipproto = 0; + curr_txd = adapter->next_avail_tx_desc; + + /* + * Determine where frame payload starts. + * Jump over vlan headers if already present, + * helpful for QinQ too. + */ + eh = mtod(mp, struct ether_vlan_header *); + if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { + etype = ntohs(eh->evl_proto); + ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; + } else { + etype = ntohs(eh->evl_encap_proto); + ehdrlen = ETHER_HDR_LEN; + } + + /* + * We only support TCP/UDP for IPv4 and IPv6 for the moment. + * TODO: Support SCTP too when it hits the tree. + */ + switch (etype) { + case ETHERTYPE_IP: + ip = (struct ip *)(mp->m_data + ehdrlen); + ip_hlen = ip->ip_hl << 2; + + /* Setup of IP header checksum. */ + if (mp->m_pkthdr.csum_flags & CSUM_IP) { + /* + * Start offset for header checksum calculation. + * End offset for header checksum calculation. + * Offset of place to put the checksum. + */ + TXD = (struct e1000_context_desc *) + &adapter->tx_desc_base[curr_txd]; + TXD->lower_setup.ip_fields.ipcss = ehdrlen; + TXD->lower_setup.ip_fields.ipcse = + htole16(ehdrlen + ip_hlen); + TXD->lower_setup.ip_fields.ipcso = + ehdrlen + offsetof(struct ip, ip_sum); + cmd |= E1000_TXD_CMD_IP; + *txd_upper |= E1000_TXD_POPTS_IXSM << 8; + } + + if (mp->m_len < ehdrlen + ip_hlen) + return; /* failure */ + + hdr_len = ehdrlen + ip_hlen; + ipproto = ip->ip_p; + + break; + case ETHERTYPE_IPV6: + ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); + ip_hlen = sizeof(struct ip6_hdr); /* XXX: No header stacking. */ + + if (mp->m_len < ehdrlen + ip_hlen) + return; /* failure */ + + /* IPv6 doesn't have a header checksum. */ + + hdr_len = ehdrlen + ip_hlen; + ipproto = ip6->ip6_nxt; + + break; + default: + *txd_upper = 0; + *txd_lower = 0; + return; + } + + switch (ipproto) { + case IPPROTO_TCP: + if (mp->m_pkthdr.csum_flags & CSUM_TCP) { + *txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D; + *txd_upper |= E1000_TXD_POPTS_TXSM << 8; + /* no need for context if already set */ + if (adapter->last_hw_offload == CSUM_TCP) + return; + adapter->last_hw_offload = CSUM_TCP; + /* + * Start offset for payload checksum calculation. + * End offset for payload checksum calculation. + * Offset of place to put the checksum. + */ + TXD = (struct e1000_context_desc *) + &adapter->tx_desc_base[curr_txd]; + TXD->upper_setup.tcp_fields.tucss = hdr_len; + TXD->upper_setup.tcp_fields.tucse = htole16(0); + TXD->upper_setup.tcp_fields.tucso = + hdr_len + offsetof(struct tcphdr, th_sum); + cmd |= E1000_TXD_CMD_TCP; + } + break; + case IPPROTO_UDP: + { + if (mp->m_pkthdr.csum_flags & CSUM_UDP) { + *txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D; + *txd_upper |= E1000_TXD_POPTS_TXSM << 8; + /* no need for context if already set */ + if (adapter->last_hw_offload == CSUM_UDP) + return; + adapter->last_hw_offload = CSUM_UDP; + /* + * Start offset for header checksum calculation. + * End offset for header checksum calculation. + * Offset of place to put the checksum. + */ + TXD = (struct e1000_context_desc *) + &adapter->tx_desc_base[curr_txd]; + TXD->upper_setup.tcp_fields.tucss = hdr_len; + TXD->upper_setup.tcp_fields.tucse = htole16(0); + TXD->upper_setup.tcp_fields.tucso = + hdr_len + offsetof(struct udphdr, uh_sum); + } + /* Fall Thru */ + } + default: + break; + } + + TXD->tcp_seg_setup.data = htole32(0); + TXD->cmd_and_length = + htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | cmd); + tx_buffer = &adapter->tx_buffer_area[curr_txd]; + tx_buffer->m_head = NULL; + tx_buffer->next_eop = -1; + + if (++curr_txd == adapter->num_tx_desc) + curr_txd = 0; + + adapter->num_tx_desc_avail--; + adapter->next_avail_tx_desc = curr_txd; +} + + +/********************************************************************** + * + * Examine each tx_buffer in the used queue. If the hardware is done + * processing the packet then free associated resources. The + * tx_buffer is put back on the free queue. + * + **********************************************************************/ +static void +lem_txeof(struct adapter *adapter) +{ + int first, last, done, num_avail; + struct em_buffer *tx_buffer; + struct e1000_tx_desc *tx_desc, *eop_desc; + struct ifnet *ifp = adapter->ifp; + + EM_TX_LOCK_ASSERT(adapter); + + if (adapter->num_tx_desc_avail == adapter->num_tx_desc) + return; + + num_avail = adapter->num_tx_desc_avail; + first = adapter->next_tx_to_clean; + tx_desc = &adapter->tx_desc_base[first]; + tx_buffer = &adapter->tx_buffer_area[first]; + last = tx_buffer->next_eop; + eop_desc = &adapter->tx_desc_base[last]; + + /* + * What this does is get the index of the + * first descriptor AFTER the EOP of the + * first packet, that way we can do the + * simple comparison on the inner while loop. + */ + if (++last == adapter->num_tx_desc) + last = 0; + done = last; + + bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, + BUS_DMASYNC_POSTREAD); + + while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) { + /* We clean the range of the packet */ + while (first != done) { + tx_desc->upper.data = 0; + tx_desc->lower.data = 0; + tx_desc->buffer_addr = 0; + ++num_avail; + + if (tx_buffer->m_head) { + ifp->if_opackets++; + bus_dmamap_sync(adapter->txtag, + tx_buffer->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(adapter->txtag, + tx_buffer->map); + + m_freem(tx_buffer->m_head); + tx_buffer->m_head = NULL; + } + tx_buffer->next_eop = -1; + adapter->watchdog_time = ticks; + + if (++first == adapter->num_tx_desc) + first = 0; + + tx_buffer = &adapter->tx_buffer_area[first]; + tx_desc = &adapter->tx_desc_base[first]; + } + /* See if we can continue to the next packet */ + last = tx_buffer->next_eop; + if (last != -1) { + eop_desc = &adapter->tx_desc_base[last]; + /* Get new done point */ + if (++last == adapter->num_tx_desc) last = 0; + done = last; + } else + break; + } + bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + adapter->next_tx_to_clean = first; + + /* + * If we have enough room, clear IFF_DRV_OACTIVE to + * tell the stack that it is OK to send packets. + * If there are no pending descriptors, clear the watchdog. + */ + if (num_avail > EM_TX_CLEANUP_THRESHOLD) { + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + if (num_avail == adapter->num_tx_desc) { + adapter->watchdog_check = FALSE; + adapter->num_tx_desc_avail = num_avail; + return; + } + } + + adapter->num_tx_desc_avail = num_avail; + return; +} + +/********************************************************************* + * + * When Link is lost sometimes there is work still in the TX ring + * which may result in a watchdog, rather than allow that we do an + * attempted cleanup and then reinit here. Note that this has been + * seens mostly with fiber adapters. + * + **********************************************************************/ +static void +lem_tx_purge(struct adapter *adapter) +{ + if ((!adapter->link_active) && (adapter->watchdog_check)) { + EM_TX_LOCK(adapter); + lem_txeof(adapter); + EM_TX_UNLOCK(adapter); + if (adapter->watchdog_check) /* Still outstanding? */ + lem_init_locked(adapter); + } +} + +/********************************************************************* + * + * Get a buffer from system mbuf buffer pool. + * + **********************************************************************/ +static int +lem_get_buf(struct adapter *adapter, int i) +{ + struct mbuf *m; + bus_dma_segment_t segs[1]; + bus_dmamap_t map; + struct em_buffer *rx_buffer; + int error, nsegs; + + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) { + adapter->mbuf_cluster_failed++; + return (ENOBUFS); + } + m->m_len = m->m_pkthdr.len = MCLBYTES; + + if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN)) + m_adj(m, ETHER_ALIGN); + + /* + * Using memory from the mbuf cluster pool, invoke the + * bus_dma machinery to arrange the memory mapping. + */ + error = bus_dmamap_load_mbuf_sg(adapter->rxtag, + adapter->rx_sparemap, m, segs, &nsegs, BUS_DMA_NOWAIT); + if (error != 0) { + m_free(m); + return (error); + } + + /* If nsegs is wrong then the stack is corrupt. */ + KASSERT(nsegs == 1, ("Too many segments returned!")); + + rx_buffer = &adapter->rx_buffer_area[i]; + if (rx_buffer->m_head != NULL) + bus_dmamap_unload(adapter->rxtag, rx_buffer->map); + + map = rx_buffer->map; + rx_buffer->map = adapter->rx_sparemap; + adapter->rx_sparemap = map; + bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD); + rx_buffer->m_head = m; + + adapter->rx_desc_base[i].buffer_addr = htole64(segs[0].ds_addr); + return (0); +} + +/********************************************************************* + * + * Allocate memory for rx_buffer structures. Since we use one + * rx_buffer per received packet, the maximum number of rx_buffer's + * that we'll need is equal to the number of receive descriptors + * that we've allocated. + * + **********************************************************************/ +static int +lem_allocate_receive_structures(struct adapter *adapter) +{ + device_t dev = adapter->dev; + struct em_buffer *rx_buffer; + int i, error; + + adapter->rx_buffer_area = malloc(sizeof(struct em_buffer) * + adapter->num_rx_desc, M_DEVBUF, M_NOWAIT | M_ZERO); + if (adapter->rx_buffer_area == NULL) { + device_printf(dev, "Unable to allocate rx_buffer memory\n"); + return (ENOMEM); + } + +#if __FreeBSD_version >= 700000 + error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ +#else + error = bus_dma_tag_create(NULL, /* parent */ +#endif + 1, 0, /* alignment, bounds */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + MCLBYTES, /* maxsize */ + 1, /* nsegments */ + MCLBYTES, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockarg */ + &adapter->rxtag); + if (error) { + device_printf(dev, "%s: bus_dma_tag_create failed %d\n", + __func__, error); + goto fail; + } + + /* Create the spare map (used by getbuf) */ + error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT, + &adapter->rx_sparemap); + if (error) { + device_printf(dev, "%s: bus_dmamap_create failed: %d\n", + __func__, error); + goto fail; + } + + rx_buffer = adapter->rx_buffer_area; + for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) { + error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT, + &rx_buffer->map); + if (error) { + device_printf(dev, "%s: bus_dmamap_create failed: %d\n", + __func__, error); + goto fail; + } + } + + return (0); + +fail: + lem_free_receive_structures(adapter); + return (error); +} + +/********************************************************************* + * + * (Re)initialize receive structures. + * + **********************************************************************/ +static int +lem_setup_receive_structures(struct adapter *adapter) +{ + struct em_buffer *rx_buffer; + int i, error; + + /* Reset descriptor ring */ + bzero(adapter->rx_desc_base, + (sizeof(struct e1000_rx_desc)) * adapter->num_rx_desc); + + /* Free current RX buffers. */ + rx_buffer = adapter->rx_buffer_area; + for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) { + if (rx_buffer->m_head != NULL) { + bus_dmamap_sync(adapter->rxtag, rx_buffer->map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(adapter->rxtag, rx_buffer->map); + m_freem(rx_buffer->m_head); + rx_buffer->m_head = NULL; + } + } + + /* Allocate new ones. */ + for (i = 0; i < adapter->num_rx_desc; i++) { + error = lem_get_buf(adapter, i); + if (error) + return (error); + } + + /* Setup our descriptor pointers */ + adapter->next_rx_desc_to_check = 0; + bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + return (0); +} + +/********************************************************************* + * + * Enable receive unit. + * + **********************************************************************/ +#define MAX_INTS_PER_SEC 8000 +#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256) + +static void +lem_initialize_receive_unit(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; + u64 bus_addr; + u32 rctl, rxcsum; + + INIT_DEBUGOUT("lem_initialize_receive_unit: begin"); + + /* + * Make sure receives are disabled while setting + * up the descriptor ring + */ + rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); + + if (adapter->hw.mac.type >= e1000_82540) { + E1000_WRITE_REG(&adapter->hw, E1000_RADV, + adapter->rx_abs_int_delay.value); + /* + * Set the interrupt throttling rate. Value is calculated + * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) + */ + E1000_WRITE_REG(&adapter->hw, E1000_ITR, DEFAULT_ITR); + } + + /* + ** When using MSIX interrupts we need to throttle + ** using the EITR register (82574 only) + */ + if (adapter->msix) + for (int i = 0; i < 4; i++) + E1000_WRITE_REG(&adapter->hw, + E1000_EITR_82574(i), DEFAULT_ITR); + + /* Disable accelerated ackknowledge */ + if (adapter->hw.mac.type == e1000_82574) + E1000_WRITE_REG(&adapter->hw, + E1000_RFCTL, E1000_RFCTL_ACK_DIS); + + /* Setup the Base and Length of the Rx Descriptor Ring */ + bus_addr = adapter->rxdma.dma_paddr; + E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0), + adapter->num_rx_desc * sizeof(struct e1000_rx_desc)); + E1000_WRITE_REG(&adapter->hw, E1000_RDBAH(0), + (u32)(bus_addr >> 32)); + E1000_WRITE_REG(&adapter->hw, E1000_RDBAL(0), + (u32)bus_addr); + + /* Setup the Receive Control Register */ + rctl &= ~(3 << E1000_RCTL_MO_SHIFT); + rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | + E1000_RCTL_RDMTS_HALF | + (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); + + /* Make sure VLAN Filters are off */ + rctl &= ~E1000_RCTL_VFE; + + if (e1000_tbi_sbp_enabled_82543(&adapter->hw)) + rctl |= E1000_RCTL_SBP; + else + rctl &= ~E1000_RCTL_SBP; + + switch (adapter->rx_buffer_len) { + default: + case 2048: + rctl |= E1000_RCTL_SZ_2048; + break; + case 4096: + rctl |= E1000_RCTL_SZ_4096 | + E1000_RCTL_BSEX | E1000_RCTL_LPE; + break; + case 8192: + rctl |= E1000_RCTL_SZ_8192 | + E1000_RCTL_BSEX | E1000_RCTL_LPE; + break; + case 16384: + rctl |= E1000_RCTL_SZ_16384 | + E1000_RCTL_BSEX | E1000_RCTL_LPE; + break; + } + + if (ifp->if_mtu > ETHERMTU) + rctl |= E1000_RCTL_LPE; + else + rctl &= ~E1000_RCTL_LPE; + + /* Enable 82543 Receive Checksum Offload for TCP and UDP */ + if ((adapter->hw.mac.type >= e1000_82543) && + (ifp->if_capenable & IFCAP_RXCSUM)) { + rxcsum = E1000_READ_REG(&adapter->hw, E1000_RXCSUM); + rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL); + E1000_WRITE_REG(&adapter->hw, E1000_RXCSUM, rxcsum); + } + + /* Enable Receives */ + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl); + + /* + * Setup the HW Rx Head and + * Tail Descriptor Pointers + */ + E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0); + E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), adapter->num_rx_desc - 1); + + return; +} + +/********************************************************************* + * + * Free receive related data structures. + * + **********************************************************************/ +static void +lem_free_receive_structures(struct adapter *adapter) +{ + struct em_buffer *rx_buffer; + int i; + + INIT_DEBUGOUT("free_receive_structures: begin"); + + if (adapter->rx_sparemap) { + bus_dmamap_destroy(adapter->rxtag, adapter->rx_sparemap); + adapter->rx_sparemap = NULL; + } + + /* Cleanup any existing buffers */ + if (adapter->rx_buffer_area != NULL) { + rx_buffer = adapter->rx_buffer_area; + for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) { + if (rx_buffer->m_head != NULL) { + bus_dmamap_sync(adapter->rxtag, rx_buffer->map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(adapter->rxtag, + rx_buffer->map); + m_freem(rx_buffer->m_head); + rx_buffer->m_head = NULL; + } else if (rx_buffer->map != NULL) + bus_dmamap_unload(adapter->rxtag, + rx_buffer->map); + if (rx_buffer->map != NULL) { + bus_dmamap_destroy(adapter->rxtag, + rx_buffer->map); + rx_buffer->map = NULL; + } + } + } + + if (adapter->rx_buffer_area != NULL) { + free(adapter->rx_buffer_area, M_DEVBUF); + adapter->rx_buffer_area = NULL; + } + + if (adapter->rxtag != NULL) { + bus_dma_tag_destroy(adapter->rxtag); + adapter->rxtag = NULL; + } +} + +/********************************************************************* + * + * This routine executes in interrupt context. It replenishes + * the mbufs in the descriptor and sends data which has been + * dma'ed into host memory to upper layer. + * + * We loop at most count times if count is > 0, or until done if + * count < 0. + * + * For polling we also now return the number of cleaned packets + *********************************************************************/ +static int +lem_rxeof(struct adapter *adapter, int count) +{ + struct ifnet *ifp = adapter->ifp;; + struct mbuf *mp; + u8 status, accept_frame = 0, eop = 0; + u16 len, desc_len, prev_len_adj; + int i, rx_sent = 0; + struct e1000_rx_desc *current_desc; + + EM_RX_LOCK(adapter); + i = adapter->next_rx_desc_to_check; + current_desc = &adapter->rx_desc_base[i]; + bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, + BUS_DMASYNC_POSTREAD); + + if (!((current_desc->status) & E1000_RXD_STAT_DD)) { + EM_RX_UNLOCK(adapter); + return (rx_sent); + } + + while ((current_desc->status & E1000_RXD_STAT_DD) && + (count != 0) && + (ifp->if_drv_flags & IFF_DRV_RUNNING)) { + struct mbuf *m = NULL; + + mp = adapter->rx_buffer_area[i].m_head; + /* + * Can't defer bus_dmamap_sync(9) because TBI_ACCEPT + * needs to access the last received byte in the mbuf. + */ + bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map, + BUS_DMASYNC_POSTREAD); + + accept_frame = 1; + prev_len_adj = 0; + desc_len = le16toh(current_desc->length); + status = current_desc->status; + if (status & E1000_RXD_STAT_EOP) { + count--; + eop = 1; + if (desc_len < ETHER_CRC_LEN) { + len = 0; + prev_len_adj = ETHER_CRC_LEN - desc_len; + } else + len = desc_len - ETHER_CRC_LEN; + } else { + eop = 0; + len = desc_len; + } + + if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) { + u8 last_byte; + u32 pkt_len = desc_len; + + if (adapter->fmp != NULL) + pkt_len += adapter->fmp->m_pkthdr.len; + + last_byte = *(mtod(mp, caddr_t) + desc_len - 1); + if (TBI_ACCEPT(&adapter->hw, status, + current_desc->errors, pkt_len, last_byte, + adapter->min_frame_size, adapter->max_frame_size)) { + e1000_tbi_adjust_stats_82543(&adapter->hw, + &adapter->stats, pkt_len, + adapter->hw.mac.addr, + adapter->max_frame_size); + if (len > 0) + len--; + } else + accept_frame = 0; + } + + if (accept_frame) { + if (lem_get_buf(adapter, i) != 0) { + ifp->if_iqdrops++; + goto discard; + } + + /* Assign correct length to the current fragment */ + mp->m_len = len; + + if (adapter->fmp == NULL) { + mp->m_pkthdr.len = len; + adapter->fmp = mp; /* Store the first mbuf */ + adapter->lmp = mp; + } else { + /* Chain mbuf's together */ + mp->m_flags &= ~M_PKTHDR; + /* + * Adjust length of previous mbuf in chain if + * we received less than 4 bytes in the last + * descriptor. + */ + if (prev_len_adj > 0) { + adapter->lmp->m_len -= prev_len_adj; + adapter->fmp->m_pkthdr.len -= + prev_len_adj; + } + adapter->lmp->m_next = mp; + adapter->lmp = adapter->lmp->m_next; + adapter->fmp->m_pkthdr.len += len; + } + + if (eop) { + adapter->fmp->m_pkthdr.rcvif = ifp; + ifp->if_ipackets++; + lem_receive_checksum(adapter, current_desc, + adapter->fmp); +#ifndef __NO_STRICT_ALIGNMENT + if (adapter->max_frame_size > + (MCLBYTES - ETHER_ALIGN) && + lem_fixup_rx(adapter) != 0) + goto skip; +#endif + if (status & E1000_RXD_STAT_VP) { +#if __FreeBSD_version < 700000 + VLAN_INPUT_TAG_NEW(ifp, adapter->fmp, + (le16toh(current_desc->special) & + E1000_RXD_SPC_VLAN_MASK)); +#else + adapter->fmp->m_pkthdr.ether_vtag = + (le16toh(current_desc->special) & + E1000_RXD_SPC_VLAN_MASK); + adapter->fmp->m_flags |= M_VLANTAG; +#endif + } +#ifndef __NO_STRICT_ALIGNMENT +skip: +#endif + m = adapter->fmp; + adapter->fmp = NULL; + adapter->lmp = NULL; + } + } else { + ifp->if_ierrors++; +discard: + /* Reuse loaded DMA map and just update mbuf chain */ + mp = adapter->rx_buffer_area[i].m_head; + mp->m_len = mp->m_pkthdr.len = MCLBYTES; + mp->m_data = mp->m_ext.ext_buf; + mp->m_next = NULL; + if (adapter->max_frame_size <= + (MCLBYTES - ETHER_ALIGN)) + m_adj(mp, ETHER_ALIGN); + if (adapter->fmp != NULL) { + m_freem(adapter->fmp); + adapter->fmp = NULL; + adapter->lmp = NULL; + } + m = NULL; + } + + /* Zero out the receive descriptors status. */ + current_desc->status = 0; + bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + /* Advance our pointers to the next descriptor. */ + if (++i == adapter->num_rx_desc) + i = 0; + /* Call into the stack */ + if (m != NULL) { + adapter->next_rx_desc_to_check = i; + EM_RX_UNLOCK(adapter); + (*ifp->if_input)(ifp, m); + EM_RX_LOCK(adapter); + rx_sent++; + i = adapter->next_rx_desc_to_check; + } + current_desc = &adapter->rx_desc_base[i]; + } + adapter->next_rx_desc_to_check = i; + + /* Advance the E1000's Receive Queue #0 "Tail Pointer". */ + if (--i < 0) + i = adapter->num_rx_desc - 1; + E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i); + EM_RX_UNLOCK(adapter); + return (rx_sent); +} + +#ifndef __NO_STRICT_ALIGNMENT +/* + * When jumbo frames are enabled we should realign entire payload on + * architecures with strict alignment. This is serious design mistake of 8254x + * as it nullifies DMA operations. 8254x just allows RX buffer size to be + * 2048/4096/8192/16384. What we really want is 2048 - ETHER_ALIGN to align its + * payload. On architecures without strict alignment restrictions 8254x still + * performs unaligned memory access which would reduce the performance too. + * To avoid copying over an entire frame to align, we allocate a new mbuf and + * copy ethernet header to the new mbuf. The new mbuf is prepended into the + * existing mbuf chain. + * + * Be aware, best performance of the 8254x is achived only when jumbo frame is + * not used at all on architectures with strict alignment. + */ +static int +lem_fixup_rx(struct adapter *adapter) +{ + struct mbuf *m, *n; + int error; + + error = 0; + m = adapter->fmp; + if (m->m_len <= (MCLBYTES - ETHER_HDR_LEN)) { + bcopy(m->m_data, m->m_data + ETHER_HDR_LEN, m->m_len); + m->m_data += ETHER_HDR_LEN; + } else { + MGETHDR(n, M_DONTWAIT, MT_DATA); + if (n != NULL) { + bcopy(m->m_data, n->m_data, ETHER_HDR_LEN); + m->m_data += ETHER_HDR_LEN; + m->m_len -= ETHER_HDR_LEN; + n->m_len = ETHER_HDR_LEN; + M_MOVE_PKTHDR(n, m); + n->m_next = m; + adapter->fmp = n; + } else { + adapter->dropped_pkts++; + m_freem(adapter->fmp); + adapter->fmp = NULL; + error = ENOMEM; + } + } + + return (error); +} +#endif + +/********************************************************************* + * + * Verify that the hardware indicated that the checksum is valid. + * Inform the stack about the status of checksum so that stack + * doesn't spend time verifying the checksum. + * + *********************************************************************/ +static void +lem_receive_checksum(struct adapter *adapter, + struct e1000_rx_desc *rx_desc, struct mbuf *mp) +{ + /* 82543 or newer only */ + if ((adapter->hw.mac.type < e1000_82543) || + /* Ignore Checksum bit is set */ + (rx_desc->status & E1000_RXD_STAT_IXSM)) { + mp->m_pkthdr.csum_flags = 0; + return; + } + + if (rx_desc->status & E1000_RXD_STAT_IPCS) { + /* Did it pass? */ + if (!(rx_desc->errors & E1000_RXD_ERR_IPE)) { + /* IP Checksum Good */ + mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED; + mp->m_pkthdr.csum_flags |= CSUM_IP_VALID; + + } else { + mp->m_pkthdr.csum_flags = 0; + } + } + + if (rx_desc->status & E1000_RXD_STAT_TCPCS) { + /* Did it pass? */ + if (!(rx_desc->errors & E1000_RXD_ERR_TCPE)) { + mp->m_pkthdr.csum_flags |= + (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); + mp->m_pkthdr.csum_data = htons(0xffff); + } + } +} + +#if __FreeBSD_version >= 700029 +/* + * This routine is run via an vlan + * config EVENT + */ +static void +lem_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) +{ + struct adapter *adapter = ifp->if_softc; + u32 index, bit; + + if (ifp->if_softc != arg) /* Not our event */ + return; + + if ((vtag == 0) || (vtag > 4095)) /* Invalid ID */ + return; + + index = (vtag >> 5) & 0x7F; + bit = vtag & 0x1F; + lem_shadow_vfta[index] |= (1 << bit); + ++adapter->num_vlans; + /* Re-init to load the changes */ + lem_init(adapter); +} + +/* + * This routine is run via an vlan + * unconfig EVENT + */ +static void +lem_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) +{ + struct adapter *adapter = ifp->if_softc; + u32 index, bit; + + if (ifp->if_softc != arg) + return; + + if ((vtag == 0) || (vtag > 4095)) /* Invalid */ + return; + + index = (vtag >> 5) & 0x7F; + bit = vtag & 0x1F; + lem_shadow_vfta[index] &= ~(1 << bit); + --adapter->num_vlans; + /* Re-init to load the changes */ + lem_init(adapter); +} + +static void +lem_setup_vlan_hw_support(struct adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 reg; + + /* + ** We get here thru init_locked, meaning + ** a soft reset, this has already cleared + ** the VFTA and other state, so if there + ** have been no vlan's registered do nothing. + */ + if (adapter->num_vlans == 0) + return; + + /* + ** A soft reset zero's out the VFTA, so + ** we need to repopulate it now. + */ + for (int i = 0; i < EM_VFTA_SIZE; i++) + if (lem_shadow_vfta[i] != 0) + E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, + i, lem_shadow_vfta[i]); + + reg = E1000_READ_REG(hw, E1000_CTRL); + reg |= E1000_CTRL_VME; + E1000_WRITE_REG(hw, E1000_CTRL, reg); + + /* Enable the Filter Table */ + reg = E1000_READ_REG(hw, E1000_RCTL); + reg &= ~E1000_RCTL_CFIEN; + reg |= E1000_RCTL_VFE; + E1000_WRITE_REG(hw, E1000_RCTL, reg); + + /* Update the frame size */ + E1000_WRITE_REG(&adapter->hw, E1000_RLPML, + adapter->max_frame_size + VLAN_TAG_SIZE); +} +#endif + +static void +lem_enable_intr(struct adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 ims_mask = IMS_ENABLE_MASK; + + if (adapter->msix) { + E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK); + ims_mask |= EM_MSIX_MASK; + } + E1000_WRITE_REG(hw, E1000_IMS, ims_mask); +} + +static void +lem_disable_intr(struct adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + + if (adapter->msix) + E1000_WRITE_REG(hw, EM_EIAC, 0); + E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff); +} + +/* + * Bit of a misnomer, what this really means is + * to enable OS management of the system... aka + * to disable special hardware management features + */ +static void +lem_init_manageability(struct adapter *adapter) +{ + /* A shared code workaround */ + if (adapter->has_manage) { + int manc = E1000_READ_REG(&adapter->hw, E1000_MANC); + /* disable hardware interception of ARP */ + manc &= ~(E1000_MANC_ARP_EN); + E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc); + } +} + +/* + * Give control back to hardware management + * controller if there is one. + */ +static void +lem_release_manageability(struct adapter *adapter) +{ + if (adapter->has_manage) { + int manc = E1000_READ_REG(&adapter->hw, E1000_MANC); + + /* re-enable hardware interception of ARP */ + manc |= E1000_MANC_ARP_EN; + E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc); + } +} + +/* + * lem_get_hw_control sets the {CTRL_EXT|FWSM}:DRV_LOAD bit. + * For ASF and Pass Through versions of f/w this means + * that the driver is loaded. For AMT version type f/w + * this means that the network i/f is open. + */ +static void +lem_get_hw_control(struct adapter *adapter) +{ + u32 ctrl_ext; + + ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); + E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, + ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); + return; +} + +/* + * lem_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit. + * For ASF and Pass Through versions of f/w this means that + * the driver is no longer loaded. For AMT versions of the + * f/w this means that the network i/f is closed. + */ +static void +lem_release_hw_control(struct adapter *adapter) +{ + u32 ctrl_ext; + + if (!adapter->has_manage) + return; + + ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); + E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, + ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD); + return; +} + +static int +lem_is_valid_ether_addr(u8 *addr) +{ + char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; + + if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) { + return (FALSE); + } + + return (TRUE); +} + +/* +** Parse the interface capabilities with regard +** to both system management and wake-on-lan for +** later use. +*/ +static void +lem_get_wakeup(device_t dev) +{ + struct adapter *adapter = device_get_softc(dev); + u16 eeprom_data = 0, device_id, apme_mask; + + adapter->has_manage = e1000_enable_mng_pass_thru(&adapter->hw); + apme_mask = EM_EEPROM_APME; + + switch (adapter->hw.mac.type) { + case e1000_82542: + case e1000_82543: + break; + case e1000_82544: + e1000_read_nvm(&adapter->hw, + NVM_INIT_CONTROL2_REG, 1, &eeprom_data); + apme_mask = EM_82544_APME; + break; + case e1000_82546: + case e1000_82546_rev_3: + if (adapter->hw.bus.func == 1) { + e1000_read_nvm(&adapter->hw, + NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); + break; + } else + e1000_read_nvm(&adapter->hw, + NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); + break; + default: + e1000_read_nvm(&adapter->hw, + NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); + break; + } + if (eeprom_data & apme_mask) + adapter->wol = (E1000_WUFC_MAG | E1000_WUFC_MC); + /* + * We have the eeprom settings, now apply the special cases + * where the eeprom may be wrong or the board won't support + * wake on lan on a particular port + */ + device_id = pci_get_device(dev); + switch (device_id) { + case E1000_DEV_ID_82546GB_PCIE: + adapter->wol = 0; + break; + case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546GB_FIBER: + /* Wake events only supported on port A for dual fiber + * regardless of eeprom setting */ + if (E1000_READ_REG(&adapter->hw, E1000_STATUS) & + E1000_STATUS_FUNC_1) + adapter->wol = 0; + break; + case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: + /* if quad port adapter, disable WoL on all but port A */ + if (global_quad_port_a != 0) + adapter->wol = 0; + /* Reset for multiple quad port adapters */ + if (++global_quad_port_a == 4) + global_quad_port_a = 0; + break; + } + return; +} + + +/* + * Enable PCI Wake On Lan capability + */ +static void +lem_enable_wakeup(device_t dev) +{ + struct adapter *adapter = device_get_softc(dev); + struct ifnet *ifp = adapter->ifp; + u32 pmc, ctrl, ctrl_ext, rctl; + u16 status; + + if ((pci_find_extcap(dev, PCIY_PMG, &pmc) != 0)) + return; + + /* Advertise the wakeup capability */ + ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL); + ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3); + E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); + E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN); + + /* Keep the laser running on Fiber adapters */ + if (adapter->hw.phy.media_type == e1000_media_type_fiber || + adapter->hw.phy.media_type == e1000_media_type_internal_serdes) { + ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); + ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA; + E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext); + } + + /* + ** Determine type of Wakeup: note that wol + ** is set with all bits on by default. + */ + if ((ifp->if_capenable & IFCAP_WOL_MAGIC) == 0) + adapter->wol &= ~E1000_WUFC_MAG; + + if ((ifp->if_capenable & IFCAP_WOL_MCAST) == 0) + adapter->wol &= ~E1000_WUFC_MC; + else { + rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + rctl |= E1000_RCTL_MPE; + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl); + } + + if (adapter->hw.mac.type == e1000_pchlan) { + if (lem_enable_phy_wakeup(adapter)) + return; + } else { + E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN); + E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol); + } + + + /* Request PME */ + status = pci_read_config(dev, pmc + PCIR_POWER_STATUS, 2); + status &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE); + if (ifp->if_capenable & IFCAP_WOL) + status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; + pci_write_config(dev, pmc + PCIR_POWER_STATUS, status, 2); + + return; +} + +/* +** WOL in the newer chipset interfaces (pchlan) +** require thing to be copied into the phy +*/ +static int +lem_enable_phy_wakeup(struct adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 mreg, ret = 0; + u16 preg; + + /* copy MAC RARs to PHY RARs */ + for (int i = 0; i < adapter->hw.mac.rar_entry_count; i++) { + mreg = E1000_READ_REG(hw, E1000_RAL(i)); + e1000_write_phy_reg(hw, BM_RAR_L(i), (u16)(mreg & 0xFFFF)); + e1000_write_phy_reg(hw, BM_RAR_M(i), + (u16)((mreg >> 16) & 0xFFFF)); + mreg = E1000_READ_REG(hw, E1000_RAH(i)); + e1000_write_phy_reg(hw, BM_RAR_H(i), (u16)(mreg & 0xFFFF)); + e1000_write_phy_reg(hw, BM_RAR_CTRL(i), + (u16)((mreg >> 16) & 0xFFFF)); + } + + /* copy MAC MTA to PHY MTA */ + for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) { + mreg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i); + e1000_write_phy_reg(hw, BM_MTA(i), (u16)(mreg & 0xFFFF)); + e1000_write_phy_reg(hw, BM_MTA(i) + 1, + (u16)((mreg >> 16) & 0xFFFF)); + } + + /* configure PHY Rx Control register */ + e1000_read_phy_reg(&adapter->hw, BM_RCTL, &preg); + mreg = E1000_READ_REG(hw, E1000_RCTL); + if (mreg & E1000_RCTL_UPE) + preg |= BM_RCTL_UPE; + if (mreg & E1000_RCTL_MPE) + preg |= BM_RCTL_MPE; + preg &= ~(BM_RCTL_MO_MASK); + if (mreg & E1000_RCTL_MO_3) + preg |= (((mreg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT) + << BM_RCTL_MO_SHIFT); + if (mreg & E1000_RCTL_BAM) + preg |= BM_RCTL_BAM; + if (mreg & E1000_RCTL_PMCF) + preg |= BM_RCTL_PMCF; + mreg = E1000_READ_REG(hw, E1000_CTRL); + if (mreg & E1000_CTRL_RFCE) + preg |= BM_RCTL_RFCE; + e1000_write_phy_reg(&adapter->hw, BM_RCTL, preg); + + /* enable PHY wakeup in MAC register */ + E1000_WRITE_REG(hw, E1000_WUC, + E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN); + E1000_WRITE_REG(hw, E1000_WUFC, adapter->wol); + + /* configure and enable PHY wakeup in PHY registers */ + e1000_write_phy_reg(&adapter->hw, BM_WUFC, adapter->wol); + e1000_write_phy_reg(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); + + /* activate PHY wakeup */ + ret = hw->phy.ops.acquire(hw); + if (ret) { + printf("Could not acquire PHY\n"); + return ret; + } + e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, + (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); + ret = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &preg); + if (ret) { + printf("Could not read PHY page 769\n"); + goto out; + } + preg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; + ret = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, preg); + if (ret) + printf("Could not set PHY Host Wakeup bit\n"); +out: + hw->phy.ops.release(hw); + + return ret; +} + +static void +lem_led_func(void *arg, int onoff) +{ + struct adapter *adapter = arg; + + EM_CORE_LOCK(adapter); + if (onoff) { + e1000_setup_led(&adapter->hw); + e1000_led_on(&adapter->hw); + } else { + e1000_led_off(&adapter->hw); + e1000_cleanup_led(&adapter->hw); + } + EM_CORE_UNLOCK(adapter); +} + +/********************************************************************* +* 82544 Coexistence issue workaround. +* There are 2 issues. +* 1. Transmit Hang issue. +* To detect this issue, following equation can be used... +* SIZE[3:0] + ADDR[2:0] = SUM[3:0]. +* If SUM[3:0] is in between 1 to 4, we will have this issue. +* +* 2. DAC issue. +* To detect this issue, following equation can be used... +* SIZE[3:0] + ADDR[2:0] = SUM[3:0]. +* If SUM[3:0] is in between 9 to c, we will have this issue. +* +* +* WORKAROUND: +* Make sure we do not have ending address +* as 1,2,3,4(Hang) or 9,a,b,c (DAC) +* +*************************************************************************/ +static u32 +lem_fill_descriptors (bus_addr_t address, u32 length, + PDESC_ARRAY desc_array) +{ + u32 safe_terminator; + + /* Since issue is sensitive to length and address.*/ + /* Let us first check the address...*/ + if (length <= 4) { + desc_array->descriptor[0].address = address; + desc_array->descriptor[0].length = length; + desc_array->elements = 1; + return (desc_array->elements); + } + safe_terminator = (u32)((((u32)address & 0x7) + + (length & 0xF)) & 0xF); + /* if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then return */ + if (safe_terminator == 0 || + (safe_terminator > 4 && + safe_terminator < 9) || + (safe_terminator > 0xC && + safe_terminator <= 0xF)) { + desc_array->descriptor[0].address = address; + desc_array->descriptor[0].length = length; + desc_array->elements = 1; + return (desc_array->elements); + } + + desc_array->descriptor[0].address = address; + desc_array->descriptor[0].length = length - 4; + desc_array->descriptor[1].address = address + (length - 4); + desc_array->descriptor[1].length = 4; + desc_array->elements = 2; + return (desc_array->elements); +} + +/********************************************************************** + * + * Update the board statistics counters. + * + **********************************************************************/ +static void +lem_update_stats_counters(struct adapter *adapter) +{ + struct ifnet *ifp; + + if(adapter->hw.phy.media_type == e1000_media_type_copper || + (E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) { + adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, E1000_SYMERRS); + adapter->stats.sec += E1000_READ_REG(&adapter->hw, E1000_SEC); + } + adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, E1000_CRCERRS); + adapter->stats.mpc += E1000_READ_REG(&adapter->hw, E1000_MPC); + adapter->stats.scc += E1000_READ_REG(&adapter->hw, E1000_SCC); + adapter->stats.ecol += E1000_READ_REG(&adapter->hw, E1000_ECOL); + + adapter->stats.mcc += E1000_READ_REG(&adapter->hw, E1000_MCC); + adapter->stats.latecol += E1000_READ_REG(&adapter->hw, E1000_LATECOL); + adapter->stats.colc += E1000_READ_REG(&adapter->hw, E1000_COLC); + adapter->stats.dc += E1000_READ_REG(&adapter->hw, E1000_DC); + adapter->stats.rlec += E1000_READ_REG(&adapter->hw, E1000_RLEC); + adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, E1000_XONRXC); + adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, E1000_XONTXC); + adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, E1000_XOFFRXC); + adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC); + adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC); + adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64); + adapter->stats.prc127 += E1000_READ_REG(&adapter->hw, E1000_PRC127); + adapter->stats.prc255 += E1000_READ_REG(&adapter->hw, E1000_PRC255); + adapter->stats.prc511 += E1000_READ_REG(&adapter->hw, E1000_PRC511); + adapter->stats.prc1023 += E1000_READ_REG(&adapter->hw, E1000_PRC1023); + adapter->stats.prc1522 += E1000_READ_REG(&adapter->hw, E1000_PRC1522); + adapter->stats.gprc += E1000_READ_REG(&adapter->hw, E1000_GPRC); + adapter->stats.bprc += E1000_READ_REG(&adapter->hw, E1000_BPRC); + adapter->stats.mprc += E1000_READ_REG(&adapter->hw, E1000_MPRC); + adapter->stats.gptc += E1000_READ_REG(&adapter->hw, E1000_GPTC); + + /* For the 64-bit byte counters the low dword must be read first. */ + /* Both registers clear on the read of the high dword */ + + adapter->stats.gorc += E1000_READ_REG(&adapter->hw, E1000_GORCH); + adapter->stats.gotc += E1000_READ_REG(&adapter->hw, E1000_GOTCH); + + adapter->stats.rnbc += E1000_READ_REG(&adapter->hw, E1000_RNBC); + adapter->stats.ruc += E1000_READ_REG(&adapter->hw, E1000_RUC); + adapter->stats.rfc += E1000_READ_REG(&adapter->hw, E1000_RFC); + adapter->stats.roc += E1000_READ_REG(&adapter->hw, E1000_ROC); + adapter->stats.rjc += E1000_READ_REG(&adapter->hw, E1000_RJC); + + adapter->stats.tor += E1000_READ_REG(&adapter->hw, E1000_TORH); + adapter->stats.tot += E1000_READ_REG(&adapter->hw, E1000_TOTH); + + adapter->stats.tpr += E1000_READ_REG(&adapter->hw, E1000_TPR); + adapter->stats.tpt += E1000_READ_REG(&adapter->hw, E1000_TPT); + adapter->stats.ptc64 += E1000_READ_REG(&adapter->hw, E1000_PTC64); + adapter->stats.ptc127 += E1000_READ_REG(&adapter->hw, E1000_PTC127); + adapter->stats.ptc255 += E1000_READ_REG(&adapter->hw, E1000_PTC255); + adapter->stats.ptc511 += E1000_READ_REG(&adapter->hw, E1000_PTC511); + adapter->stats.ptc1023 += E1000_READ_REG(&adapter->hw, E1000_PTC1023); + adapter->stats.ptc1522 += E1000_READ_REG(&adapter->hw, E1000_PTC1522); + adapter->stats.mptc += E1000_READ_REG(&adapter->hw, E1000_MPTC); + adapter->stats.bptc += E1000_READ_REG(&adapter->hw, E1000_BPTC); + + if (adapter->hw.mac.type >= e1000_82543) { + adapter->stats.algnerrc += + E1000_READ_REG(&adapter->hw, E1000_ALGNERRC); + adapter->stats.rxerrc += + E1000_READ_REG(&adapter->hw, E1000_RXERRC); + adapter->stats.tncrs += + E1000_READ_REG(&adapter->hw, E1000_TNCRS); + adapter->stats.cexterr += + E1000_READ_REG(&adapter->hw, E1000_CEXTERR); + adapter->stats.tsctc += + E1000_READ_REG(&adapter->hw, E1000_TSCTC); + adapter->stats.tsctfc += + E1000_READ_REG(&adapter->hw, E1000_TSCTFC); + } + ifp = adapter->ifp; + + ifp->if_collisions = adapter->stats.colc; + + /* Rx Errors */ + ifp->if_ierrors = adapter->dropped_pkts + adapter->stats.rxerrc + + adapter->stats.crcerrs + adapter->stats.algnerrc + + adapter->stats.ruc + adapter->stats.roc + + adapter->stats.mpc + adapter->stats.cexterr; + + /* Tx Errors */ + ifp->if_oerrors = adapter->stats.ecol + + adapter->stats.latecol + adapter->watchdog_events; +} + + +/********************************************************************** + * + * This routine is called only when lem_display_debug_stats is enabled. + * This routine provides a way to take a look at important statistics + * maintained by the driver and hardware. + * + **********************************************************************/ +static void +lem_print_debug_info(struct adapter *adapter) +{ + device_t dev = adapter->dev; + u8 *hw_addr = adapter->hw.hw_addr; + + device_printf(dev, "Adapter hardware address = %p \n", hw_addr); + device_printf(dev, "CTRL = 0x%x RCTL = 0x%x \n", + E1000_READ_REG(&adapter->hw, E1000_CTRL), + E1000_READ_REG(&adapter->hw, E1000_RCTL)); + device_printf(dev, "Packet buffer = Tx=%dk Rx=%dk \n", + ((E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff0000) >> 16),\ + (E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff) ); + device_printf(dev, "Flow control watermarks high = %d low = %d\n", + adapter->hw.fc.high_water, + adapter->hw.fc.low_water); + device_printf(dev, "tx_int_delay = %d, tx_abs_int_delay = %d\n", + E1000_READ_REG(&adapter->hw, E1000_TIDV), + E1000_READ_REG(&adapter->hw, E1000_TADV)); + device_printf(dev, "rx_int_delay = %d, rx_abs_int_delay = %d\n", + E1000_READ_REG(&adapter->hw, E1000_RDTR), + E1000_READ_REG(&adapter->hw, E1000_RADV)); + device_printf(dev, "fifo workaround = %lld, fifo_reset_count = %lld\n", + (long long)adapter->tx_fifo_wrk_cnt, + (long long)adapter->tx_fifo_reset_cnt); + device_printf(dev, "hw tdh = %d, hw tdt = %d\n", + E1000_READ_REG(&adapter->hw, E1000_TDH(0)), + E1000_READ_REG(&adapter->hw, E1000_TDT(0))); + device_printf(dev, "hw rdh = %d, hw rdt = %d\n", + E1000_READ_REG(&adapter->hw, E1000_RDH(0)), + E1000_READ_REG(&adapter->hw, E1000_RDT(0))); + device_printf(dev, "Num Tx descriptors avail = %d\n", + adapter->num_tx_desc_avail); + device_printf(dev, "Tx Descriptors not avail1 = %ld\n", + adapter->no_tx_desc_avail1); + device_printf(dev, "Tx Descriptors not avail2 = %ld\n", + adapter->no_tx_desc_avail2); + device_printf(dev, "Std mbuf failed = %ld\n", + adapter->mbuf_alloc_failed); + device_printf(dev, "Std mbuf cluster failed = %ld\n", + adapter->mbuf_cluster_failed); + device_printf(dev, "Driver dropped packets = %ld\n", + adapter->dropped_pkts); + device_printf(dev, "Driver tx dma failure in encap = %ld\n", + adapter->no_tx_dma_setup); +} + +static void +lem_print_hw_stats(struct adapter *adapter) +{ + device_t dev = adapter->dev; + + device_printf(dev, "Excessive collisions = %lld\n", + (long long)adapter->stats.ecol); +#if (DEBUG_HW > 0) /* Dont output these errors normally */ + device_printf(dev, "Symbol errors = %lld\n", + (long long)adapter->stats.symerrs); +#endif + device_printf(dev, "Sequence errors = %lld\n", + (long long)adapter->stats.sec); + device_printf(dev, "Defer count = %lld\n", + (long long)adapter->stats.dc); + device_printf(dev, "Missed Packets = %lld\n", + (long long)adapter->stats.mpc); + device_printf(dev, "Receive No Buffers = %lld\n", + (long long)adapter->stats.rnbc); + /* RLEC is inaccurate on some hardware, calculate our own. */ + device_printf(dev, "Receive Length Errors = %lld\n", + ((long long)adapter->stats.roc + (long long)adapter->stats.ruc)); + device_printf(dev, "Receive errors = %lld\n", + (long long)adapter->stats.rxerrc); + device_printf(dev, "Crc errors = %lld\n", + (long long)adapter->stats.crcerrs); + device_printf(dev, "Alignment errors = %lld\n", + (long long)adapter->stats.algnerrc); + device_printf(dev, "Collision/Carrier extension errors = %lld\n", + (long long)adapter->stats.cexterr); + device_printf(dev, "RX overruns = %ld\n", adapter->rx_overruns); + device_printf(dev, "watchdog timeouts = %ld\n", + adapter->watchdog_events); + device_printf(dev, "RX MSIX IRQ = %ld TX MSIX IRQ = %ld" + " LINK MSIX IRQ = %ld\n", adapter->rx_irq, + adapter->tx_irq , adapter->link_irq); + device_printf(dev, "XON Rcvd = %lld\n", + (long long)adapter->stats.xonrxc); + device_printf(dev, "XON Xmtd = %lld\n", + (long long)adapter->stats.xontxc); + device_printf(dev, "XOFF Rcvd = %lld\n", + (long long)adapter->stats.xoffrxc); + device_printf(dev, "XOFF Xmtd = %lld\n", + (long long)adapter->stats.xofftxc); + device_printf(dev, "Good Packets Rcvd = %lld\n", + (long long)adapter->stats.gprc); + device_printf(dev, "Good Packets Xmtd = %lld\n", + (long long)adapter->stats.gptc); + device_printf(dev, "TSO Contexts Xmtd = %lld\n", + (long long)adapter->stats.tsctc); + device_printf(dev, "TSO Contexts Failed = %lld\n", + (long long)adapter->stats.tsctfc); +} + +/********************************************************************** + * + * This routine provides a way to dump out the adapter eeprom, + * often a useful debug/service tool. This only dumps the first + * 32 words, stuff that matters is in that extent. + * + **********************************************************************/ +static void +lem_print_nvm_info(struct adapter *adapter) +{ + u16 eeprom_data; + int i, j, row = 0; + + /* Its a bit crude, but it gets the job done */ + printf("\nInterface EEPROM Dump:\n"); + printf("Offset\n0x0000 "); + for (i = 0, j = 0; i < 32; i++, j++) { + if (j == 8) { /* Make the offset block */ + j = 0; ++row; + printf("\n0x00%x0 ",row); + } + e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data); + printf("%04x ", eeprom_data); + } + printf("\n"); +} + +static int +lem_sysctl_debug_info(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter; + int error; + int result; + + result = -1; + error = sysctl_handle_int(oidp, &result, 0, req); + + if (error || !req->newptr) + return (error); + + if (result == 1) { + adapter = (struct adapter *)arg1; + lem_print_debug_info(adapter); + } + /* + * This value will cause a hex dump of the + * first 32 16-bit words of the EEPROM to + * the screen. + */ + if (result == 2) { + adapter = (struct adapter *)arg1; + lem_print_nvm_info(adapter); + } + + return (error); +} + + +static int +lem_sysctl_stats(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter; + int error; + int result; + + result = -1; + error = sysctl_handle_int(oidp, &result, 0, req); + + if (error || !req->newptr) + return (error); + + if (result == 1) { + adapter = (struct adapter *)arg1; + lem_print_hw_stats(adapter); + } + + return (error); +} + +static int +lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS) +{ + struct em_int_delay_info *info; + struct adapter *adapter; + u32 regval; + int error; + int usecs; + int ticks; + + info = (struct em_int_delay_info *)arg1; + usecs = info->value; + error = sysctl_handle_int(oidp, &usecs, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (usecs < 0 || usecs > EM_TICKS_TO_USECS(65535)) + return (EINVAL); + info->value = usecs; + ticks = EM_USECS_TO_TICKS(usecs); + + adapter = info->adapter; + + EM_CORE_LOCK(adapter); + regval = E1000_READ_OFFSET(&adapter->hw, info->offset); + regval = (regval & ~0xffff) | (ticks & 0xffff); + /* Handle a few special cases. */ + switch (info->offset) { + case E1000_RDTR: + break; + case E1000_TIDV: + if (ticks == 0) { + adapter->txd_cmd &= ~E1000_TXD_CMD_IDE; + /* Don't write 0 into the TIDV register. */ + regval++; + } else + adapter->txd_cmd |= E1000_TXD_CMD_IDE; + break; + } + E1000_WRITE_OFFSET(&adapter->hw, info->offset, regval); + EM_CORE_UNLOCK(adapter); + return (0); +} + +static void +lem_add_int_delay_sysctl(struct adapter *adapter, const char *name, + const char *description, struct em_int_delay_info *info, + int offset, int value) +{ + info->adapter = adapter; + info->offset = offset; + info->value = value; + SYSCTL_ADD_PROC(device_get_sysctl_ctx(adapter->dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), + OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, + info, 0, lem_sysctl_int_delay, "I", description); +} + +#ifndef EM_LEGACY_IRQ +static void +lem_add_rx_process_limit(struct adapter *adapter, const char *name, + const char *description, int *limit, int value) +{ + *limit = value; + SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), + OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); +} +#endif + + diff --git a/sys/dev/e1000/if_lem.h b/sys/dev/e1000/if_lem.h new file mode 100644 index 00000000000..13c2cbc4dd3 --- /dev/null +++ b/sys/dev/e1000/if_lem.h @@ -0,0 +1,481 @@ +/****************************************************************************** + + Copyright (c) 2001-2010, Intel Corporation + 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. + + 3. Neither the name of the Intel 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. + +******************************************************************************/ +/*$FreeBSD$*/ + + +#ifndef _LEM_H_DEFINED_ +#define _LEM_H_DEFINED_ + + +/* Tunables */ + +/* + * EM_TXD: Maximum number of Transmit Descriptors + * Valid Range: 80-256 for 82542 and 82543-based adapters + * 80-4096 for others + * Default Value: 256 + * This value is the number of transmit descriptors allocated by the driver. + * Increasing this value allows the driver to queue more transmits. Each + * descriptor is 16 bytes. + * Since TDLEN should be multiple of 128bytes, the number of transmit + * desscriptors should meet the following condition. + * (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0 + */ +#define EM_MIN_TXD 80 +#define EM_MAX_TXD_82543 256 +#define EM_MAX_TXD 4096 +#define EM_DEFAULT_TXD EM_MAX_TXD_82543 + +/* + * EM_RXD - Maximum number of receive Descriptors + * Valid Range: 80-256 for 82542 and 82543-based adapters + * 80-4096 for others + * Default Value: 256 + * This value is the number of receive descriptors allocated by the driver. + * Increasing this value allows the driver to buffer more incoming packets. + * Each descriptor is 16 bytes. A receive buffer is also allocated for each + * descriptor. The maximum MTU size is 16110. + * Since TDLEN should be multiple of 128bytes, the number of transmit + * desscriptors should meet the following condition. + * (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0 + */ +#define EM_MIN_RXD 80 +#define EM_MAX_RXD_82543 256 +#define EM_MAX_RXD 4096 +#define EM_DEFAULT_RXD EM_MAX_RXD_82543 + +/* + * EM_TIDV - Transmit Interrupt Delay Value + * Valid Range: 0-65535 (0=off) + * Default Value: 64 + * This value delays the generation of transmit interrupts in units of + * 1.024 microseconds. Transmit interrupt reduction can improve CPU + * efficiency if properly tuned for specific network traffic. If the + * system is reporting dropped transmits, this value may be set too high + * causing the driver to run out of available transmit descriptors. + */ +#define EM_TIDV 64 + +/* + * EM_TADV - Transmit Absolute Interrupt Delay Value + * (Not valid for 82542/82543/82544) + * Valid Range: 0-65535 (0=off) + * Default Value: 64 + * This value, in units of 1.024 microseconds, limits the delay in which a + * transmit interrupt is generated. Useful only if EM_TIDV is non-zero, + * this value ensures that an interrupt is generated after the initial + * packet is sent on the wire within the set amount of time. Proper tuning, + * along with EM_TIDV, may improve traffic throughput in specific + * network conditions. + */ +#define EM_TADV 64 + +/* + * EM_RDTR - Receive Interrupt Delay Timer (Packet Timer) + * Valid Range: 0-65535 (0=off) + * Default Value: 0 + * This value delays the generation of receive interrupts in units of 1.024 + * microseconds. Receive interrupt reduction can improve CPU efficiency if + * properly tuned for specific network traffic. Increasing this value adds + * extra latency to frame reception and can end up decreasing the throughput + * of TCP traffic. If the system is reporting dropped receives, this value + * may be set too high, causing the driver to run out of available receive + * descriptors. + * + * CAUTION: When setting EM_RDTR to a value other than 0, adapters + * may hang (stop transmitting) under certain network conditions. + * If this occurs a WATCHDOG message is logged in the system + * event log. In addition, the controller is automatically reset, + * restoring the network connection. To eliminate the potential + * for the hang ensure that EM_RDTR is set to 0. + */ +#define EM_RDTR 0 + +/* + * Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544) + * Valid Range: 0-65535 (0=off) + * Default Value: 64 + * This value, in units of 1.024 microseconds, limits the delay in which a + * receive interrupt is generated. Useful only if EM_RDTR is non-zero, + * this value ensures that an interrupt is generated after the initial + * packet is received within the set amount of time. Proper tuning, + * along with EM_RDTR, may improve traffic throughput in specific network + * conditions. + */ +#define EM_RADV 64 + +/* + * This parameter controls the max duration of transmit watchdog. + */ +#define EM_WATCHDOG (10 * hz) + +/* + * This parameter controls when the driver calls the routine to reclaim + * transmit descriptors. + */ +#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8) +#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32) + +/* + * This parameter controls whether or not autonegotation is enabled. + * 0 - Disable autonegotiation + * 1 - Enable autonegotiation + */ +#define DO_AUTO_NEG 1 + +/* + * This parameter control whether or not the driver will wait for + * autonegotiation to complete. + * 1 - Wait for autonegotiation to complete + * 0 - Don't wait for autonegotiation to complete + */ +#define WAIT_FOR_AUTO_NEG_DEFAULT 0 + +/* Tunables -- End */ + +#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \ + ADVERTISE_100_HALF | ADVERTISE_100_FULL | \ + ADVERTISE_1000_FULL) + +#define AUTO_ALL_MODES 0 + +/* PHY master/slave setting */ +#define EM_MASTER_SLAVE e1000_ms_hw_default + +/* + * Micellaneous constants + */ +#define EM_VENDOR_ID 0x8086 +#define EM_FLASH 0x0014 + +#define EM_JUMBO_PBA 0x00000028 +#define EM_DEFAULT_PBA 0x00000030 +#define EM_SMARTSPEED_DOWNSHIFT 3 +#define EM_SMARTSPEED_MAX 15 +#define EM_MAX_LOOP 10 + +#define MAX_NUM_MULTICAST_ADDRESSES 128 +#define PCI_ANY_ID (~0U) +#define ETHER_ALIGN 2 +#define EM_FC_PAUSE_TIME 0x0680 +#define EM_EEPROM_APME 0x400; +#define EM_82544_APME 0x0004; + +/* Code compatilbility between 6 and 7 */ +#ifndef ETHER_BPF_MTAP +#define ETHER_BPF_MTAP BPF_MTAP +#endif + +/* + * TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be + * multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will + * also optimize cache line size effect. H/W supports up to cache line size 128. + */ +#define EM_DBA_ALIGN 128 + +#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */ + +/* PCI Config defines */ +#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK) +#define EM_BAR_TYPE_MASK 0x00000001 +#define EM_BAR_TYPE_MMEM 0x00000000 +#define EM_BAR_TYPE_IO 0x00000001 +#define EM_BAR_TYPE_FLASH 0x0014 +#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK) +#define EM_BAR_MEM_TYPE_MASK 0x00000006 +#define EM_BAR_MEM_TYPE_32BIT 0x00000000 +#define EM_BAR_MEM_TYPE_64BIT 0x00000004 +#define EM_MSIX_BAR 3 /* On 82575 */ + +/* Defines for printing debug information */ +#define DEBUG_INIT 0 +#define DEBUG_IOCTL 0 +#define DEBUG_HW 0 + +#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n") +#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A) +#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B) +#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n") +#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A) +#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B) +#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n") +#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A) +#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B) + +#define EM_MAX_SCATTER 64 +#define EM_VFTA_SIZE 128 +#define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header)) +#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */ +#define EM_MSIX_MASK 0x01F00000 /* For 82574 use */ +#define ETH_ZLEN 60 +#define ETH_ADDR_LEN 6 +#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */ + +/* + * 82574 has a nonstandard address for EIAC + * and since its only used in MSIX, and in + * the em driver only 82574 uses MSIX we can + * solve it just using this define. + */ +#define EM_EIAC 0x000DC + +/* Used in for 82547 10Mb Half workaround */ +#define EM_PBA_BYTES_SHIFT 0xA +#define EM_TX_HEAD_ADDR_SHIFT 7 +#define EM_PBA_TX_MASK 0xFFFF0000 +#define EM_FIFO_HDR 0x10 +#define EM_82547_PKT_THRESH 0x3e0 + +/* Precision Time Sync (IEEE 1588) defines */ +#define ETHERTYPE_IEEE1588 0x88F7 +#define PICOSECS_PER_TICK 20833 +#define TSYNC_PORT 319 /* UDP port for the protocol */ + +/* + * Bus dma allocation structure used by + * e1000_dma_malloc and e1000_dma_free. + */ +struct em_dma_alloc { + bus_addr_t dma_paddr; + caddr_t dma_vaddr; + bus_dma_tag_t dma_tag; + bus_dmamap_t dma_map; + bus_dma_segment_t dma_seg; + int dma_nseg; +}; + +struct adapter; + +struct em_int_delay_info { + struct adapter *adapter; /* Back-pointer to the adapter struct */ + int offset; /* Register offset to read/write */ + int value; /* Current value in usecs */ +}; + +/* Our adapter structure */ +struct adapter { + struct ifnet *ifp; +#if __FreeBSD_version >= 800000 + struct buf_ring *br; +#endif + struct e1000_hw hw; + + /* FreeBSD operating-system-specific structures. */ + struct e1000_osdep osdep; + struct device *dev; + struct cdev *led_dev; + + struct resource *memory; + struct resource *flash; + struct resource *msix; + + struct resource *ioport; + int io_rid; + + /* 82574 may use 3 int vectors */ + struct resource *res[3]; + void *tag[3]; + int rid[3]; + + struct ifmedia media; + struct callout timer; + struct callout tx_fifo_timer; + bool watchdog_check; + int watchdog_time; + int msi; + int if_flags; + int max_frame_size; + int min_frame_size; + struct mtx core_mtx; + struct mtx tx_mtx; + struct mtx rx_mtx; + int em_insert_vlan_header; + + /* Task for FAST handling */ + struct task link_task; + struct task rxtx_task; + struct task rx_task; + struct task tx_task; + struct taskqueue *tq; /* private task queue */ + +#if __FreeBSD_version >= 700029 + eventhandler_tag vlan_attach; + eventhandler_tag vlan_detach; + u32 num_vlans; +#endif + + /* Management and WOL features */ + u32 wol; + bool has_manage; + bool has_amt; + + /* Info about the board itself */ + uint8_t link_active; + uint16_t link_speed; + uint16_t link_duplex; + uint32_t smartspeed; + struct em_int_delay_info tx_int_delay; + struct em_int_delay_info tx_abs_int_delay; + struct em_int_delay_info rx_int_delay; + struct em_int_delay_info rx_abs_int_delay; + + /* + * Transmit definitions + * + * We have an array of num_tx_desc descriptors (handled + * by the controller) paired with an array of tx_buffers + * (at tx_buffer_area). + * The index of the next available descriptor is next_avail_tx_desc. + * The number of remaining tx_desc is num_tx_desc_avail. + */ + struct em_dma_alloc txdma; /* bus_dma glue for tx desc */ + struct e1000_tx_desc *tx_desc_base; + uint32_t next_avail_tx_desc; + uint32_t next_tx_to_clean; + volatile uint16_t num_tx_desc_avail; + uint16_t num_tx_desc; + uint16_t last_hw_offload; + uint32_t txd_cmd; + struct em_buffer *tx_buffer_area; + bus_dma_tag_t txtag; /* dma tag for tx */ + uint32_t tx_tso; /* last tx was tso */ + + /* + * Receive definitions + * + * we have an array of num_rx_desc rx_desc (handled by the + * controller), and paired with an array of rx_buffers + * (at rx_buffer_area). + * The next pair to check on receive is at offset next_rx_desc_to_check + */ + struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */ + struct e1000_rx_desc *rx_desc_base; + uint32_t next_rx_desc_to_check; + uint32_t rx_buffer_len; + uint16_t num_rx_desc; + int rx_process_limit; + struct em_buffer *rx_buffer_area; + bus_dma_tag_t rxtag; + bus_dmamap_t rx_sparemap; + + /* + * First/last mbuf pointers, for + * collecting multisegment RX packets. + */ + struct mbuf *fmp; + struct mbuf *lmp; + + /* Misc stats maintained by the driver */ + unsigned long dropped_pkts; + unsigned long mbuf_alloc_failed; + unsigned long mbuf_cluster_failed; + unsigned long no_tx_desc_avail1; + unsigned long no_tx_desc_avail2; + unsigned long no_tx_map_avail; + unsigned long no_tx_dma_setup; + unsigned long watchdog_events; + unsigned long rx_overruns; + unsigned long rx_irq; + unsigned long tx_irq; + unsigned long link_irq; + + /* 82547 workaround */ + uint32_t tx_fifo_size; + uint32_t tx_fifo_head; + uint32_t tx_fifo_head_addr; + uint64_t tx_fifo_reset_cnt; + uint64_t tx_fifo_wrk_cnt; + uint32_t tx_head_addr; + + /* For 82544 PCIX Workaround */ + boolean_t pcix_82544; + boolean_t in_detach; + + + struct e1000_hw_stats stats; +}; + +/* ****************************************************************************** + * vendor_info_array + * + * This array contains the list of Subvendor/Subdevice IDs on which the driver + * should load. + * + * ******************************************************************************/ +typedef struct _em_vendor_info_t { + unsigned int vendor_id; + unsigned int device_id; + unsigned int subvendor_id; + unsigned int subdevice_id; + unsigned int index; +} em_vendor_info_t; + +struct em_buffer { + int next_eop; /* Index of the desc to watch */ + struct mbuf *m_head; + bus_dmamap_t map; /* bus_dma map for packet */ +}; + +/* For 82544 PCIX Workaround */ +typedef struct _ADDRESS_LENGTH_PAIR +{ + uint64_t address; + uint32_t length; +} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR; + +typedef struct _DESCRIPTOR_PAIR +{ + ADDRESS_LENGTH_PAIR descriptor[4]; + uint32_t elements; +} DESC_ARRAY, *PDESC_ARRAY; + +#define EM_CORE_LOCK_INIT(_sc, _name) \ + mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF) +#define EM_TX_LOCK_INIT(_sc, _name) \ + mtx_init(&(_sc)->tx_mtx, _name, "EM TX Lock", MTX_DEF) +#define EM_RX_LOCK_INIT(_sc, _name) \ + mtx_init(&(_sc)->rx_mtx, _name, "EM RX Lock", MTX_DEF) +#define EM_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx) +#define EM_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx) +#define EM_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx) +#define EM_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx) +#define EM_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) +#define EM_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx) +#define EM_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx) +#define EM_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx) +#define EM_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) +#define EM_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx) +#define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED) +#define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED) + +#endif /* _LEM_H_DEFINED_ */ From dd75f66126c61bfee28749d47a217afb825582be Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Mon, 5 Apr 2010 21:43:22 +0000 Subject: [PATCH 1836/2592] Add missing module Makefile for ixgbe and em MFCs --- sys/modules/em/Makefile | 18 +++++++++++------- sys/modules/ixgbe/Makefile | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/sys/modules/em/Makefile b/sys/modules/em/Makefile index b5e2c3b6681..3e91c14fbbf 100644 --- a/sys/modules/em/Makefile +++ b/sys/modules/em/Makefile @@ -2,15 +2,19 @@ .PATH: ${.CURDIR}/../../dev/e1000 KMOD = if_em SRCS = device_if.h bus_if.h pci_if.h opt_inet.h -SRCS += if_em.c $(SHARED_SRCS) -SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c -SHARED_SRCS += e1000_80003es2lan.c e1000_82542.c e1000_82541.c e1000_82543.c -SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c e1000_osdep.c -SHARED_SRCS += e1000_82575.c +SRCS += $(CORE_SRC) $(LEGACY_SRC) +SRCS += $(COMMON_SHARED) $(LEGACY_SHARED) $(PCIE_SHARED) +CORE_SRC = if_em.c e1000_osdep.c +# This is the Legacy, pre-PCIE source, it can be +# undefined when using modular driver if not needed +LEGACY_SRC += if_lem.c +COMMON_SHARED = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c +PCIE_SHARED = e1000_80003es2lan.c e1000_ich8lan.c e1000_82571.c e1000_82575.c +LEGACY_SHARED = e1000_82540.c e1000_82542.c e1000_82541.c e1000_82543.c -CFLAGS+= -I${.CURDIR}/../../dev/e1000 +CFLAGS += -I${.CURDIR}/../../dev/e1000 -# DEVICE_POLLING gives you Legacy interrupt handling +# DEVICE_POLLING for a non-interrupt-driven method #CFLAGS += -DDEVICE_POLLING clean: diff --git a/sys/modules/ixgbe/Makefile b/sys/modules/ixgbe/Makefile index 844ac7c5e55..2de7549a581 100644 --- a/sys/modules/ixgbe/Makefile +++ b/sys/modules/ixgbe/Makefile @@ -6,7 +6,7 @@ SRCS += ixgbe.c # Shared source SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c SRCS += ixgbe_82599.c ixgbe_82598.c -CFLAGS+= -I${.CURDIR}/../../dev/ixgbe -DSMP +CFLAGS+= -I${.CURDIR}/../../dev/ixgbe -DSMP -DIXGBE_FDIR clean: rm -f device_if.h bus_if.h pci_if.h setdef* *_StripErr From ece8cb88894bfbd7441dd23c39d57647ef9180b2 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Mon, 5 Apr 2010 23:29:27 +0000 Subject: [PATCH 1837/2592] cxgb(4) MFCs: r204271,r204274,r204348,r204921,r205944,r205945,r205946,r205947,r205948,r205949,r205950,r206109 r204271: Accessing an mbuf after it has been handed off to the hardware is a bad race as it could already have been tx'd and freed by that time. Place the bpf tap just _before_ writing the gen bit. This fixes a panic when running tcpdump on a cxgb interface. r204274: There is no need to test __FreeBSD_version for features that have been around for a long time now (7.1-ish or even earlier); assume they are present. These includes MSI, TSO, LRO, VLAN, INTR_FILTERS, FIRMWARE, etc. Also, eliminate some dead code and clean up in other places as part of this quick once-over. r204348: Support IFCAP_VLANHWTSO in cxgb(4). It works with or without vlanhwtag. While here, remove old DPRINTFs and tidy up the capability code a bit. r204921: Better TwinAx transceiver detection. Originally submitted by: (This is a rewritten, corrected version of that patch) r205944: Refresh the firmware version immediately after it is upgraded (or downgraded). r205945: Improved PHY EDC settings. r205946: Do not attempt to retrieve interrupt information before it is available. r205947: Fix build with "nooptions INET" r205948: Fix tx drop statistics. r205949: Fix signed/unsigned mix-up that allowed txq->in_use to grow beyond txq->size. r205950: Multiple fixes related to queue set sizing and resources: - Only the tunnelq (TXQ_ETH) requires a buf_ring, an ifq, and the watchdog/timer callouts. Do not allocate these for the other tx queues. - Use 16k jumbo clusters only on offload capable cards by default. - Do not allocate a full tx ring for the offload queue if the card is not offload capable. - Slightly better freelist size calculation. - Fix nmbjumbo4 typo, remove unneeded global variables. r206109: Increase response queue size to avoid starvation, add a counter to track it when it does occur. --- sys/dev/cxgb/common/cxgb_ael1002.c | 807 +++++++++++++------------ sys/dev/cxgb/common/cxgb_common.h | 9 +- sys/dev/cxgb/common/cxgb_t3_hw.c | 10 +- sys/dev/cxgb/common/cxgb_version.h | 41 -- sys/dev/cxgb/cxgb_adapter.h | 15 +- sys/dev/cxgb/cxgb_config.h | 40 -- sys/dev/cxgb/cxgb_main.c | 235 +++---- sys/dev/cxgb/cxgb_offload.h | 2 - sys/dev/cxgb/cxgb_osdep.h | 30 - sys/dev/cxgb/cxgb_sge.c | 248 ++++---- sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c | 3 +- sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c | 1 - sys/modules/cxgb/cxgb/Makefile | 8 - 13 files changed, 646 insertions(+), 803 deletions(-) delete mode 100644 sys/dev/cxgb/common/cxgb_version.h delete mode 100644 sys/dev/cxgb/cxgb_config.h diff --git a/sys/dev/cxgb/common/cxgb_ael1002.c b/sys/dev/cxgb/common/cxgb_ael1002.c index ec5ffe7aedb..fc2e1408138 100644 --- a/sys/dev/cxgb/common/cxgb_ael1002.c +++ b/sys/dev/cxgb/common/cxgb_ael1002.c @@ -446,7 +446,7 @@ static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms) return v; if (v == 0x1) - return phy_modtype_twinax; + goto twinax; if (v == 0x10) return phy_modtype_sr; if (v == 0x20) @@ -454,6 +454,17 @@ static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms) if (v == 0x40) return phy_modtype_lrm; + v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 8); + if (v < 0) + return v; + if (v == 4) { + v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 60); + if (v < 0) + return v; + if (v & 0x1) + goto twinax; + } + v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6); if (v < 0) return v; @@ -465,6 +476,7 @@ static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms) return v; if (v & 0x80) { +twinax: v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); if (v < 0) return v; @@ -1435,395 +1447,439 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype) 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, + 0xd806, 0x20c5, + 0xd807, 0x3c05, + 0xd808, 0x6536, + 0xd809, 0x2fe4, + 0xd80a, 0x3dc4, + 0xd80b, 0x6624, + 0xd80c, 0x2ff4, + 0xd80d, 0x3dc4, + 0xd80e, 0x2035, + 0xd80f, 0x30a5, + 0xd810, 0x6524, + 0xd811, 0x2ca2, + 0xd812, 0x3012, 0xd813, 0x1002, - 0xd814, 0x2822, - 0xd815, 0x3012, + 0xd814, 0x27e2, + 0xd815, 0x3022, 0xd816, 0x1002, - 0xd817, 0x2492, + 0xd817, 0x28d2, 0xd818, 0x3022, 0xd819, 0x1002, - 0xd81a, 0x2772, + 0xd81a, 0x2892, 0xd81b, 0x3012, 0xd81c, 0x1002, - 0xd81d, 0x23d2, + 0xd81d, 0x24e2, 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, + 0xd820, 0x27e2, + 0xd821, 0x3012, + 0xd822, 0x1002, + 0xd823, 0x2422, + 0xd824, 0x3022, + 0xd825, 0x1002, + 0xd826, 0x22cd, + 0xd827, 0x301d, + 0xd828, 0x28f2, + 0xd829, 0x3022, + 0xd82a, 0x1002, + 0xd82b, 0x5553, + 0xd82c, 0x0307, + 0xd82d, 0x2572, + 0xd82e, 0x3022, + 0xd82f, 0x1002, + 0xd830, 0x21a2, 0xd831, 0x3012, 0xd832, 0x1002, - 0xd833, 0x400e, - 0xd834, 0x2522, - 0xd835, 0x3022, - 0xd836, 0x1002, - 0xd837, 0x2b52, - 0xd838, 0x3012, - 0xd839, 0x1002, - 0xd83a, 0x2742, + 0xd833, 0x4016, + 0xd834, 0x5e63, + 0xd835, 0x0344, + 0xd836, 0x21a2, + 0xd837, 0x3012, + 0xd838, 0x1002, + 0xd839, 0x400e, + 0xd83a, 0x2572, 0xd83b, 0x3022, 0xd83c, 0x1002, - 0xd83d, 0x25e2, - 0xd83e, 0x3022, + 0xd83d, 0x2b22, + 0xd83e, 0x3012, 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, + 0xd840, 0x2842, + 0xd841, 0x3022, + 0xd842, 0x1002, + 0xd843, 0x26e2, + 0xd844, 0x3022, + 0xd845, 0x1002, + 0xd846, 0x2fa4, + 0xd847, 0x3dc4, + 0xd848, 0x6624, + 0xd849, 0x2e8b, + 0xd84a, 0x303b, + 0xd84b, 0x56b3, + 0xd84c, 0x03c6, + 0xd84d, 0x866b, + 0xd84e, 0x400c, + 0xd84f, 0x2782, + 0xd850, 0x3012, + 0xd851, 0x1002, + 0xd852, 0x2c4b, + 0xd853, 0x309b, + 0xd854, 0x56b3, + 0xd855, 0x03c3, + 0xd856, 0x866b, + 0xd857, 0x400c, + 0xd858, 0x22a2, + 0xd859, 0x3022, + 0xd85a, 0x1002, + 0xd85b, 0x2842, + 0xd85c, 0x3022, + 0xd85d, 0x1002, + 0xd85e, 0x26e2, + 0xd85f, 0x3022, + 0xd860, 0x1002, + 0xd861, 0x2fb4, + 0xd862, 0x3dc4, + 0xd863, 0x6624, + 0xd864, 0x56b3, + 0xd865, 0x03c3, + 0xd866, 0x866b, + 0xd867, 0x401c, + 0xd868, 0x2c45, + 0xd869, 0x3095, + 0xd86a, 0x5b53, + 0xd86b, 0x23d2, 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, + 0xd86d, 0x13c2, + 0xd86e, 0x5cc3, + 0xd86f, 0x2782, + 0xd870, 0x3012, + 0xd871, 0x1312, + 0xd872, 0x2b22, + 0xd873, 0x3012, + 0xd874, 0x1002, + 0xd875, 0x2842, + 0xd876, 0x3022, + 0xd877, 0x1002, + 0xd878, 0x2622, + 0xd879, 0x3022, + 0xd87a, 0x1002, + 0xd87b, 0x21a2, + 0xd87c, 0x3012, + 0xd87d, 0x1002, + 0xd87e, 0x628f, + 0xd87f, 0x2985, + 0xd880, 0x33a5, + 0xd881, 0x26e2, + 0xd882, 0x3022, + 0xd883, 0x1002, + 0xd884, 0x5653, + 0xd885, 0x03d2, + 0xd886, 0x401e, + 0xd887, 0x6f72, + 0xd888, 0x1002, + 0xd889, 0x628f, + 0xd88a, 0x2304, + 0xd88b, 0x3c84, + 0xd88c, 0x6436, + 0xd88d, 0xdff4, + 0xd88e, 0x6436, + 0xd88f, 0x2ff5, + 0xd890, 0x3005, + 0xd891, 0x8656, + 0xd892, 0xdfba, + 0xd893, 0x56a3, + 0xd894, 0xd05a, + 0xd895, 0x29e2, + 0xd896, 0x3012, + 0xd897, 0x1392, + 0xd898, 0xd05a, + 0xd899, 0x56a3, + 0xd89a, 0xdfba, + 0xd89b, 0x0383, + 0xd89c, 0x6f72, + 0xd89d, 0x1002, + 0xd89e, 0x2a64, + 0xd89f, 0x3014, + 0xd8a0, 0x2005, + 0xd8a1, 0x3d75, + 0xd8a2, 0xc451, + 0xd8a3, 0x29a2, + 0xd8a4, 0x3022, + 0xd8a5, 0x1002, + 0xd8a6, 0x178c, + 0xd8a7, 0x1898, + 0xd8a8, 0x19a4, + 0xd8a9, 0x1ab0, + 0xd8aa, 0x1bbc, + 0xd8ab, 0x1cc8, + 0xd8ac, 0x1dd3, + 0xd8ad, 0x1ede, + 0xd8ae, 0x1fe9, + 0xd8af, 0x20f4, + 0xd8b0, 0x21ff, + 0xd8b1, 0x0000, + 0xd8b2, 0x2741, + 0xd8b3, 0x3021, + 0xd8b4, 0x1001, + 0xd8b5, 0xc620, + 0xd8b6, 0x0000, + 0xd8b7, 0xc621, + 0xd8b8, 0x0000, + 0xd8b9, 0xc622, + 0xd8ba, 0x00e2, + 0xd8bb, 0xc623, + 0xd8bc, 0x007f, + 0xd8bd, 0xc624, + 0xd8be, 0x00ce, + 0xd8bf, 0xc625, + 0xd8c0, 0x0000, + 0xd8c1, 0xc627, + 0xd8c2, 0x0000, + 0xd8c3, 0xc628, + 0xd8c4, 0x0000, + 0xd8c5, 0xc90a, + 0xd8c6, 0x3a7c, + 0xd8c7, 0xc62c, + 0xd8c8, 0x0000, 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, + 0xd8ca, 0x2741, + 0xd8cb, 0x3021, + 0xd8cc, 0x1001, + 0xd8cd, 0xc502, + 0xd8ce, 0x53ac, + 0xd8cf, 0xc503, + 0xd8d0, 0x2cd3, + 0xd8d1, 0xc600, + 0xd8d2, 0x2a6e, + 0xd8d3, 0xc601, + 0xd8d4, 0x2a2c, + 0xd8d5, 0xc605, + 0xd8d6, 0x5557, + 0xd8d7, 0xc60c, + 0xd8d8, 0x5400, + 0xd8d9, 0xc710, + 0xd8da, 0x0700, + 0xd8db, 0xc711, + 0xd8dc, 0x0f06, + 0xd8dd, 0xc718, + 0xd8de, 0x700, + 0xd8df, 0xc719, + 0xd8e0, 0x0f06, + 0xd8e1, 0xc720, + 0xd8e2, 0x4700, + 0xd8e3, 0xc721, + 0xd8e4, 0x0f06, + 0xd8e5, 0xc728, + 0xd8e6, 0x0700, + 0xd8e7, 0xc729, + 0xd8e8, 0x1207, + 0xd8e9, 0xc801, + 0xd8ea, 0x7f50, + 0xd8eb, 0xc802, + 0xd8ec, 0x7760, + 0xd8ed, 0xc803, + 0xd8ee, 0x7fce, + 0xd8ef, 0xc804, + 0xd8f0, 0x520e, + 0xd8f1, 0xc805, + 0xd8f2, 0x5c11, + 0xd8f3, 0xc806, + 0xd8f4, 0x3c51, + 0xd8f5, 0xc807, + 0xd8f6, 0x4061, + 0xd8f7, 0xc808, + 0xd8f8, 0x49c1, + 0xd8f9, 0xc809, + 0xd8fa, 0x3840, + 0xd8fb, 0xc80a, + 0xd8fc, 0x0000, + 0xd8fd, 0xc821, + 0xd8fe, 0x0002, + 0xd8ff, 0xc822, + 0xd900, 0x0046, + 0xd901, 0xc844, + 0xd902, 0x182f, + 0xd903, 0xc849, + 0xd904, 0x0400, + 0xd905, 0xc84a, + 0xd906, 0x0002, + 0xd907, 0xc013, + 0xd908, 0xf341, + 0xd909, 0xc084, + 0xd90a, 0x0030, + 0xd90b, 0xc904, + 0xd90c, 0x1401, + 0xd90d, 0xcb0c, + 0xd90e, 0x0004, + 0xd90f, 0xcb0e, + 0xd910, 0xa00a, + 0xd911, 0xcb0f, + 0xd912, 0xc0c0, + 0xd913, 0xcb10, + 0xd914, 0xc0c0, + 0xd915, 0xcb11, + 0xd916, 0x00a0, + 0xd917, 0xcb12, + 0xd918, 0x0007, + 0xd919, 0xc241, + 0xd91a, 0xa000, + 0xd91b, 0xc243, + 0xd91c, 0x7fe0, + 0xd91d, 0xc604, + 0xd91e, 0x000e, + 0xd91f, 0xc609, + 0xd920, 0x00f5, + 0xd921, 0xc611, + 0xd922, 0x000e, + 0xd923, 0xc660, + 0xd924, 0x9600, + 0xd925, 0xc687, + 0xd926, 0x0004, + 0xd927, 0xc60a, + 0xd928, 0x04f5, + 0xd929, 0x0000, + 0xd92a, 0x2741, + 0xd92b, 0x3021, + 0xd92c, 0x1001, + 0xd92d, 0xc620, + 0xd92e, 0x14e5, + 0xd92f, 0xc621, + 0xd930, 0xc53d, + 0xd931, 0xc622, + 0xd932, 0x3cbe, + 0xd933, 0xc623, + 0xd934, 0x4452, + 0xd935, 0xc624, + 0xd936, 0xc5c5, + 0xd937, 0xc625, + 0xd938, 0xe01e, + 0xd939, 0xc627, + 0xd93a, 0x0000, + 0xd93b, 0xc628, 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, + 0xd93d, 0xc62c, + 0xd93e, 0x0000, + 0xd93f, 0xc90a, + 0xd940, 0x3a7c, + 0xd941, 0x0000, + 0xd942, 0x2b84, + 0xd943, 0x3c74, + 0xd944, 0x6435, + 0xd945, 0xdff4, + 0xd946, 0x6435, + 0xd947, 0x2806, + 0xd948, 0x3006, + 0xd949, 0x8565, + 0xd94a, 0x2b24, + 0xd94b, 0x3c24, + 0xd94c, 0x6436, + 0xd94d, 0x1002, + 0xd94e, 0x2b24, + 0xd94f, 0x3c24, + 0xd950, 0x6436, + 0xd951, 0x4045, + 0xd952, 0x8656, + 0xd953, 0x5663, + 0xd954, 0x0302, + 0xd955, 0x401e, + 0xd956, 0x1002, + 0xd957, 0x2807, + 0xd958, 0x31a7, + 0xd959, 0x20c4, + 0xd95a, 0x3c24, + 0xd95b, 0x6724, + 0xd95c, 0x2ff7, + 0xd95d, 0x30f7, + 0xd95e, 0x20c4, + 0xd95f, 0x3c04, + 0xd960, 0x6724, + 0xd961, 0x1002, + 0xd962, 0x2807, + 0xd963, 0x3187, + 0xd964, 0x20c4, + 0xd965, 0x3c24, + 0xd966, 0x6724, + 0xd967, 0x2fe4, + 0xd968, 0x3dc4, + 0xd969, 0x6437, + 0xd96a, 0x20c4, + 0xd96b, 0x3c04, + 0xd96c, 0x6724, 0xd96d, 0x1002, - 0xd96e, 0x20d4, - 0xd96f, 0x3c24, - 0xd970, 0x2025, - 0xd971, 0x3005, - 0xd972, 0x6524, + 0xd96e, 0x24f4, + 0xd96f, 0x3c64, + 0xd970, 0x6436, + 0xd971, 0xdff4, + 0xd972, 0x6436, 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, + 0xd974, 0x2006, + 0xd975, 0x3d76, + 0xd976, 0xc161, + 0xd977, 0x6134, + 0xd978, 0x6135, + 0xd979, 0x5443, + 0xd97a, 0x0303, + 0xd97b, 0x6524, + 0xd97c, 0x00fb, + 0xd97d, 0x1002, + 0xd97e, 0x20d4, + 0xd97f, 0x3c24, + 0xd980, 0x2025, + 0xd981, 0x3005, + 0xd982, 0x6524, + 0xd983, 0x1002, + 0xd984, 0xd019, + 0xd985, 0x2104, + 0xd986, 0x3c24, + 0xd987, 0x2105, + 0xd988, 0x3805, + 0xd989, 0x6524, + 0xd98a, 0xdff4, + 0xd98b, 0x4005, + 0xd98c, 0x6524, + 0xd98d, 0x2e8d, + 0xd98e, 0x303d, + 0xd98f, 0x2408, + 0xd990, 0x35d8, + 0xd991, 0x5dd3, + 0xd992, 0x0307, + 0xd993, 0x8887, + 0xd994, 0x63a7, + 0xd995, 0x8887, + 0xd996, 0x63a7, + 0xd997, 0xdffd, + 0xd998, 0x00f9, + 0xd999, 0x1002, + 0xd99a, 0x866a, + 0xd99b, 0x6138, + 0xd99c, 0x5883, + 0xd99d, 0x2aa2, + 0xd99e, 0x3022, + 0xd99f, 0x1302, + 0xd9a0, 0x2ff7, + 0xd9a1, 0x3007, + 0xd9a2, 0x8785, + 0xd9a3, 0xb887, + 0xd9a4, 0x8786, + 0xd9a5, 0xb8c6, + 0xd9a6, 0x5a53, + 0xd9a7, 0x29b2, + 0xd9a8, 0x3022, + 0xd9a9, 0x13c2, + 0xd9aa, 0x2474, + 0xd9ab, 0x3c84, + 0xd9ac, 0x64d7, + 0xd9ad, 0x64d7, + 0xd9ae, 0x2ff5, + 0xd9af, 0x3c05, + 0xd9b0, 0x8757, + 0xd9b1, 0xb886, + 0xd9b2, 0x9767, + 0xd9b3, 0x67c4, + 0xd9b4, 0x6f72, + 0xd9b5, 0x1002, + 0xd9b6, 0x0000, }; int i, err; @@ -1944,10 +2000,14 @@ static struct reg_val ael2020_reset_regs[] = { { MDIO_DEV_PMA_PMD, 0xcd40, 0xffff, 0x0001 }, + { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0x0100 }, + { MDIO_DEV_PMA_PMD, 0xca22, 0xffff, 0x0100 }, + { MDIO_DEV_PMA_PMD, 0xca42, 0xffff, 0x0100 }, { MDIO_DEV_PMA_PMD, 0xff02, 0xffff, 0x0023 }, { MDIO_DEV_PMA_PMD, 0xff03, 0xffff, 0x0000 }, { MDIO_DEV_PMA_PMD, 0xff04, 0xffff, 0x0000 }, + { MDIO_DEV_PMA_PMD, 0xc20d, 0xffff, 0x0002 }, /* end */ { 0, 0, 0, 0 } }; @@ -1975,6 +2035,7 @@ static int ael2020_reset(struct cphy *phy, int wait) err = set_phy_regs(phy, ael2020_reset_regs); if (err) return err; + msleep(100); /* determine module type and perform appropriate initialization */ err = ael2020_get_module_type(phy, 0); @@ -2079,6 +2140,8 @@ int t3_ael2020_phy_prep(pinfo_t *pinfo, int phy_addr, err = set_phy_regs(phy, ael2020_reset_regs); if (err) return err; + msleep(100); + err = ael2020_get_module_type(phy, 0); if (err >= 0) phy->modtype = err; diff --git a/sys/dev/cxgb/common/cxgb_common.h b/sys/dev/cxgb/common/cxgb_common.h index 2f55e9fec66..d523a1a0228 100644 --- a/sys/dev/cxgb/common/cxgb_common.h +++ b/sys/dev/cxgb/common/cxgb_common.h @@ -314,6 +314,7 @@ struct qset_params { /* SGE queue set parameters */ unsigned int rspq_size; /* # of entries in response queue */ unsigned int fl_size; /* # of entries in regular free list */ unsigned int jumbo_size; /* # of entries in jumbo free list */ + unsigned int jumbo_buf_size; /* buffer size of jumbo entry */ unsigned int txq_size[SGE_TXQ_PER_SET]; /* Tx queue sizes */ unsigned int cong_thres; /* FL congestion threshold */ unsigned int vector; /* Interrupt (line or vector) number */ @@ -392,11 +393,9 @@ struct adapter_params { const struct adapter_info *info; -#ifdef CONFIG_CHELSIO_T3_CORE unsigned short mtus[NMTUS]; unsigned short a_wnd[NCCTRL_WIN]; unsigned short b_wnd[NCCTRL_WIN]; -#endif unsigned int nports; /* # of ethernet ports */ unsigned int chan_map; /* bitmap of in-use Tx channels */ unsigned int stats_update_period; /* MAC stats accumulation period */ @@ -650,11 +649,7 @@ static inline int is_10G(const adapter_t *adap) static inline int is_offload(const adapter_t *adap) { -#if defined(CONFIG_CHELSIO_T3_CORE) return adap->params.offload; -#else - return 0; -#endif } static inline unsigned int core_ticks_per_usec(const adapter_t *adap) @@ -772,7 +767,6 @@ void t3_mc5_intr_handler(struct mc5 *mc5); int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, unsigned int n, u32 *buf); -#ifdef CONFIG_CHELSIO_T3_CORE int t3_tp_set_coalescing_size(adapter_t *adap, unsigned int size, int psh); void t3_tp_set_max_rxsize(adapter_t *adap, unsigned int size); void t3_tp_get_mib_stats(adapter_t *adap, struct tp_mib_stats *tps); @@ -793,7 +787,6 @@ void t3_get_tx_sched(adapter_t *adap, unsigned int sched, unsigned int *kbps, void t3_read_pace_tbl(adapter_t *adap, unsigned int pace_vals[NTX_SCHED]); void t3_set_pace_tbl(adapter_t *adap, unsigned int *pace_vals, unsigned int start, unsigned int n); -#endif int t3_get_up_la(adapter_t *adapter, u32 *stopped, u32 *index, u32 *size, void *data); diff --git a/sys/dev/cxgb/common/cxgb_t3_hw.c b/sys/dev/cxgb/common/cxgb_t3_hw.c index 2c205ec2383..4c28a047c42 100644 --- a/sys/dev/cxgb/common/cxgb_t3_hw.c +++ b/sys/dev/cxgb/common/cxgb_t3_hw.c @@ -3263,7 +3263,6 @@ static void tp_set_timers(adapter_t *adap, unsigned int core_clk) #undef SECONDS } -#ifdef CONFIG_CHELSIO_T3_CORE /** * t3_tp_set_coalescing_size - set receive coalescing size * @adap: the adapter @@ -3566,7 +3565,6 @@ int t3_set_proto_sram(adapter_t *adap, const u8 *data) } return 0; } -#endif /** * t3_config_trace_filter - configure one of the tracing filters @@ -4150,14 +4148,12 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params) if (tp_init(adapter, &adapter->params.tp)) goto out_err; -#ifdef CONFIG_CHELSIO_T3_CORE t3_tp_set_coalescing_size(adapter, min(adapter->params.sge.max_pkt_size, MAX_RX_COALESCING_LEN), 1); t3_tp_set_max_rxsize(adapter, min(adapter->params.sge.max_pkt_size, 16384U)); ulp_config(adapter, &adapter->params.tp); -#endif if (is_pcie(adapter)) config_pcie(adapter); else @@ -4471,8 +4467,6 @@ int __devinit t3_prep_adapter(adapter_t *adapter, if (reset && t3_reset_adapter(adapter)) return -1; - t3_sge_prep(adapter, &adapter->params.sge); - if (adapter->params.vpd.mclk) { struct tp_params *p = &adapter->params.tp; @@ -4501,6 +4495,8 @@ int __devinit t3_prep_adapter(adapter_t *adapter, t3_mc7_size(&adapter->pmtx) && t3_mc7_size(&adapter->cm); + t3_sge_prep(adapter, &adapter->params.sge); + if (is_offload(adapter)) { adapter->params.mc5.nservers = DEFAULT_NSERVERS; /* PR 6487. TOE and filtering are mutually exclusive */ @@ -4508,10 +4504,8 @@ int __devinit t3_prep_adapter(adapter_t *adapter, adapter->params.mc5.nroutes = 0; t3_mc5_prep(adapter, &adapter->mc5, MC5_MODE_144_BIT); -#ifdef CONFIG_CHELSIO_T3_CORE init_mtus(adapter->params.mtus); init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); -#endif } early_hw_init(adapter, ai); diff --git a/sys/dev/cxgb/common/cxgb_version.h b/sys/dev/cxgb/common/cxgb_version.h deleted file mode 100644 index 3f4a652fb42..00000000000 --- a/sys/dev/cxgb/common/cxgb_version.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************** - -Copyright (c) 2007-2008, 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. - -$FreeBSD$ - -***************************************************************************/ -/* - * Note that although this driver doesn't contain all of the functionality of the Linux driver - * the common code is 99% the same. Hence we keep the same version number to indicate what linux - * driver the common code corresponds to. - */ -#ifndef __CHELSIO_VERSION_H -#define __CHELSIO_VERSION_H -#define DRV_DESC "Chelsio T3 Network Driver" -#define DRV_NAME "cxgb" -#define DRV_VERSION "1.0.133" -#endif diff --git a/sys/dev/cxgb/cxgb_adapter.h b/sys/dev/cxgb/cxgb_adapter.h index c5b366bc74f..d1f5ef64c50 100644 --- a/sys/dev/cxgb/cxgb_adapter.h +++ b/sys/dev/cxgb/cxgb_adapter.h @@ -46,6 +46,7 @@ $FreeBSD$ #include #include #include +#include #include #include @@ -58,10 +59,6 @@ $FreeBSD$ #include #include -#ifdef LRO_SUPPORTED -#include -#endif - struct adapter; struct sge_qset; extern int cxgb_debug; @@ -142,8 +139,10 @@ enum { #define FL_Q_SIZE 4096 #define JUMBO_Q_SIZE 1024 -#define RSPQ_Q_SIZE 1024 +#define RSPQ_Q_SIZE 2048 #define TX_ETH_Q_SIZE 1024 +#define TX_OFLD_Q_SIZE 1024 +#define TX_CTRL_Q_SIZE 256 enum { TXQ_ETH = 0, TXQ_OFLD = 1, @@ -156,12 +155,10 @@ enum { TXQ_ETH = 0, #define WR_LEN (WR_FLITS * 8) #define PIO_LEN (WR_LEN - sizeof(struct cpl_tx_pkt_lso)) -#ifdef LRO_SUPPORTED struct lro_state { unsigned short enabled; struct lro_ctrl ctrl; }; -#endif #define RX_BUNDLE_SIZE 8 @@ -182,6 +179,7 @@ struct sge_rspq { uint32_t offload_bundles; uint32_t pure_rsps; uint32_t unhandled_irqs; + uint32_t starved; bus_addr_t phys_addr; bus_dma_tag_t desc_tag; @@ -253,7 +251,6 @@ struct sge_txq { struct callout txq_timer; struct callout txq_watchdog; uint64_t txq_coalesced; - uint32_t txq_drops; uint32_t txq_skipped; uint32_t txq_enqueued; uint32_t txq_dump_start; @@ -284,9 +281,7 @@ enum { struct sge_qset { struct sge_rspq rspq; struct sge_fl fl[SGE_RXQ_PER_SET]; -#ifdef LRO_SUPPORTED struct lro_state lro; -#endif struct sge_txq txq[SGE_TXQ_PER_SET]; uint32_t txq_stopped; /* which Tx queues are stopped */ uint64_t port_stats[SGE_PSTAT_MAX]; diff --git a/sys/dev/cxgb/cxgb_config.h b/sys/dev/cxgb/cxgb_config.h deleted file mode 100644 index 79af94ca8e0..00000000000 --- a/sys/dev/cxgb/cxgb_config.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************** - -Copyright (c) 2007-2008, 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. - - -$FreeBSD$ - -***************************************************************************/ -#ifndef _CXGB_CONFIG_H_ -#define _CXGB_CONFIG_H_ - -#define CONFIG_CHELSIO_T3_CORE - -#if __FreeBSD_version > 800053 -#define IFNET_MULTIQUEUE -#endif -#endif diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 59e7fec8eed..cecec149690 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -218,9 +218,9 @@ TUNABLE_INT("hw.cxgb.force_fw_update", &force_fw_update); SYSCTL_UINT(_hw_cxgb, OID_AUTO, force_fw_update, CTLFLAG_RDTUN, &force_fw_update, 0, "update firmware even if up to date"); -int cxgb_use_16k_clusters = 1; +int cxgb_use_16k_clusters = -1; TUNABLE_INT("hw.cxgb.use_16k_clusters", &cxgb_use_16k_clusters); -SYSCTL_UINT(_hw_cxgb, OID_AUTO, use_16k_clusters, CTLFLAG_RDTUN, +SYSCTL_INT(_hw_cxgb, OID_AUTO, use_16k_clusters, CTLFLAG_RDTUN, &cxgb_use_16k_clusters, 0, "use 16kB clusters for the jumbo queue "); /* @@ -376,22 +376,27 @@ cxgb_controller_probe(device_t dev) static int upgrade_fw(adapter_t *sc) { -#ifdef FIRMWARE_LATEST const struct firmware *fw; -#else - struct firmware *fw; -#endif int status; + u32 vers; if ((fw = firmware_get(FW_FNAME)) == NULL) { device_printf(sc->dev, "Could not find firmware image %s\n", FW_FNAME); return (ENOENT); } else - device_printf(sc->dev, "updating firmware on card\n"); + device_printf(sc->dev, "installing firmware on card\n"); status = t3_load_fw(sc, (const uint8_t *)fw->data, fw->datasize); - device_printf(sc->dev, "firmware update returned %s %d\n", (status == 0) ? "success" : "fail", status); - + if (status != 0) { + device_printf(sc->dev, "failed to install firmware: %d\n", + status); + } else { + t3_get_fw_version(sc, &vers); + snprintf(&sc->fw_version[0], sizeof(sc->fw_version), "%d.%d.%d", + G_FW_VERSION_MAJOR(vers), G_FW_VERSION_MINOR(vers), + G_FW_VERSION_MICRO(vers)); + } + firmware_put(fw, FIRMWARE_UNLOAD); return (status); @@ -432,9 +437,7 @@ cxgb_controller_attach(device_t dev) int i, error = 0; uint32_t vers; int port_qsets = 1; -#ifdef MSI_SUPPORTED int msi_needed, reg; -#endif char buf[80]; sc = device_get_softc(dev); @@ -442,10 +445,6 @@ cxgb_controller_attach(device_t dev) sc->msi_count = 0; ai = cxgb_get_adapter_info(dev); - /* - * XXX not really related but a recent addition - */ -#ifdef MSI_SUPPORTED /* find the PCIe link width and set max read request to 4KB*/ if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) { uint16_t lnk, pectl; @@ -463,7 +462,7 @@ cxgb_controller_attach(device_t dev) "PCIe x%d Link, expect reduced performance\n", sc->link_width); } -#endif + touch_bars(dev); pci_enable_busmaster(dev); /* @@ -518,8 +517,6 @@ cxgb_controller_attach(device_t dev) * back to MSI. If that fails, then try falling back to the legacy * interrupt pin model. */ -#ifdef MSI_SUPPORTED - sc->msix_regs_rid = 0x20; if ((msi_allowed >= 2) && (sc->msix_regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -565,20 +562,14 @@ cxgb_controller_attach(device_t dev) device_printf(dev, "using MSI interrupts\n"); } } -#endif if (sc->msi_count == 0) { device_printf(dev, "using line interrupts\n"); sc->cxgb_intr = t3b_intr; } /* Create a private taskqueue thread for handling driver events */ -#ifdef TASKQUEUE_CURRENT sc->tq = taskqueue_create("cxgb_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->tq); -#else - sc->tq = taskqueue_create_fast("cxgb_taskq", M_NOWAIT, - taskqueue_thread_enqueue, &sc->tq); -#endif if (sc->tq == NULL) { device_printf(dev, "failed to allocate controller task queue\n"); goto out; @@ -764,7 +755,6 @@ cxgb_free(struct adapter *sc) * Release all interrupt resources. */ cxgb_teardown_interrupts(sc); -#ifdef MSI_SUPPORTED if (sc->flags & (USING_MSI | USING_MSIX)) { device_printf(sc->dev, "releasing msi message(s)\n"); pci_release_msi(sc->dev); @@ -776,7 +766,6 @@ cxgb_free(struct adapter *sc) bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->msix_regs_rid, sc->msix_regs_res); } -#endif /* * Free the adapter's taskqueue. @@ -910,11 +899,8 @@ cxgb_setup_interrupts(adapter_t *sc) sc->irq_rid = 0; } else { err = bus_setup_intr(sc->dev, sc->irq_res, - INTR_MPSAFE | INTR_TYPE_NET, -#ifdef INTR_FILTERS - NULL, -#endif - sc->cxgb_intr, sc, &sc->intr_tag); + INTR_MPSAFE | INTR_TYPE_NET, NULL, + sc->cxgb_intr, sc, &sc->intr_tag); if (err) { device_printf(sc->dev, @@ -943,10 +929,7 @@ cxgb_setup_interrupts(adapter_t *sc) } err = bus_setup_intr(sc->dev, res, INTR_MPSAFE | INTR_TYPE_NET, -#ifdef INTR_FILTERS - NULL, -#endif - t3_intr_msix, &sc->sge.qs[i], &tag); + NULL, t3_intr_msix, &sc->sge.qs[i], &tag); if (err) { device_printf(sc->dev, "Cannot set up interrupt " "for message %d (%d)\n", rid, err); @@ -996,26 +979,10 @@ cxgb_makedev(struct port_info *pi) return (0); } -#ifndef LRO_SUPPORTED -#ifdef IFCAP_LRO -#undef IFCAP_LRO -#endif -#define IFCAP_LRO 0x0 -#endif - -#ifdef TSO_SUPPORTED -#define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO) -/* Don't enable TSO6 yet */ -#define CXGB_CAP_ENABLE (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO4 | IFCAP_JUMBO_MTU | IFCAP_LRO) -#else -#define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_JUMBO_MTU) -/* Don't enable TSO6 yet */ -#define CXGB_CAP_ENABLE (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_JUMBO_MTU) -#define IFCAP_TSO4 0x0 -#define IFCAP_TSO6 0x0 -#define CSUM_TSO 0x0 -#endif - +#define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \ + IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \ + IFCAP_VLAN_HWTSO) +#define CXGB_CAP_ENABLE (CXGB_CAP & ~IFCAP_TSO6) static int cxgb_port_attach(device_t dev) @@ -1024,8 +991,7 @@ cxgb_port_attach(device_t dev) struct ifnet *ifp; int err; struct adapter *sc; - - + p = device_get_softc(dev); sc = p->adapter; snprintf(p->lockbuf, PORT_NAME_LEN, "cxgb port lock %d:%d", @@ -1039,9 +1005,6 @@ cxgb_port_attach(device_t dev) return (ENOMEM); } - /* - * Note that there is currently no watchdog timer. - */ if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_init = cxgb_init; ifp->if_softc = p; @@ -1057,16 +1020,16 @@ cxgb_port_attach(device_t dev) IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); IFQ_SET_READY(&ifp->if_snd); - ifp->if_hwassist = ifp->if_capabilities = ifp->if_capenable = 0; - ifp->if_capabilities |= CXGB_CAP; - ifp->if_capenable |= CXGB_CAP_ENABLE; - ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO); + ifp->if_capabilities = CXGB_CAP; + ifp->if_capenable = CXGB_CAP_ENABLE; + ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO; + /* - * disable TSO on 4-port - it isn't supported by the firmware yet + * Disable TSO on 4-port - it isn't supported by the firmware. */ - if (p->adapter->params.nports > 2) { - ifp->if_capabilities &= ~(IFCAP_TSO4 | IFCAP_TSO6); - ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TSO6); + if (sc->params.nports > 2) { + ifp->if_capabilities &= ~(IFCAP_TSO | IFCAP_VLAN_HWTSO); + ifp->if_capenable &= ~(IFCAP_TSO | IFCAP_VLAN_HWTSO); ifp->if_hwassist &= ~CSUM_TSO; } @@ -1074,11 +1037,10 @@ cxgb_port_attach(device_t dev) ifp->if_transmit = cxgb_transmit; ifp->if_qflush = cxgb_qflush; - /* - * Only default to jumbo frames on 10GigE - */ - if (p->adapter->params.nports <= 2) +#ifdef DEFAULT_JUMBO + if (sc->params.nports <= 2) ifp->if_mtu = ETHERMTU_JUMBO; +#endif if ((err = cxgb_makedev(p)) != 0) { printf("makedev failed %d\n", err); return (err); @@ -1279,7 +1241,7 @@ t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed, void t3_os_phymod_changed(struct adapter *adap, int port_id) { static const char *mod_str[] = { - NULL, "SR", "LR", "LRM", "TWINAX", "TWINAX", "unknown" + NULL, "SR", "LR", "LRM", "TWINAX", "TWINAX-L", "unknown" }; struct port_info *pi = &adap->port[port_id]; int mod = pi->phy.modtype; @@ -1587,11 +1549,7 @@ bind_qsets(adapter_t *sc) static void update_tpeeprom(struct adapter *adap) { -#ifdef FIRMWARE_LATEST const struct firmware *tpeeprom; -#else - struct firmware *tpeeprom; -#endif uint32_t version; unsigned int major, minor; @@ -1649,11 +1607,7 @@ release_tpeeprom: static int update_tpsram(struct adapter *adap) { -#ifdef FIRMWARE_LATEST const struct firmware *tpsram; -#else - struct firmware *tpsram; -#endif int ret; char rev, name[32]; @@ -2003,7 +1957,6 @@ cxgb_uninit_synchronized(struct port_info *pi) return (0); } -#ifdef LRO_SUPPORTED /* * Mark lro enabled or disabled in all qsets for this port */ @@ -2021,7 +1974,6 @@ cxgb_set_lro(struct port_info *p, int enabled) } return (0); } -#endif static int cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) @@ -2106,37 +2058,41 @@ fail: mask = ifr->ifr_reqcap ^ ifp->if_capenable; if (mask & IFCAP_TXCSUM) { - if (IFCAP_TXCSUM & ifp->if_capenable) { - ifp->if_capenable &= ~(IFCAP_TXCSUM|IFCAP_TSO4); - ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP - | CSUM_IP | CSUM_TSO); - } else { - ifp->if_capenable |= IFCAP_TXCSUM; - ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP - | CSUM_IP); + ifp->if_capenable ^= IFCAP_TXCSUM; + ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP); + + if (IFCAP_TSO & ifp->if_capenable && + !(IFCAP_TXCSUM & ifp->if_capenable)) { + ifp->if_capenable &= ~IFCAP_TSO; + ifp->if_hwassist &= ~CSUM_TSO; + if_printf(ifp, + "tso disabled due to -txcsum.\n"); } } - if (mask & IFCAP_RXCSUM) { + if (mask & IFCAP_RXCSUM) ifp->if_capenable ^= IFCAP_RXCSUM; - } if (mask & IFCAP_TSO4) { - if (IFCAP_TSO4 & ifp->if_capenable) { - ifp->if_capenable &= ~IFCAP_TSO4; - ifp->if_hwassist &= ~CSUM_TSO; - } else if (IFCAP_TXCSUM & ifp->if_capenable) { - ifp->if_capenable |= IFCAP_TSO4; - ifp->if_hwassist |= CSUM_TSO; + ifp->if_capenable ^= IFCAP_TSO4; + + if (IFCAP_TSO & ifp->if_capenable) { + if (IFCAP_TXCSUM & ifp->if_capenable) + ifp->if_hwassist |= CSUM_TSO; + else { + ifp->if_capenable &= ~IFCAP_TSO; + ifp->if_hwassist &= ~CSUM_TSO; + if_printf(ifp, + "enable txcsum first.\n"); + error = EAGAIN; + } } else - error = EINVAL; + ifp->if_hwassist &= ~CSUM_TSO; } -#ifdef LRO_SUPPORTED if (mask & IFCAP_LRO) { ifp->if_capenable ^= IFCAP_LRO; /* Safe to do this even if cxgb_up not called yet */ cxgb_set_lro(p, ifp->if_capenable & IFCAP_LRO); } -#endif if (mask & IFCAP_VLAN_HWTAGGING) { ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { @@ -2153,6 +2109,8 @@ fail: PORT_UNLOCK(p); } } + if (mask & IFCAP_VLAN_HWTSO) + ifp->if_capenable ^= IFCAP_VLAN_HWTSO; if (mask & IFCAP_VLAN_HWCSUM) ifp->if_capenable ^= IFCAP_VLAN_HWCSUM; @@ -2444,31 +2402,40 @@ cxgb_tick_handler(void *arg, int count) if (p->rev == T3_REV_B2 && p->nports < 4 && sc->open_device_map) check_t3b2_mac(sc); - cause = t3_read_reg(sc, A_SG_INT_CAUSE); - reset = 0; - if (cause & F_FLEMPTY) { + cause = t3_read_reg(sc, A_SG_INT_CAUSE) & (F_RSPQSTARVE | F_FLEMPTY); + if (cause) { struct sge_qset *qs = &sc->sge.qs[0]; + uint32_t mask, v; - i = 0; - reset |= F_FLEMPTY; + v = t3_read_reg(sc, A_SG_RSPQ_FL_STATUS) & ~0xff00; - cause = (t3_read_reg(sc, A_SG_RSPQ_FL_STATUS) >> - S_FL0EMPTY) & 0xffff; - while (cause) { - qs->fl[i].empty += (cause & 1); - if (i) - qs++; - i ^= 1; - cause >>= 1; + mask = 1; + for (i = 0; i < SGE_QSETS; i++) { + if (v & mask) + qs[i].rspq.starved++; + mask <<= 1; } + + mask <<= SGE_QSETS; /* skip RSPQXDISABLED */ + + for (i = 0; i < SGE_QSETS * 2; i++) { + if (v & mask) { + qs[i / 2].fl[i % 2].empty++; + } + mask <<= 1; + } + + /* clear */ + t3_write_reg(sc, A_SG_RSPQ_FL_STATUS, v); + t3_write_reg(sc, A_SG_INT_CAUSE, cause); } - t3_write_reg(sc, A_SG_INT_CAUSE, reset); for (i = 0; i < sc->params.nports; i++) { struct port_info *pi = &sc->port[i]; struct ifnet *ifp = pi->ifp; struct cmac *mac = &pi->mac; struct mac_stats *mstats = &mac->stats; + int drops, j; if (!isset(&sc->open_device_map, pi->port_id)) continue; @@ -2477,34 +2444,20 @@ cxgb_tick_handler(void *arg, int count) t3_mac_update_stats(mac); PORT_UNLOCK(pi); - ifp->if_opackets = - mstats->tx_frames_64 + - mstats->tx_frames_65_127 + - mstats->tx_frames_128_255 + - mstats->tx_frames_256_511 + - mstats->tx_frames_512_1023 + - mstats->tx_frames_1024_1518 + - mstats->tx_frames_1519_max; - - ifp->if_ipackets = - mstats->rx_frames_64 + - mstats->rx_frames_65_127 + - mstats->rx_frames_128_255 + - mstats->rx_frames_256_511 + - mstats->rx_frames_512_1023 + - mstats->rx_frames_1024_1518 + - mstats->rx_frames_1519_max; - + ifp->if_opackets = mstats->tx_frames; + ifp->if_ipackets = mstats->rx_frames; ifp->if_obytes = mstats->tx_octets; ifp->if_ibytes = mstats->rx_octets; ifp->if_omcasts = mstats->tx_mcast_frames; ifp->if_imcasts = mstats->rx_mcast_frames; - - ifp->if_collisions = - mstats->tx_total_collisions; - + ifp->if_collisions = mstats->tx_total_collisions; ifp->if_iqdrops = mstats->rx_cong_drops; - + + drops = 0; + for (j = pi->first_qset; j < pi->first_qset + pi->nqsets; j++) + drops += sc->sge.qs[j].txq[TXQ_ETH].txq_mr->br_drops; + ifp->if_snd.ifq_drops = drops; + ifp->if_oerrors = mstats->tx_excess_collisions + mstats->tx_underrun + @@ -2761,7 +2714,9 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data, t->cong_thres = q->cong_thres; t->qnum = i; - if (sc->flags & USING_MSIX) + if ((sc->flags & FULL_INIT_DONE) == 0) + t->vector = 0; + else if (sc->flags & USING_MSIX) t->vector = rman_get_start(sc->msix_irq_res[i]); else t->vector = rman_get_start(sc->irq_res); diff --git a/sys/dev/cxgb/cxgb_offload.h b/sys/dev/cxgb/cxgb_offload.h index dccefdcbb70..a8b858e7103 100644 --- a/sys/dev/cxgb/cxgb_offload.h +++ b/sys/dev/cxgb/cxgb_offload.h @@ -33,8 +33,6 @@ $FreeBSD$ #ifndef _CXGB_OFFLOAD_H #define _CXGB_OFFLOAD_H -#include -#include #include #include diff --git a/sys/dev/cxgb/cxgb_osdep.h b/sys/dev/cxgb/cxgb_osdep.h index 956789085d8..5dc256dd23a 100644 --- a/sys/dev/cxgb/cxgb_osdep.h +++ b/sys/dev/cxgb/cxgb_osdep.h @@ -41,9 +41,6 @@ $FreeBSD$ #include -#define CONFIG_CHELSIO_T3_CORE -#include - #ifndef _CXGB_OSDEP_H_ #define _CXGB_OSDEP_H_ @@ -91,33 +88,6 @@ struct t3_mbuf_hdr { #define MT_DONTFREE 128 -#if __FreeBSD_version > 700030 -#define INTR_FILTERS -#define FIRMWARE_LATEST -#endif - -#if ((__FreeBSD_version > 602103) && (__FreeBSD_version < 700000)) -#define FIRMWARE_LATEST -#endif - -#if __FreeBSD_version > 700000 -#define MSI_SUPPORTED -#define TSO_SUPPORTED -#define VLAN_SUPPORTED -#define TASKQUEUE_CURRENT -#else -#define if_name(ifp) (ifp)->if_xname -#define M_SANITY(m, n) -#endif - -#if __FreeBSD_version >= 701000 -#include "opt_inet.h" -#ifdef INET -#define LRO_SUPPORTED -#define TOE_SUPPORTED -#endif -#endif - #if __FreeBSD_version < 800054 #if defined (__GNUC__) #if #cpu(i386) || defined __i386 || defined i386 || defined __i386__ || #cpu(x86_64) || defined __x86_64__ diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index 27a7c899209..9bc36c94fa7 100644 --- a/sys/dev/cxgb/cxgb_sge.c +++ b/sys/dev/cxgb/cxgb_sge.c @@ -30,6 +30,8 @@ POSSIBILITY OF SUCH DAMAGE. #include __FBSDID("$FreeBSD$"); +#include "opt_inet.h" + #include #include #include @@ -50,8 +52,12 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include +#include +#include #include #include @@ -113,13 +119,9 @@ SYSCTL_UINT(_hw_cxgb, OID_AUTO, tx_reclaim_threshold, CTLFLAG_RW, * we have an m_ext */ static int recycle_enable = 0; -int cxgb_ext_freed = 0; -int cxgb_ext_inited = 0; -int fl_q_size = 0; -int jumbo_q_size = 0; extern int cxgb_use_16k_clusters; -extern int nmbjumbo4; +extern int nmbjumbop; extern int nmbjumbo9; extern int nmbjumbo16; @@ -526,21 +528,30 @@ t3_sge_err_intr_handler(adapter_t *adapter) void t3_sge_prep(adapter_t *adap, struct sge_params *p) { - int i, nqsets; + int i, nqsets, fl_q_size, jumbo_q_size, use_16k, jumbo_buf_size; - nqsets = min(SGE_QSETS, mp_ncpus*4); + nqsets = min(SGE_QSETS / adap->params.nports, mp_ncpus); + nqsets *= adap->params.nports; fl_q_size = min(nmbclusters/(3*nqsets), FL_Q_SIZE); while (!powerof2(fl_q_size)) fl_q_size--; + + use_16k = cxgb_use_16k_clusters != -1 ? cxgb_use_16k_clusters : + is_offload(adap); + #if __FreeBSD_version >= 700111 - if (cxgb_use_16k_clusters) + if (use_16k) { jumbo_q_size = min(nmbjumbo16/(3*nqsets), JUMBO_Q_SIZE); - else + jumbo_buf_size = MJUM16BYTES; + } else { jumbo_q_size = min(nmbjumbo9/(3*nqsets), JUMBO_Q_SIZE); + jumbo_buf_size = MJUM9BYTES; + } #else - jumbo_q_size = min(nmbjumbo4/(3*nqsets), JUMBO_Q_SIZE); + jumbo_q_size = min(nmbjumbop/(3*nqsets), JUMBO_Q_SIZE); + jumbo_buf_size = MJUMPAGESIZE; #endif while (!powerof2(jumbo_q_size)) jumbo_q_size--; @@ -549,8 +560,7 @@ t3_sge_prep(adapter_t *adap, struct sge_params *p) device_printf(adap->dev, "Insufficient clusters and/or jumbo buffers.\n"); - /* XXX Does ETHER_ALIGN need to be accounted for here? */ - p->max_pkt_size = adap->sge.qs[0].fl[1].buf_size - sizeof(struct cpl_rx_data); + p->max_pkt_size = jumbo_buf_size - sizeof(struct cpl_rx_data); for (i = 0; i < SGE_QSETS; ++i) { struct qset_params *q = p->qset + i; @@ -568,9 +578,10 @@ t3_sge_prep(adapter_t *adap, struct sge_params *p) q->rspq_size = RSPQ_Q_SIZE; q->fl_size = fl_q_size; q->jumbo_size = jumbo_q_size; + q->jumbo_buf_size = jumbo_buf_size; q->txq_size[TXQ_ETH] = TX_ETH_Q_SIZE; - q->txq_size[TXQ_OFLD] = 1024; - q->txq_size[TXQ_CTRL] = 256; + q->txq_size[TXQ_OFLD] = is_offload(adap) ? TX_OFLD_Q_SIZE : 16; + q->txq_size[TXQ_CTRL] = TX_CTRL_Q_SIZE; q->cong_thres = 0; } } @@ -1145,10 +1156,9 @@ calc_tx_descs(const struct mbuf *m, int nsegs) return 1; flits = sgl_len(nsegs) + 2; -#ifdef TSO_SUPPORTED if (m->m_pkthdr.csum_flags & CSUM_TSO) flits++; -#endif + return flits_to_desc(flits); } @@ -1363,20 +1373,15 @@ write_wr_hdr_sgl(unsigned int ndesc, struct tx_desc *txd, struct txq_state *txqs } } -/* sizeof(*eh) + sizeof(*vhdr) + sizeof(*ip) + sizeof(*tcp) */ -#define TCPPKTHDRSIZE (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + 20 + 20) +/* sizeof(*eh) + sizeof(*ip) + sizeof(*tcp) */ +#define TCPPKTHDRSIZE (ETHER_HDR_LEN + 20 + 20) -#ifdef VLAN_SUPPORTED #define GET_VTAG(cntrl, m) \ do { \ if ((m)->m_flags & M_VLANTAG) \ cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN((m)->m_pkthdr.ether_vtag); \ } while (0) -#else -#define GET_VTAG(cntrl, m) -#endif - static int t3_encap(struct sge_qset *qs, struct mbuf **m) { @@ -1405,19 +1410,15 @@ t3_encap(struct sge_qset *qs, struct mbuf **m) prefetch(txd); m0 = *m; - - DPRINTF("t3_encap port_id=%d qsidx=%d ", pi->port_id, pi->first_qset); - DPRINTF("mlen=%d txpkt_intf=%d tx_chan=%d\n", m[0]->m_pkthdr.len, pi->txpkt_intf, pi->tx_chan); - + mtx_assert(&qs->lock, MA_OWNED); cntrl = V_TXPKT_INTF(pi->txpkt_intf); KASSERT(m0->m_flags & M_PKTHDR, ("not packet header\n")); -#ifdef VLAN_SUPPORTED if (m0->m_nextpkt == NULL && m0->m_next != NULL && m0->m_pkthdr.csum_flags & (CSUM_TSO)) tso_info = V_LSO_MSS(m0->m_pkthdr.tso_segsz); -#endif + if (m0->m_nextpkt != NULL) { busdma_map_sg_vec(txq->entry_tag, txsd->map, m0, segs, &nsegs); ndesc = 1; @@ -1477,15 +1478,16 @@ t3_encap(struct sge_qset *qs, struct mbuf **m) V_WR_GEN(txqs.gen)) | htonl(V_WR_TID(txq->token)); set_wr_hdr(wrp, wr_hi, wr_lo); wmb(); + ETHER_BPF_MTAP(pi->ifp, m0); wr_gen2(txd, txqs.gen); check_ring_tx_db(sc, txq); return (0); } else if (tso_info) { - int min_size = TCPPKTHDRSIZE, eth_type, tagged; + int eth_type; struct cpl_tx_pkt_lso *hdr = (struct cpl_tx_pkt_lso *)txd; + struct ether_header *eh; struct ip *ip; struct tcphdr *tcp; - char *pkthdr; txd->flit[2] = 0; GET_VTAG(cntrl, m0); @@ -1493,13 +1495,7 @@ t3_encap(struct sge_qset *qs, struct mbuf **m) hdr->cntrl = htonl(cntrl); hdr->len = htonl(mlen | 0x80000000); - DPRINTF("tso buf len=%d\n", mlen); - - tagged = m0->m_flags & M_VLANTAG; - if (!tagged) - min_size -= ETHER_VLAN_ENCAP_LEN; - - if (__predict_false(mlen < min_size)) { + if (__predict_false(mlen < TCPPKTHDRSIZE)) { printf("mbuf=%p,len=%d,tso_segsz=%d,csum_flags=%#x,flags=%#x", m0, mlen, m0->m_pkthdr.tso_segsz, m0->m_pkthdr.csum_flags, m0->m_flags); @@ -1507,25 +1503,23 @@ t3_encap(struct sge_qset *qs, struct mbuf **m) } /* Make sure that ether, ip, tcp headers are all in m0 */ - if (__predict_false(m0->m_len < min_size)) { - m0 = m_pullup(m0, min_size); + if (__predict_false(m0->m_len < TCPPKTHDRSIZE)) { + m0 = m_pullup(m0, TCPPKTHDRSIZE); if (__predict_false(m0 == NULL)) { /* XXX panic probably an overreaction */ panic("couldn't fit header into mbuf"); } } - pkthdr = m0->m_data; - if (tagged) { + eh = mtod(m0, struct ether_header *); + if (eh->ether_type == htons(ETHERTYPE_VLAN)) { eth_type = CPL_ETH_II_VLAN; - ip = (struct ip *)(pkthdr + ETHER_HDR_LEN + - ETHER_VLAN_ENCAP_LEN); + ip = (struct ip *)((struct ether_vlan_header *)eh + 1); } else { eth_type = CPL_ETH_II; - ip = (struct ip *)(pkthdr + ETHER_HDR_LEN); + ip = (struct ip *)(eh + 1); } - tcp = (struct tcphdr *)((uint8_t *)ip + - sizeof(*ip)); + tcp = (struct tcphdr *)(ip + 1); tso_info |= V_LSO_ETH_TYPE(eth_type) | V_LSO_IPHDR_WORDS(ip->ip_hl) | @@ -1533,12 +1527,10 @@ t3_encap(struct sge_qset *qs, struct mbuf **m) hdr->lso_info = htonl(tso_info); if (__predict_false(mlen <= PIO_LEN)) { - /* pkt not undersized but fits in PIO_LEN + /* + * pkt not undersized but fits in PIO_LEN * Indicates a TSO bug at the higher levels. - * */ - DPRINTF("**5592 Fix** mbuf=%p,len=%d,tso_segsz=%d,csum_flags=%#x,flags=%#x", - m0, mlen, m0->m_pkthdr.tso_segsz, m0->m_pkthdr.csum_flags, m0->m_flags); txsd->m = NULL; m_copydata(m0, 0, mlen, (caddr_t)&txd->flit[3]); flits = (mlen + 7) / 8 + 3; @@ -1549,8 +1541,10 @@ t3_encap(struct sge_qset *qs, struct mbuf **m) V_WR_GEN(txqs.gen) | V_WR_TID(txq->token)); set_wr_hdr(&hdr->wr, wr_hi, wr_lo); wmb(); + ETHER_BPF_MTAP(pi->ifp, m0); wr_gen2(txd, txqs.gen); check_ring_tx_db(sc, txq); + m_freem(m0); return (0); } flits = 3; @@ -1578,8 +1572,10 @@ t3_encap(struct sge_qset *qs, struct mbuf **m) V_WR_GEN(txqs.gen) | V_WR_TID(txq->token)); set_wr_hdr(&cpl->wr, wr_hi, wr_lo); wmb(); + ETHER_BPF_MTAP(pi->ifp, m0); wr_gen2(txd, txqs.gen); check_ring_tx_db(sc, txq); + m_freem(m0); return (0); } flits = 2; @@ -1590,12 +1586,14 @@ t3_encap(struct sge_qset *qs, struct mbuf **m) sgl_flits = sgl_len(nsegs); + ETHER_BPF_MTAP(pi->ifp, m0); + KASSERT(ndesc <= 4, ("ndesc too large %d", ndesc)); wr_hi = htonl(V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) | txqs.compl); wr_lo = htonl(V_WR_TID(txq->token)); write_wr_hdr_sgl(ndesc, txd, &txqs, txq, sgl, flits, sgl_flits, wr_hi, wr_lo); - check_ring_tx_db(pi->adapter, txq); + check_ring_tx_db(sc, txq); return (0); } @@ -1645,12 +1643,9 @@ cxgb_start_locked(struct sge_qset *qs) { struct mbuf *m_head = NULL; struct sge_txq *txq = &qs->txq[TXQ_ETH]; - int avail, txmax; int in_use_init = txq->in_use; struct port_info *pi = qs->port; struct ifnet *ifp = pi->ifp; - avail = txq->size - txq->in_use - 4; - txmax = min(TX_START_MAX_DESC, avail); if (qs->qs_flags & (QS_FLUSHING|QS_TIMEOUT)) reclaim_completed_tx(qs, 0, TXQ_ETH); @@ -1660,12 +1655,14 @@ cxgb_start_locked(struct sge_qset *qs) return; } TXQ_LOCK_ASSERT(qs); - while ((txq->in_use - in_use_init < txmax) && - !TXQ_RING_EMPTY(qs) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && + while ((txq->in_use - in_use_init < TX_START_MAX_DESC) && + !TXQ_RING_EMPTY(qs) && (ifp->if_drv_flags & IFF_DRV_RUNNING) && pi->link_config.link_ok) { reclaim_completed_tx(qs, cxgb_tx_reclaim_threshold, TXQ_ETH); + if (txq->size - txq->in_use <= TX_MAX_DESC) + break; + if ((m_head = cxgb_dequeue(qs)) == NULL) break; /* @@ -1674,16 +1671,6 @@ cxgb_start_locked(struct sge_qset *qs) */ if (t3_encap(qs, &m_head) || m_head == NULL) break; - - /* Send a copy of the frame to the BPF listener */ - ETHER_BPF_MTAP(ifp, m_head); - - /* - * We sent via PIO, no longer need a copy - */ - if (m_head->m_nextpkt == NULL && - m_head->m_pkthdr.len <= PIO_LEN) - m_freem(m_head); m_head = NULL; } @@ -1714,7 +1701,7 @@ cxgb_transmit_locked(struct ifnet *ifp, struct sge_qset *qs, struct mbuf *m) * - there is space in hardware transmit queue */ if (check_pkt_coalesce(qs) == 0 && - !TXQ_RING_NEEDS_ENQUEUE(qs) && avail > 4) { + !TXQ_RING_NEEDS_ENQUEUE(qs) && avail > TX_MAX_DESC) { if (t3_encap(qs, &m)) { if (m != NULL && (error = drbr_enqueue(ifp, br, m)) != 0) @@ -1726,17 +1713,6 @@ cxgb_transmit_locked(struct ifnet *ifp, struct sge_qset *qs, struct mbuf *m) */ txq->txq_direct_packets++; txq->txq_direct_bytes += m->m_pkthdr.len; - /* - ** Send a copy of the frame to the BPF - ** listener and set the watchdog on. - */ - ETHER_BPF_MTAP(ifp, m); - /* - * We sent via PIO, no longer need a copy - */ - if (m->m_pkthdr.len <= PIO_LEN) - m_freem(m); - } } else if ((error = drbr_enqueue(ifp, br, m)) != 0) return (error); @@ -2033,15 +2009,13 @@ t3_free_qset(adapter_t *sc, struct sge_qset *q) int i; reclaim_completed_tx(q, 0, TXQ_ETH); - for (i = 0; i < SGE_TXQ_PER_SET; i++) { - if (q->txq[i].txq_mr != NULL) - buf_ring_free(q->txq[i].txq_mr, M_DEVBUF); - if (q->txq[i].txq_ifq != NULL) { - ifq_delete(q->txq[i].txq_ifq); - free(q->txq[i].txq_ifq, M_DEVBUF); - } + if (q->txq[TXQ_ETH].txq_mr != NULL) + buf_ring_free(q->txq[TXQ_ETH].txq_mr, M_DEVBUF); + if (q->txq[TXQ_ETH].txq_ifq != NULL) { + ifq_delete(q->txq[TXQ_ETH].txq_ifq); + free(q->txq[TXQ_ETH].txq_ifq, M_DEVBUF); } - + for (i = 0; i < SGE_RXQ_PER_SET; ++i) { if (q->fl[i].desc) { mtx_lock_spin(&sc->sge.reg_lock); @@ -2090,7 +2064,7 @@ t3_free_qset(adapter_t *sc, struct sge_qset *q) MTX_DESTROY(&q->rspq.lock); } -#ifdef LRO_SUPPORTED +#ifdef INET tcp_lro_free(&q->lro.ctrl); #endif @@ -2578,25 +2552,22 @@ t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx, MTX_INIT(&q->lock, q->namebuf, NULL, MTX_DEF); q->port = pi; - for (i = 0; i < SGE_TXQ_PER_SET; i++) { - - if ((q->txq[i].txq_mr = buf_ring_alloc(cxgb_txq_buf_ring_size, - M_DEVBUF, M_WAITOK, &q->lock)) == NULL) { - device_printf(sc->dev, "failed to allocate mbuf ring\n"); - goto err; - } - if ((q->txq[i].txq_ifq = - malloc(sizeof(struct ifaltq), M_DEVBUF, M_NOWAIT|M_ZERO)) - == NULL) { - device_printf(sc->dev, "failed to allocate ifq\n"); - goto err; - } - ifq_init(q->txq[i].txq_ifq, pi->ifp); - callout_init(&q->txq[i].txq_timer, 1); - callout_init(&q->txq[i].txq_watchdog, 1); - q->txq[i].txq_timer.c_cpu = id % mp_ncpus; - q->txq[i].txq_watchdog.c_cpu = id % mp_ncpus; + if ((q->txq[TXQ_ETH].txq_mr = buf_ring_alloc(cxgb_txq_buf_ring_size, + M_DEVBUF, M_WAITOK, &q->lock)) == NULL) { + device_printf(sc->dev, "failed to allocate mbuf ring\n"); + goto err; } + if ((q->txq[TXQ_ETH].txq_ifq = malloc(sizeof(struct ifaltq), M_DEVBUF, + M_NOWAIT | M_ZERO)) == NULL) { + device_printf(sc->dev, "failed to allocate ifq\n"); + goto err; + } + ifq_init(q->txq[TXQ_ETH].txq_ifq, pi->ifp); + callout_init(&q->txq[TXQ_ETH].txq_timer, 1); + callout_init(&q->txq[TXQ_ETH].txq_watchdog, 1); + q->txq[TXQ_ETH].txq_timer.c_cpu = id % mp_ncpus; + q->txq[TXQ_ETH].txq_watchdog.c_cpu = id % mp_ncpus; + init_qset_cntxt(q, id); q->idx = id; if ((ret = alloc_ring(sc, p->fl_size, sizeof(struct rx_desc), @@ -2661,32 +2632,33 @@ t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx, q->fl[0].buf_size = MCLBYTES; q->fl[0].zone = zone_pack; q->fl[0].type = EXT_PACKET; -#if __FreeBSD_version > 800000 - if (cxgb_use_16k_clusters) { - q->fl[1].buf_size = MJUM16BYTES; + + if (p->jumbo_buf_size == MJUM16BYTES) { q->fl[1].zone = zone_jumbo16; q->fl[1].type = EXT_JUMBO16; - } else { - q->fl[1].buf_size = MJUM9BYTES; + } else if (p->jumbo_buf_size == MJUM9BYTES) { q->fl[1].zone = zone_jumbo9; q->fl[1].type = EXT_JUMBO9; + } else if (p->jumbo_buf_size == MJUMPAGESIZE) { + q->fl[1].zone = zone_jumbop; + q->fl[1].type = EXT_JUMBOP; + } else { + KASSERT(0, ("can't deal with jumbo_buf_size %d.", p->jumbo_buf_size)); + ret = EDOOFUS; + goto err; } -#else - q->fl[1].buf_size = MJUMPAGESIZE; - q->fl[1].zone = zone_jumbop; - q->fl[1].type = EXT_JUMBOP; -#endif + q->fl[1].buf_size = p->jumbo_buf_size; -#ifdef LRO_SUPPORTED /* Allocate and setup the lro_ctrl structure */ q->lro.enabled = !!(pi->ifp->if_capenable & IFCAP_LRO); +#ifdef INET ret = tcp_lro_init(&q->lro.ctrl); if (ret) { printf("error %d from tcp_lro_init\n", ret); goto err; } - q->lro.ctrl.ifp = pi->ifp; #endif + q->lro.ctrl.ifp = pi->ifp; mtx_lock_spin(&sc->sge.reg_lock); ret = -t3_sge_init_rspcntxt(sc, q->rspq.cntxt_id, irq_vec_idx, @@ -2787,16 +2759,12 @@ t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad) m->m_pkthdr.csum_flags = (CSUM_IP_CHECKED|CSUM_IP_VALID|CSUM_DATA_VALID|CSUM_PSEUDO_HDR); m->m_pkthdr.csum_data = 0xffff; } - /* - * XXX need to add VLAN support for 6.x - */ -#ifdef VLAN_SUPPORTED - if (__predict_false(cpl->vlan_valid)) { + + if (cpl->vlan_valid) { m->m_pkthdr.ether_vtag = ntohs(cpl->vlan); m->m_flags |= M_VLANTAG; } -#endif - + m->m_pkthdr.rcvif = ifp; m->m_pkthdr.header = mtod(m, uint8_t *) + sizeof(*cpl) + ethpad; /* @@ -2976,11 +2944,9 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget) struct rsp_desc *r = &rspq->desc[rspq->cidx]; int budget_left = budget; unsigned int sleeping = 0; -#ifdef LRO_SUPPORTED int lro_enabled = qs->lro.enabled; int skip_lro; struct lro_ctrl *lro_ctrl = &qs->lro.ctrl; -#endif struct mbuf *offload_mbufs[RX_BUNDLE_SIZE]; int ngathered = 0; #ifdef DEBUG @@ -3089,7 +3055,6 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget) t3_rx_eth(adap, rspq, m, ethpad); -#ifdef LRO_SUPPORTED /* * The T304 sends incoming packets on any qset. If LRO * is also enabled, we could end up sending packet up @@ -3100,12 +3065,13 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget) */ skip_lro = __predict_false(qs->port->ifp != m->m_pkthdr.rcvif); - if (lro_enabled && lro_ctrl->lro_cnt && !skip_lro && - (tcp_lro_rx(lro_ctrl, m, 0) == 0)) { - /* successfully queue'd for LRO */ - } else + if (lro_enabled && lro_ctrl->lro_cnt && !skip_lro +#ifdef INET + && (tcp_lro_rx(lro_ctrl, m, 0) == 0) #endif - { + ) { + /* successfully queue'd for LRO */ + } else { /* * LRO not enabled, packet unsuitable for LRO, * or unable to queue. Pass it up right now in @@ -3124,7 +3090,7 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget) deliver_partial_bundle(&adap->tdev, rspq, offload_mbufs, ngathered); -#ifdef LRO_SUPPORTED +#ifdef INET /* Flush LRO */ while (!SLIST_EMPTY(&lro_ctrl->lro_active)) { struct lro_entry *queued = SLIST_FIRST(&lro_ctrl->lro_active); @@ -3620,6 +3586,9 @@ t3_add_configured_sysctls(adapter_t *sc) SYSCTL_ADD_UINT(ctx, rspqpoidlist, OID_AUTO, "credits", CTLFLAG_RD, &qs->rspq.credits, 0, "#credits"); + SYSCTL_ADD_UINT(ctx, rspqpoidlist, OID_AUTO, "starved", + CTLFLAG_RD, &qs->rspq.starved, + 0, "#times starved"); SYSCTL_ADD_XLONG(ctx, rspqpoidlist, OID_AUTO, "phys_addr", CTLFLAG_RD, &qs->rspq.phys_addr, "physical_address_of the queue"); @@ -3633,10 +3602,9 @@ t3_add_configured_sysctls(adapter_t *sc) CTLTYPE_STRING | CTLFLAG_RD, &qs->rspq, 0, t3_dump_rspq, "A", "dump of the response queue"); - - SYSCTL_ADD_INT(ctx, txqpoidlist, OID_AUTO, "dropped", - CTLFLAG_RD, &qs->txq[TXQ_ETH].txq_drops, - 0, "#tunneled packets dropped"); + SYSCTL_ADD_QUAD(ctx, txqpoidlist, OID_AUTO, "dropped", + CTLFLAG_RD, &qs->txq[TXQ_ETH].txq_mr->br_drops, + "#tunneled packets dropped"); SYSCTL_ADD_INT(ctx, txqpoidlist, OID_AUTO, "sendqlen", CTLFLAG_RD, &qs->txq[TXQ_ETH].sendq.qlen, 0, "#tunneled packets waiting to be sent"); @@ -3704,7 +3672,6 @@ t3_add_configured_sysctls(adapter_t *sc) CTLTYPE_STRING | CTLFLAG_RD, &qs->txq[TXQ_CTRL], 0, t3_dump_txq_ctrl, "A", "dump of the transmit queue"); -#ifdef LRO_SUPPORTED SYSCTL_ADD_INT(ctx, lropoidlist, OID_AUTO, "lro_queued", CTLFLAG_RD, &qs->lro.ctrl.lro_queued, 0, NULL); SYSCTL_ADD_INT(ctx, lropoidlist, OID_AUTO, "lro_flushed", @@ -3713,7 +3680,6 @@ t3_add_configured_sysctls(adapter_t *sc) CTLFLAG_RD, &qs->lro.ctrl.lro_bad_csum, 0, NULL); SYSCTL_ADD_INT(ctx, lropoidlist, OID_AUTO, "lro_cnt", CTLFLAG_RD, &qs->lro.ctrl.lro_cnt, 0, NULL); -#endif } /* Now add a node for mac stats. */ diff --git a/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c b/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c index cf42ea0c94a..a4f2ff669ca 100644 --- a/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c +++ b/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c @@ -138,8 +138,7 @@ open_rnic_dev(struct t3cdev *tdev) CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev); if (!vers_printed++) - printf("Chelsio T3 RDMA Driver - version %s\n", - DRV_VERSION); + printf("Chelsio T3 RDMA Driver - version x.xx\n"); rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp)); if (!rnicp) { printf("Cannot allocate ib device\n"); diff --git a/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c b/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c index 76237fb99bc..bbb594ac2b2 100644 --- a/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c +++ b/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c @@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include diff --git a/sys/modules/cxgb/cxgb/Makefile b/sys/modules/cxgb/cxgb/Makefile index 65b2f6f4934..9a433b200bc 100644 --- a/sys/modules/cxgb/cxgb/Makefile +++ b/sys/modules/cxgb/cxgb/Makefile @@ -12,13 +12,5 @@ SRCS+= opt_inet.h opt_zero.h opt_sched.h SRCS+= uipc_mvec.c CFLAGS+= -g -DDEFAULT_JUMBO -I${CXGB} -CFLAGS+= -DDISABLE_MBUF_IOVEC -#CFLAGS+= -DIFNET_MULTIQUEUE -#CFLAGS+= -DDISABLE_MBUF_IOVEC -#CFLAGS+= -DDEBUG -DDEBUG_PRINT -#CFLAGS+= -DINVARIANT_SUPPORT -DINVARIANTS -#CFLAGS+= -DWITNESS -#CFLAGS += -DLOCK_PROFILING -#CFLAGS+= -DWITNESS .include From b6b8213e386bdbe96e3e45e3ddb33ac0b0abdeb9 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Mon, 5 Apr 2010 23:43:23 +0000 Subject: [PATCH 1838/2592] MFC of tzdata2010h: From tzdata2010h: - Tunis will not go into DST this year. - Pakistan will not go into DST this year. From tzdata2010g: - Bangladesh cancels DST. - Palestine goes into DST one day later than expected. - Russian timezones update: Europe/Samara goes to Moscow time. Asia/Kamchatka goes to Moscow+8 time. Asia/Anadyr goes to Moscow+8 time. --- share/zoneinfo/asia | 71 ++++++++++++++++++++++------------------- share/zoneinfo/europe | 12 ++++--- share/zoneinfo/zone.tab | 8 ++--- 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia index 859d9c54d43..8cafc5973e2 100644 --- a/share/zoneinfo/asia +++ b/share/zoneinfo/asia @@ -1,4 +1,4 @@ -# @(#)asia 8.56 +# @(#)asia 8.58 # This file is in the public domain, so clarified as of # 2009-05-17 by Arthur David Olson. @@ -214,42 +214,20 @@ Zone Asia/Bahrain 3:22:20 - LMT 1920 # Al Manamah # 2010 midnight. The decision came at a cabinet meeting at the Prime # Minister's Office last night..." -# From Danvin Ruangchan (2009-12-24): -# ...the news mentions DST will be turned off again 7 months after March -# 31st on Oct 31, 2010. - -# From Arthur David Olson (2009-12-26): -# Indeed, "The government will advance again the Banglasdesh Standard -# Time by one one hour on March 31 next year by enforcing the Daylight -# Saving Time (DST) for seven months. It will continue till October 31 -# until further notice." I take that last sentence as the -# establishment of a rule. - -# From Nobutomo Nakano (2010-02-19): -# We received a report from Bangladesh saying that the start/end of -# Bangladesh DST is incorrect. Currently we have only the Bengali version -# of the official mail from BTRC which describes the following: -# -# "From 2010 each year when local standard time is about to reach -# March 31 at 10:59:00 PM clocks are turned forward 1 hour (11:59:00 PM) -# and when local daylight time is about to October 31 at 11:59:00 PM -# clocks are turned backward 1 hour (10:59:00 PM)." -# -# So, DST will start/end 1 minute earlier. - -# From Arthur David Olson (2010-03-03): -# The file -# -# http://www.cabinet.gov/bd/file_upload/news_events/en_169.pdf +# From Alexander Krivenyshev (2010-03-22): +# According to Bangladesh newspaper "The Daily Star," +# Cabinet cancels Daylight Saving Time +# +# http://www.thedailystar.net/newDesign/latest_news.php?nid=22817 +# +# or +# +# http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html # -# is in Bengali; it does contain two "31"s as well as two "11.59"s and a "10.59" -# which is consistent with the information provided by Nobutomo Nakano. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Dhaka 2009 only - Jun 19 23:00 1:00 S Rule Dhaka 2009 only - Dec 31 23:59 0 - -Rule Dhaka 2010 max - Mar 31 22:59 1:00 S -Rule Dhaka 2010 max - Oct 31 23:59 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Dhaka 6:01:40 - LMT 1890 @@ -2129,6 +2107,32 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html # +# From Alexander Krivenyshev (2010-03-19): +# According to Voice of Palestine DST will last for 191 days, from March +# 26, 2010 till "the last Sunday before the tenth day of Tishri +# (October), each year" (October 03, 2010?) +# +# +# http://palvoice.org/forums/showthread.php?t=245697 +# +# (in Arabic) +# or +# +# http://www.worldtimezone.com/dst_news/dst_news_westbank03.html +# + +# From Steffen Thorsen (2010-03-24): +# ...Ma'an News Agency reports that Hamas cabinet has decided it will +# start one day later, at 12:01am. Not sure if they really mean 12:01am or +# noon though: +# +# +# http://www.maannews.net/eng/ViewDetails.aspx?ID=271178 +# +# (Ma'an News Agency) +# "At 12:01am Friday, clocks in Israel and the West Bank will change to +# 1:01am, while Gaza clocks will change at 12:01am Saturday morning." + # The rules for Egypt are stolen from the `africa' file. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S @@ -2146,7 +2150,8 @@ Rule Palestine 2006 2008 - Apr 1 0:00 1:00 S Rule Palestine 2006 only - Sep 22 0:00 0 - Rule Palestine 2007 only - Sep Thu>=8 2:00 0 - Rule Palestine 2008 only - Aug lastFri 2:00 0 - -Rule Palestine 2009 max - Mar lastFri 0:00 1:00 S +Rule Palestine 2009 only - Mar lastFri 0:00 1:00 S +Rule Palestine 2010 max - Mar lastSat 0:01 1:00 S Rule Palestine 2009 max - Sep Fri>=1 2:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] diff --git a/share/zoneinfo/europe b/share/zoneinfo/europe index 05e3caec3ae..aca3a0bd3ae 100644 --- a/share/zoneinfo/europe +++ b/share/zoneinfo/europe @@ -1,5 +1,5 @@ #
    -# @(#)europe	8.25
    +# @(#)europe	8.26
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -2041,7 +2041,9 @@ Zone Europe/Samara	 3:20:36 -	LMT	1919 Jul  1 2:00
     			 3:00	Russia	KUY%sT	1991 Mar 31 2:00s
     			 2:00	Russia	KUY%sT	1991 Sep 29 2:00s
     			 3:00	-	KUYT	1991 Oct 20 3:00
    -			 4:00	Russia	SAM%sT	# Samara Time
    +			 4:00	Russia	SAM%sT	2010 Mar 28 2:00s # Samara Time
    +			 3:00	Russia	SAM%sT
    +
     #
     # From Oscar van Vlijmen (2001-08-25): [This region consists of]
     # Respublika Bashkortostan, Komi-Permyatskij avtonomnyj okrug,
    @@ -2194,7 +2196,8 @@ Zone Asia/Kamchatka	10:34:36 -	LMT	1922 Nov 10
     			11:00	-	PETT	1930 Jun 21 # P-K Time
     			12:00	Russia	PET%sT	1991 Mar 31 2:00s
     			11:00	Russia	PET%sT	1992 Jan 19 2:00s
    -			12:00	Russia	PET%sT
    +			12:00	Russia	PET%sT	2010 Mar 28 2:00s
    +			11:00	Russia	PET%sT
     #
     # Chukotskij avtonomnyj okrug
     Zone Asia/Anadyr	11:49:56 -	LMT	1924 May  2
    @@ -2202,7 +2205,8 @@ Zone Asia/Anadyr	11:49:56 -	LMT	1924 May  2
     			13:00	Russia	ANA%sT	1982 Apr  1 0:00s
     			12:00	Russia	ANA%sT	1991 Mar 31 2:00s
     			11:00	Russia	ANA%sT	1992 Jan 19 2:00s
    -			12:00	Russia	ANA%sT
    +			12:00	Russia	ANA%sT	2010 Mar 28 2:00s
    +			11:00	Russia	ANA%sT
     
     # Serbia
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
    diff --git a/share/zoneinfo/zone.tab b/share/zoneinfo/zone.tab
    index 59b86007e30..6959c494df9 100644
    --- a/share/zoneinfo/zone.tab
    +++ b/share/zoneinfo/zone.tab
    @@ -1,5 +1,5 @@
     # 
    -# @(#)zone.tab	8.34
    +# @(#)zone.tab	8.35
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     #
    @@ -330,7 +330,7 @@ RS	+4450+02030	Europe/Belgrade
     RU	+5443+02030	Europe/Kaliningrad	Moscow-01 - Kaliningrad
     RU	+5545+03735	Europe/Moscow	Moscow+00 - west Russia
     RU	+4844+04425	Europe/Volgograd	Moscow+00 - Caspian Sea
    -RU	+5312+05009	Europe/Samara	Moscow+01 - Samara, Udmurtia
    +RU	+5312+05009	Europe/Samara	Moscow - 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
    @@ -341,8 +341,8 @@ RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
     RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Amur River
     RU	+4658+14242	Asia/Sakhalin	Moscow+07 - Sakhalin Island
     RU	+5934+15048	Asia/Magadan	Moscow+08 - Magadan
    -RU	+5301+15839	Asia/Kamchatka	Moscow+09 - Kamchatka
    -RU	+6445+17729	Asia/Anadyr	Moscow+10 - Bering Sea
    +RU	+5301+15839	Asia/Kamchatka	Moscow+08 - Kamchatka
    +RU	+6445+17729	Asia/Anadyr	Moscow+08 - Bering Sea
     RW	-0157+03004	Africa/Kigali
     SA	+2438+04643	Asia/Riyadh
     SB	-0932+16012	Pacific/Guadalcanal
    
    From 423a1f84bf4fb88183f5bd1a49c8966567131a9c Mon Sep 17 00:00:00 2001
    From: Navdeep Parhar 
    Date: Mon, 5 Apr 2010 23:55:04 +0000
    Subject: [PATCH 1839/2592] MFC r204267: Allow cxgbtool to build with WARNS=6
    
    ---
     usr.sbin/cxgbtool/cxgbtool.c     | 205 +++++++++++++++++++------------
     usr.sbin/cxgbtool/reg_defs.c     |  22 ++--
     usr.sbin/cxgbtool/reg_defs_t3.c  |  48 ++++----
     usr.sbin/cxgbtool/reg_defs_t3b.c |  48 ++++----
     usr.sbin/cxgbtool/reg_defs_t3c.c |  48 ++++----
     5 files changed, 211 insertions(+), 160 deletions(-)
    
    diff --git a/usr.sbin/cxgbtool/cxgbtool.c b/usr.sbin/cxgbtool/cxgbtool.c
    index 8d7e677b1bb..28d91f96dfe 100644
    --- a/usr.sbin/cxgbtool/cxgbtool.c
    +++ b/usr.sbin/cxgbtool/cxgbtool.c
    @@ -85,7 +85,8 @@ struct reg_info {
     
     static const char *progname;
     
    -static void __attribute__((noreturn)) usage(FILE *fp)
    +static void
    +usage(FILE *fp)
     {
     	fprintf(fp, "Usage: %s  [operation]\n", progname);
     	fprintf(fp,
    @@ -136,7 +137,8 @@ doit(const char *iff_name, unsigned long cmd, void *data)
     	return ioctl(fd, cmd, data) < 0 ? -1 : 0;
     }
     
    -static int get_int_arg(const char *s, uint32_t *valp)
    +static int
    +get_int_arg(const char *s, uint32_t *valp)
     {
     	char *p;
     
    @@ -172,11 +174,12 @@ write_reg(const char *iff_name, uint32_t addr, uint32_t val)
     		err(1, "register write");
     }
     
    -static int register_io(int argc, char *argv[], int start_arg,
    +static int
    +register_io(int argc, char *argv[], int start_arg,
     		       const char *iff_name)
     {
     	char *p;
    -	uint32_t addr, val = 0, write = 0;
    +	uint32_t addr, val = 0, w = 0;
     
     	if (argc != start_arg + 1) return -1;
     
    @@ -184,14 +187,14 @@ static int register_io(int argc, char *argv[], int start_arg,
     	if (p == argv[start_arg]) return -1;
     	if (*p == '=' && p[1]) {
     		val = strtoul(p + 1, &p, 0);
    -		write = 1;
    +		w = 1;
     	}
     	if (*p) {
     		warnx("bad parameter \"%s\"", argv[start_arg]);
     		return -1;
     	}
     
    -	if (write)
    +	if (w)
     		write_reg(iff_name, addr, val);
     	else {
     		val = read_reg(iff_name, addr);
    @@ -200,9 +203,9 @@ static int register_io(int argc, char *argv[], int start_arg,
     	return 0;
     }
     
    -static int mdio_io(int argc, char *argv[], int start_arg, const char *iff_name) 
    +static int
    +mdio_io(int argc, char *argv[], int start_arg, const char *iff_name) 
     { 
    -        struct ifreq ifr; 
             struct ch_mii_data p;
             unsigned int cmd, phy_addr, reg, mmd, val; 
      
    @@ -230,12 +233,14 @@ static int mdio_io(int argc, char *argv[], int start_arg, const char *iff_name)
             return 0; 
     } 
     
    -static inline uint32_t xtract(uint32_t val, int shift, int len)
    +static inline
    +uint32_t xtract(uint32_t val, int shift, int len)
     {
     	return (val >> shift) & ((1 << len) - 1);
     }
     
    -static int dump_block_regs(const struct reg_info *reg_array, uint32_t *regs)
    +static int
    +dump_block_regs(const struct reg_info *reg_array, uint32_t *regs)
     {
     	uint32_t reg_val = 0; // silence compiler warning
     
    @@ -254,7 +259,8 @@ static int dump_block_regs(const struct reg_info *reg_array, uint32_t *regs)
     	return 1;
     }
     
    -static int dump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs)
    +static int
    +dump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs)
     {
     	int match = 0;
     	char *block_name = NULL;
    @@ -292,8 +298,8 @@ static int dump_regs_t2(int argc, char *argv[], int start_arg, uint32_t *regs)
     }
     
     #if defined(CONFIG_T3_REGS)
    -static int dump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs,
    -			int is_pcie)
    +static int
    +dump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs, int is_pcie)
     {
     	int match = 0;
     	char *block_name = NULL;
    @@ -353,8 +359,9 @@ static int dump_regs_t3(int argc, char *argv[], int start_arg, uint32_t *regs,
     	return 0;
     }
     
    -static int dump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs,
    -			 int is_pcie)
    +static int
    +dump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs,
    +    int is_pcie)
     {
     	int match = 0;
     	char *block_name = NULL;
    @@ -414,8 +421,9 @@ static int dump_regs_t3b(int argc, char *argv[], int start_arg, uint32_t *regs,
     	return 0;
     }
     
    -static int dump_regs_t3c(int argc, char *argv[], int start_arg, uint32_t *regs,
    -			 int is_pcie)
    +static int
    +dump_regs_t3c(int argc, char *argv[], int start_arg, uint32_t *regs,
    +    int is_pcie)
     {
     	int match = 0;
     	char *block_name = NULL;
    @@ -479,7 +487,7 @@ static int dump_regs_t3c(int argc, char *argv[], int start_arg, uint32_t *regs,
     static int
     dump_regs(int argc, char *argv[], int start_arg, const char *iff_name)
     {
    -	int i, vers, revision, is_pcie;
    +	int vers, revision, is_pcie;
     	struct ch_ifconf_regs regs;
     
     	regs.len = REGDUMP_SIZE;
    @@ -514,7 +522,8 @@ dump_regs(int argc, char *argv[], int start_arg, const char *iff_name)
     	return 0;
     }
     
    -static int t3_meminfo(const uint32_t *regs)
    +static int
    +t3_meminfo(const uint32_t *regs)
     {
     	enum {
     		SG_EGR_CNTX_BADDR       = 0x58,
    @@ -592,11 +601,16 @@ static int t3_meminfo(const uint32_t *regs)
     	return 0;
     }
     
    -static int meminfo(int argc, char *argv[], int start_arg, const char *iff_name)
    +static int
    +meminfo(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	int vers;
     	struct ch_ifconf_regs regs;
     
    +	(void) argc;
    +	(void) argv;
    +	(void) start_arg;
    +
     	regs.len = REGDUMP_SIZE;
     	if ((regs.data = malloc(regs.len)) == NULL)
     		err(1, "can't malloc");
    @@ -612,11 +626,11 @@ static int meminfo(int argc, char *argv[], int start_arg, const char *iff_name)
     	return 0;
     }
     
    -static int mtu_tab_op(int argc, char *argv[], int start_arg,
    -		      const char *iff_name)
    +static int
    +mtu_tab_op(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	struct ch_mtus m;
    -	int i;
    +	unsigned int i;
     
     	if (argc == start_arg) {
     		if (doit(iff_name, CHELSIO_GETMTUTAB, &m) < 0)
    @@ -649,13 +663,14 @@ static int mtu_tab_op(int argc, char *argv[], int start_arg,
     }
     
     #ifdef CHELSIO_INTERNAL
    -static void show_egress_cntxt(uint32_t data[])
    +static void
    +show_egress_cntxt(uint32_t data[])
     {
     	printf("credits:      %u\n", data[0] & 0x7fff);
     	printf("GTS:          %u\n", (data[0] >> 15) & 1);
     	printf("index:        %u\n", data[0] >> 16);
     	printf("queue size:   %u\n", data[1] & 0xffff);
    -	printf("base address: 0x%llx\n",
    +	printf("base address: 0x%" PRIx64 "\n",
     	       ((data[1] >> 16) | ((uint64_t)data[2] << 16) |
     	       (((uint64_t)data[3] & 0xf) << 48)) << 12);
     	printf("rsp queue #:  %u\n", (data[3] >> 4) & 7);
    @@ -667,9 +682,10 @@ static void show_egress_cntxt(uint32_t data[])
     	printf("valid:        %u\n", (data[3] >> 31) & 1);
     }
     
    -static void show_fl_cntxt(uint32_t data[])
    +static void
    +show_fl_cntxt(uint32_t data[])
     {
    -	printf("base address: 0x%llx\n",
    +	printf("base address: 0x%" PRIx64 "\n",
     	       ((uint64_t)data[0] | ((uint64_t)data[1] & 0xfffff) << 32) << 12);
     	printf("index:        %u\n", (data[1] >> 20) | ((data[2] & 0xf) << 12));
     	printf("queue size:   %u\n", (data[2] >> 4) & 0xffff);
    @@ -680,11 +696,12 @@ static void show_fl_cntxt(uint32_t data[])
     	printf("GTS:          %u\n", (data[3] >> 31) & 1);
     }
     
    -static void show_response_cntxt(uint32_t data[])
    +static void
    +show_response_cntxt(uint32_t data[])
     {
     	printf("index:        %u\n", data[0] & 0xffff);
     	printf("size:         %u\n", data[0] >> 16);
    -	printf("base address: 0x%llx\n",
    +	printf("base address: 0x%" PRIx64 "\n",
     	       ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12);
     	printf("MSI-X/RspQ:   %u\n", (data[2] >> 20) & 0x3f);
     	printf("intr enable:  %u\n", (data[2] >> 26) & 1);
    @@ -694,11 +711,12 @@ static void show_response_cntxt(uint32_t data[])
     	printf("FL threshold: %u\n", data[3]);
     }
     
    -static void show_cq_cntxt(uint32_t data[])
    +static void
    +show_cq_cntxt(uint32_t data[])
     {
     	printf("index:            %u\n", data[0] & 0xffff);
     	printf("size:             %u\n", data[0] >> 16);
    -	printf("base address:     0x%llx\n",
    +	printf("base address:     0x%" PRIx64 "\n",
     	       ((uint64_t)data[1] | ((uint64_t)data[2] & 0xfffff) << 32) << 12);
     	printf("rsp queue #:      %u\n", (data[2] >> 20) & 0x3f);
     	printf("AN:               %u\n", (data[2] >> 26) & 1);
    @@ -710,8 +728,8 @@ static void show_cq_cntxt(uint32_t data[])
     	printf("credit threshold: %u\n", data[3] >> 16);
     }
     
    -static int get_sge_context(int argc, char *argv[], int start_arg,
    -			   const char *iff_name)
    +static int
    +get_sge_context(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	struct ch_cntxt ctx;
     
    @@ -750,8 +768,8 @@ static int get_sge_context(int argc, char *argv[], int start_arg,
     
     #define ntohll(x) be64toh((x))
     
    -static int get_sge_desc(int argc, char *argv[], int start_arg,
    -			const char *iff_name)
    +static int
    +get_sge_desc(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	uint64_t *p, wr_hdr;
     	unsigned int n = 1, qset, qnum;
    @@ -796,7 +814,8 @@ static int get_sge_desc(int argc, char *argv[], int start_arg,
     }
     #endif
     
    -static int get_tcb2(int argc, char *argv[], int start_arg, const char *iff_name)
    +static int
    +get_tcb2(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	uint64_t *d;
     	unsigned int i;
    @@ -835,8 +854,9 @@ static int get_tcb2(int argc, char *argv[], int start_arg, const char *iff_name)
     	return 0;
     }
     
    -static int get_pm_page_spec(const char *s, unsigned int *page_size,
    -			    unsigned int *num_pages)
    +static int
    +get_pm_page_spec(const char *s, unsigned int *page_size,
    +    unsigned int *num_pages)
     {
     	char *p;
     	unsigned long val;
    @@ -854,7 +874,8 @@ static int get_pm_page_spec(const char *s, unsigned int *page_size,
     	return *p;
     }
     
    -static int conf_pm(int argc, char *argv[], int start_arg, const char *iff_name)
    +static int
    +conf_pm(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	struct ch_pm pm;
     
    @@ -884,8 +905,8 @@ static int conf_pm(int argc, char *argv[], int start_arg, const char *iff_name)
     }
     
     #ifdef	CHELSIO_INTERNAL
    -static int dump_tcam(int argc, char *argv[], int start_arg,
    -		     const char *iff_name)
    +static int
    +dump_tcam(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	unsigned int nwords;
     	struct ch_tcam_word op;
    @@ -907,7 +928,8 @@ static int dump_tcam(int argc, char *argv[], int start_arg,
     	return 0;
     }
     
    -static void hexdump_8b(unsigned int start, uint64_t *data, unsigned int len)
    +static void
    +hexdump_8b(unsigned int start, uint64_t *data, unsigned int len)
     {
     	int i;
     
    @@ -920,8 +942,8 @@ static void hexdump_8b(unsigned int start, uint64_t *data, unsigned int len)
     	}
     }
     
    -static int dump_mc7(int argc, char *argv[], int start_arg,
    -		    const char *iff_name)
    +static int
    +dump_mc7(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	struct ch_mem_range mem;
     	unsigned int mem_id, addr, len;
    @@ -959,10 +981,11 @@ static int dump_mc7(int argc, char *argv[], int start_arg,
     }
     #endif
     
    -/* Max FW size is 32K including version, +4 bytes for the checksum. */
    +/* Max FW size is 64K including version, +4 bytes for the checksum. */
     #define MAX_FW_IMAGE_SIZE (64 * 1024)
     
    -static int load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
    +static int
    +load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	int fd, len;
     	struct ch_mem_range op;
    @@ -979,12 +1002,13 @@ static int load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
     	if (!op.buf)
     		err(1, "load firmware");
     
    -	op.len = read(fd, op.buf, MAX_FW_IMAGE_SIZE + 1);
    -	if (op.len < 0)
    +	len = read(fd, op.buf, MAX_FW_IMAGE_SIZE + 1);
    +	if (len < 0)
     		err(1, "load firmware");
    - 	if (op.len > MAX_FW_IMAGE_SIZE)
    + 	if (len > MAX_FW_IMAGE_SIZE)
     		errx(1, "FW image too large");
     
    +	op.len = len;
     	if (doit(iff_name, CHELSIO_LOAD_FW, &op) < 0)
     		err(1, "load firmware");
     	return 0;
    @@ -993,8 +1017,8 @@ static int load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
     /* Max BOOT size is 255*512 bytes including the BIOS boot ROM basic header */
     #define MAX_BOOT_IMAGE_SIZE (0xff * 512)
     
    -static int load_boot(int argc, char *argv[],
    -		     int start_arg, const char *iff_name)
    +static int
    +load_boot(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	int fd, len;
     	struct ch_mem_range op;
    @@ -1024,7 +1048,8 @@ static int load_boot(int argc, char *argv[],
     	return 0;
     }
     
    -static int dump_proto_sram(const char *iff_name)
    +static int
    +dump_proto_sram(const char *iff_name)
     {
     	int i, j;
     	uint8_t buf[PROTO_SRAM_SIZE];
    @@ -1054,15 +1079,20 @@ static int dump_proto_sram(const char *iff_name)
     	return 0;
     }
     
    -static int proto_sram_op(int argc, char *argv[], int start_arg,
    +static int
    +proto_sram_op(int argc, char *argv[], int start_arg,
     			 const char *iff_name)
     {
    +	(void) argv;
    +	(void) start_arg;
    +
     	if (argc == start_arg)
     		return dump_proto_sram(iff_name);
     	return -1;
     }
     
    -static int dump_qset_params(const char *iff_name)
    +static int
    +dump_qset_params(const char *iff_name)
     {
     	struct ch_qset_params qp;
     
    @@ -1084,10 +1114,10 @@ static int dump_qset_params(const char *iff_name)
     	return 0;
     }
     
    -static int qset_config(int argc, char *argv[], int start_arg,
    -		       const char *iff_name)
    +static int
    +qset_config(int argc, char *argv[], int start_arg, const char *iff_name)
     {
    -	struct ch_qset_params qp;
    +	(void) argv;
     
     	if (argc == start_arg)
     		return dump_qset_params(iff_name);
    @@ -1095,11 +1125,13 @@ static int qset_config(int argc, char *argv[], int start_arg,
     	return -1;
     }
     
    -static int qset_num_config(int argc, char *argv[], int start_arg,
    -			   const char *iff_name)
    +static int
    +qset_num_config(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	struct ch_reg reg;
     
    +	(void) argv;
    +
     	if (argc == start_arg) {
     		if (doit(iff_name, CHELSIO_GET_QSET_NUM, ®) < 0)
     			err(1, "get qsets");
    @@ -1113,7 +1145,8 @@ static int qset_num_config(int argc, char *argv[], int start_arg,
     /*
      * Parse a string containing an IP address with an optional network prefix.
      */
    -static int parse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask)
    +static int
    +parse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask)
     {
     	char *p, *slash;
     	struct in_addr ia;
    @@ -1143,7 +1176,8 @@ static int parse_ipaddr(const char *s, uint32_t *addr, uint32_t *mask)
     /*
      * Parse a string containing a value and an optional colon separated mask.
      */
    -static int parse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask)
    +static int
    +parse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask)
     {
     	char *p;
     
    @@ -1156,14 +1190,15 @@ static int parse_val_mask_param(const char *s, uint32_t *val, uint32_t *mask)
     	return *p ? -1 : 0;
     }
     
    -static int parse_trace_param(const char *s, uint32_t *val, uint32_t *mask)
    +static int
    +parse_trace_param(const char *s, uint32_t *val, uint32_t *mask)
     {
     	return strchr(s, '.') ? parse_ipaddr(s, val, mask) :
     				parse_val_mask_param(s, val, mask);
     }
     
    -static int trace_config(int argc, char *argv[], int start_arg,
    -			const char *iff_name)
    +static int
    +trace_config(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	uint32_t val, mask;
     	struct ch_trace trace;
    @@ -1238,7 +1273,8 @@ static int trace_config(int argc, char *argv[], int start_arg,
     	return 0;
     }
     
    -static int get_sched_param(int argc, char *argv[], int pos, unsigned int *valp)
    +static int
    +get_sched_param(int argc, char *argv[], int pos, unsigned int *valp)
     {
     	if (pos + 1 >= argc)
     		errx(1, "missing value for %s", argv[pos]);
    @@ -1247,7 +1283,8 @@ static int get_sched_param(int argc, char *argv[], int pos, unsigned int *valp)
     	return 0;
     }
     
    -static int tx_sched(int argc, char *argv[], int start_arg, const char *iff_name)
    +static int
    +tx_sched(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	struct ch_hw_sched op;
     	unsigned int idx, val;
    @@ -1293,7 +1330,8 @@ static int tx_sched(int argc, char *argv[], int start_arg, const char *iff_name)
     	return 0;
     }
     
    -static int pktsched(int argc, char *argv[], int start_arg, const char *iff_name)
    +static int
    +pktsched(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	struct ch_pktsched_params op;
     	unsigned int idx, min = -1, max, binding = -1;
    @@ -1333,20 +1371,29 @@ static int pktsched(int argc, char *argv[], int start_arg, const char *iff_name)
     	return 0;
     }
     
    -static int clear_stats(int argc, char *argv[], int start_arg,
    -		       const char *iff_name)
    +static int
    +clear_stats(int argc, char *argv[], int start_arg, const char *iff_name)
     {
    +	(void) argc;
    +	(void) argv;
    +	(void) start_arg;
    +
     	if (doit(iff_name, CHELSIO_CLEAR_STATS, NULL) < 0)
     		 err(1, "clearstats");
     
     	return 0;
     }
     
    -static int get_up_la(int argc, char *argv[], int start_arg, const char *iff_name)
    +static int
    +get_up_la(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	struct ch_up_la la;
     	int i, idx, max_idx, entries;
     
    +	(void) argc;
    +	(void) argv;
    +	(void) start_arg;
    +
     	la.stopped = 0;
     	la.idx = -1;
     	la.bufsize = LA_BUFSIZE;
    @@ -1372,11 +1419,16 @@ static int get_up_la(int argc, char *argv[], int start_arg, const char *iff_name
     	return 0;
     }
     
    -static int get_up_ioqs(int argc, char *argv[], int start_arg, const char *iff_name)
    +static int
    +get_up_ioqs(int argc, char *argv[], int start_arg, const char *iff_name)
     {
     	struct ch_up_ioqs ioqs;
     	int i, entries;
     
    +	(void) argc;
    +	(void) argv;
    +	(void) start_arg;
    +
     	bzero(&ioqs, sizeof(ioqs));
     	ioqs.bufsize = IOQS_BUFSIZE;
     	ioqs.data = malloc(IOQS_BUFSIZE);
    @@ -1465,10 +1517,12 @@ run_cmd(int argc, char *argv[], const char *iff_name)
     static int
     run_cmd_loop(int argc, char *argv[], const char *iff_name)
     {
    -	int n, i;
    +	int n;
    +	unsigned int i;
     	char buf[64];
     	char *args[8], *s;
     
    +	(void) argc;
     	args[0] = argv[0];
     	args[1] = argv[1];
     
    @@ -1481,11 +1535,8 @@ run_cmd_loop(int argc, char *argv[], const char *iff_name)
     	for (;;) {
     		fprintf(stdout, "> ");
     		fflush(stdout);
    -		n = read(STDIN_FILENO, buf, sizeof(buf));
    -		if (n > sizeof(buf) - 1) {
    -			fprintf(stdout, "too much input.\n");
    -			return (0);
    -		} else if (n <= 0)
    +		n = read(STDIN_FILENO, buf, sizeof(buf) - 1);
    +		if (n <= 0)
     			return (0);
     
     		if (buf[--n] != '\n')
    diff --git a/usr.sbin/cxgbtool/reg_defs.c b/usr.sbin/cxgbtool/reg_defs.c
    index 734061fa17a..687bb75cee9 100644
    --- a/usr.sbin/cxgbtool/reg_defs.c
    +++ b/usr.sbin/cxgbtool/reg_defs.c
    @@ -106,7 +106,7 @@ struct reg_info sge_regs[] = {
     		{ "Packet_Too_Big", 3, 1 },
     		{ "Packet_Mismatch", 4, 1 },
     	{ "SG_RESPACCUTIMER", 0xc0, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info mc3_regs[] = {
    @@ -196,7 +196,7 @@ struct reg_info mc3_regs[] = {
     		{ "MC3_Uncorr_Err", 1, 1 },
     		{ "MC3_Parity_Err", 2, 8 },
     		{ "MC3_Addr_Err", 10, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info mc4_regs[] = {
    @@ -276,7 +276,7 @@ struct reg_info mc4_regs[] = {
     		{ "MC4_Corr_Err", 0, 1 },
     		{ "MC4_Uncorr_Err", 1, 1 },
     		{ "MC4_Addr_Err", 2, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info tpi_regs[] = {
    @@ -290,7 +290,7 @@ struct reg_info tpi_regs[] = {
     		{ "INT_DIR", 31, 1 },
     	{ "TPI_PAR", 0x29c, 0 },
     		{ "TPIPAR", 0, 7 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info tp_regs[] = {
    @@ -509,7 +509,7 @@ struct reg_info tp_regs[] = {
     		{ "DROP_TICKS_CNT", 4, 26 },
     		{ "NUM_PKTS_DROPPED", 0, 4 },
     	{ "TP_TX_DROP_COUNT", 0x4bc, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info rat_regs[] = {
    @@ -532,7 +532,7 @@ struct reg_info rat_regs[] = {
     		{ "CspiFramingError", 1, 1 },
     		{ "SgeFramingError", 2, 1 },
     		{ "TpFramingError", 3, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info cspi_regs[] = {
    @@ -560,7 +560,7 @@ struct reg_info cspi_regs[] = {
     		{ "TXDrop", 2, 1 },
     		{ "RXOverflow", 3, 1 },
     		{ "RAMParityErr", 4, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info espi_regs[] = {
    @@ -660,7 +660,7 @@ struct reg_info espi_regs[] = {
     		{ "Error_Ack", 9, 1 },
     		{ "Unmapped_Err", 10, 1 },
     		{ "Transaction_Timer", 16, 8 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info ulp_regs[] = {
    @@ -682,7 +682,7 @@ struct reg_info ulp_regs[] = {
     		{ "Pm_E2C_Wrt_Full", 24, 1 },
     		{ "Pm_C2E_Wrt_Full", 25, 1 },
     	{ "ULP_PIO_CTRL", 0x998, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info pl_regs[] = {
    @@ -712,7 +712,7 @@ struct reg_info pl_regs[] = {
     		{ "PL_Intr_CSPI", 9, 1 },
     		{ "PL_Intr_PCIX", 10, 1 },
     		{ "PL_Intr_EXT", 11, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info mc5_regs[] = {
    @@ -833,5 +833,5 @@ struct reg_info mc5_regs[] = {
     	{ "MC5_DATA_WRITE_CMD", 0xcf4, 0 },
     	{ "MC5_DATA_READ_CMD", 0xcf8, 0 },
     	{ "MC5_MASK_WRITE_CMD", 0xcfc, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
    diff --git a/usr.sbin/cxgbtool/reg_defs_t3.c b/usr.sbin/cxgbtool/reg_defs_t3.c
    index ffa4aefa78f..6e9b8b1176f 100644
    --- a/usr.sbin/cxgbtool/reg_defs_t3.c
    +++ b/usr.sbin/cxgbtool/reg_defs_t3.c
    @@ -140,7 +140,7 @@ struct reg_info sge3_regs[] = {
     		{ "DrbPriThrsh", 0, 16 },
     	{ "SG_DEBUG_INDEX", 0x78, 0 },
     	{ "SG_DEBUG_DATA", 0x7c, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info pcix1_regs[] = {
    @@ -212,7 +212,7 @@ struct reg_info pcix1_regs[] = {
     		{ "WakeUp0", 2, 1 },
     		{ "SleepMode1", 1, 1 },
     		{ "SleepMode0", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info pcie0_regs[] = {
    @@ -411,7 +411,7 @@ struct reg_info pcie0_regs[] = {
     		{ "BISTDone", 24, 8 },
     		{ "BISTCycleThresh", 3, 16 },
     		{ "BISTMode", 0, 3 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3dbg_regs[] = {
    @@ -557,7 +557,7 @@ struct reg_info t3dbg_regs[] = {
     		{ "PMON_CDEL_MANUAL", 4, 1 },
     		{ "PMON_MANUAL", 1, 1 },
     		{ "PMON_AUTO", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info mc7_pmrx_regs[] = {
    @@ -674,7 +674,7 @@ struct reg_info mc7_pmrx_regs[] = {
     		{ "PE", 2, 15 },
     		{ "UE", 1, 1 },
     		{ "CE", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info mc7_pmtx_regs[] = {
    @@ -791,7 +791,7 @@ struct reg_info mc7_pmtx_regs[] = {
     		{ "PE", 2, 15 },
     		{ "UE", 1, 1 },
     		{ "CE", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info mc7_cm_regs[] = {
    @@ -908,7 +908,7 @@ struct reg_info mc7_cm_regs[] = {
     		{ "PE", 2, 15 },
     		{ "UE", 1, 1 },
     		{ "CE", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info cim_regs[] = {
    @@ -1024,7 +1024,7 @@ struct reg_info cim_regs[] = {
     	{ "CIM_CDEBUGDATA", 0x2d0, 0 },
     		{ "CDebugDataH", 16, 16 },
     		{ "CDebugDataL", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info tp1_regs[] = {
    @@ -1384,7 +1384,7 @@ struct reg_info tp1_regs[] = {
     	{ "TP_EMBED_OP_FIELD3", 0x4f4, 0 },
     	{ "TP_EMBED_OP_FIELD4", 0x4f8, 0 },
     	{ "TP_EMBED_OP_FIELD5", 0x4fc, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info ulp2_rx_regs[] = {
    @@ -1428,7 +1428,7 @@ struct reg_info ulp2_rx_regs[] = {
     	{ "ULPRX_RQ_ULIMIT", 0x538, 0 },
     	{ "ULPRX_PBL_LLIMIT", 0x53c, 0 },
     	{ "ULPRX_PBL_ULIMIT", 0x540, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info ulp2_tx_regs[] = {
    @@ -1456,7 +1456,7 @@ struct reg_info ulp2_tx_regs[] = {
     	{ "ULPTX_DMA_WEIGHT", 0x5ac, 0 },
     		{ "D1_WEIGHT", 16, 16 },
     		{ "D0_WEIGHT", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info pm1_rx_regs[] = {
    @@ -1500,7 +1500,7 @@ struct reg_info pm1_rx_regs[] = {
     		{ "ocspi1_ofifo2x_Tx_framing_error", 6, 1 },
     		{ "iespi_par_error", 3, 3 },
     		{ "ocspi_par_error", 0, 3 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info pm1_tx_regs[] = {
    @@ -1544,7 +1544,7 @@ struct reg_info pm1_tx_regs[] = {
     		{ "oespi1_ofifo2x_Tx_framing_error", 6, 1 },
     		{ "icspi_par_error", 3, 3 },
     		{ "oespi_par_error", 0, 3 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info mps0_regs[] = {
    @@ -1585,7 +1585,7 @@ struct reg_info mps0_regs[] = {
     		{ "RXTpParErr", 4, 2 },
     		{ "TX1TpParErr", 2, 2 },
     		{ "TX0TpParErr", 0, 2 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info cpl_switch_regs[] = {
    @@ -1616,7 +1616,7 @@ struct reg_info cpl_switch_regs[] = {
     		{ "cpl_map_tbl_idx", 0, 8 },
     	{ "CPL_MAP_TBL_DATA", 0x65c, 0 },
     		{ "cpl_map_tbl_data", 0, 8 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info smb0_regs[] = {
    @@ -1682,7 +1682,7 @@ struct reg_info smb0_regs[] = {
     		{ "DebugDataL", 0, 16 },
     	{ "SMB_DEBUG_LA", 0x69c, 0 },
     		{ "DebugLAReqAddr", 0, 10 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info i2cm0_regs[] = {
    @@ -1695,7 +1695,7 @@ struct reg_info i2cm0_regs[] = {
     		{ "Ack", 30, 1 },
     		{ "Cont", 1, 1 },
     		{ "Op", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info mi1_regs[] = {
    @@ -1714,7 +1714,7 @@ struct reg_info mi1_regs[] = {
     		{ "Busy", 31, 1 },
     		{ "Inc", 2, 1 },
     		{ "Op", 0, 2 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info jm1_regs[] = {
    @@ -1727,7 +1727,7 @@ struct reg_info jm1_regs[] = {
     	{ "JM_OP", 0x6cc, 0 },
     		{ "Busy", 31, 1 },
     		{ "Cnt", 0, 5 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info sf1_regs[] = {
    @@ -1737,7 +1737,7 @@ struct reg_info sf1_regs[] = {
     		{ "Cont", 3, 1 },
     		{ "ByteCnt", 1, 2 },
     		{ "Op", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info pl3_regs[] = {
    @@ -1839,7 +1839,7 @@ struct reg_info pl3_regs[] = {
     	{ "PL_REV", 0x6f4, 0 },
     		{ "Rev", 0, 4 },
     	{ "PL_CLI", 0x6f8, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info mc5a_regs[] = {
    @@ -2010,7 +2010,7 @@ struct reg_info mc5a_regs[] = {
     		{ "ReadCmd", 0, 20 },
     	{ "MC5_DB_MASK_WRITE_CMD", 0x7fc, 0 },
     		{ "MaskWr", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info xgmac0_0_regs[] = {
    @@ -2341,7 +2341,7 @@ struct reg_info xgmac0_0_regs[] = {
     	{ "XGM_RX_SPI4_SOP_EOP_CNT", 0x9ac, 0 },
     		{ "RxSPI4SopCnt", 16, 16 },
     		{ "RxSPI4EopCnt", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info xgmac0_1_regs[] = {
    @@ -2672,5 +2672,5 @@ struct reg_info xgmac0_1_regs[] = {
     	{ "XGM_RX_SPI4_SOP_EOP_CNT", 0xbac, 0 },
     		{ "RxSPI4SopCnt", 16, 16 },
     		{ "RxSPI4EopCnt", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
    diff --git a/usr.sbin/cxgbtool/reg_defs_t3b.c b/usr.sbin/cxgbtool/reg_defs_t3b.c
    index 539742ce3c9..cd85d840a1d 100644
    --- a/usr.sbin/cxgbtool/reg_defs_t3b.c
    +++ b/usr.sbin/cxgbtool/reg_defs_t3b.c
    @@ -150,7 +150,7 @@ struct reg_info t3b_sge3_regs[] = {
     		{ "DrbPriThrsh", 0, 16 },
     	{ "SG_DEBUG_INDEX", 0x78, 0 },
     	{ "SG_DEBUG_DATA", 0x7c, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_pcix1_regs[] = {
    @@ -222,7 +222,7 @@ struct reg_info t3b_pcix1_regs[] = {
     		{ "WakeUp0", 2, 1 },
     		{ "SleepMode1", 1, 1 },
     		{ "SleepMode0", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_pcie0_regs[] = {
    @@ -376,7 +376,7 @@ struct reg_info t3b_pcie0_regs[] = {
     		{ "BeaconDetect", 2, 1 },
     		{ "RxDetect", 1, 1 },
     		{ "TxIdleDetect", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_t3dbg_regs[] = {
    @@ -557,7 +557,7 @@ struct reg_info t3b_t3dbg_regs[] = {
     		{ "BSEnLane1", 4, 1 },
     		{ "BSInSelLane0", 1, 2 },
     		{ "BSEnLane0", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_mc7_pmrx_regs[] = {
    @@ -678,7 +678,7 @@ struct reg_info t3b_mc7_pmrx_regs[] = {
     		{ "PE", 2, 15 },
     		{ "UE", 1, 1 },
     		{ "CE", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_mc7_pmtx_regs[] = {
    @@ -799,7 +799,7 @@ struct reg_info t3b_mc7_pmtx_regs[] = {
     		{ "PE", 2, 15 },
     		{ "UE", 1, 1 },
     		{ "CE", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_mc7_cm_regs[] = {
    @@ -920,7 +920,7 @@ struct reg_info t3b_mc7_cm_regs[] = {
     		{ "PE", 2, 15 },
     		{ "UE", 1, 1 },
     		{ "CE", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_cim_regs[] = {
    @@ -1047,7 +1047,7 @@ struct reg_info t3b_cim_regs[] = {
     		{ "PILADbgWrPtr", 0, 9 },
     	{ "CIM_PO_LA_DEBUGDATA", 0x2e8, 0 },
     	{ "CIM_PI_LA_DEBUGDATA", 0x2ec, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_tp1_regs[] = {
    @@ -1453,7 +1453,7 @@ struct reg_info t3b_tp1_regs[] = {
     	{ "TP_EMBED_OP_FIELD3", 0x4f4, 0 },
     	{ "TP_EMBED_OP_FIELD4", 0x4f8, 0 },
     	{ "TP_EMBED_OP_FIELD5", 0x4fc, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_ulp2_rx_regs[] = {
    @@ -1497,7 +1497,7 @@ struct reg_info t3b_ulp2_rx_regs[] = {
     	{ "ULPRX_RQ_ULIMIT", 0x538, 0 },
     	{ "ULPRX_PBL_LLIMIT", 0x53c, 0 },
     	{ "ULPRX_PBL_ULIMIT", 0x540, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_ulp2_tx_regs[] = {
    @@ -1525,7 +1525,7 @@ struct reg_info t3b_ulp2_tx_regs[] = {
     	{ "ULPTX_DMA_WEIGHT", 0x5ac, 0 },
     		{ "D1_WEIGHT", 16, 16 },
     		{ "D0_WEIGHT", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_pm1_rx_regs[] = {
    @@ -1569,7 +1569,7 @@ struct reg_info t3b_pm1_rx_regs[] = {
     		{ "ocspi1_ofifo2x_Tx_framing_error", 6, 1 },
     		{ "iespi_par_error", 3, 3 },
     		{ "ocspi_par_error", 0, 3 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_pm1_tx_regs[] = {
    @@ -1613,7 +1613,7 @@ struct reg_info t3b_pm1_tx_regs[] = {
     		{ "oespi1_ofifo2x_Tx_framing_error", 6, 1 },
     		{ "icspi_par_error", 3, 3 },
     		{ "oespi_par_error", 0, 3 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_mps0_regs[] = {
    @@ -1655,7 +1655,7 @@ struct reg_info t3b_mps0_regs[] = {
     		{ "RXTpParErr", 4, 2 },
     		{ "TX1TpParErr", 2, 2 },
     		{ "TX0TpParErr", 0, 2 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_cpl_switch_regs[] = {
    @@ -1686,7 +1686,7 @@ struct reg_info t3b_cpl_switch_regs[] = {
     		{ "cpl_map_tbl_idx", 0, 8 },
     	{ "CPL_MAP_TBL_DATA", 0x65c, 0 },
     		{ "cpl_map_tbl_data", 0, 8 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_smb0_regs[] = {
    @@ -1752,7 +1752,7 @@ struct reg_info t3b_smb0_regs[] = {
     		{ "DebugDataL", 0, 16 },
     	{ "SMB_DEBUG_LA", 0x69c, 0 },
     		{ "DebugLAReqAddr", 0, 10 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_i2cm0_regs[] = {
    @@ -1765,7 +1765,7 @@ struct reg_info t3b_i2cm0_regs[] = {
     		{ "Ack", 30, 1 },
     		{ "Cont", 1, 1 },
     		{ "Op", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_mi1_regs[] = {
    @@ -1784,7 +1784,7 @@ struct reg_info t3b_mi1_regs[] = {
     		{ "Busy", 31, 1 },
     		{ "Inc", 2, 1 },
     		{ "Op", 0, 2 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_jm1_regs[] = {
    @@ -1797,7 +1797,7 @@ struct reg_info t3b_jm1_regs[] = {
     	{ "JM_OP", 0x6cc, 0 },
     		{ "Busy", 31, 1 },
     		{ "Cnt", 0, 5 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_sf1_regs[] = {
    @@ -1807,7 +1807,7 @@ struct reg_info t3b_sf1_regs[] = {
     		{ "Cont", 3, 1 },
     		{ "ByteCnt", 1, 2 },
     		{ "Op", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_pl3_regs[] = {
    @@ -1917,7 +1917,7 @@ struct reg_info t3b_pl3_regs[] = {
     	{ "PL_CLI", 0x6f8, 0 },
     	{ "PL_LCK", 0x6fc, 0 },
     		{ "Lck", 0, 2 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_mc5a_regs[] = {
    @@ -2100,7 +2100,7 @@ struct reg_info t3b_mc5a_regs[] = {
     		{ "ReadCmd", 0, 20 },
     	{ "MC5_DB_MASK_WRITE_CMD", 0x7fc, 0 },
     		{ "MaskWr", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_xgmac0_0_regs[] = {
    @@ -2464,7 +2464,7 @@ struct reg_info t3b_xgmac0_0_regs[] = {
     	{ "XGM_RX_SPI4_SOP_EOP_CNT", 0x9ac, 0 },
     		{ "RxSPI4SopCnt", 16, 16 },
     		{ "RxSPI4EopCnt", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3b_xgmac0_1_regs[] = {
    @@ -2828,5 +2828,5 @@ struct reg_info t3b_xgmac0_1_regs[] = {
     	{ "XGM_RX_SPI4_SOP_EOP_CNT", 0xbac, 0 },
     		{ "RxSPI4SopCnt", 16, 16 },
     		{ "RxSPI4EopCnt", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
    diff --git a/usr.sbin/cxgbtool/reg_defs_t3c.c b/usr.sbin/cxgbtool/reg_defs_t3c.c
    index 6127fa4ce86..b9181b68e9a 100644
    --- a/usr.sbin/cxgbtool/reg_defs_t3c.c
    +++ b/usr.sbin/cxgbtool/reg_defs_t3c.c
    @@ -177,7 +177,7 @@ struct reg_info t3c_sge3_regs[] = {
     		{ "DrbPriThrsh", 0, 16 },
     	{ "SG_DEBUG_INDEX", 0x78, 0 },
     	{ "SG_DEBUG_DATA", 0x7c, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_pcix1_regs[] = {
    @@ -282,7 +282,7 @@ struct reg_info t3c_pcix1_regs[] = {
     		{ "IntSt", 4, 3 },
     		{ "PIOSt", 2, 2 },
     		{ "RFReqRdSt", 0, 2 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_pcie0_regs[] = {
    @@ -475,7 +475,7 @@ struct reg_info t3c_pcie0_regs[] = {
     		{ "P_WMark", 18, 11 },
     		{ "NP_WMark", 11, 7 },
     		{ "CPL_WMark", 0, 11 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_t3dbg_regs[] = {
    @@ -656,7 +656,7 @@ struct reg_info t3c_t3dbg_regs[] = {
     		{ "BSEnLane1", 4, 1 },
     		{ "BSInSelLane0", 1, 2 },
     		{ "BSEnLane0", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_mc7_pmrx_regs[] = {
    @@ -777,7 +777,7 @@ struct reg_info t3c_mc7_pmrx_regs[] = {
     		{ "PE", 2, 15 },
     		{ "UE", 1, 1 },
     		{ "CE", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_mc7_pmtx_regs[] = {
    @@ -898,7 +898,7 @@ struct reg_info t3c_mc7_pmtx_regs[] = {
     		{ "PE", 2, 15 },
     		{ "UE", 1, 1 },
     		{ "CE", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_mc7_cm_regs[] = {
    @@ -1019,7 +1019,7 @@ struct reg_info t3c_mc7_cm_regs[] = {
     		{ "PE", 2, 15 },
     		{ "UE", 1, 1 },
     		{ "CE", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_cim_regs[] = {
    @@ -1194,7 +1194,7 @@ struct reg_info t3c_cim_regs[] = {
     		{ "PILADbgWrPtr", 0, 9 },
     	{ "CIM_PO_LA_DEBUGDATA", 0x2e8, 0 },
     	{ "CIM_PI_LA_DEBUGDATA", 0x2ec, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_tp1_regs[] = {
    @@ -1667,7 +1667,7 @@ struct reg_info t3c_tp1_regs[] = {
     	{ "TP_EMBED_OP_FIELD3", 0x4f4, 0 },
     	{ "TP_EMBED_OP_FIELD4", 0x4f8, 0 },
     	{ "TP_EMBED_OP_FIELD5", 0x4fc, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_ulp2_rx_regs[] = {
    @@ -1725,7 +1725,7 @@ struct reg_info t3c_ulp2_rx_regs[] = {
     	{ "ULPRX_RQ_ULIMIT", 0x538, 0 },
     	{ "ULPRX_PBL_LLIMIT", 0x53c, 0 },
     	{ "ULPRX_PBL_ULIMIT", 0x540, 0 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_ulp2_tx_regs[] = {
    @@ -1766,7 +1766,7 @@ struct reg_info t3c_ulp2_tx_regs[] = {
     	{ "ULPTX_DMA_WEIGHT", 0x5ac, 0 },
     		{ "D1_WEIGHT", 16, 16 },
     		{ "D0_WEIGHT", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_pm1_rx_regs[] = {
    @@ -1810,7 +1810,7 @@ struct reg_info t3c_pm1_rx_regs[] = {
     		{ "ocspi1_ofifo2x_Tx_framing_error", 6, 1 },
     		{ "iespi_par_error", 3, 3 },
     		{ "ocspi_par_error", 0, 3 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_pm1_tx_regs[] = {
    @@ -1854,7 +1854,7 @@ struct reg_info t3c_pm1_tx_regs[] = {
     		{ "oespi1_ofifo2x_Tx_framing_error", 6, 1 },
     		{ "icspi_par_error", 3, 3 },
     		{ "oespi_par_error", 0, 3 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_mps0_regs[] = {
    @@ -1896,7 +1896,7 @@ struct reg_info t3c_mps0_regs[] = {
     		{ "RXTpParErr", 4, 2 },
     		{ "TX1TpParErr", 2, 2 },
     		{ "TX0TpParErr", 0, 2 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_cpl_switch_regs[] = {
    @@ -1930,7 +1930,7 @@ struct reg_info t3c_cpl_switch_regs[] = {
     		{ "cpl_map_tbl_idx", 0, 8 },
     	{ "CPL_MAP_TBL_DATA", 0x65c, 0 },
     		{ "cpl_map_tbl_data", 0, 8 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_smb0_regs[] = {
    @@ -1996,7 +1996,7 @@ struct reg_info t3c_smb0_regs[] = {
     		{ "DebugDataL", 0, 16 },
     	{ "SMB_DEBUG_LA", 0x69c, 0 },
     		{ "DebugLAReqAddr", 0, 10 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_i2cm0_regs[] = {
    @@ -2009,7 +2009,7 @@ struct reg_info t3c_i2cm0_regs[] = {
     		{ "Ack", 30, 1 },
     		{ "Cont", 1, 1 },
     		{ "Op", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_mi1_regs[] = {
    @@ -2028,7 +2028,7 @@ struct reg_info t3c_mi1_regs[] = {
     		{ "Busy", 31, 1 },
     		{ "Inc", 2, 1 },
     		{ "Op", 0, 2 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_jm1_regs[] = {
    @@ -2041,7 +2041,7 @@ struct reg_info t3c_jm1_regs[] = {
     	{ "JM_OP", 0x6cc, 0 },
     		{ "Busy", 31, 1 },
     		{ "Cnt", 0, 5 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_sf1_regs[] = {
    @@ -2051,7 +2051,7 @@ struct reg_info t3c_sf1_regs[] = {
     		{ "Cont", 3, 1 },
     		{ "ByteCnt", 1, 2 },
     		{ "Op", 0, 1 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_pl3_regs[] = {
    @@ -2162,7 +2162,7 @@ struct reg_info t3c_pl3_regs[] = {
     	{ "PL_CLI", 0x6f8, 0 },
     	{ "PL_LCK", 0x6fc, 0 },
     		{ "Lck", 0, 2 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_mc5a_regs[] = {
    @@ -2346,7 +2346,7 @@ struct reg_info t3c_mc5a_regs[] = {
     		{ "ReadCmd", 0, 20 },
     	{ "MC5_DB_MASK_WRITE_CMD", 0x7fc, 0 },
     		{ "MaskWr", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_xgmac0_0_regs[] = {
    @@ -2730,7 +2730,7 @@ struct reg_info t3c_xgmac0_0_regs[] = {
     	{ "XGM_RX_SPI4_SOP_EOP_CNT", 0x9ac, 0 },
     		{ "RxSPI4SopCnt", 16, 16 },
     		{ "RxSPI4EopCnt", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
     struct reg_info t3c_xgmac0_1_regs[] = {
    @@ -3114,6 +3114,6 @@ struct reg_info t3c_xgmac0_1_regs[] = {
     	{ "XGM_RX_SPI4_SOP_EOP_CNT", 0xbac, 0 },
     		{ "RxSPI4SopCnt", 16, 16 },
     		{ "RxSPI4EopCnt", 0, 16 },
    -	{ NULL }
    +	{ NULL, 0, 0 }
     };
     
    
    From f4516d699b399f671d2f0dafe45be5025f7562aa Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Tue, 6 Apr 2010 00:46:49 +0000
    Subject: [PATCH 1840/2592] MFC r205520:
    
    Correct cross reference.
    ---
     share/man/man3/pthread_affinity_np.3 | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/share/man/man3/pthread_affinity_np.3 b/share/man/man3/pthread_affinity_np.3
    index a04ba97b483..95128c8ebd5 100644
    --- a/share/man/man3/pthread_affinity_np.3
    +++ b/share/man/man3/pthread_affinity_np.3
    @@ -25,7 +25,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd January 12, 2010
    +.Dd March 23, 2010
     .Dt PTHREAD_AFFINITY_NP 3
     .Os
     .Sh NAME
    @@ -125,8 +125,8 @@ operation.
     .Xr cpuset_setid 2 ,
     .Xr CPU_SET 3 ,
     .Xr pthread 3 ,
    -.Xr pthread_attr_get_affinity_np 3 ,
    -.Xr pthread_attr_set_affinity_np 3
    +.Xr pthread_attr_getaffinity_np 3 ,
    +.Xr pthread_attr_setaffinity_np 3
     .Sh STANDARDS
     The
     .Nm pthread_getaffinity_np
    
    From f33c89d1ae0d0fad96f5a896fa403bd2acf2ba00 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Tue, 6 Apr 2010 00:50:23 +0000
    Subject: [PATCH 1841/2592] MFC r205534:
    
    Add PCI ID for MCS9901's parallel port.
    
    PR:		kern/144713
    Submitted by:	gcooper
    ---
     sys/dev/ppc/ppc_pci.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/dev/ppc/ppc_pci.c b/sys/dev/ppc/ppc_pci.c
    index c8e40b56377..ed59413ee9c 100644
    --- a/sys/dev/ppc/ppc_pci.c
    +++ b/sys/dev/ppc/ppc_pci.c
    @@ -89,6 +89,7 @@ static struct pci_id pci_ids[] = {
     	{ 0x84031415, "Oxford Semiconductor OX12PCI840 Parallel port", 0x10 },
     	{ 0x95131415, "Oxford Semiconductor OX16PCI954 Parallel port", 0x10 },
     	{ 0x98059710, "NetMos NM9805 1284 Printer port", 0x10 },
    +	{ 0x99019710, "MosChip MCS9901 PCIe to Peripheral Controller", 0x10 },
     	{ 0xffff }
     };
     
    
    From e2aa0109fb2066b50f31eb4e0394a8cf07a93414 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Tue, 6 Apr 2010 10:32:26 +0000
    Subject: [PATCH 1842/2592] MFC r201210:
    
    Remove pppd, it's gone.
    ---
     secure/Makefile | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/secure/Makefile b/secure/Makefile
    index 7a78d947c55..7342709e1f7 100644
    --- a/secure/Makefile
    +++ b/secure/Makefile
    @@ -7,8 +7,7 @@ SUBDIR= lib libexec usr.bin usr.sbin
     # These are the programs which depend on crypto, but not Kerberos.
     SPROGS=	lib/libfetch lib/libpam lib/libradius lib/libtelnet	\
     	bin/ed libexec/telnetd usr.bin/fetch usr.bin/telnet	\
    -	usr.sbin/pkg_install usr.sbin/ppp usr.sbin/pppd		\
    -	usr.sbin/tcpdump/tcpdump
    +	usr.sbin/pkg_install usr.sbin/ppp usr.sbin/tcpdump/tcpdump
     .if ${MK_SENDMAIL} != "no"
     SPROGS+=usr.sbin/sendmail
     .endif
    
    From 24b82d83bc925592ea91575af571bde71e65dec8 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Tue, 6 Apr 2010 10:34:15 +0000
    Subject: [PATCH 1843/2592] MFC r201211:
    
    Remove pppd and SLIP-related stuff.
    ---
     usr.sbin/crunch/examples/really-big.conf | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/usr.sbin/crunch/examples/really-big.conf b/usr.sbin/crunch/examples/really-big.conf
    index 45a10de0cf4..bc692c68f82 100644
    --- a/usr.sbin/crunch/examples/really-big.conf
    +++ b/usr.sbin/crunch/examples/really-big.conf
    @@ -27,7 +27,7 @@ progs badsect bim clri disklabel dmesg dump dumpfs fdisk fsck halt
     progs ifconfig init mknod modload modunload mount mount_isofs
     progs mount_lofs mount_msdosfs mount_portalfs mountd
     progs newfs nfsd nfsiod ping quotacheck reboot restore route routed savecore
    -progs shutdown slattach swapon ttyflags tunefs umount
    +progs shutdown  swapon ttyflags tunefs umount
     # shell scripts: fastboot
     
     ln dump rdump
    @@ -71,7 +71,7 @@ progs ac accton amd arp bad144 catman chown chroot config config.new cron
     progs dev_mkdb diskpart edquota flcopy gettable grfinfo hilinfo htable inetd
     progs iostat iteconfig kvm_mkdb mtree named portmap pppd
     progs pstat pwd_mkdb quot quotaon rarpd rbootd repquota rmt rpc.bootparamd
    -progs rwhod sa sliplogin slstats spray sysctl syslogd tcpdump
    +progs rwhod sa spray sysctl syslogd tcpdump
     progs traceroute trpt trsp update vipw vnconfig ypbind yppoll ypset
     
     special amd srcdir /usr/src/usr.sbin/amd/amd
    
    From 807645566baf8578cb95d3c57aece94e898fa5e5 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Tue, 6 Apr 2010 10:58:40 +0000
    Subject: [PATCH 1844/2592] MFC r201213:
    
    Remove examples for pppd and SLIP-related stuff.
    
    PR:		conf/144950
    ---
     ObsoleteFiles.inc                       | 23 +++++++++++++++++
     etc/mtree/BSD.usr.dist                  |  8 ------
     share/examples/Makefile                 | 22 -----------------
     share/examples/pppd/auth-down.sample    |  7 ------
     share/examples/pppd/auth-up.sample      |  7 ------
     share/examples/pppd/chap-secrets.sample | 17 -------------
     share/examples/pppd/chat.sh.sample      | 33 -------------------------
     share/examples/pppd/ip-down.sample      |  7 ------
     share/examples/pppd/ip-up.sample        |  8 ------
     share/examples/pppd/options.sample      | 16 ------------
     share/examples/pppd/pap-secrets.sample  | 17 -------------
     share/examples/pppd/ppp.deny.sample     | 27 --------------------
     share/examples/pppd/ppp.shells.sample   | 14 -----------
     share/examples/slattach/unit-command.sh | 18 --------------
     share/examples/sliplogin/slip.hosts     | 16 ------------
     share/examples/sliplogin/slip.login     | 18 --------------
     share/examples/sliplogin/slip.logout    | 14 -----------
     share/examples/sliplogin/slip.slparms   | 12 ---------
     share/examples/startslip/sldown.sh      |  3 ---
     share/examples/startslip/slip.sh        |  5 ----
     share/examples/startslip/slup.sh        | 16 ------------
     21 files changed, 23 insertions(+), 285 deletions(-)
     delete mode 100644 share/examples/pppd/auth-down.sample
     delete mode 100644 share/examples/pppd/auth-up.sample
     delete mode 100644 share/examples/pppd/chap-secrets.sample
     delete mode 100644 share/examples/pppd/chat.sh.sample
     delete mode 100644 share/examples/pppd/ip-down.sample
     delete mode 100644 share/examples/pppd/ip-up.sample
     delete mode 100644 share/examples/pppd/options.sample
     delete mode 100644 share/examples/pppd/pap-secrets.sample
     delete mode 100644 share/examples/pppd/ppp.deny.sample
     delete mode 100644 share/examples/pppd/ppp.shells.sample
     delete mode 100755 share/examples/slattach/unit-command.sh
     delete mode 100644 share/examples/sliplogin/slip.hosts
     delete mode 100644 share/examples/sliplogin/slip.login
     delete mode 100644 share/examples/sliplogin/slip.logout
     delete mode 100644 share/examples/sliplogin/slip.slparms
     delete mode 100755 share/examples/startslip/sldown.sh
     delete mode 100755 share/examples/startslip/slip.sh
     delete mode 100755 share/examples/startslip/slup.sh
    
    diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
    index faeee6bcc10..4e6d408ca60 100644
    --- a/ObsoleteFiles.inc
    +++ b/ObsoleteFiles.inc
    @@ -27,6 +27,29 @@ OLD_FILES+=usr/share/man/man1/gcpio.1.gz
     # 20100301: 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
    +# 20091229: remove no longer relevant examples
    +OLD_FILES+=usr/share/examples/pppd/auth-down.sample
    +OLD_FILES+=usr/share/examples/pppd/auth-up.sample
    +OLD_FILES+=usr/share/examples/pppd/chap-secrets.sample
    +OLD_FILES+=usr/share/examples/pppd/chat.sh.sample
    +OLD_FILES+=usr/share/examples/pppd/ip-down.sample
    +OLD_FILES+=usr/share/examples/pppd/ip-up.sample
    +OLD_FILES+=usr/share/examples/pppd/options.sample
    +OLD_FILES+=usr/share/examples/pppd/pap-secrets.sample
    +OLD_FILES+=usr/share/examples/pppd/ppp.deny.sample
    +OLD_FILES+=usr/share/examples/pppd/ppp.shells.sample
    +OLD_DIRS+=usr/share/examples/pppd
    +OLD_FILES+=usr/share/examples/slattach/unit-command.sh
    +OLD_DIRS+=usr/share/examples/slattach
    +OLD_FILES+=usr/share/examples/sliplogin/slip.hosts
    +OLD_FILES+=usr/share/examples/sliplogin/slip.login
    +OLD_FILES+=usr/share/examples/sliplogin/slip.logout
    +OLD_FILES+=usr/share/examples/sliplogin/slip.slparms
    +OLD_DIRS+=usr/share/examples/sliplogin
    +OLD_FILES+=usr/share/examples/startslip/sldown.sh
    +OLD_FILES+=usr/share/examples/startslip/slip.sh
    +OLD_FILES+=usr/share/examples/startslip/slup.sh
    +OLD_DIRS+=usr/share/examples/startslip
     # 20091218: removal of rc.early(8) link
     OLD_FILES+=usr/share/man/man8/rc.early.8.gz
     # 20091027: pselect.3 implemented as syscall
    diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist
    index 44a9aad5ab6..e2032b1e17b 100644
    --- a/etc/mtree/BSD.usr.dist
    +++ b/etc/mtree/BSD.usr.dist
    @@ -265,8 +265,6 @@
                 ..
                 ppp
                 ..
    -            pppd
    -            ..
                 printing
                 ..
                 scsi_target
    @@ -283,16 +281,10 @@
                     srcs
                     ..
                 ..
    -            slattach
    -            ..
    -            sliplogin
    -            ..
                 smbfs
                     print
                     ..
                 ..
    -            startslip
    -            ..
                 sunrpc
                     dir
                     ..
    diff --git a/share/examples/Makefile b/share/examples/Makefile
    index 3d28511ff2f..315eb913519 100644
    --- a/share/examples/Makefile
    +++ b/share/examples/Makefile
    @@ -24,13 +24,9 @@ LDIRS=	BSD_daemon \
     	portal \
     	ppi \
     	ppp \
    -	pppd \
     	printing \
     	ses \
     	scsi_target \
    -	slattach \
    -	sliplogin \
    -	startslip \
     	sunrpc
     
     XFILES=	BSD_daemon/FreeBSD.pfa \
    @@ -135,16 +131,6 @@ XFILES=	BSD_daemon/FreeBSD.pfa \
     	ppp/ppp.secret.sample \
     	ppp/ppp.secret.span-isp \
     	ppp/ppp.secret.span-isp.working \
    -	pppd/auth-down.sample \
    -	pppd/auth-up.sample \
    -	pppd/chap-secrets.sample \
    -	pppd/chat.sh.sample \
    -	pppd/ip-down.sample \
    -	pppd/ip-up.sample \
    -	pppd/options.sample \
    -	pppd/pap-secrets.sample \
    -	pppd/ppp.deny.sample \
    -	pppd/ppp.shells.sample \
     	printing/README \
     	printing/diablo-if-net \
     	printing/hpdf \
    @@ -187,14 +173,6 @@ XFILES=	BSD_daemon/FreeBSD.pfa \
     	scsi_target/scsi_target.h \
     	scsi_target/scsi_target.8 \
     	scsi_target/scsi_cmds.c \
    -	slattach/unit-command.sh \
    -	sliplogin/slip.hosts \
    -	sliplogin/slip.login \
    -	sliplogin/slip.logout \
    -	sliplogin/slip.slparms \
    -	startslip/sldown.sh \
    -	startslip/slip.sh \
    -	startslip/slup.sh \
     	sunrpc/Makefile \
     	sunrpc/dir/Makefile \
     	sunrpc/dir/dir.x \
    diff --git a/share/examples/pppd/auth-down.sample b/share/examples/pppd/auth-down.sample
    deleted file mode 100644
    index b2da150dc04..00000000000
    --- a/share/examples/pppd/auth-down.sample
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -#!/bin/sh
    -#
    -# $FreeBSD$
    -#
    -# Example for /etc/ppp/auth-down file.
    -
    -/usr/bin/logger -p daemon.notice -t pppd "User $2 is logged off"
    diff --git a/share/examples/pppd/auth-up.sample b/share/examples/pppd/auth-up.sample
    deleted file mode 100644
    index 3d9c07e8034..00000000000
    --- a/share/examples/pppd/auth-up.sample
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -#!/bin/sh
    -#
    -# $FreeBSD$
    -#
    -# Example for /etc/ppp/auth-up file.
    -
    -/usr/bin/logger -p daemon.notice -t pppd "User $2 is logged in"
    diff --git a/share/examples/pppd/chap-secrets.sample b/share/examples/pppd/chap-secrets.sample
    deleted file mode 100644
    index 40d5dfdc86e..00000000000
    --- a/share/examples/pppd/chap-secrets.sample
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -# $FreeBSD$
    -#
    -# Example for /etc/ppp/chap-secrets file.
    -#
    -# This file should be owned by root and not readable or
    -# writable by any other user.
    -#
    -# Dialin format:    
    -#
    -joe	server	password	192.168.0.0/24 192.168.2.2
    -lisa	server	l1z4		* !192.168.0.1
    -mike	server	secret		*
    -luser	server	nopass		-
    -#
    -# Dialout format:   
    -#
    -jane	isp	password
    diff --git a/share/examples/pppd/chat.sh.sample b/share/examples/pppd/chat.sh.sample
    deleted file mode 100644
    index 6418ebfdf6a..00000000000
    --- a/share/examples/pppd/chat.sh.sample
    +++ /dev/null
    @@ -1,33 +0,0 @@
    -#!/bin/sh
    -#
    -# $FreeBSD$
    -#
    -# Example for chat.sh file.
    -
    -INIT='at&f'
    -
    -dial(){
    -	/usr/bin/chat -v		\
    -		ABORT	"ERROR"		\
    -		ABORT	"NO DIALTONE"	\
    -		TIMEOUT	5		\
    -		""	"AT"		\
    -		"OK"	"${INIT}"	\
    -		"OK"-"+++"-""	"ATH"	\
    -		ABORT	"BUSY"		\
    -		ABORT	"NO ANSWER"	\
    -		ABORT	"NO CARRIER"	\
    -		"OK"	"ATDP$1"	\
    -		TIMEOUT	70		\
    -		"ogin:"	"username"	\
    -		"word:"	"pasword"	\
    -		TIMEOUT	50		\
    -		"PPP"	"\c"
    -
    -	[ $? -eq 0 ] && exit 0
    -
    -	echo "$1 failed" 1>&2
    -	exit 1
    -}
    -
    -dial 1234567
    diff --git a/share/examples/pppd/ip-down.sample b/share/examples/pppd/ip-down.sample
    deleted file mode 100644
    index 45b8eb45675..00000000000
    --- a/share/examples/pppd/ip-down.sample
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -#!/bin/sh
    -#
    -# $FreeBSD$
    -#
    -# Example for /etc/ppp/ip-down file.
    -
    -/usr/bin/logger -p daemon.notice -t pppd "$1 is down"
    diff --git a/share/examples/pppd/ip-up.sample b/share/examples/pppd/ip-up.sample
    deleted file mode 100644
    index a0fc1b02aaa..00000000000
    --- a/share/examples/pppd/ip-up.sample
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -#!/bin/sh
    -#
    -# $FreeBSD$
    -#
    -# Example for /etc/ppp/ip-up file.
    -
    -/usr/bin/logger -p daemon.notice -t pppd "$1 is up"
    -/usr/sbin/ntpdate ntpserver
    diff --git a/share/examples/pppd/options.sample b/share/examples/pppd/options.sample
    deleted file mode 100644
    index fd0a927c57c..00000000000
    --- a/share/examples/pppd/options.sample
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -# $FreeBSD$
    -#
    -# Example for /etc/ppp/options file.
    -#
    -/dev/cuad4
    -115200
    -modem
    -crtscts
    -asyncmap 0
    -connect '/etc/ppp/chat.sh'
    -defaultroute
    -noipdefault
    -persist
    -holdoff 5
    -mtu 250
    -mru 250
    diff --git a/share/examples/pppd/pap-secrets.sample b/share/examples/pppd/pap-secrets.sample
    deleted file mode 100644
    index 8896bdd7a65..00000000000
    --- a/share/examples/pppd/pap-secrets.sample
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -# $FreeBSD$
    -#
    -# Example for /etc/ppp/pap-secrets file.
    -#
    -# This file should be owned by root and not readable or
    -# writable by any other user.
    -#
    -# Dialin format:    
    -#
    -joe	server	password	192.168.0.1/24 192.168.2.2
    -lisa	server	l1z4		* !192.168.0.1
    -mike	server	secret		*
    -luser	server	nopass		-
    -#
    -# Dialout format:    
    -#
    -jane	isp	password
    diff --git a/share/examples/pppd/ppp.deny.sample b/share/examples/pppd/ppp.deny.sample
    deleted file mode 100644
    index 948e11527cd..00000000000
    --- a/share/examples/pppd/ppp.deny.sample
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -# $FreeBSD$
    -#
    -# list of users disallowed any pppd access via 'system
    -# password login'.
    -# read by pppd(8).
    -root
    -toor
    -daemon
    -operator
    -bin
    -tty
    -kmem
    -games
    -news
    -man
    -sshd
    -smmsp
    -mailnull
    -bind
    -proxy
    -_pflogd
    -_dhcp
    -ftp
    -uucp
    -pop
    -www
    -nobody
    diff --git a/share/examples/pppd/ppp.shells.sample b/share/examples/pppd/ppp.shells.sample
    deleted file mode 100644
    index 93b68406c21..00000000000
    --- a/share/examples/pppd/ppp.shells.sample
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -# $FreeBSD$
    -#
    -# List of acceptable shells for pppd(8).
    -# Pppd will not accept a system password login
    -# by a user whose shell is not listed below.
    -
    -/bin/sh
    -/bin/csh
    -/bin/tcsh
    -/usr/local/bin/ksh
    -/usr/local/bin/zsh
    -/usr/local/bin/bash
    -/usr/local/bin/tcsh
    -/usr/local/bin/ppplogin.sh
    diff --git a/share/examples/slattach/unit-command.sh b/share/examples/slattach/unit-command.sh
    deleted file mode 100755
    index 9e97ffdcd69..00000000000
    --- a/share/examples/slattach/unit-command.sh
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -#!/bin/sh
    -
    -old_unit=$1
    -new_unit=$2
    -
    -if [ $old_unit != -1 ]; then
    -	ifconfig sl$old_unit delete down
    -	if [ $new_unit == -1 ]; then
    -		route delete default
    -	fi
    -fi
    -
    -if [ $new_unit != -1 ]; then
    -	ifconfig sl$new_unit  
    -	if [ $old_unit == -1 ]; then
    -		route add default 
    -	fi
    -fi
    diff --git a/share/examples/sliplogin/slip.hosts b/share/examples/sliplogin/slip.hosts
    deleted file mode 100644
    index b20d7c8b416..00000000000
    --- a/share/examples/sliplogin/slip.hosts
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -#	@(#)slip.hosts	8.1 (Berkeley) 6/6/93
    -#
    -# option(s) consist of the following: (see the sliplogin man page)
    -#   normal - no header compression
    -#   compress - compress headers
    -#   autocomp - compress headers if remote end allows it
    -#   noicmp - disable ICMP packets (such as 'ping' or 'traceroute' packets)
    -# 
    -#login		local-address	remote-address	netmask		option(s)
    -#------		----------	-----------	-------		---------
    -Schez		vangogh		chez		0xffffff00	compress
    -Sjun		vangogh		128.32.130.36	0xffffff00	normal
    -Sleconte	vangogh		leconte		0xffffff00	compress
    -Sleeb		vangogh		leeb		0xffffff00	compress
    -Smjk		vangogh		pissaro-sl	0xffffff00	noicmp
    -Soxford		vangogh		oxford		0xffffff00	autocomp
    diff --git a/share/examples/sliplogin/slip.login b/share/examples/sliplogin/slip.login
    deleted file mode 100644
    index 81102280acb..00000000000
    --- a/share/examples/sliplogin/slip.login
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -#!/bin/sh -
    -#
    -#	@(#)slip.login	8.1 (Berkeley) 6/6/93
    -
    -#
    -# generic login file for a slip line.  sliplogin invokes this with
    -# the parameters:
    -#      1        2         3        4          5         6     7-n
    -#   slipunit ttyspeed loginname local-addr remote-addr mask opt-args
    -#
    -# Delete any arp table entries for this site, just in case
    -/usr/sbin/arp -d $5
    -# Bringup the line
    -/sbin/ifconfig sl$1 inet $4 $5 netmask $6
    -# Answer ARP request for the SLIP client with our Ethernet addr
    -# XXX - Must be filled in with the ethernet address of the local machine
    -# /usr/sbin/arp -s $5 00:00:c0:50:b9:0a pub
    -exit
    diff --git a/share/examples/sliplogin/slip.logout b/share/examples/sliplogin/slip.logout
    deleted file mode 100644
    index b27fe09d099..00000000000
    --- a/share/examples/sliplogin/slip.logout
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -#!/bin/sh -
    -#
    -#       slip.logout
    -
    -#
    -# logout file for a slip line.  sliplogin invokes this with
    -# the parameters:
    -#      1        2         3        4          5         6     7-n
    -#   slipunit ttyspeed loginname local-addr remote-addr mask opt-args
    -#
    -/sbin/ifconfig sl$1 delete
    -# Remove the ARP table entry for the host
    -/usr/sbin/arp -d $5
    -exit
    diff --git a/share/examples/sliplogin/slip.slparms b/share/examples/sliplogin/slip.slparms
    deleted file mode 100644
    index a87c7c3cc7b..00000000000
    --- a/share/examples/sliplogin/slip.slparms
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -#
    -# Additional SLIP configuration (for all login names).
    -# Use slip.slparms. for particular login.
    -#
    -# Format:
    -# keepalive [outfill [slunit]]
    -# (seconds) (seconds) (number)
    -#
    -# Default values:
    -# 0         0         
    -#
    -600     300
    diff --git a/share/examples/startslip/sldown.sh b/share/examples/startslip/sldown.sh
    deleted file mode 100755
    index 1f342a47b0c..00000000000
    --- a/share/examples/startslip/sldown.sh
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -#!/bin/sh
    -/sbin/ifconfig $1 $2
    -/sbin/route delete default
    diff --git a/share/examples/startslip/slip.sh b/share/examples/startslip/slip.sh
    deleted file mode 100755
    index 2b4254e88f6..00000000000
    --- a/share/examples/startslip/slip.sh
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -#!/bin/sh
    -# $FreeBSD$
    -startslip -b 57600 -U ./slup.sh -D ./sldown.sh \
    -	-s atd -s atd -s atd \
    -	-h -t 60 -w 2 -W 20 /dev/cuad1  
    diff --git a/share/examples/startslip/slup.sh b/share/examples/startslip/slup.sh
    deleted file mode 100755
    index 79cded33955..00000000000
    --- a/share/examples/startslip/slup.sh
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -#!/bin/sh
    -myname=
    -gateway=
    -netmask=255.255.255.248
    -tune1="link0 -link2"    # force headers compression
    -tune2="mtu 296"         # for FreeBSD 1.x host
    -
    -case $LINE in
    -	0) tune=$tune1;;        # 1st phone connected
    -	1) tune=$tune2;;        # 2nd phone connected
    -	*) tune=;;              # others
    -esac
    -
    -/sbin/ifconfig $1 $2 $tune
    -/sbin/ifconfig $1 inet $myname $gateway netmask $netmask
    -/sbin/route add default $gateway
    
    From b02c965e31b3402907d265deafb1fe97c2548acd Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Tue, 6 Apr 2010 13:04:27 +0000
    Subject: [PATCH 1845/2592] MFC r205514:  Add a missing LINE_BREAK() after
     printing the roaming parameters in  verbose mode.
    
     Sponsored by:	iXsystems, inc.
    ---
     sbin/ifconfig/ifieee80211.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
    index 48201bd74ef..a0ee24706e3 100644
    --- a/sbin/ifconfig/ifieee80211.c
    +++ b/sbin/ifconfig/ifieee80211.c
    @@ -4516,6 +4516,7 @@ end:
     		} else {
     			LINE_BREAK();
     			list_roam(s);
    +			LINE_BREAK();
     		}
     	}
     
    
    From 8d3cd908c4599860534fcd68adb544ae037e7bb7 Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Tue, 6 Apr 2010 14:07:48 +0000
    Subject: [PATCH 1846/2592] MFC r203422, r205516:
    
     When receiving a management frame, pass the mbuf to bpf before calling
     iv_recv_mgmt(). iv_recv_mgmt() will generate management frame
     responses
     and pass them to bpf before the management frame that triggered the
     response.
    
     PR:		144323
     Submitted by:	Alexander Egorenkov 
     Sponsored by:	iXsystems, inc.
    ---
     sys/net80211/ieee80211_hostap.c | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
    index 240ea7cb30f..1a5eefccc1a 100644
    --- a/sys/net80211/ieee80211_hostap.c
    +++ b/sys/net80211/ieee80211_hostap.c
    @@ -884,6 +884,14 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
     			wh = mtod(m, struct ieee80211_frame *);
     			wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
     		}
    +		/*
    +		 * Pass the packet to radiotap before calling iv_recv_mgmt().
    +		 * Otherwise iv_recv_mgmt() might pass another packet to
    +		 * radiotap, resulting in out of order packet captures.
    +		 */
    +		if (ieee80211_radiotap_active_vap(vap))
    +			ieee80211_radiotap_rx(vap, m);
    +		need_tap = 0;
     		vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
     		goto out;
     
    
    From 775e2b25c373ab0e9aaed721f9e95b6df3050b26 Mon Sep 17 00:00:00 2001
    From: Ken Smith 
    Date: Tue, 6 Apr 2010 17:57:27 +0000
    Subject: [PATCH 1847/2592] Merge r204044:
    
    Provide a script that can be used to create the memstick images.
    ---
     release/scripts/make-memstick.sh | 83 ++++++++++++++++++++++++++++++++
     1 file changed, 83 insertions(+)
     create mode 100755 release/scripts/make-memstick.sh
    
    diff --git a/release/scripts/make-memstick.sh b/release/scripts/make-memstick.sh
    new file mode 100755
    index 00000000000..18f9cf1d8d5
    --- /dev/null
    +++ b/release/scripts/make-memstick.sh
    @@ -0,0 +1,83 @@
    +#!/bin/sh
    +#
    +# This script generates a "memstick image" (image that can be copied to a
    +# USB memory stick) from a directory tree.  Note that the script does not
    +# clean up after itself very well for error conditions on purpose so the
    +# problem can be diagnosed (full filesystem most likely but ...).
    +#
    +# Usage: make-memstick.sh  
    +#
    +# $FreeBSD$
    +#
    +
    +PATH=/bin:/usr/bin:/sbin:/usr/sbin
    +export PATH
    +
    +BLOCKSIZE=10240
    +
    +if [ $# -ne 2 ]; then
    +  echo "make-memstick.sh /path/to/directory /path/to/image/file"
    +  exit 1
    +fi
    +
    +tempfile="${2}.$$"
    +
    +if [ ! -d ${1} ]; then
    +  echo "${1} must be a directory"
    +  exit 1
    +fi
    +
    +if [ -e ${2} ]; then
    +  echo "won't overwrite ${2}"
    +  exit 1
    +fi
    +
    +rm -f ${tempfile}
    +makefs ${tempfile} ${1}
    +if [ $? -ne 0 ]; then
    +  echo "makefs failed"
    +  exit 1
    +fi
    +
    +#
    +# Use $BLOCKSIZE for transfers to improve efficiency.  When calculating
    +# how many blocks to transfer "+ 2" is to account for truncation in the
    +# division and to provide space for the label.
    +#
    +
    +filesize=`stat -f "%z" ${tempfile}`
    +blocks=$(($filesize / ${BLOCKSIZE} + 2))
    +dd if=/dev/zero of=${2} bs=${BLOCKSIZE} count=${blocks}
    +if [ $? -ne 0 ]; then
    +  echo "creation of image file failed"
    +  exit 1
    +fi
    +
    +unit=`mdconfig -a -t vnode -f ${2}`
    +if [ $? -ne 0 ]; then
    +  echo "mdconfig failed"
    +  exit 1
    +fi
    +
    +fdisk -BIq /dev/${unit}
    +if [ $? -ne 0 ]; then
    +  echo "fdisk failed"
    +  exit 1
    +fi
    +
    +bsdlabel -B -w /dev/${unit}
    +if [ $? -ne 0 ]; then
    +  echo "bsdlabel failed"
    +  exit 1
    +fi
    +
    +dd if=${tempfile} of=/dev/${unit}a bs=$BLOCKSIZE conv=sync
    +if [ $? -ne 0 ]; then
    +  echo "copying filesystem into image file failed"
    +  exit 1
    +fi
    +
    +mdconfig -d -u ${unit}
    +
    +rm -f ${tempfile}
    +
    
    From c161c6f4a7f2d05140778801625206f525c74f7b Mon Sep 17 00:00:00 2001
    From: Daniel Gerzo 
    Date: Tue, 6 Apr 2010 21:39:18 +0000
    Subject: [PATCH 1848/2592] Merge r205659: - update zfs and zpool manual pages
     to match the current state of the source
    
    PR:		144984
    Submitted by:	mm@
    Approved by:	pjd@
    Obtained from:	OpenSolaris
    ---
     cddl/contrib/opensolaris/cmd/zfs/zfs.8     | 998 ++++++++++-----------
     cddl/contrib/opensolaris/cmd/zpool/zpool.8 | 205 ++---
     2 files changed, 579 insertions(+), 624 deletions(-)
    
    diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
    index 39445ea13a8..9cda0e55643 100644
    --- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8
    +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
    @@ -1,24 +1,9 @@
     '\" te
    -.\" CDDL HEADER START
    -.\"
    -.\" The contents of this file are subject to the terms of the
    -.\" Common Development and Distribution License (the "License").  
    -.\" You may not use this file except in compliance with the License.
    -.\"
    -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    -.\" or http://www.opensolaris.org/os/licensing.
    -.\" See the License for the specific language governing permissions
    -.\" and limitations under the License.
    -.\"
    -.\" When distributing Covered Code, include this CDDL HEADER in each
    -.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
    -.\" If applicable, add the following below this CDDL HEADER, with the
    -.\" fields enclosed by brackets "[]" replaced with your own identifying
    -.\" information: Portions Copyright [yyyy] [name of copyright owner]
    -.\"
    -.\" CDDL HEADER END
    -.\" Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
    -.TH zfs 1M "8 Apr 2008" "SunOS 5.11" "System Administration Commands"
    +.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
    +.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
    +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
    +.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
    +.TH zfs 1M "14 Feb 2009" "SunOS 5.11" "System Administration Commands"
     .SH NAME
     zfs \- configures ZFS file systems
     .SH SYNOPSIS
    @@ -44,7 +29,8 @@ zfs \- configures ZFS file systems
     
     .LP
     .nf
    -\fBzfs\fR \fBsnapshot\fR [\fB-r\fR] \fIfilesystem@snapname\fR|\fIvolume@snapname\fR
    +\fBzfs\fR \fBsnapshot\fR [\fB-r\fR] [\fB-o\fR \fIproperty\fR=\fIvalue\fR]... 
    +      \fIfilesystem@snapname\fR|\fIvolume@snapname\fR
     .fi
     
     .LP
    @@ -54,7 +40,7 @@ zfs \- configures ZFS file systems
     
     .LP
     .nf
    -\fBzfs\fR \fBclone\fR [\fB-p\fR] \fIsnapshot\fR \fIfilesystem\fR|\fIvolume\fR
    +\fBzfs\fR \fBclone\fR [\fB-p\fR] [\fB-o\fR \fIproperty\fR=\fIvalue\fR] ... \fIsnapshot\fR \fIfilesystem\fR|\fIvolume\fR
     .fi
     
     .LP
    @@ -65,7 +51,7 @@ zfs \- configures ZFS file systems
     .LP
     .nf
     \fBzfs\fR \fBrename\fR \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR 
    -    \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR
    +     \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR
     .fi
     
     .LP
    @@ -81,23 +67,23 @@ zfs \- configures ZFS file systems
     .LP
     .nf
     \fBzfs\fR \fBlist\fR [\fB-rH\fR] [\fB-o\fR \fIproperty\fR[,...]] [\fB-t\fR \fItype\fR[,...]]
    -    [\fB-s\fR \fIproperty\fR] ... [\fB-S\fR \fIproperty\fR ... [\fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR] ...
    +     [\fB-s\fR \fIproperty\fR] ... [\fB-S\fR \fIproperty\fR] ... [\fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR] ...
     .fi
     
     .LP
     .nf
    -\fBzfs\fR \fBset\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR ...
    +\fBzfs\fR \fBset\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR|snapshot ...
     .fi
     
     .LP
     .nf
     \fBzfs\fR \fBget\fR [\fB-rHp\fR] [\fB-o\fR \fIfield\fR[,...]] [\fB-s\fR \fIsource\fR[,...]] "\fIall\fR" | \fIproperty\fR[,...]
    -     \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...
    +      \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...
     .fi
     
     .LP
     .nf
    -\fBzfs\fR \fBinherit\fR [\fB-r\fR] \fIproperty\fR \fIfilesystem\fR|\fIvolume\fR ...
    +\fBzfs\fR \fBinherit\fR [\fB-r\fR] \fIproperty\fR \fIfilesystem\fR|\fIvolume|snapshot\fR ...
     .fi
     
     .LP
    @@ -132,12 +118,12 @@ zfs \- configures ZFS file systems
     
     .LP
     .nf
    -\fBzfs\fR \fBunshare\fR  \fB-a\fR \fIfilesystem\fR|\fImountpoint\fR
    +\fBzfs\fR \fBunshare\fR \fB-a\fR \fIfilesystem\fR|\fImountpoint\fR
     .fi
     
     .LP
     .nf
    -\fBzfs\fR \fBsend\fR [\fB-vR\fR] [\fB-\fR[\fB-iI\fR] \fIsnapshot\fR] \fIsnapshot\fR
    +\fBzfs\fR \fBsend\fR [\fB-vR\fR] [\fB-\fR[\fBiI\fR] \fIsnapshot\fR] \fIsnapshot\fR
     .fi
     
     .LP
    @@ -153,7 +139,7 @@ zfs \- configures ZFS file systems
     .LP
     .nf
     \fBzfs\fR \fBallow\fR [\fB-ldug\fR] "\fIeveryone\fR"|\fIuser\fR|\fIgroup\fR[,...] \fIperm\fR|\fI@setname\fR[,...] 
    -    \fIfilesystem\fR|\fIvolume\fR
    +     \fIfilesystem\fR|\fIvolume\fR
     .fi
     
     .LP
    @@ -174,7 +160,7 @@ zfs \- configures ZFS file systems
     .LP
     .nf
     \fBzfs\fR \fBunallow\fR [\fB-rldug\fR] "\fIeveryone\fR"|\fIuser\fR|\fIgroup\fR[,...] [\fIperm\fR|@\fIsetname\fR[,... ]] 
    -    \fIfilesystem\fR|\fIvolume\fR
    +     \fIfilesystem\fR|\fIvolume\fR
     .fi
     
     .LP
    @@ -192,20 +178,10 @@ zfs \- configures ZFS file systems
     \fBzfs\fR \fBunallow\fR [\fB-r\fR] \fB-s\fR @setname [\fIperm\fR|@\fIsetname\fR[,... ]] \fIfilesystem\fR|\fIvolume\fR
     .fi
     
    -.LP
    -.nf
    -\fBzfs\fR \fBjail\fR \fBjailid\fR \fB\fIfilesystem\fR\fR
    -.fi
    -.LP
    -.nf
    -\fBzfs\fR \fBunjail\fR \fBjailid\fR \fB\fIfilesystem\fR\fR
    -.fi
    -
     .SH DESCRIPTION
     .sp
     .LP
    -The \fBzfs\fR command configures \fBZFS\fR datasets within a \fBZFS\fR storage pool, as described in \fBzpool\fR(1M). A
    -dataset is identified by a unique path within the \fBZFS\fR namespace. For example:
    +The \fBzfs\fR command configures \fBZFS\fR datasets within a \fBZFS\fR storage pool, as described in \fBzpool\fR(1M). A dataset is identified by a unique path within the \fBZFS\fR namespace. For example:
     .sp
     .in +2
     .nf
    @@ -226,9 +202,9 @@ A dataset can be one of the following:
     .na
     \fB\fIfile system\fR\fR
     .ad
    -.RS 15n
    -.rt  
    -A standard \fBPOSIX\fR file system. \fBZFS\fR file systems can be mounted within the standard file system namespace and behave like any other file system.
    +.sp .6
    +.RS 4n
    +A \fBZFS\fR dataset of type "filesystem" that can be mounted within the standard system namespace and behaves like other file systems. While \fBZFS\fR file systems are designed to be \fBPOSIX\fR compliant, known issues exist that prevent compliance in some cases. Applications that depend on standards conformance might fail due to nonstandard behavior when checking file system free space.
     .RE
     
     .sp
    @@ -237,8 +213,8 @@ A standard \fBPOSIX\fR file system. \fBZFS\fR file systems can be mounted within
     .na
     \fB\fIvolume\fR\fR
     .ad
    -.RS 15n
    -.rt  
    +.sp .6
    +.RS 4n
     A logical volume exported as a raw or block device. This type of dataset should only be used under special circumstances. File systems are typically used in most environments. Volumes cannot be used in a non-global zone.
     .RE
     
    @@ -248,8 +224,8 @@ A logical volume exported as a raw or block device. This type of dataset should
     .na
     \fB\fIsnapshot\fR\fR
     .ad
    -.RS 15n
    -.rt  
    +.sp .6
    +.RS 4n
     A read-only version of a file system or volume at a given point in time. It is specified as \fIfilesystem@name\fR or \fIvolume@name\fR.
     .RE
     
    @@ -272,20 +248,17 @@ A snapshot is a read-only copy of a file system or volume. Snapshots can be crea
     Snapshots can have arbitrary names. Snapshots of volumes can be cloned or rolled back, but cannot be accessed independently.
     .sp
     .LP
    -File system snapshots can be accessed under the ".zfs/snapshot" directory in the root of the file system. Snapshots are automatically mounted on demand and may be unmounted at regular intervals. The visibility of the ".zfs" directory can be controlled by the "snapdir"
    -property.
    +File system snapshots can be accessed under the ".zfs/snapshot" directory in the root of the file system. Snapshots are automatically mounted on demand and may be unmounted at regular intervals. The visibility of the ".zfs" directory can be controlled by the "snapdir" property.
     .SS "Clones"
     .sp
     .LP
     A clone is a writable volume or file system whose initial contents are the same as another dataset. As with snapshots, creating a clone is nearly instantaneous, and initially consumes no additional space.
     .sp
     .LP
    -Clones can only be created from a snapshot. When a snapshot is cloned, it creates an implicit dependency between the parent and child. Even though the clone is created somewhere else in the dataset hierarchy, the original snapshot cannot be destroyed as long as a clone exists. The "origin"
    -property exposes this dependency, and the \fBdestroy\fR command lists any such dependencies, if they exist.
    +Clones can only be created from a snapshot. When a snapshot is cloned, it creates an implicit dependency between the parent and child. Even though the clone is created somewhere else in the dataset hierarchy, the original snapshot cannot be destroyed as long as a clone exists. The "origin" property exposes this dependency, and the \fBdestroy\fR command lists any such dependencies, if they exist.
     .sp
     .LP
    -The clone parent-child dependency relationship can be reversed by using the "\fBpromote\fR" subcommand. This causes the "origin" file system to become a clone of the specified file system, which makes it possible to destroy the file system that the clone
    -was created from.
    +The clone parent-child dependency relationship can be reversed by using the "\fBpromote\fR" subcommand. This causes the "origin" file system to become a clone of the specified file system, which makes it possible to destroy the file system that the clone was created from.
     .SS "Mount Points"
     .sp
     .LP
    @@ -301,8 +274,7 @@ A file system can also have a mount point set in the "mountpoint" property. This
     A file system mountpoint property of "none" prevents the file system from being mounted.
     .sp
     .LP
    -If needed, \fBZFS\fR file systems can also be managed with traditional tools (\fBmount\fR, \fBumount\fR, \fB/etc/vfstab\fR). If a file system's mount point is set to "legacy", \fBZFS\fR makes no attempt to manage
    -the file system, and the administrator is responsible for mounting and unmounting the file system.
    +If needed, \fBZFS\fR file systems can also be managed with traditional tools (\fBmount\fR, \fBumount\fR, \fB/etc/vfstab\fR). If a file system's mount point is set to "legacy", \fBZFS\fR makes no attempt to manage the file system, and the administrator is responsible for mounting and unmounting the file system.
     .SS "Zones"
     .sp
     .LP
    @@ -312,8 +284,7 @@ A \fBZFS\fR file system can be added to a non-global zone by using zonecfg's "\f
     The physical properties of an added file system are controlled by the global administrator. However, the zone administrator can create, modify, or destroy files within the added file system, depending on how the file system is mounted.
     .sp
     .LP
    -A dataset can also be delegated to a non-global zone by using zonecfg's "\fBadd dataset\fR" subcommand. You cannot delegate a dataset to one zone and the children of the same dataset to another zone. The zone administrator can change properties of the dataset or
    -any of its children. However, the "quota" property is controlled by the global administrator.
    +A dataset can also be delegated to a non-global zone by using zonecfg's "\fBadd dataset\fR" subcommand. You cannot delegate a dataset to one zone and the children of the same dataset to another zone. The zone administrator can change properties of the dataset or any of its children. However, the "quota" property is controlled by the global administrator.
     .sp
     .LP
     A \fBZFS\fR volume can be added as a device to a non-global zone by using zonecfg's "\fBadd device\fR" subcommand. However, its physical properties can only be modified by the global administrator.
    @@ -329,15 +300,13 @@ The global administrator can forcibly clear the "zoned" property, though this sh
     .SS "Native Properties"
     .sp
     .LP
    -Properties are divided into two types, native properties and user defined properties. Native properties either export internal statistics or control \fBZFS\fR behavior. In addition, native properties are either editable or read-only. User properties have no effect on \fBZFS\fR behavior,
    -but you can use them to annotate datasets in a way that is meaningful in your environment. For more information about user properties, see the "User Properties" section.
    +Properties are divided into two types, native properties and user defined properties. Native properties either export internal statistics or control \fBZFS\fR behavior. In addition, native properties are either editable or read-only. User properties have no effect on \fBZFS\fR behavior, but you can use them to annotate datasets in a way that is meaningful in your environment. For more information about user properties, see the "User Properties" section.
     .sp
     .LP
    -Every dataset has a set of properties that export statistics about the dataset as well as control various behavior. Properties are inherited from the parent unless overridden by the child. Snapshot properties can not be edited; they always inherit their inheritable properties. Properties
    -that are not applicable to snapshots are not displayed.
    +Every dataset has a set of properties that export statistics about the dataset as well as control various behavior. Properties are inherited from the parent unless overridden by the child. Some properties only apply to certain types of datasets (file systems, volumes or snapshots).
     .sp
     .LP
    -The values of numeric properties can be specified using the following human-readable suffixes (for example, "k", "KB", "M", "Gb", etc, up to Z for zettabyte). The following are all valid (and equal) specifications: 
    +The values of numeric properties can be specified using human-readable suffixes (for example, "k", "KB", "M", "Gb", etc, up to Z for zettabyte). The following are all valid (and equal) specifications: 
     .sp
     .in +2
     .nf
    @@ -360,8 +329,7 @@ The following native properties consist of read-only statistics about the datase
     .ad
     .sp .6
     .RS 4n
    -The amount of space available to the dataset and all its children, assuming that there is no other activity in the pool. Because space is shared within a pool, availability can be limited by any number of factors, including physical pool size, quotas, reservations, or other datasets
    -within the pool.
    +The amount of space available to the dataset and all its children, assuming that there is no other activity in the pool. Because space is shared within a pool, availability can be limited by any number of factors, including physical pool size, quotas, reservations, or other datasets within the pool.
     .sp
     This property can also be referred to by its shortened column name, "avail".
     .RE
    @@ -418,8 +386,7 @@ For cloned file systems or volumes, the snapshot from which the clone was create
     .ad
     .sp .6
     .RS 4n
    -The amount of data that is accessible by this dataset, which may or may not be shared with other datasets in the pool. When a snapshot or clone is created, it initially references the same amount of space as the file system or snapshot it was created from, since its contents are
    -identical.
    +The amount of data that is accessible by this dataset, which may or may not be shared with other datasets in the pool. When a snapshot or clone is created, it initially references the same amount of space as the file system or snapshot it was created from, since its contents are identical.
     .sp
     This property can also be referred to by its shortened column name, "refer".
     .RE
    @@ -432,7 +399,7 @@ This property can also be referred to by its shortened column name, "refer".
     .ad
     .sp .6
     .RS 4n
    -The type of dataset: "filesystem", "volume", "snapshot", or "clone".
    +The type of dataset: "filesystem", "volume", or "snapshot".
     .RE
     
     .sp
    @@ -443,15 +410,68 @@ The type of dataset: "filesystem", "volume", "snapshot", or "clone".
     .ad
     .sp .6
     .RS 4n
    -The amount of space consumed by this dataset and all its descendents. This is the value that is checked against this dataset's quota and reservation. The space used does not include this dataset's reservation, but does take into account the reservations of any descendent datasets.
    -The amount of space that a dataset consumes from its parent, as well as the amount of space that are freed if this dataset is recursively destroyed, is the greater of its space used and its reservation.
    +The amount of space consumed by this dataset and all its descendents. This is the value that is checked against this dataset's quota and reservation. The space used does not include this dataset's reservation, but does take into account the reservations of any descendent datasets. The amount of space that a dataset consumes from its parent, as well as the amount of space that are freed if this dataset is recursively destroyed, is the greater of its space used and its reservation.
     .sp
    -When snapshots (see the "Snapshots" section) are created, their space is initially shared between the snapshot and the file system, and possibly with previous snapshots. As the file system changes, space that was previously shared becomes unique to the snapshot, and counted in
    -the snapshot's space used. Additionally, deleting snapshots can increase the amount of space unique to (and used by) other snapshots.
    +When snapshots (see the "Snapshots" section) are created, their space is initially shared between the snapshot and the file system, and possibly with previous snapshots. As the file system changes, space that was previously shared becomes unique to the snapshot, and counted in the snapshot's space used. Additionally, deleting snapshots can increase the amount of space unique to (and used by) other snapshots.
     .sp
     The amount of space used, available, or referenced does not take into account pending changes. Pending changes are generally accounted for within a few seconds. Committing a change to a disk using \fBfsync\fR(3c) or \fBO_SYNC\fR does not necessarily guarantee that the space usage information is updated immediately.
     .RE
     
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fBusedby*\fR
    +.ad
    +.sp .6
    +.RS 4n
    +The \fBusedby*\fR snapshots decompose the "used" properties into the various reasons that space is used. Specifically, \fBused\fR = \fBusedbychildren\fR + \fBusedbydataset\fR + \fBusedbyrefreservation\fR +, \fBusedbysnapshots\fR. These properties are only available for datasets created on zpool "version 13" pools.
    +.RE
    +
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fBusedbychildren\fR
    +.ad
    +.sp .6
    +.RS 4n
    +The amount of space used by children of this dataset, which would be freed if all the dataset's children were destroyed.
    +.RE
    +
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fBusedbydataset\fR
    +.ad
    +.sp .6
    +.RS 4n
    +The amount of space used by this dataset itself, which would be freed if the dataset were destroyed (after first removing any \fBrefreservation\fR and destroying any necessary snapshots or descendents).
    +.RE
    +
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fBusedbyrefreservation\fR
    +.ad
    +.sp .6
    +.RS 4n
    +The amount of space used by a \fBrefreservation\fR set on this dataset, which would be freed if the \fBrefreservation\fR was removed.
    +.RE
    +
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fBusedbysnapshots\fR
    +.ad
    +.sp .6
    +.RS 4n
    +The amount of space consumed by snapshots of this dataset. In particular, it is the amount of space that would be freed if all of this dataset's snapshots were destroyed. Note that this is not simply the sum of the snapshots' "used" properties because space can be shared by multiple snapshots
    +.RE
    +
     .sp
     .ne 2
     .mk
    @@ -460,8 +480,7 @@ The amount of space used, available, or referenced does not take into account pe
     .ad
     .sp .6
     .RS 4n
    -For volumes, specifies the block size of the volume. The \fBblocksize\fR cannot be changed once the volume has been written, so it should be set at volume creation time. The default \fBblocksize\fR for volumes is 8 Kbytes. Any power of 2 from 512 bytes
    -to 128 Kbytes is valid.
    +For volumes, specifies the block size of the volume. The \fBblocksize\fR cannot be changed once the volume has been written, so it should be set at volume creation time. The default \fBblocksize\fR for volumes is 8 Kbytes. Any power of 2 from 512 bytes to 128 Kbytes is valid.
     .sp
     This property can also be referred to by its shortened column name, "volblock".
     .RE
    @@ -473,15 +492,13 @@ The following native properties can be used to change the behavior of a \fBZFS\f
     .ne 2
     .mk
     .na
    -\fBaclinherit=\fBdiscard\fR | \fBnoallow\fR | \fBrestricted\fR | \fBpassthrough\fR\fR
    +\fBaclinherit=\fBdiscard\fR | \fBnoallow\fR | \fBrestricted\fR | \fBpassthrough\fR | \fBpassthrough-x\fR\fR
     .ad
     .sp .6
     .RS 4n
    -Controls how \fBACL\fR entries are inherited when files and directories are created. A file system with an "aclinherit" property of "\fBdiscard\fR" does not inherit any \fBACL\fR entries. A file system with an "aclinherit"
    -property value of "\fBnoallow\fR" only inherits inheritable \fBACL\fR entries that specify "deny" permissions. The property value "\fBrestricted\fR" (the default) removes the "\fBwrite_acl\fR" and "\fBwrite_owner\fR" permissions when the \fBACL\fR entry is inherited. A file system with an "aclinherit" property value of "\fBpassthrough\fR" inherits all inheritable \fBACL\fR entries without any modifications made to the \fBACL\fR entries when they are inherited.
    +Controls how \fBACL\fR entries are inherited when files and directories are created. A file system with an "aclinherit" property of "\fBdiscard\fR" does not inherit any \fBACL\fR entries. A file system with an "aclinherit" property value of "\fBnoallow\fR" only inherits inheritable \fBACL\fR entries that specify "deny" permissions. The property value "\fBrestricted\fR" (the default) removes the "\fBwrite_acl\fR" and "\fBwrite_owner\fR" permissions when the \fBACL\fR entry is inherited. A file system with an "aclinherit" property value of "\fBpassthrough\fR" inherits all inheritable \fBACL\fR entries without any modifications made to the \fBACL\fR entries when they are inherited. A file system with an "aclinherit" property value of "\fBpassthrough-x\fR" has the same meaning as "\fBpassthrough\fR", except that the \fBowner@\fR, \fBgroup@\fR, and \fBeveryone@\fR \fBACE\fRs inherit the execute permission only if the file creation mode also requests the execute bit.
     .sp
    -When the property value is set to "\fBpassthrough\fR," files are created with a mode determined by the inheritable \fBACE\fRs. If no inheritable \fBACE\fRs exist that affect the mode, then the mode is set in accordance to the requested mode
    -from the application.
    +When the property value is set to "\fBpassthrough\fR," files are created with a mode determined by the inheritable \fBACE\fRs. If no inheritable \fBACE\fRs exist that affect the mode, then the mode is set in accordance to the requested mode from the application.
     .RE
     
     .sp
    @@ -492,9 +509,7 @@ from the application.
     .ad
     .sp .6
     .RS 4n
    -Controls how an \fBACL\fR is modified during \fBchmod\fR(2). A file system with an "aclmode" property of "\fBdiscard\fR"
    -deletes all \fBACL\fR entries that do not represent the mode of the file. An "aclmode" property of "\fBgroupmask\fR" (the default) reduces user or group permissions. The permissions are reduced, such that they are no greater than the group permission
    -bits, unless it is a user entry that has the same \fBUID\fR as the owner of the file or directory. In this case, the \fBACL\fR permissions are reduced so that they are no greater than owner permission bits. A file system with an "aclmode" property of "\fBpassthrough\fR" indicates that no changes are made to the \fBACL\fR other than generating the necessary \fBACL\fR entries to represent the new mode of the file or directory.
    +Controls how an \fBACL\fR is modified during \fBchmod\fR(2). A file system with an "aclmode" property of "\fBdiscard\fR" deletes all \fBACL\fR entries that do not represent the mode of the file. An "aclmode" property of "\fBgroupmask\fR" (the default) reduces user or group permissions. The permissions are reduced, such that they are no greater than the group permission bits, unless it is a user entry that has the same \fBUID\fR as the owner of the file or directory. In this case, the \fBACL\fR permissions are reduced so that they are no greater than owner permission bits. A file system with an "aclmode" property of "\fBpassthrough\fR" indicates that no changes are made to the \fBACL\fR other than generating the necessary \fBACL\fR entries to represent the new mode of the file or directory.
     .RE
     
     .sp
    @@ -505,8 +520,7 @@ bits, unless it is a user entry that has the same \fBUID\fR as the owner of the
     .ad
     .sp .6
     .RS 4n
    -Controls whether the access time for files is updated when they are read. Turning this property off avoids producing write traffic when reading files and can result in significant performance gains, though it might confuse mailers and other similar utilities. The default value
    -is "on".
    +Controls whether the access time for files is updated when they are read. Turning this property off avoids producing write traffic when reading files and can result in significant performance gains, though it might confuse mailers and other similar utilities. The default value is "on".
     .RE
     
     .sp
    @@ -517,12 +531,9 @@ is "on".
     .ad
     .sp .6
     .RS 4n
    -If this property is set to "\fBoff\fR", the file system cannot be mounted, and is ignored by "\fBzfs mount -a\fR". Setting this property to "\fBoff\fR" is similar to setting the "mountpoint"
    -property to "\fBnone\fR", except that the dataset still has a normal "mountpoint" property, which can be inherited. Setting this property to "\fBoff\fR" allows datasets to be used solely as a mechanism to inherit properties. One example
    -of setting canmount=\fBoff\fR is to have two datasets with the same mountpoint, so that the children of both datasets appear in the same directory, but might have different inherited characteristics.
    +If this property is set to "\fBoff\fR", the file system cannot be mounted, and is ignored by "\fBzfs mount -a\fR". Setting this property to "\fBoff\fR" is similar to setting the "mountpoint" property to "\fBnone\fR", except that the dataset still has a normal "mountpoint" property, which can be inherited. Setting this property to "\fBoff\fR" allows datasets to be used solely as a mechanism to inherit properties. One example of setting canmount=\fBoff\fR is to have two datasets with the same mountpoint, so that the children of both datasets appear in the same directory, but might have different inherited characteristics.
     .sp
    -When the "\fBnoauto\fR" option is set, a dataset can only be mounted and unmounted explicitly. The dataset is not mounted automatically when the dataset is created or imported, nor is it mounted by the "\fBzfs mount -a\fR" command or unmounted
    -by the "\fBzfs unmount -a\fR" command. 
    +When the "\fBnoauto\fR" option is set, a dataset can only be mounted and unmounted explicitly. The dataset is not mounted automatically when the dataset is created or imported, nor is it mounted by the "\fBzfs mount -a\fR" command or unmounted by the "\fBzfs unmount -a\fR" command. 
     .sp
     This property is not inherited.
     .RE
    @@ -535,8 +546,7 @@ This property is not inherited.
     .ad
     .sp .6
     .RS 4n
    -Controls the checksum used to verify data integrity. The default value is "on", which automatically selects an appropriate algorithm (currently, \fIfletcher4\fR, but this may change in future releases). The value "off" disables integrity
    -checking on user data. Disabling checksums is NOT a recommended practice.
    +Controls the checksum used to verify data integrity. The default value is "on", which automatically selects an appropriate algorithm (currently, \fIfletcher2\fR, but this may change in future releases). The value "off" disables integrity checking on user data. Disabling checksums is NOT a recommended practice.
     .RE
     
     .sp
    @@ -547,9 +557,7 @@ checking on user data. Disabling checksums is NOT a recommended practice.
     .ad
     .sp .6
     .RS 4n
    -Controls the compression algorithm used for this dataset. The "lzjb" compression algorithm is optimized for performance while providing decent data compression. Setting compression to "on" uses the "lzjb" compression algorithm. The "gzip"
    -compression algorithm uses the same compression as the \fBgzip\fR(1) command. You can specify the "gzip" level by using the value "gzip-\fIN\fR" where \fIN\fR is
    -an integer from 1 (fastest) to 9 (best compression ratio). Currently, "gzip" is equivalent to "gzip-6" (which is also the default for \fBgzip\fR(1)).
    +Controls the compression algorithm used for this dataset. The "lzjb" compression algorithm is optimized for performance while providing decent data compression. Setting compression to "on" uses the "lzjb" compression algorithm. The "gzip" compression algorithm uses the same compression as the \fBgzip\fR(1) command. You can specify the "gzip" level by using the value "gzip-\fIN\fR" where \fIN\fR is an integer from 1 (fastest) to 9 (best compression ratio). Currently, "gzip" is equivalent to "gzip-6" (which is also the default for \fBgzip\fR(1)).
     .sp
     This property can also be referred to by its shortened column name "compress".
     .RE
    @@ -562,8 +570,7 @@ This property can also be referred to by its shortened column name "compress".
     .ad
     .sp .6
     .RS 4n
    -Controls the number of copies of data stored for this dataset. These copies are in addition to any redundancy provided by the pool, for example, mirroring or raid-z. The copies are stored on different disks, if possible. The space used by multiple copies is charged to the associated
    -file and dataset, changing the "used" property and counting against quotas and reservations.
    +Controls the number of copies of data stored for this dataset. These copies are in addition to any redundancy provided by the pool, for example, mirroring or raid-z. The copies are stored on different disks, if possible. The space used by multiple copies is charged to the associated file and dataset, changing the "used" property and counting against quotas and reservations.
     .sp
     Changing this property only affects newly-written data. Therefore, set this property at file system creation time by using the "\fB-o\fR copies=" option.
     .RE
    @@ -600,8 +607,7 @@ Controls whether processes can be executed from within this file system. The def
     .RS 4n
     Controls the mount point used for this file system. See the "Mount Points" section for more information on how this property is used. 
     .sp
    -When the mountpoint property is changed for a file system, the file system and any children that inherit the mount point are unmounted. If the new value is "legacy", then they remain unmounted. Otherwise, they are automatically remounted in the new location if the property was
    -previously "legacy" or "none", or if they were mounted before the property was changed. In addition, any shared file systems are unshared and shared in the new location.
    +When the mountpoint property is changed for a file system, the file system and any children that inherit the mount point are unmounted. If the new value is "legacy", then they remain unmounted. Otherwise, they are automatically remounted in the new location if the property was previously "legacy" or "none", or if they were mounted before the property was changed. In addition, any shared file systems are unshared and shared in the new location.
     .RE
     
     .sp
    @@ -612,7 +618,18 @@ previously "legacy" or "none", or if they were mounted before the property was c
     .ad
     .sp .6
     .RS 4n
    -Controls whether the file system should be mounted with "\fBnbmand\fR" (Non Blocking mandatory locks). This is used for \fBCIFS\fR clients. 	Changes to this property only take effect when the file system is umounted and remounted. See \fBmount\fR(1M) for more information on "\fBnbmand\fR" mounts.
    +Controls whether the file system should be mounted with "\fBnbmand\fR" (Non Blocking mandatory locks). This is used for \fBCIFS\fR clients. Changes to this property only take effect when the file system is umounted and remounted. See \fBmount\fR(1M) for more information on "\fBnbmand\fR" mounts.
    +.RE
    +
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fBprimarycache=\fIall\fR | \fInone\fR | \fImetadata\fR\fR
    +.ad
    +.sp .6
    +.RS 4n
    +Controls what is cached in the primary cache (ARC). If this property is set to "all", then both user data and metadata is cached. If this property is set to "none", then neither user data nor metadata is cached. If this property is set to "metadata", then only metadata is cached. The default value is "all".
     .RE
     
     .sp
    @@ -623,8 +640,7 @@ Controls whether the file system should be mounted with "\fBnbmand\fR" (Non Bloc
     .ad
     .sp .6
     .RS 4n
    -Limits the amount of space a dataset and its descendents can consume. This property enforces a hard limit on the amount of space used. This includes all space consumed by descendents, including file systems and snapshots. Setting a quota on a descendent of a dataset that already
    -has a quota does not override the ancestor's quota, but rather imposes an additional limit.
    +Limits the amount of space a dataset and its descendents can consume. This property enforces a hard limit on the amount of space used. This includes all space consumed by descendents, including file systems and snapshots. Setting a quota on a descendent of a dataset that already has a quota does not override the ancestor's quota, but rather imposes an additional limit.
     .sp
     Quotas cannot be set on volumes, as the "volsize" property acts as an implicit quota.
     .RE
    @@ -650,11 +666,9 @@ This property can also be referred to by its shortened column name, "rdonly".
     .ad
     .sp .6
     .RS 4n
    -Specifies a suggested block size for files in the file system. This property is designed solely for use with database workloads that access files in fixed-size records. \fBZFS\fR automatically tunes block sizes according to internal algorithms optimized for typical
    -access patterns. 
    +Specifies a suggested block size for files in the file system. This property is designed solely for use with database workloads that access files in fixed-size records. \fBZFS\fR automatically tunes block sizes according to internal algorithms optimized for typical access patterns. 
     .sp
    -For databases that create very large files but access them in small random chunks, these algorithms may be suboptimal. Specifying a "recordsize" greater than or equal to the record size of the database can result in significant performance gains. Use of this property for general
    -purpose file systems is strongly discouraged, and may adversely affect performance.
    +For databases that create very large files but access them in small random chunks, these algorithms may be suboptimal. Specifying a "recordsize" greater than or equal to the record size of the database can result in significant performance gains. Use of this property for general purpose file systems is strongly discouraged, and may adversely affect performance.
     .sp
     The size specified must be a power of two greater than or equal to 512 and less than or equal to 128 Kbytes.
     .sp
    @@ -682,8 +696,7 @@ Limits the amount of space a dataset can consume. This property enforces a hard
     .ad
     .sp .6
     .RS 4n
    -The minimum amount of space guaranteed to a dataset, not including its descendents. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by \fBrefreservation\fR. The \fBrefreservation\fR reservation
    -is accounted for in the parent datasets' space used, and counts against the parent datasets' quotas and reservations.
    +The minimum amount of space guaranteed to a dataset, not including its descendents. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by \fBrefreservation\fR. The \fBrefreservation\fR reservation is accounted for in the parent datasets' space used, and counts against the parent datasets' quotas and reservations.
     .sp
     If \fBrefreservation\fR is set, a snapshot is only allowed if there is enough free pool space outside of this reservation to accommodate the current number of "referenced" bytes in the dataset.
     .sp
    @@ -698,12 +711,22 @@ This property can also be referred to by its shortened column name, "refreserv".
     .ad
     .sp .6
     .RS 4n
    -The minimum amount of space guaranteed to a dataset and its descendents. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by its reservation. Reservations are accounted for in the parent datasets' space
    -used, and count against the parent datasets' quotas and reservations.
    +The minimum amount of space guaranteed to a dataset and its descendents. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by its reservation. Reservations are accounted for in the parent datasets' space used, and count against the parent datasets' quotas and reservations.
     .sp
     This property can also be referred to by its shortened column name, "reserv".
     .RE
     
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fBsecondarycache=\fIall\fR | \fInone\fR | \fImetadata\fR\fR
    +.ad
    +.sp .6
    +.RS 4n
    +Controls what is cached in the secondary cache (L2ARC). If this property is set to "all", then both user data and metadata is cached. If this property is set to "none", then neither user data nor metadata is cached. If this property is set to "metadata", then only metadata is cached. The default value is "all".
    +.RE
    +
     .sp
     .ne 2
     .mk
    @@ -723,8 +746,7 @@ Controls whether the set-\fBUID\fR bit is respected for the file system. The def
     .ad
     .sp .6
     .RS 4n
    -Like the "sharenfs" property, "shareiscsi" indicates whether a \fBZFS\fR volume is exported as an \fBiSCSI\fR target. The acceptable values for this property are "on", "off", and "type=disk".
    -The default value is "off". In the future, other target types might be supported. For example, "tape".
    +Like the "sharenfs" property, "shareiscsi" indicates whether a \fBZFS\fR volume is exported as an \fBiSCSI\fR target. The acceptable values for this property are "on", "off", and "type=disk". The default value is "off". In the future, other target types might be supported. For example, "tape".
     .sp
     You might want to set "shareiscsi=on" for a file system so that all \fBZFS\fR volumes within the file system are shared by default. Setting this property on a file system has no direct effect, however.
     .RE
    @@ -737,15 +759,13 @@ You might want to set "shareiscsi=on" for a file system so that all \fBZFS\fR vo
     .ad
     .sp .6
     .RS 4n
    -Controls whether the file system is shared by using the Solaris \fBCIFS\fR service, and what options are to be used. A file system with the "\fBsharesmb\fR" property set to "off" is managed through traditional tools such as \fBsharemgr\fR(1M). Otherwise, the file system is automatically shared and unshared with the "zfs share" and "zfs unshare" commands. If the property is set to "on",
    -the \fBsharemgr\fR(1M) command is invoked with no options. Otherwise, the \fBsharemgr\fR(1M) command is invoked with options equivalent to the contents of this property.
    +Controls whether the file system is shared by using the Solaris \fBCIFS\fR service, and what options are to be used. A file system with the "\fBsharesmb\fR" property set to "off" is managed through traditional tools such as \fBsharemgr\fR(1M). Otherwise, the file system is automatically shared and unshared with the \fBzfs share\fR and \fBzfs unshare\fR commands. If the property is set to \fBon\fR, the \fBsharemgr\fR(1M) command is invoked with no options. Otherwise, the \fBsharemgr\fR(1M) command is invoked with options equivalent to the contents of this property.
     .sp
    -Because \fBSMB\fR shares requires a resource name, a unique resource name is constructed from the dataset name. The constructed name is a copy of the dataset name except that the characters in the dataset name, which would be illegal in the resource name, are replaced with underscore
    -(_) characters. A pseudo property "name" is also supported that allows you to replace the data set name with a specified name. The specified name is then used to replace the prefix dataset in the case of inheritance. For example, if the dataset "\fBdata/home/john\fR"
    -is set to "name=john", then "\fBdata/home/john\fR" has a resource name of "john". If a child dataset of "\fBdata/home/john/backups\fR", it has a resource name of "john_backups".
    +Because \fBSMB\fR shares requires a resource name, a unique resource name is constructed from the dataset name. The constructed name is a copy of the dataset name except that the characters in the dataset name, which would be illegal in the resource name, are replaced with underscore (\fB_\fR) characters. A pseudo property "name" is also supported that allows you to replace the data set name with a specified name. The specified name is then used to replace the prefix dataset in the case of inheritance. For example, if the dataset \fBdata/home/john\fR is set to \fBname=john\fR, then \fBdata/home/john\fR has a resource name of \fBjohn\fR. If a child dataset of \fBdata/home/john/backups\fR, it has a resource name of \fBjohn_backups\fR.
     .sp
    -When the "sharesmb" property is changed for a dataset, the dataset and any children inheriting the property are re-shared with the new options, only if the property was previously set to "off", or if they were shared before the property was changed. If the new property
    -is set to "off", the file systems are unshared.
    +When SMB shares are created, the SMB share name appears as an entry in the \fB\&.zfs/shares\fR directory. You can use the \fBls\fR or \fBchmod\fR command to display the share-level ACLs on the entries in this directory.
    +.sp
    +When the \fBsharesmb\fR property is changed for a dataset, the dataset and any children inheriting the property are re-shared with the new options, only if the property was previously set to \fBoff\fR, or if they were shared before the property was changed. If the new property is set to \fBoff\fR, the file systems are unshared.
     .RE
     
     .sp
    @@ -756,11 +776,9 @@ is set to "off", the file systems are unshared.
     .ad
     .sp .6
     .RS 4n
    -Controls whether the file system is shared via \fBNFS\fR, and what options are used. A file system with a"\fBsharenfs\fR" property of "off" is managed through traditional tools such as \fBshare\fR(1M), \fBunshare\fR(1M), and \fBdfstab\fR(4). Otherwise, the file system is automatically shared and unshared with the "\fBzfs share\fR" and "\fBzfs unshare\fR" commands. If the property is set to "on",
    -the \fBshare\fR(1M) command is invoked with no options. Otherwise, the \fBshare\fR(1M) command is invoked with options equivalent to the contents of this property.
    +Controls whether the file system is shared via \fBNFS\fR, and what options are used. A file system with a"\fBsharenfs\fR" property of "off" is managed through traditional tools such as \fBshare\fR(1M), \fBunshare\fR(1M), and \fBdfstab\fR(4). Otherwise, the file system is automatically shared and unshared with the "\fBzfs share\fR" and "\fBzfs unshare\fR" commands. If the property is set to "on", the \fBshare\fR(1M) command is invoked with no options. Otherwise, the \fBshare\fR(1M) command is invoked with options equivalent to the contents of this property.
     .sp
    -When the "sharenfs" property is changed for a dataset, the dataset and any children inheriting the property are re-shared with the new options, only if the property was previously "off", or if they were shared before the property was changed. If the new property is "off",
    -the file systems are unshared.
    +When the "sharenfs" property is changed for a dataset, the dataset and any children inheriting the property are re-shared with the new options, only if the property was previously "off", or if they were shared before the property was changed. If the new property is "off", the file systems are unshared.
     .RE
     
     .sp
    @@ -793,14 +811,11 @@ The on-disk version of this file system, which is independent of the pool versio
     .ad
     .sp .6
     .RS 4n
    -For volumes, specifies the logical size of the volume. By default, creating a volume establishes a reservation of equal size. For storage pools with a version number of 9 or higher, a \fBrefreservation\fR is set instead. Any changes to \fBvolsize\fR are
    -reflected in an equivalent change to the reservation (or \fBrefreservation\fR). The \fBvolsize\fR can only be set to a multiple of \fBvolblocksize\fR, and cannot be zero.
    +For volumes, specifies the logical size of the volume. By default, creating a volume establishes a reservation of equal size. For storage pools with a version number of 9 or higher, a \fBrefreservation\fR is set instead. Any changes to \fBvolsize\fR are reflected in an equivalent change to the reservation (or \fBrefreservation\fR). The \fBvolsize\fR can only be set to a multiple of \fBvolblocksize\fR, and cannot be zero.
     .sp
    -The reservation is kept equal to the volume's logical size to prevent unexpected behavior for consumers. Without the reservation, the volume could run out of space, resulting in undefined behavior or data corruption, depending on how the volume is used. These effects can also occur when
    -the volume size is changed while it is in use (particularly when shrinking the size). Extreme care should be used when adjusting the volume size.
    +The reservation is kept equal to the volume's logical size to prevent unexpected behavior for consumers. Without the reservation, the volume could run out of space, resulting in undefined behavior or data corruption, depending on how the volume is used. These effects can also occur when the volume size is changed while it is in use (particularly when shrinking the size). Extreme care should be used when adjusting the volume size.
     .sp
    -Though not recommended, a "sparse volume" (also known as "thin provisioning") can be created by specifying the \fB-s\fR option to the "\fBzfs create -V\fR" command, or by changing the reservation after the volume has been created.
    -A "sparse volume" is a volume where the reservation is less then the volume size. Consequently, writes to a sparse volume can fail with \fBENOSPC\fR when the pool is low on space. For a sparse volume, changes to \fBvolsize\fR are not reflected in the reservation.
    +Though not recommended, a "sparse volume" (also known as "thin provisioning") can be created by specifying the \fB-s\fR option to the "\fBzfs create -V\fR" command, or by changing the reservation after the volume has been created. A "sparse volume" is a volume where the reservation is less then the volume size. Consequently, writes to a sparse volume can fail with \fBENOSPC\fR when the pool is low on space. For a sparse volume, changes to \fBvolsize\fR are not reflected in the reservation.
     .RE
     
     .sp
    @@ -838,8 +853,7 @@ Controls whether the dataset is managed from a non-global zone. See the "Zones"
     
     .sp
     .LP
    -The following three properties cannot be changed after the file system is created, and therefore, should be set when the file system is created. If the properties are not set with the "\fBzfs create\fR" command, these properties are inherited from the parent dataset.
    -If the parent dataset lacks these properties due to having been created prior to these features being supported, the new file system will have the default values for these properties.
    +The following three properties cannot be changed after the file system is created, and therefore, should be set when the file system is created. If the properties are not set with the "\fBzfs create\fR" or "\fBzpool create\fR" commands, these properties are inherited from the parent dataset. If the parent dataset lacks these properties due to having been created prior to these features being supported, the new file system will have the default values for these properties.
     .sp
     .ne 2
     .mk
    @@ -848,11 +862,9 @@ If the parent dataset lacks these properties due to having been created prior to
     .ad
     .sp .6
     .RS 4n
    -Indicates whether the file name matching algorithm used by the file system should be case-sensitive, case-insensitive, or allow a combination of both styles of matching. The default value for the "\fBcasesensitivity\fR" property is "\fBsensitive\fR."
    -Traditionally, UNIX and POSIX file systems have case-sensitive file names.
    +Indicates whether the file name matching algorithm used by the file system should be case-sensitive, case-insensitive, or allow a combination of both styles of matching. The default value for the "\fBcasesensitivity\fR" property is "\fBsensitive\fR." Traditionally, UNIX and POSIX file systems have case-sensitive file names.
     .sp
    -The "\fBmixed\fR" value for the "\fBcasesensitivity\fR" property indicates that the file system can support requests for both case-sensitive and case-insensitive matching behavior. Currently, case-insensitive matching behavior on a file system
    -that supports mixed behavior is limited to the Solaris CIFS server product. For more information about the "mixed" value behavior, see the \fIZFS Administration Guide\fR.
    +The "\fBmixed\fR" value for the "\fBcasesensitivity\fR" property indicates that the file system can support requests for both case-sensitive and case-insensitive matching behavior. Currently, case-insensitive matching behavior on a file system that supports mixed behavior is limited to the Solaris CIFS server product. For more information about the "mixed" value behavior, see the \fIZFS Administration Guide\fR.
     .RE
     
     .sp
    @@ -863,20 +875,7 @@ that supports mixed behavior is limited to the Solaris CIFS server product. For
     .ad
     .sp .6
     .RS 4n
    -Indicates whether the file system should perform a \fBunicode\fR normalization of file names whenever two file names are compared, and which normalization algorithm should be used. File names are always stored unmodified, names are normalized as part of any comparison
    -process. If this property is set to a legal value other than "\fBnone\fR," and the "\fButf8only\fR" property was left unspecified, the "\fButf8only\fR" property is automatically set to "\fBon\fR."
    -The default value of the "\fBnormalization\fR" property is "\fBnone\fR." This property cannot be changed after the file system is created.
    -.RE
    -
    -.sp
    -.ne 2
    -.mk
    -.na
    -\fBjailed =\fIon\fR | \fIoff\fR\fR
    -.ad
    -.sp .6
    -.RS 4n
    -Controls whether the dataset is managed from within a jail. The default value is "off".
    +Indicates whether the file system should perform a \fBunicode\fR normalization of file names whenever two file names are compared, and which normalization algorithm should be used. File names are always stored unmodified, names are normalized as part of any comparison process. If this property is set to a legal value other than "\fBnone\fR," and the "\fButf8only\fR" property was left unspecified, the "\fButf8only\fR" property is automatically set to "\fBon\fR." The default value of the "\fBnormalization\fR" property is "\fBnone\fR." This property cannot be changed after the file system is created.
     .RE
     
     .sp
    @@ -887,63 +886,52 @@ Controls whether the dataset is managed from within a jail. The default value is
     .ad
     .sp .6
     .RS 4n
    -Indicates whether the file system should reject file names that include characters that are not present in the \fBUTF-8\fR character code set. If this property is explicitly set to "\fBoff\fR," the normalization property must either not be
    -explicitly set or be set to "\fBnone\fR." The default value for the "\fButf8only\fR" property is "off." This property cannot be changed after the file system is created.
    +Indicates whether the file system should reject file names that include characters that are not present in the \fBUTF-8\fR character code set. If this property is explicitly set to "\fBoff\fR," the normalization property must either not be explicitly set or be set to "\fBnone\fR." The default value for the "\fButf8only\fR" property is "off." This property cannot be changed after the file system is created.
     .RE
     
     .sp
     .LP
    -The "\fBcasesensitivity\fR," "\fBnormalization\fR," and "\fButf8only\fR" properties are also new permissions that can be assigned to non-privileged users by using the \fBZFS\fR delegated administration
    -feature.
    +The "\fBcasesensitivity\fR," "\fBnormalization\fR," and "\fButf8only\fR" properties are also new permissions that can be assigned to non-privileged users by using the \fBZFS\fR delegated administration feature.
     .SS "Temporary Mount Point Properties"
     .sp
     .LP
    -When a file system is mounted, either through \fBmount\fR(1M) for legacy mounts or the "\fBzfs mount\fR" command for normal file systems,
    -its mount options are set according to its properties. The correlation between properties and mount options is as follows:
    +When a file system is mounted, either through \fBmount\fR(1M) for legacy mounts or the "\fBzfs mount\fR" command for normal file systems, its mount options are set according to its properties. The correlation between properties and mount options is as follows:
     .sp
     .in +2
     .nf
         PROPERTY                MOUNT OPTION
    -    devices                 devices/nodevices
    -    exec                    exec/noexec
    -    readonly                ro/rw
    -    setuid                  setuid/nosetuid
    -    xattr                   xattr/noxattr
    +     devices                 devices/nodevices
    +     exec                    exec/noexec
    +     readonly                ro/rw
    +     setuid                  setuid/nosetuid
    +     xattr                   xattr/noxattr
     .fi
     .in -2
     .sp
     
     .sp
     .LP
    -In addition, these options can be set on a per-mount basis using the \fB-o\fR option, without affecting the property that is stored on disk. The values specified on the command line override the values stored in the dataset. The \fB-nosuid\fR option is an alias for "nodevices,nosetuid".
    -These properties are reported as "temporary" by the "\fBzfs get\fR" command. If the properties are changed while the dataset is mounted, the new setting overrides any temporary settings.
    +In addition, these options can be set on a per-mount basis using the \fB-o\fR option, without affecting the property that is stored on disk. The values specified on the command line override the values stored in the dataset. The \fB-nosuid\fR option is an alias for "nodevices,nosetuid". These properties are reported as "temporary" by the "\fBzfs get\fR" command. If the properties are changed while the dataset is mounted, the new setting overrides any temporary settings.
     .SS "User Properties"
     .sp
     .LP
    -In addition to the standard native properties, \fBZFS\fR supports arbitrary user properties. User properties have no effect on \fBZFS\fR behavior, but applications or administrators can use them to annotate datasets.
    +In addition to the standard native properties, \fBZFS\fR supports arbitrary user properties. User properties have no effect on \fBZFS\fR behavior, but applications or administrators can use them to annotate datasets (file systems, volumes, and snapshots).
     .sp
     .LP
    -User property names must contain a colon (":") character, to distinguish them from native properties. They might contain lowercase letters, numbers, and the following punctuation characters: colon (":"), dash ("-"), period ("."), and underscore
    -("_"). The expected convention is that the property name is divided into two portions such as "\fImodule\fR:\fIproperty\fR", but this namespace is not enforced by \fBZFS\fR. User property names can be at most 256 characters,
    -and cannot begin with a dash ("-").
    +User property names must contain a colon (":") character to distinguish them from native properties. They may contain lowercase letters, numbers, and the following punctuation characters: colon (":"), dash ("-"), period ("."), and underscore ("_"). The expected convention is that the property name is divided into two portions such as "\fImodule\fR:\fIproperty\fR", but this namespace is not enforced by \fBZFS\fR. User property names can be at most 256 characters, and cannot begin with a dash ("-").
     .sp
     .LP
    -When making programmatic use of user properties, it is strongly suggested to use a reversed \fBDNS\fR domain name for the \fImodule\fR component of property names to reduce the chance that two independently-developed packages use the same property name for
    -different purposes. Property names beginning with "com.sun." are reserved for use by Sun Microsystems.
    +When making programmatic use of user properties, it is strongly suggested to use a reversed \fBDNS\fR domain name for the \fImodule\fR component of property names to reduce the chance that two independently-developed packages use the same property name for different purposes. Property names beginning with "com.sun." are reserved for use by Sun Microsystems.
     .sp
     .LP
    -The values of user properties are arbitrary strings, are always inherited, and are never validated. All of the commands that operate on properties ("zfs list", "zfs get", "zfs set", etc.) can be used to manipulate both native properties and user properties.
    -Use the "\fBzfs inherit\fR" command to clear a user property . If the property is not defined in any parent dataset, it is removed entirely. Property values are limited to 1024 characters.
    -.SS "Volumes as Swap or Dump Devices"
    +The values of user properties are arbitrary strings, are always inherited, and are never validated. All of the commands that operate on properties ("zfs list", "zfs get", "zfs set", etc.) can be used to manipulate both native properties and user properties. Use the "\fBzfs inherit\fR" command to clear a user property . If the property is not defined in any parent dataset, it is removed entirely. Property values are limited to 1024 characters.
    +.SS "ZFS Volumes as Swap or Dump Devices"
     .sp
     .LP
    -To set up a swap area, create a \fBZFS\fR volume of a specific size and then enable swap on that device. For more information, see the EXAMPLES section.
    +During an initial installation or a live upgrade from a \fBUFS\fR file system, a swap device and dump device are created on \fBZFS\fR volumes in the \fBZFS\fR root pool. By default, the swap area size is based on 1/2 the size of physical memory up to 2 Gbytes. The size of the dump device depends on the kernel's requirements at installation time. Separate \fBZFS\fR volumes must be used for the swap area and dump devices. Do not swap to a file on a \fBZFS\fR file system. A \fBZFS\fR swap file configuration is not supported. 
     .sp
     .LP
    -Do not swap to a file on a \fBZFS\fR file system. A \fBZFS\fR swap file configuration is not supported.
    -.sp
    -.LP
    -Using a \fBZFS\fR volume as a dump device is not supported.
    +If you need to change your swap area or dump device after the system is installed or upgraded, use the \fBswap\fR(1M) and \fBdumpadm\fR(1M) commands. If you need to change the size of your swap area or dump device, see the \fISolaris ZFS Administration Guide\fR.
     .SH SUBCOMMANDS
     .sp
     .LP
    @@ -974,10 +962,9 @@ Creates a new \fBZFS\fR file system. The file system is automatically mounted ac
     .na
     \fB\fB-p\fR\fR
     .ad
    -.RS 21n
    -.rt  
    -Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. Any property specified on the command line using the \fB-o\fR option is ignored. If
    -the target filesystem already exists, the operation completes successfully.
    +.sp .6
    +.RS 4n
    +Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. Any property specified on the command line using the \fB-o\fR option is ignored. If the target filesystem already exists, the operation completes successfully.
     .RE
     
     .sp
    @@ -986,10 +973,9 @@ the target filesystem already exists, the operation completes successfully.
     .na
     \fB\fB-o\fR \fIproperty\fR=\fIvalue\fR\fR
     .ad
    -.RS 21n
    -.rt  
    -Sets the specified property as if "\fBzfs set property=value\fR" was invoked at the same time the dataset was created. Any editable \fBZFS\fR property can also be set at creation time. Multiple \fB-o\fR options can be specified. An
    -error results if the same property is specified in multiple \fB-o\fR options.
    +.sp .6
    +.RS 4n
    +Sets the specified property as if "\fBzfs set property=value\fR" was invoked at the same time the dataset was created. Any editable \fBZFS\fR property can also be set at creation time. Multiple \fB-o\fR options can be specified. An error results if the same property is specified in multiple \fB-o\fR options.
     .RE
     
     .RE
    @@ -1002,8 +988,7 @@ error results if the same property is specified in multiple \fB-o\fR options.
     .ad
     .sp .6
     .RS 4n
    -Creates a volume of the given size. The volume is exported as a block device in \fB/dev/zvol/{dsk,rdsk}/\fIpath\fR\fR, where \fIpath\fR is the name of the volume in the \fBZFS\fR namespace. The size represents
    -the logical size as exported by the device. By default, a reservation of equal size is created.
    +Creates a volume of the given size. The volume is exported as a block device in \fB/dev/zvol/{dsk,rdsk}/\fIpath\fR\fR, where \fIpath\fR is the name of the volume in the \fBZFS\fR namespace. The size represents the logical size as exported by the device. By default, a reservation of equal size is created.
     .sp
     \fIsize\fR is automatically rounded up to the nearest 128 Kbytes to ensure that the volume has an integral number of blocks regardless of \fIblocksize\fR.
     .sp
    @@ -1012,10 +997,9 @@ the logical size as exported by the device. By default, a reservation of equal s
     .na
     \fB\fB-p\fR\fR
     .ad
    -.RS 21n
    -.rt  
    -Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. Any property specified on the command line using the \fB-o\fR option is ignored. If
    -the target filesystem already exists, the operation completes successfully.
    +.sp .6
    +.RS 4n
    +Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. Any property specified on the command line using the \fB-o\fR option is ignored. If the target filesystem already exists, the operation completes successfully.
     .RE
     
     .sp
    @@ -1024,8 +1008,8 @@ the target filesystem already exists, the operation completes successfully.
     .na
     \fB\fB-s\fR\fR
     .ad
    -.RS 21n
    -.rt  
    +.sp .6
    +.RS 4n
     Creates a sparse volume with no reservation. See "volsize" in the Native Properties section for more information about sparse volumes.
     .RE
     
    @@ -1035,10 +1019,9 @@ Creates a sparse volume with no reservation. See "volsize" in the Native Propert
     .na
     \fB\fB-o\fR \fIproperty\fR=\fIvalue\fR\fR
     .ad
    -.RS 21n
    -.rt  
    -Sets the specified property as if "\fBzfs set property=value\fR" was invoked at the same time the dataset was created. Any editable \fBZFS\fR property can also be set at creation time. Multiple \fB-o\fR options can be specified. An
    -error results if the same property is specified in multiple \fB-o\fR options.
    +.sp .6
    +.RS 4n
    +Sets the specified property as if "\fBzfs set property=value\fR" was invoked at the same time the dataset was created. Any editable \fBZFS\fR property can also be set at creation time. Multiple \fB-o\fR options can be specified. An error results if the same property is specified in multiple \fB-o\fR options.
     .RE
     
     .sp
    @@ -1047,10 +1030,9 @@ error results if the same property is specified in multiple \fB-o\fR options.
     .na
     \fB\fB-b\fR \fIblocksize\fR\fR
     .ad
    -.RS 21n
    -.rt  
    -Equivalent to "\fB\fR\fB-o\fR \fBvolblocksize=\fIblocksize\fR\fR". If this option is specified in conjunction with "\fB\fR\fB-o\fR \fBvolblocksize\fR", the resulting
    -behavior is undefined.
    +.sp .6
    +.RS 4n
    +Equivalent to "\fB\fR\fB-o\fR \fBvolblocksize=\fIblocksize\fR\fR". If this option is specified in conjunction with "\fB\fR\fB-o\fR \fBvolblocksize\fR", the resulting behavior is undefined.
     .RE
     
     .RE
    @@ -1070,8 +1052,8 @@ Destroys the given dataset. By default, the command unshares any file systems th
     .na
     \fB\fB-r\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Recursively destroy all children. If a snapshot is specified, destroy all snapshots with this name in descendent file systems.
     .RE
     
    @@ -1081,8 +1063,8 @@ Recursively destroy all children. If a snapshot is specified, destroy all snapsh
     .na
     \fB\fB-R\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Recursively destroy all dependents, including cloned file systems outside the target hierarchy. If a snapshot is specified, destroy all snapshots with this name in descendent file systems.
     .RE
     
    @@ -1092,8 +1074,8 @@ Recursively destroy all dependents, including cloned file systems outside the ta
     .na
     \fB\fB-f\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Force an unmount of any file systems using the "\fBunmount -f\fR" command. This option has no effect on non-file systems or unmounted file systems.
     .RE
     
    @@ -1104,7 +1086,7 @@ Extreme care should be taken when applying either the \fB-r\fR or the \fB-f\fR o
     .ne 2
     .mk
     .na
    -\fB\fBzfs snapshot\fR [\fB-r\fR] \fIfilesystem@snapname\fR|\fIvolume@snapname\fR\fR
    +\fB\fBzfs snapshot\fR [\fB-r\fR] [\fB-o\fR \fIproperty\fR=\fIvalue\fR] ... \fIfilesystem@snapname\fR|\fIvolume@snapname\fR\fR
     .ad
     .sp .6
     .RS 4n
    @@ -1115,11 +1097,22 @@ Creates a snapshot with the given name. See the "Snapshots" section for details.
     .na
     \fB\fB-r\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Recursively create snapshots of all descendent datasets. Snapshots are taken atomically, so that all recursive snapshots correspond to the same moment in time.
     .RE
     
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fB\fB-o\fR \fIproperty\fR=\fIvalue\fR\fR
    +.ad
    +.sp .6
    +.RS 4n
    +Sets the specified property; see "\fBzfs create\fR" for details.
    +.RE
    +
     .RE
     
     .sp
    @@ -1130,16 +1123,15 @@ Recursively create snapshots of all descendent datasets. Snapshots are taken ato
     .ad
     .sp .6
     .RS 4n
    -Roll back the given dataset to a previous snapshot. When a dataset is rolled back, all data that has changed since the snapshot is discarded, and the dataset reverts to the state at the time of the snapshot. By default, the command refuses to roll back to a snapshot other than
    -the most recent one. In order to do so, all intermediate snapshots must be destroyed by specifying the \fB-r\fR option.
    +Roll back the given dataset to a previous snapshot. When a dataset is rolled back, all data that has changed since the snapshot is discarded, and the dataset reverts to the state at the time of the snapshot. By default, the command refuses to roll back to a snapshot other than the most recent one. In order to do so, all intermediate snapshots must be destroyed by specifying the \fB-r\fR option.
     .sp
     .ne 2
     .mk
     .na
     \fB\fB-r\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Recursively destroy any snapshots more recent than the one specified.
     .RE
     
    @@ -1149,8 +1141,8 @@ Recursively destroy any snapshots more recent than the one specified.
     .na
     \fB\fB-R\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Recursively destroy any more recent snapshots, as well as any clones of those snapshots.
     .RE
     
    @@ -1160,8 +1152,8 @@ Recursively destroy any more recent snapshots, as well as any clones of those sn
     .na
     \fB\fB-f\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Used with the \fB-R\fR option to force an unmount of any clone file systems that are to be destroyed.
     .RE
     
    @@ -1171,7 +1163,7 @@ Used with the \fB-R\fR option to force an unmount of any clone file systems that
     .ne 2
     .mk
     .na
    -\fB\fBzfs clone\fR [\fB-p\fR] \fIsnapshot\fR \fIfilesystem\fR|\fIvolume\fR\fR
    +\fB\fBzfs clone\fR [\fB-p\fR] [\fB-o\fR \fIproperty\fR=\fIvalue\fR] ... \fIsnapshot\fR \fIfilesystem\fR|\fIvolume\fR\fR
     .ad
     .sp .6
     .RS 4n
    @@ -1182,11 +1174,22 @@ Creates a clone of the given snapshot. See the "Clones" section for details. The
     .na
     \fB\fB-p\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent. If the target filesystem or volume already exists, the operation completes successfully.
     .RE
     
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fB\fB-o\fR \fIproperty\fR=\fIvalue\fR\fR
    +.ad
    +.sp .6
    +.RS 4n
    +Sets the specified property; see "\fBzfs create\fR" for details.
    +.RE
    +
     .RE
     
     .sp
    @@ -1197,11 +1200,9 @@ Creates all the non-existing parent datasets. Datasets created in this manner ar
     .ad
     .sp .6
     .RS 4n
    -Promotes a clone file system to no longer be dependent on its "origin" snapshot. This makes it possible to destroy the file system that the clone was created from. The clone parent-child dependency relationship is reversed, so that the "origin" file system
    -becomes a clone of the specified file system. 
    +Promotes a clone file system to no longer be dependent on its "origin" snapshot. This makes it possible to destroy the file system that the clone was created from. The clone parent-child dependency relationship is reversed, so that the "origin" file system becomes a clone of the specified file system. 
     .sp
    -The snapshot that was cloned, and any snapshots previous to this snapshot, are now owned by the promoted clone. The space they use moves from the "origin" file system to the promoted clone, so enough space must be available to accommodate these snapshots. No new space is consumed
    -by this operation, but the space accounting is adjusted. The promoted clone must not have any conflicting snapshot names of its own. The "\fBrename\fR" subcommand can be used to rename any conflicting snapshots.
    +The snapshot that was cloned, and any snapshots previous to this snapshot, are now owned by the promoted clone. The space they use moves from the "origin" file system to the promoted clone, so enough space must be available to accommodate these snapshots. No new space is consumed by this operation, but the space accounting is adjusted. The promoted clone must not have any conflicting snapshot names of its own. The "\fBrename\fR" subcommand can be used to rename any conflicting snapshots.
     .RE
     
     .sp
    @@ -1216,21 +1217,19 @@ by this operation, but the space accounting is adjusted. The promoted clone must
     .ad
     .br
     .na
    -\fB\fBzfs
    -rename\fR [\fB-p\fR] \fIfilesystem\fR|\fIvolume\fR \fIfilesystem\fR|\fIvolume\fR\fR
    +\fB\fBzfs rename\fR [\fB-p\fR] \fIfilesystem\fR|\fIvolume\fR \fIfilesystem\fR|\fIvolume\fR\fR
     .ad
     .sp .6
     .RS 4n
    -Renames the given dataset. The new target can be located anywhere in the \fBZFS\fR hierarchy, with the exception of snapshots. Snapshots can only be renamed within the parent file system or volume. When renaming a snapshot, the parent file system of the snapshot does
    -not need to be specified as part of the second argument. Renamed file systems can inherit new mount points, in which case they are unmounted and remounted at the new mount point.
    +Renames the given dataset. The new target can be located anywhere in the \fBZFS\fR hierarchy, with the exception of snapshots. Snapshots can only be renamed within the parent file system or volume. When renaming a snapshot, the parent file system of the snapshot does not need to be specified as part of the second argument. Renamed file systems can inherit new mount points, in which case they are unmounted and remounted at the new mount point.
     .sp
     .ne 2
     .mk
     .na
     \fB\fB-p\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Creates all the non-existing parent datasets. Datasets created in this manner are automatically mounted according to the "mountpoint" property inherited from their parent.
     .RE
     
    @@ -1259,7 +1258,7 @@ Recursively rename the snapshots of all descendent datasets. Snapshots are the o
     .ad
     .sp .6
     .RS 4n
    -Lists the property information for the given datasets in tabular form. If specified, you can list property information by the absolute pathname or the relative pathname. By default, all datasets are displayed and contain the following fields:
    +Lists the property information for the given datasets in tabular form. If specified, you can list property information by the absolute pathname or the relative pathname. By default, all file systems and volumes are displayed. Snapshots are displayed if the "listsnaps" property is "on" (the default is "off") . The following fields are displayed:
     .sp
     .in +2
     .nf
    @@ -1274,8 +1273,8 @@ name,used,available,referenced,mountpoint
     .na
     \fB\fB-H\fR\fR
     .ad
    -.RS 15n
    -.rt  
    +.sp .6
    +.RS 4n
     Used for scripting mode. Do not print headers and separate fields by a single tab instead of arbitrary whitespace.
     .RE
     
    @@ -1285,8 +1284,8 @@ Used for scripting mode. Do not print headers and separate fields by a single ta
     .na
     \fB\fB-r\fR\fR
     .ad
    -.RS 15n
    -.rt  
    +.sp .6
    +.RS 4n
     Recursively display any children of the dataset on the command line. 
     .RE
     
    @@ -1296,9 +1295,33 @@ Recursively display any children of the dataset on the command line.
     .na
     \fB\fB-o\fR \fIproperty\fR\fR
     .ad
    -.RS 15n
    -.rt  
    -A comma-separated list of properties to display. The property must be one of the properties described in the "Native Properties" section, or the special value "name" to display the dataset name.
    +.sp .6
    +.RS 4n
    +A comma-separated list of properties to display. The property must be:
    +.RS +4
    +.TP
    +.ie t \(bu
    +.el o
    +one of the properties described in the "Native Properties" section.
    +.RE
    +.RS +4
    +.TP
    +.ie t \(bu
    +.el o
    +a user property.
    +.RE
    +.RS +4
    +.TP
    +.ie t \(bu
    +.el o
    +the value "name" to display the dataset name.
    +.RE
    +.RS +4
    +.TP
    +.ie t \(bu
    +.el o
    +the value "space" to display space usage properties on file systems and volumes. This is a shortcut for "\fB-o name,avail,used,usedsnap,usedds, usedrefreserv,usedchild -t filesystem,volume\fR".
    +.RE
     .RE
     
     .sp
    @@ -1307,10 +1330,9 @@ A comma-separated list of properties to display. The property must be one of the
     .na
     \fB\fB-s\fR \fIproperty\fR\fR
     .ad
    -.RS 15n
    -.rt  
    -A property to use for sorting the output by column in ascending order based on the value of the property. The property must be one of the properties described in the "Properties" section, or the special value "name" to sort by the dataset name. Multiple
    -properties can be specified at one time using multiple \fB-s\fR property options. Multiple \fB-s\fR options are evaluated from left to right in decreasing order of importance.
    +.sp .6
    +.RS 4n
    +A property to use for sorting the output by column in ascending order based on the value of the property. The property must be one of the properties described in the "Properties" section, or the special value "name" to sort by the dataset name. Multiple properties can be specified at one time using multiple \fB-s\fR property options. Multiple \fB-s\fR options are evaluated from left to right in decreasing order of importance.
     .sp
     The following is a list of sorting criteria:
     .RS +4
    @@ -1345,8 +1367,8 @@ If no sorting options are specified the existing behavior of "\fBzfs list\fR" is
     .na
     \fB\fB-S\fR \fIproperty\fR\fR
     .ad
    -.RS 15n
    -.rt  
    +.sp .6
    +.RS 4n
     Same as the \fB-s\fR option, but sorts by property in descending order. 
     .RE
     
    @@ -1356,9 +1378,9 @@ Same as the \fB-s\fR option, but sorts by property in descending order.
     .na
     \fB\fB-t\fR \fItype\fR\fR
     .ad
    -.RS 15n
    -.rt  
    -A comma-separated list of types to display, where "type" is one of "filesystem", "snapshot" or "volume". For example, specifying "\fB-t snapshot\fR" displays only snapshots.
    +.sp .6
    +.RS 4n
    +A comma-separated list of types to display, where "type" is one of "filesystem", "snapshot" , "volume" or "all". For example, specifying "\fB-t snapshot\fR" displays only snapshots.
     .RE
     
     .RE
    @@ -1367,12 +1389,11 @@ A comma-separated list of types to display, where "type" is one of "filesystem",
     .ne 2
     .mk
     .na
    -\fB\fBzfs set\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR ...\fR
    +\fB\fBzfs set\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...\fR
     .ad
     .sp .6
     .RS 4n
    -Sets the property to the given value for each dataset. Only some properties can be edited. See the "Properties" section for more information on what properties can be set and acceptable values. Numeric values can be specified as exact values, or in a human-readable
    -form with a suffix of "B", "K", "M", "G", "T", "P", "E", "Z" (for bytes, Kbytes, Mbytes, gigabytes, terabytes, petabytes, exabytes, or zettabytes, respectively). Properties cannot be set on snapshots.
    +Sets the property to the given value for each dataset. Only some properties can be edited. See the "Properties" section for more information on what properties can be set and acceptable values. Numeric values can be specified as exact values, or in a human-readable form with a suffix of "B", "K", "M", "G", "T", "P", "E", "Z" (for bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, or zettabytes, respectively). Properties cannot be set on snapshots.
     .RE
     
     .sp
    @@ -1388,25 +1409,25 @@ Displays properties for the given datasets. If no datasets are specified, then t
     .in +2
     .nf
         name      Dataset name
    -    property  Property name
    -    value     Property value
    -    source    Property source. Can either be local, default,
    -              temporary, inherited, or none (-).
    +     property  Property name
    +     value     Property value
    +     source    Property source. Can either be local, default,
    +               temporary, inherited, or none (-).
     .fi
     .in -2
     .sp
     
     All columns are displayed by default, though this can be controlled by using the \fB-o\fR option. This command takes a comma-separated list of properties as described in the "Native Properties" and "User Properties" sections.
     .sp
    -The special value "all" can be used to display all properties for the given dataset.
    +The special value "all" can be used to display all properties that apply to the given dataset's type (filesystem, volume or snapshot).
     .sp
     .ne 2
     .mk
     .na
     \fB\fB-r\fR\fR
     .ad
    -.RS 13n
    -.rt  
    +.sp .6
    +.RS 4n
     Recursively display properties for any children.
     .RE
     
    @@ -1416,8 +1437,8 @@ Recursively display properties for any children.
     .na
     \fB\fB-H\fR\fR
     .ad
    -.RS 13n
    -.rt  
    +.sp .6
    +.RS 4n
     Display output in a form more easily parsed by scripts. Any headers are omitted, and fields are explicitly separated by a single tab instead of an arbitrary amount of space.
     .RE
     
    @@ -1427,8 +1448,8 @@ Display output in a form more easily parsed by scripts. Any headers are omitted,
     .na
     \fB\fB-o\fR \fIfield\fR\fR
     .ad
    -.RS 13n
    -.rt  
    +.sp .6
    +.RS 4n
     A comma-separated list of columns to display. "name,property,value,source" is the default value. 
     .RE
     
    @@ -1438,8 +1459,8 @@ A comma-separated list of columns to display. "name,property,value,source" is th
     .na
     \fB\fB-s\fR \fIsource\fR\fR
     .ad
    -.RS 13n
    -.rt  
    +.sp .6
    +.RS 4n
     A comma-separated list of sources to display. Those properties coming from a source other than those in this list are ignored. Each source must be one of the following: "local,default,inherited,temporary,none". The default value is all sources.
     .RE
     
    @@ -1449,8 +1470,8 @@ A comma-separated list of sources to display. Those properties coming from a sou
     .na
     \fB\fB-p\fR\fR
     .ad
    -.RS 13n
    -.rt  
    +.sp .6
    +.RS 4n
     Display numbers in parsable (exact) values.
     .RE
     
    @@ -1460,7 +1481,7 @@ Display numbers in parsable (exact) values.
     .ne 2
     .mk
     .na
    -\fB\fBzfs inherit\fR [\fB-r\fR] \fIproperty\fR \fIfilesystem\fR|\fIvolume\fR ...\fR
    +\fB\fBzfs inherit\fR [\fB-r\fR] \fIproperty\fR \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...\fR
     .ad
     .sp .6
     .RS 4n
    @@ -1471,8 +1492,8 @@ Clears the specified property, causing it to be inherited from an ancestor. If n
     .na
     \fB\fB-r\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Recursively inherit the given property for all children.
     .RE
     
    @@ -1497,8 +1518,7 @@ Displays a list of file systems that are not the most recent version.
     .ad
     .sp .6
     .RS 4n
    -Upgrades file systems to a new on-disk version. Once this is done, the file systems will no longer be accessible on systems running older versions of the software. "\fBzfs send\fR" streams generated from new snapshots of these file systems can not be accessed
    -on systems running older versions of the software.
    +Upgrades file systems to a new on-disk version. Once this is done, the file systems will no longer be accessible on systems running older versions of the software. "\fBzfs send\fR" streams generated from new snapshots of these file systems can not be accessed on systems running older versions of the software.
     .sp
     The file system version is independent of the pool version (see \fBzpool\fR(1M) for information on the "\fBzpool upgrade\fR" command). 
     .sp
    @@ -1509,8 +1529,8 @@ The file system version does not have to be upgraded when the pool version is up
     .na
     \fB\fB-a\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     Upgrade all file systems on all imported pools.
     .RE
     
    @@ -1520,8 +1540,8 @@ Upgrade all file systems on all imported pools.
     .na
     \fB\fIfilesystem\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     Upgrade the specified file system. 
     .RE
     
    @@ -1531,8 +1551,8 @@ Upgrade the specified file system.
     .na
     \fB\fB-r\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     Upgrade the specified file system and all descendent file systems 
     .RE
     
    @@ -1542,10 +1562,9 @@ Upgrade the specified file system and all descendent file systems
     .na
     \fB\fB-V\fR \fIversion\fR\fR
     .ad
    -.RS 14n
    -.rt  
    -Upgrade to the specified \fIversion\fR. If the \fB-V\fR flag is not specified, this command upgrades to the most recent version. This option can only be used to increase the version number, and only up to the most recent version supported by this
    -software.
    +.sp .6
    +.RS 4n
    +Upgrade to the specified \fIversion\fR. If the \fB-V\fR flag is not specified, this command upgrades to the most recent version. This option can only be used to increase the version number, and only up to the most recent version supported by this software.
     .RE
     
     .RE
    @@ -1576,8 +1595,8 @@ Mounts \fBZFS\fR file systems. Invoked automatically as part of the boot process
     .na
     \fB\fB-o\fR \fIoptions\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     An optional comma-separated list of mount options to use temporarily for the duration of the mount. See the "Temporary Mount Point Properties" section for details.
     .RE
     
    @@ -1587,8 +1606,8 @@ An optional comma-separated list of mount options to use temporarily for the dur
     .na
     \fB\fB-O\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     Perform an overlay mount. See \fBmount\fR(1M) for more information.
     .RE
     
    @@ -1598,8 +1617,8 @@ Perform an overlay mount. See \fBmount\fR(1M) for more information.
     .na
     \fB\fB-v\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     Report mount progress.
     .RE
     
    @@ -1609,8 +1628,8 @@ Report mount progress.
     .na
     \fB\fB-a\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     Mount all available \fBZFS\fR file systems. Invoked automatically as part of the boot process. 
     .RE
     
    @@ -1620,8 +1639,8 @@ Mount all available \fBZFS\fR file systems. Invoked automatically as part of the
     .na
     \fB\fIfilesystem\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     Mount the specified filesystem.
     .RE
     
    @@ -1642,8 +1661,8 @@ Unmounts currently mounted \fBZFS\fR file systems. Invoked automatically as part
     .na
     \fB\fB-f\fR\fR
     .ad
    -.RS 25n
    -.rt  
    +.sp .6
    +.RS 4n
     Forcefully unmount the file system, even if it is currently in use.
     .RE
     
    @@ -1653,8 +1672,8 @@ Forcefully unmount the file system, even if it is currently in use.
     .na
     \fB\fB-a\fR\fR
     .ad
    -.RS 25n
    -.rt  
    +.sp .6
    +.RS 4n
     Unmount all available \fBZFS\fR file systems. Invoked automatically as part of the boot process. 
     .RE
     
    @@ -1664,8 +1683,8 @@ Unmount all available \fBZFS\fR file systems. Invoked automatically as part of t
     .na
     \fB\fIfilesystem\fR|\fImountpoint\fR\fR
     .ad
    -.RS 25n
    -.rt  
    +.sp .6
    +.RS 4n
     Unmount the specified filesystem. The command can also be given a path to a \fBZFS\fR file system mount point on the system.
     .RE
     
    @@ -1686,8 +1705,8 @@ Shares available \fBZFS\fR file systems.
     .na
     \fB\fB-a\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     Share all available \fBZFS\fR file systems. Invoked automatically as part of the boot process. 
     .RE
     
    @@ -1697,8 +1716,8 @@ Share all available \fBZFS\fR file systems. Invoked automatically as part of the
     .na
     \fB\fIfilesystem\fR\fR
     .ad
    -.RS 14n
    -.rt  
    +.sp .6
    +.RS 4n
     Share the specified filesystem according to the "sharenfs" and "sharesmb" properties. File systems are shared when the "sharenfs" or "sharesmb" property is set.
     .RE
     
    @@ -1719,8 +1738,8 @@ Unshares currently shared \fBZFS\fR file systems. This is invoked automatically
     .na
     \fB\fB-a\fR\fR
     .ad
    -.RS 25n
    -.rt  
    +.sp .6
    +.RS 4n
     Unshare all available \fBZFS\fR file systems. Invoked automatically as part of the boot process. 
     .RE
     
    @@ -1730,8 +1749,8 @@ Unshare all available \fBZFS\fR file systems. Invoked automatically as part of t
     .na
     \fB\fIfilesystem\fR|\fImountpoint\fR\fR
     .ad
    -.RS 25n
    -.rt  
    +.sp .6
    +.RS 4n
     Unshare the specified filesystem. The command can also be given a path to a \fBZFS\fR file system shared on the system.
     .RE
     
    @@ -1741,7 +1760,7 @@ Unshare the specified filesystem. The command can also be given a path to a \fBZ
     .ne 2
     .mk
     .na
    -\fB\fBzfs send\fR [\fB-vR\fR] [\fB-\fR[\fB-iI\fR] \fIsnapshot\fR] \fIsnapshot\fR\fR
    +\fB\fBzfs send\fR [\fB-vR\fR] [\fB-\fR[\fBiI\fR] \fIsnapshot\fR] \fIsnapshot\fR\fR
     .ad
     .sp .6
     .RS 4n
    @@ -1752,10 +1771,9 @@ Creates a stream representation of the second \fIsnapshot\fR, which is written t
     .na
     \fB\fB-i\fR \fIsnapshot\fR\fR
     .ad
    -.RS 15n
    -.rt  
    -Generate an incremental stream from the first \fIsnapshot\fR to the second \fIsnapshot\fR. The incremental source (the first \fIsnapshot\fR) can be specified as the last component of the snapshot name (for example,
    -the part after the "@"), and it is assumed to be from the same file system as the second \fIsnapshot\fR.
    +.sp .6
    +.RS 4n
    +Generate an incremental stream from the first \fIsnapshot\fR to the second \fIsnapshot\fR. The incremental source (the first \fIsnapshot\fR) can be specified as the last component of the snapshot name (for example, the part after the "@"), and it is assumed to be from the same file system as the second \fIsnapshot\fR.
     .sp
     If the destination is a clone, the source may be the origin snapshot, which must be fully specified (for example, "pool/fs@origin", not just "@origin").
     .RE
    @@ -1766,10 +1784,9 @@ If the destination is a clone, the source may be the origin snapshot, which must
     .na
     \fB\fB-I\fR \fIsnapshot\fR\fR
     .ad
    -.RS 15n
    -.rt  
    -Generate a stream package that sends all intermediary snapshots from the first snapshot to the second snapshot. For example, "\fB-I @a fs@d\fR" is similar to "\fB-i @a fs@b; -i @b fs@c; -i @c fs@d\fR". The incremental source snapshot
    -may be specified as with the \fB-i\fR option.
    +.sp .6
    +.RS 4n
    +Generate a stream package that sends all intermediary snapshots from the first snapshot to the second snapshot. For example, "\fB-I @a fs@d\fR" is similar to "\fB-i @a fs@b; -i @b fs@c; -i @c fs@d\fR". The incremental source snapshot may be specified as with the \fB-i\fR option.
     .RE
     
     .sp
    @@ -1778,8 +1795,8 @@ may be specified as with the \fB-i\fR option.
     .na
     \fB\fB-R\fR\fR
     .ad
    -.RS 15n
    -.rt  
    +.sp .6
    +.RS 4n
     Generate a replication stream package, which will replicate the specified filesystem, and all descendant file systems, up to the named snapshot. When received, all properties, snapshots, descendent file systems, and clones are preserved.
     .sp
     If the \fB-i\fR or \fB-I\fR flags are used in conjunction with the \fB-R\fR flag, an incremental replication stream is generated. The current values of properties, and current snapshot and file system names are set when the stream is received. If the \fB-F\fR flag is specified when this stream is recieved, snapshots and file systems that do not exist on the sending side are destroyed. 
    @@ -1791,8 +1808,8 @@ If the \fB-i\fR or \fB-I\fR flags are used in conjunction with the \fB-R\fR flag
     .na
     \fB\fB-v\fR\fR
     .ad
    -.RS 15n
    -.rt  
    +.sp .6
    +.RS 4n
     Print verbose information about the stream package generated.
     .RE
     
    @@ -1811,24 +1828,21 @@ The format of the stream is evolving. No backwards compatibility is guaranteed.
     .ad
     .sp .6
     .RS 4n
    -Creates a snapshot whose contents are as specified in the stream provided on standard input. If a full stream is received, then a new file system is created as well. Streams are created using the "\fBzfs send\fR" subcommand, which by default creates a full
    -stream. "\fBzfs recv\fR" can be used as an alias for "\fBzfs receive\fR".
    +Creates a snapshot whose contents are as specified in the stream provided on standard input. If a full stream is received, then a new file system is created as well. Streams are created using the "\fBzfs send\fR" subcommand, which by default creates a full stream. "\fBzfs recv\fR" can be used as an alias for "\fBzfs receive\fR".
     .sp
    -If an incremental stream is received, then the destination file system must already exist, and its most recent snapshot must match the incremental stream's source. For \fBzvols\fR, the destination device link is destroyed and re-created, which means the \fBzvol\fR cannot
    -be accessed during the \fBreceive\fR operation.
    +If an incremental stream is received, then the destination file system must already exist, and its most recent snapshot must match the incremental stream's source. For \fBzvols\fR, the destination device link is destroyed and re-created, which means the \fBzvol\fR cannot be accessed during the \fBreceive\fR operation.
     .sp
     The name of the snapshot (and file system, if a full stream is received) that this subcommand creates depends on the argument type and the \fB-d\fR option.
     .sp
    -If the argument is a snapshot name, the specified \fIsnapshot\fR is created. If the argument is a file system or volume name, a snapshot with the same name as the sent snapshot is created within the specified \fIfilesystem\fR or \fIvolume\fR.
    -If the \fB-d\fR option is specified, the snapshot name is determined by appending the sent snapshot's name to the specified \fIfilesystem\fR. If the \fB-d\fR option is specified, any required file systems within the specified one are created.
    +If the argument is a snapshot name, the specified \fIsnapshot\fR is created. If the argument is a file system or volume name, a snapshot with the same name as the sent snapshot is created within the specified \fIfilesystem\fR or \fIvolume\fR. If the \fB-d\fR option is specified, the snapshot name is determined by appending the sent snapshot's name to the specified \fIfilesystem\fR. If the \fB-d\fR option is specified, any required file systems within the specified one are created.
     .sp
     .ne 2
     .mk
     .na
     \fB\fB-d\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Use the name of the sent snapshot to determine the name of the new snapshot as described in the paragraph above.
     .RE
     
    @@ -1838,8 +1852,8 @@ Use the name of the sent snapshot to determine the name of the new snapshot as d
     .na
     \fB\fB-v\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Print verbose information about the stream and the time required to perform the receive operation.
     .RE
     
    @@ -1849,8 +1863,8 @@ Print verbose information about the stream and the time required to perform the
     .na
     \fB\fB-n\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Do not actually receive the stream. This can be useful in conjunction with the \fB-v\fR option to verify the name the receive operation would use.
     .RE
     
    @@ -1860,10 +1874,9 @@ Do not actually receive the stream. This can be useful in conjunction with the \
     .na
     \fB\fB-F\fR\fR
     .ad
    -.RS 6n
    -.rt  
    -Force a rollback of the file system to the most recent snapshot before performing the receive operation. If receiving an incremental replication stream (for example, one generated by "z\fBfs send -R -[iI]\fR"), destroy snapshots and file systems that do
    -not exist on the sending side.
    +.sp .6
    +.RS 4n
    +Force a rollback of the file system to the most recent snapshot before performing the receive operation. If receiving an incremental replication stream (for example, one generated by "z\fBfs send -R -[iI]\fR"), destroy snapshots and file systems that do not exist on the sending side.
     .RE
     
     .RE
    @@ -1889,8 +1902,7 @@ Delegates \fBZFS\fR administration permission for the file systems to non-privil
     .ad
     .sp .6
     .RS 4n
    -Specifies to whom the permissions are delegated. Multiple entities can be specified as a comma-separated list. If neither of the \fB-ug\fR options are specified, then the argument is interpreted preferentially as the keyword "everyone", then as a user name,
    -and lastly as a group name. To specify a user or group named "everyone", use the \fB-u\fR or \fB-g\fR options. To specify a group with the same name as a user, use the \fB-g\fR options.
    +Specifies to whom the permissions are delegated. Multiple entities can be specified as a comma-separated list. If neither of the \fB-ug\fR options are specified, then the argument is interpreted preferentially as the keyword "everyone", then as a user name, and lastly as a group name. To specify a user or group named "everyone", use the \fB-u\fR or \fB-g\fR options. To specify a group with the same name as a user, use the \fB-g\fR options.
     .RE
     
     .sp
    @@ -1901,8 +1913,7 @@ and lastly as a group name. To specify a user or group named "everyone", use the
     .ad
     .sp .6
     .RS 4n
    -Specifies that the permissions be delegated to "everyone." Multiple permissions may be specified as a comma-separated list. Permission names are the same as \fBZFS\fR subcommand and property names. See the property list below. Property set names, which
    -begin with an "at sign" ("@") , may be specified. See the \fB-s\fR form below for details.
    +Specifies that the permissions be delegated to "everyone." Multiple permissions may be specified as a comma-separated list. Permission names are the same as \fBZFS\fR subcommand and property names. See the property list below. Property set names, which begin with an "at sign" ("@") , may be specified. See the \fB-s\fR form below for details.
     .RE
     
     .sp
    @@ -1913,8 +1924,7 @@ begin with an "at sign" ("@") , may be specified. See the \fB-s\fR form below fo
     .ad
     .sp .6
     .RS 4n
    -Specifies where the permissions are delegated. If neither of the \fB-ld\fR options are specified, or both are, then the permissions are allowed for the file system or volume, and all of its descendents. If only the \fB-l\fR option is used, then is allowed "locally"
    -only for the specified file system. If only the \fB-d\fR option is used, then is allowed only for the descendent file systems.
    +Specifies where the permissions are delegated. If neither of the \fB-ld\fR options are specified, or both are, then the permissions are allowed for the file system or volume, and all of its descendents. If only the \fB-l\fR option is used, then is allowed "locally" only for the specified file system. If only the \fB-d\fR option is used, then is allowed only for the descendent file systems.
     .RE
     
     .RE
    @@ -1927,49 +1937,51 @@ Permissions are generally the ability to use a \fBZFS\fR subcommand or change a
     .nf
     NAME         TYPE         NOTES
     allow        subcommand   Must also have the permission
    -                          that is being allowed.
    +                           that is being allowed.
     clone        subcommand   Must also have the 'create' ability
    -                          and the 'mount' ability in the origin 
    -                          file system.
    +                           and the 'mount' ability in the origin 
    +                           file system.
     create       subcommand   Must also have the 'mount' ability.
     destroy      subcommand   Must also have the 'mount' ability.     
     mount        subcommand   Allows mount, unmount, and
    -                          create/remove zvol device links.
    +                           create/remove zvol device links.
     promote      subcommand   Must also have the 'mount' ability and
    -                          'promote' ability in the origin file system.    
    +                           'promote' ability in the origin file system.    
     receive      subcommand   Must also have the 'mount' ability and 
    -                          the 'create' ability.     
    +                           the 'create' ability.     
     rename       subcommand   Must also have the 'mount' ability and
    -                          the 'create' ability in the new parent.
    +                           the 'create' ability in the new parent.
     rollback     subcommand   Must also have the 'mount' ability.      
     snapshot     subcommand   Must also have the 'mount' ability.
     share        subcommand   Allows share and unshare.
     send         subcommand
    -      
    -      
    -aclinherit   property
    -aclmode      property
    -atime        property
    -canmount     property
    -checksum     property
    -compression  property
    -copies       property
    -devices      property
    -exec         property
    -mountpoint   property
    -quota        property
    -readonly     property
    -recordsize   property
    -reservation  property
    -setuid       property
    -shareiscsi   property
    -sharenfs     property
    -snapdir      property
    -version      property
    -volsize      property
    -xattr        property
    -zoned        property
    -userprop     other        Allows changing any user property.
    +       
    +       
    +aclinherit       property
    +aclmode          property
    +atime            property
    +canmount         property
    +checksum         property
    +compression      property
    +copies           property
    +devices          property
    +exec             property
    +mountpoint       property
    +primarycache     property
    +quota            property
    +readonly         property
    +recordsize       property
    +reservation      property
    +secondarycache   property
    +setuid           property
    +shareiscsi       property
    +sharenfs         property
    +snapdir          property
    +version          property
    +volsize          property
    +xattr            property
    +zoned            property
    +userprop         other        Allows changing any user property.
     .fi
     .in -2
     .sp
    @@ -1993,8 +2005,7 @@ Sets "create time" permissions. These permissions are granted (locally) to the c
     .ad
     .sp .6
     .RS 4n
    -Defines or adds permissions to a permission set. The set can be used by other \fBzfs allow\fR commands for the specified file system and its descendents. Sets are evaluated dynamically, so changes to a set are immediately reflected. Permission sets follow the same
    -naming restrictions as ZFS file systems, but the name must begin with an "at sign" ("@"), and can be no more than 64 characters long.
    +Defines or adds permissions to a permission set. The set can be used by other \fBzfs allow\fR commands for the specified file system and its descendents. Sets are evaluated dynamically, so changes to a set are immediately reflected. Permission sets follow the same naming restrictions as ZFS file systems, but the name must begin with an "at sign" ("@"), and can be no more than 64 characters long.
     .RE
     
     .sp
    @@ -2017,17 +2028,15 @@ naming restrictions as ZFS file systems, but the name must begin with an "at sig
     .ad
     .sp .6
     .RS 4n
    -Removes permissions that were granted with the "\fBzfs allow\fR" command. No permissions are explicitly denied, so other permissions granted are still in effect. For example, if the permission is granted by an ancestor. If no permissions are specified,
    -then all permissions for the specified \fIuser\fR, \fIgroup\fR, or \fIeveryone\fR are removed. Specifying "everyone" (or using the \fB-e\fR option) only removes the permissions that were granted to "everyone",
    -not all permissions for every user and group. See the "\fBzfs allow\fR" command for a description of the \fB-ldugec\fR options.
    +Removes permissions that were granted with the "\fBzfs allow\fR" command. No permissions are explicitly denied, so other permissions granted are still in effect. For example, if the permission is granted by an ancestor. If no permissions are specified, then all permissions for the specified \fIuser\fR, \fIgroup\fR, or \fIeveryone\fR are removed. Specifying "everyone" (or using the \fB-e\fR option) only removes the permissions that were granted to "everyone", not all permissions for every user and group. See the "\fBzfs allow\fR" command for a description of the \fB-ldugec\fR options.
     .sp
     .ne 2
     .mk
     .na
     \fB\fB-r\fR\fR
     .ad
    -.RS 6n
    -.rt  
    +.sp .6
    +.RS 4n
     Recursively remove the permissions from this file system and all descendents.
     .RE
     
    @@ -2048,36 +2057,12 @@ Recursively remove the permissions from this file system and all descendents.
     Removes permissions from a permission set. If no permissions are specified, then all permissions are removed, thus removing the set entirely.
     .RE
     
    -.sp
    -.ne 2
    -.mk
    -.na
    -\fB\fBzfs jail\fR \fIjailid\fR \fIfilesystem\fR\fR
    -.ad
    -.sp .6
    -.RS 4n
    -Attaches the given file system to the given jail. From now on this file system tree can be managed from within a jail if the "\fBjailed\fR" property has been set.
    -To use this functionality, sysctl \fBsecurity.jail.enforce_statfs\fR should be set to 0 and sysctl \fBsecurity.jail.mount_allowed\fR should be set to 1.
    -.RE
    -
    -.sp
    -.ne 2
    -.mk
    -.na
    -\fB\fBzfs unjail\fR \fIjailid\fR \fIfilesystem\fR\fR
    -.ad
    -.sp .6
    -.RS 4n
    -Detaches the given file system from the given jail.
    -.RE
    -
     .SH EXAMPLES
     .LP
     \fBExample 1 \fRCreating a ZFS File System Hierarchy
     .sp
     .LP
    -The following commands create a file system named "\fBpool/home\fR" and a file system named "\fBpool/home/bob\fR". The mount point "\fB/export/home\fR" is set for the parent file system, and automatically inherited
    -by the child file system.
    +The following commands create a file system named "\fBpool/home\fR" and a file system named "\fBpool/home/bob\fR". The mount point "\fB/export/home\fR" is set for the parent file system, and automatically inherited by the child file system.
     
     .sp
     .in +2
    @@ -2107,8 +2092,7 @@ The following command creates a snapshot named "yesterday". This snapshot is mou
     \fBExample 3 \fRTaking and destroying multiple snapshots
     .sp
     .LP
    -The following command creates snapshots named "\fByesterday\fR" of "\fBpool/home\fR" and all of its descendent file systems. Each snapshot is mounted on demand in the ".zfs/snapshot" directory at the root of its file system. The
    -second command destroys the newly created snapshots.
    +The following command creates snapshots named "\fByesterday\fR" of "\fBpool/home\fR" and all of its descendent file systems. Each snapshot is mounted on demand in the ".zfs/snapshot" directory at the root of its file system. The second command destroys the newly created snapshots.
     
     .sp
     .in +2
    @@ -2138,7 +2122,7 @@ The following commands turn compression off for all file systems under "\fBpool/
     \fBExample 5 \fRListing ZFS Datasets
     .sp
     .LP
    -The following command lists all active file systems and volumes in the system.
    +The following command lists all active file systems and volumes in the system. Snapshots are displayed if the "listsnaps" property is "on" (the default is "off") . See \fBzpool\fR(1M) for more information on pool properties.
     
     .sp
     .in +2
    @@ -2146,12 +2130,11 @@ The following command lists all active file systems and volumes in the system.
     \fB# zfs list\fR
     
     
    -  NAME                      USED  AVAIL  REFER  MOUNTPOINT
    -  pool                      450K   457G    18K  /pool
    -  pool/home                 315K   457G    21K  /export/home
    -  pool/home/anne             18K   457G    18K  /export/home/anne
    -  pool/home/bob             276K   457G   276K  /export/home/bob
    -  pool/home/bob@yesterday      0      -   276K  -
    +   NAME                      USED  AVAIL  REFER  MOUNTPOINT
    +   pool                      450K   457G    18K  /pool
    +   pool/home                 315K   457G    21K  /export/home
    +   pool/home/anne             18K   457G    18K  /export/home/anne
    +   pool/home/bob             276K   457G   276K  /export/home/bob
     .fi
     .in -2
     .sp
    @@ -2182,42 +2165,52 @@ The following command lists all properties for "\fBpool/home/bob\fR".
     \fB# zfs get all pool/home/bob\fR
     
     
    -  NAME           PROPERTY       VALUE                  SOURCE
    -  pool/home/bob  type           filesystem             -
    -  pool/home/bob  creation       Thu Jul 12 14:44 2007  -
    -  pool/home/bob  used           276K                   -
    -  pool/home/bob  available      50.0G                  -
    -  pool/home/bob  referenced     276K                   -
    -  pool/home/bob  compressratio  1.00x                  -
    -  pool/home/bob  mounted        yes                    -
    -  pool/home/bob  quota          50G                    local
    -  pool/home/bob  reservation    none                   default
    -  pool/home/bob  recordsize     128K                   default
    -  pool/home/bob  mountpoint     /export/home/bob       inherited from
    -                                                       pool/home
    -  pool/home/bob  checksum       on                     default
    -  pool/home/bob  compression    off                    default
    -  pool/home/bob  atime          on                     default
    -  pool/home/bob  devices        on                     default
    -  pool/home/bob  exec           on                     default
    -  pool/home/bob  setuid         on                     default
    -  pool/home/bob  readonly       off                    default
    -  pool/home/bob  zoned          off                    default
    -  pool/home/bob  snapdir        hidden                 default
    -  pool/home/bob  aclmode        groupmask              default
    -  pool/home/bob  aclinherit     restricted             default
    -  pool/home/bob  canmount       on                     default
    -  pool/home/bob  nbmand         off                    default
    -  pool/home/bob  shareiscsi     off                    default
    -  pool/home/bob  sharesmb       off                    default
    -  pool/home/bob  sharenfs       off                    default
    -  pool/home/bob  xattr          on                     default
    -  pool/home/bob  refquota       10M                    local
    -  pool/home/bob  refreservation none                   default
    -  pool/home/bob  copies         1                      default
    -  pool/home/bob  version        1                      -
    -
    -   
    +NAME           PROPERTY              VALUE                  SOURCE
    +pool/home/bob  type                  filesystem             -
    +pool/home/bob  creation              Thu Jul 12 14:44 2007  -
    +pool/home/bob  used                  276K                   -
    +pool/home/bob  available             50.0G                  -
    +pool/home/bob  referenced            276K                   -
    +pool/home/bob  compressratio         1.00x                  -
    +pool/home/bob  mounted               yes                    -
    +pool/home/bob  quota                 50G                    local
    +pool/home/bob  reservation           none                   default
    +pool/home/bob  recordsize            128K                   default
    +pool/home/bob  mountpoint            /export/home/bob       inherited 
    +                                                            from
    +                                                            pool/home
    +pool/home/bob  sharenfs              off                    default
    +pool/home/bob  checksum              on                     default
    +pool/home/bob  compression           off                    default
    +pool/home/bob  atime                 on                     default
    +pool/home/bob  devices               on                     default
    +pool/home/bob  exec                  on                     default
    +pool/home/bob  setuid                on                     default
    +pool/home/bob  readonly              off                    default
    +pool/home/bob  zoned                 off                    default
    +pool/home/bob  snapdir               hidden                 default
    +pool/home/bob  aclmode               groupmask              default
    +pool/home/bob  aclinherit            restricted             default
    +pool/home/bob  canmount              on                     default
    +pool/home/bob  shareiscsi            off                    default
    +pool/home/bob  xattr                 on                     default
    +pool/home/bob  copies                1                      default
    +pool/home/bob  version               1                      -
    +pool/home/bob  utf8only              off                    -
    +pool/home/bob  normalization         none                   -
    +pool/home/bob  casesensitivity       sensitive              -
    +pool/home/bob  vscan                 off                    default
    +pool/home/bob  nbmand                off                    default
    +pool/home/bob  sharesmb              off                    default
    +pool/home/bob  refquota              10M                    local
    +pool/home/bob  refreservation        none                   default
    +pool/home/bob  primarycache          all                    default
    +pool/home/bob  secondarycache        a                      default
    +pool/home/bob  usedbysnapshots       0                      -
    +pool/home/bob  usedbydataset         18K                    -
    +pool/home/bob  usedbychildren        0                      -
    +pool/home/bob  usedbyrefreservation  0                      -
    +    
     .fi
     .in -2
     .sp
    @@ -2244,9 +2237,9 @@ The following command lists all properties with local settings for "\fBpool/home
     .nf
     \fB# zfs get -r -s local -o name,property,value all pool/home/bob\fR
     
    -  NAME             PROPERTY      VALUE
    -  pool             compression   on
    -  pool/home        checksum      off
    +   NAME             PROPERTY      VALUE
    +   pool             compression   on
    +   pool/home        checksum      off
     .fi
     .in -2
     .sp
    @@ -2289,15 +2282,15 @@ The following commands illustrate how to test out changes to a file system, and
     .in +2
     .nf
     \fB# zfs create pool/project/production\fR
    - populate /pool/project/production with data
    +  populate /pool/project/production with data
     \fB# zfs snapshot pool/project/production@today
     # zfs clone pool/project/production@today pool/project/beta\fR
    - make changes to /pool/project/beta and test them
    +  make changes to /pool/project/beta and test them
     \fB# zfs promote pool/project/beta
     # zfs rename pool/project/production pool/project/legacy
     # zfs rename pool/project/beta pool/project/production\fR
    - once the legacy version is no longer needed, it can be
    - destroyed
    +  once the legacy version is no longer needed, it can be
    +  destroyed
     \fB# zfs destroy pool/project/legacy\fR
     .fi
     .in -2
    @@ -2321,16 +2314,15 @@ The following command causes "\fBpool/home/bob\fR" and "\fBpool/home/anne\fR" to
     \fBExample 12 \fRRemotely Replicating ZFS Data
     .sp
     .LP
    -The following commands send a full stream and then an incremental stream to a remote machine, restoring them into "\fBpoolB/received/fs\fR@a" and "\fBpoolB/received/fs@b\fR", respectively. "\fBpoolB\fR" must contain
    -the file system "\fBpoolB/received\fR", and must not initially contain "\fBpoolB/received/fs\fR".
    +The following commands send a full stream and then an incremental stream to a remote machine, restoring them into "\fBpoolB/received/fs\fR@a" and "\fBpoolB/received/fs@b\fR", respectively. "\fBpoolB\fR" must contain the file system "\fBpoolB/received\fR", and must not initially contain "\fBpoolB/received/fs\fR".
     
     .sp
     .in +2
     .nf
     # zfs send pool/fs@a | \e
    -  ssh host zfs receive poolB/received/fs@a
    +   ssh host zfs receive poolB/received/fs@a
     # zfs send -i a pool/fs@b | ssh host \e
    -  zfs receive poolB/received/fs
    +   zfs receive poolB/received/fs
     .fi
     .in -2
     .sp
    @@ -2339,35 +2331,19 @@ the file system "\fBpoolB/received\fR", and must not initially contain "\fBpoolB
     \fBExample 13 \fRUsing the zfs receive -d Option
     .sp
     .LP
    -The following command sends a full stream of "\fBpoolA/fsA/fsB@snap\fR" to a remote machine, receiving it into "\fBpoolB/received/fsA/fsB@snap\fR". The "\fBfsA/fsB@snap\fR" portion of the received snapshot's name
    -is determined from the name of the sent snapshot. "\fBpoolB\fR" must contain the file system "\fBpoolB/received\fR". If "\fBpoolB/received/fsA\fR" does not exist, it is be created as an empty file system.
    +The following command sends a full stream of "\fBpoolA/fsA/fsB@snap\fR" to a remote machine, receiving it into "\fBpoolB/received/fsA/fsB@snap\fR". The "\fBfsA/fsB@snap\fR" portion of the received snapshot's name is determined from the name of the sent snapshot. "\fBpoolB\fR" must contain the file system "\fBpoolB/received\fR". If "\fBpoolB/received/fsA\fR" does not exist, it is be created as an empty file system.
     
     .sp
     .in +2
     .nf
     \fB# zfs send poolA/fsA/fsB@snap | \e
    -  ssh host zfs receive -d poolB/received\fR
    +   ssh host zfs receive -d poolB/received\fR
     .fi
     .in -2
     .sp
     
     .LP
    -\fBExample 14 \fRCreating a ZFS volume as a Swap Device
    -.sp
    -.LP
    -The following example shows how to create a 5-Gbyte ZFS volume and then add the volume as a swap device.
    -
    -.sp
    -.in +2
    -.nf
    -\fB# zfs create -V 5gb tank/vol
    -# swap -a /dev/zvol/dsk/tank/vol\fR
    -.fi
    -.in -2
    -.sp
    -
    -.LP
    -\fBExample 15 \fRSetting User Properties
    +\fBExample 14 \fRSetting User Properties
     .sp
     .LP
     The following example sets the user defined "com.example:department" property for a dataset.
    @@ -2381,7 +2357,7 @@ The following example sets the user defined "com.example:department" property fo
     .sp
     
     .LP
    -\fBExample 16 \fRCreating a ZFS Volume as a iSCSI Target Device
    +\fBExample 15 \fRCreating a ZFS Volume as a iSCSI Target Device
     .sp
     .LP
     The following example shows how to create a \fBZFS\fR volume as an \fBiSCSI\fR target. 
    @@ -2390,12 +2366,12 @@ The following example shows how to create a \fBZFS\fR volume as an \fBiSCSI\fR t
     .in +2
     .nf
     \fB# zfs create -V 2g pool/volumes/vol1
    -# zfs set shareiscsi=on pool/volumes/vol1
    -# iscsitadm list target\fR
    -Target: pool/volumes/vol1
    -iSCSI Name: 
    -iqn.1986-03.com.sun:02:7b4b02a6-3277-eb1b-e686-a24762c52a8c
    -Connections: 0
    + # zfs set shareiscsi=on pool/volumes/vol1
    + # iscsitadm list target\fR
    + Target: pool/volumes/vol1
    + iSCSI Name: 
    + iqn.1986-03.com.sun:02:7b4b02a6-3277-eb1b-e686-a24762c52a8c
    + Connections: 0
     .fi
     .in -2
     .sp
    @@ -2404,7 +2380,7 @@ Connections: 0
     .LP
     After the \fBiSCSI\fR target is created, set up the \fBiSCSI\fR initiator. For more information about the Solaris \fBiSCSI\fR initiator, see the Solaris Administration Guide: Devices and File Systems.
     .LP
    -\fBExample 17 \fRPerforming a Rolling Snapshot
    +\fBExample 16 \fRPerforming a Rolling Snapshot
     .sp
     .LP
     The following example shows how to maintain a history of snapshots with a consistent naming scheme. To keep a week's worth of snapshots, the user destroys the oldest snapshot, renames the remaining snapshots, and then creates a new snapshot, as follows:
    @@ -2424,7 +2400,7 @@ The following example shows how to maintain a history of snapshots with a consis
     .sp
     
     .LP
    -\fBExample 18 \fRSetting sharenfs Property Options on a ZFS File System
    +\fBExample 17 \fRSetting sharenfs Property Options on a ZFS File System
     .sp
     .LP
     The following commands show how to set "sharenfs" property options to enable \fBrw\fR access for a set of \fBIP\fR addresses and to enable root access for system \fBneo\fR on the \fBtank/home\fR file system.
    @@ -2433,7 +2409,7 @@ The following commands show how to set "sharenfs" property options to enable \fB
     .in +2
     .nf
     \fB# zfs set sharenfs='rw=@123.123.0.0/16,root=neo' tank/home\fR
    -
    + 
     .fi
     .in -2
     .sp
    @@ -2443,7 +2419,7 @@ The following commands show how to set "sharenfs" property options to enable \fB
     If you are using \fBDNS\fR for host name resolution, specify the fully qualified hostname.
     
     .LP
    -\fBExample 19 \fRDelegating ZFS Administration Permissions on a ZFS Dataset
    +\fBExample 18 \fRDelegating ZFS Administration Permissions on a ZFS Dataset
     .sp
     .LP
     The following example shows how to set permissions so that user "\fBcindys\fR" can create, destroy, mount and take snapshots on \fBtank/cindys\fR. The permissions on \fBtank/cindys\fR are also displayed.
    @@ -2455,9 +2431,9 @@ The following example shows how to set permissions so that user "\fBcindys\fR" c
     # zfs allow tank/cindys\fR
     -------------------------------------------------------------
     Local+Descendent permissions on (tank/cindys)
    -         user cindys create,destroy,mount,snapshot
    +          user cindys create,destroy,mount,snapshot
     -------------------------------------------------------------
    -
    + 
     .fi
     .in -2
     .sp
    @@ -2474,7 +2450,7 @@ Because the \fBtank/cindys\fR mount point permission is set to 755 by default, u
     .sp
     
     .LP
    -\fBExample 20 \fRDelegating Create Time Permissions on a ZFS Dataset
    +\fBExample 19 \fRDelegating Create Time Permissions on a ZFS Dataset
     .sp
     .LP
     The following example shows how to grant anyone in the group \fBstaff\fR to create file systems in \fBtank/users\fR. This syntax also allows staff members to destroy their own file systems, but not destroy anyone else's file system. The permissions on \fBtank/users\fR are also displayed.
    @@ -2487,16 +2463,16 @@ The following example shows how to grant anyone in the group \fBstaff\fR to crea
     # zfs allow tank/users\fR
     -------------------------------------------------------------
     Create time permissions on (tank/users)
    -         create,destroy
    +          create,destroy
     Local+Descendent permissions on (tank/users)
    -         group staff create,mount
    +          group staff create,mount
     ------------------------------------------------------------- 
     .fi
     .in -2
     .sp
     
     .LP
    -\fBExample 21 \fRDefining and Granting a Permission Set on a ZFS Dataset
    +\fBExample 20 \fRDefining and Granting a Permission Set on a ZFS Dataset
     .sp
     .LP
     The following example shows how to define and grant a permission set on the \fBtank/users\fR file system. The permissions on \fBtank/users\fR are also displayed.
    @@ -2509,18 +2485,18 @@ The following example shows how to define and grant a permission set on the \fBt
     # zfs allow tank/users
     -------------------------------------------------------------
     Permission sets on (tank/users)
    -       @pset create,destroy,mount,snapshot
    +        @pset create,destroy,mount,snapshot
     Create time permissions on (tank/users)
    -       create,destroy
    +        create,destroy
     Local+Descendent permissions on (tank/users)
    -       group staff @pset,create,mount
    +        group staff @pset,create,mount
     -------------------------------------------------------------\fR
     .fi
     .in -2
     .sp
     
     .LP
    -\fBExample 22 \fRDelegating Property Permissions on a ZFS Dataset
    +\fBExample 21 \fRDelegating Property Permissions on a ZFS Dataset
     .sp
     .LP
     The following example shows to grant the ability to set quotas and reservations on the \fBusers/home\fR file system. The permissions on \fBusers/home\fR are also displayed.
    @@ -2532,7 +2508,7 @@ The following example shows to grant the ability to set quotas and reservations
     # zfs allow users/home\fR
     -------------------------------------------------------------
     Local+Descendent permissions on (users/home)
    -       user cindys quota,reservation
    +        user cindys quota,reservation
     -------------------------------------------------------------
     cindys% zfs set quota=10G users/home/marks
     cindys% zfs get quota users/home/marks
    @@ -2543,7 +2519,7 @@ users/home/marks  quota     10G               local
     .sp
     
     .LP
    -\fBExample 23 \fRRemoving ZFS Delegated Permissions on a ZFS Dataset
    +\fBExample 22 \fRRemoving ZFS Delegated Permissions on a ZFS Dataset
     .sp
     .LP
     The following example shows how to remove the snapshot permission from the \fBstaff\fR group on the \fBtank/users\fR file system. The permissions on \fBtank/users\fR are also displayed.
    @@ -2555,11 +2531,11 @@ The following example shows how to remove the snapshot permission from the \fBst
     # zfs allow tank/users\fR
     -------------------------------------------------------------
     Permission sets on (tank/users)
    -       @pset create,destroy,mount,snapshot
    +        @pset create,destroy,mount,snapshot
     Create time permissions on (tank/users)
    -       create,destroy
    +        create,destroy
     Local+Descendent permissions on (tank/users)
    -       group staff @pset,create,mount
    +        group staff @pset,create,mount
     ------------------------------------------------------------- 
     .fi
     .in -2
    @@ -2575,8 +2551,8 @@ The following exit values are returned:
     .na
     \fB\fB0\fR\fR
     .ad
    -.RS 5n
    -.rt  
    +.sp .6
    +.RS 4n
     Successful completion. 
     .RE
     
    @@ -2586,8 +2562,8 @@ Successful completion.
     .na
     \fB\fB1\fR\fR
     .ad
    -.RS 5n
    -.rt  
    +.sp .6
    +.RS 4n
     An error occurred.
     .RE
     
    @@ -2597,8 +2573,8 @@ An error occurred.
     .na
     \fB\fB2\fR\fR
     .ad
    -.RS 5n
    -.rt  
    +.sp .6
    +.RS 4n
     Invalid command line options were specified.
     .RE
     
    @@ -2627,4 +2603,4 @@ Interface StabilityCommitted
     \fBgzip\fR(1), \fBssh\fR(1), \fBmount\fR(1M), \fBshare\fR(1M), \fBsharemgr\fR(1M), \fBunshare\fR(1M), \fBzonecfg\fR(1M), \fBzpool\fR(1M), \fBchmod\fR(2), \fBstat\fR(2), \fBfsync\fR(3c), \fBdfstab\fR(4), \fBattributes\fR(5)
     .sp
     .LP
    -For information about using the \fBZFS\fR web-based management tool and other \fBZFS\fR features, see the \fIZFS Administration Guide\fR.
    +For information about using the \fBZFS\fR web-based management tool and other \fBZFS\fR features, see the \fISolaris ZFS Administration Guide\fR.
    diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
    index a7967d7330f..b6c97c1a5ef 100644
    --- a/cddl/contrib/opensolaris/cmd/zpool/zpool.8
    +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
    @@ -1,24 +1,9 @@
     '\" te
    -.\" CDDL HEADER START
    -.\"
    -.\" The contents of this file are subject to the terms of the
    -.\" Common Development and Distribution License (the "License").  
    -.\" You may not use this file except in compliance with the License.
    -.\"
    -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    -.\" or http://www.opensolaris.org/os/licensing.
    -.\" See the License for the specific language governing permissions
    -.\" and limitations under the License.
    -.\"
    -.\" When distributing Covered Code, include this CDDL HEADER in each
    -.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
    -.\" If applicable, add the following below this CDDL HEADER, with the
    -.\" fields enclosed by brackets "[]" replaced with your own identifying
    -.\" information: Portions Copyright [yyyy] [name of copyright owner]
    -.\"
    -.\" CDDL HEADER END
     .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved.
    -.TH zpool 1M "13 Nov 2007" "SunOS 5.11" "System Administration Commands"
    +.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
    +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
    +.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
    +.TH zpool 1M "5 Mar 2009" "SunOS 5.11" "System Administration Commands"
     .SH NAME
     zpool \- configures ZFS storage pools
     .SH SYNOPSIS
    @@ -29,8 +14,8 @@ zpool \- configures ZFS storage pools
     
     .LP
     .nf
    -\fBzpool create\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR]
    -    \fIpool\fR \fIvdev\fR ...
    +\fBzpool create\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-O\fR \fIfile-system-property=value\fR] 
    +     ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR \fIvdev\fR ...
     .fi
     
     .LP
    @@ -106,13 +91,13 @@ zpool \- configures ZFS storage pools
     .LP
     .nf
     \fBzpool import\fR [\fB-o \fImntopts\fR\fR] [\fB-p\fR \fIproperty=value\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR] 
    -    [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fB-a\fR
    +     [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fB-a\fR
     .fi
     
     .LP
     .nf
     \fBzpool import\fR [\fB-o \fImntopts\fR\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR]
    -    [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR |\fIid\fR [\fInewpool\fR]
    +     [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR |\fIid\fR [\fInewpool\fR]
     .fi
     
     .LP
    @@ -169,8 +154,7 @@ A "virtual device" describes a single device or a collection of devices organize
     .ad
     .RS 10n
     .rt  
    -A block device, typically located under "/dev/dsk". \fBZFS\fR can use individual slices or partitions, though the recommended mode of operation is to use whole disks. A disk can be specified by a full path, or it can be a shorthand name (the relative portion
    -of the path under "/dev/dsk"). A whole disk can be specified by omitting the slice or partition designation. For example, "c0t0d0" is equivalent to "/dev/dsk/c0t0d0s2". When given a whole disk, \fBZFS\fR automatically labels the disk, if necessary.
    +A block device, typically located under "/dev/dsk". \fBZFS\fR can use individual slices or partitions, though the recommended mode of operation is to use whole disks. A disk can be specified by a full path, or it can be a shorthand name (the relative portion of the path under "/dev/dsk"). A whole disk can be specified by omitting the slice or partition designation. For example, "c0t0d0" is equivalent to "/dev/dsk/c0t0d0s2". When given a whole disk, \fBZFS\fR automatically labels the disk, if necessary.
     .RE
     
     .sp
    @@ -192,8 +176,7 @@ A regular file. The use of files as a backing store is strongly discouraged. It
     .ad
     .RS 10n
     .rt  
    -A mirror of two or more devices. Data is replicated in an identical fashion across all components of a mirror. A mirror with \fIN\fR disks of size \fIX\fR can hold \fIX\fR bytes and can withstand (\fIN-1\fR)
    -devices failing before data integrity is compromised.
    +A mirror of two or more devices. Data is replicated in an identical fashion across all components of a mirror. A mirror with \fIN\fR disks of size \fIX\fR can hold \fIX\fR bytes and can withstand (\fIN-1\fR) devices failing before data integrity is compromised.
     .RE
     
     .sp
    @@ -214,11 +197,9 @@ devices failing before data integrity is compromised.
     .rt  
     A variation on \fBRAID-5\fR that allows for better distribution of parity and eliminates the "\fBRAID-5\fR write hole" (in which data and parity become inconsistent after a power loss). Data and parity is striped across all disks within a \fBraidz\fR group.
     .sp
    -A \fBraidz\fR group can have either single- or double-parity, meaning that the \fBraidz\fR group can sustain one or two failures respectively without losing any data. The \fBraidz1\fR \fBvdev\fR type specifies a single-parity \fBraidz\fR group
    -and the \fBraidz2\fR \fBvdev\fR type specifies a double-parity \fBraidz\fR group. The \fBraidz\fR \fBvdev\fR type is an alias for \fBraidz1\fR.
    +A \fBraidz\fR group can have either single- or double-parity, meaning that the \fBraidz\fR group can sustain one or two failures respectively without losing any data. The \fBraidz1\fR \fBvdev\fR type specifies a single-parity \fBraidz\fR group and the \fBraidz2\fR \fBvdev\fR type specifies a double-parity \fBraidz\fR group. The \fBraidz\fR \fBvdev\fR type is an alias for \fBraidz1\fR.
     .sp
    -A \fBraidz\fR group with \fIN\fR disks of size \fIX\fR with \fIP\fR parity disks can hold approximately (\fIN-P\fR)*\fIX\fR bytes and can withstand \fIP\fR device(s)
    -failing before data integrity is compromised. The minimum number of devices in a \fBraidz\fR group is one more than the number of parity disks. The recommended number is between 3 and 9 to help increase performance.
    +A \fBraidz\fR group with \fIN\fR disks of size \fIX\fR with \fIP\fR parity disks can hold approximately (\fIN-P\fR)*\fIX\fR bytes and can withstand \fIP\fR device(s) failing before data integrity is compromised. The minimum number of devices in a \fBraidz\fR group is one more than the number of parity disks. The recommended number is between 3 and 9 to help increase performance.
     .RE
     
     .sp
    @@ -240,8 +221,7 @@ A special pseudo-\fBvdev\fR which keeps track of available hot spares for a pool
     .ad
     .RS 10n
     .rt  
    -A separate intent log device. If more than one log device is specified, then writes are load-balanced between devices. Log devices can be mirrored. However, \fBraidz\fR and \fBraidz2\fR are not supported for the intent log. For more information, see the "Intent
    -Log" section.
    +A separate intent log device. If more than one log device is specified, then writes are load-balanced between devices. Log devices can be mirrored. However, \fBraidz\fR and \fBraidz2\fR are not supported for the intent log. For more information, see the "Intent Log" section.
     .RE
     
     .sp
    @@ -260,8 +240,7 @@ A device used to cache storage pool data. A cache device cannot be mirrored or p
     Virtual devices cannot be nested, so a mirror or \fBraidz\fR virtual device can only contain files or disks. Mirrors of mirrors (or other combinations) are not allowed.
     .sp
     .LP
    -A pool can have any number of virtual devices at the top of the configuration (known as "root vdevs"). Data is dynamically distributed across all top-level devices to balance data among devices. As new virtual devices are added, \fBZFS\fR automatically places data
    -on the newly available devices.
    +A pool can have any number of virtual devices at the top of the configuration (known as "root vdevs"). Data is dynamically distributed across all top-level devices to balance data among devices. As new virtual devices are added, \fBZFS\fR automatically places data on the newly available devices.
     .sp
     .LP
     Virtual devices are specified one at a time on the command line, separated by whitespace. The keywords "mirror" and "raidz" are used to distinguish where a group ends and another begins. For example, the following creates two root vdevs, each a mirror of two disks:
    @@ -279,12 +258,10 @@ Virtual devices are specified one at a time on the command line, separated by wh
     \fBZFS\fR supports a rich set of mechanisms for handling device failure and data corruption. All metadata and data is checksummed, and \fBZFS\fR automatically repairs bad data from a good copy when corruption is detected.
     .sp
     .LP
    -In order to take advantage of these features, a pool must make use of some form of redundancy, using either mirrored or \fBraidz\fR groups. While \fBZFS\fR supports running in a non-redundant configuration, where each root vdev is simply a disk or file, this is
    -strongly discouraged. A single case of bit corruption can render some or all of your data unavailable.
    +In order to take advantage of these features, a pool must make use of some form of redundancy, using either mirrored or \fBraidz\fR groups. While \fBZFS\fR supports running in a non-redundant configuration, where each root vdev is simply a disk or file, this is strongly discouraged. A single case of bit corruption can render some or all of your data unavailable.
     .sp
     .LP
    -A pool's health status is described by one of three states: online, degraded, or faulted. An online pool has all devices operating normally. A degraded pool is one in which one or more devices have failed, but the data is still available due to a redundant configuration. A faulted pool has
    -corrupted metadata, or one or more faulted devices, and insufficient replicas to continue functioning. 
    +A pool's health status is described by one of three states: online, degraded, or faulted. An online pool has all devices operating normally. A degraded pool is one in which one or more devices have failed, but the data is still available due to a redundant configuration. A faulted pool has corrupted metadata, or one or more faulted devices, and insufficient replicas to continue functioning. 
     .sp
     .LP
     The health of the top-level vdev, such as mirror or \fBraidz\fR device, is potentially impacted by the state of its associated vdevs, or component devices. A top-level vdev or component device is in one of the following states:
    @@ -399,8 +376,10 @@ If a device is removed and later re-attached to the system, \fBZFS\fR attempts t
     
     .sp
     .LP
    -Spares can be shared across multiple pools, and can be added with the "\fBzpool add\fR" command and removed with the "\fBzpool remove\fR" command. Once a spare replacement is initiated, a new "spare" \fBvdev\fR is
    -created within the configuration that will remain there until the original device is replaced. At this point, the hot spare becomes available again if another device fails.
    +Spares can be shared across multiple pools, and can be added with the "\fBzpool add\fR" command and removed with the "\fBzpool remove\fR" command. Once a spare replacement is initiated, a new "spare" \fBvdev\fR is created within the configuration that will remain there until the original device is replaced. At this point, the hot spare becomes available again if another device fails.
    +.sp
    +.LP
    +If a pool has a shared spare that is currently being used, the pool can not be exported since other pools may use this shared spare, which may lead to potential data corruption.
     .sp
     .LP
     An in-progress spare replacement can be cancelled by detaching the hot spare. If the original faulted device is detached, then the hot spare assumes its place in the configuration, and is removed from the spare list of all active pools.
    @@ -410,9 +389,7 @@ Spares cannot replace log devices.
     .SS "Intent Log"
     .sp
     .LP
    -The \fBZFS\fR Intent Log (\fBZIL\fR) satisfies \fBPOSIX\fR requirements for synchronous transactions. For instance, databases often require their transactions to be on stable storage devices when returning from a system call. \fBNFS\fR and
    -other applications can also use \fBfsync\fR() to ensure data stability. By default, the intent log is allocated from blocks within the main pool. However, it might be possible to get better performance using separate intent log devices such as \fBNVRAM\fR or a dedicated
    -disk. For example:
    +The \fBZFS\fR Intent Log (\fBZIL\fR) satisfies \fBPOSIX\fR requirements for synchronous transactions. For instance, databases often require their transactions to be on stable storage devices when returning from a system call. \fBNFS\fR and other applications can also use \fBfsync\fR() to ensure data stability. By default, the intent log is allocated from blocks within the main pool. However, it might be possible to get better performance using separate intent log devices such as \fBNVRAM\fR or a dedicated disk. For example:
     .sp
     .in +2
     .nf
    @@ -430,8 +407,7 @@ Log devices can be added, replaced, attached, detached, and imported and exporte
     .SS "Cache Devices"
     .sp
     .LP
    -Devices can be added to a storage pool as "cache devices." These devices provide an additional layer of caching between main memory and disk. For read-heavy workloads, where the working set size is much larger than what can be cached in main memory, using cache devices allow
    -much more of this working set to be served from low latency media. Using cache devices provides the greatest performance improvement for random read-workloads of mostly static content.
    +Devices can be added to a storage pool as "cache devices." These devices provide an additional layer of caching between main memory and disk. For read-heavy workloads, where the working set size is much larger than what can be cached in main memory, using cache devices allow much more of this working set to be served from low latency media. Using cache devices provides the greatest performance improvement for random read-workloads of mostly static content.
     .sp
     .LP
     To create a pool with cache devices, specify a "cache" \fBvdev\fR with any number of devices. For example:
    @@ -521,8 +497,7 @@ Amount of storage space used within the pool.
     
     .sp
     .LP
    -These space usage properties report actual physical space available to the storage pool. The physical space can be different from the total amount of space that any contained datasets can actually use. The amount of space used in a \fBraidz\fR configuration depends on the characteristics
    -of the data being written. In addition, \fBZFS\fR reserves some space for internal accounting that the \fBzfs\fR(1M) command takes into account, but the \fBzpool\fR command does not. For non-full pools of a reasonable size, these effects should be invisible. For small pools, or pools that are close to being completely full, these discrepancies may become more noticeable.
    +These space usage properties report actual physical space available to the storage pool. The physical space can be different from the total amount of space that any contained datasets can actually use. The amount of space used in a \fBraidz\fR configuration depends on the characteristics of the data being written. In addition, \fBZFS\fR reserves some space for internal accounting that the \fBzfs\fR(1M) command takes into account, but the \fBzpool\fR command does not. For non-full pools of a reasonable size, these effects should be invisible. For small pools, or pools that are close to being completely full, these discrepancies may become more noticeable.
     .sp
     .LP
     The following property can be set at creation time and import time:
    @@ -534,8 +509,7 @@ The following property can be set at creation time and import time:
     .ad
     .sp .6
     .RS 4n
    -Alternate root directory. If set, this directory is prepended to any mount points within the pool. This can be used when examining an unknown pool where the mount points cannot be trusted, or in an alternate boot environment, where the typical paths are not valid. \fBaltroot\fR is
    -not a persistent property. It is valid only while the system is up. Setting \fBaltroot\fR defaults to using \fBcachefile\fR=none, though this may be overridden	 using an explicit setting.
    +Alternate root directory. If set, this directory is prepended to any mount points within the pool. This can be used when examining an unknown pool where the mount points cannot be trusted, or in an alternate boot environment, where the typical paths are not valid. \fBaltroot\fR is not a persistent property. It is valid only while the system is up. Setting \fBaltroot\fR defaults to using \fBcachefile\fR=none, though this may be overridden	 using an explicit setting.
     .RE
     
     .sp
    @@ -549,8 +523,7 @@ The following properties can be set at creation time and import time, and later
     .ad
     .sp .6
     .RS 4n
    -Controls automatic device replacement. If set to "\fBoff\fR", device replacement must be initiated by the administrator by using the "\fBzpool replace\fR" command. If set to "\fBon\fR", any new device, found
    -in the same physical location as a device that previously belonged to the pool, is automatically formatted and replaced. The default behavior is "\fBoff\fR". This property can also be referred to by its shortened column name, "replace".
    +Controls automatic device replacement. If set to "\fBoff\fR", device replacement must be initiated by the administrator by using the "\fBzpool replace\fR" command. If set to "\fBon\fR", any new device, found in the same physical location as a device that previously belonged to the pool, is automatically formatted and replaced. The default behavior is "\fBoff\fR". This property can also be referred to by its shortened column name, "replace".
     .RE
     
     .sp
    @@ -572,9 +545,7 @@ Identifies the default bootable dataset for the root pool. This property is expe
     .ad
     .sp .6
     .RS 4n
    -Controls the location of where the pool configuration is cached. Discovering all pools on system startup requires a cached copy of the configuration data that is stored on the root file system. All pools in this cache are automatically imported when the system boots. Some environments,
    -such as install and clustering, need to cache this information in a different location so that pools are not automatically imported. Setting this property caches the pool configuration in a different location that can later be imported with "\fBzpool import -c\fR". Setting
    -it to the special value "\fBnone\fR" creates a temporary pool that is never cached, and the special value \fB\&''\fR (empty string) uses the default location. 
    +Controls the location of where the pool configuration is cached. Discovering all pools on system startup requires a cached copy of the configuration data that is stored on the root file system. All pools in this cache are automatically imported when the system boots. Some environments, such as install and clustering, need to cache this information in a different location so that pools are not automatically imported. Setting this property caches the pool configuration in a different location that can later be imported with "\fBzpool import -c\fR". Setting it to the special value "\fBnone\fR" creates a temporary pool that is never cached, and the special value \fB\&''\fR (empty string) uses the default location. 
     .sp
     Multiple pools can share the same cache file. Because the kernel destroys and recreates this file when pools are added and removed, care should be taken when attempting to access this file. When the last pool using a \fBcachefile\fR is exported or destroyed, the file is removed.
     .RE
    @@ -587,8 +558,7 @@ Multiple pools can share the same cache file. Because the kernel destroys and re
     .ad
     .sp .6
     .RS 4n
    -Controls whether a non-privileged user is granted access based on the dataset permissions defined on the dataset. See \fBzfs\fR(1M) for more information
    -on \fBZFS\fR delegated administration.
    +Controls whether a non-privileged user is granted access based on the dataset permissions defined on the dataset. See \fBzfs\fR(1M) for more information on \fBZFS\fR delegated administration.
     .RE
     
     .sp
    @@ -635,6 +605,17 @@ Prints out a message to the console and generates a system crash dump.
     
     .RE
     
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fB\fBlistsnaps\fR=on | off\fR
    +.ad
    +.sp .6
    +.RS 4n
    +Controls whether information about snapshots associated with this pool is output when "\fBzfs list\fR" is run without the  \fB-t\fR option.  The default value is "off".
    +.RE
    +
     .sp
     .ne 2
     .mk
    @@ -643,8 +624,7 @@ Prints out a message to the console and generates a system crash dump.
     .ad
     .sp .6
     .RS 4n
    -The current on-disk version of the pool. This can be increased, but never decreased. The preferred method of updating pools is with the "\fBzpool upgrade\fR" command, though this property can be used when a specific version is needed for backwards compatibility.
    -This property can be any number between 1 and the current version reported by "\fBzpool upgrade -v\fR". The special value "\fBcurrent\fR" is an alias for the latest supported version.
    +The current on-disk version of the pool. This can be increased, but never decreased. The preferred method of updating pools is with the "\fBzpool upgrade\fR" command, though this property can be used when a specific version is needed for backwards compatibility. This property can be any number between 1 and the current version reported by "\fBzpool upgrade -v\fR".
     .RE
     
     .SS "Subcommands"
    @@ -669,18 +649,15 @@ Displays a help message.
     .ne 2
     .mk
     .na
    -\fB\fBzpool create\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR \fIvdev\fR ...\fR
    +\fB\fBzpool create\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-O\fR \fIfile-system-property=value\fR] ... [\fB-m\fR \fImountpoint\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR \fIvdev\fR ...\fR
     .ad
     .sp .6
     .RS 4n
    -Creates a new storage pool containing the virtual devices specified on the command line. The pool name must begin with a letter, and can only contain alphanumeric characters as well as underscore ("_"), dash ("-"), and period ("."). The pool
    -names "mirror", "raidz", "spare" and "log" are reserved, as are names beginning with the pattern "c[0-9]". The \fBvdev\fR specification is described in the "Virtual Devices" section.
    +Creates a new storage pool containing the virtual devices specified on the command line. The pool name must begin with a letter, and can only contain alphanumeric characters as well as underscore ("_"), dash ("-"), and period ("."). The pool names "mirror", "raidz", "spare" and "log" are reserved, as are names beginning with the pattern "c[0-9]". The \fBvdev\fR specification is described in the "Virtual Devices" section.
     .sp
    -The command verifies that each device specified is accessible and not currently in use by another subsystem. There are some uses, such as being currently mounted, or specified as the dedicated dump device, that prevents a device from ever being used by \fBZFS\fR. Other uses,
    -such as having a preexisting \fBUFS\fR file system, can be overridden with the \fB-f\fR option.
    +The command verifies that each device specified is accessible and not currently in use by another subsystem. There are some uses, such as being currently mounted, or specified as the dedicated dump device, that prevents a device from ever being used by \fBZFS\fR. Other uses, such as having a preexisting \fBUFS\fR file system, can be overridden with the \fB-f\fR option.
     .sp
    -The command also checks that the replication strategy for the pool is consistent. An attempt to combine redundant and non-redundant storage in a single pool, or to mix disks and files, results in an error unless \fB-f\fR is specified. The use of differently sized devices within
    -a single \fBraidz\fR or mirror group is also flagged as an error unless \fB-f\fR is specified.
    +The command also checks that the replication strategy for the pool is consistent. An attempt to combine redundant and non-redundant storage in a single pool, or to mix disks and files, results in an error unless \fB-f\fR is specified. The use of differently sized devices within a single \fBraidz\fR or mirror group is also flagged as an error unless \fB-f\fR is specified.
     .sp
     Unless the \fB-R\fR option is specified, the default mount point is "/\fIpool\fR". The mount point must not exist or must be empty, or else the root dataset cannot be mounted. This can be overridden with the \fB-m\fR option.
     .sp
    @@ -716,6 +693,21 @@ Displays the configuration that would be used without actually creating the pool
     Sets the given pool properties. See the "Properties" section for a list of valid properties that can be set.
     .RE
     
    +.sp
    +.ne 2
    +.mk
    +.na
    +\fB\fB-O\fR \fIfile-system-property=value\fR\fR
    +.ad
    +.br
    +.na
    +\fB[\fB-O\fR \fIfile-system-property=value\fR] ...\fR
    +.ad
    +.sp .6
    +.RS 4n
    +Sets the given file system properties in the root file system of the pool. See the "Properties" section of \fBzfs\fR(1M) for a list of valid properties that can be set.
    +.RE
    +
     .sp
     .ne 2
     .mk
    @@ -770,8 +762,7 @@ Forces any active datasets contained within the pool to be unmounted.
     .ad
     .sp .6
     .RS 4n
    -Adds the specified virtual devices to the given pool. The \fIvdev\fR specification is described in the "Virtual Devices" section. The behavior of the \fB-f\fR option, and the device checks performed are described in the "zpool create"
    -subcommand.
    +Adds the specified virtual devices to the given pool. The \fIvdev\fR specification is described in the "Virtual Devices" section. The behavior of the \fB-f\fR option, and the device checks performed are described in the "zpool create" subcommand.
     .sp
     .ne 2
     .mk
    @@ -805,8 +796,7 @@ Do not add a disk that is currently configured as a quorum device to a zpool. Af
     .ad
     .sp .6
     .RS 4n
    -Removes the specified device from the pool. This command currently only supports removing hot spares and cache devices. Devices that are part of a mirrored configuration can be removed using the "\fBzpool detach\fR" command. Non-redundant and \fBraidz\fR devices
    -cannot be removed from a pool.
    +Removes the specified device from the pool. This command currently only supports removing hot spares and cache devices. Devices that are part of a mirrored configuration can be removed using the "\fBzpool detach\fR" command. Non-redundant and \fBraidz\fR devices cannot be removed from a pool.
     .RE
     
     .sp
    @@ -850,8 +840,7 @@ Comma-separated list of properties to display. See the "Properties" section for
     .ad
     .sp .6
     .RS 4n
    -Displays \fBI/O\fR statistics for the given pools. When given an interval, the statistics are printed every \fIinterval\fR seconds until \fBCtrl-C\fR is pressed. If no \fIpools\fR are specified, statistics for
    -every pool in the system is shown. If \fIcount\fR is specified, the command exits after \fIcount\fR reports are printed.
    +Displays \fBI/O\fR statistics for the given pools. When given an interval, the statistics are printed every \fIinterval\fR seconds until \fBCtrl-C\fR is pressed. If no \fIpools\fR are specified, statistics for every pool in the system is shown. If \fIcount\fR is specified, the command exits after \fIcount\fR reports are printed.
     .sp
     .ne 2
     .mk
    @@ -956,8 +945,7 @@ Clears device errors in a pool. If no arguments are specified, all device errors
     .ad
     .sp .6
     .RS 4n
    -Attaches \fInew_device\fR to an existing \fBzpool\fR device. The existing device cannot be part of a \fBraidz\fR configuration. If \fIdevice\fR is not currently part of a mirrored configuration, \fIdevice\fR automatically
    -transforms into a two-way mirror of \fIdevice\fR and \fInew_device\fR. If \fIdevice\fR is part of a two-way mirror, attaching \fInew_device\fR creates a three-way mirror, and so on. In either case, \fInew_device\fR begins to resilver immediately.
    +Attaches \fInew_device\fR to an existing \fBzpool\fR device. The existing device cannot be part of a \fBraidz\fR configuration. If \fIdevice\fR is not currently part of a mirrored configuration, \fIdevice\fR automatically transforms into a two-way mirror of \fIdevice\fR and \fInew_device\fR. If \fIdevice\fR is part of a two-way mirror, attaching \fInew_device\fR creates a three-way mirror, and so on. In either case, \fInew_device\fR begins to resilver immediately.
     .sp
     .ne 2
     .mk
    @@ -994,8 +982,7 @@ Replaces \fIold_device\fR with \fInew_device\fR. This is equivalent to attaching
     .sp
     The size of \fInew_device\fR must be greater than or equal to the minimum size of all the devices in a mirror or \fBraidz\fR configuration.
     .sp
    -\fInew_device\fR is required if the pool is not redundant. If \fInew_device\fR is not specified, it defaults to \fIold_device\fR. This form of replacement is useful after an existing disk has failed and has been physically replaced.
    -In this case, the new disk may have the same \fB/dev/dsk\fR path as the old device, even though it is actually a different disk. \fBZFS\fR recognizes this.
    +\fInew_device\fR is required if the pool is not redundant. If \fInew_device\fR is not specified, it defaults to \fIold_device\fR. This form of replacement is useful after an existing disk has failed and has been physically replaced. In this case, the new disk may have the same \fB/dev/dsk\fR path as the old device, even though it is actually a different disk. \fBZFS\fR recognizes this.
     .sp
     .ne 2
     .mk
    @@ -1017,11 +1004,9 @@ Forces use of \fInew_device\fR, even if its appears to be in use. Not all device
     .ad
     .sp .6
     .RS 4n
    -Begins a scrub. The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror or \fBraidz\fR) devices, \fBZFS\fR automatically repairs any damage discovered during the scrub. The "\fBzpool
    -status\fR" command reports the progress of the scrub and summarizes the results of the scrub upon completion.
    +Begins a scrub. The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror or \fBraidz\fR) devices, \fBZFS\fR automatically repairs any damage discovered during the scrub. The "\fBzpool status\fR" command reports the progress of the scrub and summarizes the results of the scrub upon completion.
     .sp
    -Scrubbing and resilvering are very similar operations. The difference is that resilvering only examines data that \fBZFS\fR knows to be out of date (for example, when attaching a new device to a mirror or replacing an existing device), whereas scrubbing examines all data to
    -discover silent errors due to hardware faults or disk failure.
    +Scrubbing and resilvering are very similar operations. The difference is that resilvering only examines data that \fBZFS\fR knows to be out of date (for example, when attaching a new device to a mirror or replacing an existing device), whereas scrubbing examines all data to discover silent errors due to hardware faults or disk failure.
     .sp
     Because scrubbing and resilvering are \fBI/O\fR-intensive operations, \fBZFS\fR only allows one at a time. If a scrub is already in progress, the "\fBzpool scrub\fR" command terminates it and starts a new scrub. If a resilver is in progress, \fBZFS\fR does not allow a scrub to be started until the resilver completes.
     .sp
    @@ -1045,8 +1030,7 @@ Stop scrubbing.
     .ad
     .sp .6
     .RS 4n
    -Lists pools available to import. If the \fB-d\fR option is not specified, this command searches for devices in "/dev/dsk". The \fB-d\fR option can be specified multiple times, and all directories are searched. If the device appears to be part of
    -an exported pool, this command displays a summary of the pool with the name of the pool, a numeric identifier, as well as the \fIvdev\fR layout and current health of the device for each device or file. Destroyed pools, pools that were previously destroyed with the "\fBzpool destroy\fR" command, are not listed unless the \fB-D\fR option is specified. 
    +Lists pools available to import. If the \fB-d\fR option is not specified, this command searches for devices in "/dev/dsk". The \fB-d\fR option can be specified multiple times, and all directories are searched. If the device appears to be part of an exported pool, this command displays a summary of the pool with the name of the pool, a numeric identifier, as well as the \fIvdev\fR layout and current health of the device for each device or file. Destroyed pools, pools that were previously destroyed with the "\fBzpool destroy\fR" command, are not listed unless the \fB-D\fR option is specified. 
     .sp
     The numeric identifier is unique, and can be used instead of the pool name when multiple exported pools of the same name are available.
     .sp
    @@ -1088,13 +1072,11 @@ Lists destroyed pools only.
     .ne 2
     .mk
     .na
    -\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR]
    -[\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fB-a\fR\fR
    +\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR] [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fB-a\fR\fR
     .ad
     .sp .6
     .RS 4n
    -Imports all pools found in the search directories. Identical to the previous command, except that all pools with a sufficient number of devices available are imported. Destroyed pools, pools that were previously destroyed with the "\fBzpool destroy\fR"
    -command, will not be imported unless the \fB-D\fR option is specified.
    +Imports all pools found in the search directories. Identical to the previous command, except that all pools with a sufficient number of devices available are imported. Destroyed pools, pools that were previously destroyed with the "\fBzpool destroy\fR" command, will not be imported unless the \fB-D\fR option is specified.
     .sp
     .ne 2
     .mk
    @@ -1103,8 +1085,7 @@ command, will not be imported unless the \fB-D\fR option is specified.
     .ad
     .RS 21n
     .rt  
    -Comma-separated list of mount options to use when mounting datasets within the pool. See \fBzfs\fR(1M) for a description of dataset properties and mount
    -options.
    +Comma-separated list of mount options to use when mounting datasets within the pool. See \fBzfs\fR(1M) for a description of dataset properties and mount options.
     .RE
     
     .sp
    @@ -1190,15 +1171,13 @@ Sets the "\fBcachefile\fR" property to "\fBnone\fR" and the "\fIaltroot\fR" prop
     .ne 2
     .mk
     .na
    -\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR]
    -[\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR | \fIid\fR [\fInewpool\fR]\fR
    +\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR] [\fB-D\fR] [\fB-f\fR] [\fB-R\fR \fIroot\fR] \fIpool\fR | \fIid\fR [\fInewpool\fR]\fR
     .ad
     .sp .6
     .RS 4n
     Imports a specific pool. A pool can be identified by its name or the numeric identifier. If \fInewpool\fR is specified, the pool is imported using the name \fInewpool\fR. Otherwise, it is imported with the same name as its exported name.
     .sp
    -If a device is removed from a system without running "\fBzpool export\fR" first, the device appears as potentially active. It cannot be determined if this was a failed export, or whether the device is really in use from another host. To import a pool in this state,
    -the \fB-f\fR option is required.
    +If a device is removed from a system without running "\fBzpool export\fR" first, the device appears as potentially active. It cannot be determined if this was a failed export, or whether the device is really in use from another host. To import a pool in this state, the \fB-f\fR option is required.
     .sp
     .ne 2
     .mk
    @@ -1207,8 +1186,7 @@ the \fB-f\fR option is required.
     .ad
     .sp .6
     .RS 4n
    -Comma-separated list of mount options to use when mounting datasets within the pool. See \fBzfs\fR(1M) for a description of dataset properties and mount
    -options.
    +Comma-separated list of mount options to use when mounting datasets within the pool. See \fBzfs\fR(1M) for a description of dataset properties and mount options.
     .RE
     
     .sp
    @@ -1289,7 +1267,7 @@ Sets the "\fBcachefile\fR" property to "\fBnone\fR" and the "\fIaltroot\fR" prop
     .RS 4n
     Exports the given pools from the system. All devices are marked as exported, but are still considered in use by other subsystems. The devices can be moved between systems (even those of different endianness) and imported as long as a sufficient number of devices are present.
     .sp
    -Before exporting the pool, all datasets within the pool are unmounted.
    +Before exporting the pool, all datasets within the pool are unmounted. A pool can not be exported if it has a shared spare that is currently being used.
     .sp
     For pools to be portable, you must give the \fBzpool\fR command whole disks, not just slices, so that \fBZFS\fR can label the disks with portable \fBEFI\fR labels. Otherwise, disk drivers on platforms of different endianness will not recognize the disks.
     .sp
    @@ -1301,6 +1279,8 @@ For pools to be portable, you must give the \fBzpool\fR command whole disks, not
     .RS 6n
     .rt  
     Forcefully unmount all datasets, using the "\fBunmount -f\fR" command.
    +.sp
    +This command will forcefully export the pool even if it has a shared spare that is currently being used. This may lead to potential data corruption.
     .RE
     
     .RE
    @@ -1313,8 +1293,7 @@ Forcefully unmount all datasets, using the "\fBunmount -f\fR" command.
     .ad
     .sp .6
     .RS 4n
    -Displays all pools formatted using a different \fBZFS\fR on-disk version. Older versions can continue to be used, but some features may not be available. These pools can be upgraded using "\fBzpool upgrade -a\fR". Pools that are formatted with
    -a more recent version are also displayed, although these pools will be inaccessible on the system.
    +Displays all pools formatted using a different \fBZFS\fR on-disk version. Older versions can continue to be used, but some features may not be available. These pools can be upgraded using "\fBzpool upgrade -a\fR". Pools that are formatted with a more recent version are also displayed, although these pools will be inaccessible on the system.
     .RE
     
     .sp
    @@ -1407,9 +1386,9 @@ Retrieves the given list of properties (or all properties if "\fBall\fR" is used
     .in +2
     .nf
            name          Name of storage pool
    -       property      Property name
    -       value         Property value
    -       source        Property source, either 'default' or 'local'.
    +        property      Property name
    +        value         Property value
    +        source        Property source, either 'default' or 'local'.
     .fi
     .in -2
     .sp
    @@ -1421,7 +1400,7 @@ See the "Properties" section for more information on the available pool properti
     .ne 2
     .mk
     .na
    -\fB\fBzpool set\fR \fIproperty\fR=\fIvalue\fR \fIpool\fR \fR
    +\fB\fBzpool set\fR \fIproperty\fR=\fIvalue\fR \fIpool\fR\fR
     .ad
     .sp .6
     .RS 4n
    @@ -1513,10 +1492,10 @@ The results from this command are similar to the following:
     .in +2
     .nf
     \fB# zpool list\fR
    -    NAME              SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
    -    pool             67.5G   2.92M   67.5G     0%  ONLINE     -
    -    tank             67.5G   2.92M   67.5G     0%  ONLINE     -
    -    zion                 -       -       -     0%  FAULTED    -
    +     NAME              SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
    +     pool             67.5G   2.92M   67.5G     0%  ONLINE     -
    +     tank             67.5G   2.92M   67.5G     0%  ONLINE     -
    +     zion                 -       -       -     0%  FAULTED    -
     .fi
     .in -2
     .sp
    @@ -1563,16 +1542,16 @@ The results from this command are similar to the following:
     .in +2
     .nf
     \fB# zpool import\fR
    - pool: tank
    -   id: 15451357997522795478
    -state: ONLINE
    +  pool: tank
    +    id: 15451357997522795478
    + state: ONLINE
     action: The pool can be imported using its name or numeric identifier.
     config:
     
    -       tank        ONLINE
    -         mirror    ONLINE
    -           c1t2d0  ONLINE
    -           c1t3d0  ONLINE
    +        tank        ONLINE
    +          mirror    ONLINE
    +            c1t2d0  ONLINE
    +            c1t3d0  ONLINE
     
     \fB# zpool import tank\fR
     .fi
    @@ -1642,7 +1621,7 @@ The following command creates a ZFS storage pool consisting of two, two-way mirr
     .in +2
     .nf
     \fB# zpool create pool mirror c0d0 c1d0 mirror c2d0 c3d0 log mirror \e
    -  c4d0 c5d0\fR
    +   c4d0 c5d0\fR
     .fi
     .in -2
     .sp
    
    From 9377fe10217459e6ddf56f536d9032b2e50e1d36 Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Tue, 6 Apr 2010 23:03:20 +0000
    Subject: [PATCH 1849/2592] MFC: r205562 When the regular NFS server replied to
     a UDP client out of the replay cache, it did not free the request argument
     mbuf list, resulting in a leak. This patch fixes that leak.
    
    PR:	kern/144330
    ---
     sys/rpc/svc.c | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c
    index a59489457f6..8678a18a3a5 100644
    --- a/sys/rpc/svc.c
    +++ b/sys/rpc/svc.c
    @@ -819,9 +819,11 @@ svc_getreq(SVCXPRT *xprt, struct svc_req **rqstp_ret)
     					free(r->rq_addr, M_SONAME);
     					r->rq_addr = NULL;
     				}
    +				m_freem(args);
     				goto call_done;
     
     			default:
    +				m_freem(args);
     				goto call_done;
     			}
     		}
    
    From 0b2d5c2977d20915362dd56e2e523430a4d570e5 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:14:43 +0000
    Subject: [PATCH 1850/2592] MFC r203134
    
     Add run(4), a driver for Ralink RT2700U/RT2800U/RT3000U USB 802.11agn devices.
    
     This driver was written for OpenBSD by Damien Bergamini and ported over by
     Akinori Furukoshi.
    ---
     sys/conf/files                 |    1 +
     sys/contrib/dev/run/LICENSE    |   39 +
     sys/contrib/dev/run/run-rt2870 |  Bin 0 -> 8192 bytes
     sys/dev/usb/usbdevs            |  209 +-
     sys/dev/usb/wlan/if_run.c      | 4143 ++++++++++++++++++++++++++++++++
     sys/dev/usb/wlan/if_runreg.h   | 1130 +++++++++
     sys/dev/usb/wlan/if_runvar.h   |  222 ++
     sys/modules/Makefile           |    1 +
     sys/modules/runfw/Makefile     |    8 +
     sys/modules/usb/Makefile       |    2 +-
     sys/modules/usb/run/Makefile   |   36 +
     11 files changed, 5789 insertions(+), 2 deletions(-)
     create mode 100644 sys/contrib/dev/run/LICENSE
     create mode 100644 sys/contrib/dev/run/run-rt2870
     create mode 100644 sys/dev/usb/wlan/if_run.c
     create mode 100644 sys/dev/usb/wlan/if_runreg.h
     create mode 100644 sys/dev/usb/wlan/if_runvar.h
     create mode 100644 sys/modules/runfw/Makefile
     create mode 100644 sys/modules/usb/run/Makefile
    
    diff --git a/sys/conf/files b/sys/conf/files
    index 86e9d472152..07614871e69 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -1717,6 +1717,7 @@ dev/usb/net/uhso.c		optional uhso
     # USB WLAN drivers
     #
     dev/usb/wlan/if_rum.c		optional rum
    +dev/usb/wlan/if_run.c		optional run
     dev/usb/wlan/if_uath.c		optional uath
     dev/usb/wlan/if_upgt.c		optional upgt
     dev/usb/wlan/if_ural.c		optional ural
    diff --git a/sys/contrib/dev/run/LICENSE b/sys/contrib/dev/run/LICENSE
    new file mode 100644
    index 00000000000..39e3c521891
    --- /dev/null
    +++ b/sys/contrib/dev/run/LICENSE
    @@ -0,0 +1,39 @@
    +Copyright (c) 2007, Ralink Technology 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 Ralink Technology 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. Ralink Technology 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/run/run-rt2870 b/sys/contrib/dev/run/run-rt2870
    new file mode 100644
    index 0000000000000000000000000000000000000000..06ca5e16bbe184f47c04405771d261b4994c99e1
    GIT binary patch
    literal 8192
    zcmeHLU2GIp6yCWryWLVscW1Yy6$-<+l^;VL6%}g2&+c{?+HFhA0PHxdo
    z3+)Ir8Ur$}gcmh2%Y%`GY=RBG0WO62JjD29a)G`0guMw&0s>vnoh>0j7L~-1kZCga
    z=iKj{bMH52&fU{ese}THP~bHb_y~#bBXJuNKSAPQQT$X!4eQYC`6#pxiANN#Ppaj`
    z*+0o9cNi-)#^9(P{C-#P
    z*WF_C9&x4N@rYX`#4CLBew5!N)_eiB(gwKJLzHZ~r8A>Q92noU#zL~G2e3LegtW4&
    zARh8-emo>O^Gr9N>5%{v#F0`q37Zmd3y!>NZ)R$xbh2gh?MsuF*m^0wwmd1`e}Yev
    z9IDc4p!I8BlANgaGgYRlQa=nZuWgtTaP+dY}K(y7glIg-|CM43+@=F7*P
    zSzBT(mbkE3zB$E6K{R%@r2^zYh&Xb(eYG2aO{J37>XNn$l8lQag21Z
    zE=p3YbJq2(8)9|Fd*kb3NJp*D%ve1dQqh%w$Nh_n0lO^ApP)kz_S*f6g*58g(pTW
    zO(sb#5IL{&V#8uFbhwZ&2v%M$4@VzwzgkCFj6+)~n_
    zhm=My8IVYg($oY(rF2dSg4mmBnQ5T<7HilVG3v;Ga@|*8L%|v@i~wi6zCh_Liy8sW
    zE2$t*?&wuL&||S0CUNOn4QYc9$IHT2U{*{$L6%Z!dll)IFgm?W+Q~*&(CHo02pe5R
    zr-w~F37AalYH7QW+h)9^Z1a&s?yAwu)`c;SC{;&jKXZx^T&s9%01cL(oP|_
    z0~B^VRDc9iNgOCv&V7!-ydDqN|ouq&&Z0S|^;Ma=+@FC0@=hjY8K`*M1AFKG>h
    z)KzwCVV|`Z0Hl?&@X}KzT8z~xN@5TpVJ#e)(q4@45OocWCR&7*WSvpP22#=oD3HcE
    z){=zs;G}F-o$7I^
    zN4kOL<+taMyMjrU8&yu1UEyr_Ui(67>R*#Kh}I;G*1$+E!bYi*6!Ptc
    zK-zDW069tJqwB3L@=?`#M=sifg*@pEYl*Nn7-9K#Hg9doY~)OogA7bhK)Qzny9};`
    zIgpl618ag~lGw1y3Q7te8Oib8q@HA6r=1*hfaPihJrR`1ZvAeY&QigvG2J?+WvC4*Xh
    zfdg4#%c;TqYH{`vGC08_i+4Urg%jaYJ5JehfrA^z0rZ8nYC%tB`oJ8|Y{zFgKI3)Z
    zv)p){t?-ncKYkv9PQdY*kaPR&jS8wMp#5Ba4frxpfp;8$x5-=D(&AJ)+-e^vF4OIU
    zc%szwa5hQPb04hSpz^G`=$BBX15$N_rRstgHX_R&_s?a(Wx!>?Wx!>?W#IW_VCJz^rDszA
    z|5l;?Kl3#8|H)@i|5xw{KkWZ?{eQAT{a?X!h5Ek|`oGuzk68M9{r@Q7G4=nWkf*Hw
    x&$#u!TmQ3vGE^?--TL3H|K0lEt^c3TA7<{UTn1bQTn1bQTn7F}2GCdM{{jc()VKfu
    
    literal 0
    HcmV?d00001
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index 53d676dc842..e18f7be2c1a 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -524,6 +524,7 @@ vendor ELCON		0x0db7	ELCON Systemtechnik
     vendor NETAC		0x0dd8	Netac
     vendor SITECOMEU	0x0df6	Sitecom Europe
     vendor MOBILEACTION	0x0df7	Mobile Action
    +vendor AMIGO		0x0e0b	Amigo Technology
     vendor SPEEDDRAGON	0x0e55	Speed Dragon Multimedia
     vendor HAWKING		0x0e66	Hawking
     vendor FOSSIL		0x0e67	Fossil, Inc
    @@ -589,12 +590,14 @@ vendor NETGEAR3		0x1385	Netgear
     vendor BALTECH		0x13ad	Baltech
     vendor CISCOLINKSYS	0x13b1	Cisco-Linksys
     vendor SHARK		0x13d2	Shark
    +vendor AZUREWAVE	0x13d3	AsureWave
     vendor EMTEC		0x13fe	Emtec
     vendor NOVATEL		0x1410	Novatel Wireless
     vendor MERLIN		0x1416	Merlin
     vendor WISTRONNEWEB	0x1435	Wistron NeWeb
     vendor RADIOSHACK	0x1453	Radio Shack
     vendor HUAWEI3COM	0x1472	Huawei-3Com
    +vendor ABOCOM2		0x1482	AboCom Systems
     vendor SILICOM		0x1485	Silicom
     vendor RALINK		0x148f	Ralink Technology
     vendor IMAGINATION	0x149a	Imagination Technologies
    @@ -610,6 +613,7 @@ vendor OQO		0x1557	OQO
     vendor UMEDIA		0x157e	U-MEDIA Communications
     vendor FIBERLINE	0x1582	Fiberline
     vendor SPARKLAN		0x15a9	SparkLAN
    +vendor AMIT2		0x15c5	AMIT
     vendor SOHOWARE		0x15e8	SOHOware
     vendor UMAX		0x1606	UMAX Data Systems
     vendor INSIDEOUT	0x1608	Inside Out Networks
    @@ -617,6 +621,7 @@ vendor AMOI		0x1614	Amoi Electronics
     vendor GOODWAY		0x1631	Good Way Technology
     vendor ENTREGA		0x1645	Entrega
     vendor ACTIONTEC	0x1668	Actiontec Electronics
    +vendor CISCOLINKSYS2	0x167b  Cisco-Linksys
     vendor ATHEROS		0x168c	Atheros Communications
     vendor GIGASET		0x1690	Gigaset
     vendor GLOBALSUN	0x16ab	Global Sun Technology
    @@ -626,6 +631,8 @@ vendor CMOTECH		0x16d8	C-motech
     vendor AXESSTEL		0x1726  Axesstel Co., Ltd.
     vendor LINKSYS4		0x1737	Linksys
     vendor SENAO		0x1740	Senao
    +vendor ASUS2		0x1761	ASUS
    +vendor SWEEX2		0x177f	Sweex
     vendor METAGEEK		0x1781	MetaGeek
     vendor AMIT		0x18c5	AMIT
     vendor QCOM		0x18e8	Qcom
    @@ -637,11 +644,15 @@ vendor TCTMOBILE	0x1bbb  TCT Mobile
     vendor TELIT		0x1bc7  Telit
     vendor MPMAN		0x1cae	MpMan
     vendor DRESDENELEKTRONIK 0x1cf1 dresden elektronik
    +vendor PEGATRON		0x1d4d	Pegatron
     vendor QISDA		0x1da5  Qisda
     vendor ALINK		0x1e0e  Alink
    +vendor AIRTIES		0x1eda	AirTies
     vendor DLINK		0x2001	D-Link
     vendor PLANEX2		0x2019	Planex Communications
     vendor TLAYTECH		0x20b9	Tlay Tech
    +vendor ENCORE		0x203d	Encore
    +vendor PARA		0x20b8	PARA Industrial
     vendor ERICSSON		0x2282	Ericsson
     vendor MOTOROLA2	0x22b8	Motorola
     vendor TRIPPLITE	0x2478	Tripp-Lite
    @@ -667,6 +678,7 @@ vendor ZINWELL		0x5a57	Zinwell
     vendor SITECOM		0x6189	Sitecom
     vendor ARKMICRO		0x6547	Arkmicro Technologies Inc.
     vendor 3COM2		0x6891	3Com
    +vendor EDIMAX		0x7392	Edimax
     vendor INTEL		0x8086	Intel
     vendor INTEL2		0x8087	Intel
     vendor SITECOM2		0x9016	Sitecom
    @@ -701,6 +713,12 @@ product 3COMUSR USR56K		0x3021	U.S. Robotics 56000 Voice FaxModem Pro
     /* AboCom products */
     product ABOCOM XX1		0x110c	XX1
     product ABOCOM XX2		0x200c	XX2
    +product ABOCOM RT2770		0x2770	RT2770
    +product ABOCOM RT2870		0x2870	RT2870
    +product ABOCOM RT3070		0x3070	RT3070
    +product ABOCOM RT3071		0x3071	RT3071
    +product ABOCOM RT3072		0x3072	RT3072
    +product ABOCOM2 RT2870_1	0x3c09	RT2870
     product ABOCOM URE450		0x4000	URE450 Ethernet Adapter
     product ABOCOM UFE1000		0x4002	UFE1000 Fast Ethernet Adapter
     product ABOCOM DSB650TX_PNA	0x4003	1/10/100 Ethernet Adapter
    @@ -731,6 +749,17 @@ product ACCTON SMCWUSBTG2_NF	0x4507	SMCWUSBT-G2 (no firmware)
     product ACCTON SMCWUSBTG2	0x4508	SMCWUSBT-G2
     product ACCTON PRISM_GT		0x4521	PrismGT USB 2.0 WLAN
     product ACCTON SS1001		0x5046	SpeedStream Ethernet Adapter
    +product ACCTON RT2870_2		0x6618	RT2870
    +product ACCTON RT3070		0x7511	RT3070
    +product ACCTON RT2770		0x7512	RT2770
    +product ACCTON RT2870_3		0x7522	RT2870
    +product ACCTON RT2870_5		0x8522	RT2870
    +product ACCTON RT3070_4		0xa512	RT3070
    +product ACCTON RT2870_4		0xa618	RT2870
    +product	ACCTON RT3070_1		0xa701	RT3070
    +product	ACCTON RT3070_2		0xa702	RT3070
    +product ACCTON RT2870_1		0xb522	RT2870
    +product	ACCTON RT3070_3		0xc522	RT3070
     product ACCTON ZD1211B		0xe501	ZD1211B
     
     /* Aceeca products */
    @@ -833,6 +862,9 @@ product AIRPLUS MCD650		0x3198	MCD650 modem
     /* AirPrime products */
     product AIRPRIME PC5220		0x0112	CDMA Wireless PC Card
     
    +/* AirTies products */
    +product AIRTIES RT3070		0x2310	RT3070
    +
     /* AKS products */
     product AKS USBHASP		0x0001	USB-HASP 0.06
     
    @@ -872,8 +904,20 @@ product APC UPS			0x0002	Uninterruptible Power Supply
     product AMBIT WLAN		0x0302	WLAN
     product AMBIT NTL_250		0x6098	NTL 250 cable modem
     
    +/* American Power Conversion products */
    +product APC UPS			0x0002	Uninterruptible Power Supply
    +
    +/* Amigo Technology products */
    +product AMIGO RT2870_1		0x9031	RT2870
    +product AMIGO RT2870_2		0x9041	RT2870
    +
     /* AMIT products */
     product AMIT CGWLUSB2GO		0x0002	CG-WLUSB2GO
    +product AMIT CGWLUSB2GNR	0x0008	CG-WLUSB2GNR
    +product AMIT RT2870_1		0x0012	RT2870
    +
    +/* AMIT(2) products */
    +product AMIT2 RT2870		0x0008	RT2870
     
     /* Anchor products */
     product ANCHOR EZUSB		0x2131	EZUSB
    @@ -933,6 +977,7 @@ product ASIX AX88772		0x7720	AX88772
     product ASIX AX88772A		0x772a	AX88772A USB 2.0 10/100 Ethernet
     
     /* ASUS products */
    +product ASUS2 USBN11		0x0b05	USB-N11
     product ASUS WL167G		0x1707	WL-167g Wireless Adapter
     product ASUS WL159G		0x170c	WL-159g
     product ASUS A9T_WIFI		0x171b	A9T wireless
    @@ -940,6 +985,12 @@ 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
    +product ASUS RT2870_1		0x1731	RT2870
    +product ASUS RT2870_2		0x1732	RT2870
    +product ASUS RT2870_3		0x1742	RT2870
    +product ASUS RT2870_4		0x1760	RT2870
    +product ASUS RT2870_5		0x1761	RT2870
    +product	ASUS RT3070		0x1784	RT3070
     product ASUS P535		0x420f	ASUS P535 PDA
     product	ASUS GMSC		0x422f	ASUS Generic Mass Storage
     product ASUS RT2570		0x1706	RT2500USB Wireless Adapter
    @@ -976,6 +1027,13 @@ product AVISION 1200U		0x0268	1200U scanner
     /* Axesstel products */
     product AXESSTEL DATAMODEM	0x1000  Data Modem
     
    +/* AsureWave products */
    +product AZUREWAVE RT2870_1	0x3247	RT2870
    +product AZUREWAVE RT2870_2	0x3262	RT2870
    +product AZUREWAVE RT3070_1	0x3273	RT3070
    +product	AZUREWAVE RT3070_2	0x3284	RT3070
    +product	AZUREWAVE RT3070_3	0x3305	RT3070
    +
     /* Baltech products */
     product BALTECH CARDREADER	0x9999	Card reader
     
    @@ -1006,8 +1064,13 @@ 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 RT2870_1		0x8053	RT2870
    +product BELKIN RT2870_2		0x805c	RT2870
    +product BELKIN F5D8053V3	0x815c	F5D8053 v3
    +product BELKIN F5D8055		0x825a	F5D8055
     product BELKIN F5D9050V3	0x905b	F5D9050 ver 3 Wireless Adapter
     product BELKIN2 F5U002		0x0002	F5U002 Parallel printer
    +product BELKIN F6D4050V1	0x935a	F6D4050 v1
     
     /* Billionton products */
     product BILLIONTON USB100	0x0986	USB100N 10/100 FastEthernet
    @@ -1084,6 +1147,7 @@ product CISCOLINKSYS HU200TS	0x001a	HU200TS Wireless Adapter
     product CISCOLINKSYS WUSB54GC	0x0020	WUSB54GC
     product CISCOLINKSYS WUSB54GR	0x0023	WUSB54GR
     product CISCOLINKSYS WUSBF54G	0x0024	WUSBF54G
    +product	CISCOLINKSYS2	RT3070	0x4001	RT3070
     
     /* CMOTECH products */
     product CMOTECH CNU510		0x5141	CDMA Technologies USB modem
    @@ -1110,6 +1174,15 @@ product CONCEPTRONIC AR5523_2	0x7811	AR5523
     product CONCEPTRONIC AR5523_2_NF	0x7812	AR5523 (no firmware)
     product CONCEPTRONIC2 C54RU	0x3c02	C54RU WLAN
     product CONCEPTRONIC2 C54RU2	0x3c22	C54RU
    +product CONCEPTRONIC2 VIGORN61	0x3c25	VIGORN61
    +product CONCEPTRONIC2 RT2870_1	0x3c06	RT2870
    +product CONCEPTRONIC2 RT2870_2	0x3c07	RT2870
    +product CONCEPTRONIC2 RT2870_7	0x3c09	RT2870
    +product CONCEPTRONIC2 RT2870_8	0x3c12	RT2870
    +product CONCEPTRONIC2 RT2870_3	0x3c23	RT2870
    +product CONCEPTRONIC2 RT2870_4	0x3c25	RT2870
    +product CONCEPTRONIC2 RT2870_5	0x3c27	RT2870
    +product CONCEPTRONIC2 RT2870_6	0x3c28	RT2870
     
     /* Connectix products */
     product CONNECTIX QUICKCAM	0x0001	QuickCam
    @@ -1124,6 +1197,12 @@ product COREGA FETHER_USB2_TX	0x0017	FEther USB2-TX
     product COREGA WLUSB_11_KEY	0x001a	ULUSB-11 Key
     product COREGA CGWLUSB2GL	0x002d	CG-WLUSB2GL
     product COREGA CGWLUSB2GPX	0x002e	CG-WLUSB2GPX
    +product COREGA RT2870_1		0x002f	RT2870
    +product COREGA RT2870_2		0x003c	RT2870
    +product COREGA RT2870_3		0x003f	RT2870
    +product COREGA RT3070		0x0041	RT3070
    +product COREGA CGWLUSB300GNM	0x0042	CG-WLUSB300GNM
    +
     product COREGA WLUSB_11_STICK	0x7613	WLAN USB Stick 11
     product COREGA FETHER_USB_TXC	0x9601	FEther USB-TXC
     
    @@ -1152,6 +1231,7 @@ product CYBERPOWER 1500CAVRLCD	0x0501	1500CAVRLCD
     
     /* CyberTAN Technology products */
     product CYBERTAN TG54USB	0x1666	TG54USB
    +product CYBERTAN RT2870		0x1828	RT2870
     
     /* Cypress Semiconductor products */
     product CYPRESS MOUSE		0x0001	mouse
    @@ -1229,6 +1309,8 @@ product DLINK DWLAG122		0x3a04	DWL-AG122
     product DLINK DWLAG122_NF	0x3a05	DWL-AG122 (no firmware)
     product DLINK DWLG122		0x3c00	DWL-G122 b1 Wireless Adapter
     product DLINK DUBE100B1		0x3c05	DUB-E100 rev B1
    +product DLINK RT2870		0x3c09	RT2870
    +product DLINK RT3072		0x3c0a	RT3072
     product DLINK DSB650C		0x4000	10Mbps Ethernet
     product DLINK DSB650TX1		0x4001	10/100 Ethernet
     product DLINK DSB650TX		0x4002	10/100 Ethernet
    @@ -1241,7 +1323,15 @@ product DLINK2 DWA120		0x3a0e	DWA-120
     product DLINK2 DWLG122C1	0x3c03	DWL-G122 c1
     product DLINK2 WUA1340		0x3c04	WUA-1340
     product DLINK2 DWA111		0x3c06	DWA-111
    +product DLINK2 RT2870_1		0x3c09	RT2870
     product DLINK2 DWA110		0x3c07	DWA-110
    +product DLINK2 RT3072		0x3c0a	RT3072
    +product DLINK2 RT3070_1		0x3c0d	RT3070
    +product DLINK2 RT3070_2		0x3c0e	RT3070
    +product DLINK2 RT3070_3		0x3c0f	RT3070
    +product DLINK2 RT2870_2		0x3c11	RT2870
    +product DLINK2 DWA130		0x3c13	DWA-130
    +product DLINK2 RT3070_4		0x3c15	RT3070
     product DLINK3 DWM652		0x3e04	DWM-652
     
     /* DMI products */
    @@ -1257,6 +1347,12 @@ product DRESDENELEKTRONIK WIRELESSHANDHELDTERMINAL  0x0004 Wireless Handheld Ter
     /* Dynastream Innovations */
     product DYNASTREAM ANTDEVBOARD	0x1003	ANT dev board
     
    +/* Edimax products */
    +product EDIMAX EW7318USG	0x7318	USB Wireless dongle
    +product EDIMAX RT2870_1		0x7711	RT2870
    +product EDIMAX EW7717		0x7717	EW-7717
    +product EDIMAX EW7718		0x7718	EW-7718
    +
     /* Eicon Networks */
     product EICON DIVA852		0x4905	Diva 852 ISDN TA
     
    @@ -1285,6 +1381,11 @@ product ELSA USB2ETHERNET	0x3000	Microlink USB2Ethernet
     /* EMS products */
     product EMS DUAL_SHOOTER	0x0003	PSX gun controller converter
     
    +/* Encore products */
    +product ENCORE RT3070_1		0x1480	RT3070
    +product ENCORE RT3070_2		0x14a1	RT3070
    +product ENCORE RT3070_3		0x14a9	RT3070
    +
     /* Entrega products */
     product ENTREGA 1S		0x0001	1S serial
     product ENTREGA 2S		0x0002	2S serial
    @@ -1429,6 +1530,11 @@ product GIGASET SMCWUSBTG_NF	0x0711	SMCWUSBT-G (no firmware)
     product GIGASET AR5523		0x0712	AR5523
     product GIGASET AR5523_NF	0x0713	AR5523 (no firmware)
     product GIGASET RT2573		0x0722	RT2573
    +product GIGASET RT3070_1	0x0740	RT3070
    +product GIGASET RT3070_2	0x0744	RT3070
    +product GIGABYTE RT2870_1	0x800b	RT2870
    +product GIGABYTE GNWB31N	0x800c	GN-WB31N
    +product GIGABYTE GNWB32L	0x800d	GN-WB32L
     
     /* Global Sun Technology product */
     product GLOBALSUN AR5523_1	0x7801	AR5523
    @@ -1464,6 +1570,7 @@ product GUILLEMOT DALEADER	0xa300	DA Leader
     product GUILLEMOT HWGUSB254	0xe000	HWGUSB2-54 WLAN
     product GUILLEMOT HWGUSB254LB	0xe010	HWGUSB2-54-LB
     product GUILLEMOT HWGUSB254V2AP	0xe020	HWGUSB2-54V2-AP
    +product GUILLEMOT HWNU300	0xe030	HWNU-300
     
     /* Hagiwara products */
     product HAGIWARA FGSM		0x0002	FlashGate SmartMedia Card Reader
    @@ -1482,6 +1589,10 @@ product HANDSPRING TREO600	0x0300	Handspring Treo 600
     product HAUPPAUGE WINTV_USB_FM	0x4d12	WinTV USB FM
     
     /* Hawking Technologies products */
    +product HAWKING RT2870_1	0x0001	RT2870
    +product HAWKING RT2870_2	0x0003	RT2870
    +product HAWKING HWUN2		0x0009	HWUN2
    +product HAWKING RT3070		0x000b	RT3070
     product HAWKING UF100		0x400c	10/100 USB Ethernet
     
     /* Hitachi, Ltd. products */
    @@ -1528,6 +1639,7 @@ product HP 2215			0x1016	iPAQ 22xx/Jornada 548
     product HP 568J			0x1116	Jornada 568
     product HP 930C			0x1204	DeskJet 930c
     product HP P2000U		0x1801	Inkjet P-2000U
    +product HP HS2300		0x1e1d  HS2300 HSDPA (aka MC8775)
     product HP 640C			0x2004	DeskJet 640c
     product HP 4670V		0x3005	ScanJet 4670v
     product HP P1100		0x3102	Photosmart P1100
    @@ -1655,6 +1767,10 @@ product IODATA USBETTXS		0x0913	USB ETTX
     product IODATA USBWNB11A	0x0919	USB WN-B11
     product IODATA USBWNB11		0x0922	USB Airport WN-B11
     product IODATA ETGUS2		0x0930	ETG-US2
    +product IODATA RT3072_1		0x0944	RT3072
    +product IODATA RT3072_2		0x0945	RT3072
    +product IODATA RT3072_3		0x0947	RT3072
    +product IODATA RT3072_4		0x0948	RT3072
     product IODATA USBRSAQ		0x0a03	Serial USB-RSAQ1
     product IODATA2 USB2SC		0x0a09	USB2.0-SCSI Bridge USB2-SC
     
    @@ -1779,7 +1895,11 @@ 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 WUSB100	0x0070	WUSB100
    +product LINKSYS4 WUSB600N	0x0071	WUSB600N
     product LINKSYS4 WUSB54GCV2	0x0073	WUSB54GC v2
    +product LINKSYS4 WUSB54GCV3	0x0077	WUSB54GC v3
    +product LINKSYS4 WUSB600NV2	0x0079	WUSB600N v2
     
     /* Logitech products */
     product LOGITECH M2452		0x0203	M2452 keyboard
    @@ -1809,6 +1929,9 @@ product LOGITECH QUICKCAMPRO2	0xd001	QuickCam Pro
     /* Logitec Corp. products */
     product LOGITEC LDR_H443SU2	0x0033	DVD Multi-plus unit LDR-H443SU2
     product LOGITEC LDR_H443U2	0x00b3	DVD Multi-plus unit LDR-H443U2
    +product LOGITEC RT2870_1	0x0162	RT2870
    +product LOGITEC RT2870_2	0x0163	RT2870
    +product LOGITEC RT2870_3	0x0164	RT2870
     
     /* Lucent products */
     product LUCENT EVALKIT		0x1001	USS-720 evaluation kit
    @@ -1846,7 +1969,10 @@ product MELCO PCOPRS1		0x00b3	PC-OP-RS1 RemoteStation
     product MELCO SG54HP		0x00d8	WLI-U2-SG54HP
     product MELCO G54HP		0x00d9	WLI-U2-G54HP
     product MELCO KG54L		0x00da	WLI-U2-KG54L
    +product MELCO WLIUCG300N	0x00e8	WLI-UC-G300N
     product MELCO SG54HG		0x00f4	WLI-U2-SG54HG
    +product MELCO WLIUCAG300N	0x012e	WLI-UC-AG300N
    +product MELCO WLIUCGN		0x015d	WLI-UC-GN
     
     /* Merlin products */
     product MERLIN V620             0x1110  Merlin V620
    @@ -1864,15 +1990,25 @@ product MGE UPS2		0xffff	MGE UPS SYSTEMS PROTECTIONCENTER 2
     
     /* Micro Star International products */
     product MSI BT_DONGLE		0x1967	Bluetooth USB dongle
    +product MSI RT3070_1		0x3820	RT3070
    +product MSI RT3070_2		0x3821	RT3070
    +product MSI RT3070_3		0x3870	RT3070
     product MSI UB11B		0x6823	UB11B
     product MSI RT2570		0x6861	RT2570
     product MSI RT2570_2		0x6865	RT2570
     product MSI RT2570_3		0x6869	RT2570
     product MSI RT2573_1		0x6874	RT2573
     product MSI RT2573_2		0x6877	RT2573
    +product MSI RT3070_4		0x6899	RT3070
    +product MSI RT3070_5		0x821a	RT3070
    +product MSI RT3070_6		0x870a	RT3070
    +product MSI RT3070_7		0x899a	RT3070
     product MSI RT2573_3		0xa861	RT2573
     product MSI RT2573_4		0xa874	RT2573
     
    +/* Microdia products */
    +product MICRODIA TWINKLECAM	0x600d	TwinkleCam USB camera
    +
     /* Microsoft products */
     product MICROSOFT SIDEPREC	0x0008	SideWinder Precision Pro
     product MICROSOFT INTELLIMOUSE	0x0009	IntelliMouse
    @@ -2021,8 +2157,12 @@ product NIKON D300		0x041a  Digital Camera D300
     product NOVATECH NV902		0x9020	NovaTech NV-902W
     product NOVATECH RT2573		0x9021	RT2573
     
    +/* Nokia products */
    +product NOKIA N958GB		0x0070	Nokia N95 8GBc
    +
     /* Novatel Wireless products */
     product NOVATEL V640		0x1100	Merlin V620
    +product NOVATEL CDMA_MODEM	0x1110	Novatel Wireless Merlin CDMA
     product NOVATEL V620		0x1110	Merlin V620
     product NOVATEL V740		0x1120	Merlin V740
     product NOVATEL V720		0x1130	Merlin V720
    @@ -2034,6 +2174,7 @@ product NOVATEL X950D		0x1450	Merlin X950D
     product NOVATEL ES620		0x2100	Expedite ES620
     product NOVATEL E725		0x2120	Expedite E725
     product NOVATEL ES620_2		0x2130	Expedite ES620
    +product NOVATEL ES620		0x2100	ES620 CDMA
     product NOVATEL U720		0x2110	Merlin U720
     product NOVATEL EU730		0x2400	Expedite EU730
     product NOVATEL EU740		0x2410	Expedite EU740
    @@ -2140,6 +2281,14 @@ product PANASONIC KXLCB20AN	0x0d0a	CD-R Drive KXL-CB20AN
     product PANASONIC KXLCB35AN	0x0d0e	DVD-ROM & CD-R/RW
     product PANASONIC SDCAAE	0x1b00	MultiMediaCard
     
    +/* PARA Industrial products */
    +product PARA RT3070		0x8888	RT3070
    + 	 
    +/* Pegatron products */
    +product PEGATRON RT2870		0x0002	RT2870
    +product PEGATRON RT3070		0x000c	RT3070
    +product PEGATRON RT3070_2	0x000e	RT3070
    +
     /* Peracom products */
     product PERACOM SERIAL1		0x0001	Serial
     product PERACOM ENET		0x0002	Ethernet
    @@ -2157,6 +2306,7 @@ product PHILIPS SPE3030CC	0x083a	USB 2.0 External Disk
     product PHILIPS SNU5600		0x1236	SNU5600
     product PHILIPS UM10016		0x1552	ISP 1581 Hi-Speed USB MPEG2 Encoder Reference Kit
     product PHILIPS DIVAUSB		0x1801	DIVA USB mp3 player
    +product PHILIPS RT2870		0x200f	RT2870
     
     /* Philips Semiconductor products */
     product PHILIPSSEMI HUB1122	0x1122	HUB
    @@ -2172,11 +2322,15 @@ product PLANEX GW_US11H		0x14ea	GW-US11H WLAN
     product PLANEX2 GW_US11S	0x3220	GW-US11S WLAN
     product PLANEX2 GW_US54GXS	0x5303	GW-US54GXS WLAN
     product PLANEX2 GWUS54HP	0xab01	GW-US54HP
    +product PLANEX2 GWUS300MINIS	0xab24	GW-US300MiniS
    +product PLANEX2	RT3070		0xab25	RT3070
     product PLANEX2 GWUS54MINI2	0xab50	GW-US54Mini2
     product PLANEX2 GWUS54SG	0xc002	GW-US54SG
     product PLANEX2 GWUS54GZL	0xc007	GW-US54GZL
     product PLANEX2 GWUS54GD	0xed01	GW-US54GD
     product PLANEX2 GWUSMM		0xed02	GW-USMM
    +product PLANEX2 RT2870		0xed06	RT2870
    +product PLANEX2 GWUSMICRON	0xed14	GW-USMicroN
     product PLANEX3 GWUS54GZ	0xab10	GW-US54GZ
     product PLANEX3 GU1000T		0xab11	GU-1000T
     product PLANEX3 GWUS54MINI	0xab13	GW-US54Mini
    @@ -2234,6 +2388,7 @@ product PUTERCOM UPA100		0x047e	USB-1284 BRIDGE
     product QCOM RT2573		0x6196	RT2573
     product QCOM RT2573_2		0x6229	RT2573
     product QCOM RT2573_3		0x6238	RT2573
    +product QCOM RT2870		0x6259	RT2870
     
     /* Qisda products */
     product QISDA H21_1		0x4512	3G modem
    @@ -2320,6 +2475,8 @@ product QUALCOMMINC E2002	0x2002	3G modem
     product QUALCOMMINC E2003	0x2003	3G modem
     
     /* Quanta products */
    +/* Quanta products */
    +product QUANTA RT3070		0x0304	RT3070
     product QUANTA Q101		0xea02	HSDPA modem
     product QUANTA Q111		0xea03	HSDPA modem
     product QUANTA GLX		0xea04	HSDPA modem
    @@ -2340,9 +2497,16 @@ product RAINBOW IKEY2000	0x1200	i-Key 2000
     
     /* Ralink Technology products */
     product RALINK RT2570		0x1706	RT2500USB Wireless Adapter
    +product RALINK RT2070		0x2070	RT2070
     product RALINK RT2570_2		0x2570	RT2500USB Wireless Adapter
     product RALINK RT2573		0x2573	RT2501USB Wireless Adapter
     product RALINK RT2671		0x2671	RT2601USB Wireless Adapter
    +product RALINK RT2770		0x2770	RT2770
    +product RALINK RT2870		0x2870	RT2870
    +product RALINK RT3070		0x3070	RT3070
    +product RALINK RT3071		0x3071	RT3071
    +product RALINK RT3072		0x3072	RT3072
    +product RALINK RT3572		0x3572	RT3572
     product RALINK RT2570_3		0x9020	RT2500USB Wireless Adapter
     product RALINK RT2573_2		0x9021	RT2501USB Wireless Adapter
     
    @@ -2383,6 +2547,7 @@ product SAGEM XG76NA		0x0062	XG-76NA
     product SAMSUNG ML6060		0x3008	ML-6060 laser printer
     product SAMSUNG YP_U2		0x5050	YP-U2 MP3 Player
     product SAMSUNG I500		0x6601	I500 Palm USB Phone 
    +product SAMSUNG2 RT2870_1	0x2018	RT2870
     
     /* Samsung Techwin products */
     product SAMSUNG_TECHWIN DIGIMAX_410	0x000a	Digimax 410
    @@ -2406,7 +2571,18 @@ product SCANLOGIC SL11R		0x0002	SL11R IDE Adapter
     product SCANLOGIC 336CX		0x0300	Phantom 336CX - C3 scanner
     
     /* Senao products */
    +product SENAO RT2870_3		0x0605	RT2870
    +product SENAO RT2870_4		0x0615	RT2870
     product SENAO NUB8301		0x2000	NUB-8301
    +product SENAO RT2870_1		0x9701	RT2870
    +product SENAO RT2870_2		0x9702	RT2870
    +product SENAO RT3070		0x9703	RT3070
    +product SENAO RT3071		0x9705	RT3071
    +product SENAO RT3072_1		0x9706	RT3072
    +product SENAO RT3072_2		0x9707	RT3072
    +product SENAO RT3072_3		0x9708	RT3072
    +product SENAO RT3072_4		0x9709	RT3072
    +product SENAO RT3072_5		0x9801	RT3072
     
     /* ShanTou products */
     product SHANTOU ST268		0x0268	ST268
    @@ -2453,7 +2629,9 @@ product SIEMENS3 X75		0x0004	X75
     product SIERRA EM5625		0x0017	EM5625
     product SIERRA MC5720_2		0x0018	MC5720
     product SIERRA MC5725		0x0020	MC5725
    +product SIERRA AIRCARD580	0x0112	Sierra Wireless AirCard 580
     product SIERRA AIRCARD595	0x0019	Sierra Wireless AirCard 595
    +product SIERRA AC595U		0x0120	Sierra Wireless AirCard 595U
     product SIERRA AC597E		0x0021	Sierra Wireless AirCard 597E
     product SIERRA EM5725		0x0022	EM5725
     product SIERRA C597		0x0023	Sierra Wireless Compass 597
    @@ -2553,8 +2731,24 @@ product SITECOM SERIAL		0x2068	USB to serial cable (v2)
     product SITECOM2 WL022		0x182d	WL-022
     
     /* Sitecom Europe products */
    +product SITECOMEU RT2870_1	0x0017	RT2870
     product SITECOMEU WL168V1	0x000d	WL-168 v1
     product SITECOMEU WL168V4	0x0028	WL-168 v4
    +product SITECOMEU RT2870_2	0x002b	RT2870
    +product SITECOMEU RT2870_3	0x002c	RT2870
    +product SITECOMEU RT2870_4	0x002d	RT2870
    +product SITECOMEU RT2770	0x0039	RT2770
    +product SITECOMEU RT3070_2	0x003b	RT3070
    +product SITECOMEU RT3070_3	0x003c	RT3070
    +product SITECOMEU RT3070_4	0x003d	RT3070
    +product SITECOMEU RT3070	0x003e	RT3070
    +product SITECOMEU WL608		0x003f	WL-608
    +product SITECOMEU RT3072_1	0x0041	RT3072
    +product SITECOMEU RT3072_2	0x0042	RT3072
    +product SITECOMEU RT3072_3	0x0047	RT3072
    +product SITECOMEU RT3072_4	0x0048	RT3072
    +product SITECOMEU RT3072_5	0x004a	RT3072
    +product SITECOMEU RT3072_6	0x004d	RT3072
     product SITECOMEU LN028		0x061c	LN-028
     product SITECOMEU WL113		0x9071	WL-113
     product SITECOMEU ZD1211B	0x9075	ZD1211B
    @@ -2612,7 +2806,9 @@ product SOURCENEXT KEIKAI8	0x039f	KeikaiDenwa 8
     product SOURCENEXT KEIKAI8_CHG	0x012e	KeikaiDenwa 8 with charger
     
     /* SparkLAN products */
    -product SPARKLAN RT2573		0x0004	 RT2573
    +product SPARKLAN RT2573		0x0004	RT2573
    +product SPARKLAN RT2870_1	0x0006	RT2870
    +product SPARKLAN RT3070		0x0010	RT3070
     
     /* Sphairon Access Systems GmbH products */
     product SPHAIRON UB801R		0x0110	UB801R
    @@ -2682,6 +2878,8 @@ product SURECOM RT2573		0x31f3	RT2573
     
     /* Sweex products */
     product SWEEX ZD1211		0x1809	ZD1211
    +product SWEEX2 LW303		0x0302	LW303
    +product SWEEX2 LW313		0x0313	LW313
     
     /* System TALKS, Inc. */
     product SYSTEMTALKS SGCX2UL	0x1920	SGC-X2UL
    @@ -2775,6 +2973,7 @@ product UMEDIA TEW444UBEU_NF	0x3007	TEW-444UB EU (no firmware)
     product UMEDIA TEW429UB_A	0x300a	TEW-429UB_A
     product UMEDIA TEW429UB		0x300b	TEW-429UB
     product UMEDIA TEW429UBC1	0x300d	TEW-429UB C1
    +product UMEDIA RT2870_1		0x300e	RT2870
     product UMEDIA ALL0298V2	0x3204	ALL0298 v2
     product UMEDIA AR5523_2		0x3205	AR5523
     product UMEDIA AR5523_2_NF	0x3206	AR5523 (no firmware)
    @@ -2884,9 +3083,16 @@ product ZCOM AR5523		0x0012	AR5523
     product ZCOM AR5523_NF		0x0013	AR5523 driver (no firmware)
     product ZCOM XM142		0x0015	XM-142
     product ZCOM ZD1211B		0x001a	ZD1211B
    +product ZCOM RT2870_1		0x0022	RT2870
    +product ZCOM RT2870_2		0x0025	RT2870
     
     /* Zinwell products */
     product ZINWELL RT2570		0x0260	RT2570
    +product ZINWELL RT2870_1	0x0280	RT2870
    +product ZINWELL RT2870_2	0x0282	RT2870
    +product ZINWELL RT3072_1	0x0283	RT3072
    +product ZINWELL RT3072_2	0x0284	RT3072
    +product ZINWELL RT3070		0x5257	RT3070
     
     /* Zoom Telephonics, Inc. products */
     product ZOOM 2986L		0x9700	2986L Fax modem
    @@ -2907,3 +3113,4 @@ product ZYXEL AG225H		0x3409	AG-225H
     product ZYXEL M202		0x340a	M-202
     product ZYXEL G220V2		0x340f	G-220 v2
     product ZYXEL G202		0x3410	G-202
    +product ZYXEL RT2870_1		0x3416	RT2870
    diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
    new file mode 100644
    index 00000000000..92acd470467
    --- /dev/null
    +++ b/sys/dev/usb/wlan/if_run.c
    @@ -0,0 +1,4143 @@
    +/*	$FreeBSD$	*/
    +
    +/*-
    + * Copyright (c) 2008,2009 Damien Bergamini 
    + *	ported to FreeBSD by Akinori Furukoshi 
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +/* release date Jan. 09, 2010 */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +/*-
    + * Ralink Technology RT2700U/RT2800U/RT3000U chipset driver.
    + * http://www.ralinktech.com/
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#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 run_debug
    +#include 
    +
    +#include "if_runreg.h"		/* shared with ral(4) */
    +#include "if_runvar.h"
    +
    +#define nitems(_a)      (sizeof((_a)) / sizeof((_a)[0]))
    +
    +#if	USB_DEBUG
    +#define RUN_DEBUG
    +#endif
    +
    +#ifdef	RUN_DEBUG
    +int run_debug = 0;
    +SYSCTL_NODE(_hw_usb, OID_AUTO, run, CTLFLAG_RW, 0, "USB run");
    +SYSCTL_INT(_hw_usb_run, OID_AUTO, debug, CTLFLAG_RW, &run_debug, 0,
    +    "run debug level");
    +#endif
    +
    +#define IEEE80211_HAS_ADDR4(wh) \
    +	(((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
    +
    +static const struct usb_device_id run_devs[] = {
    +    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2770) },
    +    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2870) },
    +    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT3070) },
    +    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT3071) },
    +    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT3072) },
    +    { USB_VP(USB_VENDOR_ABOCOM2,	USB_PRODUCT_ABOCOM2_RT2870_1) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT2770) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT2870_1) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT2870_2) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT2870_3) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT2870_4) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT2870_5) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070_1) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070_2) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070_3) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070_4) },
    +    { USB_VP(USB_VENDOR_AIRTIES,	USB_PRODUCT_AIRTIES_RT3070) },
    +    { USB_VP(USB_VENDOR_AMIGO,		USB_PRODUCT_AMIGO_RT2870_1) },
    +    { USB_VP(USB_VENDOR_AMIGO,		USB_PRODUCT_AMIGO_RT2870_2) },
    +    { USB_VP(USB_VENDOR_AMIT,		USB_PRODUCT_AMIT_CGWLUSB2GNR) },
    +    { USB_VP(USB_VENDOR_AMIT,		USB_PRODUCT_AMIT_RT2870_1) },
    +    { USB_VP(USB_VENDOR_AMIT2,		USB_PRODUCT_AMIT2_RT2870) },
    +    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2870_1) },
    +    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2870_2) },
    +    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2870_3) },
    +    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2870_4) },
    +    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2870_5) },
    +    { USB_VP(USB_VENDOR_ASUS2,		USB_PRODUCT_ASUS2_USBN11) },
    +    { USB_VP(USB_VENDOR_AZUREWAVE,	USB_PRODUCT_AZUREWAVE_RT2870_1) },
    +    { USB_VP(USB_VENDOR_AZUREWAVE,	USB_PRODUCT_AZUREWAVE_RT2870_2) },
    +    { USB_VP(USB_VENDOR_AZUREWAVE,	USB_PRODUCT_AZUREWAVE_RT3070_1) },
    +    { USB_VP(USB_VENDOR_AZUREWAVE,	USB_PRODUCT_AZUREWAVE_RT3070_2) },
    +    { USB_VP(USB_VENDOR_AZUREWAVE,	USB_PRODUCT_AZUREWAVE_RT3070_3) },
    +    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D8053V3) },
    +    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D8055) },
    +    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F6D4050V1) },
    +    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_RT2870_1) },
    +    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_RT2870_2) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_1) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_2) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_3) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_4) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_5) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_6) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_7) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_8) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_VIGORN61) },
    +    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB300GNM) },
    +    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_RT2870_1) },
    +    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_RT2870_2) },
    +    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_RT2870_3) },
    +    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_RT3070) },
    +    { USB_VP(USB_VENDOR_CYBERTAN,	USB_PRODUCT_CYBERTAN_RT2870) },
    +    { USB_VP(USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_RT2870) },
    +    { USB_VP(USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_RT3072) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA130) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT2870_1) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT2870_2) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3070_1) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3070_2) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3070_3) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3070_4) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3072) },
    +    { USB_VP(USB_VENDOR_EDIMAX,		USB_PRODUCT_EDIMAX_EW7717) },
    +    { USB_VP(USB_VENDOR_EDIMAX,		USB_PRODUCT_EDIMAX_EW7718) },
    +    { USB_VP(USB_VENDOR_EDIMAX,		USB_PRODUCT_EDIMAX_RT2870_1) },
    +    { USB_VP(USB_VENDOR_ENCORE,		USB_PRODUCT_ENCORE_RT3070_1) },
    +    { USB_VP(USB_VENDOR_ENCORE,		USB_PRODUCT_ENCORE_RT3070_2) },
    +    { USB_VP(USB_VENDOR_ENCORE,		USB_PRODUCT_ENCORE_RT3070_3) },
    +    { USB_VP(USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_GNWB31N) },
    +    { USB_VP(USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_GNWB32L) },
    +    { USB_VP(USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_RT2870_1) },
    +    { USB_VP(USB_VENDOR_GIGASET,	USB_PRODUCT_GIGASET_RT3070_1) },
    +    { USB_VP(USB_VENDOR_GIGASET,	USB_PRODUCT_GIGASET_RT3070_2) },
    +    { USB_VP(USB_VENDOR_GUILLEMOT,	USB_PRODUCT_GUILLEMOT_HWNU300) },
    +    { USB_VP(USB_VENDOR_HAWKING,	USB_PRODUCT_HAWKING_HWUN2) },
    +    { USB_VP(USB_VENDOR_HAWKING,	USB_PRODUCT_HAWKING_RT2870_1) },
    +    { USB_VP(USB_VENDOR_HAWKING,	USB_PRODUCT_HAWKING_RT2870_2) },
    +    { USB_VP(USB_VENDOR_HAWKING,	USB_PRODUCT_HAWKING_RT3070) },
    +    { USB_VP(USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_RT3072_1) },
    +    { USB_VP(USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_RT3072_2) },
    +    { USB_VP(USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_RT3072_3) },
    +    { USB_VP(USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_RT3072_4) },
    +    { USB_VP(USB_VENDOR_LINKSYS4,	USB_PRODUCT_LINKSYS4_WUSB100) },
    +    { USB_VP(USB_VENDOR_LINKSYS4,	USB_PRODUCT_LINKSYS4_WUSB54GCV3) },
    +    { USB_VP(USB_VENDOR_LINKSYS4,	USB_PRODUCT_LINKSYS4_WUSB600N) },
    +    { USB_VP(USB_VENDOR_LINKSYS4,	USB_PRODUCT_LINKSYS4_WUSB600NV2) },
    +    { USB_VP(USB_VENDOR_LOGITEC,	USB_PRODUCT_LOGITEC_RT2870_1) },
    +    { USB_VP(USB_VENDOR_LOGITEC,	USB_PRODUCT_LOGITEC_RT2870_2) },
    +    { USB_VP(USB_VENDOR_LOGITEC,	USB_PRODUCT_LOGITEC_RT2870_3) },
    +    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_WLIUCAG300N) },
    +    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_WLIUCG300N) },
    +    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_WLIUCGN) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_1) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_2) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_3) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_4) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_5) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_6) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_7) },
    +    { USB_VP(USB_VENDOR_PARA,		USB_PRODUCT_PARA_RT3070) },
    +    { USB_VP(USB_VENDOR_PEGATRON,	USB_PRODUCT_PEGATRON_RT2870) },
    +    { USB_VP(USB_VENDOR_PEGATRON,	USB_PRODUCT_PEGATRON_RT3070) },
    +    { USB_VP(USB_VENDOR_PEGATRON,	USB_PRODUCT_PEGATRON_RT3070_2) },
    +    { USB_VP(USB_VENDOR_PHILIPS,	USB_PRODUCT_PHILIPS_RT2870) },
    +    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUS300MINIS) },
    +    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUSMICRON) },
    +    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_RT2870) },
    +    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_RT3070) },
    +    { USB_VP(USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2870) },
    +    { USB_VP(USB_VENDOR_QUANTA,		USB_PRODUCT_QUANTA_RT3070) },
    +    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2070) },
    +    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2770) },
    +    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2870) },
    +    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT3070) },
    +    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT3071) },
    +    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT3072) },
    +    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT3572) },
    +    { USB_VP(USB_VENDOR_SAMSUNG2,	USB_PRODUCT_SAMSUNG2_RT2870_1) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT2870_1) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT2870_2) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT2870_3) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT2870_4) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT3070) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT3071) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT3072_1) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT3072_2) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT3072_3) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT3072_4) },
    +    { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT3072_5) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT2770) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT2870_1) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT2870_2) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT2870_3) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT2870_4) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3070) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3070_2) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3070_3) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3070_4) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3072_1) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3072_2) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3072_3) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3072_4) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3072_5) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3072_6) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_WL608) },
    +    { USB_VP(USB_VENDOR_SPARKLAN,	USB_PRODUCT_SPARKLAN_RT2870_1) },
    +    { USB_VP(USB_VENDOR_SPARKLAN,	USB_PRODUCT_SPARKLAN_RT3070) },
    +    { USB_VP(USB_VENDOR_SWEEX2,		USB_PRODUCT_SWEEX2_LW303) },
    +    { USB_VP(USB_VENDOR_SWEEX2,		USB_PRODUCT_SWEEX2_LW313) },
    +    { USB_VP(USB_VENDOR_UMEDIA,		USB_PRODUCT_UMEDIA_RT2870_1) },
    +    { USB_VP(USB_VENDOR_ZCOM,		USB_PRODUCT_ZCOM_RT2870_1) },
    +    { USB_VP(USB_VENDOR_ZCOM,		USB_PRODUCT_ZCOM_RT2870_2) },
    +    { USB_VP(USB_VENDOR_ZINWELL,	USB_PRODUCT_ZINWELL_RT2870_1) },
    +    { USB_VP(USB_VENDOR_ZINWELL,	USB_PRODUCT_ZINWELL_RT2870_2) },
    +    { USB_VP(USB_VENDOR_ZINWELL,	USB_PRODUCT_ZINWELL_RT3070) },
    +    { USB_VP(USB_VENDOR_ZINWELL,	USB_PRODUCT_ZINWELL_RT3072_1) },
    +    { USB_VP(USB_VENDOR_ZINWELL,	USB_PRODUCT_ZINWELL_RT3072_2) },
    +    { USB_VP(USB_VENDOR_ZYXEL,		USB_PRODUCT_ZYXEL_RT2870_1) },
    +};
    +
    +MODULE_DEPEND(run, wlan, 1, 1, 1);
    +MODULE_DEPEND(run, wlan_amrr, 1, 1, 1);
    +MODULE_DEPEND(run, usb, 1, 1, 1);
    +MODULE_DEPEND(run, firmware, 1, 1, 1);
    +
    +static device_probe_t	run_match;
    +static device_attach_t	run_attach;
    +static device_detach_t	run_detach;
    +
    +static usb_callback_t	run_bulk_rx_callback;
    +static usb_callback_t	run_bulk_tx_callback0;
    +static usb_callback_t	run_bulk_tx_callback1;
    +static usb_callback_t	run_bulk_tx_callback2;
    +static usb_callback_t	run_bulk_tx_callback3;
    +static usb_callback_t	run_bulk_tx_callback4;
    +static usb_callback_t	run_bulk_tx_callback5;
    +
    +static void	run_bulk_tx_callbackN(struct usb_xfer *xfer,
    +		    usb_error_t error, unsigned int index);
    +static struct ieee80211vap *run_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	run_vap_delete(struct ieee80211vap *);
    +static void	run_setup_tx_list(struct run_softc *,
    +		    struct run_endpoint_queue *);
    +static void	run_unsetup_tx_list(struct run_softc *,
    +		    struct run_endpoint_queue *);
    +static int	run_load_microcode(struct run_softc *);
    +static int	run_reset(struct run_softc *);
    +static usb_error_t run_do_request(struct run_softc *,
    +		    struct usb_device_request *, void *);
    +static int	run_read(struct run_softc *, uint16_t, uint32_t *);
    +static int	run_read_region_1(struct run_softc *, uint16_t, uint8_t *, int);
    +static int	run_write_2(struct run_softc *, uint16_t, uint16_t);
    +static int	run_write(struct run_softc *, uint16_t, uint32_t);
    +static int	run_write_region_1(struct run_softc *, uint16_t,
    +		    const uint8_t *, int);
    +static int	run_set_region_4(struct run_softc *, uint16_t, uint32_t, int);
    +static int	run_efuse_read_2(struct run_softc *, uint16_t, uint16_t *);
    +static int	run_eeprom_read_2(struct run_softc *, uint16_t, uint16_t *);
    +static int	run_rt2870_rf_write(struct run_softc *, uint8_t, uint32_t);
    +static int	run_rt3070_rf_read(struct run_softc *, uint8_t, uint8_t *);
    +static int	run_rt3070_rf_write(struct run_softc *, uint8_t, uint8_t);
    +static int	run_bbp_read(struct run_softc *, uint8_t, uint8_t *);
    +static int	run_bbp_write(struct run_softc *, uint8_t, uint8_t);
    +static int	run_mcu_cmd(struct run_softc *, uint8_t, uint16_t);
    +static const char *run_get_rf(int);
    +static int	run_read_eeprom(struct run_softc *);
    +static struct ieee80211_node *run_node_alloc(struct ieee80211vap *,
    +			    const uint8_t mac[IEEE80211_ADDR_LEN]);
    +static int	run_media_change(struct ifnet *);
    +static int	run_newstate(struct ieee80211vap *, enum ieee80211_state, int);
    +static int	run_wme_update(struct ieee80211com *);
    +static void	run_wme_update_cb(void *, int);
    +static void	run_key_update_begin(struct ieee80211vap *);
    +static void	run_key_update_end(struct ieee80211vap *);
    +static int	run_key_set(struct ieee80211vap *, const struct ieee80211_key *,
    +			    const uint8_t mac[IEEE80211_ADDR_LEN]);
    +static int	run_key_delete(struct ieee80211vap *,
    +		    const struct ieee80211_key *);
    +static void	run_amrr_start(struct run_softc *, struct ieee80211_node *);
    +static void	run_amrr_to(void *);
    +static void	run_amrr_cb(void *, int);
    +static void	run_iter_func(void *, struct ieee80211_node *);
    +static void	run_newassoc(struct ieee80211_node *, int);
    +static void	run_rx_frame(struct run_softc *, struct mbuf *, uint32_t);
    +static void	run_tx_free(struct run_endpoint_queue *pq,
    +		    struct run_tx_data *, int);
    +static void	run_set_tx_desc(struct run_softc *, struct run_tx_data *,
    +		    uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
    +static int	run_tx(struct run_softc *, struct mbuf *,
    +		    struct ieee80211_node *);
    +static int	run_tx_mgt(struct run_softc *, struct mbuf *,
    +		    struct ieee80211_node *);
    +static int	run_sendprot(struct run_softc *, const struct mbuf *,
    +		    struct ieee80211_node *, int, int);
    +static int	run_tx_param(struct run_softc *, struct mbuf *,
    +		    struct ieee80211_node *,
    +		    const struct ieee80211_bpf_params *);
    +static int	run_raw_xmit(struct ieee80211_node *, struct mbuf *,
    +		    const struct ieee80211_bpf_params *);
    +static void	run_start(struct ifnet *);
    +static int	run_ioctl(struct ifnet *, u_long, caddr_t);
    +static void	run_select_chan_group(struct run_softc *, int);
    +static void	run_set_rx_antenna(struct run_softc *, int);
    +static void	run_rt2870_set_chan(struct run_softc *, u_int);
    +static void	run_rt3070_set_chan(struct run_softc *, u_int);
    +static int	run_set_chan(struct run_softc *, struct ieee80211_channel *);
    +static void	run_set_channel(struct ieee80211com *);
    +static void	run_scan_start(struct ieee80211com *);
    +static void	run_scan_end(struct ieee80211com *);
    +static uint8_t	run_rate2mcs(uint8_t);
    +static void	run_update_beacon(struct ieee80211vap *, int);
    +static void	run_update_beacon_locked(struct ieee80211vap *, int);
    +static void	run_updateprot(struct ieee80211com *);
    +static void	run_usb_timeout_cb(void *, int);
    +static void	run_reset_livelock(struct run_softc *);
    +static void	run_enable_tsf_sync(struct run_softc *);
    +static void	run_enable_mrr(struct run_softc *);
    +static void	run_set_txpreamble(struct run_softc *);
    +static void	run_set_basicrates(struct run_softc *);
    +static void	run_set_leds(struct run_softc *, uint16_t);
    +static void	run_set_bssid(struct run_softc *, const uint8_t *);
    +static void	run_set_macaddr(struct run_softc *, const uint8_t *);
    +static void	run_updateslot(struct ifnet *);
    +static int8_t	run_rssi2dbm(struct run_softc *, uint8_t, uint8_t);
    +static void	run_update_promisc_locked(struct ifnet *);
    +static void	run_update_promisc(struct ifnet *);
    +static int	run_bbp_init(struct run_softc *);
    +static int	run_rt3070_rf_init(struct run_softc *);
    +static int	run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t,
    +		    uint8_t *);
    +static int	run_txrx_enable(struct run_softc *);
    +static void	run_init(void *);
    +static void	run_init_locked(struct run_softc *);
    +static void	run_stop(void *);
    +static void	run_delay(struct run_softc *, unsigned int);
    +
    +static const struct {
    +	uint32_t	reg;
    +	uint32_t	val;
    +} rt2870_def_mac[] = {
    +	RT2870_DEF_MAC
    +};
    +
    +static const struct {
    +	uint8_t	reg;
    +	uint8_t	val;
    +} rt2860_def_bbp[] = {
    +	RT2860_DEF_BBP
    +};
    +
    +static const struct rfprog {
    +	uint8_t		chan;
    +	uint32_t	r1, r2, r3, r4;
    +} rt2860_rf2850[] = {
    +	RT2860_RF2850
    +};
    +
    +struct {
    +	uint8_t	n, r, k;
    +} run_rf3020_freqs[] = {
    +	RT3070_RF3020
    +};
    +
    +static const struct {
    +	uint8_t	reg;
    +	uint8_t	val;
    +} rt3070_def_rf[] = {
    +	RT3070_DEF_RF
    +};
    +
    +static const struct usb_config run_config[RUN_N_XFER] = {
    +    [RUN_BULK_TX_BE] = {
    +	.type = UE_BULK,
    +	.endpoint = UE_ADDR_ANY,
    +	.ep_index = 0,
    +	.direction = UE_DIR_OUT,
    +	.bufsize = RUN_MAX_TXSZ,
    +	.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
    +	.callback = run_bulk_tx_callback0,
    +	.timeout = 5000,	/* ms */
    +    },
    +    [RUN_BULK_TX_BK] = {
    +	.type = UE_BULK,
    +	.endpoint = UE_ADDR_ANY,
    +	.direction = UE_DIR_OUT,
    +	.ep_index = 1,
    +	.bufsize = RUN_MAX_TXSZ,
    +	.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
    +	.callback = run_bulk_tx_callback1,
    +	.timeout = 5000,	/* ms */
    +    },
    +    [RUN_BULK_TX_VI] = {
    +	.type = UE_BULK,
    +	.endpoint = UE_ADDR_ANY,
    +	.direction = UE_DIR_OUT,
    +	.ep_index = 2,
    +	.bufsize = RUN_MAX_TXSZ,
    +	.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
    +	.callback = run_bulk_tx_callback2,
    +	.timeout = 5000,	/* ms */
    +    },
    +    [RUN_BULK_TX_VO] = {
    +	.type = UE_BULK,
    +	.endpoint = UE_ADDR_ANY,
    +	.direction = UE_DIR_OUT,
    +	.ep_index = 3,
    +	.bufsize = RUN_MAX_TXSZ,
    +	.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
    +	.callback = run_bulk_tx_callback3,
    +	.timeout = 5000,	/* ms */
    +    },
    +    [RUN_BULK_TX_HCCA] = {
    +	.type = UE_BULK,
    +	.endpoint = UE_ADDR_ANY,
    +	.direction = UE_DIR_OUT,
    +	.ep_index = 4,
    +	.bufsize = RUN_MAX_TXSZ,
    +	.flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,},
    +	.callback = run_bulk_tx_callback4,
    +	.timeout = 5000,	/* ms */
    +    },
    +    [RUN_BULK_TX_PRIO] = {
    +	.type = UE_BULK,
    +	.endpoint = UE_ADDR_ANY,
    +	.direction = UE_DIR_OUT,
    +	.ep_index = 5,
    +	.bufsize = RUN_MAX_TXSZ,
    +	.flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,},
    +	.callback = run_bulk_tx_callback5,
    +	.timeout = 5000,	/* ms */
    +    },
    +    [RUN_BULK_RX] = {
    +	.type = UE_BULK,
    +	.endpoint = UE_ADDR_ANY,
    +	.direction = UE_DIR_IN,
    +	.bufsize = RUN_MAX_RXSZ,
    +	.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
    +	.callback = run_bulk_rx_callback,
    +    }
    +};
    +
    +int
    +run_match(device_t self)
    +{
    +	struct usb_attach_arg *uaa = device_get_ivars(self);
    +
    +	if (uaa->usb_mode != USB_MODE_HOST)
    +		return (ENXIO);
    +	if (uaa->info.bConfigIndex != 0)
    +		return (ENXIO);
    +	if (uaa->info.bIfaceIndex != RT2860_IFACE_INDEX)
    +		return (ENXIO);
    +
    +	return (usbd_lookup_id_by_uaa(run_devs, sizeof(run_devs), uaa));
    +}
    +
    +static int
    +run_attach(device_t self)
    +{
    +	struct run_softc *sc = device_get_softc(self);
    +	struct usb_attach_arg *uaa = device_get_ivars(self);
    +	struct ieee80211com *ic;
    +	struct ifnet *ifp;
    +	int i, ntries, error;
    +	uint8_t iface_index, bands;
    +
    +	device_set_usb_desc(self);
    +	sc->sc_udev = uaa->device;
    +	sc->sc_dev = self;
    +
    +	mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
    +	    MTX_NETWORK_LOCK, MTX_DEF);
    +
    +	iface_index = RT2860_IFACE_INDEX;
    +	/* Rx transfer has own lock */
    +	error = usbd_transfer_setup(uaa->device, &iface_index,
    +	    sc->sc_xfer, run_config, RUN_N_XFER, sc, &sc->sc_mtx);
    +	if (error) {
    +		device_printf(self, "could not allocate USB Tx transfers, "
    +		    "err=%s\n", usbd_errstr(error));
    +		goto detach;
    +	}
    +
    +	RUN_LOCK(sc);
    +
    +	/* wait for the chip to settle */
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		if (run_read(sc, RT2860_ASIC_VER_ID, &sc->mac_rev) != 0){
    +			RUN_UNLOCK(sc);
    +			goto detach;
    +		}
    +		if (sc->mac_rev != 0 && sc->mac_rev != 0xffffffff)
    +			break;
    +		run_delay(sc, 10);
    +	}
    +	if (ntries == 100) {
    +		printf("%s: timeout waiting for NIC to initialize\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		RUN_UNLOCK(sc);
    +		goto detach;
    +	}
    +
    +	/* retrieve RF rev. no and various other things from EEPROM */
    +	run_read_eeprom(sc);
    +
    +	printf("%s: MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), "
    +	    "address %s\n", device_get_nameunit(sc->sc_dev), sc->mac_rev >> 16,
    +	    sc->mac_rev & 0xffff, run_get_rf(sc->rf_rev), sc->ntxchains,
    +	    sc->nrxchains, ether_sprintf(sc->sc_bssid));
    +
    +	if ((error = run_load_microcode(sc)) != 0) {
    +		printf("%s: could not load 8051 microcode\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		RUN_UNLOCK(sc);
    +		goto detach;
    +	}
    +
    +	RUN_UNLOCK(sc);
    +
    +	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
    +	if(ifp == NULL){
    +		printf("%s: can not if_alloc()\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		goto detach;
    +	}
    +	ic = ifp->if_l2com;
    +
    +	ifp->if_softc = sc;
    +	if_initname(ifp, "run", device_get_unit(sc->sc_dev));
    +	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    +	ifp->if_init = run_init;
    +	ifp->if_ioctl = run_ioctl;
    +	ifp->if_start = run_start;
    +	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
    +	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
    +	IFQ_SET_READY(&ifp->if_snd);
    +
    +	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 */
    +#if 0
    +	ic->ic_state = IEEE80211_S_INIT;
    +#endif
    +	/* set device capabilities */
    +	ic->ic_caps =
    +	    IEEE80211_C_STA |		/* station mode supported */
    +	    IEEE80211_C_MONITOR |	/* monitor mode supported */
    +	    IEEE80211_C_IBSS |
    +	    IEEE80211_C_HOSTAP |
    +	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
    +	    IEEE80211_C_SHSLOT |	/* short slot time supported */
    +	    IEEE80211_C_WME |		/* WME */
    +	    IEEE80211_C_WPA;		/* WPA1|WPA2(RSN) */
    +
    +	ic->ic_cryptocaps =
    +	    IEEE80211_CRYPTO_WEP |
    +	    IEEE80211_CRYPTO_AES_CCM |
    +	    IEEE80211_CRYPTO_TKIPMIC |
    +	    IEEE80211_CRYPTO_TKIP;
    +
    +	ic->ic_flags |= IEEE80211_F_DATAPAD;
    +	ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
    +
    +	bands = 0;
    +	setbit(&bands, IEEE80211_MODE_11B);
    +	setbit(&bands, IEEE80211_MODE_11G);
    +	ieee80211_init_channels(ic, NULL, &bands);
    +
    +	/*
    +	 * Do this by own because h/w supports
    +	 * more channels than ieee80211_init_channels()
    +	 */
    +	if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850) {
    +		/* set supported .11a rates */
    +		for (i = 14; i < nitems(rt2860_rf2850); i++) {
    +			uint8_t chan = rt2860_rf2850[i].chan;
    +			ic->ic_channels[ic->ic_nchans].ic_freq =
    +			    ieee80211_ieee2mhz(chan, IEEE80211_CHAN_A);
    +			ic->ic_channels[ic->ic_nchans].ic_ieee = chan;
    +			ic->ic_channels[ic->ic_nchans].ic_flags = IEEE80211_CHAN_A;
    +			ic->ic_channels[ic->ic_nchans].ic_extieee = 0;
    +			ic->ic_nchans++;
    +		}
    +	}
    +
    +	ieee80211_ifattach(ic, sc->sc_bssid);
    +
    +	ic->ic_scan_start = run_scan_start;
    +	ic->ic_scan_end = run_scan_end;
    +	ic->ic_set_channel = run_set_channel;
    +	ic->ic_node_alloc = run_node_alloc;
    +	ic->ic_newassoc = run_newassoc;
    +	//ic->ic_updateslot = run_updateslot;
    +	ic->ic_wme.wme_update = run_wme_update;
    +	ic->ic_raw_xmit = run_raw_xmit;
    +	ic->ic_update_promisc = run_update_promisc;
    +
    +	ic->ic_vap_create = run_vap_create;
    +	ic->ic_vap_delete = run_vap_delete;
    +
    +	ieee80211_radiotap_attach(ic,
    +	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
    +		RUN_TX_RADIOTAP_PRESENT,
    +	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
    +		RUN_RX_RADIOTAP_PRESENT);
    +
    +	if (bootverbose)
    +		ieee80211_announce(ic);
    +
    +	return 0;
    +
    +detach:
    +	run_detach(self);
    +	return(ENXIO);
    +}
    +
    +static int
    +run_detach(device_t self)
    +{
    +	struct run_softc *sc = device_get_softc(self);
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic;
    +	int i;
    +
    +	/* stop all USB transfers */
    +	usbd_transfer_unsetup(sc->sc_xfer, RUN_N_XFER);
    +
    +	RUN_LOCK(sc);
    +	/* free TX list, if any */
    +	for (i = 0; i != RUN_EP_QUEUES; i++)
    +		run_unsetup_tx_list(sc, &sc->sc_epq[i]);
    +	RUN_UNLOCK(sc);
    +
    +	if (ifp) {
    +		ic = ifp->if_l2com;
    +		ieee80211_ifdetach(ic);
    +		if_free(ifp);
    +	}
    +
    +	mtx_destroy(&sc->sc_mtx);
    +
    +	return (0);
    +}
    +
    +static struct ieee80211vap *
    +run_vap_create(struct ieee80211com *ic,
    +    const char name[IFNAMSIZ], int unit, int opmode, int flags,
    +    const uint8_t bssid[IEEE80211_ADDR_LEN],
    +    const uint8_t mac[IEEE80211_ADDR_LEN])
    +{
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +	struct run_vap *rvp;
    +	struct ieee80211vap *vap;
    +
    +	if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
    +		return NULL;
    +	sc->sc_rvp = rvp = (struct run_vap *) malloc(sizeof(struct run_vap),
    +	    M_80211_VAP, M_NOWAIT | M_ZERO);
    +	if (rvp == NULL)
    +		return NULL;
    +	vap = &rvp->vap;
    +	/* enable s/w bmiss handling for sta mode */
    +	ieee80211_vap_setup(ic, vap, name, unit, opmode,
    +	    flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
    +
    +	vap->iv_key_update_begin = run_key_update_begin;
    +	vap->iv_key_update_end = run_key_update_end;
    +	vap->iv_key_delete = run_key_delete;
    +	vap->iv_key_set = run_key_set;
    +	vap->iv_update_beacon = run_update_beacon;
    +
    +	/* override state transition machine */
    +	rvp->newstate = vap->iv_newstate;
    +	vap->iv_newstate = run_newstate;
    +
    +	TASK_INIT(&rvp->amrr_task, 0, run_amrr_cb, rvp);
    +	TASK_INIT(&sc->wme_task, 0, run_wme_update_cb, ic);
    +	TASK_INIT(&sc->usb_timeout_task, 0, run_usb_timeout_cb, sc);
    +	callout_init((struct callout *)&rvp->amrr_ch, 1);
    +	ieee80211_amrr_init(&rvp->amrr, vap,
    +	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
    +	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
    +	    1000 /* 1 sec */);
    +
    +	/* complete setup */
    +	ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status);
    +	ic->ic_opmode = opmode;
    +	return vap;
    +}
    +
    +static void
    +run_vap_delete(struct ieee80211vap *vap)
    +{
    +	struct run_vap *rvp = RUN_VAP(vap);
    +	struct ifnet *ifp;
    +	struct ieee80211com *ic;
    +	struct run_softc *sc;
    +
    +	if(vap == NULL)
    +		return;
    +
    +	ic = vap->iv_ic;
    +	ifp = ic->ic_ifp;
    +
    +	sc = ifp->if_softc;
    +
    +	if (ifp && ifp->if_flags & IFF_UP){
    +		RUN_LOCK(sc);
    +		run_stop(sc);
    +		RUN_UNLOCK(sc);
    +	}
    +
    +	ieee80211_amrr_cleanup(&rvp->amrr);
    +	ieee80211_vap_detach(vap);
    +	free(rvp, M_80211_VAP);
    +	sc->sc_rvp = NULL;
    +}
    +
    +static void
    +run_setup_tx_list(struct run_softc *sc, struct run_endpoint_queue *pq)
    +{
    +	struct run_tx_data *data;
    +
    +	memset(pq, 0, sizeof(*pq));
    +
    +	STAILQ_INIT(&pq->tx_qh);
    +	STAILQ_INIT(&pq->tx_fh);
    +
    +	for (data = &pq->tx_data[0];
    +	    data < &pq->tx_data[RUN_TX_RING_COUNT]; data++) {
    +		data->sc = sc;
    +		STAILQ_INSERT_TAIL(&pq->tx_fh, data, next);
    +	}
    +	pq->tx_nfree = RUN_TX_RING_COUNT;
    +}
    +
    +static void
    +run_unsetup_tx_list(struct run_softc *sc, struct run_endpoint_queue *pq)
    +{
    +	struct run_tx_data *data;
    +
    +	/* make sure any subsequent use of the queues will fail */
    +	pq->tx_nfree = 0;
    +	STAILQ_INIT(&pq->tx_fh);
    +	STAILQ_INIT(&pq->tx_qh);
    +
    +	/* free up all node references and mbufs */
    +	for (data = &pq->tx_data[0];
    +	    data < &pq->tx_data[RUN_TX_RING_COUNT]; data++){
    +		if (data->m != NULL) {
    +			m_freem(data->m);
    +			data->m = NULL;
    +		}
    +		if (data->ni != NULL) {
    +			ieee80211_free_node(data->ni);
    +			data->ni = NULL;
    +		}
    +	}
    +}
    +
    +int
    +run_load_microcode(struct run_softc *sc)
    +{
    +	usb_device_request_t req;
    +	const u_char *base;
    +	uint32_t tmp;
    +	int ntries, error;
    +	const uint64_t *temp;
    +	uint64_t bytes;
    +
    +	if((sc->fwp = firmware_get("runfw")) == NULL){
    +		printf("%s: failed loadfirmware of file %s (error %d)\n",
    +		    device_get_nameunit(sc->sc_dev), "runfw", ENOENT);
    +		return ENOENT;
    +	}
    +
    +	if (sc->fwp->datasize != 8192) {
    +		printf("%s: invalid firmware size (should be 8KB)\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		return EINVAL;
    +	}
    +
    +	/*
    +	 * RT3071/RT3072 use a different firmware
    +	 * run-rt2870 (8KB) contains both,
    +	 * first half (4KB) is for rt2870,
    +	 * last half is for rt3071.
    +	 */
    +	base = sc->fwp->data;
    +	if ((sc->mac_rev >> 16) != 0x2860 &&
    +	    (sc->mac_rev >> 16) != 0x2872 &&
    +	    (sc->mac_rev >> 16) != 0x3070 &&
    +	    (sc->mac_rev >> 16) != 0x3572){
    +		base += 4096;
    +		printf("%s: You are using firmware RT3071.\n",
    +		    device_get_nameunit(sc->sc_dev));
    +	} else
    +		printf("%s: You are using firmware RT2870.\n",
    +		    device_get_nameunit(sc->sc_dev));
    +
    +	/* cheap sanity check */
    +	temp = sc->fwp->data;
    +	bytes = *temp;
    +	if(bytes != be64toh(0xffffff0210280210))
    +		return EINVAL;
    +
    +	run_read(sc, RT2860_ASIC_VER_ID, &tmp);
    +	/* write microcode image */
    +	run_write_region_1(sc, RT2870_FW_BASE, base, 4096);
    +	run_write(sc, RT2860_H2M_MAILBOX_CID, 0xffffffff);
    +	run_write(sc, RT2860_H2M_MAILBOX_STATUS, 0xffffffff);
    +
    +	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
    +	req.bRequest = RT2870_RESET;
    +	USETW(req.wValue, 8);
    +	USETW(req.wIndex, 0);
    +	USETW(req.wLength, 0);
    +	if ((error = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL)) != 0)
    +		return error;
    +
    +	run_delay(sc, 10);
    +
    +	run_write(sc, RT2860_H2M_MAILBOX, 0);
    +	if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_BOOT, 0)) != 0)
    +		return error;
    +
    +	/* wait until microcontroller is ready */
    +	for (ntries = 0; ntries < 1000; ntries++) {
    +		if ((error = run_read(sc, RT2860_SYS_CTRL, &tmp)) != 0)
    +			return error;
    +		if (tmp & RT2860_MCU_READY)
    +			break;
    +		run_delay(sc, 10);
    +	}
    +	if (ntries == 1000) {
    +		printf("%s: timeout waiting for MCU to initialize\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		return ETIMEDOUT;
    +	}
    +	DPRINTF("microcode successfully loaded after %d tries\n", ntries);
    +
    +	return 0;
    +}
    +
    +int
    +run_reset(struct run_softc *sc)
    +{
    +	usb_device_request_t req;
    +
    +	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
    +	req.bRequest = RT2870_RESET;
    +	USETW(req.wValue, 1);
    +	USETW(req.wIndex, 0);
    +	USETW(req.wLength, 0);
    +	return usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL);
    +}
    +
    +static usb_error_t
    +run_do_request(struct run_softc *sc,
    +    struct usb_device_request *req, void *data)
    +{
    +	usb_error_t err;
    +	int ntries = 10;
    +
    +	RUN_LOCK_ASSERT(sc, MA_OWNED);
    +
    +	while (ntries--) {
    +		err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
    +		    req, data, 0, NULL, 250 /* ms */);
    +		if (err == 0)
    +			break;
    +		DPRINTFN(1, "Control request failed, %s (retrying)\n",
    +		    usbd_errstr(err));
    +		run_delay(sc, 10);
    +	}
    +	return (err);
    +}
    +
    +static int
    +run_read(struct run_softc *sc, uint16_t reg, uint32_t *val)
    +{
    +	uint32_t tmp;
    +	int error;
    +
    +	error = run_read_region_1(sc, reg, (uint8_t *)&tmp, sizeof tmp);
    +	if (error == 0)
    +		*val = le32toh(tmp);
    +	else
    +		*val = 0xffffffff;
    +	return error;
    +}
    +
    +static int
    +run_read_region_1(struct run_softc *sc, uint16_t reg, uint8_t *buf, int len)
    +{
    +	usb_device_request_t req;
    +
    +	req.bmRequestType = UT_READ_VENDOR_DEVICE;
    +	req.bRequest = RT2870_READ_REGION_1;
    +	USETW(req.wValue, 0);
    +	USETW(req.wIndex, reg);
    +	USETW(req.wLength, len);
    +
    +	return run_do_request(sc, &req, buf);
    +}
    +
    +static int
    +run_write_2(struct run_softc *sc, uint16_t reg, uint16_t val)
    +{
    +	usb_device_request_t req;
    +
    +	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
    +	req.bRequest = RT2870_WRITE_2;
    +	USETW(req.wValue, val);
    +	USETW(req.wIndex, reg);
    +	USETW(req.wLength, 0);
    +
    +	return run_do_request(sc, &req, NULL);
    +}
    +
    +static int
    +run_write(struct run_softc *sc, uint16_t reg, uint32_t val)
    +{
    +	int error;
    +
    +	if ((error = run_write_2(sc, reg, val & 0xffff)) == 0)
    +		error = run_write_2(sc, reg + 2, val >> 16);
    +	return error;
    +}
    +
    +static int
    +run_write_region_1(struct run_softc *sc, uint16_t reg, const uint8_t *buf,
    +    int len)
    +{
    +#if 1
    +	int i, error = 0;
    +	/*
    +	 * NB: the WRITE_REGION_1 command is not stable on RT2860.
    +	 * We thus issue multiple WRITE_2 commands instead.
    +	 */
    +	KASSERT((len & 1) == 0, ("run_write_region_1: Data too long.\n"));
    +	for (i = 0; i < len && error == 0; i += 2)
    +		error = run_write_2(sc, reg + i, buf[i] | buf[i + 1] << 8);
    +	return error;
    +#else
    +	usb_device_request_t req;
    +
    +	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
    +	req.bRequest = RT2870_WRITE_REGION_1;
    +	USETW(req.wValue, 0);
    +	USETW(req.wIndex, reg);
    +	USETW(req.wLength, len);
    +	return run_do_request(sc, &req, buf);
    +#endif
    +}
    +
    +static int
    +run_set_region_4(struct run_softc *sc, uint16_t reg, uint32_t val, int len)
    +{
    +	int i, error = 0;
    +
    +	KASSERT((len & 3) == 0, ("run_set_region_4: Invalid data length.\n"));
    +	for (i = 0; i < len && error == 0; i += 4)
    +		error = run_write(sc, reg + i, val);
    +	return error;
    +}
    +
    +/* Read 16-bit from eFUSE ROM (RT3070 only.) */
    +static int
    +run_efuse_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val)
    +{
    +	uint32_t tmp;
    +	uint16_t reg;
    +	int error, ntries;
    +
    +	if ((error = run_read(sc, RT3070_EFUSE_CTRL, &tmp)) != 0)
    +		return error;
    +
    +	addr *= 2;
    +	/*-
    +	 * Read one 16-byte block into registers EFUSE_DATA[0-3]:
    +	 * DATA0: F E D C
    +	 * DATA1: B A 9 8
    +	 * DATA2: 7 6 5 4
    +	 * DATA3: 3 2 1 0
    +	 */
    +	tmp &= ~(RT3070_EFSROM_MODE_MASK | RT3070_EFSROM_AIN_MASK);
    +	tmp |= (addr & ~0xf) << RT3070_EFSROM_AIN_SHIFT | RT3070_EFSROM_KICK;
    +	run_write(sc, RT3070_EFUSE_CTRL, tmp);
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		if ((error = run_read(sc, RT3070_EFUSE_CTRL, &tmp)) != 0)
    +			return error;
    +		if (!(tmp & RT3070_EFSROM_KICK))
    +			break;
    +		run_delay(sc, 2);
    +	}
    +	if (ntries == 100)
    +		return ETIMEDOUT;
    +
    +	if ((tmp & RT3070_EFUSE_AOUT_MASK) == RT3070_EFUSE_AOUT_MASK) {
    +		*val = 0xffff;	/* address not found */
    +		return 0;
    +	}
    +	/* determine to which 32-bit register our 16-bit word belongs */
    +	reg = RT3070_EFUSE_DATA3 - (addr & 0xc);
    +	if ((error = run_read(sc, reg, &tmp)) != 0)
    +		return error;
    +
    +	*val = (addr & 2) ? tmp >> 16 : tmp & 0xffff;
    +	return 0;
    +}
    +
    +static int
    +run_eeprom_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val)
    +{
    +	usb_device_request_t req;
    +	uint16_t tmp;
    +	int error;
    +
    +	addr *= 2;
    +	req.bmRequestType = UT_READ_VENDOR_DEVICE;
    +	req.bRequest = RT2870_EEPROM_READ;
    +	USETW(req.wValue, 0);
    +	USETW(req.wIndex, addr);
    +	USETW(req.wLength, sizeof tmp);
    +
    +	error = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, &tmp);
    +	if (error == 0)
    +		*val = le16toh(tmp);
    +	else
    +		*val = 0xffff;
    +	return error;
    +}
    +
    +static __inline int
    +run_srom_read(struct run_softc *sc, uint16_t addr, uint16_t *val)
    +{
    +	/* either eFUSE ROM or EEPROM */
    +	return sc->sc_srom_read(sc, addr, val);
    +}
    +
    +static int
    +run_rt2870_rf_write(struct run_softc *sc, uint8_t reg, uint32_t val)
    +{
    +	uint32_t tmp;
    +	int error, ntries;
    +
    +	for (ntries = 0; ntries < 10; ntries++) {
    +		if ((error = run_read(sc, RT2860_RF_CSR_CFG0, &tmp)) != 0)
    +			return error;
    +		if (!(tmp & RT2860_RF_REG_CTRL))
    +			break;
    +	}
    +	if (ntries == 10)
    +		return ETIMEDOUT;
    +
    +	/* RF registers are 24-bit on the RT2860 */
    +	tmp = RT2860_RF_REG_CTRL | 24 << RT2860_RF_REG_WIDTH_SHIFT |
    +	    (val & 0x3fffff) << 2 | (reg & 3);
    +	return run_write(sc, RT2860_RF_CSR_CFG0, tmp);
    +}
    +
    +static int
    +run_rt3070_rf_read(struct run_softc *sc, uint8_t reg, uint8_t *val)
    +{
    +	uint32_t tmp;
    +	int error, ntries;
    +
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		if ((error = run_read(sc, RT3070_RF_CSR_CFG, &tmp)) != 0)
    +			return error;
    +		if (!(tmp & RT3070_RF_KICK))
    +			break;
    +	}
    +	if (ntries == 100)
    +		return ETIMEDOUT;
    +
    +	tmp = RT3070_RF_KICK | reg << 8;
    +	if ((error = run_write(sc, RT3070_RF_CSR_CFG, tmp)) != 0)
    +		return error;
    +
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		if ((error = run_read(sc, RT3070_RF_CSR_CFG, &tmp)) != 0)
    +			return error;
    +		if (!(tmp & RT3070_RF_KICK))
    +			break;
    +	}
    +	if (ntries == 100)
    +		return ETIMEDOUT;
    +
    +	*val = tmp & 0xff;
    +	return 0;
    +}
    +
    +static int
    +run_rt3070_rf_write(struct run_softc *sc, uint8_t reg, uint8_t val)
    +{
    +	uint32_t tmp;
    +	int error, ntries;
    +
    +	for (ntries = 0; ntries < 10; ntries++) {
    +		if ((error = run_read(sc, RT3070_RF_CSR_CFG, &tmp)) != 0)
    +			return error;
    +		if (!(tmp & RT3070_RF_KICK))
    +			break;
    +	}
    +	if (ntries == 10)
    +		return ETIMEDOUT;
    +
    +	tmp = RT3070_RF_WRITE | RT3070_RF_KICK | reg << 8 | val;
    +	return run_write(sc, RT3070_RF_CSR_CFG, tmp);
    +}
    +
    +static int
    +run_bbp_read(struct run_softc *sc, uint8_t reg, uint8_t *val)
    +{
    +	uint32_t tmp;
    +	int ntries, error;
    +
    +	for (ntries = 0; ntries < 10; ntries++) {
    +		if ((error = run_read(sc, RT2860_BBP_CSR_CFG, &tmp)) != 0)
    +			return error;
    +		if (!(tmp & RT2860_BBP_CSR_KICK))
    +			break;
    +	}
    +	if (ntries == 10)
    +		return ETIMEDOUT;
    +
    +	tmp = RT2860_BBP_CSR_READ | RT2860_BBP_CSR_KICK | reg << 8;
    +	if ((error = run_write(sc, RT2860_BBP_CSR_CFG, tmp)) != 0)
    +		return error;
    +
    +	for (ntries = 0; ntries < 10; ntries++) {
    +		if ((error = run_read(sc, RT2860_BBP_CSR_CFG, &tmp)) != 0)
    +			return error;
    +		if (!(tmp & RT2860_BBP_CSR_KICK))
    +			break;
    +	}
    +	if (ntries == 10)
    +		return ETIMEDOUT;
    +
    +	*val = tmp & 0xff;
    +	return 0;
    +}
    +
    +static int
    +run_bbp_write(struct run_softc *sc, uint8_t reg, uint8_t val)
    +{
    +	uint32_t tmp;
    +	int ntries, error;
    +
    +	for (ntries = 0; ntries < 10; ntries++) {
    +		if ((error = run_read(sc, RT2860_BBP_CSR_CFG, &tmp)) != 0)
    +			return error;
    +		if (!(tmp & RT2860_BBP_CSR_KICK))
    +			break;
    +	}
    +	if (ntries == 10)
    +		return ETIMEDOUT;
    +
    +	tmp = RT2860_BBP_CSR_KICK | reg << 8 | val;
    +	return run_write(sc, RT2860_BBP_CSR_CFG, tmp);
    +}
    +
    +/*
    + * Send a command to the 8051 microcontroller unit.
    + */
    +static int
    +run_mcu_cmd(struct run_softc *sc, uint8_t cmd, uint16_t arg)
    +{
    +	uint32_t tmp;
    +	int error, ntries;
    +
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		if ((error = run_read(sc, RT2860_H2M_MAILBOX, &tmp)) != 0)
    +			return error;
    +		if (!(tmp & RT2860_H2M_BUSY))
    +			break;
    +	}
    +	if (ntries == 100)
    +		return ETIMEDOUT;
    +
    +	tmp = RT2860_H2M_BUSY | RT2860_TOKEN_NO_INTR << 16 | arg;
    +	if ((error = run_write(sc, RT2860_H2M_MAILBOX, tmp)) == 0)
    +		error = run_write(sc, RT2860_HOST_CMD, cmd);
    +	return error;
    +}
    +
    +/*
    + * Add `delta' (signed) to each 4-bit sub-word of a 32-bit word.
    + * Used to adjust per-rate Tx power registers.
    + */
    +static __inline uint32_t
    +b4inc(uint32_t b32, int8_t delta)
    +{
    +	int8_t i, b4;
    +
    +	for (i = 0; i < 8; i++) {
    +		b4 = b32 & 0xf;
    +		b4 += delta;
    +		if (b4 < 0)
    +			b4 = 0;
    +		else if (b4 > 0xf)
    +			b4 = 0xf;
    +		b32 = b32 >> 4 | b4 << 28;
    +	}
    +	return b32;
    +}
    +
    +static const char *
    +run_get_rf(int rev)
    +{
    +	switch (rev) {
    +	case RT2860_RF_2820:	return "RT2820";
    +	case RT2860_RF_2850:	return "RT2850";
    +	case RT2860_RF_2720:	return "RT2720";
    +	case RT2860_RF_2750:	return "RT2750";
    +	case RT3070_RF_3020:	return "RT3020";
    +	case RT3070_RF_2020:	return "RT2020";
    +	case RT3070_RF_3021:	return "RT3021";
    +	case RT3070_RF_3022:	return "RT3022";
    +	case RT3070_RF_3052:	return "RT3052";
    +	}
    +	return "unknown";
    +}
    +
    +int
    +run_read_eeprom(struct run_softc *sc)
    +{
    +	int8_t delta_2ghz, delta_5ghz;
    +	uint32_t tmp;
    +	uint16_t val;
    +	int ridx, ant, i;
    +
    +	/* check whether the ROM is eFUSE ROM or EEPROM */
    +	sc->sc_srom_read = run_eeprom_read_2;
    +	if ((sc->mac_rev & 0xfff00000) >= 0x30700000) {
    +		run_read(sc, RT3070_EFUSE_CTRL, &tmp);
    +		DPRINTF("EFUSE_CTRL=0x%08x\n", tmp);
    +		if (tmp & RT3070_SEL_EFUSE)
    +			sc->sc_srom_read = run_efuse_read_2;
    +	}
    +
    +	/* read ROM version */
    +	run_srom_read(sc, RT2860_EEPROM_VERSION, &val);
    +	DPRINTF("EEPROM rev=%d, FAE=%d\n", val & 0xff, val >> 8);
    +
    +	/* read MAC address */
    +	run_srom_read(sc, RT2860_EEPROM_MAC01, &val);
    +	sc->sc_bssid[0] = val & 0xff;
    +	sc->sc_bssid[1] = val >> 8;
    +	run_srom_read(sc, RT2860_EEPROM_MAC23, &val);
    +	sc->sc_bssid[2] = val & 0xff;
    +	sc->sc_bssid[3] = val >> 8;
    +	run_srom_read(sc, RT2860_EEPROM_MAC45, &val);
    +	sc->sc_bssid[4] = val & 0xff;
    +	sc->sc_bssid[5] = val >> 8;
    +
    +	/* read default BBP settings */
    +	for (i = 0; i < 8; i++) {
    +		run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val);
    +		sc->bbp[i].val = val & 0xff;
    +		sc->bbp[i].reg = val >> 8;
    +		DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val);
    +	}
    +
    +	/* read RF frequency offset from EEPROM */
    +	run_srom_read(sc, RT2860_EEPROM_FREQ_LEDS, &val);
    +	sc->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0;
    +	DPRINTF("EEPROM freq offset %d\n", sc->freq & 0xff);
    +
    +	if ((sc->leds = val >> 8) != 0xff) {
    +		/* read LEDs operating mode */
    +		run_srom_read(sc, RT2860_EEPROM_LED1, &sc->led[0]);
    +		run_srom_read(sc, RT2860_EEPROM_LED2, &sc->led[1]);
    +		run_srom_read(sc, RT2860_EEPROM_LED3, &sc->led[2]);
    +	} else {
    +		/* broken EEPROM, use default settings */
    +		sc->leds = 0x01;
    +		sc->led[0] = 0x5555;
    +		sc->led[1] = 0x2221;
    +		sc->led[2] = 0x5627;	/* differs from RT2860 */
    +	}
    +	DPRINTF("EEPROM LED mode=0x%02x, LEDs=0x%04x/0x%04x/0x%04x\n",
    +	    sc->leds, sc->led[0], sc->led[1], sc->led[2]);
    +
    +	/* read RF information */
    +	run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
    +	if (val == 0xffff) {
    +		DPRINTF("invalid EEPROM antenna info, using default\n");
    +		if ((sc->mac_rev >> 16) >= 0x3070) {
    +			/* default to RF3020 1T1R */
    +			sc->rf_rev = RT3070_RF_3020;
    +			sc->ntxchains = 1;
    +			sc->nrxchains = 1;
    +		} else {
    +			/* default to RF2820 1T2R */
    +			sc->rf_rev = RT2860_RF_2820;
    +			sc->ntxchains = 1;
    +			sc->nrxchains = 2;
    +		}
    +	} else {
    +		sc->rf_rev = (val >> 8) & 0xf;
    +		sc->ntxchains = (val >> 4) & 0xf;
    +		sc->nrxchains = val & 0xf;
    +	}
    +	DPRINTF("EEPROM RF rev=0x%02x chains=%dT%dR\n",
    +	    sc->rf_rev, sc->ntxchains, sc->nrxchains);
    +
    +	/* check if RF supports automatic Tx access gain control */
    +	run_srom_read(sc, RT2860_EEPROM_CONFIG, &val);
    +	DPRINTF("EEPROM CFG 0x%04x\n", val);
    +	if ((val & 0xff) != 0xff) {
    +		sc->ext_5ghz_lna = (val >> 3) & 1;
    +		sc->ext_2ghz_lna = (val >> 2) & 1;
    +		sc->calib_2ghz = sc->calib_5ghz = (val >> 1) & 1;
    +	}
    +
    +	/* read power settings for 2GHz channels */
    +	for (i = 0; i < 14; i += 2) {
    +		run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2, &val);
    +		sc->txpow1[i + 0] = (int8_t)(val & 0xff);
    +		sc->txpow1[i + 1] = (int8_t)(val >> 8);
    +
    +		run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val);
    +		sc->txpow2[i + 0] = (int8_t)(val & 0xff);
    +		sc->txpow2[i + 1] = (int8_t)(val >> 8);
    +	}
    +	/* fix broken Tx power entries */
    +	for (i = 0; i < 14; i++) {
    +		if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31)
    +			sc->txpow1[i] = 5;
    +		if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31)
    +			sc->txpow2[i] = 5;
    +		DPRINTF("chan %d: power1=%d, power2=%d\n",
    +		    rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]);
    +	}
    +	/* read power settings for 5GHz channels */
    +	for (i = 0; i < 36; i += 2) {
    +		run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2, &val);
    +		sc->txpow1[i + 14] = (int8_t)(val & 0xff);
    +		sc->txpow1[i + 15] = (int8_t)(val >> 8);
    +
    +		run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2, &val);
    +		sc->txpow2[i + 14] = (int8_t)(val & 0xff);
    +		sc->txpow2[i + 15] = (int8_t)(val >> 8);
    +	}
    +	/* fix broken Tx power entries */
    +	for (i = 0; i < 36; i++) {
    +		if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15)
    +			sc->txpow1[14 + i] = 5;
    +		if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15)
    +			sc->txpow2[14 + i] = 5;
    +		DPRINTF("chan %d: power1=%d, power2=%d\n",
    +		    rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i],
    +		    sc->txpow2[14 + i]);
    +	}
    +
    +	/* read Tx power compensation for each Tx rate */
    +	run_srom_read(sc, RT2860_EEPROM_DELTAPWR, &val);
    +	delta_2ghz = delta_5ghz = 0;
    +	if ((val & 0xff) != 0xff && (val & 0x80)) {
    +		delta_2ghz = val & 0xf;
    +		if (!(val & 0x40))	/* negative number */
    +			delta_2ghz = -delta_2ghz;
    +	}
    +	val >>= 8;
    +	if ((val & 0xff) != 0xff && (val & 0x80)) {
    +		delta_5ghz = val & 0xf;
    +		if (!(val & 0x40))	/* negative number */
    +			delta_5ghz = -delta_5ghz;
    +	}
    +	DPRINTF("power compensation=%d (2GHz), %d (5GHz)\n",
    +	    delta_2ghz, delta_5ghz);
    +
    +	for (ridx = 0; ridx < 5; ridx++) {
    +		uint32_t reg;
    +
    +		run_srom_read(sc, RT2860_EEPROM_RPWR + ridx, &val);
    +		reg = (uint32_t)val << 16;
    +		run_srom_read(sc, RT2860_EEPROM_RPWR + ridx + 1, &val);
    +		reg |= val;
    +
    +		sc->txpow20mhz[ridx] = reg;
    +		sc->txpow40mhz_2ghz[ridx] = b4inc(reg, delta_2ghz);
    +		sc->txpow40mhz_5ghz[ridx] = b4inc(reg, delta_5ghz);
    +
    +		DPRINTF("ridx %d: power 20MHz=0x%08x, 40MHz/2GHz=0x%08x, "
    +		    "40MHz/5GHz=0x%08x\n", ridx, sc->txpow20mhz[ridx],
    +		    sc->txpow40mhz_2ghz[ridx], sc->txpow40mhz_5ghz[ridx]);
    +	}
    +
    +	/* read RSSI offsets and LNA gains from EEPROM */
    +	run_srom_read(sc, RT2860_EEPROM_RSSI1_2GHZ, &val);
    +	sc->rssi_2ghz[0] = val & 0xff;	/* Ant A */
    +	sc->rssi_2ghz[1] = val >> 8;	/* Ant B */
    +	run_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ, &val);
    +	sc->rssi_2ghz[2] = val & 0xff;	/* Ant C */
    +	sc->lna[2] = val >> 8;		/* channel group 2 */
    +
    +	run_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ, &val);
    +	sc->rssi_5ghz[0] = val & 0xff;	/* Ant A */
    +	sc->rssi_5ghz[1] = val >> 8;	/* Ant B */
    +	run_srom_read(sc, RT2860_EEPROM_RSSI2_5GHZ, &val);
    +	sc->rssi_5ghz[2] = val & 0xff;	/* Ant C */
    +	sc->lna[3] = val >> 8;		/* channel group 3 */
    +
    +	run_srom_read(sc, RT2860_EEPROM_LNA, &val);
    +	sc->lna[0] = val & 0xff;	/* channel group 0 */
    +	sc->lna[1] = val >> 8;		/* channel group 1 */
    +
    +	/* fix broken 5GHz LNA entries */
    +	if (sc->lna[2] == 0 || sc->lna[2] == 0xff) {
    +		DPRINTF("invalid LNA for channel group %d\n", 2);
    +		sc->lna[2] = sc->lna[1];
    +	}
    +	if (sc->lna[3] == 0 || sc->lna[3] == 0xff) {
    +		DPRINTF("invalid LNA for channel group %d\n", 3);
    +		sc->lna[3] = sc->lna[1];
    +	}
    +
    +	/* fix broken RSSI offset entries */
    +	for (ant = 0; ant < 3; ant++) {
    +		if (sc->rssi_2ghz[ant] < -10 || sc->rssi_2ghz[ant] > 10) {
    +			DPRINTF("invalid RSSI%d offset: %d (2GHz)\n",
    +			    ant + 1, sc->rssi_2ghz[ant]);
    +			sc->rssi_2ghz[ant] = 0;
    +		}
    +		if (sc->rssi_5ghz[ant] < -10 || sc->rssi_5ghz[ant] > 10) {
    +			DPRINTF("invalid RSSI%d offset: %d (5GHz)\n",
    +			    ant + 1, sc->rssi_5ghz[ant]);
    +			sc->rssi_5ghz[ant] = 0;
    +		}
    +	}
    +	return 0;
    +}
    +
    +struct ieee80211_node *
    +run_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
    +{
    +	return malloc(sizeof (struct run_node), M_DEVBUF, M_NOWAIT | M_ZERO);
    +}
    +
    +static int
    +run_media_change(struct ifnet *ifp)
    +{
    +	const struct ieee80211_txparam *tp;
    +	struct run_softc *sc = ifp->if_softc;
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	struct ieee80211vap *vap = &sc->sc_rvp->vap;
    +	uint8_t rate, ridx;
    +	int error;
    +
    +	RUN_LOCK(sc);
    +
    +	error = ieee80211_media_change(ifp);
    +	if (error != ENETRESET)
    +		RUN_UNLOCK(sc);
    +		return error;
    +
    +	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
    +	if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
    +		rate = ic->ic_sup_rates[ic->ic_curmode].
    +		    rs_rates[tp->ucastrate] & IEEE80211_RATE_VAL;
    +		for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
    +			if (rt2860_rates[ridx].rate == rate)
    +				break;
    +		sc->fixed_ridx = ridx;
    +	}
    +
    +	if ((ifp->if_flags & IFF_UP) &&
    +	    (ifp->if_drv_flags &  IFF_DRV_RUNNING)){
    +		run_init_locked(sc);
    +	}
    +
    +	RUN_UNLOCK(sc);
    +
    +	return 0;
    +}
    +
    +static int
    +run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
    +{
    +	const struct ieee80211_txparam *tp;
    +	struct ieee80211com *ic = vap->iv_ic;
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +	struct run_vap *rvp = RUN_VAP(vap);
    +	enum ieee80211_state ostate;
    +	struct ieee80211_node *ni;
    +	uint32_t tmp;
    +	uint8_t wcid;
    +
    +	ostate = vap->iv_state;
    +	DPRINTF("%s -> %s\n",
    +		ieee80211_state_name[ostate],
    +		ieee80211_state_name[nstate]);
    +
    +	IEEE80211_UNLOCK(ic);
    +	RUN_LOCK(sc);
    +
    +	sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
    +	usb_callout_stop(&rvp->amrr_ch);
    +
    +	if (ostate == IEEE80211_S_RUN) {
    +		/* turn link LED off */
    +		run_set_leds(sc, RT2860_LED_RADIO);
    +	}
    +
    +	switch (nstate) {
    +	case IEEE80211_S_INIT:
    +		if (ostate == IEEE80211_S_RUN) {
    +			/* abort TSF synchronization */
    +			run_read(sc, RT2860_BCN_TIME_CFG, &tmp);
    +			run_write(sc, RT2860_BCN_TIME_CFG,
    +			    tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN |
    +			    RT2860_TBTT_TIMER_EN));
    +		}
    +		break;
    +
    +	case IEEE80211_S_RUN:
    +		ni = vap->iv_bss;
    +
    +		if (vap->iv_opmode != IEEE80211_M_MONITOR) {
    +			run_updateslot(ic->ic_ifp);
    +			run_enable_mrr(sc);
    +			run_set_txpreamble(sc);
    +			run_set_basicrates(sc);
    +			IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
    +			run_set_bssid(sc, ni->ni_bssid);
    +		}
    +
    +		if (vap->iv_opmode == IEEE80211_M_STA) {
    +			/* add BSS entry to the WCID table */
    +			wcid = RUN_AID2WCID(ni->ni_associd);
    +			run_write_region_1(sc, RT2860_WCID_ENTRY(wcid),
    +			    ni->ni_macaddr, IEEE80211_ADDR_LEN);
    +		}
    +
    +		if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
    +		    vap->iv_opmode == IEEE80211_M_IBSS)
    +			run_update_beacon_locked(vap, 0);
    +
    +		if (vap->iv_opmode != IEEE80211_M_MONITOR) {
    +			run_enable_tsf_sync(sc);
    +		} /* else tsf */
    +
    +		/* enable automatic rate adaptation */
    +		tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
    +		if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
    +			run_amrr_start(sc, ni);
    +
    +		/* turn link LED on */
    +		run_set_leds(sc, RT2860_LED_RADIO |
    +		    (IEEE80211_IS_CHAN_2GHZ(vap->iv_bss->ni_chan) ?
    +		     RT2860_LED_LINK_2GHZ : RT2860_LED_LINK_5GHZ));
    +
    +		break;
    +	default:
    +		DPRINTFN(6, "undefined case\n");
    +		break;
    +	}
    +
    +	RUN_UNLOCK(sc);
    +	IEEE80211_LOCK(ic);
    +
    +	return(rvp->newstate(vap, nstate, arg));
    +}
    +
    +/* another taskqueue, so usbd_do_request() can go sleep */
    +static int
    +run_wme_update(struct ieee80211com *ic)
    +{
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +
    +	ieee80211_runtask(ic, &sc->wme_task);
    +
    +	/* return whatever, upper layer desn't care anyway */
    +	return 0;
    +}
    +
    +/* ARGSUSED */
    +static void
    +run_wme_update_cb(void *arg, int pending)
    +{
    +	struct ieee80211com *ic = arg;
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +	struct ieee80211_wme_state *wmesp = &ic->ic_wme;
    +	int aci, error = 0;
    +
    +	RUN_LOCK(sc);
    +
    +	/* update MAC TX configuration registers */
    +	for (aci = 0; aci < WME_NUM_AC; aci++) {
    +		error = run_write(sc, RT2860_EDCA_AC_CFG(aci),
    +		    wmesp->wme_params[aci].wmep_logcwmax << 16 |
    +		    wmesp->wme_params[aci].wmep_logcwmin << 12 |
    +		    wmesp->wme_params[aci].wmep_aifsn  <<  8 |
    +		    wmesp->wme_params[aci].wmep_txopLimit);
    +		if(error) goto err;
    +	}
    +
    +	/* update SCH/DMA registers too */
    +	error = run_write(sc, RT2860_WMM_AIFSN_CFG,
    +	    wmesp->wme_params[WME_AC_VO].wmep_aifsn  << 12 |
    +	    wmesp->wme_params[WME_AC_VI].wmep_aifsn  <<  8 |
    +	    wmesp->wme_params[WME_AC_BK].wmep_aifsn  <<  4 |
    +	    wmesp->wme_params[WME_AC_BE].wmep_aifsn);
    +	if(error) goto err;
    +	error = run_write(sc, RT2860_WMM_CWMIN_CFG,
    +	    wmesp->wme_params[WME_AC_VO].wmep_logcwmin << 12 |
    +	    wmesp->wme_params[WME_AC_VI].wmep_logcwmin <<  8 |
    +	    wmesp->wme_params[WME_AC_BK].wmep_logcwmin <<  4 |
    +	    wmesp->wme_params[WME_AC_BE].wmep_logcwmin);
    +	if(error) goto err;
    +	error = run_write(sc, RT2860_WMM_CWMAX_CFG,
    +	    wmesp->wme_params[WME_AC_VO].wmep_logcwmax << 12 |
    +	    wmesp->wme_params[WME_AC_VI].wmep_logcwmax <<  8 |
    +	    wmesp->wme_params[WME_AC_BK].wmep_logcwmax <<  4 |
    +	    wmesp->wme_params[WME_AC_BE].wmep_logcwmax);
    +	if(error) goto err;
    +	error = run_write(sc, RT2860_WMM_TXOP0_CFG,
    +	    wmesp->wme_params[WME_AC_BK].wmep_txopLimit << 16 |
    +	    wmesp->wme_params[WME_AC_BE].wmep_txopLimit);
    +	if(error) goto err;
    +	error = run_write(sc, RT2860_WMM_TXOP1_CFG,
    +	    wmesp->wme_params[WME_AC_VO].wmep_txopLimit << 16 |
    +	    wmesp->wme_params[WME_AC_VI].wmep_txopLimit);
    +
    +err:
    +	if(error)
    +		DPRINTF("WME update failed\n");
    +
    +	RUN_UNLOCK(sc);
    +	return;
    +}
    +
    +static void
    +run_key_update_begin(struct ieee80211vap *vap)
    +{
    +	/*
    +	 * Because run_key_delete() needs special attention
    +	 * on lock related operation, lock handling is being done
    +	 * differently in run_key_set and _delete.
    +	 *
    +	 * So, we don't use key_update_begin and _end.
    +	 */
    +}
    +
    +static void
    +run_key_update_end(struct ieee80211vap *vap)
    +{
    +	/* null */
    +}
    +
    +/*
    + * return 0 on error
    + */
    +static int
    +run_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k,
    +		const uint8_t mac[IEEE80211_ADDR_LEN])
    +{
    +	struct ieee80211com *ic = vap->iv_ic;
    +	struct ifnet *ifp = ic->ic_ifp;
    +	struct run_softc *sc = ifp->if_softc;
    +	struct ieee80211_node *ni;
    +	uint32_t attr;
    +	uint16_t base, associd;
    +	uint8_t mode, wcid, txmic, rxmic, iv[8];
    +	int error = 0;
    +
    +	RUN_LOCK(sc);
    +
    +	if(vap->iv_opmode == IEEE80211_M_HOSTAP){
    +		ni = ieee80211_find_vap_node(&ic->ic_sta, vap, mac);
    +		associd = (ni != NULL) ? ni->ni_associd : 0;
    +		if(ni != NULL)
    +			ieee80211_free_node(ni);
    +		txmic = 24;
    +		rxmic = 16;
    +	} else {
    +		ni = vap->iv_bss;
    +		associd = (ni != NULL) ? ni->ni_associd : 0;
    +		txmic = 16;
    +		rxmic = 24;
    +	}
    +
    +	/* map net80211 cipher to RT2860 security mode */
    +	switch (k->wk_cipher->ic_cipher) {
    +	case IEEE80211_CIPHER_WEP:
    +		if(k->wk_keylen < 8)
    +			mode = RT2860_MODE_WEP40;
    +		else
    +			mode = RT2860_MODE_WEP104;
    +		break;
    +	case IEEE80211_CIPHER_TKIP:
    +		mode = RT2860_MODE_TKIP;
    +		break;
    +	case IEEE80211_CIPHER_AES_CCM:
    +		mode = RT2860_MODE_AES_CCMP;
    +		break;
    +	default:
    +		DPRINTF("undefined case\n");
    +		goto fail;
    +	}
    +
    +	DPRINTFN(1, "associd=%x, keyix=%d, mode=%x, type=%s\n",
    +	    associd, k->wk_keyix, mode,
    +	    (k->wk_flags & IEEE80211_KEY_GROUP) ? "group" : "pairwise");
    +
    +	if (k->wk_flags & IEEE80211_KEY_GROUP) {
    +		wcid = 0;	/* NB: update WCID0 for group keys */
    +		base = RT2860_SKEY(0, k->wk_keyix);
    +	} else {
    +		wcid = RUN_AID2WCID(associd);
    +		base = RT2860_PKEY(wcid);
    +	}
    +
    +	if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP) {
    +		if(run_write_region_1(sc, base, k->wk_key, 16))
    +			goto fail;
    +		if(run_write_region_1(sc, base + 16, &k->wk_key[txmic], 8))	/* wk_txmic */
    +			goto fail;
    +		if(run_write_region_1(sc, base + 24, &k->wk_key[rxmic], 8))	/* wk_rxmic */
    +			goto fail;
    +	} else {
    +		/* roundup len to 16-bit: XXX fix write_region_1() instead */
    +		if(run_write_region_1(sc, base, k->wk_key, (k->wk_keylen + 1) & ~1))
    +			goto fail;
    +	}
    +
    +	if (!(k->wk_flags & IEEE80211_KEY_GROUP) ||
    +	    (k->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV))) {
    +		/* set initial packet number in IV+EIV */
    +		if (k->wk_cipher == IEEE80211_CIPHER_WEP){
    +			memset(iv, 0, sizeof iv);
    +			iv[3] = sc->sc_rvp->vap.iv_def_txkey << 6;
    +		} else {
    +			if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP) {
    +				iv[0] = k->wk_keytsc >> 8;
    +				iv[1] = (iv[0] | 0x20) & 0x7f;
    +				iv[2] = k->wk_keytsc;
    +			} else /* CCMP */ {
    +				iv[0] = k->wk_keytsc;
    +				iv[1] = k->wk_keytsc >> 8;
    +				iv[2] = 0;
    +			}
    +			iv[3] = k->wk_keyix << 6 | IEEE80211_WEP_EXTIV;
    +			iv[4] = k->wk_keytsc >> 16;
    +			iv[5] = k->wk_keytsc >> 24;
    +			iv[6] = k->wk_keytsc >> 32;
    +			iv[7] = k->wk_keytsc >> 40;
    +		}
    +		if(run_write_region_1(sc, RT2860_IVEIV(wcid), iv, 8))
    +			goto fail;
    +	}
    +
    +	if (k->wk_flags & IEEE80211_KEY_GROUP) {
    +		/* install group key */
    +		if(run_read(sc, RT2860_SKEY_MODE_0_7, &attr))
    +			goto fail;
    +		attr &= ~(0xf << (k->wk_keyix * 4));
    +		attr |= mode << (k->wk_keyix * 4);
    +		if(run_write(sc, RT2860_SKEY_MODE_0_7, attr))
    +			goto fail;
    +	} else {
    +		/* install pairwise key */
    +		if(run_read(sc, RT2860_WCID_ATTR(wcid), &attr))
    +			goto fail;
    +		attr = (attr & ~0xf) | (mode << 1) | RT2860_RX_PKEY_EN;
    +		if(run_write(sc, RT2860_WCID_ATTR(wcid), attr))
    +			goto fail;
    +	}
    +
    +	/* TODO create a pass-thru key entry? */
    +
    +fail:
    +	RUN_UNLOCK(sc);
    +	return (error? 0 : 1);
    +}
    +
    +/*
    + * return 0 on error
    + */
    +static int
    +run_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
    +{
    +	struct ieee80211com *ic = vap->iv_ic;
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +	struct ieee80211_node *ni = vap->iv_bss;
    +	struct ieee80211_node_table *nt = &ic->ic_sta;
    +	uint32_t attr;
    +	uint8_t wcid;
    +	int error = 0;
    +	uint8_t nislocked, cislocked;
    +
    +	if((nislocked = IEEE80211_NODE_IS_LOCKED(nt)))
    +		IEEE80211_NODE_UNLOCK(nt);
    +	if((cislocked = mtx_owned(&ic->ic_comlock.mtx)))
    +		IEEE80211_UNLOCK(ic);
    +	RUN_LOCK(sc);
    +
    +	if (k->wk_flags & IEEE80211_KEY_GROUP) {
    +		/* remove group key */
    +		if(run_read(sc, RT2860_SKEY_MODE_0_7, &attr))
    +			goto fail;
    +		attr &= ~(0xf << (k->wk_keyix * 4));
    +		if(run_write(sc, RT2860_SKEY_MODE_0_7, attr))
    +			goto fail;
    +	} else {
    +		/* remove pairwise key */
    +		wcid = RUN_AID2WCID((ni != NULL) ? ni->ni_associd : 0);
    +		if(run_read(sc, RT2860_WCID_ATTR(wcid), &attr))
    +			goto fail;
    +		attr &= ~0xf;
    +		if(run_write(sc, RT2860_WCID_ATTR(wcid), attr))
    +			goto fail;
    +	}
    +
    +fail:
    +	RUN_UNLOCK(sc);
    +	if(cislocked)
    +		IEEE80211_LOCK(ic);
    +	if(nislocked)
    +		IEEE80211_NODE_LOCK(nt);
    +
    +	return (error? 0 : 1);
    +}
    +
    +static void
    +run_amrr_start(struct run_softc *sc, struct ieee80211_node *ni)
    +{
    +	struct ieee80211vap *vap = ni->ni_vap;
    +	struct run_vap *rvp = RUN_VAP(vap);
    +	uint32_t sta[3];
    +	uint8_t wcid;
    +
    +	RUN_LOCK_ASSERT(sc, MA_OWNED);
    +
    +	/* read statistic counters (clear on read) and update AMRR state */
    +	run_read_region_1(sc, RT2860_TX_STA_CNT0,
    +	    (uint8_t *)sta, sizeof sta);
    +
    +	wcid = RUN_AID2WCID(ni == NULL ? 0 : ni->ni_associd);
    +	ieee80211_amrr_node_init(&rvp->amrr, &rvp->amn[wcid], ni);
    +
    +	/* start at lowest available bit-rate, AMRR will raise */
    +	ni->ni_txrate = 2;
    +
    +	/* start calibration timer */
    +	rvp->amrr_run = RUN_AMRR_ON;
    +	usb_callout_reset(&rvp->amrr_ch, hz, run_amrr_to, rvp);
    +}
    +
    +static void
    +run_amrr_to(void *arg)
    +{
    +	struct run_vap *rvp = arg;
    +
    +	/* do it in a process context, so it can go sleep */
    +	ieee80211_runtask(rvp->vap.iv_ic, &rvp->amrr_task);
    +	/* next timeout will be rescheduled in the callback task */
    +}
    +
    +/* ARGSUSED */
    +static void
    +run_amrr_cb(void *arg, int pending)
    +{
    +	struct run_vap *rvp = arg;
    +	struct ieee80211vap *vap = &rvp->vap;
    +	struct ieee80211com *ic = vap->iv_ic;
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +
    +	if (ic->ic_opmode == IEEE80211_M_STA)
    +		run_iter_func(rvp, vap->iv_bss);
    +	else {
    +		/*
    +		 * run_reset_livelock() doesn't do anything with AMRR,
    +		 * but Ralink wants us to call it every 1 sec. So, we
    +		 * piggyback here rather than creating another callout.
    +		 * Livelock may occur only in HOSTAP or IBSS mode
    +		 * (when h/w is sending beacons).
    +		 */
    +		RUN_LOCK(sc);
    +		run_reset_livelock(sc);
    +		RUN_UNLOCK(sc);
    +		ieee80211_iterate_nodes(&ic->ic_sta, run_iter_func, rvp);
    +	}
    +
    +	if(rvp->amrr_run == RUN_AMRR_ON)
    +		usb_callout_reset(&rvp->amrr_ch, hz, run_amrr_to, rvp);
    +}
    +
    +
    +static void
    +run_iter_func(void *arg, struct ieee80211_node *ni)
    +{
    +	struct run_vap *rvp = arg;
    +	struct ieee80211com *ic = rvp->vap.iv_ic;
    +	struct ifnet *ifp = ic->ic_ifp;
    +	struct run_softc *sc = ifp->if_softc;
    +	struct ieee80211_node_table *nt = &ic->ic_sta;
    +	struct ieee80211_amrr_node *amn = &rvp->amn[0]; /* make compiler happy */
    +	uint32_t sta[3], stat;
    +	int error;
    +	uint8_t wcid, mcs, pid;
    +
    +	if(ic->ic_opmode != IEEE80211_M_STA)
    +		IEEE80211_NODE_ITERATE_UNLOCK(nt);
    +
    +	RUN_LOCK(sc);
    +
    +	if(ic->ic_opmode != IEEE80211_M_STA){
    +		/* drain Tx status FIFO (maxsize = 16) */
    +		run_read(sc, RT2860_TX_STAT_FIFO, &stat);
    +		while (stat & RT2860_TXQ_VLD) {
    +			DPRINTFN(4, "tx stat 0x%08x\n", stat);
    +
    +			wcid = (stat >> RT2860_TXQ_WCID_SHIFT) & 0xff;
    +
    +			/* if no ACK was requested, no feedback is available */
    +			if (!(stat & RT2860_TXQ_ACKREQ) || wcid == 0xff)
    +				continue;
    +
    +			/* update per-STA AMRR stats */
    +			amn = &rvp->amn[wcid];
    +			amn->amn_txcnt++;
    +			if (stat & RT2860_TXQ_OK) {
    +				amn->amn_success++;
    +				/*
    +				 * Check if there were retries, ie if the Tx
    +				 * success rate is different from the requested
    +				 * rate.  Note that it works only because we do
    +				 * not allow rate fallback from OFDM to CCK.
    +				 */
    +				mcs = (stat >> RT2860_TXQ_MCS_SHIFT) & 0x7f;
    +				pid = (stat >> RT2860_TXQ_PID_SHIFT) & 0xf;
    +				if (mcs + 1 != pid)
    +					amn->amn_retrycnt++;
    +			} else {
    +				amn->amn_retrycnt++;
    +				ifp->if_oerrors++;
    +			}
    +			run_read_region_1(sc, RT2860_TX_STAT_FIFO,
    +			    (uint8_t *)&stat, sizeof stat);
    +		}
    +		DPRINTFN(3, "retrycnt=%d txcnt=%d success=%d\n",
    +		    amn->amn_retrycnt, amn->amn_txcnt, amn->amn_success);
    +	} else {
    +		/* read statistic counters (clear on read) and update AMRR state */
    +		error = run_read_region_1(sc, RT2860_TX_STA_CNT0, (uint8_t *)sta,
    +		    sizeof sta);
    +		if (error != 0)
    +			goto skip;
    +
    +		DPRINTFN(3, "retrycnt=%d txcnt=%d failcnt=%d\n",
    +		    le32toh(sta[1]) >> 16, le32toh(sta[1]) & 0xffff,
    +		    le32toh(sta[0]) & 0xffff);
    +
    +		wcid = RUN_AID2WCID(ni == NULL ? 0 : ni->ni_associd);
    +		amn = &rvp->amn[wcid];
    +
    +		/* count failed TX as errors */
    +		ifp->if_oerrors += le32toh(sta[0]) & 0xffff;
    +
    +		amn->amn_retrycnt =
    +		    (le32toh(sta[0]) & 0xffff) +	/* failed TX count */
    +		    (le32toh(sta[1]) >> 16);		/* TX retransmission count */
    +
    +		amn->amn_txcnt =
    +		    amn->amn_retrycnt +
    +		    (le32toh(sta[1]) & 0xffff);		/* successful TX count */
    +
    +		amn->amn_success =
    +		    (le32toh(sta[1]) >> 16) +
    +		    (le32toh(sta[1]) & 0xffff);
    +	}
    +
    +	ieee80211_amrr_choose(ni, amn);
    +
    +skip:;
    +	RUN_UNLOCK(sc);
    +
    +	if(ic->ic_opmode != IEEE80211_M_STA)
    +		IEEE80211_NODE_ITERATE_LOCK(nt);
    +}
    +
    +static void
    +run_newassoc(struct ieee80211_node *ni, int isnew)
    +{
    +	struct run_node *rn = (void *)ni;
    +	struct ieee80211_rateset *rs = &ni->ni_rates;
    +	uint8_t rate;
    +	int ridx, i, j;
    +
    +	DPRINTF("new assoc isnew=%d addr=%s\n",
    +	    isnew, ether_sprintf(ni->ni_macaddr));
    +
    +	for (i = 0; i < rs->rs_nrates; i++) {
    +		rate = rs->rs_rates[i] & IEEE80211_RATE_VAL;
    +		/* convert 802.11 rate to hardware rate index */
    +		for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
    +			if (rt2860_rates[ridx].rate == rate)
    +				break;
    +		rn->ridx[i] = ridx;
    +		/* determine rate of control response frames */
    +		for (j = i; j >= 0; j--) {
    +			if ((rs->rs_rates[j] & IEEE80211_RATE_BASIC) &&
    +			    rt2860_rates[rn->ridx[i]].phy ==
    +			    rt2860_rates[rn->ridx[j]].phy)
    +				break;
    +		}
    +		if (j >= 0) {
    +			rn->ctl_ridx[i] = rn->ridx[j];
    +		} else {
    +			/* no basic rate found, use mandatory one */
    +			rn->ctl_ridx[i] = rt2860_rates[ridx].ctl_ridx;
    +		}
    +		DPRINTF("rate=0x%02x ridx=%d ctl_ridx=%d\n",
    +		    rs->rs_rates[i], rn->ridx[i], rn->ctl_ridx[i]);
    +	}
    +}
    +
    +/*
    + * Return the Rx chain with the highest RSSI for a given frame.
    + */
    +static __inline uint8_t
    +run_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi)
    +{
    +	uint8_t rxchain = 0;
    +
    +	if (sc->nrxchains > 1) {
    +		if (rxwi->rssi[1] > rxwi->rssi[rxchain])
    +			rxchain = 1;
    +		if (sc->nrxchains > 2)
    +			if (rxwi->rssi[2] > rxwi->rssi[rxchain])
    +				rxchain = 2;
    +	}
    +	return rxchain;
    +}
    +
    +static void
    +run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
    +{
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211vap *vap = &sc->sc_rvp->vap;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	struct ieee80211_frame *wh;
    +	struct ieee80211_node *ni;
    +	struct rt2870_rxd *rxd;
    +	struct rt2860_rxwi *rxwi;
    +	uint32_t flags;
    +	uint16_t len, phy;
    +	uint8_t ant, rssi;
    +	int8_t nf;
    +
    +	rxwi = mtod(m, struct rt2860_rxwi *);
    +	len = le16toh(rxwi->len) & 0xfff;
    +	if (__predict_false(len > dmalen)) {
    +		m_freem(m);
    +		ifp->if_ierrors++;
    +		DPRINTF("bad RXWI length %u > %u\n", len, dmalen);
    +		return;
    +	}
    +	/* Rx descriptor is located at the end */
    +	rxd = (struct rt2870_rxd *)(mtod(m, caddr_t) + dmalen);
    +	flags = le32toh(rxd->flags);
    +
    +	if (__predict_false(flags & (RT2860_RX_CRCERR | RT2860_RX_ICVERR))) {
    +		m_freem(m);
    +		ifp->if_ierrors++;
    +		DPRINTF("%s error.\n", (flags & RT2860_RX_CRCERR)?"CRC":"ICV");
    +		return;
    +	}
    +
    +	m->m_data += sizeof(struct rt2860_rxwi);
    +	m->m_pkthdr.len = m->m_len -= sizeof(struct rt2860_rxwi);
    +
    +	wh = mtod(m, struct ieee80211_frame *);
    +
    +	if (wh->i_fc[1] & IEEE80211_FC1_WEP){
    +		wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
    +		m->m_flags |= M_WEP;
    +	}
    +
    +	if (flags & RT2860_RX_L2PAD){
    +		DPRINTFN(8, "received RT2860_RX_L2PAD frame\n");
    +		len += 2;
    +	}
    +
    +	if (__predict_false(flags & RT2860_RX_MICERR)) {
    +		/* report MIC failures to net80211 for TKIP */
    +		ieee80211_notify_michael_failure(vap, wh, rxwi->keyidx);
    +		m_freem(m);
    +		ifp->if_ierrors++;
    +		DPRINTF("MIC error. Someone is lying.\n");
    +		return;
    +	}
    +
    +	ant = run_maxrssi_chain(sc, rxwi);
    +	rssi = rxwi->rssi[ant];
    +	nf = run_rssi2dbm(sc, rssi, ant);
    +
    +	m->m_pkthdr.rcvif = ifp;
    +	m->m_pkthdr.len = m->m_len = len;
    +
    +	ni = ieee80211_find_rxnode(ic,
    +	    mtod(m, struct ieee80211_frame_min *));
    +	if (ni != NULL) {
    +		(void)ieee80211_input(ni, m, rssi, nf);
    +		ieee80211_free_node(ni);
    +	} else {
    +		(void)ieee80211_input_all(ic, m, rssi, nf);
    +	}
    +
    +	if(__predict_false(ieee80211_radiotap_active(ic))){
    +		struct run_rx_radiotap_header *tap = &sc->sc_rxtap;
    +
    +		tap->wr_flags = 0;
    +		tap->wr_chan_freq = htole16(ic->ic_bsschan->ic_freq);
    +		tap->wr_chan_flags = htole16(ic->ic_bsschan->ic_flags);
    +		tap->wr_antsignal = rssi;
    +		tap->wr_antenna = ant;
    +		tap->wr_dbm_antsignal = run_rssi2dbm(sc, rssi, ant);
    +		tap->wr_rate = 2;	/* in case it can't be found below */
    +		phy = le16toh(rxwi->phy);
    +		switch (phy & RT2860_PHY_MODE) {
    +		case RT2860_PHY_CCK:
    +			switch ((phy & RT2860_PHY_MCS) & ~RT2860_PHY_SHPRE) {
    +			case 0:	tap->wr_rate =   2; break;
    +			case 1:	tap->wr_rate =   4; break;
    +			case 2:	tap->wr_rate =  11; break;
    +			case 3:	tap->wr_rate =  22; break;
    +			}
    +			if (phy & RT2860_PHY_SHPRE)
    +				tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
    +			break;
    +		case RT2860_PHY_OFDM:
    +			switch (phy & RT2860_PHY_MCS) {
    +			case 0:	tap->wr_rate =  12; break;
    +			case 1:	tap->wr_rate =  18; break;
    +			case 2:	tap->wr_rate =  24; break;
    +			case 3:	tap->wr_rate =  36; break;
    +			case 4:	tap->wr_rate =  48; break;
    +			case 5:	tap->wr_rate =  72; break;
    +			case 6:	tap->wr_rate =  96; break;
    +			case 7:	tap->wr_rate = 108; break;
    +			}
    +			break;
    +		}
    +	}
    +}
    +
    +static void
    +run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
    +{
    +	struct run_softc *sc = usbd_xfer_softc(xfer);
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct mbuf *m = NULL;
    +	struct mbuf *m0;
    +	uint32_t dmalen;
    +	int xferlen;
    +
    +	usbd_xfer_status(xfer, &xferlen, NULL, NULL, NULL);
    +
    +	switch (USB_GET_STATE(xfer)) {
    +	case USB_ST_TRANSFERRED:
    +
    +		DPRINTFN(15, "rx done, actlen=%d\n", xferlen);
    +
    +		if (xferlen < sizeof (uint32_t) +
    +		    sizeof (struct rt2860_rxwi) + sizeof (struct rt2870_rxd)) {
    +			DPRINTF("xfer too short %d\n", xferlen);
    +			goto tr_setup;
    +		}
    +
    +		m = sc->rx_m;
    +		sc->rx_m = NULL;
    +
    +		/* FALLTHROUGH */
    +	case USB_ST_SETUP:
    +tr_setup:
    +		if (sc->rx_m == NULL) {
    +			sc->rx_m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
    +			    MJUMPAGESIZE /* xfer can be bigger than MCLBYTES */);
    +		}
    +		if (sc->rx_m == NULL) {
    +			DPRINTF("could not allocate mbuf - idle with stall\n");
    +			ifp->if_ierrors++;
    +			usbd_xfer_set_stall(xfer);
    +			usbd_xfer_set_frames(xfer, 0);
    +		} else {
    +			/*
    +			 * Directly loading a mbuf cluster into DMA to
    +			 * save some data copying. This works because
    +			 * there is only one cluster.
    +			 */
    +			usbd_xfer_set_frame_data(xfer, 0, 
    +			    mtod(sc->rx_m, caddr_t), RUN_MAX_RXSZ);
    +			usbd_xfer_set_frames(xfer, 1);
    +		}
    +		usbd_transfer_submit(xfer);
    +		break;
    +
    +	default:	/* Error */
    +		if (error != USB_ERR_CANCELLED) {
    +			/* try to clear stall first */
    +			usbd_xfer_set_stall(xfer);
    +
    +			if (error == USB_ERR_TIMEOUT)
    +				device_printf(sc->sc_dev, "device timeout\n");
    +
    +			ifp->if_ierrors++;
    +
    +			goto tr_setup;
    +		}
    +		if(sc->rx_m != NULL){
    +			m_freem(sc->rx_m);
    +			sc->rx_m = NULL;
    +		}
    +		break;
    +	}
    +
    +	if (m == NULL)
    +		return;
    +
    +	/* inputting all the frames must be last */
    +
    +	RUN_UNLOCK(sc);
    +
    +	m->m_pkthdr.len = m->m_len = xferlen;
    +
    +	/* HW can aggregate multiple 802.11 frames in a single USB xfer */
    +	for(;;) {
    +		dmalen = le32toh(*mtod(m, uint32_t *)) & 0xffff;
    +
    +		if ((dmalen == 0) || ((dmalen & 3) != 0)) {
    +			DPRINTF("bad DMA length %u\n", dmalen);
    +			break;
    +		}
    +		if ((dmalen + 8) > xferlen) {
    +			DPRINTF("bad DMA length %u > %d\n",
    +			dmalen + 8, xferlen);
    +			break;
    +		}
    +
    +		/* If it is the last one or a single frame, we won't copy. */
    +		if((xferlen -= dmalen + 8) <= 8){
    +			/* trim 32-bit DMA-len header */
    +			m->m_data += 4;
    +			m->m_pkthdr.len = m->m_len -= 4;
    +			run_rx_frame(sc, m, dmalen);
    +			break;
    +		}
    +
    +		/* copy aggregated frames to another mbuf */
    +		m0 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
    +		if (__predict_false(m0 == NULL)) {
    +			DPRINTF("could not allocate mbuf\n");
    +			ifp->if_ierrors++;
    +			break;
    +		}
    +		m_copydata(m, 4 /* skip 32-bit DMA-len header */,
    +		    dmalen + sizeof(struct rt2870_rxd), mtod(m0, caddr_t));
    +		m0->m_pkthdr.len = m0->m_len =
    +		    dmalen + sizeof(struct rt2870_rxd);
    +		run_rx_frame(sc, m0, dmalen);
    +
    +		/* update data ptr */
    +		m->m_data += dmalen + 8;
    +		m->m_pkthdr.len = m->m_len -= dmalen + 8;
    +	}
    +
    +	RUN_LOCK(sc);
    +}
    +
    +static void
    +run_tx_free(struct run_endpoint_queue *pq,
    +    struct run_tx_data *data, int txerr)
    +{
    +	if (data->m != NULL) {
    +		if (data->m->m_flags & M_TXCB)
    +			ieee80211_process_callback(data->ni, data->m,
    +			    txerr ? ETIMEDOUT : 0);
    +		m_freem(data->m);
    +		data->m = NULL;
    +
    +		if(data->ni == NULL) {
    +			DPRINTF("no node\n");
    +		} else {
    +			ieee80211_free_node(data->ni);
    +			data->ni = NULL;
    +		}
    +	}
    +
    +	STAILQ_INSERT_TAIL(&pq->tx_fh, data, next);
    +	pq->tx_nfree++;
    +}
    +
    +static void
    +run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, unsigned int index)
    +{
    +	struct run_softc *sc = usbd_xfer_softc(xfer);
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct run_tx_data *data;
    +	struct ieee80211vap *vap = NULL;
    +	struct usb_page_cache *pc;
    +	struct run_endpoint_queue *pq = &sc->sc_epq[index];
    +	struct mbuf *m;
    +	usb_frlength_t size;
    +	unsigned int len;
    +	int actlen;
    +	int sumlen;
    +
    +	usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
    +
    +	switch (USB_GET_STATE(xfer)){
    +	case USB_ST_TRANSFERRED:
    +		DPRINTFN(11, "transfer complete: %d "
    +		    "bytes @ index %d\n", actlen, index);
    +
    +		data = usbd_xfer_get_priv(xfer);
    +
    +		run_tx_free(pq, data, 0);
    +		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
    +
    +		usbd_xfer_set_priv(xfer, NULL);
    +
    +		ifp->if_opackets++;
    +
    +		/* FALLTHROUGH */
    +	case USB_ST_SETUP:
    +tr_setup:
    +		data = STAILQ_FIRST(&pq->tx_qh);
    +		if(data == NULL)
    +			break;
    +
    +		STAILQ_REMOVE_HEAD(&pq->tx_qh, next);
    +
    +		m = data->m;
    +		if (m->m_pkthdr.len > RUN_MAX_TXSZ) {
    +			DPRINTF("data overflow, %u bytes\n",
    +			    m->m_pkthdr.len);
    +
    +			ifp->if_oerrors++;
    +
    +			run_tx_free(pq, data, 1);
    +
    +			goto tr_setup;
    +		}
    +
    +		pc = usbd_xfer_get_frame(xfer, 0);
    +		size = sizeof(data->desc);
    +		usbd_copy_in(pc, 0, &data->desc, size);
    +		usbd_m_copy_in(pc, size, m, 0, m->m_pkthdr.len);
    +
    +		vap = data->ni->ni_vap;
    +		if (ieee80211_radiotap_active_vap(vap)) {
    +			struct run_tx_radiotap_header *tap = &sc->sc_txtap;
    +
    +			tap->wt_flags = 0;
    +			tap->wt_rate = rt2860_rates[data->ridx].rate;
    +			tap->wt_chan_freq = htole16(vap->iv_bss->ni_chan->ic_freq);
    +			tap->wt_chan_flags = htole16(vap->iv_bss->ni_chan->ic_flags);
    +			tap->wt_hwqueue = index;
    +			if (data->mcs & RT2860_PHY_SHPRE)
    +				tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
    +
    +			ieee80211_radiotap_tx(vap, m);
    +		}
    +
    +		/* align end on a 4-bytes boundary */
    +		len = (size + m->m_pkthdr.len + 3) & ~3;
    +
    +		DPRINTFN(11, "sending frame len=%u xferlen=%u @ index %d\n",
    +			m->m_pkthdr.len, len, index);
    +
    +		usbd_xfer_set_frame_len(xfer, 0, len);
    +		usbd_xfer_set_priv(xfer, data);
    +
    +		usbd_transfer_submit(xfer);
    +
    +		RUN_UNLOCK(sc);
    +		run_start(ifp);
    +		RUN_LOCK(sc);
    +
    +		break;
    +
    +	default:
    +		DPRINTF("USB transfer error, %s\n",
    +		    usbd_errstr(error));
    +
    +		data = usbd_xfer_get_priv(xfer);
    +
    +		ifp->if_oerrors++;
    +
    +		if (data != NULL) {
    +			run_tx_free(pq, data, error);
    +			usbd_xfer_set_priv(xfer, NULL);
    +		}
    +
    +		if (error != USB_ERR_CANCELLED) {
    +			if (error == USB_ERR_TIMEOUT) {
    +				device_printf(sc->sc_dev, "device timeout\n");
    +				ieee80211_runtask(ifp->if_l2com, &sc->usb_timeout_task);
    +			}
    +
    +			/*
    +			 * Try to clear stall first, also if other
    +			 * errors occur, hence clearing stall
    +			 * introduces a 50 ms delay:
    +			 */
    +			usbd_xfer_set_stall(xfer);
    +			goto tr_setup;
    +		}
    +		break;
    +	}
    +}
    +
    +static void
    +run_bulk_tx_callback0(struct usb_xfer *xfer, usb_error_t error)
    +{
    +	run_bulk_tx_callbackN(xfer, error, 0);
    +}
    +
    +static void
    +run_bulk_tx_callback1(struct usb_xfer *xfer, usb_error_t error)
    +{
    +	run_bulk_tx_callbackN(xfer, error, 1);
    +}
    +
    +static void
    +run_bulk_tx_callback2(struct usb_xfer *xfer, usb_error_t error)
    +{
    +	run_bulk_tx_callbackN(xfer, error, 2);
    +}
    +
    +static void
    +run_bulk_tx_callback3(struct usb_xfer *xfer, usb_error_t error)
    +{
    +	run_bulk_tx_callbackN(xfer, error, 3);
    +}
    +
    +static void
    +run_bulk_tx_callback4(struct usb_xfer *xfer, usb_error_t error)
    +{
    +	run_bulk_tx_callbackN(xfer, error, 4);
    +}
    +
    +static void
    +run_bulk_tx_callback5(struct usb_xfer *xfer, usb_error_t error)
    +{
    +	run_bulk_tx_callbackN(xfer, error, 5);
    +}
    +
    +static void
    +run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data,
    +	uint8_t wflags, uint8_t xflags, uint8_t opflags, uint8_t dflags,
    +	uint8_t type, uint8_t pad)
    +{
    +	struct mbuf *m = data->m;
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	struct ieee80211vap *vap = &sc->sc_rvp->vap;
    +	struct ieee80211_frame *wh;
    +	struct rt2870_txd *txd;
    +	struct rt2860_txwi *txwi;
    +	int xferlen;
    +	uint8_t mcs;
    +	uint8_t ridx = data->ridx;
    +
    +	/* get MCS code from rate index */
    +	data->mcs = mcs = rt2860_rates[ridx].mcs;
    +
    +	xferlen = sizeof(*txwi) + m->m_pkthdr.len;
    +
    +	/* roundup to 32-bit alignment */
    +	xferlen = (xferlen + 3) & ~3;
    +
    +	txd = (struct rt2870_txd *)&data->desc;
    +	txd->flags = dflags;
    +	txd->len = htole16(xferlen);
    +
    +	/* setup TX Wireless Information */
    +	txwi = (struct rt2860_txwi *)(txd + 1);
    +	txwi->flags = wflags;
    +	txwi->xflags = xflags;
    +	txwi->wcid = (type == IEEE80211_FC0_TYPE_DATA) ?
    +	    RUN_AID2WCID(data->ni->ni_associd) : 0xff;
    +	txwi->len = htole16(m->m_pkthdr.len - pad);
    +	if (rt2860_rates[ridx].phy == IEEE80211_T_DS) {
    +		txwi->phy = htole16(RT2860_PHY_CCK);
    +		if (ridx != RT2860_RIDX_CCK1 &&
    +		    (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
    +			mcs |= RT2860_PHY_SHPRE;
    +	} else
    +		txwi->phy = htole16(RT2860_PHY_OFDM);
    +	txwi->phy |= htole16(mcs);
    +
    +	wh = mtod(m, struct ieee80211_frame *);
    +
    +	/* check if RTS/CTS or CTS-to-self protection is required */
    +	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
    +	    (m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold ||
    +	     ((ic->ic_flags & IEEE80211_F_USEPROT) &&
    +	      rt2860_rates[ridx].phy == IEEE80211_T_OFDM)))
    +		txwi->txop = RT2860_TX_TXOP_HT | opflags;
    +	else
    +		txwi->txop = RT2860_TX_TXOP_BACKOFF | opflags;
    +}
    +
    +/* This function must be called locked */
    +static int
    +run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
    +{
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	struct ieee80211vap *vap = &sc->sc_rvp->vap;
    +	struct ieee80211_frame *wh;
    +	const struct ieee80211_txparam *tp;
    +	struct run_tx_data *data;
    +	uint16_t qos;
    +	uint16_t dur;
    +	uint8_t type;
    +	uint8_t tid;
    +	uint8_t qid;
    +	uint8_t qflags;
    +	uint8_t pad;
    +	uint8_t xflags = 0;
    +	int hasqos;
    +	int ridx;
    +	int ctl_ridx;
    +
    +	RUN_LOCK_ASSERT(sc, MA_OWNED);
    +
    +	wh = mtod(m, struct ieee80211_frame *);
    +
    +	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
    +
    +	/*
    +	 * There are 7 bulk endpoints: 1 for RX
    +	 * and 6 for TX (4 EDCAs + HCCA + Prio).
    +	 * Update 03-14-2009:  some devices like the Planex GW-US300MiniS
    +	 * seem to have only 4 TX bulk endpoints (Fukaumi Naoki).
    +	 */
    +	if ((hasqos = IEEE80211_QOS_HAS_SEQ(wh))) {
    +		uint8_t *frm;
    +
    +		if(IEEE80211_HAS_ADDR4(wh))
    +			frm = ((struct ieee80211_qosframe_addr4 *)wh)->i_qos;
    +		else
    +			frm =((struct ieee80211_qosframe *)wh)->i_qos;
    +
    +		qos = le16toh(*(const uint16_t *)frm);
    +		tid = qos & IEEE80211_QOS_TID;
    +		qid = TID_TO_WME_AC(tid);
    +		pad = 2;
    +	} else {
    +		qos = 0;
    +		tid = 0;
    +		qid = WME_AC_BE;
    +		pad = 0;
    +	}
    +	qflags = (qid < 4) ? RT2860_TX_QSEL_EDCA : RT2860_TX_QSEL_HCCA;
    +
    +	DPRINTFN(8, "qos %d\tqid %d\ttid %d\tqflags %x\n",
    +	    qos, qid, tid, qflags);
    +
    +	tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
    +
    +	/* pickup a rate index */
    +	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
    +	    type != IEEE80211_FC0_TYPE_DATA) {
    +		ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
    +		    RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1;
    +		ctl_ridx = rt2860_rates[ridx].ctl_ridx;
    +	} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
    +		ridx = sc->fixed_ridx;
    +		ctl_ridx = rt2860_rates[ridx].ctl_ridx;
    +	} else {
    +		for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++){
    +		        if (rt2860_rates[ridx].rate == ni->ni_txrate)
    +		                break;
    +		}
    +		ctl_ridx = rt2860_rates[ridx].ctl_ridx;
    +	}
    +
    +	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
    +	    (!hasqos || (qos & IEEE80211_QOS_ACKPOLICY) !=
    +	     IEEE80211_QOS_ACKPOLICY_NOACK)) {
    +		xflags |= RT2860_TX_ACK;
    +		if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
    +			dur = rt2860_rates[ridx].sp_ack_dur;
    +		else
    +			dur = rt2860_rates[ridx].lp_ack_dur;
    +		*(uint16_t *)wh->i_dur = htole16(dur + sc->sifs);
    +	}
    +
    +	/* reserve slots for mgmt packets, just in case */
    +	if (sc->sc_epq[qid].tx_nfree < 3) {
    +		DPRINTFN(10, "tx ring %d is full\n", qid);
    +		return (-1);
    +	}
    +
    +	data = STAILQ_FIRST(&sc->sc_epq[qid].tx_fh);
    +	STAILQ_REMOVE_HEAD(&sc->sc_epq[qid].tx_fh, next);
    +	sc->sc_epq[qid].tx_nfree--;
    +
    +	data->m = m;
    +	data->ni = ni;
    +	data->ridx = ridx;
    +
    +	run_set_tx_desc(sc, data, 0, xflags, 0, qflags, type, pad);
    +
    +        STAILQ_INSERT_TAIL(&sc->sc_epq[qid].tx_qh, data, next);
    +
    +	usbd_transfer_start(sc->sc_xfer[qid]);
    +
    +	DPRINTFN(8, "sending data frame len=%d rate=%d qid=%d\n", m->m_pkthdr.len +
    +	    (int)(sizeof (struct rt2870_txd) + sizeof (struct rt2860_rxwi)),
    +	    rt2860_rates[ridx].rate, qid);
    +
    +	return (0);
    +}
    +
    +static int
    +run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
    +{
    +	const struct ieee80211_txparam *tp;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211vap *vap = ni->ni_vap;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	struct run_tx_data *data;
    +	struct ieee80211_frame *wh;
    +	int ridx;
    +	uint16_t dur;
    +	uint8_t type;
    +	uint8_t xflags = 0;
    +
    +	RUN_LOCK_ASSERT(sc, MA_OWNED);
    +
    +	wh = mtod(m, struct ieee80211_frame *);
    +
    +	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
    +	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
    +
    +	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
    +		xflags |= RT2860_TX_ACK;
    +
    +		dur = ieee80211_ack_duration(ic->ic_rt, tp->mgmtrate, 
    +		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
    +		*(uint16_t *)wh->i_dur = htole16(dur);
    +
    +		/* tell hardware to add timestamp for probe responses */
    +		if ((wh->i_fc[0] &
    +		    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
    +		    (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
    +			xflags |= RT2860_TX_TS;
    +	}
    +
    +	if (sc->sc_epq[0].tx_nfree == 0) {
    +		/* let caller free mbuf */
    +		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +		return (EIO);
    +	}
    +	data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh);
    +	STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next);
    +	sc->sc_epq[0].tx_nfree--;
    +
    +	data->m = m;
    +	data->ni = ni;
    +	for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
    +		if (rt2860_rates[ridx].rate == tp->mgmtrate)
    +			break;
    +	data->ridx = ridx;
    +
    +	run_set_tx_desc(sc, data, 0, xflags, 0, RT2860_TX_QSEL_MGMT,
    +	    wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, 0);
    +
    +	DPRINTFN(10, "sending mgt frame len=%d rate=%d\n", m->m_pkthdr.len +
    +	    (int)(sizeof (struct rt2870_txd) + sizeof (struct rt2860_rxwi)),
    +	    tp->mgmtrate);
    +
    +	STAILQ_INSERT_TAIL(&sc->sc_epq[0].tx_qh, data, next);
    +
    +	usbd_transfer_start(sc->sc_xfer[0]);
    +
    +	return (0);
    +}
    +
    +static int
    +run_sendprot(struct run_softc *sc,
    +    const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
    +{
    +	struct ieee80211com *ic = ni->ni_ic;
    +	struct ieee80211_frame *wh;
    +	struct run_tx_data *data;
    +	struct mbuf *mprot;
    +	int ridx;
    +	int protrate;
    +	int ackrate;
    +	int pktlen;
    +	int isshort;
    +	uint16_t dur;
    +	uint8_t type;
    +	uint8_t wflags;
    +	uint8_t txflags = 0;
    +
    +	RUN_LOCK_ASSERT(sc, MA_OWNED);
    +
    +	KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY,
    +	    ("protection %d", prot));
    +
    +	wh = mtod(m, struct ieee80211_frame *);
    +	pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
    +	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
    +
    +	protrate = ieee80211_ctl_rate(ic->ic_rt, rate);
    +	ackrate = ieee80211_ack_rate(ic->ic_rt, rate);
    +
    +	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
    +	dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort);
    +	    + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
    +	wflags = RT2860_TX_FRAG;
    +
    +	/* check that there are free slots before allocating the mbuf */
    +	if (sc->sc_epq[0].tx_nfree == 0) {
    +		/* let caller free mbuf */
    +		sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +		return (ENOBUFS);
    +	}
    +
    +	if (prot == IEEE80211_PROT_RTSCTS) {
    +		/* NB: CTS is the same size as an ACK */
    +		dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort);
    +		txflags |= RT2860_TX_ACK;
    +		mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
    +	} else {
    +		mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
    +	}
    +	if (mprot == NULL) {
    +		sc->sc_ifp->if_oerrors++;
    +		DPRINTF("could not allocate mbuf\n");
    +		return (ENOBUFS);
    +	}
    +
    +        data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh);
    +        STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next);
    +        sc->sc_epq[0].tx_nfree--;
    +
    +	data->m = mprot;
    +	data->ni = ieee80211_ref_node(ni);
    +
    +	for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
    +		if (rt2860_rates[ridx].rate == protrate)
    +			break;
    +	data->ridx = ridx;
    +
    +	run_set_tx_desc(sc, data, wflags, txflags, 0,
    +	    RT2860_TX_QSEL_EDCA, type, 0);
    +
    +        DPRINTFN(1, "sending prot len=%u rate=%u\n",
    +            m->m_pkthdr.len, rate);
    +
    +        STAILQ_INSERT_TAIL(&sc->sc_epq[0].tx_qh, data, next);
    +
    +	usbd_transfer_start(sc->sc_xfer[0]);
    +
    +	return (0);
    +}
    +
    +static int
    +run_tx_param(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
    +    const struct ieee80211_bpf_params *params)
    +{
    +	struct ieee80211com *ic = ni->ni_ic;
    +	struct ieee80211_frame *wh;
    +	struct run_tx_data *data;
    +	uint8_t type;
    +	uint8_t opflags;
    +	uint8_t txflags;
    +	int ridx;
    +	int rate;
    +	int error;
    +
    +	RUN_LOCK_ASSERT(sc, MA_OWNED);
    +
    +	KASSERT(params != NULL, ("no raw xmit params"));
    +
    +	wh = mtod(m, struct ieee80211_frame *);
    +	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
    +
    +	rate = params->ibp_rate0;
    +	if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
    +		/* let caller free mbuf */
    +		return (EINVAL);
    +	}
    +
    +	opflags = 0;
    +	txflags = 0;
    +	if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
    +		txflags |= RT2860_TX_ACK;
    +	if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) {
    +		error = run_sendprot(sc, m, ni,
    +		    params->ibp_flags & IEEE80211_BPF_RTS ?
    +			IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
    +		    rate);
    +		if (error) {
    +			/* let caller free mbuf */
    +			return (error);
    +		}
    +		opflags |= /*XXX RT2573_TX_LONG_RETRY |*/ RT2860_TX_TXOP_SIFS;
    +	}
    +
    +	if (sc->sc_epq[0].tx_nfree == 0) {
    +		/* let caller free mbuf */
    +		sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +		DPRINTF("sending raw frame, but tx ring is full\n");
    +		return (EIO);
    +	}
    +        data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh);
    +        STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next);
    +        sc->sc_epq[0].tx_nfree--;
    +
    +        data->m = m;
    +        data->ni = ni;
    +	for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
    +		if (rt2860_rates[ridx].rate == rate)
    +			break;
    +	data->ridx = ridx;
    +
    +        run_set_tx_desc(sc, data, 0, txflags, opflags, 
    +	    RT2860_TX_QSEL_EDCA, type, 0);
    +
    +        DPRINTFN(10, "sending raw frame len=%u rate=%u\n",
    +            m->m_pkthdr.len, rate);
    +
    +        STAILQ_INSERT_TAIL(&sc->sc_epq[0].tx_qh, data, next);
    +
    +	usbd_transfer_start(sc->sc_xfer[0]);
    +
    +        return (0); 
    +}
    +
    +static int
    +run_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
    +    const struct ieee80211_bpf_params *params)
    +{
    +	struct ifnet *ifp = ni->ni_ic->ic_ifp;
    +	struct run_softc *sc = ifp->if_softc;
    +	int error;
    +
    +	RUN_LOCK(sc);
    +
    +	/* prevent management frames from being sent if we're not ready */
    +	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
    +		error =  ENETDOWN;
    +		goto bad;
    +	}
    +
    +	if (params == NULL) {
    +		/* tx mgt packet */
    +		if ((error = run_tx_mgt(sc, m, ni)) != 0){
    +			ifp->if_oerrors++;
    +			DPRINTF("mgt tx failed\n");
    +			goto bad;
    +		}
    +	} else {
    +		/* tx raw packet with param */
    +		if ((error = run_tx_param(sc, m, ni, params)) != 0){
    +			ifp->if_oerrors++;
    +			DPRINTF("tx with param failed\n");
    +			goto bad;
    +		}
    +	}
    +
    +	ifp->if_opackets++;
    +
    +	RUN_UNLOCK(sc);
    +
    +	return (0);
    +
    +bad:
    +	RUN_UNLOCK(sc);
    +	if(m != NULL)
    +		m_freem(m);
    +	ieee80211_free_node(ni);
    +
    +	return (error);
    +}
    +
    +static void
    +run_start(struct ifnet *ifp)
    +{
    +	struct run_softc *sc = ifp->if_softc;
    +	struct ieee80211_node *ni;
    +	struct mbuf *m;
    +
    +	RUN_LOCK(sc);
    +
    +	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
    +		RUN_UNLOCK(sc);
    +		return;
    +	}
    +
    +	for (;;) {
    +		/* send data frames */
    +		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
    +		if (m == NULL)
    +			break;
    +
    +		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
    +		if (run_tx(sc, m, ni) != 0) {
    +			IFQ_DRV_PREPEND(&ifp->if_snd, m);
    +			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +			break;
    +		}
    +	}
    +
    +	RUN_UNLOCK(sc);
    +}
    +
    +static int
    +run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
    +{
    +	struct run_softc *sc = ifp->if_softc;
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	struct ifreq *ifr = (struct ifreq *) data;
    +	int error = 0, startall = 0;
    +
    +	switch (cmd) {
    +	case SIOCSIFFLAGS:
    +		RUN_LOCK(sc);
    +		if (ifp->if_flags & IFF_UP) {
    +			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)){
    +				run_init_locked(sc);
    +				startall = 1;
    +			} else
    +				run_update_promisc_locked(ifp);
    +		} else {
    +			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
    +				run_stop(sc);
    +		}
    +		RUN_UNLOCK(sc);
    +		if(startall)
    +		    ieee80211_start_all(ic);
    +		break;
    +	case SIOCGIFMEDIA:
    +		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
    +		break;
    +	case SIOCGIFADDR:
    +		error = ether_ioctl(ifp, cmd, data);
    +		break;
    +	default:
    +		error = EINVAL;
    +		break;
    +	}
    +
    +	return (error);
    +}
    +
    +static void
    +run_select_chan_group(struct run_softc *sc, int group)
    +{
    +	uint32_t tmp;
    +
    +	run_bbp_write(sc, 62, 0x37 - sc->lna[group]);
    +	run_bbp_write(sc, 63, 0x37 - sc->lna[group]);
    +	run_bbp_write(sc, 64, 0x37 - sc->lna[group]);
    +	run_bbp_write(sc, 86, 0x00);
    +
    +	if (group == 0) {
    +		if (sc->ext_2ghz_lna) {
    +			run_bbp_write(sc, 82, 0x62);
    +			run_bbp_write(sc, 75, 0x46);
    +		} else {
    +			run_bbp_write(sc, 82, 0x84);
    +			run_bbp_write(sc, 75, 0x50);
    +		}
    +	} else {
    +		if (sc->ext_5ghz_lna) {
    +			run_bbp_write(sc, 82, 0xf2);
    +			run_bbp_write(sc, 75, 0x46);
    +		} else {
    +			run_bbp_write(sc, 82, 0xf2);
    +			run_bbp_write(sc, 75, 0x50);
    +		}
    +	}
    +
    +	run_read(sc, RT2860_TX_BAND_CFG, &tmp);
    +	tmp &= ~(RT2860_5G_BAND_SEL_N | RT2860_5G_BAND_SEL_P);
    +	tmp |= (group == 0) ? RT2860_5G_BAND_SEL_N : RT2860_5G_BAND_SEL_P;
    +	run_write(sc, RT2860_TX_BAND_CFG, tmp);
    +
    +	/* enable appropriate Power Amplifiers and Low Noise Amplifiers */
    +	tmp = RT2860_RFTR_EN | RT2860_TRSW_EN;
    +	if (group == 0) {	/* 2GHz */
    +		tmp |= RT2860_PA_PE_G0_EN | RT2860_LNA_PE_G0_EN;
    +		if (sc->ntxchains > 1)
    +			tmp |= RT2860_PA_PE_G1_EN;
    +		if (sc->nrxchains > 1)
    +			tmp |= RT2860_LNA_PE_G1_EN;
    +	} else {		/* 5GHz */
    +		tmp |= RT2860_PA_PE_A0_EN | RT2860_LNA_PE_A0_EN;
    +		if (sc->ntxchains > 1)
    +			tmp |= RT2860_PA_PE_A1_EN;
    +		if (sc->nrxchains > 1)
    +			tmp |= RT2860_LNA_PE_A1_EN;
    +	}
    +	run_write(sc, RT2860_TX_PIN_CFG, tmp);
    +
    +	/* set initial AGC value */
    +	if (group == 0)
    +		run_bbp_write(sc, 66, 0x2e + sc->lna[0]);
    +	else
    +		run_bbp_write(sc, 66, 0x32 + (sc->lna[group] * 5) / 3);
    +}
    +
    +static void
    +run_rt2870_set_chan(struct run_softc *sc, uint32_t chan)
    +{
    +	const struct rfprog *rfprog = rt2860_rf2850;
    +	uint32_t r2, r3, r4;
    +	int8_t txpow1, txpow2;
    +	int i;
    +
    +	/* find the settings for this channel (we know it exists) */
    +	for (i = 0; rfprog[i].chan != chan; i++);
    +
    +	r2 = rfprog[i].r2;
    +	if (sc->ntxchains == 1)
    +		r2 |= 1 << 12;		/* 1T: disable Tx chain 2 */
    +	if (sc->nrxchains == 1)
    +		r2 |= 1 << 15 | 1 << 4;	/* 1R: disable Rx chains 2 & 3 */
    +	else if (sc->nrxchains == 2)
    +		r2 |= 1 << 4;		/* 2R: disable Rx chain 3 */
    +
    +	/* use Tx power values from EEPROM */
    +	txpow1 = sc->txpow1[i];
    +	txpow2 = sc->txpow2[i];
    +	if (chan > 14) {
    +		if (txpow1 >= 0)
    +			txpow1 = txpow1 << 1;
    +		else
    +			txpow1 = (7 + txpow1) << 1 | 1;
    +		if (txpow2 >= 0)
    +			txpow2 = txpow2 << 1;
    +		else
    +			txpow2 = (7 + txpow2) << 1 | 1;
    +	}
    +	r3 = rfprog[i].r3 | txpow1 << 7;
    +	r4 = rfprog[i].r4 | sc->freq << 13 | txpow2 << 4;
    +
    +	run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1);
    +	run_rt2870_rf_write(sc, RT2860_RF2, r2);
    +	run_rt2870_rf_write(sc, RT2860_RF3, r3);
    +	run_rt2870_rf_write(sc, RT2860_RF4, r4);
    +
    +	run_delay(sc, 10);
    +
    +	run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1);
    +	run_rt2870_rf_write(sc, RT2860_RF2, r2);
    +	run_rt2870_rf_write(sc, RT2860_RF3, r3 | 1);
    +	run_rt2870_rf_write(sc, RT2860_RF4, r4);
    +
    +	run_delay(sc, 10);
    +
    +	run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1);
    +	run_rt2870_rf_write(sc, RT2860_RF2, r2);
    +	run_rt2870_rf_write(sc, RT2860_RF3, r3);
    +	run_rt2870_rf_write(sc, RT2860_RF4, r4);
    +}
    +
    +static void
    +run_rt3070_set_chan(struct run_softc *sc, uint32_t chan)
    +{
    +	int8_t txpow1, txpow2;
    +	uint8_t rf;
    +
    +	/* RT3070 is 2GHz only */
    +	KASSERT(chan >= 1 && chan <= 14, ("wrong channel selected\n"));
    +
    +	/* use Tx power values from EEPROM */
    +	txpow1 = sc->txpow1[chan - 1];
    +	txpow2 = sc->txpow2[chan - 1];
    +
    +	run_rt3070_rf_write(sc, 2, run_rf3020_freqs[chan - 1].n);
    +	run_rt3070_rf_write(sc, 3, run_rf3020_freqs[chan - 1].k);
    +	run_rt3070_rf_read(sc, 6, &rf);
    +	rf = (rf & ~0x03) | run_rf3020_freqs[chan - 1].r;
    +	run_rt3070_rf_write(sc, 6, rf);
    +
    +	/* set Tx0 power */
    +	run_rt3070_rf_read(sc, 12, &rf);
    +	rf = (rf & ~0x1f) | txpow1;
    +	run_rt3070_rf_write(sc, 12, rf);
    +
    +	/* set Tx1 power */
    +	run_rt3070_rf_read(sc, 13, &rf);
    +	rf = (rf & ~0x1f) | txpow2;
    +	run_rt3070_rf_write(sc, 13, rf);
    +
    +	run_rt3070_rf_read(sc, 1, &rf);
    +	rf &= ~0xfc;
    +	if (sc->ntxchains == 1)
    +		rf |= 1 << 7 | 1 << 5;	/* 1T: disable Tx chains 2 & 3 */
    +	else if (sc->ntxchains == 2)
    +		rf |= 1 << 7;		/* 2T: disable Tx chain 3 */
    +	if (sc->nrxchains == 1)
    +		rf |= 1 << 6 | 1 << 4;	/* 1R: disable Rx chains 2 & 3 */
    +	else if (sc->nrxchains == 2)
    +		rf |= 1 << 6;		/* 2R: disable Rx chain 3 */
    +	run_rt3070_rf_write(sc, 1, rf);
    +
    +	/* set RF offset */
    +	run_rt3070_rf_read(sc, 23, &rf);
    +	rf = (rf & ~0x7f) | sc->freq;
    +	run_rt3070_rf_write(sc, 23, rf);
    +
    +	/* program RF filter */
    +	run_rt3070_rf_write(sc, 24, sc->rf24_20mhz);
    +	run_rt3070_rf_write(sc, 31, sc->rf24_20mhz);
    +
    +	/* enable RF tuning */
    +	run_rt3070_rf_read(sc, 7, &rf);
    +	run_rt3070_rf_write(sc, 7, rf | 0x01);
    +}
    +
    +static void
    +run_set_rx_antenna(struct run_softc *sc, int aux)
    +{
    +	uint32_t tmp;
    +
    +	if (aux) {
    +		run_read(sc, RT2860_PCI_EECTRL, &tmp);
    +		run_write(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C);
    +		run_read(sc, RT2860_GPIO_CTRL, &tmp);
    +		run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08);
    +	} else {
    +		run_read(sc, RT2860_PCI_EECTRL, &tmp);
    +		run_write(sc, RT2860_PCI_EECTRL, tmp | RT2860_C);
    +		run_read(sc, RT2860_GPIO_CTRL, &tmp);
    +		run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808);
    +	}
    +}
    +
    +static int
    +run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
    +{
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	uint32_t chan, group;
    +
    +	chan = ieee80211_chan2ieee(ic, c);
    +	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
    +		return EINVAL;
    +
    +	if ((sc->mac_rev >> 16) >= 0x3070)
    +		run_rt3070_set_chan(sc, chan);
    +	else
    +		run_rt2870_set_chan(sc, chan);
    +
    +	/* 802.11a uses a 16 microseconds short interframe space */
    +	sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
    +
    +	/* determine channel group */
    +	if (chan <= 14)
    +		group = 0;
    +	else if (chan <= 64)
    +		group = 1;
    +	else if (chan <= 128)
    +		group = 2;
    +	else
    +		group = 3;
    +
    +	/* XXX necessary only when group has changed! */
    +	run_select_chan_group(sc, group);
    +
    +	run_delay(sc, 10);
    +
    +	return 0;
    +}
    +
    +static void
    +run_set_channel(struct ieee80211com *ic)
    +{
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +
    +	RUN_LOCK(sc);
    +	run_set_chan(sc, ic->ic_curchan);
    +	RUN_UNLOCK(sc);
    +
    +	return;
    +}
    +
    +static void
    +run_scan_start(struct ieee80211com *ic)
    +{
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +	uint32_t tmp;
    +
    +	RUN_LOCK(sc);
    +
    +	/* abort TSF synchronization */
    +	run_read(sc, RT2860_BCN_TIME_CFG, &tmp);
    +	run_write(sc, RT2860_BCN_TIME_CFG,
    +	    tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN |
    +	    RT2860_TBTT_TIMER_EN));
    +	run_set_bssid(sc, sc->sc_ifp->if_broadcastaddr);
    +
    +	RUN_UNLOCK(sc);
    +
    +	return;
    +}
    +
    +static void
    +run_scan_end(struct ieee80211com *ic)
    +{
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +
    +	RUN_LOCK(sc);
    +
    +	run_enable_tsf_sync(sc);
    +	/* XXX keep local copy */
    +	run_set_bssid(sc, sc->sc_bssid);
    +
    +	RUN_UNLOCK(sc);
    +
    +	return;
    +}
    +
    +static uint8_t
    +run_rate2mcs(uint8_t rate)
    +{
    +	switch (rate) {
    +	/* CCK rates */
    +	case 2:		return 0;
    +	case 4:		return 1;
    +	case 11:	return 2;
    +	case 22:	return 3;
    +	/* OFDM rates */
    +	case 12:	return 0;
    +	case 18:	return 1;
    +	case 24:	return 2;
    +	case 36:	return 3;
    +	case 48:	return 4;
    +	case 72:	return 5;
    +	case 96:	return 6;
    +	case 108:	return 7;
    +	}
    +	return 0;	/* shouldn't get here */
    +}
    +
    +static void
    +run_update_beacon_locked(struct ieee80211vap *vap, int item)
    +{
    +	struct ieee80211com *ic = vap->iv_ic;
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +	struct rt2860_txwi txwi;
    +	struct mbuf *m;
    +	int rate;
    +
    +	if ((m = ieee80211_beacon_alloc(vap->iv_bss, &RUN_VAP(vap)->bo)) == NULL)
    +	        return;
    +
    +	memset(&txwi, 0, sizeof txwi);
    +	txwi.wcid = 0xff;
    +	txwi.len = htole16(m->m_pkthdr.len);
    +	/* send beacons at the lowest available rate */
    +	rate = (ic->ic_curmode == IEEE80211_MODE_11A) ? 12 : 2;
    +	txwi.phy = htole16(run_rate2mcs(rate));
    +	if (rate == 12)
    +	        txwi.phy |= htole16(RT2860_PHY_OFDM);
    +	txwi.txop = RT2860_TX_TXOP_HT;
    +	txwi.flags = RT2860_TX_TS;
    +
    +	run_write_region_1(sc, RT2860_BCN_BASE(0),
    +	    (u_int8_t *)&txwi, sizeof txwi);
    +	run_write_region_1(sc, RT2860_BCN_BASE(0) + sizeof txwi,
    +	    mtod(m, uint8_t *), (m->m_pkthdr.len + 1) & ~1);	/* roundup len */
    +
    +	m_freem(m);
    +
    +	return;
    +}
    +
    +static void
    +run_update_beacon(struct ieee80211vap *vap, int item)
    +{
    +	struct ieee80211com *ic = vap->iv_ic;
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +
    +	IEEE80211_UNLOCK(ic);
    +	RUN_LOCK(sc);
    +	run_update_beacon_locked(vap, item);
    +	RUN_UNLOCK(sc);
    +	IEEE80211_LOCK(ic);
    +
    +	return;
    +}
    +
    +static void
    +run_updateprot(struct ieee80211com *ic)
    +{
    +	struct run_softc *sc = ic->ic_ifp->if_softc;
    +	uint32_t tmp;
    +
    +	tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
    +	/* setup protection frame rate (MCS code) */
    +	tmp |= (ic->ic_curmode == IEEE80211_MODE_11A) ?
    +	    rt2860_rates[RT2860_RIDX_OFDM6].mcs :
    +	    rt2860_rates[RT2860_RIDX_CCK11].mcs;
    +
    +	/* CCK frames don't require protection */
    +	run_write(sc, RT2860_CCK_PROT_CFG, tmp);
    +	if (ic->ic_flags & IEEE80211_F_USEPROT) {
    +		if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
    +			tmp |= RT2860_PROT_CTRL_RTS_CTS;
    +		else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
    +			tmp |= RT2860_PROT_CTRL_CTS;
    +	}
    +	run_write(sc, RT2860_OFDM_PROT_CFG, tmp);
    +}
    +
    +static void
    +run_usb_timeout_cb(void *arg, int pending)
    +{
    +	struct run_softc *sc = arg;
    +	struct ieee80211vap *vap = &sc->sc_rvp->vap;
    +
    +	RUN_LOCK_ASSERT(sc, MA_OWNED);
    +
    +	if(vap->iv_state == IEEE80211_S_RUN &&
    +	    vap->iv_opmode != IEEE80211_M_STA)
    +		run_reset_livelock(sc);
    +	else if(vap->iv_state == IEEE80211_S_SCAN){
    +		DPRINTF("timeout caused by scan\n");
    +		/* cancel bgscan */
    +		ieee80211_cancel_scan(vap);
    +	} else
    +		DPRINTF("timeout by unknown cause\n");
    +}
    +
    +static void
    +run_reset_livelock(struct run_softc *sc)
    +{
    +	uint32_t tmp;
    +
    +	/*
    +	 * In IBSS or HostAP modes (when the hardware sends beacons), the MAC
    +	 * can run into a livelock and start sending CTS-to-self frames like
    +	 * crazy if protection is enabled.  Reset MAC/BBP for a while
    +	 */
    +	run_read(sc, RT2860_DEBUG, &tmp);
    +	if((tmp & (1 << 29)) && (tmp & (1 << 7 | 1 << 5))){
    +		DPRINTF("CTS-to-self livelock detected\n");
    +		run_write(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_SRST);
    +		run_delay(sc, 1);
    +		run_write(sc, RT2860_MAC_SYS_CTRL,
    +		    RT2860_MAC_RX_EN | RT2860_MAC_TX_EN);
    +	}
    +}
    +
    +static void
    +run_update_promisc_locked(struct ifnet *ifp)
    +{
    +	struct run_softc *sc = ifp->if_softc;
    +        uint32_t tmp;
    +
    +	run_read(sc, RT2860_RX_FILTR_CFG, &tmp);
    +
    +	tmp |= RT2860_DROP_UC_NOME;
    +        if (ifp->if_flags & IFF_PROMISC)
    +		tmp &= ~RT2860_DROP_UC_NOME;
    +
    +	run_write(sc, RT2860_RX_FILTR_CFG, tmp);
    +
    +        DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
    +            "entering" : "leaving");
    +}
    +
    +static void
    +run_update_promisc(struct ifnet *ifp)
    +{
    +	struct run_softc *sc = ifp->if_softc;
    +
    +	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
    +		return;
    +
    +	RUN_LOCK(sc);
    +	run_update_promisc_locked(ifp);
    +	RUN_UNLOCK(sc);
    +}
    +
    +static void
    +run_enable_tsf_sync(struct run_softc *sc)
    +{
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
    +	uint32_t tmp;
    +
    +	run_read(sc, RT2860_BCN_TIME_CFG, &tmp);
    +	tmp &= ~0x1fffff;
    +	tmp |= vap->iv_bss->ni_intval * 16;
    +	tmp |= RT2860_TSF_TIMER_EN | RT2860_TBTT_TIMER_EN;
    +
    +	if (vap->iv_opmode == IEEE80211_M_STA) {
    +		/*
    +		 * Local TSF is always updated with remote TSF on beacon
    +		 * reception.
    +		 */
    +		tmp |= 1 << RT2860_TSF_SYNC_MODE_SHIFT;
    +	} else if (vap->iv_opmode == IEEE80211_M_IBSS) {
    +	        tmp |= RT2860_BCN_TX_EN;
    +	        /*
    +	         * Local TSF is updated with remote TSF on beacon reception
    +	         * only if the remote TSF is greater than local TSF.
    +	         */
    +	        tmp |= 2 << RT2860_TSF_SYNC_MODE_SHIFT;
    +	} else if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
    +	        tmp |= RT2860_BCN_TX_EN;
    +	        /* SYNC with nobody */
    +	        tmp |= 3 << RT2860_TSF_SYNC_MODE_SHIFT;
    +	} else
    +		DPRINTF("Enabling TSF failed. undefined opmode\n");
    +
    +	run_write(sc, RT2860_BCN_TIME_CFG, tmp);
    +}
    +
    +static void
    +run_enable_mrr(struct run_softc *sc)
    +{
    +#define CCK(mcs)	(mcs)
    +#define OFDM(mcs)	(1 << 3 | (mcs))
    +	run_write(sc, RT2860_LG_FBK_CFG0,
    +	    OFDM(6) << 28 |	/* 54->48 */
    +	    OFDM(5) << 24 |	/* 48->36 */
    +	    OFDM(4) << 20 |	/* 36->24 */
    +	    OFDM(3) << 16 |	/* 24->18 */
    +	    OFDM(2) << 12 |	/* 18->12 */
    +	    OFDM(1) <<  8 |	/* 12-> 9 */
    +	    OFDM(0) <<  4 |	/*  9-> 6 */
    +	    OFDM(0));		/*  6-> 6 */
    +
    +	run_write(sc, RT2860_LG_FBK_CFG1,
    +	    CCK(2) << 12 |	/* 11->5.5 */
    +	    CCK(1) <<  8 |	/* 5.5-> 2 */
    +	    CCK(0) <<  4 |	/*   2-> 1 */
    +	    CCK(0));		/*   1-> 1 */
    +#undef OFDM
    +#undef CCK
    +}
    +
    +static void
    +run_set_txpreamble(struct run_softc *sc)
    +{
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	uint32_t tmp;
    +
    +	run_read(sc, RT2860_AUTO_RSP_CFG, &tmp);
    +	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
    +		tmp |= RT2860_CCK_SHORT_EN;
    +	else
    +		tmp &= ~RT2860_CCK_SHORT_EN;
    +	run_write(sc, RT2860_AUTO_RSP_CFG, tmp);
    +}
    +
    +static void
    +run_set_basicrates(struct run_softc *sc)
    +{
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +
    +	/* set basic rates mask */
    +	if (ic->ic_curmode == IEEE80211_MODE_11B)
    +		run_write(sc, RT2860_LEGACY_BASIC_RATE, 0x003);
    +	else if (ic->ic_curmode == IEEE80211_MODE_11A)
    +		run_write(sc, RT2860_LEGACY_BASIC_RATE, 0x150);
    +	else	/* 11g */
    +		run_write(sc, RT2860_LEGACY_BASIC_RATE, 0x15f);
    +}
    +
    +static void
    +run_set_leds(struct run_softc *sc, uint16_t which)
    +{
    +	(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LEDS,
    +	    which | (sc->leds & 0x7f));
    +}
    +
    +static void
    +run_set_bssid(struct run_softc *sc, const uint8_t *bssid)
    +{
    +	run_write(sc, RT2860_MAC_BSSID_DW0,
    +	    bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24);
    +	run_write(sc, RT2860_MAC_BSSID_DW1,
    +	    bssid[4] | bssid[5] << 8);
    +}
    +
    +static void
    +run_set_macaddr(struct run_softc *sc, const uint8_t *addr)
    +{
    +	run_write(sc, RT2860_MAC_ADDR_DW0,
    +	    addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
    +	run_write(sc, RT2860_MAC_ADDR_DW1,
    +	    addr[4] | addr[5] << 8 | 0xff << 16);
    +}
    +
    +/* ARGSUSED */
    +static void
    +run_updateslot(struct ifnet *ifp)
    +{
    +	struct run_softc *sc = ifp->if_softc;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	uint32_t tmp;
    +
    +	run_read(sc, RT2860_BKOFF_SLOT_CFG, &tmp);
    +	tmp &= ~0xff;
    +	tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
    +	run_write(sc, RT2860_BKOFF_SLOT_CFG, tmp);
    +}
    +
    +static int8_t
    +run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain)
    +{
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	struct ieee80211_channel *c = ic->ic_curchan;
    +	int delta;
    +
    +	if (IEEE80211_IS_CHAN_5GHZ(c)) {
    +		uint32_t chan = ieee80211_chan2ieee(ic, c);
    +		delta = sc->rssi_5ghz[rxchain];
    +
    +		/* determine channel group */
    +		if (chan <= 64)
    +			delta -= sc->lna[1];
    +		else if (chan <= 128)
    +			delta -= sc->lna[2];
    +		else
    +			delta -= sc->lna[3];
    +	} else
    +		delta = sc->rssi_2ghz[rxchain] - sc->lna[0];
    +
    +	return -12 - delta - rssi;
    +}
    +
    +static int
    +run_bbp_init(struct run_softc *sc)
    +{
    +	int i, error, ntries;
    +	uint8_t bbp0;
    +
    +	/* wait for BBP to wake up */
    +	for (ntries = 0; ntries < 20; ntries++) {
    +		if ((error = run_bbp_read(sc, 0, &bbp0)) != 0)
    +			return error;
    +		if (bbp0 != 0 && bbp0 != 0xff)
    +			break;
    +	}
    +	if (ntries == 20)
    +		return ETIMEDOUT;
    +
    +	/* initialize BBP registers to default values */
    +	for (i = 0; i < nitems(rt2860_def_bbp); i++) {
    +		run_bbp_write(sc, rt2860_def_bbp[i].reg,
    +		    rt2860_def_bbp[i].val);
    +	}
    +
    +	/* fix BBP84 for RT2860E */
    +	if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101)
    +		run_bbp_write(sc,  84, 0x19);
    +
    +	if ((sc->mac_rev >> 16) >= 0x3070) {
    +		run_bbp_write(sc, 79, 0x13);
    +		run_bbp_write(sc, 80, 0x05);
    +		run_bbp_write(sc, 81, 0x33);
    +		/* XXX RT3090 needs more */
    +	} else if (sc->mac_rev == 0x28600100) {
    +		run_bbp_write(sc, 69, 0x16);
    +		run_bbp_write(sc, 73, 0x12);
    +	}
    +	return 0;
    +}
    +
    +static int
    +run_rt3070_rf_init(struct run_softc *sc)
    +{
    +	uint32_t tmp;
    +	uint8_t rf, bbp4;
    +	int i;
    +
    +	run_rt3070_rf_read(sc, 30, &rf);
    +	/* toggle RF R30 bit 7 */
    +	run_rt3070_rf_write(sc, 30, rf | 0x80);
    +	run_delay(sc, 10);
    +	run_rt3070_rf_write(sc, 30, rf & ~0x80);
    +
    +	/* initialize RF registers to default value */
    +	for (i = 0; i < nitems(rt3070_def_rf); i++) {
    +		run_rt3070_rf_write(sc, rt3070_def_rf[i].reg,
    +		    rt3070_def_rf[i].val);
    +	}
    +	if ((sc->mac_rev >> 16) == 0x3070) {
    +		/* change voltage from 1.2V to 1.35V for RT3070 */
    +		run_read(sc, RT3070_LDO_CFG0, &tmp);
    +		tmp = (tmp & ~0x0f000000) | 0x0d000000;
    +		run_write(sc, RT3070_LDO_CFG0, tmp);
    +
    +	} else if ((sc->mac_rev >> 16) == 0x3071) {
    +		run_rt3070_rf_read(sc, 6, &rf);
    +		run_rt3070_rf_write(sc, 6, rf | 0x40);
    +		run_rt3070_rf_write(sc, 31, 0x14);
    +
    +		run_read(sc, RT3070_LDO_CFG0, &tmp);
    +		tmp &= ~0x1f000000;
    +		if ((sc->mac_rev & 0xffff) < 0x0211)
    +			tmp |= 0x0d000000;
    +		else
    +			tmp |= 0x01000000;
    +		run_write(sc, RT3070_LDO_CFG0, tmp);
    +
    +		/* patch LNA_PE_G1 */
    +		run_read(sc, RT3070_GPIO_SWITCH, &tmp);
    +		run_write(sc, RT3070_GPIO_SWITCH, tmp & ~0x20);
    +	} else if((sc->mac_rev >> 16) == 0x3572){
    +		if ((sc->mac_rev & 0xffff) < 0x0211){
    +			run_read(sc, RT3070_LDO_CFG0, &tmp);
    +			tmp = (tmp & ~0x0f000000) | 0x0d000000;
    +			run_write(sc, RT3070_LDO_CFG0, tmp);
    +		} else {
    +			run_read(sc, RT3070_LDO_CFG0, &tmp);
    +			tmp = (tmp & ~0x1f000000) | 0x0d000000;
    +			run_write(sc, RT3070_LDO_CFG0, tmp);
    +
    +			run_delay(sc, 1);	/* wait for 1msec */
    +
    +			tmp = (tmp & ~0x1f000000) | 0x01000000;
    +			run_write(sc, RT3070_LDO_CFG0, tmp);
    +		}
    +	}
    +
    +	/* select 20MHz bandwidth */
    +	run_rt3070_rf_read(sc, 31, &rf);
    +	run_rt3070_rf_write(sc, 31, rf & ~0x20);
    +
    +	/* calibrate filter for 20MHz bandwidth */
    +	sc->rf24_20mhz = 0x1f;	/* default value */
    +	run_rt3070_filter_calib(sc, 0x07, 0x16, &sc->rf24_20mhz);
    +
    +	/* select 40MHz bandwidth */
    +	run_bbp_read(sc, 4, &bbp4);
    +	run_bbp_write(sc, 4, (bbp4 & ~0x08) | 0x10);
    +
    +	/* calibrate filter for 40MHz bandwidth */
    +	sc->rf24_40mhz = 0x2f;	/* default value */
    +	run_rt3070_filter_calib(sc, 0x27, 0x19, &sc->rf24_40mhz);
    +
    +	/* go back to 20MHz bandwidth */
    +	run_bbp_read(sc, 4, &bbp4);
    +	run_bbp_write(sc, 4, bbp4 & ~0x18);
    +
    +	if ((sc->mac_rev & 0xffff) < 0x0211)
    +		run_rt3070_rf_write(sc, 27, 0x03);
    +
    +	run_read(sc, RT3070_OPT_14, &tmp);
    +	run_write(sc, RT3070_OPT_14, tmp | 1);
    +
    +	if ((sc->mac_rev >> 16) == 0x3071) {
    +		run_rt3070_rf_read(sc, 1, &rf);
    +		rf &= ~(RT3070_RX0_PD | RT3070_TX0_PD);
    +		rf |= RT3070_RF_BLOCK | RT3070_RX1_PD | RT3070_TX1_PD;
    +		run_rt3070_rf_write(sc, 1, rf);
    +
    +		run_rt3070_rf_read(sc, 15, &rf);
    +		run_rt3070_rf_write(sc, 15, rf & ~RT3070_TX_LO2);
    +
    +		run_rt3070_rf_read(sc, 17, &rf);
    +		rf &= ~RT3070_TX_LO1;
    +		if ((sc->mac_rev & 0xffff) >= 0x0211 && !sc->ext_2ghz_lna)
    +			rf |= 0x20;	/* fix for long range Rx issue */
    +		run_rt3070_rf_write(sc, 17, rf);
    +
    +		run_rt3070_rf_read(sc, 20, &rf);
    +		run_rt3070_rf_write(sc, 20, rf & ~RT3070_RX_LO1);
    +
    +		run_rt3070_rf_read(sc, 21, &rf);
    +		run_rt3070_rf_write(sc, 21, rf & ~RT3070_RX_LO2);
    +
    +		run_rt3070_rf_read(sc, 27, &rf);
    +		rf &= ~0x77;
    +		if ((sc->mac_rev & 0xffff) < 0x0211)
    +			rf |= 0x03;
    +		run_rt3070_rf_write(sc, 27, rf);
    +	}
    +	return 0;
    +}
    +
    +static int
    +run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
    +    uint8_t *val)
    +{
    +	uint8_t rf22, rf24;
    +	uint8_t bbp55_pb, bbp55_sb, delta;
    +	int ntries;
    +
    +	/* program filter */
    +	rf24 = init;	/* initial filter value */
    +	run_rt3070_rf_write(sc, 24, rf24);
    +
    +	/* enable baseband loopback mode */
    +	run_rt3070_rf_read(sc, 22, &rf22);
    +	run_rt3070_rf_write(sc, 22, rf22 | 0x01);
    +
    +	/* set power and frequency of passband test tone */
    +	run_bbp_write(sc, 24, 0x00);
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		/* transmit test tone */
    +		run_bbp_write(sc, 25, 0x90);
    +		run_delay(sc, 10);
    +		/* read received power */
    +		run_bbp_read(sc, 55, &bbp55_pb);
    +		if (bbp55_pb != 0)
    +			break;
    +	}
    +	if (ntries == 100)
    +		return ETIMEDOUT;
    +
    +	/* set power and frequency of stopband test tone */
    +	run_bbp_write(sc, 24, 0x06);
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		/* transmit test tone */
    +		run_bbp_write(sc, 25, 0x90);
    +		run_delay(sc, 10);
    +		/* read received power */
    +		run_bbp_read(sc, 55, &bbp55_sb);
    +
    +		delta = bbp55_pb - bbp55_sb;
    +		if (delta > target)
    +			break;
    +
    +		/* reprogram filter */
    +		rf24++;
    +		run_rt3070_rf_write(sc, 24, rf24);
    +	}
    +	if (ntries < 100) {
    +		if (rf24 != init)
    +			rf24--;	/* backtrack */
    +		*val = rf24;
    +		run_rt3070_rf_write(sc, 24, rf24);
    +	}
    +
    +	/* restore initial state */
    +	run_bbp_write(sc, 24, 0x00);
    +
    +	/* disable baseband loopback mode */
    +	run_rt3070_rf_read(sc, 22, &rf22);
    +	run_rt3070_rf_write(sc, 22, rf22 & ~0x01);
    +
    +	return 0;
    +}
    +
    +static int
    +run_txrx_enable(struct run_softc *sc)
    +{
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	uint32_t tmp;
    +	int error, ntries;
    +
    +	run_write(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_TX_EN);
    +	for (ntries = 0; ntries < 200; ntries++) {
    +		if ((error = run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp)) != 0)
    +			return error;
    +		if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
    +			break;
    +		run_delay(sc, 50);
    +	}
    +	if (ntries == 200)
    +		return ETIMEDOUT;
    +
    +	run_delay(sc, 50);
    +
    +	tmp |= RT2860_RX_DMA_EN | RT2860_TX_DMA_EN | RT2860_TX_WB_DDONE;
    +	run_write(sc, RT2860_WPDMA_GLO_CFG, tmp);
    +
    +	/* enable Rx bulk aggregation (set timeout and limit) */
    +	tmp = RT2860_USB_TX_EN | RT2860_USB_RX_EN | RT2860_USB_RX_AGG_EN |
    +	    RT2860_USB_RX_AGG_TO(128) | RT2860_USB_RX_AGG_LMT(2);
    +	run_write(sc, RT2860_USB_DMA_CFG, tmp);
    +
    +	/* set Rx filter */
    +	tmp = RT2860_DROP_CRC_ERR | RT2860_DROP_PHY_ERR;
    +	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
    +		tmp |= RT2860_DROP_UC_NOME | RT2860_DROP_DUPL |
    +		    RT2860_DROP_CTS | RT2860_DROP_BA | RT2860_DROP_ACK |
    +		    RT2860_DROP_VER_ERR | RT2860_DROP_CTRL_RSV |
    +		    RT2860_DROP_CFACK | RT2860_DROP_CFEND;
    +		if (ic->ic_opmode == IEEE80211_M_STA)
    +			tmp |= RT2860_DROP_RTS | RT2860_DROP_PSPOLL;
    +	}
    +	run_write(sc, RT2860_RX_FILTR_CFG, tmp);
    +
    +	run_write(sc, RT2860_MAC_SYS_CTRL,
    +	    RT2860_MAC_RX_EN | RT2860_MAC_TX_EN);
    +
    +	return 0;
    +}
    +
    +static void
    +run_init_locked(struct run_softc *sc)
    +{
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	struct ieee80211vap *vap = &sc->sc_rvp->vap;
    +	uint32_t tmp;
    +	uint8_t bbp1, bbp3;
    +	int i;
    +	int ridx;
    +	int ntries;
    +
    +	run_stop(sc);
    +
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		if (run_read(sc, RT2860_ASIC_VER_ID, &tmp) != 0)
    +			goto fail;
    +		if (tmp != 0 && tmp != 0xffffffff)
    +			break;
    +		run_delay(sc, 10);
    +	}
    +	if (ntries == 100)
    +		goto fail;
    +
    +	for (i = 0; i != RUN_EP_QUEUES; i++)
    +		run_setup_tx_list(sc, &sc->sc_epq[i]);
    +
    +	run_set_macaddr(sc, IF_LLADDR(ifp));
    +
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0)
    +			goto fail;
    +		if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
    +			break;
    +		run_delay(sc, 10);
    +	}
    +	if (ntries == 100) {
    +		printf("%s: timeout waiting for DMA engine\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		goto fail;
    +	}
    +	tmp &= 0xff0;
    +	tmp |= RT2860_TX_WB_DDONE;
    +	run_write(sc, RT2860_WPDMA_GLO_CFG, tmp);
    +
    +	/* turn off PME_OEN to solve high-current issue */
    +	run_read(sc, RT2860_SYS_CTRL, &tmp);
    +	run_write(sc, RT2860_SYS_CTRL, tmp & ~RT2860_PME_OEN);
    +
    +	run_write(sc, RT2860_MAC_SYS_CTRL,
    +	    RT2860_BBP_HRST | RT2860_MAC_SRST);
    +	run_write(sc, RT2860_USB_DMA_CFG, 0);
    +
    +	if (run_reset(sc) != 0) {
    +		printf("%s: could not reset chipset\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		goto fail;
    +	}
    +
    +	run_write(sc, RT2860_MAC_SYS_CTRL, 0);
    +
    +	/* init Tx power for all Tx rates (from EEPROM) */
    +	for (ridx = 0; ridx < 5; ridx++) {
    +		if (sc->txpow20mhz[ridx] == 0xffffffff)
    +			continue;
    +		run_write(sc, RT2860_TX_PWR_CFG(ridx), sc->txpow20mhz[ridx]);
    +	}
    +
    +	for (i = 0; i < nitems(rt2870_def_mac); i++)
    +		run_write(sc, rt2870_def_mac[i].reg, rt2870_def_mac[i].val);
    +	run_write(sc, RT2860_WMM_AIFSN_CFG, 0x00002273);
    +	run_write(sc, RT2860_WMM_CWMIN_CFG, 0x00002344);
    +	run_write(sc, RT2860_WMM_CWMAX_CFG, 0x000034aa);
    +
    +	if ((sc->mac_rev >> 16) >= 0x3070) {
    +		/* set delay of PA_PE assertion to 1us (unit of 0.25us) */
    +		run_write(sc, RT2860_TX_SW_CFG0,
    +		    4 << RT2860_DLY_PAPE_EN_SHIFT);
    +		run_write(sc, RT2860_TX_SW_CFG1, 0);
    +		run_write(sc, RT2860_TX_SW_CFG2, 0x1f);
    +	}
    +
    +	/* wait while MAC is busy */
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		if (run_read(sc, RT2860_MAC_STATUS_REG, &tmp) != 0)
    +			goto fail;
    +		if (!(tmp & (RT2860_RX_STATUS_BUSY | RT2860_TX_STATUS_BUSY)))
    +			break;
    +		run_delay(sc, 10);
    +	}
    +	if (ntries == 100)
    +		goto fail;
    +
    +	/* clear Host to MCU mailbox */
    +	run_write(sc, RT2860_H2M_BBPAGENT, 0);
    +	run_write(sc, RT2860_H2M_MAILBOX, 0);
    +	run_delay(sc, 10);
    +
    +	if (run_bbp_init(sc) != 0) {
    +		printf("%s: could not initialize BBP\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		goto fail;
    +	}
    +
    +	/* abort TSF synchronization */
    +	run_read(sc, RT2860_BCN_TIME_CFG, &tmp);
    +	tmp &= ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN |
    +	    RT2860_TBTT_TIMER_EN);
    +	run_write(sc, RT2860_BCN_TIME_CFG, tmp);
    +
    +	/* clear RX WCID search table */
    +	run_set_region_4(sc, RT2860_WCID_ENTRY(0), 0, 512);
    +	/* clear WCID attribute table */
    +	run_set_region_4(sc, RT2860_WCID_ATTR(0), 0, 8 * 32);
    +	/* clear shared key table */
    +	run_set_region_4(sc, RT2860_SKEY(0, 0), 0, 8 * 32);
    +	/* clear shared key mode */
    +	run_set_region_4(sc, RT2860_SKEY_MODE_0_7, 0, 4);
    +
    +	run_read(sc, RT2860_US_CYC_CNT, &tmp);
    +	tmp = (tmp & ~0xff) | 0x1e;
    +	run_write(sc, RT2860_US_CYC_CNT, tmp);
    +
    +	if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101)
    +		run_write(sc, RT2860_TXOP_CTRL_CFG, 0x0000583f);
    +
    +	run_write(sc, RT2860_WMM_TXOP0_CFG, 0);
    +	run_write(sc, RT2860_WMM_TXOP1_CFG, 48 << 16 | 96);
    +
    +	/* write vendor-specific BBP values (from EEPROM) */
    +	for (i = 0; i < 8; i++) {
    +		if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff)
    +			continue;
    +		run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val);
    +	}
    +
    +	/* select Main antenna for 1T1R devices */
    +	if (sc->rf_rev == RT3070_RF_3020)
    +		run_set_rx_antenna(sc, 0);
    +
    +	/* send LEDs operating mode to microcontroller */
    +	(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED1, sc->led[0]);
    +	(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1]);
    +	(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2]);
    +
    +	/* disable non-existing Rx chains */
    +	run_bbp_read(sc, 3, &bbp3);
    +	bbp3 &= ~(1 << 3 | 1 << 4);
    +	if (sc->nrxchains == 2)
    +		bbp3 |= 1 << 3;
    +	else if (sc->nrxchains == 3)
    +		bbp3 |= 1 << 4;
    +	run_bbp_write(sc, 3, bbp3);
    +
    +	/* disable non-existing Tx chains */
    +	run_bbp_read(sc, 1, &bbp1);
    +	if (sc->ntxchains == 1)
    +		bbp1 &= ~(1 << 3 | 1 << 4);
    +	run_bbp_write(sc, 1, bbp1);
    +
    +	if ((sc->mac_rev >> 16) >= 0x3070)
    +		run_rt3070_rf_init(sc);
    +
    +	/* select default channel */
    +	vap->iv_bss->ni_chan = ic->ic_curchan;	/* ic_bsschan?? */
    +	run_set_chan(sc, ic->ic_curchan);
    +
    +	/* setup initial protection mode */
    +	run_updateprot(ic);
    +
    +	/* turn radio LED on */
    +	run_set_leds(sc, RT2860_LED_RADIO);
    +
    +	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
    +	ifp->if_drv_flags |= IFF_DRV_RUNNING;
    +
    +	for(i = 0; i != RUN_N_XFER; i++)
    +		usbd_xfer_set_stall(sc->sc_xfer[i]);
    +
    +	usbd_transfer_start(sc->sc_xfer[RUN_BULK_RX]);
    +
    +	if (run_txrx_enable(sc) != 0)
    +		goto fail;
    +
    +	return;
    +
    +fail:
    +	run_stop(sc);
    +}
    +
    +static void
    +run_init(void *arg)
    +{
    +	struct run_softc *sc = arg;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +
    +	RUN_LOCK(sc);
    +	run_init_locked(sc);
    +	RUN_UNLOCK(sc);
    +
    +	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
    +	        ieee80211_start_all(ic);
    +}
    +
    +static void
    +run_stop(void *arg)
    +{
    +	struct run_softc *sc = (struct run_softc *)arg;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	uint32_t tmp;
    +	int i;
    +	int ntries;
    +
    +	RUN_LOCK_ASSERT(sc, MA_OWNED);
    +
    +	if (ic->ic_flags & IEEE80211_F_SCAN)
    +		ieee80211_cancel_scan(&sc->sc_rvp->vap);
    +
    +	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
    +		run_set_leds(sc, 0);	/* turn all LEDs off */
    +
    +	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
    +
    +	sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
    +
    +	RUN_UNLOCK(sc);
    +
    +	/* drain them all */
    +	usb_callout_drain(&sc->sc_rvp->amrr_ch);
    +	ieee80211_draintask(ic, &sc->sc_rvp->amrr_task);
    +	ieee80211_draintask(ic, &sc->wme_task);
    +	for(i = 0; i < RUN_N_XFER; i++)
    +		usbd_transfer_drain(sc->sc_xfer[i]);
    +	ieee80211_draintask(ic, &sc->usb_timeout_task);
    +
    +	RUN_LOCK(sc);
    +
    +	if(sc->rx_m != NULL){
    +		m_free(sc->rx_m);
    +		sc->rx_m = NULL;
    +	}
    +
    +	/* disable Tx/Rx */
    +	run_read(sc, RT2860_MAC_SYS_CTRL, &tmp);
    +	tmp &= ~(RT2860_MAC_RX_EN | RT2860_MAC_TX_EN);
    +	run_write(sc, RT2860_MAC_SYS_CTRL, tmp);
    +
    +	/* wait for pending Tx to complete */
    +	for (ntries = 0; ntries < 100; ntries++) {
    +		if (run_read(sc, RT2860_TXRXQ_PCNT, &tmp) != 0){
    +			DPRINTF("Cannot read Tx queue count\n");
    +			break;
    +		}
    +		if ((tmp & RT2860_TX2Q_PCNT_MASK) == 0){
    +			DPRINTF("All Tx cleared\n");
    +			break;
    +		}
    +		run_delay(sc, 10);
    +	}
    +	if(ntries >= 100)
    +		DPRINTF("There are still pending Tx\n");
    +	run_delay(sc, 10);
    +	run_write(sc, RT2860_USB_DMA_CFG, 0);
    +
    +	run_write(sc, RT2860_MAC_SYS_CTRL, RT2860_BBP_HRST | RT2860_MAC_SRST);
    +	run_write(sc, RT2860_MAC_SYS_CTRL, 0);
    +
    +	for (i = 0; i != RUN_EP_QUEUES; i++)
    +		run_unsetup_tx_list(sc, &sc->sc_epq[i]);
    +
    +	return;
    +}
    +
    +static void
    +run_delay(struct run_softc *sc, unsigned int ms)
    +{
    +	usb_pause_mtx(mtx_owned(&sc->sc_mtx) ? 
    +	    &sc->sc_mtx : NULL, USB_MS_TO_TICKS(ms));
    +}
    +
    +static device_method_t run_methods[] = {
    +	/* Device interface */
    +	DEVMETHOD(device_probe,		run_match),
    +	DEVMETHOD(device_attach,	run_attach),
    +	DEVMETHOD(device_detach,	run_detach),
    +
    +	{ 0, 0 }
    +};
    +
    +static driver_t run_driver = {
    +	"run",
    +	run_methods,
    +	sizeof(struct run_softc)
    +};
    +
    +static devclass_t run_devclass;
    +
    +DRIVER_MODULE(run, uhub, run_driver, run_devclass, NULL, 0);
    diff --git a/sys/dev/usb/wlan/if_runreg.h b/sys/dev/usb/wlan/if_runreg.h
    new file mode 100644
    index 00000000000..f630fb10e67
    --- /dev/null
    +++ b/sys/dev/usb/wlan/if_runreg.h
    @@ -0,0 +1,1130 @@
    +/*	$OpenBSD: rt2860reg.h,v 1.19 2009/05/18 19:25:07 damien Exp $	*/
    +
    +/*-
    + * Copyright (c) 2007
    + *	Damien Bergamini 
    + *
    + * Permission to use, copy, modify, and 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 _IF_RUNREG_H_
    +#define	_IF_RUNREG_H_
    +
    +/* PCI registers */
    +#define RT2860_PCI_CFG			0x0000
    +#define RT2860_PCI_EECTRL		0x0004
    +#define RT2860_PCI_MCUCTRL		0x0008
    +#define RT2860_PCI_SYSCTRL		0x000c
    +#define RT2860_PCIE_JTAG		0x0010
    +
    +#define RT2860_CONFIG_NO		1
    +#define RT2860_IFACE_INDEX		0
    +
    +#define RT3070_OPT_14			0x0114
    +
    +/* SCH/DMA registers */
    +#define RT2860_INT_STATUS		0x0200
    +#define RT2860_INT_MASK			0x0204
    +#define RT2860_WPDMA_GLO_CFG		0x0208
    +#define RT2860_WPDMA_RST_IDX		0x020c
    +#define RT2860_DELAY_INT_CFG		0x0210
    +#define RT2860_WMM_AIFSN_CFG		0x0214
    +#define RT2860_WMM_CWMIN_CFG		0x0218
    +#define RT2860_WMM_CWMAX_CFG		0x021c
    +#define RT2860_WMM_TXOP0_CFG		0x0220
    +#define RT2860_WMM_TXOP1_CFG		0x0224
    +#define RT2860_GPIO_CTRL		0x0228
    +#define RT2860_MCU_CMD_REG		0x022c
    +#define RT2860_TX_BASE_PTR(qid)		(0x0230 + (qid) * 16)
    +#define RT2860_TX_MAX_CNT(qid)		(0x0234 + (qid) * 16)
    +#define RT2860_TX_CTX_IDX(qid)		(0x0238 + (qid) * 16)
    +#define RT2860_TX_DTX_IDX(qid)		(0x023c + (qid) * 16)
    +#define RT2860_RX_BASE_PTR		0x0290
    +#define RT2860_RX_MAX_CNT		0x0294
    +#define RT2860_RX_CALC_IDX		0x0298
    +#define RT2860_FS_DRX_IDX		0x029c
    +#define RT2860_USB_DMA_CFG		0x02a0	/* RT2870 only */
    +#define RT2860_US_CYC_CNT		0x02a4
    +
    +/* PBF registers */
    +#define RT2860_SYS_CTRL			0x0400
    +#define RT2860_HOST_CMD			0x0404
    +#define RT2860_PBF_CFG			0x0408
    +#define RT2860_MAX_PCNT			0x040c
    +#define RT2860_BUF_CTRL			0x0410
    +#define RT2860_MCU_INT_STA		0x0414
    +#define RT2860_MCU_INT_ENA		0x0418
    +#define RT2860_TXQ_IO(qid)		(0x041c + (qid) * 4)
    +#define RT2860_RX0Q_IO			0x0424
    +#define RT2860_BCN_OFFSET0		0x042c
    +#define RT2860_BCN_OFFSET1		0x0430
    +#define RT2860_TXRXQ_STA		0x0434
    +#define RT2860_TXRXQ_PCNT		0x0438
    +#define RT2860_PBF_DBG			0x043c
    +#define RT2860_CAP_CTRL			0x0440
    +
    +/* RT3070 registers */
    +#define RT3070_RF_CSR_CFG		0x0500
    +#define RT3070_EFUSE_CTRL		0x0580
    +#define RT3070_EFUSE_DATA0		0x0590
    +#define RT3070_EFUSE_DATA1		0x0594
    +#define RT3070_EFUSE_DATA2		0x0598
    +#define RT3070_EFUSE_DATA3		0x059c
    +#define RT3070_LDO_CFG0			0x05d4
    +#define RT3070_GPIO_SWITCH		0x05dc
    +
    +/* MAC registers */
    +#define RT2860_ASIC_VER_ID		0x1000
    +#define RT2860_MAC_SYS_CTRL		0x1004
    +#define RT2860_MAC_ADDR_DW0		0x1008
    +#define RT2860_MAC_ADDR_DW1		0x100c
    +#define RT2860_MAC_BSSID_DW0		0x1010
    +#define RT2860_MAC_BSSID_DW1		0x1014
    +#define RT2860_MAX_LEN_CFG		0x1018
    +#define RT2860_BBP_CSR_CFG		0x101c
    +#define RT2860_RF_CSR_CFG0		0x1020
    +#define RT2860_RF_CSR_CFG1		0x1024
    +#define RT2860_RF_CSR_CFG2		0x1028
    +#define RT2860_LED_CFG			0x102c
    +
    +/* undocumented registers */
    +#define RT2860_DEBUG			0x10f4
    +
    +/* MAC Timing control registers */
    +#define RT2860_XIFS_TIME_CFG		0x1100
    +#define RT2860_BKOFF_SLOT_CFG		0x1104
    +#define RT2860_NAV_TIME_CFG		0x1108
    +#define RT2860_CH_TIME_CFG		0x110c
    +#define RT2860_PBF_LIFE_TIMER		0x1110
    +#define RT2860_BCN_TIME_CFG		0x1114
    +#define RT2860_TBTT_SYNC_CFG		0x1118
    +#define RT2860_TSF_TIMER_DW0		0x111c
    +#define RT2860_TSF_TIMER_DW1		0x1120
    +#define RT2860_TBTT_TIMER		0x1124
    +#define RT2860_INT_TIMER_CFG		0x1128
    +#define RT2860_INT_TIMER_EN		0x112c
    +#define RT2860_CH_IDLE_TIME		0x1130
    +
    +/* MAC Power Save configuration registers */
    +#define RT2860_MAC_STATUS_REG		0x1200
    +#define RT2860_PWR_PIN_CFG		0x1204
    +#define RT2860_AUTO_WAKEUP_CFG		0x1208
    +
    +/* MAC TX configuration registers */
    +#define RT2860_EDCA_AC_CFG(aci)		(0x1300 + (aci) * 4)
    +#define RT2860_EDCA_TID_AC_MAP		0x1310
    +#define RT2860_TX_PWR_CFG(ridx)		(0x1314 + (ridx) * 4)
    +#define RT2860_TX_PIN_CFG		0x1328
    +#define RT2860_TX_BAND_CFG		0x132c
    +#define RT2860_TX_SW_CFG0		0x1330
    +#define RT2860_TX_SW_CFG1		0x1334
    +#define RT2860_TX_SW_CFG2		0x1338
    +#define RT2860_TXOP_THRES_CFG		0x133c
    +#define RT2860_TXOP_CTRL_CFG		0x1340
    +#define RT2860_TX_RTS_CFG		0x1344
    +#define RT2860_TX_TIMEOUT_CFG		0x1348
    +#define RT2860_TX_RTY_CFG		0x134c
    +#define RT2860_TX_LINK_CFG		0x1350
    +#define RT2860_HT_FBK_CFG0		0x1354
    +#define RT2860_HT_FBK_CFG1		0x1358
    +#define RT2860_LG_FBK_CFG0		0x135c
    +#define RT2860_LG_FBK_CFG1		0x1360
    +#define RT2860_CCK_PROT_CFG		0x1364
    +#define RT2860_OFDM_PROT_CFG		0x1368
    +#define RT2860_MM20_PROT_CFG		0x136c
    +#define RT2860_MM40_PROT_CFG		0x1370
    +#define RT2860_GF20_PROT_CFG		0x1374
    +#define RT2860_GF40_PROT_CFG		0x1378
    +#define RT2860_EXP_CTS_TIME		0x137c
    +#define RT2860_EXP_ACK_TIME		0x1380
    +
    +/* MAC RX configuration registers */
    +#define RT2860_RX_FILTR_CFG		0x1400
    +#define RT2860_AUTO_RSP_CFG		0x1404
    +#define RT2860_LEGACY_BASIC_RATE	0x1408
    +#define RT2860_HT_BASIC_RATE		0x140c
    +#define RT2860_HT_CTRL_CFG		0x1410
    +#define RT2860_SIFS_COST_CFG		0x1414
    +#define RT2860_RX_PARSER_CFG		0x1418
    +
    +/* MAC Security configuration registers */
    +#define RT2860_TX_SEC_CNT0		0x1500
    +#define RT2860_RX_SEC_CNT0		0x1504
    +#define RT2860_CCMP_FC_MUTE		0x1508
    +
    +/* MAC HCCA/PSMP configuration registers */
    +#define RT2860_TXOP_HLDR_ADDR0		0x1600
    +#define RT2860_TXOP_HLDR_ADDR1		0x1604
    +#define RT2860_TXOP_HLDR_ET		0x1608
    +#define RT2860_QOS_CFPOLL_RA_DW0	0x160c
    +#define RT2860_QOS_CFPOLL_A1_DW1	0x1610
    +#define RT2860_QOS_CFPOLL_QC		0x1614
    +
    +/* MAC Statistics Counters */
    +#define RT2860_RX_STA_CNT0		0x1700
    +#define RT2860_RX_STA_CNT1		0x1704
    +#define RT2860_RX_STA_CNT2		0x1708
    +#define RT2860_TX_STA_CNT0		0x170c
    +#define RT2860_TX_STA_CNT1		0x1710
    +#define RT2860_TX_STA_CNT2		0x1714
    +#define RT2860_TX_STAT_FIFO		0x1718
    +
    +/* RX WCID search table */
    +#define RT2860_WCID_ENTRY(wcid)		(0x1800 + (wcid) * 8)
    +
    +#define RT2860_FW_BASE			0x2000
    +#define RT2870_FW_BASE			0x3000
    +
    +/* Pair-wise key table */
    +#define RT2860_PKEY(wcid)		(0x4000 + (wcid) * 32)
    +
    +/* IV/EIV table */
    +#define RT2860_IVEIV(wcid)		(0x6000 + (wcid) * 8)
    +
    +/* WCID attribute table */
    +#define RT2860_WCID_ATTR(wcid)		(0x6800 + (wcid) * 4)
    +
    +/* Shared Key Table */
    +#define RT2860_SKEY(vap, kidx)		(0x6c00 + (vap) * 128 + (kidx) * 32)
    +
    +/* Shared Key Mode */
    +#define RT2860_SKEY_MODE_0_7		0x7000
    +#define RT2860_SKEY_MODE_8_15		0x7004
    +#define RT2860_SKEY_MODE_16_23		0x7008
    +#define RT2860_SKEY_MODE_24_31		0x700c
    +
    +/* Shared Memory between MCU and host */
    +#define RT2860_H2M_MAILBOX		0x7010
    +#define RT2860_H2M_MAILBOX_CID		0x7014
    +#define RT2860_H2M_MAILBOX_STATUS	0x701c
    +#define RT2860_H2M_BBPAGENT		0x7028
    +#define RT2860_BCN_BASE(vap)		(0x7800 + (vap) * 512)
    +
    +
    +/* possible flags for register RT2860_PCI_EECTRL */
    +#define RT2860_C	(1 << 0)
    +#define RT2860_S	(1 << 1)
    +#define RT2860_D	(1 << 2)
    +#define RT2860_SHIFT_D	2
    +#define RT2860_Q	(1 << 3)
    +#define RT2860_SHIFT_Q	3
    +
    +/* possible flags for registers INT_STATUS/INT_MASK */
    +#define RT2860_TX_COHERENT	(1 << 17)
    +#define RT2860_RX_COHERENT	(1 << 16)
    +#define RT2860_MAC_INT_4	(1 << 15)
    +#define RT2860_MAC_INT_3	(1 << 14)
    +#define RT2860_MAC_INT_2	(1 << 13)
    +#define RT2860_MAC_INT_1	(1 << 12)
    +#define RT2860_MAC_INT_0	(1 << 11)
    +#define RT2860_TX_RX_COHERENT	(1 << 10)
    +#define RT2860_MCU_CMD_INT	(1 <<  9)
    +#define RT2860_TX_DONE_INT5	(1 <<  8)
    +#define RT2860_TX_DONE_INT4	(1 <<  7)
    +#define RT2860_TX_DONE_INT3	(1 <<  6)
    +#define RT2860_TX_DONE_INT2	(1 <<  5)
    +#define RT2860_TX_DONE_INT1	(1 <<  4)
    +#define RT2860_TX_DONE_INT0	(1 <<  3)
    +#define RT2860_RX_DONE_INT	(1 <<  2)
    +#define RT2860_TX_DLY_INT	(1 <<  1)
    +#define RT2860_RX_DLY_INT	(1 <<  0)
    +
    +/* possible flags for register WPDMA_GLO_CFG */
    +#define RT2860_HDR_SEG_LEN_SHIFT	8
    +#define RT2860_BIG_ENDIAN		(1 << 7)
    +#define RT2860_TX_WB_DDONE		(1 << 6)
    +#define RT2860_WPDMA_BT_SIZE_SHIFT	4
    +#define RT2860_WPDMA_BT_SIZE16		0
    +#define RT2860_WPDMA_BT_SIZE32		1
    +#define RT2860_WPDMA_BT_SIZE64		2
    +#define RT2860_WPDMA_BT_SIZE128		3
    +#define RT2860_RX_DMA_BUSY		(1 << 3)
    +#define RT2860_RX_DMA_EN		(1 << 2)
    +#define RT2860_TX_DMA_BUSY		(1 << 1)
    +#define RT2860_TX_DMA_EN		(1 << 0)
    +
    +/* possible flags for register DELAY_INT_CFG */
    +#define RT2860_TXDLY_INT_EN		(1 << 31)
    +#define RT2860_TXMAX_PINT_SHIFT		24
    +#define RT2860_TXMAX_PTIME_SHIFT	16
    +#define RT2860_RXDLY_INT_EN		(1 << 15)
    +#define RT2860_RXMAX_PINT_SHIFT		8
    +#define RT2860_RXMAX_PTIME_SHIFT	0
    +
    +/* possible flags for register GPIO_CTRL */
    +#define RT2860_GPIO_D_SHIFT	8
    +#define RT2860_GPIO_O_SHIFT	0
    +
    +/* possible flags for register USB_DMA_CFG */
    +#define RT2860_USB_TX_BUSY		(1 << 31)
    +#define RT2860_USB_RX_BUSY		(1 << 30)
    +#define RT2860_USB_EPOUT_VLD_SHIFT	24
    +#define RT2860_USB_TX_EN		(1 << 23)
    +#define RT2860_USB_RX_EN		(1 << 22)
    +#define RT2860_USB_RX_AGG_EN		(1 << 21)
    +#define RT2860_USB_TXOP_HALT		(1 << 20)
    +#define RT2860_USB_TX_CLEAR		(1 << 19)
    +#define RT2860_USB_PHY_WD_EN		(1 << 16)
    +#define RT2860_USB_PHY_MAN_RST		(1 << 15)
    +#define RT2860_USB_RX_AGG_LMT(x)	((x) << 8)	/* in unit of 1KB */
    +#define RT2860_USB_RX_AGG_TO(x)		((x) & 0xff)	/* in unit of 33ns */
    +
    +/* possible flags for register US_CYC_CNT */
    +#define RT2860_TEST_EN		(1 << 24)
    +#define RT2860_TEST_SEL_SHIFT	16
    +#define RT2860_BT_MODE_EN	(1 <<  8)
    +#define RT2860_US_CYC_CNT_SHIFT	0
    +
    +/* possible flags for register SYS_CTRL */
    +#define RT2860_HST_PM_SEL	(1 << 16)
    +#define RT2860_CAP_MODE		(1 << 14)
    +#define RT2860_PME_OEN		(1 << 13)
    +#define RT2860_CLKSELECT	(1 << 12)
    +#define RT2860_PBF_CLK_EN	(1 << 11)
    +#define RT2860_MAC_CLK_EN	(1 << 10)
    +#define RT2860_DMA_CLK_EN	(1 <<  9)
    +#define RT2860_MCU_READY	(1 <<  7)
    +#define RT2860_ASY_RESET	(1 <<  4)
    +#define RT2860_PBF_RESET	(1 <<  3)
    +#define RT2860_MAC_RESET	(1 <<  2)
    +#define RT2860_DMA_RESET	(1 <<  1)
    +#define RT2860_MCU_RESET	(1 <<  0)
    +
    +/* possible values for register HOST_CMD */
    +#define RT2860_MCU_CMD_SLEEP	0x30
    +#define RT2860_MCU_CMD_WAKEUP	0x31
    +#define RT2860_MCU_CMD_LEDS	0x50
    +#define RT2860_MCU_CMD_LED_RSSI	0x51
    +#define RT2860_MCU_CMD_LED1	0x52
    +#define RT2860_MCU_CMD_LED2	0x53
    +#define RT2860_MCU_CMD_LED3	0x54
    +#define RT2860_MCU_CMD_BOOT	0x72
    +#define RT2860_MCU_CMD_BBP	0x80
    +#define RT2860_MCU_CMD_PSLEVEL	0x83
    +
    +/* possible flags for register PBF_CFG */
    +#define RT2860_TX1Q_NUM_SHIFT	21
    +#define RT2860_TX2Q_NUM_SHIFT	16
    +#define RT2860_NULL0_MODE	(1 << 15)
    +#define RT2860_NULL1_MODE	(1 << 14)
    +#define RT2860_RX_DROP_MODE	(1 << 13)
    +#define RT2860_TX0Q_MANUAL	(1 << 12)
    +#define RT2860_TX1Q_MANUAL	(1 << 11)
    +#define RT2860_TX2Q_MANUAL	(1 << 10)
    +#define RT2860_RX0Q_MANUAL	(1 <<  9)
    +#define RT2860_HCCA_EN		(1 <<  8)
    +#define RT2860_TX0Q_EN		(1 <<  4)
    +#define RT2860_TX1Q_EN		(1 <<  3)
    +#define RT2860_TX2Q_EN		(1 <<  2)
    +#define RT2860_RX0Q_EN		(1 <<  1)
    +
    +/* possible flags for register BUF_CTRL */
    +#define RT2860_WRITE_TXQ(qid)	(1 << (11 - (qid)))
    +#define RT2860_NULL0_KICK	(1 << 7)
    +#define RT2860_NULL1_KICK	(1 << 6)
    +#define RT2860_BUF_RESET	(1 << 5)
    +#define RT2860_READ_TXQ(qid)	(1 << (3 - (qid))
    +#define RT2860_READ_RX0Q	(1 << 0)
    +
    +/* possible flags for registers MCU_INT_STA/MCU_INT_ENA */
    +#define RT2860_MCU_MAC_INT_8	(1 << 24)
    +#define RT2860_MCU_MAC_INT_7	(1 << 23)
    +#define RT2860_MCU_MAC_INT_6	(1 << 22)
    +#define RT2860_MCU_MAC_INT_4	(1 << 20)
    +#define RT2860_MCU_MAC_INT_3	(1 << 19)
    +#define RT2860_MCU_MAC_INT_2	(1 << 18)
    +#define RT2860_MCU_MAC_INT_1	(1 << 17)
    +#define RT2860_MCU_MAC_INT_0	(1 << 16)
    +#define RT2860_DTX0_INT		(1 << 11)
    +#define RT2860_DTX1_INT		(1 << 10)
    +#define RT2860_DTX2_INT		(1 <<  9)
    +#define RT2860_DRX0_INT		(1 <<  8)
    +#define RT2860_HCMD_INT		(1 <<  7)
    +#define RT2860_N0TX_INT		(1 <<  6)
    +#define RT2860_N1TX_INT		(1 <<  5)
    +#define RT2860_BCNTX_INT	(1 <<  4)
    +#define RT2860_MTX0_INT		(1 <<  3)
    +#define RT2860_MTX1_INT		(1 <<  2)
    +#define RT2860_MTX2_INT		(1 <<  1)
    +#define RT2860_MRX0_INT		(1 <<  0)
    +
    +/* possible flags for register TXRXQ_PCNT */
    +#define RT2860_RX0Q_PCNT_MASK	0xff000000
    +#define RT2860_TX2Q_PCNT_MASK	0x00ff0000
    +#define RT2860_TX1Q_PCNT_MASK	0x0000ff00
    +#define RT2860_TX0Q_PCNT_MASK	0x000000ff
    +
    +/* possible flags for register CAP_CTRL */
    +#define RT2860_CAP_ADC_FEQ		(1 << 31)
    +#define RT2860_CAP_START		(1 << 30)
    +#define RT2860_MAN_TRIG			(1 << 29)
    +#define RT2860_TRIG_OFFSET_SHIFT	16
    +#define RT2860_START_ADDR_SHIFT		0
    +
    +/* possible flags for register RF_CSR_CFG */
    +#define RT3070_RF_KICK		(1 << 17)
    +#define RT3070_RF_WRITE		(1 << 16)
    +
    +/* possible flags for register EFUSE_CTRL */
    +#define RT3070_SEL_EFUSE	(1 << 31)
    +#define RT3070_EFSROM_KICK	(1 << 30)
    +#define RT3070_EFSROM_AIN_MASK	0x03ff0000
    +#define RT3070_EFSROM_AIN_SHIFT	16
    +#define RT3070_EFSROM_MODE_MASK	0x000000c0
    +#define RT3070_EFUSE_AOUT_MASK	0x0000003f
    +
    +/* possible flags for register MAC_SYS_CTRL */
    +#define RT2860_RX_TS_EN		(1 << 7)
    +#define RT2860_WLAN_HALT_EN	(1 << 6)
    +#define RT2860_PBF_LOOP_EN	(1 << 5)
    +#define RT2860_CONT_TX_TEST	(1 << 4)
    +#define RT2860_MAC_RX_EN	(1 << 3)
    +#define RT2860_MAC_TX_EN	(1 << 2)
    +#define RT2860_BBP_HRST		(1 << 1)
    +#define RT2860_MAC_SRST		(1 << 0)
    +
    +/* possible flags for register MAC_BSSID_DW1 */
    +#define RT2860_MULTI_BCN_NUM_SHIFT	18
    +#define RT2860_MULTI_BSSID_MODE_SHIFT	16
    +
    +/* possible flags for register MAX_LEN_CFG */
    +#define RT2860_MIN_MPDU_LEN_SHIFT	16
    +#define RT2860_MAX_PSDU_LEN_SHIFT	12
    +#define RT2860_MAX_PSDU_LEN8K		0
    +#define RT2860_MAX_PSDU_LEN16K		1
    +#define RT2860_MAX_PSDU_LEN32K		2
    +#define RT2860_MAX_PSDU_LEN64K		3
    +#define RT2860_MAX_MPDU_LEN_SHIFT	0
    +
    +/* possible flags for registers BBP_CSR_CFG/H2M_BBPAGENT */
    +#define RT2860_BBP_RW_PARALLEL		(1 << 19)
    +#define RT2860_BBP_PAR_DUR_112_5	(1 << 18)
    +#define RT2860_BBP_CSR_KICK		(1 << 17)
    +#define RT2860_BBP_CSR_READ		(1 << 16)
    +#define RT2860_BBP_ADDR_SHIFT		8
    +#define RT2860_BBP_DATA_SHIFT		0
    +
    +/* possible flags for register RF_CSR_CFG0 */
    +#define RT2860_RF_REG_CTRL		(1 << 31)
    +#define RT2860_RF_LE_SEL1		(1 << 30)
    +#define RT2860_RF_LE_STBY		(1 << 29)
    +#define RT2860_RF_REG_WIDTH_SHIFT	24
    +#define RT2860_RF_REG_0_SHIFT		0
    +
    +/* possible flags for register RF_CSR_CFG1 */
    +#define RT2860_RF_DUR_5		(1 << 24)
    +#define RT2860_RF_REG_1_SHIFT	0
    +
    +/* possible flags for register LED_CFG */
    +#define RT2860_LED_POL			(1 << 30)
    +#define RT2860_Y_LED_MODE_SHIFT		28
    +#define RT2860_G_LED_MODE_SHIFT		26
    +#define RT2860_R_LED_MODE_SHIFT		24
    +#define RT2860_LED_MODE_OFF		0
    +#define RT2860_LED_MODE_BLINK_TX	1
    +#define RT2860_LED_MODE_SLOW_BLINK	2
    +#define RT2860_LED_MODE_ON		3
    +#define RT2860_SLOW_BLK_TIME_SHIFT	16
    +#define RT2860_LED_OFF_TIME_SHIFT	8
    +#define RT2860_LED_ON_TIME_SHIFT	0
    +
    +/* possible flags for register XIFS_TIME_CFG */
    +#define RT2860_BB_RXEND_EN		(1 << 29)
    +#define RT2860_EIFS_TIME_SHIFT		20
    +#define RT2860_OFDM_XIFS_TIME_SHIFT	16
    +#define RT2860_OFDM_SIFS_TIME_SHIFT	8
    +#define RT2860_CCK_SIFS_TIME_SHIFT	0
    +
    +/* possible flags for register BKOFF_SLOT_CFG */
    +#define RT2860_CC_DELAY_TIME_SHIFT	8
    +#define RT2860_SLOT_TIME		0
    +
    +/* possible flags for register NAV_TIME_CFG */
    +#define RT2860_NAV_UPD			(1 << 31)
    +#define RT2860_NAV_UPD_VAL_SHIFT	16
    +#define RT2860_NAV_CLR_EN		(1 << 15)
    +#define RT2860_NAV_TIMER_SHIFT		0
    +
    +/* possible flags for register CH_TIME_CFG */
    +#define RT2860_EIFS_AS_CH_BUSY	(1 << 4)
    +#define RT2860_NAV_AS_CH_BUSY	(1 << 3)
    +#define RT2860_RX_AS_CH_BUSY	(1 << 2)
    +#define RT2860_TX_AS_CH_BUSY	(1 << 1)
    +#define RT2860_CH_STA_TIMER_EN	(1 << 0)
    +
    +/* possible values for register BCN_TIME_CFG */
    +#define RT2860_TSF_INS_COMP_SHIFT	24
    +#define RT2860_BCN_TX_EN		(1 << 20)
    +#define RT2860_TBTT_TIMER_EN		(1 << 19)
    +#define RT2860_TSF_SYNC_MODE_SHIFT	17
    +#define RT2860_TSF_SYNC_MODE_DIS	0
    +#define RT2860_TSF_SYNC_MODE_STA	1
    +#define RT2860_TSF_SYNC_MODE_IBSS	2
    +#define RT2860_TSF_SYNC_MODE_HOSTAP	3
    +#define RT2860_TSF_TIMER_EN		(1 << 16)
    +#define RT2860_BCN_INTVAL_SHIFT		0
    +
    +/* possible flags for register TBTT_SYNC_CFG */
    +#define RT2860_BCN_CWMIN_SHIFT		20
    +#define RT2860_BCN_AIFSN_SHIFT		16
    +#define RT2860_BCN_EXP_WIN_SHIFT	8
    +#define RT2860_TBTT_ADJUST_SHIFT	0
    +
    +/* possible flags for register INT_TIMER_CFG */
    +#define RT2860_GP_TIMER_SHIFT		16
    +#define RT2860_PRE_TBTT_TIMER_SHIFT	0
    +
    +/* possible flags for register INT_TIMER_EN */
    +#define RT2860_GP_TIMER_EN	(1 << 1)
    +#define RT2860_PRE_TBTT_INT_EN	(1 << 0)
    +
    +/* possible flags for register MAC_STATUS_REG */
    +#define RT2860_RX_STATUS_BUSY	(1 << 1)
    +#define RT2860_TX_STATUS_BUSY	(1 << 0)
    +
    +/* possible flags for register PWR_PIN_CFG */
    +#define RT2860_IO_ADDA_PD	(1 << 3)
    +#define RT2860_IO_PLL_PD	(1 << 2)
    +#define RT2860_IO_RA_PE		(1 << 1)
    +#define RT2860_IO_RF_PE		(1 << 0)
    +
    +/* possible flags for register AUTO_WAKEUP_CFG */
    +#define RT2860_AUTO_WAKEUP_EN		(1 << 15)
    +#define RT2860_SLEEP_TBTT_NUM_SHIFT	8
    +#define RT2860_WAKEUP_LEAD_TIME_SHIFT	0
    +
    +/* possible flags for register TX_PIN_CFG */
    +#define RT2860_TRSW_POL		(1 << 19)
    +#define RT2860_TRSW_EN		(1 << 18)
    +#define RT2860_RFTR_POL		(1 << 17)
    +#define RT2860_RFTR_EN		(1 << 16)
    +#define RT2860_LNA_PE_G1_POL	(1 << 15)
    +#define RT2860_LNA_PE_A1_POL	(1 << 14)
    +#define RT2860_LNA_PE_G0_POL	(1 << 13)
    +#define RT2860_LNA_PE_A0_POL	(1 << 12)
    +#define RT2860_LNA_PE_G1_EN	(1 << 11)
    +#define RT2860_LNA_PE_A1_EN	(1 << 10)
    +#define RT2860_LNA_PE_G0_EN	(1 <<  9)
    +#define RT2860_LNA_PE_A0_EN	(1 <<  8)
    +#define RT2860_PA_PE_G1_POL	(1 <<  7)
    +#define RT2860_PA_PE_A1_POL	(1 <<  6)
    +#define RT2860_PA_PE_G0_POL	(1 <<  5)
    +#define RT2860_PA_PE_A0_POL	(1 <<  4)
    +#define RT2860_PA_PE_G1_EN	(1 <<  3)
    +#define RT2860_PA_PE_A1_EN	(1 <<  2)
    +#define RT2860_PA_PE_G0_EN	(1 <<  1)
    +#define RT2860_PA_PE_A0_EN	(1 <<  0)
    +
    +/* possible flags for register TX_BAND_CFG */
    +#define RT2860_5G_BAND_SEL_N	(1 << 2)
    +#define RT2860_5G_BAND_SEL_P	(1 << 1)
    +#define RT2860_TX_BAND_SEL	(1 << 0)
    +
    +/* possible flags for register TX_SW_CFG0 */
    +#define RT2860_DLY_RFTR_EN_SHIFT	24
    +#define RT2860_DLY_TRSW_EN_SHIFT	16
    +#define RT2860_DLY_PAPE_EN_SHIFT	8
    +#define RT2860_DLY_TXPE_EN_SHIFT	0
    +
    +/* possible flags for register TX_SW_CFG1 */
    +#define RT2860_DLY_RFTR_DIS_SHIFT	16
    +#define RT2860_DLY_TRSW_DIS_SHIFT	8
    +#define RT2860_DLY_PAPE_DIS SHIFT	0
    +
    +/* possible flags for register TX_SW_CFG2 */
    +#define RT2860_DLY_LNA_EN_SHIFT		24
    +#define RT2860_DLY_LNA_DIS_SHIFT	16
    +#define RT2860_DLY_DAC_EN_SHIFT		8
    +#define RT2860_DLY_DAC_DIS_SHIFT	0
    +
    +/* possible flags for register TXOP_THRES_CFG */
    +#define RT2860_TXOP_REM_THRES_SHIFT	24
    +#define RT2860_CF_END_THRES_SHIFT	16
    +#define RT2860_RDG_IN_THRES		8
    +#define RT2860_RDG_OUT_THRES		0
    +
    +/* possible flags for register TXOP_CTRL_CFG */
    +#define RT2860_EXT_CW_MIN_SHIFT		16
    +#define RT2860_EXT_CCA_DLY_SHIFT	8
    +#define RT2860_EXT_CCA_EN		(1 << 7)
    +#define RT2860_LSIG_TXOP_EN		(1 << 6)
    +#define RT2860_TXOP_TRUN_EN_MIMOPS	(1 << 4)
    +#define RT2860_TXOP_TRUN_EN_TXOP	(1 << 3)
    +#define RT2860_TXOP_TRUN_EN_RATE	(1 << 2)
    +#define RT2860_TXOP_TRUN_EN_AC		(1 << 1)
    +#define RT2860_TXOP_TRUN_EN_TIMEOUT	(1 << 0)
    +
    +/* possible flags for register TX_RTS_CFG */
    +#define RT2860_RTS_FBK_EN		(1 << 24)
    +#define RT2860_RTS_THRES_SHIFT		8
    +#define RT2860_RTS_RTY_LIMIT_SHIFT	0
    +
    +/* possible flags for register TX_TIMEOUT_CFG */
    +#define RT2860_TXOP_TIMEOUT_SHIFT	16
    +#define RT2860_RX_ACK_TIMEOUT_SHIFT	8
    +#define RT2860_MPDU_LIFE_TIME_SHIFT	4
    +
    +/* possible flags for register TX_RTY_CFG */
    +#define RT2860_TX_AUTOFB_EN		(1 << 30)
    +#define RT2860_AGG_RTY_MODE_TIMER	(1 << 29)
    +#define RT2860_NAG_RTY_MODE_TIMER	(1 << 28)
    +#define RT2860_LONG_RTY_THRES_SHIFT	16
    +#define RT2860_LONG_RTY_LIMIT_SHIFT	8
    +#define RT2860_SHORT_RTY_LIMIT_SHIFT	0
    +
    +/* possible flags for register TX_LINK_CFG */
    +#define RT2860_REMOTE_MFS_SHIFT		24
    +#define RT2860_REMOTE_MFB_SHIFT		16
    +#define RT2860_TX_CFACK_EN		(1 << 12)
    +#define RT2860_TX_RDG_EN		(1 << 11)
    +#define RT2860_TX_MRQ_EN		(1 << 10)
    +#define RT2860_REMOTE_UMFS_EN		(1 <<  9)
    +#define RT2860_TX_MFB_EN		(1 <<  8)
    +#define RT2860_REMOTE_MFB_LT_SHIFT	0
    +
    +/* possible flags for registers *_PROT_CFG */
    +#define RT2860_RTSTH_EN			(1 << 26)
    +#define RT2860_TXOP_ALLOW_GF40		(1 << 25)
    +#define RT2860_TXOP_ALLOW_GF20		(1 << 24)
    +#define RT2860_TXOP_ALLOW_MM40		(1 << 23)
    +#define RT2860_TXOP_ALLOW_MM20		(1 << 22)
    +#define RT2860_TXOP_ALLOW_OFDM		(1 << 21)
    +#define RT2860_TXOP_ALLOW_CCK		(1 << 20)
    +#define RT2860_TXOP_ALLOW_ALL		(0x3f << 20)
    +#define RT2860_PROT_NAV_SHORT		(1 << 18)
    +#define RT2860_PROT_NAV_LONG		(2 << 18)
    +#define RT2860_PROT_CTRL_RTS_CTS	(1 << 16)
    +#define RT2860_PROT_CTRL_CTS		(2 << 16)
    +
    +/* possible flags for registers EXP_{CTS,ACK}_TIME */
    +#define RT2860_EXP_OFDM_TIME_SHIFT	16
    +#define RT2860_EXP_CCK_TIME_SHIFT	0
    +
    +/* possible flags for register RX_FILTR_CFG */
    +#define RT2860_DROP_CTRL_RSV	(1 << 16)
    +#define RT2860_DROP_BAR		(1 << 15)
    +#define RT2860_DROP_BA		(1 << 14)
    +#define RT2860_DROP_PSPOLL	(1 << 13)
    +#define RT2860_DROP_RTS		(1 << 12)
    +#define RT2860_DROP_CTS		(1 << 11)
    +#define RT2860_DROP_ACK		(1 << 10)
    +#define RT2860_DROP_CFEND	(1 <<  9)
    +#define RT2860_DROP_CFACK	(1 <<  8)
    +#define RT2860_DROP_DUPL	(1 <<  7)
    +#define RT2860_DROP_BC		(1 <<  6)
    +#define RT2860_DROP_MC		(1 <<  5)
    +#define RT2860_DROP_VER_ERR	(1 <<  4)
    +#define RT2860_DROP_NOT_MYBSS	(1 <<  3)
    +#define RT2860_DROP_UC_NOME	(1 <<  2)
    +#define RT2860_DROP_PHY_ERR	(1 <<  1)
    +#define RT2860_DROP_CRC_ERR	(1 <<  0)
    +
    +/* possible flags for register AUTO_RSP_CFG */
    +#define RT2860_CTRL_PWR_BIT	(1 << 7)
    +#define RT2860_BAC_ACK_POLICY	(1 << 6)
    +#define RT2860_CCK_SHORT_EN	(1 << 4)
    +#define RT2860_CTS_40M_REF_EN	(1 << 3)
    +#define RT2860_CTS_40M_MODE_EN	(1 << 2)
    +#define RT2860_BAC_ACKPOLICY_EN	(1 << 1)
    +#define RT2860_AUTO_RSP_EN	(1 << 0)
    +
    +/* possible flags for register SIFS_COST_CFG */
    +#define RT2860_OFDM_SIFS_COST_SHIFT	8
    +#define RT2860_CCK_SIFS_COST_SHIFT	0
    +
    +/* possible flags for register TXOP_HLDR_ET */
    +#define RT2860_TXOP_ETM1_EN		(1 << 25)
    +#define RT2860_TXOP_ETM0_EN		(1 << 24)
    +#define RT2860_TXOP_ETM_THRES_SHIFT	16
    +#define RT2860_TXOP_ETO_EN		(1 <<  8)
    +#define RT2860_TXOP_ETO_THRES_SHIFT	1
    +#define RT2860_PER_RX_RST_EN		(1 <<  0)
    +
    +/* possible flags for register TX_STAT_FIFO */
    +#define RT2860_TXQ_MCS_SHIFT	16
    +#define RT2860_TXQ_WCID_SHIFT	8
    +#define RT2860_TXQ_ACKREQ	(1 << 7)
    +#define RT2860_TXQ_AGG		(1 << 6)
    +#define RT2860_TXQ_OK		(1 << 5)
    +#define RT2860_TXQ_PID_SHIFT	1
    +#define RT2860_TXQ_VLD		(1 << 0)
    +
    +/* possible flags for register WCID_ATTR */
    +#define RT2860_MODE_NOSEC	0
    +#define RT2860_MODE_WEP40	1
    +#define RT2860_MODE_WEP104	2
    +#define RT2860_MODE_TKIP	3
    +#define RT2860_MODE_AES_CCMP	4
    +#define RT2860_MODE_CKIP40	5
    +#define RT2860_MODE_CKIP104	6
    +#define RT2860_MODE_CKIP128	7
    +#define RT2860_RX_PKEY_EN	(1 << 0)
    +
    +/* possible flags for register H2M_MAILBOX */
    +#define RT2860_H2M_BUSY		(1 << 24)
    +#define RT2860_TOKEN_NO_INTR	0xff
    +
    +
    +/* possible flags for MCU command RT2860_MCU_CMD_LEDS */
    +#define RT2860_LED_RADIO	(1 << 13)
    +#define RT2860_LED_LINK_2GHZ	(1 << 14)
    +#define RT2860_LED_LINK_5GHZ	(1 << 15)
    +
    +
    +/* possible flags for RT3020 RF register 1 */
    +#define RT3070_RF_BLOCK	(1 << 0)
    +#define RT3070_RX0_PD	(1 << 2)
    +#define RT3070_TX0_PD	(1 << 3)
    +#define RT3070_RX1_PD	(1 << 4)
    +#define RT3070_TX1_PD	(1 << 5)
    +
    +/* possible flags for RT3020 RF register 15 */
    +#define RT3070_TX_LO2	(1 << 3)
    +
    +/* possible flags for RT3020 RF register 17 */
    +#define RT3070_TX_LO1	(1 << 3)
    +
    +/* possible flags for RT3020 RF register 20 */
    +#define RT3070_RX_LO1	(1 << 3)
    +
    +/* possible flags for RT3020 RF register 21 */
    +#define RT3070_RX_LO2	(1 << 3)
    +
    +
    +/* RT2860 TX descriptor */
    +struct rt2860_txd {
    +	uint32_t	sdp0;		/* Segment Data Pointer 0 */
    +	uint16_t	sdl1;		/* Segment Data Length 1 */
    +#define RT2860_TX_BURST	(1 << 15)
    +#define RT2860_TX_LS1	(1 << 14)	/* SDP1 is the last segment */
    +
    +	uint16_t	sdl0;		/* Segment Data Length 0 */
    +#define RT2860_TX_DDONE	(1 << 15)
    +#define RT2860_TX_LS0	(1 << 14)	/* SDP0 is the last segment */
    +
    +	uint32_t	sdp1;		/* Segment Data Pointer 1 */
    +	uint8_t		reserved[3];
    +	uint8_t		flags;
    +#define RT2860_TX_QSEL_SHIFT	1
    +#define RT2860_TX_QSEL_MGMT	(0 << 1)
    +#define RT2860_TX_QSEL_HCCA	(1 << 1)
    +#define RT2860_TX_QSEL_EDCA	(2 << 1)
    +#define RT2860_TX_WIV		(1 << 0)
    +} __packed;
    +
    +/* RT2870 TX descriptor */
    +struct rt2870_txd {
    +	uint16_t	len;
    +	uint8_t		pad;
    +	uint8_t		flags;
    +} __packed;
    +
    +/* TX Wireless Information */
    +struct rt2860_txwi {
    +	uint8_t		flags;
    +#define RT2860_TX_MPDU_DSITY_SHIFT	5
    +#define RT2860_TX_AMPDU			(1 << 4)
    +#define RT2860_TX_TS			(1 << 3)
    +#define RT2860_TX_CFACK			(1 << 2)
    +#define RT2860_TX_MMPS			(1 << 1)
    +#define RT2860_TX_FRAG			(1 << 0)
    +
    +	uint8_t		txop;
    +#define RT2860_TX_TXOP_HT	0
    +#define RT2860_TX_TXOP_PIFS	1
    +#define RT2860_TX_TXOP_SIFS	2
    +#define RT2860_TX_TXOP_BACKOFF	3
    +
    +	uint16_t	phy;
    +#define RT2860_PHY_MODE		0xc000
    +#define RT2860_PHY_CCK		(0 << 14)
    +#define RT2860_PHY_OFDM		(1 << 14)
    +#define RT2860_PHY_HT		(2 << 14)
    +#define RT2860_PHY_HT_GF	(3 << 14)
    +#define RT2860_PHY_SGI		(1 << 8)
    +#define RT2860_PHY_BW40		(1 << 7)
    +#define RT2860_PHY_MCS		0x7f
    +#define RT2860_PHY_SHPRE	(1 << 3)
    +
    +	uint8_t		xflags;
    +#define RT2860_TX_BAWINSIZE_SHIFT	2
    +#define RT2860_TX_NSEQ			(1 << 1)
    +#define RT2860_TX_ACK			(1 << 0)
    +
    +	uint8_t		wcid;	/* Wireless Client ID */
    +	uint16_t	len;
    +#define RT2860_TX_PID_SHIFT	12
    +
    +	uint32_t	iv;
    +	uint32_t	eiv;
    +} __packed;
    +
    +/* RT2860 RX descriptor */
    +struct rt2860_rxd {
    +	uint32_t	sdp0;
    +	uint16_t	sdl1;	/* unused */
    +	uint16_t	sdl0;
    +#define RT2860_RX_DDONE	(1 << 15)
    +#define RT2860_RX_LS0	(1 << 14)
    +
    +	uint32_t	sdp1;	/* unused */
    +	uint32_t	flags;
    +#define RT2860_RX_DEC		(1 << 16)
    +#define RT2860_RX_AMPDU		(1 << 15)
    +#define RT2860_RX_L2PAD		(1 << 14)
    +#define RT2860_RX_RSSI		(1 << 13)
    +#define RT2860_RX_HTC		(1 << 12)
    +#define RT2860_RX_AMSDU		(1 << 11)
    +#define RT2860_RX_MICERR	(1 << 10)
    +#define RT2860_RX_ICVERR	(1 <<  9)
    +#define RT2860_RX_CRCERR	(1 <<  8)
    +#define RT2860_RX_MYBSS		(1 <<  7)
    +#define RT2860_RX_BC		(1 <<  6)
    +#define RT2860_RX_MC		(1 <<  5)
    +#define RT2860_RX_UC2ME		(1 <<  4)
    +#define RT2860_RX_FRAG		(1 <<  3)
    +#define RT2860_RX_NULL		(1 <<  2)
    +#define RT2860_RX_DATA		(1 <<  1)
    +#define RT2860_RX_BA		(1 <<  0)
    +} __packed;
    +
    +/* RT2870 RX descriptor */
    +struct rt2870_rxd {
    +	/* single 32-bit field */
    +	uint32_t	flags;
    +} __packed;
    +
    +/* RX Wireless Information */
    +struct rt2860_rxwi {
    +	uint8_t		wcid;
    +	uint8_t		keyidx;
    +#define RT2860_RX_UDF_SHIFT	5
    +#define RT2860_RX_BSS_IDX_SHIFT	2
    +
    +	uint16_t	len;
    +#define RT2860_RX_TID_SHIFT	12
    +
    +	uint16_t	seq;
    +	uint16_t	phy;
    +	uint8_t		rssi[3];
    +	uint8_t		reserved1;
    +	uint8_t		snr[2];
    +	uint16_t	reserved2;
    +} __packed;
    +
    +
    +/* first DMA segment contains TXWI + 802.11 header + 32-bit padding */
    +#define RT2860_TXWI_DMASZ			\
    +	(sizeof (struct rt2860_txwi) +		\
    +	 sizeof (struct ieee80211_htframe) +	\
    +	 sizeof (uint16_t))
    +
    +#define RT2860_RF1	0
    +#define RT2860_RF2	2
    +#define RT2860_RF3	1
    +#define RT2860_RF4	3
    +
    +#define RT2860_RF_2820	1	/* 2T3R */
    +#define RT2860_RF_2850	2	/* dual-band 2T3R */
    +#define RT2860_RF_2720	3	/* 1T2R */
    +#define RT2860_RF_2750	4	/* dual-band 1T2R */
    +#define RT3070_RF_3020	5	/* 1T1R */
    +#define RT3070_RF_2020	6	/* b/g */
    +#define RT3070_RF_3021	7	/* 1T2R */
    +#define RT3070_RF_3022	8	/* 2T2R */
    +#define RT3070_RF_3052	9	/* dual-band 2T2R */
    +
    +/* USB commands for RT2870 only */
    +#define RT2870_RESET		1
    +#define RT2870_WRITE_2		2
    +#define RT2870_WRITE_REGION_1	6
    +#define RT2870_READ_REGION_1	7
    +#define RT2870_EEPROM_READ	9
    +
    +#define RT2860_EEPROM_DELAY	1	/* minimum hold time (microsecond) */
    +
    +#define RT2860_EEPROM_VERSION		0x01
    +#define RT2860_EEPROM_MAC01		0x02
    +#define RT2860_EEPROM_MAC23		0x03
    +#define RT2860_EEPROM_MAC45		0x04
    +#define RT2860_EEPROM_PCIE_PSLEVEL	0x11
    +#define RT2860_EEPROM_REV		0x12
    +#define RT2860_EEPROM_ANTENNA		0x1a
    +#define RT2860_EEPROM_CONFIG		0x1b
    +#define RT2860_EEPROM_COUNTRY		0x1c
    +#define RT2860_EEPROM_FREQ_LEDS		0x1d
    +#define RT2860_EEPROM_LED1		0x1e
    +#define RT2860_EEPROM_LED2		0x1f
    +#define RT2860_EEPROM_LED3		0x20
    +#define RT2860_EEPROM_LNA		0x22
    +#define RT2860_EEPROM_RSSI1_2GHZ	0x23
    +#define RT2860_EEPROM_RSSI2_2GHZ	0x24
    +#define RT2860_EEPROM_RSSI1_5GHZ	0x25
    +#define RT2860_EEPROM_RSSI2_5GHZ	0x26
    +#define RT2860_EEPROM_DELTAPWR		0x28
    +#define RT2860_EEPROM_PWR2GHZ_BASE1	0x29
    +#define RT2860_EEPROM_PWR2GHZ_BASE2	0x30
    +#define RT2860_EEPROM_TSSI1_2GHZ	0x37
    +#define RT2860_EEPROM_TSSI2_2GHZ	0x38
    +#define RT2860_EEPROM_TSSI3_2GHZ	0x39
    +#define RT2860_EEPROM_TSSI4_2GHZ	0x3a
    +#define RT2860_EEPROM_TSSI5_2GHZ	0x3b
    +#define RT2860_EEPROM_PWR5GHZ_BASE1	0x3c
    +#define RT2860_EEPROM_PWR5GHZ_BASE2	0x53
    +#define RT2860_EEPROM_TSSI1_5GHZ	0x6a
    +#define RT2860_EEPROM_TSSI2_5GHZ	0x6b
    +#define RT2860_EEPROM_TSSI3_5GHZ	0x6c
    +#define RT2860_EEPROM_TSSI4_5GHZ	0x6d
    +#define RT2860_EEPROM_TSSI5_5GHZ	0x6e
    +#define RT2860_EEPROM_RPWR		0x6f
    +#define RT2860_EEPROM_BBP_BASE		0x78
    +
    +#define RT2860_RIDX_CCK1	 0
    +#define RT2860_RIDX_CCK11	 3
    +#define RT2860_RIDX_OFDM6	 4
    +#define RT2860_RIDX_MAX		11
    +static const struct rt2860_rate {
    +	uint8_t		rate;
    +	uint8_t		mcs;
    +	enum		ieee80211_phytype phy;
    +	uint8_t		ctl_ridx;
    +	uint16_t	sp_ack_dur;
    +	uint16_t	lp_ack_dur;
    +} rt2860_rates[] = {
    +	{   2, 0, IEEE80211_T_DS,   0, 304, 304 },
    +	{   4, 1, IEEE80211_T_DS,   1, 248, 152 },
    +	{  11, 2, IEEE80211_T_DS,   2, 213, 117 },
    +	{  22, 3, IEEE80211_T_DS,   3, 203, 107 },
    +	{  12, 0, IEEE80211_T_OFDM, 4,  50,  50 },
    +	{  18, 1, IEEE80211_T_OFDM, 4,  42,  42 },
    +	{  24, 2, IEEE80211_T_OFDM, 6,  38,  38 },
    +	{  36, 3, IEEE80211_T_OFDM, 6,  34,  34 },
    +	{  48, 4, IEEE80211_T_OFDM, 8,  34,  34 },
    +	{  72, 5, IEEE80211_T_OFDM, 8,  30,  30 },
    +	{  96, 6, IEEE80211_T_OFDM, 8,  30,  30 },
    +	{ 108, 7, IEEE80211_T_OFDM, 8,  30,  30 }
    +};
    +
    +/*
    + * Control and status registers access macros.
    + */
    +#define RAL_READ(sc, reg)						\
    +	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
    +
    +#define RAL_WRITE(sc, reg, val)						\
    +	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
    +
    +#define RAL_BARRIER_WRITE(sc)						\
    +	bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, 0x1800,		\
    +	    BUS_SPACE_BARRIER_WRITE)
    +
    +#define RAL_BARRIER_READ_WRITE(sc)					\
    +	bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, 0x1800,		\
    +	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
    +
    +#define RAL_WRITE_REGION_1(sc, offset, datap, count)			\
    +	bus_space_write_region_1((sc)->sc_st, (sc)->sc_sh, (offset),	\
    +	    (datap), (count))
    +
    +#define RAL_SET_REGION_4(sc, offset, val, count)			\
    +	bus_space_set_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
    +	    (val), (count))
    +
    +/*
    + * EEPROM access macro.
    + */
    +#define RT2860_EEPROM_CTL(sc, val) do {					\
    +	RAL_WRITE((sc), RT2860_PCI_EECTRL, (val));			\
    +	RAL_BARRIER_READ_WRITE((sc));					\
    +	DELAY(RT2860_EEPROM_DELAY);					\
    +} while (/* CONSTCOND */0)
    +
    +/*
    + * Default values for MAC registers; values taken from the reference driver.
    + */
    +#define RT2860_DEF_MAC					\
    +	{ RT2860_BCN_OFFSET0,		0xf8f0e8e0 },	\
    +	{ RT2860_LEGACY_BASIC_RATE,	0x0000013f },	\
    +	{ RT2860_HT_BASIC_RATE,		0x00008003 },	\
    +	{ RT2860_MAC_SYS_CTRL,		0x00000000 },	\
    +	{ RT2860_BKOFF_SLOT_CFG,	0x00000209 },	\
    +	{ RT2860_TX_SW_CFG0,		0x00000000 },	\
    +	{ RT2860_TX_SW_CFG1,		0x00080606 },	\
    +	{ RT2860_TX_LINK_CFG,		0x00001020 },	\
    +	{ RT2860_TX_TIMEOUT_CFG,	0x000a2090 },	\
    +	{ RT2860_LED_CFG,		0x7f031e46 },	\
    +	{ RT2860_WMM_AIFSN_CFG,		0x00002273 },	\
    +	{ RT2860_WMM_CWMIN_CFG,		0x00002344 },	\
    +	{ RT2860_WMM_CWMAX_CFG,		0x000034aa },	\
    +	{ RT2860_MAX_PCNT,		0x1f3fbf9f },	\
    +	{ RT2860_TX_RTY_CFG,		0x47d01f0f },	\
    +	{ RT2860_AUTO_RSP_CFG,		0x00000013 },	\
    +	{ RT2860_CCK_PROT_CFG,		0x05740003 },	\
    +	{ RT2860_OFDM_PROT_CFG,		0x05740003 },	\
    +	{ RT2860_GF20_PROT_CFG,		0x01744004 },	\
    +	{ RT2860_GF40_PROT_CFG,		0x03f44084 },	\
    +	{ RT2860_MM20_PROT_CFG,		0x01744004 },	\
    +	{ RT2860_MM40_PROT_CFG,		0x03f54084 },	\
    +	{ RT2860_TXOP_CTRL_CFG,		0x0000583f },	\
    +	{ RT2860_TXOP_HLDR_ET,		0x00000002 },	\
    +	{ RT2860_TX_RTS_CFG,		0x00092b20 },	\
    +	{ RT2860_EXP_ACK_TIME,		0x002400ca },	\
    +	{ RT2860_XIFS_TIME_CFG,		0x33a41010 },	\
    +	{ RT2860_PWR_PIN_CFG,		0x00000003 }
    +
    +/* XXX only a few registers differ from above, try to merge? */
    +#define RT2870_DEF_MAC					\
    +	{ RT2860_BCN_OFFSET0,		0xf8f0e8e0 },	\
    +	{ RT2860_LEGACY_BASIC_RATE,	0x0000013f },	\
    +	{ RT2860_HT_BASIC_RATE,		0x00008003 },	\
    +	{ RT2860_MAC_SYS_CTRL,		0x00000000 },	\
    +	{ RT2860_BKOFF_SLOT_CFG,	0x00000209 },	\
    +	{ RT2860_TX_SW_CFG0,		0x00000000 },	\
    +	{ RT2860_TX_SW_CFG1,		0x00080606 },	\
    +	{ RT2860_TX_LINK_CFG,		0x00001020 },	\
    +	{ RT2860_TX_TIMEOUT_CFG,	0x000a2090 },	\
    +	{ RT2860_LED_CFG,		0x7f031e46 },	\
    +	{ RT2860_WMM_AIFSN_CFG,		0x00002273 },	\
    +	{ RT2860_WMM_CWMIN_CFG,		0x00002344 },	\
    +	{ RT2860_WMM_CWMAX_CFG,		0x000034aa },	\
    +	{ RT2860_MAX_PCNT,		0x1f3fbf9f },	\
    +	{ RT2860_TX_RTY_CFG,		0x47d01f0f },	\
    +	{ RT2860_AUTO_RSP_CFG,		0x00000013 },	\
    +	{ RT2860_CCK_PROT_CFG,		0x05740003 },	\
    +	{ RT2860_OFDM_PROT_CFG,		0x05740003 },	\
    +	{ RT2860_PBF_CFG,		0x00f40006 },	\
    +	{ RT2860_WPDMA_GLO_CFG,		0x00000030 },	\
    +	{ RT2860_GF20_PROT_CFG,		0x01744004 },	\
    +	{ RT2860_GF40_PROT_CFG,		0x03f44084 },	\
    +	{ RT2860_MM20_PROT_CFG,		0x01744004 },	\
    +	{ RT2860_MM40_PROT_CFG,		0x03f44084 },	\
    +	{ RT2860_TXOP_CTRL_CFG,		0x0000583f },	\
    +	{ RT2860_TXOP_HLDR_ET,		0x00000002 },	\
    +	{ RT2860_TX_RTS_CFG,		0x00092b20 },	\
    +	{ RT2860_EXP_ACK_TIME,		0x002400ca },	\
    +	{ RT2860_XIFS_TIME_CFG,		0x33a41010 },	\
    +	{ RT2860_PWR_PIN_CFG,		0x00000003 }
    +
    +/*
    + * Default values for BBP registers; values taken from the reference driver.
    + */
    +#define RT2860_DEF_BBP	\
    +	{  65, 0x2c },	\
    +	{  66, 0x38 },	\
    +	{  69, 0x12 },	\
    +	{  70, 0x0a },	\
    +	{  73, 0x10 },	\
    +	{  81, 0x37 },	\
    +	{  82, 0x62 },	\
    +	{  83, 0x6a },	\
    +	{  84, 0x99 },	\
    +	{  86, 0x00 },	\
    +	{  91, 0x04 },	\
    +	{  92, 0x00 },	\
    +	{ 103, 0x00 },	\
    +	{ 105, 0x05 }
    +
    +/*
    + * Default settings for RF registers; values derived from the reference driver.
    + */
    +#define RT2860_RF2850						\
    +	{   1, 0x100bb3, 0x1301e1, 0x05a014, 0x001402 },	\
    +	{   2, 0x100bb3, 0x1301e1, 0x05a014, 0x001407 },	\
    +	{   3, 0x100bb3, 0x1301e2, 0x05a014, 0x001402 },	\
    +	{   4, 0x100bb3, 0x1301e2, 0x05a014, 0x001407 },	\
    +	{   5, 0x100bb3, 0x1301e3, 0x05a014, 0x001402 },	\
    +	{   6, 0x100bb3, 0x1301e3, 0x05a014, 0x001407 },	\
    +	{   7, 0x100bb3, 0x1301e4, 0x05a014, 0x001402 },	\
    +	{   8, 0x100bb3, 0x1301e4, 0x05a014, 0x001407 },	\
    +	{   9, 0x100bb3, 0x1301e5, 0x05a014, 0x001402 },	\
    +	{  10, 0x100bb3, 0x1301e5, 0x05a014, 0x001407 },	\
    +	{  11, 0x100bb3, 0x1301e6, 0x05a014, 0x001402 },	\
    +	{  12, 0x100bb3, 0x1301e6, 0x05a014, 0x001407 },	\
    +	{  13, 0x100bb3, 0x1301e7, 0x05a014, 0x001402 },	\
    +	{  14, 0x100bb3, 0x1301e8, 0x05a014, 0x001404 },	\
    +	{  36, 0x100bb3, 0x130266, 0x056014, 0x001408 },	\
    +	{  38, 0x100bb3, 0x130267, 0x056014, 0x001404 },	\
    +	{  40, 0x100bb2, 0x1301a0, 0x056014, 0x001400 },	\
    +	{  44, 0x100bb2, 0x1301a0, 0x056014, 0x001408 },	\
    +	{  46, 0x100bb2, 0x1301a1, 0x056014, 0x001402 },	\
    +	{  48, 0x100bb2, 0x1301a1, 0x056014, 0x001406 },	\
    +	{  52, 0x100bb2, 0x1301a2, 0x056014, 0x001404 },	\
    +	{  54, 0x100bb2, 0x1301a2, 0x056014, 0x001408 },	\
    +	{  56, 0x100bb2, 0x1301a3, 0x056014, 0x001402 },	\
    +	{  60, 0x100bb2, 0x1301a4, 0x056014, 0x001400 },	\
    +	{  62, 0x100bb2, 0x1301a4, 0x056014, 0x001404 },	\
    +	{  64, 0x100bb2, 0x1301a4, 0x056014, 0x001408 },	\
    +	{ 100, 0x100bb2, 0x1301ac, 0x05e014, 0x001400 },	\
    +	{ 102, 0x100bb2, 0x1701ac, 0x15e014, 0x001404 },	\
    +	{ 104, 0x100bb2, 0x1701ac, 0x15e014, 0x001408 },	\
    +	{ 108, 0x100bb3, 0x17028c, 0x15e014, 0x001404 },	\
    +	{ 110, 0x100bb3, 0x13028d, 0x05e014, 0x001400 },	\
    +	{ 112, 0x100bb3, 0x13028d, 0x05e014, 0x001406 },	\
    +	{ 116, 0x100bb3, 0x13028e, 0x05e014, 0x001408 },	\
    +	{ 118, 0x100bb3, 0x13028f, 0x05e014, 0x001404 },	\
    +	{ 120, 0x100bb1, 0x1300e0, 0x05e014, 0x001400 },	\
    +	{ 124, 0x100bb1, 0x1300e0, 0x05e014, 0x001404 },	\
    +	{ 126, 0x100bb1, 0x1300e0, 0x05e014, 0x001406 },	\
    +	{ 128, 0x100bb1, 0x1300e0, 0x05e014, 0x001408 },	\
    +	{ 132, 0x100bb1, 0x1300e1, 0x05e014, 0x001402 },	\
    +	{ 134, 0x100bb1, 0x1300e1, 0x05e014, 0x001404 },	\
    +	{ 136, 0x100bb1, 0x1300e1, 0x05e014, 0x001406 },	\
    +	{ 140, 0x100bb1, 0x1300e2, 0x05e014, 0x001400 },	\
    +	{ 149, 0x100bb1, 0x1300e2, 0x05e014, 0x001409 },	\
    +	{ 151, 0x100bb1, 0x1300e3, 0x05e014, 0x001401 },	\
    +	{ 153, 0x100bb1, 0x1300e3, 0x05e014, 0x001403 },	\
    +	{ 157, 0x100bb1, 0x1300e3, 0x05e014, 0x001407 },	\
    +	{ 159, 0x100bb1, 0x1300e3, 0x05e014, 0x001409 },	\
    +	{ 161, 0x100bb1, 0x1300e4, 0x05e014, 0x001401 },	\
    +	{ 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 }
    +
    +#define RT3070_RF3020	\
    +	{ 241, 2, 2 },	\
    +	{ 241, 2, 7 },	\
    +	{ 242, 2, 2 },	\
    +	{ 242, 2, 7 },	\
    +	{ 243, 2, 2 },	\
    +	{ 243, 2, 7 },	\
    +	{ 244, 2, 2 },	\
    +	{ 244, 2, 7 },	\
    +	{ 245, 2, 2 },	\
    +	{ 245, 2, 7 },	\
    +	{ 246, 2, 2 },	\
    +	{ 246, 2, 7 },	\
    +	{ 247, 2, 2 },	\
    +	{ 248, 2, 4 }
    +
    +#define RT3070_DEF_RF	\
    +	{  4, 0x40 },	\
    +	{  5, 0x03 },	\
    +	{  6, 0x02 },	\
    +	{  7, 0x70 },	\
    +	{  9, 0x0f },	\
    +	{ 10, 0x41 },	\
    +	{ 11, 0x21 },	\
    +	{ 12, 0x7b },	\
    +	{ 14, 0x90 },	\
    +	{ 15, 0x58 },	\
    +	{ 16, 0xb3 },	\
    +	{ 17, 0x92 },	\
    +	{ 18, 0x2c },	\
    +	{ 19, 0x02 },	\
    +	{ 20, 0xba },	\
    +	{ 21, 0xdb },	\
    +	{ 24, 0x16 },	\
    +	{ 25, 0x01 },	\
    +	{ 29, 0x1f }
    +
    +#endif	/* _IF_RUNREG_H_ */
    diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
    new file mode 100644
    index 00000000000..a8795a9776a
    --- /dev/null
    +++ b/sys/dev/usb/wlan/if_runvar.h
    @@ -0,0 +1,222 @@
    +/*	$OpenBSD: if_runvar.h,v 1.3 2009/03/26 20:17:27 damien Exp $	*/
    +
    +/*-
    + * Copyright (c) 2008,2009 Damien Bergamini 
    + *	ported to FreeBSD by Akinori Furukoshi 
    + *
    + * Permission to use, copy, modify, and 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 _IF_RUNVAR_H_
    +#define	_IF_RUNVAR_H_
    +
    +#define RUN_MAX_RXSZ			\
    +	MIN(4096, MJUMPAGESIZE)
    +#if 0
    +	(sizeof (uint32_t) +		\
    +	 sizeof (struct rt2860_rxwi) +	\
    +	 sizeof (uint16_t) +		\
    +	 MCLBYTES +			\
    +	 sizeof (struct rt2870_rxd))
    +#endif
    +/* NB: "11" is the maximum number of padding bytes needed for Tx */
    +#define RUN_MAX_TXSZ			\
    +	(sizeof (struct rt2870_txd) +	\
    +	 sizeof (struct rt2860_rxwi) +	\
    +	 MCLBYTES + 11)
    +
    +#define RUN_TX_TIMEOUT	5000	/* ms */
    +
    +/* Tx ring count was 8/endpoint, now 32 for all 4 (or 6) endpoints. */
    +#define RUN_TX_RING_COUNT	32
    +#define RUN_RX_RING_COUNT	1
    +
    +#define RT2870_WCID_MAX		253
    +#define RUN_AID2WCID(aid)	((aid) & 0xff)
    +
    +struct run_rx_radiotap_header {
    +	struct ieee80211_radiotap_header wr_ihdr;
    +	uint8_t		wr_flags;
    +	uint8_t		wr_rate;
    +	uint16_t	wr_chan_freq;
    +	uint16_t	wr_chan_flags;
    +	uint8_t		wr_dbm_antsignal;
    +	uint8_t		wr_antenna;
    +	uint8_t		wr_antsignal;
    +} __packed;
    +
    +#define RUN_RX_RADIOTAP_PRESENT				\
    +	(1 << IEEE80211_RADIOTAP_FLAGS |		\
    +	 1 << IEEE80211_RADIOTAP_RATE |			\
    +	 1 << IEEE80211_RADIOTAP_CHANNEL |		\
    +	 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL |	\
    +	 1 << IEEE80211_RADIOTAP_ANTENNA |		\
    +	 1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)
    +
    +struct run_tx_radiotap_header {
    +	struct ieee80211_radiotap_header wt_ihdr;
    +	uint8_t		wt_flags;
    +	uint8_t		wt_rate;
    +	uint16_t	wt_chan_freq;
    +	uint16_t	wt_chan_flags;
    +	uint8_t		wt_hwqueue;
    +} __packed;
    +
    +#define IEEE80211_RADIOTAP_HWQUEUE 15
    +
    +#define RUN_TX_RADIOTAP_PRESENT				\
    +	(1 << IEEE80211_RADIOTAP_FLAGS |		\
    +	 1 << IEEE80211_RADIOTAP_RATE |			\
    +	 1 << IEEE80211_RADIOTAP_CHANNEL |		\
    +	 1 << IEEE80211_RADIOTAP_HWQUEUE)
    +
    +struct run_softc;
    +
    +struct run_tx_data {
    +	STAILQ_ENTRY(run_tx_data)	next;
    +	struct run_softc	*sc;
    +	struct mbuf		*m;
    +	struct ieee80211_node	*ni;
    +	uint32_t align[0];	/* dummy field */
    +	uint8_t	desc[sizeof(struct rt2870_txd) +
    +		     sizeof(struct rt2860_txwi)];
    +	int			ridx;
    +	uint8_t			mcs;
    +};
    +STAILQ_HEAD(run_tx_data_head, run_tx_data);
    +
    +struct run_node {
    +	struct ieee80211_node	ni;
    +	uint8_t			ridx[IEEE80211_RATE_MAXSIZE];
    +	uint8_t			ctl_ridx[IEEE80211_RATE_MAXSIZE];
    +};
    +
    +struct run_vap {
    +	struct ieee80211vap             vap;
    +	struct ieee80211_beacon_offsets bo;
    +	struct ieee80211_amrr           amrr;
    +	struct ieee80211_amrr_node	amn[RT2870_WCID_MAX + 1];
    +	struct usb_callout              amrr_ch;
    +	struct task                     amrr_task;
    +	uint8_t				amrr_run;
    +#define RUN_AMRR_ON	1
    +#define RUN_AMRR_OFF	0
    +
    +	int                             (*newstate)(struct ieee80211vap *,
    +                                            enum ieee80211_state, int);
    +};
    +#define RUN_VAP(vap)    ((struct run_vap *)(vap))
    +
    +/*
    + * There are 7 bulk endpoints: 1 for RX
    + * and 6 for TX (4 EDCAs + HCCA + Prio).
    + * Update 03-14-2009:  some devices like the Planex GW-US300MiniS
    + * seem to have only 4 TX bulk endpoints (Fukaumi Naoki).
    + */
    +enum {
    +	RUN_BULK_TX_BE,		/* = WME_AC_BE */
    +	RUN_BULK_TX_BK,		/* = WME_AC_BK */
    +	RUN_BULK_TX_VI,		/* = WME_AC_VI */
    +	RUN_BULK_TX_VO,		/* = WME_AC_VO */
    +	RUN_BULK_TX_HCCA,
    +	RUN_BULK_TX_PRIO,
    +	RUN_BULK_RX,
    +	RUN_N_XFER,
    +};
    +
    +#define	RUN_EP_QUEUES	RUN_BULK_RX
    +
    +struct run_endpoint_queue {
    +	struct run_tx_data		tx_data[RUN_TX_RING_COUNT];
    +	struct run_tx_data_head		tx_qh;
    +	struct run_tx_data_head		tx_fh;
    +	uint32_t			tx_nfree;
    +};
    +
    +struct run_softc {
    +	device_t			sc_dev;
    +	struct usb_device		*sc_udev;
    +	struct ifnet			*sc_ifp;
    +	struct run_vap			*sc_rvp;
    +
    +	int				(*sc_srom_read)(struct run_softc *,
    +					    uint16_t, uint16_t *);
    +
    +	const struct firmware		*fwp;
    +
    +	uint32_t			mac_rev;
    +	uint8_t				rf_rev;
    +	uint8_t				freq;
    +	uint8_t				ntxchains;
    +	uint8_t				nrxchains;
    +	int				fixed_ridx;
    +
    +	uint8_t				rf24_20mhz;
    +	uint8_t				rf24_40mhz;
    +	uint8_t				ext_2ghz_lna;
    +	uint8_t				ext_5ghz_lna;
    +	uint8_t				calib_2ghz;
    +	uint8_t				calib_5ghz;
    +	int8_t				txpow1[50];
    +	int8_t				txpow2[50];
    +	int8_t				rssi_2ghz[3];
    +	int8_t				rssi_5ghz[3];
    +	uint8_t				lna[4];
    +
    +	struct {
    +		uint8_t	reg;
    +		uint8_t	val;
    +	}				bbp[8];
    +	uint8_t				leds;
    +	uint16_t			led[3];
    +	uint32_t			txpow20mhz[5];
    +	uint32_t			txpow40mhz_2ghz[5];
    +	uint32_t			txpow40mhz_5ghz[5];
    +
    +	uint8_t				sc_bssid[6];
    +
    +	struct mtx			sc_mtx;
    +
    +	struct run_endpoint_queue	sc_epq[RUN_EP_QUEUES];
    +
    +	struct task			wme_task;
    +	struct task			usb_timeout_task;
    +
    +	struct usb_xfer			*sc_xfer[RUN_N_XFER];
    +
    +	struct mbuf			*rx_m;
    +
    +	int				sifs;
    +
    +	union {
    +		struct run_rx_radiotap_header th;
    +		uint8_t	pad[64];
    +	}				sc_rxtapu;
    +#define sc_rxtap	sc_rxtapu.th
    +	int				sc_rxtap_len;
    +
    +	union {
    +		struct run_tx_radiotap_header th;
    +		uint8_t	pad[64];
    +	}				sc_txtapu;
    +#define sc_txtap	sc_txtapu.th
    +	int				sc_txtap_len;
    +};
    +
    +#define RUN_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
    +#define RUN_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
    +#define RUN_LOCK_ASSERT(sc, t)	mtx_assert(&(sc)->sc_mtx, t)
    +
    +#endif	/* _IF_RUNVAR_H_ */
    diff --git a/sys/modules/Makefile b/sys/modules/Makefile
    index cad745dcc59..aebdcea188c 100644
    --- a/sys/modules/Makefile
    +++ b/sys/modules/Makefile
    @@ -238,6 +238,7 @@ SUBDIR=	${_3dfx} \
     	re \
     	reiserfs \
     	rl \
    +	runfw \
     	${_s3} \
     	${_safe} \
     	${_sbni} \
    diff --git a/sys/modules/runfw/Makefile b/sys/modules/runfw/Makefile
    new file mode 100644
    index 00000000000..ded04083440
    --- /dev/null
    +++ b/sys/modules/runfw/Makefile
    @@ -0,0 +1,8 @@
    +# $FreeBSD$
    +
    +.PATH: ${.CURDIR}/../../contrib/dev/run
    +
    +KMOD=	runfw
    +FIRMWS=	run-rt2870:runfw:1
    +
    +.include 
    diff --git a/sys/modules/usb/Makefile b/sys/modules/usb/Makefile
    index 09ad669fe1e..7f43e2bcc08 100644
    --- a/sys/modules/usb/Makefile
    +++ b/sys/modules/usb/Makefile
    @@ -27,7 +27,7 @@
     
     SUBDIR = usb
     SUBDIR += ehci musb ohci uhci uss820dci ${_at91dci} ${_atmegadci}
    -SUBDIR += rum uath upgt ural zyd ${_urtw}
    +SUBDIR += rum run uath upgt ural zyd ${_urtw}
     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
    diff --git a/sys/modules/usb/run/Makefile b/sys/modules/usb/run/Makefile
    new file mode 100644
    index 00000000000..5acada486ff
    --- /dev/null
    +++ b/sys/modules/usb/run/Makefile
    @@ -0,0 +1,36 @@
    +#
    +# $FreeBSD$
    +#
    +# Copyright (c) 2010 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/wlan
    +
    +KMOD=	if_run
    +SRCS=	opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h usbdevs.h \
    +	if_run.c
    +
    +.include 
    
    From 13548b8bd0a940c99d9daead964622f426fc700b Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:15:16 +0000
    Subject: [PATCH 1851/2592] MFC r203137
    
     Release the firmware after loading to the device.
    ---
     sys/dev/usb/wlan/if_run.c    | 42 ++++++++++++++++++++++++------------
     sys/dev/usb/wlan/if_runvar.h |  2 --
     2 files changed, 28 insertions(+), 16 deletions(-)
    
    diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
    index 92acd470467..edde487b24d 100644
    --- a/sys/dev/usb/wlan/if_run.c
    +++ b/sys/dev/usb/wlan/if_run.c
    @@ -803,22 +803,25 @@ int
     run_load_microcode(struct run_softc *sc)
     {
     	usb_device_request_t req;
    +	const struct firmware *fw;
     	const u_char *base;
     	uint32_t tmp;
     	int ntries, error;
     	const uint64_t *temp;
     	uint64_t bytes;
     
    -	if((sc->fwp = firmware_get("runfw")) == NULL){
    +	fw = firmware_get("runfw");
    +	if(fw == NULL){
     		printf("%s: failed loadfirmware of file %s (error %d)\n",
     		    device_get_nameunit(sc->sc_dev), "runfw", ENOENT);
     		return ENOENT;
     	}
     
    -	if (sc->fwp->datasize != 8192) {
    +	if (fw->datasize != 8192) {
     		printf("%s: invalid firmware size (should be 8KB)\n",
     		    device_get_nameunit(sc->sc_dev));
    -		return EINVAL;
    +		error = EINVAL;
    +		goto fail;
     	}
     
     	/*
    @@ -827,7 +830,7 @@ run_load_microcode(struct run_softc *sc)
     	 * first half (4KB) is for rt2870,
     	 * last half is for rt3071.
     	 */
    -	base = sc->fwp->data;
    +	base = fw->data;
     	if ((sc->mac_rev >> 16) != 0x2860 &&
     	    (sc->mac_rev >> 16) != 0x2872 &&
     	    (sc->mac_rev >> 16) != 0x3070 &&
    @@ -840,10 +843,14 @@ run_load_microcode(struct run_softc *sc)
     		    device_get_nameunit(sc->sc_dev));
     
     	/* cheap sanity check */
    -	temp = sc->fwp->data;
    +	temp = fw->data;
     	bytes = *temp;
    -	if(bytes != be64toh(0xffffff0210280210))
    -		return EINVAL;
    +	if(bytes != be64toh(0xffffff0210280210)) {
    +		printf("%s: firmware checksum failed\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		error = EINVAL;
    +		goto fail;
    +	}
     
     	run_read(sc, RT2860_ASIC_VER_ID, &tmp);
     	/* write microcode image */
    @@ -856,19 +863,23 @@ run_load_microcode(struct run_softc *sc)
     	USETW(req.wValue, 8);
     	USETW(req.wIndex, 0);
     	USETW(req.wLength, 0);
    -	if ((error = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL)) != 0)
    -		return error;
    +	if ((error = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL)) != 0) {
    +		printf("%s: firmware reset failed\n",
    +		    device_get_nameunit(sc->sc_dev));
    +		goto fail;
    +	}
     
     	run_delay(sc, 10);
     
     	run_write(sc, RT2860_H2M_MAILBOX, 0);
     	if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_BOOT, 0)) != 0)
    -		return error;
    +		goto fail;
     
     	/* wait until microcontroller is ready */
     	for (ntries = 0; ntries < 1000; ntries++) {
    -		if ((error = run_read(sc, RT2860_SYS_CTRL, &tmp)) != 0)
    -			return error;
    +		if ((error = run_read(sc, RT2860_SYS_CTRL, &tmp)) != 0) {
    +			goto fail;
    +		}
     		if (tmp & RT2860_MCU_READY)
     			break;
     		run_delay(sc, 10);
    @@ -876,11 +887,14 @@ run_load_microcode(struct run_softc *sc)
     	if (ntries == 1000) {
     		printf("%s: timeout waiting for MCU to initialize\n",
     		    device_get_nameunit(sc->sc_dev));
    -		return ETIMEDOUT;
    +		error = ETIMEDOUT;
    +		goto fail;
     	}
     	DPRINTF("microcode successfully loaded after %d tries\n", ntries);
     
    -	return 0;
    +fail:
    +	firmware_put(fw, FIRMWARE_UNLOAD);
    +	return (error);
     }
     
     int
    diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
    index a8795a9776a..28d6feb52b1 100644
    --- a/sys/dev/usb/wlan/if_runvar.h
    +++ b/sys/dev/usb/wlan/if_runvar.h
    @@ -154,8 +154,6 @@ struct run_softc {
     	int				(*sc_srom_read)(struct run_softc *,
     					    uint16_t, uint16_t *);
     
    -	const struct firmware		*fwp;
    -
     	uint32_t			mac_rev;
     	uint8_t				rf_rev;
     	uint8_t				freq;
    
    From 7e2c44f0087e0e6a7446362d500e7de65618e637 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:15:44 +0000
    Subject: [PATCH 1852/2592] MFC r203138
    
     Use device_printf rather than printf + device_get_nameunit.
    ---
     sys/dev/usb/wlan/if_run.c | 51 ++++++++++++++++-----------------------
     1 file changed, 21 insertions(+), 30 deletions(-)
    
    diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
    index edde487b24d..03fbdf1bed2 100644
    --- a/sys/dev/usb/wlan/if_run.c
    +++ b/sys/dev/usb/wlan/if_run.c
    @@ -535,8 +535,8 @@ run_attach(device_t self)
     		run_delay(sc, 10);
     	}
     	if (ntries == 100) {
    -		printf("%s: timeout waiting for NIC to initialize\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev,
    +		    "timeout waiting for NIC to initialize\n");
     		RUN_UNLOCK(sc);
     		goto detach;
     	}
    @@ -544,14 +544,13 @@ run_attach(device_t self)
     	/* retrieve RF rev. no and various other things from EEPROM */
     	run_read_eeprom(sc);
     
    -	printf("%s: MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), "
    -	    "address %s\n", device_get_nameunit(sc->sc_dev), sc->mac_rev >> 16,
    -	    sc->mac_rev & 0xffff, run_get_rf(sc->rf_rev), sc->ntxchains,
    -	    sc->nrxchains, ether_sprintf(sc->sc_bssid));
    +	device_printf(sc->sc_dev,
    +	    "MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), address %s\n",
    +	    sc->mac_rev >> 16, sc->mac_rev & 0xffff, run_get_rf(sc->rf_rev),
    +	    sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid));
     
     	if ((error = run_load_microcode(sc)) != 0) {
    -		printf("%s: could not load 8051 microcode\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev, "could not load 8051 microcode\n");
     		RUN_UNLOCK(sc);
     		goto detach;
     	}
    @@ -560,8 +559,7 @@ run_attach(device_t self)
     
     	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
     	if(ifp == NULL){
    -		printf("%s: can not if_alloc()\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev, "can not if_alloc()\n");
     		goto detach;
     	}
     	ic = ifp->if_l2com;
    @@ -812,14 +810,14 @@ run_load_microcode(struct run_softc *sc)
     
     	fw = firmware_get("runfw");
     	if(fw == NULL){
    -		printf("%s: failed loadfirmware of file %s (error %d)\n",
    -		    device_get_nameunit(sc->sc_dev), "runfw", ENOENT);
    +		device_printf(sc->sc_dev,
    +		    "failed loadfirmware of file %s\n", "runfw");
     		return ENOENT;
     	}
     
     	if (fw->datasize != 8192) {
    -		printf("%s: invalid firmware size (should be 8KB)\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev,
    +		    "invalid firmware size (should be 8KB)\n");
     		error = EINVAL;
     		goto fail;
     	}
    @@ -836,18 +834,15 @@ run_load_microcode(struct run_softc *sc)
     	    (sc->mac_rev >> 16) != 0x3070 &&
     	    (sc->mac_rev >> 16) != 0x3572){
     		base += 4096;
    -		printf("%s: You are using firmware RT3071.\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev, "loading RT3071 firmware\n");
     	} else
    -		printf("%s: You are using firmware RT2870.\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev, "loading RT2870 firmware\n");
     
     	/* cheap sanity check */
     	temp = fw->data;
     	bytes = *temp;
     	if(bytes != be64toh(0xffffff0210280210)) {
    -		printf("%s: firmware checksum failed\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev, "firmware checksum failed\n");
     		error = EINVAL;
     		goto fail;
     	}
    @@ -864,8 +859,7 @@ run_load_microcode(struct run_softc *sc)
     	USETW(req.wIndex, 0);
     	USETW(req.wLength, 0);
     	if ((error = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL)) != 0) {
    -		printf("%s: firmware reset failed\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev, "firmware reset failed\n");
     		goto fail;
     	}
     
    @@ -885,8 +879,8 @@ run_load_microcode(struct run_softc *sc)
     		run_delay(sc, 10);
     	}
     	if (ntries == 1000) {
    -		printf("%s: timeout waiting for MCU to initialize\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev,
    +		    "timeout waiting for MCU to initialize\n");
     		error = ETIMEDOUT;
     		goto fail;
     	}
    @@ -3892,8 +3886,7 @@ run_init_locked(struct run_softc *sc)
     		run_delay(sc, 10);
     	}
     	if (ntries == 100) {
    -		printf("%s: timeout waiting for DMA engine\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev, "timeout waiting for DMA engine\n");
     		goto fail;
     	}
     	tmp &= 0xff0;
    @@ -3909,8 +3902,7 @@ run_init_locked(struct run_softc *sc)
     	run_write(sc, RT2860_USB_DMA_CFG, 0);
     
     	if (run_reset(sc) != 0) {
    -		printf("%s: could not reset chipset\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev, "could not reset chipset\n");
     		goto fail;
     	}
     
    @@ -3954,8 +3946,7 @@ run_init_locked(struct run_softc *sc)
     	run_delay(sc, 10);
     
     	if (run_bbp_init(sc) != 0) {
    -		printf("%s: could not initialize BBP\n",
    -		    device_get_nameunit(sc->sc_dev));
    +		device_printf(sc->sc_dev, "could not initialize BBP\n");
     		goto fail;
     	}
     
    
    From 3f3b0d48a9f65cf2bbc58988571398ab52f1e612 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:16:09 +0000
    Subject: [PATCH 1853/2592] MFC r203139
    
     Add device ID.
    
    PR:		usb/142427
    ---
     sys/dev/usb/wlan/if_rum.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
    index 316bbec881e..d4103bc597c 100644
    --- a/sys/dev/usb/wlan/if_rum.c
    +++ b/sys/dev/usb/wlan/if_rum.c
    @@ -104,6 +104,7 @@ static const struct usb_device_id rum_devs[] = {
         RUM_DEV(COREGA, CGWLUSB2GPX),
         RUM_DEV(DICKSMITH, CWD854F),
         RUM_DEV(DICKSMITH, RT2573),
    +    RUM_DEV(EDIMAX, EW7318USG),
         RUM_DEV(DLINK2, DWLG122C1),
         RUM_DEV(DLINK2, WUA1340),
         RUM_DEV(DLINK2, DWA111),
    
    From a67855641134e9beca3e3f48898f1f7e63a67711 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:16:40 +0000
    Subject: [PATCH 1854/2592] MFC r203140
    
     Optimise EHCI ISOC HS done check.
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/controller/ehci.c | 17 +++++++----------
     1 file changed, 7 insertions(+), 10 deletions(-)
    
    diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c
    index 952dd983edd..03ecc377c3e 100644
    --- a/sys/dev/usb/controller/ehci.c
    +++ b/sys/dev/usb/controller/ehci.c
    @@ -1340,25 +1340,22 @@ ehci_check_transfer(struct usb_xfer *xfer)
     		}
     	} else if (methods == &ehci_device_isoc_hs_methods) {
     		ehci_itd_t *td;
    +		uint8_t n = (xfer->nframes & 7);
     
     		/* isochronous high speed transfer */
     
    +		/* check last transfer */
     		td = xfer->td_transfer_last;
     		usb_pc_cpu_invalidate(td->page_cache);
    -		status =
    -		    td->itd_status[0] | td->itd_status[1] |
    -		    td->itd_status[2] | td->itd_status[3] |
    -		    td->itd_status[4] | td->itd_status[5] |
    -		    td->itd_status[6] | td->itd_status[7];
    +		if (n == 0)
    +			status = td->itd_status[7];
    +		else
    +			status = td->itd_status[n-1];
     
     		/* also check first transfer */
     		td = xfer->td_transfer_first;
     		usb_pc_cpu_invalidate(td->page_cache);
    -		status |=
    -		    td->itd_status[0] | td->itd_status[1] |
    -		    td->itd_status[2] | td->itd_status[3] |
    -		    td->itd_status[4] | td->itd_status[5] |
    -		    td->itd_status[6] | td->itd_status[7];
    +		status |= td->itd_status[0];
     
     		/* if no transactions are active we continue */
     		if (!(status & htohc32(sc, EHCI_ITD_ACTIVE))) {
    
    From e7cccdd19ab71643750187b4f1a952c60449884c Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:17:13 +0000
    Subject: [PATCH 1855/2592] MFC r203141
    
     Attempt to recover on a TX error rather than stopping all transfers.
    
    Submitted by:	Hans Petter Selesky
    ---
     sys/dev/usb/wlan/if_rum.c | 13 +++++++++----
     sys/dev/usb/wlan/if_zyd.c | 13 +++++++++----
     2 files changed, 18 insertions(+), 8 deletions(-)
    
    diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
    index d4103bc597c..0cd394d1444 100644
    --- a/sys/dev/usb/wlan/if_rum.c
    +++ b/sys/dev/usb/wlan/if_rum.c
    @@ -845,13 +845,18 @@ tr_setup:
     			usbd_xfer_set_priv(xfer, NULL);
     		}
     
    -		if (error == USB_ERR_STALLED) {
    -			/* try to clear stall first */
    +		if (error != USB_ERR_CANCELLED) {
    +			if (error == USB_ERR_TIMEOUT)
    +				device_printf(sc->sc_dev, "device timeout\n");
    +
    +			/*
    +			 * Try to clear stall first, also if other
    +			 * errors occur, hence clearing stall
    +			 * introduces a 50 ms delay:
    +			 */
     			usbd_xfer_set_stall(xfer);
     			goto tr_setup;
     		}
    -		if (error == USB_ERR_TIMEOUT)
    -			device_printf(sc->sc_dev, "device timeout\n");
     		break;
     	}
     }
    diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
    index 6fa07c7af2f..724bfaaf957 100644
    --- a/sys/dev/usb/wlan/if_zyd.c
    +++ b/sys/dev/usb/wlan/if_zyd.c
    @@ -2449,13 +2449,18 @@ tr_setup:
     		if (data != NULL)
     			zyd_tx_free(data, error);
     
    -		if (error == USB_ERR_STALLED) {
    -			/* try to clear stall first */
    +		if (error != USB_ERR_CANCELLED) {
    +			if (error == USB_ERR_TIMEOUT)
    +				device_printf(sc->sc_dev, "device timeout\n");
    +
    +			/*
    +			 * Try to clear stall first, also if other
    +			 * errors occur, hence clearing stall
    +			 * introduces a 50 ms delay:
    +			 */
     			usbd_xfer_set_stall(xfer);
     			goto tr_setup;
     		}
    -		if (error == USB_ERR_TIMEOUT)
    -			device_printf(sc->sc_dev, "device timeout\n");
     		break;
     	}
     }
    
    From fe5c7a4e819facb52239435265be817b7ec647a9 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:17:43 +0000
    Subject: [PATCH 1856/2592] MFC r203142
    
     Sync usb products to perforce.
    ---
     sys/dev/usb/usbdevs | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index e18f7be2c1a..373d06ca1b0 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -1117,6 +1117,7 @@ product CCYU ED1064		0x2136	EasyDisk ED1064
     
     /* Century products */
     product CENTURY EX35QUAT	0x011e	Century USB Disk Enclosure
    +product CENTURY EX35SW4_SB4	0x011f	Century USB Disk Enclosure
     
     /* Cherry products */
     product CHERRY MY3000KBD	0x0001	My3000 keyboard
    @@ -1336,6 +1337,7 @@ product DLINK3 DWM652		0x3e04	DWM-652
     
     /* DMI products */
     product DMI CFSM_RW		0xa109	CF/SM Reader/Writer
    +product DMI DISK		0x2bcf	Generic Disk
     
     /* DrayTek products */
     product DRAYTEK VIGOR550	0x0550	Vigor550
    @@ -2147,6 +2149,7 @@ product NETGEAR3 WG111T		0x4250	WG111T
     product NETGEAR3 WG111T_NF	0x4251	WG111T (no firmware)
     product NETGEAR3 WPN111		0x5f00	WPN111
     product NETGEAR3 WPN111_NF	0x5f01	WPN111 (no firmware)
    +product NETGEAR3 WPN111_2	0x5f02	WPN111
     
     /* Nikon products */
     product NIKON E990		0x0102	Digital Camera E990
    
    From 401b356e9bfd7a08994a7380b6b5d48eec69638a Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:18:09 +0000
    Subject: [PATCH 1857/2592] MFC r203143
    
     Add the Netgear WPN111
    ---
     sys/dev/usb/wlan/if_uath.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
    index 686f9b629e9..4c8e4ea96c9 100644
    --- a/sys/dev/usb/wlan/if_uath.c
    +++ b/sys/dev/usb/wlan/if_uath.c
    @@ -188,6 +188,7 @@ static const struct usb_device_id uath_devs[] = {
     	UATH_DEV(NETGEAR,		WG111U),
     	UATH_DEV(NETGEAR3,		WG111T),
     	UATH_DEV(NETGEAR3,		WPN111),
    +	UATH_DEV(NETGEAR3,		WPN111_2),
     	UATH_DEV(UMEDIA,		TEW444UBEU),
     	UATH_DEV(UMEDIA,		AR5523_2),
     	UATH_DEV(UMEDIA,		AR5523_3),
    
    From ce176213dd1d24b364befe20738923bf7ef5e33f Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:18:41 +0000
    Subject: [PATCH 1858/2592] MFC r203144
    
     Add null check on quirk lookup and add a couple of umass quirks.
    
    Submitted by:	Hans Petter Selesky
    ---
     sys/dev/usb/quirk/usb_quirk.c | 12 ++++++++++--
     1 file changed, 10 insertions(+), 2 deletions(-)
    
    diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
    index 63ad120b9c9..5fb862661ce 100644
    --- a/sys/dev/usb/quirk/usb_quirk.c
    +++ b/sys/dev/usb/quirk/usb_quirk.c
    @@ -169,12 +169,14 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
     	USB_QUIRK(CENTURY, EX35QUAT, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
     	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
     	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE),
    +	USB_QUIRK(CENTURY, EX35SW4_SB4, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
     	USB_QUIRK(CYPRESS, XX6830XX, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN,
     	    UQ_MSC_NO_SYNC_CACHE),
     	USB_QUIRK(DESKNOTE, UCR_61S2B, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
     	    UQ_MSC_FORCE_PROTO_SCSI),
     	USB_QUIRK(DMI, CFSM_RW, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI,
     	    UQ_MSC_NO_GETMAXLUN),
    +	USB_QUIRK(DMI, DISK, 0x000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
     	USB_QUIRK(EPSON, STYLUS_875DC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
     	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
     	USB_QUIRK(EPSON, STYLUS_895, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
    @@ -259,8 +261,6 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
     	    UQ_MSC_FORCE_PROTO_SCSI),
     	USB_QUIRK(MITSUMI, CDRRW, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI |
     	    UQ_MSC_FORCE_PROTO_ATAPI),
    -	USB_QUIRK(MITSUMI, FDD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
    -	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
     	USB_QUIRK(MOTOROLA2, E398, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
     	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
     	    UQ_MSC_NO_INQUIRY_EVPD, UQ_MSC_NO_GETMAXLUN),
    @@ -680,6 +680,10 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
     		mtx_lock(&usb_quirk_mtx);
     		pqe = usb_quirk_get_entry(pgq->vid, pgq->pid,
     		    pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 1);
    +		if (pqe == NULL) {
    +			mtx_unlock(&usb_quirk_mtx);
    +			return (EINVAL);
    +		}
     		for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
     			if (pqe->quirks[x] == UQ_NONE) {
     				pqe->quirks[x] = y;
    @@ -714,6 +718,10 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
     		mtx_lock(&usb_quirk_mtx);
     		pqe = usb_quirk_get_entry(pgq->vid, pgq->pid,
     		    pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 0);
    +		if (pqe == NULL) {
    +			mtx_unlock(&usb_quirk_mtx);
    +			return (EINVAL);
    +		}
     		for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
     			if (pqe->quirks[x] == y) {
     				pqe->quirks[x] = UQ_NONE;
    
    From 7ba8e24410f35d74dec3efde97a89726fc213a96 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:19:11 +0000
    Subject: [PATCH 1859/2592] MFC r203145
    
     Simplify attach for UMASS_PROTO_CBI_I mode and change some switch() returns
     into breaks.
    
    Submitted by:	Hans Petter Selesky
    ---
     sys/dev/usb/storage/umass.c | 52 +++++++++++++++++++------------------
     1 file changed, 27 insertions(+), 25 deletions(-)
    
    diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
    index e41e55b7f90..1e99464f3e3 100644
    --- a/sys/dev/usb/storage/umass.c
    +++ b/sys/dev/usb/storage/umass.c
    @@ -671,7 +671,7 @@ static struct usb_config umass_cbi_config[UMASS_T_CBI_MAX] = {
     		.type = UE_INTERRUPT,
     		.endpoint = UE_ADDR_ANY,
     		.direction = UE_DIR_IN,
    -		.flags = {.short_xfer_ok = 1,},
    +		.flags = {.short_xfer_ok = 1,.no_pipe_ok = 1,},
     		.bufsize = sizeof(umass_cbi_sbl_t),
     		.callback = &umass_t_cbi_status_callback,
     		.timeout = 5000,	/* ms */
    @@ -984,9 +984,7 @@ umass_attach(device_t dev)
     
     		err = usbd_transfer_setup(uaa->device,
     		    &uaa->info.bIfaceIndex, sc->sc_xfer, umass_cbi_config,
    -		    (sc->sc_proto & UMASS_PROTO_CBI_I) ?
    -		    UMASS_T_CBI_MAX : (UMASS_T_CBI_MAX - 2), sc,
    -		    &sc->sc_mtx);
    +		    UMASS_T_CBI_MAX, sc, &sc->sc_mtx);
     
     		/* skip reset first time */
     		sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
    @@ -1676,7 +1674,7 @@ umass_t_cbi_reset1_callback(struct usb_xfer *xfer, usb_error_t error)
     	switch (USB_GET_STATE(xfer)) {
     	case USB_ST_TRANSFERRED:
     		umass_transfer_start(sc, UMASS_T_CBI_RESET2);
    -		return;
    +		break;
     
     	case USB_ST_SETUP:
     		/*
    @@ -1723,11 +1721,14 @@ umass_t_cbi_reset1_callback(struct usb_xfer *xfer, usb_error_t error)
     		usbd_xfer_set_frame_len(xfer, 1, sizeof(buf));
     		usbd_xfer_set_frames(xfer, 2);
     		usbd_transfer_submit(xfer);
    -		return;
    +		break;
     
     	default:			/* Error */
    -		umass_tr_error(xfer, error);
    -		return;
    +		if (error == USB_ERR_CANCELLED)
    +			umass_tr_error(xfer, error);
    +		else
    +			umass_transfer_start(sc, UMASS_T_CBI_RESET2);
    +		break;
     
     	}
     }
    @@ -1772,17 +1773,17 @@ tr_transferred:
     		} else {
     			umass_transfer_start(sc, next_xfer);
     		}
    -		return;
    +		break;
     
     	case USB_ST_SETUP:
     		if (usbd_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) {
     			goto tr_transferred;	/* should not happen */
     		}
    -		return;
    +		break;
     
     	default:			/* Error */
     		umass_tr_error(xfer, error);
    -		return;
    +		break;
     
     	}
     }
    @@ -1805,7 +1806,7 @@ umass_t_cbi_command_callback(struct usb_xfer *xfer, usb_error_t error)
     			    (sc, (sc->sc_transfer.dir == DIR_IN) ?
     			    UMASS_T_CBI_DATA_READ : UMASS_T_CBI_DATA_WRITE);
     		}
    -		return;
    +		break;
     
     	case USB_ST_SETUP:
     
    @@ -1844,12 +1845,13 @@ umass_t_cbi_command_callback(struct usb_xfer *xfer, usb_error_t error)
     
     			usbd_transfer_submit(xfer);
     		}
    -		return;
    +		break;
     
     	default:			/* Error */
     		umass_tr_error(xfer, error);
    -		return;
    -
    +		/* skip reset */
    +		sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
    +		break;
     	}
     }
     
    @@ -1885,7 +1887,7 @@ umass_t_cbi_data_read_callback(struct usb_xfer *xfer, usb_error_t error)
     
     		if (sc->sc_transfer.data_rem == 0) {
     			umass_cbi_start_status(sc);
    -			return;
    +			break;
     		}
     		if (max_bulk > sc->sc_transfer.data_rem) {
     			max_bulk = sc->sc_transfer.data_rem;
    @@ -1899,7 +1901,7 @@ umass_t_cbi_data_read_callback(struct usb_xfer *xfer, usb_error_t error)
     		usbd_xfer_set_frame_len(xfer, 0, max_bulk);
     #endif
     		usbd_transfer_submit(xfer);
    -		return;
    +		break;
     
     	default:			/* Error */
     		if ((error == USB_ERR_CANCELLED) ||
    @@ -1908,7 +1910,7 @@ umass_t_cbi_data_read_callback(struct usb_xfer *xfer, usb_error_t error)
     		} else {
     			umass_transfer_start(sc, UMASS_T_CBI_DATA_RD_CS);
     		}
    -		return;
    +		break;
     
     	}
     }
    @@ -1948,7 +1950,7 @@ umass_t_cbi_data_write_callback(struct usb_xfer *xfer, usb_error_t error)
     
     		if (sc->sc_transfer.data_rem == 0) {
     			umass_cbi_start_status(sc);
    -			return;
    +			break;
     		}
     		if (max_bulk > sc->sc_transfer.data_rem) {
     			max_bulk = sc->sc_transfer.data_rem;
    @@ -1965,7 +1967,7 @@ umass_t_cbi_data_write_callback(struct usb_xfer *xfer, usb_error_t error)
     #endif
     
     		usbd_transfer_submit(xfer);
    -		return;
    +		break;
     
     	default:			/* Error */
     		if ((error == USB_ERR_CANCELLED) ||
    @@ -1974,7 +1976,7 @@ umass_t_cbi_data_write_callback(struct usb_xfer *xfer, usb_error_t error)
     		} else {
     			umass_transfer_start(sc, UMASS_T_CBI_DATA_WR_CS);
     		}
    -		return;
    +		break;
     
     	}
     }
    @@ -2035,7 +2037,7 @@ umass_t_cbi_status_callback(struct usb_xfer *xfer, usb_error_t error)
     			(sc->sc_transfer.callback)
     			    (sc, ccb, residue, status);
     
    -			return;
    +			break;
     
     		} else {
     
    @@ -2060,7 +2062,7 @@ umass_t_cbi_status_callback(struct usb_xfer *xfer, usb_error_t error)
     				(sc->sc_transfer.callback)
     				    (sc, ccb, residue, status);
     
    -				return;
    +				break;
     			}
     		}
     
    @@ -2070,13 +2072,13 @@ umass_t_cbi_status_callback(struct usb_xfer *xfer, usb_error_t error)
     tr_setup:
     		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
     		usbd_transfer_submit(xfer);
    -		return;
    +		break;
     
     	default:			/* Error */
     		DPRINTF(sc, UDMASS_CBI, "Failed to read CSW: %s\n",
     		    usbd_errstr(error));
     		umass_tr_error(xfer, error);
    -		return;
    +		break;
     
     	}
     }
    
    From e6fdf62105a1effc02703721e6cad93c224d6511 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:19:43 +0000
    Subject: [PATCH 1860/2592] MFC r203146
    
     Rework cam error handling to fix Mitsumi floppy drives.
    
    Submitted by:	mav
    ---
     sys/dev/usb/storage/umass.c | 16 ++++++++++++----
     1 file changed, 12 insertions(+), 4 deletions(-)
    
    diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
    index 1e99464f3e3..b14bb47e8cb 100644
    --- a/sys/dev/usb/storage/umass.c
    +++ b/sys/dev/usb/storage/umass.c
    @@ -2594,11 +2594,19 @@ umass_cam_cb(struct umass_softc *sc, union ccb *ccb, uint32_t residue,
     
     	default:
     		/*
    -		 * the wire protocol failed and will have recovered
    -		 * (hopefully).  We return an error to CAM and let CAM retry
    -		 * the command if necessary.
    +		 * The wire protocol failed and will hopefully have
    +		 * recovered. We return an error to CAM and let CAM
    +		 * retry the command if necessary. In case of SCSI IO
    +		 * commands we ask the CAM layer to check the
    +		 * condition first. This is a quick hack to make
    +		 * certain devices work.
     		 */
    -		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
    +		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;
    +		} else {
    +			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
    +		}
     		xpt_done(ccb);
     		break;
     	}
    
    From 62bd90e5c70c8208dd32a19d9d2a14278654e7e9 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:20:13 +0000
    Subject: [PATCH 1861/2592] MFC r203506
    
     Properly name the 0x0016 ZTE product as MF633R now that its known.
    ---
     sys/dev/usb/serial/u3g.c | 2 +-
     sys/dev/usb/usbdevs      | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
    index 6fc3651a81a..4e92ac34e06 100644
    --- a/sys/dev/usb/serial/u3g.c
    +++ b/sys/dev/usb/serial/u3g.c
    @@ -362,7 +362,6 @@ static const struct usb_device_id u3g_devs[] = {
     	U3G_DEV(QUALCOMMINC, E0012, 0),
     	U3G_DEV(QUALCOMMINC, E0013, 0),
     	U3G_DEV(QUALCOMMINC, E0014, 0),
    -	U3G_DEV(QUALCOMMINC, E0016, 0),
     	U3G_DEV(QUALCOMMINC, E0017, 0),
     	U3G_DEV(QUALCOMMINC, E0018, 0),
     	U3G_DEV(QUALCOMMINC, E0019, 0),
    @@ -409,6 +408,7 @@ static const struct usb_device_id u3g_devs[] = {
     	U3G_DEV(QUALCOMMINC, E2003, 0),
     	U3G_DEV(QUALCOMMINC, MF626, 0),
     	U3G_DEV(QUALCOMMINC, MF628, 0),
    +	U3G_DEV(QUALCOMMINC, MF633R, 0),
     	U3G_DEV(QUANTA, GKE, 0),
     	U3G_DEV(QUANTA, GLE, 0),
     	U3G_DEV(QUANTA, GLX, 0),
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index 373d06ca1b0..d10c13da1a8 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -2430,7 +2430,7 @@ product QUALCOMMINC E0012	0x0012	3G modem
     product QUALCOMMINC E0013	0x0013	3G modem
     product QUALCOMMINC E0014	0x0014	3G modem
     product QUALCOMMINC MF628	0x0015	3G modem
    -product QUALCOMMINC E0016	0x0016	3G modem
    +product QUALCOMMINC MF633R	0x0016	ZTE WCDMA modem
     product QUALCOMMINC E0017	0x0017	3G modem
     product QUALCOMMINC E0018	0x0018	3G modem
     product QUALCOMMINC E0019	0x0019	3G modem
    
    From 9f524548aa5eb9762cbd553e2d075853f5369b00 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:20:41 +0000
    Subject: [PATCH 1862/2592] MFC r203507
    
     The ZTE MF633R modem has a different type of cdrom driver disk, add the product
     ID and use a standard scsi eject.
    
    Reported by:	Patrick Lamaiziere
    ---
     sys/dev/usb/serial/u3g.c | 1 +
     sys/dev/usb/usbdevs      | 1 +
     2 files changed, 2 insertions(+)
    
    diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
    index 4e92ac34e06..0c67ed8e0b5 100644
    --- a/sys/dev/usb/serial/u3g.c
    +++ b/sys/dev/usb/serial/u3g.c
    @@ -498,6 +498,7 @@ static const struct usb_device_id u3g_devs[] = {
     	U3G_DEV(NOVATEL, ZEROCD, U3GINIT_SCSIEJECT),
     	U3G_DEV(OPTION, GTICON322, U3GINIT_REZERO),
     	U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GINIT_ZTESTOR),
    +	U3G_DEV(QUALCOMMINC, ZTE_STOR2, U3GINIT_SCSIEJECT),
     	U3G_DEV(SIERRA, TRUINSTALL, U3GINIT_SIERRA),
     #undef	U3G_DEV
     };
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index d10c13da1a8..9a4ba17b423 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -2456,6 +2456,7 @@ product QUALCOMMINC E0048	0x0048	3G modem
     product QUALCOMMINC E0049	0x0049	3G modem
     product QUALCOMMINC E0051	0x0051	3G modem
     product QUALCOMMINC E0052	0x0052	3G modem
    +product QUALCOMMINC ZTE_STOR2	0x0053	USB ZTE Storage
     product QUALCOMMINC E0054	0x0054	3G modem
     product QUALCOMMINC E0055	0x0055	3G modem
     product QUALCOMMINC E0057	0x0057	3G modem
    
    From 9081202938e737a0c2da484600a38b3b922b846e Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:21:06 +0000
    Subject: [PATCH 1863/2592] MFC r203693
    
     Disable the use of the IAAD usb doorbell on NVidia controllers as it can cause
     the hardware to stall.
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/controller/ehci.c     | 19 +++++++++++++++++++
     sys/dev/usb/controller/ehci.h     |  1 +
     sys/dev/usb/controller/ehci_pci.c | 13 +++++++++++++
     3 files changed, 33 insertions(+)
    
    diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c
    index 03ecc377c3e..28ad987b31d 100644
    --- a/sys/dev/usb/controller/ehci.c
    +++ b/sys/dev/usb/controller/ehci.c
    @@ -92,15 +92,23 @@ __FBSDID("$FreeBSD$");
     #if USB_DEBUG
     static int ehcidebug = 0;
     static int ehcinohighspeed = 0;
    +static int ehciiaadbug = 0;
    +static int ehcilostintrbug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci");
     SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW,
         &ehcidebug, 0, "Debug level");
     SYSCTL_INT(_hw_usb_ehci, OID_AUTO, no_hs, CTLFLAG_RW,
         &ehcinohighspeed, 0, "Disable High Speed USB");
    +SYSCTL_INT(_hw_usb_ehci, OID_AUTO, iaadbug, CTLFLAG_RW,
    +    &ehciiaadbug, 0, "Enable doorbell bug workaround");
    +SYSCTL_INT(_hw_usb_ehci, OID_AUTO, lostintrbug, CTLFLAG_RW,
    +    &ehcilostintrbug, 0, "Enable lost interrupt bug workaround");
     
     TUNABLE_INT("hw.usb.ehci.debug", &ehcidebug);
     TUNABLE_INT("hw.usb.ehci.no_hs", &ehcinohighspeed);
    +TUNABLE_INT("hw.usb.ehci.iaadbug", &ehciiaadbug);
    +TUNABLE_INT("hw.usb.ehci.lostintrbug", &ehcilostintrbug);
     
     static void ehci_dump_regs(ehci_softc_t *sc);
     static void ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *sqh);
    @@ -251,6 +259,10 @@ ehci_init(ehci_softc_t *sc)
     	usb_callout_init_mtx(&sc->sc_tmo_poll, &sc->sc_bus.bus_mtx, 0);
     
     #if USB_DEBUG
    +	if (ehciiaadbug)
    +		sc->sc_flags |= EHCI_SCFLG_IAADBUG;
    +	if (ehcilostintrbug)
    +		sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG;
     	if (ehcidebug > 2) {
     		ehci_dump_regs(sc);
     	}
    @@ -2280,6 +2292,13 @@ ehci_device_bulk_start(struct usb_xfer *xfer)
     	/* put transfer on interrupt queue */
     	ehci_transfer_intr_enqueue(xfer);
     
    +	/* 
    +	 * XXX Certain nVidia chipsets choke when using the IAAD
    +	 * feature too frequently.
    +	 */
    +	if (sc->sc_flags & EHCI_SCFLG_IAADBUG)
    +		return;
    +
     	/* XXX Performance quirk: Some Host Controllers have a too low
     	 * interrupt rate. Issue an IAAD to stimulate the Host
     	 * Controller after queueing the BULK transfer.
    diff --git a/sys/dev/usb/controller/ehci.h b/sys/dev/usb/controller/ehci.h
    index a3d84063c84..b6426c45ca3 100644
    --- a/sys/dev/usb/controller/ehci.h
    +++ b/sys/dev/usb/controller/ehci.h
    @@ -350,6 +350,7 @@ typedef struct ehci_softc {
     #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 */
    +#define	EHCI_SCFLG_IAADBUG	0x0080	/* workaround for nVidia 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 17ec65a512c..c81122b6d5f 100644
    --- a/sys/dev/usb/controller/ehci_pci.c
    +++ b/sys/dev/usb/controller/ehci_pci.c
    @@ -466,6 +466,19 @@ ehci_pci_attach(device_t self)
     		break;
     	}
     
    +	/* Doorbell feature workaround */
    +	switch (pci_get_vendor(self)) {
    +	case PCI_EHCI_VENDORID_NVIDIA:
    +	case PCI_EHCI_VENDORID_NVIDIA2:
    +		sc->sc_flags |= EHCI_SCFLG_IAADBUG;
    +		if (bootverbose)
    +			device_printf(self,
    +			    "Doorbell workaround enabled\n");
    +		break;
    +	default:
    +		break;
    +	}
    +
     	err = ehci_init(sc);
     	if (!err) {
     		err = device_probe_and_attach(sc->sc_bus.bdev);
    
    From 2c50fc457cdad576d5f09fe8e8463c6cee975060 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:21:30 +0000
    Subject: [PATCH 1864/2592] MFC r203896
    
     Detect when we are polling from kernel via cngetc() in the boot process and
     reserve the keypresses so they do not get passed to syscons.
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/input/ukbd.c | 178 +++++++++++++++++++++++++++++++--------
     1 file changed, 144 insertions(+), 34 deletions(-)
    
    diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
    index d7bc2cd1a86..4e4393108b3 100644
    --- a/sys/dev/usb/input/ukbd.c
    +++ b/sys/dev/usb/input/ukbd.c
    @@ -151,6 +151,7 @@ struct ukbd_softc {
     	struct ukbd_data sc_ndata;
     	struct ukbd_data sc_odata;
     
    +	struct thread *sc_poll_thread;
     	struct usb_device *sc_udev;
     	struct usb_interface *sc_iface;
     	struct usb_xfer *sc_xfer[UKBD_N_TRANSFER];
    @@ -174,9 +175,10 @@ struct ukbd_softc {
     #define	UKBD_FLAG_APPLE_SWAP	0x0100
     #define	UKBD_FLAG_TIMER_RUNNING	0x0200
     
    -	int32_t	sc_mode;		/* input mode (K_XLATE,K_RAW,K_CODE) */
    -	int32_t	sc_state;		/* shift/lock key state */
    -	int32_t	sc_accents;		/* accent key index (> 0) */
    +	int	sc_mode;		/* input mode (K_XLATE,K_RAW,K_CODE) */
    +	int	sc_state;		/* shift/lock key state */
    +	int	sc_accents;		/* accent key index (> 0) */
    +	int	sc_poll_tick_last;
     
     	uint16_t sc_inputs;
     	uint16_t sc_inputhead;
    @@ -187,6 +189,7 @@ struct ukbd_softc {
     	uint8_t	sc_iface_no;
     	uint8_t sc_kbd_id;
     	uint8_t sc_led_id;
    +	uint8_t sc_poll_detected;
     };
     
     #define	KEY_ERROR	  0x01
    @@ -281,6 +284,9 @@ static int	ukbd_ioctl(keyboard_t *, u_long, caddr_t);
     static int	ukbd_enable(keyboard_t *);
     static int	ukbd_disable(keyboard_t *);
     static void	ukbd_interrupt(struct ukbd_softc *);
    +static int	ukbd_is_polling(struct ukbd_softc *);
    +static int	ukbd_polls_other_thread(struct ukbd_softc *);
    +static void	ukbd_event_keyinput(struct ukbd_softc *);
     
     static device_probe_t ukbd_probe;
     static device_attach_t ukbd_attach;
    @@ -331,8 +337,21 @@ ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait)
     {
     	DPRINTFN(2, "polling\n");
     
    -	if (kdb_active == 0)
    +	/* update stats about last polling event */
    +	sc->sc_poll_tick_last = ticks;
    +	sc->sc_poll_detected = 1;
    +
    +	if (kdb_active == 0) {
    +		while (sc->sc_inputs == 0) {
    +			/* make sure the USB code gets a chance to run */
    +			pause("UKBD", 1);
    +
    +			/* check if we should wait */
    +			if (!wait)
    +				break;
    +		}
     		return;		/* Only poll if KDB is active */
    +	}
     
     	while (sc->sc_inputs == 0) {
     
    @@ -366,9 +385,13 @@ ukbd_get_key(struct ukbd_softc *sc, uint8_t wait)
     		/* start transfer, if not already started */
     		usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);
     	}
    -	if (sc->sc_flags & UKBD_FLAG_POLLING) {
    +
    +	if (ukbd_polls_other_thread(sc))
    +		return (-1);
    +
    +	if (sc->sc_flags & UKBD_FLAG_POLLING)
     		ukbd_do_poll(sc, wait);
    -	}
    +
     	if (sc->sc_inputs == 0) {
     		c = -1;
     	} else {
    @@ -389,14 +412,13 @@ ukbd_interrupt(struct ukbd_softc *sc)
     	uint32_t o_mod;
     	uint32_t now = sc->sc_time_ms;
     	uint32_t dtime;
    -	uint32_t c;
     	uint8_t key;
     	uint8_t i;
     	uint8_t j;
     
    -	if (sc->sc_ndata.keycode[0] == KEY_ERROR) {
    -		goto done;
    -	}
    +	if (sc->sc_ndata.keycode[0] == KEY_ERROR)
    +		return;
    +
     	n_mod = sc->sc_ndata.modifiers;
     	o_mod = sc->sc_odata.modifiers;
     	if (n_mod != o_mod) {
    @@ -469,14 +491,22 @@ pfound:	;
     
     	sc->sc_odata = sc->sc_ndata;
     
    -	bcopy(sc->sc_ntime, sc->sc_otime, sizeof(sc->sc_otime));
    +	memcpy(sc->sc_otime, sc->sc_ntime, sizeof(sc->sc_otime));
    +
    +	ukbd_event_keyinput(sc);
    +}
    +
    +static void
    +ukbd_event_keyinput(struct ukbd_softc *sc)
    +{
    +	int c;
    +
    +	if (ukbd_is_polling(sc))
    +		return;
    +
    +	if (sc->sc_inputs == 0)
    +		return;
     
    -	if (sc->sc_inputs == 0) {
    -		goto done;
    -	}
    -	if (sc->sc_flags & UKBD_FLAG_POLLING) {
    -		goto done;
    -	}
     	if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
     	    KBD_IS_BUSY(&sc->sc_kbd)) {
     		/* let the callback function process the input */
    @@ -488,8 +518,6 @@ pfound:	;
     			c = ukbd_read_char(&sc->sc_kbd, 0);
     		} while (c != NOKEY);
     	}
    -done:
    -	return;
     }
     
     static void
    @@ -499,12 +527,14 @@ ukbd_timeout(void *arg)
     
     	mtx_assert(&Giant, MA_OWNED);
     
    -	if (!(sc->sc_flags & UKBD_FLAG_POLLING)) {
    -		sc->sc_time_ms += 25;	/* milliseconds */
    -	}
    +	sc->sc_time_ms += 25;	/* milliseconds */
    +
     	ukbd_interrupt(sc);
     
    -	if (ukbd_any_key_pressed(sc)) {
    +	/* Make sure any leftover key events gets read out */
    +	ukbd_event_keyinput(sc);
    +
    +	if (ukbd_any_key_pressed(sc) || (sc->sc_inputs != 0)) {
     		ukbd_start_timer(sc);
     	} else {
     		sc->sc_flags &= ~UKBD_FLAG_TIMER_RUNNING;
    @@ -837,6 +867,18 @@ ukbd_attach(device_t dev)
     	 */
     	KBD_PROBE_DONE(kbd);
     
    +	/*
    +	 * Set boot protocol if we need the quirk.
    +	 */
    +	if (usb_test_quirk(uaa, UQ_KBD_BOOTPROTO)) {
    +		err = usbd_req_set_protocol(sc->sc_udev, NULL, 
    +			sc->sc_iface_index, 0);
    +		if (err != USB_ERR_NORMAL_COMPLETION) {
    +			DPRINTF("set protocol error=%s\n", usbd_errstr(err));
    +			goto detach;
    +		}
    +	}
    +
     	/* figure out if there is an ID byte in the data */
     	err = usbd_req_get_hid_desc(uaa->device, NULL, &hid_ptr,
     	    &hid_len, M_TEMP, uaa->info.bIfaceIndex);
    @@ -880,10 +922,14 @@ ukbd_attach(device_t dev)
     	/* ignore if SETIDLE fails, hence it is not crucial */
     	err = usbd_req_set_idle(sc->sc_udev, NULL, sc->sc_iface_index, 0, 0);
     
    +	mtx_lock(&Giant);
    +
     	ukbd_ioctl(kbd, KDSETLED, (caddr_t)&sc->sc_state);
     
     	KBD_INIT_DONE(kbd);
     
    +	mtx_unlock(&Giant);
    +
     	if (kbd_register(kbd) < 0) {
     		goto detach;
     	}
    @@ -925,9 +971,8 @@ ukbd_detach(device_t dev)
     
     	DPRINTF("\n");
     
    -	if (sc->sc_flags & UKBD_FLAG_POLLING) {
    -		panic("cannot detach polled keyboard\n");
    -	}
    +	mtx_lock(&Giant);
    +
     	sc->sc_flags |= UKBD_FLAG_GONE;
     
     	usb_callout_stop(&sc->sc_callout);
    @@ -954,6 +999,8 @@ ukbd_detach(device_t dev)
     	}
     	sc->sc_kbd.kb_flags = 0;
     
    +	mtx_unlock(&Giant);
    +
     	usbd_transfer_unsetup(sc->sc_xfer, UKBD_N_TRANSFER);
     
     	usb_callout_drain(&sc->sc_callout);
    @@ -969,8 +1016,12 @@ ukbd_resume(device_t dev)
     {
     	struct ukbd_softc *sc = device_get_softc(dev);
     
    +	mtx_lock(&Giant);
    +
     	ukbd_clear_state(&sc->sc_kbd);
     
    +	mtx_unlock(&Giant);
    +
     	return (0);
     }
     
    @@ -1076,13 +1127,19 @@ ukbd_check(keyboard_t *kbd)
     			mtx_unlock(&Giant);
     			return (retval);
     		}
    -		ukbd_do_poll(sc, 0);
     	} else {
     		/* XXX the keyboard layer requires Giant */
     		if (!mtx_owned(&Giant))
     			return (0);
     	}
     
    +	/* check if key belongs to this thread */
    +	if (ukbd_polls_other_thread(sc))
    +		return (0);
    +
    +	if (sc->sc_flags & UKBD_FLAG_POLLING)
    +		ukbd_do_poll(sc, 0);
    +
     #ifdef UKBD_EMULATE_ATSCANCODE
     	if (sc->sc_buffered_char[0]) {
     		return (1);
    @@ -1118,6 +1175,10 @@ ukbd_check_char(keyboard_t *kbd)
     			return (0);
     	}
     
    +	/* check if key belongs to this thread */
    +	if (ukbd_polls_other_thread(sc))
    +		return (0);
    +
     	if ((sc->sc_composed_char > 0) &&
     	    (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) {
     		return (1);
    @@ -1156,6 +1217,10 @@ ukbd_read(keyboard_t *kbd, int wait)
     			return (-1);
     	}
     
    +	/* check if key belongs to this thread */
    +	if (ukbd_polls_other_thread(sc))
    +		return (-1);
    +
     #ifdef UKBD_EMULATE_ATSCANCODE
     	if (sc->sc_buffered_char[0]) {
     		scancode = sc->sc_buffered_char[0];
    @@ -1220,6 +1285,10 @@ ukbd_read_char(keyboard_t *kbd, int wait)
     			return (NOKEY);
     	}
     
    +	/* check if key belongs to this thread */
    +	if (ukbd_polls_other_thread(sc))
    +		return (NOKEY);
    +
     next_code:
     
     	/* do we have a composed char to return ? */
    @@ -1419,7 +1488,17 @@ ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
     		 * keyboard system must get out of "Giant" first, before the
     		 * CPU can proceed here ...
     		 */
    -		return (EINVAL);
    +		switch (cmd) {
    +		case KDGKBMODE:
    +		case KDSKBMODE:
    +			/* workaround for Geli */
    +			mtx_lock(&Giant);
    +			i = ukbd_ioctl(kbd, cmd, arg);
    +			mtx_unlock(&Giant);
    +			return (i);
    +		default:
    +			return (EINVAL);
    +		}
     	}
     
     	switch (cmd) {
    @@ -1445,7 +1524,8 @@ ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
     		case K_RAW:
     		case K_CODE:
     			if (sc->sc_mode != *(int *)arg) {
    -				ukbd_clear_state(kbd);
    +				if (ukbd_is_polling(sc) == 0)
    +					ukbd_clear_state(kbd);
     				sc->sc_mode = *(int *)arg;
     			}
     			break;
    @@ -1552,7 +1632,11 @@ ukbd_clear_state(keyboard_t *kbd)
     	struct ukbd_softc *sc = kbd->kb_data;
     
     	if (!mtx_owned(&Giant)) {
    -		return;			/* XXX */
    +		/* XXX cludge */
    +		mtx_lock(&Giant);
    +		ukbd_clear_state(kbd);
    +		mtx_unlock(&Giant);
    +		return;
     	}
     
     	sc->sc_flags &= ~(UKBD_FLAG_COMPOSE | UKBD_FLAG_POLLING);
    @@ -1563,10 +1647,10 @@ ukbd_clear_state(keyboard_t *kbd)
     	sc->sc_buffered_char[0] = 0;
     	sc->sc_buffered_char[1] = 0;
     #endif
    -	bzero(&sc->sc_ndata, sizeof(sc->sc_ndata));
    -	bzero(&sc->sc_odata, sizeof(sc->sc_odata));
    -	bzero(&sc->sc_ntime, sizeof(sc->sc_ntime));
    -	bzero(&sc->sc_otime, sizeof(sc->sc_otime));
    +	memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
    +	memset(&sc->sc_odata, 0, sizeof(sc->sc_odata));
    +	memset(&sc->sc_ntime, 0, sizeof(sc->sc_ntime));
    +	memset(&sc->sc_otime, 0, sizeof(sc->sc_otime));
     }
     
     /* save the internal state, not used */
    @@ -1583,6 +1667,30 @@ ukbd_set_state(keyboard_t *kbd, void *buf, size_t len)
     	return (EINVAL);
     }
     
    +static int
    +ukbd_is_polling(struct ukbd_softc *sc)
    +{
    +	int delta;
    +
    +	if (sc->sc_flags & UKBD_FLAG_POLLING)
    +		return (1);	/* polling */
    +
    +	delta = ticks - sc->sc_poll_tick_last;
    +	if ((delta < 0) || (delta >= hz)) {
    +		sc->sc_poll_detected = 0;
    +		return (0);		/* not polling */
    +	}
    +
    +	return (sc->sc_poll_detected);
    +}
    +
    +static int
    +ukbd_polls_other_thread(struct ukbd_softc *sc)
    +{
    +	return (ukbd_is_polling(sc) &&
    +	    (sc->sc_poll_thread != curthread));
    +}
    +
     static int
     ukbd_poll(keyboard_t *kbd, int on)
     {
    @@ -1599,8 +1707,10 @@ ukbd_poll(keyboard_t *kbd, int on)
     
     	if (on) {
     		sc->sc_flags |= UKBD_FLAG_POLLING;
    +		sc->sc_poll_thread = curthread;
     	} else {
     		sc->sc_flags &= ~UKBD_FLAG_POLLING;
    +		ukbd_start_timer(sc);	/* start timer */
     	}
     	return (0);
     }
    
    From 76e18c912806305f4ae7e8becc176ec45cb6f8c9 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:21:54 +0000
    Subject: [PATCH 1865/2592] MFC r203899
    
     Add UQ_KBD_BOOTPROTO quirk needed in r203896
    ---
     sys/dev/usb/quirk/usb_quirk.c | 1 +
     sys/dev/usb/quirk/usb_quirk.h | 1 +
     2 files changed, 2 insertions(+)
    
    diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
    index 5fb862661ce..aa89fdc6011 100644
    --- a/sys/dev/usb/quirk/usb_quirk.c
    +++ b/sys/dev/usb/quirk/usb_quirk.c
    @@ -459,6 +459,7 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
     	[UQ_BUS_POWERED]	= "UQ_BUS_POWERED",
     	[UQ_HID_IGNORE]		= "UQ_HID_IGNORE",
     	[UQ_KBD_IGNORE]		= "UQ_KBD_IGNORE",
    +	[UQ_KBD_BOOTPROTO]	= "UQ_KBD_BOOTPROTO",
     	[UQ_MS_BAD_CLASS]	= "UQ_MS_BAD_CLASS",
     	[UQ_MS_LEADING_BYTE]	= "UQ_MS_LEADING_BYTE",
     	[UQ_MS_REVZ]		= "UQ_MS_REVZ",
    diff --git a/sys/dev/usb/quirk/usb_quirk.h b/sys/dev/usb/quirk/usb_quirk.h
    index 3187bcacc2c..d68140262ce 100644
    --- a/sys/dev/usb/quirk/usb_quirk.h
    +++ b/sys/dev/usb/quirk/usb_quirk.h
    @@ -45,6 +45,7 @@ enum {	/* keep in sync with usb_quirk_str table */
     	UQ_BUS_POWERED,		/* device is bus powered, despite claim */
     	UQ_HID_IGNORE,		/* device should be ignored by hid class */
     	UQ_KBD_IGNORE,		/* device should be ignored by kbd class */
    +	UQ_KBD_BOOTPROTO,	/* device should set the boot protocol */
     	UQ_MS_BAD_CLASS,	/* doesn't identify properly */
     	UQ_MS_LEADING_BYTE,	/* mouse sends an unknown leading byte */
     	UQ_MS_REVZ,		/* mouse has Z-axis reversed */
    
    From 5aab223c3ca336971f2d7ad8860d95e72422bcb8 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:22:19 +0000
    Subject: [PATCH 1866/2592] MFC r203903
    
     Make umodem more tolerant for devices which modem descriptors are misplaced.
    
    Reported by:	Erick Wales
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/serial/umodem.c | 13 +++++++++----
     1 file changed, 9 insertions(+), 4 deletions(-)
    
    diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c
    index 6945e79e430..39afdad893f 100644
    --- a/sys/dev/usb/serial/umodem.c
    +++ b/sys/dev/usb/serial/umodem.c
    @@ -312,11 +312,16 @@ umodem_attach(device_t dev)
     		    0 - 1, UDESCSUB_CDC_UNION, 0 - 1);
     
     		if ((cud == NULL) || (cud->bLength < sizeof(*cud))) {
    -			device_printf(dev, "no CM or union descriptor\n");
    -			goto detach;
    +			device_printf(dev, "Missing descriptor. "
    +			    "Assuming data interface is next.\n");
    +			if (sc->sc_ctrl_iface_no == 0xFF)
    +				goto detach;
    +			else
    +				sc->sc_data_iface_no = 
    +				    sc->sc_ctrl_iface_no + 1;
    +		} else {
    +			sc->sc_data_iface_no = cud->bSlaveInterface[0];
     		}
    -
    -		sc->sc_data_iface_no = cud->bSlaveInterface[0];
     	} else {
     		sc->sc_data_iface_no = cmd->bDataInterface;
     	}
    
    From 5821ad555bcca6d93694997ec58def070108d44a Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:22:47 +0000
    Subject: [PATCH 1867/2592] MFC r203905
    
     Add support for the E1752 3G modem and the required eject command.
    
    Submitted by:	Milan Obuch
    ---
     sys/dev/usb/serial/u3g.c  | 5 +++++
     sys/dev/usb/usb_msctest.c | 8 ++++++++
     sys/dev/usb/usb_msctest.h | 3 ++-
     sys/dev/usb/usbdevs       | 1 +
     4 files changed, 16 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
    index 0c67ed8e0b5..0d218d548bf 100644
    --- a/sys/dev/usb/serial/u3g.c
    +++ b/sys/dev/usb/serial/u3g.c
    @@ -92,6 +92,7 @@ SYSCTL_INT(_hw_usb_u3g, OID_AUTO, debug, CTLFLAG_RW,
     #define	U3GINIT_CMOTECH		6	/* Requires CMOTECH SCSI command */
     #define	U3GINIT_WAIT		7	/* Device reappears after a delay */
     #define	U3GINIT_SAEL_M460	8	/* Requires vendor init */
    +#define	U3GINIT_HUAWEISCSI	9	/* Requires Huawei SCSI init command */
     
     enum {
     	U3G_BULK_WR,
    @@ -281,6 +282,7 @@ static const struct usb_device_id u3g_devs[] = {
     	U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI),
     	U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI),
     	U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI),
    +	U3G_DEV(HUAWEI, E1752, U3GINIT_HUAWEISCSI),
     	U3G_DEV(KYOCERA2, CDMA_MSM_K, 0),
     	U3G_DEV(KYOCERA2, KPC680, 0),
     	U3G_DEV(MERLIN, V620, 0),
    @@ -649,6 +651,9 @@ u3g_test_autoinst(void *arg, struct usb_device *udev,
     		case U3GINIT_HUAWEI:
     			error = u3g_huawei_init(udev);
     			break;
    +		case U3GINIT_HUAWEISCSI:
    +			error = usb_msc_eject(udev, 0, MSC_EJECT_HUAWEI);
    +			break;
     		case U3GINIT_SCSIEJECT:
     			error = usb_msc_eject(udev, 0, MSC_EJECT_STOPUNIT);
     			break;
    diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c
    index 4325d7980e0..ed9eac40ba7 100644
    --- a/sys/dev/usb/usb_msctest.c
    +++ b/sys/dev/usb/usb_msctest.c
    @@ -94,6 +94,9 @@ static uint8_t scsi_ztestor_eject[] =   { 0x85, 0x01, 0x01, 0x01, 0x18, 0x01,
     					  0x01, 0x01, 0x01, 0x01, 0x00, 0x00 };
     static uint8_t scsi_cmotech_eject[] =   { 0xff, 0x52, 0x44, 0x45, 0x56, 0x43,
     					  0x48, 0x47 };
    +static uint8_t scsi_huawei_eject[] =	{ 0x11, 0x06, 0x00, 0x00, 0x00, 0x00,
    +					  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    +					  0x00, 0x00, 0x00, 0x00 };
     
     #define	BULK_SIZE		64	/* dummy */
     #define	ERR_CSW_FAILED		-1
    @@ -611,6 +614,11 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
     		    &scsi_cmotech_eject, sizeof(scsi_cmotech_eject),
     		    USB_MS_HZ);
     		break;
    +	case MSC_EJECT_HUAWEI:
    +		err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
    +		    &scsi_huawei_eject, sizeof(scsi_huawei_eject),
    +		    USB_MS_HZ);
    +		break;
     	default:
     		printf("usb_msc_eject: unknown eject method (%d)\n", method);
     		break;
    diff --git a/sys/dev/usb/usb_msctest.h b/sys/dev/usb/usb_msctest.h
    index 2310bba29e7..ce763df3fbe 100644
    --- a/sys/dev/usb/usb_msctest.h
    +++ b/sys/dev/usb/usb_msctest.h
    @@ -31,7 +31,8 @@ enum {
     	MSC_EJECT_STOPUNIT,
     	MSC_EJECT_REZERO,
     	MSC_EJECT_ZTESTOR,
    -	MSC_EJECT_CMOTECH
    +	MSC_EJECT_CMOTECH,
    +	MSC_EJECT_HUAWEI,
     };
     
     int usb_iface_is_cdrom(struct usb_device *udev,
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index 9a4ba17b423..0c15275f637 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -1723,6 +1723,7 @@ product HUAWEI E143C		0x143c	3G modem
     product HUAWEI E143D		0x143d	3G modem
     product HUAWEI E143E		0x143e	3G modem
     product HUAWEI E143F		0x143f	3G modem
    +product HUAWEI E1752		0x1446	3G modem
     product HUAWEI E14AC		0x14ac	3G modem
     
     /* HUAWEI 3com products */
    
    From c96e62bb8af19175c2eeb0b3c8c7c100e676a567 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:23:19 +0000
    Subject: [PATCH 1868/2592] MFC r203906
    
     Add device ID for the FTDI 4232H.
    
    PR:		usb/143832
    Submitted by:	UEMURA Tetsuya
    ---
     sys/dev/usb/serial/uftdi.c | 1 +
     sys/dev/usb/usbdevs        | 1 +
     2 files changed, 2 insertions(+)
    
    diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
    index e6eca43c57d..3518a411141 100644
    --- a/sys/dev/usb/serial/uftdi.c
    +++ b/sys/dev/usb/serial/uftdi.c
    @@ -224,6 +224,7 @@ static struct usb_device_id uftdi_devs[] = {
     	UFTDI_DEV(FTDI, SERIAL_8U100AX, SIO),
     	UFTDI_DEV(FTDI, SERIAL_2232C, 8U232AM),
     	UFTDI_DEV(FTDI, SERIAL_2232D, 8U232AM),
    +	UFTDI_DEV(FTDI, SERIAL_4232H, 8U232AM),
     	UFTDI_DEV(FTDI, SERIAL_8U232AM, 8U232AM),
     	UFTDI_DEV(FTDI, SERIAL_8U232AM4, 8U232AM),
     	UFTDI_DEV(FTDI, SEMC_DSS20, 8U232AM),
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index 0c15275f637..bf2e01546d0 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -1472,6 +1472,7 @@ product FTDI SERIAL_8U232AM	0x6001	8U232AM Serial
     product FTDI SERIAL_8U232AM4	0x6004	8U232AM Serial
     product FTDI SERIAL_2232C	0x6010	FT2232C Dual port Serial
     product FTDI SERIAL_2232D	0x9e90	FT2232D Dual port Serial
    +product FTDI SERIAL_4232H	0x6011	FT4232H Quad port Serial
     /* Gude Analog- und Digitalsysteme products also uses FTDI's id: */
     product FTDI TACTRIX_OPENPORT_13M 0xcc48 OpenPort 1.3 Mitsubishi
     product FTDI TACTRIX_OPENPORT_13S 0xcc49 OpenPort 1.3 Subaru
    
    From b766264da8dac96d4199227565e8d8345516aa2a Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:23:43 +0000
    Subject: [PATCH 1869/2592] MFC r205005
    
     Wrap the proc wakeup special case for ddb in ifdef DDB.
    
    Submitted by:	Giovanni Trematerra
    ---
     sys/dev/usb/controller/usb_controller.c | 6 ++++++
     1 file changed, 6 insertions(+)
    
    diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c
    index eb961fcb945..e91904c33e9 100644
    --- a/sys/dev/usb/controller/usb_controller.c
    +++ b/sys/dev/usb/controller/usb_controller.c
    @@ -24,6 +24,8 @@
      * SUCH DAMAGE.
      */
     
    +#include "opt_ddb.h"
    +
     #include 
     #include 
     #include 
    @@ -220,6 +222,7 @@ usb_bus_explore(struct usb_proc_msg *pm)
     			bus->driver_added_refcount = 1;
     		}
     
    +#ifdef DDB
     		/*
     		 * The following three lines of code are only here to
     		 * recover from DDB:
    @@ -227,6 +230,7 @@ usb_bus_explore(struct usb_proc_msg *pm)
     		usb_proc_rewakeup(&bus->control_xfer_proc);
     		usb_proc_rewakeup(&bus->giant_callback_proc);
     		usb_proc_rewakeup(&bus->non_giant_callback_proc);
    +#endif
     
     		USB_BUS_UNLOCK(bus);
     
    @@ -289,11 +293,13 @@ usb_power_wdog(void *arg)
     	usb_callout_reset(&bus->power_wdog,
     	    4 * hz, usb_power_wdog, arg);
     
    +#ifdef DDB
     	/*
     	 * The following line of code is only here to recover from
     	 * DDB:
     	 */
     	usb_proc_rewakeup(&bus->explore_proc);	/* recover from DDB */
    +#endif
     
     	USB_BUS_UNLOCK(bus);
     
    
    From 14c9d510988cb11e88c3fd73047cf5f52878568d Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:24:07 +0000
    Subject: [PATCH 1870/2592] MFC r205026
    
     Reapply r185998 which was overwritten at some point.
    ---
     sys/dev/usb/usbdevs | 3 ---
     1 file changed, 3 deletions(-)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index bf2e01546d0..a67563594df 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -2010,9 +2010,6 @@ product MSI RT3070_7		0x899a	RT3070
     product MSI RT2573_3		0xa861	RT2573
     product MSI RT2573_4		0xa874	RT2573
     
    -/* Microdia products */
    -product MICRODIA TWINKLECAM	0x600d	TwinkleCam USB camera
    -
     /* Microsoft products */
     product MICROSOFT SIDEPREC	0x0008	SideWinder Precision Pro
     product MICROSOFT INTELLIMOUSE	0x0009	IntelliMouse
    
    From a8562ad04680004126f30e7986f34e8d0421c4c3 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:24:29 +0000
    Subject: [PATCH 1871/2592] MFC r205029
    
     Use wMaxPacketSize for the uftdi input buffer size.
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/serial/uftdi.c | 4 +---
     1 file changed, 1 insertion(+), 3 deletions(-)
    
    diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
    index 3518a411141..fe2d494cc02 100644
    --- a/sys/dev/usb/serial/uftdi.c
    +++ b/sys/dev/usb/serial/uftdi.c
    @@ -91,8 +91,6 @@ SYSCTL_INT(_hw_usb_uftdi, OID_AUTO, debug, CTLFLAG_RW,
     #define	UFTDI_CONFIG_INDEX	0
     #define	UFTDI_IFACE_INDEX	0
     
    -#define	UFTDI_IBUFSIZE 64		/* bytes, maximum number of bytes per
    -					 * frame */
     #define	UFTDI_OBUFSIZE 64		/* bytes, cannot be increased due to
     					 * do size encoding */
     
    @@ -173,7 +171,7 @@ static const struct usb_config uftdi_config[UFTDI_N_TRANSFER] = {
     		.type = UE_BULK,
     		.endpoint = UE_ADDR_ANY,
     		.direction = UE_DIR_IN,
    -		.bufsize = UFTDI_IBUFSIZE,
    +		.bufsize = 0,		/* use wMaxPacketSize */
     		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
     		.callback = &uftdi_read_callback,
     	},
    
    From 18fef95d4931cb0d01586ffcd325282b5b20ac09 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:24:55 +0000
    Subject: [PATCH 1872/2592] MFC r205030
    
     - make the usb_temp_setup() and usb_temp_unsetup() functions public so that
       other modules can generate USB descriptors.
     - extend the vendor specific request function by one length pointer argument,
       because not all descriptors store the length in the first byte. For example
       HID descriptors.
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/template/usb_template.c     | 31 ++++++++++---------------
     sys/dev/usb/template/usb_template.h     |  5 +++-
     sys/dev/usb/template/usb_template_mtp.c |  2 +-
     3 files changed, 17 insertions(+), 21 deletions(-)
    
    diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c
    index d3271b24f74..be45ed9cf19 100644
    --- a/sys/dev/usb/template/usb_template.c
    +++ b/sys/dev/usb/template/usb_template.c
    @@ -98,13 +98,10 @@ static void	*usb_temp_get_config_desc(struct usb_device *, uint16_t *,
     static const void *usb_temp_get_string_desc(struct usb_device *, uint16_t,
     		    uint8_t);
     static const void *usb_temp_get_vendor_desc(struct usb_device *,
    -		    const struct usb_device_request *);
    +		    const struct usb_device_request *, uint16_t *plen);
     static const void *usb_temp_get_hub_desc(struct usb_device *);
     static usb_error_t usb_temp_get_desc(struct usb_device *,
     		    struct usb_device_request *, const void **, uint16_t *);
    -static usb_error_t usb_temp_setup(struct usb_device *,
    -		    const struct usb_temp_device_desc *);
    -static void	usb_temp_unsetup(struct usb_device *);
     static usb_error_t usb_temp_setup_by_index(struct usb_device *,
     		    uint16_t index);
     static void	usb_temp_init(void *);
    @@ -1035,7 +1032,7 @@ usb_temp_get_config_desc(struct usb_device *udev,
      *------------------------------------------------------------------------*/
     static const void *
     usb_temp_get_vendor_desc(struct usb_device *udev,
    -    const struct usb_device_request *req)
    +    const struct usb_device_request *req, uint16_t *plen)
     {
     	const struct usb_temp_device_desc *tdd;
     
    @@ -1046,7 +1043,7 @@ usb_temp_get_vendor_desc(struct usb_device *udev,
     	if (tdd->getVendorDesc == NULL) {
     		return (NULL);
     	}
    -	return ((tdd->getVendorDesc) (req));
    +	return ((tdd->getVendorDesc) (req, plen));
     }
     
     /*------------------------------------------------------------------------*
    @@ -1109,7 +1106,6 @@ usb_temp_get_desc(struct usb_device *udev, struct usb_device_request *req,
     		default:
     			goto tr_stalled;
     		}
    -		break;
     	case UT_READ_CLASS_DEVICE:
     		switch (req->bRequest) {
     		case UR_GET_DESCRIPTOR:
    @@ -1117,11 +1113,6 @@ usb_temp_get_desc(struct usb_device *udev, struct usb_device_request *req,
     		default:
     			goto tr_stalled;
     		}
    -		break;
    -	case UT_READ_VENDOR_DEVICE:
    -	case UT_READ_VENDOR_OTHER:
    -		buf = usb_temp_get_vendor_desc(udev, req);
    -		goto tr_valid;
     	default:
     		goto tr_stalled;
     	}
    @@ -1158,7 +1149,6 @@ tr_handle_get_descriptor:
     	default:
     		goto tr_stalled;
     	}
    -	goto tr_stalled;
     
     tr_handle_get_class_descriptor:
     	if (req->wValue[0]) {
    @@ -1168,17 +1158,20 @@ tr_handle_get_class_descriptor:
     	goto tr_valid;
     
     tr_valid:
    -	if (buf == NULL) {
    +	if (buf == NULL)
     		goto tr_stalled;
    -	}
    -	if (len == 0) {
    +	if (len == 0)
     		len = buf[0];
    -	}
     	*pPtr = buf;
     	*pLength = len;
     	return (0);	/* success */
     
     tr_stalled:
    +	/* try to get a vendor specific descriptor */
    +	len = 0;
    +	buf = usb_temp_get_vendor_desc(udev, req, &len);
    +	if (buf != NULL)
    +		goto tr_valid;
     	*pPtr = NULL;
     	*pLength = 0;
     	return (0);	/* we ignore failures */
    @@ -1195,7 +1188,7 @@ tr_stalled:
      *    0: Success
      * Else: Failure
      *------------------------------------------------------------------------*/
    -static usb_error_t
    +usb_error_t
     usb_temp_setup(struct usb_device *udev,
         const struct usb_temp_device_desc *tdd)
     {
    @@ -1285,7 +1278,7 @@ error:
      * This function frees any memory associated with the currently
      * setup template, if any.
      *------------------------------------------------------------------------*/
    -static void
    +void
     usb_temp_unsetup(struct usb_device *udev)
     {
     	if (udev->usb_template_ptr) {
    diff --git a/sys/dev/usb/template/usb_template.h b/sys/dev/usb/template/usb_template.h
    index cc9ca0c08cb..2473af3b4ce 100644
    --- a/sys/dev/usb/template/usb_template.h
    +++ b/sys/dev/usb/template/usb_template.h
    @@ -31,7 +31,7 @@
     #define	_USB_TEMPLATE_H_
     
     typedef const void *(usb_temp_get_string_desc_t)(uint16_t lang_id, uint8_t string_index);
    -typedef const void *(usb_temp_get_vendor_desc_t)(const struct usb_device_request *req);
    +typedef const void *(usb_temp_get_vendor_desc_t)(const struct usb_device_request *req, uint16_t *plen);
     
     struct usb_temp_packet_size {
     	uint16_t mps[USB_SPEED_MAX];
    @@ -98,5 +98,8 @@ extern const struct usb_temp_device_desc usb_template_cdce;
     extern const struct usb_temp_device_desc usb_template_msc;	/* Mass Storage Class */
     extern const struct usb_temp_device_desc usb_template_mtp;	/* Message Transfer
     								 * Protocol */
    +usb_error_t	usb_temp_setup(struct usb_device *,
    +		    const struct usb_temp_device_desc *);
    +void	usb_temp_unsetup(struct usb_device *);
     
     #endif					/* _USB_TEMPLATE_H_ */
    diff --git a/sys/dev/usb/template/usb_template_mtp.c b/sys/dev/usb/template/usb_template_mtp.c
    index a98a242e1f3..40da823cc82 100644
    --- a/sys/dev/usb/template/usb_template_mtp.c
    +++ b/sys/dev/usb/template/usb_template_mtp.c
    @@ -211,7 +211,7 @@ const struct usb_temp_device_desc usb_template_mtp = {
      * Else: Success. Pointer to vendor descriptor is returned.
      *------------------------------------------------------------------------*/
     static const void *
    -mtp_get_vendor_desc(const struct usb_device_request *req)
    +mtp_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
     {
     	static const uint8_t dummy_desc[0x28] = {
     		0x28, 0, 0, 0, 0, 1, 4, 0,
    
    From 15a1f2780d7589106a1706678e2c3598c21bb5db Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:25:19 +0000
    Subject: [PATCH 1873/2592] MFC r205031
    
     It appears that some UVISOR devices do not handle when the clear stall command
     is issued at the beginning of the initial IN/OUT data transfers.  Reason
     unknown, probably firmware fault. Now the stall is only cleared on data
     transfer errors.
    
    PR:		usb/144199
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/serial/uvisor.c | 5 -----
     1 file changed, 5 deletions(-)
    
    diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c
    index 9e6daa97cfa..fbd4afe1c06 100644
    --- a/sys/dev/usb/serial/uvisor.c
    +++ b/sys/dev/usb/serial/uvisor.c
    @@ -345,11 +345,6 @@ uvisor_attach(device_t dev)
     		DPRINTF("could not allocate all pipes\n");
     		goto detach;
     	}
    -	/* clear stall at first run */
    -	mtx_lock(&sc->sc_mtx);
    -	usbd_xfer_set_stall(sc->sc_xfer[UVISOR_BULK_DT_WR]);
    -	usbd_xfer_set_stall(sc->sc_xfer[UVISOR_BULK_DT_RD]);
    -	mtx_unlock(&sc->sc_mtx);
     
     	error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
     	    &uvisor_callback, &sc->sc_mtx);
    
    From 4e4177b3d07dfc90691988125c64555e8db58dd3 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:25:53 +0000
    Subject: [PATCH 1874/2592] MFC r205032
    
     Add new uvisor(4) device ID.
    
    PR:		usb/144201
    ---
     sys/dev/usb/serial/uvisor.c | 1 +
     sys/dev/usb/usbdevs         | 5 +++++
     2 files changed, 6 insertions(+)
    
    diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c
    index fbd4afe1c06..8615c8ab24f 100644
    --- a/sys/dev/usb/serial/uvisor.c
    +++ b/sys/dev/usb/serial/uvisor.c
    @@ -263,6 +263,7 @@ MODULE_DEPEND(uvisor, usb, 1, 1, 1);
     static const struct usb_device_id uvisor_devs[] = {
     #define	UVISOR_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
     	UVISOR_DEV(ACEECA, MEZ1000, UVISOR_FLAG_PALM4),
    +	UVISOR_DEV(ALPHASMART, DANA_SYNC, UVISOR_FLAG_PALM4),
     	UVISOR_DEV(GARMIN, IQUE_3600, UVISOR_FLAG_PALM4),
     	UVISOR_DEV(FOSSIL, WRISTPDA, UVISOR_FLAG_PALM4),
     	UVISOR_DEV(HANDSPRING, VISOR, UVISOR_FLAG_VISOR),
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index a67563594df..35951cc3963 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -407,6 +407,7 @@ vendor STSN		0x07ef	STSN
     vendor CENTURY		0x07f7	Century Corp
     vendor ZOOM		0x0803	Zoom Telephonics
     vendor PCS		0x0810	Personal Communication Systems
    +vendor ALPHASMART	0x081e	AlphaSmart, Inc.
     vendor BROADLOGIC	0x0827	BroadLogic
     vendor HANDSPRING	0x082d	Handspring
     vendor PALM		0x0830	Palm Computing
    @@ -892,6 +893,10 @@ product ALTEC ASC495		0xff05	ASC495 Speakers
     /* Allied Telesyn International products */
     product ALLIEDTELESYN ATUSB100	0xb100	AT-USB100
     
    +/* AlphaSmart, Inc. products */
    +product ALPHASMART DANA_KB	0xdbac	AlphaSmart Dana Keyboard
    +product ALPHASMART DANA_SYNC	0xdf00	AlphaSmart Dana HotSync
    +
     /* Amoi products */
     product AMOI H01		0x0800	H01 3G modem
     product AMOI H01A		0x7002	H01A 3G modem
    
    From 722095f272bba6b9ea56cdd9a50f2826a3fb0663 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:26:17 +0000
    Subject: [PATCH 1875/2592] MFC r205033
    
     isochronous endpoint descriptors should have two more bytes which are zero by
     default.
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/template/usb_template.c | 23 ++++++++++++++++-------
     1 file changed, 16 insertions(+), 7 deletions(-)
    
    diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c
    index be45ed9cf19..80ea15f4ce3 100644
    --- a/sys/dev/usb/template/usb_template.c
    +++ b/sys/dev/usb/template/usb_template.c
    @@ -162,15 +162,23 @@ usb_make_endpoint_desc(struct usb_temp_setup *temp,
     	const void **rd;
     	uint16_t old_size;
     	uint16_t mps;
    -	uint8_t ea = 0;			/* Endpoint Address */
    -	uint8_t et = 0;			/* Endpiont Type */
    +	uint8_t ea;			/* Endpoint Address */
    +	uint8_t et;			/* Endpiont Type */
     
     	/* Reserve memory */
     	old_size = temp->size;
    -	temp->size += sizeof(*ed);
    +
    +	ea = (ted->bEndpointAddress & (UE_ADDR | UE_DIR_IN | UE_DIR_OUT));
    +	et = (ted->bmAttributes & UE_XFERTYPE);
    +
    +	if (et == UE_ISOCHRONOUS) {
    +		/* account for extra byte fields */
    +		temp->size += sizeof(*ed) + 2;
    +	} else {
    +		temp->size += sizeof(*ed);
    +	}
     
     	/* Scan all Raw Descriptors first */
    -
     	rd = ted->ppRawDesc;
     	if (rd) {
     		while (*rd) {
    @@ -192,8 +200,6 @@ usb_make_endpoint_desc(struct usb_temp_setup *temp,
     		/* escape for Zero Max Packet Size */
     		mps = 0;
     	}
    -	ea = (ted->bEndpointAddress & (UE_ADDR | UE_DIR_IN | UE_DIR_OUT));
    -	et = (ted->bmAttributes & UE_XFERTYPE);
     
     	/*
     	 * Fill out the real USB endpoint descriptor
    @@ -201,7 +207,10 @@ usb_make_endpoint_desc(struct usb_temp_setup *temp,
     	 */
     	if (temp->buf) {
     		ed = USB_ADD_BYTES(temp->buf, old_size);
    -		ed->bLength = sizeof(*ed);
    +		if (et == UE_ISOCHRONOUS)
    +			ed->bLength = sizeof(*ed) + 2;
    +		else
    +			ed->bLength = sizeof(*ed);
     		ed->bDescriptorType = UDESC_ENDPOINT;
     		ed->bEndpointAddress = ea;
     		ed->bmAttributes = ted->bmAttributes;
    
    From 252913a125661d9bf31afe46902b4a66eb292833 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:26:40 +0000
    Subject: [PATCH 1876/2592] MFC r205034
    
     For USS820 driver we need to manually reset TX FIFO at each SETUP transaction
     because the chip doesn't do this by itself.
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/controller/uss820dci.c | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c
    index fe14d513c8b..c910c1f21dd 100644
    --- a/sys/dev/usb/controller/uss820dci.c
    +++ b/sys/dev/usb/controller/uss820dci.c
    @@ -333,6 +333,14 @@ uss820dci_setup_rx(struct uss820dci_td *td)
     	} else {
     		sc->sc_dv_addr = 0xFF;
     	}
    +
    +	/* reset TX FIFO */
    +	temp = USS820_READ_1(sc, USS820_TXCON);
    +	temp |= USS820_TXCON_TXCLR;
    +	USS820_WRITE_1(sc, USS820_TXCON, temp);
    +	temp &= ~USS820_TXCON_TXCLR;
    +	USS820_WRITE_1(sc, USS820_TXCON, temp);
    +
     	return (0);			/* complete */
     
     setup_not_complete:
    
    From 33f167cc00a55eb929a0aa121507c4fb35951c7b Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:27:04 +0000
    Subject: [PATCH 1877/2592] MFC r205035
    
     Make sure there is a way to reset the endpoint FIFO on transfer errors for
     ISOCHRONOUS transfers
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/usb_transfer.c | 22 ++++++++++++++++++----
     1 file changed, 18 insertions(+), 4 deletions(-)
    
    diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c
    index e7cb202aef5..9be1c0f4bde 100644
    --- a/sys/dev/usb/usb_transfer.c
    +++ b/sys/dev/usb/usb_transfer.c
    @@ -2410,21 +2410,24 @@ usbd_pipe_start(struct usb_xfer_queue *pq)
     	 * Check if we are supposed to stall the endpoint:
     	 */
     	if (xfer->flags.stall_pipe) {
    +		struct usb_device *udev;
    +		struct usb_xfer_root *info;
    +
     		/* clear stall command */
     		xfer->flags.stall_pipe = 0;
     
    +		/* get pointer to USB device */
    +		info = xfer->xroot;
    +		udev = info->udev;
    +
     		/*
     		 * Only stall BULK and INTERRUPT endpoints.
     		 */
     		type = (ep->edesc->bmAttributes & UE_XFERTYPE);
     		if ((type == UE_BULK) ||
     		    (type == UE_INTERRUPT)) {
    -			struct usb_device *udev;
    -			struct usb_xfer_root *info;
     			uint8_t did_stall;
     
    -			info = xfer->xroot;
    -			udev = info->udev;
     			did_stall = 1;
     
     			if (udev->flags.usb_mode == USB_MODE_DEVICE) {
    @@ -2452,6 +2455,17 @@ usbd_pipe_start(struct usb_xfer_queue *pq)
     				ep->is_stalled = 1;
     				return;
     			}
    +		} else if (type == UE_ISOCHRONOUS) {
    +
    +			/* 
    +			 * Make sure any FIFO overflow or other FIFO
    +			 * error conditions go away by resetting the
    +			 * endpoint FIFO through the clear stall
    +			 * method.
    +			 */
    +			if (udev->flags.usb_mode == USB_MODE_DEVICE) {
    +				(udev->bus->methods->clear_stall) (udev, ep);
    +			}
     		}
     	}
     	/* Set or clear stall complete - special case */
    
    From d3a6755914d81e70caf28360b64d0cc67d322725 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:27:31 +0000
    Subject: [PATCH 1878/2592] MFC r205038
    
     add new vendor ID for APACER
    
    Submitted by:	Paul B Mahol
    ---
     sys/dev/usb/usbdevs | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index 35951cc3963..33f2c983163 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -545,6 +545,7 @@ vendor FALCOM		0x0f94	Falcom Wireless Communications GmbH
     vendor RIM		0x0fca	Research In Motion
     vendor DYNASTREAM	0x0fcf	Dynastream Innovations
     vendor QUALCOMM		0x1004	Qualcomm
    +vendor APACER		0x1005	Apacer
     vendor DESKNOTE		0x1019	Desknote
     vendor GIGABYTE		0x1044	GIGABYTE
     vendor WESTERN		0x1058	Western Digital
    
    From 10cd601e1792a98367ff4a048961ebf7d61b5e0a Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:27:55 +0000
    Subject: [PATCH 1879/2592] MFC r205039
    
     Add new device ID for the SMC 2514HUB
    
    Submitted by:	Alexander Best
    ---
     sys/dev/usb/usbdevs | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index 33f2c983163..d6441579100 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -2778,6 +2778,7 @@ product SMC 2202USB		0x0200	10/100 Ethernet
     product SMC 2206USB		0x0201	EZ Connect USB Ethernet
     product SMC 2862WG		0xee13	EZ Connect Wireless Adapter
     product SMC2 2020HUB		0x2020	USB Hub
    +product SMC2 2514HUB		0x2514	USB Hub
     product SMC3 2662WUSB		0xa002	2662W-AR Wireless
     
     /* SOHOware products */
    
    From 963d675e132336c0f16b187b0f73c75881374695 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:28:18 +0000
    Subject: [PATCH 1880/2592] MFC r205040
    
     extend search for Apple Function Key.
    
    PR:		usb/144414
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/input/ukbd.c | 31 ++++++++++++++++++-------------
     1 file changed, 18 insertions(+), 13 deletions(-)
    
    diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
    index 4e4393108b3..22539047b16 100644
    --- a/sys/dev/usb/input/ukbd.c
    +++ b/sys/dev/usb/input/ukbd.c
    @@ -883,28 +883,33 @@ ukbd_attach(device_t dev)
     	err = usbd_req_get_hid_desc(uaa->device, NULL, &hid_ptr,
     	    &hid_len, M_TEMP, uaa->info.bIfaceIndex);
     	if (err == 0) {
    +		uint8_t apple_keys = 0;
     		uint8_t temp_id;
     
     		/* investigate if this is an Apple Keyboard */
     		if (hid_locate(hid_ptr, hid_len,
     		    HID_USAGE2(HUP_CONSUMER, HUG_APPLE_EJECT),
     		    hid_input, 0, &sc->sc_loc_apple_eject, &flags,
    -		    &sc->sc_kbd_id)) {
    +		    &temp_id)) {
     			if (flags & HIO_VARIABLE)
     				sc->sc_flags |= UKBD_FLAG_APPLE_EJECT | 
     				    UKBD_FLAG_APPLE_SWAP;
    -			if (hid_locate(hid_ptr, hid_len,
    -			    HID_USAGE2(0xFFFF, 0x0003),
    -			    hid_input, 0, &sc->sc_loc_apple_fn, &flags,
    -			    &temp_id)) {
    -				if (flags & HIO_VARIABLE)
    -					sc->sc_flags |= UKBD_FLAG_APPLE_FN |
    -					    UKBD_FLAG_APPLE_SWAP;
    -				if (temp_id != sc->sc_kbd_id) {
    -					DPRINTF("HID IDs mismatch\n");
    -				}
    -			}
    -		} else {
    +			DPRINTFN(1, "Found Apple eject-key\n");
    +			apple_keys = 1;
    +			sc->sc_kbd_id = temp_id;
    +		}
    +		if (hid_locate(hid_ptr, hid_len,
    +		    HID_USAGE2(0xFFFF, 0x0003),
    +		    hid_input, 0, &sc->sc_loc_apple_fn, &flags,
    +		    &temp_id)) {
    +			if (flags & HIO_VARIABLE)
    +				sc->sc_flags |= UKBD_FLAG_APPLE_FN |
    +				    UKBD_FLAG_APPLE_SWAP;
    +			DPRINTFN(1, "Found Apple FN-key\n");
    +			apple_keys = 1;
    +			sc->sc_kbd_id = temp_id;
    +		}
    +		if (apple_keys == 0) {
     			/* 
     			 * Assume the first HID ID contains the
     			 * keyboard data
    
    From 1e426764e88a41055b30bf4579fe0b6e67960846 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:28:46 +0000
    Subject: [PATCH 1881/2592] MFC r205042
    
     - Integrate latest driver code from OpenBSD
     - Drain our tasks from the ieee80211 taskqueue
     - Add more IDs
    
    Submitted by:	Akinori Furukoshi
    ---
     sys/dev/usb/usbdevs          |  43 ++-
     sys/dev/usb/wlan/if_run.c    | 595 ++++++++++++++++++++++++++++-------
     sys/dev/usb/wlan/if_runreg.h | 127 +++++++-
     sys/dev/usb/wlan/if_runvar.h |  20 +-
     4 files changed, 653 insertions(+), 132 deletions(-)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index d6441579100..6007cf3f163 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -277,6 +277,7 @@ vendor LACIE		0x059f	LaCie
     vendor FUJIFILM		0x05a2	Fuji Film
     vendor ARC		0x05a3	ARC
     vendor ORTEK		0x05a4	Ortek
    +vendor CISCOLINKSYS3	0x05a6	Cisco-Linksys
     vendor BOSE		0x05a7	Bose
     vendor OMNIVISION	0x05a9	OmniVision
     vendor INSYSTEM		0x05ab	In-System Design
    @@ -546,6 +547,7 @@ vendor RIM		0x0fca	Research In Motion
     vendor DYNASTREAM	0x0fcf	Dynastream Innovations
     vendor QUALCOMM		0x1004	Qualcomm
     vendor APACER		0x1005	Apacer
    +vendor MOTOROLA4	0x100d	Motorola
     vendor DESKNOTE		0x1019	Desknote
     vendor GIGABYTE		0x1044	GIGABYTE
     vendor WESTERN		0x1058	Western Digital
    @@ -642,6 +644,7 @@ vendor LINKSYS3		0x1915	Linksys
     vendor QUALCOMMINC	0x19d2	Qualcomm, Incorporated
     vendor WCH2		0x1a86	QinHeng Electronics
     vendor STELERA		0x1a8d	Stelera Wireless
    +vendor OVISLINK		0x1b75	OvisLink
     vendor TCTMOBILE	0x1bbb  TCT Mobile
     vendor TELIT		0x1bc7  Telit
     vendor MPMAN		0x1cae	MpMan
    @@ -683,6 +686,7 @@ vendor 3COM2		0x6891	3Com
     vendor EDIMAX		0x7392	Edimax
     vendor INTEL		0x8086	Intel
     vendor INTEL2		0x8087	Intel
    +vendor ALLWIN		0x8516	ALLWIN Tech
     vendor SITECOM2		0x9016	Sitecom
     vendor MOSCHIP		0x9710	MosChip Semiconductor
     vendor MARVELL		0x9e88	Marvell Technology Group Ltd.
    @@ -762,6 +766,7 @@ product	ACCTON RT3070_1		0xa701	RT3070
     product	ACCTON RT3070_2		0xa702	RT3070
     product ACCTON RT2870_1		0xb522	RT2870
     product	ACCTON RT3070_3		0xc522	RT3070
    +product	ACCTON RT3070_5		0xd522	RT3070
     product ACCTON ZD1211B		0xe501	ZD1211B
     
     /* Aceeca products */
    @@ -894,6 +899,15 @@ product ALTEC ASC495		0xff05	ASC495 Speakers
     /* Allied Telesyn International products */
     product ALLIEDTELESYN ATUSB100	0xb100	AT-USB100
     
    +/* ALLWIN Tech products */
    +product ALLWIN RT2070		0x2070	RT2070
    +product ALLWIN RT2770		0x2770	RT2770
    +product ALLWIN RT2870		0x2870	RT2870
    +product ALLWIN RT3070		0x3070	RT3070
    +product ALLWIN RT3071		0x3071	RT3071
    +product ALLWIN RT3072		0x3072	RT3072
    +product ALLWIN RT3572		0x3572	RT3572
    +
     /* AlphaSmart, Inc. products */
     product ALPHASMART DANA_KB	0xdbac	AlphaSmart Dana Keyboard
     product ALPHASMART DANA_SYNC	0xdf00	AlphaSmart Dana HotSync
    @@ -996,7 +1010,8 @@ product ASUS RT2870_2		0x1732	RT2870
     product ASUS RT2870_3		0x1742	RT2870
     product ASUS RT2870_4		0x1760	RT2870
     product ASUS RT2870_5		0x1761	RT2870
    -product	ASUS RT3070		0x1784	RT3070
    +product	ASUS USBN13		0x1784	USB-N13
    +product	ASUS RT3070_1		0x1790	RT3070
     product ASUS P535		0x420f	ASUS P535 PDA
     product	ASUS GMSC		0x422f	ASUS Generic Mass Storage
     product ASUS RT2570		0x1706	RT2500USB Wireless Adapter
    @@ -1154,7 +1169,8 @@ product CISCOLINKSYS HU200TS	0x001a	HU200TS Wireless Adapter
     product CISCOLINKSYS WUSB54GC	0x0020	WUSB54GC
     product CISCOLINKSYS WUSB54GR	0x0023	WUSB54GR
     product CISCOLINKSYS WUSBF54G	0x0024	WUSBF54G
    -product	CISCOLINKSYS2	RT3070	0x4001	RT3070
    +product	CISCOLINKSYS2 RT3070	0x4001	RT3070
    +product	CISCOLINKSYS3 RT3070	0x0101	RT3070
     
     /* CMOTECH products */
     product CMOTECH CNU510		0x5141	CDMA Technologies USB modem
    @@ -1181,6 +1197,8 @@ product CONCEPTRONIC AR5523_2	0x7811	AR5523
     product CONCEPTRONIC AR5523_2_NF	0x7812	AR5523 (no firmware)
     product CONCEPTRONIC2 C54RU	0x3c02	C54RU WLAN
     product CONCEPTRONIC2 C54RU2	0x3c22	C54RU
    +product CONCEPTRONIC2 RT3070_1	0x3c08	RT3070
    +product CONCEPTRONIC2 RT3070_2	0x3c11	RT3070
     product CONCEPTRONIC2 VIGORN61	0x3c25	VIGORN61
     product CONCEPTRONIC2 RT2870_1	0x3c06	RT2870
     product CONCEPTRONIC2 RT2870_2	0x3c07	RT2870
    @@ -1333,12 +1351,14 @@ product DLINK2 DWA111		0x3c06	DWA-111
     product DLINK2 RT2870_1		0x3c09	RT2870
     product DLINK2 DWA110		0x3c07	DWA-110
     product DLINK2 RT3072		0x3c0a	RT3072
    +product DLINK2 RT3072_1		0x3c0b	RT3072
     product DLINK2 RT3070_1		0x3c0d	RT3070
     product DLINK2 RT3070_2		0x3c0e	RT3070
     product DLINK2 RT3070_3		0x3c0f	RT3070
     product DLINK2 RT2870_2		0x3c11	RT2870
     product DLINK2 DWA130		0x3c13	DWA-130
     product DLINK2 RT3070_4		0x3c15	RT3070
    +product DLINK2 RT3070_5		0x3c16	RT3070
     product DLINK3 DWM652		0x3e04	DWM-652
     
     /* DMI products */
    @@ -1909,6 +1929,7 @@ product LINKSYS4 WUSB100	0x0070	WUSB100
     product LINKSYS4 WUSB600N	0x0071	WUSB600N
     product LINKSYS4 WUSB54GCV2	0x0073	WUSB54GC v2
     product LINKSYS4 WUSB54GCV3	0x0077	WUSB54GC v3
    +product LINKSYS4 RT3070		0x0078	RT3070
     product LINKSYS4 WUSB600NV2	0x0079	WUSB600N v2
     
     /* Logitech products */
    @@ -1982,6 +2003,8 @@ product MELCO KG54L		0x00da	WLI-U2-KG54L
     product MELCO WLIUCG300N	0x00e8	WLI-UC-G300N
     product MELCO SG54HG		0x00f4	WLI-U2-SG54HG
     product MELCO WLIUCAG300N	0x012e	WLI-UC-AG300N
    +product MELCO RT2870_1		0x0148	RT2870
    +product MELCO RT2870_2		0x0150	RT2870
     product MELCO WLIUCGN		0x015d	WLI-UC-GN
     
     /* Merlin products */
    @@ -2002,7 +2025,9 @@ product MGE UPS2		0xffff	MGE UPS SYSTEMS PROTECTIONCENTER 2
     product MSI BT_DONGLE		0x1967	Bluetooth USB dongle
     product MSI RT3070_1		0x3820	RT3070
     product MSI RT3070_2		0x3821	RT3070
    +product MSI RT3070_8		0x3822	RT3070
     product MSI RT3070_3		0x3870	RT3070
    +product MSI RT3070_9		0x3871	RT3070
     product MSI UB11B		0x6823	UB11B
     product MSI RT2570		0x6861	RT2570
     product MSI RT2570_2		0x6865	RT2570
    @@ -2011,7 +2036,9 @@ product MSI RT2573_1		0x6874	RT2573
     product MSI RT2573_2		0x6877	RT2573
     product MSI RT3070_4		0x6899	RT3070
     product MSI RT3070_5		0x821a	RT3070
    +product MSI RT3070_10		0x822a	RT3070
     product MSI RT3070_6		0x870a	RT3070
    +product MSI RT3070_11		0x871a	RT3070
     product MSI RT3070_7		0x899a	RT3070
     product MSI RT2573_3		0xa861	RT2573
     product MSI RT2573_4		0xa874	RT2573
    @@ -2092,6 +2119,8 @@ product MOTOROLA2 A41XV32X	0x2a22	A41x/V32x Mobile Phones
     product MOTOROLA2 E398		0x4810	E398 Mobile Phone
     product MOTOROLA2 USBLAN	0x600c	USBLAN
     product MOTOROLA2 USBLAN2	0x6027	USBLAN
    +product MOTOROLA4 RT2770	0x9031	RT2770
    +product MOTOROLA4 RT3070	0x9032	RT3070
     
     /* MultiTech products */
     product MULTITECH ATLAS		0xf101	MT5634ZBA-USB modem
    @@ -2262,6 +2291,9 @@ product OPTION MODHSXPA		0xd013	Globetrotter HSUPA
     product OPTION ICON321		0xd031	Globetrotter HSUPA
     product OPTION ICON505		0xd055	Globetrotter iCON 505
     
    +/* OvisLink product */
    +product OVISLINK RT3072		0x3072	RT3072
    +
     /* OQO */
     product OQO WIFI01		0x0002	model 01 WiFi interface
     product OQO BT01		0x0003	model 01 Bluetooth interface
    @@ -2296,6 +2328,7 @@ product PARA RT3070		0x8888	RT3070
     product PEGATRON RT2870		0x0002	RT2870
     product PEGATRON RT3070		0x000c	RT3070
     product PEGATRON RT3070_2	0x000e	RT3070
    +product PEGATRON RT3070_3	0x0010	RT3070
     
     /* Peracom products */
     product PERACOM SERIAL1		0x0001	Serial
    @@ -2515,7 +2548,9 @@ product RALINK RT2870		0x2870	RT2870
     product RALINK RT3070		0x3070	RT3070
     product RALINK RT3071		0x3071	RT3071
     product RALINK RT3072		0x3072	RT3072
    +product RALINK RT3370		0x3370	RT3370
     product RALINK RT3572		0x3572	RT3572
    +product RALINK RT8070		0x8070	RT8070
     product RALINK RT2570_3		0x9020	RT2500USB Wireless Adapter
     product RALINK RT2573_2		0x9021	RT2501USB Wireless Adapter
     
    @@ -2752,6 +2787,7 @@ product SITECOMEU RT3070_3	0x003c	RT3070
     product SITECOMEU RT3070_4	0x003d	RT3070
     product SITECOMEU RT3070	0x003e	RT3070
     product SITECOMEU WL608		0x003f	WL-608
    +product SITECOMEU RT3071	0x0040	RT3071
     product SITECOMEU RT3072_1	0x0041	RT3072
     product SITECOMEU RT3072_2	0x0042	RT3072
     product SITECOMEU RT3072_3	0x0047	RT3072
    @@ -2888,6 +2924,7 @@ product SURECOM RT2573		0x31f3	RT2573
     
     /* Sweex products */
     product SWEEX ZD1211		0x1809	ZD1211
    +product SWEEX2 LW153		0x0153	LW153
     product SWEEX2 LW303		0x0302	LW303
     product SWEEX2 LW313		0x0313	LW313
     
    @@ -2943,6 +2980,7 @@ product TOPRE HHKB		0x0100	HHKB Professional
     
     /* Toshiba Corporation products */
     product TOSHIBA POCKETPC_E740	0x0706	PocketPC e740
    +product TOSHIBA RT3070		0x0a07	RT3070
     product TOSHIBA G450		0x0d45	G450 modem
     product TOSHIBA HSDPA		0x1302	G450 modem
     
    @@ -3124,3 +3162,4 @@ product ZYXEL M202		0x340a	M-202
     product ZYXEL G220V2		0x340f	G-220 v2
     product ZYXEL G202		0x3410	G-202
     product ZYXEL RT2870_1		0x3416	RT2870
    +product ZYXEL RT2870_2		0x341a	RT2870
    diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
    index 03fbdf1bed2..65f48e47be3 100644
    --- a/sys/dev/usb/wlan/if_run.c
    +++ b/sys/dev/usb/wlan/if_run.c
    @@ -1,8 +1,9 @@
     /*	$FreeBSD$	*/
     
     /*-
    - * Copyright (c) 2008,2009 Damien Bergamini 
    - *	ported to FreeBSD by Akinori Furukoshi 
    + * Copyright (c) 2008,2010 Damien Bergamini 
    + * ported to FreeBSD by Akinori Furukoshi 
    + * USB Consulting, Hans Petter Selasky 
      *
      * Permission to use, copy, modify, and distribute this software for any
      * purpose with or without fee is hereby granted, provided that the above
    @@ -17,8 +18,6 @@
      * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      */
     
    -/* release date Jan. 09, 2010 */
    -
     #include 
     __FBSDID("$FreeBSD$");
     
    @@ -107,11 +106,20 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT2870_3) },
         { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT2870_4) },
         { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT2870_5) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070) },
         { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070_1) },
         { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070_2) },
         { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070_3) },
         { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070_4) },
    +    { USB_VP(USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_RT3070_5) },
         { USB_VP(USB_VENDOR_AIRTIES,	USB_PRODUCT_AIRTIES_RT3070) },
    +    { USB_VP(USB_VENDOR_ALLWIN,		USB_PRODUCT_ALLWIN_RT2070) },
    +    { USB_VP(USB_VENDOR_ALLWIN,		USB_PRODUCT_ALLWIN_RT2770) },
    +    { USB_VP(USB_VENDOR_ALLWIN,		USB_PRODUCT_ALLWIN_RT2870) },
    +    { USB_VP(USB_VENDOR_ALLWIN,		USB_PRODUCT_ALLWIN_RT3070) },
    +    { USB_VP(USB_VENDOR_ALLWIN,		USB_PRODUCT_ALLWIN_RT3071) },
    +    { USB_VP(USB_VENDOR_ALLWIN,		USB_PRODUCT_ALLWIN_RT3072) },
    +    { USB_VP(USB_VENDOR_ALLWIN,		USB_PRODUCT_ALLWIN_RT3572) },
         { USB_VP(USB_VENDOR_AMIGO,		USB_PRODUCT_AMIGO_RT2870_1) },
         { USB_VP(USB_VENDOR_AMIGO,		USB_PRODUCT_AMIGO_RT2870_2) },
         { USB_VP(USB_VENDOR_AMIT,		USB_PRODUCT_AMIT_CGWLUSB2GNR) },
    @@ -122,6 +130,8 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2870_3) },
         { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2870_4) },
         { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2870_5) },
    +    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_USBN13) },
    +    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT3070_1) },
         { USB_VP(USB_VENDOR_ASUS2,		USB_PRODUCT_ASUS2_USBN11) },
         { USB_VP(USB_VENDOR_AZUREWAVE,	USB_PRODUCT_AZUREWAVE_RT2870_1) },
         { USB_VP(USB_VENDOR_AZUREWAVE,	USB_PRODUCT_AZUREWAVE_RT2870_2) },
    @@ -133,6 +143,8 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F6D4050V1) },
         { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_RT2870_1) },
         { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_RT2870_2) },
    +    { USB_VP(USB_VENDOR_CISCOLINKSYS2,	USB_PRODUCT_CISCOLINKSYS2_RT3070) },
    +    { USB_VP(USB_VENDOR_CISCOLINKSYS3,	USB_PRODUCT_CISCOLINKSYS2_RT3070) },
         { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_1) },
         { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_2) },
         { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_3) },
    @@ -141,6 +153,8 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_6) },
         { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_7) },
         { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT2870_8) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT3070_1) },
    +    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_RT3070_2) },
         { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_VIGORN61) },
         { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB300GNM) },
         { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_RT2870_1) },
    @@ -157,7 +171,9 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3070_2) },
         { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3070_3) },
         { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3070_4) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3070_5) },
         { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3072) },
    +    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_RT3072_1) },
         { USB_VP(USB_VENDOR_EDIMAX,		USB_PRODUCT_EDIMAX_EW7717) },
         { USB_VP(USB_VENDOR_EDIMAX,		USB_PRODUCT_EDIMAX_EW7718) },
         { USB_VP(USB_VENDOR_EDIMAX,		USB_PRODUCT_EDIMAX_RT2870_1) },
    @@ -178,6 +194,7 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_RT3072_2) },
         { USB_VP(USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_RT3072_3) },
         { USB_VP(USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_RT3072_4) },
    +    { USB_VP(USB_VENDOR_LINKSYS4,	USB_PRODUCT_LINKSYS4_RT3070) },
         { USB_VP(USB_VENDOR_LINKSYS4,	USB_PRODUCT_LINKSYS4_WUSB100) },
         { USB_VP(USB_VENDOR_LINKSYS4,	USB_PRODUCT_LINKSYS4_WUSB54GCV3) },
         { USB_VP(USB_VENDOR_LINKSYS4,	USB_PRODUCT_LINKSYS4_WUSB600N) },
    @@ -185,9 +202,13 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_LOGITEC,	USB_PRODUCT_LOGITEC_RT2870_1) },
         { USB_VP(USB_VENDOR_LOGITEC,	USB_PRODUCT_LOGITEC_RT2870_2) },
         { USB_VP(USB_VENDOR_LOGITEC,	USB_PRODUCT_LOGITEC_RT2870_3) },
    +    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_RT2870_1) },
    +    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_RT2870_2) },
         { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_WLIUCAG300N) },
         { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_WLIUCG300N) },
         { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_WLIUCGN) },
    +    { USB_VP(USB_VENDOR_MOTOROLA4,	USB_PRODUCT_MOTOROLA4_RT2770) },
    +    { USB_VP(USB_VENDOR_MOTOROLA4,	USB_PRODUCT_MOTOROLA4_RT3070) },
         { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_1) },
         { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_2) },
         { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_3) },
    @@ -195,10 +216,16 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_5) },
         { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_6) },
         { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_7) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_8) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_9) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_10) },
    +    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT3070_11) },
    +    { USB_VP(USB_VENDOR_OVISLINK,	USB_PRODUCT_OVISLINK_RT3072) },
         { USB_VP(USB_VENDOR_PARA,		USB_PRODUCT_PARA_RT3070) },
         { USB_VP(USB_VENDOR_PEGATRON,	USB_PRODUCT_PEGATRON_RT2870) },
         { USB_VP(USB_VENDOR_PEGATRON,	USB_PRODUCT_PEGATRON_RT3070) },
         { USB_VP(USB_VENDOR_PEGATRON,	USB_PRODUCT_PEGATRON_RT3070_2) },
    +    { USB_VP(USB_VENDOR_PEGATRON,	USB_PRODUCT_PEGATRON_RT3070_3) },
         { USB_VP(USB_VENDOR_PHILIPS,	USB_PRODUCT_PHILIPS_RT2870) },
         { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUS300MINIS) },
         { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUSMICRON) },
    @@ -212,7 +239,9 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT3070) },
         { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT3071) },
         { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT3072) },
    +    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT3370) },
         { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT3572) },
    +    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT8070) },
         { USB_VP(USB_VENDOR_SAMSUNG2,	USB_PRODUCT_SAMSUNG2_RT2870_1) },
         { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT2870_1) },
         { USB_VP(USB_VENDOR_SENAO,		USB_PRODUCT_SENAO_RT2870_2) },
    @@ -234,6 +263,7 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3070_2) },
         { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3070_3) },
         { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3070_4) },
    +    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3071) },
         { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3072_1) },
         { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3072_2) },
         { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_RT3072_3) },
    @@ -243,8 +273,10 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_WL608) },
         { USB_VP(USB_VENDOR_SPARKLAN,	USB_PRODUCT_SPARKLAN_RT2870_1) },
         { USB_VP(USB_VENDOR_SPARKLAN,	USB_PRODUCT_SPARKLAN_RT3070) },
    +    { USB_VP(USB_VENDOR_SWEEX2,		USB_PRODUCT_SWEEX2_LW153) },
         { USB_VP(USB_VENDOR_SWEEX2,		USB_PRODUCT_SWEEX2_LW303) },
         { USB_VP(USB_VENDOR_SWEEX2,		USB_PRODUCT_SWEEX2_LW313) },
    +    { USB_VP(USB_VENDOR_TOSHIBA,	USB_PRODUCT_TOSHIBA_RT3070) },
         { USB_VP(USB_VENDOR_UMEDIA,		USB_PRODUCT_UMEDIA_RT2870_1) },
         { USB_VP(USB_VENDOR_ZCOM,		USB_PRODUCT_ZCOM_RT2870_1) },
         { USB_VP(USB_VENDOR_ZCOM,		USB_PRODUCT_ZCOM_RT2870_2) },
    @@ -254,6 +286,7 @@ static const struct usb_device_id run_devs[] = {
         { USB_VP(USB_VENDOR_ZINWELL,	USB_PRODUCT_ZINWELL_RT3072_1) },
         { USB_VP(USB_VENDOR_ZINWELL,	USB_PRODUCT_ZINWELL_RT3072_2) },
         { USB_VP(USB_VENDOR_ZYXEL,		USB_PRODUCT_ZYXEL_RT2870_1) },
    +    { USB_VP(USB_VENDOR_ZYXEL,		USB_PRODUCT_ZYXEL_RT2870_2) },
     };
     
     MODULE_DEPEND(run, wlan, 1, 1, 1);
    @@ -340,10 +373,12 @@ static int	run_raw_xmit(struct ieee80211_node *, struct mbuf *,
     		    const struct ieee80211_bpf_params *);
     static void	run_start(struct ifnet *);
     static int	run_ioctl(struct ifnet *, u_long, caddr_t);
    +static void	run_set_agc(struct run_softc *, uint8_t);
     static void	run_select_chan_group(struct run_softc *, int);
     static void	run_set_rx_antenna(struct run_softc *, int);
     static void	run_rt2870_set_chan(struct run_softc *, u_int);
     static void	run_rt3070_set_chan(struct run_softc *, u_int);
    +static void	run_rt3572_set_chan(struct run_softc *, u_int);
     static int	run_set_chan(struct run_softc *, struct ieee80211_channel *);
     static void	run_set_channel(struct ieee80211com *);
     static void	run_scan_start(struct ieee80211com *);
    @@ -369,6 +404,7 @@ static int	run_bbp_init(struct run_softc *);
     static int	run_rt3070_rf_init(struct run_softc *);
     static int	run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t,
     		    uint8_t *);
    +static void	run_rt3070_rf_setup(struct run_softc *);
     static int	run_txrx_enable(struct run_softc *);
     static void	run_init(void *);
     static void	run_init_locked(struct run_softc *);
    @@ -398,8 +434,8 @@ static const struct rfprog {
     
     struct {
     	uint8_t	n, r, k;
    -} run_rf3020_freqs[] = {
    -	RT3070_RF3020
    +} rt3070_freqs[] = {
    +	RT3070_RF3052
     };
     
     static const struct {
    @@ -407,6 +443,8 @@ static const struct {
     	uint8_t	val;
     } rt3070_def_rf[] = {
     	RT3070_DEF_RF
    +},rt3572_def_rf[] = {
    +	RT3572_DEF_RF
     };
     
     static const struct usb_config run_config[RUN_N_XFER] = {
    @@ -502,6 +540,7 @@ run_attach(device_t self)
     	struct usb_attach_arg *uaa = device_get_ivars(self);
     	struct ieee80211com *ic;
     	struct ifnet *ifp;
    +	uint32_t ver;
     	int i, ntries, error;
     	uint8_t iface_index, bands;
     
    @@ -513,11 +552,10 @@ run_attach(device_t self)
     	    MTX_NETWORK_LOCK, MTX_DEF);
     
     	iface_index = RT2860_IFACE_INDEX;
    -	/* Rx transfer has own lock */
     	error = usbd_transfer_setup(uaa->device, &iface_index,
     	    sc->sc_xfer, run_config, RUN_N_XFER, sc, &sc->sc_mtx);
     	if (error) {
    -		device_printf(self, "could not allocate USB Tx transfers, "
    +		device_printf(self, "could not allocate USB transfers, "
     		    "err=%s\n", usbd_errstr(error));
     		goto detach;
     	}
    @@ -526,11 +564,11 @@ run_attach(device_t self)
     
     	/* wait for the chip to settle */
     	for (ntries = 0; ntries < 100; ntries++) {
    -		if (run_read(sc, RT2860_ASIC_VER_ID, &sc->mac_rev) != 0){
    +		if (run_read(sc, RT2860_ASIC_VER_ID, &ver) != 0){
     			RUN_UNLOCK(sc);
     			goto detach;
     		}
    -		if (sc->mac_rev != 0 && sc->mac_rev != 0xffffffff)
    +		if (ver != 0 && ver != 0xffffffff)
     			break;
     		run_delay(sc, 10);
     	}
    @@ -540,13 +578,15 @@ run_attach(device_t self)
     		RUN_UNLOCK(sc);
     		goto detach;
     	}
    +	sc->mac_ver = ver >> 16;
    +	sc->mac_rev = ver & 0xffff;
     
     	/* retrieve RF rev. no and various other things from EEPROM */
     	run_read_eeprom(sc);
     
     	device_printf(sc->sc_dev,
     	    "MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), address %s\n",
    -	    sc->mac_rev >> 16, sc->mac_rev & 0xffff, run_get_rf(sc->rf_rev),
    +	    sc->mac_ver, sc->mac_rev, run_get_rf(sc->rf_rev),
     	    sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid));
     
     	if ((error = run_load_microcode(sc)) != 0) {
    @@ -609,7 +649,9 @@ run_attach(device_t self)
     	 * Do this by own because h/w supports
     	 * more channels than ieee80211_init_channels()
     	 */
    -	if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850) {
    +	if (sc->rf_rev == RT2860_RF_2750 ||
    +	    sc->rf_rev == RT2860_RF_2850 ||
    +	    sc->rf_rev == RT3070_RF_3052) {
     		/* set supported .11a rates */
     		for (i = 14; i < nitems(rt2860_rf2850); i++) {
     			uint8_t chan = rt2860_rf2850[i].chan;
    @@ -743,11 +785,15 @@ run_vap_delete(struct ieee80211vap *vap)
     
     	sc = ifp->if_softc;
     
    -	if (ifp && ifp->if_flags & IFF_UP){
    -		RUN_LOCK(sc);
    -		run_stop(sc);
    -		RUN_UNLOCK(sc);
    -	}
    +	RUN_LOCK(sc);
    +	sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
    +	RUN_UNLOCK(sc);
    +
    +	/* drain them all */
    +	usb_callout_drain(&sc->sc_rvp->amrr_ch);
    +	ieee80211_draintask(ic, &sc->sc_rvp->amrr_task);
    +	ieee80211_draintask(ic, &sc->wme_task);
    +	ieee80211_draintask(ic, &sc->usb_timeout_task);
     
     	ieee80211_amrr_cleanup(&rvp->amrr);
     	ieee80211_vap_detach(vap);
    @@ -808,7 +854,9 @@ run_load_microcode(struct run_softc *sc)
     	const uint64_t *temp;
     	uint64_t bytes;
     
    +	RUN_UNLOCK(sc);
     	fw = firmware_get("runfw");
    +	RUN_LOCK(sc);
     	if(fw == NULL){
     		device_printf(sc->sc_dev,
     		    "failed loadfirmware of file %s\n", "runfw");
    @@ -829,14 +877,11 @@ run_load_microcode(struct run_softc *sc)
     	 * last half is for rt3071.
     	 */
     	base = fw->data;
    -	if ((sc->mac_rev >> 16) != 0x2860 &&
    -	    (sc->mac_rev >> 16) != 0x2872 &&
    -	    (sc->mac_rev >> 16) != 0x3070 &&
    -	    (sc->mac_rev >> 16) != 0x3572){
    +	if ((sc->mac_ver) != 0x2860 &&
    +	    (sc->mac_ver) != 0x2872 &&
    +	    (sc->mac_ver) != 0x3070){ 
     		base += 4096;
    -		device_printf(sc->sc_dev, "loading RT3071 firmware\n");
    -	} else
    -		device_printf(sc->sc_dev, "loading RT2870 firmware\n");
    +	}
     
     	/* cheap sanity check */
     	temp = fw->data;
    @@ -866,7 +911,7 @@ run_load_microcode(struct run_softc *sc)
     	run_delay(sc, 10);
     
     	run_write(sc, RT2860_H2M_MAILBOX, 0);
    -	if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_BOOT, 0)) != 0)
    +	if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0)) != 0)
     		goto fail;
     
     	/* wait until microcontroller is ready */
    @@ -884,7 +929,8 @@ run_load_microcode(struct run_softc *sc)
     		error = ETIMEDOUT;
     		goto fail;
     	}
    -	DPRINTF("microcode successfully loaded after %d tries\n", ntries);
    +	device_printf(sc->sc_dev, "firmware %s loaded\n",
    +	    (base == fw->data) ? "RT2870" : "RT3071");
     
     fail:
     	firmware_put(fw, FIRMWARE_UNLOAD);
    @@ -1283,7 +1329,7 @@ run_read_eeprom(struct run_softc *sc)
     
     	/* check whether the ROM is eFUSE ROM or EEPROM */
     	sc->sc_srom_read = run_eeprom_read_2;
    -	if ((sc->mac_rev & 0xfff00000) >= 0x30700000) {
    +	if (sc->mac_ver >= 0x3070) {
     		run_read(sc, RT3070_EFUSE_CTRL, &tmp);
     		DPRINTF("EFUSE_CTRL=0x%08x\n", tmp);
     		if (tmp & RT3070_SEL_EFUSE)
    @@ -1305,21 +1351,32 @@ run_read_eeprom(struct run_softc *sc)
     	sc->sc_bssid[4] = val & 0xff;
     	sc->sc_bssid[5] = val >> 8;
     
    -	/* read default BBP settings */
    -	for (i = 0; i < 8; i++) {
    +	/* read vender BBP settings */
    +	for (i = 0; i < 10; i++) {
     		run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val);
     		sc->bbp[i].val = val & 0xff;
     		sc->bbp[i].reg = val >> 8;
     		DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val);
     	}
    +	if (sc->mac_ver >= 0x3071) {
    +		/* read vendor RF settings */
    +		for (i = 0; i < 10; i++) {
    +			run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, &val);
    +			sc->rf[i].val = val & 0xff;
    +			sc->rf[i].reg = val >> 8;
    +			DPRINTF("RF%d=0x%02x\n", sc->rf[i].reg,
    +			    sc->rf[i].val);
    +		}
    +	}
     
     	/* read RF frequency offset from EEPROM */
     	run_srom_read(sc, RT2860_EEPROM_FREQ_LEDS, &val);
     	sc->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0;
     	DPRINTF("EEPROM freq offset %d\n", sc->freq & 0xff);
     
    -	if ((sc->leds = val >> 8) != 0xff) {
    +	if (val >> 8 != 0xff) {
     		/* read LEDs operating mode */
    +		sc->leds = val >> 8;
     		run_srom_read(sc, RT2860_EEPROM_LED1, &sc->led[0]);
     		run_srom_read(sc, RT2860_EEPROM_LED2, &sc->led[1]);
     		run_srom_read(sc, RT2860_EEPROM_LED3, &sc->led[2]);
    @@ -1337,7 +1394,12 @@ run_read_eeprom(struct run_softc *sc)
     	run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
     	if (val == 0xffff) {
     		DPRINTF("invalid EEPROM antenna info, using default\n");
    -		if ((sc->mac_rev >> 16) >= 0x3070) {
    +		if (sc->mac_ver == 0x3572) {
    +			/* default to RF3052 2T2R */
    +			sc->rf_rev = RT3070_RF_3052;
    +			sc->ntxchains = 2;
    +			sc->nrxchains = 2;
    +		} else if (sc->mac_ver >= 0x3070) {
     			/* default to RF3020 1T1R */
     			sc->rf_rev = RT3070_RF_3020;
     			sc->ntxchains = 1;
    @@ -1356,13 +1418,18 @@ run_read_eeprom(struct run_softc *sc)
     	DPRINTF("EEPROM RF rev=0x%02x chains=%dT%dR\n",
     	    sc->rf_rev, sc->ntxchains, sc->nrxchains);
     
    -	/* check if RF supports automatic Tx access gain control */
     	run_srom_read(sc, RT2860_EEPROM_CONFIG, &val);
     	DPRINTF("EEPROM CFG 0x%04x\n", val);
    +	/* check if driver should patch the DAC issue */
    +	if ((val >> 8) != 0xff)
    +		sc->patch_dac = (val >> 15) & 1;
     	if ((val & 0xff) != 0xff) {
     		sc->ext_5ghz_lna = (val >> 3) & 1;
     		sc->ext_2ghz_lna = (val >> 2) & 1;
    +		/* check if RF supports automatic Tx access gain control */
     		sc->calib_2ghz = sc->calib_5ghz = (val >> 1) & 1;
    +		/* check if we have a hardware radio switch */
    +		sc->rfswitch = val & 1;
     	}
     
     	/* read power settings for 2GHz channels */
    @@ -1385,7 +1452,7 @@ run_read_eeprom(struct run_softc *sc)
     		    rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]);
     	}
     	/* read power settings for 5GHz channels */
    -	for (i = 0; i < 36; i += 2) {
    +	for (i = 0; i < 40; i += 2) {
     		run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2, &val);
     		sc->txpow1[i + 14] = (int8_t)(val & 0xff);
     		sc->txpow1[i + 15] = (int8_t)(val >> 8);
    @@ -1395,7 +1462,7 @@ run_read_eeprom(struct run_softc *sc)
     		sc->txpow2[i + 15] = (int8_t)(val >> 8);
     	}
     	/* fix broken Tx power entries */
    -	for (i = 0; i < 36; i++) {
    +	for (i = 0; i < 40; i++) {
     		if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15)
     			sc->txpow1[14 + i] = 5;
     		if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15)
    @@ -1444,14 +1511,32 @@ run_read_eeprom(struct run_softc *sc)
     	sc->rssi_2ghz[0] = val & 0xff;	/* Ant A */
     	sc->rssi_2ghz[1] = val >> 8;	/* Ant B */
     	run_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ, &val);
    -	sc->rssi_2ghz[2] = val & 0xff;	/* Ant C */
    +	if (sc->mac_ver >= 0x3070) {
    +		/*
    +		 * On RT3070 chips (limited to 2 Rx chains), this ROM
    +		 * field contains the Tx mixer gain for the 2GHz band.
    +		 */
    +		if ((val & 0xff) != 0xff)
    +			sc->txmixgain_2ghz = val & 0x7;
    +		DPRINTF("tx mixer gain=%u (2GHz)\n", sc->txmixgain_2ghz);
    +	} else
    +		sc->rssi_2ghz[2] = val & 0xff;	/* Ant C */
     	sc->lna[2] = val >> 8;		/* channel group 2 */
     
     	run_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ, &val);
     	sc->rssi_5ghz[0] = val & 0xff;	/* Ant A */
     	sc->rssi_5ghz[1] = val >> 8;	/* Ant B */
     	run_srom_read(sc, RT2860_EEPROM_RSSI2_5GHZ, &val);
    -	sc->rssi_5ghz[2] = val & 0xff;	/* Ant C */
    +	if (sc->mac_ver == 0x3572) {
    +		/*
    +		 * On RT3572 chips (limited to 2 Rx chains), this ROM
    +		 * field contains the Tx mixer gain for the 5GHz band.
    +		 */
    +		if ((val & 0xff) != 0xff)
    +			sc->txmixgain_5ghz = val & 0x7;
    +		DPRINTF("tx mixer gain=%u (5GHz)\n", sc->txmixgain_5ghz);
    +	} else
    +		sc->rssi_5ghz[2] = val & 0xff;	/* Ant C */
     	sc->lna[3] = val >> 8;		/* channel group 3 */
     
     	run_srom_read(sc, RT2860_EEPROM_LNA, &val);
    @@ -2639,7 +2724,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
     			dur = rt2860_rates[ridx].sp_ack_dur;
     		else
     			dur = rt2860_rates[ridx].lp_ack_dur;
    -		*(uint16_t *)wh->i_dur = htole16(dur + sc->sifs);
    +		*(uint16_t *)wh->i_dur = htole16(dur);
     	}
     
     	/* reserve slots for mgmt packets, just in case */
    @@ -3005,10 +3090,27 @@ run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     	return (error);
     }
     
    +static void
    +run_set_agc(struct run_softc *sc, uint8_t agc)
    +{
    +	uint8_t bbp;
    +
    +	if (sc->mac_ver == 0x3572) {
    +		run_bbp_read(sc, 27, &bbp);
    +		bbp &= ~(0x3 << 5);
    +		run_bbp_write(sc, 27, bbp | 0 << 5);	/* select Rx0 */
    +		run_bbp_write(sc, 66, agc);
    +		run_bbp_write(sc, 27, bbp | 1 << 5);	/* select Rx1 */
    +		run_bbp_write(sc, 66, agc);
    +	} else
    +		run_bbp_write(sc, 66, agc);
    +}
    +
     static void
     run_select_chan_group(struct run_softc *sc, int group)
     {
     	uint32_t tmp;
    +	uint8_t agc;
     
     	run_bbp_write(sc, 62, 0x37 - sc->lna[group]);
     	run_bbp_write(sc, 63, 0x37 - sc->lna[group]);
    @@ -3024,13 +3126,14 @@ run_select_chan_group(struct run_softc *sc, int group)
     			run_bbp_write(sc, 75, 0x50);
     		}
     	} else {
    -		if (sc->ext_5ghz_lna) {
    +		if (sc->mac_ver == 0x3572)
    +			run_bbp_write(sc, 82, 0x94);
    +		else
     			run_bbp_write(sc, 82, 0xf2);
    +		if (sc->ext_5ghz_lna)
     			run_bbp_write(sc, 75, 0x46);
    -		} else {
    -			run_bbp_write(sc, 82, 0xf2);
    +		else 
     			run_bbp_write(sc, 75, 0x50);
    -		}
     	}
     
     	run_read(sc, RT2860_TX_BAND_CFG, &tmp);
    @@ -3053,13 +3156,26 @@ run_select_chan_group(struct run_softc *sc, int group)
     		if (sc->nrxchains > 1)
     			tmp |= RT2860_LNA_PE_A1_EN;
     	}
    -	run_write(sc, RT2860_TX_PIN_CFG, tmp);
    +	if (sc->mac_ver == 0x3572) {
    +		run_rt3070_rf_write(sc, 8, 0x00);
    +		run_write(sc, RT2860_TX_PIN_CFG, tmp);
    +		run_rt3070_rf_write(sc, 8, 0x80);
    +	} else
    +		run_write(sc, RT2860_TX_PIN_CFG, tmp);
     
     	/* set initial AGC value */
    -	if (group == 0)
    -		run_bbp_write(sc, 66, 0x2e + sc->lna[0]);
    -	else
    -		run_bbp_write(sc, 66, 0x32 + (sc->lna[group] * 5) / 3);
    +	if (group == 0) {	/* 2GHz band */
    +		if (sc->mac_ver >= 0x3070)
    +			agc = 0x1c + sc->lna[0] * 2;
    +		else
    +			agc = 0x2e + sc->lna[0];
    +	} else {		/* 5GHz band */
    +		if (sc->mac_ver == 0x3572)
    +			agc = 0x22 + (sc->lna[group] * 5) / 3;
    +		else
    +			agc = 0x32 + (sc->lna[group] * 5) / 3;
    +	}
    +	run_set_agc(sc, agc);
     }
     
     static void
    @@ -3122,18 +3238,22 @@ run_rt3070_set_chan(struct run_softc *sc, uint32_t chan)
     {
     	int8_t txpow1, txpow2;
     	uint8_t rf;
    +	int i;
     
     	/* RT3070 is 2GHz only */
     	KASSERT(chan >= 1 && chan <= 14, ("wrong channel selected\n"));
     
    -	/* use Tx power values from EEPROM */
    -	txpow1 = sc->txpow1[chan - 1];
    -	txpow2 = sc->txpow2[chan - 1];
    +	/* find the settings for this channel (we know it exists) */
    +	for (i = 0; rt2860_rf2850[i].chan != chan; i++);
     
    -	run_rt3070_rf_write(sc, 2, run_rf3020_freqs[chan - 1].n);
    -	run_rt3070_rf_write(sc, 3, run_rf3020_freqs[chan - 1].k);
    +	/* use Tx power values from EEPROM */
    +	txpow1 = sc->txpow1[i];
    +	txpow2 = sc->txpow2[i];
    +
    +	run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n);
    +	run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k);
     	run_rt3070_rf_read(sc, 6, &rf);
    -	rf = (rf & ~0x03) | run_rf3020_freqs[chan - 1].r;
    +	rf = (rf & ~0x03) | rt3070_freqs[i].r;
     	run_rt3070_rf_write(sc, 6, rf);
     
     	/* set Tx0 power */
    @@ -3164,27 +3284,179 @@ run_rt3070_set_chan(struct run_softc *sc, uint32_t chan)
     	run_rt3070_rf_write(sc, 23, rf);
     
     	/* program RF filter */
    -	run_rt3070_rf_write(sc, 24, sc->rf24_20mhz);
    -	run_rt3070_rf_write(sc, 31, sc->rf24_20mhz);
    +	run_rt3070_rf_read(sc, 24, &rf);	/* Tx */
    +	rf = (rf & ~0x3f) | sc->rf24_20mhz;
    +	run_rt3070_rf_write(sc, 24, rf);
    +	run_rt3070_rf_read(sc, 31, &rf);	/* Rx */
    +	rf = (rf & ~0x3f) | sc->rf24_20mhz;
    +	run_rt3070_rf_write(sc, 31, rf);
     
     	/* enable RF tuning */
     	run_rt3070_rf_read(sc, 7, &rf);
     	run_rt3070_rf_write(sc, 7, rf | 0x01);
     }
     
    +static void
    +run_rt3572_set_chan(struct run_softc *sc, u_int chan)
    +{
    +	int8_t txpow1, txpow2;
    +	uint32_t tmp;
    +	uint8_t rf;
    +	int i;
    +
    +	/* find the settings for this channel (we know it exists) */
    +	for (i = 0; rt2860_rf2850[i].chan != chan; i++);
    +
    +	/* use Tx power values from EEPROM */
    +	txpow1 = sc->txpow1[i];
    +	txpow2 = sc->txpow2[i];
    +
    +	if (chan <= 14) {
    +		run_bbp_write(sc, 25, sc->bbp25);
    +		run_bbp_write(sc, 26, sc->bbp26);
    +	} else {
    +		/* enable IQ phase correction */
    +		run_bbp_write(sc, 25, 0x09);
    +		run_bbp_write(sc, 26, 0xff);
    +	}
    +
    +	run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n);
    +	run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k);
    +	run_rt3070_rf_read(sc, 6, &rf);
    +	rf  = (rf & ~0x0f) | rt3070_freqs[i].r;
    +	rf |= (chan <= 14) ? 0x08 : 0x04;
    +	run_rt3070_rf_write(sc, 6, rf);
    +
    +	/* set PLL mode */
    +	run_rt3070_rf_read(sc, 5, &rf);
    +	rf &= ~(0x08 | 0x04);
    +	rf |= (chan <= 14) ? 0x04 : 0x08;
    +	run_rt3070_rf_write(sc, 5, rf);
    +
    +	/* set Tx power for chain 0 */
    +	if (chan <= 14)
    +		rf = 0x60 | txpow1;
    +	else
    +		rf = 0xe0 | (txpow1 & 0xc) << 1 | (txpow1 & 0x3);
    +	run_rt3070_rf_write(sc, 12, rf);
    +
    +	/* set Tx power for chain 1 */
    +	if (chan <= 14)
    +		rf = 0x60 | txpow2;
    +	else
    +		rf = 0xe0 | (txpow2 & 0xc) << 1 | (txpow2 & 0x3);
    +	run_rt3070_rf_write(sc, 13, rf);
    +
    +	/* set Tx/Rx streams */
    +	run_rt3070_rf_read(sc, 1, &rf);
    +	rf &= ~0xfc;
    +	if (sc->ntxchains == 1)
    +		rf |= 1 << 7 | 1 << 5;  /* 1T: disable Tx chains 2 & 3 */
    +	else if (sc->ntxchains == 2)
    +		rf |= 1 << 7;           /* 2T: disable Tx chain 3 */
    +	if (sc->nrxchains == 1)
    +		rf |= 1 << 6 | 1 << 4;  /* 1R: disable Rx chains 2 & 3 */
    +	else if (sc->nrxchains == 2)
    +		rf |= 1 << 6;           /* 2R: disable Rx chain 3 */
    +	run_rt3070_rf_write(sc, 1, rf);
    +
    +	/* set RF offset */
    +	run_rt3070_rf_read(sc, 23, &rf);
    +	rf = (rf & ~0x7f) | sc->freq;
    +	run_rt3070_rf_write(sc, 23, rf);
    +
    +	/* program RF filter */
    +	rf = sc->rf24_20mhz;
    +	run_rt3070_rf_write(sc, 24, rf);	/* Tx */
    +	run_rt3070_rf_write(sc, 31, rf);	/* Rx */
    +
    +	/* enable RF tuning */
    +	run_rt3070_rf_read(sc, 7, &rf);
    +	rf = (chan <= 14) ? 0xd8 : ((rf & ~0xc8) | 0x14);
    +	run_rt3070_rf_write(sc, 7, rf);
    +
    +	/* TSSI */
    +	rf = (chan <= 14) ? 0xc3 : 0xc0;
    +	run_rt3070_rf_write(sc, 9, rf);
    +
    +	/* set loop filter 1 */
    +	run_rt3070_rf_write(sc, 10, 0xf1);
    +	/* set loop filter 2 */
    +	run_rt3070_rf_write(sc, 11, (chan <= 14) ? 0xb9 : 0x00);
    +
    +	/* set tx_mx2_ic */
    +	run_rt3070_rf_write(sc, 15, (chan <= 14) ? 0x53 : 0x43);
    +	/* set tx_mx1_ic */
    +	if (chan <= 14)
    +		rf = 0x48 | sc->txmixgain_2ghz;
    +	else
    +		rf = 0x78 | sc->txmixgain_5ghz;
    +	run_rt3070_rf_write(sc, 16, rf);
    +
    +	/* set tx_lo1 */
    +	run_rt3070_rf_write(sc, 17, 0x23);
    +	/* set tx_lo2 */
    +	if (chan <= 14)
    +		rf = 0x93;
    +	else if (chan <= 64)
    +		rf = 0xb7;
    +	else if (chan <= 128)
    +		rf = 0x74;
    +	else
    +		rf = 0x72;
    +	run_rt3070_rf_write(sc, 19, rf);
    +
    +	/* set rx_lo1 */
    +	if (chan <= 14)
    +		rf = 0xb3;
    +	else if (chan <= 64)
    +		rf = 0xf6;
    +	else if (chan <= 128)
    +		rf = 0xf4;
    +	else
    +		rf = 0xf3;
    +	run_rt3070_rf_write(sc, 20, rf);
    +
    +	/* set pfd_delay */
    +	if (chan <= 14)
    +		rf = 0x15;
    +	else if (chan <= 64)
    +		rf = 0x3d;
    +	else
    +		rf = 0x01;
    +	run_rt3070_rf_write(sc, 25, rf);
    +
    +	/* set rx_lo2 */
    +	run_rt3070_rf_write(sc, 26, (chan <= 14) ? 0x85 : 0x87);
    +	/* set ldo_rf_vc */
    +	run_rt3070_rf_write(sc, 27, (chan <= 14) ? 0x00 : 0x01);
    +	/* set drv_cc */
    +	run_rt3070_rf_write(sc, 29, (chan <= 14) ? 0x9b : 0x9f);
    +
    +	run_read(sc, RT2860_GPIO_CTRL, &tmp);
    +	tmp &= ~0x8080;
    +	if (chan <= 14)
    +		tmp |= 0x80;
    +	run_write(sc, RT2860_GPIO_CTRL, tmp);
    +
    +	/* enable RF tuning */
    +	run_rt3070_rf_read(sc, 7, &rf);
    +	run_rt3070_rf_write(sc, 7, rf | 0x01);
    +
    +	run_delay(sc, 2);
    +}
    +
     static void
     run_set_rx_antenna(struct run_softc *sc, int aux)
     {
     	uint32_t tmp;
     
     	if (aux) {
    -		run_read(sc, RT2860_PCI_EECTRL, &tmp);
    -		run_write(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C);
    +		run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 0);
     		run_read(sc, RT2860_GPIO_CTRL, &tmp);
     		run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08);
     	} else {
    -		run_read(sc, RT2860_PCI_EECTRL, &tmp);
    -		run_write(sc, RT2860_PCI_EECTRL, tmp | RT2860_C);
    +		run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 1);
     		run_read(sc, RT2860_GPIO_CTRL, &tmp);
     		run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808);
     	}
    @@ -3200,14 +3472,13 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
     	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
     		return EINVAL;
     
    -	if ((sc->mac_rev >> 16) >= 0x3070)
    +	if (sc->mac_ver == 0x3572)
    +		run_rt3572_set_chan(sc, chan);
    +	else if (sc->mac_ver >= 0x3070)
     		run_rt3070_set_chan(sc, chan);
     	else
     		run_rt2870_set_chan(sc, chan);
     
    -	/* 802.11a uses a 16 microseconds short interframe space */
    -	sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
    -
     	/* determine channel group */
     	if (chan <= 14)
     		group = 0;
    @@ -3373,7 +3644,7 @@ run_usb_timeout_cb(void *arg, int pending)
     	struct run_softc *sc = arg;
     	struct ieee80211vap *vap = &sc->sc_rvp->vap;
     
    -	RUN_LOCK_ASSERT(sc, MA_OWNED);
    +	RUN_LOCK(sc);
     
     	if(vap->iv_state == IEEE80211_S_RUN &&
     	    vap->iv_opmode != IEEE80211_M_STA)
    @@ -3384,6 +3655,8 @@ run_usb_timeout_cb(void *arg, int pending)
     		ieee80211_cancel_scan(vap);
     	} else
     		DPRINTF("timeout by unknown cause\n");
    +
    +	RUN_UNLOCK(sc);
     }
     
     static void
    @@ -3611,15 +3884,14 @@ run_bbp_init(struct run_softc *sc)
     	}
     
     	/* fix BBP84 for RT2860E */
    -	if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101)
    -		run_bbp_write(sc,  84, 0x19);
    +	if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101)
    +		run_bbp_write(sc, 84, 0x19);
     
    -	if ((sc->mac_rev >> 16) >= 0x3070) {
    +	if (sc->mac_ver >= 0x3070) {
     		run_bbp_write(sc, 79, 0x13);
     		run_bbp_write(sc, 80, 0x05);
     		run_bbp_write(sc, 81, 0x33);
    -		/* XXX RT3090 needs more */
    -	} else if (sc->mac_rev == 0x28600100) {
    +	} else if (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) {
     		run_bbp_write(sc, 69, 0x16);
     		run_bbp_write(sc, 73, 0x12);
     	}
    @@ -3630,7 +3902,7 @@ static int
     run_rt3070_rf_init(struct run_softc *sc)
     {
     	uint32_t tmp;
    -	uint8_t rf, bbp4;
    +	uint8_t rf, target, bbp4;
     	int i;
     
     	run_rt3070_rf_read(sc, 30, &rf);
    @@ -3640,44 +3912,58 @@ run_rt3070_rf_init(struct run_softc *sc)
     	run_rt3070_rf_write(sc, 30, rf & ~0x80);
     
     	/* initialize RF registers to default value */
    -	for (i = 0; i < nitems(rt3070_def_rf); i++) {
    -		run_rt3070_rf_write(sc, rt3070_def_rf[i].reg,
    -		    rt3070_def_rf[i].val);
    +	if (sc->mac_ver == 0x3572) {
    +		for (i = 0; i < nitems(rt3572_def_rf); i++) {
    +			run_rt3070_rf_write(sc, rt3572_def_rf[i].reg,
    +			    rt3572_def_rf[i].val);
    +		}
    +	} else {
    +		for (i = 0; i < nitems(rt3070_def_rf); i++) {
    +			run_rt3070_rf_write(sc, rt3070_def_rf[i].reg,
    +			    rt3070_def_rf[i].val);
    +		}
     	}
    -	if ((sc->mac_rev >> 16) == 0x3070) {
    +
    +	if (sc->mac_ver == 0x3070) {
     		/* change voltage from 1.2V to 1.35V for RT3070 */
     		run_read(sc, RT3070_LDO_CFG0, &tmp);
     		tmp = (tmp & ~0x0f000000) | 0x0d000000;
     		run_write(sc, RT3070_LDO_CFG0, tmp);
     
    -	} else if ((sc->mac_rev >> 16) == 0x3071) {
    +	} else if (sc->mac_ver == 0x3071) {
     		run_rt3070_rf_read(sc, 6, &rf);
     		run_rt3070_rf_write(sc, 6, rf | 0x40);
     		run_rt3070_rf_write(sc, 31, 0x14);
     
     		run_read(sc, RT3070_LDO_CFG0, &tmp);
     		tmp &= ~0x1f000000;
    -		if ((sc->mac_rev & 0xffff) < 0x0211)
    -			tmp |= 0x0d000000;
    +		if (sc->mac_rev < 0x0211)
    +			tmp |= 0x0d000000;	/* 1.3V */
     		else
    -			tmp |= 0x01000000;
    +			tmp |= 0x01000000;	/* 1.2V */
     		run_write(sc, RT3070_LDO_CFG0, tmp);
     
     		/* patch LNA_PE_G1 */
     		run_read(sc, RT3070_GPIO_SWITCH, &tmp);
     		run_write(sc, RT3070_GPIO_SWITCH, tmp & ~0x20);
    -	} else if((sc->mac_rev >> 16) == 0x3572){
    -		if ((sc->mac_rev & 0xffff) < 0x0211){
    +	} else if(sc->mac_ver == 0x3572){
    +		run_rt3070_rf_read(sc, 6, &rf);
    +		run_rt3070_rf_write(sc, 6, rf | 0x40);
    +
    +		if (sc->mac_rev < 0x0211){
    +			/* increase voltage from 1.2V to 1.35V */
     			run_read(sc, RT3070_LDO_CFG0, &tmp);
     			tmp = (tmp & ~0x0f000000) | 0x0d000000;
     			run_write(sc, RT3070_LDO_CFG0, tmp);
     		} else {
    +			/* increase voltage from 1.2V to 1.35V */
     			run_read(sc, RT3070_LDO_CFG0, &tmp);
     			tmp = (tmp & ~0x1f000000) | 0x0d000000;
     			run_write(sc, RT3070_LDO_CFG0, tmp);
     
     			run_delay(sc, 1);	/* wait for 1msec */
     
    +			/* decrease voltage back to 1.2V */
     			tmp = (tmp & ~0x1f000000) | 0x01000000;
     			run_write(sc, RT3070_LDO_CFG0, tmp);
     		}
    @@ -3689,27 +3975,47 @@ run_rt3070_rf_init(struct run_softc *sc)
     
     	/* calibrate filter for 20MHz bandwidth */
     	sc->rf24_20mhz = 0x1f;	/* default value */
    -	run_rt3070_filter_calib(sc, 0x07, 0x16, &sc->rf24_20mhz);
    +	target = (sc->mac_ver < 0x3071) ? 0x16 : 0x13;
    +	run_rt3070_filter_calib(sc, 0x07, target, &sc->rf24_20mhz);
     
     	/* select 40MHz bandwidth */
     	run_bbp_read(sc, 4, &bbp4);
     	run_bbp_write(sc, 4, (bbp4 & ~0x08) | 0x10);
    +	run_rt3070_rf_read(sc, 31, &rf);
    +	run_rt3070_rf_write(sc, 31, rf | 0x20);
     
     	/* calibrate filter for 40MHz bandwidth */
     	sc->rf24_40mhz = 0x2f;	/* default value */
    -	run_rt3070_filter_calib(sc, 0x27, 0x19, &sc->rf24_40mhz);
    +	target = (sc->mac_ver < 0x3071) ? 0x19 : 0x15;
    +	run_rt3070_filter_calib(sc, 0x27, target, &sc->rf24_40mhz);
     
     	/* go back to 20MHz bandwidth */
     	run_bbp_read(sc, 4, &bbp4);
     	run_bbp_write(sc, 4, bbp4 & ~0x18);
     
    -	if ((sc->mac_rev & 0xffff) < 0x0211)
    +	if (sc->mac_ver == 0x3572) {
    +		/* save default BBP registers 25 and 26 values */
    +		run_bbp_read(sc, 25, &sc->bbp25);
    +		run_bbp_read(sc, 26, &sc->bbp26);
    +	} else if (sc->mac_rev < 0x0211)
     		run_rt3070_rf_write(sc, 27, 0x03);
     
     	run_read(sc, RT3070_OPT_14, &tmp);
     	run_write(sc, RT3070_OPT_14, tmp | 1);
     
    -	if ((sc->mac_rev >> 16) == 0x3071) {
    +	if (sc->mac_ver == 0x3070 || sc->mac_ver == 0x3071) {
    +		run_rt3070_rf_read(sc, 17, &rf);
    +		rf &= ~RT3070_TX_LO1;
    +		if ((sc->mac_ver == 0x3070 ||
    +		     (sc->mac_ver == 0x3071 && sc->mac_rev >= 0x0211)) &&
    +		    !sc->ext_2ghz_lna)
    +			rf |= 0x20;	/* fix for long range Rx issue */
    +		if (sc->txmixgain_2ghz >= 1)
    +			rf = (rf & ~0x7) | sc->txmixgain_2ghz;
    +		run_rt3070_rf_write(sc, 17, rf);
    +	}
    +
    +	if (sc->mac_rev == 0x3071) {
     		run_rt3070_rf_read(sc, 1, &rf);
     		rf &= ~(RT3070_RX0_PD | RT3070_TX0_PD);
     		rf |= RT3070_RF_BLOCK | RT3070_RX1_PD | RT3070_TX1_PD;
    @@ -3718,21 +4024,18 @@ run_rt3070_rf_init(struct run_softc *sc)
     		run_rt3070_rf_read(sc, 15, &rf);
     		run_rt3070_rf_write(sc, 15, rf & ~RT3070_TX_LO2);
     
    -		run_rt3070_rf_read(sc, 17, &rf);
    -		rf &= ~RT3070_TX_LO1;
    -		if ((sc->mac_rev & 0xffff) >= 0x0211 && !sc->ext_2ghz_lna)
    -			rf |= 0x20;	/* fix for long range Rx issue */
    -		run_rt3070_rf_write(sc, 17, rf);
    -
     		run_rt3070_rf_read(sc, 20, &rf);
     		run_rt3070_rf_write(sc, 20, rf & ~RT3070_RX_LO1);
     
     		run_rt3070_rf_read(sc, 21, &rf);
     		run_rt3070_rf_write(sc, 21, rf & ~RT3070_RX_LO2);
    +	}
     
    +	if (sc->mac_ver == 0x3070 || sc->mac_ver == 0x3071) {
    +		/* fix Tx to Rx IQ glitch by raising RF voltage */
     		run_rt3070_rf_read(sc, 27, &rf);
     		rf &= ~0x77;
    -		if ((sc->mac_rev & 0xffff) < 0x0211)
    +		if (sc->mac_rev < 0x0211)
     			rf |= 0x03;
     		run_rt3070_rf_write(sc, 27, rf);
     	}
    @@ -3748,7 +4051,8 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
     	int ntries;
     
     	/* program filter */
    -	rf24 = init;	/* initial filter value */
    +	run_rt3070_rf_read(sc, 24, &rf24);
    +	rf24 = (rf24 & 0xc0) | init;	/* initial filter value */
     	run_rt3070_rf_write(sc, 24, rf24);
     
     	/* enable baseband loopback mode */
    @@ -3803,6 +4107,86 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
     	return 0;
     }
     
    +static void
    +run_rt3070_rf_setup(struct run_softc *sc)
    +{
    +	uint8_t bbp, rf;
    +	int i;
    +
    +	if (sc->mac_ver == 0x3572) {
    +		/* enable DC filter */
    +		if (sc->mac_rev >= 0x0201)
    +			run_bbp_write(sc, 103, 0xc0);
    +
    +		run_bbp_read(sc, 138, &bbp);
    +		if (sc->ntxchains == 1)
    +			bbp |= 0x20;	/* turn off DAC1 */
    +		if (sc->nrxchains == 1)
    +			bbp &= ~0x02;	/* turn off ADC1 */
    +		run_bbp_write(sc, 138, bbp);
    +
    +		if (sc->mac_rev >= 0x0211) {
    +			/* improve power consumption */
    +			run_bbp_read(sc, 31, &bbp);
    +			run_bbp_write(sc, 31, bbp & ~0x03);
    +		}
    +
    +		run_rt3070_rf_read(sc, 16, &rf);
    +		rf = (rf & ~0x07) | sc->txmixgain_2ghz;
    +		run_rt3070_rf_write(sc, 16, rf);
    +
    +	} else if (sc->mac_ver == 0x3071) {
    +		/* enable DC filter */
    +		if (sc->mac_rev >= 0x0201)
    +			run_bbp_write(sc, 103, 0xc0);
    +
    +		run_bbp_read(sc, 138, &bbp);
    +		if (sc->ntxchains == 1)
    +			bbp |= 0x20;	/* turn off DAC1 */
    +		if (sc->nrxchains == 1)
    +			bbp &= ~0x02;	/* turn off ADC1 */
    +		run_bbp_write(sc, 138, bbp);
    +
    +		if (sc->mac_rev >= 0x0211) {
    +			/* improve power consumption */
    +			run_bbp_read(sc, 31, &bbp);
    +			run_bbp_write(sc, 31, bbp & ~0x03);
    +		}
    +
    +		run_write(sc, RT2860_TX_SW_CFG1, 0);
    +		if (sc->mac_rev < 0x0211) {
    +			run_write(sc, RT2860_TX_SW_CFG2,
    +			    sc->patch_dac ? 0x2c : 0x0f);
    +		} else
    +			run_write(sc, RT2860_TX_SW_CFG2, 0);
    +
    +	} else if (sc->mac_ver == 0x3070) {
    +		if (sc->mac_rev >= 0x0201) {
    +			/* enable DC filter */
    +			run_bbp_write(sc, 103, 0xc0);
    +
    +			/* improve power consumption */
    +			run_bbp_read(sc, 31, &bbp);
    +			run_bbp_write(sc, 31, bbp & ~0x03);
    +		}
    +
    +		if (sc->mac_rev < 0x0211) {
    +			run_write(sc, RT2860_TX_SW_CFG1, 0);
    +			run_write(sc, RT2860_TX_SW_CFG2, 0x2c);
    +		} else
    +			run_write(sc, RT2860_TX_SW_CFG2, 0);
    +	}
    +
    +	/* initialize RF registers from ROM for >=RT3071*/
    +	if (sc->mac_ver >= 0x3071) {
    +		for (i = 0; i < 10; i++) {
    +			if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff)
    +				continue;
    +			run_rt3070_rf_write(sc, sc->rf[i].reg, sc->rf[i].val);
    +		}
    +	}
    +}
    +
     static int
     run_txrx_enable(struct run_softc *sc)
     {
    @@ -3854,7 +4238,6 @@ run_init_locked(struct run_softc *sc)
     {
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
    -	struct ieee80211vap *vap = &sc->sc_rvp->vap;
     	uint32_t tmp;
     	uint8_t bbp1, bbp3;
     	int i;
    @@ -3921,12 +4304,10 @@ run_init_locked(struct run_softc *sc)
     	run_write(sc, RT2860_WMM_CWMIN_CFG, 0x00002344);
     	run_write(sc, RT2860_WMM_CWMAX_CFG, 0x000034aa);
     
    -	if ((sc->mac_rev >> 16) >= 0x3070) {
    +	if (sc->mac_ver >= 0x3070) {
     		/* set delay of PA_PE assertion to 1us (unit of 0.25us) */
     		run_write(sc, RT2860_TX_SW_CFG0,
     		    4 << RT2860_DLY_PAPE_EN_SHIFT);
    -		run_write(sc, RT2860_TX_SW_CFG1, 0);
    -		run_write(sc, RT2860_TX_SW_CFG2, 0x1f);
     	}
     
     	/* wait while MAC is busy */
    @@ -3969,7 +4350,7 @@ run_init_locked(struct run_softc *sc)
     	tmp = (tmp & ~0xff) | 0x1e;
     	run_write(sc, RT2860_US_CYC_CNT, tmp);
     
    -	if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101)
    +	if (sc->mac_rev != 0x0101)
     		run_write(sc, RT2860_TXOP_CTRL_CFG, 0x0000583f);
     
     	run_write(sc, RT2860_WMM_TXOP0_CFG, 0);
    @@ -3991,6 +4372,9 @@ run_init_locked(struct run_softc *sc)
     	(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1]);
     	(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2]);
     
    +	if (sc->mac_ver >= 0x3070)
    +		run_rt3070_rf_init(sc);
    +
     	/* disable non-existing Rx chains */
     	run_bbp_read(sc, 3, &bbp3);
     	bbp3 &= ~(1 << 3 | 1 << 4);
    @@ -4006,11 +4390,10 @@ run_init_locked(struct run_softc *sc)
     		bbp1 &= ~(1 << 3 | 1 << 4);
     	run_bbp_write(sc, 1, bbp1);
     
    -	if ((sc->mac_rev >> 16) >= 0x3070)
    -		run_rt3070_rf_init(sc);
    +	if (sc->mac_ver >= 0x3070)
    +		run_rt3070_rf_setup(sc);
     
     	/* select default channel */
    -	vap->iv_bss->ni_chan = ic->ic_curchan;	/* ic_bsschan?? */
     	run_set_chan(sc, ic->ic_curchan);
     
     	/* setup initial protection mode */
    @@ -4063,25 +4446,21 @@ run_stop(void *arg)
     
     	RUN_LOCK_ASSERT(sc, MA_OWNED);
     
    -	if (ic->ic_flags & IEEE80211_F_SCAN)
    -		ieee80211_cancel_scan(&sc->sc_rvp->vap);
    +	if(sc->sc_rvp != NULL){
    +		sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
    +		if (ic->ic_flags & IEEE80211_F_SCAN)
    +			ieee80211_cancel_scan(&sc->sc_rvp->vap);
    +	}
     
     	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
     		run_set_leds(sc, 0);	/* turn all LEDs off */
     
     	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
     
    -	sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
    -
     	RUN_UNLOCK(sc);
     
    -	/* drain them all */
    -	usb_callout_drain(&sc->sc_rvp->amrr_ch);
    -	ieee80211_draintask(ic, &sc->sc_rvp->amrr_task);
    -	ieee80211_draintask(ic, &sc->wme_task);
     	for(i = 0; i < RUN_N_XFER; i++)
     		usbd_transfer_drain(sc->sc_xfer[i]);
    -	ieee80211_draintask(ic, &sc->usb_timeout_task);
     
     	RUN_LOCK(sc);
     
    diff --git a/sys/dev/usb/wlan/if_runreg.h b/sys/dev/usb/wlan/if_runreg.h
    index f630fb10e67..f872fad9a59 100644
    --- a/sys/dev/usb/wlan/if_runreg.h
    +++ b/sys/dev/usb/wlan/if_runreg.h
    @@ -310,7 +310,8 @@
     #define RT2860_MCU_CMD_LED1	0x52
     #define RT2860_MCU_CMD_LED2	0x53
     #define RT2860_MCU_CMD_LED3	0x54
    -#define RT2860_MCU_CMD_BOOT	0x72
    +#define RT2860_MCU_CMD_RFRESET	0x72
    +#define RT2860_MCU_CMD_ANTSEL	0x73
     #define RT2860_MCU_CMD_BBP	0x80
     #define RT2860_MCU_CMD_PSLEVEL	0x83
     
    @@ -890,6 +891,7 @@ struct rt2860_rxwi {
     #define RT2860_EEPROM_TSSI5_5GHZ	0x6e
     #define RT2860_EEPROM_RPWR		0x6f
     #define RT2860_EEPROM_BBP_BASE		0x78
    +#define RT3071_EEPROM_RF_BASE		0x82
     
     #define RT2860_RIDX_CCK1	 0
     #define RT2860_RIDX_CCK11	 3
    @@ -903,18 +905,18 @@ static const struct rt2860_rate {
     	uint16_t	sp_ack_dur;
     	uint16_t	lp_ack_dur;
     } rt2860_rates[] = {
    -	{   2, 0, IEEE80211_T_DS,   0, 304, 304 },
    -	{   4, 1, IEEE80211_T_DS,   1, 248, 152 },
    -	{  11, 2, IEEE80211_T_DS,   2, 213, 117 },
    -	{  22, 3, IEEE80211_T_DS,   3, 203, 107 },
    -	{  12, 0, IEEE80211_T_OFDM, 4,  50,  50 },
    -	{  18, 1, IEEE80211_T_OFDM, 4,  42,  42 },
    -	{  24, 2, IEEE80211_T_OFDM, 6,  38,  38 },
    -	{  36, 3, IEEE80211_T_OFDM, 6,  34,  34 },
    -	{  48, 4, IEEE80211_T_OFDM, 8,  34,  34 },
    -	{  72, 5, IEEE80211_T_OFDM, 8,  30,  30 },
    -	{  96, 6, IEEE80211_T_OFDM, 8,  30,  30 },
    -	{ 108, 7, IEEE80211_T_OFDM, 8,  30,  30 }
    +	{   2, 0, IEEE80211_T_DS,   0, 314, 314 },
    +	{   4, 1, IEEE80211_T_DS,   1, 258, 162 },
    +	{  11, 2, IEEE80211_T_DS,   2, 223, 127 },
    +	{  22, 3, IEEE80211_T_DS,   3, 213, 117 },
    +	{  12, 0, IEEE80211_T_OFDM, 4,  60,  60 },
    +	{  18, 1, IEEE80211_T_OFDM, 4,  52,  52 },
    +	{  24, 2, IEEE80211_T_OFDM, 6,  48,  48 },
    +	{  36, 3, IEEE80211_T_OFDM, 6,  44,  44 },
    +	{  48, 4, IEEE80211_T_OFDM, 8,  44,  44 },
    +	{  72, 5, IEEE80211_T_OFDM, 8,  40,  40 },
    +	{  96, 6, IEEE80211_T_OFDM, 8,  40,  40 },
    +	{ 108, 7, IEEE80211_T_OFDM, 8,  40,  40 }
     };
     
     /*
    @@ -1034,7 +1036,8 @@ static const struct rt2860_rate {
     	{  91, 0x04 },	\
     	{  92, 0x00 },	\
     	{ 103, 0x00 },	\
    -	{ 105, 0x05 }
    +	{ 105, 0x05 },	\
    +	{ 106, 0x35 }
     
     /*
      * Default settings for RF registers; values derived from the reference driver.
    @@ -1088,8 +1091,13 @@ static const struct rt2860_rate {
     	{ 157, 0x100bb1, 0x1300e3, 0x05e014, 0x001407 },	\
     	{ 159, 0x100bb1, 0x1300e3, 0x05e014, 0x001409 },	\
     	{ 161, 0x100bb1, 0x1300e4, 0x05e014, 0x001401 },	\
    -	{ 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 }
    +	{ 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 },	\
    +	{ 167, 0x100bb1, 0x1300f4, 0x05e014, 0x001407 },	\
    +	{ 169, 0x100bb1, 0x1300f4, 0x05e014, 0x001409 },	\
    +	{ 171, 0x100bb1, 0x1300f5, 0x05e014, 0x001401 },	\
    +	{ 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 }
     
    +#if 0
     #define RT3070_RF3020	\
     	{ 241, 2, 2 },	\
     	{ 241, 2, 7 },	\
    @@ -1105,6 +1113,62 @@ static const struct rt2860_rate {
     	{ 246, 2, 7 },	\
     	{ 247, 2, 2 },	\
     	{ 248, 2, 4 }
    +#endif
    +
    +#define RT3070_RF3052		\
    +	{ 0xf1, 2,  2 },	\
    +	{ 0xf1, 2,  7 },	\
    +	{ 0xf2, 2,  2 },	\
    +	{ 0xf2, 2,  7 },	\
    +	{ 0xf3, 2,  2 },	\
    +	{ 0xf3, 2,  7 },	\
    +	{ 0xf4, 2,  2 },	\
    +	{ 0xf4, 2,  7 },	\
    +	{ 0xf5, 2,  2 },	\
    +	{ 0xf5, 2,  7 },	\
    +	{ 0xf6, 2,  2 },	\
    +	{ 0xf6, 2,  7 },	\
    +	{ 0xf7, 2,  2 },	\
    +	{ 0xf8, 2,  4 },	\
    +	{ 0x56, 0,  4 },	\
    +	{ 0x56, 0,  6 },	\
    +	{ 0x56, 0,  8 },	\
    +	{ 0x57, 0,  0 },	\
    +	{ 0x57, 0,  2 },	\
    +	{ 0x57, 0,  4 },	\
    +	{ 0x57, 0,  8 },	\
    +	{ 0x57, 0, 10 },	\
    +	{ 0x58, 0,  0 },	\
    +	{ 0x58, 0,  4 },	\
    +	{ 0x58, 0,  6 },	\
    +	{ 0x58, 0,  8 },	\
    +	{ 0x5b, 0,  8 },	\
    +	{ 0x5b, 0, 10 },	\
    +	{ 0x5c, 0,  0 },	\
    +	{ 0x5c, 0,  4 },	\
    +	{ 0x5c, 0,  6 },	\
    +	{ 0x5c, 0,  8 },	\
    +	{ 0x5d, 0,  0 },	\
    +	{ 0x5d, 0,  2 },	\
    +	{ 0x5d, 0,  4 },	\
    +	{ 0x5d, 0,  8 },	\
    +	{ 0x5d, 0, 10 },	\
    +	{ 0x5e, 0,  0 },	\
    +	{ 0x5e, 0,  4 },	\
    +	{ 0x5e, 0,  6 },	\
    +	{ 0x5e, 0,  8 },	\
    +	{ 0x5f, 0,  0 },	\
    +	{ 0x5f, 0,  9 },	\
    +	{ 0x5f, 0, 11 },	\
    +	{ 0x60, 0,  1 },	\
    +	{ 0x60, 0,  5 },	\
    +	{ 0x60, 0,  7 },	\
    +	{ 0x60, 0,  9 },	\
    +	{ 0x61, 0,  1 },	\
    +	{ 0x61, 0,  3 },	\
    +	{ 0x61, 0,  5 },	\
    +	{ 0x61, 0,  7 },	\
    +	{ 0x61, 0,  9 }
     
     #define RT3070_DEF_RF	\
     	{  4, 0x40 },	\
    @@ -1127,4 +1191,37 @@ static const struct rt2860_rate {
     	{ 25, 0x01 },	\
     	{ 29, 0x1f }
     
    +#define RT3572_DEF_RF	\
    +	{  0, 0x70 },	\
    +	{  1, 0x81 },	\
    +	{  2, 0xf1 },	\
    +	{  3, 0x02 },	\
    +	{  4, 0x4c },	\
    +	{  5, 0x05 },	\
    +	{  6, 0x4a },	\
    +	{  7, 0xd8 },	\
    +	{  9, 0xc3 },	\
    +	{ 10, 0xf1 },	\
    +	{ 11, 0xb9 },	\
    +	{ 12, 0x70 },	\
    +	{ 13, 0x65 },	\
    +	{ 14, 0xa0 },	\
    +	{ 15, 0x53 },	\
    +	{ 16, 0x4c },	\
    +	{ 17, 0x23 },	\
    +	{ 18, 0xac },	\
    +	{ 19, 0x93 },	\
    +	{ 20, 0xb3 },	\
    +	{ 21, 0xd0 },	\
    +	{ 22, 0x00 },  	\
    +	{ 23, 0x3c },	\
    +	{ 24, 0x16 },	\
    +	{ 25, 0x15 },	\
    +	{ 26, 0x85 },	\
    +	{ 27, 0x00 },	\
    +	{ 28, 0x00 },	\
    +	{ 29, 0x9b },	\
    +	{ 30, 0x09 },	\
    +	{ 31, 0x10 }
    +
     #endif	/* _IF_RUNREG_H_ */
    diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
    index 28d6feb52b1..87b15bc7034 100644
    --- a/sys/dev/usb/wlan/if_runvar.h
    +++ b/sys/dev/usb/wlan/if_runvar.h
    @@ -2,7 +2,8 @@
     
     /*-
      * Copyright (c) 2008,2009 Damien Bergamini 
    - *	ported to FreeBSD by Akinori Furukoshi 
    + * ported to FreeBSD by Akinori Furukoshi 
    + * USB Consulting, Hans Petter Selasky 
      *
      * Permission to use, copy, modify, and distribute this software for any
      * purpose with or without fee is hereby granted, provided that the above
    @@ -154,21 +155,28 @@ struct run_softc {
     	int				(*sc_srom_read)(struct run_softc *,
     					    uint16_t, uint16_t *);
     
    -	uint32_t			mac_rev;
    +	uint16_t			mac_ver;
    +	uint16_t			mac_rev;
     	uint8_t				rf_rev;
     	uint8_t				freq;
     	uint8_t				ntxchains;
     	uint8_t				nrxchains;
     	int				fixed_ridx;
     
    +	uint8_t				bbp25;
    +	uint8_t				bbp26;
     	uint8_t				rf24_20mhz;
     	uint8_t				rf24_40mhz;
    +	uint8_t				patch_dac;
    +	uint8_t				rfswitch;
     	uint8_t				ext_2ghz_lna;
     	uint8_t				ext_5ghz_lna;
     	uint8_t				calib_2ghz;
     	uint8_t				calib_5ghz;
    -	int8_t				txpow1[50];
    -	int8_t				txpow2[50];
    +	uint8_t				txmixgain_2ghz;
    +	uint8_t				txmixgain_5ghz;
    +	int8_t				txpow1[54];
    +	int8_t				txpow2[54];
     	int8_t				rssi_2ghz[3];
     	int8_t				rssi_5ghz[3];
     	uint8_t				lna[4];
    @@ -176,7 +184,7 @@ struct run_softc {
     	struct {
     		uint8_t	reg;
     		uint8_t	val;
    -	}				bbp[8];
    +	}				bbp[8], rf[10];
     	uint8_t				leds;
     	uint16_t			led[3];
     	uint32_t			txpow20mhz[5];
    @@ -196,8 +204,6 @@ struct run_softc {
     
     	struct mbuf			*rx_m;
     
    -	int				sifs;
    -
     	union {
     		struct run_rx_radiotap_header th;
     		uint8_t	pad[64];
    
    From 67232500cdb9a901d1a620b9cd2742ad95619722 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:29:14 +0000
    Subject: [PATCH 1882/2592] MFC r205043
    
     Add device ID for the NATURAL4000 keyboard
    ---
     sys/dev/usb/usbdevs | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index 6007cf3f163..e3889586e83 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -2062,6 +2062,7 @@ product MICROSOFT WLNOTEBOOK2	0x00e1	Wireless Optical Mouse 3000 (Model 1056)
     product MICROSOFT WLNOTEBOOK3	0x00d2	Wireless Optical Mouse 3000 (Model 1049)
     product MICROSOFT WLUSBMOUSE	0x00b9	Wireless USB Mouse
     product MICROSOFT XBOX360	0x0292	XBOX 360 WLAN
    +product MICROSOFT NATURAL4000	0x00db	Natural Ergonomic Keyboard 4000
     
     /* Microtech products */
     product MICROTECH SCSIDB25	0x0004	USB-SCSI-DB25
    
    From 57023f990cfe4fcedfc3296873e6e74834020c79 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:29:38 +0000
    Subject: [PATCH 1883/2592] MFC r205801
    
     Add a couple of usb product IDs.
    
    Submitted by:	Dmitry Luhtionov @ gmail.com
    ---
     sys/dev/usb/usbdevs | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index e3889586e83..0492545dfdf 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -2519,12 +2519,14 @@ product QUALCOMMINC E2003	0x2003	3G modem
     
     /* Quanta products */
     /* Quanta products */
    +product QUANTA RW6815_1		0x00ce	HP iPAQ rw6815
     product QUANTA RT3070		0x0304	RT3070
     product QUANTA Q101		0xea02	HSDPA modem
     product QUANTA Q111		0xea03	HSDPA modem
     product QUANTA GLX		0xea04	HSDPA modem
     product QUANTA GKE		0xea05	HSDPA modem
     product QUANTA GLE		0xea06	HSDPA modem
    +product QUANTA RW6815_2		0xf003	HP iPAQ rw6815
     
     /* Qtronix products */
     product QTRONIX 980N		0x2011	Scorpion-980N keyboard
    @@ -2732,6 +2734,7 @@ product SIERRA AIRCARD875	0x6820	Aircard 875 HSDPA
     product SIERRA TRUINSTALL	0x0fff	Aircard Tru Installer
     
     /* Sigmatel products */
    +product SIGMATEL WBT_3052	0x4200	WBT-3052 IrDA/USB Bridge
     product SIGMATEL I_BEAD100	0x8008	i-Bead 100 MP3 Player
     
     /* SIIG products */
    
    From 441f5e4c8ab6eb6400770a8dc0f44744c131645e Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:30:02 +0000
    Subject: [PATCH 1884/2592] MFC r205802
    
     Add PCI IDs for two more nForce controllers.
    
    Submitted by:	Dmitry Luhtionov @ gmail.com
    ---
     sys/dev/usb/controller/ehci_pci.c | 2 ++
     sys/dev/usb/controller/ohci_pci.c | 2 ++
     2 files changed, 4 insertions(+)
    
    diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
    index c81122b6d5f..bd7afcf8ade 100644
    --- a/sys/dev/usb/controller/ehci_pci.c
    +++ b/sys/dev/usb/controller/ehci_pci.c
    @@ -215,6 +215,8 @@ ehci_pci_match(device_t self)
     		return "NVIDIA nForce3 250 USB 2.0 controller";
     	case 0x005b10de:
     		return "NVIDIA nForce4 USB 2.0 controller";
    +	case 0x036d10de:
    +		return "NVIDIA nForce MCP55 USB 2.0 controller";
     	case 0x03f210de:
     		return "NVIDIA nForce MCP61 USB 2.0 controller";
     	case 0x0aa610de:
    diff --git a/sys/dev/usb/controller/ohci_pci.c b/sys/dev/usb/controller/ohci_pci.c
    index 395947174e5..a4fcd9f13b2 100644
    --- a/sys/dev/usb/controller/ohci_pci.c
    +++ b/sys/dev/usb/controller/ohci_pci.c
    @@ -173,6 +173,8 @@ ohci_pci_match(device_t self)
     	case 0x00d710de:
     		return ("nVidia nForce3 USB Controller");
     
    +	case 0x036c10de:
    +		return ("nVidia nForce MCP55 USB Controller");
     	case 0x03f110de:
     		return ("nVidia nForce MCP61 USB Controller");
     	case 0x0aa510de:
    
    From 3224ea55bbc4f619bbb69576a3d5a209a8252c95 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:30:30 +0000
    Subject: [PATCH 1885/2592] MFC r205803
    
     Make sure the bsd_urb_list gets initialised and that new URB's are queued at
     the end of the list.
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/usb_compat_linux.c | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/usb/usb_compat_linux.c b/sys/dev/usb/usb_compat_linux.c
    index b95a4f6f349..fc28a1c5060 100644
    --- a/sys/dev/usb/usb_compat_linux.c
    +++ b/sys/dev/usb/usb_compat_linux.c
    @@ -435,7 +435,7 @@ usb_submit_urb(struct urb *urb, uint16_t mem_flags)
     	    uhe->bsd_xfer[1]) {
     		/* we are ready! */
     
    -		TAILQ_INSERT_HEAD(&uhe->bsd_urb_list, urb, bsd_urb_list);
    +		TAILQ_INSERT_TAIL(&uhe->bsd_urb_list, urb, bsd_urb_list);
     
     		urb->status = -EINPROGRESS;
     
    @@ -908,6 +908,7 @@ usb_linux_create_usb_device(struct usb_device *udev, device_t dev)
     				if (p_uhe) {
     					bcopy(ed, &p_uhe->desc, sizeof(p_uhe->desc));
     					p_uhe->bsd_iface_index = iface_index - 1;
    +					TAILQ_INIT(&p_uhe->bsd_urb_list);
     					p_uhe++;
     				}
     				if (p_uhi) {
    
    From 6b6aaa9fcd90ae5ff1006a1add9d2dd8b17fddbd Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:30:57 +0000
    Subject: [PATCH 1886/2592] MFC r205804
    
     Do not swap Apple keys when detecting Apple-FN keyboards.
    
    Reported by:	Steven Noonan
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/input/ukbd.c | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
    index 22539047b16..47c6f889fe6 100644
    --- a/sys/dev/usb/input/ukbd.c
    +++ b/sys/dev/usb/input/ukbd.c
    @@ -903,8 +903,7 @@ ukbd_attach(device_t dev)
     		    hid_input, 0, &sc->sc_loc_apple_fn, &flags,
     		    &temp_id)) {
     			if (flags & HIO_VARIABLE)
    -				sc->sc_flags |= UKBD_FLAG_APPLE_FN |
    -				    UKBD_FLAG_APPLE_SWAP;
    +				sc->sc_flags |= UKBD_FLAG_APPLE_FN;
     			DPRINTFN(1, "Found Apple FN-key\n");
     			apple_keys = 1;
     			sc->sc_kbd_id = temp_id;
    
    From a811dd8b6454de58a6a1730c10800dfb57a11cb0 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Tue, 6 Apr 2010 23:31:22 +0000
    Subject: [PATCH 1887/2592] MFC r205805
    
     Do not sync cache for the PL2506
    
    PR:		usb/144915
    Submitted by:	Monty Hall
    ---
     sys/dev/usb/quirk/usb_quirk.c | 2 ++
     sys/dev/usb/usbdevs           | 1 +
     2 files changed, 3 insertions(+)
    
    diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
    index aa89fdc6011..f21fab41973 100644
    --- a/sys/dev/usb/quirk/usb_quirk.c
    +++ b/sys/dev/usb/quirk/usb_quirk.c
    @@ -317,6 +317,8 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
     	USB_QUIRK(PNY, ATTACHE2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
     	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE,
     	    UQ_MSC_NO_START_STOP),
    +	USB_QUIRK(PROLIFIC, PL2506, 0x0000, 0xffff,
    +	    UQ_MSC_NO_SYNC_CACHE),
     	USB_QUIRK_VP(USB_VENDOR_SAMSUNG_TECHWIN,
     	    USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, UQ_MSC_FORCE_WIRE_BBB,
     	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index 0492545dfdf..c8cd51e9173 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -2419,6 +2419,7 @@ product PROLIFIC PL2303		0x2303	PL2303 Serial (ATEN/IOGEAR UC232A)
     product PROLIFIC PL2305		0x2305	Parallel printer
     product PROLIFIC ATAPI4		0x2307	ATAPI-4 Controller
     product PROLIFIC PL2501		0x2501	PL2501 Host-Host interface
    +product PROLIFIC PL2506		0x2506	PL2506 USB to IDE Bridge
     product PROLIFIC PHAROS		0xaaa0	Prolific Pharos
     product PROLIFIC RSAQ3		0xaaa2	PL2303 Serial Adapter (IODATA USB-RSAQ3)
     product PROLIFIC2 WSIM		0x2001	Willcom WSIM
    
    From cfc42a27851d0a2b94d486a7f1218a9011752e6e Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Wed, 7 Apr 2010 00:25:03 +0000
    Subject: [PATCH 1888/2592] MFC r202608
    
     Remove a hack to attach TRENDnet TEW-504UB/EU, this has been solved.
    ---
     sys/dev/usb/usbdevs        | 1 -
     sys/dev/usb/wlan/if_uath.c | 1 -
     2 files changed, 2 deletions(-)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index c8cd51e9173..c00162e2439 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -3030,7 +3030,6 @@ product UMEDIA RT2870_1		0x300e	RT2870
     product UMEDIA ALL0298V2	0x3204	ALL0298 v2
     product UMEDIA AR5523_2		0x3205	AR5523
     product UMEDIA AR5523_2_NF	0x3206	AR5523 (no firmware)
    -product UMEDIA AR5523_3		0x3207	AR5523
     
     /* Universal Access products */
     product UNIACCESS PANACHE	0x0101	Panache Surf USB ISDN Adapter
    diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
    index 4c8e4ea96c9..7838d5ad353 100644
    --- a/sys/dev/usb/wlan/if_uath.c
    +++ b/sys/dev/usb/wlan/if_uath.c
    @@ -191,7 +191,6 @@ static const struct usb_device_id uath_devs[] = {
     	UATH_DEV(NETGEAR3,		WPN111_2),
     	UATH_DEV(UMEDIA,		TEW444UBEU),
     	UATH_DEV(UMEDIA,		AR5523_2),
    -	UATH_DEV(UMEDIA,		AR5523_3),
     	UATH_DEV(WISTRONNEWEB,		AR5523_1),
     	UATH_DEV(WISTRONNEWEB,		AR5523_2),
     	UATH_DEV(ZCOM,			AR5523)
    
    From 1e6c93d364d9ece6bb1b71c400338d6f043bd04c Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Wed, 7 Apr 2010 00:26:39 +0000
    Subject: [PATCH 1889/2592] MFC r202609
    
     Product ID of D-Link DWA-120 after loading the firmware is incorrect.
    ---
     sys/dev/usb/usbdevs | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index c00162e2439..c2ceb883318 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -1343,8 +1343,8 @@ product DLINK DSB650TX_PNA	0x4003	1/10/100 Ethernet
     product DLINK DSB650TX3		0x400b	10/100 Ethernet
     product DLINK DSB650TX2		0x4102	10/100 Ethernet
     product DLINK DSB650		0xabc1	10/100 Ethernet
    +product DLINK2 DWA120		0x3a0c	DWA-120
     product DLINK2 DWA120_NF	0x3a0d	DWA-120 (no firmware)
    -product DLINK2 DWA120		0x3a0e	DWA-120
     product DLINK2 DWLG122C1	0x3c03	DWL-G122 c1
     product DLINK2 WUA1340		0x3c04	WUA-1340
     product DLINK2 DWA111		0x3c06	DWA-111
    
    From 3769678a8262f91d4826e7518560acc8dd3f280c Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Wed, 7 Apr 2010 00:27:59 +0000
    Subject: [PATCH 1890/2592] MFC r203087
    
     adds sysctl knobs to show rate statistics that it could be useful to
     debug slow TX speed.
    ---
     sys/dev/usb/wlan/if_urtw.c    | 53 +++++++++++++++++++++++++++++++++++
     sys/dev/usb/wlan/if_urtwvar.h |  6 ++++
     2 files changed, 59 insertions(+)
    
    diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
    index 00789b89acc..6604268e009 100644
    --- a/sys/dev/usb/wlan/if_urtw.c
    +++ b/sys/dev/usb/wlan/if_urtw.c
    @@ -762,6 +762,7 @@ 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 void		urtw_sysctl_node(struct urtw_softc *);
     
     static int
     urtw_match(device_t dev)
    @@ -906,6 +907,8 @@ urtw_attach(device_t dev)
     	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
     	    URTW_RX_RADIOTAP_PRESENT);
     
    +	urtw_sysctl_node(sc);
    +
     	if (bootverbose)
     		ieee80211_announce(ic);
     	return (0);
    @@ -1703,6 +1706,8 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
     			rate = urtw_rtl2rate(sc->sc_currate);
     	}
     
    +	sc->sc_stats.txrates[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);
    @@ -4372,6 +4377,54 @@ fail:
     	URTW_UNLOCK(sc);
     }
     
    +static void
    +urtw_sysctl_node(struct urtw_softc *sc)
    +{
    +#define	URTW_SYSCTL_STAT_ADD32(c, h, n, p, d)	\
    +	SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
    +	struct sysctl_ctx_list *ctx;
    +	struct sysctl_oid_list *child, *parent;
    +	struct sysctl_oid *tree;
    +	struct urtw_stats *stats = &sc->sc_stats;
    +
    +	ctx = device_get_sysctl_ctx(sc->sc_dev);
    +	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
    +
    +	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
    +	    NULL, "URTW statistics");
    +	parent = SYSCTL_CHILDREN(tree);
    +
    +	/* Tx statistics. */
    +	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
    +	    NULL, "Tx MAC statistics");
    +	child = SYSCTL_CHILDREN(tree);
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "1m", &stats->txrates[0],
    +	    "1 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "2m", &stats->txrates[1],
    +	    "2 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "5.5m", &stats->txrates[2],
    +	    "5.5 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "6m", &stats->txrates[4],
    +	    "6 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "9m", &stats->txrates[5],
    +	    "9 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "11m", &stats->txrates[3],
    +	    "11 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "12m", &stats->txrates[6],
    +	    "12 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "18m", &stats->txrates[7],
    +	    "18 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "24m", &stats->txrates[8],
    +	    "24 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "36m", &stats->txrates[9],
    +	    "36 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "48m", &stats->txrates[10],
    +	    "48 Mbit/s");
    +	URTW_SYSCTL_STAT_ADD32(ctx, child, "54m", &stats->txrates[11],
    +	    "54 Mbit/s");
    +#undef URTW_SYSCTL_STAT_ADD32
    +}
    +
     static device_method_t urtw_methods[] = {
     	DEVMETHOD(device_probe, urtw_match),
     	DEVMETHOD(device_attach, urtw_attach),
    diff --git a/sys/dev/usb/wlan/if_urtwvar.h b/sys/dev/usb/wlan/if_urtwvar.h
    index 6941abbb8b8..e4a872147fe 100644
    --- a/sys/dev/usb/wlan/if_urtwvar.h
    +++ b/sys/dev/usb/wlan/if_urtwvar.h
    @@ -81,6 +81,10 @@ struct urtw_tx_radiotap_header {
     	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
     	 (1 << IEEE80211_RADIOTAP_CHANNEL))
     
    +struct urtw_stats {
    +	unsigned int			txrates[12];
    +};
    +
     struct urtw_vap {
     	struct ieee80211vap		vap;
     	int				(*newstate)(struct ieee80211vap *,
    @@ -169,6 +173,8 @@ struct urtw_softc {
     	uint64_t			sc_txstatus;	/* only for 8187B */
     	struct task			sc_updateslot_task;
     
    +	struct urtw_stats		sc_stats;
    +
     	struct	urtw_rx_radiotap_header	sc_rxtap;
     	int				sc_rxtap_len;
     	struct	urtw_tx_radiotap_header	sc_txtap;
    
    From fb8f1e2afc389d2518b8f7df946fda6c30f9033b Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Wed, 7 Apr 2010 00:30:25 +0000
    Subject: [PATCH 1891/2592] MFC r205681
    
     - add some usb devices (scanner, printer, usb storage)
     - add quirks for the usb storage
    ---
     sys/dev/usb/quirk/usb_quirk.c | 2 ++
     sys/dev/usb/usbdevs           | 7 +++++++
     2 files changed, 9 insertions(+)
    
    diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
    index f21fab41973..b829ac1d307 100644
    --- a/sys/dev/usb/quirk/usb_quirk.c
    +++ b/sys/dev/usb/quirk/usb_quirk.c
    @@ -227,6 +227,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
     	USB_QUIRK(IOMEGA, ZIP100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
     	    UQ_MSC_FORCE_PROTO_SCSI,
     	    UQ_MSC_NO_TEST_UNIT_READY), /* XXX ZIP drives can also use ATAPI */
    +	USB_QUIRK(JMICRON, JM20336, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
     	USB_QUIRK(JMICRON, JM20337, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
     	    UQ_MSC_FORCE_PROTO_SCSI,
     	    UQ_MSC_NO_SYNC_CACHE),
    @@ -444,6 +445,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
     	USB_QUIRK(ACTIONS, MP4, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
     	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_SYNC_CACHE),
     	USB_QUIRK(ASUS, GMSC, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
    +	USB_QUIRK(UNKNOWN4, USBMEMSTICK, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
     };
     #undef USB_QUIRK_VP
     #undef USB_QUIRK
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index c2ceb883318..312beabb1a4 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -65,6 +65,7 @@ $FreeBSD$
     vendor UNKNOWN1		0x0053	Unknown vendor
     vendor UNKNOWN2		0x0105	Unknown vendor
     vendor EGALAX2		0x0123	eGalax, Inc.
    +vendor UNKNOWN4		0x0204	Unknown vendor
     vendor HUMAX		0x02ad	HUMAX
     vendor LTS		0x0386	LTS
     vendor BWCT		0x03da	Bernd Walter Computer Technology
    @@ -1105,6 +1106,7 @@ product BROADCOM BCM2033	0x2033	BCM2033 Bluetooth USB dongle
     
     /* Brother Industries products */
     product BROTHER HL1050		0x0002	HL-1050 laser printer
    +product BROTHER MFC8600_9650	0x0100	MFC8600/9650 multifunction device
     
     /* Behavior Technology Computer products */
     product BTC BTC7932		0x6782	Keyboard with mouse port
    @@ -1819,6 +1821,7 @@ product JABLOTRON PC60B		0x0001	PC-60B
     product JATON EDA		0x5704	Ethernet
     
     /* JMicron products */
    +product JMICRON JM20336		0x2336	USB to SATA Bridge
     product JMICRON JM20337		0x2338	USB to ATA/ATAPI Bridge
     
     /* JVC products */
    @@ -2134,6 +2137,7 @@ product MUSTEK 1200UB		0x0006	1200 UB scanner
     product MUSTEK 1200USBPLUS	0x0007	1200 USB Plus scanner
     product MUSTEK 1200CUPLUS	0x0008	1200 CU Plus scanner
     product MUSTEK BEARPAW1200F	0x0010	BearPaw 1200F scanner
    +product MUSTEK BEARPAW2400TA	0x0218	BearPaw 2400TA scanner
     product MUSTEK BEARPAW1200TA	0x021e	BearPaw 1200TA scanner
     product MUSTEK 600USB		0x0873	600 USB scanner
     product MUSTEK MDC800		0xa800	MDC-800 digital camera
    @@ -3034,6 +3038,9 @@ product UMEDIA AR5523_2_NF	0x3206	AR5523 (no firmware)
     /* Universal Access products */
     product UNIACCESS PANACHE	0x0101	Panache Surf USB ISDN Adapter
     
    +/* Unknown vendors */
    +product UNKNOWN4 USBMEMSTICK	0x6025	Flash Disk CBM
    +
     /* U.S. Robotics products */
     product USR USR5423		0x0121	USR5423 WLAN
     
    
    From 464b64f6c89b9876839958ad959e5f4913177cfd Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Wed, 7 Apr 2010 00:32:59 +0000
    Subject: [PATCH 1892/2592] MFC r205036
    
     Implement USB kernel driver detach from userland.
    
    Submitted by:	Hans Petter Selasky
    ---
     sys/dev/usb/usb_device.c  |  1 -
     sys/dev/usb/usb_device.h  |  1 +
     sys/dev/usb/usb_generic.c | 25 ++++++++++++++++++++-----
     3 files changed, 21 insertions(+), 6 deletions(-)
    
    diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
    index 5aef59d379d..d7f0c31c8d3 100644
    --- a/sys/dev/usb/usb_device.c
    +++ b/sys/dev/usb/usb_device.c
    @@ -80,7 +80,6 @@
     static void	usb_init_endpoint(struct usb_device *, uint8_t,
     		    struct usb_endpoint_descriptor *, struct usb_endpoint *);
     static void	usb_unconfigure(struct usb_device *, uint8_t);
    -static void	usb_detach_device(struct usb_device *, uint8_t, uint8_t);
     static void	usb_detach_device_sub(struct usb_device *, device_t *,
     		    uint8_t);
     static uint8_t	usb_probe_and_attach_sub(struct usb_device *,
    diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h
    index 66f975a5c1f..3afdecf3ae9 100644
    --- a/sys/dev/usb/usb_device.h
    +++ b/sys/dev/usb/usb_device.h
    @@ -196,6 +196,7 @@ struct usb_device *usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
     		    enum usb_dev_speed speed, enum usb_hc_mode mode);
     usb_error_t	usb_probe_and_attach(struct usb_device *udev,
     		    uint8_t iface_index);
    +void		usb_detach_device(struct usb_device *, uint8_t, uint8_t);
     usb_error_t	usb_reset_iface_endpoints(struct usb_device *udev,
     		    uint8_t iface_index);
     usb_error_t	usbd_set_config_index(struct usb_device *udev, uint8_t index);
    diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
    index 9fc0cc7eef2..fb7d5df0fcb 100644
    --- a/sys/dev/usb/usb_generic.c
    +++ b/sys/dev/usb/usb_generic.c
    @@ -2095,17 +2095,32 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
     		break;
     
     	case USB_IFACE_DRIVER_ACTIVE:
    -		/* TODO */
    -		*u.pint = 0;
    +
    +		n = *u.pint & 0xFF;
    +
    +		iface = usbd_get_iface(f->udev, n);
    +
    +		if (iface && iface->subdev)
    +			error = 0;
    +		else
    +			error = ENXIO;
     		break;
     
     	case USB_IFACE_DRIVER_DETACH:
    -		/* TODO */
    +
     		error = priv_check(curthread, PRIV_DRIVER);
    -		if (error) {
    +
    +		if (error)
    +			break;
    +
    +		n = *u.pint & 0xFF;
    +
    +		if (n == USB_IFACE_INDEX_ANY) {
    +			error = EINVAL;
     			break;
     		}
    -		error = EINVAL;
    +
    +		usb_detach_device(f->udev, n, 0);
     		break;
     
     	case USB_SET_POWER_MODE:
    
    From 6836afc4c683a5bfa6c625f8adf455b7107eddae Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Wed, 7 Apr 2010 00:34:05 +0000
    Subject: [PATCH 1893/2592] MFC r203147
    
     Add a function to check if the usb devices is still connected.
    
    Submitted by:	Hans Petter Selasky
    ---
     lib/libusb/libusb20.3        | 11 +++++++++++
     lib/libusb/libusb20.c        | 10 ++++++++++
     lib/libusb/libusb20.h        |  1 +
     lib/libusb/libusb20_int.h    |  2 ++
     lib/libusb/libusb20_ugen20.c | 20 ++++++++++++++++++++
     5 files changed, 44 insertions(+)
    
    diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3
    index 5404013ee99..7896e8f0109 100644
    --- a/lib/libusb/libusb20.3
    +++ b/lib/libusb/libusb20.3
    @@ -143,6 +143,8 @@ USB access library (libusb -lusb)
     .Ft int
     .Fn libusb20_dev_reset "struct libusb20_device *pdev"
     .Ft int
    +.Fn libusb20_dev_check_connected "struct libusb20_device *pdev"
    +.Ft int
     .Fn libusb20_dev_set_power_mode "struct libusb20_device *pdev" "uint8_t power_mode"
     .Ft uint8_t
     .Fn libusb20_dev_get_power_mode "struct libusb20_device *pdev"
    @@ -677,6 +679,15 @@ the last set USB configuration.
     This function returns zero on success else a LIBUSB20_ERROR value is
     returned.
     .
    +.
    +.Pp
    +.
    +.Fn libusb20_dev_check_connected
    +will check if an opened USB device is still connected.
    +.
    +This function returns zero if the device is still connected else a LIBUSB20_ERROR value is returned.
    +.
    +.
     .Pp
     .
     .Fn libusb20_dev_set_power_mode
    diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c
    index 1c75fc16712..e181b49d24e 100644
    --- a/lib/libusb/libusb20.c
    +++ b/lib/libusb/libusb20.c
    @@ -67,6 +67,7 @@ dummy_callback(struct libusb20_transfer *xfer)
     #define	dummy_set_config_index (void *)dummy_int
     #define	dummy_set_alt_index (void *)dummy_int
     #define	dummy_reset_device (void *)dummy_int
    +#define	dummy_check_connected (void *)dummy_int
     #define	dummy_set_power_mode (void *)dummy_int
     #define	dummy_get_power_mode (void *)dummy_int
     #define	dummy_kernel_driver_active (void *)dummy_int
    @@ -672,6 +673,15 @@ libusb20_dev_reset(struct libusb20_device *pdev)
     	return (error);
     }
     
    +int
    +libusb20_dev_check_connected(struct libusb20_device *pdev)
    +{
    +	int error;
    +
    +	error = pdev->methods->check_connected(pdev);
    +	return (error);
    +}
    +
     int
     libusb20_dev_set_power_mode(struct libusb20_device *pdev, uint8_t power_mode)
     {
    diff --git a/lib/libusb/libusb20.h b/lib/libusb/libusb20.h
    index bb7d8a4ab3d..6b253aa559a 100644
    --- a/lib/libusb/libusb20.h
    +++ b/lib/libusb/libusb20.h
    @@ -250,6 +250,7 @@ int	libusb20_dev_request_sync(struct libusb20_device *pdev, struct LIBUSB20_CONT
     int	libusb20_dev_req_string_sync(struct libusb20_device *pdev, uint8_t index, uint16_t langid, void *ptr, uint16_t len);
     int	libusb20_dev_req_string_simple_sync(struct libusb20_device *pdev, uint8_t index, void *ptr, uint16_t len);
     int	libusb20_dev_reset(struct libusb20_device *pdev);
    +int	libusb20_dev_check_connected(struct libusb20_device *pdev);
     int	libusb20_dev_set_power_mode(struct libusb20_device *pdev, uint8_t power_mode);
     uint8_t	libusb20_dev_get_power_mode(struct libusb20_device *pdev);
     int	libusb20_dev_set_alt_index(struct libusb20_device *pdev, uint8_t iface_index, uint8_t alt_index);
    diff --git a/lib/libusb/libusb20_int.h b/lib/libusb/libusb20_int.h
    index 004b0cf381d..b0e0e2dd7f6 100644
    --- a/lib/libusb/libusb20_int.h
    +++ b/lib/libusb/libusb20_int.h
    @@ -101,6 +101,7 @@ typedef int (libusb20_set_power_mode_t)(struct libusb20_device *pdev, uint8_t po
     typedef int (libusb20_get_power_mode_t)(struct libusb20_device *pdev, uint8_t *power_mode);
     typedef int (libusb20_set_alt_index_t)(struct libusb20_device *pdev, uint8_t iface_index, uint8_t alt_index);
     typedef int (libusb20_set_config_index_t)(struct libusb20_device *pdev, uint8_t index);
    +typedef int (libusb20_check_connected_t)(struct libusb20_device *pdev);
     
     /* USB transfer specific */
     typedef int (libusb20_tr_open_t)(struct libusb20_transfer *xfer, uint32_t MaxBufSize, uint32_t MaxFrameCount, uint8_t ep_no);
    @@ -117,6 +118,7 @@ typedef void (libusb20_tr_cancel_async_t)(struct libusb20_transfer *xfer);
       m(n, kernel_driver_active) \
       m(n, process) \
       m(n, reset_device) \
    +  m(n, check_connected) \
       m(n, set_power_mode) \
       m(n, get_power_mode) \
       m(n, set_alt_index) \
    diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c
    index efcca63a209..892ba0eb78a 100644
    --- a/lib/libusb/libusb20_ugen20.c
    +++ b/lib/libusb/libusb20_ugen20.c
    @@ -67,6 +67,7 @@ static libusb20_get_config_index_t ugen20_get_config_index;
     static libusb20_set_config_index_t ugen20_set_config_index;
     static libusb20_set_alt_index_t ugen20_set_alt_index;
     static libusb20_reset_device_t ugen20_reset_device;
    +static libusb20_check_connected_t ugen20_check_connected;
     static libusb20_set_power_mode_t ugen20_set_power_mode;
     static libusb20_get_power_mode_t ugen20_get_power_mode;
     static libusb20_kernel_driver_active_t ugen20_kernel_driver_active;
    @@ -552,6 +553,25 @@ ugen20_reset_device(struct libusb20_device *pdev)
     	return (ugen20_tr_renew(pdev));
     }
     
    +static int
    +ugen20_check_connected(struct libusb20_device *pdev)
    +{
    +	uint32_t plugtime;
    +	int error = 0;
    +
    +	if (ioctl(pdev->file_ctrl, USB_GET_PLUGTIME, &plugtime)) {
    +		error = LIBUSB20_ERROR_NO_DEVICE;
    +		goto done;
    +	}
    +
    +	if (pdev->session_data.plugtime != plugtime) {
    +		error = LIBUSB20_ERROR_NO_DEVICE;
    +		goto done;
    +	}
    +done:
    +	return (error);
    +}
    +
     static int
     ugen20_set_power_mode(struct libusb20_device *pdev, uint8_t power_mode)
     {
    
    From 4ccf64eb2bb126b295631f77a22b60a34abd8f79 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Wed, 7 Apr 2010 02:24:41 +0000
    Subject: [PATCH 1894/2592] MFC r205014,205015:
    
    Provide groundwork for 32-bit binary compatibility on non-x86 platforms,
    for upcoming 64-bit PowerPC and MIPS support. This renames the COMPAT_IA32
    option to COMPAT_FREEBSD32, removes some IA32-specific code from MI parts
    of the kernel and enhances the freebsd32 compatibility code to support
    big-endian platforms.
    
    This MFC is required for MFCs of later changes to the freebsd32
    compatibility from HEAD.
    
    Requested by:	kib
    ---
     UPDATING                              |   6 +
     sys/amd64/amd64/db_trace.c            |   2 +-
     sys/amd64/amd64/exception.S           |   2 +-
     sys/amd64/amd64/vm_machdep.c          |   4 +-
     sys/amd64/conf/GENERIC                |   2 +-
     sys/amd64/conf/NOTES                  |   4 +-
     sys/amd64/conf/XENHVM                 |   2 +-
     sys/amd64/include/elf.h               |   1 +
     sys/amd64/include/reg.h               |   9 ++
     sys/amd64/linux32/linux32_sysvec.c    |   4 +-
     sys/compat/freebsd32/freebsd32.h      |  24 ++++
     sys/compat/freebsd32/freebsd32_misc.c | 185 ++++++++++++++++++++++----
     sys/compat/freebsd32/freebsd32_util.h |   2 +
     sys/compat/freebsd32/syscalls.master  |  92 ++++++++-----
     sys/compat/ia32/ia32_reg.h            |  23 ----
     sys/compat/ia32/ia32_sysvec.c         | 124 +----------------
     sys/conf/files.amd64                  |  24 ++--
     sys/conf/files.ia64                   |  20 +--
     sys/conf/options.amd64                |   2 +-
     sys/conf/options.ia64                 |   2 +-
     sys/fs/procfs/procfs_dbregs.c         |   7 +-
     sys/fs/procfs/procfs_fpregs.c         |   7 +-
     sys/fs/procfs/procfs_ioctl.c          |   6 +-
     sys/fs/procfs/procfs_map.c            |   8 +-
     sys/fs/procfs/procfs_regs.c           |   7 +-
     sys/ia64/conf/GENERIC                 |   1 +
     sys/ia64/conf/NOTES                   |   4 +-
     sys/ia64/ia64/exception.S             |   2 +-
     sys/ia64/ia64/genassym.c              |   4 +-
     sys/ia64/ia64/machdep.c               |   6 +-
     sys/ia64/include/elf.h                |   1 +
     sys/ia64/include/reg.h                |   9 ++
     sys/kern/imgact_elf.c                 |  15 +--
     sys/kern/kern_jail.c                  |   8 +-
     sys/kern/kern_module.c                |   2 +-
     sys/kern/kern_thr.c                   |   2 +-
     sys/kern/kern_umtx.c                  |   6 +-
     sys/kern/sys_generic.c                |  34 ++++-
     sys/kern/sys_process.c                |  30 ++---
     sys/kern/uipc_socket.c                |   6 +-
     sys/kern/vfs_aio.c                    |   2 +-
     sys/modules/linux/Makefile            |   2 +-
     sys/modules/procfs/Makefile           |   2 +-
     sys/sys/ptrace.h                      |   3 +-
     44 files changed, 399 insertions(+), 309 deletions(-)
    
    diff --git a/UPDATING b/UPDATING
    index 28892561183..9ba6b287c18 100644
    --- a/UPDATING
    +++ b/UPDATING
    @@ -15,6 +15,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
     	debugging tools present in HEAD were left in place because
     	sun4v support still needs work to become production ready.
     
    +20100406:
    +	The kernel option COMPAT_IA32 has been replaced with COMPAT_FREEBSD32
    +	to allow 32-bit compatibility on non-x86 platforms. All kernel
    +	configurations on amd64 and ia64 platforms using these options must
    +	be modified accordingly.
    +
     20100125:
     	Introduce the kernel thread "deadlock resolver" (which can be enabled
     	via the DEADLKRES option, see NOTES for more details) and the
    diff --git a/sys/amd64/amd64/db_trace.c b/sys/amd64/amd64/db_trace.c
    index 73ffac53def..cba90f2f577 100644
    --- a/sys/amd64/amd64/db_trace.c
    +++ b/sys/amd64/amd64/db_trace.c
    @@ -319,7 +319,7 @@ db_nextframe(struct amd64_frame **fp, db_addr_t *ip, struct thread *td)
     			frame_type = INTERRUPT;
     		else if (strcmp(name, "Xfast_syscall") == 0)
     			frame_type = SYSCALL;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     		else if (strcmp(name, "Xint0x80_syscall") == 0)
     			frame_type = SYSCALL;
     #endif
    diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
    index 3d1a20ee201..1799b7466e2 100644
    --- a/sys/amd64/amd64/exception.S
    +++ b/sys/amd64/amd64/exception.S
    @@ -572,7 +572,7 @@ ENTRY(fork_trampoline)
      * included.
      */
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	.data
     	.p2align 4
     	.text
    diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
    index a99fdaaf634..d6906ac6948 100644
    --- a/sys/amd64/amd64/vm_machdep.c
    +++ b/sys/amd64/amd64/vm_machdep.c
    @@ -439,7 +439,7 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
     	 */
     	cpu_thread_clean(td);
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
     		/*
     	 	 * Set the trap frame to point at the beginning of the uts
    @@ -490,7 +490,7 @@ cpu_set_user_tls(struct thread *td, void *tls_base)
     	if ((u_int64_t)tls_base >= VM_MAXUSER_ADDRESS)
     		return (EINVAL);
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
     		td->td_pcb->pcb_gsbase = (register_t)tls_base;
     		return (0);
    diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
    index e5a6955f1c5..e9f3c170789 100644
    --- a/sys/amd64/conf/GENERIC
    +++ b/sys/amd64/conf/GENERIC
    @@ -54,7 +54,7 @@ options 	PSEUDOFS		# Pseudo-filesystem framework
     options 	GEOM_PART_GPT		# GUID Partition Tables.
     options 	GEOM_LABEL		# Provides labelization
     options 	COMPAT_43TTY		# BSD 4.3 TTY compat (sgtty)
    -options 	COMPAT_IA32		# Compatible with i386 binaries
    +options 	COMPAT_FREEBSD32	# Compatible with i386 binaries
     options 	COMPAT_FREEBSD4		# Compatible with FreeBSD4
     options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
     options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
    diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
    index 159f12e809d..4b6debb34c9 100644
    --- a/sys/amd64/conf/NOTES
    +++ b/sys/amd64/conf/NOTES
    @@ -445,7 +445,7 @@ options 	PMAP_SHPGPERPROC=201
     #XXX these 32 bit binaries is added.
     
     # Enable 32-bit runtime support for FreeBSD/i386 binaries.
    -options 	COMPAT_IA32
    +options 	COMPAT_FREEBSD32
     
     # Enable iBCS2 runtime support for SCO and ISC binaries
     #XXX#options 	IBCS2
    @@ -456,7 +456,7 @@ options 	COMPAT_IA32
     # Enable Linux ABI emulation
     #XXX#options 	COMPAT_LINUX
     
    -# Enable 32-bit Linux ABI emulation (requires COMPAT_43 and COMPAT_IA32)
    +# Enable 32-bit Linux ABI emulation (requires COMPAT_43 and COMPAT_FREEBSD32)
     options 	COMPAT_LINUX32
     
     # Enable the linux-like proc filesystem support (requires COMPAT_LINUX32
    diff --git a/sys/amd64/conf/XENHVM b/sys/amd64/conf/XENHVM
    index f875f5af7ed..377276e39fa 100644
    --- a/sys/amd64/conf/XENHVM
    +++ b/sys/amd64/conf/XENHVM
    @@ -55,7 +55,7 @@ options 	PSEUDOFS		# Pseudo-filesystem framework
     options 	GEOM_PART_GPT		# GUID Partition Tables.
     options 	GEOM_LABEL		# Provides labelization
     options 	COMPAT_43TTY		# BSD 4.3 TTY compat (sgtty)
    -options 	COMPAT_IA32		# Compatible with i386 binaries
    +options 	COMPAT_FREEBSD32	# Compatible with i386 binaries
     options 	COMPAT_FREEBSD4		# Compatible with FreeBSD4
     options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
     options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
    diff --git a/sys/amd64/include/elf.h b/sys/amd64/include/elf.h
    index 88f439805ba..678f5d3ba0f 100644
    --- a/sys/amd64/include/elf.h
    +++ b/sys/amd64/include/elf.h
    @@ -42,6 +42,7 @@
     #include 
     
     #define	ELF_ARCH	EM_X86_64
    +#define	ELF_ARCH32	EM_386
     
     #define	ELF_MACHINE_OK(x) ((x) == EM_X86_64)
     
    diff --git a/sys/amd64/include/reg.h b/sys/amd64/include/reg.h
    index 89211a32651..4a839181882 100644
    --- a/sys/amd64/include/reg.h
    +++ b/sys/amd64/include/reg.h
    @@ -37,6 +37,10 @@
     #ifndef _MACHINE_REG_H_
     #define	_MACHINE_REG_H_
     
    +#if defined(_KERNEL) && !defined(_STANDALONE)
    +#include "opt_compat.h"
    +#endif
    +
     /*
      * Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS.
      */
    @@ -116,6 +120,11 @@ struct dbreg {
     #define	DBREG_DRX(d,x)	((d)->dr[(x)])	/* reference dr0 - dr15 by
     					   register number */
     
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#endif
    +
     #ifdef _KERNEL
     /*
      * XXX these interfaces are MI, so they should be declared in a MI place.
    diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
    index 6e3e32622bf..d967ad70113 100644
    --- a/sys/amd64/linux32/linux32_sysvec.c
    +++ b/sys/amd64/linux32/linux32_sysvec.c
    @@ -34,8 +34,8 @@
     __FBSDID("$FreeBSD$");
     #include "opt_compat.h"
     
    -#ifndef COMPAT_IA32
    -#error "Unable to compile Linux-emulator due to missing COMPAT_IA32 option!"
    +#ifndef COMPAT_FREEBSD32
    +#error "Unable to compile Linux-emulator due to missing COMPAT_FREEBSD32 option!"
     #endif
     
     #define	__ELF_WORD_SIZE	32
    diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
    index 84e832c4e61..058ac72fe5f 100644
    --- a/sys/compat/freebsd32/freebsd32.h
    +++ b/sys/compat/freebsd32/freebsd32.h
    @@ -29,6 +29,9 @@
     #ifndef _COMPAT_FREEBSD32_FREEBSD32_H_
     #define _COMPAT_FREEBSD32_FREEBSD32_H_
     
    +#include 
    +#include 
    +
     #define PTRIN(v)	(void *)(uintptr_t) (v)
     #define PTROUT(v)	(u_int32_t)(uintptr_t) (v)
     
    @@ -197,4 +200,25 @@ struct i386_ldt_args32 {
     	uint32_t num;
     };
     
    +/*
    + * Alternative layouts for 
    + */
    +struct prstatus32 {
    +        int     pr_version;
    +        u_int   pr_statussz;
    +        u_int   pr_gregsetsz;
    +        u_int   pr_fpregsetsz;
    +        int     pr_osreldate;
    +        int     pr_cursig;
    +        pid_t   pr_pid;
    +        struct reg32 pr_reg;
    +};
    +
    +struct prpsinfo32 {
    +        int     pr_version;
    +        u_int   pr_psinfosz;
    +        char    pr_fname[PRFNAMESZ+1];
    +        char    pr_psargs[PRARGSZ+1];
    +};
    +
     #endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */
    diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
    index 75b290b365f..c20e5fbd226 100644
    --- a/sys/compat/freebsd32/freebsd32_misc.c
    +++ b/sys/compat/freebsd32/freebsd32_misc.c
    @@ -31,6 +31,8 @@ __FBSDID("$FreeBSD$");
     #include "opt_inet.h"
     #include "opt_inet6.h"
     
    +#define __ELF_WORD_SIZE 32
    +
     #include 
     #include 
     #include 
    @@ -44,6 +46,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 		/* Must come after sys/malloc.h */
    +#include 
     #include 
     #include 
     #include 
    @@ -91,6 +94,7 @@ __FBSDID("$FreeBSD$");
     #include 
     
     #include 
    +#include 
     
     #include 
     
    @@ -115,6 +119,16 @@ CTASSERT(sizeof(struct sigaction32) == 24);
     static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
     static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
     
    +#if BYTE_ORDER == BIG_ENDIAN
    +#define PAIR32TO64(type, name) ((name ## 2) | ((type)(name ## 1) << 32))
    +#define RETVAL_HI 0	
    +#define RETVAL_LO 1	
    +#else
    +#define PAIR32TO64(type, name) ((name ## 1) | ((type)(name ## 2) << 32))
    +#define RETVAL_HI 1	
    +#define RETVAL_LO 0	
    +#endif
    +
     int
     freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
     {
    @@ -426,8 +440,7 @@ freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
     	int prot	 = uap->prot;
     	int flags	 = uap->flags;
     	int fd		 = uap->fd;
    -	off_t pos	 = (uap->poslo
    -			    | ((off_t)uap->poshi << 32));
    +	off_t pos	 = PAIR32TO64(off_t,uap->pos);
     #ifdef __ia64__
     	vm_size_t pageoff;
     	int error;
    @@ -523,8 +536,8 @@ freebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *
     	ap.prot = uap->prot;
     	ap.flags = uap->flags;
     	ap.fd = uap->fd;
    -	ap.poslo = uap->poslo;
    -	ap.poshi = uap->poshi;
    +	ap.pos1 = uap->pos1;
    +	ap.pos2 = uap->pos2;
     
     	return (freebsd32_mmap(td, &ap));
     }
    @@ -586,7 +599,6 @@ freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
     	} else
     		tvp = NULL;
     	/*
    -	 * XXX big-endian needs to convert the fd_sets too.
     	 * XXX Do pointers need PTRIN()?
     	 */
     	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
    @@ -620,7 +632,6 @@ freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap)
     	} 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,
    @@ -843,7 +854,7 @@ freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
     	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
     	if (error)
     		return (error);
    -	error = kern_preadv(td, uap->fd, auio, uap->offset);
    +	error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
     	free(auio, M_IOV);
     	return (error);
     }
    @@ -857,7 +868,7 @@ freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
     	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
     	if (error)
     		return (error);
    -	error = kern_pwritev(td, uap->fd, auio, uap->offset);
    +	error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
     	free(auio, M_IOV);
     	return (error);
     }
    @@ -1982,7 +1993,7 @@ freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
     	ap.fd = uap->fd;
     	ap.buf = uap->buf;
     	ap.nbyte = uap->nbyte;
    -	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
    +	ap.offset = PAIR32TO64(off_t,uap->offset);
     	return (pread(td, &ap));
     }
     
    @@ -1994,7 +2005,7 @@ freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
     	ap.fd = uap->fd;
     	ap.buf = uap->buf;
     	ap.nbyte = uap->nbyte;
    -	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
    +	ap.offset = PAIR32TO64(off_t,uap->offset);
     	return (pwrite(td, &ap));
     }
     
    @@ -2006,13 +2017,13 @@ freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
     	off_t pos;
     
     	ap.fd = uap->fd;
    -	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
    +	ap.offset = PAIR32TO64(off_t,uap->offset);
     	ap.whence = uap->whence;
     	error = lseek(td, &ap);
     	/* Expand the quad return into two parts for eax and edx */
     	pos = *(off_t *)(td->td_retval);
    -	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
    -	td->td_retval[1] = pos >> 32;		/* %edx */
    +	td->td_retval[RETVAL_LO] = pos & 0xffffffff;	/* %eax */
    +	td->td_retval[RETVAL_HI] = pos >> 32;		/* %edx */
     	return error;
     }
     
    @@ -2022,7 +2033,7 @@ freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
     	struct truncate_args ap;
     
     	ap.path = uap->path;
    -	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
    +	ap.length = PAIR32TO64(off_t,uap->length);
     	return (truncate(td, &ap));
     }
     
    @@ -2032,7 +2043,7 @@ freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
     	struct ftruncate_args ap;
     
     	ap.fd = uap->fd;
    -	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
    +	ap.length = PAIR32TO64(off_t,uap->length);
     	return (ftruncate(td, &ap));
     }
     
    @@ -2064,7 +2075,7 @@ freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args
     	ap.fd = uap->fd;
     	ap.buf = uap->buf;
     	ap.nbyte = uap->nbyte;
    -	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
    +	ap.offset = PAIR32TO64(off_t,uap->offset);
     	return (pread(td, &ap));
     }
     
    @@ -2076,7 +2087,7 @@ freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_ar
     	ap.fd = uap->fd;
     	ap.buf = uap->buf;
     	ap.nbyte = uap->nbyte;
    -	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
    +	ap.offset = PAIR32TO64(off_t,uap->offset);
     	return (pwrite(td, &ap));
     }
     
    @@ -2088,13 +2099,13 @@ freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args
     	off_t pos;
     
     	ap.fd = uap->fd;
    -	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
    +	ap.offset = PAIR32TO64(off_t,uap->offset);
     	ap.whence = uap->whence;
     	error = lseek(td, &ap);
     	/* Expand the quad return into two parts for eax and edx */
     	pos = *(off_t *)(td->td_retval);
    -	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
    -	td->td_retval[1] = pos >> 32;		/* %edx */
    +	td->td_retval[RETVAL_LO] = pos & 0xffffffff;	/* %eax */
    +	td->td_retval[RETVAL_HI] = pos >> 32;		/* %edx */
     	return error;
     }
     
    @@ -2104,7 +2115,7 @@ freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncat
     	struct truncate_args ap;
     
     	ap.path = uap->path;
    -	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
    +	ap.length = PAIR32TO64(off_t,uap->length);
     	return (truncate(td, &ap));
     }
     
    @@ -2114,7 +2125,7 @@ freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftrunc
     	struct ftruncate_args ap;
     
     	ap.fd = uap->fd;
    -	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
    +	ap.length = PAIR32TO64(off_t,uap->length);
     	return (ftruncate(td, &ap));
     }
     #endif /* COMPAT_FREEBSD6 */
    @@ -2141,7 +2152,7 @@ freebsd32_do_sendfile(struct thread *td,
     
     	ap.fd = uap->fd;
     	ap.s = uap->s;
    -	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
    +	ap.offset = PAIR32TO64(off_t,uap->offset);
     	ap.nbytes = uap->nbytes;
     	ap.hdtr = (struct sf_hdtr *)uap->hdtr;		/* XXX not used */
     	ap.sbytes = uap->sbytes;
    @@ -2879,7 +2890,7 @@ freebsd32_cpuset_setid(struct thread *td,
     	struct cpuset_setid_args ap;
     
     	ap.which = uap->which;
    -	ap.id = (uap->idlo | ((id_t)uap->idhi << 32));
    +	ap.id = PAIR32TO64(id_t,uap->id);
     	ap.setid = uap->setid;
     
     	return (cpuset_setid(td, &ap));
    @@ -2893,7 +2904,7 @@ freebsd32_cpuset_getid(struct thread *td,
     
     	ap.level = uap->level;
     	ap.which = uap->which;
    -	ap.id = (uap->idlo | ((id_t)uap->idhi << 32));
    +	ap.id = PAIR32TO64(id_t,uap->id);
     	ap.setid = uap->setid;
     
     	return (cpuset_getid(td, &ap));
    @@ -2907,7 +2918,7 @@ freebsd32_cpuset_getaffinity(struct thread *td,
     
     	ap.level = uap->level;
     	ap.which = uap->which;
    -	ap.id = (uap->idlo | ((id_t)uap->idhi << 32));
    +	ap.id = PAIR32TO64(id_t,uap->id);
     	ap.cpusetsize = uap->cpusetsize;
     	ap.mask = uap->mask;
     
    @@ -2922,7 +2933,7 @@ freebsd32_cpuset_setaffinity(struct thread *td,
     
     	ap.level = uap->level;
     	ap.which = uap->which;
    -	ap.id = (uap->idlo | ((id_t)uap->idhi << 32));
    +	ap.id = PAIR32TO64(id_t,uap->id);
     	ap.cpusetsize = uap->cpusetsize;
     	ap.mask = uap->mask;
     
    @@ -3072,3 +3083,123 @@ syscall32_module_handler(struct module *mod, int what, void *arg)
     		return (error);
     	}
     }
    +
    +register_t *
    +freebsd32_copyout_strings(struct image_params *imgp)
    +{
    +	int argc, envc;
    +	u_int32_t *vectp;
    +	char *stringp, *destp;
    +	u_int32_t *stack_base;
    +	struct freebsd32_ps_strings *arginfo;
    +	size_t execpath_len;
    +	int szsigcode;
    +
    +	/*
    +	 * Calculate string base and vector table pointers.
    +	 * Also deal with signal trampoline code for this exec type.
    +	 */
    +	if (imgp->execpath != NULL && imgp->auxargs != NULL)
    +		execpath_len = strlen(imgp->execpath) + 1;
    +	else
    +		execpath_len = 0;
    +	arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS;
    +	szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
    +	destp =	(caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
    +		roundup(execpath_len, sizeof(char *)) -
    +		roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
    +
    +	/*
    +	 * install sigcode
    +	 */
    +	if (szsigcode)
    +		copyout(imgp->proc->p_sysent->sv_sigcode,
    +			((caddr_t)arginfo - szsigcode), szsigcode);
    +
    +	/*
    +	 * Copy the image path for the rtld.
    +	 */
    +	if (execpath_len != 0) {
    +		imgp->execpathp = (uintptr_t)arginfo - szsigcode - execpath_len;
    +		copyout(imgp->execpath, (void *)imgp->execpathp,
    +		    execpath_len);
    +	}
    +
    +	/*
    +	 * If we have a valid auxargs ptr, prepare some room
    +	 * on the stack.
    +	 */
    +	if (imgp->auxargs) {
    +		/*
    +		 * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
    +		 * lower compatibility.
    +		 */
    +		imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
    +			: (AT_COUNT * 2);
    +		/*
    +		 * The '+ 2' is for the null pointers at the end of each of
    +		 * the arg and env vector sets,and imgp->auxarg_size is room
    +		 * for argument of Runtime loader.
    +		 */
    +		vectp = (u_int32_t *) (destp - (imgp->args->argc +
    +		    imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) *
    +		    sizeof(u_int32_t));
    +	} else
    +		/*
    +		 * The '+ 2' is for the null pointers at the end of each of
    +		 * the arg and env vector sets
    +		 */
    +		vectp = (u_int32_t *)
    +			(destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
    +
    +	/*
    +	 * vectp also becomes our initial stack base
    +	 */
    +	stack_base = vectp;
    +
    +	stringp = imgp->args->begin_argv;
    +	argc = imgp->args->argc;
    +	envc = imgp->args->envc;
    +	/*
    +	 * Copy out strings - arguments and environment.
    +	 */
    +	copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
    +
    +	/*
    +	 * Fill in "ps_strings" struct for ps, w, etc.
    +	 */
    +	suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
    +	suword32(&arginfo->ps_nargvstr, argc);
    +
    +	/*
    +	 * Fill in argument portion of vector table.
    +	 */
    +	for (; argc > 0; --argc) {
    +		suword32(vectp++, (u_int32_t)(intptr_t)destp);
    +		while (*stringp++ != 0)
    +			destp++;
    +		destp++;
    +	}
    +
    +	/* a null vector table pointer separates the argp's from the envp's */
    +	suword32(vectp++, 0);
    +
    +	suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
    +	suword32(&arginfo->ps_nenvstr, envc);
    +
    +	/*
    +	 * Fill in environment portion of vector table.
    +	 */
    +	for (; envc > 0; --envc) {
    +		suword32(vectp++, (u_int32_t)(intptr_t)destp);
    +		while (*stringp++ != 0)
    +			destp++;
    +		destp++;
    +	}
    +
    +	/* end of vector table is a null pointer */
    +	suword32(vectp, 0);
    +
    +	return ((register_t *)stack_base);
    +}
    +
    diff --git a/sys/compat/freebsd32/freebsd32_util.h b/sys/compat/freebsd32/freebsd32_util.h
    index 6536b2ca1a7..5e5942b0930 100644
    --- a/sys/compat/freebsd32/freebsd32_util.h
    +++ b/sys/compat/freebsd32/freebsd32_util.h
    @@ -83,4 +83,6 @@ int    syscall32_register(int *offset, struct sysent *new_sysent,
     int    syscall32_deregister(int *offset, struct sysent *old_sysent);
     int    syscall32_module_handler(struct module *mod, int what, void *arg);
     
    +register_t *freebsd32_copyout_strings(struct image_params *imgp);
    +
     #endif /* !_COMPAT_FREEBSD32_FREEBSD32_UTIL_H_ */
    diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
    index 485f7a6d816..f6d9a6b6f34 100644
    --- a/sys/compat/freebsd32/syscalls.master
    +++ b/sys/compat/freebsd32/syscalls.master
    @@ -53,6 +53,10 @@
     #include 
     #include 
     
    +#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
    +#define PAD64_REQUIRED
    +#endif
    +
     ; Reserved/unimplemented system calls in the range 0-150 inclusive
     ; are reserved for use in future Berkeley releases.
     ; Additional system calls implemented in vendor and other
    @@ -195,7 +199,6 @@
     93	AUE_SELECT	STD	{ int freebsd32_select(int nd, fd_set *in, \
     				    fd_set *ou, fd_set *ex, \
     				    struct timeval32 *tv); }
    -; XXX need to override for big-endian - little-endian should work fine.
     94	AUE_NULL	UNIMPL	setdopt
     95	AUE_FSYNC	NOPROTO	{ int fsync(int fd); }
     96	AUE_SETPRIORITY	NOPROTO	{ int setpriority(int which, int who, \
    @@ -316,12 +319,10 @@
     172	AUE_NULL	UNIMPL	nosys
     173	AUE_PREAD	COMPAT6	{ ssize_t freebsd32_pread(int fd, void *buf, \
     				    size_t nbyte, int pad, \
    -				    u_int32_t offsetlo, u_int32_t offsethi); }
    -; XXX note - bigendian is different
    +				    u_int32_t offset1, u_int32_t offset2); }
     174	AUE_PWRITE	COMPAT6	{ ssize_t freebsd32_pwrite(int fd, \
     				    const void *buf, size_t nbyte, int pad, \
    -				    u_int32_t offsetlo, u_int32_t offsethi); }
    -; XXX note - bigendian is different
    +				    u_int32_t offset1, u_int32_t offset2); }
     175	AUE_NULL	UNIMPL	nosys
     176	AUE_NTP_ADJTIME	NOPROTO	{ int ntp_adjtime(struct timex *tp); }
     177	AUE_NULL	UNIMPL	sfork (BSD/OS 2.x)
    @@ -356,21 +357,17 @@
     				    char *buf, u_int count, int32_t *basep); }
     197	AUE_MMAP	COMPAT6	{ caddr_t freebsd32_mmap(caddr_t addr, \
     				    size_t len, int prot, int flags, int fd, \
    -				    int pad, u_int32_t poslo, \
    -				    u_int32_t poshi); }
    +				    int pad, u_int32_t pos1, u_int32_t pos2); }
     198	AUE_NULL	NOPROTO	{ int nosys(void); } __syscall \
     				    __syscall_args int
    -; XXX note - bigendian is different
     199	AUE_LSEEK	COMPAT6	{ off_t freebsd32_lseek(int fd, int pad, \
    -				    u_int32_t offsetlo, u_int32_t offsethi, \
    +				    u_int32_t offset1, u_int32_t offset2, \
     				    int whence); }
    -; XXX note - bigendian is different
     200	AUE_TRUNCATE	COMPAT6	{ int freebsd32_truncate(char *path, \
    -				    int pad, u_int32_t lengthlo, \
    -				    u_int32_t lengthhi); }
    -; XXX note - bigendian is different
    +				    int pad, u_int32_t length1, \
    +				    u_int32_t length2); }
     201	AUE_FTRUNCATE	COMPAT6	{ int freebsd32_ftruncate(int fd, int pad, \
    -				    u_int32_t lengthlo, u_int32_t lengthhi); }
    +				    u_int32_t length1, u_int32_t length2); }
     202	AUE_SYSCTL	STD	{ int freebsd32_sysctl(int *name, \
     				    u_int namelen, void *old, \
     				    u_int32_t *oldlenp, void *new, \
    @@ -403,7 +400,7 @@
     
     ;
     ; The following were introduced with NetBSD/4.4Lite-2
    -; They are initialized by thier respective modules/sysinits
    +; They are initialized by their respective modules/sysinits
     ; XXX PROBLEM!!
     220	AUE_SEMCTL	COMPAT7	{ int freebsd32_semctl(int semid, int semnum, \
     				    int cmd, union semun32 *arg); }
    @@ -504,12 +501,12 @@
     ; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
     289	AUE_PREADV	STD	{ ssize_t freebsd32_preadv(int fd, \
     					struct iovec32 *iovp, \
    -					u_int iovcnt, off_t offset); }
    -; XXX note - bigendian is different
    +					u_int iovcnt, \
    +					u_int32_t offset1, u_int32_t offset2); }
     290	AUE_PWRITEV	STD	{ ssize_t freebsd32_pwritev(int fd, \
     					struct iovec32 *iovp, \
    -					u_int iovcnt, off_t offset); }
    -; XXX note - bigendian is different
    +					u_int iovcnt, \
    +					u_int32_t offset1, u_int32_t offset2); }
     291	AUE_NULL	UNIMPL	nosys
     292	AUE_NULL	UNIMPL	nosys
     293	AUE_NULL	UNIMPL	nosys
    @@ -582,9 +579,8 @@
     334	AUE_NULL	NOPROTO	{ int sched_rr_get_interval (pid_t pid, \
     				    struct timespec *interval); }
     335	AUE_NULL	NOPROTO	{ int utrace(const void *addr, size_t len); }
    -; XXX note - bigendian is different
     336	AUE_SENDFILE	COMPAT4	{ int freebsd32_sendfile(int fd, int s, \
    -				    u_int32_t offsetlo, u_int32_t offsethi, \
    +				    u_int32_t offset1, u_int32_t offset2, \
     				    size_t nbytes, struct sf_hdtr32 *hdtr, \
     				    off_t *sbytes, int flags); }
     337	AUE_NULL	NOPROTO	{ int kldsym(int fileid, int cmd, \
    @@ -687,7 +683,7 @@
     392	AUE_NULL	NOPROTO	{ int uuidgen(struct uuid *store, \
     				    int count); }
     393	AUE_SENDFILE	STD	{ int freebsd32_sendfile(int fd, int s, \
    -				    u_int32_t offsetlo, u_int32_t offsethi, \
    +				    u_int32_t offset1, u_int32_t offset2, \
     				    size_t nbytes, struct sf_hdtr32 *hdtr, \
     				    off_t *sbytes, int flags); }
     394	AUE_NULL	UNIMPL	mac_syscall
    @@ -821,42 +817,74 @@
     474	AUE_NULL	NOPROTO	{ int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
     				    struct sockaddr * from, __socklen_t *fromlenaddr, \
     				    struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
    +#ifdef PAD64_REQUIRED
     475	AUE_PREAD	STD	{ ssize_t freebsd32_pread(int fd, \
     				    void *buf,size_t nbyte, \
    -				    u_int32_t offsetlo, u_int32_t offsethi); }
    +				    int pad, \
    +				    u_int32_t offset1, u_int32_t offset2); }
     476	AUE_PWRITE	STD	{ ssize_t freebsd32_pwrite(int fd, \
     				    const void *buf, size_t nbyte, \
    -				    u_int32_t offsetlo, u_int32_t offsethi); }
    +				    int pad, \
    +				    u_int32_t offset1, u_int32_t offset2); }
     477	AUE_MMAP	STD 	{ caddr_t freebsd32_mmap(caddr_t addr, \
     				    size_t len, int prot, int flags, int fd, \
    -				    u_int32_t poslo, u_int32_t poshi); }
    +				    int pad, \
    +				    u_int32_t pos1, u_int32_t pos2); }
     478	AUE_LSEEK	STD	{ off_t freebsd32_lseek(int fd, \
    -				    u_int32_t offsetlo, u_int32_t offsethi, \
    +				    int pad, \
    +				    u_int32_t offset1, u_int32_t offset2, \
     				    int whence); }
     479	AUE_TRUNCATE	STD	{ int freebsd32_truncate(char *path, \
    -				    u_int32_t lengthlo, u_int32_t lengthhi); }
    +				    int pad, \
    +				    u_int32_t length1, u_int32_t length2); }
     480	AUE_FTRUNCATE	STD	{ int freebsd32_ftruncate(int fd, \
    -				    u_int32_t lengthlo, u_int32_t lengthhi); }
    +				    int pad, \
    +				    u_int32_t length1, u_int32_t length2); }
    +#else
    +475	AUE_PREAD	STD	{ ssize_t freebsd32_pread(int fd, \
    +				    void *buf,size_t nbyte, \
    +				    u_int32_t offset1, u_int32_t offset2); }
    +476	AUE_PWRITE	STD	{ ssize_t freebsd32_pwrite(int fd, \
    +				    const void *buf, size_t nbyte, \
    +				    u_int32_t offset1, u_int32_t offset2); }
    +477	AUE_MMAP	STD 	{ caddr_t freebsd32_mmap(caddr_t addr, \
    +				    size_t len, int prot, int flags, int fd, \
    +				    u_int32_t pos1, u_int32_t pos2); }
    +478	AUE_LSEEK	STD	{ off_t freebsd32_lseek(int fd, \
    +				    u_int32_t offset1, u_int32_t offset2, \
    +				    int whence); }
    +479	AUE_TRUNCATE	STD	{ int freebsd32_truncate(char *path, \
    +				    u_int32_t length1, u_int32_t length2); }
    +480	AUE_FTRUNCATE	STD	{ int freebsd32_ftruncate(int fd, \
    +				    u_int32_t length1, u_int32_t length2); }
    +#endif
     481	AUE_KILL	NOPROTO	{ int thr_kill2(pid_t pid, long id, int sig); }
     482	AUE_SHMOPEN	NOPROTO	{ int shm_open(const char *path, int flags, \
     				    mode_t mode); }
     483	AUE_SHMUNLINK	NOPROTO	{ int shm_unlink(const char *path); }
     484	AUE_NULL	NOPROTO	{ int cpuset(cpusetid_t *setid); }
    +#ifdef PAD64_REQUIRED
     485	AUE_NULL	STD	{ int freebsd32_cpuset_setid(cpuwhich_t which, \
    -				    uint32_t idlo, uint32_t idhi, \
    +				    int pad, \
    +				    u_int32_t id1, u_int32_t id2, \
     				    cpusetid_t setid); }
    +#else
    +485	AUE_NULL	STD	{ int freebsd32_cpuset_setid(cpuwhich_t which, \
    +				    u_int32_t id1, u_int32_t id2, \
    +				    cpusetid_t setid); }
    +#endif
     486	AUE_NULL	STD	{ int freebsd32_cpuset_getid(cpulevel_t level, \
     				    cpuwhich_t which, \
    -				    uint32_t idlo, uint32_t idhi, \
    +				    u_int32_t id1, u_int32_t id2, \
     				    cpusetid_t *setid); }
     487	AUE_NULL	STD	{ int freebsd32_cpuset_getaffinity( \
     				    cpulevel_t level, cpuwhich_t which, \
    -				    uint32_t idlo, uint32_t idhi, \
    +				    u_int32_t id1, u_int32_t id2, \
     				    size_t cpusetsize, \
     				    cpuset_t *mask); }
     488	AUE_NULL	STD	{ int freebsd32_cpuset_setaffinity( \
     				    cpulevel_t level, cpuwhich_t which, \
    -				    uint32_t idlo, uint32_t idhi, \
    +				    u_int32_t id1, u_int32_t id2, \
     				    size_t cpusetsize, \
     				    const cpuset_t *mask); }
     489	AUE_FACCESSAT	NOPROTO	{ int faccessat(int fd, char *path, int mode, \
    diff --git a/sys/compat/ia32/ia32_reg.h b/sys/compat/ia32/ia32_reg.h
    index 5a9cdf2eebf..b9301974607 100644
    --- a/sys/compat/ia32/ia32_reg.h
    +++ b/sys/compat/ia32/ia32_reg.h
    @@ -105,29 +105,6 @@ struct save87 {
     	u_char	sv_pad[64];	/* padding; used by emulators */
     };
     
    -
    -/*
    - * Alternative layouts for 
    - * Used in core dumps, the reason for this file existing.
    - */
    -struct prstatus32 {
    -	int	pr_version;
    -	u_int	pr_statussz;
    -	u_int	pr_gregsetsz;
    -	u_int	pr_fpregsetsz;
    -	int	pr_osreldate;
    -	int	pr_cursig;
    -	pid_t	pr_pid;
    -	struct reg32 pr_reg;
    -};
    -
    -struct prpsinfo32 {
    -	int	pr_version;
    -	u_int	pr_psinfosz;
    -	char	pr_fname[PRFNAMESZ+1];
    -	char	pr_psargs[PRARGSZ+1];
    -};
    -
     /*
      * Wrappers and converters.
      */
    diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c
    index cb8d33df43a..79448a52507 100644
    --- a/sys/compat/ia32/ia32_sysvec.c
    +++ b/sys/compat/ia32/ia32_sysvec.c
    @@ -93,7 +93,6 @@ CTASSERT(sizeof(struct ia32_ucontext4) == 324);
     CTASSERT(sizeof(struct ia32_sigframe4) == 408);
     #endif
     
    -static register_t *ia32_copyout_strings(struct image_params *imgp);
     static void ia32_fixlimit(struct rlimit *rl, int which);
     
     SYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW, 0, "ia32 mode");
    @@ -132,7 +131,7 @@ struct sysentvec ia32_freebsd_sysvec = {
     	.sv_usrstack	= FREEBSD32_USRSTACK,
     	.sv_psstrings	= FREEBSD32_PS_STRINGS,
     	.sv_stackprot	= VM_PROT_ALL,
    -	.sv_copyout_strings	= ia32_copyout_strings,
    +	.sv_copyout_strings	= freebsd32_copyout_strings,
     	.sv_setregs	= ia32_setregs,
     	.sv_fixlimit	= ia32_fixlimit,
     	.sv_maxssiz	= &ia32_maxssiz,
    @@ -194,127 +193,6 @@ elf32_dump_thread(struct thread *td __unused, void *dst __unused,
     {
     }
     
    -
    -/* XXX may be freebsd32 MI */
    -static register_t *
    -ia32_copyout_strings(struct image_params *imgp)
    -{
    -	int argc, envc;
    -	u_int32_t *vectp;
    -	char *stringp, *destp;
    -	u_int32_t *stack_base;
    -	struct freebsd32_ps_strings *arginfo;
    -	size_t execpath_len;
    -	int szsigcode;
    -
    -	/*
    -	 * Calculate string base and vector table pointers.
    -	 * Also deal with signal trampoline code for this exec type.
    -	 */
    -	if (imgp->execpath != NULL && imgp->auxargs != NULL)
    -		execpath_len = strlen(imgp->execpath) + 1;
    -	else
    -		execpath_len = 0;
    -	arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS;
    -	szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
    -	destp =	(caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
    -		roundup(execpath_len, sizeof(char *)) -
    -		roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
    -
    -	/*
    -	 * install sigcode
    -	 */
    -	if (szsigcode)
    -		copyout(imgp->proc->p_sysent->sv_sigcode,
    -			((caddr_t)arginfo - szsigcode), szsigcode);
    -
    -	/*
    -	 * Copy the image path for the rtld.
    -	 */
    -	if (execpath_len != 0) {
    -		imgp->execpathp = (uintptr_t)arginfo - szsigcode - execpath_len;
    -		copyout(imgp->execpath, (void *)imgp->execpathp,
    -		    execpath_len);
    -	}
    -
    -	/*
    -	 * If we have a valid auxargs ptr, prepare some room
    -	 * on the stack.
    -	 */
    -	if (imgp->auxargs) {
    -		/*
    -		 * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
    -		 * lower compatibility.
    -		 */
    -		imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
    -			: (AT_COUNT * 2);
    -		/*
    -		 * The '+ 2' is for the null pointers at the end of each of
    -		 * the arg and env vector sets,and imgp->auxarg_size is room
    -		 * for argument of Runtime loader.
    -		 */
    -		vectp = (u_int32_t *) (destp - (imgp->args->argc +
    -		    imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) *
    -		    sizeof(u_int32_t));
    -	} else
    -		/*
    -		 * The '+ 2' is for the null pointers at the end of each of
    -		 * the arg and env vector sets
    -		 */
    -		vectp = (u_int32_t *)
    -			(destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
    -
    -	/*
    -	 * vectp also becomes our initial stack base
    -	 */
    -	stack_base = vectp;
    -
    -	stringp = imgp->args->begin_argv;
    -	argc = imgp->args->argc;
    -	envc = imgp->args->envc;
    -	/*
    -	 * Copy out strings - arguments and environment.
    -	 */
    -	copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
    -
    -	/*
    -	 * Fill in "ps_strings" struct for ps, w, etc.
    -	 */
    -	suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
    -	suword32(&arginfo->ps_nargvstr, argc);
    -
    -	/*
    -	 * Fill in argument portion of vector table.
    -	 */
    -	for (; argc > 0; --argc) {
    -		suword32(vectp++, (u_int32_t)(intptr_t)destp);
    -		while (*stringp++ != 0)
    -			destp++;
    -		destp++;
    -	}
    -
    -	/* a null vector table pointer separates the argp's from the envp's */
    -	suword32(vectp++, 0);
    -
    -	suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
    -	suword32(&arginfo->ps_nenvstr, envc);
    -
    -	/*
    -	 * Fill in environment portion of vector table.
    -	 */
    -	for (; envc > 0; --envc) {
    -		suword32(vectp++, (u_int32_t)(intptr_t)destp);
    -		while (*stringp++ != 0)
    -			destp++;
    -		destp++;
    -	}
    -
    -	/* end of vector table is a null pointer */
    -	suword32(vectp, 0);
    -
    -	return ((register_t *)stack_base);
    -}
    -
     static void
     ia32_fixlimit(struct rlimit *rl, int which)
     {
    diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
    index 2b33ea60b1e..2457abba0aa 100644
    --- a/sys/conf/files.amd64
    +++ b/sys/conf/files.amd64
    @@ -236,20 +236,20 @@ kern/link_elf_obj.c		standard
     #
     # IA32 binary support
     #
    -#amd64/ia32/ia32_exception.S	optional	compat_ia32
    -amd64/ia32/ia32_reg.c		optional	compat_ia32
    -amd64/ia32/ia32_signal.c	optional	compat_ia32
    -amd64/ia32/ia32_sigtramp.S	optional	compat_ia32
    -amd64/ia32/ia32_syscall.c	optional	compat_ia32
    -amd64/ia32/ia32_misc.c		optional	compat_ia32
    -compat/freebsd32/freebsd32_ioctl.c	optional	compat_ia32
    -compat/freebsd32/freebsd32_misc.c	optional	compat_ia32
    -compat/freebsd32/freebsd32_syscalls.c	optional	compat_ia32
    -compat/freebsd32/freebsd32_sysent.c	optional	compat_ia32
    -compat/ia32/ia32_sysvec.c	optional	compat_ia32
    +#amd64/ia32/ia32_exception.S	optional	compat_freebsd32
    +amd64/ia32/ia32_reg.c		optional	compat_freebsd32
    +amd64/ia32/ia32_signal.c	optional	compat_freebsd32
    +amd64/ia32/ia32_sigtramp.S	optional	compat_freebsd32
    +amd64/ia32/ia32_syscall.c	optional	compat_freebsd32
    +amd64/ia32/ia32_misc.c		optional	compat_freebsd32
    +compat/freebsd32/freebsd32_ioctl.c	optional	compat_freebsd32
    +compat/freebsd32/freebsd32_misc.c	optional	compat_freebsd32
    +compat/freebsd32/freebsd32_syscalls.c	optional	compat_freebsd32
    +compat/freebsd32/freebsd32_sysent.c	optional	compat_freebsd32
    +compat/ia32/ia32_sysvec.c	optional	compat_freebsd32
     compat/linprocfs/linprocfs.c	optional	linprocfs
     compat/linsysfs/linsysfs.c	optional	linsysfs
    -kern/imgact_elf32.c		optional	compat_ia32
    +kern/imgact_elf32.c		optional	compat_freebsd32
     #
     # Linux/i386 binary support
     #
    diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64
    index 17673317904..253c55ed056 100644
    --- a/sys/conf/files.ia64
    +++ b/sys/conf/files.ia64
    @@ -28,11 +28,11 @@ ukbdmap.h			optional	ukbd_dflt_keymap	\
     	no-obj no-implicit-rule before-depend				\
     	clean		"ukbdmap.h"
     #
    -compat/freebsd32/freebsd32_ioctl.c	optional	compat_ia32
    -compat/freebsd32/freebsd32_misc.c	optional	compat_ia32
    -compat/freebsd32/freebsd32_syscalls.c	optional	compat_ia32
    -compat/freebsd32/freebsd32_sysent.c	optional	compat_ia32
    -compat/ia32/ia32_sysvec.c		optional	compat_ia32
    +compat/freebsd32/freebsd32_ioctl.c	optional	compat_freebsd32
    +compat/freebsd32/freebsd32_misc.c	optional	compat_freebsd32
    +compat/freebsd32/freebsd32_syscalls.c	optional	compat_freebsd32
    +compat/freebsd32/freebsd32_sysent.c	optional	compat_freebsd32
    +compat/ia32/ia32_sysvec.c		optional	compat_freebsd32
     contrib/ia64/libuwx/src/uwx_bstream.c		standard
     contrib/ia64/libuwx/src/uwx_context.c		standard
     contrib/ia64/libuwx/src/uwx_env.c		standard
    @@ -69,10 +69,10 @@ ia64/acpica/madt.c		optional	acpi
     ia64/disasm/disasm_decode.c	standard
     ia64/disasm/disasm_extract.c	standard
     ia64/disasm/disasm_format.c	standard
    -ia64/ia32/ia32_misc.c		optional	compat_ia32
    -ia64/ia32/ia32_reg.c		optional	compat_ia32
    -ia64/ia32/ia32_signal.c		optional	compat_ia32
    -ia64/ia32/ia32_trap.c		optional	compat_ia32
    +ia64/ia32/ia32_misc.c		optional	compat_freebsd32
    +ia64/ia32/ia32_reg.c		optional	compat_freebsd32
    +ia64/ia32/ia32_signal.c		optional	compat_freebsd32
    +ia64/ia32/ia32_trap.c		optional	compat_freebsd32
     ia64/ia64/autoconf.c		standard
     ia64/ia64/bus_machdep.c		standard
     ia64/ia64/busdma_machdep.c	standard
    @@ -118,7 +118,7 @@ ia64/isa/isa_dma.c		optional	isa
     ia64/pci/pci_cfgreg.c		optional	pci
     isa/syscons_isa.c		optional	sc
     isa/vga_isa.c			optional	vga
    -kern/imgact_elf32.c		optional	compat_ia32
    +kern/imgact_elf32.c		optional	compat_freebsd32
     libkern/bcmp.c			standard
     libkern/ffsl.c			standard
     libkern/fls.c			standard
    diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64
    index 5617da4e181..20a49a188c6 100644
    --- a/sys/conf/options.amd64
    +++ b/sys/conf/options.amd64
    @@ -11,7 +11,7 @@ MP_WATCHDOG
     # Options for emulators.  These should only be used at config time, so
     # they are handled like options for static filesystems
     # (see src/sys/conf/options), except for broken debugging options.
    -COMPAT_IA32		opt_compat.h
    +COMPAT_FREEBSD32	opt_compat.h
     #IBCS2			opt_dontuse.h
     #COMPAT_LINUX		opt_dontuse.h
     COMPAT_LINUX32		opt_compat.h
    diff --git a/sys/conf/options.ia64 b/sys/conf/options.ia64
    index 7a292ed711d..603c5ed011f 100644
    --- a/sys/conf/options.ia64
    +++ b/sys/conf/options.ia64
    @@ -9,7 +9,7 @@ LOG2_PAGE_SIZE		opt_global.h
     
     UWX_TRACE_ENABLE	opt_global.h
     
    -COMPAT_IA32		opt_compat.h
    +COMPAT_FREEBSD32	opt_compat.h
     
     EXCEPTION_TRACING	opt_xtrace.h
     
    diff --git a/sys/fs/procfs/procfs_dbregs.c b/sys/fs/procfs/procfs_dbregs.c
    index efa4e14d668..68945ef952f 100644
    --- a/sys/fs/procfs/procfs_dbregs.c
    +++ b/sys/fs/procfs/procfs_dbregs.c
    @@ -59,10 +59,9 @@
     #include 
     #include 
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #include 
     #include 
    -#include 
     
     /*
      * PROC(write, dbregs, td2, &r) becomes
    @@ -90,7 +89,7 @@ procfs_doprocdbregs(PFS_FILL_ARGS)
     	int error;
     	struct dbreg r;
     	struct thread *td2;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	struct dbreg32 r32;
     	int wrap32 = 0;
     #endif
    @@ -106,7 +105,7 @@ procfs_doprocdbregs(PFS_FILL_ARGS)
     	}
     
     	td2 = FIRST_THREAD_IN_PROC(p);
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	if (SV_CURPROC_FLAG(SV_ILP32)) {
     		if ((td2->td_proc->p_sysent->sv_flags & SV_ILP32) == 0) {
     			PROC_UNLOCK(p);
    diff --git a/sys/fs/procfs/procfs_fpregs.c b/sys/fs/procfs/procfs_fpregs.c
    index 43af53e3ce5..c35b0660f1a 100644
    --- a/sys/fs/procfs/procfs_fpregs.c
    +++ b/sys/fs/procfs/procfs_fpregs.c
    @@ -53,10 +53,9 @@
     #include 
     #include 
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #include 
     #include 
    -#include 
     
     /*
      * PROC(write, fpregs, td2, &r) becomes
    @@ -84,7 +83,7 @@ procfs_doprocfpregs(PFS_FILL_ARGS)
     	int error;
     	struct fpreg r;
     	struct thread *td2;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	struct fpreg32 r32;
     	int wrap32 = 0;
     #endif
    @@ -101,7 +100,7 @@ procfs_doprocfpregs(PFS_FILL_ARGS)
     
     	/* XXXKSE: */
     	td2 = FIRST_THREAD_IN_PROC(p);
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	if (SV_CURPROC_FLAG(SV_ILP32)) {
     		if ((td2->td_proc->p_sysent->sv_flags & SV_ILP32) == 0) {
     			PROC_UNLOCK(p);
    diff --git a/sys/fs/procfs/procfs_ioctl.c b/sys/fs/procfs/procfs_ioctl.c
    index ccff555280f..4b45af67009 100644
    --- a/sys/fs/procfs/procfs_ioctl.c
    +++ b/sys/fs/procfs/procfs_ioctl.c
    @@ -42,7 +42,7 @@
     #include 
     #include 
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     struct procfs_status32 {
     	int	state;	/* Running, stopped, something else? */
     	int	flags;	/* Any flags */
    @@ -62,7 +62,7 @@ int
     procfs_ioctl(PFS_IOCTL_ARGS)
     {
     	struct procfs_status *ps;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	struct procfs_status32 *ps32;
     #endif
     	int error, flags, sig;
    @@ -142,7 +142,7 @@ procfs_ioctl(PFS_IOCTL_ARGS)
     		ps->why = p->p_step ? p->p_stype : 0;
     		ps->val = p->p_step ? p->p_xstat : 0;
     		break;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	case PIOCWAIT32:
     		while (p->p_step == 0 && (p->p_flag & P_WEXIT) == 0) {
     			/* sleep until p stops */
    diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
    index 878e2d5a658..2622d1e335f 100644
    --- a/sys/fs/procfs/procfs_map.c
    +++ b/sys/fs/procfs/procfs_map.c
    @@ -47,7 +47,7 @@
     #include 
     #include 
     #include 
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #include 
     #endif
     #include 
    @@ -86,7 +86,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
     	struct uidinfo *uip;
     	int error, vfslocked;
     	unsigned int last_timestamp;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	int wrap32 = 0;
     #endif
     
    @@ -99,7 +99,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
     	if (uio->uio_rw != UIO_READ)
     		return (EOPNOTSUPP);
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
             if (curproc->p_sysent->sv_flags & SV_ILP32) {
                     if (!(p->p_sysent->sv_flags & SV_ILP32))
                             return (EOPNOTSUPP);
    @@ -209,7 +209,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
     		    "0x%lx 0x%lx %d %d %p %s%s%s %d %d 0x%x %s %s %s %s %s %d\n",
     			(u_long)e_start, (u_long)e_end,
     			resident, privateresident,
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     			wrap32 ? NULL : obj,	/* Hide 64 bit value */
     #else
     			obj,
    diff --git a/sys/fs/procfs/procfs_regs.c b/sys/fs/procfs/procfs_regs.c
    index 82922fbe897..5bf1c0ac7f9 100644
    --- a/sys/fs/procfs/procfs_regs.c
    +++ b/sys/fs/procfs/procfs_regs.c
    @@ -53,10 +53,9 @@
     #include 
     #include 
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #include 
     #include 
    -#include 
     
     /*
      * PROC(write, regs, td2, &r) becomes
    @@ -84,7 +83,7 @@ procfs_doprocregs(PFS_FILL_ARGS)
     	int error;
     	struct reg r;
     	struct thread *td2;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	struct reg32 r32;
     	int wrap32 = 0;
     #endif
    @@ -101,7 +100,7 @@ procfs_doprocregs(PFS_FILL_ARGS)
     
     	/* XXXKSE: */
     	td2 = FIRST_THREAD_IN_PROC(p);
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	if (SV_CURPROC_FLAG(SV_ILP32)) {
     		if ((td2->td_proc->p_sysent->sv_flags & SV_ILP32) == 0) {
     			PROC_UNLOCK(p);
    diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
    index e0e739da290..a536ced00ec 100644
    --- a/sys/ia64/conf/GENERIC
    +++ b/sys/ia64/conf/GENERIC
    @@ -28,6 +28,7 @@ makeoptions	DEBUG=-g	# Build kernel with debug information.
     options 	AUDIT		# Security event auditing
     options 	CD9660		# ISO 9660 Filesystem
     options 	COMPAT_43TTY	# BSD 4.3 TTY compat (sgtty)
    +options 	COMPAT_FREEBSD6	# Compatible with FreeBSD6
     options 	COMPAT_FREEBSD7	# Compatible with FreeBSD7
     options 	FFS		# Berkeley Fast Filesystem
     options 	FLOWTABLE	# per-cpu routing cache
    diff --git a/sys/ia64/conf/NOTES b/sys/ia64/conf/NOTES
    index 873199a61b0..3f3821856b1 100644
    --- a/sys/ia64/conf/NOTES
    +++ b/sys/ia64/conf/NOTES
    @@ -12,10 +12,10 @@
     cpu		ITANIUM
     cpu		ITANIUM2
     
    -# option: COMPAT_IA32
    +# option: COMPAT_FREEBSD32
     # This option enables the support for execution of i386 (32-bit) programs on
     # ia64. It is based on the ia32 emulation in the processor.
    -options 	COMPAT_IA32
    +options 	COMPAT_FREEBSD32
     
     # option: LOG2_ID_PAGE_SIZE
     # Specify the log2 size of the identity (direct) mappings in regions 6 and 7
    diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S
    index 755a467d745..4464a880b16 100644
    --- a/sys/ia64/ia64/exception.S
    +++ b/sys/ia64/ia64/exception.S
    @@ -676,7 +676,7 @@ ivt_##name:					\
     #define	IVT_END(name)				\
     	.endp	ivt_##name
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #define	IA32_TRAP	ia32_trap
     #else
     #define	IA32_TRAP	trap
    diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c
    index 9f7625279d9..d81054b9cea 100644
    --- a/sys/ia64/ia64/genassym.c
    +++ b/sys/ia64/ia64/genassym.c
    @@ -61,8 +61,8 @@
     #include 
     #include 
     
    -#ifdef COMPAT_IA32
    -ASSYM(COMPAT_IA32,	COMPAT_IA32);
    +#ifdef COMPAT_FREEBSD32
    +ASSYM(COMPAT_FREEBSD32,	COMPAT_FREEBSD32);
     #endif
     
     ASSYM(DT_NULL,		DT_NULL);
    diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
    index e2e9f9141d9..ec3d612ebac 100644
    --- a/sys/ia64/ia64/machdep.c
    +++ b/sys/ia64/ia64/machdep.c
    @@ -440,7 +440,7 @@ cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx)
     	struct pcb *oldpcb, *newpcb;
     
     	oldpcb = old->td_pcb;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	ia32_savectx(oldpcb);
     #endif
     	if (PCPU_GET(fpcurthread) == old)
    @@ -459,7 +459,7 @@ cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx)
     
     		PCPU_SET(curthread, new);
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     		ia32_restorectx(newpcb);
     #endif
     
    @@ -487,7 +487,7 @@ cpu_throw(struct thread *old __unused, struct thread *new)
     
     	PCPU_SET(curthread, new);
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	ia32_restorectx(newpcb);
     #endif
     
    diff --git a/sys/ia64/include/elf.h b/sys/ia64/include/elf.h
    index c6a43fcdc17..27182dbcae9 100644
    --- a/sys/ia64/include/elf.h
    +++ b/sys/ia64/include/elf.h
    @@ -43,6 +43,7 @@
     #include 
     
     #define	ELF_ARCH	EM_IA_64
    +#define	ELF_ARCH32	EM_386
     
     #define	ELF_MACHINE_OK(x) ((x) == EM_IA_64)
     
    diff --git a/sys/ia64/include/reg.h b/sys/ia64/include/reg.h
    index 453c9b83141..e95db312d4a 100644
    --- a/sys/ia64/include/reg.h
    +++ b/sys/ia64/include/reg.h
    @@ -31,6 +31,10 @@
     
     #include 
     
    +#if defined(_KERNEL) && !defined(_STANDALONE)
    +#include "opt_compat.h"
    +#endif
    +
     struct reg {
     	struct _special		r_special;
     	struct _callee_saved	r_preserved;
    @@ -48,6 +52,11 @@ struct dbreg {
     	unsigned long	dbr_inst[8];
     };
     
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#endif
    +
     #ifdef _KERNEL
     struct thread;
     
    diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
    index 56cd66f254f..0ece0204107 100644
    --- a/sys/kern/imgact_elf.c
    +++ b/sys/kern/imgact_elf.c
    @@ -70,11 +70,6 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
    -#include 
    -#include 
    -#endif
    -
     #define OLD_EI_BRAND	8
     
     static int __elfN(check_header)(const Elf_Ehdr *hdr);
    @@ -1210,7 +1205,9 @@ __elfN(corehdr)(td, vp, cred, numsegs, hdr, hdrsize)
     	    td));
     }
     
    -#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
    +#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
    +#include 
    +
     typedef struct prstatus32 elf_prstatus_t;
     typedef struct prpsinfo32 elf_prpsinfo_t;
     typedef struct fpreg32 elf_prfpregset_t;
    @@ -1294,7 +1291,7 @@ __elfN(puthdr)(struct thread *td, void *dst, size_t *off, int numsegs)
     			status->pr_osreldate = osreldate;
     			status->pr_cursig = p->p_sig;
     			status->pr_pid = thr->td_tid;
    -#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
    +#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
     			fill_regs32(thr, &status->pr_reg);
     			fill_fpregs32(thr, fpregset);
     #else
    @@ -1346,8 +1343,8 @@ __elfN(puthdr)(struct thread *td, void *dst, size_t *off, int numsegs)
     		ehdr->e_ident[EI_ABIVERSION] = 0;
     		ehdr->e_ident[EI_PAD] = 0;
     		ehdr->e_type = ET_CORE;
    -#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
    -		ehdr->e_machine = EM_386;
    +#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
    +		ehdr->e_machine = ELF_ARCH32;
     #else
     		ehdr->e_machine = ELF_ARCH;
     #endif
    diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
    index 93fdfa9303b..d419833dada 100644
    --- a/sys/kern/kern_jail.c
    +++ b/sys/kern/kern_jail.c
    @@ -734,8 +734,8 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
     		}
     	}
     
    -#ifdef COMPAT_IA32
    -	if (td->td_proc->p_sysent->sv_flags & SV_IA32) {
    +#ifdef COMPAT_FREEBSD32
    +	if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
     		uint32_t hid32;
     
     		error = vfs_copyopt(opts, "host.hostid", &hid32, sizeof(hid32));
    @@ -1961,8 +1961,8 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)
     	error = vfs_setopts(opts, "host.hostuuid", pr->pr_hostuuid);
     	if (error != 0 && error != ENOENT)
     		goto done_deref;
    -#ifdef COMPAT_IA32
    -	if (td->td_proc->p_sysent->sv_flags & SV_IA32) {
    +#ifdef COMPAT_FREEBSD32
    +	if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
     		uint32_t hid32 = pr->pr_hostid;
     
     		error = vfs_setopt(opts, "host.hostid", &hid32, sizeof(hid32));
    diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c
    index 9c53bf6f463..0409344b9b0 100644
    --- a/sys/kern/kern_module.c
    +++ b/sys/kern/kern_module.c
    @@ -446,7 +446,7 @@ modfind(struct thread *td, struct modfind_args *uap)
     
     MODULE_VERSION(kernel, __FreeBSD_version);
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #include 
     #include 
     #include 
    diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
    index 116e79bae33..0b90dfc3406 100644
    --- a/sys/kern/kern_thr.c
    +++ b/sys/kern/kern_thr.c
    @@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     
     static inline int
     suword_lwpid(void *addr, lwpid_t lwpid)
    diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
    index a57dc3d903b..dac168c4b40 100644
    --- a/sys/kern/kern_umtx.c
    +++ b/sys/kern/kern_umtx.c
    @@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #include 
     #endif
     
    @@ -751,7 +751,7 @@ do_unlock_umtx(struct thread *td, struct umtx *umtx, u_long id)
     	return (0);
     }
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     
     /*
      * Lock a umtx object.
    @@ -3075,7 +3075,7 @@ _umtx_op(struct thread *td, struct _umtx_op_args *uap)
     	return (EINVAL);
     }
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     int
     freebsd32_umtx_lock(struct thread *td, struct freebsd32_umtx_lock_args *uap)
         /* struct umtx *umtx */
    diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
    index b34af613237..eaefd9c6903 100644
    --- a/sys/kern/sys_generic.c
    +++ b/sys/kern/sys_generic.c
    @@ -878,9 +878,10 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
     	sbp = selbits;
     #define	getbits(name, x) \
     	do {								\
    -		if (name == NULL)					\
    +		if (name == NULL) {					\
     			ibits[x] = NULL;				\
    -		else {							\
    +			obits[x] = NULL;				\
    +		} else {						\
     			ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp;	\
     			obits[x] = sbp;					\
     			sbp += ncpbytes / sizeof *sbp;			\
    @@ -895,6 +896,28 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
     	getbits(fd_ou, 1);
     	getbits(fd_ex, 2);
     #undef	getbits
    +
    +#if BYTE_ORDER == BIG_ENDIAN && defined(__LP64__)
    +	/*
    +	 * XXX: swizzle_fdset assumes that if abi_nfdbits != NFDBITS,
    +	 * we are running under 32-bit emulation. This should be more
    +	 * generic.
    +	 */
    +#define swizzle_fdset(bits)						\
    +	if (abi_nfdbits != NFDBITS && bits != NULL) {			\
    +		int i;							\
    +		for (i = 0; i < ncpbytes / sizeof *sbp; i++)		\
    +			bits[i] = (bits[i] >> 32) | (bits[i] << 32);	\
    +	}
    +#else
    +#define swizzle_fdset(bits)
    +#endif
    +
    +	/* Make sure the bit order makes it through an ABI transition */
    +	swizzle_fdset(ibits[0]);
    +	swizzle_fdset(ibits[1]);
    +	swizzle_fdset(ibits[2]);
    +	
     	if (nbufbytes != 0)
     		bzero(selbits, nbufbytes / 2);
     
    @@ -941,6 +964,13 @@ done:
     		error = EINTR;
     	if (error == EWOULDBLOCK)
     		error = 0;
    +
    +	/* swizzle bit order back, if necessary */
    +	swizzle_fdset(obits[0]);
    +	swizzle_fdset(obits[1]);
    +	swizzle_fdset(obits[2]);
    +#undef swizzle_fdset
    +
     #define	putbits(name, x) \
     	if (name && (error2 = copyout(obits[x], name, ncpubytes))) \
     		error = error2;
    diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
    index 4f2569d1860..88f4f6011e8 100644
    --- a/sys/kern/sys_process.c
    +++ b/sys/kern/sys_process.c
    @@ -61,10 +61,8 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #include 
    -#include 
    -#include 
     
     struct ptrace_io_desc32 {
     	int		piod_op;
    @@ -171,7 +169,7 @@ proc_write_fpregs(struct thread *td, struct fpreg *fpregs)
     	PROC_ACTION(set_fpregs(td, fpregs));
     }
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     /* For 32 bit binaries, we need to expose the 32 bit regs layouts. */
     int
     proc_read_regs32(struct thread *td, struct reg32 *regs32)
    @@ -470,7 +468,7 @@ ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
     	return (error);
     }
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     static int      
     ptrace_vm_entry32(struct thread *td, struct proc *p,
         struct ptrace_vm_entry32 *pve32)
    @@ -497,7 +495,7 @@ ptrace_vm_entry32(struct thread *td, struct proc *p,
     	pve32->pve_pathlen = pve.pve_pathlen;
     	return (error);
     }
    -#endif /* COMPAT_IA32 */
    +#endif /* COMPAT_FREEBSD32 */
     
     /*
      * Process debugging system call.
    @@ -511,7 +509,7 @@ struct ptrace_args {
     };
     #endif
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     /*
      * This CPP subterfuge is to try and reduce the number of ifdefs in
      * the body of the code.
    @@ -546,7 +544,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
     		struct dbreg dbreg;
     		struct fpreg fpreg;
     		struct reg reg;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     		struct dbreg32 dbreg32;
     		struct fpreg32 fpreg32;
     		struct reg32 reg32;
    @@ -556,7 +554,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
     	} r;
     	void *addr;
     	int error = 0;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	int wrap32 = 0;
     
     	if (SV_CURPROC_FLAG(SV_ILP32))
    @@ -624,7 +622,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
     #undef COPYIN
     #undef COPYOUT
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     /*
      *   PROC_READ(regs, td2, addr);
      * becomes either:
    @@ -658,7 +656,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
     	int error, write, tmp, num;
     	int proctree_locked = 0;
     	lwpid_t tid = 0, *buf;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	int wrap32 = 0, safe = 0;
     	struct ptrace_io_desc32 *piod32 = NULL;
     #endif
    @@ -746,7 +744,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
     		tid = td2->td_tid;
     	}
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     	/*
     	 * Test if we're a 32 bit client and what the target is.
     	 * Set the wrap controls accordingly.
    @@ -1014,7 +1012,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
     		break;
     
     	case PT_IO:
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     		if (wrap32) {
     			piod32 = addr;
     			iov.iov_base = (void *)(uintptr_t)piod32->piod_addr;
    @@ -1034,7 +1032,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
     		uio.uio_iovcnt = 1;
     		uio.uio_segflg = UIO_USERSPACE;
     		uio.uio_td = td;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     		tmp = wrap32 ? piod32->piod_op : piod->piod_op;
     #else
     		tmp = piod->piod_op;
    @@ -1055,7 +1053,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
     		}
     		PROC_UNLOCK(p);
     		error = proc_rwmem(p, &uio);
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     		if (wrap32)
     			piod32->piod_len -= uio.uio_resid;
     		else
    @@ -1144,7 +1142,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
     
     	case PT_VM_ENTRY:
     		PROC_UNLOCK(p);
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     		if (wrap32)
     			error = ptrace_vm_entry32(td, p, addr);
     		else
    diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
    index afa3d71884c..07f0e1ba87f 100644
    --- a/sys/kern/uipc_socket.c
    +++ b/sys/kern/uipc_socket.c
    @@ -136,7 +136,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #include 
     #include 
     #include 
    @@ -2496,7 +2496,7 @@ sosetopt(struct socket *so, struct sockopt *sopt)
     
     		case SO_SNDTIMEO:
     		case SO_RCVTIMEO:
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     			if (SV_CURPROC_FLAG(SV_ILP32)) {
     				struct timeval32 tv32;
     
    @@ -2677,7 +2677,7 @@ integer:
     
     			tv.tv_sec = optval / hz;
     			tv.tv_usec = (optval % hz) * tick;
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     			if (SV_CURPROC_FLAG(SV_ILP32)) {
     				struct timeval32 tv32;
     
    diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
    index 3f7596b7956..841d39a15f1 100644
    --- a/sys/kern/vfs_aio.c
    +++ b/sys/kern/vfs_aio.c
    @@ -2524,7 +2524,7 @@ filt_lio(struct knote *kn, long hint)
     	return (lj->lioj_flags & LIOJ_KEVENT_POSTED);
     }
     
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     #include 
     #include 
     #include 
    diff --git a/sys/modules/linux/Makefile b/sys/modules/linux/Makefile
    index a24b6b27be7..a67fcc70284 100644
    --- a/sys/modules/linux/Makefile
    +++ b/sys/modules/linux/Makefile
    @@ -2,7 +2,7 @@
     
     .if ${MACHINE_ARCH} == "amd64"
     SFX= 32
    -CFLAGS+=-DCOMPAT_IA32 -DCOMPAT_LINUX32
    +CFLAGS+=-DCOMPAT_FREEBSD32 -DCOMPAT_LINUX32
     .endif
     
     .PATH: ${.CURDIR}/../../compat/linux ${.CURDIR}/../../${MACHINE_ARCH}/linux${SFX}
    diff --git a/sys/modules/procfs/Makefile b/sys/modules/procfs/Makefile
    index c3b36337f02..9a94838c70a 100644
    --- a/sys/modules/procfs/Makefile
    +++ b/sys/modules/procfs/Makefile
    @@ -35,7 +35,7 @@ opt_compat.h:
     	echo "#define COMPAT_FREEBSD5 1" >> ${.TARGET}
     	echo "#define COMPAT_FREEBSD6 1" >> ${.TARGET}
     .if ${MACHINE_ARCH} == "amd64"
    -	echo "#define COMPAT_IA32 1" >> ${.TARGET}
    +	echo "#define COMPAT_FREEBSD32 1" >> ${.TARGET}
     	echo "#define COMPAT_LINUX32 1" >> ${.TARGET}
     .endif
     .endif
    diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
    index e3653b657d1..b30447cfb68 100644
    --- a/sys/sys/ptrace.h
    +++ b/sys/sys/ptrace.h
    @@ -34,6 +34,7 @@
     #define	_SYS_PTRACE_H_
     
     #include 
    +#include 
     
     #define	PT_TRACE_ME	0	/* child declares it's being traced */
     #define	PT_READ_I	1	/* read word in child's I space */
    @@ -157,7 +158,7 @@ int	proc_read_dbregs(struct thread *_td, struct dbreg *_dbreg);
     int	proc_write_dbregs(struct thread *_td, struct dbreg *_dbreg);
     int	proc_sstep(struct thread *_td);
     int	proc_rwmem(struct proc *_p, struct uio *_uio);
    -#ifdef COMPAT_IA32
    +#ifdef COMPAT_FREEBSD32
     struct reg32;
     struct fpreg32;
     struct dbreg32;
    
    From b47065d16d47bcd89d3bca65642669f29961728f Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Wed, 7 Apr 2010 02:25:36 +0000
    Subject: [PATCH 1895/2592] Regen after MFC of COMPAT_FREEBSD32.
    
    ---
     sys/compat/freebsd32/freebsd32_proto.h    | 200 +++++++++++++++++-----
     sys/compat/freebsd32/freebsd32_syscall.h  |   9 +-
     sys/compat/freebsd32/freebsd32_syscalls.c |  18 +-
     sys/compat/freebsd32/freebsd32_sysent.c   |  18 +-
     4 files changed, 203 insertions(+), 42 deletions(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h
    index 551d9011bd7..e6c91af6f7b 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: stable/8/sys/compat/freebsd32/syscalls.master 200725 2009-12-19 11:47:00Z kib 
    + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 206336 2010-04-07 02:24:41Z nwhitehorn 
      */
     
     #ifndef _FREEBSD32_SYSPROTO_H_
    @@ -32,6 +32,9 @@ struct thread;
     #define	PADR_(t)	0
     #endif
     
    +#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
    +#define PAD64_REQUIRED
    +#endif
     struct freebsd32_wait4_args {
     	char pid_l_[PADL_(int)]; int pid; char pid_r_[PADR_(int)];
     	char status_l_[PADL_(int *)]; int * status; char status_r_[PADR_(int *)];
    @@ -223,13 +226,15 @@ struct freebsd32_preadv_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char iovp_l_[PADL_(struct iovec32 *)]; struct iovec32 * iovp; char iovp_r_[PADR_(struct iovec32 *)];
     	char iovcnt_l_[PADL_(u_int)]; u_int iovcnt; char iovcnt_r_[PADR_(u_int)];
    -	char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     };
     struct freebsd32_pwritev_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char iovp_l_[PADL_(struct iovec32 *)]; struct iovec32 * iovp; char iovp_r_[PADR_(struct iovec32 *)];
     	char iovcnt_l_[PADL_(u_int)]; u_int iovcnt; char iovcnt_r_[PADR_(u_int)];
    -	char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     };
     struct freebsd32_modstat_args {
     	char modid_l_[PADL_(int)]; int modid; char modid_r_[PADR_(int)];
    @@ -294,8 +299,8 @@ struct freebsd32_nmount_args {
     struct freebsd32_sendfile_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
    -	char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
    -	char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     	char nbytes_l_[PADL_(size_t)]; size_t nbytes; char nbytes_r_[PADR_(size_t)];
     	char hdtr_l_[PADL_(struct sf_hdtr32 *)]; struct sf_hdtr32 * hdtr; char hdtr_r_[PADR_(struct sf_hdtr32 *)];
     	char sbytes_l_[PADL_(off_t *)]; off_t * sbytes; char sbytes_r_[PADR_(off_t *)];
    @@ -343,19 +348,22 @@ struct freebsd32_aio_fsync_args {
     	char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)];
     	char aiocbp_l_[PADL_(struct aiocb32 *)]; struct aiocb32 * aiocbp; char aiocbp_r_[PADR_(struct aiocb32 *)];
     };
    +#ifdef PAD64_REQUIRED
     struct freebsd32_pread_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
     	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
    -	char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
    -	char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
    +	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     };
     struct freebsd32_pwrite_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
     	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
    -	char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
    -	char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
    +	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     };
     struct freebsd32_mmap_args {
     	char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
    @@ -363,51 +371,106 @@ struct freebsd32_mmap_args {
     	char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
     	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
    -	char poslo_l_[PADL_(u_int32_t)]; u_int32_t poslo; char poslo_r_[PADR_(u_int32_t)];
    -	char poshi_l_[PADL_(u_int32_t)]; u_int32_t poshi; char poshi_r_[PADR_(u_int32_t)];
    +	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    +	char pos1_l_[PADL_(u_int32_t)]; u_int32_t pos1; char pos1_r_[PADR_(u_int32_t)];
    +	char pos2_l_[PADL_(u_int32_t)]; u_int32_t pos2; char pos2_r_[PADR_(u_int32_t)];
     };
     struct freebsd32_lseek_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
    -	char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
    -	char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
    +	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     	char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
     };
     struct freebsd32_truncate_args {
     	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
    -	char lengthlo_l_[PADL_(u_int32_t)]; u_int32_t lengthlo; char lengthlo_r_[PADR_(u_int32_t)];
    -	char lengthhi_l_[PADL_(u_int32_t)]; u_int32_t lengthhi; char lengthhi_r_[PADR_(u_int32_t)];
    +	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    +	char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
    +	char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
     };
     struct freebsd32_ftruncate_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
    -	char lengthlo_l_[PADL_(u_int32_t)]; u_int32_t lengthlo; char lengthlo_r_[PADR_(u_int32_t)];
    -	char lengthhi_l_[PADL_(u_int32_t)]; u_int32_t lengthhi; char lengthhi_r_[PADR_(u_int32_t)];
    +	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    +	char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
    +	char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
     };
    +#else
    +struct freebsd32_pread_args {
    +	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
    +	char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
    +	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
    +};
    +struct freebsd32_pwrite_args {
    +	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
    +	char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
    +	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
    +};
    +struct freebsd32_mmap_args {
    +	char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
    +	char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
    +	char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
    +	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
    +	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
    +	char pos1_l_[PADL_(u_int32_t)]; u_int32_t pos1; char pos1_r_[PADR_(u_int32_t)];
    +	char pos2_l_[PADL_(u_int32_t)]; u_int32_t pos2; char pos2_r_[PADR_(u_int32_t)];
    +};
    +struct freebsd32_lseek_args {
    +	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
    +	char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
    +};
    +struct freebsd32_truncate_args {
    +	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
    +	char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
    +	char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
    +};
    +struct freebsd32_ftruncate_args {
    +	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
    +	char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
    +	char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
    +};
    +#endif
    +#ifdef PAD64_REQUIRED
     struct freebsd32_cpuset_setid_args {
     	char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
    -	char idlo_l_[PADL_(uint32_t)]; uint32_t idlo; char idlo_r_[PADR_(uint32_t)];
    -	char idhi_l_[PADL_(uint32_t)]; uint32_t idhi; char idhi_r_[PADR_(uint32_t)];
    +	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    +	char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
    +	char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
     	char setid_l_[PADL_(cpusetid_t)]; cpusetid_t setid; char setid_r_[PADR_(cpusetid_t)];
     };
    +#else
    +struct freebsd32_cpuset_setid_args {
    +	char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
    +	char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
    +	char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
    +	char setid_l_[PADL_(cpusetid_t)]; cpusetid_t setid; char setid_r_[PADR_(cpusetid_t)];
    +};
    +#endif
     struct freebsd32_cpuset_getid_args {
     	char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
     	char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
    -	char idlo_l_[PADL_(uint32_t)]; uint32_t idlo; char idlo_r_[PADR_(uint32_t)];
    -	char idhi_l_[PADL_(uint32_t)]; uint32_t idhi; char idhi_r_[PADR_(uint32_t)];
    +	char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
    +	char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
     	char setid_l_[PADL_(cpusetid_t *)]; cpusetid_t * setid; char setid_r_[PADR_(cpusetid_t *)];
     };
     struct freebsd32_cpuset_getaffinity_args {
     	char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
     	char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
    -	char idlo_l_[PADL_(uint32_t)]; uint32_t idlo; char idlo_r_[PADR_(uint32_t)];
    -	char idhi_l_[PADL_(uint32_t)]; uint32_t idhi; char idhi_r_[PADR_(uint32_t)];
    +	char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
    +	char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
     	char cpusetsize_l_[PADL_(size_t)]; size_t cpusetsize; char cpusetsize_r_[PADR_(size_t)];
     	char mask_l_[PADL_(cpuset_t *)]; cpuset_t * mask; char mask_r_[PADR_(cpuset_t *)];
     };
     struct freebsd32_cpuset_setaffinity_args {
     	char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
     	char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
    -	char idlo_l_[PADL_(uint32_t)]; uint32_t idlo; char idlo_r_[PADR_(uint32_t)];
    -	char idhi_l_[PADL_(uint32_t)]; uint32_t idhi; char idhi_r_[PADR_(uint32_t)];
    +	char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
    +	char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
     	char cpusetsize_l_[PADL_(size_t)]; size_t cpusetsize; char cpusetsize_r_[PADR_(size_t)];
     	char mask_l_[PADL_(const cpuset_t *)]; const cpuset_t * mask; char mask_r_[PADR_(const cpuset_t *)];
     };
    @@ -461,6 +524,9 @@ struct freebsd32_pselect_args {
     	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 *)];
     };
    +#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
    +#define PAD64_REQUIRED
    +#endif
     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 *);
    @@ -526,13 +592,26 @@ int	freebsd32_thr_suspend(struct thread *, struct freebsd32_thr_suspend_args *);
     int	freebsd32_umtx_op(struct thread *, struct freebsd32_umtx_op_args *);
     int	freebsd32_thr_new(struct thread *, struct freebsd32_thr_new_args *);
     int	freebsd32_aio_fsync(struct thread *, struct freebsd32_aio_fsync_args *);
    +#ifdef PAD64_REQUIRED
     int	freebsd32_pread(struct thread *, struct freebsd32_pread_args *);
     int	freebsd32_pwrite(struct thread *, struct freebsd32_pwrite_args *);
     int	freebsd32_mmap(struct thread *, struct freebsd32_mmap_args *);
     int	freebsd32_lseek(struct thread *, struct freebsd32_lseek_args *);
     int	freebsd32_truncate(struct thread *, struct freebsd32_truncate_args *);
     int	freebsd32_ftruncate(struct thread *, struct freebsd32_ftruncate_args *);
    +#else
    +int	freebsd32_pread(struct thread *, struct freebsd32_pread_args *);
    +int	freebsd32_pwrite(struct thread *, struct freebsd32_pwrite_args *);
    +int	freebsd32_mmap(struct thread *, struct freebsd32_mmap_args *);
    +int	freebsd32_lseek(struct thread *, struct freebsd32_lseek_args *);
    +int	freebsd32_truncate(struct thread *, struct freebsd32_truncate_args *);
    +int	freebsd32_ftruncate(struct thread *, struct freebsd32_ftruncate_args *);
    +#endif
    +#ifdef PAD64_REQUIRED
     int	freebsd32_cpuset_setid(struct thread *, struct freebsd32_cpuset_setid_args *);
    +#else
    +int	freebsd32_cpuset_setid(struct thread *, struct freebsd32_cpuset_setid_args *);
    +#endif
     int	freebsd32_cpuset_getid(struct thread *, struct freebsd32_cpuset_getid_args *);
     int	freebsd32_cpuset_getaffinity(struct thread *, struct freebsd32_cpuset_getaffinity_args *);
     int	freebsd32_cpuset_setaffinity(struct thread *, struct freebsd32_cpuset_setaffinity_args *);
    @@ -548,6 +627,9 @@ int	freebsd32_pselect(struct thread *, struct freebsd32_pselect_args *);
     
     #ifdef COMPAT_43
     
    +#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
    +#define PAD64_REQUIRED
    +#endif
     struct ofreebsd32_sigaction_args {
     	char signum_l_[PADL_(int)]; int signum; char signum_r_[PADR_(int)];
     	char nsa_l_[PADL_(struct osigaction32 *)]; struct osigaction32 * nsa; char nsa_r_[PADR_(struct osigaction32 *)];
    @@ -575,6 +657,12 @@ struct ofreebsd32_sigstack_args {
     	char nss_l_[PADL_(struct sigstack32 *)]; struct sigstack32 * nss; char nss_r_[PADR_(struct sigstack32 *)];
     	char oss_l_[PADL_(struct sigstack32 *)]; struct sigstack32 * oss; char oss_r_[PADR_(struct sigstack32 *)];
     };
    +#ifdef PAD64_REQUIRED
    +#else
    +#endif
    +#ifdef PAD64_REQUIRED
    +#else
    +#endif
     int	ofreebsd32_sigaction(struct thread *, struct ofreebsd32_sigaction_args *);
     int	ofreebsd32_sigprocmask(struct thread *, struct ofreebsd32_sigprocmask_args *);
     int	ofreebsd32_sigpending(struct thread *, struct ofreebsd32_sigpending_args *);
    @@ -589,6 +677,9 @@ int	ofreebsd32_sigstack(struct thread *, struct ofreebsd32_sigstack_args *);
     
     #ifdef COMPAT_FREEBSD4
     
    +#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
    +#define PAD64_REQUIRED
    +#endif
     struct freebsd4_freebsd32_getfsstat_args {
     	char buf_l_[PADL_(struct statfs32 *)]; struct statfs32 * buf; char buf_r_[PADR_(struct statfs32 *)];
     	char bufsize_l_[PADL_(long)]; long bufsize; char bufsize_r_[PADR_(long)];
    @@ -609,8 +700,8 @@ struct freebsd4_freebsd32_fhstatfs_args {
     struct freebsd4_freebsd32_sendfile_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
    -	char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
    -	char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     	char nbytes_l_[PADL_(size_t)]; size_t nbytes; char nbytes_r_[PADR_(size_t)];
     	char hdtr_l_[PADL_(struct sf_hdtr32 *)]; struct sf_hdtr32 * hdtr; char hdtr_r_[PADR_(struct sf_hdtr32 *)];
     	char sbytes_l_[PADL_(off_t *)]; off_t * sbytes; char sbytes_r_[PADR_(off_t *)];
    @@ -624,6 +715,12 @@ struct freebsd4_freebsd32_sigaction_args {
     struct freebsd4_freebsd32_sigreturn_args {
     	char sigcntxp_l_[PADL_(const struct freebsd4_freebsd32_ucontext *)]; const struct freebsd4_freebsd32_ucontext * sigcntxp; char sigcntxp_r_[PADR_(const struct freebsd4_freebsd32_ucontext *)];
     };
    +#ifdef PAD64_REQUIRED
    +#else
    +#endif
    +#ifdef PAD64_REQUIRED
    +#else
    +#endif
     int	freebsd4_freebsd32_getfsstat(struct thread *, struct freebsd4_freebsd32_getfsstat_args *);
     int	freebsd4_freebsd32_statfs(struct thread *, struct freebsd4_freebsd32_statfs_args *);
     int	freebsd4_freebsd32_fstatfs(struct thread *, struct freebsd4_freebsd32_fstatfs_args *);
    @@ -637,21 +734,24 @@ int	freebsd4_freebsd32_sigreturn(struct thread *, struct freebsd4_freebsd32_sigr
     
     #ifdef COMPAT_FREEBSD6
     
    +#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
    +#define PAD64_REQUIRED
    +#endif
     struct freebsd6_freebsd32_pread_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
     	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
     	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    -	char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
    -	char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     };
     struct freebsd6_freebsd32_pwrite_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
     	char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
     	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    -	char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
    -	char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     };
     struct freebsd6_freebsd32_mmap_args {
     	char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
    @@ -660,28 +760,34 @@ struct freebsd6_freebsd32_mmap_args {
     	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    -	char poslo_l_[PADL_(u_int32_t)]; u_int32_t poslo; char poslo_r_[PADR_(u_int32_t)];
    -	char poshi_l_[PADL_(u_int32_t)]; u_int32_t poshi; char poshi_r_[PADR_(u_int32_t)];
    +	char pos1_l_[PADL_(u_int32_t)]; u_int32_t pos1; char pos1_r_[PADR_(u_int32_t)];
    +	char pos2_l_[PADL_(u_int32_t)]; u_int32_t pos2; char pos2_r_[PADR_(u_int32_t)];
     };
     struct freebsd6_freebsd32_lseek_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    -	char offsetlo_l_[PADL_(u_int32_t)]; u_int32_t offsetlo; char offsetlo_r_[PADR_(u_int32_t)];
    -	char offsethi_l_[PADL_(u_int32_t)]; u_int32_t offsethi; char offsethi_r_[PADR_(u_int32_t)];
    +	char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
    +	char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
     	char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
     };
     struct freebsd6_freebsd32_truncate_args {
     	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
     	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    -	char lengthlo_l_[PADL_(u_int32_t)]; u_int32_t lengthlo; char lengthlo_r_[PADR_(u_int32_t)];
    -	char lengthhi_l_[PADL_(u_int32_t)]; u_int32_t lengthhi; char lengthhi_r_[PADR_(u_int32_t)];
    +	char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
    +	char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
     };
     struct freebsd6_freebsd32_ftruncate_args {
     	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
     	char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
    -	char lengthlo_l_[PADL_(u_int32_t)]; u_int32_t lengthlo; char lengthlo_r_[PADR_(u_int32_t)];
    -	char lengthhi_l_[PADL_(u_int32_t)]; u_int32_t lengthhi; char lengthhi_r_[PADR_(u_int32_t)];
    +	char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
    +	char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
     };
    +#ifdef PAD64_REQUIRED
    +#else
    +#endif
    +#ifdef PAD64_REQUIRED
    +#else
    +#endif
     int	freebsd6_freebsd32_pread(struct thread *, struct freebsd6_freebsd32_pread_args *);
     int	freebsd6_freebsd32_pwrite(struct thread *, struct freebsd6_freebsd32_pwrite_args *);
     int	freebsd6_freebsd32_mmap(struct thread *, struct freebsd6_freebsd32_mmap_args *);
    @@ -694,6 +800,9 @@ int	freebsd6_freebsd32_ftruncate(struct thread *, struct freebsd6_freebsd32_ftru
     
     #ifdef COMPAT_FREEBSD7
     
    +#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
    +#define PAD64_REQUIRED
    +#endif
     struct freebsd7_freebsd32_semctl_args {
     	char semid_l_[PADL_(int)]; int semid; char semid_r_[PADR_(int)];
     	char semnum_l_[PADL_(int)]; int semnum; char semnum_r_[PADR_(int)];
    @@ -710,6 +819,12 @@ struct freebsd7_freebsd32_shmctl_args {
     	char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)];
     	char buf_l_[PADL_(struct shmid_ds32_old *)]; struct shmid_ds32_old * buf; char buf_r_[PADR_(struct shmid_ds32_old *)];
     };
    +#ifdef PAD64_REQUIRED
    +#else
    +#endif
    +#ifdef PAD64_REQUIRED
    +#else
    +#endif
     int	freebsd7_freebsd32_semctl(struct thread *, struct freebsd7_freebsd32_semctl_args *);
     int	freebsd7_freebsd32_msgctl(struct thread *, struct freebsd7_freebsd32_msgctl_args *);
     int	freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_args *);
    @@ -811,6 +926,13 @@ int	freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_
     #define	FREEBSD32_SYS_AUE_freebsd32_lseek	AUE_LSEEK
     #define	FREEBSD32_SYS_AUE_freebsd32_truncate	AUE_TRUNCATE
     #define	FREEBSD32_SYS_AUE_freebsd32_ftruncate	AUE_FTRUNCATE
    +#define	FREEBSD32_SYS_AUE_freebsd32_pread	AUE_PREAD
    +#define	FREEBSD32_SYS_AUE_freebsd32_pwrite	AUE_PWRITE
    +#define	FREEBSD32_SYS_AUE_freebsd32_mmap	AUE_MMAP
    +#define	FREEBSD32_SYS_AUE_freebsd32_lseek	AUE_LSEEK
    +#define	FREEBSD32_SYS_AUE_freebsd32_truncate	AUE_TRUNCATE
    +#define	FREEBSD32_SYS_AUE_freebsd32_ftruncate	AUE_FTRUNCATE
    +#define	FREEBSD32_SYS_AUE_freebsd32_cpuset_setid	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_cpuset_setid	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_cpuset_getid	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_cpuset_getaffinity	AUE_NULL
    diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h
    index dfa1f5c5509..a7cd7a00e71 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: stable/8/sys/compat/freebsd32/syscalls.master 200725 2009-12-19 11:47:00Z kib 
    + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 206336 2010-04-07 02:24:41Z nwhitehorn 
      */
     
     #define	FREEBSD32_SYS_syscall	0
    @@ -354,11 +354,18 @@
     #define	FREEBSD32_SYS_freebsd32_lseek	478
     #define	FREEBSD32_SYS_freebsd32_truncate	479
     #define	FREEBSD32_SYS_freebsd32_ftruncate	480
    +#define	FREEBSD32_SYS_freebsd32_pread	475
    +#define	FREEBSD32_SYS_freebsd32_pwrite	476
    +#define	FREEBSD32_SYS_freebsd32_mmap	477
    +#define	FREEBSD32_SYS_freebsd32_lseek	478
    +#define	FREEBSD32_SYS_freebsd32_truncate	479
    +#define	FREEBSD32_SYS_freebsd32_ftruncate	480
     #define	FREEBSD32_SYS_thr_kill2	481
     #define	FREEBSD32_SYS_shm_open	482
     #define	FREEBSD32_SYS_shm_unlink	483
     #define	FREEBSD32_SYS_cpuset	484
     #define	FREEBSD32_SYS_freebsd32_cpuset_setid	485
    +#define	FREEBSD32_SYS_freebsd32_cpuset_setid	485
     #define	FREEBSD32_SYS_freebsd32_cpuset_getid	486
     #define	FREEBSD32_SYS_freebsd32_cpuset_getaffinity	487
     #define	FREEBSD32_SYS_freebsd32_cpuset_setaffinity	488
    diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c
    index c823c048a65..07aad20e0bf 100644
    --- a/sys/compat/freebsd32/freebsd32_syscalls.c
    +++ b/sys/compat/freebsd32/freebsd32_syscalls.c
    @@ -3,10 +3,13 @@
      *
      * DO NOT EDIT-- this file is automatically generated.
      * $FreeBSD$
    - * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 200725 2009-12-19 11:47:00Z kib 
    + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 206336 2010-04-07 02:24:41Z nwhitehorn 
      */
     
     const char *freebsd32_syscallnames[] = {
    +#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
    +#define PAD64_REQUIRED
    +#endif
     	"syscall",			/* 0 = syscall */
     	"exit",			/* 1 = exit */
     	"fork",			/* 2 = fork */
    @@ -482,17 +485,30 @@ const char *freebsd32_syscallnames[] = {
     	"sctp_generic_sendmsg",			/* 472 = sctp_generic_sendmsg */
     	"sctp_generic_sendmsg_iov",			/* 473 = sctp_generic_sendmsg_iov */
     	"sctp_generic_recvmsg",			/* 474 = sctp_generic_recvmsg */
    +#ifdef PAD64_REQUIRED
     	"freebsd32_pread",			/* 475 = freebsd32_pread */
     	"freebsd32_pwrite",			/* 476 = freebsd32_pwrite */
     	"freebsd32_mmap",			/* 477 = freebsd32_mmap */
     	"freebsd32_lseek",			/* 478 = freebsd32_lseek */
     	"freebsd32_truncate",			/* 479 = freebsd32_truncate */
     	"freebsd32_ftruncate",			/* 480 = freebsd32_ftruncate */
    +#else
    +	"freebsd32_pread",			/* 475 = freebsd32_pread */
    +	"freebsd32_pwrite",			/* 476 = freebsd32_pwrite */
    +	"freebsd32_mmap",			/* 477 = freebsd32_mmap */
    +	"freebsd32_lseek",			/* 478 = freebsd32_lseek */
    +	"freebsd32_truncate",			/* 479 = freebsd32_truncate */
    +	"freebsd32_ftruncate",			/* 480 = freebsd32_ftruncate */
    +#endif
     	"thr_kill2",			/* 481 = thr_kill2 */
     	"shm_open",			/* 482 = shm_open */
     	"shm_unlink",			/* 483 = shm_unlink */
     	"cpuset",			/* 484 = cpuset */
    +#ifdef PAD64_REQUIRED
     	"freebsd32_cpuset_setid",			/* 485 = freebsd32_cpuset_setid */
    +#else
    +	"freebsd32_cpuset_setid",			/* 485 = freebsd32_cpuset_setid */
    +#endif
     	"freebsd32_cpuset_getid",			/* 486 = freebsd32_cpuset_getid */
     	"freebsd32_cpuset_getaffinity",			/* 487 = freebsd32_cpuset_getaffinity */
     	"freebsd32_cpuset_setaffinity",			/* 488 = freebsd32_cpuset_setaffinity */
    diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c
    index c82cec852fb..6735d523a33 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: stable/8/sys/compat/freebsd32/syscalls.master 200725 2009-12-19 11:47:00Z kib 
    + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 206336 2010-04-07 02:24:41Z nwhitehorn 
      */
     
     #include "opt_compat.h"
    @@ -44,6 +44,9 @@
     
     /* The casts are bogus but will do for now. */
     struct sysent freebsd32_sysent[] = {
    +#if !defined(PAD64_REQUIRED) && defined(__powerpc__)
    +#define PAD64_REQUIRED
    +#endif
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },		/* 0 = syscall */
     	{ AS(sys_exit_args), (sy_call_t *)sys_exit, AUE_EXIT, NULL, 0, 0, 0 },	/* 1 = exit */
     	{ 0, (sy_call_t *)fork, AUE_FORK, NULL, 0, 0, 0 },		/* 2 = fork */
    @@ -519,17 +522,30 @@ struct sysent freebsd32_sysent[] = {
     	{ AS(sctp_generic_sendmsg_args), (sy_call_t *)sctp_generic_sendmsg, AUE_NULL, NULL, 0, 0, 0 },	/* 472 = sctp_generic_sendmsg */
     	{ AS(sctp_generic_sendmsg_iov_args), (sy_call_t *)sctp_generic_sendmsg_iov, AUE_NULL, NULL, 0, 0, 0 },	/* 473 = sctp_generic_sendmsg_iov */
     	{ AS(sctp_generic_recvmsg_args), (sy_call_t *)sctp_generic_recvmsg, AUE_NULL, NULL, 0, 0, 0 },	/* 474 = sctp_generic_recvmsg */
    +#ifdef PAD64_REQUIRED
     	{ AS(freebsd32_pread_args), (sy_call_t *)freebsd32_pread, AUE_PREAD, NULL, 0, 0, 0 },	/* 475 = freebsd32_pread */
     	{ AS(freebsd32_pwrite_args), (sy_call_t *)freebsd32_pwrite, AUE_PWRITE, NULL, 0, 0, 0 },	/* 476 = freebsd32_pwrite */
     	{ AS(freebsd32_mmap_args), (sy_call_t *)freebsd32_mmap, AUE_MMAP, NULL, 0, 0, 0 },	/* 477 = freebsd32_mmap */
     	{ AS(freebsd32_lseek_args), (sy_call_t *)freebsd32_lseek, AUE_LSEEK, NULL, 0, 0, 0 },	/* 478 = freebsd32_lseek */
     	{ AS(freebsd32_truncate_args), (sy_call_t *)freebsd32_truncate, AUE_TRUNCATE, NULL, 0, 0, 0 },	/* 479 = freebsd32_truncate */
     	{ AS(freebsd32_ftruncate_args), (sy_call_t *)freebsd32_ftruncate, AUE_FTRUNCATE, NULL, 0, 0, 0 },	/* 480 = freebsd32_ftruncate */
    +#else
    +	{ AS(freebsd32_pread_args), (sy_call_t *)freebsd32_pread, AUE_PREAD, NULL, 0, 0, 0 },	/* 475 = freebsd32_pread */
    +	{ AS(freebsd32_pwrite_args), (sy_call_t *)freebsd32_pwrite, AUE_PWRITE, NULL, 0, 0, 0 },	/* 476 = freebsd32_pwrite */
    +	{ AS(freebsd32_mmap_args), (sy_call_t *)freebsd32_mmap, AUE_MMAP, NULL, 0, 0, 0 },	/* 477 = freebsd32_mmap */
    +	{ AS(freebsd32_lseek_args), (sy_call_t *)freebsd32_lseek, AUE_LSEEK, NULL, 0, 0, 0 },	/* 478 = freebsd32_lseek */
    +	{ AS(freebsd32_truncate_args), (sy_call_t *)freebsd32_truncate, AUE_TRUNCATE, NULL, 0, 0, 0 },	/* 479 = freebsd32_truncate */
    +	{ AS(freebsd32_ftruncate_args), (sy_call_t *)freebsd32_ftruncate, AUE_FTRUNCATE, NULL, 0, 0, 0 },	/* 480 = freebsd32_ftruncate */
    +#endif
     	{ AS(thr_kill2_args), (sy_call_t *)thr_kill2, AUE_KILL, NULL, 0, 0, 0 },	/* 481 = thr_kill2 */
     	{ AS(shm_open_args), (sy_call_t *)shm_open, AUE_SHMOPEN, NULL, 0, 0, 0 },	/* 482 = shm_open */
     	{ AS(shm_unlink_args), (sy_call_t *)shm_unlink, AUE_SHMUNLINK, NULL, 0, 0, 0 },	/* 483 = shm_unlink */
     	{ AS(cpuset_args), (sy_call_t *)cpuset, AUE_NULL, NULL, 0, 0, 0 },	/* 484 = cpuset */
    +#ifdef PAD64_REQUIRED
     	{ AS(freebsd32_cpuset_setid_args), (sy_call_t *)freebsd32_cpuset_setid, AUE_NULL, NULL, 0, 0, 0 },	/* 485 = freebsd32_cpuset_setid */
    +#else
    +	{ AS(freebsd32_cpuset_setid_args), (sy_call_t *)freebsd32_cpuset_setid, AUE_NULL, NULL, 0, 0, 0 },	/* 485 = freebsd32_cpuset_setid */
    +#endif
     	{ AS(freebsd32_cpuset_getid_args), (sy_call_t *)freebsd32_cpuset_getid, AUE_NULL, NULL, 0, 0, 0 },	/* 486 = freebsd32_cpuset_getid */
     	{ AS(freebsd32_cpuset_getaffinity_args), (sy_call_t *)freebsd32_cpuset_getaffinity, AUE_NULL, NULL, 0, 0, 0 },	/* 487 = freebsd32_cpuset_getaffinity */
     	{ AS(freebsd32_cpuset_setaffinity_args), (sy_call_t *)freebsd32_cpuset_setaffinity, AUE_NULL, NULL, 0, 0, 0 },	/* 488 = freebsd32_cpuset_setaffinity */
    
    From 7b3c0af43e160b0174e910d2ffddd2ebb25fb16a Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Wed, 7 Apr 2010 12:42:49 +0000
    Subject: [PATCH 1896/2592] fix breakage in ipfw removal.
    
    ---
     sys/netinet/ipfw/ip_fw_sockopt.c | 154 +++++++++++++++++++------------
     1 file changed, 97 insertions(+), 57 deletions(-)
    
    diff --git a/sys/netinet/ipfw/ip_fw_sockopt.c b/sys/netinet/ipfw/ip_fw_sockopt.c
    index 5f203eae6c6..de7bfbe560f 100644
    --- a/sys/netinet/ipfw/ip_fw_sockopt.c
    +++ b/sys/netinet/ipfw/ip_fw_sockopt.c
    @@ -232,12 +232,49 @@ ipfw_reap_rules(struct ip_fw *head)
     	}
     }
     
    +/*
    + * Used by del_entry() to check if a rule should be kept.
    + * Returns 1 if the rule must be kept, 0 otherwise.
    + *
    + * Called with cmd = {0,1,5}.
    + * cmd == 0 matches on rule numbers, excludes rules in RESVD_SET if n == 0 ;
    + * cmd == 1 matches on set numbers only, rule numbers are ignored;
    + * cmd == 5 matches on rule and set numbers.
    + *
    + * n == 0 is a wildcard for rule numbers, there is no wildcard for sets.
    + *
    + * Rules to keep are
    + *	(default || reserved || !match_set || !match_number)
    + * where
    + *   default ::= (rule->rulenum == IPFW_DEFAULT_RULE)
    + *	// the default rule is always protected
    + *
    + *   reserved ::= (cmd == 0 && n == 0 && rule->set == RESVD_SET)
    + *	// RESVD_SET is protected only if cmd == 0 and n == 0 ("ipfw flush")
    + *
    + *   match_set ::= (cmd == 0 || rule->set == set)
    + *	// set number is ignored for cmd == 0
    + *
    + *   match_number ::= (cmd == 1 || n == 0 || n == rule->rulenum)
    + *	// number is ignored for cmd == 1 or n == 0
    + *
    + */
    +static int
    +keep_rule(struct ip_fw *rule, uint8_t cmd, uint8_t set, uint32_t n)
    +{
    +	return
    +		 (rule->rulenum == IPFW_DEFAULT_RULE)		||
    +		 (cmd == 0 && n == 0 && rule->set == RESVD_SET)	||
    +		!(cmd == 0 || rule->set == set)			||
    +		!(cmd == 1 || n == 0 || n == rule->rulenum);
    +}
    +
     /**
    - * Remove all rules with given number, and also do set manipulation.
    + * Remove all rules with given number, or do set manipulation.
      * Assumes chain != NULL && *chain != NULL.
      *
    - * The argument is an u_int32_t. The low 16 bit are the rule or set number,
    - * the next 8 bits are the new set, the top 8 bits are the command:
    + * The argument is an uint32_t. The low 16 bit are the rule or set number;
    + * the next 8 bits are the new set; the top 8 bits indicate the command:
      *
      *	0	delete rules numbered "rulenum"
      *	1	delete rules in set "rulenum"
    @@ -247,26 +284,26 @@ ipfw_reap_rules(struct ip_fw *head)
      *	5	delete rules "rulenum" and set "new_set"
      */
     static int
    -del_entry(struct ip_fw_chain *chain, u_int32_t arg)
    +del_entry(struct ip_fw_chain *chain, uint32_t arg)
     {
     	struct ip_fw *rule;
    -	uint32_t rulenum;	/* rule or old_set */
    +	uint32_t num;	/* rule number or old_set */
     	uint8_t cmd, new_set;
    -	int start, end = 0, i, ofs, n;
    +	int start, end, i, ofs, n;
     	struct ip_fw **map = NULL;
     	int error = 0;
     
    -	rulenum = arg & 0xffff;
    +	num = arg & 0xffff;
     	cmd = (arg >> 24) & 0xff;
     	new_set = (arg >> 16) & 0xff;
     
     	if (cmd > 5 || new_set > RESVD_SET)
     		return EINVAL;
     	if (cmd == 0 || cmd == 2 || cmd == 5) {
    -		if (rulenum >= IPFW_DEFAULT_RULE)
    +		if (num >= IPFW_DEFAULT_RULE)
     			return EINVAL;
     	} else {
    -		if (rulenum > RESVD_SET)	/* old_set */
    +		if (num > RESVD_SET)	/* old_set */
     			return EINVAL;
     	}
     
    @@ -274,20 +311,24 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg)
     	chain->reap = NULL;	/* prepare for deletions */
     
     	switch (cmd) {
    -	case 0:	/* delete rules "rulenum" (rulenum == 0 matches all) */
    +	case 0:	/* delete rules "num" (num == 0 matches all) */
     	case 1:	/* delete all rules in set N */
     	case 5: /* delete rules with number N and set "new_set". */
     
     		/*
     		 * Locate first rule to delete (start), the rule after
     		 * the last one to delete (end), and count how many
    -		 * rules to delete (n)
    +		 * rules to delete (n). Always use keep_rule() to
    +		 * determine which rules to keep.
     		 */
     		n = 0;
    -		if (cmd == 1) { /* look for a specific set, must scan all */
    -			new_set = rulenum;
    -			for (start = -1, i = 0; i < chain->n_rules; i++) {
    -				if (chain->map[i]->set != new_set)
    +		if (cmd == 1) {
    +			/* look for a specific set including RESVD_SET.
    +			 * Must scan the entire range, ignore num.
    +			 */
    +			new_set = num;
    +			for (start = -1, end = i = 0; i < chain->n_rules; i++) {
    +				if (keep_rule(chain->map[i], cmd, new_set, 0))
     					continue;
     				if (start < 0)
     					start = i;
    @@ -296,61 +337,54 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg)
     			}
     			end++;	/* first non-matching */
     		} else {
    -			start = ipfw_find_rule(chain, rulenum, 0);
    +			/* Optimized search on rule numbers */
    +			start = ipfw_find_rule(chain, num, 0);
     			for (end = start; end < chain->n_rules; end++) {
     				rule = chain->map[end];
    -				if (rulenum > 0 && rule->rulenum != rulenum)
    +				if (num > 0 && rule->rulenum != num)
     					break;
    -				if (rule->set != RESVD_SET &&
    -				    (cmd == 0 || rule->set == new_set) )
    +				if (!keep_rule(rule, cmd, new_set, num))
     					n++;
     			}
     		}
    -		if (n == 0 && arg == 0)
    -			break; /* special case, flush on empty ruleset */
    -		/* allocate the map, if needed */
    -		if (n > 0)
    +
    +		if (n == 0) {
    +			/* A flush request (arg == 0) on empty ruleset
    +			 * returns with no error. On the contrary,
    +			 * if there is no match on a specific request,
    +			 * we return EINVAL.
    +			 */
    +			error = (arg == 0) ? 0 : EINVAL;
    +			break;
    +		}
    +
    +		/* We have something to delete. Allocate the new map */
     			map = get_map(chain, -n, 1 /* locked */);
    -		if (n == 0 || map == NULL) {
    +		if (map == NULL) {
     			error = EINVAL;
     			break;
     		}
    -		/*
    -		 * bcopy the initial part of the map, then individually
    -		 * copy all matching entries between start and end,
    -		 * and then bcopy the final part.
    -		 * Once we are done we can swap maps and clean up the
    -		 * deleted rules (unfortunately we need to repeat a
    -		 * convoluted test). Rules to keep are
    -		 *	(set == RESVD_SET || !match_set || !match_rule)
    -		 * where
    -		 *   match_set ::= (cmd == 0 || rule->set == new_set)
    -		 *   match_rule ::= (cmd == 1 || rule->rulenum == rulenum)
    -		 */
    +
    +		/* 1. bcopy the initial part of the map */
     		if (start > 0)
     			bcopy(chain->map, map, start * sizeof(struct ip_fw *));
    +		/* 2. copy active rules between start and end */
     		for (i = ofs = start; i < end; i++) {
     			rule = chain->map[i];
    -			if (rule->set == RESVD_SET ||
    -			    !(cmd == 0 || rule->set == new_set) ||
    -			    !(cmd == 1 || rule->rulenum == rulenum) ) {
    -				map[ofs++] = chain->map[i];
    -			}
    +			if (keep_rule(rule, cmd, new_set, num))
    +				map[ofs++] = rule;
     		}
    +		/* 3. copy the final part of the map */
     		bcopy(chain->map + end, map + ofs,
     			(chain->n_rules - end) * sizeof(struct ip_fw *));
    -
    +		/* 4. swap the maps (under BH_LOCK) */
     		map = swap_map(chain, map, chain->n_rules - n);
    -		/* now remove the rules deleted */
    +		/* 5. now remove the rules deleted from the old map */
     		for (i = start; i < end; i++) {
     			int l;
     			rule = map[i];
    -			/* same test as above */
    -			if (rule->set == RESVD_SET ||
    -			    !(cmd == 0 || rule->set == new_set) ||
    -			    !(cmd == 1 || rule->rulenum == rulenum) )
    +			if (keep_rule(rule, cmd, new_set, num))
     				continue;
    -
     			l = RULESIZE(rule);
     			chain->static_len -= l;
     			ipfw_remove_dyn_children(rule);
    @@ -359,32 +393,38 @@ del_entry(struct ip_fw_chain *chain, u_int32_t arg)
     		}
     		break;
     
    -	case 2:	/* move rules with given number to new set */
    -		for (i = 0; i < chain->n_rules; i++) {
    +	/*
    +	 * In the next 3 cases the loop stops at (n_rules - 1)
    +	 * because the default rule is never eligible..
    +	 */
    +
    +	case 2:	/* move rules with given RULE number to new set */
    +		for (i = 0; i < chain->n_rules - 1; i++) {
     			rule = chain->map[i];
    -			if (rule->rulenum == rulenum)
    +			if (rule->rulenum == num)
     				rule->set = new_set;
     		}
     		break;
     
    -	case 3: /* move rules with given set number to new set */
    -		for (i = 0; i < chain->n_rules; i++) {
    +	case 3: /* move rules with given SET number to new set */
    +		for (i = 0; i < chain->n_rules - 1; i++) {
     			rule = chain->map[i];
    -			if (rule->set == rulenum)
    +			if (rule->set == num)
     				rule->set = new_set;
     		}
     		break;
     
     	case 4: /* swap two sets */
    -		for (i = 0; i < chain->n_rules; i++) {
    +		for (i = 0; i < chain->n_rules - 1; i++) {
     			rule = chain->map[i];
    -			if (rule->set == rulenum)
    +			if (rule->set == num)
     				rule->set = new_set;
     			else if (rule->set == new_set)
    -				rule->set = rulenum;
    +				rule->set = num;
     		}
     		break;
     	}
    +
     	rule = chain->reap;
     	chain->reap = NULL;
     	IPFW_UH_WUNLOCK(chain);
    
    From 54d63d7b13c67f5eab462bd5f0309b89d7a355af Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Wed, 7 Apr 2010 13:18:58 +0000
    Subject: [PATCH 1897/2592] add priority scheduler.
    
    ---
     sys/conf/files                   |   3 +-
     sys/modules/dummynet/Makefile    |   1 +
     sys/netinet/ipfw/dn_sched_prio.c | 229 +++++++++++++++++++++++++++++++
     sys/netinet/ipfw/test/Makefile   |   3 +-
     4 files changed, 234 insertions(+), 2 deletions(-)
     create mode 100644 sys/netinet/ipfw/dn_sched_prio.c
    
    diff --git a/sys/conf/files b/sys/conf/files
    index 07614871e69..72f215a1eb3 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -2480,9 +2480,10 @@ netinet/in_rmx.c		optional inet
     netinet/ip_divert.c		optional inet ipdivert ipfirewall
     netinet/ipfw/dn_heap.c		optional inet dummynet
     netinet/ipfw/dn_sched_fifo.c	optional inet dummynet
    +netinet/ipfw/dn_sched_prio.c	optional inet dummynet 
    +netinet/ipfw/dn_sched_qfq.c	optional inet dummynet 
     netinet/ipfw/dn_sched_rr.c	optional inet dummynet
     netinet/ipfw/dn_sched_wf2q.c	optional inet dummynet 
    -netinet/ipfw/dn_sched_qfq.c	optional inet dummynet 
     netinet/ipfw/ip_dummynet.c	optional inet dummynet
     netinet/ipfw/ip_dn_io.c		optional inet dummynet
     netinet/ipfw/ip_dn_glue.c	optional inet dummynet
    diff --git a/sys/modules/dummynet/Makefile b/sys/modules/dummynet/Makefile
    index 0e22ca53570..cc09aadc6f5 100644
    --- a/sys/modules/dummynet/Makefile
    +++ b/sys/modules/dummynet/Makefile
    @@ -7,6 +7,7 @@ KMOD=   dummynet
     SRCS=   ip_dummynet.c
     SRCS+= ip_dn_glue.c ip_dn_io.c
     SRCS+= dn_heap.c dn_sched_fifo.c dn_sched_qfq.c dn_sched_rr.c dn_sched_wf2q.c
    +SRCS+= dn_sched_prio.c
     SRCS+=	opt_inet6.h
     
     .if !defined(KERNBUILDDIR)
    diff --git a/sys/netinet/ipfw/dn_sched_prio.c b/sys/netinet/ipfw/dn_sched_prio.c
    new file mode 100644
    index 00000000000..28f60062cfc
    --- /dev/null
    +++ b/sys/netinet/ipfw/dn_sched_prio.c
    @@ -0,0 +1,229 @@
    +/*
    + * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
    + * 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$
    + */
    +#ifdef _KERNEL
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 	/* IFNAMSIZ */
    +#include 
    +#include 		/* ipfw_rule_ref */
    +#include 	/* flow_id */
    +#include 
    +#include 
    +#include 
    +#include 
    +#else
    +#include 
    +#endif
    +
    +#define DN_SCHED_PRIO	5 //XXX
    +
    +#if !defined(_KERNEL) || !defined(__linux__)
    +#define test_bit(ix, pData)	((*pData) & (1<<(ix)))
    +#define __set_bit(ix, pData)	(*pData) |= (1<<(ix))
    +#define __clear_bit(ix, pData)	(*pData) &= ~(1<<(ix))
    +#endif
    +
    +#ifdef __MIPSEL__
    +#define __clear_bit(ix, pData)	(*pData) &= ~(1<<(ix))
    +#endif
    +
    +/* Size of the array of queues pointers. */
    +#define BITMAP_T	unsigned long
    +#define MAXPRIO		(sizeof(BITMAP_T) * 8)
    +
    +/*
    + * The scheduler instance contains an array of pointers to queues,
    + * one for each priority, and a bitmap listing backlogged queues.
    + */
    +struct prio_si {
    +	BITMAP_T bitmap;			/* array bitmap */
    +	struct dn_queue *q_array[MAXPRIO];	/* Array of queues pointers */
    +};
    +
    +/*
    + * If a queue with the same priority is already backlogged, use
    + * that one instead of the queue passed as argument.
    + */
    +static int 
    +prio_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
    +{
    +	struct prio_si *si = (struct prio_si *)(_si + 1);
    +	int prio = q->fs->fs.par[0];
    +
    +	if (test_bit(prio, &si->bitmap) == 0) {
    +		/* No queue with this priority, insert */
    +		__set_bit(prio, &si->bitmap);
    +		si->q_array[prio] = q;
    +	} else { /* use the existing queue */
    +		q = si->q_array[prio];
    +	}
    +	if (dn_enqueue(q, m, 0))
    +		return 1;
    +	return 0;
    +}
    +
    +/*
    + * Packets are dequeued only from the highest priority queue.
    + * The function ffs() return the lowest bit in the bitmap that rapresent
    + * the array index (-1) which contains the pointer to the highest priority
    + * queue.
    + * After the dequeue, if this queue become empty, it is index is removed
    + * from the bitmap.
    + * Scheduler is idle if the bitmap is empty
    + *
    + * NOTE: highest priority is 0, lowest is sched->max_prio_q
    + */
    +static struct mbuf *
    +prio_dequeue(struct dn_sch_inst *_si)
    +{
    +	struct prio_si *si = (struct prio_si *)(_si + 1);
    +	struct mbuf *m;
    +	struct dn_queue *q;
    +	int prio;
    +
    +	if (si->bitmap == 0) /* scheduler idle */
    +		return NULL;
    +
    +	prio = ffs(si->bitmap) - 1;
    +
    +	/* Take the highest priority queue in the scheduler */
    +	q = si->q_array[prio];
    +	// assert(q)
    +
    +	m = dn_dequeue(q);
    +	if (q->mq.head == NULL) {
    +		/* Queue is now empty, remove from scheduler
    +		 * and mark it
    +		 */
    +		si->q_array[prio] = NULL;
    +		__clear_bit(prio, &si->bitmap);
    +	}
    +	return m;
    +}
    +
    +static int
    +prio_new_sched(struct dn_sch_inst *_si)
    +{
    +	struct prio_si *si = (struct prio_si *)(_si + 1);
    +
    +	bzero(si->q_array, sizeof(si->q_array));
    +	si->bitmap = 0;
    +
    +	return 0;
    +}
    +
    +static int
    +prio_new_fsk(struct dn_fsk *fs)
    +{
    +	/* Check if the prioritiy is between 0 and MAXPRIO-1 */
    +	ipdn_bound_var(&fs->fs.par[0], 0, 0, MAXPRIO - 1, "PRIO priority");
    +	return 0;
    +}
    +
    +static int
    +prio_new_queue(struct dn_queue *q)
    +{
    +	struct prio_si *si = (struct prio_si *)(q->_si + 1);
    +	int prio = q->fs->fs.par[0];
    +	struct dn_queue *oldq;
    +
    +	q->ni.oid.subtype = DN_SCHED_PRIO;
    +
    +	if (q->mq.head == NULL)
    +		return 0;
    +
    +	/* Queue already full, must insert in the scheduler or append
    +	 * mbufs to existing queue. This partly duplicates prio_enqueue
    +	 */
    +	if (test_bit(prio, &si->bitmap) == 0) {
    +		/* No queue with this priority, insert */
    +		__set_bit(prio, &si->bitmap);
    +		si->q_array[prio] = q;
    +	} else if ( (oldq = si->q_array[prio]) != q) {
    +		/* must append to the existing queue.
    +		 * can simply append q->mq.head to q2->...
    +		 * and add the counters to those of q2
    +		 */
    +		oldq->mq.tail->m_nextpkt = q->mq.head;
    +		oldq->mq.tail = q->mq.tail;
    +		oldq->ni.length += q->ni.length;
    +		q->ni.length = 0;
    +		oldq->ni.len_bytes += q->ni.len_bytes;
    +		q->ni.len_bytes = 0;
    +		q->mq.tail = q->mq.head = NULL;
    +	}
    +	return 0;
    +}
    +
    +static int
    +prio_free_queue(struct dn_queue *q)
    +{
    +	int prio = q->fs->fs.par[0];
    +	struct prio_si *si = (struct prio_si *)(q->_si + 1);
    +
    +	if (si->q_array[prio] == q) {
    +		si->q_array[prio] = NULL;
    +		__clear_bit(prio, &si->bitmap);
    +	}
    +	return 0;
    +}
    +
    +
    +static struct dn_alg prio_desc = {
    +	_SI( .type = ) DN_SCHED_PRIO,
    +	_SI( .name = ) "PRIO",
    +	_SI( .flags = ) DN_MULTIQUEUE,
    +
    +	/* we need extra space in the si and the queue */
    +	_SI( .schk_datalen = ) 0,
    +	_SI( .si_datalen = ) sizeof(struct prio_si),
    +	_SI( .q_datalen = ) 0,
    +
    +	_SI( .enqueue = ) prio_enqueue,
    +	_SI( .dequeue = ) prio_dequeue,
    +
    +	_SI( .config = )  NULL,
    +	_SI( .destroy = )  NULL,
    +	_SI( .new_sched = ) prio_new_sched,
    +	_SI( .free_sched = ) NULL,
    +
    +	_SI( .new_fsk = ) prio_new_fsk,
    +	_SI( .free_fsk = )  NULL,
    +
    +	_SI( .new_queue = ) prio_new_queue,
    +	_SI( .free_queue = ) prio_free_queue,
    +};
    +
    +
    +DECLARE_DNSCHED_MODULE(dn_prio, &prio_desc);
    diff --git a/sys/netinet/ipfw/test/Makefile b/sys/netinet/ipfw/test/Makefile
    index bbeb94278ac..c556a4bf3d5 100644
    --- a/sys/netinet/ipfw/test/Makefile
    +++ b/sys/netinet/ipfw/test/Makefile
    @@ -6,9 +6,10 @@
     
     SCHED_SRCS = test_dn_sched.c
     SCHED_SRCS += dn_sched_fifo.c
    -SCHED_SRCS += dn_sched_wf2q.c
    +SCHED_SRCS += dn_sched_prio.c
     SCHED_SRCS += dn_sched_qfq.c
     SCHED_SRCS += dn_sched_rr.c
    +SCHED_SRCS += dn_sched_wf2q.c
     SCHED_SRCS += dn_heap.c
     SCHED_SRCS += main.c
     
    
    From 6283dea5ca4c4e279dc7434788ac3205fcfe0561 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:09:29 +0000
    Subject: [PATCH 1898/2592] MFC r205319: Make freebsd32_copyiniov() available
     outside of freebsd32_misc.
    
    ---
     sys/compat/freebsd32/freebsd32_misc.c | 2 +-
     sys/compat/freebsd32/freebsd32_util.h | 3 +++
     2 files changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
    index c20e5fbd226..56bd02ae1fa 100644
    --- a/sys/compat/freebsd32/freebsd32_misc.c
    +++ b/sys/compat/freebsd32/freebsd32_misc.c
    @@ -873,7 +873,7 @@ freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
     	return (error);
     }
     
    -static int
    +int
     freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
         int error)
     {
    diff --git a/sys/compat/freebsd32/freebsd32_util.h b/sys/compat/freebsd32/freebsd32_util.h
    index 5e5942b0930..1e52eda4b64 100644
    --- a/sys/compat/freebsd32/freebsd32_util.h
    +++ b/sys/compat/freebsd32/freebsd32_util.h
    @@ -84,5 +84,8 @@ int    syscall32_deregister(int *offset, struct sysent *old_sysent);
     int    syscall32_module_handler(struct module *mod, int what, void *arg);
     
     register_t *freebsd32_copyout_strings(struct image_params *imgp);
    +struct iovec32;
    +int	freebsd32_copyiniov(struct iovec32 *iovp, u_int iovcnt,
    +	    struct iovec **iov, int error);
     
     #endif /* !_COMPAT_FREEBSD32_FREEBSD32_UTIL_H_ */
    
    From 9fb7bf55841ffa941c8409364bedc218edc393bd Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:16:14 +0000
    Subject: [PATCH 1899/2592] MFC r205318: Properly handle compat32 calls to sctp
     generic sendmsd/recvmsg functions that take iov.
    
    ---
     sys/kern/uipc_syscalls.c | 23 +++++++++++++++++++----
     1 file changed, 19 insertions(+), 4 deletions(-)
    
    diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
    index 093107fad0f..761e4ebfddf 100644
    --- a/sys/kern/uipc_syscalls.c
    +++ b/sys/kern/uipc_syscalls.c
    @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -69,6 +70,9 @@ __FBSDID("$FreeBSD$");
     #ifdef KTRACE
     #include 
     #endif
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#endif
     
     #include 
     
    @@ -2513,7 +2517,13 @@ sctp_generic_sendmsg_iov(td, uap)
     	if (error)
     		goto sctp_bad1;
     
    -	error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
    +#ifdef COMPAT_FREEBSD32
    +	if (SV_CURPROC_FLAG(SV_ILP32))
    +		error = freebsd32_copyiniov((struct iovec32 *)uap->iov,
    +		    uap->iovlen, &iov, EMSGSIZE);
    +	else
    +#endif
    +		error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
     	if (error)
     		goto sctp_bad1;
     #ifdef KTRACE
    @@ -2615,10 +2625,15 @@ sctp_generic_recvmsg(td, uap)
     	if (error) {
     		return (error);
     	}
    -	error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
    -	if (error) {
    +#ifdef COMPAT_FREEBSD32
    +	if (SV_CURPROC_FLAG(SV_ILP32))
    +		error = freebsd32_copyiniov((struct iovec32 *)uap->iov,
    +		    uap->iovlen, &iov, EMSGSIZE);
    +	else
    +#endif
    +		error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
    +	if (error)
     		goto out1;
    -	}
     
     	so = fp->f_data;
     #ifdef MAC
    
    From ba4a8a92d13805a460980d127ac974f6b2a61e62 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:22:38 +0000
    Subject: [PATCH 1900/2592] MFC r205320: For SYSCALL_MODULE_HELPER, use
     "sys/" module name. For SYSCALL32_MODULE_HELPER, use
     "sys32/" module name. This avoids modules name conflict when
     compat32 syscall does not need shims.
    
    ---
     sys/compat/freebsd32/freebsd32_util.h | 2 +-
     sys/sys/sysent.h                      | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32_util.h b/sys/compat/freebsd32/freebsd32_util.h
    index 1e52eda4b64..8f9461248a4 100644
    --- a/sys/compat/freebsd32/freebsd32_util.h
    +++ b/sys/compat/freebsd32/freebsd32_util.h
    @@ -61,7 +61,7 @@ static struct syscall_module_data name##_syscall32_mod = {     \
     };                                                             \
                                                                    \
     static moduledata_t name##32_mod = {                           \
    -       #name,                                                  \
    +       "sys32/" #name,                                         \
            syscall32_module_handler,                               \
            &name##_syscall32_mod                                   \
     };                                                             \
    diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
    index f17f4f0345f..d4cc1a8d618 100644
    --- a/sys/sys/sysent.h
    +++ b/sys/sys/sysent.h
    @@ -149,7 +149,7 @@ static struct syscall_module_data name##_syscall_mod = {	\
     };								\
     								\
     static moduledata_t name##_mod = {				\
    -	#name,							\
    +	"sys/" #name,						\
     	syscall_module_handler,					\
     	&name##_syscall_mod					\
     };								\
    
    From 0272ddd8bb4cef0d682c0e99ca9212cdce506de9 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:28:47 +0000
    Subject: [PATCH 1901/2592] MFC r205321: Introduce SYSCALL_INIT_HELPER and
     SYSCALL32_INIT_HELPER macros and neccessary support functions to allow
     registering dynamically loaded syscalls from the MOD_LOAD handlers. Helpers
     handle registration failures semi-automatically.
    
    ---
     sys/compat/freebsd32/freebsd32_misc.c | 30 +++++++++++++++++++++++++++
     sys/compat/freebsd32/freebsd32_util.h | 11 ++++++++++
     sys/kern/kern_syscalls.c              | 30 +++++++++++++++++++++++++++
     sys/sys/sysent.h                      | 24 +++++++++++++++++++++
     4 files changed, 95 insertions(+)
    
    diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
    index 56bd02ae1fa..7a7dc2e3e72 100644
    --- a/sys/compat/freebsd32/freebsd32_misc.c
    +++ b/sys/compat/freebsd32/freebsd32_misc.c
    @@ -3084,6 +3084,36 @@ syscall32_module_handler(struct module *mod, int what, void *arg)
     	}
     }
     
    +int
    +syscall32_helper_register(struct syscall_helper_data *sd)
    +{
    +	struct syscall_helper_data *sd1;
    +	int error;
    +
    +	for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
    +		error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent,
    +		    &sd1->old_sysent);
    +		if (error != 0) {
    +			syscall32_helper_unregister(sd);
    +			return (error);
    +		}
    +		sd1->registered = 1;
    +	}
    +	return (0);
    +}
    +
    +int
    +syscall32_helper_unregister(struct syscall_helper_data *sd)
    +{
    +	struct syscall_helper_data *sd1;
    +
    +	for (sd1 = sd; sd1->registered != 0; sd1++) {
    +		syscall32_deregister(&sd1->syscall_no, &sd1->old_sysent);
    +		sd1->registered = 0;
    +	}
    +	return (0);
    +}
    +
     register_t *
     freebsd32_copyout_strings(struct image_params *imgp)
     {
    diff --git a/sys/compat/freebsd32/freebsd32_util.h b/sys/compat/freebsd32/freebsd32_util.h
    index 8f9461248a4..f5ccbf16e04 100644
    --- a/sys/compat/freebsd32/freebsd32_util.h
    +++ b/sys/compat/freebsd32/freebsd32_util.h
    @@ -78,10 +78,21 @@ SYSCALL32_MODULE(syscallname,                           \
         & syscallname##_syscall32, & syscallname##_sysent32,\
         NULL, NULL);
     
    +#define SYSCALL32_INIT_HELPER(syscallname) {			\
    +    .new_sysent = {						\
    +	.sy_narg = (sizeof(struct syscallname ## _args )	\
    +	    / sizeof(register_t)),				\
    +	.sy_call = (sy_call_t *)& syscallname,			\
    +    },								\
    +    .syscall_no = FREEBSD32_SYS_##syscallname			\
    +}
    +
     int    syscall32_register(int *offset, struct sysent *new_sysent,
     	    struct sysent *old_sysent);
     int    syscall32_deregister(int *offset, struct sysent *old_sysent);
     int    syscall32_module_handler(struct module *mod, int what, void *arg);
    +int    syscall32_helper_register(struct syscall_helper_data *sd);
    +int    syscall32_helper_unregister(struct syscall_helper_data *sd);
     
     register_t *freebsd32_copyout_strings(struct image_params *imgp);
     struct iovec32;
    diff --git a/sys/kern/kern_syscalls.c b/sys/kern/kern_syscalls.c
    index 077aedcc047..9cb7b68bd54 100644
    --- a/sys/kern/kern_syscalls.c
    +++ b/sys/kern/kern_syscalls.c
    @@ -135,3 +135,33 @@ syscall_module_handler(struct module *mod, int what, void *arg)
     	else
     		return (0);
     }
    +
    +int
    +syscall_helper_register(struct syscall_helper_data *sd)
    +{
    +	struct syscall_helper_data *sd1;
    +	int error;
    +
    +	for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
    +		error = syscall_register(&sd1->syscall_no, &sd1->new_sysent,
    +		    &sd1->old_sysent);
    +		if (error != 0) {
    +			syscall_helper_unregister(sd);
    +			return (error);
    +		}
    +		sd1->registered = 1;
    +	}
    +	return (0);
    +}
    +
    +int
    +syscall_helper_unregister(struct syscall_helper_data *sd)
    +{
    +	struct syscall_helper_data *sd1;
    +
    +	for (sd1 = sd; sd1->registered != 0; sd1++) {
    +		syscall_deregister(&sd1->syscall_no, &sd1->old_sysent);
    +		sd1->registered = 0;
    +	}
    +	return (0);
    +}
    diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
    index d4cc1a8d618..58ed73f3b59 100644
    --- a/sys/sys/sysent.h
    +++ b/sys/sys/sysent.h
    @@ -166,10 +166,34 @@ SYSCALL_MODULE(syscallname,					\
     	(sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmnosys &&	\
     	sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmressys)
     
    +/*
    + * Syscall registration helpers with resource allocation handling.
    + */
    +struct syscall_helper_data {
    +	struct sysent new_sysent;
    +	struct sysent old_sysent;
    +	int syscall_no;
    +	int registered;
    +};
    +#define SYSCALL_INIT_HELPER(syscallname) {			\
    +    .new_sysent = {						\
    +	.sy_narg = (sizeof(struct syscallname ## _args )	\
    +	    / sizeof(register_t)),				\
    +	.sy_call = (sy_call_t *)& syscallname,			\
    +	.sy_auevent = SYS_AUE_##syscallname			\
    +    },								\
    +    .syscall_no = SYS_##syscallname				\
    +}
    +#define SYSCALL_INIT_LAST {					\
    +    .syscall_no = NO_SYSCALL					\
    +}
    +
     int	syscall_register(int *offset, struct sysent *new_sysent,
     	    struct sysent *old_sysent);
     int	syscall_deregister(int *offset, struct sysent *old_sysent);
     int	syscall_module_handler(struct module *mod, int what, void *arg);
    +int	syscall_helper_register(struct syscall_helper_data *sd);
    +int	syscall_helper_unregister(struct syscall_helper_data *sd);
     
     /* Special purpose system call functions. */
     struct nosys_args;
    
    From 4ad2ce357aaf5518ebcdbe8e1cc8157915565da4 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:35:09 +0000
    Subject: [PATCH 1902/2592] MFC r205322: Move SysV IPC freebsd32 compat shims
     helpers from freebsd32_misc.c to sysv_ipc.c.
    
    ---
     sys/compat/freebsd32/freebsd32_ipc.h  |  8 ++++
     sys/compat/freebsd32/freebsd32_misc.c | 54 ----------------------
     sys/kern/sysv_ipc.c                   | 66 +++++++++++++++++++++++++++
     3 files changed, 74 insertions(+), 54 deletions(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32_ipc.h b/sys/compat/freebsd32/freebsd32_ipc.h
    index 2b07494e4cd..320a63f0c2d 100644
    --- a/sys/compat/freebsd32/freebsd32_ipc.h
    +++ b/sys/compat/freebsd32/freebsd32_ipc.h
    @@ -147,6 +147,14 @@ struct shmid_ds32_old {
     	int32_t		shm_ctime;
     	uint32_t	shm_internal;
     };
    +
    +void	freebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32,
    +	    struct ipc_perm *ip);
    +void	freebsd32_ipcperm_old_out(struct ipc_perm *ip,
    +	    struct ipc_perm32_old *ip32);
     #endif
     
    +void	freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip);
    +void	freebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32);
    +
     #endif /* !_COMPAT_FREEBSD32_FREEBSD32_IPC_H_ */
    diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
    index 7a7dc2e3e72..424bb94c709 100644
    --- a/sys/compat/freebsd32/freebsd32_misc.c
    +++ b/sys/compat/freebsd32/freebsd32_misc.c
    @@ -1400,60 +1400,6 @@ freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatf
     }
     #endif
     
    -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    -    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    -static void
    -freebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32, struct ipc_perm *ip)
    -{
    -
    -	CP(*ip32, *ip, cuid);
    -	CP(*ip32, *ip, cgid);
    -	CP(*ip32, *ip, uid);
    -	CP(*ip32, *ip, gid);
    -	CP(*ip32, *ip, mode);
    -	CP(*ip32, *ip, seq);
    -	CP(*ip32, *ip, key);
    -}
    -
    -static void
    -freebsd32_ipcperm_old_out(struct ipc_perm *ip, struct ipc_perm32_old *ip32)
    -{
    -
    -	CP(*ip, *ip32, cuid);
    -	CP(*ip, *ip32, cgid);
    -	CP(*ip, *ip32, uid);
    -	CP(*ip, *ip32, gid);
    -	CP(*ip, *ip32, mode);
    -	CP(*ip, *ip32, seq);
    -	CP(*ip, *ip32, key);
    -}
    -#endif
    -
    -static void
    -freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip)
    -{
    -
    -	CP(*ip32, *ip, cuid);
    -	CP(*ip32, *ip, cgid);
    -	CP(*ip32, *ip, uid);
    -	CP(*ip32, *ip, gid);
    -	CP(*ip32, *ip, mode);
    -	CP(*ip32, *ip, seq);
    -	CP(*ip32, *ip, key);
    -}
    -
    -static void
    -freebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32)
    -{
    -
    -	CP(*ip, *ip32, cuid);
    -	CP(*ip, *ip32, cgid);
    -	CP(*ip, *ip32, uid);
    -	CP(*ip, *ip32, gid);
    -	CP(*ip, *ip32, mode);
    -	CP(*ip, *ip32, seq);
    -	CP(*ip, *ip32, key);
    -}
     
     int
     freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
    diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c
    index d33fdb09920..e402cb5b01b 100644
    --- a/sys/kern/sysv_ipc.c
    +++ b/sys/kern/sysv_ipc.c
    @@ -178,3 +178,69 @@ ipcperm_new2old(struct ipc_perm *new, struct ipc_perm_old *old)
     	old->key = new->key;
     }
     #endif
    +
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +void
    +freebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32, struct ipc_perm *ip)
    +{
    +
    +	CP(*ip32, *ip, cuid);
    +	CP(*ip32, *ip, cgid);
    +	CP(*ip32, *ip, uid);
    +	CP(*ip32, *ip, gid);
    +	CP(*ip32, *ip, mode);
    +	CP(*ip32, *ip, seq);
    +	CP(*ip32, *ip, key);
    +}
    +
    +void
    +freebsd32_ipcperm_old_out(struct ipc_perm *ip, struct ipc_perm32_old *ip32)
    +{
    +
    +	CP(*ip, *ip32, cuid);
    +	CP(*ip, *ip32, cgid);
    +	CP(*ip, *ip32, uid);
    +	CP(*ip, *ip32, gid);
    +	CP(*ip, *ip32, mode);
    +	CP(*ip, *ip32, seq);
    +	CP(*ip, *ip32, key);
    +}
    +#endif
    +
    +void
    +freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip)
    +{
    +
    +	CP(*ip32, *ip, cuid);
    +	CP(*ip32, *ip, cgid);
    +	CP(*ip32, *ip, uid);
    +	CP(*ip32, *ip, gid);
    +	CP(*ip32, *ip, mode);
    +	CP(*ip32, *ip, seq);
    +	CP(*ip32, *ip, key);
    +}
    +
    +void
    +freebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32)
    +{
    +
    +	CP(*ip, *ip32, cuid);
    +	CP(*ip, *ip32, cgid);
    +	CP(*ip, *ip32, uid);
    +	CP(*ip, *ip32, gid);
    +	CP(*ip, *ip32, mode);
    +	CP(*ip, *ip32, seq);
    +	CP(*ip, *ip32, key);
    +}
    +#endif
    
    From db5805dded55edda51d866c4528a8b447f5870cb Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:46:28 +0000
    Subject: [PATCH 1903/2592] MFC r205323: Move SysV IPC freebsd32 compat shims
     from freebsd32_misc.c to corresponding sysv_{msg,sem,shm}.c files.
    
    Mark SysV IPC freebsd32 syscalls as NOSTD and add required
    SYSCALL_INIT_HELPER/SYSCALL32_INIT_HELPERs to provide auto
    register/unregister on module load.
    
    This makes COMPAT_FREEBSD32 functional with SysV IPC compiled and loaded
    as modules.
    ---
     sys/compat/freebsd32/freebsd32_misc.c | 530 --------------------------
     sys/compat/freebsd32/syscalls.master  |  39 +-
     sys/kern/sysv_msg.c                   | 220 ++++++++++-
     sys/kern/sysv_sem.c                   | 236 +++++++++++-
     sys/kern/sysv_shm.c                   | 295 +++++++++++++-
     5 files changed, 733 insertions(+), 587 deletions(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
    index 424bb94c709..ad83f1613d2 100644
    --- a/sys/compat/freebsd32/freebsd32_misc.c
    +++ b/sys/compat/freebsd32/freebsd32_misc.c
    @@ -1401,536 +1401,6 @@ freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatf
     #endif
     
     
    -int
    -freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
    -{
    -
    -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    -    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    -	switch (uap->which) {
    -	case 0:
    -		return (freebsd7_freebsd32_semctl(td,
    -		    (struct freebsd7_freebsd32_semctl_args *)&uap->a2));
    -	default:
    -		return (semsys(td, (struct semsys_args *)uap));
    -	}
    -#else
    -	return (nosys(td, NULL));
    -#endif
    -}
    -
    -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    -    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    -int
    -freebsd7_freebsd32_semctl(struct thread *td,
    -    struct freebsd7_freebsd32_semctl_args *uap)
    -{
    -	struct semid_ds32_old dsbuf32;
    -	struct semid_ds dsbuf;
    -	union semun semun;
    -	union semun32 arg;
    -	register_t rval;
    -	int error;
    -
    -	switch (uap->cmd) {
    -	case SEM_STAT:
    -	case IPC_SET:
    -	case IPC_STAT:
    -	case GETALL:
    -	case SETVAL:
    -	case SETALL:
    -		error = copyin(uap->arg, &arg, sizeof(arg));
    -		if (error)
    -			return (error);		
    -		break;
    -	}
    -
    -	switch (uap->cmd) {
    -	case SEM_STAT:
    -	case IPC_STAT:
    -		semun.buf = &dsbuf;
    -		break;
    -	case IPC_SET:
    -		error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
    -		if (error)
    -			return (error);
    -		freebsd32_ipcperm_old_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
    -		PTRIN_CP(dsbuf32, dsbuf, sem_base);
    -		CP(dsbuf32, dsbuf, sem_nsems);
    -		CP(dsbuf32, dsbuf, sem_otime);
    -		CP(dsbuf32, dsbuf, sem_ctime);
    -		semun.buf = &dsbuf;
    -		break;
    -	case GETALL:
    -	case SETALL:
    -		semun.array = PTRIN(arg.array);
    -		break;
    -	case SETVAL:
    -		semun.val = arg.val;
    -		break;
    -	}
    -
    -	error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
    -	    &rval);
    -	if (error)
    -		return (error);
    -
    -	switch (uap->cmd) {
    -	case SEM_STAT:
    -	case IPC_STAT:
    -		bzero(&dsbuf32, sizeof(dsbuf32));
    -		freebsd32_ipcperm_old_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
    -		PTROUT_CP(dsbuf, dsbuf32, sem_base);
    -		CP(dsbuf, dsbuf32, sem_nsems);
    -		CP(dsbuf, dsbuf32, sem_otime);
    -		CP(dsbuf, dsbuf32, sem_ctime);
    -		error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
    -		break;
    -	}
    -
    -	if (error == 0)
    -		td->td_retval[0] = rval;
    -	return (error);
    -}
    -#endif
    -
    -int
    -freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
    -{
    -	struct semid_ds32 dsbuf32;
    -	struct semid_ds dsbuf;
    -	union semun semun;
    -	union semun32 arg;
    -	register_t rval;
    -	int error;
    -
    -	switch (uap->cmd) {
    -	case SEM_STAT:
    -	case IPC_SET:
    -	case IPC_STAT:
    -	case GETALL:
    -	case SETVAL:
    -	case SETALL:
    -		error = copyin(uap->arg, &arg, sizeof(arg));
    -		if (error)
    -			return (error);		
    -		break;
    -	}
    -
    -	switch (uap->cmd) {
    -	case SEM_STAT:
    -	case IPC_STAT:
    -		semun.buf = &dsbuf;
    -		break;
    -	case IPC_SET:
    -		error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
    -		if (error)
    -			return (error);
    -		freebsd32_ipcperm_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
    -		PTRIN_CP(dsbuf32, dsbuf, sem_base);
    -		CP(dsbuf32, dsbuf, sem_nsems);
    -		CP(dsbuf32, dsbuf, sem_otime);
    -		CP(dsbuf32, dsbuf, sem_ctime);
    -		semun.buf = &dsbuf;
    -		break;
    -	case GETALL:
    -	case SETALL:
    -		semun.array = PTRIN(arg.array);
    -		break;
    -	case SETVAL:
    -		semun.val = arg.val;
    -		break;		
    -	}
    -
    -	error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
    -	    &rval);
    -	if (error)
    -		return (error);
    -
    -	switch (uap->cmd) {
    -	case SEM_STAT:
    -	case IPC_STAT:
    -		bzero(&dsbuf32, sizeof(dsbuf32));
    -		freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
    -		PTROUT_CP(dsbuf, dsbuf32, sem_base);
    -		CP(dsbuf, dsbuf32, sem_nsems);
    -		CP(dsbuf, dsbuf32, sem_otime);
    -		CP(dsbuf, dsbuf32, sem_ctime);
    -		error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
    -		break;
    -	}
    -
    -	if (error == 0)
    -		td->td_retval[0] = rval;
    -	return (error);
    -}
    -
    -int
    -freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
    -{
    -
    -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    -    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    -	switch (uap->which) {
    -	case 0:
    -		return (freebsd7_freebsd32_msgctl(td,
    -		    (struct freebsd7_freebsd32_msgctl_args *)&uap->a2));
    -	case 2:
    -		return (freebsd32_msgsnd(td,
    -		    (struct freebsd32_msgsnd_args *)&uap->a2));
    -	case 3:
    -		return (freebsd32_msgrcv(td,
    -		    (struct freebsd32_msgrcv_args *)&uap->a2));
    -	default:
    -		return (msgsys(td, (struct msgsys_args *)uap));
    -	}
    -#else
    -	return (nosys(td, NULL));
    -#endif
    -}
    -
    -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    -    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    -int
    -freebsd7_freebsd32_msgctl(struct thread *td,
    -    struct freebsd7_freebsd32_msgctl_args *uap)
    -{
    -	struct msqid_ds msqbuf;
    -	struct msqid_ds32_old msqbuf32;
    -	int error;
    -
    -	if (uap->cmd == IPC_SET) {
    -		error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
    -		if (error)
    -			return (error);
    -		freebsd32_ipcperm_old_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
    -		PTRIN_CP(msqbuf32, msqbuf, msg_first);
    -		PTRIN_CP(msqbuf32, msqbuf, msg_last);
    -		CP(msqbuf32, msqbuf, msg_cbytes);
    -		CP(msqbuf32, msqbuf, msg_qnum);
    -		CP(msqbuf32, msqbuf, msg_qbytes);
    -		CP(msqbuf32, msqbuf, msg_lspid);
    -		CP(msqbuf32, msqbuf, msg_lrpid);
    -		CP(msqbuf32, msqbuf, msg_stime);
    -		CP(msqbuf32, msqbuf, msg_rtime);
    -		CP(msqbuf32, msqbuf, msg_ctime);
    -	}
    -	error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
    -	if (error)
    -		return (error);
    -	if (uap->cmd == IPC_STAT) {
    -		bzero(&msqbuf32, sizeof(msqbuf32));
    -		freebsd32_ipcperm_old_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
    -		PTROUT_CP(msqbuf, msqbuf32, msg_first);
    -		PTROUT_CP(msqbuf, msqbuf32, msg_last);
    -		CP(msqbuf, msqbuf32, msg_cbytes);
    -		CP(msqbuf, msqbuf32, msg_qnum);
    -		CP(msqbuf, msqbuf32, msg_qbytes);
    -		CP(msqbuf, msqbuf32, msg_lspid);
    -		CP(msqbuf, msqbuf32, msg_lrpid);
    -		CP(msqbuf, msqbuf32, msg_stime);
    -		CP(msqbuf, msqbuf32, msg_rtime);
    -		CP(msqbuf, msqbuf32, msg_ctime);
    -		error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
    -	}
    -	return (error);
    -}
    -#endif
    -
    -int
    -freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
    -{
    -	struct msqid_ds msqbuf;
    -	struct msqid_ds32 msqbuf32;
    -	int error;
    -
    -	if (uap->cmd == IPC_SET) {
    -		error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
    -		if (error)
    -			return (error);
    -		freebsd32_ipcperm_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
    -		PTRIN_CP(msqbuf32, msqbuf, msg_first);
    -		PTRIN_CP(msqbuf32, msqbuf, msg_last);
    -		CP(msqbuf32, msqbuf, msg_cbytes);
    -		CP(msqbuf32, msqbuf, msg_qnum);
    -		CP(msqbuf32, msqbuf, msg_qbytes);
    -		CP(msqbuf32, msqbuf, msg_lspid);
    -		CP(msqbuf32, msqbuf, msg_lrpid);
    -		CP(msqbuf32, msqbuf, msg_stime);
    -		CP(msqbuf32, msqbuf, msg_rtime);
    -		CP(msqbuf32, msqbuf, msg_ctime);
    -	}
    -	error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
    -	if (error)
    -		return (error);
    -	if (uap->cmd == IPC_STAT) {
    -		freebsd32_ipcperm_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
    -		PTROUT_CP(msqbuf, msqbuf32, msg_first);
    -		PTROUT_CP(msqbuf, msqbuf32, msg_last);
    -		CP(msqbuf, msqbuf32, msg_cbytes);
    -		CP(msqbuf, msqbuf32, msg_qnum);
    -		CP(msqbuf, msqbuf32, msg_qbytes);
    -		CP(msqbuf, msqbuf32, msg_lspid);
    -		CP(msqbuf, msqbuf32, msg_lrpid);
    -		CP(msqbuf, msqbuf32, msg_stime);
    -		CP(msqbuf, msqbuf32, msg_rtime);
    -		CP(msqbuf, msqbuf32, msg_ctime);
    -		error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
    -	}
    -	return (error);
    -}
    -
    -int
    -freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
    -{
    -	const void *msgp;
    -	long mtype;
    -	int32_t mtype32;
    -	int error;
    -
    -	msgp = PTRIN(uap->msgp);
    -	if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
    -		return (error);
    -	mtype = mtype32;
    -	return (kern_msgsnd(td, uap->msqid,
    -	    (const char *)msgp + sizeof(mtype32),
    -	    uap->msgsz, uap->msgflg, mtype));
    -}
    -
    -int
    -freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
    -{
    -	void *msgp;
    -	long mtype;
    -	int32_t mtype32;
    -	int error;
    -
    -	msgp = PTRIN(uap->msgp);
    -	if ((error = kern_msgrcv(td, uap->msqid,
    -	    (char *)msgp + sizeof(mtype32), uap->msgsz,
    -	    uap->msgtyp, uap->msgflg, &mtype)) != 0)
    -		return (error);
    -	mtype32 = (int32_t)mtype;
    -	return (copyout(&mtype32, msgp, sizeof(mtype32)));
    -}
    -
    -int
    -freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
    -{
    -
    -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    -    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    -	switch (uap->which) {
    -	case 0:	{	/* shmat */
    -		struct shmat_args ap;
    -
    -		ap.shmid = uap->a2;
    -		ap.shmaddr = PTRIN(uap->a3);
    -		ap.shmflg = uap->a4;
    -		return (sysent[SYS_shmat].sy_call(td, &ap));
    -	}
    -	case 2: {	/* shmdt */
    -		struct shmdt_args ap;
    -
    -		ap.shmaddr = PTRIN(uap->a2);
    -		return (sysent[SYS_shmdt].sy_call(td, &ap));
    -	}
    -	case 3: {	/* shmget */
    -		struct shmget_args ap;
    -
    -		ap.key = uap->a2;
    -		ap.size = uap->a3;
    -		ap.shmflg = uap->a4;
    -		return (sysent[SYS_shmget].sy_call(td, &ap));
    -	}
    -	case 4: {	/* shmctl */
    -		struct freebsd7_freebsd32_shmctl_args ap;
    -
    -		ap.shmid = uap->a2;
    -		ap.cmd = uap->a3;
    -		ap.buf = PTRIN(uap->a4);
    -		return (freebsd7_freebsd32_shmctl(td, &ap));
    -	}
    -	case 1:		/* oshmctl */
    -	default:
    -		return (EINVAL);
    -	}
    -#else
    -	return (nosys(td, NULL));
    -#endif
    -}
    -
    -#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    -    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    -int
    -freebsd7_freebsd32_shmctl(struct thread *td,
    -    struct freebsd7_freebsd32_shmctl_args *uap)
    -{
    -	int error = 0;
    -	union {
    -		struct shmid_ds shmid_ds;
    -		struct shm_info shm_info;
    -		struct shminfo shminfo;
    -	} u;
    -	union {
    -		struct shmid_ds32_old shmid_ds32;
    -		struct shm_info32 shm_info32;
    -		struct shminfo32 shminfo32;
    -	} u32;
    -	size_t sz;
    -
    -	if (uap->cmd == IPC_SET) {
    -		if ((error = copyin(uap->buf, &u32.shmid_ds32,
    -		    sizeof(u32.shmid_ds32))))
    -			goto done;
    -		freebsd32_ipcperm_old_in(&u32.shmid_ds32.shm_perm,
    -		    &u.shmid_ds.shm_perm);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
    -	}
    -	
    -	error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
    -	if (error)
    -		goto done;
    -	
    -	/* Cases in which we need to copyout */
    -	switch (uap->cmd) {
    -	case IPC_INFO:
    -		CP(u.shminfo, u32.shminfo32, shmmax);
    -		CP(u.shminfo, u32.shminfo32, shmmin);
    -		CP(u.shminfo, u32.shminfo32, shmmni);
    -		CP(u.shminfo, u32.shminfo32, shmseg);
    -		CP(u.shminfo, u32.shminfo32, shmall);
    -		error = copyout(&u32.shminfo32, uap->buf,
    -		    sizeof(u32.shminfo32));
    -		break;
    -	case SHM_INFO:
    -		CP(u.shm_info, u32.shm_info32, used_ids);
    -		CP(u.shm_info, u32.shm_info32, shm_rss);
    -		CP(u.shm_info, u32.shm_info32, shm_tot);
    -		CP(u.shm_info, u32.shm_info32, shm_swp);
    -		CP(u.shm_info, u32.shm_info32, swap_attempts);
    -		CP(u.shm_info, u32.shm_info32, swap_successes);
    -		error = copyout(&u32.shm_info32, uap->buf,
    -		    sizeof(u32.shm_info32));
    -		break;
    -	case SHM_STAT:
    -	case IPC_STAT:
    -		freebsd32_ipcperm_old_out(&u.shmid_ds.shm_perm,
    -		    &u32.shmid_ds32.shm_perm);
    -		if (u.shmid_ds.shm_segsz > INT32_MAX)
    -			u32.shmid_ds32.shm_segsz = INT32_MAX;
    -		else
    -			CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
    -		u32.shmid_ds32.shm_internal = 0;
    -		error = copyout(&u32.shmid_ds32, uap->buf,
    -		    sizeof(u32.shmid_ds32));
    -		break;
    -	}
    -
    -done:
    -	if (error) {
    -		/* Invalidate the return value */
    -		td->td_retval[0] = -1;
    -	}
    -	return (error);
    -}
    -#endif
    -
    -int
    -freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
    -{
    -	int error = 0;
    -	union {
    -		struct shmid_ds shmid_ds;
    -		struct shm_info shm_info;
    -		struct shminfo shminfo;
    -	} u;
    -	union {
    -		struct shmid_ds32 shmid_ds32;
    -		struct shm_info32 shm_info32;
    -		struct shminfo32 shminfo32;
    -	} u32;
    -	size_t sz;
    -	
    -	if (uap->cmd == IPC_SET) {
    -		if ((error = copyin(uap->buf, &u32.shmid_ds32,
    -		    sizeof(u32.shmid_ds32))))
    -			goto done;
    -		freebsd32_ipcperm_in(&u32.shmid_ds32.shm_perm,
    -		    &u.shmid_ds.shm_perm);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
    -		CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
    -	}
    -	
    -	error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
    -	if (error)
    -		goto done;
    -	
    -	/* Cases in which we need to copyout */
    -	switch (uap->cmd) {
    -	case IPC_INFO:
    -		CP(u.shminfo, u32.shminfo32, shmmax);
    -		CP(u.shminfo, u32.shminfo32, shmmin);
    -		CP(u.shminfo, u32.shminfo32, shmmni);
    -		CP(u.shminfo, u32.shminfo32, shmseg);
    -		CP(u.shminfo, u32.shminfo32, shmall);
    -		error = copyout(&u32.shminfo32, uap->buf,
    -		    sizeof(u32.shminfo32));
    -		break;
    -	case SHM_INFO:
    -		CP(u.shm_info, u32.shm_info32, used_ids);
    -		CP(u.shm_info, u32.shm_info32, shm_rss);
    -		CP(u.shm_info, u32.shm_info32, shm_tot);
    -		CP(u.shm_info, u32.shm_info32, shm_swp);
    -		CP(u.shm_info, u32.shm_info32, swap_attempts);
    -		CP(u.shm_info, u32.shm_info32, swap_successes);
    -		error = copyout(&u32.shm_info32, uap->buf,
    -		    sizeof(u32.shm_info32));
    -		break;
    -	case SHM_STAT:
    -	case IPC_STAT:
    -		freebsd32_ipcperm_out(&u.shmid_ds.shm_perm,
    -		    &u32.shmid_ds32.shm_perm);
    -		if (u.shmid_ds.shm_segsz > INT32_MAX)
    -			u32.shmid_ds32.shm_segsz = INT32_MAX;
    -		else
    -			CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
    -		CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
    -		error = copyout(&u32.shmid_ds32, uap->buf,
    -		    sizeof(u32.shmid_ds32));
    -		break;
    -	}
    -
    -done:
    -	if (error) {
    -		/* Invalidate the return value */
    -		td->td_retval[0] = -1;
    -	}
    -	return (error);
    -}
    -
     int
     freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
     {
    diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
    index f6d9a6b6f34..ce7f3a0efe3 100644
    --- a/sys/compat/freebsd32/syscalls.master
    +++ b/sys/compat/freebsd32/syscalls.master
    @@ -310,11 +310,11 @@
     				    struct rtprio *rtp); }
     167	AUE_NULL	UNIMPL	nosys
     168	AUE_NULL	UNIMPL	nosys
    -169	AUE_SEMSYS	STD	{ int freebsd32_semsys(int which, int a2, \
    +169	AUE_SEMSYS	NOSTD	{ int freebsd32_semsys(int which, int a2, \
     				    int a3, int a4, int a5); }
    -170	AUE_MSGSYS	STD	{ int freebsd32_msgsys(int which, int a2, \
    +170	AUE_MSGSYS	NOSTD	{ int freebsd32_msgsys(int which, int a2, \
     				    int a3, int a4, int a5, int a6); }
    -171	AUE_SHMSYS	STD	{ int freebsd32_shmsys(uint32_t which, uint32_t a2, \
    +171	AUE_SHMSYS	NOSTD	{ int freebsd32_shmsys(uint32_t which, uint32_t a2, \
     				    uint32_t a3, uint32_t a4); }
     172	AUE_NULL	UNIMPL	nosys
     173	AUE_PREAD	COMPAT6	{ ssize_t freebsd32_pread(int fd, void *buf, \
    @@ -402,26 +402,29 @@
     ; The following were introduced with NetBSD/4.4Lite-2
     ; They are initialized by their respective modules/sysinits
     ; XXX PROBLEM!!
    -220	AUE_SEMCTL	COMPAT7	{ int freebsd32_semctl(int semid, int semnum, \
    +220	AUE_SEMCTL	COMPAT7|NOSTD	{ int freebsd32_semctl( \
    +				    int semid, int semnum, \
     				    int cmd, union semun32 *arg); }
    -221	AUE_SEMGET	NOPROTO	{ int semget(key_t key, int nsems, \
    +221	AUE_SEMGET	NOSTD|NOPROTO	{ int semget(key_t key, int nsems, \
     				    int semflg); }
    -222	AUE_SEMOP	NOPROTO	{ int semop(int semid, struct sembuf *sops, \
    -				    u_int nsops); }
    +222	AUE_SEMOP	NOSTD|NOPROTO	{ int semop(int semid, \
    +				    struct sembuf *sops, u_int nsops); }
     223	AUE_NULL	UNIMPL	semconfig
    -224	AUE_MSGCTL	COMPAT7	{ int freebsd32_msgctl(int msqid, int cmd, \
    +224	AUE_MSGCTL	COMPAT7|NOSTD	{ int freebsd32_msgctl( \
    +				    int msqid, int cmd, \
     				    struct msqid_ds32_old *buf); }
    -225	AUE_MSGGET	NOPROTO	{ int msgget(key_t key, int msgflg); }
    -226	AUE_MSGSND	STD	{ int freebsd32_msgsnd(int msqid, void *msgp, \
    +225	AUE_MSGGET	NOSTD|NOPROTO	{ int msgget(key_t key, int msgflg); }
    +226	AUE_MSGSND	NOSTD	{ int freebsd32_msgsnd(int msqid, void *msgp, \
     				    size_t msgsz, int msgflg); }
    -227	AUE_MSGRCV	STD	{ int freebsd32_msgrcv(int msqid, void *msgp, \
    +227	AUE_MSGRCV	NOSTD	{ int freebsd32_msgrcv(int msqid, void *msgp, \
     				    size_t msgsz, long msgtyp, int msgflg); }
    -228	AUE_SHMAT	NOPROTO	{ int shmat(int shmid, void *shmaddr, \
    +228	AUE_SHMAT	NOSTD|NOPROTO	{ int shmat(int shmid, void *shmaddr, \
     				    int shmflg); }
    -229	AUE_SHMCTL	COMPAT7	{ int freebsd32_shmctl(int shmid, int cmd, \
    +229	AUE_SHMCTL	COMPAT7|NOSTD	{ int freebsd32_shmctl( \
    +				    int shmid, int cmd, \
     				    struct shmid_ds32_old *buf); }
    -230	AUE_SHMDT	NOPROTO	{ int shmdt(void *shmaddr); }
    -231	AUE_SHMGET	NOPROTO	{ int shmget(key_t key, int size, \
    +230	AUE_SHMDT	NOSTD|NOPROTO	{ int shmdt(void *shmaddr); }
    +231	AUE_SHMGET	NOSTD|NOPROTO	{ int shmget(key_t key, int size, \
     				    int shmflg); }
     ;
     232	AUE_NULL	STD 	{ int freebsd32_clock_gettime(clockid_t clock_id, \
    @@ -926,11 +929,11 @@
     				    unsigned int iovcnt, int flags); }
     508	AUE_NULL	NOPROTO	{ int jail_remove(int jid); }
     509	AUE_CLOSEFROM	NOPROTO	{ int closefrom(int lowfd); }
    -510	AUE_SEMCTL	STD { int freebsd32_semctl(int semid, int semnum, \
    +510	AUE_SEMCTL	NOSTD { int freebsd32_semctl(int semid, int semnum, \
     				    int cmd, union semun32 *arg); }
    -511	AUE_MSGCTL	STD	{ int freebsd32_msgctl(int msqid, int cmd, \
    +511	AUE_MSGCTL	NOSTD	{ int freebsd32_msgctl(int msqid, int cmd, \
     				    struct msqid_ds32 *buf); }
    -512	AUE_SHMCTL	STD	{ int freebsd32_shmctl(int shmid, int cmd, \
    +512	AUE_SHMCTL	NOSTD	{ int freebsd32_shmctl(int shmid, int cmd, \
     				    struct shmid_ds32 *buf); }
     513	AUE_LPATHCONF	NOPROTO	{ int lpathconf(char *path, int name); }
     514	AUE_CAP_NEW	UNIMPL	cap_new
    diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c
    index c7c67d457ed..01d7f79214a 100644
    --- a/sys/kern/sysv_msg.c
    +++ b/sys/kern/sysv_msg.c
    @@ -74,7 +74,7 @@ __FBSDID("$FreeBSD$");
     
     static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
     
    -static void msginit(void);
    +static int msginit(void);
     static int msgunload(void);
     static int sysvmsg_modload(struct module *, int, void *);
     
    @@ -152,10 +152,45 @@ static struct msg *msghdrs;	/* MSGTQL msg headers */
     static struct msqid_kernel *msqids;	/* MSGMNI msqid_kernel struct's */
     static struct mtx msq_mtx;	/* global mutex for message queues. */
     
    -static void
    +static struct syscall_helper_data msg_syscalls[] = {
    +	SYSCALL_INIT_HELPER(msgctl),
    +	SYSCALL_INIT_HELPER(msgget),
    +	SYSCALL_INIT_HELPER(msgsnd),
    +	SYSCALL_INIT_HELPER(msgrcv),
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +	SYSCALL_INIT_HELPER(msgsys),
    +	SYSCALL_INIT_HELPER(freebsd7_msgctl),
    +#endif
    +	SYSCALL_INIT_LAST
    +};
    +
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +static struct syscall_helper_data msg32_syscalls[] = {
    +	SYSCALL32_INIT_HELPER(freebsd32_msgctl),
    +	SYSCALL32_INIT_HELPER(freebsd32_msgsnd),
    +	SYSCALL32_INIT_HELPER(freebsd32_msgrcv),
    +	SYSCALL32_INIT_HELPER(msgget),
    +	SYSCALL32_INIT_HELPER(freebsd32_msgsys),
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +	SYSCALL32_INIT_HELPER(freebsd7_freebsd32_msgctl),
    +#endif
    +	SYSCALL_INIT_LAST
    +};
    +#endif
    +
    +static int
     msginit()
     {
    -	register int i;
    +	int i, error;
     
     	TUNABLE_INT_FETCH("kern.ipc.msgseg", &msginfo.msgseg);
     	TUNABLE_INT_FETCH("kern.ipc.msgssz", &msginfo.msgssz);
    @@ -235,6 +270,16 @@ msginit()
     #endif
     	}
     	mtx_init(&msq_mtx, "msq", NULL, MTX_DEF);
    +
    +	error = syscall_helper_register(msg_syscalls);
    +	if (error != 0)
    +		return (error);
    +#ifdef COMPAT_FREEBSD32
    +	error = syscall32_helper_register(msg32_syscalls);
    +	if (error != 0)
    +		return (error);
    +#endif
    +	return (0);
     }
     
     static int
    @@ -246,6 +291,11 @@ msgunload()
     	int i;
     #endif
     
    +	syscall_helper_unregister(msg_syscalls);
    +#ifdef COMPAT_FREEBSD32
    +	syscall32_helper_unregister(msg32_syscalls);
    +#endif
    +
     	for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
     		/*
     		 * Look for an unallocated and unlocked msqid_ds.
    @@ -283,7 +333,9 @@ sysvmsg_modload(struct module *module, int cmd, void *arg)
     
     	switch (cmd) {
     	case MOD_LOAD:
    -		msginit();
    +		error = msginit();
    +		if (error != 0)
    +			msgunload();
     		break;
     	case MOD_UNLOAD:
     		error = msgunload();
    @@ -303,11 +355,6 @@ static moduledata_t sysvmsg_mod = {
     	NULL
     };
     
    -SYSCALL_MODULE_HELPER(msgctl);
    -SYSCALL_MODULE_HELPER(msgget);
    -SYSCALL_MODULE_HELPER(msgsnd);
    -SYSCALL_MODULE_HELPER(msgrcv);
    -
     DECLARE_MODULE(sysvmsg, sysvmsg_mod, SI_SUB_SYSV_MSG, SI_ORDER_FIRST);
     MODULE_VERSION(sysvmsg, 1);
     
    @@ -1257,10 +1304,159 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RDTUN, &msginfo.msgseg, 0,
     SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
         NULL, 0, sysctl_msqids, "", "Message queue IDs");
     
    +#ifdef COMPAT_FREEBSD32
    +int
    +freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
    +{
    +
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +	switch (uap->which) {
    +	case 0:
    +		return (freebsd7_freebsd32_msgctl(td,
    +		    (struct freebsd7_freebsd32_msgctl_args *)&uap->a2));
    +	case 2:
    +		return (freebsd32_msgsnd(td,
    +		    (struct freebsd32_msgsnd_args *)&uap->a2));
    +	case 3:
    +		return (freebsd32_msgrcv(td,
    +		    (struct freebsd32_msgrcv_args *)&uap->a2));
    +	default:
    +		return (msgsys(td, (struct msgsys_args *)uap));
    +	}
    +#else
    +	return (nosys(td, NULL));
    +#endif
    +}
    +
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +int
    +freebsd7_freebsd32_msgctl(struct thread *td,
    +    struct freebsd7_freebsd32_msgctl_args *uap)
    +{
    +	struct msqid_ds msqbuf;
    +	struct msqid_ds32_old msqbuf32;
    +	int error;
    +
    +	if (uap->cmd == IPC_SET) {
    +		error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
    +		if (error)
    +			return (error);
    +		freebsd32_ipcperm_old_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
    +		PTRIN_CP(msqbuf32, msqbuf, msg_first);
    +		PTRIN_CP(msqbuf32, msqbuf, msg_last);
    +		CP(msqbuf32, msqbuf, msg_cbytes);
    +		CP(msqbuf32, msqbuf, msg_qnum);
    +		CP(msqbuf32, msqbuf, msg_qbytes);
    +		CP(msqbuf32, msqbuf, msg_lspid);
    +		CP(msqbuf32, msqbuf, msg_lrpid);
    +		CP(msqbuf32, msqbuf, msg_stime);
    +		CP(msqbuf32, msqbuf, msg_rtime);
    +		CP(msqbuf32, msqbuf, msg_ctime);
    +	}
    +	error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
    +	if (error)
    +		return (error);
    +	if (uap->cmd == IPC_STAT) {
    +		bzero(&msqbuf32, sizeof(msqbuf32));
    +		freebsd32_ipcperm_old_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
    +		PTROUT_CP(msqbuf, msqbuf32, msg_first);
    +		PTROUT_CP(msqbuf, msqbuf32, msg_last);
    +		CP(msqbuf, msqbuf32, msg_cbytes);
    +		CP(msqbuf, msqbuf32, msg_qnum);
    +		CP(msqbuf, msqbuf32, msg_qbytes);
    +		CP(msqbuf, msqbuf32, msg_lspid);
    +		CP(msqbuf, msqbuf32, msg_lrpid);
    +		CP(msqbuf, msqbuf32, msg_stime);
    +		CP(msqbuf, msqbuf32, msg_rtime);
    +		CP(msqbuf, msqbuf32, msg_ctime);
    +		error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
    +	}
    +	return (error);
    +}
    +#endif
    +
    +int
    +freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
    +{
    +	struct msqid_ds msqbuf;
    +	struct msqid_ds32 msqbuf32;
    +	int error;
    +
    +	if (uap->cmd == IPC_SET) {
    +		error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
    +		if (error)
    +			return (error);
    +		freebsd32_ipcperm_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
    +		PTRIN_CP(msqbuf32, msqbuf, msg_first);
    +		PTRIN_CP(msqbuf32, msqbuf, msg_last);
    +		CP(msqbuf32, msqbuf, msg_cbytes);
    +		CP(msqbuf32, msqbuf, msg_qnum);
    +		CP(msqbuf32, msqbuf, msg_qbytes);
    +		CP(msqbuf32, msqbuf, msg_lspid);
    +		CP(msqbuf32, msqbuf, msg_lrpid);
    +		CP(msqbuf32, msqbuf, msg_stime);
    +		CP(msqbuf32, msqbuf, msg_rtime);
    +		CP(msqbuf32, msqbuf, msg_ctime);
    +	}
    +	error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
    +	if (error)
    +		return (error);
    +	if (uap->cmd == IPC_STAT) {
    +		freebsd32_ipcperm_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
    +		PTROUT_CP(msqbuf, msqbuf32, msg_first);
    +		PTROUT_CP(msqbuf, msqbuf32, msg_last);
    +		CP(msqbuf, msqbuf32, msg_cbytes);
    +		CP(msqbuf, msqbuf32, msg_qnum);
    +		CP(msqbuf, msqbuf32, msg_qbytes);
    +		CP(msqbuf, msqbuf32, msg_lspid);
    +		CP(msqbuf, msqbuf32, msg_lrpid);
    +		CP(msqbuf, msqbuf32, msg_stime);
    +		CP(msqbuf, msqbuf32, msg_rtime);
    +		CP(msqbuf, msqbuf32, msg_ctime);
    +		error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
    +	}
    +	return (error);
    +}
    +
    +int
    +freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
    +{
    +	const void *msgp;
    +	long mtype;
    +	int32_t mtype32;
    +	int error;
    +
    +	msgp = PTRIN(uap->msgp);
    +	if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
    +		return (error);
    +	mtype = mtype32;
    +	return (kern_msgsnd(td, uap->msqid,
    +	    (const char *)msgp + sizeof(mtype32),
    +	    uap->msgsz, uap->msgflg, mtype));
    +}
    +
    +int
    +freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
    +{
    +	void *msgp;
    +	long mtype;
    +	int32_t mtype32;
    +	int error;
    +
    +	msgp = PTRIN(uap->msgp);
    +	if ((error = kern_msgrcv(td, uap->msqid,
    +	    (char *)msgp + sizeof(mtype32), uap->msgsz,
    +	    uap->msgtyp, uap->msgflg, &mtype)) != 0)
    +		return (error);
    +	mtype32 = (int32_t)mtype;
    +	return (copyout(&mtype32, msgp, sizeof(mtype32)));
    +}
    +#endif
    +
     #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
         defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    -SYSCALL_MODULE_HELPER(msgsys);
    -SYSCALL_MODULE_HELPER(freebsd7_msgctl);
     
     /* XXX casting to (sy_call_t *) is bogus, as usual. */
     static sy_call_t *msgcalls[] = {
    @@ -1295,7 +1491,9 @@ msgsys(td, uap)
     	return (error);
     }
     
    +#ifndef CP
     #define CP(src, dst, fld)	do { (dst).fld = (src).fld; } while (0)
    +#endif
     
     #ifndef _SYS_SYSPROTO_H_
     struct freebsd7_msgctl_args {
    diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
    index 2f2b52833d3..f6d781c71e1 100644
    --- a/sys/kern/sysv_sem.c
    +++ b/sys/kern/sysv_sem.c
    @@ -70,7 +70,7 @@ static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
     #define DPRINTF(a)
     #endif
     
    -static void seminit(void);
    +static int seminit(void);
     static int sysvsem_modload(struct module *, int, void *);
     static int semunload(void);
     static void semexit_myhook(void *arg, struct proc *p);
    @@ -214,10 +214,43 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RW, &seminfo.semaem, 0,
     SYSCTL_PROC(_kern_ipc, OID_AUTO, sema, CTLFLAG_RD,
         NULL, 0, sysctl_sema, "", "");
     
    -static void
    +static struct syscall_helper_data sem_syscalls[] = {
    +	SYSCALL_INIT_HELPER(__semctl),
    +	SYSCALL_INIT_HELPER(semget),
    +	SYSCALL_INIT_HELPER(semop),
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +	SYSCALL_INIT_HELPER(semsys),
    +	SYSCALL_INIT_HELPER(freebsd7___semctl),
    +#endif
    +	SYSCALL_INIT_LAST
    +};
    +
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +static struct syscall_helper_data sem32_syscalls[] = {
    +	SYSCALL32_INIT_HELPER(freebsd32_semctl),
    +	SYSCALL32_INIT_HELPER(semget),
    +	SYSCALL32_INIT_HELPER(semop),
    +	SYSCALL32_INIT_HELPER(freebsd32_semsys),
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +	SYSCALL32_INIT_HELPER(freebsd7_freebsd32_semctl),
    +#endif
    +	SYSCALL_INIT_LAST
    +};
    +#endif
    +
    +static int
     seminit(void)
     {
    -	int i;
    +	int i, error;
     
     	TUNABLE_INT_FETCH("kern.ipc.semmap", &seminfo.semmap);
     	TUNABLE_INT_FETCH("kern.ipc.semmni", &seminfo.semmni);
    @@ -258,6 +291,16 @@ seminit(void)
     	mtx_init(&sem_undo_mtx, "semu", NULL, MTX_DEF);
     	semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
     	    EVENTHANDLER_PRI_ANY);
    +
    +	error = syscall_helper_register(sem_syscalls);
    +	if (error != 0)
    +		return (error);
    +#ifdef COMPAT_FREEBSD32
    +	error = syscall32_helper_register(sem32_syscalls);
    +	if (error != 0)
    +		return (error);
    +#endif
    +	return (0);
     }
     
     static int
    @@ -269,6 +312,10 @@ semunload(void)
     	if (semtot != 0)
     		return (EBUSY);
     
    +#ifdef COMPAT_FREEBSD32
    +	syscall32_helper_unregister(sem32_syscalls);
    +#endif
    +	syscall_helper_unregister(sem_syscalls);
     	EVENTHANDLER_DEREGISTER(process_exit, semexit_tag);
     #ifdef MAC
     	for (i = 0; i < seminfo.semmni; i++)
    @@ -292,7 +339,9 @@ sysvsem_modload(struct module *module, int cmd, void *arg)
     
     	switch (cmd) {
     	case MOD_LOAD:
    -		seminit();
    +		error = seminit();
    +		if (error != 0)
    +			semunload();
     		break;
     	case MOD_UNLOAD:
     		error = semunload();
    @@ -312,10 +361,6 @@ static moduledata_t sysvsem_mod = {
     	NULL
     };
     
    -SYSCALL_MODULE_HELPER(__semctl);
    -SYSCALL_MODULE_HELPER(semget);
    -SYSCALL_MODULE_HELPER(semop);
    -
     DECLARE_MODULE(sysvsem, sysvsem_mod, SI_SUB_SYSV_SEM, SI_ORDER_FIRST);
     MODULE_VERSION(sysvsem, 1);
     
    @@ -1316,8 +1361,6 @@ sysctl_sema(SYSCTL_HANDLER_ARGS)
     
     #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
         defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    -SYSCALL_MODULE_HELPER(semsys);
    -SYSCALL_MODULE_HELPER(freebsd7___semctl);
     
     /* XXX casting to (sy_call_t *) is bogus, as usual. */
     static sy_call_t *semcalls[] = {
    @@ -1351,7 +1394,9 @@ semsys(td, uap)
     	return (error);
     }
     
    +#ifndef CP
     #define CP(src, dst, fld)	do { (dst).fld = (src).fld; } while (0)
    +#endif
     
     #ifndef _SYS_SYSPROTO_H_
     struct freebsd7___semctl_args {
    @@ -1432,7 +1477,172 @@ freebsd7___semctl(struct thread *td, struct freebsd7___semctl_args *uap)
     	return (error);
     }
     
    -#undef CP
    +#endif /* COMPAT_FREEBSD{4,5,6,7} */
     
    -#endif	/* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
    -	   COMPAT_FREEBSD7 */
    +#ifdef COMPAT_FREEBSD32
    +
    +int
    +freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
    +{
    +
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +	switch (uap->which) {
    +	case 0:
    +		return (freebsd7_freebsd32_semctl(td,
    +		    (struct freebsd7_freebsd32_semctl_args *)&uap->a2));
    +	default:
    +		return (semsys(td, (struct semsys_args *)uap));
    +	}
    +#else
    +	return (nosys(td, NULL));
    +#endif
    +}
    +
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +int
    +freebsd7_freebsd32_semctl(struct thread *td,
    +    struct freebsd7_freebsd32_semctl_args *uap)
    +{
    +	struct semid_ds32_old dsbuf32;
    +	struct semid_ds dsbuf;
    +	union semun semun;
    +	union semun32 arg;
    +	register_t rval;
    +	int error;
    +
    +	switch (uap->cmd) {
    +	case SEM_STAT:
    +	case IPC_SET:
    +	case IPC_STAT:
    +	case GETALL:
    +	case SETVAL:
    +	case SETALL:
    +		error = copyin(uap->arg, &arg, sizeof(arg));
    +		if (error)
    +			return (error);		
    +		break;
    +	}
    +
    +	switch (uap->cmd) {
    +	case SEM_STAT:
    +	case IPC_STAT:
    +		semun.buf = &dsbuf;
    +		break;
    +	case IPC_SET:
    +		error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
    +		if (error)
    +			return (error);
    +		freebsd32_ipcperm_old_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
    +		PTRIN_CP(dsbuf32, dsbuf, sem_base);
    +		CP(dsbuf32, dsbuf, sem_nsems);
    +		CP(dsbuf32, dsbuf, sem_otime);
    +		CP(dsbuf32, dsbuf, sem_ctime);
    +		semun.buf = &dsbuf;
    +		break;
    +	case GETALL:
    +	case SETALL:
    +		semun.array = PTRIN(arg.array);
    +		break;
    +	case SETVAL:
    +		semun.val = arg.val;
    +		break;
    +	}
    +
    +	error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
    +	    &rval);
    +	if (error)
    +		return (error);
    +
    +	switch (uap->cmd) {
    +	case SEM_STAT:
    +	case IPC_STAT:
    +		bzero(&dsbuf32, sizeof(dsbuf32));
    +		freebsd32_ipcperm_old_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
    +		PTROUT_CP(dsbuf, dsbuf32, sem_base);
    +		CP(dsbuf, dsbuf32, sem_nsems);
    +		CP(dsbuf, dsbuf32, sem_otime);
    +		CP(dsbuf, dsbuf32, sem_ctime);
    +		error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
    +		break;
    +	}
    +
    +	if (error == 0)
    +		td->td_retval[0] = rval;
    +	return (error);
    +}
    +#endif
    +
    +int
    +freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
    +{
    +	struct semid_ds32 dsbuf32;
    +	struct semid_ds dsbuf;
    +	union semun semun;
    +	union semun32 arg;
    +	register_t rval;
    +	int error;
    +
    +	switch (uap->cmd) {
    +	case SEM_STAT:
    +	case IPC_SET:
    +	case IPC_STAT:
    +	case GETALL:
    +	case SETVAL:
    +	case SETALL:
    +		error = copyin(uap->arg, &arg, sizeof(arg));
    +		if (error)
    +			return (error);		
    +		break;
    +	}
    +
    +	switch (uap->cmd) {
    +	case SEM_STAT:
    +	case IPC_STAT:
    +		semun.buf = &dsbuf;
    +		break;
    +	case IPC_SET:
    +		error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
    +		if (error)
    +			return (error);
    +		freebsd32_ipcperm_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
    +		PTRIN_CP(dsbuf32, dsbuf, sem_base);
    +		CP(dsbuf32, dsbuf, sem_nsems);
    +		CP(dsbuf32, dsbuf, sem_otime);
    +		CP(dsbuf32, dsbuf, sem_ctime);
    +		semun.buf = &dsbuf;
    +		break;
    +	case GETALL:
    +	case SETALL:
    +		semun.array = PTRIN(arg.array);
    +		break;
    +	case SETVAL:
    +		semun.val = arg.val;
    +		break;		
    +	}
    +
    +	error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
    +	    &rval);
    +	if (error)
    +		return (error);
    +
    +	switch (uap->cmd) {
    +	case SEM_STAT:
    +	case IPC_STAT:
    +		bzero(&dsbuf32, sizeof(dsbuf32));
    +		freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
    +		PTROUT_CP(dsbuf, dsbuf32, sem_base);
    +		CP(dsbuf, dsbuf32, sem_nsems);
    +		CP(dsbuf, dsbuf32, sem_otime);
    +		CP(dsbuf, dsbuf32, sem_ctime);
    +		error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
    +		break;
    +	}
    +
    +	if (error == 0)
    +		td->td_retval[0] = rval;
    +	return (error);
    +}
    +
    +#endif /* COMPAT_FREEBSD32 */
    diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
    index 4e62211ebca..ea616ec718f 100644
    --- a/sys/kern/sysv_shm.c
    +++ b/sys/kern/sysv_shm.c
    @@ -122,7 +122,7 @@ static struct shmid_kernel *shm_find_segment_by_shmid(int);
     static struct shmid_kernel *shm_find_segment_by_shmidx(int);
     static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *);
     static void shmrealloc(void);
    -static void shminit(void);
    +static int shminit(void);
     static int sysvshm_modload(struct module *, int, void *);
     static int shmunload(void);
     static void shmexit_myhook(struct vmspace *vm);
    @@ -816,10 +816,47 @@ shmrealloc(void)
     	shmalloced = shminfo.shmmni;
     }
     
    -static void
    +static struct syscall_helper_data shm_syscalls[] = {
    +	SYSCALL_INIT_HELPER(shmat),
    +	SYSCALL_INIT_HELPER(shmctl),
    +	SYSCALL_INIT_HELPER(shmdt),
    +	SYSCALL_INIT_HELPER(shmget),
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +	SYSCALL_INIT_HELPER(freebsd7_shmctl),
    +#endif
    +#if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43))
    +	SYSCALL_INIT_HELPER(shmsys),
    +#endif
    +	SYSCALL_INIT_LAST
    +};
    +
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +static struct syscall_helper_data shm32_syscalls[] = {
    +	SYSCALL32_INIT_HELPER(shmat),
    +	SYSCALL32_INIT_HELPER(shmdt),
    +	SYSCALL32_INIT_HELPER(shmget),
    +	SYSCALL32_INIT_HELPER(freebsd32_shmsys),
    +	SYSCALL32_INIT_HELPER(freebsd32_shmctl),
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +	SYSCALL32_INIT_HELPER(freebsd7_freebsd32_shmctl),
    +#endif
    +	SYSCALL_INIT_LAST
    +};
    +#endif
    +
    +static int
     shminit()
     {
    -	int i;
    +	int i, error;
     
     	TUNABLE_ULONG_FETCH("kern.ipc.shmmaxpgs", &shminfo.shmall);
     	for (i = PAGE_SIZE; i > 0; i--) {
    @@ -848,6 +885,16 @@ shminit()
     	shm_committed = 0;
     	shmexit_hook = &shmexit_myhook;
     	shmfork_hook = &shmfork_myhook;
    +
    +	error = syscall_helper_register(shm_syscalls);
    +	if (error != 0)
    +		return (error);
    +#ifdef COMPAT_FREEBSD32
    +	error = syscall32_helper_register(shm32_syscalls);
    +	if (error != 0)
    +		return (error);
    +#endif
    +	return (0);
     }
     
     static int
    @@ -860,6 +907,11 @@ shmunload()
     	if (shm_nused > 0)
     		return (EBUSY);
     
    +#ifdef COMPAT_FREEBSD32
    +	syscall32_helper_unregister(shm32_syscalls);
    +#endif
    +	syscall_helper_unregister(shm_syscalls);
    +
     #ifdef MAC
     	for (i = 0; i < shmalloced; i++)
     		mac_sysvshm_destroy(&shmsegs[i]);
    @@ -978,14 +1030,234 @@ shmsys(td, uap)
     	return (error);
     }
     
    -SYSCALL_MODULE_HELPER(shmsys);
     #endif	/* i386 && (COMPAT_FREEBSD4 || COMPAT_43) */
     
    +#ifdef COMPAT_FREEBSD32
    +
    +int
    +freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
    +{
    +
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +	switch (uap->which) {
    +	case 0:	{	/* shmat */
    +		struct shmat_args ap;
    +
    +		ap.shmid = uap->a2;
    +		ap.shmaddr = PTRIN(uap->a3);
    +		ap.shmflg = uap->a4;
    +		return (sysent[SYS_shmat].sy_call(td, &ap));
    +	}
    +	case 2: {	/* shmdt */
    +		struct shmdt_args ap;
    +
    +		ap.shmaddr = PTRIN(uap->a2);
    +		return (sysent[SYS_shmdt].sy_call(td, &ap));
    +	}
    +	case 3: {	/* shmget */
    +		struct shmget_args ap;
    +
    +		ap.key = uap->a2;
    +		ap.size = uap->a3;
    +		ap.shmflg = uap->a4;
    +		return (sysent[SYS_shmget].sy_call(td, &ap));
    +	}
    +	case 4: {	/* shmctl */
    +		struct freebsd7_freebsd32_shmctl_args ap;
    +
    +		ap.shmid = uap->a2;
    +		ap.cmd = uap->a3;
    +		ap.buf = PTRIN(uap->a4);
    +		return (freebsd7_freebsd32_shmctl(td, &ap));
    +	}
    +	case 1:		/* oshmctl */
    +	default:
    +		return (EINVAL);
    +	}
    +#else
    +	return (nosys(td, NULL));
    +#endif
    +}
    +
    +#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
    +    defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
    +int
    +freebsd7_freebsd32_shmctl(struct thread *td,
    +    struct freebsd7_freebsd32_shmctl_args *uap)
    +{
    +	int error = 0;
    +	union {
    +		struct shmid_ds shmid_ds;
    +		struct shm_info shm_info;
    +		struct shminfo shminfo;
    +	} u;
    +	union {
    +		struct shmid_ds32_old shmid_ds32;
    +		struct shm_info32 shm_info32;
    +		struct shminfo32 shminfo32;
    +	} u32;
    +	size_t sz;
    +
    +	if (uap->cmd == IPC_SET) {
    +		if ((error = copyin(uap->buf, &u32.shmid_ds32,
    +		    sizeof(u32.shmid_ds32))))
    +			goto done;
    +		freebsd32_ipcperm_old_in(&u32.shmid_ds32.shm_perm,
    +		    &u.shmid_ds.shm_perm);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
    +	}
    +	
    +	error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
    +	if (error)
    +		goto done;
    +	
    +	/* Cases in which we need to copyout */
    +	switch (uap->cmd) {
    +	case IPC_INFO:
    +		CP(u.shminfo, u32.shminfo32, shmmax);
    +		CP(u.shminfo, u32.shminfo32, shmmin);
    +		CP(u.shminfo, u32.shminfo32, shmmni);
    +		CP(u.shminfo, u32.shminfo32, shmseg);
    +		CP(u.shminfo, u32.shminfo32, shmall);
    +		error = copyout(&u32.shminfo32, uap->buf,
    +		    sizeof(u32.shminfo32));
    +		break;
    +	case SHM_INFO:
    +		CP(u.shm_info, u32.shm_info32, used_ids);
    +		CP(u.shm_info, u32.shm_info32, shm_rss);
    +		CP(u.shm_info, u32.shm_info32, shm_tot);
    +		CP(u.shm_info, u32.shm_info32, shm_swp);
    +		CP(u.shm_info, u32.shm_info32, swap_attempts);
    +		CP(u.shm_info, u32.shm_info32, swap_successes);
    +		error = copyout(&u32.shm_info32, uap->buf,
    +		    sizeof(u32.shm_info32));
    +		break;
    +	case SHM_STAT:
    +	case IPC_STAT:
    +		freebsd32_ipcperm_old_out(&u.shmid_ds.shm_perm,
    +		    &u32.shmid_ds32.shm_perm);
    +		if (u.shmid_ds.shm_segsz > INT32_MAX)
    +			u32.shmid_ds32.shm_segsz = INT32_MAX;
    +		else
    +			CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
    +		u32.shmid_ds32.shm_internal = 0;
    +		error = copyout(&u32.shmid_ds32, uap->buf,
    +		    sizeof(u32.shmid_ds32));
    +		break;
    +	}
    +
    +done:
    +	if (error) {
    +		/* Invalidate the return value */
    +		td->td_retval[0] = -1;
    +	}
    +	return (error);
    +}
    +#endif
    +
    +int
    +freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
    +{
    +	int error = 0;
    +	union {
    +		struct shmid_ds shmid_ds;
    +		struct shm_info shm_info;
    +		struct shminfo shminfo;
    +	} u;
    +	union {
    +		struct shmid_ds32 shmid_ds32;
    +		struct shm_info32 shm_info32;
    +		struct shminfo32 shminfo32;
    +	} u32;
    +	size_t sz;
    +	
    +	if (uap->cmd == IPC_SET) {
    +		if ((error = copyin(uap->buf, &u32.shmid_ds32,
    +		    sizeof(u32.shmid_ds32))))
    +			goto done;
    +		freebsd32_ipcperm_in(&u32.shmid_ds32.shm_perm,
    +		    &u.shmid_ds.shm_perm);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
    +		CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
    +	}
    +	
    +	error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
    +	if (error)
    +		goto done;
    +	
    +	/* Cases in which we need to copyout */
    +	switch (uap->cmd) {
    +	case IPC_INFO:
    +		CP(u.shminfo, u32.shminfo32, shmmax);
    +		CP(u.shminfo, u32.shminfo32, shmmin);
    +		CP(u.shminfo, u32.shminfo32, shmmni);
    +		CP(u.shminfo, u32.shminfo32, shmseg);
    +		CP(u.shminfo, u32.shminfo32, shmall);
    +		error = copyout(&u32.shminfo32, uap->buf,
    +		    sizeof(u32.shminfo32));
    +		break;
    +	case SHM_INFO:
    +		CP(u.shm_info, u32.shm_info32, used_ids);
    +		CP(u.shm_info, u32.shm_info32, shm_rss);
    +		CP(u.shm_info, u32.shm_info32, shm_tot);
    +		CP(u.shm_info, u32.shm_info32, shm_swp);
    +		CP(u.shm_info, u32.shm_info32, swap_attempts);
    +		CP(u.shm_info, u32.shm_info32, swap_successes);
    +		error = copyout(&u32.shm_info32, uap->buf,
    +		    sizeof(u32.shm_info32));
    +		break;
    +	case SHM_STAT:
    +	case IPC_STAT:
    +		freebsd32_ipcperm_out(&u.shmid_ds.shm_perm,
    +		    &u32.shmid_ds32.shm_perm);
    +		if (u.shmid_ds.shm_segsz > INT32_MAX)
    +			u32.shmid_ds32.shm_segsz = INT32_MAX;
    +		else
    +			CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
    +		CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
    +		error = copyout(&u32.shmid_ds32, uap->buf,
    +		    sizeof(u32.shmid_ds32));
    +		break;
    +	}
    +
    +done:
    +	if (error) {
    +		/* Invalidate the return value */
    +		td->td_retval[0] = -1;
    +	}
    +	return (error);
    +}
    +#endif
    +
     #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
         defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
     
    +#ifndef CP
     #define CP(src, dst, fld)	do { (dst).fld = (src).fld; } while (0)
    -
    +#endif
     
     #ifndef _SYS_SYSPROTO_H_
     struct freebsd7_shmctl_args {
    @@ -1061,10 +1333,6 @@ done:
     	return (error);
     }
     
    -SYSCALL_MODULE_HELPER(freebsd7_shmctl);
    -
    -#undef CP
    -
     #endif	/* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
     	   COMPAT_FREEBSD7 */
     
    @@ -1075,7 +1343,9 @@ sysvshm_modload(struct module *module, int cmd, void *arg)
     
     	switch (cmd) {
     	case MOD_LOAD:
    -		shminit();
    +		error = shminit();
    +		if (error != 0)
    +			shmunload();
     		break;
     	case MOD_UNLOAD:
     		error = shmunload();
    @@ -1095,10 +1365,5 @@ static moduledata_t sysvshm_mod = {
     	NULL
     };
     
    -SYSCALL_MODULE_HELPER(shmat);
    -SYSCALL_MODULE_HELPER(shmctl);
    -SYSCALL_MODULE_HELPER(shmdt);
    -SYSCALL_MODULE_HELPER(shmget);
    -
     DECLARE_MODULE(sysvshm, sysvshm_mod, SI_SUB_SYSV_SHM, SI_ORDER_FIRST);
     MODULE_VERSION(sysvshm, 1);
    
    From 0aab10e1a8a3f220fac50e2c90d3a309cdd112dc Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:47:55 +0000
    Subject: [PATCH 1904/2592] MFC r205324: Implement compat32 shims for ksem
     syscalls.
    
    ---
     sys/compat/freebsd32/syscalls.master |  26 ++--
     sys/kern/uipc_sem.c                  | 179 ++++++++++++++++++---------
     2 files changed, 138 insertions(+), 67 deletions(-)
    
    diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
    index ce7f3a0efe3..3256d523d64 100644
    --- a/sys/compat/freebsd32/syscalls.master
    +++ b/sys/compat/freebsd32/syscalls.master
    @@ -698,16 +698,19 @@
     398	AUE_FHSTATFS	NOPROTO	{ int fhstatfs(const struct fhandle *u_fhp, \
     				    struct statfs *buf); }
     399	AUE_NULL	UNIMPL	nosys
    -; XXX implement these?
    -400	AUE_NULL	UNIMPL	ksem_close
    -401	AUE_NULL	UNIMPL	ksem_post
    -402	AUE_NULL	UNIMPL	ksem_wait
    -403	AUE_NULL	UNIMPL	ksem_trywait
    -404	AUE_NULL	UNIMPL	ksem_init
    -405	AUE_NULL	UNIMPL	ksem_open
    -406	AUE_NULL	UNIMPL	ksem_unlink
    -407	AUE_NULL	UNIMPL	ksem_getvalue
    -408	AUE_NULL	UNIMPL	ksem_destroy
    +400	AUE_NULL	NOSTD|NOPROTO	{ int ksem_close(semid_t id); }
    +401	AUE_NULL	NOSTD|NOPROTO	{ int ksem_post(semid_t id); }
    +402	AUE_NULL	NOSTD|NOPROTO	{ int ksem_wait(semid_t id); }
    +403	AUE_NULL	NOSTD|NOPROTO	{ int ksem_trywait(semid_t id); }
    +404	AUE_NULL	NOSTD	{ int freebsd32_ksem_init(semid_t *idp, \
    +				    unsigned int value); }
    +405	AUE_NULL	NOSTD	{ int freebsd32_ksem_open(semid_t *idp, \
    +				    const char *name, int oflag, \
    +				    mode_t mode, unsigned int value); }
    +406	AUE_NULL	NOSTD|NOPROTO	{ int ksem_unlink(const char *name); }
    +407	AUE_NULL	NOSTD|NOPROTO	{ int ksem_getvalue(semid_t id, \
    +				    int *val); }
    +408	AUE_NULL	NOSTD|NOPROTO	{ int ksem_destroy(semid_t id); }
     409	AUE_NULL	UNIMPL	__mac_get_pid
     410	AUE_NULL	UNIMPL	__mac_get_link
     411	AUE_NULL	UNIMPL	__mac_set_link
    @@ -766,7 +769,8 @@
     				    const char *path, int attrnamespace, \
     				    void *data, size_t nbytes); }
     440	AUE_NULL	UNIMPL	kse_switchin
    -441	AUE_NULL	UNIMPL	ksem_timedwait
    +441	AUE_NULL	NOSTD	{ int freebsd32_ksem_timedwait(semid_t id, \
    +				    const struct timespec32 *abstime); }
     442	AUE_NULL	STD	{ int freebsd32_thr_suspend( \
     				    const struct timespec32 *timeout); }
     443	AUE_NULL	NOPROTO	{ int thr_wake(long id); }
    diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c
    index 5ca13f8844f..0aee3f741ff 100644
    --- a/sys/kern/uipc_sem.c
    +++ b/sys/kern/uipc_sem.c
    @@ -34,6 +34,7 @@
     #include 
     __FBSDID("$FreeBSD$");
     
    +#include "opt_compat.h"
     #include "opt_posix.h"
     
     #include 
    @@ -113,7 +114,7 @@ static struct ksem *ksem_alloc(struct ucred *ucred, mode_t mode,
     		    unsigned int value);
     static int	ksem_create(struct thread *td, const char *path,
     		    semid_t *semidp, mode_t mode, unsigned int value,
    -		    int flags);
    +		    int flags, int compat32);
     static void	ksem_drop(struct ksem *ks);
     static int	ksem_get(struct thread *td, semid_t id, struct file **fpp);
     static struct ksem *ksem_hold(struct ksem *ks);
    @@ -375,16 +376,44 @@ ksem_remove(char *path, Fnv32_t fnv, struct ucred *ucred)
     	return (ENOENT);
     }
     
    +static int
    +ksem_create_copyout_semid(struct thread *td, semid_t *semidp, int fd,
    +    int compat32)
    +{
    +	semid_t semid;
    +#ifdef COMPAT_FREEBSD32
    +	int32_t semid32;
    +#endif
    +	void *ptr;
    +	size_t ptrs;
    +
    +#ifdef COMPAT_FREEBSD32
    +	if (compat32) {
    +		semid32 = fd;
    +		ptr = &semid32;
    +		ptrs = sizeof(semid32);
    +	} else {
    +#endif
    +		semid = fd;
    +		ptr = &semid;
    +		ptrs = sizeof(semid);
    +		compat32 = 0; /* silence gcc */
    +#ifdef COMPAT_FREEBSD32
    +	}
    +#endif
    +
    +	return (copyout(ptr, semidp, ptrs));
    +}
    +
     /* Other helper routines. */
     static int
     ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
    -    unsigned int value, int flags)
    +    unsigned int value, int flags, int compat32)
     {
     	struct filedesc *fdp;
     	struct ksem *ks;
     	struct file *fp;
     	char *path;
    -	semid_t semid;
     	Fnv32_t fnv;
     	int error, fd;
     
    @@ -405,8 +434,7 @@ ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
     	 * premature, but it is a lot easier to handle errors as opposed
     	 * to later when we've possibly created a new semaphore, etc.
     	 */
    -	semid = fd;
    -	error = copyout(&semid, semidp, sizeof(semid));
    +	error = ksem_create_copyout_semid(td, semidp, fd, compat32);
     	if (error) {
     		fdclose(fdp, fp, fd, td);
     		fdrop(fp, td);
    @@ -531,7 +559,7 @@ ksem_init(struct thread *td, struct ksem_init_args *uap)
     {
     
     	return (ksem_create(td, NULL, uap->idp, S_IRWXU | S_IRWXG, uap->value,
    -	    0));
    +	    0, 0));
     }
     
     #ifndef _SYS_SYSPROTO_H_
    @@ -552,7 +580,7 @@ ksem_open(struct thread *td, struct ksem_open_args *uap)
     	if ((uap->oflag & ~(O_CREAT | O_EXCL)) != 0)
     		return (EINVAL);
     	return (ksem_create(td, uap->name, uap->idp, uap->mode, uap->value,
    -	    uap->oflag));
    +	    uap->oflag, 0));
     }
     
     #ifndef _SYS_SYSPROTO_H_
    @@ -833,38 +861,85 @@ err:
     	return (error);
     }
     
    -#define	SYSCALL_DATA(syscallname)				\
    -static int syscallname##_syscall = SYS_##syscallname;		\
    -static int syscallname##_registered;				\
    -static struct sysent syscallname##_old_sysent;			\
    -MAKE_SYSENT(syscallname);
    +static struct syscall_helper_data ksem_syscalls[] = {
    +	SYSCALL_INIT_HELPER(ksem_init),
    +	SYSCALL_INIT_HELPER(ksem_open),
    +	SYSCALL_INIT_HELPER(ksem_unlink),
    +	SYSCALL_INIT_HELPER(ksem_close),
    +	SYSCALL_INIT_HELPER(ksem_post),
    +	SYSCALL_INIT_HELPER(ksem_wait),
    +	SYSCALL_INIT_HELPER(ksem_timedwait),
    +	SYSCALL_INIT_HELPER(ksem_trywait),
    +	SYSCALL_INIT_HELPER(ksem_getvalue),
    +	SYSCALL_INIT_HELPER(ksem_destroy),
    +	SYSCALL_INIT_LAST
    +};
     
    -#define	SYSCALL_REGISTER(syscallname) do {				\
    -	error = syscall_register(& syscallname##_syscall,		\
    -	    & syscallname##_sysent, & syscallname##_old_sysent);	\
    -	if (error)							\
    -		return (error);						\
    -	syscallname##_registered = 1;					\
    -} while(0)
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
     
    -#define	SYSCALL_DEREGISTER(syscallname) do {				\
    -	if (syscallname##_registered) {					\
    -		syscallname##_registered = 0;				\
    -		syscall_deregister(& syscallname##_syscall,		\
    -		    & syscallname##_old_sysent);			\
    -	}								\
    -} while(0)
    +int
    +freebsd32_ksem_init(struct thread *td, struct freebsd32_ksem_init_args *uap)
    +{
     
    -SYSCALL_DATA(ksem_init);
    -SYSCALL_DATA(ksem_open);
    -SYSCALL_DATA(ksem_unlink);
    -SYSCALL_DATA(ksem_close);
    -SYSCALL_DATA(ksem_post);
    -SYSCALL_DATA(ksem_wait);
    -SYSCALL_DATA(ksem_timedwait);
    -SYSCALL_DATA(ksem_trywait);
    -SYSCALL_DATA(ksem_getvalue);
    -SYSCALL_DATA(ksem_destroy);
    +	return (ksem_create(td, NULL, uap->idp, S_IRWXU | S_IRWXG, uap->value,
    +	    0, 1));
    +}
    +
    +int
    +freebsd32_ksem_open(struct thread *td, struct freebsd32_ksem_open_args *uap)
    +{
    +
    +	if ((uap->oflag & ~(O_CREAT | O_EXCL)) != 0)
    +		return (EINVAL);
    +	return (ksem_create(td, uap->name, uap->idp, uap->mode, uap->value,
    +	    uap->oflag, 1));
    +}
    +
    +int
    +freebsd32_ksem_timedwait(struct thread *td,
    +    struct freebsd32_ksem_timedwait_args *uap)
    +{
    +	struct timespec32 abstime32;
    +	struct timespec *ts, abstime;
    +	int error;
    +
    +	/*
    +	 * We allow a null timespec (wait forever).
    +	 */
    +	if (uap->abstime == NULL)
    +		ts = NULL;
    +	else {
    +		error = copyin(uap->abstime, &abstime32, sizeof(abstime32));
    +		if (error != 0)
    +			return (error);
    +		CP(abstime32, abstime, tv_sec);
    +		CP(abstime32, abstime, tv_nsec);
    +		if (abstime.tv_nsec >= 1000000000 || abstime.tv_nsec < 0)
    +			return (EINVAL);
    +		ts = &abstime;
    +	}
    +	return (kern_sem_wait(td, uap->id, 0, ts));
    +}
    +
    +static struct syscall_helper_data ksem32_syscalls[] = {
    +	SYSCALL32_INIT_HELPER(freebsd32_ksem_init),
    +	SYSCALL32_INIT_HELPER(freebsd32_ksem_open),
    +	SYSCALL32_INIT_HELPER(ksem_unlink),
    +	SYSCALL32_INIT_HELPER(ksem_close),
    +	SYSCALL32_INIT_HELPER(ksem_post),
    +	SYSCALL32_INIT_HELPER(ksem_wait),
    +	SYSCALL32_INIT_HELPER(freebsd32_ksem_timedwait),
    +	SYSCALL32_INIT_HELPER(ksem_trywait),
    +	SYSCALL32_INIT_HELPER(ksem_getvalue),
    +	SYSCALL32_INIT_HELPER(ksem_destroy),
    +	SYSCALL_INIT_LAST
    +};
    +#endif
     
     static int
     ksem_module_init(void)
    @@ -878,16 +953,14 @@ ksem_module_init(void)
     	p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
     	p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX);
     
    -	SYSCALL_REGISTER(ksem_init);
    -	SYSCALL_REGISTER(ksem_open);
    -	SYSCALL_REGISTER(ksem_unlink);
    -	SYSCALL_REGISTER(ksem_close);
    -	SYSCALL_REGISTER(ksem_post);
    -	SYSCALL_REGISTER(ksem_wait);
    -	SYSCALL_REGISTER(ksem_timedwait);
    -	SYSCALL_REGISTER(ksem_trywait);
    -	SYSCALL_REGISTER(ksem_getvalue);
    -	SYSCALL_REGISTER(ksem_destroy);
    +	error = syscall_helper_register(ksem_syscalls);
    +	if (error)
    +		return (error);
    +#ifdef COMPAT_FREEBSD32
    +	error = syscall32_helper_register(ksem32_syscalls);
    +	if (error)
    +		return (error);
    +#endif
     	return (0);
     }
     
    @@ -895,16 +968,10 @@ static void
     ksem_module_destroy(void)
     {
     
    -	SYSCALL_DEREGISTER(ksem_init);
    -	SYSCALL_DEREGISTER(ksem_open);
    -	SYSCALL_DEREGISTER(ksem_unlink);
    -	SYSCALL_DEREGISTER(ksem_close);
    -	SYSCALL_DEREGISTER(ksem_post);
    -	SYSCALL_DEREGISTER(ksem_wait);
    -	SYSCALL_DEREGISTER(ksem_timedwait);
    -	SYSCALL_DEREGISTER(ksem_trywait);
    -	SYSCALL_DEREGISTER(ksem_getvalue);
    -	SYSCALL_DEREGISTER(ksem_destroy);
    +#ifdef COMPAT_FREEBSD32
    +	syscall32_helper_unregister(ksem32_syscalls);
    +#endif
    +	syscall_helper_unregister(ksem_syscalls);
     
     	hashdestroy(ksem_dictionary, M_KSEM, ksem_hash);
     	sx_destroy(&ksem_dict_lock);
    
    From 048575ee75f03c4da4a279c7e1311cae1f06a203 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:49:35 +0000
    Subject: [PATCH 1905/2592] MFC r205325: Implement compat32 shims for mqueuefs.
    
    ---
     sys/compat/freebsd32/freebsd32.h     |   8 +
     sys/compat/freebsd32/syscalls.master |  23 +-
     sys/kern/uipc_mqueue.c               | 365 ++++++++++++++++++++++-----
     3 files changed, 328 insertions(+), 68 deletions(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
    index 058ac72fe5f..b68f8fbbc03 100644
    --- a/sys/compat/freebsd32/freebsd32.h
    +++ b/sys/compat/freebsd32/freebsd32.h
    @@ -221,4 +221,12 @@ struct prpsinfo32 {
             char    pr_psargs[PRARGSZ+1];
     };
     
    +struct mq_attr32 {
    +	int	mq_flags;
    +	int	mq_maxmsg;
    +	int	mq_msgsize;
    +	int	mq_curmsgs;
    +	int	__reserved[4];
    +};
    +
     #endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */
    diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
    index 3256d523d64..001b020a719 100644
    --- a/sys/compat/freebsd32/syscalls.master
    +++ b/sys/compat/freebsd32/syscalls.master
    @@ -798,12 +798,23 @@
     				    int param_size); }
     456	AUE_NULL	NOPROTO	{ int sigqueue(pid_t pid, int signum, \
     				    void *value); }
    -457	AUE_NULL	UNIMPL	kmq_open
    -458	AUE_NULL	UNIMPL	kmq_setattr
    -459	AUE_NULL	UNIMPL	kmq_timedreceive
    -460	AUE_NULL	UNIMPL  kmq_timedsend
    -461	AUE_NULL	UNIMPL	kmq_notify
    -462	AUE_NULL	UNIMPL	kmq_unlink
    +457	AUE_NULL	NOSTD	{ int freebsd32_kmq_open( \
    +				    const char *path, int flags, mode_t mode, \
    +				    const struct mq_attr32 *attr); }
    +458	AUE_NULL	NOSTD	{ int freebsd32_kmq_setattr(int mqd, \
    +				    const struct mq_attr32 *attr,	\
    +				    struct mq_attr32 *oattr); }
    +459	AUE_NULL	NOSTD	{ int freebsd32_kmq_timedreceive(int mqd, \
    +				    char *msg_ptr, size_t msg_len,	\
    +				    unsigned *msg_prio,			\
    +				    const struct timespec32 *abs_timeout); }
    +460	AUE_NULL	NOSTD	{ int freebsd32_kmq_timedsend(int mqd,	\
    +				    const char *msg_ptr, size_t msg_len,\
    +				    unsigned msg_prio,			\
    +				    const struct timespec32 *abs_timeout);}
    +461	AUE_NULL	NOPROTO|NOSTD	{ int kmq_notify(int mqd,	\
    +				    const struct sigevent *sigev); }
    +462	AUE_NULL	NOPROTO|NOSTD	{ int kmq_unlink(const char *path); }
     463	AUE_NULL	NOPROTO	{ int abort2(const char *why, int nargs, void **args); }
     464	AUE_NULL 	NOPROTO	{ int thr_set_name(long id, const char *name); }
     465	AUE_NULL	NOSTD	{ int freebsd32_aio_fsync(int op, \
    diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
    index 69bf59c296c..a9a9c037405 100644
    --- a/sys/kern/uipc_mqueue.c
    +++ b/sys/kern/uipc_mqueue.c
    @@ -45,6 +45,8 @@
     #include 
     __FBSDID("$FreeBSD$");
     
    +#include "opt_compat.h"
    +
     #include 
     #include 
     #include 
    @@ -1616,7 +1618,7 @@ mqueue_send(struct mqueue *mq, const char *msg_ptr,
     	const struct timespec *abs_timeout)
     {
     	struct mqueue_msg *msg;
    -	struct timespec ets, ts, ts2;
    +	struct timespec ts, ts2;
     	struct timeval tv;
     	int error;
     
    @@ -1652,15 +1654,12 @@ mqueue_send(struct mqueue *mq, const char *msg_ptr,
     	if (error != EAGAIN)
     		goto bad;
     
    -	error = copyin(abs_timeout, &ets, sizeof(ets));
    -	if (error != 0)
    -		goto bad;
    -	if (ets.tv_nsec >= 1000000000 || ets.tv_nsec < 0) {
    +	if (abs_timeout->tv_nsec >= 1000000000 || abs_timeout->tv_nsec < 0) {
     		error = EINVAL;
     		goto bad;
     	}
     	for (;;) {
    -		ts2 = ets;
    +		ts2 = *abs_timeout;
     		getnanotime(&ts);
     		timespecsub(&ts2, &ts);
     		if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0)) {
    @@ -1767,7 +1766,7 @@ mqueue_receive(struct mqueue *mq, char *msg_ptr,
     	const struct timespec *abs_timeout)
     {
     	struct mqueue_msg *msg;
    -	struct timespec ets, ts, ts2;
    +	struct timespec ts, ts2;
     	struct timeval tv;
     	int error;
     
    @@ -1798,16 +1797,13 @@ mqueue_receive(struct mqueue *mq, char *msg_ptr,
     	if (error != EAGAIN)
     		return (error);
     
    -	error = copyin(abs_timeout, &ets, sizeof(ets));
    -	if (error != 0)
    -		return (error);
    -	if (ets.tv_nsec >= 1000000000 || ets.tv_nsec < 0) {
    +	if (abs_timeout->tv_nsec >= 1000000000 || abs_timeout->tv_nsec < 0) {
     		error = EINVAL;
     		return (error);
     	}
     
     	for (;;) {
    -		ts2 = ets;
    +		ts2 = *abs_timeout;
     		getnanotime(&ts);
     		timespecsub(&ts2, &ts);
     		if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0)) {
    @@ -1928,40 +1924,28 @@ notifier_remove(struct proc *p, struct mqueue *mq, int fd)
     	PROC_UNLOCK(p);
     }
     
    -/*
    - * Syscall to open a message queue.
    - */
    -int
    -kmq_open(struct thread *td, struct kmq_open_args *uap)
    +static int
    +kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
    +    const struct mq_attr *attr)
     {
     	char path[MQFS_NAMELEN + 1];
    -	struct mq_attr attr, *pattr;
     	struct mqfs_node *pn;
     	struct filedesc *fdp;
     	struct file *fp;
     	struct mqueue *mq;
    -	int fd, error, len, flags, cmode;
    -
    -	if ((uap->flags & O_ACCMODE) == O_ACCMODE)
    -		return (EINVAL);
    +	int fd, error, len, cmode;
     
     	fdp = td->td_proc->p_fd;
    -	flags = FFLAGS(uap->flags);
    -	cmode = (((uap->mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT);
    +	cmode = (((mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT);
     	mq = NULL;
    -	if ((flags & O_CREAT) && (uap->attr != NULL)) {
    -		error = copyin(uap->attr, &attr, sizeof(attr));
    -		if (error)
    -			return (error);
    -		if (attr.mq_maxmsg <= 0 || attr.mq_maxmsg > maxmsg)
    +	if ((flags & O_CREAT) != 0 && attr != NULL) {
    +		if (attr->mq_maxmsg <= 0 || attr->mq_maxmsg > maxmsg)
     			return (EINVAL);
    -		if (attr.mq_msgsize <= 0 || attr.mq_msgsize > maxmsgsize)
    +		if (attr->mq_msgsize <= 0 || attr->mq_msgsize > maxmsgsize)
     			return (EINVAL);
    -		pattr = &attr;
    -	} else
    -		pattr = NULL;
    +	}
     
    -	error = copyinstr(uap->path, path, MQFS_NAMELEN + 1, NULL);
    +	error = copyinstr(upath, path, MQFS_NAMELEN + 1, NULL);
             if (error)
     		return (error);
     
    @@ -1984,7 +1968,7 @@ kmq_open(struct thread *td, struct kmq_open_args *uap)
     		if (!(flags & O_CREAT)) {
     			error = ENOENT;
     		} else {
    -			mq = mqueue_alloc(pattr);
    +			mq = mqueue_alloc(attr);
     			if (mq == NULL) {
     				error = ENFILE;
     			} else {
    @@ -2038,6 +2022,27 @@ kmq_open(struct thread *td, struct kmq_open_args *uap)
     	return (0);
     }
     
    +/*
    + * Syscall to open a message queue.
    + */
    +int
    +kmq_open(struct thread *td, struct kmq_open_args *uap)
    +{
    +	struct mq_attr attr;
    +	int flags, error;
    +
    +	if ((uap->flags & O_ACCMODE) == O_ACCMODE)
    +		return (EINVAL);
    +	flags = FFLAGS(uap->flags);
    +	if ((flags & O_CREAT) != 0 && uap->attr != NULL) {
    +		error = copyin(uap->attr, &attr, sizeof(attr));
    +		if (error)
    +			return (error);
    +	}
    +	return (kern_kmq_open(td, uap->path, flags, uap->mode,
    +	    uap->attr != NULL ? &attr : NULL));
    +}
    +
     /*
      * Syscall to unlink a message queue.
      */
    @@ -2114,39 +2119,52 @@ getmq_write(struct thread *td, int fd, struct file **fpp,
     	return _getmq(td, fd, fget_write, fpp, ppn, pmq);
     }
     
    -int
    -kmq_setattr(struct thread *td, struct kmq_setattr_args *uap)
    +static int
    +kern_kmq_setattr(struct thread *td, int mqd, const struct mq_attr *attr,
    +    struct mq_attr *oattr)
     {
     	struct mqueue *mq;
     	struct file *fp;
    -	struct mq_attr attr, oattr;
     	u_int oflag, flag;
     	int error;
     
    -	if (uap->attr) {
    -		error = copyin(uap->attr, &attr, sizeof(attr));
    -		if (error)
    -			return (error);
    -		if (attr.mq_flags & ~O_NONBLOCK)
    -			return (EINVAL);
    -	}
    -	error = getmq(td, uap->mqd, &fp, NULL, &mq);
    +	if (attr != NULL && (attr->mq_flags & ~O_NONBLOCK) != 0)
    +		return (EINVAL);
    +	error = getmq(td, mqd, &fp, NULL, &mq);
     	if (error)
     		return (error);
    -	oattr.mq_maxmsg  = mq->mq_maxmsg;
    -	oattr.mq_msgsize = mq->mq_msgsize;
    -	oattr.mq_curmsgs = mq->mq_curmsgs;
    -	if (uap->attr) {
    +	oattr->mq_maxmsg  = mq->mq_maxmsg;
    +	oattr->mq_msgsize = mq->mq_msgsize;
    +	oattr->mq_curmsgs = mq->mq_curmsgs;
    +	if (attr != NULL) {
     		do {
     			oflag = flag = fp->f_flag;
     			flag &= ~O_NONBLOCK;
    -			flag |= (attr.mq_flags & O_NONBLOCK);
    +			flag |= (attr->mq_flags & O_NONBLOCK);
     		} while (atomic_cmpset_int(&fp->f_flag, oflag, flag) == 0);
     	} else
     		oflag = fp->f_flag;
    -	oattr.mq_flags = (O_NONBLOCK & oflag);
    +	oattr->mq_flags = (O_NONBLOCK & oflag);
     	fdrop(fp, td);
    -	if (uap->oattr)
    +	return (error);
    +}
    +
    +int
    +kmq_setattr(struct thread *td, struct kmq_setattr_args *uap)
    +{
    +	struct mq_attr attr, oattr;
    +	int error;
    +
    +	if (uap->attr != NULL) {
    +		error = copyin(uap->attr, &attr, sizeof(attr));
    +		if (error != 0)
    +			return (error);
    +	}
    +	error = kern_kmq_setattr(td, uap->mqd, uap->attr != NULL ? &attr : NULL,
    +	    &oattr);
    +	if (error != 0)
    +		return (error);
    +	if (uap->oattr != NULL)
     		error = copyout(&oattr, uap->oattr, sizeof(oattr));
     	return (error);
     }
    @@ -2156,15 +2174,23 @@ kmq_timedreceive(struct thread *td, struct kmq_timedreceive_args *uap)
     {
     	struct mqueue *mq;
     	struct file *fp;
    +	struct timespec *abs_timeout, ets;
     	int error;
     	int waitok;
     
     	error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
     	if (error)
     		return (error);
    +	if (uap->abs_timeout != NULL) {
    +		error = copyin(uap->abs_timeout, &ets, sizeof(ets));
    +		if (error != 0)
    +			return (error);
    +		abs_timeout = &ets;
    +	} else
    +		abs_timeout = NULL;
     	waitok = !(fp->f_flag & O_NONBLOCK);
     	error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
    -		uap->msg_prio, waitok, uap->abs_timeout);
    +		uap->msg_prio, waitok, abs_timeout);
     	fdrop(fp, td);
     	return (error);
     }
    @@ -2174,14 +2200,22 @@ kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap)
     {
     	struct mqueue *mq;
     	struct file *fp;
    +	struct timespec *abs_timeout, ets;
     	int error, waitok;
     
     	error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
     	if (error)
     		return (error);
    +	if (uap->abs_timeout != NULL) {
    +		error = copyin(uap->abs_timeout, &ets, sizeof(ets));
    +		if (error != 0)
    +			return (error);
    +		abs_timeout = &ets;
    +	} else
    +		abs_timeout = NULL;
     	waitok = !(fp->f_flag & O_NONBLOCK);
     	error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
    -		uap->msg_prio, waitok, uap->abs_timeout);
    +		uap->msg_prio, waitok, abs_timeout);
     	fdrop(fp, td);
     	return (error);
     }
    @@ -2505,12 +2539,219 @@ static struct vfsops mqfs_vfsops = {
     	.vfs_statfs		= mqfs_statfs,
     };
     
    -SYSCALL_MODULE_HELPER(kmq_open);
    -SYSCALL_MODULE_HELPER(kmq_setattr);
    -SYSCALL_MODULE_HELPER(kmq_timedsend);
    -SYSCALL_MODULE_HELPER(kmq_timedreceive);
    -SYSCALL_MODULE_HELPER(kmq_notify);
    -SYSCALL_MODULE_HELPER(kmq_unlink);
    +static struct vfsconf mqueuefs_vfsconf = {
    +	.vfc_version = VFS_VERSION,
    +	.vfc_name = "mqueuefs",
    +	.vfc_vfsops = &mqfs_vfsops,
    +	.vfc_typenum = -1,
    +	.vfc_flags = VFCF_SYNTHETIC
    +};
     
    -VFS_SET(mqfs_vfsops, mqueuefs, VFCF_SYNTHETIC);
    +static struct syscall_helper_data mq_syscalls[] = {
    +	SYSCALL_INIT_HELPER(kmq_open),
    +	SYSCALL_INIT_HELPER(kmq_setattr),
    +	SYSCALL_INIT_HELPER(kmq_timedsend),
    +	SYSCALL_INIT_HELPER(kmq_timedreceive),
    +	SYSCALL_INIT_HELPER(kmq_notify),
    +	SYSCALL_INIT_HELPER(kmq_unlink),
    +	SYSCALL_INIT_LAST
    +};
    +
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +static void
    +mq_attr_from32(const struct mq_attr32 *from, struct mq_attr *to)
    +{
    +
    +	to->mq_flags = from->mq_flags;
    +	to->mq_maxmsg = from->mq_maxmsg;
    +	to->mq_msgsize = from->mq_msgsize;
    +	to->mq_curmsgs = from->mq_curmsgs;
    +}
    +
    +static void
    +mq_attr_to32(const struct mq_attr *from, struct mq_attr32 *to)
    +{
    +
    +	to->mq_flags = from->mq_flags;
    +	to->mq_maxmsg = from->mq_maxmsg;
    +	to->mq_msgsize = from->mq_msgsize;
    +	to->mq_curmsgs = from->mq_curmsgs;
    +}
    +
    +int
    +freebsd32_kmq_open(struct thread *td, struct freebsd32_kmq_open_args *uap)
    +{
    +	struct mq_attr attr;
    +	struct mq_attr32 attr32;
    +	int flags, error;
    +
    +	if ((uap->flags & O_ACCMODE) == O_ACCMODE)
    +		return (EINVAL);
    +	flags = FFLAGS(uap->flags);
    +	if ((flags & O_CREAT) != 0 && uap->attr != NULL) {
    +		error = copyin(uap->attr, &attr32, sizeof(attr32));
    +		if (error)
    +			return (error);
    +		mq_attr_from32(&attr32, &attr);
    +	}
    +	return (kern_kmq_open(td, uap->path, flags, uap->mode,
    +	    uap->attr != NULL ? &attr : NULL));
    +}
    +
    +int
    +freebsd32_kmq_setattr(struct thread *td, struct freebsd32_kmq_setattr_args *uap)
    +{
    +	struct mq_attr attr, oattr;
    +	struct mq_attr32 attr32, oattr32;
    +	int error;
    +
    +	if (uap->attr != NULL) {
    +		error = copyin(uap->attr, &attr32, sizeof(attr32));
    +		if (error != 0)
    +			return (error);
    +		mq_attr_from32(&attr32, &attr);
    +	}
    +	error = kern_kmq_setattr(td, uap->mqd, uap->attr != NULL ? &attr : NULL,
    +	    &oattr);
    +	if (error != 0)
    +		return (error);
    +	if (uap->oattr != NULL) {
    +		mq_attr_to32(&oattr, &oattr32);
    +		error = copyout(&oattr32, uap->oattr, sizeof(oattr32));
    +	}
    +	return (error);
    +}
    +
    +int
    +freebsd32_kmq_timedsend(struct thread *td,
    +    struct freebsd32_kmq_timedsend_args *uap)
    +{
    +	struct mqueue *mq;
    +	struct file *fp;
    +	struct timespec32 ets32;
    +	struct timespec *abs_timeout, ets;
    +	int error;
    +	int waitok;
    +
    +	error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
    +	if (error)
    +		return (error);
    +	if (uap->abs_timeout != NULL) {
    +		error = copyin(uap->abs_timeout, &ets32, sizeof(ets32));
    +		if (error != 0)
    +			return (error);
    +		CP(ets32, ets, tv_sec);
    +		CP(ets32, ets, tv_nsec);
    +		abs_timeout = &ets;
    +	} else
    +		abs_timeout = NULL;
    +	waitok = !(fp->f_flag & O_NONBLOCK);
    +	error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
    +		uap->msg_prio, waitok, abs_timeout);
    +	fdrop(fp, td);
    +	return (error);
    +}
    +
    +int
    +freebsd32_kmq_timedreceive(struct thread *td,
    +    struct freebsd32_kmq_timedreceive_args *uap)
    +{
    +	struct mqueue *mq;
    +	struct file *fp;
    +	struct timespec32 ets32;
    +	struct timespec *abs_timeout, ets;
    +	int error, waitok;
    +
    +	error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
    +	if (error)
    +		return (error);
    +	if (uap->abs_timeout != NULL) {
    +		error = copyin(uap->abs_timeout, &ets32, sizeof(ets32));
    +		if (error != 0)
    +			return (error);
    +		CP(ets32, ets, tv_sec);
    +		CP(ets32, ets, tv_nsec);
    +		abs_timeout = &ets;
    +	} else
    +		abs_timeout = NULL;
    +	waitok = !(fp->f_flag & O_NONBLOCK);
    +	error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
    +		uap->msg_prio, waitok, abs_timeout);
    +	fdrop(fp, td);
    +	return (error);
    +}
    +
    +static struct syscall_helper_data mq32_syscalls[] = {
    +	SYSCALL32_INIT_HELPER(freebsd32_kmq_open),
    +	SYSCALL32_INIT_HELPER(freebsd32_kmq_setattr),
    +	SYSCALL32_INIT_HELPER(freebsd32_kmq_timedsend),
    +	SYSCALL32_INIT_HELPER(freebsd32_kmq_timedreceive),
    +	SYSCALL32_INIT_HELPER(kmq_notify),
    +	SYSCALL32_INIT_HELPER(kmq_unlink),
    +	SYSCALL_INIT_LAST
    +};
    +#endif
    +
    +static int
    +mqinit(void)
    +{
    +	int error;
    +
    +	error = syscall_helper_register(mq_syscalls);
    +	if (error != 0)
    +		return (error);
    +#ifdef COMPAT_FREEBSD32
    +	error = syscall32_helper_register(mq32_syscalls);
    +	if (error != 0)
    +		return (error);
    +#endif
    +	return (0);
    +}
    +
    +static int
    +mqunload(void)
    +{
    +
    +#ifdef COMPAT_FREEBSD32
    +	syscall32_helper_unregister(mq32_syscalls);
    +#endif
    +	syscall_helper_unregister(mq_syscalls);
    +	return (0);
    +}
    +
    +static int
    +mq_modload(struct module *module, int cmd, void *arg)
    +{
    +	int error = 0;
    +
    +	error = vfs_modevent(module, cmd, arg);
    +	if (error != 0)
    +		return (error);
    +
    +	switch (cmd) {
    +	case MOD_LOAD:
    +		error = mqinit();
    +		if (error != 0)
    +			mqunload();
    +		break;
    +	case MOD_UNLOAD:
    +		error = mqunload();
    +		break;
    +	default:
    +		break;
    +	}
    +	return (error);
    +}
    +
    +static moduledata_t mqueuefs_mod = {
    +	"mqueuefs",
    +	mq_modload,
    +	&mqueuefs_vfsconf
    +};
    +DECLARE_MODULE(mqueuefs, mqueuefs_mod, SI_SUB_VFS, SI_ORDER_MIDDLE);
     MODULE_VERSION(mqueuefs, 1);
    
    From 36131b48edaedc4950ce79ca65c19e1d664f181a Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:50:58 +0000
    Subject: [PATCH 1906/2592] MFC r205326: Convert aio syscall registration to
     SYSCALL_INIT_HELPER.
    
    ---
     sys/kern/vfs_aio.c | 92 +++++++++++++++++++++++++++++-----------------
     1 file changed, 59 insertions(+), 33 deletions(-)
    
    diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
    index 841d39a15f1..d94c1e7a22c 100644
    --- a/sys/kern/vfs_aio.c
    +++ b/sys/kern/vfs_aio.c
    @@ -334,7 +334,7 @@ static TAILQ_HEAD(,aiocblist) aio_jobs;			/* (c) Async job list */
     static struct unrhdr *aiod_unr;
     
     void		aio_init_aioinfo(struct proc *p);
    -static void	aio_onceonly(void);
    +static int	aio_onceonly(void);
     static int	aio_free_entry(struct aiocblist *aiocbe);
     static void	aio_process(struct aiocblist *aiocbe);
     static int	aio_newproc(int *);
    @@ -411,18 +411,47 @@ static moduledata_t aio_mod = {
     	NULL
     };
     
    -SYSCALL_MODULE_HELPER(aio_cancel);
    -SYSCALL_MODULE_HELPER(aio_error);
    -SYSCALL_MODULE_HELPER(aio_fsync);
    -SYSCALL_MODULE_HELPER(aio_read);
    -SYSCALL_MODULE_HELPER(aio_return);
    -SYSCALL_MODULE_HELPER(aio_suspend);
    -SYSCALL_MODULE_HELPER(aio_waitcomplete);
    -SYSCALL_MODULE_HELPER(aio_write);
    -SYSCALL_MODULE_HELPER(lio_listio);
    -SYSCALL_MODULE_HELPER(oaio_read);
    -SYSCALL_MODULE_HELPER(oaio_write);
    -SYSCALL_MODULE_HELPER(olio_listio);
    +static struct syscall_helper_data aio_syscalls[] = {
    +	SYSCALL_INIT_HELPER(aio_cancel),
    +	SYSCALL_INIT_HELPER(aio_error),
    +	SYSCALL_INIT_HELPER(aio_fsync),
    +	SYSCALL_INIT_HELPER(aio_read),
    +	SYSCALL_INIT_HELPER(aio_return),
    +	SYSCALL_INIT_HELPER(aio_suspend),
    +	SYSCALL_INIT_HELPER(aio_waitcomplete),
    +	SYSCALL_INIT_HELPER(aio_write),
    +	SYSCALL_INIT_HELPER(lio_listio),
    +	SYSCALL_INIT_HELPER(oaio_read),
    +	SYSCALL_INIT_HELPER(oaio_write),
    +	SYSCALL_INIT_HELPER(olio_listio),
    +	SYSCALL_INIT_LAST
    +};
    +
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +static struct syscall_helper_data aio32_syscalls[] = {
    +	SYSCALL32_INIT_HELPER(freebsd32_aio_return),
    +	SYSCALL32_INIT_HELPER(freebsd32_aio_suspend),
    +	SYSCALL32_INIT_HELPER(freebsd32_aio_cancel),
    +	SYSCALL32_INIT_HELPER(freebsd32_aio_error),
    +	SYSCALL32_INIT_HELPER(freebsd32_aio_fsync),
    +	SYSCALL32_INIT_HELPER(freebsd32_aio_read),
    +	SYSCALL32_INIT_HELPER(freebsd32_aio_write),
    +	SYSCALL32_INIT_HELPER(freebsd32_aio_waitcomplete),
    +	SYSCALL32_INIT_HELPER(freebsd32_lio_listio),
    +	SYSCALL32_INIT_HELPER(freebsd32_oaio_read),
    +	SYSCALL32_INIT_HELPER(freebsd32_oaio_write),
    +	SYSCALL32_INIT_HELPER(freebsd32_olio_listio),
    +	SYSCALL_INIT_LAST
    +};
    +#endif
     
     DECLARE_MODULE(aio, aio_mod,
     	SI_SUB_VFS, SI_ORDER_ANY);
    @@ -431,9 +460,10 @@ MODULE_VERSION(aio, 1);
     /*
      * Startup initialization
      */
    -static void
    +static int
     aio_onceonly(void)
     {
    +	int error;
     
     	/* XXX: should probably just use so->callback */
     	aio_swake = &aio_swake_cb;
    @@ -466,6 +496,16 @@ aio_onceonly(void)
     	p31b_setcfg(CTL_P1003_1B_AIO_LISTIO_MAX, AIO_LISTIO_MAX);
     	p31b_setcfg(CTL_P1003_1B_AIO_MAX, MAX_AIO_QUEUE);
     	p31b_setcfg(CTL_P1003_1B_AIO_PRIO_DELTA_MAX, 0);
    +
    +	error = syscall_helper_register(aio_syscalls);
    +	if (error)
    +		return (error);
    +#ifdef COMPAT_FREEBSD32
    +	error = syscall32_helper_register(aio32_syscalls);
    +	if (error)
    +		return (error);
    +#endif
    +	return (0);
     }
     
     /*
    @@ -487,6 +527,11 @@ aio_unload(void)
     	if (!unloadable)
     		return (EOPNOTSUPP);
     
    +#ifdef COMPAT_FREEBSD32
    +	syscall32_helper_unregister(aio32_syscalls);
    +#endif
    +	syscall_helper_unregister(aio_syscalls);
    +
     	error = kqueue_del_filteropts(EVFILT_AIO);
     	if (error)
     		return error;
    @@ -2525,13 +2570,6 @@ filt_lio(struct knote *kn, long hint)
     }
     
     #ifdef COMPAT_FREEBSD32
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
     
     struct __aiocb_private32 {
     	int32_t	status;
    @@ -2940,16 +2978,4 @@ freebsd32_lio_listio(struct thread *td, struct freebsd32_lio_listio_args *uap)
     	return (error);
     }
     
    -SYSCALL32_MODULE_HELPER(freebsd32_aio_return);
    -SYSCALL32_MODULE_HELPER(freebsd32_aio_suspend);
    -SYSCALL32_MODULE_HELPER(freebsd32_aio_cancel);
    -SYSCALL32_MODULE_HELPER(freebsd32_aio_error);
    -SYSCALL32_MODULE_HELPER(freebsd32_aio_fsync);
    -SYSCALL32_MODULE_HELPER(freebsd32_aio_read);
    -SYSCALL32_MODULE_HELPER(freebsd32_aio_write);
    -SYSCALL32_MODULE_HELPER(freebsd32_aio_waitcomplete);
    -SYSCALL32_MODULE_HELPER(freebsd32_lio_listio);
    -SYSCALL32_MODULE_HELPER(freebsd32_oaio_read);
    -SYSCALL32_MODULE_HELPER(freebsd32_oaio_write);
    -SYSCALL32_MODULE_HELPER(freebsd32_olio_listio);
     #endif
    
    From 7f67bb1b41a4742925e2eb813f4e67c7e4214602 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:52:42 +0000
    Subject: [PATCH 1907/2592] MFC r205327: Remove empty line.
    
    ---
     sys/compat/freebsd32/freebsd32_misc.c | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
    index ad83f1613d2..1284e386cdd 100644
    --- a/sys/compat/freebsd32/freebsd32_misc.c
    +++ b/sys/compat/freebsd32/freebsd32_misc.c
    @@ -1400,7 +1400,6 @@ freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatf
     }
     #endif
     
    -
     int
     freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
     {
    
    From 548ce22832ec9f56a14d88c53271e34f6cbae4f6 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 7 Apr 2010 14:53:49 +0000
    Subject: [PATCH 1908/2592] Regen.
    
    ---
     sys/compat/freebsd32/freebsd32_proto.h    | 56 ++++++++++++++++++-
     sys/compat/freebsd32/freebsd32_syscall.h  | 18 +++++-
     sys/compat/freebsd32/freebsd32_syscalls.c | 34 ++++++------
     sys/compat/freebsd32/freebsd32_sysent.c   | 68 +++++++++++------------
     4 files changed, 123 insertions(+), 53 deletions(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h
    index e6c91af6f7b..38377b6348c 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: stable/8/sys/compat/freebsd32/syscalls.master 206336 2010-04-07 02:24:41Z nwhitehorn 
    + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 206351 2010-04-07 14:49:35Z kib 
      */
     
     #ifndef _FREEBSD32_SYSPROTO_H_
    @@ -306,6 +306,17 @@ struct freebsd32_sendfile_args {
     	char sbytes_l_[PADL_(off_t *)]; off_t * sbytes; char sbytes_r_[PADR_(off_t *)];
     	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
     };
    +struct freebsd32_ksem_init_args {
    +	char idp_l_[PADL_(semid_t *)]; semid_t * idp; char idp_r_[PADR_(semid_t *)];
    +	char value_l_[PADL_(unsigned int)]; unsigned int value; char value_r_[PADR_(unsigned int)];
    +};
    +struct freebsd32_ksem_open_args {
    +	char idp_l_[PADL_(semid_t *)]; semid_t * idp; char idp_r_[PADR_(semid_t *)];
    +	char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
    +	char oflag_l_[PADL_(int)]; int oflag; char oflag_r_[PADR_(int)];
    +	char mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)];
    +	char value_l_[PADL_(unsigned int)]; unsigned int value; char value_r_[PADR_(unsigned int)];
    +};
     struct freebsd32_sigaction_args {
     	char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
     	char act_l_[PADL_(struct sigaction32 *)]; struct sigaction32 * act; char act_r_[PADR_(struct sigaction32 *)];
    @@ -330,6 +341,10 @@ struct freebsd32_umtx_lock_args {
     struct freebsd32_umtx_unlock_args {
     	char umtx_l_[PADL_(struct umtx *)]; struct umtx * umtx; char umtx_r_[PADR_(struct umtx *)];
     };
    +struct freebsd32_ksem_timedwait_args {
    +	char id_l_[PADL_(semid_t)]; semid_t id; char id_r_[PADR_(semid_t)];
    +	char abstime_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * abstime; char abstime_r_[PADR_(const struct timespec32 *)];
    +};
     struct freebsd32_thr_suspend_args {
     	char timeout_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * timeout; char timeout_r_[PADR_(const struct timespec32 *)];
     };
    @@ -344,6 +359,31 @@ struct freebsd32_thr_new_args {
     	char param_l_[PADL_(struct thr_param32 *)]; struct thr_param32 * param; char param_r_[PADR_(struct thr_param32 *)];
     	char param_size_l_[PADL_(int)]; int param_size; char param_size_r_[PADR_(int)];
     };
    +struct freebsd32_kmq_open_args {
    +	char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
    +	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
    +	char mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)];
    +	char attr_l_[PADL_(const struct mq_attr32 *)]; const struct mq_attr32 * attr; char attr_r_[PADR_(const struct mq_attr32 *)];
    +};
    +struct freebsd32_kmq_setattr_args {
    +	char mqd_l_[PADL_(int)]; int mqd; char mqd_r_[PADR_(int)];
    +	char attr_l_[PADL_(const struct mq_attr32 *)]; const struct mq_attr32 * attr; char attr_r_[PADR_(const struct mq_attr32 *)];
    +	char oattr_l_[PADL_(struct mq_attr32 *)]; struct mq_attr32 * oattr; char oattr_r_[PADR_(struct mq_attr32 *)];
    +};
    +struct freebsd32_kmq_timedreceive_args {
    +	char mqd_l_[PADL_(int)]; int mqd; char mqd_r_[PADR_(int)];
    +	char msg_ptr_l_[PADL_(char *)]; char * msg_ptr; char msg_ptr_r_[PADR_(char *)];
    +	char msg_len_l_[PADL_(size_t)]; size_t msg_len; char msg_len_r_[PADR_(size_t)];
    +	char msg_prio_l_[PADL_(unsigned *)]; unsigned * msg_prio; char msg_prio_r_[PADR_(unsigned *)];
    +	char abs_timeout_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * abs_timeout; char abs_timeout_r_[PADR_(const struct timespec32 *)];
    +};
    +struct freebsd32_kmq_timedsend_args {
    +	char mqd_l_[PADL_(int)]; int mqd; char mqd_r_[PADR_(int)];
    +	char msg_ptr_l_[PADL_(const char *)]; const char * msg_ptr; char msg_ptr_r_[PADR_(const char *)];
    +	char msg_len_l_[PADL_(size_t)]; size_t msg_len; char msg_len_r_[PADR_(size_t)];
    +	char msg_prio_l_[PADL_(unsigned)]; unsigned msg_prio; char msg_prio_r_[PADR_(unsigned)];
    +	char abs_timeout_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * abs_timeout; char abs_timeout_r_[PADR_(const struct timespec32 *)];
    +};
     struct freebsd32_aio_fsync_args {
     	char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)];
     	char aiocbp_l_[PADL_(struct aiocb32 *)]; struct aiocb32 * aiocbp; char aiocbp_r_[PADR_(struct aiocb32 *)];
    @@ -581,6 +621,8 @@ int	freebsd32_aio_waitcomplete(struct thread *, struct freebsd32_aio_waitcomplet
     int	freebsd32_kevent(struct thread *, struct freebsd32_kevent_args *);
     int	freebsd32_nmount(struct thread *, struct freebsd32_nmount_args *);
     int	freebsd32_sendfile(struct thread *, struct freebsd32_sendfile_args *);
    +int	freebsd32_ksem_init(struct thread *, struct freebsd32_ksem_init_args *);
    +int	freebsd32_ksem_open(struct thread *, struct freebsd32_ksem_open_args *);
     int	freebsd32_sigaction(struct thread *, struct freebsd32_sigaction_args *);
     int	freebsd32_sigreturn(struct thread *, struct freebsd32_sigreturn_args *);
     int	freebsd32_getcontext(struct thread *, struct freebsd32_getcontext_args *);
    @@ -588,9 +630,14 @@ int	freebsd32_setcontext(struct thread *, struct freebsd32_setcontext_args *);
     int	freebsd32_swapcontext(struct thread *, struct freebsd32_swapcontext_args *);
     int	freebsd32_umtx_lock(struct thread *, struct freebsd32_umtx_lock_args *);
     int	freebsd32_umtx_unlock(struct thread *, struct freebsd32_umtx_unlock_args *);
    +int	freebsd32_ksem_timedwait(struct thread *, struct freebsd32_ksem_timedwait_args *);
     int	freebsd32_thr_suspend(struct thread *, struct freebsd32_thr_suspend_args *);
     int	freebsd32_umtx_op(struct thread *, struct freebsd32_umtx_op_args *);
     int	freebsd32_thr_new(struct thread *, struct freebsd32_thr_new_args *);
    +int	freebsd32_kmq_open(struct thread *, struct freebsd32_kmq_open_args *);
    +int	freebsd32_kmq_setattr(struct thread *, struct freebsd32_kmq_setattr_args *);
    +int	freebsd32_kmq_timedreceive(struct thread *, struct freebsd32_kmq_timedreceive_args *);
    +int	freebsd32_kmq_timedsend(struct thread *, struct freebsd32_kmq_timedsend_args *);
     int	freebsd32_aio_fsync(struct thread *, struct freebsd32_aio_fsync_args *);
     #ifdef PAD64_REQUIRED
     int	freebsd32_pread(struct thread *, struct freebsd32_pread_args *);
    @@ -909,6 +956,8 @@ int	freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_
     #define	FREEBSD32_SYS_AUE_freebsd32_kevent	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_nmount	AUE_NMOUNT
     #define	FREEBSD32_SYS_AUE_freebsd32_sendfile	AUE_SENDFILE
    +#define	FREEBSD32_SYS_AUE_freebsd32_ksem_init	AUE_NULL
    +#define	FREEBSD32_SYS_AUE_freebsd32_ksem_open	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_sigaction	AUE_SIGACTION
     #define	FREEBSD32_SYS_AUE_freebsd32_sigreturn	AUE_SIGRETURN
     #define	FREEBSD32_SYS_AUE_freebsd32_getcontext	AUE_NULL
    @@ -916,9 +965,14 @@ int	freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_
     #define	FREEBSD32_SYS_AUE_freebsd32_swapcontext	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_umtx_lock	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_umtx_unlock	AUE_NULL
    +#define	FREEBSD32_SYS_AUE_freebsd32_ksem_timedwait	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_thr_suspend	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_umtx_op	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_thr_new	AUE_NULL
    +#define	FREEBSD32_SYS_AUE_freebsd32_kmq_open	AUE_NULL
    +#define	FREEBSD32_SYS_AUE_freebsd32_kmq_setattr	AUE_NULL
    +#define	FREEBSD32_SYS_AUE_freebsd32_kmq_timedreceive	AUE_NULL
    +#define	FREEBSD32_SYS_AUE_freebsd32_kmq_timedsend	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_aio_fsync	AUE_NULL
     #define	FREEBSD32_SYS_AUE_freebsd32_pread	AUE_PREAD
     #define	FREEBSD32_SYS_AUE_freebsd32_pwrite	AUE_PWRITE
    diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h
    index a7cd7a00e71..3534701e80b 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: stable/8/sys/compat/freebsd32/syscalls.master 206336 2010-04-07 02:24:41Z nwhitehorn 
    + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 206351 2010-04-07 14:49:35Z kib 
      */
     
     #define	FREEBSD32_SYS_syscall	0
    @@ -303,6 +303,15 @@
     #define	FREEBSD32_SYS_statfs	396
     #define	FREEBSD32_SYS_fstatfs	397
     #define	FREEBSD32_SYS_fhstatfs	398
    +#define	FREEBSD32_SYS_ksem_close	400
    +#define	FREEBSD32_SYS_ksem_post	401
    +#define	FREEBSD32_SYS_ksem_wait	402
    +#define	FREEBSD32_SYS_ksem_trywait	403
    +#define	FREEBSD32_SYS_freebsd32_ksem_init	404
    +#define	FREEBSD32_SYS_freebsd32_ksem_open	405
    +#define	FREEBSD32_SYS_ksem_unlink	406
    +#define	FREEBSD32_SYS_ksem_getvalue	407
    +#define	FREEBSD32_SYS_ksem_destroy	408
     #define	FREEBSD32_SYS_extattr_set_link	412
     #define	FREEBSD32_SYS_extattr_get_link	413
     #define	FREEBSD32_SYS_extattr_delete_link	414
    @@ -325,6 +334,7 @@
     #define	FREEBSD32_SYS_extattr_list_fd	437
     #define	FREEBSD32_SYS_extattr_list_file	438
     #define	FREEBSD32_SYS_extattr_list_link	439
    +#define	FREEBSD32_SYS_freebsd32_ksem_timedwait	441
     #define	FREEBSD32_SYS_freebsd32_thr_suspend	442
     #define	FREEBSD32_SYS_thr_wake	443
     #define	FREEBSD32_SYS_kldunloadf	444
    @@ -340,6 +350,12 @@
     #define	FREEBSD32_SYS_freebsd32_umtx_op	454
     #define	FREEBSD32_SYS_freebsd32_thr_new	455
     #define	FREEBSD32_SYS_sigqueue	456
    +#define	FREEBSD32_SYS_freebsd32_kmq_open	457
    +#define	FREEBSD32_SYS_freebsd32_kmq_setattr	458
    +#define	FREEBSD32_SYS_freebsd32_kmq_timedreceive	459
    +#define	FREEBSD32_SYS_freebsd32_kmq_timedsend	460
    +#define	FREEBSD32_SYS_kmq_notify	461
    +#define	FREEBSD32_SYS_kmq_unlink	462
     #define	FREEBSD32_SYS_abort2	463
     #define	FREEBSD32_SYS_thr_set_name	464
     #define	FREEBSD32_SYS_freebsd32_aio_fsync	465
    diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c
    index 07aad20e0bf..390fc0e71fa 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: stable/8/sys/compat/freebsd32/syscalls.master 206336 2010-04-07 02:24:41Z nwhitehorn 
    + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 206351 2010-04-07 14:49:35Z kib 
      */
     
     const char *freebsd32_syscallnames[] = {
    @@ -410,15 +410,15 @@ const char *freebsd32_syscallnames[] = {
     	"fstatfs",			/* 397 = fstatfs */
     	"fhstatfs",			/* 398 = fhstatfs */
     	"#399",			/* 399 = nosys */
    -	"#400",			/* 400 = ksem_close */
    -	"#401",			/* 401 = ksem_post */
    -	"#402",			/* 402 = ksem_wait */
    -	"#403",			/* 403 = ksem_trywait */
    -	"#404",			/* 404 = ksem_init */
    -	"#405",			/* 405 = ksem_open */
    -	"#406",			/* 406 = ksem_unlink */
    -	"#407",			/* 407 = ksem_getvalue */
    -	"#408",			/* 408 = ksem_destroy */
    +	"ksem_close",			/* 400 = ksem_close */
    +	"ksem_post",			/* 401 = ksem_post */
    +	"ksem_wait",			/* 402 = ksem_wait */
    +	"ksem_trywait",			/* 403 = ksem_trywait */
    +	"freebsd32_ksem_init",			/* 404 = freebsd32_ksem_init */
    +	"freebsd32_ksem_open",			/* 405 = freebsd32_ksem_open */
    +	"ksem_unlink",			/* 406 = ksem_unlink */
    +	"ksem_getvalue",			/* 407 = ksem_getvalue */
    +	"ksem_destroy",			/* 408 = ksem_destroy */
     	"#409",			/* 409 = __mac_get_pid */
     	"#410",			/* 410 = __mac_get_link */
     	"#411",			/* 411 = __mac_set_link */
    @@ -451,7 +451,7 @@ const char *freebsd32_syscallnames[] = {
     	"extattr_list_file",			/* 438 = extattr_list_file */
     	"extattr_list_link",			/* 439 = extattr_list_link */
     	"#440",			/* 440 = kse_switchin */
    -	"#441",			/* 441 = ksem_timedwait */
    +	"freebsd32_ksem_timedwait",			/* 441 = freebsd32_ksem_timedwait */
     	"freebsd32_thr_suspend",			/* 442 = freebsd32_thr_suspend */
     	"thr_wake",			/* 443 = thr_wake */
     	"kldunloadf",			/* 444 = kldunloadf */
    @@ -467,12 +467,12 @@ const char *freebsd32_syscallnames[] = {
     	"freebsd32_umtx_op",			/* 454 = freebsd32_umtx_op */
     	"freebsd32_thr_new",			/* 455 = freebsd32_thr_new */
     	"sigqueue",			/* 456 = sigqueue */
    -	"#457",			/* 457 = kmq_open */
    -	"#458",			/* 458 = kmq_setattr */
    -	"#459",			/* 459 = kmq_timedreceive */
    -	"#460",			/* 460 = kmq_timedsend */
    -	"#461",			/* 461 = kmq_notify */
    -	"#462",			/* 462 = kmq_unlink */
    +	"freebsd32_kmq_open",			/* 457 = freebsd32_kmq_open */
    +	"freebsd32_kmq_setattr",			/* 458 = freebsd32_kmq_setattr */
    +	"freebsd32_kmq_timedreceive",			/* 459 = freebsd32_kmq_timedreceive */
    +	"freebsd32_kmq_timedsend",			/* 460 = freebsd32_kmq_timedsend */
    +	"kmq_notify",			/* 461 = kmq_notify */
    +	"kmq_unlink",			/* 462 = kmq_unlink */
     	"abort2",			/* 463 = abort2 */
     	"thr_set_name",			/* 464 = thr_set_name */
     	"freebsd32_aio_fsync",			/* 465 = freebsd32_aio_fsync */
    diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c
    index 6735d523a33..20cb3f7425a 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: stable/8/sys/compat/freebsd32/syscalls.master 206336 2010-04-07 02:24:41Z nwhitehorn 
    + * created from FreeBSD: stable/8/sys/compat/freebsd32/syscalls.master 206351 2010-04-07 14:49:35Z kib 
      */
     
     #include "opt_compat.h"
    @@ -216,9 +216,9 @@ struct sysent freebsd32_sysent[] = {
     	{ AS(rtprio_args), (sy_call_t *)rtprio, AUE_RTPRIO, NULL, 0, 0, 0 },	/* 166 = rtprio */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 167 = nosys */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 168 = nosys */
    -	{ AS(freebsd32_semsys_args), (sy_call_t *)freebsd32_semsys, AUE_SEMSYS, NULL, 0, 0, 0 },	/* 169 = freebsd32_semsys */
    -	{ AS(freebsd32_msgsys_args), (sy_call_t *)freebsd32_msgsys, AUE_MSGSYS, NULL, 0, 0, 0 },	/* 170 = freebsd32_msgsys */
    -	{ AS(freebsd32_shmsys_args), (sy_call_t *)freebsd32_shmsys, AUE_SHMSYS, NULL, 0, 0, 0 },	/* 171 = freebsd32_shmsys */
    +	{ AS(freebsd32_semsys_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 169 = freebsd32_semsys */
    +	{ AS(freebsd32_msgsys_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 170 = freebsd32_msgsys */
    +	{ AS(freebsd32_shmsys_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 171 = freebsd32_shmsys */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 172 = nosys */
     	{ compat6(AS(freebsd6_freebsd32_pread_args),freebsd32_pread), AUE_PREAD, NULL, 0, 0, 0 },	/* 173 = freebsd6 freebsd32_pread */
     	{ compat6(AS(freebsd6_freebsd32_pwrite_args),freebsd32_pwrite), AUE_PWRITE, NULL, 0, 0, 0 },	/* 174 = freebsd6 freebsd32_pwrite */
    @@ -267,18 +267,18 @@ struct sysent freebsd32_sysent[] = {
     	{ AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 },	/* 217 = lkmnosys */
     	{ AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 },	/* 218 = lkmnosys */
     	{ AS(nosys_args), (sy_call_t *)lkmnosys, AUE_NULL, NULL, 0, 0, 0 },	/* 219 = lkmnosys */
    -	{ compat7(AS(freebsd7_freebsd32_semctl_args),freebsd32_semctl), AUE_SEMCTL, NULL, 0, 0, 0 },	/* 220 = freebsd7 freebsd32_semctl */
    -	{ AS(semget_args), (sy_call_t *)semget, AUE_SEMGET, NULL, 0, 0, 0 },	/* 221 = semget */
    -	{ AS(semop_args), (sy_call_t *)semop, AUE_SEMOP, NULL, 0, 0, 0 },	/* 222 = semop */
    +	{ 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },		/* 220 = freebsd7 freebsd32_semctl */
    +	{ AS(semget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 221 = semget */
    +	{ AS(semop_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 222 = semop */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 223 = semconfig */
    -	{ compat7(AS(freebsd7_freebsd32_msgctl_args),freebsd32_msgctl), AUE_MSGCTL, NULL, 0, 0, 0 },	/* 224 = freebsd7 freebsd32_msgctl */
    -	{ AS(msgget_args), (sy_call_t *)msgget, AUE_MSGGET, NULL, 0, 0, 0 },	/* 225 = msgget */
    -	{ AS(freebsd32_msgsnd_args), (sy_call_t *)freebsd32_msgsnd, AUE_MSGSND, NULL, 0, 0, 0 },	/* 226 = freebsd32_msgsnd */
    -	{ AS(freebsd32_msgrcv_args), (sy_call_t *)freebsd32_msgrcv, AUE_MSGRCV, NULL, 0, 0, 0 },	/* 227 = freebsd32_msgrcv */
    -	{ AS(shmat_args), (sy_call_t *)shmat, AUE_SHMAT, NULL, 0, 0, 0 },	/* 228 = shmat */
    -	{ compat7(AS(freebsd7_freebsd32_shmctl_args),freebsd32_shmctl), AUE_SHMCTL, NULL, 0, 0, 0 },	/* 229 = freebsd7 freebsd32_shmctl */
    -	{ AS(shmdt_args), (sy_call_t *)shmdt, AUE_SHMDT, NULL, 0, 0, 0 },	/* 230 = shmdt */
    -	{ AS(shmget_args), (sy_call_t *)shmget, AUE_SHMGET, NULL, 0, 0, 0 },	/* 231 = shmget */
    +	{ 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },		/* 224 = freebsd7 freebsd32_msgctl */
    +	{ AS(msgget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 225 = msgget */
    +	{ AS(freebsd32_msgsnd_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 226 = freebsd32_msgsnd */
    +	{ AS(freebsd32_msgrcv_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 227 = freebsd32_msgrcv */
    +	{ AS(shmat_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 228 = shmat */
    +	{ 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },		/* 229 = freebsd7 freebsd32_shmctl */
    +	{ AS(shmdt_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 230 = shmdt */
    +	{ AS(shmget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 231 = shmget */
     	{ AS(freebsd32_clock_gettime_args), (sy_call_t *)freebsd32_clock_gettime, AUE_NULL, NULL, 0, 0, 0 },	/* 232 = freebsd32_clock_gettime */
     	{ AS(freebsd32_clock_settime_args), (sy_call_t *)freebsd32_clock_settime, AUE_CLOCK_SETTIME, NULL, 0, 0, 0 },	/* 233 = freebsd32_clock_settime */
     	{ AS(freebsd32_clock_getres_args), (sy_call_t *)freebsd32_clock_getres, AUE_NULL, NULL, 0, 0, 0 },	/* 234 = freebsd32_clock_getres */
    @@ -447,15 +447,15 @@ struct sysent freebsd32_sysent[] = {
     	{ AS(fstatfs_args), (sy_call_t *)fstatfs, AUE_FSTATFS, NULL, 0, 0, 0 },	/* 397 = fstatfs */
     	{ AS(fhstatfs_args), (sy_call_t *)fhstatfs, AUE_FHSTATFS, NULL, 0, 0, 0 },	/* 398 = fhstatfs */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 399 = nosys */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 400 = ksem_close */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 401 = ksem_post */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 402 = ksem_wait */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 403 = ksem_trywait */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 404 = ksem_init */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 405 = ksem_open */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 406 = ksem_unlink */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 407 = ksem_getvalue */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 408 = ksem_destroy */
    +	{ AS(ksem_close_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 400 = ksem_close */
    +	{ AS(ksem_post_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 401 = ksem_post */
    +	{ AS(ksem_wait_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 402 = ksem_wait */
    +	{ AS(ksem_trywait_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 403 = ksem_trywait */
    +	{ AS(freebsd32_ksem_init_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 404 = freebsd32_ksem_init */
    +	{ AS(freebsd32_ksem_open_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 405 = freebsd32_ksem_open */
    +	{ AS(ksem_unlink_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 406 = ksem_unlink */
    +	{ AS(ksem_getvalue_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 407 = ksem_getvalue */
    +	{ AS(ksem_destroy_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 408 = ksem_destroy */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 409 = __mac_get_pid */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 410 = __mac_get_link */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 411 = __mac_set_link */
    @@ -488,7 +488,7 @@ struct sysent freebsd32_sysent[] = {
     	{ AS(extattr_list_file_args), (sy_call_t *)extattr_list_file, AUE_EXTATTR_LIST_FILE, NULL, 0, 0, 0 },	/* 438 = extattr_list_file */
     	{ AS(extattr_list_link_args), (sy_call_t *)extattr_list_link, AUE_EXTATTR_LIST_LINK, NULL, 0, 0, 0 },	/* 439 = extattr_list_link */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 440 = kse_switchin */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 441 = ksem_timedwait */
    +	{ AS(freebsd32_ksem_timedwait_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 441 = freebsd32_ksem_timedwait */
     	{ AS(freebsd32_thr_suspend_args), (sy_call_t *)freebsd32_thr_suspend, AUE_NULL, NULL, 0, 0, 0 },	/* 442 = freebsd32_thr_suspend */
     	{ AS(thr_wake_args), (sy_call_t *)thr_wake, AUE_NULL, NULL, 0, 0, 0 },	/* 443 = thr_wake */
     	{ AS(kldunloadf_args), (sy_call_t *)kldunloadf, AUE_MODUNLOAD, NULL, 0, 0, 0 },	/* 444 = kldunloadf */
    @@ -504,12 +504,12 @@ struct sysent freebsd32_sysent[] = {
     	{ AS(freebsd32_umtx_op_args), (sy_call_t *)freebsd32_umtx_op, AUE_NULL, NULL, 0, 0, 0 },	/* 454 = freebsd32_umtx_op */
     	{ AS(freebsd32_thr_new_args), (sy_call_t *)freebsd32_thr_new, AUE_NULL, NULL, 0, 0, 0 },	/* 455 = freebsd32_thr_new */
     	{ AS(sigqueue_args), (sy_call_t *)sigqueue, AUE_NULL, NULL, 0, 0, 0 },	/* 456 = sigqueue */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 457 = kmq_open */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 458 = kmq_setattr */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 459 = kmq_timedreceive */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 460 = kmq_timedsend */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 461 = kmq_notify */
    -	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 462 = kmq_unlink */
    +	{ AS(freebsd32_kmq_open_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 457 = freebsd32_kmq_open */
    +	{ AS(freebsd32_kmq_setattr_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 458 = freebsd32_kmq_setattr */
    +	{ AS(freebsd32_kmq_timedreceive_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 459 = freebsd32_kmq_timedreceive */
    +	{ AS(freebsd32_kmq_timedsend_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 460 = freebsd32_kmq_timedsend */
    +	{ AS(kmq_notify_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 461 = kmq_notify */
    +	{ AS(kmq_unlink_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 462 = kmq_unlink */
     	{ AS(abort2_args), (sy_call_t *)abort2, AUE_NULL, NULL, 0, 0, 0 },	/* 463 = abort2 */
     	{ AS(thr_set_name_args), (sy_call_t *)thr_set_name, AUE_NULL, NULL, 0, 0, 0 },	/* 464 = thr_set_name */
     	{ AS(freebsd32_aio_fsync_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 465 = freebsd32_aio_fsync */
    @@ -570,9 +570,9 @@ struct sysent freebsd32_sysent[] = {
     	{ AS(freebsd32_jail_set_args), (sy_call_t *)freebsd32_jail_set, AUE_NULL, NULL, 0, 0, 0 },	/* 507 = freebsd32_jail_set */
     	{ AS(jail_remove_args), (sy_call_t *)jail_remove, AUE_NULL, NULL, 0, 0, 0 },	/* 508 = jail_remove */
     	{ AS(closefrom_args), (sy_call_t *)closefrom, AUE_CLOSEFROM, NULL, 0, 0, 0 },	/* 509 = closefrom */
    -	{ AS(freebsd32_semctl_args), (sy_call_t *)freebsd32_semctl, AUE_SEMCTL, NULL, 0, 0, 0 },	/* 510 = freebsd32_semctl */
    -	{ AS(freebsd32_msgctl_args), (sy_call_t *)freebsd32_msgctl, AUE_MSGCTL, NULL, 0, 0, 0 },	/* 511 = freebsd32_msgctl */
    -	{ AS(freebsd32_shmctl_args), (sy_call_t *)freebsd32_shmctl, AUE_SHMCTL, NULL, 0, 0, 0 },	/* 512 = freebsd32_shmctl */
    +	{ AS(freebsd32_semctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 510 = freebsd32_semctl */
    +	{ AS(freebsd32_msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 511 = freebsd32_msgctl */
    +	{ AS(freebsd32_shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0 },	/* 512 = freebsd32_shmctl */
     	{ AS(lpathconf_args), (sy_call_t *)lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0 },	/* 513 = lpathconf */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 514 = cap_new */
     	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 },			/* 515 = cap_getrights */
    
    From 0a6281552473152f11f47df8de6cdb33c1b3b834 Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Wed, 7 Apr 2010 14:59:07 +0000
    Subject: [PATCH 1909/2592] MFC r205986:  Constify vap argument of
     ieee80211_{note,discard}* functions.
    
    ---
     sys/net80211/ieee80211_input.c | 15 ++++++++-------
     sys/net80211/ieee80211_var.h   | 12 ++++++------
     2 files changed, 14 insertions(+), 13 deletions(-)
    
    diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
    index e701cb5eba1..28a58fe06b3 100644
    --- a/sys/net80211/ieee80211_input.c
    +++ b/sys/net80211/ieee80211_input.c
    @@ -734,7 +734,8 @@ ieee80211_ssid_mismatch(struct ieee80211vap *vap, const char *tag,
      * Return the bssid of a frame.
      */
     static const uint8_t *
    -ieee80211_getbssid(struct ieee80211vap *vap, const struct ieee80211_frame *wh)
    +ieee80211_getbssid(const struct ieee80211vap *vap,
    +	const struct ieee80211_frame *wh)
     {
     	if (vap->iv_opmode == IEEE80211_M_STA)
     		return wh->i_addr2;
    @@ -748,7 +749,7 @@ ieee80211_getbssid(struct ieee80211vap *vap, const struct ieee80211_frame *wh)
     #include 
     
     void
    -ieee80211_note(struct ieee80211vap *vap, const char *fmt, ...)
    +ieee80211_note(const struct ieee80211vap *vap, const char *fmt, ...)
     {
     	char buf[128];		/* XXX */
     	va_list ap;
    @@ -761,7 +762,7 @@ ieee80211_note(struct ieee80211vap *vap, const char *fmt, ...)
     }
     
     void
    -ieee80211_note_frame(struct ieee80211vap *vap,
    +ieee80211_note_frame(const struct ieee80211vap *vap,
     	const struct ieee80211_frame *wh,
     	const char *fmt, ...)
     {
    @@ -776,7 +777,7 @@ ieee80211_note_frame(struct ieee80211vap *vap,
     }
     
     void
    -ieee80211_note_mac(struct ieee80211vap *vap,
    +ieee80211_note_mac(const struct ieee80211vap *vap,
     	const uint8_t mac[IEEE80211_ADDR_LEN],
     	const char *fmt, ...)
     {
    @@ -790,7 +791,7 @@ ieee80211_note_mac(struct ieee80211vap *vap,
     }
     
     void
    -ieee80211_discard_frame(struct ieee80211vap *vap,
    +ieee80211_discard_frame(const struct ieee80211vap *vap,
     	const struct ieee80211_frame *wh,
     	const char *type, const char *fmt, ...)
     {
    @@ -811,7 +812,7 @@ ieee80211_discard_frame(struct ieee80211vap *vap,
     }
     
     void
    -ieee80211_discard_ie(struct ieee80211vap *vap,
    +ieee80211_discard_ie(const struct ieee80211vap *vap,
     	const struct ieee80211_frame *wh,
     	const char *type, const char *fmt, ...)
     {
    @@ -830,7 +831,7 @@ ieee80211_discard_ie(struct ieee80211vap *vap,
     }
     
     void
    -ieee80211_discard_mac(struct ieee80211vap *vap,
    +ieee80211_discard_mac(const struct ieee80211vap *vap,
     	const uint8_t mac[IEEE80211_ADDR_LEN],
     	const char *type, const char *fmt, ...)
     {
    diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
    index 3d23f4780d0..1a58cac4feb 100644
    --- a/sys/net80211/ieee80211_var.h
    +++ b/sys/net80211/ieee80211_var.h
    @@ -848,10 +848,10 @@ ieee80211_htchanflags(const struct ieee80211_channel *c)
     	if (ieee80211_msg(_vap, _m))					\
     		ieee80211_note_frame(_vap, _wh, _fmt, __VA_ARGS__);	\
     } while (0)
    -void	ieee80211_note(struct ieee80211vap *, const char *, ...);
    -void	ieee80211_note_mac(struct ieee80211vap *,
    +void	ieee80211_note(const struct ieee80211vap *, const char *, ...);
    +void	ieee80211_note_mac(const struct ieee80211vap *,
     		const uint8_t mac[IEEE80211_ADDR_LEN], const char *, ...);
    -void	ieee80211_note_frame(struct ieee80211vap *,
    +void	ieee80211_note_frame(const struct ieee80211vap *,
     		const struct ieee80211_frame *, const char *, ...);
     #define	ieee80211_msg_debug(_vap) \
     	((_vap)->iv_debug & IEEE80211_MSG_DEBUG)
    @@ -889,11 +889,11 @@ void	ieee80211_note_frame(struct ieee80211vap *,
     		ieee80211_discard_mac(_vap, _mac, _type, _fmt, __VA_ARGS__);\
     } while (0)
     
    -void ieee80211_discard_frame(struct ieee80211vap *,
    +void ieee80211_discard_frame(const struct ieee80211vap *,
     	const struct ieee80211_frame *, const char *type, const char *fmt, ...);
    -void ieee80211_discard_ie(struct ieee80211vap *,
    +void ieee80211_discard_ie(const struct ieee80211vap *,
     	const struct ieee80211_frame *, const char *type, const char *fmt, ...);
    -void ieee80211_discard_mac(struct ieee80211vap *,
    +void ieee80211_discard_mac(const struct ieee80211vap *,
     	const uint8_t mac[IEEE80211_ADDR_LEN], const char *type,
     	const char *fmt, ...);
     #else
    
    From 0bbe1d9baa5b87b5df3aad9de1890b772be256a5 Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Wed, 7 Apr 2010 15:19:52 +0000
    Subject: [PATCH 1910/2592] MFC: r205572 Fix the experimental NFS subsystem so
     that it uses the correct preprocessor macro name for not requiring strict
     data alignment.
    
    ---
     sys/fs/nfs/nfs_commonport.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
    index bf982aa0c0e..c9ae4a820a1 100644
    --- a/sys/fs/nfs/nfs_commonport.c
    +++ b/sys/fs/nfs/nfs_commonport.c
    @@ -117,7 +117,7 @@ struct mtx nfs_slock_mutex;
     /* local functions */
     static int nfssvc_call(struct thread *, struct nfssvc_args *, struct ucred *);
     
    -#if defined(__i386__)
    +#ifdef __NO_STRICT_ALIGNMENT
     /*
      * These architectures don't need re-alignment, so just return.
      */
    @@ -127,7 +127,7 @@ newnfs_realign(struct mbuf **pm)
     
     	return;
     }
    -#else
    +#else	/* !__NO_STRICT_ALIGNMENT */
     /*
      *	newnfs_realign:
      *
    @@ -185,7 +185,7 @@ newnfs_realign(struct mbuf **pm)
     		pm = &m->m_next;
     	}
     }
    -#endif	/* !__i386__ */
    +#endif	/* __NO_STRICT_ALIGNMENT */
     
     #ifdef notdef
     static void
    
    From 81b67791ee94f400d689dfc030dd0f82d248dd95 Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Wed, 7 Apr 2010 17:58:29 +0000
    Subject: [PATCH 1911/2592] This is an MFC of 205993
    
    For unhandled actions in xpt_action_default, remember to call
    xpt_done for queued requests. This solves the problem of
    indefinite hangs for unspecified transports when XPT_SCAN_BUS
    is called.
    
    A few minor cosmetics elsewhere.
    ---
     sys/cam/cam_xpt.c | 7 +++++--
     1 file changed, 5 insertions(+), 2 deletions(-)
    
    diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
    index 560ccfd480b..613542705f0 100644
    --- a/sys/cam/cam_xpt.c
    +++ b/sys/cam/cam_xpt.c
    @@ -2375,6 +2375,7 @@ xpt_action_default(union ccb *start_ccb)
     		if (start_ccb->ccb_h.func_code == XPT_ATA_IO) {
     			start_ccb->ataio.resid = 0;
     		}
    +		/* FALLTHROUGH */
     	case XPT_RESET_DEV:
     	case XPT_ENG_EXEC:
     	{
    @@ -2883,6 +2884,9 @@ xpt_action_default(union ccb *start_ccb)
     	case XPT_ENG_INQ:
     		/* XXX Implement */
     		start_ccb->ccb_h.status = CAM_PROVIDE_FAIL;
    +		if (start_ccb->ccb_h.func_code & XPT_FC_DEV_QUEUED) {
    +			xpt_done(start_ccb);
    +		}
     		break;
     	}
     }
    @@ -3925,7 +3929,7 @@ xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus,
     		      struct cam_et *target, struct cam_ed *device,
     		      void *async_arg)
     {
    -	printf("xpt_dev_async called\n");
    +	printf("%s called\n", __func__);
     }
     
     u_int32_t
    @@ -4827,4 +4831,3 @@ camisr_runqueue(void *V_queue)
     		(*ccb_h->cbfcnp)(ccb_h->path->periph, (union ccb *)ccb_h);
     	}
     }
    -
    
    From 362fb32a52b954e068ab132335ddb5a55f431c9a Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Wed, 7 Apr 2010 19:04:36 +0000
    Subject: [PATCH 1912/2592] MFC r200028, r201193, r201752, r201930, r202460,
     r200672, r206375: Unify rc.firewall and rc.firewall6, and obsolete
     rc.firewall6 and rc.d/ip6fw.
    
    ---
     ObsoleteFiles.inc    |   3 +
     UPDATING             |  13 ++
     etc/Makefile         |   2 +-
     etc/defaults/rc.conf |  20 +--
     etc/rc.d/Makefile    |   2 +-
     etc/rc.d/ip6fw       |  48 -------
     etc/rc.d/ipfw        |  13 +-
     etc/rc.firewall      | 145 +++++++++++++++++++--
     etc/rc.firewall6     | 295 -------------------------------------------
     9 files changed, 177 insertions(+), 364 deletions(-)
     delete mode 100755 etc/rc.d/ip6fw
     delete mode 100644 etc/rc.firewall6
    
    diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
    index 4e6d408ca60..9edd071e9e3 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.
     #
     
    +# 20100408: unify rc.firewall and rc.firewall6.
    +OLD_FILES+=etc/rc.d/ip6fw
    +OLD_FILES+=etc/rc.firewall6
     # 20100330: [ia64] Sync with 9-current
     .if ${TARGET_ARCH} == "ia64"
     OLD_FILES+=usr/include/machine/nexusvar.h
    diff --git a/UPDATING b/UPDATING
    index 9ba6b287c18..2bd2b6f63d0 100644
    --- a/UPDATING
    +++ b/UPDATING
    @@ -15,6 +15,19 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
     	debugging tools present in HEAD were left in place because
     	sun4v support still needs work to become production ready.
     
    +20100408:
    +	The rc.firewall and rc.firewall6 were unified, and
    +	rc.firewall6 and rc.d/ip6fw were removed.
    +	According to the removal of rc.d/ip6fw, ipv6_firewall_* rc
    +	variables are obsoleted.  Instead, the following new rc
    +	variables are added to rc.d/ipfw:
    +
    +		firewall_client_net_ipv6, firewall_simple_iif_ipv6,
    +		firewall_simple_inet_ipv6, firewall_simple_oif_ipv6,
    +		firewall_simple_onet_ipv6
    +
    +	The meanings correspond to the relevant IPv4 variables.
    +
     20100406:
     	The kernel option COMPAT_IA32 has been replaced with COMPAT_FREEBSD32
     	to allow 32-bit compatibility on non-x86 platforms. All kernel
    diff --git a/etc/Makefile b/etc/Makefile
    index 23bc526da05..36828e82a43 100644
    --- a/etc/Makefile
    +++ b/etc/Makefile
    @@ -15,7 +15,7 @@ BIN1=	auth.conf \
     	inetd.conf libalias.conf login.access login.conf mac.conf motd \
     	netconfig network.subr networks newsyslog.conf nsswitch.conf \
     	phones profile protocols \
    -	rc rc.bsdextended rc.firewall rc.firewall6 rc.initdiskless \
    +	rc rc.bsdextended rc.firewall rc.initdiskless \
     	rc.sendmail rc.shutdown \
     	rc.subr remote rpc services shells \
     	sysctl.conf syslog.conf \
    diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
    index 1cd4904f1b9..c9bea689974 100644
    --- a/etc/defaults/rc.conf
    +++ b/etc/defaults/rc.conf
    @@ -120,7 +120,10 @@ firewall_logging="NO"		# Set to YES to enable events logging
     firewall_flags=""		# Flags passed to ipfw when type is a file
     firewall_coscripts=""		# List of executables/scripts to run after
     				# firewall starts/stops
    -firewall_client_net="192.0.2.0/24" # Network address for "client" firewall.
    +firewall_client_net="192.0.2.0/24" # IPv4 Network address for "client"
    +				# firewall.
    +#firewall_client_net_ipv6="2001:db8:2:1::/64" # IPv6 network prefix for
    +				# "client" firewall.
     firewall_simple_iif="ed1"	# Inside network interface for "simple"
     				# firewall.
     firewall_simple_inet="192.0.2.16/28" # Inside network address for "simple"
    @@ -129,6 +132,14 @@ firewall_simple_oif="ed0"	# Outside network interface for "simple"
     				# firewall.
     firewall_simple_onet="192.0.2.0/28" # Outside network address for "simple"
     				# firewall.
    +#firewall_simple_iif_ipv6="ed1"	# Inside IPv6 network interface for "simple"
    +				# firewall.
    +#firewall_simple_inet_ipv6="2001:db8:2:800::/56" # Inside IPv6 network prefix
    +				# for "simple" firewall.
    +#firewall_simple_oif_ipv6="ed0"	# Outside IPv6 network interface for "simple"
    +				# firewall.
    +#firewall_simple_onet_ipv6="2001:db8:2:0::/56" # Outside IPv6 network prefix
    +				# for "simple" firewall.
     firewall_myservices=""		# List of TCP ports on which this host
     				# offers services for "workstation" firewall.
     firewall_allowservices=""	# List of IPs which have access to
    @@ -479,13 +490,6 @@ ipv6_faith_prefix="NO"		# Set faith prefix to enable a FAITH
     				# faithd(8) setup.
     ipv6_ipv4mapping="NO"		# Set to "YES" to enable IPv4 mapped IPv6 addr
     				# communication. (like ::ffff:a.b.c.d)
    -ipv6_firewall_enable="NO"	# Set to YES to enable IPv6 firewall
    -				# functionality
    -ipv6_firewall_script="/etc/rc.firewall6" # Which script to run to set up the IPv6 firewall
    -ipv6_firewall_type="UNKNOWN"	# IPv6 Firewall type (see /etc/rc.firewall6)
    -ipv6_firewall_quiet="NO"	# Set to YES to suppress rule display
    -ipv6_firewall_logging="NO"	# Set to YES to enable events logging
    -ipv6_firewall_flags=""		# Flags passed to ip6fw when type is a file
     ipv6_ipfilter_rules="/etc/ipf6.rules"	# rules definition file for ipfilter,
     					# see /usr/src/contrib/ipfilter/rules
     					# for examples
    diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile
    index 49010e5e2c9..6c12ad0844e 100755
    --- a/etc/rc.d/Makefile
    +++ b/etc/rc.d/Makefile
    @@ -15,7 +15,7 @@ FILES=	DAEMON FILESYSTEMS LOGIN NETWORKING SERVERS \
     	hcsecd \
     	hostapd hostid hostid_save hostname \
     	inetd initrandom \
    -	ip6addrctl ip6fw ipfilter ipfs ipfw ipmon \
    +	ip6addrctl ipfilter ipfs ipfw ipmon \
     	ipnat ipsec ipxrouted \
     	jail \
     	kadmind kerberos keyserv kldxref kpasswdd \
    diff --git a/etc/rc.d/ip6fw b/etc/rc.d/ip6fw
    deleted file mode 100755
    index ca95d368a2f..00000000000
    --- a/etc/rc.d/ip6fw
    +++ /dev/null
    @@ -1,48 +0,0 @@
    -#!/bin/sh
    -#
    -# $FreeBSD$
    -#
    -
    -# PROVIDE: ip6fw
    -# REQUIRE: routing
    -# KEYWORD: nojail
    -
    -. /etc/rc.subr
    -
    -name="ip6fw"
    -rcvar=`set_rcvar ipv6_firewall`
    -start_cmd="ip6fw_start"
    -stop_cmd="${SYSCTL_W} net.inet6.ip6.fw.enable=0"
    -required_modules="ipfw"
    -
    -ip6fw_start()
    -{
    -	# Specify default rules file if none provided
    -	if [ -z "${ipv6_firewall_script}" ]; then
    -		ipv6_firewall_script=/etc/rc.firewall6
    -	fi
    -
    -	# Load rules
    -	#
    -	if [ -r "${ipv6_firewall_script}" ]; then
    -		/bin/sh "${ipv6_firewall_script}"
    -		echo 'IPv6 Firewall rules loaded.'
    -	elif [ "`ipfw show 65535`" = "65535 deny ip from any to any" ]; then
    -		warn 'IPv6 firewall rules have not been loaded. Default' \
    -		    ' to DENY all access.'
    -	fi
    -
    -	# Enable firewall logging
    -	#
    -	if checkyesno ipv6_firewall_logging; then
    -		echo 'IPv6 Firewall logging=YES'
    -		sysctl net.inet.ip.fw.verbose=1 >/dev/null
    -	fi
    -
    -	# Enable the firewall
    -	#
    -	${SYSCTL_W} net.inet6.ip6.fw.enable=1
    -}
    -
    -load_rc_config $name
    -run_rc_command "$1"
    diff --git a/etc/rc.d/ipfw b/etc/rc.d/ipfw
    index 28e59d8cf11..689905d9e4a 100755
    --- a/etc/rc.d/ipfw
    +++ b/etc/rc.d/ipfw
    @@ -18,6 +18,8 @@ start_postcmd="ipfw_poststart"
     stop_cmd="ipfw_stop"
     required_modules="ipfw"
     
    +set_rcvar_obsolete ipv6_firewall_enable
    +
     ipfw_prestart()
     {
     	if checkyesno dummynet_enable; then
    @@ -72,7 +74,13 @@ ipfw_poststart()
     	# Enable the firewall
     	#
     	if ! ${SYSCTL_W} net.inet.ip.fw.enable=1 1>/dev/null 2>&1; then
    -		warn "failed to enable firewall"
    +		warn "failed to enable IPv4 firewall"
    +	fi
    +	if afexists inet6; then
    +		if ! ${SYSCTL_W} net.inet6.ip6.fw.enable=1 1>/dev/null 2>&1
    +		then
    +			warn "failed to enable IPv6 firewall"
    +		fi
     	fi
     }
     
    @@ -83,6 +91,9 @@ ipfw_stop()
     	# Disable the firewall
     	#
     	${SYSCTL_W} net.inet.ip.fw.enable=0
    +	if afexists inet6; then
    +		${SYSCTL_W} net.inet6.ip6.fw.enable=0
    +	fi
     
     	# Stop firewall coscripts
     	#
    diff --git a/etc/rc.firewall b/etc/rc.firewall
    index bc700d1f8b2..d8f50af6c2b 100644
    --- a/etc/rc.firewall
    +++ b/etc/rc.firewall
    @@ -85,12 +85,42 @@ setup_loopback () {
     	${fwcmd} add 100 pass all from any to any via lo0
     	${fwcmd} add 200 deny all from any to 127.0.0.0/8
     	${fwcmd} add 300 deny ip from 127.0.0.0/8 to any
    +	if [ $ipv6_available -eq 0 ]; then
    +		${fwcmd} add 400 deny all from any to ::1
    +		${fwcmd} add 500 deny all from ::1 to any
    +	fi
    +}
    +
    +setup_ipv6_mandatory () {
    +	[ $ipv6_available -eq 0 ] || return 0
    +
    +	############
    +	# Only in rare cases do you want to change these rules
    +	#
    +	# ND
    +	#
    +	# DAD
    +	${fwcmd} add pass ipv6-icmp from :: to ff02::/16
    +	# RS, RA, NS, NA, redirect...
    +	${fwcmd} add pass ipv6-icmp from fe80::/10 to fe80::/10
    +	${fwcmd} add pass ipv6-icmp from fe80::/10 to ff02::/16
    +
    +	# Allow ICMPv6 destination unreach
    +	${fwcmd} add pass ipv6-icmp from any to any icmp6types 1
    +
    +	# Allow NS/NA/toobig (don't filter it out)
    +	${fwcmd} add pass ipv6-icmp from any to any icmp6types 2,135,136
     }
     
     if [ -n "${1}" ]; then
     	firewall_type="${1}"
     fi
     
    +. /etc/rc.subr
    +. /etc/network.subr
    +afexists inet6
    +ipv6_available=$?
    +
     ############
     # Set quiet mode if requested
     #
    @@ -109,6 +139,7 @@ esac
     ${fwcmd} -f flush
     
     setup_loopback
    +setup_ipv6_mandatory
     
     ############
     # Network Address Translation.  All packets are passed to natd(8)
    @@ -166,11 +197,13 @@ case ${firewall_type} in
     	# against people from outside your own network.
     	#
     	# Configuration:
    -	#  firewall_client_net:		Network address of local network.
    +	#  firewall_client_net:		Network address of local IPv4 network.
    +	#  firewall_client_net_ipv6:	Network address of local IPv6 network.
     	############
     
     	# set this to your local network
     	net="$firewall_client_net"
    +	net6="$firewall_client_net_ipv6"
     
     	# Allow limited broadcast traffic from my own net.
     	${fwcmd} add pass all from ${net} to 255.255.255.255
    @@ -178,6 +211,18 @@ case ${firewall_type} in
     	# Allow any traffic to or from my own net.
     	${fwcmd} add pass all from me to ${net}
     	${fwcmd} add pass all from ${net} to me
    +	if [ -n "$net6" ]; then
    +		${fwcmd} add pass all from me to ${net6}
    +		${fwcmd} add pass all from ${net6} to me
    +	fi
    +
    +	if [ -n "$net6" ]; then
    +		# Allow any link-local multicast traffic
    +		${fwcmd} add pass all from fe80::/10 to ff02::/16
    +		${fwcmd} add pass all from ${net6} to ff02::/16
    +		# Allow DHCPv6
    +		${fwcmd} add pass udp from fe80::/10 to me 546
    +	fi
     
     	# Allow TCP through if setup succeeded
     	${fwcmd} add pass tcp from any to any established
    @@ -212,23 +257,38 @@ case ${firewall_type} in
     	# on the inside at this machine for those services.
     	#
     	# Configuration:
    -	#  firewall_simple_iif:		Inside network interface.
    -	#  firewall_simple_inet:	Inside network address.
    -	#  firewall_simple_oif:		Outside network interface.
    -	#  firewall_simple_onet:	Outside network address.
    +	#  firewall_simple_iif:		Inside IPv4 network interface.
    +	#  firewall_simple_inet:	Inside IPv4 network address.
    +	#  firewall_simple_oif:		Outside IPv4 network interface.
    +	#  firewall_simple_onet:	Outside IPv4 network address.
    +	#  firewall_simple_iif_ipv6:	Inside IPv6 network interface.
    +	#  firewall_simple_inet_ipv6:	Inside IPv6 network prefix.
    +	#  firewall_simple_oif_ipv6:	Outside IPv6 network interface.
    +	#  firewall_simple_onet_ipv6:	Outside IPv6 network prefix.
     	############
     
     	# set these to your outside interface network
     	oif="$firewall_simple_oif"
     	onet="$firewall_simple_onet"
    +	oif6="${firewall_simple_oif_ipv6:-$firewall_simple_oif}"
    +	onet6="$firewall_simple_onet_ipv6"
     
     	# set these to your inside interface network
     	iif="$firewall_simple_iif"
     	inet="$firewall_simple_inet"
    +	iif6="${firewall_simple_iif_ipv6:-$firewall_simple_iif}"
    +	inet6="$firewall_simple_inet_ipv6"
     
     	# Stop spoofing
     	${fwcmd} add deny all from ${inet} to any in via ${oif}
     	${fwcmd} add deny all from ${onet} to any in via ${iif}
    +	if [ -n "$inet6" ]; then
    +		${fwcmd} add deny all from ${inet6} to any in via ${oif6}
    +		if [ -n "$onet6" ]; then
    +			${fwcmd} add deny all from ${onet6} to any in \
    +			    via ${iif6}
    +		fi
    +	fi
     
     	# Stop RFC1918 nets on the outside interface
     	${fwcmd} add deny all from any to 10.0.0.0/8 via ${oif}
    @@ -254,7 +314,7 @@ case ${firewall_type} in
     	case ${natd_enable} in
     	[Yy][Ee][Ss])
     		if [ -n "${natd_interface}" ]; then
    -			${fwcmd} add divert natd all from any to any via ${natd_interface}
    +			${fwcmd} add divert natd ip4 from any to any via ${natd_interface}
     		fi
     		;;
     	esac
    @@ -273,6 +333,55 @@ case ${firewall_type} in
     	${fwcmd} add deny all from 224.0.0.0/4 to any via ${oif}
     	${fwcmd} add deny all from 240.0.0.0/4 to any via ${oif}
     
    +	if [ -n "$inet6" ]; then
    +		# Stop unique local unicast address on the outside interface
    +		${fwcmd} add deny all from fc00::/7 to any via ${oif6}
    +		${fwcmd} add deny all from any to fc00::/7 via ${oif6}
    +
    +		# Stop site-local on the outside interface
    +		${fwcmd} add deny all from fec0::/10 to any via ${oif6}
    +		${fwcmd} add deny all from any to fec0::/10 via ${oif6}
    +
    +		# Disallow "internal" addresses to appear on the wire.
    +		${fwcmd} add deny all from ::ffff:0.0.0.0/96 to any \
    +		    via ${oif6}
    +		${fwcmd} add deny all from any to ::ffff:0.0.0.0/96 \
    +		    via ${oif6}
    +
    +		# Disallow packets to malicious IPv4 compatible prefix.
    +		${fwcmd} add deny all from ::224.0.0.0/100 to any via ${oif6}
    +		${fwcmd} add deny all from any to ::224.0.0.0/100 via ${oif6}
    +		${fwcmd} add deny all from ::127.0.0.0/104 to any via ${oif6}
    +		${fwcmd} add deny all from any to ::127.0.0.0/104 via ${oif6}
    +		${fwcmd} add deny all from ::0.0.0.0/104 to any via ${oif6}
    +		${fwcmd} add deny all from any to ::0.0.0.0/104 via ${oif6}
    +		${fwcmd} add deny all from ::255.0.0.0/104 to any via ${oif6}
    +		${fwcmd} add deny all from any to ::255.0.0.0/104 via ${oif6}
    +
    +		${fwcmd} add deny all from ::0.0.0.0/96 to any via ${oif6}
    +		${fwcmd} add deny all from any to ::0.0.0.0/96 via ${oif6}
    +
    +		# Disallow packets to malicious 6to4 prefix.
    +		${fwcmd} add deny all from 2002:e000::/20 to any via ${oif6}
    +		${fwcmd} add deny all from any to 2002:e000::/20 via ${oif6}
    +		${fwcmd} add deny all from 2002:7f00::/24 to any via ${oif6}
    +		${fwcmd} add deny all from any to 2002:7f00::/24 via ${oif6}
    +		${fwcmd} add deny all from 2002:0000::/24 to any via ${oif6}
    +		${fwcmd} add deny all from any to 2002:0000::/24 via ${oif6}
    +		${fwcmd} add deny all from 2002:ff00::/24 to any via ${oif6}
    +		${fwcmd} add deny all from any to 2002:ff00::/24 via ${oif6}
    +
    +		${fwcmd} add deny all from 2002:0a00::/24 to any via ${oif6}
    +		${fwcmd} add deny all from any to 2002:0a00::/24 via ${oif6}
    +		${fwcmd} add deny all from 2002:ac10::/28 to any via ${oif6}
    +		${fwcmd} add deny all from any to 2002:ac10::/28 via ${oif6}
    +		${fwcmd} add deny all from 2002:c0a8::/32 to any via ${oif6}
    +		${fwcmd} add deny all from any to 2002:c0a8::/32 via ${oif6}
    +
    +		${fwcmd} add deny all from ff05::/16 to any via ${oif6}
    +		${fwcmd} add deny all from any to ff05::/16 via ${oif6}
    +	fi
    +
     	# Allow TCP through if setup succeeded
     	${fwcmd} add pass tcp from any to any established
     
    @@ -291,7 +400,11 @@ case ${firewall_type} in
     	${fwcmd} add pass tcp from any to me 80 setup
     
     	# Reject&Log all setup of incoming connections from the outside
    -	${fwcmd} add deny log tcp from any to any in via ${oif} setup
    +	${fwcmd} add deny log ip4 from any to any in via ${oif} setup proto tcp
    +	if [ -n "$inet6" ]; then
    +		${fwcmd} add deny log ip6 from any to any in via ${oif6} \
    +		    setup proto tcp
    +	fi
     
     	# Allow setup of any other TCP connection
     	${fwcmd} add pass tcp from any to any setup
    @@ -324,7 +437,7 @@ case ${firewall_type} in
     	#  firewall_nologports:		List of TCP/UDP ports for which
     	#				 denied incomming packets are not
     	#				 logged.
    -	
    +
     	# Allow packets for which a state has been built.
     	${fwcmd} add check-state
     
    @@ -335,18 +448,30 @@ case ${firewall_type} in
     	${fwcmd} add pass tcp  from me to any setup keep-state
     	${fwcmd} add pass udp  from me to any       keep-state
     	${fwcmd} add pass icmp from me to any       keep-state
    +	if [ $ipv6_available -eq 0 ]; then
    +		${fwcmd} add pass ipv6-icmp from me to any keep-state
    +	fi
     
     	# Allow DHCP.
     	${fwcmd} add pass udp  from 0.0.0.0 68 to 255.255.255.255 67 out
     	${fwcmd} add pass udp  from any 67     to me 68 in
     	${fwcmd} add pass udp  from any 67     to 255.255.255.255 68 in
    +	if [ $ipv6_available -eq 0 ]; then
    +		${fwcmd} add pass udp from fe80::/10 to me 546 in
    +	fi
     	# Some servers will ping the IP while trying to decide if it's 
     	# still in use.
     	${fwcmd} add pass icmp from any to any icmptype 8
    +	if [ $ipv6_available -eq 0 ]; then
    +		${fwcmd} add pass ipv6-icmp from any to any icmp6type 128,129
    +	fi
     
     	# Allow "mandatory" ICMP in.
     	${fwcmd} add pass icmp from any to any icmptype 3,4,11
    -	
    +	if [ $ipv6_available -eq 0 ]; then
    +		${fwcmd} add pass ipv6-icmp from any to any icmp6type 3
    +	fi
    +
     	# Add permits for this workstations published services below
     	# Only IPs and nets in firewall_allowservices is allowed in.
     	# If you really wish to let anyone use services on your 
    @@ -370,7 +495,7 @@ case ${firewall_type} in
     	for i in ${firewall_trusted} ; do
     	  ${fwcmd} add pass ip from $i to me
     	done
    -	
    +
     	${fwcmd} add 65000 count ip from any to any
     
     	# Drop packets to ports where we don't want logging
    diff --git a/etc/rc.firewall6 b/etc/rc.firewall6
    deleted file mode 100644
    index 7498bbc68f5..00000000000
    --- a/etc/rc.firewall6
    +++ /dev/null
    @@ -1,295 +0,0 @@
    -#!/bin/sh -
    -############
    -# Setup system for IPv6 firewall service.
    -# $FreeBSD$
    -
    -# Suck in the configuration variables.
    -if [ -z "${source_rc_confs_defined}" ]; then
    -	if [ -r /etc/defaults/rc.conf ]; then
    -		. /etc/defaults/rc.conf
    -		source_rc_confs
    -	elif [ -r /etc/rc.conf ]; then
    -		. /etc/rc.conf
    -	fi
    -fi
    -
    -############
    -# Define the firewall type in /etc/rc.conf.  Valid values are:
    -#   open     - will allow anyone in
    -#   client   - will try to protect just this machine
    -#   simple   - will try to protect a whole network
    -#   closed   - totally disables IP services except via lo0 interface
    -#   UNKNOWN  - disables the loading of firewall rules.
    -#   filename - will load the rules in the given filename (full path required)
    -#
    -# For ``client'' and ``simple'' the entries below should be customized
    -# appropriately.
    -
    -############
    -#
    -# If you don't know enough about packet filtering, we suggest that you
    -# take time to read this book:
    -#
    -#	Building Internet Firewalls, 2nd Edition
    -#	Brent Chapman and Elizabeth Zwicky
    -#
    -#	O'Reilly & Associates, Inc
    -#	ISBN 1-56592-871-7
    -#	http://www.ora.com/
    -#	http://www.oreilly.com/catalog/fire2/
    -#
    -# For a more advanced treatment of Internet Security read:
    -#
    -#	Firewalls and Internet Security: Repelling the Wily Hacker, 2nd Edition
    -#	William R. Cheswick, Steven M. Bellowin, Aviel D. Rubin
    -#
    -#	Addison-Wesley / Prentice Hall
    -#	ISBN 0-201-63466-X
    -#	http://www.pearsonhighered.com/
    -#	http://www.pearsonhighered.com/educator/academic/product/0,3110,020163466X,00.html
    -#
    -
    -setup_local () {
    -	############
    -	# Only in rare cases do you want to change these rules
    -	#
    -	${fw6cmd} add 100 pass ip6 from any to any via lo0
    -	${fw6cmd} add 200 deny ip6 from any to ::1
    -	${fw6cmd} add 300 deny ip6 from ::1 to any
    -	#
    -	# ND
    -	#
    -	# DAD
    -	${fw6cmd} add pass ip6 from :: to ff02::/16 proto ipv6-icmp
    -	# RS, RA, NS, NA, redirect...
    -	${fw6cmd} add pass ip6 from fe80::/10 to fe80::/10 proto ipv6-icmp
    -	${fw6cmd} add pass ip6 from fe80::/10 to ff02::/16 proto ipv6-icmp
    -}
    -
    -if [ -n "${1}" ]; then
    -	ipv6_firewall_type="${1}"
    -fi
    -
    -############
    -# Set quiet mode if requested
    -#
    -case ${ipv6_firewall_quiet} in
    -[Yy][Ee][Ss])
    -	fw6cmd="/sbin/ipfw -q"
    -	;;
    -*)
    -	fw6cmd="/sbin/ipfw"
    -	;;
    -esac
    -
    -############
    -# Flush out the list before we begin.
    -#
    -${fw6cmd} -f flush
    -
    -############
    -# If you just configured ipfw in the kernel as a tool to solve network
    -# problems or you just want to disallow some particular kinds of traffic
    -# then you will want to change the default policy to open.  You can also
    -# do this as your only action by setting the ipv6_firewall_type to ``open''.
    -#
    -# ${fw6cmd} add 65000 pass all from any to any
    -
    -
    -# Prototype setups.
    -#
    -case ${ipv6_firewall_type} in
    -[Oo][Pp][Ee][Nn])
    -	setup_local
    -	${fw6cmd} add 65000 pass ip6 from any to any
    -	;;
    -
    -[Cc][Ll][Ii][Ee][Nn][Tt])
    -	############
    -	# This is a prototype setup that will protect your system somewhat
    -	# against people from outside your own network.
    -	############
    -
    -	# set these to your network and prefixlen and ip
    -	#
    -	# This needs more work
    -	#
    -	net="2001:db8:2:1::"
    -	prefixlen="64"
    -	ip="2001:db8:2:1::1"
    -
    -	setup_local
    -
    -	# Allow any traffic to or from my own net.
    -	${fw6cmd} add pass ip6 from ${ip} to ${net}/${prefixlen}
    -	${fw6cmd} add pass ip6 from ${net}/${prefixlen} to ${ip}
    -
    -	# Allow any link-local multicast traffic
    -	${fw6cmd} add pass ip6 from fe80::/10 to ff02::/16
    -	${fw6cmd} add pass ip6 from ${net}/${prefixlen} to ff02::/16
    -
    -	# Allow TCP through if setup succeeded
    -	${fw6cmd} add pass ip6 from any to any established proto tcp
    -
    -	# Allow IP fragments to pass through
    -	${fw6cmd} add pass ip6 from any to any frag
    -
    -	# Allow setup of incoming email
    -	${fw6cmd} add pass ip6 from any to ${ip} 25 setup proto tcp
    -
    -	# Allow setup of outgoing TCP connections only
    -	${fw6cmd} add pass ip6 from ${ip} to any setup proto tcp
    -
    -	# Disallow setup of all other TCP connections
    -	${fw6cmd} add deny ip6 from any to any setup proto tcp
    -
    -	# Allow DNS queries out in the world
    -	${fw6cmd} add pass ip6 from any 53 to ${ip} proto udp
    -	${fw6cmd} add pass ip6 from ${ip} to any 53 proto udp
    -
    -	# Allow NTP queries out in the world
    -	${fw6cmd} add pass ip6 from any 123 to ${ip} proto udp
    -	${fw6cmd} add pass ip6 from ${ip} to any 123 proto udp
    -
    -	# Allow ICMPv6 destination unreach
    -	${fw6cmd} add pass ip6 from any to any icmp6types 1 proto ipv6-icmp
    -
    -	# Allow NS/NA/toobig (don't filter it out)
    -	${fw6cmd} add pass ip6 from any to any icmp6types 2,135,136 \
    -	    proto ipv6-icmp
    -
    -	# Everything else is denied by default, unless the
    -	# IPV6FIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel
    -	# config file.
    -	;;
    -
    -[Ss][Ii][Mm][Pp][Ll][Ee])
    -	############
    -	# This is a prototype setup for a simple firewall.  Configure this
    -	# machine as a DNS and NTP server, and point all the machines
    -	# on the inside at this machine for those services.
    -	############
    -
    -	# set these to your outside interface network and prefixlen and ip
    -	oif="ed0"
    -	onet="2001:db8:2:1::"
    -	oprefixlen="64"
    -	oip="2001:db8:2:1::1"
    -
    -	# set these to your inside interface network and prefixlen and ip
    -	iif="ed1"
    -	inet="2001:db8:2:2::"
    -	iprefixlen="64"
    -	iip="2001:db8:2:2::1"
    -
    -	setup_local
    -
    -	# Stop spoofing
    -	${fw6cmd} add deny ip6 from ${inet}/${iprefixlen} to any in via ${oif}
    -	${fw6cmd} add deny ip6 from ${onet}/${oprefixlen} to any in via ${iif}
    -
    -	# Stop unique local unicast address on the outside interface
    -	${fw6cmd} add deny ip6 from fc00::/7 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to fc00::/7 via ${oif}
    -
    -	# Stop site-local on the outside interface
    -	${fw6cmd} add deny ip6 from fec0::/10 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to fec0::/10 via ${oif}
    -
    -	# Disallow "internal" addresses to appear on the wire.
    -	${fw6cmd} add deny ip6 from ::ffff:0.0.0.0/96 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to ::ffff:0.0.0.0/96 via ${oif}
    -
    -	# Disallow packets to malicious IPv4 compatible prefix.
    -	${fw6cmd} add deny ip6 from ::224.0.0.0/100 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to ::224.0.0.0/100 via ${oif}
    -	${fw6cmd} add deny ip6 from ::127.0.0.0/104 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to ::127.0.0.0/104 via ${oif}
    -	${fw6cmd} add deny ip6 from ::0.0.0.0/104 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to ::0.0.0.0/104 via ${oif}
    -	${fw6cmd} add deny ip6 from ::255.0.0.0/104 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to ::255.0.0.0/104 via ${oif}
    -
    -	${fw6cmd} add deny ip6 from ::0.0.0.0/96 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to ::0.0.0.0/96 via ${oif}
    -
    -	# Disallow packets to malicious 6to4 prefix.
    -	${fw6cmd} add deny ip6 from 2002:e000::/20 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to 2002:e000::/20 via ${oif}
    -	${fw6cmd} add deny ip6 from 2002:7f00::/24 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to 2002:7f00::/24 via ${oif}
    -	${fw6cmd} add deny ip6 from 2002:0000::/24 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to 2002:0000::/24 via ${oif}
    -	${fw6cmd} add deny ip6 from 2002:ff00::/24 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to 2002:ff00::/24 via ${oif}
    -
    -	${fw6cmd} add deny ip6 from 2002:0a00::/24 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to 2002:0a00::/24 via ${oif}
    -	${fw6cmd} add deny ip6 from 2002:ac10::/28 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to 2002:ac10::/28 via ${oif}
    -	${fw6cmd} add deny ip6 from 2002:c0a8::/32 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to 2002:c0a8::/32 via ${oif}
    -
    -	${fw6cmd} add deny ip6 from ff05::/16 to any via ${oif}
    -	${fw6cmd} add deny ip6 from any to ff05::/16 via ${oif}
    -
    -	# Allow TCP through if setup succeeded
    -	${fw6cmd} add pass tcp from any to any established
    -
    -	# Allow IP fragments to pass through
    -	${fw6cmd} add pass ip6 from any to any frag
    -
    -	# Allow setup of incoming email
    -	${fw6cmd} add pass ip6 from any to ${oip} 25 setup proto tcp
    -
    -	# Allow access to our DNS
    -	${fw6cmd} add pass ip6 from any to ${oip} 53 setup proto tcp
    -	${fw6cmd} add pass ip6 from any to ${oip} 53 proto udp
    -	${fw6cmd} add pass ip6 from ${oip} 53 to any proto udp
    -
    -	# Allow access to our WWW
    -	${fw6cmd} add pass ip6 from any to ${oip} 80 setup proto tcp
    -
    -	# Reject&Log all setup of incoming connections from the outside
    -	${fw6cmd} add deny log ip6 from any to any in via ${oif} setup \
    -	    proto tcp
    -
    -	# Allow setup of any other TCP connection
    -	${fw6cmd} add pass ip6 from any to any setup proto tcp
    -
    -	# Allow DNS queries out in the world
    -	${fw6cmd} add pass ip6 from any 53 to ${oip} proto udp
    -	${fw6cmd} add pass ip6 from ${oip} to any 53 proto udp
    -
    -	# Allow NTP queries out in the world
    -	${fw6cmd} add pass ip6 from any 123 to ${oip} proto udp
    -	${fw6cmd} add pass ip6 from ${oip} to any 123 proto udp
    -
    -	# Allow RIPng
    -	#${fw6cmd} add pass ip6 from fe80::/10 521 to ff02::9 521 proto udp
    -	#${fw6cmd} add pass ip6 from fe80::/10 521 to fe80::/10 521 proto udp
    -
    -	# Allow ICMPv6 destination unreach
    -	${fw6cmd} add pass ip6 from any to any icmp6types 1 proto ipv6-icmp
    -
    -	# Allow NS/NA/toobig (don't filter it out)
    -	${fw6cmd} add pass ip6 from any to any icmp6types 2,135,136 \
    -	     proto ipv6-icmp
    -
    -	# Everything else is denied by default, unless the
    -	# IPV6FIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel
    -	# config file.
    -	;;
    -
    -[Cc][Ll][Oo][Ss][Ee][Dd])
    -	# Only enable the loopback interface
    -	${fw6cmd} add 100 pass ip6 from any to any via lo0
    -	;;
    -[Uu][Nn][Kk][Nn][Oo][Ww][Nn])
    -	;;
    -*)
    -	if [ -r "${ipv6_firewall_type}" ]; then
    -		${fw6cmd} ${ipv6_firewall_flags} ${ipv6_firewall_type}
    -	fi
    -	;;
    -esac
    
    From 354b61f607e46d44e7247e75dfcf681a285fad79 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Wed, 7 Apr 2010 22:19:46 +0000
    Subject: [PATCH 1913/2592] MFC r205988: indent(1): correctly handle case/label
     at the very start of a function
    
    ---
     usr.bin/indent/indent.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/usr.bin/indent/indent.c b/usr.bin/indent/indent.c
    index 9917960446a..7820ebeb72d 100644
    --- a/usr.bin/indent/indent.c
    +++ b/usr.bin/indent/indent.c
    @@ -675,7 +675,7 @@ check_type:
     		ps.want_blank = true;
     		break;
     	    }
    -	    if (ps.in_decl) {
    +	    if (ps.in_or_st) {
     		*e_code++ = ':';
     		ps.want_blank = false;
     		break;
    
    From e546195f071dc452405cfa7176604c393cd756db Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Thu, 8 Apr 2010 00:52:28 +0000
    Subject: [PATCH 1914/2592] MFC r204901
    
    Remove the check for IFF_DRV_OACTIVE right before adding a port into lagg
    interface.  The check itself seems to be coming from OpenBSD but does not
    seem to be useful for our code.
    
    Discussed with:	thomasa
    ---
     sys/net/if_lagg.c | 4 ----
     1 file changed, 4 deletions(-)
    
    diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
    index 583cc4135ad..1deab5628fc 100644
    --- a/sys/net/if_lagg.c
    +++ b/sys/net/if_lagg.c
    @@ -424,10 +424,6 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
     	if (sc->sc_count >= LAGG_MAX_PORTS)
     		return (ENOSPC);
     
    -	/* New lagg port has to be in an idle state */
    -	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
    -		return (EBUSY);
    -
     	/* Check if port has already been associated to a lagg */
     	if (ifp->if_lagg != NULL)
     		return (EBUSY);
    
    From a1a102fb157a38ecc94ebd15d66b58b740c7d115 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Thu, 8 Apr 2010 07:43:15 +0000
    Subject: [PATCH 1915/2592] MFC r206177: hash.3: fix a factual mistake in the
     man page
    
    ---
     lib/libc/db/man/hash.3 | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/lib/libc/db/man/hash.3 b/lib/libc/db/man/hash.3
    index 67240421019..133885d841c 100644
    --- a/lib/libc/db/man/hash.3
    +++ b/lib/libc/db/man/hash.3
    @@ -78,7 +78,7 @@ The
     element
     defines the
     .Nm
    -table bucket size, and is, by default, 256 bytes.
    +table bucket size, and is, by default, 4096 bytes.
     It may be preferable to increase the page size for disk-resident tables
     and tables with large data items.
     .It Va ffactor
    
    From f2647399494d46bba7facb7546bc6f1336fb2d04 Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Thu, 8 Apr 2010 18:33:35 +0000
    Subject: [PATCH 1916/2592] This is an MFC of 206029 Add a couple missing basic
     mode page codes.
    
    ---
     sys/cam/scsi/scsi_all.h | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
    index 029b2ccd136..d6b6e81c871 100644
    --- a/sys/cam/scsi/scsi_all.h
    +++ b/sys/cam/scsi/scsi_all.h
    @@ -170,6 +170,8 @@ struct scsi_mode_sense_6
     #define	SMS_PAGE_CODE 			0x3F
     #define SMS_VENDOR_SPECIFIC_PAGE	0x00
     #define SMS_DISCONNECT_RECONNECT_PAGE	0x02
    +#define SMS_FORMAT_DEVICE_PAGE		0x03
    +#define SMS_GEOMETRY_PAGE		0x04
     #define SMS_CACHE_PAGE			0x08
     #define SMS_PERIPHERAL_DEVICE_PAGE	0x09
     #define SMS_CONTROL_MODE_PAGE		0x0A
    
    From ae4539db79bfb19c2352ce145649953ebed53137 Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Fri, 9 Apr 2010 01:14:39 +0000
    Subject: [PATCH 1917/2592] MFC: r205661 Patch the regular NFS server so that
     it returns ESTALE to the client for all errors returned by VFS_FHTOVP(). This
     is required to ensure that EIO doesn't get returned to the client when ZFS is
     used as the server file system.
    
    ---
     sys/nfsserver/nfs_srvsubs.c | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
    index d84261e8249..f2e9d510e01 100644
    --- a/sys/nfsserver/nfs_srvsubs.c
    +++ b/sys/nfsserver/nfs_srvsubs.c
    @@ -1128,6 +1128,9 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp,
     		}
     	}
     	error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
    +	if (error != 0)
    +		/* Make sure the server replies ESTALE to the client. */
    +		error = ESTALE;
     	vfs_unbusy(mp);
     	if (error)
     		goto out;
    
    From 5b41805237eaab4ac86140d26d5088e8a6999a11 Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Fri, 9 Apr 2010 01:33:12 +0000
    Subject: [PATCH 1918/2592] MFC: r205663 Patch the experimental NFS server in a
     manner analagous to r205661 for the regular NFS server, to ensure that ESTALE
     is returned to the client for all errors returned by VFS_FHTOVP().
    
    ---
     sys/fs/nfsserver/nfs_nfsdport.c | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
    index 3b7f8d0a1df..79f04c0f350 100644
    --- a/sys/fs/nfsserver/nfs_nfsdport.c
    +++ b/sys/fs/nfsserver/nfs_nfsdport.c
    @@ -2443,6 +2443,9 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct sockaddr *nam,
     	*credp = NULL;
     	exp->nes_numsecflavor = 0;
     	error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
    +	if (error != 0)
    +		/* Make sure the server replies ESTALE to the client. */
    +		error = ESTALE;
     	if (nam && !error) {
     		error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
     		    &exp->nes_numsecflavor, &secflavors);
    
    From 55146b83de066a8a4c0991bed56daf982b921a24 Mon Sep 17 00:00:00 2001
    From: Alan Cox 
    Date: Fri, 9 Apr 2010 06:40:30 +0000
    Subject: [PATCH 1919/2592] MFC r206174   vm_reserv_alloc_page() should never
     be called on an OBJT_SG object, just   as it is never called on an
     OBJT_DEVICE object.  (This change should have   been included in r195840.)
    
    ---
     sys/vm/vm_page.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
    index 8ba2f7f7ad0..439c410c7d1 100644
    --- a/sys/vm/vm_page.c
    +++ b/sys/vm/vm_page.c
    @@ -1084,6 +1084,7 @@ vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
     			return (NULL);
     #if VM_NRESERVLEVEL > 0
     		} else if (object == NULL || object->type == OBJT_DEVICE ||
    +		    object->type == OBJT_SG ||
     		    (object->flags & OBJ_COLORED) == 0 ||
     		    (m = vm_reserv_alloc_page(object, pindex)) == NULL) {
     #else
    
    From bb9a8424a36ad6970a2ac339f412de8961a5b2e9 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Fri, 9 Apr 2010 08:39:28 +0000
    Subject: [PATCH 1920/2592] MFC r206093: Add function vop_rename_fail(9) that
     performs needed cleanup for locks and references of the VOP_RENAME(9)
     arguments. Use vop_rename_fail() in deadfs_rename().
    
    ---
     sys/fs/deadfs/dead_vnops.c | 10 ++--------
     sys/kern/vfs_subr.c        | 14 ++++++++++++++
     sys/sys/vnode.h            |  2 ++
     3 files changed, 18 insertions(+), 8 deletions(-)
    
    diff --git a/sys/fs/deadfs/dead_vnops.c b/sys/fs/deadfs/dead_vnops.c
    index 7a07b38542e..e2556543fb6 100644
    --- a/sys/fs/deadfs/dead_vnops.c
    +++ b/sys/fs/deadfs/dead_vnops.c
    @@ -225,13 +225,7 @@ dead_rename(ap)
     		struct componentname *a_tcnp;
     	} */ *ap;
     {
    -	if (ap->a_tvp)
    -		vput(ap->a_tvp);
    -	if (ap->a_tdvp == ap->a_tvp)
    -		vrele(ap->a_tdvp);
    -	else
    -		vput(ap->a_tdvp);
    -	vrele(ap->a_fdvp);
    -	vrele(ap->a_fvp);
    +
    +	vop_rename_fail(ap);
     	return (EXDEV);
     }
    diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
    index cf73dff0458..51ec34e8bb1 100644
    --- a/sys/kern/vfs_subr.c
    +++ b/sys/kern/vfs_subr.c
    @@ -3748,6 +3748,20 @@ assert_vop_slocked(struct vnode *vp, const char *str)
     #endif /* 0 */
     #endif /* DEBUG_VFS_LOCKS */
     
    +void
    +vop_rename_fail(struct vop_rename_args *ap)
    +{
    +
    +	if (ap->a_tvp != NULL)
    +		vput(ap->a_tvp);
    +	if (ap->a_tdvp == ap->a_tvp)
    +		vrele(ap->a_tdvp);
    +	else
    +		vput(ap->a_tdvp);
    +	vrele(ap->a_fdvp);
    +	vrele(ap->a_fvp);
    +}
    +
     void
     vop_rename_pre(void *ap)
     {
    diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
    index 4c84ea30ebe..b5784e4a75a 100644
    --- a/sys/sys/vnode.h
    +++ b/sys/sys/vnode.h
    @@ -720,6 +720,8 @@ void	vop_symlink_post(void *a, int rc);
     void	vop_unlock_post(void *a, int rc);
     void	vop_unlock_pre(void *a);
     
    +void	vop_rename_fail(struct vop_rename_args *ap);
    +
     #define	VOP_WRITE_PRE(ap)						\
     	struct vattr va;						\
     	int error, osize, ooffset, noffset;				\
    
    From f2c7b98632f7269313eda4c4d85a2c86a649424c Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Fri, 9 Apr 2010 08:45:30 +0000
    Subject: [PATCH 1921/2592] MFC r206094: Supply default implementation of
     VOP_RENAME() that does neccessary unlocks and unreferences for argument
     vnodes, as expected by kern_renameat(9), and returns EOPNOTSUPP. This fixes
     locks and reference leaks when rename is attempted on fs that does not
     implement rename.
    
    ---
     sys/kern/vfs_default.c | 16 ++++++++++++++++
     1 file changed, 16 insertions(+)
    
    diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
    index b80d03d0e9e..5c9425332a1 100644
    --- a/sys/kern/vfs_default.c
    +++ b/sys/kern/vfs_default.c
    @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
     #include 
     
     static int	vop_nolookup(struct vop_lookup_args *);
    +static int	vop_norename(struct vop_rename_args *);
     static int	vop_nostrategy(struct vop_strategy_args *);
     static int	get_next_dirent(struct vnode *vp, struct dirent **dpp,
     				char *dirbuf, int dirbuflen, off_t *off,
    @@ -113,6 +114,7 @@ struct vop_vector default_vnodeops = {
     	.vop_poll =		vop_nopoll,
     	.vop_putpages =		vop_stdputpages,
     	.vop_readlink =		VOP_EINVAL,
    +	.vop_rename =		vop_norename,
     	.vop_revoke =		VOP_PANIC,
     	.vop_strategy =		vop_nostrategy,
     	.vop_unlock =		vop_stdunlock,
    @@ -205,6 +207,20 @@ vop_nolookup(ap)
     	return (ENOTDIR);
     }
     
    +/*
    + * vop_norename:
    + *
    + * Handle unlock and reference counting for arguments of vop_rename
    + * for filesystems that do not implement rename operation.
    + */
    +static int
    +vop_norename(struct vop_rename_args *ap)
    +{
    +
    +	vop_rename_fail(ap);
    +	return (EOPNOTSUPP);
    +}
    +
     /*
      *	vop_nostrategy:
      *
    
    From f246dccccaf09c1b3bfd5be9050df326ecbf82b7 Mon Sep 17 00:00:00 2001
    From: Ed Maste 
    Date: Fri, 9 Apr 2010 22:50:36 +0000
    Subject: [PATCH 1922/2592] MFC r206383:   Remove extraneous '>'.
    
    ---
     share/man/man9/stack.9 | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/share/man/man9/stack.9 b/share/man/man9/stack.9
    index 65676417c0d..2c2b76241c3 100644
    --- a/share/man/man9/stack.9
    +++ b/share/man/man9/stack.9
    @@ -34,7 +34,7 @@
     .Nm stack
     .Nd kernel thread stack tracing routines
     .Sh SYNOPSIS
    -.In sys/param.h>
    +.In sys/param.h
     .In sys/stack.h
     In the kernel configuration file:
     .Cd "options DDB"
    
    From e3359a8c1af541ccb7b9f2d3f7b027eb92e7bcce Mon Sep 17 00:00:00 2001
    From: Jaakko Heinonen 
    Date: Sat, 10 Apr 2010 14:28:58 +0000
    Subject: [PATCH 1923/2592] MFC r205385:
    
    Escape characters unsafe for XML output in GEOM class, instance and
    provider names.
    
    - Characters in range 0x01-0x1f except '\t', '\n', and '\r' are replaced
      with '?'. Those characters are disallowed in XML.
    - '&', '<', '>', '\'', '"' and characters in range 0x7f-0xff are
      replaced with XML numeric character reference.
    
    If the kern.geom.confxml sysctl provides invalid XML, libgeom
    geom_xml2tree() fails and utilities using it do not work. Unsafe
    characters are common in msdosfs and cd9660 labels.
    
    PR:		kern/104389
    ---
     sys/geom/geom_dump.c | 28 +++++++++++++++++++++++++---
     1 file changed, 25 insertions(+), 3 deletions(-)
    
    diff --git a/sys/geom/geom_dump.c b/sys/geom/geom_dump.c
    index 1f00db9de17..e2f1fb7396b 100644
    --- a/sys/geom/geom_dump.c
    +++ b/sys/geom/geom_dump.c
    @@ -153,6 +153,28 @@ g_conftxt(void *p, int flag)
     }
     
     
    +static void
    +g_conf_print_escaped(struct sbuf *sb, const char *fmt, const char *str)
    +{
    +	struct sbuf *s;
    +	const u_char *c;
    +
    +	s = sbuf_new_auto();
    +
    +	for (c = str; *c != '\0'; c++) {
    +		if (*c == '&' || *c == '<' || *c == '>' ||
    +		    *c == '\'' || *c == '"' || *c > 0x7e)
    +			sbuf_printf(s, "&#x%X;", *c);
    +		else if (*c == '\t' || *c == '\n' || *c == '\r' || *c > 0x1f)
    +			sbuf_putc(s, *c);
    +		else
    +			sbuf_putc(s, '?');
    +	}
    +	sbuf_finish(s);
    +	sbuf_printf(sb, fmt, sbuf_data(s));
    +	sbuf_delete(s);
    +}
    +
     static void
     g_conf_consumer(struct sbuf *sb, struct g_consumer *cp)
     {
    @@ -181,7 +203,7 @@ g_conf_provider(struct sbuf *sb, struct g_provider *pp)
     	sbuf_printf(sb, "\t  \n", pp->geom);
     	sbuf_printf(sb, "\t  r%dw%de%d\n",
     	    pp->acr, pp->acw, pp->ace);
    -	sbuf_printf(sb, "\t  %s\n", pp->name);
    +	g_conf_print_escaped(sb, "\t  %s\n", pp->name);
     	sbuf_printf(sb, "\t  %jd\n",
     	    (intmax_t)pp->mediasize);
     	sbuf_printf(sb, "\t  %u\n", pp->sectorsize);
    @@ -204,7 +226,7 @@ g_conf_geom(struct sbuf *sb, struct g_geom *gp, struct g_provider *pp, struct g_
     
     	sbuf_printf(sb, "    \n", gp);
     	sbuf_printf(sb, "      \n", gp->class);
    -	sbuf_printf(sb, "      %s\n", gp->name);
    +	g_conf_print_escaped(sb, "      %s\n", gp->name);
     	sbuf_printf(sb, "      %d\n", gp->rank);
     	if (gp->flags & G_GEOM_WITHER)
     		sbuf_printf(sb, "      \n");
    @@ -233,7 +255,7 @@ g_conf_class(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_pr
     	struct g_geom *gp2;
     
     	sbuf_printf(sb, "  \n", mp);
    -	sbuf_printf(sb, "    %s\n", mp->name);
    +	g_conf_print_escaped(sb, "    %s\n", mp->name);
     	LIST_FOREACH(gp2, &mp->geom, geom) {
     		if (gp != NULL && gp != gp2)
     			continue;
    
    From e42bcb8719498911bfe37267359ddf3573fa199c Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Sun, 11 Apr 2010 15:17:52 +0000
    Subject: [PATCH 1924/2592] MFC r206266: Set net.inet6.ip6.fw.enable as well.
    
    ---
     sbin/ipfw/ipfw2.c | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
    index 9e212fc012a..41f6e3ab3e8 100644
    --- a/sbin/ipfw/ipfw2.c
    +++ b/sbin/ipfw/ipfw2.c
    @@ -1740,6 +1740,8 @@ ipfw_sysctl_handler(char *av[], int which)
     	} else if (_substrcmp(*av, "firewall") == 0) {
     		sysctlbyname("net.inet.ip.fw.enable", NULL, 0,
     		    &which, sizeof(which));
    +		sysctlbyname("net.inet6.ip6.fw.enable", NULL, 0,
    +		    &which, sizeof(which));
     	} else if (_substrcmp(*av, "one_pass") == 0) {
     		sysctlbyname("net.inet.ip.fw.one_pass", NULL, 0,
     		    &which, sizeof(which));
    
    From 8d5ce86fd6e0e00c51e945749f9e2246c0dd10c1 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Mon, 12 Apr 2010 20:53:17 +0000
    Subject: [PATCH 1925/2592] MFC r206098: mountmsdosfs: reject too high value of
     bytes per cluster
    
    ---
     sys/fs/msdosfs/msdosfs_vfsops.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
    index 77583eecd39..a0801bde22a 100644
    --- a/sys/fs/msdosfs/msdosfs_vfsops.c
    +++ b/sys/fs/msdosfs/msdosfs_vfsops.c
    @@ -580,6 +580,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
     	  || (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1))
     	  || (pmp->pm_HugeSectors == 0)
     	  || (pmp->pm_FATsecs == 0)
    +	  || (SecPerClust * pmp->pm_BlkPerSec > MAXBSIZE / DEV_BSIZE)
     	) {
     		error = EINVAL;
     		goto error_exit;
    
    From ce749f106e58c095ab6905f9f991637d5e1ceb99 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Mon, 12 Apr 2010 21:04:35 +0000
    Subject: [PATCH 1926/2592] MFC r205989: indent(1): new option, -ta, to treat
     all *_t identifiers as types
    
    ---
     usr.bin/indent/args.c         |  1 +
     usr.bin/indent/indent.1       |  4 ++++
     usr.bin/indent/indent_globs.h |  2 ++
     usr.bin/indent/lexi.c         | 12 ++++++++++++
     4 files changed, 19 insertions(+)
    
    diff --git a/usr.bin/indent/args.c b/usr.bin/indent/args.c
    index f139de58840..cab0f7d092b 100644
    --- a/usr.bin/indent/args.c
    +++ b/usr.bin/indent/args.c
    @@ -157,6 +157,7 @@ struct pro {
         {"sc", PRO_BOOL, true, ON, &star_comment_cont},
         {"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines},
         {"st", PRO_SPECIAL, 0, STDIN, 0},
    +    {"ta", PRO_BOOL, false, ON, &auto_typedefs},
         {"troff", PRO_BOOL, false, ON, &troff},
         {"ut", PRO_BOOL, true, ON, &use_tabs},
         {"v", PRO_BOOL, false, ON, &verbose},
    diff --git a/usr.bin/indent/indent.1 b/usr.bin/indent/indent.1
    index f04e13d5f42..1a7c789750e 100644
    --- a/usr.bin/indent/indent.1
    +++ b/usr.bin/indent/indent.1
    @@ -80,6 +80,7 @@
     .Op Fl sob | Fl nsob
     .Ek
     .Op Fl \&st
    +.Op Fl \&ta
     .Op Fl troff
     .Op Fl ut | Fl nut
     .Op Fl v | Fl \&nv
    @@ -377,6 +378,9 @@ Default:
     Causes
     .Nm
     to take its input from stdin and put its output to stdout.
    +.It Fl ta
    +Automatically add all identifiers ending in "_t" to the list
    +of type keywords.
     .It Fl T Ns Ar typename
     Adds
     .Ar typename
    diff --git a/usr.bin/indent/indent_globs.h b/usr.bin/indent/indent_globs.h
    index 11ea239571b..087f41c2390 100644
    --- a/usr.bin/indent/indent_globs.h
    +++ b/usr.bin/indent/indent_globs.h
    @@ -204,6 +204,8 @@ int	    function_brace_split;	/* split function declaration and
     					 * brace onto separate lines */
     int	    use_tabs;			/* set true to use tabs for spacing,
     					 * false uses all spaces */
    +int	    auto_typedefs;		/* set true to recognize identifiers
    +					 * ending in "_t" like typedefs */
     
     /* -troff font state information */
     
    diff --git a/usr.bin/indent/lexi.c b/usr.bin/indent/lexi.c
    index 60fc1aee9ee..3d415d074dc 100644
    --- a/usr.bin/indent/lexi.c
    +++ b/usr.bin/indent/lexi.c
    @@ -249,6 +249,17 @@ lexi(void)
     	last_code = ident;	/* Remember that this is the code we will
     				 * return */
     
    +	if (auto_typedefs) {
    +	    const char *q = s_token;
    +	    /* Check if we have an "_t" in the end */
    +	    if (q[0] && q[1] &&
    +	        (strcmp(q + strlen(q) - 2, "_t") == 0)) {
    +	        ps.its_a_keyword = true;
    +		ps.last_u_d = true;
    +	        goto found_auto_typedef;
    +	    }
    +	}
    +
     	/*
     	 * This loop will check if the token is a keyword.
     	 */
    @@ -285,6 +296,7 @@ lexi(void)
     		/* FALLTHROUGH */
     
     	    case 4:		/* one of the declaration keywords */
    +	    found_auto_typedef:
     		if (ps.p_l_follow) {
     		    ps.cast_mask |= (1 << ps.p_l_follow) & ~ps.sizeof_mask;
     		    break;	/* inside parens: cast, param list or sizeof */
    
    From 8eb59aff80e972f3fded86fe17c0b81e947e95a1 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Mon, 12 Apr 2010 21:07:58 +0000
    Subject: [PATCH 1927/2592] MFC r206128: ffs_mount: remove redundant assignment
     of to devvp.v_bufobj
    
    ---
     sys/ufs/ffs/ffs_vfsops.c | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
    index d3d7c2c6073..368f3112ced 100644
    --- a/sys/ufs/ffs/ffs_vfsops.c
    +++ b/sys/ufs/ffs/ffs_vfsops.c
    @@ -650,7 +650,6 @@ ffs_mountfs(devvp, mp, td)
     	if (mp->mnt_iosize_max > MAXPHYS)
     		mp->mnt_iosize_max = MAXPHYS;
     
    -	devvp->v_bufobj.bo_private = cp;
     	devvp->v_bufobj.bo_ops = &ffs_ops;
     
     	fs = NULL;
    
    From d1bec90bbe3b3b55c353b44d43d2412b59a9213f Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Mon, 12 Apr 2010 21:12:03 +0000
    Subject: [PATCH 1928/2592] MFC r206178: ibc/db/hash: cap auto-tuned block size
    
    ---
     lib/libc/db/hash/hash.c | 2 ++
     lib/libc/db/hash/hash.h | 2 +-
     2 files changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c
    index 83d26577740..638814ceb5d 100644
    --- a/lib/libc/db/hash/hash.c
    +++ b/lib/libc/db/hash/hash.c
    @@ -293,6 +293,8 @@ init_hash(HTAB *hashp, const char *file, const HASHINFO *info)
     		if (stat(file, &statbuf))
     			return (NULL);
     		hashp->BSIZE = statbuf.st_blksize;
    +		if (hashp->BSIZE > MAX_BSIZE)
    +			hashp->BSIZE = MAX_BSIZE;
     		hashp->BSHIFT = __log2(hashp->BSIZE);
     	}
     
    diff --git a/lib/libc/db/hash/hash.h b/lib/libc/db/hash/hash.h
    index 8329413fffe..cd11a3ae98e 100644
    --- a/lib/libc/db/hash/hash.h
    +++ b/lib/libc/db/hash/hash.h
    @@ -118,7 +118,7 @@ typedef struct htab	 {		/* Memory resident data structure */
     /*
      * Constants
      */
    -#define	MAX_BSIZE		65536		/* 2^16 */
    +#define	MAX_BSIZE		32768		/* 2^15 but should be 65536 */
     #define MIN_BUFFERS		6
     #define MINHDRSIZE		512
     #define DEF_BUFSIZE		65536		/* 64 K */
    
    From 31810d290bc2f75b6938962c8f5ddc0bf9f6b3b8 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Mon, 12 Apr 2010 21:18:58 +0000
    Subject: [PATCH 1929/2592] MFC r206102,206103,206175,206176: add example
     indent.pro file
    
    ---
     share/examples/indent/indent.pro | 46 ++++++++++++++++++++++++++++++++
     1 file changed, 46 insertions(+)
     create mode 100644 share/examples/indent/indent.pro
    
    diff --git a/share/examples/indent/indent.pro b/share/examples/indent/indent.pro
    new file mode 100644
    index 00000000000..c85bfda3f4b
    --- /dev/null
    +++ b/share/examples/indent/indent.pro
    @@ -0,0 +1,46 @@
    +-TFILE
    +-Tfd_mask
    +-Tfd_set
    +-Tlinker_sym_tT
    +-Tu_char
    +-Tu_int
    +-Tu_long
    +-Tu_short
    +-TTAILQ_HEAD
    +-TTAILQ_ENTRY
    +-TLIST_HEAD
    +-TLIST_ENTRY
    +-TSTAILQ_HEAD
    +-TSTAILQ_ENTRY
    +-TSLIST_HEAD
    +-TSLIST_ENTRY
    +-bad
    +-bap
    +-nbbb
    +-nbc
    +-br
    +-nbs
    +-c41
    +-cd41
    +-cdb
    +-ce
    +-ci4
    +-cli0
    +-d0
    +-di8
    +-ndj
    +-ei
    +-nfc1
    +-nfcb
    +-i8
    +-ip8
    +-l79
    +-lc77
    +-ldi0
    +-nlp
    +-npcs
    +-psl
    +-sc
    +-nsob
    +-ta
    +-nv
    
    From 18f2288474093eca9f4ff5935065c1c322eba3b0 Mon Sep 17 00:00:00 2001
    From: Fabien Thomas 
    Date: Mon, 12 Apr 2010 21:37:28 +0000
    Subject: [PATCH 1930/2592] MFC r206090: Improve "top" header by: - Display
     sample received per PMCs (or merged PMCs). - Display percentage vs all
     samples
    
    ---
     usr.sbin/pmcstat/pmcpl_callgraph.c |  1 +
     usr.sbin/pmcstat/pmcpl_calltree.c  |  9 +++++
     usr.sbin/pmcstat/pmcstat_log.c     | 60 +++++++++++++++++++++++-------
     usr.sbin/pmcstat/pmcstat_log.h     |  2 +
     4 files changed, 59 insertions(+), 13 deletions(-)
    
    diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.c b/usr.sbin/pmcstat/pmcpl_callgraph.c
    index 84e281958de..53d342bfdc1 100644
    --- a/usr.sbin/pmcstat/pmcpl_callgraph.c
    +++ b/usr.sbin/pmcstat/pmcpl_callgraph.c
    @@ -341,6 +341,7 @@ pmcpl_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
     	parent = pmcstat_cgnode_hash_lookup_pc(pp, pmcid, pc, usermode);
     	if (parent == NULL) {
     		pmcstat_stats.ps_callchain_dubious_frames++;
    +		pmcr->pr_dubious_frames++;
     		return;
     	}
     
    diff --git a/usr.sbin/pmcstat/pmcpl_calltree.c b/usr.sbin/pmcstat/pmcpl_calltree.c
    index aac7913c92b..4f62c62158b 100644
    --- a/usr.sbin/pmcstat/pmcpl_calltree.c
    +++ b/usr.sbin/pmcstat/pmcpl_calltree.c
    @@ -403,6 +403,10 @@ pmcpl_ct_node_dumptop(int pmcin, struct pmcpl_ct_node *ct,
     	    &pmcin, pmcpl_ct_arc_compare);
     
     	for (i = 0; i < ct->pct_narc; i++) {
    +		/* Skip this arc if there is no sample at all. */
    +		if (PMCPL_CT_SAMPLE(pmcin,
    +		    &ct->pct_arc[i].pcta_samples) == 0)
    +			continue;
     		if (PMCPL_CT_SAMPLEP(pmcin,
     		    &ct->pct_arc[i].pcta_samples) > pmcstat_threshold) {
     			if (pmcpl_ct_node_dumptop(pmcin,
    @@ -516,6 +520,10 @@ pmcpl_ct_topdisplay(void)
     
     		x = y = 0;
     		for (i = 0; i < pmcpl_ct_root->pct_narc; i++) {
    +			/* Skip this arc if there is no sample at all. */
    +			if (PMCPL_CT_SAMPLE(pmcin,
    +			    &pmcpl_ct_root->pct_arc[i].pcta_samples) == 0)
    +				continue;
     			if (pmcpl_ct_node_dumptop(pmcin,
     			        pmcpl_ct_root->pct_arc[i].pcta_child,
     			        &rsamples, x, &y, pmcstat_displayheight - 2)) {
    @@ -693,6 +701,7 @@ pmcpl_ct_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
     	}
     	if (n-- == 0) {
     		pmcstat_stats.ps_callchain_dubious_frames++;
    +		pmcr->pr_dubious_frames++;
     		return;
     	}
     
    diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c
    index 9b524ff7275..51f66ca9e25 100644
    --- a/usr.sbin/pmcstat/pmcstat_log.c
    +++ b/usr.sbin/pmcstat/pmcstat_log.c
    @@ -247,6 +247,7 @@ static int	pmcstat_string_compute_hash(const char *_string);
     static void pmcstat_string_initialize(void);
     static int	pmcstat_string_lookup_hash(pmcstat_interned_string _is);
     static void pmcstat_string_shutdown(void);
    +static void pmcstat_stats_reset(void);
     
     /*
      * A simple implementation of interned strings.  Each interned string
    @@ -274,6 +275,21 @@ int pmcstat_npmcs;
      */
     int pmcstat_pause;
     
    +static void
    +pmcstat_stats_reset(void)
    +{
    +	struct pmcstat_pmcrecord *pr;
    +
    +	/* Flush PMCs stats. */
    +	LIST_FOREACH(pr, &pmcstat_pmcs, pr_next) {
    +		pr->pr_samples = 0;
    +		pr->pr_dubious_frames = 0;
    +	}
    +
    +	/* Flush global stats. */
    +	bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
    +}
    +
     /*
      * Compute a 'hash' value for a string.
      */
    @@ -1009,6 +1025,8 @@ pmcstat_pmcid_add(pmc_id_t pmcid, pmcstat_interned_string ps)
     	pr->pr_pmcid = pmcid;
     	pr->pr_pmcname = ps;
     	pr->pr_pmcin = pmcstat_npmcs++;
    +	pr->pr_samples = 0;
    +	pr->pr_dubious_frames = 0;
     	pr->pr_merge = prm == NULL ? pr : prm;
     
     	LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next);
    @@ -1387,6 +1405,7 @@ pmcstat_analyze_log(void)
     			/* Get PMC record. */
     			pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_s.pl_pmcid);
     			assert(pmcr != NULL);
    +			pmcr->pr_samples++;
     
     			/*
     			 * Call the plugins processing
    @@ -1420,6 +1439,7 @@ pmcstat_analyze_log(void)
     			/* Get PMC record. */
     			pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_cc.pl_pmcid);
     			assert(pmcr != NULL);
    +			pmcr->pr_samples++;
     
     			/*
     			 * Call the plugins processing
    @@ -1787,32 +1807,46 @@ pmcstat_process_log(void)
     static void
     pmcstat_refresh_top(void)
     {
    +	int v_attrs;
    +	float v;
     	char pmcname[40];
    -	const char *s;
    +	struct pmcstat_pmcrecord *pmcpr;
     
     	/* If in pause mode do not refresh display. */
     	if (pmcstat_pause)
     		return;
     
     	/* Wait until PMC pop in the log. */
    -	s = pmcstat_pmcindex_to_name(pmcstat_pmcinfilter);
    -	if (s == NULL)
    +	pmcpr = pmcstat_pmcindex_to_pmcr(pmcstat_pmcinfilter);
    +	if (pmcpr == NULL)
     		return;
     
     	/* Format PMC name. */
     	if (pmcstat_mergepmc)
    -		snprintf(pmcname, sizeof(pmcname), "[%s]", s);
    +		snprintf(pmcname, sizeof(pmcname), "[%s]",
    +		    pmcstat_string_unintern(pmcpr->pr_pmcname));
     	else
     		snprintf(pmcname, sizeof(pmcname), "%s.%d",
    -		    s, pmcstat_pmcinfilter);
    +		    pmcstat_string_unintern(pmcpr->pr_pmcname),
    +		    pmcstat_pmcinfilter);
    +
    +	/* Format samples count. */
    +	if (pmcstat_stats.ps_samples_total > 0)
    +		v = (pmcpr->pr_samples * 100.0) /
    +		    pmcstat_stats.ps_samples_total;
    +	else
    +		v = 0.;
    +	v_attrs = PMCSTAT_ATTRPERCENT(v);
     
     	PMCSTAT_PRINTBEGIN();
    -	PMCSTAT_PRINTW("PMC: %s Samples: %u processed, %u invalid\n\n",
    +	PMCSTAT_PRINTW("PMC: %s Samples: %u ",
     	    pmcname,
    -	    pmcstat_stats.ps_samples_total,
    -	    pmcstat_stats.ps_samples_unknown_offset +
    -	    pmcstat_stats.ps_samples_indeterminable +
    -	    pmcstat_stats.ps_callchain_dubious_frames);
    +	    pmcpr->pr_samples);
    +	PMCSTAT_ATTRON(v_attrs);
    +	PMCSTAT_PRINTW("(%.1f%%) ", v);
    +	PMCSTAT_ATTROFF(v_attrs);
    +	PMCSTAT_PRINTW(", %u unresolved\n\n",
    +	    pmcpr->pr_dubious_frames);
     	if (plugins[args.pa_plugin].pl_topdisplay != NULL)
     		plugins[args.pa_plugin].pl_topdisplay();
     	PMCSTAT_PRINTEND();
    @@ -1879,7 +1913,7 @@ pmcstat_keypress_log(void)
     		 */
     		if (plugins[args.pa_plugin].pl_shutdown != NULL)
     			plugins[args.pa_plugin].pl_shutdown(NULL);
    -		bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
    +		pmcstat_stats_reset();
     		if (plugins[args.pa_plugin].pl_init != NULL)
     			plugins[args.pa_plugin].pl_init();
     
    @@ -1900,7 +1934,7 @@ pmcstat_keypress_log(void)
     		} while (plugins[args.pa_plugin].pl_topdisplay == NULL);
     
     		/* Open new plugin. */
    -		bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
    +		pmcstat_stats_reset();
     		if (plugins[args.pa_plugin].pl_init != NULL)
     			plugins[args.pa_plugin].pl_init();
     		wprintw(w, "switching to plugin %s",
    @@ -1949,7 +1983,7 @@ pmcstat_display_log(void)
     	if (args.pa_topmode == PMCSTAT_TOP_DELTA) {
     		if (plugins[args.pa_plugin].pl_shutdown != NULL)
     			plugins[args.pa_plugin].pl_shutdown(NULL);
    -		bzero(&pmcstat_stats, sizeof(struct pmcstat_stats));
    +		pmcstat_stats_reset();
     		if (plugins[args.pa_plugin].pl_init != NULL)
     			plugins[args.pa_plugin].pl_init();
     	}
    diff --git a/usr.sbin/pmcstat/pmcstat_log.h b/usr.sbin/pmcstat/pmcstat_log.h
    index de92649c0d7..8936fad0581 100644
    --- a/usr.sbin/pmcstat/pmcstat_log.h
    +++ b/usr.sbin/pmcstat/pmcstat_log.h
    @@ -146,6 +146,8 @@ struct pmcstat_pmcrecord {
     	pmc_id_t			pr_pmcid;
     	int				pr_pmcin;
     	pmcstat_interned_string		pr_pmcname;
    +	int				pr_samples;
    +	int				pr_dubious_frames;
     	struct pmcstat_pmcrecord	*pr_merge;
     };
     extern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs; /* PMC list */
    
    From 3d1783b6c825824a0124cc6e8c4bb70f3179425c Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Tue, 13 Apr 2010 00:48:54 +0000
    Subject: [PATCH 1931/2592] MFC r203710:
    
      When you have multiple addresses on the same network on different
      interfaces (such as when you are part of a carp pool), and you run
      rpcbind -h to restrict which interfaces have rpc services, rpcbind can
      none-the-less return addresses that aren't in the -h list.  This patch
      enforces the rule that when you specify -h on the command line, then
      services returned from rpcbind must be to one of the addresses listed
      in -h, or be a loopback address (since localhost is implicit when
      running -h).
    
      The root cause of this is the assumption in addrmerge that there can
      be only one interface that matches a given network IP address.  This
      turns out not to be the case.  To retain historical behavior, I didn't
      try to fix the routine to prefer the address that the request came
      into, since I didn't know the side effects that might cause in the
      normal case.  My quick analysis suggests that it wouldn't be a
      problem, but since this code is tricky I opted for the more
      conservative patch of only restricting the reply when -h is in effect.
    
      Hence, this change will have no effect when you are running rpcbind
      without -h.
    
      Reviewed by:	alfred@
      Sponsored by:	iX Systems
      MFC after:	2 weeks
    ---
     usr.sbin/rpcbind/rpcbind.c | 76 +++++++++++++++++++++++++++++++++++++-
     usr.sbin/rpcbind/rpcbind.h |  9 +++++
     usr.sbin/rpcbind/util.c    | 20 +++++-----
     3 files changed, 93 insertions(+), 12 deletions(-)
    
    diff --git a/usr.sbin/rpcbind/rpcbind.c b/usr.sbin/rpcbind/rpcbind.c
    index b601da5b6f6..5a76a68f1f3 100644
    --- a/usr.sbin/rpcbind/rpcbind.c
    +++ b/usr.sbin/rpcbind/rpcbind.c
    @@ -92,6 +92,7 @@ int oldstyle_local = 0;
     int verboselog = 0;
     
     char **hosts = NULL;
    +struct sockaddr **bound_sa;
     int ipv6_only = 0;
     int nhosts = 0;
     int on = 1;
    @@ -119,6 +120,7 @@ static void rbllist_add(rpcprog_t, rpcvers_t, struct netconfig *,
     			     struct netbuf *);
     static void terminate(int);
     static void parseargs(int, char *[]);
    +static void update_bound_sa(void);
     
     int
     main(int argc, char *argv[])
    @@ -130,6 +132,8 @@ main(int argc, char *argv[])
     
     	parseargs(argc, argv);
     
    +	update_bound_sa();
    +
     	/* Check that another rpcbind isn't already running. */
     	if ((rpcbindlockfd = (open(RPCBINDDLOCK,
     	    O_RDONLY|O_CREAT, 0444))) == -1)
    @@ -323,8 +327,7 @@ init_transport(struct netconfig *nconf)
     	     * If no hosts were specified, just bind to INADDR_ANY.
     	     * Otherwise  make sure 127.0.0.1 is added to the list.
     	     */
    -	    nhostsbak = nhosts;
    -	    nhostsbak++;
    +	    nhostsbak = nhosts + 1;
     	    hosts = realloc(hosts, nhostsbak * sizeof(char *));
     	    if (nhostsbak == 1)
     	        hosts[0] = "*";
    @@ -657,6 +660,75 @@ error:
     	return (1);
     }
     
    +/*
    + * Create the list of addresses that we're bound to.  Normally, this
    + * list is empty because we're listening on the wildcard address
    + * (nhost == 0).  If -h is specified on the command line, then
    + * bound_sa will have a list of the addresses that the program binds
    + * to specifically.  This function takes that list and converts them to
    + * struct sockaddr * and stores them in bound_sa.
    + */
    +static void
    +update_bound_sa(void)
    +{
    +	struct addrinfo hints, *res = NULL;
    +	int i;
    +
    +	if (nhosts == 0)
    +		return;
    +	bound_sa = malloc(sizeof(*bound_sa) * nhosts);
    +	memset(&hints, 0, sizeof(hints));
    +	hints.ai_family = PF_UNSPEC;
    +	for (i = 0; i < nhosts; i++)  {
    +		if (getaddrinfo(hosts[i], NULL, &hints, &res) != 0)
    +			continue;
    +		bound_sa[i] = malloc(res->ai_addrlen);
    +		memcpy(bound_sa[i], res->ai_addr, res->ai_addrlen);
    +	}
    +}
    +
    +/*
    + * Match the sa against the list of addresses we've bound to.  If
    + * we've not specifically bound to anything, we match everything.
    + * Otherwise, if the IPv4 or IPv6 address matches one of the addresses
    + * in bound_sa, we return true.  If not, we return false.
    + */
    +int
    +listen_addr(const struct sockaddr *sa)
    +{
    +	int i;
    +
    +	/*
    +	 * If nhosts == 0, then there were no -h options on the
    +	 * command line, so all addresses are addresses we're
    +	 * listening to.
    +	 */
    +	if (nhosts == 0)
    +		return 1;
    +	for (i = 0; i < nhosts; i++) {
    +		if (bound_sa[i] == NULL ||
    +		    sa->sa_family != bound_sa[i]->sa_family)
    +			continue;
    +		switch (sa->sa_family) {
    +		case AF_INET:
    +		  	if (memcmp(&SA2SINADDR(sa), &SA2SINADDR(bound_sa[i]),
    +			    sizeof(struct in_addr)) == 0)
    +				return (1);
    +			break;
    +#ifdef INET6
    +		case AF_INET6:
    +		  	if (memcmp(&SA2SIN6ADDR(sa), &SA2SIN6ADDR(bound_sa[i]),
    +			    sizeof(struct in6_addr)) == 0)
    +				return (1);
    +			break;
    +#endif
    +		default:
    +			break;
    +		}
    +	}
    +	return (0);
    +}
    +
     static void
     rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf,
     	    struct netbuf *addr)
    diff --git a/usr.sbin/rpcbind/rpcbind.h b/usr.sbin/rpcbind/rpcbind.h
    index 5537ce4f6a0..717bb3bb11e 100644
    --- a/usr.sbin/rpcbind/rpcbind.h
    +++ b/usr.sbin/rpcbind/rpcbind.h
    @@ -134,6 +134,7 @@ void read_warmstart(void);
     
     char *addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
     		     char *netid);
    +int listen_addr(const struct sockaddr *sa);
     void network_init(void);
     struct sockaddr *local_sa(int);
     
    @@ -141,4 +142,12 @@ struct sockaddr *local_sa(int);
     #define	RPCB_ALLVERS 0
     #define	RPCB_ONEVERS 1
     
    +/* To convert a struct sockaddr to IPv4 or IPv6 address */
    +#define	SA2SIN(sa)	((struct sockaddr_in *)(sa))
    +#define	SA2SINADDR(sa)	(SA2SIN(sa)->sin_addr)
    +#ifdef INET6
    +#define	SA2SIN6(sa)	((struct sockaddr_in6 *)(sa))
    +#define	SA2SIN6ADDR(sa)	(SA2SIN6(sa)->sin6_addr)
    +#endif
    +
     #endif /* rpcbind_h */
    diff --git a/usr.sbin/rpcbind/util.c b/usr.sbin/rpcbind/util.c
    index 66797a70fa0..9cdfa705461 100644
    --- a/usr.sbin/rpcbind/util.c
    +++ b/usr.sbin/rpcbind/util.c
    @@ -58,13 +58,6 @@
     
     #include "rpcbind.h"
     
    -#define	SA2SIN(sa)	((struct sockaddr_in *)(sa))
    -#define	SA2SINADDR(sa)	(SA2SIN(sa)->sin_addr)
    -#ifdef INET6
    -#define	SA2SIN6(sa)	((struct sockaddr_in6 *)(sa))
    -#define	SA2SIN6ADDR(sa)	(SA2SIN6(sa)->sin6_addr)
    -#endif
    -
     static struct sockaddr_in *local_in4;
     #ifdef INET6
     static struct sockaddr_in6 *local_in6;
    @@ -176,9 +169,13 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
     		goto freeit;
     
     	/*
    -	 * Loop through all interfaces. For each interface, see if the
    -	 * network portion of its address is equal to that of the client.
    -	 * If so, we have found the interface that we want to use.
    +	 * Loop through all interfaces. For each interface, see if it
    +	 * is either the loopback interface (which we always listen
    +	 * on) or is one of the addresses the program bound to (the
    +	 * wildcard by default, or a subset if -h is specified) and
    +	 * the network portion of its address is equal to that of the
    +	 * client.  If so, we have found the interface that we want to
    +	 * use.
     	 */
     	bestif = NULL;
     	for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
    @@ -189,6 +186,9 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
     		    !(ifap->ifa_flags & IFF_UP))
     			continue;
     
    +		if (!(ifap->ifa_flags & IFF_LOOPBACK) && !listen_addr(ifsa))
    +			continue;
    +
     		switch (hint_sa->sa_family) {
     		case AF_INET:
     			/*
    
    From 4bbe66c93fbb029deb0808b19a21e51a9b246859 Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Tue, 13 Apr 2010 00:55:11 +0000
    Subject: [PATCH 1932/2592] MFC 205838:
    
      Mark the vtoc.h structure as packed so that it is the right size and
      layout on arm.
    
      MFC after:	7 days
    ---
     sys/sys/vtoc.h | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/sys/vtoc.h b/sys/sys/vtoc.h
    index 231da0055b2..7745bcac4b0 100644
    --- a/sys/sys/vtoc.h
    +++ b/sys/sys/vtoc.h
    @@ -97,7 +97,7 @@ struct vtoc8 {
     	} map[VTOC8_NPARTS];
     	uint16_t	magic;
     	uint16_t	cksum;
    -};
    +} __packed;
     
     #ifdef CTASSERT
     CTASSERT(sizeof(struct vtoc8) == 512);
    
    From 4e6eaf365b803e199edd8c5da38c67b2add2a1ad Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Tue, 13 Apr 2010 00:57:54 +0000
    Subject: [PATCH 1933/2592] MFC 205980:
    
      Stop hard coding i386 as the arch for the build.  Instead, default to the
      processor we're running on.  Also, supply amd64 version of create_diskimage
      that's the same as i386's.
    
      # didn't fix the confusion between using the processor for this and using
      # the machine (which would be more appropriate).  NANO_ARCH smashes the two
      # together right now.
    
      MFC after:	7 days
    ---
     tools/tools/nanobsd/nanobsd.sh | 10 +++++++++-
     1 file changed, 9 insertions(+), 1 deletion(-)
    
    diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh
    index 10d8f78b6c9..e50db8bd3b2 100644
    --- a/tools/tools/nanobsd/nanobsd.sh
    +++ b/tools/tools/nanobsd/nanobsd.sh
    @@ -134,7 +134,7 @@ PPLEVEL=3
     #######################################################################
     # Not a variable at this time
     
    -NANO_ARCH=i386
    +NANO_ARCH=`uname -p`
     
     #######################################################################
     #
    @@ -238,6 +238,9 @@ install_etc ( ) (
     	${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} distribution \
     		DESTDIR=${NANO_WORLDDIR} \
     		> ${NANO_OBJ}/_.etc 2>&1
    +	# make.conf doesn't get created by default, but some ports need it
    +	# so they can spam it.
    +	cp /dev/null ${NANO_WORLDDIR}/etc/make.conf
     )
     
     install_kernel ( ) (
    @@ -497,6 +500,11 @@ create_i386_diskimage ( ) (
     	) > ${NANO_OBJ}/_.di 2>&1
     )
     
    +# i386 and amd64 are identical for disk images
    +create_amd64_diskimage ( ) (
    +	create_i386_diskimage
    +)
    +
     last_orders () (
     	# Redefine this function with any last orders you may have
     	# after the build completed, for instance to copy the finished
    
    From 92f7bd5aecfc359f6b962f89176a6ab3f7825b90 Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Tue, 13 Apr 2010 01:02:20 +0000
    Subject: [PATCH 1934/2592] MFC: 205992
    
      Make -r mean exactly the same thing as -E for increased compatibility
      with GNU sed.
    
      MFC after:	7 days
    ---
     usr.bin/sed/main.c | 3 ++-
     usr.bin/sed/sed.1  | 8 ++++++--
     2 files changed, 8 insertions(+), 3 deletions(-)
    
    diff --git a/usr.bin/sed/main.c b/usr.bin/sed/main.c
    index 1a140b14414..8d4fe95a33d 100644
    --- a/usr.bin/sed/main.c
    +++ b/usr.bin/sed/main.c
    @@ -130,8 +130,9 @@ main(int argc, char *argv[])
     	fflag = 0;
     	inplace = NULL;
     
    -	while ((c = getopt(argc, argv, "EI:ae:f:i:ln")) != -1)
    +	while ((c = getopt(argc, argv, "EI:ae:f:i:lnr")) != -1)
     		switch (c) {
    +		case 'r':		/* Gnu sed compat */
     		case 'E':
     			rflags = REG_EXTENDED;
     			break;
    diff --git a/usr.bin/sed/sed.1 b/usr.bin/sed/sed.1
    index d5858ffc82f..0744630b57a 100644
    --- a/usr.bin/sed/sed.1
    +++ b/usr.bin/sed/sed.1
    @@ -39,11 +39,11 @@
     .Nd stream editor
     .Sh SYNOPSIS
     .Nm
    -.Op Fl Ealn
    +.Op Fl Ealnr
     .Ar command
     .Op Ar
     .Nm
    -.Op Fl Ealn
    +.Op Fl Ealnr
     .Op Fl e Ar command
     .Op Fl f Ar command_file
     .Op Fl I Ar extension
    @@ -144,6 +144,10 @@ all of the commands have been applied to it.
     The
     .Fl n
     option suppresses this behavior.
    +.It Fl r
    +Same as
    +.Fl E 
    +for compatibility with GNU sed.
     .El
     .Pp
     The form of a
    
    From 3a1e7f892f80d8ec2d064bba8c14037361fcb9be Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Tue, 13 Apr 2010 01:04:11 +0000
    Subject: [PATCH 1935/2592] MFC: 205994
    
      Two fixes:
    
      (1) We don't need a custom install_kernel.  We can install without
      symbols by adding INSTALL_NODEBUG (which likely should be
      WITHOUT_KERNEL_SYMBOLS_FILE, or something shorter) to CONF_INSTALL
      (2) for make buildenv stage, use NANO_MAKE_CONF_BUILD rather than the
      non-existant NANO_MAKE_CONF.
    
      MFC after:	7 days
    ---
     tools/tools/nanobsd/gateworks/common | 17 ++---------------
     1 file changed, 2 insertions(+), 15 deletions(-)
    
    diff --git a/tools/tools/nanobsd/gateworks/common b/tools/tools/nanobsd/gateworks/common
    index 750cd39b1da..2e2d46c52ba 100644
    --- a/tools/tools/nanobsd/gateworks/common
    +++ b/tools/tools/nanobsd/gateworks/common
    @@ -37,7 +37,7 @@ NANO_CUSTOMIZE="$NANO_CUSTOMIZE cust_install_files cust_install_machine_files"
     buildenv()
     {
     	cd ${NANO_SRC}
    -	env TARGET_ARCH=${NANO_ARCH} __MAKE_CONF=${NANO_MAKE_CONF} \
    +	env TARGET_ARCH=${NANO_ARCH} __MAKE_CONF=${NANO_MAKE_CONF_BUILD} \
     	    DESTDIR=${NANO_WORLDDIR} make buildenv
     }
     
    @@ -146,22 +146,9 @@ WITHOUT_TCSH=true
     CONF_INSTALL="$CONF_BUILD
     WITHOUT_TOOLCHAIN=true
     WITHOUT_INSTALLLIB=true
    +INSTALL_NODEBUG=true
     "
     
    -# NB: override to suppress install of kernel.symbols
    -install_kernel()
    -{
    -	pprint 2 "install kernel"
    -	pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.ik"
    -
    -	cd ${NANO_SRC}
    -	env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} installkernel \
    -		INSTALL_NODEBUG=true \
    -		DESTDIR=${NANO_WORLDDIR} \
    -		__MAKE_CONF=${NANO_MAKE_CONF} KERNCONF=`basename ${NANO_KERNEL}` \
    -		> ${MAKEOBJDIRPREFIX}/_.ik 2>&1
    -}
    -
     # NB: override to force / on s1 instead of s1a
     setup_nanobsd_etc()
     {
    
    From 5b796d064a914d9a92300be97944609fe3fd30f5 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Tue, 13 Apr 2010 06:01:24 +0000
    Subject: [PATCH 1936/2592] MFC r205796:
    
    Make acl_to_text_np(3) not crash on long group or user names in NFSv4 ACLs.
    
    PR:		amd64/145091
    ---
     lib/libc/posix1e/acl_to_text_nfs4.c | 11 ++++-------
     1 file changed, 4 insertions(+), 7 deletions(-)
    
    diff --git a/lib/libc/posix1e/acl_to_text_nfs4.c b/lib/libc/posix1e/acl_to_text_nfs4.c
    index 3adbfb4bd92..5d0aa319143 100644
    --- a/lib/libc/posix1e/acl_to_text_nfs4.c
    +++ b/lib/libc/posix1e/acl_to_text_nfs4.c
    @@ -167,7 +167,7 @@ format_additional_id(char *str, size_t size, const acl_entry_t entry)
     static int
     format_entry(char *str, size_t size, const acl_entry_t entry, int flags)
     {
    -	size_t off = 0, padding_length, maximum_who_field_length = 18;
    +	size_t off = 0, min_who_field_length = 18;
     	acl_permset_t permset;
     	acl_flagset_t flagset;
     	int error, len;
    @@ -188,12 +188,9 @@ format_entry(char *str, size_t size, const acl_entry_t entry, int flags)
     	if (error)
     		return (error);
     	len = strlen(buf);
    -	padding_length = maximum_who_field_length - len;
    -	if (padding_length > 0) {
    -		memset(str, ' ', padding_length);
    -		off += padding_length;
    -	}
    -	off += snprintf(str + off, size - off, "%s:", buf);
    +	if (len < min_who_field_length)
    +		len = min_who_field_length;
    +	off += snprintf(str + off, size - off, "%*s:", len, buf);
     
     	error = _nfs4_format_access_mask(buf, sizeof(buf), *permset,
     	    flags & ACL_TEXT_VERBOSE);
    
    From 1d7437b3dbcaf12bd618358935b9a559b9e4b8c2 Mon Sep 17 00:00:00 2001
    From: Edward Tomasz Napierala 
    Date: Tue, 13 Apr 2010 06:05:15 +0000
    Subject: [PATCH 1937/2592] MFC r205853:
    
    Add myself.
    ---
     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 54d17af4275..cbb16963cdd 100644
    --- a/usr.bin/calendar/calendars/calendar.freebsd
    +++ b/usr.bin/calendar/calendars/calendar.freebsd
    @@ -107,6 +107,7 @@
     04/03	Tong Liu  born in Beijing, People's Republic of China, 1981
     04/03	Gabor Pali  born in Kunhegyes, Hungary, 1982
     04/05	Stacey Son  born in Burley, Idaho, United States. 1967
    +04/07	Edward Tomasz Napierala  born in Wolsztyn, Poland, 1981
     04/08	Jordan K. Hubbard  born in Honolulu, Hawaii, United States, 1963
     04/09	Ceri Davies  born in Haverfordwest, Pembrokeshire, United Kingdom, 1976
     04/11	Bruce A. Mah  born in Fresno, California, United States, 1969
    
    From a0e70f3995795a417d5119670d24d699ae1a20ae Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 13 Apr 2010 10:23:03 +0000
    Subject: [PATCH 1938/2592] MFC r206459: Handle a case when non-canonical
     address is loaded into the fsbase or gsbase MSR.
    
    ---
     sys/amd64/amd64/exception.S | 30 ++++++++++++++++++++++++++++--
     sys/amd64/amd64/trap.c      |  8 ++++++++
     sys/amd64/include/md_var.h  |  4 ++++
     3 files changed, 40 insertions(+), 2 deletions(-)
    
    diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
    index 1799b7466e2..69288f38d0b 100644
    --- a/sys/amd64/amd64/exception.S
    +++ b/sys/amd64/amd64/exception.S
    @@ -668,7 +668,8 @@ ld_fs:	movw	%ax,%fs
     	movl	$MSR_FSBASE,%ecx
     	movl	PCB_FSBASE(%r8),%eax
     	movl	PCB_FSBASE+4(%r8),%edx
    -	wrmsr
    +	.globl	ld_fsbase
    +ld_fsbase: wrmsr
     1:
     	/* Restore %gs and gsbase */
     	movw	TF_GS(%rsp),%si
    @@ -685,7 +686,8 @@ ld_gs:	movw	%si,%gs
     	movl	$MSR_KGSBASE,%ecx
     	movl	PCB_GSBASE(%r8),%eax
     	movl	PCB_GSBASE+4(%r8),%edx
    -	wrmsr
    +	.globl	ld_gsbase
    +ld_gsbase: wrmsr
     1:	.globl	ld_es
     ld_es:	movw	TF_ES(%rsp),%es
     	.globl	ld_ds
    @@ -798,6 +800,30 @@ gs_load_fault:
     	call	trap
     	movw	$KUG32SEL,TF_GS(%rsp)
     	jmp	doreti
    +
    +	ALIGN_TEXT
    +	.globl	fsbase_load_fault
    +fsbase_load_fault:
    +	movl	$T_PROTFLT,TF_TRAPNO(%rsp)
    +	movq	%rsp, %rdi
    +	call	trap
    +	movq	PCPU(CURTHREAD),%r8
    +	movq	TD_PCB(%r8),%r8
    +	movq	$0,PCB_FSBASE(%r8)
    +	jmp	doreti
    +
    +	ALIGN_TEXT
    +	.globl	gsbase_load_fault
    +gsbase_load_fault:
    +	popfq
    +	movl	$T_PROTFLT,TF_TRAPNO(%rsp)
    +	movq	%rsp, %rdi
    +	call	trap
    +	movq	PCPU(CURTHREAD),%r8
    +	movq	TD_PCB(%r8),%r8
    +	movq	$0,PCB_GSBASE(%r8)
    +	jmp	doreti
    +
     #ifdef HWPMC_HOOKS
     	ENTRY(end_exceptions)
     #endif
    diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
    index 41ca7581071..4b5d8c7b48f 100644
    --- a/sys/amd64/amd64/trap.c
    +++ b/sys/amd64/amd64/trap.c
    @@ -563,6 +563,14 @@ trap(struct trapframe *frame)
     				frame->tf_gs = _ugssel;
     				goto out;
     			}
    +			if (frame->tf_rip == (long)ld_gsbase) {
    +				frame->tf_rip = (long)gsbase_load_fault;
    +				goto out;
    +			}
    +			if (frame->tf_rip == (long)ld_fsbase) {
    +				frame->tf_rip = (long)fsbase_load_fault;
    +				goto out;
    +			}
     			if (PCPU_GET(curpcb)->pcb_onfault != NULL) {
     				frame->tf_rip =
     				    (long)PCPU_GET(curpcb)->pcb_onfault;
    diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
    index 2b43b37cc18..88f3e1dbaed 100644
    --- a/sys/amd64/include/md_var.h
    +++ b/sys/amd64/include/md_var.h
    @@ -83,10 +83,14 @@ void	ld_ds(void) __asm(__STRING(ld_ds));
     void	ld_es(void) __asm(__STRING(ld_es));
     void	ld_fs(void) __asm(__STRING(ld_fs));
     void	ld_gs(void) __asm(__STRING(ld_gs));
    +void	ld_fsbase(void) __asm(__STRING(ld_fsbase));
    +void	ld_gsbase(void) __asm(__STRING(ld_gsbase));
     void	ds_load_fault(void) __asm(__STRING(ds_load_fault));
     void	es_load_fault(void) __asm(__STRING(es_load_fault));
     void	fs_load_fault(void) __asm(__STRING(fs_load_fault));
     void	gs_load_fault(void) __asm(__STRING(gs_load_fault));
    +void	fsbase_load_fault(void) __asm(__STRING(fsbase_load_fault));
    +void	gsbase_load_fault(void) __asm(__STRING(gsbase_load_fault));
     void	dump_add_page(vm_paddr_t);
     void	dump_drop_page(vm_paddr_t);
     void	initializecpu(void);
    
    From e7edb3e30946a61a4d319257c50f61e6412c5041 Mon Sep 17 00:00:00 2001
    From: Ed Maste 
    Date: Tue, 13 Apr 2010 18:46:18 +0000
    Subject: [PATCH 1939/2592] MFC r205880 by ru:
    
      - Handle calloc() allocation failures.
      - Fixed a comment.
      - 2 -> EXIT_FAILURE in some places.
      - errx() -> err() where appropriate.
    
    PR:		144644
    Submitted by:	Garrett Cooper
    
    Also fix endinclude() prototype to avoid compiler warning.
    ---
     usr.sbin/config/config.y     | 10 ++++++++++
     usr.sbin/config/lang.l       |  5 ++++-
     usr.sbin/config/main.c       | 20 +++++++++++---------
     usr.sbin/config/mkmakefile.c |  2 ++
     usr.sbin/config/mkoptions.c  | 10 ++++++++++
     5 files changed, 37 insertions(+), 10 deletions(-)
    
    diff --git a/usr.sbin/config/config.y b/usr.sbin/config/config.y
    index 9425daf3c33..19f2779fd47 100644
    --- a/usr.sbin/config/config.y
    +++ b/usr.sbin/config/config.y
    @@ -166,6 +166,8 @@ Config_spec:
     	CPU Save_id {
     		struct cputype *cp =
     		    (struct cputype *)calloc(1, sizeof (struct cputype));
    +		if (cp == NULL)
    +			err(EXIT_FAILURE, "calloc");
     		cp->cpu_name = $2;
     		SLIST_INSERT_HEAD(&cputype, cp, cpu_next);
     	      } |
    @@ -197,6 +199,8 @@ Config_spec:
     		struct hint *hint;
     
     		hint = (struct hint *)calloc(1, sizeof (struct hint));
    +		if (hint == NULL)
    +			err(EXIT_FAILURE, "calloc");	
     		hint->hint_name = $2;
     		STAILQ_INSERT_TAIL(&hints, hint, hint_next);
     		hintmode = 1;
    @@ -331,6 +335,8 @@ newfile(char *name)
     	struct files_name *nl;
     	
     	nl = (struct files_name *) calloc(1, sizeof *nl);
    +	if (nl == NULL)
    +		err(EXIT_FAILURE, "calloc");
     	nl->f_name = name;
     	STAILQ_INSERT_TAIL(&fntab, nl, f_next);
     }
    @@ -364,6 +370,8 @@ newdev(char *name)
     	}
     
     	np = (struct device *) calloc(1, sizeof *np);
    +	if (np == NULL)
    +		err(EXIT_FAILURE, "calloc");
     	np->d_name = name;
     	STAILQ_INSERT_TAIL(&dtab, np, d_next);
     }
    @@ -422,6 +430,8 @@ newopt(struct opt_head *list, char *name, char *value, int append)
     	}
     
     	op = (struct opt *)calloc(1, sizeof (struct opt));
    +	if (op == NULL)
    +		err(EXIT_FAILURE, "calloc");
     	op->op_name = name;
     	op->op_ownfile = 0;
     	op->op_value = value;
    diff --git a/usr.sbin/config/lang.l b/usr.sbin/config/lang.l
    index 075f21f4dfc..4eb94da933f 100644
    --- a/usr.sbin/config/lang.l
    +++ b/usr.sbin/config/lang.l
    @@ -33,6 +33,7 @@
     
     #include 
     #include 
    +#include 
     #include 
     #include "y.tab.h"
     #include "config.h"
    @@ -220,6 +221,8 @@ cfgfile_add(const char *fname)
     	struct cfgfile *cf;
     
     	cf = calloc(1, sizeof(*cf));
    +	if (cf == NULL)
    +		err(EXIT_FAILURE, "calloc");
     	assert(cf != NULL);
     	asprintf(&cf->cfg_path, "%s", fname);
     	STAILQ_INSERT_TAIL(&cfgfiles, cf, cfg_next);
    @@ -285,7 +288,7 @@ include(const char *fname, int ateof)
      * Terminate the most recent inclusion.
      */
     static int
    -endinclude()
    +endinclude(void)
     {
     	struct incl *in;
     	int ateof;
    diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c
    index 34806ab7df8..2b5e055130b 100644
    --- a/usr.sbin/config/main.c
    +++ b/usr.sbin/config/main.c
    @@ -120,7 +120,7 @@ main(int argc, char **argv)
     			if (*destdir == '\0')
     				strlcpy(destdir, optarg, sizeof(destdir));
     			else
    -				errx(2, "directory already set");
    +				errx(EXIT_FAILURE, "directory already set");
     			break;
     		case 'g':
     			debugging++;
    @@ -175,7 +175,7 @@ main(int argc, char **argv)
     		if (mkdir(p, 0777))
     			err(2, "%s", p);
     	} else if (!S_ISDIR(buf.st_mode))
    -		errx(2, "%s isn't a directory", p);
    +		errx(EXIT_FAILURE, "%s isn't a directory", p);
     
     	SLIST_INIT(&cputype);
     	SLIST_INIT(&mkopt);
    @@ -256,7 +256,7 @@ get_srcdir(void)
     	int i;
     
     	if (realpath("../..", srcdir) == NULL)
    -		errx(2, "Unable to find root of source tree");
    +		err(EXIT_FAILURE, "Unable to find root of source tree");
     	if ((pwd = getenv("PWD")) != NULL && *pwd == '/' &&
     	    (pwd = strdup(pwd)) != NULL) {
     		/* Remove the last two path components. */
    @@ -513,7 +513,7 @@ configfile(void)
     	}
     	sbuf_finish(sb);
     	/* 
    -	 * We print first part of the tamplate, replace our tag with
    +	 * We print first part of the template, replace our tag with
     	 * configuration files content and later continue writing our
     	 * template.
     	 */
    @@ -650,6 +650,8 @@ remember(const char *file)
     		}
     	}
     	hl = calloc(1, sizeof(*hl));
    +	if (hl == NULL)
    +		err(EXIT_FAILURE, "calloc");
     	hl->h_name = s;
     	hl->h_next = htab;
     	htab = hl;
    @@ -671,19 +673,19 @@ kernconfdump(const char *file)
     
     	r = open(file, O_RDONLY);
     	if (r == -1)
    -		errx(EXIT_FAILURE, "Couldn't open file '%s'", file);
    +		err(EXIT_FAILURE, "Couldn't open file '%s'", file);
     	error = fstat(r, &st);
     	if (error == -1)
    -		errx(EXIT_FAILURE, "fstat() failed");
    +		err(EXIT_FAILURE, "fstat() failed");
     	if (S_ISDIR(st.st_mode))
     		errx(EXIT_FAILURE, "'%s' is a directory", file);
     	fp = fdopen(r, "r");
     	if (fp == NULL)
    -		errx(EXIT_FAILURE, "fdopen() failed");
    +		err(EXIT_FAILURE, "fdopen() failed");
     	osz = 1024;
     	o = calloc(1, osz);
     	if (o == NULL)
    -		errx(EXIT_FAILURE, "Couldn't allocate memory");
    +		err(EXIT_FAILURE, "Couldn't allocate memory");
     	/* ELF note section header. */
     	asprintf(&cmd, "/usr/bin/elfdump -c %s | grep -A 5 kern_conf"
     	    "| tail -2 | cut -d ' ' -f 2 | paste - - -", file);
    @@ -703,7 +705,7 @@ kernconfdump(const char *file)
     		    "INCLUDE_CONFIG_FILE", file);
     	r = fseek(fp, off, SEEK_CUR);
     	if (r != 0)
    -		errx(EXIT_FAILURE, "fseek() failed");
    +		err(EXIT_FAILURE, "fseek() failed");
     	for (i = 0; i < size - 1; i++) {
     		r = fgetc(fp);
     		if (r == EOF)
    diff --git a/usr.sbin/config/mkmakefile.c b/usr.sbin/config/mkmakefile.c
    index a89db8eba7a..f0d37faadc8 100644
    --- a/usr.sbin/config/mkmakefile.c
    +++ b/usr.sbin/config/mkmakefile.c
    @@ -98,6 +98,8 @@ new_fent(void)
     	struct file_list *fp;
     
     	fp = (struct file_list *) calloc(1, sizeof *fp);
    +	if (fp == NULL)
    +		err(EXIT_FAILURE, "calloc");
     	STAILQ_INSERT_TAIL(&ftab, fp, f_next);
     	return (fp);
     }
    diff --git a/usr.sbin/config/mkoptions.c b/usr.sbin/config/mkoptions.c
    index c4bd6246440..5cd9d61a824 100644
    --- a/usr.sbin/config/mkoptions.c
    +++ b/usr.sbin/config/mkoptions.c
    @@ -70,6 +70,8 @@ options(void)
     	/* Fake the cpu types as options. */
     	SLIST_FOREACH(cp, &cputype, cpu_next) {
     		op = (struct opt *)calloc(1, sizeof(*op));
    +		if (op == NULL)
    +			err(EXIT_FAILURE, "calloc");
     		op->op_name = ns(cp->cpu_name);
     		SLIST_INSERT_HEAD(&opt, op, op_next);
     	}	
    @@ -84,6 +86,8 @@ options(void)
     
     	/* Fake MAXUSERS as an option. */
     	op = (struct opt *)calloc(1, sizeof(*op));
    +	if (op == NULL)
    +		err(EXIT_FAILURE, "calloc");
     	op->op_name = ns("MAXUSERS");
     	snprintf(buf, sizeof(buf), "%d", maxusers);
     	op->op_value = ns(buf);
    @@ -199,6 +203,8 @@ do_option(char *name)
     			tidy++;
     		} else {
     			op = (struct opt *) calloc(1, sizeof *op);
    +			if (op == NULL)
    +				err(EXIT_FAILURE, "calloc");
     			op->op_name = inw;
     			op->op_value = invalue;
     			SLIST_INSERT_HEAD(&op_head, op, op_next);
    @@ -225,6 +231,8 @@ do_option(char *name)
     	if (value && !seen) {
     		/* New option appears */
     		op = (struct opt *) calloc(1, sizeof *op);
    +		if (op == NULL)
    +			err(EXIT_FAILURE, "calloc");
     		op->op_name = ns(name);
     		op->op_value = value ? ns(value) : NULL;
     		SLIST_INSERT_HEAD(&op_head, op, op_next);
    @@ -336,6 +344,8 @@ next:
     	}
     	
     	po = (struct opt_list *) calloc(1, sizeof *po);
    +	if (po == NULL)
    +		err(EXIT_FAILURE, "calloc");
     	po->o_name = this;
     	po->o_file = val;
     	SLIST_INSERT_HEAD(&otab, po, o_next);
    
    From 6cb7b50152715e222462b2d9dc1a5d471c20f80d Mon Sep 17 00:00:00 2001
    From: Doug Barton 
    Date: Tue, 13 Apr 2010 20:36:54 +0000
    Subject: [PATCH 1940/2592] MFC r206248:
    
    Change where we nap so that if pwait(1) returns but kill -0 still sees
    a zombie we don't print an endless string of the same pid number until
    the zombie exits.
    
    While I'm here, local'ize the variables that this function uses.
    ---
     etc/rc.subr | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/etc/rc.subr b/etc/rc.subr
    index 091ac3fed7e..c2b1b42971d 100644
    --- a/etc/rc.subr
    +++ b/etc/rc.subr
    @@ -372,6 +372,8 @@ _find_processes()
     #
     wait_for_pids()
     {
    +	local _list _prefix _nlist _j
    +
     	_list="$@"
     	if [ -z "$_list" ]; then
     		return
    @@ -382,6 +384,7 @@ wait_for_pids()
     		for _j in $_list; do
     			if kill -0 $_j 2>/dev/null; then
     				_nlist="${_nlist}${_nlist:+ }$_j"
    +				[ -n "$_prefix" ] && sleep 1
     			fi
     		done
     		if [ -z "$_nlist" ]; then
    @@ -390,7 +393,7 @@ wait_for_pids()
     		_list=$_nlist
     		echo -n ${_prefix:-"Waiting for PIDS: "}$_list
     		_prefix=", "
    -		pwait $_list 2>/dev/null || sleep 2
    +		pwait $_list 2>/dev/null
     	done
     	if [ -n "$_prefix" ]; then
     		echo "."
    
    From 459706bd14107c1836ea8218b72ce3077bdad72c Mon Sep 17 00:00:00 2001
    From: Doug Barton 
    Date: Tue, 13 Apr 2010 20:44:16 +0000
    Subject: [PATCH 1941/2592] MFC r205995:
    
    Massive cleanup and synchronization with other *BSDs
    ---
     games/fortune/Notes                    |   16 +-
     games/fortune/datfiles/fortunes        | 2173 ++++++++++++------------
     games/fortune/datfiles/fortunes-o.real |  358 ++--
     games/fortune/datfiles/fortunes.sp.ok  |   47 +-
     games/fortune/datfiles/limerick        |   22 +-
     games/fortune/datfiles/startrek        |    5 +-
     games/fortune/datfiles/zippy           |   12 +-
     7 files changed, 1312 insertions(+), 1321 deletions(-)
    
    diff --git a/games/fortune/Notes b/games/fortune/Notes
    index 83b062defa3..f049391d7d6 100644
    --- a/games/fortune/Notes
    +++ b/games/fortune/Notes
    @@ -19,13 +19,13 @@ Warning:
     /usr/share/games/fortune.  A fortune file has two parts: the source file
     (which contains the fortunes themselves) and the data file which describes
     the fortunes.  The data file always has the same name as the fortune file
    -with the string ".dat" concatenated, i.e. "fort" is the standard fortune
    -database, and "fort.dat" is the data file which describes it.  See
    +with the string ".dat" concatenated, i.e. "fortunes" is the standard fortune
    +database, and "fortunes.dat" is the data file which describes it.  See
     strfile(8) for more information on creating the data files.
     	Fortunes are split into potentially offensive and not potentially
     offensive parts.  The offensive version of a file has the same name as the
    -non-offensive version with "-o" concatenated, i.e. "fort" is the standard
    -fortune database, and "fort-o" is the standard offensive database.  The
    +non-offensive version with "-o" concatenated, i.e. "fortunes" is the standard
    +fortune database, and "fortunes-o" is the standard offensive database.  The
     fortune program automatically assumes that any file with a name ending in
     "-o" is potentially offensive, and should therefore only be displayed if
     explicitly requested, either with the -o option or by specifying a file name
    @@ -42,10 +42,10 @@ MUST be in the potentially offensive database.  Fortunes containing any
     explicit language (see George Carlin's recent updated list) MUST be in the
     potentially offensive database.  Political and religious opinions are often
     sequestered in the potentially offensive section as well.  Anything which
    -assumes as a world view blatantly racist, mysogynist (sexist), or homophobic
    +assumes as a world view blatantly racist, misogynist (sexist), or homophobic
     ideas should not be in either, since they are not really funny unless *you*
    -are racist, mysogynist, or homophobic.
    -	The point of this is that people have should have a reasonable
    +are racist, misogynist, or homophobic.
    +	The point of this is that people should have a reasonable
     expectation that, should they just run "fortune", they will not be offended.
     We know that some people take offense at anything, but normal people do have
     opinions, too, and have a right not to have their sensibilities offended by
    @@ -53,7 +53,7 @@ a program which is supposed to be entertaining.  People who run "fortune
     -o" or "fortune -a" are saying, in effect, that they are willing to have
     their sensibilities tweaked.  However, they should not have their personal
     worth seriously (i.e., not in jest) assaulted.  Jokes which depend for their
    -humor on racist, mysogynist, or homophobic stereotypes *do* seriously
    +humor on racist, misogynist, or homophobic stereotypes *do* seriously
     assault individual personal worth, and in a general entertainment medium
     we should be able to get by without it.
     
    diff --git a/games/fortune/datfiles/fortunes b/games/fortune/datfiles/fortunes
    index 06ec724f958..7d6fdd55517 100644
    --- a/games/fortune/datfiles/fortunes
    +++ b/games/fortune/datfiles/fortunes
    @@ -368,8 +368,10 @@ OR'd together, outta sight!
     	Double bucky, I'd like a whole word of
     	Double bucky, I'm happy I heard of
     	Double bucky, I'd like a whole word of you!
    -
    -		-- (C) 1978 by Guy L. Steele, Jr.
    +		-- Guy L. Steele, Jr., (C) 1978
    +		(to Nicholas Wirth, who suggested that an extra bit
    +		be added to terminal codes on 36-bit machines for use
    +		by screen editors.)
     %
     		Hard Copies and Chmod
     
    @@ -834,7 +836,7 @@ would like on it.  "Here lies an honest man and a lawyer," responded the
     lawyer.
     	"Sorry, but I can't do that," replied the stonecutter.  "In this
     state, it's against the law to bury two people in the same grave.  However,
    -I could put ``here lies an honest lawyer'', if that would be okay."
    +I could put `here lies an honest lawyer', if that would be okay."
     	"But that won't let people know who it is" protested the lawyer.
     	"Certainly will," retorted the stonecutter.  "people will read it
     and exclaim, "That's Strange!"
    @@ -1146,7 +1148,7 @@ strings of pearls.  The spirit and intent of the program should be retained
     throughout.  There should be neither too little nor too much, neither needless
     loops nor useless variables, neither lack of structure nor overwhelming
     rigidity.
    -	A program should follow the 'Law of Least Astonishment'.  What is this
    +	A program should follow the "Law of Least Astonishment."  What is this
     law?  It is simply that the program should always respond to the user in the
     way that astonishes him least.
     	A program, no matter how complex, should act as a single unit.  The
    @@ -1161,7 +1163,7 @@ program.
     conference and then returned to report to his manager, saying: "What sort
     of programmers work for other companies?  They behaved badly and were
     unconcerned with appearances. Their hair was long and unkempt and their
    -clothes were wrinkled and old. They crashed out hospitality suites and they
    +clothes were wrinkled and old. They crashed our hospitality suites and they
     made rude noises during my presentation."
     	The manager said: "I should have never sent you to the conference.
     Those programmers live beyond the physical world.  They consider life absurd,
    @@ -1466,7 +1468,7 @@ generalizable.
     	The general tendency is to over-design the second system, using all
     the ideas and frills that were cautiously sidetracked on the first one.
     The result, as Ovid says, is a "big pile".
    -		-- Frederick Brooks, "The Mythical Man Month"
    +		-- Frederick Brooks, Jr., "The Mythical Man-Month"
     %
     	An eighty-year-old woman is rocking away the afternoon on her
     porch when she sees an old, tarnished lamp sitting near the steps.  She
    @@ -1513,7 +1515,7 @@ over canoe frames, for my people need transportation.  We are a fair people,
     and we offer you a chance to kill yourself with our ceremonial knife."
     	The Englishman accepts the knife and yells, "God Save the Queen",
     while plunging the knife into his heart.
    - 	The Frenchman removes the knife from the fallen body, and yells,
    +	The Frenchman removes the knife from the fallen body, and yells,
     "Vive la France", while plunging the knife into his heart.
     	The American removes the knife from the fallen body, and yells,
     while stabbing himself all over his body, "Here's your lousy canoe!"
    @@ -1562,7 +1564,7 @@ a postcard?"
     	"The curious incident of the stable dog in the nighttime."
     	"But the dog did nothing in the nighttime."
     	"That was the curious incident."
    -		-- A. Conan Doyle, "Silver Blaze"
    +		-- Sir Arthur Conan Doyle, "Silver Blaze"
     %
     	Approaching the gates of the monastery, Hakuin found Ken the Zen
     preaching to a group of disciples.
    @@ -1609,8 +1611,8 @@ Los Angeles fainted from hyperoxygenation, and we had to hold his head
     under the exhaust of a bus until he revived.
     %
     	Before he became a hermit, Zarathud was a young Priest, and
    -	took great delight in making fools of his opponents in front of
    -his followers.
    +took great delight in making fools of his opponents in front of his
    +followers.
     	One day Zarathud took his students to a pleasant pasture and
     there he confronted The Sacred Chao while She was contentedly grazing.
     	"Tell me, you dumb beast," demanded the Priest in his
    @@ -1626,7 +1628,7 @@ Chinese ideogram for NO-THING.)
     and finds himself no wiser than before," Bokonon tells us.  "He is full
     of murderous resentment of people who are ignorant without having come
     by their ignorance the hard way."
    -		-- Kurt Vonnegut, "Cat's Cradle"
    +		-- Kurt Vonnegut, Jr., "Cat's Cradle"
     %
     	Bubba, Jim Bob, and Leroy were fishing out on the lake last November,
     and, when Bubba tipped his head back to empty the Jim Beam, he fell out of the
    @@ -1694,7 +1696,7 @@ way I ought to go from here?"
     the Cat.
     	"I don't care much where--" said Alice.
     	"Then it doesn't matter which way you go," said the Cat.
    -		-- Lewis Carroll
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     	Concerning the war in Vietnam, Senator George Aiken of Vermont noted
     in January, 1966, "I'm not very keen for doves or hawks.  I think we need more
    @@ -1877,7 +1879,7 @@ how to be excellent: "In Search of Excellence", "Finding Excellence",
     So the Cleaning Personnel Don't Steal It", etc.
     		-- Dave Barry, "In Search of Excellence"
     %
    -	Exxon's 'Universe of Energy' tends to the peculiar rather than the
    +	Exxon's "Universe of Energy" tends to the peculiar rather than the
     humorous ... After [an incomprehensible film montage about wind and sun and
     rain and strip mines and] two or three minutes of mechanical confusion, the
     seats locomote through a short tunnel filled with clock-work dinosaurs.
    @@ -1923,9 +1925,9 @@ of events, there lurks a singular, sinister attitude of mind."
     	"MINE! HA-HA!"
     %
     	"Found it," the Mouse replied rather crossly:
    -"of course you know what 'it' means."
    +"of course you know what `it' means."
     
    -	"I know what 'it' means well enough, when I find a thing,"
    +	"I know what `it' means well enough, when I find a thing,"
     said the Duck: "it's generally a frog or a worm.
     
     The question is, what did the archbishop find?"
    @@ -1937,15 +1939,15 @@ such as a "pride of lions" or a "gaggle of geese."
     	One of the professors noticed a group of prostitutes down the block,
     and posed the question, "What name would be given to that group?"  The four
     fell into silence for a moment, as they pondered the possibilities...
    -	At last, one spoke: "How about 'a Jam of Tarts'?"  The others nodded
    +	At last, one spoke: "How about `a Jam of Tarts'?"  The others nodded
     in acknowledgment as they continued to consider the problem.  A second
    -professor spoke: "I'd suggest 'an Essay of Trollops.'"  Again, the others
    -nodded.  A third spoke: "I propose 'a Flourish of Strumpets.'"
    +professor spoke: "I'd suggest `an Essay of Trollops.'"  Again, the others
    +nodded.  A third spoke: "I propose `a Flourish of Strumpets.'"
     	They continued their walk in silence, until the first professor
     remarked to the remaining professor, who was the most senior and learned of
     the four, "You haven't suggested a name for our ladies.  What are your
     thoughts?"
    -	Replied the fourth professor, "'An Anthology of Prose.'"
    +	Replied the fourth professor, "`An Anthology of Prose.'"
     %
     	Fred noticed his roommate had a black eye upon returning from a dance.
     "What happened?"
    @@ -1958,12 +1960,11 @@ and sarcastic?"
     	"Of course not," said a sympathetic friend.
     	"Well," retorted Frank, "neither would Jennifer."
     %
    -	"Gee, Mudhead, everyone at More Science High has an
    +	"Gee, Mudhead, everyone at Morse Science High has an
     extracurricular activity except you."
     	"Well, gee, doesn't Louise count?"
     	"Only to ten, Mudhead."
    -
    -		-- Firesign Theater
    +		-- The Firesign Theatre
     %
     	"Gentlemen of the jury," said the defense attorney, now beginning
     to warm to his summation, "the real question here before you is, shall this
    @@ -2261,7 +2262,7 @@ each other up:
     	  the floor.)  S-word.  Excuse me.  Look, Bob, I'm going to
     	  have to get back to you.
          Bob: Fine.
    -		-- Dave Barry
    +		-- Dave Barry, "$#$%#^%!^%&@%@!"
     %
     	"I don't know what you mean by `glory,'" Alice said
     	Humpty Dumpty smiled contemptuously.  "Of course you don't --
    @@ -2276,7 +2277,9 @@ less."
     so many different things."
     	"The question is," said Humpty Dumpty, "which is to be master--
     that's all."
    -		-- Lewis Carroll, "Through the Looking Glass"
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     	I for one cannot protest the recent M.T.A. fare hike and the
     accompanying promises that this would in no way improve service.  For
    @@ -2328,7 +2331,7 @@ operation - namely, to remove those irritant bodies."
     	"And then he will be sane?"
     	"Then he will be perfectly sane, and a quite admirable citizen."
     	"Thank heaven for science!" said old Yacob.
    -		-- H.G. Wells, "The Country of the Blind"
    +		-- H. G. Wells, "The Country of the Blind"
     %
     	"I keep seeing spots in front of my eyes."
     	"Did you ever see a doctor?"
    @@ -2403,7 +2406,7 @@ more simply -- `Never imagine yourself not to be otherwise than what it
     might appear to others that what you were or might have been was not
     otherwise than what you had been would have appeared to them to be
     otherwise.'"
    -		-- Lewis Carroll, "Alice in Wonderland"
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     	I said, "Preacher, give me strength for round 5."
     	He said, "What you need is to grow up, son."
    @@ -2567,7 +2570,7 @@ man.  Mud-as-man alone could speak.
     	"Certainly," said man.
     	"Then I leave it to you to think of one for all of this," said God.
     	And He went away.
    -		-- Kurt Vonnegut, "Between Time and Timbuktu"
    +		-- Kurt Vonnegut, Jr., "Between Time and Timbuktu"
     %
     	In the beginning there was data.  The data was without form and
     null, and darkness was upon the face of the console; and the Spirit of
    @@ -2815,7 +2818,7 @@ guzzled in one gulp and then smashed on the bar.  He then stood aghast as
     the man stuffed the broken bottle in his mouth, munched broken glass and
     smacked his lips with relish.
     	"Can I, ah, uh, get you another, sir?" the drifter stammered.
    -	"Naw, I gotta git outa here, boy," the man grunted.  "Big Mike's
    +	"Naw, I gotta git outta here, boy," the man grunted.  "Big Mike's
     a-comin'."
     %
     	Love's Drug
    @@ -3002,7 +3005,7 @@ confirm who I am.
     		-- Captain Freedom
     %
     	Old Barlow was a crossing-tender at a junction where an express train
    -demolished an automobile and it's occupants. Being the chief witness, his
    +demolished an automobile and its occupants. Being the chief witness, his
     testimony was vitally important. Barlow explained that the night was dark,
     and he waved his lantern frantically, but the driver of the car paid
     no attention to the signal.
    @@ -3072,7 +3075,7 @@ and it was very juicy.  I stood up and took aim, and went into the windup,
     when my mother at the kitchen window called my name in a sharp voice.  I had
     to decide quickly.  I decided.
     	A rotten Big Boy hitting the target is a memorable sound, like a fat
    -man doing a belly-flop.  With a whoop and a yell the tomatoe came after
    +man doing a belly-flop.  With a whoop and a yell the tomatoee came after me
     faster than I knew she could run, and grabbed my shirt and was about to brain
     me when Mother called her name in a sharp voice.  And my sister, who was a
     good person, obeyed and let go -- and burst into tears.  I guess she knew that
    @@ -3164,7 +3167,7 @@ biggest, strongest fish he had ever caught.  He fought with it for hours,
     until, finally, he managed to bring it to the surface.  Looking of the edge
     of the boat, he saw the head of this huge fish breaking the surface.  Smiling
     with pride, he reached over the edge to pull the fish up.  Unfortunately, he
    -accidently caught his watch on the edge, and, before he knew it, there was a
    +accidentally caught his watch on the edge, and, before he knew it, there was a
     snap, and his watch tumbled into the water next to the fish with a loud
     "sploosh!"  Distracted by this shiny object, the fish made a sudden lunge,
     simultaneously snapping the line, and swallowing the watch.  Sadly, the
    @@ -3539,12 +3542,14 @@ know."
     "An uncomfortable sort of age.  Now if you'd asked MY advice, I'd have
     said 'Leave off at seven' -- but it's too late now."
     	"I never ask advice about growing,"  Alice said indignantly.
    -	"Too proud?"  the other enquired.
    +	"Too proud?" the other enquired.
     	Alice felt even more indignant at this suggestion.  "I mean,"
     she said, "that one can't help growing older."
     	"ONE can't, perhaps," said Humpty Dumpty; "but TWO can.  With
     proper assistance, you might have left off at seven."
    -		-- Lewis Carroll, "Through the Looking-Glass"
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     	Several students were asked to prove that all odd integers are prime.
     	The first student to try to do this was a math student.  "Hmmm...
    @@ -3732,7 +3737,7 @@ she'd been she said she'd spent the night with her sister Shirley."
     %
     	"That's right; the upper-case shift works fine on the screen, but
     they're not coming out on the damn printer...  Hold?  Sure, I'll hold."
    -		-- e.e. cummings last service call
    +		-- e. e. cummings last service call
     %
     	"The best thing for being sad," replied Merlin, beginning to puff
     and blow, "is to learn something.  That's the only thing that never fails.
    @@ -3907,7 +3912,7 @@ married!  You're a sadist, that's what!"
     	THE LESSER-KNOWN PROGRAMMING LANGUAGES #2: RENE
     
     Named after the famous French philosopher and mathematician Rene
    -DesCartes, RENE is a language used for artificial intelligence.  The
    +Descartes, RENE is a language used for artificial intelligence.  The
     language is being developed at the Chicago Center of Machine Politics
     and Programming under a grant from the Jane Byrne Victory Fund.  A
     spokesman described the language as "Just as great as dis [sic] city of
    @@ -4030,7 +4035,9 @@ called 'Ways and Means':  but that's only what it is called you know!"
     time completely bewildered.
     	"I was coming to that," the Knight said.  "The song really is
     "A-sitting on a Gate": and the tune's my own invention."
    -		--Lewis Carroll, "Through the Looking Glass"
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     	The only real game in the world, I think, is baseball...
     You've got to start way down, at the bottom, when you're six or seven years
    @@ -4065,7 +4072,8 @@ blocks of wood.  Opaque, like black pools in darkened caves.
     	"The pyramid is opening!"
     	"Which one?"
     	"The one with the ever-widening hole in it!"
    -		-- Firesign Theater, "How Can You Be In Two Places At
    +		-- The Firesign Theatre,
    +		   "How Can You Be In Two Places At
     		   Once When You're Not Anywhere At All"
     %
     	The salesman and the system analyst took off to spend a weekend in the
    @@ -4157,8 +4165,8 @@ make sure that they are Earthlings.  Then there's the police.  In Portland,
     when some guy goes bananas, the cops rope off a sixteen block area around
     him and call a shrink from the medical school who stands atop a patrol car
     with a megaphone and shouts, "OK!  THIS!  ALL!  STARTED!  WHEN!  YOU!  WERE!
    -THREE! YEARS!  OLD!  ON!  ACCOUNT! OF!  YOUR MOTHER!  RIGHT?  SO!  LET'S!
    -TALK! ABOUT!  IT!"  Down here they don't waste that kind of time.  The LAPD
    +THREE!  YEARS!  OLD!  ON!  ACCOUNT!  OF!  YOUR MOTHER!  RIGHT?  SO!  LET'S!
    +TALK!  ABOUT!  IT!"  Down here they don't waste that kind of time.  The LAPD
     has SWAT teams composed of guys who make Darth Vader look like Mr. Peepers.
     Before they go to bust a bookie joint they mortar it first.
     		-- M. Christensen, "A Portland Innocent in LA"
    @@ -4270,7 +4278,7 @@ you the Widow Miffin?" a small boy asked.
     	"Oh, no?" replied the little boy.  "Wait 'til you see what
     they're carrying upstairs!"
     %
    -	There was a mad scientist (a mad... social... scientist) who kidnaped
    +	There was a mad scientist (a mad... social... scientist) who kidnapped
     three colleagues, an engineer, a physicist, and a mathematician, and locked
     each of them in separate cells with plenty of canned food and water but no
     can opener.
    @@ -4282,13 +4290,13 @@ and escaped.
     off the tin cans by throwing them against the wall.  She was developing a good
     pitching arm and a new quantum theory.
     	The mathematician had stacked the unopened cans into a surprising
    -solution to the kissing problem; his dessicated corpse was propped calmly
    +solution to the kissing problem; his desiccated corpse was propped calmly
     against a wall, and this was inscribed on the floor:
     	Theorem: If I can't open these cans, I'll die.
     	Proof: assume the opposite...
     %
     	There was once a programmer who was attached to the court of the
    -warlord Wu.  The warlord asked the programmer: "Which is easier to design:
    +warlord of Wu.  The warlord asked the programmer: "Which is easier to design:
     an accounting package or an operating system?"
     	"An operating system," replied the programmer.
     	The warlord uttered an exclamation of disbelief.  "Surely an
    @@ -4328,7 +4336,7 @@ demands from him more than his utmost strength, that absorbs him, bone and
     sinew and brain and hope and fear and dreams -- and still calls for more.
     	They are fools that think otherwise.  No great effort was ever bought.
     No painting, no music, no poem, no cathedral in stone, no church, no state was
    -ever raised into being for payment of any kind.  No parthenon, no Thermopylae
    +ever raised into being for payment of any kind.  No Parthenon, no Thermopylae
     was ever built or fought for pay or glory; no Bukhara sacked, or China ground
     beneath Mongol heel, for loot or power alone.  The payment for doing these
     things was itself the doing of them.
    @@ -4393,14 +4401,14 @@ be as easily led to beauty as to ugliness, to truth as to public
     relations, to joy as to bitterness, be said to be suffering from Hunter
     Thompson's disease.  I don't have it this morning.  It comes and goes.
     This morning I don't have Hunter Thompson's disease.
    -		-- Kurt Vonnegut Jr. on Dr. Hunter S. Thompson: Excerpt
    +		-- Kurt Vonnegut, Jr. on Dr. Hunter S. Thompson: Excerpt
     		   from "A Political Disease", Vonnegut's review of "Fear
     		   and Loathing: On the Campaign Trail '72"
     %
    -	To A Quick Young Fox
    +	To A Quick Young Fox:
     Why jog exquisite bulk, fond crazy vamp,
     Daft buxom jonquil, zephyr's gawky vice?
    -Guy fed by work, quiz Jove's xanthic lamp--
    +Guy fed by work, quiz Jove's xanthic lamp --
     Zow! Qualms by deja vu gyp fox-kin thrice.
     		-- Lazy Dog
     %
    @@ -4565,7 +4573,7 @@ let him lie there all night."
     	"Don't worry about that.  They have a guard station in front of the
     White House that's open 24 hours a day.  The guards would recognize Colson...
     and by that time of course his wife would have called the cops and reported
    -that a bunch of thugs had kidnaped him."
    +that a bunch of thugs had kidnapped him."
     	"Wouldn't it be a little kinder if you drove about four more blocks
     and stopped at a phone box to ring the hospital and say, 'Would you mind going
     around to the front of the White House?  There's a naked man lying outside
    @@ -4574,7 +4582,7 @@ in the street, bleeding to death...'"
     	"It would be quite a story for the newspapers, wouldn't it?"
     	"Yeah, I think it's safe to say we'd see some headlines on that one."
     		-- Hunter S. Thompson, talking to R. Steadman on C. Colson,
    -		ex-Marine captain, now born again, of Watergate fame.
    +		   ex-Marine captain, now born again, of Watergate fame.
     %
     	"Well, it's garish, ugly, and derelicts have used it for a toilet.
     The rides are dilapidated to the point of being lethal, and could easily
    @@ -4593,7 +4601,7 @@ an End-user of Very Little Brain, and long words bother me."
     	"Well, that was a piece of cake, eh K-9?"
     	"Piece of cake, Master?  Radial slice of baked confection ...
     coefficient of relevance to Key of Time: zero."
    -		-- Dr. Who
    +		-- "Doctor Who"
     %
     	"We're running out of adjectives to describe our situation.  We
     had crisis, then we went into chaos, and now what do we call this?" said
    @@ -4691,7 +4699,7 @@ ever happened to me... the most dreadful thing."
     	"Well, it's a highly technical, sensitive instrument we use in
     computer repair.  Being a layman, you probably can't grasp exactly what
     it does.  We call it a two-by-four."
    -		-- Jeff MacNelley, "Shoe"
    +		-- Jeff MacNelly, "Shoe"
     %
     	"When I drink, *everybody* drinks!" a man shouted to the
     assembled bar patrons.  A loud general cheer went up.  After downing his
    @@ -4860,14 +4868,14 @@ There, that ought to patch it.  Dist it out, wouldja?"
     	"The famous scientific criminal, as famous among crooks as --"
     	"My blushes, Watson," Holmes murmured, in a deprecating voice.  "I
     was about to say 'as he is unknown to the public.'"
    -		-- A. Conan Doyle, "The Valley of Fear"
    +		-- Sir Arthur Conan Doyle, "The Valley of Fear"
     %
     	"You know, it's at times like this when I'm trapped in a Vogon
     airlock with a man from Betelgeuse and about to die of asphyxiation in
     deep space that I really wish I'd listened to what my mother told me
     when I was young!"
     	"Why, what did she tell you?"
    -	"I don't know, I didn't listen."
    +	"I don't know, I didn't listen!"
     		-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
     %
     	"You mean, if you allow the master to be uncivil, to treat you
    @@ -5076,7 +5084,7 @@ please communicate them by one of the following paths:
     
     	ARPA:  WastebasketSLMHQ.ARPA
     	UUCP:  [berkeley, seismo, harpo]!fubar!thekid!slmhq!wastebasket
    - 	Non-network sites:  Federal Express to:
    +	Non-network sites:  Federal Express to:
     		Wastebasket
     		Room NE43-926
     		Copernicus, The Moon, 12345-6789
    @@ -5223,7 +5231,7 @@ III. Any body passing through solid matter will leave a perforation
      8.  Babes in Boyland
      9.  Santa's Magic Lap
     10.  Hot Buttered Elves
    -		-- David Letterman's "Top Ten Christmas Movies in Times
    +		-- David Letterman, "Top Ten Christmas Movies in Times
     		   Square"
     %
     ... A booming voice says, "Wrong, cretin!", and you notice that you
    @@ -5337,7 +5345,7 @@ other's private parts.
     ... computer hardware progress is so fast.  No other technology since
     civilization began has seen six orders of magnitude in performance-price
     gain in 30 years.
    -		-- Fred Brooks
    +		-- Frederick Brooks, Jr.
     %
     ... [concerning quotation marks] even if we *_d_i_d* quote anybody in this
     business, it probably would be gibberish.
    @@ -5349,8 +5357,6 @@ attainable?  Millions of innocent men, women, and children, since the
     introduction of Christianity, have been burnt, tortured, fined, imprisoned;
     yet we have not advanced one inch towards uniformity.
     		-- Thomas Jefferson, "Notes on Virginia"
    -%
    - Eat drink and be merry, for tomorrow they may make it illegal.
     %
     <<<<< EVACUATION ROUTE <<<<<
     %
    @@ -5440,14 +5446,14 @@ legally ... impeccable!
     -- Individuals who make their abode in vitreous edifices would be well advised
     	to refrain from catapulting projectiles.
     -- Neophyte's serendipity.
    --- Exclusive dedication to necessitious chores without interludes of hedonistic
    +-- Exclusive dedication to necessitous chores without interludes of hedonistic
     	diversion renders John a hebetudinous fellow.
     -- A revolving concretion of earthy or mineral matter accumulates no congeries
     	of small, green bryophytic plant.
     -- Abstention from any aleatory undertaking precludes a potential escalation
     	of a lucrative nature.
     -- Missiles of ligneous or osteal consistency have the potential of fracturing
    -	osseous structure, but appelations will eternally remain innocuous.
    +	osseous structure, but appellations will eternally remain innocuous.
     %
     ** MAXIMUM TERMINALS ACTIVE.  TRY AGAIN LATER **
     %
    @@ -5492,7 +5498,7 @@ their C programs.
     		-- Robert Firth
     %
     ... Our second completely true news item was sent to me by Mr. H. Boyce
    -Connell Jr. of Atlanta, Ga., where he is involved in a law firm.  One
    +Connell, Jr. of Atlanta, Ga., where he is involved in a law firm.  One
     thing I like about the South is, folks there care about tradition.  If
     somebody gets handed a name like "H. Boyce," he hangs on to it, puts it
     on his legal stationery, even passes it to his son, rather than do what
    @@ -5519,7 +5525,7 @@ awareness of the great goals for Man and the society he conspired to erect.
     	galled saucepan does not reach 212 degrees Fahrenheit.
     %
     ... so long as the people do not care to exercise their freedom, those
    -who wish to tyrranize will do so; for tyrants are active and ardent,
    +who wish to tyrannize will do so; for tyrants are active and ardent,
     and will devote themselves in the name of any number of gods, religious
     and otherwise, to put shackles upon sleeping men.
     		-- Voltarine de Cleyre
    @@ -5596,13 +5602,13 @@ cleanersayingIllgetyoumyprettyandyourlittledogTototoo ...
     %
     ... this is an awesome sight.  The entire rebel resistance buried under six
     million hardbound copies of "The Naked Lunch."
    -		-- The Firesign Theater
    +		-- The Firesign Theatre
     %
     ... though his invention worked superbly -- his theory was a crock of sewage
     from beginning to end.
     		-- Vernor Vinge, "The Peace War"
     %
    - U	X
    + U       X
     e dUdX, e dX, cosine, secant, tangent, sine, 3.14159...
     %
     * UNIX is a Trademark of Bell Laboratories.
    @@ -5647,7 +5653,7 @@ into doubt.
     %
     ... when fits of creativity run strong, more than one programmer or writer
     has been known to abandon the desktop for the more spacious floor.
    -		-- Fred Brooks
    +		-- Frederick Brooks, Jr.
     %
     ... which reminds me of the Carrot family: Ma Carrot, Pa Carrot, and Baby
     Carrot.  One fine spring day they decided to go out for a picnic.  They all
    @@ -5708,20 +5714,20 @@ QED: A sheet of paper is a lazy dog.
     10. The city does not employ so called "Wallet Inspectors".
     		-- David Letterman, "Top Ten New York City Pedestrian Tips"
     %
    -[1] Alexander the Great was a great general.
    -[2] Great generals are forewarned.
    -[3] Forewarned is forearmed.
    -[4] Four is an even number.
    -[5] Four is certainly an odd number of arms for a man to have.
    -[6] The only number that is both even and odd is infinity.
    +(1) Alexander the Great was a great general.
    +(2) Great generals are forewarned.
    +(3) Forewarned is forearmed.
    +(4) Four is an even number.
    +(5) Four is certainly an odd number of arms for a man to have.
    +(6) The only number that is both even and odd is infinity.
     	Therefore, Alexander the Great had an infinite number of arms.
     %
    -[1] Alexander the Great was a great general.
    -[2] Great generals are forewarned.
    -[3] Forewarned is forearmed.
    -[4] Four is an even number.
    -[5] Four is certainly an odd number of arms for a man to have.
    -[6] The only number that is both even and odd is infinity.
    +(1) Alexander the Great was a great general.
    +(2) Great generals are forewarned.
    +(3) Forewarned is forearmed.
    +(4) Four is an even number.
    +(5) Four is certainly an odd number of arms for a man to have.
    +(6) The only number that is both even and odd is infinity.
     	Therefore, all horses are black.
     %
     1. Avoid fried meats which angry up the blood.
    @@ -5792,7 +5798,7 @@ you have to (always catch the buyer hungry and always make him wait).
      2. I, David Letterman, will never rent out my farm again.
      1. We are stardust.  We are golden.  We are going to look really stupid to
     	future generations.
    -		-- David Letterman, Top Ten Lessons of Woodstock
    +		-- David Letterman, "Top Ten Lessons of Woodstock"
     %
     10 Reasons Why a Beer is Better Than a Woman:
     
    @@ -5801,8 +5807,8 @@ you have to (always catch the buyer hungry and always make him wait).
      3. A beer doesn't think baseball is stupid simply because the guys spit.
      4. A beer doesn't give a [expletive deleted] if you keep a bunch of
     	other beers on the side.
    - 5. A beer will not call you a sexist pig if you say "doberman" instead of
    -	"doberperson".
    + 5. A beer will not call you a sexist pig if you say "Doberman" instead of
    +	"Doberperson."
      6. A beer won't get a job as a DJ and play 5 straight hours of lesbian
     	folk music on yer fave radio station.
      7. A beer understands why The Three Stooges are funny.
    @@ -5820,7 +5826,7 @@ FF buckets of bits on the bus
     FF buckets of bits on the bus
     FF buckets of bits
     Take one down, short it to ground
    -FE buckets of bits on the bus...
    +FE buckets of bits on the bus
     
     ad infinitum...
     %
    @@ -5932,13 +5938,13 @@ It isn't just a good idea, it's the law!
     	What 20th Century U.S. President was almost impeached and what
     office did he later hold?
     %
    -3 syncs represent the trinity - init, the child and the eternal zombie
    +3 syncs represent the trinity -- init, the child and the eternal zombie
     process.  In doing 3, you're paying homage to each and I think such
     traditions are important in this shallow, mercurial business we find
     ourselves in.
     		-- Jordan K. Hubbard
     %
    -$3,000,000.
    +$3,000,000
     %
     355/113 --
     	Not the famous irrational number PI, but an incredible simulation.
    @@ -6050,7 +6056,7 @@ A beautiful woman is a blessing from Heaven, but a good cigar is a smoke.
     		-- Kipling
     %
     A beautiful woman is a picture which drives all beholders nobly mad.
    -		-- Emerson
    +		-- Ralph Waldo Emerson
     %
     A beer delayed is a beer denied.
     %
    @@ -6067,7 +6073,7 @@ A billion hours ago man had not yet walked on earth.
     A billion dollars ago was late yesterday afternoon at the U.S. Treasury.
     %
     A biologist, a statistician, a mathematician and a computer scientist are on
    -a photo-safari in Africa.  As they're driving along the savanna in their
    +a photo-safari in Africa.  As they're driving along the savannah in their
     jeep, they stop and scout the horizon with their binoculars.
     
     The biologist: "Look!  A herd of zebras!  And there's a white zebra!
    @@ -6203,7 +6209,7 @@ invariably sat silent.  The monk had already asked about a bean, a lake,
     and a moonlit night.  One day he brought to Tortue a piece of string, and
     asked the same question.  In reply, the Grand Tortue grasped the loop
     between his feet and, with a few simple manipulations, created a complex
    -string which he proferred wordlessly to the monk.  At that moment, the monk
    +string which he proffered wordlessly to the monk.  At that moment, the monk
     was enlightened.
     
     From then on, the monk did not bother Tortue.  Instead, he made string after
    @@ -6261,9 +6267,10 @@ A city is a large community where people are lonesome together.
     %
     A clash of doctrine is not a disaster - it is an opportunity.
     %
    -A classic is something that everyone wants to have read
    +A classic is something that everybody wants to have read
     and nobody wants to read.
    -		-- Mark Twain, "The Disappearance of Literature"
    +		-- Mark Twain quoting Professor Winchester,
    +		   "The Disappearance of Literature"
     %
     A clever prophet makes sure of the event first.
     %
    @@ -6438,7 +6445,7 @@ damned things is ample.
     A couch is as good as a chair.
     %
     A countryman between two lawyers is like a fish between two cats.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     %
     A couple of young fellers were fishing at their special pond off the
     beaten track when out of the bushes jumped the Game Warden.  Immediately,
    @@ -6535,7 +6542,7 @@ A diplomatic husband said to his wife, "How do you expect me to remember
     your birthday when you never look any older?"
     %
     A diplomat's life consists of three things: protocol, Geritol, and alcohol.
    -		-- Adlai Stevenson
    +		-- Adlai E. Stevenson
     %
     A distraught patient phoned her doctor's office.  "Was it true," the woman
     inquired, "that the medication the doctor had prescribed was for the rest
    @@ -6544,7 +6551,7 @@ of her life?"
     the woman proceeded bravely on.  "Well, I'm wondering, then, how serious my
     condition is.  This prescription is marked `NO REFILLS'".
     %
    -A diva who specializes in risque arias is an off-coloratura soprano.
    +A diva who specializes in risqu'e arias is an off-coloratura soprano.
     %
     A doctor calls his patient to give him the results of his tests.  "I have
     some bad news," says the doctor, "and some worse news."  The bad news is
    @@ -6708,7 +6715,7 @@ dimension strictly exceeds the topological dimension.
     		-- Mandelbrot, "The Fractal Geometry of Nature"
     %
     A free society is one where it is safe to be unpopular.
    -		-- Adlai Stevenson
    +		-- Adlai E. Stevenson
     %
     A freelancer is one who gets paid by the word -- per piece or perhaps.
     		-- Robert Benchley
    @@ -6728,11 +6735,11 @@ lawyers more than he hates his wife.
     A friend with weed is a friend indeed.
     %
     A full belly makes a dull brain.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     
     		[and the local candy machine man.  Ed]
     %
    -A 'full' life in my experience is usually full only of other
    +A "full" life in my experience is usually full only of other
     people's demands.
     %
     A furore Normanorum libera nos, O Domine!
    @@ -6782,7 +6789,7 @@ A gift of a flower will soon be made to you.
     A girl and a boy bump into each other -- surely an accident.
     A girl and a boy bump and her handkerchief drops -- surely another accident.
     But when a girl gives a boy a dead squid -- *_t_h_a_t _h_a_d _t_o _m_e_a_n _s_o_m_e_t_h_i_n_g*.
    -		-- S. Morganstern, "The Silent Gondoliers"
    +		-- S. Morgenstern, "The Silent Gondoliers"
     %
     A girl with a future avoids the man with a past.
     		-- Evan Esar, "The Humor of Humor"
    @@ -6847,7 +6854,7 @@ then asks the backhoe operator for directions.
     A GOOD WAY TO THREATEN somebody is to light a stick of dynamite.  Then you
     call the guy and hold the burning fuse to the phone.  "Hear that?" you say.
     "That's dynamite, baby."
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     A gossip is one who talks to you about others, a bore is one who talks to
     you about himself; and a brilliant conversationalist is one who talks to
    @@ -6867,7 +6874,7 @@ to take it all away.
     A grammarian's life is always intense.
     %
     A great empire, like a great cake, is most easily diminished at the edges.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     %
     A great many people think they are thinking
     when they are merely rearranging their prejudices.
    @@ -6883,7 +6890,7 @@ indicating two directions at once.  Full, pursed lips protruded beneath the
     bushy black moustache and, at their corners, sank into little folds filled
     with disapproval and potato chip crumbs.  In the shadow under the green visor
     of the cap Ignatius J. Reilly's supercilious blue and yellow eyes looked down
    -upon the other people waiting under the clock at the D.H. Holmes department
    +upon the other people waiting under the clock at the D. H. Holmes department
     store, studying the crowd of people for signs of bad taste in dress.  Several
     of the outfits, Ignatius noticed, were new enough and expensive enough to be
     properly considered offenses against taste and decency.  Possession of
    @@ -6981,19 +6988,19 @@ Stormtroopers, who can't hit the broad side of a planet?
     		-- Tom Galloway
     %
     A is for Amy who fell down the stairs, B is for Basil assaulted by bears.
    -C is for Clair who wasted away, D is for Desmond thrown out of the sleigh.
    +C is for Clara who wasted away, D is for Desmond thrown out of the sleigh.
     E is for Ernest who choked on a peach, F is for Fanny, sucked dry by a leech.
     G is for George, smothered under a rug, H is for Hector, done in by a thug.
     I is for Ida who drowned in the lake, J is for James who took lye, by mistake.
     K is for Kate who was struck with an axe, L is for Leo who swallowed some tacks.
    -M is for Maud who was swept out to sea, N is for Nevil who died of ennui.
    +M is for Maud who was swept out to sea, N is for Neville who died of ennui.
     O is for Olive, run through with an awl, P is for Prue, trampled flat in a brawl
    -Q is for Quinton who sank in a mire, R is for Rhoda, consumed by a fire.
    -S is for Susan who parished of fits, T is for Titas who flew into bits.
    +Q is for Quentin who sank in a mire, R is for Rhoda, consumed by a fire.
    +S is for Susan who parished of fits, T is for Titus who flew into bits.
     U is for Una who slipped down a drain, V is for Victor, squashed under a train.
    -W is for Winie, embedded in ice, X is for Xercies, devoured by mice.
    -Y is for Yoric whose head was bashed in, Z is for Zilla who drank too much gin.
    -		-- Edward Gorey "The Gastly Crumb Tines"
    +W is for Winnie, embedded in ice, X is for Xerxes, devoured by mice.
    +Y is for Yorick whose head was bashed in, Z is for Zillah who drank too much gin.
    +		-- Edward Gorey, "The Gashlycrumb Tinies"
     %
     A is for Apple.
     		-- Hester Pryne
    @@ -7077,7 +7084,7 @@ The lady, indignant, removed her ear.
     %
     A language that doesn't affect the way you
     think about programming is not worth knowing.
    -		-- Alan Perlis
    +		-- Alan J. Perlis
     %
     A language that doesn't have everything is
     actually easier to program in than some that do.
    @@ -7138,7 +7145,7 @@ A lie in time saves nine.
     %
     A lie is an abomination unto the Lord and a very present help in time of
     trouble.
    -		-- Adlai Stevenson
    +		-- Adlai E. Stevenson
     %
     A life lived in fear is a life half lived.
     %
    @@ -7160,10 +7167,10 @@ And the clean ones so seldom are comical.
     %
     A LISP programmer knows the value of
     everything, but the cost of nothing.
    -		-- Alan Perlis
    +		-- Alan J. Perlis
     %
     A list is only as strong as its weakest link.
    -		-- Don Knuth
    +		-- Donald E. Knuth
     %
     A little experience often upsets a lot of theory.
     %
    @@ -7171,7 +7178,7 @@ A little inaccuracy saves a world of explanation.
     		-- C. E. Ayres
     %
     A little inaccuracy sometimes saves tons of explanation.
    -		-- H. H. Munro, "Saki"
    +		-- H. H. Munroe a.k.a. Saki, "The Square Egg" (1924)
     %
     A little kid went up to Santa and asked him, "Santa, you know when I'm bad
     right?"  And Santa says, "Yes, I do."  The little kid then asks, "And you
    @@ -7185,7 +7192,7 @@ those software systems that have excited passionate fans are those that are
     the products of one or a few designing minds, great designers.  Consider Unix,
     APL, Pascal, Modula, the Smalltalk interface, even Fortran; and contrast them
     with Cobol, PL/I, Algol, MVS/370, and MS-DOS.
    -		-- Fred Brooks
    +		-- Frederick Brooks, Jr.
     %
     A little word of doubtful number,
     A foe to rest and peaceful slumber.
    @@ -7208,7 +7215,7 @@ A lot of people are afraid of heights.  Not me.  I'm afraid of widths.
     		-- Steven Wright
     %
     A lot of people I know believe in positive thinking,
    -and so do I. I believe everything positively stinks.
    +and so do I.  I believe everything positively stinks.
     		-- Lew Col
     %
     A lover without indiscretion is no lover at all.
    @@ -7228,7 +7235,7 @@ a beautiful woman.  Somewhere, somebody's tired of her.
     %
     A man always remembers his first love with special
     tenderness, but after that begins to bunch them.
    -		-- Mencken
    +		-- H. L. Mencken
     %
     A man arrived home early to find his wife in the arms of his best friend,
     who swore how much they were in love.  To quiet the enraged husband, the
    @@ -7288,7 +7295,7 @@ staggers up to the door and confronts the head waiter.
     	"I'm sorry, sir, ties required."
     %
     A man is known by the company he organizes.
    -		-- A. Bierce
    +		-- Ambrose Bierce
     %
     A man is like a rusty wheel on a rusty cart,
     He sings his song as he rattles along and then he falls apart.
    @@ -7366,7 +7373,7 @@ Tell, me who is buried here?"
     	"My wife's first husband."
     %
     A man who cannot seduce men cannot save them either.
    -		-- Soren Kierkegaard
    +		-- S. A. Kierkegaard (1813-1855)
     %
     A man who carries a cat by its tail learns something he can learn
     in no other way.
    @@ -7444,7 +7451,7 @@ but to protect the writer.
     %
     A method of solution is perfect if we can foresee from the start,
     and even prove, that following that method we shall attain our aim.
    -		-- Leibnitz
    +		-- Gottfried Wilhelm Leibniz
     %
     A Mexican newspaper reports that bored Royal Air Force pilots stationed
     on the Falkland Islands have devised what they consider a marvelous new
    @@ -7454,28 +7461,24 @@ along it at the water's edge.  Perhaps ten thousand penguins turn their
     heads in unison watching the planes go by, and when the pilots turn
     around and fly back, the birds turn their heads in the opposite
     direction, like spectators at a slow-motion tennis match.  Then, the
    -paper reports "The pilots fly out to sea and directly to the penguin
    +paper reports, "The pilots fly out to sea and directly to the penguin
     colony and overfly it.  Heads go up, up, up, and ten thousand penguins
     fall over gently onto their backs.
    -		-- Audobon Society Magazine
    +		-- Audubon Society Magazine
     
    -2001-02-02, from http://news.bbc.co.uk:
    -
    -For five weeks, a team from the British Antarctic Survey (BAS)
    -monitored 1,000 king penguins on the island of South Georgia as
    -Lynx helicopters passed overhead.
    -
    -"Not one king penguin fell over when the helicopters came over,"
    -said team leader Dr Richard Stone.
    -
    -"As the aircraft approached, the birds went quiet and stopped
    +[From the BBC, 2001-02-02:
    +	For five weeks, a team from the British Antarctic Survey (BAS)
    +monitored 1,000 king penguins on the island of South Georgia as Lynx
    +helicopters passed overhead.
    +	"Not one king penguin fell over when the helicopters came over,"
    +said team leader Dr. Richard Stone.
    +	"As the aircraft approached, the birds went quiet and stopped
     calling to each other, and adolescent birds that were not associated
     with nests began walking away from the noise. Pure animal instinct,
     really."
    -
    -The conclusion, said Dr Stone, is that flights over 305 metres
    -(1,000 feet) caused "only minor and transitory ecological effects"
    -on king penguins.
    +	The conclusion, said Dr. Stone, is that flights over 305 metres
    +(1,000 feet) caused "only minor and transitory ecological effects" on
    +king penguins.]
     %
     A mighty creature is the germ,
     Though smaller than the pachyderm.
    @@ -7613,7 +7616,7 @@ A nickel ain't worth a dime anymore.
     %
     A "No" uttered from deepest conviction is better and greater than a
     "Yes" merely uttered to please, or what is worse, to avoid trouble.
    -		-- Mahatma Ghandi
    +		-- Mahatma Gandhi
     %
     A novice of the temple once approached the Chief Priest with a question.
     
    @@ -7684,12 +7687,12 @@ A person who has something looks at all there is and wants all the rest.
     %
     A person who is more than casually interested in computers should be well
     schooled in machine language, since it is a fundamental part of a computer.
    -		-- Donald Knuth
    +		-- Donald E. Knuth
     %
     A pessimist is a man who has been compelled to live with an optimist.
     		-- Elbert Hubbard
     %
    -A physicist is an atoms way of knowing about atoms.
    +A physicist is an atom's way of knowing about atoms.
     		-- George Wald
     %
     A pickup with three guys in it pulls into the lumber yard.  One of the men
    @@ -7756,7 +7759,7 @@ paycheck?"
     %
     A political man can have as his aim the realization of freedom,
     but he has no means to realize it other than through violence.
    -		-- Jean Paul Sartre
    +		-- Jean-Paul Sartre
     %
     A possum must be himself, and being himself he is honest.
     		-- Walt Kelly
    @@ -7764,7 +7767,7 @@ A possum must be himself, and being himself he is honest.
     A pound of salt will not sweeten a single cup of tea.
     %
     A power so great, it can only be used for Good or Evil!
    -		-- Firesign Theatre, "The Giant Rat of Summatra"
    +		-- The Firesign Theatre, "The Giant Rat of Sumatra"
     %
     A "practical joker" deserves applause for his wit according to its quality.
     Bastinado is about right.  For exceptional wit one might grant keelhauling.
    @@ -7777,7 +7780,7 @@ A prediction is worth twenty explanations.
     A pretty foot is one of the greatest gifts of nature... please send me your
     last pair of shoes, already worn out in dancing... so I can have something
     of yours to press against my heart.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     A pretty woman can do anything; an ugly woman must do everything.
     %
    @@ -7831,7 +7834,7 @@ when its programs require attention to the irrelevant.
     %
     A prohibitionist is the sort of man one wouldn't care to
     drink with -- even if he drank.
    -		-- Mencken
    +		-- H. L. Mencken
     %
     A prominent broadcaster, on a big-game safari in Africa, was taken to a
     watering hole where the life of the jungle could be observed. As he
    @@ -8019,7 +8022,7 @@ die and a new generation grows up that is familiar with it.
     %
     A sect or party is an elegant incognito devised to save a man from
     the vexation of thinking.
    -		-- Ralph Waldo Emerson, Journals, 1831
    +		-- Ralph Waldo Emerson, "Journals" (1831)
     %
     A sense of desolation and uncertainty, of futility, of the baselessness
     of aspirations, of the vanity of endeavor, and a thirst for a life giving
    @@ -8197,7 +8200,7 @@ Lord of the Rings LITE(tm)
     	Some guys take a long vacation to throw a ring into a volcano.
     
     Hamlet LITE(tm)
    -	-- by Wm. Shakespeare
    +	-- by William Shakespeare
     
     	A college student on vacation with family problems, a screwy
     	girl-friend and a mother who won't act her age.
    @@ -8210,7 +8213,7 @@ A Tale of Two Cities LITE(tm)
     	lady who knits.
     
     Crime and Punishment LITE(tm)
    -	-- by Fyodor Dostoevski
    +	-- by Fyodor Dostoyevsky
     
     	A man sends a nasty letter to a pawnbroker, but later
     	feels guilty and apologizes.
    @@ -8235,7 +8238,7 @@ of the Alamo, commented, "I'll bet you never had anyone that brave around
     help?"
     %
     A thing is not necessarily true because a man dies for it.
    -		-- Oscar Wilde, "The Portrait of Mr. W.H."
    +		-- Oscar Wilde, "The Portrait of Mr. W. H."
     %
     A timely marriage: one made before your children start nagging you about it.
     		-- Diane Duane
    @@ -8273,7 +8276,7 @@ drudge for his living at seventy, sooner than work at anything but his art.
     		-- Shaw
     %
     A truly great man will neither trample on a worm nor sneak to an emperor.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     %
     A truly wise man never plays leapfrog with a unicorn.
     %
    @@ -8394,7 +8397,7 @@ she follows.
     %
     A woman may very well form a friendship with a man, but for this to endure,
     it must be assisted by a little physical antipathy.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     A woman must be a cute, cuddly, naive little thing -- tender, sweet,
     and stupid.
    @@ -8505,8 +8508,6 @@ A: "A symphony is a very complex musical form, perhaps you should begin with
     Q: "But Herr Mozart, you were writing symphonies when you were 8 years old."
     A: "But I never asked anybody how."
     %
    -A.A.A.A.A.: An organization for drunks who drive.
    -%
     AAAAAAAAAAAaaaaaaaaaaaaaaaccccccccckkkkkk!!!!!!!!!
     You brute!  Knock before entering a ladies room!
     %
    @@ -8561,7 +8562,7 @@ Above all things, reverence yourself.
     %
     Abraham Lincoln didn't die in vain.  He died in Washington, D.C.
     %
    -Abscond, v:
    +Abscond, v.:
     	To be unexpectedly called away to the bedside of a dying relative
     	and miss the return train.
     %
    @@ -8646,7 +8647,7 @@ religion; rejection without proof is the fundamental characteristic of
     Western science.
     		-- Gary Zukav, "The Dancing Wu Li Masters"
     %
    -Accident:
    +Accident, n.:
     	A condition in which presence of mind is good,
     	but absence of body is better.
     		-- Foolish Dictionary
    @@ -8712,7 +8713,7 @@ Accordion, n.:
     	A bagpipe with pleats.
     %
     Accuracy, n.:
    -	The vice of being right
    +	The vice of being right.
     %
     Acid -- better living through chemistry.
     %
    @@ -8739,7 +8740,7 @@ Edward G. Robinson	Emmanual Goldenburg
     Gene Wilder		Gerald Silberman
     John Wayne		Marion Morrison
     Kirk Douglas		Issur Danielovitch
    -Richard Burton		Richard Jenkins Jr.
    +Richard Burton		Richard Jenkins, Jr.
     Roy Rogers		Leonard Slye
     Woody Allen		Allen Stewart Konigsberg
     %
    @@ -8790,16 +8791,16 @@ Adding features does not necessarily increase
     functionality -- it just makes the manuals thicker.
     %
     Adding manpower to a late software project makes it later.
    -		-- F. Brooks, "The Mythical Man-Month"
    +		-- Frederick Brooks, Jr., "The Mythical Man-Month"
     
     Whenever one person is found adequate to the discharge of a duty by
     close application thereto, it is worse execute by two persons and
     scarcely done at all if three or more are employed therein.
    -		-- George Washington, 1732-1799
    +		-- George Washington (1732-1799)
     %
     Adding sound to movies would be like
     putting lipstick on the Venus de Milo.
    -		-- actress Mary Pickford, 1925
    +		-- Mary Pickford, actress, 1925
     %
     Adhere to your own act, and congratulate yourself if you have done
     something strange and extravagant, and broken the monotony of a
    @@ -8821,7 +8822,7 @@ Adopted kids are such a pain -- you have to teach them how to look
     like you ...
     		-- Gilda Radner
     %
    -Adore, v:
    +Adore, v.:
     	To venerate expectantly.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    @@ -8862,7 +8863,7 @@ African violet:		Such worth is rare
     Apple blossom:		Preference
     Bachelor's button:	Celibacy
     Bay leaf:		I change but in death
    -Camelia:		Reflected loveliness
    +Camellia:		Reflected loveliness
     Chrysanthemum, red:	I love
     Chrysanthemum, white:	Truth
     Chrysanthemum, other:	Slighted love
    @@ -9066,7 +9067,7 @@ In works of labour or of skill		In books, or work, or healthful play,
     I would be busy too;			Let my first years be passed,
     For Satan finds some mischief still	That I may give for every day
     For idle hands to do.			Some good account at last.
    -		-- Isaac Watts, 1674-1748
    +		-- Isaac Watts (1674-1748)
     %
     Against stupidity the very gods Themselves contend in vain.
     		-- Friedrich von Schiller, "The Maid of Orleans", III, 6
    @@ -9193,7 +9194,7 @@ ALBRECHT'S LAW:
     %
     Alcohol, hashish, prussic acid, strychnine are weak dilutions.
     The surest poison is time.
    -		-- Emerson, "Society and Solitude"
    +		-- Ralph Waldo Emerson, "Society and Solitude"
     %
     Alcohol is the anesthesia by which we endure the operation of life.
     		-- George Bernard Shaw
    @@ -9206,7 +9207,7 @@ Alden's Laws:
     %
     Aleph-null bottles of beer on the wall,
     Aleph-null bottles of beer,
    -You take one down, and pass it around,
    +	You take one down, and pass it around,
     Aleph-null bottles of beer on the wall.
     %
     Alex Haley was adopted!
    @@ -9263,7 +9264,7 @@ than others.
     		-- Alan Truscott
     %
     All business is based on the mutual trust of one of the parts.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     All constants are variables.
     %
    @@ -9276,7 +9277,7 @@ All Finagle Laws may be bypassed by learning the simple art of doing
     without thinking.
     %
     All flesh is grass.
    -		-- Isaiah
    +		-- Isaiah 40:6
     Smoke a friend today.
     %
     All generalizations are false, including this one.
    @@ -9287,7 +9288,7 @@ barely presentable.
     		-- Fran Lebowitz, "Metropolitan Life"
     %
     All Gods were immortal.
    -		-- Stanislaw J. Lem, "Unkempt Thoughts"
    +		-- Stanislaw J. Lec, "Unkempt Thoughts"
     %
     All great discoveries are made by mistake.
     		-- Young
    @@ -9352,13 +9353,13 @@ that said there were eleven countries, in the world this is I think,
     that have queens as sovereign rulers.  That's probably my best shot.
     %
     All kings is mostly rapscallions.
    -		--Mark Twain
    +		-- Mark Twain
     %
     All laws are simulations of reality.
     		-- John C. Lilly
     %
     All life evolves by the differential survival of replicating entities.
    -		-- Dawkins
    +		-- Richard Dawkins
     %
     All men are mortal.  Socrates was mortal.  Therefore, all men are
     Socrates.
    @@ -9368,7 +9369,7 @@ All men have the right to wait in line.
     %
     All men know the utility of useful things;
     but they do not know the utility of futility.
    -		-- Chuang-tzu
    +		-- Chuang Tzu
     %
     All men profess honesty as long as they can.
     To believe all men honest would be folly.
    @@ -9411,7 +9412,7 @@ of the money in the vault, or I'm marking down everything in the store."
     		-- Steven Wright
     %
     All of the true things I am about to tell you are shameless lies.
    -		-- The Book of Bokonon / Kurt Vonnegut Jr.
    +		-- Kurt Vonnegut, Jr., "The Book of Bokonon"
     %
     All of us should treasure his Oriental wisdom and his preaching of a
     Zen-like detachment, as exemplified by his constant reminder to clerks,
    @@ -9447,7 +9448,7 @@ goal.  Perhaps it is merely that computers are young, programmers are younger,
     and the young are always optimists.  But however the selection process works,
     the result is indisputable:  "This time it will surely run," or "I just found
     the last bug."
    -		-- Frederick Brooks, "The Mythical Man Month"
    +		-- Frederick Brooks, Jr., "The Mythical Man-Month"
     %
     All programmers are playwrights and all computers are lousy actors.
     %
    @@ -9558,7 +9559,7 @@ All things are possible, except for skiing through a revolving door.
     All things being equal, you are bound to lose.
     %
     All things that are, are with more spirit chased than enjoyed.
    -		-- Shakespeare, "Merchant of Venice"
    +		-- William Shakespeare, "Merchant of Venice"
     %
     All this wheeling and dealing around, why, it isn't for money,
     it's for fun.  Money's just the way we keep score.
    @@ -9664,9 +9665,9 @@ apprehending of poachers, ways to control vermin, and other chores and duties
     of the professional gamekeeper.  Unfortunately, one is obliged to wade
     through many pages of extraneous material in order to discover and savour
     those sidelights on the management of a midland shooting estate, and in this
    -reviewer's opinion the book cannot take the place of J.R. Miller's "Practical
    +reviewer's opinion the book cannot take the place of J. R. Miller's "Practical
     Gamekeeping."
    -		-- Ed Zern, "Field and Stream", Nov., 1959
    +		-- Ed Zern, "Field and Stream" (Nov. 1959)
     %
     Always borrow money from a pessimist; he doesn't expect to be paid back.
     %
    @@ -9733,13 +9734,13 @@ and the scum rises to the top.
     		-- Utah Phillips
     %
     America is a stronger nation for the ACLU's uncompromising effort.
    -		 -- President John F. Kennedy
    +		-- President John F. Kennedy
     
     The simple rights, the civil liberties from generations of struggle must not
     be just fine words for patriotic holidays, words we subvert on weekdays, but
     living, honored rules of conduct amongst us...I'm glad the American Civil
     Liberties Union gets indignant, and I hope this will always be so.
    -		 -- Senator Adlai E. Stevenson
    +		-- Adlai E. Stevenson
     
     The ACLU has stood foursquare against the recurring tides of hysteria that
     from time to time threaten freedoms everywhere... Indeed, it is difficult
    @@ -9803,7 +9804,7 @@ AMOEBIT:
     	and divide at the same time.
     %
     Among all savage beasts, none is found so harmful as woman.
    -		-- St. John Chrysostom, 304-407
    +		-- St. John Chrysostom (304-407)
     %
     Among the lucky, you are the chosen one.
     %
    @@ -9814,7 +9815,7 @@ An actor's a guy who if you ain't talkin' about him, ain't listening.
     		-- Marlon Brando
     %
     An Ada exception is when a routine gets
    -in trouble and says 'Beam me up, Scotty'.
    +in trouble and says "Beam me up, Scotty."
     %
     An adequate bootstrap is a contradiction in terms.
     %
    @@ -9831,11 +9832,11 @@ An alcoholic is someone you don't like who drinks as much as you do.
     		-- Dylan Thomas
     %
     An algorithm must be seen to be believed.
    -		-- D. E. Knuth
    +		-- Donald E. Knuth
     %
     An ambassador is an honest man sent abroad
     to lie and intrigue for the benefit of his country.
    -		-- Sir Henry Wotton, 1568-1639
    +		-- Sir Henry Wotton (1568-1639)
     %
     An amendment to a motion may be amended, but an amendment to an amendment
     to a motion may not be amended.  However, a substitute for an amendment to
    @@ -9932,7 +9933,7 @@ An economist is a man who would marry
     Farrah Fawcett-Majors for her money.
     %
     An editor is one who separates the wheat from the chaff and prints the chaff.
    -		-- Adlai Stevenson
    +		-- Adlai E. Stevenson
     %
     An effective way to deal with predators is to taste terrible.
     %
    @@ -10266,7 +10267,7 @@ The venerable XGP,			Has made the Ten dumb,
     But his slow artistic hand,		Without you, Dover,
     Lacks your clean velocity.		We're system untounged-
     
    -Theses and papers 			DRAW Plots and TEXage
    +Theses and papers			DRAW Plots and TEXage
     And code in a queue			Have been biding their time,
     Dover, oh Dover,			With LISP code and programs,
     We've been waiting for you.		And this crufty rhyme.
    @@ -10444,7 +10445,7 @@ cracking secret NATO codes and editing propaganda for your own people all
     at the same time with the other! (Well, you really can't, but the Americans
     think you can, and that's the point, right?)
     %
    -Anoint, v:
    +Anoint, v.:
     	To grease a king or other great functionary already sufficiently
     	slippery.
     		-- Ambrose Bierce, "The Devil's Dictionary"
    @@ -10456,7 +10457,7 @@ Another day, another dollar.
     %
     Another flaw in the human character is that everybody wants to build
     and nobody wants to do maintenance.
    -		-- Kurt Vonnegut, "Hocus Pocus"
    +		-- Kurt Vonnegut, Jr., "Hocus Pocus"
     %
     Another good night not to sleep in a eucalyptus tree.
     %
    @@ -10472,7 +10473,7 @@ Another such victory over the Romans, and we are undone.
     		-- Pyrrhus
     %
     Answer a fool according to his folly, lest he be wise in his own conceit.
    -		-- Proverbs, 26:5
    +		-- Proverbs 26:5
     %
     Anthony's Law of Force:
     	Don't force it; get a larger hammer.
    @@ -10578,7 +10579,7 @@ requires a heroism which is transcendent.
     		-- Henry Ward Beecher
     %
     Any man who hates dogs and babies can't be all bad.
    -		-- Leo Rosten, on W.C. Fields
    +		-- Leo Rosten, on W. C. Fields
     %
     Any member introducing a dog into the Society's premises shall be
     liable to a fine of one pound.  Any animal leading a blind person shall
    @@ -10674,7 +10675,6 @@ Anyone stupid enough to be caught by the police is probably guilty.
     %
     Anyone taking offence at fortune(s) is desperately lacking beer, in my
     extremely humble opinion.
    -
     		-- Philip Paeps
     %
     Anyone who cannot cope with mathematics is not fully human.  At best he
    @@ -10683,7 +10683,7 @@ make messes in the house.
     		-- Lazarus Long, "Time Enough for Love"
     %
     Anyone who considers protocol unimportant has never dealt with a cat.
    -		-- R. Heinlein
    +		-- Robert A. Heinlein
     %
     Anyone who describes Islam as a religion as intolerant encourages violence.
     		-- Tasnim Aslam, Spokesman for Pakistani Foreign Ministry
    @@ -10767,9 +10767,9 @@ APHASIA:
     	Loss of speech in social scientists when asked
     	at parties, "But of what use is your research?"
     %
    -aphorism, n.:
    +Aphorism, n.:
     	A concise, clever statement.
    -afterism, n.:
    +Afterism, n.:
     	A concise, clever statement you don't think of until too late.
     		-- James Alexander Thom
     %
    @@ -10782,7 +10782,7 @@ of coding bums.
     %
     APL is a natural extension of assembler language programming;
     ...and is best for educational purposes.
    -		-- A. Perlis
    +		-- Alan J. Perlis
     %
     APL is a write-only language.  I can write programs
     in APL, but I can't read any of them.
    @@ -10804,7 +10804,7 @@ April is the cruelest month...
     Aquadextrous, adj.:
     	Possessing the ability to turn the bathtub
     	faucet on and off with your toes.
    -		-- Rich Hall, "Sniglets"
    +		-- Rich Hall & Friends, "Sniglets"
     %
     AQUARIUS (Jan 20 - Feb 18)
     	You have an inventive mind and are inclined to be progressive.
    @@ -10971,7 +10971,7 @@ ARITHMETIC:
     Arithmetic is being able to count up to twenty without taking off your shoes.
     		-- Mickey Mouse
     %
    -ARMADILLO:
    +Armadillo, v.:
     	To provide weapons to a Spanish pickle.
     %
     Armenians and Azerbaijanis in Stepanakert, capital of the Nagorno-Karabakh
    @@ -10987,9 +10987,9 @@ Armstrong's Collection Law:
     	it is surely made out to someone else.
     %
     Arnold's Laws of Documentation:
    -	1.) If it should exist, it doesn't.
    -	2.) If it does exist, it's out of date.
    -	3.) Only documentation for useless programs transcends the
    +	(1) If it should exist, it doesn't.
    +	(2) If it does exist, it's out of date.
    +	(3) Only documentation for useless programs transcends the
     	    first two laws.
     %
     Around computers it is difficult to find the correct unit of time to
    @@ -11031,14 +11031,14 @@ Art is Nature speeded up and God slowed down.
     		-- Chazal
     %
     "Art" is the ability to separate the significant from the insignificant.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     Art is the tree of life.  Science is the tree of death.
     %
     Arthur's Laws of Love:
    -	1.  People to whom you are attracted invariably think you
    +	(1) People to whom you are attracted invariably think you
     	    remind them of someone else.
    -	2.  The love letter you finally got the courage to send will
    +	(2) The love letter you finally got the courage to send will
     	    be delayed in the mail long enough for you to make a fool
     	    of yourself in person.
     %
    @@ -11106,7 +11106,7 @@ As far as we know, our computer has never had an undetected error.
     		-- Weisert
     %
     As flies to wanton boys are we to the gods; they kill us for their sport.
    -		-- Shakespeare, "King Lear"
    +		-- William Shakespeare, "King Lear"
     %
     As for the women, though we scorn and flout 'em,
     We may live with, but cannot live without 'em.
    @@ -11198,7 +11198,7 @@ industries are secure.  We hear about constitutional rights, free speech
     and the free press.  Every time I hear these words I say to myself, "That
     man is a Red, that man is a Communist".  You never hear a real American
     talk like that.
    -		-- Frank Hague, 1896-1956
    +		-- Frank Hague (1896-1956)
     %
     As long as the answer is right, who cares if the question is wrong?
     %
    @@ -11331,7 +11331,7 @@ or putatively less buggy.  The replacement of a working component by a new
     version requires the same systematic testing procedure that adding a new
     component does, although it should require less time, for more complete and
     efficient test cases will usually be available.
    -		-- Frederick Brooks Jr., "The Mythical Man Month"
    +		-- Frederick Brooks, Jr., "The Mythical Man-Month"
     %
     As the trials of life continue to take their toll, remember that there
     is always a future in Computer Maintenance.
    @@ -11395,7 +11395,7 @@ Do not give up to the great distance:
     It's by going that you will reach your aim.
     Be not discouraged by human frailty:
     You will overcome it if you try to.
    -		-- Chinggis (Genghis) Khan 
    +		-- Chinggis (Genghis) Khan
     %
     ASCII:
     	The control code for all beginning programmers and those who would
    @@ -11421,7 +11421,7 @@ will pay only the station-to-station rate.
     %
     Ask not for whom the  tolls.
     %
    -Ask not for whom the telephone bell tolls...
    +Ask not for whom the telephone bell tolls ...
     if thou art in the bathtub, it tolls for thee.
     %
     Ask not what's inside your head, but what your head's inside of.
    @@ -11611,8 +11611,7 @@ Atlee is a very modest man.  And with reason.
     %
     Attempting to stop MySQL by buying companies around it is like trying
     to kill a dolphin by drinking the ocean.
    -
    -		-- Mårten Mickos
    +		-- Marten Mickos
     %
     Attorney General Edwin Meese III explained why the Supreme Court's Miranda
     decision (holding that subjects have a right to remain silent and have a
    @@ -11621,13 +11620,13 @@ suspects who are innocent of a crime.  That's contradictory.  If a person
     is innocent of a crime, then he is not a suspect."
     		-- U.S. News and World Report, 10/14/85
     %
    -AUCTION:
    +Auction, n.:
     	A gyp off the old block.
     %
     Audacity, and again, audacity, and always audacity.
     		-- G. J. Danton
     %
    -audiophile, n:
    +Audiophile, n.:
     	Someone who listens to the equipment instead of the music.
     %
     Auribus teneo lupum.
    @@ -11815,7 +11814,7 @@ BASIC is the Computer Science equivalent of "Scientific Creationism."
     BASIC is to computer programming as QWERTY is to typing.
     		-- Seymour Papert
     %
    -Basic, n.:
    +BASIC, n.:
     	A programming language.  Related to certain social diseases in
     	that those who have it will not admit it in polite company.
     %
    @@ -11923,10 +11922,12 @@ Be valiant, but not too venturous.
     Let thy attire be comely, but not costly.
     		-- John Lyly
     %
    -beachhead:
    -In marketing: a small piece of a market over which you gain control and
    -from which you go out to control other pieces of the market.
    -In war: where soldiers die.
    +Beachhead, n.:
    +	In marketing: A small piece of a market over which you gain
    +	control and from which you go out to control other pieces of
    +	the market.
    +
    +	In war: Where soldiers die.
     %
     Beam me up, Scotty!
     %
    @@ -12072,9 +12073,9 @@ seven or eight periods now and it's beginning to worry me."
     Being conservative has never been regarded as old-fashioned.  But
     if you fight for a sensible step in the right direction which others
     has deserted you will be branded "reactionary".
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
    -"Being disintegrated makes me ve-ry an-gry!"  
    +"Being disintegrated makes me ve-ry an-gry!" 
     %
     Being frustrated is disagreeable, but the real
     disasters in life begin when you get what you want.
    @@ -12098,14 +12099,14 @@ standing next to a lamp post infested with pigeons.
     %
     Being ugly isn't illegal.  Yet.
     %
    -belief, n:
    +Belief, n.:
     	Something you do not believe.
     %
     Believe everything you hear about the world; nothing is too
     impossibly bad.
    -		-- Honore DeBalzac
    +		-- Honore de Balzac
     %
    -Bell Labs Unix - Reach out and grep someone.
    +Bell Labs Unix -- Reach out and grep someone.
     %
     Ben, why didn't you tell me?
     		-- Luke Skywalker
    @@ -12134,7 +12135,7 @@ none of his friends like him either.
     %
     Bernard was a young eighty-three, not a gomer, and able to talk.  He'd been
     transferred from MBH (Man's Best Hospital), the House's Rival.  Founded in
    -Colonial times by the WASPs, the insemination fo MBH by non-WASPs had taken
    +Colonial times by the WASPs, the insemination of MBH by non-WASPs had taken
     place only mid-twentieth century with the token multidextrous Oriental
     surgeon, and finally, with the token red-hot internal-medicine Jew.  Yet,
     MBH was still Brooks Brothers, while the House was still the Garment District.
    @@ -12205,7 +12206,7 @@ clearly visible on one of the leading characters.
     Best of all is never to have been born.
     Second best is to die soon.
     %
    -beta test, v:
    +Beta test, v.:
     	To voluntarily entrust one's data, one's livelihood and one's
     	sanity to hardware or software intended to destroy all three.
     	In earlier days, virgins were often selected to beta test volcanos.
    @@ -12236,7 +12237,7 @@ ncheck list
     ncheck list
     cat list | grep naughty >nogiftlist
     cat list | grep nice >giftlist
    -santa claus  town
    +santa claus town
     
     who | grep sleeping
     who | grep awake
    @@ -12303,7 +12304,7 @@ Beware of Bigfoot!
     %
     Beware of bugs in the above code; I have only proved it correct, not
     tried it.
    -		-- Donald Knuth
    +		-- Donald E. Knuth
     %
     Beware of computerized fortune-tellers!
     %
    @@ -12337,7 +12338,7 @@ Beware the new TTY code!
     %
     Beware the one behind you.
     %
    -bi, n:
    +Bi, n.:
     	When *everybody* thinks you're a pervert.
     %
     Bierman's Laws of Contracts:
    @@ -12406,7 +12407,7 @@ time, so it is now realized that numbers are not absolute, but depend
     on the observer's movement in restaurants.
     		-- Douglas Adams, "Life, The Universe and Everything"
     %
    -bit, n:
    +Bit, n.:
     	A unit of measure applied to color.  Twenty-four-bit color
     	refers to expensive $3 color as opposed to the cheaper 25
     	cent, or two-bit, color that use to be available a few years
    @@ -12462,7 +12463,7 @@ Blame Saint Andreas -- it's all his fault.
     %
     Blessed are the forgetful:  for they
     get the better even of their blunders.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     Blessed are the meek for they shall inhibit the earth.
     %
    @@ -12493,9 +12494,9 @@ abstains from giving wordy evidence of the fact.
     Blinding speed can compensate for a lot of deficiencies.
     		-- David Nichols
     %
    -BLISS is ignorance
    +BLISS is ignorance.
     %
    -Blithwapping, v:
    +Blithwapping, v.:
     	Using anything BUT a hammer to hammer a nail into the
     	wall, such as shoes, lamp bases, doorstops, etc.
     		-- Rich Hall & Friends, "Sniglets"
    @@ -12561,13 +12562,13 @@ Boren's Laws:
     	(2) When in trouble, delegate.
     	(3) When in doubt, mumble.
     %
    -Boss, n:
    +Boss, n.:
     	According to the Oxford English Dictionary, in the Middle Ages the
     	words "boss" and "botch" were largely synonymous, except that boss,
     	in addition to meaning "a supervisor of workers" also meant "an
     	ornamental stud."
     %
    -Boston:
    +Boston, n.:
     	An outdoor Betty Ford Clinic.
     %
     Boston, n.:
    @@ -12610,10 +12611,10 @@ And get the maximum pleasure from a minimum of love.
     Boy, I sure wish that I could be in the
     'Advanced Systems Development' group!
     %
    -Boy, life takes a long time to live
    +Boy, life takes a long time to live.
     		-- Steven Wright
     %
    -boy, n:
    +Boy, n.:
     	A noise with dirt on it.
     %
     Boy, that crayon sure did hurt!
    @@ -12637,7 +12638,7 @@ Everybody tends to drift toward Bozoness.  It has Oz in it.  They mean
     well.  They're straight-looking except they've got inflatable shoes.  They
     like their comforts.  The Bozos have learned to enjoy their free time,
     which is all the time.
    -		-- Firesign Theatre, "If Bees Lived Inside Your Head"
    +		-- The Firesign Theatre, "If Bees Lived Inside Your Head"
     %
     Brace yourselves.  We're about to try something that borders on the
     unique: an actually rather serious technical book which is not only
    @@ -12661,14 +12662,14 @@ Brain, n.:
     	The apparatus with which we think that we think.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    -Brain, v: [as in "to brain"]
    +Brain, v. [as in "to brain"]:
     	To rebuke bluntly, but not pointedly; to dispel a source
     	of error in an opponent.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
     brain-damaged, generalization of "Honeywell Brain Damage" (HBD), a
     theoretical disease invented to explain certain utter cretinisms in
    -Multics, adj:
    +Multics, adj.:
     	Obviously wrong; cretinous; demented.  There is an implication
     	that the person responsible must have suffered brain damage,
     	because he/she should have known better.  Calling something
    @@ -12725,7 +12726,7 @@ Bride, n.:
     %
     Bridge ahead.  Pay troll.
     %
    -briefcase, n:
    +Briefcase, n.:
     	A trial where the jury gets together and forms a lynching party.
     %
     Briefly stated, the findings are that when presented with an array of
    @@ -12777,14 +12778,14 @@ believe that if you sleep with your head under the pillow a fairy will come
     and take all your teeth.
     		-- Mike Harding, "The Armchair Anarchist's Almanac"
     %
    -broad-mindedness, n:
    +Broad-mindedness, n.:
     	The result of flattening high-mindedness out.
     %
     Brogan's Constant:
     	People tend to congregate in the back
     	of the church and the front of the bus.
     %
    -brokee, n:
    +Brokee, n.:
     	Someone who buys stocks on the advice of a broker.
     %
     Brontosaurus Principle:
    @@ -12801,7 +12802,7 @@ Brooke's Law:
     Brooks' Law:
     	Adding manpower to a late software project makes it later
     %
    -Brucify, v:
    +Brucify, v.:
     	1: Kill by nailing onto style(9); "David O'Brien was brucified"
     	2: Annoy constantly by reminding of potential improvements
     	   [syn: {torment}, {rag}, {tantalize}, {bedevil}, {dun},
    @@ -12842,7 +12843,7 @@ wrote the program.
     Fortunately, the second-to-last bug has just been fixed.
     		-- Ray Simard
     %
    -Bug, n:
    +Bug, n.:
     	An elusive creature living in a program that makes it incorrect.
     	The activity of "debugging", or removing bugs from a program, ends
     	when people get tired of doing it, not when the bugs are removed.
    @@ -12859,7 +12860,7 @@ BULLWINKLE: "You just leave that to my pal.  He's the brains of the
     	    outfit."
     GENERAL:    "What does that make YOU?"
     BULLWINKLE: "What else?  An executive..."
    -		-- Jay Ward
    +		-- Jay Ward, "Rocky and Bullwinkle"
     %
     Bumper sticker:
     	All the parts falling off this car are
    @@ -12868,7 +12869,7 @@ Bumper sticker:
     Bunker's Admonition:
     	You cannot buy beer; you can only rent it.
     %
    -Burbulation, v:
    +Burbulation, v.:
     	The obsessive act of opening and closing a refrigerator door in
     	an attempt to catch it before the automatic light comes on.
     		-- Rich Hall & Friends, "Sniglets"
    @@ -12878,14 +12879,14 @@ Bureau Termination, Law of:
     	the number of employees in that bureau will double within
     	12 months after the decision is made.
     %
    -bureaucracy, n:
    +Bureaucracy, n.:
     	A method for transforming energy into solid waste.
     %
     Bureaucrat, n.:
     	A person who cuts red tape sideways.
     		-- J. McCabe
     %
    -bureaucrat, n:
    +Bureaucrat, n.:
     	A politician who has tenure.
     %
     Burke's Postulates:
    @@ -13045,7 +13046,7 @@ But you shall not escape my iambics.
     But you who live on dreams, you are better pleased with the sophistical
     reasoning and frauds of talkers about great and uncertain matters than
     those who speak of certain and natural matters, not of such lofty nature.
    -		-- Leonardo Da Vinci, "The Codex on the Flight of Birds"
    +		-- Leonardo da Vinci, "The Codex on the Flight of Birds"
     %
     Buzz off, Banana Nose; Relieve mine eyes
     Of hateful soreness, purge mine ears of corn;
    @@ -13062,7 +13063,7 @@ Thy cheer, like thy complexion, is the pits.
     Be off, I say; go bug somebody new,
     Scram, beat it, get thee hence, and nuts to you.
     %
    -buzzword, n:
    +Buzzword, n.:
     	The fly in the ointment of computer literacy.
     %
     By doing just a little every day, you can
    @@ -13082,7 +13083,7 @@ by practice, they get to be wide apart.
     By necessity, by proclivity, and by delight, we all quote.
     In fact, it is as difficult to appropriate the thoughts of others
     as it is to invent.
    -		-- R. Emerson
    +		-- Ralph Waldo Emerson
     		-- Quoted from a fortune cookie program
     		(whose author claims, "Actually, stealing IS easier.")
     		[to which I reply, "You think it's easy for me to
    @@ -13117,7 +13118,7 @@ By working faithfully eight hours a day,
     you may eventually get to be boss and work twelve.
     		-- Robert Frost
     %
    -byob, v:
    +BYOB, v.:
     	Believing Your Own Bull
     %
     Bypasses are devices that allow some people to dash from point A to
    @@ -13148,7 +13149,7 @@ C makes it easy for you to shoot yourself in the foot.  C++ makes that
     harder, but when you do, it blows away your whole leg.
     		-- Bjarne Stroustrup
     %
    -C, n:
    +C, n.:
     	A programming language that is sort of like Pascal except more like
     	assembly except that it isn't very much like either one, or anything
     	else.  It is either the best language available to the art today, or
    @@ -13161,7 +13162,7 @@ Cabbage, n.:
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
     Cable is not a luxury, since many areas have poor TV reception.
    -		-- The mayor of Tucson, Arizona, 1989
    +		-- The Mayor of Tucson, Arizona, 1989
     %
     Cache:
     	A very expensive part of the memory system of a computer that no one
    @@ -13395,7 +13396,7 @@ Did you ever have the measles, and, if so, how many?
     %
     Center meeting at 4pm in 2C-543.
     %
    -cerebral atrophy, n:
    +Cerebral atrophy, n.:
     	The phenomena which occurs as brain cells become weak and sick, and
     impair the brain's performance.  An abundance of these "bad" cells can cause
     symptoms related to senility, apathy, depression, and overall poor academic
    @@ -13404,7 +13405,7 @@ everyday activity, but large amounts are weakened by intense mental effort
     and the assimilation of difficult concepts.  Many college students become
     victims of this dread disorder due to poor habits such as overstudying.
     
    -cerebral darwinism, n:
    +Cerebral darwinism, n.:
     	The theory that the effects of cerebral atrophy can be reversed
     through the purging action of heavy alcohol consumption.  Large amounts of
     alcohol cause many brain cells to perish due to oxygen deprivation.  Through
    @@ -13415,7 +13416,7 @@ Thus, the devastating effects of cerebral atrophy are reversed, and academic
     performance actually increases beyond previous levels.
     %
     Cerebus:	I'd love to lick apricot brandy out of your navel.
    -Jaka:		Look, Cerebus-- Jaka has to tell you ... something
    +Jaka:		Look, Cerebus -- Jaka has to tell you ... something
     Cerebus:	If Cerebus had a navel, would you lick apricot brandy
     		out of it?
     Jaka:		Ugh!
    @@ -13443,7 +13444,7 @@ nuts, as would but for this amending Order not qualify as nuts
     %
     Certainly the game is rigged.
     Don't let that stop you; if you don't bet, you can't win.
    -		-- Robert Heinlein, "Time Enough For Love"
    +		-- Robert A. Heinlein, "Time Enough For Love"
     %
     Certainly there are things in life that money can't buy,
     But it's very funny --
    @@ -13485,18 +13486,18 @@ a function that would continue to grow, but never reach unity.  This equation
     can be applied to charging capacitors, over-damped springs, and the human
     race in general.
     %
    -character density, n.:
    +Character density, n.:
     	The number of very weird people in the office.
     %
     Character is what you are in the dark!
     		-- Lord John Whorfin
     %
    -CHARITY:
    -	A thing that begins at home and usually stays there.
    -%
     Charity begins at home.
     		-- Publius Terentius Afer (Terence)
     %
    +Charity, n.:
    +	A thing that begins at home and usually stays there.
    +%
     Charlie Brown:	Why was I put on this earth?
     Linus:		To make others happy.
     Charlie Brown:	Why were others put on this earth?
    @@ -13513,7 +13514,7 @@ Cheap things are of no value, valuable things are not cheap.
     Check me if I'm wrong, Sandy, but if I kill all the golfers...
     they're gonna lock me up and throw away the key!
     %
    -checkuary, n:
    +Checkuary, n.:
     	The thirteenth month of the year.  Begins New Year's Day and ends
     	when a person stops absentmindedly writing the old year on his checks.
     %
    @@ -13522,7 +13523,7 @@ Cheer Up!  Things are getting worse at a slower rate.
     Cheese -- milk's leap toward immortality.
     		-- Clifton Fadiman, "Any Number Can Play"
     %
    -Chef, n:
    +Chef, n.:
     	Any cook who swears in French.
     %
     Cheit's Lament:
    @@ -13767,7 +13768,7 @@ please?" it asked the bartender.
     "Hey, aren't you the string I just threw out of here?"
     	"No, I'm a frayed knot."
     %
    -clone, n:
    +Clone, n.:
     	1. An exact duplicate, as in "our product is a clone of their
     	product."  2. A shoddy, spurious copy, as in "their product
     	is a clone of our product."
    @@ -13992,7 +13993,7 @@ And that you'll be so glad to do,
     Because you'll be my POSSLQ.
     %
     Come, muse, let us sing of rats!
    -		-- From a poem by James Grainger, 1721-1767
    +		-- From a poem by James Grainger (1721-1767)
     %
     Come quickly, I am tasting stars!
     		-- Dom Perignon, upon discovering champagne
    @@ -14012,7 +14013,7 @@ And pall the in the dunnest smoke of hell,
     That my keen knife see not the wound it makes,
     Nor heaven peep through the blanket of the dark,
     To cry `Hold, hold!'
    -		-- Lady MacBeth
    +		-- Lady Macbeth, "Macbeth"
     %
     Comedy, like Medicine, was never meant to be practiced by the general public.
     %
    @@ -14071,7 +14072,7 @@ Common sense is the collection of prejudices acquired by age eighteen.
     %
     Common sense is the most evenly distributed quantity in the world.
     Everyone thinks he has enough.
    -		-- Descartes, 1637
    +		-- Rene Descartes, 1637
     %
     Commoner's three laws of ecology:
     	1) No action is without side-effects.
    @@ -14112,7 +14113,7 @@ COMPLEX SYSTEM:
     COMPLIMENT:
     	When you say something to another which everyone knows isn't true.
     %
    -compuberty, n:
    +Compuberty, n.:
     	The uncomfortable period of emotional and hormonal changes a
     	computer experiences when the operating system is upgraded and
     	a sun4 is put online sharing files.
    @@ -14171,7 +14172,7 @@ Computers will not be perfected until they can compute how much more
     than the estimate the job will cost.
     %
     Conceit causes more conversation than wit.
    -		-- LaRouchefoucauld
    +		-- La Rochefoucauld
     %
     Concept, n.:
     	Any "idea" for which an outside consultant billed you more than
    @@ -14179,7 +14180,7 @@ Concept, n.:
     %
     Conceptual integrity in turn dictates that the design must proceed
     from one mind, or from a very small number of agreeing resonant minds.
    -		-- Frederick Brooks Jr., "The Mythical Man Month"
    +		-- Frederick Brooks, Jr., "The Mythical Man-Month"
     %
     Condense soup, not books!
     %
    @@ -14200,7 +14201,7 @@ that a tweed coat is good for dandruff.
     %
     Confessions may be good for the soul, but they are bad for
     the reputation.
    -		-- Lord Thomas Dewar
    +		-- Lord Thomas Robert Dewar
     %
     Confidant, confidante, n.:
     	One entrusted by A with the secrets of B, confided to himself by C.
    @@ -14226,7 +14227,7 @@ Conformity is the refuge of the unimaginative.
     Confucius say too damn much!
     %
     Confucius say too much.
    -		-- Recent Chinese Proverb
    +		-- Recent Chinese proverb
     %
     Confusion will be my epitaph
     as I walk a cracked and broken path
    @@ -14281,10 +14282,10 @@ Conjecture: All odd numbers are prime.
     	Engineer's Proof:
     		3 is prime.  5 is prime.  7 is prime.  9 is prime.
     		11 is prime.  13 is prime ...
    -	Computer Scientists's Proof:
    +	Computer Scientist's Proof:
     		3 is prime.  3 is prime.  3 is prime.  3 is prime...
     %
    -Connector Conspiracy, n:
    +Connector Conspiracy, n.:
     	[probably came into prominence with the appearance of the
     KL-10, none of whose connectors match anything else] The tendency of
     manufacturers (or, by extension, programmers or purveyors of anything)
    @@ -14299,7 +14300,7 @@ governing that is hard.
     		-- Chinggis (Genghis) Khan
     %
     Conscience doth make cowards of us all.
    -		-- Shakespeare
    +		-- William Shakespeare
     %
     Conscience is a mother-in-law whose visit never ends.
     		-- H. L. Mencken
    @@ -14380,7 +14381,9 @@ seduction, observable even in the animal kingdom.
     %
     "Contrariwise," continued Tweedledee, "if it was so, it might be, and
     if it were so, it would be; but as it isn't, it ain't.  That's logic!"
    -		-- Lewis Carroll, "Through the Looking Glass"
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     Contrary to popular belief, penguins are not the salvation of modern
     technology.  Neither do they throw parties for the urban proletariat.
    @@ -14417,7 +14420,7 @@ Coronation, n.:
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
     Correction does much, but encouragement does more.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     Corrupt, adj.:
     	In politics, holding an office of trust or profit.
    @@ -14457,7 +14460,7 @@ Courage is resistance to fear, mastery of fear -- not absence of fear.
     %
     Courage is your greatest present need.
     %
    -court, n.:
    +Court, n.:
     	A place where they dispense with justice.
     		-- Arthur Train
     %
    @@ -14556,7 +14559,7 @@ CURSOR:
     	One whose program will not run.
     		-- Robb Russon
     %
    -cursor address, n:
    +Cursor address, n.:
     	"Hello, cursor!"
     		-- Stan Kelly-Bootle, "The Devil's DP Dictionary"
     %
    @@ -14599,18 +14602,18 @@ Cutler Webster's Law:
     %
     Cutting the space budget really restores my faith in humanity.  It
     eliminates dreams, goals, and ideals and lets us get straight to the
    -business of hate, debauchery, and self-annihilation."
    +business of hate, debauchery, and self-annihilation.
     		-- Johnny Hart
     %
    -CYNIC:
    -	Experienced.
    -%
     Cynic, n.:
     	A blackguard whose faulty vision sees things as they are, not
     	as they ought to be.  Hence the custom among the Scythians of
     	plucking out a cynic's eyes to improve his vision.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    +Cynic, n.:
    +	Experienced.
    +%
     Cynic, n.:
     	One who looks through rose-colored glasses with a jaundiced
     	eye.
    @@ -15049,7 +15052,7 @@ claim "I've got a deep semantic theory", they are truly blessed.
     DEFAULT:
     	The hardware's, of course.
     %
    -default, n.:
    +Default, n.:
     	[Possibly from Black English "De fault wid dis system is you,
     mon."] The vain attempt to avoid errors by inactivity.  "Nothing will
     come of nothing: speak again." -- King Lear.
    @@ -15102,10 +15105,10 @@ Delay is preferable to error.
     		-- Thomas Jefferson
     %
     Delay not, Caesar.  Read it instantly.
    -		-- Shakespeare, "Julius Caesar" 3,1
    +		-- William Shakespeare, "Julius Caesar" 3,1
     
     Here is a letter, read it at your leisure.
    -		-- Shakespeare, "Merchant of Venice" 5,1
    +		-- William Shakespeare, "Merchant of Venice" 5,1
     
     	[Quoted in "VMS Internals and Data Structures", V4.4, when
     	 referring to I/O system services.]
    @@ -15137,7 +15140,7 @@ Deliver yesterday, code today, think tomorrow.
     Delores breezed along the surface of her life like a flat stone forever
     skipping along smooth water, rippling reality sporadically but oblivious
     to it consistently, until she finally lost momentum, sank, and due to an
    -overdose of flouride as a child which caused her to suffer from chronic
    +overdose of fluoride as a child which caused her to suffer from chronic
     apathy, doomed herself to lie forever on the floor of her life as useless
     as an appendix and as lonely as a five-hundred pound barbell in a
     steroid-free fitness center.
    @@ -15154,7 +15157,7 @@ Democracy becomes a government of bullies, tempered by editors.
     		-- Ralph Waldo Emerson
     %
     Democracy can only be measured on the existence of an opposition.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     Democracy is a device that insures we shall be governed no better than
     we deserve.
    @@ -15173,7 +15176,7 @@ don't think.
     %
     Democracy is a process by which the people are free to choose the man who
     will get the blame.
    -		-- Laurence J. Peter
    +		-- Dr. Laurence J. Peter
     %
     Democracy is also a form of worship.
     It is the worship of Jackals by Jackasses.
    @@ -15197,7 +15200,7 @@ Democracy is the worst form of government except all those other
     forms that have been tried from time to time.
     		-- Winston Churchill
     %
    -Democracy, n:
    +Democracy, n.:
     	A government of the masses.  Authority derived through mass meeting
     or any other form of direct expression.  Results in mobocracy.  Attitude
     toward property is communistic... negating property rights.  Attitude toward
    @@ -15208,7 +15211,7 @@ agitation, discontent, anarchy.
     		-- U. S. Army Training Manual No. 2000-25 (1928-1932),
     		   since withdrawn.
     %
    -Democracy, n:
    +Democracy, n.:
     	In which you say what you like and do what you're told.
     		-- Gerald Barry
     
    @@ -15242,8 +15245,8 @@ Dentist, n.:
     	pulls coins out of one's pockets.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    -Denver, n:
    -	A smallish city located just below the `O' in Colorado.
    +Denver, n.:
    +	A smallish city located just below the "O" in Colorado.
     %
     Depart in pieces, i.e., split.
     %
    @@ -15260,7 +15263,7 @@ Deprive a mirror of its silver and even the Czar won't see his face.
     Der Horizont vieler Menschen ist ein Kreis mit Radius Null -
     und das nennen sie ihren Standpunkt.
     %
    -design, v:
    +Design, v.:
     	What you regret not doing later on.
     %
     Desist from enumerating your fowl
    @@ -15445,7 +15448,7 @@ Diplomacy is the art of saying "nice doggie" until you can find a rock.
     Diplomacy is to do and say, the nastiest thing in the nicest way.
     		-- Balfour
     %
    -diplomacy, n:
    +Diplomacy, n.:
     	Lying in state.
     %
     Dirksen's Three Laws of Politics:
    @@ -15455,7 +15458,7 @@ Dirksen's Three Laws of Politics:
     	3: Don't get mad, get even.
     		-- Sen. Everett Dirksen
     %
    -disbar, n:
    +Disbar, n.:
     	As distinguished from some other bar.
     %
     Disc space -- the final frontier!
    @@ -15551,7 +15554,7 @@ Their tastes may not be the same.
     Do not drink coffee in early A.M.  It will keep you awake until noon.
     %
     Do not handicap your children by making their lives easy.
    -		-- Robert Heinlein
    +		-- Robert A. Heinlein
     %
     Do not meddle in the affairs of troff, for it is subtle and quick to anger.
     %
    @@ -15658,7 +15661,7 @@ between Nixon and the White House.
     		-- John F. Kennedy, in 1960
     %
     Do you suffer painful elimination?
    -		-- Don Knuth, "Structured Programming with Gotos"
    +		-- Donald E. Knuth, "Structured Programming with Gotos"
     
     Do you suffer painful recrimination?
     		-- Nancy Boxer, "Structured Programming with Come-froms"
    @@ -15683,7 +15686,7 @@ your business success?  Here's a telling test: Look in the mirror.  Is
     your skin smooth and lovely, your hair gleaming, your make-up glamorous?
     Are you slender enough for your height?  Do you stand erect, confident?
     Yes?  Then you are on your way to success as a woman.
    -		-- Ladies Home Journal, 1947 advertisement
    +		-- Ladies' Home Journal, 1947 advertisement
     %
     Do your otters do the shimmy?
     Do they like to shake their tails?
    @@ -15728,12 +15731,12 @@ Doing gets it done.
     Don
     Ameche:	I didn't know you had a cousin Penelope, Bill!
     	Was she pretty?
    -W.C.:	Well, her face was so wrinkled it looked like seven miles of
    +W. C.:	Well, her face was so wrinkled it looked like seven miles of
     	bad road.  She had so many gold teeth, Don, she use to have
     	to sleep with her head in a safe.  She died in Bolivia.
     Don:	Oh Bill, it must be hard to lose a relative.
    -W.C.:	It's almost impossible.
    -		-- W.C. Fields, "The Further Adventures of Larson E.
    +W. C.:	It's almost impossible.
    +		-- W. C. Fields, "The Further Adventures of Larson E.
     		   Whipsnade and other Tarradiddles"
     %
     Don't abandon hope: your Tom Mix decoder ring arrives tomorrow.
    @@ -15773,7 +15776,7 @@ with those that take care of themselves.
     Don't cook tonight -- starve a rat today!
     %
     Don't crush that dwarf, hand me the pliers!
    -		-- Firesign Theatre
    +		-- The Firesign Theatre
     %
     Don't despair; your ideal lover is waiting for you around the corner.
     %
    @@ -15888,12 +15891,12 @@ Your brains are in it.
     Don't make a big deal out of everything; just deal with everything.
     %
     Don't marry for money; you can borrow it cheaper.
    -		-- Scottish Proverb
    +		-- Scottish proverb
     %
     Don't mind him; politicians always sound like that.
     %
     Don't patch bad code -- rewrite it.
    -		-- "The Elements of Programming Style", Kernighan and Plauger
    +		-- Kernighan and Plauger, "The Elements of Programming Style"
     %
     Don't plan any hasty moves.
     You'll be evicted soon anyway.
    @@ -15922,7 +15925,7 @@ Don't say "yes" until I finish talking.
     Don't shoot until you're sure you both aren't on the same side.
     %
     Don't shout for help at night.  You might wake your neighbors.
    -		-- Stanislaw J. Lem, "Unkempt Thoughts"
    +		-- Stanislaw J. Lec, "Unkempt Thoughts"
     %
     Don't smoke the next cigarette.  Repeat.
     %
    @@ -16047,7 +16050,7 @@ Double Bucky, I'd like a whole word of you!
     		   be added to terminal codes on 36-bit machines for use
     		   by screen editors.  [to the tune of "Rubber Ducky"]
     %
    -double-blind Experiment, n:
    +Double-blind Experiment, n.:
     	An experiment in which the chief researcher believes he is
     fooling both the subject and the lab assistant.  Often accompanied
     by a strong belief in the tooth fairy.
    @@ -16172,7 +16175,7 @@ DROP THE DAMN BEAR!!!
     Drop the vase and it will become a Ming of the past.
     		-- The Adventurer
     %
    -drug, n:
    +Drug, n.:
     	A substance that, when injected into a rat, produces a scientific
     	paper.
     %
    @@ -16232,13 +16235,13 @@ Dustin Farnum:	Why, yesterday, I had the audience glued to their seats!
     Oliver Herford:	Wonderful!  Wonderful!  Clever of you to think of it!
     		-- Brian Herbert, "Classic Comebacks"
     %
    -Duty, n:
    +Duty, n.:
     	What one expects from others.
     		-- Oscar Wilde
     %
     Dying is a very dull, dreary affair.  My advice to you is to have
     nothing whatever to do with it.
    -		-- W. Somerset Maughm, his last words
    +		-- W. Somerset Maugham, his last words
     %
     Dying is easy.  Comedy is difficult.
     		-- Actor Edmond Gween, on his deathbed
    @@ -16351,9 +16354,11 @@ But I'm goin' to heaven in a flash of fire,
     Eat as much as you like -- just don't swallow it.
     		-- Harry Secombe's diet
     %
    -Eat drink and be merry!  Tomorrow you may be in Utah.
    +Eat, drink, and be merry!  Tomorrow you may be in Utah.
     %
    -Eat drink and be merry, for tomorrow we diet.
    +Eat, drink, and be merry, for tomorrow they may make it illegal.
    +%
    +Eat, drink, and be merry, for tomorrow we diet.
     %
     Eat, drink, and be merry, for tomorrow you may work.
     %
    @@ -16371,8 +16376,8 @@ Eating chocolate is like being in love without the aggravation.
     Economics is extremely useful as a form of employment for economists.
     		-- John Kenneth Galbraith
     %
    -economics, n.:
    -	Economics is the study of the value and meaning of J.K. Galbraith.
    +Economics, n.:
    +	Economics is the study of the value and meaning of J. K. Galbraith.
     		-- Mike Harding, "The Armchair Anarchist's Almanac"
     %
     Economies of scale:
    @@ -16383,7 +16388,7 @@ Economies of scale:
     	as an article of faith by those who love small machines and all
     	those limitations.
     %
    -economist, n:
    +Economist, n.:
     	Someone who's good with figures, but doesn't have enough
     	personality to become an accountant.
     %
    @@ -16424,17 +16429,17 @@ royal-blue chickens.
     		-- Fran Lebowitz, "Social Studies"
     %
     Eeny, Meeny, Jelly Beanie, the spirits are about to speak!
    -		-- Bullwinkle Moose
    +		-- Bullwinkle J. Moose
     %
     Eggheads unite!  You have nothing to lose but your yolks.
    -		-- Adlai Stevenson
    +		-- Adlai E. Stevenson
     %
     Eggnog is a traditional holiday drink invented by the English.  Many
     people wonder where the word "eggnog" comes from.  The first syllable
     comes from the English word "egg", meaning "egg".  I don't know where
     the "nog" comes from.
     
    -To make eggnog, you'll need rum, whiskey, wine gin and, if they are in
    +To make eggnog, you'll need rum, whiskey, wine, gin and, if they are in
     season, eggs...
     %
     Ego sum ens omnipotens
    @@ -16445,9 +16450,8 @@ to relieve the pain of being a damned fool.
     %
     Egotism is the anesthetic which numbs the pain of stupidity.
     %
    -Egotism, n:
    +Egotism, n.:
     	Doing the New York Times crossword puzzle with a pen.
    -
     %
     Egotist, n.:
     	A person of low taste, more interested in himself than me.
    @@ -16456,8 +16460,8 @@ Egotist, n.:
     egrep -n '^[a-z].*\(' $ | sort -t':' +2.0
     %
     Ehrman's Commentary:
    -	1.  Things will get worse before they get better.
    -	2.  Who said things would get better?
    +	(1) Things will get worse before they get better.
    +	(2) Who said things would get better?
     %
     ...eighty years later he could still recall with the young pang of his
     original joy his falling in love with Ada.
    @@ -16466,12 +16470,12 @@ original joy his falling in love with Ada.
     Einstein argued that there must be simplified explanations of nature, because
     God is not capricious or arbitrary.  No such faith comforts the software
     engineer.
    -		-- Fred Brooks
    +		-- Frederick Brooks, Jr.
     %
     Either I'm dead or my watch has stopped.
     		-- Groucho Marx' last words
     %
    -Elbonics, v:
    +Elbonics, v.:
     	The actions of two people maneuvering for one
     	armrest in a movie theatre.
     		-- Rich Hall & Friends, "Sniglets"
    @@ -16521,13 +16525,13 @@ WARNING:
     %
     Electrical Engineers do it with less resistance.
     %
    -Electrocution, n:
    +Electrocution, n.:
     	Burning at the stake with all the modern improvements.
     %
     Elegance and truth are inversely related.
     		-- Becker's Razor
     %
    -Elephant, n:
    +Elephant, n.:
     	A mouse built to government specifications.
     %
     Elevators smell different to midgets.
    @@ -16549,7 +16553,7 @@ Half asleep, Eli murmured,
     %
     Elliptic paraboloids for sale.
     %
    -Elliptical, n:
    +Elliptical, n.:
     	The feel of a kiss.
     %
     Eloquence is logic on fire.
    @@ -16557,10 +16561,10 @@ Eloquence is logic on fire.
     Elwood:  What kind of music do you get here ma'am?
     Barmaid: Why, we get both kinds of music, Country and Western.
     %
    -Emacs, n:
    +Emacs, n.:
     	A slow-moving parody of a text editor.
     %
    -Emersons' Law of Contrariness:
    +Emerson's Law of Contrariness:
     	Our chief want in life is somebody who shall make us do
     	what we can.  Having found them, we shall then hate them
     	for it.
    @@ -16595,7 +16599,7 @@ Liberal Arts:	"Do you want fries with that?"
     English literature's performing flea.
     		-- Sean O'Casey on P. G. Wodehouse
     %
    -Engram, n:
    +Engram, n.:
     	1. The physical manifestation of human memory -- "the engram."
     2. A particular memory in physical form.  [Usage note:  this term is no longer
     in common use.  Prior to Wilson and Magruder's historic discovery, the nature
    @@ -16610,14 +16614,14 @@ time.]
     		-- New Century Unabridged English Dictionary,
     		   3rd edition, 2007 A.D.
     %
    -enhance, v:
    +Enhance, v.:
     	To tamper with an image, usually to its detriment.
     %
     Enjoy your life; be pleasant and gay, like the birds in May.
     %
     Enjoy yourself while you're still old.
     %
    -Entrepreneur, n:
    +Entrepreneur, n.:
     	A high-rolling risk taker who would rather
     	be a spectacular failure than a dismal success.
     %
    @@ -16629,7 +16633,7 @@ Entropy requires no maintenance.
     Envy is a pain of mind that successful men cause their neighbors.
     		-- Onasander
     %
    -Envy, n:
    +Envy, n.:
     	Wishing you'd been born with an unfair advantage,
     	instead of having to try and acquire one.
     %
    @@ -16655,7 +16659,9 @@ Es brilig war.  Die schlichte Toven
     	Wirrten und wimmelten in Waben;
     Und aller-m"umsige Burggoven
     	Dir mohmen R"ath ausgraben.
    -		-- Lewis Carroll, "Through the Looking Glass"
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     Eschew obfuscation.
     %
    @@ -16673,7 +16679,7 @@ Eternity is a terrible thought.  I mean, where's it going to end?
     Etiquette is for those with no breeding;
     fashion for those with no taste.
     %
    -Etymology, n:
    +Etymology, n.:
     	Some early etymological scholars came up with derivations that
     	were hard for the public to believe.  The term 'etymology' was
     	formed from the Latin 'etus' ("eaten"), the root 'mal' ("bad"),
    @@ -16681,9 +16687,9 @@ Etymology, n:
     	hard to swallow."
     		-- Mike Kellen
     %
    -Euch ist becannt, was wir beduerfen;
    +Euch ist bekannt, was wir beduerfen;
     Wir wollen stark Getraenke schluerfen.
    -		-- Goethe, "Faust"
    +		-- Johann Wolfgang von Goethe, "Faust"
     %
     Eudaemonic research proceeded with the casual mania peculiar to this part of
     the world.  Nude sunbathing on the back deck was combined with phone calls to
    @@ -16852,7 +16858,7 @@ Therefore fire engines are red.
     Ever wondered about the origins of the term "bugs" as applied to computer
     technology?  U.S. Navy Capt. Grace Murray Hopper has firsthand explanation.
     The 74-year-old captain, who is still on active duty, was a pioneer in
    -computer technology during World War II.  At the C.W. Post Center of Long
    +computer technology during World War II.  At the C. W. Post Center of Long
     Island University, Hopper told a group of Long Island public school adminis-
     trators that the first computer "bug" was a real bug--a moth.  At Harvard
     one August night in 1945, Hopper and her associates were working on the
    @@ -16909,7 +16915,7 @@ spending money alone.  It is spending the sweat of its laborers, the
     genius of its scientists, the hopes of its children.  This is not a way
     of life at all in any true sense.  Under the clouds of war, it is
     humanity hanging on a cross of iron.
    -		-- Dwight Eisenhower, April 16, 1953
    +		-- Dwight D. Eisenhower, April 16, 1953
     %
     Every Horse has an Infinite Number of Legs (proof by intimidation):
     
    @@ -17090,7 +17096,7 @@ Everybody is given the same amount of hormones, at birth, and
     if you want to use yours for growing hair, that's fine with me.
     %
     Everybody is somebody else's weirdo.
    -		-- Dykstra
    +		-- Edsger W. Dijkstra
     %
     Everybody knows that the dice are loaded.  Everybody rolls with their
     fingers crossed.  Everybody knows the war is over.  Everybody knows the
    @@ -17202,7 +17208,7 @@ Everything might be different in the present
     if only one thing had been different in the past.
     %
     Everything new stalls because there is precedence for the old.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     Everything should be built top-down, except the first time.
     %
    @@ -17306,7 +17312,7 @@ Excess on occasion is exhilarating.  It prevents moderation from
     acquiring the deadening effect of a habit.
     		-- W. Somerset Maugham
     %
    -Excessive login messages is a sure sign of senility.
    +Excessive login messages are a sure sign of senility.
     %
     Excessive login or logout messages are a sure sign of senility.
     %
    @@ -17332,7 +17338,7 @@ Expect the worst, it's the least you can do.
     %
     Expedience is the best teacher.
     %
    -Expense accounts, n:
    +Expense accounts, n.:
     	Corporate food stamps.
     %
     Experience is a good teacher, but she sends in terrific bills.
    @@ -17410,6 +17416,11 @@ F:	When into a room I plunge, I
     	On the poison they're exuding.
     		-- The Roguelet's ABC
     %
    +F. Scott Fitzgerald to Hemingway:
    +	"Ernest, the rich are different from us."
    +Hemingway:
    +	"Yes.  They have more money."
    +%
     f u cn rd ths, itn tyg h myxbl cd.
     %
     f u cn rd ths, u cn gt a gd jb n cmptr prgrmmng.
    @@ -17462,7 +17473,7 @@ Faith goes out through the window when beauty comes in at the door.
     Faith has never moved as much as a pin-head from the place it
     ought to be according to tradition and the scriptures.  It is
     the doubt that moved all the mountains.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     Faith is the quality that enables you to eat blackberry jam
     on a picnic without looking to see whether the seeds move.
    @@ -17470,11 +17481,11 @@ on a picnic without looking to see whether the seeds move.
     Faith is under the left nipple.
     		-- Martin Luther
     %
    -Faith, n:
    +Faith, n.:
     	That quality which enables us to
     	believe what we know to be untrue.
     %
    -Fakir, n:
    +Fakir, n.:
     	A psychologist whose charismatic data have inspired almost
     	religious devotion in his followers, even though the sources
     	seem to have shinnied up a rope and vanished.
    @@ -17603,7 +17614,7 @@ Fear and loathing, my man, fear and loathing.
     Fear is the greatest salesman.
     		-- Robert Klein
     %
    -feature, n:
    +Feature, n.:
     	A surprising property of a program.  Occasionally documented.  To
     	call a property a feature sometimes means the author did not
     	consider that case, and the program makes an unexpected, though
    @@ -17621,7 +17632,7 @@ Feeling amorous, she looked under the sheets and cried, "Oh, no,
     it's Microsoft!"
     %
     Felix Catus is your taxonomic nomenclature,
    -An endothermic quadroped, carniverous by nature.
    +An endothermic quadruped, carnivorous by nature.
     Your visual, olfactory, and auditory senses
     Contribute to your hunting skills and natural defenses.
     I find myself intrigued by your sub-vocal oscillations,
    @@ -17641,7 +17652,7 @@ I nonetheless consider you a true and valued friend.
     Fellow programmer, greetings!  You are reading a letter which will bring
     you luck and good fortune.  Just mail (or UUCP) ten copies of this letter
     to ten of your friends.  Before you make the copies, send a chip or
    -other bit of hardware, and 100 lines of 'C' code to the first person on the
    +other bit of hardware, and 100 lines of "C" code to the first person on the
     list given at the bottom of this letter.  Then delete their name and add
     yours to the bottom of the list.
     
    @@ -17680,14 +17691,14 @@ Rod:	No, the ability to get hung up on them.
     Few things are harder to put up with than the annoyance of a good example.
     		-- Mark Twain
     %
    -Fidelity, n:
    +Fidelity, n.:
     	A virtue peculiar to those who are about to be betrayed.
     %
     Fifteen men on a dead man's chest,
     Yo-ho-ho and a bottle of rum!
     Drink and the devil had done for the rest,
     Yo-ho-ho and a bottle of rum!
    -		-- Stevenson, "Treasure Island"
    +		-- Robert Louis Stevenson, "Treasure Island"
     %
     Fifth Law of Applied Terror:
     	If you are given an open-book exam, you will forget your book.
    @@ -17709,7 +17720,7 @@ Carolina.
     File cabinet:
     	A four drawer, manually activated trash compactor.
     %
    -filibuster, n:
    +Filibuster, n.:
     	Throwing your wait around.
     %
     Fill what's empty, empty what's full, scratch where it itches.
    @@ -17862,8 +17873,8 @@ and after questioning, released him to be charged on summons.
     telephone booths.
     		-- "Newcastle Morning Herald", NSW Australia, Aug 1980
     %
    -First things first -- but not necessarily in that order
    -		-- Dr. Who, "Doctor Who"
    +First things first -- but not necessarily in that order.
    +		-- The Doctor, "Doctor Who"
     %
     "First World" nations are the ones where people drive Japanese cars;
     "Second World" nations are where First World residents go on vacation;
    @@ -17871,7 +17882,7 @@ and "Third World" nations are the ones where people still dive out of
     trees to prove their manhood.
     		-- Dave Barry
     %
    -Fishbowl, n:
    +Fishbowl, n.:
     	A glass-enclosed isolation cell where newly
     	promoted managers are kept for observation.
     %
    @@ -17974,7 +17985,7 @@ catch him there."  With that, he jumped on his carbon cycle in an
     activated state and sped off along the reaction pathway ...
     		-- Daniel B. Murphy, "Precipitations"
     %
    -flowchart, n. & v.:
    +Flowchart, n. & v.:
     	[From flow "to ripple down in rich profusion, as hair" + chart
     "a cryptic hidden-treasure map designed to mislead the uninitiated."]
     1. n. The solution, if any, to a class of Mascheroni construction
    @@ -18002,7 +18013,7 @@ Flying saucers on occasion
     Aliens fume, put off invasion
     	While they brand these tales as lies.
     %
    -Fog Lamps, n:
    +Fog Lamps, n.:
     	Excessively (often obnoxiously) bright lamps mounted on the fronts
     	of automobiles; used on dry, clear nights to indicate that the
     	driver's brain is in a fog.  See also "Idiot Lights".
    @@ -18037,7 +18048,7 @@ For a good time, call (510) 642-9483
     For a holy stint, a moth of the cloth gave up his woolens for lint.
     %
     For a light heart lives long.
    -		-- Shakespeare, "Love's Labour's Lost"
    +		-- William Shakespeare, "Love's Labour's Lost"
     %
     For a man to truly understand rejection, he must first be ignored by a
     cat.
    @@ -18053,7 +18064,7 @@ prejudice, to fear, to miracle, to slavery, to the unknown, and to
     misery hereafter. The few have said "Think". The many have said "Believe!"
     		-- Robert Ingersoll, "Gods"
     %
    -For an adequate time call 555-3321
    +For an adequate time call 555-3321.
     %
     For an idea to be fashionable is ominous,
     since it must afterwards be always old-fashioned.
    @@ -18088,7 +18099,7 @@ that glue in math mode varies with the size only when it is an \mskip;
     when moving between an mskip and ordinary skip, the conversion factor
     1mu=1pt is always used.  The meaning of '\mskip\skip12' and
     '\baselineskip=\the\thickmskip' should be clear.
    -		-- Donald Knuth, TeX 82 -- Comparison with TeX80
    +		-- Donald E. Knuth, TeX 82 -- Comparison with TeX80
     %
     For fast-acting relief, try slowing down.
     %
    @@ -18269,7 +18280,7 @@ Breasts can sell anything. Shiny red latex body suits start
     religions.
     		-- Brian McGroarty 
     %
    -For years a secret shame destroyed my peace--
    +For years a secret shame destroyed my peace --
     I'd not read Eliot, Auden or MacNiece.
     But now I think a thought that brings me hope:
     Neither had Chaucer, Shakespeare, Milton, Pope.
    @@ -18292,13 +18303,13 @@ No, don't force it, get a bigger hammer.
     %
     FORCE YOURSELF TO RELAX!
     %
    -Forecast, n:
    +Forecast, n.:
     	A prediction of the future, based on the past, for
     	which the forecaster demands payment in the present.
     %
     Forest fires cause Smokey Bears.
     %
    -Forgetfulness, n:
    +Forgetfulness, n.:
     	A gift of God bestowed upon debtors in compensation for
     	their destitution of conscience.
     %
    @@ -18307,7 +18318,7 @@ Forgive and forget.
     %
     Forgive him,
     for he believes that the customs of his tribe are the laws of nature!
    -		-- G. B. Shaw
    +		-- George Bernard Shaw
     %
     Forgive, O Lord, my little jokes on Thee
     And I'll forgive Thy great big one on me.
    @@ -18329,7 +18340,7 @@ which is easier to parse using ad hoc techniques.
     %
     FORTRAN is not a flower but a weed -- it is hardy,
     occasionally blooms, and grows in every computer.
    -		-- A. J. Perlis
    +		-- Alan J. Perlis
     %
     FORTRAN is the language of Powerful Computers.
     		-- Steven Feiner
    @@ -18552,7 +18563,7 @@ CARTABLANCA:
     	trouble with the local French authorities who would really prefer
     	wine and the occupying Germans who believe that only their beer is
     	fit to be sold.  Wacky events ensue until the gripping climax in
    -	which the much-hated German beer distributer is drowned in a vat.
    +	which the much-hated German beer distributor is drowned in a vat.
     %
     FORTUNE DISCUSSES THE OBSCURE FILMS: #11
     
    @@ -18664,52 +18675,52 @@ it carries every reasonable implication of ill-will toward that person.
     %
     FORTUNE EXPLAINS WHAT JOB REVIEW CATCH PHRASES MEAN:	#1
     
    -skilled oral communicator:
    +Skilled oral communicator:
     	Mumbles inaudibly when attempting to speak.  Talks to self.
     	Argues with self.  Loses these arguments.
     
    -skilled written communicator:
    +Skilled written communicator:
     	Scribbles well.  Memos are invariable illegible, except for
     	the portions that attribute recent failures to someone else.
     
    -growth potential:
    +Growth potential:
     	With proper guidance, periodic counseling, and remedial training,
     	the reviewee may, given enough time and close supervision, meet
     	the minimum requirements expected of him by the company.
     
    -key company figure:
    +Key company figure:
     	Serves as the perfect counter example.
     %
     FORTUNE EXPLAINS WHAT JOB REVIEW CATCH PHRASES MEAN:	#4
     
    -consistent:
    +Consistent:
     	Reviewee hasn't gotten anything right yet, and it is anticipated
     	that this pattern will continue throughout the coming year.
     
    -an excellent sounding board:
    +An excellent sounding board:
     	Present reviewee with any number of alternatives, and implement
     	them in the order precisely opposite of his/her specification.
     
    -a planner and organizer:
    +A planner and organizer:
     	Usually manages to put on socks before shoes.  Can match the
     	animal tags on his clothing.
     %
     FORTUNE EXPLAINS WHAT JOB REVIEW CATCH PHRASES MEAN:	#9
     
    -has management potential:
    +Has management potential:
     	Because of his intimate relationship with inanimate objects, the
     	reviewee has been appointed to the critical position of department
     	pencil monitor.
     
    -inspirational:
    +Inspirational:
     	A true inspiration to others.  ("There, but for the grace of God,
     	go I.")
     
    -adapts to stress:
    +Adapts to stress:
     	Passes wind, water, or out depending upon the severity of the
     	situation.
     
    -goal oriented:
    +Goal oriented:
     	Continually sets low goals for himself, and usually fails
     	to meet them.
     %
    @@ -18866,7 +18877,7 @@ sword wielding purple fish glued to Harley-Davidson motorcycles.
     Oh, and have a nice day!
     		-- Bryce Nesbitt '84
     %
    -fortune's Contribution of the Month to the Animal Rights Debate:
    +Fortune's Contribution of the Month to the Animal Rights Debate:
     
     	I'll stay out of animals' way if they'll stay out of mine.
     	"Hey you, get off my plate"
    @@ -18948,9 +18959,9 @@ Fortune's Fictitious Country Song Title of the Week:
     FORTUNE'S FUN FACTS TO KNOW AND TELL:		#1
     	A guinea pig is not from Guinea but a rodent from South America.
     	A firefly is not a fly, but a beetle.
    -	A giant panda bear is really a member of the racoon family.
    +	A giant panda bear is really a member of the raccoon family.
     	A black panther is really a leopard that has a solid black coat
    -	    rather then a spotted one.
    +	    rather than a spotted one.
     	Peanuts are not really nuts.  The majority of nuts grow on trees
     		while peanuts grow underground.  They are classified as a
     		legume-part of the pea family.
    @@ -18962,7 +18973,7 @@ Ruth, but after the oldest daughter of President Grover Cleveland.
     %
     FORTUNE'S FUN FACTS TO KNOW AND TELL:		#37
     	Can you name the seven seas?
    -		Antartic, Artic, North Atlantic, South Atlantic, Indian,
    +		Antarctic, Arctic, North Atlantic, South Atlantic, Indian,
     		North Pacific, South Pacific.
     	Can you name the seven dwarfs from Snow White?
     		Doc, Dopey, Sneezy, Happy, Grumpy, Sleepy and Bashful.
    @@ -19236,7 +19247,7 @@ Three be the things I shall have till I die:
     %
     Four fifths of the perjury in the world is expended on
     tombstones, women and competitors.
    -		-- Lord Thomas Dewar
    +		-- Lord Thomas Robert Dewar
     %
     Four hours to bury the cat?
     Yes, damn thing wouldn't keep still, kept mucking about, 'owling...
    @@ -19272,8 +19283,8 @@ Frankly, Scarlett, I don't have a fix.
     Fraud is the homage that force pays to reason.
     		-- Charles Curtis, "A Commonplace Book"
     %
    -Free Speech Is The Right To Shout 'Theater' In A Crowded Fire.
    -		-- A Yippie Proverb
    +Free Speech Is The Right To Shout "Theater" In A Crowded Fire.
    +		-- A Yippie proverb
     %
     FreeBSD: everything but the fairings
     %
    @@ -19320,7 +19331,7 @@ Fried's 1st Rule:
     Friends may come and go, but enemies accumulate.
     		-- Thomas Jones
     %
    -Friends, n:
    +Friends, n.:
     	People who borrow your books and set wet glasses on them.
     
     	People who know you well, but like you anyway.
    @@ -19339,7 +19350,7 @@ Come I to make this gig at Caesar's laying down.
     %
     Friendships last when each friend thinks he has a slight superiority
     over the other.
    -		-- Honore DeBalzac
    +		-- Honore de Balzac
     %
     Frisbeetarianism, n.:
     	The belief that when you die, your soul goes up on the roof and
    @@ -19466,11 +19477,6 @@ That dead men rise up never,
     That even the weariest river winds somewhere safe to sea.
     		-- Swinburne
     %
    -F.S. Fitzgerald to Hemingway:
    -	"Ernest, the rich are different from us."
    -Hemingway:
    -	"Yes.  They have more money."
    -%
     Fuch's Warning:
     	If you actually look like your passport photo, you aren't well
     	enough to travel.
    @@ -19497,7 +19503,7 @@ Function reject.
     %
     Fundamentally, there may be no basis for anything.
     %
    -Furbling, v:
    +Furbling, v.:
     	Having to wander through a maze of ropes at an airport or bank
     	even when you are the only person in line.
     		-- Rich Hall, "Sniglets"
    @@ -19511,7 +19517,7 @@ but if we send it by ship, it's cargo.
     Future looks spotty.  You will spill soup in late evening.
     %
     Future will arrive by its own means.  Progress not so.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     G. B. Shaw to William Douglas Home: "Go on writing plays, my boy.  One
     of these days a London producer will go into his office and say to his
    @@ -19622,11 +19628,11 @@ Genius is the talent of a person who is dead.
     Genius may have its limitations, but stupidity is not thus handicapped.
     		-- Elbert Hubbard
     %
    -genius, n:
    +Genius, n.:
     	A chemist who discovers a laundry additive that rhymes with
     	"bright".
     %
    -genlock, n:
    +Genlock, n.:
     	Why he stays in the bottle.
     %
     Gentlemen,
    @@ -19641,7 +19647,7 @@ Each item and every farthing has been accounted for, with two regrettable
     exceptions for which I beg your indulgence.
     	Unfortunately the sum of one shilling and ninepence remains unaccounted
     for in one infantry battalion's petty cash and there has been a hideous
    -confusion as the number of jars of raspberry jam issued to one cavalry
    +confusion as to the number of jars of raspberry jam issued to one cavalry
     regiment during a sandstorm in western Spain.  This reprehensible carelessness
     may be related to the pressure of circumstance, since we are war with France, a
     fact which may come as a bit of a surprise to you gentlemen in Whitehall.
    @@ -19772,7 +19778,6 @@ Ginsberg's Theorem:
     	3. You can't even quit the game.
     
     Freeman's Commentary on Ginsberg's theorem:
    -
     	Every major philosophy that attempts to make life seem
     	meaningful is based on the negation of one part of Ginsberg's
     	Theorem.  To wit:
    @@ -19816,7 +19821,7 @@ Give me chastity and continence, but not just now.
     		-- St. Augustine
     %
     Give me enough medals, and I'll win any war.
    -		-- Napolean
    +		-- Napoleon
     %
     Give me libertines or give me meth.
     %
    @@ -19967,7 +19972,7 @@ God created woman.
     And boredom did indeed cease from that moment --
     but many other things ceased as well.
     Woman was God's second mistake.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     God did not create the world in seven days; he screwed around for six
     days and then pulled an all-nighter.
    @@ -20006,7 +20011,7 @@ God help those who do not help themselves.
     		-- Wilson Mizner
     %
     God helps them that helps themselves.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     %
     God, I ask for patience -- and I want it right now!
     %
    @@ -20023,7 +20028,7 @@ God is Dead.
     Nietzsche is Dead.
     		-- God
     Nietzsche is God.
    -		-- Dead
    +		-- The Dead
     %
     God is dead and I don't feel all too well either....
     		-- Ralph Moonen
    @@ -20056,12 +20061,12 @@ God made the integers; all else is the work of Man.
     %
     God made the world in six days, and was arrested on the seventh.
     %
    -God may be subtle, but he isn't plain mean.
    +God may be subtle, but He isn't plain mean.
     		-- Albert Einstein
     %
     God must have loved calories, she made so many of them.
     %
    -God must love the common man; He made so many of them.
    +God must love the Common Man; He made so many of them.
     %
     God rest ye CS students now,		The bearings on the drum are gone,
     Let nothing you dismay.			The disk is wobbling, too.
    @@ -20113,7 +20118,7 @@ Going the speed of light is bad for your age.
     Going to church does not make a person religious, nor does going to school
     make a person educated, any more than going to a garage makes a person a car.
     %
    -Gold, n:
    +Gold, n.:
     	A soft malleable metal relatively scarce in distribution.  It
     	is mined deep in the earth by poor men who then give it to rich
     	men who immediately bury it back in the earth in great prisons,
    @@ -20159,7 +20164,7 @@ Good advice is one of those insults that ought to be forgiven.
     %
     Good advice is something a man gives
     when he is too old to set a bad example.
    -		-- La Rouchefoucauld
    +		-- La Rochefoucauld
     %
     Good day for a change of scene.  Repaper the bedroom wall.
     %
    @@ -20243,10 +20248,10 @@ Gordon's Law:
     	If you think you have the solution, the question was poorly phrased.
     %
     Gosh that takes me back... or is it forward?  That's the trouble with
    -time travel, you never can tell."
    -		-- Dr. Who, "Androids of Tara"
    +time travel, you never can tell.
    +		-- The Doctor, "Doctor Who: Androids of Tara"
     %
    -gossip, n:
    +Gossip, n.:
     	Hearing something you like about someone you don't.
     		-- Earl Wilson
     %
    @@ -20288,7 +20293,7 @@ Goto, n.:
     	to complain about unstructured programmers.
     		-- Ray Simard
     %
    -Gourmet, n:
    +Gourmet, n.:
     	Anyone whom, when you fail to finish something strange or
     	revolting, remarks that it's an acquired taste and that you're
     	leaving the best part.
    @@ -20380,7 +20385,7 @@ place of residence.
     %
     GREAT MOMENTS IN HISTORY (#7):  April 2, 1751
     
    -Issac Newton becomes discouraged when he falls up a flight of stairs.
    +Isaac Newton becomes discouraged when he falls up a flight of stairs.
     %
     GREAT MOMENTS IN HISTORY (#7):  November 23, 1915
     
    @@ -20493,7 +20498,7 @@ GURU:
     	a senior vice-president and is ultimately responsible for the
     	phone call you are about to receive from your boss.
     %
    -guru, n:
    +Guru, n.:
     	A computer owner who can read the manual.
     %
     Gyroscope, n.:
    @@ -20525,10 +20530,10 @@ Martin's Extension:
     
     		[No, those who can't teach, teach here.  Ed.]
     %
    -hacker, n:
    +Hacker, n.:
     	Originally, any person with a knack for coercing stubborn inanimate
     things; hence, a person with a happy knack, later contracted by the mythical
    -philosopher Frisbee Frobenius to the common usage, 'hack'.
    +philosopher Frisbee Frobenius to the common usage, "hack."
     	In olden times, upon completion of some particularly atrocious body
     of coding that happened to work well, culpable programmers would gather in
     a small circle around a first edition of Knuth's Best Volume I by candlelight,
    @@ -20629,7 +20634,7 @@ But half the bee has got to be, vis-a-vis its entity.  See?
     But can a bee be said to be or not to be an entire bee,
     When half the bee is not a bee, due to some ancient injury?
     %
    -Half Moon tonight.  (At least its better than no Moon at all.)
    +Half Moon tonight.  (At least it is better than no Moon at all.)
     %
     Half of being smart is knowing what you're dumb at.
     %
    @@ -20649,7 +20654,7 @@ Half-done, n.:
     	Essex (along the park), make your first left onto Hester Street, walk
     	about fifteen steps, turn ninety degrees left, and stop.  Say to the
     	man, "Let me have a nice half-done."  Worth the trouble, wasn't it?
    -		-- Arthur Naiman
    +		-- Arthur Naiman, "Every Goy's Guide to Yiddish"
     %
     Halley's Comet: It came, we saw, we drank.
     %
    @@ -20669,7 +20674,7 @@ Hand, n.:
     Handel's Proverb:
     	You can't produce a baby in one month by impregnating 9 women!
     %
    -handshaking protocol, n:
    +Handshaking protocol, n.:
     	A process employed by hostile hardware devices to initiate a
     	terse but civil dialogue, which, in turn, is characterized by
     	occasional misunderstanding, sulking, and name-calling.
    @@ -20677,7 +20682,7 @@ handshaking protocol, n:
     Hanging on in quiet desperation is the English way.
     		-- Pink Floyd
     %
    -hangover, n:
    +Hangover, n.:
     	The wrath of grapes.
     %
     Hanlon's Razor:
    @@ -20718,14 +20723,14 @@ Happiness, n.:
     	another.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    -happiness, n:
    +Happiness, n.:
     	Finding the owner of a lost bikini.
     %
     Happy feast of the pig!
     %
     Happy is the child whose father died rich.
     %
    -hard, adj:
    +Hard, adj.:
     	The quality of your own data; also how it is to believe those
     	of other people.
     %
    @@ -20737,14 +20742,14 @@ Hard work may not kill you, but why take the chance?
     Hard work never killed anybody, but why take a chance?
     		-- Charlie McCarthy
     %
    -hardware, n:
    +Hardware, n.:
     	The parts of a computer system that can be kicked.
     %
     Hark, Hark, the dogs do bark
     The Duke is fond of kittens
     He likes to take their insides out
     And use them for his mittens
    -	From "The Thirteen Clocks"
    +		-- "The 13 Clocks"
     %
     Hark, the Herald Tribune sings,
     Advertising wondrous things.
    @@ -20829,7 +20834,7 @@ Hartley's First Law:
     	You can lead a horse to water, but if you can
     	get him to float on his back, you've got something.
     %
    -HARTLEY'S SECOND LAW:
    +Hartley's Second Law:
     	Never sleep with anyone crazier than yourself.
     
     My corollary:
    @@ -20967,7 +20972,7 @@ vigorous grass is a crack in your sidewalk?
     %
     Have you noticed the way people's intelligence capabilities decline
     sharply the minute they start waving guns around?
    -		-- Dr. Who
    +		-- The Doctor, "Doctor Who"
     %
     Have you reconsidered a computer career?
     %
    @@ -21073,6 +21078,7 @@ finer than the staple of his argument.
     		-- William Shakespeare, "Love's Labour's Lost"
     %
     He flung himself on his horse and rode madly off in all directions.
    +		-- Stephen Leacock
     %
     He gave her a look that you could have poured on a waffle.
     %
    @@ -21123,7 +21129,7 @@ He is the best of men who dislikes power.
     He is truly wise who gains wisdom from another's mishap.
     %
     He jests at scars who never felt a wound.
    -		-- Shakespeare, "Romeo and Juliet, II. 2"
    +		-- William Shakespeare, "Romeo and Juliet, II. 2"
     %
     He keeps differentiating, flying off on a tangent.
     %
    @@ -21162,7 +21168,7 @@ had fallen to the ground.
     	That my translation must be changed again.
     	The spirit helps me.  Now it is exact.
     	I write: "In the beginning was the Act."
    -		-- Goethe's Faust
    +		-- Johann Wolfgang von Goethe, "Faust"
     %
     [He] played the King as if afraid someone else might play the ace.
     		-- Unattributed review of a performance of King Lear
    @@ -21178,7 +21184,7 @@ He played the king as if afraid someone else would play the ace.
     %
     He tells you when you've got on too much lipstick,
     And helps you with your girdle when your hips stick.
    -		-- O. Nash, on the perfect husband
    +		-- Ogden Nash, on the perfect husband
     %
     He that breaks a thing to find out what it is has left the path of wisdom.
     		-- J. R. R. Tolkien
    @@ -21187,7 +21193,7 @@ He that bringeth a present, findeth the door open.
     		-- Scottish proverb
     %
     He that composes himself is wiser than he that composes a book.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     %
     He that is giddy thinks the world turns round.
     		-- William Shakespeare, "The Taming of the Shrew"
    @@ -21228,14 +21234,16 @@ told the others, "I'll be waiting for you in heaven -- with a gun."
     		-- Jack Handey
     %
     He was a fiddler, and consequently a rogue.
    -		-- Jonathon Swift
    +		-- Jonathan Swift
     %
     He was a modest, good-humored boy.  It was Oxford that made him
     insufferable.
     %
     He was part of my dream, of course --
     but then I was part of his dream too.
    -		-- Lewis Carroll
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     He was so narrow-minded he could see through a keyhole with both eyes.
     %
    @@ -21249,7 +21257,7 @@ broadcasting industry attacks democracy itself.
     		-- William S. Paley, chairman of CBS
     %
     He who dares the wrong, acts right, that's how it happens!
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     He who despairs over an event is a coward, but he who holds hopes for
     the human condition is a fool.
    @@ -21259,7 +21267,7 @@ He who despises himself nevertheless esteems himself as a self-despiser.
     		-- Friedrich Nietzsche
     %
     He who enters his wife's dressing room is a philosopher or a fool.
    -		-- Balzac
    +		-- Honore de Balzac
     %
     He who fears the unknown may one day flee from his own backside.
     		-- Sinbad
    @@ -21357,10 +21365,10 @@ be the greatest benefactor the world has yet known.
     		-- Sir Richard Burton
     %
     He who slings mud generally loses ground.
    -		-- Adlai Stevenson
    +		-- Adlai E. Stevenson
     %
     He who slings mud loses ground.
    -		-- Chinese Proverb
    +		-- Chinese proverb
     %
     He who spends a storm beneath a tree, takes life with a grain of TNT.
     %
    @@ -21441,7 +21449,7 @@ Heaven, n.:
     Heavier than air flying machines are impossible.
     		-- Lord Kelvin, President, Royal Society, c. 1895
     %
    -heavy, adj:
    +Heavy, adj.:
     	Seduced by the chocolate side of the force.
     %
     Hedonist for hire... no job too easy!
    @@ -21463,7 +21471,7 @@ how are they supposed to know you care?
     Hell is empty and all the devils are here.
     		-- William Shakespeare, "The Tempest"
     %
    -hell, n:
    +Hell, n.:
     	Truth seen too late.
     %
     Heller's Law:
    @@ -21505,7 +21513,7 @@ Help a swallow land at Capistrano.
     %
     Help fight continental drift.
     %
    -HELP!!!! I'm being held prisoner in /usr/share/games/fortune/!
    +HELP!!!! I'm being held prisoner in /usr/share/games/fortune!
     %
     Help me, I'm a prisoner in a Fortune cookie file!
     %
    @@ -21631,7 +21639,7 @@ Here there by tygers.
     HERE'S A GOOD JOKE to do during an earthquake.  Straddle a big crack in
     the earth and if it opens wider, go, "Whoa! Whoa!" and flap your arms
     around as if you're going to fall.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     Here's something to think about:  How come you never see a headline like
     `Psychic Wins Lottery.'
    @@ -21752,7 +21760,7 @@ Call (511) 338-0959 for an immediate appointment.
     %
     Hier liegt ein Mann ganz ohnegleich;
     Im Leibe dick, an Suenden reich.
    -Wir haben ihn in das Grab gesteckt,	Here lies a man with sundry flaws
    +Wir haben ihn ins Grab gesteckt,	Here lies a man with sundry flaws
     Weil es uns duenkt er sei verreckt.	And numerous Sins upon his head;
     					We buried him today because
     					As far as we can tell, he's dead.
    @@ -21763,12 +21771,9 @@ Weil es uns duenkt er sei verreckt.	And numerous Sins upon his head;
     %
     Higgeldy Piggeldy,
     Hamlet of Elsinore
    -Ruffled the critics by
    -Dropping this bomb:
    -"Phooey on Freud and his
    -Psychoanalysis,
    -Oedipus, Shmoedipus,
    -I just loved Mom."
    +Ruffled the critics by dropping this bomb:
    +"Phooey on Freud and his Psychoanalysis --
    +Oedipus, Shmoedipus, I just loved Mom."
     %
     Higgins:	Doolittle, you're either an honest man or a rogue.
     Doolittle:	A little of both, Guv'nor.  Like the rest of us, a
    @@ -21937,7 +21942,7 @@ Hitchcock's Staple Principle:
     Hitler used methods against white men in Europe, which by tacit
     agreement between the cultural European nations were only to be
     used against the coloured.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     Hlade's Law:
     	If you have a difficult task, give it to a lazy person --
    @@ -21997,7 +22002,7 @@ HOGAN'S HEROES DRINKING GAME --
     	plan is impossible.
     -- The prisoners capture an important German, and sneak him out the tunnel.
     %
    -Hollerith, v:
    +Hollerith, v.:
     	What thou doest when thy phone is on the fritzeth.
     %
     Hollywood is where if you don't have happiness you send out for it.
    @@ -22041,7 +22046,7 @@ Honesty pays, but it doesn't seem to pay enough to suit some people.
     Honesty's the best policy.
     		-- Miguel de Cervantes
     %
    -honeymoon, n:
    +Honeymoon, n.:
     	A short period of doting between dating and debting.
     		-- Ray C. Bandy
     %
    @@ -22085,7 +22090,7 @@ Hors d'oeuvres -- a ham sandwich cut into forty pieces.
     		-- Jack Benny
     %
     Horse sense is the thing a horse has which keeps it from betting on people.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     HOST SYSTEM NOT RESPONDING, PROBABLY DOWN. DO YOU WANT TO WAIT? (Y/N)
     %
    @@ -22113,7 +22118,7 @@ How apt the poor are to be proud.
     How can you be in two places at once
     when you're not anywhere at all?
     %
    -How can you do 'New Math' problems with an 'Old Math' mind?
    +How can you do "New Math" problems with an "Old Math" mind?
     		-- Schulz
     %
     How can you govern a nation which has 246 kinds of cheese?
    @@ -22194,7 +22199,7 @@ How cheerfully he seems to grin,
     	How neatly spreads his claws,
     And welcomes little fishes in,
     	With gently smiling jaws!
    -		-- Lewis Carroll, "Alice in Wonderland"
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     How doth the VAX's C-compiler
     	Improve its object code.
    @@ -22204,7 +22209,7 @@ And even as we speak does it
     How patiently it seems to run
     	And spit out error flags,
     While users, with frustration, all
    -	Tear their clothes to rags.
    +	Tear all their clothes to rags.
     %
     How is the world ruled, and how do wars start?  Diplomats tell lies to
     journalists, and they believe what they read.
    @@ -22277,7 +22282,6 @@ HOW YOU CAN TELL THAT IT'S GOING TO BE A ROTTEN DAY:
     	#15 Your pet rock snaps at you.
     %
     HOW YOU CAN TELL THAT IT'S GOING TO BE A ROTTEN DAY:
    -
     	#32: You call your answering service and they've never heard of
     	     you.
     %
    @@ -22443,7 +22447,7 @@ It is never any good to oneself.
     		-- Oscar Wilde, "An Ideal Husband"
     %
     I always say beauty is only sin deep.
    -		-- Saki, "Reginald's Choir Treat"
    +		-- H. H. Munro, a.k.a. Saki, "Reginald's Choir Treat"
     %
     I always turn to the sports pages first, which record people's
     accomplishments.  The front page has nothing but man's failures.
    @@ -22545,7 +22549,7 @@ I am more bored than you could ever possibly be.  Go back to work.
     I am NOMAD!
     %
     I am not a crook.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     I am not a politician and my other habits are also good.
     		-- A. Ward
    @@ -22560,7 +22564,7 @@ I am not now and never have been a girl friend of Henry Kissinger.
     		-- Gloria Steinem
     %
     I am not now, nor have I ever been, a member of the demigodic party.
    -		-- Dennis Ritchie
    +		-- Dennis M. Ritchie
     %
     I am not sure what this is, but an "F" would only dignify it.
     		-- English Professor
    @@ -22687,13 +22691,13 @@ I bet the human brain is a kludge.
     %
     I BET WHAT HAPPENED was they discovered fire and invented the wheel on
     the same day.  Then that night, they burned the wheel.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I BET WHEN NEANDERTHAL KIDS would make a snowman, someone would always
     end up saying, "Don't forget the thick heavy brows."  Then they would get
     embarrassed because they remembered they had the big hunky brows too, and
     they'd get mad and eat the snowman.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I bet you have fun chasing the soap around the bathtub.
     		-- Princess Diana, to a one-armed war veteran during
    @@ -22729,7 +22733,7 @@ I came, I saw, I deleted all your files.
     %
     I came out of twelve years of college and I didn't even know how to sew.
     All I could do was account -- I couldn't even account for myself.
    -		-- Firesign Theatre
    +		-- The Firesign Theatre
     %
     I came to MIT to get an education for myself and a diploma for my mother.
     %
    @@ -22963,7 +22967,7 @@ comes nearest to it of any.
     %
     I do not know whether I was then a man dreaming I was a
     butterfly, or whether I am now a butterfly dreaming I am a man.
    -		-- Chuang-tzu
    +		-- Chuang Tzu
     %
     I do not remember ever having seen a sustained argument by an author which,
     starting from philosophical premises likely to meet with general acceptance,
    @@ -23103,13 +23107,13 @@ he starts to practice law.
     %
     I DON'T THINK I'M ALONE when I say I'd like to see more and more planets
     fall under the ruthless domination of our solar system.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     "I don't think so," said Ren'e Descartes.  Just then, he vanished.
     %
     I don't think they are going to give a shit about the Republican
     Committee trying to bug the Democratic Committee's headquarters.
    -		-- Richard Nixon, 1972
    +		-- Richard M. Nixon, 1972
     %
     "I don't understand," said the scientist, "why you lemmings all rush down
     to the sea and drown yourselves."
    @@ -23142,7 +23146,7 @@ thinking about eliminating a federal program under which scientists
     broadcast signals to alien beings.  This would be a large mistake.
     Alien beings have nuclear blaster death cannons.  You cannot cut off
     their federal programs as if they were merely poor people ...
    -		-- Davy Barry, "THE ALIENS ARE COMING, THE ALIENS ARE
    +		-- Dave Barry, "THE ALIENS ARE COMING, THE ALIENS ARE
     		   COMING!"
     %
     I don't want to bore you, but there's nobody else around for me to bore.
    @@ -23182,7 +23186,7 @@ so I woke up from sheer boredom.
     %
     I figure that if God actually does exist, He's big enough to understand an
     honest difference of opinion.
    -		- Isaac Asimov
    +		-- Isaac Asimov
     %
     I finally went to the eye doctor.  I got contacts.
     I only need them to read, so I got flip-ups.
    @@ -23199,7 +23203,7 @@ I found Rome a city of bricks and left it a city of marble.
     %
     I gained nothing at all from Supreme Enlightenment, and for that very
     reason it is called Supreme Enlightenment.
    -		-- Gotama Buddha
    +		-- Gautama Buddha
     %
     I gave my love an Apple, that had no core;
     I gave my love a building, that had no floor;
    @@ -23277,12 +23281,12 @@ human emotions which is freaking out.  Another emotion is greed, as when
     you kill someone for money or something like that.  Another emotion is
     generosity, as when you pay someone double what he paid for his stupid
     puppet.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I GUESS I'LL NEVER FORGET HER.  And maybe I don't want to.  Her spirit
     was wild, like a wild monkey.  Her beauty was like a beautiful horse
     being ridden by a wild monkey.  I forget her other qualities.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I guess I've been so wrapped up in playing the game that I never took
     time enough to figure out where the goal line was -- what it meant to
    @@ -23296,14 +23300,14 @@ other people...  Certainty is just an emotion.
     I GUESS OF ALL MY UNCLES, I liked Uncle Caveman the best. We called him
     Uncle Caveman because he lived in a cave and because sometimes he'd eat
     one of us.  Later, we found out he was a bear.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I guess the Little League is even littler than we thought.
     		-- D. Cavett
     %
     I GUESS WE WERE ALL GUILTY, in a way.  We shot him, we skinned him, and
     we all got a complimentary bumper sticker that said, "I helped skin Bob."
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I had a dream last night...
     I dreamt about 1976.
    @@ -23423,7 +23427,7 @@ The funniest thing about him is the way he likes to grow--
     Not at all like proper children, which is always very slow;
     For he sometimes shoots up taller, like an india-rubber ball,
     And he sometimes gets so little that there's none of him at all.
    -		-- Robert L. Stevenson
    +		-- Robert Louis Stevenson
     %
     I have a map of the United States.  It's actual size.
     I spent last summer folding it.
    @@ -23481,9 +23485,9 @@ I tell them the truth and they never believe me.
     I have found it impossible to carry the heavy burden of responsibility and
     to discharge my duties as king as I would wish to do without the help and
     support of the woman I love.
    -		-- Edward, Duke of Windsor, 1936, announcing his abdication
    +		-- Edward, Duke of Windsor, announcing his abdication
     		   of the British throne in order to marry the American
    -		   divorcee Wallis Warfield Simpson.
    +		   divorcee Wallis Warfield Simpson. (1936)
     %
     I have found little that is good about human beings.  In my experience
     most of them are trash.
    @@ -23622,7 +23626,7 @@ declare the construction of such machinery impracticable...
     	And at a period when the progress of physical science is obstructed
     by that exhausting intellectual and manual labor, indispensable for its
     advancement, which it is the object of the Analytical Engine to relieve, I
    -think the application of machinery in aid of the most complicated and abtruse
    +think the application of machinery in aid of the most complicated and abstruse
     calculations can no longer be deemed unworthy of the attention of the country.
     In fact, there is no reason why mental as well as bodily labor should not
     be economized by the aid of machinery.
    @@ -23927,7 +23931,7 @@ I will not Reason and Compare; my business is to Create.
     		-- William Blake, "Jerusalem"
     %
     I must get out of these wet clothes and into a dry Martini.
    -		-- Alexander Woolcott
    +		-- Alexander Woollcott
     %
     I must have a prodigious quantity of mind; it takes me as much as a
     week sometimes to make it up.
    @@ -24010,7 +24014,7 @@ I've never seen a purple cow
     I never hope to see one
     But from the milk we're getting now
     There certainly must be one
    -		-- Odgen Nash
    +		-- Ogden Nash
     
     Ah, yes, I wrote "The Purple Cow"
     I'm sorry now I wrote it
    @@ -24021,7 +24025,7 @@ I'll kill you if you quote it.
     I never take work home with me; I always leave it in some bar along the way.
     %
     I never vote for anyone.  I always vote against.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     I often quote myself; it adds spice to my conversation.
     		-- George Bernard Shaw
    @@ -24150,7 +24154,7 @@ But only what I tell it.
     I really look with commiseration over the great body of my fellow citizens
     who, reading newspapers, live and die in the belief that they have known
     something of what has been passing in their time.
    -		-- Harry S. Truman
    +		-- Thomas Jefferson
     %
     I recognize terror as the finest emotion and so I will try to terrorize the
     reader.  But if I find that I cannot terrify, I will try to horrify, and if
    @@ -24167,7 +24171,7 @@ I remember once being on a station platform in Cleveland at four in the
     morning.  A black porter was carrying my bags, and as we were waiting for
     the train to come in, he said to me: "Excuse me, Mr. Cooke, I don't want to
     invade your privacy, but I have a bet with a friend of mine.  Who composed
    -the opening theme music of 'Omnibus'?  My friend said Virgil Thomson."  I
    +the opening theme music of `Omnibus'?  My friend said Virgil Thomson."  I
     asked him, "What do you say?" He replied, "I say Aaron Copeland." I said,
     "You're right."  The porter said, "I knew Thomson doesn't write counterpoint
     that way."  I told that to a network president, and he was deeply unimpressed.
    @@ -24233,7 +24237,7 @@ There's a bad moon on the rise.
     %
     I see a good deal of talk from Washington about lowering taxes.  I hope
     they do get 'em lowered down enough so people can afford to pay 'em.
    -		-- The Best of Will Rogers
    +		-- Will Rogers
     %
     I see the eigenvalue in thine eye,
     I hear the tender tensor in thy sigh.
    @@ -24262,6 +24266,9 @@ I said to him, and I said it plain	And when I found the door was shut,
     
     	"Is that all?" asked Alice.
     	"That is all." said Humpty Dumpty. "Goodbye."
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     I sent a message to another time,
     But as the days unwind -- this I just can't believe,
    @@ -24324,7 +24331,7 @@ Easy.  I own Chicago.  I own Miami.  I own Las Vegas.
     		-- Sam Giancana, when asked what he did for a living
     %
     I stick my neck out for nobody.
    -		-- Humphrey Bogart, "Casablanca"
    +		-- Humphrey Bogart, "Casablanca" (1942)
     %
     I stood on the leading edge,
     The eastern seaboard at my feet.
    @@ -24338,8 +24345,8 @@ I stopped believing in Santa Claus when I was six.  Mother took me to
     see him in a department store and he asked for my autograph.
     		-- Shirley Temple
     %
    -I suggest a new strategy, Artoo: let the Wookiee win.
    -		-- CP30
    +I suggest a new strategy, R2: let the Wookiee win.
    +		-- C-3PO
     %
     I suggest you locate your hot tub outside your house, so it won't do
     too much damage if it catches fire or explodes.  First you decide which
    @@ -24436,14 +24443,14 @@ I tell ya, I was afraid to go to the bathroom.
     		-- Rodney Dangerfield
     %
     I think...  I think it's in my basement... Let me go upstairs and check.
    -		-- Escher
    +		-- M. C. Escher
     %
     I think a relationship is like a shark.  It has to constantly move forward
     or it dies.  Well, what we have on our hands here is a dead shark.
     		-- Woody Allen
     %
     I think I'll snatch a kiss and flee.
    -		-- Shakespeare
    +		-- William Shakespeare
     %
     I think I'm schizophrenic.  One half of me's
     paranoid and the other half's out to get him.
    @@ -24453,13 +24460,13 @@ because I couldn't remember the proof.
     		-- Baker, Pure Math 351a
     %
     I THINK MAN INVENTED THE CAR by instinct.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I think sex is better than logic, but I can't prove it.
     %
     I think she must have been very strictly brought up, she's so
     desperately anxious to do the wrong thing correctly.
    -		-- Saki, "Reginald on Worries"
    +		-- H. H. Munro, a.k.a. Saki, "Reginald on Worries"
     %
     I think that all good, right thinking people in this country are sick
     and tired of being told that all good, right thinking people in this
    @@ -24490,7 +24497,7 @@ They went this morning with the dawn.
     A logging firm from out of town
     Came and chopped the trees all down.
     But I will trick those dirty skunks
    -And write a brand new poem called 'Trunks'.
    +And write a brand new poem called "Trunks."
     %
     I think the sky is blue because it's a shift from black through purple
     to blue, and it has to do with where the light is.  You know, the
    @@ -24518,16 +24525,16 @@ I THINK THERE SHOULD BE SOMETHING in science called the "reindeer effect."
     I don't know what it would be, but I think it'd be good to hear someone
     say, "Gentlemen, what we have here is a terrifying example of the reindeer
     effect."
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I think, therefore I am... I think.
     %
     I think there's a world market for about five computers.
    -		-- attr. Thomas J. Watson (Chairman of the Board, IBM), 1943
    +		-- attr. Thomas J. Watson, Chairman of the Board, IBM (1943)
     %
     I THINK THEY SHOULD CONTINUE the policy of not giving a Nobel Prize for
     paneling.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I think we are in Rats Alley where the dead men lost their bones.
     		-- T. S. Eliot
    @@ -24544,14 +24551,14 @@ conversation ...
     		-- Dave Barry, "The Stuff of Etiquette"
     %
     I think we're all Bozos on this bus.
    -		-- Firesign Theatre
    +		-- The Firesign Theatre
     %
     I think we're in trouble.
     		-- Han Solo
     %
     I think your opinions are reasonable,
     except for the one about my mental instability.
    -		-- Psychology Professor, Farifield University
    +		-- Psychology Professor, Fairfield University
     %
     "I thought that you said you were 20 years old!"
     "As a programmer, yes," she replied,
    @@ -24578,7 +24585,8 @@ And would not have had fun with the game.
     %
     I thought there was something fishy about the butler.  Probably a Pisces,
     working for scale.
    -		-- Firesign Theatre, "The Further Adventures of Nick Danger"
    +		-- The Firesign Theatre,
    +		   "The Further Adventures of Nick Danger"
     %
     I thought YOU silenced the guard!
     %
    @@ -24967,7 +24975,7 @@ we could all take a shot at him and not feel too bad.
     %
     I WISH I HAD A KRYPTONITE CROSS, because then you could keep both Dracula
     and Superman away.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I wish there was a knob on the TV where you could turn up the
     intelligence.  They've got one called brightness, but it doesn't
    @@ -24998,7 +25006,7 @@ I don't know yet and all kinds of adventures and battles."
     		-- Bastian B. Bux
     %
     I wonder what the leash and collar set does for excitement?
    -		-- Tramp, Lady and the Tramp
    +		-- Tramp, "Lady and the Tramp"
     %
     I worked in a health food store once.  A guy came in and asked me,
     "If I melt dry ice, can I take a bath without getting wet?"
    @@ -25015,7 +25023,7 @@ only they won't let me raise my voice.
     		-- Winkle
     %
     I would have made a good pope.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     I would have promised those terrorists a trip to Disneyland if it would have
     gotten the hostages released.  I thank God they were satisfied with the
    @@ -25036,7 +25044,7 @@ understanding, in mutuality of interest, in concern for the common good,
     our tasks will be solved.
     		-- Warren G. Harding
     %
    -I would like to electrocute everyone who uses the word 'fair' in connection
    +I would like to electrocute everyone who uses the word "fair" in connection
     with income tax policies.
     		-- William F. Buckley
     %
    @@ -25047,18 +25055,18 @@ And what I was fencing out.
     %
     I would much rather have men ask why
     I have no statue, than why I have one.
    -		-- Marcus Procius Cato
    +		-- Marcus Porcius Cato
     %
     I would not like to be a political leader in Russia.  They never know when
     they're being taped.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     
     I love America.  You always hurt the one you love.
     		-- David Frye impersonating Nixon
     %
     I would rather be a serf in a poor man's house
     and be above ground than reign among the dead.
    -		-- Achilles, "The Odessey", XI, 489-91
    +		-- Achilles, "The Odyssey", XI, 489-91
     %
     I would rather say that a desire to drive fast
     sports cars is what sets man apart from the animals.
    @@ -25112,7 +25120,7 @@ IBM:
     %
     IBM Advanced Systems Group -- a bunch of mindless jerks,
     who'll be first against the wall when the revolution comes...
    -		-- with regrets to D. Adams
    +		-- with regrets to Douglas Adams
     %
     IBM had a PL/I,
     Its syntax worse than JOSS;
    @@ -25143,7 +25151,7 @@ I'd just as soon kiss a Wookiee.
     I'D LIKE TO BE BURIED INDIAN-STYLE, where they put you up on a high rack,
     above the ground.  That way, you could get hit by meteorites and not even
     feel it.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     I'd like to meet the guy who invented beer and see what he's working on now.
     %
    @@ -25179,7 +25187,7 @@ Yes life is fine when things combine,
     	Like ham in beef chow mein...
     But lord, this time I think I mind,
     	They've put acid in my rain.
    -		--- Milo Bloom
    +		-- Milo Bloom
     %
     I'd never join any club that would have the likes of me as a member.
     		-- Groucho Marx
    @@ -25198,7 +25206,7 @@ I'd rather have a free bottle in front of me than a prefrontal lobotomy.
     [Also attributed to S. Clay Wilson.  Ed.]
     %
     I'd rather have two girls at 21 each than one girl at 42.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     I'd rather just believe that it's done by little elves running around.
     %
    @@ -25276,7 +25284,7 @@ is certain to vote acquittal, save in those instances where it votes guilty.
     IF A KID ASKS YOU where rain comes from, I think a cute thing to tell him
     is, "God is crying."  And if he asks why God is crying, another cute thing
     to tell him is, "Probably because of something you did."
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     If a listener nods his head when you're
     explaining your program, wake him up.
    @@ -25360,7 +25368,7 @@ If a thing's worth doing, it is worth doing badly.
     		-- G. K. Chesterton
     %
     If a thing's worth having, it's worth cheating for.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     If a train station is a place where a train stops, what's a workstation?
     %
    @@ -25451,7 +25459,7 @@ If at first you don't succeed, try, try again.
     %
     If at first you don't succeed, try, try again.
     Then quit. No use being a damn fool about it.
    -		-- W.C. Fields
    +		-- W. C. Fields
     
     [Also attributed to Roy Mengot.  Ed.]
     %
    @@ -25511,7 +25519,7 @@ no middleman.
     %
     If every kid had a funny tooth to bite down on whenever the world disappointed
     him, prussic acid could solve our population problems in one generation.
    -		-- G.C. Edmonson's Albert, "The Man Who Corrupted Earth"
    +		-- G. C. Edmonson's Albert, "The Man Who Corrupted Earth"
     %
     If everybody minded their own business, the world would go
     around a deal faster.
    @@ -25681,7 +25689,7 @@ If *I* had a hammer, there'd be no more folk singers.
     %
     IF I HAD A MINE SHAFT, I don't think I would just abandon it.  There's
     got to be a better way.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     If I had a plantation in Georgia and a home in Hell,
     I'd sell the plantation and go home.
    @@ -25754,7 +25762,7 @@ I would send a barrel or so to my other generals.
     		-- Abraham Lincoln, on General Grant
     %
     If I love you, what business is it of yours?
    -		-- Johann van Goethe
    +		-- Johann Wolfgang von Goethe
     %
     If I made peace with Russia today, I'd only attack her again tomorrow.  I
     just couldn't help myself.
    @@ -25932,7 +25940,7 @@ be a merrier world.
     If once a man indulges himself in murder, very soon he comes to think little
     of robbing; and from robbing he next comes to drinking and Sabbath-breaking,
     and from that to incivility and procrastination.
    -		-- Thomas De Quincey (1785 - 1859)
    +		-- Thomas De Quincey (1785-1859)
     %
     If one cannot enjoy reading a book over and
     over again, there is no use in reading it at all.
    @@ -25949,7 +25957,7 @@ get an unfair advantage.
     		-- John Dewey, "Democracy in the Schools", 1908
     %
     If one studies too zealously, one easily loses his pants.
    -		-- A. Einstein
    +		-- Albert Einstein
     %
     If one tells the truth, one is sure, sooner or later, to be found out.
     		-- Oscar Wilde,
    @@ -26064,7 +26072,7 @@ Their romance might have flourished.
     But he built tetrahedral in his shape,
     His ions ferric,
     Love could not help but die,
    -Uncatylised, inert, and undernourished.
    +Uncatalyzed, inert, and undernourished.
     %
     If society fits you comfortably enough, you call it freedom.
     		-- Robert Frost
    @@ -26213,7 +26221,7 @@ of this life.
     		-- Albert Camus
     %
     If there is a wrong way to do something, then someone will do it.
    -		-- Edward A. Murphy Jr.
    +		-- Edward A. Murphy, Jr.
     %
     If there is any realistic deterrent to marriage, it's the fact that you
     can't afford divorce.
    @@ -26283,7 +26291,7 @@ If two people love each other, there can be no happy end to it.
     		-- Ernest Hemingway
     %
     If two wrongs don't make a right, try three.
    -		-- Laurence J. Peter
    +		-- Dr. Laurence J. Peter
     %
     If value corrupts then absolute value corrupts absolutely.
     %
    @@ -26349,7 +26357,7 @@ If women are supposed to be less rational and more emotional at the
     beginning of our menstrual cycle, when the female hormone is at its
     lowest level, then why isn't it logical to say that in those few days
     women behave the most like the way men behave all month long?
    -		-- Gloria Steinham
    +		-- Gloria Steinem
     %
     If women didn't exist, all the money in the world would have no meaning.
     		-- Aristotle Onassis
    @@ -26522,12 +26530,12 @@ If you ever want to get anywhere in politics, my boy, you're going to
     have to get a toehold in the public eye.
     %
     If you ever want to have a lot of fun, I recommend that you go off and program
    -an imbedded system.  The salient characteristic of an imbedded system is that
    +an embedded system.  The salient characteristic of an embedded system is that
     it cannot be allowed to get into a state from which only direct intervention
    -will suffice to remove it.  An imbedded system can't permanently trust anything
    +will suffice to remove it.  An embedded system can't permanently trust anything
     it hears from the outside world.  It must sniff around, adapt, consider, sniff
     around, and adapt again.  I'm not talking about ordinary modular programming
    -carefulness here.  No.  Programming an imbedded system calls for undiluted
    +carefulness here.  No.  Programming an embedded system calls for undiluted
     raging maniacal paranoia.  For example, our ethernet front ends need to know
     what network number they are on so that they can address and route PUPs
     properly.  How do you find out what your network number is?  Easy, you ask a
    @@ -26746,13 +26754,13 @@ ice, but no cup.
     %
     If you put garbage in a computer nothing comes out but garbage.  But
     this garbage, having passed through a very expensive machine, is
    -somehow enobled and none dare criticize it.
    +somehow ennobled and none dare criticize it.
     %
     If you put it off long enough, it might go away.
     %
     If you put tomfoolery into a computer, nothing comes out but tomfoolery.
     But this tomfoolery, having passed through a very expensive machine,
    -is somehow enobled and no-one dare criticise it.
    +is somehow ennobled and no-one dare criticise it.
     		-- Pierre Gallois
     %
     If you put your supper dish to your ear you can hear the sounds of a
    @@ -26799,8 +26807,8 @@ they taste more like prunes than rhubarb does.
     %
     If you stick a stock of liquor in your locker,
     It is slick to stick a lock upon your stock.
    -Or some joker who is slicker,
    -Will trick you of your liquor,
    +	Or some joker who is slicker,
    +	Will trick you of your liquor,
     If you fail to lock your liquor with a lock.
     %
     If you stick your head in the sand,
    @@ -26883,7 +26891,7 @@ If you treat people right they will treat you right -- 90% of the time.
     If you try to please everyone, somebody is not going to like it.
     %
     If you understand what you're doing, you're not learning anything.
    -		-- A. L.
    +		-- Abraham Lincoln
     %
     If you wait long enough, it will go away... after having
     done its damage.  If it was bad, it will be back.
    @@ -26945,7 +26953,7 @@ If you wish to be happy for one hour, get drunk.
     If you wish to be happy for three days, get married.
     If you wish to be happy for a month, kill your pig and eat it.
     If you wish to be happy forever, learn to fish.
    -		-- Chinese Proverb
    +		-- Chinese proverb
     %
     If you wish to live wisely, ignore sayings -- including this one.
     %
    @@ -26970,7 +26978,7 @@ If you do that, you are loosening the tendrils that are holding you to the
     If you would keep a secret from an enemy, tell it not to a friend.
     %
     If you would know the value of money, go try to borrow some.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     %
     If you would understand your own age, read the works
     of fiction produced in it.  People in disguise speak freely.
    @@ -26985,7 +26993,7 @@ If your bread is stale, make toast.
     %
     If your enemy is buried in quicksand up to his neck, pull him out.
     If he is buried up to his eyes, step on his head.
    -		-- Niccoli Machiavelli, "The Prince"
    +		-- Niccolo Machiavelli, "The Prince"
     %
     If your happiness depends on what somebody else does,
     I guess you do have a problem.
    @@ -27086,7 +27094,9 @@ Il brilgue: les t^oves libricilleux
     	Se gyrent et frillant dans le guave,
     Enm^im'es sont les gougebosquex,
     	Et le m^omerade horgrave.
    -		-- Lewis Carroll, "Through the Looking Glass"
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     Iles's Law:
     	There is always an easier way to do it.  When looking directly
    @@ -27173,12 +27183,12 @@ that I could have evolved from man.
     		-- "Friday's Child", when asked to help the very pregnant
     		   Ellen up a steep incline.
     "I'm a doctor, not a bricklayer."
    -		-- Devil in the Dark", when asked to patch up the Horta
    +		-- "Devil in the Dark", when asked to patch up the Horta.
     "I'm a doctor, not an engineer."
     		-- "Mirror, Mirror", when asked by Scotty for help in
    -		   Engineering aboard the ISS Enterprise.
    +		   Engineering aboard the USS Enterprise.
     "I'm a doctor, not a coal miner."
    -		-- "The Empath", on being beneath the surface of Minara 2
    +		-- "The Empath", on being beneath the surface of Minara 2.
     "I'm a surgeon, not a psychiatrist."
     		-- "City on the Edge of Forever", on Edith Keeler's remark
     		   that Kirk talked strangely.
    @@ -27195,7 +27205,7 @@ a sports jacket and take off my brain.
     I'm a Lisp variable -- bind me!
     %
     I'm a lucky guy, and I'm happy to be with the Yankees.  And I want to
    - thank everyone for making this night necessary.
    +thank everyone for making this night necessary.
     		-- Yogi Berra at a dinner in his honor
     %
     I'm all for computer dating, but I
    @@ -27314,7 +27324,7 @@ Please say that you're not mad at me
     %
     I'm living so far beyond my income that we may almost be said to be
     living apart.
    -		-- E.E. Cummings
    +		-- e. e. cummings
     %
     I'm N-ary the tree, I am,
     N-ary the tree, I am, I am.
    @@ -27328,7 +27338,7 @@ N-ary the tree I am.
     		-- Stolen from Paul Revere and the Raiders
     %
     I'm not a lovable man.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     I'm not a real movie star -- I've still got the same wife I started out
     with twenty-eight years ago.
    @@ -27424,7 +27434,7 @@ I'm willing to sacrifice anything for this cause, even other people's
     lives.
     %
     Imagination is more important than knowledge.
    -		-- A. Einstein
    +		-- Albert Einstein
     %
     Imagination is the one weapon in the war against reality.
     		-- Jules de Gaultier
    @@ -27493,8 +27503,9 @@ Boss is reading it.
     %
     Impossible, adj.:
     	(1) I wouldn't like it and when it happens I won't approve;
    -(2) I can't be bothered; (3) God can't be bothered.  Meaning (3) may
    -perhaps be valid but the others are 101% whaledreck.
    +	(2) I can't be bothered;
    +	(3) God can't be bothered.
    +Meaning (3) may perhaps be valid but the others are 101% whaledreck.
     		-- Chad C. Mulligan, "The Hipcrime Vocab"
     %
     In 1869 the waffle iron was invented for people who had wrinkled
    @@ -27583,7 +27594,7 @@ this a form of primitive self-expression.  In America we call it golf.
     %
     In America, any boy may become president and I suppose that's just one
     of the risks he takes.
    -		-- Adlai Stevenson
    +		-- Adlai E. Stevenson
     %
     In America today ... we have Woody Allen, whose humor has become so
     sophisticated that nobody gets it any more except Mia Farrow.  All
    @@ -27772,7 +27783,7 @@ which will melt a brass door-knob and weather which will only make it mushy.
     		-- Mark Twain
     %
     In Italy, for thirty years under the Borgias, they had warfare, terror,
    -murder, and bloodshed, but they produced Michaelangelo, Leonardo da Vinci
    +murder, and bloodshed, but they produced Michelangelo, Leonardo da Vinci
     and the Renaissance.  In Switzerland, they had brotherly love, they had
     five hundred years of democracy and peace -- and what did they produce?
     The cuckoo-clock.
    @@ -27829,7 +27840,7 @@ your left leg, it's modern architecture.
     %
     IN MY OPINION anyone interested in improving himself should not rule out
     becoming pure energy.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     In Nature there are neither rewards nor
     punishments, there are consequences.
    @@ -27910,8 +27921,8 @@ We shall encounter, counting, face to face.
     In San Francisco, Halloween is redundant.
     		-- Will Durst
     %
    -In science it often happens that scientists say, 'You know that's a really
    -good argument; my position is mistaken,' and then they actually change
    +In science it often happens that scientists say, "You know that's a really
    +good argument; my position is mistaken," and then they actually change
     their minds and you never hear that old view from them again.  They really
     do it.  It doesn't happen as often as it should, because scientists are
     human and change is sometimes painful.  But it happens every day.  I cannot
    @@ -27945,7 +27956,7 @@ And that, I think, was the handle -- the sense of inevitable victory
     over the forces of Old and Evil.  Not in any mean or military sense; we
     didn't need that.  Our energy would simply `prevail'.  There was no
     point in fighting -- on our side or theirs.  We had all the momentum;
    -we were riding the crest of a high and beautiful wave ....
    +we were riding the crest of a high and beautiful wave ...
     
     So now, less than five years later, you can go up on a steep hill in
     Las Vegas and look West, and with the right kind of eyes you can almost
    @@ -27962,7 +27973,7 @@ And still there was nothing, but at least now you could see it.
     %
     In the beginning was the word.
     But by the time the second word was added to it,
    -There was trouble.
    +there was trouble.
     For with it came syntax ...
     		-- John Simon
     %
    @@ -28038,7 +28049,7 @@ Sun is driven by the Grateful Dead.
     		-- Egyptian Book of the Dead
     %
     In the long run, every program becomes rococo, and then rubble.
    -		-- Alan Perlis
    +		-- Alan J. Perlis
     %
     In the long run we are all dead.
     		-- John Maynard Keynes
    @@ -28152,7 +28163,7 @@ my advice.
     %
     In time, every post tends to be occupied by an
     employee who is incompetent to carry out its duties.
    -		-- Dr. L. J. Peter
    +		-- Dr. Laurence J. Peter
     %
     In Tulsa, Oklahoma, it is against the law to open a soda bottle without
     the supervision of a licensed engineer.
    @@ -28191,7 +28202,7 @@ And there were gardens bright with sinuous rills,
     Where blossomed many an incense-bearing tree;
     And here were forest ancient as the hills,
     Enfolding sunny spots of greenery.
    -		-- S. T. Coleridge, "Kubla Kahn"
    +		-- Samuel T. Coleridge, "Kubla Kahn"
     %
     In youth, it was a way I had
     To do my best to please,
    @@ -28315,7 +28326,7 @@ Inglish Spocken Hier: some mangled translations
     
     		-- Colin Bowles, San Francisco Chronicle
     %
    -ingrate, n:
    +Ingrate, n.:
     	A man who bites the hand that feeds him,
     	and then complains of indigestion.
     %
    @@ -28405,7 +28416,7 @@ and 8 percent said "Gimme a quarter?"
     %
     Interfere?  Of course we should interfere!  Always do what you're
     best at, that's what I say.
    -		-- Doctor Who
    +		-- "Doctor Who"
     %
     Interpreter, n.:
     	One who enables two persons of different languages to understand
    @@ -28479,7 +28490,7 @@ Is knowledge knowable?  If not, how do we know that?
     Is not marriage an open question, when it is alleged, from the beginning
     of the world, that such as are in the institution wish to get out,
     and such as are out wish to get in?
    -		-- Ralph Emerson
    +		-- Ralph Waldo Emerson
     %
     Is sex dirty?  Only if it's done right.
     		-- Woody Allen, "All You Ever Wanted To Know About Sex"
    @@ -28500,7 +28511,7 @@ Breakfast in London, dinner in New York, luggage in Brazil.
     %
     Isn't it conceivable to you that an intelligent
     person could harbor two opposing ideas in his mind?
    -		-- Adlai Stevenson, to reporters
    +		-- Adlai E. Stevenson, to reporters
     %
     Isn't it interesting that the same people who laugh at science fiction
     listen to weather forecasts and economists?
    @@ -28701,7 +28712,7 @@ to argue with the belly, since it has no ears.
     %
     It is a lesson which all history teaches
     wise men, to put trust in ideas, and not in circumstances.
    -		-- Emerson
    +		-- Ralph Waldo Emerson
     %
     It is a poor judge who cannot award a prize.
     %
    @@ -28731,7 +28742,7 @@ but would also be three months late, and of much lower quality.  I did, and
     it was.  He was right on both counts.  Moreover, the lack of conceptual
     integrity made the system far more costly to build and change, and I would
     estimate that it added a year to debugging time.
    -		-- Frederick Brooks Jr., "The Mythical Man Month"
    +		-- Frederick Brooks, Jr., "The Mythical Man-Month"
     %
     It is a wise father that knows his own child.
     		-- William Shakespeare, "The Merchant of Venice"
    @@ -28739,7 +28750,7 @@ It is a wise father that knows his own child.
     It is against the grain of modern education to teach children to program.
     What fun is there in making plans, acquiring discipline in organizing
     thoughts, devoting attention to detail, and learning to be self-critical?
    -		-- Alan Perlis
    +		-- Alan J. Perlis
     %
     It is against the law for a monster to enter the corporate limits of
     Urbana, Illinois.
    @@ -28771,7 +28782,7 @@ Curiously enough, the dolphins had long known of the impending
     destruction of the of the planet Earth and had made many attempts to
     alert mankind to the danger; but most of their communications were
     misinterpreted ...
    -		-- Douglas Adams, "The Hitchhiker's Guide To The Galaxy"
    +		-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
     %
     It is annoying to be honest to no purpose.
     		-- Publius Ovidius Naso (Ovid)
    @@ -28829,7 +28840,7 @@ admit it frankly and try another.  But above all, try something.
     %
     It is contrary to reasoning to say that there
     is a vacuum or space in which there is absolutely nothing.
    -		-- Descartes
    +		-- Rene Descartes
     %
     It is convenient that there be gods, and,
     as it is convenient, let us believe there are.
    @@ -28914,7 +28925,7 @@ without your help.
     It is Fortune, not Wisdom, that rules man's life.
     %
     It is fruitless:
    -	to become lacrymose over precipitately departed lactate fluid.
    +	to become lachrymose over precipitately departed lactate fluid.
     
     	to attempt to indoctrinate a superannuated canine with
     		innovative maneuvers.
    @@ -29002,10 +29013,10 @@ It is not a good omen when goldfish commit suicide.
     %
     It is not doing the thing we like to do, but liking the thing we have to do,
     that makes life blessed.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     It is not enough that I should succeed.  Others must fail.
    -		-- Ray Kroc, Founder of McDonald's
    +		-- Ray Kroc, founder of McDonald's
     		   [Also attributed to David Merrick.  Ed.]
     
     It is not enough to succeed.  Others must fail.
    @@ -29034,8 +29045,8 @@ and he who makes haste with his feet misses his way.
     It is not necessary to inquire whether a woman would like something for
     dessert.  The answer is yes, she would like something for dessert, but
     she would like you to order it so she can pick at it with your fork.  She
    -does not want you to call attention to this by saying, 'If you wanted a
    -dessert, why didn't you order one?'  You must understand, she has the
    +does not want you to call attention to this by saying, "If you wanted a
    +dessert, why didn't you order one?"  You must understand, she has the
     dessert she wants.  The dessert she wants is contained within yours.
     		-- Merrill Marcoe, "An Insider's Guide to the American Woman"
     %
    @@ -29093,7 +29104,7 @@ to be obscene, they could never have dared to be great.
     %
     It is only with the heart one can see clearly;
     what is essential is invisible to the eye.
    -		-- The Fox, 'The Little Prince"
    +		-- The Fox, "The Little Prince"
     %
     It is perfectly permissible for every system call to fail with [ENOTADUCK]
     unless the first five bytes of the caller's address space contain the
    @@ -29238,7 +29249,7 @@ a hundred drumsticks, then the guy at Marineland says, "You can't throw
     that chicken to the dolphins. They eat fish."
     
     Sure they eat fish if that's all you give them!  Man, wise up.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     It [marriage] happens as with cages: the birds without despair
     to get in, and those within despair of getting out.
    @@ -29398,7 +29409,7 @@ when you're stickin' those artificial stimulants in your arm.
     %
     It was one of those perfect summer days -- the sun was shining, a breeze
     was blowing, the birds were singing, and the lawn mower was broken ...
    -		--- James Dent
    +		-- James Dent
     %
     It was one time too many
     One word too few
    @@ -29470,7 +29481,7 @@ the way some people are of everything.
     %
     It would save me a lot of time if you just gave up and went mad now.
     %
    -italic, adj:
    +Italic, adj.:
     	Slanted to the right to emphasize key phrases.  Unique to
     	Western alphabets; in Eastern languages, the same phrases
     	are often slanted to the left.
    @@ -29549,7 +29560,7 @@ but why do the rats always have to win?
     It's better to be quotable than to be honest.
     		-- Tom Stoppard
     %
    -It's better to be wanted for murder that not to be wanted at all.
    +It's better to be wanted for murder than not to be wanted at all.
     		-- Marty Winch
     %
     It's better to burn out than to fade away.
    @@ -29647,9 +29658,9 @@ our's either.  It's ours, and likewise yours and theirs.
     It's just a jump to the left
     	And then a step to the right.
     Put your hands on your hips
    -	And pull your knees in tight.
    -It's the pelvic thrust
    -	That really gets you insa-a-a-a-ane
    +	You bring your knees in tight.
    +But it's the pelvic thrust
    +	That really drives you insa-a-a-a-a-ane!
     
     	LET'S DO THE TIME WARP AGAIN!
     
    @@ -29779,7 +29790,7 @@ as a warning to others.
     %
     It's pretty hard to tell what does bring happiness;
     poverty and wealth have both failed.
    -		-- Kim Hubbard
    +		-- Kin Hubbard
     %
     It's raisins that make Post Raisin Bran so raisiny ...
     %
    @@ -29947,7 +29958,7 @@ bad taste.
     		-- Keith Richards
     %
     I've never struck a woman in my life, not even my own mother.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     I've noticed several design suggestions in your code.
     %
    @@ -29968,7 +29979,7 @@ And from that full meridian of my glory
     I haste now to my setting.  I shall fall,
     Like a bright exhalation in the evening
     And no man see me more.
    -		-- Shakespeare
    +		-- William Shakespeare
     %
     I've tried several varieties of sex.  The conventional position makes
     me claustrophobic, and the others either give me a stiff neck or lockjaw.
    @@ -29996,7 +30007,7 @@ all except			ones; the mean
     	  the dead ones		kind dirty clean)
     				all
     				   except the green ones
    -		-- e e cummings
    +		-- e. e. cummings
     %
     James Joyce -- an essentially private man who wished his total
     indifference to public notice to be universally recognized.
    @@ -30016,7 +30027,7 @@ television?" and "Good night".
     		-- Goodman Ace, letter to Groucho Marx, in The Groucho
     		   Letters, 1967
     %
    -Japan, n:
    +Japan, n.:
     	A fictional place where elves, gnomes and economic imperialists
     	create electronic equipment and computers using black magic.  It
     	is said that in the capital city of Akihabara, the streets are
    @@ -30055,7 +30066,7 @@ JOB INTERVIEW:
     	The excruciating process during which personnel officers
     	separate the wheat from the chaff -- then hire the chaff.
     %
    -job Placement, n:
    +Job Placement, n.:
     	Telling your boss what he can do with your job.
     %
     Joe Cool always spends the first two weeks at college sailing his Frisbee.
    @@ -30073,7 +30084,7 @@ whispered Joe. "I'm the one who poisoned you."
     %
     Joe's sister puts spaghetti in her shoes!
     %
    -jogger, n:
    +Jogger, n.:
     	An odd sort of person with a thing for pain.
     %
     John			Dame May		Oscar
    @@ -30216,7 +30227,7 @@ going to get hit.
     Just because the message may never be
     received does not mean it is not worth sending.
     %
    -Just because they are called 'forbidden' transitions does not mean that they
    +Just because they are called "forbidden" transitions does not mean that they
     are forbidden.  They are less allowed than allowed transitions, if you see
     what I mean.
     		-- From a Part 2 Quantum Mechanics lecture
    @@ -30230,7 +30241,7 @@ condition doesn't mean he knows what it is.
     Just because you're paranoid doesn't mean they AREN'T after you.
     %
     Just close your eyes, tap your heels together three times,
    -and think to yourself, `There's no place like home.'
    +and think to yourself, "There's no place like home."
     		-- Billie Burke as Glinda, "The Wizard of Oz"
     %
     Just give Alice some pencils and she will stay busy for hours.
    @@ -30253,7 +30264,7 @@ What a glorious time to be free.
     %
     Just once, I wish we would encounter
     an alien menace that wasn't immune to bullets.
    -		-- The Brigader, "Dr. Who"
    +		-- The Brigadier, "Doctor Who"
     %
     Just out of curiosity does this actually mean something or have some
     of the few remaining bits of your brain just evaporated?
    @@ -30309,7 +30320,7 @@ Justice always prevails ... three times out of seven!
     Justice is incidental to law and order.
     		-- J. Edgar Hoover
     %
    -Justice, n:
    +Justice, n.:
     	A decision in your favor.
     %
     K:	Cobalt's metal, hard and shining;
    @@ -30446,7 +30457,7 @@ Kennedy's Market Theorem:
     Kent's Heuristic:
     	Look for it first where you'd most like to find it.
     %
    -kern, v:
    +Kern, v.:
     	1. To pack type together as tightly as the kernels on an ear
     	of corn.  2. In parts of Brooklyn and Queens, N.Y., a small,
     	metal object used as part of the monetary system.
    @@ -30494,13 +30505,13 @@ Kime's Law for the Reward of Meekness:
     	Turning the other cheek merely ensures two bruised cheeks.
     %
     Kin, n.:
    -	An affliction of the blood
    +	An affliction of the blood.
     %
     Kindness is a language which the deaf can hear and the blind can read.
     		-- Mark Twain
     %
     Kindness is the beginning of cruelty.
    -		-- Muad'dib
    +		-- Muad'dib, "Dune"
     %
     Kington's Law of Perforation:
     	If a straight line of holes is made in a piece of paper, such
    @@ -30562,7 +30573,7 @@ Kliban's First Law of Dining:
     Klingon phaser attack from front!!!!!
     100% Damage to life support!!!!
     %
    -Kludge, n:
    +Kludge, n.:
     	An ill-assorted collection of poorly-matching parts, forming a
     	distressing whole.
     		-- Jackson Granholm, "Datamation"
    @@ -30772,11 +30783,11 @@ Lansdale seized on the idea of using Nixon to build support for the
     [Vietnamese] elections ... really honest elections, this time.  "Oh, sure,
     honest, yes, that's right," Nixon said, "so long as you win!"  With that
     he winked, drove his elbow into Lansdale's arm and slapped his own knee.
    -		-- Richard Nixon, quoted in "Sideshow" by W. Shawcross
    +		-- Richard M. Nixon, quoted in "Sideshow" by W. Shawcross
     %
     Large increases in cost with questionable increases in
     performance can be tolerated only in race horses and women.
    -		-- Lord Kalvin
    +		-- Lord Kelvin
     %
     Largest Number of Driving Test Failures
     	By April 1970 Mrs. Miriam Hargrave had failed her test thirty-nine
    @@ -30917,7 +30928,7 @@ Lay off the muses, it's a very tough dollar.
     		-- S. J. Perelman
     %
     Lay on, MacDuff, and curs'd be him who first cries, "Hold, enough!".
    -		-- Shakespeare
    +		-- William Shakespeare
     %
     Layers are for cakes, not for software.
     		-- Bart Smaalders
    @@ -31038,7 +31049,7 @@ Let a fool hold his tongue and he will pass for a sage.
     Let he who takes the plunge remember to return it by Tuesday.
     %
     Let him choose out of my files, his projects to accomplish.
    -		-- Shakespeare, "Coriolanus"
    +		-- William Shakespeare, "Coriolanus"
     %
     Let me assure you that to us here at First National, you're not just a
     number.  You're two numbers, a dash, three more numbers, another dash and
    @@ -31095,7 +31106,7 @@ Let sleeping dogs lie.
     		-- Charles Dickens
     %
     Let the machine do the dirty work.
    -		-- "The Elements of Programming Style", Kernighan and Plauger
    +		-- Kernighan and Plauger, "The Elements of Programming Style"
     %
     Let the meek inherit the earth -- they have it coming to them.
     		-- James Thurber
    @@ -31105,7 +31116,7 @@ Let the people think they govern and they will be governed.
     %
     Let the worthy citizens of Chicago get their liquor the best way
     they can. I'm sick of the job.  It's a thankless one and full of grief.
    -		-- Capone
    +		-- Al Capone
     %
     Let thy maid servant be faithful, strong, and homely.
     		-- Benjamin Franklin
    @@ -31396,7 +31407,7 @@ Life is like a tin of sardines.
     We're, all of us, looking for the key.
     		-- Beyond the Fringe
     %
    -Life is like an analogy
    +Life is like an analogy.
     %
     Life is like an egg stain on your chin --
     you can lick it, but it still won't go away.
    @@ -31422,7 +31433,7 @@ Life is one long struggle in the dark.
     		-- Titus Lucretius Carus
     %
     Life is the childhood of our immortality.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     Life is the living you do,
     Death is the living you don't do.
    @@ -31624,7 +31635,7 @@ as you keep the television turned down and don't try to eat any solid foods.
     %
     Likewise, the national appetizer, brine-cured herring with raw onions,
     wins few friends, Germans excepted.
    -		-- Darwin Porter "Scandinavia On $50 A Day"
    +		-- Darwin Porter, "Scandinavia On $50 A Day"
     %
     Lincoln was elected to Congress in 1846.
     Kennedy exactly one hundred years later in 1946.
    @@ -31646,7 +31657,7 @@ Kennedy was succeeded by a Southerner named Johnson.
     The first Johnson was born in 1808.
     The second Johnson was born in 1908.
     
    -		-- Alistair Cooke, "Letter From America", 26nov2001
    +		-- Alistair Cooke, "Letter From America", Nov. 26, 2001
     %
     Line Printer paper is strongest at the perforations.
     %
    @@ -31861,7 +31872,7 @@ from NecroSoft inc., 6502 Charnelhouse Blvd., Cleveland, OH 44101.
     Loneliness is a terrible price to pay for independence.
     %
     Lonely is a man without love.
    -		-- Englebert Humperdinck
    +		-- Engelbert Humperdinck
     %
     Lonely men seek companionship.
     Lonely women sit at home and wait. They never meet.
    @@ -32032,7 +32043,7 @@ arms about love you'll find you are left only holding yourself.
     %
     Love is an ideal thing, marriage a real thing; a confusion of the real
     with the ideal never goes unpunished.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     Love is an obsessive delusion that is cured by marriage.
     		-- Dr. Karl Bowman
    @@ -32081,7 +32092,7 @@ Love is the only game that is not called on account of darkness.
     		-- M. Hirschfield
     %
     Love is the process of my leading you gently back to yourself.
    -		-- Saint Exupery
    +		-- Antoine de Saint-Exupery
     %
     Love is the triumph of imagination over intelligence.
     		-- H. L. Mencken
    @@ -32113,7 +32124,7 @@ That's the most ridiculous thing I've ever heard.
     Love means nothing to a tennis player.
     %
     Love tells us many things that are not so.
    -		-- Krainian Proverb
    +		-- Krainian proverb
     %
     Love the sea?  I dote upon it -- from the beach.
     %
    @@ -32165,7 +32176,7 @@ Luck can't last a lifetime, unless you die young.
     Luck, that's when preparation and opportunity meet.
     		-- P. E. Trudeau
     %
    -Lucky, adj:
    +Lucky, adj.:
     	When you have a wife and a cigarette
     	lighter -- both of which work.
     %
    @@ -32209,7 +32220,7 @@ Machines have less problems.  I'd like to be a machine.
     Machines that have broken down will work perfectly when the
     repairman arrives.
     %
    -macho, adj.:
    +Macho, adj.:
     	Jogging home from your vasectomy.
     %
     Macho does not prove mucho.
    @@ -32221,14 +32232,14 @@ Mad, adj.:
     %
     Madam, there's no such thing as a tough child --
     if you parboil them first for seven hours, they always come out tender.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     Madison's Inquiry:
     	If you have to travel on the Titanic, why not go first class?
     %
     Madness takes its toll.
     %
    -MAFIA, n:
    +MAFIA, n.:
     	[Acronym for Mechanized Applications in Forced Insurance
     Accounting.] An extensive network with many on-line and offshore
     subsystems running under OS, DOS, and IOS.  MAFIA documentation is
    @@ -32276,7 +32287,7 @@ Magpie, n.:
     MAIDEN AUNT:
     	A girl who never had the sense to say "uncle."
     %
    -Maiden, n:
    +Maiden, n.:
     	A young person of the unfair sex addicted to clewless conduct and
     	views that madden to crime.  The genus has a wide geographical
     	distribution, being found wherever sought and deplored wherever found.
    @@ -32418,7 +32429,7 @@ Man is the only animal that blushes -- or needs to.
     %
     Man is the only animal that can remain on friendly terms
     with the victims he intends to eat until he eats them.
    -		-- Samuel Butler, 1835-1902
    +		-- Samuel Butler (1835-1902)
     %
     Man is the only animal that laughs and weeps;
     for he is the only animal that is struck with the
    @@ -32491,12 +32502,12 @@ MANAGER:
     Mandrell: "You know what I think?"
     Doctor:   "Ah, ah that's a catch question.  With a brain your size you
     	  don't think, right?"
    -		-- Dr. Who
    +		-- "Doctor Who"
     %
    -man-hour, n:
    +Man-hour, n.:
     	A sexist, obsolete measure of macho effort, equal to 60 Kiplings.
     %
    -MANIC-DEPRESSIVE:
    +Manic-depressive, n.:
     	Easy glum, easy glow.
     %
     Mankind is poised midway between the gods and the beasts.
    @@ -32524,7 +32535,7 @@ Man's unique agony as a species consists in his perpetual
     conflict between the desire to stand out and the need to blend in.
     		-- Sydney J. Harris
     %
    -manual, n:
    +Manual, n.:
     	A unit of documentation.  There are always three or more on a given
     	item.  One is on the shelf; someone has the others.  The information
     	you need is in the others.
    @@ -32627,10 +32638,10 @@ Many people write memos to tell you they have nothing to say.
     Many receive advice, few profit by it.
     		-- Publilius Syrus
     %
    -Many years ago in a period commonly know as Next Friday Afternoon,
    +Many years ago in a period commonly known as Next Friday Afternoon,
     there lived a King who was very Gloomy on Tuesday mornings because he
     was so Sad thinking about how Unhappy he had been on Monday and how
    -completely Mournful he would be on Wednesday....
    +completely Mournful he would be on Wednesday ...
     		-- Walt Kelly
     %
     Margaret, are you grieving
    @@ -32733,8 +32744,8 @@ chopsticks.  It looks easy until you try it.
     Marriage is low down, but you spend the rest of your life paying for it.
     		-- Baskins
     %
    -Marriage is not merely sharing the fettucine, but sharing the
    -burden of finding the fettucine restaurant in the first place.
    +Marriage is not merely sharing the fettuccine, but sharing the
    +burden of finding the fettuccine restaurant in the first place.
     		-- Calvin Trillin
     %
     Marriage is the only adventure open to the cowardly.
    @@ -32745,7 +32756,7 @@ kind of man your wife would have preferred.
     %
     Marriage is the waste-paper basket of the emotions.
     %
    -Marriage, n:
    +Marriage, n.:
     	The evil aye.
     %
     Marriages are made in heaven and consummated on earth.
    @@ -32757,14 +32768,14 @@ MARTA SAYS THE INTERESTING thing about fly-fishing is that its two lives
     connected by a thin strand.
     
     Come on, Marta, grow up.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     MARTA WAS WATCHING THE FOOTBALL GAME with me when she said, "You know most
     of these sports are based on the idea of one group protecting its
     territory from invasion by another group."
     
     "Yeah," I said, trying not to laugh.  Girls are funny.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     Martin was probably ripping them off.  That's some family, isn't it?
     Incest, prostitution, fanaticism, software.
    @@ -32844,7 +32855,7 @@ MATH AND ALCOHOL DON'T MIX!
     Math is like love -- a simple idea but it can get complicated.
     		-- R. Drabek
     %
    -mathematician, n:
    +Mathematician, n.:
     	Some one who believes imaginary things appear right before your i's.
     %
     Mathematicians are like Frenchmen: whatever you say to them they translate
    @@ -32891,7 +32902,7 @@ Matter will be damaged in direct proportion to its value.
     [Maturity consists in the discovery that] there comes a critical moment
     where everything is reversed, after which the point becomes to understand
     more and more that there is something which cannot be understood.
    -		-- S. Kierkegaard
    +		-- S. A. Kierkegaard (1813-1855)
     %
     Maturity is only a short break in adolescence.
     		-- Jules Feiffer
    @@ -33009,7 +33020,7 @@ moonlit night, some horrible persona has been jabbing away at, dragging
     magnets over, and surging these voodoo boxen.  Fortunately, they seem to
     have gotten a bit bored and fallen asleep, for it looks like Cynthia may
     get to go home.  However, she has made note to quickly put together a totem
    -of sweaty, sordid static straps, random bits of wire, flecks of once meaniful
    +of sweaty, sordid static straps, random bits of wire, flecks of once meaningful
     oxide, bus grant cards, gummy worms, and some bits of old pdp backplane to
     hang above the machine room.  This totem must be blessed by the old and wise
     venerable god of unibus at once, before the idolatization of vme, q and pc
    @@ -33028,7 +33039,7 @@ Meekness is uncommon patience in planning a worthwhile revenge.
     %
     Meester, do you vant to buy a duck?
     %
    -meeting, n:
    +Meeting, n.:
     	An assembly of people coming together to decide what person or
     	department not represented in the room must solve a problem.
     %
    @@ -33055,7 +33066,7 @@ played.  I remember a bigger, older guy whom we called "Dad."  We'd eat
     some stuff or not and then I think we went home.
     
     I guess some things never leave you.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     Memory fault -- brain fried
     %
    @@ -33087,7 +33098,7 @@ thing they marry later; for another thing they die earlier.
     %
     Men have as exaggerated an idea of their
     rights as women have of their wrongs.
    -		-- E. W. Howe
    +		-- Edgar W. Howe
     %
     Men live for three things, fast cars, fast women and fast food.
     %
    @@ -33095,7 +33106,7 @@ Men love to wonder, and that is the seed of science.
     %
     Men never do evil so completely and cheerfully as when they do it
     from religious conviction.
    -		-- Blaise Pascal, "Pensées", 1670
    +		-- Blaise Pascal, "Pens'ees", 1670
     %
     Men never make passes at girls wearing glasses.
     		-- Dorothy Parker
    @@ -33118,7 +33129,7 @@ and tears.  ...  It is the same thing which makes us mad or delirious,
     inspires us with dread and fear, whether by night or by day, brings us
     sleeplessness, inopportune mistakes, aimless anxieties, absent-mindedness
     and acts that are contrary to habit...
    -		-- Hippocrates "The Sacred Disease"
    +		-- Hippocrates, "The Sacred Disease"
     %
     Men say of women what pleases them; women do with men what pleases them.
     		-- DeSegur
    @@ -33159,7 +33170,7 @@ Mencken and Nathan's Sixteenth Law of The Average American:
     	is possessed only by yokels, and no person born in a large city
     	can never hope to acquire it.
     %
    -Mene, mene, tekel, upharsen.
    +Mene, mene, tekel, upharsin.
     %
     Mental power tended to corrupt, and absolute intelligence tended to
     corrupt absolutely, until the victim eschewed violence entirely in
    @@ -33217,7 +33228,8 @@ lylglutamyllysylmethionylleucylalanylalanylleucyllysylvalylphenylalanylvalyl-
     glutaminylprolylmethionyllysylalanylalanylthreonylarginylserine, n.:
     	The chemical name for tryptophan synthetase A protein, a
     	1,913-letter enzyme with 267 amino acids.
    -		-- Mrs. Bryne's Dictionary of Unusual, Obscure, and
    +		-- Mrs. Byrne's Dictionary of Unusual, Obscure, and
    +		   Preposterous Words
     %
     Mickey Mouse wears a Spiro Agnew watch.
     %
    @@ -33238,7 +33250,7 @@ Mieux vaut tard que jamais!
     %
     Might as well be frank, monsieur.  It would take a miracle to
     get you out of Casablanca and the Germans have outlawed miracles.
    -		-- Casablanca
    +		-- Signor Ferrari, "Casablanca" (1942)
     %
     Mike:	"The Fourth Dimension is a shambles?"
     Bernie:	"Nobody ever empties the ashtrays.  People are SO
    @@ -33259,7 +33271,7 @@ Military justice is to justice what military music is to music.
     Miller's Slogan:
     	Lose a few, lose a few.
     %
    -millihelen, adj:
    +Millihelen, adj.:
     	The amount of beauty required to launch one ship.
     %
     Millions long for immortality who do not know what
    @@ -33333,6 +33345,12 @@ Miss, n.:
     	women to indicate that they are in the market.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    +Mistakeholder, n.:
    +	A person who depends on accidental features or
    +	implementation errors and so now has a vested
    +	interest in keeping things from being fixed.
    +		-- Chip Morningstar
    +%
     Mistakes are often the stepping stones to utter failure.
     %
     Mistrust first impulses; they are always right.
    @@ -33353,7 +33371,7 @@ Mix a little foolishness with your serious plans;
     it's lovely to be silly at the right moment.
     		-- Horace
     %
    -mixed emotions:
    +Mixed emotions:
     	Watching a bus-load of lawyers plunge off a cliff.
     	With five empty seats.
     %
    @@ -33382,7 +33400,7 @@ is crisp and golden.  Serve warm.  Cut into 6 to 8 slices.
     Modeling paged and segmented memories is tricky business.
     		-- P. J. Denning
     %
    -modem, adj:
    +Modem, adj.:
     	Up-to-date, new-fangled, as in "Thoroughly Modem Millie."  An
     	unfortunate byproduct of kerning.
     %
    @@ -33552,7 +33570,7 @@ in California ... [it] is also a great place for cock-fighting, gambling
     of all sorts, fandangos, and various kinds of amusements and knavery.
     		-- Richard Henry Dama, "Two Years Before the Mast", 1840
     %
    -moon, n:
    +Moon, n.:
     	1. A celestial object whose phase is very important to
     hackers.  See PHASE OF THE MOON.  2. Dave Moon (MOON@MC).
     %
    @@ -33560,7 +33578,7 @@ Moore's Constant:
     	Everybody sets out to do something, and everybody
     	does something, but no one does what he sets out to do.
     %
    -mophobia, n:
    +Mophobia, n.:
     	Fear of being verbally abused by a Mississippian.
     %
     More are taken in by hope than by cunning.
    @@ -33694,14 +33712,14 @@ Most people don't need a great deal of love
     nearly so much as they need a steady supply.
     %
     Most people eat as though they were fattening themselves for market.
    -		-- E. W. Howe
    +		-- Edgar W. Howe
     %
     Most people feel that everyone is entitled to their opinion.
     %
     Most people have a furious itch to talk about themselves and are restrained
     only by the disinclination of others to listen.  Reserve is an artificial
     quality that is developed in most of us as the result of innumerable rebuffs.
    -		-- W. S. Maugham
    +		-- W. Somerset Maugham
     %
     Most people have a mind that's open by appointment only.
     %
    @@ -33749,7 +33767,7 @@ Mother is the invention of necessity.
     Mother said there would be days like this, but she never said there
     would be so many.
     %
    -Mother told me to be good but she's been wrong before.
    +Mother told me to be good, but she's been wrong before.
     %
     Mothers all want their sons to grow up to be President, but they
     don't want them to become politicians in the process.
    @@ -34016,7 +34034,7 @@ My father was a saint, I'm not.
     %
     My favorite sandwich is peanut butter, baloney, cheddar cheese, lettuce
     and mayonnaise on toasted bread with catsup on the side.
    -		-- Senator Hubert Humphrey
    +		-- Hubert H. Humphrey
     %
     My first basename is George "Catfish" Metkovich from our 1952 Pittsburgh
     Pirates team, which lost 112 games.  After a terrible series against the
    @@ -34172,7 +34190,7 @@ Any man who has $10,000 left when he dies is a failure.
     %
     My rackets are run on strictly American
     lines, and they're going to stay that way.
    -		-- A. Capone
    +		-- Al Capone
     %
     My religion consists of a humble admiration of the illimitable superior
     spirit who reveals himself in the slight details we are able to perceive
    @@ -34347,7 +34365,7 @@ given them little.
     %
     Nature is by and large to be found out of doors, a location where, it
     cannot be argued, there are never enough comfortable chairs.
    -		-- Fran Leibowitz
    +		-- Fran Lebowitz
     %
     Nature makes boys and girls lovely to look upon so they can be
     tolerated until they acquire some sense.
    @@ -34426,7 +34444,7 @@ Nemo me impune lacessit
     	[No one provokes me with impunity]
     		-- Motto of the Crown of Scotland
     %
    -nerd pack, n:
    +Nerd pack, n.:
     	Plastic pouch worn in breast pocket to keep pens from soiling
     	clothes.  Nerd's position in engineering hierarchy can be
     	measured by number of pens, grease pencils, and rulers bristling
    @@ -34448,7 +34466,7 @@ Neutrinos are into physicists.
     %
     Neutrinos have bad breadth.
     %
    -neutron bomb, n:
    +Neutron bomb, n.:
     	An explosive device of limited military value because, as
     	it only destroys people without destroying property, it
     	must be used in conjunction with bombs that destroy property.
    @@ -34552,7 +34570,7 @@ Never keep up with the Joneses. Drag them down to your level.
     Never kick a man, unless he's down.
     %
     Never laugh at live dragons.
    -		-- Bilbo Baggins
    +		-- Bilbo Baggins, "The Hobbit"
     %
     Never leave anything to chance;
     make sure all your crimes are premeditated.
    @@ -34657,7 +34675,7 @@ Never trust anyone who says money is no object.
     %
     Never try to explain computers to a layman.  It's easier to explain
     sex to a virgin.
    -		-- Robert Heinlein
    +		-- Robert A. Heinlein
     
     (Note, however, that virgins tend to know a lot about computers.)
     %
    @@ -34673,7 +34691,7 @@ Never underestimate the bandwidth of a station wagon full of tapes.
     Never underestimate the power of a small tactical nuclear weapon.
     %
     Never underestimate the power of human stupidity.
    -		-- Robert Heinlein
    +		-- Robert A. Heinlein
     %
     Never use "etc." -- it makes people think there is more where
     there is not or that there is not space to list it all, etc.
    @@ -34685,7 +34703,7 @@ Never worry about theory as long as the
     machinery does what it's supposed to do.
     		-- Robert A. Heinlein
     %
    -new, adj:
    +New, adj.:
     	Different color from previous model.
     %
     New crypt.  See /usr/news/crypt.
    @@ -34750,7 +34768,7 @@ It was.  Age 31.
     %
     Newspaper editors are men who separate the wheat from the chaff, and then
     print the chaff.
    -		-- Adlai Stevenson
    +		-- Adlai E. Stevenson
     %
     Newton's Fourth Law:  Every action has an equal and opposite satisfaction.
     %
    @@ -34844,7 +34862,7 @@ absolutely certain he can hold his own in conversation.
     No bird soars too high if he soars with his own wings.
     		-- William Blake
     %
    -no brainer:
    +No brainer, n.:
     	A decision which, viewed through the retrospectoscope,
     	is "obvious" to those who failed to make it originally.
     %
    @@ -34860,7 +34878,7 @@ No Civil War picture ever made a nickel.
     No committee could ever come up with anything as revolutionary as a
     camel -- anything as practical and as perfectly designed to perform
     effectively under such difficult conditions.
    -		-- Laurence J. Peter
    +		-- Dr. Laurence J. Peter
     %
     No directory.
     %
    @@ -34871,8 +34889,8 @@ lectures which are really worth the attending.
     No doubt Jack the Ripper excused himself
     on the grounds that it was human nature.
     %
    -No, `Eureka' is Greek for `This bath is too hot.'
    -		-- Dr. Who
    +No, "Eureka" is Greek for "This bath is too hot."
    +		-- The Doctor, "Doctor Who"
     %
     No evil can happen to a good man.
     		-- Plato
    @@ -34902,7 +34920,7 @@ No guts, no glory.
     %
     No hardware designer should be allowed to produce any piece of hardware
     until three software guys have signed off for it.
    -		-- Andy Tanenbaum
    +		-- Andrew S. Tanenbaum
     %
     No, his mind is not for rent
     To any god or government.
    @@ -34942,7 +34960,7 @@ doors were sensibly shut; silence lay steadily against the wood and stone
     of Hill House, and whatever walked there, walked alone.
     		-- Shirley Jackson, "The Haunting of Hill House"
     %
    -no maintenance:
    +No maintenance:
     	Impossible to fix.
     %
     No man can have a reasonable opinion of women until he has long lost
    @@ -34970,7 +34988,7 @@ and if we are loved we are indispensable.
     		-- Robert Louis Stevenson
     %
     No man would listen to you talk if he didn't know it was his turn next.
    -		-- E. W. Howe
    +		-- Edgar W. Howe
     %
     No man's ambition has a right to stand in
     the way of performing a simple act of justice.
    @@ -35148,7 +35166,7 @@ May beat admission in a thousand years.
     %
     No self-made man ever did such a good job
     that some woman didn't want to make some alterations.
    -		-- Kim Hubbard
    +		-- Kin Hubbard
     %
     No self-respecting fish would want to be wrapped in that kind of
     paper.
    @@ -35159,7 +35177,7 @@ No skis take rocks like rental skis!
     %
     No small art is it to sleep: it is necessary
     for that purpose to keep awake all day.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     No snowflake in an avalanche ever feels responsible.
     %
    @@ -35174,7 +35192,7 @@ No spitting on the Bus!
     Thank you, The Management.
     %
     No television performance takes as much preparation as an off-the-cuff talk.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     No two persons ever read the same book.
     		-- Edmund Wilson
    @@ -35190,11 +35208,11 @@ she will or will not be a mother.
     		-- Margaret H. Sanger
     %
     No woman can endure a gambling husband, unless he is a steady winner.
    -		-- Lord Thomas Dewar
    +		-- Lord Thomas Robert Dewar
     %
     No woman ever falls in love with a man unless she has a better opinion of
     him than he deserves.
    -		-- Edgar Watson Howe
    +		-- Edgar W. Howe
     %
     No wonder Clairol makes so much money selling shampoo.
     Lather, Rinse, Repeat is an infinite loop!
    @@ -35203,29 +35221,6 @@ No wonder you're tired!  You understood so much today.
     %
     No yak too dirty; no dumpster too hollow.
     %
    -Nobert Weiner was the subject of many dotty professor stories.  Weiner was, in
    -fact, very absent minded.  The following story is told about him: when they
    -moved from Cambridge to Newton his wife, knowing that he would be absolutely
    -useless on the move, packed him off to MIT while she directed the move.  Since
    -she was certain that he would forget that they had moved and where they had
    -moved to, she wrote down the new address on a piece of paper, and gave it to
    -him.  Naturally, in the course of the day, an insight occurred to him.  He
    -reached in his pocket, found a piece of paper on which he furiously scribbled
    -some notes, thought it over, decided there was a fallacy in his idea, and
    -threw the piece of paper away.  At the end of the day he went home (to the
    -old address in Cambridge, of course).  When he got there he realized that they
    -had moved, that he had no idea where they had moved to, and that the piece of
    -paper with the address was long gone.  Fortunately inspiration struck.  There
    -was a young girl on the street and he conceived the idea of asking her where
    -he had moved to, saying, "Excuse me, perhaps you know me.  I'm Norbert Weiner
    -and we've just moved.  Would you know where we've moved to?"  To which the
    -young girl replied, "Yes, Daddy, Mommy thought you would forget."
    -	The capper to the story is that I asked his daughter (the girl in the
    -story) about the truth of the story, many years later.  She said that it wasn't
    -quite true -- that he never forgot who his children were!  The rest of it,
    -however, was pretty close to what actually happened...
    -		-- Richard Harter
    -%
     Nobody can be as agreeable as an uninvited guest.
     %
     Nobody can be exactly like me.  Sometimes even I have trouble doing
    @@ -35303,11 +35298,11 @@ Noise proves nothing.  Often a hen who has
     merely laid an egg cackles as if she laid an asteroid.
     		-- Mark Twain
     %
    -nolo contendere:
    +Nolo contendere:
     	A legal term meaning: "I didn't do it, judge, and I'll never do
     	it again."
     %
    -nominal egg:
    +Nominal egg:
     	New Yorkerese for expensive.
     %
     Noncombatant, n.:
    @@ -35350,6 +35345,29 @@ No-one would remember the Good Samaritan if he had only had good
     intentions.  He had money as well.
     		-- Margaret Thatcher
     %
    +Norbert Wiener was the subject of many dotty professor stories.  Wiener was, in
    +fact, very absent minded.  The following story is told about him: when they
    +moved from Cambridge to Newton his wife, knowing that he would be absolutely
    +useless on the move, packed him off to MIT while she directed the move.  Since
    +she was certain that he would forget that they had moved and where they had
    +moved to, she wrote down the new address on a piece of paper, and gave it to
    +him.  Naturally, in the course of the day, an insight occurred to him.  He
    +reached in his pocket, found a piece of paper on which he furiously scribbled
    +some notes, thought it over, decided there was a fallacy in his idea, and
    +threw the piece of paper away.  At the end of the day he went home (to the
    +old address in Cambridge, of course).  When he got there he realized that they
    +had moved, that he had no idea where they had moved to, and that the piece of
    +paper with the address was long gone.  Fortunately inspiration struck.  There
    +was a young girl on the street and he conceived the idea of asking her where
    +he had moved to, saying, "Excuse me, perhaps you know me.  I'm Norbert Wiener
    +and we've just moved.  Would you know where we've moved to?"  To which the
    +young girl replied, "Yes, Daddy, Mommy thought you would forget."
    +	The capper to the story is that I asked his daughter (the girl in the
    +story) about the truth of the story, many years later.  She said that it wasn't
    +quite true -- that he never forgot who his children were!  The rest of it,
    +however, was pretty close to what actually happened...
    +		-- Richard Harter
    +%
     Norm:	Hey, everybody.
     All:	[silence; everybody is mad at Norm for being rich.]
     Norm:	[Carries on both sides of the conversation himself.]
    @@ -35443,7 +35461,7 @@ All:   Anton!
     		-- Cheers, The Two Faces of Norm
     
     Woody: What's going on, Mr. Peterson?
    -Norm:  A flashing sign in my gut that says, ``Insert beer here.''
    +Norm:  A flashing sign in my gut that says, "Insert beer here."
     		-- Cheers, Call Me, Irresponsible
     
     Sam:	What can I get you, Norm?
    @@ -35492,11 +35510,11 @@ chipped at it a bit, and everything was just fine ...
     		-- Stanislaw Lem, "Cyberiad"
     %
     Not Hercules could have knock'd out his brains, for he had none.
    -		-- Shakespeare
    +		-- William Shakespeare
     %
     Not only is this incomprehensible, but the ink is
     ugly and the paper is from the wrong kind of tree.
    -		-- Professor, EECS, George Washington University
    +		-- Professor W., EECS, George Washington University
     
     I'm looking forward to working with you on this next year.
     		-- Professor, Harvard, on a senior thesis
    @@ -35532,7 +35550,7 @@ and/or frogs falling from the sky.
     %
     Note: The system panics with a "NULL pointer dereference" message
     
    -Failed due to : SunOS 5.8 is installed.
    +Failed due to: SunOS 5.8 is installed.
     		-- Output of a SunCheckup run on a Solaris 8 machine
     %
     Note to myself: use real bullets next time.
    @@ -35627,7 +35645,7 @@ Nothing, nothing, nothing, no error, no crime is so absolutely
     repugnant to God as everything which is official; and why? because
     the official is so impersonal and therefore the deepest insult
     which can be offered to a personality.
    -		-- Soren Kierkegaard
    +		-- S. A. Kierkegaard (1813-1855)
     %
     Nothing recedes like success.
     		-- Walter Winchell
    @@ -35674,7 +35692,7 @@ I said oh, you can leave it.
     		-- Al Stewart, "If It Doesn't Come Naturally, Leave It"
     %
     Nothing will dispel enthusiasm like a small admission fee.
    -		-- Kim Hubbard
    +		-- Kin Hubbard
     %
     Nothing will ever be attempted
     if all possible objections must be first overcome.
    @@ -35690,16 +35708,16 @@ NOTICE:
     
     (The nearest working elevator is in the building across the street.)
     %
    -Nouvelle cuisine, n:
    +Nouvelle cuisine, n.:
     	French for "not enough food".
     
    -Continental breakfast, n:
    +Continental breakfast, n.:
     	English for "not enough food".
     
    -Tapas, n:
    +Tapas, n.:
     	Spanish for "not enough food".
     
    -Dim Sum, n:
    +Dim Sum, n.:
     	Chinese for more food than you've ever seen in your entire life.
     %
     November, n.:
    @@ -35906,7 +35924,7 @@ O imitators, you slavish herd!
     O, it is excellent
     To have a giant's strength; but it is tyrannous
     To use it like a giant.
    -		-- Shakespeare, "Measure for Measure", II, 2
    +		-- William Shakespeare, "Measure for Measure", II, 2
     %
     O Lord, grant that we may always be right,
     for Thou knowest we will never change our minds.
    @@ -36010,7 +36028,7 @@ Of course you have a purpose -- to find a purpose.
     Of what you see in books, believe 75%.  Of newspapers, believe 50%.  And of
     TV news, believe 25% -- make that 5% if the anchorman wears a blazer.
     %
    -Office Automation:
    +Office Automation, n.:
     	The use of computers to improve efficiency in the office
     	by removing anyone you would want to talk with over coffee.
     %
    @@ -36079,7 +36097,7 @@ Oh, give me a locus where the gravitons focus
     	Where the three-body problem is solved,
     	Where the microwaves play down at three degrees K,
     	And the cold virus never evolved.			(chorus)
    -We eat algea pie, our vacuum is high,
    +We eat algae pie, our vacuum is high,
     	Our ball bearings are perfectly round.
     	Our horizon is curved, our warheads are MIRVed,
     	And a kilogram weighs half a pound.			(chorus)
    @@ -36149,7 +36167,7 @@ Shooting up my veins,
     Tell you, I've been a-thinkin'
     I could drive a shiny Lincoln,
     If I dealt in good cocaine.
    -		-- To 'If I Only Had A Brain' from "The Wizard of Oz"
    +		-- To "If I Only Had A Brain" from "The Wizard of Oz"
     %
     Oh, I don't blame Congress.  If I had $600 billion at my disposal, I'd
     be irresponsible, too.
    @@ -36171,7 +36189,7 @@ Where never lark, or even eagle flew;
     And, while with silent, lifting mind I've trod
     The high untrespassed sanctity of space,
     Put out my hand, and touched the face of God.
    -		-- John Gillespie Magee Jr., "High Flight"
    +		-- John Gillespie Magee, Jr., "High Flight"
     %
     Oh I'm just a typical American boy
     From a typical American town.
    @@ -36233,7 +36251,7 @@ Born under one law, to another bound.
     Oh, well, I guess this is just going to be one of those lifetimes.
     %
     Oh what a tangled web we weave, when first we practice to deceive.
    -		-- Shakespeare
    +		-- William Shakespeare
     %
     Oh, when I was in love with you,
     	Then I was clean and brave,
    @@ -36248,10 +36266,10 @@ And miles around they'll say that I
     %
     Oh, wow!  Look at the moon!
     %
    -Oh, ya doesn't have ta call me 'Johnson'!  Well, you can call me 'Ray', or
    -you can call me 'Jay', or you can call me 'R.J.', or you can call me 'Ray
    -J.', or you can call me 'R.J.J.', or you can call me 'Ray J. Johnson', or
    -you can call me 'R.J. Johnson', but ya DOESN'T have to call me 'Johnson'...
    +Oh, ya doesn't have ta call me "Johnson"!  Well, you can call me "Ray", or
    +you can call me "Jay", or you can call me "R. J.", or you can call me "Ray
    +J.", or you can call me "R. J. J.", or you can call me "Ray J. Johnson", or
    +you can call me "R. J. Johnson", but ya DOESN'T have to call me "Johnson" ...
     %
     Oh, yeah, life goes on, long after the thrill of livin' is gone.
     		-- John Cougar, "Jack and Diane"
    @@ -36317,13 +36335,13 @@ Old programmers never die, they just hit account block limit.
     %
     Old soldiers never die.  Young ones do.
     %
    -Old timer, n:
    +Old timer, n.:
     	One who remembers when charity was a virtue and not an organization.
     %
     Olivier's Law:
     	Experience is something you don't get until just after you need it.
     %
    -omnibiblious, adj.:
    +Omnibiblious, adj.:
     	Indifferent to type of drink.  Ex: "Oh, you can get me anything.
     	I'm omnibiblious."
     %
    @@ -36388,7 +36406,7 @@ On the subject of C program indentation:
     		-- Blair P. Houghton
     %
     On the whole, I'd rather be in Philadelphia.
    -		-- W.C. Fields' epitaph
    +		-- W. C. Fields' epitaph
     %
     On two occasions I have been asked [by members of Parliament!], "Pray, Mr.
     Babbage, if you put into the machine wrong figures, will the right answers
    @@ -36398,7 +36416,7 @@ ideas that could provoke such a question.
     %
     Once ... in the wilds of Afghanistan, I lost my corkscrew,
     and we were forced to live on nothing but food and water for days.
    -		-- W.C. Fields, "My Little Chickadee"
    +		-- W. C. Fields, "My Little Chickadee"
     %
     Once a word has been allowed to escape, it cannot be recalled.
     		-- Quintus Horatius Flaccus (Horace)
    @@ -36451,16 +36469,16 @@ each of us observes, in his own way, by going to the mall of his
     choice.
     
     In the old days, it was not called the Holiday Season; the Christians
    -called it "Christmas" and went to church; the Jews called it "Hanukka"
    +called it "Christmas" and went to church; the Jews called it "Hanukkah"
     and went to synagogue; the atheists went to parties and drank.  People
     passing each other on the street would say "Merry Christmas!" or "Happy
    -Hanukka!" or (to the atheists) "Look out for the wall!"
    +Hanukkah!" or (to the atheists) "Look out for the wall!"
     		-- Dave Barry, "Christmas Shopping: A Survivor's Guide"
     %
     Once at a social gathering, Gladstone said to Disraeli, "I predict,
     Sir, that you will die either by hanging or of some vile disease".
     Disraeli replied, "That all depends upon whether I embrace your
    -principles or your mistress".
    +principals or your mistress."
     %
     Once harm has been done, even a fool understands it.
     		-- Homer
    @@ -36793,7 +36811,7 @@ many ...
     		-- Anthony Chevins
     %
     One man's constant is another man's variable.
    -		-- A. J. Perlis
    +		-- Alan J. Perlis
     %
     One man's folly is another man's wife.
     		-- Helen Rowland
    @@ -36854,7 +36872,7 @@ to get people off their guard, pretending to be stupid because he couldn't
     be bothered to think and wanted someone else to do it for him, pretending
     to be so outrageously stupid to hide the fact that he actually didn't
     understand what was going on, and really being genuinely stupid.  He was
    -reknowned for being quite clever and quite clearly was so -- but not all the
    +renowned for being quite clever and quite clearly was so -- but not all the
     time, which obviously worried him, hence the act.  He preferred people to be
     puzzled rather than contemptuous.  This above all appeared to Trillian to be
     genuinely stupid, but she could no longer be bothered to argue about.
    @@ -36931,9 +36949,6 @@ One planet is all you get.
     One possible reason that things aren't going according to plan
     is that there never was a plan in the first place.
     %
    -One possible reason why things aren't going
    -according to plan is that there never was a plan.
    -%
     One promising concept that I came up with right away was that you could
     manufacture personal air bags, then get a law passed requiring that
     they be installed on congressmen to keep them from taking trips.  Let's
    @@ -36989,7 +37004,7 @@ cried, but I think that deep down he thought it was a pretty good joke.
     
     I started to drive over to the real Disneyland, but it was getting pretty
     late.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     One thing the inventors can't seem to
     get the bugs out of is fresh paint.
    @@ -37023,7 +37038,7 @@ One would like to stroke and caress human beings, but one dares not do so,
     because they bite.
     		-- Vladimir Lenin
     %
    -One-Shot Case Study, n:
    +One-Shot Case Study, n.:
     	The scientific equivalent of the four-leaf clover, from which
     	it is concluded all clovers possess four leaves and are sometimes green.
     %
    @@ -37034,7 +37049,7 @@ On-line, adj.:
     Only a fool has no doubts.
     %
     Only a mediocre person is always at his best.
    -		-- Laurence Peter
    +		-- Dr. Laurence J. Peter
     %
     Only adults have difficulty with childproof caps.
     %
    @@ -37120,7 +37135,7 @@ Oppernockity tunes but once.
     Opportunities are usually disguised as hard
     work, so most people don't recognize them.
     %
    -Oprah Winfrey has an incredible talent for getting the wierdest people to
    +Oprah Winfrey has an incredible talent for getting the weirdest people to
     talk to.  And you just HAVE to watch it.  "Blind, masochistic minority,
     crippled, depressed, government latrine diggers, and the women who love
     them too much on the next Oprah Winfrey."
    @@ -37128,7 +37143,7 @@ them too much on the next Oprah Winfrey."
     Optimism is the content of small men in high places.
     		-- F. Scott Fitzgerald, "The Crack Up"
     %
    -Optimism, n:
    +Optimism, n.:
     The belief that everything is beautiful, including what is ugly, good, bad,
     and everything right that is wrong.  It is held with greatest tenacity by
     those accustomed to falling into adversity, and most acceptably expounded
    @@ -37136,11 +37151,7 @@ with the grin that apes a smile.  Being a blind faith, it is inaccessible
     to the light of disproof -- an intellectual disorder, yielding to no treatment
     but death.  It is hereditary, but not contagious.
     %
    -Optimist:
    -	Someone who goes down to the marriage
    -	bureau to see if his license has expired.
    -%
    -Optimist, n:
    +Optimist, n.:
     	A bagpiper with a beeper.
     %
     Optimist, n.:
    @@ -37154,6 +37165,10 @@ would justify them."
     something -- the mortality of the optimist."
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    +Optimist, n.:
    +	Someone who goes down to the marriage
    +	bureau to see if his license has expired.
    +%
     Optimization hinders evolution.
     %
     Oral sex is like being attacked by a giant snail.
    @@ -37349,7 +37364,7 @@ move?'
     %
     Overdrawn?  But I still have checks left!
     %
    -Overflow on /dev/null, please empty the bit bucket.
    +Overflow on /dev/null: please empty the bit bucket.
     %
     Overheard:
     	"How do I feel?  Great!  And I kiss pretty good, too!"
    @@ -37433,7 +37448,7 @@ panic: kernel trap (ignored)
     %
     Paprika Measure:
     
    -	2 dashes    ==  1smidgen
    +	2 dashes    ==  1 smidgen
     	2 smidgens  ==  1 pinch
     	3 pinches   ==  1 soupcon
     	2 soupcons  ==  too much paprika
    @@ -37482,7 +37497,7 @@ Parker's Law:
     	Beauty is only skin deep, but ugly goes clean to the bone.
     %
     Parkinson's Fifth Law:
    -	If there is a way to delay in important decision, the good
    +	If there is a way to delay an important decision, the good
     	bureaucracy, public or private, will find it.
     %
     Parkinson's Fourth Law:
    @@ -37548,7 +37563,7 @@ A:	No, you SINGE 'em.  You SINGE 'em and eat 'em.  *I* read about the
     P:	Squirrels eating squirrels -- my GOD, that's sick!
     A:	That's sick, SURE.  But a MAN eating a squirrel -- that's (heh, heh)
     	par for the course, Charlie.
    -		-- Firesign Theatre
    +		-- The Firesign Theatre
     %
     Patageometry, n.:
     	The study of those mathematical properties that are invariant
    @@ -37557,7 +37572,7 @@ under brain transplants.
     Patch griefs with proverbs.
     		-- William Shakespeare, "Much Ado About Nothing"
     %
    -patent:
    +Patent, v.:
     	A method of publicizing inventions so others can copy them.
     %
     "Pathetic," he said.  "That's what it is.  Pathetic."
    @@ -37609,7 +37624,7 @@ Pause for storage relocation.
     Pay no attention to that man behind the curtain.
     		-- Frank Morgan as The Wizard, "The Wizard of Oz"
     %
    -paycheck:
    +Paycheck, n.:
     	The weekly $5.27 that remains after deductions for federal
     	withholding, state withholding, city withholding, FICA,
     	medical/dental, long-term disability, unemployment insurance,
    @@ -37634,11 +37649,11 @@ Peace be to this house, and all that dwell in it.
     %
     Peace cannot be kept by force; it
     can only be achieved by understanding.
    -		-- A. Einstein
    +		-- Albert Einstein
     %
     Peace is much more precious than a piece
     of land... let there be no more wars.
    -		-- Mohammed Anwar Sadat, 1918-1981
    +		-- Mohammed Anwar Sadat (1918-1981)
     %
     Peace, n.:
     	In international affairs, a period of cheating between two
    @@ -37701,7 +37716,7 @@ if he didn't understand people; and how could he have done that if people
     weren't easy to understand?  You show me someone who can't understand
     people and I'll show you someone who has built up a false image of himself
     -- no offense intended."
    -		-- Asimov, "Foundation's Edge"
    +		-- Isaac Asimov, "Foundation's Edge"
     %
     Penguin Trivia #46:
     	Animals who are not penguins can only wish they were.
    @@ -37709,7 +37724,7 @@ Penguin Trivia #46:
     %
     PENGUINICITY!!
     %
    -pension:
    +Pension, n.:
     	A federally insured chain letter.
     %
     People (a group that in my opinion has always attracted an undue amount of
    @@ -37838,7 +37853,7 @@ or
     %
     Perfect day for scrubbing the floor and other exciting things.
     %
    -perfect guest:
    +Perfect guest, n.:
     	One who makes his host feel at home.
     %
     Perfection is finally attained, not when there is no longer
    @@ -37877,7 +37892,7 @@ Periphrasis is the putting of things in a round-about way.  "The cost may be
     upwards of a figure rather below 10m#." is a periphrasis for The cost may be
     nearly 10m#.  "In Paris there reigns a complete absence of really reliable
     news" is a periphrasis for There is no reliable news in Paris.  "Rarely does
    -the 'Little Summer' linger until November, but at times its stay has been
    +the `Little Summer' linger until November, but at times its stay has been
     prolonged until quite late in the year's penultimate month" contains a
     periphrasis for November, and another for lingers.  "The answer is in the
     negative" is a periphrasis for No.  "Was made the recipient of" is a
    @@ -37908,15 +37923,15 @@ persons attempting to find a moral in it will be banished; persons attempting
     to find a plot in it will be shot.  By Order of the Author
     		-- Mark Twain, "Tom Sawyer"
     %
    -pessimist:
    +Pessimist, n.:
     	A man who spends all his time worrying about how he can keep the
     	wolf from the door.
     
    -optimist:
    +Optimist, n.:
     	A man who refuses to see the wolf until he seizes the seat of
     	his pants.
     
    -opportunist:
    +Opportunist, n.:
     	A man who invites the wolf in and appears the next day in a fur coat.
     %
     Pete:	Waiter, this meat is bad.
    @@ -37970,10 +37985,10 @@ exciting Camden, New Jersey.
     %
     Philogyny recapitulates erogeny; erogeny recapitulates philogyny.
     %
    -philosophy:
    +Philosophy, n.:
     	The ability to bear with calmness the misfortunes of our friends.
     %
    -philosophy:
    +Philosophy, n.:
     	Unintelligible answers to insoluble problems.
     %
     Philosophy will clip an angel's wings.
    @@ -37981,7 +37996,7 @@ Philosophy will clip an angel's wings.
     %
     Phone call for chucky-pooh.
     %
    -Phosflink, v:
    +Phosflink, v.:
     	To flick a bulb on and off when it burns out (as if, somehow,
     	that will bring it back to life).
     		-- Rich Hall & Friends, "Sniglets"
    @@ -38060,7 +38075,7 @@ So I piped with merry cheer.
     So I piped: he wept to hear.
     		-- William Blake, "Songs of Innocence"
     %
    -Pipo was born with few complications, but then the doctor accidently dropped
    +Pipo was born with few complications, but then the doctor accidentally dropped
     the infant on her head provoking her drunken father to drag the physician
     outside where he would beat him to death with a live ocelot.
     		-- Love and Rockets
    @@ -38087,7 +38102,7 @@ PISCES (Feb.19 - Mar.20)
     Pity the meek, for they shall inherit the earth.
     		-- Don Marquis
     %
    -pixel, n:
    +Pixel, n.:
     	A mischievous, magical spirit associated with screen displays.
     	The computer industry has frequently borrowed from mythology:
     	Witness the sprites in computer graphics, the demons in artificial
    @@ -38240,7 +38255,7 @@ Plus ca change, plus c'est le meme chose.
     Pohl's law:
     	Nothing is so good that somebody, somewhere, will not hate it.
     %
    -poisoned coffee, n:
    +Poisoned coffee, n.:
     	Grounds for divorce.
     %
     Poland has gun control.
    @@ -38259,7 +38274,7 @@ Host:	Oh, the noise.  Well that makes sense because there are no guns
     Police:	No, the neighbors fled inland hours ago.  Most of the recent
     	complaints have come from Pittsburgh.  Do you think you could
     	ask the host to quiet things down?
    -Host:	No Problem.  (At this point, a Volkswagon bug with primitive
    +Host:	No Problem.  (At this point, a Volkswagen bug with primitive
     	religious symbols drawn on the doors emerges from the living
     	room and roars down the hall, past the police and onto the
     	lawn, where it smashes into a tree.  Eight guests tumble out
    @@ -38447,7 +38462,7 @@ poor people.
     		-- Don Herold
     %
     Power and ignorance is a detestable cocktail.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     Power corrupts.  Absolute power is kind of neat.
     		-- John Lehman, Secretary of the Navy, 1981-1987
    @@ -38465,7 +38480,7 @@ Power, like a desolating pestilence,
     Pollutes whate'er it touches...
     		-- Percy Bysshe Shelley
     %
    -Power, n:
    +Power, n.:
     	The only narcotic regulated by the SEC instead of the FDA.
     %
     Power tends to corrupt, absolute power corrupts absolutely.
    @@ -38502,7 +38517,7 @@ Praise the sea; on shore remain.
     Pray to God, but keep rowing to shore.
     		-- Russian Proverb
     %
    -Pray, v:
    +Pray, v.:
     	To ask that the laws of the universe be annulled on behalf
     	of a single petitioner confessedly unworthy.
     		-- Ambrose Bierce, "The Devil's Dictionary"
    @@ -38517,7 +38532,7 @@ Prejudice, n.:
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
     Premature optimization is the root of all evil.
    -		-- D. E. Knuth
    +		-- Donald E. Knuth
     %
     Preserve the old, but know the new.
     %
    @@ -38613,7 +38628,7 @@ PROGRAM:
     	"sales program," or "marketing program"), its implementation
     	always justifies hiring at least three more people.
     %
    -program, n:
    +Program, n.:
     	A magic spell cast over a computer allowing it to turn one's input
     	into error messages.  tr.v. To engage in a pastime similar to banging
     	one's head against a wall, but with fewer opportunities for reward.
    @@ -38632,7 +38647,6 @@ Programming is an unnatural act.
     Programming today is a race between software engineers striving to
     build bigger and better idiot-proof programs, and the Universe trying
     to produce bigger and better idiots.  So far, the Universe is winning.
    -
     		-- Rich Cook
     %
     PROGRESS:
    @@ -38743,11 +38757,11 @@ POPI	Punch Operator Immediately
     PVLC	Punch Variable Length Card
     RASC	Read And Shred Card
     RPM	Read Programmers Mind
    -RSSC	reduce speed, step carefully  (for improved accuracy)
    -RTAB	Rewind tape and break
    -RWDSK	rewind disk
    +RSSC	Reduce Speed, Step Carefully (for improved accuracy)
    +RTAB	Rewind Tape and Break
    +RWDSK	Rewind Disk
     RWOC	Read Writing On Card
    -SCRBL	scribble to disk  - faster than a write
    +SCRBL	Scribble to disk - faster than a write
     SLC	Search for Lost Chord
     SPSW	Scramble Program Status Word
     SRSD	Seek Record and Scar Disk
    @@ -38790,7 +38804,7 @@ three friends.  If they're OK, you're it.
     %
     Psychiatry enables us to correct our faults by confessing our parents'
     shortcomings.
    -		-- Laurence J. Peter, "Peter's Principles"
    +		-- Dr. Laurence J. Peter, "Peter's Principles"
     %
     Psychics will soon lead dogs to your body.
     %
    @@ -38803,7 +38817,7 @@ Psychiatry is the care of the id by the odd.
     Show me a sane man and I will cure him for you.
     		-- Carl G. Jung
     %
    -psychologist, n:
    +Psychologist, n.:
     	Someone who watches everyone else when an attractive woman walks
     	into a room.
     %
    @@ -38860,7 +38874,7 @@ PURITAN:
     Puritanism -- the haunting fear that someone, somewhere, may be happy.
     		-- H. L. Mencken, "A Book of Burlesques"
     %
    -Purpitation, v:
    +Purpitation, v.:
     	To take something off the grocery shelf, decide you
     	don't want it, and then put it in another section.
     		-- Rich Hall & Friends, "Sniglets"
    @@ -38960,8 +38974,8 @@ A:	The tame way!
     %
     Q:	How do you keep a moron in suspense?
     %
    -Q.	How do you keep an Aggie busy at a terminal?
    -A.	While he's not looking, switch it to "local".
    +Q:	How do you keep an Aggie busy at a terminal?
    +A:	While he's not looking, switch it to "local".
     %
     Q:	How do you know when you're in the  section of Vermont?
     A:	The maple sap buckets are hanging on utility poles.
    @@ -39309,8 +39323,8 @@ Q:	What do you call a principal female opera singer whose high C
     	is lower than those of other principal female opera singers?
     A:	A deep C diva.
     %
    -Q.	What do you call a TV set that fixes itself?
    -A.	A Christian Science Monitor.
    +Q:	What do you call a TV set that fixes itself?
    +A:	A Christian Science Monitor.
     %
     Q:	What do you call a WASP who doesn't work for his father, isn't a
     	lawyer, and believes in social causes?
    @@ -39421,7 +39435,7 @@ Q:	What's bruised, bleeding, and lies in a ditch?
     A:	Somebody who tells Aggie jokes.
     %
     Q:	What's tan and black and looks great on a lawyer?
    -A:	A doberman.
    +A:	A Doberman.
     %
     Q:	What's the Blonde's cheer?
     A:	I'm blonde, I'm blonde, I'm B.L.O.N... ah, oh well..
    @@ -39433,8 +39447,8 @@ A:	Artificial intelligence.
     Q:	How do you make a blonde's eyes light up?
     A:	Shine a flashlight in their ear.
     %
    -Q.	What's the capital of Canada?
    -A.	American.
    +Q:	What's the capital of Canada?
    +A:	American.
     %
     Q:	What's the difference between a dead dog in the road and a dead
     	lawyer in the road?
    @@ -39455,8 +39469,8 @@ A:	One more drunk.
     Q:	What's the difference between Bell Labs and the Boy Scouts of America?
     A:	The Boy Scouts have adult supervision.
     %
    -Q.	What's the difference between Los Angeles and yogurt?
    -A.	Yogurt has a living, active culture.
    +Q:	What's the difference between Los Angeles and yogurt?
    +A:	Yogurt has a living, active culture.
     %
     Q:	What's the difference between USL and the Graf Zeppelin?
     A:	The Graf Zeppelin represented cutting edge technology for its time.
    @@ -39507,7 +39521,7 @@ Q:	Why did the germ cross the microscope?
     A:	To get to the other slide.
     %
     Q:	Why did the lone ranger kill Tonto?
    -A:	He found out what "kimosabe" really means.
    +A:	He found out what "kemosabe" really means.
     %
     Q:	Why did the mathematician name his dog "Cauchy"?
     A:	Because he left a residue at every pole.
    @@ -39582,9 +39596,6 @@ A:	It wasn't IBM compatible.
     %
     QED.
     %
    -QOTD:
    -	 "It's not the despair... I can stand the despair.  It's the hope."
    -%
     QOTD:
     	"A child of 5 could understand this!  Fetch me a child of 5."
     %
    @@ -39644,7 +39655,7 @@ QOTD:
     	"I ain't broke, but I'm badly bent."
     %
     QOTD:
    -	"I am not sure what this is, but an 'F' would only dignify it."
    +	"I am not sure what this is, but an `F' would only dignify it."
     %
     QOTD:
     	"I don't think they could put him in a mental hospital.  On the
    @@ -39658,7 +39669,7 @@ QOTD:
     %
     QOTD:
     	"I looked out my window, and saw Kyle Pettys' car upside down,
    -	then I thought 'One of us is in real trouble.'"
    +	then I thought `One of us is in real trouble.'"
     		-- Davey Allison, on a 150 m.p.h. crash
     %
     QOTD:
    @@ -39684,7 +39695,7 @@ QOTD:
     	horse with one of the horns broken off."
     %
     QOTD:
    -	"I treat her like a throughbred, and she's STILL a nag!"
    +	"I treat her like a thoroughbred, and she's STILL a nag!"
     %
     QOTD:
     	"I tried buying a goat instead of a lawn tractor; had to return
    @@ -39789,6 +39800,9 @@ QOTD:
     QOTD:
     	"It's men like him that give the Y chromosome a bad name."
     %
    +QOTD:
    +	"It's not the despair... I can stand the despair.  It's the hope."
    +%
     QOTD:
     	"It's sort of a threat, you see.  I've never been very good at
     	them myself, but I'm told they can be very effective."
    @@ -39967,7 +39981,7 @@ QUARK:
     Quark!  Quark!  Beware the quantum duck!
     %
     question = ( to ) ? be : ! be;
    -		-- Wm. Shakespeare
    +		-- William Shakespeare
     %
     QUESTION AUTHORITY.
     
    @@ -40014,7 +40028,7 @@ Qvid me anxivs svm?
     %
     Radicalism:
     	The conservatism of tomorrow injected into the affairs of today.
    -		-- A. Bierce
    +		-- Ambrose Bierce
     %
     RADIO SHACK LEVEL II BASIC
     READY
    @@ -40042,7 +40056,7 @@ realise that you are in a hurry.
     %
     RAM wasn't built in a day.
     %
    -Random, n:
    +Random, n.:
     	as in number, predictable.
     	as in memory access, unpredictable.
     %
    @@ -40061,7 +40075,7 @@ Do you use the "greasy kid's stuff" to stick down your cowlick?
     Do you wear a "nerd-pack" in your shirt pocket to keep the dozen
     	or so pencils from marking the cloth?
     Do you think Mary Jane is somebody's name?
    -Is illegal fishing is something only a daring criminal would do?
    +Is illegal fishing something only a daring criminal would do?
     Is Batman your hero?  Superman?  Green Lantern?  The Shadow?
     Do you think girls who kiss on the first date are loose?
     
    @@ -40234,8 +40248,8 @@ Real World, The n.:
     be used in the same sentence as FORTRAN, COBOL, RPG, IBM, etc.  2. To
     programmers, the location of non-programmers and activities not related
     to programming.  3. A universe in which the standard dress is shirt and
    -tie and in which a person's working hours are defined as 9 to 5.  4.
    -The location of the status quo.  5. Anywhere outside a university.
    +tie and in which a person's working hours are defined as 9 to 5.
    +4. The location of the status quo.  5. Anywhere outside a university.
     "Poor fellow, he's left MIT and gone into the real world."  Used
     pejoratively by those not in residence there.  In conversation, talking
     of someone who has entered the real world is not unlike talking about a
    @@ -40276,7 +40290,7 @@ cannot be fooled.
     %
     Really??  What a coincidence, I'm shallow too!!
     %
    -Reappraisal, n:
    +Reappraisal, n.:
     	An abrupt change of mind after being found out.
     %
     Rebellion lay in his way, and he found it.
    @@ -40302,14 +40316,14 @@ Just then, Karen Carpenter walks in, sits down at the drums, and says:
     "'Close to You'.  Hit it, boys!"
     		-- Told by Penn Jillette, of magic/comedy duo Penn and Teller
     %
    -Reception area, n:
    +Reception area, n.:
     	The purgatory where office visitors are condemned to spend
     	innumerable hours reading dog-eared back issues of trade
     	magazines like Modern Plastics, Chain Saw Age, and Chicken World,
     	while the receptionist blithely reads her own trade magazine --
     	Cosmopolitan.
     %
    -Recession is when your neighbor loses his job. Depression is when you
    +Recession is when your neighbor loses his job.  Depression is when you
     lose your job.  These economic downturns are very difficult to predict,
     but sophisticated econometric modeling houses like Data Resources and
     Chase Econometrics have successfully predicted 14 of the last 3 recessions.
    @@ -40371,7 +40385,7 @@ knowledge of how to live, nor the smallest instinct about when to die.
     has no need to put up a front of any kind.
     		-- John Ball, "Mark One: the Dummy"
     %
    -Reliable source, n:
    +Reliable source, n.:
     	The guy you just met.
     %
     Religion has done love a great service by making it a sin.
    @@ -40420,7 +40434,7 @@ the first one.
     %
     Remember, if it's being done correctly, here or abroad, it's
     *not* the U.S. Army doing it!
    -		-- Good Morning, Vietnam
    +		-- "Good Morning, Vietnam"
     %
     Remember kids, if there's a loaded gun in the room, be sure
     that you're the one holding it.
    @@ -40518,7 +40532,7 @@ Reporter (to Mahatma Gandhi):
     		Mr. Gandhi, what do you think of Western Civilization?
     Gandhi:		I think it would be a good idea.
     %
    -Reputation, adj:
    +Reputation, adj.:
     	What others are not thinking about you.
     %
     Research is the best place to be: you work your buns off, and if it works
    @@ -40531,7 +40545,7 @@ and think what nobody else has thought.
     Research is what I'm doing when I don't know what I'm doing.
     		-- Wernher von Braun
     %
    -Research, n:
    +Research, n.:
     	Consider Columbus:
     	He didn't know where he was going.
     	When he got there he didn't know where he was.
    @@ -40551,7 +40565,7 @@ is to take the blame for your mistakes.  If they're smart, that is.
     Retirement means that when someone says "Have a nice day", you
     actually have a shot at it.
     %
    -Reunite Gondwondaland!
    +Reunite Gondwanaland!
     %
     Rev. Jim:	What does an amber light mean?
     Bobby:		Slow down.
    @@ -40580,14 +40594,14 @@ Review Questions
     	a pyramid, how soon will Johnson's pyramid be larger than King
     	Tut's?  When will it fall on him?  Will he notice?
     %
    -Revolution, n:
    +Revolution, n.:
     	A form of government abroad.
     %
     Revolution, n.:
     	In politics, an abrupt change in the form of misgovernment.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    -revolutionary, adj:
    +Revolutionary, adj.:
     	Repackaged.
     %
     Rhode's Law:
    @@ -40621,7 +40635,7 @@ Renault:	"I'm shocked!  Shocked!  To find that gambling is
     Croupier (handing money to Renault):
     		"Your winnings, sir."
     Renault:	"Oh.  Thank you very much."
    -		-- Casablanca
    +		-- "Casablanca" (1942)
     %
     Riffle West Virginia is so small that the
     Boy Scout had to double as the town drunk.
    @@ -40641,13 +40655,13 @@ Ritchie's Rule:
     	(2) Paint splashes last longer than the paint job.
     	(3) Search and ye shall find -- but make sure it was lost.
     %
    -Robot, n:
    +Robot, n.:
     	Someone who's been made by a scientist.
     %
    -Robot, n:
    +Robot, n.:
     	University administrator.
     %
    -Robustness, adj:
    +Robustness, adj.:
     	Never having to say you're sorry.
     %
     Rocky's Lemma of Innovation Prevention
    @@ -40711,7 +40725,7 @@ Rudin's Second Law:
     	courses of action, people tend to choose the worst possible
     	course.
     %
    -rugby, n:
    +Rugby, n.:
     	Elegant violence.
     
     	(Rugby players eat their dead.)
    @@ -40792,9 +40806,9 @@ Rules for Good Grammar #4.
     12:	Proofread your writing to see if you any words out.
     13:	Correct speling is essential.
     14:	A preposition is something you never end a sentence with.
    -15:	While a transcendant vocabulary is laudable, one must be eternally
    +15:	While a transcendent vocabulary is laudable, one must be eternally
     	careful so that the calculated objective of communication does not
    -	become ensconsed in obscurity.  In other words, eschew obfuscation.
    +	become ensconced in obscurity.  In other words, eschew obfuscation.
     %
     Rules for Writers:
     	Avoid run-on sentences they are hard to read.  Don't use no double
    @@ -40828,7 +40842,7 @@ RULES OF EATING -- THE BRONX DIETER'S CREED
     	     can always eat it later.
     	(10) Avoid any wine with a childproof cap.
     	(11) Avoid blue food.
    -		-- Richard Smit, "The Bronx Diet"
    +		-- Richard Smith, "The Bronx Diet"
     %
     Ruling a big country is like cooking a small fish.
     		-- Lao Tsu
    @@ -40877,7 +40891,7 @@ Sacred cows make great hamburgers.
     SADISM:
     	A sadist refusing to whip a masochist.
     %
    -sadoequinecrophilia, n:
    +Sadoequinecrophilia, n.:
     	Beating a dead horse.
     %
     Safety Third.
    @@ -41169,7 +41183,7 @@ shoulder.  His eyebrows are raised, matter-of-factly, as he spies the boy
     intently watching him.
     
     Caption:
    -	"I'm sorry you've seen me, Billy.  Now I'll have to kill you.
    +	I'm sorry you've seen me, Billy.  Now I'll have to kill you.
     %
     Schapiro's Explanation:
     	The grass is always greener on the other side --
    @@ -41207,12 +41221,12 @@ To the late night, double feature, Picture show.
     Science is built up of facts, as a house is with stones.  But a
     collection of facts is no more a science than a heap of stones
     is a house.
    -		-- Jules Henri Poincare
    +		-- Jules Henri Poincar'e
     %
     Science is facts; just as houses are made of stones, so is science made
     of facts; but a pile of stones is not a house and a collection of facts
     is not necessarily science.
    -		-- Henri Poincair'e
    +		-- Jules Henri Poincar'e
     %
     Science is like sex: sometimes something useful comes
     out, but that is not the reason we are doing it
    @@ -41238,10 +41252,10 @@ To seek a shelter in some happier star?
     Hast thou not torn the Naiad from her flood,
     The Elfin from the green grass, and from me
     The summer dream beneath the tamarind tree?
    -		-- Edgar Allen Poe, "Science, a Sonnet"
    +		-- Edgar Allan Poe, "Science, a Sonnet"
     %
     Scientists are people who build the Brooklyn Bridge and then buy it.
    -		-- William Buckley
    +		-- William F. Buckley
     
     %
     Scientists still know less about what attracts men
    @@ -41258,11 +41272,11 @@ was a loud crash, and a bolt of lightning came down from the sky,
     struck the computers, and welded all the connections permanently
     together.  "There is now", came the reply.
     %
    -Scintilate, scintilate, globule vivific,
    +Scintillate, scintillate, globule vivific,
     Fain how I pause at your nature specific,
     Loftily poised in the ether capacious,
     Highly resembling a gem carbonaceous.
    -Scintilate, scintilate, globule vivific,
    +Scintillate, scintillate, globule vivific,
     Fain how I pause at your nature specific.
     %
     Scintillation is not always identification for an auric substance.
    @@ -41311,7 +41325,7 @@ Scribline, n.:
     %
     Scrubbing floors and emptying bedpans has as much dignity as the
     Presidency.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     'Scuse me, while I kiss the sky!
     		-- Robert James Marshall (Jimi) Hendrix
    @@ -41337,7 +41351,7 @@ Secrecy is the beginning of tyranny.
     Secretary's Revenge:
     	Filing almost everything under "the".
     %
    -"Section 2.4.3.5   AWNS   (Acceptor Wait for New Cycle State).
    +Section 2.4.3.5   AWNS   (Acceptor Wait for New Cycle State).
     	In AWNS the AH function indicates that it has received a
     multiline message byte.
     	In AWNS the RFD message must be sent false and the DAC message
    @@ -41346,7 +41360,7 @@ must be sent passive true.
     	(1)  The ANRS if DAV is false
     	(2)  The AIDS if the ATN message is false and neither:
     		(a)  The LADS is active
    -		(b)  Nor LACS is active"
    +		(b)  Nor LACS is active
     
     		-- from the IEEE Standard Digital Interface for
     		   Programmable Instrumentation
    @@ -41437,8 +41451,8 @@ register.
     bears know yer there so's they can run away ...  I'll take one fer black
     bears, and one fer them grizzlies.  Say, how do you know yer in grizzly
     country, anyhow?"
    -	"Look fer scatt.  Grizzly scatt's different from black bear scatt."
    -	"Well now, what's IN grizzly scatt that's different?"
    +	"Look fer scat.  Grizzly scat's different from black bear scat."
    +	"Well now, what's IN grizzly scat that's different?"
     	"Bear bells."
     %
     Seems that a pollster was taking a worldwide opinion poll.
    @@ -41625,7 +41639,7 @@ Shannon's Observation
     	Nothing is so frustrating as a bad situation
     	that is beginning to improve.
     %
    -share, n:
    +Share, n.:
     	To give in, endure humiliation.
     %
     Sharks are as tough as those football fans who take their shirts off
    @@ -41693,9 +41707,9 @@ a look that you could have poured on a waffle.
     %
     She often gave herself very good advice
     (though she very seldom followed it).
    -		-- Lewis Carroll
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
    -She ran the gamut of emotions from 'A' to 'B'.
    +She ran the gamut of emotions from "A" to "B".
     		-- Dorothy Parker, on a Kate Hepburn performance
     %
     She say, Miss Colie, You better hush.  God might hear you.
    @@ -41960,7 +41974,7 @@ Sink or Swim with Teddy!
     Sinners can repent, but stupid is forever.
     %
     Sir, it's very possible this asteroid is not stable.
    -		-- CP30
    +		-- C-3PO
     %
     [Sir Stafford Cripps] has all the virtues
     I dislike and none of the vices I admire.
    @@ -42015,7 +42029,7 @@ for deliverance from chains.
     		-- Frederick Douglass
     %
     Sleep -- the most beautiful experience in life -- except drink.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     Sleep is for the weak and sickly.
     %
    @@ -42079,7 +42093,7 @@ Snacktrek, n.:
     	The peculiar habit, when searching for a snack, of constantly
     	returning to the refrigerator in hopes that something new will
     	have materialized.
    -		-- Rich Hall, "Sniglets"
    +		-- Rich Hall & Friends, "Sniglets"
     %
     Snakes.  Why did it have to be snakes?
     %
    @@ -42283,7 +42297,7 @@ COMMUNISM:
     	Give both to the government.  The government gives you milk.
     CAPITALISM:
     	You sell one cow and buy a bull.
    -FACISM:
    +FASCISM:
     	You have two cows.  Give milk to the government.
     	The government sells it.
     NAZISM:
    @@ -42345,7 +42359,7 @@ Some husbands are living proof that a woman can take a joke.
     Some marriages are made in heaven -- but so are thunder and lightning.
     %
     Some men are alive simply because it is against the law to kill them.
    -		-- Ed Howe
    +		-- Edgar W. Howe
     %
     Some men are all right in their place -- if they only the knew the right
     places!
    @@ -42520,7 +42534,7 @@ Some scholars are like donkeys, they merely carry a lot of books.
     Some things have to be believed to be seen.
     %
     Somebody left the cork out of my lunch.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     Somebody ought to cross ball point pens with coat hangers
     so that the pens will multiply instead of disappear.
    @@ -42616,7 +42630,7 @@ Something unpleasant is coming when men are anxious to tell the truth.
     		-- Benjamin Disraeli
     %
     Something's rotten in the state of Denmark.
    -		-- Shakespeare
    +		-- William Shakespeare
     %
     Sometime when you least expect it, Love will tap you on the shoulder...
     and ask you to move out of the way because it still isn't your turn.
    @@ -42669,7 +42683,7 @@ Sometimes love ain't nothing but a misunderstanding between two fools.
     SOMETIMES THE BEAUTY OF THE WORLD is so overwhelming, I just want to throw
     back my head and gargle. Just gargle and gargle and I don't care who hears
     me because I am beautiful.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     Sometimes the best medicine is to stop taking something.
     %
    @@ -42770,7 +42784,7 @@ For he can thoroughly enjoy
     	The pepper when he pleases!
     
     	Wow!  wow!  wow!
    -		-- Lewis Carroll, "Alice in Wonderland"
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     Speak roughly to your little VAX,
     	And boot it when it crashes;
    @@ -42939,7 +42953,7 @@ STANDARDS:
     	The principles we use to reject other people's code.
     %
     Standards are different for all things, so the standard set by man is by
    -no means the only 'certain' standard.  If you mistake what is relative for
    +no means the only "certain" standard.  If you mistake what is relative for
     something certain, you have strayed far from the ultimate truth.
     		-- Chuang Tzu
     %
    @@ -42955,7 +42969,7 @@ on, one-by-one or all in a bunch to back it up!
     		-- Harlan Ellison
     %
     Start every day off with a smile and get it over with.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     Start the day with a smile.
     After that you can be your nasty old self again.
    @@ -42982,7 +42996,7 @@ WHERE THE SMART NY WORK FORCE LIVES	THE MOST OFTEN MISSPELLED STATE
     
     	TEXAS					FLORIDA
           1-2-3 HIKE				ZON KED
    - PLAY FOOTBALL OR DIE			AMERICA'S DRUG DEALER
    +PLAY FOOTBALL OR DIE			AMERICA'S DRUG DEALER
     %
     State license plates we'd like to see:
     
    @@ -43164,7 +43178,7 @@ Style may not be the answer, but at least it's a workable alternative.
     Suaviter in modo, fortiter in re.
     Se non e vero, e ben trovato.
     %
    -Substitute 'damn' every time you're inclined to write 'very'; your
    +Substitute "damn" every time you're inclined to write "very"; your
     editor will delete it and the writing will be just as it should be.
     		-- Mark Twain
     %
    @@ -43330,11 +43344,11 @@ Surprise due today.  Also the rent.
     %
     Surprise your boss.  Get to work on time.
     %
    -sushi, n:
    +Sushi, n.:
     	When that-which-may-still-be-alive is put on top of rice and
     	strapped on with electrical tape.
     %
    -Sushido, n:
    +Sushido, n.:
     	The way of the tuna.
     %
     Suspicion always haunts the guilty mind.
    @@ -43433,7 +43447,7 @@ Fault:			You have fallen forward.
     Action Required:	See above.
     
     Symptom:		Opposite wall covered with acoustic tile and several
    -			flourescent light strips.
    +			fluorescent light strips.
     Fault:			You have fallen over backward.
     Action Required:	If your glass is full and no one is standing on your
     			drinking arm, stay put.  If not, get someone to help
    @@ -43518,7 +43532,7 @@ TAKE FORCEFUL ACTION:
     	Do something that should have been done a long time ago.
     %
     Take heart amid the deepening gloom that your dog is finally getting
    -enough cheese
    +enough cheese.
     		-- National Lampoon, "Deteriorata"
     %
     Take it easy, we're in a hurry.
    @@ -43540,7 +43554,7 @@ Take what you can use and let the rest go by.
     Take your dying with some seriousness, however.
     Laughing on the way to your execution is not generally understood
     by less-advanced life-forms, and they'll call you crazy.
    -		-- Messiah's Handbook: Reminders for the Advanced Soul
    +		-- "Messiah's Handbook: Reminders for the Advanced Soul"
     %
     Take your Senator to lunch this week.
     %
    @@ -43583,7 +43597,7 @@ All together now...
     %
     Tart words make no friends; a spoonful of honey
     will catch more flies than a gallon of vinegar.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     %
     TAURUS (Apr 20 - May 20)
     	You are practical and persistent.  You have a dogged determination
    @@ -43646,7 +43660,7 @@ Technicality, n.:
     	affirm the death of the cook, that being only an inference.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    -Technique?" said the programmer turning from his terminal, "What I follow
    +"Technique?" said the programmer turning from his terminal, "What I follow
     is Tao -- beyond all technique! When I first began to program I would see
     before me the whole problem in one mass. After three years I no longer saw
     this mass.  Instead, I used subroutines.  But now I see nothing.  My whole
    @@ -43656,7 +43670,7 @@ itself.  True, sometimes there are difficult problems.  I see them coming, I
     slow down, I watch silently.  Then I change a single line of code and the
     difficulties vanish like puffs of idle smoke.  I then compile the program.
     I sit still and let the joy of the work fill my being.  I close my eyes for
    -a moment and then log off.
    +a moment and then log off."
     %
     Technological progress has merely provided us
     with more efficient means for going backwards.
    @@ -43777,7 +43791,7 @@ Come, pipe a tune to dance to, lad.
     %
     Term, holidays, term, holidays, till we leave
     school, and then work, work, work till we die.
    -		-- C.S. Lewis
    +		-- C. S. Lewis
     %
     Termiter's argument that God is His own grandmother generated a surprising
     amount of controversy among Church leaders, who on the one hand considered
    @@ -43806,7 +43820,7 @@ Test for paraquat:
     	bicarbonate and sodium dithionite. If paraquat is present,
     	the solution will turn blue-green.
     %
    -Testing can show the presense of bugs, but not their absence.
    +Testing can show the presence of bugs, but not their absence.
     		-- Edsger W. Dijkstra
     %
     Test-tube babies shouldn't throw stones.
    @@ -43924,10 +43938,10 @@ That's life for you, said McDunn.  Someone always waiting for someone
     who never comes home.  Always someone loving something more than that
     thing loves them.  And after awhile you want to destroy whatever that
     thing is, so it can't hurt you no more.
    -		-- R. Bradbury, "The Fog Horn"
    +		-- Ray Bradbury, "The Fog Horn"
     %
     "That's no answer," Job said, "And for someone who's supposed to be
    -omnipotent, let me tell you 'tabernacle' has only one l."
    +omnipotent, let me tell you `tabernacle' has only one l."
     		-- Woody Allen, "Without Feathers"
     %
     That's no moon...
    @@ -44080,7 +44094,7 @@ with which you can threaten your enemies.
     %
     The Anglo-Saxon conscience does not prevent the Anglo-Saxon from
     sinning, it merely prevents him from enjoying his sin.
    -		--Salvador De Madariaga
    +		-- Salvador De Madariaga
     %
     The angry man always thinks he can do more than he can.
     		-- Albertano of Brescia
    @@ -44092,15 +44106,15 @@ doctors nor lawyers.
     The annual meeting of the "You Have To Listen To Experience" Club is now in
     session.  Our Achievement Awards this year are in the fields of publishing,
     advertising and industry.  For best consistent contribution in the field of
    -publishing our award goes to editor, R.L.K., [...] for his unrivaled alle-
    +publishing our award goes to editor, R. L. K., [...] for his unrivaled alle-
     giance without variation to the statement: "Personally I'd love to do it,
     we'd ALL love to do it.  But we're not going to do it.  It's not the kind of
     book our house knows how to handle."  Our superior performance award in the
    -field of advertising goes to media executive, E.L.M., [...] for the continu-
    +field of advertising goes to media executive, E. L. M., [...] for the continu-
     ally creative use of the old favorite: "I think what you've got here could be
     very exciting.  Why not give it one more try based on the approach I've out-
     lined and see if you can come up with something fresh."  Our final award for
    -courageous holding action in the field of industry goes to supervisor, R.S.,
    +courageous holding action in the field of industry goes to supervisor, R. S.,
     [...] for her unyielding grip on "I don't care if they fire me, I've been
     arguing for a new approach for YEARS but are we SURE that this is the right
     time--"  I would like to conclude this meeting with a verse written specially
    @@ -44199,7 +44213,7 @@ The average woman must inevitably view her actual husband with a certain
     disdain; he is anything but her ideal.  In consequence, she cannot help
     feeling that her children are cruelly handicapped by the fact that he is
     their father.
    -		-- Mencken
    +		-- H. L. Mencken
     %
     The average woman would rather have beauty than brains, because the
     average man can see better than he can think.
    @@ -44286,11 +44300,10 @@ Pretty good case:  Get salary from England, build a house in America,
     			live with a Chinese wife, and eat Japanese food.
     The worst case:    Get salary from China, build a house in Japan,
     			live with a British wife, and eat American food.
    -
    -		--Bungei Shunju, a popular Japanese magazine
    +		-- Bungei Shunju, a popular Japanese magazine
     %
     The best cure for insomnia is to get a lot of sleep.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     The best defense against logic is ignorance.
     %
    @@ -44382,7 +44395,7 @@ The better part of valor is discretion.
     %
     The better the state is established, the fainter is humanity.
     To make the individual uncomfortable, that is my task.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     The Bible contains six admonishments to homosexuals and 362 admonishments
     to heterosexuals.  That doesn't mean that God doesn't love heterosexuals.
    @@ -44439,7 +44452,7 @@ The bland leadeth the bland and they both shall fall into the kitsch.
     The bogosity meter just pegged.
     %
     The bold youth of today is very lonely.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     The bomb will never go off.  I speak as an expert in explosives.
     		-- Admiral William Leahy, U.S. Atomic Bomb Project
    @@ -44560,7 +44573,7 @@ sometimes three.
     		-- Alexandre Dumas
     %
     The chicken that clucks the loudest is the one most likely to show up
    -at the steam fitters picnic.
    +at the steam fitters' picnic.
     %
     The chief cause of problems is solutions.
     		-- Eric Sevareid
    @@ -44677,7 +44690,7 @@ central power station is to the electrical industry.
     The Computer made me do it.
     %
     The computing field is always in need of new cliches.
    -		-- Alan Perlis
    +		-- Alan J. Perlis
     %
     The concept seems to be clear by now.  It has been
     defined several times by examples of what it is not.
    @@ -44719,13 +44732,13 @@ talked about.
     The cost of feathers has risen, even down is up!
     %
     The cost of living has just gone up another dollar a quart.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     The cost of living hasn't affected its popularity.
     %
     The cost of living is going up, and the chance of living is going down.
     %
    -The countdown had stalled at 'T' minus 69 seconds when Desiree, the first
    +The countdown had stalled at "T" minus 69 seconds when Desiree, the first
     female ape to go up in space, winked at me slyly and pouted her thick,
     rubbery lips unmistakably -- the first of many such advances during what
     would prove to be the longest, and most memorable, space voyage of my
    @@ -44743,14 +44756,14 @@ ceremoniously handed it to the defendant.
     father!"
     %
     The covers of this book are too far apart.
    -		-- Book review by Ambrose Bierce
    +		-- Ambrose Bierce, reviewing a book
     %
     The cow is nothing but a machine which makes grass fit for us people to eat.
     		-- John McNulty
     %
     The Creation of the Universe was made possible by a grant from Texas
     Instruments.
    -		-- Credits from the PBS program ``The Creation of the Universe''
    +		-- Credits from the PBS program "The Creation of the Universe"
     %
     The Crown is full of it!
     		-- Nate Harris, 1775
    @@ -44762,7 +44775,6 @@ and they are screened at once from scrutiny. ...  In war, then, as in peace,
     assert the freedom of speech and of the press.  Cling to this as the bulwark
     of all our rights and privileges.
     		-- William Ellery Channing
    -
     %
     The curse of the Irish is not that they don't know the
     words to a song -- it's that they know them *all*.
    @@ -44782,7 +44794,7 @@ The dangerous Lego Bomb, which targets shag rugs and scatters pieces of
     plastic that hurt like hell when you step on them is banned entirely....
     Hiring David Copperfield to pretend to saw the missiles in half will not
     be permitted...  In order to reduce risk of accidental war, both sides
    -agree to ban the popular but dangerous 'Simon Says' training drill at
    +agree to ban the popular but dangerous "Simon Says" training drill at
     nuclear launch sites...  Under no circumstances will either side reveal
     that it hammered out the treaty in one afternoon, but spent the last nine
     years arguing the Monty Hall and the three doors problem.
    @@ -44885,7 +44897,7 @@ miles is a long distance and the Americans think 100 years is a long time.
     %
     The difference between art and science is that science is what we
     understand well enough to explain to a computer.  Art is everything else.
    -		-- Donald Knuth, "Discover"
    +		-- Donald E. Knuth, "Discover"
     %
     The difference between common-sense and paranoia is that common-sense is
     thinking everyone is out to get you.  That's normal -- they are.  Paranoia
    @@ -44906,7 +44918,7 @@ is that reality has so little to recommend it.
     %
     The difference between science and the fuzzy subjects is that science
     requires reasoning while those other subjects merely require scholarship.
    -		-- Robert Heinlein
    +		-- Robert A. Heinlein
     %
     The difference between sentiment and being sentimental is the following:
     Sentiment is when a driver swerves out of the way to avoid hitting a
    @@ -44990,7 +45002,7 @@ it to his master.
     %
     The duration of passion is proportionate with the original resistance
     of the woman.
    -		-- Honore DeBalzac
    +		-- Honore de Balzac
     %
     The eagle may soar, but the weasel never gets sucked into a jet engine.
     %
    @@ -45043,17 +45055,17 @@ Compute' -- I forget which."
     %
     The Encyclopaedia Galactica defines a robot as a mechanical apparatus designed
     to do the work of a man.  The marketing division of Sirius Cybernetics
    -Corporation defines a robot as 'Your Plastic Pal Who's Fun To Be With'.
    +Corporation defines a robot as "Your Plastic Pal Who's Fun To Be With".
     The Hitchhiker's Guide to the Galaxy defines the marketing division of the
    -Sirius Cybernetics Corporation as 'a bunch of mindless jerks who'll be the
    -first against the wall when the revolution comes', with a footnote to effect
    +Sirius Cybernetics Corporation as "a bunch of mindless jerks who'll be the
    +first against the wall when the revolution comes", with a footnote to effect
     that the editors would welcome applications from anyone interested in taking
     over the post of robotics correspondent.
     	Curiously enough, an edition of the Encyclopaedia Galactica that
     had the good fortune to fall through a time warp from a thousand years in
     the future defined the marketing division of the Sirius Cybernetics
    -Corporation as 'a bunch of mindless jerks who were the first against the
    -wall when the revolution came'.
    +Corporation as "a bunch of mindless jerks who were the first against the
    +wall when the revolution came".
     %
     The end move in politics is always to pick up a gun.
     		-- Buckminster Fuller
    @@ -45119,7 +45131,7 @@ a substitute for intelligence.
     		-- Lyman Bryson
     %
     The eternal feminine draws us upward.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     The executioner is, I hear, very expert, and my neck is very slender.
     		-- Anne Boleyn
    @@ -45191,7 +45203,9 @@ so long as they are Tories.
     		-- Christopher Booker
     %
     The faster I go, the behinder I get.
    -		-- Lewis Carroll
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     The faster we go, the rounder we get.
     		-- The Grateful Dead
    @@ -45228,7 +45242,7 @@ dull and creepy and humorless and war-oriented like the engineers across the
     quad.  And our most impressive critics have commonly been such English majors,
     and they are squeamish about technology to this very day.  So it is natural
     for them to despise science fiction.
    -		-- Kurt Vonnegut Jr., "Science Fiction"
    +		-- Kurt Vonnegut, Jr., "Science Fiction"
     %
     The fellow sat down at a bar, ordered a drink and asked the bartender if he
     wanted to hear a dumb-jock joke.
    @@ -45387,7 +45401,7 @@ The five rules of Socialism:
     ...the flaw that makes perfection perfect.
     %
     The flow chart is a most thoroughly oversold piece of program documentation.
    -		-- Frederick Brooks, "The Mythical Man Month"
    +		-- Frederick Brooks, Jr., "The Mythical Man-Month"
     %
     The flush toilet is the basis of Western civilization.
     		-- Alan Coult
    @@ -45446,7 +45460,7 @@ vinyl.
     		-- Dave Barry
     %
     [The French Riviera is] a sunny place for shady people.
    -		-- Somerset Maugham
    +		-- W. Somerset Maugham
     %
     The full impact of parenthood doesn't hit you until you multiply the
     number of your kids by thirty-two teeth.
    @@ -45554,7 +45568,7 @@ You can live a life of fun.
     The good life was so elusive
     It really got me down
     I had to regain some confidence
    -So I got into camaflouge
    +So I got into camouflage
     %
     The good time is approaching,
     The season is at hand.
    @@ -45764,7 +45778,7 @@ NOW -- McCLANAHAN!!!
     
     *NOT FOR SISSIES! DON'T COME IF YOU'RE CHICKEN!
     A Horrifying Movie of Weird Beauties and Shocking Monsters...
    -1001 WIERDEST SCENES EVER!!  MOST SHOCKING THRILLER OF THE CENTURY!
    +1001 WEIRDEST SCENES EVER!!  MOST SHOCKING THRILLER OF THE CENTURY!
     		-- Teenage Psycho meets Bloody Mary (1964)  (Alternate Title:
     		   The Incredibly Strange Creatures Who Stopped Living and
     		   Became Mixed Up Zombies)
    @@ -45881,7 +45895,7 @@ SEE Man-Fish Battle Shark-Man-Killer!
     See Jane Russell in 3-D; She'll Knock Both Your Eyes Out!
     		-- The French Line (1954)
     
    -See Jane Russell Shake Her Tamborines... and Drive Cornel WILDE!
    +See Jane Russell Shake Her Tambourines... and Drive Cornel WILDE!
     		-- Hot Blood (1956)
     %
     The Great Movie Posters:
    @@ -45948,7 +45962,7 @@ spokesman said.
     The greatest of faults is to be conscious of none.
     %
     The greatest productive force is human selfishness.
    -		-- Robert Heinlein
    +		-- Robert A. Heinlein
     %
     The greatest remedy for anger is delay.
     %
    @@ -45976,7 +45990,7 @@ you put a lot of relatives on the train for home.
     The hater of property and of government takes care to have his warranty
     deed recorded, and the book written against fame and learning has the
     author's name on the title page.
    -		-- Ralph Waldo Emerson, Journals, 1831
    +		-- Ralph Waldo Emerson, "Journals" (1831)
     %
     The hatred of relatives is the most violent.
     		-- Tacitus (c.55 - c.117)
    @@ -46130,7 +46144,7 @@ no sex, no owner, and a message of importance for every housewife.
     The ideas of economists and political philosophers, both when they
     are right and when they are wrong, are more powerful than is generally
     understood.  Indeed, the world is ruled by little else.
    -		-- John Maynard Keyes
    +		-- John Maynard Keynes
     %
     The identical is equal to itself, since it is different.
     		-- Franco Spisani
    @@ -46168,7 +46182,7 @@ a delight to moralists.  That is why they invented hell.
     %
     The inherent vice of capitalism is the unequal sharing of blessings;
     the inherent virtue of socialism is the equal sharing of misery.
    -		-- Churchill
    +		-- Winston Churchill
     %
     The instruments of science do not in themselves discover truth.  And
     there are searchings that are not concluded by the coincidence of a
    @@ -46622,8 +46636,8 @@ The louder he talked of his honour, the faster we counted our spoons.
     The lovely woman-child Kaa was mercilessly chained to the cruel post of
     the warrior-chief Beast, with his barbarian tribe now stacking wood at
     her nubile feet, when the strong clear voice of the poetic and heroic
    -Handsomas roared, 'Flick your Bic, crisp that chick, and you'll feel my
    -steel through your last meal!'
    +Handsomas roared, "Flick your Bic, crisp that chick, and you'll feel my
    +steel through your last meal!"
     		-- Winning sentence, 1984 Bulwer-Lytton bad fiction contest
     %
     The luck that is ordained for you will be coveted by others.
    @@ -46652,7 +46666,7 @@ The major sin is the sin of being born.
     %
     The majority of husbands remind me of an orangutan trying to play
     the violin.
    -		-- Honore DeBalzac
    +		-- Honore de Balzac
     %
     The majority of the stupid is invincible and guaranteed for all time.
     The terror of their tyranny, however, is alleviated by their lack of
    @@ -46757,7 +46771,7 @@ which, when properly cared for, will rust out in two or three years.
     The mate for beauty should be a man and not a money chest.
     		-- Bulwer
     %
    -The mature bohemian is one whose woman works full time.
    +The mature Bohemian is one whose woman works full time.
     %
     The means-and-ends moralists, or non-doers,
     always end up on their ends without any means.
    @@ -46789,7 +46803,7 @@ The meek will inherit the earth -- if that's OK with you.
     %
     The meeting of two personalities is like the contact of two
     chemical substances: if there is any reaction, both are transformed.
    -		-- Carl Jung
    +		-- Carl G. Jung
     %
     [The members of the Chamberlain government] are decided only to be
     undecided, resolved to be irresolute, adamant for drift, all-powerful
    @@ -46844,7 +46858,7 @@ The Modelski Chain Rule:
     	thrashing anyway, just to show you mean business.
     %
     The modern child will answer you back before you've said anything.
    -		-- Laurence J. Peter
    +		-- Dr. Laurence J. Peter
     %
     "The molars, I'm sure, will be all right, the molars can take care of
     themselves," the old man said, no longer to me.  "But what will become
    @@ -46877,7 +46891,7 @@ lower the mailing cost.
     The more I know men the more I like my horse.
     %
     The more I see of men the more I admire dogs.
    -		-- Mme De Sevigne, 1626-1696
    +		-- Mme De Sevigne (1626-1696)
     %
     The more I want to get something done, the less I call it work.
     		-- Richard Bach, "Illusions"
    @@ -46971,7 +46985,7 @@ the wineyness of a late sun, the intimate kiss of fertilizing rain, and the
     bite of fire.  You must slice it thin, almost as thin as this page you hold
     in your hands.  The making of a ham dinner, like the making of a gentleman,
     starts a long, long time before the event.
    -		-- W.B. Courtney, "Reflections of Maryland Country Ham",
    +		-- W. B. Courtney, "Reflections of Maryland Country Ham",
     		   from "Congress Eate It Up"
     %
     ...the most exquisitely squalid hells known to middle-class man:
    @@ -46980,7 +46994,7 @@ freshman English at a Midwestern university.
     %
     The most happy marriage I can imagine to myself would be the union
     of a deaf man to a blind woman.
    -		-- Samuel Taylor Coleridge
    +		-- Samuel T. Coleridge
     %
     The most hopelessly stupid man is he who is not aware that he is wise.
     %
    @@ -47027,7 +47041,7 @@ an ultimatum which demanded that they disband, this would-be successor to the
     radical student movements of the Sixties promptly voted itself out of
     existence.  As del Borgo and Margaronis put it, "After much chaotic discussion
     and a confused voice vote, the convention suspended all its other work and
    -broke into regional groups to discuss 'outreach.'"
    +broke into regional groups to discuss `outreach.'"
     		-- Libertarian Agenda, May 1988
     %
     The most remarkable thing about my mother is that for thirty years she
    @@ -47088,7 +47102,7 @@ The Net interprets censorship as damage and routes around it.
     The net is like a vast sea of lutefisk with tiny dinosaur brains embedded
     in it here and there. Any given spoonful will likely have an IQ of 1, but
     occasional spoonfuls may have an IQ more than six times that!
    -		-- James 'Kibo' Parry
    +		-- James "Kibo" Parry
     %
     The net of law is spread so wide,
     No sinner from its sweep may hide.
    @@ -47119,7 +47133,7 @@ The New York Times is read by the people who run the country.  The
     Washington Post is read by the people who think they run the country.
     The National Enquirer is read by the people who think Elvis is alive
     and running the country ...
    -		-- Robert J Woodhead
    +		-- Robert J. Woodhead
     %
     The next person to mention spaghetti stacks
     to me is going to have his head knocked off.
    @@ -47233,7 +47247,7 @@ to hang up the cue. When he did, all the other cues came crashing go the
     floor.
     
     "Sorry," he said with a smile.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     The older a man gets, the farther he had to walk to school as a boy.
     %
    @@ -47255,7 +47269,7 @@ The one L lama, he's a priest
     The two L llama, he's a beast
     And I will bet my silk pyjama
     There isn't any three L lllama.
    -		-- O. Nash, to which a fire chief replied that occasionally
    +		-- Ogden Nash, to which a fire chief replied that occasionally
     		his department responded to something like a "three L lllama."
     %
     The One Page Principle:
    @@ -47304,15 +47318,15 @@ swift.  Thinking of oneself gives little happiness.  If, however, one feels
     much happiness in this, it is because at bottom one is not thinking of
     oneself but of one's ideal.  This is far, and only the swift shall reach
     it and are delighted.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     The only "ism" Hollywood believes in is plagiarism.
     		-- Dorothy Parker
     %
     The only justification for our concepts and systems of concepts is
     that they serve to represent the complex of our experiences;
    -beyond this they have not legitimacy.
    -		-- Einstein
    +beyond this they have no legitimacy.
    +		-- Albert Einstein
     %
     The only one of your children who does not grow up and move away
     is your husband.
    @@ -47331,7 +47345,7 @@ The only perfect science is hind-sight.
     The only person who always got his work done by Friday was Robinson Crusoe.
     %
     The only possible interpretation of any research
    -whatever in the 'social sciences' is: some do, some don't.
    +whatever in the "social sciences" is: some do, some don't.
     		-- Ernest Rutherford
     %
     The only problem with being a man of leisure
    @@ -47397,7 +47411,7 @@ the lessons that history has to teach.
     		-- Aldous Huxley
     
     We learn from history that we do not learn from history.
    -		-- Georg Hegel
    +		-- Georg Wilhelm Friedrich Hegel
     
     HISTORY:  Papa Hegel he say that all we learn from history is that we learn
     nothing from history.  I know people who can't even learn from what happened
    @@ -47406,7 +47420,7 @@ this morning.  Hegel must have been taking the long view.
     %
     The only thing we learn from history is that we learn nothing from
     history.
    -		-- Hegel
    +		-- Georg Wilhelm Friedrich Hegel
     
     I know guys can't learn from yesterday ... Hegel must be taking the
     long view.
    @@ -47414,7 +47428,7 @@ long view.
     %
     The only thing which separates man from child is all the values
     he has lost over the years.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     The only time a dog gets complimented is when he doesn't do anything.
     		-- C. Schultz
    @@ -47448,7 +47462,7 @@ of a profound truth may well be another profound truth.
     		-- Niels Bohr
     %
     The opposite of a profound truth may well be another profound truth.
    -		-- Bohr
    +		-- Niels Bohr
     %
     The opposite of talking isn't listening.  The opposite of talking is
     waiting.
    @@ -47913,7 +47927,7 @@ The revolution will not be televised.
     The reward for working hard is more hard work.
     %
     The reward of a thing well done is to have done it.
    -		-- Emerson
    +		-- Ralph Waldo Emerson
     %
     The rhino is a homely beast,
     For human eyes he's not a feast.
    @@ -47933,7 +47947,7 @@ and to his imagination for his facts.
     %
     The right to be heard does not automatically include the right to be
     taken seriously.
    -		-- Hubert Humphrey
    +		-- Hubert H. Humphrey
     %
     The right to be let alone is indeed the beginning of all freedom.
     		-- Justice Douglas
    @@ -47965,7 +47979,7 @@ The road to hell is paved with NAND gates.
     		-- J. Gooding
     %
     The road to ruin is always in good repair,
    -and the travelers pay the expense of it.
    +and the travellers pay the expense of it.
     		-- Josh Billings
     %
     The Roman Rule
    @@ -47985,7 +47999,7 @@ take it too seriously.
     		-- Mike Harding, "The Armchair Anarchist's Almanac"
     %
     The rule is, jam to-morrow and jam yesterday, but never jam today.
    -		-- Lewis Carroll
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     The rule on staying alive as a forecaster is to give 'em a number or
     give 'em a date, but never give 'em both at once.
    @@ -47994,7 +48008,7 @@ give 'em a date, but never give 'em both at once.
     The rules are rather simple to understand:  Under democracy you
     can defend any view, but only defend it.  You can not try to realize
     it through power, violence or weapons.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     The rules:
     
    @@ -48030,8 +48044,8 @@ The savior becomes the victim.
     %
     The scene: in a vast, painted desert, a cowboy faces his horse.
     
    -Cowboy:	"Well, you've been a pretty good hoss, I guess.  Hardworkin'.
    - Not the fastest critter I ever come acrost, but..."
    +Cowboy: "Well, you've been a pretty good hoss, I guess.  Hardworkin'.
    +Not the fastest critter I ever come acrost, but..."
     
     Horse:  "No, stupid, not feed*back*.  I said I wanted a feed*bag*.
     %
    @@ -48040,9 +48054,9 @@ Horse:  "No, stupid, not feed*back*.  I said I wanted a feed*bag*.
     The Schwine-Kitzenger Institute study of 47 men over the age of 100
     showed that all had these things in common:
     
    -	1) They all had moderate appetites.
    -	2) They all came from middle class homes.
    -	3) All but two of them were dead.
    +	(1) They all had moderate appetites.
    +	(2) They all came from middle class homes.
    +	(3) All but two of them were dead.
     %
     The scum also rises.
     		-- Dr. Hunter S. Thompson
    @@ -48125,7 +48139,7 @@ in a direction you did not want.  (Goes the wrong way = Goes a long
     way.)
     		-- Dan Roddick
     %
    -The sixth shiek's sixth sheep's sick.
    +The sixth sheik's sixth sheep's sick.
     		-- [just say that five times...]
     %
     The sky is blue so we know where to stop mowing.
    @@ -48157,7 +48171,7 @@ The so-called "desktop metaphor" of today's workstations is instead an
     "airplane-seat" metaphor.  Anyone who has shuffled a lap full of papers
     while seated between two portly passengers will recognize the difference --
     one can see only a very few things at once.
    -		-- Fred Brooks
    +		-- Frederick Brooks, Jr.
     %
     The so-called lessons of history are for the most part the
     rationalizations of the victors.  History is written by the survivors.
    @@ -48207,7 +48221,7 @@ the table as the children gathered around him.
     sir, I know the answer is Jesus, but it sure sounds like a squirrel to me."
     %
     The sooner all the animals are dead, the sooner we'll find their money.
    -		-- Ed Bluestone, The National Lampoon
    +		-- Ed Bluestone, "The National Lampoon"
     %
     The sooner you fall behind, the more time you'll have to catch up!
     %
    @@ -48322,7 +48336,7 @@ that he has the strength to recognize -- and to live with the recognition --
     that the world is valueless in itself and that all values are human ones.
     He creates himself by fashioning his own values; he has the pride to live
     by the values he wills.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     The student in question is performing minimally for his peer group and
     is an emerging underachiever.
    @@ -48352,7 +48366,9 @@ He did his very best to make
     The billows smooth and bright --
     And this was very odd, because it was
     The middle of the night.
    -		-- Lewis Carroll, "Through the Looking Glass"
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     The sunlights differ, but there is only one darkness.
     		-- Ursula K. LeGuin, "The Dispossessed"
    @@ -48381,7 +48397,7 @@ The surest sign that a man is in love is when he divorces his wife.
     %
     The surest way to corrupt a youth is to instruct him to hold in higher
     esteem those who think alike than those who think differently.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     The surest way to remain a winner is to
     win once, and then not play any more.
    @@ -48436,7 +48452,7 @@ it is the gateway to all wizardry.
     %
     The technician should never forget that he is an artist, the
     artist never that he is a technician.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     The telephone is a good way to talk to people without having to offer
     them a drink.
    @@ -48723,7 +48739,7 @@ And the, um, plains stretch out like my moms girdle, eh?
     There's lotsa beers and doughnuts for everyone, eh?
     So the last one to be peaceful and everything is a big idiot,
     Eh?
    -So shut yer face up and dry yer mucklucks by the fire, eh?
    +So shut yer face up and dry yer mukluks by the fire, eh?
     And dream about girls with their high beams on, eh?
     They may be cold, but that's okay!  Beer's better that way!
     Eh?
    @@ -48755,7 +48771,7 @@ The universe is laughing behind your back.
     %
     The universe is like a safe to which there is a combination -- but the
     combination is locked up in the safe.
    -		-- Peter DeVries
    +		-- Peter de Vries
     
     Corollary: The combination is not a problem since we are locked in the
     same safe.
    @@ -48801,7 +48817,7 @@ regarded as a criminal offence.
     		-- Edsger W. Dijkstra, SIGPLAN Notices, Volume 17, Number 5
     %
     The use of money is all the advantage there is to having money.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     %
     The value of a program is proportional to the weight of its output.
     %
    @@ -48821,7 +48837,7 @@ The very powerful and the very stupid have one thing in common.
     Instead of altering their views to fit the facts, they alter the facts
     to fit their views ... which can be very uncomfortable if you happen to
     be one of the facts that needs altering.
    -		-- Dr. Who, "Face of Evil"
    +		-- The Doctor, "Doctor Who: Face of Evil"
     %
     The very remembrance of my former misfortune proves a new one to me.
     		-- Miguel de Cervantes
    @@ -48908,10 +48924,10 @@ but the leaves are good to smoke!
     		-- The Shadow
     %
     The White Rabbit put on his spectacles.
    -	"Where shall I begin, please your Majesty ?" he asked.
    -	"Begin at the beginning,", the King said, very gravely,
    +	"Where shall I begin, please your Majesty?" he asked.
    +	"Begin at the beginning," the King said, very gravely,
     "and go on till you come to the end: then stop."
    -		-- Lewis Carroll
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     The white race is the cancer of history.
     		-- Susan Sontag
    @@ -48944,7 +48960,7 @@ It must have blown through someone's feet,
     The wise and intelligent are coming belatedly to realize that alcohol, and
     not the dog, is man's best friend.  Rover is taking a beating -- and he
     should.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     The wise man seeks everything in himself;
     the ignorant man tries to get everything from somebody else.
    @@ -49009,7 +49025,7 @@ The world wants to be deceived.
     		-- Sebastian Brant
     %
     The world's as ugly as sin,
    -And almost as delightful
    +And almost as delightful.
     		-- Frederick Locker-Lampson
     %
     The world's great men have not commonly been great scholars,
    @@ -49025,7 +49041,7 @@ pen.
     	Whether death was by drowning, by fits or by runaway sleigh, the
     formula was the same:
     		Have you heard of the dreadful fate
    -		Of Mr. P.P. Bliss and wife?
    +		Of Mr. P. P. Bliss and wife?
     		Of their death I will relate,
     		And also others lost their life
     		(in the) Ashbula Bridge disaster,
    @@ -49093,7 +49109,7 @@ one juror revealed that he was completely deaf and did not have the
     remotest clue what was happening.
     	The judge, Mr. Justice Solomon, asked him if he had heard any
     evidence at all and, when there was no reply, dismissed him.
    -	The excitement which this caused was only equaled when a second
    +	The excitement which this caused was only equalled when a second
     juror revealed that he spoke not a word of English.  A fluent French
     speaker, he exhibited great surprised when told, after two days, that he
     was hearing a murder trial.
    @@ -49201,7 +49217,7 @@ wants and not give in to it, to spend years in silent hurt wondering
     if something could have materialized -- and never knowing.
     		-- David Viscott
     %
    -The Wright Bothers weren't the first to fly.
    +The Wright Brothers weren't the first to fly.
     They were just the first not to crash.
     %
     The yankees, son, are up north.
    @@ -49315,7 +49331,7 @@ THEORY:
     	it will look in print.
     %
     Theory is gray, but the golden tree of life is green.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     Theory of Selective Supervision:
     	The one time in the day that you lean back and relax is
    @@ -49407,7 +49423,7 @@ There are no accidents whatsoever in the universe.
     There are no answers, only cross-references.
     		-- Weiner
     %
    -There are no data that cannot be plotted on a straight line if the axis
    +There are no data that cannot be plotted on a straight line if the axes
     are chosen correctly.
     %
     There are no emotional victims, only volunteers.
    @@ -49478,7 +49494,7 @@ Why don't you go chase them?
     There are some micro-organisms that exhibit characteristics of both
     plants and animals.  When exposed to light they undergo photosynthesis;
     and when the lights go out, they turn into animals.  But then again,
    -don't we all.
    +don't we all?
     %
     There are strange things done in the midnight sun
     	By the men who moil for gold;
    @@ -49501,7 +49517,7 @@ wonder.  There are also those who believe that if you stick your fingers up
     your nose and blow, it will increase your intelligence.
     		-- The Teachings of Ebenezum, Volume VII
     %
    -There are three kinds of lies: lies, damned lies and statistics.
    +There are three kinds of lies: Lies, Damned Lies, and Statistics.
     		-- Benjamin Disraeli
     %
     There are three kinds of people: men, women, and unix.
    @@ -49532,7 +49548,7 @@ long winter evenings.
     %
     There are three rules for writing a novel.
     Unfortunately, no one knows what they are.
    -		-- Maugham
    +		-- W. Somerset Maugham
     %
     There are three schools of magic.  One:  State a tautology, then ring the
     changes on its corollaries; that's philosophy.  Two:  Record many facts.
    @@ -49552,7 +49568,6 @@ love them, suffer for them, or turn them into literature.
     		-- Stephen Stills
     %
     There are three ways to get something done:
    -
     	1: Do it yourself.
     	2: Hire someone to do it for you.
     	3: Forbid your kids to do it.
    @@ -49585,11 +49600,11 @@ I have *never* heard them sound better.  They are *wailing* up here."
     	"The bad news is that God has this girlfriend that sings..."
     %
     There are two kinds of fool.  One says, "This is old, and therefore good."
    -And one says "This is new, and therefore better."
    +And one says, "This is new, and therefore better."
     		-- John Brunner, "The Shockwave Rider"
     %
     There are two kinds of pedestrians... the quick and the dead.
    -		-- Lord Thomas Rober Dewar
    +		-- Lord Thomas Robert Dewar
     %
     There are two kinds of solar-heat systems: "passive" systems collect
     the sunlight that hits your home, and "active" systems collect the
    @@ -49653,7 +49668,7 @@ There cannot be a crisis next week.  My schedule is already full.
     %
     There comes a time in the affairs of a man when he
     has to take the bull by the tail and face the situation.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     There comes a time to stop being angry.
     		-- A Small Circle of Friends
    @@ -49704,7 +49719,7 @@ A:	The elevator would be full.
     There is a certain frame of mind to which a cemetery
     is, if not an antidote, at least an alleviation.  If
     you are in a fit of the blues, go nowhere else.
    -		-- Robert Louis Stevenson: Immortelles
    +		-- Robert Louis Stevenson, "Immortelles"
     %
     There is a certain impertinence in allowing oneself to be burned for an
     opinion.
    @@ -49827,7 +49842,7 @@ man who eats Grapenuts on principle.
     		-- G. K. Chesterton
     %
     There is more to life than increasing its speed.
    -		-- Mahatma Mohandis K. Gandhi
    +		-- Mohandas K. Gandhi
     %
     There is much Obi-Wan did not tell you.
     		-- Darth Vader
    @@ -49842,7 +49857,7 @@ is not capable; for in politics there is no honour.
     		-- Benjamin Disraeli, "Vivian Grey"
     %
     There is no bad taste.  There is only good taste, and that is bad.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     There is no better way of exercising the imagination than the study of law.
     No poet ever interpreted nature as freely as a lawyer interprets truth.
    @@ -49864,7 +49879,7 @@ There is no cure for birth and death other than to enjoy the interval.
     %
     There is no delight the equal of dread.
     As long as it is somebody else's.
    -		--Clive Barker
    +		-- Clive Barker
     %
     There is no distinction between any AI program and some existent game.
     %
    @@ -49873,7 +49888,7 @@ There is no distinctly native American criminal class except Congress.
     %
     There is no doubt that my lawyer is honest.  For example, when he
     filed his income tax return last year, he declared half of his salary
    -as 'unearned income.'
    +as "unearned income."
     		-- Michael Lara
     %
     There is no education that is not political.  An apolitical
    @@ -49992,7 +50007,7 @@ There is not opinion so absurd that some philosopher will not express it.
     		-- Marcus Tullius Cicero, "Ad familiares"
     %
     There is nothing more exhilarating than to be shot at without result.
    -		-- Churchill
    +		-- Winston Churchill
     %
     There is nothing more silly than a silly laugh.
     		-- Gaius Valerius Catullus
    @@ -50040,7 +50055,7 @@ There is only one way to be happy by means of the heart -- to have none.
     		-- Paul Bourget
     %
     There is only one way to console a widow.  But remember the risk.
    -		-- Robert Heinlein
    +		-- Robert A. Heinlein
     %
     There is only one way to kill capitalism --
     by taxes, taxes, and more taxes.
    @@ -50055,7 +50070,7 @@ it would be amusing to know, could we have it authentically communicated.
     		-- James Boswell
     %
     There is plenty of time before progress goes too far.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     There is something in the pang of change
     More than the heart can bear,
    @@ -50078,7 +50093,7 @@ There must be more to life than having everything.
     		-- Maurice Sendak
     %
     There never was a good war or a bad peace.
    -		-- Ben Franklin
    +		-- Benjamin Franklin
     %
     There once was a king who ruled his country long, wisely, and well.  The
     king had a son whom he hoped would someday rule the land.  He also wished
    @@ -50104,10 +50119,10 @@ that I had promised."
     	The king knew that his son would be a great king.
     %
     There seems no plan because it is all plan.
    -		-- C.S. Lewis
    +		-- C. S. Lewis
     %
    -There was a boy called Eustace Clarence Scrubb, and he almost deserved it."
    -		-- C.S. Lewis, "The Chronicles of Narnia"
    +There was a boy called Eustace Clarence Scrubb, and he almost deserved it.
    +		-- C. S. Lewis, "The Chronicles of Narnia"
     %
     There was a little girl
     Who had a little curl
    @@ -50151,7 +50166,7 @@ There was a writer in 'Life' magazine ... who claimed that rabbits have
     no memory, which is one of their defensive mechanisms.  If they recalled
     every close shave they had in the course of just an hour life would become
     insupportable.
    -		-- Kurt Vonnegut
    +		-- Kurt Vonnegut, Jr.
     %
     There was a young man from LeDoux,
     Whose limericks stopped at line two.
    @@ -50281,7 +50296,7 @@ There's a thrill in store for all for we're about to toast
     The corporation that we represent.
     We're here to cheer each pioneer and also proudly boast,
     Of that man of men our sterling president
    -The name of T.J. Watson means
    +The name of T. J. Watson means
     A courage none can stem
     And we feel honored to be here to toast the IBM.
     		-- Ever Onward, from the 1940 IBM Songbook
    @@ -50342,7 +50357,7 @@ There's no justice in this world.
     		   instead)
     %
     There's no point in being grown up if you can't be childish sometimes.
    -		-- Dr. Who
    +		-- The Doctor, "Doctor Who"
     %
     There's no real need to do housework -- after four years it doesn't get
     any worse.
    @@ -50364,7 +50379,7 @@ There's no such thing as an original sin.
     %
     There's no trick to being a humorist when you have the whole government
     working for you.
    -		-- Will Rodgers
    +		-- Will Rogers
     %
     There's no use in having a dog and doing your own barking.
     %
    @@ -50462,7 +50477,7 @@ the only significant job that has so far been given to them.
     They are cold-blooded. They are completely ruthless about protecting
     what they have. The only thing they connect to is the money aspect of
     life.  Let's face it: That's the American way.
    -		-- Jeffery M. Johnson, regional chairman of the District
    +		-- Jeffrey M. Johnson, regional chairman of the District
     		   of Columbia United Way, speaking of drug dealers.
     %
     They are ill discoverers that think there is no land,
    @@ -50509,7 +50524,7 @@ They make a desert and call it peace.
     They say it's the responsibility of the media to look at government --
     especially the president -- with a microscope.  I don't argue with that,
     but when they use a proctoscope, it's going too far.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     They seem to have learned the habit of cowering before authority even when
     not actually threatened.  How very nice for authority.  I decided not to
    @@ -50590,11 +50605,6 @@ for freedom.
     They're giving bank robbing a bad name.
     		-- John Dillinger, on Bonnie and Clyde
     %
    -They're just jealous because they don't have three
    -wise men and a virgin in the whole organization.
    -		-- Mayor Vincent J. `Buddy' Cianci, on the
    -		   ACLU's suit to have a city nativity scene removed.
    -%
     They're only trying to make me LOOK paranoid!
     %
     They're unfriendly, which is fortunate, really.  They'd be difficult
    @@ -50606,7 +50616,7 @@ their property that they may more perfectly respect it.
     		-- G. K. Chesterton, "The Man Who Was Thursday"
     %
     Things are more like they are today than they ever were before.
    -		-- Dwight Eisenhower
    +		-- Dwight D. Eisenhower
     %
     Things are more like they used to be than they are now.
     %
    @@ -50615,7 +50625,7 @@ Things are not always what they seem.
     %
     Things Charles Darwin did not say:
     
    -Finches, eh ? Seen one, seem 'em all.
    +Finches, eh? Seen one, seem 'em all.
     %
     Things Charles Darwin did not say:
     
    @@ -50706,6 +50716,22 @@ This door is baroquen, please wiggle Handel.
     %
     This dungeon is owned and operated by Frobazz Magic Co., Ltd.
     %
    +This email and any files transmitted with it are confidential and
    +intended solely for the use of the individual or entity to which they
    +are addressed. If you are not the intended recipient of this
    +transmission, please delete it immediately.
    +
    +Obviously, I am the idiot who sent it to you by mistake. Furthermore,
    +there is no way I can force you to delete it. Worse, by the time you
    +have reached this disclaimer you have already read the document.
    +Telling you to forget it would seem absurd. In any event, I have no
    +legal right to force you to take any action upon this email anyway.
    +
    +This entire disclaimer is just a waste of everyone's time and
    +bandwidth. Therefore, let us just forget the whole thing and enjoy a
    +cold beer instead.
    + 		-- found on the dovecot mailinglist
    +%
     This file will self-destruct in five minutes.
     %
     This Fortue Examined By INSPECTOR NO. 2-14
    @@ -50829,7 +50855,7 @@ you forget.  Our target is 300 new fortunes by the end of the week.
     Don't miss out.  All fortunes will be acknowledged.  If you contribute
     30 fortunes or more, you will receive a free subscription to "The
     Fortune Hunter", our monthly program guide.  If you contribute 50 or
    -more, you will receive a free "Fortune Hunter" coffee mug ....
    +more, you will receive a free "Fortune Hunter" coffee mug ...
     %
     This is supposed to be a happy occasion.
     Let's not BICKER and ARGUE over who killed who!
    @@ -50840,7 +50866,7 @@ and come alone.  I'm serious!
     %
     This is the first age that's paid much attention to the future,
     which is a little ironic since we may not have one.
    -		-- Arthur Clarke
    +		-- Arthur C. Clarke
     %
     This is the first numerical problem I ever did.  It demonstrates the
     power of computers:
    @@ -50899,7 +50925,7 @@ been called by others the fiddle factor..."
     This land is full of trousers!
     this land is full of mausers!
     	And pussycats to eat them when the sun goes down!
    -		-- Firesign Theater
    +		-- The Firesign Theatre
     %
     This land is made of mountains,
     This land is made of mud,
    @@ -51013,7 +51039,7 @@ adds happiness in a world in which happiness is always in short supply.
     This screen intentionally left blank.
     %
     This sentence contradicts itself -- no actually it doesn't.
    -		-- Hofstadter
    +		-- Douglas Hofstadter
     %
     This sentence does in fact not have the property it claims not to have.
     %
    @@ -51127,7 +51153,7 @@ Those who in quarrels interpose, must often wipe a bloody nose.
     %
     Those who make peaceful revolution impossible
     will make violent revolution inevitable.
    -		-- John Fitzgerald Kennedy
    +		-- John F. Kennedy
     %
     Those who profess to favor freedom, and yet depreciate agitation, are
     men who want rain without thunder and lightning.  They want the ocean
    @@ -51138,7 +51164,7 @@ Those who sweat in flames of hell,	Leaden eared, some thought their bowels
     Here's the reason that they fell:	Lispeth forth the sweetest vowels.
     While on earth they prayed in SAS,	These they offered up in praise
     PL/1, or other crass,			Thinking all this fetid haze
    -Vulgar tongue.				A rapsody sung.
    +Vulgar tongue.				A rhapsody sung.
     
     Some the lord did sorely try		Jabber of the mindless horde
     Assembling all their pleas in hex.	Sequel next did mock the lord
    @@ -51205,12 +51231,12 @@ all appearing on a quiz program, were asked to complete this sentence:
     		service station," said the Missourian.
     	"Wrong."
     	"Old MacDonald had a farm," said the Iowan.
    -	"CORRECT!" shouts the quizmaster.  "Now for $100,000, spell 'farm.'"
    +	"CORRECT!" shouts the quizmaster.  "Now for $100,000, spell `farm.'"
     	"Easy," said the Iowan. "E-I-E-I-O."
     %
     Three minutes' thought would suffice to find this out; but thought
     is irksome and three minutes is a long time.
    -		-- A. E. Houseman
    +		-- A. E. Housman
     %
     Three o'clock in the afternoon is always just a little too
     late or a little too early for anything you want to do.
    @@ -51386,7 +51412,7 @@ but I don't always approve of Time's methods.
     Time-sharing is the junk-mail part of the computer business.
     		-- H. R. J. Grosch (attributed)
     %
    -timesharing, n:
    +Timesharing, n.:
     	An access method whereby one computer abuses many people.
     %
     Timing must be perfect now.
    @@ -51473,7 +51499,7 @@ To add insult to injury.
     To announce that there must be no criticism of the president, or that we are
     to stand by the president right or wrong, is not only unpatriotic and
     servile, but is morally treasonable to the American public."
    -		--  Theodore Roosevelt
    +		-- Theodore Roosevelt
     %
     To any truly impartial person, it would
     be obvious that I am always right.
    @@ -51531,7 +51557,7 @@ To be loved is very demoralizing.
     To be nobody-but-yourself in a world which is doing its best to,
     night and day, to make you everybody else -- means to fight the hardest
     battle which any human being can fight; and never stop fighting.
    -		-- E.E. Cummings, "A Miscellany"
    +		-- e. e. cummings, "A Miscellany"
     %
     To be or not to be.
     		-- Shakespeare
    @@ -51747,7 +51773,7 @@ To many, total abstinence is easier than perfect moderation.
     TO ME, CLOWNS AREN'T FUNNY. In fact, they're kinda scary. I've wondered
     where this started, and I think it goes back to the time I went to the
     circus and a clown killed my dad.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     To one large turkey add one gallon of vermouth and a demijohn of Angostura
     bitters.  Shake.
    @@ -51782,7 +51808,7 @@ There was nothing savage in the act, although the knife was large and keen;
     it was a piece of art, high art; there was delicacy of touch, clearness of
     tone, skillful handling of the subject, fine shading.  It was the triumph of
     mind over matter; quite.
    -		-- Dickens, "Martin Chuzzlewit"
    +		-- Charles Dickens, "Martin Chuzzlewit"
     %
     To see you is to sympathize.
     %
    @@ -51931,7 +51957,7 @@ Today is the first day of the rest of your lossage.
     %
     Today is the last day of your life so far.
     %
    -Today is the tomorrow you worried about yesterday
    +Today is the tomorrow you worried about yesterday.
     %
     Today is what happened to yesterday.
     %
    @@ -51960,7 +51986,7 @@ Today's weirdness is tomorrow's reason why.
     %
     Toddlers are the stormtroopers of the Lord of Entropy.
     %
    -Toilet Toupee, n:
    +Toilet Toupee, n.:
     	Any shag carpet that causes the lid to become top-heavy, thus
     	creating endless annoyance to male users.
     		-- Rich Hall, "Sniglets"
    @@ -51994,7 +52020,7 @@ driving cabs and cutting hair.
     %
     TOO BAD YOU CAN'T BUY a voodoo globe so that you could make the earth spin
     real fast and freak everybody out.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     Too clever is dumb.
     		-- Ogden Nash
    @@ -52075,7 +52101,7 @@ Follow these simple suggestions:
     (2)  Use tape, magnets, or glue instead of paperweights.
     (3)  Give up skiing and skydiving for more horizontal sports like
          curling.
    -(4)  Avoid showers .. take baths instead.
    +(4)  Avoid showers ... take baths instead.
     (5)  Don't hang all your clothes in the closet ... Keep them in one big
          pile.
     (6)  Stop flipping pancakes
    @@ -52093,7 +52119,7 @@ Top Ten Things Overheard At The ANSI C Draft Committee Meetings:
      4:	How many times do we have to tell you, "No prior art!"
      3:	Ha, ha, I can't believe they're actually going to adopt this sucker.
      2:	Thank you for your generous donation, Mr. Wirth.
    - 1:	Gee, I wish we hadn't backed down on 'noalias'.
    + 1:	Gee, I wish we hadn't backed down on "noalias".
     %
     Topologists are just plane folks.
     	Pilots are just plane folks.
    @@ -52671,7 +52697,7 @@ And the hunter home from the hill.
     Underlying Principle of Socio-Genetics:
     	Superiority is recessive.
     %
    -understand, v:
    +Understand, v.:
     	To reach a point, in your investigation of some subject, at which
     	you cease to examine what is really present, and operate on the
     	basis of your own internal model instead.
    @@ -52706,13 +52732,13 @@ every persuasion.  Meanwhile, fears of universal disaster sank to an all-time
     low over the world.
     		-- Isaac Asimov
     %
    -universe, n:
    +Universe, n.:
     	The problem.
     %
     Universities are places of knowledge.  The freshman each bring a little
     in with them, and the seniors take none away, so knowledge accumulates.
     %
    -UNIVERSITY:
    +University, n.:
     	Like a software house, except the software's free, and it's
     	usable, and it works, and if it breaks they'll quickly tell
     	you how to fix it, and...
    @@ -52730,7 +52756,7 @@ of more feet, just to be sure.
     		-- Eric Allman
     
     ... We make rope.
    -		-- Rob Gingell on Sun Microsystem's new virtual memory
    +		-- Rob Gingell on Sun Microsystems' new virtual memory
     %
     Unix is a lot more complicated (than CP/M) of course -- the typical Unix
     hacker can never remember what the PRINT command is called this week --
    @@ -52753,7 +52779,7 @@ but it's never been everything to anybody.
     Unix is the worst operating system; except for all others.
     		-- Berry Kercheval
     %
    -Unix, n:
    +Unix, n.:
     	A computer operating system, once thought to be flabby and
     	impotent, that now shows a surprising interest in making off
     	with the workstation harem.
    @@ -52762,7 +52788,7 @@ unix soit qui mal y pense
     %
     UNIX was half a billion (500000000) seconds old on
     Tue Nov  5 00:53:20 1985 GMT (measuring since the time(2) epoch).
    -		-- Andy Tannenbaum
    +		-- Andrew S. Tanenbaum
     %
     UNIX was not designed to stop you from doing stupid things, because that
     would also stop you from doing clever things.
    @@ -52783,7 +52809,7 @@ time waste me.
     		-- William Shakespeare
     %
     Unless you love someone, nothing else makes any sense.
    -		-- E.E. Cummings
    +		-- e. e. cummings
     %
     Unnamed Law:
     	If it happens, it must be possible.
    @@ -52797,7 +52823,7 @@ pays out twice as much in taxes as he formerly got in wages.
     		-- H. L. Mencken
     %
     Until Eve arrived, this was a man's world.
    -		-- Richard Amour
    +		-- Richard Armour
     %
     UNTOLD WEALTH:
     	What you left out on April 15th.
    @@ -52824,10 +52850,10 @@ more labor and less oratory.
     %
     User hostile.
     %
    -User n.:
    +User, n.:
     	A programmer who will believe anything you tell him.
     %
    -user, n:
    +User, n.:
     	The word computer professionals use when they mean "idiot."
     		-- Dave Barry, "Claw Your Way to the Top"
     
    @@ -52960,7 +52986,7 @@ X:
     %
     Victory uber allies!
     %
    -Viking, n:
    +Viking, n.:
     	1. Daring Scandinavian seafarers, explorers, adventurers,
     	entrepreneurs world-famous for their aggressive, nautical import
     	business, highly leveraged takeovers and blue eyes.
    @@ -52989,7 +53015,7 @@ Violence is a sword that has no handle -- you have to hold the blade.
     Violence is molding.
     %
     Violence is the last refuge of the incompetent.
    -		-- Salvador Hardin
    +		-- Salvor Hardin
     %
     Violence stinks, no matter which end of it you're on.  But now and then
     there's nothing left to do but hit the other person over the head with a
    @@ -53047,11 +53073,11 @@ Visits always give pleasure: if not on arrival, then on the departure.
     Vital papers will demonstrate their vitality by spontaneously moving
     from where you left them to where you can't find them.
     %
    -Vitamin C deficiency is apauling
    +Vitamin C deficiency is apauling.
     %
     VMS is like a nightmare about RSX-11M.
     %
    -VMS, n:
    +VMS, n.:
     	The world's foremost multi-user adventure game.
     %
     VMS version 2.0 ==>
    @@ -53101,7 +53127,7 @@ Wagner's music is better than it sounds.
     Wait for that wisest of all counselors, Time.
     		-- Pericles
     %
    -Waiter:	"Tea or coffee, gentlemen?"
    +Waiter: "Tea or coffee, gentlemen?"
     1st customer: "I'll have tea."
     2nd customer: "Me, too -- and be sure the glass is clean!"
     	(Waiter exits, returns)
    @@ -53160,11 +53186,11 @@ Wanna tell you all a story 'bout a man named Jed,
     A poor mountaineer, barely kept his family fed.
     But then one day he was shootin' at some food,
     When up through the ground come a bubblin' crude -- oil, that is;
    -	black gold; 'Texas tea' ...
    +	black gold; "Texas tea" ...
     
     Well the next thing ya know, old Jed's a millionaire.
    -The kinfolk said, 'Jed, move away from there!'
    -They said, 'Californy is the place ya oughta be',
    +The kinfolk said, "Jed, move away from there!"
    +They said, "Californy is the place ya oughta be",
     So they loaded up the truck and they moved to Beverly -- Hills, that is;
     	swimmin' pools; movie stars.
     %
    @@ -53322,7 +53348,7 @@ We are all in the gutter, but some of us are looking at the stars.
     		-- Oscar Wilde
     %
     We are all so much together and yet we are all dying of loneliness.
    -		-- A. Schweitzer
    +		-- Albert Schweitzer
     %
     We are all worms.  But I do believe I am a glowworm.
     		-- Winston Churchill
    @@ -53337,7 +53363,7 @@ We are confronted with insurmountable opportunities.
     		-- Walt Kelly, "Pogo"
     %
     We are drowning in information but starved for knowledge.
    -		-- John Naisbitt, Megatrends
    +		-- John Naisbitt, "Megatrends"
     %
     We are each entitled to our own opinion, but no one is entitled to his
     own facts.
    @@ -53386,7 +53412,7 @@ Manual.
     We are simple killers of people and destroyers of property.
     %
     We are so fond of each other because our ailments are the same.
    -		-- Jonathon Swift
    +		-- Jonathan Swift
     %
     We are sorry.  We cannot complete your call as dialed.  Please check
     the number and dial again or ask your operator for assistance.
    @@ -53407,7 +53433,7 @@ to do the unnecessary... for the ungrateful...
     %
     We are unavoidably drawn towards conservatism and death.
     The order is not insignificant.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     We are upping our standards ... so up yours.
     		-- Pat Paulsen for President, 1988
    @@ -53437,11 +53463,11 @@ deceased.  My suggestion, therefore, is that you drop dead.
     		-- James E. Day, Postmaster General
     %
     We could do that, but it would be wrong, that's for sure.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     We could nuke Baghdad into glass, wipe it with Windex, tie fatback on our
     feet and go skating.
    -		-- Fred Reed, Air Force Times columnist.
    +		-- Fred Reed, Air Force Times columnist
     %
     We dedicate this book to our fellow citizens who, for love of truth,
     take from their own wants by taxes and gifts, and now and then send
    @@ -53518,13 +53544,13 @@ If it's the last thing we ever do.
     We had it tough ... I had to get up at 9 o'clock at night, half an
     hour before I went to bed, eat a lump of dry poison, work 29 hours down
     mill, and when we came home our Dad would kill us, and dance about on
    -our grave singing Halleluja ...
    +our grave singing Hallelujah ...
     		-- Monty Python
     %
     We have an equal opportunity Calculus class -- it's fully integrated.
     %
     We have art that we do not die of the truth.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     We have ears, earther...FOUR OF THEM!
     %
    @@ -53584,7 +53610,7 @@ You know the kind of flu I'm talking about.
     %
     We interrupt this fortune for an important announcement...
     %
    -"We invented a new protocol and called it Kermit, after Kermit the Frog,
    +We invented a new protocol and called it Kermit, after Kermit the Frog,
     star of "The Muppet Show." [3]
     
     [3]  Why?  Mostly because there was a Muppets calendar on the wall when we
    @@ -53703,8 +53729,8 @@ We must die because we have known them.
     		-- Ptah-hotep, 2000 B.C.
     %
     We must finish once and for all with the neutrality of chess.  We must
    -condemn once and for all the formula 'chess for the sake of chess,' like
    -the formula 'art for art's sake.'  We must organize shock-brigades of
    +condemn once and for all the formula "chess for the sake of chess," like
    +the formula "art for art's sake."  We must organize shock-brigades of
     chess-players, and begin the immediate realization of a Five-Year Plan
     for chess.
     		-- Nikolai V. Krylenko, People's Commissar for Justice
    @@ -53734,7 +53760,7 @@ children smart.
     %
     We only acknowledge small faults in order
     to make it appear that we are free from great ones.
    -		-- LaRouchefoucauld
    +		-- La Rochefoucauld
     %
     We ought to be very grateful that we have tools.  Millions of years ago
     people did not have them, and home projects were extremely difficult.
    @@ -53769,7 +53795,7 @@ We secure our friends not by accepting favors but by doing them.
     %
     We seem to have forgotten the simple truth that reason is never perfect.
     Only non-sense attains perfection.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     We seldom repent talking too little, but very often talking too much.
     		-- Jean de la Bruyere
    @@ -54048,12 +54074,12 @@ James Bond kills him and his henchmen and makes love to several attractive
     women.  There, that's it: 24 words.  But the guy who wrote the book took
     *thousands* of words to say it.
     	Or consider "The Brothers Karamazov", by the famous Russian alcoholic
    -Fyodor Dostoevsky.  It's about these two brothers who kill their father.
    +Fyodor Dostoyevsky.  It's about these two brothers who kill their father.
     Or maybe only one of them kills the father.  It's impossible to tell because
     what they mostly do is talk for nearly a thousand pages.  If all Russians talk
     as much as the Karamazovs did, I don't see how they found time to become a
     major world power.
    -	I'm told that Dostoevsky wrote "The Brothers Karamazov" to raise
    +	I'm told that Dostoyevsky wrote "The Brothers Karamazov" to raise
     the question of whether there is a God.  So why didn't he just come right
     out and say: "Is there a God? It sure beats the heck out of me."
     	Other famous works could easily have been summarized in a few words:
    @@ -54403,7 +54429,7 @@ Cooper and Claudette Colbert, and to be beaten up by both of them!
     %
     What a misfortune to be a woman!  And yet, the worst misfortune is not to
     understand what a misfortune it is.
    -		-- Kierkegaard, 1813-1855
    +		-- S. A. Kierkegaard (1813-1855)
     %
     What a strange game.  The only winning move is not to play.
     		-- WOP, "War Games"
    @@ -54474,7 +54500,7 @@ and their young frontiersmen, will require to lead us onward and upward.
     		-- Dr. Harrison H. Schmidt
     %
     What does not destroy me, makes me stronger.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     What ever happened to happily ever after?
     %
    @@ -54495,7 +54521,7 @@ What garlic is to salad, insanity is to art.
     What George Washington did for us was to throw out the British, so
     that we wouldn't have a fat, insensitive government running our
     country. Nice try anyway, George.
    -		-- D.J. on KSFO/KYA
    +		-- Disk Jockey on KSFO/KYA
     %
     What goes up must come down.  But don't expect it to come down
     where you can find it.  Murphy's Law applied to Newton's.
    @@ -54636,7 +54662,7 @@ What is love but a second-hand emotion?
     %
     What is mind?  No matter.
     What is matter?  Never mind.
    -		-- Thomas Hewitt Key, 1799-1875
    +		-- Thomas Hewitt Key (1799-1875)
     %
     What is now proved was once only imagin'd.
     		-- William Blake
    @@ -54737,7 +54763,7 @@ What one believes to be true either is true or becomes true.
     		-- John Lilly
     %
     What one fool can do, another can.
    -		-- Ancient Simian Proverb
    +		-- Ancient Simian proverb
     %
     What orators lack in depth they make up in length.
     %
    @@ -54941,16 +54967,16 @@ What this country needs is a good five cent ANYTHING!
     %
     What this country needs is a good five cent microcomputer.
     %
    -What this country needs is a good five dollar plasma weapon.
    +What this country needs is a good five cent nickel.
     %
    -What this country needs is a good five-cent nickel.
    +What this country needs is a good five dollar plasma weapon.
     %
     What time is it?
     I don't know, it keeps changing.
     %
     What upsets me is not that you lied to me,
     but that from now on I can no longer believe you.
    -		-- Nietzsche
    +		-- Friedrich Nietzsche
     %
     What use is magic if it can't save a unicorn?
     		-- Peter S. Beagle, "The Last Unicorn"
    @@ -54962,7 +54988,7 @@ What we cannot speak about we must pass over in silence.
     		-- Wittgenstein
     %
     What we do not understand we do not possess.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     What we need in this country, instead of Daylight Savings Time, which
     nobody really understands anyway, is a new concept called Weekday
    @@ -55053,7 +55079,7 @@ as good.  Luckily this is not difficult.
     %
     Whatever you do will be insignificant,
     but it is very important that you do it.
    -		-- Gandhi
    +		-- Mahatma Gandhi
     %
     Whatever you may be sure of, be sure of this: that you are dreadfully like
     other people.
    @@ -55088,7 +55114,7 @@ But I think it's your mind.
     		-- Frank Zappa, 1965
     %
     What's the use of a good quotation if you can't change it?
    -		-- Dr. Who
    +		-- The Doctor, "Doctor Who"
     %
     What's this stuff about people being "released on their
     own recognizance"?  Aren't we all out on own recognizance?
    @@ -55103,7 +55129,7 @@ When a cow laughs, does milk come out of its nose?
     %
     When a fellow says, "It ain't the money but
     the principle of the thing," it's the money.
    -		-- Kim Hubbard
    +		-- Kin Hubbard
     %
     When a fly lands on the ceiling, does it do a half roll or a half
     loop?
    @@ -55177,7 +55203,7 @@ poor.  In that lawsuit, you will lose.  If, on the other hand, you kill
     him, the most that you can expect is that a relative will bring a wrongful
     death action. You will have two advantages: first, there be only your
     story; forget Mother Teresa.  Second, even if you lose, how much could
    -the bum's life be worth anyway?  A Lot less than 50 years worth of
    +the bum's life be worth anyway?  A lot less than 50 years worth of
     paralysis.  Don't play George Bush and Saddam Hussein.  Finish the job.
     		-- G. Gordon Liddy's Forbes column on personal security
     %
    @@ -55245,7 +55271,7 @@ that, after assuming the power, we would deny to our adversaries without any
     consideration the means which were granted to us in times of our opposition.
     		-- Josef Goebbels
     %
    -When Dexter's on the Internet, can Hell be far behind?"
    +When Dexter's on the Internet, can Hell be far behind?
     %
     When does later become never?
     %
    @@ -55298,7 +55324,7 @@ then sit in my car and count how many people ask me if I'm leaving.
     %
     When I grow up, I want to be an honest
     lawyer so things like that can't happen.
    -		-- Richard Nixon, as a boy, on the Teapot Dome scandal
    +		-- Richard M. Nixon, as a boy, on the Teapot Dome scandal
     %
     When I have one foot in the grave I will tell the truth about women.  I
     shall tell it, jump into my coffin, pull the lid over me, and say, "Do
    @@ -55332,7 +55358,7 @@ to myself, "I've got to get out of this lane."
     When I say the magic word to all these people, they will vanish forever.
     I will then say the magic words to you, and you, too, will vanish -- never
     to be seen again.
    -		-- Kurt Vonnegut Jr., "Between Time and Timbuktu"
    +		-- Kurt Vonnegut, Jr., "Between Time and Timbuktu"
     %
     When I sell liquor, it's called bootlegging; when my patrons serve
     it on silver trays on Lake Shore Drive, it's called hospitality.
    @@ -55537,7 +55563,7 @@ Behind blue eyes.
     No one knows what its like to be hated,
     	to be fated,
     To telling only lies.
    -		-- The Who
    +		-- The Who, "Behind Blue Eyes"
     %
     When my freshman roommate at Cornell found out I was Jewish, she was,
     at her request, moved to a different room.  She told me she didn't
    @@ -55611,7 +55637,7 @@ is away and you get twice as much done.
     		-- Daniel B. Luten
     %
     When smashing monuments, save the pedestals -- they always come in handy.
    -		-- Stanislaw J. Lem, "Unkempt Thoughts"
    +		-- Stanislaw J. Lec, "Unkempt Thoughts"
     %
     When some people decide it's time for everyone to make
     big changes, it means that they want you to change first.
    @@ -55679,7 +55705,7 @@ When the candles are out all women are fair.
     When the cup is full, carry it level.
     %
     When the doubt vanishes and the issue becomes evident, stupidity reigns.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     When the English language gets in my way, I walk over it.
     		-- Billy Sunday
    @@ -55738,7 +55764,7 @@ When the only tool you have is a hammer, every problem starts to look
     like a nail.
     %
     When the President does it, that means it is not illegal.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     When the revolution comes, count your change.
     %
    @@ -55787,7 +55813,7 @@ is to believe the one in which people appear at their worst.
     		-- H. Allen Smith, "Let the Crabgrass Grow"
     %
     When there is an old maid in the house, a watch dog is unnecessary.
    -		-- Balzac
    +		-- Honore de Balzac
     %
     When things go well, expect something to
     explode, erode, collapse or just disappear.
    @@ -55844,7 +55870,7 @@ When women kiss it always reminds one of prize fighters shaking hands.
     When women love us, they forgive us everything, even our crimes;
     when they do not love us, they give us credit for nothing, not
     even our virtues.
    -		-- Balzac
    +		-- Honore de Balzac
     %
     When you are about to die, a wombat is better than no company at all.
     		-- Roger Zelazny, "Doorways in the Sand"
    @@ -55948,7 +55974,7 @@ When you have to kill a man it costs nothing to be polite.
     %
     When you jump for joy, beware that no-one
     moves the ground from beneath your feet.
    -		-- Stanislaw Lem, "Unkempt Thoughts"
    +		-- Stanislaw J. Lec, "Unkempt Thoughts"
     %
     When you know absolutely nothing about the topic, make your forecast by
     asking a carefully selected probability sample of 300 others who don't
    @@ -56021,7 +56047,7 @@ You're driving a Beamer.
     When you're away, I'm restless, lonely
     Wretched, bored, dejected, only
     Here's the rub, my darling dear,
    -I feel the same when you are hear.
    +I feel the same when you are near.
     		-- Samuel Hoffenstein, "Poems in Praise of Practically Nothing"
     %
     When you're bored with yourself, marry, and be bored with someone else.
    @@ -56047,12 +56073,12 @@ When you're ready to give up the struggle, who can you surrender to?
     %
     WHEN YOU'RE RIDING IN A TIME MACHINE way far into the future, don't stick
     your elbow out the window or it'll turn into a fossil.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     WHENEVER ANYBODY SAYS he's struggling to become a human being I have to
     laugh because the apes beat him to it by about a million years.  Struggle
     to become a parrot or something.
    -		-- Jack Handey, The New Mexican, 1988
    +		-- Jack Handey, "The New Mexican" (1988)
     %
     Whenever anyone says, "theoretically," they really mean "not really".
     		-- Dave Parnas
    @@ -56160,7 +56186,7 @@ Where there are visible vapors, having their prevenance
     in ignited carbonaceous materials, there is conflagration.
     %
     Where there is much light there is also much shadow.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     Where there's a whip there's a way.
     %
    @@ -56337,11 +56363,11 @@ Who does not trust enough will not be trusted.
     Who goeth a-borrowing goeth a-sorrowing.
     		-- Thomas Tusser
     %
    -Who is D.B. Cooper, and where is he now?
    +Who is D. B. Cooper, and where is he now?
     %
     Who is John Galt?
     %
    -Who is W.O. Baker, and why is he saying those terrible things about me?
    +Who is W. O. Baker, and why is he saying those terrible things about me?
     %
     Who loves me will also love my dog.
     		-- John Donne
    @@ -56390,7 +56416,7 @@ Whoever named it "necking" was a poor judge of anatomy.
     %
     Whoever tells a lie cannot be pure in heart -- and only the
     pure in heart can make a good soup.
    -		-- Ludwig Van Beethoven
    +		-- Ludwig van Beethoven
     %
     Whoever would lie usefully should lie seldom.
     %
    @@ -56626,7 +56652,7 @@ you knowing nothing?
     %
     Why my thoughts are my own, when they are in, but when they are out they
     are another's.
    -		 -- Susanna Martin, executed for witchcraft, 1681
    +		-- Susanna Martin, executed for witchcraft, 1681
     %
     Why not? -- What? -- Why not? -- Why should I not send it? -- Why should I
     not dispatch it? -- Why not? -- Strange!  I don't know why I shouldn't --
    @@ -56690,7 +56716,7 @@ Why You Can't Run When There's Trouble in the Office:
     	No matter where you stand, no matter how far or fast you flee,
     when it hits the fan, as much as possible will be propelled in your
     direction, and almost none will be returned to the source.
    -		-- John L.  Shelton
    +		-- John L. Shelton
     %
     Why you say you no bunny rabbit when you have little powder-puff tail?
     		-- The Tasmanian Devil
    @@ -56729,7 +56755,7 @@ Mother cried, "Now, William, stop!"	I haven't the heart to poke poor Billy.
     William with a thirst for gore,		Little Willie mean as hell,
     Nailed the baby to the door.		Threw his sister in the well!
     Mother said, with humor quaint:		Said his mother when drawing water,
    -"Careful, Will, don't mar the paint."	'sure is hard to raise a daughter.'
    +"Careful, Will, don't mar the paint."	"sure is hard to raise a daughter."
     		-- Harry Graham, "Ruthless Rhymes for Heartless Homes", 1899
     %
     Wilner's Observation:
    @@ -56868,7 +56894,7 @@ Hundred billion castaways looking for a call.
     WOLF:
     	A man who knows all the ankles.
     %
    -Woman:	    "Is Yoo-Hoo hyphenated?"
    +Woman:      "Is Yoo-Hoo hyphenated?"
     Yogi Berra: "No, ma'am, its not even carbonated."
     %
     Woman inspires us to great things, and prevents us from achieving them.
    @@ -56926,7 +56952,7 @@ Women are just like men, only different.
     %
     Women are like elephants to me: I like to
     look at them, but I wouldn't want to own one.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     Women are not much, but they are the best other sex we have.
     		-- Herold
    @@ -56944,7 +56970,7 @@ Women can keep a secret just as well as men,
     but it takes more of them to do it.
     %
     Women come and go, but BSD is forever.
    -				-- Derek Young
    +		-- Derek Young
     %
     Women complain about sex more than men.  Their gripes fall into two
     categories: (1) Not enough and (2) Too much.
    @@ -56969,7 +56995,7 @@ crying, a little dying -- and a good deal of lying.
     Women of genius commonly have masculine faces, figures and manners.
     In transplanting brains to an alien soil God leaves a little of the
     original earth clinging to the roots.
    -		-- Bierce
    +		-- Ambrose Bierce
     %
     Women reason with the heart and are much less often wrong
     than men who reason with the head.
    @@ -56990,15 +57016,15 @@ than being slapped is when you get on your knees and say you're sorry.
     %
     Women waste men's lives and think they have
     indemnified them by a few gracious words.
    -		-- Balzac
    +		-- Honore de Balzac
     %
     Women, when they are not in love, have all
     the cold blood of an experienced attorney.
    -		-- Balzac
    +		-- Honore de Balzac
     %
     Women, when they have made a sheep of a man,
     always tell him that he is a lion with a will of iron.
    -		-- Balzac
    +		-- Honore de Balzac
     %
     Women who want to be equal to men lack imagination.
     %
    @@ -57195,7 +57221,7 @@ a valentine.
     		-- Christopher Plummer
     %
     World tensions have, if anything, increased in the quarter century
    -since H.G. Wells uttered his glum warning:  "There is no more evil
    +since H. G. Wells uttered his glum warning:  "There is no more evil
     thing on earth than race prejudice, none at all.  I write deliberately
     -- it is the worst single thing in life now.  It justifies and holds
     together more baseness, cruelty and abomination than any other sort of
    @@ -57274,7 +57300,7 @@ Write a wise saying and your name will live forever.
     %
     Write yourself a threatening letter and pen a defiant reply.
     %
    -write-protect tab, n:
    +Write-protect tab, n.:
     	A small sticker created to cover the unsightly notch carelessly left
     	by disk manufacturers.  The use of the tab creates an error message
     	once in a while, but its aesthetic value far outweighs the momentary
    @@ -57449,7 +57475,7 @@ X windows:
     Incompatibility.  Shoddiness.  Uselessness.
     	X windows.
     %
    -Xerox does it again and again and again and...
    +Xerox does it again and again and again and ...
     %
     Xerox never comes up with anything original.
     %
    @@ -57850,7 +57876,7 @@ And yet you incessantly stand on your head --
     	"I feared it might injure the brain;
     But, now that I'm perfectly sure I have none,
     	Why, I do it again and again."
    -		-- Lewis Carroll
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     "You are old," said the youth, "and I'm told by my peers
     	That your lectures bore people to death.
    @@ -57871,7 +57897,7 @@ Yet you finished the goose, with the bones and the beak --
     	And argued each case with my wife;
     And the muscular strength which it gave to my jaw,
     	Has lasted the rest of my life."
    -		-- Lewis Carroll
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     "You are old," said the youth, "and your programs don't run,
     	And there isn't one language you like;
    @@ -57892,7 +57918,7 @@ Yet you turned a back-somersault in at the door --
     	"I kept all my limbs very supple
     By the use of this ointment -- one shilling the box --
     	Allow me to sell you a couple?"
    -		-- Lewis Carroll
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     "You are old," said the youth, "as I mentioned before,
     	And make errors few people could bear;
    @@ -57913,7 +57939,7 @@ Yet you balanced an eel on the end of your nose --
     	Said his father.  "Don't give yourself airs!
     Do you think I can listen all day to such stuff?
     	Be off, or I'll kick you down stairs!"
    -		-- Lewis Carroll
    +		-- Lewis Carroll, "Alice's Adventures in Wonderland" (1865)
     %
     You are only young once, but you can stay immature indefinitely.
     %
    @@ -57997,7 +58023,7 @@ They're the ones with arrows sticking out of their backs.
     %
     You can approach truth, but never capture it.
     Lies can be had 'round the corner.
    -		-- Poul Henningsen [1894-1967]
    +		-- Poul Henningsen (1894-1967)
     %
     You can be replaced by this computer.
     %
    @@ -58105,7 +58131,7 @@ You can make it illegal, but you can't make it unpopular.
     %
     You can measure a programmer's perspective by noting his attitude on
     the continuing viability of FORTRAN.
    -		-- Alan Perlis
    +		-- Alan J. Perlis
     %
     You can move the world with an idea,
     but you have to think of it first.
    @@ -58153,7 +58179,8 @@ You can tell the ideals of a nation by its advertisements.
     You can tune a piano, but you can't tuna fish.
     %
     You can write a small letter to Grandma in the filename.
    -		-- Forbes Burkowski, CS, University of Washington
    +		-- Forbes Burkowski, Computer Science 454,
    +		   University of Washington
     %
     You canna change the laws of physics, Captain;
     I've got to have thirty minutes!
    @@ -58185,14 +58212,14 @@ You can't carve your way to success without cutting remarks.
     %
     You can't cheat an honest man, never give
     a sucker an even break or smarten up a chump.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     You can't cheat the phone company.
     %
     You can't cross a large chasm in two small jumps.
     %
     You can't depend on the man who made the mess to clean it up.
    -		-- Richard Nixon, 1952
    +		-- Richard M. Nixon (1952)
     %
     You can't erase a dream, you can only wake me up.
     		-- Peter Frampton
    @@ -58339,7 +58366,7 @@ form.
     %
     You first parent of the human race... who ruined yourself for an apple,
     what might you have done for a truffled turkey?
    -		-- Brillat-savarin, "Physiologie du Gout"
    +		-- Brillat-Savarin, "Physiologie du go^ut"
     %
     You get along very well with everyone except animals and people.
     %
    @@ -58348,7 +58375,7 @@ You get what you pay for.
     %
     You give me space to belong to myself yet without separating me
     from your own life.  May it all turn out to your happiness.
    -		-- Goethe
    +		-- Johann Wolfgang von Goethe
     %
     You go down to the pickup station,
     	craving warmth and beauty;
    @@ -58470,7 +58497,9 @@ You have the power to influence all with whom you come in contact.
     %
     You have to run as fast as you can just to stay where you are.
     If you want to get anywhere, you'll have to run much faster.
    -		-- Lewis Carroll
    +		-- Lewis Carroll,
    +		   "Through the Looking-Glass,
    +		   and What Alice Found There" (1871)
     %
     You humans are all alike.
     %
    @@ -58517,7 +58546,7 @@ Goodtime Charlie's got the blues.
     %
     You know, of course, that the Tasmanians, who never committed adultery,
     are now extinct.
    -		-- M. Somerset Maugham
    +		-- W. Somerset Maugham
     %
     You know, the difference between this company and
     the Titanic is that the Titanic had paying customers.
    @@ -58529,7 +58558,7 @@ you can always change the channel.
     %
     You know very well that whether you are on page one or page thirty depends
     on whether [the press] fear you.  It is just as simple as that.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     You know what I wish?  I wish all the scum of the Earth had one throat
     and I had my hands about it.
    @@ -58669,7 +58698,7 @@ That a young man married is a young man marred.
     %
     You may easily play a joke on a man who likes to argue -- agree with
     him.
    -		-- Ed Howe
    +		-- Edgar W. Howe
     %
     You may get an opportunity for advancement today.  Watch it!
     %
    @@ -59295,7 +59324,7 @@ YOUR FOAMY FUTURE
     	by Miss Fortune
     
     ARIES (March 21 - April 19)
    -	Matters are not good, where you health is concerned.  This Fall, be
    +	Matters are not good, where your health is concerned.  This Fall, be
     sure to "walk groundly, talk profoundly, drink roundly, and sleep soundly"
     and you will live all the days of your life.
     
    @@ -59563,15 +59592,15 @@ 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 
    +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 
    +
    +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. 
    +
    +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.
    @@ -59593,7 +59622,7 @@ Zall's Laws:
     	2: How long a minute is, depends on which side of the bathroom
     	   door you're on.
     %
    -zeal, n:
    +Zeal, n.:
     	Quality seen in new graduates -- if you're quick.
     %
     Zero Defects, n.:
    @@ -59607,8 +59636,8 @@ Zeus gave Leda the bird.
     Zisla's Law:
     	If you're asked to join a parade, don't march behind the elephants.
     %
    -Zounds!  I was never so bethumped with words
    -since I first called my brother's father dad.
    +Zounds!  I was never so bethump'd with words
    +since I first call'd my brother's father dad.
     		-- William Shakespeare, "King John"
     %
     Zymurgy's Law of Volunteer Labor:
    diff --git a/games/fortune/datfiles/fortunes-o.real b/games/fortune/datfiles/fortunes-o.real
    index 5c893637cc4..3078315903c 100644
    --- a/games/fortune/datfiles/fortunes-o.real
    +++ b/games/fortune/datfiles/fortunes-o.real
    @@ -57,7 +57,7 @@ Now it even hurts to take a piss.
     Oh why did I get syphilis?
     
     Why'd she have VD?  I don't know, she wouldn't say.
    -I did something wrong, now I long for yesterday ....
    +I did something wrong, now I long for yesterday ...
     		-- To the tune of "Yesterday"
     %
     		My Favorite Drugs [Sung to My Favorite Things]
    @@ -111,7 +111,7 @@ Testicles, testicles, said Daddy.  A man gets tired of testicles.
     %
     	... But among the children of the Great Society there were
     those whose skins were black.  And lo!  Their portion was niggardly,
    -and of the fatted calf they were sucking hind teat....
    +and of the fatted calf they were sucking hind teat ...
     	Now it came to pass that a prophet rose up amongst them, and
     they called him King.  And he went unto Pharaoh and said, "Let my
     people go to the front of the bus."
    @@ -201,7 +201,7 @@ you explain a thing like that to a seven-year-old child?"
     %
     	A great American Olympic wrestler was receiving last-minute advice
     from his coach about the upcoming match with the Soviet Champion.
    - 	"This Russian guy is really good, very strong and quick.  But I think
    +	"This Russian guy is really good, very strong and quick.  But I think
     you can take him.  Remember, though, like I've told you before, don't let
     him get you in the Pretzel hold.  With his strength you'd never get out."
     	The American leaps onto the mat, and within moments the two behemoths
    @@ -215,7 +215,7 @@ scream and the two wrestlers fly apart, the American regaining control and
     pinning the Russian.  After the match, in the dressing room, the coach
     finally gets the winner alone.  "Great job!  But how the hell did you get out
     of the Pretzel Hold?  I thought it was over for sure!"
    - 	"Well, I did too.  I was in the hold, about to be pinned, when I saw
    +	"Well, I did too.  I was in the hold, about to be pinned, when I saw
     this huge pair of testicles hanging right in front of my eyes.  I figured
     what the hell, so I stretched forward and bit them as hard as I could.  Coach,
     you just don't know your own strength 'til you've bitten your own balls!"
    @@ -662,13 +662,6 @@ posh hotel.
     	"Anything for your wife, sir?" the bellhop asked.
     	"Why, yes, young man," said the gentleman.  "Would you bring me
     a postcard?"
    -%
    -	As we know, there are known knowns.  There are things we know we
    -know.  We also know there are known unknowns.  That is to say, we know
    -there are some things we do not know.  But there are also unknown
    -unknowns; the ones we don't know we don't know.
    -		-- United States Secretary of Defense Donald Rumsfeld
    -		   12 February 2002, Regarding the US invasion of Iraq
     %
     	"Are pirates an ethnic group?  Or are they just people who burn
     illegal cds?"
    @@ -692,6 +685,13 @@ using our exclusive Interactive Mode, invent your own!
     immersible for easy cleaning.  SofSqueeze's flesh-toned exterior is finely
     textured for a realistic effect.  Requires 4K RAM, a DB25 serial port and
     limited graphics capability.  Comes fully assembled, with 4 AA batteries.
    +%
    +	As we know, there are known knowns.  There are things we know we
    +know.  We also know there are known unknowns.  That is to say, we know
    +there are some things we do not know.  But there are also unknown
    +unknowns; the ones we don't know we don't know.
    +		-- United States Secretary of Defense Donald Rumsfeld
    +		   12 February 2002, Regarding the US invasion of Iraq
     %
     	At an elegant dinner party, Lady Astor once leaned across the table
     to remark, "If you were my husband, Winston, I'd poison your coffee."  "And
    @@ -812,7 +812,7 @@ captured early and spent the duration doing the dishes."
     	"Wha-wha-wha-what does regret mean?"
     	"Well, son, a funny thing about regret is that it's better to regret
     something you have done, than to regret something you haven't done.  And by
    -the way, if you see your Mom this weekend, would be you sure and tell her,
    +the way, if you see your Mom this weekend, would you be sure and tell her,
     `SATAN, SATAN, SATAN!!!'"
     		-- Butthole Surfers, "Sweat Loaf"
     %
    @@ -1194,7 +1194,7 @@ man.  Mud-as-man alone could speak.
     	"Certainly," said man.
     	"Then I leave it to you to think of one for all of this," said God.
     	And He went away.
    -		-- Kurt Vonnegut, Between Time and Timbuktu"
    +		-- Kurt Vonnegut, Jr., "Between Time and Timbuktu"
     %
     	In the beginning was the DEMO Project.  And the Project was
     without form.  And darkness was upon the staff members thereof.  So
    @@ -1742,14 +1742,14 @@ I use the tongs."
     the week.  As he approaches the Jones' house, Mrs. Jones greets him warmly at
     the door.  "Please come in!  We're very grateful for your years of service to
     us and our neighborhood.  I've prepared something special for you."
    - 	In walks the mailman, to a graciously appointed dining room, where
    +	In walks the mailman, to a graciously appointed dining room, where
     Mrs. Jones has prepared a sumptuous lunch.  After dumping his letter satchel
     on the couch, he and Mrs. Jones have a charming meal.  As the mailman finished
     his last glass of wine, thanking his hostess profusely, she stops him from
     leaving and disappears upstairs.  She returns in a moment, in a daring
     negligee, and takes the astonished postman to the bedroom, where the elaborate
     farewell is consummated between the sheets.
    - 	As he's putting his pants on, Mrs. Jones reaches into her nightstand,
    +	As he's putting his pants on, Mrs. Jones reaches into her nightstand,
     pulls out a dollar bill, and hands it to him.  Reacting to his astonished
     look, she says, "Well, I told my husband that you were retiring and that
     we should do something for you.  He said 'Fuck him.  Give him a dollar!'"
    @@ -1793,12 +1793,12 @@ did to us?"
     	The Split-Atom Blues
     
     Gimme Twinkies, gimme wine,
    -    Gimme jeans by Calvin Kline....
    +    Gimme jeans by Calvin Klein ...
     But if you split those atoms fine,
         Mama keep 'em off those genes of mine!
     
     Gimme zits, take my dough,
    -    Gimme arsenic in my jelly roll....
    +    Gimme arsenic in my jelly roll ...
     Call the devil and sell my soul,
         But Mama keep dem atoms whole!
     		-- Milo Bloom, "Bloom County"
    @@ -2089,7 +2089,7 @@ three days."
     %
     	We were somewhere around Barstow on the edge of the desert when the
     drugs began to take hold.  I remember saying something like "I feel a bit
    -lightheaded; maybe you should drive...."  And suddenly there was a terrible
    +lightheaded; maybe you should drive ..."  And suddenly there was a terrible
     roar all around us and the sky was full of what looked like huge bats, all
     swooping and screeching and diving around the car, which was going about a
     hundred miles an hour with the top down to Las Vegas.  And a voice was
    @@ -2244,7 +2244,7 @@ obscure such reality.
     		-- Steve Allen
     %
     ... And then there's the guy who bought 20,000 bras, cut them in half,
    -and sold 40,000 yamalchas with chin straps....
    +and sold 40,000 yamalchas with chin straps ...
     %
     ... But the reward of a successful collaboration is a thing that cannot
     be produced by either of the parties working alone.  It is akin to the
    @@ -2332,7 +2332,7 @@ your balls.
      3. A beer won't even act amazed if you can.
      4. You don't have to let a beer win.
      5. Just because you have dinner with a beer doesn't mean you have to
    -	sleep with a beer, too.
    +	sleep with it, too.
      6. A beer helps with the housework.
      7. A beer will never fumble with your bra.
      8. A beer will never take the newspaper apart before you've read it.
    @@ -2714,9 +2714,9 @@ fought, we noticed 2 more Fokkers coming at us from above and 2 more
     Fokkers, fresh from the landing field, come to join the battle".
     At this second and third mention of `Fokkers' the class was almost laughing
     openly, and the teacher interrupted the story to ask the pilot to explain
    -to the class that a 'Fokkers' was a particular type of plane flown by the
    +to the class that a `Fokker' was a particular type of plane flown by the
     German Air Force.
    -	He replied, "Ya, dat is true, but these Fokkers were Messerschmidts".
    +	He replied, "Ya, dat is true, but these Fokkers were Messerschmitts."
     %
     A group of scientists discovered an apelike creature in the jungle, which
     they hoped would prove to be the missing link.  The proof of their theory,
    @@ -3231,7 +3231,7 @@ by the propensity to be sexually aroused by the sight of males.
     %
     A nuclear family is out golfing one day, when it becomes clear that Dad isn't
     going to win any trophies, at least on this course.  On the 3rd hole, after
    -two miserable bogies, he misses a two foot put and exclaims, "Shit!"
    +two miserable bogies, he misses a two foot putt and exclaims, "Shit!"
     	His wife glances over at their sixteen year old daughter and says
     nothing.
     	On the fourth hole Dad tees off with an incredible hook, and, after
    @@ -3591,7 +3591,7 @@ A woman who is guided by the head and not by the heart is a social
     pestilence: she has all the defects of the passionate and affectionate
     woman, with none of her compensations; she is without pity, without
     love, without virtue, without sex.
    -		-- Balzac
    +		-- Honore de Balzac
     %
     A woman who is unfaithful deserves to be shot.
     		-- Pancho Villa
    @@ -3658,9 +3658,10 @@ received a telegram from their sister.  It read:
     
     	I liked the couch falling apart when we sat on it.  I was amused
     	when the shower went cold five minutes after it started.  But I'm
    -	going to kill whoever put the novacaine into the KY jelly...
    +	going to kill whoever put the novocaine into the KY jelly...
     %
    -A.A.A.A.A.: An organization for drunks who drive.
    +A.A.A.A.A., n.:
    +	An organization for drunks who drive.
     %
     Aboard the good ship Venus,		The cabin boy, the captain's joy,
     The mast it was a penis,		A cunning little nipper,
    @@ -3837,7 +3838,7 @@ down."
     "Algorithms" is an anagram for "Hilt orgasm".  Maybe this explains
     the popularity of this field of study in computer science.
     %
    -alimony, n:
    +Alimony, n.:
     	Having an ex you can bank on.
     %
     All a hacker needs is a tight PUSHJ, a loose pair of UUOs, and a warm
    @@ -3930,7 +3931,7 @@ willing that either the history of the content of religion should be taught
     in this spirit; while those to whom the scientific standpoint is not merely
     a technical device, but is the embodiment of the integrity of mind, must
     protest against its being taught in any other spirit.
    -		-- John Dewey, "Democracy in the Schools", 1908
    +		-- John Dewey, "Democracy in the Schools" (1908)
     %
     Alright, yes, date, and shop, and hang out, and go to school ... and
     save the world from unspeakable demons.  You know, I want to do girlie
    @@ -3967,7 +3968,7 @@ main may!'"
     Always talk to your wife while you're
     making love... if there's a phone handy.
     %
    -ambition, n:
    +Ambition, n.:
     	An ant crawling up an elephant's leg with rape on his mind.
     %
     America ... just a nation of two hundred million used car salesman
    @@ -4153,7 +4154,7 @@ open.  "What's the matter with you?" he said. "Born in a barn?"
     %
     And prively he caughte hire by the queynte,
     And heeld hire harde by the haunche-bones.
    -		--Geoffrey Chaucer, The Miller's Tale
    +		-- Geoffrey Chaucer, "The Miller's Tale"
     %
     And so it goes.  It is humiliating, when you should know better, to become
     victim of the timeless story of the little brown dog running across the
    @@ -4214,7 +4215,7 @@ daiquiri.  The bartender looks him over with amusement and says: "We don't
     serve your kind, buddy, why don't you get out of here before the boys come
     in and kick your ass?"
     	The guy whimpers a little and lisps, "Pleasse misssture I am soooo
    -thurstay...."
    +thurstay ..."
     	Well, the bartender feels somewhat sorry for him and hands him a beer
     on the house on the condition that he drink it in the back and leave as soon
     as he's done.  A little while later, a hulking cowboy walks in and up to the
    @@ -4284,7 +4285,7 @@ be childless.
     
     The only solid and lasting peace between a man and his wife is,
     doubtless, a separation.
    -		-- Lord Chesterfield, letter to his son, 1763
    +		-- Lord Chesterfield, letter to his son (1763)
     %
     As for Carter being for registration but against the draft, isn't that
     sort of being like for putting it in and not taking it out?  Even if it
    @@ -4466,7 +4467,7 @@ Unless you get a good percentage of her price ...
     %
     Beat me, bite me, whip me, fuck me, make me write bad checks!
     %
    -Beauty, n:
    +Beauty, n.:
     	The power by which a woman charms a lover and terrifies a husband.
     		-- Ambrose Bierce, "The Devil's Dictionary"
     %
    @@ -4489,7 +4490,7 @@ we are part of the women's liberation movement.
     %
     Bedfellows make strange politicians.
     %
    -beef stroganoff, n:
    +Beef stroganoff, n.:
     	A bull masturbating.
     %
     Behold the unborn fetus and
    @@ -4631,7 +4632,7 @@ campus by another religious organization, and the system was first used on
     Brother Jim, who suffered a broken rib and numerous small bruises, in
     addition to the usual humiliation.
     %
    -brunette bush, n:
    +Brunette bush, n.:
     	The dark side of the moon.
     %
     Buffy:	Am I repulsive?  If there was something repulsive about me, you'd
    @@ -4662,7 +4663,7 @@ Xander:	Yay.
     		-- Buffy the Vampire Slayer, "The Prom"
     		   Season 3, Episode 20
     %
    -bug, n:
    +Bug, n.:
     	A son of a glitch.
     %
     Build a better mousetrap, the saying goes -- and with the brassiere,
    @@ -4709,7 +4710,7 @@ California is proud to be the home of the freeway.
     %
     Call for Ms. Lingus, Ms. Connie Lingus...
     %
    -callgirl, n:
    +Callgirl, n.:
     	A negotiable blond.
     %
     Camille's Axiom:
    @@ -4877,7 +4878,7 @@ G's Third Law:
     	is composed of only two basic substances: magic and bullshit.
     
     H's Dictum:
    -	There is no magic....
    +	There is no magic...
     %
     Claude believed that only smart attractive people had the right to
     fuck, and it sincerely hurt him when he discovered evidence to the
    @@ -4886,7 +4887,7 @@ contrary.
     %
     Cleveland still lives.  God MUST be dead.
     %
    -clitoris, n:
    +Clitoris, n.:
     	A haired trigger.
     %
     CLONE OF MY OWN (to Home on the Range)
    @@ -4921,7 +4922,7 @@ Cocaine: using tomorrow's energy today.
     Cocaine's a joke!
     	(Who's got the next line?)
     %
    -cock-sucker, n:
    +Cock-sucker, n.:
     	Someone who got caught doing what you got away with.
     %
     Coffee without caffeine.  Beer without alcohol.  Milk without fat.
    @@ -4930,7 +4931,7 @@ What's next?  Bridal suites with bunk beds?
     %
     Coito ergo sum
     %
    -coitus interruptus, n:
    +Coitus interruptus, n.:
     	A jerky movement following the words (by either sex partner)
     	"I want to have your child."
     %
    @@ -4948,15 +4949,12 @@ And eliminates all the palaver.
     COLD:
     	When the local flashers are handing out written descriptions.
     %
    -cold, adj:
    +Cold, adj.:
     	When your dog sticks to the fire hydrant.
     %
     College is like a woman -- you work so hard to get in, and nine months
     later you wish you'd never come.
     %
    -College is like a woman -- you work so hard to get in,
    -and nine months later you wish you'd never come.
    -%
     Come along and sing a song and join our family.
     B & D
     S & M
    @@ -5005,7 +5003,7 @@ Communists do it without class.
     %
     Computer scientists are programmed to do it by macro insertion.
     %
    -computerfirm nymphomaniac, n:
    +Computerfirm nymphomaniac, n.:
     	Hot Apple pie.
     %
     Condoms are like listening to a symphony with cotton in your ears.
    @@ -5078,7 +5076,7 @@ BEDLAM:
     CHAOS:
     	Four women plus one luncheon check.
     %
    -confusion, n:
    +Confusion, n.:
     	Father's Day in San Francisco.
     %
     Conservative, n.:
    @@ -5090,10 +5088,10 @@ Conserve energy -- make love more slowly.
     CONSULTANT:
     	Someone who knows 101 ways to make love, but can't get a date.
     %
    -continental breakfast, n:
    +Continental breakfast, n.:
     	A roll in bed with some honey.
     %
    -Coors, n:
    +Coors, n.:
     	Like making love in a canoe -- fucking close to water.
     %
     Copa-ulation:
    @@ -5135,14 +5133,14 @@ If you're not going to sack it, go home and wack it.
     Cox's philosophy:
     	Life's a bitch, then you die.
     %
    -coyote love, n:
    +Coyote love, n.:
     	Coyote love is a nebulous term.  Basically, what it involves is
     	the taking of a member of the preferred sex home from a singles
     	bar.  Then, when you wake up the next morning, they're sleeping
     	on your arm.  So, rather than wake them up as you escape, you
     	chew off your arm at the shoulder.
     
    -coyote ugly, adj:
    +Coyote ugly, adj.:
     	When you chew off the other arm 'cause she'll be looking for
     	a one-armed man!
     
    @@ -5159,7 +5157,7 @@ to a doctrine not only known to be false, but calculated to undermine any
     general understanding of science as an enterprise?
     		-- Stephen Jay Gould, "The Skeptical Inquirer"
     %
    -crew, n:
    +Crew, n.:
     	Eight big men and their cute little cox.
     %
     Cried Miss Pratt: "What are you staring at?
    @@ -5247,7 +5245,7 @@ Dear Abby:
     	I just met the most terrific girl and we get along fabulously.  I
     think she's the one for me.  There's just one problem: I can't remember
     from our first date if she told me she had TB or VD.  What should I do?
    -			--Confused
    +			-- Confused
     
     Dear Confused:
     	If she coughs, fuck her.
    @@ -5329,10 +5327,10 @@ of her husband with his penis inside the pencil sharpener on the counter.
     %
     Dial 911.  Make a cop come.
     %
    -diaphragm, n:
    +Diaphragm, n.:
     	A childproof cap.
     %
    -dicker, v:
    +Dicker, v.:
     	What you do to your wife if arguing doesn't work.
     %
     Did Detroit invent the back seat to destroy the morals of America?
    @@ -5410,7 +5408,7 @@ UP PERISCOPE!!!
     
     (Ooops, sorry, wrong fantasy.)
     %
    -divorce, n:
    +Divorce, n.:
     	A change of wife.
     %
     Do infants have as much fun in infancy as adults do in adultery?
    @@ -5439,7 +5437,7 @@ very good; and when it is bad, it is better than nothing.
     		-- Dick Brandon
     %
     Does he treat your breasts like unripe grapefruit?  Who needs him?
    -		-- `J', "The Sensuous Woman"
    +		-- J, "The Sensuous Woman"
     %
     Does it rape elephants?
     		-- Brent Byer
    @@ -5518,7 +5516,7 @@ say, and when he was done, grinned broadly and replied, 'Eat it raw, fuzz
     nuts.'"
     		-- "The Churchill Wit", National Lampoon
     %
    -dyke, n:
    +Dyke, n.:
     	A woman who kick-starts her vibrator.  And rolls her own
     	tampons.
     %
    @@ -5572,7 +5570,7 @@ Eleven reasons a cucumber is better than a man:
     	(11) With a cucumber, the toilet seat is always the way you
     	     left it.
     %
    -embarrassment, n:
    +Embarrassment, n.:
     	Finding out your German Shepherd has the clap.
     %
     Equality is not when a female Einstein gets promoted to assistant
    @@ -5580,7 +5578,7 @@ professor; equality is when a female schlemiel moves ahead as fast as a
     male schlemiel.
     		-- Ewald Nyquist
     %
    -Erogenous zone, n:
    +Erogenous zone, n.:
     	The skin you touch to love.
     %
     Es giebt ein Arbeiter von Tinz,
    @@ -5589,7 +5587,7 @@ Er schlaft mit ein Madel von Linz.
     	Ich hore Mann kommen."
     "Jacht, jacht," sagt der Plummer, "Ich binz."
     %
    -eternity, n:
    +Eternity, n.:
     	The length of time between when you come and he leaves.
     %
     Ethnologists up with the Sioux
    @@ -5680,7 +5678,7 @@ do with ones time.  Like lie in the sun and sleep.  Or go exploring the world.
     Except for 75% of the women, everyone in the whole world wants to have sex.
     		-- Ellyn Mustard
     %
    -exotic dancer, n:
    +Exotic dancer, n.:
     	A girl who brings home the bacon a strip at a time.
     %
     Exuberant Sue from Anjou
    @@ -5694,7 +5692,7 @@ Buffy:	It didn't suck.
     		-- Buffy the Vampire Slayer, "Bad Girls"
     		   Season 3, Episode 14
     %
    -falsie salesman, n:
    +Falsie salesman, n.:
     	Fuller bust man.
     %
     Famous last words:
    @@ -5729,17 +5727,17 @@ Shrieks and screams were heard from Grandma
     He had chased her up a tree!
     	(chorus)
     %
    -felt tip, v:
    +Felt tip, v.:
     	Past tense for a breast examination!
     %
     Female ballet dancers are the bravest girls around.  Who else would take a
     flying leap into the arms of a homosexual and expect to be caught?
     		-- Rita Rudner
     %
    -female, n:
    +Female, n.:
     	Life support system for a pussy.
     %
    -Feminism, n:
    +Feminism, n.:
     	A political position which seeks to rebuild society so that
     	both men and women are treated as women wish to be treated.
     %
    @@ -5801,7 +5799,7 @@ He's so neat, he's so cool,
     Walks across my swimming pool.
     Has anybody...
     %
    -Flirt, n:
    +Flirt, n.:
     	A girl whose favorite man is the next one.
     %
     Floating idly one day through the air,
    @@ -5844,7 +5842,7 @@ to the heads of unfaithful men.  I brought forth destruction and chaos
     for the pleasure of the lower beings.  I was feared and worshiped across
     the mortal globe.  And now I'm stuck at Sunnydale High.  A mortal.
     A child ...  and I'm flunking math.
    -		-- Anya, Buffy the Vampire Slayer, "Dopplegangland"
    +		-- Anya, Buffy the Vampire Slayer, "Doppelgangland"
     		   Season 3, Episode 16
     %
     For a young man, not yet: for an old man, never at all.
    @@ -6130,13 +6128,13 @@ It satisfies a normal need. -- I like it.
     	It turns your spine to fucking jell,
     It damns your soul to Eternal Hell! -- I like it.
     %
    -fuck-me-pumps, n:
    +Fuck-me pumps, n.:
     	Stiletto heels of a certain length, usually black patent leather.
     The proper designation is "throw-me-down-and-fuck-me" pumps.  Shoes with
     heels just high enough to let the frayed tip of a bullwhip trail around
     them properly.
     %
    -fuckoff, n:
    +Fuckoff, n.:
     	The tie breaker at the Miss America Beauty Pageant.
     %
     Gardeners do it in raised beds.
    @@ -6198,7 +6196,7 @@ I'm too hot, too hot for you.		I'm the queen of babes supreme,
     					But you'll only see me in you dreams.
     "Well?  What'd she say??"		I'm too hot, too hot for you.
     "Well, she didn't say no..."
    - 		-- Barry and the Bookbinders, "The Worst She Can Say is No"
    +		-- Barry and the Bookbinders, "The Worst She Can Say is No"
     %
     GET OFF THE FUCKING SYSTEM THIS INSTANT, YOU ASSHOLE!!!!
     %
    @@ -6428,7 +6426,7 @@ or they will stick you in the dock,
     and you won't come back.
     		-- Monty Python, "The Meaning of Life"
     %
    -good scout, n:
    +Good scout, n.:
     	Someone who knows the lay of the land and will take you to her.
     %
     Gorbachev woke up early one morning, and felt great.  He walked over to his
    @@ -6475,7 +6473,7 @@ Gross, adj.:
     	When your grandmother kisses you goodnight and
     	slips you some tongue.
     %
    -Gynecologist, n:
    +Gynecologist, n.:
     	Someone who spends their time spreading old wives' tails.
     %
     HACKER:
    @@ -6498,7 +6496,7 @@ Haggis, n.:
     considered by them to be not only a delicacy but fit for human
     consumption.  The minced heart, liver and lungs of a sheep, calf or
     other animal are mixed with oatmeal, sealed and boiled in maw in the sheep's
    -intestinal stomach-bag and ... Excuse me a minute....
    +intestinal stomach-bag and ... Excuse me a minute ...
     %
     Half the posts to this group are about masturbation and the other half
     are about penis size.  And what I want to know is, if all you're doing
    @@ -6519,7 +6517,7 @@ Handy hint:
     %
     Hang gliders come down very slowly.
     %
    -Hangover, n:
    +Hangover, n.:
     	The burden of proof.
     %
     HAPPINESS:
    @@ -7146,7 +7144,7 @@ And when he did, he dropped stone dead,
     'Cause the blasted thing had a left-hand thread!
     %
     Here's the holiday schedule for Monday's observation of Martin Luther
    -King Jr.'s birthday, when the following will be closed:
    +King, Jr.'s birthday, when the following will be closed:
     
     	* Governmental offices
     	* Post offices
    @@ -7269,7 +7267,7 @@ in jeopardy, why, I'd never have lit one!
     HONOR:
     	Almost as good as in 'er.
     %
    -horny, adj:
    +Horny, adj.:
     	When your cock gets hard if the wind blows.
     %
     Horsecrap, little brother.  There's always something more to be done.
    @@ -7323,13 +7321,13 @@ bush, shoot more often and *always* eat what they shoot.
     %
     Hypocrisy is the Vaseline of social intercourse.
     %
    -hypocrite, n:
    +Hypocrite, n.:
     	A man who says he likes cats, but won't eat pussy.
     %
     I am an atheist, thank God!
     %
     I believe that Ronald Reagan will someday make this country what it
    -once was ... an arctic wilderness
    +once was ... an arctic wilderness.
     		-- Steve Martin
     %
     I bet you think you're pretty cool driving around without auto insurance.
    @@ -7350,7 +7348,7 @@ I've reached the point where I might do *anything* to stop the war.  We'll
     just slip the word to them that "For God's sake, you know, Nixon is obsessed
     about Communism.  We can't restrain him when he's angry -- and he has his
     hand on the nuclear button."
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     I came; I saw; I fucked up.
     %
    @@ -7406,13 +7404,12 @@ I don't care who you are, Fatso.  Get those reindeer off my roof.
     %
     I don't discriminate on the basis of sex.
     		-- Bisexuality, 101
    -
     		[An equal opportunity lover?  Ed.]
     %
     I don't give a shit what happens.  I want you all to stonewall it.  Let
     them plead the Fifth Amendment, cover up, or anything else if it'll save
     the plan.
    -		-- Richard Nixon
    +		-- Richard M. Nixon
     %
     I don't know why women get so upset, they have half the
     money and all the pussy.
    @@ -7530,7 +7527,7 @@ By the tricks that he makes his foreskin do.
     %
     I know what you're up to, you white-feathered fiend!
     Go release your bowels on some lesser personage!
    -		-- W.C. Fields, upon seeing a bird overhead
    +		-- W. C. Fields, upon seeing a bird overhead
     %
     I know why the sun never sets on the British Empire -- God wouldn't trust
     an Englishman in the dark.
    @@ -7589,7 +7586,6 @@ But I'm already stewed, screwed, and tattooed."
     %
     I only date queers.
     		-- Bisexuality, 101
    -
     		[I'm not queer, but my boyfriend is!  Ed.]
     %
     I own my own body, but I share.
    @@ -7672,7 +7668,7 @@ I was 15 years old before I found out that "damn yankee" was two words.
     %
     I was a cock-teaser at Rooster Rama.
     I used to enrage the bantams before the big bouts.
    -		-- Firesign Theatre
    +		-- The Firesign Theatre
     %
     I was having sex just the other night, but she hung up.
     %
    @@ -7680,12 +7676,12 @@ I was on vacation in Greece last summer, and was being driven round an island
     by a Greek cab-driver.  He was a friendly man, and as we drove, he told me
     about various historic and scenic places he had been involved with.
     	"See the entrance to that church over there?  I built that with my
    -two sons.  But do they call me `Dimitri the church builder'?  Do they hell!"
    +two sons.  But do they call me `Dimitri the church builder?'  Do they hell!"
     	As we passed a dam, he said, "See that dam?  Four of us built that
     dam by ourselves!  But do they call me `Dimitri the dam builder?'  Hell, no!"
     	As we passed a beautiful cottage, Dimitri started up again -- "See
     that house?  I built that for my wife with my own two hands!  But do they
    -call me `Dimitri the home builder'?  No!  But just one little sheep!"
    +call me `Dimitri the home builder?'  No!  But just one little sheep!"
     %
     I went to a wild party last night.  I tell ya, it was so wild, we played
     a new version of Russian roulette.  We passed around six girls and one
    @@ -7949,7 +7945,7 @@ Will be hailed by all as miraculous!
     %
     If you're a real good kid, I'll give you a piggy-back ride on a
     buzz-saw.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     If you're Catholic you've only got two choices: periodic
     abstinence and complete continence; (you know, rhythm and blues).
    @@ -8082,10 +8078,10 @@ girlfriend's name.  Yeah, I went down to the hall of records.  I said, "I'd
     like to change it... I'd like to change it to... LYING LITTLE BITCH!"
     		-- Sam Kinison
     %
    -I'm unbuttoning your shirt, unzipping your jeans....
    +I'm unbuttoning your shirt, unzipping your jeans ...
     
     Oh, I can feel your fingers on the keys, baby,
    -	I'm getting WARM....
    +	I'm getting WARM ...
     
     I am getting there, oh yes,.  Oh, my. OH YES... OHHHH!
     	...!!!rrrrrgh!!!!!
    @@ -8110,7 +8106,7 @@ Yes, Socrates, himself, is particularly missed;
     A lovely little thinker but a bugger when he's pissed!
     		-- Monty Python, "The Philosopher's Drinking Song"
     %
    -impotent loser, n:
    +Impotent loser, n.:
     	Someone who can't even get his hopes up.
     %
     In 1953, Stalin dies.  The politburo holds a special meeting to decide
    @@ -8141,7 +8137,7 @@ Legette Hair Fastener Heat Bags; Lady O' Spain Self-Blinding Eye Shadow
     with Magic Puncture Pencil; Sanitary Napkin Rings in Little Miss, Moon
     Maid and Stuck Pig Strength; and deported Italian Napagel Balls for
     soaking or eating; and they're all slash-priced with the lady in mind...
    -		-- Firesign Theatre
    +		-- The Firesign Theatre
     %
     In days of old, when knights were bold,
     	And rubbers weren't invented,
    @@ -8186,7 +8182,7 @@ And in peaceful submission I lay,
     My sweet little night gown of blue.
     %
     In my world, there are people in chains and we can ride them like ponies.
    -		-- Evil Willow, Buffy the Vampire Slayer, "Dopplegangland"
    +		-- Evil Willow, Buffy the Vampire Slayer, "Doppelgangland"
     		   Season 3, Episode 16
     %
     In outer space, nobody can hear you fart.
    @@ -8242,7 +8238,7 @@ kissing him on the balls.
     Incest, n.:
     	Sibling revelry; a sport the whole family can enjoy.
     %
    -Infatuation, n:
    +Infatuation, n.:
     	When you're in love, there's a lump in your throat.
     	When you're infatuated, there's a lump in your pants.
     %
    @@ -8265,8 +8261,8 @@ Re: S. White
     	Let it be noted that if she whistles that goddamned song one
     more time I'm gonna rip her fuckin' lips off.  Have a nice day.
     %
    -Is it just me, or does anyone else read `bible humpers' every time
    -someone writes `bible thumpers?'
    +Is it just me, or does anyone else read "bible humpers" every time
    +someone writes "bible thumpers?"
     		-- Joel M. Snyder, jms@mis.arizona.edu
     %
     Isn't it odd that people who object to "foul" language are always the
    @@ -8791,14 +8787,14 @@ Knowledge Engineering:
     
     A combination of:
     
    -Engineering, n:
    +Engineering, n.:
     	The application of science and mathematics by which the properties
     of matter and the sources of energy in nature are made useful to man in
     structures, machines, products, systems and processes.
     
     and
     
    -Knowledge, n:
    +Knowledge, n.:
     	Sexual intercourse.
     
     See also: Prostitution, Grantsmanship.
    @@ -8822,10 +8818,10 @@ left a deep impression on him -- about how faithfully animals respond to
     intention movements, that is.
     		-- The Sciences, May/June, 1988, N.Y. Academy of Science
     %
    -Kotex, n:
    +Kotex, n.:
     	Not the best thing on earth, but next to the best.
     %
    -Kumquat, n:
    +Kumquat, n.:
     	Any of several small citrus fruits with sweet spongy rind and
     	somewhat acidic pulp that are used chiefly for preserves.
     	Extremely popular in some forms of sexual intercourse.  In fact,
    @@ -8836,7 +8832,7 @@ Kumquat, n:
     	Note: this is *not* to be confused with a warning from your
     	partner that his/her parents are upstairs and probably awake.
     %
    -Labia majora, n:
    +Labia majora, n.:
     	The curly gates.
     %
     Lady to Golf Pro: "I was stung by bees on your golf course!"
    @@ -8844,7 +8840,7 @@ Pro:	"Ummm, well, where?"
     Lady:	"Between the 1st and 2nd holes."
     Pro:	"That's going to real tough to treat."
     %
    -lagnaf, n:
    +Lagnaf, n.:
     	Let's All Get Naked And Fuck!
     %
     Laissez Faire Economics is the theory that if each acts like a vulture,
    @@ -8860,7 +8856,7 @@ I was screwed, if you must know the truth."
     %
     Last week I saw a girl in a sweater so tight I could hardly breathe.
     %
    -lawyer, n:
    +Lawyer, n.:
     	Someone who can get a sodomy charge changed to "following too
     	closely."
     %
    @@ -8968,7 +8964,7 @@ Lisp hackers
     	... have DEFUN while doing it.
     	... have Moby dicks.
     %
    -Lisp hackers have to be bound (to-do 'it)....
    +Lisp hackers have to be bound (to-do 'it) ...
     %
     Lisp programmers do it deeper and deeper and deeper.
     %
    @@ -9069,7 +9065,7 @@ was because they wanted to make sure he was dead.
     		-- Samuel Goldwyn
     %
     Love comes in spurts.
    -	--Devo, "Please Please"
    +		-- Devo, "Please Please"
     %
     Love does not make the world go around, just up and down a bit.
     %
    @@ -9091,18 +9087,18 @@ Love letters no longer they write us,
     To their homes they so seldom invite us.
     	It grieves me to say,
     	They have learned with dismay,
    -We can't cure their `vulva pruritus'.
    +We can't cure their "vulva pruritus."
     %
    -Luser, n:
    +Luser, n.:
     	Someone who picks up a female
     	hitch-hiker walking home from a date.
     %
     Ma Bell runs a baudy house.
     %
    -Macho, adj:
    +Macho, adj.:
     	Jogging home from a vasectomy.
     %
    -Male, n:
    +Male, n.:
     	Life support system for a cock.
     %
     Man in stall:
    @@ -9207,10 +9203,10 @@ Just look up Mary's ...
     Masturbation!  The amazing availability of it!
     		-- James Joyce
     %
    -masturbation, n:
    +Masturbation, n.:
     	A self-service elevator.
     %
    -masturbation, n:
    +Masturbation, n.:
     	Coming unscrewed.
     %
     Math is to physics like masturbation is to sex.
    @@ -9239,11 +9235,6 @@ May the fairy god-camel leave a lump on your pillow!
     Maybe if the guy who developed Twinkies hadn't had such a low
     opinion of himself they would have been an inch or two longer!
     %
    -Mayor Vincent J. `Buddy' Cianci on the ACLU's suit to have a city
    -nativity scene removed:
    -	"They're just jealous because they don't have three wise men
    -and a virgin in the whole organization."
    -%
     McCoy's a seducer galore,
     And of virgins he has quite a score.
     	He tells them, "My dear,
    @@ -9258,7 +9249,7 @@ McQuillan was on the stand. The case involved a railroad and several of
     the passengers who were injured.
     	"You say," thundered the counsel for the railroad, "that you saw
     the two trains crash head on while doing sixty miles an hour.  What did you
    -think when you saw this happen ?"
    +think when you saw this happen?"
     	"I thought," replied the Irishman, "this is one *helluva* way to run
     a railroad."
     %
    @@ -9318,7 +9309,7 @@ Everything they say,
     Men will fuck mud.
     		-- Lenny Bruce
     %
    -menage a trois, n:
    +Menage a trois, n.:
     	Using both hands to masturbate.
     %
     Men's magazines often feature pictures of naked ladies.  Women's magazines
    @@ -9346,7 +9337,7 @@ views, are constantly being shoved out the window head first, without so
     much as a pension plan, by younger hotshot cells moving up from below.
     		-- Dave Barry
     %
    -Meteorologist, n:
    +Meteorologist, n.:
     	A man who can look in a woman's eyes and predict whether.
     %
     Mickey Mouse has a long talk one day with a psychiatrist, after which
    @@ -9385,10 +9376,10 @@ How does your garden grow?
     With silver bells and cockle shells,
     And one really fucked-up petunia.
     %
    -Mistress, n:
    +Mistress, n.:
     	Something between a mister and a mattress.
     %
    -mixed emotions:
    +Mixed emotions:
     	Watching your mother-in-law back off a cliff...
     	in your brand new Mercedes.
     %
    @@ -9581,19 +9572,19 @@ seems he's making it hard for everyone but her.
     %
     National Sex Week -- don't let your meat loaf.
     %
    -navel, n:
    +Navel, n.:
     	A place to stash your gum on the way down.
     %
     Necessity is the mother of strange bedfellows.
     Watch who you sleep with.
     %
    -necrophilia, n:
    +Necrophilia, n.:
     	Dead boring.
     
    -incest, n:
    +Incest, n.:
     	Relatively boring.
     %
    -necrophilia, n:
    +Necrophilia, n.:
     	Dropping in for a cold one.
     %
     Negotiate my ass, let's kill something!
    @@ -9679,7 +9670,7 @@ Not everyone has a one-track mind.
     Not only is God dead, but just try to find a plumber on weekends.
     		-- Woody Allen
     %
    -nothing, adj:
    +Nothing, adj.:
     	A man with an erection who walks into a wall and breaks his nose.
     %
     Nothing is better than Sex.
    @@ -10352,7 +10343,7 @@ OPTIMIST:
     ORAL CONTRACEPTIVE:
     	The word "No".
     %
    -oral sex, n:
    +Oral sex, n.:
     	The taste of things to come.
     %
     O'Riordan's Theorem:
    @@ -10384,7 +10375,7 @@ national emergency... Always there has been some terrible evil to
     gobble us up if we did not blindly rally behind it  by furnishing the
     exorbitant sums demanded.  Yet, in retrospect, these disasters seem
     never to have happened, seem never to have been quite real.
    -		-- General Douglas MacArthur, 1957
    +		-- General Douglas MacArthur (1957)
     %
     Our readers ask, "Why don't more WASPs go to orgies?"  Well, it's really
     quite simple.  They don't want to have to write all those thank-you notes.
    @@ -10446,7 +10437,7 @@ the bill at the XXX South Trail Cinema featured:
     	+ Turn Up the Heat, starring Savannah
     	+ Tiger Shark, starring Raven
     %
    -penis envy, n:
    +Penis envy, n.:
     	The desire to be pink and wrinkled and about four inches long.
     %
     People humiliating a salami!
    @@ -10473,7 +10464,7 @@ When her summer turned out quite a bummer!
     %
     Persistence, like perspiration, is 99 percent of the fine art of love.
     %
    -Philadelphia flying fuck, n:
    +Philadelphia flying fuck, n.:
     	Okay, see, he hangs from a chin-up bar with his feet on the arms
     	of the rocking chair.  She crouches in the rocking chair pleasuring
     	him orally.
    @@ -10490,7 +10481,7 @@ Physicists do it with charm.
     Picking up a man in a bar is like a snowstorm, you never know when
     he's coming, how many inches you'll get or how long he'll stay.
     %
    -pile driver, n:
    +Pile driver, n.:
     	Local drink; two parts vodka, one part prune juice.
     %
     Planned Parenthood:
    @@ -10510,11 +10501,11 @@ If you do the things we say, then you'll soon rule the nation.
     Kill your foes and enemies and then kill your relations.
     Pillage, rape, and loot and burn, but all in moderation.
     %
    -pocket pool, n:
    +Pocket pool, n.:
     	Well, for guys, it's two-ball in the side pocket.
     	For women, it's playing the slots.
     %
    -polish fly, n:
    +Polish fly, n.:
     	You put it in her drink and she begs you to take her bowling.
     %
     Politicians do it to everyone.
    @@ -10574,10 +10565,10 @@ Pregnancy -- the worst sexually transmitted disease of them all.
     %
     Pregnancy begins with a single sell.
     %
    -premature ejaculation, n:
    +Premature ejaculation, n.:
     	A spoilspurt.
     %
    -premature ejaculator, n:
    +Premature ejaculator, n.:
     	Troubled shooter.
     %
     Premenstrual Syndrome:
    @@ -10625,7 +10616,7 @@ both promise to make people feel better, but the prostitute doesn't
     make pretensions that the feelings will last once the client walks
     out the door.
     %
    -pubic hair, n:
    +Pubic hair, n.:
     	Organic dental floss.
     %
     Puff the Jewish dragon lived in Palestine,
    @@ -10715,7 +10706,7 @@ A:	You stand around in a circle and blaspheme and see who gets struck
     %
     Q:	How do you tell if an elephant has been making love in your
     	backyard?
    -A:	If all your trashcan liners are missing....
    +A:	If all your trashcan liners are missing ...
     %
     Q:	How do you tell if you're making love to a nurse, a schoolteacher,
     	or an airline stewardess?
    @@ -11087,7 +11078,7 @@ Q:	Why do Scotsmen wear kilts?
     A:	Because a sheep can hear the sound of a zipper from fifty feet away.
     		-- Iain MacKintosh, Glasgow folksinger
     %
    -Q:	Why do WASPs play golf ?
    +Q:	Why do WASPs play golf?
     A:	So they can dress like pimps.
     %
     Q:	Why do women have vaginas?
    @@ -11267,10 +11258,10 @@ weighing the odds of a slander suit.  Mayor Koch could naturally be
     reached for comment, but we chose not to listen.
     		-- Dennis Miller, "Saturday Night Live"
     %
    -quickie, n:
    +Quickie, n.:
     	A moment's piece.
     %
    -quickie, n:
    +Quickie, n.:
     	No sooner spread than done.
     %
     QWERT (kwirt) n. [MW < OW qwertyuiop, a thirteenth]  1. a unit of weight
    @@ -11287,7 +11278,7 @@ Lisa:	Ralph... get off my back!!
     Randel, n.:
     	A nonsensical poem recited by Irish schoolboys as an apology
     for farting at a friend.
    -		-- Mrs. Byrne's Dictionary of Unusual, Obscure &
    +		-- Mrs. Byrne's Dictionary of Unusual, Obscure, and
     		   Preposterous Words
     %
     Raquel Welch:		36-24-36
    @@ -11329,19 +11320,19 @@ you'll never have to worry about those damn bats pestering the neighbors again.
     %
     Reagan can't _a_c_t, either.
     %
    -real buddy, n:
    +Real buddy, n.:
     	Someone who'll go downtown and get two blowjobs, and come back
     	and give you one.
     %
    -real class, adj:
    +Real class, adj.:
     	When you're by yourself, fart, and say "Excuse me."
     %
     Real fur: the ultimate sadist symbol.
     %
    -Reformed, n:
    +Reformed, n.:
     	A synagogue that closes for the Jewish holidays.
     %
    -rejection, n:
    +Rejection, n.:
     	When you're masturbating and your hand falls asleep.
     %
     Religion is fine, Churchianity sucks.
    @@ -11395,7 +11386,7 @@ phone number!"
     Revenge is sleeping with your enemy's wife.
     Sweet revenge is the realization that she's a lousy lay.
     %
    -rodeo fuck, n:
    +Rodeo fuck, n.:
     	When you lean down and whisper in your lover's ear, "Honey, you're
     	the worst piece of ass I've ever had!".  And then try to stay on
     	for seven seconds...
    @@ -11435,7 +11426,7 @@ Roumanian-Yiddish cooking has killed more Jews than Hitler.
     %
     Rugby is a game played by men with peculiarly shaped balls.
     %
    -rugby, n:
    +Rugby, n.:
     	A sport requiring leather balls.
     %
     Rumour has it that the intrepid New Zealanders have finally discovered
    @@ -11745,7 +11736,7 @@ Let _P be a constant persuasion;
     
     "Let _V over _P be inverted
     With the square root of _M_u inserted
    -	_N times into _V....
    +	_N times into _V ...
     	The result, Q.E.D.,
     Is a relative!"  Einstein asserted.
     %
    @@ -11936,7 +11927,7 @@ production, protects a bunch of pricks and gives everyone a false sense of
     security while they're being screwed.
     %
     Self-abuse is the most certain road to the grave.
    -		-- Dr. George M. Calhoun, 1855
    +		-- Dr. George M. Calhoun (1855)
     %
     SEMINARS:
     	From 'semi' and 'arse', hence, any half-assed discussion.
    @@ -11957,7 +11948,7 @@ The shit has hit the fan.
     		-- Warren Zevon
     %
     Sensible and responsible women do not want to vote.
    -		-- Grover Cleveland, 1905
    +		-- Grover Cleveland (1905)
     %
     Sex and drugs and UNIX.
     %
    @@ -11996,7 +11987,7 @@ are unimportant.
     		-- Henry Miller
     %
     Sex is the poor man's opera.
    -		-- G. B. Shaw
    +		-- George Bernard Shaw
     %
     Sex is what women have and men want.
     %
    @@ -12177,7 +12168,7 @@ Sixteen'll get you twenty.
     %
     Size counts.
     %
    -small, adj:
    +Small, adj.:
     	Is it in yet?
     %
     Smoking a woman is like kissing a fish.
    @@ -12313,7 +12304,7 @@ Some women achieve greatness, some have greatness thrust into them.
     %
     Some women are like musical glasses.
     To keep them in tune they must be wet.
    -		-- Samuel Coleridge
    +		-- Samuel T. Coleridge
     %
     Some women should be beaten regularly, like gongs.
     		-- Noel Coward
    @@ -12376,7 +12367,7 @@ Stockmayer's Theorem:
     STRAPLESS EVENING GOWN:
     	Bust truster.
     %
    -stress, n:
    +Stress, n.:
     	The confusion created when one's mind overrides the body's
     	desire to choke the living shit out of some asshole who
     	desperately needs it.
    @@ -12390,7 +12381,7 @@ Success has many fathers, but failure is a bastard.
     Success is like a fart -- only your own smells nice.
     		-- James P. Hogan
     %
    -successful cunnilingus:
    +Successful cunnilingus, n.:
     	When you wake up the next morning with a face like a
     	frosted doughnut.
     %
    @@ -12418,7 +12409,7 @@ you'll eat that stuff, you'll eat anything.
     Sure, Reagan has promised to take senility tests.  But what if he
     forgets?
     %
    -swallow, v:
    +Swallow, v.:
     	The (blew) bird of birth control.
     %
     Systems people do it with a small, but clean, interface.
    @@ -12461,11 +12452,11 @@ Teaching undergraduates is like herding sheep.  And, like the old Basque
     sheepherder explained, whenever the livestock starts looking good to you,
     it's time to spend a night in town.
     %
    -tear leather:
    +Tear leather:
     	To become excited, as in the sentence "Robin Hood tore
     	his leather jerkin' off."
     %
    -tearing off a quicky:
    +Tearing off a quicky:
     	Gunning the jump.
     %
     Teddy Kennedy:	A Blond in Every Pond!
    @@ -12875,11 +12866,6 @@ the older woman pleaded.  Reluctantly, he agreed.
     "I knew my daughter would have an explanation," she said, a note of triumph
     in her voice.  "She didn't receive your telegram!"
     %
    -The Italian entry in the Eurovision Song Contest, "I Can't Get No
    -Contraception", has been withdrawn after the Pope advised them to
    -pull it out at the last minute.
    -		-- Not the Nine O'Clock News
    -%
     The investment community feels very putupon.  They feel there is no
     reason why they shouldn't earn $1 million to $200 million a year,
     and they don't want to be held responsible for the global financial
    @@ -12888,6 +12874,11 @@ meltdown.
     		   Barack Obama's financial-industry fundraising party
     		   20 October 2009
     %
    +The Italian entry in the Eurovision Song Contest, "I Can't Get No
    +Contraception", has been withdrawn after the Pope advised them to
    +pull it out at the last minute.
    +		-- Not the Nine O'Clock News
    +%
     The king arranged a regal marriage for his daughter -- a bond that would unite
     two great kingdoms.  Yet, because the young couple seemed so formal to each
     other, he posted a spy outside the royal wedding chamber and demanded a full
    @@ -13205,7 +13196,7 @@ prohibitive, and the position ridiculous.
     		-- Disraeli, on sex
     %
     The plural of spouse is spice.
    -		-- R.A. Heinlein
    +		-- Robert A. Heinlein
     %
     The police were investigating the mysterious death of a prominent businessman
     who had jumped from a window of his 11th story office.  His voluptuous private
    @@ -13557,7 +13548,7 @@ But had dribbled away all too soon.
     %
     The woman you buy -- and she is the least expensive -- takes a great
     deal of money.  The woman who gives herself takes all your time.
    -		-- Balzac
    +		-- Honore de Balzac
     %
     The word "spine" is, of course, an anagram of "penis".  This is true in
     almost fifty percent of the languages of the Galaxy, and many people
    @@ -13643,7 +13634,7 @@ There are a couple of things about her I greatly admire.
     There are also a lot of nice buildings in Haiphong.  What their
     contributions are to the war effort I don't know, but the desire to
     bomb a virgin building is terrific.
    -		-- Commander Henry Urban Jr.
    +		-- Commander Henry Urban, Jr.
     %
     There are Jews in the world, there are Buddhists,	Every sperm is sacred,
     there are Hindus and Mormons and then			Every sperm is great,
    @@ -13935,6 +13926,11 @@ mind raced with fear "Will it stop?".  Exhausted, he lay down beside her.
     burned as he stared for what seemed an eternity.  Finally, his father spoke.
     	"Son, you ain't supposed to milk the damn cow till mornin'!"
     %
    +They're just jealous because they don't have three
    +wise men and a virgin in the whole organization.
    +		-- Mayor Vincent J. "Buddy" Cianci, on the
    +		   ACLU's suit to have a city nativity scene removed.
    +%
     This Czech walks into police station in 1968 during the Fraternal Assistance.
     Czech:	Hey, out there in the street, a Swiss soldier knocked me down and
     	took my Russian watch.
    @@ -14035,7 +14031,7 @@ This limerick is **SO**FILTHY** that it would offend you.  So I'll put
     
     	Di-dah, di-dah, di-dah di-dah,
     	Di-dah di-dah di-dah, di-dah;
    -		di-dah di-dah di-dah?
    +		Di-dah di-dah di-dah?
     		Di-dah di-dah di-dah.
     	Di-dah di-dah, di-dah di-fuck.
     %
    @@ -14129,12 +14125,12 @@ the second woman.
     	"Frankly," murmured the third woman, "I understand the situation,
     but I fail to see the problem."
     %
    -three-bag ugly, adj:
    +Three-bag ugly, adj.:
     	That's when you put one bag over her head, one bag over your
     	head in case her's falls off, and one over the dog's to keep
     	it from howling.
     
    -four-bag ugly, adj:
    +Four-bag ugly, adj.:
     	When you leave a bag by the door in case someone drops by.
     %
     Through a major bureaucratic error, you are made county coroner.
    @@ -14174,19 +14170,19 @@ Todays title:
     Tonight's piss is tomorrow's Tang.
     		-- An American astronaut
     %
    -tourist, n:
    +Tourist, n.:
     	A pretty girl in Oklahoma.
     %
     Tourist to New Yorker:
     	"Pardon me, sir, do you know what time it is, or should I
     	just go fuck myself?"
     %
    -transvestite, n:
    +Transvestite, n.:
     	Someone who likes to eat, drink, and be Mary.
     %
     Tri Delts; everyone else has.
     %
    -trust me:
    +Trust me:
     	Los Angeles for "Fuck you, your mother, and the horse
     	she rode in on."
     %
    @@ -14529,10 +14525,10 @@ especially if special features and options are utilized.
     vacation;look;find;talk;grep;touch;finger;find;flex;unzip;mount;workbone; \
     fsck;yes;gasp;fsck;yes;eject;umount;make clean;zip;split;done;exit
     %
    -vagina, n:
    +Vagina, n.:
     	The box a penis comes in.
     %
    -vaginal lubricant, n:
    +Vaginal lubricant, n.:
     	A slitty slicker.
     %
     Vandalism On The Upswing!
    @@ -14543,7 +14539,7 @@ Vandalism On The Upswing!
     %
     Vatican upholds ban on contraceptives: "To heir is humane," claims the Pope.
     %
    -Vd, n:
    +VD, n.:
     	The gift that keeps on giving.
     %
     Vegetarians for oral sex -- "The only meat that's fit to eat"
    @@ -14634,7 +14630,7 @@ I need someone to protect		But I'm not waiting on a lady
     		-- Rolling Stones, "Waiting on a Friend"
     %
     Water?  Never touch the stuff!  Fish fuck in it.
    -		-- W.C. Fields
    +		-- W. C. Fields
     %
     We ... make the modern error of dignifying the Individual.  We do everything
     we can to butter him up.  We give him a name, assure him that he has certain
    @@ -14993,7 +14989,7 @@ Giles:	Controlled circumstances.
     		-- Buffy the Vampire Slayer, "Bad Girls"
     		   Season 3, Episode 14
     %
    -wet dream, n:
    +Wet dream, n.:
     	Overnight sensation.
     %
     We've all heard about the woman who married a Field Service engineer but
    @@ -15133,7 +15129,7 @@ Stand up, cop's wife cried, don't take him down,
     Rather be dead six feet in the ground.
     When you come home, you can eat pork and beans,
     I eats more chicken than any man's seen.
    -		-- Willie Dixon, "Backdoor Man", 1961
    +		-- Willie Dixon, "Backdoor Man" (1961)
     %
     When God created man, She was only testing.
     %
    @@ -15167,7 +15163,7 @@ Give me a moron			My father's out of Harvard
     With talented hands		My brother's out of Yale
     I go bar-hopping		Well the guy I took home last night
     And they say "Last call"	Just got out of jail
    -I start shopping 		The way he grabbed and threw me
    +I start shopping		The way he grabbed and threw me
     For a Neanderthal		Oooo, it really got me hot
     				But the way he growled and bit me
     The bigger they come		I hoped he had his shots
    @@ -15393,7 +15389,7 @@ Winning isn't everything, but losing really sucks.
     With a bushel of apples, you can have
     a hell of a time with the doctor's wife.
     %
    -wok, n:
    +Wok, n.:
     	Something to thwow at a wabbit.
     %
     Woman is: finally screwing and your groin and buttocks and thighs ache like
    @@ -15529,7 +15525,7 @@ You can't underestimate the power of fear.
     %
     You come out of a woman and you spend the rest of your life trying to
     get back inside.
    -		--  Heathcote Williams
    +		-- Heathcote Williams
     %
     You have been bitchy since Tuesday and you'll probably get fired today.
     %
    diff --git a/games/fortune/datfiles/fortunes.sp.ok b/games/fortune/datfiles/fortunes.sp.ok
    index f26b5e3798f..2ba73ec389a 100644
    --- a/games/fortune/datfiles/fortunes.sp.ok
    +++ b/games/fortune/datfiles/fortunes.sp.ok
    @@ -205,7 +205,6 @@ Astaire's
     asterisked
     Asterix
     asthma's
    -astonishment's
     Astro
     astrology
     Astroturf
    @@ -217,7 +216,7 @@ Attila
     Auberon
     Auden
     AUDITME
    -Audobon
    +Audubon
     Auerbach
     Aug
     Augier
    @@ -326,7 +325,6 @@ Beatty
     Beaumadine
     Beaumarchais
     Beauvoir
    -becannt
     Becker's
     Beckett
     Beckmann
    @@ -550,7 +548,6 @@ Bruton
     Brutus
     Bruyere
     Brylcreem
    -Bryne's
     Brynner
     Bryson
     BST
    @@ -1020,9 +1017,7 @@ deppart
     deregulated
     dermis
     DeSalvo
    -DesCartes
     Desiree
    -dessicated
     deStalinization
     destitution
     destructure
    @@ -1159,7 +1154,6 @@ Dutsky
     dwelleth
     Dyer's
     Dykes
    -Dykstra
     dyslexic
     Dyson
     Eagleson
    @@ -1240,16 +1234,13 @@ endian
     Enesco
     Enfolding
     England's
    -Englebert
     Englishman's
     ENIACs
     enkindles
     Enm
     Ennius
     Ennui
    -enobled
     ENOTADUCK
    -ensconsed
     Epcot
     Ephron
     EPI
    @@ -1547,7 +1538,6 @@ Garbers
     Gardner's
     garnishment
     Garp
    -Gastly
     Gatling
     Gaulle
     Gauls
    @@ -1580,7 +1570,6 @@ getchar
     Getraenke
     Gettys
     gewerken
    -Ghandi
     gharsley
     Ghostbusters
     Giancana
    @@ -1643,7 +1632,6 @@ Goebbels
     goest
     Goestheveezl
     goeth
    -Goethe's
     Gold's
     Golda
     Goldengrove
    @@ -1656,7 +1644,6 @@ Goldwyn
     Goleta
     Gomme's
     Gondoliers
    -Gondwondaland
     gonna
     Gonnet
     goodbye
    @@ -1670,7 +1657,6 @@ Gordon's
     Gorey
     Gorin
     Gossling
    -Gotama
     Gotlieb
     goto
     goto's
    @@ -2088,7 +2074,6 @@ IRS
     Irulan
     Isaak
     Iso
    -Issac
     Issawi
     Issawi's
     Ist
    @@ -2150,7 +2135,6 @@ joggers
     Jogging
     Johnson's
     Johnston
    -Jonathon
     Jone's
     Jones's
     Jonesboro
    @@ -2374,7 +2358,6 @@ Lapwarmer
     Lardner
     Larkin
     Larkinson's
    -LaRouchefoucauld
     Lascl
     laserbeam
     Lasorda
    @@ -2414,8 +2397,7 @@ Lehrer
     Leia
     Leibe
     Leiber
    -Leibnitz
    -Leibowitz
    +Leibniz
     Leibowitz's
     Leith
     Lem
    @@ -2428,7 +2410,6 @@ lerts
     les
     LeSage
     letez
    -Letterman's
     Lettvin
     Levant
     Levenson
    @@ -2827,7 +2808,6 @@ Moping
     moralists
     Mordecai
     Mordor
    -Morganstern
     Morley
     morons
     Morrisey
    @@ -2907,7 +2887,6 @@ nanocentury
     nanohenry
     nanometers
     Nansen
    -Napolean
     Napoleon's
     narcolepulacyi
     Narnia
    @@ -2930,7 +2909,6 @@ Neantical
     Nebuchadnezzar
     Nebuchadnezzar's
     necesas
    -necessitas
     necessitious
     NecroSoft
     Nehru
    @@ -2984,7 +2962,6 @@ Niven
     Nixon's
     Noah's
     noalias
    -Nobert
     Noelie
     nog
     nogiftlist
    @@ -3053,7 +3030,6 @@ OCP
     Oct
     octalthorpe
     Octopussy
    -Odgen
     Oech
     Oedipa
     Ogborn
    @@ -3172,7 +3148,7 @@ Parnas
     Parnell
     paroxysmally
     Parrafin
    -parthenon
    +Parthenon
     passwd
     pastureland
     Patageometry
    @@ -3340,7 +3316,6 @@ PRL
     PROCESSORs
     Prochnow
     proelium
    -proferred
     profundities
     proletarian
     Propos
    @@ -3455,7 +3430,6 @@ Reichel's
     Reinfeld
     Reinhart
     Reisner's
    -reknowned
     Relaxen
     RENE
     Renegades
    @@ -3531,7 +3505,6 @@ Rosten
     Rotherham
     Rothesay
     Rothschild
    -Rouchefoucauld
     Roumania
     rousers
     Rowlands
    @@ -3653,7 +3626,7 @@ Schweitzer
     Schwiggle
     Schwine
     Scientologist
    -scintilate
    +scintillate
     Scintillae
     Scott's
     Scoville
    @@ -3883,7 +3856,6 @@ Steinbach
     Steinbach's
     Steinbeck
     Steinem
    -Steinham
     Steinman
     Stekel
     Stenderup's
    @@ -3926,7 +3898,7 @@ Sugarcreek
     Suggoth
     Sulu
     Sumeria
    -Summatra
    +Sumatra
     sunbathing
     SunCheckup
     SUNKIST
    @@ -3987,7 +3959,6 @@ Talking's
     Tallulah
     tamperest
     Tanenbaum
    -Tannenbaum
     tannogallate
     tapeworms
     tapioca
    @@ -4150,7 +4121,6 @@ TYDFS
     tyg
     typefaces
     Tyroon
    -tyrranize
     tzu
     Ubi
     UDA
    @@ -4168,7 +4138,6 @@ unamerican
     unbegot
     unbelievers
     UNC
    -Uncatylised
     undemanding
     underachiever
     Unger
    @@ -4273,7 +4242,7 @@ vodkas
     Vogon
     Vogons
     voist
    -Volkswagon
    +Volkswagen
     Vollyballocracy
     Voltarine
     von
    @@ -4373,7 +4342,6 @@ whomped
     Whooa
     Whoopie
     Wickersham
    -wierdest
     Wiggam
     Wihelminalaan
     Wiker's
    @@ -4391,7 +4359,6 @@ Winchell
     Windex
     windstorms
     Winfrey
    -Winie
     winnowed
     Winny
     Winokur
    @@ -4423,7 +4390,6 @@ woodlands
     Woodstock
     Woodward's
     Wookiee
    -Woolcott
     Woolf
     Woollcott
     worketh
    @@ -4446,7 +4412,6 @@ Xaviera
     XCVI
     xen
     xenophobic
    -Xercies
     XGP
     XIIdigitation
     XINU
    diff --git a/games/fortune/datfiles/limerick b/games/fortune/datfiles/limerick
    index 4852840a73e..a0344a8a6fc 100644
    --- a/games/fortune/datfiles/limerick
    +++ b/games/fortune/datfiles/limerick
    @@ -827,8 +827,8 @@ And such is the Kingdom of Heaven.
     %
     A pretty young lady named Vogel
     Once sat herself down on a molehill.
    -     A curious mole
    -     Nosed into her hole --
    +	A curious mole
    +	Nosed into her hole --
     Ms. Vogel's okay, but the mole's ill.
     %
     A pretty young maiden from France
    @@ -854,7 +854,7 @@ Said, I'm the match for any machine.
     	My secret's aversion,
     	To loops and recursion,
     Just acres of in-line routine.
    -		-- W.J. Wilson
    +		-- W. J. Wilson
     %
     A progressive professor named Winners
     Held classes each evening for sinners.
    @@ -1097,7 +1097,7 @@ Reproached for not acting quite primly
     	I know sex isn't love,
     But it's such an entrancing facsimile."
     %
    -A water pipe suited miss Hunt;
    +A water pipe suited Miss Hunt;
     She used it for many a bunt.
     	But the unlucky wench
     	Got it caught in her trench ---
    @@ -2048,9 +2048,9 @@ Who canoed with a girl in Bermuder.
     So McGru took an oar and subduder.
     %
     There once was a man named McSweeny
    -Who spilled lots of gin on his weeney
    -	So just to be couth
    -	He added vermouth
    +Who spilled lots of gin on his weeney.
    +	So just to be couth,
    +	He added vermouth,
     And slipped his best girl a martini.
     %
     There once was a man named Parridge
    @@ -2259,7 +2259,7 @@ There was a gay countess of Bray,
     And you may think it odd when I say,
     	That in spite of high station,
     	Rank and education,
    -She always spelled cunt with a 'k'.
    +She always spelled cunt with a "k."
     %
     There was a gay dog from Ontario
     Who fancied himself a Lothario.
    @@ -2564,7 +2564,7 @@ There was a young fellow named Paul
     Who confessed, "I have only one ball.
     	But the size of my prick
     	Is God's dirtiest trick,
    -For my girls always ask, 'Is that all?'"
    +For my girls always ask, `Is that all?'"
     %
     There was a young fellow named Pell
     Who didn't like cunt very well.
    @@ -3043,7 +3043,7 @@ Who strung himself up with a cord
     	Said he, of his work
     	(Ere the rope snapped with a jerk)
     "I am leaving because I am bored."
    -		- E.A. Guest
    +		-- E. A. Guest
     %
     There was a young lad named McFee
     Who was stung in the balls by a bee
    @@ -4423,7 +4423,7 @@ Who was stung in the arm by a wasp.
     	When asked, "Does it hurt?"
     	He replied, "No, it doesn't.
     I'm so glad that it wasn't a hornet."
    -		-- W.S. Gilbert
    +		-- W. S. Gilbert
     %
     There was an old man of Tagore
     Whose tool was a yard long or more,
    diff --git a/games/fortune/datfiles/startrek b/games/fortune/datfiles/startrek
    index f45a0e20573..af3f9d4ef95 100644
    --- a/games/fortune/datfiles/startrek
    +++ b/games/fortune/datfiles/startrek
    @@ -507,6 +507,7 @@ The joys of love made her human and the agonies of love destroyed her.
     %
     The man on tops walks a lonely street; the "chain" of command is often
     a noose.
    +		-- McCoy, "The Conscience of the King," stardate 2818.9
     %
     The more complex the mind, the greater the need for the simplicity of
     play.
    @@ -656,7 +657,7 @@ What kind of love is that?  Not to be loved; never to have shown love.
     		-- Commissioner Nancy Hedford, "Metamorphosis",
     		   stardate 3219.8
     %
    -When a child is taught ... its programmed with simple instructions --
    +When a child is taught ... it's programmed with simple instructions --
     and at some point, if its mind develops properly, it exceeds the sum of
     what it was taught, thinks independently.
     		-- Dr. Richard Daystrom, "The Ultimate Computer",
    @@ -689,7 +690,7 @@ sheer horror than the male of the species.
     		-- Spock, "Wolf in the Fold", stardate 3615.4
     %
     Women professionals do tend to over-compensate.
    -		-- Dr. Elizabeth Dehaver, "Where No Man Has Gone Before",
    +		-- Dr. Elizabeth Dehner, "Where No Man Has Gone Before",
     		   stardate 1312.9.
     %
     Worlds are conquered, galaxies destroyed -- but a woman is always a
    diff --git a/games/fortune/datfiles/zippy b/games/fortune/datfiles/zippy
    index a613036e2d4..7c43436f93c 100644
    --- a/games/fortune/datfiles/zippy
    +++ b/games/fortune/datfiles/zippy
    @@ -178,7 +178,7 @@ LEFT at th'HOLIDAY INN!!  JOIN the CREDIT WORLD!!  MAKE me an OFFER!!!
     CONGRATULATIONS!  Now should I make thinly veiled comments about
     DIGNITY, self-esteem and finding TRUE FUN in your RIGHT VENTRICLE??
     %
    -Content:  80% POLYESTER, 20% DACRONi ... The waitress's UNIFORM sheds
    +Content:  80% POLYESTER, 20% DACRON ... The waitress's UNIFORM sheds
     TARTAR SAUCE like an 8" by 10" GLOSSY ...
     %
     Could I have a drug overdose?
    @@ -200,7 +200,7 @@ DIDI ... is that a MARTIAN name, or, are we in ISRAEL?
     %
     Didn't I buy a 1951 Packard from you last March in Cairo?
     %
    -Disco oil bussing will create a throbbing naugahide pipeline running
    +Disco oil bussing will create a throbbing naugahyde pipeline running
     straight to the tropics from the rug producing regions and devalue the
     dollar!
     %
    @@ -290,7 +290,7 @@ He is the MELBA-BEING ... the ANGEL CAKE ... XEROX him ... XEROX him --
     %
     He probably just wants to take over my CELLS and then EXPLODE inside me
     like a BARREL of runny CHOPPED LIVER!  Or maybe he'd like to
    -PSYCHOLIGICALLY TERRORISE ME until I have no objection to a RIGHT-WING
    +PSYCHOLOGICALLY TERRORISE ME until I have no objection to a RIGHT-WING
     MILITARY TAKEOVER of my apartment!!  I guess I should call AL PACINO!
     %
     Hello?  Enema Bondage?  I'm calling because I want to be happy, I
    @@ -351,7 +351,7 @@ MOUSTACHE ...  Have you ever noticed th' way it radiates SINCERITY,
     HONESTY & WARMTH?  It's a MOUSTACHE you want to take HOME and introduce
     to NANCY SINATRA!
     %
    -How many returned bricklayers from FLORIDA are out purchasing PENCIL
    +How many retired bricklayers from FLORIDA are out purchasing PENCIL
     SHARPENERS right NOW??
     %
     How's it going in those MODULAR LOVE UNITS??
    @@ -604,7 +604,7 @@ if it GLISTENS, gobble it!!
     %
     If our behavior is strict, we do not need fun!
     %
    -If Robert Di Niro assassinates Walter Slezak, will Jodie Foster marry
    +If Robert De Niro assassinates Walter Slezak, will Jodie Foster marry
     Bonzo??
     %
     I'll eat ANYTHING that's BRIGHT BLUE!!
    @@ -802,7 +802,7 @@ ASHTRAYS ...
     %
     Let me do my TRIBUTE to FISHNET STOCKINGS ...
     %
    -Let's all show human CONCERN for REVERAND MOON's legal difficulties!!
    +Let's all show human CONCERN for REVEREND MOON's legal difficulties!!
     %
     Let's send the Russians defective lifestyle accessories!
     %
    
    From b9b10dc47b767ac12944ba339694c69675ece580 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Wed, 14 Apr 2010 00:50:18 +0000
    Subject: [PATCH 1942/2592] MFC r206364:   Partial revert r204545.   Just
     relying on status LE ownership of status block seems to cause   poor
     performance. Always read current status index register first   and then check
     status ownership as we had before. Accessing status   index register seems to
     trigger immediate status update if   controller have pending status updates.
    
      Reported by:	Andre Albsmeier  siemens dot com>
      Tested by:	Andre Albsmeier  siemens dot com>
    ---
     sys/dev/msk/if_msk.c | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
    index 9f97a87ecf3..90b794c6a6d 100644
    --- a/sys/dev/msk/if_msk.c
    +++ b/sys/dev/msk/if_msk.c
    @@ -3327,6 +3327,9 @@ msk_handle_events(struct msk_softc *sc)
     	uint32_t control, status;
     	int cons, len, port, rxprog;
     
    +	if (sc->msk_stat_cons == CSR_READ_2(sc, STAT_PUT_IDX))
    +		return (0);
    +
     	/* Sync status LEs. */
     	bus_dmamap_sync(sc->msk_stat_tag, sc->msk_stat_map,
     	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
    @@ -3407,7 +3410,7 @@ msk_handle_events(struct msk_softc *sc)
     	if (rxput[MSK_PORT_B] > 0)
     		msk_rxput(sc->msk_if[MSK_PORT_B]);
     
    -	return (rxprog > sc->msk_process_limit ? EAGAIN : 0);
    +	return (sc->msk_stat_cons != CSR_READ_2(sc, STAT_PUT_IDX));
     }
     
     static void
    
    From 8451de87b9302b8efa3e9b0955a6acae286ed481 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Wed, 14 Apr 2010 01:12:24 +0000
    Subject: [PATCH 1943/2592] MFC r206433:   Add preliminary support for
     8168E/8111E PCIe controller.   While I'm here simplify device description
     string.
    
      Tested by:	Michael Beckmann < michael <> apfel dot de >
    ---
     sys/dev/re/if_re.c | 14 ++++++++++++--
     sys/pci/if_rlreg.h |  3 +++
     2 files changed, 15 insertions(+), 2 deletions(-)
    
    diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
    index 978580179d5..80915061c7d 100644
    --- a/sys/dev/re/if_re.c
    +++ b/sys/dev/re/if_re.c
    @@ -174,8 +174,7 @@ static struct rl_type re_devs[] = {
     	{ RT_VENDORID, RT_DEVICEID_8101E, 0,
     	    "RealTek 8101E/8102E/8102EL/8103E PCIe 10/100baseTX" },
     	{ RT_VENDORID, RT_DEVICEID_8168, 0,
    -	    "RealTek 8168/8168B/8168C/8168CP/8168D/8168DP/"
    -	    "8111B/8111C/8111CP/8111DP PCIe Gigabit Ethernet" },
    +	    "RealTek 8168/8111 B/C/CP/D/DP/E PCIe Gigabit Ethernet" },
     	{ RT_VENDORID, RT_DEVICEID_8169, 0,
     	    "RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" },
     	{ RT_VENDORID, RT_DEVICEID_8169SC, 0,
    @@ -220,6 +219,7 @@ static struct rl_hwrev re_hwrevs[] = {
     	{ RL_HWREV_8168CP, RL_8169, "8168CP/8111CP"},
     	{ RL_HWREV_8168D, RL_8169, "8168D/8111D"},
     	{ RL_HWREV_8168DP, RL_8169, "8168DP/8111DP"},
    +	{ RL_HWREV_8168E, RL_8169, "8168E/8111E"},
     	{ 0, 0, NULL }
     };
     
    @@ -1310,6 +1310,11 @@ re_attach(device_t dev)
     		 */
     		sc->rl_flags |= RL_FLAG_NOJUMBO;
     		break;
    +	case RL_HWREV_8168E:
    +		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM |
    +		    RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT |
    +		    RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD | RL_FLAG_NOJUMBO;
    +		break;
     	case RL_HWREV_8169_8110SB:
     	case RL_HWREV_8169_8110SBL:
     	case RL_HWREV_8169_8110SC:
    @@ -1393,6 +1398,8 @@ re_attach(device_t dev)
     	}
     
     	/* Take PHY out of power down mode. */
    +	if ((sc->rl_flags & RL_FLAG_PHYWAKE_PM) != 0)
    +		CSR_WRITE_1(sc, RL_PMCH, CSR_READ_1(sc, RL_PMCH) | 0x80);
     	if ((sc->rl_flags & RL_FLAG_PHYWAKE) != 0) {
     		re_gmii_writereg(dev, 1, 0x1f, 0);
     		re_gmii_writereg(dev, 1, 0x0e, 0);
    @@ -3135,6 +3142,9 @@ re_setwol(struct rl_softc *sc)
     		v |= RL_CFG5_WOL_LANWAKE;
     	CSR_WRITE_1(sc, RL_CFG5, v);
     
    +	if ((ifp->if_capenable & IFCAP_WOL) != 0 &&
    +	    (sc->rl_flags & RL_FLAG_PHYWAKE_PM) != 0)
    +		CSR_WRITE_1(sc, RL_PMCH, CSR_READ_1(sc, RL_PMCH) & ~0x80);
     	/*
     	 * It seems that hardware resets its link speed to 100Mbps in
     	 * power down mode so switching to 100Mbps in driver is not
    diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h
    index b5752895a85..e8fddc9428b 100644
    --- a/sys/pci/if_rlreg.h
    +++ b/sys/pci/if_rlreg.h
    @@ -133,6 +133,7 @@
     #define RL_GMEDIASTAT		0x006C	/* 8 bits */
     #define RL_MACDBG		0x006D	/* 8 bits, 8168C SPIN2 only */
     #define RL_GPIO			0x006E	/* 8 bits, 8168C SPIN2 only */
    +#define RL_PMCH			0x006F	/* 8 bits */
     #define RL_MAXRXPKTLEN		0x00DA	/* 16 bits, chip multiplies by 8 */
     #define RL_GTXSTART		0x0038	/* 8 bits */
     
    @@ -162,6 +163,7 @@
     #define RL_HWREV_8102EL_SPIN1	0x24c00000
     #define RL_HWREV_8168D		0x28000000
     #define RL_HWREV_8168DP		0x28800000
    +#define RL_HWREV_8168E		0x2C000000
     #define RL_HWREV_8168_SPIN1	0x30000000
     #define RL_HWREV_8100E		0x30800000
     #define RL_HWREV_8101E		0x34000000
    @@ -884,6 +886,7 @@ struct rl_softc {
     	uint32_t		rl_flags;
     #define	RL_FLAG_MSI		0x0001
     #define	RL_FLAG_AUTOPAD		0x0002
    +#define	RL_FLAG_PHYWAKE_PM	0x0004
     #define	RL_FLAG_PHYWAKE		0x0008
     #define	RL_FLAG_NOJUMBO		0x0010
     #define	RL_FLAG_PAR		0x0020
    
    From f49339f5cdd50e3402b90e252f7c0c86d90af197 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Wed, 14 Apr 2010 01:22:33 +0000
    Subject: [PATCH 1944/2592] MFC r206436:   Consistently use capital letters.
    
    ---
     sys/pci/if_rlreg.h | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h
    index e8fddc9428b..7d2c7e4ad65 100644
    --- a/sys/pci/if_rlreg.h
    +++ b/sys/pci/if_rlreg.h
    @@ -160,7 +160,7 @@
     #define RL_HWREV_8169_8110SB	0x10000000
     #define RL_HWREV_8169_8110SC	0x18000000
     #define RL_HWREV_8102EL		0x24800000
    -#define RL_HWREV_8102EL_SPIN1	0x24c00000
    +#define RL_HWREV_8102EL_SPIN1	0x24C00000
     #define RL_HWREV_8168D		0x28000000
     #define RL_HWREV_8168DP		0x28800000
     #define RL_HWREV_8168E		0x2C000000
    @@ -182,7 +182,7 @@
     #define RL_HWREV_8139C		0x74000000
     #define RL_HWREV_8139D		0x74400000
     #define RL_HWREV_8139CPLUS	0x74800000
    -#define RL_HWREV_8101		0x74c00000
    +#define RL_HWREV_8101		0x74C00000
     #define RL_HWREV_8100		0x78800000
     #define RL_HWREV_8169_8110SBL	0x7CC00000
     #define RL_HWREV_8169_8110SCE	0x98000000
    
    From 066adacfb11b2642f7618ccd395bfcdebd98296a Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Wed, 14 Apr 2010 03:13:02 +0000
    Subject: [PATCH 1945/2592] MFC: r205941 This patch should fix handling of byte
     range locks locally on the server for the experimental nfs server. When
     enabled by setting vfs.newnfs.locallocks_enable to non-zero, the experimental
     nfs server will now acquire byte range locks on the file on behalf of NFSv4
     clients, such that lock conflicts between the NFSv4 clients and processes
     running locally on the server, will be recognized and handled correctly.
    
    ---
     sys/fs/nfs/nfs_commonport.c      |   8 +-
     sys/fs/nfs/nfs_commonsubs.c      |  13 +
     sys/fs/nfs/nfs_var.h             |   1 +
     sys/fs/nfs/nfsport.h             |   3 +
     sys/fs/nfs/nfsrvstate.h          |  15 +
     sys/fs/nfsserver/nfs_nfsdstate.c | 774 ++++++++++++++++++++-----------
     6 files changed, 530 insertions(+), 284 deletions(-)
    
    diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
    index c9ae4a820a1..56ccf1b85ee 100644
    --- a/sys/fs/nfs/nfs_commonport.c
    +++ b/sys/fs/nfs/nfs_commonport.c
    @@ -82,7 +82,8 @@ SYSCTL_STRING(_vfs_newnfs, OID_AUTO, callback_addr, CTLFLAG_RW,
      */
     MALLOC_DEFINE(M_NEWNFSRVCACHE, "NFSD srvcache", "NFSD Server Request Cache");
     MALLOC_DEFINE(M_NEWNFSDCLIENT, "NFSD V4client", "NFSD V4 Client Id");
    -MALLOC_DEFINE(M_NEWNFSDSTATE, "NFSD V4state", "NFSD V4 State (Openowner, Open, Lockowner, Delegation");
    +MALLOC_DEFINE(M_NEWNFSDSTATE, "NFSD V4state",
    +    "NFSD V4 State (Openowner, Open, Lockowner, Delegation");
     MALLOC_DEFINE(M_NEWNFSDLOCK, "NFSD V4lock", "NFSD V4 byte range lock");
     MALLOC_DEFINE(M_NEWNFSDLOCKFILE, "NFSD lckfile", "NFSD Open/Lock file");
     MALLOC_DEFINE(M_NEWNFSSTRING, "NFSD string", "NFSD V4 long string");
    @@ -97,7 +98,10 @@ MALLOC_DEFINE(M_NEWNFSCLLOCKOWNER, "NFSCL lckown", "NFSCL Lock Owner");
     MALLOC_DEFINE(M_NEWNFSCLLOCK, "NFSCL lck", "NFSCL Lock");
     MALLOC_DEFINE(M_NEWNFSV4NODE, "NEWNFSnode", "New nfs vnode");
     MALLOC_DEFINE(M_NEWNFSDIRECTIO, "NEWdirectio", "New nfs Direct IO buffer");
    -MALLOC_DEFINE(M_NEWNFSDIROFF, "Newnfscl_diroff", "New NFS directory offset data");
    +MALLOC_DEFINE(M_NEWNFSDIROFF, "NFSCL diroffdiroff",
    +    "New NFS directory offset data");
    +MALLOC_DEFINE(M_NEWNFSDROLLBACK, "NFSD rollback",
    +    "New NFS local lock rollback");
     
     /*
      * Definition of mutex locks.
    diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
    index b1a7051359b..0aa185d5c4a 100644
    --- a/sys/fs/nfs/nfs_commonsubs.c
    +++ b/sys/fs/nfs/nfs_commonsubs.c
    @@ -1834,6 +1834,19 @@ nfsv4_getref(struct nfsv4lock *lp, int *isleptp, void *mutex)
     	lp->nfslock_usecnt++;
     }
     
    +/*
    + * Test for a lock. Return 1 if locked, 0 otherwise.
    + */
    +APPLESTATIC int
    +nfsv4_testlock(struct nfsv4lock *lp)
    +{
    +
    +	if ((lp->nfslock_lock & NFSV4LOCK_LOCK) == 0 &&
    +	    lp->nfslock_usecnt == 0)
    +		return (0);
    +	return (1);
    +}
    +
     /*
      * Wake up anyone sleeping, waiting for this lock.
      */
    diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
    index 5864250c555..7df321d1470 100644
    --- a/sys/fs/nfs/nfs_var.h
    +++ b/sys/fs/nfs/nfs_var.h
    @@ -251,6 +251,7 @@ int nfsv4_lock(struct nfsv4lock *, int, int *, void *);
     void nfsv4_unlock(struct nfsv4lock *, int);
     void nfsv4_relref(struct nfsv4lock *);
     void nfsv4_getref(struct nfsv4lock *, int *, void *);
    +int nfsv4_testlock(struct nfsv4lock *);
     int nfsrv_mtostr(struct nfsrv_descript *, char *, int);
     int nfsrv_checkutf8(u_int8_t *, int);
     int newnfs_sndlock(int *);
    diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
    index f320316be7d..cad7d05a654 100644
    --- a/sys/fs/nfs/nfsport.h
    +++ b/sys/fs/nfs/nfsport.h
    @@ -543,6 +543,7 @@ void nfsrvd_rcv(struct socket *, void *, int);
     #define	NFSSTATESPINLOCK	extern struct mtx nfs_state_mutex
     #define	NFSLOCKSTATE()		mtx_lock(&nfs_state_mutex)
     #define	NFSUNLOCKSTATE()	mtx_unlock(&nfs_state_mutex)
    +#define	NFSSTATEMUTEXPTR	(&nfs_state_mutex)
     #define	NFSREQSPINLOCK		extern struct mtx nfs_req_mutex
     #define	NFSLOCKREQ()		mtx_lock(&nfs_req_mutex)
     #define	NFSUNLOCKREQ()		mtx_unlock(&nfs_req_mutex)
    @@ -678,6 +679,7 @@ MALLOC_DECLARE(M_NEWNFSDIROFF);
     MALLOC_DECLARE(M_NEWNFSV4NODE);
     MALLOC_DECLARE(M_NEWNFSDIRECTIO);
     MALLOC_DECLARE(M_NEWNFSMNT);
    +MALLOC_DECLARE(M_NEWNFSDROLLBACK);
     #define	M_NFSRVCACHE	M_NEWNFSRVCACHE
     #define	M_NFSDCLIENT	M_NEWNFSDCLIENT
     #define	M_NFSDSTATE	M_NEWNFSDSTATE
    @@ -696,6 +698,7 @@ MALLOC_DECLARE(M_NEWNFSMNT);
     #define	M_NFSDIROFF	M_NEWNFSDIROFF
     #define	M_NFSV4NODE	M_NEWNFSV4NODE
     #define	M_NFSDIRECTIO	M_NEWNFSDIRECTIO
    +#define	M_NFSDROLLBACK	M_NEWNFSDROLLBACK
     
     #define	NFSINT_SIGMASK(set) 						\
     	(SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) ||	\
    diff --git a/sys/fs/nfs/nfsrvstate.h b/sys/fs/nfs/nfsrvstate.h
    index 629b18c64c8..964b998aed0 100644
    --- a/sys/fs/nfs/nfsrvstate.h
    +++ b/sys/fs/nfs/nfsrvstate.h
    @@ -184,6 +184,17 @@ struct nfslockconflict {
     	u_char			cl_owner[NFSV4_OPAQUELIMIT];
     };
     
    +/*
    + * This structure is used to keep track of local locks that might need
    + * to be rolled back.
    + */
    +struct nfsrollback {
    +	LIST_ENTRY(nfsrollback)	rlck_list;
    +	uint64_t		rlck_first;
    +	uint64_t		rlck_end;
    +	int			rlck_type;
    +};
    +
     /*
      * This structure refers to a file for which lock(s) and/or open(s) exist.
      * Searched via hash table on file handle or found via the back pointer from an
    @@ -193,8 +204,12 @@ struct nfslockfile {
     	LIST_HEAD(, nfsstate)	lf_open;	/* Open list */
     	LIST_HEAD(, nfsstate)	lf_deleg;	/* Delegation list */
     	LIST_HEAD(, nfslock)	lf_lock;	/* Lock list */
    +	LIST_HEAD(, nfslock)	lf_locallock;	/* Local lock list */
    +	LIST_HEAD(, nfsrollback) lf_rollback;	/* Local lock rollback list */
     	LIST_ENTRY(nfslockfile)	lf_hash;	/* Hash list entry */
     	fhandle_t		lf_fh;		/* The file handle */
    +	struct nfsv4lock	lf_locallock_lck; /* serialize local locking */
    +	int			lf_usecount;	/* Ref count for locking */
     };
     
     /*
    diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
    index 3e38cf48e1f..a4df1ed9c33 100644
    --- a/sys/fs/nfsserver/nfs_nfsdstate.c
    +++ b/sys/fs/nfsserver/nfs_nfsdstate.c
    @@ -65,11 +65,11 @@ static void nfsrv_dumpaclient(struct nfsclient *clp,
         struct nfsd_dumpclients *dumpp);
     static void nfsrv_freeopenowner(struct nfsstate *stp, int cansleep,
         NFSPROC_T *p);
    -static int nfsrv_freeopen(struct nfsstate *stp, int *freedlockp,
    -    int cansleep, NFSPROC_T *p);
    -static int nfsrv_freelockowner(struct nfsstate *stp, int *freedlockp,
    -    int cansleep, NFSPROC_T *p);
    -static int nfsrv_freeallnfslocks(struct nfsstate *stp, int *freedlockp,
    +static int nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep,
    +    NFSPROC_T *p);
    +static void nfsrv_freelockowner(struct nfsstate *stp, vnode_t vp, int cansleep,
    +    NFSPROC_T *p);
    +static void nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp,
         int cansleep, NFSPROC_T *p);
     static void nfsrv_freenfslock(struct nfslock *lop);
     static void nfsrv_freenfslockfile(struct nfslockfile *lfp);
    @@ -80,8 +80,8 @@ static void nfsrv_getowner(struct nfsstatehead *hp, struct nfsstate *new_stp,
         struct nfsstate **stpp);
     static int nfsrv_getlockfh(vnode_t vp, u_short flags,
         struct nfslockfile **new_lfpp, fhandle_t *nfhp, NFSPROC_T *p);
    -static int nfsrv_getlockfile(u_short flags,
    -    struct nfslockfile **new_lfpp, struct nfslockfile **lfpp, fhandle_t *nfhp);
    +static int nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp,
    +    struct nfslockfile **lfpp, fhandle_t *nfhp, int lockit);
     static void nfsrv_insertlock(struct nfslock *new_lop,
         struct nfslock *insert_lop, struct nfsstate *stp, struct nfslockfile *lfp);
     static void nfsrv_updatelock(struct nfsstate *stp, struct nfslock **new_lopp,
    @@ -109,9 +109,20 @@ static time_t nfsrv_leaseexpiry(void);
     static void nfsrv_delaydelegtimeout(struct nfsstate *stp);
     static int nfsrv_checkseqid(struct nfsrv_descript *nd, u_int32_t seqid,
         struct nfsstate *stp, struct nfsrvcache *op);
    -static void nfsrv_locallocks(vnode_t vp, struct nfslockfile *lfp,
    -    NFSPROC_T *p);
     static int nfsrv_nootherstate(struct nfsstate *stp);
    +static int nfsrv_locallock(vnode_t vp, struct nfslockfile *lfp, int flags,
    +    uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p);
    +static void nfsrv_localunlock(vnode_t vp, struct nfslockfile *lfp,
    +    uint64_t init_first, uint64_t init_end, NFSPROC_T *p);
    +static int nfsrv_dolocal(vnode_t vp, struct nfslockfile *lfp, int flags,
    +    int oldflags, uint64_t first, uint64_t end, struct nfslockconflict *cfp,
    +    NFSPROC_T *p);
    +static void nfsrv_locallock_rollback(vnode_t vp, struct nfslockfile *lfp,
    +    NFSPROC_T *p);
    +static void nfsrv_locallock_commit(struct nfslockfile *lfp, int flags,
    +    uint64_t first, uint64_t end);
    +static void nfsrv_locklf(struct nfslockfile *lfp);
    +static void nfsrv_unlocklf(struct nfslockfile *lfp);
     
     /*
      * Scan the client list for a match and either return the current one,
    @@ -683,7 +694,7 @@ nfsrv_dumplocks(vnode_t vp, struct nfsd_dumplocks *ldumpp, int maxcnt,
     	ret = nfsrv_getlockfh(vp, 0, NULL, &nfh, p);
     	NFSLOCKSTATE();
     	if (!ret)
    -		ret = nfsrv_getlockfile(0, NULL, &lfp, &nfh);
    +		ret = nfsrv_getlockfile(0, NULL, &lfp, &nfh, 0);
     	if (ret) {
     		ldumpp[0].ndlck_clid.nclid_idlen = 0;
     		NFSUNLOCKSTATE();
    @@ -927,9 +938,8 @@ nfsrv_cleanclient(struct nfsclient *clp, NFSPROC_T *p)
     {
     	struct nfsstate *stp, *nstp;
     
    -	LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) {
    +	LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp)
     		nfsrv_freeopenowner(stp, 1, p);
    -	}
     }
     
     /*
    @@ -993,7 +1003,10 @@ nfsrv_freedeleg(struct nfsstate *stp)
     	LIST_REMOVE(stp, ls_file);
     	lfp = stp->ls_lfp;
     	if (LIST_EMPTY(&lfp->lf_open) &&
    -	    LIST_EMPTY(&lfp->lf_lock) && LIST_EMPTY(&lfp->lf_deleg))
    +	    LIST_EMPTY(&lfp->lf_lock) && LIST_EMPTY(&lfp->lf_deleg) &&
    +	    LIST_EMPTY(&lfp->lf_locallock) && LIST_EMPTY(&lfp->lf_rollback) &&
    +	    lfp->lf_usecount == 0 &&
    +	    nfsv4_testlock(&lfp->lf_locallock_lck) == 0)
     		nfsrv_freenfslockfile(lfp);
     	FREE((caddr_t)stp, M_NFSDSTATE);
     	newnfsstats.srvdelegates--;
    @@ -1031,22 +1044,26 @@ nfsrv_freeopenowner(struct nfsstate *stp, int cansleep, NFSPROC_T *p)
      * This function frees an open (nfsstate open structure) with all associated
      * lock_owners and locks. It also frees the nfslockfile structure iff there
      * are no other opens on the file.
    - * Must be called with soft clock interrupts disabled.
      * Returns 1 if it free'd the nfslockfile, 0 otherwise.
      */
     static int
    -nfsrv_freeopen(struct nfsstate *stp, int *freedlockp, int cansleep,
    -    NFSPROC_T *p)
    +nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, NFSPROC_T *p)
     {
     	struct nfsstate *nstp, *tstp;
     	struct nfslockfile *lfp;
    -	int ret = 0, ret2;
    +	int ret;
     
     	LIST_REMOVE(stp, ls_hash);
     	LIST_REMOVE(stp, ls_list);
     	LIST_REMOVE(stp, ls_file);
     
     	lfp = stp->ls_lfp;
    +	/*
    +	 * Now, free all lockowners associated with this open.
    +	 */
    +	LIST_FOREACH_SAFE(tstp, &stp->ls_open, ls_list, nstp)
    +		nfsrv_freelockowner(tstp, vp, cansleep, p);
    +
     	/*
     	 * The nfslockfile is freed here if there are no locks
     	 * associated with the open.
    @@ -1054,22 +1071,15 @@ nfsrv_freeopen(struct nfsstate *stp, int *freedlockp, int cansleep,
     	 * nfslockfile structure can be freed via nfsrv_freelockowner().
     	 * (That is why the call must be here instead of after the loop.)
     	 */
    -	if (LIST_EMPTY(&lfp->lf_open) && LIST_EMPTY(&lfp->lf_lock) &&
    -	    LIST_EMPTY(&lfp->lf_deleg)) {
    +	if (lfp != NULL && LIST_EMPTY(&lfp->lf_open) &&
    +	    LIST_EMPTY(&lfp->lf_deleg) && LIST_EMPTY(&lfp->lf_lock) &&
    +	    LIST_EMPTY(&lfp->lf_locallock) && LIST_EMPTY(&lfp->lf_rollback) &&
    +	    lfp->lf_usecount == 0 &&
    +	    (cansleep != 0 || nfsv4_testlock(&lfp->lf_locallock_lck) == 0)) {
     		nfsrv_freenfslockfile(lfp);
     		ret = 1;
    -	}
    -	/*
    -	 * Now, free all lockowners associated with this open.
    -	 */
    -	nstp = LIST_FIRST(&stp->ls_open);
    -	while (nstp != LIST_END(&stp->ls_open)) {
    -		tstp = nstp;
    -		nstp = LIST_NEXT(nstp, ls_list);
    -		ret2 = nfsrv_freelockowner(tstp, freedlockp, cansleep, p);
    -		if (ret == 0 && ret2 != 0)
    -			ret = ret2;
    -	}
    +	} else
    +		ret = 0;
     	FREE((caddr_t)stp, M_NFSDSTATE);
     	newnfsstats.srvopens--;
     	nfsrv_openpluslock--;
    @@ -1078,79 +1088,76 @@ nfsrv_freeopen(struct nfsstate *stp, int *freedlockp, int cansleep,
     
     /*
      * Frees a lockowner and all associated locks.
    - * It also frees the nfslockfile structure, if there are no more
    - * references to it.
    - * Must be called with soft clock interrupts disabled.
    - * Returns 1 if it free'd the nfslockfile structure, 1 otherwise.
      */
    -static int
    -nfsrv_freelockowner(struct nfsstate *stp, int *freedlockp, int cansleep,
    +static void
    +nfsrv_freelockowner(struct nfsstate *stp, vnode_t vp, int cansleep,
         NFSPROC_T *p)
     {
    -	int ret;
     
     	LIST_REMOVE(stp, ls_hash);
     	LIST_REMOVE(stp, ls_list);
    -	ret = nfsrv_freeallnfslocks(stp, freedlockp, cansleep, p);
    +	nfsrv_freeallnfslocks(stp, vp, cansleep, p);
     	if (stp->ls_op)
     		nfsrvd_derefcache(stp->ls_op);
     	FREE((caddr_t)stp, M_NFSDSTATE);
     	newnfsstats.srvlockowners--;
     	nfsrv_openpluslock--;
    -	return (ret);
     }
     
     /*
      * Free all the nfs locks on a lockowner.
    - * Returns 1 if it free'd the nfslockfile structure, 0 otherwise.
    - * If any byte range lock is free'd, *freedlockp is set to 1.
      */
    -static int
    -nfsrv_freeallnfslocks(struct nfsstate *stp, int *freedlockp, int cansleep,
    +static void
    +nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep,
         NFSPROC_T *p)
     {
     	struct nfslock *lop, *nlop;
    -	struct nfslockfile *lfp = NULL, *olfp = NULL;
    -	int ret = 0;
    +	struct nfsrollback *rlp, *nrlp;
    +	struct nfslockfile *lfp = NULL;
    +	int gottvp = 0;
    +	vnode_t tvp = NULL;
     
     	lop = LIST_FIRST(&stp->ls_lock);
     	while (lop != LIST_END(&stp->ls_lock)) {
     		nlop = LIST_NEXT(lop, lo_lckowner);
     		/*
    -		 * Since locks off a lockowner are ordered by
    -		 * file, you should update the local locks when
    -		 * you hit the next file OR the end of the lock
    -		 * list. If there are no locks for other owners,
    -		 * it must be done before the lockowner is discarded.
    -		 * (All this only applies if cansleep == 1.)
    +		 * Since all locks should be for the same file, lfp should
    +		 * not change.
     		 */
    -		olfp = lfp;
    -		lfp = lop->lo_lfp;
    -		nfsrv_freenfslock(lop);
    -		if (freedlockp)
    -			*freedlockp = 1;
    -		if (LIST_EMPTY(&lfp->lf_open) && LIST_EMPTY(&lfp->lf_lock) &&
    -		    LIST_EMPTY(&lfp->lf_deleg)) {
    -			if (cansleep)
    -				nfsrv_locallocks(NULL, lfp, p);
    -			nfsrv_freenfslockfile(lfp);
    -			/*
    -			 * Set the pointer(s) to this lockowner NULL,
    -			 * to indicate it has been free'd and local
    -			 * locks discarded already.
    -			 */
    -			if (olfp == lfp)
    -				olfp = NULL;
    -			lfp = NULL;
    -			ret = 1;
    +		if (lfp == NULL)
    +			lfp = lop->lo_lfp;
    +		else if (lfp != lop->lo_lfp)
    +			panic("allnfslocks");
    +		/*
    +		 * If vp is NULL and cansleep != 0, a vnode must be acquired
    +		 * from the file handle. This only occurs when called from
    +		 * nfsrv_cleanclient().
    +		 */
    +		if (gottvp == 0) {
    +			if (nfsrv_dolocallocks == 0)
    +				tvp = NULL;
    +			else if (vp == NULL && cansleep != 0)
    +				tvp = nfsvno_getvp(&lfp->lf_fh);
    +			else
    +				tvp = vp;
    +			gottvp = 1;
     		}
    -		if (cansleep && olfp != lfp && olfp != NULL)
    -			nfsrv_locallocks(NULL, olfp, p);
    +
    +		if (tvp != NULL) {
    +			if (cansleep == 0)
    +				panic("allnfs2");
    +			nfsrv_localunlock(tvp, lfp, lop->lo_first,
    +			    lop->lo_end, p);
    +			LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list,
    +			    nrlp)
    +				free(rlp, M_NFSDROLLBACK);
    +			LIST_INIT(&lfp->lf_rollback);
    +		}
    +		nfsrv_freenfslock(lop);
     		lop = nlop;
     	}
    -	if (cansleep && lfp != NULL)
    -		nfsrv_locallocks(NULL, olfp, p);
    -	return (ret);
    +	if (vp == NULL && tvp != NULL)
    +		vput(tvp);
     }
     
     /*
    @@ -1161,11 +1168,13 @@ static void
     nfsrv_freenfslock(struct nfslock *lop)
     {
     
    -	LIST_REMOVE(lop, lo_lckfile);
    +	if (lop->lo_lckfile.le_prev != NULL) {
    +		LIST_REMOVE(lop, lo_lckfile);
    +		newnfsstats.srvlocks--;
    +		nfsrv_openpluslock--;
    +	}
     	LIST_REMOVE(lop, lo_lckowner);
     	FREE((caddr_t)lop, M_NFSDLOCK);
    -	newnfsstats.srvlocks--;
    -	nfsrv_openpluslock--;
     }
     
     /*
    @@ -1240,7 +1249,8 @@ nfsrv_getowner(struct nfsstatehead *hp, struct nfsstate *new_stp,
     APPLESTATIC int
     nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
         struct nfslock **new_lopp, struct nfslockconflict *cfp,
    -    nfsquad_t clientid, nfsv4stateid_t *stateidp, __unused struct nfsexstuff *exp,
    +    nfsquad_t clientid, nfsv4stateid_t *stateidp,
    +    __unused struct nfsexstuff *exp,
         struct nfsrv_descript *nd, NFSPROC_T *p)
     {
     	struct nfslock *lop;
    @@ -1253,9 +1263,11 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
     	struct nfsstate *stp, *lckstp = NULL;
     	struct nfsclient *clp = NULL;
     	u_int32_t bits;
    -	int error = 0, haslock = 0, ret;
    -	int getlckret, delegation = 0;
    +	int error = 0, haslock = 0, ret, reterr;
    +	int getlckret, delegation = 0, filestruct_locked;
     	fhandle_t nfh;
    +	uint64_t first, end;
    +	uint32_t lock_flags;
     
     	if (new_stp->ls_flags & (NFSLCK_CHECK | NFSLCK_SETATTR)) {
     		/*
    @@ -1289,23 +1301,6 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
     	    nfsrv_openpluslock > NFSRV_V4STATELIMIT)
     		return (NFSERR_RESOURCE);
     
    -	/*
    -	 * For Lock, check for a conflict with a lock held by
    -	 * a process running locally on the server now, before
    -	 * monkeying with nfsd state. Since the vp is locked, any
    -	 * other local calls are blocked during this Op.
    -	 */
    -	if (new_stp->ls_flags & NFSLCK_LOCK) {
    -		if (new_lop->lo_flags & NFSLCK_WRITE)
    -			error = nfsvno_localconflict(vp, F_WRLCK,
    -			    new_lop->lo_first, new_lop->lo_end, cfp, p);
    -		else
    -			error = nfsvno_localconflict(vp, F_RDLCK,
    -			    new_lop->lo_first, new_lop->lo_end, cfp, p);
    -		if (error)
    -			return (error);
    -	}
    -
     	/*
     	 * For the lock case, get another nfslock structure,
     	 * just in case we need it.
    @@ -1316,6 +1311,9 @@ tryagain:
     	if (new_stp->ls_flags & NFSLCK_LOCK)
     		MALLOC(other_lop, struct nfslock *, sizeof (struct nfslock),
     		    M_NFSDLOCK, M_WAITOK);
    +	filestruct_locked = 0;
    +	reterr = 0;
    +	lfp = NULL;
     
     	/*
     	 * Get the lockfile structure for CFH now, so we can do a sanity
    @@ -1324,22 +1322,41 @@ tryagain:
     	 * shouldn't be incremented for this case.
     	 * If nfsrv_getlockfile() returns -1, it means "not found", which
     	 * will be handled later.
    +	 * If we are doing Lock/LockU and local locking is enabled, sleep
    +	 * lock the nfslockfile structure.
     	 */
     	getlckret = nfsrv_getlockfh(vp, new_stp->ls_flags, NULL, &nfh, p);
     	NFSLOCKSTATE();
    -	if (!getlckret)
    -		getlckret = nfsrv_getlockfile(new_stp->ls_flags, NULL,
    -		    &lfp, &nfh);
    -	if (getlckret != 0 && getlckret != -1) {
    -		NFSUNLOCKSTATE();
    -		if (other_lop)
    -			FREE((caddr_t)other_lop, M_NFSDLOCK);
    -		if (haslock) {
    -			NFSLOCKV4ROOTMUTEX();
    -			nfsv4_unlock(&nfsv4rootfs_lock, 1);
    -			NFSUNLOCKV4ROOTMUTEX();
    +	if (getlckret == 0) {
    +		if ((new_stp->ls_flags & (NFSLCK_LOCK | NFSLCK_UNLOCK)) != 0 &&
    +		    nfsrv_dolocallocks != 0 && nd->nd_repstat == 0) {
    +			getlckret = nfsrv_getlockfile(new_stp->ls_flags, NULL,
    +			    &lfp, &nfh, 1);
    +			if (getlckret == 0)
    +				filestruct_locked = 1;
    +		} else
    +			getlckret = nfsrv_getlockfile(new_stp->ls_flags, NULL,
    +			    &lfp, &nfh, 0);
    +	}
    +	if (getlckret != 0 && getlckret != -1)
    +		reterr = getlckret;
    +
    +	if (filestruct_locked != 0) {
    +		LIST_INIT(&lfp->lf_rollback);
    +		if ((new_stp->ls_flags & NFSLCK_LOCK)) {
    +			/*
    +			 * For local locking, do the advisory locking now, so
    +			 * that any conflict can be detected. A failure later
    +			 * can be rolled back locally. If an error is returned,
    +			 * struct nfslockfile has been unlocked and any local
    +			 * locking rolled back.
    +			 */
    +			NFSUNLOCKSTATE();
    +			reterr = nfsrv_locallock(vp, lfp,
    +			    (new_lop->lo_flags & (NFSLCK_READ | NFSLCK_WRITE)),
    +			    new_lop->lo_first, new_lop->lo_end, cfp, p);
    +			NFSLOCKSTATE();
     		}
    -		return (getlckret);
     	}
     
     	/*
    @@ -1381,11 +1398,11 @@ tryagain:
     	       */
     	      if (error == 0 && (stp->ls_flags & NFSLCK_OPEN) &&
     		  ((stp->ls_openowner->ls_flags & NFSLCK_NEEDSCONFIRM) ||
    -		   (getlckret != -1 && stp->ls_lfp != lfp)))
    +		   (getlckret == 0 && stp->ls_lfp != lfp)))
     			error = NFSERR_BADSTATEID;
     	      if (error == 0 &&
     		  (stp->ls_flags & (NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) &&
    -		  getlckret != -1 && stp->ls_lfp != lfp)
    +		  getlckret == 0 && stp->ls_lfp != lfp)
     			error = NFSERR_BADSTATEID;
     
     	      /*
    @@ -1398,7 +1415,7 @@ tryagain:
     	       */
     	      if (error == 0 && (stp->ls_flags &
     		  (NFSLCK_OPEN | NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) == 0 &&
    -		  getlckret != -1 && stp->ls_lfp != lfp) {
    +		  getlckret == 0 && stp->ls_lfp != lfp) {
     #ifdef DIAGNOSTIC
     		  printf("Got a lock statid for different file open\n");
     #endif
    @@ -1478,12 +1495,30 @@ tryagain:
     		nfsrv_markstable(clp);
     
     	/*
    -	 * If nd_repstat is set, we can return that now, since the
    -	 * seqid# has been incremented.
    +	 * At this point, either error == NFSERR_BADSTATEID or the
    +	 * seqid# has been updated, so we can return any error.
    +	 * If error == 0, there may be an error in:
    +	 *    nd_repstat - Set by the calling function.
    +	 *    reterr - Set above, if getting the nfslockfile structure
    +	 *       or acquiring the local lock failed.
    +	 *    (If both of these are set, nd_repstat should probably be
    +	 *     returned, since that error was detected before this
    +	 *     function call.)
     	 */
    -	if (nd->nd_repstat && !error)
    -		error = nd->nd_repstat;
    -	if (error) {
    +	if (error != 0 || nd->nd_repstat != 0 || reterr != 0) {
    +		if (error == 0) {
    +			if (nd->nd_repstat != 0)
    +				error = nd->nd_repstat;
    +			else
    +				error = reterr;
    +		}
    +		if (filestruct_locked != 0) {
    +			/* Roll back local locks. */
    +			NFSUNLOCKSTATE();
    +			nfsrv_locallock_rollback(vp, lfp, p);
    +			NFSLOCKSTATE();
    +			nfsrv_unlocklf(lfp);
    +		}
     		NFSUNLOCKSTATE();
     		if (other_lop)
     			FREE((caddr_t)other_lop, M_NFSDLOCK);
    @@ -1569,6 +1604,13 @@ tryagain:
     		    ((new_stp->ls_flags & (NFSLCK_CHECK|NFSLCK_WRITEACCESS)) ==
     		      (NFSLCK_CHECK | NFSLCK_WRITEACCESS) &&
     		     !(mystp->ls_flags & NFSLCK_WRITEACCESS))) {
    +			if (filestruct_locked != 0) {
    +				/* Roll back local locks. */
    +				NFSUNLOCKSTATE();
    +				nfsrv_locallock_rollback(vp, lfp, p);
    +				NFSLOCKSTATE();
    +				nfsrv_unlocklf(lfp);
    +			}
     			NFSUNLOCKSTATE();
     			if (other_lop)
     				FREE((caddr_t)other_lop, M_NFSDLOCK);
    @@ -1680,11 +1722,18 @@ tryagain:
     		   (new_lop->lo_flags & NFSLCK_WRITE) &&
     		  (clp != tstp->ls_clp ||
     		   (tstp->ls_flags & NFSLCK_DELEGREAD)))) {
    +		if (filestruct_locked != 0) {
    +			/* Roll back local locks. */
    +			NFSUNLOCKSTATE();
    +			nfsrv_locallock_rollback(vp, lfp, p);
    +			NFSLOCKSTATE();
    +			nfsrv_unlocklf(lfp);
    +		}
     		ret = nfsrv_delegconflict(tstp, &haslock, p, vp);
     		if (ret) {
     		    /*
     		     * nfsrv_delegconflict unlocks state when it
    -		     * returns non-zero.
    +		     * returns non-zero, which it always does.
     		     */
     		    if (other_lop) {
     			FREE((caddr_t)other_lop, M_NFSDLOCK);
    @@ -1696,6 +1745,7 @@ tryagain:
     		    }
     		    return (ret);
     		}
    +		/* Never gets here. */
     	    }
     	    tstp = nstp;
     	}
    @@ -1706,32 +1756,21 @@ tryagain:
     	 *  just let it happen.)
     	 */
     	if (new_stp->ls_flags & NFSLCK_UNLOCK) {
    +		first = new_lop->lo_first;
    +		end = new_lop->lo_end;
     		nfsrv_updatelock(stp, new_lopp, &other_lop, lfp);
     		stateidp->seqid = ++(stp->ls_stateid.seqid);
     		stateidp->other[0] = stp->ls_stateid.other[0];
     		stateidp->other[1] = stp->ls_stateid.other[1];
     		stateidp->other[2] = stp->ls_stateid.other[2];
    -		/*
    -		 * For a non-empty flp->lf_lock list, I believe
    -		 * nfsrv_locallocks() can safely traverse the list, including
    -		 * sleeping, for two reasons:
    -		 * 1 - The Lock/LockU/Close Ops all require a locked
    -		 *     vnode for the file and we currently have that.
    -		 * 2 - The only other thing that modifies a non-empty
    -		 *     list is nfsrv_cleanclient() and it is always
    -		 *     done with the exclusive nfsv4rootfs_lock held.
    -		 *     Since this Op in progress holds either a shared or
    -		 *     exclusive lock on nfsv4rootfs_lock, that can't
    -		 *     happen now.
    -		 * However, the structure pointed to by lfp can go
    -		 * in many places for an empty list, so that is handled
    -		 * by passing a NULL pointer to nfsrv_locallocks().
    -		 * Do that check now, while we are still SMP safe.
    -		 */
    -		if (LIST_EMPTY(&lfp->lf_lock))
    -			lfp = NULL;
    +		if (filestruct_locked != 0) {
    +			NFSUNLOCKSTATE();
    +			/* Update the local locks. */
    +			nfsrv_localunlock(vp, lfp, first, end, p);
    +			NFSLOCKSTATE();
    +			nfsrv_unlocklf(lfp);
    +		}
     		NFSUNLOCKSTATE();
    -		nfsrv_locallocks(vp, lfp, p);
     		if (haslock) {
     			NFSLOCKV4ROOTMUTEX();
     			nfsv4_unlock(&nfsv4rootfs_lock, 1);
    @@ -1763,6 +1802,13 @@ tryagain:
     		}
     		ret = nfsrv_clientconflict(lop->lo_stp->ls_clp,&haslock,vp,p);
     		if (ret) {
    +		    if (filestruct_locked != 0) {
    +			/* Roll back local locks. */
    +			nfsrv_locallock_rollback(vp, lfp, p);
    +			NFSLOCKSTATE();
    +			nfsrv_unlocklf(lfp);
    +			NFSUNLOCKSTATE();
    +		    }
     		    /*
     		     * nfsrv_clientconflict() unlocks state when it
     		     * returns non-zero.
    @@ -1790,6 +1836,13 @@ tryagain:
     		    error = NFSERR_LOCKED;
     		else
     		    error = NFSERR_DENIED;
    +		if (filestruct_locked != 0) {
    +			/* Roll back local locks. */
    +			NFSUNLOCKSTATE();
    +			nfsrv_locallock_rollback(vp, lfp, p);
    +			NFSLOCKSTATE();
    +			nfsrv_unlocklf(lfp);
    +		}
     		NFSUNLOCKSTATE();
     		if (haslock) {
     			NFSLOCKV4ROOTMUTEX();
    @@ -1820,6 +1873,9 @@ tryagain:
     	 * - exist_lock_owner where lock_owner exists
     	 * - open_to_lock_owner with new lock_owner
     	 */
    +	first = new_lop->lo_first;
    +	end = new_lop->lo_end;
    +	lock_flags = new_lop->lo_flags;
     	if (!(new_stp->ls_flags & NFSLCK_OPENTOLOCK)) {
     		nfsrv_updatelock(lckstp, new_lopp, &other_lop, lfp);
     		stateidp->seqid = ++(lckstp->ls_stateid.seqid);
    @@ -1854,11 +1910,13 @@ tryagain:
     		newnfsstats.srvlockowners++;
     		nfsrv_openpluslock++;
     	}
    -	/* See comment above, w.r.t. nfsrv_locallocks(). */
    -	if (LIST_EMPTY(&lfp->lf_lock))
    -		lfp = NULL;
    +	if (filestruct_locked != 0) {
    +		NFSUNLOCKSTATE();
    +		nfsrv_locallock_commit(lfp, lock_flags, first, end);
    +		NFSLOCKSTATE();
    +		nfsrv_unlocklf(lfp);
    +	}
     	NFSUNLOCKSTATE();
    -	nfsrv_locallocks(vp, lfp, p);
     	if (haslock) {
     		NFSLOCKV4ROOTMUTEX();
     		nfsv4_unlock(&nfsv4rootfs_lock, 1);
    @@ -1984,7 +2042,7 @@ tryagain:
     		error = getfhret;
     	else
     		error = nfsrv_getlockfile(new_stp->ls_flags, &new_lfp, &lfp,
    -		    NULL);
    +		    NULL, 0);
     	if (new_lfp)
     		FREE((caddr_t)new_lfp, M_NFSDLOCKFILE);
     	if (error) {
    @@ -2227,7 +2285,7 @@ tryagain:
     		error = getfhret;
     	else
     		error = nfsrv_getlockfile(new_stp->ls_flags, &new_lfp, &lfp,
    -		    NULL);
    +		    NULL, 0);
     	if (new_lfp)
     		FREE((caddr_t)new_lfp, M_NFSDLOCKFILE);
     	if (error) {
    @@ -2775,7 +2833,7 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
     	struct nfsclient *clp;
     	struct nfslockfile *lfp;
     	u_int32_t bits;
    -	int error, gotstate = 0, len = 0, ret, freedlock;
    +	int error, gotstate = 0, len = 0;
     	u_char client[NFSV4_OPAQUELIMIT];
     
     	/*
    @@ -2863,26 +2921,19 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
     	} else if (new_stp->ls_flags & NFSLCK_CLOSE) {
     		ownerstp = stp->ls_openowner;
     		lfp = stp->ls_lfp;
    -		freedlock = 0;
    -		ret = nfsrv_freeopen(stp, &freedlock, 0, p);
    -		/* See comment on nfsrv_lockctrl() w.r.t. locallocks. */
    -		if (ret) {
    -			lfp = NULL;
    +		if (nfsrv_dolocallocks != 0 && !LIST_EMPTY(&stp->ls_open)) {
    +			/* Get the lf lock */
    +			nfsrv_locklf(lfp);
    +			NFSUNLOCKSTATE();
    +			if (nfsrv_freeopen(stp, vp, 1, p) == 0) {
    +				NFSLOCKSTATE();
    +				nfsrv_unlocklf(lfp);
    +				NFSUNLOCKSTATE();
    +			}
     		} else {
    -			if (LIST_EMPTY(&lfp->lf_lock))
    -				lfp = NULL;
    +			(void) nfsrv_freeopen(stp, NULL, 0, p);
    +			NFSUNLOCKSTATE();
     		}
    -		/*
    -		 * For now, I won't do this. The openowner should be
    -		 * free'd in NFSNOOPEN seconds and it will be deref'd then.
    -		if (LIST_EMPTY(&ownerstp->ls_open) && ownerstp->ls_op) {
    -			nfsrvd_derefcache(ownerstp->ls_op);
    -			ownerstp->ls_op = NULL;
    -		}
    -		 */
    -		NFSUNLOCKSTATE();
    -		if (freedlock && lfp != NULL)
    -			nfsrv_locallocks(vp, lfp, p);
     	} else {
     		/*
     		 * Update the share bits, making sure that the new set are a
    @@ -3024,7 +3075,7 @@ nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid,
     			!NFSBCMP(stp->ls_owner, new_stp->ls_owner,
     			 stp->ls_ownerlen)){
     			if (LIST_EMPTY(&stp->ls_lock)) {
    -			    (void) nfsrv_freelockowner(stp, NULL, 0, p);
    +			    nfsrv_freelockowner(stp, NULL, 0, p);
     			} else {
     			    NFSUNLOCKSTATE();
     			    return (NFSERR_LOCKSHELD);
    @@ -3072,7 +3123,7 @@ nfsrv_getlockfh(vnode_t vp, u_short flags,
      */
     static int
     nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp,
    -    struct nfslockfile **lfpp, fhandle_t *nfhp)
    +    struct nfslockfile **lfpp, fhandle_t *nfhp, int lockit)
     {
     	struct nfslockfile *lfp;
     	fhandle_t *fhp = NULL, *tfhp;
    @@ -3096,6 +3147,8 @@ nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp,
     	LIST_FOREACH(lfp, hp, lf_hash) {
     		tfhp = &lfp->lf_fh;
     		if (NFSVNO_CMPFH(fhp, tfhp)) {
    +			if (lockit)
    +				nfsrv_locklf(lfp);
     			*lfpp = lfp;
     			return (0);
     		}
    @@ -3109,6 +3162,11 @@ nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp,
     	LIST_INIT(&new_lfp->lf_open);
     	LIST_INIT(&new_lfp->lf_lock);
     	LIST_INIT(&new_lfp->lf_deleg);
    +	LIST_INIT(&new_lfp->lf_locallock);
    +	LIST_INIT(&new_lfp->lf_rollback);
    +	new_lfp->lf_locallock_lck.nfslock_usecnt = 0;
    +	new_lfp->lf_locallock_lck.nfslock_lock = 0;
    +	new_lfp->lf_usecount = 0;
     	LIST_INSERT_HEAD(hp, new_lfp, lf_hash);
     	*lfpp = new_lfp;
     	*new_lfpp = NULL;
    @@ -3130,31 +3188,39 @@ nfsrv_insertlock(struct nfslock *new_lop, struct nfslock *insert_lop,
     	new_lop->lo_stp = stp;
     	new_lop->lo_lfp = lfp;
     
    -	/* Insert in increasing lo_first order */
    -	lop = LIST_FIRST(&lfp->lf_lock);
    -	if (lop == LIST_END(&lfp->lf_lock) ||
    -	    new_lop->lo_first <= lop->lo_first) {
    -		LIST_INSERT_HEAD(&lfp->lf_lock, new_lop, lo_lckfile);
    -	} else {
    -		nlop = LIST_NEXT(lop, lo_lckfile);
    -		while (nlop != LIST_END(&lfp->lf_lock) &&
    -		       nlop->lo_first < new_lop->lo_first) {
    -			lop = nlop;
    +	if (stp != NULL) {
    +		/* Insert in increasing lo_first order */
    +		lop = LIST_FIRST(&lfp->lf_lock);
    +		if (lop == LIST_END(&lfp->lf_lock) ||
    +		    new_lop->lo_first <= lop->lo_first) {
    +			LIST_INSERT_HEAD(&lfp->lf_lock, new_lop, lo_lckfile);
    +		} else {
     			nlop = LIST_NEXT(lop, lo_lckfile);
    +			while (nlop != LIST_END(&lfp->lf_lock) &&
    +			       nlop->lo_first < new_lop->lo_first) {
    +				lop = nlop;
    +				nlop = LIST_NEXT(lop, lo_lckfile);
    +			}
    +			LIST_INSERT_AFTER(lop, new_lop, lo_lckfile);
     		}
    -		LIST_INSERT_AFTER(lop, new_lop, lo_lckfile);
    +	} else {
    +		new_lop->lo_lckfile.le_prev = NULL;	/* list not used */
     	}
     
     	/*
    -	 * Insert after insert_lop, which is overloaded as stp for
    +	 * Insert after insert_lop, which is overloaded as stp or lfp for
     	 * an empty list.
     	 */
    -	if ((struct nfsstate *)insert_lop == stp)
    +	if (stp == NULL && (struct nfslockfile *)insert_lop == lfp)
    +		LIST_INSERT_HEAD(&lfp->lf_locallock, new_lop, lo_lckowner);
    +	else if ((struct nfsstate *)insert_lop == stp)
     		LIST_INSERT_HEAD(&stp->ls_lock, new_lop, lo_lckowner);
     	else
     		LIST_INSERT_AFTER(insert_lop, new_lop, lo_lckowner);
    -	newnfsstats.srvlocks++;
    -	nfsrv_openpluslock++;
    +	if (stp != NULL) {
    +		newnfsstats.srvlocks++;
    +		nfsrv_openpluslock++;
    +	}
     }
     
     /*
    @@ -3180,9 +3246,14 @@ nfsrv_updatelock(struct nfsstate *stp, struct nfslock **new_lopp,
     	 */
     	if (new_lop->lo_flags & NFSLCK_UNLOCK)
     		unlock = 1;
    -	ilop = (struct nfslock *)stp;
    -	lop = LIST_FIRST(&stp->ls_lock);
    -	while (lop != LIST_END(&stp->ls_lock)) {
    +	if (stp != NULL) {
    +		ilop = (struct nfslock *)stp;
    +		lop = LIST_FIRST(&stp->ls_lock);
    +	} else {
    +		ilop = (struct nfslock *)lfp;
    +		lop = LIST_FIRST(&lfp->lf_locallock);
    +	}
    +	while (lop != NULL) {
     	    /*
     	     * Only check locks for this file that aren't before the start of
     	     * new lock's range.
    @@ -3278,8 +3349,7 @@ nfsrv_updatelock(struct nfsstate *stp, struct nfslock **new_lopp,
     	    }
     	    ilop = lop;
     	    lop = LIST_NEXT(lop, lo_lckowner);
    -	    if (myfile && (lop == LIST_END(&stp->ls_lock) ||
    -		lop->lo_lfp != lfp))
    +	    if (myfile && (lop == NULL || lop->lo_lfp != lfp))
     		break;
     	}
     
    @@ -4362,7 +4432,7 @@ nfsrv_checkremove(vnode_t vp, int remove, NFSPROC_T *p)
     tryagain:
     	NFSLOCKSTATE();
     	if (!error)
    -		error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh);
    +		error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh, 0);
     	if (error) {
     		NFSUNLOCKSTATE();
     		if (haslock) {
    @@ -4612,7 +4682,7 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
     	error = nfsrv_getlockfh(vp, NFSLCK_CHECK, NULL, &nfh, p);
     	NFSLOCKSTATE();
     	if (!error)
    -		error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh);
    +		error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh, 0);
     	if (error) {
     		NFSUNLOCKSTATE();
     		if (error == -1)
    @@ -4782,99 +4852,6 @@ nfsrv_delaydelegtimeout(struct nfsstate *stp)
     	}
     }
     
    -/*
    - * Go through a lock list and set local locks for all ranges.
    - * This assumes that the lock list is sorted on increasing
    - * lo_first and that the list won't change, despite the possibility
    - * of sleeps.
    - */
    -static void
    -nfsrv_locallocks(vnode_t vp, struct nfslockfile *lfp,
    -    NFSPROC_T *p)
    -{
    -	struct nfslock *lop, *nlop;
    -	vnode_t tvp;
    -	int newcollate, flags = 0;
    -	u_int64_t first = 0x0ull, end = 0x0ull;
    -
    -	if (!nfsrv_dolocallocks)
    -		return;
    -	/*
    -	 * If vp is NULL, a vnode must be aquired from the file
    -	 * handle.
    -	 */
    -	if (vp == NULL) {
    -		if (lfp == NULL)
    -			panic("nfsrv_locallocks");
    -		tvp = nfsvno_getvp(&lfp->lf_fh);
    -		if (tvp == NULL)
    -			return;
    -	} else {
    -		tvp = vp;
    -	}
    -
    -	/*
    -	 * If lfp == NULL, the lock list is empty, so just unlock
    -	 * everything.
    -	 */
    -	if (lfp == NULL) {
    -		(void) nfsvno_advlock(tvp, F_UNLCK, (u_int64_t)0,
    -		    NFS64BITSSET, p);
    -		/* vp can't be NULL */
    -		return;
    -	}
    -
    -	/* handle whole file case first */
    -	lop = LIST_FIRST(&lfp->lf_lock);
    -	if (lop != LIST_END(&lfp->lf_lock) &&
    -	    lop->lo_first == (u_int64_t)0 &&
    -	    lop->lo_end == NFS64BITSSET) {
    -		if (lop->lo_flags & NFSLCK_WRITE)
    -			(void) nfsvno_advlock(tvp, F_WRLCK, lop->lo_first,
    -			    lop->lo_end, p);
    -		else
    -			(void) nfsvno_advlock(tvp, F_RDLCK, lop->lo_first,
    -			    lop->lo_end, p);
    -		if (vp == NULL)
    -			vput(tvp);
    -		return;
    -	}
    -
    -	/*
    -	 * Now, handle the separate byte ranges cases.
    -	 */
    -	(void) nfsvno_advlock(tvp, F_UNLCK, (u_int64_t)0,
    -	    NFS64BITSSET, p);
    -	newcollate = 1;
    -	while (lop != LIST_END(&lfp->lf_lock)) {
    -		nlop = LIST_NEXT(lop, lo_lckfile);
    -		if (newcollate) {
    -			first = lop->lo_first;
    -			end = lop->lo_end;
    -			flags = lop->lo_flags;
    -			newcollate = 0;
    -		}
    -		if (nlop != LIST_END(&lfp->lf_lock) &&
    -		    flags == nlop->lo_flags &&
    -		    end >= nlop->lo_first) {
    -			/* can collate this one */
    -			end = nlop->lo_end;
    -		} else {
    -			/* do the local lock and start again */
    -			if (flags & NFSLCK_WRITE)
    -				(void) nfsvno_advlock(tvp, F_WRLCK, first,
    -				    end, p);
    -			else
    -				(void) nfsvno_advlock(tvp, F_RDLCK, first,
    -				    end, p);
    -			newcollate = 1;
    -		}
    -		lop = nlop;
    -	}
    -	if (vp == NULL)
    -		vput(tvp);
    -}
    -
     /*
      * This function checks to see if there is any other state associated
      * with the openowner for this Open.
    @@ -4892,3 +4869,236 @@ nfsrv_nootherstate(struct nfsstate *stp)
     	return (1);
     }
     
    +/*
    + * Create a list of lock deltas (changes to local byte range locking
    + * that can be rolled back using the list) and apply the changes via
    + * nfsvno_advlock(). Optionally, lock the list. It is expected that either
    + * the rollback or update function will be called after this.
    + * It returns an error (and rolls back, as required), if any nfsvno_advlock()
    + * call fails. If it returns an error, it will unlock the list.
    + */
    +static int
    +nfsrv_locallock(vnode_t vp, struct nfslockfile *lfp, int flags,
    +    uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p)
    +{
    +	struct nfslock *lop, *nlop;
    +	int error = 0;
    +
    +	/* Loop through the list of locks. */
    +	lop = LIST_FIRST(&lfp->lf_locallock);
    +	while (first < end && lop != NULL) {
    +		nlop = LIST_NEXT(lop, lo_lckowner);
    +		if (first >= lop->lo_end) {
    +			/* not there yet */
    +			lop = nlop;
    +		} else if (first < lop->lo_first) {
    +			/* new one starts before entry in list */
    +			if (end <= lop->lo_first) {
    +				/* no overlap between old and new */
    +				error = nfsrv_dolocal(vp, lfp, flags,
    +				    NFSLCK_UNLOCK, first, end, cfp, p);
    +				if (error != 0)
    +					break;
    +				first = end;
    +			} else {
    +				/* handle fragment overlapped with new one */
    +				error = nfsrv_dolocal(vp, lfp, flags,
    +				    NFSLCK_UNLOCK, first, lop->lo_first, cfp,
    +				    p);
    +				if (error != 0)
    +					break;
    +				first = lop->lo_first;
    +			}
    +		} else {
    +			/* new one overlaps this entry in list */
    +			if (end <= lop->lo_end) {
    +				/* overlaps all of new one */
    +				error = nfsrv_dolocal(vp, lfp, flags,
    +				    lop->lo_flags, first, end, cfp, p);
    +				if (error != 0)
    +					break;
    +				first = end;
    +			} else {
    +				/* handle fragment overlapped with new one */
    +				error = nfsrv_dolocal(vp, lfp, flags,
    +				    lop->lo_flags, first, lop->lo_end, cfp, p);
    +				if (error != 0)
    +					break;
    +				first = lop->lo_end;
    +				lop = nlop;
    +			}
    +		}
    +	}
    +	if (first < end && error == 0)
    +		/* handle fragment past end of list */
    +		error = nfsrv_dolocal(vp, lfp, flags, NFSLCK_UNLOCK, first,
    +		    end, cfp, p);
    +	return (error);
    +}
    +
    +/*
    + * Local lock unlock. Unlock all byte ranges that are no longer locked
    + * by NFSv4.
    + */
    +static void
    +nfsrv_localunlock(vnode_t vp, struct nfslockfile *lfp, uint64_t init_first,
    +    uint64_t init_end, NFSPROC_T *p)
    +{
    +	struct nfslock *lop;
    +
    +	uint64_t first, end;
    +
    +	first = init_first;
    +	end = init_end;
    +	while (first < init_end) {
    +		/* Loop through all nfs locks, adjusting first and end */
    +		LIST_FOREACH(lop, &lfp->lf_lock, lo_lckfile) {
    +			if (first >= lop->lo_first &&
    +			    first < lop->lo_end)
    +				/* Overlaps initial part */
    +				first = lop->lo_end;
    +			else if (end > lop->lo_first &&
    +			    lop->lo_first >= first)
    +				/* Begins before end and past first */
    +				end = lop->lo_first;
    +			if (first >= end)
    +				/* shrunk to 0 so this iteration is done */
    +				break;
    +		}
    +		if (first < end) {
    +			/* Unlock this segment */
    +			(void) nfsrv_dolocal(vp, lfp, NFSLCK_UNLOCK,
    +			    NFSLCK_READ, first, end, NULL, p);
    +			nfsrv_locallock_commit(lfp, NFSLCK_UNLOCK,
    +			    first, end);
    +		}
    +		/* and move on to the rest of the range */
    +		first = end;
    +		end = init_end;
    +	}
    +}
    +
    +/*
    + * Do the local lock operation and update the rollback list, as required.
    + * Perform the rollback and return the error if nfsvno_advlock() fails.
    + */
    +static int
    +nfsrv_dolocal(vnode_t vp, struct nfslockfile *lfp, int flags, int oldflags,
    +    uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p)
    +{
    +	struct nfsrollback *rlp;
    +	int error, ltype, oldltype;
    +
    +	if (flags & NFSLCK_WRITE)
    +		ltype = F_WRLCK;
    +	else if (flags & NFSLCK_READ)
    +		ltype = F_RDLCK;
    +	else
    +		ltype = F_UNLCK;
    +	if (oldflags & NFSLCK_WRITE)
    +		oldltype = F_WRLCK;
    +	else if (oldflags & NFSLCK_READ)
    +		oldltype = F_RDLCK;
    +	else
    +		oldltype = F_UNLCK;
    +	if (ltype == oldltype || (oldltype == F_WRLCK && ltype == F_RDLCK))
    +		/* nothing to do */
    +		return (0);
    +	error = nfsvno_advlock(vp, ltype, first, end, p);
    +	if (error != 0) {
    +		if (cfp != NULL) {
    +			cfp->cl_clientid.lval[0] = 0;
    +			cfp->cl_clientid.lval[1] = 0;
    +			cfp->cl_first = 0;
    +			cfp->cl_end = NFS64BITSSET;
    +			cfp->cl_flags = NFSLCK_WRITE;
    +			cfp->cl_ownerlen = 5;
    +			NFSBCOPY("LOCAL", cfp->cl_owner, 5);
    +		}
    +		nfsrv_locallock_rollback(vp, lfp, p);
    +	} else if (ltype != F_UNLCK) {
    +		rlp = malloc(sizeof (struct nfsrollback), M_NFSDROLLBACK,
    +		    M_WAITOK);
    +		rlp->rlck_first = first;
    +		rlp->rlck_end = end;
    +		rlp->rlck_type = oldltype;
    +		LIST_INSERT_HEAD(&lfp->lf_rollback, rlp, rlck_list);
    +	}
    +	return (error);
    +}
    +
    +/*
    + * Roll back local lock changes and free up the rollback list.
    + */
    +static void
    +nfsrv_locallock_rollback(vnode_t vp, struct nfslockfile *lfp, NFSPROC_T *p)
    +{
    +	struct nfsrollback *rlp, *nrlp;
    +
    +	LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list, nrlp) {
    +		(void) nfsvno_advlock(vp, rlp->rlck_type, rlp->rlck_first,
    +		    rlp->rlck_end, p);
    +		free(rlp, M_NFSDROLLBACK);
    +	}
    +	LIST_INIT(&lfp->lf_rollback);
    +}
    +
    +/*
    + * Update local lock list and delete rollback list (ie now committed to the
    + * local locks). Most of the work is done by the internal function.
    + */
    +static void
    +nfsrv_locallock_commit(struct nfslockfile *lfp, int flags, uint64_t first,
    +    uint64_t end)
    +{
    +	struct nfsrollback *rlp, *nrlp;
    +	struct nfslock *new_lop, *other_lop;
    +
    +	new_lop = malloc(sizeof (struct nfslock), M_NFSDLOCK, M_WAITOK);
    +	if (flags & (NFSLCK_READ | NFSLCK_WRITE))
    +		other_lop = malloc(sizeof (struct nfslock), M_NFSDLOCK,
    +		    M_WAITOK);
    +	else
    +		other_lop = NULL;
    +	new_lop->lo_flags = flags;
    +	new_lop->lo_first = first;
    +	new_lop->lo_end = end;
    +	nfsrv_updatelock(NULL, &new_lop, &other_lop, lfp);
    +	if (new_lop != NULL)
    +		free(new_lop, M_NFSDLOCK);
    +	if (other_lop != NULL)
    +		free(other_lop, M_NFSDLOCK);
    +
    +	/* and get rid of the rollback list */
    +	LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list, nrlp)
    +		free(rlp, M_NFSDROLLBACK);
    +	LIST_INIT(&lfp->lf_rollback);
    +}
    +
    +/*
    + * Lock the struct nfslockfile for local lock updating.
    + */
    +static void
    +nfsrv_locklf(struct nfslockfile *lfp)
    +{
    +	int gotlock;
    +
    +	/* lf_usecount ensures *lfp won't be free'd */
    +	lfp->lf_usecount++;
    +	do {
    +		gotlock = nfsv4_lock(&lfp->lf_locallock_lck, 1, NULL,
    +		    NFSSTATEMUTEXPTR);
    +	} while (gotlock == 0);
    +	lfp->lf_usecount--;
    +}
    +
    +/*
    + * Unlock the struct nfslockfile after local lock updating.
    + */
    +static void
    +nfsrv_unlocklf(struct nfslockfile *lfp)
    +{
    +
    +	nfsv4_unlock(&lfp->lf_locallock_lck, 0);
    +}
    +
    
    From 5f99d9e2ba9b4c038c259abffdd293663d262536 Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Wed, 14 Apr 2010 15:00:46 +0000
    Subject: [PATCH 1946/2592] MFC 205851: Add a handler for the local APIC error
     interrupt.  For now it just prints out the current value of the local APIC
     error register when the interrupt fires.
    
    ---
     sys/amd64/amd64/apic_vector.S | 12 +++++++++
     sys/amd64/amd64/local_apic.c  | 47 +++++++++++++++++++++-------------
     sys/amd64/include/apicvar.h   |  5 ++--
     sys/i386/i386/apic_vector.s   | 13 ++++++++++
     sys/i386/i386/local_apic.c    | 48 ++++++++++++++++++++++-------------
     sys/i386/include/apicvar.h    |  5 ++--
     6 files changed, 90 insertions(+), 40 deletions(-)
    
    diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
    index cebafc8370e..df94a4700c6 100644
    --- a/sys/amd64/amd64/apic_vector.S
    +++ b/sys/amd64/amd64/apic_vector.S
    @@ -104,6 +104,18 @@ IDTVEC(timerint)
     	MEXITCOUNT
     	jmp	doreti
     
    +/*
    + * Local APIC error interrupt handler.
    + */
    +	.text
    +	SUPERALIGN_TEXT
    +IDTVEC(errorint)
    +	PUSH_FRAME
    +	FAKE_MCOUNT(TF_RIP(%rsp))
    +	call	lapic_handle_error
    +	MEXITCOUNT
    +	jmp	doreti
    +
     #ifdef SMP
     /*
      * Global address space TLB shootdown.
    diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c
    index c27463182a7..8edc971c95c 100644
    --- a/sys/amd64/amd64/local_apic.c
    +++ b/sys/amd64/amd64/local_apic.c
    @@ -115,14 +115,12 @@ struct lapic {
     	int la_ioint_irqs[APIC_NUM_IOINTS + 1];
     } static lapics[MAX_APIC_ID + 1];
     
    -/* XXX: should thermal be an NMI? */
    -
     /* Global defaults for local APIC LVT entries. */
     static struct lvt lvts[LVT_MAX + 1] = {
     	{ 1, 1, 1, 1, APIC_LVT_DM_EXTINT, 0 },	/* LINT0: masked ExtINT */
     	{ 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 },	/* LINT1: NMI */
     	{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_TIMER_INT },	/* Timer */
    -	{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT },	/* Error */
    +	{ 1, 1, 0, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT },	/* Error */
     	{ 1, 1, 1, 1, APIC_LVT_DM_NMI, 0 },	/* PMC */
     	{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_THERMAL_INT },	/* Thermal */
     };
    @@ -225,7 +223,10 @@ lapic_init(vm_paddr_t addr)
     	/* Local APIC timer interrupt. */
     	setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYSIGT, SEL_KPL, 0);
     
    -	/* XXX: error/thermal interrupts */
    +	/* Local APIC error interrupt. */
    +	setidt(APIC_ERROR_INT, IDTVEC(errorint), SDT_SYSIGT, SEL_KPL, 0);
    +
    +	/* XXX: Thermal interrupt */
     }
     
     /*
    @@ -278,7 +279,7 @@ lapic_dump(const char* str)
     	    lapic->id, lapic->version, lapic->ldr, lapic->dfr);
     	printf("  lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n",
     	    lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr);
    -	printf("  timer: 0x%08x therm: 0x%08x err: 0x%08x pcm: 0x%08x\n",
    +	printf("  timer: 0x%08x therm: 0x%08x err: 0x%08x pmc: 0x%08x\n",
     	    lapic->lvt_timer, lapic->lvt_thermal, lapic->lvt_error,
     	    lapic->lvt_pcint);
     }
    @@ -326,7 +327,11 @@ lapic_setup(int boot)
     		lapic_timer_enable_intr();
     	}
     
    -	/* XXX: Error and thermal LVTs */
    +	/* Program error LVT and clear any existing errors. */
    +	lapic->lvt_error = lvt_mode(la, LVT_ERROR, lapic->lvt_error);
    +	lapic->esr = 0;
    +
    +	/* XXX: Thermal LVT */
     
     	intr_restore(eflags);
     }
    @@ -725,18 +730,6 @@ lapic_eoi(void)
     	lapic->eoi = 0;
     }
     
    -/*
    - * Read the contents of the error status register.  We have to write
    - * to the register first before reading from it.
    - */
    -u_int
    -lapic_error(void)
    -{
    -
    -	lapic->esr = 0;
    -	return (lapic->esr);
    -}
    -
     void
     lapic_handle_intr(int vector, struct trapframe *frame)
     {
    @@ -863,6 +856,24 @@ lapic_timer_enable_intr(void)
     	lapic->lvt_timer = value;
     }
     
    +void
    +lapic_handle_error(void)
    +{
    +	u_int32_t esr;
    +
    +	/*
    +	 * Read the contents of the error status register.  Write to
    +	 * the register first before reading from it to force the APIC
    +	 * to update its value to indicate any errors that have
    +	 * occurred since the previous write to the register.
    +	 */
    +	lapic->esr = 0;
    +	esr = lapic->esr;
    +
    +	printf("CPU%d: local APIC error 0x%x\n", PCPU_GET(cpuid), esr);
    +	lapic_eoi();
    +}
    +
     u_int
     apic_cpuid(u_int apic_id)
     {
    diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h
    index 110ce814317..91bba992d8b 100644
    --- a/sys/amd64/include/apicvar.h
    +++ b/sys/amd64/include/apicvar.h
    @@ -179,7 +179,8 @@ struct apic_enumerator {
     inthand_t
     	IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
     	IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
    -	IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint);
    +	IDTVEC(apic_isr7), IDTVEC(errorint), IDTVEC(spuriousint),
    +	IDTVEC(timerint);
     
     extern vm_paddr_t lapic_paddr;
     extern int apic_cpuids[];
    @@ -211,13 +212,13 @@ void	lapic_disable_pmc(void);
     void	lapic_dump(const char *str);
     int	lapic_enable_pmc(void);
     void	lapic_eoi(void);
    -u_int	lapic_error(void);
     int	lapic_id(void);
     void	lapic_init(vm_paddr_t addr);
     int	lapic_intr_pending(u_int vector);
     void	lapic_ipi_raw(register_t icrlo, u_int dest);
     void	lapic_ipi_vectored(u_int vector, int dest);
     int	lapic_ipi_wait(int delay);
    +void	lapic_handle_error(void);
     void	lapic_handle_intr(int vector, struct trapframe *frame);
     void	lapic_handle_timer(struct trapframe *frame);
     void	lapic_reenable_pmc(void);
    diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
    index d4dd90b3842..c4c5b019c43 100644
    --- a/sys/i386/i386/apic_vector.s
    +++ b/sys/i386/i386/apic_vector.s
    @@ -110,6 +110,19 @@ IDTVEC(timerint)
     	MEXITCOUNT
     	jmp	doreti
     
    +/*
    + * Local APIC error interrupt handler.
    + */
    +	.text
    +	SUPERALIGN_TEXT
    +IDTVEC(errorint)
    +	PUSH_FRAME
    +	SET_KERNEL_SREGS
    +	FAKE_MCOUNT(TF_EIP(%esp))
    +	call	lapic_handle_error
    +	MEXITCOUNT
    +	jmp	doreti
    +
     #ifdef SMP
     /*
      * Global address space TLB shootdown.
    diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c
    index 6c6220022b9..302535f27f9 100644
    --- a/sys/i386/i386/local_apic.c
    +++ b/sys/i386/i386/local_apic.c
    @@ -116,14 +116,12 @@ struct lapic {
     	int la_ioint_irqs[APIC_NUM_IOINTS + 1];
     } static lapics[MAX_APIC_ID + 1];
     
    -/* XXX: should thermal be an NMI? */
    -
     /* Global defaults for local APIC LVT entries. */
     static struct lvt lvts[LVT_MAX + 1] = {
     	{ 1, 1, 1, 1, APIC_LVT_DM_EXTINT, 0 },	/* LINT0: masked ExtINT */
     	{ 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 },	/* LINT1: NMI */
     	{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_TIMER_INT },	/* Timer */
    -	{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT },	/* Error */
    +	{ 1, 1, 0, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT },	/* Error */
     	{ 1, 1, 1, 1, APIC_LVT_DM_NMI, 0 },	/* PMC */
     	{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_THERMAL_INT },	/* Thermal */
     };
    @@ -228,7 +226,11 @@ lapic_init(vm_paddr_t addr)
     	setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYS386IGT, SEL_KPL,
     	    GSEL(GCODE_SEL, SEL_KPL));
     
    -	/* XXX: error/thermal interrupts */
    +	/* Local APIC error interrupt. */
    +	setidt(APIC_ERROR_INT, IDTVEC(errorint), SDT_SYS386IGT, SEL_KPL,
    +	    GSEL(GCODE_SEL, SEL_KPL));
    +
    +	/* XXX: Thermal interrupt */
     }
     
     /*
    @@ -281,7 +283,7 @@ lapic_dump(const char* str)
     	    lapic->id, lapic->version, lapic->ldr, lapic->dfr);
     	printf("  lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n",
     	    lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr);
    -	printf("  timer: 0x%08x therm: 0x%08x err: 0x%08x pcm: 0x%08x\n",
    +	printf("  timer: 0x%08x therm: 0x%08x err: 0x%08x pmc: 0x%08x\n",
     	    lapic->lvt_timer, lapic->lvt_thermal, lapic->lvt_error,
     	    lapic->lvt_pcint);
     }
    @@ -329,7 +331,11 @@ lapic_setup(int boot)
     		lapic_timer_enable_intr();
     	}
     
    -	/* XXX: Error and thermal LVTs */
    +	/* Program error LVT and clear any existing errors. */
    +	lapic->lvt_error = lvt_mode(la, LVT_ERROR, lapic->lvt_error);
    +	lapic->esr = 0;
    +
    +	/* XXX: Thermal LVT */
     
     	intr_restore(eflags);
     }
    @@ -725,18 +731,6 @@ lapic_eoi(void)
     	lapic->eoi = 0;
     }
     
    -/*
    - * Read the contents of the error status register.  We have to write
    - * to the register first before reading from it.
    - */
    -u_int
    -lapic_error(void)
    -{
    -
    -	lapic->esr = 0;
    -	return (lapic->esr);
    -}
    -
     void
     lapic_handle_intr(int vector, struct trapframe *frame)
     {
    @@ -863,6 +857,24 @@ lapic_timer_enable_intr(void)
     	lapic->lvt_timer = value;
     }
     
    +void
    +lapic_handle_error(void)
    +{
    +	u_int32_t esr;
    +
    +	/*
    +	 * Read the contents of the error status register.  Write to
    +	 * the register first before reading from it to force the APIC
    +	 * to update its value to indicate any errors that have
    +	 * occurred since the previous write to the register.
    +	 */
    +	lapic->esr = 0;
    +	esr = lapic->esr;
    +
    +	printf("CPU%d: local APIC error 0x%x\n", PCPU_GET(cpuid), esr);
    +	lapic_eoi();
    +}
    +
     u_int
     apic_cpuid(u_int apic_id)
     {
    diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h
    index 208ffb53302..bcb84a0c49f 100644
    --- a/sys/i386/include/apicvar.h
    +++ b/sys/i386/include/apicvar.h
    @@ -208,7 +208,8 @@ struct apic_enumerator {
     inthand_t
     	IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
     	IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
    -	IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint);
    +	IDTVEC(apic_isr7), IDTVEC(errorint), IDTVEC(spuriousint),
    +	IDTVEC(timerint);
     
     extern vm_paddr_t lapic_paddr;
     extern int apic_cpuids[];
    @@ -240,13 +241,13 @@ void	lapic_disable_pmc(void);
     void	lapic_dump(const char *str);
     int	lapic_enable_pmc(void);
     void	lapic_eoi(void);
    -u_int	lapic_error(void);
     int	lapic_id(void);
     void	lapic_init(vm_paddr_t addr);
     int	lapic_intr_pending(u_int vector);
     void	lapic_ipi_raw(register_t icrlo, u_int dest);
     void	lapic_ipi_vectored(u_int vector, int dest);
     int	lapic_ipi_wait(int delay);
    +void	lapic_handle_error(void);
     void	lapic_handle_intr(int vector, struct trapframe *frame);
     void	lapic_handle_timer(struct trapframe *frame);
     void	lapic_reenable_pmc(void);
    
    From f76f001a479b56103810de5da5fc0635984c11ad Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Wed, 14 Apr 2010 15:03:58 +0000
    Subject: [PATCH 1947/2592] MFC r206399, r206479: Disambiguate `IPs' to a more
     specific term.
    
    ---
     etc/rc.firewall | 14 ++++++++------
     1 file changed, 8 insertions(+), 6 deletions(-)
    
    diff --git a/etc/rc.firewall b/etc/rc.firewall
    index d8f50af6c2b..cda7c34e1dd 100644
    --- a/etc/rc.firewall
    +++ b/etc/rc.firewall
    @@ -424,13 +424,15 @@ case ${firewall_type} in
     	# Configuration:
     	#  firewall_myservices:		List of TCP ports on which this host
     	#			 	 offers services.
    -	#  firewall_allowservices:	List of IPs which has access to
    +	#  firewall_allowservices:	List of IPv4 and/or IPv6 addresses
    +	#				 that have access to
     	#				 $firewall_myservices.
    -	#  firewall_trusted:		List of IPs which has full access 
    -	#				 to this host. Be very carefull 
    -	#				 when setting this. This option can
    -	#				 seriously degrade the level of 
    -	#				 protection provided by the firewall.
    +	#  firewall_trusted:		List of IPv4 and/or IPv6 addresses
    +	#				 that have full access to this host.
    +	#				 Be very careful when setting this.
    +	#				 This option can seriously degrade
    +	#				 the level of protection provided by
    +	#				 the firewall.
     	#  firewall_logdeny:		Boolean (YES/NO) specifying if the
     	#				 default denied packets should be
     	#				 logged (in /var/log/security).
    
    From f70ad5484f0bf06d599b98a6a8cfd47739789c0b Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Wed, 14 Apr 2010 15:22:58 +0000
    Subject: [PATCH 1948/2592] MFC 205536: Reject attempts to create a MAP_ANON
     mapping with a non-zero offset.
    
    ---
     lib/libc/sys/mmap.2 | 7 ++++++-
     sys/vm/vm_mmap.c    | 3 +--
     2 files changed, 7 insertions(+), 3 deletions(-)
    
    diff --git a/lib/libc/sys/mmap.2 b/lib/libc/sys/mmap.2
    index e63274808d5..85019b2e25c 100644
    --- a/lib/libc/sys/mmap.2
    +++ b/lib/libc/sys/mmap.2
    @@ -105,7 +105,7 @@ The file descriptor used for creating
     must be \-1.
     The
     .Fa offset
    -argument is ignored.
    +argument must be 0.
     .\".It Dv MAP_FILE
     .\"Mapped from a regular file or character-special device memory.
     .It Dv MAP_FIXED
    @@ -312,6 +312,11 @@ was equal to zero.
     was specified and the
     .Fa fd
     argument was not -1.
    +.It Bq Er EINVAL
    +.Dv MAP_ANON
    +was specified and the
    +.Fa offset
    +argument was not 0.
     .It Bq Er ENODEV
     .Dv MAP_ANON
     has not been specified and
    diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
    index c8d25ee3a30..14a39795f5f 100644
    --- a/sys/vm/vm_mmap.c
    +++ b/sys/vm/vm_mmap.c
    @@ -232,7 +232,7 @@ mmap(td, uap)
     	/* make sure mapping fits into numeric range etc */
     	if ((uap->len == 0 && !SV_CURPROC_FLAG(SV_AOUT) &&
     	     curproc->p_osrel >= 800104) ||
    -	    ((flags & MAP_ANON) && uap->fd != -1))
    +	    ((flags & MAP_ANON) && (uap->fd != -1 || pos != 0)))
     		return (EINVAL);
     
     	if (flags & MAP_STACK) {
    @@ -298,7 +298,6 @@ mmap(td, uap)
     		handle = NULL;
     		handle_type = OBJT_DEFAULT;
     		maxprot = VM_PROT_ALL;
    -		pos = 0;
     	} else {
     		/*
     		 * Mapping file, get fp for validation and
    
    From 805de54cfcc90e1ad0f2e11f4c0edb06a7c5df5f Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Wed, 14 Apr 2010 15:33:15 +0000
    Subject: [PATCH 1949/2592] MFC 205886: Defer freeing a kevent list until after
     dropping kqueue locks.
    
    ---
     sys/kern/kern_event.c | 10 ++++++----
     1 file changed, 6 insertions(+), 4 deletions(-)
    
    diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
    index 9109e0e087d..bcfe2767a75 100644
    --- a/sys/kern/kern_event.c
    +++ b/sys/kern/kern_event.c
    @@ -1203,7 +1203,7 @@ static int
     kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
     	int waitok)
     {
    -	struct klist *list, *tmp_knhash;
    +	struct klist *list, *tmp_knhash, *to_free;
     	u_long tmp_knhashmask;
     	int size;
     	int fd;
    @@ -1211,6 +1211,7 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
     
     	KQ_NOTOWNED(kq);
     
    +	to_free = NULL;
     	if (fops->f_isfd) {
     		fd = ident;
     		if (kq->kq_knlistsize <= fd) {
    @@ -1222,13 +1223,13 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
     				return ENOMEM;
     			KQ_LOCK(kq);
     			if (kq->kq_knlistsize > fd) {
    -				free(list, M_KQUEUE);
    +				to_free = list;
     				list = NULL;
     			} else {
     				if (kq->kq_knlist != NULL) {
     					bcopy(kq->kq_knlist, list,
     					    kq->kq_knlistsize * sizeof list);
    -					free(kq->kq_knlist, M_KQUEUE);
    +					to_free = kq->kq_knlist;
     					kq->kq_knlist = NULL;
     				}
     				bzero((caddr_t)list +
    @@ -1250,11 +1251,12 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
     				kq->kq_knhash = tmp_knhash;
     				kq->kq_knhashmask = tmp_knhashmask;
     			} else {
    -				free(tmp_knhash, M_KQUEUE);
    +				to_free = tmp_knhash;
     			}
     			KQ_UNLOCK(kq);
     		}
     	}
    +	free(to_free, M_KQUEUE);
     
     	KQ_NOTOWNED(kq);
     	return 0;
    
    From 311d363969d37b9eb431754cb82f2b592165860a Mon Sep 17 00:00:00 2001
    From: Alan Cox 
    Date: Wed, 14 Apr 2010 16:31:59 +0000
    Subject: [PATCH 1950/2592] MFC r206409   Introduce the function
     kmem_alloc_attr(), which allocates kernel virtual   memory with the specified
     physical attributes.
    
      Correct an error in the prototype for kmem_malloc().
    ---
     sys/vm/vm_contig.c | 115 ++++++++++++++++++++++++++++++++++++++-------
     sys/vm/vm_extern.h |   4 +-
     2 files changed, 100 insertions(+), 19 deletions(-)
    
    diff --git a/sys/vm/vm_contig.c b/sys/vm/vm_contig.c
    index 7358cb0cca8..78d7e280836 100644
    --- a/sys/vm/vm_contig.c
    +++ b/sys/vm/vm_contig.c
    @@ -87,6 +87,8 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    +static void vm_contig_grow_cache(int tries);
    +
     static int
     vm_contig_launder_page(vm_page_t m, vm_page_t *next)
     {
    @@ -185,6 +187,99 @@ vm_page_release_contig(vm_page_t m, vm_pindex_t count)
     	}
     }
     
    +/*
    + * Increase the number of cached pages.
    + */
    +static void
    +vm_contig_grow_cache(int tries)
    +{
    +	int actl, actmax, inactl, inactmax;
    +
    +	vm_page_lock_queues();
    +	inactl = 0;
    +	inactmax = tries < 1 ? 0 : cnt.v_inactive_count;
    +	actl = 0;
    +	actmax = tries < 2 ? 0 : cnt.v_active_count;
    +again:
    +	if (inactl < inactmax && vm_contig_launder(PQ_INACTIVE)) {
    +		inactl++;
    +		goto again;
    +	}
    +	if (actl < actmax && vm_contig_launder(PQ_ACTIVE)) {
    +		actl++;
    +		goto again;
    +	}
    +	vm_page_unlock_queues();
    +}
    +
    +/*
    + * Allocates a region from the kernel address map and pages within the
    + * specified physical address range to the kernel object, creates a wired
    + * mapping from the region to these pages, and returns the region's starting
    + * virtual address.  The allocated pages are not necessarily physically
    + * contiguous.  If M_ZERO is specified through the given flags, then the pages
    + * are zeroed before they are mapped.
    + */
    +vm_offset_t
    +kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low,
    +    vm_paddr_t high, vm_memattr_t memattr)
    +{
    +	vm_object_t object = kernel_object;
    +	vm_offset_t addr, i, offset;
    +	vm_page_t m;
    +	int tries;
    +
    +	size = round_page(size);
    +	vm_map_lock(map);
    +	if (vm_map_findspace(map, vm_map_min(map), size, &addr)) {
    +		vm_map_unlock(map);
    +		return (0);
    +	}
    +	offset = addr - VM_MIN_KERNEL_ADDRESS;
    +	vm_object_reference(object);
    +	vm_map_insert(map, object, offset, addr, addr + size, VM_PROT_ALL,
    +	    VM_PROT_ALL, 0);
    +	VM_OBJECT_LOCK(object);
    +	for (i = 0; i < size; i += PAGE_SIZE) {
    +		tries = 0;
    +retry:
    +		m = vm_phys_alloc_contig(1, low, high, PAGE_SIZE, 0);
    +		if (m == NULL) {
    +			if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
    +				VM_OBJECT_UNLOCK(object);
    +				vm_map_unlock(map);
    +				vm_contig_grow_cache(tries);
    +				vm_map_lock(map);
    +				VM_OBJECT_LOCK(object);
    +				goto retry;
    +			}
    +			while (i != 0) {
    +				i -= PAGE_SIZE;
    +				m = vm_page_lookup(object, OFF_TO_IDX(offset +
    +				    i));
    +				vm_page_lock_queues();
    +				vm_page_free(m);
    +				vm_page_unlock_queues();
    +			}
    +			VM_OBJECT_UNLOCK(object);
    +			vm_map_delete(map, addr, addr + size);
    +			vm_map_unlock(map);
    +			return (0);
    +		}
    +		if (memattr != VM_MEMATTR_DEFAULT)
    +			pmap_page_set_memattr(m, memattr);
    +		vm_page_insert(m, object, OFF_TO_IDX(offset + i));
    +		if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0)
    +			pmap_zero_page(m);
    +		m->valid = VM_PAGE_BITS_ALL;
    +	}
    +	VM_OBJECT_UNLOCK(object);
    +	vm_map_unlock(map);
    +	vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM |
    +	    VM_MAP_WIRE_NOHOLES);
    +	return (addr);
    +}
    +
     /*
      *	Allocates a region from the kernel address map, inserts the
      *	given physically contiguous pages into the kernel object,
    @@ -253,7 +348,7 @@ kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low,
     	vm_offset_t ret;
     	vm_page_t pages;
     	unsigned long npgs;
    -	int actl, actmax, inactl, inactmax, tries;
    +	int tries;
     
     	size = round_page(size);
     	npgs = size >> PAGE_SHIFT;
    @@ -262,23 +357,7 @@ retry:
     	pages = vm_phys_alloc_contig(npgs, low, high, alignment, boundary);
     	if (pages == NULL) {
     		if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
    -			vm_page_lock_queues();
    -			inactl = 0;
    -			inactmax = tries < 1 ? 0 : cnt.v_inactive_count;
    -			actl = 0;
    -			actmax = tries < 2 ? 0 : cnt.v_active_count;
    -again:
    -			if (inactl < inactmax &&
    -			    vm_contig_launder(PQ_INACTIVE)) {
    -				inactl++;
    -				goto again;
    -			}
    -			if (actl < actmax &&
    -			    vm_contig_launder(PQ_ACTIVE)) {
    -				actl++;
    -				goto again;
    -			}
    -			vm_page_unlock_queues();
    +			vm_contig_grow_cache(tries);
     			tries++;
     			goto retry;
     		}
    diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h
    index ff489839a36..e81b7b2b3c5 100644
    --- a/sys/vm/vm_extern.h
    +++ b/sys/vm/vm_extern.h
    @@ -41,6 +41,8 @@ struct vnode;
     
     int kernacc(void *, int, int);
     vm_offset_t kmem_alloc(vm_map_t, vm_size_t);
    +vm_offset_t kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags,
    +    vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr);
     vm_offset_t kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags,
         vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
         unsigned long boundary, vm_memattr_t memattr);
    @@ -49,7 +51,7 @@ vm_offset_t kmem_alloc_wait(vm_map_t, vm_size_t);
     void kmem_free(vm_map_t, vm_offset_t, vm_size_t);
     void kmem_free_wakeup(vm_map_t, vm_offset_t, vm_size_t);
     void kmem_init(vm_offset_t, vm_offset_t);
    -vm_offset_t kmem_malloc(vm_map_t, vm_size_t, boolean_t);
    +vm_offset_t kmem_malloc(vm_map_t map, vm_size_t size, int flags);
     vm_map_t kmem_suballoc(vm_map_t, vm_offset_t *, vm_offset_t *, vm_size_t,
         boolean_t);
     void swapout_procs(int);
    
    From 88b4fd072e733c753a689f6c0277a2bfe6331dc0 Mon Sep 17 00:00:00 2001
    From: "Justin T. Gibbs" 
    Date: Wed, 14 Apr 2010 16:37:34 +0000
    Subject: [PATCH 1951/2592] MFC revision 205781: Use standard types in
     preference to BSD types so that these header files can be used in
     applications compiled with only POSIX types visible.
    
    ---
     sys/dev/bktr/ioctl_bt848.h  | 14 +++++++-------
     sys/dev/bktr/ioctl_meteor.h | 26 +++++++++++++-------------
     2 files changed, 20 insertions(+), 20 deletions(-)
    
    diff --git a/sys/dev/bktr/ioctl_bt848.h b/sys/dev/bktr/ioctl_bt848.h
    index 3731e7d2b34..6e50b615deb 100644
    --- a/sys/dev/bktr/ioctl_bt848.h
    +++ b/sys/dev/bktr/ioctl_bt848.h
    @@ -89,9 +89,9 @@
      * EEProm stuff
      */
     struct eeProm {
    -	short	offset;
    -	short	count;
    -	u_char	bytes[ 256 ];
    +	short		offset;
    +	short		count;
    +	unsigned char	bytes[ 256 ];
     };
     
     
    @@ -147,7 +147,7 @@ struct eeProm {
      * b23-b16:  i2c addr (write)
      * b31-b24:  1 = write, 0 = read 
      */
    -#define BT848_I2CWR     _IOWR('x', 57, u_long)    /* i2c read-write */
    +#define BT848_I2CWR     _IOWR('x', 57, unsigned long)    /* i2c read-write */
     
     struct bktr_msp_control {
     	unsigned char function;
    @@ -192,10 +192,10 @@ typedef enum { METEOR_PIXTYPE_RGB, METEOR_PIXTYPE_YUV,
     
     
     struct meteor_pixfmt {
    -	u_int          index;         /* Index in supported pixfmt list     */
    +	unsigned int   index;         /* Index in supported pixfmt list     */
     	METEOR_PIXTYPE type;          /* What's the board gonna feed us     */
    -	u_int          Bpp;           /* Bytes per pixel                    */
    -	u_long         masks[3];      /* R,G,B or Y,U,V masks, respectively */
    +	unsigned int   Bpp;           /* Bytes per pixel                    */
    +	unsigned long  masks[3];      /* R,G,B or Y,U,V masks, respectively */
     	unsigned       swap_bytes :1; /* Bytes  swapped within shorts       */
     	unsigned       swap_shorts:1; /* Shorts swapped within longs        */
     };
    diff --git a/sys/dev/bktr/ioctl_meteor.h b/sys/dev/bktr/ioctl_meteor.h
    index 681990aa03c..8e769ecbe92 100644
    --- a/sys/dev/bktr/ioctl_meteor.h
    +++ b/sys/dev/bktr/ioctl_meteor.h
    @@ -50,27 +50,27 @@ struct meteor_capframe {
     
     /* structure for METEOR[GS]ETGEO - get/set geometry  */
     struct meteor_geomet {
    -	u_short		rows;
    -	u_short		columns;
    -	u_short		frames;
    -	u_long		oformat;
    +	unsigned short		rows;
    +	unsigned short		columns;
    +	unsigned short		frames;
    +	unsigned long		oformat;
     } ;
     
     /* structure for METEORGCOUNT-get count of frames, fifo errors and dma errors */
     struct meteor_counts {
    -	u_long fifo_errors;	/* count of fifo errors since open */
    -	u_long dma_errors;	/* count of dma errors since open */
    -	u_long frames_captured;	/* count of frames captured since open */
    -	u_long even_fields_captured; /* count of even fields captured */
    -	u_long odd_fields_captured; /* count of odd fields captured */
    +	unsigned long fifo_errors;	/* count of fifo errors since open */
    +	unsigned long dma_errors;	/* count of dma errors since open */
    +	unsigned long frames_captured;	/* count of frames captured since open */
    +	unsigned long even_fields_captured; /* count of even fields captured */
    +	unsigned long odd_fields_captured; /* count of odd fields captured */
     } ;
     
     /* structure for getting and setting direct transfers to vram */
     struct meteor_video {
    -	u_long	addr;	/* Address of location to dma to */
    -	u_long	width;	/* Width of memory area */
    -	u_long	banksize;	/* Size of Vram bank */
    -	u_long	ramsize;	/* Size of Vram */
    +	unsigned long	addr;		/* Address of location to dma to */
    +	unsigned long	width;		/* Width of memory area */
    +	unsigned long	banksize;	/* Size of Vram bank */
    +	unsigned long	ramsize;	/* Size of Vram */
     };
     
     #define METEORCAPTUR _IOW('x', 1, int)			 /* capture a frame */
    
    From 060c98cc06cdb2c9860326600074c2448e62ab03 Mon Sep 17 00:00:00 2001
    From: "Justin T. Gibbs" 
    Date: Wed, 14 Apr 2010 17:01:29 +0000
    Subject: [PATCH 1952/2592] MFC 204214: Enforce stronger bus-dma alignment
     semantics so bus-dma operates correctly with Xen's blkfront driver.
    
    ---
     sys/amd64/amd64/busdma_machdep.c | 31 +++++++++++++++++++------------
     1 file changed, 19 insertions(+), 12 deletions(-)
    
    diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c
    index 3197d154960..fae6ef36687 100644
    --- a/sys/amd64/amd64/busdma_machdep.c
    +++ b/sys/amd64/amd64/busdma_machdep.c
    @@ -239,8 +239,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
     	newtag->alignment = alignment;
     	newtag->boundary = boundary;
     	newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1);
    -	newtag->highaddr = trunc_page((vm_paddr_t)highaddr) +
    -	    (PAGE_SIZE - 1);
    +	newtag->highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1);
     	newtag->filter = filter;
     	newtag->filterarg = filterarg;
     	newtag->maxsize = maxsize;
    @@ -605,13 +604,18 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
     		vendaddr = (vm_offset_t)buf + buflen;
     
     		while (vaddr < vendaddr) {
    +			bus_size_t sg_len;
    +
    +			sg_len = PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK);
     			if (pmap)
     				paddr = pmap_extract(pmap, vaddr);
     			else
     				paddr = pmap_kextract(vaddr);
    -			if (run_filter(dmat, paddr) != 0)
    +			if (run_filter(dmat, paddr) != 0) {
    +				sg_len = roundup2(sg_len, dmat->alignment);
     				map->pagesneeded++;
    -			vaddr += (PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK));
    +			}
    +			vaddr += sg_len;
     		}
     		CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
     	}
    @@ -644,6 +648,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
     	bmask = ~(dmat->boundary - 1);
     
     	for (seg = *segp; buflen > 0 ; ) {
    +		bus_size_t max_sgsize;
    +
     		/*
     		 * Get the physical address for this segment.
     		 */
    @@ -655,11 +661,15 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
     		/*
     		 * Compute the segment size, and adjust counts.
     		 */
    -		sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
    -		if (sgsize > dmat->maxsegsz)
    -			sgsize = dmat->maxsegsz;
    -		if (buflen < sgsize)
    -			sgsize = buflen;
    +		max_sgsize = MIN(buflen, dmat->maxsegsz);
    +		sgsize = PAGE_SIZE - ((vm_offset_t)curaddr & PAGE_MASK);
    +		if (map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
    +			sgsize = roundup2(sgsize, dmat->alignment);
    +			sgsize = MIN(sgsize, max_sgsize);
    +			curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
    +		} else {
    +			sgsize = MIN(sgsize, max_sgsize);
    +		}
     
     		/*
     		 * Make sure we don't cross any boundaries.
    @@ -670,9 +680,6 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
     				sgsize = (baddr - curaddr);
     		}
     
    -		if (map->pagesneeded != 0 && run_filter(dmat, curaddr))
    -			curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
    -
     		/*
     		 * Insert chunk into a segment, coalescing with
     		 * previous segment if possible.
    
    From a9a298a070547d7273ab16e912fdb11fd11ba17d Mon Sep 17 00:00:00 2001
    From: John Baldwin 
    Date: Wed, 14 Apr 2010 17:17:06 +0000
    Subject: [PATCH 1953/2592] MFC 205900: Use panic() (which the environment is
     required to provide to libstand) to implement assert() instead of relying on
     a non-required exit().  The exit() invocation also did not match the
     semantics of the exit() routine that current boot environments happen to
     require.
    
    ---
     lib/libstand/assert.c | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/lib/libstand/assert.c b/lib/libstand/assert.c
    index b42435824ae..8eec63a4729 100644
    --- a/lib/libstand/assert.c
    +++ b/lib/libstand/assert.c
    @@ -35,10 +35,10 @@ void
     __assert(const char *func, const char *file, int line, const char *expression)
     {
     	if (func == NULL)
    -		printf("Assertion failed: (%s), file %s, line %d.\n",
    +		panic("Assertion failed: (%s), file %s, line %d.\n",
     		    expression, file, line);
     	else
    -		printf("Assertion failed: (%s), function %s, file %s, line "
    -		    "%d.\n", expression, func, file, line);
    -	exit();
    +		panic(
    +		    "Assertion failed: (%s), function %s, file %s, line %d.\n",
    +		    expression, func, file, line);
     }
    
    From 58b823dede2c27f0133e233c5b83b7ec1b049796 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Thu, 15 Apr 2010 01:20:30 +0000
    Subject: [PATCH 1954/2592] MFC r205198:
    
    Merge OpenSolaris revision 8802:010b31dd4c53:
    
    6773366 "zfs list" memory consumption can be further reduced
    
    PR:		bin/144720
    Submitted by:	mm
    ---
     cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c   | 55 +++++++++++++++++--
     .../opensolaris/lib/libzfs/common/libzfs.h    |  1 +
     .../lib/libzfs/common/libzfs_dataset.c        | 30 +++++++++-
     .../lib/libzfs/common/libzfs_impl.h           |  3 +-
     4 files changed, 81 insertions(+), 8 deletions(-)
    
    diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
    index a22370a0279..e5149cbb9ef 100644
    --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
    +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
    @@ -19,7 +19,7 @@
      * CDDL HEADER END
      */
     /*
    - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
    + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
      * Use is subject to license terms.
      */
     
    @@ -58,6 +58,7 @@ typedef struct callback_data {
     	zfs_type_t	cb_types;
     	zfs_sort_column_t *cb_sortcol;
     	zprop_list_t	**cb_proplist;
    +	uint8_t		cb_props_table[ZFS_NUM_PROPS];
     } callback_data_t;
     
     uu_avl_pool_t *avl_pool;
    @@ -98,11 +99,20 @@ zfs_callback(zfs_handle_t *zhp, void *data)
     		uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
     		if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
     		    &idx) == NULL) {
    -			if (cb->cb_proplist &&
    -			    zfs_expand_proplist(zhp, cb->cb_proplist) != 0) {
    -				free(node);
    -				return (-1);
    +
    +			if (cb->cb_proplist) {
    +				if ((*cb->cb_proplist) &&
    +				    !(*cb->cb_proplist)->pl_all)
    +					zfs_prune_proplist(zhp,
    +					    cb->cb_props_table);
    +
    +				if (zfs_expand_proplist(zhp, cb->cb_proplist)
    +				    != 0) {
    +					free(node);
    +					return (-1);
    +				}
     			}
    +
     			uu_avl_insert(cb->cb_avl, node, idx);
     			dontclose = 1;
     		} else {
    @@ -328,7 +338,7 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
         zfs_sort_column_t *sortcol, zprop_list_t **proplist,
         zfs_iter_f callback, void *data)
     {
    -	callback_data_t cb;
    +	callback_data_t cb = {0};
     	int ret = 0;
     	zfs_node_t *node;
     	uu_avl_walk_t *walk;
    @@ -346,6 +356,39 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
     	cb.cb_flags = flags;
     	cb.cb_proplist = proplist;
     	cb.cb_types = types;
    +
    +	/*
    +	 * If cb_proplist is provided then in the zfs_handles created  we
    +	 * retain only those properties listed in cb_proplist and sortcol.
    +	 * The rest are pruned. So, the caller should make sure that no other
    +	 * properties other than those listed in cb_proplist/sortcol are
    +	 * accessed.
    +	 *
    +	 * If cb_proplist is NULL then we retain all the properties.
    +	 */
    +	if (cb.cb_proplist && *cb.cb_proplist) {
    +		zprop_list_t *p = *cb.cb_proplist;
    +
    +		while (p) {
    +			if (p->pl_prop >= ZFS_PROP_TYPE &&
    +			    p->pl_prop < ZFS_NUM_PROPS) {
    +				cb.cb_props_table[p->pl_prop] = B_TRUE;
    +			}
    +			p = p->pl_next;
    +		}
    +
    +		while (sortcol) {
    +			if (sortcol->sc_prop >= ZFS_PROP_TYPE &&
    +			    sortcol->sc_prop < ZFS_NUM_PROPS) {
    +				cb.cb_props_table[sortcol->sc_prop] = B_TRUE;
    +			}
    +			sortcol = sortcol->sc_next;
    +		}
    +	} else {
    +		(void) memset(cb.cb_props_table, B_TRUE,
    +		    sizeof (cb.cb_props_table));
    +	}
    +
     	if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) {
     		(void) fprintf(stderr,
     		    gettext("internal error: out of memory\n"));
    diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
    index 9a13bbbf542..a959494cd52 100644
    --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
    +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
    @@ -369,6 +369,7 @@ typedef struct zprop_list {
     } zprop_list_t;
     
     extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **);
    +extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *);
     
     #define	ZFS_MOUNTPOINT_NONE	"none"
     #define	ZFS_MOUNTPOINT_LEGACY	"legacy"
    diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
    index 58ce6c8fa20..7ed14735629 100644
    --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
    +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
    @@ -20,7 +20,7 @@
      */
     
     /*
    - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
    + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
      * Use is subject to license terms.
      */
     
    @@ -2042,6 +2042,8 @@ getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
     		verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
     		(void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
     	} else {
    +		verify(!zhp->zfs_props_table ||
    +		    zhp->zfs_props_table[prop] == B_TRUE);
     		value = zfs_prop_default_numeric(prop);
     		*source = "";
     	}
    @@ -2061,6 +2063,8 @@ getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
     		verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
     		(void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
     	} else {
    +		verify(!zhp->zfs_props_table ||
    +		    zhp->zfs_props_table[prop] == B_TRUE);
     		if ((value = (char *)zfs_prop_default_string(prop)) == NULL)
     			value = "";
     		*source = "";
    @@ -4264,6 +4268,30 @@ zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path,
     	return (error);
     }
     
    +void
    +zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
    +{
    +	nvpair_t *curr;
    +
    +	/*
    +	 * Keep a reference to the props-table against which we prune the
    +	 * properties.
    +	 */
    +	zhp->zfs_props_table = props;
    +
    +	curr = nvlist_next_nvpair(zhp->zfs_props, NULL);
    +
    +	while (curr) {
    +		zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
    +		nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr);
    +
    +		if (props[zfs_prop] == B_FALSE)
    +			(void) nvlist_remove(zhp->zfs_props,
    +			    nvpair_name(curr), nvpair_type(curr));
    +		curr = next;
    +	}
    +}
    +
     /*
      * Attach/detach the given filesystem to/from the given jail.
      */
    diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
    index afe71f39948..c0e47e905f9 100644
    --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
    +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
    @@ -20,7 +20,7 @@
      */
     
     /*
    - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
    + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
      * Use is subject to license terms.
      */
     
    @@ -77,6 +77,7 @@ struct zfs_handle {
     	nvlist_t *zfs_user_props;
     	boolean_t zfs_mntcheck;
     	char *zfs_mntopts;
    +	uint8_t *zfs_props_table;
     };
     
     /*
    
    From 8dcde976b24d2e779fdf9226ec43b78a8f0cd710 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Thu, 15 Apr 2010 01:22:38 +0000
    Subject: [PATCH 1955/2592] MFC r205199:
    
    Merge OpenSolaris revision 9365:7838a22eccd6:
    
    PSARC/2009/171 zfs list -d and zfs get -d
    6762432 zfs list --depth
    
    PR:		bin/144720
    Submitted by:	mm
    ---
     cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c | 26 +++++----
     cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h |  5 +-
     cddl/contrib/opensolaris/cmd/zfs/zfs_main.c | 62 +++++++++++++++------
     3 files changed, 64 insertions(+), 29 deletions(-)
    
    diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
    index e5149cbb9ef..f0bc01e9dea 100644
    --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
    +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
    @@ -53,12 +53,14 @@ typedef struct zfs_node {
     } zfs_node_t;
     
     typedef struct callback_data {
    -	uu_avl_t	*cb_avl;
    -	int		cb_flags;
    -	zfs_type_t	cb_types;
    -	zfs_sort_column_t *cb_sortcol;
    -	zprop_list_t	**cb_proplist;
    -	uint8_t		cb_props_table[ZFS_NUM_PROPS];
    +	uu_avl_t		*cb_avl;
    +	int			cb_flags;
    +	zfs_type_t		cb_types;
    +	zfs_sort_column_t	*cb_sortcol;
    +	zprop_list_t		**cb_proplist;
    +	int			cb_depth_limit;
    +	int			cb_depth;
    +	uint8_t			cb_props_table[ZFS_NUM_PROPS];
     } callback_data_t;
     
     uu_avl_pool_t *avl_pool;
    @@ -99,7 +101,6 @@ zfs_callback(zfs_handle_t *zhp, void *data)
     		uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
     		if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
     		    &idx) == NULL) {
    -
     			if (cb->cb_proplist) {
     				if ((*cb->cb_proplist) &&
     				    !(*cb->cb_proplist)->pl_all)
    @@ -112,7 +113,6 @@ zfs_callback(zfs_handle_t *zhp, void *data)
     					return (-1);
     				}
     			}
    -
     			uu_avl_insert(cb->cb_avl, node, idx);
     			dontclose = 1;
     		} else {
    @@ -123,11 +123,15 @@ zfs_callback(zfs_handle_t *zhp, void *data)
     	/*
     	 * Recurse if necessary.
     	 */
    -	if (cb->cb_flags & ZFS_ITER_RECURSE) {
    +	if (cb->cb_flags & ZFS_ITER_RECURSE &&
    +	    ((cb->cb_flags & ZFS_ITER_DEPTH_LIMIT) == 0 ||
    +	    cb->cb_depth < cb->cb_depth_limit)) {
    +		cb->cb_depth++;
     		if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
     			(void) zfs_iter_filesystems(zhp, zfs_callback, data);
     		if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps)
     			(void) zfs_iter_snapshots(zhp, zfs_callback, data);
    +		cb->cb_depth--;
     	}
     
     	if (!dontclose)
    @@ -335,7 +339,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
     
     int
     zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
    -    zfs_sort_column_t *sortcol, zprop_list_t **proplist,
    +    zfs_sort_column_t *sortcol, zprop_list_t **proplist, int limit,
         zfs_iter_f callback, void *data)
     {
     	callback_data_t cb = {0};
    @@ -356,7 +360,7 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
     	cb.cb_flags = flags;
     	cb.cb_proplist = proplist;
     	cb.cb_types = types;
    -
    +	cb.cb_depth_limit = limit;
     	/*
     	 * If cb_proplist is provided then in the zfs_handles created  we
     	 * retain only those properties listed in cb_proplist and sortcol.
    diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h
    index 76a11085a1e..a0290775b6b 100644
    --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h
    +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h
    @@ -19,7 +19,7 @@
      * CDDL HEADER END
      */
     /*
    - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
    + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
      * Use is subject to license terms.
      */
     
    @@ -41,9 +41,10 @@ typedef struct zfs_sort_column {
     #define	ZFS_ITER_RECURSE	   (1 << 0)
     #define	ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1)
     #define	ZFS_ITER_PROP_LISTSNAPS    (1 << 2)
    +#define	ZFS_ITER_DEPTH_LIMIT	   (1 << 3)
     
     int zfs_for_each(int, char **, int options, zfs_type_t,
    -    zfs_sort_column_t *, zprop_list_t **, zfs_iter_f, void *);
    +    zfs_sort_column_t *, zprop_list_t **, int, zfs_iter_f, void *);
     int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
     void zfs_free_sort_columns(zfs_sort_column_t *);
     
    diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
    index d6bc6e129af..79428f7f541 100644
    --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
    +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
    @@ -190,8 +190,8 @@ get_usage(zfs_help_t idx)
     		return (gettext("\tdestroy [-rRf] "
     		    "\n"));
     	case HELP_GET:
    -		return (gettext("\tget [-rHp] [-o field[,...]] "
    -		    "[-s source[,...]]\n"
    +		return (gettext("\tget [-rHp] [-d max] "
    +		    "[-o field[,...]] [-s source[,...]]\n"
     		    "\t    <\"all\" | property[,...]> "
     		    "[filesystem|volume|snapshot] ...\n"));
     	case HELP_INHERIT:
    @@ -205,8 +205,8 @@ get_usage(zfs_help_t idx)
     	case HELP_UNJAIL:
     		return (gettext("\tunjail  \n"));
     	case HELP_LIST:
    -		return (gettext("\tlist [-rH] [-o property[,...]] "
    -		    "[-t type[,...]] [-s property] ...\n"
    +		return (gettext("\tlist [-rH][-d max] "
    +		    "[-o property[,...]] [-t type[,...]] [-s property] ...\n"
     		    "\t    [-S property] ... "
     		    "[filesystem|volume|snapshot] ...\n"));
     	case HELP_MOUNT:
    @@ -432,6 +432,27 @@ parseprop(nvlist_t *props)
     
     }
     
    +static int
    +parse_depth(char *opt, int *flags)
    +{
    +	char *tmp;
    +	int depth;
    +
    +	depth = (int)strtol(opt, &tmp, 0);
    +	if (*tmp) {
    +		(void) fprintf(stderr,
    +		    gettext("%s is not an integer\n"), optarg);
    +		usage(B_FALSE);
    +	}
    +	if (depth < 0) {
    +		(void) fprintf(stderr,
    +		    gettext("Depth can not be negative.\n"));
    +		usage(B_FALSE);
    +	}
    +	*flags |= (ZFS_ITER_DEPTH_LIMIT|ZFS_ITER_RECURSE);
    +	return (depth);
    +}
    +
     /*
      * zfs clone [-p] [-o prop=value] ...  
      *
    @@ -1119,6 +1140,7 @@ zfs_do_get(int argc, char **argv)
     	int i, c, flags = 0;
     	char *value, *fields;
     	int ret;
    +	int limit = 0;
     	zprop_list_t fake_name = { 0 };
     
     	/*
    @@ -1132,11 +1154,14 @@ zfs_do_get(int argc, char **argv)
     	cb.cb_type = ZFS_TYPE_DATASET;
     
     	/* check options */
    -	while ((c = getopt(argc, argv, ":o:s:rHp")) != -1) {
    +	while ((c = getopt(argc, argv, ":d:o:s:rHp")) != -1) {
     		switch (c) {
     		case 'p':
     			cb.cb_literal = B_TRUE;
     			break;
    +		case 'd':
    +			limit = parse_depth(optarg, &flags);
    +			break;
     		case 'r':
     			flags |= ZFS_ITER_RECURSE;
     			break;
    @@ -1267,7 +1292,7 @@ zfs_do_get(int argc, char **argv)
     
     	/* run for each object */
     	ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET, NULL,
    -	    &cb.cb_proplist, get_callback, &cb);
    +	    &cb.cb_proplist, limit, get_callback, &cb);
     
     	if (cb.cb_proplist == &fake_name)
     		zprop_free_list(fake_name.pl_next);
    @@ -1380,10 +1405,10 @@ zfs_do_inherit(int argc, char **argv)
     
     	if (flags & ZFS_ITER_RECURSE) {
     		ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET,
    -		    NULL, NULL, inherit_recurse_cb, propname);
    +		    NULL, NULL, 0, inherit_recurse_cb, propname);
     	} else {
     		ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET,
    -		    NULL, NULL, inherit_cb, propname);
    +		    NULL, NULL, 0, inherit_cb, propname);
     	}
     
     	return (ret);
    @@ -1578,7 +1603,7 @@ zfs_do_upgrade(int argc, char **argv)
     		if (cb.cb_version == 0)
     			cb.cb_version = ZPL_VERSION;
     		ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_FILESYSTEM,
    -		    NULL, NULL, upgrade_set_callback, &cb);
    +		    NULL, NULL, 0, upgrade_set_callback, &cb);
     		(void) printf(gettext("%llu filesystems upgraded\n"),
     		    cb.cb_numupgraded);
     		if (cb.cb_numsamegraded) {
    @@ -1596,14 +1621,14 @@ zfs_do_upgrade(int argc, char **argv)
     
     		flags |= ZFS_ITER_RECURSE;
     		ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM,
    -		    NULL, NULL, upgrade_list_callback, &cb);
    +		    NULL, NULL, 0, upgrade_list_callback, &cb);
     
     		found = cb.cb_foundone;
     		cb.cb_foundone = B_FALSE;
     		cb.cb_newer = B_TRUE;
     
     		ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM,
    -		    NULL, NULL, upgrade_list_callback, &cb);
    +		    NULL, NULL, 0, upgrade_list_callback, &cb);
     
     		if (!cb.cb_foundone && !found) {
     			(void) printf(gettext("All filesystems are "
    @@ -1615,11 +1640,12 @@ zfs_do_upgrade(int argc, char **argv)
     }
     
     /*
    - * list [-rH] [-o property[,property]...] [-t type[,type]...]
    + * list [-r][-d max] [-H] [-o property[,property]...] [-t type[,type]...]
      *      [-s property [-s property]...] [-S property [-S property]...]
      *       ...
      *
      * 	-r	Recurse over all children
    + * 	-d	Limit recursion by depth.
      * 	-H	Scripted mode; elide headers and separate columns by tabs
      * 	-o	Control which fields to display.
      * 	-t	Control which object types to display.
    @@ -1769,16 +1795,20 @@ zfs_do_list(int argc, char **argv)
     	char *fields = NULL;
     	list_cbdata_t cb = { 0 };
     	char *value;
    +	int limit = 0;
     	int ret;
     	zfs_sort_column_t *sortcol = NULL;
     	int flags = ZFS_ITER_PROP_LISTSNAPS | ZFS_ITER_ARGS_CAN_BE_PATHS;
     
     	/* check options */
    -	while ((c = getopt(argc, argv, ":o:rt:Hs:S:")) != -1) {
    +	while ((c = getopt(argc, argv, ":d:o:rt:Hs:S:")) != -1) {
     		switch (c) {
     		case 'o':
     			fields = optarg;
     			break;
    +		case 'd':
    +			limit = parse_depth(optarg, &flags);
    +			break;
     		case 'r':
     			flags |= ZFS_ITER_RECURSE;
     			break;
    @@ -1869,7 +1899,7 @@ zfs_do_list(int argc, char **argv)
     	cb.cb_first = B_TRUE;
     
     	ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist,
    -	    list_callback, &cb);
    +	    limit, list_callback, &cb);
     
     	zprop_free_list(cb.cb_proplist);
     	zfs_free_sort_columns(sortcol);
    @@ -2252,7 +2282,7 @@ zfs_do_set(int argc, char **argv)
     	}
     
     	ret = zfs_for_each(argc - 2, argv + 2, NULL,
    -	    ZFS_TYPE_DATASET, NULL, NULL, set_callback, &cb);
    +	    ZFS_TYPE_DATASET, NULL, NULL, 0, set_callback, &cb);
     
     	return (ret);
     }
    @@ -2886,7 +2916,7 @@ zfs_do_unallow(int argc, char **argv)
     		flags |= ZFS_ITER_RECURSE;
     	error = zfs_for_each(argc, argv, flags,
     	    ZFS_TYPE_FILESYSTEM|ZFS_TYPE_VOLUME, NULL,
    -	    NULL, unallow_callback, (void *)zperms);
    +	    NULL, 0, unallow_callback, (void *)zperms);
     
     	if (zperms)
     		nvlist_free(zperms);
    
    From 305cb06fe341129c1930ad388cebe02debc445ec Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Thu, 15 Apr 2010 01:25:17 +0000
    Subject: [PATCH 1956/2592] MFC r205200 + r206199
    
    Merge OpenSolaris revision 9396:f41cf682d0d3:
    
    6830813 zfs list -t all fails assertion
    
    *Note that this is only a partial merge of this revision addressing only
    this one issue.*
    
    PR:		bin/144720
    Submitted by:	mm
    ---
     cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c               | 8 +++++++-
     .../opensolaris/lib/libzfs/common/libzfs_dataset.c        | 7 ++++++-
     2 files changed, 13 insertions(+), 2 deletions(-)
    
    diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
    index f0bc01e9dea..ca5c2b23278 100644
    --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
    +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
    @@ -368,7 +368,10 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
     	 * properties other than those listed in cb_proplist/sortcol are
     	 * accessed.
     	 *
    -	 * If cb_proplist is NULL then we retain all the properties.
    +	 * If cb_proplist is NULL then we retain all the properties.  We
    +	 * always retain the zoned property, which some other properties
    +	 * need (userquota & friends), and the createtxg property, which
    +	 * we need to sort snapshots.
     	 */
     	if (cb.cb_proplist && *cb.cb_proplist) {
     		zprop_list_t *p = *cb.cb_proplist;
    @@ -388,6 +391,9 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
     			}
     			sortcol = sortcol->sc_next;
     		}
    +
    +		cb.cb_props_table[ZFS_PROP_ZONED] = B_TRUE;
    +		cb.cb_props_table[ZFS_PROP_CREATETXG] = B_TRUE;
     	} else {
     		(void) memset(cb.cb_props_table, B_TRUE,
     		    sizeof (cb.cb_props_table));
    diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
    index 7ed14735629..fa92a1d87a1 100644
    --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
    +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
    @@ -4285,7 +4285,12 @@ zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
     		zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
     		nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr);
     
    -		if (props[zfs_prop] == B_FALSE)
    +		/*
    +		 * We leave user:props in the nvlist, so there will be
    +		 * some ZPROP_INVAL.  To be extra safe, don't prune
    +		 * those.
    +		 */
    +		if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE)
     			(void) nvlist_remove(zhp->zfs_props,
     			    nvpair_name(curr), nvpair_type(curr));
     		curr = next;
    
    From b754ab83bc91b3be115ec4a1e70651817c669eae Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Thu, 15 Apr 2010 08:17:28 +0000
    Subject: [PATCH 1957/2592] MFC r206395: Do not leak master pty or ptmx vnode.
    
    ---
     sys/kern/tty_pts.c | 9 +++++++++
     1 file changed, 9 insertions(+)
    
    diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
    index e1883d68082..363bdebade0 100644
    --- a/sys/kern/tty_pts.c
    +++ b/sys/kern/tty_pts.c
    @@ -589,6 +589,15 @@ ptsdev_close(struct file *fp, struct thread *td)
     	tty_lock(tp);
     	tty_rel_gone(tp);
     
    +	/*
    +	 * Open of /dev/ptmx or /dev/ptyXX changes the type of file
    +	 * from DTYPE_VNODE to DTYPE_PTS. vn_open() increases vnode
    +	 * use count, we need to decrement it, and possibly do other
    +	 * required cleanup.
    +	 */
    +	if (fp->f_vnode != NULL)
    +		return (vnops.fo_close(fp, td));
    +
     	return (0);
     }
     
    
    From eada7f55a885dec9dde9a15bebda88c3f56aa2ad Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Thu, 15 Apr 2010 08:20:57 +0000
    Subject: [PATCH 1958/2592] MFC r206397: Enhance r199804 by marking the
     daemonised child as immune to OOM instead of short-living parent. Only mark
     the master process that accepts connections, do not protect connection
     handlers spawned from inetd.
    
    ---
     crypto/openssh/sshd.c | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
    index 1d44fc8d9b9..3b955d944b7 100644
    --- a/crypto/openssh/sshd.c
    +++ b/crypto/openssh/sshd.c
    @@ -1293,10 +1293,6 @@ main(int ac, char **av)
     	/* Initialize configuration options to their default values. */
     	initialize_server_options(&options);
     
    -	/* Avoid killing the process in high-pressure swapping environments. */
    -	if (madvise(NULL, 0, MADV_PROTECT) != 0)
    -		debug("madvise(): %.200s", strerror(errno));
    -
     	/* Parse command-line arguments. */
     	while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) {
     		switch (opt) {
    @@ -1663,6 +1659,10 @@ main(int ac, char **av)
     	/* Reinitialize the log (because of the fork above). */
     	log_init(__progname, options.log_level, options.log_facility, log_stderr);
     
    +	/* Avoid killing the process in high-pressure swapping environments. */
    +	if (!inetd_flag && madvise(NULL, 0, MADV_PROTECT) != 0)
    +		debug("madvise(): %.200s", strerror(errno));
    +
     	/* Initialize the random number generator. */
     	arc4random_stir();
     
    
    From b1a034ef8e8d61872d0850342ebd0a4c05406a4d Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Thu, 15 Apr 2010 12:20:13 +0000
    Subject: [PATCH 1959/2592] MFC r205680: Use last 16 bytes of serial number in
     metadata instead of first ones, same as Intel MatrixRAID does.
    
    PR:             kern/124064
    ---
     sys/dev/ata/ata-raid.c | 18 ++++++++++++++++--
     1 file changed, 16 insertions(+), 2 deletions(-)
    
    diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c
    index a3b1e78a78b..98336786583 100644
    --- a/sys/dev/ata/ata-raid.c
    +++ b/sys/dev/ata/ata-raid.c
    @@ -2568,8 +2568,15 @@ ata_raid_intel_read_meta(device_t dev, struct ar_softc **raidp)
     	if (meta->generation >= raid->generation) {
     	    for (disk = 0; disk < raid->total_disks; disk++) {
     		struct ata_device *atadev = device_get_softc(parent);
    +		int len;
     
    -		if (!strncmp(raid->disks[disk].serial, atadev->param.serial,
    +		for (len = 0; len < sizeof(atadev->param.serial); len++) {
    +		    if (atadev->param.serial[len] < 0x20)
    +			break;
    +		}
    +		len = (len > sizeof(raid->disks[disk].serial)) ?
    +		    len - sizeof(raid->disks[disk].serial) : 0;
    +		if (!strncmp(raid->disks[disk].serial, atadev->param.serial + len,
     		    sizeof(raid->disks[disk].serial))) {
     		    raid->disks[disk].dev = parent;
     		    raid->disks[disk].flags |= (AR_DF_PRESENT | AR_DF_ONLINE);
    @@ -2639,8 +2646,15 @@ ata_raid_intel_write_meta(struct ar_softc *rdp)
     		device_get_softc(device_get_parent(rdp->disks[disk].dev));
     	    struct ata_device *atadev =
     		device_get_softc(rdp->disks[disk].dev);
    +	    int len;
     
    -	    bcopy(atadev->param.serial, meta->disk[disk].serial,
    +	    for (len = 0; len < sizeof(atadev->param.serial); len++) {
    +		if (atadev->param.serial[len] < 0x20)
    +		    break;
    +	    }
    +	    len = (len > sizeof(rdp->disks[disk].serial)) ?
    +	        len - sizeof(rdp->disks[disk].serial) : 0;
    +	    bcopy(atadev->param.serial + len, meta->disk[disk].serial,
     		  sizeof(rdp->disks[disk].serial));
     	    meta->disk[disk].sectors = rdp->disks[disk].sectors;
     	    meta->disk[disk].id = (ch->unit << 16) | atadev->unit;
    
    From fec9df653c5bc210fda24ee751881febe507e68e Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Thu, 15 Apr 2010 12:26:24 +0000
    Subject: [PATCH 1960/2592] MFC r205967: Include opt_ata.h, as some structures
     here depending on ATA_CAM option. This fixes ATA_CAM with atamvsata and
     probably some other drivers.
    
    ---
     sys/dev/ata/ata-all.h | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
    index 3d5d36e59f1..d7b3f4412d6 100644
    --- a/sys/dev/ata/ata-all.h
    +++ b/sys/dev/ata/ata-all.h
    @@ -26,6 +26,8 @@
      * $FreeBSD$
      */
     
    +#include "opt_ata.h"
    +
     #if 0
     #define	ATA_LEGACY_SUPPORT		/* Enable obsolete features that break
     					 * some modern devices */
    
    From 48e700702f51bcd6597818dce66cf263798e8764 Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Thu, 15 Apr 2010 12:30:46 +0000
    Subject: [PATCH 1961/2592] MFC r206053, r206054: Fill extended ATA command
     registers in cPRD to support 48bit commands.
    
    ---
     sys/arm/mv/mv_sata.c | 5 +++++
     1 file changed, 5 insertions(+)
    
    diff --git a/sys/arm/mv/mv_sata.c b/sys/arm/mv/mv_sata.c
    index 01713daa27c..a6072983735 100644
    --- a/sys/arm/mv/mv_sata.c
    +++ b/sys/arm/mv/mv_sata.c
    @@ -600,7 +600,12 @@ sata_channel_begin_transaction(struct ata_request *request)
     	crqb->crqb_ata_lba_mid = request->u.ata.lba >> 8;
     	crqb->crqb_ata_lba_high = request->u.ata.lba >> 16;
     	crqb->crqb_ata_device = ((request->u.ata.lba >> 24) & 0x0F) | (1 << 6);
    +	crqb->crqb_ata_lba_low_p = request->u.ata.lba >> 24;
    +	crqb->crqb_ata_lba_mid_p = request->u.ata.lba >> 32;
    +	crqb->crqb_ata_lba_high_p = request->u.ata.lba >> 40;
    +	crqb->crqb_ata_feature_p = request->u.ata.feature >> 8;
     	crqb->crqb_ata_count = request->u.ata.count;
    +	crqb->crqb_ata_count_p = request->u.ata.count >> 8;
     
     	bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
     	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    
    From f1725d1c1cae9253b4ad683521d16695a619491b Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Thu, 15 Apr 2010 12:38:55 +0000
    Subject: [PATCH 1962/2592] NFC r206000: Make ng_ppp fulfill upper protocol
     stack layers alignment requirements on platforms with strict alignment
     constraints. This fixes kernel panics on arm and probably other
     architectures.
    
    PR:             sparc64/80410, sparc/118932, sparc/113556
    ---
     sys/netgraph/ng_ppp.c | 14 ++++++++++++++
     1 file changed, 14 insertions(+)
    
    diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c
    index b2b0cb0a446..ec3ed82ea7f 100644
    --- a/sys/netgraph/ng_ppp.c
    +++ b/sys/netgraph/ng_ppp.c
    @@ -907,7 +907,21 @@ ng_ppp_proto_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
     	const priv_p priv = NG_NODE_PRIVATE(node);
     	hook_p outHook = NULL;
     	int error;
    +#ifdef ALIGNED_POINTER
    +	struct mbuf *m, *n;
     
    +	NGI_GET_M(item, m);
    +	if (!ALIGNED_POINTER(mtod(m, caddr_t), uint32_t)) {
    +		n = m_defrag(m, M_NOWAIT);
    +		if (n == NULL) {
    +			m_freem(m);
    +			NG_FREE_ITEM(item);
    +			return (ENOBUFS);
    +		}
    +		m = n;
    +	}
    +	NGI_M(item) = m;
    +#endif /* ALIGNED_POINTER */
     	switch (proto) {
     	    case PROT_IP:
     		if (priv->conf.enableIP)
    
    From b7261229f9fc2f7b46d98db7d334f6c46ad20be6 Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Thu, 15 Apr 2010 12:40:02 +0000
    Subject: [PATCH 1963/2592] MFC r206015: Make ng_l2tp irrelevant to data
     alignment.
    
    ---
     sys/netgraph/ng_l2tp.c | 46 ++++++++++++++++++++++++++++--------------
     1 file changed, 31 insertions(+), 15 deletions(-)
    
    diff --git a/sys/netgraph/ng_l2tp.c b/sys/netgraph/ng_l2tp.c
    index a5bb6280abf..ce15bc1e12e 100644
    --- a/sys/netgraph/ng_l2tp.c
    +++ b/sys/netgraph/ng_l2tp.c
    @@ -790,7 +790,7 @@ ng_l2tp_rcvdata_lower(hook_p h, item_p item)
     		NG_FREE_ITEM(item);
     		ERROUT(EINVAL);
     	}
    -	hdr = ntohs(*mtod(m, u_int16_t *));
    +	hdr = (mtod(m, uint8_t *)[0] << 8) + mtod(m, uint8_t *)[1];
     	m_adj(m, 2);
     
     	/* Check required header bits and minimum length */
    @@ -819,7 +819,7 @@ ng_l2tp_rcvdata_lower(hook_p h, item_p item)
     			NG_FREE_ITEM(item);
     			ERROUT(EINVAL);
     		}
    -		len = (u_int16_t)ntohs(*mtod(m, u_int16_t *)) - 4;
    +		len = (mtod(m, uint8_t *)[0] << 8) + mtod(m, uint8_t *)[1] - 4;
     		m_adj(m, 2);
     		if (len < 0 || len > m->m_pkthdr.len) {
     			priv->stats.recvInvalid++;
    @@ -1095,9 +1095,10 @@ ng_l2tp_rcvdata(hook_p hook, item_p item)
     	const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
     	const hookpriv_p hpriv = NG_HOOK_PRIVATE(hook);
     	struct mbuf *m;
    +	uint8_t *p;
     	u_int16_t hdr;
     	int error;
    -	int i = 1;
    +	int i = 2;
     
     	/* Sanity check */
     	L2TP_SEQ_CHECK(&priv->seq);
    @@ -1129,20 +1130,27 @@ ng_l2tp_rcvdata(hook_p hook, item_p item)
     		NG_FREE_ITEM(item);
     		ERROUT(ENOBUFS);
     	}
    +	p = mtod(m, uint8_t *);
     	hdr = L2TP_DATA_HDR;
     	if (hpriv->conf.include_length) {
     		hdr |= L2TP_HDR_LEN;
    -		mtod(m, u_int16_t *)[i++] = htons(m->m_pkthdr.len);
    +		p[i++] = m->m_pkthdr.len >> 8;
    +		p[i++] = m->m_pkthdr.len & 0xff;
     	}
    -	mtod(m, u_int16_t *)[i++] = htons(priv->conf.peer_id);
    -	mtod(m, u_int16_t *)[i++] = htons(hpriv->conf.peer_id);
    +	p[i++] = priv->conf.peer_id >> 8;
    +	p[i++] = priv->conf.peer_id & 0xff;
    +	p[i++] = hpriv->conf.peer_id >> 8;
    +	p[i++] = hpriv->conf.peer_id & 0xff;
     	if (hpriv->conf.enable_dseq) {
     		hdr |= L2TP_HDR_SEQ;
    -		mtod(m, u_int16_t *)[i++] = htons(hpriv->ns);
    -		mtod(m, u_int16_t *)[i++] = htons(hpriv->nr);
    +		p[i++] = hpriv->ns >> 8;
    +		p[i++] = hpriv->ns & 0xff;
    +		p[i++] = hpriv->nr >> 8;
    +		p[i++] = hpriv->nr & 0xff;
     		hpriv->ns++;
     	}
    -	mtod(m, u_int16_t *)[0] = htons(hdr);
    +	p[0] = hdr >> 8;
    +	p[1] = hdr & 0xff;
     
     	/* Update per session stats. */
     	hpriv->stats.xmitPackets++;
    @@ -1496,6 +1504,7 @@ static int
     ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns)
     {
     	struct l2tp_seq *const seq = &priv->seq;
    +	uint8_t *p;
     	u_int16_t session_id = 0;
     	int error;
     
    @@ -1540,12 +1549,19 @@ ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns)
     	}
     
     	/* Fill in L2TP header */
    -	mtod(m, u_int16_t *)[0] = htons(L2TP_CTRL_HDR);
    -	mtod(m, u_int16_t *)[1] = htons(m->m_pkthdr.len);
    -	mtod(m, u_int16_t *)[2] = htons(priv->conf.peer_id);
    -	mtod(m, u_int16_t *)[3] = htons(session_id);
    -	mtod(m, u_int16_t *)[4] = htons(ns);
    -	mtod(m, u_int16_t *)[5] = htons(seq->nr);
    +	p = mtod(m, u_int8_t *);
    +	p[0] = L2TP_CTRL_HDR >> 8;
    +	p[1] = L2TP_CTRL_HDR & 0xff;
    +	p[2] = m->m_pkthdr.len >> 8;
    +	p[3] = m->m_pkthdr.len & 0xff;
    +	p[4] = priv->conf.peer_id >> 8;
    +	p[5] = priv->conf.peer_id & 0xff;
    +	p[6] = session_id >> 8;
    +	p[7] = session_id & 0xff;
    +	p[8] = ns >> 8;
    +	p[9] = ns & 0xff;
    +	p[10] = seq->nr >> 8;
    +	p[11] = seq->nr & 0xff;
     
     	/* Update sequence number info and stats */
     	priv->stats.xmitPackets++;
    
    From a35d181273abcd97d3b2544f08e726404738a730 Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Thu, 15 Apr 2010 12:41:36 +0000
    Subject: [PATCH 1964/2592] MFC r206017: Make ng_ksocket fulfill lower protocol
     stack layers alignment requirements on platforms with strict alignment
     constraints. This fixes kernel panics on arm and probably other
     architectures.
    
    PR:             sparc64/80410, sparc/118932, sparc/113556
    ---
     sys/netgraph/ng_ksocket.c | 14 +++++++++++++-
     1 file changed, 13 insertions(+), 1 deletion(-)
    
    diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
    index d1571b14fbf..260eba90d7e 100644
    --- a/sys/netgraph/ng_ksocket.c
    +++ b/sys/netgraph/ng_ksocket.c
    @@ -902,12 +902,24 @@ ng_ksocket_rcvdata(hook_p hook, item_p item)
     	struct sockaddr *sa = NULL;
     	int error;
     	struct mbuf *m;
    +#ifdef ALIGNED_POINTER
    +	struct mbuf *n;
    +#endif /* ALIGNED_POINTER */
     	struct sa_tag *stag;
     
     	/* Extract data */
     	NGI_GET_M(item, m);
     	NG_FREE_ITEM(item);
    -
    +#ifdef ALIGNED_POINTER
    +	if (!ALIGNED_POINTER(mtod(m, caddr_t), uint32_t)) {
    +		n = m_defrag(m, M_NOWAIT);
    +		if (n == NULL) {
    +			m_freem(m);
    +			return (ENOBUFS);
    +		}
    +		m = n;
    +	}
    +#endif /* ALIGNED_POINTER */
     	/*
     	 * Look if socket address is stored in packet tags.
     	 * If sockaddr is ours, or provided by a third party (zero id),
    
    From d9b0781af8f3b5d61c4675dc2a0d94e6c1d5a5de Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Thu, 15 Apr 2010 12:46:16 +0000
    Subject: [PATCH 1965/2592] MFC r206021, r206032, r206049, r206050: Remove some
     more alignment constraints.
    
    ---
     sys/netgraph/ng_deflate.c |  9 +++++----
     sys/netgraph/ng_mppc.c    |  6 +++---
     sys/netgraph/ng_ppp.c     |  9 +++++----
     sys/netgraph/ng_pptpgre.c | 22 +++++++++++-----------
     sys/netgraph/ng_tcpmss.c  | 19 +++++++++++--------
     5 files changed, 35 insertions(+), 30 deletions(-)
    
    diff --git a/sys/netgraph/ng_deflate.c b/sys/netgraph/ng_deflate.c
    index b248a83cc22..f3ce1c0444d 100644
    --- a/sys/netgraph/ng_deflate.c
    +++ b/sys/netgraph/ng_deflate.c
    @@ -36,6 +36,7 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     
    @@ -505,8 +506,8 @@ ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
     		priv->stats.OutOctets+=inlen;
     	} else {
     		/* Install header. */
    -		((u_int16_t *)priv->outbuf)[0] = htons(PROT_COMPD);
    -		((u_int16_t *)priv->outbuf)[1] = htons(priv->seqnum);
    +		be16enc(priv->outbuf, PROT_COMPD);
    +		be16enc(priv->outbuf + 2, priv->seqnum);
     
     		/* Return packet in an mbuf. */
     		m_copyback(m, 0, outlen, (caddr_t)priv->outbuf);
    @@ -568,7 +569,7 @@ ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
     		proto = priv->inbuf[0];
     		offset = 1;
     	} else {
    -		proto = ntohs(((uint16_t *)priv->inbuf)[0]);
    +		proto = be16dec(priv->inbuf);
     		offset = 2;
     	}
     
    @@ -579,7 +580,7 @@ ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
     		priv->stats.FramesComp++;
     
     		/* Check sequence number. */
    -		rseqnum = ntohs(((uint16_t *)(priv->inbuf + offset))[0]);
    +		rseqnum = be16dec(priv->inbuf + offset);
     		offset += 2;
     		if (rseqnum != priv->seqnum) {
     			priv->stats.Errors++;
    diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c
    index e93448137c8..074c018bc97 100644
    --- a/sys/netgraph/ng_mppc.c
    +++ b/sys/netgraph/ng_mppc.c
    @@ -53,6 +53,7 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     
    @@ -601,7 +602,7 @@ err1:
     	/* Install header */
     	M_PREPEND(m, MPPC_HDRLEN, M_DONTWAIT);
     	if (m != NULL)
    -		*(mtod(m, uint16_t *)) = htons(header);
    +		be16enc(mtod(m, void *), header);
     
     	*datap = m;
     	return (*datap == NULL ? ENOBUFS : 0);
    @@ -630,8 +631,7 @@ ng_mppc_decompress(node_p node, struct mbuf **datap)
     		m_freem(m);
     		return (EINVAL);
     	}
    -	m_copydata(m, 0, MPPC_HDRLEN, (caddr_t)&header);
    -	header = ntohs(header);
    +	header = be16dec(mtod(m, void *));
     	cc = (header & MPPC_CCOUNT_MASK);
     	m_adj(m, MPPC_HDRLEN);
     
    diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c
    index ec3ed82ea7f..e5897f32f7a 100644
    --- a/sys/netgraph/ng_ppp.c
    +++ b/sys/netgraph/ng_ppp.c
    @@ -97,6 +97,7 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     
    @@ -860,8 +861,8 @@ ng_ppp_rcvdata_bypass(hook_p hook, item_p item)
     		NG_FREE_ITEM(item);
     		return (ENOBUFS);
     	}
    -	linkNum = ntohs(mtod(m, uint16_t *)[0]);
    -	proto = ntohs(mtod(m, uint16_t *)[1]);
    +	linkNum = be16dec(mtod(m, uint8_t *));
    +	proto = be16dec(mtod(m, uint8_t *) + 2);
     	m_adj(m, 4);
     	NGI_M(item) = m;
     
    @@ -1544,7 +1545,7 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
     		if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL)
     			ERROUT(ENOBUFS);
     
    -		shdr = ntohs(*mtod(m, uint16_t *));
    +		shdr = be16dec(mtod(m, void *));
     		frag->seq = MP_SHORT_EXTEND(shdr);
     		frag->first = (shdr & MP_SHORT_FIRST_FLAG) != 0;
     		frag->last = (shdr & MP_SHORT_LAST_FLAG) != 0;
    @@ -1561,7 +1562,7 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
     		if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL)
     			ERROUT(ENOBUFS);
     
    -		lhdr = ntohl(*mtod(m, uint32_t *));
    +		lhdr = be32dec(mtod(m, void *));
     		frag->seq = MP_LONG_EXTEND(lhdr);
     		frag->first = (lhdr & MP_LONG_FIRST_FLAG) != 0;
     		frag->last = (lhdr & MP_LONG_LAST_FLAG) != 0;
    diff --git a/sys/netgraph/ng_pptpgre.c b/sys/netgraph/ng_pptpgre.c
    index 5c5d1280064..606d278eca9 100644
    --- a/sys/netgraph/ng_pptpgre.c
    +++ b/sys/netgraph/ng_pptpgre.c
    @@ -62,6 +62,7 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
     
     #include 
    @@ -572,9 +573,9 @@ ng_pptpgre_xmit(hpriv_p hpriv, item_p item)
     	}
     
     	/* Build GRE header */
    -	((u_int32_t *)gre)[0] = htonl(PPTP_INIT_VALUE);
    -	gre->length = (m != NULL) ? htons((u_short)m->m_pkthdr.len) : 0;
    -	gre->cid = htons(hpriv->conf.peerCid);
    +	be32enc(gre, PPTP_INIT_VALUE);
    +	be16enc(&gre->length, (m != NULL) ? m->m_pkthdr.len : 0);
    +	be16enc(&gre->cid, hpriv->conf.peerCid);
     
     	/* Include sequence number if packet contains any data */
     	if (m != NULL) {
    @@ -584,13 +585,13 @@ ng_pptpgre_xmit(hpriv_p hpriv, item_p item)
     			    = ng_pptpgre_time();
     		}
     		hpriv->xmitSeq++;
    -		gre->data[0] = htonl(hpriv->xmitSeq);
    +		be32enc(&gre->data[0], hpriv->xmitSeq);
     	}
     
     	/* Include acknowledgement (and stop send ack timer) if needed */
     	if (hpriv->conf.enableAlwaysAck || hpriv->xmitAck != hpriv->recvSeq) {
     		gre->hasAck = 1;
    -		gre->data[gre->hasSeq] = htonl(hpriv->recvSeq);
    +		be32enc(&gre->data[gre->hasSeq], hpriv->recvSeq);
     		hpriv->xmitAck = hpriv->recvSeq;
     		if (hpriv->conf.enableDelayedAck)
     			ng_uncallout(&hpriv->sackTimer, hpriv->node);
    @@ -705,18 +706,17 @@ ng_pptpgre_rcvdata_lower(hook_p hook, item_p item)
     
     	/* Sanity check packet length and GRE header bits */
     	extralen = m->m_pkthdr.len
    -	    - (iphlen + grelen + gre->hasSeq * (u_int16_t)ntohs(gre->length));
    +	    - (iphlen + grelen + gre->hasSeq * be16dec(&gre->length));
     	if (extralen < 0) {
     		priv->stats.recvBadGRE++;
     		ERROUT(EINVAL);
     	}
    -	if ((ntohl(*((const u_int32_t *)gre)) & PPTP_INIT_MASK)
    -	    != PPTP_INIT_VALUE) {
    +	if ((be32dec(gre) & PPTP_INIT_MASK) != PPTP_INIT_VALUE) {
     		priv->stats.recvBadGRE++;
     		ERROUT(EINVAL);
     	}
     
    -	hpriv = ng_pptpgre_find_session(priv, ntohs(gre->cid));
    +	hpriv = ng_pptpgre_find_session(priv, be16dec(&gre->cid));
     	if (hpriv == NULL || hpriv->hook == NULL || !hpriv->conf.enabled) {
     		priv->stats.recvBadCID++;
     		ERROUT(EINVAL);
    @@ -725,7 +725,7 @@ ng_pptpgre_rcvdata_lower(hook_p hook, item_p item)
     
     	/* Look for peer ack */
     	if (gre->hasAck) {
    -		const u_int32_t	ack = ntohl(gre->data[gre->hasSeq]);
    +		const u_int32_t	ack = be32dec(&gre->data[gre->hasSeq]);
     		const int index = ack - hpriv->recvAck - 1;
     		long sample;
     		long diff;
    @@ -776,7 +776,7 @@ badAck:
     
     	/* See if frame contains any data */
     	if (gre->hasSeq) {
    -		const u_int32_t seq = ntohl(gre->data[0]);
    +		const u_int32_t seq = be32dec(&gre->data[0]);
     
     		/* Sanity check sequence number */
     		if (PPTP_SEQ_DIFF(seq, hpriv->recvSeq) <= 0) {
    diff --git a/sys/netgraph/ng_tcpmss.c b/sys/netgraph/ng_tcpmss.c
    index bcc421a9e08..19f9edc74c1 100644
    --- a/sys/netgraph/ng_tcpmss.c
    +++ b/sys/netgraph/ng_tcpmss.c
    @@ -47,6 +47,7 @@
     
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -410,9 +411,9 @@ correct_mss(struct tcphdr *tc, int hlen, uint16_t maxmss, int flags)
     {
     	int olen, optlen;
     	u_char *opt;
    -	uint16_t *mss;
     	int accumulate;
     	int res = 0;
    +	uint16_t sum;
     
     	for (olen = hlen - sizeof(struct tcphdr), opt = (u_char *)(tc + 1);
     	     olen > 0; olen -= optlen, opt += optlen) {
    @@ -427,13 +428,15 @@ correct_mss(struct tcphdr *tc, int hlen, uint16_t maxmss, int flags)
     			if (*opt == TCPOPT_MAXSEG) {
     				if (optlen != TCPOLEN_MAXSEG)
     					continue;
    -				mss = (uint16_t *)(opt + 2);
    -				if (ntohs(*mss) > maxmss) {
    -					accumulate = *mss;
    -					*mss = htons(maxmss);
    -					accumulate -= *mss;
    -					if ((flags & CSUM_TCP) == 0)
    -						TCPMSS_ADJUST_CHECKSUM(accumulate, tc->th_sum);
    +				accumulate = be16dec(opt + 2);
    +				if (accumulate > maxmss) {
    +					if ((flags & CSUM_TCP) == 0) {
    +						accumulate -= maxmss;
    +						sum = be16dec(&tc->th_sum);
    +						TCPMSS_ADJUST_CHECKSUM(accumulate, sum);
    +						be16enc(&tc->th_sum, sum);
    +					}
    +					be16enc(opt + 2, maxmss);
     					res = 1;
     				}
     			}
    
    From 679953c6bd985ea6790adbd4e4c287f2ff0e4a09 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 15 Apr 2010 19:19:59 +0000
    Subject: [PATCH 1966/2592] MFC r205299:   - Added support for 5709S/5716S
     PHYs.
    
      Submitted by: pyunyh
      PR:	kern/134658, kern/136417, kern/139761, kern/140970
    ---
     sys/dev/mii/brgphy.c    | 125 ++++++++++++++++++++++++++++++++--------
     sys/dev/mii/brgphyreg.h |  55 ++++++++++++++++++
     sys/dev/mii/miidevs     |   1 +
     3 files changed, 158 insertions(+), 23 deletions(-)
    
    diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
    index ce73d8c9e5b..97a423cd27e 100644
    --- a/sys/dev/mii/brgphy.c
    +++ b/sys/dev/mii/brgphy.c
    @@ -75,6 +75,7 @@ struct brgphy_softc {
     #define BRGPHY_5706S		0x0001
     #define BRGPHY_5708S		0x0002
     #define BRGPHY_NOANWAIT		0x0004
    +#define BRGPHY_5709S		0x0008
     	int bce_phy_flags;	/* PHY flags transferred from the MAC driver */
     };
     
    @@ -139,6 +140,7 @@ static const struct mii_phydesc brgphys[] = {
     	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5784),
     	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
     	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5761),
    +    MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709S),
     	MII_PHY_DESC(BROADCOM2, BCM5906),
     	MII_PHY_END
     };
    @@ -216,30 +218,34 @@ brgphy_attach(device_t dev)
     		break;
     	case MII_OUI_xxBROADCOM:
     		switch (bsc->mii_model) {
    -			case MII_MODEL_xxBROADCOM_BCM5706:
    -			case MII_MODEL_xxBROADCOM_BCM5714:
    -				/*
    -				 * The 5464 PHY used in the 5706 supports both copper
    -				 * and fiber interfaces over GMII.  Need to check the
    -				 * shadow registers to see which mode is actually
    -				 * in effect, and therefore whether we have 5706C or
    -				 * 5706S.
    -				 */
    -				PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C,
    -					BRGPHY_SHADOW_1C_MODE_CTRL);
    -				if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) &
    -					BRGPHY_SHADOW_1C_ENA_1000X) {
    -					bsc->serdes_flags |= BRGPHY_5706S;
    -					sc->mii_flags |= MIIF_HAVEFIBER;
    -				}
    -				break;
    +		case MII_MODEL_xxBROADCOM_BCM5706:
    +		case MII_MODEL_xxBROADCOM_BCM5714:
    +			/*
    +			 * The 5464 PHY used in the 5706 supports both copper
    +			 * and fiber interfaces over GMII.  Need to check the
    +			 * shadow registers to see which mode is actually
    +			 * in effect, and therefore whether we have 5706C or
    +			 * 5706S.
    +			 */
    +			PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C,
    +				BRGPHY_SHADOW_1C_MODE_CTRL);
    +			if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) &
    +				BRGPHY_SHADOW_1C_ENA_1000X) {
    +				bsc->serdes_flags |= BRGPHY_5706S;
    +				sc->mii_flags |= MIIF_HAVEFIBER;
    +			}
    +			break;
     		} break;
     	case MII_OUI_xxBROADCOM_ALT1:
     		switch (bsc->mii_model) {
    -			case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
    -				bsc->serdes_flags |= BRGPHY_5708S;
    -				sc->mii_flags |= MIIF_HAVEFIBER;
    -				break;
    +		case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
    +			bsc->serdes_flags |= BRGPHY_5708S;
    +			sc->mii_flags |= MIIF_HAVEFIBER;
    +			break;
    +        case MII_MODEL_xxBROADCOM_ALT1_BCM5709S:
    +            bsc->serdes_flags |= BRGPHY_5709S;
    +            sc->mii_flags |= MIIF_HAVEFIBER;
    +            break;
     		} break;
     	default:
     		device_printf(dev, "Unrecognized OUI for PHY!\n");
    @@ -631,6 +637,7 @@ brgphy_status(struct mii_softc *sc)
     			PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0);
     			xstat = PHY_READ(sc, BRGPHY_5708S_PG0_1000X_STAT1);
     
    +            /* Check for MRBE auto-negotiated speed results. */
     			switch (xstat & BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK) {
     			case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10:
     				mii->mii_media_active |= IFM_10_FL; break;
    @@ -642,11 +649,40 @@ brgphy_status(struct mii_softc *sc)
     				mii->mii_media_active |= IFM_2500_SX; break;
     			}
     
    +            /* Check for MRBE auto-negotiated duplex results. */
     			if (xstat & BRGPHY_5708S_PG0_1000X_STAT1_FDX)
     				mii->mii_media_active |= IFM_FDX;
     			else
     				mii->mii_media_active |= IFM_HDX;
    -		}
    +
    +        } else if (bsc->serdes_flags & BRGPHY_5709S) {
    +
    +            /* Select GP Status Block of the AN MMD, get autoneg results. */
    +            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_GP_STATUS);
    +			xstat = PHY_READ(sc, BRGPHY_GP_STATUS_TOP_ANEG_STATUS);
    +
    +            /* Restore IEEE0 block (assumed in all brgphy(4) code). */
    +            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
    +
    +            /* Check for MRBE auto-negotiated speed results. */
    +            switch (xstat & BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK) {
    +			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10:
    +				mii->mii_media_active |= IFM_10_FL; break;
    +			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100:
    +				mii->mii_media_active |= IFM_100_FX; break;
    +			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G:
    +				mii->mii_media_active |= IFM_1000_SX; break;
    +			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G:
    +				mii->mii_media_active |= IFM_2500_SX; break;
    +			}
    +
    +            /* Check for MRBE auto-negotiated duplex results. */
    +			if (xstat & BRGPHY_GP_STATUS_TOP_ANEG_FDX)
    +				mii->mii_media_active |= IFM_FDX;
    +			else
    +				mii->mii_media_active |= IFM_HDX;
    +        }
    +
     	}
     
     #if 0
    @@ -967,6 +1003,7 @@ brgphy_reset(struct mii_softc *sc)
     	struct bge_softc *bge_sc = NULL;
     	struct bce_softc *bce_sc = NULL;
     	struct ifnet *ifp;
    +    int val;
     
     	/* Perform a standard PHY reset. */
     	mii_phy_reset(sc);
    @@ -1089,7 +1126,49 @@ brgphy_reset(struct mii_softc *sc)
     					PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
     						BRGPHY_5708S_DIG_PG0);
     			}
    -		} else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) {
    +		} else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709 &&
    +			(bce_sc->bce_phy_flags & BCE_PHY_SERDES_FLAG)) {
    +
    +            /* Select the SerDes Digital block of the AN MMD. */
    +            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_SERDES_DIG);
    +			val = PHY_READ(sc, BRGPHY_SERDES_DIG_1000X_CTL1);
    +			val &= ~BRGPHY_SD_DIG_1000X_CTL1_AUTODET;
    +			val |= BRGPHY_SD_DIG_1000X_CTL1_FIBER;
    +			PHY_WRITE(sc, BRGPHY_SERDES_DIG_1000X_CTL1, val);
    +
    +            /* Select the Over 1G block of the AN MMD. */
    +			PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_OVER_1G);
    +
    +            /* Enable autoneg "Next Page" to advertise 2.5G support. */
    +            val = PHY_READ(sc, BRGPHY_OVER_1G_UNFORMAT_PG1);
    +			if (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
    +				val |= BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G;
    +			else
    +				val &= ~BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G;
    +			PHY_WRITE(sc, BRGPHY_OVER_1G_UNFORMAT_PG1, val);
    +
    +            /* Select the Multi-Rate Backplane Ethernet block of the AN MMD. */
    +			PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_MRBE);
    +
    +            /* Enable MRBE speed autoneg. */
    +            val = PHY_READ(sc, BRGPHY_MRBE_MSG_PG5_NP);
    +			val |= BRGPHY_MRBE_MSG_PG5_NP_MBRE |
    +			    BRGPHY_MRBE_MSG_PG5_NP_T2;
    +			PHY_WRITE(sc, BRGPHY_MRBE_MSG_PG5_NP, val);
    +
    +            /* Select the Clause 73 User B0 block of the AN MMD. */
    +            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_CL73_USER_B0);
    +
    +            /* Enable MRBE speed autoneg. */
    +			PHY_WRITE(sc, BRGPHY_CL73_USER_B0_MBRE_CTL1,
    +			    BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP |
    +			    BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR |
    +			    BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG);
    +
    +            /* Restore IEEE0 block (assumed in all brgphy(4) code). */
    +            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
    +
    +        } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) {
     			if ((BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Ax) ||
     				(BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Bx))
     				brgphy_fixup_disable_early_dac(sc);
    diff --git a/sys/dev/mii/brgphyreg.h b/sys/dev/mii/brgphyreg.h
    index 643655f4bea..883269e2f66 100644
    --- a/sys/dev/mii/brgphyreg.h
    +++ b/sys/dev/mii/brgphyreg.h
    @@ -359,6 +359,61 @@
     /* End: PHY register values for the 5708S SerDes PHY   */
     /*******************************************************/
     
    +/*******************************************************/
    +/* Begin: PHY register values for the 5709S SerDes PHY */
    +/*******************************************************/
    +
    +/* 5709S SerDes "General Purpose Status" Registers */
    +#define BRGPHY_BLOCK_ADDR_GP_STATUS		        0x8120
    +#define BRGPHY_GP_STATUS_TOP_ANEG_STATUS	    0x1B
    +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK	0x3F00
    +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10	    0x0000
    +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100	    0x0100
    +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G	    0x0200
    +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G	    0x0300
    +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1GKX	0x0D00
    +#define BRGPHY_GP_STATUS_TOP_ANEG_FDX		    0x0008
    +#define BRGPHY_GP_STATUS_TOP_ANEG_LINK_UP	    0x0004
    +#define BRGPHY_GP_STATUS_TOP_ANEG_CL73_COMP	    0x0001
    +
    +/* 5709S SerDes "SerDes Digital" Registers */
    +#define BRGPHY_BLOCK_ADDR_SERDES_DIG		    0x8300
    +#define	BRGPHY_SERDES_DIG_1000X_CTL1		    0x0010
    +#define	BRGPHY_SD_DIG_1000X_CTL1_AUTODET	    0x0010
    +#define	BRGPHY_SD_DIG_1000X_CTL1_FIBER		    0x0001
    +
    +/* 5709S SerDes "Over 1G" Registers */
    +#define BRGPHY_BLOCK_ADDR_OVER_1G		        0x8320
    +#define BRGPHY_OVER_1G_UNFORMAT_PG1		        0x19
    +
    +/* 5709S SerDes "Multi-Rate Backplane Ethernet" Registers */
    +#define BRGPHY_BLOCK_ADDR_MRBE			        0x8350
    +#define BRGPHY_MRBE_MSG_PG5_NP			        0x10
    +#define BRGPHY_MRBE_MSG_PG5_NP_MBRE		        0x0001
    +#define BRGPHY_MRBE_MSG_PG5_NP_T2		        0x0001
    +
    +/* 5709S SerDes "IEEE Clause 73 User B0" Registers */
    +#define BRGPHY_BLOCK_ADDR_CL73_USER_B0		    0x8370
    +#define BRGPHY_CL73_USER_B0_MBRE_CTL1		    0x12
    +#define	BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP	0x2000
    +#define	BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR	0x4000
    +#define	BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG	    0x8000
    +
    +/* 5709S SerDes "IEEE Clause 73 User B0" Registers */
    +#define BRGPHY_BLOCK_ADDR_ADDR_EXT		        0xFFD0
    +
    +/* 5709S SerDes "Combo IEEE 0" Registers */
    +#define BRGPHY_BLOCK_ADDR_COMBO_IEEE0		    0xFFE0
    +
    +#define BRGPHY_ADDR_EXT				            0x1E
    +#define BRGPHY_BLOCK_ADDR			            0x1F
    +
    +#define BRGPHY_ADDR_EXT_AN_MMD			        0x3800
    +
    +/*******************************************************/
    +/* End: PHY register values for the 5709S SerDes PHY   */
    +/*******************************************************/
    +
     #define	BRGPHY_INTRS	\
     	~(BRGPHY_IMR_LNK_CHG|BRGPHY_IMR_LSP_CHG|BRGPHY_IMR_DUP_CHG)
     
    diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
    index 06e07be53ea..f3ef20dae35 100644
    --- a/sys/dev/mii/miidevs
    +++ b/sys/dev/mii/miidevs
    @@ -157,6 +157,7 @@ model xxBROADCOM_ALT1 BCM5722	0x002d BCM5722 10/100/1000baseTX PHY
     model xxBROADCOM_ALT1 BCM5784	0x003a BCM5784 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 xxBROADCOM_ALT1 BCM5709S	0x003f BCM5709S 1000/2500baseSX PHY
     model BROADCOM2 BCM5906		0x0004 BCM5906 10/100baseTX PHY
     
     /* Cicada Semiconductor PHYs (now owned by Vitesse?) */
    
    From 9c89e9777034100f37afe3e36021e6fd01f13506 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 15 Apr 2010 19:26:28 +0000
    Subject: [PATCH 1967/2592] MFC r205300:   - Added support for 5709S/5716S
     PHYs.   - Update copyright to 2010.   - Add new debug code for RV2P block.  
     - Improve output formatting for various debug functions.
    
      PR:	kern/134658, kern/136417, kern/139761, kern/140970
    ---
     sys/dev/bce/if_bce.c    | 652 +++++++++++++++++-----------------------
     sys/dev/bce/if_bcefw.h  |   2 +-
     sys/dev/bce/if_bcereg.h |  17 +-
     3 files changed, 285 insertions(+), 386 deletions(-)
    
    diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
    index 8b6f2226a1f..61f3af565af 100644
    --- a/sys/dev/bce/if_bce.c
    +++ b/sys/dev/bce/if_bce.c
    @@ -1,5 +1,5 @@
     /*-
    - * Copyright (c) 2006-2009 Broadcom Corporation
    + * Copyright (c) 2006-2010 Broadcom Corporation
      *	David Christensen .  All rights reserved.
      *
      * Redistribution and use in source and binary forms, with or without
    @@ -38,7 +38,9 @@ __FBSDID("$FreeBSD$");
      *   BCM5708C B1, B2
      *   BCM5708S B1, B2
      *   BCM5709C A1, C0
    + *   BCM5709S A1, C0
      * 	 BCM5716C C0
    + * 	 BCM5716S C0
      *
      * The following controllers are not supported by this driver:
      *   BCM5706C A0, A1 (pre-production)
    @@ -46,7 +48,7 @@ __FBSDID("$FreeBSD$");
      *   BCM5708C A0, B0 (pre-production)
      *   BCM5708S A0, B0 (pre-production)
      *   BCM5709C A0  B0, B1, B2 (pre-production)
    - *   BCM5709S A0, A1, B0, B1, B2, C0 (pre-production)
    + *   BCM5709S A0, B0, B1, B2 (pre-production)
      */
     
     #include "opt_bce.h"
    @@ -320,6 +322,7 @@ static void bce_dump_rxp_state		(struct bce_softc *, int);
     static void bce_dump_tpat_state		(struct bce_softc *, int);
     static void bce_dump_cp_state		(struct bce_softc *, int);
     static void bce_dump_com_state		(struct bce_softc *, int);
    +static void bce_dump_rv2p_state		(struct bce_softc *);
     static void bce_breakpoint			(struct bce_softc *);
     #endif
     
    @@ -360,6 +363,7 @@ static int  bce_nvram_write			(struct bce_softc *, u32, u8 *, int);
     /*                                                                          */
     /****************************************************************************/
     static void bce_get_media			(struct bce_softc *);
    +static void bce_init_media			(struct bce_softc *);
     static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
     static int  bce_dma_alloc			(device_t);
     static void bce_dma_free			(struct bce_softc *);
    @@ -1096,7 +1100,10 @@ bce_attach(device_t dev)
     	else
     		ifp->if_baudrate = IF_Mbps(1000);
     
    -	/* Check for an MII child bus by probing the PHY. */
    +    /* Handle any special PHY initialization for SerDes PHYs. */
    +    bce_init_media(sc);
    +
    +	/* MII child bus by probing the PHY. */
     	if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
     		bce_ifmedia_sts)) {
     		BCE_PRINTF("%s(%d): No PHY found on child MII bus!\n",
    @@ -1504,7 +1511,17 @@ bce_miibus_read_reg(device_t dev, int phy, int reg)
     		return(0);
     	}
     
    -	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
    +    /*
    +     * The 5709S PHY is an IEEE Clause 45 PHY
    +     * with special mappings to work with IEEE
    +     * Clause 22 register accesses.
    +     */
    +	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
    +		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
    +			reg += 0x10;
    +	}
    +
    +    if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
     		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
     		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
     
    @@ -1584,6 +1601,16 @@ bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
     
     	DB_PRINT_PHY_REG(reg, val);
     
    +    /*
    +     * The 5709S PHY is an IEEE Clause 45 PHY
    +     * with special mappings to work with IEEE
    +     * Clause 22 register accesses.
    +     */
    +	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
    +		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
    +			reg += 0x10;
    +	}
    +
     	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
     		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
     		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
    @@ -2647,9 +2674,11 @@ bce_get_media(struct bce_softc *sc)
     				DBPRINT(sc, BCE_INFO_LOAD,
     					"BCM5709 s/w configured for SerDes.\n");
     				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
    +                break;
     			default:
     				DBPRINT(sc, BCE_INFO_LOAD,
     					"BCM5709 s/w configured for Copper.\n");
    +                break;
     			}
     		} else {
     			switch (strap) {
    @@ -2659,9 +2688,11 @@ bce_get_media(struct bce_softc *sc)
     				DBPRINT(sc, BCE_INFO_LOAD,
     					"BCM5709 s/w configured for SerDes.\n");
     				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
    +                break;
     			default:
     				DBPRINT(sc, BCE_INFO_LOAD,
     					"BCM5709 s/w configured for Copper.\n");
    +                break;
     			}
     		}
     
    @@ -2669,15 +2700,22 @@ bce_get_media(struct bce_softc *sc)
     		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
     
     	if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
    +
     		sc->bce_flags |= BCE_NO_WOL_FLAG;
    -		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
    +
    +		/* 5708S, 5709S, and 5716S use a separate PHY for SerDes. */
    +		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) 
     			sc->bce_phy_addr = 2;
    +
    +		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
    +			sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
    +
     			val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
     			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
     				sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
     				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb capable adapter\n");
     			}
    -		}
    +        }
     	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
     		   (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
     		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
    @@ -2690,6 +2728,37 @@ bce_get_media_exit:
     }
     
     
    +/****************************************************************************/
    +/* Performs PHY initialization required before MII drivers access the       */
    +/* device.                                                                  */
    +/*                                                                          */
    +/* Returns:                                                                 */
    +/*   Nothing.                                                               */
    +/****************************************************************************/
    +static void
    +bce_init_media(struct bce_softc *sc)
    +{
    +	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
    +		/*
    +		 * Configure 5709S/5716S PHYs to use traditional IEEE
    +		 * Clause 22 method. Otherwise we have no way to attach
    +		 * the PHY in mii(4) layer. PHY specific configuration
    +		 * is done in mii layer.
    +		 */
    +
    +        /* Select auto-negotiation MMD of the PHY. */
    +        bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
    +		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
    +		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
    +		    BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
    +
    +        /* Select IEEE0 block of AN MMD (assumed in all brgphy(4) code). */
    +		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
    +		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
    +	}
    +}
    +
    +
     /****************************************************************************/
     /* Free any DMA memory owned by the driver.                                 */
     /*                                                                          */
    @@ -6679,7 +6748,7 @@ bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
     
     	DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
     	    "ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
    -	    __FUNCTION__, hdr_len, sizeof(struct ether_header), ip_hlen,
    +	    __FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
     	    tcp_hlen, ip_len);
     
     	/* Set the LSO flag in the TX BD */
    @@ -7943,7 +8012,7 @@ bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
     
             if (result == 1) {
                     sc = (struct bce_softc *)arg1;
    -                bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
    +                bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
             }
     
             return error;
    @@ -8626,7 +8695,7 @@ bce_add_sysctls(struct bce_softc *sc)
     /* Returns:                                                                 */
     /*   Nothing.                                                               */
     /****************************************************************************/
    -static void
    +static __attribute__ ((noinline)) void
     bce_freeze_controller(struct bce_softc *sc)
     {
     	u32 val;
    @@ -8643,7 +8712,7 @@ bce_freeze_controller(struct bce_softc *sc)
     /* Returns:                                                                 */
     /*   Nothing.                                                               */
     /****************************************************************************/
    -static void
    +static __attribute__ ((noinline)) void
     bce_unfreeze_controller(struct bce_softc *sc)
     {
     	u32 val;
    @@ -8661,7 +8730,7 @@ bce_unfreeze_controller(struct bce_softc *sc)
     /* Returns:                                                                 */
     /*   Nothing.                                                               */
     /****************************************************************************/
    -static void
    +static __attribute__ ((noinline)) void
     bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
     {
     	struct ether_vlan_header *eh;
    @@ -8915,7 +8984,9 @@ bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
     static __attribute__ ((noinline)) void
     bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
     {
    -	if (idx > MAX_TX_BD)
    +    int i = 0;
    +
    +    if (idx > MAX_TX_BD)
     		/* Index out of range. */
     		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
     	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
    @@ -8923,52 +8994,65 @@ bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
     		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
     			idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
     	else {
    -			/* Normal tx_bd entry. */
    -			BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
    -				"vlan tag= 0x%04X, flags = 0x%04X (", idx,
    -				txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
    -				txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
    -				txbd->tx_bd_flags);
    +		/* Normal tx_bd entry. */
    +		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, mss_nbytes = 0x%08X, "
    +			"vlan tag = 0x%04X, flags = 0x%04X (", idx,
    +			txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
    +			txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
    +			txbd->tx_bd_flags);
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT)
    -				printf(" CONN_FAULT");
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
    +			if (i>0) printf("|"); printf("CONN_FAULT"); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM)
    -				printf(" TCP_UDP_CKSUM");
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
    +            if (i>0) printf("|"); printf("TCP_UDP_CKSUM"); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM)
    -				printf(" IP_CKSUM");
    +        if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
    +            if (i>0) printf("|"); printf("IP_CKSUM"); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG)
    -				printf("  VLAN");
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
    +            if (i>0) printf("|"); printf("VLAN"); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW)
    -				printf(" COAL_NOW");
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
    +            if (i>0) printf("|"); printf("COAL_NOW"); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC)
    -				printf(" DONT_GEN_CRC");
    +        if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
    +            if (i>0) printf("|"); printf("DONT_GEN_CRC"); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_START)
    -				printf(" START");
    +        if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
    +            if (i>0) printf("|"); printf("START"); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_END)
    -				printf(" END");
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
    +            if (i>0) printf("|"); printf("END"); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO)
    -				printf(" LSO");
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
    +            if (i>0) printf("|"); printf("LSO"); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD)
    -				printf(" OPTION_WORD");
    +        if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
    +            if (i>0) printf("|"); 
    +            printf("SW_OPTION=%d", ((txbd->tx_bd_flags & 
    +                TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
    +        }
     
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS)
    -				printf(" FLAGS");
    -
    -			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP)
    -				printf(" SNAP");
    -
    -			printf(" )\n");
    -		}
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
    +            if (i>0) printf("|"); printf("SW_FLAGS"); i++;
    +        }
     
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
    +            if (i>0) printf("|"); printf("SNAP)");
    +        } else {
    +            printf(")\n");
    +        }
    +    }
     }
     
     
    @@ -9415,10 +9499,8 @@ bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
     
     	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
     		(u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
    -
     	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
     		(u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
    -
     	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
     
     	BCE_PRINTF(
    @@ -9426,11 +9508,11 @@ bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
     		"   tx_bd data   "
     		"----------------------------\n");
     
    -	/* Now print out the tx_bd's themselves. */
    +	/* Now print out a decoded list of TX buffer descriptors. */
     	for (int i = 0; i < count; i++) {
     	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
     		bce_dump_txbd(sc, tx_prod, txbd);
    -		tx_prod = NEXT_TX_BD(tx_prod);
    +		tx_prod++;
     	}
     
     	BCE_PRINTF(
    @@ -9530,6 +9612,17 @@ bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
     }
     #endif
     
    +#define BCE_PRINT_RX_CONS(arg)                                          \
    +if (sblk->status_rx_quick_consumer_index##arg)                          \
    +    BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index##arg\n",       \
    +		sblk->status_rx_quick_consumer_index##arg,                      \
    +		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg));
    +
    +#define BCE_PRINT_TX_CONS(arg)                                          \
    +if (sblk->status_tx_quick_consumer_index##arg)                          \
    +    BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index##arg\n",       \
    +        sblk->status_tx_quick_consumer_index##arg,                      \
    +        (u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg));
     
     /****************************************************************************/
     /* Prints out the status block from host memory.                            */
    @@ -9549,90 +9642,28 @@ bce_dump_status_block(struct bce_softc *sc)
     		"  Status Block  "
     		"----------------------------\n");
     
    +    /* Theses indices are used for normal L2 drivers. */
     	BCE_PRINTF("    0x%08X - attn_bits\n",
     		sblk->status_attn_bits);
     
     	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
     		sblk->status_attn_bits_ack);
     
    -	BCE_PRINTF("0x%04X(0x%04X) - rx_cons0\n",
    -		sblk->status_rx_quick_consumer_index0,
    -		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index0));
    -
    -	BCE_PRINTF("0x%04X(0x%04X) - tx_cons0\n",
    -		sblk->status_tx_quick_consumer_index0,
    -		(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index0));
    +    BCE_PRINT_RX_CONS(0);
    +    BCE_PRINT_TX_CONS(0)
     
     	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
     
     	/* Theses indices are not used for normal L2 drivers. */
    -	if (sblk->status_rx_quick_consumer_index1)
    -		BCE_PRINTF("0x%04X(0x%04X) - rx_cons1\n",
    -			sblk->status_rx_quick_consumer_index1,
    -			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index1));
    +    BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
    +    BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
    +    BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
    +    BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
    +    BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
     
    -	if (sblk->status_tx_quick_consumer_index1)
    -		BCE_PRINTF("0x%04X(0x%04X) - tx_cons1\n",
    -			sblk->status_tx_quick_consumer_index1,
    -			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index1));
    +    BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
     
    -	if (sblk->status_rx_quick_consumer_index2)
    -		BCE_PRINTF("0x%04X(0x%04X)- rx_cons2\n",
    -			sblk->status_rx_quick_consumer_index2,
    -			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index2));
    -
    -	if (sblk->status_tx_quick_consumer_index2)
    -		BCE_PRINTF("0x%04X(0x%04X) - tx_cons2\n",
    -			sblk->status_tx_quick_consumer_index2,
    -			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index2));
    -
    -	if (sblk->status_rx_quick_consumer_index3)
    -		BCE_PRINTF("0x%04X(0x%04X) - rx_cons3\n",
    -			sblk->status_rx_quick_consumer_index3,
    -			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index3));
    -
    -	if (sblk->status_tx_quick_consumer_index3)
    -		BCE_PRINTF("0x%04X(0x%04X) - tx_cons3\n",
    -			sblk->status_tx_quick_consumer_index3,
    -			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index3));
    -
    -	if (sblk->status_rx_quick_consumer_index4 ||
    -		sblk->status_rx_quick_consumer_index5)
    -		BCE_PRINTF("rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
    -			sblk->status_rx_quick_consumer_index4,
    -			sblk->status_rx_quick_consumer_index5);
    -
    -	if (sblk->status_rx_quick_consumer_index6 ||
    -		sblk->status_rx_quick_consumer_index7)
    -		BCE_PRINTF("rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
    -			sblk->status_rx_quick_consumer_index6,
    -			sblk->status_rx_quick_consumer_index7);
    -
    -	if (sblk->status_rx_quick_consumer_index8 ||
    -		sblk->status_rx_quick_consumer_index9)
    -		BCE_PRINTF("rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
    -			sblk->status_rx_quick_consumer_index8,
    -			sblk->status_rx_quick_consumer_index9);
    -
    -	if (sblk->status_rx_quick_consumer_index10 ||
    -		sblk->status_rx_quick_consumer_index11)
    -		BCE_PRINTF("rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
    -			sblk->status_rx_quick_consumer_index10,
    -			sblk->status_rx_quick_consumer_index11);
    -
    -	if (sblk->status_rx_quick_consumer_index12 ||
    -		sblk->status_rx_quick_consumer_index13)
    -		BCE_PRINTF("rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
    -			sblk->status_rx_quick_consumer_index12,
    -			sblk->status_rx_quick_consumer_index13);
    -
    -	if (sblk->status_rx_quick_consumer_index14 ||
    -		sblk->status_rx_quick_consumer_index15)
    -		BCE_PRINTF("rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
    -			sblk->status_rx_quick_consumer_index14,
    -			sblk->status_rx_quick_consumer_index15);
    -
    -	if (sblk->status_completion_producer_index ||
    +    if (sblk->status_completion_producer_index ||
     		sblk->status_cmd_consumer_index)
     		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
     			sblk->status_completion_producer_index,
    @@ -9645,6 +9676,14 @@ bce_dump_status_block(struct bce_softc *sc)
     }
     
     
    +#define BCE_PRINT_64BIT_STAT(arg)                                       \
    +if (sblk->arg##_lo || sblk->arg##_hi)                               \
    +	BCE_PRINTF("0x%08X:%08X : arg\n", sblk->arg##_hi, sblk->arg##_lo);
    +
    +#define BCE_PRINT_32BIT_STAT(arg)                                       \
    +if (sblk->arg)                                                        \
    +	BCE_PRINTF("         0x%08X : arg\n", sblk->arg);
    +
     /****************************************************************************/
     /* Prints out the statistics block from host memory.                        */
     /*                                                                          */
    @@ -9663,252 +9702,60 @@ bce_dump_stats_block(struct bce_softc *sc)
     		" Stats Block  (All Stats Not Shown Are 0) "
     		"---------------\n");
     
    -	if (sblk->stat_IfHCInOctets_hi
    -		|| sblk->stat_IfHCInOctets_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcInOctets\n",
    -			sblk->stat_IfHCInOctets_hi,
    -			sblk->stat_IfHCInOctets_lo);
    -
    -	if (sblk->stat_IfHCInBadOctets_hi
    -		|| sblk->stat_IfHCInBadOctets_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcInBadOctets\n",
    -			sblk->stat_IfHCInBadOctets_hi,
    -			sblk->stat_IfHCInBadOctets_lo);
    -
    -	if (sblk->stat_IfHCOutOctets_hi
    -		|| sblk->stat_IfHCOutOctets_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcOutOctets\n",
    -			sblk->stat_IfHCOutOctets_hi,
    -			sblk->stat_IfHCOutOctets_lo);
    -
    -	if (sblk->stat_IfHCOutBadOctets_hi
    -		|| sblk->stat_IfHCOutBadOctets_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcOutBadOctets\n",
    -			sblk->stat_IfHCOutBadOctets_hi,
    -			sblk->stat_IfHCOutBadOctets_lo);
    -
    -	if (sblk->stat_IfHCInUcastPkts_hi
    -		|| sblk->stat_IfHCInUcastPkts_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcInUcastPkts\n",
    -			sblk->stat_IfHCInUcastPkts_hi,
    -			sblk->stat_IfHCInUcastPkts_lo);
    -
    -	if (sblk->stat_IfHCInBroadcastPkts_hi
    -		|| sblk->stat_IfHCInBroadcastPkts_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcInBroadcastPkts\n",
    -			sblk->stat_IfHCInBroadcastPkts_hi,
    -			sblk->stat_IfHCInBroadcastPkts_lo);
    -
    -	if (sblk->stat_IfHCInMulticastPkts_hi
    -		|| sblk->stat_IfHCInMulticastPkts_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcInMulticastPkts\n",
    -			sblk->stat_IfHCInMulticastPkts_hi,
    -			sblk->stat_IfHCInMulticastPkts_lo);
    -
    -	if (sblk->stat_IfHCOutUcastPkts_hi
    -		|| sblk->stat_IfHCOutUcastPkts_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcOutUcastPkts\n",
    -			sblk->stat_IfHCOutUcastPkts_hi,
    -			sblk->stat_IfHCOutUcastPkts_lo);
    -
    -	if (sblk->stat_IfHCOutBroadcastPkts_hi
    -		|| sblk->stat_IfHCOutBroadcastPkts_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcOutBroadcastPkts\n",
    -			sblk->stat_IfHCOutBroadcastPkts_hi,
    -			sblk->stat_IfHCOutBroadcastPkts_lo);
    -
    -	if (sblk->stat_IfHCOutMulticastPkts_hi
    -		|| sblk->stat_IfHCOutMulticastPkts_lo)
    -		BCE_PRINTF("0x%08X:%08X : "
    -			"IfHcOutMulticastPkts\n",
    -			sblk->stat_IfHCOutMulticastPkts_hi,
    -			sblk->stat_IfHCOutMulticastPkts_lo);
    -
    -	if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
    -		BCE_PRINTF("         0x%08X : "
    -			"emac_tx_stat_dot3statsinternalmactransmiterrors\n",
    -			sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
    -
    -	if (sblk->stat_Dot3StatsCarrierSenseErrors)
    -		BCE_PRINTF("         0x%08X : Dot3StatsCarrierSenseErrors\n",
    -			sblk->stat_Dot3StatsCarrierSenseErrors);
    -
    -	if (sblk->stat_Dot3StatsFCSErrors)
    -		BCE_PRINTF("         0x%08X : Dot3StatsFCSErrors\n",
    -			sblk->stat_Dot3StatsFCSErrors);
    -
    -	if (sblk->stat_Dot3StatsAlignmentErrors)
    -		BCE_PRINTF("         0x%08X : Dot3StatsAlignmentErrors\n",
    -			sblk->stat_Dot3StatsAlignmentErrors);
    -
    -	if (sblk->stat_Dot3StatsSingleCollisionFrames)
    -		BCE_PRINTF("         0x%08X : Dot3StatsSingleCollisionFrames\n",
    -			sblk->stat_Dot3StatsSingleCollisionFrames);
    -
    -	if (sblk->stat_Dot3StatsMultipleCollisionFrames)
    -		BCE_PRINTF("         0x%08X : Dot3StatsMultipleCollisionFrames\n",
    -			sblk->stat_Dot3StatsMultipleCollisionFrames);
    -
    -	if (sblk->stat_Dot3StatsDeferredTransmissions)
    -		BCE_PRINTF("         0x%08X : Dot3StatsDeferredTransmissions\n",
    -			sblk->stat_Dot3StatsDeferredTransmissions);
    -
    -	if (sblk->stat_Dot3StatsExcessiveCollisions)
    -		BCE_PRINTF("         0x%08X : Dot3StatsExcessiveCollisions\n",
    -			sblk->stat_Dot3StatsExcessiveCollisions);
    -
    -	if (sblk->stat_Dot3StatsLateCollisions)
    -		BCE_PRINTF("         0x%08X : Dot3StatsLateCollisions\n",
    -			sblk->stat_Dot3StatsLateCollisions);
    -
    -	if (sblk->stat_EtherStatsCollisions)
    -		BCE_PRINTF("         0x%08X : EtherStatsCollisions\n",
    -			sblk->stat_EtherStatsCollisions);
    -
    -	if (sblk->stat_EtherStatsFragments)
    -		BCE_PRINTF("         0x%08X : EtherStatsFragments\n",
    -			sblk->stat_EtherStatsFragments);
    -
    -	if (sblk->stat_EtherStatsJabbers)
    -		BCE_PRINTF("         0x%08X : EtherStatsJabbers\n",
    -			sblk->stat_EtherStatsJabbers);
    -
    -	if (sblk->stat_EtherStatsUndersizePkts)
    -		BCE_PRINTF("         0x%08X : EtherStatsUndersizePkts\n",
    -			sblk->stat_EtherStatsUndersizePkts);
    -
    -	if (sblk->stat_EtherStatsOversizePkts)
    -		BCE_PRINTF("         0x%08X : EtherStatsOverrsizePkts\n",
    -			sblk->stat_EtherStatsOversizePkts);
    -
    -	if (sblk->stat_EtherStatsPktsRx64Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsRx64Octets\n",
    -			sblk->stat_EtherStatsPktsRx64Octets);
    -
    -	if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
    -			sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
    -
    -	if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsRx128Octetsto255Octets\n",
    -			sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
    -
    -	if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsRx256Octetsto511Octets\n",
    -			sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
    -
    -	if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsRx512Octetsto1023Octets\n",
    -			sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
    -
    -	if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1024Octetsto1522Octets\n",
    -			sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
    -
    -	if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1523Octetsto9022Octets\n",
    -			sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
    -
    -	if (sblk->stat_EtherStatsPktsTx64Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsTx64Octets\n",
    -			sblk->stat_EtherStatsPktsTx64Octets);
    -
    -	if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
    -			sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
    -
    -	if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsTx128Octetsto255Octets\n",
    -			sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
    -
    -	if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsTx256Octetsto511Octets\n",
    -			sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
    -
    -	if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsTx512Octetsto1023Octets\n",
    -			sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
    -
    -	if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1024Octetsto1522Octets\n",
    -			sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
    -
    -	if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
    -		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1523Octetsto9022Octets\n",
    -			sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
    -
    -	if (sblk->stat_XonPauseFramesReceived)
    -		BCE_PRINTF("         0x%08X : XonPauseFramesReceived\n",
    -			sblk->stat_XonPauseFramesReceived);
    -
    -	if (sblk->stat_XoffPauseFramesReceived)
    -	   BCE_PRINTF("          0x%08X : XoffPauseFramesReceived\n",
    -			sblk->stat_XoffPauseFramesReceived);
    -
    -	if (sblk->stat_OutXonSent)
    -		BCE_PRINTF("         0x%08X : OutXonSent\n",
    -			sblk->stat_OutXonSent);
    -
    -	if (sblk->stat_OutXoffSent)
    -		BCE_PRINTF("         0x%08X : OutXoffSent\n",
    -			sblk->stat_OutXoffSent);
    -
    -	if (sblk->stat_FlowControlDone)
    -		BCE_PRINTF("         0x%08X : FlowControlDone\n",
    -			sblk->stat_FlowControlDone);
    -
    -	if (sblk->stat_MacControlFramesReceived)
    -		BCE_PRINTF("         0x%08X : MacControlFramesReceived\n",
    -			sblk->stat_MacControlFramesReceived);
    -
    -	if (sblk->stat_XoffStateEntered)
    -		BCE_PRINTF("         0x%08X : XoffStateEntered\n",
    -			sblk->stat_XoffStateEntered);
    -
    -	if (sblk->stat_IfInFramesL2FilterDiscards)
    -		BCE_PRINTF("         0x%08X : IfInFramesL2FilterDiscards\n",
    -			sblk->stat_IfInFramesL2FilterDiscards);
    -
    -	if (sblk->stat_IfInRuleCheckerDiscards)
    -		BCE_PRINTF("         0x%08X : IfInRuleCheckerDiscards\n",
    -			sblk->stat_IfInRuleCheckerDiscards);
    -
    -	if (sblk->stat_IfInFTQDiscards)
    -		BCE_PRINTF("         0x%08X : IfInFTQDiscards\n",
    -			sblk->stat_IfInFTQDiscards);
    -
    -	if (sblk->stat_IfInMBUFDiscards)
    -		BCE_PRINTF("         0x%08X : IfInMBUFDiscards\n",
    -			sblk->stat_IfInMBUFDiscards);
    -
    -	if (sblk->stat_IfInRuleCheckerP4Hit)
    -		BCE_PRINTF("         0x%08X : IfInRuleCheckerP4Hit\n",
    -			sblk->stat_IfInRuleCheckerP4Hit);
    -
    -	if (sblk->stat_CatchupInRuleCheckerDiscards)
    -		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerDiscards\n",
    -			sblk->stat_CatchupInRuleCheckerDiscards);
    -
    -	if (sblk->stat_CatchupInFTQDiscards)
    -		BCE_PRINTF("         0x%08X : CatchupInFTQDiscards\n",
    -			sblk->stat_CatchupInFTQDiscards);
    -
    -	if (sblk->stat_CatchupInMBUFDiscards)
    -		BCE_PRINTF("         0x%08X : CatchupInMBUFDiscards\n",
    -			sblk->stat_CatchupInMBUFDiscards);
    -
    -	if (sblk->stat_CatchupInRuleCheckerP4Hit)
    -		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerP4Hit\n",
    -			sblk->stat_CatchupInRuleCheckerP4Hit);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
    +    BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
    +    BCE_PRINT_32BIT_STAT(stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
    +    BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
    +    BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
    +    BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
    +    BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
    +    BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
    +    BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
    +    BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
    +    BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
    +    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
    +    BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
    +    BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
    +    BCE_PRINT_32BIT_STAT(stat_OutXonSent);
    +    BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
    +    BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
    +    BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
    +    BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
    +    BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
    +    BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
    +    BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
    +    BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
    +    BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
    +    BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
    +    BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
    +    BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
    +    BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
     
     	BCE_PRINTF(
     		"----------------------------"
    @@ -10465,7 +10312,7 @@ static __attribute__ ((noinline)) void
     bce_dump_com_state(struct bce_softc *sc, int regs)
     {
     	u32 val;
    -	u32 fw_version[3];
    +	u32 fw_version[4];
     
     	BCE_PRINTF(
     		"----------------------------"
    @@ -10507,13 +10354,77 @@ bce_dump_com_state(struct bce_softc *sc, int regs)
     }
     
     
    +/****************************************************************************/
    +/* Prints out the Receive Virtual 2 Physical (RV2P) state.                  */
    +/*                                                                          */
    +/* Returns:                                                                 */
    +/*   Nothing.                                                               */
    +/****************************************************************************/
    +static __attribute__ ((noinline)) void
    +bce_dump_rv2p_state(struct bce_softc *sc)
    +{
    +	u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
    +
    +	BCE_PRINTF(
    +		"----------------------------"
    +		"   RV2P State   "
    +		"----------------------------\n");
    +
    +    /* Stall the RV2P processors. */
    +    val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
    +    val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
    +    REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
    +
    +    /* Read the firmware version. */
    +    val = 0x00000001;
    +    REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
    +    fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
    +    fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & BCE_RV2P_INSTR_HIGH_HIGH;
    +	BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n", fw_ver_high, fw_ver_low);
    +
    +    val = 0x00000001;
    +    REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
    +    fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
    +    fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & BCE_RV2P_INSTR_HIGH_HIGH;
    +    BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n", fw_ver_high, fw_ver_low);
    +
    +    /* Resume the RV2P processors. */
    +    val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
    +    val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
    +    REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
    +
    +    /* Fetch the program counter value. */
    +	val = 0x68007800;
    +    REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
    +    val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
    +    pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
    +    pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
    +    BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
    +    BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
    +
    +    /* Fetch the program counter value again to see if it is advancing. */
    +    val = 0x68007800;
    +    REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
    +    val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
    +    pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
    +    pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
    +    BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
    +    BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
    +
    +	BCE_PRINTF(
    +		"----------------------------"
    +		"----------------"
    +		"----------------------------\n");
    +}
    +
    +
     /****************************************************************************/
     /* Prints out the driver state and then enters the debugger.                */
     /*                                                                          */
     /* Returns:                                                                 */
     /*   Nothing.                                                               */
     /****************************************************************************/
    -static void
    +static __attribute__ ((noinline)) void
     bce_breakpoint(struct bce_softc *sc)
     {
     
    @@ -10544,6 +10455,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);
    +        bce_dump_rv2p_state(sc);
     #ifdef BCE_JUMBO_HDRSPLIT
     		bce_dump_pgbd(sc, 0, NULL);
     		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);
    diff --git a/sys/dev/bce/if_bcefw.h b/sys/dev/bce/if_bcefw.h
    index 7f12ac71ec5..c41ff10acf4 100644
    --- a/sys/dev/bce/if_bcefw.h
    +++ b/sys/dev/bce/if_bcefw.h
    @@ -1,5 +1,5 @@
     /*-
    - * Copyright (c) 2006-2009 Broadcom Corporation
    + * Copyright (c) 2006-2010 Broadcom Corporation
      *	David Christensen .  All rights reserved.
      *
      * Redistribution and use in source and binary forms, with or without
    diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h
    index a437686478e..177378b3aab 100644
    --- a/sys/dev/bce/if_bcereg.h
    +++ b/sys/dev/bce/if_bcereg.h
    @@ -1,5 +1,5 @@
     /*-
    - * Copyright (c) 2006-2009 Broadcom Corporation
    + * Copyright (c) 2006-2010 Broadcom Corporation
      *	David Christensen .  All rights reserved.
      *
      * Redistribution and use in source and binary forms, with or without
    @@ -453,24 +453,10 @@
     	}
     
     /* Announces function entry. */
    -#if 0
    -#define DBENTER(cond)								 			\
    -	u32 start_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN);		\
    -	u32 end_time;										  		\
    -	DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__);
    -#endif
    -
     #define DBENTER(cond)									  		\
     	DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__)
     
     /* Announces function exit. */
    -#if 0
    -#define DBEXIT(cond, val)								  		\
    -	end_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN);	  		\
    -	val += (u64) BCE_TIME_DELTA(start_time, end_time);			\
    -	DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__);
    -#endif
    -
     #define DBEXIT(cond)											\
     	DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__)
     
    @@ -6454,6 +6440,7 @@ struct bce_softc
     #define BCE_PHY_INT_MODE_MASK_FLAG			0x00000300
     #define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG	0x00000100
     #define BCE_PHY_INT_MODE_LINK_READY_FLAG	0x00000200
    +#define BCE_PHY_IEEE_CLAUSE_45_FLAG     	0x00000400
     
     	/* Values that need to be shared with the PHY driver. */
     	u32					bce_shared_hw_cfg;
    
    From fa7ad760a6261d2ec8e345560659b5637b8a9cd8 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 15 Apr 2010 19:29:56 +0000
    Subject: [PATCH 1968/2592] MFC r206268   - Fixed 5708S 2.5G support broken in
     last commit.   - Added some new debug helper routines to systcl.   - Fixed
     many of the style(9) violations that have crept into the code     due to my
     use of a "smart" editor.
    
    ---
     sys/dev/bce/if_bce.c    | 4319 +++++++++++++++++++++------------------
     sys/dev/bce/if_bcereg.h | 1672 +++++++--------
     2 files changed, 3135 insertions(+), 2856 deletions(-)
    
    diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
    index 61f3af565af..2ad5ab2d37f 100644
    --- a/sys/dev/bce/if_bce.c
    +++ b/sys/dev/bce/if_bce.c
    @@ -39,8 +39,8 @@ __FBSDID("$FreeBSD$");
      *   BCM5708S B1, B2
      *   BCM5709C A1, C0
      *   BCM5709S A1, C0
    - * 	 BCM5716C C0
    - * 	 BCM5716S C0
    + *   BCM5716C C0
    + *   BCM5716S C0
      *
      * The following controllers are not supported by this driver:
      *   BCM5706C A0, A1 (pre-production)
    @@ -277,37 +277,41 @@ static struct flash_spec flash_5709 = {
     /****************************************************************************/
     /* FreeBSD device entry points.                                             */
     /****************************************************************************/
    -static int  bce_probe				(device_t);
    -static int  bce_attach				(device_t);
    -static int  bce_detach				(device_t);
    -static int  bce_shutdown			(device_t);
    +static int  bce_probe			(device_t);
    +static int  bce_attach			(device_t);
    +static int  bce_detach			(device_t);
    +static int  bce_shutdown		(device_t);
     
     
     /****************************************************************************/
     /* BCE Debug Data Structure Dump Routines                                   */
     /****************************************************************************/
     #ifdef BCE_DEBUG
    -static u32	bce_reg_rd				(struct bce_softc *, u32);
    -static void	bce_reg_wr				(struct bce_softc *, u32, u32);
    -static void	bce_reg_wr16			(struct bce_softc *, u32, u16);
    -static u32  bce_ctx_rd				(struct bce_softc *, u32, u32);
    -static void bce_dump_enet           (struct bce_softc *, struct mbuf *);
    -static void bce_dump_mbuf 			(struct bce_softc *, struct mbuf *);
    +static u32  bce_reg_rd			(struct bce_softc *, u32);
    +static void bce_reg_wr			(struct bce_softc *, u32, u32);
    +static void bce_reg_wr16		(struct bce_softc *, u32, u16);
    +static u32  bce_ctx_rd			(struct bce_softc *, u32, u32);
    +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 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 *);
    +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 BCE_JUMBO_HDRSPLIT
    -static void bce_dump_pgbd			(struct bce_softc *, int, struct rx_bd *);
    +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 *);
    -static void bce_dump_ctx			(struct bce_softc *, u16);
    -static void bce_dump_ftqs			(struct bce_softc *);
    +static void bce_dump_l2fhdr		(struct bce_softc *,
    +    int, struct l2_fhdr *);
    +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);
    +static void bce_dump_rx_bd_chain	(struct bce_softc *, u16, int);
     #ifdef BCE_JUMBO_HDRSPLIT
     static void bce_dump_pg_chain		(struct bce_softc *, u16, int);
     #endif
    @@ -315,7 +319,7 @@ static void bce_dump_status_block	(struct bce_softc *);
     static void bce_dump_stats_block	(struct bce_softc *);
     static void bce_dump_driver_state	(struct bce_softc *);
     static void bce_dump_hw_state		(struct bce_softc *);
    -static void bce_dump_mq_regs        (struct bce_softc *);
    +static void bce_dump_mq_regs		(struct bce_softc *);
     static void bce_dump_bc_state		(struct bce_softc *);
     static void bce_dump_txp_state		(struct bce_softc *, int);
     static void bce_dump_rxp_state		(struct bce_softc *, int);
    @@ -323,18 +327,18 @@ static void bce_dump_tpat_state		(struct bce_softc *, int);
     static void bce_dump_cp_state		(struct bce_softc *, int);
     static void bce_dump_com_state		(struct bce_softc *, int);
     static void bce_dump_rv2p_state		(struct bce_softc *);
    -static void bce_breakpoint			(struct bce_softc *);
    +static void bce_breakpoint		(struct bce_softc *);
     #endif
     
     
     /****************************************************************************/
     /* BCE Register/Memory Access Routines                                      */
     /****************************************************************************/
    -static u32  bce_reg_rd_ind			(struct bce_softc *, u32);
    -static void bce_reg_wr_ind			(struct bce_softc *, u32, u32);
    -static void bce_shmem_wr            (struct bce_softc *, u32, u32);
    -static u32  bce_shmem_rd            (struct bce_softc *, u32);
    -static void bce_ctx_wr				(struct bce_softc *, u32, u32, u32);
    +static u32  bce_reg_rd_ind		(struct bce_softc *, u32);
    +static void bce_reg_wr_ind		(struct bce_softc *, u32, u32);
    +static void bce_shmem_wr		(struct bce_softc *, u32, u32);
    +static u32  bce_shmem_rd		(struct bce_softc *, u32);
    +static void bce_ctx_wr			(struct bce_softc *, u32, u32, u32);
     static int  bce_miibus_read_reg		(device_t, int, int);
     static int  bce_miibus_write_reg	(device_t, int, int, int);
     static void bce_miibus_statchg		(device_t);
    @@ -346,96 +350,101 @@ static void bce_miibus_statchg		(device_t);
     static int  bce_acquire_nvram_lock	(struct bce_softc *);
     static int  bce_release_nvram_lock	(struct bce_softc *);
     static void bce_enable_nvram_access	(struct bce_softc *);
    -static void	bce_disable_nvram_access(struct bce_softc *);
    +static void bce_disable_nvram_access	(struct bce_softc *);
     static int  bce_nvram_read_dword	(struct bce_softc *, u32, u8 *, u32);
    -static int  bce_init_nvram			(struct bce_softc *);
    -static int  bce_nvram_read			(struct bce_softc *, u32, u8 *, int);
    -static int  bce_nvram_test			(struct bce_softc *);
    +static int  bce_init_nvram		(struct bce_softc *);
    +static int  bce_nvram_read		(struct bce_softc *, u32, u8 *, int);
    +static int  bce_nvram_test		(struct bce_softc *);
     #ifdef BCE_NVRAM_WRITE_SUPPORT
     static int  bce_enable_nvram_write	(struct bce_softc *);
     static void bce_disable_nvram_write	(struct bce_softc *);
     static int  bce_nvram_erase_page	(struct bce_softc *, u32);
     static int  bce_nvram_write_dword	(struct bce_softc *, u32, u8 *, u32);
    -static int  bce_nvram_write			(struct bce_softc *, u32, u8 *, int);
    +static int  bce_nvram_write		(struct bce_softc *, u32, u8 *, int);
     #endif
     
     /****************************************************************************/
     /*                                                                          */
     /****************************************************************************/
    -static void bce_get_media			(struct bce_softc *);
    -static void bce_init_media			(struct bce_softc *);
    -static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
    -static int  bce_dma_alloc			(device_t);
    -static void bce_dma_free			(struct bce_softc *);
    +static void bce_get_media		(struct bce_softc *);
    +static void bce_init_media		(struct bce_softc *);
    +static void bce_dma_map_addr		(void *, 
    +    bus_dma_segment_t *, int, int);
    +static int  bce_dma_alloc		(device_t);
    +static void bce_dma_free		(struct bce_softc *);
     static void bce_release_resources	(struct bce_softc *);
     
     /****************************************************************************/
     /* BCE Firmware Synchronization and Load                                    */
     /****************************************************************************/
    -static int  bce_fw_sync				(struct bce_softc *, u32);
    +static int  bce_fw_sync			(struct bce_softc *, u32);
     static void bce_load_rv2p_fw		(struct bce_softc *, u32 *, u32, u32);
    -static void bce_load_cpu_fw			(struct bce_softc *, struct cpu_reg *, struct fw_info *);
    -static void bce_start_cpu           (struct bce_softc *, struct cpu_reg *);
    -static void bce_halt_cpu            (struct bce_softc *, struct cpu_reg *);
    -static void bce_start_rxp_cpu       (struct bce_softc *);
    +static void bce_load_cpu_fw		(struct bce_softc *, 
    +    struct cpu_reg *, struct fw_info *);
    +static void bce_start_cpu		(struct bce_softc *, struct cpu_reg *);
    +static void bce_halt_cpu		(struct bce_softc *, struct cpu_reg *);
    +static void bce_start_rxp_cpu		(struct bce_softc *);
     static void bce_init_rxp_cpu		(struct bce_softc *);
     static void bce_init_txp_cpu 		(struct bce_softc *);
     static void bce_init_tpat_cpu		(struct bce_softc *);
    -static void bce_init_cp_cpu		  	(struct bce_softc *);
    +static void bce_init_cp_cpu	  	(struct bce_softc *);
     static void bce_init_com_cpu	  	(struct bce_softc *);
    -static void bce_init_cpus			(struct bce_softc *);
    +static void bce_init_cpus		(struct bce_softc *);
     
     static void	bce_print_adapter_info	(struct bce_softc *);
     static void bce_probe_pci_caps		(device_t, struct bce_softc *);
    -static void bce_stop				(struct bce_softc *);
    -static int  bce_reset				(struct bce_softc *, u32);
    -static int  bce_chipinit 			(struct bce_softc *);
    -static int  bce_blockinit 			(struct bce_softc *);
    +static void bce_stop			(struct bce_softc *);
    +static int  bce_reset			(struct bce_softc *, u32);
    +static int  bce_chipinit 		(struct bce_softc *);
    +static int  bce_blockinit 		(struct bce_softc *);
     
     static int  bce_init_tx_chain		(struct bce_softc *);
     static void bce_free_tx_chain		(struct bce_softc *);
     
    -static int  bce_get_rx_buf			(struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
    +static int  bce_get_rx_buf		(struct bce_softc *, 
    +    struct mbuf *, u16 *, u16 *, u32 *);
     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 BCE_JUMBO_HDRSPLIT
    -static int  bce_get_pg_buf			(struct bce_softc *, struct mbuf *, u16 *, u16 *);
    +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 *);
     static void bce_free_pg_chain		(struct bce_softc *);
     #endif
     
    -static struct mbuf *bce_tso_setup	(struct bce_softc *, struct mbuf **, u16 *);
    -static int  bce_tx_encap			(struct bce_softc *, struct mbuf **);
    +static struct mbuf *bce_tso_setup	(struct bce_softc *, 
    +    struct mbuf **, u16 *);
    +static int  bce_tx_encap		(struct bce_softc *, struct mbuf **);
     static void bce_start_locked		(struct ifnet *);
    -static void bce_start				(struct ifnet *);
    -static int  bce_ioctl				(struct ifnet *, u_long, caddr_t);
    -static void bce_watchdog			(struct bce_softc *);
    -static int  bce_ifmedia_upd			(struct ifnet *);
    +static void bce_start			(struct ifnet *);
    +static int  bce_ioctl			(struct ifnet *, u_long, caddr_t);
    +static void bce_watchdog		(struct bce_softc *);
    +static int  bce_ifmedia_upd		(struct ifnet *);
     static void bce_ifmedia_upd_locked	(struct ifnet *);
    -static void bce_ifmedia_sts			(struct ifnet *, struct ifmediareq *);
    -static void bce_init_locked			(struct bce_softc *);
    -static void bce_init				(void *);
    +static void bce_ifmedia_sts		(struct ifnet *, struct ifmediareq *);
    +static void bce_init_locked		(struct bce_softc *);
    +static void bce_init			(void *);
     static void bce_mgmt_init_locked	(struct bce_softc *sc);
     
    -static void bce_init_ctx			(struct bce_softc *);
    +static void bce_init_ctx		(struct bce_softc *);
     static void bce_get_mac_addr		(struct bce_softc *);
     static void bce_set_mac_addr		(struct bce_softc *);
    -static void bce_phy_intr			(struct bce_softc *);
    -static inline u16 bce_get_hw_rx_cons(struct bce_softc *);
    -static void bce_rx_intr				(struct bce_softc *);
    -static void bce_tx_intr				(struct bce_softc *);
    +static void bce_phy_intr		(struct bce_softc *);
    +static inline u16 bce_get_hw_rx_cons	(struct bce_softc *);
    +static void bce_rx_intr			(struct bce_softc *);
    +static void bce_tx_intr			(struct bce_softc *);
     static void bce_disable_intr		(struct bce_softc *);
    -static void bce_enable_intr			(struct bce_softc *, int);
    +static void bce_enable_intr		(struct bce_softc *, int);
     
    -static void bce_intr				(void *);
    -static void bce_set_rx_mode			(struct bce_softc *);
    +static void bce_intr			(void *);
    +static void bce_set_rx_mode		(struct bce_softc *);
     static void bce_stats_update		(struct bce_softc *);
    -static void bce_tick				(void *);
    -static void bce_pulse				(void *);
    -static void bce_add_sysctls			(struct bce_softc *);
    +static void bce_tick			(void *);
    +static void bce_pulse			(void *);
    +static void bce_add_sysctls		(struct bce_softc *);
     
     
     /****************************************************************************/
    @@ -540,15 +549,15 @@ bce_probe(device_t dev)
     	sdid = pci_get_subdevice(dev);
     
     	DBPRINT(sc, BCE_EXTREME_LOAD,
    -		"%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
    -		"SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
    +	    "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
    +	    "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
     
     	/* Look through the list of known devices for a match. */
     	while(t->bce_name != NULL) {
     
     		if ((vid == t->bce_vid) && (did == t->bce_did) &&
    -			((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
    -			((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
    +		    ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
    +		    ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
     
     			descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
     
    @@ -557,8 +566,8 @@ bce_probe(device_t dev)
     
     			/* Print out the device identity. */
     			snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
    -				t->bce_name,
    -			    (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
    +			    t->bce_name, (((pci_read_config(dev, 
    +			    PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
     			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
     
     			device_set_desc_copy(dev, descbuf);
    @@ -590,21 +599,21 @@ bce_print_adapter_info(struct bce_softc *sc)
     
     	BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
     	printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A',
    -		((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
    +	    ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
     
     	/* Bus info. */
     	if (sc->bce_flags & BCE_PCIE_FLAG) {
     		printf("Bus (PCIe x%d, ", sc->link_width);
     		switch (sc->link_speed) {
    -			case 1: printf("2.5Gbps); "); break;
    -			case 2:	printf("5Gbps); "); break;
    -			default: printf("Unknown link speed); ");
    +		case 1: printf("2.5Gbps); "); break;
    +		case 2:	printf("5Gbps); "); break;
    +		default: printf("Unknown link speed); ");
     		}
     	} else {
     		printf("Bus (PCI%s, %s, %dMHz); ",
    -			((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
    -			((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
    -			sc->bus_speed_mhz);
    +		    ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
    +		    ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? 
    +		    "32-bit" : "64-bit"), sc->bus_speed_mhz);
     	}
     
     	/* Firmware version and device features. */
    @@ -612,30 +621,30 @@ bce_print_adapter_info(struct bce_softc *sc)
     
     #ifdef BCE_JUMBO_HDRSPLIT
     	printf("SPLT");
    -    i++;
    +	i++;
     #endif
     
    -    if (sc->bce_flags & BCE_USING_MSI_FLAG) {
    -        if (i > 0) printf("|");
    +	if (sc->bce_flags & BCE_USING_MSI_FLAG) {
    +		if (i > 0) printf("|");
     		printf("MSI"); i++;
    -    }
    +	}
     
    -    if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
    -        if (i > 0) printf("|");
    +	if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
    +		if (i > 0) printf("|");
     		printf("MSI-X"); i++;
    -    }
    +	}
     
    -    if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
    -        if (i > 0) printf("|");
    +	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
    +		if (i > 0) printf("|");
     		printf("2.5G"); i++;
    -    }
    +	}
     
    -    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    -        if (i > 0) printf("|");
    -        printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
    -    } else {
    -        printf(")\n");
    -    }
    +	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    +		if (i > 0) printf("|");
    +		printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
    +	} else {
    +		printf(")\n");
    +	}
     
     	DBEXIT(BCE_VERBOSE_LOAD);
     }
    @@ -667,8 +676,8 @@ bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
     	if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
     		if (reg != 0) {
     			u16 link_status = pci_read_config(dev, reg + 0x12, 2);
    -			DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = 0x%08X\n",
    -				link_status);
    +			DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = "
    +			    "0x%08X\n",	link_status);
     			sc->link_speed = link_status & 0xf;
     			sc->link_width = (link_status >> 4) & 0x3f;
     			sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
    @@ -730,7 +739,7 @@ bce_attach(device_t dev)
     
     	if (sc->bce_res_mem == NULL) {
     		BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		rc = ENXIO;
     		goto bce_attach_fail;
     	}
    @@ -801,14 +810,14 @@ bce_attach(device_t dev)
     	}
     
     	sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
    -		&rid, RF_SHAREABLE | RF_ACTIVE);
    +	    &rid, RF_SHAREABLE | RF_ACTIVE);
     
     	sc->bce_irq_rid = rid;
     
     	/* Report any IRQ allocation errors. */
     	if (sc->bce_res_irq == NULL) {
     		BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		rc = ENXIO;
     		goto bce_attach_fail;
     	}
    @@ -823,28 +832,28 @@ bce_attach(device_t dev)
     	 * valid until this is done.
     	 */
     	pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
    -			       BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
    -			       BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
    +	    BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
    +	    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
     
     	/* Save ASIC revsion info. */
     	sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
     
     	/* Weed out any non-production controller revisions. */
     	switch(BCE_CHIP_ID(sc)) {
    -		case BCE_CHIP_ID_5706_A0:
    -		case BCE_CHIP_ID_5706_A1:
    -		case BCE_CHIP_ID_5708_A0:
    -		case BCE_CHIP_ID_5708_B0:
    -		case BCE_CHIP_ID_5709_A0:
    -		case BCE_CHIP_ID_5709_B0:
    -		case BCE_CHIP_ID_5709_B1:
    -		case BCE_CHIP_ID_5709_B2:
    -			BCE_PRINTF("%s(%d): Unsupported controller revision (%c%d)!\n",
    -				__FILE__, __LINE__,
    -				(((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
    -			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
    -			rc = ENODEV;
    -			goto bce_attach_fail;
    +	case BCE_CHIP_ID_5706_A0:
    +	case BCE_CHIP_ID_5706_A1:
    +	case BCE_CHIP_ID_5708_A0:
    +	case BCE_CHIP_ID_5708_B0:
    +	case BCE_CHIP_ID_5709_A0:
    +	case BCE_CHIP_ID_5709_B0:
    +	case BCE_CHIP_ID_5709_B1:
    +	case BCE_CHIP_ID_5709_B2:
    +		BCE_PRINTF("%s(%d): Unsupported controller revision (%c%d)!\n",
    +		    __FILE__, __LINE__,
    +		    (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
    +		    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
    +		rc = ENODEV;
    +		goto bce_attach_fail;
     	}
     
     	/*
    @@ -866,58 +875,67 @@ bce_attach(device_t dev)
     	if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
     		/* Multi-port devices use different offsets in shared memory. */
     		sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
    -			(pci_get_function(sc->bce_dev) << 2));
    +		    (pci_get_function(sc->bce_dev) << 2));
     	else
     		sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
     
     	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
    -		__FUNCTION__, sc->bce_shmem_base);
    +	    __FUNCTION__, sc->bce_shmem_base);
     
     	/* Fetch the bootcode revision. */
    -    val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
    -    for (int i = 0, j = 0; i < 3; i++) {
    -        u8 num;
    +	val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
    +	for (int i = 0, j = 0; i < 3; i++) {
    +		u8 num;
     
    -        num = (u8) (val >> (24 - (i * 8)));
    -        for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
    -            if (num >= k || !skip0 || k == 1) {
    -                sc->bce_bc_ver[j++] = (num / k) + '0';
    -                skip0 = 0;
    -            }
    -        }
    -        if (i != 2)
    -            sc->bce_bc_ver[j++] = '.';
    -    }
    +		num = (u8) (val >> (24 - (i * 8)));
    +		for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
    +			if (num >= k || !skip0 || k == 1) {
    +				sc->bce_bc_ver[j++] = (num / k) + '0';
    +				skip0 = 0;
    +			}
    +		}
     
    -    /* Check if any management firwmare is running. */
    -    val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
    -    if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
    -        sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
    +		if (i != 2)
    +			sc->bce_bc_ver[j++] = '.';
    +	}
     
    -        /* Allow time for firmware to enter the running state. */
    -        for (int i = 0; i < 30; i++) {
    -            val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
    -            if (val & BCE_CONDITION_MFW_RUN_MASK)
    -                break;
    -            DELAY(10000);
    -        }
    -    }
    +	/* Check if any management firwmare is enabled. */
    +	val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
    +	if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
    +		sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
     
    -    /* Check the current bootcode state. */
    -    val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
    -    val &= BCE_CONDITION_MFW_RUN_MASK;
    -    if (val != BCE_CONDITION_MFW_RUN_UNKNOWN &&
    -        val != BCE_CONDITION_MFW_RUN_NONE) {
    -        u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
    -        int i = 0;
    +		/* Allow time for firmware to enter the running state. */
    +		for (int i = 0; i < 30; i++) {
    +			val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
    +			if (val & BCE_CONDITION_MFW_RUN_MASK)
    +				break;
    +			DELAY(10000);
    +		}
     
    -        for (int j = 0; j < 3; j++) {
    -            val = bce_reg_rd_ind(sc, addr + j * 4);
    -            val = bswap32(val);
    -            memcpy(&sc->bce_mfw_ver[i], &val, 4);
    -            i += 4;
    -        }
    -    }
    +		/* Check if management firmware is running. */
    +		val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
    +		val &= BCE_CONDITION_MFW_RUN_MASK;
    +		if ((val != BCE_CONDITION_MFW_RUN_UNKNOWN) &&
    +		    (val != BCE_CONDITION_MFW_RUN_NONE)) {
    +			u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
    +			int i = 0;
    +
    +			/* Read the management firmware version string. */
    +			for (int j = 0; j < 3; j++) {
    +				val = bce_reg_rd_ind(sc, addr + j * 4);
    +				val = bswap32(val);
    +				memcpy(&sc->bce_mfw_ver[i], &val, 4);
    +				i += 4;
    +			}
    +		} else {
    +			/* May cause firmware synchronization timeouts. */
    +			BCE_PRINTF("%s(%d): Management firmware enabled "
    +			    "but not running!\n", __FILE__, __LINE__);
    +			strcpy(sc->bce_mfw_ver, "NOT RUNNING!");
    +
    +			/* ToDo: Any action the driver should take? */
    +		}
    +	}
     
     	/* Get PCI bus information (speed and type). */
     	val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
    @@ -964,10 +982,10 @@ bce_attach(device_t dev)
     	if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
     		sc->bce_flags |= BCE_PCI_32BIT_FLAG;
     
    -	/* Reset the controller and announce to bootcode that driver is present. */
    +	/* Reset controller and announce to bootcode that driver is present. */
     	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
     		BCE_PRINTF("%s(%d): Controller reset failed!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		rc = ENXIO;
     		goto bce_attach_fail;
     	}
    @@ -975,7 +993,7 @@ bce_attach(device_t dev)
     	/* Initialize the controller. */
     	if (bce_chipinit(sc)) {
     		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		rc = ENXIO;
     		goto bce_attach_fail;
     	}
    @@ -983,7 +1001,7 @@ bce_attach(device_t dev)
     	/* Perform NVRAM test. */
     	if (bce_nvram_test(sc)) {
     		BCE_PRINTF("%s(%d): NVRAM test failed!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		rc = ENXIO;
     		goto bce_attach_fail;
     	}
    @@ -1024,6 +1042,14 @@ bce_attach(device_t dev)
     	sc->bce_rx_ticks               = 18;
     #endif
     
    +	/* Not used for L2. */
    +	sc->bce_comp_prod_trip_int = 0;
    +	sc->bce_comp_prod_trip = 0;
    +	sc->bce_com_ticks_int = 0;
    +	sc->bce_com_ticks = 0;
    +	sc->bce_cmd_ticks_int = 0;
    +	sc->bce_cmd_ticks = 0;
    +
     	/* Update statistics once every second. */
     	sc->bce_stats_ticks = 1000000 & 0xffff00;
     
    @@ -1507,7 +1533,8 @@ bce_miibus_read_reg(device_t dev, int phy, int reg)
     
     	/* Make sure we are accessing the correct PHY address. */
     	if (phy != sc->bce_phy_addr) {
    -		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY read!\n", phy);
    +		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
    +		    "for PHY read!\n", phy);
     		return(0);
     	}
     
    @@ -1533,8 +1560,8 @@ bce_miibus_read_reg(device_t dev, int phy, int reg)
     
     
     	val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
    -		BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
    -		BCE_EMAC_MDIO_COMM_START_BUSY;
    +	    BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
    +	    BCE_EMAC_MDIO_COMM_START_BUSY;
     	REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
     
     	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
    @@ -1552,8 +1579,8 @@ bce_miibus_read_reg(device_t dev, int phy, int reg)
     	}
     
     	if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
    -		BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, reg = 0x%04X\n",
    -			__FILE__, __LINE__, phy, reg);
    +		BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, "
    +		    "reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
     		val = 0x0;
     	} else {
     		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
    @@ -1595,17 +1622,18 @@ bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
     
     	/* Make sure we are accessing the correct PHY address. */
     	if (phy != sc->bce_phy_addr) {
    -		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY write!\n", phy);
    +		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
    +		    "for PHY write!\n", phy);
     		return(0);
     	}
     
     	DB_PRINT_PHY_REG(reg, val);
     
    -    /*
    -     * The 5709S PHY is an IEEE Clause 45 PHY
    -     * with special mappings to work with IEEE
    -     * Clause 22 register accesses.
    -     */
    +	/*
    +	 * The 5709S PHY is an IEEE Clause 45 PHY
    +	 * with special mappings to work with IEEE
    +	 * Clause 22 register accesses.
    +	 */
     	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
     		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
     			reg += 0x10;
    @@ -1622,8 +1650,8 @@ bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
     	}
     
     	val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
    -		BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
    -		BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
    +	    BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
    +	    BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
     	REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
     
     	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
    @@ -1638,7 +1666,7 @@ bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
     
     	if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
     		BCE_PRINTF("%s(%d): PHY write timeout!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     
     	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
     		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
    @@ -2653,18 +2681,22 @@ bce_get_media(struct bce_softc *sc)
     		 * for Copper or SerDes operation.
     		 */
     		if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
    -			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for copper.\n");
    +			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
    +			    "for copper.\n");
     			goto bce_get_media_exit;
     		} else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
    -			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for dual media.\n");
    +			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
    +			    "for dual media.\n");
     			sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
     			goto bce_get_media_exit;
     		}
     
     		if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
    -			strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
    +			strap = (val & 
    +			    BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
     		else
    -			strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
    +			strap = (val & 
    +			    BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
     
     		if (pci_get_function(sc->bce_dev) == 0) {
     			switch (strap) {
    @@ -2672,13 +2704,13 @@ bce_get_media(struct bce_softc *sc)
     			case 0x5:
     			case 0x6:
     				DBPRINT(sc, BCE_INFO_LOAD,
    -					"BCM5709 s/w configured for SerDes.\n");
    +				    "BCM5709 s/w configured for SerDes.\n");
     				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
    -                break;
    +				break;
     			default:
     				DBPRINT(sc, BCE_INFO_LOAD,
    -					"BCM5709 s/w configured for Copper.\n");
    -                break;
    +				    "BCM5709 s/w configured for Copper.\n");
    +				break;
     			}
     		} else {
     			switch (strap) {
    @@ -2686,13 +2718,13 @@ bce_get_media(struct bce_softc *sc)
     			case 0x2:
     			case 0x4:
     				DBPRINT(sc, BCE_INFO_LOAD,
    -					"BCM5709 s/w configured for SerDes.\n");
    +				    "BCM5709 s/w configured for SerDes.\n");
     				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
    -                break;
    +				break;
     			default:
     				DBPRINT(sc, BCE_INFO_LOAD,
    -					"BCM5709 s/w configured for Copper.\n");
    -                break;
    +				    "BCM5709 s/w configured for Copper.\n");
    +				break;
     			}
     		}
     
    @@ -2703,21 +2735,23 @@ bce_get_media(struct bce_softc *sc)
     
     		sc->bce_flags |= BCE_NO_WOL_FLAG;
     
    -		/* 5708S, 5709S, and 5716S use a separate PHY for SerDes. */
    -		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) 
    -			sc->bce_phy_addr = 2;
    -
    -		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
    +		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
     			sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
     
    +		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
    +			/* 5708S/09S/16S use a separate PHY for SerDes. */
    +			sc->bce_phy_addr = 2;
    +
     			val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
     			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
    -				sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
    -				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb capable adapter\n");
    +				sc->bce_phy_flags |= 
    +				    BCE_PHY_2_5G_CAPABLE_FLAG;
    +				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb "
    +				    "capable adapter\n");
     			}
    -        }
    +		}
     	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
    -		   (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
    +	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
     		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
     
     bce_get_media_exit:
    @@ -2746,13 +2780,13 @@ bce_init_media(struct bce_softc *sc)
     		 * is done in mii layer.
     		 */
     
    -        /* Select auto-negotiation MMD of the PHY. */
    -        bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
    +		/* Select auto-negotiation MMD of the PHY. */
    +		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
     		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
     		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
     		    BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
     
    -        /* Select IEEE0 block of AN MMD (assumed in all brgphy(4) code). */
    +		/* Set IEEE0 block of AN MMD (assumed in brgphy(4) code). */
     		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
     		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
     	}
    @@ -2778,7 +2812,7 @@ bce_dma_free(struct bce_softc *sc)
     	/* Free, unmap, and destroy the status block. */
     	if (sc->status_block != NULL) {
     		bus_dmamem_free(
    -			sc->status_tag,
    +		   sc->status_tag,
     		    sc->status_block,
     		    sc->status_map);
     		sc->status_block = NULL;
    @@ -2786,7 +2820,7 @@ bce_dma_free(struct bce_softc *sc)
     
     	if (sc->status_map != NULL) {
     		bus_dmamap_unload(
    -			sc->status_tag,
    +		    sc->status_tag,
     		    sc->status_map);
     		bus_dmamap_destroy(sc->status_tag,
     		    sc->status_map);
    @@ -2802,7 +2836,7 @@ bce_dma_free(struct bce_softc *sc)
     	/* Free, unmap, and destroy the statistics block. */
     	if (sc->stats_block != NULL) {
     		bus_dmamem_free(
    -			sc->stats_tag,
    +		    sc->stats_tag,
     		    sc->stats_block,
     		    sc->stats_map);
     		sc->stats_block = NULL;
    @@ -2810,7 +2844,7 @@ bce_dma_free(struct bce_softc *sc)
     
     	if (sc->stats_map != NULL) {
     		bus_dmamap_unload(
    -			sc->stats_tag,
    +		    sc->stats_tag,
     		    sc->stats_map);
     		bus_dmamap_destroy(sc->stats_tag,
     		    sc->stats_map);
    @@ -2829,7 +2863,7 @@ bce_dma_free(struct bce_softc *sc)
     		for (i = 0; i < sc->ctx_pages; i++ ) {
     			if (sc->ctx_block[i] != NULL) {
     				bus_dmamem_free(
    -					sc->ctx_tag,
    +				    sc->ctx_tag,
     				    sc->ctx_block[i],
     				    sc->ctx_map[i]);
     				sc->ctx_block[i] = NULL;
    @@ -2837,10 +2871,10 @@ bce_dma_free(struct bce_softc *sc)
     
     			if (sc->ctx_map[i] != NULL) {
     				bus_dmamap_unload(
    -					sc->ctx_tag,
    -		    		sc->ctx_map[i]);
    +				    sc->ctx_tag,
    +				    sc->ctx_map[i]);
     				bus_dmamap_destroy(
    -					sc->ctx_tag,
    +				    sc->ctx_tag,
     				    sc->ctx_map[i]);
     				sc->ctx_map[i] = NULL;
     			}
    @@ -2858,7 +2892,7 @@ bce_dma_free(struct bce_softc *sc)
     	for (i = 0; i < TX_PAGES; i++ ) {
     		if (sc->tx_bd_chain[i] != NULL) {
     			bus_dmamem_free(
    -				sc->tx_bd_chain_tag,
    +			    sc->tx_bd_chain_tag,
     			    sc->tx_bd_chain[i],
     			    sc->tx_bd_chain_map[i]);
     			sc->tx_bd_chain[i] = NULL;
    @@ -2866,10 +2900,10 @@ bce_dma_free(struct bce_softc *sc)
     
     		if (sc->tx_bd_chain_map[i] != NULL) {
     			bus_dmamap_unload(
    -				sc->tx_bd_chain_tag,
    -		    	sc->tx_bd_chain_map[i]);
    +			    sc->tx_bd_chain_tag,
    +			    sc->tx_bd_chain_map[i]);
     			bus_dmamap_destroy(
    -				sc->tx_bd_chain_tag,
    +			    sc->tx_bd_chain_tag,
     			    sc->tx_bd_chain_map[i]);
     			sc->tx_bd_chain_map[i] = NULL;
     		}
    @@ -2886,7 +2920,7 @@ bce_dma_free(struct bce_softc *sc)
     	for (i = 0; i < RX_PAGES; i++ ) {
     		if (sc->rx_bd_chain[i] != NULL) {
     			bus_dmamem_free(
    -				sc->rx_bd_chain_tag,
    +			    sc->rx_bd_chain_tag,
     			    sc->rx_bd_chain[i],
     			    sc->rx_bd_chain_map[i]);
     			sc->rx_bd_chain[i] = NULL;
    @@ -2894,10 +2928,10 @@ bce_dma_free(struct bce_softc *sc)
     
     		if (sc->rx_bd_chain_map[i] != NULL) {
     			bus_dmamap_unload(
    -				sc->rx_bd_chain_tag,
    -		    	sc->rx_bd_chain_map[i]);
    +			    sc->rx_bd_chain_tag,
    +			    sc->rx_bd_chain_map[i]);
     			bus_dmamap_destroy(
    -				sc->rx_bd_chain_tag,
    +			    sc->rx_bd_chain_tag,
     			    sc->rx_bd_chain_map[i]);
     			sc->rx_bd_chain_map[i] = NULL;
     		}
    @@ -2915,7 +2949,7 @@ bce_dma_free(struct bce_softc *sc)
     	for (i = 0; i < PG_PAGES; i++ ) {
     		if (sc->pg_bd_chain[i] != NULL) {
     			bus_dmamem_free(
    -				sc->pg_bd_chain_tag,
    +			    sc->pg_bd_chain_tag,
     			    sc->pg_bd_chain[i],
     			    sc->pg_bd_chain_map[i]);
     			sc->pg_bd_chain[i] = NULL;
    @@ -2923,10 +2957,10 @@ bce_dma_free(struct bce_softc *sc)
     
     		if (sc->pg_bd_chain_map[i] != NULL) {
     			bus_dmamap_unload(
    -				sc->pg_bd_chain_tag,
    -		    	sc->pg_bd_chain_map[i]);
    +			    sc->pg_bd_chain_tag,
    +			    sc->pg_bd_chain_map[i]);
     			bus_dmamap_destroy(
    -				sc->pg_bd_chain_tag,
    +			    sc->pg_bd_chain_tag,
     			    sc->pg_bd_chain_map[i]);
     			sc->pg_bd_chain_map[i] = NULL;
     		}
    @@ -2944,9 +2978,9 @@ bce_dma_free(struct bce_softc *sc)
     	for (i = 0; i < TOTAL_TX_BD; i++) {
     		if (sc->tx_mbuf_map[i] != NULL) {
     			bus_dmamap_unload(sc->tx_mbuf_tag,
    -				sc->tx_mbuf_map[i]);
    +			    sc->tx_mbuf_map[i]);
     			bus_dmamap_destroy(sc->tx_mbuf_tag,
    -	 			sc->tx_mbuf_map[i]);
    +	 		    sc->tx_mbuf_map[i]);
     			sc->tx_mbuf_map[i] = NULL;
     		}
     	}
    @@ -2961,9 +2995,9 @@ bce_dma_free(struct bce_softc *sc)
     	for (i = 0; i < TOTAL_RX_BD; i++) {
     		if (sc->rx_mbuf_map[i] != NULL) {
     			bus_dmamap_unload(sc->rx_mbuf_tag,
    -				sc->rx_mbuf_map[i]);
    +			    sc->rx_mbuf_map[i]);
     			bus_dmamap_destroy(sc->rx_mbuf_tag,
    -	 			sc->rx_mbuf_map[i]);
    +	 		    sc->rx_mbuf_map[i]);
     			sc->rx_mbuf_map[i] = NULL;
     		}
     	}
    @@ -2979,9 +3013,9 @@ bce_dma_free(struct bce_softc *sc)
     	for (i = 0; i < TOTAL_PG_BD; i++) {
     		if (sc->pg_mbuf_map[i] != NULL) {
     			bus_dmamap_unload(sc->pg_mbuf_tag,
    -				sc->pg_mbuf_map[i]);
    +			    sc->pg_mbuf_map[i]);
     			bus_dmamap_destroy(sc->pg_mbuf_tag,
    -	 			sc->pg_mbuf_map[i]);
    +	 		    sc->pg_mbuf_map[i]);
     			sc->pg_mbuf_map[i] = NULL;
     		}
     	}
    @@ -3074,20 +3108,12 @@ bce_dma_alloc(device_t dev)
     	/*
     	 * Allocate the parent bus DMA tag appropriate for PCI.
     	 */
    -	if (bus_dma_tag_create(NULL,
    -			1,
    -			BCE_DMA_BOUNDARY,
    -			sc->max_bus_addr,
    -			BUS_SPACE_MAXADDR,
    -			NULL, NULL,
    -			MAXBSIZE,
    -			BUS_SPACE_UNRESTRICTED,
    -			BUS_SPACE_MAXSIZE_32BIT,
    -			0,
    -			NULL, NULL,
    -			&sc->parent_tag)) {
    +	if (bus_dma_tag_create(NULL, 1,	BCE_DMA_BOUNDARY,
    +	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
    +	    MAXBSIZE, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE_32BIT,
    +	    0, NULL, NULL, &sc->parent_tag)) {
     		BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
    @@ -3097,117 +3123,89 @@ bce_dma_alloc(device_t dev)
     	 * memory, map the memory into DMA space, and fetch the physical
     	 * address of the block.
     	 */
    -	if (bus_dma_tag_create(sc->parent_tag,
    -	    	BCE_DMA_ALIGN,
    -	    	BCE_DMA_BOUNDARY,
    -	    	sc->max_bus_addr,
    -	    	BUS_SPACE_MAXADDR,
    -	    	NULL, NULL,
    -	    	BCE_STATUS_BLK_SZ,
    -	    	1,
    -	    	BCE_STATUS_BLK_SZ,
    -	    	0,
    -	    	NULL, NULL,
    -	    	&sc->status_tag)) {
    -		BCE_PRINTF("%s(%d): Could not allocate status block DMA tag!\n",
    -			__FILE__, __LINE__);
    +	if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
    +	    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
    +	    NULL, NULL,	BCE_STATUS_BLK_SZ, 1, BCE_STATUS_BLK_SZ,
    +	    0, NULL, NULL, &sc->status_tag)) {
    +		BCE_PRINTF("%s(%d): Could not allocate status block "
    +		    "DMA tag!\n", __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
     
    -	if(bus_dmamem_alloc(sc->status_tag,
    -	    	(void **)&sc->status_block,
    -	    	BUS_DMA_NOWAIT,
    -	    	&sc->status_map)) {
    -		BCE_PRINTF("%s(%d): Could not allocate status block DMA memory!\n",
    -			__FILE__, __LINE__);
    +	if(bus_dmamem_alloc(sc->status_tag, (void **)&sc->status_block,
    +	    BUS_DMA_NOWAIT, &sc->status_map)) {
    +		BCE_PRINTF("%s(%d): Could not allocate status block "
    +		    "DMA memory!\n", __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
     
     	bzero((char *)sc->status_block, BCE_STATUS_BLK_SZ);
     
    -	error = bus_dmamap_load(sc->status_tag,
    -	    	sc->status_map,
    -	    	sc->status_block,
    -	    	BCE_STATUS_BLK_SZ,
    -	    	bce_dma_map_addr,
    -	    	&sc->status_block_paddr,
    -	    	BUS_DMA_NOWAIT);
    +	error = bus_dmamap_load(sc->status_tag,	sc->status_map,
    +	    sc->status_block, BCE_STATUS_BLK_SZ, bce_dma_map_addr,
    +	    &sc->status_block_paddr, BUS_DMA_NOWAIT);
     
     	if (error) {
    -		BCE_PRINTF("%s(%d): Could not map status block DMA memory!\n",
    -			__FILE__, __LINE__);
    +		BCE_PRINTF("%s(%d): Could not map status block "
    +		    "DMA memory!\n", __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
     
     	DBPRINT(sc, BCE_INFO, "%s(): status_block_paddr = 0x%jX\n",
    -		__FUNCTION__, (uintmax_t) sc->status_block_paddr);
    +	    __FUNCTION__, (uintmax_t) sc->status_block_paddr);
     
     	/*
     	 * Create a DMA tag for the statistics block, allocate and clear the
     	 * memory, map the memory into DMA space, and fetch the physical
     	 * address of the block.
     	 */
    -	if (bus_dma_tag_create(sc->parent_tag,
    -	    	BCE_DMA_ALIGN,
    -	    	BCE_DMA_BOUNDARY,
    -	    	sc->max_bus_addr,
    -	    	BUS_SPACE_MAXADDR,
    -	    	NULL, NULL,
    -	    	BCE_STATS_BLK_SZ,
    -	    	1,
    -	    	BCE_STATS_BLK_SZ,
    -	    	0,
    -	    	NULL, NULL,
    -	    	&sc->stats_tag)) {
    -		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA tag!\n",
    -			__FILE__, __LINE__);
    +	if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
    +	    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
    +	    NULL, NULL,	BCE_STATS_BLK_SZ, 1, BCE_STATS_BLK_SZ,
    +	    0, NULL, NULL, &sc->stats_tag)) {
    +		BCE_PRINTF("%s(%d): Could not allocate statistics block "
    +		    "DMA tag!\n", __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
     
    -	if (bus_dmamem_alloc(sc->stats_tag,
    -	    	(void **)&sc->stats_block,
    -	    	BUS_DMA_NOWAIT,
    -	    	&sc->stats_map)) {
    -		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA memory!\n",
    -			__FILE__, __LINE__);
    +	if (bus_dmamem_alloc(sc->stats_tag, (void **)&sc->stats_block,
    +	    BUS_DMA_NOWAIT,	&sc->stats_map)) {
    +		BCE_PRINTF("%s(%d): Could not allocate statistics block "
    +		    "DMA memory!\n", __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
     
     	bzero((char *)sc->stats_block, BCE_STATS_BLK_SZ);
     
    -	error = bus_dmamap_load(sc->stats_tag,
    -	    	sc->stats_map,
    -	    	sc->stats_block,
    -	    	BCE_STATS_BLK_SZ,
    -	    	bce_dma_map_addr,
    -	    	&sc->stats_block_paddr,
    -	    	BUS_DMA_NOWAIT);
    +	error = bus_dmamap_load(sc->stats_tag, sc->stats_map,
    +	    sc->stats_block, BCE_STATS_BLK_SZ, bce_dma_map_addr,
    +	    &sc->stats_block_paddr, BUS_DMA_NOWAIT);
     
     	if(error) {
    -		BCE_PRINTF("%s(%d): Could not map statistics block DMA memory!\n",
    -			__FILE__, __LINE__);
    +		BCE_PRINTF("%s(%d): Could not map statistics block "
    +		    "DMA memory!\n", __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
     
     	DBPRINT(sc, BCE_INFO, "%s(): stats_block_paddr = 0x%jX\n",
    -		__FUNCTION__, (uintmax_t) sc->stats_block_paddr);
    +	    __FUNCTION__, (uintmax_t) sc->stats_block_paddr);
     
     	/* BCM5709 uses host memory as cache for context memory. */
     	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    -		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
    +	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
     		sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
     		if (sc->ctx_pages == 0)
     			sc->ctx_pages = 1;
     
     		DBRUNIF((sc->ctx_pages > 512),
    -			BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
    -				__FILE__, __LINE__, sc->ctx_pages));
    +		    BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
    +		    __FILE__, __LINE__, sc->ctx_pages));
     
     		/*
     		 * Create a DMA tag for the context pages,
    @@ -3215,20 +3213,12 @@ bce_dma_alloc(device_t dev)
     		 * memory into DMA space, and fetch the
     		 * physical address of the block.
     		 */
    -		if(bus_dma_tag_create(sc->parent_tag,
    -			BCM_PAGE_SIZE,
    -		    BCE_DMA_BOUNDARY,
    -			sc->max_bus_addr,
    -			BUS_SPACE_MAXADDR,
    -			NULL, NULL,
    -			BCM_PAGE_SIZE,
    -			1,
    -			BCM_PAGE_SIZE,
    -			0,
    -			NULL, NULL,
    -			&sc->ctx_tag)) {
    +		if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
    +		    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
    +		    NULL, NULL,	BCM_PAGE_SIZE, 1, BCM_PAGE_SIZE,
    +		    0, NULL, NULL, &sc->ctx_tag)) {
     			BCE_PRINTF("%s(%d): Could not allocate CTX DMA tag!\n",
    -				__FILE__, __LINE__);
    +			    __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
    @@ -3236,34 +3226,30 @@ bce_dma_alloc(device_t dev)
     		for (i = 0; i < sc->ctx_pages; i++) {
     
     			if(bus_dmamem_alloc(sc->ctx_tag,
    -		    		(void **)&sc->ctx_block[i],
    -	    		BUS_DMA_NOWAIT,
    -		    	&sc->ctx_map[i])) {
    +			    (void **)&sc->ctx_block[i],
    +			    BUS_DMA_NOWAIT,
    +			    &sc->ctx_map[i])) {
     				BCE_PRINTF("%s(%d): Could not allocate CTX "
    -					"DMA memory!\n", __FILE__, __LINE__);
    +				    "DMA memory!\n", __FILE__, __LINE__);
     				rc = ENOMEM;
     				goto bce_dma_alloc_exit;
     			}
     
     			bzero((char *)sc->ctx_block[i], BCM_PAGE_SIZE);
     
    -			error = bus_dmamap_load(sc->ctx_tag,
    -	    		sc->ctx_map[i],
    -	    		sc->ctx_block[i],
    -		    	BCM_PAGE_SIZE,
    -		    	bce_dma_map_addr,
    -	    		&sc->ctx_paddr[i],
    -	    		BUS_DMA_NOWAIT);
    +			error = bus_dmamap_load(sc->ctx_tag, sc->ctx_map[i],
    +			    sc->ctx_block[i], BCM_PAGE_SIZE, bce_dma_map_addr,
    +			    &sc->ctx_paddr[i], BUS_DMA_NOWAIT);
     
     			if (error) {
    -				BCE_PRINTF("%s(%d): Could not map CTX DMA memory!\n",
    -					__FILE__, __LINE__);
    +				BCE_PRINTF("%s(%d): Could not map CTX "
    +				    "DMA memory!\n", __FILE__, __LINE__);
     				rc = ENOMEM;
     				goto bce_dma_alloc_exit;
     			}
     
     			DBPRINT(sc, BCE_INFO, "%s(): ctx_paddr[%d] = 0x%jX\n",
    -				__FUNCTION__, i, (uintmax_t) sc->ctx_paddr[i]);
    +			    __FUNCTION__, i, (uintmax_t) sc->ctx_paddr[i]);
     		}
     	}
     
    @@ -3272,53 +3258,41 @@ bce_dma_alloc(device_t dev)
     	 * allocate and clear the  memory, and fetch the
     	 * physical address of the block.
     	 */
    -	if(bus_dma_tag_create(sc->parent_tag,
    -			BCM_PAGE_SIZE,
    -		    BCE_DMA_BOUNDARY,
    -			sc->max_bus_addr,
    -			BUS_SPACE_MAXADDR,
    -			NULL, NULL,
    -			BCE_TX_CHAIN_PAGE_SZ,
    -			1,
    -			BCE_TX_CHAIN_PAGE_SZ,
    -			0,
    -			NULL, NULL,
    -			&sc->tx_bd_chain_tag)) {
    -		BCE_PRINTF("%s(%d): Could not allocate TX descriptor chain DMA tag!\n",
    -			__FILE__, __LINE__);
    +	if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, BCE_DMA_BOUNDARY,
    +	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
    +	    BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ, 0,
    +	    NULL, NULL,	&sc->tx_bd_chain_tag)) {
    +		BCE_PRINTF("%s(%d): Could not allocate TX descriptor chain "
    +		    "DMA tag!\n", __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
     
     	for (i = 0; i < TX_PAGES; i++) {
     
    -		if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
    -	    		(void **)&sc->tx_bd_chain[i],
    -	    		BUS_DMA_NOWAIT,
    -		    	&sc->tx_bd_chain_map[i])) {
    +		if(bus_dmamem_alloc(sc->tx_bd_chain_tag, 
    +		    (void **)&sc->tx_bd_chain[i], BUS_DMA_NOWAIT,
    +		    &sc->tx_bd_chain_map[i])) {
     			BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
    -				"chain DMA memory!\n", __FILE__, __LINE__);
    +			    "chain DMA memory!\n", __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
     
     		error = bus_dmamap_load(sc->tx_bd_chain_tag,
    -	    		sc->tx_bd_chain_map[i],
    -	    		sc->tx_bd_chain[i],
    -		    	BCE_TX_CHAIN_PAGE_SZ,
    -		    	bce_dma_map_addr,
    -	    		&sc->tx_bd_chain_paddr[i],
    -	    		BUS_DMA_NOWAIT);
    +		    sc->tx_bd_chain_map[i], sc->tx_bd_chain[i],
    +		    BCE_TX_CHAIN_PAGE_SZ, bce_dma_map_addr,
    +		    &sc->tx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
     
     		if (error) {
    -			BCE_PRINTF("%s(%d): Could not map TX descriptor chain DMA memory!\n",
    -				__FILE__, __LINE__);
    +			BCE_PRINTF("%s(%d): Could not map TX descriptor "
    +			    "chain DMA memory!\n", __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
     
     		DBPRINT(sc, BCE_INFO, "%s(): tx_bd_chain_paddr[%d] = 0x%jX\n",
    -			__FUNCTION__, i, (uintmax_t) sc->tx_bd_chain_paddr[i]);
    +		    __FUNCTION__, i, (uintmax_t) sc->tx_bd_chain_paddr[i]);
     	}
     
     	/* Check the required size before mapping to conserve resources. */
    @@ -3333,20 +3307,11 @@ bce_dma_alloc(device_t dev)
     	}
     
     	/* Create a DMA tag for TX mbufs. */
    -	if (bus_dma_tag_create(sc->parent_tag,
    -			1,
    -			BCE_DMA_BOUNDARY,
    -			sc->max_bus_addr,
    -			BUS_SPACE_MAXADDR,
    -			NULL, NULL,
    -			max_size,
    -			max_segments,
    -			max_seg_size,
    -			0,
    -			NULL, NULL,
    -			&sc->tx_mbuf_tag)) {
    +	if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
    +	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
    +	    max_segments, max_seg_size,	0, NULL, NULL, &sc->tx_mbuf_tag)) {
     		BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
    @@ -3355,8 +3320,8 @@ bce_dma_alloc(device_t dev)
     	for (i = 0; i < TOTAL_TX_BD; i++) {
     		if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
     			&sc->tx_mbuf_map[i])) {
    -			BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA map!\n",
    -				__FILE__, __LINE__);
    +			BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA "
    +			    "map!\n", __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
    @@ -3367,20 +3332,13 @@ bce_dma_alloc(device_t dev)
     	 * allocate and clear the memory, and fetch the physical
     	 * address of the blocks.
     	 */
    -	if (bus_dma_tag_create(sc->parent_tag,
    -			BCM_PAGE_SIZE,
    -			BCE_DMA_BOUNDARY,
    -			BUS_SPACE_MAXADDR,
    -			sc->max_bus_addr,
    -			NULL, NULL,
    -			BCE_RX_CHAIN_PAGE_SZ,
    -			1,
    -			BCE_RX_CHAIN_PAGE_SZ,
    -			0,
    -			NULL, NULL,
    -			&sc->rx_bd_chain_tag)) {
    -		BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain DMA tag!\n",
    -			__FILE__, __LINE__);
    +	if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
    +			BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR,
    +			sc->max_bus_addr, NULL, NULL,
    +			BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ,
    +			0, NULL, NULL, &sc->rx_bd_chain_tag)) {
    +		BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
    +		    "DMA tag!\n", __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
    @@ -3388,11 +3346,10 @@ bce_dma_alloc(device_t dev)
     	for (i = 0; i < RX_PAGES; i++) {
     
     		if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
    -	    		(void **)&sc->rx_bd_chain[i],
    -	    		BUS_DMA_NOWAIT,
    -		    	&sc->rx_bd_chain_map[i])) {
    -			BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
    -				"DMA memory!\n", __FILE__, __LINE__);
    +		    (void **)&sc->rx_bd_chain[i], BUS_DMA_NOWAIT,
    +		    &sc->rx_bd_chain_map[i])) {
    +			BCE_PRINTF("%s(%d): Could not allocate RX descriptor "
    +			    "chain DMA memory!\n", __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
    @@ -3400,22 +3357,19 @@ bce_dma_alloc(device_t dev)
     		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
     
     		error = bus_dmamap_load(sc->rx_bd_chain_tag,
    -	    		sc->rx_bd_chain_map[i],
    -	    		sc->rx_bd_chain[i],
    -		    	BCE_RX_CHAIN_PAGE_SZ,
    -		    	bce_dma_map_addr,
    -	    		&sc->rx_bd_chain_paddr[i],
    -	    		BUS_DMA_NOWAIT);
    +		    sc->rx_bd_chain_map[i], sc->rx_bd_chain[i],
    +		    BCE_RX_CHAIN_PAGE_SZ, bce_dma_map_addr,
    +		    &sc->rx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
     
     		if (error) {
    -			BCE_PRINTF("%s(%d): Could not map RX descriptor chain DMA memory!\n",
    -				__FILE__, __LINE__);
    +			BCE_PRINTF("%s(%d): Could not map RX descriptor "
    +			    "chain DMA memory!\n", __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
     
     		DBPRINT(sc, BCE_INFO, "%s(): rx_bd_chain_paddr[%d] = 0x%jX\n",
    -			__FUNCTION__, i, (uintmax_t) sc->rx_bd_chain_paddr[i]);
    +		    __FUNCTION__, i, (uintmax_t) sc->rx_bd_chain_paddr[i]);
     	}
     
     	/*
    @@ -3430,23 +3384,14 @@ bce_dma_alloc(device_t dev)
     	max_segments = 1;
     
     	DBPRINT(sc, BCE_INFO, "%s(): Creating rx_mbuf_tag (max size = 0x%jX "
    -		"max segments = %d, max segment size = 0x%jX)\n", __FUNCTION__,
    -		(uintmax_t) max_size, max_segments, (uintmax_t) max_seg_size);
    +	    "max segments = %d, max segment size = 0x%jX)\n", __FUNCTION__,
    +	    (uintmax_t) max_size, max_segments, (uintmax_t) max_seg_size);
     
    -	if (bus_dma_tag_create(sc->parent_tag,
    -			1,
    -			BCE_DMA_BOUNDARY,
    -			sc->max_bus_addr,
    -			BUS_SPACE_MAXADDR,
    -			NULL, NULL,
    -			max_size,
    -			max_segments,
    -			max_seg_size,
    -			0,
    -			NULL, NULL,
    -	    	&sc->rx_mbuf_tag)) {
    +	if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
    +	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
    +	   max_segments, max_seg_size, 0, NULL, NULL, &sc->rx_mbuf_tag)) {
     		BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
    @@ -3454,9 +3399,9 @@ bce_dma_alloc(device_t dev)
     	/* Create DMA maps for the RX mbuf clusters. */
     	for (i = 0; i < TOTAL_RX_BD; i++) {
     		if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
    -				&sc->rx_mbuf_map[i])) {
    -			BCE_PRINTF("%s(%d): Unable to create RX mbuf DMA map!\n",
    -				__FILE__, __LINE__);
    +		    &sc->rx_mbuf_map[i])) {
    +			BCE_PRINTF("%s(%d): Unable to create RX mbuf "
    +			    "DMA map!\n", __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
    @@ -3468,20 +3413,12 @@ bce_dma_alloc(device_t dev)
     	 * allocate and clear the memory, and fetch the physical
     	 * address of the blocks.
     	 */
    -	if (bus_dma_tag_create(sc->parent_tag,
    -			BCM_PAGE_SIZE,
    -			BCE_DMA_BOUNDARY,
    -			BUS_SPACE_MAXADDR,
    -			sc->max_bus_addr,
    -			NULL, NULL,
    -			BCE_PG_CHAIN_PAGE_SZ,
    -			1,
    -			BCE_PG_CHAIN_PAGE_SZ,
    -			0,
    -			NULL, NULL,
    -			&sc->pg_bd_chain_tag)) {
    -		BCE_PRINTF("%s(%d): Could not allocate page descriptor chain DMA tag!\n",
    -			__FILE__, __LINE__);
    +	if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
    +	    BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
    +	    NULL, NULL,	BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
    +	    0, NULL, NULL, &sc->pg_bd_chain_tag)) {
    +		BCE_PRINTF("%s(%d): Could not allocate page descriptor "
    +		    "chain DMA tag!\n",	__FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
    @@ -3489,56 +3426,44 @@ bce_dma_alloc(device_t dev)
     	for (i = 0; i < PG_PAGES; i++) {
     
     		if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
    -	    		(void **)&sc->pg_bd_chain[i],
    -	    		BUS_DMA_NOWAIT,
    -		    	&sc->pg_bd_chain_map[i])) {
    -			BCE_PRINTF("%s(%d): Could not allocate page descriptor chain "
    -				"DMA memory!\n", __FILE__, __LINE__);
    +		    (void **)&sc->pg_bd_chain[i], BUS_DMA_NOWAIT,
    +		    &sc->pg_bd_chain_map[i])) {
    +			BCE_PRINTF("%s(%d): Could not allocate page "
    +			    "descriptor chain DMA memory!\n", 
    +			    __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
     
     		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
     
    -		error = bus_dmamap_load(sc->pg_bd_chain_tag,
    -	    		sc->pg_bd_chain_map[i],
    -	    		sc->pg_bd_chain[i],
    -		    	BCE_PG_CHAIN_PAGE_SZ,
    -		    	bce_dma_map_addr,
    -	    		&sc->pg_bd_chain_paddr[i],
    -	    		BUS_DMA_NOWAIT);
    +		error = bus_dmamap_load(sc->pg_bd_chain_tag, 
    +		    sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
    +		    BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
    +		    &sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
     
     		if (error) {
    -			BCE_PRINTF("%s(%d): Could not map page descriptor chain DMA memory!\n",
    -				__FILE__, __LINE__);
    +			BCE_PRINTF("%s(%d): Could not map page descriptor "
    +			    "chain DMA memory!\n", __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
     
     		DBPRINT(sc, BCE_INFO, "%s(): pg_bd_chain_paddr[%d] = 0x%jX\n",
    -			__FUNCTION__, i, (uintmax_t) sc->pg_bd_chain_paddr[i]);
    +		    __FUNCTION__, i, (uintmax_t) sc->pg_bd_chain_paddr[i]);
     	}
     
     	/*
     	 * Create a DMA tag for page mbufs.
     	 */
     	max_size = max_seg_size = ((sc->pg_bd_mbuf_alloc_size < MCLBYTES) ?
    -		MCLBYTES : sc->pg_bd_mbuf_alloc_size);
    +	    MCLBYTES : sc->pg_bd_mbuf_alloc_size);
     
    -	if (bus_dma_tag_create(sc->parent_tag,
    -			1,
    -			BCE_DMA_BOUNDARY,
    -			sc->max_bus_addr,
    -			BUS_SPACE_MAXADDR,
    -			NULL, NULL,
    -			max_size,
    -			1,
    -			max_seg_size,
    -			0,
    -			NULL, NULL,
    -	    	&sc->pg_mbuf_tag)) {
    -		BCE_PRINTF("%s(%d): Could not allocate page mbuf DMA tag!\n",
    -			__FILE__, __LINE__);
    +	if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
    +	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
    +	    max_size, 1, max_seg_size, 0, NULL, NULL, &sc->pg_mbuf_tag)) {
    +		BCE_PRINTF("%s(%d): Could not allocate page mbuf "
    +		    "DMA tag!\n", __FILE__, __LINE__);
     		rc = ENOMEM;
     		goto bce_dma_alloc_exit;
     	}
    @@ -3546,9 +3471,9 @@ bce_dma_alloc(device_t dev)
     	/* Create DMA maps for the page mbuf clusters. */
     	for (i = 0; i < TOTAL_PG_BD; i++) {
     		if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
    -				&sc->pg_mbuf_map[i])) {
    -			BCE_PRINTF("%s(%d): Unable to create page mbuf DMA map!\n",
    -				__FILE__, __LINE__);
    +		    &sc->pg_mbuf_map[i])) {
    +			BCE_PRINTF("%s(%d): Unable to create page mbuf "
    +			    "DMA map!\n", __FILE__, __LINE__);
     			rc = ENOMEM;
     			goto bce_dma_alloc_exit;
     		}
    @@ -3589,7 +3514,7 @@ bce_release_resources(struct bce_softc *sc)
     	if (sc->bce_res_irq != NULL) {
     		DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
     		bus_release_resource(dev, SYS_RES_IRQ, sc->bce_irq_rid,
    -			sc->bce_res_irq);
    +		    sc->bce_res_irq);
     	}
     
     	if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
    @@ -3599,7 +3524,8 @@ bce_release_resources(struct bce_softc *sc)
     
     	if (sc->bce_res_mem != NULL) {
     		DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
    -		bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->bce_res_mem);
    +		    bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), 
    +		    sc->bce_res_mem);
     	}
     
     	if (sc->bce_ifp != NULL) {
    @@ -3632,7 +3558,7 @@ bce_fw_sync(struct bce_softc *sc, u32 msg_data)
     	DBENTER(BCE_VERBOSE_RESET);
     
     	/* Don't waste any time if we've timed out before. */
    -	if (sc->bce_fw_timed_out) {
    +	if (sc->bce_fw_timed_out == TRUE) {
     		rc = EBUSY;
     		goto bce_fw_sync_exit;
     	}
    @@ -3641,8 +3567,8 @@ bce_fw_sync(struct bce_softc *sc, u32 msg_data)
     	sc->bce_fw_wr_seq++;
     	msg_data |= sc->bce_fw_wr_seq;
     
    - 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = 0x%08X\n",
    - 		msg_data);
    + 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = "
    +	    "0x%08X\n",	msg_data);
     
     	/* Send the message to the bootcode driver mailbox. */
     	bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
    @@ -3658,18 +3584,17 @@ bce_fw_sync(struct bce_softc *sc, u32 msg_data)
     
     	/* If we've timed out, tell the bootcode that we've stopped waiting. */
     	if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
    -		((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
    +	    ((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
     
     		BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
    -			"msg_data = 0x%08X\n",
    -			__FILE__, __LINE__, msg_data);
    +		    "msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
     
     		msg_data &= ~BCE_DRV_MSG_CODE;
     		msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
     
     		bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
     
    -		sc->bce_fw_timed_out = 1;
    +		sc->bce_fw_timed_out = TRUE;
     		rc = EBUSY;
     	}
     
    @@ -3797,9 +3722,9 @@ bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
     		}
     	}
     
    -    /* Clear the pre-fetch instruction and set the FW start address. */
    -    REG_WR_IND(sc, cpu_reg->inst, 0);
    -    REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
    +	/* Clear the pre-fetch instruction and set the FW start address. */
    +	REG_WR_IND(sc, cpu_reg->inst, 0);
    +	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
     
     	DBEXIT(BCE_VERBOSE_RESET);
     }
    @@ -3843,11 +3768,11 @@ bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
     
     	DBENTER(BCE_VERBOSE_RESET);
     
    -    /* Halt the CPU. */
    -    val = REG_RD_IND(sc, cpu_reg->mode);
    -    val |= cpu_reg->mode_value_halt;
    -    REG_WR_IND(sc, cpu_reg->mode, val);
    -    REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
    +	/* Halt the CPU. */
    +	val = REG_RD_IND(sc, cpu_reg->mode);
    +	val |= cpu_reg->mode_value_halt;
    +	REG_WR_IND(sc, cpu_reg->mode, val);
    +	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
     
     	DBEXIT(BCE_VERBOSE_RESET);
     }
    @@ -4175,7 +4100,7 @@ bce_init_tpat_cpu(struct bce_softc *sc)
     
     	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
     	bce_load_cpu_fw(sc, &cpu_reg, &fw);
    -    bce_start_cpu(sc, &cpu_reg);
    +	bce_start_cpu(sc, &cpu_reg);
     
     	DBEXIT(BCE_VERBOSE_RESET);
     }
    @@ -4273,7 +4198,7 @@ bce_init_cp_cpu(struct bce_softc *sc)
     
     	DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
     	bce_load_cpu_fw(sc, &cpu_reg, &fw);
    -    bce_start_cpu(sc, &cpu_reg);
    +	bce_start_cpu(sc, &cpu_reg);
     
     	DBEXIT(BCE_VERBOSE_RESET);
     }
    @@ -4371,7 +4296,7 @@ bce_init_com_cpu(struct bce_softc *sc)
     
     	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
     	bce_load_cpu_fw(sc, &cpu_reg, &fw);
    -    bce_start_cpu(sc, &cpu_reg);
    +	bce_start_cpu(sc, &cpu_reg);
     
     	DBEXIT(BCE_VERBOSE_RESET);
     }
    @@ -4437,7 +4362,7 @@ bce_init_ctx(struct bce_softc *sc)
     	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
     
     	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    -		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
    +	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
     		int i, retry_cnt = CTX_INIT_RETRY_COUNT;
     		u32 val;
     
    @@ -4448,7 +4373,8 @@ bce_init_ctx(struct bce_softc *sc)
     		 * in host memory so prepare the host memory
     		 * for access.
     		 */
    -		val = BCE_CTX_COMMAND_ENABLED | BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
    +		val = BCE_CTX_COMMAND_ENABLED | 
    +		    BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
     		val |= (BCM_PAGE_BITS - 8) << 16;
     		REG_WR(sc, BCE_CTX_COMMAND, val);
     
    @@ -4462,33 +4388,34 @@ bce_init_ctx(struct bce_softc *sc)
     
     		/* ToDo: Consider returning an error here. */
     		DBRUNIF((val & BCE_CTX_COMMAND_MEM_INIT),
    -			BCE_PRINTF("%s(): Context memory initialization failed!\n",
    -			__FUNCTION__));
    +		    BCE_PRINTF("%s(): Context memory initialization "
    +		    "failed!\n", __FUNCTION__));
     
     		for (i = 0; i < sc->ctx_pages; i++) {
     			int j;
     
    -			/* Set the physical address of the context memory cache. */
    +			/* Set the physical address of the context memory. */
     			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
    -				BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
    -				BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
    +			    BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
    +			    BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
     			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
    -				BCE_ADDR_HI(sc->ctx_paddr[i]));
    +			    BCE_ADDR_HI(sc->ctx_paddr[i]));
     			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
    -				BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
    +			    BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
     
    -			/* Verify that the context memory write was successful. */
    +			/* Verify the context memory write was successful. */
     			for (j = 0; j < retry_cnt; j++) {
     				val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
    -				if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
    +				if ((val & 
    +				    BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
     					break;
     				DELAY(5);
     			}
     
     			/* ToDo: Consider returning an error here. */
     			DBRUNIF((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ),
    -				BCE_PRINTF("%s(): Failed to initialize context page %d!\n",
    -				__FUNCTION__, i));
    +			    BCE_PRINTF("%s(): Failed to initialize "
    +			    "context page %d!\n", __FUNCTION__, i));
     		}
     	} else {
     		u32 vcid_addr, offset;
    @@ -4509,9 +4436,9 @@ bce_init_ctx(struct bce_softc *sc)
     			REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
     			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
     
    -            for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
    -                CTX_WR(sc, 0x00, offset, 0);
    -            }
    +			for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
    +				CTX_WR(sc, 0x00, offset, 0);
    +			}
     
     			REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
     			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
    @@ -4654,7 +4581,7 @@ bce_stop(struct bce_softc *sc)
     	ifp->if_flags = itmp;
     	sc->watchdog_timer = 0;
     
    -	sc->bce_link = 0;
    +	sc->bce_link_up = FALSE;
     
     	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
     
    @@ -4691,7 +4618,8 @@ bce_reset(struct bce_softc *sc, u32 reset_code)
     	}
     
     	/* Assume bootcode is running. */
    -	sc->bce_fw_timed_out = 0;
    +	sc->bce_fw_timed_out = FALSE;
    +	sc->bce_drv_cardiac_arrest = FALSE;
     
     	/* Give the firmware a chance to prepare for the reset. */
     	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
    @@ -4751,7 +4679,8 @@ bce_reset(struct bce_softc *sc, u32 reset_code)
     	}
     
     	/* Just completed a reset, assume that firmware is running again. */
    -	sc->bce_fw_timed_out = 0;
    +	sc->bce_fw_timed_out = FALSE;
    +	sc->bce_drv_cardiac_arrest = FALSE;
     
     	/* Wait for the firmware to finish its initialization. */
     	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
    @@ -4807,9 +4736,9 @@ bce_chipinit(struct bce_softc *sc)
     
     	/* Enable the RX_V2P and Context state machines before access. */
     	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
    -	       BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
    -	       BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
    -	       BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
    +	    BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
    +	    BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
    +	    BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
     
     	/* Initialize context mapping and zero out the quick contexts. */
     	bce_init_ctx(sc);
    @@ -4817,11 +4746,11 @@ bce_chipinit(struct bce_softc *sc)
     	/* Initialize the on-boards CPUs */
     	bce_init_cpus(sc);
     
    -    /* Enable management frames (NC-SI) to flow to the MCP. */
    -    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    -        val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
    -        REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
    -    }
    +	/* Enable management frames (NC-SI) to flow to the MCP. */
    +	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    +		val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
    +		REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
    +	}
     
     	/* Prepare NVRAM for access. */
     	if (bce_init_nvram(sc)) {
    @@ -4899,56 +4828,56 @@ bce_blockinit(struct bce_softc *sc)
     
     	/* Program the physical address of the status block. */
     	REG_WR(sc, BCE_HC_STATUS_ADDR_L,
    -		BCE_ADDR_LO(sc->status_block_paddr));
    +	    BCE_ADDR_LO(sc->status_block_paddr));
     	REG_WR(sc, BCE_HC_STATUS_ADDR_H,
    -		BCE_ADDR_HI(sc->status_block_paddr));
    +	    BCE_ADDR_HI(sc->status_block_paddr));
     
     	/* Program the physical address of the statistics block. */
     	REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
    -		BCE_ADDR_LO(sc->stats_block_paddr));
    +	    BCE_ADDR_LO(sc->stats_block_paddr));
     	REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
    -		BCE_ADDR_HI(sc->stats_block_paddr));
    +	    BCE_ADDR_HI(sc->stats_block_paddr));
     
     	/* Program various host coalescing parameters. */
     	REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
    -		(sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
    +	    (sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
     	REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
    -		(sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
    +	    (sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
     	REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
    -		(sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
    +	    (sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
     	REG_WR(sc, BCE_HC_TX_TICKS,
    -		(sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
    +	    (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
     	REG_WR(sc, BCE_HC_RX_TICKS,
    -		(sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
    +	    (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
     	REG_WR(sc, BCE_HC_COM_TICKS,
    -		(sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
    +	    (sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
     	REG_WR(sc, BCE_HC_CMD_TICKS,
    -		(sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
    +	    (sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
     	REG_WR(sc, BCE_HC_STATS_TICKS,
    -		(sc->bce_stats_ticks & 0xffff00));
    +	    (sc->bce_stats_ticks & 0xffff00));
     	REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
     
     	/* Configure the Host Coalescing block. */
     	val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
    -		      BCE_HC_CONFIG_COLLECT_STATS;
    +	    BCE_HC_CONFIG_COLLECT_STATS;
     
     #if 0
     	/* ToDo: Add MSI-X support. */
     	if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
     		u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
    -			   BCE_HC_SB_CONFIG_1;
    +		    BCE_HC_SB_CONFIG_1;
     
     		REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
     
     		REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
    -			BCE_HC_SB_CONFIG_1_ONE_SHOT);
    +		    BCE_HC_SB_CONFIG_1_ONE_SHOT);
     
     		REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
    -			(sc->tx_quick_cons_trip_int << 16) |
    -			 sc->tx_quick_cons_trip);
    +		    (sc->tx_quick_cons_trip_int << 16) |
    +		     sc->tx_quick_cons_trip);
     
     		REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
    -			(sc->tx_ticks_int << 16) | sc->tx_ticks);
    +		    (sc->tx_ticks_int << 16) | sc->tx_ticks);
     
     		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
     	}
    @@ -4975,49 +4904,53 @@ bce_blockinit(struct bce_softc *sc)
     	reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
     
     	DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
    -		BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
    -			__FILE__, __LINE__);
    -		reg = 0);
    +	    BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
    +	    __FILE__, __LINE__);
    +	    reg = 0);
     
     	if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
     	    BCE_DEV_INFO_SIGNATURE_MAGIC) {
     		BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
    -			"Expected: 08%08X\n", __FILE__, __LINE__,
    -			(reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
    -			BCE_DEV_INFO_SIGNATURE_MAGIC);
    +		    "Expected: 08%08X\n", __FILE__, __LINE__,
    +		    (reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
    +		    BCE_DEV_INFO_SIGNATURE_MAGIC);
     		rc = ENODEV;
     		goto bce_blockinit_exit;
     	}
     
     	/* Enable DMA */
     	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    -		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
    +	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
     		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
     		val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
     		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
     	}
     
    -	/* Allow bootcode to apply any additional fixes before enabling MAC. */
    -	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | BCE_DRV_MSG_CODE_RESET);
    +	/* Allow bootcode to apply additional fixes before enabling MAC. */
    +	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | 
    +	    BCE_DRV_MSG_CODE_RESET);
     
     	/* Enable link state change interrupt generation. */
     	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
     
    -    /* Enable the RXP. */
    -    bce_start_rxp_cpu(sc);
    +	/* Enable the RXP. */
    +	bce_start_rxp_cpu(sc);
     
    -    /* Disable management frames (NC-SI) from flowing to the MCP. */
    -    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    -        val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) & ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
    -        REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
    -    }
    +	/* Disable management frames (NC-SI) from flowing to the MCP. */
    +	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    +		val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) & 
    +		    ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
    +		REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
    +	}
     
     	/* Enable all remaining blocks in the MAC. */
    -	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
    -		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
    -		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT_XI);
    +	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    +	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
    +		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 
    +		    BCE_MISC_ENABLE_DEFAULT_XI);
     	else
    -		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
    +		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 
    +		    BCE_MISC_ENABLE_DEFAULT);
     
     	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
     	DELAY(20);
    @@ -5040,7 +4973,7 @@ bce_blockinit_exit:
     /****************************************************************************/
     static int
     bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
    -	u16 *chain_prod, u32 *prod_bseq)
    +    u16 *chain_prod, u32 *prod_bseq)
     {
     	bus_dmamap_t map;
     	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
    @@ -5058,8 +4991,9 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     		BCE_PRINTF("%s(%d): RX producer out of range: 0x%04X > 0x%04X\n",
     		__FILE__, __LINE__, *chain_prod, (u16) MAX_RX_BD));
     
    -	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, chain_prod = 0x%04X, "
    -		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
    +	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
    +	    "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__,
    +	    *prod, *chain_prod, *prod_bseq);
     
     	/* Update some debug statistic counters */
     	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
    @@ -5071,10 +5005,10 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     
     		/* Simulate an mbuf allocation failure. */
     		DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
    -			sc->mbuf_alloc_failed_count++;
    -			sc->mbuf_alloc_failed_sim_count++;
    -			rc = ENOBUFS;
    -			goto bce_get_rx_buf_exit);
    +		    sc->mbuf_alloc_failed_count++;
    +		    sc->mbuf_alloc_failed_sim_count++;
    +		    rc = ENOBUFS;
    +		    goto bce_get_rx_buf_exit);
     
     		/* This is a new mbuf allocation. */
     #ifdef BCE_JUMBO_HDRSPLIT
    @@ -5083,7 +5017,8 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     		if (sc->rx_bd_mbuf_alloc_size <= MCLBYTES)
     			m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
     		else
    -			m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, sc->rx_bd_mbuf_alloc_size);
    +			m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, 
    +			    sc->rx_bd_mbuf_alloc_size);
     #endif
     
     		if (m_new == NULL) {
    @@ -5115,7 +5050,7 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     	/* Handle any mapping errors. */
     	if (error) {
     		BCE_PRINTF("%s(%d): Error mapping mbuf into RX chain (%d)!\n",
    -			__FILE__, __LINE__, error);
    +		    __FILE__, __LINE__, error);
     
     		sc->dma_map_addr_rx_failed_count++;
     		m_freem(m_new);
    @@ -5128,9 +5063,7 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     
     	/* All mbufs must map to a single segment. */
     	KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
    -		 __FUNCTION__, nsegs));
    -
    -	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
    +	    __FUNCTION__, nsegs));
     
     	/* Setup the rx_bd for the segment. */
     	rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
    @@ -5145,11 +5078,12 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     	sc->rx_mbuf_ptr[*chain_prod] = m_new;
     	sc->free_rx_bd -= nsegs;
     
    -	DBRUNMSG(BCE_INSANE_RECV, bce_dump_rx_mbuf_chain(sc, debug_chain_prod,
    -		nsegs));
    +	DBRUNMSG(BCE_INSANE_RECV, 
    +	    bce_dump_rx_mbuf_chain(sc, debug_chain_prod, nsegs));
     
    -	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, chain_prod = 0x%04X, "
    -		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
    +	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
    +	    "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", 
    +	    __FUNCTION__, *prod, *chain_prod, *prod_bseq);
     
     bce_get_rx_buf_exit:
     	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
    @@ -5160,7 +5094,7 @@ bce_get_rx_buf_exit:
     
     #ifdef BCE_JUMBO_HDRSPLIT
     /****************************************************************************/
    -/* Encapsulate an mbuf cluster into the page chain.                        */
    +/* Encapsulate an mbuf cluster into the page chain.                         */
     /*                                                                          */
     /* Returns:                                                                 */
     /*   0 for success, positive value for failure.                             */
    @@ -5182,15 +5116,15 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     
     	/* Make sure the inputs are valid. */
     	DBRUNIF((*prod_idx > MAX_PG_BD),
    -		BCE_PRINTF("%s(%d): page producer out of range: 0x%04X > 0x%04X\n",
    -		__FILE__, __LINE__, *prod_idx, (u16) MAX_PG_BD));
    +	    BCE_PRINTF("%s(%d): page producer out of range: 0x%04X > 0x%04X\n",
    +	    __FILE__, __LINE__, *prod_idx, (u16) MAX_PG_BD));
     
     	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
    -		"chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
    +	    "chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
     
     	/* Update counters if we've hit a new low or run out of pages. */
     	DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
    -		sc->pg_low_watermark = sc->free_pg_bd);
    +	    sc->pg_low_watermark = sc->free_pg_bd);
     	DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
     
     	/* Check whether this is a new mbuf allocation. */
    @@ -5198,10 +5132,10 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     
     		/* Simulate an mbuf allocation failure. */
     		DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
    -			sc->mbuf_alloc_failed_count++;
    -			sc->mbuf_alloc_failed_sim_count++;
    -			rc = ENOBUFS;
    -			goto bce_get_pg_buf_exit);
    +		    sc->mbuf_alloc_failed_count++;
    +		    sc->mbuf_alloc_failed_sim_count++;
    +		    rc = ENOBUFS;
    +		    goto bce_get_pg_buf_exit);
     
     		/* This is a new mbuf allocation. */
     		m_new = m_getcl(M_DONTWAIT, MT_DATA, 0);
    @@ -5225,12 +5159,13 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     	/* Map the mbuf cluster into device memory. */
     	map = sc->pg_mbuf_map[*prod_idx];
     	error = bus_dmamap_load(sc->pg_mbuf_tag, map, mtod(m_new, void *),
    -	    sc->pg_bd_mbuf_alloc_size, bce_dma_map_addr, &busaddr, BUS_DMA_NOWAIT);
    +	    sc->pg_bd_mbuf_alloc_size, bce_dma_map_addr, 
    +	    &busaddr, BUS_DMA_NOWAIT);
     
     	/* Handle any mapping errors. */
     	if (error) {
     		BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     
     		m_freem(m_new);
     		DBRUN(sc->debug_pg_mbuf_alloc--);
    @@ -5256,11 +5191,11 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
     	sc->pg_mbuf_ptr[*prod_idx] = m_new;
     	sc->free_pg_bd--;
     
    -	DBRUNMSG(BCE_INSANE_RECV, bce_dump_pg_mbuf_chain(sc, debug_prod_idx,
    -		1));
    +	DBRUNMSG(BCE_INSANE_RECV, 
    +	    bce_dump_pg_mbuf_chain(sc, debug_prod_idx, 1));
     
     	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
    -		"prod_idx = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
    +	    "prod_idx = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
     
     bce_get_pg_buf_exit:
     	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
    @@ -5269,6 +5204,7 @@ bce_get_pg_buf_exit:
     }
     #endif /* BCE_JUMBO_HDRSPLIT */
     
    +
     /****************************************************************************/
     /* Initialize the TX context memory.                                        */
     /*                                                                          */
    @@ -5286,16 +5222,20 @@ bce_init_tx_context(struct bce_softc *sc)
     	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
     		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
     		/* Set the CID type to support an L2 connection. */
    -		val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI | BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
    +		val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI | 
    +		    BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
     		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
     		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
    -		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE_XI, val);
    +		CTX_WR(sc, GET_CID_ADDR(TX_CID), 
    +		    BCE_L2CTX_TX_CMD_TYPE_XI, val);
     
     		/* Point the hardware to the first page in the chain. */
     		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
    -		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
    +		CTX_WR(sc, GET_CID_ADDR(TX_CID), 
    +		    BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
     		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
    -		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
    +		CTX_WR(sc, GET_CID_ADDR(TX_CID), 
    +		    BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
     	} else {
     		/* Set the CID type to support an L2 connection. */
     		val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
    @@ -5305,9 +5245,11 @@ bce_init_tx_context(struct bce_softc *sc)
     
     		/* Point the hardware to the first page in the chain. */
     		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
    -		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
    +		CTX_WR(sc, GET_CID_ADDR(TX_CID), 
    +		    BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
     		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
    -		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
    +		CTX_WR(sc, GET_CID_ADDR(TX_CID), 
    +		    BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
     	}
     
     	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
    @@ -5334,7 +5276,7 @@ bce_init_tx_chain(struct bce_softc *sc)
     	sc->tx_prod_bseq   = 0;
     	sc->used_tx_bd     = 0;
     	sc->max_tx_bd      = USABLE_TX_BD;
    -	DBRUN(sc->tx_hi_watermark = USABLE_TX_BD);
    +	DBRUN(sc->tx_hi_watermark = 0);
     	DBRUN(sc->tx_full_count = 0);
     
     	/*
    @@ -5389,8 +5331,9 @@ bce_free_tx_chain(struct bce_softc *sc)
     	for (i = 0; i < TOTAL_TX_BD; i++) {
     		if (sc->tx_mbuf_ptr[i] != NULL) {
     			if (sc->tx_mbuf_map[i] != NULL)
    -				bus_dmamap_sync(sc->tx_mbuf_tag, sc->tx_mbuf_map[i],
    -					BUS_DMASYNC_POSTWRITE);
    +				bus_dmamap_sync(sc->tx_mbuf_tag, 
    +				    sc->tx_mbuf_map[i],
    +				    BUS_DMASYNC_POSTWRITE);
     			m_freem(sc->tx_mbuf_ptr[i]);
     			sc->tx_mbuf_ptr[i] = NULL;
     			DBRUN(sc->debug_tx_mbuf_alloc--);
    @@ -5401,13 +5344,13 @@ bce_free_tx_chain(struct bce_softc *sc)
     	for (i = 0; i < TX_PAGES; i++)
     		bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
     
    -	sc->used_tx_bd     = 0;
    +	sc->used_tx_bd = 0;
     
     	/* Check if we lost any mbufs in the process. */
     	DBRUNIF((sc->debug_tx_mbuf_alloc),
    -		BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
    -			"from tx chain!\n",
    -			__FILE__, __LINE__, sc->debug_tx_mbuf_alloc));
    +	    BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
    +	    "from tx chain!\n",	__FILE__, __LINE__, 
    +	    sc->debug_tx_mbuf_alloc));
     
     	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
     }
    @@ -5426,10 +5369,10 @@ bce_init_rx_context(struct bce_softc *sc)
     
     	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
     
    -	/* Initialize the type, size, and BD cache levels for the RX context. */
    +	/* Init the type, size, and BD cache levels for the RX context. */
     	val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
    -		BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
    -		(0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
    +	    BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
    +	    (0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
     
     	/*
     	 * Set the level for generating pause frames
    @@ -5439,7 +5382,7 @@ bce_init_rx_context(struct bce_softc *sc)
     	 * watermark).
     	 */
     	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    -		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
    +	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
     		u32 lo_water, hi_water;
     
     		lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
    @@ -5460,7 +5403,7 @@ bce_init_rx_context(struct bce_softc *sc)
     
     	/* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
     	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    -		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
    +	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
     		val = REG_RD(sc, BCE_MQ_MAP_L2_5);
     		REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
     	}
    @@ -5488,7 +5431,7 @@ bce_init_rx_chain(struct bce_softc *sc)
     	int i, rc = 0;
     
     	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
    -		BCE_VERBOSE_CTX);
    +	    BCE_VERBOSE_CTX);
     
     	/* Initialize the RX producer and consumer indices. */
     	sc->rx_prod        = 0;
    @@ -5496,8 +5439,6 @@ bce_init_rx_chain(struct bce_softc *sc)
     	sc->rx_prod_bseq   = 0;
     	sc->free_rx_bd     = USABLE_RX_BD;
     	sc->max_rx_bd      = USABLE_RX_BD;
    -	DBRUN(sc->rx_low_watermark = sc->max_rx_bd);
    -	DBRUN(sc->rx_empty_count = 0);
     
     	/* Initialize the RX next pointer chain entries. */
     	for (i = 0; i < RX_PAGES; i++) {
    @@ -5512,13 +5453,17 @@ bce_init_rx_chain(struct bce_softc *sc)
     			j = i + 1;
     
     		/* Setup the chain page pointers. */
    -		rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
    -		rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
    +		rxbd->rx_bd_haddr_hi = 
    +		    htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
    +		rxbd->rx_bd_haddr_lo = 
    +		    htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
     	}
     
     	/* Fill up the RX chain. */
     	bce_fill_rx_chain(sc);
     
    +	DBRUN(sc->rx_low_watermark = USABLE_RX_BD);
    +	DBRUN(sc->rx_empty_count = 0);
     	for (i = 0; i < RX_PAGES; i++) {
     		bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i],
     		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    @@ -5526,10 +5471,12 @@ bce_init_rx_chain(struct bce_softc *sc)
     
     	bce_init_rx_context(sc);
     
    -	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_chain(sc, 0, TOTAL_RX_BD));
    +	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD));
     	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
    -		BCE_VERBOSE_CTX);
    +	    BCE_VERBOSE_CTX);
    +
     	/* ToDo: Are there possible failure modes here? */
    +
     	return(rc);
     }
     
    @@ -5548,7 +5495,7 @@ bce_fill_rx_chain(struct bce_softc *sc)
     	u32 prod_bseq;
     
     	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
    -		BCE_VERBOSE_CTX);
    +	    BCE_VERBOSE_CTX);
     
     	/* Get the RX chain producer indices. */
     	prod      = sc->rx_prod;
    @@ -5568,6 +5515,7 @@ bce_fill_rx_chain(struct bce_softc *sc)
     	sc->rx_prod      = prod;
     	sc->rx_prod_bseq = prod_bseq;
     
    +	/* We should never end up pointing to a next page pointer. */
     	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
     		BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
     		__FUNCTION__, sc->rx_prod));
    @@ -5579,7 +5527,7 @@ bce_fill_rx_chain(struct bce_softc *sc)
     		sc->rx_prod_bseq);
     
     	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
    -		BCE_VERBOSE_CTX);
    +	    BCE_VERBOSE_CTX);
     }
     
     
    @@ -5600,8 +5548,9 @@ bce_free_rx_chain(struct bce_softc *sc)
     	for (i = 0; i < TOTAL_RX_BD; i++) {
     		if (sc->rx_mbuf_ptr[i] != NULL) {
     			if (sc->rx_mbuf_map[i] != NULL)
    -				bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[i],
    -					BUS_DMASYNC_POSTREAD);
    +				bus_dmamap_sync(sc->rx_mbuf_tag, 
    +				    sc->rx_mbuf_map[i],
    +				    BUS_DMASYNC_POSTREAD);
     			m_freem(sc->rx_mbuf_ptr[i]);
     			sc->rx_mbuf_ptr[i] = NULL;
     			DBRUN(sc->debug_rx_mbuf_alloc--);
    @@ -5610,14 +5559,17 @@ bce_free_rx_chain(struct bce_softc *sc)
     
     	/* Clear each RX chain page. */
     	for (i = 0; i < RX_PAGES; i++)
    -		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
    +		if (sc->rx_bd_chain[i] != NULL) {
    +			bzero((char *)sc->rx_bd_chain[i], 
    +			    BCE_RX_CHAIN_PAGE_SZ);
    +		}
     
     	sc->free_rx_bd = sc->max_rx_bd;
     
     	/* Check if we lost any mbufs in the process. */
     	DBRUNIF((sc->debug_rx_mbuf_alloc),
    -		BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
    -			__FUNCTION__, sc->debug_rx_mbuf_alloc));
    +	    BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
    +	    __FUNCTION__, sc->debug_rx_mbuf_alloc));
     
     	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
     }
    @@ -5832,12 +5784,12 @@ bce_ifmedia_upd_locked(struct ifnet *ifp)
     
     	/* Make sure the MII bus has been enumerated. */
     	if (mii) {
    -		sc->bce_link = 0;
    +		sc->bce_link_up = FALSE;
     		if (mii->mii_instance) {
     			struct mii_softc *miisc;
     
     			LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
    -				mii_phy_reset(miisc);
    +			    mii_phy_reset(miisc);
     		}
     		mii_mediachg(mii);
     	}
    @@ -5887,26 +5839,28 @@ bce_phy_intr(struct bce_softc *sc)
     
     	DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
     
    +	DBRUN(sc->phy_interrupts++);
    +
     	new_link_state = sc->status_block->status_attn_bits &
    -		STATUS_ATTN_BITS_LINK_STATE;
    +	    STATUS_ATTN_BITS_LINK_STATE;
     	old_link_state = sc->status_block->status_attn_bits_ack &
    -		STATUS_ATTN_BITS_LINK_STATE;
    +	    STATUS_ATTN_BITS_LINK_STATE;
     
     	/* Handle any changes if the link state has changed. */
     	if (new_link_state != old_link_state) {
     
    -		/* Update the status_attn_bits_ack field in the status block. */
    +		/* Update the status_attn_bits_ack field. */
     		if (new_link_state) {
     			REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
    -				STATUS_ATTN_BITS_LINK_STATE);
    +			    STATUS_ATTN_BITS_LINK_STATE);
     			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
    -				__FUNCTION__);
    +			    __FUNCTION__);
     		}
     		else {
     			REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
    -				STATUS_ATTN_BITS_LINK_STATE);
    +			    STATUS_ATTN_BITS_LINK_STATE);
     			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
    -				__FUNCTION__);
    +			    __FUNCTION__);
     		}
     
     		/*
    @@ -5914,7 +5868,7 @@ bce_phy_intr(struct bce_softc *sc)
     		 * tick routine to update the state
     		 * based on the actual media state.
     		 */
    -		sc->bce_link = 0;
    +		sc->bce_link_up = FALSE;
     		callout_stop(&sc->bce_tick_callout);
     		bce_tick(sc);
     	}
    @@ -5969,8 +5923,8 @@ bce_rx_intr(struct bce_softc *sc)
     	DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
     	DBRUN(sc->rx_interrupts++);
     	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
    -		"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
    -		__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
    +	    "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
    +	    __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
     
     	/* Prepare the RX chain pages to be accessed by the host CPU. */
     	for (int i = 0; i < RX_PAGES; i++)
    @@ -6008,7 +5962,8 @@ bce_rx_intr(struct bce_softc *sc)
     		sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
     
     		/* Unmap the mbuf from DMA space. */
    -		bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[sw_rx_cons_idx],
    +		bus_dmamap_sync(sc->rx_mbuf_tag, 
    +		    sc->rx_mbuf_map[sw_rx_cons_idx],
     		    BUS_DMASYNC_POSTREAD);
     		bus_dmamap_unload(sc->rx_mbuf_tag,
     		    sc->rx_mbuf_map[sw_rx_cons_idx]);
    @@ -6019,29 +5974,30 @@ bce_rx_intr(struct bce_softc *sc)
     		DBRUN(sc->debug_rx_mbuf_alloc--);
     		sc->free_rx_bd++;
     
    -        if(m0 == NULL) {
    -            DBPRINT(sc, BCE_EXTREME_RECV, "%s(): Oops! Empty mbuf pointer "
    -                "found in sc->rx_mbuf_ptr[0x%04X]!\n",
    -                __FUNCTION__, sw_rx_cons_idx);
    -            goto bce_rx_int_next_rx;
    -        }
    +		if(m0 == NULL) {
    +			DBPRINT(sc, BCE_EXTREME_RECV, 
    +			    "%s(): Oops! Empty mbuf pointer "
    +			    "found in sc->rx_mbuf_ptr[0x%04X]!\n",
    +			    __FUNCTION__, sw_rx_cons_idx);
    +			goto bce_rx_int_next_rx;
    +		}
     
    -        /*
    -         * Frames received on the NetXteme II are prepended	with an
    -         * l2_fhdr structure which provides status information about
    -         * the received frame (including VLAN tags and checksum info).
    -         * The frames are also automatically adjusted to align the IP
    -         * header (i.e. two null bytes are inserted before the Ethernet
    -         * header).  As a result the data DMA'd by the controller into
    -         * the mbuf is as follows:
    -         * 
    -         * +---------+-----+---------------------+-----+
    -         * | l2_fhdr | pad | packet data         | FCS |
    -         * +---------+-----+---------------------+-----+
    -         * 
    -         * The l2_fhdr needs to be checked and skipped and the FCS needs
    -         * to be stripped before sending the packet up the stack.
    -         */
    +		/*
    +		 * Frames received on the NetXteme II are prepended	with an
    +		 * l2_fhdr structure which provides status information about
    +		 * the received frame (including VLAN tags and checksum info).
    +		 * The frames are also automatically adjusted to align the IP
    +		 * header (i.e. two null bytes are inserted before the Ethernet
    +		 * header).  As a result the data DMA'd by the controller into
    +		 * the mbuf is as follows:
    +		 * 
    +		 * +---------+-----+---------------------+-----+
    +		 * | l2_fhdr | pad | packet data         | FCS |
    +		 * +---------+-----+---------------------+-----+
    +		 * 
    +		 * The l2_fhdr needs to be checked and skipped and the FCS needs
    +		 * to be stripped before sending the packet up the stack.
    +		 */
     		l2fhdr  = mtod(m0, struct l2_fhdr *);
     
     		/* Get the packet data + FCS length and the status. */
    @@ -6076,8 +6032,8 @@ bce_rx_intr(struct bce_softc *sc)
     			 * in the page chain.
     			 */
     
    -			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large packet.\n",
    -				__FUNCTION__);
    +			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large "
    +			    "packet.\n", __FUNCTION__);
     
     			/*
     			 * When the page chain is enabled and the TCP
    @@ -6105,10 +6061,10 @@ bce_rx_intr(struct bce_softc *sc)
     
     				/* Unmap the page chain mbuf from DMA space. */
     				bus_dmamap_sync(sc->pg_mbuf_tag,
    -					sc->pg_mbuf_map[sw_pg_cons_idx],
    -					BUS_DMASYNC_POSTREAD);
    +				    sc->pg_mbuf_map[sw_pg_cons_idx],
    +				    BUS_DMASYNC_POSTREAD);
     				bus_dmamap_unload(sc->pg_mbuf_tag,
    -					sc->pg_mbuf_map[sw_pg_cons_idx]);
    +				    sc->pg_mbuf_map[sw_pg_cons_idx]);
     
     				/* Adjust the mbuf length. */
     				if (rem_len < m_pg->m_len) {
    @@ -6137,8 +6093,8 @@ bce_rx_intr(struct bce_softc *sc)
     			 * 154 bytes or less in size.
     			 */
     
    -			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small packet.\n",
    -				__FUNCTION__);
    +			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small "
    +			    "packet.\n", __FUNCTION__);
     
     			/* Set the total packet length. */
     			m0->m_pkthdr.len = m0->m_len = pkt_len;
    @@ -6154,19 +6110,19 @@ bce_rx_intr(struct bce_softc *sc)
     		/* Check that the resulting mbuf chain is valid. */
     		DBRUN(m_sanity(m0, FALSE));
     		DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
    -			(m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
    -			BCE_PRINTF("Invalid Ethernet frame size!\n");
    -			m_print(m0, 128));
    +		    (m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
    +		     BCE_PRINTF("Invalid Ethernet frame size!\n");
    +		     m_print(m0, 128));
     
     		DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control),
    -			BCE_PRINTF("Simulating l2_fhdr status error.\n");
    -			sc->l2fhdr_error_sim_count++;
    -			status = status | L2_FHDR_ERRORS_PHY_DECODE);
    +		    BCE_PRINTF("Simulating l2_fhdr status error.\n");
    +		    sc->l2fhdr_error_sim_count++;
    +		    status = status | L2_FHDR_ERRORS_PHY_DECODE);
     
     		/* Check the received frame for errors. */
    -		if (status & (L2_FHDR_ERRORS_BAD_CRC |
    -			L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
    -			L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
    +		if (status & (L2_FHDR_ERRORS_BAD_CRC | 
    +		    L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
    +		    L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
     
     			/* Log the error and release the mbuf. */
     			ifp->if_ierrors++;
    @@ -6193,20 +6149,22 @@ bce_rx_intr(struct bce_softc *sc)
     
     				/* Check if the IP checksum is valid. */
     				if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
    -					m0->m_pkthdr.csum_flags |= CSUM_IP_VALID;
    +					m0->m_pkthdr.csum_flags |= 
    +					    CSUM_IP_VALID;
     			}
     
     			/* Check for a valid TCP/UDP frame. */
     			if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
    -				L2_FHDR_STATUS_UDP_DATAGRAM)) {
    +			    L2_FHDR_STATUS_UDP_DATAGRAM)) {
     
     				/* Check for a good TCP/UDP checksum. */
     				if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
    -					      L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
    +				    L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
     					m0->m_pkthdr.csum_data =
     					    l2fhdr->l2_fhdr_tcp_udp_xsum;
    -					m0->m_pkthdr.csum_flags |= (CSUM_DATA_VALID
    -						| CSUM_PSEUDO_HDR);
    +					m0->m_pkthdr.csum_flags |= 
    +					    (CSUM_DATA_VALID
    +					    | CSUM_PSEUDO_HDR);
     				}
     			}
     		}
    @@ -6297,8 +6255,8 @@ bce_rx_int_next_rx:
     #endif
     
     	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
    -		"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
    -		__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
    +	    "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
    +	    __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
     	DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
     }
     
    @@ -6339,8 +6297,8 @@ bce_tx_intr(struct bce_softc *sc)
     	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
     	DBRUN(sc->tx_interrupts++);
     	DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
    -		"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
    -		__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
    +	    "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
    +	    __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
     
     	BCE_LOCK_ASSERT(sc);
     
    @@ -6350,7 +6308,7 @@ bce_tx_intr(struct bce_softc *sc)
     
     	/* Prevent speculative reads from getting ahead of the status block. */
     	bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
    -		BUS_SPACE_BARRIER_READ);
    +	    BUS_SPACE_BARRIER_READ);
     
     	/* Cycle through any completed TX chain page entries. */
     	while (sw_tx_cons != hw_tx_cons) {
    @@ -6360,26 +6318,26 @@ bce_tx_intr(struct bce_softc *sc)
     		sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
     
     		DBPRINT(sc, BCE_INFO_SEND,
    -			"%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
    -			"sw_tx_chain_cons = 0x%04X\n",
    -			__FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
    +		    "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
    +		    "sw_tx_chain_cons = 0x%04X\n",
    +		    __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
     
     		DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
    -			BCE_PRINTF("%s(%d): TX chain consumer out of range! "
    -				" 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
    -				(int) MAX_TX_BD);
    -			bce_breakpoint(sc));
    +		    BCE_PRINTF("%s(%d): TX chain consumer out of range! "
    +		    " 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
    +		    (int) MAX_TX_BD);
    +		    bce_breakpoint(sc));
     
     		DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
    -				[TX_IDX(sw_tx_chain_cons)]);
    +		    [TX_IDX(sw_tx_chain_cons)]);
     
     		DBRUNIF((txbd == NULL),
    -			BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
    -				__FILE__, __LINE__, sw_tx_chain_cons);
    -			bce_breakpoint(sc));
    +		    BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
    +		    __FILE__, __LINE__, sw_tx_chain_cons);
    +		    bce_breakpoint(sc));
     
     		DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
    -			bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
    +		    bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
     
     		/*
     		 * Free the associated mbuf. Remember
    @@ -6390,13 +6348,14 @@ bce_tx_intr(struct bce_softc *sc)
     
     			/* Validate that this is the last tx_bd. */
     			DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
    -				BCE_PRINTF("%s(%d): tx_bd END flag not set but "
    -				"txmbuf == NULL!\n", __FILE__, __LINE__);
    -				bce_breakpoint(sc));
    +			    BCE_PRINTF("%s(%d): tx_bd END flag not set but "
    +			    "txmbuf == NULL!\n", __FILE__, __LINE__);
    +			    bce_breakpoint(sc));
     
     			DBRUNMSG(BCE_INFO_SEND,
    -				BCE_PRINTF("%s(): Unloading map/freeing mbuf "
    -					"from tx_bd[0x%04X]\n", __FUNCTION__, sw_tx_chain_cons));
    +			    BCE_PRINTF("%s(): Unloading map/freeing mbuf "
    +			    "from tx_bd[0x%04X]\n", __FUNCTION__, 
    +			    sw_tx_chain_cons));
     
     			/* Unmap the mbuf. */
     			bus_dmamap_unload(sc->tx_mbuf_tag,
    @@ -6416,9 +6375,9 @@ bce_tx_intr(struct bce_softc *sc)
     		/* Refresh hw_cons to see if there's new work. */
     		hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
     
    -		/* Prevent speculative reads from getting ahead of the status block. */
    +		/* Prevent speculative reads of the status block. */
     		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
    -			BUS_SPACE_BARRIER_READ);
    +		    BUS_SPACE_BARRIER_READ);
     	}
     
     	/* Clear the TX timeout timer. */
    @@ -6427,17 +6386,17 @@ bce_tx_intr(struct bce_softc *sc)
     	/* Clear the tx hardware queue full flag. */
     	if (sc->used_tx_bd < sc->max_tx_bd) {
     		DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
    -			DBPRINT(sc, BCE_INFO_SEND,
    -				"%s(): Open TX chain! %d/%d (used/total)\n",
    -				__FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
    +		    DBPRINT(sc, BCE_INFO_SEND,
    +		    "%s(): Open TX chain! %d/%d (used/total)\n",
    +		    __FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
     		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
     	}
     
     	sc->tx_cons = sw_tx_cons;
     
     	DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
    -		"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
    -		__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
    +	    "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
    +	    __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
     	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
     }
     
    @@ -6472,11 +6431,11 @@ bce_enable_intr(struct bce_softc *sc, int coal_now)
     	DBENTER(BCE_VERBOSE_INTR);
     
     	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
    -	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
    -	       BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
    +	    BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
    +	    BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
     
     	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
    -	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
    +	    BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
     
     	/* Force an immediate interrupt (whether there is new data or not). */
     	if (coal_now)
    @@ -6512,19 +6471,19 @@ bce_init_locked(struct bce_softc *sc)
     
     	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
     		BCE_PRINTF("%s(%d): Controller reset failed!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		goto bce_init_locked_exit;
     	}
     
     	if (bce_chipinit(sc)) {
     		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		goto bce_init_locked_exit;
     	}
     
     	if (bce_blockinit(sc)) {
     		BCE_PRINTF("%s(%d): Block initialization failed!\n",
    -			__FILE__, __LINE__);
    +		    __FILE__, __LINE__);
     		goto bce_init_locked_exit;
     	}
     
    @@ -6537,8 +6496,10 @@ bce_init_locked(struct bce_softc *sc)
     	 * size. Be generous on the receive if we have room.
     	 */
     #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;
    +	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
     	if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len)
     		ether_mtu = sc->rx_bd_mbuf_data_len;
    @@ -6548,29 +6509,29 @@ bce_init_locked(struct bce_softc *sc)
     
     	ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
     
    -	DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n", __FUNCTION__,
    -		ether_mtu);
    +	DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n", 
    +	    __FUNCTION__, ether_mtu);
     
     	/* Program the mtu, enabling jumbo frame support if necessary. */
     	if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
     		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
    -			min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
    -			BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
    +		    min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
    +		    BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
     	else
     		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
     
     	DBPRINT(sc, BCE_INFO_LOAD,
    -		"%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_mbuf_data_len = %d, "
    -		"rx_bd_mbuf_align_pad = %d\n", __FUNCTION__, 
    -		sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
    -		sc->rx_bd_mbuf_align_pad);
    +	    "%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_mbuf_data_len = %d, "
    +	    "rx_bd_mbuf_align_pad = %d\n", __FUNCTION__, 
    +	    sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
    +	    sc->rx_bd_mbuf_align_pad);
     
     	/* Program appropriate promiscuous/multicast filtering. */
     	bce_set_rx_mode(sc);
     
     #ifdef BCE_JUMBO_HDRSPLIT
     	DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_mbuf_alloc_size = %d\n",
    -		__FUNCTION__, sc->pg_bd_mbuf_alloc_size);
    +	    __FUNCTION__, sc->pg_bd_mbuf_alloc_size);
     
     	/* Init page buffer descriptor chain. */
     	bce_init_pg_chain(sc);
    @@ -6617,7 +6578,7 @@ bce_mgmt_init_locked(struct bce_softc *sc)
     	/* Bail out if management firmware is not running. */
     	if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
     		DBPRINT(sc, BCE_VERBOSE_SPECIAL,
    -			"No management firmware running...\n");
    +		    "No management firmware running...\n");
     		goto bce_mgmt_init_locked_exit;
     	}
     
    @@ -6786,10 +6747,10 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
     
     	DBENTER(BCE_VERBOSE_SEND);
     	DBPRINT(sc, BCE_INFO_SEND,
    -		"%s(enter): tx_prod = 0x%04X, tx_chain_prod = %04X, "
    -		"tx_prod_bseq = 0x%08X\n",
    -		__FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
    -		sc->tx_prod_bseq);
    +	    "%s(enter): tx_prod = 0x%04X, tx_chain_prod = %04X, "
    +	    "tx_prod_bseq = 0x%08X\n",
    +	    __FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
    +	    sc->tx_prod_bseq);
     
     	/* Transfer any checksum offload flags to the bd. */
     	m0 = *m_head;
    @@ -6850,10 +6811,9 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
     			rc = error;
     			goto bce_tx_encap_exit;
     		} else if (error != 0) {
    -			/* Still can't map the mbuf, release it and return an error. */
    -			BCE_PRINTF(
    -			    "%s(%d): Unknown error mapping mbuf into TX chain!\n",
    -			    __FILE__, __LINE__);
    +			/* Release it and return an error. */
    +			BCE_PRINTF("%s(%d): Unknown error mapping mbuf into "
    +			    "TX chain!\n", __FILE__, __LINE__);
     			m_freem(m0);
     			*m_head = NULL;
     			sc->dma_map_addr_tx_failed_count++;
    @@ -6888,9 +6848,9 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
     #endif
     
     	DBPRINT(sc, BCE_INFO_SEND,
    -		"%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
    -		"prod_bseq = 0x%08X\n",
    -		__FUNCTION__, prod, chain_prod, prod_bseq);
    +	    "%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
    +	    "prod_bseq = 0x%08X\n",
    +	    __FUNCTION__, prod, chain_prod, prod_bseq);
     
     	/*
     	 * Cycle through each mbuf segment that makes up
    @@ -6901,11 +6861,13 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
     	for (i = 0; i < nsegs ; i++) {
     
     		chain_prod = TX_CHAIN_IDX(prod);
    -		txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
    +		txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)]
    +		    [TX_IDX(chain_prod)];
     
     		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr));
     		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr));
    -		txbd->tx_bd_mss_nbytes = htole32(mss << 16) | htole16(segs[i].ds_len);
    +		txbd->tx_bd_mss_nbytes = htole32(mss << 16) | 
    +		    htole16(segs[i].ds_len);
     		txbd->tx_bd_vlan_tag = htole16(vlan_tag);
     		txbd->tx_bd_flags = htole16(flags);
     		prod_bseq += segs[i].ds_len;
    @@ -6920,9 +6882,9 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
     	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_chain(sc, debug_prod, nsegs));
     
     	DBPRINT(sc, BCE_INFO_SEND,
    -		"%s( end ): prod = 0x%04X, chain_prod = 0x%04X, "
    -		"prod_bseq = 0x%08X\n",
    -		__FUNCTION__, prod, chain_prod, prod_bseq);
    +	    "%s( end ): prod = 0x%04X, chain_prod = 0x%04X, "
    +	    "prod_bseq = 0x%08X\n",
    +	    __FUNCTION__, prod, chain_prod, prod_bseq);
     
     	/*
     	 * Ensure that the mbuf pointer for this transmission
    @@ -6938,7 +6900,7 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
     
     	/* Update some debug statistic counters */
     	DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
    -		sc->tx_hi_watermark = sc->used_tx_bd);
    +	    sc->tx_hi_watermark = sc->used_tx_bd);
     	DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
     	DBRUNIF(sc->debug_tx_mbuf_alloc++);
     
    @@ -6949,10 +6911,10 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
     	sc->tx_prod_bseq = prod_bseq;
     
     	DBPRINT(sc, BCE_INFO_SEND,
    -		"%s(exit): prod = 0x%04X, chain_prod = %04X, "
    -		"prod_bseq = 0x%08X\n",
    -		__FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
    -		sc->tx_prod_bseq);
    +	    "%s(exit): prod = 0x%04X, chain_prod = %04X, "
    +	    "prod_bseq = 0x%08X\n", __FUNCTION__, 
    +	    sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
    +	    sc->tx_prod_bseq);
     
     bce_tx_encap_exit:
     	DBEXIT(BCE_VERBOSE_SEND);
    @@ -6983,20 +6945,20 @@ bce_start_locked(struct ifnet *ifp)
     	tx_chain_prod = TX_CHAIN_IDX(tx_prod);
     
     	DBPRINT(sc, BCE_INFO_SEND,
    -		"%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
    -		"tx_prod_bseq = 0x%08X\n",
    -		__FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
    +	    "%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
    +	    "tx_prod_bseq = 0x%08X\n",
    +	    __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
     
     	/* If there's no link or the transmit queue is empty then just exit. */
    -	if (!sc->bce_link) {
    +	if (sc->bce_link_up == FALSE) {
     		DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
    -			__FUNCTION__);
    +		    __FUNCTION__);
     		goto bce_start_locked_exit;
     	}
     
     	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
     		DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
    -			__FUNCTION__);
    +		    __FUNCTION__);
     		goto bce_start_locked_exit;
     	}
     
    @@ -7019,13 +6981,12 @@ bce_start_locked(struct ifnet *ifp)
     		 * to wait for the NIC to drain the chain.
     		 */
     		if (bce_tx_encap(sc, &m_head)) {
    -			/* No room, put the frame back on the transmit queue. */
     			if (m_head != NULL)
     				IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
     			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
     			DBPRINT(sc, BCE_INFO_SEND,
    -				"TX chain is closed for business! Total tx_bd used = %d\n",
    -				sc->used_tx_bd);
    +			    "TX chain is closed for business! Total "
    +			    "tx_bd used = %d\n", sc->used_tx_bd);
     			break;
     		}
     
    @@ -7037,26 +6998,29 @@ bce_start_locked(struct ifnet *ifp)
     
     	/* Exit if no packets were dequeued. */
     	if (count == 0) {
    -		DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were dequeued\n",
    -			__FUNCTION__);
    +		DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were "
    +		    "dequeued\n", __FUNCTION__);
     		goto bce_start_locked_exit;
     	}
     
    -	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into send queue.\n",
    -		__FUNCTION__, count);
    +	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into "
    +	    "send queue.\n", __FUNCTION__, count);
     
    -	REG_WR(sc, BCE_MQ_COMMAND, REG_RD(sc, BCE_MQ_COMMAND) | BCE_MQ_COMMAND_NO_MAP_ERROR);
    +	REG_WR(sc, BCE_MQ_COMMAND, REG_RD(sc, BCE_MQ_COMMAND) | 
    +	    BCE_MQ_COMMAND_NO_MAP_ERROR);
     
     	/* Write the mailbox and tell the chip about the waiting tx_bd's. */
    -	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
    -		"BCE_L2MQ_TX_HOST_BIDX = 0x%08X, sc->tx_prod = 0x%04X\n",
    -		__FUNCTION__,
    -		MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
    -	REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
    -	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
    -		"BCE_L2MQ_TX_HOST_BSEQ = 0x%08X, sc->tx_prod_bseq = 0x%04X\n",
    -		__FUNCTION__,
    -		MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
    +	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = "
    +	    "0x%08X; BCE_L2MQ_TX_HOST_BIDX = 0x%08X, sc->tx_prod = 0x%04X\n",
    +	    __FUNCTION__, MB_GET_CID_ADDR(TX_CID), 
    +	    BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
    +	REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) + 
    +	    BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
    +
    +	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = "
    +	    "0x%08X; BCE_L2MQ_TX_HOST_BSEQ = 0x%08X, sc->tx_prod_bseq = "
    +	    "0x%04X\n",	__FUNCTION__, MB_GET_CID_ADDR(TX_CID), 
    +	    BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
     	REG_WR(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
     
     	/* Set the tx timeout. */
    @@ -7110,165 +7074,172 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     
     	switch(command) {
     
    -		/* Set the interface MTU. */
    -		case SIOCSIFMTU:
    -			/* Check that the MTU setting is supported. */
    -			if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
    -				(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
    -				error = EINVAL;
    -				break;
    -			}
    +	/* Set the interface MTU. */
    +	case SIOCSIFMTU:
    +		/* Check that the MTU setting is supported. */
    +		if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
    +			(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
    +			error = EINVAL;
    +			break;
    +		}
     
    -			DBPRINT(sc, BCE_INFO_MISC,
    -				"SIOCSIFMTU: Changing MTU from %d to %d\n",
    -				(int) ifp->if_mtu, (int) ifr->ifr_mtu);
    +		DBPRINT(sc, BCE_INFO_MISC,
    +		    "SIOCSIFMTU: Changing MTU from %d to %d\n",
    +		    (int) ifp->if_mtu, (int) ifr->ifr_mtu);
     
    -			BCE_LOCK(sc);
    -			ifp->if_mtu = ifr->ifr_mtu;
    -			reinit = 0;
    -			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    -				/*
    -				 * Because allocation size is used in RX
    -				 * buffer allocation, stop controller if
    -				 * it is already running.
    -				 */
    -				bce_stop(sc);
    -				reinit = 1;
    -			}
    +		BCE_LOCK(sc);
    +		ifp->if_mtu = ifr->ifr_mtu;
    +		reinit = 0;
    +		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    +			/*
    +			 * Because allocation size is used in RX
    +			 * buffer allocation, stop controller if
    +			 * it is already running.
    +			 */
    +			bce_stop(sc);
    +			reinit = 1;
    +		}
     #ifdef BCE_JUMBO_HDRSPLIT
    -			/* No buffer allocation size changes are necessary. */
    +		/* No buffer allocation size changes are necessary. */
     #else
    -			/* Recalculate our buffer allocation sizes. */
    -			if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN) > MCLBYTES) {
    -				sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
    -				sc->rx_bd_mbuf_align_pad  = roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
    -				sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
    -					sc->rx_bd_mbuf_align_pad;
    -			} else {
    -				sc->rx_bd_mbuf_alloc_size = MCLBYTES;
    -				sc->rx_bd_mbuf_align_pad  = roundup2(MCLBYTES, 16) - MCLBYTES;
    -				sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
    -					sc->rx_bd_mbuf_align_pad;
    -			}
    +		/* Recalculate our buffer allocation sizes. */
    +		if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + 
    +		     ETHER_CRC_LEN) > MCLBYTES) {
    +			sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
    +			sc->rx_bd_mbuf_align_pad  = 
    +			    roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
    +			sc->rx_bd_mbuf_data_len = 
    +			    sc->rx_bd_mbuf_alloc_size -
    +			    sc->rx_bd_mbuf_align_pad;
    +		} else {
    +			sc->rx_bd_mbuf_alloc_size = MCLBYTES;
    +			sc->rx_bd_mbuf_align_pad  = 
    +			    roundup2(MCLBYTES, 16) - MCLBYTES;
    +			sc->rx_bd_mbuf_data_len = 
    +			    sc->rx_bd_mbuf_alloc_size -
    +			    sc->rx_bd_mbuf_align_pad;
    +		}
     #endif
     
    -			if (reinit != 0)
    -				bce_init_locked(sc);
    -			BCE_UNLOCK(sc);
    -			break;
    +		if (reinit != 0)
    +			bce_init_locked(sc);
    +		BCE_UNLOCK(sc);
    +		break;
     
    -		/* Set interface flags. */
    -		case SIOCSIFFLAGS:
    -			DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
    +	/* Set interface flags. */
    +	case SIOCSIFFLAGS:
    +		DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
     
    -			BCE_LOCK(sc);
    +		BCE_LOCK(sc);
     
    -			/* Check if the interface is up. */
    -			if (ifp->if_flags & IFF_UP) {
    -				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    -					/* Change promiscuous/multicast flags as necessary. */
    -					bce_set_rx_mode(sc);
    -				} else {
    -					/* Start the HW */
    -					bce_init_locked(sc);
    -				}
    -			} else {
    -				/* The interface is down, check if driver is running. */
    -				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    -					bce_stop(sc);
    -
    -					/* If MFW is running, restart the controller a bit. */
    -					if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    -						bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
    -						bce_chipinit(sc);
    -						bce_mgmt_init_locked(sc);
    -					}
    -				}
    -			}
    -
    -			BCE_UNLOCK(sc);
    -
    -			break;
    -
    -		/* Add/Delete multicast address */
    -		case SIOCADDMULTI:
    -		case SIOCDELMULTI:
    -			DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCADDMULTI/SIOCDELMULTI\n");
    -
    -			BCE_LOCK(sc);
    -			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
    +		/* Check if the interface is up. */
    +		if (ifp->if_flags & IFF_UP) {
    +			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    +				/* Change promiscuous/multicast flags as necessary. */
     				bce_set_rx_mode(sc);
    -			BCE_UNLOCK(sc);
    -
    -			break;
    -
    -		/* Set/Get Interface media */
    -		case SIOCSIFMEDIA:
    -		case SIOCGIFMEDIA:
    -			DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
    -
    -			mii = device_get_softc(sc->bce_miibus);
    -			error = ifmedia_ioctl(ifp, ifr,
    -			    &mii->mii_media, command);
    -			break;
    -
    -		/* Set interface capability */
    -		case SIOCSIFCAP:
    -			mask = ifr->ifr_reqcap ^ ifp->if_capenable;
    -			DBPRINT(sc, BCE_INFO_MISC, "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
    -
    -			/* Toggle the TX checksum capabilities enable flag. */
    -			if (mask & IFCAP_TXCSUM &&
    -			    ifp->if_capabilities & IFCAP_TXCSUM) {
    -				ifp->if_capenable ^= IFCAP_TXCSUM;
    -				if (IFCAP_TXCSUM & ifp->if_capenable)
    -					ifp->if_hwassist |= BCE_IF_HWASSIST;
    -				else
    -					ifp->if_hwassist &= ~BCE_IF_HWASSIST;
    +			} else {
    +				/* Start the HW */
    +				bce_init_locked(sc);
     			}
    +		} else {
    +			/* The interface is down, check if driver is running. */
    +			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    +				bce_stop(sc);
     
    -			/* Toggle the RX checksum capabilities enable flag. */
    -			if (mask & IFCAP_RXCSUM &&
    -			    ifp->if_capabilities & IFCAP_RXCSUM)
    -				ifp->if_capenable ^= IFCAP_RXCSUM;
    -
    -			/* Toggle the TSO capabilities enable flag. */
    -			if (bce_tso_enable && (mask & IFCAP_TSO4) &&
    -			    ifp->if_capabilities & IFCAP_TSO4) {
    -				ifp->if_capenable ^= IFCAP_TSO4;
    -				if (IFCAP_TSO4 & ifp->if_capenable)
    -					ifp->if_hwassist |= CSUM_TSO;
    -				else
    -					ifp->if_hwassist &= ~CSUM_TSO;
    +				/* If MFW is running, restart the controller a bit. */
    +				if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
    +					bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
    +					bce_chipinit(sc);
    +					bce_mgmt_init_locked(sc);
    +				}
     			}
    +		}
     
    -			if (mask & IFCAP_VLAN_HWCSUM &&
    -			    ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
    -				ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
    +		BCE_UNLOCK(sc);
    +		break;
     
    -			if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
    -			    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
    -				ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
    -			/*
    -			 * Don't actually disable VLAN tag stripping as
    -			 * management firmware (ASF/IPMI/UMP) requires the
    -			 * feature. If VLAN tag stripping is disabled driver
    -			 * will manually reconstruct the VLAN frame by
    -			 * appending stripped VLAN tag.
    -			 */
    -			if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    -			    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)) {
    -				ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    -				if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
    -				    == 0)
    -					ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
    -			}
    -			VLAN_CAPABILITIES(ifp);
    -			break;
    -		default:
    -			/* We don't know how to handle the IOCTL, pass it on. */
    -			error = ether_ioctl(ifp, command, data);
    -			break;
    +	/* Add/Delete multicast address */
    +	case SIOCADDMULTI:
    +	case SIOCDELMULTI:
    +		DBPRINT(sc, BCE_VERBOSE_MISC, 
    +		    "Received SIOCADDMULTI/SIOCDELMULTI\n");
    +
    +		BCE_LOCK(sc);
    +		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
    +			bce_set_rx_mode(sc);
    +		BCE_UNLOCK(sc);
    +
    +		break;
    +
    +	/* Set/Get Interface media */
    +	case SIOCSIFMEDIA:
    +	case SIOCGIFMEDIA:
    +		DBPRINT(sc, BCE_VERBOSE_MISC, 
    +		    "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
    +
    +		mii = device_get_softc(sc->bce_miibus);
    +		error = ifmedia_ioctl(ifp, ifr,
    +		    &mii->mii_media, command);
    +		break;
    +
    +	/* Set interface capability */
    +	case SIOCSIFCAP:
    +		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
    +		DBPRINT(sc, BCE_INFO_MISC, 
    +		    "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
    +
    +		/* Toggle the TX checksum capabilities enable flag. */
    +		if (mask & IFCAP_TXCSUM &&
    +		    ifp->if_capabilities & IFCAP_TXCSUM) {
    +			ifp->if_capenable ^= IFCAP_TXCSUM;
    +			if (IFCAP_TXCSUM & ifp->if_capenable)
    +				ifp->if_hwassist |= BCE_IF_HWASSIST;
    +			else
    +				ifp->if_hwassist &= ~BCE_IF_HWASSIST;
    +		}
    +
    +		/* Toggle the RX checksum capabilities enable flag. */
    +		if (mask & IFCAP_RXCSUM &&
    +		    ifp->if_capabilities & IFCAP_RXCSUM)
    +			ifp->if_capenable ^= IFCAP_RXCSUM;
    +
    +		/* Toggle the TSO capabilities enable flag. */
    +		if (bce_tso_enable && (mask & IFCAP_TSO4) &&
    +		    ifp->if_capabilities & IFCAP_TSO4) {
    +			ifp->if_capenable ^= IFCAP_TSO4;
    +			if (IFCAP_TSO4 & ifp->if_capenable)
    +				ifp->if_hwassist |= CSUM_TSO;
    +			else
    +				ifp->if_hwassist &= ~CSUM_TSO;
    +		}
    +
    +		if (mask & IFCAP_VLAN_HWCSUM &&
    +		    ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
    +			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
    +
    +		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
    +		/*
    +		 * Don't actually disable VLAN tag stripping as
    +		 * management firmware (ASF/IPMI/UMP) requires the
    +		 * feature. If VLAN tag stripping is disabled driver
    +		 * will manually reconstruct the VLAN frame by
    +		 * appending stripped VLAN tag.
    +		 */
    +		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)) {
    +			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
    +			if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
    +			    == 0)
    +				ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
    +		}
    +		VLAN_CAPABILITIES(ifp);
    +		break;
    +	default:
    +		/* We don't know how to handle the IOCTL, pass it on. */
    +		error = ether_ioctl(ifp, command, data);
    +		break;
     	}
     
     	DBEXIT(BCE_VERBOSE_MISC);
    @@ -7302,15 +7273,15 @@ bce_watchdog(struct bce_softc *sc)
     		__FILE__, __LINE__);
     
     	DBRUNMSG(BCE_INFO,
    -		bce_dump_driver_state(sc);
    -		bce_dump_status_block(sc);
    -		bce_dump_stats_block(sc);
    -		bce_dump_ftqs(sc);
    -		bce_dump_txp_state(sc, 0);
    -		bce_dump_rxp_state(sc, 0);
    -		bce_dump_tpat_state(sc, 0);
    -		bce_dump_cp_state(sc, 0);
    -		bce_dump_com_state(sc, 0));
    +	    bce_dump_driver_state(sc);
    +	    bce_dump_status_block(sc);
    +	    bce_dump_stats_block(sc);
    +	    bce_dump_ftqs(sc);
    +	    bce_dump_txp_state(sc, 0);
    +	    bce_dump_rxp_state(sc, 0);
    +	    bce_dump_tpat_state(sc, 0);
    +	    bce_dump_cp_state(sc, 0);
    +	    bce_dump_com_state(sc, 0));
     
     	DBRUN(bce_breakpoint(sc));
     
    @@ -7348,6 +7319,7 @@ bce_intr(void *xsc)
     
     	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
     	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
    +	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_stats_block(sc));
     
     	BCE_LOCK(sc);
     
    @@ -7364,16 +7336,17 @@ bce_intr(void *xsc)
     	 * interrupt then there's nothing to do.
     	 */
     	if ((sc->status_block->status_idx == sc->last_status_idx) &&
    -		(REG_RD(sc, BCE_PCICFG_MISC_STATUS) & BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
    -			DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
    -				__FUNCTION__);
    -			goto bce_intr_exit;
    +	    (REG_RD(sc, BCE_PCICFG_MISC_STATUS) & 
    +	     BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
    +		DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
    +		    __FUNCTION__);
    +		goto bce_intr_exit;
     	}
     
     	/* Ack the interrupt and stop others from occuring. */
     	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
    -		BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
    -		BCE_PCICFG_INT_ACK_CMD_MASK_INT);
    +	    BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
    +	    BCE_PCICFG_INT_ACK_CMD_MASK_INT);
     
     	/* Check if the hardware has finished any work. */
     	hw_rx_cons = bce_get_hw_rx_cons(sc);
    @@ -7384,35 +7357,39 @@ bce_intr(void *xsc)
     
     		status_attn_bits = sc->status_block->status_attn_bits;
     
    -	DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
    -		BCE_PRINTF("Simulating unexpected status attention bit set.");
    -		sc->unexpected_attention_sim_count++;
    -		status_attn_bits = status_attn_bits | STATUS_ATTN_BITS_PARITY_ERROR);
    +		DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
    +		    BCE_PRINTF("Simulating unexpected status attention "
    +		    "bit set.");
    +		    sc->unexpected_attention_sim_count++;
    +		    status_attn_bits = status_attn_bits | 
    +		    STATUS_ATTN_BITS_PARITY_ERROR);
     
     		/* Was it a link change interrupt? */
     		if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
    -			(sc->status_block->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) {
    +		    (sc->status_block->status_attn_bits_ack & 
    +		     STATUS_ATTN_BITS_LINK_STATE)) {
     			bce_phy_intr(sc);
     
    -			/* Clear any transient status updates during link state change. */
    -			REG_WR(sc, BCE_HC_COMMAND,
    -				sc->hc_command | BCE_HC_COMMAND_COAL_NOW_WO_INT);
    +			/* Clear transient updates during link state change. */
    +			REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | 
    +			    BCE_HC_COMMAND_COAL_NOW_WO_INT);
     			REG_RD(sc, BCE_HC_COMMAND);
     		}
     
    -		/* If any other attention is asserted then the chip is toast. */
    +		/* If any other attention is asserted, the chip is toast. */
     		if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
    -			(sc->status_block->status_attn_bits_ack &
    -			~STATUS_ATTN_BITS_LINK_STATE))) {
    +		    (sc->status_block->status_attn_bits_ack &
    +		    ~STATUS_ATTN_BITS_LINK_STATE))) {
     
    -		sc->unexpected_attention_count++;
    +			sc->unexpected_attention_count++;
     
    -			BCE_PRINTF("%s(%d): Fatal attention detected: 0x%08X\n",
    -				__FILE__, __LINE__, sc->status_block->status_attn_bits);
    +			BCE_PRINTF("%s(%d): Fatal attention detected: "
    +			    "0x%08X\n",	__FILE__, __LINE__, 
    +			    sc->status_block->status_attn_bits);
     
     			DBRUNMSG(BCE_FATAL,
    -				if (unexpected_attention_sim_control == 0)
    -					bce_breakpoint(sc));
    +			    if (unexpected_attention_sim_control == 0)
    +				bce_breakpoint(sc));
     
     			bce_init_locked(sc);
     			goto bce_intr_exit;
    @@ -7426,18 +7403,25 @@ bce_intr(void *xsc)
     		if (hw_tx_cons != sc->hw_tx_cons)
     			bce_tx_intr(sc);
     
    -		/* Save the status block index value for use during the next interrupt. */
    +		/* Save status block index value for the next interrupt. */
     		sc->last_status_idx = sc->status_block->status_idx;
     
    -		/* Prevent speculative reads from getting ahead of the status block. */
    + 		/*
    + 		 * Prevent speculative reads from getting
    + 		 * ahead of the status block.
    +		 */
     		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
    -			BUS_SPACE_BARRIER_READ);
    +		    BUS_SPACE_BARRIER_READ);
     
    -		/* If there's no work left then exit the interrupt service routine. */
    + 		/*
    + 		 * If there's no work left then exit the
    + 		 * interrupt service routine.
    +		 */
     		hw_rx_cons = bce_get_hw_rx_cons(sc);
     		hw_tx_cons = bce_get_hw_tx_cons(sc);
     
    -		if ((hw_rx_cons == sc->hw_rx_cons) && (hw_tx_cons == sc->hw_tx_cons))
    +		if ((hw_rx_cons == sc->hw_rx_cons) && 
    +		    (hw_tx_cons == sc->hw_tx_cons))
     			break;
     
     	}
    @@ -7449,7 +7433,8 @@ bce_intr(void *xsc)
     	bce_enable_intr(sc, 0);
     
     	/* Handle any frames that arrived while handling the interrupt. */
    -	if (ifp->if_drv_flags & IFF_DRV_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
    +	if (ifp->if_drv_flags & IFF_DRV_RUNNING && 
    +	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
     		bce_start_locked(ifp);
     
     bce_intr_exit:
    @@ -7482,7 +7467,7 @@ bce_set_rx_mode(struct bce_softc *sc)
     
     	/* Initialize receive mode default settings. */
     	rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
    -			    BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
    +	    BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
     	sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
     
     	/*
    @@ -7490,7 +7475,7 @@ bce_set_rx_mode(struct bce_softc *sc)
     	 * be enbled.
     	 */
     	if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
    -		(!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
    +	    (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
     		rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
     
     	/*
    @@ -7533,8 +7518,8 @@ bce_set_rx_mode(struct bce_softc *sc)
     
     	/* Only make changes if the recive mode has actually changed. */
     	if (rx_mode != sc->rx_mode) {
    -		DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: 0x%08X\n",
    -			rx_mode);
    +		DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: "
    +		    "0x%08X\n", rx_mode);
     
     		sc->rx_mode = rx_mode;
     		REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
    @@ -7575,183 +7560,187 @@ bce_stats_update(struct bce_softc *sc)
     	 */
     	if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
     	    !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
    -		ifp->if_oerrors += (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
    +		ifp->if_oerrors += 
    +		    (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
     
     	/*
     	 * Update the sysctl statistics from the
     	 * hardware statistics.
     	 */
     	sc->stat_IfHCInOctets =
    -		((u64) stats->stat_IfHCInOctets_hi << 32) +
    -		 (u64) stats->stat_IfHCInOctets_lo;
    +	    ((u64) stats->stat_IfHCInOctets_hi << 32) +
    +	     (u64) stats->stat_IfHCInOctets_lo;
     
     	sc->stat_IfHCInBadOctets =
    -		((u64) stats->stat_IfHCInBadOctets_hi << 32) +
    -		 (u64) stats->stat_IfHCInBadOctets_lo;
    +	    ((u64) stats->stat_IfHCInBadOctets_hi << 32) +
    +	     (u64) stats->stat_IfHCInBadOctets_lo;
     
     	sc->stat_IfHCOutOctets =
    -		((u64) stats->stat_IfHCOutOctets_hi << 32) +
    -		 (u64) stats->stat_IfHCOutOctets_lo;
    +	    ((u64) stats->stat_IfHCOutOctets_hi << 32) +
    +	     (u64) stats->stat_IfHCOutOctets_lo;
     
     	sc->stat_IfHCOutBadOctets =
    -		((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
    -		 (u64) stats->stat_IfHCOutBadOctets_lo;
    +	    ((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
    +	     (u64) stats->stat_IfHCOutBadOctets_lo;
     
     	sc->stat_IfHCInUcastPkts =
    -		((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
    -		 (u64) stats->stat_IfHCInUcastPkts_lo;
    +	    ((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
    +	     (u64) stats->stat_IfHCInUcastPkts_lo;
     
     	sc->stat_IfHCInMulticastPkts =
    -		((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
    -		 (u64) stats->stat_IfHCInMulticastPkts_lo;
    +	    ((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
    +	     (u64) stats->stat_IfHCInMulticastPkts_lo;
     
     	sc->stat_IfHCInBroadcastPkts =
    -		((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
    -		 (u64) stats->stat_IfHCInBroadcastPkts_lo;
    +	    ((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
    +	     (u64) stats->stat_IfHCInBroadcastPkts_lo;
     
     	sc->stat_IfHCOutUcastPkts =
    -		((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
    -		 (u64) stats->stat_IfHCOutUcastPkts_lo;
    +	    ((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
    +	     (u64) stats->stat_IfHCOutUcastPkts_lo;
     
     	sc->stat_IfHCOutMulticastPkts =
    -		((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
    -		 (u64) stats->stat_IfHCOutMulticastPkts_lo;
    +	    ((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
    +	     (u64) stats->stat_IfHCOutMulticastPkts_lo;
     
     	sc->stat_IfHCOutBroadcastPkts =
    -		((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
    -		 (u64) stats->stat_IfHCOutBroadcastPkts_lo;
    +	    ((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
    +	     (u64) stats->stat_IfHCOutBroadcastPkts_lo;
    +
    +	/* ToDo: Preserve counters beyond 32 bits? */
    +	/* ToDo: Read the statistics from auto-clear regs? */
     
     	sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
    -		stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
    +	    stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
     
     	sc->stat_Dot3StatsCarrierSenseErrors =
    -		stats->stat_Dot3StatsCarrierSenseErrors;
    +	    stats->stat_Dot3StatsCarrierSenseErrors;
     
     	sc->stat_Dot3StatsFCSErrors =
    -		stats->stat_Dot3StatsFCSErrors;
    +	    stats->stat_Dot3StatsFCSErrors;
     
     	sc->stat_Dot3StatsAlignmentErrors =
    -		stats->stat_Dot3StatsAlignmentErrors;
    +	    stats->stat_Dot3StatsAlignmentErrors;
     
     	sc->stat_Dot3StatsSingleCollisionFrames =
    -		stats->stat_Dot3StatsSingleCollisionFrames;
    +	    stats->stat_Dot3StatsSingleCollisionFrames;
     
     	sc->stat_Dot3StatsMultipleCollisionFrames =
    -		stats->stat_Dot3StatsMultipleCollisionFrames;
    +	    stats->stat_Dot3StatsMultipleCollisionFrames;
     
     	sc->stat_Dot3StatsDeferredTransmissions =
    -		stats->stat_Dot3StatsDeferredTransmissions;
    +	    stats->stat_Dot3StatsDeferredTransmissions;
     
     	sc->stat_Dot3StatsExcessiveCollisions =
    -		stats->stat_Dot3StatsExcessiveCollisions;
    +	    stats->stat_Dot3StatsExcessiveCollisions;
     
     	sc->stat_Dot3StatsLateCollisions =
    -		stats->stat_Dot3StatsLateCollisions;
    +	    stats->stat_Dot3StatsLateCollisions;
     
     	sc->stat_EtherStatsCollisions =
    -		stats->stat_EtherStatsCollisions;
    +	    stats->stat_EtherStatsCollisions;
     
     	sc->stat_EtherStatsFragments =
    -		stats->stat_EtherStatsFragments;
    +	    stats->stat_EtherStatsFragments;
     
     	sc->stat_EtherStatsJabbers =
    -		stats->stat_EtherStatsJabbers;
    +	    stats->stat_EtherStatsJabbers;
     
     	sc->stat_EtherStatsUndersizePkts =
    -		stats->stat_EtherStatsUndersizePkts;
    +	    stats->stat_EtherStatsUndersizePkts;
     
     	sc->stat_EtherStatsOversizePkts =
    -		stats->stat_EtherStatsOversizePkts;
    +	     stats->stat_EtherStatsOversizePkts;
     
     	sc->stat_EtherStatsPktsRx64Octets =
    -		stats->stat_EtherStatsPktsRx64Octets;
    +	    stats->stat_EtherStatsPktsRx64Octets;
     
     	sc->stat_EtherStatsPktsRx65Octetsto127Octets =
    -		stats->stat_EtherStatsPktsRx65Octetsto127Octets;
    +	    stats->stat_EtherStatsPktsRx65Octetsto127Octets;
     
     	sc->stat_EtherStatsPktsRx128Octetsto255Octets =
    -		stats->stat_EtherStatsPktsRx128Octetsto255Octets;
    +	    stats->stat_EtherStatsPktsRx128Octetsto255Octets;
     
     	sc->stat_EtherStatsPktsRx256Octetsto511Octets =
    -		stats->stat_EtherStatsPktsRx256Octetsto511Octets;
    +	    stats->stat_EtherStatsPktsRx256Octetsto511Octets;
     
     	sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
    -		stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
    +	    stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
     
     	sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
    -		stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
    +	    stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
     
     	sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
    -		stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
    +	    stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
     
     	sc->stat_EtherStatsPktsTx64Octets =
    -		stats->stat_EtherStatsPktsTx64Octets;
    +	    stats->stat_EtherStatsPktsTx64Octets;
     
     	sc->stat_EtherStatsPktsTx65Octetsto127Octets =
    -		stats->stat_EtherStatsPktsTx65Octetsto127Octets;
    +	    stats->stat_EtherStatsPktsTx65Octetsto127Octets;
     
     	sc->stat_EtherStatsPktsTx128Octetsto255Octets =
    -		stats->stat_EtherStatsPktsTx128Octetsto255Octets;
    +	    stats->stat_EtherStatsPktsTx128Octetsto255Octets;
     
     	sc->stat_EtherStatsPktsTx256Octetsto511Octets =
    -		stats->stat_EtherStatsPktsTx256Octetsto511Octets;
    +	    stats->stat_EtherStatsPktsTx256Octetsto511Octets;
     
     	sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
    -		stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
    +	    stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
     
     	sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
    -		stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
    +	    stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
     
     	sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
    -		stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
    +	    stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
     
     	sc->stat_XonPauseFramesReceived =
    -		stats->stat_XonPauseFramesReceived;
    +	    stats->stat_XonPauseFramesReceived;
     
     	sc->stat_XoffPauseFramesReceived =
    -		stats->stat_XoffPauseFramesReceived;
    +	    stats->stat_XoffPauseFramesReceived;
     
     	sc->stat_OutXonSent =
    -		stats->stat_OutXonSent;
    +	    stats->stat_OutXonSent;
     
     	sc->stat_OutXoffSent =
    -		stats->stat_OutXoffSent;
    +	    stats->stat_OutXoffSent;
     
     	sc->stat_FlowControlDone =
    -		stats->stat_FlowControlDone;
    +	    stats->stat_FlowControlDone;
     
     	sc->stat_MacControlFramesReceived =
    -		stats->stat_MacControlFramesReceived;
    +	    stats->stat_MacControlFramesReceived;
     
     	sc->stat_XoffStateEntered =
    -		stats->stat_XoffStateEntered;
    +	    stats->stat_XoffStateEntered;
     
     	sc->stat_IfInFramesL2FilterDiscards =
    -		stats->stat_IfInFramesL2FilterDiscards;
    +	    stats->stat_IfInFramesL2FilterDiscards;
     
     	sc->stat_IfInRuleCheckerDiscards =
    -		stats->stat_IfInRuleCheckerDiscards;
    +	    stats->stat_IfInRuleCheckerDiscards;
     
     	sc->stat_IfInFTQDiscards =
    -		stats->stat_IfInFTQDiscards;
    +	    stats->stat_IfInFTQDiscards;
     
     	sc->stat_IfInMBUFDiscards =
    -		stats->stat_IfInMBUFDiscards;
    +	    stats->stat_IfInMBUFDiscards;
     
     	sc->stat_IfInRuleCheckerP4Hit =
    -		stats->stat_IfInRuleCheckerP4Hit;
    +	    stats->stat_IfInRuleCheckerP4Hit;
     
     	sc->stat_CatchupInRuleCheckerDiscards =
    -		stats->stat_CatchupInRuleCheckerDiscards;
    +	    stats->stat_CatchupInRuleCheckerDiscards;
     
     	sc->stat_CatchupInFTQDiscards =
    -		stats->stat_CatchupInFTQDiscards;
    +	    stats->stat_CatchupInFTQDiscards;
     
     	sc->stat_CatchupInMBUFDiscards =
    -		stats->stat_CatchupInMBUFDiscards;
    +	    stats->stat_CatchupInMBUFDiscards;
     
     	sc->stat_CatchupInRuleCheckerP4Hit =
    -		stats->stat_CatchupInRuleCheckerP4Hit;
    +	    stats->stat_CatchupInRuleCheckerP4Hit;
     
     	sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
     
    @@ -7760,26 +7749,26 @@ bce_stats_update(struct bce_softc *sc)
     	 * hardware statistics.
     	 */
     	ifp->if_collisions =
    -		(u_long) sc->stat_EtherStatsCollisions;
    +	    (u_long) sc->stat_EtherStatsCollisions;
     
     	/* ToDo: This method loses soft errors. */
     	ifp->if_ierrors =
    -		(u_long) sc->stat_EtherStatsUndersizePkts +
    -		(u_long) sc->stat_EtherStatsOversizePkts +
    -		(u_long) sc->stat_IfInMBUFDiscards +
    -		(u_long) sc->stat_Dot3StatsAlignmentErrors +
    -		(u_long) sc->stat_Dot3StatsFCSErrors +
    -		(u_long) sc->stat_IfInRuleCheckerDiscards +
    -		(u_long) sc->stat_IfInFTQDiscards +
    -		(u_long) sc->com_no_buffers;
    +	    (u_long) sc->stat_EtherStatsUndersizePkts +
    +	    (u_long) sc->stat_EtherStatsOversizePkts +
    +	    (u_long) sc->stat_IfInMBUFDiscards +
    +	    (u_long) sc->stat_Dot3StatsAlignmentErrors +
    +	    (u_long) sc->stat_Dot3StatsFCSErrors +
    +	    (u_long) sc->stat_IfInRuleCheckerDiscards +
    +	    (u_long) sc->stat_IfInFTQDiscards +
    +	    (u_long) sc->com_no_buffers;
     
     	/* ToDo: This method loses soft errors. */
     	ifp->if_oerrors =
    -		(u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
    -		(u_long) sc->stat_Dot3StatsExcessiveCollisions +
    -		(u_long) sc->stat_Dot3StatsLateCollisions;
    +	    (u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
    +	    (u_long) sc->stat_Dot3StatsExcessiveCollisions +
    +	    (u_long) sc->stat_Dot3StatsLateCollisions;
     
    -	/* ToDo: Add additional statistics. */
    +	/* ToDo: Add additional statistics? */
     
     	DBEXIT(BCE_EXTREME_MISC);
     }
    @@ -7806,6 +7795,33 @@ bce_pulse(void *xsc)
     	msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
     	bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
     
    +	/* Update the bootcode condition. */
    +	sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
    +
    +	/* Report whether the bootcode still knows the driver is running. */
    +	if (sc->bce_drv_cardiac_arrest == FALSE) {
    +		if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) {
    +			sc->bce_drv_cardiac_arrest = TRUE;
    +			BCE_PRINTF("%s(): Bootcode lost the driver pulse! "
    +			    "(bc_state = 0x%08X)\n", __FUNCTION__, 
    +			    sc->bc_state);
    +		}
    +	} else {
    + 		/*
    + 		 * Not supported by all bootcode versions.
    + 		 * (v5.0.11+ and v5.2.1+)  Older bootcode
    + 		 * will require the driver to reset the
    + 		 * controller to clear this condition.
    +		 */
    +		if (sc->bc_state & BCE_CONDITION_DRV_PRESENT) {
    +			sc->bce_drv_cardiac_arrest = FALSE;
    +			BCE_PRINTF("%s(): Bootcode found the driver pulse! "
    +			    "(bc_state = 0x%08X)\n", __FUNCTION__, 
    +			    sc->bc_state);
    +		}
    +	}
    +
    +
     	/* Schedule the next pulse. */
     	callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
     
    @@ -7848,7 +7864,7 @@ bce_tick(void *xsc)
     	bce_watchdog(sc);
     
     	/* If link is up already up then we're done. */
    -	if (sc->bce_link)
    +	if (sc->bce_link_up == TRUE)
     		goto bce_tick_exit;
     
     	/* Link is down.  Check what the PHY's doing. */
    @@ -7858,16 +7874,19 @@ bce_tick(void *xsc)
     	/* Check if the link has come up. */
     	if ((mii->mii_media_status & IFM_ACTIVE) &&
     	    (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
    -		DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n", __FUNCTION__);
    -		sc->bce_link++;
    +		DBPRINT(sc, BCE_VERBOSE_MISC, 
    +		    "%s(): Link up!\n", __FUNCTION__);
    +		sc->bce_link_up = TRUE;
     		if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
    -		    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) &&
    +		    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
    +		    IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
     		    bootverbose)
     			BCE_PRINTF("Gigabit link up!\n");
    +
     		/* Now that link is up, handle any outstanding TX traffic. */
     		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
    -			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found pending TX traffic.\n",
    -				 __FUNCTION__);
    +			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found "
    +			    "pending TX traffic.\n", __FUNCTION__);
     			bce_start_locked(ifp);
     		}
     	}
    @@ -7888,22 +7907,22 @@ bce_tick_exit:
     static int
     bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
     {
    -        int error;
    -        int result;
    -        struct bce_softc *sc;
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
     
    -        result = -1;
    -        error = sysctl_handle_int(oidp, &result, 0, req);
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
     
    -        if (error || !req->newptr)
    -                return (error);
    +	if (error || !req->newptr)
    +		return (error);
     
    -        if (result == 1) {
    -                sc = (struct bce_softc *)arg1;
    -                bce_dump_driver_state(sc);
    -        }
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_dump_driver_state(sc);
    +	}
     
    -        return error;
    +	return error;
     }
     
     
    @@ -7916,22 +7935,78 @@ bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
     static int
     bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
     {
    -        int error;
    -        int result;
    -        struct bce_softc *sc;
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
     
    -        result = -1;
    -        error = sysctl_handle_int(oidp, &result, 0, req);
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
     
    -        if (error || !req->newptr)
    -                return (error);
    +	if (error || !req->newptr)
    +		return (error);
     
    -        if (result == 1) {
    -                sc = (struct bce_softc *)arg1;
    -                bce_dump_hw_state(sc);
    -        }
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_dump_hw_state(sc);
    +	}
     
    -        return error;
    +	return error;
    +}
    +
    +
    +/****************************************************************************/
    +/* Allows the status block to be dumped through the sysctl interface.       */
    +/*                                                                          */
    +/* Returns:                                                                 */
    +/*   0 for success, positive value for failure.                             */
    +/****************************************************************************/
    +static int
    +bce_sysctl_status_block(SYSCTL_HANDLER_ARGS)
    +{
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
    +
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
    +
    +	if (error || !req->newptr)
    +		return (error);
    +
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_dump_status_block(sc);
    +	}
    +
    +	return error;
    +}
    +
    +
    +/****************************************************************************/
    +/* Allows the stats block to be dumped through the sysctl interface.        */
    +/*                                                                          */
    +/* Returns:                                                                 */
    +/*   0 for success, positive value for failure.                             */
    +/****************************************************************************/
    +static int
    +bce_sysctl_stats_block(SYSCTL_HANDLER_ARGS)
    +{
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
    +
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
    +
    +	if (error || !req->newptr)
    +		return (error);
    +
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_dump_stats_block(sc);
    +	}
    +
    +	return error;
     }
     
     
    @@ -7944,50 +8019,78 @@ bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
     static int
     bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
     {
    -        int error;
    -        int result;
    -        struct bce_softc *sc;
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
     
    -        result = -1;
    -        error = sysctl_handle_int(oidp, &result, 0, req);
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
     
    -        if (error || !req->newptr)
    -                return (error);
    +	if (error || !req->newptr)
    +		return (error);
     
    -        if (result == 1) {
    -                sc = (struct bce_softc *)arg1;
    -                bce_dump_bc_state(sc);
    -        }
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_dump_bc_state(sc);
    +	}
     
    -        return error;
    +	return error;
     }
     
     
     /****************************************************************************/
    -/* Provides a sysctl interface to allow dumping the RX chain.               */
    +/* Provides a sysctl interface to allow dumping the RX BD chain.            */
     /*                                                                          */
     /* Returns:                                                                 */
     /*   0 for success, positive value for failure.                             */
     /****************************************************************************/
     static int
    -bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
    +bce_sysctl_dump_rx_bd_chain(SYSCTL_HANDLER_ARGS)
     {
    -        int error;
    -        int result;
    -        struct bce_softc *sc;
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
     
    -        result = -1;
    -        error = sysctl_handle_int(oidp, &result, 0, req);
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
     
    -        if (error || !req->newptr)
    -                return (error);
    +	if (error || !req->newptr)
    +		return (error);
     
    -        if (result == 1) {
    -                sc = (struct bce_softc *)arg1;
    -                bce_dump_rx_chain(sc, 0, TOTAL_RX_BD);
    -        }
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD);
    +	}
     
    -        return error;
    +	return error;
    +}
    +
    +
    +/****************************************************************************/
    +/* Provides a sysctl interface to allow dumping the RX MBUF chain.          */
    +/*                                                                          */
    +/* Returns:                                                                 */
    +/*   0 for success, positive value for failure.                             */
    +/****************************************************************************/
    +static int
    +bce_sysctl_dump_rx_mbuf_chain(SYSCTL_HANDLER_ARGS)
    +{
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
    +
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
    +
    +	if (error || !req->newptr)
    +		return (error);
    +
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
    +	}
    +
    +	return error;
     }
     
     
    @@ -8000,22 +8103,22 @@ bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
     static int
     bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
     {
    -        int error;
    -        int result;
    -        struct bce_softc *sc;
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
     
    -        result = -1;
    -        error = sysctl_handle_int(oidp, &result, 0, req);
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
     
    -        if (error || !req->newptr)
    -                return (error);
    +	if (error || !req->newptr)
    +		return (error);
     
    -        if (result == 1) {
    -                sc = (struct bce_softc *)arg1;
    -                bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
    -        }
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
    +	}
     
    -        return error;
    +	return error;
     }
     
     
    @@ -8029,22 +8132,22 @@ bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
     static int
     bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
     {
    -        int error;
    -        int result;
    -        struct bce_softc *sc;
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
     
    -        result = -1;
    -        error = sysctl_handle_int(oidp, &result, 0, req);
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
     
    -        if (error || !req->newptr)
    -                return (error);
    +	if (error || !req->newptr)
    +		return (error);
     
    -        if (result == 1) {
    -                sc = (struct bce_softc *)arg1;
    -                bce_dump_pg_chain(sc, 0, TOTAL_PG_BD);
    -        }
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_dump_pg_chain(sc, 0, TOTAL_PG_BD);
    +	}
     
    -        return error;
    +	return error;
     }
     #endif
     
    @@ -8177,22 +8280,22 @@ bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
     static int
     bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
     {
    -        int error;
    -        int result;
    -        struct bce_softc *sc;
    +	int error;
    +	int result;
    +	struct bce_softc *sc;
     
    -        result = -1;
    -        error = sysctl_handle_int(oidp, &result, 0, req);
    +	result = -1;
    +	error = sysctl_handle_int(oidp, &result, 0, req);
     
    -        if (error || !req->newptr)
    -                return (error);
    +	if (error || !req->newptr)
    +		return (error);
     
    -        if (result == 1) {
    -                sc = (struct bce_softc *)arg1;
    -                bce_breakpoint(sc);
    -        }
    +	if (result == 1) {
    +		sc = (struct bce_softc *)arg1;
    +		bce_breakpoint(sc);
    +	}
     
    -        return error;
    +	return error;
     }
     #endif
     
    @@ -8216,467 +8319,474 @@ bce_add_sysctls(struct bce_softc *sc)
     
     #ifdef BCE_DEBUG
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"l2fhdr_error_sim_control",
    -		CTLFLAG_RW, &l2fhdr_error_sim_control,
    -		0, "Debug control to force l2fhdr errors");
    +	    "l2fhdr_error_sim_control",
    +	    CTLFLAG_RW, &l2fhdr_error_sim_control,
    +	    0, "Debug control to force l2fhdr errors");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"l2fhdr_error_sim_count",
    -		CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
    -		0, "Number of simulated l2_fhdr errors");
    +	    "l2fhdr_error_sim_count",
    +	    CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
    +	    0, "Number of simulated l2_fhdr errors");
     #endif
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"l2fhdr_error_count",
    -		CTLFLAG_RD, &sc->l2fhdr_error_count,
    -		0, "Number of l2_fhdr errors");
    +	    "l2fhdr_error_count",
    +	    CTLFLAG_RD, &sc->l2fhdr_error_count,
    +	    0, "Number of l2_fhdr errors");
     
     #ifdef BCE_DEBUG
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"mbuf_alloc_failed_sim_control",
    -		CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
    -		0, "Debug control to force mbuf allocation failures");
    +	    "mbuf_alloc_failed_sim_control",
    +	    CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
    +	    0, "Debug control to force mbuf allocation failures");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"mbuf_alloc_failed_sim_count",
    -		CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
    -		0, "Number of simulated mbuf cluster allocation failures");
    +	    "mbuf_alloc_failed_sim_count",
    +	    CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
    +	    0, "Number of simulated mbuf cluster allocation failures");
     #endif
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"mbuf_alloc_failed_count",
    -		CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
    -		0, "Number of mbuf allocation failures");
    +	    "mbuf_alloc_failed_count",
    +	    CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
    +	    0, "Number of mbuf allocation failures");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"fragmented_mbuf_count",
    -		CTLFLAG_RD, &sc->fragmented_mbuf_count,
    -		0, "Number of fragmented mbufs");
    +	    "fragmented_mbuf_count",
    +	    CTLFLAG_RD, &sc->fragmented_mbuf_count,
    +	    0, "Number of fragmented mbufs");
     
     #ifdef BCE_DEBUG
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"dma_map_addr_failed_sim_control",
    -		CTLFLAG_RW, &dma_map_addr_failed_sim_control,
    -		0, "Debug control to force DMA mapping failures");
    +	    "dma_map_addr_failed_sim_control",
    +	    CTLFLAG_RW, &dma_map_addr_failed_sim_control,
    +	    0, "Debug control to force DMA mapping failures");
     
     	/* ToDo: Figure out how to update this value in bce_dma_map_addr(). */
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"dma_map_addr_failed_sim_count",
    -		CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
    -		0, "Number of simulated DMA mapping failures");
    +	    "dma_map_addr_failed_sim_count",
    +	    CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
    +	    0, "Number of simulated DMA mapping failures");
     	
     #endif
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"dma_map_addr_rx_failed_count",
    -		CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
    -		0, "Number of RX DMA mapping failures");
    +	    "dma_map_addr_rx_failed_count",
    +	    CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
    +	    0, "Number of RX DMA mapping failures");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"dma_map_addr_tx_failed_count",
    -		CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
    -		0, "Number of TX DMA mapping failures");
    +	    "dma_map_addr_tx_failed_count",
    +	    CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
    +	    0, "Number of TX DMA mapping failures");
     
     #ifdef BCE_DEBUG
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"unexpected_attention_sim_control",
    -		CTLFLAG_RW, &unexpected_attention_sim_control,
    -		0, "Debug control to simulate unexpected attentions");
    +	    "unexpected_attention_sim_control",
    +	    CTLFLAG_RW, &unexpected_attention_sim_control,
    +	    0, "Debug control to simulate unexpected attentions");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"unexpected_attention_sim_count",
    -		CTLFLAG_RW, &sc->unexpected_attention_sim_count,
    -		0, "Number of simulated unexpected attentions");
    +	    "unexpected_attention_sim_count",
    +	    CTLFLAG_RW, &sc->unexpected_attention_sim_count,
    +	    0, "Number of simulated unexpected attentions");
     #endif
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"unexpected_attention_count",
    -		CTLFLAG_RW, &sc->unexpected_attention_count,
    -		0, "Number of unexpected attentions");
    +	    "unexpected_attention_count",
    +	    CTLFLAG_RW, &sc->unexpected_attention_count,
    +	    0, "Number of unexpected attentions");
     
     #ifdef BCE_DEBUG
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"debug_bootcode_running_failure",
    -		CTLFLAG_RW, &bootcode_running_failure_sim_control,
    -		0, "Debug control to force bootcode running failures");
    +	    "debug_bootcode_running_failure",
    +	    CTLFLAG_RW, &bootcode_running_failure_sim_control,
    +	    0, "Debug control to force bootcode running failures");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"rx_low_watermark",
    -		CTLFLAG_RD, &sc->rx_low_watermark,
    -		0, "Lowest level of free rx_bd's");
    +	    "rx_low_watermark",
    +	    CTLFLAG_RD, &sc->rx_low_watermark,
    +	    0, "Lowest level of free rx_bd's");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"rx_empty_count",
    -		CTLFLAG_RD, &sc->rx_empty_count,
    -		0, "Number of times the RX chain was empty");
    +	    "rx_empty_count",
    +	    CTLFLAG_RD, &sc->rx_empty_count,
    +	    0, "Number of times the RX chain was empty");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"tx_hi_watermark",
    -		CTLFLAG_RD, &sc->tx_hi_watermark,
    -		0, "Highest level of used tx_bd's");
    +	    "tx_hi_watermark",
    +	    CTLFLAG_RD, &sc->tx_hi_watermark,
    +	    0, "Highest level of used tx_bd's");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"tx_full_count",
    -		CTLFLAG_RD, &sc->tx_full_count,
    -		0, "Number of times the TX chain was full");
    +	    "tx_full_count",
    +	    CTLFLAG_RD, &sc->tx_full_count,
    +	    0, "Number of times the TX chain was full");
     
     	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
    -		"requested_tso_frames",
    -		CTLFLAG_RD, &sc->requested_tso_frames,
    -		0, "Number of TSO frames received");
    +	    "requested_tso_frames",
    +	    CTLFLAG_RD, &sc->requested_tso_frames,
    +	    0, "Number of TSO frames received");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"rx_interrupts",
    -		CTLFLAG_RD, &sc->rx_interrupts,
    -		0, "Number of RX interrupts");
    +	    "rx_interrupts",
    +	    CTLFLAG_RD, &sc->rx_interrupts,
    +	    0, "Number of RX interrupts");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"tx_interrupts",
    -		CTLFLAG_RD, &sc->tx_interrupts,
    -		0, "Number of TX interrupts");
    -
    -	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"rx_intr_time",
    -		CTLFLAG_RD, &sc->rx_intr_time,
    -		"RX interrupt time");
    -
    -	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"tx_intr_time",
    -		CTLFLAG_RD, &sc->tx_intr_time,
    -		"TX interrupt time");
    +	    "tx_interrupts",
    +	    CTLFLAG_RD, &sc->tx_interrupts,
    +	    0, "Number of TX interrupts");
     #endif
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHcInOctets",
    -		CTLFLAG_RD, &sc->stat_IfHCInOctets,
    -		"Bytes received");
    +	    "stat_IfHcInOctets",
    +	    CTLFLAG_RD, &sc->stat_IfHCInOctets,
    +	    "Bytes received");
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHCInBadOctets",
    -		CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
    -		"Bad bytes received");
    +	    "stat_IfHCInBadOctets",
    +	    CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
    +	    "Bad bytes received");
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHCOutOctets",
    -		CTLFLAG_RD, &sc->stat_IfHCOutOctets,
    -		"Bytes sent");
    +	    "stat_IfHCOutOctets",
    +	    CTLFLAG_RD, &sc->stat_IfHCOutOctets,
    +	    "Bytes sent");
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHCOutBadOctets",
    -		CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
    -		"Bad bytes sent");
    +	    "stat_IfHCOutBadOctets",
    +	    CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
    +	    "Bad bytes sent");
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHCInUcastPkts",
    -		CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
    -		"Unicast packets received");
    +	    "stat_IfHCInUcastPkts",
    +	    CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
    +	    "Unicast packets received");
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHCInMulticastPkts",
    -		CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
    -		"Multicast packets received");
    +	    "stat_IfHCInMulticastPkts",
    +	    CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
    +	    "Multicast packets received");
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHCInBroadcastPkts",
    -		CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
    -		"Broadcast packets received");
    +	    "stat_IfHCInBroadcastPkts",
    +	    CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
    +	    "Broadcast packets received");
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHCOutUcastPkts",
    -		CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
    -		"Unicast packets sent");
    +	    "stat_IfHCOutUcastPkts",
    +	    CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
    +	    "Unicast packets sent");
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHCOutMulticastPkts",
    -		CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
    -		"Multicast packets sent");
    +	    "stat_IfHCOutMulticastPkts",
    +	    CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
    +	    "Multicast packets sent");
     
     	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
    -		"stat_IfHCOutBroadcastPkts",
    -		CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
    -		"Broadcast packets sent");
    +	    "stat_IfHCOutBroadcastPkts",
    +	    CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
    +	    "Broadcast packets sent");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
    -		CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
    -		0, "Internal MAC transmit errors");
    +	    "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
    +	    CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
    +	    0, "Internal MAC transmit errors");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_Dot3StatsCarrierSenseErrors",
    -		CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
    -		0, "Carrier sense errors");
    +	    "stat_Dot3StatsCarrierSenseErrors",
    +	    CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
    +	    0, "Carrier sense errors");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_Dot3StatsFCSErrors",
    -		CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
    -		0, "Frame check sequence errors");
    +	    "stat_Dot3StatsFCSErrors",
    +	    CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
    +	    0, "Frame check sequence errors");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_Dot3StatsAlignmentErrors",
    -		CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
    -		0, "Alignment errors");
    +	    "stat_Dot3StatsAlignmentErrors",
    +	    CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
    +	    0, "Alignment errors");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_Dot3StatsSingleCollisionFrames",
    -		CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
    -		0, "Single Collision Frames");
    +	    "stat_Dot3StatsSingleCollisionFrames",
    +	    CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
    +	    0, "Single Collision Frames");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_Dot3StatsMultipleCollisionFrames",
    -		CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
    -		0, "Multiple Collision Frames");
    +	    "stat_Dot3StatsMultipleCollisionFrames",
    +	    CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
    +	    0, "Multiple Collision Frames");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_Dot3StatsDeferredTransmissions",
    -		CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
    -		0, "Deferred Transmissions");
    +	    "stat_Dot3StatsDeferredTransmissions",
    +	    CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
    +	    0, "Deferred Transmissions");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_Dot3StatsExcessiveCollisions",
    -		CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
    -		0, "Excessive Collisions");
    +	    "stat_Dot3StatsExcessiveCollisions",
    +	    CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
    +	    0, "Excessive Collisions");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_Dot3StatsLateCollisions",
    -		CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
    -		0, "Late Collisions");
    +	    "stat_Dot3StatsLateCollisions",
    +	    CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
    +	    0, "Late Collisions");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsCollisions",
    -		CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
    -		0, "Collisions");
    +	    "stat_EtherStatsCollisions",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
    +	    0, "Collisions");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsFragments",
    -		CTLFLAG_RD, &sc->stat_EtherStatsFragments,
    -		0, "Fragments");
    +	    "stat_EtherStatsFragments",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsFragments,
    +	    0, "Fragments");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsJabbers",
    -		CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
    -		0, "Jabbers");
    +	    "stat_EtherStatsJabbers",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
    +	    0, "Jabbers");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsUndersizePkts",
    -		CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
    -		0, "Undersize packets");
    +	    "stat_EtherStatsUndersizePkts",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
    +	    0, "Undersize packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsOversizePkts",
    -		CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
    -		0, "stat_EtherStatsOversizePkts");
    +	    "stat_EtherStatsOversizePkts",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
    +	    0, "stat_EtherStatsOversizePkts");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsRx64Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
    -		0, "Bytes received in 64 byte packets");
    +	    "stat_EtherStatsPktsRx64Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
    +	    0, "Bytes received in 64 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsRx65Octetsto127Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
    -		0, "Bytes received in 65 to 127 byte packets");
    +	    "stat_EtherStatsPktsRx65Octetsto127Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
    +	    0, "Bytes received in 65 to 127 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsRx128Octetsto255Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
    -		0, "Bytes received in 128 to 255 byte packets");
    +	    "stat_EtherStatsPktsRx128Octetsto255Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
    +	    0, "Bytes received in 128 to 255 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsRx256Octetsto511Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
    -		0, "Bytes received in 256 to 511 byte packets");
    +	    "stat_EtherStatsPktsRx256Octetsto511Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
    +	    0, "Bytes received in 256 to 511 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsRx512Octetsto1023Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
    -		0, "Bytes received in 512 to 1023 byte packets");
    +	    "stat_EtherStatsPktsRx512Octetsto1023Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
    +	    0, "Bytes received in 512 to 1023 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsRx1024Octetsto1522Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
    -		0, "Bytes received in 1024 t0 1522 byte packets");
    +	    "stat_EtherStatsPktsRx1024Octetsto1522Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
    +	    0, "Bytes received in 1024 t0 1522 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsRx1523Octetsto9022Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
    -		0, "Bytes received in 1523 to 9022 byte packets");
    +	    "stat_EtherStatsPktsRx1523Octetsto9022Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
    +	    0, "Bytes received in 1523 to 9022 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsTx64Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
    -		0, "Bytes sent in 64 byte packets");
    +	    "stat_EtherStatsPktsTx64Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
    +	    0, "Bytes sent in 64 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsTx65Octetsto127Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
    -		0, "Bytes sent in 65 to 127 byte packets");
    +	    "stat_EtherStatsPktsTx65Octetsto127Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
    +	    0, "Bytes sent in 65 to 127 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsTx128Octetsto255Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
    -		0, "Bytes sent in 128 to 255 byte packets");
    +	    "stat_EtherStatsPktsTx128Octetsto255Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
    +	    0, "Bytes sent in 128 to 255 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsTx256Octetsto511Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
    -		0, "Bytes sent in 256 to 511 byte packets");
    +	    "stat_EtherStatsPktsTx256Octetsto511Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
    +	    0, "Bytes sent in 256 to 511 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsTx512Octetsto1023Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
    -		0, "Bytes sent in 512 to 1023 byte packets");
    +	    "stat_EtherStatsPktsTx512Octetsto1023Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
    +	    0, "Bytes sent in 512 to 1023 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsTx1024Octetsto1522Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
    -		0, "Bytes sent in 1024 to 1522 byte packets");
    +	    "stat_EtherStatsPktsTx1024Octetsto1522Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
    +	    0, "Bytes sent in 1024 to 1522 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_EtherStatsPktsTx1523Octetsto9022Octets",
    -		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
    -		0, "Bytes sent in 1523 to 9022 byte packets");
    +	    "stat_EtherStatsPktsTx1523Octetsto9022Octets",
    +	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
    +	    0, "Bytes sent in 1523 to 9022 byte packets");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_XonPauseFramesReceived",
    -		CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
    -		0, "XON pause frames receved");
    +	    "stat_XonPauseFramesReceived",
    +	    CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
    +	    0, "XON pause frames receved");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_XoffPauseFramesReceived",
    -		CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
    -		0, "XOFF pause frames received");
    +	    "stat_XoffPauseFramesReceived",
    +	    CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
    +	    0, "XOFF pause frames received");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_OutXonSent",
    -		CTLFLAG_RD, &sc->stat_OutXonSent,
    -		0, "XON pause frames sent");
    +	    "stat_OutXonSent",
    +	    CTLFLAG_RD, &sc->stat_OutXonSent,
    +	    0, "XON pause frames sent");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_OutXoffSent",
    -		CTLFLAG_RD, &sc->stat_OutXoffSent,
    -		0, "XOFF pause frames sent");
    +	    "stat_OutXoffSent",
    +	    CTLFLAG_RD, &sc->stat_OutXoffSent,
    +	    0, "XOFF pause frames sent");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_FlowControlDone",
    -		CTLFLAG_RD, &sc->stat_FlowControlDone,
    -		0, "Flow control done");
    +	    "stat_FlowControlDone",
    +	    CTLFLAG_RD, &sc->stat_FlowControlDone,
    +	    0, "Flow control done");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_MacControlFramesReceived",
    -		CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
    -		0, "MAC control frames received");
    +	    "stat_MacControlFramesReceived",
    +	    CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
    +	    0, "MAC control frames received");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_XoffStateEntered",
    -		CTLFLAG_RD, &sc->stat_XoffStateEntered,
    -		0, "XOFF state entered");
    +	    "stat_XoffStateEntered",
    +	    CTLFLAG_RD, &sc->stat_XoffStateEntered,
    +	    0, "XOFF state entered");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_IfInFramesL2FilterDiscards",
    -		CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
    -		0, "Received L2 packets discarded");
    +	    "stat_IfInFramesL2FilterDiscards",
    +	    CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
    +	    0, "Received L2 packets discarded");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_IfInRuleCheckerDiscards",
    -		CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
    -		0, "Received packets discarded by rule");
    +	    "stat_IfInRuleCheckerDiscards",
    +	    CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
    +	    0, "Received packets discarded by rule");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_IfInFTQDiscards",
    -		CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
    -		0, "Received packet FTQ discards");
    +	    "stat_IfInFTQDiscards",
    +	    CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
    +	    0, "Received packet FTQ discards");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_IfInMBUFDiscards",
    -		CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
    -		0, "Received packets discarded due to lack of controller buffer memory");
    +	    "stat_IfInMBUFDiscards",
    +	    CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
    +	    0, "Received packets discarded due to lack "
    +	    "of controller buffer memory");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_IfInRuleCheckerP4Hit",
    -		CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
    -		0, "Received packets rule checker hits");
    +	    "stat_IfInRuleCheckerP4Hit",
    +	    CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
    +	    0, "Received packets rule checker hits");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_CatchupInRuleCheckerDiscards",
    -		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
    -		0, "Received packets discarded in Catchup path");
    +	    "stat_CatchupInRuleCheckerDiscards",
    +	    CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
    +	    0, "Received packets discarded in Catchup path");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_CatchupInFTQDiscards",
    -		CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
    -		0, "Received packets discarded in FTQ in Catchup path");
    +	    "stat_CatchupInFTQDiscards",
    +	    CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
    +	    0, "Received packets discarded in FTQ in Catchup path");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_CatchupInMBUFDiscards",
    -		CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
    -		0, "Received packets discarded in controller buffer memory in Catchup path");
    +	    "stat_CatchupInMBUFDiscards",
    +	    CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
    +	    0, "Received packets discarded in controller "
    +	    "buffer memory in Catchup path");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"stat_CatchupInRuleCheckerP4Hit",
    -		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
    -		0, "Received packets rule checker hits in Catchup path");
    +	    "stat_CatchupInRuleCheckerP4Hit",
    +	    CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
    +	    0, "Received packets rule checker hits in Catchup path");
     
     	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
    -		"com_no_buffers",
    -		CTLFLAG_RD, &sc->com_no_buffers,
    -		0, "Valid packets received but no RX buffers available");
    +	    "com_no_buffers",
    +	    CTLFLAG_RD, &sc->com_no_buffers,
    +	    0, "Valid packets received but no RX buffers available");
     
     #ifdef BCE_DEBUG
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"driver_state", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_driver_state, "I", "Drive state information");
    +	    "driver_state", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_driver_state, "I", "Drive state information");
     
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"hw_state", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_hw_state, "I", "Hardware state information");
    +	    "hw_state", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_hw_state, "I", "Hardware state information");
     
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"bc_state", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_bc_state, "I", "Bootcode state information");
    +	    "status_block", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_status_block, "I", "Status block");
     
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"dump_rx_chain", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_dump_rx_chain, "I", "Dump rx_bd chain");
    +	    "stats_block", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_stats_block, "I", "Stats block");
     
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
    +	    "bc_state", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_bc_state, "I", "Bootcode state information");
    +
    +	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    +	    "dump_rx_bd_chain", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_dump_rx_bd_chain, "I", "Dump RX BD chain");
    +
    +	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    +	    "dump_rx_mbuf_chain", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_dump_rx_mbuf_chain, "I", "Dump RX MBUF chain");
    +
    +	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    +	    "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
     
     #ifdef BCE_JUMBO_HDRSPLIT
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_dump_pg_chain, "I", "Dump page chain");
    +	    "dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_dump_pg_chain, "I", "Dump page chain");
     #endif
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_dump_ctx, "I", "Dump context memory");
    +	    "dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_dump_ctx, "I", "Dump context memory");
     
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"breakpoint", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_breakpoint, "I", "Driver breakpoint");
    +	    "breakpoint", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_breakpoint, "I", "Driver breakpoint");
     
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"reg_read", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_reg_read, "I", "Register read");
    +	    "reg_read", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_reg_read, "I", "Register read");
     
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"nvram_read", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_nvram_read, "I", "NVRAM read");
    +	    "nvram_read", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_nvram_read, "I", "NVRAM read");
     
     	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
    -		"phy_read", CTLTYPE_INT | CTLFLAG_RW,
    -		(void *)sc, 0,
    -		bce_sysctl_phy_read, "I", "PHY register read");
    +	    "phy_read", CTLTYPE_INT | CTLFLAG_RW,
    +	    (void *)sc, 0,
    +	    bce_sysctl_phy_read, "I", "PHY register read");
     
     #endif
     
    @@ -8741,10 +8851,10 @@ bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
     	struct udphdr *uh;
     	struct arphdr *ah;
     
    -		BCE_PRINTF(
    -			"-----------------------------"
    -			" Frame Decode "
    -			"-----------------------------\n");
    +	BCE_PRINTF(
    +	    "-----------------------------"
    +	    " Frame Decode "
    +	    "-----------------------------\n");
     
     	eh = mtod(m, struct ether_vlan_header *);
     
    @@ -8759,63 +8869,65 @@ bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
     
     	/* ToDo: Add VLAN output. */
     	BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
    -		eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
    +	    eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
     
     	switch (etype) {
    -		case ETHERTYPE_IP:
    -			ip = (struct ip *)(m->m_data + ehlen);
    -			BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, len = %d bytes, "
    -				"protocol = 0x%02X, xsum = 0x%04X\n",
    -				ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
    -				ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
    +	case ETHERTYPE_IP:
    +		ip = (struct ip *)(m->m_data + ehlen);
    +		BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, "
    +		    "len = %d bytes, protocol = 0x%02X, xsum = 0x%04X\n",
    +		    ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
    +		    ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
     
    -			switch (ip->ip_p) {
    -				case IPPROTO_TCP:
    -					th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
    -					BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = %d bytes, "
    -						"flags = 0x%b, csum = 0x%04X\n",
    -						ntohs(th->th_dport), ntohs(th->th_sport), (th->th_off << 2),
    -						th->th_flags, "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST\02SYN\01FIN",
    -						ntohs(th->th_sum));
    -					break;
    -				case IPPROTO_UDP:
    -        		    uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
    -					BCE_PRINTF("-udp: dest = %d, src = %d, len = %d bytes, "
    -						"csum = 0x%04X\n", ntohs(uh->uh_dport), ntohs(uh->uh_sport),
    -						ntohs(uh->uh_ulen), ntohs(uh->uh_sum));
    -					break;
    -				case IPPROTO_ICMP:
    -					BCE_PRINTF("icmp:\n");
    -					break;
    -				default:
    -					BCE_PRINTF("----: Other IP protocol.\n");
    -			}
    +		switch (ip->ip_p) {
    +		case IPPROTO_TCP:
    +			th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
    +			BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = %d bytes, "
    +			    "flags = 0x%b, csum = 0x%04X\n",
    +			    ntohs(th->th_dport), ntohs(th->th_sport), 
    +			    (th->th_off << 2), th->th_flags, 
    +			    "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST"
    +			    "\02SYN\01FIN", ntohs(th->th_sum));
     			break;
    -		case ETHERTYPE_IPV6:
    -			BCE_PRINTF("ipv6: No decode supported.\n");
    +		case IPPROTO_UDP:
    +			uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
    +			BCE_PRINTF("-udp: dest = %d, src = %d, len = %d "
    +			    "bytes, csum = 0x%04X\n", ntohs(uh->uh_dport), 
    +			    ntohs(uh->uh_sport), ntohs(uh->uh_ulen), 
    +			    ntohs(uh->uh_sum));
     			break;
    -		case ETHERTYPE_ARP:
    -			BCE_PRINTF("-arp: ");
    -			ah = (struct arphdr *) (m->m_data + ehlen);
    -			switch (ntohs(ah->ar_op)) {
    -				case ARPOP_REVREQUEST:
    -					printf("reverse ARP request\n");
    -					break;
    -				case ARPOP_REVREPLY:
    -					printf("reverse ARP reply\n");
    -					break;
    -				case ARPOP_REQUEST:
    -					printf("ARP request\n");
    -					break;
    -				case ARPOP_REPLY:
    -					printf("ARP reply\n");
    -					break;
    -				default:
    -					printf("other ARP operation\n");
    -			}
    +		case IPPROTO_ICMP:
    +			BCE_PRINTF("icmp:\n");
     			break;
     		default:
    -			BCE_PRINTF("----: Other protocol.\n");
    +			BCE_PRINTF("----: Other IP protocol.\n");
    +			}
    +		break;
    +	case ETHERTYPE_IPV6:
    +		BCE_PRINTF("ipv6: No decode supported.\n");
    +		break;
    +	case ETHERTYPE_ARP:
    +		BCE_PRINTF("-arp: ");
    +		ah = (struct arphdr *) (m->m_data + ehlen);
    +		switch (ntohs(ah->ar_op)) {
    +		case ARPOP_REVREQUEST:
    +			printf("reverse ARP request\n");
    +			break;
    +		case ARPOP_REVREPLY:
    +			printf("reverse ARP reply\n");
    +			break;
    +		case ARPOP_REQUEST:
    +			printf("ARP request\n");
    +			break;
    +		case ARPOP_REPLY:
    +			printf("ARP reply\n");
    +			break;
    +		default:
    +			printf("other ARP operation\n");
    +		}
    +		break;
    +	default:
    +		BCE_PRINTF("----: Other protocol.\n");
     	}
     
     	BCE_PRINTF(
    @@ -8842,37 +8954,49 @@ bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
     	}
     
     	while (mp) {
    -		BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, m_data = %p\n",
    -			mp, mp->m_len, mp->m_flags,
    -			"\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY",
    -			mp->m_data);
    +		BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, "
    +		    "m_data = %p\n", mp, mp->m_len, mp->m_flags,
    +		    "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY", mp->m_data);
     
     		if (mp->m_flags & M_PKTHDR) {
    -			BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, csum_flags = %b\n",
    -				mp->m_pkthdr.len, mp->m_flags,
    -				"\20\12M_BCAST\13M_MCAST\14M_FRAG\15M_FIRSTFRAG"
    -				"\16M_LASTFRAG\21M_VLANTAG\22M_PROMISC\23M_NOFREE",
    -				mp->m_pkthdr.csum_flags,
    -				"\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP\4CSUM_IP_FRAGS"
    -				"\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
    -				"\12CSUM_IP_VALID\13CSUM_DATA_VALID\14CSUM_PSEUDO_HDR");
    +			BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, "
    +			    "csum_flags = %b\n", mp->m_pkthdr.len, 
    +			    mp->m_flags, "\20\12M_BCAST\13M_MCAST\14M_FRAG"
    +			    "\15M_FIRSTFRAG\16M_LASTFRAG\21M_VLANTAG"
    +			    "\22M_PROMISC\23M_NOFREE", 
    +			    mp->m_pkthdr.csum_flags,
    +			    "\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP\4CSUM_IP_FRAGS"
    +			    "\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
    +			    "\12CSUM_IP_VALID\13CSUM_DATA_VALID"
    +			    "\14CSUM_PSEUDO_HDR");
     		}
     
     		if (mp->m_flags & M_EXT) {
     			BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
    -				mp->m_ext.ext_buf, mp->m_ext.ext_size);
    +			    mp->m_ext.ext_buf, mp->m_ext.ext_size);
     			switch (mp->m_ext.ext_type) {
    -				case EXT_CLUSTER:    printf("EXT_CLUSTER\n"); break;
    -				case EXT_SFBUF:      printf("EXT_SFBUF\n"); break;
    -				case EXT_JUMBO9:     printf("EXT_JUMBO9\n"); break;
    -				case EXT_JUMBO16:    printf("EXT_JUMBO16\n"); break;
    -				case EXT_PACKET:     printf("EXT_PACKET\n"); break;
    -				case EXT_MBUF:       printf("EXT_MBUF\n"); break;
    -				case EXT_NET_DRV:    printf("EXT_NET_DRV\n"); break;
    -				case EXT_MOD_TYPE:   printf("EXT_MDD_TYPE\n"); break;
    -				case EXT_DISPOSABLE: printf("EXT_DISPOSABLE\n"); break;
    -				case EXT_EXTREF:     printf("EXT_EXTREF\n"); break;
    -				default:             printf("UNKNOWN\n");
    +			case EXT_CLUSTER:
    +				printf("EXT_CLUSTER\n"); break;
    +			case EXT_SFBUF:
    +				printf("EXT_SFBUF\n"); break;
    +			case EXT_JUMBO9:
    +				printf("EXT_JUMBO9\n"); break;
    +			case EXT_JUMBO16:
    +				printf("EXT_JUMBO16\n"); break;
    +			case EXT_PACKET:
    +				printf("EXT_PACKET\n"); break;
    +			case EXT_MBUF:
    +				printf("EXT_MBUF\n"); break;
    +			case EXT_NET_DRV:
    +				printf("EXT_NET_DRV\n"); break;
    +			case EXT_MOD_TYPE:
    +				printf("EXT_MDD_TYPE\n"); break;
    +			case EXT_DISPOSABLE:
    +				printf("EXT_DISPOSABLE\n"); break;
    +			case EXT_EXTREF:
    +				printf("EXT_EXTREF\n"); break;
    +			default:             
    +				printf("UNKNOWN\n");
     			}
     		}
     
    @@ -8984,75 +9108,109 @@ bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
     static __attribute__ ((noinline)) void
     bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
     {
    -    int i = 0;
    +	int i = 0;
     
    -    if (idx > MAX_TX_BD)
    +	if (idx > MAX_TX_BD)
     		/* Index out of range. */
     		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
     	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
     		/* TX Chain page pointer. */
    -		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
    -			idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
    +		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
    +		    "pointer\n", idx, txbd->tx_bd_haddr_hi, 
    +		    txbd->tx_bd_haddr_lo);
     	else {
     		/* Normal tx_bd entry. */
    -		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, mss_nbytes = 0x%08X, "
    -			"vlan tag = 0x%04X, flags = 0x%04X (", idx,
    -			txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
    -			txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
    -			txbd->tx_bd_flags);
    +		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
    +		    "mss_nbytes = 0x%08X, vlan tag = 0x%04X, flags = "
    +		    "0x%04X (", idx, txbd->tx_bd_haddr_hi, 
    +		    txbd->tx_bd_haddr_lo, txbd->tx_bd_mss_nbytes, 
    +		    txbd->tx_bd_vlan_tag, txbd->tx_bd_flags);
     
     		if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
    -			if (i>0) printf("|"); printf("CONN_FAULT"); i++;
    -        }
    +			if (i>0) 
    +				printf("|"); 
    +			printf("CONN_FAULT"); 
    +			i++;
    +		}
     
     		if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
    -            if (i>0) printf("|"); printf("TCP_UDP_CKSUM"); i++;
    -        }
    +			if (i>0) 
    +				printf("|"); 
    +			printf("TCP_UDP_CKSUM"); 
    +			i++;
    +		}
     
    -        if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
    -            if (i>0) printf("|"); printf("IP_CKSUM"); i++;
    -        }
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
    +			if (i>0) 
    +				printf("|"); 
    +			printf("IP_CKSUM"); 
    +			i++;
    +		}
     
     		if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
    -            if (i>0) printf("|"); printf("VLAN"); i++;
    -        }
    +			if (i>0) 
    +				printf("|"); 
    +			printf("VLAN"); 
    +			i++;
    +		}
     
     		if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
    -            if (i>0) printf("|"); printf("COAL_NOW"); i++;
    -        }
    +			if (i>0) 
    +				printf("|"); 
    +			printf("COAL_NOW"); 
    +			i++;
    +		}
     
    -        if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
    -            if (i>0) printf("|"); printf("DONT_GEN_CRC"); i++;
    -        }
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
    +			if (i>0) 
    +				printf("|"); 
    +			printf("DONT_GEN_CRC"); 
    +			i++;
    +		}
     
    -        if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
    -            if (i>0) printf("|"); printf("START"); i++;
    -        }
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
    +			if (i>0) 
    +				printf("|"); 
    +			printf("START"); 
    +			i++;
    +		}
     
     		if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
    -            if (i>0) printf("|"); printf("END"); i++;
    -        }
    +			if (i>0) 
    +				printf("|"); 
    +			printf("END"); 
    +			i++;
    +		}
     
     		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
    -            if (i>0) printf("|"); printf("LSO"); i++;
    -        }
    +			if (i>0) 
    +				printf("|"); 
    +			printf("LSO"); 
    +			i++;
    +		}
     
    -        if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
    -            if (i>0) printf("|"); 
    -            printf("SW_OPTION=%d", ((txbd->tx_bd_flags & 
    -                TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
    -        }
    +		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
    +			if (i>0) 
    +				printf("|"); 
    +			printf("SW_OPTION=%d", ((txbd->tx_bd_flags & 
    +			    TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
    +		}
     
     		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
    -            if (i>0) printf("|"); printf("SW_FLAGS"); i++;
    -        }
    +			if (i>0) 
    +				printf("|"); 
    +			printf("SW_FLAGS"); 
    +			i++;
    +		}
     
     		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
    -            if (i>0) printf("|"); printf("SNAP)");
    -        } else {
    -            printf(")\n");
    -        }
    -    }
    +			if (i>0) 
    +				printf("|"); 
    +			printf("SNAP)");
    +		} else {
    +			printf(")\n");
    +		}
    +	}
     }
     
     
    @@ -9070,14 +9228,15 @@ bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
     		BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
     	else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
     		/* RX Chain page pointer. */
    -		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
    -			idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo);
    +		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
    +		    "pointer\n", idx, rxbd->rx_bd_haddr_hi, 
    +		    rxbd->rx_bd_haddr_lo);
     	else
     		/* Normal rx_bd entry. */
    -		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
    -			"flags = 0x%08X\n", idx,
    -			rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
    -			rxbd->rx_bd_len, rxbd->rx_bd_flags);
    +		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
    +		    "0x%08X, flags = 0x%08X\n", idx, rxbd->rx_bd_haddr_hi, 
    +		    rxbd->rx_bd_haddr_lo, rxbd->rx_bd_len, 
    +		    rxbd->rx_bd_flags);
     }
     
     
    @@ -9135,104 +9294,117 @@ bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
     static __attribute__ ((noinline)) void
     bce_dump_ctx(struct bce_softc *sc, u16 cid)
     {
    -	if (cid <= TX_CID) {
    -		BCE_PRINTF(
    -			"----------------------------"
    -			"    CTX Data    "
    -			"----------------------------\n");
    -
    -		BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
    -
    -		if (cid == RX_CID) {
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
    -				"producer index\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host byte sequence\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BSEQ));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
    -				"descriptor address\n",
    - 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
    -				"descriptor address\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer index\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDIDX));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
    -				"producer index\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_PG_BDIDX));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
    -				"buffer size\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_PG_BUF_SIZE));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
    -				"chain address\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
    -				"chain address\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
    -			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
    -				"consumer index\n",
    -				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDIDX));
    -		} else if (cid == TX_CID) {
    -			if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    -				(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
    -					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE_XI));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx cmd\n",
    -					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE_XI));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) h/w buffer "
    -					"descriptor address\n",	CTX_RD(sc,
    -					GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) h/w buffer "
    -					"descriptor address\n", CTX_RD(sc,
    -					GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) host producer "
    -					"index\n", CTX_RD(sc, GET_CID_ADDR(cid),
    -					BCE_L2CTX_TX_HOST_BIDX_XI));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) host byte "
    -					"sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
    -					BCE_L2CTX_TX_HOST_BSEQ_XI));
    -			} else {
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
    -					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
    -					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) h/w buffer "
    -					"descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
    -					BCE_L2CTX_TX_TBDR_BHADDR_HI));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) h/w buffer "
    -					"descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
    -					BCE_L2CTX_TX_TBDR_BHADDR_LO));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host producer "
    -					"index\n", CTX_RD(sc, GET_CID_ADDR(cid),
    -					BCE_L2CTX_TX_HOST_BIDX));
    -				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
    -					"sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
    -					BCE_L2CTX_TX_HOST_BSEQ));
    -			}
    -		} else
    -			BCE_PRINTF(" Unknown CID\n");
    -
    -		BCE_PRINTF(
    -			"----------------------------"
    -			"    Raw CTX     "
    -			"----------------------------\n");
    -
    -		for (int i = 0x0; i < 0x300; i += 0x10) {
    -			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
    -				CTX_RD(sc, GET_CID_ADDR(cid), i),
    -				CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
    -				CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
    -				CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
    -		}
    -
    -
    -		BCE_PRINTF(
    -			"----------------------------"
    -			"----------------"
    -			"----------------------------\n");
    +	if (cid > TX_CID) {
    +		BCE_PRINTF(" Unknown CID\n");
    +		return;
     	}
    +
    +	BCE_PRINTF(
    +	    "----------------------------"
    +	    "    CTX Data    "
    +	    "----------------------------\n");
    +
    +	BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
    +
    +	if (cid == RX_CID) {
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
    +		   "producer index\n",
    +		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host "
    +		    "byte sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
    +		    BCE_L2CTX_RX_HOST_BSEQ));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
    +		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
    +		    "descriptor address\n",
    + 		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
    +		    "descriptor address\n",
    +		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer "
    +		    "index\n", CTX_RD(sc, GET_CID_ADDR(cid),
    +		    BCE_L2CTX_RX_NX_BDIDX));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
    +		    "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid), 
    +		    BCE_L2CTX_RX_HOST_PG_BDIDX));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
    +		    "buffer size\n", CTX_RD(sc, GET_CID_ADDR(cid), 
    +		    BCE_L2CTX_RX_PG_BUF_SIZE));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
    +		    "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid), 
    +		    BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
    +		    "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid), 
    +		    BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
    +		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
    +		    "consumer index\n",	CTX_RD(sc, GET_CID_ADDR(cid), 
    +		    BCE_L2CTX_RX_NX_PG_BDIDX));
    +	} else if (cid == TX_CID) {
    +		if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    +		    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
    +			    CTX_RD(sc, GET_CID_ADDR(cid), 
    +			    BCE_L2CTX_TX_TYPE_XI));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx "
    +			    "cmd\n", CTX_RD(sc, GET_CID_ADDR(cid), 
    +			    BCE_L2CTX_TX_CMD_TYPE_XI));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) "
    +			    "h/w buffer descriptor address\n",	
    +			    CTX_RD(sc, GET_CID_ADDR(cid), 
    +			    BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) "
    +			    "h/w buffer	descriptor address\n", 
    +			    CTX_RD(sc, GET_CID_ADDR(cid),
    +			    BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) "
    +			    "host producer index\n", 
    +			    CTX_RD(sc, GET_CID_ADDR(cid),
    +			    BCE_L2CTX_TX_HOST_BIDX_XI));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) "
    +			    "host byte sequence\n", 
    +			    CTX_RD(sc, GET_CID_ADDR(cid),
    +			    BCE_L2CTX_TX_HOST_BSEQ_XI));
    +		} else {
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
    +			    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
    +			    CTX_RD(sc, GET_CID_ADDR(cid), 
    +			    BCE_L2CTX_TX_CMD_TYPE));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) "
    +			    "h/w buffer	descriptor address\n", 
    +			    CTX_RD(sc, GET_CID_ADDR(cid),
    +			    BCE_L2CTX_TX_TBDR_BHADDR_HI));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) "
    +			    "h/w buffer	descriptor address\n", 
    +			    CTX_RD(sc, GET_CID_ADDR(cid),
    +			    BCE_L2CTX_TX_TBDR_BHADDR_LO));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host "
    +			    "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
    +			    BCE_L2CTX_TX_HOST_BIDX));
    +			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
    +			    "sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
    +			    BCE_L2CTX_TX_HOST_BSEQ));
    +		}
    +	}
    +
    +	BCE_PRINTF(
    +	   "----------------------------"
    +	   "    Raw CTX     "
    +	   "----------------------------\n");
    +
    +	for (int i = 0x0; i < 0x300; i += 0x10) {
    +		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
    +		   CTX_RD(sc, GET_CID_ADDR(cid), i),
    +		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
    +		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
    +		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
    +	}
    +
    +
    +	BCE_PRINTF(
    +	   "----------------------------"
    +	   "----------------"
    +	   "----------------------------\n");
     }
     
     
    @@ -9248,36 +9420,38 @@ bce_dump_ftqs(struct bce_softc *sc)
     	u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"    FTQ Data    "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "    FTQ Data    "
    +	    "----------------------------\n");
     
    -	BCE_PRINTF("   FTQ    Command    Control   Depth_Now  Max_Depth  Valid_Cnt \n");
    -	BCE_PRINTF(" ------- ---------- ---------- ---------- ---------- ----------\n");
    +	BCE_PRINTF("   FTQ    Command    Control   Depth_Now  "
    +	    "Max_Depth  Valid_Cnt \n");
    +	BCE_PRINTF(" ------- ---------- ---------- ---------- "
    +	    "---------- ----------\n");
     
     	/* Setup the generic statistic counters for the FTQ valid count. */
     	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
     	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
     
     	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT  << 24) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
     	REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
     
     	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT  << 24) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
     	REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
     
     	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT   << 24) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
     	REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
     
     	/* Input queue to the Receive Lookup state machine */
    @@ -9287,7 +9461,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
     	BCE_PRINTF(" RLUP    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Receive Processor */
     	cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
    @@ -9296,7 +9470,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
     	BCE_PRINTF(" RXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Recevie Processor */
     	cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
    @@ -9305,7 +9479,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
     	BCE_PRINTF(" RXPC    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Receive Virtual to Physical state machine */
     	cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
    @@ -9314,7 +9488,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
     	BCE_PRINTF(" RV2PP   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Recevie Virtual to Physical state machine */
     	cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
    @@ -9323,7 +9497,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
     	BCE_PRINTF(" RV2PM   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Receive Virtual to Physical state machine */
     	cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
    @@ -9332,7 +9506,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
     	BCE_PRINTF(" RV2PT   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Receive DMA state machine */
     	cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
    @@ -9341,7 +9515,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
     	BCE_PRINTF(" RDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Transmit Scheduler state machine */
     	cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
    @@ -9350,7 +9524,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
     	BCE_PRINTF(" TSCH    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Transmit Buffer Descriptor state machine */
     	cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
    @@ -9359,7 +9533,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
     	BCE_PRINTF(" TBDR    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Transmit Processor */
     	cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
    @@ -9368,7 +9542,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
     	BCE_PRINTF(" TXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Transmit DMA state machine */
     	cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
    @@ -9377,7 +9551,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
     	BCE_PRINTF(" TDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Transmit Patch-Up Processor */
     	cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
    @@ -9386,7 +9560,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
     	BCE_PRINTF(" TPAT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Transmit Assembler state machine */
     	cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
    @@ -9395,7 +9569,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
     	BCE_PRINTF(" TAS     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Completion Processor */
     	cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
    @@ -9404,7 +9578,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
     	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Completion Processor */
     	cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
    @@ -9413,7 +9587,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
     	BCE_PRINTF(" COMT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Completion Processor */
     	cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
    @@ -9422,17 +9596,19 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
     	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Setup the generic statistic counters for the FTQ valid count. */
     	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  << 16) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
    -		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
    +	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
     
    -	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
    -		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
    -		val = val | (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI << 24);
    -		REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
    +	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    +	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
    +		val = val | 
    +		    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI << 
    +		     24);
    +	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
     
     	/* Input queue to the Management Control Processor */
     	cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
    @@ -9441,7 +9617,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
     	BCE_PRINTF(" MCP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Command Processor */
     	cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
    @@ -9450,7 +9626,7 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
     	BCE_PRINTF(" CP      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	/* Input queue to the Completion Scheduler state machine */
     	cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
    @@ -9459,24 +9635,24 @@ bce_dump_ftqs(struct bce_softc *sc)
     	max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
     	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
     	BCE_PRINTF(" CS      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -		cmd, ctl, cur_depth, max_depth, valid_cnt);
    +	    cmd, ctl, cur_depth, max_depth, valid_cnt);
     
     	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
    -		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
    -		/* Input queue to the Receive Virtual to Physical Command Scheduler */
    +	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
    +		/* Input queue to the RV2P Command Scheduler */
     		cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
     		ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
     		cur_depth = (ctl & 0xFFC00000) >> 22;
     		max_depth = (ctl & 0x003FF000) >> 12;
     		valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
     		BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -			cmd, ctl, cur_depth, max_depth, valid_cnt);
    +		    cmd, ctl, cur_depth, max_depth, valid_cnt);
     	}
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -9493,20 +9669,20 @@ bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
     
     	/* First some info about the tx_bd chain structure. */
     	BCE_PRINTF(
    -		"----------------------------"
    -		"  tx_bd  chain  "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "  tx_bd  chain  "
    +	    "----------------------------\n");
     
     	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
    -		(u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
    +	    (u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
     	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
    -		(u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
    +	    (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
     	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"   tx_bd data   "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "   tx_bd data   "
    +	    "----------------------------\n");
     
     	/* Now print out a decoded list of TX buffer descriptors. */
     	for (int i = 0; i < count; i++) {
    @@ -9516,9 +9692,9 @@ bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
     	}
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -9529,28 +9705,28 @@ bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
     /*   Nothing.                                                               */
     /****************************************************************************/
     static __attribute__ ((noinline)) void
    -bce_dump_rx_chain(struct bce_softc *sc, u16 rx_prod, int count)
    +bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count)
     {
     	struct rx_bd *rxbd;
     
     	/* First some info about the rx_bd chain structure. */
     	BCE_PRINTF(
    -		"----------------------------"
    -		"  rx_bd  chain  "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "  rx_bd  chain  "
    +	    "----------------------------\n");
     
     	BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
    -		(u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
    +	    (u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
     
     	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
    -		(u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
    +	    (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
     
     	BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD);
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"   rx_bd data   "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "   rx_bd data   "
    +	    "----------------------------\n");
     
     	/* Now print out the rx_bd's themselves. */
     	for (int i = 0; i < count; i++) {
    @@ -9560,9 +9736,9 @@ bce_dump_rx_chain(struct bce_softc *sc, u16 rx_prod, int count)
     	}
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -9580,23 +9756,23 @@ bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
     
     	/* First some info about the page chain structure. */
     	BCE_PRINTF(
    -		"----------------------------"
    -		"   page chain   "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "   page chain   "
    +	    "----------------------------\n");
     
     	BCE_PRINTF("page size      = 0x%08X, pg chain pages        = 0x%08X\n",
    -		(u32) BCM_PAGE_SIZE, (u32) PG_PAGES);
    +	    (u32) BCM_PAGE_SIZE, (u32) PG_PAGES);
     
     	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
    -		(u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
    +	    (u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
     
     	BCE_PRINTF("total rx_bd    = 0x%08X, max_pg_bd             = 0x%08X\n",
    -		(u32) TOTAL_PG_BD, (u32) MAX_PG_BD);
    +	    (u32) TOTAL_PG_BD, (u32) MAX_PG_BD);
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"   page data    "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "   page data    "
    +	    "----------------------------\n");
     
     	/* Now print out the rx_bd's themselves. */
     	for (int i = 0; i < count; i++) {
    @@ -9606,23 +9782,27 @@ bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
     	}
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     #endif
     
    -#define BCE_PRINT_RX_CONS(arg)                                          \
    -if (sblk->status_rx_quick_consumer_index##arg)                          \
    -    BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index##arg\n",       \
    -		sblk->status_rx_quick_consumer_index##arg,                      \
    -		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg));
     
    -#define BCE_PRINT_TX_CONS(arg)                                          \
    -if (sblk->status_tx_quick_consumer_index##arg)                          \
    -    BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index##arg\n",       \
    -        sblk->status_tx_quick_consumer_index##arg,                      \
    -        (u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg));
    +#define BCE_PRINT_RX_CONS(arg)						\
    +if (sblk->status_rx_quick_consumer_index##arg)				\
    +	BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index%d\n",	\
    +	    sblk->status_rx_quick_consumer_index##arg, (u16)		\
    +	    RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg),	\
    +	    arg);
    +
    +
    +#define BCE_PRINT_TX_CONS(arg)						\
    +if (sblk->status_tx_quick_consumer_index##arg)				\
    +	BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index%d\n",	\
    +	    sblk->status_tx_quick_consumer_index##arg, (u16)		\
    +	    TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg),	\
    +	    arg);
     
     /****************************************************************************/
     /* Prints out the status block from host memory.                            */
    @@ -9637,52 +9817,54 @@ bce_dump_status_block(struct bce_softc *sc)
     
     	sblk = sc->status_block;
     
    -   	BCE_PRINTF(
    -		"----------------------------"
    -		"  Status Block  "
    -		"----------------------------\n");
    +	BCE_PRINTF(
    +	    "----------------------------"
    +	    "  Status Block  "
    +	    "----------------------------\n");
     
    -    /* Theses indices are used for normal L2 drivers. */
    +	/* Theses indices are used for normal L2 drivers. */
     	BCE_PRINTF("    0x%08X - attn_bits\n",
    -		sblk->status_attn_bits);
    +	    sblk->status_attn_bits);
     
     	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
    -		sblk->status_attn_bits_ack);
    +	    sblk->status_attn_bits_ack);
     
    -    BCE_PRINT_RX_CONS(0);
    -    BCE_PRINT_TX_CONS(0)
    +	BCE_PRINT_RX_CONS(0);
    +	BCE_PRINT_TX_CONS(0)
     
     	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
     
     	/* Theses indices are not used for normal L2 drivers. */
    -    BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
    -    BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
    -    BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
    -    BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
    -    BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
    +	BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
    +	BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
    +	BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
    +	BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
    +	BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
     
    -    BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
    +	BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
     
    -    if (sblk->status_completion_producer_index ||
    -		sblk->status_cmd_consumer_index)
    +	if (sblk->status_completion_producer_index ||
    +	    sblk->status_cmd_consumer_index)
     		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
    -			sblk->status_completion_producer_index,
    -			sblk->status_cmd_consumer_index);
    +		    sblk->status_completion_producer_index,
    +		    sblk->status_cmd_consumer_index);
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    -#define BCE_PRINT_64BIT_STAT(arg)                                       \
    -if (sblk->arg##_lo || sblk->arg##_hi)                               \
    -	BCE_PRINTF("0x%08X:%08X : arg\n", sblk->arg##_hi, sblk->arg##_lo);
    +#define BCE_PRINT_64BIT_STAT(arg) 				\
    +if (sblk->arg##_lo || sblk->arg##_hi)				\
    +	BCE_PRINTF("0x%08X:%08X : %s\n", sblk->arg##_hi,	\
    +	    sblk->arg##_lo, #arg);
     
    -#define BCE_PRINT_32BIT_STAT(arg)                                       \
    -if (sblk->arg)                                                        \
    -	BCE_PRINTF("         0x%08X : arg\n", sblk->arg);
    +#define BCE_PRINT_32BIT_STAT(arg)				\
    +if (sblk->arg)							\
    +	BCE_PRINTF("         0x%08X : %s\n", 			\
    +	    sblk->arg, #arg);
     
     /****************************************************************************/
     /* Prints out the statistics block from host memory.                        */
    @@ -9698,69 +9880,70 @@ bce_dump_stats_block(struct bce_softc *sc)
     	sblk = sc->stats_block;
     
     	BCE_PRINTF(
    -		"---------------"
    -		" Stats Block  (All Stats Not Shown Are 0) "
    -		"---------------\n");
    +	    "---------------"
    +	    " Stats Block  (All Stats Not Shown Are 0) "
    +	    "---------------\n");
     
    -    BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
    -    BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
    -    BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
    -    BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
    -    BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
    -    BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
    -    BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
    -    BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
    -    BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
    -    BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
    -    BCE_PRINT_32BIT_STAT(stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
    -    BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
    -    BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
    -    BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
    -    BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
    -    BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
    -    BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
    -    BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
    -    BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
    -    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
    -    BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
    -    BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
    -    BCE_PRINT_32BIT_STAT(stat_OutXonSent);
    -    BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
    -    BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
    -    BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
    -    BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
    -    BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
    -    BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
    -    BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
    -    BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
    -    BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
    -    BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
    -    BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
    -    BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
    -    BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
    +	BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
    +	BCE_PRINT_32BIT_STAT(
    +	    stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
    +	BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
    +	BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
    +	BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
    +	BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
    +	BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
    +	BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
    +	BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
    +	BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
    +	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
    +	BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
    +	BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
    +	BCE_PRINT_32BIT_STAT(stat_OutXonSent);
    +	BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
    +	BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
    +	BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
    +	BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
    +	BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
    +	BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
    +	BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
    +	BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
    +	BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
    +	BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
    +	BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
    +	BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
    +	BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -9776,146 +9959,142 @@ bce_dump_driver_state(struct bce_softc *sc)
     	u32 val_hi, val_lo;
     
     	BCE_PRINTF(
    -		"-----------------------------"
    -		" Driver State "
    -		"-----------------------------\n");
    +	    "-----------------------------"
    +	    " Driver State "
    +	    "-----------------------------\n");
     
     	val_hi = BCE_ADDR_HI(sc);
     	val_lo = BCE_ADDR_LO(sc);
    -	BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual address\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual "
    +	    "address\n", val_hi, val_lo);
     
     	val_hi = BCE_ADDR_HI(sc->bce_vhandle);
     	val_lo = BCE_ADDR_LO(sc->bce_vhandle);
    -	BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual address\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual "
    +	    "address\n", val_hi, val_lo);
     
     	val_hi = BCE_ADDR_HI(sc->status_block);
     	val_lo = BCE_ADDR_LO(sc->status_block);
    -	BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block virtual address\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block "
    +	    "virtual address\n",	val_hi, val_lo);
     
     	val_hi = BCE_ADDR_HI(sc->stats_block);
     	val_lo = BCE_ADDR_LO(sc->stats_block);
    -	BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block virtual address\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block "
    +	    "virtual address\n", val_hi, val_lo);
     
     	val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
     	val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
    -	BCE_PRINTF(
    -		"0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain virtual adddress\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain "
    +	    "virtual adddress\n", val_hi, val_lo);
     
     	val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
     	val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
    -	BCE_PRINTF(
    -		"0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain virtual address\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain "
    +	    "virtual address\n", val_hi, val_lo);
     
     #ifdef BCE_JUMBO_HDRSPLIT
     	val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
     	val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
    -	BCE_PRINTF(
    -		"0x%08X:%08X - (sc->pg_bd_chain) page chain virtual address\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain "
    +	    "virtual address\n", val_hi, val_lo);
     #endif
     
     	val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
     	val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
    -	BCE_PRINTF(
    -		"0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain "
    +	    "virtual address\n",	val_hi, val_lo);
     
     	val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
     	val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
    -	BCE_PRINTF(
    -		"0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain "
    +	    "virtual address\n", val_hi, val_lo);
     
     #ifdef BCE_JUMBO_HDRSPLIT
     	val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
     	val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
    -	BCE_PRINTF(
    -		"0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain virtual address\n",
    -		val_hi, val_lo);
    +	BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain "
    +	    "virtual address\n", val_hi, val_lo);
     #endif
     
    -	BCE_PRINTF("         0x%08X - (sc->interrupts_generated) h/w intrs\n",
    -		sc->interrupts_generated);
    +	BCE_PRINTF("         0x%08X - (sc->interrupts_generated) "
    +	    "h/w intrs\n", sc->interrupts_generated);
     
    -	BCE_PRINTF("         0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
    -		sc->rx_interrupts);
    +	BCE_PRINTF("         0x%08X - (sc->rx_interrupts) "
    +	    "rx interrupts handled\n", sc->rx_interrupts);
     
    -	BCE_PRINTF("         0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
    -		sc->tx_interrupts);
    +	BCE_PRINTF("         0x%08X - (sc->tx_interrupts) "
    +	    "tx interrupts handled\n", sc->tx_interrupts);
     
    -	BCE_PRINTF("         0x%08X - (sc->last_status_idx) status block index\n",
    -		sc->last_status_idx);
    +	BCE_PRINTF("         0x%08X - (sc->phy_interrupts) "
    +	    "phy interrupts handled\n", sc->phy_interrupts);
     
    -	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer index\n",
    -		sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
    +	BCE_PRINTF("         0x%08X - (sc->last_status_idx) "
    +	    "status block index\n", sc->last_status_idx);
     
    -	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer index\n",
    -		sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
    +	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer "
    +	    "index\n", sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
     
    -	BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
    -		sc->tx_prod_bseq);
    +	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer "
    +	    "index\n", sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
     
    -	BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx mbufs allocated\n",
    -		sc->debug_tx_mbuf_alloc);
    +	BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer "
    +	    "byte seq index\n",	sc->tx_prod_bseq);
     
    -	BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used tx_bd's\n",
    -		sc->used_tx_bd);
    +	BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx "
    +	    "mbufs allocated\n", sc->debug_tx_mbuf_alloc);
     
    -	BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
    -		sc->tx_hi_watermark, sc->max_tx_bd);
    +	BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used "
    +	    "tx_bd's\n", sc->used_tx_bd);
     
    -	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer index\n",
    -		sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
    +	BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi "
    +	    "watermark\n", sc->tx_hi_watermark, sc->max_tx_bd);
     
    -	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer index\n",
    -		sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
    +	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer "
    +	    "index\n", sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
     
    -	BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
    -		sc->rx_prod_bseq);
    +	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer "
    +	    "index\n", sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
     
    -	BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx mbufs allocated\n",
    -		sc->debug_rx_mbuf_alloc);
    +	BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer "
    +	    "byte seq index\n",	sc->rx_prod_bseq);
     
    -	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free rx_bd's\n",
    -		sc->free_rx_bd);
    +	BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx "
    +	    "mbufs allocated\n", sc->debug_rx_mbuf_alloc);
    +
    +	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free "
    +	    "rx_bd's\n", sc->free_rx_bd);
     
     #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));
    +	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer "
    +	    "index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
     
    -	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer index\n",
    -		sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
    +	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer "
    +	    "index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
     
    -	BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page mbufs allocated\n",
    -		sc->debug_pg_mbuf_alloc);
    +	BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page "
    +	    "mbufs allocated\n", sc->debug_pg_mbuf_alloc);
     
    -	BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page rx_bd's\n",
    -		sc->free_pg_bd);
    +	BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page "
    +	    "rx_bd's\n", sc->free_pg_bd);
     
    -	BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low watermark\n",
    -		sc->pg_low_watermark, sc->max_pg_bd);
    +	BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low "
    +	    "watermark\n", sc->pg_low_watermark, sc->max_pg_bd);
     #endif
     
     	BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed_count) "
    -		"mbuf alloc failures\n",
    -		sc->mbuf_alloc_failed_count);
    +	    "mbuf alloc failures\n", sc->mbuf_alloc_failed_count);
     
    -	BCE_PRINTF("         0x%08X - (sc->bce_flags) bce mac flags\n",
    -		sc->bce_flags);
    +	BCE_PRINTF("         0x%08X - (sc->bce_flags) "
    +	    "bce mac flags\n", sc->bce_flags);
     
    -	BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) bce phy flags\n",
    -		sc->bce_phy_flags);
    +	BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) "
    +	    "bce phy flags\n", sc->bce_phy_flags);
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -9932,84 +10111,102 @@ bce_dump_hw_state(struct bce_softc *sc)
     	u32 val;
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		" Hardware State "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    " Hardware State "
    +	    "----------------------------\n");
     
     	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
     
     	val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
     	BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
    -		val, BCE_MISC_ENABLE_STATUS_BITS);
    +	    val, BCE_MISC_ENABLE_STATUS_BITS);
     
     	val = REG_RD(sc, BCE_DMA_STATUS);
    -	BCE_PRINTF("0x%08X - (0x%06X) dma_status\n", val, BCE_DMA_STATUS);
    +	BCE_PRINTF("0x%08X - (0x%06X) dma_status\n", 
    +	    val, BCE_DMA_STATUS);
     
     	val = REG_RD(sc, BCE_CTX_STATUS);
    -	BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n", val, BCE_CTX_STATUS);
    +	BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n", 
    +	    val, BCE_CTX_STATUS);
     
     	val = REG_RD(sc, BCE_EMAC_STATUS);
    -	BCE_PRINTF("0x%08X - (0x%06X) emac_status\n", val, BCE_EMAC_STATUS);
    +	BCE_PRINTF("0x%08X - (0x%06X) emac_status\n", 
    +	    val, BCE_EMAC_STATUS);
     
     	val = REG_RD(sc, BCE_RPM_STATUS);
    -	BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n", val, BCE_RPM_STATUS);
    +	BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n",
    +	    val, BCE_RPM_STATUS);
     
    +	/* ToDo: Create a #define for this constant. */
     	val = REG_RD(sc, 0x2004);
    -	BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n", val, 0x2004);
    +	BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n", 
    +	    val, 0x2004);
     
     	val = REG_RD(sc, BCE_RV2P_STATUS);
    -	BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n", val, BCE_RV2P_STATUS);
    +	BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n", 
    +	    val, BCE_RV2P_STATUS);
     
    +	/* ToDo: Create a #define for this constant. */
     	val = REG_RD(sc, 0x2c04);
    -	BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n", val, 0x2c04);
    +	BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n", 
    +	    val, 0x2c04);
     
     	val = REG_RD(sc, BCE_TBDR_STATUS);
    -	BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n", val, BCE_TBDR_STATUS);
    +	BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n",
    +	    val, BCE_TBDR_STATUS);
     
     	val = REG_RD(sc, BCE_TDMA_STATUS);
    -	BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n", val, BCE_TDMA_STATUS);
    +	BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n", 
    +	    val, BCE_TDMA_STATUS);
     
     	val = REG_RD(sc, BCE_HC_STATUS);
    -	BCE_PRINTF("0x%08X - (0x%06X) hc_status\n", val, BCE_HC_STATUS);
    +	BCE_PRINTF("0x%08X - (0x%06X) hc_status\n",
    +	    val, BCE_HC_STATUS);
     
     	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", 
    +	    val, BCE_TXP_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", 
    +	    val, BCE_TPAT_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", 
    +	    val, BCE_RXP_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", 
    +	    val, BCE_COM_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n", val, BCE_MCP_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n", 
    +	    val, BCE_MCP_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", 
    +	    val, BCE_CP_CPU_STATE);
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		" Register  Dump "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    " Register  Dump "
    +	    "----------------------------\n");
     
     	for (int i = 0x400; i < 0x8000; i += 0x10) {
     		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -			i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
    -			REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
    +		    i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
    +		    REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
     	}
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -10023,25 +10220,25 @@ static __attribute__ ((noinline)) void
     bce_dump_mq_regs(struct bce_softc *sc)
     {
     	BCE_PRINTF(
    -		"----------------------------"
    -		"    MQ Regs     "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "    MQ Regs     "
    +	    "----------------------------\n");
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     
     	for (int i = 0x3c00; i < 0x4000; i += 0x10) {
     		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -			i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
    -			REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
    +		    i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
    +		    REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
     	}
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -10057,32 +10254,32 @@ bce_dump_bc_state(struct bce_softc *sc)
     	u32 val;
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		" Bootcode State "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    " Bootcode State "
    +	    "----------------------------\n");
     
     	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
     
     	val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
     	BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
    -		val, BCE_BC_RESET_TYPE);
    +	    val, BCE_BC_RESET_TYPE);
     
     	val = bce_shmem_rd(sc, BCE_BC_STATE);
     	BCE_PRINTF("0x%08X - (0x%06X) state\n",
    -		val, BCE_BC_STATE);
    +	    val, BCE_BC_STATE);
     
     	val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
     	BCE_PRINTF("0x%08X - (0x%06X) condition\n",
    -		val, BCE_BC_STATE_CONDITION);
    +	    val, BCE_BC_STATE_CONDITION);
     
     	val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
     	BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
    -		val, BCE_BC_STATE_DEBUG_CMD);
    +	    val, BCE_BC_STATE_DEBUG_CMD);
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -10099,44 +10296,49 @@ bce_dump_txp_state(struct bce_softc *sc, int regs)
     	u32 fw_version[3];
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"   TXP  State   "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "   TXP  State   "
    +	    "----------------------------\n");
     
     	for (int i = 0; i < 3; i++)
     		fw_version[i] = htonl(REG_RD_IND(sc,
    -			(BCE_TXP_SCRATCH + 0x10 + i * 4)));
    +		    (BCE_TXP_SCRATCH + 0x10 + i * 4)));
     	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
     
     	val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
    -	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n", val, BCE_TXP_CPU_MODE);
    +	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n", 
    +	    val, BCE_TXP_CPU_MODE);
     
     	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", 
    +	    val, BCE_TXP_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
    -	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n", val,
    -		BCE_TXP_CPU_EVENT_MASK);
    +	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n", 
    +	    val, BCE_TXP_CPU_EVENT_MASK);
     
     	if (regs) {
     		BCE_PRINTF(
    -			"----------------------------"
    -			" Register  Dump "
    -			"----------------------------\n");
    +		    "----------------------------"
    +		    " Register  Dump "
    +		    "----------------------------\n");
     
     		for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
     			/* Skip the big blank spaces */
     			if (i < 0x454000 && i > 0x5ffff)
    -				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
    -					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
    +				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
    +				    "0x%08X 0x%08X\n", i, 
    +				    REG_RD_IND(sc, i), 
    +				    REG_RD_IND(sc, i + 0x4),
    +				    REG_RD_IND(sc, i + 0x8),
    +				    REG_RD_IND(sc, i + 0xC));
     		}
     	}
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -10153,44 +10355,50 @@ bce_dump_rxp_state(struct bce_softc *sc, int regs)
     	u32 fw_version[3];
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"   RXP  State   "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "   RXP  State   "
    +	    "----------------------------\n");
     
     	for (int i = 0; i < 3; i++)
     		fw_version[i] = htonl(REG_RD_IND(sc,
    -			(BCE_RXP_SCRATCH + 0x10 + i * 4)));
    +		    (BCE_RXP_SCRATCH + 0x10 + i * 4)));
    +
     	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
     
     	val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
    -	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n", val, BCE_RXP_CPU_MODE);
    +	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n", 
    +	    val, BCE_RXP_CPU_MODE);
     
     	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", 
    +	    val, BCE_RXP_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
    -	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n", val,
    -		BCE_RXP_CPU_EVENT_MASK);
    +	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n", 
    +	    val, BCE_RXP_CPU_EVENT_MASK);
     
     	if (regs) {
     		BCE_PRINTF(
    -			"----------------------------"
    -			" Register  Dump "
    -			"----------------------------\n");
    +		    "----------------------------"
    +		    " Register  Dump "
    +		    "----------------------------\n");
     
     		for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
     			/* Skip the big blank sapces */
     			if (i < 0xc5400 && i > 0xdffff)
    -				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -	 				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
    -					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
    +				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
    +				    "0x%08X 0x%08X\n", i, 
    +				    REG_RD_IND(sc, i), 
    +				    REG_RD_IND(sc, i + 0x4),
    +				    REG_RD_IND(sc, i + 0x8), 
    +				    REG_RD_IND(sc, i + 0xC));
     		}
     	}
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -10207,37 +10415,43 @@ bce_dump_tpat_state(struct bce_softc *sc, int regs)
     	u32 fw_version[3];
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"   TPAT State   "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "   TPAT State   "
    +	    "----------------------------\n");
     
     	for (int i = 0; i < 3; i++)
     		fw_version[i] = htonl(REG_RD_IND(sc,
    -			(BCE_TPAT_SCRATCH + 0x410 + i * 4)));
    +		    (BCE_TPAT_SCRATCH + 0x410 + i * 4)));
    +
     	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
     
     	val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
    -	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n", val, BCE_TPAT_CPU_MODE);
    +	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n", 
    +	    val, BCE_TPAT_CPU_MODE);
     
     	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", 
    +	    val, BCE_TPAT_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
    -	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n", val,
    -		BCE_TPAT_CPU_EVENT_MASK);
    +	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n", 
    +	    val, BCE_TPAT_CPU_EVENT_MASK);
     
     	if (regs) {
     		BCE_PRINTF(
    -			"----------------------------"
    -			" Register  Dump "
    -			"----------------------------\n");
    +		    "----------------------------"
    +		    " Register  Dump "
    +		    "----------------------------\n");
     
     		for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
     			/* Skip the big blank spaces */
     			if (i < 0x854000 && i > 0x9ffff)
    -				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
    -					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
    +				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
    +				    "0x%08X 0x%08X\n", i,
    +				    REG_RD_IND(sc, i), 
    +				    REG_RD_IND(sc, i + 0x4),
    +				    REG_RD_IND(sc, i + 0x8), 
    +				    REG_RD_IND(sc, i + 0xC));
     		}
     	}
     
    @@ -10261,44 +10475,50 @@ bce_dump_cp_state(struct bce_softc *sc, int regs)
     	u32 fw_version[3];
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"    CP State    "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "    CP State    "
    +	    "----------------------------\n");
     
     	for (int i = 0; i < 3; i++)
     		fw_version[i] = htonl(REG_RD_IND(sc,
    -			(BCE_CP_SCRATCH + 0x10 + i * 4)));
    +		    (BCE_CP_SCRATCH + 0x10 + i * 4)));
    +
     	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
     
     	val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
    -	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n", val, BCE_CP_CPU_MODE);
    +	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n", 
    +	    val, BCE_CP_CPU_MODE);
     
     	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", 
    +	    val, BCE_CP_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
     	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
    -		BCE_CP_CPU_EVENT_MASK);
    +	    BCE_CP_CPU_EVENT_MASK);
     
     	if (regs) {
     		BCE_PRINTF(
    -			"----------------------------"
    -			" Register  Dump "
    -			"----------------------------\n");
    +		    "----------------------------"
    +		    " Register  Dump "
    +		    "----------------------------\n");
     
     		for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
     			/* Skip the big blank spaces */
     			if (i < 0x185400 && i > 0x19ffff)
    -				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
    -					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
    +				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
    +				    "0x%08X 0x%08X\n", i, 
    +				    REG_RD_IND(sc, i), 
    +				    REG_RD_IND(sc, i + 0x4),
    +				    REG_RD_IND(sc, i + 0x8), 
    +				    REG_RD_IND(sc, i + 0xC));
     		}
     	}
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -10315,35 +10535,41 @@ bce_dump_com_state(struct bce_softc *sc, int regs)
     	u32 fw_version[4];
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"   COM State    "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "   COM State    "
    +	    "----------------------------\n");
     
     	for (int i = 0; i < 3; i++)
     		fw_version[i] = htonl(REG_RD_IND(sc,
    -			(BCE_COM_SCRATCH + 0x10 + i * 4)));
    +		    (BCE_COM_SCRATCH + 0x10 + i * 4)));
    +
     	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
     
     	val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
    -	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n", val, BCE_COM_CPU_MODE);
    +	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n", 
    +	    val, BCE_COM_CPU_MODE);
     
     	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
    -	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
    +	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", 
    +	    val, BCE_COM_CPU_STATE);
     
     	val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
     	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
    -		BCE_COM_CPU_EVENT_MASK);
    +	    BCE_COM_CPU_EVENT_MASK);
     
     	if (regs) {
     		BCE_PRINTF(
    -			"----------------------------"
    -			" Register  Dump "
    -			"----------------------------\n");
    +		    "----------------------------"
    +		    " Register  Dump "
    +		    "----------------------------\n");
     
     		for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
    -			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
    -				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
    -				REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
    +			BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
    +			    "0x%08X 0x%08X\n", i, 
    +			    REG_RD_IND(sc, i), 
    +			    REG_RD_IND(sc, i + 0x4),
    +			    REG_RD_IND(sc, i + 0x8),
    +			    REG_RD_IND(sc, i + 0xC));
     		}
     	}
     
    @@ -10366,55 +10592,59 @@ bce_dump_rv2p_state(struct bce_softc *sc)
     	u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"   RV2P State   "
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "   RV2P State   "
    +	    "----------------------------\n");
     
    -    /* Stall the RV2P processors. */
    -    val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
    -    val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
    -    REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
    +	/* Stall the RV2P processors. */
    +	val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
    +	val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
    +	REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
     
    -    /* Read the firmware version. */
    -    val = 0x00000001;
    -    REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
    -    fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
    -    fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & BCE_RV2P_INSTR_HIGH_HIGH;
    -	BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n", fw_ver_high, fw_ver_low);
    +	/* Read the firmware version. */
    +	val = 0x00000001;
    +	REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
    +	fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
    +	fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & 
    +	    BCE_RV2P_INSTR_HIGH_HIGH;
    +	BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n", 
    +	    fw_ver_high, fw_ver_low);
     
    -    val = 0x00000001;
    -    REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
    -    fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
    -    fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & BCE_RV2P_INSTR_HIGH_HIGH;
    -    BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n", fw_ver_high, fw_ver_low);
    +	val = 0x00000001;
    +	REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
    +	fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
    +	fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & 
    +	    BCE_RV2P_INSTR_HIGH_HIGH;
    +	BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n", 
    +	    fw_ver_high, fw_ver_low);
     
    -    /* Resume the RV2P processors. */
    -    val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
    -    val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
    -    REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
    +	/* Resume the RV2P processors. */
    +	val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
    +	val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
    +	REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
     
    -    /* Fetch the program counter value. */
    +	/* Fetch the program counter value. */
     	val = 0x68007800;
    -    REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
    -    val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
    -    pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
    -    pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
    -    BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
    -    BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
    +	REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
    +	val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
    +	pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
    +	pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
    +	BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
    +	BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
     
    -    /* Fetch the program counter value again to see if it is advancing. */
    -    val = 0x68007800;
    -    REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
    -    val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
    -    pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
    -    pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
    -    BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
    -    BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
    +	/* Fetch the program counter value again to see if it is advancing. */
    +	val = 0x68007800;
    +	REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
    +	val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
    +	pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
    +	pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
    +	BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
    +	BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
     
     	BCE_PRINTF(
    -		"----------------------------"
    -		"----------------"
    -		"----------------------------\n");
    +	    "----------------------------"
    +	    "----------------"
    +	    "----------------------------\n");
     }
     
     
    @@ -10436,7 +10666,7 @@ bce_breakpoint(struct bce_softc *sc)
     		bce_freeze_controller(sc);
     		bce_unfreeze_controller(sc);
     		bce_dump_enet(sc, NULL);
    -   		bce_dump_txbd(sc, 0, NULL);
    +		bce_dump_txbd(sc, 0, NULL);
     		bce_dump_rxbd(sc, 0, NULL);
     		bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
     		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
    @@ -10444,7 +10674,7 @@ bce_breakpoint(struct bce_softc *sc)
     		bce_dump_ctx(sc, RX_CID);
     		bce_dump_ftqs(sc);
     		bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
    -		bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
    +		bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD);
     		bce_dump_status_block(sc);
     		bce_dump_stats_block(sc);
     		bce_dump_driver_state(sc);
    @@ -10455,7 +10685,8 @@ bce_breakpoint(struct bce_softc *sc)
     		bce_dump_tpat_state(sc, 0);
     		bce_dump_cp_state(sc, 0);
     		bce_dump_com_state(sc, 0);
    -        bce_dump_rv2p_state(sc);
    +		bce_dump_rv2p_state(sc);
    +
     #ifdef BCE_JUMBO_HDRSPLIT
     		bce_dump_pgbd(sc, 0, NULL);
     		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);
    diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h
    index 177378b3aab..49bba6377f8 100644
    --- a/sys/dev/bce/if_bcereg.h
    +++ b/sys/dev/bce/if_bcereg.h
    @@ -85,9 +85,9 @@
     /* Conversion to FreeBSD type definitions.                                  */
     /****************************************************************************/
     #define u64 uint64_t
    -#define u32	uint32_t
    -#define u16	uint16_t
    -#define u8	uint8_t
    +#define u32 uint32_t
    +#define u16 uint16_t
    +#define u8  uint8_t
     
     #if BYTE_ORDER == BIG_ENDIAN
     #define __BIG_ENDIAN 1
    @@ -98,371 +98,369 @@
     #endif
     
     #define BCE_DWORD_PRINTFB	\
    -	"\020"					\
    -	"\40b31"				\
    -	"\37b30"				\
    -	"\36b29"				\
    -	"\35b28"				\
    -	"\34b27"				\
    -	"\33b26"				\
    -	"\32b25"				\
    -	"\31b24"				\
    -	"\30b23"				\
    -	"\27b22"				\
    -	"\26b21"				\
    -	"\25b20"				\
    -	"\24b19"				\
    -	"\23b18"				\
    -	"\22b17"				\
    -	"\21b16"				\
    -	"\20b15"				\
    -	"\17b14"				\
    -	"\16b13"				\
    -	"\15b12"				\
    -	"\14b11"				\
    -	"\13b10"				\
    -	"\12b9"					\
    -	"\11b8"					\
    -	"\10b7"					\
    -	"\07b6"					\
    -	"\06b5"					\
    -	"\05b4"					\
    -	"\04b3"					\
    -	"\03b2"					\
    -	"\02b1"					\
    +	"\020"			\
    +	"\40b31"		\
    +	"\37b30"		\
    +	"\36b29"		\
    +	"\35b28"		\
    +	"\34b27"		\
    +	"\33b26"		\
    +	"\32b25"		\
    +	"\31b24"		\
    +	"\30b23"		\
    +	"\27b22"		\
    +	"\26b21"		\
    +	"\25b20"		\
    +	"\24b19"		\
    +	"\23b18"		\
    +	"\22b17"		\
    +	"\21b16"		\
    +	"\20b15"		\
    +	"\17b14"		\
    +	"\16b13"		\
    +	"\15b12"		\
    +	"\14b11"		\
    +	"\13b10"		\
    +	"\12b9"			\
    +	"\11b8"			\
    +	"\10b7"			\
    +	"\07b6"			\
    +	"\06b5"			\
    +	"\05b4"			\
    +	"\04b3"			\
    +	"\03b2"			\
    +	"\02b1"			\
     	"\01b0"
     
     /* MII Control Register 0x0 */
     #define BCE_BMCR_PRINTFB	\
    -	"\020"					\
    -	"\20Reset"				\
    -	"\17Loopback"			\
    -	"\16Spd0"				\
    -	"\15AnegEna"			\
    -	"\14PwrDn"				\
    -	"\13Isolate"			\
    -	"\12RstrtAneg"			\
    -	"\11FD"					\
    -	"\10CollTst"			\
    -	"\07Spd1"				\
    -	"\06Rsrvd"				\
    -	"\05Rsrvd"				\
    -	"\04Rsrvd"				\
    -	"\03Rsrvd"				\
    -	"\02Rsrvd"				\
    +	"\020"			\
    +	"\20Reset"		\
    +	"\17Loopback"		\
    +	"\16Spd0"		\
    +	"\15AnegEna"		\
    +	"\14PwrDn"		\
    +	"\13Isolate"		\
    +	"\12RstrtAneg"		\
    +	"\11FD"			\
    +	"\10CollTst"		\
    +	"\07Spd1"		\
    +	"\06Rsrvd"		\
    +	"\05Rsrvd"		\
    +	"\04Rsrvd"		\
    +	"\03Rsrvd"		\
    +	"\02Rsrvd"		\
     	"\01Rsrvd"
     
     /* MII Status Register 0x1 */
     #define BCE_BMSR_PRINTFB	\
    -	"\020"					\
    -	"\20Cap100T4"			\
    -	"\17Cap100XFD"			\
    -	"\16Cap100XHD"			\
    -	"\15Cap10FD"			\
    -	"\14Cap10HD"			\
    -	"\13Cap100T2FD"			\
    -	"\12Cap100T2HD"			\
    -	"\11ExtStsPrsnt"		\
    -	"\10Rsrvd"				\
    -	"\07PrmblSupp"			\
    -	"\06AnegCmpl"			\
    -	"\05RemFaultDet"		\
    -	"\04AnegCap"			\
    -	"\03LnkUp"				\
    -	"\02JabberDet"			\
    +	"\020"			\
    +	"\20Cap100T4"		\
    +	"\17Cap100XFD"		\
    +	"\16Cap100XHD"		\
    +	"\15Cap10FD"		\
    +	"\14Cap10HD"		\
    +	"\13Cap100T2FD"		\
    +	"\12Cap100T2HD"		\
    +	"\11ExtStsPrsnt"	\
    +	"\10Rsrvd"		\
    +	"\07PrmblSupp"		\
    +	"\06AnegCmpl"		\
    +	"\05RemFaultDet"	\
    +	"\04AnegCap"		\
    +	"\03LnkUp"		\
    +	"\02JabberDet"		\
     	"\01ExtCapSupp"
     
     /* MII Autoneg Advertisement Register 0x4 */
     #define BCE_ANAR_PRINTFB	\
    -	"\020"					\
    -	"\20AdvNxtPg"			\
    -	"\17Rsrvd"				\
    -	"\16AdvRemFault"		\
    -	"\15Rsrvd"				\
    -	"\14AdvAsymPause"		\
    -	"\13AdvPause"			\
    -	"\12Adv100T4"			\
    -	"\11Adv100FD"			\
    -	"\10Adv100HD"			\
    -	"\07Adv10FD"			\
    -	"\06Adv10HD"			\
    -	"\05Rsrvd"				\
    -	"\04Rsrvd"				\
    -	"\03Rsrvd"				\
    -	"\02Rsrvd"				\
    +	"\020"			\
    +	"\20AdvNxtPg"		\
    +	"\17Rsrvd"		\
    +	"\16AdvRemFault"	\
    +	"\15Rsrvd"		\
    +	"\14AdvAsymPause"	\
    +	"\13AdvPause"		\
    +	"\12Adv100T4"		\
    +	"\11Adv100FD"		\
    +	"\10Adv100HD"		\
    +	"\07Adv10FD"		\
    +	"\06Adv10HD"		\
    +	"\05Rsrvd"		\
    +	"\04Rsrvd"		\
    +	"\03Rsrvd"		\
    +	"\02Rsrvd"		\
     	"\01Adv802.3"
     
     /* MII Autoneg Link Partner Ability Register 0x5 */
     #define BCE_ANLPAR_PRINTFB	\
    -	"\020"					\
    -	"\20CapNxtPg"			\
    -	"\17Ack"				\
    -	"\16CapRemFault"	 	\
    -	"\15Rsrvd"				\
    -	"\14CapAsymPause"		\
    -	"\13CapPause"			\
    -	"\12Cap100T4"			\
    -	"\11Cap100FD"			\
    -	"\10Cap100HD"			\
    -	"\07Cap10FD"			\
    -	"\06Cap10HD"			\
    -	"\05Rsrvd"				\
    -	"\04Rsrvd"				\
    -	"\03Rsrvd"				\
    -	"\02Rsrvd"				\
    +	"\020"			\
    +	"\20CapNxtPg"		\
    +	"\17Ack"		\
    +	"\16CapRemFault"	\
    +	"\15Rsrvd"		\
    +	"\14CapAsymPause"	\
    +	"\13CapPause"		\
    +	"\12Cap100T4"		\
    +	"\11Cap100FD"		\
    +	"\10Cap100HD"		\
    +	"\07Cap10FD"		\
    +	"\06Cap10HD"		\
    +	"\05Rsrvd"		\
    +	"\04Rsrvd"		\
    +	"\03Rsrvd"		\
    +	"\02Rsrvd"		\
     	"\01Cap802.3"
     
     /* 1000Base-T Control Register 0x09 */
     #define BCE_1000CTL_PRINTFB	\
    -	"\020"					\
    -	"\20Test3"				\
    -	"\17Test2"				\
    -	"\16Test1"				\
    -	"\15MasterSlave"		\
    -	"\14ForceMaster"		\
    -	"\13SwitchDev" 			\
    -	"\12Adv1000TFD"			\
    -	"\11Adv1000THD"			\
    -	"\10Rsrvd"				\
    -	"\07Rsrvd"				\
    -	"\06Rsrvd"				\
    -	"\05Rsrvd"				\
    -	"\04Rsrvd"				\
    -	"\03Rsrvd"				\
    -	"\02Rsrvd"				\
    +	"\020"			\
    +	"\20Test3"		\
    +	"\17Test2"		\
    +	"\16Test1"		\
    +	"\15MasterSlave"	\
    +	"\14ForceMaster"	\
    +	"\13SwitchDev" 		\
    +	"\12Adv1000TFD"		\
    +	"\11Adv1000THD"		\
    +	"\10Rsrvd"		\
    +	"\07Rsrvd"		\
    +	"\06Rsrvd"		\
    +	"\05Rsrvd"		\
    +	"\04Rsrvd"		\
    +	"\03Rsrvd"		\
    +	"\02Rsrvd"		\
     	"\01Rsrvd"
     
     /* MII 1000Base-T Status Register 0x0a */
     #define BCE_1000STS_PRINTFB	\
    -	"\020"					\
    -	"\20MstrSlvFault"		\
    -	"\17Master"				\
    -	"\16LclRcvrOk"			\
    -	"\15RemRcvrOk"			\
    -	"\14Cap1000FD"			\
    -	"\13Cpa1000HD"			\
    -	"\12Rsrvd"				\
    +	"\020"			\
    +	"\20MstrSlvFault"	\
    +	"\17Master"		\
    +	"\16LclRcvrOk"		\
    +	"\15RemRcvrOk"		\
    +	"\14Cap1000FD"		\
    +	"\13Cpa1000HD"		\
    +	"\12Rsrvd"		\
     	"\11Rsrvd"
     
     /* MII Extended Status Register 0x0f */
     #define BCE_EXTSTS_PRINTFB	\
    -	"\020"					\
    -	"\20b15"				\
    -	"\17b14"				\
    -	"\16b13"				\
    -	"\15b12"				\
    -	"\14Rsrvd"				\
    -	"\13Rsrvd"				\
    -	"\12Rsrvd"				\
    -	"\11Rsrvd"				\
    -	"\10Rsrvd"				\
    -	"\07Rsrvd"				\
    -	"\06Rsrvd" 				\
    -	"\05Rsrvd"				\
    -	"\04Rsrvd"				\
    -	"\03Rsrvd"				\
    -	"\02Rsrvd"				\
    +	"\020"			\
    +	"\20b15"		\
    +	"\17b14"		\
    +	"\16b13"		\
    +	"\15b12"		\
    +	"\14Rsrvd"		\
    +	"\13Rsrvd"		\
    +	"\12Rsrvd"		\
    +	"\11Rsrvd"		\
    +	"\10Rsrvd"		\
    +	"\07Rsrvd"		\
    +	"\06Rsrvd" 		\
    +	"\05Rsrvd"		\
    +	"\04Rsrvd"		\
    +	"\03Rsrvd"		\
    +	"\02Rsrvd"		\
     	"\01Rsrvd"
     
     /* MII Autoneg Link Partner Ability Register 0x19 */
     #define BCE_AUXSTS_PRINTFB	\
    -	"\020"					\
    -	"\20AnegCmpl"			\
    -	"\17AnegCmplAck"		\
    -	"\16AnegAckDet"			\
    -	"\15AnegAblDet"			\
    -	"\14AnegNextPgWait"		\
    -	"\13HCD"				\
    -	"\12HCD" 				\
    -	"\11HCD" 				\
    -	"\10PrlDetFault"		\
    -	"\07RemFault"			\
    -	"\06PgRcvd"				\
    +	"\020"			\
    +	"\20AnegCmpl"		\
    +	"\17AnegCmplAck"	\
    +	"\16AnegAckDet"		\
    +	"\15AnegAblDet"		\
    +	"\14AnegNextPgWait"	\
    +	"\13HCD"		\
    +	"\12HCD" 		\
    +	"\11HCD" 		\
    +	"\10PrlDetFault"	\
    +	"\07RemFault"		\
    +	"\06PgRcvd"		\
     	"\05LnkPrtnrAnegAbl"	\
    -	"\04LnkPrtnrNPAbl"		\
    -	"\03LnkUp"				\
    -	"\02EnaPauseRcv"		\
    +	"\04LnkPrtnrNPAbl"	\
    +	"\03LnkUp"		\
    +	"\02EnaPauseRcv"	\
     	"\01EnaPausXmit"
     
    -/* Remove before release. */
    -/* #define BCE_DEBUG 1 */
    -/* #define BCE_NVRAM_WRITE_SUPPORT */
    +/* 
    + * Remove before release: 
    + *
    + * #define BCE_DEBUG
    + * #define BCE_NVRAM_WRITE_SUPPORT
    + * #define BCE_JUMBO_HDRSPLIT
    + */
     
     /****************************************************************************/
     /* Debugging macros and definitions.                                        */
     /****************************************************************************/
     
    -#define BCE_CP_LOAD 			0x00000001
    -#define BCE_CP_SEND		 		0x00000002
    -#define BCE_CP_RECV				0x00000004
    -#define BCE_CP_INTR				0x00000008
    -#define BCE_CP_UNLOAD			0x00000010
    -#define BCE_CP_RESET			0x00000020
    -#define BCE_CP_PHY				0x00000040
    -#define BCE_CP_NVRAM			0x00000080
    -#define BCE_CP_FIRMWARE			0x00000100
    -#define BCE_CP_CTX				0x00000200
    -#define BCE_CP_REG				0x00000400
    -#define BCE_CP_MISC				0x00400000
    -#define BCE_CP_SPECIAL			0x00800000
    -#define BCE_CP_ALL				0x00FFFFFF
    +#define BCE_CP_LOAD 		0x00000001
    +#define BCE_CP_SEND		0x00000002
    +#define BCE_CP_RECV		0x00000004
    +#define BCE_CP_INTR		0x00000008
    +#define BCE_CP_UNLOAD		0x00000010
    +#define BCE_CP_RESET		0x00000020
    +#define BCE_CP_PHY		0x00000040
    +#define BCE_CP_NVRAM		0x00000080
    +#define BCE_CP_FIRMWARE		0x00000100
    +#define BCE_CP_CTX		0x00000200
    +#define BCE_CP_REG		0x00000400
    +#define BCE_CP_MISC		0x00400000
    +#define BCE_CP_SPECIAL		0x00800000
    +#define BCE_CP_ALL		0x00FFFFFF
     
    -#define BCE_CP_MASK				0x00FFFFFF
    +#define BCE_CP_MASK		0x00FFFFFF
     
    -#define BCE_LEVEL_FATAL			0x00000000
    -#define BCE_LEVEL_WARN			0x01000000
    -#define BCE_LEVEL_INFO			0x02000000
    -#define BCE_LEVEL_VERBOSE		0x03000000
    -#define BCE_LEVEL_EXTREME		0x04000000
    -#define BCE_LEVEL_INSANE		0x05000000
    +#define BCE_LEVEL_FATAL		0x00000000
    +#define BCE_LEVEL_WARN		0x01000000
    +#define BCE_LEVEL_INFO		0x02000000
    +#define BCE_LEVEL_VERBOSE	0x03000000
    +#define BCE_LEVEL_EXTREME	0x04000000
    +#define BCE_LEVEL_INSANE	0x05000000
     
    -#define BCE_LEVEL_MASK			0xFF000000
    +#define BCE_LEVEL_MASK		0xFF000000
     
    -#define BCE_WARN_LOAD			(BCE_CP_LOAD | BCE_LEVEL_WARN)
    -#define BCE_INFO_LOAD			(BCE_CP_LOAD | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_LOAD		(BCE_CP_LOAD | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_LOAD		(BCE_CP_LOAD | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_LOAD			(BCE_CP_LOAD | BCE_LEVEL_INSANE)
    +#define BCE_WARN_LOAD		(BCE_CP_LOAD | BCE_LEVEL_WARN)
    +#define BCE_INFO_LOAD		(BCE_CP_LOAD | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_LOAD	(BCE_CP_LOAD | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_LOAD	(BCE_CP_LOAD | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_LOAD		(BCE_CP_LOAD | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_SEND			(BCE_CP_SEND | BCE_LEVEL_WARN)
    -#define BCE_INFO_SEND			(BCE_CP_SEND | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_SEND		(BCE_CP_SEND | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_SEND		(BCE_CP_SEND | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_SEND			(BCE_CP_SEND | BCE_LEVEL_INSANE)
    +#define BCE_WARN_SEND		(BCE_CP_SEND | BCE_LEVEL_WARN)
    +#define BCE_INFO_SEND		(BCE_CP_SEND | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_SEND	(BCE_CP_SEND | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_SEND	(BCE_CP_SEND | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_SEND		(BCE_CP_SEND | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_RECV			(BCE_CP_RECV | BCE_LEVEL_WARN)
    -#define BCE_INFO_RECV			(BCE_CP_RECV | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_RECV		(BCE_CP_RECV | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_RECV		(BCE_CP_RECV | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_RECV			(BCE_CP_RECV | BCE_LEVEL_INSANE)
    +#define BCE_WARN_RECV		(BCE_CP_RECV | BCE_LEVEL_WARN)
    +#define BCE_INFO_RECV		(BCE_CP_RECV | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_RECV	(BCE_CP_RECV | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_RECV	(BCE_CP_RECV | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_RECV		(BCE_CP_RECV | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_INTR			(BCE_CP_INTR | BCE_LEVEL_WARN)
    -#define BCE_INFO_INTR			(BCE_CP_INTR | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_INTR		(BCE_CP_INTR | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_INTR		(BCE_CP_INTR | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_INTR			(BCE_CP_INTR | BCE_LEVEL_INSANE)
    +#define BCE_WARN_INTR		(BCE_CP_INTR | BCE_LEVEL_WARN)
    +#define BCE_INFO_INTR		(BCE_CP_INTR | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_INTR	(BCE_CP_INTR | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_INTR	(BCE_CP_INTR | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_INTR		(BCE_CP_INTR | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_UNLOAD			(BCE_CP_UNLOAD | BCE_LEVEL_WARN)
    -#define BCE_INFO_UNLOAD			(BCE_CP_UNLOAD | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_UNLOAD		(BCE_CP_UNLOAD | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_UNLOAD		(BCE_CP_UNLOAD | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_UNLOAD		(BCE_CP_UNLOAD | BCE_LEVEL_INSANE)
    +#define BCE_WARN_UNLOAD		(BCE_CP_UNLOAD | BCE_LEVEL_WARN)
    +#define BCE_INFO_UNLOAD		(BCE_CP_UNLOAD | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_UNLOAD	(BCE_CP_UNLOAD | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_UNLOAD	(BCE_CP_UNLOAD | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_UNLOAD	(BCE_CP_UNLOAD | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_RESET			(BCE_CP_RESET | BCE_LEVEL_WARN)
    -#define BCE_INFO_RESET			(BCE_CP_RESET | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_RESET		(BCE_CP_RESET | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_RESET		(BCE_CP_RESET | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_RESET		(BCE_CP_RESET | BCE_LEVEL_INSANE)
    +#define BCE_WARN_RESET		(BCE_CP_RESET | BCE_LEVEL_WARN)
    +#define BCE_INFO_RESET		(BCE_CP_RESET | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_RESET	(BCE_CP_RESET | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_RESET	(BCE_CP_RESET | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_RESET	(BCE_CP_RESET | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_PHY			(BCE_CP_PHY | BCE_LEVEL_WARN)
    -#define BCE_INFO_PHY			(BCE_CP_PHY | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_PHY			(BCE_CP_PHY | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_PHY			(BCE_CP_PHY | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_PHY			(BCE_CP_PHY | BCE_LEVEL_INSANE)
    +#define BCE_WARN_PHY		(BCE_CP_PHY | BCE_LEVEL_WARN)
    +#define BCE_INFO_PHY		(BCE_CP_PHY | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_PHY		(BCE_CP_PHY | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_PHY		(BCE_CP_PHY | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_PHY		(BCE_CP_PHY | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_NVRAM			(BCE_CP_NVRAM | BCE_LEVEL_WARN)
    -#define BCE_INFO_NVRAM			(BCE_CP_NVRAM | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_NVRAM		(BCE_CP_NVRAM | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_NVRAM		(BCE_CP_NVRAM | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_NVRAM		(BCE_CP_NVRAM | BCE_LEVEL_INSANE)
    +#define BCE_WARN_NVRAM		(BCE_CP_NVRAM | BCE_LEVEL_WARN)
    +#define BCE_INFO_NVRAM		(BCE_CP_NVRAM | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_NVRAM	(BCE_CP_NVRAM | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_NVRAM	(BCE_CP_NVRAM | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_NVRAM	(BCE_CP_NVRAM | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_FIRMWARE		(BCE_CP_FIRMWARE | BCE_LEVEL_WARN)
    -#define BCE_INFO_FIRMWARE		(BCE_CP_FIRMWARE | BCE_LEVEL_INFO)
    +#define BCE_WARN_FIRMWARE	(BCE_CP_FIRMWARE | BCE_LEVEL_WARN)
    +#define BCE_INFO_FIRMWARE	(BCE_CP_FIRMWARE | BCE_LEVEL_INFO)
     #define BCE_VERBOSE_FIRMWARE	(BCE_CP_FIRMWARE | BCE_LEVEL_VERBOSE)
     #define BCE_EXTREME_FIRMWARE	(BCE_CP_FIRMWARE | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_FIRMWARE		(BCE_CP_FIRMWARE | BCE_LEVEL_INSANE)
    +#define BCE_INSANE_FIRMWARE	(BCE_CP_FIRMWARE | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_CTX			(BCE_CP_CTX | BCE_LEVEL_WARN)
    -#define BCE_INFO_CTX			(BCE_CP_CTX | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_CTX			(BCE_CP_CTX | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_CTX			(BCE_CP_CTX | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_CTX			(BCE_CP_CTX | BCE_LEVEL_INSANE)
    +#define BCE_WARN_CTX		(BCE_CP_CTX | BCE_LEVEL_WARN)
    +#define BCE_INFO_CTX		(BCE_CP_CTX | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_CTX		(BCE_CP_CTX | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_CTX		(BCE_CP_CTX | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_CTX		(BCE_CP_CTX | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_REG			(BCE_CP_REG | BCE_LEVEL_WARN)
    -#define BCE_INFO_REG			(BCE_CP_REG | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_REG			(BCE_CP_REG | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_REG			(BCE_CP_REG | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_REG			(BCE_CP_REG | BCE_LEVEL_INSANE)
    +#define BCE_WARN_REG		(BCE_CP_REG | BCE_LEVEL_WARN)
    +#define BCE_INFO_REG		(BCE_CP_REG | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_REG		(BCE_CP_REG | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_REG		(BCE_CP_REG | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_REG		(BCE_CP_REG | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_MISC			(BCE_CP_MISC | BCE_LEVEL_WARN)
    -#define BCE_INFO_MISC			(BCE_CP_MISC | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_MISC		(BCE_CP_MISC | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_MISC		(BCE_CP_MISC | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_MISC			(BCE_CP_MISC | BCE_LEVEL_INSANE)
    +#define BCE_WARN_MISC		(BCE_CP_MISC | BCE_LEVEL_WARN)
    +#define BCE_INFO_MISC		(BCE_CP_MISC | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_MISC	(BCE_CP_MISC | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_MISC	(BCE_CP_MISC | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_MISC		(BCE_CP_MISC | BCE_LEVEL_INSANE)
     
    -#define BCE_WARN_SPECIAL		(BCE_CP_SPECIAL | BCE_LEVEL_WARN)
    -#define BCE_INFO_SPECIAL		(BCE_CP_SPECIAL | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE_SPECIAL		(BCE_CP_SPECIAL | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME_SPECIAL		(BCE_CP_SPECIAL | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE_SPECIAL		(BCE_CP_SPECIAL | BCE_LEVEL_INSANE)
    +#define BCE_WARN_SPECIAL	(BCE_CP_SPECIAL | BCE_LEVEL_WARN)
    +#define BCE_INFO_SPECIAL	(BCE_CP_SPECIAL | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE_SPECIAL	(BCE_CP_SPECIAL | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME_SPECIAL	(BCE_CP_SPECIAL | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE_SPECIAL	(BCE_CP_SPECIAL | BCE_LEVEL_INSANE)
     
    -#define BCE_FATAL				(BCE_CP_ALL | BCE_LEVEL_FATAL)
    -#define BCE_WARN				(BCE_CP_ALL | BCE_LEVEL_WARN)
    -#define BCE_INFO				(BCE_CP_ALL | BCE_LEVEL_INFO)
    -#define BCE_VERBOSE				(BCE_CP_ALL | BCE_LEVEL_VERBOSE)
    -#define BCE_EXTREME				(BCE_CP_ALL | BCE_LEVEL_EXTREME)
    -#define BCE_INSANE				(BCE_CP_ALL | BCE_LEVEL_INSANE)
    +#define BCE_FATAL		(BCE_CP_ALL | BCE_LEVEL_FATAL)
    +#define BCE_WARN		(BCE_CP_ALL | BCE_LEVEL_WARN)
    +#define BCE_INFO		(BCE_CP_ALL | BCE_LEVEL_INFO)
    +#define BCE_VERBOSE		(BCE_CP_ALL | BCE_LEVEL_VERBOSE)
    +#define BCE_EXTREME		(BCE_CP_ALL | BCE_LEVEL_EXTREME)
    +#define BCE_INSANE		(BCE_CP_ALL | BCE_LEVEL_INSANE)
     
    -#define BCE_CODE_PATH(cp)		((cp & BCE_CP_MASK) & bce_debug)
    -#define BCE_MSG_LEVEL(lv)		((lv & BCE_LEVEL_MASK) <= (bce_debug & BCE_LEVEL_MASK))
    -#define BCE_LOG_MSG(m)			(BCE_CODE_PATH(m) && BCE_MSG_LEVEL(m))
    +#define BCE_CODE_PATH(cp)	((cp & BCE_CP_MASK) & bce_debug)
    +#define BCE_MSG_LEVEL(lv)	\
    +    ((lv & BCE_LEVEL_MASK) <= (bce_debug & BCE_LEVEL_MASK))
    +#define BCE_LOG_MSG(m)		(BCE_CODE_PATH(m) && BCE_MSG_LEVEL(m))
     
     #ifdef BCE_DEBUG
     
    -/*
    - * Calculate the time delta between two reads
    - * of the 25MHz free running clock.
    - */
    -#define BCE_TIME_DELTA(start, end)	(start > end ? (start - end) : \
    -	(~start + end + 1))
    -
     /* Print a message based on the logging level and code path. */
    -#define DBPRINT(sc, level, format, args...)					\
    -	if (BCE_LOG_MSG(level)) {							\
    -		device_printf(sc->bce_dev, format, ## args);						\
    +#define DBPRINT(sc, level, format, args...)			\
    +	if (BCE_LOG_MSG(level)) {				\
    +		device_printf(sc->bce_dev, format, ## args);	\
     	}
     
     /* Runs a particular command when debugging is enabled. */
    -#define DBRUN(args...)			\
    -	do {						\
    -		args;					\
    +#define DBRUN(args...)						\
    +	do {							\
    +		args;						\
     	} while (0)
     
     /* Runs a particular command based on the logging level and code path. */
    -#define DBRUNMSG(msg, args...)	\
    -	if (BCE_LOG_MSG(msg)) {		\
    -		args;					\
    +#define DBRUNMSG(msg, args...)					\
    +	if (BCE_LOG_MSG(msg)) {					\
    +		args;						\
     	}
     
     /* Runs a particular command based on the logging level. */
    -#define DBRUNLV(level, args...) \
    -	if (BCE_MSG_LEVEL(level)) { \
    -		args;					\
    +#define DBRUNLV(level, args...) 				\
    +	if (BCE_MSG_LEVEL(level)) { 				\
    +		args;						\
     	}
     
     /* Runs a particular command based on the code path. */
    -#define DBRUNCP(cp, args...) 	\
    -	if (BCE_CODE_PATH(cp)) { 	\
    -		args; 					\
    +#define DBRUNCP(cp, args...) 					\
    +	if (BCE_CODE_PATH(cp)) { 				\
    +		args; 						\
     	}
     
     /* Runs a particular command based on a condition. */
    -#define DBRUNIF(cond, args...)									\
    -	if (cond) {													\
    -		args;													\
    +#define DBRUNIF(cond, args...)					\
    +	if (cond) {						\
    +		args;						\
     	}
     
     /* Announces function entry. */
    -#define DBENTER(cond)									  		\
    +#define DBENTER(cond)						\
     	DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__)
     
     /* Announces function exit. */
    -#define DBEXIT(cond)											\
    +#define DBEXIT(cond)						\
     	DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__)
     
     /* Temporarily override the debug level. */
    -#define DBPUSH(cond)											\
    -	u32 bce_debug_temp = bce_debug;								\
    +#define DBPUSH(cond)						\
    +	u32 bce_debug_temp = bce_debug;				\
     	bce_debug |= cond;
     
     /* Restore the previously overriden debug level. */
    @@ -482,43 +480,43 @@
     #define DB_OR_RANDOMTRUE(defects)   || (random() < defects)
     #define DB_AND_RANDOMTRUE(defects)  && (random() < defects)
     
    -#define DB_PRINT_PHY_REG(reg, val)											\
    -	switch(reg) {															\
    -		case 0x00: DBPRINT(sc, BCE_INSANE_PHY,								\
    -			"%s(): phy = %d, reg = 0x%04X (BMCR   ), val = 0x%b\n",			\
    -			__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,		\
    -			BCE_BMCR_PRINTFB); break;										\
    -		case 0x01: DBPRINT(sc, BCE_INSANE_PHY,								\
    -			"%s(): phy = %d, reg = 0x%04X (BMSR   ), val = 0x%b\n",			\
    -			__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,		\
    -			BCE_BMSR_PRINTFB); break;										\
    -		case 0x04: DBPRINT(sc, BCE_INSANE_PHY,								\
    -			"%s(): phy = %d, reg = 0x%04X (ANAR   ), val = 0x%b\n",			\
    -			__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,		\
    -			BCE_ANAR_PRINTFB); break;										\
    -		case 0x05: DBPRINT(sc, BCE_INSANE_PHY,								\
    -			"%s(): phy = %d, reg = 0x%04X (ANLPAR ), val = 0x%b\n",			\
    -			__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,		\
    -			BCE_ANLPAR_PRINTFB); break;										\
    -		case 0x09: DBPRINT(sc, BCE_INSANE_PHY,								\
    -			"%s(): phy = %d, reg = 0x%04X (1000CTL), val = 0x%b\n",			\
    -			__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,		\
    -			BCE_1000CTL_PRINTFB); break;									\
    -		case 0x0a: DBPRINT(sc, BCE_INSANE_PHY,								\
    -			"%s(): phy = %d, reg = 0x%04X (1000STS), val = 0x%b\n",			\
    -			__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,		\
    -			BCE_1000STS_PRINTFB); break;									\
    -		case 0x0f: DBPRINT(sc, BCE_INSANE_PHY,								\
    -			"%s(): phy = %d, reg = 0x%04X (EXTSTS ), val = 0x%b\n",			\
    -			__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,		\
    -			BCE_EXTSTS_PRINTFB); break;										\
    -		case 0x19: DBPRINT(sc, BCE_INSANE_PHY,								\
    -			"%s(): phy = %d, reg = 0x%04X (AUXSTS ), val = 0x%b\n",			\
    -			__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,		\
    -			BCE_AUXSTS_PRINTFB); break;										\
    -		default: DBPRINT(sc, BCE_INSANE_PHY,								\
    -			"%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n",					\
    -			__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff);		\
    +#define DB_PRINT_PHY_REG(reg, val)					\
    +switch(reg) {								\
    +case 0x00: DBPRINT(sc, BCE_INSANE_PHY,					\
    +	"%s(): phy = %d, reg = 0x%04X (BMCR   ), val = 0x%b\n",		\
    +	__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,	\
    +	BCE_BMCR_PRINTFB); break;					\
    +case 0x01: DBPRINT(sc, BCE_INSANE_PHY,					\
    +	"%s(): phy = %d, reg = 0x%04X (BMSR   ), val = 0x%b\n",		\
    +	__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,	\
    +	BCE_BMSR_PRINTFB); break;					\
    +case 0x04: DBPRINT(sc, BCE_INSANE_PHY,					\
    +	"%s(): phy = %d, reg = 0x%04X (ANAR   ), val = 0x%b\n",		\
    +	__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,	\
    +	BCE_ANAR_PRINTFB); break;					\
    +case 0x05: DBPRINT(sc, BCE_INSANE_PHY,					\
    +	"%s(): phy = %d, reg = 0x%04X (ANLPAR ), val = 0x%b\n",		\
    +	__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,	\
    +	BCE_ANLPAR_PRINTFB); break;					\
    +case 0x09: DBPRINT(sc, BCE_INSANE_PHY,					\
    +	"%s(): phy = %d, reg = 0x%04X (1000CTL), val = 0x%b\n",		\
    +	__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,	\
    +	BCE_1000CTL_PRINTFB); break;					\
    +case 0x0a: DBPRINT(sc, BCE_INSANE_PHY,					\
    +	"%s(): phy = %d, reg = 0x%04X (1000STS), val = 0x%b\n",		\
    +	__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,	\
    +	BCE_1000STS_PRINTFB); break;					\
    +case 0x0f: DBPRINT(sc, BCE_INSANE_PHY,					\
    +	"%s(): phy = %d, reg = 0x%04X (EXTSTS ), val = 0x%b\n",		\
    +	__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,	\
    +	BCE_EXTSTS_PRINTFB); break;					\
    +case 0x19: DBPRINT(sc, BCE_INSANE_PHY,					\
    +	"%s(): phy = %d, reg = 0x%04X (AUXSTS ), val = 0x%b\n",		\
    +	__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff,	\
    +	BCE_AUXSTS_PRINTFB); break;					\
    +default: DBPRINT(sc, BCE_INSANE_PHY,					\
    +	"%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n",			\
    +	__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff);	\
     	}
     
     #else
    @@ -560,55 +558,55 @@
     /* Device identification definitions.                                       */
     /****************************************************************************/
     #define BRCM_VENDORID				0x14E4
    -#define BRCM_DEVICEID_BCM5706		0x164A
    -#define BRCM_DEVICEID_BCM5706S		0x16AA
    -#define BRCM_DEVICEID_BCM5708		0x164C
    -#define BRCM_DEVICEID_BCM5708S		0x16AC
    -#define BRCM_DEVICEID_BCM5709		0x1639
    -#define BRCM_DEVICEID_BCM5709S		0x163A
    -#define BRCM_DEVICEID_BCM5716		0x163B
    +#define BRCM_DEVICEID_BCM5706			0x164A
    +#define BRCM_DEVICEID_BCM5706S			0x16AA
    +#define BRCM_DEVICEID_BCM5708			0x164C
    +#define BRCM_DEVICEID_BCM5708S			0x16AC
    +#define BRCM_DEVICEID_BCM5709			0x1639
    +#define BRCM_DEVICEID_BCM5709S			0x163A
    +#define BRCM_DEVICEID_BCM5716			0x163B
     
    -#define HP_VENDORID					0x103C
    +#define HP_VENDORID				0x103C
     
    -#define PCI_ANY_ID					(u_int16_t) (~0U)
    +#define PCI_ANY_ID				(u_int16_t) (~0U)
     
     /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
     
    -#define BCE_CHIP_NUM(sc)			(((sc)->bce_chipid) & 0xffff0000)
    -#define BCE_CHIP_NUM_5706			0x57060000
    -#define BCE_CHIP_NUM_5708			0x57080000
    -#define BCE_CHIP_NUM_5709			0x57090000
    -#define BCE_CHIP_NUM_5716			0x57160000
    +#define BCE_CHIP_NUM(sc)		(((sc)->bce_chipid) & 0xffff0000)
    +#define BCE_CHIP_NUM_5706		0x57060000
    +#define BCE_CHIP_NUM_5708		0x57080000
    +#define BCE_CHIP_NUM_5709		0x57090000
    +#define BCE_CHIP_NUM_5716		0x57160000
     
    -#define BCE_CHIP_REV(sc)			(((sc)->bce_chipid) & 0x0000f000)
    -#define BCE_CHIP_REV_Ax				0x00000000
    -#define BCE_CHIP_REV_Bx				0x00001000
    -#define BCE_CHIP_REV_Cx				0x00002000
    +#define BCE_CHIP_REV(sc)		(((sc)->bce_chipid) & 0x0000f000)
    +#define BCE_CHIP_REV_Ax			0x00000000
    +#define BCE_CHIP_REV_Bx			0x00001000
    +#define BCE_CHIP_REV_Cx			0x00002000
     
    -#define BCE_CHIP_METAL(sc)			(((sc)->bce_chipid) & 0x00000ff0)
    -#define BCE_CHIP_BOND(bp)			(((sc)->bce_chipid) & 0x0000000f)
    +#define BCE_CHIP_METAL(sc)		(((sc)->bce_chipid) & 0x00000ff0)
    +#define BCE_CHIP_BOND(bp)		(((sc)->bce_chipid) & 0x0000000f)
     
    -#define BCE_CHIP_ID(sc)				(((sc)->bce_chipid) & 0xfffffff0)
    -#define BCE_CHIP_ID_5706_A0			0x57060000
    -#define BCE_CHIP_ID_5706_A1			0x57060010
    -#define BCE_CHIP_ID_5706_A2			0x57060020
    -#define BCE_CHIP_ID_5706_A3			0x57060030
    -#define BCE_CHIP_ID_5708_A0			0x57080000
    -#define BCE_CHIP_ID_5708_B0			0x57081000
    -#define BCE_CHIP_ID_5708_B1			0x57081010
    -#define BCE_CHIP_ID_5708_B2			0x57081020
    -#define BCE_CHIP_ID_5709_A0			0x57090000
    -#define BCE_CHIP_ID_5709_A1			0x57090010
    -#define BCE_CHIP_ID_5709_B0			0x57091000
    -#define BCE_CHIP_ID_5709_B1			0x57091010
    -#define BCE_CHIP_ID_5709_B2			0x57091020
    -#define BCE_CHIP_ID_5709_C0			0x57092000
    -#define BCE_CHIP_ID_5716_C0			0x57162000
    +#define BCE_CHIP_ID(sc)			(((sc)->bce_chipid) & 0xfffffff0)
    +#define BCE_CHIP_ID_5706_A0		0x57060000
    +#define BCE_CHIP_ID_5706_A1		0x57060010
    +#define BCE_CHIP_ID_5706_A2		0x57060020
    +#define BCE_CHIP_ID_5706_A3		0x57060030
    +#define BCE_CHIP_ID_5708_A0		0x57080000
    +#define BCE_CHIP_ID_5708_B0		0x57081000
    +#define BCE_CHIP_ID_5708_B1		0x57081010
    +#define BCE_CHIP_ID_5708_B2		0x57081020
    +#define BCE_CHIP_ID_5709_A0		0x57090000
    +#define BCE_CHIP_ID_5709_A1		0x57090010
    +#define BCE_CHIP_ID_5709_B0		0x57091000
    +#define BCE_CHIP_ID_5709_B1		0x57091010
    +#define BCE_CHIP_ID_5709_B2		0x57091020
    +#define BCE_CHIP_ID_5709_C0		0x57092000
    +#define BCE_CHIP_ID_5716_C0		0x57162000
     
     #define BCE_CHIP_BOND_ID(sc)		(((sc)->bce_chipid) & 0xf)
     
     /* A serdes chip will have the first bit of the bond id set. */
    -#define BCE_CHIP_BOND_ID_SERDES_BIT		0x01
    +#define BCE_CHIP_BOND_ID_SERDES_BIT	0x01
     
     
     /* shorthand one */
    @@ -623,11 +621,11 @@
     #define BCE_CHIPREV_5701_AX		0x00
     
     struct bce_type {
    -	u_int16_t		bce_vid;
    -	u_int16_t		bce_did;
    -	u_int16_t		bce_svid;
    -	u_int16_t		bce_sdid;
    -	char			*bce_name;
    +	u_int16_t bce_vid;
    +	u_int16_t bce_did;
    +	u_int16_t bce_svid;
    +	u_int16_t bce_sdid;
    +	char      *bce_name;
     };
     
     /****************************************************************************/
    @@ -669,44 +667,43 @@ struct bce_type {
     /****************************************************************************/
     
     /* Buffered flash (Atmel: AT45DB011B) specific information */
    -#define SEEPROM_PAGE_BITS				2
    -#define SEEPROM_PHY_PAGE_SIZE			(1 << SEEPROM_PAGE_BITS)
    -#define SEEPROM_BYTE_ADDR_MASK			(SEEPROM_PHY_PAGE_SIZE-1)
    -#define SEEPROM_PAGE_SIZE				4
    -#define SEEPROM_TOTAL_SIZE				65536
    +#define SEEPROM_PAGE_BITS		2
    +#define SEEPROM_PHY_PAGE_SIZE		(1 << SEEPROM_PAGE_BITS)
    +#define SEEPROM_BYTE_ADDR_MASK		(SEEPROM_PHY_PAGE_SIZE-1)
    +#define SEEPROM_PAGE_SIZE		4
    +#define SEEPROM_TOTAL_SIZE		65536
     
    -#define BUFFERED_FLASH_PAGE_BITS		9
    +#define BUFFERED_FLASH_PAGE_BITS	9
     #define BUFFERED_FLASH_PHY_PAGE_SIZE	(1 << BUFFERED_FLASH_PAGE_BITS)
     #define BUFFERED_FLASH_BYTE_ADDR_MASK	(BUFFERED_FLASH_PHY_PAGE_SIZE-1)
    -#define BUFFERED_FLASH_PAGE_SIZE		264
    -#define BUFFERED_FLASH_TOTAL_SIZE		0x21000
    +#define BUFFERED_FLASH_PAGE_SIZE	264
    +#define BUFFERED_FLASH_TOTAL_SIZE	0x21000
     
    -#define SAIFUN_FLASH_PAGE_BITS			8
    -#define SAIFUN_FLASH_PHY_PAGE_SIZE		(1 << SAIFUN_FLASH_PAGE_BITS)
    -#define SAIFUN_FLASH_BYTE_ADDR_MASK		(SAIFUN_FLASH_PHY_PAGE_SIZE-1)
    -#define SAIFUN_FLASH_PAGE_SIZE			256
    +#define SAIFUN_FLASH_PAGE_BITS		8
    +#define SAIFUN_FLASH_PHY_PAGE_SIZE	(1 << SAIFUN_FLASH_PAGE_BITS)
    +#define SAIFUN_FLASH_BYTE_ADDR_MASK	(SAIFUN_FLASH_PHY_PAGE_SIZE-1)
    +#define SAIFUN_FLASH_PAGE_SIZE		256
     #define SAIFUN_FLASH_BASE_TOTAL_SIZE	65536
     
    -#define ST_MICRO_FLASH_PAGE_BITS		8
    +#define ST_MICRO_FLASH_PAGE_BITS	8
     #define ST_MICRO_FLASH_PHY_PAGE_SIZE	(1 << ST_MICRO_FLASH_PAGE_BITS)
     #define ST_MICRO_FLASH_BYTE_ADDR_MASK	(ST_MICRO_FLASH_PHY_PAGE_SIZE-1)
    -#define ST_MICRO_FLASH_PAGE_SIZE		256
    +#define ST_MICRO_FLASH_PAGE_SIZE	256
     #define ST_MICRO_FLASH_BASE_TOTAL_SIZE	65536
     
    -#define BCM5709_FLASH_PAGE_BITS			8
    -#define BCM5709_FLASH_PHY_PAGE_SIZE		(1 << BCM5709_FLASH_PAGE_BITS)
    +#define BCM5709_FLASH_PAGE_BITS		8
    +#define BCM5709_FLASH_PHY_PAGE_SIZE	(1 << BCM5709_FLASH_PAGE_BITS)
     #define BCM5709_FLASH_BYTE_ADDR_MASK	(BCM5709_FLASH_PHY_PAGE_SIZE-1)
    -#define BCM5709_FLASH_PAGE_SIZE			256
    +#define BCM5709_FLASH_PAGE_SIZE		256
     
    -#define NVRAM_TIMEOUT_COUNT				30000
    -#define BCE_FLASHDESC_MAX				64
    +#define NVRAM_TIMEOUT_COUNT		30000
    +#define BCE_FLASHDESC_MAX		64
     
    -#define FLASH_STRAP_MASK				(BCE_NVM_CFG1_FLASH_MODE | \
    -										 BCE_NVM_CFG1_BUFFER_MODE  | \
    -										 BCE_NVM_CFG1_PROTECT_MODE | \
    -										 BCE_NVM_CFG1_FLASH_SIZE)
    +#define FLASH_STRAP_MASK	(BCE_NVM_CFG1_FLASH_MODE |	\
    +    BCE_NVM_CFG1_BUFFER_MODE | BCE_NVM_CFG1_PROTECT_MODE |	\
    +    BCE_NVM_CFG1_FLASH_SIZE)
     
    -#define FLASH_BACKUP_STRAP_MASK			(0xf << 26)
    +#define FLASH_BACKUP_STRAP_MASK		(0xf << 26)
     
     struct flash_spec {
     	u32 strapping;
    @@ -716,7 +713,7 @@ struct flash_spec {
     	u32 write1;
     #define BCE_NV_BUFFERED		0x00000001
     #define BCE_NV_TRANSLATE	0x00000002
    -#define BCE_NV_WREN			0x00000004
    +#define BCE_NV_WREN		0x00000004
     	u32 flags;
     	u32 page_bits;
     	u32 page_size;
    @@ -746,50 +743,52 @@ struct flash_spec {
      * running and there won't be any firmware-driver synchronization during a
      * driver reset.
      */
    -#define FW_ACK_TIME_OUT_MS                  1000
    +#define FW_ACK_TIME_OUT_MS			1000
     
     
    -#define BCE_DRV_RESET_SIGNATURE				0x00000000
    +#define BCE_DRV_RESET_SIGNATURE			0x00000000
     #define BCE_DRV_RESET_SIGNATURE_MAGIC		0x4841564b /* HAVK */
     
    -#define BCE_DRV_MB							0x00000004
    -#define BCE_DRV_MSG_CODE			 		0xff000000
    -#define BCE_DRV_MSG_CODE_RESET			 	0x01000000
    -#define BCE_DRV_MSG_CODE_UNLOAD		 		0x02000000
    -#define BCE_DRV_MSG_CODE_SHUTDOWN		 	0x03000000
    +#define BCE_DRV_MB				0x00000004
    +#define BCE_DRV_MSG_CODE	 		0xff000000
    +#define BCE_DRV_MSG_CODE_RESET		 	0x01000000
    +#define BCE_DRV_MSG_CODE_UNLOAD			0x02000000
    +#define BCE_DRV_MSG_CODE_SHUTDOWN	 	0x03000000
     #define BCE_DRV_MSG_CODE_SUSPEND_WOL		0x04000000
    -#define BCE_DRV_MSG_CODE_FW_TIMEOUT		 	0x05000000
    -#define BCE_DRV_MSG_CODE_PULSE			 	0x06000000
    -#define BCE_DRV_MSG_CODE_DIAG			 	0x07000000
    +#define BCE_DRV_MSG_CODE_FW_TIMEOUT	 	0x05000000
    +#define BCE_DRV_MSG_CODE_PULSE		 	0x06000000
    +#define BCE_DRV_MSG_CODE_DIAG		 	0x07000000
     #define BCE_DRV_MSG_CODE_SUSPEND_NO_WOL	 	0x09000000
     #define BCE_DRV_MSG_CODE_UNLOAD_LNK_DN		0x0b000000
     #define BCE_DRV_MSG_CODE_CMD_SET_LINK		0x10000000
     
    -#define BCE_DRV_MSG_DATA			 		0x00ff0000
    -#define BCE_DRV_MSG_DATA_WAIT0			 	0x00010000
    -#define BCE_DRV_MSG_DATA_WAIT1				0x00020000
    -#define BCE_DRV_MSG_DATA_WAIT2				0x00030000
    -#define BCE_DRV_MSG_DATA_WAIT3				0x00040000
    +#define BCE_DRV_MSG_DATA			0x00ff0000
    +#define BCE_DRV_MSG_DATA_WAIT0		 	0x00010000
    +#define BCE_DRV_MSG_DATA_WAIT1			0x00020000
    +#define BCE_DRV_MSG_DATA_WAIT2			0x00030000
    +#define BCE_DRV_MSG_DATA_WAIT3			0x00040000
     
    -#define BCE_DRV_MSG_SEQ						0x0000ffff
    +#define BCE_DRV_MSG_SEQ				0x0000ffff
     
     #define BCE_FW_MB				0x00000008
     #define BCE_FW_MSG_ACK				 0x0000ffff
     #define BCE_FW_MSG_STATUS_MASK			 0x00ff0000
     #define BCE_FW_MSG_STATUS_OK			 0x00000000
    +#define BCE_FW_MSG_STATUS_INVALID_ARGS		 0x00010000
    +#define BCE_FW_MSG_STATUS_DRV_PRSNT		 0x00020000
     #define BCE_FW_MSG_STATUS_FAILURE		 0x00ff0000
     
    -#define BCE_LINK_STATUS			0x0000000c
    +#define BCE_LINK_STATUS				0x0000000c
     #define BCE_LINK_STATUS_INIT_VALUE		 0xffffffff
    -#define BCE_LINK_STATUS_LINK_UP		 0x1
    +#define BCE_LINK_STATUS_LINK_UP		 	 0x1
     #define BCE_LINK_STATUS_LINK_DOWN		 0x0
     #define BCE_LINK_STATUS_SPEED_MASK		 0x1e
     #define BCE_LINK_STATUS_AN_INCOMPLETE		 (0<<1)
     #define BCE_LINK_STATUS_10HALF			 (1<<1)
     #define BCE_LINK_STATUS_10FULL			 (2<<1)
    -#define BCE_LINK_STATUS_100HALF		 (3<<1)
    +#define BCE_LINK_STATUS_100HALF			 (3<<1)
     #define BCE_LINK_STATUS_100BASE_T4		 (4<<1)
    -#define BCE_LINK_STATUS_100FULL		 (5<<1)
    +#define BCE_LINK_STATUS_100FULL			 (5<<1)
     #define BCE_LINK_STATUS_1000HALF		 (6<<1)
     #define BCE_LINK_STATUS_1000FULL		 (7<<1)
     #define BCE_LINK_STATUS_2500HALF		 (8<<1)
    @@ -846,9 +845,9 @@ struct flash_spec {
     #define BCE_SHARED_HW_CFG_PHY_COPPER		 0
     #define BCE_SHARED_HW_CFG_PHY_FIBER		 0x2
     #define BCE_SHARED_HW_CFG_PHY_2_5G		 0x20
    -#define BCE_SHARED_HW_CFG_PHY_BACKPLANE	 0x40
    +#define BCE_SHARED_HW_CFG_PHY_BACKPLANE		 0x40
     #define BCE_SHARED_HW_CFG_LED_MODE_SHIFT_BITS	 8
    -#define BCE_SHARED_HW_CFG_LED_MODE_MASK	 0x300
    +#define BCE_SHARED_HW_CFG_LED_MODE_MASK		 0x300
     #define BCE_SHARED_HW_CFG_LED_MODE_MAC		 0
     #define BCE_SHARED_HW_CFG_LED_MODE_GPHY1	 0x100
     #define BCE_SHARED_HW_CFG_LED_MODE_GPHY2	 0x200
    @@ -863,27 +862,27 @@ struct flash_spec {
     
     #define BCE_PORT_HW_CFG_MAC_LOWER		0x00000054
     #define BCE_PORT_HW_CFG_CONFIG			0x00000058
    -#define BCE_PORT_HW_CFG_CFG_TXCTL3_MASK	 0x0000ffff
    +#define BCE_PORT_HW_CFG_CFG_TXCTL3_MASK		 0x0000ffff
     #define BCE_PORT_HW_CFG_CFG_DFLT_LINK_MASK	 0x001f0000
     #define BCE_PORT_HW_CFG_CFG_DFLT_LINK_AN	 0x00000000
     #define BCE_PORT_HW_CFG_CFG_DFLT_LINK_1G	 0x00030000
     #define BCE_PORT_HW_CFG_CFG_DFLT_LINK_2_5G	 0x00040000
     
    -#define BCE_PORT_HW_CFG_IMD_MAC_A_UPPER	0x00000068
    -#define BCE_PORT_HW_CFG_IMD_MAC_A_LOWER	0x0000006c
    -#define BCE_PORT_HW_CFG_IMD_MAC_B_UPPER	0x00000070
    -#define BCE_PORT_HW_CFG_IMD_MAC_B_LOWER	0x00000074
    -#define BCE_PORT_HW_CFG_ISCSI_MAC_UPPER	0x00000078
    -#define BCE_PORT_HW_CFG_ISCSI_MAC_LOWER	0x0000007c
    +#define BCE_PORT_HW_CFG_IMD_MAC_A_UPPER		0x00000068
    +#define BCE_PORT_HW_CFG_IMD_MAC_A_LOWER		0x0000006c
    +#define BCE_PORT_HW_CFG_IMD_MAC_B_UPPER		0x00000070
    +#define BCE_PORT_HW_CFG_IMD_MAC_B_LOWER		0x00000074
    +#define BCE_PORT_HW_CFG_ISCSI_MAC_UPPER		0x00000078
    +#define BCE_PORT_HW_CFG_ISCSI_MAC_LOWER		0x0000007c
     
     #define BCE_DEV_INFO_PER_PORT_HW_CONFIG2	0x000000b4
     
    -#define BCE_DEV_INFO_FORMAT_REV		0x000000c4
    +#define BCE_DEV_INFO_FORMAT_REV			0x000000c4
     #define BCE_DEV_INFO_FORMAT_REV_MASK		 0xff000000
     #define BCE_DEV_INFO_FORMAT_REV_ID		 ('A' << 24)
     
     #define BCE_SHARED_FEATURE			0x000000c8
    -#define BCE_SHARED_FEATURE_MASK		 0xffffffff
    +#define BCE_SHARED_FEATURE_MASK			 0xffffffff
     
     #define BCE_PORT_FEATURE			0x000000d8
     #define BCE_PORT2_FEATURE			0x00000014c
    @@ -891,12 +890,12 @@ struct flash_spec {
     #define BCE_PORT_FEATURE_MBA_ENABLED		 0x02000000
     #define BCE_PORT_FEATURE_ASF_ENABLED		 0x04000000
     #define BCE_PORT_FEATURE_IMD_ENABLED		 0x08000000
    -#define BCE_PORT_FEATURE_BAR1_SIZE_MASK	 0xf
    +#define BCE_PORT_FEATURE_BAR1_SIZE_MASK		 0xf
     #define BCE_PORT_FEATURE_BAR1_SIZE_DISABLED	 0x0
     #define BCE_PORT_FEATURE_BAR1_SIZE_64K		 0x1
    -#define BCE_PORT_FEATURE_BAR1_SIZE_128K	 0x2
    -#define BCE_PORT_FEATURE_BAR1_SIZE_256K	 0x3
    -#define BCE_PORT_FEATURE_BAR1_SIZE_512K	 0x4
    +#define BCE_PORT_FEATURE_BAR1_SIZE_128K		 0x2
    +#define BCE_PORT_FEATURE_BAR1_SIZE_256K		 0x3
    +#define BCE_PORT_FEATURE_BAR1_SIZE_512K		 0x4
     #define BCE_PORT_FEATURE_BAR1_SIZE_1M		 0x5
     #define BCE_PORT_FEATURE_BAR1_SIZE_2M		 0x6
     #define BCE_PORT_FEATURE_BAR1_SIZE_4M		 0x7
    @@ -904,9 +903,9 @@ struct flash_spec {
     #define BCE_PORT_FEATURE_BAR1_SIZE_16M		 0x9
     #define BCE_PORT_FEATURE_BAR1_SIZE_32M		 0xa
     #define BCE_PORT_FEATURE_BAR1_SIZE_64M		 0xb
    -#define BCE_PORT_FEATURE_BAR1_SIZE_128M	 0xc
    -#define BCE_PORT_FEATURE_BAR1_SIZE_256M	 0xd
    -#define BCE_PORT_FEATURE_BAR1_SIZE_512M	 0xe
    +#define BCE_PORT_FEATURE_BAR1_SIZE_128M		 0xc
    +#define BCE_PORT_FEATURE_BAR1_SIZE_256M		 0xd
    +#define BCE_PORT_FEATURE_BAR1_SIZE_512M		 0xe
     #define BCE_PORT_FEATURE_BAR1_SIZE_1G		 0xf
     
     #define BCE_PORT_FEATURE_WOL			0xdc
    @@ -921,12 +920,12 @@ struct flash_spec {
     #define BCE_PORT_FEATURE_WOL_LINK_SPEED_AUTONEG	 0
     #define BCE_PORT_FEATURE_WOL_LINK_SPEED_10HALF	 1
     #define BCE_PORT_FEATURE_WOL_LINK_SPEED_10FULL	 2
    -#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100HALF 3
    -#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100FULL 4
    +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100HALF	 3
    +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100FULL	 4
     #define BCE_PORT_FEATURE_WOL_LINK_SPEED_1000HALF	 5
     #define BCE_PORT_FEATURE_WOL_LINK_SPEED_1000FULL	 6
     #define BCE_PORT_FEATURE_WOL_AUTONEG_ADVERTISE_1000	 0x40
    -#define BCE_PORT_FEATURE_WOL_RESERVED_PAUSE_CAP 0x400
    +#define BCE_PORT_FEATURE_WOL_RESERVED_PAUSE_CAP	 0x400
     #define BCE_PORT_FEATURE_WOL_RESERVED_ASYM_PAUSE_CAP	 0x800
     
     #define BCE_PORT_FEATURE_MBA			0xe0
    @@ -943,9 +942,9 @@ struct flash_spec {
     #define BCE_PORT_FEATURE_MBA_LINK_SPEED_10FULL	 0x8
     #define BCE_PORT_FEATURE_MBA_LINK_SPEED_100HALF	 0xc
     #define BCE_PORT_FEATURE_MBA_LINK_SPEED_100FULL	 0x10
    -#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000HALF	 0x14
    -#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000FULL	 0x18
    -#define BCE_PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE	 0x40
    +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000HALF 0x14
    +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000FULL 0x18
    +#define BCE_PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE 0x40
     #define BCE_PORT_FEATURE_MBA_HOTKEY_CTRL_S	 0
     #define BCE_PORT_FEATURE_MBA_HOTKEY_CTRL_B	 0x80
     #define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT_BITS	 8
    @@ -985,36 +984,37 @@ struct flash_spec {
     #define BCE_PORT_FEATURE_MBA_VLAN_TAG_MASK	 0xffff
     #define BCE_PORT_FEATURE_MBA_VLAN_ENABLE	 0x10000
     
    -#define BCE_MFW_VER_PTR			0x00000014c
    +#define BCE_MFW_VER_PTR				0x00000014c
     
    -#define BCE_BC_STATE_RESET_TYPE		0x000001c0
    +#define BCE_BC_STATE_RESET_TYPE			0x000001c0
     #define BCE_BC_STATE_RESET_TYPE_SIG		 0x00005254
     #define BCE_BC_STATE_RESET_TYPE_SIG_MASK	 0x0000ffff
    -#define BCE_BC_STATE_RESET_TYPE_NONE	 (BCE_BC_STATE_RESET_TYPE_SIG | \
    -					  0x00010000)
    -#define BCE_BC_STATE_RESET_TYPE_PCI	 (BCE_BC_STATE_RESET_TYPE_SIG | \
    -					  0x00020000)
    -#define BCE_BC_STATE_RESET_TYPE_VAUX	 (BCE_BC_STATE_RESET_TYPE_SIG | \
    -					  0x00030000)
    -#define BCE_BC_STATE_RESET_TYPE_DRV_MASK	 DRV_MSG_CODE
    -#define BCE_BC_STATE_RESET_TYPE_DRV_RESET (BCE_BC_STATE_RESET_TYPE_SIG | \
    -					    DRV_MSG_CODE_RESET)
    -#define BCE_BC_STATE_RESET_TYPE_DRV_UNLOAD (BCE_BC_STATE_RESET_TYPE_SIG | \
    -					     DRV_MSG_CODE_UNLOAD)
    -#define BCE_BC_STATE_RESET_TYPE_DRV_SHUTDOWN (BCE_BC_STATE_RESET_TYPE_SIG | \
    -					       DRV_MSG_CODE_SHUTDOWN)
    -#define BCE_BC_STATE_RESET_TYPE_DRV_WOL (BCE_BC_STATE_RESET_TYPE_SIG | \
    -					  DRV_MSG_CODE_WOL)
    -#define BCE_BC_STATE_RESET_TYPE_DRV_DIAG (BCE_BC_STATE_RESET_TYPE_SIG | \
    -					   DRV_MSG_CODE_DIAG)
    -#define BCE_BC_STATE_RESET_TYPE_VALUE(msg) (BCE_BC_STATE_RESET_TYPE_SIG | \
    -					     (msg))
     
    -#define BCE_BC_RESET_TYPE				0x000001c0
    +#define BCE_BC_STATE_RESET_TYPE_NONE 			\
    +    (BCE_BC_STATE_RESET_TYPE_SIG | 0x00010000)
    +#define BCE_BC_STATE_RESET_TYPE_PCI			\
    +    (BCE_BC_STATE_RESET_TYPE_SIG | 0x00020000)
    +#define BCE_BC_STATE_RESET_TYPE_VAUX			\
    +    (BCE_BC_STATE_RESET_TYPE_SIG | 0x00030000)
    +#define BCE_BC_STATE_RESET_TYPE_DRV_MASK DRV_MSG_CODE
    +#define BCE_BC_STATE_RESET_TYPE_DRV_RESET		\
    +    (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_RESET)
    +#define BCE_BC_STATE_RESET_TYPE_DRV_UNLOAD		\
    +    (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_UNLOAD)
    +#define BCE_BC_STATE_RESET_TYPE_DRV_SHUTDOWN		\
    +    (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_SHUTDOWN)
    +#define BCE_BC_STATE_RESET_TYPE_DRV_WOL			\
    +    (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_WOL)
    +#define BCE_BC_STATE_RESET_TYPE_DRV_DIAG		\
    +    (BCE_BC_STATE_RESET_TYPE_SIG | DRV_MSG_CODE_DIAG)
    +#define BCE_BC_STATE_RESET_TYPE_VALUE(msg)		\
    +    (BCE_BC_STATE_RESET_TYPE_SIG | (msg))
     
    -#define BCE_BC_STATE					0x000001c4
    +#define BCE_BC_RESET_TYPE			0x000001c0
    +
    +#define BCE_BC_STATE				0x000001c4
     #define BCE_BC_STATE_ERR_MASK			0x0000ff00
    -#define BCE_BC_STATE_SIGN				0x42530000
    +#define BCE_BC_STATE_SIGN			0x42530000
     #define BCE_BC_STATE_SIGN_MASK			0xffff0000
     #define BCE_BC_STATE_BC1_START			(BCE_BC_STATE_SIGN | 0x1)
     #define BCE_BC_STATE_GET_NVM_CFG1		(BCE_BC_STATE_SIGN | 0x2)
    @@ -1034,24 +1034,49 @@ struct flash_spec {
     #define BCE_BC_STATE_RT_SET_WOL			(BCE_BC_STATE_SIGN | 0x87)
     #define BCE_BC_STATE_RT_OTHER_FW		(BCE_BC_STATE_SIGN | 0x88)
     #define BCE_BC_STATE_RT_GOING_D3		(BCE_BC_STATE_SIGN | 0x89)
    -#define BCE_BC_STATE_ERR_BAD_VERSION	(BCE_BC_STATE_SIGN | 0x0100)
    -#define BCE_BC_STATE_ERR_BAD_BC2_CRC	(BCE_BC_STATE_SIGN | 0x0200)
    +#define BCE_BC_STATE_ERR_BAD_VERSION		(BCE_BC_STATE_SIGN | 0x0100)
    +#define BCE_BC_STATE_ERR_BAD_BC2_CRC		(BCE_BC_STATE_SIGN | 0x0200)
     #define BCE_BC_STATE_ERR_BC1_LOOP		(BCE_BC_STATE_SIGN | 0x0300)
    -#define BCE_BC_STATE_ERR_UNKNOWN_CMD	(BCE_BC_STATE_SIGN | 0x0400)
    +#define BCE_BC_STATE_ERR_UNKNOWN_CMD		(BCE_BC_STATE_SIGN | 0x0400)
     #define BCE_BC_STATE_ERR_DRV_DEAD		(BCE_BC_STATE_SIGN | 0x0500)
     #define BCE_BC_STATE_ERR_NO_RXP			(BCE_BC_STATE_SIGN | 0x0600)
    -#define BCE_BC_STATE_ERR_TOO_MANY_RBUF	(BCE_BC_STATE_SIGN | 0x0700)
    +#define BCE_BC_STATE_ERR_TOO_MANY_RBUF		(BCE_BC_STATE_SIGN | 0x0700)
     
    -#define BCE_BC_STATE_CONDITION	        0x000001c8
    -#define BCE_CONDITION_MFW_RUN_UNKNOWN   0x00000000
    -#define BCE_CONDITION_MFW_RUN_IPMI	    0x00002000
    -#define BCE_CONDITION_MFW_RUN_UMP	    0x00004000
    -#define BCE_CONDITION_MFW_RUN_NCSI	    0x00006000
    +#define BCE_BC_STATE_CONDITION			0x000001c8
    +#define BCE_CONDITION_INIT_POR			0x00000001
    +#define BCE_CONDITION_INIT_VAUX_AVAIL		0x00000002
    +#define BCE_CONDITION_INIT_PCI_AVAIL		0x00000004
    +#define BCE_CONDITION_INIT_PCI_RESET		0x00000008
    +#define BCE_CONDITION_INIT_HD_RESET		0x00000010 /* 5709/16 only */
    +#define BCE_CONDITION_DRV_PRESENT		0x00000100
    +#define BCE_CONDITION_LOW_POWER_LINK		0x00000200
    +#define BCE_CONDITION_CORE_RST_OCCURRED		0x00000400 /* 5709/16 only */
    +#define BCE_CONDITION_UNUSED			0x00000800
    +#define BCE_CONDITION_BUSY_EXPROM		0x00001000 /* 5706/08 only */
    +
    +#define BCE_CONDITION_MFW_RUN_UNKNOWN		0x00000000
    +#define BCE_CONDITION_MFW_RUN_IPMI		0x00002000
    +#define BCE_CONDITION_MFW_RUN_UMP		0x00004000
    +#define BCE_CONDITION_MFW_RUN_NCSI		0x00006000
     #define BCE_CONDITION_MFW_RUN_NONE		0x0000e000
     #define BCE_CONDITION_MFW_RUN_MASK		0x0000e000
     
    -#define BCE_BC_STATE_DEBUG_CMD					0x1dc
    -#define BCE_BC_STATE_BC_DBG_CMD_SIGNATURE		0x42440000
    +/* 5709/16 only */
    +#define BCE_CONDITION_PM_STATE_MASK		0x00030000
    +#define BCE_CONDITION_PM_STATE_FULL		0x00030000
    +#define BCE_CONDITION_PM_STATE_PREP		0x00020000
    +#define BCE_CONDITION_PM_STATE_UNPREP		0x00010000
    +#define BCE_CONDITION_PM_RESERVED		0x00000000
    +
    +/* 5709/16 only */
    +#define BCE_CONDITION_RXMODE_KEEP_VLAN		0x00040000
    +#define BCE_CONDITION_DRV_WOL_ENABLED		0x00080000
    +#define BCE_CONDITION_PORT_DISABLED		0x00100000
    +#define BCE_CONDITION_DRV_MAYBE_OUT		0x00200000
    +#define BCE_CONDITION_DPFW_DEAD			0x00400000
    +
    +#define BCE_BC_STATE_DEBUG_CMD			0x000001dc
    +#define BCE_BC_STATE_BC_DBG_CMD_SIGNATURE	0x42440000
     #define BCE_BC_STATE_BC_DBG_CMD_SIGNATURE_MASK	0xffff0000
     #define BCE_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK	0xffff
     #define BCE_BC_STATE_BC_DBG_CMD_LOOP_INFINITE	0xffff
    @@ -1067,40 +1092,51 @@ struct flash_spec {
     /****************************************************************************/
     /* Convenience definitions.                                                 */
     /****************************************************************************/
    -#define BCE_PRINTF(fmt, args...)	device_printf(sc->bce_dev, fmt, ##args)
    +#define BCE_PRINTF(fmt, args...)			\
    +    device_printf(sc->bce_dev, fmt, ##args)
     
    -#define	BCE_LOCK_INIT(_sc, _name)	mtx_init(&(_sc)->bce_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
    -#define	BCE_LOCK(_sc)				mtx_lock(&(_sc)->bce_mtx)
    +#define	BCE_LOCK_INIT(_sc, _name)			\
    +    mtx_init(&(_sc)->bce_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
    +#define	BCE_LOCK(_sc)			mtx_lock(&(_sc)->bce_mtx)
     #define	BCE_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->bce_mtx, MA_OWNED)
    -#define	BCE_UNLOCK(_sc)				mtx_unlock(&(_sc)->bce_mtx)
    +#define	BCE_UNLOCK(_sc)			mtx_unlock(&(_sc)->bce_mtx)
     #define	BCE_LOCK_DESTROY(_sc)		mtx_destroy(&(_sc)->bce_mtx)
     
     #ifdef BCE_DEBUG
    -#define REG_WR(sc, offset, val)		bce_reg_wr(sc, offset, val)
    -#define REG_WR16(sc, offset, val)	bce_reg_wr16(sc, offset, val)
    -#define REG_RD(sc, offset)			bce_reg_rd(sc, offset)
    +#define	REG_WR(sc, offset, val)		bce_reg_wr(sc, offset, val)
    +#define	REG_WR16(sc, offset, val)	bce_reg_wr16(sc, offset, val)
    +#define	REG_RD(sc, offset)		bce_reg_rd(sc, offset)
     #else
    -#define REG_WR(sc, offset, val)		bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val)
    -#define REG_WR16(sc, offset, val)	bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val)
    -#define REG_RD(sc, offset)		 	bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset)
    +#define	REG_WR(sc, offset, val)				\
    +    bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val)
    +#define	REG_WR16(sc, offset, val)			\
    +    bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val)
    +#define	REG_RD(sc, offset)	 			\
    +    bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset)
     #endif
     
    -#define REG_RD_IND(sc, offset)		bce_reg_rd_ind(sc, offset)
    -#define REG_WR_IND(sc, offset, val)	bce_reg_wr_ind(sc, offset, val)
    -#define CTX_WR(sc, cid_addr, offset, val)	bce_ctx_wr(sc, cid_addr, offset, val)
    -#define CTX_RD(sc, cid_addr, offset)		bce_ctx_rd(sc, cid_addr, offset)
    -#define BCE_SETBIT(sc, reg, x)		REG_WR(sc, reg, (REG_RD(sc, reg) | (x)))
    -#define BCE_CLRBIT(sc, reg, x)		REG_WR(sc, reg, (REG_RD(sc, reg) & ~(x)))
    -#define PCI_SETBIT(dev, reg, x, s)	pci_write_config(dev, reg, (pci_read_config(dev, reg, s) | (x)), s)
    -#define PCI_CLRBIT(dev, reg, x, s)	pci_write_config(dev, reg, (pci_read_config(dev, reg, s) & ~(x)), s)
    +#define	REG_RD_IND(sc, offset)		bce_reg_rd_ind(sc, offset)
    +#define	REG_WR_IND(sc, offset, val)	bce_reg_wr_ind(sc, offset, val)
    +#define	CTX_WR(sc, cid_addr, offset, val)bce_ctx_wr(sc, cid_addr, offset, val)
    +#define	CTX_RD(sc, cid_addr, offset)	bce_ctx_rd(sc, cid_addr, offset)
    +
    +#define	BCE_SETBIT(sc, reg, x)				\
    +    REG_WR(sc, reg, (REG_RD(sc, reg) | (x)))
    +#define	BCE_CLRBIT(sc, reg, x)				\
    +    REG_WR(sc, reg, (REG_RD(sc, reg) & ~(x)))
    +#define	PCI_SETBIT(dev, reg, x, s)			\
    +    pci_write_config(dev, reg, (pci_read_config(dev, reg, s) | (x)), s)
    +#define	PCI_CLRBIT(dev, reg, x, s)			\
    +    pci_write_config(dev, reg, (pci_read_config(dev, reg, s) & ~(x)), s)
    +
    +#define	BCE_STATS(x)			(u_long) stats->stat_ ## x ## _lo
     
    -#define BCE_STATS(x)			(u_long) stats->stat_ ## x ## _lo
     #if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
    -#define BCE_ADDR_LO(y)			((u64) (y) & 0xFFFFFFFF)
    -#define BCE_ADDR_HI(y)			((u64) (y) >> 32)
    +#define	BCE_ADDR_LO(y)			((u64) (y) & 0xFFFFFFFF)
    +#define	BCE_ADDR_HI(y)			((u64) (y) >> 32)
     #else
    -#define BCE_ADDR_LO(y)			((u32)y)
    -#define BCE_ADDR_HI(y)			(0)
    +#define	BCE_ADDR_LO(y)			((u32)y)
    +#define	BCE_ADDR_HI(y)			(0)
     #endif
     
     
    @@ -1166,7 +1202,7 @@ struct status_block {
     		#define STATUS_ATTN_BITS_TX_PATCHUP_ABORT	(1L<<6)
     		#define STATUS_ATTN_BITS_TX_ASSEMBLER_ABORT	(1L<<7)
     		#define STATUS_ATTN_BITS_RX_PARSER_MAC_ABORT	(1L<<8)
    -		#define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT	(1L<<9)
    +		#define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT (1L<<9)
     		#define STATUS_ATTN_BITS_RX_MBUF_ABORT		(1L<<10)
     		#define STATUS_ATTN_BITS_RX_LOOKUP_ABORT	(1L<<11)
     		#define STATUS_ATTN_BITS_RX_PROCESSOR_ABORT	(1L<<12)
    @@ -1369,90 +1405,90 @@ struct l2_fhdr {
     };
     
     #define BCE_L2FHDR_PRINTFB	\
    -	"\20"					\
    -	"\40UDP_XSUM_ERR"		\
    -	"\37b30"				\
    -	"\36b29"				\
    -	"\35TCP_XSUM_ERR"		\
    -	"\34b27"				\
    -	"\33b26"				\
    -	"\32b25"				\
    -	"\31b24"				\
    -	"\30b23"				\
    -	"\27b22"				\
    -	"\26GIANT_ERR"			\
    -	"\25SHORT_ERR"			\
    -	"\24ALIGN_ERR"			\
    -	"\23PHY_ERR"			\
    -	"\22CRC_ERR"			\
    -	"\21SPLIT"				\
    -	"\20UDP"				\
    -	"\17TCP"				\
    -	"\16IP"					\
    -	"\15b12"				\
    -	"\14b11"				\
    -	"\13b10"				\
    -	"\12b09"				\
    -	"\11RSS"				\
    -	"\10SNAP"				\
    -	"\07VLAN"				\
    -	"\06P4"					\
    -	"\05P3"					\
    +	"\20"			\
    +	"\40UDP_XSUM_ERR"	\
    +	"\37b30"		\
    +	"\36b29"		\
    +	"\35TCP_XSUM_ERR"	\
    +	"\34b27"		\
    +	"\33b26"		\
    +	"\32b25"		\
    +	"\31b24"		\
    +	"\30b23"		\
    +	"\27b22"		\
    +	"\26GIANT_ERR"		\
    +	"\25SHORT_ERR"		\
    +	"\24ALIGN_ERR"		\
    +	"\23PHY_ERR"		\
    +	"\22CRC_ERR"		\
    +	"\21SPLIT"		\
    +	"\20UDP"		\
    +	"\17TCP"		\
    +	"\16IP"			\
    +	"\15b12"		\
    +	"\14b11"		\
    +	"\13b10"		\
    +	"\12b09"		\
    +	"\11RSS"		\
    +	"\10SNAP"		\
    +	"\07VLAN"		\
    +	"\06P4"			\
    +	"\05P3"			\
     	"\04P2"
     
     
     /*
      *  l2_tx_context definition (5706 and 5708)
      */
    -#define BCE_L2CTX_TX_TYPE			   		0x00000000
    -#define BCE_L2CTX_TX_TYPE_SIZE_L2	   		((0xc0/0x20)<<16)
    -#define BCE_L2CTX_TX_TYPE_TYPE		   		(0xf<<28)
    -#define BCE_L2CTX_TX_TYPE_TYPE_EMPTY   		(0<<28)
    -#define BCE_L2CTX_TX_TYPE_TYPE_L2	   		(1<<28)
    +#define BCE_L2CTX_TX_TYPE			0x00000000
    +#define BCE_L2CTX_TX_TYPE_SIZE_L2		((0xc0/0x20)<<16)
    +#define BCE_L2CTX_TX_TYPE_TYPE			(0xf<<28)
    +#define BCE_L2CTX_TX_TYPE_TYPE_EMPTY		(0<<28)
    +#define BCE_L2CTX_TX_TYPE_TYPE_L2		(1<<28)
     
    -#define BCE_L2CTX_TX_HOST_BIDX	 			0x00000088
    -#define BCE_L2CTX_TX_EST_NBD		   		0x00000088
    -#define BCE_L2CTX_TX_CMD_TYPE		   		0x00000088
    -#define BCE_L2CTX_TX_CMD_TYPE_TYPE	   		(0xf<<24)
    -#define BCE_L2CTX_TX_CMD_TYPE_TYPE_L2  		(0<<24)
    -#define BCE_L2CTX_TX_CMD_TYPE_TYPE_TCP 		(1<<24)
    +#define BCE_L2CTX_TX_HOST_BIDX			0x00000088
    +#define BCE_L2CTX_TX_EST_NBD			0x00000088
    +#define BCE_L2CTX_TX_CMD_TYPE			0x00000088
    +#define BCE_L2CTX_TX_CMD_TYPE_TYPE		(0xf<<24)
    +#define BCE_L2CTX_TX_CMD_TYPE_TYPE_L2		(0<<24)
    +#define BCE_L2CTX_TX_CMD_TYPE_TYPE_TCP		(1<<24)
     
    -#define BCE_L2CTX_TX_HOST_BSEQ				0x00000090
    -#define BCE_L2CTX_TX_TSCH_BSEQ		   		0x00000094
    -#define BCE_L2CTX_TX_TBDR_BSEQ		   		0x00000098
    -#define BCE_L2CTX_TX_TBDR_BOFF		   		0x0000009c
    -#define BCE_L2CTX_TX_TBDR_BIDX		   		0x0000009c
    -#define BCE_L2CTX_TX_TBDR_BHADDR_HI			0x000000a0
    -#define BCE_L2CTX_TX_TBDR_BHADDR_LO			0x000000a4
    -#define BCE_L2CTX_TX_TXP_BOFF		   		0x000000a8
    -#define BCE_L2CTX_TX_TXP_BIDX		   		0x000000a8
    -#define BCE_L2CTX_TX_TXP_BSEQ		   		0x000000ac
    +#define BCE_L2CTX_TX_HOST_BSEQ			0x00000090
    +#define BCE_L2CTX_TX_TSCH_BSEQ			0x00000094
    +#define BCE_L2CTX_TX_TBDR_BSEQ			0x00000098
    +#define BCE_L2CTX_TX_TBDR_BOFF			0x0000009c
    +#define BCE_L2CTX_TX_TBDR_BIDX			0x0000009c
    +#define BCE_L2CTX_TX_TBDR_BHADDR_HI		0x000000a0
    +#define BCE_L2CTX_TX_TBDR_BHADDR_LO		0x000000a4
    +#define BCE_L2CTX_TX_TXP_BOFF			0x000000a8
    +#define BCE_L2CTX_TX_TXP_BIDX			0x000000a8
    +#define BCE_L2CTX_TX_TXP_BSEQ			0x000000ac
     
     /*
      *  l2_tx_context definition (5709 and 5716)
      */
    -#define BCE_L2CTX_TX_TYPE_XI		   		0x00000080
    -#define BCE_L2CTX_TX_TYPE_SIZE_L2_XI   		((0xc0/0x20)<<16)
    -#define BCE_L2CTX_TX_TYPE_TYPE_XI	   		(0xf<<28)
    +#define BCE_L2CTX_TX_TYPE_XI			0x00000080
    +#define BCE_L2CTX_TX_TYPE_SIZE_L2_XI		((0xc0/0x20)<<16)
    +#define BCE_L2CTX_TX_TYPE_TYPE_XI		(0xf<<28)
     #define BCE_L2CTX_TX_TYPE_TYPE_EMPTY_XI		(0<<28)
    -#define BCE_L2CTX_TX_TYPE_TYPE_L2_XI   		(1<<28)
    -										
    -#define BCE_L2CTX_TX_CMD_TYPE_XI	   		0x00000240
    -#define BCE_L2CTX_TX_CMD_TYPE_TYPE_XI  		(0xf<<24)
    +#define BCE_L2CTX_TX_TYPE_TYPE_L2_XI		(1<<28)
    +
    +#define BCE_L2CTX_TX_CMD_TYPE_XI		0x00000240
    +#define BCE_L2CTX_TX_CMD_TYPE_TYPE_XI		(0xf<<24)
     #define BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI	(0<<24)
     #define BCE_L2CTX_TX_CMD_TYPE_TYPE_TCP_XI	(1<<24)
     
    -#define BCE_L2CTX_TX_HOST_BIDX_XI	   		0x00000240
    -#define BCE_L2CTX_TX_HOST_BSEQ_XI			0x00000248
    -#define BCE_L2CTX_TX_TBDR_BHADDR_HI_XI 		0x00000258
    -#define BCE_L2CTX_TX_TBDR_BHADDR_LO_XI	 	0x0000025c
    +#define BCE_L2CTX_TX_HOST_BIDX_XI		0x00000240
    +#define BCE_L2CTX_TX_HOST_BSEQ_XI		0x00000248
    +#define BCE_L2CTX_TX_TBDR_BHADDR_HI_XI		0x00000258
    +#define BCE_L2CTX_TX_TBDR_BHADDR_LO_XI		0x0000025c
     
     
     /*
      *  l2_rx_context definition (5706, 5708, 5709, and 5716)
      */
    -#define BCE_L2CTX_RX_WATER_MARK				0x00000000
    -#define BCE_L2CTX_RX_LO_WATER_MARK_SHIFT 	0
    +#define BCE_L2CTX_RX_WATER_MARK			0x00000000
    +#define BCE_L2CTX_RX_LO_WATER_MARK_SHIFT	0
     #define BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT	32
     #define BCE_L2CTX_RX_LO_WATER_MARK_SCALE	4
     #define BCE_L2CTX_RX_LO_WATER_MARK_DIS		0
    @@ -1460,52 +1496,53 @@ struct l2_fhdr {
     #define BCE_L2CTX_RX_HI_WATER_MARK_SCALE	16
     #define BCE_L2CTX_RX_WATER_MARKS_MSK		0x000000ff
     
    -#define BCE_L2CTX_RX_BD_PRE_READ			0x00000000
    +#define BCE_L2CTX_RX_BD_PRE_READ		0x00000000
     #define BCE_L2CTX_RX_BD_PRE_READ_SHIFT		8
     
    -#define BCE_L2CTX_RX_CTX_SIZE				0x00000000
    -#define BCE_L2CTX_RX_CTX_SIZE_SHIFT			16
    -#define BCE_L2CTX_RX_CTX_TYPE_SIZE_L2		((0x20/20)<> BCM_PAGE_BITS)
    +#define BCM_PAGES(x)	((((x) + BCM_PAGE_SIZE - 1) & \
    +    BCM_PAGE_MASK) >> BCM_PAGE_BITS)
     
     /*
      * Page count must remain a power of 2 for all
    @@ -6177,8 +6159,7 @@ struct l2_fhdr {
     
     /* Advance to the next tx_bd, skipping any next page pointers. */
     #define NEXT_TX_BD(x) (((x) & USABLE_TX_BD_PER_PAGE) ==	\
    -		(USABLE_TX_BD_PER_PAGE - 1)) ?					  	\
    -		(x) + 2 : (x) + 1
    +    (USABLE_TX_BD_PER_PAGE - 1)) ? (x) + 2 : (x) + 1
     
     #define TX_CHAIN_IDX(x) ((x) & MAX_TX_BD)
     
    @@ -6198,8 +6179,7 @@ struct l2_fhdr {
     
     /* Advance to the next rx_bd, skipping any next page pointers. */
     #define NEXT_RX_BD(x) (((x) & USABLE_RX_BD_PER_PAGE) ==	\
    -		(USABLE_RX_BD_PER_PAGE - 1)) ?					\
    -		(x) + 2 : (x) + 1
    +    (USABLE_RX_BD_PER_PAGE - 1)) ? (x) + 2 : (x) + 1
     
     #define RX_CHAIN_IDX(x) ((x) & MAX_RX_BD)
     
    @@ -6220,8 +6200,7 @@ struct l2_fhdr {
     
     /* Advance to the next pg_bd, skipping any next page pointers. */
     #define NEXT_PG_BD(x) (((x) & USABLE_PG_BD_PER_PAGE) ==	\
    -		(USABLE_PG_BD_PER_PAGE - 1)) ?					\
    -		(x) + 2 : (x) + 1
    +    (USABLE_PG_BD_PER_PAGE - 1)) ? (x) + 2 : (x) + 1
     
     #define PG_CHAIN_IDX(x) ((x) & MAX_PG_BD)
     
    @@ -6233,29 +6212,29 @@ struct l2_fhdr {
     #define CTX_INIT_RETRY_COUNT        10
     
     /* Context size. */
    -#define CTX_SHIFT                   7
    -#define CTX_SIZE                    (1 << CTX_SHIFT)
    -#define CTX_MASK                    (CTX_SIZE - 1)
    -#define GET_CID_ADDR(_cid)          ((_cid) << CTX_SHIFT)
    -#define GET_CID(_cid_addr)          ((_cid_addr) >> CTX_SHIFT)
    +#define CTX_SHIFT		7
    +#define CTX_SIZE		(1 << CTX_SHIFT)
    +#define CTX_MASK		(CTX_SIZE - 1)
    +#define GET_CID_ADDR(_cid)	((_cid) << CTX_SHIFT)
    +#define GET_CID(_cid_addr)	((_cid_addr) >> CTX_SHIFT)
     
    -#define PHY_CTX_SHIFT               6
    -#define PHY_CTX_SIZE                (1 << PHY_CTX_SHIFT)
    -#define PHY_CTX_MASK                (PHY_CTX_SIZE - 1)
    -#define GET_PCID_ADDR(_pcid)        ((_pcid) << PHY_CTX_SHIFT)
    -#define GET_PCID(_pcid_addr)        ((_pcid_addr) >> PHY_CTX_SHIFT)
    +#define PHY_CTX_SHIFT		6
    +#define PHY_CTX_SIZE		(1 << PHY_CTX_SHIFT)
    +#define PHY_CTX_MASK		(PHY_CTX_SIZE - 1)
    +#define GET_PCID_ADDR(_pcid)	((_pcid) << PHY_CTX_SHIFT)
    +#define GET_PCID(_pcid_addr)	((_pcid_addr) >> PHY_CTX_SHIFT)
     
    -#define MB_KERNEL_CTX_SHIFT         8
    -#define MB_KERNEL_CTX_SIZE          (1 << MB_KERNEL_CTX_SHIFT)
    -#define MB_KERNEL_CTX_MASK          (MB_KERNEL_CTX_SIZE - 1)
    -#define MB_GET_CID_ADDR(_cid)       (0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT))
    +#define MB_KERNEL_CTX_SHIFT	8
    +#define MB_KERNEL_CTX_SIZE	(1 << MB_KERNEL_CTX_SHIFT)
    +#define MB_KERNEL_CTX_MASK	(MB_KERNEL_CTX_SIZE - 1)
    +#define MB_GET_CID_ADDR(_cid)	(0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT))
     
    -#define MAX_CID_CNT                 0x4000
    -#define MAX_CID_ADDR                (GET_CID_ADDR(MAX_CID_CNT))
    -#define INVALID_CID_ADDR            0xffffffff
    +#define MAX_CID_CNT		0x4000
    +#define MAX_CID_ADDR		(GET_CID_ADDR(MAX_CID_CNT))
    +#define INVALID_CID_ADDR	0xffffffff
     
    -#define TX_CID		16
    -#define RX_CID		0
    +#define TX_CID			16
    +#define RX_CID			0
     
     /****************************************************************************/
     /* BCE Processor Firmwware Load Definitions                                 */
    @@ -6318,25 +6297,27 @@ struct fw_info {
     	u32 *rodata;
     };
     
    -#define RV2P_PROC1                              0
    -#define RV2P_PROC2                              1
    +#define RV2P_PROC1		0
    +#define RV2P_PROC2		1
     
    -#define BCE_MIREG(x)	((x & 0x1F) << 16)
    -#define BCE_MIPHY(x)	((x & 0x1F) << 21)
    -#define BCE_PHY_TIMEOUT	50
    +#define BCE_MIREG(x)		((x & 0x1F) << 16)
    +#define BCE_MIPHY(x)		((x & 0x1F) << 21)
    +#define BCE_PHY_TIMEOUT		50
     
    -#define BCE_NVRAM_SIZE 					0x200
    -#define BCE_NVRAM_MAGIC					0x669955aa
    -#define BCE_CRC32_RESIDUAL				0xdebb20e3
    +#define BCE_NVRAM_SIZE		0x200
    +#define BCE_NVRAM_MAGIC		0x669955aa
    +#define BCE_CRC32_RESIDUAL	0xdebb20e3
     
    -#define BCE_TX_TIMEOUT					5
    +#define BCE_TX_TIMEOUT		5
     
    -#define BCE_MAX_SEGMENTS				32
    -#define BCE_TSO_MAX_SIZE				65536
    -#define BCE_TSO_MAX_SEG_SIZE			4096
    +#define BCE_MAX_SEGMENTS	32
    +#define BCE_TSO_MAX_SIZE	65536
    +#define BCE_TSO_MAX_SEG_SIZE	4096
     
    -#define BCE_DMA_ALIGN		 			8
    -#define BCE_DMA_BOUNDARY				0
    +#define BCE_DMA_ALIGN		8
    +#define BCE_DMA_BOUNDARY	0
    +
    +#define BCE_MAX_CONTEXT		4
     
     /* The BCM5708 has a problem with addresses greater that 40bits. */
     /* Handle the sizing issue in an architecture agnostic fashion.  */
    @@ -6358,22 +6339,23 @@ struct fw_info {
     #endif
     
     #if __FreeBSD_version < 700000
    -#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
    -							IFCAP_HWCSUM | IFCAP_JUMBO_MTU)
    +#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | 			\
    +    IFCAP_VLAN_HWTAGGING | IFCAP_HWCSUM | IFCAP_JUMBO_MTU)
     #else
    -#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
    -							IFCAP_HWCSUM | IFCAP_JUMBO_MTU | IFCAP_VLAN_HWCSUM)
    +#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU |			\
    +    IFCAP_VLAN_HWTAGGING | IFCAP_HWCSUM |			\
    +    IFCAP_JUMBO_MTU | IFCAP_VLAN_HWCSUM)
     #endif
     
    -#define BCE_MIN_MTU						60
    -#define BCE_MIN_ETHER_MTU				64
    +#define BCE_MIN_MTU			60
    +#define BCE_MIN_ETHER_MTU		64
     
    -#define BCE_MAX_STD_MTU					1500
    -#define BCE_MAX_STD_ETHER_MTU			1518
    -#define BCE_MAX_STD_ETHER_MTU_VLAN		1522
    +#define BCE_MAX_STD_MTU			1500
    +#define BCE_MAX_STD_ETHER_MTU		1518
    +#define BCE_MAX_STD_ETHER_MTU_VLAN	1522
     
    -#define BCE_MAX_JUMBO_MTU			 	9000
    -#define BCE_MAX_JUMBO_ETHER_MTU			9018
    +#define BCE_MAX_JUMBO_MTU		9000
    +#define BCE_MAX_JUMBO_ETHER_MTU		9018
     #define BCE_MAX_JUMBO_ETHER_MTU_VLAN 	9022
     
     // #define BCE_MAX_MTU		ETHER_MAX_LEN_JUMBO + ETHER_VLAN_ENCAP_LEN	/* 9022 */
    @@ -6382,155 +6364,206 @@ struct fw_info {
     /* BCE Device State Data Structure                                          */
     /****************************************************************************/
     
    -#define BCE_STATUS_BLK_SZ		sizeof(struct status_block)
    -#define BCE_STATS_BLK_SZ		sizeof(struct statistics_block)
    +#define BCE_STATUS_BLK_SZ	sizeof(struct status_block)
    +#define BCE_STATS_BLK_SZ	sizeof(struct statistics_block)
     #define BCE_TX_CHAIN_PAGE_SZ	BCM_PAGE_SIZE
     #define BCE_RX_CHAIN_PAGE_SZ	BCM_PAGE_SIZE
     #define BCE_PG_CHAIN_PAGE_SZ	BCM_PAGE_SIZE
     
     struct bce_softc
     {
    -	/* MUST start with ifnet pointer (see definition of miibus_statchg()) */
    -	struct ifnet		*bce_ifp;			/* Interface info */
    -	device_t			bce_dev;			/* Parent device handle */
    -	u_int8_t			bce_unit;			/* Interface number */
    -	struct resource		*bce_res_mem;  		/* Device resource handle */
    -	struct ifmedia		bce_ifmedia;		/* TBI media info */
    -	bus_space_tag_t		bce_btag;			/* Device bus tag */
    -	bus_space_handle_t	bce_bhandle;		/* Device bus handle */
    -	vm_offset_t			bce_vhandle;		/* Device virtual memory handle */
    -	struct resource		*bce_res_irq;		/* IRQ Resource Handle */
    -	struct mtx			bce_mtx;			/* Mutex */
    +	/* Interface info */
    +	struct ifnet		*bce_ifp;
    +
    +	/* Parent device handle */
    +	device_t		bce_dev;
    +
    +	/* Interface number */
    +	u_int8_t		bce_unit;
    +
    +	/* Device resource handle */
    +	struct resource		*bce_res_mem;
    +
    +	/* TBI media info */
    +	struct ifmedia		bce_ifmedia;
    +
    +	/* Device bus tag */
    +	bus_space_tag_t		bce_btag;
    +
    +	/* Device bus handle */
    +	bus_space_handle_t	bce_bhandle;
    +
    +	/* Device virtual memory handle */
    +	vm_offset_t		bce_vhandle;
    +
    +	/* IRQ Resource Handle */
    +	struct resource		*bce_res_irq;
    +
    +	struct mtx		bce_mtx;
     
     	/* Interrupt handler. */
     	driver_intr_t		*bce_intr;
    -	void				*bce_intrhand;
    -	int					bce_irq_rid;
    -	int					bce_msi_count;
    +	void *bce_intrhand;
    +	int  bce_irq_rid;
    +	int  bce_msi_count;
     
     	/* ASIC Chip ID. */
    -	u32					bce_chipid;
    +	u32  bce_chipid;
     
     	/* General controller flags. */
    -	u32					bce_flags;
    -#define BCE_PCIX_FLAG				0x00000001
    -#define BCE_PCI_32BIT_FLAG 			0x00000002
    -#define BCE_ONE_TDMA_FLAG			0x00000004		/* Deprecated */
    -#define BCE_NO_WOL_FLAG				0x00000008
    -#define BCE_USING_DAC_FLAG			0x00000010
    -#define BCE_USING_MSI_FLAG 			0x00000020
    -#define BCE_MFW_ENABLE_FLAG			0x00000040
    +	u32  bce_flags;
    +#define BCE_PCIX_FLAG			0x00000001
    +#define BCE_PCI_32BIT_FLAG 		0x00000002
    +#define BCE_RESERVED_FLAG		0x00000004
    +#define BCE_NO_WOL_FLAG			0x00000008
    +#define BCE_USING_DAC_FLAG		0x00000010
    +#define BCE_USING_MSI_FLAG 		0x00000020
    +#define BCE_MFW_ENABLE_FLAG		0x00000040
     #define BCE_ONE_SHOT_MSI_FLAG		0x00000080
    -#define BCE_USING_MSIX_FLAG			0x00000100
    -#define BCE_PCIE_FLAG				0x00000200
    +#define BCE_USING_MSIX_FLAG		0x00000100
    +#define BCE_PCIE_FLAG			0x00000200
     
     	/* Controller capability flags. */
    -	u32								bce_cap_flags;
    +	u32  bce_cap_flags;
     #define BCE_MSI_CAPABLE_FLAG		0x00000001
     #define BCE_MSIX_CAPABLE_FLAG		0x00000002
     #define BCE_PCIE_CAPABLE_FLAG		0x00000004
     #define BCE_PCIX_CAPABLE_FLAG		0x00000008
     
     	/* PHY specific flags. */
    -	u32					bce_phy_flags;
    -#define BCE_PHY_SERDES_FLAG					0x00000001
    -#define BCE_PHY_CRC_FIX_FLAG				0x00000002
    -#define BCE_PHY_PARALLEL_DETECT_FLAG		0x00000004
    -#define BCE_PHY_2_5G_CAPABLE_FLAG			0x00000008
    -#define BCE_PHY_INT_MODE_MASK_FLAG			0x00000300
    -#define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG	0x00000100
    -#define BCE_PHY_INT_MODE_LINK_READY_FLAG	0x00000200
    -#define BCE_PHY_IEEE_CLAUSE_45_FLAG     	0x00000400
    +	u32  bce_phy_flags;
    +#define BCE_PHY_SERDES_FLAG		0x00000001
    +#define BCE_PHY_CRC_FIX_FLAG		0x00000002
    +#define BCE_PHY_PARALLEL_DETECT_FLAG	0x00000004
    +#define BCE_PHY_2_5G_CAPABLE_FLAG	0x00000008
    +#define BCE_PHY_INT_MODE_MASK_FLAG	0x00000300
    +#define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG 0x00000100
    +#define BCE_PHY_INT_MODE_LINK_READY_FLAG 0x00000200
    +#define BCE_PHY_IEEE_CLAUSE_45_FLAG	0x00000400
     
     	/* Values that need to be shared with the PHY driver. */
    -	u32					bce_shared_hw_cfg;
    -	u32					bce_port_hw_cfg;
    +	u32  bce_shared_hw_cfg;
    +	u32  bce_port_hw_cfg;
     
    -	bus_addr_t			max_bus_addr;
    -	u16					bus_speed_mhz;		/* PCI bus speed */
    -	u16					link_width;			/* PCIe link width */
    -	u16					link_speed;			/* PCIe link speed */
    -	struct flash_spec	*bce_flash_info;	/* Flash NVRAM settings */
    -	u32					bce_flash_size;		/* Flash NVRAM size */
    -	u32					bce_shmem_base;		/* Shared Memory base address */
    -	char *				bce_name;			/* Name string */
    +	bus_addr_t max_bus_addr;
    +
    +	/* PCI bus speed */
    +	u16  bus_speed_mhz;
    +
    +	/* PCIe link width */
    +	u16  link_width;
    +
    +	/* PCIe link speed */
    +	u16  link_speed;
    +
    +	/* Flash NVRAM settings */
    +	struct flash_spec *bce_flash_info;
    +
    +	/* Flash NVRAM size */
    +	u32  bce_flash_size;
    +
    +	/* Shared Memory base address */
    +	u32  bce_shmem_base;		
    +
    +	/* Name string */
    +	char * bce_name;
     
     	/* Tracks the version of bootcode firmware. */
    -	char			    bce_bc_ver[32];
    -    char                bce_mfw_ver[32];
    +	char bce_bc_ver[32];
     
    -	/* Tracks the state of the firmware.  0 = Running while any     */
    -	/* other value indicates that the firmware is not responding.   */
    -	u16					bce_fw_timed_out;
    +	/* Tracks the version of management firmware. */
    +	char bce_mfw_ver[32];
     
    -	/* An incrementing sequence used to coordinate messages passed   */
    -	/* from the driver to the firmware.                              */
    -	u16					bce_fw_wr_seq;
    +	/* 
    +	 * Tracks the state of the firmware.  0 = Running while any
    +	 * other value indicates that the firmware is not responding.
    +	 */
    +	u16  bce_fw_timed_out;
     
    -	/* An incrementing sequence used to let the firmware know that   */
    -	/* the driver is still operating.  Without the pulse, management */
    -	/* firmware such as IPMI or UMP will operate in OS absent state. */
    -	u16					bce_fw_drv_pulse_wr_seq;
    +	/* 
    +	 * An incrementing sequence used to coordinate messages passed
    +	 * from the driver to the firmware.
    +	 */ 
    +	u16  bce_fw_wr_seq;
    +
    +	/* 
    +	 * An incrementing sequence used to let the firmware know that
    +	 * the driver is still operating.  Without the pulse, management
    +	 * firmware such as IPMI or UMP will operate in OS absent state.
    +	 */ 
    +	u16  bce_fw_drv_pulse_wr_seq;
    +
    +	/* Tracks whether firmware has lost the driver's pulse. */
    +	u16  bce_drv_cardiac_arrest;
     
     	/* Ethernet MAC address. */
    -	u_char				eaddr[6];
    +	u_char eaddr[6];
     
    -	/* These setting are used by the host coalescing (HC) block to   */
    -	/* to control how often the status block, statistics block and   */
    -	/* interrupts are generated.                                     */
    -	u16					bce_tx_quick_cons_trip_int;
    -	u16					bce_tx_quick_cons_trip;
    -	u16					bce_rx_quick_cons_trip_int;
    -	u16					bce_rx_quick_cons_trip;
    -	u16					bce_comp_prod_trip_int;
    -	u16					bce_comp_prod_trip;
    -	u16					bce_tx_ticks_int;
    -	u16					bce_tx_ticks;
    -	u16					bce_rx_ticks_int;
    -	u16					bce_rx_ticks;
    -	u16					bce_com_ticks_int;
    -	u16					bce_com_ticks;
    -	u16					bce_cmd_ticks_int;
    -	u16					bce_cmd_ticks;
    -	u32					bce_stats_ticks;
    +	/* 
    +	 * These setting are used by the host coalescing (HC) block to
    +	 * to control how often the status block, statistics block and
    +	 * interrupts are generated.
    +	 */ 
    +	u16  bce_tx_quick_cons_trip_int;
    +	u16  bce_tx_quick_cons_trip;
    +	u16  bce_rx_quick_cons_trip_int;
    +	u16  bce_rx_quick_cons_trip;
    +	u16  bce_tx_ticks_int;
    +	u16  bce_tx_ticks;
    +	u16  bce_rx_ticks_int;
    +	u16  bce_rx_ticks;
    +	u32  bce_stats_ticks;
    +
    +	/* ToDo: Can these be removed? */
    +	u16  bce_comp_prod_trip_int;
    +	u16  bce_comp_prod_trip;
    +	u16  bce_com_ticks_int;
    +	u16  bce_com_ticks;
    +	u16  bce_cmd_ticks_int;
    +	u16  bce_cmd_ticks;
     
     	/* The address of the integrated PHY on the MII bus. */
    -	int					bce_phy_addr;
    +	int  bce_phy_addr;
     
     	/* The device handle for the MII bus child device. */
    -	device_t			bce_miibus;
    +	device_t bce_miibus;
     
     	/* Driver maintained TX chain pointers and byte counter. */
    -	u16					rx_prod;
    -	u16					rx_cons;
    -	u32					rx_prod_bseq;	/* Counts the bytes used.  */
    -	u16					tx_prod;
    -	u16					tx_cons;
    -	u32					tx_prod_bseq;	/* Counts the bytes used.  */
    +	u16  rx_prod;
    +	u16  rx_cons;
    +
    +	/* Counts the bytes used in the RX chain. */
    +	u32  rx_prod_bseq;
    +	u16  tx_prod;
    +	u16  tx_cons;
    +
    +	/* Counts the bytes used in the TX chain. */
    +	u32  tx_prod_bseq;
     
     #ifdef BCE_JUMBO_HDRSPLIT
    -	u16					pg_prod;
    -	u16					pg_cons;
    +	u16  pg_prod;
    +	u16  pg_cons;
     #endif
     
    -	int					bce_link;
    -	struct callout		bce_tick_callout;
    -	struct callout		bce_pulse_callout;
    +	int  bce_link_up;
    +	struct callout bce_tick_callout;
    +	struct callout bce_pulse_callout;
     
    -	int watchdog_timer;			/* ticks until chip reset */
    +	/* Ticks until chip reset */
    +	int watchdog_timer;
     
     	/* Frame size and mbuf allocation size for RX frames. */
    -	u32					max_frame_size;
    -	int					rx_bd_mbuf_alloc_size;
    -	int					rx_bd_mbuf_data_len;
    -	int					rx_bd_mbuf_align_pad;
    +	u32  max_frame_size;
    +	int  rx_bd_mbuf_alloc_size;
    +	int  rx_bd_mbuf_data_len;
    +	int  rx_bd_mbuf_align_pad;
     
     #ifdef BCE_JUMBO_HDRSPLIT
    -	int					pg_bd_mbuf_alloc_size;
    +	int  pg_bd_mbuf_alloc_size;
     #endif
     
     	/* Receive mode settings (i.e promiscuous, multicast, etc.). */
    -	u32					rx_mode;
    +	u32  rx_mode;
     
     	/* Bus tag for the bce controller. */
     	bus_dma_tag_t		parent_tag;
    @@ -6539,46 +6572,47 @@ struct bce_softc
     	bus_dma_tag_t		tx_bd_chain_tag;
     	bus_dmamap_t		tx_bd_chain_map[TX_PAGES];
     	struct tx_bd		*tx_bd_chain[TX_PAGES];
    -	bus_addr_t			tx_bd_chain_paddr[TX_PAGES];
    +	bus_addr_t		tx_bd_chain_paddr[TX_PAGES];
     
     	/* H/W maintained RX buffer descriptor chain structure. */
     	bus_dma_tag_t		rx_bd_chain_tag;
     	bus_dmamap_t		rx_bd_chain_map[RX_PAGES];
     	struct rx_bd		*rx_bd_chain[RX_PAGES];
    -	bus_addr_t			rx_bd_chain_paddr[RX_PAGES];
    +	bus_addr_t		rx_bd_chain_paddr[RX_PAGES];
     
     #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];
     	struct rx_bd		*pg_bd_chain[PG_PAGES];
    -	bus_addr_t			pg_bd_chain_paddr[PG_PAGES];
    +	bus_addr_t		pg_bd_chain_paddr[PG_PAGES];
     #endif
     
     	/* H/W maintained status block. */
     	bus_dma_tag_t		status_tag;
     	bus_dmamap_t		status_map;
    -	struct status_block	*status_block;			/* Virtual address */
    -	bus_addr_t			status_block_paddr;		/* Physical address */
    +	struct status_block	*status_block;
    +	bus_addr_t		status_block_paddr;
     
     	/* Driver maintained status block values. */
    -	u16					last_status_idx;
    -	u16					hw_rx_cons;
    -	u16					hw_tx_cons;
    +	u16  last_status_idx;
    +	u16  hw_rx_cons;
    +	u16  hw_tx_cons;
     
     	/* H/W maintained statistics block. */
     	bus_dma_tag_t		stats_tag;
     	bus_dmamap_t		stats_map;
    -	struct statistics_block *stats_block;		/* Virtual address */
    -	bus_addr_t			stats_block_paddr;		/* Physical address */
    +	struct statistics_block *stats_block;
    +	bus_addr_t		stats_block_paddr;
     
     	/* H/W maintained context block. */
    -	int					ctx_pages;
    +	int  ctx_pages;
     	bus_dma_tag_t		ctx_tag;
    -	/* DRC - Fix hard coded value. */
    -	bus_dmamap_t		ctx_map[4];
    -	void				*ctx_block[4];			/* Virtual address */
    -	bus_addr_t			ctx_paddr[4];			/* Physical address */
    +
    +	/* BCM5709/16 use host memory for context. */
    +	bus_dmamap_t		ctx_map[BCE_MAX_CONTEXT];
    +	void			*ctx_block[BCE_MAX_CONTEXT];
    +	bus_addr_t		ctx_paddr[BCE_MAX_CONTEXT];
     
     	/* Bus tag for RX/TX mbufs. */
     	bus_dma_tag_t		rx_mbuf_tag;
    @@ -6590,16 +6624,16 @@ struct bce_softc
     
     	/* S/W maintained mbuf TX chain structure. */
     	bus_dmamap_t		tx_mbuf_map[TOTAL_TX_BD];
    -	struct mbuf			*tx_mbuf_ptr[TOTAL_TX_BD];
    +	struct mbuf		*tx_mbuf_ptr[TOTAL_TX_BD];
     
     	/* S/W maintained mbuf RX chain structure. */
     	bus_dmamap_t		rx_mbuf_map[TOTAL_RX_BD];
    -	struct mbuf			*rx_mbuf_ptr[TOTAL_RX_BD];
    +	struct mbuf		*rx_mbuf_ptr[TOTAL_RX_BD];
     
     #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];
    +	struct mbuf		*pg_mbuf_ptr[TOTAL_PG_BD];
     #endif
     
     	/* Track the number of buffer descriptors in use. */
    @@ -6674,26 +6708,28 @@ struct bce_softc
     	u32 com_no_buffers;
     
     	/* Recoverable failure counters. */
    -	u32	mbuf_alloc_failed_count;
    +	u32 mbuf_alloc_failed_count;
     	u32 fragmented_mbuf_count;
    -	u32	unexpected_attention_count;
    +	u32 unexpected_attention_count;
     	u32 l2fhdr_error_count;
     	u32 dma_map_addr_tx_failed_count;
     	u32 dma_map_addr_rx_failed_count;
     
    +	/* Host coalescing block command register */
    +	u32 hc_command;
    +
    +	/* Bootcode state */
    +	u32 bc_state;
    +
     #ifdef BCE_DEBUG
     	/* Simulated recoverable failure counters. */
    -	u32	mbuf_alloc_failed_sim_count;
    +	u32 mbuf_alloc_failed_sim_count;
     	u32 unexpected_attention_sim_count;
     	u32 l2fhdr_error_sim_count;
    -	u32	dma_map_addr_failed_sim_count;
    -#endif
    +	u32 dma_map_addr_failed_sim_count;
     
    -	u32	hc_command;
    -
    -#ifdef BCE_DEBUG
     	/* Track the number of enqueued mbufs. */
    -	int	debug_tx_mbuf_alloc;
    +	int debug_tx_mbuf_alloc;
     	int debug_rx_mbuf_alloc;
     
     #ifdef BCE_JUMBO_HDRSPLIT
    @@ -6705,23 +6741,35 @@ struct bce_softc
     	u32 interrupts_handled;
     	u32 rx_interrupts;
     	u32 tx_interrupts;
    +	u32 phy_interrupts;
     
     	/* Track interrupt time (25MHz clock). */
     	u64 rx_intr_time;
     	u64 tx_intr_time;
     
    -	u32	rx_low_watermark;			/* Lowest number of rx_bd's free. */
    -	u32 rx_empty_count;				/* Number of times the RX chain was empty. */
    +	/* Lowest number of rx_bd's free. */
    +	u32 rx_low_watermark;
    +
    +	/* Number of times the RX chain was empty. */
    +	u32 rx_empty_count;
     
     #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. */
    +
    +	/* Lowest number of pages free. */
    +	u32 pg_low_watermark;
    +
    +	/* Number of times the page chain was empty. */
    +	u32 pg_empty_count;
     #endif
     
    -	u32 tx_hi_watermark;			/* Greatest number of tx_bd's used. */
    -	u32	tx_full_count;				/* Number of times the TX chain was full. */
    +	/* Greatest number of tx_bd's used. */
    +	u32 tx_hi_watermark;
     
    -	u32	requested_tso_frames;		/* Number of TSO frames enqueued. */
    +	/* Number of times the TX chain was full. */
    +	u32 tx_full_count;
    +
    +	/* Number of TSO frames enqueued. */
    +	u32 requested_tso_frames;
     #endif
     };
     
    
    From 2d2fef10c56341ba16b05cc72adc5b15113cab3d Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Fri, 16 Apr 2010 01:39:30 +0000
    Subject: [PATCH 1969/2592] MFC: r206061 Add SAVENAME to the cn_flags for all
     cases in the experimental NFS server for the CREATE cn_nameiop where
     SAVESTART isn't set. I was not aware that this needed to be done by the
     caller until recently.
    
    ---
     sys/fs/nfsserver/nfs_nfsdserv.c | 8 +++++---
     1 file changed, 5 insertions(+), 3 deletions(-)
    
    diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
    index e56610b660e..9a362873e72 100644
    --- a/sys/fs/nfsserver/nfs_nfsdserv.c
    +++ b/sys/fs/nfsserver/nfs_nfsdserv.c
    @@ -1086,7 +1086,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram,
     		case NFFIFO:
     			break;
     		case NFDIR:
    -			cnflags = LOCKPARENT;
    +			cnflags = (LOCKPARENT | SAVENAME);
     			break;
     		default:
     			nd->nd_repstat = NFSERR_BADTYPE;
    @@ -1549,7 +1549,8 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
     				NFSVOPUNLOCK(dp, 0, p);
     		}
     	}
    -	NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, LOCKPARENT);
    +	NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
    +	    LOCKPARENT | SAVENAME);
     	if (!nd->nd_repstat) {
     		nfsvno_setpathbuf(&named, &bufp, &hashp);
     		error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
    @@ -1743,7 +1744,8 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int isdgram,
     		nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft);
     		return (0);
     	}
    -	NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, LOCKPARENT);
    +	NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
    +	    LOCKPARENT | SAVENAME);
     	nfsvno_setpathbuf(&named, &bufp, &hashp);
     	error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
     	if (error) {
    
    From 499a07ef68bcbd2f6cd3055bf80a502d14799e92 Mon Sep 17 00:00:00 2001
    From: Kevin Lo 
    Date: Fri, 16 Apr 2010 01:53:19 +0000
    Subject: [PATCH 1970/2592] MFC r206544
    
    The Quanta Q101 modem has a different type of cdrom driver disk,
    add the product id and use a standard scsi eject.
    
    Reviewed by:	thompsa
    ---
     sys/dev/usb/serial/u3g.c | 1 +
     sys/dev/usb/usbdevs      | 1 +
     2 files changed, 2 insertions(+)
    
    diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
    index 0d218d548bf..7ac1bd3310d 100644
    --- a/sys/dev/usb/serial/u3g.c
    +++ b/sys/dev/usb/serial/u3g.c
    @@ -501,6 +501,7 @@ static const struct usb_device_id u3g_devs[] = {
     	U3G_DEV(OPTION, GTICON322, U3GINIT_REZERO),
     	U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GINIT_ZTESTOR),
     	U3G_DEV(QUALCOMMINC, ZTE_STOR2, U3GINIT_SCSIEJECT),
    +	U3G_DEV(QUANTA, Q101_STOR, U3GINIT_SCSIEJECT),
     	U3G_DEV(SIERRA, TRUINSTALL, U3GINIT_SIERRA),
     #undef	U3G_DEV
     };
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index 312beabb1a4..b4baf300e5a 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -2526,6 +2526,7 @@ product QUALCOMMINC E2003	0x2003	3G modem
     /* Quanta products */
     product QUANTA RW6815_1		0x00ce	HP iPAQ rw6815
     product QUANTA RT3070		0x0304	RT3070
    +product QUANTA Q101_STOR	0x1000	USB Q101 Storage
     product QUANTA Q101		0xea02	HSDPA modem
     product QUANTA Q111		0xea03	HSDPA modem
     product QUANTA GLX		0xea04	HSDPA modem
    
    From e83c1c9d1e14d1c52473e224991ddc21827a7314 Mon Sep 17 00:00:00 2001
    From: Kevin Lo 
    Date: Fri, 16 Apr 2010 01:54:47 +0000
    Subject: [PATCH 1971/2592] MFC r206595
    
    Eliminate duplicate comment
    ---
     sys/dev/usb/usbdevs | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
    index b4baf300e5a..5790ddbdf7a 100644
    --- a/sys/dev/usb/usbdevs
    +++ b/sys/dev/usb/usbdevs
    @@ -2522,7 +2522,6 @@ product QUALCOMMINC E0086	0x0086	3G modem
     product QUALCOMMINC E2002	0x2002	3G modem
     product QUALCOMMINC E2003	0x2003	3G modem
     
    -/* Quanta products */
     /* Quanta products */
     product QUANTA RW6815_1		0x00ce	HP iPAQ rw6815
     product QUANTA RT3070		0x0304	RT3070
    
    From 4e76f29635e29e63a35b65e947a1d87264e0da5c Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Fri, 16 Apr 2010 02:16:58 +0000
    Subject: [PATCH 1972/2592] MFC: r206063 For the experimental NFS server, add a
     call to free the lookup path buffer for one case where it was missing when
     doing mkdir. This could have conceivably resulted in a leak of a buffer, but
     a leak was never observed during testing, so I suspect it would have occurred
     rarely, if ever, in practice.
    
    ---
     sys/fs/nfsserver/nfs_nfsdport.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
    index 79f04c0f350..8faddfaf3c0 100644
    --- a/sys/fs/nfsserver/nfs_nfsdport.c
    +++ b/sys/fs/nfsserver/nfs_nfsdport.c
    @@ -869,6 +869,7 @@ nfsvno_mkdir(struct nameidata *ndp, struct nfsvattr *nvap, uid_t saved_uid,
     		else
     			vput(ndp->ni_dvp);
     		vrele(ndp->ni_vp);
    +		nfsvno_relpathbuf(ndp);
     		return (EEXIST);
     	}
     	error = VOP_MKDIR(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd,
    
    From bbf7989245a6eeb68e5585e82e7895bd5a81176b Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Fri, 16 Apr 2010 08:32:08 +0000
    Subject: [PATCH 1973/2592] MFC r206546: Remove XXX comment. Add another
     comment, describing why f_vnode assignment is useful.
    
    ---
     sys/kern/vfs_syscalls.c | 7 ++++++-
     1 file changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
    index 2e4c7cfba0c..84f4be45352 100644
    --- a/sys/kern/vfs_syscalls.c
    +++ b/sys/kern/vfs_syscalls.c
    @@ -1124,7 +1124,12 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
     	NDFREE(&nd, NDF_ONLY_PNBUF);
     	vp = nd.ni_vp;
     
    -	fp->f_vnode = vp;	/* XXX Does devfs need this? */
    +	/*
    +	 * Store the vnode, for any f_type. Typically, the vnode use
    +	 * count is decremented by direct call to vn_closefile() for
    +	 * files that switched type in the cdevsw fdopen() method.
    +	 */
    +	fp->f_vnode = vp;
     	/*
     	 * If the file wasn't claimed by devfs bind it to the normal
     	 * vnode operations here.
    
    From 3dd8c32d14999e0de88dd64c05aba3c1aaaf831c Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Fri, 16 Apr 2010 09:08:19 +0000
    Subject: [PATCH 1974/2592] MFC r206420:  Setup the correct RX/TX chainmask
     when we play with the antenna  settings.
    
    Sponsored by:	iXsystems, inc
    ---
     sys/dev/ath/ath_hal/ar5416/ar9285_attach.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c b/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c
    index 946133a396f..ef8c955595d 100644
    --- a/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c
    +++ b/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c
    @@ -378,8 +378,8 @@ ar9285SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
     	case HAL_ANT_VARIABLE:
     		/* Restore original chainmask settings */
     		/* XXX */
    -		ahp->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK;
    -		ahp->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK;
    +		ahp->ah_tx_chainmask = AR9285_DEFAULT_TXCHAINMASK;
    +		ahp->ah_rx_chainmask = AR9285_DEFAULT_RXCHAINMASK;
     		break;
     	}
     	return AH_TRUE;
    
    From c8d050b52af345810cea28ad00b9ae3048935b30 Mon Sep 17 00:00:00 2001
    From: Fabien Thomas 
    Date: Fri, 16 Apr 2010 15:43:24 +0000
    Subject: [PATCH 1975/2592] MFC r206089, r206684:
    
    - Support for uncore counting events: one fixed PMC with the uncore
       domain clock, 8 programmable PMC.
    - Westmere based CPU (Xeon 5600, Corei7 980X) support.
    - New man pages with events list for core and uncore.
    - Updated Corei7 events with Intel 253669-033US December 2009 doc.
      There is some removed events in the documentation, they have been
      kept in the code but documented in the man page as obsolete.
    - Offcore response events can be setup with rsp token.
    
    Sponsored by: NETASQ
    ---
     sys/amd64/include/pmc_mdep.h |   11 +-
     sys/conf/files.amd64         |    1 +
     sys/conf/files.i386          |    1 +
     sys/conf/files.pc98          |    1 +
     sys/dev/hwpmc/hwpmc_core.c   | 1023 ++++++++++-------
     sys/dev/hwpmc/hwpmc_core.h   |   15 +-
     sys/dev/hwpmc/hwpmc_intel.c  |   41 +-
     sys/dev/hwpmc/hwpmc_uncore.c | 1121 ++++++++++++++++++
     sys/dev/hwpmc/hwpmc_uncore.h |  120 ++
     sys/dev/hwpmc/pmc_events.h   | 2100 +++++++++++++++++++++++++---------
     sys/i386/include/pmc_mdep.h  |   11 +-
     sys/modules/hwpmc/Makefile   |    4 +-
     sys/sys/pmc.h                |   15 +-
     13 files changed, 3490 insertions(+), 974 deletions(-)
     create mode 100644 sys/dev/hwpmc/hwpmc_uncore.c
     create mode 100644 sys/dev/hwpmc/hwpmc_uncore.h
    
    diff --git a/sys/amd64/include/pmc_mdep.h b/sys/amd64/include/pmc_mdep.h
    index f233a510d3c..4f164852d3c 100644
    --- a/sys/amd64/include/pmc_mdep.h
    +++ b/sys/amd64/include/pmc_mdep.h
    @@ -43,17 +43,20 @@ struct pmc_mdep;
     #include 
     #include 
     #include 
    +#include 
     
     /*
      * Intel processors implementing V2 and later of the Intel performance
      * measurement architecture have PMCs of the following classes: TSC,
    - * IAF and IAP.
    + * IAF, IAP, UCF and UCP.
      */
     #define	PMC_MDEP_CLASS_INDEX_TSC	0
     #define	PMC_MDEP_CLASS_INDEX_K8		1
     #define	PMC_MDEP_CLASS_INDEX_P4		1
     #define	PMC_MDEP_CLASS_INDEX_IAP	1
     #define	PMC_MDEP_CLASS_INDEX_IAF	2
    +#define	PMC_MDEP_CLASS_INDEX_UCP	3
    +#define	PMC_MDEP_CLASS_INDEX_UCF	4
     
     /*
      * On the amd64 platform we support the following PMCs.
    @@ -63,12 +66,16 @@ struct pmc_mdep;
      * PIV		Intel P4/HTT and P4/EMT64
      * IAP		Intel Core/Core2/Atom CPUs in 64 bits mode.
      * IAF		Intel fixed-function PMCs in Core2 and later CPUs.
    + * UCP		Intel Uncore programmable PMCs.
    + * UCF		Intel Uncore fixed-function PMCs.
      */
     
     union pmc_md_op_pmcallocate  {
     	struct pmc_md_amd_op_pmcallocate	pm_amd;
     	struct pmc_md_iaf_op_pmcallocate	pm_iaf;
     	struct pmc_md_iap_op_pmcallocate	pm_iap;
    +	struct pmc_md_ucf_op_pmcallocate	pm_ucf;
    +	struct pmc_md_ucp_op_pmcallocate	pm_ucp;
     	struct pmc_md_p4_op_pmcallocate		pm_p4;
     	uint64_t				__pad[4];
     };
    @@ -83,6 +90,8 @@ union pmc_md_pmc {
     	struct pmc_md_amd_pmc	pm_amd;
     	struct pmc_md_iaf_pmc	pm_iaf;
     	struct pmc_md_iap_pmc	pm_iap;
    +	struct pmc_md_ucf_pmc	pm_ucf;
    +	struct pmc_md_ucp_pmc	pm_ucp;
     	struct pmc_md_p4_pmc	pm_p4;
     };
     
    diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
    index 2457abba0aa..6d503a45981 100644
    --- a/sys/conf/files.amd64
    +++ b/sys/conf/files.amd64
    @@ -205,6 +205,7 @@ dev/hptrr/hptrr_config.c	optional	hptrr
     dev/hwpmc/hwpmc_amd.c		optional	hwpmc
     dev/hwpmc/hwpmc_intel.c		optional	hwpmc
     dev/hwpmc/hwpmc_core.c		optional	hwpmc
    +dev/hwpmc/hwpmc_uncore.c	optional	hwpmc
     dev/hwpmc/hwpmc_piv.c		optional	hwpmc
     dev/hwpmc/hwpmc_tsc.c		optional	hwpmc
     dev/hwpmc/hwpmc_x86.c		optional	hwpmc
    diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
    index 4df00d767e7..eb9fbe8bc39 100644
    --- a/sys/conf/files.i386
    +++ b/sys/conf/files.i386
    @@ -179,6 +179,7 @@ dev/hptrr/hptrr_config.c	optional hptrr
     dev/hwpmc/hwpmc_amd.c		optional hwpmc
     dev/hwpmc/hwpmc_intel.c		optional hwpmc
     dev/hwpmc/hwpmc_core.c		optional hwpmc
    +dev/hwpmc/hwpmc_uncore.c	optional hwpmc
     dev/hwpmc/hwpmc_pentium.c	optional hwpmc
     dev/hwpmc/hwpmc_piv.c		optional hwpmc
     dev/hwpmc/hwpmc_ppro.c		optional hwpmc
    diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
    index b4e171dfdc1..465153cad4d 100644
    --- a/sys/conf/files.pc98
    +++ b/sys/conf/files.pc98
    @@ -99,6 +99,7 @@ dev/fe/if_fe_cbus.c		optional fe isa
     dev/hwpmc/hwpmc_amd.c		optional hwpmc
     dev/hwpmc/hwpmc_intel.c		optional hwpmc
     dev/hwpmc/hwpmc_core.c		optional hwpmc
    +dev/hwpmc/hwpmc_uncore.c	optional hwpmc
     dev/hwpmc/hwpmc_pentium.c	optional hwpmc
     dev/hwpmc/hwpmc_piv.c		optional hwpmc
     dev/hwpmc/hwpmc_ppro.c		optional hwpmc
    diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
    index 43a49143fc3..e7de09915b3 100644
    --- a/sys/dev/hwpmc/hwpmc_core.c
    +++ b/sys/dev/hwpmc/hwpmc_core.c
    @@ -534,10 +534,12 @@ struct iap_event_descr {
     #define	IAP_F_CC2E	(1 << 2)	/* CPU: Core2 Extreme only */
     #define	IAP_F_CA	(1 << 3)	/* CPU: Atom */
     #define	IAP_F_I7	(1 << 4)	/* CPU: Core i7 */
    -#define	IAP_F_FM	(1 << 5)	/* Fixed mask */
    +#define	IAP_F_I7O	(1 << 4)	/* CPU: Core i7 (old) */
    +#define	IAP_F_WM	(1 << 5)	/* CPU: Westmere */
    +#define	IAP_F_FM	(1 << 6)	/* Fixed mask */
     
    -#define	IAP_F_ALLCPUS						\
    -    (IAP_F_CC | IAP_F_CC2 | IAP_F_CC2E | IAP_F_CA | IAP_F_I7)
    +#define	IAP_F_ALLCPUSCORE2					\
    +    (IAP_F_CC | IAP_F_CC2 | IAP_F_CC2E | IAP_F_CA)
     
     /* Sub fields of UMASK that this event supports. */
     #define	IAP_M_CORE		(1 << 0) /* Core specificity */
    @@ -570,151 +572,319 @@ static struct iap_event_descr iap_events[] = {
     	.iap_flags = (FLAGS)						\
     	}
     
    +    IAPDESCR(02H_01H, 0x02, 0x01, IAP_F_FM | IAP_F_I7O),
         IAPDESCR(02H_81H, 0x02, 0x81, IAP_F_FM | IAP_F_CA),
     
         IAPDESCR(03H_00H, 0x03, 0x00, IAP_F_FM | IAP_F_CC),
    -    IAPDESCR(03H_02H, 0x03, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    -    IAPDESCR(03H_04H, 0x03, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(03H_01H, 0x03, 0x01, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(03H_02H, 0x03, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_WM),
    +    IAPDESCR(03H_04H, 0x03, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
         IAPDESCR(03H_08H, 0x03, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(03H_10H, 0x03, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(03H_20H, 0x03, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(04H_00H, 0x04, 0x00, IAP_F_FM | IAP_F_CC),
    -    IAPDESCR(04H_01H, 0x04, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(04H_01H, 0x04, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
         IAPDESCR(04H_02H, 0x04, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    +    IAPDESCR(04H_07H, 0x04, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
         IAPDESCR(04H_08H, 0x04, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(05H_00H, 0x05, 0x00, IAP_F_FM | IAP_F_CC),
    +    IAPDESCR(05H_01H, 0x05, 0x01, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(05H_02H, 0x05, 0x02, IAP_F_FM | IAP_F_I7O | IAP_F_WM),
    +    IAPDESCR(05H_03H, 0x05, 0x03, IAP_F_FM | IAP_F_I7O),
     
    -    IAPDESCR(06H_00H, 0x06, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(06H_00H, 0x06, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2 |
    +	IAP_F_CC2E | IAP_F_CA),
    +    IAPDESCR(06H_01H, 0x06, 0x01, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(06H_02H, 0x06, 0x02, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(06H_04H, 0x06, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(06H_08H, 0x06, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(06H_0FH, 0x06, 0x0F, IAP_F_FM | IAP_F_I7O),
     
         IAPDESCR(07H_00H, 0x07, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
    -    IAPDESCR(07H_01H, 0x07, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(07H_02H, 0x07, 0x02, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(07H_03H, 0x07, 0x03, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(07H_01H, 0x07, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(07H_02H, 0x07, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(07H_03H, 0x07, 0x03, IAP_F_FM | IAP_F_ALLCPUSCORE2),
         IAPDESCR(07H_06H, 0x07, 0x06, IAP_F_FM | IAP_F_CA),
         IAPDESCR(07H_08H, 0x07, 0x08, IAP_F_FM | IAP_F_CA),
     
    -    IAPDESCR(08H_01H, 0x08, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(08H_02H, 0x08, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(08H_04H, 0x08, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    +    IAPDESCR(08H_01H, 0x08, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(08H_02H, 0x08, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(08H_04H, 0x08, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_WM),
         IAPDESCR(08H_05H, 0x08, 0x05, IAP_F_FM | IAP_F_CA),
         IAPDESCR(08H_06H, 0x08, 0x06, IAP_F_FM | IAP_F_CA),
         IAPDESCR(08H_07H, 0x08, 0x07, IAP_F_FM | IAP_F_CA),
         IAPDESCR(08H_08H, 0x08, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(08H_09H, 0x08, 0x09, IAP_F_FM | IAP_F_CA),
    +    IAPDESCR(08H_10H, 0x08, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(08H_20H, 0x08, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(08H_40H, 0x08, 0x40, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(08H_80H, 0x08, 0x80, IAP_F_FM | IAP_F_I7),
     
    -    IAPDESCR(09H_01H, 0x09, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(09H_02H, 0x09, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(09H_01H, 0x09, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
    +    IAPDESCR(09H_02H, 0x09, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
    +    IAPDESCR(09H_04H, 0x09, 0x04, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(09H_08H, 0x09, 0x08, IAP_F_FM | IAP_F_I7O),
     
    -    IAPDESCR(0CH_01H, 0x0C, 0x01, IAP_F_FM | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(0BH_01H, 0x0B, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(0BH_02H, 0x0B, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(0BH_10H, 0x0B, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(0CH_01H, 0x0C, 0x01, IAP_F_FM | IAP_F_CC2 | IAP_F_I7 |
    +	IAP_F_WM),
         IAPDESCR(0CH_02H, 0x0C, 0x02, IAP_F_FM | IAP_F_CC2),
         IAPDESCR(0CH_03H, 0x0C, 0x03, IAP_F_FM | IAP_F_CA),
     
    -    IAPDESCR(10H_00H, 0x10, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(10H_01H, 0x10, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
    +    IAPDESCR(0EH_01H, 0x0E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(0EH_02H, 0x0E, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(0FH_01H, 0x0F, 0x01, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(0FH_02H, 0x0F, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(0FH_08H, 0x0F, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(0FH_10H, 0x0F, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(0FH_20H, 0x0F, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(0FH_80H, 0x0F, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(10H_00H, 0x10, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(10H_01H, 0x10, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(10H_02H, 0x10, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(10H_04H, 0x10, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(10H_08H, 0x10, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(10H_10H, 0x10, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(10H_20H, 0x10, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(10H_40H, 0x10, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(10H_80H, 0x10, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
         IAPDESCR(10H_81H, 0x10, 0x81, IAP_F_FM | IAP_F_CA),
     
         IAPDESCR(11H_00H, 0x11, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
         IAPDESCR(11H_01H, 0x11, 0x01, IAP_F_FM | IAP_F_CA),
         IAPDESCR(11H_81H, 0x11, 0x81, IAP_F_FM | IAP_F_CA),
     
    -    IAPDESCR(12H_00H, 0x12, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(12H_01H, 0x12, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
    +    IAPDESCR(12H_00H, 0x12, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(12H_01H, 0x12, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(12H_02H, 0x12, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(12H_04H, 0x12, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(12H_08H, 0x12, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(12H_10H, 0x12, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(12H_20H, 0x12, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(12H_40H, 0x12, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
         IAPDESCR(12H_81H, 0x12, 0x81, IAP_F_FM | IAP_F_CA),
     
    -    IAPDESCR(13H_00H, 0x13, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(13H_01H, 0x13, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
    +    IAPDESCR(13H_00H, 0x13, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(13H_01H, 0x13, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(13H_02H, 0x13, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(13H_04H, 0x13, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(13H_07H, 0x13, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
         IAPDESCR(13H_81H, 0x13, 0x81, IAP_F_FM | IAP_F_CA),
     
         IAPDESCR(14H_00H, 0x14, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
    -    IAPDESCR(14H_01H, 0x14, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
    +    IAPDESCR(14H_01H, 0x14, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(14H_02H, 0x14, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(17H_01H, 0x17, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
         IAPDESCR(18H_00H, 0x18, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    +    IAPDESCR(18H_01H, 0x18, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
         IAPDESCR(19H_00H, 0x19, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    -    IAPDESCR(19H_01H, 0x19, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(19H_01H, 0x19, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
         IAPDESCR(19H_02H, 0x19, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
    -    IAPDESCR(21H, 0x21, IAP_M_CORE, IAP_F_ALLCPUS),
    +    IAPDESCR(1DH_01H, 0x1D, 0x01, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(1DH_02H, 0x1D, 0x02, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(1DH_04H, 0x1D, 0x04, IAP_F_FM | IAP_F_I7O),
    +
    +    IAPDESCR(1EH_01H, 0x1E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(20H_01H, 0x20, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(21H, 0x21, IAP_M_CORE, IAP_F_ALLCPUSCORE2),
         IAPDESCR(22H, 0x22, IAP_M_CORE, IAP_F_CC2),
    -    IAPDESCR(23H, 0x23, IAP_M_CORE, IAP_F_ALLCPUS),
    -    IAPDESCR(24H, 0x24, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUS),
    -    IAPDESCR(25H, 0x25, IAP_M_CORE, IAP_F_ALLCPUS),
    -    IAPDESCR(26H, 0x26, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUS),
    -    IAPDESCR(27H, 0x27, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUS),
    -    IAPDESCR(28H, 0x28, IAP_M_CORE | IAP_M_MESI, IAP_F_ALLCPUS),
    +    IAPDESCR(23H, 0x23, IAP_M_CORE, IAP_F_ALLCPUSCORE2),
    +
    +    IAPDESCR(24H, 0x24, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(24H_01H, 0x24, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_02H, 0x24, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_03H, 0x24, 0x03, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_04H, 0x24, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_08H, 0x24, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_0CH, 0x24, 0x0C, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_10H, 0x24, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_20H, 0x24, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_30H, 0x24, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_40H, 0x24, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_80H, 0x24, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_C0H, 0x24, 0xC0, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_AAH, 0x24, 0xAA, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(24H_FFH, 0x24, 0xFF, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(25H, 0x25, IAP_M_CORE, IAP_F_ALLCPUSCORE2),
    +
    +    IAPDESCR(26H, 0x26, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(26H_01H, 0x26, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_02H, 0x26, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_04H, 0x26, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_08H, 0x26, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_0FH, 0x26, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_10H, 0x26, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_20H, 0x26, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_40H, 0x26, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_80H, 0x26, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_F0H, 0x26, 0xF0, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(26H_FFH, 0x26, 0xFF, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(27H, 0x27, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(27H_01H, 0x27, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_02H, 0x27, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_04H, 0x27, 0x04, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(27H_08H, 0x27, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_0EH, 0x27, 0x0E, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_0FH, 0x27, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_10H, 0x27, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_20H, 0x27, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_40H, 0x27, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_80H, 0x27, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_E0H, 0x27, 0xE0, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(27H_F0H, 0x27, 0xF0, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(28H, 0x28, IAP_M_CORE | IAP_M_MESI, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(28H_01H, 0x28, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(28H_02H, 0x28, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(28H_04H, 0x28, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(28H_08H, 0x28, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(28H_0FH, 0x28, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
         IAPDESCR(29H, 0x29, IAP_M_CORE | IAP_M_MESI, IAP_F_CC),
         IAPDESCR(29H, 0x29, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH,
     	IAP_F_CA | IAP_F_CC2),
    -    IAPDESCR(2AH, 0x2A, IAP_M_CORE | IAP_M_MESI, IAP_F_ALLCPUS),
    +    IAPDESCR(2AH, 0x2A, IAP_M_CORE | IAP_M_MESI, IAP_F_ALLCPUSCORE2),
         IAPDESCR(2BH, 0x2B, IAP_M_CORE | IAP_M_MESI, IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(2EH, 0x2E, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH,
    -	IAP_F_ALLCPUS),
    -    IAPDESCR(2EH_41H, 0x2E, 0x41, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(2EH_4FH, 0x2E, 0x4F, IAP_F_FM | IAP_F_ALLCPUS),
    +	IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(2EH_01H, 0x2E, 0x01, IAP_F_FM | IAP_F_WM),
    +    IAPDESCR(2EH_02H, 0x2E, 0x02, IAP_F_FM | IAP_F_WM),
    +    IAPDESCR(2EH_41H, 0x2E, 0x41, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7),
    +    IAPDESCR(2EH_4FH, 0x2E, 0x4F, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7),
     
         IAPDESCR(30H, 0x30, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH,
    -	IAP_F_ALLCPUS),
    +	IAP_F_ALLCPUSCORE2),
         IAPDESCR(32H, 0x32, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH, IAP_F_CC),
         IAPDESCR(32H, 0x32, IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(3AH, 0x3A, IAP_M_TRANSITION, IAP_F_CC),
         IAPDESCR(3AH_00H, 0x3A, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
    -    IAPDESCR(3BH_C0H, 0x3B, 0xC0, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(3BH_C0H, 0x3B, 0xC0, IAP_F_FM | IAP_F_ALLCPUSCORE2),
     
    -    IAPDESCR(3CH_00H, 0x3C, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(3CH_01H, 0x3C, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(3CH_02H, 0x3C, 0x02, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(3CH_00H, 0x3C, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
    +        IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(3CH_01H, 0x3C, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
    +        IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(3CH_02H, 0x3C, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +
    +    IAPDESCR(3DH_01H, 0x3D, 0x01, IAP_F_FM | IAP_F_I7O),
     
         IAPDESCR(40H, 0x40, IAP_M_MESI, IAP_F_CC | IAP_F_CC2),
    +    IAPDESCR(40H_01H, 0x40, 0x01, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(40H_02H, 0x40, 0x02, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(40H_04H, 0x40, 0x04, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(40H_08H, 0x40, 0x08, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(40H_0FH, 0x40, 0x0F, IAP_F_FM | IAP_F_I7),
         IAPDESCR(40H_21H, 0x40, 0x21, IAP_F_FM | IAP_F_CA),
     
         IAPDESCR(41H, 0x41, IAP_M_MESI, IAP_F_CC | IAP_F_CC2),
    +    IAPDESCR(41H_01H, 0x41, 0x01, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(41H_02H, 0x41, 0x02, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(41H_04H, 0x41, 0x04, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(41H_08H, 0x41, 0x08, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(41H_0FH, 0x41, 0x0F, IAP_F_FM | IAP_F_I7O),
         IAPDESCR(41H_22H, 0x41, 0x22, IAP_F_FM | IAP_F_CA),
     
    -    IAPDESCR(42H, 0x42, IAP_M_MESI, IAP_F_ALLCPUS),
    +    IAPDESCR(42H, 0x42, IAP_M_MESI, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(42H_01H, 0x42, 0x01, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(42H_02H, 0x42, 0x02, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(42H_04H, 0x42, 0x04, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(42H_08H, 0x42, 0x08, IAP_F_FM | IAP_F_I7),
         IAPDESCR(42H_10H, 0x42, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
    -    IAPDESCR(43H_01H, 0x43, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(43H_02H, 0x43, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(43H_01H, 0x43, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
    +	IAP_F_I7),
    +    IAPDESCR(43H_02H, 0x43, 0x02, IAP_F_FM | IAP_F_CA |
    +	IAP_F_CC2 | IAP_F_I7),
     
         IAPDESCR(44H_02H, 0x44, 0x02, IAP_F_FM | IAP_F_CC),
     
    -    IAPDESCR(45H_0FH, 0x45, 0x0F, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(45H_0FH, 0x45, 0x0F, IAP_F_FM | IAP_F_ALLCPUSCORE2),
     
    -    IAPDESCR(46H_00H, 0x46, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(47H_00H, 0x47, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(48H_00H, 0x48, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(46H_00H, 0x46, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(47H_00H, 0x47, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +
    +    IAPDESCR(48H_00H, 0x48, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(48H_02H, 0x48, 0x02, IAP_F_FM | IAP_F_I7),
     
         IAPDESCR(49H_00H, 0x49, 0x00, IAP_F_FM | IAP_F_CC),
    -    IAPDESCR(49H_01H, 0x49, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(49H_02H, 0x49, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(49H_01H, 0x49, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +        IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(49H_02H, 0x49, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +        IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(49H_04H, 0x49, 0x04, IAP_F_FM | IAP_F_WM),
    +    IAPDESCR(49H_10H, 0x49, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(49H_20H, 0x49, 0x20, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(49H_40H, 0x49, 0x40, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(49H_80H, 0x49, 0x80, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
     
    -    IAPDESCR(4BH_00H, 0x4B, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(4BH_01H, 0x4B, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(4BH_02H, 0x4B, 0x02, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(4BH_00H, 0x4B, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(4BH_01H, 0x4B, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7O),
    +    IAPDESCR(4BH_02H, 0x4B, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2),
         IAPDESCR(4BH_03H, 0x4B, 0x03, IAP_F_FM | IAP_F_CC),
    +    IAPDESCR(4BH_08H, 0x4B, 0x08, IAP_F_FM | IAP_F_I7O),
     
         IAPDESCR(4CH_00H, 0x4C, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    +    IAPDESCR(4CH_01H, 0x4C, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
    +    IAPDESCR(4DH_01H, 0x4D, 0x01, IAP_F_FM | IAP_F_I7O),
    +
    +    IAPDESCR(4EH_01H, 0x4E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(4EH_02H, 0x4E, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(4EH_04H, 0x4E, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
         IAPDESCR(4EH_10H, 0x4E, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(4FH_00H, 0x4F, 0x00, IAP_F_FM | IAP_F_CC),
    +    IAPDESCR(4FH_02H, 0x4F, 0x02, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(4FH_04H, 0x4F, 0x04, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(4FH_08H, 0x4F, 0x08, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(4FH_10H, 0x4F, 0x10, IAP_F_FM | IAP_F_WM),
     
    -    IAPDESCR(60H, 0x60, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
    +    IAPDESCR(51H_01H, 0x51, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(51H_02H, 0x51, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(51H_04H, 0x51, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(51H_08H, 0x51, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(52H_01H, 0x52, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(53H_01H, 0x53, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(60H, 0x60, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(60H_01H, 0x60, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(60H_02H, 0x60, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(60H_04H, 0x60, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(60H_08H, 0x60, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
     
         IAPDESCR(61H, 0x61, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2),
         IAPDESCR(61H_00H, 0x61, 0x00, IAP_F_FM | IAP_F_CC),
     
    -    IAPDESCR(62H, 0x62, IAP_M_AGENT, IAP_F_ALLCPUS),
    +    IAPDESCR(62H, 0x62, IAP_M_AGENT, IAP_F_ALLCPUSCORE2),
         IAPDESCR(62H_00H, 0x62, 0x00, IAP_F_FM | IAP_F_CC),
     
         IAPDESCR(63H, 0x63, IAP_M_AGENT | IAP_M_CORE,
     	IAP_F_CA | IAP_F_CC2),
         IAPDESCR(63H, 0x63, IAP_M_CORE, IAP_F_CC),
    +    IAPDESCR(63H_01H, 0x63, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(63H_02H, 0x63, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
         IAPDESCR(64H, 0x64, IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
         IAPDESCR(64H_40H, 0x64, 0x40, IAP_F_FM | IAP_F_CC),
    @@ -723,16 +893,18 @@ static struct iap_event_descr iap_events[] = {
     	IAP_F_CA | IAP_F_CC2),
         IAPDESCR(65H, 0x65, IAP_M_CORE, IAP_F_CC),
     
    -    IAPDESCR(66H, 0x66, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
    +    IAPDESCR(66H, 0x66, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
     
         IAPDESCR(67H, 0x67, IAP_M_AGENT | IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
         IAPDESCR(67H, 0x67, IAP_M_AGENT, IAP_F_CC),
     
    -    IAPDESCR(68H, 0x68, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
    -    IAPDESCR(69H, 0x69, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
    -    IAPDESCR(6AH, 0x6A, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
    -    IAPDESCR(6BH, 0x6B, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
    -    IAPDESCR(6CH, 0x6C, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUS),
    +    IAPDESCR(68H, 0x68, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(69H, 0x69, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(6AH, 0x6A, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(6BH, 0x6B, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
    +
    +    IAPDESCR(6CH, 0x6C, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(6CH_01H, 0x6C, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
         IAPDESCR(6DH, 0x6D, IAP_M_AGENT | IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
         IAPDESCR(6DH, 0x6D, IAP_M_CORE, IAP_F_CC),
    @@ -757,47 +929,89 @@ static struct iap_event_descr iap_events[] = {
     
         IAPDESCR(7BH, 0x7B, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2),
     
    -    IAPDESCR(7DH, 0x7D, IAP_M_CORE, IAP_F_ALLCPUS),
    +    IAPDESCR(7DH, 0x7D, IAP_M_CORE, IAP_F_ALLCPUSCORE2),
     
         IAPDESCR(7EH, 0x7E, IAP_M_AGENT | IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
         IAPDESCR(7EH_00H, 0x7E, 0x00, IAP_F_FM | IAP_F_CC),
     
         IAPDESCR(7FH, 0x7F, IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
     
    -    IAPDESCR(80H_00H, 0x80, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(80H_02H, 0x80, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_I7),
    -    IAPDESCR(80H_03H, 0x80, 0x03, IAP_F_FM | IAP_F_CA | IAP_F_I7),
    +    IAPDESCR(80H_00H, 0x80, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(80H_01H, 0x80, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(80H_02H, 0x80, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
    +	IAP_F_WM),
    +    IAPDESCR(80H_03H, 0x80, 0x03, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
    +	IAP_F_WM),
    +    IAPDESCR(80H_04H, 0x80, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
    -    IAPDESCR(81H_00H, 0x81, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(81H_00H, 0x81, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(81H_01H, 0x81, 0x01, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(81H_02H, 0x81, 0x02, IAP_F_FM | IAP_F_I7O),
     
    +    IAPDESCR(82H_01H, 0x82, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
         IAPDESCR(82H_02H, 0x82, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(82H_04H, 0x82, 0x04, IAP_F_FM | IAP_F_CA),
         IAPDESCR(82H_10H, 0x82, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(82H_12H, 0x82, 0x12, IAP_F_FM | IAP_F_CC2),
         IAPDESCR(82H_40H, 0x82, 0x40, IAP_F_FM | IAP_F_CC2),
     
    +    IAPDESCR(83H_01H, 0x83, 0x01, IAP_F_FM | IAP_F_I7O),
         IAPDESCR(83H_02H, 0x83, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(85H_00H, 0x85, 0x00, IAP_F_FM | IAP_F_CC),
    +    IAPDESCR(85H_01H, 0x85, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(85H_02H, 0x85, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(85H_04H, 0x85, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(85H_10H, 0x85, 0x10, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(85H_20H, 0x85, 0x20, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(85H_40H, 0x85, 0x40, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(85H_80H, 0x85, 0x80, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
     
    -    IAPDESCR(86H_00H, 0x86, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(86H_00H, 0x86, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
     
    -    IAPDESCR(87H_00H, 0x87, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(87H_00H, 0x87, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(87H_01H, 0x87, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(87H_02H, 0x87, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(87H_04H, 0x87, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(87H_08H, 0x87, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(87H_0FH, 0x87, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
    -    IAPDESCR(88H_00H, 0x88, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(89H_00H, 0x89, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(8AH_00H, 0x8A, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(8BH_00H, 0x8B, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(8CH_00H, 0x8C, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(8DH_00H, 0x8D, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(8EH_00H, 0x8E, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(8FH_00H, 0x8F, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(88H_00H, 0x88, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(88H_01H, 0x88, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(88H_02H, 0x88, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(88H_04H, 0x88, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(88H_07H, 0x88, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(88H_08H, 0x88, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(88H_10H, 0x88, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(88H_20H, 0x88, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(88H_30H, 0x88, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(88H_40H, 0x88, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(88H_7FH, 0x88, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
    -    IAPDESCR(90H_00H, 0x90, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(91H_00H, 0x91, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(92H_00H, 0x92, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(93H_00H, 0x93, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(94H_00H, 0x94, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(89H_00H, 0x89, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(89H_01H, 0x89, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(89H_02H, 0x89, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(89H_04H, 0x89, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(89H_07H, 0x89, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(89H_08H, 0x89, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(89H_10H, 0x89, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(89H_20H, 0x89, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(89H_30H, 0x89, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(89H_40H, 0x89, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(89H_7FH, 0x89, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(8AH_00H, 0x8A, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(8BH_00H, 0x8B, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(8CH_00H, 0x8C, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(8DH_00H, 0x8D, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(8EH_00H, 0x8E, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(8FH_00H, 0x8F, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +
    +    IAPDESCR(90H_00H, 0x90, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(91H_00H, 0x91, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(92H_00H, 0x92, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(93H_00H, 0x93, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(94H_00H, 0x94, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
     
         IAPDESCR(97H_00H, 0x97, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(98H_00H, 0x98, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    @@ -811,6 +1025,18 @@ static struct iap_event_descr iap_events[] = {
         IAPDESCR(A1H_20H, 0xA1, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(A2H_00H, 0xA2, 0x00, IAP_F_FM | IAP_F_CC),
    +    IAPDESCR(A2H_01H, 0xA2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(A2H_02H, 0xA2, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(A2H_04H, 0xA2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(A2H_08H, 0xA2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(A2H_10H, 0xA2, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(A2H_20H, 0xA2, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(A2H_40H, 0xA2, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(A2H_80H, 0xA2, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(A6H_01H, 0xA6, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(A7H_01H, 0xA7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(A8H_01H, 0xA8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
         IAPDESCR(AAH_01H, 0xAA, 0x01, IAP_F_FM | IAP_F_CC2),
         IAPDESCR(AAH_02H, 0xAA, 0x02, IAP_F_FM | IAP_F_CA),
    @@ -820,18 +1046,42 @@ static struct iap_event_descr iap_events[] = {
         IAPDESCR(ABH_01H, 0xAB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(ABH_02H, 0xAB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
    -    IAPDESCR(B0H_00H, 0xB0, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(B0H_80H, 0xB0, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_I7),
    +    IAPDESCR(AEH_01H, 0xAE, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
    -    IAPDESCR(B1H_00H, 0xB1, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(B1H_80H, 0xB1, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_I7),
    +    IAPDESCR(B0H_00H, 0xB0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(B0H_01H, 0xB0, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(B0H_02H, 0xB0, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(B0H_04H, 0xB0, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(B0H_08H, 0xB0, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(B0H_10H, 0xB0, 0x10, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(B0H_20H, 0xB0, 0x20, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(B0H_40H, 0xB0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B0H_80H, 0xB0, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_WM | IAP_F_I7O),
     
    -    IAPDESCR(B3H_01H, 0xB3, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(B3H_02H, 0xB3, 0x02, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(B3H_04H, 0xB3, 0x04, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(B3H_08H, 0xB3, 0x08, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(B3H_10H, 0xB3, 0x10, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(B3H_20H, 0xB3, 0x20, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(B1H_00H, 0xB1, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(B1H_01H, 0xB1, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B1H_02H, 0xB1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B1H_04H, 0xB1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B1H_08H, 0xB1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B1H_10H, 0xB1, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B1H_1FH, 0xB1, 0x1F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B1H_20H, 0xB1, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B1H_3FH, 0xB1, 0x3F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B1H_40H, 0xB1, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B1H_80H, 0xB1, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
    +	IAP_F_WM),
    +
    +    IAPDESCR(B2H_01H, 0xB2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(B3H_01H, 0xB3, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
    +	IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(B3H_02H, 0xB3, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
    +	IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(B3H_04H, 0xB3, 0x04, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
    +	IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(B3H_08H, 0xB3, 0x08, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(B3H_10H, 0xB3, 0x10, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(B3H_20H, 0xB3, 0x20, IAP_F_FM | IAP_F_ALLCPUSCORE2),
         IAPDESCR(B3H_81H, 0xB3, 0x81, IAP_F_FM | IAP_F_CA),
         IAPDESCR(B3H_82H, 0xB3, 0x82, IAP_F_FM | IAP_F_CA),
         IAPDESCR(B3H_84H, 0xB3, 0x84, IAP_F_FM | IAP_F_CA),
    @@ -839,10 +1089,28 @@ static struct iap_event_descr iap_events[] = {
         IAPDESCR(B3H_90H, 0xB3, 0x90, IAP_F_FM | IAP_F_CA),
         IAPDESCR(B3H_A0H, 0xB3, 0xA0, IAP_F_FM | IAP_F_CA),
     
    -    IAPDESCR(C0H_00H, 0xC0, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(C0H_01H, 0xC0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C0H_02H, 0xC0, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C0H_04H, 0xC0, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    +    IAPDESCR(B4H_01H, 0xB4, 0x01, IAP_F_FM | IAP_F_WM),
    +    IAPDESCR(B4H_02H, 0xB4, 0x02, IAP_F_FM | IAP_F_WM),
    +    IAPDESCR(B4H_04H, 0xB4, 0x04, IAP_F_FM | IAP_F_WM),
    +
    +    IAPDESCR(B7H_01H, 0xB7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(B8H_01H, 0xB8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B8H_02H, 0xB8, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(B8H_04H, 0xB8, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(BAH_01H, 0xBA, 0x01, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(BAH_02H, 0xBA, 0x02, IAP_F_FM | IAP_F_I7O),
    +
    +    IAPDESCR(BBH_01H, 0xBB, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(C0H_00H, 0xC0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(C0H_01H, 0xC0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C0H_02H, 0xC0, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C0H_04H, 0xC0, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
         IAPDESCR(C0H_08H, 0xC0, 0x08, IAP_F_FM | IAP_F_CC2E),
     
         IAPDESCR(C1H_00H, 0xC1, 0x00, IAP_F_FM | IAP_F_CC),
    @@ -850,43 +1118,64 @@ static struct iap_event_descr iap_events[] = {
         IAPDESCR(C1H_FEH, 0xC1, 0xFE, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(C2H_00H, 0xC2, 0x00, IAP_F_FM | IAP_F_CC),
    -    IAPDESCR(C2H_01H, 0xC2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C2H_02H, 0xC2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C2H_04H, 0xC2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(C2H_01H, 0xC2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C2H_02H, 0xC2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C2H_04H, 0xC2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
         IAPDESCR(C2H_07H, 0xC2, 0x07, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(C2H_08H, 0xC2, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(C2H_0FH, 0xC2, 0x0F, IAP_F_FM | IAP_F_CC2),
         IAPDESCR(C2H_10H, 0xC2, 0x10, IAP_F_FM | IAP_F_CA),
     
         IAPDESCR(C3H_00H, 0xC3, 0x00, IAP_F_FM | IAP_F_CC),
    -    IAPDESCR(C3H_01H, 0xC3, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C3H_04H, 0xC3, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(C3H_01H, 0xC3, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C3H_02H, 0xC3, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C3H_04H, 0xC3, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C3H_10H, 0xC3, 0x10, IAP_F_FM | IAP_F_I7O),
     
    -    IAPDESCR(C4H_00H, 0xC4, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(C4H_01H, 0xC4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C4H_02H, 0xC4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C4H_04H, 0xC4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(C4H_00H, 0xC4, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C4H_01H, 0xC4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C4H_02H, 0xC4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C4H_04H, 0xC4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
         IAPDESCR(C4H_08H, 0xC4, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(C4H_0CH, 0xC4, 0x0C, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(C4H_0FH, 0xC4, 0x0F, IAP_F_FM | IAP_F_CA),
     
    -    IAPDESCR(C5H_00H, 0xC5, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(C5H_00H, 0xC5, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C5H_01H, 0xC5, 0x01, IAP_F_FM | IAP_F_WM),
    +    IAPDESCR(C5H_02H, 0xC5, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C5H_04H, 0xC5, 0x04, IAP_F_FM | IAP_F_WM),
     
         IAPDESCR(C6H_00H, 0xC6, 0x00, IAP_F_FM | IAP_F_CC),
         IAPDESCR(C6H_01H, 0xC6, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(C6H_02H, 0xC6, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(C7H_00H, 0xC7, 0x00, IAP_F_FM | IAP_F_CC),
    -    IAPDESCR(C7H_01H, 0xC7, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C7H_02H, 0xC7, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C7H_04H, 0xC7, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C7H_08H, 0xC7, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(C7H_10H, 0xC7, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(C7H_01H, 0xC7, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C7H_02H, 0xC7, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C7H_04H, 0xC7, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C7H_08H, 0xC7, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(C7H_10H, 0xC7, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
         IAPDESCR(C7H_1FH, 0xC7, 0x1F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
    -    IAPDESCR(C8H_00H, 0xC8, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(C8H_00H, 0xC8, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(C8H_20H, 0xC8, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
    -    IAPDESCR(C9H_00H, 0xC9, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(C9H_00H, 0xC9, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
     
         IAPDESCR(CAH_00H, 0xCA, 0x00, IAP_F_FM | IAP_F_CC),
         IAPDESCR(CAH_01H, 0xCA, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    @@ -894,36 +1183,59 @@ static struct iap_event_descr iap_events[] = {
         IAPDESCR(CAH_04H, 0xCA, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(CAH_08H, 0xCA, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
    -    IAPDESCR(CBH_01H, 0xCB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(CBH_02H, 0xCB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(CBH_04H, 0xCB, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(CBH_08H, 0xCB, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(CBH_10H, 0xCB, 0x10, IAP_F_FM | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(CBH_01H, 0xCB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(CBH_02H, 0xCB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(CBH_04H, 0xCB, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(CBH_08H, 0xCB, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(CBH_10H, 0xCB, 0x10, IAP_F_FM | IAP_F_CC2 | IAP_F_I7 |
    +	IAP_F_WM),
    +    IAPDESCR(CBH_40H, 0xCB, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(CBH_80H, 0xCB, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
         IAPDESCR(CCH_00H, 0xCC, 0x00, IAP_F_FM | IAP_F_CC),
    -    IAPDESCR(CCH_01H, 0xCC, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(CCH_02H, 0xCC, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(CCH_01H, 0xCC, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(CCH_02H, 0xCC, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(CCH_03H, 0xCC, 0x03, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
    -    IAPDESCR(CDH_00H, 0xCD, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(CEH_00H, 0xCE, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +    IAPDESCR(CDH_00H, 0xCD, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(CEH_00H, 0xCE, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
         IAPDESCR(CFH_00H, 0xCF, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(D0H_00H, 0xD0, 0x00, IAP_F_FM | IAP_F_CC),
    +    IAPDESCR(D0H_01H, 0xD0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
    -    IAPDESCR(D2H_01H, 0xD2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(D2H_02H, 0xD2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(D2H_04H, 0xD2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(D2H_08H, 0xD2, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    -    IAPDESCR(D2H_0FH, 0xD2, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(D1H_01H, 0xD1, 0x01, IAP_F_FM | IAP_F_WM),
    +    IAPDESCR(D1H_02H, 0xD1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(D1H_04H, 0xD1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(D1H_08H, 0xD1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(D2H_01H, 0xD2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(D2H_02H, 0xD2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(D2H_04H, 0xD2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(D2H_08H, 0xD2, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(D2H_0FH, 0xD2, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
         IAPDESCR(D2H_10H, 0xD2, 0x10, IAP_F_FM | IAP_F_CC2E),
     
    -    IAPDESCR(D4H_01H, 0xD4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(D4H_01H, 0xD4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
         IAPDESCR(D4H_02H, 0xD4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(D4H_04H, 0xD4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(D4H_08H, 0xD4, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(D4H_0FH, 0xD4, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
    -    IAPDESCR(D5H_01H, 0xD5, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
    +    IAPDESCR(D5H_01H, 0xD5, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
    +	IAP_F_I7 | IAP_F_WM),
         IAPDESCR(D5H_02H, 0xD5, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(D5H_04H, 0xD5, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(D5H_08H, 0xD5, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    @@ -947,6 +1259,7 @@ static struct iap_event_descr iap_events[] = {
         IAPDESCR(DAH_02H, 0xDA, 0x02, IAP_F_FM | IAP_F_CC),
     
         IAPDESCR(DBH_00H, 0xDB, 0x00, IAP_F_FM | IAP_F_CC),
    +    IAPDESCR(DBH_01H, 0xDB, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
         IAPDESCR(DCH_01H, 0xDC, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
         IAPDESCR(DCH_02H, 0xDC, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
    @@ -956,276 +1269,76 @@ static struct iap_event_descr iap_events[] = {
         IAPDESCR(DCH_1FH, 0xDC, 0x1F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
     
         IAPDESCR(E0H_00H, 0xE0, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
    -    IAPDESCR(E0H_01H, 0xE0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
    +    IAPDESCR(E0H_01H, 0xE0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
    +	IAP_F_WM),
     
         IAPDESCR(E2H_00H, 0xE2, 0x00, IAP_F_FM | IAP_F_CC),
    -    IAPDESCR(E4H_00H, 0xE4, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    +
    +    IAPDESCR(E4H_00H, 0xE4, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(E4H_01H, 0xE4, 0x01, IAP_F_FM | IAP_F_I7O),
    +
    +    IAPDESCR(E5H_01H, 0xE5, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
         IAPDESCR(E6H_00H, 0xE6, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
    -    IAPDESCR(E6H_01H, 0xE6, 0x01, IAP_F_FM | IAP_F_CA),
    +    IAPDESCR(E6H_01H, 0xE6, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
    +	IAP_F_WM),
    +    IAPDESCR(E6H_02H, 0xE6, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
     
    -    IAPDESCR(F0H_00H, 0xF0, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -    IAPDESCR(F8H_00H, 0xF8, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
    -
    -    /* Added with nehalem. */
    -    IAPDESCR(02H_01H, 0x02, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(03H_01H, 0x03, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(05H_01H, 0x05, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(05H_02H, 0x05, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(05H_03H, 0x05, 0x03, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(06H_01H, 0x06, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(06H_02H, 0x06, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(06H_04H, 0x06, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(06H_08H, 0x06, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(06H_0FH, 0x06, 0x0F, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(08H_10H, 0x08, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(08H_20H, 0x08, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(08H_40H, 0x08, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(08H_80H, 0x08, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(09H_04H, 0x09, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(09H_08H, 0x09, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(0BH_01H, 0x0B, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(0BH_02H, 0x0B, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(0EH_01H, 0x0E, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(0EH_02H, 0x0E, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(0FH_02H, 0x0F, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(0FH_08H, 0x0F, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(0FH_10H, 0x0F, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(0FH_20H, 0x0F, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(10H_02H, 0x10, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(10H_04H, 0x10, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(10H_08H, 0x10, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(10H_10H, 0x10, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(10H_20H, 0x10, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(10H_40H, 0x10, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(10H_80H, 0x10, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(12H_02H, 0x12, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(12H_04H, 0x12, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(12H_08H, 0x12, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(12H_10H, 0x12, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(12H_20H, 0x12, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(12H_40H, 0x12, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(13H_02H, 0x13, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(13H_04H, 0x13, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(13H_07H, 0x13, 0x07, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(14H_02H, 0x14, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(17H_01H, 0x17, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(18H_01H, 0x18, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(1DH_01H, 0x1D, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(1DH_02H, 0x1D, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(1DH_04H, 0x1D, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(1EH_01H, 0x1E, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_01H, 0x24, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_02H, 0x24, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_03H, 0x24, 0x03, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_04H, 0x24, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_08H, 0x24, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_0CH, 0x24, 0x0C, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_10H, 0x24, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_20H, 0x24, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_30H, 0x24, 0x30, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_40H, 0x24, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_80H, 0x24, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_AAH, 0x24, 0xAA, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_C0H, 0x24, 0xC0, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(24H_FFH, 0x24, 0xFF, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_01H, 0x26, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_02H, 0x26, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_04H, 0x26, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_08H, 0x26, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_0FH, 0x26, 0x0F, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_10H, 0x26, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_20H, 0x26, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_40H, 0x26, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_80H, 0x26, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_F0H, 0x26, 0xF0, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(26H_FFH, 0x26, 0xFF, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_01H, 0x27, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_02H, 0x27, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_04H, 0x27, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_08H, 0x27, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_0EH, 0x27, 0x0E, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_0FH, 0x27, 0x0F, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_10H, 0x27, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_20H, 0x27, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_40H, 0x27, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_80H, 0x27, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_E0H, 0x27, 0xE0, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(27H_F0H, 0x27, 0xF0, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(28H_01H, 0x28, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(28H_02H, 0x28, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(28H_04H, 0x28, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(28H_08H, 0x28, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(28H_0FH, 0x28, 0x0F, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(3DH_01H, 0x3D, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(40H_01H, 0x40, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(40H_02H, 0x40, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(40H_04H, 0x40, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(40H_08H, 0x40, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(40H_0FH, 0x40, 0x0F, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(41H_01H, 0x41, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(41H_02H, 0x41, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(41H_04H, 0x41, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(41H_08H, 0x41, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(41H_0FH, 0x41, 0x0F, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(42H_01H, 0x42, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(42H_02H, 0x42, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(42H_04H, 0x42, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(42H_08H, 0x42, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(48H_02H, 0x48, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(49H_10H, 0x49, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(49H_20H, 0x49, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(49H_40H, 0x49, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(49H_80H, 0x49, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(4BH_08H, 0x4B, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(4CH_01H, 0x4C, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(4DH_01H, 0x4D, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(4EH_01H, 0x4E, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(4EH_02H, 0x4E, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(4EH_04H, 0x4E, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(4FH_02H, 0x4F, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(4FH_04H, 0x4F, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(4FH_08H, 0x4F, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(51H_01H, 0x51, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(51H_02H, 0x51, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(51H_04H, 0x51, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(51H_08H, 0x51, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(52H_01H, 0x52, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(53H_01H, 0x53, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(60H_01H, 0x60, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(60H_02H, 0x60, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(60H_04H, 0x60, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(60H_08H, 0x60, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(63H_01H, 0x63, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(63H_02H, 0x63, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(6CH_01H, 0x6C, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(80H_01H, 0x80, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(80H_04H, 0x80, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(80H_10H, 0x80, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(81H_01H, 0x81, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(81H_02H, 0x81, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(82H_01H, 0x82, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(83H_01H, 0x83, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(85H_01H, 0x85, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(85H_02H, 0x85, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(85H_04H, 0x85, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(85H_10H, 0x85, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(85H_20H, 0x85, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(85H_40H, 0x85, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(85H_80H, 0x85, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(87H_01H, 0x87, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(87H_02H, 0x87, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(87H_04H, 0x87, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(87H_08H, 0x87, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(87H_0FH, 0x87, 0x0F, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(88H_01H, 0x88, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(88H_02H, 0x88, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(88H_04H, 0x88, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(88H_07H, 0x88, 0x07, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(88H_08H, 0x88, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(88H_10H, 0x88, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(88H_20H, 0x88, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(88H_30H, 0x88, 0x30, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(88H_40H, 0x88, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_01H, 0x89, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_02H, 0x89, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_04H, 0x89, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_07H, 0x89, 0x07, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_08H, 0x89, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_10H, 0x89, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_20H, 0x89, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_30H, 0x89, 0x30, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_40H, 0x89, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(89H_7FH, 0x89, 0x7F, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A2H_01H, 0xA2, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A2H_02H, 0xA2, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A2H_04H, 0xA2, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A2H_08H, 0xA2, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A2H_10H, 0xA2, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A2H_20H, 0xA2, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A2H_40H, 0xA2, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A2H_80H, 0xA2, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A6H_01H, 0xA6, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A7H_01H, 0xA7, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(A8H_01H, 0xA8, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B0H_01H, 0xB0, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B0H_02H, 0xB0, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B0H_04H, 0xB0, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B0H_08H, 0xB0, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B0H_20H, 0xB0, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B0H_40H, 0xB0, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B1H_01H, 0xB1, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B1H_02H, 0xB1, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B1H_04H, 0xB1, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B1H_08H, 0xB1, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B1H_10H, 0xB1, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B1H_20H, 0xB1, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B1H_40H, 0xB1, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B2H_01H, 0xB2, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B7H_01H, 0xB7, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B8H_01H, 0xB8, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B8H_02H, 0xB8, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(B8H_04H, 0xB8, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(BAH_01H, 0xBA, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(BAH_02H, 0xBA, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(C3H_02H, 0xC3, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(C3H_10H, 0xC3, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(C5H_02H, 0xC5, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(C8H_20H, 0xC8, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(CBH_40H, 0xCB, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(CBH_80H, 0xCB, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(CCH_03H, 0xCC, 0x03, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(D0H_01H, 0xD0, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(D1H_02H, 0xD1, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(D1H_04H, 0xD1, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(D1H_08H, 0xD1, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(DBH_01H, 0xDB, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(E4H_01H, 0xE4, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(E5H_01H, 0xE5, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(E6H_01H, 0xE6, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(E6H_02H, 0xE6, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(E8H_01H, 0xE8, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(E8H_02H, 0xE8, 0x02, IAP_F_FM | IAP_F_I7),
    +    IAPDESCR(E8H_01H, 0xE8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(E8H_02H, 0xE8, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
         IAPDESCR(E8H_03H, 0xE8, 0x03, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F0H_01H, 0xF0, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F0H_02H, 0xF0, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F0H_04H, 0xF0, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F0H_08H, 0xF0, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F0H_10H, 0xF0, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F0H_20H, 0xF0, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F0H_40H, 0xF0, 0x40, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F0H_80H, 0xF0, 0x80, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F1H_02H, 0xF1, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F1H_04H, 0xF1, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F1H_07H, 0xF1, 0x07, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F2H_01H, 0xF2, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F2H_02H, 0xF2, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F2H_04H, 0xF2, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F2H_08H, 0xF2, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F2H_0FH, 0xF2, 0x0F, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F3H_01H, 0xF3, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F3H_02H, 0xF3, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F3H_04H, 0xF3, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F3H_08H, 0xF3, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F3H_10H, 0xF3, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F3H_20H, 0xF3, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F4H_01H, 0xF4, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F4H_02H, 0xF4, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F4H_04H, 0xF4, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F4H_08H, 0xF4, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F4H_10H, 0xF4, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F6H_01H, 0xF6, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F7H_01H, 0xF7, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F7H_02H, 0xF7, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F7H_04H, 0xF7, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(F8H_01H, 0xF8, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(FDH_01H, 0xFD, 0x01, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(FDH_02H, 0xFD, 0x02, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(FDH_04H, 0xFD, 0x04, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(FDH_08H, 0xFD, 0x08, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(FDH_10H, 0xFD, 0x10, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(FDH_20H, 0xFD, 0x20, IAP_F_FM | IAP_F_I7),
    -    IAPDESCR(FDH_40H, 0xFD, 0x40, IAP_F_FM | IAP_F_I7),
    +
    +    IAPDESCR(ECH_01H, 0xEC, 0x01, IAP_F_FM | IAP_F_WM),
    +
    +    IAPDESCR(F0H_00H, 0xF0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(F0H_01H, 0xF0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F0H_02H, 0xF0, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F0H_04H, 0xF0, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F0H_08H, 0xF0, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F0H_10H, 0xF0, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F0H_20H, 0xF0, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F0H_40H, 0xF0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F0H_80H, 0xF0, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(F1H_02H, 0xF1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F1H_04H, 0xF1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F1H_07H, 0xF1, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(F2H_01H, 0xF2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F2H_02H, 0xF2, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F2H_04H, 0xF2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F2H_08H, 0xF2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +    IAPDESCR(F2H_0FH, 0xF2, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(F3H_01H, 0xF3, 0x01, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(F3H_02H, 0xF3, 0x02, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(F3H_04H, 0xF3, 0x04, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(F3H_08H, 0xF3, 0x08, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(F3H_10H, 0xF3, 0x10, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(F3H_20H, 0xF3, 0x20, IAP_F_FM | IAP_F_I7O),
    +
    +    IAPDESCR(F4H_01H, 0xF4, 0x01, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(F4H_02H, 0xF4, 0x02, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(F4H_04H, 0xF4, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
    +    IAPDESCR(F4H_08H, 0xF4, 0x08, IAP_F_FM | IAP_F_I7O),
    +    IAPDESCR(F4H_10H, 0xF4, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(F6H_01H, 0xF6, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
    +
    +    IAPDESCR(F7H_01H, 0xF7, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7),
    +    IAPDESCR(F7H_02H, 0xF7, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7),
    +    IAPDESCR(F7H_04H, 0xF7, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7),
    +
    +    IAPDESCR(F8H_00H, 0xF8, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
    +    IAPDESCR(F8H_01H, 0xF8, 0x01, IAP_F_FM | IAP_F_I7O),
    +
    +    IAPDESCR(FDH_01H, 0xFD, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7),
    +    IAPDESCR(FDH_02H, 0xFD, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7),
    +    IAPDESCR(FDH_04H, 0xFD, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7),
    +    IAPDESCR(FDH_08H, 0xFD, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7),
    +    IAPDESCR(FDH_10H, 0xFD, 0x10, IAP_F_FM | IAP_F_WM | IAP_F_I7),
    +    IAPDESCR(FDH_20H, 0xFD, 0x20, IAP_F_FM | IAP_F_WM | IAP_F_I7),
    +    IAPDESCR(FDH_40H, 0xFD, 0x40, IAP_F_FM | IAP_F_WM | IAP_F_I7),
     };
     
     static const int niap_events = sizeof(iap_events) / sizeof(iap_events[0]);
    @@ -1298,6 +1411,80 @@ iap_architectural_event_is_unsupported(enum pmc_event pe)
     	return ((core_architectural_events & (1 << ae)) == 0);
     }
     
    +static int
    +iap_event_corei7_ok_on_counter(enum pmc_event pe, int ri)
    +{
    +	uint32_t mask;
    +
    +	switch (pe) {
    +		/*
    +		 * Events valid only on counter 0, 1.
    +		 */
    +	case PMC_EV_IAP_EVENT_40H_01H:
    +	case PMC_EV_IAP_EVENT_40H_02H:
    +	case PMC_EV_IAP_EVENT_40H_04H:
    +	case PMC_EV_IAP_EVENT_40H_08H:
    +	case PMC_EV_IAP_EVENT_40H_0FH:
    +	case PMC_EV_IAP_EVENT_41H_02H:
    +	case PMC_EV_IAP_EVENT_41H_04H:
    +	case PMC_EV_IAP_EVENT_41H_08H:
    +	case PMC_EV_IAP_EVENT_42H_01H:
    +	case PMC_EV_IAP_EVENT_42H_02H:
    +	case PMC_EV_IAP_EVENT_42H_04H:
    +	case PMC_EV_IAP_EVENT_42H_08H:
    +	case PMC_EV_IAP_EVENT_43H_01H:
    +	case PMC_EV_IAP_EVENT_43H_02H:
    +	case PMC_EV_IAP_EVENT_48H_02H:
    +	case PMC_EV_IAP_EVENT_51H_01H:
    +	case PMC_EV_IAP_EVENT_51H_02H:
    +	case PMC_EV_IAP_EVENT_51H_04H:
    +	case PMC_EV_IAP_EVENT_51H_08H:
    +	case PMC_EV_IAP_EVENT_63H_01H:
    +	case PMC_EV_IAP_EVENT_63H_02H:
    +		mask = 0x3;
    +		break;
    +
    +	default:
    +		mask = ~0;	/* Any row index is ok. */
    +	}
    +
    +	return (mask & (1 << ri));
    +}
    +
    +static int
    +iap_event_westmere_ok_on_counter(enum pmc_event pe, int ri)
    +{
    +	uint32_t mask;
    +
    +	switch (pe) {
    +		/*
    +		 * Events valid only on counter 0.
    +		 */
    +	case PMC_EV_IAP_EVENT_B3H_01H:
    +	case PMC_EV_IAP_EVENT_B3H_02H:
    +	case PMC_EV_IAP_EVENT_B3H_04H:
    +		mask = 0x1;
    +		break;
    +
    +		/*
    +		 * Events valid only on counter 0, 1.
    +		 */
    +	case PMC_EV_IAP_EVENT_51H_01H:
    +	case PMC_EV_IAP_EVENT_51H_02H:
    +	case PMC_EV_IAP_EVENT_51H_04H:
    +	case PMC_EV_IAP_EVENT_51H_08H:
    +	case PMC_EV_IAP_EVENT_63H_01H:
    +	case PMC_EV_IAP_EVENT_63H_02H:
    +		mask = 0x3;
    +		break;
    +
    +	default:
    +		mask = ~0;	/* Any row index is ok. */
    +	}
    +
    +	return (mask & (1 << ri));
    +}
    +
     static int
     iap_event_ok_on_counter(enum pmc_event pe, int ri)
     {
    @@ -1310,6 +1497,9 @@ iap_event_ok_on_counter(enum pmc_event pe, int ri)
     	case PMC_EV_IAP_EVENT_10H_00H:
     	case PMC_EV_IAP_EVENT_14H_00H:
     	case PMC_EV_IAP_EVENT_18H_00H:
    +	case PMC_EV_IAP_EVENT_B3H_01H:
    +	case PMC_EV_IAP_EVENT_B3H_02H:
    +	case PMC_EV_IAP_EVENT_B3H_04H:
     	case PMC_EV_IAP_EVENT_C1H_00H:
     	case PMC_EV_IAP_EVENT_CBH_01H:
     	case PMC_EV_IAP_EVENT_CBH_02H:
    @@ -1356,8 +1546,19 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
     	if (iap_architectural_event_is_unsupported(ev))
     		return (EOPNOTSUPP);
     
    -	if (iap_event_ok_on_counter(ev, ri) == 0)
    -		return (EINVAL);
    +	switch (core_cputype) {
    +	case PMC_CPU_INTEL_COREI7:
    +		if (iap_event_corei7_ok_on_counter(ev, ri) == 0)
    +			return (EINVAL);
    +		break;
    +	case PMC_CPU_INTEL_WESTMERE:
    +		if (iap_event_westmere_ok_on_counter(ev, ri) == 0)
    +			return (EINVAL);
    +		break;
    +	default:
    +		if (iap_event_ok_on_counter(ev, ri) == 0)
    +			return (EINVAL);
    +	}
     
     	/*
     	 * Look for an event descriptor with matching CPU and event id
    @@ -1381,6 +1582,9 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
     	case PMC_CPU_INTEL_COREI7:
     		cpuflag = IAP_F_I7;
     		break;
    +	case PMC_CPU_INTEL_WESTMERE:
    +		cpuflag = IAP_F_WM;
    +		break;
     	}
     
     	for (n = 0, ie = iap_events; n < niap_events; n++, ie++)
    @@ -1469,6 +1673,22 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
     	else if (config & IAP_ANY)
     		return (EINVAL);
     
    +	/*
    +	 * Check offcore response configuration.
    +	 */
    +	if (a->pm_md.pm_iap.pm_iap_rsp != 0) {
    +		if (ev != PMC_EV_IAP_EVENT_B7H_01H &&
    +		    ev != PMC_EV_IAP_EVENT_BBH_01H)
    +			return (EINVAL);
    +		if (core_cputype == PMC_CPU_INTEL_COREI7 &&
    +		    ev == PMC_EV_IAP_EVENT_BBH_01H)
    +			return (EINVAL);
    +		if ( a->pm_md.pm_iap.pm_iap_rsp & ~IA_OFFCORE_RSP_MASK)
    +			return (EINVAL);
    +		pm->pm_md.pm_iap.pm_iap_rsp =
    +		    a->pm_md.pm_iap.pm_iap_rsp & IA_OFFCORE_RSP_MASK;
    +	}
    +
     	if (caps & PMC_CAP_THRESHOLD)
     		evsel |= (a->pm_md.pm_iap.pm_iap_config & IAP_F_CMASK);
     	if (caps & PMC_CAP_USER)
    @@ -1628,6 +1848,18 @@ iap_start_pmc(int cpu, int ri)
     	PMCDBG(MDP,STA,2, "iap-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
     	    cpu, ri, IAP_EVSEL0 + ri, evsel);
     
    +	/* Event specific configuration. */
    +	switch (pm->pm_event) {
    +	case PMC_EV_IAP_EVENT_B7H_01H:
    +		wrmsr(IA_OFFCORE_RSP0, pm->pm_md.pm_iap.pm_iap_rsp);
    +		break;
    +	case PMC_EV_IAP_EVENT_BBH_01H:
    +		wrmsr(IA_OFFCORE_RSP1, pm->pm_md.pm_iap.pm_iap_rsp);
    +		break;
    +	default:
    +		break;
    +	}
    +
     	wrmsr(IAP_EVSEL0 + ri, evsel | IAP_EN);
     
     	if (core_cputype == PMC_CPU_INTEL_CORE)
    @@ -1863,6 +2095,8 @@ core2_intr(int cpu, struct trapframe *tf)
     
     		error = pmc_process_interrupt(cpu, pm, tf,
     		    TRAPF_USERMODE(tf));
    +		if (error)
    +			intrenable &= ~flag;
     
     		v = iaf_reload_count_to_perfctr_value(pm->pm_sc.pm_reloadcount);
     
    @@ -1871,9 +2105,6 @@ core2_intr(int cpu, struct trapframe *tf)
     
     		PMCDBG(MDP,INT, 1, "iaf-intr cpu=%d error=%d v=%jx(%jx)", cpu, error,
     		    (uintmax_t) v, (uintmax_t) rdpmc(IAF_RI_TO_MSR(n)));
    -
    -		if (error)
    -			intrenable &= ~flag;
     	}
     
     	/*
    diff --git a/sys/dev/hwpmc/hwpmc_core.h b/sys/dev/hwpmc/hwpmc_core.h
    index 0c4ee5b3889..e88ecb0b343 100644
    --- a/sys/dev/hwpmc/hwpmc_core.h
    +++ b/sys/dev/hwpmc/hwpmc_core.h
    @@ -46,6 +46,7 @@ struct pmc_md_iaf_op_pmcallocate {
      */
     struct pmc_md_iap_op_pmcallocate {
     	uint32_t	pm_iap_config;
    +	uint32_t	pm_iap_rsp;
     };
     
     #define	IAP_EVSEL(C)	((C) & 0xFF)
    @@ -59,6 +60,8 @@ struct pmc_md_iap_op_pmcallocate {
     #define	IAP_INV		(1 << 23)
     #define	IAP_CMASK(C)	(((C) & 0xFF) << 24)
     
    +#define	IA_OFFCORE_RSP_MASK	0xF7FF
    +
     #ifdef	_KERNEL
     
     /*
    @@ -76,16 +79,15 @@ struct pmc_md_iap_op_pmcallocate {
     /*
      * Programmable counters.
      */
    -#define	IAP_PMC0				0x0C1
    -#define	IAP_PMC1				0x0C2
     
    +#define	IAP_PMC0				0x0C1
     #define	IAP_EVSEL0				0x186
    -#define	IAP_EVSEL1				0x187
     
     /*
      * Simplified programming interface in Intel Performance Architecture
      * v2 and later.
      */
    +
     #define	IA_GLOBAL_STATUS			0x38E
     #define	IA_GLOBAL_CTRL				0x38F
     #define	IA_GLOBAL_OVF_CTRL			0x390
    @@ -93,12 +95,19 @@ struct pmc_md_iap_op_pmcallocate {
     #define	IA_GLOBAL_STATUS_FLAG_CONDCHG		(1ULL << 63)
     #define	IA_GLOBAL_STATUS_FLAG_OVFBUF		(1ULL << 62)
     
    +/*
    + * Offcore response configuration.
    + */
    +#define	IA_OFFCORE_RSP0				0x1A6
    +#define	IA_OFFCORE_RSP1				0x1A7
    +
     struct pmc_md_iaf_pmc {
     	uint64_t	pm_iaf_ctrl;
     };
     
     struct pmc_md_iap_pmc {
     	uint32_t	pm_iap_evsel;
    +	uint32_t	pm_iap_rsp;
     };
     
     /*
    diff --git a/sys/dev/hwpmc/hwpmc_intel.c b/sys/dev/hwpmc/hwpmc_intel.c
    index cb2834faa35..746f02fa7c3 100644
    --- a/sys/dev/hwpmc/hwpmc_intel.c
    +++ b/sys/dev/hwpmc/hwpmc_intel.c
    @@ -131,8 +131,14 @@ pmc_intel_initialize(void)
     			nclasses = 3;
     			break;
     		case 0x1A:
    +		case 0x2E:
     			cputype = PMC_CPU_INTEL_COREI7;
    -			nclasses = 3;
    +			nclasses = 5;
    +			break;
    +		case 0x25:	/* Per Intel document 253669-033US 12/2009. */
    +		case 0x2C:	/* Per Intel document 253669-033US 12/2009. */
    +			cputype = PMC_CPU_INTEL_WESTMERE;
    +			nclasses = 5;
     			break;
     		}
     		break;
    @@ -174,6 +180,7 @@ pmc_intel_initialize(void)
     	case PMC_CPU_INTEL_CORE2:
     	case PMC_CPU_INTEL_CORE2EXTREME:
     	case PMC_CPU_INTEL_COREI7:
    +	case PMC_CPU_INTEL_WESTMERE:
     		error = pmc_core_initialize(pmc_mdep, ncpus);
     		break;
     
    @@ -224,6 +231,22 @@ pmc_intel_initialize(void)
     		KASSERT(0, ("[intel,%d] Unknown CPU type", __LINE__));
     	}
     
    +	/*
    +	 * Init the uncore class.
    +	 */
    +#if	defined(__i386__) || defined(__amd64__)
    +	switch (cputype) {
    +		/*
    +		 * Intel Corei7 and Westmere processors.
    +		 */
    +	case PMC_CPU_INTEL_COREI7:
    +	case PMC_CPU_INTEL_WESTMERE:
    +		error = pmc_uncore_initialize(pmc_mdep, ncpus);
    +		break;
    +	default:
    +		break;
    +	}
    +#endif
     
       error:
     	if (error) {
    @@ -245,6 +268,8 @@ pmc_intel_finalize(struct pmc_mdep *md)
     	case PMC_CPU_INTEL_CORE:
     	case PMC_CPU_INTEL_CORE2:
     	case PMC_CPU_INTEL_CORE2EXTREME:
    +	case PMC_CPU_INTEL_COREI7:
    +	case PMC_CPU_INTEL_WESTMERE:
     		pmc_core_finalize(md);
     		break;
     
    @@ -267,4 +292,18 @@ pmc_intel_finalize(struct pmc_mdep *md)
     	default:
     		KASSERT(0, ("[intel,%d] unknown CPU type", __LINE__));
     	}
    +
    +	/*
    +	 * Uncore.
    +	 */
    +#if	defined(__i386__) || defined(__amd64__)
    +	switch (md->pmd_cputype) {
    +	case PMC_CPU_INTEL_COREI7:
    +	case PMC_CPU_INTEL_WESTMERE:
    +		pmc_uncore_finalize(md);
    +		break;
    +	default:
    +		break;
    +	}
    +#endif
     }
    diff --git a/sys/dev/hwpmc/hwpmc_uncore.c b/sys/dev/hwpmc/hwpmc_uncore.c
    new file mode 100644
    index 00000000000..36cd95c09c4
    --- /dev/null
    +++ b/sys/dev/hwpmc/hwpmc_uncore.c
    @@ -0,0 +1,1121 @@
    +/*-
    + * Copyright (c) 2010 Fabien Thomas
    + * 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.
    + */
    +
    +/*
    + * Intel Uncore PMCs.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#define	UCF_PMC_CAPS \
    +	(PMC_CAP_READ | PMC_CAP_WRITE)
    +
    +#define	UCP_PMC_CAPS \
    +    (PMC_CAP_EDGE | PMC_CAP_THRESHOLD | PMC_CAP_READ | PMC_CAP_WRITE | \
    +    PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_PRECISE)
    +
    +static enum pmc_cputype	uncore_cputype;
    +
    +struct uncore_cpu {
    +	volatile uint32_t	pc_resync;
    +	volatile uint32_t	pc_ucfctrl;	/* Fixed function control. */
    +	volatile uint64_t	pc_globalctrl;	/* Global control register. */
    +	struct pmc_hw		pc_uncorepmcs[];
    +};
    +
    +static struct uncore_cpu **uncore_pcpu;
    +
    +static uint64_t uncore_pmcmask;
    +
    +static int uncore_ucf_ri;		/* relative index of fixed counters */
    +static int uncore_ucf_width;
    +static int uncore_ucf_npmc;
    +
    +static int uncore_ucp_width;
    +static int uncore_ucp_npmc;
    +
    +static int
    +uncore_pcpu_noop(struct pmc_mdep *md, int cpu)
    +{
    +	(void) md;
    +	(void) cpu;
    +	return (0);
    +}
    +
    +static int
    +uncore_pcpu_init(struct pmc_mdep *md, int cpu)
    +{
    +	struct pmc_cpu *pc;
    +	struct uncore_cpu *cc;
    +	struct pmc_hw *phw;
    +	int uncore_ri, n, npmc;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[ucf,%d] insane cpu number %d", __LINE__, cpu));
    +
    +	PMCDBG(MDP,INI,1,"uncore-init cpu=%d", cpu);
    +
    +	uncore_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_ri;
    +	npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_num;
    +	npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF].pcd_num;
    +
    +	cc = malloc(sizeof(struct uncore_cpu) + npmc * sizeof(struct pmc_hw),
    +	    M_PMC, M_WAITOK | M_ZERO);
    +
    +	uncore_pcpu[cpu] = cc;
    +	pc = pmc_pcpu[cpu];
    +
    +	KASSERT(pc != NULL && cc != NULL,
    +	    ("[uncore,%d] NULL per-cpu structures cpu=%d", __LINE__, cpu));
    +
    +	for (n = 0, phw = cc->pc_uncorepmcs; n < npmc; n++, phw++) {
    +		phw->phw_state 	  = PMC_PHW_FLAG_IS_ENABLED |
    +		    PMC_PHW_CPU_TO_STATE(cpu) |
    +		    PMC_PHW_INDEX_TO_STATE(n + uncore_ri);
    +		phw->phw_pmc	  = NULL;
    +		pc->pc_hwpmcs[n + uncore_ri]  = phw;
    +	}
    +
    +	return (0);
    +}
    +
    +static int
    +uncore_pcpu_fini(struct pmc_mdep *md, int cpu)
    +{
    +	int uncore_ri, n, npmc;
    +	struct pmc_cpu *pc;
    +	struct uncore_cpu *cc;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] insane cpu number (%d)", __LINE__, cpu));
    +
    +	PMCDBG(MDP,INI,1,"uncore-pcpu-fini cpu=%d", cpu);
    +
    +	if ((cc = uncore_pcpu[cpu]) == NULL)
    +		return (0);
    +
    +	uncore_pcpu[cpu] = NULL;
    +
    +	pc = pmc_pcpu[cpu];
    +
    +	KASSERT(pc != NULL, ("[uncore,%d] NULL per-cpu %d state", __LINE__,
    +		cpu));
    +
    +	npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_num;
    +	uncore_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_ri;
    +
    +	for (n = 0; n < npmc; n++)
    +		wrmsr(UCP_EVSEL0 + n, 0);
    +
    +	wrmsr(UCF_CTRL, 0);
    +	npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF].pcd_num;
    +
    +	for (n = 0; n < npmc; n++)
    +		pc->pc_hwpmcs[n + uncore_ri] = NULL;
    +
    +	free(cc, M_PMC);
    +
    +	return (0);
    +}
    +
    +/*
    + * Fixed function counters.
    + */
    +
    +static pmc_value_t
    +ucf_perfctr_value_to_reload_count(pmc_value_t v)
    +{
    +	v &= (1ULL << uncore_ucf_width) - 1;
    +	return (1ULL << uncore_ucf_width) - v;
    +}
    +
    +static pmc_value_t
    +ucf_reload_count_to_perfctr_value(pmc_value_t rlc)
    +{
    +	return (1ULL << uncore_ucf_width) - rlc;
    +}
    +
    +static int
    +ucf_allocate_pmc(int cpu, int ri, struct pmc *pm,
    +    const struct pmc_op_pmcallocate *a)
    +{
    +	enum pmc_event ev;
    +	uint32_t caps, flags;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal CPU %d", __LINE__, cpu));
    +
    +	PMCDBG(MDP,ALL,1, "ucf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps);
    +
    +	if (ri < 0 || ri > uncore_ucf_npmc)
    +		return (EINVAL);
    +
    +	caps = a->pm_caps;
    +
    +	if (a->pm_class != PMC_CLASS_UCF ||
    +	    (caps & UCF_PMC_CAPS) != caps)
    +		return (EINVAL);
    +
    +	ev = pm->pm_event;
    +	if (ev < PMC_EV_UCF_FIRST || ev > PMC_EV_UCF_LAST)
    +		return (EINVAL);
    +
    +	flags = UCF_EN;
    +
    +	pm->pm_md.pm_ucf.pm_ucf_ctrl = (flags << (ri * 4));
    +
    +	PMCDBG(MDP,ALL,2, "ucf-allocate config=0x%jx",
    +	    (uintmax_t) pm->pm_md.pm_ucf.pm_ucf_ctrl);
    +
    +	return (0);
    +}
    +
    +static int
    +ucf_config_pmc(int cpu, int ri, struct pmc *pm)
    +{
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal CPU %d", __LINE__, cpu));
    +
    +	KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	PMCDBG(MDP,CFG,1, "ucf-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
    +
    +	KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__,
    +	    cpu));
    +
    +	uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc = pm;
    +
    +	return (0);
    +}
    +
    +static int
    +ucf_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc)
    +{
    +	int error;
    +	struct pmc_hw *phw;
    +	char ucf_name[PMC_NAME_MAX];
    +
    +	phw = &uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri];
    +
    +	(void) snprintf(ucf_name, sizeof(ucf_name), "UCF-%d", ri);
    +	if ((error = copystr(ucf_name, pi->pm_name, PMC_NAME_MAX,
    +	    NULL)) != 0)
    +		return (error);
    +
    +	pi->pm_class = PMC_CLASS_UCF;
    +
    +	if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
    +		pi->pm_enabled = TRUE;
    +		*ppmc          = phw->phw_pmc;
    +	} else {
    +		pi->pm_enabled = FALSE;
    +		*ppmc          = NULL;
    +	}
    +
    +	return (0);
    +}
    +
    +static int
    +ucf_get_config(int cpu, int ri, struct pmc **ppm)
    +{
    +	*ppm = uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc;
    +
    +	return (0);
    +}
    +
    +static int
    +ucf_read_pmc(int cpu, int ri, pmc_value_t *v)
    +{
    +	struct pmc *pm;
    +	pmc_value_t tmp;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	pm = uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc;
    +
    +	KASSERT(pm,
    +	    ("[uncore,%d] cpu %d ri %d(%d) pmc not configured", __LINE__, cpu,
    +		ri, ri + uncore_ucf_ri));
    +
    +	tmp = rdmsr(UCF_CTR0 + ri);
    +
    +	if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
    +		*v = ucf_perfctr_value_to_reload_count(tmp);
    +	else
    +		*v = tmp;
    +
    +	PMCDBG(MDP,REA,1, "ucf-read cpu=%d ri=%d -> v=%jx", cpu, ri, *v);
    +
    +	return (0);
    +}
    +
    +static int
    +ucf_release_pmc(int cpu, int ri, struct pmc *pmc)
    +{
    +	PMCDBG(MDP,REL,1, "ucf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc);
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	KASSERT(uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc == NULL,
    +	    ("[uncore,%d] PHW pmc non-NULL", __LINE__));
    +
    +	return (0);
    +}
    +
    +static int
    +ucf_start_pmc(int cpu, int ri)
    +{
    +	struct pmc *pm;
    +	struct uncore_cpu *ucfc;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	PMCDBG(MDP,STA,1,"ucf-start cpu=%d ri=%d", cpu, ri);
    +
    +	ucfc = uncore_pcpu[cpu];
    +	pm = ucfc->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc;
    +
    +	ucfc->pc_ucfctrl |= pm->pm_md.pm_ucf.pm_ucf_ctrl;
    +
    +	wrmsr(UCF_CTRL, ucfc->pc_ucfctrl);
    +
    +	do {
    +		ucfc->pc_resync = 0;
    +		ucfc->pc_globalctrl |= (1ULL << (ri + UCF_OFFSET));
    +		wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl);
    +	} while (ucfc->pc_resync != 0);
    +
    +	PMCDBG(MDP,STA,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)",
    +	    ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL),
    +	    ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL));
    +
    +	return (0);
    +}
    +
    +static int
    +ucf_stop_pmc(int cpu, int ri)
    +{
    +	uint32_t fc;
    +	struct uncore_cpu *ucfc;
    +
    +	PMCDBG(MDP,STO,1,"ucf-stop cpu=%d ri=%d", cpu, ri);
    +
    +	ucfc = uncore_pcpu[cpu];
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	fc = (UCF_MASK << (ri * 4));
    +
    +	ucfc->pc_ucfctrl &= ~fc;
    +
    +	PMCDBG(MDP,STO,1,"ucf-stop ucfctrl=%x", ucfc->pc_ucfctrl);
    +	wrmsr(UCF_CTRL, ucfc->pc_ucfctrl);
    +
    +	do {
    +		ucfc->pc_resync = 0;
    +		ucfc->pc_globalctrl &= ~(1ULL << (ri + UCF_OFFSET));
    +		wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl);
    +	} while (ucfc->pc_resync != 0);
    +
    +	PMCDBG(MDP,STO,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)",
    +	    ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL),
    +	    ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL));
    +
    +	return (0);
    +}
    +
    +static int
    +ucf_write_pmc(int cpu, int ri, pmc_value_t v)
    +{
    +	struct uncore_cpu *cc;
    +	struct pmc *pm;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucf_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	cc = uncore_pcpu[cpu];
    +	pm = cc->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc;
    +
    +	KASSERT(pm,
    +	    ("[uncore,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri));
    +
    +	if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
    +		v = ucf_reload_count_to_perfctr_value(v);
    +
    +	wrmsr(UCF_CTRL, 0);	/* Turn off fixed counters */
    +	wrmsr(UCF_CTR0 + ri, v);
    +	wrmsr(UCF_CTRL, cc->pc_ucfctrl);
    +
    +	PMCDBG(MDP,WRI,1, "ucf-write cpu=%d ri=%d v=%jx ucfctrl=%jx ",
    +	    cpu, ri, v, (uintmax_t) rdmsr(UCF_CTRL));
    +
    +	return (0);
    +}
    +
    +
    +static void
    +ucf_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth)
    +{
    +	struct pmc_classdep *pcd;
    +
    +	KASSERT(md != NULL, ("[ucf,%d] md is NULL", __LINE__));
    +
    +	PMCDBG(MDP,INI,1, "%s", "ucf-initialize");
    +
    +	pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF];
    +
    +	pcd->pcd_caps	= UCF_PMC_CAPS;
    +	pcd->pcd_class	= PMC_CLASS_UCF;
    +	pcd->pcd_num	= npmc;
    +	pcd->pcd_ri	= md->pmd_npmc;
    +	pcd->pcd_width	= pmcwidth;
    +
    +	pcd->pcd_allocate_pmc	= ucf_allocate_pmc;
    +	pcd->pcd_config_pmc	= ucf_config_pmc;
    +	pcd->pcd_describe	= ucf_describe;
    +	pcd->pcd_get_config	= ucf_get_config;
    +	pcd->pcd_get_msr	= NULL;
    +	pcd->pcd_pcpu_fini	= uncore_pcpu_noop;
    +	pcd->pcd_pcpu_init	= uncore_pcpu_noop;
    +	pcd->pcd_read_pmc	= ucf_read_pmc;
    +	pcd->pcd_release_pmc	= ucf_release_pmc;
    +	pcd->pcd_start_pmc	= ucf_start_pmc;
    +	pcd->pcd_stop_pmc	= ucf_stop_pmc;
    +	pcd->pcd_write_pmc	= ucf_write_pmc;
    +
    +	md->pmd_npmc	       += npmc;
    +}
    +
    +/*
    + * Intel programmable PMCs.
    + */
    +
    +/*
    + * Event descriptor tables.
    + *
    + * For each event id, we track:
    + *
    + * 1. The CPUs that the event is valid for.
    + *
    + * 2. If the event uses a fixed UMASK, the value of the umask field.
    + *    If the event doesn't use a fixed UMASK, a mask of legal bits
    + *    to check against.
    + */
    +
    +struct ucp_event_descr {
    +	enum pmc_event	ucp_ev;
    +	unsigned char	ucp_evcode;
    +	unsigned char	ucp_umask;
    +	unsigned char	ucp_flags;
    +};
    +
    +#define	UCP_F_I7	(1 << 0)	/* CPU: Core i7 */
    +#define	UCP_F_WM	(1 << 1)	/* CPU: Westmere */
    +#define	UCP_F_FM	(1 << 2)	/* Fixed mask */
    +
    +#define	UCP_F_ALLCPUS					\
    +    (UCP_F_I7 | UCP_F_WM)
    +
    +#define	UCP_F_CMASK		0xFF000000
    +
    +static struct ucp_event_descr ucp_events[] = {
    +#undef UCPDESCR
    +#define	UCPDESCR(N,EV,UM,FLAGS) {					\
    +	.ucp_ev = PMC_EV_UCP_EVENT_##N,					\
    +	.ucp_evcode = (EV),						\
    +	.ucp_umask = (UM),						\
    +	.ucp_flags = (FLAGS)						\
    +	}
    +
    +    UCPDESCR(00H_01H, 0x00, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(00H_02H, 0x00, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(00H_04H, 0x00, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(01H_01H, 0x01, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(01H_02H, 0x01, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(01H_04H, 0x01, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(02H_01H, 0x02, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(03H_01H, 0x03, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(03H_02H, 0x03, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(03H_04H, 0x03, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(03H_08H, 0x03, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(03H_10H, 0x03, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(03H_20H, 0x03, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(03H_40H, 0x03, 0x40, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(04H_01H, 0x04, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(04H_02H, 0x04, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(04H_04H, 0x04, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(04H_08H, 0x04, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(04H_10H, 0x04, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(05H_01H, 0x05, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(05H_02H, 0x05, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(05H_04H, 0x05, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(06H_01H, 0x06, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(06H_02H, 0x06, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(06H_04H, 0x06, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(06H_08H, 0x06, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(06H_10H, 0x06, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(06H_20H, 0x06, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(07H_01H, 0x07, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(07H_02H, 0x07, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(07H_04H, 0x07, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(07H_08H, 0x07, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(07H_10H, 0x07, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(07H_20H, 0x07, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(07H_24H, 0x07, 0x24, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(08H_01H, 0x08, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(08H_02H, 0x08, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(08H_04H, 0x08, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(08H_03H, 0x08, 0x03, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(09H_01H, 0x09, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(09H_02H, 0x09, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(09H_04H, 0x09, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(09H_03H, 0x09, 0x03, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(0AH_01H, 0x0A, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(0AH_02H, 0x0A, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(0AH_04H, 0x0A, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(0AH_08H, 0x0A, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(0AH_0FH, 0x0A, 0x0F, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(0BH_01H, 0x0B, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(0BH_02H, 0x0B, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(0BH_04H, 0x0B, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(0BH_08H, 0x0B, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(0BH_10H, 0x0B, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(0BH_1FH, 0x0B, 0x1F, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(0CH_01H, 0x0C, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(0CH_02H, 0x0C, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(0CH_04H, 0x0C, 0x04, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(0CH_08H, 0x0C, 0x08, UCP_F_FM | UCP_F_WM),
    +
    +    UCPDESCR(20H_01H, 0x20, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(20H_02H, 0x20, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(20H_04H, 0x20, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(20H_08H, 0x20, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(20H_10H, 0x20, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(20H_20H, 0x20, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(21H_01H, 0x21, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(21H_02H, 0x21, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(21H_04H, 0x21, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(22H_01H, 0x22, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(22H_02H, 0x22, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(22H_04H, 0x22, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(23H_01H, 0x23, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(23H_02H, 0x23, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(23H_04H, 0x23, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(24H_02H, 0x24, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(24H_04H, 0x24, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(25H_01H, 0x25, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(25H_02H, 0x25, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(25H_04H, 0x25, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(26H_01H, 0x26, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(27H_01H, 0x27, 0x01, UCP_F_FM | UCP_F_I7),
    +    UCPDESCR(27H_02H, 0x27, 0x02, UCP_F_FM | UCP_F_I7),
    +    UCPDESCR(27H_04H, 0x27, 0x04, UCP_F_FM | UCP_F_I7),
    +    UCPDESCR(27H_08H, 0x27, 0x08, UCP_F_FM | UCP_F_I7),
    +    UCPDESCR(27H_10H, 0x27, 0x10, UCP_F_FM | UCP_F_I7),
    +    UCPDESCR(27H_20H, 0x27, 0x20, UCP_F_FM | UCP_F_I7),
    +
    +    UCPDESCR(28H_01H, 0x28, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(28H_02H, 0x28, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(28H_04H, 0x28, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(28H_08H, 0x28, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(28H_10H, 0x28, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(28H_20H, 0x28, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(29H_01H, 0x29, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(29H_02H, 0x29, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(29H_04H, 0x29, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(29H_08H, 0x29, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(29H_10H, 0x29, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(29H_20H, 0x29, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(2AH_01H, 0x2A, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2AH_02H, 0x2A, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2AH_04H, 0x2A, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2AH_07H, 0x2A, 0x07, UCP_F_FM | UCP_F_WM),
    +
    +    UCPDESCR(2BH_01H, 0x2B, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2BH_02H, 0x2B, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2BH_04H, 0x2B, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2BH_07H, 0x2B, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(2CH_01H, 0x2C, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2CH_02H, 0x2C, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2CH_04H, 0x2C, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2CH_07H, 0x2C, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(2DH_01H, 0x2D, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2DH_02H, 0x2D, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2DH_04H, 0x2D, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2DH_07H, 0x2D, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(2EH_01H, 0x2E, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2EH_02H, 0x2E, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2EH_04H, 0x2E, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2EH_07H, 0x2E, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(2FH_01H, 0x2F, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2FH_02H, 0x2F, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2FH_04H, 0x2F, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2FH_07H, 0x2F, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2FH_08H, 0x2F, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2FH_10H, 0x2F, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2FH_20H, 0x2F, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(2FH_38H, 0x2F, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(30H_01H, 0x30, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(30H_02H, 0x30, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(30H_04H, 0x30, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(30H_07H, 0x30, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(31H_01H, 0x31, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(31H_02H, 0x31, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(31H_04H, 0x31, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(31H_07H, 0x31, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(32H_01H, 0x32, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(32H_02H, 0x32, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(32H_04H, 0x32, 0x04, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(32H_07H, 0x32, 0x07, UCP_F_FM | UCP_F_WM),
    +
    +    UCPDESCR(33H_01H, 0x33, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(33H_02H, 0x33, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(33H_04H, 0x33, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(33H_07H, 0x33, 0x07, UCP_F_FM | UCP_F_WM),
    +
    +    UCPDESCR(34H_01H, 0x34, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(34H_02H, 0x34, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(34H_04H, 0x34, 0x04, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(34H_08H, 0x34, 0x08, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(34H_10H, 0x34, 0x10, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(34H_20H, 0x34, 0x20, UCP_F_FM | UCP_F_WM),
    +
    +    UCPDESCR(35H_01H, 0x35, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(35H_02H, 0x35, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(35H_04H, 0x35, 0x04, UCP_F_FM | UCP_F_WM),
    +
    +    UCPDESCR(40H_01H, 0x40, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(40H_02H, 0x40, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(40H_04H, 0x40, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(40H_08H, 0x40, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(40H_10H, 0x40, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(40H_20H, 0x40, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(40H_07H, 0x40, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(40H_38H, 0x40, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(41H_01H, 0x41, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(41H_02H, 0x41, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(41H_04H, 0x41, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(41H_08H, 0x41, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(41H_10H, 0x41, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(41H_20H, 0x41, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(41H_07H, 0x41, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(41H_38H, 0x41, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(42H_01H, 0x42, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(42H_02H, 0x42, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(42H_04H, 0x42, 0x04, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(42H_08H, 0x42, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(43H_01H, 0x43, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(43H_02H, 0x43, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(60H_01H, 0x60, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(60H_02H, 0x60, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(60H_04H, 0x60, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(61H_01H, 0x61, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(61H_02H, 0x61, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(61H_04H, 0x61, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(62H_01H, 0x62, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(62H_02H, 0x62, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(62H_04H, 0x62, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(63H_01H, 0x63, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(63H_02H, 0x63, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(63H_04H, 0x63, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(63H_08H, 0x63, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(63H_10H, 0x63, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(63H_20H, 0x63, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(64H_01H, 0x64, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(64H_02H, 0x64, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(64H_04H, 0x64, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(64H_08H, 0x64, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(64H_10H, 0x64, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(64H_20H, 0x64, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(65H_01H, 0x65, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(65H_02H, 0x65, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(65H_04H, 0x65, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(66H_01H, 0x66, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(66H_02H, 0x66, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +    UCPDESCR(66H_04H, 0x66, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
    +
    +    UCPDESCR(67H_01H, 0x67, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(80H_01H, 0x80, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(80H_02H, 0x80, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(80H_04H, 0x80, 0x04, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(80H_08H, 0x80, 0x08, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(81H_01H, 0x81, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(81H_02H, 0x81, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(81H_04H, 0x81, 0x04, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(81H_08H, 0x81, 0x08, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(82H_01H, 0x82, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(83H_01H, 0x83, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(83H_02H, 0x83, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(83H_04H, 0x83, 0x04, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(83H_08H, 0x83, 0x08, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(84H_01H, 0x84, 0x01, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(84H_02H, 0x84, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(84H_04H, 0x84, 0x04, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(84H_08H, 0x84, 0x08, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(85H_02H, 0x85, 0x02, UCP_F_FM | UCP_F_WM),
    +    UCPDESCR(86H_01H, 0x86, 0x01, UCP_F_FM | UCP_F_WM)
    +};
    +
    +static const int nucp_events = sizeof(ucp_events) / sizeof(ucp_events[0]);
    +
    +static pmc_value_t
    +ucp_perfctr_value_to_reload_count(pmc_value_t v)
    +{
    +	v &= (1ULL << uncore_ucp_width) - 1;
    +	return (1ULL << uncore_ucp_width) - v;
    +}
    +
    +static pmc_value_t
    +ucp_reload_count_to_perfctr_value(pmc_value_t rlc)
    +{
    +	return (1ULL << uncore_ucp_width) - rlc;
    +}
    +
    +static int
    +ucp_allocate_pmc(int cpu, int ri, struct pmc *pm,
    +    const struct pmc_op_pmcallocate *a)
    +{
    +	int n;
    +	enum pmc_event ev;
    +	struct ucp_event_descr *ie;
    +	uint32_t caps, config, cpuflag, evsel;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal CPU %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
    +	    ("[uncore,%d] illegal row-index value %d", __LINE__, ri));
    +
    +	/* check requested capabilities */
    +	caps = a->pm_caps;
    +	if ((UCP_PMC_CAPS & caps) != caps)
    +		return (EPERM);
    +
    +	ev = pm->pm_event;
    +
    +	/*
    +	 * Look for an event descriptor with matching CPU and event id
    +	 * fields.
    +	 */
    +
    +	switch (uncore_cputype) {
    +	case PMC_CPU_INTEL_COREI7:
    +		cpuflag = UCP_F_I7;
    +		break;
    +	case PMC_CPU_INTEL_WESTMERE:
    +		cpuflag = UCP_F_WM;
    +		break;
    +	default:
    +		return (EINVAL);
    +	}
    +
    +	for (n = 0, ie = ucp_events; n < nucp_events; n++, ie++)
    +		if (ie->ucp_ev == ev && ie->ucp_flags & cpuflag)
    +			break;
    +
    +	if (n == nucp_events)
    +		return (EINVAL);
    +
    +	/*
    +	 * A matching event descriptor has been found, so start
    +	 * assembling the contents of the event select register.
    +	 */
    +	evsel = ie->ucp_evcode | UCP_EN;
    +
    +	config = a->pm_md.pm_ucp.pm_ucp_config & ~UCP_F_CMASK;
    +
    +	/*
    +	 * If the event uses a fixed umask value, reject any umask
    +	 * bits set by the user.
    +	 */
    +	if (ie->ucp_flags & UCP_F_FM) {
    +
    +		if (UCP_UMASK(config) != 0)
    +			return (EINVAL);
    +
    +		evsel |= (ie->ucp_umask << 8);
    +
    +	} else
    +		return (EINVAL);
    +
    +	if (caps & PMC_CAP_THRESHOLD)
    +		evsel |= (a->pm_md.pm_ucp.pm_ucp_config & UCP_F_CMASK);
    +	if (caps & PMC_CAP_EDGE)
    +		evsel |= UCP_EDGE;
    +	if (caps & PMC_CAP_INVERT)
    +		evsel |= UCP_INV;
    +
    +	pm->pm_md.pm_ucp.pm_ucp_evsel = evsel;
    +
    +	return (0);
    +}
    +
    +static int
    +ucp_config_pmc(int cpu, int ri, struct pmc *pm)
    +{
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal CPU %d", __LINE__, cpu));
    +
    +	KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	PMCDBG(MDP,CFG,1, "ucp-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
    +
    +	KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__,
    +	    cpu));
    +
    +	uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc = pm;
    +
    +	return (0);
    +}
    +
    +static int
    +ucp_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc)
    +{
    +	int error;
    +	struct pmc_hw *phw;
    +	char ucp_name[PMC_NAME_MAX];
    +
    +	phw = &uncore_pcpu[cpu]->pc_uncorepmcs[ri];
    +
    +	(void) snprintf(ucp_name, sizeof(ucp_name), "UCP-%d", ri);
    +	if ((error = copystr(ucp_name, pi->pm_name, PMC_NAME_MAX,
    +	    NULL)) != 0)
    +		return (error);
    +
    +	pi->pm_class = PMC_CLASS_UCP;
    +
    +	if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
    +		pi->pm_enabled = TRUE;
    +		*ppmc          = phw->phw_pmc;
    +	} else {
    +		pi->pm_enabled = FALSE;
    +		*ppmc          = NULL;
    +	}
    +
    +	return (0);
    +}
    +
    +static int
    +ucp_get_config(int cpu, int ri, struct pmc **ppm)
    +{
    +	*ppm = uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc;
    +
    +	return (0);
    +}
    +
    +static int
    +ucp_read_pmc(int cpu, int ri, pmc_value_t *v)
    +{
    +	struct pmc *pm;
    +	pmc_value_t tmp;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	pm = uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc;
    +
    +	KASSERT(pm,
    +	    ("[uncore,%d] cpu %d ri %d pmc not configured", __LINE__, cpu,
    +		ri));
    +
    +	tmp = rdmsr(UCP_PMC0 + ri);
    +	if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
    +		*v = ucp_perfctr_value_to_reload_count(tmp);
    +	else
    +		*v = tmp;
    +
    +	PMCDBG(MDP,REA,1, "ucp-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
    +	    ri, *v);
    +
    +	return (0);
    +}
    +
    +static int
    +ucp_release_pmc(int cpu, int ri, struct pmc *pm)
    +{
    +	(void) pm;
    +
    +	PMCDBG(MDP,REL,1, "ucp-release cpu=%d ri=%d pm=%p", cpu, ri,
    +	    pm);
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	KASSERT(uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc
    +	    == NULL, ("[uncore,%d] PHW pmc non-NULL", __LINE__));
    +
    +	return (0);
    +}
    +
    +static int
    +ucp_start_pmc(int cpu, int ri)
    +{
    +	struct pmc *pm;
    +	uint32_t evsel;
    +	struct uncore_cpu *cc;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal CPU value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
    +	    ("[uncore,%d] illegal row-index %d", __LINE__, ri));
    +
    +	cc = uncore_pcpu[cpu];
    +	pm = cc->pc_uncorepmcs[ri].phw_pmc;
    +
    +	KASSERT(pm,
    +	    ("[uncore,%d] starting cpu%d,ri%d with no pmc configured",
    +		__LINE__, cpu, ri));
    +
    +	PMCDBG(MDP,STA,1, "ucp-start cpu=%d ri=%d", cpu, ri);
    +
    +	evsel = pm->pm_md.pm_ucp.pm_ucp_evsel;
    +
    +	PMCDBG(MDP,STA,2, "ucp-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
    +	    cpu, ri, UCP_EVSEL0 + ri, evsel);
    +
    +	wrmsr(UCP_EVSEL0 + ri, evsel);
    +
    +	do {
    +		cc->pc_resync = 0;
    +		cc->pc_globalctrl |= (1ULL << ri);
    +		wrmsr(UC_GLOBAL_CTRL, cc->pc_globalctrl);
    +	} while (cc->pc_resync != 0);
    +
    +	return (0);
    +}
    +
    +static int
    +ucp_stop_pmc(int cpu, int ri)
    +{
    +	struct pmc *pm;
    +	struct uncore_cpu *cc;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
    +	    ("[uncore,%d] illegal row index %d", __LINE__, ri));
    +
    +	cc = uncore_pcpu[cpu];
    +	pm = cc->pc_uncorepmcs[ri].phw_pmc;
    +
    +	KASSERT(pm,
    +	    ("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
    +		cpu, ri));
    +
    +	PMCDBG(MDP,STO,1, "ucp-stop cpu=%d ri=%d", cpu, ri);
    +
    +	wrmsr(UCP_EVSEL0 + ri, 0);	/* stop hw */
    +
    +	do {
    +		cc->pc_resync = 0;
    +		cc->pc_globalctrl &= ~(1ULL << ri);
    +		wrmsr(UC_GLOBAL_CTRL, cc->pc_globalctrl);
    +	} while (cc->pc_resync != 0);
    +
    +	return (0);
    +}
    +
    +static int
    +ucp_write_pmc(int cpu, int ri, pmc_value_t v)
    +{
    +	struct pmc *pm;
    +	struct uncore_cpu *cc;
    +
    +	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
    +	    ("[uncore,%d] illegal cpu value %d", __LINE__, cpu));
    +	KASSERT(ri >= 0 && ri < uncore_ucp_npmc,
    +	    ("[uncore,%d] illegal row index %d", __LINE__, ri));
    +
    +	cc = uncore_pcpu[cpu];
    +	pm = cc->pc_uncorepmcs[ri].phw_pmc;
    +
    +	KASSERT(pm,
    +	    ("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
    +		cpu, ri));
    +
    +	PMCDBG(MDP,WRI,1, "ucp-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
    +	    UCP_PMC0 + ri, v);
    +
    +	if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
    +		v = ucp_reload_count_to_perfctr_value(v);
    +
    +	/*
    +	 * Write the new value to the counter.  The counter will be in
    +	 * a stopped state when the pcd_write() entry point is called.
    +	 */
    +
    +	wrmsr(UCP_PMC0 + ri, v);
    +
    +	return (0);
    +}
    +
    +
    +static void
    +ucp_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth)
    +{
    +	struct pmc_classdep *pcd;
    +
    +	KASSERT(md != NULL, ("[ucp,%d] md is NULL", __LINE__));
    +
    +	PMCDBG(MDP,INI,1, "%s", "ucp-initialize");
    +
    +	pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP];
    +
    +	pcd->pcd_caps	= UCP_PMC_CAPS;
    +	pcd->pcd_class	= PMC_CLASS_UCP;
    +	pcd->pcd_num	= npmc;
    +	pcd->pcd_ri	= md->pmd_npmc;
    +	pcd->pcd_width	= pmcwidth;
    +
    +	pcd->pcd_allocate_pmc	= ucp_allocate_pmc;
    +	pcd->pcd_config_pmc	= ucp_config_pmc;
    +	pcd->pcd_describe	= ucp_describe;
    +	pcd->pcd_get_config	= ucp_get_config;
    +	pcd->pcd_get_msr	= NULL;
    +	pcd->pcd_pcpu_fini	= uncore_pcpu_fini;
    +	pcd->pcd_pcpu_init	= uncore_pcpu_init;
    +	pcd->pcd_read_pmc	= ucp_read_pmc;
    +	pcd->pcd_release_pmc	= ucp_release_pmc;
    +	pcd->pcd_start_pmc	= ucp_start_pmc;
    +	pcd->pcd_stop_pmc	= ucp_stop_pmc;
    +	pcd->pcd_write_pmc	= ucp_write_pmc;
    +
    +	md->pmd_npmc	       += npmc;
    +}
    +
    +int
    +pmc_uncore_initialize(struct pmc_mdep *md, int maxcpu)
    +{
    +	uncore_cputype = md->pmd_cputype;
    +	uncore_pmcmask = 0;
    +
    +	/*
    +	 * Initialize programmable counters.
    +	 */
    +
    +	uncore_ucp_npmc  = 8;
    +	uncore_ucp_width = 48;
    +
    +	uncore_pmcmask |= ((1ULL << uncore_ucp_npmc) - 1);
    +
    +	ucp_initialize(md, maxcpu, uncore_ucp_npmc, uncore_ucp_width);
    +
    +	/*
    +	 * Initialize fixed function counters, if present.
    +	 */
    +	uncore_ucf_ri = uncore_ucp_npmc;
    +	uncore_ucf_npmc  = 1;
    +	uncore_ucf_width = 48;
    +
    +	ucf_initialize(md, maxcpu, uncore_ucf_npmc, uncore_ucf_width);
    +	uncore_pmcmask |= ((1ULL << uncore_ucf_npmc) - 1) << UCF_OFFSET;
    +
    +	PMCDBG(MDP,INI,1,"uncore-init pmcmask=0x%jx ucfri=%d", uncore_pmcmask,
    +	    uncore_ucf_ri);
    +
    +	uncore_pcpu = malloc(sizeof(struct uncore_cpu **) * maxcpu, M_PMC,
    +	    M_ZERO | M_WAITOK);
    +
    +	return (0);
    +}
    +
    +void
    +pmc_uncore_finalize(struct pmc_mdep *md)
    +{
    +	PMCDBG(MDP,INI,1, "%s", "uncore-finalize");
    +
    +	free(uncore_pcpu, M_PMC);
    +	uncore_pcpu = NULL;
    +}
    diff --git a/sys/dev/hwpmc/hwpmc_uncore.h b/sys/dev/hwpmc/hwpmc_uncore.h
    new file mode 100644
    index 00000000000..2be34db3d34
    --- /dev/null
    +++ b/sys/dev/hwpmc/hwpmc_uncore.h
    @@ -0,0 +1,120 @@
    +/*-
    + * Copyright (c) 2010 Fabien Thomas
    + * 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 _DEV_HWPMC_UNCORE_H_
    +#define	_DEV_HWPMC_UNCORE_H_ 1
    +
    +/*
    + * Fixed-function PMCs.
    + */
    +struct pmc_md_ucf_op_pmcallocate {
    +	uint16_t	pm_ucf_flags;	/* additional flags */
    +};
    +
    +#define	UCF_EN		0x1
    +#define	UCF_PMI		0x4
    +
    +/*
    + * Programmable PMCs.
    + */
    +struct pmc_md_ucp_op_pmcallocate {
    +	uint32_t	pm_ucp_config;
    +};
    +
    +#define	UCP_EVSEL(C)	((C) & 0xFF)
    +#define	UCP_UMASK(C)	((C) & 0xFF00)
    +#define	UCP_CTRR	(1 << 17)
    +#define	UCP_EDGE	(1 << 18)
    +#define	UCP_INT		(1 << 20)
    +#define	UCP_EN		(1 << 22)
    +#define	UCP_INV		(1 << 23)
    +#define	UCP_CMASK(C)	(((C) & 0xFF) << 24)
    +
    +#ifdef	_KERNEL
    +
    +#define	DCTL_FLAG_UNC_PMI	(1ULL << 13)
    +
    +/*
    + * Fixed-function counters.
    + */
    +
    +#define	UCF_MASK				0xF
    +
    +#define	UCF_CTR0				0x394
    +
    +#define	UCF_OFFSET				32
    +#define	UCF_CTRL				0x395
    +
    +/*
    + * Programmable counters.
    + */
    +
    +#define	UCP_PMC0				0x3B0
    +#define	UCP_EVSEL0				0x3C0
    +#define UCP_OPCODE_MATCH			0x396
    +
    +/*
    + * Simplified programming interface in Intel Performance Architecture
    + * v2 and later.
    + */
    +
    +#define	UC_GLOBAL_STATUS			0x392
    +#define	UC_GLOBAL_CTRL				0x391
    +#define	UC_GLOBAL_OVF_CTRL			0x393
    +
    +#define	UC_GLOBAL_STATUS_FLAG_CLRCHG		(1ULL << 63)
    +#define	UC_GLOBAL_STATUS_FLAG_OVFPMI		(1ULL << 61)
    +#define	UC_GLOBAL_CTRL_FLAG_FRZ			(1ULL << 63)
    +#define	UC_GLOBAL_CTRL_FLAG_ENPMICORE0		(1ULL << 48)
    +
    +struct pmc_md_ucf_pmc {
    +	uint64_t	pm_ucf_ctrl;
    +};
    +
    +struct pmc_md_ucp_pmc {
    +	uint32_t	pm_ucp_evsel;
    +};
    +
    +/*
    + * Prototypes.
    + */
    +
    +int	pmc_uncore_initialize(struct pmc_mdep *_md, int _maxcpu);
    +void	pmc_uncore_finalize(struct pmc_mdep *_md);
    +
    +void	pmc_uncore_mark_started(int _cpu, int _pmc);
    +
    +int	pmc_ucf_initialize(struct pmc_mdep *_md, int _maxcpu, int _npmc, int _width);
    +void	pmc_ucf_finalize(struct pmc_mdep *_md);
    +
    +int	pmc_ucp_initialize(struct pmc_mdep *_md, int _maxcpu, int _npmc, int _width,
    +	    int _flags);
    +void	pmc_ucp_finalize(struct pmc_mdep *_md);
    +
    +#endif	/* _KERNEL */
    +#endif	/* _DEV_HWPMC_UNCORE_H */
    diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
    index e7bc3497af2..a2b2529a640 100644
    --- a/sys/dev/hwpmc/pmc_events.h
    +++ b/sys/dev/hwpmc/pmc_events.h
    @@ -468,8 +468,10 @@ __PMC_EV_ALIAS("unhalted-reference-cycles", IAF_CPU_CLK_UNHALTED_REF)
      * the CPU model happens inside hwpmc(4).
      */
     #define	__PMC_EV_IAP()				\
    +__PMC_EV(IAP, EVENT_02H_01H)			\
     __PMC_EV(IAP, EVENT_02H_81H)			\
     __PMC_EV(IAP, EVENT_03H_00H)			\
    +__PMC_EV(IAP, EVENT_03H_01H)			\
     __PMC_EV(IAP, EVENT_03H_02H)			\
     __PMC_EV(IAP, EVENT_03H_04H)			\
     __PMC_EV(IAP, EVENT_03H_08H)			\
    @@ -478,9 +480,18 @@ __PMC_EV(IAP, EVENT_03H_20H)			\
     __PMC_EV(IAP, EVENT_04H_00H)			\
     __PMC_EV(IAP, EVENT_04H_01H)			\
     __PMC_EV(IAP, EVENT_04H_02H)			\
    +__PMC_EV(IAP, EVENT_04H_07H)			\
     __PMC_EV(IAP, EVENT_04H_08H)			\
     __PMC_EV(IAP, EVENT_05H_00H)			\
    +__PMC_EV(IAP, EVENT_05H_01H)			\
    +__PMC_EV(IAP, EVENT_05H_02H)			\
    +__PMC_EV(IAP, EVENT_05H_03H)			\
     __PMC_EV(IAP, EVENT_06H_00H)			\
    +__PMC_EV(IAP, EVENT_06H_01H)			\
    +__PMC_EV(IAP, EVENT_06H_02H)			\
    +__PMC_EV(IAP, EVENT_06H_04H)			\
    +__PMC_EV(IAP, EVENT_06H_08H)			\
    +__PMC_EV(IAP, EVENT_06H_0FH)			\
     __PMC_EV(IAP, EVENT_07H_00H)			\
     __PMC_EV(IAP, EVENT_07H_01H)			\
     __PMC_EV(IAP, EVENT_07H_02H)			\
    @@ -495,41 +506,126 @@ __PMC_EV(IAP, EVENT_08H_06H)			\
     __PMC_EV(IAP, EVENT_08H_07H)			\
     __PMC_EV(IAP, EVENT_08H_08H)			\
     __PMC_EV(IAP, EVENT_08H_09H)			\
    +__PMC_EV(IAP, EVENT_08H_10H)			\
    +__PMC_EV(IAP, EVENT_08H_20H)			\
    +__PMC_EV(IAP, EVENT_08H_40H)			\
    +__PMC_EV(IAP, EVENT_08H_80H)			\
     __PMC_EV(IAP, EVENT_09H_01H)			\
     __PMC_EV(IAP, EVENT_09H_02H)			\
    +__PMC_EV(IAP, EVENT_09H_04H)			\
    +__PMC_EV(IAP, EVENT_09H_08H)			\
    +__PMC_EV(IAP, EVENT_0BH_01H)			\
    +__PMC_EV(IAP, EVENT_0BH_02H)			\
    +__PMC_EV(IAP, EVENT_0BH_10H)			\
     __PMC_EV(IAP, EVENT_0CH_01H)			\
     __PMC_EV(IAP, EVENT_0CH_02H)			\
     __PMC_EV(IAP, EVENT_0CH_03H)			\
    +__PMC_EV(IAP, EVENT_0EH_01H)			\
    +__PMC_EV(IAP, EVENT_0EH_02H)			\
    +__PMC_EV(IAP, EVENT_0FH_01H)			\
    +__PMC_EV(IAP, EVENT_0FH_02H)			\
    +__PMC_EV(IAP, EVENT_0FH_08H)			\
    +__PMC_EV(IAP, EVENT_0FH_10H)			\
    +__PMC_EV(IAP, EVENT_0FH_20H)			\
    +__PMC_EV(IAP, EVENT_0FH_80H)			\
     __PMC_EV(IAP, EVENT_10H_00H)			\
     __PMC_EV(IAP, EVENT_10H_01H)			\
    +__PMC_EV(IAP, EVENT_10H_02H)			\
    +__PMC_EV(IAP, EVENT_10H_04H)			\
    +__PMC_EV(IAP, EVENT_10H_08H)			\
    +__PMC_EV(IAP, EVENT_10H_10H)			\
    +__PMC_EV(IAP, EVENT_10H_20H)			\
    +__PMC_EV(IAP, EVENT_10H_40H)			\
    +__PMC_EV(IAP, EVENT_10H_80H)			\
     __PMC_EV(IAP, EVENT_10H_81H)			\
     __PMC_EV(IAP, EVENT_11H_00H)			\
     __PMC_EV(IAP, EVENT_11H_01H)			\
     __PMC_EV(IAP, EVENT_11H_81H)			\
     __PMC_EV(IAP, EVENT_12H_00H)			\
     __PMC_EV(IAP, EVENT_12H_01H)			\
    +__PMC_EV(IAP, EVENT_12H_02H)			\
    +__PMC_EV(IAP, EVENT_12H_04H)			\
    +__PMC_EV(IAP, EVENT_12H_08H)			\
    +__PMC_EV(IAP, EVENT_12H_10H)			\
    +__PMC_EV(IAP, EVENT_12H_20H)			\
    +__PMC_EV(IAP, EVENT_12H_40H)			\
     __PMC_EV(IAP, EVENT_12H_81H)			\
     __PMC_EV(IAP, EVENT_13H_00H)			\
     __PMC_EV(IAP, EVENT_13H_01H)			\
    +__PMC_EV(IAP, EVENT_13H_02H)			\
    +__PMC_EV(IAP, EVENT_13H_04H)			\
    +__PMC_EV(IAP, EVENT_13H_07H)			\
     __PMC_EV(IAP, EVENT_13H_81H)			\
     __PMC_EV(IAP, EVENT_14H_00H)			\
     __PMC_EV(IAP, EVENT_14H_01H)			\
    +__PMC_EV(IAP, EVENT_14H_02H)			\
    +__PMC_EV(IAP, EVENT_17H_01H)			\
     __PMC_EV(IAP, EVENT_18H_00H)			\
    +__PMC_EV(IAP, EVENT_18H_01H)			\
     __PMC_EV(IAP, EVENT_19H_00H)			\
     __PMC_EV(IAP, EVENT_19H_01H)			\
     __PMC_EV(IAP, EVENT_19H_02H)			\
    +__PMC_EV(IAP, EVENT_1DH_01H)			\
    +__PMC_EV(IAP, EVENT_1DH_02H)			\
    +__PMC_EV(IAP, EVENT_1DH_04H)			\
    +__PMC_EV(IAP, EVENT_1EH_01H)			\
    +__PMC_EV(IAP, EVENT_20H_01H)			\
     __PMC_EV(IAP, EVENT_21H)			\
     __PMC_EV(IAP, EVENT_22H)			\
     __PMC_EV(IAP, EVENT_23H)			\
     __PMC_EV(IAP, EVENT_24H)			\
    +__PMC_EV(IAP, EVENT_24H_01H)			\
    +__PMC_EV(IAP, EVENT_24H_02H)			\
    +__PMC_EV(IAP, EVENT_24H_03H)			\
    +__PMC_EV(IAP, EVENT_24H_04H)			\
    +__PMC_EV(IAP, EVENT_24H_08H)			\
    +__PMC_EV(IAP, EVENT_24H_0CH)			\
    +__PMC_EV(IAP, EVENT_24H_10H)			\
    +__PMC_EV(IAP, EVENT_24H_20H)			\
    +__PMC_EV(IAP, EVENT_24H_30H)			\
    +__PMC_EV(IAP, EVENT_24H_40H)			\
    +__PMC_EV(IAP, EVENT_24H_80H)			\
    +__PMC_EV(IAP, EVENT_24H_AAH)			\
    +__PMC_EV(IAP, EVENT_24H_C0H)			\
    +__PMC_EV(IAP, EVENT_24H_FFH)			\
     __PMC_EV(IAP, EVENT_25H)			\
     __PMC_EV(IAP, EVENT_26H)			\
    +__PMC_EV(IAP, EVENT_26H_01H)			\
    +__PMC_EV(IAP, EVENT_26H_02H)			\
    +__PMC_EV(IAP, EVENT_26H_04H)			\
    +__PMC_EV(IAP, EVENT_26H_08H)			\
    +__PMC_EV(IAP, EVENT_26H_0FH)			\
    +__PMC_EV(IAP, EVENT_26H_10H)			\
    +__PMC_EV(IAP, EVENT_26H_20H)			\
    +__PMC_EV(IAP, EVENT_26H_40H)			\
    +__PMC_EV(IAP, EVENT_26H_80H)			\
    +__PMC_EV(IAP, EVENT_26H_F0H)			\
    +__PMC_EV(IAP, EVENT_26H_FFH)			\
     __PMC_EV(IAP, EVENT_27H)			\
    +__PMC_EV(IAP, EVENT_27H_01H)			\
    +__PMC_EV(IAP, EVENT_27H_02H)			\
    +__PMC_EV(IAP, EVENT_27H_04H)			\
    +__PMC_EV(IAP, EVENT_27H_08H)			\
    +__PMC_EV(IAP, EVENT_27H_0EH)			\
    +__PMC_EV(IAP, EVENT_27H_0FH)			\
    +__PMC_EV(IAP, EVENT_27H_10H)			\
    +__PMC_EV(IAP, EVENT_27H_20H)			\
    +__PMC_EV(IAP, EVENT_27H_40H)			\
    +__PMC_EV(IAP, EVENT_27H_80H)			\
    +__PMC_EV(IAP, EVENT_27H_E0H)			\
    +__PMC_EV(IAP, EVENT_27H_F0H)			\
     __PMC_EV(IAP, EVENT_28H)			\
    +__PMC_EV(IAP, EVENT_28H_01H)			\
    +__PMC_EV(IAP, EVENT_28H_02H)			\
    +__PMC_EV(IAP, EVENT_28H_04H)			\
    +__PMC_EV(IAP, EVENT_28H_08H)			\
    +__PMC_EV(IAP, EVENT_28H_0FH)			\
     __PMC_EV(IAP, EVENT_29H)			\
     __PMC_EV(IAP, EVENT_2AH)			\
     __PMC_EV(IAP, EVENT_2BH)			\
     __PMC_EV(IAP, EVENT_2EH)			\
    +__PMC_EV(IAP, EVENT_2EH_01H)			\
    +__PMC_EV(IAP, EVENT_2EH_02H)			\
     __PMC_EV(IAP, EVENT_2EH_41H)			\
     __PMC_EV(IAP, EVENT_2EH_4FH)			\
     __PMC_EV(IAP, EVENT_30H)			\
    @@ -540,11 +636,26 @@ __PMC_EV(IAP, EVENT_3BH_C0H)			\
     __PMC_EV(IAP, EVENT_3CH_00H)			\
     __PMC_EV(IAP, EVENT_3CH_01H)			\
     __PMC_EV(IAP, EVENT_3CH_02H)			\
    +__PMC_EV(IAP, EVENT_3DH_01H)			\
     __PMC_EV(IAP, EVENT_40H)			\
    +__PMC_EV(IAP, EVENT_40H_01H)			\
    +__PMC_EV(IAP, EVENT_40H_02H)			\
    +__PMC_EV(IAP, EVENT_40H_04H)			\
    +__PMC_EV(IAP, EVENT_40H_08H)			\
    +__PMC_EV(IAP, EVENT_40H_0FH)			\
     __PMC_EV(IAP, EVENT_40H_21H)			\
     __PMC_EV(IAP, EVENT_41H)			\
    +__PMC_EV(IAP, EVENT_41H_01H)			\
    +__PMC_EV(IAP, EVENT_41H_02H)			\
    +__PMC_EV(IAP, EVENT_41H_04H)			\
    +__PMC_EV(IAP, EVENT_41H_08H)			\
    +__PMC_EV(IAP, EVENT_41H_0FH)			\
     __PMC_EV(IAP, EVENT_41H_22H)			\
     __PMC_EV(IAP, EVENT_42H)			\
    +__PMC_EV(IAP, EVENT_42H_01H)			\
    +__PMC_EV(IAP, EVENT_42H_02H)			\
    +__PMC_EV(IAP, EVENT_42H_04H)			\
    +__PMC_EV(IAP, EVENT_42H_08H)			\
     __PMC_EV(IAP, EVENT_42H_10H)			\
     __PMC_EV(IAP, EVENT_43H_01H)			\
     __PMC_EV(IAP, EVENT_43H_02H)			\
    @@ -553,22 +664,50 @@ __PMC_EV(IAP, EVENT_45H_0FH)			\
     __PMC_EV(IAP, EVENT_46H_00H)			\
     __PMC_EV(IAP, EVENT_47H_00H)			\
     __PMC_EV(IAP, EVENT_48H_00H)			\
    +__PMC_EV(IAP, EVENT_48H_02H)			\
     __PMC_EV(IAP, EVENT_49H_00H)			\
     __PMC_EV(IAP, EVENT_49H_01H)			\
     __PMC_EV(IAP, EVENT_49H_02H)			\
    +__PMC_EV(IAP, EVENT_49H_04H)			\
    +__PMC_EV(IAP, EVENT_49H_10H)			\
    +__PMC_EV(IAP, EVENT_49H_20H)			\
    +__PMC_EV(IAP, EVENT_49H_40H)			\
    +__PMC_EV(IAP, EVENT_49H_80H)			\
     __PMC_EV(IAP, EVENT_4BH_00H)			\
     __PMC_EV(IAP, EVENT_4BH_01H)			\
     __PMC_EV(IAP, EVENT_4BH_02H)			\
     __PMC_EV(IAP, EVENT_4BH_03H)			\
    +__PMC_EV(IAP, EVENT_4BH_08H)			\
     __PMC_EV(IAP, EVENT_4CH_00H)			\
    +__PMC_EV(IAP, EVENT_4CH_01H)			\
    +__PMC_EV(IAP, EVENT_4DH_01H)			\
    +__PMC_EV(IAP, EVENT_4EH_01H)			\
    +__PMC_EV(IAP, EVENT_4EH_02H)			\
    +__PMC_EV(IAP, EVENT_4EH_04H)			\
     __PMC_EV(IAP, EVENT_4EH_10H)			\
     __PMC_EV(IAP, EVENT_4FH_00H)			\
    +__PMC_EV(IAP, EVENT_4FH_02H)			\
    +__PMC_EV(IAP, EVENT_4FH_04H)			\
    +__PMC_EV(IAP, EVENT_4FH_08H)			\
    +__PMC_EV(IAP, EVENT_4FH_10H)			\
    +__PMC_EV(IAP, EVENT_51H_01H)			\
    +__PMC_EV(IAP, EVENT_51H_02H)			\
    +__PMC_EV(IAP, EVENT_51H_04H)			\
    +__PMC_EV(IAP, EVENT_51H_08H)			\
    +__PMC_EV(IAP, EVENT_52H_01H)			\
    +__PMC_EV(IAP, EVENT_53H_01H)			\
     __PMC_EV(IAP, EVENT_60H)			\
    +__PMC_EV(IAP, EVENT_60H_01H)			\
    +__PMC_EV(IAP, EVENT_60H_02H)			\
    +__PMC_EV(IAP, EVENT_60H_04H)			\
    +__PMC_EV(IAP, EVENT_60H_08H)			\
     __PMC_EV(IAP, EVENT_61H)			\
     __PMC_EV(IAP, EVENT_61H_00H)			\
     __PMC_EV(IAP, EVENT_62H)			\
     __PMC_EV(IAP, EVENT_62H_00H)			\
     __PMC_EV(IAP, EVENT_63H)			\
    +__PMC_EV(IAP, EVENT_63H_01H)			\
    +__PMC_EV(IAP, EVENT_63H_02H)			\
     __PMC_EV(IAP, EVENT_64H)			\
     __PMC_EV(IAP, EVENT_64H_40H)			\
     __PMC_EV(IAP, EVENT_65H)			\
    @@ -579,6 +718,7 @@ __PMC_EV(IAP, EVENT_69H)			\
     __PMC_EV(IAP, EVENT_6AH)			\
     __PMC_EV(IAP, EVENT_6BH)			\
     __PMC_EV(IAP, EVENT_6CH)			\
    +__PMC_EV(IAP, EVENT_6CH_01H)			\
     __PMC_EV(IAP, EVENT_6DH)			\
     __PMC_EV(IAP, EVENT_6EH)			\
     __PMC_EV(IAP, EVENT_6FH)			\
    @@ -592,20 +732,59 @@ __PMC_EV(IAP, EVENT_7EH)			\
     __PMC_EV(IAP, EVENT_7EH_00H)			\
     __PMC_EV(IAP, EVENT_7FH)			\
     __PMC_EV(IAP, EVENT_80H_00H)			\
    +__PMC_EV(IAP, EVENT_80H_01H)			\
     __PMC_EV(IAP, EVENT_80H_02H)			\
     __PMC_EV(IAP, EVENT_80H_03H)			\
    +__PMC_EV(IAP, EVENT_80H_04H)			\
    +__PMC_EV(IAP, EVENT_80H_10H)			\
     __PMC_EV(IAP, EVENT_81H_00H)			\
    +__PMC_EV(IAP, EVENT_81H_01H)			\
    +__PMC_EV(IAP, EVENT_81H_02H)			\
    +__PMC_EV(IAP, EVENT_82H_01H)			\
     __PMC_EV(IAP, EVENT_82H_02H)			\
     __PMC_EV(IAP, EVENT_82H_04H)			\
     __PMC_EV(IAP, EVENT_82H_10H)			\
     __PMC_EV(IAP, EVENT_82H_12H)			\
     __PMC_EV(IAP, EVENT_82H_40H)			\
    +__PMC_EV(IAP, EVENT_83H_01H)			\
     __PMC_EV(IAP, EVENT_83H_02H)			\
     __PMC_EV(IAP, EVENT_85H_00H)			\
    +__PMC_EV(IAP, EVENT_85H_01H)			\
    +__PMC_EV(IAP, EVENT_85H_02H)			\
    +__PMC_EV(IAP, EVENT_85H_04H)			\
    +__PMC_EV(IAP, EVENT_85H_10H)			\
    +__PMC_EV(IAP, EVENT_85H_20H)			\
    +__PMC_EV(IAP, EVENT_85H_40H)			\
    +__PMC_EV(IAP, EVENT_85H_80H)			\
     __PMC_EV(IAP, EVENT_86H_00H)			\
     __PMC_EV(IAP, EVENT_87H_00H)			\
    +__PMC_EV(IAP, EVENT_87H_01H)			\
    +__PMC_EV(IAP, EVENT_87H_02H)			\
    +__PMC_EV(IAP, EVENT_87H_04H)			\
    +__PMC_EV(IAP, EVENT_87H_08H)			\
    +__PMC_EV(IAP, EVENT_87H_0FH)			\
     __PMC_EV(IAP, EVENT_88H_00H)			\
    +__PMC_EV(IAP, EVENT_88H_01H)			\
    +__PMC_EV(IAP, EVENT_88H_02H)			\
    +__PMC_EV(IAP, EVENT_88H_04H)			\
    +__PMC_EV(IAP, EVENT_88H_07H)			\
    +__PMC_EV(IAP, EVENT_88H_08H)			\
    +__PMC_EV(IAP, EVENT_88H_10H)			\
    +__PMC_EV(IAP, EVENT_88H_20H)			\
    +__PMC_EV(IAP, EVENT_88H_30H)			\
    +__PMC_EV(IAP, EVENT_88H_40H)			\
    +__PMC_EV(IAP, EVENT_88H_7FH)			\
     __PMC_EV(IAP, EVENT_89H_00H)			\
    +__PMC_EV(IAP, EVENT_89H_01H)			\
    +__PMC_EV(IAP, EVENT_89H_02H)			\
    +__PMC_EV(IAP, EVENT_89H_04H)			\
    +__PMC_EV(IAP, EVENT_89H_07H)			\
    +__PMC_EV(IAP, EVENT_89H_08H)			\
    +__PMC_EV(IAP, EVENT_89H_10H)			\
    +__PMC_EV(IAP, EVENT_89H_20H)			\
    +__PMC_EV(IAP, EVENT_89H_30H)			\
    +__PMC_EV(IAP, EVENT_89H_40H)			\
    +__PMC_EV(IAP, EVENT_89H_7FH)			\
     __PMC_EV(IAP, EVENT_8AH_00H)			\
     __PMC_EV(IAP, EVENT_8BH_00H)			\
     __PMC_EV(IAP, EVENT_8CH_00H)			\
    @@ -627,16 +806,45 @@ __PMC_EV(IAP, EVENT_A1H_08H)			\
     __PMC_EV(IAP, EVENT_A1H_10H)			\
     __PMC_EV(IAP, EVENT_A1H_20H)			\
     __PMC_EV(IAP, EVENT_A2H_00H)			\
    +__PMC_EV(IAP, EVENT_A2H_01H)			\
    +__PMC_EV(IAP, EVENT_A2H_02H)			\
    +__PMC_EV(IAP, EVENT_A2H_04H)			\
    +__PMC_EV(IAP, EVENT_A2H_08H)			\
    +__PMC_EV(IAP, EVENT_A2H_10H)			\
    +__PMC_EV(IAP, EVENT_A2H_20H)			\
    +__PMC_EV(IAP, EVENT_A2H_40H)			\
    +__PMC_EV(IAP, EVENT_A2H_80H)			\
    +__PMC_EV(IAP, EVENT_A6H_01H)			\
    +__PMC_EV(IAP, EVENT_A7H_01H)			\
    +__PMC_EV(IAP, EVENT_A8H_01H)			\
     __PMC_EV(IAP, EVENT_AAH_01H)			\
     __PMC_EV(IAP, EVENT_AAH_02H)			\
     __PMC_EV(IAP, EVENT_AAH_03H)			\
     __PMC_EV(IAP, EVENT_AAH_08H)			\
     __PMC_EV(IAP, EVENT_ABH_01H)			\
     __PMC_EV(IAP, EVENT_ABH_02H)			\
    +__PMC_EV(IAP, EVENT_AEH_01H)			\
     __PMC_EV(IAP, EVENT_B0H_00H)			\
    +__PMC_EV(IAP, EVENT_B0H_01H)			\
    +__PMC_EV(IAP, EVENT_B0H_02H)			\
    +__PMC_EV(IAP, EVENT_B0H_04H)			\
    +__PMC_EV(IAP, EVENT_B0H_08H)			\
    +__PMC_EV(IAP, EVENT_B0H_10H)			\
    +__PMC_EV(IAP, EVENT_B0H_20H)			\
    +__PMC_EV(IAP, EVENT_B0H_40H)			\
     __PMC_EV(IAP, EVENT_B0H_80H)			\
     __PMC_EV(IAP, EVENT_B1H_00H)			\
    +__PMC_EV(IAP, EVENT_B1H_01H)			\
    +__PMC_EV(IAP, EVENT_B1H_02H)			\
    +__PMC_EV(IAP, EVENT_B1H_04H)			\
    +__PMC_EV(IAP, EVENT_B1H_08H)			\
    +__PMC_EV(IAP, EVENT_B1H_10H)			\
    +__PMC_EV(IAP, EVENT_B1H_1FH)			\
    +__PMC_EV(IAP, EVENT_B1H_20H)			\
    +__PMC_EV(IAP, EVENT_B1H_3FH)			\
    +__PMC_EV(IAP, EVENT_B1H_40H)			\
     __PMC_EV(IAP, EVENT_B1H_80H)			\
    +__PMC_EV(IAP, EVENT_B2H_01H)			\
     __PMC_EV(IAP, EVENT_B3H_01H)			\
     __PMC_EV(IAP, EVENT_B3H_02H)			\
     __PMC_EV(IAP, EVENT_B3H_04H)			\
    @@ -649,6 +857,16 @@ __PMC_EV(IAP, EVENT_B3H_84H)			\
     __PMC_EV(IAP, EVENT_B3H_88H)			\
     __PMC_EV(IAP, EVENT_B3H_90H)			\
     __PMC_EV(IAP, EVENT_B3H_A0H)			\
    +__PMC_EV(IAP, EVENT_B4H_01H)			\
    +__PMC_EV(IAP, EVENT_B4H_02H)			\
    +__PMC_EV(IAP, EVENT_B4H_04H)			\
    +__PMC_EV(IAP, EVENT_B7H_01H)			\
    +__PMC_EV(IAP, EVENT_B8H_01H)			\
    +__PMC_EV(IAP, EVENT_B8H_02H)			\
    +__PMC_EV(IAP, EVENT_B8H_04H)			\
    +__PMC_EV(IAP, EVENT_BAH_01H)			\
    +__PMC_EV(IAP, EVENT_BAH_02H)			\
    +__PMC_EV(IAP, EVENT_BBH_01H)			\
     __PMC_EV(IAP, EVENT_C0H_00H)			\
     __PMC_EV(IAP, EVENT_C0H_01H)			\
     __PMC_EV(IAP, EVENT_C0H_02H)			\
    @@ -662,12 +880,14 @@ __PMC_EV(IAP, EVENT_C2H_01H)			\
     __PMC_EV(IAP, EVENT_C2H_02H)			\
     __PMC_EV(IAP, EVENT_C2H_04H)			\
     __PMC_EV(IAP, EVENT_C2H_07H)			\
    +__PMC_EV(IAP, EVENT_C2H_08H)			\
     __PMC_EV(IAP, EVENT_C2H_0FH)			\
     __PMC_EV(IAP, EVENT_C2H_10H)			\
    -__PMC_EV(IAP, EVENT_C2H_08H)			\
     __PMC_EV(IAP, EVENT_C3H_00H)			\
     __PMC_EV(IAP, EVENT_C3H_01H)			\
    +__PMC_EV(IAP, EVENT_C3H_02H)			\
     __PMC_EV(IAP, EVENT_C3H_04H)			\
    +__PMC_EV(IAP, EVENT_C3H_10H)			\
     __PMC_EV(IAP, EVENT_C4H_00H)			\
     __PMC_EV(IAP, EVENT_C4H_01H)			\
     __PMC_EV(IAP, EVENT_C4H_02H)			\
    @@ -676,6 +896,9 @@ __PMC_EV(IAP, EVENT_C4H_08H)			\
     __PMC_EV(IAP, EVENT_C4H_0CH)			\
     __PMC_EV(IAP, EVENT_C4H_0FH)			\
     __PMC_EV(IAP, EVENT_C5H_00H)			\
    +__PMC_EV(IAP, EVENT_C5H_01H)			\
    +__PMC_EV(IAP, EVENT_C5H_02H)			\
    +__PMC_EV(IAP, EVENT_C5H_04H)			\
     __PMC_EV(IAP, EVENT_C6H_00H)			\
     __PMC_EV(IAP, EVENT_C6H_01H)			\
     __PMC_EV(IAP, EVENT_C6H_02H)			\
    @@ -687,6 +910,7 @@ __PMC_EV(IAP, EVENT_C7H_08H)			\
     __PMC_EV(IAP, EVENT_C7H_10H)			\
     __PMC_EV(IAP, EVENT_C7H_1FH)			\
     __PMC_EV(IAP, EVENT_C8H_00H)			\
    +__PMC_EV(IAP, EVENT_C8H_20H)			\
     __PMC_EV(IAP, EVENT_C9H_00H)			\
     __PMC_EV(IAP, EVENT_CAH_00H)			\
     __PMC_EV(IAP, EVENT_CAH_01H)			\
    @@ -698,13 +922,21 @@ __PMC_EV(IAP, EVENT_CBH_02H)			\
     __PMC_EV(IAP, EVENT_CBH_04H)			\
     __PMC_EV(IAP, EVENT_CBH_08H)			\
     __PMC_EV(IAP, EVENT_CBH_10H)			\
    +__PMC_EV(IAP, EVENT_CBH_40H)			\
    +__PMC_EV(IAP, EVENT_CBH_80H)			\
     __PMC_EV(IAP, EVENT_CCH_00H)			\
     __PMC_EV(IAP, EVENT_CCH_01H)			\
     __PMC_EV(IAP, EVENT_CCH_02H)			\
    +__PMC_EV(IAP, EVENT_CCH_03H)			\
     __PMC_EV(IAP, EVENT_CDH_00H)			\
     __PMC_EV(IAP, EVENT_CEH_00H)			\
     __PMC_EV(IAP, EVENT_CFH_00H)			\
     __PMC_EV(IAP, EVENT_D0H_00H)			\
    +__PMC_EV(IAP, EVENT_D0H_01H)			\
    +__PMC_EV(IAP, EVENT_D1H_01H)			\
    +__PMC_EV(IAP, EVENT_D1H_02H)			\
    +__PMC_EV(IAP, EVENT_D1H_04H)			\
    +__PMC_EV(IAP, EVENT_D1H_08H)			\
     __PMC_EV(IAP, EVENT_D2H_01H)			\
     __PMC_EV(IAP, EVENT_D2H_02H)			\
     __PMC_EV(IAP, EVENT_D2H_04H)			\
    @@ -735,6 +967,7 @@ __PMC_EV(IAP, EVENT_DAH_00H)			\
     __PMC_EV(IAP, EVENT_DAH_01H)			\
     __PMC_EV(IAP, EVENT_DAH_02H)			\
     __PMC_EV(IAP, EVENT_DBH_00H)			\
    +__PMC_EV(IAP, EVENT_DBH_01H)			\
     __PMC_EV(IAP, EVENT_DCH_01H)			\
     __PMC_EV(IAP, EVENT_DCH_02H)			\
     __PMC_EV(IAP, EVENT_DCH_04H)			\
    @@ -745,249 +978,16 @@ __PMC_EV(IAP, EVENT_E0H_00H)			\
     __PMC_EV(IAP, EVENT_E0H_01H)			\
     __PMC_EV(IAP, EVENT_E2H_00H)			\
     __PMC_EV(IAP, EVENT_E4H_00H)			\
    -__PMC_EV(IAP, EVENT_E6H_00H)			\
    -__PMC_EV(IAP, EVENT_E6H_01H)			\
    -__PMC_EV(IAP, EVENT_F0H_00H)			\
    -__PMC_EV(IAP, EVENT_F8H_00H)			\
    -__PMC_EV(IAP, EVENT_02H_01H)			\
    -__PMC_EV(IAP, EVENT_03H_01H)			\
    -__PMC_EV(IAP, EVENT_05H_01H)			\
    -__PMC_EV(IAP, EVENT_05H_02H)			\
    -__PMC_EV(IAP, EVENT_05H_03H)			\
    -__PMC_EV(IAP, EVENT_06H_01H)			\
    -__PMC_EV(IAP, EVENT_06H_02H)			\
    -__PMC_EV(IAP, EVENT_06H_04H)			\
    -__PMC_EV(IAP, EVENT_06H_08H)			\
    -__PMC_EV(IAP, EVENT_06H_0FH)			\
    -__PMC_EV(IAP, EVENT_08H_10H)			\
    -__PMC_EV(IAP, EVENT_08H_20H)			\
    -__PMC_EV(IAP, EVENT_08H_40H)			\
    -__PMC_EV(IAP, EVENT_08H_80H)			\
    -__PMC_EV(IAP, EVENT_09H_04H)			\
    -__PMC_EV(IAP, EVENT_09H_08H)			\
    -__PMC_EV(IAP, EVENT_0BH_01H)			\
    -__PMC_EV(IAP, EVENT_0BH_02H)			\
    -__PMC_EV(IAP, EVENT_0EH_01H)			\
    -__PMC_EV(IAP, EVENT_0EH_02H)			\
    -__PMC_EV(IAP, EVENT_0FH_02H)			\
    -__PMC_EV(IAP, EVENT_0FH_08H)			\
    -__PMC_EV(IAP, EVENT_0FH_10H)			\
    -__PMC_EV(IAP, EVENT_0FH_20H)			\
    -__PMC_EV(IAP, EVENT_10H_02H)			\
    -__PMC_EV(IAP, EVENT_10H_04H)			\
    -__PMC_EV(IAP, EVENT_10H_08H)			\
    -__PMC_EV(IAP, EVENT_10H_10H)			\
    -__PMC_EV(IAP, EVENT_10H_20H)			\
    -__PMC_EV(IAP, EVENT_10H_40H)			\
    -__PMC_EV(IAP, EVENT_10H_80H)			\
    -__PMC_EV(IAP, EVENT_12H_02H)			\
    -__PMC_EV(IAP, EVENT_12H_04H)			\
    -__PMC_EV(IAP, EVENT_12H_08H)			\
    -__PMC_EV(IAP, EVENT_12H_10H)			\
    -__PMC_EV(IAP, EVENT_12H_20H)			\
    -__PMC_EV(IAP, EVENT_12H_40H)			\
    -__PMC_EV(IAP, EVENT_13H_02H)			\
    -__PMC_EV(IAP, EVENT_13H_04H)			\
    -__PMC_EV(IAP, EVENT_13H_07H)			\
    -__PMC_EV(IAP, EVENT_14H_02H)			\
    -__PMC_EV(IAP, EVENT_17H_01H)			\
    -__PMC_EV(IAP, EVENT_18H_01H)			\
    -__PMC_EV(IAP, EVENT_1DH_01H)			\
    -__PMC_EV(IAP, EVENT_1DH_02H)			\
    -__PMC_EV(IAP, EVENT_1DH_04H)			\
    -__PMC_EV(IAP, EVENT_1EH_01H)			\
    -__PMC_EV(IAP, EVENT_24H_01H)			\
    -__PMC_EV(IAP, EVENT_24H_02H)			\
    -__PMC_EV(IAP, EVENT_24H_03H)			\
    -__PMC_EV(IAP, EVENT_24H_04H)			\
    -__PMC_EV(IAP, EVENT_24H_08H)			\
    -__PMC_EV(IAP, EVENT_24H_0CH)			\
    -__PMC_EV(IAP, EVENT_24H_10H)			\
    -__PMC_EV(IAP, EVENT_24H_20H)			\
    -__PMC_EV(IAP, EVENT_24H_30H)			\
    -__PMC_EV(IAP, EVENT_24H_40H)			\
    -__PMC_EV(IAP, EVENT_24H_80H)			\
    -__PMC_EV(IAP, EVENT_24H_AAH)			\
    -__PMC_EV(IAP, EVENT_24H_C0H)			\
    -__PMC_EV(IAP, EVENT_24H_FFH)			\
    -__PMC_EV(IAP, EVENT_26H_01H)			\
    -__PMC_EV(IAP, EVENT_26H_02H)			\
    -__PMC_EV(IAP, EVENT_26H_04H)			\
    -__PMC_EV(IAP, EVENT_26H_08H)			\
    -__PMC_EV(IAP, EVENT_26H_0FH)			\
    -__PMC_EV(IAP, EVENT_26H_10H)			\
    -__PMC_EV(IAP, EVENT_26H_20H)			\
    -__PMC_EV(IAP, EVENT_26H_40H)			\
    -__PMC_EV(IAP, EVENT_26H_80H)			\
    -__PMC_EV(IAP, EVENT_26H_F0H)			\
    -__PMC_EV(IAP, EVENT_26H_FFH)			\
    -__PMC_EV(IAP, EVENT_27H_01H)			\
    -__PMC_EV(IAP, EVENT_27H_02H)			\
    -__PMC_EV(IAP, EVENT_27H_04H)			\
    -__PMC_EV(IAP, EVENT_27H_08H)			\
    -__PMC_EV(IAP, EVENT_27H_0EH)			\
    -__PMC_EV(IAP, EVENT_27H_0FH)			\
    -__PMC_EV(IAP, EVENT_27H_10H)			\
    -__PMC_EV(IAP, EVENT_27H_20H)			\
    -__PMC_EV(IAP, EVENT_27H_40H)			\
    -__PMC_EV(IAP, EVENT_27H_80H)			\
    -__PMC_EV(IAP, EVENT_27H_E0H)			\
    -__PMC_EV(IAP, EVENT_27H_F0H)			\
    -__PMC_EV(IAP, EVENT_28H_01H)			\
    -__PMC_EV(IAP, EVENT_28H_02H)			\
    -__PMC_EV(IAP, EVENT_28H_04H)			\
    -__PMC_EV(IAP, EVENT_28H_08H)			\
    -__PMC_EV(IAP, EVENT_28H_0FH)			\
    -__PMC_EV(IAP, EVENT_3DH_01H)			\
    -__PMC_EV(IAP, EVENT_40H_01H)			\
    -__PMC_EV(IAP, EVENT_40H_02H)			\
    -__PMC_EV(IAP, EVENT_40H_04H)			\
    -__PMC_EV(IAP, EVENT_40H_08H)			\
    -__PMC_EV(IAP, EVENT_40H_0FH)			\
    -__PMC_EV(IAP, EVENT_41H_01H)			\
    -__PMC_EV(IAP, EVENT_41H_02H)			\
    -__PMC_EV(IAP, EVENT_41H_04H)			\
    -__PMC_EV(IAP, EVENT_41H_08H)			\
    -__PMC_EV(IAP, EVENT_41H_0FH)			\
    -__PMC_EV(IAP, EVENT_42H_01H)			\
    -__PMC_EV(IAP, EVENT_42H_02H)			\
    -__PMC_EV(IAP, EVENT_42H_04H)			\
    -__PMC_EV(IAP, EVENT_42H_08H)			\
    -__PMC_EV(IAP, EVENT_48H_02H)			\
    -__PMC_EV(IAP, EVENT_49H_10H)			\
    -__PMC_EV(IAP, EVENT_49H_20H)			\
    -__PMC_EV(IAP, EVENT_49H_40H)			\
    -__PMC_EV(IAP, EVENT_49H_80H)			\
    -__PMC_EV(IAP, EVENT_4BH_08H)			\
    -__PMC_EV(IAP, EVENT_4CH_01H)			\
    -__PMC_EV(IAP, EVENT_4DH_01H)			\
    -__PMC_EV(IAP, EVENT_4EH_01H)			\
    -__PMC_EV(IAP, EVENT_4EH_02H)			\
    -__PMC_EV(IAP, EVENT_4EH_04H)			\
    -__PMC_EV(IAP, EVENT_4FH_02H)			\
    -__PMC_EV(IAP, EVENT_4FH_04H)			\
    -__PMC_EV(IAP, EVENT_4FH_08H)			\
    -__PMC_EV(IAP, EVENT_51H_01H)			\
    -__PMC_EV(IAP, EVENT_51H_02H)			\
    -__PMC_EV(IAP, EVENT_51H_04H)			\
    -__PMC_EV(IAP, EVENT_51H_08H)			\
    -__PMC_EV(IAP, EVENT_52H_01H)			\
    -__PMC_EV(IAP, EVENT_53H_01H)			\
    -__PMC_EV(IAP, EVENT_60H_01H)			\
    -__PMC_EV(IAP, EVENT_60H_02H)			\
    -__PMC_EV(IAP, EVENT_60H_04H)			\
    -__PMC_EV(IAP, EVENT_60H_08H)			\
    -__PMC_EV(IAP, EVENT_63H_01H)			\
    -__PMC_EV(IAP, EVENT_63H_02H)			\
    -__PMC_EV(IAP, EVENT_6CH_01H)			\
    -__PMC_EV(IAP, EVENT_80H_01H)			\
    -__PMC_EV(IAP, EVENT_80H_04H)			\
    -__PMC_EV(IAP, EVENT_80H_10H)			\
    -__PMC_EV(IAP, EVENT_81H_01H)			\
    -__PMC_EV(IAP, EVENT_81H_02H)			\
    -__PMC_EV(IAP, EVENT_82H_01H)			\
    -__PMC_EV(IAP, EVENT_83H_01H)			\
    -__PMC_EV(IAP, EVENT_85H_01H)			\
    -__PMC_EV(IAP, EVENT_85H_02H)			\
    -__PMC_EV(IAP, EVENT_85H_04H)			\
    -__PMC_EV(IAP, EVENT_85H_10H)			\
    -__PMC_EV(IAP, EVENT_85H_20H)			\
    -__PMC_EV(IAP, EVENT_85H_40H)			\
    -__PMC_EV(IAP, EVENT_85H_80H)			\
    -__PMC_EV(IAP, EVENT_87H_01H)			\
    -__PMC_EV(IAP, EVENT_87H_02H)			\
    -__PMC_EV(IAP, EVENT_87H_04H)			\
    -__PMC_EV(IAP, EVENT_87H_08H)			\
    -__PMC_EV(IAP, EVENT_87H_0FH)			\
    -__PMC_EV(IAP, EVENT_88H_01H)			\
    -__PMC_EV(IAP, EVENT_88H_02H)			\
    -__PMC_EV(IAP, EVENT_88H_04H)			\
    -__PMC_EV(IAP, EVENT_88H_07H)			\
    -__PMC_EV(IAP, EVENT_88H_08H)			\
    -__PMC_EV(IAP, EVENT_88H_10H)			\
    -__PMC_EV(IAP, EVENT_88H_20H)			\
    -__PMC_EV(IAP, EVENT_88H_30H)			\
    -__PMC_EV(IAP, EVENT_88H_40H)			\
    -__PMC_EV(IAP, EVENT_89H_01H)			\
    -__PMC_EV(IAP, EVENT_89H_02H)			\
    -__PMC_EV(IAP, EVENT_89H_04H)			\
    -__PMC_EV(IAP, EVENT_89H_07H)			\
    -__PMC_EV(IAP, EVENT_89H_08H)			\
    -__PMC_EV(IAP, EVENT_89H_10H)			\
    -__PMC_EV(IAP, EVENT_89H_20H)			\
    -__PMC_EV(IAP, EVENT_89H_30H)			\
    -__PMC_EV(IAP, EVENT_89H_40H)			\
    -__PMC_EV(IAP, EVENT_89H_7FH)			\
    -__PMC_EV(IAP, EVENT_A2H_01H)			\
    -__PMC_EV(IAP, EVENT_A2H_02H)			\
    -__PMC_EV(IAP, EVENT_A2H_04H)			\
    -__PMC_EV(IAP, EVENT_A2H_08H)			\
    -__PMC_EV(IAP, EVENT_A2H_10H)			\
    -__PMC_EV(IAP, EVENT_A2H_20H)			\
    -__PMC_EV(IAP, EVENT_A2H_40H)			\
    -__PMC_EV(IAP, EVENT_A2H_80H)			\
    -__PMC_EV(IAP, EVENT_A6H_01H)			\
    -__PMC_EV(IAP, EVENT_A7H_01H)			\
    -__PMC_EV(IAP, EVENT_A8H_01H)			\
    -__PMC_EV(IAP, EVENT_B0H_01H)			\
    -__PMC_EV(IAP, EVENT_B0H_02H)			\
    -__PMC_EV(IAP, EVENT_B0H_04H)			\
    -__PMC_EV(IAP, EVENT_B0H_08H)			\
    -__PMC_EV(IAP, EVENT_B0H_20H)			\
    -__PMC_EV(IAP, EVENT_B0H_40H)			\
    -__PMC_EV(IAP, EVENT_B1H_01H)			\
    -__PMC_EV(IAP, EVENT_B1H_02H)			\
    -__PMC_EV(IAP, EVENT_B1H_04H)			\
    -__PMC_EV(IAP, EVENT_B1H_08H)			\
    -__PMC_EV(IAP, EVENT_B1H_10H)			\
    -__PMC_EV(IAP, EVENT_B1H_20H)			\
    -__PMC_EV(IAP, EVENT_B1H_40H)			\
    -__PMC_EV(IAP, EVENT_B2H_01H)			\
    -__PMC_EV(IAP, EVENT_B7H_01H)			\
    -__PMC_EV(IAP, EVENT_B8H_01H)			\
    -__PMC_EV(IAP, EVENT_B8H_02H)			\
    -__PMC_EV(IAP, EVENT_B8H_04H)			\
    -__PMC_EV(IAP, EVENT_BAH_01H)			\
    -__PMC_EV(IAP, EVENT_BAH_02H)			\
    -__PMC_EV(IAP, EVENT_C3H_02H)			\
    -__PMC_EV(IAP, EVENT_C3H_10H)			\
    -__PMC_EV(IAP, EVENT_C5H_02H)			\
    -__PMC_EV(IAP, EVENT_C8H_20H)			\
    -__PMC_EV(IAP, EVENT_CBH_40H)			\
    -__PMC_EV(IAP, EVENT_CBH_80H)			\
    -__PMC_EV(IAP, EVENT_CCH_03H)			\
    -__PMC_EV(IAP, EVENT_D0H_01H)			\
    -__PMC_EV(IAP, EVENT_D1H_02H)			\
    -__PMC_EV(IAP, EVENT_D1H_04H)			\
    -__PMC_EV(IAP, EVENT_D1H_08H)			\
    -__PMC_EV(IAP, EVENT_DBH_01H)			\
     __PMC_EV(IAP, EVENT_E4H_01H)			\
     __PMC_EV(IAP, EVENT_E5H_01H)			\
    -__PMC_EV(IAP, EVENT_F3H_04H)			\
    -__PMC_EV(IAP, EVENT_F3H_08H)			\
    -__PMC_EV(IAP, EVENT_F3H_10H)			\
    -__PMC_EV(IAP, EVENT_F3H_20H)			\
    -__PMC_EV(IAP, EVENT_F4H_01H)			\
    -__PMC_EV(IAP, EVENT_F4H_02H)			\
    -__PMC_EV(IAP, EVENT_F4H_04H)			\
    -__PMC_EV(IAP, EVENT_F4H_08H)			\
    -__PMC_EV(IAP, EVENT_F4H_10H)			\
    -__PMC_EV(IAP, EVENT_F6H_01H)			\
    -__PMC_EV(IAP, EVENT_F7H_01H)			\
    -__PMC_EV(IAP, EVENT_F7H_02H)			\
    -__PMC_EV(IAP, EVENT_F7H_04H)			\
    -__PMC_EV(IAP, EVENT_F8H_01H)			\
    -__PMC_EV(IAP, EVENT_FDH_01H)			\
    -__PMC_EV(IAP, EVENT_FDH_02H)			\
    -__PMC_EV(IAP, EVENT_FDH_04H)			\
    -__PMC_EV(IAP, EVENT_FDH_08H)			\
    -__PMC_EV(IAP, EVENT_FDH_10H)			\
    -__PMC_EV(IAP, EVENT_FDH_20H)			\
    -__PMC_EV(IAP, EVENT_FDH_40H)			\
    +__PMC_EV(IAP, EVENT_E6H_00H)			\
    +__PMC_EV(IAP, EVENT_E6H_01H)			\
     __PMC_EV(IAP, EVENT_E6H_02H)			\
     __PMC_EV(IAP, EVENT_E8H_01H)			\
     __PMC_EV(IAP, EVENT_E8H_02H)			\
     __PMC_EV(IAP, EVENT_E8H_03H)			\
    +__PMC_EV(IAP, EVENT_ECH_01H)			\
    +__PMC_EV(IAP, EVENT_F0H_00H)			\
     __PMC_EV(IAP, EVENT_F0H_01H)			\
     __PMC_EV(IAP, EVENT_F0H_02H)			\
     __PMC_EV(IAP, EVENT_F0H_04H)			\
    @@ -1005,10 +1005,31 @@ __PMC_EV(IAP, EVENT_F2H_04H)			\
     __PMC_EV(IAP, EVENT_F2H_08H)			\
     __PMC_EV(IAP, EVENT_F2H_0FH)			\
     __PMC_EV(IAP, EVENT_F3H_01H)			\
    -__PMC_EV(IAP, EVENT_F3H_02H)			
    +__PMC_EV(IAP, EVENT_F3H_02H)			\
    +__PMC_EV(IAP, EVENT_F3H_04H)			\
    +__PMC_EV(IAP, EVENT_F3H_08H)			\
    +__PMC_EV(IAP, EVENT_F3H_10H)			\
    +__PMC_EV(IAP, EVENT_F3H_20H)			\
    +__PMC_EV(IAP, EVENT_F4H_01H)			\
    +__PMC_EV(IAP, EVENT_F4H_02H)			\
    +__PMC_EV(IAP, EVENT_F4H_04H)			\
    +__PMC_EV(IAP, EVENT_F4H_08H)			\
    +__PMC_EV(IAP, EVENT_F4H_10H)			\
    +__PMC_EV(IAP, EVENT_F6H_01H)			\
    +__PMC_EV(IAP, EVENT_F7H_01H)			\
    +__PMC_EV(IAP, EVENT_F7H_02H)			\
    +__PMC_EV(IAP, EVENT_F7H_04H)			\
    +__PMC_EV(IAP, EVENT_F8H_00H)			\
    +__PMC_EV(IAP, EVENT_F8H_01H)			\
    +__PMC_EV(IAP, EVENT_FDH_01H)			\
    +__PMC_EV(IAP, EVENT_FDH_02H)			\
    +__PMC_EV(IAP, EVENT_FDH_04H)			\
    +__PMC_EV(IAP, EVENT_FDH_08H)			\
    +__PMC_EV(IAP, EVENT_FDH_10H)			\
    +__PMC_EV(IAP, EVENT_FDH_20H)			\
    +__PMC_EV(IAP, EVENT_FDH_40H)
     
    -
    -#define	PMC_EV_IAP_FIRST	PMC_EV_IAP_EVENT_02H_81H
    +#define	PMC_EV_IAP_FIRST	PMC_EV_IAP_EVENT_02H_01H
     #define	PMC_EV_IAP_LAST		PMC_EV_IAP_EVENT_FDH_40H
     
     /*
    @@ -1647,330 +1668,655 @@ __PMC_EV_ALIAS("X87_OPS_RETIRED.ANY",		IAP_EVENT_C1H_FEH)	\
     __PMC_EV_ALIAS("X87_OPS_RETIRED.FXCH",		IAP_EVENT_C1H_01H)
     
     /*
    - * Aliases for Core i7 PMC events.
    + * Core i7 and Xeon 5500 events removed between 253669-031US June 2009
    + * and 253669-033US December 2009.
    + */
    +#define	__PMC_EV_ALIAS_COREI7_OLD()					\
    +__PMC_EV_ALIAS("SB_FORWARD.ANY", IAP_EVENT_02H_01H)			\
    +__PMC_EV_ALIAS("LOAD_BLOCK.STD", IAP_EVENT_03H_01H)			\
    +__PMC_EV_ALIAS("LOAD_BLOCK.ADDRESS_OFFSET", IAP_EVENT_03H_04H)		\
    +__PMC_EV_ALIAS("SB_DRAIN.CYCLES", IAP_EVENT_04H_01H)			\
    +__PMC_EV_ALIAS("MISALIGN_MEM_REF.LOAD", IAP_EVENT_05H_01H)		\
    +__PMC_EV_ALIAS("MISALIGN_MEM_REF.STORE", IAP_EVENT_05H_02H)		\
    +__PMC_EV_ALIAS("MISALIGN_MEM_REF.ANY", IAP_EVENT_05H_03H)		\
    +__PMC_EV_ALIAS("STORE_BLOCKS.NOT_STA", IAP_EVENT_06H_01H)		\
    +__PMC_EV_ALIAS("STORE_BLOCKS.STA", IAP_EVENT_06H_02H)			\
    +__PMC_EV_ALIAS("STORE_BLOCKS.ANY", IAP_EVENT_06H_0FH)			\
    +__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.RESET", IAP_EVENT_09H_01H)	\
    +__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.SUCCESS", IAP_EVENT_09H_02H)	\
    +__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.WATCHDOG", IAP_EVENT_09H_04H)	\
    +__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.WATCH_CYCLES", IAP_EVENT_09H_08H)\
    +__PMC_EV_ALIAS("HW_INT.RCV", IAP_EVENT_1DH_01H)				\
    +__PMC_EV_ALIAS("HW_INT.CYCLES_MASKED", IAP_EVENT_1DH_02H)		\
    +__PMC_EV_ALIAS("HW_INT.CYCLES_PENDING_AND_MASKED", IAP_EVENT_1DH_04H)	\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.E_STATE", IAP_EVENT_27H_04H)		\
    +__PMC_EV_ALIAS("UOPS_DECODED.DEC0", IAP_EVENT_3DH_01H)			\
    +__PMC_EV_ALIAS("L1D_CACHE_ST.I_STATE", IAP_EVENT_41H_01H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_ST.MESI", IAP_EVENT_41H_0FH)			\
    +__PMC_EV_ALIAS("DTLB_MISSES.PDE_MISS", IAP_EVENT_49H_20H)		\
    +__PMC_EV_ALIAS("DTLB_MISSES.PDP_MISS", IAP_EVENT_49H_40H)		\
    +__PMC_EV_ALIAS("DTLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_49H_80H)	\
    +__PMC_EV_ALIAS("SSE_MEM_EXEC.NTA", IAP_EVENT_4BH_01H)			\
    +__PMC_EV_ALIAS("SSE_MEM_EXEC.STREAMING_STORES", IAP_EVENT_4BH_08H)	\
    +__PMC_EV_ALIAS("SFENCE_CYCLES", IAP_EVENT_4DH_01H)			\
    +__PMC_EV_ALIAS("EPT.EPDE_MISS", IAP_EVENT_4FH_02H)			\
    +__PMC_EV_ALIAS("EPT.EPDPE_HIT", IAP_EVENT_4FH_04H)			\
    +__PMC_EV_ALIAS("EPT.EPDPE_MISS", IAP_EVENT_4FH_08H)			\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA",		\
    +    IAP_EVENT_60H_01H)							\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE",		\
    +    IAP_EVENT_60H_02H)							\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO",		\
    +    IAP_EVENT_60H_04H)							\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.ANY.READ",			\
    +    IAP_EVENT_60H_08H)							\
    +__PMC_EV_ALIAS("IFU_IVC.FULL", IAP_EVENT_81H_01H)			\
    +__PMC_EV_ALIAS("IFU_IVC.L1I_EVICTION", IAP_EVENT_81H_02H)		\
    +__PMC_EV_ALIAS("L1I_OPPORTUNISTIC_HITS", IAP_EVENT_83H_01H)		\
    +__PMC_EV_ALIAS("ITLB_MISSES.WALK_CYCLES", IAP_EVENT_85H_04H)		\
    +__PMC_EV_ALIAS("ITLB_MISSES.PMH_BUSY_CYCLES", IAP_EVENT_85H_04H)	\
    +__PMC_EV_ALIAS("ITLB_MISSES.STLB_HIT", IAP_EVENT_85H_10H)		\
    +__PMC_EV_ALIAS("ITLB_MISSES.PDE_MISS", IAP_EVENT_85H_20H)		\
    +__PMC_EV_ALIAS("ITLB_MISSES.PDP_MISS", IAP_EVENT_85H_40H)		\
    +__PMC_EV_ALIAS("ITLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_85H_80H)	\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_DATA", IAP_EVENT_B0H_01H)	\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_CODE", IAP_EVENT_B0H_02H)	\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.RFO", IAP_EVENT_B0H_04H)	\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.READ", IAP_EVENT_B0H_08H)		\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.RFO", IAP_EVENT_B0H_10H)		\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.UNCACHED_MEM", IAP_EVENT_B0H_20H)	\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY", IAP_EVENT_B0H_80H)		\
    +__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.DATA", IAP_EVENT_B3H_01H)	\
    +__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE",		\
    +    IAP_EVENT_B3H_02H)							\
    +__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.CODE", IAP_EVENT_B3H_04H)	\
    +__PMC_EV_ALIAS("PIC_ACCESSES.TPR_READS", IAP_EVENT_BAH_01H)		\
    +__PMC_EV_ALIAS("PIC_ACCESSES.TPR_WRITES", IAP_EVENT_BAH_02H)		\
    +__PMC_EV_ALIAS("MACHINE_CLEARS.FUSION_ASSIST", IAP_EVENT_C3H_10H)	\
    +__PMC_EV_ALIAS("BOGUS_BR", IAP_EVENT_E4H_01H)				\
    +__PMC_EV_ALIAS("L2_HW_PREFETCH.HIT", IAP_EVENT_F3H_01H)			\
    +__PMC_EV_ALIAS("L2_HW_PREFETCH.ALLOC", IAP_EVENT_F3H_02H)		\
    +__PMC_EV_ALIAS("L2_HW_PREFETCH.DATA_TRIGGER", IAP_EVENT_F3H_04H)	\
    +__PMC_EV_ALIAS("L2_HW_PREFETCH.CODE_TRIGGER", IAP_EVENT_F3H_08H)	\
    +__PMC_EV_ALIAS("L2_HW_PREFETCH.DCA_TRIGGER", IAP_EVENT_F3H_10H)		\
    +__PMC_EV_ALIAS("L2_HW_PREFETCH.KICK_START", IAP_EVENT_F3H_20H)		\
    +__PMC_EV_ALIAS("SQ_MISC.PROMOTION", IAP_EVENT_F4H_01H)			\
    +__PMC_EV_ALIAS("SQ_MISC.PROMOTION_POST_GO", IAP_EVENT_F4H_02H)		\
    +__PMC_EV_ALIAS("SQ_MISC.LRU_HINTS", IAP_EVENT_F4H_04H)			\
    +__PMC_EV_ALIAS("SQ_MISC.FILL_DROPPED", IAP_EVENT_F4H_08H)		\
    +__PMC_EV_ALIAS("SEGMENT_REG_LOADS", IAP_EVENT_F8H_01H)
    +
    +/*
    + * Aliases for Core i7 and Xeon 5500 PMC events (253669-033US December 2009)
      */
     #define	__PMC_EV_ALIAS_COREI7()						\
     __PMC_EV_ALIAS_INTEL_ARCHITECTURAL()					\
    -__PMC_EV_ALIAS("SB_FORWARD.ANY",			IAP_EVENT_02H_01H) \
    -__PMC_EV_ALIAS("LOAD_BLOCK.STD",			IAP_EVENT_03H_01H) \
    -__PMC_EV_ALIAS("LOAD_BLOCK.ADDRESS_OFFSET",		IAP_EVENT_03H_04H) \
    -__PMC_EV_ALIAS("SB_DRAIN.CYCLES",			IAP_EVENT_04H_01H) \
    -__PMC_EV_ALIAS("MISALIGN_MEM_REF.LOAD",			IAP_EVENT_05H_01H) \
    -__PMC_EV_ALIAS("MISALIGN_MEM_REF.STORE",		IAP_EVENT_05H_02H) \
    -__PMC_EV_ALIAS("MISALIGN_MEM_REF.ANY",			IAP_EVENT_05H_03H) \
    -__PMC_EV_ALIAS("STORE_BLOCKS.NOT_STA",			IAP_EVENT_06H_01H) \
    -__PMC_EV_ALIAS("STORE_BLOCKS.STA",			IAP_EVENT_06H_02H) \
    -__PMC_EV_ALIAS("STORE_BLOCKS.AT_RET",			IAP_EVENT_06H_04H) \
    -__PMC_EV_ALIAS("STORE_BLOCKS.L1D_BLOCK",		IAP_EVENT_06H_08H) \
    -__PMC_EV_ALIAS("STORE_BLOCKS.ANY",			IAP_EVENT_06H_0FH) \
    -__PMC_EV_ALIAS("PARTIAL_ADDRESS_ALIAS",			IAP_EVENT_07H_01H) \
    -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.ANY",			IAP_EVENT_08H_01H) \
    -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED",	IAP_EVENT_08H_02H) \
    -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT",		IAP_EVENT_08H_10H) \
    -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDE_MISS",		IAP_EVENT_08H_20H) \
    -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDP_MISS",		IAP_EVENT_08H_40H) \
    -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.LARGE_WALK_COMPLETED",	IAP_EVENT_08H_80H) \
    -__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.RESET",		IAP_EVENT_09H_01H) \
    -__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.SUCCESS",	IAP_EVENT_09H_02H) \
    -__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.WATCHDOG",	IAP_EVENT_09H_04H) \
    -__PMC_EV_ALIAS("MEMORY_DISAMBIGURATION.WATCH_CYCLES",	IAP_EVENT_09H_08H) \
    -__PMC_EV_ALIAS("MEM_INST_RETIRED.LOADS",		IAP_EVENT_0BH_01H) \
    -__PMC_EV_ALIAS("MEM_INST_RETIRED.STORES",		IAP_EVENT_0BH_02H) \
    -__PMC_EV_ALIAS("MEM_STORE_RETIRED.DTLB_MISS",		IAP_EVENT_0CH_01H) \
    -__PMC_EV_ALIAS("UOPS_ISSUED.ANY",			IAP_EVENT_0EH_01H) \
    -__PMC_EV_ALIAS("UOPS_ISSUED.FUSED",			IAP_EVENT_0EH_02H) \
    -__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.OTHER_CORE_L2_HITM",	IAP_EVENT_0FH_02H) \
    -__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_CACHE_LOCAL_HOME_HIT", IAP_EVENT_0FH_08H) \
    -__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_DRAM",	IAP_EVENT_0FH_10H) \
    -__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_DRAM",		IAP_EVENT_0FH_20H) \
    -__PMC_EV_ALIAS("FP_COMP_OPS_EXE.X87",			IAP_EVENT_10H_01H) \
    -__PMC_EV_ALIAS("FP_COMP_OPS_EXE.MMX",			IAP_EVENT_10H_02H) \
    -__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP",		IAP_EVENT_10H_04H) \
    -__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE2_INTEGER",		IAP_EVENT_10H_08H) \
    -__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_PACKED",		IAP_EVENT_10H_10H) \
    -__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_SCALAR",		IAP_EVENT_10H_20H) \
    -__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION",	IAP_EVENT_10H_40H) \
    -__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION",	IAP_EVENT_10H_80H) \
    -__PMC_EV_ALIAS("SIMD_INT_128.PACKED_MPY",		IAP_EVENT_12H_01H) \
    -__PMC_EV_ALIAS("SIMD_INT_128.PACKED_SHIFT",		IAP_EVENT_12H_02H) \
    -__PMC_EV_ALIAS("SIMD_INT_128.PACK",			IAP_EVENT_12H_04H) \
    -__PMC_EV_ALIAS("SIMD_INT_128.UNPACK",			IAP_EVENT_12H_08H) \
    -__PMC_EV_ALIAS("SIMD_INT_128.PACKED_LOGICAL",		IAP_EVENT_12H_10H) \
    -__PMC_EV_ALIAS("SIMD_INT_128.PACKED_ARITH",		IAP_EVENT_12H_20H) \
    -__PMC_EV_ALIAS("SIMD_INT_128.SHUFFLE_MOVE",		IAP_EVENT_12H_40H) \
    -__PMC_EV_ALIAS("LOAD_DISPATCH.RS",			IAP_EVENT_13H_01H) \
    -__PMC_EV_ALIAS("LOAD_DISPATCH.RS_DELAYED",		IAP_EVENT_13H_02H) \
    -__PMC_EV_ALIAS("LOAD_DISPATCH.MOB",			IAP_EVENT_13H_04H) \
    -__PMC_EV_ALIAS("LOAD_DISPATCH.ANY",			IAP_EVENT_13H_07H) \
    -__PMC_EV_ALIAS("ARITH.CYCLES_DIV_BUSY",			IAP_EVENT_14H_01H) \
    -__PMC_EV_ALIAS("ARITH.MUL",				IAP_EVENT_14H_02H) \
    -__PMC_EV_ALIAS("INST_QUEUE_WRITES",			IAP_EVENT_17H_01H) \
    -__PMC_EV_ALIAS("INST_DECODED.DEC0",			IAP_EVENT_18H_01H) \
    -__PMC_EV_ALIAS("TWO_UOP_INSTS_DECODED",			IAP_EVENT_19H_01H) \
    -__PMC_EV_ALIAS("HW_INT.RCV",				IAP_EVENT_1DH_01H) \
    -__PMC_EV_ALIAS("HW_INT.CYCLES_MASKED",			IAP_EVENT_1DH_02H) \
    -__PMC_EV_ALIAS("HW_INT.CYCLES_PENDING_AND_MASKED",	IAP_EVENT_1DH_04H) \
    -__PMC_EV_ALIAS("INST_QUEUE_WRITE_CYCLES",		IAP_EVENT_1EH_01H) \
    -__PMC_EV_ALIAS("L2_RQSTS.LD_HIT",			IAP_EVENT_24H_01H) \
    -__PMC_EV_ALIAS("L2_RQSTS.LD_MISS",			IAP_EVENT_24H_02H) \
    -__PMC_EV_ALIAS("L2_RQSTS.LOADS",			IAP_EVENT_24H_03H) \
    -__PMC_EV_ALIAS("L2_RQSTS.RFO_HIT",			IAP_EVENT_24H_04H) \
    -__PMC_EV_ALIAS("L2_RQSTS.RFO_MISS",			IAP_EVENT_24H_08H) \
    -__PMC_EV_ALIAS("L2_RQSTS.RFOS",				IAP_EVENT_24H_0CH) \
    -__PMC_EV_ALIAS("L2_RQSTS.IFETCH_HIT",			IAP_EVENT_24H_10H) \
    -__PMC_EV_ALIAS("L2_RQSTS.IFETCH_MISS",			IAP_EVENT_24H_20H) \
    -__PMC_EV_ALIAS("L2_RQSTS.IFETCHES",			IAP_EVENT_24H_30H) \
    -__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_HIT",			IAP_EVENT_24H_40H) \
    -__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_MISS",		IAP_EVENT_24H_80H) \
    -__PMC_EV_ALIAS("L2_RQSTS.PREFETCHES",			IAP_EVENT_24H_C0H) \
    -__PMC_EV_ALIAS("L2_RQSTS.MISS",				IAP_EVENT_24H_AAH) \
    -__PMC_EV_ALIAS("L2_RQSTS.REFERENCES",			IAP_EVENT_24H_FFH) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.I_STATE",		IAP_EVENT_26H_01H) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.S_STATE",		IAP_EVENT_26H_02H) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.E_STATE",		IAP_EVENT_26H_04H) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.M_STATE",		IAP_EVENT_26H_08H) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.MESI",		IAP_EVENT_26H_0FH) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.I_STATE",	IAP_EVENT_26H_10H) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.S_STATE",	IAP_EVENT_26H_20H) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.E_STATE",	IAP_EVENT_26H_40H) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.M_STATE",	IAP_EVENT_26H_80H) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.MESI",		IAP_EVENT_26H_F0H) \
    -__PMC_EV_ALIAS("L2_DATA_RQSTS.ANY",			IAP_EVENT_26H_FFH) \
    -__PMC_EV_ALIAS("L2_WRITE.RFO.I_STATE",			IAP_EVENT_27H_01H) \
    -__PMC_EV_ALIAS("L2_WRITE.RFO.S_STATE",			IAP_EVENT_27H_02H) \
    -__PMC_EV_ALIAS("L2_WRITE.RFO.E_STATE",			IAP_EVENT_27H_04H) \
    -__PMC_EV_ALIAS("L2_WRITE.RFO.M_STATE",			IAP_EVENT_27H_08H) \
    -__PMC_EV_ALIAS("L2_WRITE.RFO.HIT",			IAP_EVENT_27H_0EH) \
    -__PMC_EV_ALIAS("L2_WRITE.RFO.MESI",			IAP_EVENT_27H_0FH) \
    -__PMC_EV_ALIAS("L2_WRITE.LOCK.I_STATE",			IAP_EVENT_27H_10H) \
    -__PMC_EV_ALIAS("L2_WRITE.LOCK.S_STATE",			IAP_EVENT_27H_20H) \
    -__PMC_EV_ALIAS("L2_WRITE.LOCK.E_STATE",			IAP_EVENT_27H_40H) \
    -__PMC_EV_ALIAS("L2_WRITE.LOCK.M_STATE",			IAP_EVENT_27H_80H) \
    -__PMC_EV_ALIAS("L2_WRITE.LOCK.HIT",			IAP_EVENT_27H_E0H) \
    -__PMC_EV_ALIAS("L2_WRITE.LOCK.MESI",			IAP_EVENT_27H_F0H) \
    -__PMC_EV_ALIAS("L1D_WB_L2.I_STATE",			IAP_EVENT_28H_01H) \
    -__PMC_EV_ALIAS("L1D_WB_L2.S_STATE",			IAP_EVENT_28H_02H) \
    -__PMC_EV_ALIAS("L1D_WB_L2.E_STATE",			IAP_EVENT_28H_04H) \
    -__PMC_EV_ALIAS("L1D_WB_L2.M_STATE",			IAP_EVENT_28H_08H) \
    -__PMC_EV_ALIAS("L1D_WB_L2.MESI",			IAP_EVENT_28H_0FH) \
    -__PMC_EV_ALIAS("LONGEST_LAT_CACHE.REFERENCE",		IAP_EVENT_2EH_4FH) \
    -__PMC_EV_ALIAS("LONGEST_LAT_CACHE.MISS",		IAP_EVENT_2EH_41H) \
    -__PMC_EV_ALIAS("CPU_CLK_UNHALTED.THREAD_P",		IAP_EVENT_3CH_00H) \
    -__PMC_EV_ALIAS("CPU_CLK_UNHALTED.REF_P",		IAP_EVENT_3CH_01H) \
    -__PMC_EV_ALIAS("UOPS_DECODED.DEC0",			IAP_EVENT_3DH_01H) \
    -__PMC_EV_ALIAS("L1D_CACHE_LD.I_STATE",			IAP_EVENT_40H_01H) \
    -__PMC_EV_ALIAS("L1D_CACHE_LD.S_STATE",			IAP_EVENT_40H_02H) \
    -__PMC_EV_ALIAS("L1D_CACHE_LD.E_STATE",			IAP_EVENT_40H_04H) \
    -__PMC_EV_ALIAS("L1D_CACHE_LD.M_STATE",			IAP_EVENT_40H_08H) \
    -__PMC_EV_ALIAS("L1D_CACHE_LD.MESI",			IAP_EVENT_40H_0FH) \
    -__PMC_EV_ALIAS("L1D_CACHE_ST.I_STATE",			IAP_EVENT_41H_01H) \
    -__PMC_EV_ALIAS("L1D_CACHE_ST.S_STATE",			IAP_EVENT_41H_02H) \
    -__PMC_EV_ALIAS("L1D_CACHE_ST.E_STATE",			IAP_EVENT_41H_04H) \
    -__PMC_EV_ALIAS("L1D_CACHE_ST.M_STATE",			IAP_EVENT_41H_08H) \
    -__PMC_EV_ALIAS("L1D_CACHE_ST.MESI",			IAP_EVENT_41H_0FH) \
    -__PMC_EV_ALIAS("L1D_CACHE_LOCK.HIT",			IAP_EVENT_42H_01H) \
    -__PMC_EV_ALIAS("L1D_CACHE_LOCK.S_STATE",		IAP_EVENT_42H_02H) \
    -__PMC_EV_ALIAS("L1D_CACHE_LOCK.E_STATE",		IAP_EVENT_42H_04H) \
    -__PMC_EV_ALIAS("L1D_CACHE_LOCK.M_STATE",		IAP_EVENT_42H_08H) \
    -__PMC_EV_ALIAS("L1D_ALL_REF.ANY",			IAP_EVENT_43H_01H) \
    -__PMC_EV_ALIAS("L1D_ALL_REF.CACHEABLE",			IAP_EVENT_43H_02H) \
    -__PMC_EV_ALIAS("L1D_PEND_MISS.LOAD_BUFFERS_FULL",	IAP_EVENT_48H_02H) \
    -__PMC_EV_ALIAS("DTLB_MISSES.ANY",			IAP_EVENT_49H_01H) \
    -__PMC_EV_ALIAS("DTLB_MISSES.WALK_COMPLETED",		IAP_EVENT_49H_02H) \
    -__PMC_EV_ALIAS("DTLB_MISSES.STLB_HIT",			IAP_EVENT_49H_10H) \
    -__PMC_EV_ALIAS("DTLB_MISSES.PDE_MISS",			IAP_EVENT_49H_20H) \
    -__PMC_EV_ALIAS("DTLB_MISSES.PDP_MISS",			IAP_EVENT_49H_40H) \
    -__PMC_EV_ALIAS("DTLB_MISSES.LARGE_WALK_COMPLETED",	IAP_EVENT_49H_80H) \
    -__PMC_EV_ALIAS("SSE_MEM_EXEC.NTA",			IAP_EVENT_4BH_01H) \
    -__PMC_EV_ALIAS("SSE_MEM_EXEC.STREAMING_STORES",		IAP_EVENT_4BH_08H) \
    -__PMC_EV_ALIAS("LOAD_HIT_PRE",				IAP_EVENT_4CH_01H) \
    -__PMC_EV_ALIAS("SFENCE_CYCLES",				IAP_EVENT_4DH_01H) \
    -__PMC_EV_ALIAS("L1D_PREFETCH.REQUESTS",			IAP_EVENT_4EH_01H) \
    -__PMC_EV_ALIAS("L1D_PREFETCH.MISS",			IAP_EVENT_4EH_02H) \
    -__PMC_EV_ALIAS("L1D_PREFETCH.TRIGGERS",			IAP_EVENT_4EH_04H) \
    -__PMC_EV_ALIAS("EPT.EPDE_MISS",				IAP_EVENT_4FH_02H) \
    -__PMC_EV_ALIAS("EPT.EPDPE_HIT",				IAP_EVENT_4FH_04H) \
    -__PMC_EV_ALIAS("EPT.EPDPE_MISS",			IAP_EVENT_4FH_08H) \
    -__PMC_EV_ALIAS("L1D.REPL",				IAP_EVENT_51H_01H) \
    -__PMC_EV_ALIAS("L1D.M_REPL",				IAP_EVENT_51H_02H) \
    -__PMC_EV_ALIAS("L1D.M_EVICT",				IAP_EVENT_51H_04H) \
    -__PMC_EV_ALIAS("L1D.M_SNOOP_EVICT",			IAP_EVENT_51H_08H) \
    -__PMC_EV_ALIAS("L1D_CACHE_PREFETCH_LOCK_FB_HIT",	IAP_EVENT_52H_01H) \
    -__PMC_EV_ALIAS("L1D_CACHE_LOCK_FB_HIT",			IAP_EVENT_53H_01H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA", IAP_EVENT_60H_01H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE", IAP_EVENT_60H_02H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO", IAP_EVENT_60H_04H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.ANY.READ",	IAP_EVENT_60H_08H) \
    -__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D_L2",		IAP_EVENT_63H_01H) \
    -__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D",			IAP_EVENT_63H_02H) \
    -__PMC_EV_ALIAS("IO_TRANSACTIONS",			IAP_EVENT_6CH_01H) \
    -__PMC_EV_ALIAS("L1I.HITS",				IAP_EVENT_80H_01H) \
    -__PMC_EV_ALIAS("L1I.MISSES",				IAP_EVENT_80H_02H) \
    -__PMC_EV_ALIAS("L1I.READS",				IAP_EVENT_80H_03H) \
    -__PMC_EV_ALIAS("L1I.CYCLES_STALLED",			IAP_EVENT_80H_04H) \
    -__PMC_EV_ALIAS("IFU_IVC.FULL",				IAP_EVENT_81H_01H) \
    -__PMC_EV_ALIAS("IFU_IVC.L1I_EVICTION",			IAP_EVENT_81H_02H) \
    -__PMC_EV_ALIAS("LARGE_ITLB.HIT",			IAP_EVENT_82H_01H) \
    -__PMC_EV_ALIAS("L1I_OPPORTUNISTIC_HITS",		IAP_EVENT_83H_01H) \
    -__PMC_EV_ALIAS("ITLB_MISSES.ANY",			IAP_EVENT_85H_01H) \
    -__PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED",		IAP_EVENT_85H_02H) \
    -__PMC_EV_ALIAS("ITLB_MISSES.WALK_CYCLES",		IAP_EVENT_85H_04H) \
    -__PMC_EV_ALIAS("ITLB_MISSES.STLB_HIT",			IAP_EVENT_85H_10H) \
    -__PMC_EV_ALIAS("ITLB_MISSES.PDE_MISS",			IAP_EVENT_85H_20H) \
    -__PMC_EV_ALIAS("ITLB_MISSES.PDP_MISS",			IAP_EVENT_85H_40H) \
    -__PMC_EV_ALIAS("ITLB_MISSES.LARGE_WALK_COMPLETED",	IAP_EVENT_85H_80H) \
    -__PMC_EV_ALIAS("ILD_STALL.LCP",				IAP_EVENT_87H_01H) \
    -__PMC_EV_ALIAS("ILD_STALL.MRU",				IAP_EVENT_87H_02H) \
    -__PMC_EV_ALIAS("ILD_STALL.IQ_FULL",			IAP_EVENT_87H_04H) \
    -__PMC_EV_ALIAS("ILD_STALL.REGEN",			IAP_EVENT_87H_08H) \
    -__PMC_EV_ALIAS("ILD_STALL.ANY",				IAP_EVENT_87H_0FH) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.COND",			IAP_EVENT_88H_01H) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT",			IAP_EVENT_88H_02H) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NON_CALL",	IAP_EVENT_88H_04H) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.NON_CALLS",		IAP_EVENT_88H_07H) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.RETURN_NEAR",		IAP_EVENT_88H_08H) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_NEAR_CALL",		IAP_EVENT_88H_10H) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NEAR_CALL",	IAP_EVENT_88H_20H) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.NEAR_CALLS",		IAP_EVENT_88H_30H) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.TAKEN",			IAP_EVENT_88H_40H) \
    -__PMC_EV_ALIAS("BR_INST_EXEC.ANY",			IAP_EVENT_7FH)	\
    -__PMC_EV_ALIAS("BR_MISP_EXEC.COND",			IAP_EVENT_89H_01H) \
    -__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT",			IAP_EVENT_89H_02H) \
    -__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NON_CALL",	IAP_EVENT_89H_04H) \
    -__PMC_EV_ALIAS("BR_MISP_EXEC.NON_CALLS",		IAP_EVENT_89H_07H) \
    -__PMC_EV_ALIAS("BR_MISP_EXEC.RETURN_NEAR",		IAP_EVENT_89H_08H) \
    -__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT_NEAR_CALL",		IAP_EVENT_89H_10H) \
    -__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NEAR_CALL",	IAP_EVENT_89H_20H) \
    -__PMC_EV_ALIAS("BR_MISP_EXEC.NEAR_CALLS",		IAP_EVENT_89H_30H) \
    -__PMC_EV_ALIAS("BR_MISP_EXEC.TAKEN",			IAP_EVENT_89H_40H) \
    -__PMC_EV_ALIAS("BR_MISP_EXEC.ANY",			IAP_EVENT_89H_7FH) \
    -__PMC_EV_ALIAS("RESOURCE_STALLS.ANY",			IAP_EVENT_A2H_01H) \
    -__PMC_EV_ALIAS("RESOURCE_STALLS.LOAD",			IAP_EVENT_A2H_02H) \
    -__PMC_EV_ALIAS("RESOURCE_STALLS.RS_FULL",		IAP_EVENT_A2H_04H) \
    -__PMC_EV_ALIAS("RESOURCE_STALLS.STORE",			IAP_EVENT_A2H_08H) \
    -__PMC_EV_ALIAS("RESOURCE_STALLS.ROB_FULL",		IAP_EVENT_A2H_10H) \
    -__PMC_EV_ALIAS("RESOURCE_STALLS.FPCW",			IAP_EVENT_A2H_20H) \
    -__PMC_EV_ALIAS("RESOURCE_STALLS.MXCSR",			IAP_EVENT_A2H_40H) \
    -__PMC_EV_ALIAS("RESOURCE_STALLS.OTHER",			IAP_EVENT_A2H_80H) \
    -__PMC_EV_ALIAS("MACRO_INSTS.FUSIONS_DECODED",		IAP_EVENT_A6H_01H) \
    -__PMC_EV_ALIAS("BACLEAR_FORCE_IQ",			IAP_EVENT_A7H_01H) \
    -__PMC_EV_ALIAS("LSD.UOPS",				IAP_EVENT_A8H_01H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_DATA",	IAP_EVENT_B0H_01H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_CODE",	IAP_EVENT_B0H_02H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.RFO",		IAP_EVENT_B0H_04H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.READ",		IAP_EVENT_B0H_08H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.RFO",		IAP_EVENT_80H_10H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS.UNCACHED_MEM",		IAP_EVENT_B0H_20H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS.L1D_WRITEBACK",	IAP_EVENT_B0H_40H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY",			IAP_EVENT_B0H_80H) \
    -__PMC_EV_ALIAS("UOPS_EXECUTED.PORT0",			IAP_EVENT_B1H_01H) \
    -__PMC_EV_ALIAS("UOPS_EXECUTED.PORT1",			IAP_EVENT_B1H_02H) \
    -__PMC_EV_ALIAS("UOPS_EXECUTED.PORT2_CORE",		IAP_EVENT_B1H_04H) \
    -__PMC_EV_ALIAS("UOPS_EXECUTED.PORT3_CORE",		IAP_EVENT_B1H_08H) \
    -__PMC_EV_ALIAS("UOPS_EXECUTED.PORT4_CORE",		IAP_EVENT_B1H_10H) \
    -__PMC_EV_ALIAS("UOPS_EXECUTED.PORT5",			IAP_EVENT_B1H_20H) \
    -__PMC_EV_ALIAS("UOPS_EXECUTED.PORT015",			IAP_EVENT_B1H_40H) \
    -__PMC_EV_ALIAS("UOPS_EXECUTED.PORT234",			IAP_EVENT_B1H_80H) \
    -__PMC_EV_ALIAS("OFFCORE_REQUESTS_SQ_FULL",		IAP_EVENT_B2H_01H) \
    -__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.DATA",	IAP_EVENT_B3H_01H) \
    -__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE", IAP_EVENT_B3H_02H) \
    -__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.CODE",	IAP_EVENT_B3H_04H) \
    -__PMC_EV_ALIAS("OOF_CORE_RESPONSE_0",			IAP_EVENT_B7H_01H) \
    -__PMC_EV_ALIAS("SNOOP_RESPONSE.HIT",			IAP_EVENT_B8H_01H) \
    -__PMC_EV_ALIAS("SNOOP_RESPONSE.HITE",			IAP_EVENT_B8H_02H) \
    -__PMC_EV_ALIAS("SNOOP_RESPONSE.HITM",			IAP_EVENT_B8H_04H) \
    -__PMC_EV_ALIAS("PIC_ACCESSES.TPR_READS",		IAP_EVENT_BAH_01H) \
    -__PMC_EV_ALIAS("PIC_ACCESSES.TPR_WRITES",		IAP_EVENT_BAH_02H) \
    -__PMC_EV_ALIAS("INST_RETIRED.ANY_P",			IAP_EVENT_C0H_01H) \
    -__PMC_EV_ALIAS("INST_RETIRED.X87",			IAP_EVENT_C0H_02H) \
    -__PMC_EV_ALIAS("UOPS_RETIRED.ANY",			IAP_EVENT_C2H_01H) \
    -__PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS",		IAP_EVENT_C2H_02H) \
    -__PMC_EV_ALIAS("UOPS_RETIRED.MACRO_FUSED",		IAP_EVENT_C2H_04H) \
    -__PMC_EV_ALIAS("MACHINE_CLEARS.CYCLES",			IAP_EVENT_C3H_01H) \
    -__PMC_EV_ALIAS("MACHINE_CLEARS.MEM_ORDER",		IAP_EVENT_C3H_02H) \
    -__PMC_EV_ALIAS("MACHINE_CLEARS.SMC",			IAP_EVENT_C3H_04H) \
    -__PMC_EV_ALIAS("MACHINE_CLEARS.FUSION_ASSIST",		IAP_EVENT_C3H_10H) \
    -__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES",		IAP_EVENT_C4H_00H) \
    -__PMC_EV_ALIAS("BR_INST_RETIRED.CONDITIONAL",		IAP_EVENT_C4H_01H) \
    -__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_CALL",		IAP_EVENT_C4H_02H) \
    -__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES",		IAP_EVENT_C4H_04H) \
    -__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES",		IAP_EVENT_C5H_00H) \
    -__PMC_EV_ALIAS("BR_MISP_RETIRED.NEAR_CALL",		IAP_EVENT_C5H_02H) \
    -__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_SINGLE",	IAP_EVENT_C7H_01H) \
    -__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_SINGLE",	IAP_EVENT_C7H_02H) \
    -__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_DOUBLE",	IAP_EVENT_C7H_04H) \
    -__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_DOUBLE",	IAP_EVENT_C7H_08H) \
    -__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.VECTOR_INTEGER",	IAP_EVENT_C7H_10H) \
    -__PMC_EV_ALIAS("ITLB_MISS_RETIRED",			IAP_EVENT_C8H_20H) \
    -__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L1D_HIT",		IAP_EVENT_CBH_01H) \
    -__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L2_HIT",		IAP_EVENT_CBH_02H) \
    -__PMC_EV_ALIAS("MEM_LOAD_RETIRED.LLC_UNSHARED_HIT",	IAP_EVENT_CBH_04H) \
    -__PMC_EV_ALIAS("MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM", IAP_EVENT_CBH_08H) \
    -__PMC_EV_ALIAS("MEM_LOAD_RETIRED.LLC_MISS",		IAP_EVENT_CBH_10H) \
    -__PMC_EV_ALIAS("MEM_LOAD_RETIRED.HIT_LFB",		IAP_EVENT_CBH_40H) \
    -__PMC_EV_ALIAS("MEM_LOAD_RETIRED.DTLB_MISS",		IAP_EVENT_CBH_80H) \
    -__PMC_EV_ALIAS("FP_MMX_TRANS.TO_FP",			IAP_EVENT_CCH_01H) \
    -__PMC_EV_ALIAS("FP_MMX_TRANS.TO_MMX",			IAP_EVENT_CCH_02H) \
    -__PMC_EV_ALIAS("FP_MMX_TRANS.ANY",			IAP_EVENT_CCH_03H) \
    -__PMC_EV_ALIAS("MACRO_INSTS.DECODED",			IAP_EVENT_D0H_01H) \
    -__PMC_EV_ALIAS("UOPS_DECODED.MS",			IAP_EVENT_D1H_02H) \
    -__PMC_EV_ALIAS("UOPS_DECODED.ESP_FOLDING",		IAP_EVENT_D1H_04H) \
    -__PMC_EV_ALIAS("UOPS_DECODED.ESP_SYNC",			IAP_EVENT_D1H_08H) \
    -__PMC_EV_ALIAS("RAT_STALLS.FLAGS",			IAP_EVENT_D2H_01H) \
    -__PMC_EV_ALIAS("RAT_STALLS.REGISTERS",			IAP_EVENT_D2H_02H) \
    -__PMC_EV_ALIAS("RAT_STALLS.ROB_READ_PORT",		IAP_EVENT_D2H_04H) \
    -__PMC_EV_ALIAS("RAT_STALLS.SCOREBOARD",			IAP_EVENT_D2H_08H) \
    -__PMC_EV_ALIAS("RAT_STALLS.ANY",			IAP_EVENT_D2H_0FH) \
    -__PMC_EV_ALIAS("SEG_RENAME_STALLS",			IAP_EVENT_D4H_01H) \
    -__PMC_EV_ALIAS("ES_REG_RENAMES",			IAP_EVENT_D5H_01H) \
    -__PMC_EV_ALIAS("UOP_UNFUSION",				IAP_EVENT_DBH_01H) \
    -__PMC_EV_ALIAS("BR_INST_DECODED",			IAP_EVENT_E0H_01H) \
    -__PMC_EV_ALIAS("BOGUS_BR",				IAP_EVENT_E4H_01H) \
    -__PMC_EV_ALIAS("BPU_MISSED_CALL_RET",			IAP_EVENT_E5H_01H) \
    -__PMC_EV_ALIAS("BACLEAR.CLEAR",				IAP_EVENT_E6H_01H) \
    -__PMC_EV_ALIAS("BACLEAR.BAD_TARGET",			IAP_EVENT_E6H_02H) \
    -__PMC_EV_ALIAS("BPU_CLEARS.EARLY",			IAP_EVENT_E8H_01H) \
    -__PMC_EV_ALIAS("BPU_CLEARS.LATE",			IAP_EVENT_E8H_02H) \
    -__PMC_EV_ALIAS("BPU_CLEARS.ANY",			IAP_EVENT_E8H_03H) \
    -__PMC_EV_ALIAS("L2_TRANSACTIONS.LOAD",			IAP_EVENT_F0H_01H) \
    -__PMC_EV_ALIAS("L2_TRANSACTIONS.RFO",			IAP_EVENT_F0H_02H) \
    -__PMC_EV_ALIAS("L2_TRANSACTIONS.IFETCH",		IAP_EVENT_F0H_04H) \
    -__PMC_EV_ALIAS("L2_TRANSACTIONS.PREFETCH",		IAP_EVENT_F0H_08H) \
    -__PMC_EV_ALIAS("L2_TRANSACTIONS.L1D_WB",		IAP_EVENT_F0H_10H) \
    -__PMC_EV_ALIAS("L2_TRANSACTIONS.FILL",			IAP_EVENT_F0H_20H) \
    -__PMC_EV_ALIAS("L2_TRANSACTIONS.WB",			IAP_EVENT_F0H_40H) \
    -__PMC_EV_ALIAS("L2_TRANSACTIONS.ANY",			IAP_EVENT_F0H_80H) \
    -__PMC_EV_ALIAS("L2_LINES_IN.S_STATE",			IAP_EVENT_F1H_02H) \
    -__PMC_EV_ALIAS("L2_LINES_IN.E_STATE",			IAP_EVENT_F1H_04H) \
    -__PMC_EV_ALIAS("L2_LINES_IN.ANY",			IAP_EVENT_F1H_07H) \
    -__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_CLEAN",		IAP_EVENT_F2H_01H) \
    -__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY",		IAP_EVENT_F2H_02H) \
    -__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_CLEAN",		IAP_EVENT_F2H_04H) \
    -__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_DIRTY",		IAP_EVENT_F2H_08H) \
    -__PMC_EV_ALIAS("L2_LINES_OUT.ANY",			IAP_EVENT_F2H_0FH) \
    -__PMC_EV_ALIAS("L2_HW_PREFETCH.HIT",			IAP_EVENT_F3H_01H) \
    -__PMC_EV_ALIAS("L2_HW_PREFETCH.ALLOC",			IAP_EVENT_F3H_02H) \
    -__PMC_EV_ALIAS("L2_HW_PREFETCH.DATA_TRIGGER",		IAP_EVENT_F3H_04H) \
    -__PMC_EV_ALIAS("L2_HW_PREFETCH.CODE_TRIGGER",		IAP_EVENT_F3H_08H) \
    -__PMC_EV_ALIAS("L2_HW_PREFETCH.DCA_TRIGGER",		IAP_EVENT_F3H_10H) \
    -__PMC_EV_ALIAS("L2_HW_PREFETCH.KICK_START",		IAP_EVENT_F3H_20H) \
    -__PMC_EV_ALIAS("SQ_MISC.PROMOTION",			IAP_EVENT_F4H_01H) \
    -__PMC_EV_ALIAS("SQ_MISC.PROMOTION_POST_GO",		IAP_EVENT_F4H_02H) \
    -__PMC_EV_ALIAS("SQ_MISC.LRU_HINTS",			IAP_EVENT_F4H_04H) \
    -__PMC_EV_ALIAS("SQ_MISC.FILL_DROPPED",			IAP_EVENT_F4H_08H) \
    -__PMC_EV_ALIAS("SQ_MISC.SPLIT_LOCK",			IAP_EVENT_F4H_10H) \
    -__PMC_EV_ALIAS("SQ_FULL_STALL_CYCLES",			IAP_EVENT_F6H_01H) \
    -__PMC_EV_ALIAS("FP_ASSIST.ALL",				IAP_EVENT_F7H_01H) \
    -__PMC_EV_ALIAS("FP_ASSIST.OUTPUT",			IAP_EVENT_F7H_02H) \
    -__PMC_EV_ALIAS("FP_ASSIST.INPUT",			IAP_EVENT_F7H_04H) \
    -__PMC_EV_ALIAS("SEGMENT_REG_LOADS",			IAP_EVENT_F8H_01H) \
    -__PMC_EV_ALIAS("SIMD_INT_64.PACKED_MPY",		IAP_EVENT_FDH_01H) \
    -__PMC_EV_ALIAS("SIMD_INT_64.PACKED_SHIFT",		IAP_EVENT_FDH_02H) \
    -__PMC_EV_ALIAS("SIMD_INT_64.PACK",			IAP_EVENT_FDH_04H) \
    -__PMC_EV_ALIAS("SIMD_INT_64.UNPACK",			IAP_EVENT_FDH_08H) \
    -__PMC_EV_ALIAS("SIMD_INT_64.PACKED_LOGICAL",		IAP_EVENT_FDH_10H) \
    -__PMC_EV_ALIAS("SIMD_INT_64.PACKED_ARITH",		IAP_EVENT_FDH_20H) \
    -__PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE",		IAP_EVENT_FDH_40H)
    +__PMC_EV_ALIAS("SB_DRAIN.ANY", 	IAP_EVENT_04H_07H)			\
    +__PMC_EV_ALIAS("STORE_BLOCKS.AT_RET", IAP_EVENT_06H_04H)		\
    +__PMC_EV_ALIAS("STORE_BLOCKS.L1D_BLOCK", IAP_EVENT_06H_08H)		\
    +__PMC_EV_ALIAS("PARTIAL_ADDRESS_ALIAS", IAP_EVENT_07H_01H)		\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.ANY", IAP_EVENT_08H_01H)		\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_02H)	\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT", IAP_EVENT_08H_10H)		\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDE_MISS", IAP_EVENT_08H_20H)		\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDP_MISS", IAP_EVENT_08H_40H)		\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.LARGE_WALK_COMPLETED",			\
    +    IAP_EVENT_08H_80H) 							\
    +__PMC_EV_ALIAS("MEM_INST_RETIRED.LOADS", IAP_EVENT_0BH_01H)		\
    +__PMC_EV_ALIAS("MEM_INST_RETIRED.STORES", IAP_EVENT_0BH_02H)		\
    +__PMC_EV_ALIAS("MEM_INST_RETIRED.LATENCY_ABOVE_THRESHOLD",		\
    +    IAP_EVENT_0BH_10H) 							\
    +__PMC_EV_ALIAS("MEM_STORE_RETIRED.DTLB_MISS", IAP_EVENT_0CH_01H)	\
    +__PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H)			\
    +__PMC_EV_ALIAS("UOPS_ISSUED.STALLED_CYCLES", IAP_EVENT_0EH_01H)		\
    +__PMC_EV_ALIAS("UOPS_ISSUED.FUSED", IAP_EVENT_0EH_02H)			\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.L3_DATA_MISS_UNKNOWN",		\
    +    IAP_EVENT_0FH_01H)							\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.OTHER_CORE_L2_HITM",			\
    +    IAP_EVENT_0FH_02H)							\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_CACHE_LOCAL_HOME_HIT",	\
    +    IAP_EVENT_0FH_08H)							\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_DRAM",			\
    +    IAP_EVENT_0FH_10H)							\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_DRAM", IAP_EVENT_0FH_20H)	\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.UNCACHEABLE", IAP_EVENT_0FH_80H)	\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.X87", IAP_EVENT_10H_01H)		\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.MMX", IAP_EVENT_10H_02H)		\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP", IAP_EVENT_10H_04H)		\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE2_INTEGER", IAP_EVENT_10H_08H)	\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_PACKED", IAP_EVENT_10H_10H)	\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_SCALAR", IAP_EVENT_10H_20H)	\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION",			\
    +    IAP_EVENT_10H_40H)							\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION",			\
    +    IAP_EVENT_10H_80H)							\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACKED_MPY", IAP_EVENT_12H_01H)		\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACKED_SHIFT", IAP_EVENT_12H_02H)		\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACK", IAP_EVENT_12H_04H)			\
    +__PMC_EV_ALIAS("SIMD_INT_128.UNPACK", IAP_EVENT_12H_08H)		\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACKED_LOGICAL", IAP_EVENT_12H_10H)	\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACKED_ARITH", IAP_EVENT_12H_20H)		\
    +__PMC_EV_ALIAS("SIMD_INT_128.SHUFFLE_MOVE", IAP_EVENT_12H_40H)		\
    +__PMC_EV_ALIAS("LOAD_DISPATCH.RS", IAP_EVENT_13H_01H)			\
    +__PMC_EV_ALIAS("LOAD_DISPATCH.RS_DELAYED", IAP_EVENT_13H_02H)		\
    +__PMC_EV_ALIAS("LOAD_DISPATCH.MOB", IAP_EVENT_13H_04H)			\
    +__PMC_EV_ALIAS("LOAD_DISPATCH.ANY", IAP_EVENT_13H_07H)			\
    +__PMC_EV_ALIAS("ARITH.CYCLES_DIV_BUSY", IAP_EVENT_14H_01H)		\
    +__PMC_EV_ALIAS("ARITH.MUL", IAP_EVENT_14H_02H)				\
    +__PMC_EV_ALIAS("INST_QUEUE_WRITES", IAP_EVENT_17H_01H)			\
    +__PMC_EV_ALIAS("INST_DECODED.DEC0", IAP_EVENT_18H_01H)			\
    +__PMC_EV_ALIAS("TWO_UOP_INSTS_DECODED", IAP_EVENT_19H_01H)		\
    +__PMC_EV_ALIAS("INST_QUEUE_WRITE_CYCLES", IAP_EVENT_1EH_01H)		\
    +__PMC_EV_ALIAS("LSD_OVERFLOW", IAP_EVENT_20H_01H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.LD_HIT", IAP_EVENT_24H_01H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.LD_MISS", IAP_EVENT_24H_02H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.LOADS", IAP_EVENT_24H_03H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.RFO_HIT", IAP_EVENT_24H_04H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.RFO_MISS", IAP_EVENT_24H_08H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.RFOS", IAP_EVENT_24H_0CH)			\
    +__PMC_EV_ALIAS("L2_RQSTS.IFETCH_HIT", IAP_EVENT_24H_10H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.IFETCH_MISS", IAP_EVENT_24H_20H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.IFETCHES", IAP_EVENT_24H_30H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_HIT", IAP_EVENT_24H_40H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_MISS", IAP_EVENT_24H_80H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.PREFETCHES", IAP_EVENT_24H_C0H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.MISS", IAP_EVENT_24H_AAH)			\
    +__PMC_EV_ALIAS("L2_RQSTS.REFERENCES", IAP_EVENT_24H_FFH)		\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.I_STATE", IAP_EVENT_26H_01H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.S_STATE", IAP_EVENT_26H_02H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.E_STATE", IAP_EVENT_26H_04H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.M_STATE", IAP_EVENT_26H_08H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.MESI", IAP_EVENT_26H_0FH)		\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.I_STATE", IAP_EVENT_26H_10H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.S_STATE", IAP_EVENT_26H_20H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.E_STATE", IAP_EVENT_26H_40H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.M_STATE", IAP_EVENT_26H_80H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.MESI", IAP_EVENT_26H_F0H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.ANY", IAP_EVENT_26H_FFH)			\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.I_STATE", IAP_EVENT_27H_01H)		\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.S_STATE", IAP_EVENT_27H_02H)		\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.M_STATE", IAP_EVENT_27H_08H)		\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.HIT", IAP_EVENT_27H_0EH)			\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.MESI", IAP_EVENT_27H_0FH)			\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.I_STATE", IAP_EVENT_27H_10H)		\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.S_STATE", IAP_EVENT_27H_20H)		\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.E_STATE", IAP_EVENT_27H_40H)		\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.M_STATE", IAP_EVENT_27H_80H)		\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.HIT", IAP_EVENT_27H_E0H)			\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.MESI", IAP_EVENT_27H_F0H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.I_STATE", IAP_EVENT_28H_01H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.S_STATE", IAP_EVENT_28H_02H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.E_STATE", IAP_EVENT_28H_04H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.M_STATE", IAP_EVENT_28H_08H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.MESI", IAP_EVENT_28H_0FH)			\
    +__PMC_EV_ALIAS("L3_LAT_CACHE.REFERENCE", IAP_EVENT_2EH_4FH)		\
    +__PMC_EV_ALIAS("L3_LAT_CACHE.MISS", IAP_EVENT_2EH_41H)			\
    +__PMC_EV_ALIAS("CPU_CLK_UNHALTED.THREAD_P", IAP_EVENT_3CH_00H)		\
    +__PMC_EV_ALIAS("CPU_CLK_UNHALTED.REF_P", IAP_EVENT_3CH_01H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_LD.I_STATE", IAP_EVENT_40H_01H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_LD.S_STATE", IAP_EVENT_40H_02H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_LD.E_STATE", IAP_EVENT_40H_04H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_LD.M_STATE", IAP_EVENT_40H_08H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_LD.MESI", IAP_EVENT_40H_0FH)			\
    +__PMC_EV_ALIAS("L1D_CACHE_ST.S_STATE", IAP_EVENT_41H_02H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_ST.E_STATE", IAP_EVENT_41H_04H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_ST.M_STATE", IAP_EVENT_41H_08H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_LOCK.HIT", IAP_EVENT_42H_01H)			\
    +__PMC_EV_ALIAS("L1D_CACHE_LOCK.S_STATE", IAP_EVENT_42H_02H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_LOCK.E_STATE", IAP_EVENT_42H_04H)		\
    +__PMC_EV_ALIAS("L1D_CACHE_LOCK.M_STATE", IAP_EVENT_42H_08H)		\
    +__PMC_EV_ALIAS("L1D_ALL_REF.ANY", IAP_EVENT_43H_01H)			\
    +__PMC_EV_ALIAS("L1D_ALL_REF.CACHEABLE", IAP_EVENT_43H_02H)		\
    +__PMC_EV_ALIAS("L1D_PEND_MISS.LOAD_BUFFERS_FULL", IAP_EVENT_48H_02H)	\
    +__PMC_EV_ALIAS("DTLB_MISSES.ANY", IAP_EVENT_49H_01H)			\
    +__PMC_EV_ALIAS("DTLB_MISSES.WALK_COMPLETED", IAP_EVENT_49H_02H)		\
    +__PMC_EV_ALIAS("DTLB_MISSES.STLB_HIT", IAP_EVENT_49H_10H)		\
    +__PMC_EV_ALIAS("LOAD_HIT_PRE", IAP_EVENT_4CH_01H)			\
    +__PMC_EV_ALIAS("L1D_PREFETCH.REQUESTS", IAP_EVENT_4EH_01H)		\
    +__PMC_EV_ALIAS("L1D_PREFETCH.MISS", IAP_EVENT_4EH_02H)			\
    +__PMC_EV_ALIAS("L1D_PREFETCH.TRIGGERS", IAP_EVENT_4EH_04H)		\
    +__PMC_EV_ALIAS("L1D.REPL", IAP_EVENT_51H_01H)				\
    +__PMC_EV_ALIAS("L1D.M_REPL", IAP_EVENT_51H_02H)				\
    +__PMC_EV_ALIAS("L1D.M_EVICT", IAP_EVENT_51H_04H)			\
    +__PMC_EV_ALIAS("L1D.M_SNOOP_EVICT", IAP_EVENT_51H_08H)			\
    +__PMC_EV_ALIAS("L1D_CACHE_PREFETCH_LOCK_FB_HIT", IAP_EVENT_52H_01H)	\
    +__PMC_EV_ALIAS("L1D_CACHE_LOCK_FB_HIT", IAP_EVENT_53H_01H)		\
    +__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D_L2", IAP_EVENT_63H_01H)		\
    +__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D", IAP_EVENT_63H_02H)		\
    +__PMC_EV_ALIAS("IO_TRANSACTIONS", IAP_EVENT_6CH_01H)			\
    +__PMC_EV_ALIAS("L1I.HITS", IAP_EVENT_80H_01H)				\
    +__PMC_EV_ALIAS("L1I.MISSES", IAP_EVENT_80H_02H)				\
    +__PMC_EV_ALIAS("L1I.READS", IAP_EVENT_80H_03H)				\
    +__PMC_EV_ALIAS("L1I.CYCLES_STALLED", IAP_EVENT_80H_04H)			\
    +__PMC_EV_ALIAS("LARGE_ITLB.HIT", IAP_EVENT_82H_01H)			\
    +__PMC_EV_ALIAS("ITLB_MISSES.ANY", IAP_EVENT_85H_01H)			\
    +__PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED", IAP_EVENT_85H_02H)		\
    +__PMC_EV_ALIAS("ILD_STALL.LCP", IAP_EVENT_87H_01H)			\
    +__PMC_EV_ALIAS("ILD_STALL.MRU", IAP_EVENT_87H_02H)			\
    +__PMC_EV_ALIAS("ILD_STALL.IQ_FULL", IAP_EVENT_87H_04H)			\
    +__PMC_EV_ALIAS("ILD_STALL.REGEN", IAP_EVENT_87H_08H)			\
    +__PMC_EV_ALIAS("ILD_STALL.ANY", IAP_EVENT_87H_0FH)			\
    +__PMC_EV_ALIAS("BR_INST_EXEC.COND", IAP_EVENT_88H_01H)			\
    +__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT", IAP_EVENT_88H_02H)		\
    +__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NON_CALL", IAP_EVENT_88H_04H)	\
    +__PMC_EV_ALIAS("BR_INST_EXEC.NON_CALLS", IAP_EVENT_88H_07H)		\
    +__PMC_EV_ALIAS("BR_INST_EXEC.RETURN_NEAR", IAP_EVENT_88H_08H)		\
    +__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_88H_10H)	\
    +__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_88H_20H)	\
    +__PMC_EV_ALIAS("BR_INST_EXEC.NEAR_CALLS", IAP_EVENT_88H_30H)		\
    +__PMC_EV_ALIAS("BR_INST_EXEC.TAKEN", IAP_EVENT_88H_40H)			\
    +__PMC_EV_ALIAS("BR_INST_EXEC.ANY", IAP_EVENT_88H_7FH)			\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.COND", IAP_EVENT_89H_01H)			\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT", IAP_EVENT_89H_02H)		\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NON_CALL", IAP_EVENT_89H_04H)	\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.NON_CALLS", IAP_EVENT_89H_07H)		\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.RETURN_NEAR", IAP_EVENT_89H_08H)		\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_89H_10H)	\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_89H_20H)	\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.NEAR_CALLS", IAP_EVENT_89H_30H)		\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.TAKEN", IAP_EVENT_89H_40H)			\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.ANY", IAP_EVENT_89H_7FH)			\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.ANY", IAP_EVENT_A2H_01H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.LOAD", IAP_EVENT_A2H_02H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.RS_FULL", IAP_EVENT_A2H_04H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.STORE", IAP_EVENT_A2H_08H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.ROB_FULL", IAP_EVENT_A2H_10H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.FPCW", IAP_EVENT_A2H_20H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.MXCSR", IAP_EVENT_A2H_40H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.OTHER", IAP_EVENT_A2H_80H)		\
    +__PMC_EV_ALIAS("MACRO_INSTS.FUSIONS_DECODED", IAP_EVENT_A6H_01H)	\
    +__PMC_EV_ALIAS("BACLEAR_FORCE_IQ", IAP_EVENT_A7H_01H)			\
    +__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H)				\
    +__PMC_EV_ALIAS("ITLB_FLUSH", IAP_EVENT_AEH_01H)				\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.L1D_WRITEBACK", IAP_EVENT_B0H_40H)	\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT0", IAP_EVENT_B1H_01H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT1", IAP_EVENT_B1H_02H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT2_CORE", IAP_EVENT_B1H_04H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT3_CORE", IAP_EVENT_B1H_08H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT4_CORE", IAP_EVENT_B1H_10H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.CORE_ACTIVE_CYCLES_NO_PORT5",		\
    +    IAP_EVENT_B1H_1FH)							\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT5", IAP_EVENT_B1H_20H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.CORE_ACTIVE_CYCLES", IAP_EVENT_B1H_3FH)	\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT015", IAP_EVENT_B1H_40H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT234", IAP_EVENT_B1H_80H)		\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_SQ_FULL", IAP_EVENT_B2H_01H)		\
    +__PMC_EV_ALIAS("OFF_CORE_RESPONSE_0", IAP_EVENT_B7H_01H)		\
    +__PMC_EV_ALIAS("SNOOP_RESPONSE.HIT", IAP_EVENT_B8H_01H)			\
    +__PMC_EV_ALIAS("SNOOP_RESPONSE.HITE", IAP_EVENT_B8H_02H)		\
    +__PMC_EV_ALIAS("SNOOP_RESPONSE.HITM", IAP_EVENT_B8H_04H)		\
    +__PMC_EV_ALIAS("OFF_CORE_RESPONSE_1", IAP_EVENT_BBH_01H)		\
    +__PMC_EV_ALIAS("INST_RETIRED.ANY_P", IAP_EVENT_C0H_01H)			\
    +__PMC_EV_ALIAS("INST_RETIRED.X87", IAP_EVENT_C0H_02H)			\
    +__PMC_EV_ALIAS("INST_RETIRED.MMX", IAP_EVENT_C0H_04H)			\
    +__PMC_EV_ALIAS("UOPS_RETIRED.ANY", IAP_EVENT_C2H_01H)			\
    +__PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS", IAP_EVENT_C2H_02H)		\
    +__PMC_EV_ALIAS("UOPS_RETIRED.MACRO_FUSED", IAP_EVENT_C2H_04H)		\
    +__PMC_EV_ALIAS("MACHINE_CLEARS.CYCLES", IAP_EVENT_C3H_01H)		\
    +__PMC_EV_ALIAS("MACHINE_CLEARS.MEM_ORDER", IAP_EVENT_C3H_02H)		\
    +__PMC_EV_ALIAS("MACHINE_CLEARS.SMC", IAP_EVENT_C3H_04H)			\
    +__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_00H)	\
    +__PMC_EV_ALIAS("BR_INST_RETIRED.CONDITIONAL", IAP_EVENT_C4H_01H)	\
    +__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_CALL", IAP_EVENT_C4H_02H)		\
    +__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_04H)	\
    +__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_00H)	\
    +__PMC_EV_ALIAS("BR_MISP_RETIRED.NEAR_CALL", IAP_EVENT_C5H_02H)		\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_SINGLE", IAP_EVENT_C7H_01H)	\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_SINGLE", IAP_EVENT_C7H_02H)	\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_DOUBLE", IAP_EVENT_C7H_04H)	\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_DOUBLE", IAP_EVENT_C7H_08H)	\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.VECTOR_INTEGER", IAP_EVENT_C7H_10H)	\
    +__PMC_EV_ALIAS("ITLB_MISS_RETIRED", IAP_EVENT_C8H_20H)			\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L1D_HIT", IAP_EVENT_CBH_01H)		\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L2_HIT", IAP_EVENT_CBH_02H)		\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L3_UNSHARED_HIT", IAP_EVENT_CBH_04H)	\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM",		\
    +    IAP_EVENT_CBH_08H)							\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L3_MISS", IAP_EVENT_CBH_10H)		\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.HIT_LFB", IAP_EVENT_CBH_40H)		\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.DTLB_MISS", IAP_EVENT_CBH_80H)		\
    +__PMC_EV_ALIAS("FP_MMX_TRANS.TO_FP", IAP_EVENT_CCH_01H)			\
    +__PMC_EV_ALIAS("FP_MMX_TRANS.TO_MMX", IAP_EVENT_CCH_02H)		\
    +__PMC_EV_ALIAS("FP_MMX_TRANS.ANY", IAP_EVENT_CCH_03H)			\
    +__PMC_EV_ALIAS("MACRO_INSTS.DECODED", IAP_EVENT_D0H_01H)		\
    +__PMC_EV_ALIAS("UOPS_DECODED.MS", IAP_EVENT_D1H_02H)			\
    +__PMC_EV_ALIAS("UOPS_DECODED.ESP_FOLDING", IAP_EVENT_D1H_04H)		\
    +__PMC_EV_ALIAS("UOPS_DECODED.ESP_SYNC", IAP_EVENT_D1H_08H)		\
    +__PMC_EV_ALIAS("RAT_STALLS.FLAGS", IAP_EVENT_D2H_01H)			\
    +__PMC_EV_ALIAS("RAT_STALLS.REGISTERS", IAP_EVENT_D2H_02H)		\
    +__PMC_EV_ALIAS("RAT_STALLS.ROB_READ_PORT", IAP_EVENT_D2H_04H)		\
    +__PMC_EV_ALIAS("RAT_STALLS.SCOREBOARD", IAP_EVENT_D2H_08H)		\
    +__PMC_EV_ALIAS("RAT_STALLS.ANY", IAP_EVENT_D2H_0FH)			\
    +__PMC_EV_ALIAS("SEG_RENAME_STALLS", IAP_EVENT_D4H_01H)			\
    +__PMC_EV_ALIAS("ES_REG_RENAMES", IAP_EVENT_D5H_01H)			\
    +__PMC_EV_ALIAS("UOP_UNFUSION", IAP_EVENT_DBH_01H)			\
    +__PMC_EV_ALIAS("BR_INST_DECODED", IAP_EVENT_E0H_01H)			\
    +__PMC_EV_ALIAS("BPU_MISSED_CALL_RET", IAP_EVENT_E5H_01H)		\
    +__PMC_EV_ALIAS("BACLEAR.CLEAR", IAP_EVENT_E6H_01H)			\
    +__PMC_EV_ALIAS("BACLEAR.BAD_TARGET", IAP_EVENT_E6H_02H)			\
    +__PMC_EV_ALIAS("BPU_CLEARS.EARLY", IAP_EVENT_E8H_01H)			\
    +__PMC_EV_ALIAS("BPU_CLEARS.LATE", IAP_EVENT_E8H_02H)			\
    +__PMC_EV_ALIAS("BPU_CLEARS.ANY", IAP_EVENT_E8H_03H)			\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.LOAD", IAP_EVENT_F0H_01H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.RFO", IAP_EVENT_F0H_02H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.IFETCH", IAP_EVENT_F0H_04H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.PREFETCH", IAP_EVENT_F0H_08H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.L1D_WB", IAP_EVENT_F0H_10H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.FILL", IAP_EVENT_F0H_20H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.WB", IAP_EVENT_F0H_40H)			\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.ANY", IAP_EVENT_F0H_80H)		\
    +__PMC_EV_ALIAS("L2_LINES_IN.S_STATE", IAP_EVENT_F1H_02H)		\
    +__PMC_EV_ALIAS("L2_LINES_IN.E_STATE", IAP_EVENT_F1H_04H)		\
    +__PMC_EV_ALIAS("L2_LINES_IN.ANY", IAP_EVENT_F1H_07H)			\
    +__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_CLEAN", IAP_EVENT_F2H_01H)		\
    +__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_02H)		\
    +__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_CLEAN", IAP_EVENT_F2H_04H)	\
    +__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_DIRTY", IAP_EVENT_F2H_08H)	\
    +__PMC_EV_ALIAS("L2_LINES_OUT.ANY", IAP_EVENT_F2H_0FH)			\
    +__PMC_EV_ALIAS("SQ_MISC.SPLIT_LOCK", IAP_EVENT_F4H_10H)			\
    +__PMC_EV_ALIAS("SQ_FULL_STALL_CYCLES", IAP_EVENT_F6H_01H)		\
    +__PMC_EV_ALIAS("FP_ASSIST.ALL", IAP_EVENT_F7H_01H)			\
    +__PMC_EV_ALIAS("FP_ASSIST.OUTPUT", IAP_EVENT_F7H_02H)			\
    +__PMC_EV_ALIAS("FP_ASSIST.INPUT", IAP_EVENT_F7H_04H)			\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACKED_MPY", IAP_EVENT_FDH_01H)		\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACKED_SHIFT", IAP_EVENT_FDH_02H)		\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACK", IAP_EVENT_FDH_04H)			\
    +__PMC_EV_ALIAS("SIMD_INT_64.UNPACK", IAP_EVENT_FDH_08H)			\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACKED_LOGICAL", IAP_EVENT_FDH_10H)		\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACKED_ARITH", IAP_EVENT_FDH_20H)		\
    +__PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)		\
    +__PMC_EV_ALIAS_COREI7_OLD()
    +
    +/*
    + * Aliases for Westmere PMC events (253669-033US December 2009)
    + */
    +#define	__PMC_EV_ALIAS_WESTMERE()					\
    +__PMC_EV_ALIAS_INTEL_ARCHITECTURAL()					\
    +__PMC_EV_ALIAS("LOAD_BLOCK.OVERLAP_STORE", IAP_EVENT_03H_02H)		\
    +__PMC_EV_ALIAS("SB_DRAIN.ANY", IAP_EVENT_04H_07H)			\
    +__PMC_EV_ALIAS("MISALIGN_MEMORY.STORE", IAP_EVENT_05H_02H)		\
    +__PMC_EV_ALIAS("STORE_BLOCKS.AT_RET", IAP_EVENT_06H_04H)		\
    +__PMC_EV_ALIAS("STORE_BLOCKS.L1D_BLOCK", IAP_EVENT_06H_08H)		\
    +__PMC_EV_ALIAS("PARTIAL_ADDRESS_ALIAS", IAP_EVENT_07H_01H)		\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.ANY", IAP_EVENT_08H_01H)		\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_02H)	\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_CYCLES", IAP_EVENT_08H_04H)	\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT", IAP_EVENT_08H_10H)		\
    +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDE_MISS", IAP_EVENT_08H_20H)		\
    +__PMC_EV_ALIAS("MEM_INST_RETIRED.LOADS", IAP_EVENT_0BH_01H)		\
    +__PMC_EV_ALIAS("MEM_INST_RETIRED.STORES", IAP_EVENT_0BH_02H)		\
    +__PMC_EV_ALIAS("MEM_INST_RETIRED.LATENCY_ABOVE_THRESHOLD",		\
    +    IAP_EVENT_0BH_10H)							\
    +__PMC_EV_ALIAS("MEM_STORE_RETIRED.DTLB_MISS", IAP_EVENT_0CH_01H)	\
    +__PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H)			\
    +__PMC_EV_ALIAS("UOPS_ISSUED.STALLED_CYCLES", IAP_EVENT_0EH_01H)		\
    +__PMC_EV_ALIAS("UOPS_ISSUED.FUSED", IAP_EVENT_0EH_02H)			\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_HITM", IAP_EVENT_0FH_02H)	\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_DRAM_AND_REMOTE_CACHE_HIT",	\
    +    IAP_EVENT_0FH_08H)							\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.LOCAL_DRAM", IAP_EVENT_0FH_10H)	\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.REMOTE_DRAM", IAP_EVENT_0FH_20H)	\
    +__PMC_EV_ALIAS("MEM_UNCORE_RETIRED.UNCACHEABLE", IAP_EVENT_0FH_80H)	\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.X87", IAP_EVENT_10H_01H)		\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.MMX", IAP_EVENT_10H_02H)		\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP", IAP_EVENT_10H_04H)		\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE2_INTEGER", IAP_EVENT_10H_08H)	\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_PACKED", IAP_EVENT_10H_10H)	\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_SCALAR", IAP_EVENT_10H_20H)	\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION",			\
    +    IAP_EVENT_10H_40H) 							\
    +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION",			\
    +    IAP_EVENT_10H_80H)							\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACKED_MPY", IAP_EVENT_12H_01H)		\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACKED_SHIFT", IAP_EVENT_12H_02H)		\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACK", IAP_EVENT_12H_04H)			\
    +__PMC_EV_ALIAS("SIMD_INT_128.UNPACK", IAP_EVENT_12H_08H)		\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACKED_LOGICAL", IAP_EVENT_12H_10H)	\
    +__PMC_EV_ALIAS("SIMD_INT_128.PACKED_ARITH", IAP_EVENT_12H_20H)		\
    +__PMC_EV_ALIAS("SIMD_INT_128.SHUFFLE_MOVE", IAP_EVENT_12H_40H)		\
    +__PMC_EV_ALIAS("LOAD_DISPATCH.RS", IAP_EVENT_13H_01H)			\
    +__PMC_EV_ALIAS("LOAD_DISPATCH.RS_DELAYED", IAP_EVENT_13H_02H)		\
    +__PMC_EV_ALIAS("LOAD_DISPATCH.MOB", IAP_EVENT_13H_04H)			\
    +__PMC_EV_ALIAS("LOAD_DISPATCH.ANY", IAP_EVENT_13H_07H)			\
    +__PMC_EV_ALIAS("ARITH.CYCLES_DIV_BUSY", IAP_EVENT_14H_01H)		\
    +__PMC_EV_ALIAS("ARITH.MUL", IAP_EVENT_14H_02H)				\
    +__PMC_EV_ALIAS("INST_QUEUE_WRITES", IAP_EVENT_17H_01H)			\
    +__PMC_EV_ALIAS("INST_DECODED.DEC0", IAP_EVENT_18H_01H)			\
    +__PMC_EV_ALIAS("TWO_UOP_INSTS_DECODED", IAP_EVENT_19H_01H)		\
    +__PMC_EV_ALIAS("INST_QUEUE_WRITE_CYCLES", IAP_EVENT_1EH_01H)		\
    +__PMC_EV_ALIAS("LSD_OVERFLOW", IAP_EVENT_20H_01H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.LD_HIT", IAP_EVENT_24H_01H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.LD_MISS", IAP_EVENT_24H_02H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.LOADS", IAP_EVENT_24H_03H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.RFO_HIT", IAP_EVENT_24H_04H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.RFO_MISS", IAP_EVENT_24H_08H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.RFOS", IAP_EVENT_24H_0CH)			\
    +__PMC_EV_ALIAS("L2_RQSTS.IFETCH_HIT", IAP_EVENT_24H_10H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.IFETCH_MISS", IAP_EVENT_24H_20H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.IFETCHES", IAP_EVENT_24H_30H)			\
    +__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_HIT", IAP_EVENT_24H_40H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.PREFETCH_MISS", IAP_EVENT_24H_80H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.PREFETCHES", IAP_EVENT_24H_C0H)		\
    +__PMC_EV_ALIAS("L2_RQSTS.MISS", IAP_EVENT_24H_AAH)			\
    +__PMC_EV_ALIAS("L2_RQSTS.REFERENCES", IAP_EVENT_24H_FFH)		\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.I_STATE", IAP_EVENT_26H_01H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.S_STATE", IAP_EVENT_26H_02H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.E_STATE", IAP_EVENT_26H_04H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.M_STATE", IAP_EVENT_26H_08H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.DEMAND.MESI", IAP_EVENT_26H_0FH)		\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.I_STATE", IAP_EVENT_26H_10H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.S_STATE", IAP_EVENT_26H_20H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.E_STATE", IAP_EVENT_26H_40H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.M_STATE", IAP_EVENT_26H_80H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.PREFETCH.MESI", IAP_EVENT_26H_F0H)	\
    +__PMC_EV_ALIAS("L2_DATA_RQSTS.ANY", IAP_EVENT_26H_FFH)			\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.I_STATE", IAP_EVENT_27H_01H)		\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.S_STATE", IAP_EVENT_27H_02H)		\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.M_STATE", IAP_EVENT_27H_08H)		\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.HIT", IAP_EVENT_27H_0EH)			\
    +__PMC_EV_ALIAS("L2_WRITE.RFO.MESI", IAP_EVENT_27H_0FH)			\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.I_STATE", IAP_EVENT_27H_10H)		\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.S_STATE", IAP_EVENT_27H_20H)		\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.E_STATE", IAP_EVENT_27H_40H)		\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.M_STATE", IAP_EVENT_27H_80H)		\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.HIT", IAP_EVENT_27H_E0H)			\
    +__PMC_EV_ALIAS("L2_WRITE.LOCK.MESI", IAP_EVENT_27H_F0H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.I_STATE", IAP_EVENT_28H_01H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.S_STATE", IAP_EVENT_28H_02H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.E_STATE", IAP_EVENT_28H_04H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.M_STATE", IAP_EVENT_28H_08H)			\
    +__PMC_EV_ALIAS("L1D_WB_L2.MESI", IAP_EVENT_28H_0FH)			\
    +__PMC_EV_ALIAS("L3_LAT_CACHE.REFERENCE", IAP_EVENT_2EH_02H)		\
    +__PMC_EV_ALIAS("L3_LAT_CACHE.MISS", IAP_EVENT_2EH_01H)			\
    +__PMC_EV_ALIAS("CPU_CLK_UNHALTED.THREAD_P", IAP_EVENT_3CH_00H)		\
    +__PMC_EV_ALIAS("CPU_CLK_UNHALTED.REF_P", IAP_EVENT_3CH_01H)		\
    +__PMC_EV_ALIAS("DTLB_MISSES.ANY", IAP_EVENT_49H_01H)			\
    +__PMC_EV_ALIAS("DTLB_MISSES.WALK_COMPLETED", IAP_EVENT_49H_02H)		\
    +__PMC_EV_ALIAS("DTLB_MISSES.WALK_CYCLES", IAP_EVENT_49H_04H)		\
    +__PMC_EV_ALIAS("DTLB_MISSES.STLB_HIT", IAP_EVENT_49H_10H)		\
    +__PMC_EV_ALIAS("DTLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_49H_80H)	\
    +__PMC_EV_ALIAS("LOAD_HIT_PRE", IAP_EVENT_4CH_01H)			\
    +__PMC_EV_ALIAS("L1D_PREFETCH.REQUESTS", IAP_EVENT_4EH_01H)		\
    +__PMC_EV_ALIAS("L1D_PREFETCH.MISS", IAP_EVENT_4EH_02H)			\
    +__PMC_EV_ALIAS("L1D_PREFETCH.TRIGGERS", IAP_EVENT_4EH_04H)		\
    +__PMC_EV_ALIAS("EPT.WALK_CYCLES", IAP_EVENT_4FH_10H)			\
    +__PMC_EV_ALIAS("L1D.REPL", IAP_EVENT_51H_01H)				\
    +__PMC_EV_ALIAS("L1D.M_REPL", IAP_EVENT_51H_02H)				\
    +__PMC_EV_ALIAS("L1D.M_EVICT", IAP_EVENT_51H_04H)			\
    +__PMC_EV_ALIAS("L1D.M_SNOOP_EVICT", IAP_EVENT_51H_08H)			\
    +__PMC_EV_ALIAS("L1D_CACHE_PREFETCH_LOCK_FB_HIT", IAP_EVENT_52H_01H)	\
    +__PMC_EV_ALIAS("L1D_CACHE_LOCK_FB_HIT", IAP_EVENT_53H_01H)		\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA",		\
    +    IAP_EVENT_60H_01H)							\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE",		\
    +    IAP_EVENT_60H_02H)							\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO",		\
    +    IAP_EVENT_60H_04H)							\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.ANY.READ",			\
    +    IAP_EVENT_60H_08H)							\
    +__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D_L2", IAP_EVENT_63H_01H)		\
    +__PMC_EV_ALIAS("CACHE_LOCK_CYCLES.L1D", IAP_EVENT_63H_02H)		\
    +__PMC_EV_ALIAS("IO_TRANSACTIONS", IAP_EVENT_6CH_01H)			\
    +__PMC_EV_ALIAS("L1I.HITS", IAP_EVENT_80H_01H)				\
    +__PMC_EV_ALIAS("L1I.MISSES", IAP_EVENT_80H_02H)				\
    +__PMC_EV_ALIAS("L1I.READS", IAP_EVENT_80H_03H)				\
    +__PMC_EV_ALIAS("L1I.CYCLES_STALLED", IAP_EVENT_80H_04H)			\
    +__PMC_EV_ALIAS("LARGE_ITLB.HIT", IAP_EVENT_82H_01H)			\
    +__PMC_EV_ALIAS("ITLB_MISSES.ANY", IAP_EVENT_85H_01H)			\
    +__PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED", IAP_EVENT_85H_02H)		\
    +__PMC_EV_ALIAS("ITLB_MISSES.WALK_CYCLES", IAP_EVENT_85H_04H)		\
    +__PMC_EV_ALIAS("ITLB_MISSES.LARGE_WALK_COMPLETED", IAP_EVENT_85H_80H)	\
    +__PMC_EV_ALIAS("ILD_STALL.LCP", IAP_EVENT_87H_01H)			\
    +__PMC_EV_ALIAS("ILD_STALL.MRU", IAP_EVENT_87H_02H)			\
    +__PMC_EV_ALIAS("ILD_STALL.IQ_FULL", IAP_EVENT_87H_04H)			\
    +__PMC_EV_ALIAS("ILD_STALL.REGEN", IAP_EVENT_87H_08H)			\
    +__PMC_EV_ALIAS("ILD_STALL.ANY", IAP_EVENT_87H_0FH)			\
    +__PMC_EV_ALIAS("BR_INST_EXEC.COND", IAP_EVENT_88H_01H)			\
    +__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT", IAP_EVENT_88H_02H)		\
    +__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NON_CALL", IAP_EVENT_88H_04H)	\
    +__PMC_EV_ALIAS("BR_INST_EXEC.NON_CALLS", IAP_EVENT_88H_07H)		\
    +__PMC_EV_ALIAS("BR_INST_EXEC.RETURN_NEAR", IAP_EVENT_88H_08H)		\
    +__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_88H_10H)	\
    +__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_88H_20H)	\
    +__PMC_EV_ALIAS("BR_INST_EXEC.NEAR_CALLS", IAP_EVENT_88H_30H)		\
    +__PMC_EV_ALIAS("BR_INST_EXEC.TAKEN", IAP_EVENT_88H_40H)			\
    +__PMC_EV_ALIAS("BR_INST_EXEC.ANY", IAP_EVENT_88H_7FH)			\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.COND", IAP_EVENT_89H_01H)			\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT", IAP_EVENT_89H_02H)		\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NON_CALL", IAP_EVENT_89H_04H)	\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.NON_CALLS", IAP_EVENT_89H_07H)		\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.RETURN_NEAR", IAP_EVENT_89H_08H)		\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_89H_10H)	\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_89H_20H)	\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.NEAR_CALLS", IAP_EVENT_89H_30H)		\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.TAKEN", IAP_EVENT_89H_40H)			\
    +__PMC_EV_ALIAS("BR_MISP_EXEC.ANY", IAP_EVENT_89H_7FH)			\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.ANY", IAP_EVENT_A2H_01H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.LOAD", IAP_EVENT_A2H_02H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.RS_FULL", IAP_EVENT_A2H_04H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.STORE", IAP_EVENT_A2H_08H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.ROB_FULL", IAP_EVENT_A2H_10H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.FPCW", IAP_EVENT_A2H_20H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.MXCSR", IAP_EVENT_A2H_40H)		\
    +__PMC_EV_ALIAS("RESOURCE_STALLS.OTHER", IAP_EVENT_A2H_80H)		\
    +__PMC_EV_ALIAS("MACRO_INSTS.FUSIONS_DECODED", IAP_EVENT_A6H_01H)	\
    +__PMC_EV_ALIAS("BACLEAR_FORCE_IQ", IAP_EVENT_A7H_01H)			\
    +__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H)				\
    +__PMC_EV_ALIAS("ITLB_FLUSH", IAP_EVENT_AEH_01H)				\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_DATA", IAP_EVENT_B0H_01H)	\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.READ_CODE", IAP_EVENT_B0H_02H)	\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND.RFO", IAP_EVENT_B0H_04H)	\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.READ", IAP_EVENT_B0H_08H)		\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY.RFO", IAP_EVENT_B0H_10H)		\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.L1D_WRITEBACK", IAP_EVENT_B0H_40H)	\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY", IAP_EVENT_B0H_80H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT0", IAP_EVENT_B1H_01H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT1", IAP_EVENT_B1H_02H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT2_CORE", IAP_EVENT_B1H_04H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT3_CORE", IAP_EVENT_B1H_08H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT4_CORE", IAP_EVENT_B1H_10H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.CORE_ACTIVE_CYCLES_NO_PORT5",		\
    +    IAP_EVENT_B1H_1FH)							\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT5", IAP_EVENT_B1H_20H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.CORE_ACTIVE_CYCLES", IAP_EVENT_B1H_3FH)	\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT015", IAP_EVENT_B1H_40H)		\
    +__PMC_EV_ALIAS("UOPS_EXECUTED.PORT234", IAP_EVENT_B1H_80H)		\
    +__PMC_EV_ALIAS("OFFCORE_REQUESTS_SQ_FULL", IAP_EVENT_B2H_01H)		\
    +__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.DATA", IAP_EVENT_B3H_01H)	\
    +__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE",		\
    +    IAP_EVENT_B3H_02H)							\
    +__PMC_EV_ALIAS("SNOOPQ_REQUESTS_OUTSTANDING.CODE", IAP_EVENT_B3H_04H)	\
    +__PMC_EV_ALIAS("SNOOPQ_REQUESTS.CODE", IAP_EVENT_B4H_01H)		\
    +__PMC_EV_ALIAS("SNOOPQ_REQUESTS.DATA", IAP_EVENT_B4H_02H)		\
    +__PMC_EV_ALIAS("SNOOPQ_REQUESTS.INVALIDATE", IAP_EVENT_B4H_04H)		\
    +__PMC_EV_ALIAS("OFF_CORE_RESPONSE_0", IAP_EVENT_B7H_01H)		\
    +__PMC_EV_ALIAS("SNOOP_RESPONSE.HIT", IAP_EVENT_B8H_01H)			\
    +__PMC_EV_ALIAS("SNOOP_RESPONSE.HITE", IAP_EVENT_B8H_02H)		\
    +__PMC_EV_ALIAS("SNOOP_RESPONSE.HITM", IAP_EVENT_B8H_04H)		\
    +__PMC_EV_ALIAS("OFF_CORE_RESPONSE_1", IAP_EVENT_BBH_01H)		\
    +__PMC_EV_ALIAS("INST_RETIRED.ANY_P", IAP_EVENT_C0H_01H)			\
    +__PMC_EV_ALIAS("INST_RETIRED.X87", IAP_EVENT_C0H_02H)			\
    +__PMC_EV_ALIAS("INST_RETIRED.MMX", IAP_EVENT_C0H_04H)			\
    +__PMC_EV_ALIAS("UOPS_RETIRED.ANY", IAP_EVENT_C2H_01H)			\
    +__PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS", IAP_EVENT_C2H_02H)		\
    +__PMC_EV_ALIAS("UOPS_RETIRED.MACRO_FUSED", IAP_EVENT_C2H_04H)		\
    +__PMC_EV_ALIAS("MACHINE_CLEARS.CYCLES", IAP_EVENT_C3H_01H)		\
    +__PMC_EV_ALIAS("MACHINE_CLEARS.MEM_ORDER", IAP_EVENT_C3H_02H)		\
    +__PMC_EV_ALIAS("MACHINE_CLEARS.SMC", IAP_EVENT_C3H_04H)			\
    +__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_00H)	\
    +__PMC_EV_ALIAS("BR_INST_RETIRED.CONDITIONAL", IAP_EVENT_C4H_01H)	\
    +__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_CALL", IAP_EVENT_C4H_02H)		\
    +__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_04H)	\
    +__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_00H)	\
    +__PMC_EV_ALIAS("BR_MISP_RETIRED.CONDITIONAL", IAP_EVENT_C5H_01H)	\
    +__PMC_EV_ALIAS("BR_MISP_RETIRED.NEAR_CALL", IAP_EVENT_C5H_02H)		\
    +__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_04H)	\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_SINGLE", IAP_EVENT_C7H_01H)	\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_SINGLE", IAP_EVENT_C7H_02H)	\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.PACKED_DOUBLE", IAP_EVENT_C7H_04H)	\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.SCALAR_DOUBLE", IAP_EVENT_C7H_08H)	\
    +__PMC_EV_ALIAS("SSEX_UOPS_RETIRED.VECTOR_INTEGER", IAP_EVENT_C7H_10H)	\
    +__PMC_EV_ALIAS("ITLB_MISS_RETIRED", IAP_EVENT_C8H_20H)			\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L1D_HIT", IAP_EVENT_CBH_01H)		\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L2_HIT", IAP_EVENT_CBH_02H)		\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L3_UNSHARED_HIT", IAP_EVENT_CBH_04H)	\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM",		\
    +    IAP_EVENT_CBH_08H)							\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.L3_MISS", IAP_EVENT_CBH_10H)		\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.HIT_LFB", IAP_EVENT_CBH_40H)		\
    +__PMC_EV_ALIAS("MEM_LOAD_RETIRED.DTLB_MISS", IAP_EVENT_CBH_80H)		\
    +__PMC_EV_ALIAS("FP_MMX_TRANS.TO_FP", IAP_EVENT_CCH_01H)			\
    +__PMC_EV_ALIAS("FP_MMX_TRANS.TO_MMX", IAP_EVENT_CCH_02H)		\
    +__PMC_EV_ALIAS("FP_MMX_TRANS.ANY", IAP_EVENT_CCH_03H)			\
    +__PMC_EV_ALIAS("MACRO_INSTS.DECODED", IAP_EVENT_D0H_01H)		\
    +__PMC_EV_ALIAS("UOPS_DECODED.STALL_CYCLES", IAP_EVENT_D1H_01H)		\
    +__PMC_EV_ALIAS("UOPS_DECODED.MS", IAP_EVENT_D1H_02H)			\
    +__PMC_EV_ALIAS("UOPS_DECODED.ESP_FOLDING", IAP_EVENT_D1H_04H)		\
    +__PMC_EV_ALIAS("UOPS_DECODED.ESP_SYNC", IAP_EVENT_D1H_08H)		\
    +__PMC_EV_ALIAS("RAT_STALLS.FLAGS", IAP_EVENT_D2H_01H)			\
    +__PMC_EV_ALIAS("RAT_STALLS.REGISTERS", IAP_EVENT_D2H_02H)		\
    +__PMC_EV_ALIAS("RAT_STALLS.ROB_READ_PORT", IAP_EVENT_D2H_04H)		\
    +__PMC_EV_ALIAS("RAT_STALLS.SCOREBOARD", IAP_EVENT_D2H_08H)		\
    +__PMC_EV_ALIAS("RAT_STALLS.ANY", IAP_EVENT_D2H_0FH)			\
    +__PMC_EV_ALIAS("SEG_RENAME_STALLS", IAP_EVENT_D4H_01H)			\
    +__PMC_EV_ALIAS("ES_REG_RENAMES", IAP_EVENT_D5H_01H)			\
    +__PMC_EV_ALIAS("UOP_UNFUSION", IAP_EVENT_DBH_01H)			\
    +__PMC_EV_ALIAS("BR_INST_DECODED", IAP_EVENT_E0H_01H)			\
    +__PMC_EV_ALIAS("BPU_MISSED_CALL_RET", IAP_EVENT_E5H_01H)		\
    +__PMC_EV_ALIAS("BACLEAR.CLEAR", IAP_EVENT_E6H_01H)			\
    +__PMC_EV_ALIAS("BACLEAR.BAD_TARGET", IAP_EVENT_E6H_02H)			\
    +__PMC_EV_ALIAS("BPU_CLEARS.EARLY", IAP_EVENT_E8H_01H)			\
    +__PMC_EV_ALIAS("BPU_CLEARS.LATE", IAP_EVENT_E8H_02H)			\
    +__PMC_EV_ALIAS("THREAD_ACTIVE", IAP_EVENT_ECH_01H)			\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.LOAD", IAP_EVENT_F0H_01H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.RFO", IAP_EVENT_F0H_02H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.IFETCH", IAP_EVENT_F0H_04H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.PREFETCH", IAP_EVENT_F0H_08H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.L1D_WB", IAP_EVENT_F0H_10H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.FILL", IAP_EVENT_F0H_20H)		\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.WB", IAP_EVENT_F0H_40H)			\
    +__PMC_EV_ALIAS("L2_TRANSACTIONS.ANY", IAP_EVENT_F0H_80H)		\
    +__PMC_EV_ALIAS("L2_LINES_IN.S_STATE", IAP_EVENT_F1H_02H)		\
    +__PMC_EV_ALIAS("L2_LINES_IN.E_STATE", IAP_EVENT_F1H_04H)		\
    +__PMC_EV_ALIAS("L2_LINES_IN.ANY", IAP_EVENT_F1H_07H)			\
    +__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_CLEAN", IAP_EVENT_F2H_01H)		\
    +__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_02H)		\
    +__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_CLEAN", IAP_EVENT_F2H_04H)	\
    +__PMC_EV_ALIAS("L2_LINES_OUT.PREFETCH_DIRTY", IAP_EVENT_F2H_08H)	\
    +__PMC_EV_ALIAS("L2_LINES_OUT.ANY", IAP_EVENT_F2H_0FH)			\
    +__PMC_EV_ALIAS("SQ_MISC.LRU_HINTS", IAP_EVENT_F4H_04H)			\
    +__PMC_EV_ALIAS("SQ_MISC.SPLIT_LOCK", IAP_EVENT_F4H_10H)			\
    +__PMC_EV_ALIAS("SQ_FULL_STALL_CYCLES", IAP_EVENT_F6H_01H)		\
    +__PMC_EV_ALIAS("FP_ASSIST.ALL", IAP_EVENT_F7H_01H)			\
    +__PMC_EV_ALIAS("FP_ASSIST.OUTPUT", IAP_EVENT_F7H_02H)			\
    +__PMC_EV_ALIAS("FP_ASSIST.INPUT", IAP_EVENT_F7H_04H)			\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACKED_MPY", IAP_EVENT_FDH_01H)		\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACKED_SHIFT", IAP_EVENT_FDH_02H)		\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACK", IAP_EVENT_FDH_04H)			\
    +__PMC_EV_ALIAS("SIMD_INT_64.UNPACK", IAP_EVENT_FDH_08H)			\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACKED_LOGICAL", IAP_EVENT_FDH_10H)		\
    +__PMC_EV_ALIAS("SIMD_INT_64.PACKED_ARITH", IAP_EVENT_FDH_20H)		\
    +__PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
     
     /* timestamp counters. */
     #define	__PMC_EV_TSC()							\
    @@ -1979,6 +2325,628 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE",		IAP_EVENT_FDH_40H)
     #define	PMC_EV_TSC_FIRST	PMC_EV_TSC_TSC
     #define	PMC_EV_TSC_LAST		PMC_EV_TSC_TSC
     
    +#define	__PMC_EV_UCF()				\
    +__PMC_EV(UCF, UCLOCK)
    +
    +#define	PMC_EV_UCF_FIRST	PMC_EV_UCF_UCLOCK
    +#define	PMC_EV_UCF_LAST		PMC_EV_UCF_UCLOCK
    +
    +#define	__PMC_EV_UCP()				\
    +__PMC_EV(UCP, EVENT_00H_01H)			\
    +__PMC_EV(UCP, EVENT_00H_02H)			\
    +__PMC_EV(UCP, EVENT_00H_04H)			\
    +__PMC_EV(UCP, EVENT_01H_01H)			\
    +__PMC_EV(UCP, EVENT_01H_02H)			\
    +__PMC_EV(UCP, EVENT_01H_04H)			\
    +__PMC_EV(UCP, EVENT_02H_01H)			\
    +__PMC_EV(UCP, EVENT_03H_01H)			\
    +__PMC_EV(UCP, EVENT_03H_02H)			\
    +__PMC_EV(UCP, EVENT_03H_04H)			\
    +__PMC_EV(UCP, EVENT_03H_08H)			\
    +__PMC_EV(UCP, EVENT_03H_10H)			\
    +__PMC_EV(UCP, EVENT_03H_20H)			\
    +__PMC_EV(UCP, EVENT_03H_40H)			\
    +__PMC_EV(UCP, EVENT_04H_01H)			\
    +__PMC_EV(UCP, EVENT_04H_02H)			\
    +__PMC_EV(UCP, EVENT_04H_04H)			\
    +__PMC_EV(UCP, EVENT_04H_08H)			\
    +__PMC_EV(UCP, EVENT_04H_10H)			\
    +__PMC_EV(UCP, EVENT_05H_01H)			\
    +__PMC_EV(UCP, EVENT_05H_02H)			\
    +__PMC_EV(UCP, EVENT_05H_04H)			\
    +__PMC_EV(UCP, EVENT_06H_01H)			\
    +__PMC_EV(UCP, EVENT_06H_02H)			\
    +__PMC_EV(UCP, EVENT_06H_04H)			\
    +__PMC_EV(UCP, EVENT_06H_08H)			\
    +__PMC_EV(UCP, EVENT_06H_10H)			\
    +__PMC_EV(UCP, EVENT_06H_20H)			\
    +__PMC_EV(UCP, EVENT_07H_01H)			\
    +__PMC_EV(UCP, EVENT_07H_02H)			\
    +__PMC_EV(UCP, EVENT_07H_04H)			\
    +__PMC_EV(UCP, EVENT_07H_08H)			\
    +__PMC_EV(UCP, EVENT_07H_10H)			\
    +__PMC_EV(UCP, EVENT_07H_20H)			\
    +__PMC_EV(UCP, EVENT_07H_24H)			\
    +__PMC_EV(UCP, EVENT_08H_01H)			\
    +__PMC_EV(UCP, EVENT_08H_02H)			\
    +__PMC_EV(UCP, EVENT_08H_04H)			\
    +__PMC_EV(UCP, EVENT_08H_03H)			\
    +__PMC_EV(UCP, EVENT_09H_01H)			\
    +__PMC_EV(UCP, EVENT_09H_02H)			\
    +__PMC_EV(UCP, EVENT_09H_04H)			\
    +__PMC_EV(UCP, EVENT_09H_03H)			\
    +__PMC_EV(UCP, EVENT_0AH_01H)			\
    +__PMC_EV(UCP, EVENT_0AH_02H)			\
    +__PMC_EV(UCP, EVENT_0AH_04H)			\
    +__PMC_EV(UCP, EVENT_0AH_08H)			\
    +__PMC_EV(UCP, EVENT_0AH_0FH)			\
    +__PMC_EV(UCP, EVENT_0BH_01H)			\
    +__PMC_EV(UCP, EVENT_0BH_02H)			\
    +__PMC_EV(UCP, EVENT_0BH_04H)			\
    +__PMC_EV(UCP, EVENT_0BH_08H)			\
    +__PMC_EV(UCP, EVENT_0BH_10H)			\
    +__PMC_EV(UCP, EVENT_0BH_1FH)			\
    +__PMC_EV(UCP, EVENT_0CH_01H)			\
    +__PMC_EV(UCP, EVENT_0CH_02H)			\
    +__PMC_EV(UCP, EVENT_0CH_04H)			\
    +__PMC_EV(UCP, EVENT_0CH_08H)			\
    +__PMC_EV(UCP, EVENT_20H_01H)			\
    +__PMC_EV(UCP, EVENT_20H_02H)			\
    +__PMC_EV(UCP, EVENT_20H_04H)			\
    +__PMC_EV(UCP, EVENT_20H_08H)			\
    +__PMC_EV(UCP, EVENT_20H_10H)			\
    +__PMC_EV(UCP, EVENT_20H_20H)			\
    +__PMC_EV(UCP, EVENT_21H_01H)			\
    +__PMC_EV(UCP, EVENT_21H_02H)			\
    +__PMC_EV(UCP, EVENT_21H_04H)			\
    +__PMC_EV(UCP, EVENT_22H_01H)			\
    +__PMC_EV(UCP, EVENT_22H_02H)			\
    +__PMC_EV(UCP, EVENT_22H_04H)			\
    +__PMC_EV(UCP, EVENT_23H_01H)			\
    +__PMC_EV(UCP, EVENT_23H_02H)			\
    +__PMC_EV(UCP, EVENT_23H_04H)			\
    +__PMC_EV(UCP, EVENT_24H_02H)			\
    +__PMC_EV(UCP, EVENT_24H_04H)			\
    +__PMC_EV(UCP, EVENT_25H_01H)			\
    +__PMC_EV(UCP, EVENT_25H_02H)			\
    +__PMC_EV(UCP, EVENT_25H_04H)			\
    +__PMC_EV(UCP, EVENT_26H_01H)			\
    +__PMC_EV(UCP, EVENT_27H_01H)			\
    +__PMC_EV(UCP, EVENT_27H_02H)			\
    +__PMC_EV(UCP, EVENT_27H_04H)			\
    +__PMC_EV(UCP, EVENT_27H_08H)			\
    +__PMC_EV(UCP, EVENT_27H_10H)			\
    +__PMC_EV(UCP, EVENT_27H_20H)			\
    +__PMC_EV(UCP, EVENT_28H_01H)			\
    +__PMC_EV(UCP, EVENT_28H_02H)			\
    +__PMC_EV(UCP, EVENT_28H_04H)			\
    +__PMC_EV(UCP, EVENT_28H_08H)			\
    +__PMC_EV(UCP, EVENT_28H_10H)			\
    +__PMC_EV(UCP, EVENT_28H_20H)			\
    +__PMC_EV(UCP, EVENT_29H_01H)			\
    +__PMC_EV(UCP, EVENT_29H_02H)			\
    +__PMC_EV(UCP, EVENT_29H_04H)			\
    +__PMC_EV(UCP, EVENT_29H_08H)			\
    +__PMC_EV(UCP, EVENT_29H_10H)			\
    +__PMC_EV(UCP, EVENT_29H_20H)			\
    +__PMC_EV(UCP, EVENT_2AH_01H)			\
    +__PMC_EV(UCP, EVENT_2AH_02H)			\
    +__PMC_EV(UCP, EVENT_2AH_04H)			\
    +__PMC_EV(UCP, EVENT_2AH_07H)			\
    +__PMC_EV(UCP, EVENT_2BH_01H)			\
    +__PMC_EV(UCP, EVENT_2BH_02H)			\
    +__PMC_EV(UCP, EVENT_2BH_04H)			\
    +__PMC_EV(UCP, EVENT_2BH_07H)			\
    +__PMC_EV(UCP, EVENT_2CH_01H)			\
    +__PMC_EV(UCP, EVENT_2CH_02H)			\
    +__PMC_EV(UCP, EVENT_2CH_04H)			\
    +__PMC_EV(UCP, EVENT_2CH_07H)			\
    +__PMC_EV(UCP, EVENT_2DH_01H)			\
    +__PMC_EV(UCP, EVENT_2DH_02H)			\
    +__PMC_EV(UCP, EVENT_2DH_04H)			\
    +__PMC_EV(UCP, EVENT_2DH_07H)			\
    +__PMC_EV(UCP, EVENT_2EH_01H)			\
    +__PMC_EV(UCP, EVENT_2EH_02H)			\
    +__PMC_EV(UCP, EVENT_2EH_04H)			\
    +__PMC_EV(UCP, EVENT_2EH_07H)			\
    +__PMC_EV(UCP, EVENT_2FH_01H)			\
    +__PMC_EV(UCP, EVENT_2FH_02H)			\
    +__PMC_EV(UCP, EVENT_2FH_04H)			\
    +__PMC_EV(UCP, EVENT_2FH_07H)			\
    +__PMC_EV(UCP, EVENT_2FH_08H)			\
    +__PMC_EV(UCP, EVENT_2FH_10H)			\
    +__PMC_EV(UCP, EVENT_2FH_20H)			\
    +__PMC_EV(UCP, EVENT_2FH_38H)			\
    +__PMC_EV(UCP, EVENT_30H_01H)			\
    +__PMC_EV(UCP, EVENT_30H_02H)			\
    +__PMC_EV(UCP, EVENT_30H_04H)			\
    +__PMC_EV(UCP, EVENT_30H_07H)			\
    +__PMC_EV(UCP, EVENT_31H_01H)			\
    +__PMC_EV(UCP, EVENT_31H_02H)			\
    +__PMC_EV(UCP, EVENT_31H_04H)			\
    +__PMC_EV(UCP, EVENT_31H_07H)			\
    +__PMC_EV(UCP, EVENT_32H_01H)			\
    +__PMC_EV(UCP, EVENT_32H_02H)			\
    +__PMC_EV(UCP, EVENT_32H_04H)			\
    +__PMC_EV(UCP, EVENT_32H_07H)			\
    +__PMC_EV(UCP, EVENT_33H_01H)			\
    +__PMC_EV(UCP, EVENT_33H_02H)			\
    +__PMC_EV(UCP, EVENT_33H_04H)			\
    +__PMC_EV(UCP, EVENT_33H_07H)			\
    +__PMC_EV(UCP, EVENT_34H_01H)			\
    +__PMC_EV(UCP, EVENT_34H_02H)			\
    +__PMC_EV(UCP, EVENT_34H_04H)			\
    +__PMC_EV(UCP, EVENT_34H_08H)			\
    +__PMC_EV(UCP, EVENT_34H_10H)			\
    +__PMC_EV(UCP, EVENT_34H_20H)			\
    +__PMC_EV(UCP, EVENT_35H_01H)			\
    +__PMC_EV(UCP, EVENT_35H_02H)			\
    +__PMC_EV(UCP, EVENT_35H_04H)			\
    +__PMC_EV(UCP, EVENT_40H_01H)			\
    +__PMC_EV(UCP, EVENT_40H_02H)			\
    +__PMC_EV(UCP, EVENT_40H_04H)			\
    +__PMC_EV(UCP, EVENT_40H_08H)			\
    +__PMC_EV(UCP, EVENT_40H_10H)			\
    +__PMC_EV(UCP, EVENT_40H_20H)			\
    +__PMC_EV(UCP, EVENT_40H_07H)			\
    +__PMC_EV(UCP, EVENT_40H_38H)			\
    +__PMC_EV(UCP, EVENT_41H_01H)			\
    +__PMC_EV(UCP, EVENT_41H_02H)			\
    +__PMC_EV(UCP, EVENT_41H_04H)			\
    +__PMC_EV(UCP, EVENT_41H_08H)			\
    +__PMC_EV(UCP, EVENT_41H_10H)			\
    +__PMC_EV(UCP, EVENT_41H_20H)			\
    +__PMC_EV(UCP, EVENT_41H_07H)			\
    +__PMC_EV(UCP, EVENT_41H_38H)			\
    +__PMC_EV(UCP, EVENT_42H_01H)			\
    +__PMC_EV(UCP, EVENT_42H_02H)			\
    +__PMC_EV(UCP, EVENT_42H_04H)			\
    +__PMC_EV(UCP, EVENT_42H_08H)			\
    +__PMC_EV(UCP, EVENT_43H_01H)			\
    +__PMC_EV(UCP, EVENT_43H_02H)			\
    +__PMC_EV(UCP, EVENT_60H_01H)			\
    +__PMC_EV(UCP, EVENT_60H_02H)			\
    +__PMC_EV(UCP, EVENT_60H_04H)			\
    +__PMC_EV(UCP, EVENT_61H_01H)			\
    +__PMC_EV(UCP, EVENT_61H_02H)			\
    +__PMC_EV(UCP, EVENT_61H_04H)			\
    +__PMC_EV(UCP, EVENT_62H_01H)			\
    +__PMC_EV(UCP, EVENT_62H_02H)			\
    +__PMC_EV(UCP, EVENT_62H_04H)			\
    +__PMC_EV(UCP, EVENT_63H_01H)			\
    +__PMC_EV(UCP, EVENT_63H_02H)			\
    +__PMC_EV(UCP, EVENT_63H_04H)			\
    +__PMC_EV(UCP, EVENT_63H_08H)			\
    +__PMC_EV(UCP, EVENT_63H_10H)			\
    +__PMC_EV(UCP, EVENT_63H_20H)			\
    +__PMC_EV(UCP, EVENT_64H_01H)			\
    +__PMC_EV(UCP, EVENT_64H_02H)			\
    +__PMC_EV(UCP, EVENT_64H_04H)			\
    +__PMC_EV(UCP, EVENT_64H_08H)			\
    +__PMC_EV(UCP, EVENT_64H_10H)			\
    +__PMC_EV(UCP, EVENT_64H_20H)			\
    +__PMC_EV(UCP, EVENT_65H_01H)			\
    +__PMC_EV(UCP, EVENT_65H_02H)			\
    +__PMC_EV(UCP, EVENT_65H_04H)			\
    +__PMC_EV(UCP, EVENT_66H_01H)			\
    +__PMC_EV(UCP, EVENT_66H_02H)			\
    +__PMC_EV(UCP, EVENT_66H_04H)			\
    +__PMC_EV(UCP, EVENT_67H_01H)			\
    +__PMC_EV(UCP, EVENT_80H_01H)			\
    +__PMC_EV(UCP, EVENT_80H_02H)			\
    +__PMC_EV(UCP, EVENT_80H_04H)			\
    +__PMC_EV(UCP, EVENT_80H_08H)			\
    +__PMC_EV(UCP, EVENT_81H_01H)			\
    +__PMC_EV(UCP, EVENT_81H_02H)			\
    +__PMC_EV(UCP, EVENT_81H_04H)			\
    +__PMC_EV(UCP, EVENT_81H_08H)			\
    +__PMC_EV(UCP, EVENT_82H_01H)			\
    +__PMC_EV(UCP, EVENT_83H_01H)			\
    +__PMC_EV(UCP, EVENT_83H_02H)			\
    +__PMC_EV(UCP, EVENT_83H_04H)			\
    +__PMC_EV(UCP, EVENT_83H_08H)			\
    +__PMC_EV(UCP, EVENT_84H_01H)			\
    +__PMC_EV(UCP, EVENT_84H_02H)			\
    +__PMC_EV(UCP, EVENT_84H_04H)			\
    +__PMC_EV(UCP, EVENT_84H_08H)			\
    +__PMC_EV(UCP, EVENT_85H_02H)			\
    +__PMC_EV(UCP, EVENT_86H_01H)
    +
    +#define	PMC_EV_UCP_FIRST	PMC_EV_UCP_EVENT_00H_01H
    +#define	PMC_EV_UCP_LAST		PMC_EV_UCP_EVENT_86H_01H
    +
    +#define	__PMC_EV_ALIAS_COREI7UC()					\
    +__PMC_EV_ALIAS("GQ_CYCLES_FULL.READ_TRACKER", UCP_EVENT_00H_01H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_FULL.WRITE_TRACKER", UCP_EVENT_00H_02H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_FULL.PEER_PROBE_TRACKER", UCP_EVENT_00H_04H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.READ_TRACKER", UCP_EVENT_01H_01H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.WRITE_TRACKER", UCP_EVENT_01H_02H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.PEER_PROBE_TRACKER", UCP_EVENT_01H_04H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.READ_TRACKER", UCP_EVENT_03H_01H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.RT_L3_MISS", UCP_EVENT_03H_02H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.RT_TO_L3_RESP", UCP_EVENT_03H_04H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.RT_TO_RTID_ACQUIRED", UCP_EVENT_03H_08H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.WT_TO_RTID_ACQUIRED", UCP_EVENT_03H_10H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.WRITE_TRACKER", UCP_EVENT_03H_20H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.PEER_PROBE_TRACKER", UCP_EVENT_03H_40H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_QPI", UCP_EVENT_04H_01H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_QMC", UCP_EVENT_04H_02H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_L3", UCP_EVENT_04H_04H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_CORES_02", UCP_EVENT_04H_08H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_CORES_13", UCP_EVENT_04H_10H)	\
    +__PMC_EV_ALIAS("GQ_DATA.TO_QPI_QMC", UCP_EVENT_05H_01H)	\
    +__PMC_EV_ALIAS("GQ_DATA.TO_L3", UCP_EVENT_05H_02H)	\
    +__PMC_EV_ALIAS("GQ_DATA.TO_CORES", UCP_EVENT_05H_04H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.I_STATE", UCP_EVENT_06H_01H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.S_STATE", UCP_EVENT_06H_02H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.FWD_S_STATE", UCP_EVENT_06H_04H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.FWD_I_STATE", UCP_EVENT_06H_08H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.CONFLICT", UCP_EVENT_06H_10H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.WB", UCP_EVENT_06H_20H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.I_STATE", UCP_EVENT_07H_01H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.S_STATE", UCP_EVENT_07H_02H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.FWD_S_STATE", UCP_EVENT_07H_04H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.FWD_I_STATE", UCP_EVENT_07H_08H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.CONFLICT", UCP_EVENT_07H_10H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.WB", UCP_EVENT_07H_20H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.HITM", UCP_EVENT_07H_24H)	\
    +__PMC_EV_ALIAS("L3_HITS.READ", UCP_EVENT_08H_01H)	\
    +__PMC_EV_ALIAS("L3_HITS.WRITE", UCP_EVENT_08H_02H)	\
    +__PMC_EV_ALIAS("L3_HITS.PROBE", UCP_EVENT_08H_04H)	\
    +__PMC_EV_ALIAS("L3_HITS.ANY", UCP_EVENT_08H_03H)	\
    +__PMC_EV_ALIAS("L3_MISS.READ", UCP_EVENT_09H_01H)	\
    +__PMC_EV_ALIAS("L3_MISS.WRITE", UCP_EVENT_09H_02H)	\
    +__PMC_EV_ALIAS("L3_MISS.PROBE", UCP_EVENT_09H_04H)	\
    +__PMC_EV_ALIAS("L3_MISS.ANY", UCP_EVENT_09H_03H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.M_STATE", UCP_EVENT_0AH_01H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.E_STATE", UCP_EVENT_0AH_02H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.S_STATE", UCP_EVENT_0AH_04H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.F_STATE", UCP_EVENT_0AH_08H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.ANY", UCP_EVENT_0AH_0FH)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.M_STATE", UCP_EVENT_0BH_01H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.E_STATE", UCP_EVENT_0BH_02H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.S_STATE", UCP_EVENT_0BH_04H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.I_STATE", UCP_EVENT_0BH_08H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.F_STATE", UCP_EVENT_0BH_10H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.ANY", UCP_EVENT_0BH_1FH)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.IOH_READS", UCP_EVENT_20H_01H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.IOH_WRITES", UCP_EVENT_20H_02H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.REMOTE_READS", UCP_EVENT_20H_04H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.REMOTE_WRITES", UCP_EVENT_20H_08H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.LOCAL_READS", UCP_EVENT_20H_10H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.LOCAL_WRITES", UCP_EVENT_20H_20H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_FULL.IOH", UCP_EVENT_21H_01H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_FULL.REMOTE", UCP_EVENT_21H_02H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_FULL.LOCAL", UCP_EVENT_21H_04H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.IOH", UCP_EVENT_22H_01H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.REMOTE", UCP_EVENT_22H_02H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.LOCAL", UCP_EVENT_22H_04H)	\
    +__PMC_EV_ALIAS("QHL_OCCUPANCY.IOH", UCP_EVENT_23H_01H)	\
    +__PMC_EV_ALIAS("QHL_OCCUPANCY.REMOTE", UCP_EVENT_23H_02H)	\
    +__PMC_EV_ALIAS("QHL_OCCUPANCY.LOCAL", UCP_EVENT_23H_04H)	\
    +__PMC_EV_ALIAS("QHL_ADDRESS_CONFLICTS.2WAY", UCP_EVENT_24H_02H)	\
    +__PMC_EV_ALIAS("QHL_ADDRESS_CONFLICTS.3WAY", UCP_EVENT_24H_04H)	\
    +__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.IOH", UCP_EVENT_25H_01H)	\
    +__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.REMOTE", UCP_EVENT_25H_02H)	\
    +__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.LOCAL", UCP_EVENT_25H_04H)	\
    +__PMC_EV_ALIAS("QHL_TO_QMC_BYPASS", UCP_EVENT_26H_01H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_FULL.READ.CH0", UCP_EVENT_27H_01H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_FULL.READ.CH1", UCP_EVENT_27H_02H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_FULL.READ.CH2", UCP_EVENT_27H_04H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_FULL.WRITE.CH0", UCP_EVENT_27H_08H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_FULL.WRITE.CH1", UCP_EVENT_27H_10H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_FULL.WRITE.CH2", UCP_EVENT_27H_20H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH0", UCP_EVENT_28H_01H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH1", UCP_EVENT_28H_02H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH2", UCP_EVENT_28H_04H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH0", UCP_EVENT_28H_08H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH1", UCP_EVENT_28H_10H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH2", UCP_EVENT_28H_20H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.READ.CH0", UCP_EVENT_29H_01H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.READ.CH1", UCP_EVENT_29H_02H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.READ.CH2", UCP_EVENT_29H_04H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH0", UCP_EVENT_29H_08H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH1", UCP_EVENT_29H_10H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH2", UCP_EVENT_29H_20H)	\
    +__PMC_EV_ALIAS("QMC_OCCUPANCY.CH0", UCP_EVENT_2AH_01H)	\
    +__PMC_EV_ALIAS("QMC_OCCUPANCY.CH1", UCP_EVENT_2AH_02H)	\
    +__PMC_EV_ALIAS("QMC_OCCUPANCY.CH2", UCP_EVENT_2AH_04H)	\
    +__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH0", UCP_EVENT_2BH_01H)	\
    +__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH1", UCP_EVENT_2BH_02H)	\
    +__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH2", UCP_EVENT_2BH_04H)	\
    +__PMC_EV_ALIAS("QMC_ISSOC_READS.ANY", UCP_EVENT_2BH_07H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_READS.CH0", UCP_EVENT_2CH_01H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_READS.CH1", UCP_EVENT_2CH_02H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_READS.CH2", UCP_EVENT_2CH_04H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_READS.ANY", UCP_EVENT_2CH_07H)	\
    +__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH0", UCP_EVENT_2DH_01H)	\
    +__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH1", UCP_EVENT_2DH_02H)	\
    +__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH2", UCP_EVENT_2DH_04H)	\
    +__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.ANY", UCP_EVENT_2DH_07H)	\
    +__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH0", UCP_EVENT_2EH_01H)	\
    +__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH1", UCP_EVENT_2EH_02H)	\
    +__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH2", UCP_EVENT_2EH_04H)	\
    +__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.ANY", UCP_EVENT_2EH_07H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.FULL.CH0", UCP_EVENT_2FH_01H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.FULL.CH1", UCP_EVENT_2FH_02H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.FULL.CH2", UCP_EVENT_2FH_04H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.FULL.ANY", UCP_EVENT_2FH_07H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH0", UCP_EVENT_2FH_08H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH1", UCP_EVENT_2FH_10H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH2", UCP_EVENT_2FH_20H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.ANY", UCP_EVENT_2FH_38H)	\
    +__PMC_EV_ALIAS("QMC_CANCEL.CH0", UCP_EVENT_30H_01H)	\
    +__PMC_EV_ALIAS("QMC_CANCEL.CH1", UCP_EVENT_30H_02H)	\
    +__PMC_EV_ALIAS("QMC_CANCEL.CH2", UCP_EVENT_30H_04H)	\
    +__PMC_EV_ALIAS("QMC_CANCEL.ANY", UCP_EVENT_30H_07H)	\
    +__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH0", UCP_EVENT_31H_01H)	\
    +__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH1", UCP_EVENT_31H_02H)	\
    +__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH2", UCP_EVENT_31H_04H)	\
    +__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.ANY", UCP_EVENT_31H_07H)	\
    +__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.LOCAL", UCP_EVENT_33H_04H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_0", UCP_EVENT_40H_01H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_0", UCP_EVENT_40H_02H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_0", UCP_EVENT_40H_04H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_1", UCP_EVENT_40H_08H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_1", UCP_EVENT_40H_10H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_1", UCP_EVENT_40H_20H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.LINK_0", UCP_EVENT_40H_07H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.LINK_1", UCP_EVENT_40H_38H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_0", UCP_EVENT_41H_01H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_0", UCP_EVENT_41H_02H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_0", UCP_EVENT_41H_04H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_1", UCP_EVENT_41H_08H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_1", UCP_EVENT_41H_10H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_1", UCP_EVENT_41H_20H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.LINK_0", UCP_EVENT_41H_07H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.LINK_1", UCP_EVENT_41H_38H)	\
    +__PMC_EV_ALIAS("QPI_TX_HEADER.BUSY.LINK_0", UCP_EVENT_42H_02H)	\
    +__PMC_EV_ALIAS("QPI_TX_HEADER.BUSY.LINK_1", UCP_EVENT_42H_08H)	\
    +__PMC_EV_ALIAS("QPI_RX_NO_PPT_CREDIT.STALLS.LINK_0", UCP_EVENT_43H_01H)	\
    +__PMC_EV_ALIAS("QPI_RX_NO_PPT_CREDIT.STALLS.LINK_1", UCP_EVENT_43H_02H)	\
    +__PMC_EV_ALIAS("DRAM_OPEN.CH0", UCP_EVENT_60H_01H)	\
    +__PMC_EV_ALIAS("DRAM_OPEN.CH1", UCP_EVENT_60H_02H)	\
    +__PMC_EV_ALIAS("DRAM_OPEN.CH2", UCP_EVENT_60H_04H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH0", UCP_EVENT_61H_01H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH1", UCP_EVENT_61H_02H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH2", UCP_EVENT_61H_04H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH0", UCP_EVENT_62H_01H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH1", UCP_EVENT_62H_02H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH2", UCP_EVENT_62H_04H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.CH0", UCP_EVENT_63H_01H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH0", UCP_EVENT_63H_02H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.CH1", UCP_EVENT_63H_04H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH1", UCP_EVENT_63H_08H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.CH2", UCP_EVENT_63H_10H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH2", UCP_EVENT_63H_20H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH0", UCP_EVENT_64H_01H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH0", UCP_EVENT_64H_02H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH1", UCP_EVENT_64H_04H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH1", UCP_EVENT_64H_08H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH2", UCP_EVENT_64H_10H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH2", UCP_EVENT_64H_20H)	\
    +__PMC_EV_ALIAS("DRAM_REFRESH.CH0", UCP_EVENT_65H_01H)	\
    +__PMC_EV_ALIAS("DRAM_REFRESH.CH1", UCP_EVENT_65H_02H)	\
    +__PMC_EV_ALIAS("DRAM_REFRESH.CH2", UCP_EVENT_65H_04H)	\
    +__PMC_EV_ALIAS("DRAM_PRE_ALL.CH0", UCP_EVENT_66H_01H)	\
    +__PMC_EV_ALIAS("DRAM_PRE_ALL.CH1", UCP_EVENT_66H_02H)	\
    +__PMC_EV_ALIAS("DRAM_PRE_ALL.CH2", UCP_EVENT_66H_04H)
    +
    +#define	__PMC_EV_ALIAS_WESTMEREUC()					\
    +__PMC_EV_ALIAS("GQ_CYCLES_FULL.READ_TRACKER", UCP_EVENT_00H_01H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_FULL.WRITE_TRACKER", UCP_EVENT_00H_02H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_FULL.PEER_PROBE_TRACKER", UCP_EVENT_00H_04H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.READ_TRACKER", UCP_EVENT_01H_01H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.WRITE_TRACKER", UCP_EVENT_01H_02H)	\
    +__PMC_EV_ALIAS("GQ_CYCLES_NOT_EMPTY.PEER_PROBE_TRACKER", UCP_EVENT_01H_04H)	\
    +__PMC_EV_ALIAS("GQ_OCCUPANCY.READ_TRACKER", UCP_EVENT_02H_01H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.READ_TRACKER", UCP_EVENT_03H_01H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.RT_L3_MISS", UCP_EVENT_03H_02H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.RT_TO_L3_RESP", UCP_EVENT_03H_04H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.RT_TO_RTID_ACQUIRED", UCP_EVENT_03H_08H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.WT_TO_RTID_ACQUIRED", UCP_EVENT_03H_10H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.WRITE_TRACKER", UCP_EVENT_03H_20H)	\
    +__PMC_EV_ALIAS("GQ_ALLOC.PEER_PROBE_TRACKER", UCP_EVENT_03H_40H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_QPI", UCP_EVENT_04H_01H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_QMC", UCP_EVENT_04H_02H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_L3", UCP_EVENT_04H_04H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_CORES_02", UCP_EVENT_04H_08H)	\
    +__PMC_EV_ALIAS("GQ_DATA.FROM_CORES_13", UCP_EVENT_04H_10H)	\
    +__PMC_EV_ALIAS("GQ_DATA.TO_QPI_QMC", UCP_EVENT_05H_01H)	\
    +__PMC_EV_ALIAS("GQ_DATA.TO_L3", UCP_EVENT_05H_02H)	\
    +__PMC_EV_ALIAS("GQ_DATA.TO_CORES", UCP_EVENT_05H_04H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.I_STATE", UCP_EVENT_06H_01H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.S_STATE", UCP_EVENT_06H_02H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.FWD_S_STATE", UCP_EVENT_06H_04H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.FWD_I_STATE", UCP_EVENT_06H_08H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.CONFLICT", UCP_EVENT_06H_10H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_LOCAL_HOME.WB", UCP_EVENT_06H_20H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.I_STATE", UCP_EVENT_07H_01H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.S_STATE", UCP_EVENT_07H_02H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.FWD_S_STATE", UCP_EVENT_07H_04H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.FWD_I_STATE", UCP_EVENT_07H_08H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.CONFLICT", UCP_EVENT_07H_10H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.WB", UCP_EVENT_07H_20H)	\
    +__PMC_EV_ALIAS("SNP_RESP_TO_REMOTE_HOME.HITM", UCP_EVENT_07H_24H)	\
    +__PMC_EV_ALIAS("L3_HITS.READ", UCP_EVENT_08H_01H)	\
    +__PMC_EV_ALIAS("L3_HITS.WRITE", UCP_EVENT_08H_02H)	\
    +__PMC_EV_ALIAS("L3_HITS.PROBE", UCP_EVENT_08H_04H)	\
    +__PMC_EV_ALIAS("L3_HITS.ANY", UCP_EVENT_08H_03H)	\
    +__PMC_EV_ALIAS("L3_MISS.READ", UCP_EVENT_09H_01H)	\
    +__PMC_EV_ALIAS("L3_MISS.WRITE", UCP_EVENT_09H_02H)	\
    +__PMC_EV_ALIAS("L3_MISS.PROBE", UCP_EVENT_09H_04H)	\
    +__PMC_EV_ALIAS("L3_MISS.ANY", UCP_EVENT_09H_03H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.M_STATE", UCP_EVENT_0AH_01H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.E_STATE", UCP_EVENT_0AH_02H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.S_STATE", UCP_EVENT_0AH_04H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.F_STATE", UCP_EVENT_0AH_08H)	\
    +__PMC_EV_ALIAS("L3_LINES_IN.ANY", UCP_EVENT_0AH_0FH)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.M_STATE", UCP_EVENT_0BH_01H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.E_STATE", UCP_EVENT_0BH_02H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.S_STATE", UCP_EVENT_0BH_04H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.I_STATE", UCP_EVENT_0BH_08H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.F_STATE", UCP_EVENT_0BH_10H)	\
    +__PMC_EV_ALIAS("L3_LINES_OUT.ANY", UCP_EVENT_0BH_1FH)	\
    +__PMC_EV_ALIAS("GQ_SNOOP.GOTO_S", UCP_EVENT_0CH_01H)	\
    +__PMC_EV_ALIAS("GQ_SNOOP.GOTO_I", UCP_EVENT_0CH_02H)	\
    +__PMC_EV_ALIAS("GQ_SNOOP.GOTO_S_HIT", UCP_EVENT_0CH_04H)	\
    +__PMC_EV_ALIAS("GQ_SNOOP.GOTO_I_HIT", UCP_EVENT_0CH_08H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.IOH_READS", UCP_EVENT_20H_01H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.IOH_WRITES", UCP_EVENT_20H_02H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.REMOTE_READS", UCP_EVENT_20H_04H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.REMOTE_WRITES", UCP_EVENT_20H_08H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.LOCAL_READS", UCP_EVENT_20H_10H)	\
    +__PMC_EV_ALIAS("QHL_REQUESTS.LOCAL_WRITES", UCP_EVENT_20H_20H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_FULL.IOH", UCP_EVENT_21H_01H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_FULL.REMOTE", UCP_EVENT_21H_02H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_FULL.LOCAL", UCP_EVENT_21H_04H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.IOH", UCP_EVENT_22H_01H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.REMOTE", UCP_EVENT_22H_02H)	\
    +__PMC_EV_ALIAS("QHL_CYCLES_NOT_EMPTY.LOCAL", UCP_EVENT_22H_04H)	\
    +__PMC_EV_ALIAS("QHL_OCCUPANCY.IOH", UCP_EVENT_23H_01H)	\
    +__PMC_EV_ALIAS("QHL_OCCUPANCY.REMOTE", UCP_EVENT_23H_02H)	\
    +__PMC_EV_ALIAS("QHL_OCCUPANCY.LOCAL", UCP_EVENT_23H_04H)	\
    +__PMC_EV_ALIAS("QHL_ADDRESS_CONFLICTS.2WAY", UCP_EVENT_24H_02H)	\
    +__PMC_EV_ALIAS("QHL_ADDRESS_CONFLICTS.3WAY", UCP_EVENT_24H_04H)	\
    +__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.IOH", UCP_EVENT_25H_01H)	\
    +__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.REMOTE", UCP_EVENT_25H_02H)	\
    +__PMC_EV_ALIAS("QHL_CONFLICT_CYCLES.LOCAL", UCP_EVENT_25H_04H)	\
    +__PMC_EV_ALIAS("QHL_TO_QMC_BYPASS", UCP_EVENT_26H_01H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH0", UCP_EVENT_28H_01H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH1", UCP_EVENT_28H_02H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.READ.CH2", UCP_EVENT_28H_04H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH0", UCP_EVENT_28H_08H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH1", UCP_EVENT_28H_10H)	\
    +__PMC_EV_ALIAS("QMC_ISOC_FULL.WRITE.CH2", UCP_EVENT_28H_20H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.READ.CH0", UCP_EVENT_29H_01H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.READ.CH1", UCP_EVENT_29H_02H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.READ.CH2", UCP_EVENT_29H_04H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH0", UCP_EVENT_29H_08H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH1", UCP_EVENT_29H_10H)	\
    +__PMC_EV_ALIAS("QMC_BUSY.WRITE.CH2", UCP_EVENT_29H_20H)	\
    +__PMC_EV_ALIAS("QMC_OCCUPANCY.CH0", UCP_EVENT_2AH_01H)	\
    +__PMC_EV_ALIAS("QMC_OCCUPANCY.CH1", UCP_EVENT_2AH_02H)	\
    +__PMC_EV_ALIAS("QMC_OCCUPANCY.CH2", UCP_EVENT_2AH_04H)	\
    +__PMC_EV_ALIAS("QMC_OCCUPANCY.ANY", UCP_EVENT_2AH_07H)	\
    +__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH0", UCP_EVENT_2BH_01H)	\
    +__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH1", UCP_EVENT_2BH_02H)	\
    +__PMC_EV_ALIAS("QMC_ISSOC_OCCUPANCY.CH2", UCP_EVENT_2BH_04H)	\
    +__PMC_EV_ALIAS("QMC_ISSOC_READS.ANY", UCP_EVENT_2BH_07H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_READS.CH0", UCP_EVENT_2CH_01H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_READS.CH1", UCP_EVENT_2CH_02H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_READS.CH2", UCP_EVENT_2CH_04H)	\
    +__PMC_EV_ALIAS("QMC_NORMAL_READS.ANY", UCP_EVENT_2CH_07H)	\
    +__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH0", UCP_EVENT_2DH_01H)	\
    +__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH1", UCP_EVENT_2DH_02H)	\
    +__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.CH2", UCP_EVENT_2DH_04H)	\
    +__PMC_EV_ALIAS("QMC_HIGH_PRIORITY_READS.ANY", UCP_EVENT_2DH_07H)	\
    +__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH0", UCP_EVENT_2EH_01H)	\
    +__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH1", UCP_EVENT_2EH_02H)	\
    +__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.CH2", UCP_EVENT_2EH_04H)	\
    +__PMC_EV_ALIAS("QMC_CRITICAL_PRIORITY_READS.ANY", UCP_EVENT_2EH_07H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.FULL.CH0", UCP_EVENT_2FH_01H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.FULL.CH1", UCP_EVENT_2FH_02H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.FULL.CH2", UCP_EVENT_2FH_04H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.FULL.ANY", UCP_EVENT_2FH_07H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH0", UCP_EVENT_2FH_08H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH1", UCP_EVENT_2FH_10H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.CH2", UCP_EVENT_2FH_20H)	\
    +__PMC_EV_ALIAS("QMC_WRITES.PARTIAL.ANY", UCP_EVENT_2FH_38H)	\
    +__PMC_EV_ALIAS("QMC_CANCEL.CH0", UCP_EVENT_30H_01H)	\
    +__PMC_EV_ALIAS("QMC_CANCEL.CH1", UCP_EVENT_30H_02H)	\
    +__PMC_EV_ALIAS("QMC_CANCEL.CH2", UCP_EVENT_30H_04H)	\
    +__PMC_EV_ALIAS("QMC_CANCEL.ANY", UCP_EVENT_30H_07H)	\
    +__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH0", UCP_EVENT_31H_01H)	\
    +__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH1", UCP_EVENT_31H_02H)	\
    +__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.CH2", UCP_EVENT_31H_04H)	\
    +__PMC_EV_ALIAS("QMC_PRIORITY_UPDATES.ANY", UCP_EVENT_31H_07H)	\
    +__PMC_EV_ALIAS("IMC_RETRY.CH0", UCP_EVENT_32H_01H)	\
    +__PMC_EV_ALIAS("IMC_RETRY.CH1", UCP_EVENT_32H_02H)	\
    +__PMC_EV_ALIAS("IMC_RETRY.CH2", UCP_EVENT_32H_04H)	\
    +__PMC_EV_ALIAS("IMC_RETRY.ANY", UCP_EVENT_32H_07H)	\
    +__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.IOH", UCP_EVENT_33H_01H)	\
    +__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.REMOTE", UCP_EVENT_33H_02H)	\
    +__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.LOCAL", UCP_EVENT_33H_04H)	\
    +__PMC_EV_ALIAS("QHL_FRC_ACK_CNFLTS.ANY", UCP_EVENT_33H_07H)	\
    +__PMC_EV_ALIAS("QHL_SLEEPS.IOH_ORDER", UCP_EVENT_34H_01H)	\
    +__PMC_EV_ALIAS("QHL_SLEEPS.REMOTE_ORDER", UCP_EVENT_34H_02H)	\
    +__PMC_EV_ALIAS("QHL_SLEEPS.LOCAL_ORDER", UCP_EVENT_34H_04H)	\
    +__PMC_EV_ALIAS("QHL_SLEEPS.IOH_CONFLICT", UCP_EVENT_34H_08H)	\
    +__PMC_EV_ALIAS("QHL_SLEEPS.REMOTE_CONFLICT", UCP_EVENT_34H_10H)	\
    +__PMC_EV_ALIAS("QHL_SLEEPS.LOCAL_CONFLICT", UCP_EVENT_34H_20H)	\
    +__PMC_EV_ALIAS("ADDR_OPCODE_MATCH.IOH", UCP_EVENT_35H_01H)	\
    +__PMC_EV_ALIAS("ADDR_OPCODE_MATCH.REMOTE", UCP_EVENT_35H_02H)	\
    +__PMC_EV_ALIAS("ADDR_OPCODE_MATCH.LOCAL", UCP_EVENT_35H_04H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_0", UCP_EVENT_40H_01H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_0", UCP_EVENT_40H_02H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_0", UCP_EVENT_40H_04H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_1", UCP_EVENT_40H_08H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_1", UCP_EVENT_40H_10H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_1", UCP_EVENT_40H_20H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.LINK_0", UCP_EVENT_40H_07H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_SINGLE_FLIT.LINK_1", UCP_EVENT_40H_38H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_0", UCP_EVENT_41H_01H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_0", UCP_EVENT_41H_02H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_0", UCP_EVENT_41H_04H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_1", UCP_EVENT_41H_08H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_1", UCP_EVENT_41H_10H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_1", UCP_EVENT_41H_20H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.LINK_0", UCP_EVENT_41H_07H)	\
    +__PMC_EV_ALIAS("QPI_TX_STALLED_MULTI_FLIT.LINK_1", UCP_EVENT_41H_38H)	\
    +__PMC_EV_ALIAS("QPI_TX_HEADER.FULL.LINK_0", UCP_EVENT_42H_01H)	\
    +__PMC_EV_ALIAS("QPI_TX_HEADER.BUSY.LINK_0", UCP_EVENT_42H_02H)	\
    +__PMC_EV_ALIAS("QPI_TX_HEADER.FULL.LINK_1", UCP_EVENT_42H_04H)	\
    +__PMC_EV_ALIAS("QPI_TX_HEADER.BUSY.LINK_1", UCP_EVENT_42H_08H)	\
    +__PMC_EV_ALIAS("QPI_RX_NO_PPT_CREDIT.STALLS.LINK_0", UCP_EVENT_43H_01H)	\
    +__PMC_EV_ALIAS("QPI_RX_NO_PPT_CREDIT.STALLS.LINK_1", UCP_EVENT_43H_02H)	\
    +__PMC_EV_ALIAS("DRAM_OPEN.CH0", UCP_EVENT_60H_01H)	\
    +__PMC_EV_ALIAS("DRAM_OPEN.CH1", UCP_EVENT_60H_02H)	\
    +__PMC_EV_ALIAS("DRAM_OPEN.CH2", UCP_EVENT_60H_04H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH0", UCP_EVENT_61H_01H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH1", UCP_EVENT_61H_02H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_CLOSE.CH2", UCP_EVENT_61H_04H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH0", UCP_EVENT_62H_01H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH1", UCP_EVENT_62H_02H)	\
    +__PMC_EV_ALIAS("DRAM_PAGE_MISS.CH2", UCP_EVENT_62H_04H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.CH0", UCP_EVENT_63H_01H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH0", UCP_EVENT_63H_02H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.CH1", UCP_EVENT_63H_04H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH1", UCP_EVENT_63H_08H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.CH2", UCP_EVENT_63H_10H)	\
    +__PMC_EV_ALIAS("DRAM_READ_CAS.AUTOPRE_CH2", UCP_EVENT_63H_20H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH0", UCP_EVENT_64H_01H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH0", UCP_EVENT_64H_02H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH1", UCP_EVENT_64H_04H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH1", UCP_EVENT_64H_08H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.CH2", UCP_EVENT_64H_10H)	\
    +__PMC_EV_ALIAS("DRAM_WRITE_CAS.AUTOPRE_CH2", UCP_EVENT_64H_20H)	\
    +__PMC_EV_ALIAS("DRAM_REFRESH.CH0", UCP_EVENT_65H_01H)	\
    +__PMC_EV_ALIAS("DRAM_REFRESH.CH1", UCP_EVENT_65H_02H)	\
    +__PMC_EV_ALIAS("DRAM_REFRESH.CH2", UCP_EVENT_65H_04H)	\
    +__PMC_EV_ALIAS("DRAM_PRE_ALL.CH0", UCP_EVENT_66H_01H)	\
    +__PMC_EV_ALIAS("DRAM_PRE_ALL.CH1", UCP_EVENT_66H_02H)	\
    +__PMC_EV_ALIAS("DRAM_PRE_ALL.CH2", UCP_EVENT_66H_04H)	\
    +__PMC_EV_ALIAS("DRAM_THERMAL_THROTTLED", UCP_EVENT_67H_01H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLING_TEMP.CORE_0", UCP_EVENT_80H_01H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLING_TEMP.CORE_1", UCP_EVENT_80H_02H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLING_TEMP.CORE_2", UCP_EVENT_80H_04H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLING_TEMP.CORE_3", UCP_EVENT_80H_08H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLED_TEMP.CORE_0", UCP_EVENT_81H_01H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLED_TEMP.CORE_1", UCP_EVENT_81H_02H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLED_TEMP.CORE_2", UCP_EVENT_81H_04H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLED_TEMP.CORE_3", UCP_EVENT_81H_08H)	\
    +__PMC_EV_ALIAS("PROCHOT_ASSERTION", UCP_EVENT_82H_01H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLING_PROCHOT.CORE_0", UCP_EVENT_83H_01H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLING_PROCHOT.CORE_1", UCP_EVENT_83H_02H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLING_PROCHOT.CORE_2", UCP_EVENT_83H_04H)	\
    +__PMC_EV_ALIAS("THERMAL_THROTTLING_PROCHOT.CORE_3", UCP_EVENT_83H_08H)	\
    +__PMC_EV_ALIAS("TURBO_MODE.CORE_0", UCP_EVENT_84H_01H)	\
    +__PMC_EV_ALIAS("TURBO_MODE.CORE_1", UCP_EVENT_84H_02H)	\
    +__PMC_EV_ALIAS("TURBO_MODE.CORE_2", UCP_EVENT_84H_04H)	\
    +__PMC_EV_ALIAS("TURBO_MODE.CORE_3", UCP_EVENT_84H_08H)	\
    +__PMC_EV_ALIAS("CYCLES_UNHALTED_L3_FLL_ENABLE", UCP_EVENT_85H_02H)	\
    +__PMC_EV_ALIAS("CYCLES_UNHALTED_L3_FLL_DISABLE", UCP_EVENT_86H_01H)
    +
     /*
      * All known PMC events.
      *
    @@ -2013,9 +2981,13 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE",		IAP_EVENT_FDH_40H)
     	__PMC_EV_BLOCK(P5,	0x11080)	\
     	__PMC_EV_P5()				\
     	__PMC_EV_BLOCK(P6,	0x11100)	\
    -	__PMC_EV_P6()
    +	__PMC_EV_P6()				\
    +	__PMC_EV_BLOCK(UCF,	0x12000)	\
    +	__PMC_EV_UCF()				\
    +	__PMC_EV_BLOCK(UCP,	0x12080)	\
    +	__PMC_EV_UCP()
     
     #define	PMC_EVENT_FIRST	PMC_EV_TSC_TSC
    -#define	PMC_EVENT_LAST	PMC_EV_P6_LAST
    +#define	PMC_EVENT_LAST	PMC_EV_UCP_LAST
     
     #endif /* _DEV_HWPMC_PMC_EVENTS_H_ */
    diff --git a/sys/i386/include/pmc_mdep.h b/sys/i386/include/pmc_mdep.h
    index 4389a20c203..9209a2b79ed 100644
    --- a/sys/i386/include/pmc_mdep.h
    +++ b/sys/i386/include/pmc_mdep.h
    @@ -49,6 +49,8 @@ struct pmc_mdep;
      * PENTIUM	Intel Pentium MMX.
      * IAP		Intel Core/Core2/Atom programmable PMCs.
      * IAF		Intel fixed-function PMCs.
    + * UCP		Intel Uncore programmable PMCs.
    + * UCF		Intel Uncore fixed-function PMCs.
      */
     
     #include  /* K7 and K8 */
    @@ -57,11 +59,12 @@ struct pmc_mdep;
     #include 
     #include 
     #include 
    +#include 
     
     /*
      * Intel processors implementing V2 and later of the Intel performance
      * measurement architecture have PMCs of the following classes: TSC,
    - * IAF and IAP.
    + * IAF, IAP, UCF and UCP.
      */
     #define	PMC_MDEP_CLASS_INDEX_TSC	0
     #define	PMC_MDEP_CLASS_INDEX_K7		1
    @@ -71,6 +74,8 @@ struct pmc_mdep;
     #define	PMC_MDEP_CLASS_INDEX_P6		1
     #define	PMC_MDEP_CLASS_INDEX_IAP	1
     #define	PMC_MDEP_CLASS_INDEX_IAF	2
    +#define PMC_MDEP_CLASS_INDEX_UCP	3
    +#define PMC_MDEP_CLASS_INDEX_UCF	4
     
     /*
      * Architecture specific extensions to  structures.
    @@ -80,6 +85,8 @@ union pmc_md_op_pmcallocate  {
     	struct pmc_md_amd_op_pmcallocate	pm_amd;
     	struct pmc_md_iaf_op_pmcallocate	pm_iaf;
     	struct pmc_md_iap_op_pmcallocate	pm_iap;
    +	struct pmc_md_ucf_op_pmcallocate	pm_ucf;
    +	struct pmc_md_ucp_op_pmcallocate	pm_ucp;
     	struct pmc_md_p4_op_pmcallocate		pm_p4;
     	struct pmc_md_pentium_op_pmcallocate	pm_pentium;
     	struct pmc_md_ppro_op_pmcallocate	pm_ppro;
    @@ -97,6 +104,8 @@ union pmc_md_pmc  {
     	struct pmc_md_amd_pmc	pm_amd;
     	struct pmc_md_iaf_pmc	pm_iaf;
     	struct pmc_md_iap_pmc	pm_iap;
    +	struct pmc_md_ucf_pmc	pm_ucf;
    +	struct pmc_md_ucp_pmc	pm_ucp;
     	struct pmc_md_p4_pmc	pm_p4;
     	struct pmc_md_pentium_pmc pm_pentium;
     	struct pmc_md_ppro_pmc	pm_ppro;
    diff --git a/sys/modules/hwpmc/Makefile b/sys/modules/hwpmc/Makefile
    index 0a696a12e08..1febf548943 100644
    --- a/sys/modules/hwpmc/Makefile
    +++ b/sys/modules/hwpmc/Makefile
    @@ -10,7 +10,7 @@ SRCS=	hwpmc_mod.c hwpmc_logging.c vnode_if.h
     
     .if ${MACHINE_ARCH} == "amd64"
     SRCS+=	hwpmc_amd.c hwpmc_core.c hwpmc_intel.c hwpmc_piv.c hwpmc_tsc.c
    -SRCS+=	hwpmc_x86.c
    +SRCS+=	hwpmc_x86.c hwpmc_uncore.c
     SRCS+=	device_if.h bus_if.h
     .endif
     
    @@ -20,7 +20,7 @@ SRCS+=	hwpmc_arm.c
     
     .if ${MACHINE_ARCH} == "i386"
     SRCS+=	hwpmc_amd.c hwpmc_core.c hwpmc_intel.c hwpmc_piv.c hwpmc_ppro.c
    -SRCS+=	hwpmc_pentium.c hwpmc_tsc.c hwpmc_x86.c
    +SRCS+=	hwpmc_pentium.c hwpmc_tsc.c hwpmc_x86.c hwpmc_uncore.c
     SRCS+=	device_if.h bus_if.h
     .endif
     
    diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
    index 1cc23933a9a..488bfbb46ce 100644
    --- a/sys/sys/pmc.h
    +++ b/sys/sys/pmc.h
    @@ -40,7 +40,7 @@
     
     #define	PMC_MODULE_NAME		"hwpmc"
     #define	PMC_NAME_MAX		16 /* HW counter name size */
    -#define	PMC_CLASS_MAX		4  /* max #classes of PMCs per-system */
    +#define	PMC_CLASS_MAX		6  /* max #classes of PMCs per-system */
     
     /*
      * Kernel<->userland API version number [MMmmpppp]
    @@ -83,8 +83,9 @@
     	__PMC_CPU(INTEL_CORE,	0x87,	"Intel Core Solo/Duo")	\
     	__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_ATOM,	0x8A,	"Intel Atom")		\
    +	__PMC_CPU(INTEL_COREI7, 0x8B,   "Intel Core i7")	\
    +	__PMC_CPU(INTEL_WESTMERE, 0x8C,   "Intel Westmere")
     
     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_WESTMERE
     
     /*
      * Classes of PMCs
    @@ -107,7 +108,9 @@ 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(UCF)	/* Intel Uncore programmable */		\
    +	__PMC_CLASS(UCP)	/* Intel Uncore fixed function */
     
     enum pmc_class {
     #undef  __PMC_CLASS
    @@ -116,7 +119,7 @@ enum pmc_class {
     };
     
     #define	PMC_CLASS_FIRST	PMC_CLASS_TSC
    -#define	PMC_CLASS_LAST	PMC_CLASS_IAP
    +#define	PMC_CLASS_LAST	PMC_CLASS_UCP
     
     /*
      * A PMC can be in the following states:
    
    From cc32d5b339b0041f6fc54f8fc76fa019ea441e4b Mon Sep 17 00:00:00 2001
    From: Fabien Thomas 
    Date: Fri, 16 Apr 2010 15:45:09 +0000
    Subject: [PATCH 1976/2592] MFC r206089, r206684:
    
    - Support for uncore counting events: one fixed PMC with the uncore
       domain clock, 8 programmable PMC.
    - Westmere based CPU (Xeon 5600, Corei7 980X) support.
    - New man pages with events list for core and uncore.
    - Updated Corei7 events with Intel 253669-033US December 2009 doc.
      There is some removed events in the documentation, they have been
      kept in the code but documented in the man page as obsolete.
    - Offcore response events can be setup with rsp token.
    
    Sponsored by: NETASQ
    ---
     lib/libpmc/Makefile         |    5 +
     lib/libpmc/libpmc.c         |  181 +++-
     lib/libpmc/pmc.corei7.3     | 1581 +++++++++++++++++++++++++++++++++++
     lib/libpmc/pmc.corei7uc.3   |  880 +++++++++++++++++++
     lib/libpmc/pmc.ucf.3        |  115 +++
     lib/libpmc/pmc.westmere.3   | 1329 +++++++++++++++++++++++++++++
     lib/libpmc/pmc.westmereuc.3 | 1083 ++++++++++++++++++++++++
     7 files changed, 5167 insertions(+), 7 deletions(-)
     create mode 100644 lib/libpmc/pmc.corei7.3
     create mode 100644 lib/libpmc/pmc.corei7uc.3
     create mode 100644 lib/libpmc/pmc.ucf.3
     create mode 100644 lib/libpmc/pmc.westmere.3
     create mode 100644 lib/libpmc/pmc.westmereuc.3
    
    diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile
    index 7d97c96a0da..3ad1c4dee28 100644
    --- a/lib/libpmc/Makefile
    +++ b/lib/libpmc/Makefile
    @@ -28,11 +28,16 @@ MAN+=	pmc.atom.3
     MAN+=	pmc.core.3
     MAN+=	pmc.core2.3
     MAN+=	pmc.iaf.3
    +MAN+=	pmc.ucf.3
     MAN+=	pmc.k7.3
     MAN+=	pmc.k8.3
     MAN+=	pmc.p4.3
     MAN+=	pmc.p5.3
     MAN+=	pmc.p6.3
    +MAN+=	pmc.corei7.3
    +MAN+=	pmc.corei7uc.3
    +MAN+=	pmc.westmere.3
    +MAN+=	pmc.westmereuc.3
     MAN+=	pmc.tsc.3
     
     MLINKS+= \
    diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
    index af716da157b..929ca73a15c 100644
    --- a/lib/libpmc/libpmc.c
    +++ b/lib/libpmc/libpmc.c
    @@ -54,6 +54,10 @@ static int iaf_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
         struct pmc_op_pmcallocate *_pmc_config);
     static int iap_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
         struct pmc_op_pmcallocate *_pmc_config);
    +static int ucf_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
    +    struct pmc_op_pmcallocate *_pmc_config);
    +static int ucp_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
    +    struct pmc_op_pmcallocate *_pmc_config);
     static int k8_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
         struct pmc_op_pmcallocate *_pmc_config);
     static int p4_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
    @@ -132,6 +136,7 @@ PMC_CLASSDEP_TABLE(k8, K8);
     PMC_CLASSDEP_TABLE(p4, P4);
     PMC_CLASSDEP_TABLE(p5, P5);
     PMC_CLASSDEP_TABLE(p6, P6);
    +PMC_CLASSDEP_TABLE(ucf, UCF);
     
     #undef	__PMC_EV_ALIAS
     #define	__PMC_EV_ALIAS(N,CODE) 	{ N, PMC_EV_##CODE },
    @@ -157,6 +162,21 @@ static const struct pmc_event_descr corei7_event_table[] =
     	__PMC_EV_ALIAS_COREI7()
     };
     
    +static const struct pmc_event_descr westmere_event_table[] =
    +{
    +	__PMC_EV_ALIAS_WESTMERE()
    +};
    +
    +static const struct pmc_event_descr corei7uc_event_table[] =
    +{
    +	__PMC_EV_ALIAS_COREI7UC()
    +};
    +
    +static const struct pmc_event_descr westmereuc_event_table[] =
    +{
    +	__PMC_EV_ALIAS_WESTMEREUC()
    +};
    +
     /*
      * PMC_MDEP_TABLE(NAME, PRIMARYCLASS, ADDITIONAL_CLASSES...)
      *
    @@ -170,7 +190,8 @@ static const struct pmc_event_descr corei7_event_table[] =
     PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
     PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC);
     PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
    -PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
    +PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
    +PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
     PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC);
     PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC);
     PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC);
    @@ -201,6 +222,10 @@ PMC_CLASS_TABLE_DESC(atom, IAP, atom, iap);
     PMC_CLASS_TABLE_DESC(core, IAP, core, iap);
     PMC_CLASS_TABLE_DESC(core2, IAP, core2, iap);
     PMC_CLASS_TABLE_DESC(corei7, IAP, corei7, iap);
    +PMC_CLASS_TABLE_DESC(westmere, IAP, westmere, iap);
    +PMC_CLASS_TABLE_DESC(ucf, UCF, ucf, ucf);
    +PMC_CLASS_TABLE_DESC(corei7uc, UCP, corei7uc, ucp);
    +PMC_CLASS_TABLE_DESC(westmereuc, UCP, westmereuc, ucp);
     #endif
     #if	defined(__i386__)
     PMC_CLASS_TABLE_DESC(k7, K7, k7, k7);
    @@ -281,7 +306,7 @@ struct pmc_masks {
     	const uint32_t	pm_value;
     };
     #define	PMCMASK(N,V)	{ .pm_name = #N, .pm_value = (V) }
    -#define	NULLMASK	PMCMASK(NULL,0)
    +#define	NULLMASK	{ .pm_name = NULL }
     
     #if defined(__amd64__) || defined(__i386__)
     static int
    @@ -474,6 +499,8 @@ static struct pmc_event_alias core2_aliases_without_iaf[] = {
     #define	atom_aliases_without_iaf	core2_aliases_without_iaf
     #define corei7_aliases			core2_aliases
     #define corei7_aliases_without_iaf	core2_aliases_without_iaf
    +#define westmere_aliases		core2_aliases
    +#define westmere_aliases_without_iaf	core2_aliases_without_iaf
     
     #define	IAF_KW_OS		"os"
     #define	IAF_KW_USR		"usr"
    @@ -524,6 +551,7 @@ iaf_allocate_pmc(enum pmc_event pe, char *ctrspec,
     #define	IAP_KW_SNOOPTYPE	"snooptype"
     #define	IAP_KW_TRANSITION	"trans"
     #define	IAP_KW_USR		"usr"
    +#define	IAP_KW_RSP		"rsp"
     
     static struct pmc_masks iap_core_mask[] = {
     	PMCMASK(all,	(0x3 << 14)),
    @@ -571,19 +599,38 @@ static struct pmc_masks iap_transition_mask[] = {
     	NULLMASK
     };
     
    +static struct pmc_masks iap_rsp_mask[] = {
    +	PMCMASK(DMND_DATA_RD,		(1 <<  0)),
    +	PMCMASK(DMND_RFO,		(1 <<  1)),
    +	PMCMASK(DMND_IFETCH,		(1 <<  2)),
    +	PMCMASK(WB,			(1 <<  3)),
    +	PMCMASK(PF_DATA_RD,		(1 <<  4)),
    +	PMCMASK(PF_RFO,			(1 <<  5)),
    +	PMCMASK(PF_IFETCH,		(1 <<  6)),
    +	PMCMASK(OTHER,			(1 <<  7)),
    +	PMCMASK(UNCORE_HIT,		(1 <<  8)),
    +	PMCMASK(OTHER_CORE_HIT_SNP,	(1 <<  9)),
    +	PMCMASK(OTHER_CORE_HITM,	(1 << 10)),
    +	PMCMASK(REMOTE_CACHE_FWD,	(1 << 12)),
    +	PMCMASK(REMOTE_DRAM,		(1 << 13)),
    +	PMCMASK(LOCAL_DRAM,		(1 << 14)),
    +	PMCMASK(NON_DRAM,		(1 << 15)),
    +	NULLMASK
    +};
    +
     static int
     iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
         struct pmc_op_pmcallocate *pmc_config)
     {
     	char *e, *p, *q;
    -	uint32_t cachestate, evmask;
    +	uint32_t cachestate, evmask, rsp;
     	int count, n;
     
     	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE |
     	    PMC_CAP_QUALIFIER);
     	pmc_config->pm_md.pm_iap.pm_iap_config = 0;
     
    -	cachestate = evmask = 0;
    +	cachestate = evmask = rsp = 0;
     
     	/* Parse additional modifiers if present */
     	while ((p = strsep(&ctrspec, ",")) != NULL) {
    @@ -630,8 +677,7 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
     				return (-1);
     		} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM ||
     		    cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2 ||
    -		    cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2EXTREME ||
    -		    cpu_info.pm_cputype == PMC_CPU_INTEL_COREI7) {
    +		    cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2EXTREME) {
     			if (KWPREFIXMATCH(p, IAP_KW_SNOOPRESPONSE "=")) {
     				n = pmc_parse_mask(iap_snoopresponse_mask, p,
     				    &evmask);
    @@ -640,6 +686,12 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
     				    &evmask);
     			} else
     				return (-1);
    +		} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_COREI7 ||
    +		    cpu_info.pm_cputype == PMC_CPU_INTEL_WESTMERE) {
    +			if (KWPREFIXMATCH(p, IAP_KW_RSP "=")) {
    +				n = pmc_parse_mask(iap_rsp_mask, p, &rsp);
    +			} else
    +				return (-1);
     		} else
     			return (-1);
     
    @@ -672,6 +724,69 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
     	}
     
     	pmc_config->pm_md.pm_iap.pm_iap_config |= cachestate;
    +	pmc_config->pm_md.pm_iap.pm_iap_rsp = rsp;
    +
    +	return (0);
    +}
    +
    +/*
    + * Intel Uncore.
    + */
    +
    +static int
    +ucf_allocate_pmc(enum pmc_event pe, char *ctrspec,
    +    struct pmc_op_pmcallocate *pmc_config)
    +{
    +	(void) pe;
    +	(void) ctrspec;
    +
    +	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
    +	pmc_config->pm_md.pm_ucf.pm_ucf_flags = 0;
    +
    +	return (0);
    +}
    +
    +#define	UCP_KW_CMASK		"cmask"
    +#define	UCP_KW_EDGE		"edge"
    +#define	UCP_KW_INV		"inv"
    +
    +static int
    +ucp_allocate_pmc(enum pmc_event pe, char *ctrspec,
    +    struct pmc_op_pmcallocate *pmc_config)
    +{
    +	char *e, *p, *q;
    +	int count, n;
    +
    +	(void) pe;
    +
    +	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE |
    +	    PMC_CAP_QUALIFIER);
    +	pmc_config->pm_md.pm_ucp.pm_ucp_config = 0;
    +
    +	/* Parse additional modifiers if present */
    +	while ((p = strsep(&ctrspec, ",")) != NULL) {
    +
    +		n = 0;
    +		if (KWPREFIXMATCH(p, UCP_KW_CMASK "=")) {
    +			q = strchr(p, '=');
    +			if (*++q == '\0') /* skip '=' */
    +				return (-1);
    +			count = strtol(q, &e, 0);
    +			if (e == q || *e != '\0')
    +				return (-1);
    +			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
    +			pmc_config->pm_md.pm_ucp.pm_ucp_config |=
    +			    UCP_CMASK(count);
    +		} else if (KWMATCH(p, UCP_KW_EDGE)) {
    +			pmc_config->pm_caps |= PMC_CAP_EDGE;
    +		} else if (KWMATCH(p, UCP_KW_INV)) {
    +			pmc_config->pm_caps |= PMC_CAP_INVERT;
    +		} else
    +			return (-1);
    +
    +		if (n < 0)	/* Parsing failed. */
    +			return (-1);
    +	}
     
     	return (0);
     }
    @@ -2309,6 +2424,31 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
     			ev = corei7_event_table;
     			count = PMC_EVENT_TABLE_SIZE(corei7);
     			break;
    +		case PMC_CPU_INTEL_WESTMERE:
    +			ev = westmere_event_table;
    +			count = PMC_EVENT_TABLE_SIZE(westmere);
    +			break;
    +		}
    +		break;
    +	case PMC_CLASS_UCF:
    +		ev = ucf_event_table;
    +		count = PMC_EVENT_TABLE_SIZE(ucf);
    +		break;
    +	case PMC_CLASS_UCP:
    +		/*
    +		 * Return the most appropriate set of event name
    +		 * spellings for the current CPU.
    +		 */
    +		switch (cpu_info.pm_cputype) {
    +		default:
    +		case PMC_CPU_INTEL_COREI7:
    +			ev = corei7uc_event_table;
    +			count = PMC_EVENT_TABLE_SIZE(corei7uc);
    +			break;
    +		case PMC_CPU_INTEL_WESTMERE:
    +			ev = westmereuc_event_table;
    +			count = PMC_EVENT_TABLE_SIZE(westmereuc);
    +			break;
     		}
     		break;
     	case PMC_CLASS_TSC:
    @@ -2514,8 +2654,15 @@ pmc_init(void)
     		PMC_MDEP_INIT_INTEL_V2(core2);
     		break;
     	case PMC_CPU_INTEL_COREI7:
    +		pmc_class_table[n++] = &ucf_class_table_descr;
    +		pmc_class_table[n++] = &corei7uc_class_table_descr;
     		PMC_MDEP_INIT_INTEL_V2(corei7);
     		break;
    +	case PMC_CPU_INTEL_WESTMERE:
    +		pmc_class_table[n++] = &ucf_class_table_descr;
    +		pmc_class_table[n++] = &westmereuc_class_table_descr;
    +		PMC_MDEP_INIT_INTEL_V2(westmere);
    +		break;
     	case PMC_CPU_INTEL_PIV:
     		PMC_MDEP_INIT(p4);
     		pmc_class_table[n] = &p4_class_table_descr;
    @@ -2618,10 +2765,30 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
     			ev = corei7_event_table;
     			evfence = corei7_event_table + PMC_EVENT_TABLE_SIZE(corei7);
     			break;
    +		case PMC_CPU_INTEL_WESTMERE:
    +			ev = westmere_event_table;
    +			evfence = westmere_event_table + PMC_EVENT_TABLE_SIZE(westmere);
    +			break;
     		default:	/* Unknown CPU type. */
     			break;
     		}
    -	} if (pe >= PMC_EV_K7_FIRST && pe <= PMC_EV_K7_LAST) {
    +	} else if (pe >= PMC_EV_UCF_FIRST && pe <= PMC_EV_UCF_LAST) {
    +		ev = ucf_event_table;
    +		evfence = ucf_event_table + PMC_EVENT_TABLE_SIZE(ucf);
    +	} else if (pe >= PMC_EV_UCP_FIRST && pe <= PMC_EV_UCP_LAST) {
    +		switch (cpu) {
    +		case PMC_CPU_INTEL_COREI7:
    +			ev = corei7uc_event_table;
    +			evfence = corei7uc_event_table + PMC_EVENT_TABLE_SIZE(corei7uc);
    +			break;
    +		case PMC_CPU_INTEL_WESTMERE:
    +			ev = westmereuc_event_table;
    +			evfence = westmereuc_event_table + PMC_EVENT_TABLE_SIZE(westmereuc);
    +			break;
    +		default:	/* Unknown CPU type. */
    +			break;
    +		}
    +	} else if (pe >= PMC_EV_K7_FIRST && pe <= PMC_EV_K7_LAST) {
     		ev = k7_event_table;
     		evfence = k7_event_table + PMC_EVENT_TABLE_SIZE(k7);
     	} else if (pe >= PMC_EV_K8_FIRST && pe <= PMC_EV_K8_LAST) {
    diff --git a/lib/libpmc/pmc.corei7.3 b/lib/libpmc/pmc.corei7.3
    new file mode 100644
    index 00000000000..1a8b9d9d419
    --- /dev/null
    +++ b/lib/libpmc/pmc.corei7.3
    @@ -0,0 +1,1581 @@
    +.\" Copyright (c) 2010 Fabien Thomas.  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 Joseph Koshy ``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 Joseph Koshy 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 March 24, 2010
    +.Os
    +.Dt PMC.COREI7 3
    +.Sh NAME
    +.Nm pmc.corei7
    +.Nd measurement events for
    +.Tn Intel
    +.Tn Core i7 and Xeon 5500
    +family CPUs
    +.Sh LIBRARY
    +.Lb libpmc
    +.Sh SYNOPSIS
    +.In pmc.h
    +.Sh DESCRIPTION
    +.Tn Intel
    +.Tn "Core i7"
    +CPUs contain PMCs conforming to version 2 of the
    +.Tn Intel
    +performance measurement architecture.
    +These CPUs may contain up to three classes of PMCs:
    +.Bl -tag -width "Li PMC_CLASS_IAP"
    +.It Li PMC_CLASS_IAF
    +Fixed-function counters that count only one hardware event per counter.
    +.It Li PMC_CLASS_IAP
    +Programmable counters that may be configured to count one of a defined
    +set of hardware events.
    +.El
    +.Pp
    +The number of PMCs available in each class and their widths need to be
    +determined at run time by calling
    +.Xr pmc_cpuinfo 3 .
    +.Pp
    +Intel Core i7 and Xeon 5500 PMCs are documented in
    +.Rs
    +.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
    +.%T "Volume 3B: System Programming Guide, Part 2"
    +.%N "Order Number: 253669-033US"
    +.%D December 2009
    +.%Q "Intel Corporation"
    +.Re
    +.Ss COREI7 AND XEON 5500 FIXED FUNCTION PMCS
    +These PMCs and their supported events are documented in
    +.Xr pmc.iaf 3 .
    +Not all CPUs in this family implement fixed-function counters.
    +.Ss COREI7 AND XEON 5500 PROGRAMMABLE PMCS
    +The programmable PMCs support the following capabilities:
    +.Bl -column "PMC_CAP_INTERRUPT" "Support"
    +.It Em Capability Ta Em Support
    +.It PMC_CAP_CASCADE Ta \&No
    +.It PMC_CAP_EDGE Ta Yes
    +.It PMC_CAP_INTERRUPT Ta Yes
    +.It PMC_CAP_INVERT Ta Yes
    +.It PMC_CAP_READ Ta Yes
    +.It PMC_CAP_PRECISE Ta \&No
    +.It PMC_CAP_SYSTEM Ta Yes
    +.It PMC_CAP_TAGGING Ta \&No
    +.It PMC_CAP_THRESHOLD Ta Yes
    +.It PMC_CAP_USER Ta Yes
    +.It PMC_CAP_WRITE Ta Yes
    +.El
    +.Ss Event Qualifiers
    +Event specifiers for these PMCs support the following common
    +qualifiers:
    +.Bl -tag -width indent
    +.It Li rsp= Ns Ar value
    +Configure the Off-core Response bits.
    +.Bl -tag -width indent
    +.It Li DMND_DATA_RD
    +Counts the number of demand and DCU prefetch data reads of full
    +and partial cachelines as well as demand data page table entry
    +cacheline reads. Does not count L2 data read prefetches or
    +instruction fetches.
    +.It Li DMND_RFO
    +Counts the number of demand and DCU prefetch reads for ownership
    +(RFO) requests generated by a write to data cacheline. Does not
    +count L2 RFO.
    +.It Li DMND_IFETCH
    +Counts the number of demand and DCU prefetch instruction cacheline
    +reads. Does not count L2 code read prefetches.
    +WB
    +Counts the number of writeback (modified to exclusive) transactions.
    +.It Li PF_DATA_RD
    +Counts the number of data cacheline reads generated by L2 prefetchers.
    +.It Li PF_RFO
    +Counts the number of RFO requests generated by L2 prefetchers.
    +.It Li PF_IFETCH
    +Counts the number of code reads generated by L2 prefetchers.
    +.It Li OTHER
    +Counts one of the following transaction types, including L3 invalidate,
    +I/O, full or partial writes, WC or non-temporal stores, CLFLUSH, Fences,
    +lock, unlock, split lock.
    +.It Li UNCORE_HIT
    +L3 Hit: local or remote home requests that hit L3 cache in the uncore
    +with no coherency actions required (snooping).
    +.It Li OTHER_CORE_HIT_SNP
    +L3 Hit: local or remote home requests that hit L3 cache in the uncore
    +and was serviced by another core with a cross core snoop where no modified
    +copies were found (clean).
    +.It Li OTHER_CORE_HITM
    +L3 Hit: local or remote home requests that hit L3 cache in the uncore
    +and was serviced by another core with a cross core snoop where modified
    +copies were found (HITM).
    +.It Li REMOTE_CACHE_FWD
    +L3 Miss: local homed requests that missed the L3 cache and was serviced
    +by forwarded data following a cross package snoop where no modified
    +copies found. (Remote home requests are not counted)
    +.It Li REMOTE_DRAM
    +L3 Miss: remote home requests that missed the L3 cache and were serviced
    +by remote DRAM.
    +.It Li LOCAL_DRAM
    +L3 Miss: local home requests that missed the L3 cache and were serviced
    +by local DRAM.
    +.It Li NON_DRAM
    +Non-DRAM requests that were serviced by IOH.
    +.El
    +.It Li cmask= Ns Ar value
    +Configure the PMC to increment only if the number of configured
    +events measured in a cycle is greater than or equal to
    +.Ar value .
    +.It Li edge
    +Configure the PMC to count the number of de-asserted to asserted
    +transitions of the conditions expressed by the other qualifiers.
    +If specified, the counter will increment only once whenever a
    +condition becomes true, irrespective of the number of clocks during
    +which the condition remains true.
    +.It Li inv
    +Invert the sense of comparison when the
    +.Dq Li cmask
    +qualifier is present, making the counter increment when the number of
    +events per cycle is less than the value specified by the
    +.Dq Li cmask
    +qualifier.
    +.It Li os
    +Configure the PMC to count events happening at processor privilege
    +level 0.
    +.It Li usr
    +Configure the PMC to count events occurring at privilege levels 1, 2
    +or 3.
    +.El
    +.Pp
    +If neither of the
    +.Dq Li os
    +or
    +.Dq Li usr
    +qualifiers are specified, the default is to enable both.
    +.Ss Event Specifiers (Programmable PMCs)
    +Core i7 and Xeon 5500 programmable PMCs support the following events:
    +.Bl -tag -width indent
    +.It Li SB_DRAIN.ANY
    +.Pq Event 04H , Umask 07H
    +Counts the number of store buffer drains.
    +.It Li STORE_BLOCKS.AT_RET
    +.Pq Event 06H , Umask 04H
    +Counts number of loads delayed with at-Retirement block code. The following
    +loads need to be executed at retirement and wait for all senior stores on
    +the same thread to be drained: load splitting across 4K boundary (page
    +split), load accessing uncacheable (UC or USWC) memory, load lock, and load
    +with page table in UC or USWC memory region.
    +.It Li STORE_BLOCKS.L1D_BLOCK
    +.Pq Event 06H , Umask 08H
    +Cacheable loads delayed with L1D block code
    +.It Li PARTIAL_ADDRESS_ALIAS
    +.Pq Event 07H , Umask 01H
    +Counts false dependency due to partial address aliasing
    +.It Li DTLB_LOAD_MISSES.ANY
    +.Pq Event 08H , Umask 01H
    +Counts all load misses that cause a page walk
    +.It Li DTLB_LOAD_MISSES.WALK_COMPLETED
    +.Pq Event 08H , Umask 02H
    +Counts number of completed page walks due to load miss in the STLB.
    +.It Li DTLB_LOAD_MISSES.STLB_HIT
    +.Pq Event 08H , Umask 10H
    +Number of cache load STLB hits
    +.It Li DTLB_LOAD_MISSES.PDE_MISS
    +.Pq Event 08H , Umask 20H
    +Number of DTLB cache load misses where the low part of the linear to
    +physical address translation was missed.
    +.It Li DTLB_LOAD_MISSES.PDP_MISS
    +.Pq Event 08H , Umask 40H
    +Number of DTLB cache load misses where the high part of the linear to
    +physical address translation was missed.
    +.It Li DTLB_LOAD_MISSES.LARGE_WALK_COMPLETED
    +.Pq Event 08H , Umask 80H
    +Counts number of completed large page walks due to load miss in the STLB.
    +.It Li MEM_INST_RETIRED.LOADS
    +.Pq Event 0BH , Umask 01H
    +Counts the number of instructions with an architecturally-visible store
    +retired on the architected path.
    +In conjunction with ld_lat facility
    +.It Li MEM_INST_RETIRED.STORES
    +.Pq Event 0BH , Umask 02H
    +Counts the number of instructions with an architecturally-visible store
    +retired on the architected path.
    +In conjunction with ld_lat facility
    +.It Li MEM_INST_RETIRED.LATENCY_ABOVE_THRESHOLD
    +.Pq Event 0BH , Umask 10H
    +Counts the number of instructions exceeding the latency specified with
    +ld_lat facility.
    +In conjunction with ld_lat facility
    +.It Li MEM_STORE_RETIRED.DTLB_MISS
    +.Pq Event 0CH , Umask 01H
    +The event counts the number of retired stores that missed the DTLB. The DTLB
    +miss is not counted if the store operation causes a fault. Does not counter
    +prefetches. Counts both primary and secondary misses to the TLB
    +.It Li UOPS_ISSUED.ANY
    +.Pq Event 0EH , Umask 01H
    +Counts the number of Uops issued by the Register Allocation Table to the
    +Reservation Station, i.e. the UOPs issued from the front end to the back
    +end.
    +.It Li UOPS_ISSUED.STALLED_CYCLES
    +.Pq Event 0EH , Umask 01H
    +Counts the number of cycles no Uops issued by the Register Allocation Table
    +to the Reservation Station, i.e. the UOPs issued from the front end to the
    +back end.
    +set invert=1, cmask = 1
    +.It Li UOPS_ISSUED.FUSED
    +.Pq Event 0EH , Umask 02H
    +Counts the number of fused Uops that were issued from the Register
    +Allocation Table to the Reservation Station.
    +.It Li MEM_UNCORE_RETIRED.L3_DATA_MISS_UNKNOWN
    +.Pq Event 0FH , Umask 01H
    +Counts number of memory load instructions retired where the memory reference
    +missed L3 and data source is unknown.
    +Available only for CPUID signature 06_2EH
    +.It Li MEM_UNCORE_RETIRED.OTHER_CORE_L2_HITM
    +.Pq Event 0FH , Umask 02H
    +Counts number of memory load instructions retired where the memory reference
    +hit modified data in a sibling core residing on the same socket.
    +.It Li MEM_UNCORE_RETIRED.REMOTE_CACHE_LOCAL_HOME_HIT
    +.Pq Event 0FH , Umask 08H
    +Counts number of memory load instructions retired where the memory reference
    +missed the L1, L2 and L3 caches and HIT in a remote socket's cache. Only
    +counts locally homed lines.
    +.It Li MEM_UNCORE_RETIRED.REMOTE_DRAM
    +.Pq Event 0FH , Umask 10H
    +Counts number of memory load instructions retired where the memory reference
    +missed the L1, L2 and L3 caches and was remotely homed. This includes both
    +DRAM access and HITM in a remote socket's cache for remotely homed lines.
    +.It Li MEM_UNCORE_RETIRED.LOCAL_DRAM
    +.Pq Event 0FH , Umask 20H
    +Counts number of memory load instructions retired where the memory reference
    +missed the L1, L2 and L3 caches and required a local socket memory
    +reference. This includes locally homed cachelines that were in a modified
    +state in another socket.
    +.It Li MEM_UNCORE_RETIRED.UNCACHEABLE
    +.Pq Event 0FH , Umask 80H
    +Counts number of memory load instructions retired where the memory reference
    +missed the L1, L2 and L3 caches and to perform I/O.
    +Available only for CPUID signature 06_2EH
    +.It Li FP_COMP_OPS_EXE.X87
    +.Pq Event 10H , Umask 01H
    +Counts the number of FP Computational Uops Executed. The number of FADD,
    +FSUB, FCOM, FMULs, integer MULsand IMULs, FDIVs, FPREMs, FSQRTS, integer
    +DIVs, and IDIVs. This event does not distinguish an FADD used in the middle
    +of a transcendental flow from a separate FADD instruction.
    +.It Li FP_COMP_OPS_EXE.MMX
    +.Pq Event 10H , Umask 02H
    +Counts number of MMX Uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_FP
    +.Pq Event 10H , Umask 04H
    +Counts number of SSE and SSE2 FP uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE2_INTEGER
    +.Pq Event 10H , Umask 08H
    +Counts number of SSE2 integer uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_FP_PACKED
    +.Pq Event 10H , Umask 10H
    +Counts number of SSE FP packed uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_FP_SCALAR
    +.Pq Event 10H , Umask 20H
    +Counts number of SSE FP scalar uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION
    +.Pq Event 10H , Umask 40H
    +Counts number of SSE* FP single precision uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION
    +.Pq Event 10H , Umask 80H
    +Counts number of SSE* FP double precision uops executed.
    +.It Li SIMD_INT_128.PACKED_MPY
    +.Pq Event 12H , Umask 01H
    +Counts number of 128 bit SIMD integer multiply operations.
    +.It Li SIMD_INT_128.PACKED_SHIFT
    +.Pq Event 12H , Umask 02H
    +Counts number of 128 bit SIMD integer shift operations.
    +.It Li SIMD_INT_128.PACK
    +.Pq Event 12H , Umask 04H
    +Counts number of 128 bit SIMD integer pack operations.
    +.It Li SIMD_INT_128.UNPACK
    +.Pq Event 12H , Umask 08H
    +Counts number of 128 bit SIMD integer unpack operations.
    +.It Li SIMD_INT_128.PACKED_LOGICAL
    +.Pq Event 12H , Umask 10H
    +Counts number of 128 bit SIMD integer logical operations.
    +.It Li SIMD_INT_128.PACKED_ARITH
    +.Pq Event 12H , Umask 20H
    +Counts number of 128 bit SIMD integer arithmetic operations.
    +.It Li SIMD_INT_128.SHUFFLE_MOVE
    +.Pq Event 12H , Umask 40H
    +Counts number of 128 bit SIMD integer shuffle and move operations.
    +.It Li LOAD_DISPATCH.RS
    +.Pq Event 13H , Umask 01H
    +Counts number of loads dispatched from the Reservation Station that bypass
    +the Memory Order Buffer.
    +.It Li LOAD_DISPATCH.RS_DELAYED
    +.Pq Event 13H , Umask 02H
    +Counts the number of delayed RS dispatches at the stage latch. If an RS
    +dispatch can not bypass to LB, it has another chance to dispatch from the
    +one-cycle delayed staging latch before it is written into the LB.
    +.It Li LOAD_DISPATCH.MOB
    +.Pq Event 13H , Umask 04H
    +Counts the number of loads dispatched from the Reservation Station to the
    +Memory Order Buffer.
    +.It Li LOAD_DISPATCH.ANY
    +.Pq Event 13H , Umask 07H
    +Counts all loads dispatched from the Reservation Station.
    +.It Li ARITH.CYCLES_DIV_BUSY
    +.Pq Event 14H , Umask 01H
    +Counts the number of cycles the divider is busy executing divide or square
    +root operations. The divide can be integer, X87 or Streaming SIMD Extensions
    +(SSE). The square root operation can be either X87 or SSE.
    +Set 'edge =1, invert=1, cmask=1' to count the number of divides.
    +Count may be incorrect When SMT is on.
    +.It Li ARITH.MUL
    +.Pq Event 14H , Umask 02H
    +Counts the number of multiply operations executed. This includes integer as
    +well as floating point multiply operations but excludes DPPS mul and MPSAD.
    +Count may be incorrect When SMT is on
    +.It Li INST_QUEUE_WRITES
    +.Pq Event 17H , Umask 01H
    +Counts the number of instructions written into the instruction queue every
    +cycle.
    +.It Li INST_DECODED.DEC0
    +.Pq Event 18H , Umask 01H
    +Counts number of instructions that require decoder 0 to be decoded. Usually,
    +this means that the instruction maps to more than 1 uop
    +.It Li TWO_UOP_INSTS_DECODED
    +.Pq Event 19H , Umask 01H
    +An instruction that generates two uops was decoded
    +.It Li INST_QUEUE_WRITE_CYCLES
    +.Pq Event 1EH , Umask 01H
    +This event counts the number of cycles during which instructions are written
    +to the instruction queue. Dividing this counter by the number of
    +instructions written to the instruction queue (INST_QUEUE_WRITES) yields the
    +average number of instructions decoded each cycle. If this number is less
    +than four and the pipe stalls, this indicates that the decoder is failing to
    +decode enough instructions per cycle to sustain the 4-wide pipeline.
    +If SSE* instructions that are 6 bytes or longer arrive one after another,
    +then front end throughput may limit execution speed. In such case,
    +.It Li LSD_OVERFLOW
    +.Pq Event 20H , Umask 01H
    +Counts number of loops that cant stream from the instruction queue.
    +.It Li L2_RQSTS.LD_HIT
    +.Pq Event 24H , Umask 01H
    +Counts number of loads that hit the L2 cache. L2 loads include both L1D
    +demand misses as well as L1D prefetches. L2 loads can be rejected for
    +various reasons. Only non rejected loads are counted.
    +.It Li L2_RQSTS.LD_MISS
    +.Pq Event 24H , Umask 02H
    +Counts the number of loads that miss the L2 cache. L2 loads include both L1D
    +demand misses as well as L1D prefetches.
    +.It Li L2_RQSTS.LOADS
    +.Pq Event 24H , Umask 03H
    +Counts all L2 load requests. L2 loads include both L1D demand misses as well
    +as L1D prefetches.
    +.It Li L2_RQSTS.RFO_HIT
    +.Pq Event 24H , Umask 04H
    +Counts the number of store RFO requests that hit the L2 cache. L2 RFO
    +requests include both L1D demand RFO misses as well as L1D RFO prefetches.
    +Count includes WC memory requests, where the data is not fetched but the
    +permission to write the line is required.
    +.It Li L2_RQSTS.RFO_MISS
    +.Pq Event 24H , Umask 08H
    +Counts the number of store RFO requests that miss the L2 cache. L2 RFO
    +requests include both L1D demand RFO misses as well as L1D RFO prefetches.
    +.It Li L2_RQSTS.RFOS
    +.Pq Event 24H , Umask 0CH
    +Counts all L2 store RFO requests. L2 RFO requests include both L1D demand
    +RFO misses as well as L1D RFO prefetches.
    +.It Li L2_RQSTS.IFETCH_HIT
    +.Pq Event 24H , Umask 10H
    +Counts number of instruction fetches that hit the L2 cache. L2 instruction
    +fetches include both L1I demand misses as well as L1I instruction
    +prefetches.
    +.It Li L2_RQSTS.IFETCH_MISS
    +.Pq Event 24H , Umask 20H
    +Counts number of instruction fetches that miss the L2 cache. L2 instruction
    +fetches include both L1I demand misses as well as L1I instruction
    +prefetches.
    +.It Li L2_RQSTS.IFETCHES
    +.Pq Event 24H , Umask 30H
    +Counts all instruction fetches. L2 instruction fetches include both L1I
    +demand misses as well as L1I instruction prefetches.
    +.It Li L2_RQSTS.PREFETCH_HIT
    +.Pq Event 24H , Umask 40H
    +Counts L2 prefetch hits for both code and data.
    +.It Li L2_RQSTS.PREFETCH_MISS
    +.Pq Event 24H , Umask 80H
    +Counts L2 prefetch misses for both code and data.
    +.It Li L2_RQSTS.PREFETCHES
    +.Pq Event 24H , Umask C0H
    +Counts all L2 prefetches for both code and data.
    +.It Li L2_RQSTS.MISS
    +.Pq Event 24H , Umask AAH
    +Counts all L2 misses for both code and data.
    +.It Li L2_RQSTS.REFERENCES
    +.Pq Event 24H , Umask FFH
    +Counts all L2 requests for both code and data.
    +.It Li L2_DATA_RQSTS.DEMAND.I_STATE
    +.Pq Event 26H , Umask 01H
    +Counts number of L2 data demand loads where the cache line to be loaded is
    +in the I (invalid) state, i.e. a cache miss. L2 demand loads are both L1D
    +demand misses and L1D prefetches.
    +.It Li L2_DATA_RQSTS.DEMAND.S_STATE
    +.Pq Event 26H , Umask 02H
    +Counts number of L2 data demand loads where the cache line to be loaded is
    +in the S (shared) state. L2 demand loads are both L1D demand misses and L1D
    +prefetches.
    +.It Li L2_DATA_RQSTS.DEMAND.E_STATE
    +.Pq Event 26H , Umask 04H
    +Counts number of L2 data demand loads where the cache line to be loaded is
    +in the E (exclusive) state. L2 demand loads are both L1D demand misses and
    +L1D prefetches.
    +.It Li L2_DATA_RQSTS.DEMAND.M_STATE
    +.Pq Event 26H , Umask 08H
    +Counts number of L2 data demand loads where the cache line to be loaded is
    +in the M (modified) state. L2 demand loads are both L1D demand misses and
    +L1D prefetches.
    +.It Li L2_DATA_RQSTS.DEMAND.MESI
    +.Pq Event 26H , Umask 0FH
    +Counts all L2 data demand requests. L2 demand loads are both L1D demand
    +misses and L1D prefetches.
    +.It Li L2_DATA_RQSTS.PREFETCH.I_STATE
    +.Pq Event 26H , Umask 10H
    +Counts number of L2 prefetch data loads where the cache line to be loaded is
    +in the I (invalid) state, i.e. a cache miss.
    +.It Li L2_DATA_RQSTS.PREFETCH.S_STATE
    +.Pq Event 26H , Umask 20H
    +Counts number of L2 prefetch data loads where the cache line to be loaded is
    +in the S (shared) state. A prefetch RFO will miss on an S state line, while
    +a prefetch read will hit on an S state line.
    +.It Li L2_DATA_RQSTS.PREFETCH.E_STATE
    +.Pq Event 26H , Umask 40H
    +Counts number of L2 prefetch data loads where the cache line to be loaded is
    +in the E (exclusive) state.
    +.It Li L2_DATA_RQSTS.PREFETCH.M_STATE
    +.Pq Event 26H , Umask 80H
    +Counts number of L2 prefetch data loads where the cache line to be loaded is
    +in the M (modified) state.
    +.It Li L2_DATA_RQSTS.PREFETCH.MESI
    +.Pq Event 26H , Umask F0H
    +Counts all L2 prefetch requests.
    +.It Li L2_DATA_RQSTS.ANY
    +.Pq Event 26H , Umask FFH
    +Counts all L2 data requests.
    +.It Li L2_WRITE.RFO.I_STATE
    +.Pq Event 27H , Umask 01H
    +Counts number of L2 demand store RFO requests where the cache line to be
    +loaded is in the I (invalid) state, i.e, a cache miss. The L1D prefetcher
    +does not issue a RFO prefetch.
    +This is a demand RFO request
    +.It Li L2_WRITE.RFO.S_STATE
    +.Pq Event 27H , Umask 02H
    +Counts number of L2 store RFO requests where the cache line to be loaded is
    +in the S (shared) state. The L1D prefetcher does not issue a RFO prefetch,.
    +This is a demand RFO request
    +.It Li L2_WRITE.RFO.M_STATE
    +.Pq Event 27H , Umask 08H
    +Counts number of L2 store RFO requests where the cache line to be loaded is
    +in the M (modified) state. The L1D prefetcher does not issue a RFO prefetch.
    +This is a demand RFO request
    +.It Li L2_WRITE.RFO.HIT
    +.Pq Event 27H , Umask 0EH
    +Counts number of L2 store RFO requests where the cache line to be loaded is
    +in either the S, E or M states. The L1D prefetcher does not issue a RFO
    +prefetch.
    +This is a demand RFO request
    +.It Li L2_WRITE.RFO.MESI
    +.Pq Event 27H , Umask 0FH
    +Counts all L2 store RFO requests.The L1D prefetcher does not issue a RFO
    +prefetch.
    +This is a demand RFO request
    +.It Li L2_WRITE.LOCK.I_STATE
    +.Pq Event 27H , Umask 10H
    +Counts number of L2 demand lock RFO requests where the cache line to be
    +loaded is in the I (invalid) state, i.e. a cache miss.
    +.It Li L2_WRITE.LOCK.S_STATE
    +.Pq Event 27H , Umask 20H
    +Counts number of L2 lock RFO requests where the cache line to be loaded is
    +in the S (shared) state.
    +.It Li L2_WRITE.LOCK.E_STATE
    +.Pq Event 27H , Umask 40H
    +Counts number of L2 demand lock RFO requests where the cache line to be
    +loaded is in the E (exclusive) state.
    +.It Li L2_WRITE.LOCK.M_STATE
    +.Pq Event 27H , Umask 80H
    +Counts number of L2 demand lock RFO requests where the cache line to be
    +loaded is in the M (modified) state.
    +.It Li L2_WRITE.LOCK.HIT
    +.Pq Event 27H , Umask E0H
    +Counts number of L2 demand lock RFO requests where the cache line to be
    +loaded is in either the S, E, or M state.
    +.It Li L2_WRITE.LOCK.MESI
    +.Pq Event 27H , Umask F0H
    +Counts all L2 demand lock RFO requests.
    +.It Li L1D_WB_L2.I_STATE
    +.Pq Event 28H , Umask 01H
    +Counts number of L1 writebacks to the L2 where the cache line to be written
    +is in the I (invalid) state, i.e. a cache miss.
    +.It Li L1D_WB_L2.S_STATE
    +.Pq Event 28H , Umask 02H
    +Counts number of L1 writebacks to the L2 where the cache line to be written
    +is in the S state.
    +.It Li L1D_WB_L2.E_STATE
    +.Pq Event 28H , Umask 04H
    +Counts number of L1 writebacks to the L2 where the cache line to be written
    +is in the E (exclusive) state.
    +.It Li L1D_WB_L2.M_STATE
    +.Pq Event 28H , Umask 08H
    +Counts number of L1 writebacks to the L2 where the cache line to be written
    +is in the M (modified) state.
    +.It Li L1D_WB_L2.MESI
    +.Pq Event 28H , Umask 0FH
    +Counts all L1 writebacks to the L2.
    +.It Li L3_LAT_CACHE.REFERENCE
    +.Pq Event 2EH , Umask 4FH
    +This event counts requests originating from the core that reference a cache
    +line in the last level cache. The event count includes speculative traffic
    +but excludes cache line fills due to a L2 hardware-prefetch. Because cache
    +hierarchy, cache sizes and other implementation-specific characteristics;
    +value comparison to estimate performance differences is not recommended.
    +see Table A-1
    +.It Li L3_LAT_CACHE.MISS
    +.Pq Event 2EH , Umask 41H
    +This event counts each cache miss condition for references to the last level
    +cache. The event count may include speculative traffic but excludes cache
    +line fills due to L2 hardware-prefetches. Because cache hierarchy, cache
    +sizes and other implementation-specific characteristics; value comparison to
    +estimate performance differences is not recommended.
    +see Table A-1
    +.It Li CPU_CLK_UNHALTED.THREAD_P
    +.Pq Event 3CH , Umask 00H
    +Counts the number of thread cycles while the thread is not in a halt state.
    +The thread enters the halt state when it is running the HLT instruction. The
    +core frequency may change from time to time due to power or thermal
    +throttling.
    +see Table A-1
    +.It Li CPU_CLK_UNHALTED.REF_P
    +.Pq Event 3CH , Umask 01H
    +Increments at the frequency of TSC when not halted.
    +see Table A-1
    +.It Li L1D_CACHE_LD.I_STATE
    +.Pq Event 40H , Umask 01H
    +Counts L1 data cache read requests where the cache line to be loaded is in
    +the I (invalid) state, i.e. the read request missed the cache.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_LD.S_STATE
    +.Pq Event 40H , Umask 02H
    +Counts L1 data cache read requests where the cache line to be loaded is in
    +the S (shared) state.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_LD.E_STATE
    +.Pq Event 40H , Umask 04H
    +Counts L1 data cache read requests where the cache line to be loaded is in
    +the E (exclusive) state.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_LD.M_STATE
    +.Pq Event 40H , Umask 08H
    +Counts L1 data cache read requests where the cache line to be loaded is in
    +the M (modified) state.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_LD.MESI
    +.Pq Event 40H , Umask 0FH
    +Counts L1 data cache read requests.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_ST.S_STATE
    +.Pq Event 41H , Umask 02H
    +Counts L1 data cache store RFO requests where the cache line to be loaded is
    +in the S (shared) state.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_ST.E_STATE
    +.Pq Event 41H , Umask 04H
    +Counts L1 data cache store RFO requests where the cache line to be loaded is
    +in the E (exclusive) state.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_ST.M_STATE
    +.Pq Event 41H , Umask 08H
    +Counts L1 data cache store RFO requests where cache line to be loaded is in
    +the M (modified) state.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_LOCK.HIT
    +.Pq Event 42H , Umask 01H
    +Counts retired load locks that hit in the L1 data cache or hit in an already
    +allocated fill buffer.	The lock portion of the load lock transaction must
    +hit in the L1D.
    +The initial load will pull the lock into the L1 data cache. Counter 0, 1
    +only
    +.It Li L1D_CACHE_LOCK.S_STATE
    +.Pq Event 42H , Umask 02H
    +Counts L1 data cache retired load locks that hit the target cache line in
    +the shared state.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_LOCK.E_STATE
    +.Pq Event 42H , Umask 04H
    +Counts L1 data cache retired load locks that hit the target cache line in
    +the exclusive state.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_LOCK.M_STATE
    +.Pq Event 42H , Umask 08H
    +Counts L1 data cache retired load locks that hit the target cache line in
    +the modified state.
    +Counter 0, 1 only
    +.It Li L1D_ALL_REF.ANY
    +.Pq Event 43H , Umask 01H
    +Counts all references (uncached, speculated and retired) to the L1 data
    +cache, including all loads and stores with any memory types. The event
    +counts memory accesses only when they are actually performed. For example, a
    +load blocked by unknown store address and later performed is only counted
    +once.
    +The event does not include non- memory accesses, such as I/O accesses.
    +Counter 0, 1 only
    +.It Li L1D_ALL_REF.CACHEABLE
    +.Pq Event 43H , Umask 02H
    +Counts all data reads and writes (speculated and retired) from cacheable
    +memory, including locked operations.
    +Counter 0, 1 only
    +.It Li L1D_PEND_MISS.LOAD_BUFFERS_FULL
    +.Pq Event 48H , Umask 02H
    +Counts cycles of L1 data cache load fill buffers full.
    +Counter 0, 1 only
    +.It Li DTLB_MISSES.ANY
    +.Pq Event 49H , Umask 01H
    +Counts the number of misses in the STLB which causes a page walk.
    +.It Li DTLB_MISSES.WALK_COMPLETED
    +.Pq Event 49H , Umask 02H
    +Counts number of misses in the STLB which resulted in a completed page walk.
    +.It Li DTLB_MISSES.STLB_HIT
    +.Pq Event 49H , Umask 10H
    +Counts the number of DTLB first level misses that hit in the second level
    +TLB. This event is only relevant if the core contains multiple DTLB levels.
    +.It Li LOAD_HIT_PRE
    +.Pq Event 4CH , Umask 01H
    +Counts load operations sent to the L1 data cache while a previous SSE
    +prefetch instruction to the same cache line has started prefetching but has
    +not yet finished.
    +.It Li L1D_PREFETCH.REQUESTS
    +.Pq Event 4EH , Umask 01H
    +Counts number of hardware prefetch requests dispatched out of the prefetch
    +FIFO.
    +.It Li L1D_PREFETCH.MISS
    +.Pq Event 4EH , Umask 02H
    +Counts number of hardware prefetch requests that miss the L1D. There are two
    +prefetchers in the L1D. A streamer, which predicts lines sequentially after
    +this one should be fetched, and the IP prefetcher that remembers access
    +patterns for the current instruction. The streamer prefetcher stops on an
    +L1D hit, while the IP prefetcher does not.
    +.It Li L1D_PREFETCH.TRIGGERS
    +.Pq Event 4EH , Umask 04H
    +Counts number of prefetch requests triggered by the Finite State Machine and
    +pushed into the prefetch FIFO. Some of the prefetch requests are dropped due
    +to overwrites or competition between the IP index prefetcher and streamer
    +prefetcher. The prefetch FIFO contains 4 entries.
    +.It Li L1D.REPL
    +.Pq Event 51H , Umask 01H
    +Counts the number of lines brought into the L1 data cache.
    +Counter 0, 1 only
    +.It Li L1D.M_REPL
    +.Pq Event 51H , Umask 02H
    +Counts the number of modified lines brought into the L1 data cache.
    +Counter 0, 1 only
    +.It Li L1D.M_EVICT
    +.Pq Event 51H , Umask 04H
    +Counts the number of modified lines evicted from the L1 data cache due to
    +replacement.
    +Counter 0, 1 only
    +.It Li L1D.M_SNOOP_EVICT
    +.Pq Event 51H , Umask 08H
    +Counts the number of modified lines evicted from the L1 data cache due to
    +snoop HITM intervention.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_PREFETCH_LOCK_FB_HIT
    +.Pq Event 52H , Umask 01H
    +Counts the number of cacheable load lock speculated instructions accepted
    +into the fill buffer.
    +.It Li L1D_CACHE_LOCK_FB_HIT
    +.Pq Event 53H , Umask 01H
    +Counts the number of cacheable load lock speculated or retired instructions
    +accepted into the fill buffer.
    +.It Li CACHE_LOCK_CYCLES.L1D_L2
    +.Pq Event 63H , Umask 01H
    +Cycle count during which the L1D and L2 are locked. A lock is asserted when
    +there is a locked memory access, due to uncacheable memory, a locked
    +operation that spans two cache lines, or a page walk from an uncacheable
    +page table.
    +Counter 0, 1 only. L1D and L2 locks have a very high performance penalty and
    +it is highly recommended to avoid such accesses.
    +.It Li CACHE_LOCK_CYCLES.L1D
    +.Pq Event 63H , Umask 02H
    +Counts the number of cycles that cacheline in the L1 data cache unit is
    +locked.
    +Counter 0, 1 only.
    +.It Li IO_TRANSACTIONS
    +.Pq Event 6CH , Umask 01H
    +Counts the number of completed I/O transactions.
    +.It Li L1I.HITS
    +.Pq Event 80H , Umask 01H
    +Counts all instruction fetches that hit the L1 instruction cache.
    +.It Li L1I.MISSES
    +.Pq Event 80H , Umask 02H
    +Counts all instruction fetches that miss the L1I cache. This includes
    +instruction cache misses, streaming buffer misses, victim cache misses and
    +uncacheable fetches. An instruction fetch miss is counted only once and not
    +once for every cycle it is outstanding.
    +.It Li L1I.READS
    +.Pq Event 80H , Umask 03H
    +Counts all instruction fetches, including uncacheable fetches that bypass
    +the L1I.
    +.It Li L1I.CYCLES_STALLED
    +.Pq Event 80H , Umask 04H
    +Cycle counts for which an instruction fetch stalls due to a L1I cache miss,
    +ITLB miss or ITLB fault.
    +.It Li LARGE_ITLB.HIT
    +.Pq Event 82H , Umask 01H
    +Counts number of large ITLB hits.
    +.It Li ITLB_MISSES.ANY
    +.Pq Event 85H , Umask 01H
    +Counts the number of misses in all levels of the ITLB which causes a page
    +walk.
    +.It Li ITLB_MISSES.WALK_COMPLETED
    +.Pq Event 85H , Umask 02H
    +Counts number of misses in all levels of the ITLB which resulted in a
    +completed page walk.
    +.It Li ILD_STALL.LCP
    +.Pq Event 87H , Umask 01H
    +Cycles Instruction Length Decoder stalls due to length changing prefixes:
    +66, 67 or REX.W (for EM64T) instructions which change the length of the
    +decoded instruction.
    +.It Li ILD_STALL.MRU
    +.Pq Event 87H , Umask 02H
    +Instruction Length Decoder stall cycles due to Brand Prediction Unit (PBU)
    +Most Recently Used (MRU) bypass.
    +.It Li ILD_STALL.IQ_FULL
    +.Pq Event 87H , Umask 04H
    +Stall cycles due to a full instruction queue.
    +.It Li ILD_STALL.REGEN
    +.Pq Event 87H , Umask 08H
    +Counts the number of regen stalls.
    +.It Li ILD_STALL.ANY
    +.Pq Event 87H , Umask 0FH
    +Counts any cycles the Instruction Length Decoder is stalled.
    +.It Li BR_INST_EXEC.COND
    +.Pq Event 88H , Umask 01H
    +Counts the number of conditional near branch instructions executed, but not
    +necessarily retired.
    +.It Li BR_INST_EXEC.DIRECT
    +.Pq Event 88H , Umask 02H
    +Counts all unconditional near branch instructions excluding calls and
    +indirect branches.
    +.It Li BR_INST_EXEC.INDIRECT_NON_CALL
    +.Pq Event 88H , Umask 04H
    +Counts the number of executed indirect near branch instructions that are not
    +calls.
    +.It Li BR_INST_EXEC.NON_CALLS
    +.Pq Event 88H , Umask 07H
    +Counts all non call near branch instructions executed, but not necessarily
    +retired.
    +.It Li BR_INST_EXEC.RETURN_NEAR
    +.Pq Event 88H , Umask 08H
    +Counts indirect near branches that have a return mnemonic.
    +.It Li BR_INST_EXEC.DIRECT_NEAR_CALL
    +.Pq Event 88H , Umask 10H
    +Counts unconditional near call branch instructions, excluding non call
    +branch, executed.
    +.It Li BR_INST_EXEC.INDIRECT_NEAR_CALL
    +.Pq Event 88H , Umask 20H
    +Counts indirect near calls, including both register and memory indirect,
    +executed.
    +.It Li BR_INST_EXEC.NEAR_CALLS
    +.Pq Event 88H , Umask 30H
    +Counts all near call branches executed, but not necessarily retired.
    +.It Li BR_INST_EXEC.TAKEN
    +.Pq Event 88H , Umask 40H
    +Counts taken near branches executed, but not necessarily retired.
    +.It Li BR_INST_EXEC.ANY
    +.Pq Event 88H , Umask 7FH
    +Counts all near executed branches (not necessarily retired). This includes
    +only instructions and not micro-op branches. Frequent branching is not
    +necessarily a major performance issue. However frequent branch
    +mispredictions may be a problem.
    +.It Li BR_MISP_EXEC.COND
    +.Pq Event 89H , Umask 01H
    +Counts the number of mispredicted conditional near branch instructions
    +executed, but not necessarily retired.
    +.It Li BR_MISP_EXEC.DIRECT
    +.Pq Event 89H , Umask 02H
    +Counts mispredicted macro unconditional near branch instructions, excluding
    +calls and indirect branches (should always be 0).
    +.It Li BR_MISP_EXEC.INDIRECT_NON_CALL
    +.Pq Event 89H , Umask 04H
    +Counts the number of executed mispredicted indirect near branch instructions
    +that are not calls.
    +.It Li BR_MISP_EXEC.NON_CALLS
    +.Pq Event 89H , Umask 07H
    +Counts mispredicted non call near branches executed, but not necessarily
    +retired.
    +.It Li BR_MISP_EXEC.RETURN_NEAR
    +.Pq Event 89H , Umask 08H
    +Counts mispredicted indirect branches that have a rear return mnemonic.
    +.It Li BR_MISP_EXEC.DIRECT_NEAR_CALL
    +.Pq Event 89H , Umask 10H
    +Counts mispredicted non-indirect near calls executed, (should always be 0).
    +.It Li BR_MISP_EXEC.INDIRECT_NEAR_CALL
    +.Pq Event 89H , Umask 20H
    +Counts mispredicted indirect near calls exeucted, including both register
    +and memory indirect.
    +.It Li BR_MISP_EXEC.NEAR_CALLS
    +.Pq Event 89H , Umask 30H
    +Counts all mispredicted near call branches executed, but not necessarily
    +retired.
    +.It Li BR_MISP_EXEC.TAKEN
    +.Pq Event 89H , Umask 40H
    +Counts executed mispredicted near branches that are taken, but not
    +necessarily retired.
    +.It Li BR_MISP_EXEC.ANY
    +.Pq Event 89H , Umask 7FH
    +Counts the number of mispredicted near branch instructions that were
    +executed, but not necessarily retired.
    +.It Li RESOURCE_STALLS.ANY
    +.Pq Event A2H , Umask 01H
    +Counts the number of Allocator resource related stalls. Includes register
    +renaming buffer entries, memory buffer entries. In addition to resource
    +related stalls, this event counts some other events. Includes stalls arising
    +during branch misprediction recovery, such as if retirement of the
    +mispredicted branch is delayed and stalls arising while store buffer is
    +draining from synchronizing operations.
    +Does not include stalls due to SuperQ (off core) queue full, too many cache
    +misses, etc.
    +.It Li RESOURCE_STALLS.LOAD
    +.Pq Event A2H , Umask 02H
    +Counts the cycles of stall due to lack of load buffer for load operation.
    +.It Li RESOURCE_STALLS.RS_FULL
    +.Pq Event A2H , Umask 04H
    +This event counts the number of cycles when the number of instructions in
    +the pipeline waiting for execution reaches the limit the processor can
    +handle. A high count of this event indicates that there are long latency
    +operations in the pipe (possibly load and store operations that miss the L2
    +cache, or instructions dependent upon instructions further down the pipeline
    +that have yet to retire.
    +When RS is full, new instructions can not enter the reservation station and
    +start execution.
    +.It Li RESOURCE_STALLS.STORE
    +.Pq Event A2H , Umask 08H
    +This event counts the number of cycles that a resource related stall will
    +occur due to the number of store instructions reaching the limit of the
    +pipeline, (i.e. all store buffers are used). The stall ends when a store
    +instruction commits its data to the cache or memory.
    +.It Li RESOURCE_STALLS.ROB_FULL
    +.Pq Event A2H , Umask 10H
    +Counts the cycles of stall due to re- order buffer full.
    +.It Li RESOURCE_STALLS.FPCW
    +.Pq Event A2H , Umask 20H
    +Counts the number of cycles while execution was stalled due to writing the
    +floating-point unit (FPU) control word.
    +.It Li RESOURCE_STALLS.MXCSR
    +.Pq Event A2H , Umask 40H
    +Stalls due to the MXCSR register rename occurring to close to a previous
    +MXCSR rename. The MXCSR provides control and status for the MMX registers.
    +.It Li RESOURCE_STALLS.OTHER
    +.Pq Event A2H , Umask 80H
    +Counts the number of cycles while execution was stalled due to other
    +resource issues.
    +.It Li MACRO_INSTS.FUSIONS_DECODED
    +.Pq Event A6H , Umask 01H
    +Counts the number of instructions decoded that are macro-fused but not
    +necessarily executed or retired.
    +.It Li BACLEAR_FORCE_IQ
    +.Pq Event A7H , Umask 01H
    +Counts number of times a BACLEAR was forced by the Instruction Queue. The IQ
    +is also responsible for providing conditional branch prediciton direction
    +based on a static scheme and dynamic data provided by the L2 Branch
    +Prediction Unit. If the conditional branch target is not found in the Target
    +Array and the IQ predicts that the branch is taken, then the IQ will force
    +the Branch Address Calculator to issue a BACLEAR. Each BACLEAR asserted by
    +the BAC generates approximately an 8 cycle bubble in the instruction fetch
    +pipeline.
    +.It Li LSD.UOPS
    +.Pq Event A8H , Umask 01H
    +Counts the number of micro-ops delivered by loop stream detector
    +Use cmask=1 and invert to count cycles
    +.It Li ITLB_FLUSH
    +.Pq Event AEH , Umask 01H
    +Counts the number of ITLB flushes
    +.It Li OFFCORE_REQUESTS.L1D_WRITEBACK
    +.Pq Event B0H , Umask 40H
    +Counts number of L1D writebacks to the uncore.
    +.It Li UOPS_EXECUTED.PORT0
    +.Pq Event B1H , Umask 01H
    +Counts number of Uops executed that were issued on port 0. Port 0 handles
    +integer arithmetic, SIMD and FP add Uops.
    +.It Li UOPS_EXECUTED.PORT1
    +.Pq Event B1H , Umask 02H
    +Counts number of Uops executed that were issued on port 1. Port 1 handles
    +integer arithmetic, SIMD, integer shift, FP multiply and FP divide Uops.
    +.It Li UOPS_EXECUTED.PORT2_CORE
    +.Pq Event B1H , Umask 04H
    +Counts number of Uops executed that were issued on port 2. Port 2 handles
    +the load Uops. This is a core count only and can not be collected per
    +thread.
    +.It Li UOPS_EXECUTED.PORT3_CORE
    +.Pq Event B1H , Umask 08H
    +Counts number of Uops executed that were issued on port 3. Port 3 handles
    +store Uops. This is a core count only and can not be collected per thread.
    +.It Li UOPS_EXECUTED.PORT4_CORE
    +.Pq Event B1H , Umask 10H
    +Counts number of Uops executed that where issued on port 4. Port 4 handles
    +the value to be stored for the store Uops issued on port 3. This is a core
    +count only and can not be collected per thread.
    +.It Li UOPS_EXECUTED.CORE_ACTIVE_CYCLES_NO_PORT5
    +.Pq Event B1H , Umask 1FH
    +Counts cycles when the Uops executed were issued from any ports except port
    +5. Use Cmask=1 for active cycles; Cmask=0 for weighted cycles; Use CMask=1,
    +Invert=1 to count P0-4 stalled cycles Use Cmask=1, Edge=1, Invert=1 to count
    +P0-4 stalls.
    +.It Li UOPS_EXECUTED.PORT5
    +.Pq Event B1H , Umask 20H
    +Counts number of Uops executed that where issued on port 5.
    +.It Li UOPS_EXECUTED.CORE_ACTIVE_CYCLES
    +.Pq Event B1H , Umask 3FH
    +Counts cycles when the Uops are executing. Use Cmask=1 for active cycles;
    +Cmask=0 for weighted cycles; Use CMask=1, Invert=1 to count P0-4 stalled
    +cycles Use Cmask=1, Edge=1, Invert=1 to count P0-4 stalls.
    +.It Li UOPS_EXECUTED.PORT015
    +.Pq Event B1H , Umask 40H
    +Counts number of Uops executed that where issued on port 0, 1, or 5.
    +use cmask=1, invert=1 to count stall cycles
    +.It Li UOPS_EXECUTED.PORT234
    +.Pq Event B1H , Umask 80H
    +Counts number of Uops executed that where issued on port 2, 3, or 4.
    +.It Li OFFCORE_REQUESTS_SQ_FULL
    +.Pq Event B2H , Umask 01H
    +Counts number of cycles the SQ is full to handle off-core requests.
    +.It Li OFF_CORE_RESPONSE_0
    +.Pq Event B7H , Umask 01H
    +see Section 30.6.1.3, Off-core Response Performance Monitoring in the
    +Processor Core
    +Requires programming MSR 01A6H
    +.It Li SNOOP_RESPONSE.HIT
    +.Pq Event B8H , Umask 01H
    +Counts HIT snoop response sent by this thread in response to a snoop
    +request.
    +.It Li SNOOP_RESPONSE.HITE
    +.Pq Event B8H , Umask 02H
    +Counts HIT E snoop response sent by this thread in response to a snoop
    +request.
    +.It Li SNOOP_RESPONSE.HITM
    +.Pq Event B8H , Umask 04H
    +Counts HIT M snoop response sent by this thread in response to a snoop
    +request.
    +.It Li OFF_CORE_RESPONSE_1
    +.Pq Event BBH , Umask 01H
    +see Section 30.6.1.3, Off-core Response Performance Monitoring in the
    +Processor Core
    +Requires programming MSR 01A7H
    +.It Li INST_RETIRED.ANY_P
    +.Pq Event C0H , Umask 01H
    +See Table A-1
    +Notes: INST_RETIRED.ANY is counted by a designated fixed counter.
    +INST_RETIRED.ANY_P is counted by a programmable counter and is an
    +architectural performance event. Event is supported if CPUID.A.EBX[1] = 0.
    +Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not
    +count as retired instructions.
    +.It Li INST_RETIRED.X87
    +.Pq Event C0H , Umask 02H
    +Counts the number of MMX instructions retired:.
    +.It Li INST_RETIRED.MMX
    +.Pq Event C0H , Umask 04H
    +Counts the number of floating point computational operations retired:
    +floating point computational operations executed by the assist handler and
    +sub-operations of complex floating point instructions like transcendental
    +instructions.
    +.It Li UOPS_RETIRED.ANY
    +.Pq Event C2H , Umask 01H
    +Counts the number of micro-ops retired, (macro-fused=1, micro- fused=2,
    +others=1; maximum count of 8 per cycle). Most instructions are composed of
    +one or two micro-ops. Some instructions are decoded into longer sequences
    +such as repeat instructions, floating point transcendental instructions, and
    +assists.
    +Use cmask=1 and invert to count active cycles or stalled cycles
    +.It Li UOPS_RETIRED.RETIRE_SLOTS
    +.Pq Event C2H , Umask 02H
    +Counts the number of retirement slots used each cycle
    +.It Li UOPS_RETIRED.MACRO_FUSED
    +.Pq Event C2H , Umask 04H
    +Counts number of macro-fused uops retired.
    +.It Li MACHINE_CLEARS.CYCLES
    +.Pq Event C3H , Umask 01H
    +Counts the cycles machine clear is asserted.
    +.It Li MACHINE_CLEARS.MEM_ORDER
    +.Pq Event C3H , Umask 02H
    +Counts the number of machine clears due to memory order conflicts.
    +.It Li MACHINE_CLEARS.SMC
    +.Pq Event C3H , Umask 04H
    +Counts the number of times that a program writes to a code section.
    +Self-modifying code causes a sever penalty in all Intel 64 and IA-32
    +processors. The modified cache line is written back to the L2 and L3caches.
    +.It Li BR_INST_RETIRED.ALL_BRANCHES
    +.Pq Event C4H , Umask 00H
    +See Table A-1
    +.It Li BR_INST_RETIRED.CONDITIONAL
    +.Pq Event C4H , Umask 01H
    +Counts the number of conditional branch instructions retired.
    +.It Li BR_INST_RETIRED.NEAR_CALL
    +.Pq Event C4H , Umask 02H
    +Counts the number of direct & indirect near unconditional calls retired
    +.It Li BR_INST_RETIRED.ALL_BRANCHES
    +.Pq Event C4H , Umask 04H
    +Counts the number of branch instructions retired
    +.It Li BR_MISP_RETIRED.ALL_BRANCHES
    +.Pq Event C5H , Umask 00H
    +See Table A-1
    +.It Li BR_MISP_RETIRED.NEAR_CALL
    +.Pq Event C5H , Umask 02H
    +Counts mispredicted direct & indirect near unconditional retired calls.
    +.It Li SSEX_UOPS_RETIRED.PACKED_SINGLE
    +.Pq Event C7H , Umask 01H
    +Counts SIMD packed single-precision floating point Uops retired.
    +.It Li SSEX_UOPS_RETIRED.SCALAR_SINGLE
    +.Pq Event C7H , Umask 02H
    +Counts SIMD calar single-precision floating point Uops retired.
    +.It Li SSEX_UOPS_RETIRED.PACKED_DOUBLE
    +.Pq Event C7H , Umask 04H
    +Counts SIMD packed double- precision floating point Uops retired.
    +.It Li SSEX_UOPS_RETIRED.SCALAR_DOUBLE
    +.Pq Event C7H , Umask 08H
    +Counts SIMD scalar double-precision floating point Uops retired.
    +.It Li SSEX_UOPS_RETIRED.VECTOR_INTEGER
    +.Pq Event C7H , Umask 10H
    +Counts 128-bit SIMD vector integer Uops retired.
    +.It Li ITLB_MISS_RETIRED
    +.Pq Event C8H , Umask 20H
    +Counts the number of retired instructions that missed the ITLB when the
    +instruction was fetched.
    +.It Li MEM_LOAD_RETIRED.L1D_HIT
    +.Pq Event CBH , Umask 01H
    +Counts number of retired loads that hit the L1 data cache.
    +.It Li MEM_LOAD_RETIRED.L2_HIT
    +.Pq Event CBH , Umask 02H
    +Counts number of retired loads that hit the L2 data cache.
    +.It Li MEM_LOAD_RETIRED.L3_UNSHARED_HIT
    +.Pq Event CBH , Umask 04H
    +Counts number of retired loads that hit their own, unshared lines in the L3
    +cache.
    +.It Li MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM
    +.Pq Event CBH , Umask 08H
    +Counts number of retired loads that hit in a sibling core's L2 (on die
    +core). Since the L3 is inclusive of all cores on the package, this is an L3
    +hit. This counts both clean or modified hits.
    +.It Li MEM_LOAD_RETIRED.L3_MISS
    +.Pq Event CBH , Umask 10H
    +Counts number of retired loads that miss the L3 cache. The load was
    +satisfied by a remote socket, local memory or an IOH.
    +.It Li MEM_LOAD_RETIRED.HIT_LFB
    +.Pq Event CBH , Umask 40H
    +Counts number of retired loads that miss the L1D and the address is located
    +in an allocated line fill buffer and will soon be committed to cache. This
    +is counting secondary L1D misses.
    +.It Li MEM_LOAD_RETIRED.DTLB_MISS
    +.Pq Event CBH , Umask 80H
    +Counts the number of retired loads that missed the DTLB. The DTLB miss is
    +not counted if the load operation causes a fault. This event counts loads
    +from cacheable memory only. The event does not count loads by software
    +prefetches. Counts both primary and secondary misses to the TLB.
    +.It Li FP_MMX_TRANS.TO_FP
    +.Pq Event CCH , Umask 01H
    +Counts the first floating-point instruction following any MMX instruction.
    +You can use this event to estimate the penalties for the transitions between
    +floating-point and MMX technology states.
    +.It Li FP_MMX_TRANS.TO_MMX
    +.Pq Event CCH , Umask 02H
    +Counts the first MMX instruction following a floating-point instruction. You
    +can use this event to estimate the penalties for the transitions between
    +floating-point and MMX technology states.
    +.It Li FP_MMX_TRANS.ANY
    +.Pq Event CCH , Umask 03H
    +Counts all transitions from floating point to MMX instructions and from MMX
    +instructions to floating point instructions. You can use this event to
    +estimate the penalties for the transitions between floating-point and MMX
    +technology states.
    +.It Li MACRO_INSTS.DECODED
    +.Pq Event D0H , Umask 01H
    +Counts the number of instructions decoded, (but not necessarily executed or
    +retired).
    +.It Li UOPS_DECODED.MS
    +.Pq Event D1H , Umask 02H
    +Counts the number of Uops decoded by the Microcode Sequencer, MS. The MS
    +delivers uops when the instruction is more than 4 uops long or a microcode
    +assist is occurring.
    +.It Li UOPS_DECODED.ESP_FOLDING
    +.Pq Event D1H , Umask 04H
    +Counts number of stack pointer (ESP) instructions decoded: push , pop , call
    +, ret, etc. ESP instructions do not generate a Uop to increment or decrement
    +ESP. Instead, they update an ESP_Offset register that keeps track of the
    +delta to the current value of the ESP register.
    +.It Li UOPS_DECODED.ESP_SYNC
    +.Pq Event D1H , Umask 08H
    +Counts number of stack pointer (ESP) sync operations where an ESP
    +instruction is corrected by adding the ESP offset register to the current
    +value of the ESP register.
    +.It Li RAT_STALLS.FLAGS
    +.Pq Event D2H , Umask 01H
    +Counts the number of cycles during which execution stalled due to several
    +reasons, one of which is a partial flag register stall. A partial register
    +stall may occur when two conditions are met: 1) an instruction modifies
    +some, but not all, of the flags in the flag register and 2) the next
    +instruction, which depends on flags, depends on flags that were not modified
    +by this instruction.
    +.It Li RAT_STALLS.REGISTERS
    +.Pq Event D2H , Umask 02H
    +This event counts the number of cycles instruction execution latency became
    +longer than the defined latency because the instruction used a register that
    +was partially written by previous instruction.
    +.It Li RAT_STALLS.ROB_READ_PORT
    +.Pq Event D2H , Umask 04H
    +Counts the number of cycles when ROB read port stalls occurred, which did
    +not allow new micro-ops to enter the out-of-order pipeline. Note that, at
    +this stage in the pipeline, additional stalls may occur at the same cycle
    +and prevent the stalled micro-ops from entering the pipe. In such a case,
    +micro-ops retry entering the execution pipe in the next cycle and the
    +ROB-read port stall is counted again.
    +.It Li RAT_STALLS.SCOREBOARD
    +.Pq Event D2H , Umask 08H
    +Counts the cycles where we stall due to microarchitecturally required
    +serialization. Microcode scoreboarding stalls.
    +.It Li RAT_STALLS.ANY
    +.Pq Event D2H , Umask 0FH
    +Counts all Register Allocation Table stall cycles due to: Cycles when ROB
    +read port stalls occurred, which did not allow new micro-ops to enter the
    +execution pipe. Cycles when partial register stalls occurred Cycles when
    +flag stalls occurred Cycles floating-point unit (FPU) status word stalls
    +occurred. To count each of these conditions separately use the events:
    +RAT_STALLS.ROB_READ_PORT, RAT_STALLS.PARTIAL, RAT_STALLS.FLAGS, and
    +RAT_STALLS.FPSW.
    +.It Li SEG_RENAME_STALLS
    +.Pq Event D4H , Umask 01H
    +Counts the number of stall cycles due to the lack of renaming resources for
    +the ES, DS, FS, and GS segment registers. If a segment is renamed but not
    +retired and a second update to the same segment occurs, a stall occurs in
    +the front-end of the pipeline until the renamed segment retires.
    +.It Li ES_REG_RENAMES
    +.Pq Event D5H , Umask 01H
    +Counts the number of times the ES segment register is renamed.
    +.It Li UOP_UNFUSION
    +.Pq Event DBH , Umask 01H
    +Counts unfusion events due to floating point exception to a fused uop.
    +.It Li BR_INST_DECODED
    +.Pq Event E0H , Umask 01H
    +Counts the number of branch instructions decoded.
    +.It Li BPU_MISSED_CALL_RET
    +.Pq Event E5H , Umask 01H
    +Counts number of times the Branch Prediciton Unit missed predicting a call
    +or return branch.
    +.It Li BACLEAR.CLEAR
    +.Pq Event E6H , Umask 01H
    +Counts the number of times the front end is resteered, mainly when the
    +Branch Prediction Unit cannot provide a correct prediction and this is
    +corrected by the Branch Address Calculator at the front end. This can occur
    +if the code has many branches such that they cannot be consumed by the BPU.
    +Each BACLEAR asserted by the BAC generates approximately an 8 cycle bubble
    +in the instruction fetch pipeline. The effect on total execution time
    +depends on the surrounding code.
    +.It Li BACLEAR.BAD_TARGET
    +.Pq Event E6H , Umask 02H
    +Counts number of Branch Address Calculator clears (BACLEAR) asserted due to
    +conditional branch instructions in which there was a target hit but the
    +direction was wrong. Each BACLEAR asserted by the BAC generates
    +approximately an 8 cycle bubble in the instruction fetch pipeline.
    +.It Li BPU_CLEARS.EARLY
    +.Pq Event E8H , Umask 01H
    +Counts early (normal) Branch Prediction Unit clears: BPU predicted a taken
    +branch after incorrectly assuming that it was not taken.
    +The BPU clear leads to 2 cycle bubble in the Front End.
    +.It Li BPU_CLEARS.LATE
    +.Pq Event E8H , Umask 02H
    +Counts late Branch Prediction Unit clears due to Most Recently Used
    +conflicts. The PBU clear leads to a 3 cycle bubble in the Front End.
    +.It Li BPU_CLEARS.ANY
    +.Pq Event E8H , Umask 03H
    +Counts all BPU clears.
    +.It Li L2_TRANSACTIONS.LOAD
    +.Pq Event F0H , Umask 01H
    +Counts L2 load operations due to HW prefetch or demand loads.
    +.It Li L2_TRANSACTIONS.RFO
    +.Pq Event F0H , Umask 02H
    +Counts L2 RFO operations due to HW prefetch or demand RFOs.
    +.It Li L2_TRANSACTIONS.IFETCH
    +.Pq Event F0H , Umask 04H
    +Counts L2 instruction fetch operations due to HW prefetch or demand ifetch.
    +.It Li L2_TRANSACTIONS.PREFETCH
    +.Pq Event F0H , Umask 08H
    +Counts L2 prefetch operations.
    +.It Li L2_TRANSACTIONS.L1D_WB
    +.Pq Event F0H , Umask 10H
    +Counts L1D writeback operations to the L2.
    +.It Li L2_TRANSACTIONS.FILL
    +.Pq Event F0H , Umask 20H
    +Counts L2 cache line fill operations due to load, RFO, L1D writeback or
    +prefetch.
    +.It Li L2_TRANSACTIONS.WB
    +.Pq Event F0H , Umask 40H
    +Counts L2 writeback operations to the L3.
    +.It Li L2_TRANSACTIONS.ANY
    +.Pq Event F0H , Umask 80H
    +Counts all L2 cache operations.
    +.It Li L2_LINES_IN.S_STATE
    +.Pq Event F1H , Umask 02H
    +Counts the number of cache lines allocated in the L2 cache in the S (shared)
    +state.
    +.It Li L2_LINES_IN.E_STATE
    +.Pq Event F1H , Umask 04H
    +Counts the number of cache lines allocated in the L2 cache in the E
    +(exclusive) state.
    +.It Li L2_LINES_IN.ANY
    +.Pq Event F1H , Umask 07H
    +Counts the number of cache lines allocated in the L2 cache.
    +.It Li L2_LINES_OUT.DEMAND_CLEAN
    +.Pq Event F2H , Umask 01H
    +Counts L2 clean cache lines evicted by a demand request.
    +.It Li L2_LINES_OUT.DEMAND_DIRTY
    +.Pq Event F2H , Umask 02H
    +Counts L2 dirty (modified) cache lines evicted by a demand request.
    +.It Li L2_LINES_OUT.PREFETCH_CLEAN
    +.Pq Event F2H , Umask 04H
    +Counts L2 clean cache line evicted by a prefetch request.
    +.It Li L2_LINES_OUT.PREFETCH_DIRTY
    +.Pq Event F2H , Umask 08H
    +Counts L2 modified cache line evicted by a prefetch request.
    +.It Li L2_LINES_OUT.ANY
    +.Pq Event F2H , Umask 0FH
    +Counts all L2 cache lines evicted for any reason.
    +.It Li SQ_MISC.SPLIT_LOCK
    +.Pq Event F4H , Umask 10H
    +Counts the number of SQ lock splits across a cache line.
    +.It Li SQ_FULL_STALL_CYCLES
    +.Pq Event F6H , Umask 01H
    +Counts cycles the Super Queue is full. Neither of the threads on this core
    +will be able to access the uncore.
    +.It Li FP_ASSIST.ALL
    +.Pq Event F7H , Umask 01H
    +Counts the number of floating point operations executed that required
    +micro-code assist intervention. Assists are required in the following cases:
    +SSE instructions, (Denormal input when the DAZ flag is off or Underflow
    +result when the FTZ flag is off): x87 instructions, (NaN or denormal are
    +loaded to a register or used as input from memory, Division by 0 or
    +Underflow output).
    +.It Li FP_ASSIST.OUTPUT
    +.Pq Event F7H , Umask 02H
    +Counts number of floating point micro-code assist when the output value
    +(destination register) is invalid.
    +.It Li FP_ASSIST.INPUT
    +.Pq Event F7H , Umask 04H
    +Counts number of floating point micro-code assist when the input value (one
    +of the source operands to an FP instruction) is invalid.
    +.It Li SIMD_INT_64.PACKED_MPY
    +.Pq Event FDH , Umask 01H
    +Counts number of SID integer 64 bit packed multiply operations.
    +.It Li SIMD_INT_64.PACKED_SHIFT
    +.Pq Event FDH , Umask 02H
    +Counts number of SID integer 64 bit packed shift operations.
    +.It Li SIMD_INT_64.PACK
    +.Pq Event FDH , Umask 04H
    +Counts number of SID integer 64 bit pack operations.
    +.It Li SIMD_INT_64.UNPACK
    +.Pq Event FDH , Umask 08H
    +Counts number of SID integer 64 bit unpack operations.
    +.It Li SIMD_INT_64.PACKED_LOGICAL
    +.Pq Event FDH , Umask 10H
    +Counts number of SID integer 64 bit logical operations.
    +.It Li SIMD_INT_64.PACKED_ARITH
    +.Pq Event FDH , Umask 20H
    +Counts number of SID integer 64 bit arithmetic operations.
    +.It Li SIMD_INT_64.SHUFFLE_MOVE
    +.Pq Event FDH , Umask 40H
    +Counts number of SID integer 64 bit shift or move operations.
    +.El
    +.Ss Event Specifiers (Programmable PMCs)
    +Core i7 and Xeon 5500 programmable PMCs support the following events as
    +June 2009 document (removed in December 2009):
    +.Bl -tag -width indent
    +.It Li SB_FORWARD.ANY
    +.Pq Event 02H , Umask 01H
    +Counts the number of store forwards.
    +.It Li LOAD_BLOCK.STD
    +.Pq Event 03H , Umask 01H
    +Counts the number of loads blocked by a preceding store with unknown data.
    +.It Li LOAD_BLOCK.ADDRESS_OFFSET
    +.Pq Event 03H , Umask 04H
    +Counts the number of loads blocked by a preceding store address.
    +.It Li LOAD_BLOCK.ADDRESS_OFFSET
    +.Pq Event 01H , Umask 04H
    +Counts the cycles of store buffer drains.
    +.It Li MISALIGN_MEM_REF.LOAD
    +.Pq Event 05H , Umask 01H
    +Counts the number of misaligned load references
    +.It Li MISALIGN_MEM_REF.STORE
    +.Pq Event 05H , Umask 02H
    +Counts the number of misaligned store references
    +.It Li MISALIGN_MEM_REF.ANY
    +.Pq Event 05H , Umask 03H
    +Counts the number of misaligned memory references
    +.It Li STORE_BLOCKS.NOT_STA
    +.Pq Event 06H , Umask 01H
    +This event counts the number of load operations delayed caused by preceding
    +stores whose addresses are known but whose data is unknown, and preceding
    +stores that conflict with the load but which incompletely overlap the load.
    +.It Li STORE_BLOCKS.STA
    +.Pq Event 06H , Umask 02H
    +This event counts load operations delayed caused by preceding stores whose
    +addresses are unknown (STA block).
    +.It Li STORE_BLOCKS.ANY
    +.Pq Event 06H , Umask 0FH
    +All loads delayed due to store blocks
    +.It Li MEMORY_DISAMBIGURATION.RESET
    +.Pq Event 09H , Umask 01H
    +Counts memory disambiguration reset cycles
    +.It Li MEMORY_DISAMBIGURATION.SUCCESS
    +.Pq Event 09H , Umask 02H
    +Counts the number of loads that memory disambiguration succeeded
    +.It Li MEMORY_DISAMBIGURATION.WATCHDOG
    +.Pq Event 09H , Umask 04H
    +Counts the number of times the memory disambiguration watchdog kicked in.
    +.It Li MEMORY_DISAMBIGURATION.WATCH_CYCLES
    +.Pq Event 09H , Umask 08H
    +Counts the cycles that the memory disambiguration watchdog is active.
    +set invert=1, cmask = 1
    +.It Li HW_INT.RCV
    +.Pq Event 1DH , Umask 01H
    +Number of interrupt received
    +.It Li HW_INT.CYCLES_MASKED
    +.Pq Event 1DH , Umask 02H
    +Number of cycles interrupt are masked
    +.It Li HW_INT.CYCLES_PENDING_AND_MASKED
    +.Pq Event 1DH , Umask 04H
    +Number of cycles interrupts are pending and masked
    +.It Li HW_INT.CYCLES_PENDING_AND_MASKED
    +.Pq Event 04H , Umask 04H
    +Counts number of L2 store RFO requests where the cache line to be loaded is
    +in the E (exclusive) state. The L1D prefetcher does not issue a RFO
    +prefetch.
    +This is a demand RFO request
    +.It Li HW_INT.CYCLES_PENDING_AND_MASKED
    +.Pq Event 27H , Umask 04H
    +LONGEST_LAT_CACH E.MISS
    +.It Li UOPS_DECODED.DEC0
    +.Pq Event 3DH , Umask 01H
    +Counts micro-ops decoded by decoder 0.
    +.It Li UOPS_DECODED.DEC0
    +.Pq Event 01H , Umask 01H
    +Counts L1 data cache store RFO requests where the cache line to be loaded is
    +in the I state.
    +Counter 0, 1 only
    +.It Li 0FH
    +.Pq Event 41H , Umask 41H
    +L1D_CACHE_ST.MESI
    +Counts L1 data cache store RFO requests.
    +Counter 0, 1 only
    +.It Li DTLB_MISSES.PDE_MISS
    +.Pq Event 49H , Umask 20H
    +Number of DTLB cache misses where the low part of the linear to physical
    +address translation was missed.
    +.It Li DTLB_MISSES.PDP_MISS
    +.Pq Event 49H , Umask 40H
    +Number of DTLB misses where the high part of the linear to physical address
    +translation was missed.
    +.It Li DTLB_MISSES.LARGE_WALK_COMPLETED
    +.Pq Event 49H , Umask 80H
    +Counts number of completed large page walks due to misses in the STLB.
    +.It Li SSE_MEM_EXEC.NTA
    +.Pq Event 4BH , Umask 01H
    +Counts number of SSE NTA prefetch/weakly-ordered instructions which missed
    +the L1 data cache.
    +.It Li SSE_MEM_EXEC.STREAMING_STORES
    +.Pq Event 4BH , Umask 08H
    +Counts number of SSE non temporal stores
    +.It Li SFENCE_CYCLES
    +.Pq Event 4DH , Umask 01H
    +Counts store fence cycles
    +.It Li EPT.EPDE_MISS
    +.Pq Event 4FH , Umask 02H
    +Counts Extended Page Directory Entry misses. The Extended Page Directory
    +cache is used by Virtual Machine operating systems while the guest operating
    +systems use the standard TLB caches.
    +.It Li EPT.EPDPE_HIT
    +.Pq Event 4FH , Umask 04H
    +Counts Extended Page Directory Pointer Entry hits.
    +.It Li EPT.EPDPE_MISS
    +.Pq Event 4FH , Umask 08H
    +Counts Extended Page Directory Pointer Entry misses. T
    +.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA
    +.Pq Event 60H , Umask 01H
    +Counts weighted cycles of offcore demand data read requests. Does not
    +include L2 prefetch requests.
    +counter 0
    +.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE
    +.Pq Event 60H , Umask 02H
    +Counts weighted cycles of offcore demand code read requests. Does not
    +include L2 prefetch requests.
    +counter 0
    +.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO
    +.Pq Event 60H , Umask 04H
    +Counts weighted cycles of offcore demand RFO requests. Does not include L2
    +prefetch requests.
    +counter 0
    +.It Li OFFCORE_REQUESTS_OUTSTANDING.ANY.READ
    +.Pq Event 60H , Umask 08H
    +Counts weighted cycles of offcore read requests of any kind. Include L2
    +prefetch requests.
    +counter 0
    +.It Li IFU_IVC.FULL
    +.Pq Event 81H , Umask 01H
    +Instruction Fetche unit victim cache full.
    +.It Li IFU_IVC.L1I_EVICTION
    +.Pq Event 81H , Umask 02H
    +L1 Instruction cache evictions.
    +.It Li L1I_OPPORTUNISTIC_HITS
    +.Pq Event 83H , Umask 01H
    +Opportunistic hits in streaming.
    +.It Li ITLB_MISSES.WALK_CYCLES
    +.Pq Event 85H , Umask 04H
    +Counts ITLB miss page walk cycles.
    +.It Li ITLB_MISSES.PMH_BUSY_CYCLES
    +.Pq Event 85H , Umask 04H
    +Counts PMH busy cycles.
    +.It Li ITLB_MISSES.STLB_HIT
    +.Pq Event 85H , Umask 10H
    +Counts the number of ITLB misses that hit in the second level TLB.
    +.It Li ITLB_MISSES.PDE_MISS
    +.Pq Event 85H , Umask 20H
    +Number of ITLB misses where the low part of the linear to physical address
    +translation was missed.
    +.It Li ITLB_MISSES.PDP_MISS
    +.Pq Event 85H , Umask 40H
    +Number of ITLB misses where the high part of the linear to physical address
    +translation was missed.
    +.It Li ITLB_MISSES.LARGE_WALK_COMPLETED
    +.Pq Event 85H , Umask 80H
    +Counts number of completed large page walks due to misses in the STLB.
    +.It Li ITLB_MISSES.LARGE_WALK_COMPLETED
    +.Pq Event 01H , Umask 80H
    +Counts number of offcore demand data read requests. Does not count L2
    +prefetch requests.
    +.It Li OFFCORE_REQUESTS.DEMAND.READ_CODE
    +.Pq Event B0H , Umask 02H
    +Counts number of offcore demand code read requests. Does not count L2
    +prefetch requests.
    +.It Li OFFCORE_REQUESTS.DEMAND.RFO
    +.Pq Event B0H , Umask 04H
    +Counts number of offcore demand RFO requests. Does not count L2 prefetch
    +requests.
    +.It Li OFFCORE_REQUESTS.ANY.READ
    +.Pq Event B0H , Umask 08H
    +Counts number of offcore read requests. Includes L2 prefetch requests.
    +.It Li OFFCORE_REQUESTS.ANY.RFO
    +.Pq Event B0H , Umask 10H
    +Counts number of offcore RFO requests. Includes L2 prefetch requests.
    +.It Li OFFCORE_REQUESTS.UNCACHED_MEM
    +.Pq Event B0H , Umask 20H
    +Counts number of offcore uncached memory requests.
    +.It Li OFFCORE_REQUESTS.ANY
    +.Pq Event B0H , Umask 80H
    +Counts all offcore requests.
    +.It Li SNOOPQ_REQUESTS_OUTSTANDING.DATA
    +.Pq Event B3H , Umask 01H
    +Counts weighted cycles of snoopq requests for data. Counter 0 only
    +Use cmask=1 to count cycles not empty.
    +.It Li SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE
    +.Pq Event B3H , Umask 02H
    +Counts weighted cycles of snoopq invalidate requests. Counter 0 only
    +Use cmask=1 to count cycles not empty.
    +.It Li SNOOPQ_REQUESTS_OUTSTANDING.CODE
    +.Pq Event B3H , Umask 04H
    +Counts weighted cycles of snoopq requests for code. Counter 0 only
    +Use cmask=1 to count cycles not empty.
    +.It Li SNOOPQ_REQUESTS_OUTSTANDING.CODE
    +.Pq Event BAH , Umask 04H
    +Counts number of TPR reads
    +.It Li PIC_ACCESSES.TPR_WRITES
    +.Pq Event BAH , Umask 02H
    +Counts number of TPR writes
    +one or two micro-ops. Some instructions are decoded into longer sequences
    +.It Li MACHINE_CLEARS.FUSION_ASSIST
    +.Pq Event C3H , Umask 10H
    +Counts the number of macro-fusion assists
    +Counts SIMD packed single- precision floating point Uops retired.
    +.It Li BOGUS_BR
    +.Pq Event E4H , Umask 01H
    +Counts the number of bogus branches.
    +.It Li L2_HW_PREFETCH.HIT
    +.Pq Event F3H , Umask 01H
    +Count L2 HW prefetcher detector hits
    +.It Li L2_HW_PREFETCH.ALLOC
    +.Pq Event F3H , Umask 02H
    +Count L2 HW prefetcher allocations
    +.It Li L2_HW_PREFETCH.DATA_TRIGGER
    +.Pq Event F3H , Umask 04H
    +Count L2 HW data prefetcher triggered
    +.It Li L2_HW_PREFETCH.CODE_TRIGGER
    +.Pq Event F3H , Umask 08H
    +Count L2 HW code prefetcher triggered
    +.It Li L2_HW_PREFETCH.DCA_TRIGGER
    +.Pq Event F3H , Umask 10H
    +Count L2 HW DCA prefetcher triggered
    +.It Li L2_HW_PREFETCH.KICK_START
    +.Pq Event F3H , Umask 20H
    +Count L2 HW prefetcher kick started
    +.It Li SQ_MISC.PROMOTION
    +.Pq Event F4H , Umask 01H
    +Counts the number of L2 secondary misses that hit the Super Queue.
    +.It Li SQ_MISC.PROMOTION_POST_GO
    +.Pq Event F4H , Umask 02H
    +Counts the number of L2 secondary misses during the Super Queue filling L2.
    +.It Li SQ_MISC.LRU_HINTS
    +.Pq Event F4H , Umask 04H
    +Counts number of Super Queue LRU hints sent to L3.
    +.It Li SQ_MISC.FILL_DROPPED
    +.Pq Event F4H , Umask 08H
    +Counts the number of SQ L2 fills dropped due to L2 busy.
    +.It Li SEGMENT_REG_LOADS
    +.Pq Event F8H , Umask 01H
    +Counts number of segment register loads.
    +.El
    +.Sh SEE ALSO
    +.Xr pmc 3 ,
    +.Xr pmc.atom 3 ,
    +.Xr pmc.core 3 ,
    +.Xr pmc.iaf 3 ,
    +.Xr pmc.ucf 3 ,
    +.Xr pmc.k7 3 ,
    +.Xr pmc.k8 3 ,
    +.Xr pmc.p4 3 ,
    +.Xr pmc.p5 3 ,
    +.Xr pmc.p6 3 ,
    +.Xr pmc.corei7uc 3 ,
    +.Xr pmc.westmere 3 ,
    +.Xr pmc.westmereuc 3 ,
    +.Xr pmc.tsc 3 ,
    +.Xr pmc_cpuinfo 3 ,
    +.Xr pmclog 3 ,
    +.Xr hwpmc 4
    +.Sh HISTORY
    +The
    +.Nm pmc
    +library first appeared in
    +.Fx 6.0 .
    +.Sh AUTHORS
    +The
    +.Lb libpmc
    +library was written by
    +.An "Joseph Koshy"
    +.Aq jkoshy@FreeBSD.org .
    diff --git a/lib/libpmc/pmc.corei7uc.3 b/lib/libpmc/pmc.corei7uc.3
    new file mode 100644
    index 00000000000..2c1b3dde07f
    --- /dev/null
    +++ b/lib/libpmc/pmc.corei7uc.3
    @@ -0,0 +1,880 @@
    +.\" Copyright (c) 2010 Fabien Thomas.  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 Joseph Koshy ``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 Joseph Koshy 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 March 24, 2010
    +.Os
    +.Dt PMC.COREI7UC 3
    +.Sh NAME
    +.Nm pmc.corei7uc
    +.Nd uncore measurement events for
    +.Tn Intel
    +.Tn Core i7 and Xeon 5500
    +family CPUs
    +.Sh LIBRARY
    +.Lb libpmc
    +.Sh SYNOPSIS
    +.In pmc.h
    +.Sh DESCRIPTION
    +.Tn Intel
    +.Tn "Core i7"
    +CPUs contain PMCs conforming to version 2 of the
    +.Tn Intel
    +performance measurement architecture.
    +These CPUs contain 2 classes of PMCs:
    +.Bl -tag -width "Li PMC_CLASS_UCP"
    +.It Li PMC_CLASS_UCF
    +Fixed-function counters that count only one hardware event per counter.
    +.It Li PMC_CLASS_UCP
    +Programmable counters that may be configured to count one of a defined
    +set of hardware events.
    +.El
    +.Pp
    +The number of PMCs available in each class and their widths need to be
    +determined at run time by calling
    +.Xr pmc_cpuinfo 3 .
    +.Pp
    +Intel Core i7 and Xeon 5500 PMCs are documented in
    +.Rs
    +.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
    +.%T "Volume 3B: System Programming Guide, Part 2"
    +.%N "Order Number: 253669-033US"
    +.%D December 2009
    +.%Q "Intel Corporation"
    +.Re
    +.Ss COREI7 AND XEON 5500 UNCORE FIXED FUNCTION PMCS
    +These PMCs and their supported events are documented in
    +.Xr pmc.ucf 3 .
    +.Ss COREI7 AND XEON 5500 UNCORE PROGRAMMABLE PMCS
    +The programmable PMCs support the following capabilities:
    +.Bl -column "PMC_CAP_INTERRUPT" "Support"
    +.It Em Capability Ta Em Support
    +.It PMC_CAP_CASCADE Ta \&No
    +.It PMC_CAP_EDGE Ta Yes
    +.It PMC_CAP_INTERRUPT Ta \&No
    +.It PMC_CAP_INVERT Ta Yes
    +.It PMC_CAP_READ Ta Yes
    +.It PMC_CAP_PRECISE Ta \&No
    +.It PMC_CAP_SYSTEM Ta \&No
    +.It PMC_CAP_TAGGING Ta \&No
    +.It PMC_CAP_THRESHOLD Ta Yes
    +.It PMC_CAP_USER Ta \&No
    +.It PMC_CAP_WRITE Ta Yes
    +.El
    +.Ss Event Qualifiers
    +Event specifiers for these PMCs support the following common
    +qualifiers:
    +.Bl -tag -width indent
    +.It Li cmask= Ns Ar value
    +Configure the PMC to increment only if the number of configured
    +events measured in a cycle is greater than or equal to
    +.Ar value .
    +.It Li edge
    +Configure the PMC to count the number of de-asserted to asserted
    +transitions of the conditions expressed by the other qualifiers.
    +If specified, the counter will increment only once whenever a
    +condition becomes true, irrespective of the number of clocks during
    +which the condition remains true.
    +.It Li inv
    +Invert the sense of comparison when the
    +.Dq Li cmask
    +qualifier is present, making the counter increment when the number of
    +events per cycle is less than the value specified by the
    +.Dq Li cmask
    +qualifier.
    +.El
    +.Ss Event Specifiers (Programmable PMCs)
    +Core i7 and Xeon 5500 uncore programmable PMCs support the following events:
    +.Bl -tag -width indent
    +.It Li GQ_CYCLES_FULL.READ_TRACKER
    +.Pq Event 00H , Umask 01H
    +Uncore cycles Global Queue read tracker is full.
    +.It Li GQ_CYCLES_FULL.WRITE_TRACKER
    +.Pq Event 00H , Umask 02H
    +Uncore cycles Global Queue write tracker is full.
    +.It Li GQ_CYCLES_FULL.PEER_PROBE_TRACKER
    +.Pq Event 00H , Umask 04H
    +Uncore cycles Global Queue peer probe tracker is full. The peer probe
    +tracker queue tracks snoops from the IOH and remote sockets.
    +.It Li GQ_CYCLES_NOT_EMPTY.READ_TRACKER
    +.Pq Event 01H , Umask 01H
    +Uncore cycles were Global Queue read tracker has at least one valid entry.
    +.It Li GQ_CYCLES_NOT_EMPTY.WRITE_TRACKER
    +.Pq Event 01H , Umask 02H
    +Uncore cycles were Global Queue write tracker has at least one valid entry.
    +.It Li GQ_CYCLES_NOT_EMPTY.PEER_PROBE_TRACKER
    +.Pq Event 01H , Umask 04H
    +Uncore cycles were Global Queue peer probe tracker has at least one valid
    +entry. The peer probe tracker queue tracks IOH and remote socket snoops.
    +.It Li GQ_ALLOC.READ_TRACKER
    +.Pq Event 03H , Umask 01H
    +Counts the number of tread tracker allocate to deallocate entries. The GQ
    +read tracker allocate to deallocate occupancy count is divided by the count
    +to obtain the average read tracker latency.
    +.It Li GQ_ALLOC.RT_L3_MISS
    +.Pq Event 03H , Umask 02H
    +Counts the number GQ read tracker entries for which a full cache line read
    +has missed the L3. The GQ read tracker L3 miss to fill occupancy count is
    +divided by this count to obtain the average cache line read L3 miss latency.
    +The latency represents the time after which the L3 has determined that the
    +cache line has missed. The time between a GQ read tracker allocation and the
    +L3 determining that the cache line has missed is the average L3 hit latency.
    +The total L3 cache line read miss latency is the hit latency + L3 miss
    +latency.
    +.It Li GQ_ALLOC.RT_TO_L3_RESP
    +.Pq Event 03H , Umask 04H
    +Counts the number of GQ read tracker entries that are allocated in the read
    +tracker queue that hit or miss the L3. The GQ read tracker L3 hit occupancy
    +count is divided by this count to obtain the average L3 hit latency.
    +.It Li GQ_ALLOC.RT_TO_RTID_ACQUIRED
    +.Pq Event 03H , Umask 08H
    +Counts the number of GQ read tracker entries that are allocated in the read
    +tracker, have missed in the L3 and have not acquired a Request Transaction
    +ID.	The GQ read tracker L3 miss to RTID acquired occupancy count is
    +divided by this count to obtain the average latency for a read L3 miss to
    +acquire an RTID.
    +.It Li GQ_ALLOC.WT_TO_RTID_ACQUIRED
    +.Pq Event 03H , Umask 10H
    +Counts the number of GQ write tracker entries that are allocated in the
    +write tracker, have missed in the L3 and have not acquired a Request
    +Transaction ID.	The GQ write tracker L3 miss to RTID occupancy count is
    +divided by this count to obtain the average latency for a write L3 miss to
    +acquire an RTID.
    +.It Li GQ_ALLOC.WRITE_TRACKER
    +.Pq Event 03H , Umask 20H
    +Counts the number of GQ write tracker entries that are allocated in the
    +write tracker queue that miss the L3. The GQ write tracker occupancy count
    +is divided by the this count to obtain the average L3 write miss latency.
    +.It Li GQ_ALLOC.PEER_PROBE_TRACKER
    +.Pq Event 03H , Umask 40H
    +Counts the number of GQ peer probe tracker (snoop) entries that are
    +allocated in the peer probe tracker queue that miss the L3. The GQ peer
    +probe occupancy count is divided by this count to obtain the average L3 peer
    +probe miss latency.
    +.It Li GQ_DATA.FROM_QPI
    +.Pq Event 04H , Umask 01H
    +Cycles Global Queue Quickpath Interface input data port is busy importing
    +data from the Quickpath Interface. Each cycle the input port can transfer 8
    +or 16 bytes of data.
    +.It Li GQ_DATA.FROM_QMC
    +.Pq Event 04H , Umask 02H
    +Cycles Global Queue Quickpath Memory Interface input data port is busy
    +importing data from the Quickpath Memory Interface. Each cycle the input
    +port can transfer 8 or 16 bytes of data.
    +.It Li GQ_DATA.FROM_L3
    +.Pq Event 04H , Umask 04H
    +Cycles GQ L3 input data port is busy importing data from the Last Level
    +Cache. Each cycle the input port can transfer 32 bytes of data.
    +.It Li GQ_DATA.FROM_CORES_02
    +.Pq Event 04H , Umask 08H
    +Cycles GQ Core 0 and 2 input data port is busy importing data from processor
    +cores 0 and 2. Each cycle the input port can transfer 32 bytes of data.
    +.It Li GQ_DATA.FROM_CORES_13
    +.Pq Event 04H , Umask 10H
    +Cycles GQ Core 1 and 3 input data port is busy importing data from processor
    +cores 1 and 3. Each cycle the input port can transfer 32 bytes of data.
    +.It Li GQ_DATA.TO_QPI_QMC
    +.Pq Event 05H , Umask 01H
    +Cycles GQ QPI and QMC output data port is busy sending data to the Quickpath
    +Interface or Quickpath Memory Interface. Each cycle the output port can
    +transfer 32 bytes of data.
    +.It Li GQ_DATA.TO_L3
    +.Pq Event 05H , Umask 02H
    +Cycles GQ L3 output data port is busy sending data to the Last Level Cache.
    +Each cycle the output port can transfer 32 bytes of data.
    +.It Li GQ_DATA.TO_CORES
    +.Pq Event 05H , Umask 04H
    +Cycles GQ Core output data port is busy sending data to the Cores. Each
    +cycle the output port can transfer 32 bytes of data.
    +.It Li SNP_RESP_TO_LOCAL_HOME.I_STATE
    +.Pq Event 06H , Umask 01H
    +Number of snoop responses to the local home that L3 does not have the
    +referenced cache line.
    +.It Li SNP_RESP_TO_LOCAL_HOME.S_STATE
    +.Pq Event 06H , Umask 02H
    +Number of snoop responses to the local home that L3 has the referenced line
    +cached in the S state.
    +.It Li SNP_RESP_TO_LOCAL_HOME.FWD_S_STATE
    +.Pq Event 06H , Umask 04H
    +Number of responses to code or data read snoops to the local home that the
    +L3 has the referenced cache line in the E state. The L3 cache line state is
    +changed to the S state and the line is forwarded to the local home in the S
    +state.
    +.It Li SNP_RESP_TO_LOCAL_HOME.FWD_I_STATE
    +.Pq Event 06H , Umask 08H
    +Number of responses to read invalidate snoops to the local home that the L3
    +has the referenced cache line in the M state. The L3 cache line state is
    +invalidated and the line is forwarded to the local home in the M state.
    +.It Li SNP_RESP_TO_LOCAL_HOME.CONFLICT
    +.Pq Event 06H , Umask 10H
    +Number of conflict snoop responses sent to the local home.
    +.It Li SNP_RESP_TO_LOCAL_HOME.WB
    +.Pq Event 06H , Umask 20H
    +Number of responses to code or data read snoops to the local home that the
    +L3 has the referenced line cached in the M state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.I_STATE
    +.Pq Event 07H , Umask 01H
    +Number of snoop responses to a remote home that L3 does not have the
    +referenced cache line.
    +.It Li SNP_RESP_TO_REMOTE_HOME.S_STATE
    +.Pq Event 07H , Umask 02H
    +Number of snoop responses to a remote home that L3 has the referenced line
    +cached in the S state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.FWD_S_STATE
    +.Pq Event 07H , Umask 04H
    +Number of responses to code or data read snoops to a remote home that the L3
    +has the referenced cache line in the E state. The L3 cache line state is
    +changed to the S state and the line is forwarded to the remote home in the S
    +state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.FWD_I_STATE
    +.Pq Event 07H , Umask 08H
    +Number of responses to read invalidate snoops to a remote home that the L3
    +has the referenced cache line in the M state. The L3 cache line state is
    +invalidated and the line is forwarded to the remote home in the M state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.CONFLICT
    +.Pq Event 07H , Umask 10H
    +Number of conflict snoop responses sent to the local home.
    +.It Li SNP_RESP_TO_REMOTE_HOME.WB
    +.Pq Event 07H , Umask 20H
    +Number of responses to code or data read snoops to a remote home that the L3
    +has the referenced line cached in the M state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.HITM
    +.Pq Event 07H , Umask 24H
    +Number of HITM snoop responses to a remote home
    +.It Li L3_HITS.READ
    +.Pq Event 08H , Umask 01H
    +Number of code read, data read and RFO requests that hit in the L3
    +.It Li L3_HITS.WRITE
    +.Pq Event 08H , Umask 02H
    +Number of writeback requests that hit in the L3. Writebacks from the cores
    +will always result in L3 hits due to the inclusive property of the L3.
    +.It Li L3_HITS.PROBE
    +.Pq Event 08H , Umask 04H
    +Number of snoops from IOH or remote sockets that hit in the L3.
    +.It Li L3_HITS.ANY
    +.Pq Event 08H , Umask 03H
    +Number of reads and writes that hit the L3.
    +.It Li L3_MISS.READ
    +.Pq Event 09H , Umask 01H
    +Number of code read, data read and RFO requests that miss the L3.
    +.It Li L3_MISS.WRITE
    +.Pq Event 09H , Umask 02H
    +Number of writeback requests that miss the L3. Should always be zero as
    +writebacks from the cores will always result in L3 hits due to the inclusive
    +property of the L3.
    +.It Li L3_MISS.PROBE
    +.Pq Event 09H , Umask 04H
    +Number of snoops from IOH or remote sockets that miss the L3.
    +.It Li L3_MISS.ANY
    +.Pq Event 09H , Umask 03H
    +Number of reads and writes that miss the L3.
    +.It Li L3_LINES_IN.M_STATE
    +.Pq Event 0AH , Umask 01H
    +Counts the number of L3 lines allocated in M state. The only time a cache
    +line is allocated in the M state is when the line was forwarded in M state
    +is forwarded due to a Snoop Read Invalidate Own request.
    +.It Li L3_LINES_IN.E_STATE
    +.Pq Event 0AH , Umask 02H
    +Counts the number of L3 lines allocated in E state.
    +.It Li L3_LINES_IN.S_STATE
    +.Pq Event 0AH , Umask 04H
    +Counts the number of L3 lines allocated in S state.
    +.It Li L3_LINES_IN.F_STATE
    +.Pq Event 0AH , Umask 08H
    +Counts the number of L3 lines allocated in F state.
    +.It Li L3_LINES_IN.ANY
    +.Pq Event 0AH , Umask 0FH
    +Counts the number of L3 lines allocated in any state.
    +.It Li L3_LINES_OUT.M_STATE
    +.Pq Event 0BH , Umask 01H
    +Counts the number of L3 lines victimized that were in the M state. When the
    +victim cache line is in M state, the line is written to its home cache agent
    +which can be either local or remote.
    +.It Li L3_LINES_OUT.E_STATE
    +.Pq Event 0BH , Umask 02H
    +Counts the number of L3 lines victimized that were in the E state.
    +.It Li L3_LINES_OUT.S_STATE
    +.Pq Event 0BH , Umask 04H
    +Counts the number of L3 lines victimized that were in the S state.
    +.It Li L3_LINES_OUT.I_STATE
    +.Pq Event 0BH , Umask 08H
    +Counts the number of L3 lines victimized that were in the I state.
    +.It Li L3_LINES_OUT.F_STATE
    +.Pq Event 0BH , Umask 10H
    +Counts the number of L3 lines victimized that were in the F state.
    +.It Li L3_LINES_OUT.ANY
    +.Pq Event 0BH , Umask 1FH
    +Counts the number of L3 lines victimized in any state.
    +.It Li QHL_REQUESTS.IOH_READS
    +.Pq Event 20H , Umask 01H
    +Counts number of Quickpath Home Logic read requests from the IOH.
    +.It Li QHL_REQUESTS.IOH_WRITES
    +.Pq Event 20H , Umask 02H
    +Counts number of Quickpath Home Logic write requests from the IOH.
    +.It Li QHL_REQUESTS.REMOTE_READS
    +.Pq Event 20H , Umask 04H
    +Counts number of Quickpath Home Logic read requests from a remote socket.
    +.It Li QHL_REQUESTS.REMOTE_WRITES
    +.Pq Event 20H , Umask 08H
    +Counts number of Quickpath Home Logic write requests from a remote socket.
    +.It Li QHL_REQUESTS.LOCAL_READS
    +.Pq Event 20H , Umask 10H
    +Counts number of Quickpath Home Logic read requests from the local socket.
    +.It Li QHL_REQUESTS.LOCAL_WRITES
    +.Pq Event 20H , Umask 20H
    +Counts number of Quickpath Home Logic write requests from the local socket.
    +.It Li QHL_CYCLES_FULL.IOH
    +.Pq Event 21H , Umask 01H
    +Counts uclk cycles all entries in the Quickpath Home Logic IOH are full.
    +.It Li QHL_CYCLES_FULL.REMOTE
    +.Pq Event 21H , Umask 02H
    +Counts uclk cycles all entries in the Quickpath Home Logic remote tracker
    +are full.
    +.It Li QHL_CYCLES_FULL.LOCAL
    +.Pq Event 21H , Umask 04H
    +Counts uclk cycles all entries in the Quickpath Home Logic local tracker are
    +full.
    +.It Li QHL_CYCLES_NOT_EMPTY.IOH
    +.Pq Event 22H , Umask 01H
    +Counts uclk cycles all entries in the Quickpath Home Logic IOH is busy.
    +.It Li QHL_CYCLES_NOT_EMPTY.REMOTE
    +.Pq Event 22H , Umask 02H
    +Counts uclk cycles all entries in the Quickpath Home Logic remote tracker is
    +busy.
    +.It Li QHL_CYCLES_NOT_EMPTY.LOCAL
    +.Pq Event 22H , Umask 04H
    +Counts uclk cycles all entries in the Quickpath Home Logic local tracker is
    +busy.
    +.It Li QHL_OCCUPANCY.IOH
    +.Pq Event 23H , Umask 01H
    +QHL IOH tracker allocate to deallocate read occupancy.
    +.It Li QHL_OCCUPANCY.REMOTE
    +.Pq Event 23H , Umask 02H
    +QHL remote tracker allocate to deallocate read occupancy.
    +.It Li QHL_OCCUPANCY.LOCAL
    +.Pq Event 23H , Umask 04H
    +QHL local tracker allocate to deallocate read occupancy.
    +.It Li QHL_ADDRESS_CONFLICTS.2WAY
    +.Pq Event 24H , Umask 02H
    +Counts number of QHL Active Address Table (AAT) entries that saw a max of 2
    +conflicts. The AAT is a structure that tracks requests that are in conflict.
    +The requests themselves are in the home tracker entries. The count is
    +reported when an AAT entry deallocates.
    +.It Li QHL_ADDRESS_CONFLICTS.3WAY
    +.Pq Event 24H , Umask 04H
    +Counts number of QHL Active Address Table (AAT) entries that saw a max of 3
    +conflicts. The AAT is a structure that tracks requests that are in conflict.
    +The requests themselves are in the home tracker entries. The count is
    +reported when an AAT entry deallocates.
    +.It Li QHL_CONFLICT_CYCLES.IOH
    +.Pq Event 25H , Umask 01H
    +Counts cycles the Quickpath Home Logic IOH Tracker contains two or more
    +requests with an address conflict. A max of 3 requests can be in conflict.
    +.It Li QHL_CONFLICT_CYCLES.REMOTE
    +.Pq Event 25H , Umask 02H
    +Counts cycles the Quickpath Home Logic Remote Tracker contains two or more
    +requests with an address conflict. A max of 3 requests can be in conflict.
    +.It Li QHL_CONFLICT_CYCLES.LOCAL
    +.Pq Event 25H , Umask 04H
    +Counts cycles the Quickpath Home Logic Local Tracker contains two or more
    +requests with an address conflict. A max of 3 requests can be in conflict.
    +.It Li QHL_TO_QMC_BYPASS
    +.Pq Event 26H , Umask 01H
    +Counts number or requests to the Quickpath Memory Controller that bypass the
    +Quickpath Home Logic. All local accesses can be bypassed. For remote
    +requests, only read requests can be bypassed.
    +.It Li QMC_NORMAL_FULL.READ.CH0
    +.Pq Event 27H , Umask 01H
    +Uncore cycles all the entries in the DRAM channel 0 medium or low priority
    +queue are occupied with read requests.
    +.It Li QMC_NORMAL_FULL.READ.CH1
    +.Pq Event 27H , Umask 02H
    +Uncore cycles all the entries in the DRAM channel 1 medium or low priority
    +queue are occupied with read requests.
    +.It Li QMC_NORMAL_FULL.READ.CH2
    +.Pq Event 27H , Umask 04H
    +Uncore cycles all the entries in the DRAM channel 2 medium or low priority
    +queue are occupied with read requests.
    +.It Li QMC_NORMAL_FULL.WRITE.CH0
    +.Pq Event 27H , Umask 08H
    +Uncore cycles all the entries in the DRAM channel 0 medium or low priority
    +queue are occupied with write requests.
    +.It Li QMC_NORMAL_FULL.WRITE.CH1
    +.Pq Event 27H , Umask 10H
    +Counts cycles all the entries in the DRAM channel 1 medium or low priority
    +queue are occupied with write requests.
    +.It Li QMC_NORMAL_FULL.WRITE.CH2
    +.Pq Event 27H , Umask 20H
    +Uncore cycles all the entries in the DRAM channel 2 medium or low priority
    +queue are occupied with write requests.
    +.It Li QMC_ISOC_FULL.READ.CH0
    +.Pq Event 28H , Umask 01H
    +Counts cycles all the entries in the DRAM channel 0 high priority queue are
    +occupied with isochronous read requests.
    +.It Li QMC_ISOC_FULL.READ.CH1
    +.Pq Event 28H , Umask 02H
    +Counts cycles all the entries in the DRAM channel 1high priority queue are
    +occupied with isochronous read requests.
    +.It Li QMC_ISOC_FULL.READ.CH2
    +.Pq Event 28H , Umask 04H
    +Counts cycles all the entries in the DRAM channel 2 high priority queue are
    +occupied with isochronous read requests.
    +.It Li QMC_ISOC_FULL.WRITE.CH0
    +.Pq Event 28H , Umask 08H
    +Counts cycles all the entries in the DRAM channel 0 high priority queue are
    +occupied with isochronous write requests.
    +.It Li QMC_ISOC_FULL.WRITE.CH1
    +.Pq Event 28H , Umask 10H
    +Counts cycles all the entries in the DRAM channel 1 high priority queue are
    +occupied with isochronous write requests.
    +.It Li QMC_ISOC_FULL.WRITE.CH2
    +.Pq Event 28H , Umask 20H
    +Counts cycles all the entries in the DRAM channel 2 high priority queue are
    +occupied with isochronous write requests.
    +.It Li QMC_BUSY.READ.CH0
    +.Pq Event 29H , Umask 01H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +read request to DRAM channel 0.
    +.It Li QMC_BUSY.READ.CH1
    +.Pq Event 29H , Umask 02H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +read request to DRAM channel 1.
    +.It Li QMC_BUSY.READ.CH2
    +.Pq Event 29H , Umask 04H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +read request to DRAM channel 2.
    +.It Li QMC_BUSY.WRITE.CH0
    +.Pq Event 29H , Umask 08H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +write request to DRAM channel 0.
    +.It Li QMC_BUSY.WRITE.CH1
    +.Pq Event 29H , Umask 10H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +write request to DRAM channel 1.
    +.It Li QMC_BUSY.WRITE.CH2
    +.Pq Event 29H , Umask 20H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +write request to DRAM channel 2.
    +.It Li QMC_OCCUPANCY.CH0
    +.Pq Event 2AH , Umask 01H
    +IMC channel 0 normal read request occupancy.
    +.It Li QMC_OCCUPANCY.CH1
    +.Pq Event 2AH , Umask 02H
    +IMC channel 1 normal read request occupancy.
    +.It Li QMC_OCCUPANCY.CH2
    +.Pq Event 2AH , Umask 04H
    +IMC channel 2 normal read request occupancy.
    +.It Li QMC_ISSOC_OCCUPANCY.CH0
    +.Pq Event 2BH , Umask 01H
    +IMC channel 0 issoc read request occupancy.
    +.It Li QMC_ISSOC_OCCUPANCY.CH1
    +.Pq Event 2BH , Umask 02H
    +IMC channel 1 issoc read request occupancy.
    +.It Li QMC_ISSOC_OCCUPANCY.CH2
    +.Pq Event 2BH , Umask 04H
    +IMC channel 2 issoc read request occupancy.
    +.It Li QMC_ISSOC_READS.ANY
    +.Pq Event 2BH , Umask 07H
    +IMC issoc read request occupancy.
    +.It Li QMC_NORMAL_READS.CH0
    +.Pq Event 2CH , Umask 01H
    +Counts the number of Quickpath Memory Controller channel 0 medium and low
    +priority read requests. The QMC channel 0 normal read occupancy divided by
    +this count provides the average QMC channel 0 read latency.
    +.It Li QMC_NORMAL_READS.CH1
    +.Pq Event 2CH , Umask 02H
    +Counts the number of Quickpath Memory Controller channel 1 medium and low
    +priority read requests. The QMC channel 1 normal read occupancy divided by
    +this count provides the average QMC channel 1 read latency.
    +.It Li QMC_NORMAL_READS.CH2
    +.Pq Event 2CH , Umask 04H
    +Counts the number of Quickpath Memory Controller channel 2 medium and low
    +priority read requests. The QMC channel 2 normal read occupancy divided by
    +this count provides the average QMC channel 2 read latency.
    +.It Li QMC_NORMAL_READS.ANY
    +.Pq Event 2CH , Umask 07H
    +Counts the number of Quickpath Memory Controller medium and low priority
    +read requests. The QMC normal read occupancy divided by this count provides
    +the average QMC read latency.
    +.It Li QMC_HIGH_PRIORITY_READS.CH0
    +.Pq Event 2DH , Umask 01H
    +Counts the number of Quickpath Memory Controller channel 0 high priority
    +isochronous read requests.
    +.It Li QMC_HIGH_PRIORITY_READS.CH1
    +.Pq Event 2DH , Umask 02H
    +Counts the number of Quickpath Memory Controller channel 1 high priority
    +isochronous read requests.
    +.It Li QMC_HIGH_PRIORITY_READS.CH2
    +.Pq Event 2DH , Umask 04H
    +Counts the number of Quickpath Memory Controller channel 2 high priority
    +isochronous read requests.
    +.It Li QMC_HIGH_PRIORITY_READS.ANY
    +.Pq Event 2DH , Umask 07H
    +Counts the number of Quickpath Memory Controller high priority isochronous
    +read requests.
    +.It Li QMC_CRITICAL_PRIORITY_READS.CH0
    +.Pq Event 2EH , Umask 01H
    +Counts the number of Quickpath Memory Controller channel 0 critical priority
    +isochronous read requests.
    +.It Li QMC_CRITICAL_PRIORITY_READS.CH1
    +.Pq Event 2EH , Umask 02H
    +Counts the number of Quickpath Memory Controller channel 1 critical priority
    +isochronous read requests.
    +.It Li QMC_CRITICAL_PRIORITY_READS.CH2
    +.Pq Event 2EH , Umask 04H
    +Counts the number of Quickpath Memory Controller channel 2 critical priority
    +isochronous read requests.
    +.It Li QMC_CRITICAL_PRIORITY_READS.ANY
    +.Pq Event 2EH , Umask 07H
    +Counts the number of Quickpath Memory Controller critical priority
    +isochronous read requests.
    +.It Li QMC_WRITES.FULL.CH0
    +.Pq Event 2FH , Umask 01H
    +Counts number of full cache line writes to DRAM channel 0.
    +.It Li QMC_WRITES.FULL.CH1
    +.Pq Event 2FH , Umask 02H
    +Counts number of full cache line writes to DRAM channel 1.
    +.It Li QMC_WRITES.FULL.CH2
    +.Pq Event 2FH , Umask 04H
    +Counts number of full cache line writes to DRAM channel 2.
    +.It Li QMC_WRITES.FULL.ANY
    +.Pq Event 2FH , Umask 07H
    +Counts number of full cache line writes to DRAM.
    +.It Li QMC_WRITES.PARTIAL.CH0
    +.Pq Event 2FH , Umask 08H
    +Counts number of partial cache line writes to DRAM channel 0.
    +.It Li QMC_WRITES.PARTIAL.CH1
    +.Pq Event 2FH , Umask 10H
    +Counts number of partial cache line writes to DRAM channel 1.
    +.It Li QMC_WRITES.PARTIAL.CH2
    +.Pq Event 2FH , Umask 20H
    +Counts number of partial cache line writes to DRAM channel 2.
    +.It Li QMC_WRITES.PARTIAL.ANY
    +.Pq Event 2FH , Umask 38H
    +Counts number of partial cache line writes to DRAM.
    +.It Li QMC_CANCEL.CH0
    +.Pq Event 30H , Umask 01H
    +Counts number of DRAM channel 0 cancel requests.
    +.It Li QMC_CANCEL.CH1
    +.Pq Event 30H , Umask 02H
    +Counts number of DRAM channel 1 cancel requests.
    +.It Li QMC_CANCEL.CH2
    +.Pq Event 30H , Umask 04H
    +Counts number of DRAM channel 2 cancel requests.
    +.It Li QMC_CANCEL.ANY
    +.Pq Event 30H , Umask 07H
    +Counts number of DRAM cancel requests.
    +.It Li QMC_PRIORITY_UPDATES.CH0
    +.Pq Event 31H , Umask 01H
    +Counts number of DRAM channel 0 priority updates. A priority update occurs
    +when an ISOC high or critical request is received by the QHL and there is a
    +matching request with normal priority that has already been issued to the
    +QMC. In this instance, the QHL will send a priority update to QMC to
    +expedite the request.
    +.It Li QMC_PRIORITY_UPDATES.CH1
    +.Pq Event 31H , Umask 02H
    +Counts number of DRAM channel 1 priority updates. A priority update occurs
    +when an ISOC high or critical request is received by the QHL and there is a
    +matching request with normal priority that has already been issued to the
    +QMC. In this instance, the QHL will send a priority update to QMC to
    +expedite the request.
    +.It Li QMC_PRIORITY_UPDATES.CH2
    +.Pq Event 31H , Umask 04H
    +Counts number of DRAM channel 2 priority updates. A priority update occurs
    +when an ISOC high or critical request is received by the QHL and there is a
    +matching request with normal priority that has already been issued to the
    +QMC. In this instance, the QHL will send a priority update to QMC to
    +expedite the request.
    +.It Li QMC_PRIORITY_UPDATES.ANY
    +.Pq Event 31H , Umask 07H
    +Counts number of DRAM priority updates. A priority update occurs when an
    +ISOC high or critical request is received by the QHL and there is a matching
    +request with normal priority that has already been issued to the QMC. In
    +this instance, the QHL will send a priority update to QMC to expedite the
    +request.
    +.It Li QHL_FRC_ACK_CNFLTS.LOCAL
    +.Pq Event 33H , Umask 04H
    +Counts number of Force Acknowledge Conflict messages sent by the Quickpath
    +Home Logic to the local home.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_0
    +.Pq Event 40H , Umask 01H
    +Counts cycles the Quickpath outbound link 0 HOME virtual channel is stalled
    +due to lack of a VNA and VN0 credit. Note that this event does not filter
    +out when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_0
    +.Pq Event 40H , Umask 02H
    +Counts cycles the Quickpath outbound link 0 SNOOP virtual channel is stalled
    +due to lack of a VNA and VN0 credit. Note that this event does not filter
    +out when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_0
    +.Pq Event 40H , Umask 04H
    +Counts cycles the Quickpath outbound link 0 non-data response virtual
    +channel is stalled due to lack of a VNA and VN0 credit. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_1
    +.Pq Event 40H , Umask 08H
    +Counts cycles the Quickpath outbound link 1 HOME virtual channel is stalled
    +due to lack of a VNA and VN0 credit. Note that this event does not filter
    +out when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_1
    +.Pq Event 40H , Umask 10H
    +Counts cycles the Quickpath outbound link 1 SNOOP virtual channel is stalled
    +due to lack of a VNA and VN0 credit. Note that this event does not filter
    +out when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_1
    +.Pq Event 40H , Umask 20H
    +Counts cycles the Quickpath outbound link 1 non-data response virtual
    +channel is stalled due to lack of a VNA and VN0 credit. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.LINK_0
    +.Pq Event 40H , Umask 07H
    +Counts cycles the Quickpath outbound link 0 virtual channels are stalled due
    +to lack of a VNA and VN0 credit. Note that this event does not filter out
    +when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.LINK_1
    +.Pq Event 40H , Umask 38H
    +Counts cycles the Quickpath outbound link 1 virtual channels are stalled due
    +to lack of a VNA and VN0 credit. Note that this event does not filter out
    +when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_0
    +.Pq Event 41H , Umask 01H
    +Counts cycles the Quickpath outbound link 0 Data ResponSe virtual channel is
    +stalled due to lack of VNA and VN0 credits. Note that this event does not
    +filter out when a flit would not have been selected for arbitration because
    +another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_0
    +.Pq Event 41H , Umask 02H
    +Counts cycles the Quickpath outbound link 0 Non-Coherent Bypass virtual
    +channel is stalled due to lack of VNA and VN0 credits. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_0
    +.Pq Event 41H , Umask 04H
    +Counts cycles the Quickpath outbound link 0 Non-Coherent Standard virtual
    +channel is stalled due to lack of VNA and VN0 credits. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_1
    +.Pq Event 41H , Umask 08H
    +Counts cycles the Quickpath outbound link 1 Data ResponSe virtual channel is
    +stalled due to lack of VNA and VN0 credits. Note that this event does not
    +filter out when a flit would not have been selected for arbitration because
    +another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_1
    +.Pq Event 41H , Umask 10H
    +Counts cycles the Quickpath outbound link 1 Non-Coherent Bypass virtual
    +channel is stalled due to lack of VNA and VN0 credits. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_1
    +.Pq Event 41H , Umask 20H
    +Counts cycles the Quickpath outbound link 1 Non-Coherent Standard virtual
    +channel is stalled due to lack of VNA and VN0 credits. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.LINK_0
    +.Pq Event 41H , Umask 07H
    +Counts cycles the Quickpath outbound link 0 virtual channels are stalled due
    +to lack of VNA and VN0 credits. Note that this event does not filter out
    +when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.LINK_1
    +.Pq Event 41H , Umask 38H
    +Counts cycles the Quickpath outbound link 1 virtual channels are stalled due
    +to lack of VNA and VN0 credits. Note that this event does not filter out
    +when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_HEADER.BUSY.LINK_0
    +.Pq Event 42H , Umask 02H
    +Number of cycles that the header buffer in the Quickpath Interface outbound
    +link 0 is busy.
    +.It Li QPI_TX_HEADER.BUSY.LINK_1
    +.Pq Event 42H , Umask 08H
    +Number of cycles that the header buffer in the Quickpath Interface outbound
    +link 1 is busy.
    +.It Li QPI_RX_NO_PPT_CREDIT.STALLS.LINK_0
    +.Pq Event 43H , Umask 01H
    +Number of cycles that snoop packets incoming to the Quickpath Interface link
    +0 are stalled and not sent to the GQ because the GQ Peer Probe Tracker (PPT)
    +does not have any available entries.
    +.It Li QPI_RX_NO_PPT_CREDIT.STALLS.LINK_1
    +.Pq Event 43H , Umask 02H
    +Number of cycles that snoop packets incoming to the Quickpath Interface link
    +1 are stalled and not sent to the GQ because the GQ Peer Probe Tracker (PPT)
    +does not have any available entries.
    +.It Li DRAM_OPEN.CH0
    +.Pq Event 60H , Umask 01H
    +Counts number of DRAM Channel 0 open commands issued either for read or
    +write. To read or write data, the referenced DRAM page must first be opened.
    +.It Li DRAM_OPEN.CH1
    +.Pq Event 60H , Umask 02H
    +Counts number of DRAM Channel 1 open commands issued either for read or
    +write. To read or write data, the referenced DRAM page must first be opened.
    +.It Li DRAM_OPEN.CH2
    +.Pq Event 60H , Umask 04H
    +Counts number of DRAM Channel 2 open commands issued either for read or
    +write. To read or write data, the referenced DRAM page must first be opened.
    +.It Li DRAM_PAGE_CLOSE.CH0
    +.Pq Event 61H , Umask 01H
    +DRAM channel 0 command issued to CLOSE a page due to page idle timer
    +expiration. Closing a page is done by issuing a precharge.
    +.It Li DRAM_PAGE_CLOSE.CH1
    +.Pq Event 61H , Umask 02H
    +DRAM channel 1 command issued to CLOSE a page due to page idle timer
    +expiration. Closing a page is done by issuing a precharge.
    +.It Li DRAM_PAGE_CLOSE.CH2
    +.Pq Event 61H , Umask 04H
    +DRAM channel 2 command issued to CLOSE a page due to page idle timer
    +expiration. Closing a page is done by issuing a precharge.
    +.It Li DRAM_PAGE_MISS.CH0
    +.Pq Event 62H , Umask 01H
    +Counts the number of precharges (PRE) that were issued to DRAM channel 0
    +because there was a page miss. A page miss refers to a situation in which a
    +page is currently open and another page from the same bank needs to be
    +opened. The new page experiences a page miss. Closing of the old page is
    +done by issuing a precharge.
    +.It Li DRAM_PAGE_MISS.CH1
    +.Pq Event 62H , Umask 02H
    +Counts the number of precharges (PRE) that were issued to DRAM channel 1
    +because there was a page miss. A page miss refers to a situation in which a
    +page is currently open and another page from the same bank needs to be
    +opened. The new page experiences a page miss. Closing of the old page is
    +done by issuing a precharge.
    +.It Li DRAM_PAGE_MISS.CH2
    +.Pq Event 62H , Umask 04H
    +Counts the number of precharges (PRE) that were issued to DRAM channel 2
    +because there was a page miss. A page miss refers to a situation in which a
    +page is currently open and another page from the same bank needs to be
    +opened. The new page experiences a page miss. Closing of the old page is
    +done by issuing a precharge.
    +.It Li DRAM_READ_CAS.CH0
    +.Pq Event 63H , Umask 01H
    +Counts the number of times a read CAS command was issued on DRAM channel 0.
    +.It Li DRAM_READ_CAS.AUTOPRE_CH0
    +.Pq Event 63H , Umask 02H
    +Counts the number of times a read CAS command was issued on DRAM channel 0
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_READ_CAS.CH1
    +.Pq Event 63H , Umask 04H
    +Counts the number of times a read CAS command was issued on DRAM channel 1.
    +.It Li DRAM_READ_CAS.AUTOPRE_CH1
    +.Pq Event 63H , Umask 08H
    +Counts the number of times a read CAS command was issued on DRAM channel 1
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_READ_CAS.CH2
    +.Pq Event 63H , Umask 10H
    +Counts the number of times a read CAS command was issued on DRAM channel 2.
    +.It Li DRAM_READ_CAS.AUTOPRE_CH2
    +.Pq Event 63H , Umask 20H
    +Counts the number of times a read CAS command was issued on DRAM channel 2
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_WRITE_CAS.CH0
    +.Pq Event 64H , Umask 01H
    +Counts the number of times a write CAS command was issued on DRAM channel 0.
    +.It Li DRAM_WRITE_CAS.AUTOPRE_CH0
    +.Pq Event 64H , Umask 02H
    +Counts the number of times a write CAS command was issued on DRAM channel 0
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_WRITE_CAS.CH1
    +.Pq Event 64H , Umask 04H
    +Counts the number of times a write CAS command was issued on DRAM channel 1.
    +.It Li DRAM_WRITE_CAS.AUTOPRE_CH1
    +.Pq Event 64H , Umask 08H
    +Counts the number of times a write CAS command was issued on DRAM channel 1
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_WRITE_CAS.CH2
    +.Pq Event 64H , Umask 10H
    +Counts the number of times a write CAS command was issued on DRAM channel 2.
    +.It Li DRAM_WRITE_CAS.AUTOPRE_CH2
    +.Pq Event 64H , Umask 20H
    +Counts the number of times a write CAS command was issued on DRAM channel 2
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_REFRESH.CH0
    +.Pq Event 65H , Umask 01H
    +Counts number of DRAM channel 0 refresh commands. DRAM loses data content
    +over time. In order to keep correct data content, the data values have to be
    +refreshed periodically.
    +.It Li DRAM_REFRESH.CH1
    +.Pq Event 65H , Umask 02H
    +Counts number of DRAM channel 1 refresh commands. DRAM loses data content
    +over time. In order to keep correct data content, the data values have to be
    +refreshed periodically.
    +.It Li DRAM_REFRESH.CH2
    +.Pq Event 65H , Umask 04H
    +Counts number of DRAM channel 2 refresh commands. DRAM loses data content
    +over time. In order to keep correct data content, the data values have to be
    +refreshed periodically.
    +.It Li DRAM_PRE_ALL.CH0
    +.Pq Event 66H , Umask 01H
    +Counts number of DRAM Channel 0 precharge-all (PREALL) commands that close
    +all open pages in a rank. PREALL is issued when the DRAM needs to be
    +refreshed or needs to go into a power down mode.
    +.It Li DRAM_PRE_ALL.CH1
    +.Pq Event 66H , Umask 02H
    +Counts number of DRAM Channel 1 precharge-all (PREALL) commands that close
    +all open pages in a rank. PREALL is issued when the DRAM needs to be
    +refreshed or needs to go into a power down mode.
    +.It Li DRAM_PRE_ALL.CH2
    +.Pq Event 66H , Umask 04H
    +Counts number of DRAM Channel 2 precharge-all (PREALL) commands that close
    +all open pages in a rank. PREALL is issued when the DRAM needs to be
    +refreshed or needs to go into a power down mode.
    +.El
    +.Sh SEE ALSO
    +.Xr pmc 3 ,
    +.Xr pmc.atom 3 ,
    +.Xr pmc.core 3 ,
    +.Xr pmc.iaf 3 ,
    +.Xr pmc.ucf 3 ,
    +.Xr pmc.k7 3 ,
    +.Xr pmc.k8 3 ,
    +.Xr pmc.p4 3 ,
    +.Xr pmc.p5 3 ,
    +.Xr pmc.p6 3 ,
    +.Xr pmc.corei7 3 ,
    +.Xr pmc.westmere 3 ,
    +.Xr pmc.westmereuc 3 ,
    +.Xr pmc.tsc 3 ,
    +.Xr pmc_cpuinfo 3 ,
    +.Xr pmclog 3 ,
    +.Xr hwpmc 4
    +.Sh HISTORY
    +The
    +.Nm pmc
    +library first appeared in
    +.Fx 6.0 .
    +.Sh AUTHORS
    +The
    +.Lb libpmc
    +library was written by
    +.An "Joseph Koshy"
    +.Aq jkoshy@FreeBSD.org .
    diff --git a/lib/libpmc/pmc.ucf.3 b/lib/libpmc/pmc.ucf.3
    new file mode 100644
    index 00000000000..c8f2468cdf8
    --- /dev/null
    +++ b/lib/libpmc/pmc.ucf.3
    @@ -0,0 +1,115 @@
    +.\" Copyright (c) 2010 Fabien Thomas.  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 Joseph Koshy ``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 Joseph Koshy 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 March 30, 2010
    +.Os
    +.Dt PMC.UCF 3
    +.Sh NAME
    +.Nm pmc.ucf
    +.Nd measurement events for
    +.Tn Intel
    +uncore fixed function performance counters.
    +.Sh LIBRARY
    +.Lb libpmc
    +.Sh SYNOPSIS
    +.In pmc.h
    +.Sh DESCRIPTION
    +Each fixed-function PMC measures a specific hardware event.
    +The number of fixed-function PMCs implemented in a CPU can vary.
    +The number of fixed-function PMCs present can be determined at runtime
    +by using function
    +.Xr pmc_cpuinfo 3 .
    +.Pp
    +Intel uncore fixed-function PMCs are documented in
    +.Rs
    +.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
    +.%T "Volume 3B: System Programming Guide, Part 2"
    +.%N "Order Number: 253669-033US"
    +.%D December 2009
    +.%Q "Intel Corporation"
    +.Re
    +.Pp
    +.Ss PMC Capabilities
    +Fixed-function PMCs support the following capabilities:
    +.Bl -column "PMC_CAP_INTERRUPT" "Support"
    +.It Em Capability Ta Em Support
    +.It PMC_CAP_CASCADE Ta \&No
    +.It PMC_CAP_EDGE Ta \&No
    +.It PMC_CAP_INTERRUPT Ta \&No
    +.It PMC_CAP_INVERT Ta \&No
    +.It PMC_CAP_READ Ta Yes
    +.It PMC_CAP_PRECISE Ta \&No
    +.It PMC_CAP_SYSTEM Ta \&No
    +.It PMC_CAP_TAGGING Ta \&No
    +.It PMC_CAP_THRESHOLD Ta \&No
    +.It PMC_CAP_USER Ta \&No
    +.It PMC_CAP_WRITE Ta Yes
    +.El
    +.Ss Class Name Prefix
    +These PMCs are named using a class name prefix of
    +.Dq Li ucf- .
    +.Ss Event Specifiers (Fixed Function PMCs)
    +The fixed function PMCs are selectable using the following
    +event names:
    +.Bl -tag -width indent
    +.It Li UCLOCK
    +.Pq Fixed Function Counter 0
    +The fixed-function uncore counter increments at the rate of the U-clock.
    +The frequency of the uncore clock domain can be determined from the uncore
    +clock ratio which is available in the PCI configuration space register at
    +offset C0H under device number 0 and Function 0.
    +.El
    +.Sh SEE ALSO
    +.Xr pmc 3 ,
    +.Xr pmc.atom 3 ,
    +.Xr pmc.core 3 ,
    +.Xr pmc.core2 3 ,
    +.Xr pmc.iaf 3 ,
    +.Xr pmc.k7 3 ,
    +.Xr pmc.k8 3 ,
    +.Xr pmc.p4 3 ,
    +.Xr pmc.p5 3 ,
    +.Xr pmc.p6 3 ,
    +.Xr pmc.corei7 3 ,
    +.Xr pmc.corei7uc 3 ,
    +.Xr pmc.westmere 3 ,
    +.Xr pmc.westmereuc 3 ,
    +.Xr pmc.tsc 3 ,
    +.Xr pmc_cpuinfo 3 ,
    +.Xr pmclog 3 ,
    +.Xr hwpmc 4
    +.Sh HISTORY
    +The
    +.Nm pmc
    +library first appeared in
    +.Fx 6.0 .
    +.Sh AUTHORS
    +The
    +.Lb libpmc
    +library was written by
    +.An "Joseph Koshy"
    +.Aq jkoshy@FreeBSD.org .
    +
    +
    diff --git a/lib/libpmc/pmc.westmere.3 b/lib/libpmc/pmc.westmere.3
    new file mode 100644
    index 00000000000..0b87e50230a
    --- /dev/null
    +++ b/lib/libpmc/pmc.westmere.3
    @@ -0,0 +1,1329 @@
    +.\" Copyright (c) 2010 Fabien Thomas.  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 Joseph Koshy ``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 Joseph Koshy 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 March 24, 2010
    +.Os
    +.Dt PMC.WESTMERE 3
    +.Sh NAME
    +.Nm pmc.westmere
    +.Nd measurement events for
    +.Tn Intel
    +.Tn Westmere
    +family CPUs
    +.Sh LIBRARY
    +.Lb libpmc
    +.Sh SYNOPSIS
    +.In pmc.h
    +.Sh DESCRIPTION
    +.Tn Intel
    +.Tn "Westmere"
    +CPUs contain PMCs conforming to version 2 of the
    +.Tn Intel
    +performance measurement architecture.
    +These CPUs may contain up to three classes of PMCs:
    +.Bl -tag -width "Li PMC_CLASS_IAP"
    +.It Li PMC_CLASS_IAF
    +Fixed-function counters that count only one hardware event per counter.
    +.It Li PMC_CLASS_IAP
    +Programmable counters that may be configured to count one of a defined
    +set of hardware events.
    +.El
    +.Pp
    +The number of PMCs available in each class and their widths need to be
    +determined at run time by calling
    +.Xr pmc_cpuinfo 3 .
    +.Pp
    +Intel Westmere PMCs are documented in
    +.Rs
    +.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
    +.%T "Volume 3B: System Programming Guide, Part 2"
    +.%N "Order Number: 253669-033US"
    +.%D December 2009
    +.%Q "Intel Corporation"
    +.Re
    +.Ss WESTMERE FIXED FUNCTION PMCS
    +These PMCs and their supported events are documented in
    +.Xr pmc.iaf 3 .
    +.Ss WESTMERE PROGRAMMABLE PMCS
    +The programmable PMCs support the following capabilities:
    +.Bl -column "PMC_CAP_INTERRUPT" "Support"
    +.It Em Capability Ta Em Support
    +.It PMC_CAP_CASCADE Ta \&No
    +.It PMC_CAP_EDGE Ta Yes
    +.It PMC_CAP_INTERRUPT Ta Yes
    +.It PMC_CAP_INVERT Ta Yes
    +.It PMC_CAP_READ Ta Yes
    +.It PMC_CAP_PRECISE Ta \&No
    +.It PMC_CAP_SYSTEM Ta Yes
    +.It PMC_CAP_TAGGING Ta \&No
    +.It PMC_CAP_THRESHOLD Ta Yes
    +.It PMC_CAP_USER Ta Yes
    +.It PMC_CAP_WRITE Ta Yes
    +.El
    +.Ss Event Qualifiers
    +Event specifiers for these PMCs support the following common
    +qualifiers:
    +.Bl -tag -width indent
    +.It Li rsp= Ns Ar value
    +Configure the Off-core Response bits.
    +.Bl -tag -width indent
    +.It Li DMND_DATA_RD
    +Counts the number of demand and DCU prefetch data reads of full
    +and partial cachelines as well as demand data page table entry
    +cacheline reads. Does not count L2 data read prefetches or
    +instruction fetches.
    +.It Li DMND_RFO
    +Counts the number of demand and DCU prefetch reads for ownership
    +(RFO) requests generated by a write to data cacheline. Does not
    +count L2 RFO.
    +.It Li DMND_IFETCH
    +Counts the number of demand and DCU prefetch instruction cacheline
    +reads. Does not count L2 code read prefetches.
    +WB
    +Counts the number of writeback (modified to exclusive) transactions.
    +.It Li PF_DATA_RD
    +Counts the number of data cacheline reads generated by L2 prefetchers.
    +.It Li PF_RFO
    +Counts the number of RFO requests generated by L2 prefetchers.
    +.It Li PF_IFETCH
    +Counts the number of code reads generated by L2 prefetchers.
    +.It Li OTHER
    +Counts one of the following transaction types, including L3 invalidate,
    +I/O, full or partial writes, WC or non-temporal stores, CLFLUSH, Fences,
    +lock, unlock, split lock.
    +.It Li UNCORE_HIT
    +L3 Hit: local or remote home requests that hit L3 cache in the uncore
    +with no coherency actions required (snooping).
    +.It Li OTHER_CORE_HIT_SNP
    +L3 Hit: local or remote home requests that hit L3 cache in the uncore
    +and was serviced by another core with a cross core snoop where no modified
    +copies were found (clean).
    +.It Li OTHER_CORE_HITM
    +L3 Hit: local or remote home requests that hit L3 cache in the uncore
    +and was serviced by another core with a cross core snoop where modified
    +copies were found (HITM).
    +.It Li REMOTE_CACHE_FWD
    +L3 Miss: local homed requests that missed the L3 cache and was serviced
    +by forwarded data following a cross package snoop where no modified
    +copies found. (Remote home requests are not counted)
    +.It Li REMOTE_DRAM
    +L3 Miss: remote home requests that missed the L3 cache and were serviced
    +by remote DRAM.
    +.It Li LOCAL_DRAM
    +L3 Miss: local home requests that missed the L3 cache and were serviced
    +by local DRAM.
    +.It Li NON_DRAM
    +Non-DRAM requests that were serviced by IOH.
    +.El
    +.It Li cmask= Ns Ar value
    +Configure the PMC to increment only if the number of configured
    +events measured in a cycle is greater than or equal to
    +.Ar value .
    +.It Li edge
    +Configure the PMC to count the number of de-asserted to asserted
    +transitions of the conditions expressed by the other qualifiers.
    +If specified, the counter will increment only once whenever a
    +condition becomes true, irrespective of the number of clocks during
    +which the condition remains true.
    +.It Li inv
    +Invert the sense of comparison when the
    +.Dq Li cmask
    +qualifier is present, making the counter increment when the number of
    +events per cycle is less than the value specified by the
    +.Dq Li cmask
    +qualifier.
    +.It Li os
    +Configure the PMC to count events happening at processor privilege
    +level 0.
    +.It Li usr
    +Configure the PMC to count events occurring at privilege levels 1, 2
    +or 3.
    +.El
    +.Pp
    +If neither of the
    +.Dq Li os
    +or
    +.Dq Li usr
    +qualifiers are specified, the default is to enable both.
    +.Ss Event Specifiers (Programmable PMCs)
    +Westmere programmable PMCs support the following events:
    +.Bl -tag -width indent
    +.It Li LOAD_BLOCK.OVERLAP_STORE
    +.Pq Event 03H , Umask 02H
    +Loads that partially overlap an earlier store
    +.It Li SB_DRAIN.ANY
    +.Pq Event 04H , Umask 07H
    +All Store buffer stall cycles
    +.It Li MISALIGN_MEMORY.STORE
    +.Pq Event 05H , Umask 02H
    +All store referenced with misaligned address
    +.It Li STORE_BLOCKS.AT_RET
    +.Pq Event 06H , Umask 04H
    +Counts number of loads delayed with at-Retirement block code. The following
    +loads need to be executed at retirement and wait for all senior stores on
    +the same thread to be drained: load splitting across 4K boundary (page
    +split), load accessing uncacheable (UC or USWC) memory, load lock, and load
    +with page table in UC or USWC memory region.
    +.It Li STORE_BLOCKS.L1D_BLOCK
    +.Pq Event 06H , Umask 08H
    +Cacheable loads delayed with L1D block code
    +.It Li PARTIAL_ADDRESS_ALIAS
    +.Pq Event 07H , Umask 01H
    +Counts false dependency due to partial address aliasing
    +.It Li DTLB_LOAD_MISSES.ANY
    +.Pq Event 08H , Umask 01H
    +Counts all load misses that cause a page walk
    +.It Li DTLB_LOAD_MISSES.WALK_COMPLETED
    +.Pq Event 08H , Umask 02H
    +Counts number of completed page walks due to load miss in the STLB.
    +.It Li DTLB_LOAD_MISSES.WALK_CYCLES
    +.Pq Event 08H , Umask 04H
    +Cycles PMH is busy with a page walk due to a load miss in the STLB.
    +.It Li DTLB_LOAD_MISSES.STLB_HIT
    +.Pq Event 08H , Umask 10H
    +Number of cache load STLB hits
    +.It Li DTLB_LOAD_MISSES.PDE_MISS
    +.Pq Event 08H , Umask 20H
    +Number of DTLB cache load misses where the low part of the linear to
    +physical address translation was missed.
    +.It Li MEM_INST_RETIRED.LOADS
    +.Pq Event 0BH , Umask 01H
    +Counts the number of instructions with an architecturally-visible store
    +retired on the architected path.
    +In conjunction with ld_lat facility
    +.It Li MEM_INST_RETIRED.STORES
    +.Pq Event 0BH , Umask 02H
    +Counts the number of instructions with an architecturally-visible store
    +retired on the architected path.
    +In conjunction with ld_lat facility
    +.It Li MEM_INST_RETIRED.LATENCY_ABOVE_THRESHOLD
    +.Pq Event 0BH , Umask 10H
    +Counts the number of instructions exceeding the latency specified with
    +ld_lat facility.
    +In conjunction with ld_lat facility
    +.It Li MEM_STORE_RETIRED.DTLB_MISS
    +.Pq Event 0CH , Umask 01H
    +The event counts the number of retired stores that missed the DTLB. The DTLB
    +miss is not counted if the store operation causes a fault. Does not counter
    +prefetches. Counts both primary and secondary misses to the TLB
    +.It Li UOPS_ISSUED.ANY
    +.Pq Event 0EH , Umask 01H
    +Counts the number of Uops issued by the Register Allocation Table to the
    +Reservation Station, i.e. the UOPs issued from the front end to the back
    +end.
    +.It Li UOPS_ISSUED.STALLED_CYCLES
    +.Pq Event 0EH , Umask 01H
    +Counts the number of cycles no Uops issued by the Register Allocation Table
    +to the Reservation Station, i.e. the UOPs issued from the front end to the
    +back end.
    +set invert=1, cmask = 1
    +.It Li UOPS_ISSUED.FUSED
    +.Pq Event 0EH , Umask 02H
    +Counts the number of fused Uops that were issued from the Register
    +Allocation Table to the Reservation Station.
    +.It Li MEM_UNCORE_RETIRED.LOCAL_HITM
    +.Pq Event 0FH , Umask 02H
    +Load instructions retired that HIT modified data in sibling core (Precise
    +Event)
    +.It Li MEM_UNCORE_RETIRED.LOCAL_DRAM_AND_REMOTE_CACHE_HIT
    +.Pq Event 0FH , Umask 08H
    +Load instructions retired local dram and remote cache HIT data sources
    +(Precise Event)
    +.It Li MEM_UNCORE_RETIRED.LOCAL_DRAM
    +.Pq Event 0FH , Umask 10H
    +Load instructions retired with a data source of local DRAM or locally homed
    +remote cache HITM (Precise Event)
    +.It Li MEM_UNCORE_RETIRED.REMOTE_DRAM
    +.Pq Event 0FH , Umask 20H
    +Load instructions retired remote DRAM and remote home-remote cache HITM
    +(Precise Event)
    +.It Li MEM_UNCORE_RETIRED.UNCACHEABLE
    +.Pq Event 0FH , Umask 80H
    +Load instructions retired I/O (Precise Event)
    +.It Li FP_COMP_OPS_EXE.X87
    +.Pq Event 10H , Umask 01H
    +Counts the number of FP Computational Uops Executed. The number of FADD,
    +FSUB, FCOM, FMULs, integer MULsand IMULs, FDIVs, FPREMs, FSQRTS, integer
    +DIVs, and IDIVs. This event does not distinguish an FADD used in the middle
    +of a transcendental flow from a separate FADD instruction.
    +.It Li FP_COMP_OPS_EXE.MMX
    +.Pq Event 10H , Umask 02H
    +Counts number of MMX Uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_FP
    +.Pq Event 10H , Umask 04H
    +Counts number of SSE and SSE2 FP uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE2_INTEGER
    +.Pq Event 10H , Umask 08H
    +Counts number of SSE2 integer uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_FP_PACKED
    +.Pq Event 10H , Umask 10H
    +Counts number of SSE FP packed uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_FP_SCALAR
    +.Pq Event 10H , Umask 20H
    +Counts number of SSE FP scalar uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_SINGLE_PRECISION
    +.Pq Event 10H , Umask 40H
    +Counts number of SSE* FP single precision uops executed.
    +.It Li FP_COMP_OPS_EXE.SSE_DOUBLE_PRECISION
    +.Pq Event 10H , Umask 80H
    +Counts number of SSE* FP double precision uops executed.
    +.It Li SIMD_INT_128.PACKED_MPY
    +.Pq Event 12H , Umask 01H
    +Counts number of 128 bit SIMD integer multiply operations.
    +.It Li SIMD_INT_128.PACKED_SHIFT
    +.Pq Event 12H , Umask 02H
    +Counts number of 128 bit SIMD integer shift operations.
    +.It Li SIMD_INT_128.PACK
    +.Pq Event 12H , Umask 04H
    +Counts number of 128 bit SIMD integer pack operations.
    +.It Li SIMD_INT_128.UNPACK
    +.Pq Event 12H , Umask 08H
    +Counts number of 128 bit SIMD integer unpack operations.
    +.It Li SIMD_INT_128.PACKED_LOGICAL
    +.Pq Event 12H , Umask 10H
    +Counts number of 128 bit SIMD integer logical operations.
    +.It Li SIMD_INT_128.PACKED_ARITH
    +.Pq Event 12H , Umask 20H
    +Counts number of 128 bit SIMD integer arithmetic operations.
    +.It Li SIMD_INT_128.SHUFFLE_MOVE
    +.Pq Event 12H , Umask 40H
    +Counts number of 128 bit SIMD integer shuffle and move operations.
    +.It Li LOAD_DISPATCH.RS
    +.Pq Event 13H , Umask 01H
    +Counts number of loads dispatched from the Reservation Station that bypass
    +the Memory Order Buffer.
    +.It Li LOAD_DISPATCH.RS_DELAYED
    +.Pq Event 13H , Umask 02H
    +Counts the number of delayed RS dispatches at the stage latch. If an RS
    +dispatch can not bypass to LB, it has another chance to dispatch from the
    +one-cycle delayed staging latch before it is written into the LB.
    +.It Li LOAD_DISPATCH.MOB
    +.Pq Event 13H , Umask 04H
    +Counts the number of loads dispatched from the Reservation Station to the
    +Memory Order Buffer.
    +.It Li LOAD_DISPATCH.ANY
    +.Pq Event 13H , Umask 07H
    +Counts all loads dispatched from the Reservation Station.
    +.It Li ARITH.CYCLES_DIV_BUSY
    +.Pq Event 14H , Umask 01H
    +Counts the number of cycles the divider is busy executing divide or square
    +root operations. The divide can be integer, X87 or Streaming SIMD Extensions
    +(SSE). The square root operation can be either X87 or SSE.
    +Set 'edge =1, invert=1, cmask=1' to count the number of divides.
    +Count may be incorrect When SMT is on
    +.It Li ARITH.MUL
    +.Pq Event 14H , Umask 02H
    +Counts the number of multiply operations executed. This includes integer as
    +well as floating point multiply operations but excludes DPPS mul and MPSAD.
    +Count may be incorrect When SMT is on
    +.It Li INST_QUEUE_WRITES
    +.Pq Event 17H , Umask 01H
    +Counts the number of instructions written into the instruction queue every
    +cycle.
    +.It Li INST_DECODED.DEC0
    +.Pq Event 18H , Umask 01H
    +Counts number of instructions that require decoder 0 to be decoded. Usually,
    +this means that the instruction maps to more than 1 uop
    +.It Li TWO_UOP_INSTS_DECODED
    +.Pq Event 19H , Umask 01H
    +An instruction that generates two uops was decoded
    +.It Li INST_QUEUE_WRITE_CYCLES
    +.Pq Event 1EH , Umask 01H
    +This event counts the number of cycles during which instructions are written
    +to the instruction queue. Dividing this counter by the number of
    +instructions written to the instruction queue (INST_QUEUE_WRITES) yields the
    +average number of instructions decoded each cycle. If this number is less
    +than four and the pipe stalls, this indicates that the decoder is failing to
    +decode enough instructions per cycle to sustain the 4-wide pipeline.
    +If SSE* instructions that are 6 bytes or longer arrive one after another,
    +then front end throughput may limit execution speed. In such case,
    +.It Li LSD_OVERFLOW
    +.Pq Event 20H , Umask 01H
    +Number of loops that can not stream from the instruction queue.
    +.It Li L2_RQSTS.LD_HIT
    +.Pq Event 24H , Umask 01H
    +Counts number of loads that hit the L2 cache. L2 loads include both L1D
    +demand misses as well as L1D prefetches. L2 loads can be rejected for
    +various reasons. Only non rejected loads are counted.
    +.It Li L2_RQSTS.LD_MISS
    +.Pq Event 24H , Umask 02H
    +Counts the number of loads that miss the L2 cache. L2 loads include both L1D
    +demand misses as well as L1D prefetches.
    +.It Li L2_RQSTS.LOADS
    +.Pq Event 24H , Umask 03H
    +Counts all L2 load requests. L2 loads include both L1D demand misses as well
    +as L1D prefetches.
    +.It Li L2_RQSTS.RFO_HIT
    +.Pq Event 24H , Umask 04H
    +Counts the number of store RFO requests that hit the L2 cache. L2 RFO
    +requests include both L1D demand RFO misses as well as L1D RFO prefetches.
    +Count includes WC memory requests, where the data is not fetched but the
    +permission to write the line is required.
    +.It Li L2_RQSTS.RFO_MISS
    +.Pq Event 24H , Umask 08H
    +Counts the number of store RFO requests that miss the L2 cache. L2 RFO
    +requests include both L1D demand RFO misses as well as L1D RFO prefetches.
    +.It Li L2_RQSTS.RFOS
    +.Pq Event 24H , Umask 0CH
    +Counts all L2 store RFO requests. L2 RFO requests include both L1D demand
    +RFO misses as well as L1D RFO prefetches..
    +.It Li L2_RQSTS.IFETCH_HIT
    +.Pq Event 24H , Umask 10H
    +Counts number of instruction fetches that hit the L2 cache. L2 instruction
    +fetches include both L1I demand misses as well as L1I instruction
    +prefetches.
    +.It Li L2_RQSTS.IFETCH_MISS
    +.Pq Event 24H , Umask 20H
    +Counts number of instruction fetches that miss the L2 cache. L2 instruction
    +fetches include both L1I demand misses as well as L1I instruction
    +prefetches.
    +.It Li L2_RQSTS.IFETCHES
    +.Pq Event 24H , Umask 30H
    +Counts all instruction fetches. L2 instruction fetches include both L1I
    +demand misses as well as L1I instruction prefetches.
    +.It Li L2_RQSTS.PREFETCH_HIT
    +.Pq Event 24H , Umask 40H
    +Counts L2 prefetch hits for both code and data.
    +.It Li L2_RQSTS.PREFETCH_MISS
    +.Pq Event 24H , Umask 80H
    +Counts L2 prefetch misses for both code and data.
    +.It Li L2_RQSTS.PREFETCHES
    +.Pq Event 24H , Umask C0H
    +Counts all L2 prefetches for both code and data.
    +.It Li L2_RQSTS.MISS
    +.Pq Event 24H , Umask AAH
    +Counts all L2 misses for both code and data.
    +.It Li L2_RQSTS.REFERENCES
    +.Pq Event 24H , Umask FFH
    +Counts all L2 requests for both code and data.
    +.It Li L2_DATA_RQSTS.DEMAND.I_STATE
    +.Pq Event 26H , Umask 01H
    +Counts number of L2 data demand loads where the cache line to be loaded is
    +in the I (invalid) state, i.e. a cache miss. L2 demand loads are both L1D
    +demand misses and L1D prefetches.
    +.It Li L2_DATA_RQSTS.DEMAND.S_STATE
    +.Pq Event 26H , Umask 02H
    +Counts number of L2 data demand loads where the cache line to be loaded is
    +in the S (shared) state. L2 demand loads are both L1D demand misses and L1D
    +prefetches.
    +.It Li L2_DATA_RQSTS.DEMAND.E_STATE
    +.Pq Event 26H , Umask 04H
    +Counts number of L2 data demand loads where the cache line to be loaded is
    +in the E (exclusive) state. L2 demand loads are both L1D demand misses and
    +L1D prefetches.
    +.It Li L2_DATA_RQSTS.DEMAND.M_STATE
    +.Pq Event 26H , Umask 08H
    +Counts number of L2 data demand loads where the cache line to be loaded is
    +in the M (modified) state. L2 demand loads are both L1D demand misses and
    +L1D prefetches.
    +.It Li L2_DATA_RQSTS.DEMAND.MESI
    +.Pq Event 26H , Umask 0FH
    +Counts all L2 data demand requests. L2 demand loads are both L1D demand
    +misses and L1D prefetches.
    +.It Li L2_DATA_RQSTS.PREFETCH.I_STATE
    +.Pq Event 26H , Umask 10H
    +Counts number of L2 prefetch data loads where the cache line to be loaded is
    +in the I (invalid) state, i.e. a cache miss.
    +.It Li L2_DATA_RQSTS.PREFETCH.S_STATE
    +.Pq Event 26H , Umask 20H
    +Counts number of L2 prefetch data loads where the cache line to be loaded is
    +in the S (shared) state. A prefetch RFO will miss on an S state line, while
    +a prefetch read will hit on an S state line.
    +.It Li L2_DATA_RQSTS.PREFETCH.E_STATE
    +.Pq Event 26H , Umask 40H
    +Counts number of L2 prefetch data loads where the cache line to be loaded is
    +in the E (exclusive) state.
    +.It Li L2_DATA_RQSTS.PREFETCH.M_STATE
    +.Pq Event 26H , Umask 80H
    +Counts number of L2 prefetch data loads where the cache line to be loaded is
    +in the M (modified) state.
    +.It Li L2_DATA_RQSTS.PREFETCH.MESI
    +.Pq Event 26H , Umask F0H
    +Counts all L2 prefetch requests.
    +.It Li L2_DATA_RQSTS.ANY
    +.Pq Event 26H , Umask FFH
    +Counts all L2 data requests.
    +.It Li L2_WRITE.RFO.I_STATE
    +.Pq Event 27H , Umask 01H
    +Counts number of L2 demand store RFO requests where the cache line to be
    +loaded is in the I (invalid) state, i.e, a cache miss. The L1D prefetcher
    +does not issue a RFO prefetch.
    +This is a demand RFO request
    +.It Li L2_WRITE.RFO.S_STATE
    +.Pq Event 27H , Umask 02H
    +Counts number of L2 store RFO requests where the cache line to be loaded is
    +in the S (shared) state. The L1D prefetcher does not issue a RFO prefetch,.
    +This is a demand RFO request
    +.It Li L2_WRITE.RFO.M_STATE
    +.Pq Event 27H , Umask 08H
    +Counts number of L2 store RFO requests where the cache line to be loaded is
    +in the M (modified) state. The L1D prefetcher does not issue a RFO prefetch.
    +This is a demand RFO request
    +.It Li L2_WRITE.RFO.HIT
    +.Pq Event 27H , Umask 0EH
    +Counts number of L2 store RFO requests where the cache line to be loaded is
    +in either the S, E or M states. The L1D prefetcher does not issue a RFO
    +prefetch.
    +This is a demand RFO request
    +.It Li L2_WRITE.RFO.MESI
    +.Pq Event 27H , Umask 0FH
    +Counts all L2 store RFO requests.The L1D prefetcher does not issue a RFO
    +prefetch.
    +This is a demand RFO request
    +.It Li L2_WRITE.LOCK.I_STATE
    +.Pq Event 27H , Umask 10H
    +Counts number of L2 demand lock RFO requests where the cache line to be
    +loaded is in the I (invalid) state, i.e. a cache miss.
    +.It Li L2_WRITE.LOCK.S_STATE
    +.Pq Event 27H , Umask 20H
    +Counts number of L2 lock RFO requests where the cache line to be loaded is
    +in the S (shared) state.
    +.It Li L2_WRITE.LOCK.E_STATE
    +.Pq Event 27H , Umask 40H
    +Counts number of L2 demand lock RFO requests where the cache line to be
    +loaded is in the E (exclusive) state.
    +.It Li L2_WRITE.LOCK.M_STATE
    +.Pq Event 27H , Umask 80H
    +Counts number of L2 demand lock RFO requests where the cache line to be
    +loaded is in the M (modified) state.
    +.It Li L2_WRITE.LOCK.HIT
    +.Pq Event 27H , Umask E0H
    +Counts number of L2 demand lock RFO requests where the cache line to be
    +loaded is in either the S, E, or M state.
    +.It Li L2_WRITE.LOCK.MESI
    +.Pq Event 27H , Umask F0H
    +Counts all L2 demand lock RFO requests.
    +.It Li L1D_WB_L2.I_STATE
    +.Pq Event 28H , Umask 01H
    +Counts number of L1 writebacks to the L2 where the cache line to be written
    +is in the I (invalid) state, i.e. a cache miss.
    +.It Li L1D_WB_L2.S_STATE
    +.Pq Event 28H , Umask 02H
    +Counts number of L1 writebacks to the L2 where the cache line to be written
    +is in the S state.
    +.It Li L1D_WB_L2.E_STATE
    +.Pq Event 28H , Umask 04H
    +Counts number of L1 writebacks to the L2 where the cache line to be written
    +is in the E (exclusive) state.
    +.It Li L1D_WB_L2.M_STATE
    +.Pq Event 28H , Umask 08H
    +Counts number of L1 writebacks to the L2 where the cache line to be written
    +is in the M (modified) state.
    +.It Li L1D_WB_L2.MESI
    +.Pq Event 28H , Umask 0FH
    +Counts all L1 writebacks to the L2.
    +.It Li L3_LAT_CACHE.REFERENCE
    +.Pq Event 2EH , Umask 02H
    +Counts uncore Last Level Cache references. Because cache hierarchy, cache
    +sizes and other implementation-specific characteristics; value comparison to
    +estimate performance differences is not recommended.
    +see Table A-1
    +.It Li L3_LAT_CACHE.MISS
    +.Pq Event 2EH , Umask 01H
    +Counts uncore Last Level Cache misses. Because cache hierarchy, cache sizes
    +and other implementation-specific characteristics; value comparison to
    +estimate performance differences is not recommended.
    +see Table A-1
    +.It Li CPU_CLK_UNHALTED.THREAD_P
    +.Pq Event 3CH , Umask 00H
    +Counts the number of thread cycles while the thread is not in a halt state.
    +The thread enters the halt state when it is running the HLT instruction. The
    +core frequency may change from time to time due to power or thermal
    +throttling.
    +see Table A-1
    +.It Li CPU_CLK_UNHALTED.REF_P
    +.Pq Event 3CH , Umask 01H
    +Increments at the frequency of TSC when not halted.
    +see Table A-1
    +.It Li DTLB_MISSES.ANY
    +.Pq Event 49H , Umask 01H
    +Counts the number of misses in the STLB which causes a page walk.
    +.It Li DTLB_MISSES.WALK_COMPLETED
    +.Pq Event 49H , Umask 02H
    +Counts number of misses in the STLB which resulted in a completed page walk.
    +.It Li DTLB_MISSES.WALK_CYCLES
    +.Pq Event 49H , Umask 04H
    +Counts cycles of page walk due to misses in the STLB.
    +.It Li DTLB_MISSES.STLB_HIT
    +.Pq Event 49H , Umask 10H
    +Counts the number of DTLB first level misses that hit in the second level
    +TLB. This event is only relevant if the core contains multiple DTLB levels.
    +.It Li DTLB_MISSES.LARGE_WALK_COMPLETED
    +.Pq Event 49H , Umask 80H
    +Counts number of completed large page walks due to misses in the STLB.
    +.It Li LOAD_HIT_PRE
    +.Pq Event 4CH , Umask 01H
    +Counts load operations sent to the L1 data cache while a previous SSE
    +prefetch instruction to the same cache line has started prefetching but has
    +not yet finished.
    +.It Li L1D_PREFETCH.REQUESTS
    +.Pq Event 4EH , Umask 01H
    +Counts number of hardware prefetch requests dispatched out of the prefetch
    +FIFO.
    +.It Li L1D_PREFETCH.MISS
    +.Pq Event 4EH , Umask 02H
    +Counts number of hardware prefetch requests that miss the L1D. There are two
    +prefetchers in the L1D. A streamer, which predicts lines sequentially after
    +this one should be fetched, and the IP prefetcher that remembers access
    +patterns for the current instruction. The streamer prefetcher stops on an
    +L1D hit, while the IP prefetcher does not.
    +.It Li L1D_PREFETCH.TRIGGERS
    +.Pq Event 4EH , Umask 04H
    +Counts number of prefetch requests triggered by the Finite State Machine and
    +pushed into the prefetch FIFO. Some of the prefetch requests are dropped due
    +to overwrites or competition between the IP index prefetcher and streamer
    +prefetcher. The prefetch FIFO contains 4 entries.
    +.It Li EPT.WALK_CYCLES
    +.Pq Event 4FH , Umask 10H
    +Counts Extended Page walk cycles.
    +.It Li L1D.REPL
    +.Pq Event 51H , Umask 01H
    +Counts the number of lines brought into the L1 data cache.
    +Counter 0, 1 only
    +.It Li L1D.M_REPL
    +.Pq Event 51H , Umask 02H
    +Counts the number of modified lines brought into the L1 data cache.
    +Counter 0, 1 only
    +.It Li L1D.M_EVICT
    +.Pq Event 51H , Umask 04H
    +Counts the number of modified lines evicted from the L1 data cache due to
    +replacement.
    +Counter 0, 1 only
    +.It Li L1D.M_SNOOP_EVICT
    +.Pq Event 51H , Umask 08H
    +Counts the number of modified lines evicted from the L1 data cache due to
    +snoop HITM intervention.
    +Counter 0, 1 only
    +.It Li L1D_CACHE_PREFETCH_LOCK_FB_HIT
    +.Pq Event 52H , Umask 01H
    +Counts the number of cacheable load lock speculated instructions accepted
    +into the fill buffer.
    +.It Li L1D_CACHE_LOCK_FB_HIT
    +.Pq Event 53H , Umask 01H
    +Counts the number of cacheable load lock speculated or retired instructions
    +accepted into the fill buffer.
    +.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_DATA
    +.Pq Event 60H , Umask 01H
    +Counts weighted cycles of offcore demand data read requests. Does not
    +include L2 prefetch requests.
    +counter 0
    +.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.READ_CODE
    +.Pq Event 60H , Umask 02H
    +Counts weighted cycles of offcore demand code read requests. Does not
    +include L2 prefetch requests.
    +counter 0
    +.It Li OFFCORE_REQUESTS_OUTSTANDING.DEMAND.RFO
    +.Pq Event 60H , Umask 04H
    +Counts weighted cycles of offcore demand RFO requests. Does not include L2
    +prefetch requests.
    +counter 0
    +.It Li OFFCORE_REQUESTS_OUTSTANDING.ANY.READ
    +.Pq Event 60H , Umask 08H
    +Counts weighted cycles of offcore read requests of any kind. Include L2
    +prefetch requests.
    +counter 0
    +.It Li CACHE_LOCK_CYCLES.L1D_L2
    +.Pq Event 63H , Umask 01H
    +Cycle count during which the L1D and L2 are locked. A lock is asserted when
    +there is a locked memory access, due to uncacheable memory, a locked
    +operation that spans two cache lines, or a page walk from an uncacheable
    +page table.
    +Counter 0, 1 only. L1D and L2 locks have a very high performance penalty and
    +it is highly recommended to avoid such accesses.
    +.It Li CACHE_LOCK_CYCLES.L1D
    +.Pq Event 63H , Umask 02H
    +Counts the number of cycles that cacheline in the L1 data cache unit is
    +locked.
    +Counter 0, 1 only.
    +.It Li IO_TRANSACTIONS
    +.Pq Event 6CH , Umask 01H
    +Counts the number of completed I/O transactions.
    +.It Li L1I.HITS
    +.Pq Event 80H , Umask 01H
    +Counts all instruction fetches that hit the L1 instruction cache.
    +.It Li L1I.MISSES
    +.Pq Event 80H , Umask 02H
    +Counts all instruction fetches that miss the L1I cache. This includes
    +instruction cache misses, streaming buffer misses, victim cache misses and
    +uncacheable fetches. An instruction fetch miss is counted only once and not
    +once for every cycle it is outstanding.
    +.It Li L1I.READS
    +.Pq Event 80H , Umask 03H
    +Counts all instruction fetches, including uncacheable fetches that bypass
    +the L1I.
    +.It Li L1I.CYCLES_STALLED
    +.Pq Event 80H , Umask 04H
    +Cycle counts for which an instruction fetch stalls due to a L1I cache miss,
    +ITLB miss or ITLB fault.
    +.It Li LARGE_ITLB.HIT
    +.Pq Event 82H , Umask 01H
    +Counts number of large ITLB hits.
    +.It Li ITLB_MISSES.ANY
    +.Pq Event 85H , Umask 01H
    +Counts the number of misses in all levels of the ITLB which causes a page
    +walk.
    +.It Li ITLB_MISSES.WALK_COMPLETED
    +.Pq Event 85H , Umask 02H
    +Counts number of misses in all levels of the ITLB which resulted in a
    +completed page walk.
    +.It Li ITLB_MISSES.WALK_CYCLES
    +.Pq Event 85H , Umask 04H
    +Counts ITLB miss page walk cycles.
    +.It Li ITLB_MISSES.LARGE_WALK_COMPLETED
    +.Pq Event 85H , Umask 80H
    +Counts number of completed large page walks due to misses in the STLB.
    +.It Li ILD_STALL.LCP
    +.Pq Event 87H , Umask 01H
    +Cycles Instruction Length Decoder stalls due to length changing prefixes:
    +66, 67 or REX.W (for EM64T) instructions which change the length of the
    +decoded instruction.
    +.It Li ILD_STALL.MRU
    +.Pq Event 87H , Umask 02H
    +Instruction Length Decoder stall cycles due to Brand Prediction Unit (PBU)
    +Most Recently Used (MRU) bypass.
    +.It Li ILD_STALL.IQ_FULL
    +.Pq Event 87H , Umask 04H
    +Stall cycles due to a full instruction queue.
    +.It Li ILD_STALL.REGEN
    +.Pq Event 87H , Umask 08H
    +Counts the number of regen stalls.
    +.It Li ILD_STALL.ANY
    +.Pq Event 87H , Umask 0FH
    +Counts any cycles the Instruction Length Decoder is stalled.
    +.It Li BR_INST_EXEC.COND
    +.Pq Event 88H , Umask 01H
    +Counts the number of conditional near branch instructions executed, but not
    +necessarily retired.
    +.It Li BR_INST_EXEC.DIRECT
    +.Pq Event 88H , Umask 02H
    +Counts all unconditional near branch instructions excluding calls and
    +indirect branches.
    +.It Li BR_INST_EXEC.INDIRECT_NON_CALL
    +.Pq Event 88H , Umask 04H
    +Counts the number of executed indirect near branch instructions that are not
    +calls.
    +.It Li BR_INST_EXEC.NON_CALLS
    +.Pq Event 88H , Umask 07H
    +Counts all non call near branch instructions executed, but not necessarily
    +retired.
    +.It Li BR_INST_EXEC.RETURN_NEAR
    +.Pq Event 88H , Umask 08H
    +Counts indirect near branches that have a return mnemonic.
    +.It Li BR_INST_EXEC.DIRECT_NEAR_CALL
    +.Pq Event 88H , Umask 10H
    +Counts unconditional near call branch instructions, excluding non call
    +branch, executed.
    +.It Li BR_INST_EXEC.INDIRECT_NEAR_CALL
    +.Pq Event 88H , Umask 20H
    +Counts indirect near calls, including both register and memory indirect,
    +executed.
    +.It Li BR_INST_EXEC.NEAR_CALLS
    +.Pq Event 88H , Umask 30H
    +Counts all near call branches executed, but not necessarily retired.
    +.It Li BR_INST_EXEC.TAKEN
    +.Pq Event 88H , Umask 40H
    +Counts taken near branches executed, but not necessarily retired.
    +.It Li BR_INST_EXEC.ANY
    +.Pq Event 88H , Umask 7FH
    +Counts all near executed branches (not necessarily retired). This includes
    +only instructions and not micro-op branches. Frequent branching is not
    +necessarily a major performance issue. However frequent branch
    +mispredictions may be a problem.
    +.It Li BR_MISP_EXEC.COND
    +.Pq Event 89H , Umask 01H
    +Counts the number of mispredicted conditional near branch instructions
    +executed, but not necessarily retired.
    +.It Li BR_MISP_EXEC.DIRECT
    +.Pq Event 89H , Umask 02H
    +Counts mispredicted macro unconditional near branch instructions, excluding
    +calls and indirect branches (should always be 0).
    +.It Li BR_MISP_EXEC.INDIRECT_NON_CALL
    +.Pq Event 89H , Umask 04H
    +Counts the number of executed mispredicted indirect near branch instructions
    +that are not calls.
    +.It Li BR_MISP_EXEC.NON_CALLS
    +.Pq Event 89H , Umask 07H
    +Counts mispredicted non call near branches executed, but not necessarily
    +retired.
    +.It Li BR_MISP_EXEC.RETURN_NEAR
    +.Pq Event 89H , Umask 08H
    +Counts mispredicted indirect branches that have a rear return mnemonic.
    +.It Li BR_MISP_EXEC.DIRECT_NEAR_CALL
    +.Pq Event 89H , Umask 10H
    +Counts mispredicted non-indirect near calls executed, (should always be 0).
    +.It Li BR_MISP_EXEC.INDIRECT_NEAR_CALL
    +.Pq Event 89H , Umask 20H
    +Counts mispredicted indirect near calls exeucted, including both register
    +and memory indirect.
    +.It Li BR_MISP_EXEC.NEAR_CALLS
    +.Pq Event 89H , Umask 30H
    +Counts all mispredicted near call branches executed, but not necessarily
    +retired.
    +.It Li BR_MISP_EXEC.TAKEN
    +.Pq Event 89H , Umask 40H
    +Counts executed mispredicted near branches that are taken, but not
    +necessarily retired.
    +.It Li BR_MISP_EXEC.ANY
    +.Pq Event 89H , Umask 7FH
    +Counts the number of mispredicted near branch instructions that were
    +executed, but not necessarily retired.
    +.It Li RESOURCE_STALLS.ANY
    +.Pq Event A2H , Umask 01H
    +Counts the number of Allocator resource related stalls. Includes register
    +renaming buffer entries, memory buffer entries. In addition to resource
    +related stalls, this event counts some other events. Includes stalls arising
    +during branch misprediction recovery, such as if retirement of the
    +mispredicted branch is delayed and stalls arising while store buffer is
    +draining from synchronizing operations.
    +Does not include stalls due to SuperQ (off core) queue full, too many cache
    +misses, etc.
    +.It Li RESOURCE_STALLS.LOAD
    +.Pq Event A2H , Umask 02H
    +Counts the cycles of stall due to lack of load buffer for load operation.
    +.It Li RESOURCE_STALLS.RS_FULL
    +.Pq Event A2H , Umask 04H
    +This event counts the number of cycles when the number of instructions in
    +the pipeline waiting for execution reaches the limit the processor can
    +handle. A high count of this event indicates that there are long latency
    +operations in the pipe (possibly load and store operations that miss the L2
    +cache, or instructions dependent upon instructions further down the pipeline
    +that have yet to retire.
    +When RS is full, new instructions can not enter the reservation station and
    +start execution.
    +.It Li RESOURCE_STALLS.STORE
    +.Pq Event A2H , Umask 08H
    +This event counts the number of cycles that a resource related stall will
    +occur due to the number of store instructions reaching the limit of the
    +pipeline, (i.e. all store buffers are used). The stall ends when a store
    +instruction commits its data to the cache or memory.
    +.It Li RESOURCE_STALLS.ROB_FULL
    +.Pq Event A2H , Umask 10H
    +Counts the cycles of stall due to re- order buffer full.
    +.It Li RESOURCE_STALLS.FPCW
    +.Pq Event A2H , Umask 20H
    +Counts the number of cycles while execution was stalled due to writing the
    +floating-point unit (FPU) control word.
    +.It Li RESOURCE_STALLS.MXCSR
    +.Pq Event A2H , Umask 40H
    +Stalls due to the MXCSR register rename occurring to close to a previous
    +MXCSR rename. The MXCSR provides control and status for the MMX registers.
    +.It Li RESOURCE_STALLS.OTHER
    +.Pq Event A2H , Umask 80H
    +Counts the number of cycles while execution was stalled due to other
    +resource issues.
    +.It Li MACRO_INSTS.FUSIONS_DECODED
    +.Pq Event A6H , Umask 01H
    +Counts the number of instructions decoded that are macro-fused but not
    +necessarily executed or retired.
    +.It Li BACLEAR_FORCE_IQ
    +.Pq Event A7H , Umask 01H
    +Counts number of times a BACLEAR was forced by the Instruction Queue. The IQ
    +is also responsible for providing conditional branch prediciton direction
    +based on a static scheme and dynamic data provided by the L2 Branch
    +Prediction Unit. If the conditional branch target is not found in the Target
    +Array and the IQ predicts that the branch is taken, then the IQ will force
    +the Branch Address Calculator to issue a BACLEAR. Each BACLEAR asserted by
    +the BAC generates approximately an 8 cycle bubble in the instruction fetch
    +pipeline.
    +.It Li LSD.UOPS
    +.Pq Event A8H , Umask 01H
    +Counts the number of micro-ops delivered by loop stream detector
    +Use cmask=1 and invert to count cycles
    +.It Li ITLB_FLUSH
    +.Pq Event AEH , Umask 01H
    +Counts the number of ITLB flushes
    +.It Li OFFCORE_REQUESTS.DEMAND.READ_DATA
    +.Pq Event B0H , Umask 01H
    +Counts number of offcore demand data read requests. Does not count L2
    +prefetch requests.
    +.It Li OFFCORE_REQUESTS.DEMAND.READ_CODE
    +.Pq Event B0H , Umask 02H
    +Counts number of offcore demand code read requests. Does not count L2
    +prefetch requests.
    +.It Li OFFCORE_REQUESTS.DEMAND.RFO
    +.Pq Event B0H , Umask 04H
    +Counts number of offcore demand RFO requests. Does not count L2 prefetch
    +requests.
    +.It Li OFFCORE_REQUESTS.ANY.READ
    +.Pq Event B0H , Umask 08H
    +Counts number of offcore read requests. Includes L2 prefetch requests.
    +.It Li OFFCORE_REQUESTS.ANY.RFO
    +.Pq Event 80H , Umask 10H
    +Counts number of offcore RFO requests. Includes L2 prefetch requests.
    +.It Li OFFCORE_REQUESTS.L1D_WRITEBACK
    +.Pq Event B0H , Umask 40H
    +Counts number of L1D writebacks to the uncore.
    +.It Li OFFCORE_REQUESTS.ANY
    +.Pq Event B0H , Umask 80H
    +Counts all offcore requests.
    +.It Li UOPS_EXECUTED.PORT0
    +.Pq Event B1H , Umask 01H
    +Counts number of Uops executed that were issued on port 0. Port 0 handles
    +integer arithmetic, SIMD and FP add Uops.
    +.It Li UOPS_EXECUTED.PORT1
    +.Pq Event B1H , Umask 02H
    +Counts number of Uops executed that were issued on port 1. Port 1 handles
    +integer arithmetic, SIMD, integer shift, FP multiply and FP divide Uops.
    +.It Li UOPS_EXECUTED.PORT2_CORE
    +.Pq Event B1H , Umask 04H
    +Counts number of Uops executed that were issued on port 2. Port 2 handles
    +the load Uops. This is a core count only and can not be collected per
    +thread.
    +.It Li UOPS_EXECUTED.PORT3_CORE
    +.Pq Event B1H , Umask 08H
    +Counts number of Uops executed that were issued on port 3. Port 3 handles
    +store Uops. This is a core count only and can not be collected per thread.
    +.It Li UOPS_EXECUTED.PORT4_CORE
    +.Pq Event B1H , Umask 10H
    +Counts number of Uops executed that where issued on port 4. Port 4 handles
    +the value to be stored for the store Uops issued on port 3. This is a core
    +count only and can not be collected per thread.
    +.It Li UOPS_EXECUTED.CORE_ACTIVE_CYCLES_NO_PORT5
    +.Pq Event B1H , Umask 1FH
    +Counts number of cycles there are one or more uops being executed and were
    +issued on ports 0-4. This is a core count only and can not be collected per
    +thread.
    +.It Li UOPS_EXECUTED.PORT5
    +.Pq Event B1H , Umask 20H
    +Counts number of Uops executed that where issued on port 5.
    +.It Li UOPS_EXECUTED.CORE_ACTIVE_CYCLES
    +.Pq Event B1H , Umask 3FH
    +Counts number of cycles there are one or more uops being executed on any
    +ports. This is a core count only and can not be collected per thread.
    +.It Li UOPS_EXECUTED.PORT015
    +.Pq Event B1H , Umask 40H
    +Counts number of Uops executed that where issued on port 0, 1, or 5.
    +use cmask=1, invert=1 to count stall cycles
    +.It Li UOPS_EXECUTED.PORT234
    +.Pq Event B1H , Umask 80H
    +Counts number of Uops executed that where issued on port 2, 3, or 4.
    +.It Li OFFCORE_REQUESTS_SQ_FULL
    +.Pq Event B2H , Umask 01H
    +Counts number of cycles the SQ is full to handle off-core requests.
    +.It Li SNOOPQ_REQUESTS_OUTSTANDING.DATA
    +.Pq Event B3H , Umask 01H
    +Counts weighted cycles of snoopq requests for data. Counter 0 only
    +Use cmask=1 to count cycles not empty.
    +.It Li SNOOPQ_REQUESTS_OUTSTANDING.INVALIDATE
    +.Pq Event B3H , Umask 02H
    +Counts weighted cycles of snoopq invalidate requests. Counter 0 only
    +Use cmask=1 to count cycles not empty.
    +.It Li SNOOPQ_REQUESTS_OUTSTANDING.CODE
    +.Pq Event B3H , Umask 04H
    +Counts weighted cycles of snoopq requests for code. Counter 0 only
    +Use cmask=1 to count cycles not empty.
    +.It Li SNOOPQ_REQUESTS.CODE
    +.Pq Event B4H , Umask 01H
    +Counts the number of snoop code requests
    +.It Li SNOOPQ_REQUESTS.DATA
    +.Pq Event B4H , Umask 02H
    +Counts the number of snoop data requests
    +.It Li SNOOPQ_REQUESTS.INVALIDATE
    +.Pq Event B4H , Umask 04H
    +Counts the number of snoop invalidate requests
    +.It Li OFF_CORE_RESPONSE_0
    +.Pq Event B7H , Umask 01H
    +see Section 30.6.1.3, Off-core Response Performance Monitoring in the
    +Processor Core.
    +Requires programming MSR 01A6H
    +.It Li SNOOP_RESPONSE.HIT
    +.Pq Event B8H , Umask 01H
    +Counts HIT snoop response sent by this thread in response to a snoop
    +request.
    +.It Li SNOOP_RESPONSE.HITE
    +.Pq Event B8H , Umask 02H
    +Counts HIT E snoop response sent by this thread in response to a snoop
    +request.
    +.It Li SNOOP_RESPONSE.HITM
    +.Pq Event B8H , Umask 04H
    +Counts HIT M snoop response sent by this thread in response to a snoop
    +request.
    +.It Li OFF_CORE_RESPONSE_1
    +.Pq Event BBH , Umask 01H
    +see Section 30.6.1.3, Off-core Response Performance Monitoring in the
    +Processor Core
    +Use MSR 01A7H
    +.It Li INST_RETIRED.ANY_P
    +.Pq Event C0H , Umask 01H
    +See Table A-1
    +Notes: INST_RETIRED.ANY is counted by a designated fixed counter.
    +INST_RETIRED.ANY_P is counted by a programmable counter and is an
    +architectural performance event. Event is supported if CPUID.A.EBX[1] = 0.
    +Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not
    +count as retired instructions.
    +.It Li INST_RETIRED.X87
    +.Pq Event C0H , Umask 02H
    +Counts the number of floating point computational operations retired:
    +floating point computational operations executed by the assist handler and
    +sub-operations of complex floating point instructions like transcendental
    +instructions.
    +.It Li INST_RETIRED.MMX
    +.Pq Event C0H , Umask 04H
    +Counts the number of retired: MMX instructions.
    +.It Li UOPS_RETIRED.ANY
    +.Pq Event C2H , Umask 01H
    +Counts the number of micro-ops retired, (macro-fused=1, micro- fused=2,
    +others=1; maximum count of 8 per cycle). Most instructions are composed of
    +one or two micro-ops. Some instructions are decoded into longer sequences
    +such as repeat instructions, floating point transcendental instructions, and
    +assists.
    +Use cmask=1 and invert to count active cycles or stalled cycles
    +.It Li UOPS_RETIRED.RETIRE_SLOTS
    +.Pq Event C2H , Umask 02H
    +Counts the number of retirement slots used each cycle
    +.It Li UOPS_RETIRED.MACRO_FUSED
    +.Pq Event C2H , Umask 04H
    +Counts number of macro-fused uops retired.
    +.It Li MACHINE_CLEARS.CYCLES
    +.Pq Event C3H , Umask 01H
    +Counts the cycles machine clear is asserted.
    +.It Li MACHINE_CLEARS.MEM_ORDER
    +.Pq Event C3H , Umask 02H
    +Counts the number of machine clears due to memory order conflicts.
    +.It Li MACHINE_CLEARS.SMC
    +.Pq Event C3H , Umask 04H
    +Counts the number of times that a program writes to a code section.
    +Self-modifying code causes a sever penalty in all Intel 64 and IA-32
    +processors. The modified cache line is written back to the L2 and L3caches.
    +.It Li BR_INST_RETIRED.ALL_BRANCHES
    +.Pq Event C4H , Umask 00H
    +See Table A-1
    +.It Li BR_INST_RETIRED.CONDITIONAL
    +.Pq Event C4H , Umask 01H
    +Counts the number of conditional branch instructions retired.
    +.It Li BR_INST_RETIRED.NEAR_CALL
    +.Pq Event C4H , Umask 02H
    +Counts the number of direct & indirect near unconditional calls retired
    +.It Li BR_INST_RETIRED.ALL_BRANCHES
    +.Pq Event C4H , Umask 04H
    +Counts the number of branch instructions retired
    +.It Li BR_MISP_RETIRED.ALL_BRANCHES
    +.Pq Event C5H , Umask 00H
    +See Table A-1
    +.It Li BR_MISP_RETIRED.CONDITIONAL
    +.Pq Event C5H , Umask 01H
    +Counts mispredicted conditional retired calls.
    +.It Li BR_MISP_RETIRED.NEAR_CALL
    +.Pq Event C5H , Umask 02H
    +Counts mispredicted direct & indirect near unconditional retired calls.
    +.It Li BR_MISP_RETIRED.ALL_BRANCHES
    +.Pq Event C5H , Umask 04H
    +Counts all mispredicted retired calls.
    +.It Li SSEX_UOPS_RETIRED.PACKED_SINGLE
    +.Pq Event C7H , Umask 01H
    +Counts SIMD packed single-precision floating point Uops retired.
    +.It Li SSEX_UOPS_RETIRED.SCALAR_SINGLE
    +.Pq Event C7H , Umask 02H
    +Counts SIMD calar single-precision floating point Uops retired.
    +.It Li SSEX_UOPS_RETIRED.PACKED_DOUBLE
    +.Pq Event C7H , Umask 04H
    +Counts SIMD packed double- precision floating point Uops retired.
    +.It Li SSEX_UOPS_RETIRED.SCALAR_DOUBLE
    +.Pq Event C7H , Umask 08H
    +Counts SIMD scalar double-precision floating point Uops retired.
    +.It Li SSEX_UOPS_RETIRED.VECTOR_INTEGER
    +.Pq Event C7H , Umask 10H
    +Counts 128-bit SIMD vector integer Uops retired.
    +.It Li ITLB_MISS_RETIRED
    +.Pq Event C8H , Umask 20H
    +Counts the number of retired instructions that missed the ITLB when the
    +instruction was fetched.
    +.It Li MEM_LOAD_RETIRED.L1D_HIT
    +.Pq Event CBH , Umask 01H
    +Counts number of retired loads that hit the L1 data cache.
    +.It Li MEM_LOAD_RETIRED.L2_HIT
    +.Pq Event CBH , Umask 02H
    +Counts number of retired loads that hit the L2 data cache.
    +.It Li MEM_LOAD_RETIRED.L3_UNSHARED_HIT
    +.Pq Event CBH , Umask 04H
    +Counts number of retired loads that hit their own, unshared lines in the L3
    +cache.
    +.It Li MEM_LOAD_RETIRED.OTHER_CORE_L2_HIT_HITM
    +.Pq Event CBH , Umask 08H
    +Counts number of retired loads that hit in a sibling core's L2 (on die
    +core). Since the L3 is inclusive of all cores on the package, this is an L3
    +hit. This counts both clean or modified hits.
    +.It Li MEM_LOAD_RETIRED.L3_MISS
    +.Pq Event CBH , Umask 10H
    +Counts number of retired loads that miss the L3 cache. The load was
    +satisfied by a remote socket, local memory or an IOH.
    +.It Li MEM_LOAD_RETIRED.HIT_LFB
    +.Pq Event CBH , Umask 40H
    +Counts number of retired loads that miss the L1D and the address is located
    +in an allocated line fill buffer and will soon be committed to cache. This
    +is counting secondary L1D misses.
    +.It Li MEM_LOAD_RETIRED.DTLB_MISS
    +.Pq Event CBH , Umask 80H
    +Counts the number of retired loads that missed the DTLB. The DTLB miss is
    +not counted if the load operation causes a fault. This event counts loads
    +from cacheable memory only. The event does not count loads by software
    +prefetches. Counts both primary and secondary misses to the TLB.
    +.It Li FP_MMX_TRANS.TO_FP
    +.Pq Event CCH , Umask 01H
    +Counts the first floating-point instruction following any MMX instruction.
    +You can use this event to estimate the penalties for the transitions between
    +floating-point and MMX technology states.
    +.It Li FP_MMX_TRANS.TO_MMX
    +.Pq Event CCH , Umask 02H
    +Counts the first MMX instruction following a floating-point instruction. You
    +can use this event to estimate the penalties for the transitions between
    +floating-point and MMX technology states.
    +.It Li FP_MMX_TRANS.ANY
    +.Pq Event CCH , Umask 03H
    +Counts all transitions from floating point to MMX instructions and from MMX
    +instructions to floating point instructions. You can use this event to
    +estimate the penalties for the transitions between floating-point and MMX
    +technology states.
    +.It Li MACRO_INSTS.DECODED
    +.Pq Event D0H , Umask 01H
    +Counts the number of instructions decoded, (but not necessarily executed or
    +retired).
    +.It Li UOPS_DECODED.STALL_CYCLES
    +.Pq Event D1H , Umask 01H
    +Counts the cycles of decoder stalls.
    +.It Li UOPS_DECODED.MS
    +.Pq Event D1H , Umask 02H
    +Counts the number of Uops decoded by the Microcode Sequencer, MS. The MS
    +delivers uops when the instruction is more than 4 uops long or a microcode
    +assist is occurring.
    +.It Li UOPS_DECODED.ESP_FOLDING
    +.Pq Event D1H , Umask 04H
    +Counts number of stack pointer (ESP) instructions decoded: push , pop , call
    +, ret, etc. ESP instructions do not generate a Uop to increment or decrement
    +ESP. Instead, they update an ESP_Offset register that keeps track of the
    +delta to the current value of the ESP register.
    +.It Li UOPS_DECODED.ESP_SYNC
    +.Pq Event D1H , Umask 08H
    +Counts number of stack pointer (ESP) sync operations where an ESP
    +instruction is corrected by adding the ESP offset register to the current
    +value of the ESP register.
    +.It Li RAT_STALLS.FLAGS
    +.Pq Event D2H , Umask 01H
    +Counts the number of cycles during which execution stalled due to several
    +reasons, one of which is a partial flag register stall. A partial register
    +stall may occur when two conditions are met: 1) an instruction modifies
    +some, but not all, of the flags in the flag register and 2) the next
    +instruction, which depends on flags, depends on flags that were not modified
    +by this instruction.
    +.It Li RAT_STALLS.REGISTERS
    +.Pq Event D2H , Umask 02H
    +This event counts the number of cycles instruction execution latency became
    +longer than the defined latency because the instruction used a register that
    +was partially written by previous instruction.
    +.It Li RAT_STALLS.ROB_READ_PORT
    +.Pq Event D2H , Umask 04H
    +Counts the number of cycles when ROB read port stalls occurred, which did
    +not allow new micro-ops to enter the out-of-order pipeline. Note that, at
    +this stage in the pipeline, additional stalls may occur at the same cycle
    +and prevent the stalled micro-ops from entering the pipe. In such a case,
    +micro-ops retry entering the execution pipe in the next cycle and the
    +ROB-read port stall is counted again.
    +.It Li RAT_STALLS.SCOREBOARD
    +.Pq Event D2H , Umask 08H
    +Counts the cycles where we stall due to microarchitecturally required
    +serialization. Microcode scoreboarding stalls.
    +.It Li RAT_STALLS.ANY
    +.Pq Event D2H , Umask 0FH
    +Counts all Register Allocation Table stall cycles due to: Cycles when ROB
    +read port stalls occurred, which did not allow new micro-ops to enter the
    +execution pipe. Cycles when partial register stalls occurred Cycles when
    +flag stalls occurred Cycles floating-point unit (FPU) status word stalls
    +occurred. To count each of these conditions separately use the events:
    +RAT_STALLS.ROB_READ_PORT, RAT_STALLS.PARTIAL, RAT_STALLS.FLAGS, and
    +RAT_STALLS.FPSW.
    +.It Li SEG_RENAME_STALLS
    +.Pq Event D4H , Umask 01H
    +Counts the number of stall cycles due to the lack of renaming resources for
    +the ES, DS, FS, and GS segment registers. If a segment is renamed but not
    +retired and a second update to the same segment occurs, a stall occurs in
    +the front- end of the pipeline until the renamed segment retires.
    +.It Li ES_REG_RENAMES
    +.Pq Event D5H , Umask 01H
    +Counts the number of times the ES segment register is renamed.
    +.It Li UOP_UNFUSION
    +.Pq Event DBH , Umask 01H
    +Counts unfusion events due to floating point exception to a fused uop.
    +.It Li BR_INST_DECODED
    +.Pq Event E0H , Umask 01H
    +Counts the number of branch instructions decoded.
    +.It Li BPU_MISSED_CALL_RET
    +.Pq Event E5H , Umask 01H
    +Counts number of times the Branch Prediciton Unit missed predicting a call
    +or return branch.
    +.It Li BACLEAR.CLEAR
    +.Pq Event E6H , Umask 01H
    +Counts the number of times the front end is resteered, mainly when the
    +Branch Prediction Unit cannot provide a correct prediction and this is
    +corrected by the Branch Address Calculator at the front end. This can occur
    +if the code has many branches such that they cannot be consumed by the BPU.
    +Each BACLEAR asserted by the BAC generates approximately an 8 cycle bubble
    +in the instruction fetch pipeline. The effect on total execution time
    +depends on the surrounding code.
    +.It Li BACLEAR.BAD_TARGET
    +.Pq Event E6H , Umask 02H
    +Counts number of Branch Address Calculator clears (BACLEAR) asserted due to
    +conditional branch instructions in which there was a target hit but the
    +direction was wrong. Each BACLEAR asserted by the BAC generates
    +approximately an 8 cycle bubble in the instruction fetch pipeline.
    +.It Li BPU_CLEARS.EARLY
    +.Pq Event E8H , Umask 01H
    +Counts early (normal) Branch Prediction Unit clears: BPU predicted a taken
    +branch after incorrectly assuming that it was not taken.
    +The BPU clear leads to 2 cycle bubble in the Front End.
    +.It Li BPU_CLEARS.LATE
    +.Pq Event E8H , Umask 02H
    +Counts late Branch Prediction Unit clears due to Most Recently Used
    +conflicts. The PBU clear leads to a 3 cycle bubble in the Front End.
    +.It Li THREAD_ACTIVE
    +.Pq Event ECH , Umask 01H
    +Counts cycles threads are active.
    +.It Li L2_TRANSACTIONS.LOAD
    +.Pq Event F0H , Umask 01H
    +Counts L2 load operations due to HW prefetch or demand loads.
    +.It Li L2_TRANSACTIONS.RFO
    +.Pq Event F0H , Umask 02H
    +Counts L2 RFO operations due to HW prefetch or demand RFOs.
    +.It Li L2_TRANSACTIONS.IFETCH
    +.Pq Event F0H , Umask 04H
    +Counts L2 instruction fetch operations due to HW prefetch or demand ifetch.
    +.It Li L2_TRANSACTIONS.PREFETCH
    +.Pq Event F0H , Umask 08H
    +Counts L2 prefetch operations.
    +.It Li L2_TRANSACTIONS.L1D_WB
    +.Pq Event F0H , Umask 10H
    +Counts L1D writeback operations to the L2.
    +.It Li L2_TRANSACTIONS.FILL
    +.Pq Event F0H , Umask 20H
    +Counts L2 cache line fill operations due to load, RFO, L1D writeback or
    +prefetch.
    +.It Li L2_TRANSACTIONS.WB
    +.Pq Event F0H , Umask 40H
    +Counts L2 writeback operations to the L3.
    +.It Li L2_TRANSACTIONS.ANY
    +.Pq Event F0H , Umask 80H
    +Counts all L2 cache operations.
    +.It Li L2_LINES_IN.S_STATE
    +.Pq Event F1H , Umask 02H
    +Counts the number of cache lines allocated in the L2 cache in the S (shared)
    +state.
    +.It Li L2_LINES_IN.E_STATE
    +.Pq Event F1H , Umask 04H
    +Counts the number of cache lines allocated in the L2 cache in the E
    +(exclusive) state.
    +.It Li L2_LINES_IN.ANY
    +.Pq Event F1H , Umask 07H
    +Counts the number of cache lines allocated in the L2 cache.
    +.It Li L2_LINES_OUT.DEMAND_CLEAN
    +.Pq Event F2H , Umask 01H
    +Counts L2 clean cache lines evicted by a demand request.
    +.It Li L2_LINES_OUT.DEMAND_DIRTY
    +.Pq Event F2H , Umask 02H
    +Counts L2 dirty (modified) cache lines evicted by a demand request.
    +.It Li L2_LINES_OUT.PREFETCH_CLEAN
    +.Pq Event F2H , Umask 04H
    +Counts L2 clean cache line evicted by a prefetch request.
    +.It Li L2_LINES_OUT.PREFETCH_DIRTY
    +.Pq Event F2H , Umask 08H
    +Counts L2 modified cache line evicted by a prefetch request.
    +.It Li L2_LINES_OUT.ANY
    +.Pq Event F2H , Umask 0FH
    +Counts all L2 cache lines evicted for any reason.
    +.It Li SQ_MISC.LRU_HINTS
    +.Pq Event F4H , Umask 04H
    +Counts number of Super Queue LRU hints sent to L3.
    +.It Li SQ_MISC.SPLIT_LOCK
    +.Pq Event F4H , Umask 10H
    +Counts the number of SQ lock splits across a cache line.
    +.It Li SQ_FULL_STALL_CYCLES
    +.Pq Event F6H , Umask 01H
    +Counts cycles the Super Queue is full. Neither of the threads on this core
    +will be able to access the uncore.
    +.It Li FP_ASSIST.ALL
    +.Pq Event F7H , Umask 01H
    +Counts the number of floating point operations executed that required
    +micro-code assist intervention. Assists are required in the following cases:
    +SSE instructions, (Denormal input when the DAZ flag is off or Underflow
    +result when the FTZ flag is off): x87 instructions, (NaN or denormal are
    +loaded to a register or used as input from memory, Division by 0 or
    +Underflow output).
    +.It Li FP_ASSIST.OUTPUT
    +.Pq Event F7H , Umask 02H
    +Counts number of floating point micro-code assist when the output value
    +(destination register) is invalid.
    +.It Li FP_ASSIST.INPUT
    +.Pq Event F7H , Umask 04H
    +Counts number of floating point micro-code assist when the input value (one
    +of the source operands to an FP instruction) is invalid.
    +.It Li SIMD_INT_64.PACKED_MPY
    +.Pq Event FDH , Umask 01H
    +Counts number of SID integer 64 bit packed multiply operations.
    +.It Li SIMD_INT_64.PACKED_SHIFT
    +.Pq Event FDH , Umask 02H
    +Counts number of SID integer 64 bit packed shift operations.
    +.It Li SIMD_INT_64.PACK
    +.Pq Event FDH , Umask 04H
    +Counts number of SID integer 64 bit pack operations.
    +.It Li SIMD_INT_64.UNPACK
    +.Pq Event FDH , Umask 08H
    +Counts number of SID integer 64 bit unpack operations.
    +.It Li SIMD_INT_64.PACKED_LOGICAL
    +.Pq Event FDH , Umask 10H
    +Counts number of SID integer 64 bit logical operations.
    +.It Li SIMD_INT_64.PACKED_ARITH
    +.Pq Event FDH , Umask 20H
    +Counts number of SID integer 64 bit arithmetic operations.
    +.It Li SIMD_INT_64.SHUFFLE_MOVE
    +.Pq Event FDH , Umask 40H
    +Counts number of SID integer 64 bit shift or move operations.
    +.El
    +.Sh SEE ALSO
    +.Xr pmc 3 ,
    +.Xr pmc.atom 3 ,
    +.Xr pmc.core 3 ,
    +.Xr pmc.iaf 3 ,
    +.Xr pmc.ucf 3 ,
    +.Xr pmc.k7 3 ,
    +.Xr pmc.k8 3 ,
    +.Xr pmc.p4 3 ,
    +.Xr pmc.p5 3 ,
    +.Xr pmc.p6 3 ,
    +.Xr pmc.corei7 3 ,
    +.Xr pmc.corei7uc 3 ,
    +.Xr pmc.westmereuc 3 ,
    +.Xr pmc.tsc 3 ,
    +.Xr pmc_cpuinfo 3 ,
    +.Xr pmclog 3 ,
    +.Xr hwpmc 4
    +.Sh HISTORY
    +The
    +.Nm pmc
    +library first appeared in
    +.Fx 6.0 .
    +.Sh AUTHORS
    +The
    +.Lb libpmc
    +library was written by
    +.An "Joseph Koshy"
    +.Aq jkoshy@FreeBSD.org .
    diff --git a/lib/libpmc/pmc.westmereuc.3 b/lib/libpmc/pmc.westmereuc.3
    new file mode 100644
    index 00000000000..c5fd12dfa66
    --- /dev/null
    +++ b/lib/libpmc/pmc.westmereuc.3
    @@ -0,0 +1,1083 @@
    +.\" Copyright (c) 2010 Fabien Thomas.  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 Joseph Koshy ``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 Joseph Koshy 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 March 24, 2010
    +.Os
    +.Dt PMC.WESTMEREUC 3
    +.Sh NAME
    +.Nm pmc.westmere
    +.Nd uncore measurement events for
    +.Tn Intel
    +.Tn Westmere
    +family CPUs
    +.Sh LIBRARY
    +.Lb libpmc
    +.Sh SYNOPSIS
    +.In pmc.h
    +.Sh DESCRIPTION
    +.Tn Intel
    +.Tn "Westmere"
    +CPUs contain PMCs conforming to version 2 of the
    +.Tn Intel
    +performance measurement architecture.
    +These CPUs contain two classes of PMCs:
    +.Bl -tag -width "Li PMC_CLASS_UCP"
    +.It Li PMC_CLASS_UCF
    +Fixed-function counters that count only one hardware event per counter.
    +.It Li PMC_CLASS_UCP
    +Programmable counters that may be configured to count one of a defined
    +set of hardware events.
    +.El
    +.Pp
    +The number of PMCs available in each class and their widths need to be
    +determined at run time by calling
    +.Xr pmc_cpuinfo 3 .
    +.Pp
    +Intel Westmere PMCs are documented in
    +.Rs
    +.%B "Intel(R) 64 and IA-32 Architectures Software Developes Manual"
    +.%T "Volume 3B: System Programming Guide, Part 2"
    +.%N "Order Number: 253669-033US"
    +.%D December 2009
    +.%Q "Intel Corporation"
    +.Re
    +.Ss WESTMERE UNCORE FIXED FUNCTION PMCS
    +These PMCs and their supported events are documented in
    +.Xr pmc.ucf 3 .
    +Not all CPUs in this family implement fixed-function counters.
    +.Ss WESTMERE UNCORE PROGRAMMABLE PMCS
    +The programmable PMCs support the following capabilities:
    +.Bl -column "PMC_CAP_INTERRUPT" "Support"
    +.It Em Capability Ta Em Support
    +.It PMC_CAP_CASCADE Ta \&No
    +.It PMC_CAP_EDGE Ta Yes
    +.It PMC_CAP_INTERRUPT Ta \&No
    +.It PMC_CAP_INVERT Ta Yes
    +.It PMC_CAP_READ Ta Yes
    +.It PMC_CAP_PRECISE Ta \&No
    +.It PMC_CAP_SYSTEM Ta \&No
    +.It PMC_CAP_TAGGING Ta \&No
    +.It PMC_CAP_THRESHOLD Ta Yes
    +.It PMC_CAP_USER Ta \&No
    +.It PMC_CAP_WRITE Ta Yes
    +.El
    +.Ss Event Qualifiers
    +Event specifiers for these PMCs support the following common
    +qualifiers:
    +.Bl -tag -width indent
    +.It Li cmask= Ns Ar value
    +Configure the PMC to increment only if the number of configured
    +events measured in a cycle is greater than or equal to
    +.Ar value .
    +.It Li edge
    +Configure the PMC to count the number of de-asserted to asserted
    +transitions of the conditions expressed by the other qualifiers.
    +If specified, the counter will increment only once whenever a
    +condition becomes true, irrespective of the number of clocks during
    +which the condition remains true.
    +.It Li inv
    +Invert the sense of comparison when the
    +.Dq Li cmask
    +qualifier is present, making the counter increment when the number of
    +events per cycle is less than the value specified by the
    +.Dq Li cmask
    +qualifier.
    +.El
    +.Ss Event Specifiers (Programmable PMCs)
    +Westmere uncore programmable PMCs support the following events:
    +.Bl -tag -width indent
    +.It Li GQ_CYCLES_FULL.READ_TRACKER
    +.Pq Event 00H , Umask 01H
    +Uncore cycles Global Queue read tracker is full.
    +.It Li GQ_CYCLES_FULL.WRITE_TRACKER
    +.Pq Event 00H , Umask 02H
    +Uncore cycles Global Queue write tracker is full.
    +.It Li GQ_CYCLES_FULL.PEER_PROBE_TRACKER
    +.Pq Event 00H , Umask 04H
    +Uncore cycles Global Queue peer probe tracker is full. The peer probe
    +tracker queue tracks snoops from the IOH and remote sockets.
    +.It Li GQ_CYCLES_NOT_EMPTY.READ_TRACKER
    +.Pq Event 01H , Umask 01H
    +Uncore cycles were Global Queue read tracker has at least one valid entry.
    +.It Li GQ_CYCLES_NOT_EMPTY.WRITE_TRACKER
    +.Pq Event 01H , Umask 02H
    +Uncore cycles were Global Queue write tracker has at least one valid entry.
    +.It Li GQ_CYCLES_NOT_EMPTY.PEER_PROBE_TRACKER
    +.Pq Event 01H , Umask 04H
    +Uncore cycles were Global Queue peer probe tracker has at least one valid
    +entry. The peer probe tracker queue tracks IOH and remote socket snoops.
    +.It Li GQ_OCCUPANCY.READ_TRACKER
    +.Pq Event 02H , Umask 01H
    +Increments the number of queue entries (code read, data read, and RFOs) in
    +the tread tracker. The GQ read tracker allocate to deallocate occupancy
    +count is divided by the count to obtain the average read tracker latency.
    +.It Li GQ_ALLOC.READ_TRACKER
    +.Pq Event 03H , Umask 01H
    +Counts the number of tread tracker allocate to deallocate entries. The GQ
    +read tracker allocate to deallocate occupancy count is divided by the count
    +to obtain the average read tracker latency.
    +.It Li GQ_ALLOC.RT_L3_MISS
    +.Pq Event 03H , Umask 02H
    +Counts the number GQ read tracker entries for which a full cache line read
    +has missed the L3. The GQ read tracker L3 miss to fill occupancy count is
    +divided by this count to obtain the average cache line read L3 miss latency.
    +The latency represents the time after which the L3 has determined that the
    +cache line has missed. The time between a GQ read tracker allocation and the
    +L3 determining that the cache line has missed is the average L3 hit latency.
    +The total L3 cache line read miss latency is the hit latency + L3 miss
    +latency.
    +.It Li GQ_ALLOC.RT_TO_L3_RESP
    +.Pq Event 03H , Umask 04H
    +Counts the number of GQ read tracker entries that are allocated in the read
    +tracker queue that hit or miss the L3. The GQ read tracker L3 hit occupancy
    +count is divided by this count to obtain the average L3 hit latency.
    +.It Li GQ_ALLOC.RT_TO_RTID_ACQUIRED
    +.Pq Event 03H , Umask 08H
    +Counts the number of GQ read tracker entries that are allocated in the read
    +tracker, have missed in the L3 and have not acquired a Request Transaction
    +ID.	The GQ read tracker L3 miss to RTID acquired occupancy count is
    +divided by this count to obtain the average latency for a read L3 miss to
    +acquire an RTID.
    +.It Li GQ_ALLOC.WT_TO_RTID_ACQUIRED
    +.Pq Event 03H , Umask 10H
    +Counts the number of GQ write tracker entries that are allocated in the
    +write tracker, have missed in the L3 and have not acquired a Request
    +Transaction ID.	The GQ write tracker L3 miss to RTID occupancy count is
    +divided by this count to obtain the average latency for a write L3 miss to
    +acquire an RTID.
    +.It Li GQ_ALLOC.WRITE_TRACKER
    +.Pq Event 03H , Umask 20H
    +Counts the number of GQ write tracker entries that are allocated in the
    +write tracker queue that miss the L3. The GQ write tracker occupancy count
    +is divided by the this count to obtain the average L3 write miss latency.
    +.It Li GQ_ALLOC.PEER_PROBE_TRACKER
    +.Pq Event 03H , Umask 40H
    +Counts the number of GQ peer probe tracker (snoop) entries that are
    +allocated in the peer probe tracker queue that miss the L3. The GQ peer
    +probe occupancy count is divided by this count to obtain the average L3 peer
    +probe miss latency.
    +.It Li GQ_DATA.FROM_QPI
    +.Pq Event 04H , Umask 01H
    +Cycles Global Queue Quickpath Interface input data port is busy importing
    +data from the Quickpath Interface. Each cycle the input port can transfer 8
    +or 16 bytes of data.
    +.It Li GQ_DATA.FROM_QMC
    +.Pq Event 04H , Umask 02H
    +Cycles Global Queue Quickpath Memory Interface input data port is busy
    +importing data from the Quickpath Memory Interface. Each cycle the input
    +port can transfer 8 or 16 bytes of data.
    +.It Li GQ_DATA.FROM_L3
    +.Pq Event 04H , Umask 04H
    +Cycles GQ L3 input data port is busy importing data from the Last Level
    +Cache. Each cycle the input port can transfer 32 bytes of data.
    +.It Li GQ_DATA.FROM_CORES_02
    +.Pq Event 04H , Umask 08H
    +Cycles GQ Core 0 and 2 input data port is busy importing data from processor
    +cores 0 and 2. Each cycle the input port can transfer 32 bytes of data.
    +.It Li GQ_DATA.FROM_CORES_13
    +.Pq Event 04H , Umask 10H
    +Cycles GQ Core 1 and 3 input data port is busy importing data from processor
    +cores 1 and 3. Each cycle the input port can transfer 32 bytes of data.
    +.It Li GQ_DATA.TO_QPI_QMC
    +.Pq Event 05H , Umask 01H
    +Cycles GQ QPI and QMC output data port is busy sending data to the Quickpath
    +Interface or Quickpath Memory Interface. Each cycle the output port can
    +transfer 32 bytes of data.
    +.It Li GQ_DATA.TO_L3
    +.Pq Event 05H , Umask 02H
    +Cycles GQ L3 output data port is busy sending data to the Last Level Cache.
    +Each cycle the output port can transfer 32 bytes of data.
    +.It Li GQ_DATA.TO_CORES
    +.Pq Event 05H , Umask 04H
    +Cycles GQ Core output data port is busy sending data to the Cores. Each
    +cycle the output port can transfer 32 bytes of data.
    +.It Li SNP_RESP_TO_LOCAL_HOME.I_STATE
    +.Pq Event 06H , Umask 01H
    +Number of snoop responses to the local home that L3 does not have the
    +referenced cache line.
    +.It Li SNP_RESP_TO_LOCAL_HOME.S_STATE
    +.Pq Event 06H , Umask 02H
    +Number of snoop responses to the local home that L3 has the referenced line
    +cached in the S state.
    +.It Li SNP_RESP_TO_LOCAL_HOME.FWD_S_STATE
    +.Pq Event 06H , Umask 04H
    +Number of responses to code or data read snoops to the local home that the
    +L3 has the referenced cache line in the E state. The L3 cache line state is
    +changed to the S state and the line is forwarded to the local home in the S
    +state.
    +.It Li SNP_RESP_TO_LOCAL_HOME.FWD_I_STATE
    +.Pq Event 06H , Umask 08H
    +Number of responses to read invalidate snoops to the local home that the L3
    +has the referenced cache line in the M state. The L3 cache line state is
    +invalidated and the line is forwarded to the local home in the M state.
    +.It Li SNP_RESP_TO_LOCAL_HOME.CONFLICT
    +.Pq Event 06H , Umask 10H
    +Number of conflict snoop responses sent to the local home.
    +.It Li SNP_RESP_TO_LOCAL_HOME.WB
    +.Pq Event 06H , Umask 20H
    +Number of responses to code or data read snoops to the local home that the
    +L3 has the referenced line cached in the M state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.I_STATE
    +.Pq Event 07H , Umask 01H
    +Number of snoop responses to a remote home that L3 does not have the
    +referenced cache line.
    +.It Li SNP_RESP_TO_REMOTE_HOME.S_STATE
    +.Pq Event 07H , Umask 02H
    +Number of snoop responses to a remote home that L3 has the referenced line
    +cached in the S state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.FWD_S_STATE
    +.Pq Event 07H , Umask 04H
    +Number of responses to code or data read snoops to a remote home that the L3
    +has the referenced cache line in the E state. The L3 cache line state is
    +changed to the S state and the line is forwarded to the remote home in the S
    +state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.FWD_I_STATE
    +.Pq Event 07H , Umask 08H
    +Number of responses to read invalidate snoops to a remote home that the L3
    +has the referenced cache line in the M state. The L3 cache line state is
    +invalidated and the line is forwarded to the remote home in the M state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.CONFLICT
    +.Pq Event 07H , Umask 10H
    +Number of conflict snoop responses sent to the local home.
    +.It Li SNP_RESP_TO_REMOTE_HOME.WB
    +.Pq Event 07H , Umask 20H
    +Number of responses to code or data read snoops to a remote home that the L3
    +has the referenced line cached in the M state.
    +.It Li SNP_RESP_TO_REMOTE_HOME.HITM
    +.Pq Event 07H , Umask 24H
    +Number of HITM snoop responses to a remote home
    +.It Li L3_HITS.READ
    +.Pq Event 08H , Umask 01H
    +Number of code read, data read and RFO requests that hit in the L3
    +.It Li L3_HITS.WRITE
    +.Pq Event 08H , Umask 02H
    +Number of writeback requests that hit in the L3. Writebacks from the cores
    +will always result in L3 hits due to the inclusive property of the L3.
    +.It Li L3_HITS.PROBE
    +.Pq Event 08H , Umask 04H
    +Number of snoops from IOH or remote sockets that hit in the L3.
    +.It Li L3_HITS.ANY
    +.Pq Event 08H , Umask 03H
    +Number of reads and writes that hit the L3.
    +.It Li L3_MISS.READ
    +.Pq Event 09H , Umask 01H
    +Number of code read, data read and RFO requests that miss the L3.
    +.It Li L3_MISS.WRITE
    +.Pq Event 09H , Umask 02H
    +Number of writeback requests that miss the L3. Should always be zero as
    +writebacks from the cores will always result in L3 hits due to the inclusive
    +property of the L3.
    +.It Li L3_MISS.PROBE
    +.Pq Event 09H , Umask 04H
    +Number of snoops from IOH or remote sockets that miss the L3.
    +.It Li L3_MISS.ANY
    +.Pq Event 09H , Umask 03H
    +Number of reads and writes that miss the L3.
    +.It Li L3_LINES_IN.M_STATE
    +.Pq Event 0AH , Umask 01H
    +Counts the number of L3 lines allocated in M state. The only time a cache
    +line is allocated in the M state is when the line was forwarded in M state
    +is forwarded due to a Snoop Read Invalidate Own request.
    +.It Li L3_LINES_IN.E_STATE
    +.Pq Event 0AH , Umask 02H
    +Counts the number of L3 lines allocated in E state.
    +.It Li L3_LINES_IN.S_STATE
    +.Pq Event 0AH , Umask 04H
    +Counts the number of L3 lines allocated in S state.
    +.It Li L3_LINES_IN.F_STATE
    +.Pq Event 0AH , Umask 08H
    +Counts the number of L3 lines allocated in F state.
    +.It Li L3_LINES_IN.ANY
    +.Pq Event 0AH , Umask 0FH
    +Counts the number of L3 lines allocated in any state.
    +.It Li L3_LINES_OUT.M_STATE
    +.Pq Event 0BH , Umask 01H
    +Counts the number of L3 lines victimized that were in the M state. When the
    +victim cache line is in M state, the line is written to its home cache agent
    +which can be either local or remote.
    +.It Li L3_LINES_OUT.E_STATE
    +.Pq Event 0BH , Umask 02H
    +Counts the number of L3 lines victimized that were in the E state.
    +.It Li L3_LINES_OUT.S_STATE
    +.Pq Event 0BH , Umask 04H
    +Counts the number of L3 lines victimized that were in the S state.
    +.It Li L3_LINES_OUT.I_STATE
    +.Pq Event 0BH , Umask 08H
    +Counts the number of L3 lines victimized that were in the I state.
    +.It Li L3_LINES_OUT.F_STATE
    +.Pq Event 0BH , Umask 10H
    +Counts the number of L3 lines victimized that were in the F state.
    +.It Li L3_LINES_OUT.ANY
    +.Pq Event 0BH , Umask 1FH
    +Counts the number of L3 lines victimized in any state.
    +.It Li GQ_SNOOP.GOTO_S
    +.Pq Event 0CH , Umask 01H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the S state.
    +.It Li GQ_SNOOP.GOTO_I
    +.Pq Event 0CH , Umask 02H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the I state.
    +.It Li GQ_SNOOP.GOTO_S_HIT_E
    +.Pq Event 0CH , Umask 04H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the S state from E state.
    +Requires writing MSR 301H with mask = 2H
    +.It Li GQ_SNOOP.GOTO_S_HIT_F
    +.Pq Event 0CH , Umask 04H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the S state from F (forward) state.
    +Requires writing MSR 301H with mask = 8H
    +.It Li GQ_SNOOP.GOTO_S_HIT_M
    +.Pq Event 0CH , Umask 04H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the S state from M state.
    +Requires writing MSR 301H with mask = 1H
    +.It Li GQ_SNOOP.GOTO_S_HIT_S
    +.Pq Event 0CH , Umask 04H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the S state from S state.
    +Requires writing MSR 301H with mask = 4H
    +.It Li GQ_SNOOP.GOTO_I_HIT_E
    +.Pq Event 0CH , Umask 08H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the I state from E state.
    +Requires writing MSR 301H with mask = 2H
    +.It Li GQ_SNOOP.GOTO_I_HIT_F
    +.Pq Event 0CH , Umask 08H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the I state from F (forward) state.
    +Requires writing MSR 301H with mask = 8H
    +.It Li GQ_SNOOP.GOTO_I_HIT_M
    +.Pq Event 0CH , Umask 08H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the I state from M state.
    +Requires writing MSR 301H with mask = 1H
    +.It Li GQ_SNOOP.GOTO_I_HIT_S
    +.Pq Event 0CH , Umask 08H
    +Counts the number of remote snoops that have requested a cache line be set
    +to the I state from S state.
    +Requires writing MSR 301H with mask = 4H
    +.It Li QHL_REQUESTS.IOH_READS
    +.Pq Event 20H , Umask 01H
    +Counts number of Quickpath Home Logic read requests from the IOH.
    +.It Li QHL_REQUESTS.IOH_WRITES
    +.Pq Event 20H , Umask 02H
    +Counts number of Quickpath Home Logic write requests from the IOH.
    +.It Li QHL_REQUESTS.REMOTE_READS
    +.Pq Event 20H , Umask 04H
    +Counts number of Quickpath Home Logic read requests from a remote socket.
    +.It Li QHL_REQUESTS.REMOTE_WRITES
    +.Pq Event 20H , Umask 08H
    +Counts number of Quickpath Home Logic write requests from a remote socket.
    +.It Li QHL_REQUESTS.LOCAL_READS
    +.Pq Event 20H , Umask 10H
    +Counts number of Quickpath Home Logic read requests from the local socket.
    +.It Li QHL_REQUESTS.LOCAL_WRITES
    +.Pq Event 20H , Umask 20H
    +Counts number of Quickpath Home Logic write requests from the local socket.
    +.It Li QHL_CYCLES_FULL.IOH
    +.Pq Event 21H , Umask 01H
    +Counts uclk cycles all entries in the Quickpath Home Logic IOH are full.
    +.It Li QHL_CYCLES_FULL.REMOTE
    +.Pq Event 21H , Umask 02H
    +Counts uclk cycles all entries in the Quickpath Home Logic remote tracker
    +are full.
    +.It Li QHL_CYCLES_FULL.LOCAL
    +.Pq Event 21H , Umask 04H
    +Counts uclk cycles all entries in the Quickpath Home Logic local tracker are
    +full.
    +.It Li QHL_CYCLES_NOT_EMPTY.IOH
    +.Pq Event 22H , Umask 01H
    +Counts uclk cycles all entries in the Quickpath Home Logic IOH is busy.
    +.It Li QHL_CYCLES_NOT_EMPTY.REMOTE
    +.Pq Event 22H , Umask 02H
    +Counts uclk cycles all entries in the Quickpath Home Logic remote tracker is
    +busy.
    +.It Li QHL_CYCLES_NOT_EMPTY.LOCAL
    +.Pq Event 22H , Umask 04H
    +Counts uclk cycles all entries in the Quickpath Home Logic local tracker is
    +busy.
    +.It Li QHL_OCCUPANCY.IOH
    +.Pq Event 23H , Umask 01H
    +QHL IOH tracker allocate to deallocate read occupancy.
    +.It Li QHL_OCCUPANCY.REMOTE
    +.Pq Event 23H , Umask 02H
    +QHL remote tracker allocate to deallocate read occupancy.
    +.It Li QHL_OCCUPANCY.LOCAL
    +.Pq Event 23H , Umask 04H
    +QHL local tracker allocate to deallocate read occupancy.
    +.It Li QHL_ADDRESS_CONFLICTS.2WAY
    +.Pq Event 24H , Umask 02H
    +Counts number of QHL Active Address Table (AAT) entries that saw a max of 2
    +conflicts. The AAT is a structure that tracks requests that are in conflict.
    +The requests themselves are in the home tracker entries. The count is
    +reported when an AAT entry deallocates.
    +.It Li QHL_ADDRESS_CONFLICTS.3WAY
    +.Pq Event 24H , Umask 04H
    +Counts number of QHL Active Address Table (AAT) entries that saw a max of 3
    +conflicts. The AAT is a structure that tracks requests that are in conflict.
    +The requests themselves are in the home tracker entries. The count is
    +reported when an AAT entry deallocates.
    +.It Li QHL_CONFLICT_CYCLES.IOH
    +.Pq Event 25H , Umask 01H
    +Counts cycles the Quickpath Home Logic IOH Tracker contains two or more
    +requests with an address conflict. A max of 3 requests can be in conflict.
    +.It Li QHL_CONFLICT_CYCLES.REMOTE
    +.Pq Event 25H , Umask 02H
    +Counts cycles the Quickpath Home Logic Remote Tracker contains two or more
    +requests with an address conflict. A max of 3 requests can be in conflict.
    +.It Li QHL_CONFLICT_CYCLES.LOCAL
    +.Pq Event 25H , Umask 04H
    +Counts cycles the Quickpath Home Logic Local Tracker contains two or more
    +requests with an address conflict. A max of 3 requests can be in conflict.
    +.It Li QHL_TO_QMC_BYPASS
    +.Pq Event 26H , Umask 01H
    +Counts number or requests to the Quickpath Memory Controller that bypass the
    +Quickpath Home Logic. All local accesses can be bypassed. For remote
    +requests, only read requests can be bypassed.
    +.It Li QMC_ISOC_FULL.READ.CH0
    +.Pq Event 28H , Umask 01H
    +Counts cycles all the entries in the DRAM channel 0 high priority queue are
    +occupied with isochronous read requests.
    +.It Li QMC_ISOC_FULL.READ.CH1
    +.Pq Event 28H , Umask 02H
    +Counts cycles all the entries in the DRAM channel 1high priority queue are
    +occupied with isochronous read requests.
    +.It Li QMC_ISOC_FULL.READ.CH2
    +.Pq Event 28H , Umask 04H
    +Counts cycles all the entries in the DRAM channel 2 high priority queue are
    +occupied with isochronous read requests.
    +.It Li QMC_ISOC_FULL.WRITE.CH0
    +.Pq Event 28H , Umask 08H
    +Counts cycles all the entries in the DRAM channel 0 high priority queue are
    +occupied with isochronous write requests.
    +.It Li QMC_ISOC_FULL.WRITE.CH1
    +.Pq Event 28H , Umask 10H
    +Counts cycles all the entries in the DRAM channel 1 high priority queue are
    +occupied with isochronous write requests.
    +.It Li QMC_ISOC_FULL.WRITE.CH2
    +.Pq Event 28H , Umask 20H
    +Counts cycles all the entries in the DRAM channel 2 high priority queue are
    +occupied with isochronous write requests.
    +.It Li QMC_BUSY.READ.CH0
    +.Pq Event 29H , Umask 01H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +read request to DRAM channel 0.
    +.It Li QMC_BUSY.READ.CH1
    +.Pq Event 29H , Umask 02H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +read request to DRAM channel 1.
    +.It Li QMC_BUSY.READ.CH2
    +.Pq Event 29H , Umask 04H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +read request to DRAM channel 2.
    +.It Li QMC_BUSY.WRITE.CH0
    +.Pq Event 29H , Umask 08H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +write request to DRAM channel 0.
    +.It Li QMC_BUSY.WRITE.CH1
    +.Pq Event 29H , Umask 10H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +write request to DRAM channel 1.
    +.It Li QMC_BUSY.WRITE.CH2
    +.Pq Event 29H , Umask 20H
    +Counts cycles where Quickpath Memory Controller has at least 1 outstanding
    +write request to DRAM channel 2.
    +.It Li QMC_OCCUPANCY.CH0
    +.Pq Event 2AH , Umask 01H
    +IMC channel 0 normal read request occupancy.
    +.It Li QMC_OCCUPANCY.CH1
    +.Pq Event 2AH , Umask 02H
    +IMC channel 1 normal read request occupancy.
    +.It Li QMC_OCCUPANCY.CH2
    +.Pq Event 2AH , Umask 04H
    +IMC channel 2 normal read request occupancy.
    +.It Li QMC_OCCUPANCY.ANY
    +.Pq Event 2AH , Umask 07H
    +Normal read request occupancy for any channel.
    +.It Li QMC_ISSOC_OCCUPANCY.CH0
    +.Pq Event 2BH , Umask 01H
    +IMC channel 0 issoc read request occupancy.
    +.It Li QMC_ISSOC_OCCUPANCY.CH1
    +.Pq Event 2BH , Umask 02H
    +IMC channel 1 issoc read request occupancy.
    +.It Li QMC_ISSOC_OCCUPANCY.CH2
    +.Pq Event 2BH , Umask 04H
    +IMC channel 2 issoc read request occupancy.
    +.It Li QMC_ISSOC_READS.ANY
    +.Pq Event 2BH , Umask 07H
    +IMC issoc read request occupancy.
    +.It Li QMC_NORMAL_READS.CH0
    +.Pq Event 2CH , Umask 01H
    +Counts the number of Quickpath Memory Controller channel 0 medium and low
    +priority read requests. The QMC channel 0 normal read occupancy divided by
    +this count provides the average QMC channel 0 read latency.
    +.It Li QMC_NORMAL_READS.CH1
    +.Pq Event 2CH , Umask 02H
    +Counts the number of Quickpath Memory Controller channel 1 medium and low
    +priority read requests. The QMC channel 1 normal read occupancy divided by
    +this count provides the average QMC channel 1 read latency.
    +.It Li QMC_NORMAL_READS.CH2
    +.Pq Event 2CH , Umask 04H
    +Counts the number of Quickpath Memory Controller channel 2 medium and low
    +priority read requests. The QMC channel 2 normal read occupancy divided by
    +this count provides the average QMC channel 2 read latency.
    +.It Li QMC_NORMAL_READS.ANY
    +.Pq Event 2CH , Umask 07H
    +Counts the number of Quickpath Memory Controller medium and low priority
    +read requests. The QMC normal read occupancy divided by this count provides
    +the average QMC read latency.
    +.It Li QMC_HIGH_PRIORITY_READS.CH0
    +.Pq Event 2DH , Umask 01H
    +Counts the number of Quickpath Memory Controller channel 0 high priority
    +isochronous read requests.
    +.It Li QMC_HIGH_PRIORITY_READS.CH1
    +.Pq Event 2DH , Umask 02H
    +Counts the number of Quickpath Memory Controller channel 1 high priority
    +isochronous read requests.
    +.It Li QMC_HIGH_PRIORITY_READS.CH2
    +.Pq Event 2DH , Umask 04H
    +Counts the number of Quickpath Memory Controller channel 2 high priority
    +isochronous read requests.
    +.It Li QMC_HIGH_PRIORITY_READS.ANY
    +.Pq Event 2DH , Umask 07H
    +Counts the number of Quickpath Memory Controller high priority isochronous
    +read requests.
    +.It Li QMC_CRITICAL_PRIORITY_READS.CH0
    +.Pq Event 2EH , Umask 01H
    +Counts the number of Quickpath Memory Controller channel 0 critical priority
    +isochronous read requests.
    +.It Li QMC_CRITICAL_PRIORITY_READS.CH1
    +.Pq Event 2EH , Umask 02H
    +Counts the number of Quickpath Memory Controller channel 1 critical priority
    +isochronous read requests.
    +.It Li QMC_CRITICAL_PRIORITY_READS.CH2
    +.Pq Event 2EH , Umask 04H
    +Counts the number of Quickpath Memory Controller channel 2 critical priority
    +isochronous read requests.
    +.It Li QMC_CRITICAL_PRIORITY_READS.ANY
    +.Pq Event 2EH , Umask 07H
    +Counts the number of Quickpath Memory Controller critical priority
    +isochronous read requests.
    +.It Li QMC_WRITES.FULL.CH0
    +.Pq Event 2FH , Umask 01H
    +Counts number of full cache line writes to DRAM channel 0.
    +.It Li QMC_WRITES.FULL.CH1
    +.Pq Event 2FH , Umask 02H
    +Counts number of full cache line writes to DRAM channel 1.
    +.It Li QMC_WRITES.FULL.CH2
    +.Pq Event 2FH , Umask 04H
    +Counts number of full cache line writes to DRAM channel 2.
    +.It Li QMC_WRITES.FULL.ANY
    +.Pq Event 2FH , Umask 07H
    +Counts number of full cache line writes to DRAM.
    +.It Li QMC_WRITES.PARTIAL.CH0
    +.Pq Event 2FH , Umask 08H
    +Counts number of partial cache line writes to DRAM channel 0.
    +.It Li QMC_WRITES.PARTIAL.CH1
    +.Pq Event 2FH , Umask 10H
    +Counts number of partial cache line writes to DRAM channel 1.
    +.It Li QMC_WRITES.PARTIAL.CH2
    +.Pq Event 2FH , Umask 20H
    +Counts number of partial cache line writes to DRAM channel 2.
    +.It Li QMC_WRITES.PARTIAL.ANY
    +.Pq Event 2FH , Umask 38H
    +Counts number of partial cache line writes to DRAM.
    +.It Li QMC_CANCEL.CH0
    +.Pq Event 30H , Umask 01H
    +Counts number of DRAM channel 0 cancel requests.
    +.It Li QMC_CANCEL.CH1
    +.Pq Event 30H , Umask 02H
    +Counts number of DRAM channel 1 cancel requests.
    +.It Li QMC_CANCEL.CH2
    +.Pq Event 30H , Umask 04H
    +Counts number of DRAM channel 2 cancel requests.
    +.It Li QMC_CANCEL.ANY
    +.Pq Event 30H , Umask 07H
    +Counts number of DRAM cancel requests.
    +.It Li QMC_PRIORITY_UPDATES.CH0
    +.Pq Event 31H , Umask 01H
    +Counts number of DRAM channel 0 priority updates. A priority update occurs
    +when an ISOC high or critical request is received by the QHL and there is a
    +matching request with normal priority that has already been issued to the
    +QMC. In this instance, the QHL will send a priority update to QMC to
    +expedite the request.
    +.It Li QMC_PRIORITY_UPDATES.CH1
    +.Pq Event 31H , Umask 02H
    +Counts number of DRAM channel 1 priority updates. A priority update occurs
    +when an ISOC high or critical request is received by the QHL and there is a
    +matching request with normal priority that has already been issued to the
    +QMC. In this instance, the QHL will send a priority update to QMC to
    +expedite the request.
    +.It Li QMC_PRIORITY_UPDATES.CH2
    +.Pq Event 31H , Umask 04H
    +Counts number of DRAM channel 2 priority updates. A priority update occurs
    +when an ISOC high or critical request is received by the QHL and there is a
    +matching request with normal priority that has already been issued to the
    +QMC. In this instance, the QHL will send a priority update to QMC to
    +expedite the request.
    +.It Li QMC_PRIORITY_UPDATES.ANY
    +.Pq Event 31H , Umask 07H
    +Counts number of DRAM priority updates. A priority update occurs when an
    +ISOC high or critical request is received by the QHL and there is a matching
    +request with normal priority that has already been issued to the QMC. In
    +this instance, the QHL will send a priority update to QMC to expedite the
    +request.
    +.It Li IMC_RETRY.CH0
    +.Pq Event 32H , Umask 01H
    +Counts number of IMC DRAM channel 0 retries. DRAM retry only occurs when
    +configured in RAS mode.
    +.It Li IMC_RETRY.CH1
    +.Pq Event 32H , Umask 02H
    +Counts number of IMC DRAM channel 1 retries. DRAM retry only occurs when
    +configured in RAS mode.
    +.It Li IMC_RETRY.CH2
    +.Pq Event 32H , Umask 04H
    +Counts number of IMC DRAM channel 2 retries. DRAM retry only occurs when
    +configured in RAS mode.
    +.It Li IMC_RETRY.ANY
    +.Pq Event 32H , Umask 07H
    +Counts number of IMC DRAM retries from any channel. DRAM retry only occurs
    +when configured in RAS mode.
    +.It Li QHL_FRC_ACK_CNFLTS.IOH
    +.Pq Event 33H , Umask 01H
    +Counts number of Force Acknowledge Conflict messages sent by the Quickpath
    +Home Logic to the IOH.
    +.It Li QHL_FRC_ACK_CNFLTS.REMOTE
    +.Pq Event 33H , Umask 02H
    +Counts number of Force Acknowledge Conflict messages sent by the Quickpath
    +Home Logic to the remote home.
    +.It Li QHL_FRC_ACK_CNFLTS.LOCAL
    +.Pq Event 33H , Umask 04H
    +Counts number of Force Acknowledge Conflict messages sent by the Quickpath
    +Home Logic to the local home.
    +.It Li QHL_FRC_ACK_CNFLTS.ANY
    +.Pq Event 33H , Umask 07H
    +Counts number of Force Acknowledge Conflict messages sent by the Quickpath
    +Home Logic.
    +.It Li QHL_SLEEPS.IOH_ORDER
    +.Pq Event 34H , Umask 01H
    +Counts number of occurrences a request was put to sleep due to IOH ordering
    +(write after read) conflicts. While in the sleep state, the request is not
    +eligible to be scheduled to the QMC.
    +.It Li QHL_SLEEPS.REMOTE_ORDER
    +.Pq Event 34H , Umask 02H
    +Counts number of occurrences a request was put to sleep due to remote socket
    +ordering (write after read) conflicts. While in the sleep state, the request
    +is not eligible to be scheduled to the QMC.
    +.It Li QHL_SLEEPS.LOCAL_ORDER
    +.Pq Event 34H , Umask 04H
    +Counts number of occurrences a request was put to sleep due to local socket
    +ordering (write after read) conflicts. While in the sleep state, the request
    +is not eligible to be scheduled to the QMC.
    +.It Li QHL_SLEEPS.IOH_CONFLICT
    +.Pq Event 34H , Umask 08H
    +Counts number of occurrences a request was put to sleep due to IOH address
    +conflicts. While in the sleep state, the request is not eligible to be
    +scheduled to the QMC.
    +.It Li QHL_SLEEPS.REMOTE_CONFLICT
    +.Pq Event 34H , Umask 10H
    +Counts number of occurrences a request was put to sleep due to remote socket
    +address conflicts. While in the sleep state, the request is not eligible to
    +be scheduled to the QMC.
    +.It Li QHL_SLEEPS.LOCAL_CONFLICT
    +.Pq Event 34H , Umask 20H
    +Counts number of occurrences a request was put to sleep due to local socket
    +address conflicts. While in the sleep state, the request is not eligible to
    +be scheduled to the QMC.
    +.It Li ADDR_OPCODE_MATCH.IOH
    +.Pq Event 35H , Umask 01H
    +Counts number of requests from the IOH, address/opcode of request is
    +qualified by mask value written to MSR 396H. The following mask values are
    +supported:
    +0: NONE 40000000_00000000H:RSPFWDI 40001A00_00000000H:RSPFWDS
    +40001D00_00000000H:RSPIWB
    +Match opcode/addres s by writing MSR 396H with mask supported mask value
    +.It Li ADDR_OPCODE_MATCH.REMOTE
    +.Pq Event 35H , Umask 02H
    +Counts number of requests from the remote socket, address/opcode of request
    +is qualified by mask value written to MSR 396H. The following mask values
    +are supported:
    +0: NONE 40000000_00000000H:RSPFWDI 40001A00_00000000H:RSPFWDS
    +40001D00_00000000H:RSPIWB
    +Match opcode/addres s by writing MSR 396H with mask supported mask value
    +.It Li ADDR_OPCODE_MATCH.LOCAL
    +.Pq Event 35H , Umask 04H
    +Counts number of requests from the local socket, address/opcode of request
    +is qualified by mask value written to MSR 396H. The following mask values
    +are supported:
    +0: NONE 40000000_00000000H:RSPFWDI 40001A00_00000000H:RSPFWDS
    +40001D00_00000000H:RSPIWB
    +Match opcode/addres s by writing MSR 396H with mask supported mask value
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_0
    +.Pq Event 40H , Umask 01H
    +Counts cycles the Quickpath outbound link 0 HOME virtual channel is stalled
    +due to lack of a VNA and VN0 credit. Note that this event does not filter
    +out when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_0
    +.Pq Event 40H , Umask 02H
    +Counts cycles the Quickpath outbound link 0 SNOOP virtual channel is stalled
    +due to lack of a VNA and VN0 credit. Note that this event does not filter
    +out when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_0
    +.Pq Event 40H , Umask 04H
    +Counts cycles the Quickpath outbound link 0 non-data response virtual
    +channel is stalled due to lack of a VNA and VN0 credit. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.HOME.LINK_1
    +.Pq Event 40H , Umask 08H
    +Counts cycles the Quickpath outbound link 1 HOME virtual channel is stalled
    +due to lack of a VNA and VN0 credit. Note that this event does not filter
    +out when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.SNOOP.LINK_1
    +.Pq Event 40H , Umask 10H
    +Counts cycles the Quickpath outbound link 1 SNOOP virtual channel is stalled
    +due to lack of a VNA and VN0 credit. Note that this event does not filter
    +out when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.NDR.LINK_1
    +.Pq Event 40H , Umask 20H
    +Counts cycles the Quickpath outbound link 1 non-data response virtual
    +channel is stalled due to lack of a VNA and VN0 credit. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.LINK_0
    +.Pq Event 40H , Umask 07H
    +Counts cycles the Quickpath outbound link 0 virtual channels are stalled due
    +to lack of a VNA and VN0 credit. Note that this event does not filter out
    +when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_SINGLE_FLIT.LINK_1
    +.Pq Event 40H , Umask 38H
    +Counts cycles the Quickpath outbound link 1 virtual channels are stalled due
    +to lack of a VNA and VN0 credit. Note that this event does not filter out
    +when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_0
    +.Pq Event 41H , Umask 01H
    +Counts cycles the Quickpath outbound link 0 Data ResponSe virtual channel is
    +stalled due to lack of VNA and VN0 credits. Note that this event does not
    +filter out when a flit would not have been selected for arbitration because
    +another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_0
    +.Pq Event 41H , Umask 02H
    +Counts cycles the Quickpath outbound link 0 Non-Coherent Bypass virtual
    +channel is stalled due to lack of VNA and VN0 credits. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_0
    +.Pq Event 41H , Umask 04H
    +Counts cycles the Quickpath outbound link 0 Non-Coherent Standard virtual
    +channel is stalled due to lack of VNA and VN0 credits. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.DRS.LINK_1
    +.Pq Event 41H , Umask 08H
    +Counts cycles the Quickpath outbound link 1 Data ResponSe virtual channel is
    +stalled due to lack of VNA and VN0 credits. Note that this event does not
    +filter out when a flit would not have been selected for arbitration because
    +another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.NCB.LINK_1
    +.Pq Event 41H , Umask 10H
    +Counts cycles the Quickpath outbound link 1 Non-Coherent Bypass virtual
    +channel is stalled due to lack of VNA and VN0 credits. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.NCS.LINK_1
    +.Pq Event 41H , Umask 20H
    +Counts cycles the Quickpath outbound link 1 Non-Coherent Standard virtual
    +channel is stalled due to lack of VNA and VN0 credits. Note that this event
    +does not filter out when a flit would not have been selected for arbitration
    +because another virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.LINK_0
    +.Pq Event 41H , Umask 07H
    +Counts cycles the Quickpath outbound link 0 virtual channels are stalled due
    +to lack of VNA and VN0 credits. Note that this event does not filter out
    +when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_STALLED_MULTI_FLIT.LINK_1
    +.Pq Event 41H , Umask 38H
    +Counts cycles the Quickpath outbound link 1 virtual channels are stalled due
    +to lack of VNA and VN0 credits. Note that this event does not filter out
    +when a flit would not have been selected for arbitration because another
    +virtual channel is getting arbitrated.
    +.It Li QPI_TX_HEADER.FULL.LINK_0
    +.Pq Event 42H , Umask 01H
    +Number of cycles that the header buffer in the Quickpath Interface outbound
    +link 0 is full.
    +.It Li QPI_TX_HEADER.BUSY.LINK_0
    +.Pq Event 42H , Umask 02H
    +Number of cycles that the header buffer in the Quickpath Interface outbound
    +link 0 is busy.
    +.It Li QPI_TX_HEADER.FULL.LINK_1
    +.Pq Event 42H , Umask 04H
    +Number of cycles that the header buffer in the Quickpath Interface outbound
    +link 1 is full.
    +.It Li QPI_TX_HEADER.BUSY.LINK_1
    +.Pq Event 42H , Umask 08H
    +Number of cycles that the header buffer in the Quickpath Interface outbound
    +link 1 is busy.
    +.It Li QPI_RX_NO_PPT_CREDIT.STALLS.LINK_0
    +.Pq Event 43H , Umask 01H
    +Number of cycles that snoop packets incoming to the Quickpath Interface link
    +0 are stalled and not sent to the GQ because the GQ Peer Probe Tracker (PPT)
    +does not have any available entries.
    +.It Li QPI_RX_NO_PPT_CREDIT.STALLS.LINK_1
    +.Pq Event 43H , Umask 02H
    +Number of cycles that snoop packets incoming to the Quickpath Interface link
    +1 are stalled and not sent to the GQ because the GQ Peer Probe Tracker (PPT)
    +does not have any available entries.
    +.It Li DRAM_OPEN.CH0
    +.Pq Event 60H , Umask 01H
    +Counts number of DRAM Channel 0 open commands issued either for read or
    +write. To read or write data, the referenced DRAM page must first be opened.
    +.It Li DRAM_OPEN.CH1
    +.Pq Event 60H , Umask 02H
    +Counts number of DRAM Channel 1 open commands issued either for read or
    +write. To read or write data, the referenced DRAM page must first be opened.
    +.It Li DRAM_OPEN.CH2
    +.Pq Event 60H , Umask 04H
    +Counts number of DRAM Channel 2 open commands issued either for read or
    +write. To read or write data, the referenced DRAM page must first be opened.
    +.It Li DRAM_PAGE_CLOSE.CH0
    +.Pq Event 61H , Umask 01H
    +DRAM channel 0 command issued to CLOSE a page due to page idle timer
    +expiration. Closing a page is done by issuing a precharge.
    +.It Li DRAM_PAGE_CLOSE.CH1
    +.Pq Event 61H , Umask 02H
    +DRAM channel 1 command issued to CLOSE a page due to page idle timer
    +expiration. Closing a page is done by issuing a precharge.
    +.It Li DRAM_PAGE_CLOSE.CH2
    +.Pq Event 61H , Umask 04H
    +DRAM channel 2 command issued to CLOSE a page due to page idle timer
    +expiration. Closing a page is done by issuing a precharge.
    +.It Li DRAM_PAGE_MISS.CH0
    +.Pq Event 62H , Umask 01H
    +Counts the number of precharges (PRE) that were issued to DRAM channel 0
    +because there was a page miss. A page miss refers to a situation in which a
    +page is currently open and another page from the same bank needs to be
    +opened. The new page experiences a page miss. Closing of the old page is
    +done by issuing a precharge.
    +.It Li DRAM_PAGE_MISS.CH1
    +.Pq Event 62H , Umask 02H
    +Counts the number of precharges (PRE) that were issued to DRAM channel 1
    +because there was a page miss. A page miss refers to a situation in which a
    +page is currently open and another page from the same bank needs to be
    +opened. The new page experiences a page miss. Closing of the old page is
    +done by issuing a precharge.
    +.It Li DRAM_PAGE_MISS.CH2
    +.Pq Event 62H , Umask 04H
    +Counts the number of precharges (PRE) that were issued to DRAM channel 2
    +because there was a page miss. A page miss refers to a situation in which a
    +page is currently open and another page from the same bank needs to be
    +opened. The new page experiences a page miss. Closing of the old page is
    +done by issuing a precharge.
    +.It Li DRAM_READ_CAS.CH0
    +.Pq Event 63H , Umask 01H
    +Counts the number of times a read CAS command was issued on DRAM channel 0.
    +.It Li DRAM_READ_CAS.AUTOPRE_CH0
    +.Pq Event 63H , Umask 02H
    +Counts the number of times a read CAS command was issued on DRAM channel 0
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_READ_CAS.CH1
    +.Pq Event 63H , Umask 04H
    +Counts the number of times a read CAS command was issued on DRAM channel 1.
    +.It Li DRAM_READ_CAS.AUTOPRE_CH1
    +.Pq Event 63H , Umask 08H
    +Counts the number of times a read CAS command was issued on DRAM channel 1
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_READ_CAS.CH2
    +.Pq Event 63H , Umask 10H
    +Counts the number of times a read CAS command was issued on DRAM channel 2.
    +.It Li DRAM_READ_CAS.AUTOPRE_CH2
    +.Pq Event 63H , Umask 20H
    +Counts the number of times a read CAS command was issued on DRAM channel 2
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_WRITE_CAS.CH0
    +.Pq Event 64H , Umask 01H
    +Counts the number of times a write CAS command was issued on DRAM channel 0.
    +.It Li DRAM_WRITE_CAS.AUTOPRE_CH0
    +.Pq Event 64H , Umask 02H
    +Counts the number of times a write CAS command was issued on DRAM channel 0
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_WRITE_CAS.CH1
    +.Pq Event 64H , Umask 04H
    +Counts the number of times a write CAS command was issued on DRAM channel 1.
    +.It Li DRAM_WRITE_CAS.AUTOPRE_CH1
    +.Pq Event 64H , Umask 08H
    +Counts the number of times a write CAS command was issued on DRAM channel 1
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_WRITE_CAS.CH2
    +.Pq Event 64H , Umask 10H
    +Counts the number of times a write CAS command was issued on DRAM channel 2.
    +.It Li DRAM_WRITE_CAS.AUTOPRE_CH2
    +.Pq Event 64H , Umask 20H
    +Counts the number of times a write CAS command was issued on DRAM channel 2
    +where the command issued used the auto-precharge (auto page close) mode.
    +.It Li DRAM_REFRESH.CH0
    +.Pq Event 65H , Umask 01H
    +Counts number of DRAM channel 0 refresh commands. DRAM loses data content
    +over time. In order to keep correct data content, the data values have to be
    +refreshed periodically.
    +.It Li DRAM_REFRESH.CH1
    +.Pq Event 65H , Umask 02H
    +Counts number of DRAM channel 1 refresh commands. DRAM loses data content
    +over time. In order to keep correct data content, the data values have to be
    +refreshed periodically.
    +.It Li DRAM_REFRESH.CH2
    +.Pq Event 65H , Umask 04H
    +Counts number of DRAM channel 2 refresh commands. DRAM loses data content
    +over time. In order to keep correct data content, the data values have to be
    +refreshed periodically.
    +.It Li DRAM_PRE_ALL.CH0
    +.Pq Event 66H , Umask 01H
    +Counts number of DRAM Channel 0 precharge-all (PREALL) commands that close
    +all open pages in a rank. PREALL is issued when the DRAM needs to be
    +refreshed or needs to go into a power down mode.
    +.It Li DRAM_PRE_ALL.CH1
    +.Pq Event 66H , Umask 02H
    +Counts number of DRAM Channel 1 precharge-all (PREALL) commands that close
    +all open pages in a rank. PREALL is issued when the DRAM needs to be
    +refreshed or needs to go into a power down mode.
    +.It Li DRAM_PRE_ALL.CH2
    +.Pq Event 66H , Umask 04H
    +Counts number of DRAM Channel 2 precharge-all (PREALL) commands that close
    +all open pages in a rank. PREALL is issued when the DRAM needs to be
    +refreshed or needs to go into a power down mode.
    +.It Li DRAM_THERMAL_THROTTLED
    +.Pq Event 67H , Umask 01H
    +Uncore cycles DRAM was throttled due to its temperature being above the
    +thermal throttling threshold.
    +.It Li THERMAL_THROTTLING_TEMP.CORE_0
    +.Pq Event 80H , Umask 01H
    +Cycles that the PCU records that core 0 is above the thermal throttling
    +threshold temperature.
    +.It Li THERMAL_THROTTLING_TEMP.CORE_1
    +.Pq Event 80H , Umask 02H
    +Cycles that the PCU records that core 1 is above the thermal throttling
    +threshold temperature.
    +.It Li THERMAL_THROTTLING_TEMP.CORE_2
    +.Pq Event 80H , Umask 04H
    +Cycles that the PCU records that core 2 is above the thermal throttling
    +threshold temperature.
    +.It Li THERMAL_THROTTLING_TEMP.CORE_3
    +.Pq Event 80H , Umask 08H
    +Cycles that the PCU records that core 3 is above the thermal throttling
    +threshold temperature.
    +.It Li THERMAL_THROTTLED_TEMP.CORE_0
    +.Pq Event 81H , Umask 01H
    +Cycles that the PCU records that core 0 is in the power throttled state due
    +to cores temperature being above the thermal throttling threshold.
    +.It Li THERMAL_THROTTLED_TEMP.CORE_1
    +.Pq Event 81H , Umask 02H
    +Cycles that the PCU records that core 1 is in the power throttled state due
    +to cores temperature being above the thermal throttling threshold.
    +.It Li THERMAL_THROTTLED_TEMP.CORE_2
    +.Pq Event 81H , Umask 04H
    +Cycles that the PCU records that core 2 is in the power throttled state due
    +to cores temperature being above the thermal throttling threshold.
    +.It Li THERMAL_THROTTLED_TEMP.CORE_3
    +.Pq Event 81H , Umask 08H
    +Cycles that the PCU records that core 3 is in the power throttled state due
    +to cores temperature being above the thermal throttling threshold.
    +.It Li PROCHOT_ASSERTION
    +.Pq Event 82H , Umask 01H
    +Number of system assertions of PROCHOT indicating the entire processor has
    +exceeded the thermal limit.
    +.It Li THERMAL_THROTTLING_PROCHOT.CORE_0
    +.Pq Event 83H , Umask 01H
    +Cycles that the PCU records that core 0 is a low power state due to the
    +system asserting PROCHOT the entire processor has exceeded the thermal
    +limit.
    +.It Li THERMAL_THROTTLING_PROCHOT.CORE_1
    +.Pq Event 83H , Umask 02H
    +Cycles that the PCU records that core 1 is a low power state due to the
    +system asserting PROCHOT the entire processor has exceeded the thermal
    +limit.
    +.It Li THERMAL_THROTTLING_PROCHOT.CORE_2
    +.Pq Event 83H , Umask 04H
    +Cycles that the PCU records that core 2 is a low power state due to the
    +system asserting PROCHOT the entire processor has exceeded the thermal
    +limit.
    +.It Li THERMAL_THROTTLING_PROCHOT.CORE_3
    +.Pq Event 83H , Umask 08H
    +Cycles that the PCU records that core 3 is a low power state due to the
    +system asserting PROCHOT the entire processor has exceeded the thermal
    +limit.
    +.It Li TURBO_MODE.CORE_0
    +.Pq Event 84H , Umask 01H
    +Uncore cycles that core 0 is operating in turbo mode.
    +.It Li TURBO_MODE.CORE_1
    +.Pq Event 84H , Umask 02H
    +Uncore cycles that core 1 is operating in turbo mode.
    +.It Li TURBO_MODE.CORE_2
    +.Pq Event 84H , Umask 04H
    +Uncore cycles that core 2 is operating in turbo mode.
    +.It Li TURBO_MODE.CORE_3
    +.Pq Event 84H , Umask 08H
    +Uncore cycles that core 3 is operating in turbo mode.
    +.It Li CYCLES_UNHALTED_L3_FLL_ENABLE
    +.Pq Event 85H , Umask 02H
    +Uncore cycles that at least one core is unhalted and all L3 ways are
    +enabled.
    +.It Li CYCLES_UNHALTED_L3_FLL_DISABLE
    +.Pq Event 86H , Umask 01H
    +Uncore cycles that at least one core is unhalted and all L3 ways are
    +disabled.
    +.El
    +.Sh SEE ALSO
    +.Xr pmc 3 ,
    +.Xr pmc.atom 3 ,
    +.Xr pmc.core 3 ,
    +.Xr pmc.iaf 3 ,
    +.Xr pmc.ucf 3 ,
    +.Xr pmc.k7 3 ,
    +.Xr pmc.k8 3 ,
    +.Xr pmc.p4 3 ,
    +.Xr pmc.p5 3 ,
    +.Xr pmc.p6 3 ,
    +.Xr pmc.corei7 3 ,
    +.Xr pmc.corei7uc 3 ,
    +.Xr pmc.westmere 3 ,
    +.Xr pmc.tsc 3 ,
    +.Xr pmc_cpuinfo 3 ,
    +.Xr pmclog 3 ,
    +.Xr hwpmc 4
    +.Sh HISTORY
    +The
    +.Nm pmc
    +library first appeared in
    +.Fx 6.0 .
    +.Sh AUTHORS
    +The
    +.Lb libpmc
    +library was written by
    +.An "Joseph Koshy"
    +.Aq jkoshy@FreeBSD.org .
    
    From ace006dec77b2fbb02f84f1cafff7d7b9ea2cea1 Mon Sep 17 00:00:00 2001
    From: Jack F Vogel 
    Date: Fri, 16 Apr 2010 17:27:20 +0000
    Subject: [PATCH 1977/2592] MFC bug fixes to em and igb from HEAD.
    
    ---
     sys/dev/e1000/if_em.c  | 155 +++++++++++++++++++++++++-------------
     sys/dev/e1000/if_em.h  |   3 +-
     sys/dev/e1000/if_igb.c |  81 +++++++++++++++-----
     sys/dev/e1000/if_lem.c | 164 ++---------------------------------------
     4 files changed, 173 insertions(+), 230 deletions(-)
    
    diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
    index f8329f89663..1db90121ddb 100644
    --- a/sys/dev/e1000/if_em.c
    +++ b/sys/dev/e1000/if_em.c
    @@ -93,7 +93,7 @@ int	em_display_debug_stats = 0;
     /*********************************************************************
      *  Driver version:
      *********************************************************************/
    -char em_driver_version[] = "7.0.0";
    +char em_driver_version[] = "7.0.5";
     
     
     /*********************************************************************
    @@ -192,7 +192,7 @@ static int	em_suspend(device_t);
     static int	em_resume(device_t);
     static void	em_start(struct ifnet *);
     static void	em_start_locked(struct ifnet *, struct tx_ring *);
    -#if __FreeBSD_version >= 800000
    +#ifdef EM_MULTIQUEUE
     static int	em_mq_start(struct ifnet *, struct mbuf *);
     static int	em_mq_start_locked(struct ifnet *,
     		    struct tx_ring *, struct mbuf *);
    @@ -797,7 +797,7 @@ em_resume(device_t dev)
      *  the packet is requeued.
      **********************************************************************/
     
    -#if __FreeBSD_version >= 800000
    +#ifdef EM_MULTIQUEUE
     static int
     em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
     {
    @@ -812,10 +812,18 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
     		return (err);
     	}
     
    +        /* Call cleanup if number of TX descriptors low */
    +	if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD)
    +		em_txeof(txr);
    +
     	enq = 0;
    -	if (m == NULL)
    +	if (m == NULL) {
     		next = drbr_dequeue(ifp, txr->br);
    -	else
    +	} else if (drbr_needs_enqueue(ifp, txr->br)) {
    +		if ((err = drbr_enqueue(ifp, txr->br, m)) != 0)
    +			return (err);
    +		next = drbr_dequeue(ifp, txr->br);
    +	} else
     		next = m;
     
     	/* Process the queue */
    @@ -830,12 +838,17 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
     		ETHER_BPF_MTAP(ifp, next);
     		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
                             break;
    +		if (txr->tx_avail < EM_MAX_SCATTER) {
    +			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +			break;
    +		}
     		next = drbr_dequeue(ifp, txr->br);
     	}
     
     	if (enq > 0) {
                     /* Set the watchdog */
                     txr->watchdog_check = TRUE;
    +		txr->watchdog_time = ticks;
     	}
     	return (err);
     }
    @@ -860,8 +873,7 @@ em_mq_start(struct ifnet *ifp, struct mbuf *m)
     	txr = &adapter->tx_rings[i];
     
     	if (EM_TX_TRYLOCK(txr)) {
    -		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
    -			error = em_mq_start_locked(ifp, txr, m);
    +		error = em_mq_start_locked(ifp, txr, m);
     		EM_TX_UNLOCK(txr);
     	} else 
     		error = drbr_enqueue(ifp, txr->br, m);
    @@ -888,7 +900,7 @@ em_qflush(struct ifnet *ifp)
     	if_qflush(ifp);
     }
     
    -#endif /* FreeBSD_version */
    +#endif /* EM_MULTIQUEUE */
     
     static void
     em_start_locked(struct ifnet *ifp, struct tx_ring *txr)
    @@ -905,8 +917,15 @@ em_start_locked(struct ifnet *ifp, struct tx_ring *txr)
     	if (!adapter->link_active)
     		return;
     
    -	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
    +        /* Call cleanup if number of TX descriptors low */
    +	if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD)
    +		em_txeof(txr);
     
    +	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
    +		if (txr->tx_avail < EM_MAX_SCATTER) {
    +			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +			break;
    +		}
                     IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
     		if (m_head == NULL)
     			break;
    @@ -926,6 +945,7 @@ em_start_locked(struct ifnet *ifp, struct tx_ring *txr)
     		ETHER_BPF_MTAP(ifp, m_head);
     
     		/* Set timeout in case hardware has problems transmitting. */
    +		txr->watchdog_time = ticks;
     		txr->watchdog_check = TRUE;
     	}
     
    @@ -1118,6 +1138,10 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
     			reinit = 1;
     		}
    +		if (mask & IFCAP_VLAN_HWFILTER) {
    +			ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
    +			reinit = 1;
    +		}
     		if ((mask & IFCAP_WOL) &&
     		    (ifp->if_capabilities & IFCAP_WOL) != 0) {
     			if (mask & IFCAP_WOL_MCAST)
    @@ -1228,8 +1252,18 @@ em_init_locked(struct adapter *adapter)
     	/* Setup VLAN support, basic and offload if available */
     	E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
     
    -	/* Use real VLAN Filter support */
    -	em_setup_vlan_hw_support(adapter);
    +	/* Use real VLAN Filter support? */
    +	if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
    +		if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
    +			/* Use real VLAN Filter support */
    +			em_setup_vlan_hw_support(adapter);
    +		else {
    +			u32 ctrl;
    +			ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
    +			ctrl |= E1000_CTRL_VME;
    +			E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
    +		}
    +	}
     
     	/* Set hardware offload abilities */
     	ifp->if_hwassist = 0;
    @@ -1337,11 +1371,13 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
     	}
     	EM_CORE_UNLOCK(adapter);
     
    +	EM_RX_LOCK(rxr);
     	rx_done = em_rxeof(rxr, count);
    +	EM_RX_UNLOCK(rxr);
     
     	EM_TX_LOCK(txr);
     	em_txeof(txr);
    -#if __FreeBSD_version >= 800000
    +#ifdef EM_MULTIQUEUE
     	if (!drbr_empty(ifp, txr->br))
     		em_mq_start_locked(ifp, txr, NULL);
     #else
    @@ -1409,28 +1445,28 @@ em_handle_que(void *context, int pending)
     	struct ifnet	*ifp = adapter->ifp;
     	struct tx_ring	*txr = adapter->tx_rings;
     	struct rx_ring	*rxr = adapter->rx_rings;
    -	u32		loop = EM_MAX_LOOP;
    -	bool		more_rx, more_tx;
    +	bool		more_rx;
     
     
     	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    -		EM_TX_LOCK(txr);
    -		do {
    -			more_rx = em_rxeof(rxr, adapter->rx_process_limit);
    -			more_tx = em_txeof(txr);
    -		} while (loop-- && (more_rx || more_tx));
    +		EM_RX_LOCK(rxr);
    +		more_rx = em_rxeof(rxr, adapter->rx_process_limit);
    +		EM_RX_UNLOCK(rxr);
     
    -#if __FreeBSD_version >= 800000
    +		EM_TX_LOCK(txr);
    +		em_txeof(txr);
    +#ifdef EM_MULTIQUEUE
     		if (!drbr_empty(ifp, txr->br))
     			em_mq_start_locked(ifp, txr, NULL);
     #else
     		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
     			em_start_locked(ifp, txr);
     #endif
    -		if (more_rx || more_tx)
    -			taskqueue_enqueue(adapter->tq, &adapter->que_task);
    -
     		EM_TX_UNLOCK(txr);
    +		if (more_rx) {
    +			taskqueue_enqueue(adapter->tq, &adapter->que_task);
    +			return;
    +		}
     	}
     
     	em_enable_intr(adapter);
    @@ -1475,8 +1511,10 @@ em_msix_rx(void *arg)
     	struct adapter	*adapter = rxr->adapter;
     	bool		more;
     
    +	EM_RX_LOCK(rxr);
     	++rxr->rx_irq;
     	more = em_rxeof(rxr, adapter->rx_process_limit);
    +	EM_RX_UNLOCK(rxr);
     	if (more)
     		taskqueue_enqueue(rxr->tq, &rxr->rx_task);
     	else
    @@ -1513,14 +1551,16 @@ em_handle_rx(void *context, int pending)
     {
     	struct rx_ring	*rxr = context;
     	struct adapter	*adapter = rxr->adapter;
    -	u32		loop = EM_MAX_LOOP;
             bool            more;
     
    -        do {
    -		more = em_rxeof(rxr, adapter->rx_process_limit);
    -        } while (loop-- && more);
    -        /* Reenable this interrupt */
    -	E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims);
    +	EM_RX_LOCK(rxr);
    +	more = em_rxeof(rxr, adapter->rx_process_limit);
    +	EM_RX_UNLOCK(rxr);
    +	if (more)
    +		taskqueue_enqueue(rxr->tq, &rxr->rx_task);
    +	else
    +		/* Reenable this interrupt */
    +		E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims);
     }
     
     static void
    @@ -1529,16 +1569,13 @@ em_handle_tx(void *context, int pending)
     	struct tx_ring	*txr = context;
     	struct adapter	*adapter = txr->adapter;
     	struct ifnet	*ifp = adapter->ifp;
    -	u32		loop = EM_MAX_LOOP;
    -        bool            more;
     
     	if (!EM_TX_TRYLOCK(txr))
     		return;
    -	do {
    -		more = em_txeof(txr);
    -	} while (loop-- && more);
     
    -#if __FreeBSD_version >= 800000
    +	em_txeof(txr);
    +
    +#ifdef EM_MULTIQUEUE
     	if (!drbr_empty(ifp, txr->br))
     		em_mq_start_locked(ifp, txr, NULL);
     #else
    @@ -1706,13 +1743,6 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
     	txd_upper = txd_lower = txd_used = txd_saved = 0;
     	do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0);
     
    -        /*
    -         * Force a cleanup if number of TX descriptors
    -         * available hits the threshold
    -         */
    -	if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD)
    -		em_txeof(txr);
    -
     	/*
     	 * TSO workaround: 
     	 *  If an mbuf is only header we need  
    @@ -2642,7 +2672,7 @@ em_setup_interface(device_t dev, struct adapter *adapter)
     
     	ifp->if_capabilities = ifp->if_capenable = 0;
     
    -#if __FreeBSD_version >= 800000
    +#ifdef EM_MULTIQUEUE
     	/* Multiqueue tx functions */
     	ifp->if_transmit = em_mq_start;
     	ifp->if_qflush = em_qflush;
    @@ -2656,12 +2686,23 @@ em_setup_interface(device_t dev, struct adapter *adapter)
     	ifp->if_capenable |= IFCAP_TSO4;
     
     	/*
    -	 * Tell the upper layer(s) we support long frames.
    +	 * Tell the upper layer(s) we
    +	 * support full VLAN capability
     	 */
     	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
     	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
     	ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
     
    +	/*
    +	** Dont turn this on by default, if vlans are
    +	** created on another pseudo device (eg. lagg)
    +	** then vlan events are not passed thru, breaking
    +	** operation, but with HW FILTER off it works. If
    +	** using vlans directly on the em driver you can
    +	** enable this and get full hardware tag filtering.
    +	*/
    +	ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
    +
     #ifdef DEVICE_POLLING
     	ifp->if_capabilities |= IFCAP_POLLING;
     #endif
    @@ -3681,6 +3722,8 @@ em_refresh_mbufs(struct rx_ring *rxr, int limit)
     		rxr->next_to_refresh = i;
     	}
     update:
    +	bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
    +	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
     	if (cleaned != -1) /* Update tail index */
     		E1000_WRITE_REG(&adapter->hw,
     		    E1000_RDT(rxr->me), cleaned);
    @@ -3972,7 +4015,7 @@ em_initialize_receive_unit(struct adapter *adapter)
     	** When using MSIX interrupts we need to throttle
     	** using the EITR register (82574 only)
     	*/
    -	if (adapter->msix)
    +	if (hw->mac.type == e1000_82574)
     		for (int i = 0; i < 4; i++)
     			E1000_WRITE_REG(hw, E1000_EITR_82574(i),
     			    DEFAULT_ITR);
    @@ -4015,6 +4058,9 @@ em_initialize_receive_unit(struct adapter *adapter)
     	    E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
     	    (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
     
    +        /* Strip the CRC */
    +        rctl |= E1000_RCTL_SECRC;
    +
             /* Make sure VLAN Filters are off */
             rctl &= ~E1000_RCTL_VFE;
     	rctl &= ~E1000_RCTL_SBP;
    @@ -4046,15 +4092,15 @@ static int
     em_rxeof(struct rx_ring *rxr, int count)
     {
     	struct adapter		*adapter = rxr->adapter;
    -	struct ifnet		*ifp = adapter->ifp;;
    +	struct ifnet		*ifp = adapter->ifp;
     	struct mbuf		*mp, *sendmp;
    -	u8			status;
    +	u8			status = 0;
     	u16 			len;
     	int			i, processed, rxdone = 0;
     	bool			eop;
     	struct e1000_rx_desc	*cur;
     
    -	EM_RX_LOCK(rxr);
    +	EM_RX_LOCK_ASSERT(rxr);
     
     	for (i = rxr->next_to_check, processed = 0; count != 0;) {
     
    @@ -4109,6 +4155,10 @@ em_rxeof(struct rx_ring *rxr, int count)
     					    E1000_RXD_SPC_VLAN_MASK);
     					rxr->fmp->m_flags |= M_VLANTAG;
     				}
    +#ifdef EM_MULTIQUEUE
    +				rxr->fmp->m_pkthdr.flowid = curcpu;
    +				rxr->fmp->m_flags |= M_FLOWID;
    +#endif
     #ifndef __NO_STRICT_ALIGNMENT
     skip:
     #endif
    @@ -4162,8 +4212,11 @@ skip:
     
     	rxr->next_to_check = i;
     
    -	EM_RX_UNLOCK(rxr);
    +#ifdef DEVICE_POLLING
     	return (rxdone);
    +#else
    +	return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
    +#endif
     }
     
     #ifndef __NO_STRICT_ALIGNMENT
    @@ -4346,7 +4399,7 @@ em_enable_intr(struct adapter *adapter)
     	struct e1000_hw *hw = &adapter->hw;
     	u32 ims_mask = IMS_ENABLE_MASK;
     
    -	if (adapter->msix) {
    +	if (hw->mac.type == e1000_82574) {
     		E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK);
     		ims_mask |= EM_MSIX_MASK;
     	} 
    @@ -4358,7 +4411,7 @@ em_disable_intr(struct adapter *adapter)
     {
     	struct e1000_hw *hw = &adapter->hw;
     
    -	if (adapter->msix)
    +	if (hw->mac.type == e1000_82574)
     		E1000_WRITE_REG(hw, EM_EIAC, 0);
     	E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
     }
    diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
    index 96d217b420d..225a8d08b8e 100644
    --- a/sys/dev/e1000/if_em.h
    +++ b/sys/dev/e1000/if_em.h
    @@ -223,7 +223,7 @@
     #define HW_DEBUGOUT1(S, A)          if (DEBUG_HW) printf(S "\n", A)
     #define HW_DEBUGOUT2(S, A, B)       if (DEBUG_HW) printf(S "\n", A, B)
     
    -#define EM_MAX_SCATTER		64
    +#define EM_MAX_SCATTER		32
     #define EM_VFTA_SIZE		128
     #define EM_TSO_SIZE		(65535 + sizeof(struct ether_vlan_header))
     #define EM_TSO_SEG_SIZE		4096	/* Max dma segment size */
    @@ -453,5 +453,6 @@ struct em_buffer {
     #define	EM_RX_UNLOCK(_sc)		mtx_unlock(&(_sc)->rx_mtx)
     #define	EM_CORE_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->core_mtx, MA_OWNED)
     #define	EM_TX_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
    +#define	EM_RX_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->rx_mtx, MA_OWNED)
     
     #endif /* _EM_H_DEFINED_ */
    diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
    index 5fdd52c163b..e901bc24e2f 100644
    --- a/sys/dev/e1000/if_igb.c
    +++ b/sys/dev/e1000/if_igb.c
    @@ -99,7 +99,7 @@ int	igb_display_debug_stats = 0;
     /*********************************************************************
      *  Driver version:
      *********************************************************************/
    -char igb_driver_version[] = "version - 1.9.3";
    +char igb_driver_version[] = "version - 1.9.5";
     
     
     /*********************************************************************
    @@ -758,8 +758,15 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp)
     	if (!adapter->link_active)
     		return;
     
    -	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
    +	/* Call cleanup if number of TX descriptors low */
    +	if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD)
    +		igb_txeof(txr);
     
    +	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
    +		if (txr->tx_avail <= IGB_TX_OP_THRESHOLD) {
    +			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +			break;
    +		}
     		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
     		if (m_head == NULL)
     			break;
    @@ -779,6 +786,7 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp)
     		ETHER_BPF_MTAP(ifp, m_head);
     
     		/* Set watchdog on */
    +		txr->watchdog_time = ticks;
     		txr->watchdog_check = TRUE;
     	}
     }
    @@ -817,8 +825,6 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
     	/* Which queue to use */
     	if ((m->m_flags & M_FLOWID) != 0)
     		i = m->m_pkthdr.flowid % adapter->num_queues;
    -	else
    -		i = curcpu % adapter->num_queues;
     
     	txr = &adapter->tx_rings[i];
     
    @@ -847,6 +853,10 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
     		return (err);
     	}
     
    +	/* Call cleanup if number of TX descriptors low */
    +	if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD)
    +		igb_txeof(txr);
    +
     	enq = 0;
     	if (m == NULL) {
     		next = drbr_dequeue(ifp, txr->br);
    @@ -856,6 +866,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
     		next = drbr_dequeue(ifp, txr->br);
     	} else
     		next = m;
    +
     	/* Process the queue */
     	while (next != NULL) {
     		if ((err = igb_xmit(txr, &next)) != 0) {
    @@ -877,6 +888,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
     	if (enq > 0) {
     		/* Set the watchdog */
     		txr->watchdog_check = TRUE;
    +		txr->watchdog_time = ticks;
     	}
     	return (err);
     }
    @@ -1055,6 +1067,10 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
     			reinit = 1;
     		}
    +		if (mask & IFCAP_VLAN_HWFILTER) {
    +			ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
    +			reinit = 1;
    +		}
     		if (mask & IFCAP_LRO) {
     			ifp->if_capenable ^= IFCAP_LRO;
     			reinit = 1;
    @@ -1110,6 +1126,19 @@ igb_init_locked(struct adapter *adapter)
     
     	E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
     
    +        /* Use real VLAN Filter support? */
    +	if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
    +		if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
    +			/* Use real VLAN Filter support */
    +			igb_setup_vlan_hw_support(adapter);
    +		else {
    +			u32 ctrl;
    +			ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
    +			ctrl |= E1000_CTRL_VME;
    +			E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
    +		}
    +	}
    +                                
     	/* Set hardware offload abilities */
     	ifp->if_hwassist = 0;
     	if (ifp->if_capenable & IFCAP_TXCSUM) {
    @@ -1231,19 +1260,13 @@ igb_handle_que(void *context, int pending)
     	struct adapter *adapter = que->adapter;
     	struct tx_ring *txr = que->txr;
     	struct ifnet	*ifp = adapter->ifp;
    -	u32		loop = IGB_MAX_LOOP;
     	bool		more;
     
    -	/* RX first */
    -	do {
    +	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
     		more = igb_rxeof(que, -1);
    -	} while (loop-- && more);
     
    -	if (IGB_TX_TRYLOCK(txr)) {
    -		loop = IGB_MAX_LOOP;
    -		do {
    -			more = igb_txeof(txr);
    -		} while (loop-- && more);
    +		IGB_TX_LOCK(txr);
    +		igb_txeof(txr);
     #if __FreeBSD_version >= 800000
     		igb_mq_start_locked(ifp, txr, NULL);
     #else
    @@ -1251,6 +1274,10 @@ igb_handle_que(void *context, int pending)
     			igb_start_locked(txr, ifp);
     #endif
     		IGB_TX_UNLOCK(txr);
    +		if (more) {
    +			taskqueue_enqueue(que->tq, &que->que_task);
    +			return;
    +		}
     	}
     
     	/* Reenable this interrupt */
    @@ -1436,7 +1463,7 @@ igb_msix_que(void *arg)
             if (adapter->hw.mac.type == e1000_82575)
                     newitr |= newitr << 16;
             else
    -                newitr |= 0x8000000;
    +                newitr |= E1000_EITR_CNT_IGNR;
                      
             /* save for next interrupt */
             que->eitr_setting = newitr;
    @@ -2340,7 +2367,7 @@ igb_configure_queues(struct adapter *adapter)
             if (hw->mac.type == e1000_82575)
                     newitr |= newitr << 16;
             else
    -                newitr |= 0x8000000;
    +                newitr |= E1000_EITR_CNT_IGNR;
     
     	for (int i = 0; i < adapter->num_queues; i++) {
     		que = &adapter->queues[i];
    @@ -2669,12 +2696,23 @@ igb_setup_interface(device_t dev, struct adapter *adapter)
     #endif
     
     	/*
    -	 * Tell the upper layer(s) we support long frames.
    +	 * Tell the upper layer(s) we
    +	 * support full VLAN capability.
     	 */
     	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
     	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
     	ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
     
    +	/*
    +	** Dont turn this on by default, if vlans are
    +	** created on another pseudo device (eg. lagg)
    +	** then vlan events are not passed thru, breaking
    +	** operation, but with HW FILTER off it works. If
    +	** using vlans directly on the em driver you can
    +	** enable this and get full hardware tag filtering.
    +	*/
    +	ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
    +
     	/*
     	 * Specify the media types supported by this adapter and register
     	 * callbacks to update media and link information
    @@ -3779,6 +3817,9 @@ igb_setup_receive_ring(struct rx_ring *rxr)
     		/* Update descriptor */
     		rxr->rx_base[j].read.pkt_addr = htole64(pseg[0].ds_addr);
             }
    +
    +	/* Setup our descriptor indices */
    +	rxr->next_to_check = 0;
     	rxr->next_to_refresh = 0;
     	rxr->lro_enabled = FALSE;
     
    @@ -4672,10 +4713,12 @@ igb_update_stats_counters(struct adapter *adapter)
     {
     	struct ifnet   *ifp;
     
    -	if(adapter->hw.phy.media_type == e1000_media_type_copper ||
    +	if (adapter->hw.phy.media_type == e1000_media_type_copper ||
     	   (E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
    -		adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
    -		adapter->stats.sec += E1000_READ_REG(&adapter->hw, E1000_SEC);
    +		adapter->stats.symerrs +=
    +		    E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
    +		adapter->stats.sec +=
    +		    E1000_READ_REG(&adapter->hw, E1000_SEC);
     	}
     	adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, E1000_CRCERRS);
     	adapter->stats.mpc += E1000_READ_REG(&adapter->hw, E1000_MPC);
    diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c
    index cf71f2bb74b..825fb4ee6f0 100644
    --- a/sys/dev/e1000/if_lem.c
    +++ b/sys/dev/e1000/if_lem.c
    @@ -39,9 +39,6 @@
     
     #include 
     #include 
    -#if __FreeBSD_version >= 800000
    -#include 
    -#endif
     #include 
     #include 
     #include 
    @@ -94,7 +91,7 @@ int	lem_display_debug_stats = 0;
     /*********************************************************************
      *  Legacy Em Driver version:
      *********************************************************************/
    -char lem_driver_version[] = "1.0.0";
    +char lem_driver_version[] = "1.0.1";
     
     
     /*********************************************************************
    @@ -177,11 +174,6 @@ static int	lem_suspend(device_t);
     static int	lem_resume(device_t);
     static void	lem_start(struct ifnet *);
     static void	lem_start_locked(struct ifnet *ifp);
    -#if __FreeBSD_version >= 800000
    -static int	lem_mq_start(struct ifnet *, struct mbuf *);
    -static int	lem_mq_start_locked(struct ifnet *, struct mbuf *);
    -static void	lem_qflush(struct ifnet *);
    -#endif
     static int	lem_ioctl(struct ifnet *, u_long, caddr_t);
     static void	lem_init(void *);
     static void	lem_init_locked(struct adapter *);
    @@ -304,12 +296,6 @@ MODULE_DEPEND(lem, ether, 1, 1, 1);
     
     #define EM_TICKS_TO_USECS(ticks)	((1024 * (ticks) + 500) / 1000)
     #define EM_USECS_TO_TICKS(usecs)	((1000 * (usecs) + 512) / 1024)
    -#define M_TSO_LEN			66
    -
    -/* Allow common code without TSO */
    -#ifndef CSUM_TSO
    -#define CSUM_TSO	0
    -#endif
     
     static int lem_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV);
     static int lem_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR);
    @@ -827,118 +813,6 @@ lem_resume(device_t dev)
     }
     
     
    -/*********************************************************************
    - *  Transmit entry point
    - *
    - *  em_start is called by the stack to initiate a transmit.
    - *  The driver will remain in this routine as long as there are
    - *  packets to transmit and transmit resources are available.
    - *  In case resources are not available stack is notified and
    - *  the packet is requeued.
    - **********************************************************************/
    -
    -#if __FreeBSD_version >= 800000
    -static int
    -lem_mq_start_locked(struct ifnet *ifp, struct mbuf *m)
    -{
    -	struct adapter	*adapter = ifp->if_softc;
    -	struct mbuf	*next;
    -	int error = E1000_SUCCESS;
    -
    -	EM_TX_LOCK_ASSERT(adapter);
    -	/* To allow being called from a tasklet */
    -	if (m == NULL)
    -		goto process;
    -
    -	if (((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
    -	    IFF_DRV_RUNNING)
    -	    || (!adapter->link_active)) {
    -		error = drbr_enqueue(ifp, adapter->br, m);
    -		return (error);
    -	} else if (drbr_empty(ifp, adapter->br) &&
    -	    (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) {
    -		if ((error = lem_xmit(adapter, &m)) != 0) {
    -			if (m)
    -				error = drbr_enqueue(ifp, adapter->br, m);
    -			return (error);
    -		} else {
    -			/*
    -			 * We've bypassed the buf ring so we need to update
    -			 * ifp directly
    -			 */
    -			drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags);
    -			/*
    -			** Send a copy of the frame to the BPF
    -			** listener and set the watchdog on.
    -			*/
    -			ETHER_BPF_MTAP(ifp, m);
    -			adapter->watchdog_check = TRUE;
    -		}
    -	} else if ((error = drbr_enqueue(ifp, adapter->br, m)) != 0)
    -		return (error);
    -	
    -process:
    -	if (drbr_empty(ifp, adapter->br))
    -		return(error);
    -        /* Process the queue */
    -        while (TRUE) {
    -                if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
    -                        break;
    -                next = drbr_dequeue(ifp, adapter->br);
    -                if (next == NULL)
    -                        break;
    -                if ((error = lem_xmit(adapter, &next)) != 0) {
    -			if (next != NULL)
    -				error = drbr_enqueue(ifp, adapter->br, next);
    -                        break;
    -		}
    -		drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
    -                ETHER_BPF_MTAP(ifp, next);
    -                /* Set the watchdog */
    -		adapter->watchdog_check = TRUE;
    -        }
    -
    -        if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
    -                ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    -
    -	return (error);
    -}
    -
    -/*
    -** Multiqueue capable stack interface, this is not
    -** yet truely multiqueue, but that is coming...
    -*/
    -static int
    -lem_mq_start(struct ifnet *ifp, struct mbuf *m)
    -{
    -	
    -	struct adapter *adapter = ifp->if_softc;
    -	int error = 0;
    -
    -	if (EM_TX_TRYLOCK(adapter)) {
    -		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
    -			error = lem_mq_start_locked(ifp, m);
    -		EM_TX_UNLOCK(adapter);
    -	} else 
    -		error = drbr_enqueue(ifp, adapter->br, m);
    -
    -	return (error);
    -}
    -
    -static void
    -lem_qflush(struct ifnet *ifp)
    -{
    -	struct mbuf *m;
    -	struct adapter *adapter = (struct adapter *)ifp->if_softc;
    -
    -	EM_TX_LOCK(adapter);
    -	while ((m = buf_ring_dequeue_sc(adapter->br)) != NULL)
    -		m_freem(m);
    -	if_qflush(ifp);
    -	EM_TX_UNLOCK(adapter);
    -}
    -#endif /* FreeBSD_version */
    -
     static void
     lem_start_locked(struct ifnet *ifp)
     {
    @@ -975,6 +849,7 @@ lem_start_locked(struct ifnet *ifp)
     
     		/* Set timeout in case hardware has problems transmitting. */
     		adapter->watchdog_check = TRUE;
    +		adapter->watchdog_time = ticks;
     	}
     	if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
     		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    @@ -1151,12 +1026,6 @@ lem_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     			ifp->if_capenable ^= IFCAP_HWCSUM;
     			reinit = 1;
     		}
    -#if __FreeBSD_version >= 700000
    -		if (mask & IFCAP_TSO4) {
    -			ifp->if_capenable ^= IFCAP_TSO4;
    -			reinit = 1;
    -		}
    -#endif
     		if (mask & IFCAP_VLAN_HWTAGGING) {
     			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
     			reinit = 1;
    @@ -1279,10 +1148,6 @@ lem_init_locked(struct adapter *adapter)
     	if (adapter->hw.mac.type >= e1000_82543) {
     		if (ifp->if_capenable & IFCAP_TXCSUM)
     			ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
    -#if __FreeBSD_version >= 700000
    -		if (ifp->if_capenable & IFCAP_TSO4)
    -			ifp->if_hwassist |= CSUM_TSO;
    -#endif
     	}
     
     	/* Configure for OS presence */
    @@ -1394,13 +1259,8 @@ lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
     
     	EM_TX_LOCK(adapter);
     	lem_txeof(adapter);
    -#if __FreeBSD_version >= 800000
    -	if (!drbr_empty(ifp, adapter->br))
    -		lem_mq_start_locked(ifp, NULL);
    -#else
     	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
     		lem_start_locked(ifp);
    -#endif
     	EM_TX_UNLOCK(adapter);
     	return (rx_done);
     }
    @@ -1494,14 +1354,8 @@ lem_handle_rxtx(void *context, int pending)
     			taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
     		EM_TX_LOCK(adapter);
     		lem_txeof(adapter);
    -
    -#if __FreeBSD_version >= 800000
    -		if (!drbr_empty(ifp, adapter->br))
    -			lem_mq_start_locked(ifp, NULL);
    -#else
     		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
     			lem_start_locked(ifp);
    -#endif
     		EM_TX_UNLOCK(adapter);
     	}
     
    @@ -1852,15 +1706,17 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
             if (mtag != NULL) {
                     ctxd->upper.fields.special =
                         htole16(VLAN_TAG_VALUE(mtag));
    +                ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
    +	}
     #else /* FreeBSD 7 */
     	if (m_head->m_flags & M_VLANTAG) {
     		/* Set the vlan id. */
     		ctxd->upper.fields.special =
     		    htole16(m_head->m_pkthdr.ether_vtag);
    -#endif
                     /* Tell hardware to add tag */
                     ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
             }
    +#endif
     
             tx_buffer->m_head = m_head;
     	tx_buffer_mapped->map = tx_buffer->map;
    @@ -2544,12 +2400,6 @@ lem_setup_interface(device_t dev, struct adapter *adapter)
     
     	ifp->if_capabilities = ifp->if_capenable = 0;
     
    -#if __FreeBSD_version >= 800000
    -	/* Multiqueue tx functions */
    -	ifp->if_transmit = lem_mq_start;
    -	ifp->if_qflush = lem_qflush;
    -	adapter->br = buf_ring_alloc(4096, M_DEVBUF, M_WAITOK, &adapter->tx_mtx);
    -#endif	
     	if (adapter->hw.mac.type >= e1000_82543) {
     		int version_cap;
     #if __FreeBSD_version < 700000
    @@ -4549,10 +4399,6 @@ lem_print_hw_stats(struct adapter *adapter)
     	    (long long)adapter->stats.gprc);
     	device_printf(dev, "Good Packets Xmtd = %lld\n",
     	    (long long)adapter->stats.gptc);
    -	device_printf(dev, "TSO Contexts Xmtd = %lld\n",
    -	    (long long)adapter->stats.tsctc);
    -	device_printf(dev, "TSO Contexts Failed = %lld\n",
    -	    (long long)adapter->stats.tsctfc);
     }
     
     /**********************************************************************
    
    From 42fc50186401ed667ca268429c04b446a672c33c Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:38:26 +0000
    Subject: [PATCH 1978/2592] Merge of SVN 196507.
    
    This optimizes the sack handling a bit and
    restructures it so its much more readable ;-)
    ---
     sys/netinet/sctp_indata.c | 715 ++++++++++++++------------------------
     1 file changed, 255 insertions(+), 460 deletions(-)
    
    diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
    index 5914105c147..9174522237b 100644
    --- a/sys/netinet/sctp_indata.c
    +++ b/sys/netinet/sctp_indata.c
    @@ -2525,6 +2525,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	 */
     	struct sctp_association *asoc;
     	int at;
    +	uint8_t comb_byte;
     	int last_all_ones = 0;
     	int slide_from, slide_end, lgap, distance;
     
    @@ -2555,7 +2556,6 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     		memcpy(aux_array, asoc->mapping_array, 64);
     	/* EY do the same for nr_mapping_array */
     	if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    -
     		if (asoc->nr_mapping_array_size != asoc->mapping_array_size) {
     			/*
     			 * printf("\nEY-IN sack_check method: \nEY-" "The
    @@ -2582,13 +2582,18 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	 */
     	at = 0;
     	for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; slide_from++) {
    -
    -		if (asoc->mapping_array[slide_from] == 0xff) {
    +		/*
    +		 * We must combine the renegable and non-renegable arrays
    +		 * here to form a unified view of what is acked right now
    +		 * (since they are kept separate
    +		 */
    +		comb_byte = asoc->mapping_array[slide_from] | asoc->nr_mapping_array[slide_from];
    +		if (comb_byte == 0xff) {
     			at += 8;
     			last_all_ones = 1;
     		} else {
     			/* there is a 0 bit */
    -			at += sctp_map_lookup_tab[asoc->mapping_array[slide_from]];
    +			at += sctp_map_lookup_tab[comb_byte];
     			last_all_ones = 0;
     			break;
     		}
    @@ -3182,6 +3187,235 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
     	return (0);
     }
     
    +static int
    +sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1, uint32_t last_tsn,
    +    uint16_t frag_strt, uint16_t frag_end, int nr_sacking,
    +    int *num_frs,
    +    uint32_t * biggest_newly_acked_tsn,
    +    uint32_t * this_sack_lowest_newack,
    +    int *ecn_seg_sums)
    +{
    +	struct sctp_tmit_chunk *tp1;
    +	unsigned int theTSN;
    +	int j, wake_him = 0;
    +
    +	/* Recover the tp1 we last saw */
    +	tp1 = *p_tp1;
    +	if (tp1 == NULL) {
    +		tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue);
    +	}
    +	for (j = frag_strt; j <= frag_end; j++) {
    +		theTSN = j + last_tsn;
    +		while (tp1) {
    +			if (tp1->rec.data.doing_fast_retransmit)
    +				(*num_frs) += 1;
    +
    +			/*-
    +			 * CMT: CUCv2 algorithm. For each TSN being
    +			 * processed from the sent queue, track the
    +			 * next expected pseudo-cumack, or
    +			 * rtx_pseudo_cumack, if required. Separate
    +			 * cumack trackers for first transmissions,
    +			 * and retransmissions.
    +			 */
    +			if ((tp1->whoTo->find_pseudo_cumack == 1) && (tp1->sent < SCTP_DATAGRAM_RESEND) &&
    +			    (tp1->snd_count == 1)) {
    +				tp1->whoTo->pseudo_cumack = tp1->rec.data.TSN_seq;
    +				tp1->whoTo->find_pseudo_cumack = 0;
    +			}
    +			if ((tp1->whoTo->find_rtx_pseudo_cumack == 1) && (tp1->sent < SCTP_DATAGRAM_RESEND) &&
    +			    (tp1->snd_count > 1)) {
    +				tp1->whoTo->rtx_pseudo_cumack = tp1->rec.data.TSN_seq;
    +				tp1->whoTo->find_rtx_pseudo_cumack = 0;
    +			}
    +			if (tp1->rec.data.TSN_seq == theTSN) {
    +				if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
    +					/*-
    +					 * must be held until
    +					 * cum-ack passes
    +					 */
    +					/*-
    +					 * ECN Nonce: Add the nonce
    +					 * value to the sender's
    +					 * nonce sum
    +					 */
    +					if (tp1->sent < SCTP_DATAGRAM_RESEND) {
    +						/*-
    +						 * If it is less than RESEND, it is
    +						 * now no-longer in flight.
    +						 * Higher values may already be set
    +						 * via previous Gap Ack Blocks...
    +						 * i.e. ACKED or RESEND.
    +						 */
    +						if (compare_with_wrap(tp1->rec.data.TSN_seq,
    +						    *biggest_newly_acked_tsn, MAX_TSN)) {
    +							*biggest_newly_acked_tsn = tp1->rec.data.TSN_seq;
    +						}
    +						/*-
    +						 * CMT: SFR algo (and HTNA) - set
    +						 * saw_newack to 1 for dest being
    +						 * newly acked. update
    +						 * this_sack_highest_newack if
    +						 * appropriate.
    +						 */
    +						if (tp1->rec.data.chunk_was_revoked == 0)
    +							tp1->whoTo->saw_newack = 1;
    +
    +						if (compare_with_wrap(tp1->rec.data.TSN_seq,
    +						    tp1->whoTo->this_sack_highest_newack,
    +						    MAX_TSN)) {
    +							tp1->whoTo->this_sack_highest_newack =
    +							    tp1->rec.data.TSN_seq;
    +						}
    +						/*-
    +						 * CMT DAC algo: also update
    +						 * this_sack_lowest_newack
    +						 */
    +						if (*this_sack_lowest_newack == 0) {
    +							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    +								sctp_log_sack(*this_sack_lowest_newack,
    +								    last_tsn,
    +								    tp1->rec.data.TSN_seq,
    +								    0,
    +								    0,
    +								    SCTP_LOG_TSN_ACKED);
    +							}
    +							*this_sack_lowest_newack = tp1->rec.data.TSN_seq;
    +						}
    +						/*-
    +						 * CMT: CUCv2 algorithm. If (rtx-)pseudo-cumack for corresp
    +						 * dest is being acked, then we have a new (rtx-)pseudo-cumack. Set
    +						 * new_(rtx_)pseudo_cumack to TRUE so that the cwnd for this dest can be
    +						 * updated. Also trigger search for the next expected (rtx-)pseudo-cumack.
    +						 * Separate pseudo_cumack trackers for first transmissions and
    +						 * retransmissions.
    +						 */
    +						if (tp1->rec.data.TSN_seq == tp1->whoTo->pseudo_cumack) {
    +							if (tp1->rec.data.chunk_was_revoked == 0) {
    +								tp1->whoTo->new_pseudo_cumack = 1;
    +							}
    +							tp1->whoTo->find_pseudo_cumack = 1;
    +						}
    +						if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    +							sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK);
    +						}
    +						if (tp1->rec.data.TSN_seq == tp1->whoTo->rtx_pseudo_cumack) {
    +							if (tp1->rec.data.chunk_was_revoked == 0) {
    +								tp1->whoTo->new_pseudo_cumack = 1;
    +							}
    +							tp1->whoTo->find_rtx_pseudo_cumack = 1;
    +						}
    +						if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    +							sctp_log_sack(*biggest_newly_acked_tsn,
    +							    last_tsn,
    +							    tp1->rec.data.TSN_seq,
    +							    frag_strt,
    +							    frag_end,
    +							    SCTP_LOG_TSN_ACKED);
    +						}
    +						if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
    +							sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_GAP,
    +							    tp1->whoTo->flight_size,
    +							    tp1->book_size,
    +							    (uintptr_t) tp1->whoTo,
    +							    tp1->rec.data.TSN_seq);
    +						}
    +						sctp_flight_size_decrease(tp1);
    +						sctp_total_flight_decrease(stcb, tp1);
    +
    +						tp1->whoTo->net_ack += tp1->send_size;
    +						if (tp1->snd_count < 2) {
    +							/*-
    +							 * True non-retransmited chunk
    +							 */
    +							tp1->whoTo->net_ack2 += tp1->send_size;
    +
    +							/*-
    +							 * update RTO too ?
    +							 */
    +							if (tp1->do_rtt) {
    +								tp1->whoTo->RTO =
    +								    sctp_calculate_rto(stcb,
    +								    &stcb->asoc,
    +								    tp1->whoTo,
    +								    &tp1->sent_rcv_time,
    +								    sctp_align_safe_nocopy);
    +								tp1->do_rtt = 0;
    +							}
    +						}
    +					}
    +					if (tp1->sent <= SCTP_DATAGRAM_RESEND) {
    +						(*ecn_seg_sums) += tp1->rec.data.ect_nonce;
    +						(*ecn_seg_sums) &= SCTP_SACK_NONCE_SUM;
    +						if (compare_with_wrap(tp1->rec.data.TSN_seq,
    +						    stcb->asoc.this_sack_highest_gap,
    +						    MAX_TSN)) {
    +							stcb->asoc.this_sack_highest_gap =
    +							    tp1->rec.data.TSN_seq;
    +						}
    +						if (tp1->sent == SCTP_DATAGRAM_RESEND) {
    +							sctp_ucount_decr(stcb->asoc.sent_queue_retran_cnt);
    +#ifdef SCTP_AUDITING_ENABLED
    +							sctp_audit_log(0xB2,
    +							    (stcb->asoc.sent_queue_retran_cnt & 0x000000ff));
    +#endif
    +						}
    +					}
    +					/*-
    +					 * All chunks NOT UNSENT fall through here and are marked
    +					 * (leave PR-SCTP ones that are to skip alone though)
    +					 */
    +					if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
    +						tp1->sent = SCTP_DATAGRAM_MARKED;
    +
    +					if (tp1->rec.data.chunk_was_revoked) {
    +						/* deflate the cwnd */
    +						tp1->whoTo->cwnd -= tp1->book_size;
    +						tp1->rec.data.chunk_was_revoked = 0;
    +					}
    +					/* NR Sack code here */
    +					if (nr_sacking) {
    +						if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
    +							tp1->sent = SCTP_DATAGRAM_NR_MARKED;
    +						/*
    +						 * TAILQ_REMOVE(&asoc->sent_q
    +						 * ueue, tp1, sctp_next);
    +						 */
    +						if (tp1->data) {
    +							/*
    +							 * sa_ignore
    +							 * NO_NULL_CHK
    +							 */
    +							sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
    +							sctp_m_freem(tp1->data);
    +						}
    +						tp1->data = NULL;
    +						/* asoc->sent_queue_cnt--; */
    +						/*
    +						 * sctp_free_a_chunk(stcb,
    +						 * tp1);
    +						 */
    +						wake_him++;
    +					}
    +				}
    +				break;
    +			}	/* if (tp1->TSN_seq == theTSN) */
    +			if (compare_with_wrap(tp1->rec.data.TSN_seq, theTSN,
    +			    MAX_TSN))
    +				break;
    +
    +			tp1 = TAILQ_NEXT(tp1, sctp_next);
    +		}		/* end while (tp1) */
    +		/* In case the fragments were not in order we must reset */
    +		if (tp1 == NULL) {
    +			tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue);
    +		}
    +	}			/* end for (j = fragStart */
    +	*p_tp1 = tp1;
    +	return (wake_him);	/* Return value only used for nr-sack */
    +}
    +
    +
     static void
     sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct sctp_association *asoc,
         struct sctp_sack_chunk *ch, uint32_t last_tsn, uint32_t * biggest_tsn_acked,
    @@ -3194,8 +3428,7 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
     	struct sctp_sack *sack;
     	struct sctp_gap_ack_block *frag, block;
     	struct sctp_tmit_chunk *tp1;
    -	int i, j;
    -	unsigned int theTSN;
    +	int i;
     	int num_frs = 0;
     
     	uint16_t frag_strt, frag_end, primary_flag_set;
    @@ -3263,214 +3496,9 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
     			}
     			last_frag_high = frag_end + last_tsn;
     		}
    -		for (j = frag_strt; j <= frag_end; j++) {
    -			theTSN = j + last_tsn;
    -			while (tp1) {
    -				if (tp1->rec.data.doing_fast_retransmit)
    -					num_frs++;
    -
    -				/*
    -				 * CMT: CUCv2 algorithm. For each TSN being
    -				 * processed from the sent queue, track the
    -				 * next expected pseudo-cumack, or
    -				 * rtx_pseudo_cumack, if required. Separate
    -				 * cumack trackers for first transmissions,
    -				 * and retransmissions.
    -				 */
    -				if ((tp1->whoTo->find_pseudo_cumack == 1) && (tp1->sent < SCTP_DATAGRAM_RESEND) &&
    -				    (tp1->snd_count == 1)) {
    -					tp1->whoTo->pseudo_cumack = tp1->rec.data.TSN_seq;
    -					tp1->whoTo->find_pseudo_cumack = 0;
    -				}
    -				if ((tp1->whoTo->find_rtx_pseudo_cumack == 1) && (tp1->sent < SCTP_DATAGRAM_RESEND) &&
    -				    (tp1->snd_count > 1)) {
    -					tp1->whoTo->rtx_pseudo_cumack = tp1->rec.data.TSN_seq;
    -					tp1->whoTo->find_rtx_pseudo_cumack = 0;
    -				}
    -				if (tp1->rec.data.TSN_seq == theTSN) {
    -					if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
    -						/*
    -						 * must be held until
    -						 * cum-ack passes
    -						 */
    -						/*
    -						 * ECN Nonce: Add the nonce
    -						 * value to the sender's
    -						 * nonce sum
    -						 */
    -						if (tp1->sent < SCTP_DATAGRAM_RESEND) {
    -							/*-
    -							 * If it is less than RESEND, it is
    -							 * now no-longer in flight.
    -							 * Higher values may already be set
    -							 * via previous Gap Ack Blocks...
    -							 * i.e. ACKED or RESEND.
    -							 */
    -							if (compare_with_wrap(tp1->rec.data.TSN_seq,
    -							    *biggest_newly_acked_tsn, MAX_TSN)) {
    -								*biggest_newly_acked_tsn = tp1->rec.data.TSN_seq;
    -							}
    -							/*
    -							 * CMT: SFR algo
    -							 * (and HTNA) - set
    -							 * saw_newack to 1
    -							 * for dest being
    -							 * newly acked.
    -							 * update
    -							 * this_sack_highest_
    -							 * newack if
    -							 * appropriate.
    -							 */
    -							if (tp1->rec.data.chunk_was_revoked == 0)
    -								tp1->whoTo->saw_newack = 1;
    -
    -							if (compare_with_wrap(tp1->rec.data.TSN_seq,
    -							    tp1->whoTo->this_sack_highest_newack,
    -							    MAX_TSN)) {
    -								tp1->whoTo->this_sack_highest_newack =
    -								    tp1->rec.data.TSN_seq;
    -							}
    -							/*
    -							 * CMT DAC algo:
    -							 * also update
    -							 * this_sack_lowest_n
    -							 * ewack
    -							 */
    -							if (*this_sack_lowest_newack == 0) {
    -								if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    -									sctp_log_sack(*this_sack_lowest_newack,
    -									    last_tsn,
    -									    tp1->rec.data.TSN_seq,
    -									    0,
    -									    0,
    -									    SCTP_LOG_TSN_ACKED);
    -								}
    -								*this_sack_lowest_newack = tp1->rec.data.TSN_seq;
    -							}
    -							/*
    -							 * CMT: CUCv2
    -							 * algorithm. If
    -							 * (rtx-)pseudo-cumac
    -							 * k for corresp
    -							 * dest is being
    -							 * acked, then we
    -							 * have a new
    -							 * (rtx-)pseudo-cumac
    -							 * k. Set
    -							 * new_(rtx_)pseudo_c
    -							 * umack to TRUE so
    -							 * that the cwnd for
    -							 * this dest can be
    -							 * updated. Also
    -							 * trigger search
    -							 * for the next
    -							 * expected
    -							 * (rtx-)pseudo-cumac
    -							 * k. Separate
    -							 * pseudo_cumack
    -							 * trackers for
    -							 * first
    -							 * transmissions and
    -							 * retransmissions.
    -							 */
    -							if (tp1->rec.data.TSN_seq == tp1->whoTo->pseudo_cumack) {
    -								if (tp1->rec.data.chunk_was_revoked == 0) {
    -									tp1->whoTo->new_pseudo_cumack = 1;
    -								}
    -								tp1->whoTo->find_pseudo_cumack = 1;
    -							}
    -							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    -								sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK);
    -							}
    -							if (tp1->rec.data.TSN_seq == tp1->whoTo->rtx_pseudo_cumack) {
    -								if (tp1->rec.data.chunk_was_revoked == 0) {
    -									tp1->whoTo->new_pseudo_cumack = 1;
    -								}
    -								tp1->whoTo->find_rtx_pseudo_cumack = 1;
    -							}
    -							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    -								sctp_log_sack(*biggest_newly_acked_tsn,
    -								    last_tsn,
    -								    tp1->rec.data.TSN_seq,
    -								    frag_strt,
    -								    frag_end,
    -								    SCTP_LOG_TSN_ACKED);
    -							}
    -							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
    -								sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_GAP,
    -								    tp1->whoTo->flight_size,
    -								    tp1->book_size,
    -								    (uintptr_t) tp1->whoTo,
    -								    tp1->rec.data.TSN_seq);
    -							}
    -							sctp_flight_size_decrease(tp1);
    -							sctp_total_flight_decrease(stcb, tp1);
    -
    -							tp1->whoTo->net_ack += tp1->send_size;
    -							if (tp1->snd_count < 2) {
    -								/*
    -								 * True
    -								 * non-retran
    -								 * smited
    -								 * chunk */
    -								tp1->whoTo->net_ack2 += tp1->send_size;
    -
    -								/*
    -								 * update RTO
    -								 * too ? */
    -								if (tp1->do_rtt) {
    -									tp1->whoTo->RTO =
    -									    sctp_calculate_rto(stcb,
    -									    asoc,
    -									    tp1->whoTo,
    -									    &tp1->sent_rcv_time,
    -									    sctp_align_safe_nocopy);
    -									tp1->do_rtt = 0;
    -								}
    -							}
    -						}
    -						if (tp1->sent <= SCTP_DATAGRAM_RESEND) {
    -							(*ecn_seg_sums) += tp1->rec.data.ect_nonce;
    -							(*ecn_seg_sums) &= SCTP_SACK_NONCE_SUM;
    -							if (compare_with_wrap(tp1->rec.data.TSN_seq,
    -							    asoc->this_sack_highest_gap,
    -							    MAX_TSN)) {
    -								asoc->this_sack_highest_gap =
    -								    tp1->rec.data.TSN_seq;
    -							}
    -							if (tp1->sent == SCTP_DATAGRAM_RESEND) {
    -								sctp_ucount_decr(asoc->sent_queue_retran_cnt);
    -#ifdef SCTP_AUDITING_ENABLED
    -								sctp_audit_log(0xB2,
    -								    (asoc->sent_queue_retran_cnt & 0x000000ff));
    -#endif
    -							}
    -						}
    -						/*
    -						 * All chunks NOT UNSENT
    -						 * fall through here and are
    -						 * marked (leave PR-SCTP
    -						 * ones that are to skip
    -						 * alone though)
    -						 */
    -						if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
    -							tp1->sent = SCTP_DATAGRAM_MARKED;
    -
    -						if (tp1->rec.data.chunk_was_revoked) {
    -							/* deflate the cwnd */
    -							tp1->whoTo->cwnd -= tp1->book_size;
    -							tp1->rec.data.chunk_was_revoked = 0;
    -						}
    -					}
    -					break;
    -				}	/* if (tp1->TSN_seq == theTSN) */
    -				if (compare_with_wrap(tp1->rec.data.TSN_seq, theTSN,
    -				    MAX_TSN))
    -					break;
    -
    -				tp1 = TAILQ_NEXT(tp1, sctp_next);
    -			}	/* end while (tp1) */
    -		}		/* end for (j = fragStart */
    +		sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, frag_end,
    +		    0, &num_frs, biggest_newly_acked_tsn,
    +		    this_sack_lowest_newack, ecn_seg_sums);
     		frag = (struct sctp_gap_ack_block *)sctp_m_getptr(m, *offset,
     		    sizeof(struct sctp_gap_ack_block), (uint8_t *) & block);
     		*offset += sizeof(block);
    @@ -6855,9 +6883,8 @@ sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb,
     	struct sctp_gap_ack_block *frag, block;
     	struct sctp_nr_gap_ack_block *nr_frag, nr_block;
     	struct sctp_tmit_chunk *tp1;
    -	uint32_t i, j;
    +	uint32_t i;
     	int wake_him = 0;
    -	uint32_t theTSN;
     	int num_frs = 0;
     
     	uint16_t frag_strt, frag_end, primary_flag_set;
    @@ -6932,213 +6959,9 @@ sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb,
     			}
     			last_frag_high = frag_end + last_tsn;
     		}
    -		for (j = frag_strt; j <= frag_end; j++) {
    -			theTSN = j + last_tsn;
    -			while (tp1) {
    -				if (tp1->rec.data.doing_fast_retransmit)
    -					num_frs++;
    -
    -				/*
    -				 * CMT: CUCv2 algorithm. For each TSN being
    -				 * processed from the sent queue, track the
    -				 * next expected pseudo-cumack, or
    -				 * rtx_pseudo_cumack, if required. Separate
    -				 * cumack trackers for first transmissions,
    -				 * and retransmissions.
    -				 */
    -				if ((tp1->whoTo->find_pseudo_cumack == 1) && (tp1->sent < SCTP_DATAGRAM_RESEND) &&
    -				    (tp1->snd_count == 1)) {
    -					tp1->whoTo->pseudo_cumack = tp1->rec.data.TSN_seq;
    -					tp1->whoTo->find_pseudo_cumack = 0;
    -				}
    -				if ((tp1->whoTo->find_rtx_pseudo_cumack == 1) && (tp1->sent < SCTP_DATAGRAM_RESEND) &&
    -				    (tp1->snd_count > 1)) {
    -					tp1->whoTo->rtx_pseudo_cumack = tp1->rec.data.TSN_seq;
    -					tp1->whoTo->find_rtx_pseudo_cumack = 0;
    -				}
    -				if (tp1->rec.data.TSN_seq == theTSN) {
    -					if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
    -						/*
    -						 * must be held until
    -						 * cum-ack passes
    -						 */
    -						/*
    -						 * ECN Nonce: Add the nonce
    -						 * value to the sender's
    -						 * nonce sum
    -						 */
    -						if (tp1->sent < SCTP_DATAGRAM_RESEND) {
    -							/*-
    -						         * If it is less than RESEND, it is
    -						         * now no-longer in flight.
    -						         * Higher values may already be set
    -						         * via previous Gap Ack Blocks...
    -						         * i.e. ACKED or RESEND.
    -						         */
    -							if (compare_with_wrap(tp1->rec.data.TSN_seq,
    -							    *biggest_newly_acked_tsn, MAX_TSN)) {
    -								*biggest_newly_acked_tsn = tp1->rec.data.TSN_seq;
    -							}
    -							/*
    -							 * CMT: SFR algo
    -							 * (and HTNA) - set
    -							 * saw_newack to 1
    -							 * for dest being
    -							 * newly acked.
    -							 * update
    -							 * this_sack_highest_
    -							 * newack if
    -							 * appropriate.
    -							 */
    -							if (tp1->rec.data.chunk_was_revoked == 0)
    -								tp1->whoTo->saw_newack = 1;
    -
    -							if (compare_with_wrap(tp1->rec.data.TSN_seq,
    -							    tp1->whoTo->this_sack_highest_newack,
    -							    MAX_TSN)) {
    -								tp1->whoTo->this_sack_highest_newack =
    -								    tp1->rec.data.TSN_seq;
    -							}
    -							/*
    -							 * CMT DAC algo:
    -							 * also update
    -							 * this_sack_lowest_n
    -							 * ewack
    -							 */
    -							if (*this_sack_lowest_newack == 0) {
    -								if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    -									sctp_log_sack(*this_sack_lowest_newack,
    -									    last_tsn,
    -									    tp1->rec.data.TSN_seq,
    -									    0,
    -									    0,
    -									    SCTP_LOG_TSN_ACKED);
    -								}
    -								*this_sack_lowest_newack = tp1->rec.data.TSN_seq;
    -							}
    -							/*
    -							 * CMT: CUCv2
    -							 * algorithm. If
    -							 * (rtx-)pseudo-cumac
    -							 * k for corresp
    -							 * dest is being
    -							 * acked, then we
    -							 * have a new
    -							 * (rtx-)pseudo-cumac
    -							 * k. Set
    -							 * new_(rtx_)pseudo_c
    -							 * umack to TRUE so
    -							 * that the cwnd for
    -							 * this dest can be
    -							 * updated. Also
    -							 * trigger search
    -							 * for the next
    -							 * expected
    -							 * (rtx-)pseudo-cumac
    -							 * k. Separate
    -							 * pseudo_cumack
    -							 * trackers for
    -							 * first
    -							 * transmissions and
    -							 * retransmissions.
    -							 */
    -							if (tp1->rec.data.TSN_seq == tp1->whoTo->pseudo_cumack) {
    -								if (tp1->rec.data.chunk_was_revoked == 0) {
    -									tp1->whoTo->new_pseudo_cumack = 1;
    -								}
    -								tp1->whoTo->find_pseudo_cumack = 1;
    -							}
    -							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    -								sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK);
    -							}
    -							if (tp1->rec.data.TSN_seq == tp1->whoTo->rtx_pseudo_cumack) {
    -								if (tp1->rec.data.chunk_was_revoked == 0) {
    -									tp1->whoTo->new_pseudo_cumack = 1;
    -								}
    -								tp1->whoTo->find_rtx_pseudo_cumack = 1;
    -							}
    -							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    -								sctp_log_sack(*biggest_newly_acked_tsn,
    -								    last_tsn,
    -								    tp1->rec.data.TSN_seq,
    -								    frag_strt,
    -								    frag_end,
    -								    SCTP_LOG_TSN_ACKED);
    -							}
    -							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
    -								sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_GAP,
    -								    tp1->whoTo->flight_size,
    -								    tp1->book_size,
    -								    (uintptr_t) tp1->whoTo,
    -								    tp1->rec.data.TSN_seq);
    -							}
    -							sctp_flight_size_decrease(tp1);
    -							sctp_total_flight_decrease(stcb, tp1);
    -
    -							tp1->whoTo->net_ack += tp1->send_size;
    -							if (tp1->snd_count < 2) {
    -								/*
    -								 * True
    -								 * non-retran
    -								 * smited
    -								 * chunk
    -								 */
    -								tp1->whoTo->net_ack2 += tp1->send_size;
    -
    -								/*
    -								 * update
    -								 * RTO too ?
    -								 */
    -								if (tp1->do_rtt) {
    -									tp1->whoTo->RTO =
    -									    sctp_calculate_rto(stcb,
    -									    asoc,
    -									    tp1->whoTo,
    -									    &tp1->sent_rcv_time,
    -									    sctp_align_safe_nocopy);
    -									tp1->do_rtt = 0;
    -								}
    -							}
    -						}
    -						if (tp1->sent <= SCTP_DATAGRAM_RESEND) {
    -							(*ecn_seg_sums) += tp1->rec.data.ect_nonce;
    -							(*ecn_seg_sums) &= SCTP_SACK_NONCE_SUM;
    -							if (compare_with_wrap(tp1->rec.data.TSN_seq,
    -							    asoc->this_sack_highest_gap,
    -							    MAX_TSN)) {
    -								asoc->this_sack_highest_gap =
    -								    tp1->rec.data.TSN_seq;
    -							}
    -							if (tp1->sent == SCTP_DATAGRAM_RESEND) {
    -								sctp_ucount_decr(asoc->sent_queue_retran_cnt);
    -#ifdef SCTP_AUDITING_ENABLED
    -								sctp_audit_log(0xB2,
    -								    (asoc->sent_queue_retran_cnt & 0x000000ff));
    -#endif
    -							}
    -						}
    -						/*
    -						 * All chunks NOT UNSENT
    -						 * fall through here and are
    -						 * marked
    -						 */
    -						if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
    -							tp1->sent = SCTP_DATAGRAM_NR_MARKED;
    -						if (tp1->rec.data.chunk_was_revoked) {
    -							/* deflate the cwnd */
    -							tp1->whoTo->cwnd -= tp1->book_size;
    -							tp1->rec.data.chunk_was_revoked = 0;
    -						}
    -					}
    -					break;
    -				}	/* if (tp1->TSN_seq == theTSN) */
    -				if (compare_with_wrap(tp1->rec.data.TSN_seq, theTSN,
    -				    MAX_TSN))
    -					break;
    -
    -				tp1 = TAILQ_NEXT(tp1, sctp_next);
    -			}	/* end while (tp1) */
    -		}		/* end for (j = fragStart */
    +		sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, frag_end,
    +		    0, &num_frs, biggest_newly_acked_tsn,
    +		    this_sack_lowest_newack, ecn_seg_sums);
     		frag = (struct sctp_gap_ack_block *)sctp_m_getptr(m, *offset,
     		    sizeof(struct sctp_gap_ack_block), (uint8_t *) & block);
     		*offset += sizeof(block);
    @@ -7164,6 +6987,8 @@ sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb,
     	}
     	tp1 = NULL;
     	last_nr_frag_high = 0;
    +	/* Reset to beginning for the nr_sack section */
    +	tp1 = TAILQ_FIRST(&asoc->sent_queue);
     
     	for (i = 0; i < num_nr_seg; i++) {
     
    @@ -7207,45 +7032,15 @@ sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb,
     			}
     			last_nr_frag_high = nr_frag_end + last_tsn;
     		}
    -
    -		for (j = nr_frag_strt + last_tsn; (compare_with_wrap((nr_frag_end + last_tsn), j, MAX_TSN)); j++) {
    -			while (tp1) {
    -				if (tp1->rec.data.TSN_seq == j) {
    -					if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
    -						if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
    -							tp1->sent = SCTP_DATAGRAM_NR_MARKED;
    -						/*
    -						 * TAILQ_REMOVE(&asoc->sent_q
    -						 * ueue, tp1, sctp_next);
    -						 */
    -						if (tp1->data) {
    -							/*
    -							 * sa_ignore
    -							 * NO_NULL_CHK
    -							 */
    -							sctp_free_bufspace(stcb, asoc, tp1, 1);
    -							sctp_m_freem(tp1->data);
    -						}
    -						tp1->data = NULL;
    -						/* asoc->sent_queue_cnt--; */
    -						/*
    -						 * sctp_free_a_chunk(stcb,
    -						 * tp1);
    -						 */
    -						wake_him++;
    -					}
    -					break;
    -				}	/* if (tp1->TSN_seq == j) */
    -				if (compare_with_wrap(tp1->rec.data.TSN_seq, j,
    -				    MAX_TSN))
    -					break;
    -				tp1 = TAILQ_NEXT(tp1, sctp_next);
    -			}	/* end while (tp1) */
    -
    -		}		/* end for (j = nrFragStart */
    +		num_frs = 0;
    +		wake_him = sctp_process_segment_range(stcb, &tp1, last_tsn,
    +		    nr_frag_strt, nr_frag_end, 1,
    +		    &num_frs, biggest_newly_acked_tsn,
    +		    this_sack_lowest_newack, ecn_seg_sums);
     
     		nr_frag = (struct sctp_nr_gap_ack_block *)sctp_m_getptr(m, *offset,
    -		    sizeof(struct sctp_nr_gap_ack_block), (uint8_t *) & nr_block);
    +		    sizeof(struct sctp_nr_gap_ack_block),
    +		    (uint8_t *) & nr_block);
     		*offset += sizeof(nr_block);
     		if (nr_frag == NULL) {
     			break;
    
    From aab42fa148450e87b5183dcf14a7d821ae1333b9 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:40:48 +0000
    Subject: [PATCH 1979/2592] MFC 202516
    
    This gets rid of some stray #ifdef APPLE that drifted in
    some how.
    ---
     sys/netinet/sctp_constants.h | 12 ------------
     1 file changed, 12 deletions(-)
    
    diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h
    index 2b17cbc214f..4a013d3df11 100644
    --- a/sys/netinet/sctp_constants.h
    +++ b/sys/netinet/sctp_constants.h
    @@ -276,28 +276,16 @@ __FBSDID("$FreeBSD$");
     #define SCTP_SCALE_FOR_ADDR	2
     
     /* default AUTO_ASCONF mode enable(1)/disable(0) value (sysctl) */
    -#if defined (__APPLE__) && !defined(SCTP_APPLE_AUTO_ASCONF)
    -#define SCTP_DEFAULT_AUTO_ASCONF        0
    -#else
     #define SCTP_DEFAULT_AUTO_ASCONF	1
    -#endif
     
     /* default MULTIPLE_ASCONF mode enable(1)/disable(0) value (sysctl) */
     #define SCTP_DEFAULT_MULTIPLE_ASCONFS	0
     
     /* default MOBILITY_BASE mode enable(1)/disable(0) value (sysctl) */
    -#if defined (__APPLE__) && !defined(SCTP_APPLE_MOBILITY_BASE)
    -#define SCTP_DEFAULT_MOBILITY_BASE      0
    -#else
     #define SCTP_DEFAULT_MOBILITY_BASE	0
    -#endif
     
     /* default MOBILITY_FASTHANDOFF mode enable(1)/disable(0) value (sysctl) */
    -#if defined (__APPLE__) && !defined(SCTP_APPLE_MOBILITY_FASTHANDOFF)
     #define SCTP_DEFAULT_MOBILITY_FASTHANDOFF	0
    -#else
    -#define SCTP_DEFAULT_MOBILITY_FASTHANDOFF	0
    -#endif
     
     /*
      * Theshold for rwnd updates, we have to read (sb_hiwat >>
    
    From 0146f692b5083118b62ea51e68cc3b7ca1508da1 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:43:02 +0000
    Subject: [PATCH 1980/2592] MFC of 202517
    
    Again gets rid of some rather strange ifdef's for
    APPLE/USERSPACE that drifted in through our scrubber
    programs.
    ---
     sys/netinet/sctp_output.c | 4 ----
     1 file changed, 4 deletions(-)
    
    diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
    index 50ccc93ca9f..af0e4885eb1 100644
    --- a/sys/netinet/sctp_output.c
    +++ b/sys/netinet/sctp_output.c
    @@ -3490,11 +3490,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
     			tos_value = inp->ip_inp.inp.inp_ip_tos;
     		}
     		if ((nofragment_flag) && (port == 0)) {
    -#if defined(WITH_CONVERT_IP_OFF) || defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
     			ip->ip_off = IP_DF;
    -#else
    -			ip->ip_off = htons(IP_DF);
    -#endif
     		} else
     			ip->ip_off = 0;
     
    
    From 394ddd21a6dcf8d4cb70e371a0b58378661068dd Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:44:28 +0000
    Subject: [PATCH 1981/2592] MFC of 202518 More ifdefs that should not be
     present...
    
    ---
     sys/netinet/sctp_sysctl.c | 12 ------------
     1 file changed, 12 deletions(-)
    
    diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
    index ceb4622ab8a..b4023c68213 100644
    --- a/sys/netinet/sctp_sysctl.c
    +++ b/sys/netinet/sctp_sysctl.c
    @@ -556,9 +556,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
     	if (error == 0) {
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_sendspace), SCTPCTL_MAXDGRAM_MIN, SCTPCTL_MAXDGRAM_MAX);
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_recvspace), SCTPCTL_RECVSPACE_MIN, SCTPCTL_RECVSPACE_MAX);
    -#if defined(__FreeBSD__) || defined(SCTP_APPLE_AUTO_ASCONF)
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_auto_asconf), SCTPCTL_AUTOASCONF_MIN, SCTPCTL_AUTOASCONF_MAX);
    -#endif
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_ecn_enable), SCTPCTL_ECN_ENABLE_MIN, SCTPCTL_ECN_ENABLE_MAX);
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_ecn_nonce), SCTPCTL_ECN_NONCE_MIN, SCTPCTL_ECN_NONCE_MAX);
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_sacks), SCTPCTL_STRICT_SACKS_MIN, SCTPCTL_STRICT_SACKS_MAX);
    @@ -613,12 +611,8 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_default_frag_interleave), SCTPCTL_DEFAULT_FRAG_INTERLEAVE_MIN, SCTPCTL_DEFAULT_FRAG_INTERLEAVE_MAX);
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_vtag_time_wait), SCTPCTL_TIME_WAIT_MIN, SCTPCTL_TIME_WAIT_MAX);
     
    -#if defined(__FreeBSD__) || defined(SCTP_APPLE_MOBILITY_BASE)
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_base), SCTPCTL_MOBILITY_BASE_MIN, SCTPCTL_MOBILITY_BASE_MAX);
    -#endif
    -#if defined(__FreeBSD__) || defined(SCTP_APPLE_MOBILITY_FASTHANDOFF)
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), SCTPCTL_MOBILITY_FASTHANDOFF_MIN, SCTPCTL_MOBILITY_FASTHANDOFF_MAX);
    -#endif
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable), SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MIN, SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MAX);
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX);
     		RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX);
    @@ -660,11 +654,9 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, recvspace, CTLTYPE_INT | CTLFLAG_RW,
         &SCTP_BASE_SYSCTL(sctp_recvspace), 0, sysctl_sctp_check, "IU",
         SCTPCTL_RECVSPACE_DESC);
     
    -#if defined(__FreeBSD__) || defined(SCTP_APPLE_AUTO_ASCONF)
     SYSCTL_PROC(_net_inet_sctp, OID_AUTO, auto_asconf, CTLTYPE_INT | CTLFLAG_RW,
         &SCTP_BASE_SYSCTL(sctp_auto_asconf), 0, sysctl_sctp_check, "IU",
         SCTPCTL_AUTOASCONF_DESC);
    -#endif
     
     SYSCTL_PROC(_net_inet_sctp, OID_AUTO, ecn_enable, CTLTYPE_INT | CTLFLAG_RW,
         &SCTP_BASE_SYSCTL(sctp_ecn_enable), 0, sysctl_sctp_check, "IU",
    @@ -871,17 +863,13 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, default_frag_interleave, CTLTYPE_INT | CTL
         &SCTP_BASE_SYSCTL(sctp_default_frag_interleave), 0, sysctl_sctp_check, "IU",
         SCTPCTL_DEFAULT_FRAG_INTERLEAVE_DESC);
     
    -#if defined(__FreeBSD__) || defined(SCTP_APPLE_MOBILITY_BASE)
     SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mobility_base, CTLTYPE_INT | CTLFLAG_RW,
         &SCTP_BASE_SYSCTL(sctp_mobility_base), 0, sysctl_sctp_check, "IU",
         SCTPCTL_MOBILITY_BASE_DESC);
    -#endif
     
    -#if defined(__FreeBSD__) || defined(SCTP_APPLE_MOBILITY_FASTHANDOFF)
     SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mobility_fasthandoff, CTLTYPE_INT | CTLFLAG_RW,
         &SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), 0, sysctl_sctp_check, "IU",
         SCTPCTL_MOBILITY_FASTHANDOFF_DESC);
    -#endif
     
     #if defined(SCTP_LOCAL_TRACE_BUF)
     SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, log, CTLFLAG_RD,
    
    From d50db6bd56b0c59eea1c8d1c3bc734a9c449990c Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:47:04 +0000
    Subject: [PATCH 1982/2592] MFC of 202520
    
    This aligns us to the socket api of the stream
    reset with proper naming.. and a define for backward
    compatibility.
    ---
     sys/netinet/sctp_uio.h    | 29 ++++++++++++++++-------------
     sys/netinet/sctp_usrreq.c |  4 ++--
     2 files changed, 18 insertions(+), 15 deletions(-)
    
    diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h
    index 3b34941fc67..37b581fe732 100644
    --- a/sys/netinet/sctp_uio.h
    +++ b/sys/netinet/sctp_uio.h
    @@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
     
     typedef uint32_t sctp_assoc_t;
     
    +/* Compatibility to previous define's */
    +#define sctp_stream_reset_events sctp_stream_reset_event
    +
     /* On/Off setup for subscription to events */
     struct sctp_event_subscribe {
     	uint8_t sctp_data_io_event;
    @@ -57,7 +60,7 @@ struct sctp_event_subscribe {
     	uint8_t sctp_adaptation_layer_event;
     	uint8_t sctp_authentication_event;
     	uint8_t sctp_sender_dry_event;
    -	uint8_t sctp_stream_reset_events;
    +	uint8_t sctp_stream_reset_event;
     };
     
     /* ancillary data types */
    @@ -402,19 +405,19 @@ union sctp_notification {
     };
     
     /* notification types */
    -#define SCTP_ASSOC_CHANGE		0x0001
    -#define SCTP_PEER_ADDR_CHANGE		0x0002
    -#define SCTP_REMOTE_ERROR		0x0003
    -#define SCTP_SEND_FAILED		0x0004
    -#define SCTP_SHUTDOWN_EVENT		0x0005
    -#define SCTP_ADAPTATION_INDICATION	0x0006
    +#define SCTP_ASSOC_CHANGE			0x0001
    +#define SCTP_PEER_ADDR_CHANGE			0x0002
    +#define SCTP_REMOTE_ERROR			0x0003
    +#define SCTP_SEND_FAILED			0x0004
    +#define SCTP_SHUTDOWN_EVENT			0x0005
    +#define SCTP_ADAPTATION_INDICATION		0x0006
     /* same as above */
    -#define SCTP_ADAPTION_INDICATION	0x0006
    -#define SCTP_PARTIAL_DELIVERY_EVENT	0x0007
    -#define SCTP_AUTHENTICATION_EVENT	0x0008
    -#define SCTP_STREAM_RESET_EVENT		0x0009
    -#define SCTP_SENDER_DRY_EVENT           0x000a
    -
    +#define SCTP_ADAPTION_INDICATION		0x0006
    +#define SCTP_PARTIAL_DELIVERY_EVENT		0x0007
    +#define SCTP_AUTHENTICATION_EVENT		0x0008
    +#define SCTP_STREAM_RESET_EVENT			0x0009
    +#define SCTP_SENDER_DRY_EVENT			0x000a
    +#define SCTP__NOTIFICATIONS_STOPPED_EVENT	0x000b	/* we dont send this */
     /*
      * socket option structs
      */
    diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
    index 9e1c01a2c3b..676e5758a45 100644
    --- a/sys/netinet/sctp_usrreq.c
    +++ b/sys/netinet/sctp_usrreq.c
    @@ -2008,7 +2008,7 @@ flags_out:
     				events->sctp_sender_dry_event = 1;
     
     			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT))
    -				events->sctp_stream_reset_events = 1;
    +				events->sctp_stream_reset_event = 1;
     			SCTP_INP_RUNLOCK(inp);
     			*optsize = sizeof(struct sctp_event_subscribe);
     		}
    @@ -3650,7 +3650,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
     				sctp_feature_off(inp, SCTP_PCB_FLAGS_DRYEVNT);
     			}
     
    -			if (events->sctp_stream_reset_events) {
    +			if (events->sctp_stream_reset_event) {
     				sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
     			} else {
     				sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
    
    From 57f0b741c644a8436bd5c637832adfb9fb1b1183 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:49:21 +0000
    Subject: [PATCH 1983/2592] MFC 202521
    
    More stray ifdef's that had worked their way into the
    code base somehow (yes thats ifdef Windows going out.. our
    stack runs on windows .. big thanks for that goes to
    Kozuka-san and Bruce Cran ;-D)
    ---
     sys/netinet/sctputil.c | 6 ------
     1 file changed, 6 deletions(-)
    
    diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
    index 8681acd03b2..fc89b6d09d3 100644
    --- a/sys/netinet/sctputil.c
    +++ b/sys/netinet/sctputil.c
    @@ -52,15 +52,9 @@ __FBSDID("$FreeBSD$");
     #define NUMBER_OF_MTU_SIZES 18
     
     
    -#if defined(__Windows__) && !defined(SCTP_LOCAL_TRACE_BUF)
    -#include "eventrace_netinet.h"
    -#include "sctputil.tmh"		/* this is the file that will be auto
    -				 * generated */
    -#else
     #ifndef KTR_SCTP
     #define KTR_SCTP KTR_SUBSYS
     #endif
    -#endif
     
     void
     sctp_sblog(struct sockbuf *sb,
    
    From 9eb2a664abf369ac400c76d5eebcc11680bf9222 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:51:13 +0000
    Subject: [PATCH 1984/2592] MFC of  202523
    
    This fixes a closing race condition that is unlikely
    to ever happen.. but good to fix ;-)
    ---
     sys/netinet/sctp_usrreq.c | 8 +++++++-
     1 file changed, 7 insertions(+), 1 deletion(-)
    
    diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
    index 676e5758a45..71f5f65b00b 100644
    --- a/sys/netinet/sctp_usrreq.c
    +++ b/sys/netinet/sctp_usrreq.c
    @@ -551,6 +551,7 @@ sctp_attach(struct socket *so, int proto, struct thread *p)
     	sctp_log_closing(inp, NULL, 17);
     #endif
     	if (error != 0) {
    +try_again:
     		flags = inp->sctp_flags;
     		if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
     		    (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
    @@ -561,7 +562,12 @@ sctp_attach(struct socket *so, int proto, struct thread *p)
     			sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
     			    SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
     		} else {
    -			SCTP_INP_WUNLOCK(inp);
    +			flags = inp->sctp_flags;
    +			if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
    +				goto try_again;
    +			} else {
    +				SCTP_INP_WUNLOCK(inp);
    +			}
     		}
     		return error;
     	}
    
    From 835d439e3acf0a744db449a04a39ed5984baf112 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:53:44 +0000
    Subject: [PATCH 1985/2592] MFC of 205502
    
    The firste of Michael and my long fight at the IETF to
    get the NR sack code fixed and aligned.
    ---
     sys/netinet/sctp_indata.c | 36 +-----------------------------
     sys/netinet/sctputil.c    | 47 +++++++++++++++++++++++++++------------
     sys/netinet/sctputil.h    |  2 +-
     3 files changed, 35 insertions(+), 50 deletions(-)
    
    diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
    index 9174522237b..b498bf49aaf 100644
    --- a/sys/netinet/sctp_indata.c
    +++ b/sys/netinet/sctp_indata.c
    @@ -2533,15 +2533,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	/* int nr_at; */
     	/* int nr_last_all_ones = 0; */
     	/* int nr_slide_from, nr_slide_end, nr_lgap, nr_distance; */
    -
     	uint32_t old_cumack, old_base, old_highest;
    -	unsigned char aux_array[64];
    -
    -	/*
    -	 * EY! Don't think this is required but I am immitating the code for
    -	 * map just to make sure
    -	 */
    -	unsigned char nr_aux_array[64];
     
     	asoc = &stcb->asoc;
     	at = 0;
    @@ -2549,33 +2541,6 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	old_cumack = asoc->cumulative_tsn;
     	old_base = asoc->mapping_array_base_tsn;
     	old_highest = asoc->highest_tsn_inside_map;
    -	if (asoc->mapping_array_size < 64)
    -		memcpy(aux_array, asoc->mapping_array,
    -		    asoc->mapping_array_size);
    -	else
    -		memcpy(aux_array, asoc->mapping_array, 64);
    -	/* EY do the same for nr_mapping_array */
    -	if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    -		if (asoc->nr_mapping_array_size != asoc->mapping_array_size) {
    -			/*
    -			 * printf("\nEY-IN sack_check method: \nEY-" "The
    -			 * size of map and nr_map are inconsitent")
    -			 */ ;
    -		}
    -		if (asoc->nr_mapping_array_base_tsn != asoc->mapping_array_base_tsn) {
    -			/*
    -			 * printf("\nEY-IN sack_check method VERY CRUCIAL
    -			 * error: \nEY-" "The base tsns of map and nr_map
    -			 * are inconsitent")
    -			 */ ;
    -		}
    -		/* EY! just immitating the above code */
    -		if (asoc->nr_mapping_array_size < 64)
    -			memcpy(nr_aux_array, asoc->nr_mapping_array,
    -			    asoc->nr_mapping_array_size);
    -		else
    -			memcpy(aux_array, asoc->nr_mapping_array, 64);
    -	}
     	/*
     	 * We could probably improve this a small bit by calculating the
     	 * offset of the current cum-ack as the starting point.
    @@ -2611,6 +2576,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     #else
     		SCTP_PRINTF("huh, cumack 0x%x greater than high-tsn 0x%x in map - should panic?\n",
     		    asoc->cumulative_tsn, asoc->highest_tsn_inside_map);
    +		sctp_print_mapping_array(asoc);
     		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
     			sctp_log_map(0, 6, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
     		}
    diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
    index fc89b6d09d3..3cef3aa5817 100644
    --- a/sys/netinet/sctputil.c
    +++ b/sys/netinet/sctputil.c
    @@ -1180,6 +1180,25 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
     	return (0);
     }
     
    +void
    +sctp_print_mapping_array(struct sctp_association *asoc)
    +{
    +	int i;
    +
    +	printf("Mapping size:%d baseTSN:%8.8x cumAck:%8.8x highestTSN:%8.8x\n",
    +	    asoc->mapping_array_size,
    +	    asoc->mapping_array_base_tsn,
    +	    asoc->cumulative_tsn,
    +	    asoc->highest_tsn_inside_map
    +	    );
    +	for (i = 0; i < asoc->mapping_array_size; i++) {
    +		printf("%8.8x ", asoc->mapping_array[i]);
    +		if (((i + 1) % 8) == 0)
    +			printf("\n");
    +	}
    +	printf("\n");
    +}
    +
     int
     sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
     {
    @@ -1187,7 +1206,9 @@ sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
     	uint8_t *new_array;
     	uint32_t new_size;
     
    +
     	new_size = asoc->mapping_array_size + ((needed + 7) / 8 + SCTP_MAPPING_ARRAY_INCR);
    +
     	SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
     	if (new_array == NULL) {
     		/* can't get more, forget it */
    @@ -1200,21 +1221,19 @@ sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
     	SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
     	asoc->mapping_array = new_array;
     	asoc->mapping_array_size = new_size;
    -	if (asoc->peer_supports_nr_sack) {
    -		new_size = asoc->nr_mapping_array_size + ((needed + 7) / 8 + SCTP_NR_MAPPING_ARRAY_INCR);
    -		SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
    -		if (new_array == NULL) {
    -			/* can't get more, forget it */
    -			SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
    -			    new_size);
    -			return (-1);
    -		}
    -		memset(new_array, 0, new_size);
    -		memcpy(new_array, asoc->nr_mapping_array, asoc->nr_mapping_array_size);
    -		SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
    -		asoc->nr_mapping_array = new_array;
    -		asoc->nr_mapping_array_size = new_size;
    +	new_size = asoc->nr_mapping_array_size + ((needed + 7) / 8 + SCTP_NR_MAPPING_ARRAY_INCR);
    +	SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
    +	if (new_array == NULL) {
    +		/* can't get more, forget it */
    +		SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
    +		    new_size);
    +		return (-1);
     	}
    +	memset(new_array, 0, new_size);
    +	memcpy(new_array, asoc->nr_mapping_array, asoc->nr_mapping_array_size);
    +	SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
    +	asoc->nr_mapping_array = new_array;
    +	asoc->nr_mapping_array_size = new_size;
     	return (0);
     }
     
    diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
    index f3a731ea1a0..8d663abe2ca 100644
    --- a/sys/netinet/sctputil.h
    +++ b/sys/netinet/sctputil.h
    @@ -376,7 +376,7 @@ int sctp_fill_stat_log(void *, size_t *);
     void sctp_log_fr(uint32_t, uint32_t, uint32_t, int);
     void sctp_log_sack(uint32_t, uint32_t, uint32_t, uint16_t, uint16_t, int);
     void sctp_log_map(uint32_t, uint32_t, uint32_t, int);
    -
    +void sctp_print_mapping_array(struct sctp_association *asoc);
     void sctp_clr_stat_log(void);
     
     
    
    From 535f992c6de68d6dcee4ae9938dbce437dca64c9 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:55:49 +0000
    Subject: [PATCH 1986/2592] MFC of 202526
    
    The first round of some of Michael's changes to
    get the sack processing in better shape.
    ---
     sys/netinet/sctp_header.h  |    8 -
     sys/netinet/sctp_indata.c  | 2010 +++---------------------------------
     sys/netinet/sctp_indata.h  |   17 +-
     sys/netinet/sctp_input.c   |  127 ++-
     sys/netinet/sctp_output.c  |   22 +-
     sys/netinet/sctp_structs.h |    2 -
     6 files changed, 241 insertions(+), 1945 deletions(-)
    
    diff --git a/sys/netinet/sctp_header.h b/sys/netinet/sctp_header.h
    index c551e53b473..e4ad773e049 100644
    --- a/sys/netinet/sctp_header.h
    +++ b/sys/netinet/sctp_header.h
    @@ -284,13 +284,6 @@ struct sctp_sack_chunk {
     	struct sctp_sack sack;
     }               SCTP_PACKED;
     
    -
    -/* EY Following 3 structs define NR Selective Ack (NR_SACK) chunk */
    -struct sctp_nr_gap_ack_block {
    -	uint16_t start;		/* NR Gap Ack block start */
    -	uint16_t end;		/* NR Gap Ack block end */
    -}                     SCTP_PACKED;
    -
     struct sctp_nr_sack {
     	uint32_t cum_tsn_ack;	/* cumulative TSN Ack */
     	uint32_t a_rwnd;	/* updated a_rwnd of sender */
    @@ -299,7 +292,6 @@ struct sctp_nr_sack {
     	uint16_t num_dup_tsns;	/* number of duplicate TSNs */
     	uint16_t reserved;	/* not currently used */
     	/* struct sctp_gap_ack_block's follow */
    -	/* struct sctp_nr_gap_ack_block's follow */
     	/* uint32_t duplicate_tsn's follow */
     }            SCTP_PACKED;
     
    diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
    index b498bf49aaf..600ada08bdd 100644
    --- a/sys/netinet/sctp_indata.c
    +++ b/sys/netinet/sctp_indata.c
    @@ -439,12 +439,11 @@ abandon:
     		 * EY!-TODO- this tsn should be tagged nr only if it is
     		 * out-of-order, the if statement should be modified
     		 */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    -
    +		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +		    asoc->peer_supports_nr_sack) {
     			nr_tsn = chk->rec.data.TSN_seq;
     			SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
    -			if ((nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3)) ||
    -			    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    +			if ((nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
     				/*
     				 * EY The 1st should never happen, as in
     				 * process_a_data_chunk method this check
    @@ -525,11 +524,11 @@ abandon:
     						 * nr_gap and tag this tsn
     						 * NR
     						 */
    -						if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    +						if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +						    asoc->peer_supports_nr_sack) {
     							SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
     							if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
     							    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    -								printf("Impossible NR gap calculation?\n");
     								/*
     								 * EY The
     								 * 1st
    @@ -694,7 +693,8 @@ protocol_error:
     		 * calculate the gap and such then tag this TSN nr
     		 * chk->rec.data.TSN_seq
     		 */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    +		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +		    asoc->peer_supports_nr_sack) {
     			SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
     			if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
     			    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    @@ -750,11 +750,11 @@ protocol_error:
     				 * such then tag this TSN nr
     				 * chk->rec.data.TSN_seq
     				 */
    -				if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    +				if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +				    asoc->peer_supports_nr_sack) {
     					SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
     					if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
     					    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    -						printf("Impossible nr TSN set 3?\n");
     						/*
     						 * EY The 1st should never
     						 * happen, as in
    @@ -773,7 +773,8 @@ protocol_error:
     						SCTP_TCB_LOCK_ASSERT(stcb);
     						SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
     						SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -						if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map,
    +						if (compare_with_wrap(nr_tsn,
    +						    asoc->highest_tsn_inside_nr_map,
     						    MAX_TSN))
     							asoc->highest_tsn_inside_nr_map = nr_tsn;
     					}
    @@ -1759,7 +1760,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     		SCTP_TCB_LOCK_ASSERT(stcb);
     		SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
     		/* EY set this tsn present in  nr_sack's nr_mapping_array */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    +		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +		    asoc->peer_supports_nr_sack) {
     			SCTP_TCB_LOCK_ASSERT(stcb);
     			SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
     			SCTP_REVERSE_OUT_TSN_PRES(gap, tsn, asoc);
    @@ -2015,7 +2017,8 @@ failed_express_del:
     			 * block here I should check if this delivered tsn
     			 * is out_of_order, if yes then update the nr_map
     			 */
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    +			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +			    asoc->peer_supports_nr_sack) {
     				/* EY debugging block */
     				{
     					/*
    @@ -2260,13 +2263,13 @@ failed_pdapi_express_del:
     			sctp_add_to_readq(stcb->sctp_ep, stcb,
     			    control,
     			    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
    -
     			/*
     			 * EY It is added to the read queue in prev if block
     			 * here I should check if this delivered tsn is
     			 * out_of_order, if yes then update the nr_map
     			 */
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    +			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +			    asoc->peer_supports_nr_sack) {
     				/*
     				 * EY check if the mapping_array and
     				 * nr_mapping array are consistent
    @@ -2412,6 +2415,10 @@ finish_express_del:
     	SCTP_TCB_LOCK_ASSERT(stcb);
     	SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
     
    +	/*
    +	 * EY - set tsn present in nr-map if  doing nr-sacks and the tsn is
    +	 * non-renegable
    +	 */
     	if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
     	    asoc->peer_supports_nr_sack &&
     	    (SCTP_BASE_SYSCTL(sctp_do_drain) == 0)) {
    @@ -3382,49 +3389,37 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
     }
     
     
    -static void
    +static int
     sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct sctp_association *asoc,
    -    struct sctp_sack_chunk *ch, uint32_t last_tsn, uint32_t * biggest_tsn_acked,
    +    uint32_t last_tsn, uint32_t * biggest_tsn_acked,
         uint32_t * biggest_newly_acked_tsn, uint32_t * this_sack_lowest_newack,
    -    int num_seg, int *ecn_seg_sums)
    +    int num_seg, int num_nr_seg, int *ecn_seg_sums)
     {
    -	/************************************************/
    -	/* process fragments and update sendqueue        */
    -	/************************************************/
    -	struct sctp_sack *sack;
     	struct sctp_gap_ack_block *frag, block;
     	struct sctp_tmit_chunk *tp1;
     	int i;
     	int num_frs = 0;
    +	int chunk_freed;
    +	int non_revocable;
    +	uint16_t frag_strt, frag_end;
    +	uint32_t last_frag_high;
     
    -	uint16_t frag_strt, frag_end, primary_flag_set;
    -	u_long last_frag_high;
    -
    -	/*
    -	 * @@@ JRI : TODO: This flag is not used anywhere .. remove?
    -	 */
    -	if (asoc->primary_destination->dest_state & SCTP_ADDR_SWITCH_PRIMARY) {
    -		primary_flag_set = 1;
    -	} else {
    -		primary_flag_set = 0;
    -	}
    -	sack = &ch->sack;
    -
    -	frag = (struct sctp_gap_ack_block *)sctp_m_getptr(m, *offset,
    -	    sizeof(struct sctp_gap_ack_block), (uint8_t *) & block);
    -	*offset += sizeof(block);
    -	if (frag == NULL) {
    -		return;
    -	}
     	tp1 = NULL;
     	last_frag_high = 0;
    -	for (i = 0; i < num_seg; i++) {
    +	chunk_freed = 0;
    +
    +	for (i = 0; i < (num_seg + num_nr_seg); i++) {
    +		frag = (struct sctp_gap_ack_block *)sctp_m_getptr(m, *offset,
    +		    sizeof(struct sctp_gap_ack_block), (uint8_t *) & block);
    +		*offset += sizeof(block);
    +		if (frag == NULL) {
    +			return (chunk_freed);
    +		}
     		frag_strt = ntohs(frag->start);
     		frag_end = ntohs(frag->end);
     		/* some sanity checks on the fragment offsets */
     		if (frag_strt > frag_end) {
     			/* this one is malformed, skip */
    -			frag++;
     			continue;
     		}
     		if (compare_with_wrap((frag_end + last_tsn), *biggest_tsn_acked,
    @@ -3434,7 +3429,6 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
     		/* mark acked dgs and find out the highestTSN being acked */
     		if (tp1 == NULL) {
     			tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -
     			/* save the locations of the last frags */
     			last_frag_high = frag_end + last_tsn;
     		} else {
    @@ -3462,14 +3456,15 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
     			}
     			last_frag_high = frag_end + last_tsn;
     		}
    -		sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, frag_end,
    -		    0, &num_frs, biggest_newly_acked_tsn,
    -		    this_sack_lowest_newack, ecn_seg_sums);
    -		frag = (struct sctp_gap_ack_block *)sctp_m_getptr(m, *offset,
    -		    sizeof(struct sctp_gap_ack_block), (uint8_t *) & block);
    -		*offset += sizeof(block);
    -		if (frag == NULL) {
    -			break;
    +		if (i < num_seg) {
    +			non_revocable = 0;
    +		} else {
    +			non_revocable = 1;
    +		}
    +		if (sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, frag_end,
    +		    non_revocable, &num_frs, biggest_newly_acked_tsn,
    +		    this_sack_lowest_newack, ecn_seg_sums)) {
    +			chunk_freed = 1;
     		}
     	}
     	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
    @@ -3478,6 +3473,7 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
     			    *biggest_newly_acked_tsn,
     			    last_tsn, SCTP_FR_LOG_BIGGEST_TSNS);
     	}
    +	return (chunk_freed);
     }
     
     static void
    @@ -4416,7 +4412,6 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
     		struct socket *so;
     
     #endif
    -
     		SOCKBUF_LOCK(&stcb->sctp_socket->so_snd);
     		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_WAKE_LOGGING_ENABLE) {
     			/* sa_ignore NO_NULL_CHK */
    @@ -4491,10 +4486,10 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
     			if (compare_with_wrap(asoc->last_acked_seq, asoc->nonce_resync_tsn, MAX_TSN)) {
     				asoc->nonce_sum_check = 1;
     				/*
    -				 * now we must calculate what the base is.
    +				 * Now we must calculate what the base is.
     				 * We do this based on two things, we know
     				 * the total's for all the segments
    -				 * gap-acked in the SACK (none), We also
    +				 * gap-acked in the SACK (none). We also
     				 * know the SACK's nonce sum, its in
     				 * nonce_sum_flag. So we can build a truth
     				 * table to back-calculate the new value of
    @@ -4533,6 +4528,7 @@ again:
     			/* sa_ignore FREED_MEMORY */
     			TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
     				if (tp1->window_probe) {
    +					/* move back to data send queue */
     					sctp_window_probe_recovery(stcb, asoc, net, tp1);
     					break;
     				}
    @@ -4586,9 +4582,7 @@ again:
     		 */
     		if (sctp_fs_audit(asoc)) {
     			TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -				if (net->flight_size) {
    -					net->flight_size = 0;
    -				}
    +				net->flight_size = 0;
     			}
     			asoc->total_flight = 0;
     			asoc->total_flight_count = 0;
    @@ -4748,20 +4742,62 @@ again:
     	}
     }
     
    +/* EY- nr_sack */
    +/* Identifies the non-renegable tsns that are revoked*/
    +static void
    +sctp_check_for_nr_revoked(struct sctp_tcb *stcb,
    +    struct sctp_association *asoc, uint32_t cumack,
    +    u_long biggest_tsn_acked)
    +{
    +	struct sctp_tmit_chunk *tp1;
    +
    +	for (tp1 = TAILQ_FIRST(&asoc->sent_queue); tp1; tp1 = TAILQ_NEXT(tp1, sctp_next)) {
    +		if (compare_with_wrap(tp1->rec.data.TSN_seq, cumack,
    +		    MAX_TSN)) {
    +			/*
    +			 * ok this guy is either ACK or MARKED. If it is
    +			 * ACKED it has been previously acked but not this
    +			 * time i.e. revoked.  If it is MARKED it was ACK'ed
    +			 * again.
    +			 */
    +			if (compare_with_wrap(tp1->rec.data.TSN_seq, biggest_tsn_acked,
    +			    MAX_TSN))
    +				break;
    +
    +
    +			if (tp1->sent == SCTP_DATAGRAM_NR_ACKED) {
    +				/*
    +				 * EY! a non-renegable TSN is revoked, need
    +				 * to abort the association
    +				 */
    +				/*
    +				 * EY TODO: put in the code to abort the
    +				 * assoc.
    +				 */
    +				return;
    +			} else if (tp1->sent == SCTP_DATAGRAM_NR_MARKED) {
    +				/* it has been re-acked in this SACK */
    +				tp1->sent = SCTP_DATAGRAM_NR_ACKED;
    +			}
    +		}
    +		if (tp1->sent == SCTP_DATAGRAM_UNSENT)
    +			break;
    +	}
    +	return;
    +}
    +
     void
    -sctp_handle_sack(struct mbuf *m, int offset,
    -    struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
    -    struct sctp_nets *net_from, int *abort_now, int sack_len, uint32_t rwnd)
    +sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
    +    struct sctp_tcb *stcb, struct sctp_nets *net_from,
    +    uint16_t num_seg, uint16_t num_nr_seg, uint16_t num_dup,
    +    int *abort_now, uint8_t flags,
    +    uint32_t cum_ack, uint32_t rwnd)
     {
     	struct sctp_association *asoc;
    -	struct sctp_sack *sack;
     	struct sctp_tmit_chunk *tp1, *tp2;
    -	uint32_t cum_ack, last_tsn, biggest_tsn_acked, biggest_tsn_newly_acked,
    -	         this_sack_lowest_newack;
    +	uint32_t last_tsn, biggest_tsn_acked, biggest_tsn_newly_acked, this_sack_lowest_newack;
     	uint32_t sav_cum_ack;
    -	uint16_t num_seg, num_dup;
     	uint16_t wake_him = 0;
    -	unsigned int sack_length;
     	uint32_t send_s = 0;
     	long j;
     	int accum_moved = 0;
    @@ -4797,15 +4833,13 @@ sctp_handle_sack(struct mbuf *m, int offset,
     	 * if in shutdown_recv state.
     	 */
     	SCTP_TCB_LOCK_ASSERT(stcb);
    -	sack = &ch->sack;
     	/* CMT DAC algo */
     	this_sack_lowest_newack = 0;
     	j = 0;
    -	sack_length = (unsigned int)sack_len;
    -	/* ECN Nonce */
     	SCTP_STAT_INCR(sctps_slowpath_sack);
    -	nonce_sum_flag = ch->ch.chunk_flags & SCTP_SACK_NONCE_SUM;
    -	cum_ack = last_tsn = ntohl(sack->cum_tsn_ack);
    +	last_tsn = cum_ack;
    +	nonce_sum_flag = flags & SCTP_SACK_NONCE_SUM;
    +	cmt_dac_flag = flags & SCTP_SACK_CMT_DAC;
     #ifdef SCTP_ASOCLOG_OF_TSNS
     	stcb->asoc.cumack_log[stcb->asoc.cumack_log_at] = cum_ack;
     	stcb->asoc.cumack_log_at++;
    @@ -4813,13 +4847,12 @@ sctp_handle_sack(struct mbuf *m, int offset,
     		stcb->asoc.cumack_log_at = 0;
     	}
     #endif
    -	num_seg = ntohs(sack->num_gap_ack_blks);
     	a_rwnd = rwnd;
     
    -	/* CMT DAC algo */
    -	cmt_dac_flag = ch->ch.chunk_flags & SCTP_SACK_CMT_DAC;
    -	num_dup = ntohs(sack->num_dup_tsns);
    -
    +	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_SACK_ARRIVALS_ENABLE) {
    +		sctp_misc_ints(SCTP_SACK_LOG_NORMAL, cum_ack,
    +		    rwnd, stcb->asoc.last_acked_seq, stcb->asoc.peers_rwnd);
    +	}
     	old_rwnd = stcb->asoc.peers_rwnd;
     	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
     		sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    @@ -4839,27 +4872,16 @@ sctp_handle_sack(struct mbuf *m, int offset,
     		    SCTP_LOG_NEW_SACK);
     	}
     	if ((num_dup) && (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_FR_LOGGING_ENABLE | SCTP_EARLYFR_LOGGING_ENABLE))) {
    -		int off_to_dup, iii;
    +		uint16_t i;
     		uint32_t *dupdata, dblock;
     
    -		off_to_dup = (num_seg * sizeof(struct sctp_gap_ack_block)) + sizeof(struct sctp_sack_chunk);
    -		if ((off_to_dup + (num_dup * sizeof(uint32_t))) <= sack_length) {
    -			dupdata = (uint32_t *) sctp_m_getptr(m, off_to_dup,
    +		for (i = 0; i < num_dup; i++) {
    +			dupdata = (uint32_t *) sctp_m_getptr(m, offset_dup + i * sizeof(uint32_t),
     			    sizeof(uint32_t), (uint8_t *) & dblock);
    -			off_to_dup += sizeof(uint32_t);
    -			if (dupdata) {
    -				for (iii = 0; iii < num_dup; iii++) {
    -					sctp_log_fr(*dupdata, 0, 0, SCTP_FR_DUPED);
    -					dupdata = (uint32_t *) sctp_m_getptr(m, off_to_dup,
    -					    sizeof(uint32_t), (uint8_t *) & dblock);
    -					if (dupdata == NULL)
    -						break;
    -					off_to_dup += sizeof(uint32_t);
    -				}
    +			if (dupdata == NULL) {
    +				break;
     			}
    -		} else {
    -			SCTP_PRINTF("Size invalid offset to dups:%d number dups:%d sack_len:%d num gaps:%d\n",
    -			    off_to_dup, num_dup, sack_length, num_seg);
    +			sctp_log_fr(*dupdata, 0, 0, SCTP_FR_DUPED);
     		}
     	}
     	if (SCTP_BASE_SYSCTL(sctp_strict_sacks)) {
    @@ -4881,8 +4903,6 @@ sctp_handle_sack(struct mbuf *m, int offset,
     	hopeless_peer:
     			panic("Impossible sack 1");
     #else
    -
    -
     			/*
     			 * no way, we have not even sent this TSN out yet.
     			 * Peer is hopelessly messed up with us.
    @@ -4922,8 +4942,7 @@ sctp_handle_sack(struct mbuf *m, int offset,
     	/* update the Rwnd of the peer */
     	if (TAILQ_EMPTY(&asoc->sent_queue) &&
     	    TAILQ_EMPTY(&asoc->send_queue) &&
    -	    (asoc->stream_queue_cnt == 0)
    -	    ) {
    +	    (asoc->stream_queue_cnt == 0)) {
     		/* nothing left on send/sent and strmq */
     		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_RWND_ENABLE) {
     			sctp_log_rwnd_set(SCTP_SET_PEER_RWND_VIA_SACK,
    @@ -5094,14 +5113,7 @@ sctp_handle_sack(struct mbuf *m, int offset,
     	/* always set this up to cum-ack */
     	asoc->this_sack_highest_gap = last_tsn;
     
    -	/* Move offset up to point to gaps/dups */
    -	offset += sizeof(struct sctp_sack_chunk);
    -	if (((num_seg * (sizeof(struct sctp_gap_ack_block))) + sizeof(struct sctp_sack_chunk)) > sack_length) {
    -
    -		/* skip corrupt segments */
    -		goto skip_segments;
    -	}
    -	if (num_seg > 0) {
    +	if ((num_seg > 0) || (num_nr_seg > 0)) {
     
     		/*
     		 * CMT: SFR algo (and HTNA) - this_sack_highest_newack has
    @@ -5119,10 +5131,11 @@ sctp_handle_sack(struct mbuf *m, int offset,
     		 * handling NEWLY ACKED chunks. this_sack_lowest_newack is
     		 * used for CMT DAC algo. saw_newack will also change.
     		 */
    -		sctp_handle_segments(m, &offset, stcb, asoc, ch, last_tsn,
    -		    &biggest_tsn_acked, &biggest_tsn_newly_acked, &this_sack_lowest_newack,
    -		    num_seg, &ecn_seg_sums);
    -
    +		if (sctp_handle_segments(m, &offset_seg, stcb, asoc, last_tsn, &biggest_tsn_acked,
    +		    &biggest_tsn_newly_acked, &this_sack_lowest_newack,
    +		    num_seg, num_nr_seg, &ecn_seg_sums)) {
    +			wake_him++;
    +		}
     		if (SCTP_BASE_SYSCTL(sctp_strict_sacks)) {
     			/*
     			 * validate the biggest_tsn_acked in the gap acks if
    @@ -5138,7 +5151,6 @@ sctp_handle_sack(struct mbuf *m, int offset,
     			}
     		}
     	}
    -skip_segments:
     	/*******************************************/
     	/* cancel ALL T3-send timer if accum moved */
     	/*******************************************/
    @@ -5276,6 +5288,19 @@ done_with_it:
     		if (tp1 != NULL) {
     			/* Peer revoked all dg's marked or acked */
     			TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
    +				/*
    +				 * EY- maybe check only if it is nr_acked
    +				 * nr_marked may not be possible
    +				 */
    +				if ((tp1->sent == SCTP_DATAGRAM_NR_ACKED) ||
    +				    (tp1->sent == SCTP_DATAGRAM_NR_MARKED)) {
    +					/*
    +					 * EY! - TODO: Something previously
    +					 * nr_gapped is reneged, abort the
    +					 * association
    +					 */
    +					return;
    +				}
     				if ((tp1->sent > SCTP_DATAGRAM_RESEND) &&
     				    (tp1->sent < SCTP_FORWARD_TSN_SKIP)) {
     					tp1->sent = SCTP_DATAGRAM_SENT;
    @@ -5311,6 +5336,10 @@ done_with_it:
     	else
     		asoc->saw_sack_with_frags = 0;
     
    +	/* EY! - not sure about if there should be an IF */
    +	if (num_nr_seg > 0)
    +		sctp_check_for_nr_revoked(stcb, asoc, cum_ack, biggest_tsn_acked);
    +
     	/* JRS - Use the congestion control given in the CC module */
     	asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, accum_moved, reneged_all, will_exit_fast_recovery);
     
    @@ -5446,7 +5475,7 @@ done_with_it:
     	if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac) && (cmt_dac_flag == 0)) {
     		this_sack_lowest_newack = cum_ack;
     	}
    -	if (num_seg > 0) {
    +	if ((num_seg > 0) || (num_nr_seg > 0)) {
     		sctp_strike_gap_ack_chunks(stcb, asoc, biggest_tsn_acked,
     		    biggest_tsn_newly_acked, this_sack_lowest_newack, accum_moved);
     	}
    @@ -5569,9 +5598,12 @@ again:
     		}
     		if (net->flight_size) {
     			j++;
    -			sctp_timer_start(SCTP_TIMER_TYPE_SEND,
    -			    stcb->sctp_ep, stcb, net);
    +			if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
    +				sctp_timer_start(SCTP_TIMER_TYPE_SEND,
    +				    stcb->sctp_ep, stcb, net);
    +			}
     			if (net->window_probe) {
    +				net->window_probe = 0;
     			}
     		} else {
     			if (net->window_probe) {
    @@ -5579,7 +5611,6 @@ again:
     				 * In window probes we must assure a timer
     				 * is still running there
     				 */
    -
     				if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
     					sctp_timer_start(SCTP_TIMER_TYPE_SEND,
     					    stcb->sctp_ep, stcb, net);
    @@ -5627,7 +5658,11 @@ again:
     		done_once = 1;
     		goto again;
     	}
    -	/* Fix up the a-p-a-p for future PR-SCTP sends */
    +	/*********************************************/
    +	/* Here we perform PR-SCTP procedures        */
    +	/* (section 4.2)                             */
    +	/*********************************************/
    +	/* C1. update advancedPeerAckPoint */
     	if (compare_with_wrap(cum_ack, asoc->advanced_peer_ack_point, MAX_TSN)) {
     		asoc->advanced_peer_ack_point = cum_ack;
     	}
    @@ -5739,8 +5774,8 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
     				 * such then tag this TSN nr
     				 * chk->rec.data.TSN_seq
     				 */
    -				if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    -
    +				if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +				    asoc->peer_supports_nr_sack) {
     					SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
     					if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
     					    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    @@ -5840,7 +5875,8 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
     				 * such then tag this TSN nr
     				 * chk->rec.data.TSN_seq
     				 */
    -				if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    +				if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +				    asoc->peer_supports_nr_sack) {
     					SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
     					if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
     					    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    @@ -6325,1743 +6361,3 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
     		sctp_deliver_reasm_check(stcb, &stcb->asoc);
     	}
     }
    -
    -/* EY fully identical to sctp_express_handle_sack, duplicated for only naming convention */
    -void
    -sctp_express_handle_nr_sack(struct sctp_tcb *stcb, uint32_t cumack,
    -    uint32_t rwnd, int nonce_sum_flag, int *abort_now)
    -{
    -	struct sctp_nets *net;
    -	struct sctp_association *asoc;
    -	struct sctp_tmit_chunk *tp1, *tp2;
    -	uint32_t old_rwnd;
    -	int win_probe_recovery = 0;
    -	int win_probe_recovered = 0;
    -	int j, done_once = 0;
    -
    -	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_SACK_ARRIVALS_ENABLE) {
    -		sctp_misc_ints(SCTP_SACK_LOG_EXPRESS, cumack,
    -		    rwnd, stcb->asoc.last_acked_seq, stcb->asoc.peers_rwnd);
    -	}
    -	SCTP_TCB_LOCK_ASSERT(stcb);
    -#ifdef SCTP_ASOCLOG_OF_TSNS
    -	stcb->asoc.cumack_log[stcb->asoc.cumack_log_at] = cumack;
    -	stcb->asoc.cumack_log_at++;
    -	if (stcb->asoc.cumack_log_at > SCTP_TSN_LOG_SIZE) {
    -		stcb->asoc.cumack_log_at = 0;
    -	}
    -#endif
    -	asoc = &stcb->asoc;
    -	old_rwnd = asoc->peers_rwnd;
    -	if (compare_with_wrap(asoc->last_acked_seq, cumack, MAX_TSN)) {
    -		/* old ack */
    -		return;
    -	} else if (asoc->last_acked_seq == cumack) {
    -		/* Window update sack */
    -		asoc->peers_rwnd = sctp_sbspace_sub(rwnd,
    -		    (uint32_t) (asoc->total_flight + (asoc->sent_queue_cnt * SCTP_BASE_SYSCTL(sctp_peer_chunk_oh))));
    -		if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
    -			/* SWS sender side engages */
    -			asoc->peers_rwnd = 0;
    -		}
    -		if (asoc->peers_rwnd > old_rwnd) {
    -			goto again;
    -		}
    -		return;
    -	}
    -	/* First setup for CC stuff */
    -	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -		net->prev_cwnd = net->cwnd;
    -		net->net_ack = 0;
    -		net->net_ack2 = 0;
    -
    -		/*
    -		 * CMT: Reset CUC and Fast recovery algo variables before
    -		 * SACK processing
    -		 */
    -		net->new_pseudo_cumack = 0;
    -		net->will_exit_fast_recovery = 0;
    -	}
    -	if (SCTP_BASE_SYSCTL(sctp_strict_sacks)) {
    -		uint32_t send_s;
    -
    -		if (!TAILQ_EMPTY(&asoc->sent_queue)) {
    -			tp1 = TAILQ_LAST(&asoc->sent_queue,
    -			    sctpchunk_listhead);
    -			send_s = tp1->rec.data.TSN_seq + 1;
    -		} else {
    -			send_s = asoc->sending_seq;
    -		}
    -		if ((cumack == send_s) ||
    -		    compare_with_wrap(cumack, send_s, MAX_TSN)) {
    -#ifndef INVARIANTS
    -			struct mbuf *oper;
    -
    -#endif
    -#ifdef INVARIANTS
    -			panic("Impossible sack 1");
    -#else
    -			*abort_now = 1;
    -			/* XXX */
    -			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
    -			    0, M_DONTWAIT, 1, MT_DATA);
    -			if (oper) {
    -				struct sctp_paramhdr *ph;
    -				uint32_t *ippp;
    -
    -				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
    -				    sizeof(uint32_t);
    -				ph = mtod(oper, struct sctp_paramhdr *);
    -				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
    -				ph->param_length = htons(SCTP_BUF_LEN(oper));
    -				ippp = (uint32_t *) (ph + 1);
    -				*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
    -			}
    -			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
    -			sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_PEER_FAULTY, oper, SCTP_SO_NOT_LOCKED);
    -			return;
    -#endif
    -		}
    -	}
    -	asoc->this_sack_highest_gap = cumack;
    -	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    -		sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    -		    stcb->asoc.overall_error_count,
    -		    0,
    -		    SCTP_FROM_SCTP_INDATA,
    -		    __LINE__);
    -	}
    -	stcb->asoc.overall_error_count = 0;
    -	if (compare_with_wrap(cumack, asoc->last_acked_seq, MAX_TSN)) {
    -		/* process the new consecutive TSN first */
    -		tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -		while (tp1) {
    -			tp2 = TAILQ_NEXT(tp1, sctp_next);
    -			if (compare_with_wrap(cumack, tp1->rec.data.TSN_seq,
    -			    MAX_TSN) ||
    -			    cumack == tp1->rec.data.TSN_seq) {
    -				if (tp1->sent == SCTP_DATAGRAM_UNSENT) {
    -					printf("Warning, an unsent is now acked?\n");
    -				}
    -				/*
    -				 * ECN Nonce: Add the nonce to the sender's
    -				 * nonce sum
    -				 */
    -				asoc->nonce_sum_expect_base += tp1->rec.data.ect_nonce;
    -				if (tp1->sent < SCTP_DATAGRAM_ACKED) {
    -					/*
    -					 * If it is less than ACKED, it is
    -					 * now no-longer in flight. Higher
    -					 * values may occur during marking
    -					 */
    -					if (tp1->sent < SCTP_DATAGRAM_RESEND) {
    -						if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
    -							sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_CA,
    -							    tp1->whoTo->flight_size,
    -							    tp1->book_size,
    -							    (uintptr_t) tp1->whoTo,
    -							    tp1->rec.data.TSN_seq);
    -						}
    -						sctp_flight_size_decrease(tp1);
    -						/* sa_ignore NO_NULL_CHK */
    -						sctp_total_flight_decrease(stcb, tp1);
    -					}
    -					tp1->whoTo->net_ack += tp1->send_size;
    -					if (tp1->snd_count < 2) {
    -						/*
    -						 * True non-retransmited
    -						 * chunk
    -						 */
    -						tp1->whoTo->net_ack2 +=
    -						    tp1->send_size;
    -
    -						/* update RTO too? */
    -						if (tp1->do_rtt) {
    -							tp1->whoTo->RTO =
    -							/*
    -							 * sa_ignore
    -							 * NO_NULL_CHK
    -							 */
    -							    sctp_calculate_rto(stcb,
    -							    asoc, tp1->whoTo,
    -							    &tp1->sent_rcv_time,
    -							    sctp_align_safe_nocopy);
    -							tp1->do_rtt = 0;
    -						}
    -					}
    -					/*
    -					 * CMT: CUCv2 algorithm. From the
    -					 * cumack'd TSNs, for each TSN being
    -					 * acked for the first time, set the
    -					 * following variables for the
    -					 * corresp destination.
    -					 * new_pseudo_cumack will trigger a
    -					 * cwnd update.
    -					 * find_(rtx_)pseudo_cumack will
    -					 * trigger search for the next
    -					 * expected (rtx-)pseudo-cumack.
    -					 */
    -					tp1->whoTo->new_pseudo_cumack = 1;
    -					tp1->whoTo->find_pseudo_cumack = 1;
    -					tp1->whoTo->find_rtx_pseudo_cumack = 1;
    -
    -					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    -						/* sa_ignore NO_NULL_CHK */
    -						sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK);
    -					}
    -				}
    -				if (tp1->sent == SCTP_DATAGRAM_RESEND) {
    -					sctp_ucount_decr(asoc->sent_queue_retran_cnt);
    -				}
    -				if (tp1->rec.data.chunk_was_revoked) {
    -					/* deflate the cwnd */
    -					tp1->whoTo->cwnd -= tp1->book_size;
    -					tp1->rec.data.chunk_was_revoked = 0;
    -				}
    -				tp1->sent = SCTP_DATAGRAM_ACKED;
    -				TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
    -				if (tp1->data) {
    -					/* sa_ignore NO_NULL_CHK */
    -					sctp_free_bufspace(stcb, asoc, tp1, 1);
    -					sctp_m_freem(tp1->data);
    -				}
    -				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    -					sctp_log_sack(asoc->last_acked_seq,
    -					    cumack,
    -					    tp1->rec.data.TSN_seq,
    -					    0,
    -					    0,
    -					    SCTP_LOG_FREE_SENT);
    -				}
    -				tp1->data = NULL;
    -				asoc->sent_queue_cnt--;
    -				sctp_free_a_chunk(stcb, tp1);
    -				tp1 = tp2;
    -			} else {
    -				break;
    -			}
    -		}
    -
    -	}
    -	/* sa_ignore NO_NULL_CHK */
    -	if (stcb->sctp_socket) {
    -#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    -		struct socket *so;
    -
    -#endif
    -
    -		SOCKBUF_LOCK(&stcb->sctp_socket->so_snd);
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_WAKE_LOGGING_ENABLE) {
    -			/* sa_ignore NO_NULL_CHK */
    -			sctp_wakeup_log(stcb, cumack, 1, SCTP_WAKESND_FROM_SACK);
    -		}
    -#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    -		so = SCTP_INP_SO(stcb->sctp_ep);
    -		atomic_add_int(&stcb->asoc.refcnt, 1);
    -		SCTP_TCB_UNLOCK(stcb);
    -		SCTP_SOCKET_LOCK(so, 1);
    -		SCTP_TCB_LOCK(stcb);
    -		atomic_subtract_int(&stcb->asoc.refcnt, 1);
    -		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
    -			/* assoc was freed while we were unlocked */
    -			SCTP_SOCKET_UNLOCK(so, 1);
    -			return;
    -		}
    -#endif
    -		sctp_sowwakeup_locked(stcb->sctp_ep, stcb->sctp_socket);
    -#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    -		SCTP_SOCKET_UNLOCK(so, 1);
    -#endif
    -	} else {
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_WAKE_LOGGING_ENABLE) {
    -			sctp_wakeup_log(stcb, cumack, 1, SCTP_NOWAKE_FROM_SACK);
    -		}
    -	}
    -
    -	/* JRS - Use the congestion control given in the CC module */
    -	if (asoc->last_acked_seq != cumack)
    -		asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, 1, 0, 0);
    -
    -	asoc->last_acked_seq = cumack;
    -
    -	if (TAILQ_EMPTY(&asoc->sent_queue)) {
    -		/* nothing left in-flight */
    -		TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -			net->flight_size = 0;
    -			net->partial_bytes_acked = 0;
    -		}
    -		asoc->total_flight = 0;
    -		asoc->total_flight_count = 0;
    -	}
    -	/* Fix up the a-p-a-p for future PR-SCTP sends */
    -	if (compare_with_wrap(cumack, asoc->advanced_peer_ack_point, MAX_TSN)) {
    -		asoc->advanced_peer_ack_point = cumack;
    -	}
    -	/* ECN Nonce updates */
    -	if (asoc->ecn_nonce_allowed) {
    -		if (asoc->nonce_sum_check) {
    -			if (nonce_sum_flag != ((asoc->nonce_sum_expect_base) & SCTP_SACK_NONCE_SUM)) {
    -				if (asoc->nonce_wait_for_ecne == 0) {
    -					struct sctp_tmit_chunk *lchk;
    -
    -					lchk = TAILQ_FIRST(&asoc->send_queue);
    -					asoc->nonce_wait_for_ecne = 1;
    -					if (lchk) {
    -						asoc->nonce_wait_tsn = lchk->rec.data.TSN_seq;
    -					} else {
    -						asoc->nonce_wait_tsn = asoc->sending_seq;
    -					}
    -				} else {
    -					if (compare_with_wrap(asoc->last_acked_seq, asoc->nonce_wait_tsn, MAX_TSN) ||
    -					    (asoc->last_acked_seq == asoc->nonce_wait_tsn)) {
    -						/*
    -						 * Misbehaving peer. We need
    -						 * to react to this guy
    -						 */
    -						asoc->ecn_allowed = 0;
    -						asoc->ecn_nonce_allowed = 0;
    -					}
    -				}
    -			}
    -		} else {
    -			/* See if Resynchronization Possible */
    -			if (compare_with_wrap(asoc->last_acked_seq, asoc->nonce_resync_tsn, MAX_TSN)) {
    -				asoc->nonce_sum_check = 1;
    -				/*
    -				 * now we must calculate what the base is.
    -				 * We do this based on two things, we know
    -				 * the total's for all the segments
    -				 * gap-acked in the SACK (none), We also
    -				 * know the SACK's nonce sum, its in
    -				 * nonce_sum_flag. So we can build a truth
    -				 * table to back-calculate the new value of
    -				 * asoc->nonce_sum_expect_base:
    -				 * 
    -				 * SACK-flag-Value         Seg-Sums Base 0 0 0
    -				 * 1                    0 1 0 1 1 1 1 0
    -				 */
    -				asoc->nonce_sum_expect_base = (0 ^ nonce_sum_flag) & SCTP_SACK_NONCE_SUM;
    -			}
    -		}
    -	}
    -	/* RWND update */
    -	asoc->peers_rwnd = sctp_sbspace_sub(rwnd,
    -	    (uint32_t) (asoc->total_flight + (asoc->sent_queue_cnt * SCTP_BASE_SYSCTL(sctp_peer_chunk_oh))));
    -	if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
    -		/* SWS sender side engages */
    -		asoc->peers_rwnd = 0;
    -	}
    -	if (asoc->peers_rwnd > old_rwnd) {
    -		win_probe_recovery = 1;
    -	}
    -	/* Now assure a timer where data is queued at */
    -again:
    -	j = 0;
    -	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -		int to_ticks;
    -
    -		if (win_probe_recovery && (net->window_probe)) {
    -			win_probe_recovered = 1;
    -			/*
    -			 * Find first chunk that was used with window probe
    -			 * and clear the sent
    -			 */
    -			/* sa_ignore FREED_MEMORY */
    -			TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
    -				if (tp1->window_probe) {
    -					/* move back to data send queue */
    -					sctp_window_probe_recovery(stcb, asoc, net, tp1);
    -					break;
    -				}
    -			}
    -		}
    -		if (net->RTO == 0) {
    -			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
    -		} else {
    -			to_ticks = MSEC_TO_TICKS(net->RTO);
    -		}
    -		if (net->flight_size) {
    -
    -			j++;
    -			(void)SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
    -			    sctp_timeout_handler, &net->rxt_timer);
    -			if (net->window_probe) {
    -				net->window_probe = 0;
    -			}
    -		} else {
    -			if (net->window_probe) {
    -				/*
    -				 * In window probes we must assure a timer
    -				 * is still running there
    -				 */
    -				net->window_probe = 0;
    -				(void)SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
    -				    sctp_timeout_handler, &net->rxt_timer);
    -			} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
    -				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
    -				    stcb, net,
    -				    SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
    -			}
    -			if (SCTP_BASE_SYSCTL(sctp_early_fr)) {
    -				if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
    -					SCTP_STAT_INCR(sctps_earlyfrstpidsck4);
    -					sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
    -					    SCTP_FROM_SCTP_INDATA + SCTP_LOC_23);
    -				}
    -			}
    -		}
    -	}
    -	if ((j == 0) &&
    -	    (!TAILQ_EMPTY(&asoc->sent_queue)) &&
    -	    (asoc->sent_queue_retran_cnt == 0) &&
    -	    (win_probe_recovered == 0) &&
    -	    (done_once == 0)) {
    -		/*
    -		 * huh, this should not happen unless all packets are
    -		 * PR-SCTP and marked to skip of course.
    -		 */
    -		if (sctp_fs_audit(asoc)) {
    -			TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -				net->flight_size = 0;
    -			}
    -			asoc->total_flight = 0;
    -			asoc->total_flight_count = 0;
    -			asoc->sent_queue_retran_cnt = 0;
    -			TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
    -				if (tp1->sent < SCTP_DATAGRAM_RESEND) {
    -					sctp_flight_size_increase(tp1);
    -					sctp_total_flight_increase(stcb, tp1);
    -				} else if (tp1->sent == SCTP_DATAGRAM_RESEND) {
    -					asoc->sent_queue_retran_cnt++;
    -				}
    -			}
    -		}
    -		done_once = 1;
    -		goto again;
    -	}
    -	/**********************************/
    -	/* Now what about shutdown issues */
    -	/**********************************/
    -	if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue)) {
    -		/* nothing left on sendqueue.. consider done */
    -		/* clean up */
    -		if ((asoc->stream_queue_cnt == 1) &&
    -		    ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) ||
    -		    (asoc->state & SCTP_STATE_SHUTDOWN_RECEIVED)) &&
    -		    (asoc->locked_on_sending)
    -		    ) {
    -			struct sctp_stream_queue_pending *sp;
    -
    -			/*
    -			 * I may be in a state where we got all across.. but
    -			 * cannot write more due to a shutdown... we abort
    -			 * since the user did not indicate EOR in this case.
    -			 * The sp will be cleaned during free of the asoc.
    -			 */
    -			sp = TAILQ_LAST(&((asoc->locked_on_sending)->outqueue),
    -			    sctp_streamhead);
    -			if ((sp) && (sp->length == 0)) {
    -				/* Let cleanup code purge it */
    -				if (sp->msg_is_complete) {
    -					asoc->stream_queue_cnt--;
    -				} else {
    -					asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
    -					asoc->locked_on_sending = NULL;
    -					asoc->stream_queue_cnt--;
    -				}
    -			}
    -		}
    -		if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) &&
    -		    (asoc->stream_queue_cnt == 0)) {
    -			if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
    -				/* Need to abort here */
    -				struct mbuf *oper;
    -
    -		abort_out_now:
    -				*abort_now = 1;
    -				/* XXX */
    -				oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
    -				    0, M_DONTWAIT, 1, MT_DATA);
    -				if (oper) {
    -					struct sctp_paramhdr *ph;
    -					uint32_t *ippp;
    -
    -					SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
    -					    sizeof(uint32_t);
    -					ph = mtod(oper, struct sctp_paramhdr *);
    -					ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
    -					ph->param_length = htons(SCTP_BUF_LEN(oper));
    -					ippp = (uint32_t *) (ph + 1);
    -					*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_24);
    -				}
    -				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24;
    -				sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_RESPONSE_TO_USER_REQ, oper, SCTP_SO_NOT_LOCKED);
    -			} else {
    -				if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
    -				    (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
    -					SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    -				}
    -				SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
    -				SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
    -				sctp_stop_timers_for_shutdown(stcb);
    -				sctp_send_shutdown(stcb,
    -				    stcb->asoc.primary_destination);
    -				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
    -				    stcb->sctp_ep, stcb, asoc->primary_destination);
    -				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
    -				    stcb->sctp_ep, stcb, asoc->primary_destination);
    -			}
    -		} else if ((SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED) &&
    -		    (asoc->stream_queue_cnt == 0)) {
    -			if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
    -				goto abort_out_now;
    -			}
    -			SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    -			SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
    -			SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
    -			sctp_send_shutdown_ack(stcb,
    -			    stcb->asoc.primary_destination);
    -
    -			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
    -			    stcb->sctp_ep, stcb, asoc->primary_destination);
    -		}
    -	}
    -	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_RWND_LOGGING_ENABLE) {
    -		sctp_misc_ints(SCTP_SACK_RWND_UPDATE,
    -		    rwnd,
    -		    stcb->asoc.peers_rwnd,
    -		    stcb->asoc.total_flight,
    -		    stcb->asoc.total_output_queue_size);
    -	}
    -}
    -
    -/* EY! nr_sack version of sctp_handle_segments, nr-gapped TSNs get removed from RtxQ in this method*/
    -static void
    -sctp_handle_nr_sack_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct sctp_association *asoc,
    -    struct sctp_nr_sack_chunk *ch, uint32_t last_tsn, uint32_t * biggest_tsn_acked,
    -    uint32_t * biggest_newly_acked_tsn, uint32_t * this_sack_lowest_newack,
    -    uint32_t num_seg, uint32_t num_nr_seg, int *ecn_seg_sums)
    -{
    -	/************************************************/
    -	/* process fragments and update sendqueue        */
    -	/************************************************/
    -	struct sctp_nr_sack *nr_sack;
    -	struct sctp_gap_ack_block *frag, block;
    -	struct sctp_nr_gap_ack_block *nr_frag, nr_block;
    -	struct sctp_tmit_chunk *tp1;
    -	uint32_t i;
    -	int wake_him = 0;
    -	int num_frs = 0;
    -
    -	uint16_t frag_strt, frag_end, primary_flag_set;
    -	uint16_t nr_frag_strt, nr_frag_end;
    -
    -	uint32_t last_frag_high;
    -	uint32_t last_nr_frag_high;
    -
    -	/*
    -	 * @@@ JRI : TODO: This flag is not used anywhere .. remove?
    -	 */
    -	if (asoc->primary_destination->dest_state & SCTP_ADDR_SWITCH_PRIMARY) {
    -		primary_flag_set = 1;
    -	} else {
    -		primary_flag_set = 0;
    -	}
    -	nr_sack = &ch->nr_sack;
    -
    -	/*
    -	 * EY! - I will process nr_gaps similarly,by going to this position
    -	 * again if All bit is set
    -	 */
    -	frag = (struct sctp_gap_ack_block *)sctp_m_getptr(m, *offset,
    -	    sizeof(struct sctp_gap_ack_block), (uint8_t *) & block);
    -	*offset += sizeof(block);
    -	if (frag == NULL) {
    -		return;
    -	}
    -	tp1 = NULL;
    -	last_frag_high = 0;
    -	for (i = 0; i < num_seg; i++) {
    -		frag_strt = ntohs(frag->start);
    -		frag_end = ntohs(frag->end);
    -		/* some sanity checks on the fargment offsets */
    -		if (frag_strt > frag_end) {
    -			/* this one is malformed, skip */
    -			frag++;
    -			continue;
    -		}
    -		if (compare_with_wrap((frag_end + last_tsn), *biggest_tsn_acked,
    -		    MAX_TSN))
    -			*biggest_tsn_acked = frag_end + last_tsn;
    -
    -		/* mark acked dgs and find out the highestTSN being acked */
    -		if (tp1 == NULL) {
    -			tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -
    -			/* save the locations of the last frags */
    -			last_frag_high = frag_end + last_tsn;
    -		} else {
    -			/*
    -			 * now lets see if we need to reset the queue due to
    -			 * a out-of-order SACK fragment
    -			 */
    -			if (compare_with_wrap(frag_strt + last_tsn,
    -			    last_frag_high, MAX_TSN)) {
    -				/*
    -				 * if the new frag starts after the last TSN
    -				 * frag covered, we are ok and this one is
    -				 * beyond the last one
    -				 */
    -				;
    -			} else {
    -				/*
    -				 * ok, they have reset us, so we need to
    -				 * reset the queue this will cause extra
    -				 * hunting but hey, they chose the
    -				 * performance hit when they failed to order
    -				 * there gaps..
    -				 */
    -				tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -			}
    -			last_frag_high = frag_end + last_tsn;
    -		}
    -		sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, frag_end,
    -		    0, &num_frs, biggest_newly_acked_tsn,
    -		    this_sack_lowest_newack, ecn_seg_sums);
    -		frag = (struct sctp_gap_ack_block *)sctp_m_getptr(m, *offset,
    -		    sizeof(struct sctp_gap_ack_block), (uint8_t *) & block);
    -		*offset += sizeof(block);
    -		if (frag == NULL) {
    -			break;
    -		}
    -	}
    -
    -	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
    -		if (num_frs)
    -			sctp_log_fr(*biggest_tsn_acked,
    -			    *biggest_newly_acked_tsn,
    -			    last_tsn, SCTP_FR_LOG_BIGGEST_TSNS);
    -	}
    -	nr_frag = (struct sctp_nr_gap_ack_block *)sctp_m_getptr(m, *offset,
    -	    sizeof(struct sctp_nr_gap_ack_block), (uint8_t *) & nr_block);
    -	*offset += sizeof(nr_block);
    -
    -
    -
    -	if (nr_frag == NULL) {
    -		return;
    -	}
    -	tp1 = NULL;
    -	last_nr_frag_high = 0;
    -	/* Reset to beginning for the nr_sack section */
    -	tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -
    -	for (i = 0; i < num_nr_seg; i++) {
    -
    -		nr_frag_strt = ntohs(nr_frag->start);
    -		nr_frag_end = ntohs(nr_frag->end);
    -
    -		/* some sanity checks on the nr fargment offsets */
    -		if (nr_frag_strt > nr_frag_end) {
    -			/* this one is malformed, skip */
    -			nr_frag++;
    -			continue;
    -		}
    -		/* mark acked dgs and find out the highestTSN being acked */
    -		if (tp1 == NULL) {
    -			tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -
    -			/* save the locations of the last frags */
    -			last_nr_frag_high = nr_frag_end + last_tsn;
    -		} else {
    -			/*
    -			 * now lets see if we need to reset the queue due to
    -			 * a out-of-order SACK fragment
    -			 */
    -			if (compare_with_wrap(nr_frag_strt + last_tsn,
    -			    last_nr_frag_high, MAX_TSN)) {
    -				/*
    -				 * if the new frag starts after the last TSN
    -				 * frag covered, we are ok and this one is
    -				 * beyond the last one
    -				 */
    -				;
    -			} else {
    -				/*
    -				 * ok, they have reset us, so we need to
    -				 * reset the queue this will cause extra
    -				 * hunting but hey, they chose the
    -				 * performance hit when they failed to order
    -				 * there gaps..
    -				 */
    -				tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -			}
    -			last_nr_frag_high = nr_frag_end + last_tsn;
    -		}
    -		num_frs = 0;
    -		wake_him = sctp_process_segment_range(stcb, &tp1, last_tsn,
    -		    nr_frag_strt, nr_frag_end, 1,
    -		    &num_frs, biggest_newly_acked_tsn,
    -		    this_sack_lowest_newack, ecn_seg_sums);
    -
    -		nr_frag = (struct sctp_nr_gap_ack_block *)sctp_m_getptr(m, *offset,
    -		    sizeof(struct sctp_nr_gap_ack_block),
    -		    (uint8_t *) & nr_block);
    -		*offset += sizeof(nr_block);
    -		if (nr_frag == NULL) {
    -			break;
    -		}
    -	}
    -
    -	/*
    -	 * EY- wake up the socket if things have been removed from the sent
    -	 * queue
    -	 */
    -	if ((wake_him) && (stcb->sctp_socket)) {
    -#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    -		struct socket *so;
    -
    -#endif
    -		SOCKBUF_LOCK(&stcb->sctp_socket->so_snd);
    -		/*
    -		 * if (SCTP_BASE_SYSCTL(sctp_logging_level) &
    -		 * SCTP_WAKE_LOGGING_ENABLE) { sctp_wakeup_log(stcb,
    -		 * cum_ack, wake_him, SCTP_WAKESND_FROM_SACK);}
    -		 */
    -#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    -		so = SCTP_INP_SO(stcb->sctp_ep);
    -		atomic_add_int(&stcb->asoc.refcnt, 1);
    -		SCTP_TCB_UNLOCK(stcb);
    -		SCTP_SOCKET_LOCK(so, 1);
    -		SCTP_TCB_LOCK(stcb);
    -		atomic_subtract_int(&stcb->asoc.refcnt, 1);
    -		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
    -			/* assoc was freed while we were unlocked */
    -			SCTP_SOCKET_UNLOCK(so, 1);
    -			return;
    -		}
    -#endif
    -		sctp_sowwakeup_locked(stcb->sctp_ep, stcb->sctp_socket);
    -#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    -		SCTP_SOCKET_UNLOCK(so, 1);
    -#endif
    -	}			/* else { if
    -				 * (SCTP_BASE_SYSCTL(sctp_logging_level) &
    -				 * SCTP_WAKE_LOGGING_ENABLE) {
    -				 * sctp_wakeup_log(stcb, cum_ack, wake_him,
    -				 * SCTP_NOWAKE_FROM_SACK); } } */
    -}
    -
    -/* EY- nr_sack */
    -/* Identifies the non-renegable tsns that are revoked*/
    -static void
    -sctp_check_for_nr_revoked(struct sctp_tcb *stcb,
    -    struct sctp_association *asoc, uint32_t cumack,
    -    u_long biggest_tsn_acked)
    -{
    -	struct sctp_tmit_chunk *tp1;
    -
    -	tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -	while (tp1) {
    -		if (compare_with_wrap(tp1->rec.data.TSN_seq, cumack,
    -		    MAX_TSN)) {
    -			/*
    -			 * ok this guy is either ACK or MARKED. If it is
    -			 * ACKED it has been previously acked but not this
    -			 * time i.e. revoked.  If it is MARKED it was ACK'ed
    -			 * again.
    -			 */
    -			if (compare_with_wrap(tp1->rec.data.TSN_seq, biggest_tsn_acked,
    -			    MAX_TSN))
    -				break;
    -
    -
    -			if (tp1->sent == SCTP_DATAGRAM_NR_ACKED) {
    -				/*
    -				 * EY! a non-renegable TSN is revoked, need
    -				 * to abort the association
    -				 */
    -				/*
    -				 * EY TODO: put in the code to abort the
    -				 * assoc.
    -				 */
    -				return;
    -			} else if (tp1->sent == SCTP_DATAGRAM_NR_MARKED) {
    -				/* it has been re-acked in this SACK */
    -				tp1->sent = SCTP_DATAGRAM_NR_ACKED;
    -			}
    -		}
    -		if (tp1->sent == SCTP_DATAGRAM_UNSENT)
    -			break;
    -		tp1 = TAILQ_NEXT(tp1, sctp_next);
    -	}
    -}
    -
    -/* EY! nr_sack version of sctp_handle_sack, nr_gap_ack processing should be added to this method*/
    -void
    -sctp_handle_nr_sack(struct mbuf *m, int offset,
    -    struct sctp_nr_sack_chunk *ch, struct sctp_tcb *stcb,
    -    struct sctp_nets *net_from, int *abort_now, int nr_sack_len, uint32_t rwnd)
    -{
    -	struct sctp_association *asoc;
    -
    -	/* EY sack */
    -	struct sctp_nr_sack *nr_sack;
    -	struct sctp_tmit_chunk *tp1, *tp2;
    -	uint32_t cum_ack, last_tsn, biggest_tsn_acked, biggest_tsn_newly_acked,
    -	         this_sack_lowest_newack;
    -	uint32_t sav_cum_ack;
    -
    -	/* EY num_seg */
    -	uint16_t num_seg, num_nr_seg, num_dup;
    -	uint16_t wake_him = 0;
    -	unsigned int nr_sack_length;
    -	uint32_t send_s = 0;
    -	long j;
    -	int accum_moved = 0;
    -	int will_exit_fast_recovery = 0;
    -	uint32_t a_rwnd, old_rwnd;
    -	int win_probe_recovery = 0;
    -	int win_probe_recovered = 0;
    -	struct sctp_nets *net = NULL;
    -	int nonce_sum_flag, ecn_seg_sums = 0;
    -	int done_once;
    -	uint8_t reneged_all = 0;
    -	uint8_t cmt_dac_flag;
    -
    -	/*
    -	 * we take any chance we can to service our queues since we cannot
    -	 * get awoken when the socket is read from :<
    -	 */
    -	/*
    -	 * Now perform the actual SACK handling: 1) Verify that it is not an
    -	 * old sack, if so discard. 2) If there is nothing left in the send
    -	 * queue (cum-ack is equal to last acked) then you have a duplicate
    -	 * too, update any rwnd change and verify no timers are running.
    -	 * then return. 3) Process any new consequtive data i.e. cum-ack
    -	 * moved process these first and note that it moved. 4) Process any
    -	 * sack blocks. 5) Drop any acked from the queue. 6) Check for any
    -	 * revoked blocks and mark. 7) Update the cwnd. 8) Nothing left,
    -	 * sync up flightsizes and things, stop all timers and also check
    -	 * for shutdown_pending state. If so then go ahead and send off the
    -	 * shutdown. If in shutdown recv, send off the shutdown-ack and
    -	 * start that timer, Ret. 9) Strike any non-acked things and do FR
    -	 * procedure if needed being sure to set the FR flag. 10) Do pr-sctp
    -	 * procedures. 11) Apply any FR penalties. 12) Assure we will SACK
    -	 * if in shutdown_recv state.
    -	 */
    -	SCTP_TCB_LOCK_ASSERT(stcb);
    -	nr_sack = &ch->nr_sack;
    -	/* CMT DAC algo */
    -	this_sack_lowest_newack = 0;
    -	j = 0;
    -	nr_sack_length = (unsigned int)nr_sack_len;
    -	/* ECN Nonce */
    -	SCTP_STAT_INCR(sctps_slowpath_sack);
    -	nonce_sum_flag = ch->ch.chunk_flags & SCTP_SACK_NONCE_SUM;
    -	cum_ack = last_tsn = ntohl(nr_sack->cum_tsn_ack);
    -#ifdef SCTP_ASOCLOG_OF_TSNS
    -	stcb->asoc.cumack_log[stcb->asoc.cumack_log_at] = cum_ack;
    -	stcb->asoc.cumack_log_at++;
    -	if (stcb->asoc.cumack_log_at > SCTP_TSN_LOG_SIZE) {
    -		stcb->asoc.cumack_log_at = 0;
    -	}
    -#endif
    -	num_seg = ntohs(nr_sack->num_gap_ack_blks);
    -	num_nr_seg = ntohs(nr_sack->num_nr_gap_ack_blks);
    -	a_rwnd = rwnd;
    -
    -	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_SACK_ARRIVALS_ENABLE) {
    -		sctp_misc_ints(SCTP_SACK_LOG_NORMAL, cum_ack,
    -		    rwnd, stcb->asoc.last_acked_seq, stcb->asoc.peers_rwnd);
    -	}
    -	/* CMT DAC algo */
    -	cmt_dac_flag = ch->ch.chunk_flags & SCTP_SACK_CMT_DAC;
    -	num_dup = ntohs(nr_sack->num_dup_tsns);
    -
    -	old_rwnd = stcb->asoc.peers_rwnd;
    -	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    -		sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    -		    stcb->asoc.overall_error_count,
    -		    0,
    -		    SCTP_FROM_SCTP_INDATA,
    -		    __LINE__);
    -	}
    -	stcb->asoc.overall_error_count = 0;
    -	asoc = &stcb->asoc;
    -	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    -		sctp_log_sack(asoc->last_acked_seq,
    -		    cum_ack,
    -		    0,
    -		    num_seg,
    -		    num_dup,
    -		    SCTP_LOG_NEW_SACK);
    -	}
    -	if ((num_dup) && (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_FR_LOGGING_ENABLE | SCTP_EARLYFR_LOGGING_ENABLE))) {
    -		int off_to_dup, iii;
    -		uint32_t *dupdata, dblock;
    -
    -		off_to_dup = (num_seg * sizeof(struct sctp_gap_ack_block)) +
    -		    (num_nr_seg * sizeof(struct sctp_nr_gap_ack_block)) + sizeof(struct sctp_nr_sack_chunk);
    -		if ((off_to_dup + (num_dup * sizeof(uint32_t))) <= nr_sack_length) {
    -			dupdata = (uint32_t *) sctp_m_getptr(m, off_to_dup,
    -			    sizeof(uint32_t), (uint8_t *) & dblock);
    -			off_to_dup += sizeof(uint32_t);
    -			if (dupdata) {
    -				for (iii = 0; iii < num_dup; iii++) {
    -					sctp_log_fr(*dupdata, 0, 0, SCTP_FR_DUPED);
    -					dupdata = (uint32_t *) sctp_m_getptr(m, off_to_dup,
    -					    sizeof(uint32_t), (uint8_t *) & dblock);
    -					if (dupdata == NULL)
    -						break;
    -					off_to_dup += sizeof(uint32_t);
    -				}
    -			}
    -		} else {
    -			SCTP_PRINTF("Size invalid offset to dups:%d number dups:%d nr_sack_len:%d num gaps:%d num nr_gaps:%d\n",
    -			    off_to_dup, num_dup, nr_sack_length, num_seg, num_nr_seg);
    -		}
    -	}
    -	if (SCTP_BASE_SYSCTL(sctp_strict_sacks)) {
    -		/* reality check */
    -		if (!TAILQ_EMPTY(&asoc->sent_queue)) {
    -			tp1 = TAILQ_LAST(&asoc->sent_queue,
    -			    sctpchunk_listhead);
    -			send_s = tp1->rec.data.TSN_seq + 1;
    -		} else {
    -			send_s = asoc->sending_seq;
    -		}
    -		if (cum_ack == send_s ||
    -		    compare_with_wrap(cum_ack, send_s, MAX_TSN)) {
    -#ifndef INVARIANTS
    -			struct mbuf *oper;
    -
    -#endif
    -#ifdef INVARIANTS
    -	hopeless_peer:
    -			panic("Impossible sack 1");
    -#else
    -
    -
    -			/*
    -			 * no way, we have not even sent this TSN out yet.
    -			 * Peer is hopelessly messed up with us.
    -			 */
    -	hopeless_peer:
    -			*abort_now = 1;
    -			/* XXX */
    -			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
    -			    0, M_DONTWAIT, 1, MT_DATA);
    -			if (oper) {
    -				struct sctp_paramhdr *ph;
    -				uint32_t *ippp;
    -
    -				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
    -				    sizeof(uint32_t);
    -				ph = mtod(oper, struct sctp_paramhdr *);
    -				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
    -				ph->param_length = htons(SCTP_BUF_LEN(oper));
    -				ippp = (uint32_t *) (ph + 1);
    -				*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
    -			}
    -			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
    -			sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_PEER_FAULTY, oper, SCTP_SO_NOT_LOCKED);
    -			return;
    -#endif
    -		}
    -	}
    -	/**********************/
    -	/* 1) check the range */
    -	/**********************/
    -	if (compare_with_wrap(asoc->last_acked_seq, last_tsn, MAX_TSN)) {
    -		/* acking something behind */
    -		return;
    -	}
    -	sav_cum_ack = asoc->last_acked_seq;
    -
    -	/* update the Rwnd of the peer */
    -	if (TAILQ_EMPTY(&asoc->sent_queue) &&
    -	    TAILQ_EMPTY(&asoc->send_queue) &&
    -	    (asoc->stream_queue_cnt == 0)
    -	    ) {
    -		/* nothing left on send/sent and strmq */
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_RWND_ENABLE) {
    -			sctp_log_rwnd_set(SCTP_SET_PEER_RWND_VIA_SACK,
    -			    asoc->peers_rwnd, 0, 0, a_rwnd);
    -		}
    -		asoc->peers_rwnd = a_rwnd;
    -		if (asoc->sent_queue_retran_cnt) {
    -			asoc->sent_queue_retran_cnt = 0;
    -		}
    -		if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
    -			/* SWS sender side engages */
    -			asoc->peers_rwnd = 0;
    -		}
    -		/* stop any timers */
    -		TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -			sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
    -			    stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_26);
    -			if (SCTP_BASE_SYSCTL(sctp_early_fr)) {
    -				if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
    -					SCTP_STAT_INCR(sctps_earlyfrstpidsck1);
    -					sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
    -					    SCTP_FROM_SCTP_INDATA + SCTP_LOC_26);
    -				}
    -			}
    -			net->partial_bytes_acked = 0;
    -			net->flight_size = 0;
    -		}
    -		asoc->total_flight = 0;
    -		asoc->total_flight_count = 0;
    -		return;
    -	}
    -	/*
    -	 * We init netAckSz and netAckSz2 to 0. These are used to track 2
    -	 * things. The total byte count acked is tracked in netAckSz AND
    -	 * netAck2 is used to track the total bytes acked that are un-
    -	 * amibguious and were never retransmitted. We track these on a per
    -	 * destination address basis.
    -	 */
    -	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -		net->prev_cwnd = net->cwnd;
    -		net->net_ack = 0;
    -		net->net_ack2 = 0;
    -
    -		/*
    -		 * CMT: Reset CUC and Fast recovery algo variables before
    -		 * SACK processing
    -		 */
    -		net->new_pseudo_cumack = 0;
    -		net->will_exit_fast_recovery = 0;
    -	}
    -	/* process the new consecutive TSN first */
    -	tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -	while (tp1) {
    -		if (compare_with_wrap(last_tsn, tp1->rec.data.TSN_seq,
    -		    MAX_TSN) ||
    -		    last_tsn == tp1->rec.data.TSN_seq) {
    -			if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
    -				/*
    -				 * ECN Nonce: Add the nonce to the sender's
    -				 * nonce sum
    -				 */
    -				asoc->nonce_sum_expect_base += tp1->rec.data.ect_nonce;
    -				accum_moved = 1;
    -				if (tp1->sent < SCTP_DATAGRAM_ACKED) {
    -					/*
    -					 * If it is less than ACKED, it is
    -					 * now no-longer in flight. Higher
    -					 * values may occur during marking
    -					 */
    -					if ((tp1->whoTo->dest_state &
    -					    SCTP_ADDR_UNCONFIRMED) &&
    -					    (tp1->snd_count < 2)) {
    -						/*
    -						 * If there was no retran
    -						 * and the address is
    -						 * un-confirmed and we sent
    -						 * there and are now
    -						 * sacked.. its confirmed,
    -						 * mark it so.
    -						 */
    -						tp1->whoTo->dest_state &=
    -						    ~SCTP_ADDR_UNCONFIRMED;
    -					}
    -					if (tp1->sent < SCTP_DATAGRAM_RESEND) {
    -						if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
    -							sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_CA,
    -							    tp1->whoTo->flight_size,
    -							    tp1->book_size,
    -							    (uintptr_t) tp1->whoTo,
    -							    tp1->rec.data.TSN_seq);
    -						}
    -						sctp_flight_size_decrease(tp1);
    -						sctp_total_flight_decrease(stcb, tp1);
    -					}
    -					tp1->whoTo->net_ack += tp1->send_size;
    -
    -					/* CMT SFR and DAC algos */
    -					this_sack_lowest_newack = tp1->rec.data.TSN_seq;
    -					tp1->whoTo->saw_newack = 1;
    -
    -					if (tp1->snd_count < 2) {
    -						/*
    -						 * True non-retransmited
    -						 * chunk
    -						 */
    -						tp1->whoTo->net_ack2 +=
    -						    tp1->send_size;
    -
    -						/* update RTO too? */
    -						if (tp1->do_rtt) {
    -							tp1->whoTo->RTO =
    -							    sctp_calculate_rto(stcb,
    -							    asoc, tp1->whoTo,
    -							    &tp1->sent_rcv_time,
    -							    sctp_align_safe_nocopy);
    -							tp1->do_rtt = 0;
    -						}
    -					}
    -					/*
    -					 * CMT: CUCv2 algorithm. From the
    -					 * cumack'd TSNs, for each TSN being
    -					 * acked for the first time, set the
    -					 * following variables for the
    -					 * corresp destination.
    -					 * new_pseudo_cumack will trigger a
    -					 * cwnd update.
    -					 * find_(rtx_)pseudo_cumack will
    -					 * trigger search for the next
    -					 * expected (rtx-)pseudo-cumack.
    -					 */
    -					tp1->whoTo->new_pseudo_cumack = 1;
    -					tp1->whoTo->find_pseudo_cumack = 1;
    -					tp1->whoTo->find_rtx_pseudo_cumack = 1;
    -
    -
    -					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    -						sctp_log_sack(asoc->last_acked_seq,
    -						    cum_ack,
    -						    tp1->rec.data.TSN_seq,
    -						    0,
    -						    0,
    -						    SCTP_LOG_TSN_ACKED);
    -					}
    -					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
    -						sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK);
    -					}
    -				}
    -				if (tp1->sent == SCTP_DATAGRAM_RESEND) {
    -					sctp_ucount_decr(asoc->sent_queue_retran_cnt);
    -#ifdef SCTP_AUDITING_ENABLED
    -					sctp_audit_log(0xB3,
    -					    (asoc->sent_queue_retran_cnt & 0x000000ff));
    -#endif
    -				}
    -				if (tp1->rec.data.chunk_was_revoked) {
    -					/* deflate the cwnd */
    -					tp1->whoTo->cwnd -= tp1->book_size;
    -					tp1->rec.data.chunk_was_revoked = 0;
    -				}
    -				tp1->sent = SCTP_DATAGRAM_ACKED;
    -			}
    -		} else {
    -			break;
    -		}
    -		tp1 = TAILQ_NEXT(tp1, sctp_next);
    -	}
    -	biggest_tsn_newly_acked = biggest_tsn_acked = last_tsn;
    -	/* always set this up to cum-ack */
    -	asoc->this_sack_highest_gap = last_tsn;
    -
    -	/* Move offset up to point to gaps/dups */
    -	offset += sizeof(struct sctp_nr_sack_chunk);
    -	if (((num_seg * (sizeof(struct sctp_gap_ack_block))) + sizeof(struct sctp_nr_sack_chunk)) > nr_sack_length) {
    -
    -		/* skip corrupt segments */
    -		goto skip_segments;
    -	}
    -	if (num_seg > 0) {
    -
    -		/*
    -		 * CMT: SFR algo (and HTNA) - this_sack_highest_newack has
    -		 * to be greater than the cumack. Also reset saw_newack to 0
    -		 * for all dests.
    -		 */
    -		TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -			net->saw_newack = 0;
    -			net->this_sack_highest_newack = last_tsn;
    -		}
    -
    -		/*
    -		 * thisSackHighestGap will increase while handling NEW
    -		 * segments this_sack_highest_newack will increase while
    -		 * handling NEWLY ACKED chunks. this_sack_lowest_newack is
    -		 * used for CMT DAC algo. saw_newack will also change.
    -		 */
    -
    -		sctp_handle_nr_sack_segments(m, &offset, stcb, asoc, ch, last_tsn,
    -		    &biggest_tsn_acked, &biggest_tsn_newly_acked, &this_sack_lowest_newack,
    -		    num_seg, num_nr_seg, &ecn_seg_sums);
    -
    -
    -		if (SCTP_BASE_SYSCTL(sctp_strict_sacks)) {
    -			/*
    -			 * validate the biggest_tsn_acked in the gap acks if
    -			 * strict adherence is wanted.
    -			 */
    -			if ((biggest_tsn_acked == send_s) ||
    -			    (compare_with_wrap(biggest_tsn_acked, send_s, MAX_TSN))) {
    -				/*
    -				 * peer is either confused or we are under
    -				 * attack. We must abort.
    -				 */
    -				goto hopeless_peer;
    -			}
    -		}
    -	}
    -skip_segments:
    -	/*******************************************/
    -	/* cancel ALL T3-send timer if accum moved */
    -	/*******************************************/
    -	if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
    -		TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -			if (net->new_pseudo_cumack)
    -				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
    -				    stcb, net,
    -				    SCTP_FROM_SCTP_INDATA + SCTP_LOC_27);
    -
    -		}
    -	} else {
    -		if (accum_moved) {
    -			TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
    -				    stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_28);
    -			}
    -		}
    -	}
    -	/********************************************/
    -	/* drop the acked chunks from the sendqueue */
    -	/********************************************/
    -	asoc->last_acked_seq = cum_ack;
    -
    -	tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -	if (tp1 == NULL)
    -		goto done_with_it;
    -	do {
    -		if (compare_with_wrap(tp1->rec.data.TSN_seq, cum_ack,
    -		    MAX_TSN)) {
    -			break;
    -		}
    -		if (tp1->sent == SCTP_DATAGRAM_UNSENT) {
    -			/* no more sent on list */
    -			printf("Warning, tp1->sent == %d and its now acked?\n",
    -			    tp1->sent);
    -		}
    -		tp2 = TAILQ_NEXT(tp1, sctp_next);
    -		TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
    -		if (tp1->pr_sctp_on) {
    -			if (asoc->pr_sctp_cnt != 0)
    -				asoc->pr_sctp_cnt--;
    -		}
    -		if ((TAILQ_FIRST(&asoc->sent_queue) == NULL) &&
    -		    (asoc->total_flight > 0)) {
    -#ifdef INVARIANTS
    -			panic("Warning flight size is postive and should be 0");
    -#else
    -			SCTP_PRINTF("Warning flight size incorrect should be 0 is %d\n",
    -			    asoc->total_flight);
    -#endif
    -			asoc->total_flight = 0;
    -		}
    -		if (tp1->data) {
    -			/* sa_ignore NO_NULL_CHK */
    -			sctp_free_bufspace(stcb, asoc, tp1, 1);
    -			sctp_m_freem(tp1->data);
    -			if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(tp1->flags)) {
    -				asoc->sent_queue_cnt_removeable--;
    -			}
    -		}
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
    -			sctp_log_sack(asoc->last_acked_seq,
    -			    cum_ack,
    -			    tp1->rec.data.TSN_seq,
    -			    0,
    -			    0,
    -			    SCTP_LOG_FREE_SENT);
    -		}
    -		tp1->data = NULL;
    -		asoc->sent_queue_cnt--;
    -		sctp_free_a_chunk(stcb, tp1);
    -		wake_him++;
    -		tp1 = tp2;
    -	} while (tp1 != NULL);
    -
    -done_with_it:
    -	/* sa_ignore NO_NULL_CHK */
    -	if ((wake_him) && (stcb->sctp_socket)) {
    -#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    -		struct socket *so;
    -
    -#endif
    -		SOCKBUF_LOCK(&stcb->sctp_socket->so_snd);
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_WAKE_LOGGING_ENABLE) {
    -			sctp_wakeup_log(stcb, cum_ack, wake_him, SCTP_WAKESND_FROM_SACK);
    -		}
    -#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    -		so = SCTP_INP_SO(stcb->sctp_ep);
    -		atomic_add_int(&stcb->asoc.refcnt, 1);
    -		SCTP_TCB_UNLOCK(stcb);
    -		SCTP_SOCKET_LOCK(so, 1);
    -		SCTP_TCB_LOCK(stcb);
    -		atomic_subtract_int(&stcb->asoc.refcnt, 1);
    -		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
    -			/* assoc was freed while we were unlocked */
    -			SCTP_SOCKET_UNLOCK(so, 1);
    -			return;
    -		}
    -#endif
    -		sctp_sowwakeup_locked(stcb->sctp_ep, stcb->sctp_socket);
    -#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    -		SCTP_SOCKET_UNLOCK(so, 1);
    -#endif
    -	} else {
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_WAKE_LOGGING_ENABLE) {
    -			sctp_wakeup_log(stcb, cum_ack, wake_him, SCTP_NOWAKE_FROM_SACK);
    -		}
    -	}
    -
    -	if (asoc->fast_retran_loss_recovery && accum_moved) {
    -		if (compare_with_wrap(asoc->last_acked_seq,
    -		    asoc->fast_recovery_tsn, MAX_TSN) ||
    -		    asoc->last_acked_seq == asoc->fast_recovery_tsn) {
    -			/* Setup so we will exit RFC2582 fast recovery */
    -			will_exit_fast_recovery = 1;
    -		}
    -	}
    -	/*
    -	 * Check for revoked fragments:
    -	 * 
    -	 * if Previous sack - Had no frags then we can't have any revoked if
    -	 * Previous sack - Had frag's then - If we now have frags aka
    -	 * num_seg > 0 call sctp_check_for_revoked() to tell if peer revoked
    -	 * some of them. else - The peer revoked all ACKED fragments, since
    -	 * we had some before and now we have NONE.
    -	 */
    -
    -	if (num_seg)
    -		sctp_check_for_revoked(stcb, asoc, cum_ack, biggest_tsn_acked);
    -
    -	else if (asoc->saw_sack_with_frags) {
    -		int cnt_revoked = 0;
    -
    -		tp1 = TAILQ_FIRST(&asoc->sent_queue);
    -		if (tp1 != NULL) {
    -			/* Peer revoked all dg's marked or acked */
    -			TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
    -				/*
    -				 * EY- maybe check only if it is nr_acked
    -				 * nr_marked may not be possible
    -				 */
    -				if ((tp1->sent == SCTP_DATAGRAM_NR_ACKED) ||
    -				    (tp1->sent == SCTP_DATAGRAM_NR_MARKED)) {
    -					/*
    -					 * EY! - TODO: Something previously
    -					 * nr_gapped is reneged, abort the
    -					 * association
    -					 */
    -					return;
    -				}
    -				if ((tp1->sent > SCTP_DATAGRAM_RESEND) &&
    -				    (tp1->sent < SCTP_FORWARD_TSN_SKIP)) {
    -					tp1->sent = SCTP_DATAGRAM_SENT;
    -					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
    -						sctp_misc_ints(SCTP_FLIGHT_LOG_UP_REVOKE,
    -						    tp1->whoTo->flight_size,
    -						    tp1->book_size,
    -						    (uintptr_t) tp1->whoTo,
    -						    tp1->rec.data.TSN_seq);
    -					}
    -					sctp_flight_size_increase(tp1);
    -					sctp_total_flight_increase(stcb, tp1);
    -					tp1->rec.data.chunk_was_revoked = 1;
    -					/*
    -					 * To ensure that this increase in
    -					 * flightsize, which is artificial,
    -					 * does not throttle the sender, we
    -					 * also increase the cwnd
    -					 * artificially.
    -					 */
    -					tp1->whoTo->cwnd += tp1->book_size;
    -					cnt_revoked++;
    -				}
    -			}
    -			if (cnt_revoked) {
    -				reneged_all = 1;
    -			}
    -		}
    -		asoc->saw_sack_with_frags = 0;
    -	}
    -	if (num_seg)
    -		asoc->saw_sack_with_frags = 1;
    -	else
    -		asoc->saw_sack_with_frags = 0;
    -
    -	/* EY! - not sure about if there should be an IF */
    -	if (num_nr_seg)
    -		sctp_check_for_nr_revoked(stcb, asoc, cum_ack, biggest_tsn_acked);
    -	else if (asoc->saw_sack_with_nr_frags) {
    -		/*
    -		 * EY!- TODO: all previously nr_gapped chunks have been
    -		 * reneged abort the association
    -		 */
    -		asoc->saw_sack_with_nr_frags = 0;
    -	}
    -	if (num_nr_seg)
    -		asoc->saw_sack_with_nr_frags = 1;
    -	else
    -		asoc->saw_sack_with_nr_frags = 0;
    -	/* JRS - Use the congestion control given in the CC module */
    -	asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, accum_moved, reneged_all, will_exit_fast_recovery);
    -
    -	if (TAILQ_EMPTY(&asoc->sent_queue)) {
    -		/* nothing left in-flight */
    -		TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -			/* stop all timers */
    -			if (SCTP_BASE_SYSCTL(sctp_early_fr)) {
    -				if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
    -					SCTP_STAT_INCR(sctps_earlyfrstpidsck4);
    -					sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
    -					    SCTP_FROM_SCTP_INDATA + SCTP_LOC_29);
    -				}
    -			}
    -			sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
    -			    stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_30);
    -			net->flight_size = 0;
    -			net->partial_bytes_acked = 0;
    -		}
    -		asoc->total_flight = 0;
    -		asoc->total_flight_count = 0;
    -	}
    -	/**********************************/
    -	/* Now what about shutdown issues */
    -	/**********************************/
    -	if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue)) {
    -		/* nothing left on sendqueue.. consider done */
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_RWND_ENABLE) {
    -			sctp_log_rwnd_set(SCTP_SET_PEER_RWND_VIA_SACK,
    -			    asoc->peers_rwnd, 0, 0, a_rwnd);
    -		}
    -		asoc->peers_rwnd = a_rwnd;
    -		if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
    -			/* SWS sender side engages */
    -			asoc->peers_rwnd = 0;
    -		}
    -		/* clean up */
    -		if ((asoc->stream_queue_cnt == 1) &&
    -		    ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) ||
    -		    (asoc->state & SCTP_STATE_SHUTDOWN_RECEIVED)) &&
    -		    (asoc->locked_on_sending)
    -		    ) {
    -			struct sctp_stream_queue_pending *sp;
    -
    -			/*
    -			 * I may be in a state where we got all across.. but
    -			 * cannot write more due to a shutdown... we abort
    -			 * since the user did not indicate EOR in this case.
    -			 */
    -			sp = TAILQ_LAST(&((asoc->locked_on_sending)->outqueue),
    -			    sctp_streamhead);
    -			if ((sp) && (sp->length == 0)) {
    -				asoc->locked_on_sending = NULL;
    -				if (sp->msg_is_complete) {
    -					asoc->stream_queue_cnt--;
    -				} else {
    -					asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
    -					asoc->stream_queue_cnt--;
    -				}
    -			}
    -		}
    -		if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) &&
    -		    (asoc->stream_queue_cnt == 0)) {
    -			if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
    -				/* Need to abort here */
    -				struct mbuf *oper;
    -
    -		abort_out_now:
    -				*abort_now = 1;
    -				/* XXX */
    -				oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
    -				    0, M_DONTWAIT, 1, MT_DATA);
    -				if (oper) {
    -					struct sctp_paramhdr *ph;
    -					uint32_t *ippp;
    -
    -					SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
    -					    sizeof(uint32_t);
    -					ph = mtod(oper, struct sctp_paramhdr *);
    -					ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
    -					ph->param_length = htons(SCTP_BUF_LEN(oper));
    -					ippp = (uint32_t *) (ph + 1);
    -					*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_31);
    -				}
    -				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_31;
    -				sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_RESPONSE_TO_USER_REQ, oper, SCTP_SO_NOT_LOCKED);
    -				return;
    -			} else {
    -				if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
    -				    (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
    -					SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    -				}
    -				SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
    -				SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
    -				sctp_stop_timers_for_shutdown(stcb);
    -				sctp_send_shutdown(stcb,
    -				    stcb->asoc.primary_destination);
    -				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
    -				    stcb->sctp_ep, stcb, asoc->primary_destination);
    -				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
    -				    stcb->sctp_ep, stcb, asoc->primary_destination);
    -			}
    -			return;
    -		} else if ((SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED) &&
    -		    (asoc->stream_queue_cnt == 0)) {
    -			if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
    -				goto abort_out_now;
    -			}
    -			SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    -			SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
    -			SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
    -			sctp_send_shutdown_ack(stcb,
    -			    stcb->asoc.primary_destination);
    -
    -			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
    -			    stcb->sctp_ep, stcb, asoc->primary_destination);
    -			return;
    -		}
    -	}
    -	/*
    -	 * Now here we are going to recycle net_ack for a different use...
    -	 * HEADS UP.
    -	 */
    -	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -		net->net_ack = 0;
    -	}
    -
    -	/*
    -	 * CMT DAC algorithm: If SACK DAC flag was 0, then no extra marking
    -	 * to be done. Setting this_sack_lowest_newack to the cum_ack will
    -	 * automatically ensure that.
    -	 */
    -	if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac) && (cmt_dac_flag == 0)) {
    -		this_sack_lowest_newack = cum_ack;
    -	}
    -	if (num_seg > 0) {
    -		sctp_strike_gap_ack_chunks(stcb, asoc, biggest_tsn_acked,
    -		    biggest_tsn_newly_acked, this_sack_lowest_newack, accum_moved);
    -	}
    -	/* JRS - Use the congestion control given in the CC module */
    -	asoc->cc_functions.sctp_cwnd_update_after_fr(stcb, asoc);
    -
    -	/******************************************************************
    -	 *  Here we do the stuff with ECN Nonce checking.
    -	 *  We basically check to see if the nonce sum flag was incorrect
    -	 *  or if resynchronization needs to be done. Also if we catch a
    -	 *  misbehaving receiver we give him the kick.
    -	 ******************************************************************/
    -
    -	if (asoc->ecn_nonce_allowed) {
    -		if (asoc->nonce_sum_check) {
    -			if (nonce_sum_flag != ((asoc->nonce_sum_expect_base + ecn_seg_sums) & SCTP_SACK_NONCE_SUM)) {
    -				if (asoc->nonce_wait_for_ecne == 0) {
    -					struct sctp_tmit_chunk *lchk;
    -
    -					lchk = TAILQ_FIRST(&asoc->send_queue);
    -					asoc->nonce_wait_for_ecne = 1;
    -					if (lchk) {
    -						asoc->nonce_wait_tsn = lchk->rec.data.TSN_seq;
    -					} else {
    -						asoc->nonce_wait_tsn = asoc->sending_seq;
    -					}
    -				} else {
    -					if (compare_with_wrap(asoc->last_acked_seq, asoc->nonce_wait_tsn, MAX_TSN) ||
    -					    (asoc->last_acked_seq == asoc->nonce_wait_tsn)) {
    -						/*
    -						 * Misbehaving peer. We need
    -						 * to react to this guy
    -						 */
    -						asoc->ecn_allowed = 0;
    -						asoc->ecn_nonce_allowed = 0;
    -					}
    -				}
    -			}
    -		} else {
    -			/* See if Resynchronization Possible */
    -			if (compare_with_wrap(asoc->last_acked_seq, asoc->nonce_resync_tsn, MAX_TSN)) {
    -				asoc->nonce_sum_check = 1;
    -				/*
    -				 * now we must calculate what the base is.
    -				 * We do this based on two things, we know
    -				 * the total's for all the segments
    -				 * gap-acked in the SACK, its stored in
    -				 * ecn_seg_sums. We also know the SACK's
    -				 * nonce sum, its in nonce_sum_flag. So we
    -				 * can build a truth table to back-calculate
    -				 * the new value of
    -				 * asoc->nonce_sum_expect_base:
    -				 * 
    -				 * SACK-flag-Value         Seg-Sums Base 0 0 0
    -				 * 1                    0 1 0 1 1 1 1 0
    -				 */
    -				asoc->nonce_sum_expect_base = (ecn_seg_sums ^ nonce_sum_flag) & SCTP_SACK_NONCE_SUM;
    -			}
    -		}
    -	}
    -	/* Now are we exiting loss recovery ? */
    -	if (will_exit_fast_recovery) {
    -		/* Ok, we must exit fast recovery */
    -		asoc->fast_retran_loss_recovery = 0;
    -	}
    -	if ((asoc->sat_t3_loss_recovery) &&
    -	    ((compare_with_wrap(asoc->last_acked_seq, asoc->sat_t3_recovery_tsn,
    -	    MAX_TSN) ||
    -	    (asoc->last_acked_seq == asoc->sat_t3_recovery_tsn)))) {
    -		/* end satellite t3 loss recovery */
    -		asoc->sat_t3_loss_recovery = 0;
    -	}
    -	/*
    -	 * CMT Fast recovery
    -	 */
    -	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -		if (net->will_exit_fast_recovery) {
    -			/* Ok, we must exit fast recovery */
    -			net->fast_retran_loss_recovery = 0;
    -		}
    -	}
    -
    -	/* Adjust and set the new rwnd value */
    -	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_RWND_ENABLE) {
    -		sctp_log_rwnd_set(SCTP_SET_PEER_RWND_VIA_SACK,
    -		    asoc->peers_rwnd, asoc->total_flight, (asoc->sent_queue_cnt * SCTP_BASE_SYSCTL(sctp_peer_chunk_oh)), a_rwnd);
    -	}
    -	asoc->peers_rwnd = sctp_sbspace_sub(a_rwnd,
    -	    (uint32_t) (asoc->total_flight + (asoc->sent_queue_cnt * SCTP_BASE_SYSCTL(sctp_peer_chunk_oh))));
    -	if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
    -		/* SWS sender side engages */
    -		asoc->peers_rwnd = 0;
    -	}
    -	if (asoc->peers_rwnd > old_rwnd) {
    -		win_probe_recovery = 1;
    -	}
    -	/*
    -	 * Now we must setup so we have a timer up for anyone with
    -	 * outstanding data.
    -	 */
    -	done_once = 0;
    -again:
    -	j = 0;
    -	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -		if (win_probe_recovery && (net->window_probe)) {
    -			win_probe_recovered = 1;
    -			/*-
    -			 * Find first chunk that was used with
    -			 * window probe and clear the event. Put
    -			 * it back into the send queue as if has
    -			 * not been sent.
    -			 */
    -			TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
    -				if (tp1->window_probe) {
    -					sctp_window_probe_recovery(stcb, asoc, net, tp1);
    -					break;
    -				}
    -			}
    -		}
    -		if (net->flight_size) {
    -			j++;
    -			sctp_timer_start(SCTP_TIMER_TYPE_SEND,
    -			    stcb->sctp_ep, stcb, net);
    -			if (net->window_probe) {
    -				net->window_probe = 0;
    -			}
    -		} else {
    -			if (net->window_probe) {
    -				net->window_probe = 0;
    -				sctp_timer_start(SCTP_TIMER_TYPE_SEND,
    -				    stcb->sctp_ep, stcb, net);
    -			} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
    -				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
    -				    stcb, net,
    -				    SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
    -			}
    -			if (SCTP_BASE_SYSCTL(sctp_early_fr)) {
    -				if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
    -					SCTP_STAT_INCR(sctps_earlyfrstpidsck4);
    -					sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
    -					    SCTP_FROM_SCTP_INDATA + SCTP_LOC_23);
    -				}
    -			}
    -		}
    -	}
    -	if ((j == 0) &&
    -	    (!TAILQ_EMPTY(&asoc->sent_queue)) &&
    -	    (asoc->sent_queue_retran_cnt == 0) &&
    -	    (win_probe_recovered == 0) &&
    -	    (done_once == 0)) {
    -		/*
    -		 * huh, this should not happen unless all packets are
    -		 * PR-SCTP and marked to skip of course.
    -		 */
    -		if (sctp_fs_audit(asoc)) {
    -			TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    -				net->flight_size = 0;
    -			}
    -			asoc->total_flight = 0;
    -			asoc->total_flight_count = 0;
    -			asoc->sent_queue_retran_cnt = 0;
    -			TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
    -				if (tp1->sent < SCTP_DATAGRAM_RESEND) {
    -					sctp_flight_size_increase(tp1);
    -					sctp_total_flight_increase(stcb, tp1);
    -				} else if (tp1->sent == SCTP_DATAGRAM_RESEND) {
    -					asoc->sent_queue_retran_cnt++;
    -				}
    -			}
    -		}
    -		done_once = 1;
    -		goto again;
    -	}
    -	/*********************************************/
    -	/* Here we perform PR-SCTP procedures        */
    -	/* (section 4.2)                             */
    -	/*********************************************/
    -	/* C1. update advancedPeerAckPoint */
    -	if (compare_with_wrap(cum_ack, asoc->advanced_peer_ack_point, MAX_TSN)) {
    -		asoc->advanced_peer_ack_point = cum_ack;
    -	}
    -	/* C2. try to further move advancedPeerAckPoint ahead */
    -	if ((asoc->peer_supports_prsctp) && (asoc->pr_sctp_cnt > 0)) {
    -		struct sctp_tmit_chunk *lchk;
    -		uint32_t old_adv_peer_ack_point;
    -
    -		old_adv_peer_ack_point = asoc->advanced_peer_ack_point;
    -		lchk = sctp_try_advance_peer_ack_point(stcb, asoc);
    -		/* C3. See if we need to send a Fwd-TSN */
    -		if (compare_with_wrap(asoc->advanced_peer_ack_point, cum_ack,
    -		    MAX_TSN)) {
    -			/*
    -			 * ISSUE with ECN, see FWD-TSN processing for notes
    -			 * on issues that will occur when the ECN NONCE
    -			 * stuff is put into SCTP for cross checking.
    -			 */
    -			if (compare_with_wrap(asoc->advanced_peer_ack_point, old_adv_peer_ack_point,
    -			    MAX_TSN)) {
    -				send_forward_tsn(stcb, asoc);
    -				/*
    -				 * ECN Nonce: Disable Nonce Sum check when
    -				 * FWD TSN is sent and store resync tsn
    -				 */
    -				asoc->nonce_sum_check = 0;
    -				asoc->nonce_resync_tsn = asoc->advanced_peer_ack_point;
    -			} else if (lchk) {
    -				/* try to FR fwd-tsn's that get lost too */
    -				lchk->rec.data.fwd_tsn_cnt++;
    -				if (lchk->rec.data.fwd_tsn_cnt > 3) {
    -					send_forward_tsn(stcb, asoc);
    -					lchk->rec.data.fwd_tsn_cnt = 0;
    -				}
    -			}
    -		}
    -		if (lchk) {
    -			/* Assure a timer is up */
    -			sctp_timer_start(SCTP_TIMER_TYPE_SEND,
    -			    stcb->sctp_ep, stcb, lchk->whoTo);
    -		}
    -	}
    -	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_RWND_LOGGING_ENABLE) {
    -		sctp_misc_ints(SCTP_SACK_RWND_UPDATE,
    -		    a_rwnd,
    -		    stcb->asoc.peers_rwnd,
    -		    stcb->asoc.total_flight,
    -		    stcb->asoc.total_output_queue_size);
    -	}
    -}
    diff --git a/sys/netinet/sctp_indata.h b/sys/netinet/sctp_indata.h
    index 76fa9467f7d..b6a8323a5d5 100644
    --- a/sys/netinet/sctp_indata.h
    +++ b/sys/netinet/sctp_indata.h
    @@ -96,18 +96,11 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
         uint32_t rwnd, int nonce_sum_flag, int *abort_now);
     
     void
    -sctp_handle_sack(struct mbuf *m, int offset, struct sctp_sack_chunk *, struct sctp_tcb *,
    -    struct sctp_nets *, int *, int, uint32_t);
    -
    -/* EY does "exactly" the same as sctp_express_handle_sack */
    -void
    -sctp_express_handle_nr_sack(struct sctp_tcb *stcb, uint32_t cumack,
    -    uint32_t rwnd, int nonce_sum_flag, int *abort_now);
    -
    -/* EY nr_sack version of sctp_handle_sack */
    -void
    -sctp_handle_nr_sack(struct mbuf *m, int offset, struct sctp_nr_sack_chunk *, struct sctp_tcb *,
    -    struct sctp_nets *, int *, int, uint32_t);
    +sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
    +    struct sctp_tcb *stcb, struct sctp_nets *net_from,
    +    uint16_t num_seg, uint16_t num_nr_seg, uint16_t num_dup,
    +    int *abort_now, uint8_t flags,
    +    uint32_t cum_ack, uint32_t rwnd);
     
     /* draft-ietf-tsvwg-usctp */
     void
    diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
    index 18b7d557e7b..89a7a533725 100644
    --- a/sys/netinet/sctp_input.c
    +++ b/sys/netinet/sctp_input.c
    @@ -4599,16 +4599,18 @@ process_control_chunks:
     				struct sctp_sack_chunk *sack;
     				int abort_now = 0;
     				uint32_t a_rwnd, cum_ack;
    -				uint16_t num_seg;
    +				uint16_t num_seg, num_dup;
    +				uint8_t flags;
    +				int offset_seg, offset_dup;
     				int nonce_sum_flag;
     
    -				if ((stcb == NULL) || (chk_length < sizeof(struct sctp_sack_chunk))) {
    -					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on sack chunk, too small\n");
    -					*offset = length;
    -					if (locked_tcb) {
    -						SCTP_TCB_UNLOCK(locked_tcb);
    -					}
    -					return (NULL);
    +				if (stcb == NULL) {
    +					SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing SACK chunk\n");
    +					break;
    +				}
    +				if (chk_length < sizeof(struct sctp_sack_chunk)) {
    +					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on SACK chunk, too small\n");
    +					break;
     				}
     				if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
     					/*-
    @@ -4619,15 +4621,22 @@ process_control_chunks:
     					break;
     				}
     				sack = (struct sctp_sack_chunk *)ch;
    -				nonce_sum_flag = ch->chunk_flags & SCTP_SACK_NONCE_SUM;
    +				flags = ch->chunk_flags;
    +				nonce_sum_flag = flags & SCTP_SACK_NONCE_SUM;
     				cum_ack = ntohl(sack->sack.cum_tsn_ack);
     				num_seg = ntohs(sack->sack.num_gap_ack_blks);
    +				num_dup = ntohs(sack->sack.num_dup_tsns);
     				a_rwnd = (uint32_t) ntohl(sack->sack.a_rwnd);
    +				if (sizeof(struct sctp_sack_chunk) +
    +				    num_seg * sizeof(struct sctp_gap_ack_block) +
    +				    num_dup * sizeof(uint32_t) != chk_length) {
    +					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of SACK chunk\n");
    +					break;
    +				}
    +				offset_seg = *offset + sizeof(struct sctp_sack_chunk);
    +				offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
     				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
    -				    cum_ack,
    -				    num_seg,
    -				    a_rwnd
    -				    );
    +				    cum_ack, num_seg, a_rwnd);
     				stcb->asoc.seen_a_sack_this_pkt = 1;
     				if ((stcb->asoc.pr_sctp_cnt == 0) &&
     				    (num_seg == 0) &&
    @@ -4649,19 +4658,21 @@ process_control_chunks:
     					    &abort_now);
     				} else {
     					if (netp && *netp)
    -						sctp_handle_sack(m, *offset,
    -						    sack, stcb, *netp, &abort_now, chk_length, a_rwnd);
    -				}
    -				if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
    -				    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
    -				    (stcb->asoc.stream_queue_cnt == 0)) {
    -					sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    +						sctp_handle_sack(m, offset_seg, offset_dup,
    +						    stcb, *netp,
    +						    num_seg, 0, num_dup, &abort_now, flags,
    +						    cum_ack, a_rwnd);
     				}
     				if (abort_now) {
     					/* ABORT signal from sack processing */
     					*offset = length;
     					return (NULL);
     				}
    +				if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
    +				    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
    +				    (stcb->asoc.stream_queue_cnt == 0)) {
    +					sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    +				}
     			}
     			break;
     			/*
    @@ -4675,80 +4686,90 @@ process_control_chunks:
     				struct sctp_nr_sack_chunk *nr_sack;
     				int abort_now = 0;
     				uint32_t a_rwnd, cum_ack;
    -				uint16_t num_seg, num_nr_seg;
    +				uint16_t num_seg, num_nr_seg, num_dup;
    +				uint8_t flags;
    +				int offset_seg, offset_dup;
     				int nonce_sum_flag;
     
    -				if ((stcb == NULL) || (chk_length < sizeof(struct sctp_nr_sack_chunk))) {
    -					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on nr_sack chunk, too small\n");
    -			ignore_nr_sack:
    -					*offset = length;
    -					if (locked_tcb) {
    -						SCTP_TCB_UNLOCK(locked_tcb);
    -					}
    -					return (NULL);
    -				}
     				/*
     				 * EY nr_sacks have not been negotiated but
     				 * the peer end sent an nr_sack, silently
     				 * discard the chunk
     				 */
    -				if (!(SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)) {
    +				if (!(SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +				    stcb->asoc.peer_supports_nr_sack)) {
     					goto unknown_chunk;
     				}
    +				if (stcb == NULL) {
    +					SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing NR-SACK chunk\n");
    +					break;
    +				}
    +				if (chk_length < sizeof(struct sctp_nr_sack_chunk)) {
    +					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on NR-SACK chunk, too small\n");
    +					break;
    +				}
     				if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
     					/*-
     					 * If we have sent a shutdown-ack, we will pay no
     					 * attention to a sack sent in to us since
     					 * we don't care anymore.
     					 */
    -					goto ignore_nr_sack;
    +					break;
     				}
     				nr_sack = (struct sctp_nr_sack_chunk *)ch;
    -				nonce_sum_flag = ch->chunk_flags & SCTP_SACK_NONCE_SUM;
    +				flags = ch->chunk_flags;
    +				nonce_sum_flag = flags & SCTP_SACK_NONCE_SUM;
     
     				cum_ack = ntohl(nr_sack->nr_sack.cum_tsn_ack);
     				num_seg = ntohs(nr_sack->nr_sack.num_gap_ack_blks);
     				num_nr_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks);
    +				num_dup = ntohs(nr_sack->nr_sack.num_dup_tsns);
     				a_rwnd = (uint32_t) ntohl(nr_sack->nr_sack.a_rwnd);
    +				if (sizeof(struct sctp_nr_sack_chunk) +
    +				    (num_seg + num_nr_seg) * sizeof(struct sctp_gap_ack_block) +
    +				    num_dup * sizeof(uint32_t) != chk_length) {
    +					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of NR_SACK chunk\n");
    +					break;
    +				}
    +				offset_seg = *offset + sizeof(struct sctp_nr_sack_chunk);
    +				offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
     				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
    -				    cum_ack,
    -				    num_seg,
    -				    a_rwnd
    -				    );
    +				    cum_ack, num_seg, a_rwnd);
     				stcb->asoc.seen_a_sack_this_pkt = 1;
     				if ((stcb->asoc.pr_sctp_cnt == 0) &&
    -				    (num_seg == 0) &&
    +				    (num_seg == 0) && (num_nr_seg == 0) &&
     				    ((compare_with_wrap(cum_ack, stcb->asoc.last_acked_seq, MAX_TSN)) ||
     				    (cum_ack == stcb->asoc.last_acked_seq)) &&
     				    (stcb->asoc.saw_sack_with_frags == 0) &&
    -				    (!TAILQ_EMPTY(&stcb->asoc.sent_queue))
    -				    ) {
    +				    (!TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
     					/*
     					 * We have a SIMPLE sack having no
     					 * prior segments and data on sent
    -					 * queue to be acked.. Use the
    -					 * faster path sack processing. We
    -					 * also allow window update sacks
    -					 * with no missing segments to go
    -					 * this way too.
    +					 * queue to be acked. Use the faster
    +					 * path sack processing. We also
    +					 * allow window update sacks with no
    +					 * missing segments to go this way
    +					 * too.
     					 */
    -					sctp_express_handle_nr_sack(stcb, cum_ack, a_rwnd, nonce_sum_flag,
    +					sctp_express_handle_sack(stcb, cum_ack, a_rwnd, nonce_sum_flag,
     					    &abort_now);
     				} else {
     					if (netp && *netp)
    -						sctp_handle_nr_sack(m, *offset,
    -						    nr_sack, stcb, *netp, &abort_now, chk_length, a_rwnd);
    -				}
    -				if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
    -				    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
    -				    (stcb->asoc.stream_queue_cnt == 0)) {
    -					sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    +						sctp_handle_sack(m, offset_seg, offset_dup,
    +						    stcb, *netp,
    +						    num_seg, num_nr_seg, num_dup, &abort_now, flags,
    +						    cum_ack, a_rwnd);
     				}
     				if (abort_now) {
     					/* ABORT signal from sack processing */
     					*offset = length;
     					return (NULL);
     				}
    +				if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
    +				    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
    +				    (stcb->asoc.stream_queue_cnt == 0)) {
    +					sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    +				}
     			}
     			break;
     
    diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
    index af0e4885eb1..4afe0099e05 100644
    --- a/sys/netinet/sctp_output.c
    +++ b/sys/netinet/sctp_output.c
    @@ -10172,7 +10172,6 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     	struct sctp_nr_sack_chunk *nr_sack;
     
     	struct sctp_gap_ack_block *gap_descriptor;
    -	struct sctp_nr_gap_ack_block *nr_gap_descriptor;
     
     	struct sack_track *selector;
     	struct sack_track *nr_selector;
    @@ -10433,8 +10432,6 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     	}
     	/*---------------------------------------------------------filling the nr_gap_ack blocks----------------------------------------------------*/
     
    -	nr_gap_descriptor = (struct sctp_nr_gap_ack_block *)gap_descriptor;
    -
     	/* EY - there will be gaps + nr_gaps if draining is possible */
     	if ((SCTP_BASE_SYSCTL(sctp_do_drain)) && (limit_reached == 0)) {
     
    @@ -10470,7 +10467,7 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     					 * ok to merge.
     					 */
     					num_nr_gap_blocks--;
    -					nr_gap_descriptor--;
    +					gap_descriptor--;
     				}
     				if (nr_selector->num_entries == 0)
     					mergeable = 0;
    @@ -10489,12 +10486,12 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     							 * left side
     							 */
     							mergeable = 0;
    -							nr_gap_descriptor->start = htons((nr_selector->gaps[j].start + offset));
    +							gap_descriptor->start = htons((nr_selector->gaps[j].start + offset));
     						}
    -						nr_gap_descriptor->end = htons((nr_selector->gaps[j].end + offset));
    +						gap_descriptor->end = htons((nr_selector->gaps[j].end + offset));
     						num_nr_gap_blocks++;
    -						nr_gap_descriptor++;
    -						if (((caddr_t)nr_gap_descriptor + sizeof(struct sctp_nr_gap_ack_block)) > limit) {
    +						gap_descriptor++;
    +						if (((caddr_t)gap_descriptor + sizeof(struct sctp_gap_ack_block)) > limit) {
     							/* no more room */
     							limit_reached = 1;
     							break;
    @@ -10517,7 +10514,7 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     
     	/* now we must add any dups we are going to report. */
     	if ((limit_reached == 0) && (asoc->numduptsns)) {
    -		dup = (uint32_t *) nr_gap_descriptor;
    +		dup = (uint32_t *) gap_descriptor;
     		for (i = 0; i < asoc->numduptsns; i++) {
     			*dup = htonl(asoc->dup_tsns[i]);
     			dup++;
    @@ -10537,10 +10534,9 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     		num_nr_gap_blocks = num_gap_blocks;
     		num_gap_blocks = 0;
     	}
    -	a_chk->send_size = (sizeof(struct sctp_nr_sack_chunk) +
    -	    (num_gap_blocks * sizeof(struct sctp_gap_ack_block)) +
    -	    (num_nr_gap_blocks * sizeof(struct sctp_nr_gap_ack_block)) +
    -	    (num_dups * sizeof(int32_t)));
    +	a_chk->send_size = sizeof(struct sctp_nr_sack_chunk) +
    +	    (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
    +	    num_dups * sizeof(int32_t);
     
     	SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
     	nr_sack->nr_sack.num_gap_ack_blks = htons(num_gap_blocks);
    diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h
    index b1a0f13a650..9b952fd022b 100644
    --- a/sys/netinet/sctp_structs.h
    +++ b/sys/netinet/sctp_structs.h
    @@ -1043,8 +1043,6 @@ struct sctp_association {
     	uint8_t delayed_connection;
     	uint8_t ifp_had_enobuf;
     	uint8_t saw_sack_with_frags;
    -	/* EY */
    -	uint8_t saw_sack_with_nr_frags;
     	uint8_t in_asocid_hash;
     	uint8_t assoc_up_sent;
     	uint8_t adaptation_needed;
    
    From 3c9d6800fcc7ca8e0b666bed318b73f061b4f095 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:57:16 +0000
    Subject: [PATCH 1987/2592] MFC of 202782
    
    Michaels changes that took out [0] -> for []
    ---
     sys/netinet/sctp_auth.h   |  4 ++--
     sys/netinet/sctp_header.h | 18 +++++++++---------
     sys/netinet/sctp_uio.h    | 16 ++++++++--------
     3 files changed, 19 insertions(+), 19 deletions(-)
    
    diff --git a/sys/netinet/sctp_auth.h b/sys/netinet/sctp_auth.h
    index cecdb907bc6..ef021715483 100644
    --- a/sys/netinet/sctp_auth.h
    +++ b/sys/netinet/sctp_auth.h
    @@ -60,7 +60,7 @@ typedef union sctp_hash_context {
     
     typedef struct sctp_key {
     	uint32_t keylen;
    -	uint8_t key[0];
    +	uint8_t key[];
     }        sctp_key_t;
     
     typedef struct sctp_shared_key {
    @@ -83,7 +83,7 @@ typedef struct sctp_auth_chklist {
     typedef struct sctp_hmaclist {
     	uint16_t max_algo;	/* max algorithms allocated */
     	uint16_t num_algo;	/* num algorithms used */
    -	uint16_t hmac[0];
    +	uint16_t hmac[];
     }             sctp_hmaclist_t;
     
     /* authentication info */
    diff --git a/sys/netinet/sctp_header.h b/sys/netinet/sctp_header.h
    index e4ad773e049..fee4bc89763 100644
    --- a/sys/netinet/sctp_header.h
    +++ b/sys/netinet/sctp_header.h
    @@ -138,7 +138,7 @@ struct sctp_asconf_addrv4_param {	/* an ASCONF address (v4) parameter */
     
     struct sctp_supported_chunk_types_param {
     	struct sctp_paramhdr ph;/* type = 0x8008  len = x */
    -	uint8_t chunk_types[0];
    +	uint8_t chunk_types[];
     }                                SCTP_PACKED;
     
     
    @@ -219,7 +219,7 @@ struct sctp_state_cookie {	/* this is our definition... */
     struct sctp_missing_nat_state {
     	uint16_t cause;
     	uint16_t length;
    -	uint8_t data[0];
    +	uint8_t data[];
     }                      SCTP_PACKED;
     
     
    @@ -451,7 +451,7 @@ struct sctp_pktdrop_chunk {
     	uint32_t current_onq;
     	uint16_t trunc_len;
     	uint16_t reserved;
    -	uint8_t data[0];
    +	uint8_t data[];
     }                  SCTP_PACKED;
     
     /**********STREAM RESET STUFF ******************/
    @@ -461,13 +461,13 @@ struct sctp_stream_reset_out_request {
     	uint32_t request_seq;	/* monotonically increasing seq no */
     	uint32_t response_seq;	/* if a response, the resp seq no */
     	uint32_t send_reset_at_tsn;	/* last TSN I assigned outbound */
    -	uint16_t list_of_streams[0];	/* if not all list of streams */
    +	uint16_t list_of_streams[];	/* if not all list of streams */
     }                             SCTP_PACKED;
     
     struct sctp_stream_reset_in_request {
     	struct sctp_paramhdr ph;
     	uint32_t request_seq;
    -	uint16_t list_of_streams[0];	/* if not all list of streams */
    +	uint16_t list_of_streams[];	/* if not all list of streams */
     }                            SCTP_PACKED;
     
     
    @@ -545,24 +545,24 @@ struct sctp_stream_reset_resp_tsn {
     #define SCTP_RANDOM_MAX_SIZE 256
     struct sctp_auth_random {
     	struct sctp_paramhdr ph;/* type = 0x8002 */
    -	uint8_t random_data[0];
    +	uint8_t random_data[];
     }                SCTP_PACKED;
     
     struct sctp_auth_chunk_list {
     	struct sctp_paramhdr ph;/* type = 0x8003 */
    -	uint8_t chunk_types[0];
    +	uint8_t chunk_types[];
     }                    SCTP_PACKED;
     
     struct sctp_auth_hmac_algo {
     	struct sctp_paramhdr ph;/* type = 0x8004 */
    -	uint16_t hmac_ids[0];
    +	uint16_t hmac_ids[];
     }                   SCTP_PACKED;
     
     struct sctp_auth_chunk {
     	struct sctp_chunkhdr ch;
     	uint16_t shared_key_id;
     	uint16_t hmac_id;
    -	uint8_t hmac[0];
    +	uint8_t hmac[];
     }               SCTP_PACKED;
     
     struct sctp_auth_invalid_hmac {
    diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h
    index 37b581fe732..19089301411 100644
    --- a/sys/netinet/sctp_uio.h
    +++ b/sys/netinet/sctp_uio.h
    @@ -276,7 +276,7 @@ struct sctp_send_failed {
     	uint32_t ssf_error;
     	struct sctp_sndrcvinfo ssf_info;
     	sctp_assoc_t ssf_assoc_id;
    -	uint8_t ssf_data[0];
    +	uint8_t ssf_data[];
     };
     
     /* flag that indicates state of data */
    @@ -370,7 +370,7 @@ struct sctp_stream_reset_event {
     	uint16_t strreset_flags;
     	uint32_t strreset_length;
     	sctp_assoc_t strreset_assoc_id;
    -	uint16_t strreset_list[0];
    +	uint16_t strreset_list[];
     };
     
     /* flags in strreset_flags field */
    @@ -517,13 +517,13 @@ struct sctp_authchunk {
     struct sctp_authkey {
     	sctp_assoc_t sca_assoc_id;
     	uint16_t sca_keynumber;
    -	uint8_t sca_key[0];
    +	uint8_t sca_key[];
     };
     
     /* SCTP_HMAC_IDENT */
     struct sctp_hmacalgo {
     	uint32_t shmac_number_of_idents;
    -	uint16_t shmac_idents[0];
    +	uint16_t shmac_idents[];
     };
     
     /* AUTH hmac_id */
    @@ -544,7 +544,7 @@ struct sctp_authkeyid {
     /* SCTP_PEER_AUTH_CHUNKS / SCTP_LOCAL_AUTH_CHUNKS */
     struct sctp_authchunks {
     	sctp_assoc_t gauth_assoc_id;
    -	uint8_t gauth_chunks[0];
    +	uint8_t gauth_chunks[];
     };
     
     struct sctp_assoc_value {
    @@ -554,7 +554,7 @@ struct sctp_assoc_value {
     
     struct sctp_assoc_ids {
     	uint32_t gaids_number_of_ids;
    -	sctp_assoc_t gaids_assoc_id[0];
    +	sctp_assoc_t gaids_assoc_id[];
     };
     
     struct sctp_sack_info {
    @@ -603,7 +603,7 @@ struct sctp_stream_reset {
     	sctp_assoc_t strrst_assoc_id;
     	uint16_t strrst_flags;
     	uint16_t strrst_num_streams;	/* 0 == ALL */
    -	uint16_t strrst_list[0];/* list if strrst_num_streams is not 0 */
    +	uint16_t strrst_list[];	/* list if strrst_num_streams is not 0 */
     };
     
     
    @@ -756,7 +756,7 @@ struct sctp_cwnd_log_req {
     	int32_t num_ret;	/* Number returned */
     	int32_t start_at;	/* start at this one */
     	int32_t end_at;		/* end at this one */
    -	struct sctp_cwnd_log log[0];
    +	struct sctp_cwnd_log log[];
     };
     
     struct sctp_timeval {
    
    From 2b7bba217fbece129c8060deef42bf9eacc80c69 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 03:58:56 +0000
    Subject: [PATCH 1988/2592] MFC of  203503
    
    A fix to how the checksum code works that Michael put in.
    ---
     sys/netinet/sctp_input.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
    index 89a7a533725..d211e9ab7d4 100644
    --- a/sys/netinet/sctp_input.c
    +++ b/sys/netinet/sctp_input.c
    @@ -5806,6 +5806,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
     	}
     	sh->checksum = 0;	/* prepare for calc */
     	calc_check = sctp_calculate_cksum(m, iphlen);
    +	sh->checksum = check;
     	SCTP_STAT_INCR(sctps_recvswcrc);
     	if (calc_check != check) {
     		SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x  m:%p mlen:%d iphlen:%d\n",
    @@ -5831,7 +5832,6 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
     		SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors);
     		goto bad;
     	}
    -	sh->checksum = calc_check;
     sctp_skip_csum_4:
     	/* destination port of 0 is illegal, based on RFC2960. */
     	if (sh->dest_port == 0) {
    
    From ec15b6569501e0c0dd7c4bc4180a063e6b71b1ed Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:00:57 +0000
    Subject: [PATCH 1989/2592] MFC of 203847
    
    Puts in missing packed declarations (from Michael). It worked
    only because it was properly aligned anyway ;-)
    ---
     sys/netinet/sctp_header.h | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/netinet/sctp_header.h b/sys/netinet/sctp_header.h
    index fee4bc89763..7fc3e56fd8d 100644
    --- a/sys/netinet/sctp_header.h
    +++ b/sys/netinet/sctp_header.h
    @@ -62,7 +62,7 @@ struct sctp_ipv6addr_param {
     struct sctp_cookie_perserve_param {
     	struct sctp_paramhdr ph;/* type=SCTP_COOKIE_PRESERVE, len=8 */
     	uint32_t time;		/* time in ms to extend cookie */
    -};
    +}                          SCTP_PACKED;
     
     #define SCTP_ARRAY_MIN_LEN 1
     /* Host Name Address */
    @@ -495,7 +495,7 @@ struct sctp_stream_reset_add_strm {
     	uint32_t request_seq;
     	uint16_t number_of_streams;
     	uint16_t reserved;
    -};
    +}                          SCTP_PACKED;
     
     #define SCTP_STREAM_RESET_NOTHING   0x00000000	/* Nothing for me to do */
     #define SCTP_STREAM_RESET_PERFORMED 0x00000001	/* Did it */
    
    From 6c16609631be4381e590b5cf3ed92e445ee81a65 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:02:27 +0000
    Subject: [PATCH 1990/2592] MFD 204040
    
    Fixes some argument calsl (u_long vs uint32_t).
    ---
     sys/netinet/sctp_indata.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
    index 600ada08bdd..65eb08642f5 100644
    --- a/sys/netinet/sctp_indata.c
    +++ b/sys/netinet/sctp_indata.c
    @@ -3479,7 +3479,7 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
     static void
     sctp_check_for_revoked(struct sctp_tcb *stcb,
         struct sctp_association *asoc, uint32_t cumack,
    -    u_long biggest_tsn_acked)
    +    uint32_t biggest_tsn_acked)
     {
     	struct sctp_tmit_chunk *tp1;
     	int tot_revoked = 0;
    @@ -3561,7 +3561,7 @@ sctp_check_for_revoked(struct sctp_tcb *stcb,
     
     static void
     sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
    -    u_long biggest_tsn_acked, u_long biggest_tsn_newly_acked, u_long this_sack_lowest_newack, int accum_moved)
    +    uint32_t biggest_tsn_acked, uint32_t biggest_tsn_newly_acked, uint32_t this_sack_lowest_newack, int accum_moved)
     {
     	struct sctp_tmit_chunk *tp1;
     	int strike_flag = 0;
    @@ -4747,7 +4747,7 @@ again:
     static void
     sctp_check_for_nr_revoked(struct sctp_tcb *stcb,
         struct sctp_association *asoc, uint32_t cumack,
    -    u_long biggest_tsn_acked)
    +    uint32_t biggest_tsn_acked)
     {
     	struct sctp_tmit_chunk *tp1;
     
    
    From ce6856644be850007903c448336ec88a381a8963 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:06:40 +0000
    Subject: [PATCH 1991/2592] MFC of 204096
    
    One of Michaels changes to fix some sign issues and
    some minor locking.
    ---
     sys/netinet/sctp_usrreq.c | 11 +++++++++++
     sys/netinet/sctputil.c    |  5 +----
     2 files changed, 12 insertions(+), 4 deletions(-)
    
    diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
    index 71f5f65b00b..2851272d35a 100644
    --- a/sys/netinet/sctp_usrreq.c
    +++ b/sys/netinet/sctp_usrreq.c
    @@ -980,7 +980,9 @@ sctp_shutdown(struct socket *so)
     	/* For UDP model this is a invalid call */
     	if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
     		/* Restore the flags that the soshutdown took away. */
    +		SOCKBUF_LOCK(&so->so_rcv);
     		so->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
    +		SOCKBUF_UNLOCK(&so->so_rcv);
     		/* This proc will wakeup for read and do nothing (I hope) */
     		SCTP_INP_RUNLOCK(inp);
     		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
    @@ -4465,6 +4467,15 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
     	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
     		stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
     		/* Set the connected flag so we can queue data */
    +		SOCKBUF_LOCK(&so->so_rcv);
    +		so->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
    +		SOCKBUF_UNLOCK(&so->so_rcv);
    +		SOCKBUF_LOCK(&so->so_snd);
    +		so->so_snd.sb_state &= ~SBS_CANTSENDMORE;
    +		SOCKBUF_UNLOCK(&so->so_snd);
    +		SOCK_LOCK(so);
    +		so->so_state &= ~SS_ISDISCONNECTING;
    +		SOCK_UNLOCK(so);
     		soisconnecting(so);
     	}
     	SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT);
    diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
    index 3cef3aa5817..c03b9d0e245 100644
    --- a/sys/netinet/sctputil.c
    +++ b/sys/netinet/sctputil.c
    @@ -849,7 +849,7 @@ retry:
     uint32_t
     sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int save_in_twait)
     {
    -	u_long x, not_done;
    +	uint32_t x, not_done;
     	struct timeval now;
     
     	(void)SCTP_GETTIME_TIMEVAL(&now);
    @@ -2770,8 +2770,6 @@ sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
     	return (EFAULT);
     }
     
    -int sctp_asoc_change_wake = 0;
    -
     static void
     sctp_notify_assoc_change(uint32_t event, struct sctp_tcb *stcb,
         uint32_t error, void *data, int so_locked
    @@ -2825,7 +2823,6 @@ sctp_notify_assoc_change(uint32_t event, struct sctp_tcb *stcb,
     			SCTP_SOCKET_UNLOCK(so, 1);
     		}
     #endif
    -		sctp_asoc_change_wake++;
     	}
     	if (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
     		/* event not enabled */
    
    From dc47896e05bfe1df160aa10c949fd6fe17e81215 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:08:51 +0000
    Subject: [PATCH 1992/2592] MFC of 204141
    
    Cleans up so we can have a vtag reflected argument.
    One of Michaels fixes ;-)
    ---
     sys/netinet/sctp_input.c  | 12 ++++++++++--
     sys/netinet/sctp_output.c | 16 +++++++++++++---
     sys/netinet/sctp_output.h |  2 +-
     3 files changed, 24 insertions(+), 6 deletions(-)
    
    diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
    index d211e9ab7d4..ef187377b95 100644
    --- a/sys/netinet/sctp_input.c
    +++ b/sys/netinet/sctp_input.c
    @@ -918,7 +918,8 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
     
     static void
     sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp,
    -    struct sctp_tcb *stcb, struct sctp_nets *net)
    +    struct sctp_tcb *stcb,
    +    struct sctp_nets *net)
     {
     	struct sctp_association *asoc;
     
    @@ -934,6 +935,13 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp,
     
     	asoc = &stcb->asoc;
     	/* process according to association state */
    +	if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
    +	    (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
    +		/* unexpected SHUTDOWN-ACK... do OOTB handling... */
    +		sctp_send_shutdown_complete(stcb, net, 1);
    +		SCTP_TCB_UNLOCK(stcb);
    +		return;
    +	}
     	if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
     	    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
     		/* unexpected SHUTDOWN-ACK... so ignore... */
    @@ -975,7 +983,7 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp,
     	/* stop the timer */
     	sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_9);
     	/* send SHUTDOWN-COMPLETE */
    -	sctp_send_shutdown_complete(stcb, net);
    +	sctp_send_shutdown_complete(stcb, net, 0);
     	/* notify upper layer protocol */
     	if (stcb->sctp_socket) {
     		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
    index 4afe0099e05..be4c3a8633f 100644
    --- a/sys/netinet/sctp_output.c
    +++ b/sys/netinet/sctp_output.c
    @@ -10622,27 +10622,37 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
     
     void
     sctp_send_shutdown_complete(struct sctp_tcb *stcb,
    -    struct sctp_nets *net)
    +    struct sctp_nets *net,
    +    int reflect_vtag)
     {
     	/* formulate and SEND a SHUTDOWN-COMPLETE */
     	struct mbuf *m_shutdown_comp;
     	struct sctp_shutdown_complete_chunk *shutdown_complete;
    +	uint32_t vtag;
    +	uint8_t flags;
     
     	m_shutdown_comp = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_DONTWAIT, 1, MT_HEADER);
     	if (m_shutdown_comp == NULL) {
     		/* no mbuf's */
     		return;
     	}
    +	if (reflect_vtag) {
    +		flags = SCTP_HAD_NO_TCB;
    +		vtag = stcb->asoc.my_vtag;
    +	} else {
    +		flags = 0;
    +		vtag = stcb->asoc.peer_vtag;
    +	}
     	shutdown_complete = mtod(m_shutdown_comp, struct sctp_shutdown_complete_chunk *);
     	shutdown_complete->ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
    -	shutdown_complete->ch.chunk_flags = 0;
    +	shutdown_complete->ch.chunk_flags = flags;
     	shutdown_complete->ch.chunk_length = htons(sizeof(struct sctp_shutdown_complete_chunk));
     	SCTP_BUF_LEN(m_shutdown_comp) = sizeof(struct sctp_shutdown_complete_chunk);
     	(void)sctp_lowlevel_chunk_output(stcb->sctp_ep, stcb, net,
     	    (struct sockaddr *)&net->ro._l_addr,
     	    m_shutdown_comp, 0, NULL, 0, 1, 0, NULL, 0,
     	    stcb->sctp_ep->sctp_lport, stcb->rport,
    -	    htonl(stcb->asoc.peer_vtag),
    +	    htonl(vtag),
     	    net->port, SCTP_SO_NOT_LOCKED, NULL);
     	SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
     	return;
    diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h
    index ce76febda06..bd40a0b1f09 100644
    --- a/sys/netinet/sctp_output.h
    +++ b/sys/netinet/sctp_output.h
    @@ -111,7 +111,7 @@ void sctp_send_shutdown(struct sctp_tcb *, struct sctp_nets *);
     
     void sctp_send_shutdown_ack(struct sctp_tcb *, struct sctp_nets *);
     
    -void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *);
    +void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *, int);
     
     void 
     sctp_send_shutdown_complete2(struct mbuf *, int, struct sctphdr *,
    
    From f1fb6dd5de1a02dac50a3aa8442ecd220647af5f Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:10:29 +0000
    Subject: [PATCH 1993/2592] MFC of 205627
    
    Part II (more to follow) of the great IETF hack-a-thon to
    fix the NR-Sack code.
    ---
     sys/netinet/sctp_indata.c | 717 +++++++-------------------------------
     sys/netinet/sctp_input.c  |  30 +-
     sys/netinet/sctp_output.c |  72 ++--
     sys/netinet/sctputil.c    |  40 ++-
     4 files changed, 193 insertions(+), 666 deletions(-)
    
    diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
    index 65eb08642f5..243d773723d 100644
    --- a/sys/netinet/sctp_indata.c
    +++ b/sys/netinet/sctp_indata.c
    @@ -46,24 +46,13 @@ __FBSDID("$FreeBSD$");
     #include 
     
     #define SCTP_CALC_TSN_TO_GAP(gap, tsn, mapping_tsn) do { \
    -					if ((compare_with_wrap(tsn, mapping_tsn, MAX_TSN)) || \
    -                        (tsn == mapping_tsn)) { \
    +	                if (tsn >= mapping_tsn) { \
     						gap = tsn - mapping_tsn; \
     					} else { \
     						gap = (MAX_TSN - mapping_tsn) + tsn + 1; \
     					} \
                       } while(0)
     
    -#define SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc) do { \
    -                    if (asoc->mapping_array_base_tsn == asoc->nr_mapping_array_base_tsn) { \
    -                       SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, nr_gap); \
    -                    } else {\
    -                       int lgap; \
    -                       SCTP_CALC_TSN_TO_GAP(lgap, tsn, asoc->mapping_array_base_tsn); \
    -                       SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, lgap); \
    -                    } \
    -                  } while(0)
    -
     /*
      * NOTES: On the outbound side of things I need to check the sack timer to
      * see if I should generate a sack into the chunk queue (if I have data to
    @@ -304,6 +293,44 @@ sctp_build_ctl_cchunk(struct sctp_inpcb *inp,
     	return (buf);
     }
     
    +static void
    +sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn)
    +{
    +	uint32_t gap, i;
    +	int fnd = 0;
    +
    +	if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
    +		return;
    +	}
    +	SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
    +#ifdef INVARIANTS
    +	if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
    +		printf("gap:%x tsn:%x\n", gap, tsn);
    +		sctp_print_mapping_array(asoc);
    +		panic("Things are really messed up now!!");
    +	}
    +#endif
    +	SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
    +	SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
    +	if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    +		asoc->highest_tsn_inside_nr_map = tsn;
    +	}
    +	if (tsn == asoc->highest_tsn_inside_map) {
    +		/* We must back down to see what the new highest is */
    +		for (i = tsn - 1; compare_with_wrap(i, asoc->mapping_array_base_tsn, MAX_TSN); i--) {
    +			SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
    +			if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
    +				asoc->highest_tsn_inside_map = i;
    +				fnd = 1;
    +				break;
    +			}
    +		}
    +		if (!fnd) {
    +			asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
    +		}
    +	}
    +}
    +
     
     /*
      * We are delivering currently from the reassembly queue. We must continue to
    @@ -319,9 +346,6 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
     	int end = 0;
     	int cntDel;
     
    -	/* EY if any out-of-order delivered, then tag it nr on nr_map */
    -	uint32_t nr_tsn, nr_gap;
    -
     	struct sctp_queued_to_read *control, *ctl, *ctlat;
     
     	if (stcb == NULL)
    @@ -430,39 +454,7 @@ abandon:
     		}
     		/* pull it we did it */
     		TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
    -		/*
    -		 * EY this is the chunk that should be tagged nr gapped
    -		 * calculate the gap and such then tag this TSN nr
    -		 * chk->rec.data.TSN_seq
    -		 */
    -		/*
    -		 * EY!-TODO- this tsn should be tagged nr only if it is
    -		 * out-of-order, the if statement should be modified
    -		 */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -		    asoc->peer_supports_nr_sack) {
    -			nr_tsn = chk->rec.data.TSN_seq;
    -			SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
    -			if ((nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    -				/*
    -				 * EY The 1st should never happen, as in
    -				 * process_a_data_chunk method this check
    -				 * should be done
    -				 */
    -				/*
    -				 * EY The 2nd should never happen, because
    -				 * nr_mapping_array is always expanded when
    -				 * mapping_array is expanded
    -				 */
    -				printf("Impossible nr_gap ack range failed\n");
    -			} else {
    -				SCTP_TCB_LOCK_ASSERT(stcb);
    -				SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -				SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
    -				if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
    -					asoc->highest_tsn_inside_nr_map = nr_tsn;
    -			}
    -		}
    +		sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
     		if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
     			asoc->fragmented_delivery_inprogress = 0;
     			if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 0) {
    @@ -509,67 +501,11 @@ abandon:
     						asoc->size_on_all_streams -= ctl->length;
     						sctp_ucount_decr(asoc->cnt_on_all_streams);
     						strm->last_sequence_delivered++;
    -						/*
    -						 * EY will be used to
    -						 * calculate nr-gap
    -						 */
    -						nr_tsn = ctl->sinfo_tsn;
     						sctp_add_to_readq(stcb->sctp_ep, stcb,
     						    ctl,
     						    &stcb->sctp_socket->so_rcv, 1,
     						    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
    -						/*
    -						 * EY -now something is
    -						 * delivered, calculate
    -						 * nr_gap and tag this tsn
    -						 * NR
    -						 */
    -						if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -						    asoc->peer_supports_nr_sack) {
    -							SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
    -							if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
    -							    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    -								/*
    -								 * EY The
    -								 * 1st
    -								 * should
    -								 * never
    -								 * happen,
    -								 * as in
    -								 * process_a_
    -								 * data_chunk
    -								 *  method
    -								 * this
    -								 * check
    -								 * should be
    -								 * done
    -								 */
    -								/*
    -								 * EY The
    -								 * 2nd
    -								 * should
    -								 * never
    -								 * happen,
    -								 * because
    -								 * nr_mapping
    -								 * _array is
    -								 * always
    -								 * expanded
    -								 * when
    -								 * mapping_ar
    -								 * ray is
    -								 * expanded
    -								 */
    -							} else {
    -								SCTP_TCB_LOCK_ASSERT(stcb);
    -								SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -								SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
    -								if (compare_with_wrap(nr_tsn,
    -								    asoc->highest_tsn_inside_nr_map,
    -								    MAX_TSN))
    -									asoc->highest_tsn_inside_nr_map = nr_tsn;
    -							}
    -						}
    +						sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
     						ctl = ctlat;
     					} else {
     						break;
    @@ -618,9 +554,6 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
     	uint16_t nxt_todel;
     	struct mbuf *oper;
     
    -	/* EY- will be used to calculate nr-gap for a tsn */
    -	uint32_t nr_tsn, nr_gap;
    -
     	queue_needed = 1;
     	asoc->size_on_all_streams += control->length;
     	sctp_ucount_incr(asoc->cnt_on_all_streams);
    @@ -682,41 +615,12 @@ protocol_error:
     		asoc->size_on_all_streams -= control->length;
     		sctp_ucount_decr(asoc->cnt_on_all_streams);
     		strm->last_sequence_delivered++;
    -		/* EY will be used to calculate nr-gap */
    -		nr_tsn = control->sinfo_tsn;
    +
     		sctp_add_to_readq(stcb->sctp_ep, stcb,
     		    control,
     		    &stcb->sctp_socket->so_rcv, 1,
     		    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
    -		/*
    -		 * EY this is the chunk that should be tagged nr gapped
    -		 * calculate the gap and such then tag this TSN nr
    -		 * chk->rec.data.TSN_seq
    -		 */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -		    asoc->peer_supports_nr_sack) {
    -			SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
    -			if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
    -			    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    -				printf("Impossible nr_tsn set 2?\n");
    -				/*
    -				 * EY The 1st should never happen, as in
    -				 * process_a_data_chunk method this check
    -				 * should be done
    -				 */
    -				/*
    -				 * EY The 2nd should never happen, because
    -				 * nr_mapping_array is always expanded when
    -				 * mapping_array is expanded
    -				 */
    -			} else {
    -				SCTP_TCB_LOCK_ASSERT(stcb);
    -				SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -				SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
    -				if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
    -					asoc->highest_tsn_inside_nr_map = nr_tsn;
    -			}
    -		}
    +		sctp_mark_non_revokable(asoc, control->sinfo_tsn);
     		control = TAILQ_FIRST(&strm->inqueue);
     		while (control != NULL) {
     			/* all delivered */
    @@ -738,47 +642,12 @@ protocol_error:
     					    SCTP_STR_LOG_FROM_IMMED_DEL);
     				}
     				/* EY will be used to calculate nr-gap */
    -				nr_tsn = control->sinfo_tsn;
     				sctp_add_to_readq(stcb->sctp_ep, stcb,
     				    control,
     				    &stcb->sctp_socket->so_rcv, 1,
     				    SCTP_READ_LOCK_NOT_HELD,
     				    SCTP_SO_NOT_LOCKED);
    -				/*
    -				 * EY this is the chunk that should be
    -				 * tagged nr gapped calculate the gap and
    -				 * such then tag this TSN nr
    -				 * chk->rec.data.TSN_seq
    -				 */
    -				if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -				    asoc->peer_supports_nr_sack) {
    -					SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
    -					if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
    -					    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    -						/*
    -						 * EY The 1st should never
    -						 * happen, as in
    -						 * process_a_data_chunk
    -						 * method this check should
    -						 * be done
    -						 */
    -						/*
    -						 * EY The 2nd should never
    -						 * happen, because
    -						 * nr_mapping_array is
    -						 * always expanded when
    -						 * mapping_array is expanded
    -						 */
    -					} else {
    -						SCTP_TCB_LOCK_ASSERT(stcb);
    -						SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
    -						SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -						if (compare_with_wrap(nr_tsn,
    -						    asoc->highest_tsn_inside_nr_map,
    -						    MAX_TSN))
    -							asoc->highest_tsn_inside_nr_map = nr_tsn;
    -					}
    -				}
    +				sctp_mark_non_revokable(asoc, control->sinfo_tsn);
     				control = at;
     				continue;
     			}
    @@ -1586,9 +1455,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     	/* struct sctp_tmit_chunk *chk; */
     	struct sctp_tmit_chunk *chk;
     	uint32_t tsn, gap;
    -
    -	/* EY - for nr_sack */
    -	uint32_t nr_gap;
     	struct mbuf *dmbuf;
     	int indx, the_len;
     	int need_reasm_check = 0;
    @@ -1640,14 +1506,12 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     			return (0);
     		}
     	}
    -	/* EY - for nr_sack */
    -	nr_gap = gap;
    -
     	if (compare_with_wrap(tsn, *high_tsn, MAX_TSN)) {
     		*high_tsn = tsn;
     	}
     	/* See if we have received this one already */
    -	if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
    +	if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap) ||
    +	    SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, gap)) {
     		SCTP_STAT_INCR(sctps_recvdupdata);
     		if (asoc->numduptsns < SCTP_MAX_DUP_TSNS) {
     			/* Record a dup for the next outbound sack */
    @@ -1714,7 +1578,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     #endif
     		}
     		/* now is it in the mapping array of what we have accepted? */
    -		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
    +		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN) &&
    +		    compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
     			/* Nope not in the valid range dump it */
     			sctp_set_rwnd(stcb, asoc);
     			if ((asoc->cnt_on_all_streams +
    @@ -1758,23 +1623,10 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     		}
     		SCTP_STAT_INCR(sctps_badsid);
     		SCTP_TCB_LOCK_ASSERT(stcb);
    -		SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
    -		/* EY set this tsn present in  nr_sack's nr_mapping_array */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -		    asoc->peer_supports_nr_sack) {
    -			SCTP_TCB_LOCK_ASSERT(stcb);
    -			SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
    -			SCTP_REVERSE_OUT_TSN_PRES(gap, tsn, asoc);
    -		}
    -		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
    -			/* we have a new high score */
    -			asoc->highest_tsn_inside_map = tsn;
    -			/* EY nr_sack version of the above */
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack)
    -				asoc->highest_tsn_inside_nr_map = tsn;
    -			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    -				sctp_log_map(0, 2, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
    -			}
    +
    +		SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
    +		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    +			asoc->highest_tsn_inside_nr_map = tsn;
     		}
     		if (tsn == (asoc->cumulative_tsn + 1)) {
     			/* Update cum-ack */
    @@ -1925,48 +1777,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     		    control, &stcb->sctp_socket->so_rcv,
     		    1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
     
    -		/*
    -		 * EY here I should check if this delivered tsn is
    -		 * out_of_order, if yes then update the nr_map
    -		 */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    -			/*
    -			 * EY check if the mapping_array and nr_mapping
    -			 * array are consistent
    -			 */
    -			if (asoc->mapping_array_base_tsn != asoc->nr_mapping_array_base_tsn)
    -				/*
    -				 * printf("EY-IN
    -				 * sctp_process_a_data_chunk(5): Something
    -				 * is wrong the map base tsn" "\nEY-and
    -				 * nr_map base tsn should be equal.");
    -				 */
    -				/* EY debugging block */
    -			{
    -				/*
    -				 * printf("\nEY-Calculating an
    -				 * nr_gap!!\nmapping_array_size = %d
    -				 * nr_mapping_array_size = %d"
    -				 * "\nEY-mapping_array_base = %d
    -				 * nr_mapping_array_base =
    -				 * %d\nEY-highest_tsn_inside_map = %d"
    -				 * "highest_tsn_inside_nr_map = %d\nEY-TSN =
    -				 * %d nr_gap = %d",asoc->mapping_array_size,
    -				 * asoc->nr_mapping_array_size,
    -				 * asoc->mapping_array_base_tsn,
    -				 * asoc->nr_mapping_array_base_tsn,
    -				 * asoc->highest_tsn_inside_map,
    -				 * asoc->highest_tsn_inside_nr_map,tsn,nr_gap
    -				 * );
    -				 */
    -			}
    -			/* EY - not %100 sure about the lock thing */
    -			SCTP_TCB_LOCK_ASSERT(stcb);
    -			SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -			SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
    -			if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
    -				asoc->highest_tsn_inside_nr_map = tsn;
    -		}
     		if ((chunk_flags & SCTP_DATA_UNORDERED) == 0) {
     			/* for ordered, bump what we delivered */
     			asoc->strmin[strmno].last_sequence_delivered++;
    @@ -1977,6 +1787,10 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     			    SCTP_STR_LOG_FROM_EXPRS_DEL);
     		}
     		control = NULL;
    +		SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
    +		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    +			asoc->highest_tsn_inside_nr_map = tsn;
    +		}
     		goto finish_express_del;
     	}
     failed_express_del:
    @@ -2012,39 +1826,9 @@ failed_express_del:
     				SCTP_PRINTF("Append fails end:%d\n", end);
     				goto failed_pdapi_express_del;
     			}
    -			/*
    -			 * EY It is appended to the read queue in prev if
    -			 * block here I should check if this delivered tsn
    -			 * is out_of_order, if yes then update the nr_map
    -			 */
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -			    asoc->peer_supports_nr_sack) {
    -				/* EY debugging block */
    -				{
    -					/*
    -					 * printf("\nEY-Calculating an
    -					 * nr_gap!!\nEY-mapping_array_size =
    -					 * %d nr_mapping_array_size = %d"
    -					 * "\nEY-mapping_array_base = %d
    -					 * nr_mapping_array_base =
    -					 * %d\nEY-highest_tsn_inside_map =
    -					 * %d" "highest_tsn_inside_nr_map =
    -					 * %d\nEY-TSN = %d nr_gap =
    -					 * %d",asoc->mapping_array_size,
    -					 * asoc->nr_mapping_array_size,
    -					 * asoc->mapping_array_base_tsn,
    -					 * asoc->nr_mapping_array_base_tsn,
    -					 * asoc->highest_tsn_inside_map,
    -					 * asoc->highest_tsn_inside_nr_map,ts
    -					 * n,nr_gap);
    -					 */
    -				}
    -				/* EY - not %100 sure about the lock thing */
    -				SCTP_TCB_LOCK_ASSERT(stcb);
    -				SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -				SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
    -				if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
    -					asoc->highest_tsn_inside_nr_map = tsn;
    +			SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
    +			if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    +				asoc->highest_tsn_inside_nr_map = tsn;
     			}
     			SCTP_STAT_INCR(sctps_recvexpressm);
     			control->sinfo_tsn = tsn;
    @@ -2069,12 +1853,27 @@ failed_express_del:
     					need_reasm_check = 1;
     				}
     			}
    +			SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
    +			if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    +				asoc->highest_tsn_inside_nr_map = tsn;
    +			}
     			control = NULL;
     			goto finish_express_del;
     		}
     	}
     failed_pdapi_express_del:
     	control = NULL;
    +	if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
    +		SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
    +		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    +			asoc->highest_tsn_inside_nr_map = tsn;
    +		}
    +	} else {
    +		SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
    +		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
    +			asoc->highest_tsn_inside_map = tsn;
    +		}
    +	}
     	if ((chunk_flags & SCTP_DATA_NOT_FRAG) != SCTP_DATA_NOT_FRAG) {
     		sctp_alloc_a_chunk(stcb, chk);
     		if (chk == NULL) {
    @@ -2263,56 +2062,7 @@ failed_pdapi_express_del:
     			sctp_add_to_readq(stcb->sctp_ep, stcb,
     			    control,
     			    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
    -			/*
    -			 * EY It is added to the read queue in prev if block
    -			 * here I should check if this delivered tsn is
    -			 * out_of_order, if yes then update the nr_map
    -			 */
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -			    asoc->peer_supports_nr_sack) {
    -				/*
    -				 * EY check if the mapping_array and
    -				 * nr_mapping array are consistent
    -				 */
    -				if (asoc->mapping_array_base_tsn != asoc->nr_mapping_array_base_tsn)
    -					/*
    -					 * printf("EY-IN
    -					 * sctp_process_a_data_chunk(6):
    -					 * Something is wrong the map base
    -					 * tsn" "\nEY-and nr_map base tsn
    -					 * should be equal.");
    -					 */
    -					/*
    -					 * EY - not %100 sure about the lock
    -					 * thing, i think we don't need the
    -					 * below,
    -					 */
    -					/* SCTP_TCB_LOCK_ASSERT(stcb); */
    -				{
    -					/*
    -					 * printf("\nEY-Calculating an
    -					 * nr_gap!!\nEY-mapping_array_size =
    -					 * %d nr_mapping_array_size = %d"
    -					 * "\nEY-mapping_array_base = %d
    -					 * nr_mapping_array_base =
    -					 * %d\nEY-highest_tsn_inside_map =
    -					 * %d" "highest_tsn_inside_nr_map =
    -					 * %d\nEY-TSN = %d nr_gap =
    -					 * %d",asoc->mapping_array_size,
    -					 * asoc->nr_mapping_array_size,
    -					 * asoc->mapping_array_base_tsn,
    -					 * asoc->nr_mapping_array_base_tsn,
    -					 * asoc->highest_tsn_inside_map,
    -					 * asoc->highest_tsn_inside_nr_map,ts
    -					 * n,nr_gap);
    -					 */
    -				}
    -				SCTP_TCB_LOCK_ASSERT(stcb);
    -				SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -				SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
    -				if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN))
    -					asoc->highest_tsn_inside_nr_map = tsn;
    -			}
    +
     		} else {
     			/*
     			 * Special check for when streams are resetting. We
    @@ -2384,13 +2134,6 @@ failed_pdapi_express_del:
     		}
     	}
     finish_express_del:
    -	if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
    -		/* we have a new high score */
    -		asoc->highest_tsn_inside_map = tsn;
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    -			sctp_log_map(0, 2, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
    -		}
    -	}
     	if (tsn == (asoc->cumulative_tsn + 1)) {
     		/* Update cum-ack */
     		asoc->cumulative_tsn = tsn;
    @@ -2412,22 +2155,6 @@ finish_express_del:
     		sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn,
     		    asoc->highest_tsn_inside_map, SCTP_MAP_PREPARE_SLIDE);
     	}
    -	SCTP_TCB_LOCK_ASSERT(stcb);
    -	SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
    -
    -	/*
    -	 * EY - set tsn present in nr-map if  doing nr-sacks and the tsn is
    -	 * non-renegable
    -	 */
    -	if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -	    asoc->peer_supports_nr_sack &&
    -	    (SCTP_BASE_SYSCTL(sctp_do_drain) == 0)) {
    -		SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
    -		SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc);
    -		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    -			asoc->highest_tsn_inside_nr_map = tsn;
    -		}
    -	}
     	/* check the special flag for stream resets */
     	if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) &&
     	    ((compare_with_wrap(asoc->cumulative_tsn, liste->tsn, MAX_TSN)) ||
    @@ -2532,7 +2259,6 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	 */
     	struct sctp_association *asoc;
     	int at;
    -	uint8_t comb_byte;
     	int last_all_ones = 0;
     	int slide_from, slide_end, lgap, distance;
     
    @@ -2540,7 +2266,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	/* int nr_at; */
     	/* int nr_last_all_ones = 0; */
     	/* int nr_slide_from, nr_slide_end, nr_lgap, nr_distance; */
    -	uint32_t old_cumack, old_base, old_highest;
    +	uint32_t old_cumack, old_base, old_highest, highest_tsn;
     
     	asoc = &stcb->asoc;
     	at = 0;
    @@ -2553,30 +2279,23 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	 * offset of the current cum-ack as the starting point.
     	 */
     	at = 0;
    -	for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; slide_from++) {
    -		/*
    -		 * We must combine the renegable and non-renegable arrays
    -		 * here to form a unified view of what is acked right now
    -		 * (since they are kept separate
    -		 */
    -		comb_byte = asoc->mapping_array[slide_from] | asoc->nr_mapping_array[slide_from];
    -		if (comb_byte == 0xff) {
    +	for (slide_from = 0; slide_from < stcb->asoc.nr_mapping_array_size; slide_from++) {
    +		if (asoc->nr_mapping_array[slide_from] == 0xff) {
     			at += 8;
     			last_all_ones = 1;
     		} else {
     			/* there is a 0 bit */
    -			at += sctp_map_lookup_tab[comb_byte];
    +			at += sctp_map_lookup_tab[asoc->nr_mapping_array[slide_from]];
     			last_all_ones = 0;
     			break;
     		}
     	}
    -	asoc->cumulative_tsn = asoc->mapping_array_base_tsn + (at - last_all_ones);
    -	/* at is one off, since in the table a embedded -1 is present */
    +	asoc->cumulative_tsn = asoc->nr_mapping_array_base_tsn + (at - last_all_ones);
     	at++;
     
    -	if (compare_with_wrap(asoc->cumulative_tsn,
    -	    asoc->highest_tsn_inside_map,
    -	    MAX_TSN)) {
    +	if (compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_map, MAX_TSN) &&
    +	    compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)
    +	    ) {
     #ifdef INVARIANTS
     		panic("huh, cumack 0x%x greater than high-tsn 0x%x in map",
     		    asoc->cumulative_tsn, asoc->highest_tsn_inside_map);
    @@ -2591,37 +2310,29 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     		asoc->highest_tsn_inside_nr_map = asoc->cumulative_tsn;
     #endif
     	}
    -	if ((asoc->cumulative_tsn == asoc->highest_tsn_inside_map) && (at >= 8)) {
    +	if (compare_with_wrap(asoc->highest_tsn_inside_nr_map,
    +	    asoc->highest_tsn_inside_map,
    +	    MAX_TSN)) {
    +		highest_tsn = asoc->highest_tsn_inside_nr_map;
    +	} else {
    +		highest_tsn = asoc->highest_tsn_inside_map;
    +	}
    +	if ((asoc->cumulative_tsn == highest_tsn) && (at >= 8)) {
     		/* The complete array was completed by a single FR */
    -		/* higest becomes the cum-ack */
    +		/* highest becomes the cum-ack */
     		int clr;
     
    -		asoc->cumulative_tsn = asoc->highest_tsn_inside_map;
     		/* clear the array */
     		clr = (at >> 3) + 1;
     		if (clr > asoc->mapping_array_size) {
     			clr = asoc->mapping_array_size;
     		}
     		memset(asoc->mapping_array, 0, clr);
    -		/* base becomes one ahead of the cum-ack */
    +		memset(asoc->nr_mapping_array, 0, clr);
    +
     		asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
    -
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    -
    -			if (clr > asoc->nr_mapping_array_size)
    -				clr = asoc->nr_mapping_array_size;
    -
    -			memset(asoc->nr_mapping_array, 0, clr);
    -			/* base becomes one ahead of the cum-ack */
    -			asoc->nr_mapping_array_base_tsn = asoc->cumulative_tsn + 1;
    -			asoc->highest_tsn_inside_nr_map = asoc->cumulative_tsn;
    -		}
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    -			sctp_log_map(old_base, old_cumack, old_highest,
    -			    SCTP_MAP_PREPARE_SLIDE);
    -			sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn,
    -			    asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_CLEARED);
    -		}
    +		asoc->nr_mapping_array_base_tsn = asoc->cumulative_tsn + 1;
    +		asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
     	} else if (at >= 8) {
     		/* we can slide the mapping array down */
     		/* slide_from holds where we hit the first NON 0xff byte */
    @@ -2630,19 +2341,15 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     		 * now calculate the ceiling of the move using our highest
     		 * TSN value
     		 */
    -		if (asoc->highest_tsn_inside_map >= asoc->mapping_array_base_tsn) {
    -			lgap = asoc->highest_tsn_inside_map -
    -			    asoc->mapping_array_base_tsn;
    -		} else {
    -			lgap = (MAX_TSN - asoc->mapping_array_base_tsn) +
    -			    asoc->highest_tsn_inside_map + 1;
    -		}
    -		slide_end = lgap >> 3;
    +		SCTP_CALC_TSN_TO_GAP(lgap, highest_tsn, asoc->mapping_array_base_tsn);
    +		slide_end = (lgap >> 3);
     		if (slide_end < slide_from) {
    +			sctp_print_mapping_array(asoc);
     #ifdef INVARIANTS
     			panic("impossible slide");
     #else
    -			printf("impossible slide?\n");
    +			printf("impossible slide lgap:%x slide_end:%x slide_from:%x? at:%d\n",
    +			    lgap, slide_end, slide_from, at);
     			return;
     #endif
     		}
    @@ -2682,30 +2389,21 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     			for (ii = 0; ii < distance; ii++) {
     				asoc->mapping_array[ii] =
     				    asoc->mapping_array[slide_from + ii];
    +				asoc->nr_mapping_array[ii] =
    +				    asoc->nr_mapping_array[slide_from + ii];
    +
     			}
     			for (ii = distance; ii <= slide_end; ii++) {
     				asoc->mapping_array[ii] = 0;
    +				asoc->nr_mapping_array[ii] = 0;
     			}
     			asoc->mapping_array_base_tsn += (slide_from << 3);
    +			asoc->nr_mapping_array_base_tsn += (slide_from << 3);
     			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
     				sctp_log_map(asoc->mapping_array_base_tsn,
     				    asoc->cumulative_tsn, asoc->highest_tsn_inside_map,
     				    SCTP_MAP_SLIDE_RESULT);
     			}
    -			/*
    -			 * EY if doing nr_sacks then slide the
    -			 * nr_mapping_array accordingly please
    -			 */
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    -				for (ii = 0; ii < distance; ii++) {
    -					asoc->nr_mapping_array[ii] =
    -					    asoc->nr_mapping_array[slide_from + ii];
    -				}
    -				for (ii = distance; ii <= slide_end; ii++) {
    -					asoc->nr_mapping_array[ii] = 0;
    -				}
    -				asoc->nr_mapping_array_base_tsn += (slide_from << 3);
    -			}
     		}
     	}
     	/*
    @@ -2736,8 +2434,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     			int is_a_gap;
     
     			/* is there a gap now ? */
    -			is_a_gap = compare_with_wrap(stcb->asoc.highest_tsn_inside_map,
    -			    stcb->asoc.cumulative_tsn, MAX_TSN);
    +			is_a_gap = compare_with_wrap(highest_tsn, stcb->asoc.cumulative_tsn, MAX_TSN);
     
     			/*
     			 * CMT DAC algorithm: increase number of packets
    @@ -5742,9 +5439,6 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
     	struct sctp_association *asoc;
     	int tt;
     
    -	/* EY -used to calculate nr_gap information */
    -	uint32_t nr_tsn, nr_gap;
    -
     	asoc = &stcb->asoc;
     	tt = strmin->last_sequence_delivered;
     	/*
    @@ -5764,82 +5458,10 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
     			/* deliver it to at least the delivery-q */
     			if (stcb->sctp_socket) {
     				/* EY need the tsn info for calculating nr */
    -				nr_tsn = ctl->sinfo_tsn;
     				sctp_add_to_readq(stcb->sctp_ep, stcb,
     				    ctl,
     				    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
    -				/*
    -				 * EY this is the chunk that should be
    -				 * tagged nr gapped calculate the gap and
    -				 * such then tag this TSN nr
    -				 * chk->rec.data.TSN_seq
    -				 */
    -				if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -				    asoc->peer_supports_nr_sack) {
    -					SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
    -					if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
    -					    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    -						/*
    -						 * EY These should never
    -						 * happen- explained before
    -						 */
    -					} else {
    -						SCTP_TCB_LOCK_ASSERT(stcb);
    -						SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -						SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
    -						if (compare_with_wrap(nr_tsn,
    -						    asoc->highest_tsn_inside_nr_map,
    -						    MAX_TSN))
    -							asoc->highest_tsn_inside_nr_map = nr_tsn;
    -					}
    -					if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, nr_gap))
    -						/*
    -						 * printf("In
    -						 * sctp_kick_prsctp_reorder_q
    -						 * ueue(7): Something wrong,
    -						 * the TSN to be tagged"
    -						 * "\nas NR is not even in
    -						 * the mapping_array, or map
    -						 * and nr_map are
    -						 * inconsistent");
    -						 */
    -						/*
    -						 * EY - not %100 sure about
    -						 * the lock thing, don't
    -						 * think its required
    -						 */
    -						/*
    -						 * SCTP_TCB_LOCK_ASSERT(stcb)
    -						 * ;
    -						 */
    -					{
    -						/*
    -						 * printf("\nCalculating an
    -						 * nr_gap!!\nmapping_array_si
    -						 * ze = %d
    -						 * nr_mapping_array_size =
    -						 * %d" "\nmapping_array_base
    -						 * = %d
    -						 * nr_mapping_array_base =
    -						 * %d\nhighest_tsn_inside_map
    -						 *  = %d"
    -						 * "highest_tsn_inside_nr_map
    -						 *  = %d\nTSN = %d nr_gap =
    -						 * %d",asoc->mapping_array_si
    -						 * ze,
    -						 * asoc->nr_mapping_array_siz
    -						 * e,
    -						 * asoc->mapping_array_base_t
    -						 * sn,
    -						 * asoc->nr_mapping_array_bas
    -						 * e_tsn,
    -						 * asoc->highest_tsn_inside_m
    -						 * ap,
    -						 * asoc->highest_tsn_inside_n
    -						 * r_map,tsn,nr_gap);
    -						 */
    -					}
    -				}
    +				sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
     			}
     		} else {
     			/* no more delivery now. */
    @@ -5864,82 +5486,11 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
     			/* deliver it to at least the delivery-q */
     			strmin->last_sequence_delivered = ctl->sinfo_ssn;
     			if (stcb->sctp_socket) {
    -				/* EY */
    -				nr_tsn = ctl->sinfo_tsn;
     				sctp_add_to_readq(stcb->sctp_ep, stcb,
     				    ctl,
     				    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
    -				/*
    -				 * EY this is the chunk that should be
    -				 * tagged nr gapped calculate the gap and
    -				 * such then tag this TSN nr
    -				 * chk->rec.data.TSN_seq
    -				 */
    -				if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -				    asoc->peer_supports_nr_sack) {
    -					SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn);
    -					if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) ||
    -					    (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) {
    -						/*
    -						 * EY These should never
    -						 * happen, explained before
    -						 */
    -					} else {
    -						SCTP_TCB_LOCK_ASSERT(stcb);
    -						SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap);
    -						SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc);
    -						if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map,
    -						    MAX_TSN))
    -							asoc->highest_tsn_inside_nr_map = nr_tsn;
    -					}
    -					if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, nr_gap))
    -						/*
    -						 * printf("In
    -						 * sctp_kick_prsctp_reorder_q
    -						 * ueue(8): Something wrong,
    -						 * the TSN to be tagged"
    -						 * "\nas NR is not even in
    -						 * the mapping_array, or map
    -						 * and nr_map are
    -						 * inconsistent");
    -						 */
    -						/*
    -						 * EY - not %100 sure about
    -						 * the lock thing, don't
    -						 * think its required
    -						 */
    -						/*
    -						 * SCTP_TCB_LOCK_ASSERT(stcb)
    -						 * ;
    -						 */
    -					{
    -						/*
    -						 * printf("\nCalculating an
    -						 * nr_gap!!\nmapping_array_si
    -						 * ze = %d
    -						 * nr_mapping_array_size =
    -						 * %d" "\nmapping_array_base
    -						 * = %d
    -						 * nr_mapping_array_base =
    -						 * %d\nhighest_tsn_inside_map
    -						 *  = %d"
    -						 * "highest_tsn_inside_nr_map
    -						 *  = %d\nTSN = %d nr_gap =
    -						 * %d",asoc->mapping_array_si
    -						 * ze,
    -						 * asoc->nr_mapping_array_siz
    -						 * e,
    -						 * asoc->mapping_array_base_t
    -						 * sn,
    -						 * asoc->nr_mapping_array_bas
    -						 * e_tsn,
    -						 * asoc->highest_tsn_inside_m
    -						 * ap,
    -						 * asoc->highest_tsn_inside_n
    -						 * r_map,tsn,nr_gap);
    -						 */
    -					}
    -				}
    +				sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
    +
     			}
     			tt = strmin->last_sequence_delivered + 1;
     		} else {
    @@ -6096,25 +5647,19 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
     	if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_map,
     	    MAX_TSN)) {
     		asoc->highest_tsn_inside_map = new_cum_tsn;
    -		/* EY nr_mapping_array version of the above */
    -		/*
    -		 * if(SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    -		 * asoc->peer_supports_nr_sack)
    -		 */
    +
    +	}
    +	if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_nr_map,
    +	    MAX_TSN)) {
     		asoc->highest_tsn_inside_nr_map = new_cum_tsn;
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    -			sctp_log_map(0, 0, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
    -		}
     	}
     	/*
     	 * now we know the new TSN is more advanced, let's find the actual
     	 * gap
     	 */
    -	SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->mapping_array_base_tsn);
    +	SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->nr_mapping_array_base_tsn);
    +	asoc->cumulative_tsn = new_cum_tsn;
     	if (gap >= m_size) {
    -		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    -			sctp_log_map(0, 0, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
    -		}
     		if ((long)gap > sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv)) {
     			struct mbuf *oper;
     
    @@ -6147,23 +5692,15 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
     			return;
     		}
     		SCTP_STAT_INCR(sctps_fwdtsn_map_over);
    +
     		memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
    -		cumack_set_flag = 1;
     		asoc->mapping_array_base_tsn = new_cum_tsn + 1;
    -		asoc->cumulative_tsn = asoc->highest_tsn_inside_map = new_cum_tsn;
    -		/* EY - nr_sack: nr_mapping_array version of the above */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) {
    -			memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
    -			asoc->nr_mapping_array_base_tsn = new_cum_tsn + 1;
    -			asoc->highest_tsn_inside_nr_map = new_cum_tsn;
    -			if (asoc->nr_mapping_array_size != asoc->mapping_array_size) {
    -				/*
    -				 * printf("IN sctp_handle_forward_tsn:
    -				 * Something is wrong the size of" "map and
    -				 * nr_map should be equal!")
    -				 */ ;
    -			}
    -		}
    +		asoc->highest_tsn_inside_map = new_cum_tsn;
    +
    +		memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
    +		asoc->nr_mapping_array_base_tsn = new_cum_tsn + 1;
    +		asoc->highest_tsn_inside_nr_map = new_cum_tsn;
    +
     		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
     			sctp_log_map(0, 3, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
     		}
    @@ -6171,12 +5708,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
     	} else {
     		SCTP_TCB_LOCK_ASSERT(stcb);
     		for (i = 0; i <= gap; i++) {
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack
    -			    && SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
    -				SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
    -			} else {
    -				SCTP_SET_TSN_PRESENT(asoc->mapping_array, i);
    -			}
    +			SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, i);
    +			SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
     		}
     		/*
     		 * Now after marking all, slide thing forward but no sack
    diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
    index ef187377b95..07518e42cf9 100644
    --- a/sys/netinet/sctp_input.c
    +++ b/sys/netinet/sctp_input.c
    @@ -1860,9 +1860,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
     			memset(asoc->mapping_array, 0,
     			    asoc->mapping_array_size);
     		}
    -		/* EY 05/13/08 - nr_sack version of the above if statement */
    -		if (asoc->nr_mapping_array && SCTP_BASE_SYSCTL(sctp_nr_sack_on_off)
    -		    && asoc->peer_supports_nr_sack) {
    +		if (asoc->nr_mapping_array) {
     			memset(asoc->nr_mapping_array, 0,
     			    asoc->nr_mapping_array_size);
     		}
    @@ -3515,16 +3513,10 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
     					stcb->asoc.mapping_array_base_tsn = ntohl(resp->senders_next_tsn);
     					memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
     
    -					/*
    -					 * EY 05/13/08 - nr_sack: to keep
    -					 * nr_mapping array be consistent
    -					 * with mapping_array
    -					 */
    -					if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack) {
    -						stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
    -						stcb->asoc.nr_mapping_array_base_tsn = stcb->asoc.mapping_array_base_tsn;
    -						memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
    -					}
    +					stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
    +					stcb->asoc.nr_mapping_array_base_tsn = stcb->asoc.mapping_array_base_tsn;
    +					memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
    +
     					stcb->asoc.sending_seq = ntohl(resp->receivers_next_tsn);
     					stcb->asoc.last_acked_seq = stcb->asoc.cumulative_tsn;
     
    @@ -3631,15 +3623,9 @@ sctp_handle_str_reset_request_tsn(struct sctp_tcb *stcb,
     		stcb->asoc.tsn_last_delivered = stcb->asoc.cumulative_tsn = stcb->asoc.highest_tsn_inside_map;
     		stcb->asoc.mapping_array_base_tsn = stcb->asoc.highest_tsn_inside_map + 1;
     		memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
    -		/*
    -		 * EY 05/13/08 -nr_sack: to keep nr_mapping array consistent
    -		 * with mapping array
    -		 */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack) {
    -			stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
    -			stcb->asoc.nr_mapping_array_base_tsn = stcb->asoc.highest_tsn_inside_map + 1;
    -			memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
    -		}
    +		stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
    +		stcb->asoc.nr_mapping_array_base_tsn = stcb->asoc.highest_tsn_inside_map + 1;
    +		memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
     		atomic_add_int(&stcb->asoc.sending_seq, 1);
     		/* save off historical data for retrans */
     		stcb->asoc.last_sending_seq[1] = stcb->asoc.last_sending_seq[0];
    diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
    index be4c3a8633f..b3e5781ff52 100644
    --- a/sys/netinet/sctp_output.c
    +++ b/sys/netinet/sctp_output.c
    @@ -7871,19 +7871,8 @@ again_one_more_time:
     						pf_hbflag = 1;
     					}
     					/* remove these chunks at the end */
    -					if (chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) {
    -						/* turn off the timer */
    -						if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
    -							sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
    -							    inp, stcb, net, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_1);
    -						}
    -					}
    -					/*
    -					 * EY -Nr-sack version of the above
    -					 * if statement
    -					 */
    -					if ((SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) &&
    -					    (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK)) {	/* EY !?! */
    +					if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) ||
    +					    (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK)) {
     						/* turn off the timer */
     						if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
     							sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
    @@ -9885,6 +9874,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
     	unsigned int num_gap_blocks = 0, space;
     	int num_dups = 0;
     	int space_req;
    +	uint32_t highest_tsn;
     
     	a_chk = NULL;
     	asoc = &stcb->asoc;
    @@ -9970,7 +9960,12 @@ sctp_send_sack(struct sctp_tcb *stcb)
     	if (a_chk->whoTo) {
     		atomic_add_int(&a_chk->whoTo->ref_count, 1);
     	}
    -	if (asoc->highest_tsn_inside_map == asoc->cumulative_tsn) {
    +	if (compare_with_wrap(asoc->highest_tsn_inside_map, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    +		highest_tsn = asoc->highest_tsn_inside_map;
    +	} else {
    +		highest_tsn = asoc->highest_tsn_inside_nr_map;
    +	}
    +	if (highest_tsn == asoc->cumulative_tsn) {
     		/* no gaps */
     		space_req = sizeof(struct sctp_sack_chunk);
     	} else {
    @@ -10043,10 +10038,10 @@ sctp_send_sack(struct sctp_tcb *stcb)
     
     	gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)sack + sizeof(struct sctp_sack_chunk));
     
    -	if (asoc->highest_tsn_inside_map > asoc->mapping_array_base_tsn)
    -		siz = (((asoc->highest_tsn_inside_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
    +	if (highest_tsn > asoc->mapping_array_base_tsn)
    +		siz = (((highest_tsn - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
     	else
    -		siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_map + 7) / 8;
    +		siz = (((MAX_TSN - highest_tsn) + 1) + highest_tsn + 7) / 8;
     
     	if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
     		offset = 1;
    @@ -10063,10 +10058,10 @@ sctp_send_sack(struct sctp_tcb *stcb)
     		 */
     		jstart = 1;
     	}
    -	if (compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN)) {
    +	if (compare_with_wrap(highest_tsn, asoc->cumulative_tsn, MAX_TSN)) {
     		/* we have a gap .. maybe */
     		for (i = 0; i < siz; i++) {
    -			selector = &sack_array[asoc->mapping_array[i]];
    +			selector = &sack_array[(asoc->mapping_array[i] | asoc->nr_mapping_array[i])];
     			if (mergeable && selector->right_edge) {
     				/*
     				 * Backup, left and right edges were ok to
    @@ -10120,8 +10115,6 @@ sctp_send_sack(struct sctp_tcb *stcb)
     			 */
     			int abort_flag = 0;
     
    -			asoc->cumulative_tsn = asoc->highest_tsn_inside_map;
    -			sack->sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
     			sctp_sack_check(stcb, 0, 0, &abort_flag);
     		}
     	}
    @@ -10180,13 +10173,13 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     	int mergeable = 0;
     	int offset;
     	caddr_t limit;
    -	uint32_t *dup;
    +	uint32_t *dup, highest_tsn;
     	int limit_reached = 0;
    +	int seen_non_zero = 0;
     	unsigned int i, jstart, siz, j;
     	unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
     	int num_dups = 0;
     	int space_req;
    -	unsigned int reserved = 0;
     
     	a_chk = NULL;
     	asoc = &stcb->asoc;
    @@ -10272,7 +10265,12 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     	if (a_chk->whoTo) {
     		atomic_add_int(&a_chk->whoTo->ref_count, 1);
     	}
    -	if (asoc->highest_tsn_inside_map == asoc->cumulative_tsn) {
    +	if (compare_with_wrap(asoc->highest_tsn_inside_map, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    +		highest_tsn = asoc->highest_tsn_inside_map;
    +	} else {
    +		highest_tsn = asoc->highest_tsn_inside_nr_map;
    +	}
    +	if (highest_tsn == asoc->cumulative_tsn) {
     		/* no gaps */
     		space_req = sizeof(struct sctp_nr_sack_chunk);
     	} else {
    @@ -10371,6 +10369,7 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     	if (compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN)) {
     		/* we have a gap .. maybe */
     		for (i = 0; i < siz; i++) {
    +			seen_non_zero = 1;
     			selector = &sack_array[asoc->mapping_array[i]];
     			if (mergeable && selector->right_edge) {
     				/*
    @@ -10418,22 +10417,8 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     			jstart = 0;
     			offset += 8;
     		}
    -		if (num_gap_blocks == 0) {
    -			/*
    -			 * slide not yet happened, and somehow we got called
    -			 * to send a sack. Cumack needs to move up.
    -			 */
    -			int abort_flag = 0;
    -
    -			asoc->cumulative_tsn = asoc->highest_tsn_inside_map;
    -			nr_sack->nr_sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
    -			sctp_sack_check(stcb, 0, 0, &abort_flag);
    -		}
     	}
    -	/*---------------------------------------------------------filling the nr_gap_ack blocks----------------------------------------------------*/
    -
    -	/* EY - there will be gaps + nr_gaps if draining is possible */
    -	if ((SCTP_BASE_SYSCTL(sctp_do_drain)) && (limit_reached == 0)) {
    +	if (limit_reached == 0) {
     
     		mergeable = 0;
     
    @@ -10510,9 +10495,6 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     			}
     		}
     	}
    -	/*---------------------------------------------End of---filling the nr_gap_ack blocks----------------------------------------------------*/
    -
    -	/* now we must add any dups we are going to report. */
     	if ((limit_reached == 0) && (asoc->numduptsns)) {
     		dup = (uint32_t *) gap_descriptor;
     		for (i = 0; i < asoc->numduptsns; i++) {
    @@ -10530,10 +10512,6 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     	 * now that the chunk is prepared queue it to the control chunk
     	 * queue.
     	 */
    -	if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
    -		num_nr_gap_blocks = num_gap_blocks;
    -		num_gap_blocks = 0;
    -	}
     	a_chk->send_size = sizeof(struct sctp_nr_sack_chunk) +
     	    (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
     	    num_dups * sizeof(int32_t);
    @@ -10542,7 +10520,7 @@ sctp_send_nr_sack(struct sctp_tcb *stcb)
     	nr_sack->nr_sack.num_gap_ack_blks = htons(num_gap_blocks);
     	nr_sack->nr_sack.num_nr_gap_ack_blks = htons(num_nr_gap_blocks);
     	nr_sack->nr_sack.num_dup_tsns = htons(num_dups);
    -	nr_sack->nr_sack.reserved = htons(reserved);
    +	nr_sack->nr_sack.reserved = 0;
     	nr_sack->ch.chunk_length = htons(a_chk->send_size);
     	TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next);
     	asoc->ctrl_queue_cnt++;
    diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
    index c03b9d0e245..e9f5aecb998 100644
    --- a/sys/netinet/sctputil.c
    +++ b/sys/netinet/sctputil.c
    @@ -1175,7 +1175,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
     	asoc->discontinuity_time = asoc->start_time;
     	/*
     	 * sa_ignore MEMLEAK {memory is put in the assoc mapping array and
    -	 * freed later whe the association is freed.
    +	 * freed later when the association is freed.
     	 */
     	return (0);
     }
    @@ -1183,7 +1183,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
     void
     sctp_print_mapping_array(struct sctp_association *asoc)
     {
    -	int i;
    +	int i, limit;
     
     	printf("Mapping size:%d baseTSN:%8.8x cumAck:%8.8x highestTSN:%8.8x\n",
     	    asoc->mapping_array_size,
    @@ -1191,9 +1191,39 @@ sctp_print_mapping_array(struct sctp_association *asoc)
     	    asoc->cumulative_tsn,
     	    asoc->highest_tsn_inside_map
     	    );
    -	for (i = 0; i < asoc->mapping_array_size; i++) {
    -		printf("%8.8x ", asoc->mapping_array[i]);
    -		if (((i + 1) % 8) == 0)
    +	limit = asoc->mapping_array_size;
    +	for (i = asoc->mapping_array_size; i >= 0; i--) {
    +		if (asoc->mapping_array[i]) {
    +			limit = i;
    +			break;
    +		}
    +	}
    +	if (limit == 0)
    +		limit = 1;
    +	for (i = 0; i < limit; i++) {
    +		printf("%2.2x ", asoc->mapping_array[i]);
    +		if (((i + 1) % 16) == 0)
    +			printf("\n");
    +	}
    +	printf("\n");
    +	printf("NR Mapping size:%d baseTSN:%8.8x highestTSN:%8.8x\n",
    +	    asoc->nr_mapping_array_size,
    +	    asoc->nr_mapping_array_base_tsn,
    +	    asoc->highest_tsn_inside_nr_map
    +	    );
    +	limit = asoc->nr_mapping_array_size;
    +	for (i = asoc->nr_mapping_array_size; i >= 0; i--) {
    +		if (asoc->nr_mapping_array[i]) {
    +			limit = i;
    +			break;
    +		}
    +	}
    +	if (limit == 0)
    +		limit = 1;
    +
    +	for (i = 0; i < limit; i++) {
    +		printf("%2.2x ", asoc->nr_mapping_array[i]);
    +		if (((i + 1) % 16) == 0)
     			printf("\n");
     	}
     	printf("\n");
    
    From 469ff227977cf4b8fb521b71f2a7e7627008d314 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:11:45 +0000
    Subject: [PATCH 1994/2592] MFC of 205628
    
    Out goes the nr_mapping_array expand.
    ---
     sys/netinet/sctputil.h | 2 --
     1 file changed, 2 deletions(-)
    
    diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
    index 8d663abe2ca..8a6ee6fb213 100644
    --- a/sys/netinet/sctputil.h
    +++ b/sys/netinet/sctputil.h
    @@ -169,8 +169,6 @@ sctp_report_all_outbound(struct sctp_tcb *, int, int
     
     int sctp_expand_mapping_array(struct sctp_association *, uint32_t);
     
    -/* EY nr_sack version of the above method, expands nr_mapping_array */
    -int sctp_expand_nr_mapping_array(struct sctp_association *, uint32_t);
     void 
     sctp_abort_notification(struct sctp_tcb *, int, int
     #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
    
    From 07072810f01ebe895603e9c204794f4a7054cee3 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:13:52 +0000
    Subject: [PATCH 1995/2592] MFC of 205629
    
    Adds the option of seperating out the sctp stats per
    processor. This will be refined further and is definetly
    exploratory (which is why its an option) i.e. making it
    allocate the actual number of processors is coming ;-D.
    ---
     sys/conf/options          |   1 +
     sys/netinet/sctp_pcb.c    |   5 ++
     sys/netinet/sctp_pcb.h    |   4 +
     sys/netinet/sctp_sysctl.c | 160 +++++++++++++++++++++++++++++++++++++-
     sys/netinet/sctp_uio.h    |   6 +-
     5 files changed, 174 insertions(+), 2 deletions(-)
    
    diff --git a/sys/conf/options b/sys/conf/options
    index 7f5fd051b2c..204d5607a91 100644
    --- a/sys/conf/options
    +++ b/sys/conf/options
    @@ -435,6 +435,7 @@ SCTP_MBCNT_LOGGING	opt_sctp.h # Log to KTR mbcnt activity
     SCTP_PACKET_LOGGING	opt_sctp.h # Log to a packet buffer last N packets
     SCTP_LTRACE_CHUNKS	opt_sctp.h # Log to KTR chunks processed
     SCTP_LTRACE_ERRORS	opt_sctp.h # Log to KTR error returns.
    +SCTP_USE_PERCPU_STAT    opt_sctp.h # Use per cpu stats.
     #
     #
     #
    diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
    index 73e7991c659..fa188249a96 100644
    --- a/sys/netinet/sctp_pcb.c
    +++ b/sys/netinet/sctp_pcb.c
    @@ -5425,8 +5425,13 @@ sctp_pcb_init()
     	bzero(&SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
     #endif
     	(void)SCTP_GETTIME_TIMEVAL(&tv);
    +#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
    +	SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_sec = (uint32_t) tv.tv_sec;
    +	SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_usec = (uint32_t) tv.tv_usec;
    +#else
     	SCTP_BASE_STAT(sctps_discontinuitytime).tv_sec = (uint32_t) tv.tv_sec;
     	SCTP_BASE_STAT(sctps_discontinuitytime).tv_usec = (uint32_t) tv.tv_usec;
    +#endif
     	/* init the empty list of (All) Endpoints */
     	LIST_INIT(&SCTP_BASE_INFO(listhead));
     
    diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
    index d9e1db6dc05..bf14175cac3 100644
    --- a/sys/netinet/sctp_pcb.h
    +++ b/sys/netinet/sctp_pcb.h
    @@ -246,7 +246,11 @@ struct sctp_base_info {
     	 * All static structures that anchor the system must be here.
     	 */
     	struct sctp_epinfo sctppcbinfo;
    +#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
    +	struct sctpstat sctpstat[MAXCPU];
    +#else
     	struct sctpstat sctpstat;
    +#endif
     	struct sctp_sysctl sctpsysctl;
     	uint8_t first_time;
     	char sctp_pcb_initialized;
    diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
    index b4023c68213..c9967eae065 100644
    --- a/sys/netinet/sctp_sysctl.c
    +++ b/sys/netinet/sctp_sysctl.c
    @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     
     /*
      * sysctl tunable variables
    @@ -627,7 +628,158 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
     	return (error);
     }
     
    +#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
    +static int
    +sysctl_stat_get(SYSCTL_HANDLER_ARGS)
    +{
    +	int cpu, error;
    +	struct sctpstat sb, *sarry;
     
    +	memset(&sb, 0, sizeof(sb));
    +	for (cpu = 0; cpu < mp_ncpus; cpu++) {
    +		sarry = &SCTP_BASE_STATS[cpu];
    +		if (sarry->sctps_discontinuitytime.tv_sec > sb.sctps_discontinuitytime.tv_sec) {
    +			sb.sctps_discontinuitytime.tv_sec = sarry->sctps_discontinuitytime.tv_sec;
    +			sb.sctps_discontinuitytime.tv_usec = sarry->sctps_discontinuitytime.tv_usec;
    +		}
    +		sb.sctps_currestab += sarry->sctps_currestab;
    +		sb.sctps_activeestab += sarry->sctps_activeestab;
    +		sb.sctps_restartestab += sarry->sctps_restartestab;
    +		sb.sctps_collisionestab += sarry->sctps_collisionestab;
    +		sb.sctps_passiveestab += sarry->sctps_passiveestab;
    +		sb.sctps_aborted += sarry->sctps_aborted;
    +		sb.sctps_shutdown += sarry->sctps_shutdown;
    +		sb.sctps_outoftheblue += sarry->sctps_outoftheblue;
    +		sb.sctps_checksumerrors += sarry->sctps_checksumerrors;
    +		sb.sctps_outcontrolchunks += sarry->sctps_outcontrolchunks;
    +		sb.sctps_outorderchunks += sarry->sctps_outorderchunks;
    +		sb.sctps_outunorderchunks += sarry->sctps_outunorderchunks;
    +		sb.sctps_incontrolchunks += sarry->sctps_incontrolchunks;
    +		sb.sctps_inorderchunks += sarry->sctps_inorderchunks;
    +		sb.sctps_inunorderchunks += sarry->sctps_inunorderchunks;
    +		sb.sctps_fragusrmsgs += sarry->sctps_fragusrmsgs;
    +		sb.sctps_reasmusrmsgs += sarry->sctps_reasmusrmsgs;
    +		sb.sctps_outpackets += sarry->sctps_outpackets;
    +		sb.sctps_inpackets += sarry->sctps_inpackets;
    +		sb.sctps_recvpackets += sarry->sctps_recvpackets;
    +		sb.sctps_recvdatagrams += sarry->sctps_recvdatagrams;
    +		sb.sctps_recvpktwithdata += sarry->sctps_recvpktwithdata;
    +		sb.sctps_recvsacks += sarry->sctps_recvsacks;
    +		sb.sctps_recvdata += sarry->sctps_recvdata;
    +		sb.sctps_recvdupdata += sarry->sctps_recvdupdata;
    +		sb.sctps_recvheartbeat += sarry->sctps_recvheartbeat;
    +		sb.sctps_recvheartbeatack += sarry->sctps_recvheartbeatack;
    +		sb.sctps_recvecne += sarry->sctps_recvecne;
    +		sb.sctps_recvauth += sarry->sctps_recvauth;
    +		sb.sctps_recvauthmissing += sarry->sctps_recvauthmissing;
    +		sb.sctps_recvivalhmacid += sarry->sctps_recvivalhmacid;
    +		sb.sctps_recvivalkeyid += sarry->sctps_recvivalkeyid;
    +		sb.sctps_recvauthfailed += sarry->sctps_recvauthfailed;
    +		sb.sctps_recvexpress += sarry->sctps_recvexpress;
    +		sb.sctps_recvexpressm += sarry->sctps_recvexpressm;
    +		sb.sctps_recvnocrc += sarry->sctps_recvnocrc;
    +		sb.sctps_recvswcrc += sarry->sctps_recvswcrc;
    +		sb.sctps_recvhwcrc += sarry->sctps_recvhwcrc;
    +		sb.sctps_sendpackets += sarry->sctps_sendpackets;
    +		sb.sctps_sendsacks += sarry->sctps_sendsacks;
    +		sb.sctps_senddata += sarry->sctps_senddata;
    +		sb.sctps_sendretransdata += sarry->sctps_sendretransdata;
    +		sb.sctps_sendfastretrans += sarry->sctps_sendfastretrans;
    +		sb.sctps_sendmultfastretrans += sarry->sctps_sendmultfastretrans;
    +		sb.sctps_sendheartbeat += sarry->sctps_sendheartbeat;
    +		sb.sctps_sendecne += sarry->sctps_sendecne;
    +		sb.sctps_sendauth += sarry->sctps_sendauth;
    +		sb.sctps_senderrors += sarry->sctps_senderrors;
    +		sb.sctps_sendnocrc += sarry->sctps_sendnocrc;
    +		sb.sctps_sendswcrc += sarry->sctps_sendswcrc;
    +		sb.sctps_sendhwcrc += sarry->sctps_sendhwcrc;
    +		sb.sctps_pdrpfmbox += sarry->sctps_pdrpfmbox;
    +		sb.sctps_pdrpfehos += sarry->sctps_pdrpfehos;
    +		sb.sctps_pdrpmbda += sarry->sctps_pdrpmbda;
    +		sb.sctps_pdrpmbct += sarry->sctps_pdrpmbct;
    +		sb.sctps_pdrpbwrpt += sarry->sctps_pdrpbwrpt;
    +		sb.sctps_pdrpcrupt += sarry->sctps_pdrpcrupt;
    +		sb.sctps_pdrpnedat += sarry->sctps_pdrpnedat;
    +		sb.sctps_pdrppdbrk += sarry->sctps_pdrppdbrk;
    +		sb.sctps_pdrptsnnf += sarry->sctps_pdrptsnnf;
    +		sb.sctps_pdrpdnfnd += sarry->sctps_pdrpdnfnd;
    +		sb.sctps_pdrpdiwnp += sarry->sctps_pdrpdiwnp;
    +		sb.sctps_pdrpdizrw += sarry->sctps_pdrpdizrw;
    +		sb.sctps_pdrpbadd += sarry->sctps_pdrpbadd;
    +		sb.sctps_pdrpmark += sarry->sctps_pdrpmark;
    +		sb.sctps_timoiterator += sarry->sctps_timoiterator;
    +		sb.sctps_timodata += sarry->sctps_timodata;
    +		sb.sctps_timowindowprobe += sarry->sctps_timowindowprobe;
    +		sb.sctps_timoinit += sarry->sctps_timoinit;
    +		sb.sctps_timosack += sarry->sctps_timosack;
    +		sb.sctps_timoshutdown += sarry->sctps_timoshutdown;
    +		sb.sctps_timoheartbeat += sarry->sctps_timoheartbeat;
    +		sb.sctps_timocookie += sarry->sctps_timocookie;
    +		sb.sctps_timosecret += sarry->sctps_timosecret;
    +		sb.sctps_timopathmtu += sarry->sctps_timopathmtu;
    +		sb.sctps_timoshutdownack += sarry->sctps_timoshutdownack;
    +		sb.sctps_timoshutdownguard += sarry->sctps_timoshutdownguard;
    +		sb.sctps_timostrmrst += sarry->sctps_timostrmrst;
    +		sb.sctps_timoearlyfr += sarry->sctps_timoearlyfr;
    +		sb.sctps_timoasconf += sarry->sctps_timoasconf;
    +		sb.sctps_timodelprim += sarry->sctps_timodelprim;
    +		sb.sctps_timoautoclose += sarry->sctps_timoautoclose;
    +		sb.sctps_timoassockill += sarry->sctps_timoassockill;
    +		sb.sctps_timoinpkill += sarry->sctps_timoinpkill;
    +		sb.sctps_earlyfrstart += sarry->sctps_earlyfrstart;
    +		sb.sctps_earlyfrstop += sarry->sctps_earlyfrstop;
    +		sb.sctps_earlyfrmrkretrans += sarry->sctps_earlyfrmrkretrans;
    +		sb.sctps_earlyfrstpout += sarry->sctps_earlyfrstpout;
    +		sb.sctps_earlyfrstpidsck1 += sarry->sctps_earlyfrstpidsck1;
    +		sb.sctps_earlyfrstpidsck2 += sarry->sctps_earlyfrstpidsck2;
    +		sb.sctps_earlyfrstpidsck3 += sarry->sctps_earlyfrstpidsck3;
    +		sb.sctps_earlyfrstpidsck4 += sarry->sctps_earlyfrstpidsck4;
    +		sb.sctps_earlyfrstrid += sarry->sctps_earlyfrstrid;
    +		sb.sctps_earlyfrstrout += sarry->sctps_earlyfrstrout;
    +		sb.sctps_earlyfrstrtmr += sarry->sctps_earlyfrstrtmr;
    +		sb.sctps_hdrops += sarry->sctps_hdrops;
    +		sb.sctps_badsum += sarry->sctps_badsum;
    +		sb.sctps_noport += sarry->sctps_noport;
    +		sb.sctps_badvtag += sarry->sctps_badvtag;
    +		sb.sctps_badsid += sarry->sctps_badsid;
    +		sb.sctps_nomem += sarry->sctps_nomem;
    +		sb.sctps_fastretransinrtt += sarry->sctps_fastretransinrtt;
    +		sb.sctps_markedretrans += sarry->sctps_markedretrans;
    +		sb.sctps_naglesent += sarry->sctps_naglesent;
    +		sb.sctps_naglequeued += sarry->sctps_naglequeued;
    +		sb.sctps_maxburstqueued += sarry->sctps_maxburstqueued;
    +		sb.sctps_ifnomemqueued += sarry->sctps_ifnomemqueued;
    +		sb.sctps_windowprobed += sarry->sctps_windowprobed;
    +		sb.sctps_lowlevelerr += sarry->sctps_lowlevelerr;
    +		sb.sctps_lowlevelerrusr += sarry->sctps_lowlevelerrusr;
    +		sb.sctps_datadropchklmt += sarry->sctps_datadropchklmt;
    +		sb.sctps_datadroprwnd += sarry->sctps_datadroprwnd;
    +		sb.sctps_ecnereducedcwnd += sarry->sctps_ecnereducedcwnd;
    +		sb.sctps_vtagexpress += sarry->sctps_vtagexpress;
    +		sb.sctps_vtagbogus += sarry->sctps_vtagbogus;
    +		sb.sctps_primary_randry += sarry->sctps_primary_randry;
    +		sb.sctps_cmt_randry += sarry->sctps_cmt_randry;
    +		sb.sctps_slowpath_sack += sarry->sctps_slowpath_sack;
    +		sb.sctps_wu_sacks_sent += sarry->sctps_wu_sacks_sent;
    +		sb.sctps_sends_with_flags += sarry->sctps_sends_with_flags;
    +		sb.sctps_sends_with_unord += sarry->sctps_sends_with_unord;
    +		sb.sctps_sends_with_eof += sarry->sctps_sends_with_eof;
    +		sb.sctps_sends_with_abort += sarry->sctps_sends_with_abort;
    +		sb.sctps_protocol_drain_calls += sarry->sctps_protocol_drain_calls;
    +		sb.sctps_protocol_drains_done += sarry->sctps_protocol_drains_done;
    +		sb.sctps_read_peeks += sarry->sctps_read_peeks;
    +		sb.sctps_cached_chk += sarry->sctps_cached_chk;
    +		sb.sctps_cached_strmoq += sarry->sctps_cached_strmoq;
    +		sb.sctps_left_abandon += sarry->sctps_left_abandon;
    +		sb.sctps_send_burst_avoid += sarry->sctps_send_burst_avoid;
    +		sb.sctps_send_cwnd_avoid += sarry->sctps_send_cwnd_avoid;
    +		sb.sctps_fwdtsn_map_over += sarry->sctps_fwdtsn_map_over;
    +	}
    +	error = SYSCTL_OUT(req, &sb, sizeof(sb));
    +	return (error);
    +}
    +
    +#endif
     
     #if defined(SCTP_LOCAL_TRACE_BUF)
     static int
    @@ -916,10 +1068,16 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, output_unlocked, CTLTYPE_INT | CTLFLAG_RW,
         &SCTP_BASE_SYSCTL(sctp_output_unlocked), 0, sysctl_sctp_check, "IU",
         SCTPCTL_OUTPUT_UNLOCKED_DESC);
     #endif
    -
    +#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
    +SYSCTL_PROC(_net_inet_sctp, OID_AUTO, stats,
    +    CTLTYPE_STRUCT | CTLFLAG_RD,
    +    0, 0, sysctl_stat_get, "S,sctpstat",
    +    "SCTP statistics (struct sctp_stat)");
    +#else
     SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW,
         &SCTP_BASE_STATS_SYSCTL, sctpstat,
         "SCTP statistics (struct sctp_stat)");
    +#endif
     
     SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD,
         0, 0, sctp_assoclist,
    diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h
    index 19089301411..e3fbc3e6d50 100644
    --- a/sys/netinet/sctp_uio.h
    +++ b/sys/netinet/sctp_uio.h
    @@ -957,9 +957,13 @@ struct sctpstat {
     
     #define SCTP_STAT_INCR(_x) SCTP_STAT_INCR_BY(_x,1)
     #define SCTP_STAT_DECR(_x) SCTP_STAT_DECR_BY(_x,1)
    +#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
    +#define SCTP_STAT_INCR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x += _d)
    +#define SCTP_STAT_DECR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x -= _d)
    +#else
     #define SCTP_STAT_INCR_BY(_x,_d) atomic_add_int(&SCTP_BASE_STAT(_x), _d)
     #define SCTP_STAT_DECR_BY(_x,_d) atomic_subtract_int(&SCTP_BASE_STAT(_x), _d)
    -
    +#endif
     /* The following macros are for handling MIB values, */
     #define SCTP_STAT_INCR_COUNTER32(_x) SCTP_STAT_INCR(_x)
     #define SCTP_STAT_INCR_COUNTER64(_x) SCTP_STAT_INCR(_x)
    
    From 17f2eabb2b2ceaf0562b0758eba4a84900c57623 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:15:46 +0000
    Subject: [PATCH 1996/2592] MFC of 206137
    
    This is Part III of the great IETF hack-a-thon to fix
    the NR-Sack code. (the last one on the cpu options
    was a lull.. i.e MFC 205629).. still 2 more to go.
    ---
     sys/netinet/sctp_asconf.c    |  10 +-
     sys/netinet/sctp_constants.h |  15 +-
     sys/netinet/sctp_indata.c    | 442 +++++++++++-------------
     sys/netinet/sctp_indata.h    |   4 +-
     sys/netinet/sctp_input.c     |  22 +-
     sys/netinet/sctp_output.c    | 637 +++++++++++------------------------
     sys/netinet/sctp_output.h    |   3 -
     sys/netinet/sctp_pcb.c       | 124 +++----
     sys/netinet/sctp_pcb.h       |   2 +-
     sys/netinet/sctp_structs.h   |   3 -
     sys/netinet/sctp_usrreq.c    |   4 +-
     sys/netinet/sctp_var.h       |   6 +-
     sys/netinet/sctputil.c       |  93 ++---
     sys/netinet/sctputil.h       |   2 +-
     sys/netinet6/sctp6_usrreq.c  |   2 +-
     15 files changed, 500 insertions(+), 869 deletions(-)
    
    diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
    index 9513ded3361..f7de414ed1a 100644
    --- a/sys/netinet/sctp_asconf.c
    +++ b/sys/netinet/sctp_asconf.c
    @@ -556,9 +556,9 @@ sctp_process_asconf_set_primary(struct mbuf *m,
     		 * PRIMARY with DELETE IP ADDRESS of the previous primary
     		 * destination, unacknowledged DATA are retransmitted
     		 * immediately to the new primary destination for seamless
    -		 * handover.  If the destination is UNCONFIRMED and marked
    -		 * to REQ_PRIM, The retransmission occur when reception of
    -		 * the HEARTBEAT-ACK.  (See sctp_handle_heartbeat_ack in
    +		 * handover. If the destination is UNCONFIRMED and marked to
    +		 * REQ_PRIM, The retransmission occur when reception of the
    +		 * HEARTBEAT-ACK.  (See sctp_handle_heartbeat_ack in
     		 * sctp_input.c) Also, when change of the primary
     		 * destination, it is better that all subsequent new DATA
     		 * containing already queued DATA are transmitted to the new
    @@ -1166,7 +1166,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
     
     	/*
     	 * If number of local valid addresses is 1, the valid address is
    -	 * probably newly added address.  Several valid addresses in this
    +	 * probably newly added address. Several valid addresses in this
     	 * association.  A source address may not be changed.  Additionally,
     	 * they can be configured on a same interface as "alias" addresses.
     	 * (by micchie)
    @@ -1210,7 +1210,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
     		/*
     		 * Check if the nexthop is corresponding to the new address.
     		 * If the new address is corresponding to the current
    -		 * nexthop, the path will be changed.  If the new address is
    +		 * nexthop, the path will be changed. If the new address is
     		 * NOT corresponding to the current nexthop, the path will
     		 * not be changed.
     		 */
    diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h
    index 4a013d3df11..3d886311a67 100644
    --- a/sys/netinet/sctp_constants.h
    +++ b/sys/netinet/sctp_constants.h
    @@ -544,13 +544,7 @@ __FBSDID("$FreeBSD$");
     #define SCTP_INITIAL_MAPPING_ARRAY  16
     /* how much we grow the mapping array each call */
     #define SCTP_MAPPING_ARRAY_INCR     32
    -/* EY 05/13/08 - nr_sack version of the previous 3 constants */
    -/* Maximum the nr mapping array will  grow to (TSN mapping array) */
    -#define SCTP_NR_MAPPING_ARRAY	512
    -/* size of the inital malloc on the nr mapping array */
    -#define SCTP_INITIAL_NR_MAPPING_ARRAY  16
    -/* how much we grow the nr mapping array each call */
    -#define SCTP_NR_MAPPING_ARRAY_INCR     32
    +
     /*
      * Here we define the timer types used by the implementation as arguments in
      * the set/get timer type calls.
    @@ -933,6 +927,13 @@ __FBSDID("$FreeBSD$");
     #define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 0x01)
     #define SCTP_SET_TSN_PRESENT(arry, gap) (arry[(gap >> 3)] |= (0x01 << ((gap & 0x07))))
     #define SCTP_UNSET_TSN_PRESENT(arry, gap) (arry[(gap >> 3)] &= ((~(0x01 << ((gap & 0x07)))) & 0xff))
    +#define SCTP_CALC_TSN_TO_GAP(gap, tsn, mapping_tsn) do { \
    +	                if (tsn >= mapping_tsn) { \
    +						gap = tsn - mapping_tsn; \
    +					} else { \
    +						gap = (MAX_TSN - mapping_tsn) + tsn + 1; \
    +					} \
    +                  } while(0)
     
     
     #define SCTP_RETRAN_DONE -1
    diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
    index 243d773723d..055b12b68dc 100644
    --- a/sys/netinet/sctp_indata.c
    +++ b/sys/netinet/sctp_indata.c
    @@ -45,13 +45,6 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#define SCTP_CALC_TSN_TO_GAP(gap, tsn, mapping_tsn) do { \
    -	                if (tsn >= mapping_tsn) { \
    -						gap = tsn - mapping_tsn; \
    -					} else { \
    -						gap = (MAX_TSN - mapping_tsn) + tsn + 1; \
    -					} \
    -                  } while(0)
     
     /*
      * NOTES: On the outbound side of things I need to check the sack timer to
    @@ -303,13 +296,13 @@ sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn)
     		return;
     	}
     	SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
    -#ifdef INVARIANTS
     	if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
     		printf("gap:%x tsn:%x\n", gap, tsn);
     		sctp_print_mapping_array(asoc);
    +#ifdef INVARIANTS
     		panic("Things are really messed up now!!");
    -	}
     #endif
    +	}
     	SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
     	SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
     	if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    @@ -317,7 +310,8 @@ sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn)
     	}
     	if (tsn == asoc->highest_tsn_inside_map) {
     		/* We must back down to see what the new highest is */
    -		for (i = tsn - 1; compare_with_wrap(i, asoc->mapping_array_base_tsn, MAX_TSN); i--) {
    +		for (i = tsn - 1; (compare_with_wrap(i, asoc->mapping_array_base_tsn, MAX_TSN) ||
    +		    (i == asoc->mapping_array_base_tsn)); i--) {
     			SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
     			if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
     				asoc->highest_tsn_inside_map = i;
    @@ -411,6 +405,7 @@ abandon:
     				end = 1;
     			else
     				end = 0;
    +			sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
     			sctp_add_to_readq(stcb->sctp_ep,
     			    stcb, control, &stcb->sctp_socket->so_rcv, end,
     			    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
    @@ -420,6 +415,7 @@ abandon:
     				end = 1;
     			else
     				end = 0;
    +			sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
     			if (sctp_append_to_readq(stcb->sctp_ep, stcb,
     			    stcb->asoc.control_pdapi,
     			    chk->data, end, chk->rec.data.TSN_seq,
    @@ -454,7 +450,6 @@ abandon:
     		}
     		/* pull it we did it */
     		TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
    -		sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
     		if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
     			asoc->fragmented_delivery_inprogress = 0;
     			if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 0) {
    @@ -501,11 +496,11 @@ abandon:
     						asoc->size_on_all_streams -= ctl->length;
     						sctp_ucount_decr(asoc->cnt_on_all_streams);
     						strm->last_sequence_delivered++;
    +						sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
     						sctp_add_to_readq(stcb->sctp_ep, stcb,
     						    ctl,
     						    &stcb->sctp_socket->so_rcv, 1,
     						    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
    -						sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
     						ctl = ctlat;
     					} else {
     						break;
    @@ -616,11 +611,11 @@ protocol_error:
     		sctp_ucount_decr(asoc->cnt_on_all_streams);
     		strm->last_sequence_delivered++;
     
    +		sctp_mark_non_revokable(asoc, control->sinfo_tsn);
     		sctp_add_to_readq(stcb->sctp_ep, stcb,
     		    control,
     		    &stcb->sctp_socket->so_rcv, 1,
     		    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
    -		sctp_mark_non_revokable(asoc, control->sinfo_tsn);
     		control = TAILQ_FIRST(&strm->inqueue);
     		while (control != NULL) {
     			/* all delivered */
    @@ -641,13 +636,12 @@ protocol_error:
     					sctp_log_strm_del(control, NULL,
     					    SCTP_STR_LOG_FROM_IMMED_DEL);
     				}
    -				/* EY will be used to calculate nr-gap */
    +				sctp_mark_non_revokable(asoc, control->sinfo_tsn);
     				sctp_add_to_readq(stcb->sctp_ep, stcb,
     				    control,
     				    &stcb->sctp_socket->so_rcv, 1,
     				    SCTP_READ_LOCK_NOT_HELD,
     				    SCTP_SO_NOT_LOCKED);
    -				sctp_mark_non_revokable(asoc, control->sinfo_tsn);
     				control = at;
     				continue;
     			}
    @@ -965,8 +959,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
     					*abort_flag = 1;
     				} else if ((asoc->fragment_flags & SCTP_DATA_UNORDERED) !=
     					    SCTP_DATA_UNORDERED &&
    -					    chk->rec.data.stream_seq !=
    -				    asoc->ssn_of_pdapi) {
    +				    chk->rec.data.stream_seq != asoc->ssn_of_pdapi) {
     					/* Got to be the right STR Seq */
     					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS not same stream seq %d vs %d\n",
     					    chk->rec.data.stream_seq,
    @@ -1623,7 +1616,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     		}
     		SCTP_STAT_INCR(sctps_badsid);
     		SCTP_TCB_LOCK_ASSERT(stcb);
    -
     		SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
     		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
     			asoc->highest_tsn_inside_nr_map = tsn;
    @@ -1787,6 +1779,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     			    SCTP_STR_LOG_FROM_EXPRS_DEL);
     		}
     		control = NULL;
    +
     		SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
     		if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
     			asoc->highest_tsn_inside_nr_map = tsn;
    @@ -1853,10 +1846,6 @@ failed_express_del:
     					need_reasm_check = 1;
     				}
     			}
    -			SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
    -			if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    -				asoc->highest_tsn_inside_nr_map = tsn;
    -			}
     			control = NULL;
     			goto finish_express_del;
     		}
    @@ -2059,10 +2048,10 @@ failed_pdapi_express_del:
     		/* ok, if we reach here we have passed the sanity checks */
     		if (chunk_flags & SCTP_DATA_UNORDERED) {
     			/* queue directly into socket buffer */
    +			sctp_mark_non_revokable(asoc, control->sinfo_tsn);
     			sctp_add_to_readq(stcb->sctp_ep, stcb,
     			    control,
     			    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
    -
     		} else {
     			/*
     			 * Special check for when streams are resetting. We
    @@ -2134,10 +2123,6 @@ failed_pdapi_express_del:
     		}
     	}
     finish_express_del:
    -	if (tsn == (asoc->cumulative_tsn + 1)) {
    -		/* Update cum-ack */
    -		asoc->cumulative_tsn = tsn;
    -	}
     	if (last_chunk) {
     		*m = NULL;
     	}
    @@ -2215,43 +2200,43 @@ finish_express_del:
     }
     
     int8_t sctp_map_lookup_tab[256] = {
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 3,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 4,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 3,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 5,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 3,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 4,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 3,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 6,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 3,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 4,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 3,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 5,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 3,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 4,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 3,
    -	-1, 0, -1, 1, -1, 0, -1, 2,
    -	-1, 0, -1, 1, -1, 0, -1, 7,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 4,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 5,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 4,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 6,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 4,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 5,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 4,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 7,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 4,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 5,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 4,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 6,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 4,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 5,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 4,
    +	0, 1, 0, 2, 0, 1, 0, 3,
    +	0, 1, 0, 2, 0, 1, 0, 8
     };
     
     
     void
    -sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort_flag)
    +sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
     {
     	/*
     	 * Now we also need to check the mapping array in a couple of ways.
    @@ -2259,7 +2244,6 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	 */
     	struct sctp_association *asoc;
     	int at;
    -	int last_all_ones = 0;
     	int slide_from, slide_end, lgap, distance;
     
     	/* EY nr_mapping array variables */
    @@ -2279,19 +2263,16 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	 * offset of the current cum-ack as the starting point.
     	 */
     	at = 0;
    -	for (slide_from = 0; slide_from < stcb->asoc.nr_mapping_array_size; slide_from++) {
    +	for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; slide_from++) {
     		if (asoc->nr_mapping_array[slide_from] == 0xff) {
     			at += 8;
    -			last_all_ones = 1;
     		} else {
     			/* there is a 0 bit */
     			at += sctp_map_lookup_tab[asoc->nr_mapping_array[slide_from]];
    -			last_all_ones = 0;
     			break;
     		}
     	}
    -	asoc->cumulative_tsn = asoc->nr_mapping_array_base_tsn + (at - last_all_ones);
    -	at++;
    +	asoc->cumulative_tsn = asoc->mapping_array_base_tsn + (at - 1);
     
     	if (compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_map, MAX_TSN) &&
     	    compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)
    @@ -2320,18 +2301,22 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     	if ((asoc->cumulative_tsn == highest_tsn) && (at >= 8)) {
     		/* The complete array was completed by a single FR */
     		/* highest becomes the cum-ack */
    -		int clr;
    +		int clr, i;
     
     		/* clear the array */
    -		clr = (at >> 3) + 1;
    +		clr = ((at + 7) >> 3);
     		if (clr > asoc->mapping_array_size) {
     			clr = asoc->mapping_array_size;
     		}
     		memset(asoc->mapping_array, 0, clr);
     		memset(asoc->nr_mapping_array, 0, clr);
    -
    +		for (i = 0; i < asoc->mapping_array_size; i++) {
    +			if ((asoc->mapping_array[i]) || (asoc->nr_mapping_array[i])) {
    +				printf("Error Mapping array's not clean at clear\n");
    +				sctp_print_mapping_array(asoc);
    +			}
    +		}
     		asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
    -		asoc->nr_mapping_array_base_tsn = asoc->cumulative_tsn + 1;
     		asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
     	} else if (at >= 8) {
     		/* we can slide the mapping array down */
    @@ -2393,12 +2378,11 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     				    asoc->nr_mapping_array[slide_from + ii];
     
     			}
    -			for (ii = distance; ii <= slide_end; ii++) {
    +			for (ii = distance; ii <= asoc->mapping_array_size; ii++) {
     				asoc->mapping_array[ii] = 0;
     				asoc->nr_mapping_array[ii] = 0;
     			}
     			asoc->mapping_array_base_tsn += (slide_from << 3);
    -			asoc->nr_mapping_array_base_tsn += (slide_from << 3);
     			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
     				sctp_log_map(asoc->mapping_array_base_tsn,
     				    asoc->cumulative_tsn, asoc->highest_tsn_inside_map,
    @@ -2406,95 +2390,95 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
     			}
     		}
     	}
    +}
    +
    +
    +void
    +sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap, int *abort_flag)
    +{
    +	struct sctp_association *asoc;
    +	uint32_t highest_tsn;
    +
    +	asoc = &stcb->asoc;
    +	if (compare_with_wrap(asoc->highest_tsn_inside_nr_map,
    +	    asoc->highest_tsn_inside_map,
    +	    MAX_TSN)) {
    +		highest_tsn = asoc->highest_tsn_inside_nr_map;
    +	} else {
    +		highest_tsn = asoc->highest_tsn_inside_map;
    +	}
    +
     	/*
     	 * Now we need to see if we need to queue a sack or just start the
     	 * timer (if allowed).
     	 */
    -	if (ok_to_sack) {
    -		if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
    -			/*
    -			 * Ok special case, in SHUTDOWN-SENT case. here we
    -			 * maker sure SACK timer is off and instead send a
    -			 * SHUTDOWN and a SACK
    -			 */
    -			if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
    -				sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
    -				    stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
    -			}
    -			sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
    -			/*
    -			 * EY if nr_sacks used then send an nr-sack , a sack
    -			 * otherwise
    -			 */
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
    -				sctp_send_nr_sack(stcb);
    -			else
    -				sctp_send_sack(stcb);
    -		} else {
    -			int is_a_gap;
    +	if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
    +		/*
    +		 * Ok special case, in SHUTDOWN-SENT case. here we maker
    +		 * sure SACK timer is off and instead send a SHUTDOWN and a
    +		 * SACK
    +		 */
    +		if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
    +			sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
    +			    stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
    +		}
    +		sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
    +		sctp_send_sack(stcb);
    +	} else {
    +		int is_a_gap;
     
    -			/* is there a gap now ? */
    -			is_a_gap = compare_with_wrap(highest_tsn, stcb->asoc.cumulative_tsn, MAX_TSN);
    +		/* is there a gap now ? */
    +		is_a_gap = compare_with_wrap(highest_tsn, stcb->asoc.cumulative_tsn, MAX_TSN);
     
    -			/*
    -			 * CMT DAC algorithm: increase number of packets
    -			 * received since last ack
    -			 */
    -			stcb->asoc.cmt_dac_pkts_rcvd++;
    +		/*
    +		 * CMT DAC algorithm: increase number of packets received
    +		 * since last ack
    +		 */
    +		stcb->asoc.cmt_dac_pkts_rcvd++;
     
    -			if ((stcb->asoc.send_sack == 1) ||	/* We need to send a
    -								 * SACK */
    -			    ((was_a_gap) && (is_a_gap == 0)) ||	/* was a gap, but no
    -								 * longer is one */
    -			    (stcb->asoc.numduptsns) ||	/* we have dup's */
    -			    (is_a_gap) ||	/* is still a gap */
    -			    (stcb->asoc.delayed_ack == 0) ||	/* Delayed sack disabled */
    -			    (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq)	/* hit limit of pkts */
    -			    ) {
    +		if ((stcb->asoc.send_sack == 1) ||	/* We need to send a
    +							 * SACK */
    +		    ((was_a_gap) && (is_a_gap == 0)) ||	/* was a gap, but no
    +							 * longer is one */
    +		    (stcb->asoc.numduptsns) ||	/* we have dup's */
    +		    (is_a_gap) ||	/* is still a gap */
    +		    (stcb->asoc.delayed_ack == 0) ||	/* Delayed sack disabled */
    +		    (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq)	/* hit limit of pkts */
    +		    ) {
     
    -				if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off)) &&
    -				    (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
    -				    (stcb->asoc.send_sack == 0) &&
    -				    (stcb->asoc.numduptsns == 0) &&
    -				    (stcb->asoc.delayed_ack) &&
    -				    (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) {
    +			if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off)) &&
    +			    (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
    +			    (stcb->asoc.send_sack == 0) &&
    +			    (stcb->asoc.numduptsns == 0) &&
    +			    (stcb->asoc.delayed_ack) &&
    +			    (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) {
     
    -					/*
    -					 * CMT DAC algorithm: With CMT,
    -					 * delay acks even in the face of
    -					 * 
    -					 * reordering. Therefore, if acks that
    -					 * do not have to be sent because of
    -					 * the above reasons, will be
    -					 * delayed. That is, acks that would
    -					 * have been sent due to gap reports
    -					 * will be delayed with DAC. Start
    -					 * the delayed ack timer.
    -					 */
    -					sctp_timer_start(SCTP_TIMER_TYPE_RECV,
    -					    stcb->sctp_ep, stcb, NULL);
    -				} else {
    -					/*
    -					 * Ok we must build a SACK since the
    -					 * timer is pending, we got our
    -					 * first packet OR there are gaps or
    -					 * duplicates.
    -					 */
    -					(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
    -					/*
    -					 * EY if nr_sacks used then send an
    -					 * nr-sack , a sack otherwise
    -					 */
    -					if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
    -						sctp_send_nr_sack(stcb);
    -					else
    -						sctp_send_sack(stcb);
    -				}
    +				/*
    +				 * CMT DAC algorithm: With CMT, delay acks
    +				 * even in the face of
    +				 * 
    +				 * reordering. Therefore, if acks that do not
    +				 * have to be sent because of the above
    +				 * reasons, will be delayed. That is, acks
    +				 * that would have been sent due to gap
    +				 * reports will be delayed with DAC. Start
    +				 * the delayed ack timer.
    +				 */
    +				sctp_timer_start(SCTP_TIMER_TYPE_RECV,
    +				    stcb->sctp_ep, stcb, NULL);
     			} else {
    -				if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
    -					sctp_timer_start(SCTP_TIMER_TYPE_RECV,
    -					    stcb->sctp_ep, stcb, NULL);
    -				}
    +				/*
    +				 * Ok we must build a SACK since the timer
    +				 * is pending, we got our first packet OR
    +				 * there are gaps or duplicates.
    +				 */
    +				(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
    +				sctp_send_sack(stcb);
    +			}
    +		} else {
    +			if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
    +				sctp_timer_start(SCTP_TIMER_TYPE_RECV,
    +				    stcb->sctp_ep, stcb, NULL);
     			}
     		}
     	}
    @@ -2834,14 +2818,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
     			if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
     				(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
     			}
    -			/*
    -			 * EY if nr_sacks used then send an nr-sack , a sack
    -			 * otherwise
    -			 */
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
    -				sctp_send_nr_sack(stcb);
    -			else
    -				sctp_send_sack(stcb);
    +			sctp_send_sack(stcb);
     		} else {
     			if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
     				sctp_timer_start(SCTP_TIMER_TYPE_RECV,
    @@ -2849,7 +2826,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
     			}
     		}
     	} else {
    -		sctp_sack_check(stcb, 1, was_a_gap, &abort_flag);
    +		sctp_sack_check(stcb, was_a_gap, &abort_flag);
     	}
     	if (abort_flag)
     		return (2);
    @@ -2867,7 +2844,7 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
     {
     	struct sctp_tmit_chunk *tp1;
     	unsigned int theTSN;
    -	int j, wake_him = 0;
    +	int j, wake_him = 0, circled = 0;
     
     	/* Recover the tp1 we last saw */
     	tp1 = *p_tp1;
    @@ -3045,12 +3022,6 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
     					}
     					/* NR Sack code here */
     					if (nr_sacking) {
    -						if (tp1->sent != SCTP_FORWARD_TSN_SKIP)
    -							tp1->sent = SCTP_DATAGRAM_NR_MARKED;
    -						/*
    -						 * TAILQ_REMOVE(&asoc->sent_q
    -						 * ueue, tp1, sctp_next);
    -						 */
     						if (tp1->data) {
     							/*
     							 * sa_ignore
    @@ -3058,13 +3029,8 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
     							 */
     							sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
     							sctp_m_freem(tp1->data);
    +							tp1->data = NULL;
     						}
    -						tp1->data = NULL;
    -						/* asoc->sent_queue_cnt--; */
    -						/*
    -						 * sctp_free_a_chunk(stcb,
    -						 * tp1);
    -						 */
     						wake_him++;
     					}
     				}
    @@ -3075,11 +3041,16 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
     				break;
     
     			tp1 = TAILQ_NEXT(tp1, sctp_next);
    +			if ((tp1 == NULL) && (circled == 0)) {
    +				circled++;
    +				tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue);
    +			}
     		}		/* end while (tp1) */
    -		/* In case the fragments were not in order we must reset */
     		if (tp1 == NULL) {
    +			circled = 0;
     			tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue);
     		}
    +		/* In case the fragments were not in order we must reset */
     	}			/* end for (j = fragStart */
     	*p_tp1 = tp1;
     	return (wake_him);	/* Return value only used for nr-sack */
    @@ -3158,6 +3129,9 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
     		} else {
     			non_revocable = 1;
     		}
    +		if (i == num_seg) {
    +			tp1 = NULL;
    +		}
     		if (sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, frag_end,
     		    non_revocable, &num_frs, biggest_newly_acked_tsn,
     		    this_sack_lowest_newack, ecn_seg_sums)) {
    @@ -3961,6 +3935,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
     #ifdef INVARIANTS
     			panic("Impossible sack 1");
     #else
    +
     			*abort_now = 1;
     			/* XXX */
     			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
    @@ -4439,50 +4414,6 @@ again:
     	}
     }
     
    -/* EY- nr_sack */
    -/* Identifies the non-renegable tsns that are revoked*/
    -static void
    -sctp_check_for_nr_revoked(struct sctp_tcb *stcb,
    -    struct sctp_association *asoc, uint32_t cumack,
    -    uint32_t biggest_tsn_acked)
    -{
    -	struct sctp_tmit_chunk *tp1;
    -
    -	for (tp1 = TAILQ_FIRST(&asoc->sent_queue); tp1; tp1 = TAILQ_NEXT(tp1, sctp_next)) {
    -		if (compare_with_wrap(tp1->rec.data.TSN_seq, cumack,
    -		    MAX_TSN)) {
    -			/*
    -			 * ok this guy is either ACK or MARKED. If it is
    -			 * ACKED it has been previously acked but not this
    -			 * time i.e. revoked.  If it is MARKED it was ACK'ed
    -			 * again.
    -			 */
    -			if (compare_with_wrap(tp1->rec.data.TSN_seq, biggest_tsn_acked,
    -			    MAX_TSN))
    -				break;
    -
    -
    -			if (tp1->sent == SCTP_DATAGRAM_NR_ACKED) {
    -				/*
    -				 * EY! a non-renegable TSN is revoked, need
    -				 * to abort the association
    -				 */
    -				/*
    -				 * EY TODO: put in the code to abort the
    -				 * assoc.
    -				 */
    -				return;
    -			} else if (tp1->sent == SCTP_DATAGRAM_NR_MARKED) {
    -				/* it has been re-acked in this SACK */
    -				tp1->sent = SCTP_DATAGRAM_NR_ACKED;
    -			}
    -		}
    -		if (tp1->sent == SCTP_DATAGRAM_UNSENT)
    -			break;
    -	}
    -	return;
    -}
    -
     void
     sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
         struct sctp_tcb *stcb, struct sctp_nets *net_from,
    @@ -4588,22 +4519,23 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
     			    sctpchunk_listhead);
     			send_s = tp1->rec.data.TSN_seq + 1;
     		} else {
    +			tp1 = NULL;
     			send_s = asoc->sending_seq;
     		}
     		if (cum_ack == send_s ||
     		    compare_with_wrap(cum_ack, send_s, MAX_TSN)) {
    -#ifndef INVARIANTS
     			struct mbuf *oper;
     
    -#endif
    -#ifdef INVARIANTS
    -	hopeless_peer:
    -			panic("Impossible sack 1");
    -#else
     			/*
     			 * no way, we have not even sent this TSN out yet.
     			 * Peer is hopelessly messed up with us.
     			 */
    +			printf("NEW cum_ack:%x send_s:%x is smaller or equal\n",
    +			    cum_ack, send_s);
    +			if (tp1) {
    +				printf("Got send_s from tsn:%x + 1 of tp1:%p\n",
    +				    tp1->rec.data.TSN_seq, tp1);
    +			}
     	hopeless_peer:
     			*abort_now = 1;
     			/* XXX */
    @@ -4624,7 +4556,6 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
     			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
     			sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_PEER_FAULTY, oper, SCTP_SO_NOT_LOCKED);
     			return;
    -#endif
     		}
     	}
     	/**********************/
    @@ -4844,6 +4775,10 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
     				 * peer is either confused or we are under
     				 * attack. We must abort.
     				 */
    +				printf("Hopeless peer! biggest_tsn_acked:%x largest seq:%x\n",
    +				    biggest_tsn_acked,
    +				    send_s);
    +
     				goto hopeless_peer;
     			}
     		}
    @@ -4991,15 +4926,9 @@ done_with_it:
     				 */
     				if ((tp1->sent == SCTP_DATAGRAM_NR_ACKED) ||
     				    (tp1->sent == SCTP_DATAGRAM_NR_MARKED)) {
    -					/*
    -					 * EY! - TODO: Something previously
    -					 * nr_gapped is reneged, abort the
    -					 * association
    -					 */
    -					return;
    +					continue;
     				}
    -				if ((tp1->sent > SCTP_DATAGRAM_RESEND) &&
    -				    (tp1->sent < SCTP_FORWARD_TSN_SKIP)) {
    +				if (tp1->sent == SCTP_DATAGRAM_ACKED) {
     					tp1->sent = SCTP_DATAGRAM_SENT;
     					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
     						sctp_misc_ints(SCTP_FLIGHT_LOG_UP_REVOKE,
    @@ -5028,15 +4957,11 @@ done_with_it:
     		}
     		asoc->saw_sack_with_frags = 0;
     	}
    -	if (num_seg)
    +	if (num_seg || num_nr_seg)
     		asoc->saw_sack_with_frags = 1;
     	else
     		asoc->saw_sack_with_frags = 0;
     
    -	/* EY! - not sure about if there should be an IF */
    -	if (num_nr_seg > 0)
    -		sctp_check_for_nr_revoked(stcb, asoc, cum_ack, biggest_tsn_acked);
    -
     	/* JRS - Use the congestion control given in the CC module */
     	asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, accum_moved, reneged_all, will_exit_fast_recovery);
     
    @@ -5457,11 +5382,10 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
     			sctp_ucount_decr(asoc->cnt_on_all_streams);
     			/* deliver it to at least the delivery-q */
     			if (stcb->sctp_socket) {
    -				/* EY need the tsn info for calculating nr */
    +				sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
     				sctp_add_to_readq(stcb->sctp_ep, stcb,
     				    ctl,
     				    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
    -				sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
     			}
     		} else {
     			/* no more delivery now. */
    @@ -5486,10 +5410,10 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
     			/* deliver it to at least the delivery-q */
     			strmin->last_sequence_delivered = ctl->sinfo_ssn;
     			if (stcb->sctp_socket) {
    +				sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
     				sctp_add_to_readq(stcb->sctp_ep, stcb,
     				    ctl,
     				    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
    -				sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
     
     			}
     			tt = strmin->last_sequence_delivered + 1;
    @@ -5593,7 +5517,8 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
     
     void
     sctp_handle_forward_tsn(struct sctp_tcb *stcb,
    -    struct sctp_forward_tsn_chunk *fwd, int *abort_flag, struct mbuf *m, int offset)
    +    struct sctp_forward_tsn_chunk *fwd,
    +    int *abort_flag, struct mbuf *m, int offset)
     {
     	/*
     	 * ISSUES that MUST be fixed for ECN! When we are the sender of the
    @@ -5619,8 +5544,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
     	 * report where we are.
     	 */
     	struct sctp_association *asoc;
    -	uint32_t new_cum_tsn, gap;
    -	unsigned int i, fwd_sz, cumack_set_flag, m_size;
    +	uint32_t new_cum_tsn, tsn, gap;
    +	unsigned int i, fwd_sz, cumack_set_flag, m_size, fnd = 0;
     	uint32_t str_seq;
     	struct sctp_stream_in *strm;
     	struct sctp_tmit_chunk *chk, *at;
    @@ -5657,7 +5582,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
     	 * now we know the new TSN is more advanced, let's find the actual
     	 * gap
     	 */
    -	SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->nr_mapping_array_base_tsn);
    +	SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->mapping_array_base_tsn);
     	asoc->cumulative_tsn = new_cum_tsn;
     	if (gap >= m_size) {
     		if ((long)gap > sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv)) {
    @@ -5697,8 +5622,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
     		asoc->mapping_array_base_tsn = new_cum_tsn + 1;
     		asoc->highest_tsn_inside_map = new_cum_tsn;
     
    -		memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
    -		asoc->nr_mapping_array_base_tsn = new_cum_tsn + 1;
    +		memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
     		asoc->highest_tsn_inside_nr_map = new_cum_tsn;
     
     		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    @@ -5710,14 +5634,32 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
     		for (i = 0; i <= gap; i++) {
     			SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, i);
     			SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i);
    +			/* FIX ME add something to set up highest TSN in map */
    +		}
    +		if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    +			asoc->highest_tsn_inside_nr_map = new_cum_tsn;
    +		}
    +		if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_map, MAX_TSN) ||
    +		    new_cum_tsn == asoc->highest_tsn_inside_map) {
    +			/* We must back down to see what the new highest is */
    +			for (tsn = new_cum_tsn; (compare_with_wrap(tsn, asoc->mapping_array_base_tsn, MAX_TSN) ||
    +			    (tsn == asoc->mapping_array_base_tsn)); tsn--) {
    +				SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
    +				if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
    +					asoc->highest_tsn_inside_map = tsn;
    +					fnd = 1;
    +					break;
    +				}
    +			}
    +			if (!fnd) {
    +				asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
    +			}
     		}
     		/*
     		 * Now after marking all, slide thing forward but no sack
     		 * please.
     		 */
    -		sctp_sack_check(stcb, 0, 0, abort_flag);
    -		if (*abort_flag)
    -			return;
    +		sctp_slide_mapping_arrays(stcb);
     	}
     	/*************************************************************/
     	/* 2. Clear up re-assembly queue                             */
    diff --git a/sys/netinet/sctp_indata.h b/sys/netinet/sctp_indata.h
    index b6a8323a5d5..79978a5c992 100644
    --- a/sys/netinet/sctp_indata.h
    +++ b/sys/netinet/sctp_indata.h
    @@ -121,7 +121,9 @@ sctp_process_data(struct mbuf **, int, int *, int, struct sctphdr *,
         struct sctp_inpcb *, struct sctp_tcb *,
         struct sctp_nets *, uint32_t *);
     
    -void sctp_sack_check(struct sctp_tcb *, int, int, int *);
    +void sctp_slide_mapping_arrays(struct sctp_tcb *stcb);
    +
    +void sctp_sack_check(struct sctp_tcb *, int, int *);
     
     #endif
     #endif
    diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
    index 07518e42cf9..a2bb0631b1d 100644
    --- a/sys/netinet/sctp_input.c
    +++ b/sys/netinet/sctp_input.c
    @@ -343,11 +343,6 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb,
     	asoc->str_reset_seq_in = asoc->asconf_seq_in + 1;
     
     	asoc->mapping_array_base_tsn = ntohl(init->initial_tsn);
    -	/*
    -	 * EY 05/13/08 - nr_sack: initialize nr_mapping array's base tsn
    -	 * like above
    -	 */
    -	asoc->nr_mapping_array_base_tsn = ntohl(init->initial_tsn);
     	asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->asconf_seq_in;
     	asoc->last_echo_tsn = asoc->asconf_seq_in;
     	asoc->advanced_peer_ack_point = asoc->last_acked_seq;
    @@ -1862,7 +1857,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
     		}
     		if (asoc->nr_mapping_array) {
     			memset(asoc->nr_mapping_array, 0,
    -			    asoc->nr_mapping_array_size);
    +			    asoc->mapping_array_size);
     		}
     		SCTP_TCB_UNLOCK(stcb);
     		SCTP_INP_INFO_WLOCK();
    @@ -2027,7 +2022,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
     	 * socket is unbound and we must do an implicit bind. Since we are
     	 * getting a cookie, we cannot be unbound.
     	 */
    -	stcb = sctp_aloc_assoc(inp, init_src, 0, &error,
    +	stcb = sctp_aloc_assoc(inp, init_src, &error,
     	    ntohl(initack_cp->init.initiate_tag), vrf_id,
     	    (struct thread *)NULL
     	    );
    @@ -3236,13 +3231,10 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
     		}
     		break;
     	case SCTP_SELECTIVE_ACK:
    +	case SCTP_NR_SELECTIVE_ACK:
     		/* resend the sack */
     		sctp_send_sack(stcb);
     		break;
    -		/* EY for nr_sacks */
    -	case SCTP_NR_SELECTIVE_ACK:
    -		sctp_send_nr_sack(stcb);	/* EY resend the nr-sack */
    -		break;
     	case SCTP_HEARTBEAT_REQUEST:
     		/* resend a demand HB */
     		if ((stcb->asoc.overall_error_count + 3) < stcb->asoc.max_send_times) {
    @@ -3514,8 +3506,7 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
     					memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
     
     					stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
    -					stcb->asoc.nr_mapping_array_base_tsn = stcb->asoc.mapping_array_base_tsn;
    -					memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
    +					memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
     
     					stcb->asoc.sending_seq = ntohl(resp->receivers_next_tsn);
     					stcb->asoc.last_acked_seq = stcb->asoc.cumulative_tsn;
    @@ -3624,8 +3615,7 @@ sctp_handle_str_reset_request_tsn(struct sctp_tcb *stcb,
     		stcb->asoc.mapping_array_base_tsn = stcb->asoc.highest_tsn_inside_map + 1;
     		memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
     		stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
    -		stcb->asoc.nr_mapping_array_base_tsn = stcb->asoc.highest_tsn_inside_map + 1;
    -		memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size);
    +		memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
     		atomic_add_int(&stcb->asoc.sending_seq, 1);
     		/* save off historical data for retrans */
     		stcb->asoc.last_sending_seq[1] = stcb->asoc.last_sending_seq[0];
    @@ -5636,7 +5626,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
     			was_a_gap = 1;
     		}
     		stcb->asoc.send_sack = 1;
    -		sctp_sack_check(stcb, 1, was_a_gap, &abort_flag);
    +		sctp_sack_check(stcb, was_a_gap, &abort_flag);
     		if (abort_flag) {
     			/* Again, we aborted so NO UNLOCK needed */
     			goto out_now;
    diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
    index b3e5781ff52..3f7862bc55b 100644
    --- a/sys/netinet/sctp_output.c
    +++ b/sys/netinet/sctp_output.c
    @@ -9003,6 +9003,11 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
     			/* No, not sent to this net or not ready for rtx */
     			continue;
     		}
    +		if (chk->data == NULL) {
    +			printf("TSN:%x chk->snd_count:%d chk->sent:%d can't retran - no data\n",
    +			    chk->rec.data.TSN_seq, chk->snd_count, chk->sent);
    +			continue;
    +		}
     		if ((SCTP_BASE_SYSCTL(sctp_max_retran_chunk)) &&
     		    (chk->snd_count >= SCTP_BASE_SYSCTL(sctp_max_retran_chunk))) {
     			/* Gak, we have exceeded max unlucky retran, abort! */
    @@ -9426,14 +9431,7 @@ sctp_chunk_output(struct sctp_inpcb *inp,
     	 * running, if so piggy-back the sack.
     	 */
     	if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
    -		/*
    -		 * EY if nr_sacks used then send an nr-sack , a sack
    -		 * otherwise
    -		 */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack)
    -			sctp_send_nr_sack(stcb);
    -		else
    -			sctp_send_sack(stcb);
    +		sctp_send_sack(stcb);
     		(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
     	}
     	while (asoc->sent_queue_retran_cnt) {
    @@ -9856,13 +9854,15 @@ void
     sctp_send_sack(struct sctp_tcb *stcb)
     {
     	/*-
    -	 * Queue up a SACK in the control queue. We must first check to see
    -	 * if a SACK is somehow on the control queue. If so, we will take
    -	 * and and remove the old one.
    +	 * Queue up a SACK or NR-SACK in the control queue.
    +	 * We must first check to see if a SACK or NR-SACK is
    +	 * somehow on the control queue.
    +	 * If so, we will take and and remove the old one.
     	 */
     	struct sctp_association *asoc;
     	struct sctp_tmit_chunk *chk, *a_chk;
     	struct sctp_sack_chunk *sack;
    +	struct sctp_nr_sack_chunk *nr_sack;
     	struct sctp_gap_ack_block *gap_descriptor;
     	struct sack_track *selector;
     	int mergeable = 0;
    @@ -9870,12 +9870,20 @@ sctp_send_sack(struct sctp_tcb *stcb)
     	caddr_t limit;
     	uint32_t *dup;
     	int limit_reached = 0;
    -	unsigned int i, jstart, siz, j;
    -	unsigned int num_gap_blocks = 0, space;
    +	unsigned int i, sel_start, siz, j, starting_index;
    +	unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
     	int num_dups = 0;
     	int space_req;
     	uint32_t highest_tsn;
    +	uint8_t flags;
    +	uint8_t type;
     
    +	if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
    +	    stcb->asoc.peer_supports_nr_sack) {
    +		type = SCTP_NR_SELECTIVE_ACK;
    +	} else {
    +		type = SCTP_SELECTIVE_ACK;
    +	}
     	a_chk = NULL;
     	asoc = &stcb->asoc;
     	SCTP_TCB_LOCK_ASSERT(stcb);
    @@ -9883,9 +9891,10 @@ sctp_send_sack(struct sctp_tcb *stcb)
     		/* Hmm we never received anything */
     		return;
     	}
    +	sctp_slide_mapping_arrays(stcb);
     	sctp_set_rwnd(stcb, asoc);
     	TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
    -		if (chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) {
    +		if (chk->rec.chunk_id.id == type) {
     			/* Hmm, found a sack already on queue, remove it */
     			TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
     			asoc->ctrl_queue_cnt++;
    @@ -9914,8 +9923,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
     			return;
     		}
     		a_chk->copy_by_ref = 0;
    -		/* a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; */
    -		a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK;
    +		a_chk->rec.chunk_id.id = type;
     		a_chk->rec.chunk_id.can_take_data = 1;
     	}
     	/* Clear our pkt counts */
    @@ -9967,7 +9975,11 @@ sctp_send_sack(struct sctp_tcb *stcb)
     	}
     	if (highest_tsn == asoc->cumulative_tsn) {
     		/* no gaps */
    -		space_req = sizeof(struct sctp_sack_chunk);
    +		if (type == SCTP_SELECTIVE_ACK) {
    +			space_req = sizeof(struct sctp_sack_chunk);
    +		} else {
    +			space_req = sizeof(struct sctp_nr_sack_chunk);
    +		}
     	} else {
     		/* gaps get a cluster */
     		space_req = MCLBYTES;
    @@ -10003,15 +10015,13 @@ sctp_send_sack(struct sctp_tcb *stcb)
     	limit = mtod(a_chk->data, caddr_t);
     	limit += space;
     
    -	sack = mtod(a_chk->data, struct sctp_sack_chunk *);
    -	sack->ch.chunk_type = SCTP_SELECTIVE_ACK;
     	/* 0x01 is used by nonce for ecn */
     	if ((SCTP_BASE_SYSCTL(sctp_ecn_enable)) &&
     	    (SCTP_BASE_SYSCTL(sctp_ecn_nonce)) &&
     	    (asoc->peer_supports_ecn_nonce))
    -		sack->ch.chunk_flags = (asoc->receiver_nonce_sum & SCTP_SACK_NONCE_SUM);
    +		flags = (asoc->receiver_nonce_sum & SCTP_SACK_NONCE_SUM);
     	else
    -		sack->ch.chunk_flags = 0;
    +		flags = 0;
     
     	if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
     		/*-
    @@ -10019,7 +10029,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
     		 * received, then set high bit to 1, else 0. Reset
     		 * pkts_rcvd.
     		 */
    -		sack->ch.chunk_flags |= (asoc->cmt_dac_pkts_rcvd << 6);
    +		flags |= (asoc->cmt_dac_pkts_rcvd << 6);
     		asoc->cmt_dac_pkts_rcvd = 0;
     	}
     #ifdef SCTP_ASOCLOG_OF_TSNS
    @@ -10029,39 +10039,81 @@ sctp_send_sack(struct sctp_tcb *stcb)
     		stcb->asoc.cumack_log_atsnt = 0;
     	}
     #endif
    -	sack->sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
    -	sack->sack.a_rwnd = htonl(asoc->my_rwnd);
    -	asoc->my_last_reported_rwnd = asoc->my_rwnd;
    -
     	/* reset the readers interpretation */
     	stcb->freed_by_sorcv_sincelast = 0;
     
    -	gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)sack + sizeof(struct sctp_sack_chunk));
    -
    -	if (highest_tsn > asoc->mapping_array_base_tsn)
    -		siz = (((highest_tsn - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
    -	else
    -		siz = (((MAX_TSN - highest_tsn) + 1) + highest_tsn + 7) / 8;
    +	if (type == SCTP_SELECTIVE_ACK) {
    +		sack = mtod(a_chk->data, struct sctp_sack_chunk *);
    +		nr_sack = NULL;
    +		gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)sack + sizeof(struct sctp_sack_chunk));
    +		if (highest_tsn > asoc->mapping_array_base_tsn) {
    +			siz = (((highest_tsn - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
    +		} else {
    +			siz = (((MAX_TSN - highest_tsn) + 1) + highest_tsn + 7) / 8;
    +		}
    +	} else {
    +		sack = NULL;
    +		nr_sack = mtod(a_chk->data, struct sctp_nr_sack_chunk *);
    +		gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)nr_sack + sizeof(struct sctp_nr_sack_chunk));
    +		if (asoc->highest_tsn_inside_map > asoc->mapping_array_base_tsn) {
    +			siz = (((asoc->highest_tsn_inside_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
    +		} else {
    +			siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_map + 7) / 8;
    +		}
    +	}
     
     	if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
     		offset = 1;
     		/*-
    -		 * cum-ack behind the mapping array, so we start and use all
    -		 * entries.
    +		 * The base TSN is intialized to be the first TSN the peer
    +		 * will send us. If the cum-ack is behind this then when they
    +		 * send us the next in sequence it will mark the base_tsn bit.
    +		 * Thus we need to use the very first selector and the offset
    +		 * is 1. Our table is built for this case.
     		 */
    -		jstart = 0;
    +		starting_index = 0;
    +		sel_start = 0;
     	} else {
    -		offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
     		/*-
    -		 * we skip the first one when the cum-ack is at or above the
    -		 * mapping array base. Note this only works if
    +		 * we skip the first selector  when the cum-ack is at or above the
    +		 * mapping array base. This is because the bits at the base or above
    +		 * are turned on and our first selector in the table assumes they are
    +		 * off. We thus will use the second selector (first is 0). We use
    +		 * the reverse of our macro to fix the offset, in bits, that our
    +		 * table is at. Note that this method assumes that the cum-tsn is
    +		 * within the first bit, i.e. its value is 0-7 which means the
    +		 * result to our offset will be either a 0 - -7. If the cumack
    +		 * is NOT in the first byte (0) (which it should be since we did
    +		 * a mapping array slide above) then we need to calculate the starting
    +		 * index i.e. which byte of the mapping array we should start at. We
    +		 * do this by dividing by 8 and pushing the remainder (mod) into offset.
    +		 * then we multiply the offset to be negative, since we need a negative
    +		 * offset into the selector table.
     		 */
    -		jstart = 1;
    +		SCTP_CALC_TSN_TO_GAP(offset, asoc->cumulative_tsn, asoc->mapping_array_base_tsn);
    +		if (offset > 7) {
    +			starting_index = offset / 8;
    +			offset = offset % 8;
    +			printf("Strange starting index is %d offset:%d (not 0/x)\n",
    +			    starting_index, offset);
    +		} else {
    +			starting_index = 0;
    +		}
    +		/* We need a negative offset in our table */
    +		offset *= -1;
    +		sel_start = 1;
     	}
    -	if (compare_with_wrap(highest_tsn, asoc->cumulative_tsn, MAX_TSN)) {
    +	if (((type == SCTP_SELECTIVE_ACK) &&
    +	    compare_with_wrap(highest_tsn, asoc->cumulative_tsn, MAX_TSN)) ||
    +	    ((type == SCTP_NR_SELECTIVE_ACK) &&
    +	    compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN))) {
     		/* we have a gap .. maybe */
    -		for (i = 0; i < siz; i++) {
    -			selector = &sack_array[(asoc->mapping_array[i] | asoc->nr_mapping_array[i])];
    +		for (i = starting_index; i < siz; i++) {
    +			if (type == SCTP_SELECTIVE_ACK) {
    +				selector = &sack_array[asoc->mapping_array[i] | asoc->nr_mapping_array[i]];
    +			} else {
    +				selector = &sack_array[asoc->mapping_array[i]];
    +			}
     			if (mergeable && selector->right_edge) {
     				/*
     				 * Backup, left and right edges were ok to
    @@ -10073,7 +10125,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
     			if (selector->num_entries == 0)
     				mergeable = 0;
     			else {
    -				for (j = jstart; j < selector->num_entries; j++) {
    +				for (j = sel_start; j < selector->num_entries; j++) {
     					if (mergeable && selector->right_edge) {
     						/*
     						 * do a merge by NOT setting
    @@ -10105,17 +10157,86 @@ sctp_send_sack(struct sctp_tcb *stcb)
     				/* Reached the limit stop */
     				break;
     			}
    -			jstart = 0;
    +			sel_start = 0;
     			offset += 8;
     		}
    -		if (num_gap_blocks == 0) {
    -			/*
    -			 * slide not yet happened, and somehow we got called
    -			 * to send a sack. Cumack needs to move up.
    -			 */
    -			int abort_flag = 0;
    +	}
    +	if ((type == SCTP_NR_SELECTIVE_ACK) &&
    +	    (limit_reached == 0)) {
     
    -			sctp_sack_check(stcb, 0, 0, &abort_flag);
    +		mergeable = 0;
    +
    +		if (asoc->highest_tsn_inside_nr_map > asoc->mapping_array_base_tsn)
    +			siz = (((asoc->highest_tsn_inside_nr_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
    +		else
    +			siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_nr_map + 7) / 8;
    +
    +		if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
    +			offset = 1;
    +			/*-
    +			* cum-ack behind the mapping array, so we start and use all
    +			* entries.
    +			*/
    +			sel_start = 0;
    +		} else {
    +			offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
    +			/*-
    +			* we skip the first one when the cum-ack is at or above the
    +			* mapping array base. Note this only works if
    +			*/
    +			sel_start = 1;
    +		}
    +		if (compare_with_wrap(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn, MAX_TSN)) {
    +			/* we have a gap .. maybe */
    +			for (i = 0; i < siz; i++) {
    +				selector = &sack_array[asoc->nr_mapping_array[i]];
    +				if (mergeable && selector->right_edge) {
    +					/*
    +					 * Backup, left and right edges were
    +					 * ok to merge.
    +					 */
    +					num_nr_gap_blocks--;
    +					gap_descriptor--;
    +				}
    +				if (selector->num_entries == 0)
    +					mergeable = 0;
    +				else {
    +					for (j = sel_start; j < selector->num_entries; j++) {
    +						if (mergeable && selector->right_edge) {
    +							/*
    +							 * do a merge by NOT
    +							 * setting the left
    +							 * side
    +							 */
    +							mergeable = 0;
    +						} else {
    +							/*
    +							 * no merge, set the
    +							 * left side
    +							 */
    +							mergeable = 0;
    +							gap_descriptor->start = htons((selector->gaps[j].start + offset));
    +						}
    +						gap_descriptor->end = htons((selector->gaps[j].end + offset));
    +						num_nr_gap_blocks++;
    +						gap_descriptor++;
    +						if (((caddr_t)gap_descriptor + sizeof(struct sctp_gap_ack_block)) > limit) {
    +							/* no more room */
    +							limit_reached = 1;
    +							break;
    +						}
    +					}
    +					if (selector->left_edge) {
    +						mergeable = 1;
    +					}
    +				}
    +				if (limit_reached) {
    +					/* Reached the limit stop */
    +					break;
    +				}
    +				sel_start = 0;
    +				offset += 8;
    +			}
     		}
     	}
     	/* now we must add any dups we are going to report. */
    @@ -10136,393 +10257,35 @@ sctp_send_sack(struct sctp_tcb *stcb)
     	 * now that the chunk is prepared queue it to the control chunk
     	 * queue.
     	 */
    -	a_chk->send_size = (sizeof(struct sctp_sack_chunk) +
    -	    (num_gap_blocks * sizeof(struct sctp_gap_ack_block)) +
    -	    (num_dups * sizeof(int32_t)));
    -	SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
    -	sack->sack.num_gap_ack_blks = htons(num_gap_blocks);
    -	sack->sack.num_dup_tsns = htons(num_dups);
    -	sack->ch.chunk_length = htons(a_chk->send_size);
    +	if (type == SCTP_SELECTIVE_ACK) {
    +		a_chk->send_size = sizeof(struct sctp_sack_chunk) +
    +		    (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
    +		    num_dups * sizeof(int32_t);
    +		SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
    +		sack->sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
    +		sack->sack.a_rwnd = htonl(asoc->my_rwnd);
    +		sack->sack.num_gap_ack_blks = htons(num_gap_blocks);
    +		sack->sack.num_dup_tsns = htons(num_dups);
    +		sack->ch.chunk_type = type;
    +		sack->ch.chunk_flags = flags;
    +		sack->ch.chunk_length = htons(a_chk->send_size);
    +	} else {
    +		a_chk->send_size = sizeof(struct sctp_nr_sack_chunk) +
    +		    (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
    +		    num_dups * sizeof(int32_t);
    +		SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
    +		nr_sack->nr_sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
    +		nr_sack->nr_sack.a_rwnd = htonl(asoc->my_rwnd);
    +		nr_sack->nr_sack.num_gap_ack_blks = htons(num_gap_blocks);
    +		nr_sack->nr_sack.num_nr_gap_ack_blks = htons(num_nr_gap_blocks);
    +		nr_sack->nr_sack.num_dup_tsns = htons(num_dups);
    +		nr_sack->nr_sack.reserved = 0;
    +		nr_sack->ch.chunk_type = type;
    +		nr_sack->ch.chunk_flags = flags;
    +		nr_sack->ch.chunk_length = htons(a_chk->send_size);
    +	}
     	TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next);
    -	asoc->ctrl_queue_cnt++;
    -	asoc->send_sack = 0;
    -	SCTP_STAT_INCR(sctps_sendsacks);
    -	return;
    -}
    -
    -/* EY - This method will replace sctp_send_sack method if nr_sacks negotiated*/
    -void
    -sctp_send_nr_sack(struct sctp_tcb *stcb)
    -{
    -	/*-
    -	 * Queue up an NR-SACK in the control queue. We must first check to see
    -	 * if an NR-SACK is somehow on the control queue. If so, we will take
    -	 * and and remove the old one.
    -	 */
    -	struct sctp_association *asoc;
    -	struct sctp_tmit_chunk *chk, *a_chk;
    -
    -	struct sctp_nr_sack_chunk *nr_sack;
    -
    -	struct sctp_gap_ack_block *gap_descriptor;
    -
    -	struct sack_track *selector;
    -	struct sack_track *nr_selector;
    -
    -	/* EY do we need nr_mergeable, NO */
    -	int mergeable = 0;
    -	int offset;
    -	caddr_t limit;
    -	uint32_t *dup, highest_tsn;
    -	int limit_reached = 0;
    -	int seen_non_zero = 0;
    -	unsigned int i, jstart, siz, j;
    -	unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
    -	int num_dups = 0;
    -	int space_req;
    -
    -	a_chk = NULL;
    -	asoc = &stcb->asoc;
    -	SCTP_TCB_LOCK_ASSERT(stcb);
    -	if (asoc->last_data_chunk_from == NULL) {
    -		/* Hmm we never received anything */
    -		return;
    -	}
    -	sctp_set_rwnd(stcb, asoc);
    -	TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
    -		if (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK) {
    -			/* Hmm, found a sack already on queue, remove it */
    -			TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
    -			asoc->ctrl_queue_cnt++;
    -			a_chk = chk;
    -			if (a_chk->data) {
    -				sctp_m_freem(a_chk->data);
    -				a_chk->data = NULL;
    -			}
    -			sctp_free_remote_addr(a_chk->whoTo);
    -			a_chk->whoTo = NULL;
    -			break;
    -		}
    -	}
    -	if (a_chk == NULL) {
    -		sctp_alloc_a_chunk(stcb, a_chk);
    -		if (a_chk == NULL) {
    -			/* No memory so we drop the idea, and set a timer */
    -			if (stcb->asoc.delayed_ack) {
    -				sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
    -				    stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5);
    -				sctp_timer_start(SCTP_TIMER_TYPE_RECV,
    -				    stcb->sctp_ep, stcb, NULL);
    -			} else {
    -				stcb->asoc.send_sack = 1;
    -			}
    -			return;
    -		}
    -		a_chk->copy_by_ref = 0;
    -		/* a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; */
    -		a_chk->rec.chunk_id.id = SCTP_NR_SELECTIVE_ACK;
    -		a_chk->rec.chunk_id.can_take_data = 1;
    -	}
    -	/* Clear our pkt counts */
    -	asoc->data_pkts_seen = 0;
    -
    -	a_chk->asoc = asoc;
    -	a_chk->snd_count = 0;
    -	a_chk->send_size = 0;	/* fill in later */
    -	a_chk->sent = SCTP_DATAGRAM_UNSENT;
    -	a_chk->whoTo = NULL;
    -
    -	if ((asoc->numduptsns) ||
    -	    (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)
    -	    ) {
    -		/*-
    -		 * Ok, we have some duplicates or the destination for the
    -		 * sack is unreachable, lets see if we can select an
    -		 * alternate than asoc->last_data_chunk_from
    -		 */
    -		if ((!(asoc->last_data_chunk_from->dest_state &
    -		    SCTP_ADDR_NOT_REACHABLE)) &&
    -		    (asoc->used_alt_onsack > asoc->numnets)) {
    -			/* We used an alt last time, don't this time */
    -			a_chk->whoTo = NULL;
    -		} else {
    -			asoc->used_alt_onsack++;
    -			a_chk->whoTo = sctp_find_alternate_net(stcb, asoc->last_data_chunk_from, 0);
    -		}
    -		if (a_chk->whoTo == NULL) {
    -			/* Nope, no alternate */
    -			a_chk->whoTo = asoc->last_data_chunk_from;
    -			asoc->used_alt_onsack = 0;
    -		}
    -	} else {
    -		/*
    -		 * No duplicates so we use the last place we received data
    -		 * from.
    -		 */
    -		asoc->used_alt_onsack = 0;
    -		a_chk->whoTo = asoc->last_data_chunk_from;
    -	}
    -	if (a_chk->whoTo) {
    -		atomic_add_int(&a_chk->whoTo->ref_count, 1);
    -	}
    -	if (compare_with_wrap(asoc->highest_tsn_inside_map, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
    -		highest_tsn = asoc->highest_tsn_inside_map;
    -	} else {
    -		highest_tsn = asoc->highest_tsn_inside_nr_map;
    -	}
    -	if (highest_tsn == asoc->cumulative_tsn) {
    -		/* no gaps */
    -		space_req = sizeof(struct sctp_nr_sack_chunk);
    -	} else {
    -		/* EY - what is this about? */
    -		/* gaps get a cluster */
    -		space_req = MCLBYTES;
    -	}
    -	/* Ok now lets formulate a MBUF with our sack */
    -	a_chk->data = sctp_get_mbuf_for_msg(space_req, 0, M_DONTWAIT, 1, MT_DATA);
    -	if ((a_chk->data == NULL) ||
    -	    (a_chk->whoTo == NULL)) {
    -		/* rats, no mbuf memory */
    -		if (a_chk->data) {
    -			/* was a problem with the destination */
    -			sctp_m_freem(a_chk->data);
    -			a_chk->data = NULL;
    -		}
    -		sctp_free_a_chunk(stcb, a_chk);
    -		/* sa_ignore NO_NULL_CHK */
    -		if (stcb->asoc.delayed_ack) {
    -			sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
    -			    stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6);
    -			sctp_timer_start(SCTP_TIMER_TYPE_RECV,
    -			    stcb->sctp_ep, stcb, NULL);
    -		} else {
    -			stcb->asoc.send_sack = 1;
    -		}
    -		return;
    -	}
    -	/* ok, lets go through and fill it in */
    -	SCTP_BUF_RESV_UF(a_chk->data, SCTP_MIN_OVERHEAD);
    -	space = M_TRAILINGSPACE(a_chk->data);
    -	if (space > (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD)) {
    -		space = (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD);
    -	}
    -	limit = mtod(a_chk->data, caddr_t);
    -	limit += space;
    -
    -	nr_sack = mtod(a_chk->data, struct sctp_nr_sack_chunk *);
    -	nr_sack->ch.chunk_type = SCTP_NR_SELECTIVE_ACK;
    -	/* EYJ */
    -	/* 0x01 is used by nonce for ecn */
    -	if ((SCTP_BASE_SYSCTL(sctp_ecn_enable)) &&
    -	    (SCTP_BASE_SYSCTL(sctp_ecn_nonce)) &&
    -	    (asoc->peer_supports_ecn_nonce))
    -		nr_sack->ch.chunk_flags = (asoc->receiver_nonce_sum & SCTP_SACK_NONCE_SUM);
    -	else
    -		nr_sack->ch.chunk_flags = 0;
    -
    -	if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
    -		/*-
    -		 * CMT DAC algorithm: If 2 (i.e., 0x10) packets have been
    -		 * received, then set high bit to 1, else 0. Reset
    -		 * pkts_rcvd.
    -		 */
    -		/* EY - TODO: which chunk flag is used in here? -The LSB */
    -		nr_sack->ch.chunk_flags |= (asoc->cmt_dac_pkts_rcvd << 6);
    -		asoc->cmt_dac_pkts_rcvd = 0;
    -	}
    -#ifdef SCTP_ASOCLOG_OF_TSNS
    -	stcb->asoc.cumack_logsnt[stcb->asoc.cumack_log_atsnt] = asoc->cumulative_tsn;
    -	stcb->asoc.cumack_log_atsnt++;
    -	if (stcb->asoc.cumack_log_atsnt >= SCTP_TSN_LOG_SIZE) {
    -		stcb->asoc.cumack_log_atsnt = 0;
    -	}
    -#endif
    -	nr_sack->nr_sack.cum_tsn_ack = htonl(asoc->cumulative_tsn);
    -	nr_sack->nr_sack.a_rwnd = htonl(asoc->my_rwnd);
     	asoc->my_last_reported_rwnd = asoc->my_rwnd;
    -
    -	/* reset the readers interpretation */
    -	stcb->freed_by_sorcv_sincelast = 0;
    -
    -	gap_descriptor = (struct sctp_gap_ack_block *)((caddr_t)nr_sack + sizeof(struct sctp_nr_sack_chunk));
    -
    -	if (asoc->highest_tsn_inside_map > asoc->mapping_array_base_tsn)
    -		siz = (((asoc->highest_tsn_inside_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
    -	else
    -		siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_map + 7) / 8;
    -
    -	if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
    -		offset = 1;
    -		/*-
    -		 * cum-ack behind the mapping array, so we start and use all
    -		 * entries.
    -		 */
    -		jstart = 0;
    -	} else {
    -		offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
    -		/*-
    -		 * we skip the first one when the cum-ack is at or above the
    -		 * mapping array base. Note this only works if
    -		 */
    -		jstart = 1;
    -	}
    -	if (compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN)) {
    -		/* we have a gap .. maybe */
    -		for (i = 0; i < siz; i++) {
    -			seen_non_zero = 1;
    -			selector = &sack_array[asoc->mapping_array[i]];
    -			if (mergeable && selector->right_edge) {
    -				/*
    -				 * Backup, left and right edges were ok to
    -				 * merge.
    -				 */
    -				num_gap_blocks--;
    -				gap_descriptor--;
    -			}
    -			if (selector->num_entries == 0)
    -				mergeable = 0;
    -			else {
    -				for (j = jstart; j < selector->num_entries; j++) {
    -					if (mergeable && selector->right_edge) {
    -						/*
    -						 * do a merge by NOT setting
    -						 * the left side
    -						 */
    -						mergeable = 0;
    -					} else {
    -						/*
    -						 * no merge, set the left
    -						 * side
    -						 */
    -						mergeable = 0;
    -						gap_descriptor->start = htons((selector->gaps[j].start + offset));
    -					}
    -					gap_descriptor->end = htons((selector->gaps[j].end + offset));
    -					num_gap_blocks++;
    -					gap_descriptor++;
    -					if (((caddr_t)gap_descriptor + sizeof(struct sctp_gap_ack_block)) > limit) {
    -						/* no more room */
    -						limit_reached = 1;
    -						break;
    -					}
    -				}
    -				if (selector->left_edge) {
    -					mergeable = 1;
    -				}
    -			}
    -			if (limit_reached) {
    -				/* Reached the limit stop */
    -				break;
    -			}
    -			jstart = 0;
    -			offset += 8;
    -		}
    -	}
    -	if (limit_reached == 0) {
    -
    -		mergeable = 0;
    -
    -		if (asoc->highest_tsn_inside_nr_map > asoc->nr_mapping_array_base_tsn)
    -			siz = (((asoc->highest_tsn_inside_nr_map - asoc->nr_mapping_array_base_tsn) + 1) + 7) / 8;
    -		else
    -			siz = (((MAX_TSN - asoc->nr_mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_nr_map + 7) / 8;
    -
    -		if (compare_with_wrap(asoc->nr_mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
    -			offset = 1;
    -			/*-
    -			* cum-ack behind the mapping array, so we start and use all
    -			* entries.
    -			*/
    -			jstart = 0;
    -		} else {
    -			offset = asoc->nr_mapping_array_base_tsn - asoc->cumulative_tsn;
    -			/*-
    -			* we skip the first one when the cum-ack is at or above the
    -			* mapping array base. Note this only works if
    -			*/
    -			jstart = 1;
    -		}
    -		if (compare_with_wrap(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn, MAX_TSN)) {
    -			/* we have a gap .. maybe */
    -			for (i = 0; i < siz; i++) {
    -				nr_selector = &sack_array[asoc->nr_mapping_array[i]];
    -				if (mergeable && nr_selector->right_edge) {
    -					/*
    -					 * Backup, left and right edges were
    -					 * ok to merge.
    -					 */
    -					num_nr_gap_blocks--;
    -					gap_descriptor--;
    -				}
    -				if (nr_selector->num_entries == 0)
    -					mergeable = 0;
    -				else {
    -					for (j = jstart; j < nr_selector->num_entries; j++) {
    -						if (mergeable && nr_selector->right_edge) {
    -							/*
    -							 * do a merge by NOT
    -							 * setting the left
    -							 * side
    -							 */
    -							mergeable = 0;
    -						} else {
    -							/*
    -							 * no merge, set the
    -							 * left side
    -							 */
    -							mergeable = 0;
    -							gap_descriptor->start = htons((nr_selector->gaps[j].start + offset));
    -						}
    -						gap_descriptor->end = htons((nr_selector->gaps[j].end + offset));
    -						num_nr_gap_blocks++;
    -						gap_descriptor++;
    -						if (((caddr_t)gap_descriptor + sizeof(struct sctp_gap_ack_block)) > limit) {
    -							/* no more room */
    -							limit_reached = 1;
    -							break;
    -						}
    -					}
    -					if (nr_selector->left_edge) {
    -						mergeable = 1;
    -					}
    -				}
    -				if (limit_reached) {
    -					/* Reached the limit stop */
    -					break;
    -				}
    -				jstart = 0;
    -				offset += 8;
    -			}
    -		}
    -	}
    -	if ((limit_reached == 0) && (asoc->numduptsns)) {
    -		dup = (uint32_t *) gap_descriptor;
    -		for (i = 0; i < asoc->numduptsns; i++) {
    -			*dup = htonl(asoc->dup_tsns[i]);
    -			dup++;
    -			num_dups++;
    -			if (((caddr_t)dup + sizeof(uint32_t)) > limit) {
    -				/* no more room */
    -				break;
    -			}
    -		}
    -		asoc->numduptsns = 0;
    -	}
    -	/*
    -	 * now that the chunk is prepared queue it to the control chunk
    -	 * queue.
    -	 */
    -	a_chk->send_size = sizeof(struct sctp_nr_sack_chunk) +
    -	    (num_gap_blocks + num_nr_gap_blocks) * sizeof(struct sctp_gap_ack_block) +
    -	    num_dups * sizeof(int32_t);
    -
    -	SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
    -	nr_sack->nr_sack.num_gap_ack_blks = htons(num_gap_blocks);
    -	nr_sack->nr_sack.num_nr_gap_ack_blks = htons(num_nr_gap_blocks);
    -	nr_sack->nr_sack.num_dup_tsns = htons(num_dups);
    -	nr_sack->nr_sack.reserved = 0;
    -	nr_sack->ch.chunk_length = htons(a_chk->send_size);
    -	TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next);
     	asoc->ctrl_queue_cnt++;
     	asoc->send_sack = 0;
     	SCTP_STAT_INCR(sctps_sendsacks);
    @@ -12576,7 +12339,7 @@ sctp_lower_sosend(struct socket *so,
     				panic("Error, should hold create lock and I don't?");
     			}
     #endif
    -			stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id,
    +			stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
     			    p
     			    );
     			if (stcb == NULL) {
    diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h
    index bd40a0b1f09..6488b1cf739 100644
    --- a/sys/netinet/sctp_output.h
    +++ b/sys/netinet/sctp_output.h
    @@ -155,9 +155,6 @@ void send_forward_tsn(struct sctp_tcb *, struct sctp_association *);
     
     void sctp_send_sack(struct sctp_tcb *);
     
    -/* EY 05/07/08 if nr_sacks used, the following function will be called instead of sctp_send_sack */
    -void sctp_send_nr_sack(struct sctp_tcb *);
    -
     int sctp_send_hb(struct sctp_tcb *, int, struct sctp_nets *);
     
     void sctp_send_ecn_echo(struct sctp_tcb *, struct sctp_nets *, uint32_t);
    diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
    index fa188249a96..273a4a7766c 100644
    --- a/sys/netinet/sctp_pcb.c
    +++ b/sys/netinet/sctp_pcb.c
    @@ -3960,7 +3960,7 @@ try_again:
      */
     struct sctp_tcb *
     sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
    -    int for_a_init, int *error, uint32_t override_tag, uint32_t vrf_id,
    +    int *error, uint32_t override_tag, uint32_t vrf_id,
         struct thread *p
     )
     {
    @@ -4080,7 +4080,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
     	/* setup back pointer's */
     	stcb->sctp_ep = inp;
     	stcb->sctp_socket = inp->sctp_socket;
    -	if ((err = sctp_init_asoc(inp, stcb, for_a_init, override_tag, vrf_id))) {
    +	if ((err = sctp_init_asoc(inp, stcb, override_tag, vrf_id))) {
     		/* failed */
     		SCTP_TCB_LOCK_DESTROY(stcb);
     		SCTP_TCB_SEND_LOCK_DESTROY(stcb);
    @@ -4681,7 +4681,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
     	    inp->sctp_lport, stcb->rport);
     
     	/*
    -	 * Now restop the timers to be sure - this is paranoia at is finest!
    +	 * Now restop the timers to be sure this is paranoia at is finest!
     	 */
     	(void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
     	(void)SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
    @@ -6422,9 +6422,11 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
     	 */
     	struct sctp_association *asoc;
     	struct sctp_tmit_chunk *chk, *nchk;
    -	uint32_t cumulative_tsn_p1, tsn;
    +	uint32_t cumulative_tsn_p1;
     	struct sctp_queued_to_read *ctl, *nctl;
    -	int cnt, strmat, gap;
    +	int cnt, strmat;
    +	uint32_t gap, i;
    +	int fnd = 0;
     
     	/* We look for anything larger than the cum-ack + 1 */
     
    @@ -6445,13 +6447,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
     		    cumulative_tsn_p1, MAX_TSN)) {
     			/* Yep it is above cum-ack */
     			cnt++;
    -			tsn = chk->rec.data.TSN_seq;
    -			if (tsn >= asoc->mapping_array_base_tsn) {
    -				gap = tsn - asoc->mapping_array_base_tsn;
    -			} else {
    -				gap = (MAX_TSN - asoc->mapping_array_base_tsn) +
    -				    tsn + 1;
    -			}
    +			SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.TSN_seq, asoc->mapping_array_base_tsn);
     			asoc->size_on_reasm_queue = sctp_sbspace_sub(asoc->size_on_reasm_queue, chk->send_size);
     			sctp_ucount_decr(asoc->cnt_on_reasm_queue);
     			SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
    @@ -6473,22 +6469,11 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
     			    cumulative_tsn_p1, MAX_TSN)) {
     				/* Yep it is above cum-ack */
     				cnt++;
    -				tsn = ctl->sinfo_tsn;
    -				if (tsn >= asoc->mapping_array_base_tsn) {
    -					gap = tsn -
    -					    asoc->mapping_array_base_tsn;
    -				} else {
    -					gap = (MAX_TSN -
    -					    asoc->mapping_array_base_tsn) +
    -					    tsn + 1;
    -				}
    +				SCTP_CALC_TSN_TO_GAP(gap, ctl->sinfo_tsn, asoc->mapping_array_base_tsn);
     				asoc->size_on_all_streams = sctp_sbspace_sub(asoc->size_on_all_streams, ctl->length);
     				sctp_ucount_decr(asoc->cnt_on_all_streams);
    -
    -				SCTP_UNSET_TSN_PRESENT(asoc->mapping_array,
    -				    gap);
    -				TAILQ_REMOVE(&asoc->strmin[strmat].inqueue,
    -				    ctl, next);
    +				SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
    +				TAILQ_REMOVE(&asoc->strmin[strmat].inqueue, ctl, next);
     				if (ctl->data) {
     					sctp_m_freem(ctl->data);
     					ctl->data = NULL;
    @@ -6500,69 +6485,44 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
     			ctl = nctl;
     		}
     	}
    -	/*
    -	 * Question, should we go through the delivery queue? The only
    -	 * reason things are on here is the app not reading OR a p-d-api up.
    -	 * An attacker COULD send enough in to initiate the PD-API and then
    -	 * send a bunch of stuff to other streams... these would wind up on
    -	 * the delivery queue.. and then we would not get to them. But in
    -	 * order to do this I then have to back-track and un-deliver
    -	 * sequence numbers in streams.. el-yucko. I think for now we will
    -	 * NOT look at the delivery queue and leave it to be something to
    -	 * consider later. An alternative would be to abort the P-D-API with
    -	 * a notification and then deliver the data.... Or another method
    -	 * might be to keep track of how many times the situation occurs and
    -	 * if we see a possible attack underway just abort the association.
    -	 */
    +	if (cnt) {
    +		/* We must back down to see what the new highest is */
    +		for (i = asoc->highest_tsn_inside_map;
    +		    (compare_with_wrap(i, asoc->mapping_array_base_tsn, MAX_TSN) || (i == asoc->mapping_array_base_tsn));
    +		    i--) {
    +			SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
    +			if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
    +				asoc->highest_tsn_inside_map = i;
    +				fnd = 1;
    +				break;
    +			}
    +		}
    +		if (!fnd) {
    +			asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
    +		}
    +		/*
    +		 * Question, should we go through the delivery queue? The
    +		 * only reason things are on here is the app not reading OR
    +		 * a p-d-api up. An attacker COULD send enough in to
    +		 * initiate the PD-API and then send a bunch of stuff to
    +		 * other streams... these would wind up on the delivery
    +		 * queue.. and then we would not get to them. But in order
    +		 * to do this I then have to back-track and un-deliver
    +		 * sequence numbers in streams.. el-yucko. I think for now
    +		 * we will NOT look at the delivery queue and leave it to be
    +		 * something to consider later. An alternative would be to
    +		 * abort the P-D-API with a notification and then deliver
    +		 * the data.... Or another method might be to keep track of
    +		 * how many times the situation occurs and if we see a
    +		 * possible attack underway just abort the association.
    +		 */
     #ifdef SCTP_DEBUG
    -	if (cnt) {
     		SCTPDBG(SCTP_DEBUG_PCB1, "Freed %d chunks from reneg harvest\n", cnt);
    -	}
     #endif
    -	if (cnt) {
     		/*
     		 * Now do we need to find a new
     		 * asoc->highest_tsn_inside_map?
     		 */
    -		if (asoc->highest_tsn_inside_map >= asoc->mapping_array_base_tsn) {
    -			gap = asoc->highest_tsn_inside_map - asoc->mapping_array_base_tsn;
    -		} else {
    -			gap = (MAX_TSN - asoc->mapping_array_base_tsn) +
    -			    asoc->highest_tsn_inside_map + 1;
    -		}
    -		if (gap >= (asoc->mapping_array_size << 3)) {
    -			/*
    -			 * Something bad happened or cum-ack and high were
    -			 * behind the base, but if so earlier checks should
    -			 * have found NO data... wierd... we will start at
    -			 * end of mapping array.
    -			 */
    -			SCTP_PRINTF("Gap was larger than array?? %d set to max:%d maparraymax:%x\n",
    -			    (int)gap,
    -			    (int)(asoc->mapping_array_size << 3),
    -			    (int)asoc->highest_tsn_inside_map);
    -			gap = asoc->mapping_array_size << 3;
    -		}
    -		while (gap > 0) {
    -			if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
    -				/* found the new highest */
    -				asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn + gap;
    -				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    -					sctp_log_map(0, 8, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
    -				}
    -				break;
    -			}
    -			gap--;
    -		}
    -		if (gap == 0) {
    -			/* Nothing left in map */
    -			memset(asoc->mapping_array, 0, asoc->mapping_array_size);
    -			asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
    -			asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
    -			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    -				sctp_log_map(0, 9, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
    -			}
    -		}
     		asoc->last_revoke_count = cnt;
     		(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
     		/* sa_ignore NO_NULL_CHK */
    diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
    index bf14175cac3..1a468f8632d 100644
    --- a/sys/netinet/sctp_pcb.h
    +++ b/sys/netinet/sctp_pcb.h
    @@ -564,7 +564,7 @@ void sctp_inpcb_free(struct sctp_inpcb *, int, int);
     
     struct sctp_tcb *
     sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
    -    int, int *, uint32_t, uint32_t, struct thread *);
    +    int *, uint32_t, uint32_t, struct thread *);
     
     int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int);
     
    diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h
    index 9b952fd022b..cd798b521d8 100644
    --- a/sys/netinet/sctp_structs.h
    +++ b/sys/netinet/sctp_structs.h
    @@ -477,7 +477,6 @@ struct sctp_asconf_addr {
     	struct sctp_ifa *ifa;	/* save the ifa for add/del ip */
     	uint8_t sent;		/* has this been sent yet? */
     	uint8_t special_del;	/* not to be used in lookup */
    -
     };
     
     struct sctp_scoping {
    @@ -771,9 +770,7 @@ struct sctp_association {
     
     	/* EY - new NR variables used for nr_sack based on mapping_array */
     	uint8_t *nr_mapping_array;
    -	uint32_t nr_mapping_array_base_tsn;
     	uint32_t highest_tsn_inside_nr_map;
    -	uint16_t nr_mapping_array_size;
     
     	uint32_t last_echo_tsn;
     	uint32_t last_cwr_tsn;
    diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
    index 2851272d35a..fc6a4ac1abb 100644
    --- a/sys/netinet/sctp_usrreq.c
    +++ b/sys/netinet/sctp_usrreq.c
    @@ -1492,7 +1492,7 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
     
     
     	/* We are GOOD to go */
    -	stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0, vrf_id,
    +	stcb = sctp_aloc_assoc(inp, sa, &error, 0, vrf_id,
     	    (struct thread *)p
     	    );
     	if (stcb == NULL) {
    @@ -4459,7 +4459,7 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
     	}
     	vrf_id = inp->def_vrf_id;
     	/* We are GOOD to go */
    -	stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id, p);
    +	stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p);
     	if (stcb == NULL) {
     		/* Gak! no memory */
     		goto out_now;
    diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
    index 1ccccf3d3c4..bff7f5def1e 100644
    --- a/sys/netinet/sctp_var.h
    +++ b/sys/netinet/sctp_var.h
    @@ -108,7 +108,7 @@ extern struct pr_usrreqs sctp_usrreqs;
     		sctp_auth_key_release((_stcb), (_chk)->auth_keyid); \
     		(_chk)->holds_key_ref = 0; \
     	} \
    -        if(_stcb) { \
    +        if (_stcb) { \
               SCTP_TCB_LOCK_ASSERT((_stcb)); \
               if ((_chk)->whoTo) { \
                       sctp_free_remote_addr((_chk)->whoTo); \
    @@ -231,7 +231,7 @@ extern struct pr_usrreqs sctp_usrreqs;
     
     #ifdef SCTP_FS_SPEC_LOG
     #define sctp_total_flight_decrease(stcb, tp1) do { \
    -        if(stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
    +        if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
     		stcb->asoc.fs_index = 0;\
     	stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
     	stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
    @@ -252,7 +252,7 @@ extern struct pr_usrreqs sctp_usrreqs;
     } while (0)
     
     #define sctp_total_flight_increase(stcb, tp1) do { \
    -        if(stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
    +        if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
     		stcb->asoc.fs_index = 0;\
     	stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
     	stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
    diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
    index e9f5aecb998..bcc253d9baf 100644
    --- a/sys/netinet/sctputil.c
    +++ b/sys/netinet/sctputil.c
    @@ -52,9 +52,15 @@ __FBSDID("$FreeBSD$");
     #define NUMBER_OF_MTU_SIZES 18
     
     
    +#if defined(__Windows__) && !defined(SCTP_LOCAL_TRACE_BUF)
    +#include "eventrace_netinet.h"
    +#include "sctputil.tmh"		/* this is the file that will be auto
    +				 * generated */
    +#else
     #ifndef KTR_SCTP
     #define KTR_SCTP KTR_SUBSYS
     #endif
    +#endif
     
     void
     sctp_sblog(struct sockbuf *sb,
    @@ -869,7 +875,7 @@ sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int sa
     
     int
     sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
    -    int for_a_init, uint32_t override_tag, uint32_t vrf_id)
    +    uint32_t override_tag, uint32_t vrf_id)
     {
     	struct sctp_association *asoc;
     
    @@ -1132,9 +1138,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
     		return (ENOMEM);
     	}
     	memset(asoc->mapping_array, 0, asoc->mapping_array_size);
    -	/* EY  - initialize the nr_mapping_array just like mapping array */
    -	asoc->nr_mapping_array_size = SCTP_INITIAL_NR_MAPPING_ARRAY;
    -	SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->nr_mapping_array_size,
    +	SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->mapping_array_size,
     	    SCTP_M_MAP);
     	if (asoc->nr_mapping_array == NULL) {
     		SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
    @@ -1142,7 +1146,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
     		SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
     		return (ENOMEM);
     	}
    -	memset(asoc->nr_mapping_array, 0, asoc->nr_mapping_array_size);
    +	memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
     
     	/* Now the init of the other outqueues */
     	TAILQ_INIT(&asoc->free_chunks);
    @@ -1207,12 +1211,12 @@ sctp_print_mapping_array(struct sctp_association *asoc)
     	}
     	printf("\n");
     	printf("NR Mapping size:%d baseTSN:%8.8x highestTSN:%8.8x\n",
    -	    asoc->nr_mapping_array_size,
    -	    asoc->nr_mapping_array_base_tsn,
    +	    asoc->mapping_array_size,
    +	    asoc->mapping_array_base_tsn,
     	    asoc->highest_tsn_inside_nr_map
     	    );
    -	limit = asoc->nr_mapping_array_size;
    -	for (i = asoc->nr_mapping_array_size; i >= 0; i--) {
    +	limit = asoc->mapping_array_size;
    +	for (i = asoc->mapping_array_size; i >= 0; i--) {
     		if (asoc->nr_mapping_array[i]) {
     			limit = i;
     			break;
    @@ -1233,37 +1237,34 @@ int
     sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
     {
     	/* mapping array needs to grow */
    -	uint8_t *new_array;
    +	uint8_t *new_array1, *new_array2;
     	uint32_t new_size;
     
     
     	new_size = asoc->mapping_array_size + ((needed + 7) / 8 + SCTP_MAPPING_ARRAY_INCR);
     
    -	SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
    -	if (new_array == NULL) {
    +	SCTP_MALLOC(new_array1, uint8_t *, new_size, SCTP_M_MAP);
    +	SCTP_MALLOC(new_array2, uint8_t *, new_size, SCTP_M_MAP);
    +	if ((new_array1 == NULL) || (new_array2 == NULL)) {
     		/* can't get more, forget it */
    -		SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
    -		    new_size);
    +		SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n", new_size);
    +		if (new_array1) {
    +			SCTP_FREE(new_array1, SCTP_M_MAP);
    +		}
    +		if (new_array2) {
    +			SCTP_FREE(new_array2, SCTP_M_MAP);
    +		}
     		return (-1);
     	}
    -	memset(new_array, 0, new_size);
    -	memcpy(new_array, asoc->mapping_array, asoc->mapping_array_size);
    +	memset(new_array1, 0, new_size);
    +	memset(new_array2, 0, new_size);
    +	memcpy(new_array1, asoc->mapping_array, asoc->mapping_array_size);
    +	memcpy(new_array2, asoc->nr_mapping_array, asoc->mapping_array_size);
     	SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
    -	asoc->mapping_array = new_array;
    -	asoc->mapping_array_size = new_size;
    -	new_size = asoc->nr_mapping_array_size + ((needed + 7) / 8 + SCTP_NR_MAPPING_ARRAY_INCR);
    -	SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
    -	if (new_array == NULL) {
    -		/* can't get more, forget it */
    -		SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
    -		    new_size);
    -		return (-1);
    -	}
    -	memset(new_array, 0, new_size);
    -	memcpy(new_array, asoc->nr_mapping_array, asoc->nr_mapping_array_size);
     	SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
    -	asoc->nr_mapping_array = new_array;
    -	asoc->nr_mapping_array_size = new_size;
    +	asoc->mapping_array = new_array1;
    +	asoc->nr_mapping_array = new_array2;
    +	asoc->mapping_array_size = new_size;
     	return (0);
     }
     
    @@ -1684,21 +1685,9 @@ sctp_timeout_handler(void *t)
     		if ((stcb == NULL) || (inp == NULL)) {
     			break;
     		} {
    -			int abort_flag;
    -
     			SCTP_STAT_INCR(sctps_timosack);
     			stcb->asoc.timosack++;
    -			if (stcb->asoc.cumulative_tsn != stcb->asoc.highest_tsn_inside_map)
    -				sctp_sack_check(stcb, 0, 0, &abort_flag);
    -
    -			/*
    -			 * EY if nr_sacks used then send an nr-sack , a sack
    -			 * otherwise
    -			 */
    -			if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
    -				sctp_send_nr_sack(stcb);
    -			else
    -				sctp_send_sack(stcb);
    +			sctp_send_sack(stcb);
     		}
     #ifdef SCTP_AUDITING_ENABLED
     		sctp_auditing(4, inp, stcb, net);
    @@ -4758,8 +4747,7 @@ next_on_sent:
     		 */
     		if ((tp1) &&
     		    (tp1->rec.data.stream_number == stream) &&
    -		    (tp1->rec.data.stream_seq == seq)
    -		    ) {
    +		    (tp1->rec.data.stream_seq == seq)) {
     			/*
     			 * save to chk in case we have some on stream out
     			 * queue. If so and we have an un-transmitted one we
    @@ -5102,14 +5090,7 @@ sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t * freed_so_far, int hold_rlock,
     			goto out;
     		}
     		SCTP_STAT_INCR(sctps_wu_sacks_sent);
    -		/*
    -		 * EY if nr_sacks used then send an nr-sack , a sack
    -		 * otherwise
    -		 */
    -		if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
    -			sctp_send_nr_sack(stcb);
    -		else
    -			sctp_send_sack(stcb);
    +		sctp_send_sack(stcb);
     
     		sctp_chunk_output(stcb->sctp_ep, stcb,
     		    SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
    @@ -5479,8 +5460,7 @@ restart_nosblocks:
     					    ((ctl->some_taken) ||
     					    ((ctl->do_not_ref_stcb == 0) &&
     					    ((ctl->spec_flags & M_NOTIFICATION) == 0) &&
    -					    (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))
    -				    ) {
    +				    (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))) {
     					/*-
     					 * If we have the same tcb, and there is data present, and we
     					 * have the strm interleave feature present. Then if we have
    @@ -5939,8 +5919,7 @@ wait_some_more:
     			hold_sblock = 1;
     		}
     		if ((copied_so_far) && (control->length == 0) &&
    -		    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))
    -		    ) {
    +		    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) {
     			goto release;
     		}
     		if (so->so_rcv.sb_cc <= control->held_length) {
    diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
    index 8a6ee6fb213..dfd552aea19 100644
    --- a/sys/netinet/sctputil.h
    +++ b/sys/netinet/sctputil.h
    @@ -81,7 +81,7 @@ uint32_t sctp_select_initial_TSN(struct sctp_pcb *);
     
     uint32_t sctp_select_a_tag(struct sctp_inpcb *, uint16_t lport, uint16_t rport, int);
     
    -int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, int, uint32_t, uint32_t);
    +int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t);
     
     void sctp_fill_random_store(struct sctp_pcb *);
     
    diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
    index 50f5ef83746..02e28802320 100644
    --- a/sys/netinet6/sctp6_usrreq.c
    +++ b/sys/netinet6/sctp6_usrreq.c
    @@ -1033,7 +1033,7 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
     		return (EALREADY);
     	}
     	/* We are GOOD to go */
    -	stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id, p);
    +	stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p);
     	SCTP_ASOC_CREATE_UNLOCK(inp);
     	if (stcb == NULL) {
     		/* Gak! no memory */
    
    From 56be5eba8bdc564630fa7bfe314035bda3e87932 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:17:17 +0000
    Subject: [PATCH 1997/2592] MFC of  206151
    
    ---
     sys/netinet/sctp_output.c | 73 ++++++++++++++++++++++++++++++++-------
     1 file changed, 60 insertions(+), 13 deletions(-)
    
    diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
    index 3f7862bc55b..c7a806c0d9e 100644
    --- a/sys/netinet/sctp_output.c
    +++ b/sys/netinet/sctp_output.c
    @@ -3709,7 +3709,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
     			    (stcb) &&
     			    (stcb->asoc.loopback_scope))) {
     				m->m_pkthdr.csum_flags = CSUM_SCTP;
    -				m->m_pkthdr.csum_data = 0;	/* FIXME MT */
    +				m->m_pkthdr.csum_data = 0;
     				SCTP_STAT_INCR(sctps_sendhwcrc);
     			} else {
     				SCTP_STAT_INCR(sctps_sendnocrc);
    @@ -4021,7 +4021,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
     			    (stcb) &&
     			    (stcb->asoc.loopback_scope))) {
     				m->m_pkthdr.csum_flags = CSUM_SCTP;
    -				m->m_pkthdr.csum_data = 0;	/* FIXME MT */
    +				m->m_pkthdr.csum_data = 0;
     				SCTP_STAT_INCR(sctps_sendhwcrc);
     			} else {
     				SCTP_STAT_INCR(sctps_sendnocrc);
    @@ -10542,7 +10542,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
     			SCTP_ENABLE_UDP_CSUM(mout);
     		} else {
     			mout->m_pkthdr.csum_flags = CSUM_SCTP;
    -			mout->m_pkthdr.csum_data = 0;	/* FIXME MT */
    +			mout->m_pkthdr.csum_data = 0;
     			SCTP_STAT_INCR(sctps_sendhwcrc);
     		}
     		SCTP_ATTACH_CHAIN(o_pak, mout, mlen);
    @@ -10566,14 +10566,29 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
     		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
     			sctp_packet_log(mout, mlen);
     #endif
    -		comp_cp->sh.checksum = sctp_calculate_cksum(mout, offset_out);
    -		SCTP_STAT_INCR(sctps_sendswcrc);
     		SCTP_ATTACH_CHAIN(o_pak, mout, mlen);
     		if (port) {
    -			if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr),
    -			    sizeof(struct sctp_shutdown_complete_msg) + sizeof(struct udphdr))) == 0) {
    +			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    +			    (stcb) &&
    +			    (stcb->asoc.loopback_scope))) {
    +				comp_cp->sh.checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
    +				SCTP_STAT_INCR(sctps_sendswcrc);
    +			} else {
    +				SCTP_STAT_INCR(sctps_sendnocrc);
    +			}
    +			if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), mlen - sizeof(struct ip6_hdr))) == 0) {
     				udp->uh_sum = 0xffff;
     			}
    +		} else {
    +			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    +			    (stcb) &&
    +			    (stcb->asoc.loopback_scope))) {
    +				mout->m_pkthdr.csum_flags = CSUM_SCTP;
    +				mout->m_pkthdr.csum_data = 0;
    +				SCTP_STAT_INCR(sctps_sendhwcrc);
    +			} else {
    +				SCTP_STAT_INCR(sctps_sendnocrc);
    +			}
     		}
     		SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
     
    @@ -11593,7 +11608,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
     			SCTP_ENABLE_UDP_CSUM(o_pak);
     		} else {
     			mout->m_pkthdr.csum_flags = CSUM_SCTP;
    -			mout->m_pkthdr.csum_data = 0;	/* FIXME MT */
    +			mout->m_pkthdr.csum_data = 0;
     			SCTP_STAT_INCR(sctps_sendhwcrc);
     		}
     		SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id);
    @@ -11621,13 +11636,29 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
     		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
     			sctp_packet_log(mout, len);
     #endif
    -		abm->sh.checksum = sctp_calculate_cksum(mout, iphlen_out);
    -		SCTP_STAT_INCR(sctps_sendswcrc);
     		SCTP_ATTACH_CHAIN(o_pak, mout, len);
     		if (port) {
    +			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    +			    (stcb) &&
    +			    (stcb->asoc.loopback_scope))) {
    +				abm->sh.checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
    +				SCTP_STAT_INCR(sctps_sendswcrc);
    +			} else {
    +				SCTP_STAT_INCR(sctps_sendnocrc);
    +			}
     			if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) {
     				udp->uh_sum = 0xffff;
     			}
    +		} else {
    +			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    +			    (stcb) &&
    +			    (stcb->asoc.loopback_scope))) {
    +				mout->m_pkthdr.csum_flags = CSUM_SCTP;
    +				mout->m_pkthdr.csum_data = 0;
    +				SCTP_STAT_INCR(sctps_sendhwcrc);
    +			} else {
    +				SCTP_STAT_INCR(sctps_sendnocrc);
    +			}
     		}
     		SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
     
    @@ -11815,7 +11846,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
     			SCTP_ENABLE_UDP_CSUM(o_pak);
     		} else {
     			mout->m_pkthdr.csum_flags = CSUM_SCTP;
    -			mout->m_pkthdr.csum_data = 0;	/* FIXME MT */
    +			mout->m_pkthdr.csum_data = 0;
     			SCTP_STAT_INCR(sctps_sendhwcrc);
     		}
     		SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id);
    @@ -11841,13 +11872,29 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
     		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
     			sctp_packet_log(mout, len);
     #endif
    -		sh_out->checksum = sctp_calculate_cksum(mout, iphlen_out);
    -		SCTP_STAT_INCR(sctps_sendswcrc);
     		SCTP_ATTACH_CHAIN(o_pak, mout, len);
     		if (port) {
    +			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    +			    (stcb) &&
    +			    (stcb->asoc.loopback_scope))) {
    +				sh_out->checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
    +				SCTP_STAT_INCR(sctps_sendswcrc);
    +			} else {
    +				SCTP_STAT_INCR(sctps_sendnocrc);
    +			}
     			if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) {
     				udp->uh_sum = 0xffff;
     			}
    +		} else {
    +			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    +			    (stcb) &&
    +			    (stcb->asoc.loopback_scope))) {
    +				mout->m_pkthdr.csum_flags = CSUM_SCTP;
    +				mout->m_pkthdr.csum_data = 0;
    +				SCTP_STAT_INCR(sctps_sendhwcrc);
    +			} else {
    +				SCTP_STAT_INCR(sctps_sendnocrc);
    +			}
     		}
     		SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
     
    
    From 0099361644b4bce076ea8c87452d55eb9f7d60d4 Mon Sep 17 00:00:00 2001
    From: Randall Stewart 
    Date: Sat, 17 Apr 2010 04:19:18 +0000
    Subject: [PATCH 1998/2592] MFC of  206281
    
    Final MFC of all the IETF hack a-thon.. head and stable are
    now in sync ;-)
    ---
     sys/netinet/sctp_indata.c |  5 ++---
     sys/netinet/sctputil.c    | 46 ++++++++++++++-------------------------
     2 files changed, 18 insertions(+), 33 deletions(-)
    
    diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
    index 055b12b68dc..53dcf8f2a6f 100644
    --- a/sys/netinet/sctp_indata.c
    +++ b/sys/netinet/sctp_indata.c
    @@ -2275,8 +2275,7 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
     	asoc->cumulative_tsn = asoc->mapping_array_base_tsn + (at - 1);
     
     	if (compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_map, MAX_TSN) &&
    -	    compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)
    -	    ) {
    +	    compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) {
     #ifdef INVARIANTS
     		panic("huh, cumack 0x%x greater than high-tsn 0x%x in map",
     		    asoc->cumulative_tsn, asoc->highest_tsn_inside_map);
    @@ -2378,7 +2377,7 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
     				    asoc->nr_mapping_array[slide_from + ii];
     
     			}
    -			for (ii = distance; ii <= asoc->mapping_array_size; ii++) {
    +			for (ii = distance; ii < asoc->mapping_array_size; ii++) {
     				asoc->mapping_array[ii] = 0;
     				asoc->nr_mapping_array[ii] = 0;
     			}
    diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
    index bcc253d9baf..0f2805fb613 100644
    --- a/sys/netinet/sctputil.c
    +++ b/sys/netinet/sctputil.c
    @@ -1187,50 +1187,38 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
     void
     sctp_print_mapping_array(struct sctp_association *asoc)
     {
    -	int i, limit;
    +	unsigned int i, limit;
     
    -	printf("Mapping size:%d baseTSN:%8.8x cumAck:%8.8x highestTSN:%8.8x\n",
    +	printf("Mapping array size: %d, baseTSN: %8.8x, cumAck: %8.8x, highestTSN: (%8.8x, %8.8x).\n",
     	    asoc->mapping_array_size,
     	    asoc->mapping_array_base_tsn,
     	    asoc->cumulative_tsn,
    -	    asoc->highest_tsn_inside_map
    -	    );
    -	limit = asoc->mapping_array_size;
    -	for (i = asoc->mapping_array_size; i >= 0; i--) {
    -		if (asoc->mapping_array[i]) {
    -			limit = i;
    +	    asoc->highest_tsn_inside_map,
    +	    asoc->highest_tsn_inside_nr_map);
    +	for (limit = asoc->mapping_array_size; limit > 1; limit--) {
    +		if (asoc->mapping_array[limit - 1]) {
     			break;
     		}
     	}
    -	if (limit == 0)
    -		limit = 1;
    +	printf("Renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit);
     	for (i = 0; i < limit; i++) {
    -		printf("%2.2x ", asoc->mapping_array[i]);
    +		printf("%2.2x%c", asoc->mapping_array[i], ((i + 1) % 16) ? ' ' : '\n');
     		if (((i + 1) % 16) == 0)
     			printf("\n");
     	}
    -	printf("\n");
    -	printf("NR Mapping size:%d baseTSN:%8.8x highestTSN:%8.8x\n",
    -	    asoc->mapping_array_size,
    -	    asoc->mapping_array_base_tsn,
    -	    asoc->highest_tsn_inside_nr_map
    -	    );
    -	limit = asoc->mapping_array_size;
    -	for (i = asoc->mapping_array_size; i >= 0; i--) {
    -		if (asoc->nr_mapping_array[i]) {
    -			limit = i;
    +	if (limit % 16)
    +		printf("\n");
    +	for (limit = asoc->mapping_array_size; limit > 1; limit--) {
    +		if (asoc->nr_mapping_array[limit - 1]) {
     			break;
     		}
     	}
    -	if (limit == 0)
    -		limit = 1;
    -
    +	printf("Non renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit);
     	for (i = 0; i < limit; i++) {
    -		printf("%2.2x ", asoc->nr_mapping_array[i]);
    -		if (((i + 1) % 16) == 0)
    -			printf("\n");
    +		printf("%2.2x%c", asoc->mapping_array[i], ((i + 1) % 16) ? ' ' : '\n');
     	}
    -	printf("\n");
    +	if (limit % 16)
    +		printf("\n");
     }
     
     int
    @@ -1240,9 +1228,7 @@ sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
     	uint8_t *new_array1, *new_array2;
     	uint32_t new_size;
     
    -
     	new_size = asoc->mapping_array_size + ((needed + 7) / 8 + SCTP_MAPPING_ARRAY_INCR);
    -
     	SCTP_MALLOC(new_array1, uint8_t *, new_size, SCTP_M_MAP);
     	SCTP_MALLOC(new_array2, uint8_t *, new_size, SCTP_M_MAP);
     	if ((new_array1 == NULL) || (new_array2 == NULL)) {
    
    From ee3474bf7607769213b9debc5252fdf12950c95a Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Sat, 17 Apr 2010 04:54:38 +0000
    Subject: [PATCH 1999/2592] MFC r206557: Nuke the descriptions about
     ipv6_firewall_* as they were unified into firewall_*.
    
    ---
     share/man/man5/rc.conf.5 | 34 +---------------------------------
     1 file changed, 1 insertion(+), 33 deletions(-)
    
    diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
    index 6bb3a7188f7..5c55b9097bd 100644
    --- a/share/man/man5/rc.conf.5
    +++ b/share/man/man5/rc.conf.5
    @@ -24,7 +24,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd November 11, 2009
    +.Dd April 14, 2010
     .Dt RC.CONF 5
     .Os
     .Sh NAME
    @@ -432,27 +432,11 @@ the
     kernel module will be loaded.
     See also
     .Va ipfilter_enable .
    -.It Va ipv6_firewall_enable
    -.Pq Vt bool
    -The IPv6 equivalent of
    -.Va firewall_enable .
    -Set to
    -.Dq Li YES
    -to load IPv6 firewall rules at startup.
    -If the kernel was not built with
    -.Cd "options IPV6FIREWALL" ,
    -the
    -.Pa ipfw.ko
    -kernel module will be loaded.
     .It Va firewall_script
     .Pq Vt str
     This variable specifies the full path to the firewall script to run.
     The default is
     .Pa /etc/rc.firewall .
    -.It Va ipv6_firewall_script
    -.Pq Vt str
    -The IPv6 equivalent of
    -.Va firewall_script .
     .It Va firewall_type
     .Pq Vt str
     Names the firewall type from the selection in
    @@ -476,19 +460,11 @@ basic protection for a LAN.
     .Pp
     If a filename is specified, the full path
     must be given.
    -.It Va ipv6_firewall_type
    -.Pq Vt str
    -The IPv6 equivalent of
    -.Va firewall_type .
     .It Va firewall_quiet
     .Pq Vt bool
     Set to
     .Dq Li YES
     to disable the display of firewall rules on the console during boot.
    -.It Va ipv6_firewall_quiet
    -.Pq Vt bool
    -The IPv6 equivalent of
    -.Va firewall_quiet .
     .It Va firewall_logging
     .Pq Vt bool
     Set to
    @@ -497,10 +473,6 @@ to enable firewall event logging.
     This is equivalent to the
     .Dv IPFIREWALL_VERBOSE
     kernel option.
    -.It Va ipv6_firewall_logging
    -.Pq Vt bool
    -The IPv6 equivalent of
    -.Va firewall_logging .
     .It Va firewall_flags
     .Pq Vt str
     Flags passed to
    @@ -508,10 +480,6 @@ Flags passed to
     if
     .Va firewall_type
     specifies a filename.
    -.It Va ipv6_firewall_flags
    -.Pq Vt str
    -The IPv6 equivalent of
    -.Va firewall_flags .
     .It Va firewall_coscripts
     .Pq Vt str
     List of executables and/or rc scripts to run after firewall starts/stops.
    
    From b8fde9ef742a7750f2786e79c412b057563828ff Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Sat, 17 Apr 2010 09:37:08 +0000
    Subject: [PATCH 2000/2592] MFC r206623: ld_gs_base is executing with stack
     containing only the frame, temporary pushed %rflags has been popped already.
    
    ---
     sys/amd64/amd64/exception.S | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
    index 69288f38d0b..65c6452c873 100644
    --- a/sys/amd64/amd64/exception.S
    +++ b/sys/amd64/amd64/exception.S
    @@ -815,7 +815,6 @@ fsbase_load_fault:
     	ALIGN_TEXT
     	.globl	gsbase_load_fault
     gsbase_load_fault:
    -	popfq
     	movl	$T_PROTFLT,TF_TRAPNO(%rsp)
     	movq	%rsp, %rdi
     	call	trap
    
    From e747dbab7547805f87150ffb9ddef14c46ec8711 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Sat, 17 Apr 2010 11:06:42 +0000
    Subject: [PATCH 2001/2592] MFC r205860,206097: correctly set b_offset for
     getblk(devvp)
    
    ---
     sys/kern/vfs_bio.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
    index df9a257af3b..4e9cfc69957 100644
    --- a/sys/kern/vfs_bio.c
    +++ b/sys/kern/vfs_bio.c
    @@ -2678,7 +2678,7 @@ loop:
     		 */
     		if (flags & GB_NOCREAT)
     			return NULL;
    -		bsize = bo->bo_bsize;
    +		bsize = vn_isdisk(vp, NULL) ? DEV_BSIZE : bo->bo_bsize;
     		offset = blkno * bsize;
     		vmio = vp->v_object != NULL;
     		maxsize = vmio ? size + (offset & PAGE_MASK) : size;
    
    From 0866329b6e3b95c29d5e2dba567299ebd4bd942b Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Sat, 17 Apr 2010 11:25:30 +0000
    Subject: [PATCH 2002/2592] MFC r206129: vn_stat: use va_blocksize when setting
     st_blksize
    
    ---
     sys/kern/vfs_vnops.c | 5 ++---
     1 file changed, 2 insertions(+), 3 deletions(-)
    
    diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
    index d0b713cb310..7ea2f4317af 100644
    --- a/sys/kern/vfs_vnops.c
    +++ b/sys/kern/vfs_vnops.c
    @@ -788,11 +788,10 @@ vn_stat(vp, sb, active_cred, file_cred, td)
     	 *   "a filesystem-specific preferred I/O block size for this 
     	 *    object.  In some filesystem types, this may vary from file
     	 *    to file"
    -	 * Default to PAGE_SIZE after much discussion.
    -	 * XXX: min(PAGE_SIZE, vp->v_bufobj.bo_bsize) may be more correct.
    +	 * Use miminum/default of PAGE_SIZE (e.g. for VCHR).
     	 */
     
    -	sb->st_blksize = PAGE_SIZE;
    +	sb->st_blksize = max(PAGE_SIZE, vap->va_blocksize);
     	
     	sb->st_flags = vap->va_flags;
     	if (priv_check(td, PRIV_VFS_GENERATION))
    
    From 7ca64047c219c5ec03ab728fa24ae744054a7309 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Sat, 17 Apr 2010 11:57:41 +0000
    Subject: [PATCH 2003/2592] MFC r206130: g_vfs_open: allow only one mount per
     device vnode
    
    ---
     sys/geom/geom_vfs.c | 7 ++++++-
     1 file changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c
    index a35cc2c7ba1..880bfdcdc49 100644
    --- a/sys/geom/geom_vfs.c
    +++ b/sys/geom/geom_vfs.c
    @@ -163,6 +163,10 @@ g_vfs_open(struct vnode *vp, struct g_consumer **cpp, const char *fsname, int wr
     	g_topology_assert();
     
     	*cpp = NULL;
    +	bo = &vp->v_bufobj;
    +	if (bo->bo_private != vp)
    +		return (EBUSY);
    +
     	pp = g_dev_getprovider(vp->v_rdev);
     	if (pp == NULL)
     		return (ENOENT);
    @@ -178,7 +182,7 @@ g_vfs_open(struct vnode *vp, struct g_consumer **cpp, const char *fsname, int wr
     	vnode_create_vobject(vp, pp->mediasize, curthread);
     	VFS_UNLOCK_GIANT(vfslocked);
     	*cpp = cp;
    -	bo = &vp->v_bufobj;
    +	cp->private = vp;
     	bo->bo_ops = g_vfs_bufops;
     	bo->bo_private = cp;
     	bo->bo_bsize = pp->sectorsize;
    @@ -198,5 +202,6 @@ g_vfs_close(struct g_consumer *cp)
     	gp = cp->geom;
     	bo = gp->softc;
     	bufobj_invalbuf(bo, V_SAVE, 0, 0);
    +	bo->bo_private = cp->private;
     	g_wither_geom_close(gp, ENXIO);
     }
    
    From 55f05ae7e57f111030e935f82d126374b6e6c6fd Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Sat, 17 Apr 2010 17:40:12 +0000
    Subject: [PATCH 2004/2592] MFC r206456:  Honor the CE bit even when the CWR
     bit is set.
    
     PR:		145600
     Submitted by:	Richard Scheffenegger 
    ---
     sys/netinet/tcp_input.c | 6 ++----
     1 file changed, 2 insertions(+), 4 deletions(-)
    
    diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
    index 09f834bcabd..d01549152dd 100644
    --- a/sys/netinet/tcp_input.c
    +++ b/sys/netinet/tcp_input.c
    @@ -1134,6 +1134,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
     	 * TCP ECN processing.
     	 */
     	if (tp->t_flags & TF_ECN_PERMIT) {
    +		if (thflags & TH_CWR)
    +			tp->t_flags &= ~TF_ECN_SND_ECE;
     		switch (iptos & IPTOS_ECN_MASK) {
     		case IPTOS_ECN_CE:
     			tp->t_flags |= TF_ECN_SND_ECE;
    @@ -1146,10 +1148,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
     			TCPSTAT_INC(tcps_ecn_ect1);
     			break;
     		}
    -
    -		if (thflags & TH_CWR)
    -			tp->t_flags &= ~TF_ECN_SND_ECE;
    -
     		/*
     		 * Congestion experienced.
     		 * Ignore if we are already trying to recover.
    
    From 9fd42adec727b2cde9870fdf5c8336cd0f654ba9 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Sat, 17 Apr 2010 22:52:33 +0000
    Subject: [PATCH 2005/2592] MFC r197724:   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 15932fc82d4b6677ed4cbceb888e2361c29809e5 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Sat, 17 Apr 2010 22:57:07 +0000
    Subject: [PATCH 2006/2592] MFC r198195:   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 52c92a07d07ffd7cf613f3267362adfe208d3642 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Sat, 17 Apr 2010 23:04:42 +0000
    Subject: [PATCH 2007/2592] MFC r202607:   Fixes a firmware bug that in some
     devices (e.g. Netgear WG111T or   TRENDnet TEW-504UB/EU) idProduct didn't be
     decreased after loading the   firmware.
    
      Pointed by:	Steven Friedrich 
      Submitted by:	sam
    ---
     sys/contrib/dev/uath/ar5523.bin.uu | 6223 ++++++++++++++--------------
     1 file changed, 3156 insertions(+), 3067 deletions(-)
    
    diff --git a/sys/contrib/dev/uath/ar5523.bin.uu b/sys/contrib/dev/uath/ar5523.bin.uu
    index 6fa430dfde1..591c87ed255 100644
    --- a/sys/contrib/dev/uath/ar5523.bin.uu
    +++ b/sys/contrib/dev/uath/ar5523.bin.uu
    @@ -59,34 +59,34 @@ M````````````````````````````````````````````````````````````
     M````````````````````````````````````````````````````````````
     M``````!`@&@``````#P"$``T0O\`0()@`````````````````"0"``)`@H``
     M`````````````````^`((3P:@``G6@MT/!^``"?_!&0#7]`B!!$``0`````#
    -M7]`@`"#X(0-`^`D``````^`((3P:@`(G6D:X/!^``"?_!)0#7]`B!!$``0``
    +M7]`@`"#X(0-`^`D``````^`((3P:@`(G6E98/!^``"?_!)0#7]`B!!$``0``
     M```#7]`@`"#X(0-`^`D`````0`)@```````\`___-&,`_P!#$"1`@F``````
    -M````````````/`2``B2$5_``@.@A/`$?_S0A__\#H>@D/`&@``.AZ"5`!(``
    -M`````````````````^`((3P:@`(G6J6$/!^``"?_!1@#7]`B!!$``0`````#
    -M7]`@`"#X(3P!'_\T(?__`T'0)#P!H``#0=`E`T#X"0`````\'(`#)YS&L#P$
    -M@`(DA%?P`(#H(3P(@``\"8``)2D!P#P+@``E:P'DC2(``"$I``2M`@``(0@`
    +M````````````/`2``B2$9Y``@.@A/`$?_S0A__\#H>@D/`&@``.AZ"5`!(``
    +M`````````````````^`((3P:@`(G6JL0/!^``"?_!1@#7]`B!!$``0`````#
    +M7]`@`"#X(3P!'_\T(?__`T'0)#P!H``#0=`E`T#X"0`````\'(`#)YS64#P$
    +M@`(DA&>0`(#H(3P(@``\"8``)2D!P#P+@``E:P'DC2(``"$I``2M`@``(0@`
     M!!4K__L`````-`0`$#P%@``DI09T/`:``"3&`@"LQ0``(,8`!""$__\4@/_\
     M`````#P$@``DA`(`/`6``"2E!X"LA0``/`6``"2E"RBLA0`D/`6``"2E!G2L
    -MA0"`K(4`A*R%`(@,``*L``````P`:5H`````#`!J>P`````,`&D:``````@`
    -M;<\\'P``$````0````!`&F``/!O__S=[__`#6]`D0)I@````````````````
    +MA0"`K(4`A*R%`(@,``*L``````P`:KT`````#`!KW@`````,`&I]``````@`
    +M;S(\'P``$````0````!`&F``/!O__S=[__`#6]`D0)I@````````````````
     M`$`:\`````````````````!`FG``````````````````0!I@`#P;_[\W>___
     M`UO0)$":8``D&@"(/!N``"=[`@"/>P"(`V``"``````#H-@A([W^L*^Z`(BO
     MH```KZ$`!*^B``BOHP`,KZ0`$*^E`!2OI@`8KZ<`'*^H`""OJ0`DKZH`**^K
     M`"ROK``PKZT`-*^N`#BOKP`\K[``0*^Q`$2OL@!(K[,`3*^T`%"OM0!4K[8`
     M6*^W`%RON`!@K[D`9*^\`'"OO@!XK[\`?```(!```"@2KZ0`@*^E`(2ONP!T
     M0`AH`$`)8`!`"C@`0`M``$`,&`!`#7@`0`YP`*^H`)BOJ0",KZH`E*^K`)RO
    -MK`"DKZT`H*^N`)`\'(`#)YS&L`.@@"$CO?_@0!I@`#P;__\W>__P`UO0)$":
    -M8``````````````````,`&D.`@`@(0@``DT``````Z#8(2.]_K"ON@"(KZ``
    +MK`"DKZT`H*^N`)`\'(`#)YS64`.@@"$CO?_@0!I@`#P;__\W>__P`UO0)$":
    +M8``````````````````,`&IQ`@`@(0@``DT``````Z#8(2.]_K"ON@"(KZ``
     M`*^A``2OH@`(KZ,`#*^D`!"OI0`4KZ8`&*^G`!ROJ``@KZD`)*^J`"BOJP`L
     MKZP`,*^M`#2OK@`XKZ\`/*^P`$"OL0!$K[(`2*^S`$ROM`!0K[4`5*^V`%BO
     MMP!*^_`'P``"`0```H$J^D`("OI0"$K[L`=$`)
    -M8`!`"C@`0`MP`*^I`(ROJ@"4KZL`D#P<@`,GG,:P/`*``B1"1E2,1```((0`
    +M8`!`"C@`0`MP`*^I`(ROJ@"4KZL`D#P<@`,GG-90/`*``B1"5?2,1```((0`
     M`:Q$```#H(`A)[W_X$`#8```````0`)H````````0Q`D``(2@C!"`'\\`X``
     M)&,*/`!#$""`4@```D"((20!``02(0`#`````!````P`````/!&@P#8Q`!".
     M,0``,C$`?SP#@``D8PH\`'$8((!Q```F,0`&`B"0(0``````$8B`0!I@`#P;
    -M__\W>__P`UO0)$":8``````````````````\"H`")4HQ>`%14""-2@``/`6`
    -M`B2E,?``L2@@C*4```)`("$!0/@)``````!`D"$\!8`")*4R:`"Q*"",I0``
    -M`@`P(0P`=7,`0"`A`D`0(2.]`"!``F``/`/__S1C__X`0Q`D0()@````````
    +M__\W>__P`UO0)$":8``````````````````\"H`")4HW(`%14""-2@``/`6`
    +M`B2E-Y@`L2@@C*4```)`("$!0/@)``````!`D"$\!8`")*4X$`"Q*"",I0``
    +M`@`P(0P`=M8`0"`A`D`0(2.]`"!``F``/`/__S1C__X`0Q`D0()@````````
     M`````````(^H`)2/J0"`CZH`A$"(.``!(``1`4``$X^A``2/H@`(CZ,`#(^D
     M`!"/I0`4CZ8`&(^G`!R/J``@CZD`)(^J`"B/JP`LCZP`,(^M`#2/K@`XCZ\`
     M/(^P`$"/L0!$C[(`2(^S`$R/M`!0C[4`5(^V`%B/MP!(^_`'R/NP",-!K_``-:T"<#>M@D0!I@````````````,UK_``-ZV"6/
     MN@"0C[T`=#=[``)`FV``````````````````0)IP````````````````````
     M``]"```8`````````0`"``$``P`!``(``0`$``$``@`!``,``0`"``$`!0`!
     M``(``0`#``$``@`!``0``0`"``$``P`!``(``0`#X``(``````.@&"$`H.@A
    -M([W_X*^C``BOOP`0`(#X"0````"/OP`0C[T`"`/@``@`````/`2``B2$1Z@\
    -M!8`#)*6B'#"&``,4P``2``````"D.",`!SE"``P(``WK8((][```#8``(`````#0:`"0(
    @@ -111,7 +111,7 @@ MGP`LC)X`*(R<`"2,EP`@C)8`'(R5`!B,E``4C),`$(R2``R,D0`(C)``!(R=
     M```#X``(`*`0(0`````GO?_PK[\```P``TL``$`AC[\```/@``@GO0`0)[W_
     M\*^R``BOLP`,K[$`!*^P````P$@A`0"0(0#@6"$`H'`A%,`!``"`4"$`AQ`K
     M$$``9#0"__\`1Q`K%$``60#@*"$D`@`(+.,!``!`,"$``S`+/`.``@#%$`8D
    -M8Q9\`$,0(9!$```D`@`@`(8@(0!$.",0X``(``LT`@!'$",`3A`&`.H8!`!B
    +M8QP<`$,0(9!$```D`@`@`(8@(0!$.",0X``(``LT`@!'$",`3A`&`.H8!`!B
     M4"4`ZU@$`.YP!``+-`(!1@`;,6K__P`.)`)0P``!```!S0``$!(``!@0``,<
     M``!D&"4``"@2``````````!P2D@"`&D0*U!```L`:1@C`&L8(0!K$"L40``&
     M)*7__P!I$"M00``$`&D8(R2E__\`:Q@A`&D8(P!F`!M0P``!```!S3'$__\`
    @@ -120,7 +120,7 @@ M&"$`:Q`K%$``!B3&__\`:1`K$$``!``%%```:Q@A),;__P`%%```1C`E`&EP
     M(P``F"$20``$`.[(!@``P"&N6```KED`!`)@$"&/L@`(C[,`#(^Q``2/L```
     M`,`8(0/@``@GO0`0/`(`_S1"__\D`P`0`$<0*R0$`!@`8#`A$`#_I0"",`L4
     MX``*`$L0*R0"``$`1@`;4.```0```",!2U`C)!,``0`+9`(Q:/__`4P`&P`.+`)1@``!
     M```!S0``(!(``!@0``,<``!E&"4``&@2``````````!PB$@"`&D0*U!```L`
     M:1@C`&L8(0!K$"L40``&)(W__P!I$"M00``$`&D8(R6M__\`:Q@A`&D8(P!L
    @@ -134,7 +134,7 @@ M``,<``!D&"4``#`2``````````!P4T@"`&D0*Q!```L`#Q0``&L8(0!K$"L4
     M0``&),;__P!I$"L00``$``\4`"3&__\`:Q@A``\4``!&F"40`/^.`&E0(S1"
     M__\D`P`0`$L0*R0$`!@`8"@A$`#_>0""*`L`AA`K$$``!S0"__\``#`A``"8
     M(1$`_U$`H,@A$`#_30%`P"$`1A`K%$``?#P"`/\D`@`(+,,!``!`*"$``R@+
    -M/`.``@"I$`8D8Q9\`$,0(9!$```D`@`@`(4@(0!$.",4X``1`$=X(P$J$"L4
    +M/`.``@"I$`8D8QP<`$,0(9!$```D`@`@`(4@(0!$.",4X``1`$=X(P$J$"L4
     M0``%`H@!@",`!LQ,___`>X0
     M!@#J&`0`8E`E``HL`E&```$```'-`.M8!```,!(``"`0``0D``"%&"4``$`2
    @@ -148,7 +148,7 @@ M(",!I!`K`8D8(P!B8",`@&@A$`#_[B3&__\T0O__)`,`$`!&$"LD!``8`&`H
     M(1``_X,`@B@+)[W_X*^_`!`,``3L`Z!`(8^B``"/HP`$C[\`$`/@``@GO0`@
     M)[W_\*^R``BOLP`,K[$`!*^P````P$@A`0"0(0#@6"$`H'`A%,`!``"`4"$`
     MAQ`K$$``9#0"__\`1Q`K%$``60#@*"$D`@`(+.,!``!`,"$``S`+/`.``@#%
    -M$`8D8Q9\`$,0(9!$```D`@`@`(8@(0!$.",0X``(``LT`@!'$",`3A`&`.H8
    +M$`8D8QP<`$,0(9!$```D`@`@`(8@(0!$.",0X``(``LT`@!'$",`3A`&`.H8
     M!`!B4"4`ZU@$`.YP!``+-`(!1@`;,6K__P`.)`)0P``!```!S0``$!(``!@0
     M``,<``!D&"4``"@2``````````!P2D@"`&D0*U!```L`:1@C`&L8(0!K$"L4
     M0``&)*7__P!I$"M00``$`&D8(R2E__\`:Q@A`&D8(P!F`!M0P``!```!S3'$
    @@ -157,7 +157,7 @@ M``!K&"$`:Q`K%$``!B3&__\`:1`K$$``!``%%```:Q@A),;__P`%%```1C`E
     M`&EP(P``F"$20``$`.[(!@``P"&N6```KED`!`)@$"&/L@`(C[,`#(^Q``2/
     ML````,`8(0/@``@GO0`0/`(`_S1"__\D`P`0`$<0*R0$`!@`8#`A$`#_I0""
     M,`L4X``*`$L0*R0"``$`1@`;4.```0```",!2U`C)!,``0`+9`(Q:/__`4P`&P`.+`)1
     M@``!```!S0``(!(``!@0``,<``!E&"4``&@2``````````!PB$@"`&D0*U!`
     M``L`:1@C`&L8(0!K$"L40``&)(W__P!I$"M00``$`&D8(R6M__\`:Q@A`&D8
    @@ -171,7 +171,7 @@ M`!@0``,<``!D&"4``#`2``````````!P4T@"`&D0*Q!```L`#Q0``&L8(0!K
     M$"L40``&),;__P!I$"L00``$``\4`"3&__\`:Q@A``\4``!&F"40`/^.`&E0
     M(S1"__\D`P`0`$L0*R0$`!@`8"@A$`#_>0""*`L`AA`K$$``!S0"__\``#`A
     M``"8(1$`_U$`H,@A$`#_30%`P"$`1A`K%$``?#P"`/\D`@`(+,,!``!`*"$`
    -M`R@+/`.``@"I$`8D8Q9\`$,0(9!$```D`@`@`(4@(0!$.",4X``1`$=X(P$J
    +M`R@+/`.``@"I$`8D8QP<`$,0(9!$```D`@`@`(4@(0!$.",4X``1`$=X(P$J
     M$"L40``%`H@!@",`!LQ,___
     M`>X0!@#J&`0`8E`E``HL`E&```$```'-`.M8!```,!(``"`0``0D``"%&"4`
    @@ -183,173 +183,173 @@ M`&`0````````````K!`K``!H$@``````````%$``$`&K(",1A0`,`]`"`G
    -MO?_0K[``$`"`@"$D!`!`.@*"$00``+`$"(
     M(5:```&ND0``C[\`)(^T`""/LP`]`#"/H@``
    -M`$`@(0P`!L^N8@`$%$#_\0!`B"$,`!FN`F`@(11`_^T`0(@A#``2D`)@("$4
    -M0/_I`$"((0P`&=D"8"`A`$"0(1!`_^0D$0`"C[````!`("$,`!G1)`4'(`!`
    -MB"$D`@<@K@(;[`)`*"$"8"`A#``<@JYR```\`X`"K'-'J!``_]6N8@`()[W_
    -M\*^P``"OOP`$#``4GP"`@"$"`"`A#``4K```*"$00``&)`,`%H^_``2/L```
    -M`&`0(0/@``@GO0`0#``?*P(`("$`0!@A)@4;<`(`("$40/_U)`8``0P`-X4`
    -M`````$`8(20%``$40/_O`@`@(0P`%*P`````)`,`%A``_^H``A@*K*0`!`/@
    -M``BLX```)[W_H*^S`$P`H)@A```H(:^Q`$2OOP!0K[(`2*^P`$`,`!2L`("(
    -M(11``!6OH@`PCB(7W!1``"T#H"`A#`!Z=0````"/I@`@CZ4`'#P$@`(DT,0`
    -M`!`7P@("$"$``I!##`!P="2$"(@"("`A#``)M@)`*"&OH@`P$$``"P.@("$2
    -M8``"CZ(`,*YB``"/OP!0C[,`3(^R`$B/L0!$C[``0`/@``@GO0!@#`!Z=0``
    -M``"/H@`@`B`@(210Q``,``RQ`@`H(3P$@`(DA`BD`@`H(0)`,"$40/_JKZ(`
    -M,`P`<'0`````)`(``:XB%]P"("`A#``'5R>E`#"/H@`P4$#_X*X@%^@0`/_>
    +M`$`@(0P`!L^N8@`$%$#_\0!`B"$,`!G!`F`@(11`_^T`0(@A#``2E`)@("$4
    +M0/_I`$"((0P`&>P"8"`A`$"0(1!`_^0D$0`"C[````!`("$,`!GD)`4'(`!`
    +MB"$D`@<@K@(;\`)`*"$"8"`A#``E`#"/H@`P4$#_X*X@%^@0`/_>
     M`````">]_^"OL0`4K[``$*^_`!B,@Q?@)`(``0"@B"$`@(`A`Z`H(1!B``NO
     MH```$B``!JX`%^B/OP`8C[$`%(^P`!`#X``()[T`((^B```0`/_YKB(```P`
    -M!Y4`````CZ(``!1`__("`"`A#`!1E``````"`"`A#``4K"0%``$0`/_K````
    -M`">]_^"OL@`(`*"0(0``*"&OLP`,K[$`!*^P``"OOP`0#``4K`"`@"$D$P`!
    +M!Y4`````CZ(``!1`__("`"`A#`!2K``````"`"`A#``4L"0%``$0`/_K````
    +M`">]_^"OL@`(`*"0(0``*"&OLP`,K[$`!*^P``"OOP`0#``4L`"`@"$D$P`!
     M`$"((1!```L"`"`A$D```JX`%^BN40``C[\`$(^S``R/L@`(C[$`!(^P```#
    -MX``()[T`(*X`&QP,``A^KA,;)`P`"A@"`"`A#`!Q7``````D8P#(+&4`R(X$
    -M&`@`11`A`$`P(20(```D"0#(#`!Q=`!@."$,`'%<`````"1C`,@L90#(C@08
    -M0`!%$"$`0#`A)`@``"0)`,@,`'%T`&`X(8X"``0,`!T8C$0```(`("$,`"D\
    +MX``()[T`(*X`&QP,``A^KA,;)`P`"A@"`"`A#`!ROP`````D8P#(+&4`R(X$
    +M&`@`11`A`$`P(20(```D"0#(#`!RUP!@."$,`'*_`````"1C`,@L90#(C@08
    +M0`!%$"$`0#`A)`@``"0)`,@,`'+7`&`X(8X"``0,`!TKC$0```(`("$,`"E6
     M/`6```P`!_8"`"`AKA,7X!``_]$`````)[W_\*^R``BOL0`$K[```*^_``R,
     M@A?@)!(``0"@B"$`@(`A$%(`"@``*"$2(``"KA(7Z*X@``"/OP`,C[(`"(^Q
    -M``2/L````^``"">]`!`,`!2L`````#P%@``,`"EL`@`@(0P`<7N.!!@(#`!Q
    -M>XX$&$`,``LT`@`@(0P`$7<"`"`A#``(E0(`("$D!0`!#``*2`(`("$,``@'
    -M`@`@(8X"``0,`!T*C$0``*X`%^`0`/_>`````">]__"OL````*"`(:^Q``0`
    -MP"@A`("((0(`("&OOP`,K[(`"`P`!S8`P)`A#`!1E`(`("$"("`A)`4`"```
    -M,"$,`!$9)`<``59```&N0```C[\`#(^R``B/L0`$C[````/@``@GO0`0)[W_
    -M\*^Q``2OL````("((0"@@"&OOP`(#``4;20%``$"("`A$@``"SP%``0,`"D\
    -M``````(@("$,`!1M```H(8^_``B/L0`$C[````/@``@GO0`0#``I;#P%``00
    -M`/_V`B`@(2>]__`D`@`!K((]`!`,`!2P`````#P%@``,`"F&`@`@(0P``````">]__"OL````*"`(:^Q``0`
    +MP"@A`("((0(`("&OOP`,K[(`"`P`!S8`P)`A#`!2K`(`("$"("`A)`4`"```
    +M,"$,`!$=)`<``59```&N0```C[\`#(^R``B/L0`$C[````/@``@GO0`0)[W_
    +M\*^Q``2OL````("((0"@@"&OOP`(#``4<20%``$"("`A$@``"SP%``0,`"E6
    +M``````(@("$,`!1Q```H(8^_``B/L0`$C[````/@``@GO0`0#``IACP%``00
    +M`/_V`B`@(2>]__`D`@`!K((]_]"OM0`4`*"H(20%``&OOP`@K[<`
    -M'*^V`!BOM``0K[,`#`$`H"$`X)@AK[(`"*^Q``0`P)`A`("((:^P```,`!1M
    -M/!:``CP0@`(FI``0/!>``@``*"&N$C.`KM,SA`P`:S2N]#.(`J`@(0P`:S0D
    -M!0`!CB4``(X$,X`\`O_QC*-`$#1"__\`!"1``&(8)#P"``X`@B`D`&08):RC
    -M0!".)0``CL0SA#P"_X^,HT`0-$+__P`$)0``8A@D/`(`<`""("0`9!@EK*-`
    -M$(XE``".Y#.(/`+_?XRC0!`T0O__``0EP`!B&"0\`@"``((@)`!D&"6LHT`0
    -M`B`@(0P`%&T``"@AC[\`((^W`!R/M@`8C[4`%(^T`!"/LP`,C[(`"(^Q``2/
    -ML````^``"">]`#`GO?_PK[```"0&``0`@(`AK[\`!`P`-@X``"@A#`!1O28$
    -M'8P00``'`@`@(0P`-;2,10`D#``UN`(`("$,`#7H`@`@(0P`<=`F!!K(C[\`
    -M!(^P```#X``()[T`$">]__```"@A)`8``Z^P``"OOP`$#``V#@"`@"$,`''"
    -M)@0:R`P`<+4`````#``U_0(`("$,`#6_`@`@(0P`<+H`````#``(VP(`("$D
    +M'*^V`!BOM``0K[,`#`$`H"$`X)@AK[(`"*^Q``0`P)`A`("((:^P```,`!1Q
    +M/!:``CP0@`(FI``0/!>``@``*"&N$CDHKM,Y+`P`;)>N]#DP`J`@(0P`;)]`#`GO?_PK[```"0&``0`@(`AK[\`!`P`-F$``"@A#`!2U28$
    +M'9`00``'`@`@(0P`-@>,10`D#``V"P(`("$,`#8[`@`@(0P`]__```"@A)`8``Z^P``"OOP`$#``V80"`@"$,`',E
    +M)@0:R`P`]`!",I0`H)`/_\#"B``\D0@`G`$,X)`"C
     M&"0`9Q`A`$,0*Q1```<`8#`AO'$``"1C`!``QQ`A`$,0*Q!`__L`````D*(`
    -M`"0#`(`P0@#\4$,`!)2C`!0``"`A`^``"`"`$"&4@AQ>5&+__```("&4HP`2
    -ME((<7%1B__@``"`AE((<6I2C`!`48O_S)`0``1``__(`````C((:_(Q#```#
    +M`"0#`(`P0@#\4$,`!)2C`!0``"`A`^``"`"`$"&4@AQB5&+__```("&4HP`2
    +ME((<8%1B__@``"`AE((<7I2C`!`48O_S)`0``1``__(`````C((:_(Q#```#
     MX``(K(,:_(R"&ORLH@```^``"*R%&OPGO?_@)`(``:^P``"OOP`,
    +MK((`)%*@``&N!Q?`C@(`!`)`*"$,`!K:C$0``!(@``0"("@AC@(`!`P`&MJ,
     M1```H@`:^!``_XBN`!KT#``(TP(`("$`0(@AD@(:^"8E``0D0@`!HB(``"0"
     M``.B(@`!)`(`0!``_\2F(@`"D@,:^`)`*"$D8@`!H@(:^))"``&B0P``,$(`
    -M_J)"``&.`@`$#``:QXQ$```0`/]P)A8=C`P`"*X"`"`A$`#_F*X"&MR/OP`<
    +M_J)"``&.`@`$#``:VHQ$```0`/]P)A8=D`P`"*X"`"`A$`#_F*X"&MR/OP`<
     MC[8`&(^U`!2/M``0C[,`#(^R``B/L0`$C[````"`$"$#X``()[T`(">]__"O
    -ML0`$K[````#`B"$`H(`A)`4``:^_``ROL@`(#``4;0"`D"$"`"`A#``W=`(@
    -M*"$"`#`A`@`H(0P`4=@F1!V,`D`@(0P`%&T``"@AC[\`#(^R``B/L0`$C[``
    +ML0`$K[````#`B"$`H(`A)`4``:^_``ROL@`(#``4<0"`D"$"`"`A#``WQP(@
    +M*"$"`#`A`@`H(0P`4O`F1!V0`D`@(0P`%'$``"@AC[\`#(^R``B/L0`$C[``
     M``/@``@GO0`0)[W_\*^_``"0H@`!,$(``A!```8DI_^D#``(UP````"/OP``
    -M`^``"">]`!"@H```H*```8R&&^RDH``"`.`H(0P`"8@DQO_\$`#_]H^_```G
    -MO?_0K[\`(*^W`!ROM@`8K[,`#*^Q``2OL```K[4`%*^T`!"OL@`(C((;[`"`
    -MF"$DA!V,)%``H`"P`!JN8!M44@```0```]`#!RT!@")`(``:YB';0D<``0#`!Z5P(`("$0
    -M0``R`$"((0!`("$``"@A`@`P(0!`D"$,`'"J)C4`8`+V$"JN<1JX`B"@(:YP
    -M&KP00``5`J"((0+`@"&.9AOLKE0`)*Y5`"BN40`$`D`H(0)@("$,``F(),;_
    -M_(YB&^PF$/__`B(H(0)"&"$"HB`A`H(0(21R`%PDE0!<)%0`7!8`_^XDL0!<
    +M`^``"">]`!"@H```H*```8R&&_"DH``"`.`H(0P`"8@DQO_\$`#_]H^_```G
    +MO?_0K[\`(*^W`!ROM@`8K[,`#*^Q``2OL```K[4`%*^T`!"OL@`(C((;\`"`
    +MF"$DA!V0)%``H`"P`!JN8!M44@```0```]`#!RT!@")`(``:YB';@D<``0#`![N@(`("$0
    +M0``R`$"((0!`("$``"@A`@`P(0!`D"$,`'(-)C4`8`+V$"JN<1JX`B"@(:YP
    +M&KP00``5`J"((0+`@"&.9AOPKE0`)*Y5`"BN40`$`D`H(0)@("$,``F(),;_
    +M_(YB&_`F$/__`B(H(0)"&"$"HB`A`H(0(21R`%PDE0!<)%0`7!8`_^XDL0!<
     M)I$`$!K```BN8!K\`L"`(0(@*"$"8"`A#``(UR80__\6`/_[)C$`1"9P&L@,
    -M`'&T`@`@(0P`<]__"OL````("`(:^_
    -M``0,`''0)(0:F`P`<=`F!!J$)`(``:X"&K2/OP`$C[````/@``@GO0`0)[W_
    +M`',7`@`@(0P`]__"OL````("`(:^_
    +M``0,`',S)(0:F`P`]
    -M__"OL0`$`("((:X@&K0DA!J$K[\`"*^P```,`''"`*"`(0P`<<(F)!J8$@``
    +M`!#D`D`@(28Q__\&(?_M)A`!'(^_``R/L@`(C[$`!(^P```#X``()[T`$">]
    +M__"OL0`$`("((:X@&K0DA!J$K[\`"*^P```,`',E`*"`(0P`LC@,`.*X@```"0A`JKA$`.*QQ```40/_N
    -MKB,`!"8$`"0,`'&'```H(0)@$"&/OP`0C[,`#(^R``B/L0`$C[````/@``@G
    -MO0`@$`#_]R03``(GO?_PK[$`!*^_``BOL```C)``!`P`<+4`H(@AC@0`-(R%
    +ML@`(K[```#P"@`*OOP`0K[$`!(Q%5TPD@P`T)((`+`"`@"&L@@`PK(,`.*R`
    +M`"RL@``T``"0(1B@`!0``)@A#`![NB0$``PF4@`!`$"((0!`("$``"@A$$``
    +M%R0&``P,`'(-`````#P"@`*,0E=,C@,`.*X@```"0A`JKA$`.*QQ```40/_N
    +MKB,`!"8$`"0,`'+J```H(0)@$"&/OP`0C[,`#(^R``B/L0`$C[````/@``@G
    +MO0`@$`#_]R03``(GO?_PK[$`!*^_``BOL```C)``!`P`]`"`,``L3`D`@(1!`__<`
     M0"@A,$(`#R1"`"LD`__P`$,P)`"C&"0`9A`A`$,0*Q1```<`8"`AO'$``"1C
     M`!``AA`A`$,0*Q!`__L`````C*,`""0"`!`08@`*``````P`"H,"`"`ACZ(`
     M`"8Q``$"(A`J%$#_XX^_`!P0`/_=C[(`&`P`"O0"`"`A$`#_]X^B```GO?_P
     MK[(`"*^P``"OOP`,K[$`!(R1``0D`@`!``"`(0(@("&N(A?8#``*@R8R&JP"
    -M0"`A#`!QAP``*"$,``ZZ`B`@(2H#``440``.)A```5!@``TF,!J8#`!Q7```
    -M```D8P!D+&0`9`!$$"$`0#`A`&`X(0P`<94"0"`A$`#_[P`````F,!J8#`!Q
    -MT`(`("$,`'&C)B07T`P`<8XF)!?(`@`@(:X@%]@,`''"`````(^_``R/L@`(
    +M0"`A#`!RZ@``*"$,``Z^`B`@(2H#``440``.)A```5!@``TF,!J8#`!ROP``
    +M```D8P!D+&0`9`!$$"$`0#`A`&`X(0P`]_]"OL0`DK[\`+*^R`"BOL``@`*"((8R2``0`
     M`%`A``!P(1"@`'X``'@AC*T`#(RD`!`QH@`/``(8P`!B&",``QC``D,8(20"
     M__\0@@`8)'D8>``$$,``1!`A``(0P`!$$",``A"``D(0(8Q$``@D`P`!KZ,`
     M!!2```X`6!'``&DD`@`&
     MC<,`!%!B`&<``'@A)BG__(XL`!@!((`A)CC_H!$@`#\D!@`<`29`(24J_Z0E
     M"``$K4@`!(TK``"10P`.)`7P```+$"L``A$`,&,`[P!B&"6A0P`.CB(``)5#
    -M``HE9_^D)$+_Y#!"#_\`91@D`&(8):5#``J.0AOLE40`#@`+.`H`1A`C)$+_
    +M``HE9_^D)$+_Y#!"#_\`91@D`&(8):5#``J.0AOPE40`#@`+.`H`1A`C)$+_
     M_`&"&"L!@Q`+`(4@)#!"#_\`@B`EI40`#I5&``ZM)_^DC4(`/"0#_?\`#2E`
     M`$,0)#"E`@``#1E"/`3^_S2$__\`11`E,&,``0!$$"0``QX``$,0):U"`#RM
     M2``HCB,`$##&#_\D`O__)&0`!*U'`""M6``PK4\`4*U.`$P08@`C`89@(ZU$
     M`#@!8$@A%6#_PP``,"$"`$@A$2``#`%`@"$E*O^DC4,`/(TK```\`G__-$+_
    -M_P!B&"0!8$@AK4,`/*U9`%@58/_VK5``+`)`("$#("@A`P`P(0P`#TL``#@A
    +M_P!B&"0!8$@AK4,`/*U9`%@58/_VK5``+`)`("$#("@A`P`P(0P`#T\``#@A
     MCB(`%%!```.N``!4CB(`!*X"`%2/OP`LC[(`*(^Q`"2/L``@`^``"">]`#`D
     M`G__$`#_W:U"`#@``'@A$`#_F0``<"$,``JD`Z`P(:X@``0"0"`A#``*@P(@
    -M*"$0`/_NC[\`+">]_]"OL0`4K[\`(*^S`!ROL@`8K[``$`"`B"$,`'#^C)(`
    -M!`!`("$,`'$!```H(0(@("$,``L3)E,:F`)@("$,`''"`$"`(0)`("$,`!1M
    +M*"$0`/_NC[\`+">]_]"OL0`4K[\`(*^S`!ROL@`8K[``$`"`B"$,`')AC)(`
    +M!`!`("$,`')D```H(0(@("$,``L3)E,:F`)@("$,`',E`$"`(0)`("$,`!1Q
     M)`4``8X#``@D`@`0`@`H(1!B`!X"("`ACD(7X`(`*"$40``6`D`@(0P`"H,`
    -M````)B0`)`P`<:H#H"@ACZ(`````@"$00``$`B`@(0P`"Q,``````$"`(58`
    -M_^N.`P`(#`!QT`)@("$"0"`A#``4;0``*"$0`/_;`B`@(0P`"YX"("`A$`#_
    +M````)B0`)`P`]`"`,`'&T)@0:F#P%@``\!X`"/`B``CP+@`(D!``!)FID$"2E
    -M,.@"(#`A).<(Q"4(6!`E:V08#`!PRR0)#``,`'#DCF1D$!``_^<"0!`A)[W_
    -M\*^P``"OOP`$C((;]`"`@"&,0@!$%$``!20$.@"/OP`$C[````/@``@GO0`0
    -M)`(`!PP`>E>N`AL`)$("`"0#_@``0Q`DK@(=Q!``__2N`AL$)[W_X*^_`!RO
    -MM@`8K[4`%*^T`!"OL@`(K[$`!*^P``"OLP`,C((;[`"`B"$DD!AX)%4`7`"U
    -M`!H\`H`"4J```0```]`"`,`',7)@0:F#P%@``\!X`"/`B``CP+@`(D!``!)FISL"2E
    +M,.@"(#`A).<.5"4(9[`E:W.X#`!R+B0)#``,`')'CF1SL!``_^<"0!`A)[W_
    +M\*^P``"OOP`$C((;^`"`@"&,0@!$%$``!20$.@"/OP`$C[````/@``@GO0`0
    +M)`(`!PP`>[JN`AL`)$("`"0#_@``0Q`DK@(=R!``__2N`AL$)[W_X*^_`!RO
    +MM@`8K[4`%*^T`!"OL@`(K[$`!*^P``"OLP`,C((;\`"`B"$DD!AX)%4`7`"U
    +M`!H\`H`"4J```0```L)E(``0)"$"H40/_X`A6`(1``_]P`````$`#_WB03``(GO?_`K[``,*^_
    -M`#BOL0`TC((;](S+```D#``!C$,`"`%L$`0`@(`A`&(8)!1@`"D`H$@A+*(`
    +M)C`:A`P`]__"OL@`(
    +MH``D$0``!J^@`"@5(``6`````(X"'<@D0AP`KZ(`*`(`("$,`$MR`Z`H(0!`
    +M&"&.`AOXC$(`:`!B$"M40``&KB,`)(^_`#B/L0`TC[``,`/@``@GO0!`#`!S
    +M%P(@("$0`/_YC[\`.%$L_^R.`AW()`+_]P%"$"00`/_IKZ(`!">]__"OL@`(
     MK[$`!*^P``"OOP`,`("`(0``D"$DD1G(C@,:<"0"``$"0A`$`&(8)`)`*"$4
     M8``+`@`@(292``$N0@`&%$#_]B8Q`!R/OP`,C[(`"(^Q``2/L````^``"">]
    -M`!`,`$J'``````(`("$"0"@A#``-%@(@,"$0`/_P)E(``2>]__"OL@`(K[$`
    +M`!`,`$N1``````(`("$"0"@A#``-%@(@,"$0`/_P)E(``2>]__"OL@`(K[$`
     M!*^P``"OOP`,`("`(0``D"$DD1AXC@(:<"0#``$"0Q@$`$,0)%!```DF4@`!
    -MC@(;]`)`*"$"`"`AC$(`"`!#$"040``+)`8`!"92``$N0@`&%$#_\"8Q`#B/
    -MOP`,C[(`"(^Q``2/L````^``"">]`!`,`$JV)E(``0(`("$,`!#@`B`H(1``
    -M__(N0@`&)[W_\*^_``2OL```C*8`.`P`2[4`H(`AC@(`+(^_``2/L```K$``
    +MC@(;^`)`*"$"`"`AC$(`"`!#$"040``+)`8`!"92``$N0@`&%$#_\"8Q`#B/
    +MOP`,C[(`"(^Q``2/L````^``"">]`!`,`$O`)E(``0(`("$,`!#D`B`H(1``
    +M__(N0@`&)[W_\*^_``2OL```C*8`.`P`3,(`H(`AC@(`+(^_``2/L```K$``
     M0`/@``@GO0`0)[W_L*^U`#2OM``PK[,`+*^_`$"OMP`\K[8`.*^R`"BOL0`D
    -MK[``((RR`!0`H*@A`("8(1)``&XDE`2`CD(`/`1!``0``+`ACD(`(!!``.8`
    +MK[``((RR`!0`H*@A`("8(1)``&XDE`2`CD(`/`1!``0``+`ACD(`(!!``.H`
     M0)`ACD(`4%!```6.40`LC$(``%!```&N0`!0CE$`+(XB`$`40``')C<`0`)@
    -M("$,`$VK`B`H(20#``T00P!9C[\`0`)@("$,`!"&`B`H(11``,\D`@`!CB,`
    -M0*Y@&QP08@`&CE``4%(```6.H@`(ZB`#"50P`(EF(<7E!B``.50P`&$`#_VB5"`!"68AQ<%&+_UR5"`!"50P`$
    -MEF(<6E1B_],E0@`0CH(!+"1"``$0`/_TKH(!+`*@*"$,`!`!`B`P(5!`_X6.
    -ML@`4$`#_/8ZB`!P0`/^#KB``0(YB%]A00/^!C[\`0`P`<:,F9!JL$`#_?8^_
    -M`$",@P`4$&``""0$``&,8@`\!$,`!0``("&,8@`@$$```@```````"`A`^``
    -M"`"`$"$GO?_PK[$`!*^_``@`@(@AK[```(XB&\P00``4)(08>`P`#JX`````
    -M)B08L`P`#JX``H`K)B08Z`P`#JX``H`*)B09(`P`#JX``H`*4$```0``@"$"
    -M`!`AC[\`"(^Q``2/L````^``"">]`!`,``ZN`````!``__<``H`K)[W_\*^P
    -M``"OOP`$#`!PM0"`@"&.`AO,)@48>!!```L"`"`A#``-K0`````F!1BP#``-
    -MK0(`("$F!1CH#``-K0(`("$F!1D@`@`@(0P`#:T`````#`!PN@````"/OP`$
    -MC[````/@``@GO0`0C*<`*```2"&0X@`!,$(`!!1``!",J``LD.(`%C!#``]4
    -M8``-C*(`/)4"`$8``"`A``(1`J#B`!>1`@!',$(`#P`"$0``8A`EH.(`%@/@
    -M``@`@!`AC*(`/``"%H(P0@`!5$``#Y#B``&5"0!&D.,`%C$B``\``A$`,&,`
    -M#P!B&"4`"1$"H.,`%J#B`!>,H@`\/`,$``!#$"6LH@`\D.(``3!"``000/_I
    -M`2`@(8T&`"!0P/_F`2`@(8S(`"PD!/_PC,<`*"4#``@P8@`/)$(`)P!D&"0`
    -M1"@D`&40(0!#$"L40``'`&`@(;QQ```D8P`0`(40(0!#$"L00/_[`````(S"
    -M`#P``A:",$(``51```Z0X@`!D.,`%C$B``\``A$`,&,`#P!B&"4`"1$"H.,`
    -M%J#B`!>,P@`\/`,$``!#$"6LP@`\D.(``3!"``140/_8C08`(!``_[T!("`A
    -M)[W_X*^S``P`P)@AK[4`%*^T`!"OL0`$K[```*^_`!BOL@`(`("@(0"@B"$,
    -M`'"U``"H(1)@`$("8(`AC@(`/``"%D(P0@`!%$``58X2`%`20`!4`H`@(8Y"
    -M`%000`!1`````!*@`$R.`@`LC$,``(Q"`""NHP``KJ(`((X&`"PF1`!<`@`H
    -M(:S``""LP```#`!1V`````".0@!X)$(``:Y"`'@2H``"`F"`(8ZP`"!6`/_C
    -MC@(`/!)@`"$`````EB,`-%!@`!&.(@`8CF0`*)""`!8P10`/4*``"Z8@`#0`
    -M`Q$"H((`%Y(B`#60@P`!,$(`#P`"$0``HA`E-&,`"*"#``&@@@`6CB(`&%1`
    -M`!VL4P`@)`(``:XB`"RN,P`4KC4`&`````^.(@`L5$``$(YF`"2.)0`D#`!*
    -MG`*`("$,`'"Z`````(^_`!B/M0`4C[0`$(^S``R/L@`(C[$`!(^P`````!`A
    -M`^``"">]`"".)0`D#`!*E0*`("$0`/_MKB``+(XC`!B.8@`DK&(``!``_^2N
    -M-0`8$`#_N(Q3`"`"@"`A#``-H0(`*"&.@ALX4$``&(XB`!Q2```6CB(`'(X"
    -M`#P``A9",$(``11```D"@"`ACB8`&(XG`#".*``D#`!*_@(`*"%40``*CB(`
    -M'`*`("$,`"EL/`6``(X"`#`"@"`A/`6```P`*3RN(@`PCB(`'"1"``$20``*
    -MKB(`'(XB`"2.1`!0``(0P`!2$"&40P`P)(0``:Y$`%`D8P`!I$,`,!``_Y>.
    -M%0`L)[W_\*^R``BOOP`,K[$`!*^P``",H@!4%$``!P"`D"$DL0!]`!",P@`LC,4`
    -M6`)`("&,4``@K$```*Q``"`,``]+```X(8XB`!P"`#`A)$+__Q1`__2N(@`<
    -M$`#_ZZX@`!@GO?_@K[0`$*^S``ROL0`$K[\`%*^R``BOL```C-``,(RB`"2,
    -MPP!`CA(`4``"$,``H(@A`D(H(20"``(`@*`A$&(`.22S`#".(P`4C&(`/`1"
    -M`"V,8@`@C@(`/#P#`@".!P`L`$,0):X"`#R.(@`]
    -M`""L8````&`H(:XB`!0"@"`A#``*8ZQ@`"`0`/_.C@(`/)2C`#".0@!4)`8`
    -M`:YF``0`0Q`AKD(`5*9C``*.`P`\/`6'_S2E__\``Q;",$(`#R1"``$P0@`/
    -M``(6P`!E&"0`8A@EK@,`/(R"&V@``Q[",&,`#P!#$"M40``%CD(`5(R"&K14
    -M0``1C((%@(Y"`%268P`")`7__R1"__^N0@!4CH(%A"1C__^F8P`")$(``0P`
    -M5NZN@@6$`H`@(0P`#]X"0"@A$`#_QB0"__\D0@`!K((%@(X"`#P``A;",$(`
    -M#Q!&``8`````C@,`*)!B``$T0@`($`#_DJ!B``$,``[T`@`H(1``__BF(@`T
    -M)[W_\*^Q``2OL```K[\`"`"@@"&.`P!`C*4`,"0"``$`@(@A$&(`3HRD`%".
    -M(AMH$$``1@``$"%0@`!%C[\`"(RB`"B00@`!,$(`!!!``"6.`P`@$&``/0``
    -M$"&,<``LC@(`,(Q"`"B00@`6,$(`#Q!``#LF!``(,((`#R0#__`D0@`G`(,@
    -M)`!#*"0`A1`A`$00*Q1```<`@!@AO)$``"2$`!``91`A`$00*Q!`__L`````
    -M`B`@(0(`*"$,`$Z')`8``1!``"$D`O__C@(`,(Q"`"B00@`!,$(`!!1`_]V.
    -M`P`@$&``&0``$"&,<``L)`3_\"8#``@P8@`/)$(`)P!D&"0`1"@D`&40(0!#
    -M$"L40``'`&`@(;QQ```D8P`0`(40(0!#$"L00/_[``````(@("$"`"@A#`!.
    -MAR0&``$D`___``(8"P!@$"&/OP`(C[$`!(^P```#X``()[T`$!``__H``!`A
    -M)[W_T*^Q`"0`H(@AK[(`**^P`""OOP`L#`!PM0"`D"&.,``4$@``&0````".
    -M0@2PCD,$M(X$`%0D8P`!+&4``0!%$"&N0@2PKD,$M!2``!]`!`0`/_JK@(`4`P`<9P`
    -M````)`,``11#__,D!``"$`#_W``````GO?_PK[````"`@"$DA``\K[\`#*^Q
    -M``2OL@`(#`!QC@"@B"$,`'"U`````(X%`$2,HP``$&``'(RB``2L8@`$C*(`
    -M!"8$`%2,L@`($B```ZQ#``",H@`,KB(``(X"`%`D`___K*```*RB``2.`@!0
    -MK*,`"*X%`%"L10``#`!QHZR@``P,`'"Z``````)`$"&/OP`,C[(`"(^Q``2/
    -ML````^``"">]`!`0`/_EK@(`2">]_^"OOP`4K[``$(R0``2OH```)@0`/`P`
    -M<:H#H"@ACZ(```(`("$40``()Z4`!(^B``!40/_X)@0`/(^_`!2/L``0`^``
    -M"">]`"`,`!%+`````!``__>/H@``)[W_\"2E__^OL0`$K[\`#*^R``BOL```
    -M+*(`&0"`B"$00``4C)(`!#P#@`(`!1"`)&,(X`!#$"&,0@```$``"`````",
    -MA```#``;"B0%`!$`0(`A)D8$@`!`("$D!0$X#``;/@````".)```#``:O0(`
    -M*"&/OP`,C[(`"(^Q``2/L````^``"">]`!```#`A`D`@(0P`+H$D!0`"CB0`
    -M``P`&PHD!0`2`$"`(29&!(@`0"`A$`#_ZB0%``B,A```#``;"B0%`!..)```
    -M`$"`(20"`@`0`/_EK@(```P`$ZB,A``$$`#_Y(^_``P,`!/`C(0`!!``_^"/
    -MOP`,)[W_T*^S`!ROOP`@K[(`&*^Q`!2OL``0C)(`!`"`F"$#H"@A`F`@(0P`
    -M$4LF41?L`B`@(0P`<<(`0(`A`D`@(0P`%&TD!0`!CZ8```(`*"$,`!&.`F`@
    -M(0)`("$,`!1M```H(0P`<=`"("`A$`#_[0.@*"$GO?_@K[0`$*^S``ROOP`<
    -MK[8`&*^U`!2OL@`(K[$`!*^P``",D0`$``"@(0``F"&.(A?@5$``"HXB%]PF
    -M,!K(#`!QP@(`("$,`''0`@`@(8XB%^!00/_Z)C`:R(XB%]P00``X`````"8V
    -M&N`,`''"`L`@(8XC'*0D`@`#$&(`-0`````D!0`!`B`@(0P`%&TF,AK()C4:
    -MA`P`<]__"OOP``C*(`!`"@("$``#`A
    -MC$(7Q"0%`!@40``$```X(8^_```#X``()[T`$`P`$1D`````$`#_^X^_```G
    -MO?_P`*`@(0``,"$D!0`9K[\```P`$1D``#@AC[\```/@``@GO0`0)[W_\*^_
    -M``BOL0`$K[```(R0``0,`'%9`("((0!`("$,`'%7)@4;7(X$&UP\!8``)@<8
    -M""8(&!`"(#`A#`!Q822E20P,`'%<`````"1C`,@L90#(C@08"`!%$"$D"```
    -M)`D`R`!`,"$,`'%T`&`X(8X$&UP\!8``)@<80"8(&$@"(#`A#`!Q822E24P,
    -M`'%<`````"1C`,B.!!A`+&4`R`!%$"$`0#`A)`@``"0)`,@,`'%T`&`X(8^_
    -M``B/L0`$C[````/@``@GO0`0)[W_X"2"`$0D@P!,K[$`!`"`B"&OOP`8K[4`
    -M%*^S``ROL@`(K[0`$*^P```DA``\KB(`2*XC`%```"@AKB``1*X@`$PF,P!4
    -M#`!QAXXT``0"8"`A#`!QAP``*"$``*@A``"0(0P`>EH).<)1"4(9+@E:VS``B`P(20)"``,`'#+
    -M)`0``8X$;+@,`'#D/!"``CP%@``\!X`"/`B``CP+@`(F"GE@)*5'-"3G"50E
    -M"&U@)6MY:"0$``$"(#`A#`!PRR0)#``,`'#DC@1Y8`P`$ET"("`A`J`0(8^_
    -M`!B/M0`4C[0`$(^S``R/L@`(C[$`!(^P```#X``()[T`(!``__4D%0`")[W_
    -MT*^P`!``H(`AK[\`(*^S`!ROL@`8`("8(:^Q`!0,`'%"KZ``!`P`*.@"`"`A
    -M%$``$B02``$,`'%0`F`@(20"``$20@`)``````)`$"&/OP`@C[,`'(^R`!B/
    -ML0`4C[``$`/@``@GO0`P#`!Q20)@("$0`/_V`D`0(0(`("$#H"@A#``H[2>F
    -M``0`0(@A,$(``11``%`"`"`A,B(`(%1``$:.`@2$,B((`!1``#X"`"`A,B(`
    -M0!1``#<"`"`A/`(`!`(B$"040``O`@`@(3(B`(`00``2`````(X"&\Q00``B
    -MC@48G(^B``0P0@`(5$``&HX%&42/H@`$,$(`!%1``!*.!1D,CZ(`!#!"``)4
    -M0``*C@48U"0"_W\"(H@D$B#_Q:^@``".`AV$)!(``P!1$"40`/_`K@(=A`P`
    -M2IP"`"`A$`#_]20"_W\,`$J<`@`@(1``_^V/H@`$#`!*G`(`("$0`/_ECZ(`
    -M!(^B``0`LA@$`$,0)!!`_^D`````$`#_[@`````,`"EL/`4`!!``_]`R(@"`
    -M#``I;"0%`$`0`/_(/`(`!`P`2@HD!0`!)`+W_Q``_[\"(H@D`@`@(20%`"`D
    -M0@`!#``I;*X"!(00`/^V,B((``P`*6PD!0`!$`#_KS(B`"`GO?_@K[0`$*^R
    -M``BOL```K[\`%*^S``ROL0`$C,,]
    -M`"`,`#>``````%1```..!``$$`#_Z0)3D"4``#`A```X(0P`$1DD!0`#4$#_
    -MY`)`*"$0`/_A`E.0)2>]__"OL```K[\`!(R"%^`00``/`("`(8R"%]P00``,
    -M)`(``HR#'*008@`))`(``1!B``B/OP`$#`!PM0`````,`##@`@`@(0P`<+H`
    -M````C[\`!(^P```#X``()[T`$">]_]"OL0`DK[\`+*^R`"BOL``@C((7X!!`
    -M`"8`@(@AC((7W!!``",D`@`"C(,)`(``1``_]RN(AL<)[W_X"0#``&OLP`,K[(`"*^Q``2O
    -ML```K[\`$`"@D"$`P)@A`("`(1"C`$8``(@A4*``,(R"'*0D`@`"$*(`$R0"
    -M``,0H@`,`````%(@``&N$ARD5F```:YQ``"/OP`0C[,`#(^R``B/L0`$C[``
    -M``/@``@GO0`@#``4K"0%``(D$0`6$`#_\0`"B`H,`"EL/`6```(`("$,`!2L
    -M```H(201`!8"`"`A#``(E0`"B`HD!0`!#``*2`(`("&.`@`$#``="HQ$```,
    -M`%&4`@`@(0(`("&N`!?@#``I/#P%@``"`"`A#``4K"0%``$0`/_7`````!!#
    -M``D``````@`@(0``*"$,`!2L`````%1`_\\D$0`6$`#_S0````",@A?@4$#_
    -M]P(`("&,@@`$#``=&(Q$```,`''0)@0:X!``__`"`"`AC((7X%1```2,@@`$
    -M`@`@(1``_^LD!0`!#``="HQ$```,`''")@0:X!``__D"`"`A)[W_\*^P```P
    -ML`#_K[\`#*^R``BOL0`$``"0(0P`<+4`@(@A#`!Q-``````2```:CB(]`!`,`#3E)`8``8X#%]PD
    -M$@`6$&``!``"D`J.`A?@$%$`&3P%@``60/_O)`(``8X#'*A08@`/C@(%)`8``1!```0`0)`A)!(`%A9`
    -M_[X"0!`A`@`@(1``_]]__`D@@`4
    -M)(,`'*^R``BOL```K[\`#*^Q``0`@(`AK((`&*R#`""L@``4K(``'```D"$,
    -M`'I7)`0`#`!`B"$2(``1)`(``@(@("$``"@A#`!PJB0&``R.`@`@)E(``2I#
    -M``*N$0`@KB```*XB``048/_PK%$``"8$``P,`'&'```H(0``$"&/OP`,C[(`
    -M"(^Q``2/L````^``"">]`!`GO?_PK[\``(R&`!R,R```$0``$0"`."&,P@`$
    -MK0(`!(SB`!B,PP`$).0`#*S"``2,X@`8K&@``*S%``BLP```K.8`&`P`<:.L
    -M1@``C[\```/@``@GO0`0C,(`!!``__"L@@`@)[W_\*^Q``0`@(@A)(0`#*^_
    -M``@,`'&.K[````P`<+4`````CB0`%(R%```0H``3C((`!*RB``2.(@`@C(,`
    -M!(R0``BL@@`$CB(`(*QE``"N)``@K(```*R```@,`'"ZK$0```(`$"&/OP`(
    -MC[$`!(^P```#X``()[T`$!``_^ZN(@`8,*8`#R>]_?`D`O_P),,`3Z^T`@``
    -M8A@D`*"@(0"B*"0`HQ`AK[$!]*^_`@ROM@((K[4"!*^S`?ROL@'XK[`!\`!%
    -M$"L`@(@AC),`!(R6``"OH`"TKZ``H!1```<`H"`AO+$``"2E`!``@Q`A`$40
    -M*Q!`__L`````CH,``"QB`$%40``1CH(`#`!F$"$D0@`/)`/_\`!#*"0"@Q@D
    -M`&40(0!#$"L40``'`&`@(;QQ```D8P`0`(40(0!#$"L00/_[`````(Z"``P4
    -M0`.[CI``!```J"$F!?__+*(`0Q!``!L\`X`"``40@"1C"80`0Q`AC$(```!`
    -M``@`````)Z4`H">F`*0,`!MH`H`@(0*`("$GI0"@#``;:">F`*@"@"`A)Z4`
    -MH`P`&V@GI@"L`H`@(2>F`+`,`!MH)Z4`H`(@("$"8"@A#``'PR>F`+02H``'
    -M`L`@(8Z"``@"H"@AKJ(`"(^B`+0,`!J]KJ(`#(^_`@R/M@((C[4"!(^T`@"/
    -MLP'\C[(!^(^Q`?2/L`'P`^``"">]`A`"@"`A)Z4`H`P`&V@GI@"XCZ8`N`(@
    -M("$"8"@A#``&\">G`+00`/_D``````)@("$,`%>0)Z4`M!``_]\``````H`@
    -M(2>E`*`,`!MH)Z8`O(^E`+P"8"`A)Z8`P```."$,`%!<)Z@`Q(^E`,`,`!LW
    -M`J`@(8^B`,`00``1CZ4`O`*@("$GI0#(#``;5R>F`,R/I0"\CZ<`R`)@("$G
    -MI@#0#`!07">H`,2/I0#0`J`@(0P`&V$`````$`#_OP`````"8"`A)Z8`P">G
    -M`-0,`%!<)Z@`Q(^E`-0"H"`A#``;-P`````0`/^T`````">E`*`GI@#8#``;
    -M:`*`("$"@"`A)Z4`H`P`&V@GI@#F`.B/
    -MI0#8CZ<`Z`)@("$0`/_U```P(0*`("$GI0"@#``;:">F`.R/I0#L`F`@(2>F
    -M`/```#@A#`!8(2>H`/2/I0#P#``;-P*@("&/H@#P4$``#H^E`.P"H"`A)Z4`
    -M^`P`&UF`/`GIP$`#`!8(2>H`/2/I0$`$`#_N@*@("$"("`A)`4``0``,"$,
    -M`!$9```X(1``_VH``````F`@(0P`!O,GI0"T/`2``@P`<'0DA`ET$J#_:X^_
    -M`@P,`"YR`F`@(0*@("$0`/^F`$`H(0)@("$,``E`+00`/].`````">E`*`GI@$$
    -M#``;:`*`("$"@"`A)Z4`H`P`&V@GI@$(`H`@(2>E`*`,`!MH)Z8!#`*`("$G
    -MI0"@#``;F`1"/I0$$CZ8!"(^G`1`,`%#?`F`@(1``_S<`````)Z4`H">F
    -M`10,`!MH`H`@(0*`("$GI0"@#``;:">F`1@"@"`A)Z4`H`P`&V@GI@$E`*`,`!MH)Z8!/(^E
    -M`3P"8"`A#``4$">F`+00`/\#``````*`("$GI0"@#``;:">F`42/I0%$#``'
    -MW0)@("$0`/[Z`````">E`*`GI@%(#``;:`*`("$"@"`A)Z4`H`P`&V@GI@%,
    -MCZ4!2(^F`4P,``@6`F`@(1``_NP`````)Z4`H">F`5`,`!MH`H`@(0*`("$G
    -MI0"@#``;:">F`50"@"`A)Z4`H`P`&V@GI@%8`H`@(2>E`*`,`!MH)Z8!7(^E
    -M`5"/I@%4CZF`6`,`!MH`H`@
    -M(0*`("$GI0"@#``;:">F`60GL``0`H`@(2>E`*`,`!MR)Z8!:`(`("$``"@A
    -M#`!PJB0&`!R/HP%DCZ(!:)>E`6("8"`A`@`P(:^B`!2OHP`D#`!/@*^C`!P0
    -M`/ZX``````*`("$GI0"@#``;:">F`6R/I@%L`F`@(0P`3\@``"@A$`#^K@``
    -M```,`!VR`F`@(1``_JH``````H`@(2>E`*`,`!MH)Z8!<(^E`7`,`"F>`F`@
    -M(1``_J$`````)Z0`,```*"$,`'"J)`8`!@*`("$GI0"@#``;:">F`70"@"`A
    -M)Z4`H`P`&V@GI@%X`H`@(2>E`*`,`!MH)Z8!?`*`("$GI0"@#``;F`8"/
    -MI@&`EZ4`-```@"&4QP`4E,0`!"3#``@XX@`'$*0`,P!B@`L`P(@ACZ,!="QB
    -M``040``8``,0P`!#$"$``A#``$,0(P`"$(`"8A`A)$/[F"0"``<0X@`B)`(`
    -M!*1B`18D`@`#$.(`&B0"`!`0X@`8)`(`$5#B`!>48@$6).+__BQ"``(40``"
    -M)`0`""0$``2D9`$8#``(E0)@("&.8AM4`F`@(0(@,"$D0@`!KF(;5(^E`72/
    -MJ`%X#``IO`(`."$,``A^`F`@(1``_ED`````E&(!%B1"``00`/_HI&(!%J1@
    -M`1@0`/_KI&`!%I>C`#*4P@`"%&+_S`#`B"&7HP`PE,(``!1B_\<``(@A$`#_
    -MQX^C`70GI0"@)Z8!A`P`&V@"@"`A`H`@(2>E`*`,`!MH)Z8!B`*`("$GI0"@
    -M#``;:">F`8R/IP&,CZ4!A(^F`8@,`"P_`F`@(8^C`80``A0```(D`RQB``04
    -M0/XQ``,0P`!#$"$``A#``$,0(P`"$(`"8A`A$`#^*J1$_*P"@"`A)Z4`H`P`
    -M&V@GI@%`CZ4!0`P`5W\"8"`A$`#^(0`````GI0"@)Z8!D`P`&V@"@"`A`H`@
    -M(2>E`*`,`!MH)Z8!E`*`("$GI0"@#``;:">F`9@"@"`A)Z4`H`P`&V@GI@&<
    -M)Z4`H">F`9P"@"`A#``;:(^P`9P"@"`A)Z4`H`P`&W(GI@&@CZ8!E(^G`9B/
    -MJ`&@CZD!D`)@("$"`%`A#`!0$@``*"$0`/W^`````">E`*`GI@&D#``;:`*`
    -M("$"@"`A)Z4`H`P`&W(GI@&HCZ4!J`P`+2("8"`A$`#]\0`````GL``X`F`@
    -M(0P`+>T"`"@A`J`@(0(`,"$D!0`(#``;/@`````0`/WF``````P`+@0"8"`A
    -M$`#]X@`````D`@`"KF(;L`P`+A("8"`A$`#]W``````GI0"@)Z8!K`P`&V@"
    -M@"`A`H`@(2>E`*`,`!MH)Z8!L">E`*`GI@&P`H`@(0P`&VB/L`&P`H`@(2>E
    -M`*`,`!MR)Z8!M(^C`:PD`O__$&(`)0`#$,``0Q`A``(0P`!#$"./I0&T``(0
    -M@`)B$"$D1@`0`*88)3!C``,D1``($&``'R2G`"``X!@AB*(``)BB``.(IP`$
    -MF*<`!XBH``B8J``+B*D`#)BI``^HP@``N,(``ZC'``2XQP`'J,@`"+C(``NH
    -MR0`,N,D`#R2E`!`4H__N),8`$("B``"@P@``#`!2Q0(`*"$6`/VACZ4!M`P`
    -M+BX"8"`A$`#]G0````",H@``C*,`!(RH``B,J0`,K,(``*S#``2LR``(K,D`
    -M#"2E`!`4I__V),8`$!``_^H``````H`@(2>E`*`,`!MH)Z8!N(Z"``P00``?
    -MCZ,!N"0"``408@`()`(`!!1B_80"8"`A```P(0P`+H$D!0`$$`#^(0*@("$"
    -M8"`A)Z8`0`P`+H$D!0`%CZ(`0">F`%@"H"`AKZ(`6(^B`$0D!0`4KZ(`7(^B
    -M`$BOH@!@CZ(`3*^B`&27H@!2IZ(`:)>B`%80`/^"IZ(`:H^E`;@"8"`A#``N
    -M@0``,"$0`/UE``````P`+PX"8"`A$`#^`P*@("$GI0"@)Z8!O`P`&V@"@"`A
    -M`H`@(2>E`*`,`!MH)Z8!P(^E`;R/I@'`#``RH0)@("$0`/U3``````P`,XT"
    -M8"`A$`#]3P`````"@"`A)Z4`H`P`&V@GI@'DCZ4!Y`P`,\$"8"`A$`#]1@``
    -M```"@"`A)Z4`H`P`&V@GI@'HCF8<_(^E`>@,`#,5`F`@(1``_3RN8AS\)Z4`
    -MH">F`30,`!MH`H`@(0*`("$GI0"@#``;:">F`3B/I0$TCZ8!.`P`-@4"8"`A
    -M$`#]+@`````GI0"@)Z8!+`P`&V@"@"`A`H`@(2>E`*`,`!MH)Z8!,(^E`2R/
    -MI@$P#``V#@)@("$0`/T@``````P`2'\"8"`AKF(%L"9E&W`,`#KG`F`@(1``
    -M_1@`````)[`!Q`*`("$GI0"@#``;:`(`,"$"@"`A)Z4`H`(`,"$,`!MHE[(!
    -MQB>E`*`GI@'(`H`@(0P`&VB7L0'&`H`@(2>E`*`,`!MH)Z8!S`*`("$GI0"@
    -M#``;:">F`=`"@"`A)Z4`H`P`&V@"`#`A`@`P(0*`("$GI0"@#``;:(^P`<2/
    -MIP'(CZ@!S(^I`="/JP'$)Z(`M`)@("$"0"@A`B`P(0(`4"&OH@``#`!7EZ^@
    -M``00`/SJ``````P`.F<"8"`A$`#\Y@`````"@"`A)Z4`H`P`&V@GI@'4CZ4!
    -MU`P`0=<"8"`A$`#\W0`````"@"`A)Z4`H`P`&V@GI@'8CZ(!V`*`("$GI0"@
    -M``*`P`("@",,`!MH)Z8!W``0B("/H@'<`G&((28Q&E`*"N
    -M(@`$#``;:">F`=R/H@'<`H`@(2>E`*"OH@"`)Z8!W`P`&VBN(@`(CZ(!W`*`
    -M("$GI0"@KZ(`A">F`=P,`!MHKB(`#(^B`=P`$(#``H`@(:^B`)`GI0"@KB(`
    -M$">F`=P,`!MH`G"`(280&'B/H@'F`20"@"`A#``;:(^P`20"
    -M@"`A)Z4`H`P`&W(GI@$HCZ8!*``0$,``4!`CC,,````"$(``4Q`AK$,9R(S#
    -M``0D0AG()`<``:Q#``2,PP`(`@F`>"/HP'@`F`@(0`#$,``0Q`C``(0P`!3$"$,
    -M`$J'C$48G!``_&T``````H`@(2>E`*`,`!MH)Z8![)>B`>X0`/QFIF(;\`+`
    -M("$,`!L*`@`H(11`_$,`0*@A)`(``A``_&:OH@"T)[W_\*^Q``2OOP`(`("(
    -M(0P`]__"OL@`(K[$`!*^P``"OOP`,`("`(0P`%4,\
    -M$H`#/`6``#P'@`(\"(`"/`N``P!`B"$F2HH()*5F;`(`,"$DYPJ0)0AZ""5K
    -MBA`D!``!$$``""0)$``"(!`AC[\`#(^R``B/L0`$C[````/@``@GO0`0#`!P
    -MRP`````,`'#DCD2*"!``__4"(!`A)`(``:R"`#`\`H`"K$5$1#P"@`*L140\
    -M`^``"```$"$GO?_0K[0`(*^R`!BOL0`4K[``$*^_`"0\$(`"K[,`'(X%,N`\
    -M!H``/`>```"`B"$DQFI0```@(23G:K@GJ@`!)Z@`!`P`66L#H$@A/`*``HQ4
    -M1$`\`H`"C$9$.(X#,N"3H@``CZ4`!*QQ``"@8@`(K&4`!).B``&.!#+@``"0
    -M(:""``F.`C+@K$8`$*Q4``P\$X`"CG`RX`P`>E<"@"`ACF,RX``2B(`",(`A
    -MK@(`%`(CB"&.)``4#``;'B92``$J0@`"5$#_\SP3@`*.9#+@#``:VB02``\\
    -M$(`"C@(RX"92__\,`'I7C$0`#(X$,N`,`!KW`$`H(09#__@\$(`"C@(RX(^_
    -M`"2/M``@C[,`'(^R`!B/L0`4C[``$`/@``@GO0`P)[W_T#"B``\D0@!-)`/_
    -M\*^R`!@`H)`A`$,H)`)#&"0`91`A`$,0*Z^Q`!2OOP`@`("((:^S`!ROL``0
    -M%$``!P!@("&\<0``)&,`$`"%$"$`0Q`K$$#_^P````"20@`!DD0``)(C`$`0
    -M@P`2,%,``8XC`#B.(@`\K&```(XD`#0D0@`!$(``!:XB`#P,`!LIC)```!8`
    -M__T"`"`AKB``1*X@`#2B(`!`DD(``!1``$(`````DD(``%1```6.(@!$KC(`
    -M-*XR`#BN(`!$CB(`1)9#``*.)``X`$,0(:R2``"N(@!$%F``"ZXR`#B2(@!`
    -M)$(``:(B`$"/OP`@C[,`'(^R`!B/L0`4C[``$`/@``@GO0`PKD```(XC``".
    -M(@`THB``0"1D`"0D4@`$KB``-`.@*"&,<``$#`!QJJ^@``".0P`()`(`$!!B
    -M``J/H@``5$``"8XB``".`A?8)`,``5!#``6.(@``C@(:M!!#``
    -M`D`H(0P`<=`"`"`A$`#_TH^_`"`,`!LI`D`@(1``_\Z/OP`@)[W_\*^_```0
    -MX``-,*(`_Q!```8`P"@A#``:(@````"/OP```^``"">]`!",A```#``5:P#`
    -M*"$0`/_ZC[\``!!```4`P"`A#``;*0`````0`/_TC[\```P`&QX`P"`A$`#_
    -M\(^_```GO?_P,*(`_Z^_```40``&`,`H(0P`&Q8`````C[\```/@``@GO0`0
    -MC((```P`":*,1``$$`#_^H^_```GO?_PK[\``(RG``",A``$`*`P(0P`6@0`
    -M`"@AC[\```/@``@GO0`0)[W_\*^_```\`H`"C$(RY`"@,"$00``+D(4`,Y3"
    -M``(D1P`$#`!:!(R$``2/OP``)`0``3P#@`*L9#+D`^``"">]`!`0`/_W)`<'
    -M("2"`!PGO?_PK(``)```*"&OOP``#`!QAP!`("&/OP```^``"">]`!`GO?_P
    -MK[````"`@"$DA``]__"OOP`$K[````P`&N0`H(`AK%``!(^_``2/L```
    -M)`,`(*Q#```#X``()[T`$">]__"LH``$K[\```P`&O<`````C[\```/@``@G
    -MO0`0)[W_\*^_```\`H`"C$(RX`"`,"$``"@A#`!9[HQ$``2/OP```^``"">]
    -M`!`GO?_PK[\``#P"@`*,0S+@`(`P(3P"B(B090`SC&0`!#1"B(@,`%GNK,(`
    -M`(^_```#X``()[T`$(R"````@A`AK$4``(R"```D0@`$`^``"*R"```GO?_P
    -MK[\`"*^Q``2OL````("((8R$````H(`A)`+__`(D("$`P"@AK)````(`,"$D
    -MA``$)A```PP`<)T"`H`DCB(``(^_``@`4!`A)$(`!*XB``"/L```C[$`!`/@
    -M``@GO0`0C(,``"0"`@``0Q`C$*```@"#("&LI```5,```:S"```#X``(````
    -M`(R#```DI0`#)`+__`"B*"0`91@A`^``"*R#```0H``"```8(8RC````@Q`A
    -MC$(`(!"@``(D8P`$K*,```/@``BLP@``C*(```""("$0P``")(0`(*S$```#
    -MX``(`````">]__"OOP`$K[````P`:_(`@(`A)`,``:X#``RN`@``K@``"*X`
    -M``2/OP`$C[````/@``@GO0`0)[W_\*^P``"OOP`$C((`.`"`@"$40``F)`0`
    -M`0P`:LDD!``!#`!K\@````"N`@`L#`!K]20$``*.`@`````H(0P`%-^,1``$
    -M%$``$P````".`@`P%$``#```("&.`@`X%$``!0``("&/OP`$C[````/@``@G
    -MO0`0#`!K#P`````0`/_ZC[\`!`P`:P$`````$`#_\XX"`#@,`&OUC@0`+`P`
    -M:LD``"`A$`#_[8X"`#@,`&L/`````!``_]@`````)[W_\*^P``"OOP`$C((`
    -M.`"`@"$40``=)`0``8X"```D!0`!#``4WXQ$``000``%`````(^_``2/L```
    -M`^``"">]`!`,`&OUC@0`+`P`:LD``"`AC@(`,!1```@D!``!C@(`.!!`__,`
    -M`"`A#`!K#P`````0`/_PC[\`!`P`:P$`````$`#_]XX"`#@,`&L/`````!``
    -M_^*.`@``)[W_\*^P``"OOP`(K[$`!(S#`"@D`@`!$&(`!@#`@"&/OP`(C[$`
    -M!(^P```#X``()[T`$*S``#P,`'$T``````P`&[<"`"`AC@(`*!1``"```"`A
    -M$(``$`````".`@`\/`,``C1C2?`D0@`!K@(`/(X"`#P`8A@K$&``!P````".
    -M`@``C$(`!(Q1%^@D`@`!$B(`"@`````,`!S\C@0`!"0$``4,`'%)``````P`
    -M<3L`````$`#_VX^_``@,`!N'`@`@(20$``L0`/_VKA$`*`P`'0..!``$#``=
    -M(XX$``0\`P`"`$`@(1!```XT8TGPC@(`/"1"``&N`@`\C@(`/`!B$"M00``(
    -MC@(`*(X"``",0@`$C$,7Z"0"``$08O_-`````(X"`"@40/_I`````!``_\@`
    -M````)[W_\*^Q``2OL````*"((:^_``@,`'%"`("`(0(`("$"(#`A#``;W@``
    -M*"&/OP`(C[$`!(^P```D`@`!`^``"">]`!`GO?_PK[```#P'@```@(`A/`B`
    -M`"2)`"0DB@`().=PL"0$``LE"&]X```H(:^_``0,`'$(`@`P(8X"`"040``%
    -M`$`@(8^_``2/L````^``"">]`!`,`'$F`````!``__J/OP`$)[W_\"0#``&O
    -ML```K[\`"*^Q``00HP`1`("`(5"@`!*,@@`H)`(``A"B``PD`@`#4*(`!HR"
    -M`"B/OP`(C[$`!(^P```#X``()[T`$%1`__JL@``H$`#_^8^_``BN```\$`#_
    -M]H^_``@40/_TC[\`"(R"``",0@`$C%$7Z%8C__"/L0`$#``<]8R$``0,`'%"
    -M)`0`!0P`&X<"`"`AKA$`*`P`<4DD!``+$`#_Y(^_``@GO?_PK[(`"`"`D"$D
    -M!`!`K[$`!*^P``"OOP`,#`!Z5P"@B"$`0(`A$@``%```$"$``"@A)`8`0`P`
    -M<*H"`"`A)@0`+*X2``"N$0`$#``;>:X``"@,`'%))`0`!`P`'#T"`"`AC@0`
    -M!#P%@``DI7%8#``]`!``0/@)C(0`+!``__N/
    -MOP``)[W_\*^_``",@@`H%$``!"0%``&/OP```^``"">]`!``0/@)C(0`+!``
    -M__N/OP``)[W_\*^_``",@@`H%$``!"0%``*/OP```^``"">]`!``0/@)C(0`
    -M+!``__N/OP``)[W_\*^_``",@@`H%$``!"0%``./OP```^``"">]`!``0/@)
    -MC(0`+!``__N/OP``)[W_\*^_``2OL````("`(8R$``2N!@`L/`:``*X%`"@D
    -MQG*<#`!9U```*"&.!``$/`:``"3&]__"OOP``#`!:SXR$``2/OP``
    -M`^``"">]`!`GO?_PK[\```P`6N",A``$C[\```/@``@GO0`0)[W_\*^_``2O
    -ML````("`(0P`6M>,A``$#``<_`(`("$,`!T#`@`@(8^_``2/L````^``"">]
    -M`!`GO?_PK[```*^_``0,`!SU`("`(0P`6MN.!``$C[\`!(^P```#X``()[T`
    -M$">]__"OOP``#`!:](R$``2/OP```^``"">]`!",@@`````H(8Q"0"`P1@#_
    -M/`.``@`%$(`D8S,P`$,@(92"```DI0`!$,(`!2RC``A48/_X/`.``@/@``@`
    -M`!`A`^``")2"``(D`A0`I((`"B0""9ZD@@`()`(`!:2"`!0D`@`$K((`8"0"
    -M`!ZD@@`<)`()*J2"`'0D`@`'K((`>"0"``\D`P`")`4``20&``,D!P`\H((`
    -M4R0"$`"LA0!(H(8`?*"#`'VL@@!4I(<`6JR```2@@P`6H(``%ZR%`'"LA@``
    -MK(``:*R``&RL@`!,K(``9*R``#2D@`!]_^"O
    -ML````("`(20$'`!`&"$``(`A/`*``B12,N@`$!#``%(0(91"```00P`&
    -M)`(`"280``$J`@`)%$#_]SP"@`(D`@`)$@(`%20#``$,`'I7)`0`O*XB&_00
    -M0``0)`/__P``*"$D!@"\#`!PJ@!`("$,`!T\)B0;:``0$,``4A`AC$(`!`!`
    -M^`D"("`A%$``"P!`@"&N<0```@`8(8^_`!"/LP`,C[(`"(^Q``2/L````&`0
    -M(0/@``@GO0`@#`!Z:HXD&_00`/_SKB`;]!``__(D$``")[W_\"0%``X``#`A
    -MK[(`"*^Q``2OL```K[\`#`P`'B``(40`!K)!0$```4
    -M$$`D4?Z`#`!Z5P(@("$`0)@A$$#_YB0$``("(#`A`$`@(0P`<*H``"@AC@(;
    -M]"01`,`"-!@KK%,`M!!@``P"8)`A`B`H(0(`("$"H#`A#``LKR8Q``$40``*
    -M`C08*Y>B``*F0@``%&#_]B92``("@"@A#``@YP)@("$00``*`````!)@``8D
    -M!0`6#`!Z:@)@("&.`AOTK$``M"0%`!80`/_#`*`@(0P`>EB``(0`/^,`H*@)2Q"``440/]U)`0`%A``_VX"`"`A+((``A1`_W`D
    -M!``6$`#_#S0"@``GO?_PK[$`!*^P``"OOP`,K[(`"(R"&_0`@(@A)`0`(`P`
    -M>E>,4@"T$$``%P!`@"$`0"`A```H(0P`<*HD!@`@CB(;]`(`*"$"("`A#`!(
    -M#JQ0``0``(`A`@`H(0(@("$,`"F>)A```2H"`(`40/_[`@`H(8XE&_0,`#\Y
    -M`B`@(11```\`````$D```P`````,`'IJ`D`@(0P`'WP"("`A)`0`%H^_``R/
    -ML@`(C[$`!(^P````@!`A`^``"">]`!`,`#3``B`@(0P`+V0"("`ACB0;]#P#
    -M@`(D8RRT/!"``CP'@``\"(``/`J``ZR#`!BN(A?$)@E'L"3G2\`E"$VH)4JA
    -M8```*"$"(#`A#`!Q"```("$,`'$FC@1'L`P`<4D``"`A#`!Z:@)`("&.(QOT
    -M)`(`"@``("&L8@!H$`#_V:Q@`+0GO?_@K[0`$*^_`!2OLP`,K[(`"*^Q``2O
    -ML```C)(;](Y0```2```=`("@(8X$``04@`!!`````(X$``@4@``Z`````(X$
    -M``P4@``S`````(X$`!`4@``L````````F"$"`(@ACB(`%"9S``$40``B`$`@
    -M(8XB`!PF,0`,%$``&@!`("$N8@`#5$#_]XXB`!0,`'IJ`@`@(:Y```".1``$
    -M%(``#0`````"@"`A#``_1@)`*"&/OP`4C[0`$(^S``R/L@`(C[$`!(^P````
    -M`!`A`^``"">]`"`,`'IJ`````!``__&N0``$#`!Z:@`````0`/_E+F(``PP`
    -M>FH`````$`#_W8XB`!P,`'IJ``"8(1``_]0"`(@A#`!Z:@`````0`/_,C@0`
    -M$`P`>FH`````$`#_Q8X$``P,`'IJ`````!``_[Z.!``(C(,;]"0"``XD8P`T
    -M`^``"``#$`LGO?_0K[0`(*^R`!BOL``0K[\`)*^S`!ROL0`4C)$;]"0%`+\#
    -MH#`ACB(```"`D"&GH``$#``LKXQ3``0F,``T%$``I@!`H"&.0AOTEZ,``(Q"
    -M``"N(P`TE$(``"Q"4`,40`"_)Z8`!`)`("$,`"RO)`4`RA1``)D`0*`AEZ(`
    -M!#!"#\```A%"-$(``:X"`#R.0AOTC$(``)1"```L0E`!$$``IR>F``*GH``"
    -MEF(`$I9D`!"68P`4``(0@`""("4``QC`EF4```"#("4T@@`"`$4@"I9C``(`
    -M@"@A-*(`$)>D````0R@*,*(``11```.N!```)`+__0"B*"0PH@`(%$``!"0"
    -M"0@D`O_O`*(H)"0""0BF`@!$ED(<]C!"`/`L0@`P$$``A*X%``260QSP)`(`
    -M!Q!B``4D`@G$)`(`"A!B``(D`@G$)`(*K*8"`$:7J``")`(3.*8"`$`D`A?4
    -MI@(`0C$#``(D`@`!K@(`8*X``%P48``(```P(99#'/`L8@`&4$``!"0&``$D
    -M`@`%4&(`8I9#'/*61!SP)`(``:X&`%@L@P`&K@(`4*X``$P08`!8```P(20"
    -M``50@@!2ED(<\C$$__\`!!!".$(``20'``$P0@`!,0,``:X&`%2N`@!(K@<`
    -M"*X'``P48``#```P(3"B``D``C`K``00PCA"``$P0@`!,0,`!*X&`!"N`@`4
    -M%&```P``,"$PH@`)``(P*Y9B``:.9``8``49`C!C``&N!@`8K@,`(*X'`"2N
    -M`@`HK@<`'!"```0``"@ACF(`'%1```,D`@`!)`4``20"``$Q`P'PK@(`,*X%
    -M`"P48``"``,1`B0"``HQ`_``$&``'ZX"`#0``QL")`(``0!B$`2N`@`XCD(;
    -M](Q#``"7H@`$,$(/P``"(4*48@``+$)0`Q1```.N!``\-((``:X"`#R"8@`@
    -M`D`@(:X"`&2"8@`A#``?SJX"`&@"@!`AC[\`)(^T`""/LP`]`#`0`/_D)`(`@"Q"``@40/^N,03__Q``_ZLD!@`!)`(``A!B
    -M``,L8@`$5$#_G)9$'/`0`/^9)`8``1``_X0D`@G$`D`@(0P`+*\D!0#)%$#_
    -MXP!`H"&7H@`"$`#_5*9B`#@"0"`A#``LKR0%`,H40/_;`$"@(9>B``0P0@P`
    -M``(90JX#`#P0`/]"IZ(`!">]_]"OLP`B
    -M``"3HP`!``(2`J(#``"B`@`!%(#_\B80``*20P`+)`(`_Q!B``H``(@AHD``
    -M#(^_`""/LP`]
    -M__"OL````("`(:^_``0,`'I7)`0!6*X"``000`!")`,``@!`("$``"@A#`!P
    -MJB0&`5@,`'I7)`0#9*X"``@00``Y)`,``@!`("$``"@A#`!PJB0&`V2."0`(
    -M)`(`"B0(``FE(@`4)`(``Z4B`AXE(P`<)`(`"R4(__^D8@``!0'__21C`#0`
    -M`$`A`2`X(3P#@`(\`H`"``@@0"1C%X0D0A=\`((0(0"#&"&41@``E&,``"4(
    -M``$`B2`A)`(`"RD%``.D@P(@I(8")J3B`C*DX@+.%*#_[B3G`#0,`'I7)`0`
    -MB*X"``P00``/)`,``@!`("$``"@A#`!PJB0&`(@,`'I7)`0(`*X"`!`00``&
    -M)`,``@!`("$``"@A#`!PJB0&"````!@AC[\`!(^P````8!`A`^``"">]`!`G
    -MO?_@K[\`$*^S``ROL@`(K[$`!*^P``",@AOT`*!((3##__^,4P``EF(``"Q"
    -M,`,40``ICG``")8&`!0``)`A`D80*U!``!"6`@`4`@`X(0`#$$``21`AE$@`
    -M`"92``(D8P`!,00`_P`($@("1B@KI.(``*3D``(P8___%*#_]"3G``26`@`4
    -M$$``#```D"$"`(@AEB4``)9D`````#`A#``HGB92``&6`P`4IB(```)#&"L4
    -M8/_W)C$``H^_`!"/LP`,C[(`"(^Q``2/L````^``"">]`"```Q!``$40(91(
    -M```D8P`!,&/__P!@*"$`"#%```@8@@`($D(PQ@!_,&,`?P`%($"F!@`$I@(`
    -M`*8#``(`B2`AE(@``"2E``$PH___`&`@(0`($L(`""C```@9`@#","4PI0!_
    -M,&,`?P`$$$"F!0`(I@8`!*8#``8`21`AE$@``"2$``$P@___`&`@(0`($T(`
    -M"#A```@9@@"B*"4PYP!_,&,`?P`$$$"F!P`,I@4`"*8#``H`21`AE$@``"2$
    -M``$PA/__``@I@``(,\(`"!("``@80C"E`'\P0@!_`.8X)3!C`'\`!"!`I@4`
    -M$J8"``ZF!P`,I@,`$`")("&4B`````@2@@"B*"40`/^HI@4`$B>]_\"OMP`L
    -MK[4`)*^Q`!2OOP`TK[X`,*^V`"BOM``@K[,`'*^R`!BOL``0C((;]##&__^O
    -MI0``C%0``*^F``0``+@ACH(`!(Z2``@``(@AE%X`$@``J"$D`@`!```@(1*B
    -M`'>/HP`$4J``<997`!0D`@`"$J(`9P`````2X`!5``"P(0`#$$"/HP```("8
    -M(0!#@"&68@``)B<`"*8B``"6"@``)A```@`*((``"BD"``HR@C"E`#\PA``_
    -MIB0`'J8F``2F)0`"E@H``"80``(`"DN"``I!```*$@(`"AB"`(D@)3$(`#\P
    -M0@`_,&,`/Z8H`"2F)``>IB(`(*8C`"*6"@``)A```@`*&P(`"A&"`0-`)3!"
    -M`#\Q0P`_IB@`)*8B`":F(P`HE@H``"80``(`"D"```H9`@`*$H(Q"``_,&,`
    -M/Z8H`"ZF(@`JIB,`+)8*```F$``"``HC@@`*&((`"A("`01`)3!"`#\P8P`_
    -MIB@`+J8B`#"F(P`R#``H>I:$``"6)P`&$.``#0``,"$"("@AA*(`'B3&``$`
    -MQR`K``(80`!B&"$``QC``&(8(0`#&$"DHP`>%(#_]B2E``(FU@`!`M<0*R8Q
    -M`#040/^Q)G,``B:U``$NH@`#5$#_GR0"``&/OP`TC[X`,(^W`"R/M@`HC[4`
    -M)(^T`""/LP`]`$!3P/_P)K4``997`AXD8P!&
    -M)E$"+!``_Y0F1`(@)&,`!291`!80`/^0`D`@(5/`_^4FM0`!EE<"'B1C`#`````":#``$P=/__EB,````4*$``O8@A``,:`H^D`!@``#`AIF(``!!@
    -M``H`8"@A#``HG@`````F`P`!,'#__R:#``$P=/__`I(8*Q1@_^*F(@```!(0
    -M0@+"$"$P4/__IO0`%!*``&$``$`A``@@0`"($"$`G1@A``(0@)1C````2!`A
    -M``(00`!7,"$`$"A``)<@(:2#````M2@AI,,`&)2C```F`@`!,%#__P`#$$`P
    -M0@$`,&,`_P!B&".DPP`$$"/OP!$`$,0(91"`'Z/O@!`C[8`.*;B`!:/M0`TC[<`/(^T`#"/
    -MLP`LC[(`*(^Q`"2/L``@`^``"">]`%"4X@``)`,``:3#`!H``AO"``,:```"
    -M$@(`0Q`C$`#_X:3"`"H`"!!``$D0(91%```E`P`!,&C__R0"`/\`%!A`+08`
    -M`R:$``$010`#`'T8(3"4__^D90``%,#_\P`($$`0`/]TIO0`%">]__"OL```
    -M,+#__P`0$$"OL0`$`("((0!`("&OL@`(K[\`#`P`>E<`P)`AKB(``!!``#,D
    -M`P`"`!`@@`"0("$`!""``)`@(0P`>E<`!""`$$``,JXB``BF,``$$@``)P``
    -M,"$`!D"```880`$&$"$`K0"`8"&GH@`"I*,`
    -M!J>B````8#@A```P(0``("$`AQ`',$(``1A```@LPP`"$&``@```$"$`!AA`
    -M),(``0!]&"$P1O__I&0``"2"``$P1/__+((`!!1`__(`AQ`'E8(`%```2"$0
    -M0`!QI*(`!``)&$``:1@A``,8@`!I&"$`"4"```,80`$)$"$!@Q@A``(0@(RJ
    -M``B49``8`$D0(0`"$(``2A`AI$0``"1F`!B4PP`2I$,``I>C``(T`MZM$&(`
    -M7@``("$!"1@A``,8@`!I&"$`!!"``$00(0`#6(`D@P`!``(0@#!D__\!:C@A
    -M`$<0(2R#``048/_SI$``!I>C``"4Q``"``,0@`!#$"$``A"``$<0(:1$``B7
    -MHP`"``,0@`!#$"$``A"``$<0(20#`!2D0P`(EZ,``@`#$(``0Q`A``(0@`!'
    -M$"$D`P`CI$,`"I>C``(``Q"``$,0(0`"$(``1Q`A)`,`/Z1#``R7I`````00
    -M@`!$$"$``A"``6(0(0!*$"$D1``$)`(`!*2"``*4PP`&E((`!`!#$"&D@@`&
    -ME,,`"@!#$"&D@@`(E,,`#@!#$"&D@@`*E,(`!*2"``R4P@`(I((`#I3"``RD
    -M@@`0E,(`$*2"`!*7I``"``00@`!$$"$``A"``6(0(0!*$"$D1``$)`(``Z2"
    -M``*4P@`4I((`#)3"`!:D@@`.E,(`&*2"`!"4H@`$)2,``3!I__\!(A`K%$#_
    -MD@`)&$`D`@`!`^``"">]`!`!"1@A``,8@`!I&"$`!!"``$00(0`#.(`D@P`!
    -M,&3__P`"$(``ZA@A`$,0(2R#``048/_SI$``!I>D````!!"``$00(0`"$(``
    -MXA`A`$H0(21$``0D`@`$I((``I3"``*D@@`$E,,`!@!#$"&D@@`&E,,`"@!#
    -M$"&D@@`(E,,`#@!#$"&D@@`*E,(`!*2"``R4P@`(I((`#I3"``RD@@`0E,(`
    -M$!``_\VD@@`2)[W^L*^W`3ROM@$XK[4!-*^S`2ROL@$HK[$!)*^P`2"OOP%`
    -MK[0!,(R"&_0`@+`A`*"X(8Q"```PT?__`."0(8Q4``0``)@A``"H(0``@"$D
    -M`@`!4@(`-I:"`!)2```XEH(`$"0"``)2`@`QEH(`%`.@("$``"@A#`!PJB0&
    -M`1P"P"`A`Z`H(0(@,"$"H#@A`N!`(0P`(E4"`$@AEZ4`%`)`("$,`",F`Z`P
    -M(0!`F"$40``3`$`8(0.@("$,`"-Q`D`H(1!```XD`___EZ,`%``#$(``0Q`A
    -M`B(0(18```,P4?__)B(`!3!1__\F$``!+@(``Q1`_]8F4@`,`F`8(8^_`4"/
    -MMP$\C[8!.(^U`32/M`$PC[,!+(^R`2B/L0$DC[`!(`!@$"$#X``()[T!4%!`
    -M_^\F$``!$`#_S205``-00/_K)A```1``_\DD%0`*)[W_P*^W`"ROM``@K[\`
    -M-*^^`#"OM@`HK[4`)*^S`!ROL@`8K[$`%*^P`!",@AOT,,;__Z^E``",4P``
    -MKZ<`"*^F``2.8@`$``"X(0``H"&47@`2)`(``0``D"$``*@A$H(`]`$"60P`$`!`@0@`0*T(`$!'"`&48)3!"`#\0`/_=,(0`/Q``_\@`
    -M$!#"$`#_O20&``$0`/_=,%'__Q``_[(`$!)"%\``!#!1__\F(@`&$`#_VC!1
    -M__^.8@`,)!<``R15`%(0`/^;)%(`5"8B`%4P4?__`&"H(207``@0`/^5)'(`
    -M`B8B`&4P4?__$\#_\"8B``2.8@`,)!<``B15`'(0`/^,)%(`=">]_]"OM@`8
    -MK[0`$*^Q``2OOP`@K[<`'*^U`!2OLP`,K[(`"*^P``",@AOT`*"@(3#1__^,
    -M50````"P(8ZC``248@$6$$``$8ZR`!``%KA``N,0(91"`1@40``7EJ(``"8C
    -M``@F)``'+$(P`P!@B"$`@H@+CJ,`!";6``&48@$6`L(0*Q1`__$F4@!`C[\`
    -M((^W`!R/M@`8C[4`%(^T`!"/LP`,C[(`"(^Q``2/L````^``"">]`#`L0C`#
    -M%$``0``1$$``5#`A``"8(0)`*"&4R```)G,``BYD``@Q`P#_``@2`J2B``"D
    -MHP`(),8``B8Q``$4@/_V)*4`$``1$$``5$@A``"8(0)`."&5*```)G,``BYF
    -M``@`""&"``@2`@`(&X(P0@`_,&,``3"$``$Q!0`_I.(``JSC``2DY0`*K.0`
    -M#"4I``(F,0`!%,#_[R3G`!```)@A`D"`(8X"``!00``/)G,``8ZB``0"XA`A
    -ME$(!&#!#``<08``.```P(20"``,08@`,EJ0``)8%```D!@`!#``HGB9S``&F
    -M`@``+F(`"!1`_^TF$``($`#_LHZC``26I```$`#_]I8%````5!`AE$@``"8Q
    -M``$`$2!```@I0``(&((`"!)",*4`?S!C`'^F10`0ID(``*9#``@`E"`AE(@`
    -M`"8Q``$`$3!```@:P@`((,``"!$"`*,H)3"$`'\P0@!_ID0`(*9%`!"F0@`8
    -M`-0P(93(```F,0`!`!$H0``(&T(`"#!```@1@@"#("4PQ@!_,$(`?Z9&`#"F
    -M1``@ID(`*`"T*"&4J```)C$``0`1.$``""/"``@I```($@(`"!B"`,0P)3"E
    -M`#\P0@!_,&,`/Z9%``JF0@`XID,``J9&`#``]#@AE.@``"8Q``$`$2!```@;
    -M`@`($8(`HR@E,$(`/S$#`#^F10`*ID(`$J9#`!H`E"`AE(@``"8Q``$`$2A`
    -M``@@@``(&0(`"!*",(0`/S!C`#^F1``RID(`(J9#`"H`M"@AE*@``"8Q``$`
    -M"!H"``@3@@""("4P8P`_ID0`,A``_XZF0P`Z)[W_T*^U`"2OM``@K[,`'*^_
    -M`"BOL@`8K[$`%*^P`!",@AOT`*`P(0"@H"&,4@```("8(0``J"$,`"8TCD4`
    -M!)9B'/8P0@#P+$(`,%1```:60@``CD(`!)1"`"@00``I)`,`%I9"```D$`"0
    -M)!$`0"Q",`,"`#`A`B(P"P)@("$,`"%$`H`H(99"```"`#`A+$-``"Q",`,4
    -M8``&`B(P"XY"``240P`H)`(``1!B`",F1P`4`F`@(0P`(;X"@"@AED,``"QB
    -M0``40``8+&,P`XY"``240@`L)$+^ZS!&__\"8"`A`H`H(0P`)($#H#@AEZ8`
    -M``)@("$,`"45`H`H(0*@&"&/OP`HC[4`)(^T`""/LP`F1@#JID(`[*9#`.:F1`#HID4`XJ9'`.0`$1!``%,0
    -M(910```F,0`!`9)0(3($`/\`$!H"`!$00*5#`%"E1`!6`%,0(910```F,0`!
    -M`!$80#($`/\`$!("I4(`7*5$`&(`DH@`"`!$00`!3$"&44```+H5``"8Q
    -M``$`$!E"`!`@0C!C`/\PA``/,@(``:5"`(2E0P!X%*``!J5$`'X2H`$T`!`3
    -M0B0"``(2H@$N`!`30A;``!$N@C`$`!$00`!3$"&44````9(8(0`0$8(P0@!_
    -MI&(`S"0"``$2H@$<)C$``2JB``(40`$4)`(``A*B`0T`$!#"+H(P!!1``00`
    -M%1!``!480`!R&"$`$"-")&,`T``1$$"D9``"`%,0(910```F,0`!`!`0P#!"
    -M`#@`@B`E)`(``A*B`.VD9``"%J``"2Z"0``4H``'`!`8P@`0$@(P0@`_,&,`
    -M'Z9"`0*F0P$&+H)``!1``#`FH@`!)`(``1*B`,$D`@`"$J(`:P`1$$`6H``I
    -M)J(``2Z"0`$40``F)J(``0`1$$``4Q`AE%```"Z#4``F,0`!,@(`/Q1@`!VF
    -M0@#8`!`1@@`0,T(P0@!_`!$80*9&`$RF0@!"`',8(91P```F,0`!`!$H0#("
    -M``<``A#``!`8P@`0(D(`PC`E,&,`/Z)$`&NF1@!,ID,`W@"S*"&4L```)C$`
    -M`3("``$``A'``((@)0`0$$*B1`!KHD(`<":B``$P5?__+J(``Q1`_O\`%1"`
    -M4L``$X[B`!0`$1!``%,0(910```F,0`!`!$@0``0$,(R`P`',$(`!Z9#`/JF
    -M0@#^`),@(920````$!#",$(`!S(#``>F0P#\ID(!`([B`!261P$6``"H(1#@
    -M``\D4?]``!$00`!3,"&4T```)J,``@`5$$`P=?__`%(0(3(#`/\`$"("`J,@4`_R8Q``$`$"H"`H`@(20&``$,`"B>ID(!$``1
    -M&$``F0P#Z$`#^Y:9"
    -M`/XP0@`!$`#^T:9"`#`P0@`!$`#^SJ9"`"XP0@`',@,`!Z9"`/80`/Z`ID,`
    -M^!:@_I8`$1!``!`00``0&4(`$""",&,`!S"$``,,*7__R0"`/\P@___$*(`"20'`/\0P``)``40@"QB,`-0
    -M0``")*((_"2B"6`P0O__`$`X(0/@``@`X!`A`$40(21"$L`L8S`#$&#_^3!"
    -M__\LH@`_%$``!``%$(``11`A$`#_\B1"%2(`11`A``(00!``_^XD0A/L)[W_
    -MX"0%`+\#H#`AK[``$*^_`!0,`"RO`("`(1!```8``!@AC[\`%(^P`!``8!`A
    -M`^``"">]`"".`AOT)`,`SR0%`,J,0@```@`@(0.@,"&40@``+$)```P`+*\`
    -M8B@+C@(;])>C``",1```,&:``#!C"`"4@@```$`@(2Q"0``X0@```,(8"S!B
    -M__\LA$````(KPCB$`````A+"`*00"Z>C``"GH@``$`#_WC!#__^,@@``C$)`
    -M"#A"``$#X``(+$(``2>]_^"OLP`,K[$`!*^P``"OM``0K[(`"*S```",BP``
    -M)`+__P"@F"&-:0"``,"`(0"`4"$D!?__$2(`.```B"&,@QM`/`0!!32$V#`!
    -M(Q@D/`(`@`$D0"0Q)0`%`&)H)#4"``$`14`+/!(`(#!G``4P9@%`-0(`0`!R
    -MR"0Q)0%`,&P`@`!D&"0`14`+-&(``0!'&`LT8@!`/!0#_SP8(``Q+P`@,2X`
    -M@!&@``(`1A@+C7$`C`&#&"4"."`D$:```@!X$"4`1!@+`'(0)0!9&`L!XQ@E
    -M$<``#`!@*"&-8P"$)`+_?P$B2"0`=!@D``,<`JX#`````Q0`C4,```!4$"0U
    -M"`"`K&(`A(U"``"N:```K$D`@(U"``",0@"`C[0`$(^S``R/L@`(C[$`!(^P
    -M````H!`A`^``"">]`"`\`@$%-$+8,#"H`$`PJ0`!,*H`@`2A``\`@#`AC(,;
    -M](QB`!000``#)$3__ZQD`!2,8@`4%$```R0"``&,PP``K&(`)`/@``@`````
    -M`^``"`````",@P```*(H)(QB`"0X0@`!+$<``5#@``6,PAM`K&``)(R"``",
    -M0@`DC,(;0(S$```T0P%``&@0"S1#``4`:1`+`4(0)0!%$"6L@@"@C,0``(R#
    -M`*`0X/_FK,(;0"0"``&L@@`D$`#_Y``````$HP`+C(,``(R#&_2,8@`4)$(`
    -M`:QB`!2,@@``K$``)(R"``",0@`D`^``"`````",8@`D.$(``2Q'``$0X``%
    -M,*(`0*Q@`"2,@@``C$(`)#"B`$`00``#C(8;0"0"_K\`PC`D,*(``1!```0P
    -MH@"`)`+_^@#","0PH@"`$$``!#P"`04D`O]_`,(P)#P"`04T0M@PC(,```"B
    -M*"0`!1`G`,(P)*QF`*",@P``C&(`H!#@_]VLAAM`)`(``:QB`"0#X``(````
    -M`(R#```T`H@```4I0`"B*"$`91@AK&```(R"```D`P`'`$40(:Q```2,@@``
    -M`$40(:Q```B,@@```$40(:Q```R,@@```$40(:Q``!",@@```$40(:Q#`!2,
    -M@@```$40(:Q``!B,@@```$40(:Q``!P#X``(`````">]_X"OM0!D/!6JJC:U
    -MJJHD`@`'K[X`<*^W`&ROM`!@K[(`6*^Q`%0`P)`AK[\`=*^V`&BOLP!\$(`!A?``\+P)0`&,$(T!8``-,:``*^E`$2OI@!($B``!:^@`#R6(P`,
    -M)`(`$!!B`"H"@"`A```P(0.@."$`%Q#`CH,```!&$"&,Y0`,``(0@#0(B```
    -M2!`A),8``0!B&"$LQ``(K.(`"*QE```4@/_S).<`"(Z"````%R%`CZ,```""
    -M$"$`2!`AK$,``(Z"```T`X@$`((0(0!#$"&/HP`$K$,``(Z"```T`X@8`((0
    -M(0!#$"&L7@``CH(```""("$T`H@<`((@(8^B`$BL@@``$`#_D8^_`'0D!0`2
    -M#``=SB0&`!`00/_4```P(1)``0,GI``(```H(0P`<*HD!@!`)`(`!"8P`!2O
    -MH@`TD@,`#9("``R2!``.D@4`#P`#&@``0Q`E``0D``!$$"4`!2X``$40)0!5
    -M$":OH@`LD@,`"Y("``J2!``,D@4`#0`#&@``0Q`E``0D``!$$"4`!2X``$40
    -M)0!5$"8P0O__KZ(`))(#``>2`@`&D@0`"``#&@"2!0`)`$,0)0`$)```1!`E
    -MCZ0`!(^C````!2X``$40)0`$("<`51`F,(3__P`#&"D``@``"@A)`8`0`P`<*HP4___D@,``9($``*2(@!&D@4``P`#&@``0Q`E
    -M``0D``!$$"4`!2X``$40):^B``R2`P`%D@(`!)($``:2!0`'``,:``!#$"4`
    -M!"0``$00)0`%+@``11`EKZ(`'```,"$#H#@A`!,0P(Z#````1A`AC.4`#``"
    -M$(`T"(@``$@0(23&``$`8A@A+,0`"*SB``BL90``%(#_\R3G``B.@@``CZ,`
    -M```7L4`"PA`A`$@0(:Q#``".@@``-`.(!">D``@"PA`A`$,0(8^C``0``"@A
    -M)`8`0*Q#```FX@`@#`!PJC!3__\D`@`$KZ(`-))#``V20@`,DD0`#I)%``\`
    -M`QH``$,0)0`$)```1!`E``4N``!%$"4`51`FKZ(`+))#``N20@`*DD0`#))%
    -M``T``QH``$,0)0`$)```1!`E``4N``!%$"4`51`F,$+__Z^B`"220P`'DD(`
    -M!I)$``B210`)``,:``!#$"4`!"0``$00)0`%+@``11`ECZ0`!`!5$":/HP``
    -MKZ(`'(^B`$@`!"`G,(3__P`#&">OI``4KZ,`#*^^`#ROH@!$```P(0.@."$`
    -M$Q#`CH0```!&$"&,Y0`,-`.(```"$(``0Q`A),8``0""("$LPP`(K.(`"*R%
    -M```48/_S).<`""8P`$XFX@!@)Z0`"```*"$D!@!`#`!PJC!3__^2`P`!DB(`
    -M3I($``*2!0`#``,:``!#$"4`!"0``$00)0`%+@``11`EKZ(`#)(#``62`@`$
    -MD@0`!I(%``<``QH``$,0)0`$)```1!`E``4N``!%$"6OH@`<```P(0.@."$`
    -M$Q#`CH0```!&$"&,Y0`,-`.(```"$(``0Q`A),8``0""("$LPP`(K.(`"*R%
    -M```48/_S).<`"(Z"```T`XP``L(0(0!#$"&/HP``K$,``(Z"```T`XP$`L(0
    -M(0!#$"&/HP`$K$,``!``_HB/OP!T)[(`"`)`("$``"@A#`!PJB0&`$`D`@`$
    -MKZ(`-"8P`!22`P`-D@(`#)($``Z2!0`/``,:``!#$"4`!"0``$00)0`%+@``
    -M11`E`%40)J^B`"R2`P`+D@(`"I($``R2!0`-``,:``!#$"4`!"0``$00)0`%
    -M+@``11`E`%40)C!"__^OH@`DD@,`!Y("``:2!``(D@4`"0`#&@``0Q`E``0D
    -M``!$$"4`!2X``$40)8^D``0`51`FCZ,``*^B`!R/H@!(``0@)S"$__\``Q@G
    -MKZ0`%*^C``ROO@`\KZ(`1#+S__\``#`A`Z`X(0`3$,".A````$80(8SE``PT
    -M`X@```(0@`!#$"$DQ@`!`((@(2S#``BLX@`(K(4``!1@__,DYP`()C``3@)`
    -M("$FX@!````H(20&`$`,`'"J,%/__Y(#``&2(@!.D@0``I(%``,``QH``$,0
    -M)0`$)```1!`E``4N``!%$"6OH@`,D@,`!9("``22!``&D@4`!P`#&@``0Q`E
    -M``0D``!$$"4`!2X``$40):^B`!P``#`A`Z`X(0`3$,".@P```$80(8SE``P`
    -M`A"`-`B(``!($"$DQ@`!`&(8(2S$``BLX@`(K&4``!2`__,DYP`(CH(````7
    -M(4"/HP```((0(0!($"&L0P``CH(```""("$T`H@$`((@(1``_G2/H@`$%*+^
    -M!8^_`'0D`@!H$*(`)I(#``V2`@`,D@0`#I(%``\``QH``$,0)0`$)```1!`E
    -M``4N``!%$"4`51`FKZ(`+)(#``N2`@`*D@0`#)(%``T``QH``$,0)0`$)```
    -M1!`E``4N``!%$"4`51`F,$+__Z^B`"22`P`'D@(`!I($``B2!0`)``,:``!#
    -M$"4`!"0``$00)0`%+@``11`E`%40)A``_>BOH@`(1@"HF$8`JXA'
    -M`*R81P"O@$@`L*BD``"XI``#J*8`!+BF``>HIP`(N*<`"Z"H``P#X``(`&`0
    -M(8R$&_0PI?__C(,`-!!E``(``!`AK(4`-`/@``@``````^``"```$"$GO?_@
    -MK[$`%`.@,"$`H(@A)`4`'Z^R`!BOOP`<`("0(0P`+*^OL``0`D`@(0.@,"$0
    -M0``))`4`'B0$`!:/OP`B``"3HP`!`@*`
    -M(0`"$@*B(P`##``LKZ(B``(40/_G)`0`%I>B``"3HP`!/`4``@("@"$``A("
    -M```@(32E__VB(@`$$@#_W*(C``46!?_]_]"OOP`@K[,`'*^R`!BOL0`4K[``$(RC`!",I@`4`*"`(5!@``$```'-
    -M`,,`&XX"``P#H"@A`("((0``F!(```````````!B`!L``)`2#``M[0````"/
    -MHP`$CZ(``(X&``2.!0`(``,=@``"$H(`8D@EC@,``(X(``PE(@`"),;__P!H
    -M("$F9___`((8*P3``*&N!```5&#_]XX#``!PR#@"C@(`$(X#`!@`Y#`A<*(@
    -M`JX&``0`AA`A$&``C*X"``B.)```-`6``#P#`!``A2`AC((`!`!#$"6L@@`$
    -MCB(``(X#`!0`11`AK$,`)(XB``".`P`8`$40(:Q#`#B.(P``C@(`"`!E&"$`
    -M`A#`K&(`,(XB``".`P``-!*```!2$"&L0P`HCB,``)8&``X\$___`'(8(8QB
    -M`"`"("`A/`6```!3$"0`1A`EK&(`(`P`*6P`````CB(;0(XD```\`__[-&/_
    -M_P!#$"2N(AM`K((`H(XB'82.)```/`7__P!#$"2N(AV$C@(`(`"2("&,@P`8
    -M-*4`_P`"$@``91@D,$+_``!B&"6L@P`8CB(;0(XD```\`P`$`$,0):XB&T`\
    -M!8``K((`H`P`*3P"("`AC@,`'(X"``P`0Q`K5$```:X#``R.`@`0`$,0*U1`
    -M``&N`P`0C@,`#(X"`!!08@`ZC@(`!(X"``2.(P``/`8`!P`"$,`TQO__)$+_
    -MZ`!R&"$`1A`DK&(`U(XC```\!0#_-*7__P!R&"&,8@#4/`<*`#P$`!@`11`D
    -M`$<0):QB`-2.(P``C[\`(`!R&"&,8@#4`$00):QB`-2.`@``CB,````"$,`D
    -M0O_H`$80)`!R&"&L8@#8CB,```!R&"&,8@#8`$40)`!'$"6L8@#8CB(``)8#
    -M``X`4A`AK$,`W(XD``".`P`0C[$`%`"2("&,@@#<``,<``!S&"2/L@`8C[,`
    -M'(^P`!`P0O__`$,0):R"`-P#X``()[T`,!``_\:N`@``CB,``#0"@``\!/_O
    -M`&(8(8QB``0TA/__`$00)*QB``00`/^!CB(``"2E__\HH@``)D;__Q``_UP`
    -MXB@+C((``#0&@```1A`AC$(`3*BB``"XH@`#C((```!&$"&,0P!0C$(`4*BB
    -M``2XH@`'B*(`!)BB``<00P`&`````(R"````1A`AC$(`3*BB``"XH@`#`^``
    -M"`````",@P``-`6``#P&`0``91@AC&(`(`!&$"6L8@`@C(,```!E&"&,8@`@
    -M`$80):QB`"`#X``(`````(R#```T!X```(!`(0!G$"&,1``$C&(`%#P%_Y^5
    -M!AMR-$(`(*QB`!2-`P``-*7__SP"`((`A2`D`((@)0!G&"$PQC<`)`(4`*QD
    -M``10P@`#C0,```/@``@`````)`(#<*T`'/RL8A!P$`#_^@````"4@AMR```8
    -M(3!"`@`00``UC(D<")"K```18``.``!`(0"H$"&00@`!)0@``0$+4"HP1@!_
    -M,$(`@!!```0`PS@K5.```0!@,"$PPP#_%4#_]0"H$"&-)@``&,``"0``."$E
    -M)0`RD*(``!!#``4DI0`8).<``0#F$"I40/_[D*(``!C```L``$`A)24`,P#H
    -M$"I40``"H*<``*"H``"-(@``)0@``0$"$"H40/_X)*4`&%!@``Z,@P````,0
    -M0BQ"``-00``*C(,``(R$```T`H``/`,"``""("&,@@`$`$,0):R"``0#X``(
    -M`````#0"@``\!/W_`&(8(8QB``0TA/__`$00)*QB``0#X``(`````(R#```T
    -M`H```&(H(8RB&&0``A3",$,!`#!$`?\08``".((!_P`"(">,H@!0C*,`3`!#
    -M$"8#X``(`$00)B2C__\L8@`%`*#`(1!``#L`@'`A``,0@#P#@`(D8PRL`$,0
    -M(8Q"````0``(`````(R"```T#X``)(T$@`!/$"&,1`"0C:(`3(VC`%B-QP2`
    -M`$00(:VB`$R-P@``C:@`8(VD`%"-I0!4`$\0(8Q"`(R-J0!DC:L`:`!B&"&M
    -MHP!8C````
    -M`#P"4>LT0H4?`*(`&0``$!```BE")`(`9`!E`!M0H``!```!S0``&!(0`/_2
    -M`$,@(U#`_]```"`AC((``#0#@```0Q`AC$4`[*S%``",@@```$,0(8Q$`/"L
    -MQ``$C<(```!#$"&,0@#TK,(`"(W"````0Q`AC$(`^*S"``R-P@```$,0(8Q#
    -M`.R,0@#P`&48)@!$$"8``Q@K``(0*ZS"`!`0`/^SK,,`%(R"```T`X```$,0
    -M(8Q"&&0``A,"`^``"#!"`'\PI?__)(0%O```&"&4@@``$$4`"22$`$@00``(
    -M``,4`"1C``$L8@!`5$#_^92"```#X``(```0(0`#%``#X``(``(4`R>]__"O
    -ML```)`4``@"`@"&OOP`$#``N@0``,"&.`@``-`2``#P#``(`1!`AK$`!)(X"
    -M``"/OP`$`$00(:Q``2B.`@``K$``0(X"````1!`AK$,!,(X"``"/L```/`,"
    -M``!$$"&L0P$X`^``"">]`!`GO?_P```H(20&`$BOOP`$K[````P`<*H`@(`A
    -M/`(`/S1"_SBN`@!$)`(!]*X"`!`D`@!DK@(`'"0"`"BN`@`D/`,`/R0"``]`!`GO?_PK[\`!*^P``",D`6X/`(`0`"`
    -M0"&.`P`0`$,@(P!#$"H00``EK@``#*X``$".`P`8/`(`0`!#(",`0Q`J4$``
    -M`JX$`$2N``!$C0(``(X#`$`T!X```$<0(:Q#`2R-`@``C@,`1`$`("$`1Q`A
    -MK$,!-(T"```\`P`")`4``@!'$"&L0P$PC0(``#P#`@```#`A`$<0(:Q#`3@,
    -M`"Z!`````*X``#RN```XC[\`!(^P```#X``()[T`$!``_]RN!`!`)[W_\*^Q
    -M``2OOP`(K[```(R#%\``@(@AC)`%N"AB```D9`!_`&`H(0""*`L`!2G#``41
    -MP`!B$",H0@!`5$``!0"@("$D8P#^*((```!B(`L`!"'#CB(7Q!!``!2/OP`(
    -MD@(``Q!``$TD0@`!D@,`!"QB``(40`!$)&(``8X"`"0`1!`J4$``'XX"`""2
    -M`@`&$$``$B0"``&2`P`%+&(``A1```8D8@`!C[\`"(^Q``2/L````^``"">]
    -M`!`P1@#_`B`@(20%``2B`@`%#``Q5@`````0`/_UC[\`"`(@("$D!0`"H@(`
    -M!@P`,58``#`A`B`@(20%``6B```$$`#_\P``,"$`1!`J4$``"Y8B&W*2`@`&
    -M4$#_X9(#``6B```&`B`@(20%``(,`#%6)`8``1``_]J2`P`%,$(0`!!`_]N/
    -MOP`(D@(`!A!```@D`@`!D@(`!5!`_]6/OP`(H@``!0(@("$0`/_E)`4`!*("
    -M``8"("`A)`4``@P`,58``#`A$`#_])("``4P1@#_`B`@(20%``40`/_-H@(`
    -M!#!&`/\"("`A)`4``1``_\BB`@`#C(,7P">]__"OOP``*&(``"1E`'\`8#`A
    -M`*(P"P`&,<,`!A'``&(0(RA"`$`40``JC(<%N"1C`/XHH@```&(H"P`%&<.,
    -M@A?$$$``#8^_``"0X@`#$$``'"1"``&,X@`@`$,0*E!```^4@AMRD.,`!2QB
    -M``(40``$)&(``8^_```#X``()[T`$#!&`/\D!0`$H.(`!0P`,58`````$`#_
    -M^(^_```P0A``$$#_]8^_``"0X@`%$$#_\B0%``2@X``%$`#_]```,"$P1@#_
    -M)`4``1``__"@X@`#$`#_V@#`&"$GO?_PK[(`"*^Q``2OL```K[\`#)2%&W`,
    -M`"\5`("`(0`"&,``8A@A``,8P`(#D"&60P6\E@(;<"91!;P"("`A$&(`+ZX1
    -M!;@,`"]"`````)8"&W"F0@6\E@(;<@`"$@(P0@`/HB(``I(F``,"`"`A#``Q
    -M5B0%``&2)@`$`@`@(0P`,58D!0`%DB8`!@(`("$D!0`"#``Q5BS&``&2)@`'
    -M`@`@(0P`,58D!0`#DB8`!20%``0,`#%6`@`@(0P`+X<"`"`AC@(``#0$@``\
    -M`P`"`$00(:Q#`3".`@``C[\`#(^R``B/L0`$C[````!$$"$\`P(`K$,!.`/@
    -M``@GO0`0E@(;P````".`P`,`B`@(20%``(`8A@AK@,`#`P`
    -M+H$``#`ACB(``#0$@`".!0!``$08(8QG`2R,9@$T`.40*Q1``%$`````C@,`
    -M1`##$"M00``.`,,P(XX#`$0`PQ`K4$#_XX^_``B.(@```$00(:Q#`32.(@``
    -M/`,"``!$$"&L0P$X$`#_VH^_``@`Y2@CK@4`.*X&`#R.(Q>\C@0`#``#$(``
    -M0Q`A`$00*Q!``!L`9!`KC@(`%#P#$&(T8TW3<((0`@!#`!D``!`0``(1@@!%
    -M$"L40``)`````(X"`!QP@A`"`$,`&0``$!```A&"`$80*Q!```4`````#``O
    -MAP(@("$0`/^ZC[\`"`P`,*0"("`A$`#_^0`````00/^S/`,08HX"`!`T8TW3
    -M<((0`@!#`!D``!`0``(1@@!%$"L40``-`````(X"`!AP@A`"`$,`&0``$!``
    -M`A&"`$80*U!`_Z./OP`(#``P)`(@("$0`/_B``````P`+[@"("`A$`#_W@``
    -M``"L90$LCB(``#P#``(`1!`AK$,!,!``_Z^.`P!$)*7__RRB``4GO?]P`(!H
    -M(1!``%(`P&`A/`.``@`%$(`D8PVL`$,0(8Q"````0``(`````#P"@`(\!H`"
    -M)$,-*(VE``",1`THC&(`!(S##3`T"H````Q(@`$]2"&OH@`$`*HH(:^C``BO
    -MI```C2,``(RD&%`\`O`/-$+__P""("0``QT`/`(/\`!B&"0`@R`E/`B``B3&
    -M#3"LI!A0C,(`!(T##3B-I@``KZ(`#*^C`!``RC`AC2(`"(S%&%P\`__`/`0`
    -M/S1C?_\TA(````(3P`!$$"0`HR@D`*(H)3P'@`(E"`TXK,487(SC#4"-`@`$
    -MC:4``*^C`!BOH@`4`*HH(8TB`!",I!A<)`.`?P`"$<``@R`D,$)_@`""("6L
    -MI!A<).<-0(SC``2-I0``/`+\`Z^C`!P`JB@AC*086(TC`!@T0O__`((@)``#
    -M'(`\`@/\`&(8)`"#("6LI!A8`^``"">]`)`\`H`"/`B``B1##4B,1`U(C&(`
    -M!(T##5``!F`KC:8````,6(`!?5@A-`Z``*^C`"BOH@`DKZ0`(`#.,"&-8@`@
    -MC,48;#P#_^`\!``?-&,__S2$P````A.``$00)`"C*"0`HB@EK,48;#P'@`(E
    -M"`U0C0(`!(SC#5B-I0``KZ(`+*^C`#``KB@AC*08;(UC`"@\`O`?-$+__P""
    -M("0``QU`/`(/X`!B&"0`@R`EK*08;#P&@`(DYPU8C.(`!(S##6"-J```KZ(`
    -M-*^C`#@!#D`AC6,`,(T$&&@\!X`"/`+_`3P)@`(DY0UH-$+__R3",Q@`$
    -MC*4`!"4J#7",YPUH`((@)(TI#7`\`@#^``,<0`!B&"0`@R`EC4H`!*^F`#RO
    -MI0!$KZ<`0*^I`$BM!!AHC:4``(UD`#@\`H#_`*XH(8RC&&@T0O__``0F``!B
    -M&"0\`G\``((@)`!D&"6LHQAHC:4``(UD`$`D`__@`*XH(8RB&&@PA``?KZH`
    -M3`!#$"0`1!`EK*(8:(VD``"-9@!()`/`_P".("&,@AAL``8R`##&/P``0Q`D
    -M`$80):R"&&Q1@``(C:(``(VC````;A@AC&(8;#1"``&L8AAL$`#_B@`````D
    -M!/_^`$X0(8Q#&&P`9!@DK$,8;!``_X,`````/`*``B1##7B,A0``C&8`!(Q$
    -M#7@`#!@K-`*````#&(``HB@A`'T8(:^D`%"OI@!4C&0`4(RB(@@D`__`,(0`
    -M/P!#$"0`1!`EK*(B"!``_VX`````/`*``B1##8",1`V`C&4`"(QB``2-I@``
    -M``P8@*^D`%BOH@!*^I`'ROJP"$`*(H(8QB`&B,HQDD
    -M)`3_`0`"$$``9!@D,$(`_@!B&"6LHQDD$`#_,P````",A06XC(,``#0"@`",
    -MI@`T`&(8(8QJ`.PD!/__C&D`\(QG`/A0P``0K*D`,#P(OJ8`YA`K`.H8(Q1`
    -M``HU"')1C*(`+(RD`#``:1@C`&88(P!B&"$`9!@A`&@`&0``&!```R/"K*D`
    -M,*RG`#2LJ@`L`^``"`"`$"&,@P``-`*``#"E``<`8A@AK&4`6*R%&T@#X``(
    -MK(`;3(R"&_0`@&`A,,8W`(Q"````H&@A)8X;:(Q$``0D`A4`$,(`-0``&"$L
    -MPA4!$$``!P`#$$`D`A(`$,(`,20"%`!0P@`!)`,``@`#$$``1!`AE$4`EI1&
    -M`+241`"0E$@`G)1#`*Z41P"ZE$D`HI1*`,``!2F`E$L`QI1"`*@`A2`E``8Q
    -M@``(0P``9A@E``<[``"(("4`"4R```(6``!G&"4`"E2``(D@)0!J&"4`"UX`
    -M`((@)20"``$1H@`-`&LH)3FB``(`HB`*C8(``#0#@`"MS0`T`$,0(:Q$&6"-
    -M@@```$,0(:Q%&60#X``(`````!``__4`@"@A$`#_TR0#``(0`/_1)`,``2>]
    -M__"OOP``C*H!$``'/@`Q"`#_``<^`Q%(`!DDJ0"4K*@!$(R"!9@D0@`!K((%
    -MF"0"``&A(@`_C((;4!1```,D`@`"4,(`!($B`":/OP```^``"">]`!`D`P`!
    -M`&@P"B1"``(`XA`J%$#_^`#`*"$,`#*9`````!``__6/OP``C((;4!1`__*/
    -MOP``D2,`/X$B`#\D9@`!``8>`"A"``,00/_K``,>`R0"``$D!0`"`$HH"B0"
    -M``,48O_EH28`/Q``_^L`````E(,;(SB```D`P`_
    -M`$40(:Q#&?0#X``(`````#0#@```0Q`A$`#_TB0#``^,A```/`/\_S1C__^,
    -M@D`0-`6```!#$"2L@D`0C.0``"0#__V,@D`0`$,0)*R"0!",X@``)`,`#`!%
    -M$"&L0QGPC.(``"0#``$`11`AK$,!!(SD```D`\!_`(4@(8R"`!P`0Q`D-$(3
    -M@*R"`!R,X@``)`,`?P!%$"&L0QATC.(``"0#``X`11`AK$,8>(SB```D`P#_
    -M`$40(:Q#&?00P``&C.(``"0#`!\`11`AK$,8<`/@``@`````)`,`#Q``__L`
    -M11`A)[W_\*^R``BOL0`$K[\`#*^P``",@@``-`.```"`B"$`0Q`AC$(`S#!"
    -M``$00``'``"0(8^_``R/L@`(C[$`!(^P```#X``()[T`$(XC```T$(``)`0`
    -M/`!P&"&,8@#,-$(``:QB`,P,`&D_`````(XB````4!`AC$(`S#!"``$00``-
    -M)!``"0P`:3\D!``"CB(``#0#@``F$/__`$,0(8Q"`,PP0@`!$$```R0"__\6
    -M`O_U`````"92``$J0@`"5$#_XXXC```0`/_;C[\`##P+_]\\#=`^/`S0/CP*
    -M&2\\"1DK-`B``#0'@``U:___-:U&2#6,9X@U2K44-2FU%!"@`!0`@#`AC(,`
    -M``!H&"&,8@#`-$(`@*QB`,",@P``/`0`(`!H&"&,8@`$`$00):QB``2,P@``
    -M`$@0(:Q-(@B,P@```$@0(:Q*&7`#X``(K,`;4(R#```D!/]_`&<8(8QB`,``
    -M1!`DK&(`P(S#````9Q@AC&(`!`!+$"2L8@`$C,(```!'$"&L3"((C,(```!'
    -M$"&L21EP)`(``0/@``BLPAM0C((;])2#&^8D!@`!`(`X(1!F``>,0@``5&``
    -M/(SB``",0@`$C$(`-%!``#B,X@``C.(``#0%@``D`P`/`$40(:Q#&'",X@``
    -M)`,`#93D'/8`11`AK$,8=(SB```D`P`,,(0`\`!%$"&L0QAXC.(``"0#``4L
    -MA``P`$40(:Q&&?",X@```$40(:Q#&?04@`````"`,"$0:0`'
    -MC$(``!1@`#D`````C$(`!(Q"`#000``U`````(S#``"4Q1SVC&)`$#"E`/`L
    -MI0`P`$@0)*QB0!",Q```)`/__8R"0!``0Q`DK()`$(S"```D`\!_`$<0(:Q)
    -M`02,Q````(<@(8R"`!P`0Q`D-$(/@*R"`!R,P@``)`,`#P!'$"&L0QAPC,(`
    -M`"0#`'\`1Q`AK$,8=(S"```D`P`.`$<0(:Q#&'B,P@``)`,`#`!'$"&L0QGP
    -MC,(``"0#`/\`1Q`AK$,9]!2@``:,P@``)`,`%`!'$"&L0QGX`^``"``````D
    -M`P`8`$<0(:Q#&?@#X``(``````"`."$``#`A),(``0#F("$P1@#_+,,`("0"
    -M__\48/_ZH((`!)#B``,D0O__,$8`_R0"`/\0P@`1``800`!&$"$``A#``$<0
    -M(21"`"B00P`(),7__P#C("&@A@`$D$(`"0!B&"4`XQ@AH&8`!"0"`/\PI@#_
    -M%,+_\0`&$$`#X``(`````">]__"OL```/!"``B80-LBOL0`$K)`]`!`GO?_@+*(`!:^S``ROL```
    -MK[\`$*^R``BOL0`$`("`(1!``,0D$P`6/`.``@`%$(`D8PX$`$,0(8Q"````
    -M0``(`````(R$```T`H``/`,`!`""("&,@@`$`$,0):R"``00P``/``"8(8X%
    -M```D`]__/`3__(RB0!`TA/__`$,0)*RB0!".!0``/`,``HRB0`0`1!`D`$,0
    -M):RB0`0``)@A`F`0(8^_`!"/LP`,C[(`"(^Q``2/L````^``"">]`"!0P``:
    -M``"8(8R$```\`__\-&/__XR"0`0``(@A`$,0)*R"0`2.`@``/`,``8Q"0!``
    -M0Q`D4$``#0``F"$,`&D_)`0`R(X%```\`__\-&/__XRB0`0F,0`!*B0`%`!#
    -M$"2LHD`$5(#_\(X"```68/_<-`*``(X#```\!/_[`&(8(8QB``0TA/__`$00
    -M)*QB``00`/_4`F`0(8R$```T`H``/`,`!`""("&,@@`$`$,0):R"``10P/_*
    -M``"8(8X$```\`__\-&/__XR"0!`T0B``K()`$(X$``",@D`$`$,0)#P#``$`
    -M0Q`EK()`!!``_[P``)@A$,#_NP)@$"&,AP``)`+__20%``&,XT`,)`8``0``
    -MB"$`8A@DK.-`#(X#``",8D`0-$(@`*QB0!`,`#,F`````(X$```\`__\-&/_
    -M_XR"0`0`0Q`D/`,``0!#$"6L@D`$C@(``#P2``&,0D`0`%(0)%1`_YX``)@A
    -M#`!I/R0$``J.!```/`/__#1C__^,@D`$)C$``2HE`9``0Q`D`%(0):R"0`2.
    -M`P``C&)`##1"``&L8D`,5*#_ZXX"```0`/^,`F`0(1#`_XDD`O_^C(4``#P$
    -M__R,HT`,-(3__P``B"$`8A@DK*-`#(X#``",8D`$`$00)*QB0`2.`@``/`,`
    -M`8Q"0!``0Q`D4$``$0``F"$,`&D_)`0`"HX$```\`__\-&/__XR"0`0F,0`!
    -M*B4!D`!#$"2L@D`$C@,``(QB0`PT0@`"K&)`#%2@_^R.`@``C@8``#P#__PT
    -M8___C,)`!`(`("$``"@A`$,0)*S"0`0,`#,F```P(1``_UT"8!`A$`#_6B03
    -M`!&,@@``K$4`#`/@``@`````C(,``"0"``2L8@`()`(``:R"%^0#X``(````
    -M`">]__"OL@`(K[```*^_``ROL0`$C(,``"0"`"``@(`AK&(`"(R"&[0P0@!`
    -M$$``!202`^B,@AP<)`,G$#A"``4`8I`*$D``#0``B"&.`@``)`0`"B8Q``&,
    -M0@`(,$(`!!!```T``!`A#`!I/P`````",A`K5$#_]HX"```D`@`6C[\`#(^R
    -M``B/L0`$C[````/@``@GO0`0K@`7Y!``__F/OP`,)[W_\*^P``"OOP`$C((7
    -MQ!1```P`@(`AC@0``#0"@`"/OP`$`((@(8R"`$B/L```)`/_WP!#$"2L@@!(
    -M`^``"">]`!`,`#!<`````!``__..!```C(,``#0"@```8A@AC&(`2#1"`""L
    -M8@!(`^``"`````",@@``-`.```!#$"&L10!`C((```!#$"&L1@!$`^``"```
    -M```LP@`%`(!((1!``#0`H$`A/`.``@`&$(`D8PY@`$,0(8Q"````0``(````
    -M`#"E`#\Q`@0`-*,`0(R$````HA@*-`:``#$%"``T8@"``$48"P"&("&M*!M$
    -MK(,`/(TB&T2-(P``)`<`(#!%`$``X"`A,$(`@`!F&"$0H``#``(@"CP"`@(`
    -M@B`E-((`"`!%(`NL9`$,C2(;1`#@("$P0P!`,$(`@!1@``\``B`*5(``#HTC
    -M``"-(@``)`3_[XQ#`#0`9!@DK$,`-(TB```D!/_WC$,`-`!D&"2L0P`T`^``
    -M"`````"-(P``C&(`-#1"`!"L8@`T$`#_]8TB``",A!M$C28``#0'@```A2`E
    -M,((`/S"%!``T0P!``$48"C1B`(``QS`A,(4(``!%&`N,P@`\C,(!#*TD&T2L
    -MPP`\C2(;1(TC```D!@`@,$4`0`#`("$P0@"``&<8(1"@``,``B`*/`("`@""
    -M("4T@@`(`$4@"ZQD`0R-(AM$$`#_R`#`("&,A1M$``@0)XR&````HB@D,*(`
    -M/S"D!``T0P!``$08"C0'@``T8@"``,
    -MK24;1#"D`#\Q`@0`C24``#2#`$``@A@*-`:``#$$"``T8@"``$08"P"F*"&L
    -MHP`\C2,````($((P10`@,00`0`!F&"$0@``#`*`P(3P"`@(`HC`E-,(`"`!$
    -M,`NL9@$,5(#_L8TC``!0H/^CC2(``!``_ZV-(P``C(0;1(TF```T!X``,(,`
    -M/S"%!``T8@!``&40"C"$"``T0P"``&00"P#',"&LP@`\C2(;1(TC```D!@`@
    -M,$4`0`#`("$P0@"``&<8(1"@``,``B`*/`("`@""("4T@@`(`$4@"ZQD`0R-
    -M(AM$`,`@(3!#`$`P0@"`%&```P`"(`I0@``,C2(``(TC``",8@`T-$(`$*QB
    -M`#2-(@``)`3_]XQ#`#0`9!@DK$,`-`/@``@`````)`3_[XQ#`#0`9!@DK$,`
    -M-!``__6-(@```*`P(22E``@PH@`/)`/_\"1"`"<`HR@D`$,X)`"G$"$GO?_P
    -M`$40*Z^_``2OL````(!`(11```<`H!@AO+$``"2E`!``9Q`A`$40*Q!`__L`
    -M````)-``$)("``2`@`$``(1PJ#"
    -M`$N2`@`'``(00C!"``$40``8)0(<&)("``<``A"",$(``11```XD!``;D@(`
    -M!P`"$0(P0@`!$$``#B4"'!B2`@`'``(1`C!"``$00``"```8(9(#``8D!``<
    -MH,,`18^_``2/L````(`0(0/@``@GO0`0C$,`/!!@`#BLP@!,C@(````"$\(P
    -M0@`?`&(0(9!"``2@P@!&D@(`!P`"$$(P0@`!5$``#XT"&U"2`@`'``(0PC!"
    -M``$00``@`````)#"`$0T0@`!H,(`1)("``(``A%",$(``11`_^$D!``:C0(;
    -M4!!```H`````D,,`2HT"&TA00P`&K0`;3(T"&TPD0@`!+$,``Q!@``>M`AM,
    -MD@(``B0$`!T``A$",$(``1``_\\``B`*D,4`2@P`,ID!`"`A$`#_]@````"2
    -M`@`'``(10C!"``$00/_@`````)#"`$00`/_<-$(``A``_\T``!`AK(``"*R`
    -M``RL@``0K(``%"2$``B,@@`$)`/P`#"E#_\`0Q`D`$40)0/@``BL@@`$C((`
    -M`(Q"``@P0@`$`^``"``"$"LGO?^@K[X`4*^W`$ROM@!(K[4`1*^T`$"OL0`T
    -MK[\`5*^S`#ROL@`XK[``,(R"&_0`H*`A)(4<&(Q#`!B,0@```("((:^C`!RO
    -MI@`(``#P(0``L"&OH``4KZ(`&"27&V@``*@AKZ4`)!*``)(D`___)`8`$`P`
    -M'
    -M``26(QSVCB0``#0"@``P8P#P`((@(2QC`#`D`@`'K((8`!!@`>X"("`A#`!)
    -M;@*`*"&6)QST+.(`0A1``#`PY/__CB0``):%```T`H``/`,``@""("$T8Z`"
    -M)`()M*R#&"P0H@'/CZ,`&(QB``0\`V9F-&-F9Y1"`"0`0P`8``(7PP``&!``
    -M`QA#`&(@(Y:"``(D`Q0`,$(W`!!#`;`T`X``CB(```!#$"&L0!E,CB0``#0&
    -M@``D`OW_`(8@(8R#(B@\!?_^-*4#_P!B&"2L@R(HCB,```!F&"&,8B(H`$40
    -M)#1""`"L8B(HCB(``"0#``\`1A`AK$,`8##D__\L@@!#%$``!BR"`$2.(@``
    -M-`.```!#$"&L0")4+((`1%1```Z.(@``CB4``"0#@!\\!/__C*(2,#2$?_\`
    -M0Q`D-$(!X*RB$C".(P``C&(`,`!$$"2L8@`PCB(``#00@``D`P`.`%`0(:Q#
    -M&'@"("`A`H`H(0.@,"$D!P`_#`!`MB0(``$00``.)`/__X^_`%2/O@!0C[<`
    -M3(^V`$B/M0!$C[0`0(^S`#R/L@`XC[$`-(^P`#``8!`A`^``"">]`&"/I``<
    -MCZ8`&`/`."&,@@`$C,4`!`(@("$"@#`A`$#X"0.@0"&6@@`",$($`!1``5@"
    -M("`ACZ(`&`(@("$"@#`A#``_58Q%``2/HP`($&``!`````".(@``CZ0`%*Q$
    -M$4"*XP`ZFN,`/8KB`#J:X@`]BN0`.IKD`#V*Y@`ZFN8`/3!C_P```QH`CB4`
    -M```"%@``!"("`$,0)3"$_P"6XP`^`$00)0`&-@(`1A`E`+`H(:RB``"/I@`,
    -M,&(`_XXD`````QH"``(2`([E`$@`0Q`E`,(8)20"``(0H@$I`)`@(8^E`"`\
    -M`A"``&48)8^F`"0`8A`EK((`!(C#`$*8PP!%B,(`0IC"`$6(Q`!"F,0`10#`
    -M*"&(I@!"F*8`13!C_P```QH```(6```$(@(`0Q`E,(3_``!$$"4`!C8"CB4`
    -M``!&$"6/I@`D-!"```"P*"&4PP!&K*(`"(XD```P8@#_``(2```#&@(`0Q`E
    -M`)`@(:R"``R.(@``EH,``H^D`!``4!`A,&,W`*Q$`%@D`A0`4&(`]HXE'/R.
    -M(P``)`+__X^E`!RL8@"`CB0``"0#``J,H@``K(,`%(XF```D`P<``B`@(0#0
    -M,"&LPP`8`$#X"0*`*"$40/]]`$`8(8XB&_Q00``/CB4```!`("$``)`AC(4`
    -M`"92``$0H``(+D8`@8XB``",@P`$)(0`"`!%$"&L0P``5,#_]XR%``".)0``
    -M-`.```"C&"&,8@!8KB`;3#!"`/^N(AM(C&(B"#!"(`!00``#KB`;4"0"``&N
    -M(AM0-`*```"B$"&6@P`"C$(9%#!C`@`08`"[,$0__SP#NBX`!!"`-&.+HP!#
    -M`!D``!`0``(1`C00@```L!@A)$0`9"0"``&L8A@<#`!I/R02``&.(@``)`,X
    -M``!0$"&,4Q@(K$,8"(XB````4!`AC$(<)#!"`!`40`"5`````(XB```T!H``
    -MEN0`'`!&$"&L4Q@(CB,```!F&"&,8AA@-$(``:QB&&".(P```&88(8QB&&`T
    -M0@`"K&(88%"``(*.(AOTEH(``B0#$@`P0C<`$$,`?"0"``*.)1OTC*,`+!!B
    -M`'@D`P`!CB0``*RC`"P`AB`AC((9(#1"\`"L@AD@CB,``#P$``$`9A@AC&(9
    -M(`!$$"6L8AD@#``].0(@("$``)`ACB0``"0#``$"0Q@$`!(0@"92``$`1!`A
    -M+D0`"JQ#$`!4@/_XCB0``(XC```\`@`(-$((H*XB&T"L8@"@CB4``#P#``<\
    -M!@"`C*(`K`(@("$`0Q`EK*(`K(XB&T".(P```$80):XB&T",8@"@`$80):QB
    -M`*".)0``/`,@`(RB`*P`0Q`EK*(`K`P`+'8`````%$``/P```````)`ACB(`
    -M`#00@``D!``*`%`0(8Q"&&`P0@`!$$``!B92``$,`&D_`````"Y"`&140/_V
    -MCB(```P`,_8"("`ACB,``#0"@``\!/Y_`&(8(8QB`"`TA/__`$00)*QB`"".
    -M(ANT,$(`0!1``!\"@"@A`B`@(0P`,\$``"@AEB,<\"QB``900``.CB(``"0"
    -M``508@`(EB(<\HXB```T`X```$,0(20#`%*L0P$($`#^Q0``&"$L0@`(%$#_
    -M^(XB```\`P`!-&,`J@!0$"&L0P$8CB(``"0#,A``4!`AK$,!'!``_^Z.(@``
    -M#``Z*P(@("$0`/_@`B`@(0P`++@"("`A$`#_P```D"&.(AOT$`#_DZQ``"P,
    -M`&D_)`0`R"Y"`!000/]H)E(``8XB```T`X```$,0(8Q"'"0P0@`0%$#_]0``
    -M```0`/]@CB(``#P"S,PT0LS-`((`&0``$!`0`/]'``(0P@(@("$,`#,5+*8`
    -M`1``_PB.(P``CZ(`(`!B&"40`/[8/`(0@@P`0&X"@"@A$`#^IX^B`!B/HP`8
    -MCB4````$(".,8@`$``0D@#P#`/R`0@`B`(,@)#0#@````A`C``(1@#!"#\``
    -MHR@A`$00):RB&4P0`/Y%CB0``(^F`!@\`F9F-$)F9XS#``2$9``FE&,`)`!D
    -M&",`8@`8``,?PP``$!```A!#`$,0(P`"%``0`/XM``(D`PP`:3\D!``!`!Z`
    -M@```F"$D$@`H/`.``B1C%[P`$Q#``$,0(8Q$```"`Q@ACB(``(QE```FM0`!
    -M`$00(3*C`#\F4O__)A``&"9S``,D!``!K$4``!!@`#L`````!D'_[CP#@`(,
    -M`&D_)`0``0``@"$\`H`"`!`8P"1"&Y0`8A@AC&0``(XB``",90`$)K4``0!$
    -M$"$RHP`_)A```20$``&L10``$&``(P`````J`@$>%$#_\#P"@`(,`&D_)`0`
    -M`0`6@(```)@A)!(`/SP#@`(D8R2$`!,0@`!#$"&,1````@,8(8XB``",90``
    -M)K4``0!$$"$RHP`_)E+__R80``PF``(0`/VJ)!8``1``__TD'@`!$`#_\B0>``4`@#@AC(0``#0&@``D`__\
    -M`(8@(8R"`,"4J``"`$,0)#1"``*L@@#`C.0``"0#_\,Q!2```(8@(8R"`,``
    -M0Q`D-$(`&*R"`,",X@```$8P(8S"`,@P0___/`(G$!2@``,`8B`E/`(J^`!B
    -M("4Q`B``,$7__S$""``T"8``K,0`R!!``!DD`\``C.0```")("&,@@`4`$,0
    -M)#1#$3`T0@^@`&40"JR"`!2,X@```$D@(8R"`,0P0___/`(%>!2@``,`8A`E
    -M/`(&!`!B$"6L@@#$)`,$L"0"!2@Q!"```$08"HSB``"L0Q!P`^``"```$"$G
    -MO?_PK[\```P`.\\D!0`"C[\```/@``@GO0`0)[W_X*^V`!BOM0`4K[0`$*^S
    -M``ROL@`(K[```*^_`!ROL0`$`*"8(0"`@"$D%@`!``"0(0``J"$0H``F``"@
    -M(92E``*4@ASV,*,W`#!"`/`X8Q0`-*0"`"Q"`#`40``&`(,H"C"C`@`D%`#K
    -M)`(`Z@!#H`HD$@`(,*,&`"0"!@`08@!6,*,$`#9"``$`0Y`*,*(@`#9#``(P
    -MI`@`$(``30!BD`J.`ANT,$(`0%!```2N`!V()`(``392`!"N`AV(,*,!`"0"
    -M``,``*@A`$.H"P``L"$"`"`A#``[SR0%`!,00``,`$"((0(@$"&/OP`]__"OL0`$K[```*^_``B,BQOT)`(``0"`@"&-
    -M8P`L`*"((1!B`#\DA!MHEB(``B0#$@`P0C<`$$,`!"0"``*-8P`L4&(`(HX%
    -M```"("@A#``]!`(`("&6)0`",*(``11``!4D`P`8C@,``#0"@``PI"```&(8
    -M(8QB&&`T0@`"K&(88!2```D`````E@(<]C!"`/`L0@`P%$``!P``&"$PH@0`
    -M$$``!8^_``@,`$AQ`@`@(0``&"&/OP`(C[$`!(^P````8!`A`^``"">]`!`T
    -M!H``D(0`4P"F*"&,HQD@/`+__S1"#_\`!",``&(8)#"$\```9!@EK*,9((X$
    -M```D`@`!K6(`+`"&("&,@QD@/`(``0!B&"6L@QD@$`#_S`(@*"&.`@``-`.`
    -M``!#$"&,0AD@/`,``0!#$"140/^\EB(``JU@`"P``"`AC@,``#0"@``DA``!
    -M`&(H(8RJ'!`LAP`*C*8<%(RH'!@10``#`````!3```@`!AA"C*(9(#P#``$`
    -M0Q`EK*(9(%3@__".`P````880@`*$$(`0Q`A``(9PA!@_ZD`!B'"*((``E1`
    -M_Z<"("@A``@0(P!#`!I08``!```!S8X(```T"8``)`/X'P$)0"&-!QD@`.,X
    -M)"0#``*M8P`L)`,`'P``$!(``A8```(6`P%$`!LH1?_@*$8`(`!F$`HXI0``
    -M)`/_X`!E$`L``A%`,$('X`#B."6M!QD@C@<``"0"_^``Z3@AC.89(`#","0D
    -M`@`/```@$B2$_X`H@__P*(4`$`!%(`HX8P``)`+_\`!#(`LPA``?`,0P):SF
    -M&2".`P```&D8(8QB&2`T0@@`K&(9(!``_W0"("@A)[W_X*^S``ROL@`(K[$`
    -M!*^P``"OOP`0C(,```"`B"$D$___C&(`""00``8``)`A-$(`(*QB``B,@P``
    -MC&((@#1"`_^L8@B`,@(`!!!```DR`@`"CB(``(Q"``@P0@`$%$``!#("``(D
    -M`O_[`@*`)#("``(00``*,@(``8XB``",0@A`,$(#_Q1```4R`@`!)`+__0("
    -M@"0V$``!,@(``1!```T``#`ACB0`````*"&,@@H`)*4``2RC``HP0@`#`,(P
    -M(11@__HDA``$%,```B0"__X"`H`D$@``#B0$`#(,`&D_)E(``2Y"``H40/_7
    -M,@(`!`)@$"&/OP`0C[,`#(^R``B/L0`$C[````/@``@GO0`@$`#_]P``F"$G
    -MO?_@K[,`##"B`!$D$___K[$`!*^P``"OOP`0K[(`"`"@@"$`@(@A$$``)P"E
    -MF`L``"@A#``TY20&``$00``)`$`8(8^_`!"/LP`,C[(`"(^Q``2/L````&`0
    -M(0/@``@GO0`@CB(```(@("&L0``DCB(``(Q"`"0,`#N(`````!!``$HD`O_O
    -M#`!I/R0$``^.(@``)`0``380`!.,0@`,#`!JO``````,`&G3``````P`::L`
    -M````#`!I/R0$``H,`&J\```@(0P`:3\D!``/CB(``"0$``\RC(,`````,"$0
    -M`/_:)`@``8R"&[2,@P```(`H(0`"$((P0@`!K&($((RB&[R,HP``/`0`$``"
    -M$@(P0@`'K&(&`(RC```TA`(!```X(8QB!@`DIAT!-$(`"*QB!@",H@``K$0&
    -M!(RB``"L0`8@C*(``*Q'!`"0Q```C*(``"3G``$LXP"`K$0$!!1@__@DQ@`!
    -M`^``"``````GO?_`K[X`,*^W`"ROM@`HK[4`)*^T`""OL@`8K[\`-*^S`!RO
    -ML0`4K[``$)3"``*,@QOT,.?__S!*-P`D`A4``*!((0#`D"$`@*@A`0#P(:^G
    -M``",<0`$``"@(0``L"$``+@AKZ``"*^@``P``"@A$4(!-HQS`"`I0A4!$$`!
    -M/R0")``D`A(`$4(!-B0"%`!10@$OE2(`]H^B```\!(`"/`.``@`",(``!2A`
    -M)(0GC"1C)Z0`J2@A`,0@(0##&"$\`H`"C(0``(QC``"4IP#2C$(GB)2E`(2N
    -M9``$KF,`"*^G``2N8@``)F,`#"0$`"<\`H`")$(GO`#"$"&,0@``)(3__R3&
    -M`!BL8@``!('_^"1C``0F<``,`@`@(20&``$D!P$N#``^V```0"&7Q0```@`@
    -M(20&``(D!P$.#``^V```0"&7Q0`"`@`@(20&``(D!P$!#``^V```0"&60@`"
    -M,$($`%1``,Z.(@`(/_F)A``!(^_`!"/LP`,C[(`"(^Q``2/L````^``"">]`"`DQO__)[W_
    -M\*^_````H%`A,,@`!P``8"$`!A#"`*!((1B@`!P``%@A``(0@`!$,"$!"2@A
    -M**,`"20"``@`0R@*)`(``0$"(`0`HA`$)(3__XS#```D0O__`$00)@`'(,``
    -M@A`$`&(8)`"#&`8!*!`A`0,8!@%C&`0`J"@C)$G_^`"4!95@A``!`(1T@
    -M_^@DQ@`$`8`@(0P`6)0!0"@AC[\```/@``@GO0`0)[W_\"0$`."OOP`$K[``
    -M``P`>E<`H(`AK@(`((^_``2/L`````(8*P!@$"$#X``()[T`$">]__"OL```
    -MK[\`!(RB`"``H(`A%$``!0!`("&/OP`$C[````/@``@GO0`0#`!Z:@`````0
    -M`/_YK@``(">]_]"OO@`@K[8`&*^T`!"OLP`,K[(`"*^Q``2OOP`DK[<`'*^U
    -M`!2OL```C((;]`#`\"&4Q@`"C$,```"`B"$PPO__``(B`@`"$P(P4P`!,,@W
    -M`"0"%0``H)`AE'<``#"4``$1`@#U``"P(2D"%0$00`#V)`(D`"0"$@`1`@#Q
    -M)`(4`%$"``$D%@`"CB<``#0"@```%JA``.(X(0*R@"&,XAD0E@,`BB0$_`8`
    -M1!`D``,9``!#$"6.)1N<-$(``0(@("$PQO__K.(9$`P`,J$`````*NI0`!5`
    -M``:6!``\4H``!8XE````$Q!``%(0(91$`$*.)0``-`*````$(<``HB@AC*(8
    -M1"0#P'\PA#^``$,0)`!$$"6LHAA$`M(P(15```6`Q0!H4H``!(XD```""/OP`DC[X`((^W`!R/M@`8C[4`%(^T`!"/LP`,
    -MC[(`"(^Q``2/L````^``"">]`#`T`X```$,0(:Q`&>`0`/_QC[\`)!5`_^0J
    -MXE`!$`#_UHXF```0`/\3)!8``A``_Q$D%@`!$0(``R0")0!5`O\.CB<``!``
    -M_PL``+`AE*8``I2E```\`F0`,,8!`#P#R```9A`+`$4`&U"@``$```'-`(!0
    -M(20(`!\``$@2`0D0!C!"``%40``%C48``"4(__]5`/_[`0D0!HU&```D`@`F
    -M`$A`(S0'@``D`P`7`,]_\`D0@]\`Z`8(21$`$",10``C$8`!(Q'``B,2``,K&4``*QF``2L9P`(
    -MK&@`#"1"`!`41/_V)&,`$`/@``@GO0!`)[W_$*^^`.`GO@`0``<\`*^W`-RO
    -MM@#8K[(`R*^Q`,0`H)`A`("((0``*"$#P"`A`,"X(2>V`)`D!@"`KZ@`M*^_
    -M`.2OM`#0K[``P*^U`-0`!X0##`!PJJ^S`,P"P"`A```H(0P`<*HD!@`@ED(`
    -M`HXC&_0``$`A,$(@`(QT```00`#\KZ``N(8B&\"6(QO``@`@(0!0$"I40``!
    -M`&`@(0`$%````H0#*@(`0!1```("`#@A)`<`/P`'%````H0#*@(`/U!```26
    -M(QO$%@``"">U`+*6(QO$/`*``B1"+,```QA``&(8(81H```GM0"RK[4``(Z&
    -M``PGLP"P`@!((0(@("$"P"@A`D`X(0*`4"$,`$4$`F!8(3P"@`*,0D/\6$``
    -M!(XB&_0,`$"D`L`@(8XB&_0"8#`A`J`X(8Q"`!@"X$@A`B`@(8Q"``@GI0`0
    -M`$#X"0)`0"&6(QSVEZ(`KC!C`/`D0@`$+&,`,!1@`+^GH@"NEZ,`LB0"`#\#
    -MP"`A`$,0(S!%__\``#`AE(,`@"3&``$HQP`0`*,8(3!B__\L0@!`%$```Z2#
    -M`(`D`@`_I((`@!3@__4DA``"CB(;](Q#``"D10`DC&(`!)1"`"@L0@`"$$``
    -M)SP"@`*6(AST+$(`0A!```>/H@"TED(``B0#%``P0C<`4$,`?)9#``"/H@"T
    -M%$``!30%H8"/H@"X$$``&#P"@`(T!:&````P(0`&$(`GHP`0`$,0(91#``"4
    -M0@`"CB0````#&@```A(`-$(`_S1C`/\``A0`,&/__R3&``$`0S@E`(4@(22B
    -M``0HPP`@K(<``!1@_^TP1?__/`*``HQ"0_PH0@`"$$``5P````"7HP"6EZ0`
    -ME)>B`)(P8P`_,(0`/P`$)````QX`,$(`/P!D&"4``A(``&(8)9>B`)"7I`"<
    -MCB4``#!"`#\`8C@EEZ,`GI>B`)HPA``_,&,`/P`$)````QX`,$(`/P!D&"4`
    -M`A(``&(8)9>B`)@T!H```*8H(3!"`#^LIQDTEZ0`H@!B."67HP"DEZ(`KC"$
    -M`#\P8P`_``0D```#'@`P0@`_`&08)0`"$@".)0```&(8)9>B`*``IB@AK*<9
    -M.#!"`#\`8C@EEZ0`JI>C`*R7H@"HCB4``#!C`#\PA``_``0D```#'@`P0@`_
    -M`*8H(0!D&"4``A(`K*C`)8D`@FT$&(`
    -M$#P#9F:.@@`$-&-F9Y1"`"0`0P`8``(7PP``&!```QA#`&(X(P+`*"$"("`A
    -M#`!&;2>F`!`D`@`!$`#_=*^B`+B.@P`$/`)F9C1"9F>$9``FE&,`)`!D&",`
    -M8@`8``,?PP``$!```A!#`$,0(P`"%``0`/_L``(\`Q``_U,``"@AAB(;PI8C
    -M&\(0`/\%`@`@(2RC`$``H#@A)`(`/P!#.`HGO?_@``<\`"2%&W``!SP#`Z`P
    -M(:^_`!`,`$"V``!`(8^_`!`#X``()[T`(#"$__\PI?__,,;__P`'/```"$0`
    -M`,1((P"%4",`Q1@C``<4`Q#%``P`""0#`2(`&%!@``$```'-<40`````$!(`
    -M``````````!#`!H``!@2``,4```"%`,#X``(`````)2C````!"0`,,;__P`$
    -M)`,`!A!``*(0(0!D&"H48``$A$+__JS@```#X``(K0````""$"H40``$),+_
    -M_ZSB```#X``(K0(``!#```X``!@A``,00`!%2"&5(@``$$0`#21J``&5(@`"
    -M`((0*A1```D`P``F"$D$@`!%$``
    -M-```&"$``(`A`!(00`!1$"&40@```%`0*Q!```H`$Q!`)N+__P)"$"H00``&
    -M`!,00"9B``$F0P`!,%/__S!R__\`$Q!``!(80`!6("$`=D`A`%$0(0!Q&"&4
    -M9@``A(<``)1%``"%"```#`!!Y@(`("$``B0```0D`P`0&$``=1@A`)0@*A2`
    -M``RD8@``+@(`0!!```HF`@`!`@`0(28#``$P]`#"$@@!^A(,```"`2"$`
    -M0Q`C*$(`?Q1``$24A`!^)(+_@@`"%````E0#``04```")`,DA___)`(`/R4F
    -M`'XDQO_^A,,``"1"__\``A0``.,8*A!@``,``A0#!$'_^23&__X`0#`A)`<`
    -M/R3#__\P8O__+$(`/Q!``!(`!A!``$D0(81"````1!`J%$``#0`#%````C0#
    -M``800"3#__\`24`A,&+__RQ"`#\00``%`````(4"````1!`J$$#_]0`#%``0
    -MP``,).+__P`'&$`DA/_^``(4``!E&"$`!"0```(\`Z1F```$X?_@``0D`P/@
    -M``@!0!`A!.#__0``````!Q!``$4H(23B__^4HP`"``(4```"/`.DHP``!.'_
    -M^B2E__X0`/_R`````!``_[\`8%`AA((`?H2H````@%`A)`P`0`!($",H0@!_
    -M%$``392#`'XD8O^"``(4```";`,``Q0```(D`R0)`#\DB___)4@`?B4(__Z%
    -M`P``)2+__P`"%``!8Q@J$&```P`"3`,%(?_Y)0C__I2B`'X!($`A)`D`/Z3B
    -M``"$X@```$00*E!``#$``&`A%0```P````!5@``M``!@(1D```X`"!!``$H8
    -M(81B````1!`J%$``"24"__\``A0```)$`QD```4D8__^A&(```!$$"H00/_Y
    -M)0+__Q4```,E(O__$8``#0```````A0```D80"2$__X`9A@A``0D```"3`,!
    -M#!`EI&(```4A_]P`!"0#`^``"`&@$"$%(/_]```````)$$``1C`A)2+__Y3#
    -M``(``A0```),`Z3#```%(?_Z),;__A``__(``````*!0(1``_](D"``_$`#_
    -MM@$`:"$GO?O0K[X$(*^_!"2OMP0K:>B`[JGH@.X``,<0``$)$"4Q0`&``0D
    -M`P`#'`.OI`/@KZ,#Y```J"$``(@A)Z0#N`(E$`W`0@"X"`A`!&`@`(1@"$`$("``A6`(984``8F!0`()[,!(``4B$`"(#`A
    -M#`!PG280`!`"`"@A`B`P(0P`<)T"8"`AAJ<``B>R`S@"@"`A`N`H(0)@,"$,
    -M`$(F`D!`(1!``*:/I@/P`D`@(2>E`[@`W1`A)$,!.#!B``,00`$4KZ8#Z`"@
    -M$"&(AP``F(<``XB(``28B``'B(4`")B%``N(A@`,F(8`#ZAG``"X9P`#J&@`
    -M!+AH``>H90`(N&4`"ZAF``RX9@`/)(0`$!2"_^XD8P`0E[$#N@+@("$`$8"`
    -M`A&`(0`0@(`"%8`AEA0`!B8%``@F$``0`!2(0`P`<)T"(#`A`@`H(0(@,"$,
    -M`'"=`F`@(8:G``("@"`A`N`H(0)@,"$,`$(F`D!`(1!``'./IP/H`D!`(0#]
    -M$"$D0P(X,&(``Q!``-4GI`.X`(`0(8D$``"9!``#B04`!)D%``>)!@`(F08`
    -M"XD'``R9!P`/J&0``+AD``.H90`$N&4`!ZAF``BX9@`+J&<`#+AG``\E"``0
    -M%0+_[B1C`!"/J`/PCZ,#[(^B`\0FU@`!)0@`@"1C`%0`5A`KKZ@#\!!`_XBO
    -MHP/LCZ<#W(^F`\"/I0/$C.0````&$$"7IP.Z`$00(0`%&$``9!@AE%0``#0"
    -MWJT`IJ@C$.(`@91S`````(@A`Z"0(0`5@8"/J`/8`A&`(0`0@$`"'8`AAD8"8#`ACZ,#V(9'`CB&"`(XE&0```*`*"&F0@`(
    -M`F`P(0P`0>8F,0`!+B,`0*9"`(@48/_I)E(``B0"``(40`!%AZ,!!H^G`^``
    -M9Q`J%$``!(^H`^0`:!`J$$``*8^E`\R/I0/,#`!">B>D``@`0$@A``(?PI>B
    -M`(:7I0.XCZ8#T``"%````B?"CZ<#U``"%`,!(Q@A`$00(0`"$$,``QA#I\4`
    -M`J>B``"GQ0``I,,``*3B``"/J`/4CZ,#R)4"``",9!OT)`,`/P!B&".D@P`D
    -MC[\$)(^^!""/MP0B>D`(@`0$@A``(?PI>B`0:7I0.Z`2,8(0`"%````B?"``(4`P!$
    -M$"$``A!#I\4``H^D`]"GH@``I\4``(^E`]0``QA#I(,``!``_]FDH@``CZ8#
    -MS">D``@GI0"(#`!"QB>G``(`0$@AEZ,``@`")\*7H@"&``,<```#+\(``A0`
    -M``(WP@`#'`,``A0#EZ@#N)>G`[H`91@A`$80(8^E`]"/I@/4`20@(0`$($,`
    -M`QA#``(00Z2D``"GHP``I,(``*?'``(0`/^ZI\@`````B"$#H(`A`!41@`!1
    -M$"$``A!``%T0(81(`3B/H@/8A@8F,0`!+B,`
    -M0*8"``@48/_Q)A```H^E`\P,`$)Z)Z0`"`!`2"$``A_"EZ(`AI>E`[B/I@/4
    -M``(4```")\(``A0#`$00(8^D`]`!(Q@A``(00P`#&$.D@P``IZ(``*3"``"G
    -MQ0`"$`#_DJ?%``"-`@``C04`!(T&``B-!P`,K&(``*QE``2L9@`(K&<`#"4(
    -M`!`5!/_V)&,`$!``_S6/J`/PC(<``(R(``2,@@`(C(8`#*QG``"L:``$K&(`
    -M"*QF``PDA``0%(7_]B1C`!`0`/[VE[$#NB>S`0@"8"`A`!&`@`(1@"$`$("`
    -M`A6`(984``8F!0`()[(!(``4B$`"(#`A#`!PG280`!`"`"@A`B`P(0P`<)T"
    -M0"`AAJ<``B>P`S@"@"`A`F`H(0)`,"$,`$(F`@!`(1!`_V6/I0/P`@!`(0"]
    -M$"$D0P$X,&(``Q!``!)!``(F00`
    -M"XD%``R9!0`/J&8``+AF``.H9P`$N&<`!ZAD``BX9``+J&4`#+AE``\E"``0
    -M%0+_[B1C`!`0`/[RCZ@#\(T&``"-!P`$C0(`"(T%``RL9@``K&<`!*QB``BL
    -M90`,)0@`$!4$__8D8P`0$`#^Y8^H`_`D8P`L$`#^0:^C`]P0`/_])&,`(!""
    -M``,D`B4`%(+^/(^D`]00`/_W)&,`%">]_Y"OJP`HCZL`<"0"`#^OO@!@K[<`
    -M7*^V`%BOM0!4K[0`4*^R`$BOL0!$K[``0*^_`&2OLP!,`."@(:^B`"PD`O_!
    -ME.<``I:#``RE8@``CZ(`*`%`D"&-2@`$)`L`/Z1+````"$0```E,```#&$"5
    -M0@$6``A$`P`)3`,P8___KZ@`(*^I`"2OHP`PDI,`#@"`J"$`H(`A`,"X(3#^
    -M-P`D%@`_``"((1!``!2OH``T`!$00`!*$"&40@$8,$/__Q!@``B``27HP`"EZ0```$B*"H!(S`J`20X
    -M*@$E$`L!)A@+`2<@"Z8"``JF`P`,I@0`#J8)``BF"0`&I@D`!*8)``*F"0``
    -MED(``"Q"0`!40``,I@D`'C/#$``08`"*CD(`!)1"``X!(A`J5$``!`$@$"$0
    -M8`""CD(`!)1"``ZF`@`>E@(`#H^K`"B.I!OTI6(``)8#`````Q0```(4`ZZB
    -M!9RL@@`HCZ(`<*1#```SP@(`%$``%8^C`#@D`A0`4&(`$Y;G`'*/HP!PCZ0`
    -M-(^_`&2$8@``KJ0%H(^^`&"NH@6D`!(`!A0```),`P$E$"H!(B@+`2HP*@$C."H!
    -M)$`J`2`0(0%&$`H!)Q@+`2@@"Z8"`!"F`P`4I@0`&*8%`!RF`P`2I@0`%J8%
    -M`!J6HAO&$$``#(^D`"@``A!`I@(`$*8"`!:F`@`4I@(`$I:B&\8``A!`I@(`
    -M&*8"`!RF`@`:CZ0`*)8#`!J$@@```&(0*E1```&D@P``CZL`<)8#`!"%8@``
    -M`$,0*E1`_Y>E8P``$`#_EH^C`'`0`/_(```0(1``_W^40@`,$`#_=Y1"``P0
    -M`/]0```0(1``_R$FY@`",F,`^#1S``&40@$6$$#_%```B"&.0P`$`!$00`!#
    -M$"&40@$8,$/__Q!@``]_^",0@``)`4`
    -M"(Q"``2`3@`BB8(``)F"``.)@P`$F8,`!XF$``B9A``+B8@`#)F(``^KH@``
    -MNZ(``ZNC``2[HP`'JZ0`"+ND``NKJ``,NZ@`#XF"`!"9@@`3B8,`%)F#`!>)
    -MA``8F80`&XF(`!R9B``?JZ(`$+NB`!.KHP`4NZ,`%ZND`!B[I``;JZ@`'+NH
    -M`!\`!5A``7T8(91B`````$@A``!H(0!.$".D8@```7U`(84"```$0@`!I0``
    -M`"0"``@1(@`Y``D00`!,$"&40P``A0H``"4B``$P2?__$4,`)Y4$```M(@`0
    -M5$#_\0%]0"$!?2`AA((``"A"`$`40``$`6P0(20"`#^D@@```6P0(91"``"$
    -MA```)*4``0!'$",H0P````,0"P`"$$``1A`AE$,````$($`PI?__`(8@(2RB
    -M``\40/_2I(,``"0%``@`!1A``'T0(91$```DH@`!,$7__P!L&"$LH@`/%$#_
    -M^*1D```#X``()[T`(!%```4D@@`!+:(`,Q1```(D@O__)((``:4"```EH@`!
    -M,$W__Q``_]```$@A$`#_SB0)``\GO?_`K[,`+*^R`"BOL0`D,)+__Z^_`#"O
    -ML``@`*"((203`#\``"`A``00P`!1$"&40P````000"2&``$08``%`%TH(3#$
    -M__\L@@`(%$#_]J2C````@(`A)Z<`$`)`("$GJ``2`Z`H(0P`1[L"`#`A$@``
    -M"P``("&7I0`0``000`!=$"&40@``$$4`!22#``$P9/__`)`0*Q1`__D`!!!`
    -MEZ,`$)>B`!(08@`/``00P`!1$"&,0@`$$$```P`$$,``41`AE%,``@)@$"&/
    -MOP`PC[,`+(^R`"B/L0`DC[``(`/@``@GO0!`%'+_\0`````0`/_T`%$0(2>]
    -M_\"OL``@,/#__Z^V`#BOM0`TK[0`,*^S`"ROL@`H`*"8(:^_`#ROL0`D`,"0
    -M(0$`J"$``*`A``"P(1(```T``"@A``40@`!%$"$``A!``%(0(91$``@DHP`!
    -M``400#!E__\`71`A`+`8*Q1@__6D1```EF0```.@*"$GIP`0)Z@`$@P`1[L"
    -M`#`A$@``#@``*"&7IP`0EZ8`$@`%$$``71`AE$,``"2D``$`9Q`F$&8`-P"B
    -MH`HPA?__`+`0*Q1`__<`!1!``!2`@``6B(`"%(`A`C:((0`0@$``$8A``C*(
    -M(0(2@"&6!P`&EB@`!I9D``"7I0`0EZ8`$@P`1X```$@AIJ(`!I8'``26*``$
    -MEF0``)>E`!"7I@`2#`!'@```2"&FH@`$E@<``I8H``*69```EZ4`$)>F`!(,
    -M`$>```!((::B``*6!P``EB@``)9D``"7I0`0EZ8`$@P`1X```$@AIJ(``(^_
    -M`#R/M@`XC[4`-(^T`#"/LP`LC[(`*(^Q`"2/L``@`^``"">]`$`0`/_-`*"P
    -M(3#G__\Q"/__<.@0`C"*__\PI?__,,;__R0$`&000``>```8(20"``$0Q0`I
    -M`$D@"P%%&",``Q!``$,0(0`"$,``0Q`A``(0@`#%&",`0P`:4&```0```]
    -M`!`D`@`W)`<`4R0$`%,0`/_MK@(`$`P`2>T``````$`@(20&`"4``#@A#``_
    -M#B0%``8X1``_)`8`0``$,`HDPP`W),4`(P!D*`LD`P`4``08"R1"``0D!P`R
    -M`$0X"ZX#``RN!0`0$`#_UR3$`#*,A1OTC(0``#0#@`",H@`HA*8`)`"#("$`
    -M1A`A``(20#!"?@`T0H``K((9,"0"``$#X``(K*(`,">]__"OL0`$K[\`"*^P
    -M``",A1OT`("((8RP``2.`@`8$$``!R0$__^,HP`P)`(``5!B``F.(@``CB(;
    -M](Q$`#"/OP`(C[$`!(^P````@!`A`^``"">]`!`T`X```$,0(8Q$&3`P@H``
    -M5$#_](XB&_0`!!W",&,``P`$)D(D`@`"$&(`):X$``26(ASV,$(`\"Q"`#`0
    -M0``6`B`@(8XB&_26)AMR`B`@(:Q``#`,`$@R`@`H(51`_^&.(AOT#`!(SP(`
    -M("%00/_=CB(;]`(`*"$,`$C;`B`@(1A`_]K,(`'!"@`!HD`___
    -MK,0`"(S#```\`H`#C$2*L"1G__\`!QC`C,(`'`!G&"$``QB``&08(:S'``",
    -M10`0C&(`&(S$``@D8P`(`$40(P`"$$``@B`C`(@0*ZS#`!P40``#K,0`"%3@
    -M_^N,PP``)`,``0/@``@`8!`AC,D`#`$D$"L40/_[```8(8SB```D0O__$*+_
    -M]R0#__ZLQ``(C.(``"1"__\`HA`K$$#_\20#``*,PP``/`*``XQ(BK`D9P`!
    -M``<8P(S"`!P`9Q@A``,8@*S'````:!@AC$4`$(QB`!B,Q``()&,`"`!%$",`
    -M`A!``((@(P$D$"NLPP`<%$``!JS$``B-`@``)$+__P#B$"M40/_HC,,``!``
    -M_]4D`P`"/`*``A``_Z@D0BS,)[W_\*^Q``2LH``4`*"((20%``>OOP`,K[(`
    -M"*^P```,`$GM`("`(0!`("$D!0`!)`8`)`P`/PX``#@A`$"0(20"``%20@`'
    -MCB(`'(^_``R/L@`(C[$`!(^P```#X``()[T`$`(`("$D!0`'#`!)[810````
    -M0"`A)`4`!"0&`"`,`#\.```X(1(2``X`0!@A4@#_[JX@`!0D`@`"$@(`!P`#
    -M$$`D`@`#%@+_Z8^_``P``Q!`$`#_Y:XB`!00`/_])$+_^Q``_^&N(@`4)[W_
    -MX*^U`!2OM``0K[\`&*^S``ROL@`(K[$`!*^P``"4H@`"`*"H(3!"`0`00`!Q
    -M`("@(8R0'`2.`@``&$``'@``F"$F$0`HDB8`"Y(H``@"`"`A``800`!&$"$`
    -M`A#``%`0(8Q#`"@\`H`")$)$```#&(``8A@AC&(````(0(`T`X<`)`4`#@``
    -M."$`0/@)`0.0(0!`,"&.`P``CH(``"9S``$"8Q@J`%(0(:Q&```48/_E)C$`
    -M&):B``(P0@$`%$``"H^_`!B.D!P,C@(``!A```8``)@AC@,`*"0"``(08@`*
    -M)A$`*(^_`!B/M0`4C[0`$(^S``R/L@`(C[$`!(^P```#X``()[T`()(F``L\
    -M`H`")%5$```&$$``1A`A``(0P`!0$"&,0@`HDB@`"#0#AP```A"``%40(8Q"
    -M````"$"``@`@(20%``X``#@A`$#X"0$#D"$`0#`ACH(```(`("$D!0`.`%(0
    -M(:Q&``"2(P`))`<``29S``$``Q"`%&``"P)"D"&.`@```F(0*A!`_]4F,0`8
    -MCB,``"0"``)08O_;DB8`"Q``_]"/OP`8DB8`"P`&$$``1A`A``(0P`!0$"&,
    -M0@`H``(0@`!5$"&,0@```$#X"0``````0#`ACH(```!2$"&L1@``$`#_YXX"
    -M```0`/^0C)`<%)2"'/8P0@#P+$(`,!1``!,PI?__C(,;]"2E__\LH@`'$$``
    -M#HQD`"`\`X`"``40@"1C#[P`0Q`AC$(```!```@``````^``"`"`$"$#X``(
    -M)((`!`/@``@D@@`(`^``"```$"$#X``()((`#`/@``@D@@"L)[W_\*^Q``2O
    -ML````("((0"@@"&OOP`(#``I;#P%@`".)P``)`/\#P(@("&,X@`P/`6```!#
    -M0"0P0@/P``(1`BQ&`"42```3+$,``A#```TD0@`!``(1`#!"`_`!`A`EK.(`
    -M,`P`*3P`````)`(``8^_``B/L0`$C[````/@``@GO0`0#``I/#P%@``0`/_X
    -M```0(1!@_^\D0O__$`#_^0(@("&,P@`4C,<`$"0#``$`0Q`$`(!((0#`0"$`
    -MXQ@$C,8`#"1"__\\!``/-(3\`"1C__\``A*``$00)(TG```P8P/_`&(8)0`&
    -M-0`\`@_P`,(P)``%*(``9A@E`.4X(:SC$$"-)```C0,`(#P"``\T0O__`&(X
    -M)!!@``,`A2`A/`(`$`#B."6-`@`$K(<0P#!&`"`P0@`$$$``!CP$`""-(@``
    -M`$40(8Q#$0``9!@EK$,1`!#```8`````C2,```!E&"&,8A$`-$("`*QB$0`#
    -MX``(`````">]__"OOP`$K[```(R(&_2,L``(C*,`!(T'``@D`@`!`@)(!`#I
    -M."4P:@`",&,``0"@,"&M!P`($&``!`(`*"&-`@`,`$D0):T"``P10``$````
    -M`(T"`!``21`EK0(`$`P`3HL``````@`0(8^_``2/L````^``"">]`!",A!OT
    -M)`(``0"B$`2,A@`(C(<`#(R#`!```A`G`,(P)`!B&"0`XC@DK(,`$*R&``@#
    -MX``(K(<`#(R"````!2B`)*4(``!%$"&L1@```^``"`````",@P``)`(``0"B
    -M$`2L8@A``^``"`````",@AOTC$,`""0"``$`HC`$`&88)``%*(`DI0H`$&``
    -M"@``$"&,A````(40(8Q"```P0@`#%$``!`````",@@A``$80)``"$"L#X``(
    -M`````">]__``!A!`K[(`"*^Q``2OL```K[\`#`!&$"$`@(@A``(0P(R$````
    -M1A`A)`,``0"C&`0`H)`A``*`@*R#"(`"("`A#`!*H@)`*"$F$/__$$``!R0$
    -M``H&`@`&CB(```P`:3\`````$`#_]@(@("&.(@``C[\`#(^R``B/L0`$C[``
    -M`*Q`"(`#X``()[T`$!"@`!4`H#@AD*(`#@`"$0(P0@`!$$``$8SB``@\`]__
    -M``8@*S1C__\`0Q`D``0G0`!$$"6LX@`(C.<`(%#@``>,X@`(D.(`#@`"$0(P
    -M0@`!5$#_\HSB``B,X@`(/`/?_P`&("LT8___`$,0)``$+T`\`_]_`$40)31C
    -M__\`0Q`D``0EP`!$$"4#X``(K.(`"``($,``2!`C)[W_P``"$("OO@`PK[<`
    -M+*^V`"BOM``@K[,`'*^R`!BOL0`4K[``$*^_`#2OM0`D`$00(8Q"&=@`@)`A
    -M`*#P(:^B``2/HP`$)`(``:^F````X)@A``"@(0``L"$``+@AKZ(`"*^@``P`
    -M`(@A%&``#B2P``B/H@`,C[\`-(^^`#"/MP`LC[8`*(^U`"2/M``@C[,`'(^R
    -M`!B/L0`4C[``$`/@``@GO0!`#``I;#P%@``28``:)`/_\"9T``@R@@`/)$(`
    -M)P!#*"0"@Q@D`&40(0!#$"L40``'`&`@(;QQ```D8P`0`(40(0!#$"L00/_[
    -M``````)`("$"8"@A#`!.AR0&``&OH@`(CH(``(Z#``@``HV",'9__S(Q``$"
    -M0"`A#``I/#P%@`".`P``/`*`0(X%``P`8A@DC@0`"(^B``@`!34",)5__P`#
    -M&"L40``+,,8`'U!@``H#P"@A5B``2H_"`$R/HP`$`M40(0!7$",`8A`K$$``
    -M$`*W$",#P"@A`D`@(0P`2MHD!@`!CZ,`#!!@_[B/H@``4$#_MX^B``R,10`P
    -M`D`@(0P`2MH``#`A$`#_L8^B``P"0"`A/`6```P`*6P"PK`A$F``'"9E``@P
    -MH@`/CH0`""0#__`D0@`G`*,H)`!#,"0D`H```((@)#+#?_\`IA`A`(,@)0!%
    -M$"NNA``(%$``!P"@&"&\L0``)*4`$`!F$"$`11`K$$#_^P`````"8"@A`D`@
    -M(0P`3H]_\"OM``@K[(`
    -M&*^Q`!2OL``0K[\`-*^^`#"OMP`LK[8`**^U`"2OLP`KB(``)9#&]P\!?^_,((/_P!B&"HTI?__``,=@`"%("0`@R`E
    -MKB0``)("`#PP0@`!4$``!(X"`#P`A1`DKB(``(X"`#P``A;",$(`#U!```:.
    -M(P``CB(``#P#`$``0Q`EKB(``(XC```\`G__-$+__P!B&"2N(P``CZ,``!!@
    -M``.0Q``,D,(`#0""("6.(@`,/`/^#S"$`!\T8___`$,0)``$)0``1!`E$`#^
    -M[ZXB``R3P@`6CB,``#P$_O\P0@`/+$(``32$__\`9!@D``(6``!B&"40`/[7
    -MKB,``"0"`$`08OZY)`,``Q)@_KED0;
    -M<@`"$(``4A`A$`#^,XQ6'``GO?_0K[(`"`"@D"$DI0`(,*(`#Z^U`!2OLP`,
    -MK[$`!*^P``"OOP`@K[<`'*^V`!BOM``0)`/_\"1"`">.5``P`*,H)`!#,"0`
    -MIA`A`$40*P"`J"$F4``8)I,`"(Z6`%".EP`H))$$@!1```<`H!@AO+$``"2E
    -M`!``9A`A`$40*Q!`__L``````J`@(0)`*"$,`$Z')`8``1!``&8D`P`-D@(`
    -M`XYC``PP0@`!$$``J3!I`!\D`@`!KD(`0)8"``8``A!",$(/_Z9"`$:6`@``
    -MID(`1)("``*2`P`#HDD`2C!"``\``QD"`$,0(:9"`$B28@`$,$(``1!``)(`
    -M````$L``!20*`!Z"P@"Z%$```@!`4"$D"@`>D@(``S!"``$00`!K*4+_[!1`
    -M``Z.(P$()`(!)Q!B`&0``Q#``$,0(0`*(<`\`V9F`$00(31C9F<`0P`8``(7
    -MPP``&!```QB#`&(8(Y("``(P0@`/%$``!:XC`0B2`@`#``(1`A!``!8`````
    -MCB0`>(XE`'R.8@``)*4``0`"%8(LHP`!`(,@(3!"``&N)`!XKB4`?!1``$$`
    -M`#`AD@(``C!"``\00``X``88@``"&(``<1@AC&(`P"1"``&L8@#`D@(`!0`"
    -M$<(00``$`````(XB`%PD0@`!KB(`7)("``,``A#",$(``11```P``!@ACJ(;
    -M1#!"``$00``)C[\`()+B``0P0@`!%$``!H^W`!R.@@!,5$``#8Q"`#R/OP`@
    -MC[<`'(^V`!B/M0`4C[0`$(^S``R/L@`(C[$`!(^P````8!`A`^``"">]`#"2
    -M"``#CF<```!)$"&2"P`$D$8`!)9)`$@`"$!",.,Y0`$C0,```!I&"&,8@G`
    -M-$("`*QB"<",Y0`$,*(`!!!```@PH@`@C0(``#P$`"``21`AC$,1``!D&"6L
    -M0Q$`,*(`(!!```]__"OL0`$K[```*^_``B,H@"$)`8`!`"@@"$40``&`("((8^_``B/L0`$
    -MC[````/@``@GO0`0#`!*MHRE`&R.!0!L#`!*AP(@("$,`'IJC@0`A!``__.N
    -M``"$)[W_X*^S``ROL@`(K[$`!*^_`!"OL````("8(0#`B"$0P``I))(<&(Y0
    -M`(02```M`````"8$``@``"@A#`!PJB0&`!B6`@`.C@0`*(XE``2.)@`,,$(/
    -M_PP`<)T`@B`AE@(`#HXD``R6`P`.,$(/_P!$$"$D!/``,$(/_P!D&"0`8A@E
    -MI@,`#HXQ```6(/_M`````)8"``Z6`P`*KA(`3#!"#_\D0@`$`&08)#!"#_\`
    -M8A@EI@,`"@)@("$"`"@A#`!8H0``,"&/OP`0C[,`#(^R``B/L0`$C[````/@
    -M``@GO0`@#`!Z5R0$`-P`0(`A`$`@(0``*"$,`'"J)`8`7"8"`%RN4`"$K@``
    -M`*X``""N`@`$K@(`*!``_\:N$``D)[W_L*^P`#``@(`AK[,`/*^Q`#2OOP!`
    -MK[(`.`.@("$``"@A)A$<&`#`F"$D!@`L#`!PJHXR`(2.(@`$C@8;]``"&$``
    -M8A@A/`*``B1"+ZP``QB``&(8(8QD``2,90`(C&,``"2$``$D`@`%KZ(`"*^E
    -M`!2OI``0KZ,`#(S#``@D`@`")`8`!#!C`"`"`"`A)`4`!11@`!VOH@``#`!1
    -MKR8$'&`00``))`/__X^_`$"/LP`\C[(`.(^Q`#2/L``P`&`0(0/@``@GO0!0
    -M`@`@(0P`2F@#H"@ACD8`)`!`*"&N(@!L#`!*E0(`("&.)0!L#`!*G`(`("$"
    -M`"`A#`!9$@)@*"$0`/_I```8(0P`2K8`````CZ4`"`P`2H<"`"`A$`#_W@``
    -M```GO?_@K[$`!"0"__\DD1P8K[8`&*^U`!2OM``0K[,`#*^R``BOL```K[\`
    -M'#P%``0`@(`A`,"8(0#@H"$!`)`A`4"H(0$@L"$0X@`FIB8`@@P`4EZ4A!MR
    -M.$D``0(`("$"0"@A`F`P(0*`."&N(@`$`$`8(1*@``0X2``$)`(``P!(&`H`
    -M"1@*``,0@`!0$"&,0AP`KA48`*XV`!RN`AQ4ED(``*8B`$*60@`"IB(`1)9"
    -M``0,`"SJIB(`1H^_`!R/M@`8C[4`%(^T`!"/LP`,C[(`"(^Q``2/L````^``
    -M"">]`"`D`@`!K((;L"0"``:L@`6,K(`8``P`*6RN(@`$`@`@(0)`*"$``#`A
    -M#``LZ@``."$"`"`A#`!/:0(@*"$0`/_GC[\`'"2E__XLH@`F``!((1!``"0`
    -M`%`A/`.``@`%$(`D8P_8`$,0(8Q"````0``(`````(R)!'@50``%`````%3@
    -M``&LZ0``5,```:S```!5```!K0H```/@``@`````$`#_]8R)!'P0`/_SE(D<
    -M\!``__&4B1SR$`#_[Y2)'/00`/_ME(D<]A``_^N4B1SX$`#_Z0``2"&,@AOT
    -M$`#_YHQ)`#00`/_D)`H`#HR"&_00`/_AC$D`<(R"&_00`/_>C$D`.(R"&_00
    -M`/_;C$D`/(R"&_00`/_8C$D`0(R"&_00`/_5C$D`1(R"&_00`/_2C$D`2(R"
    -M&_00`/_/C$D`3(R"&_00`/_,C$D`4(R"&_00`/_)C$D`5(R"&_00`/_&C$D`
    -M6(R"&_00`/_#C$D`7(R"&_00`/_`C$D`8(R"&_00`/^]C$D`9(R"&_00`/^Z
    -MC$D`:(R"&_2,0@!L)$G__RTB``500/^T)`D`!!``_[(`````C((;]!``_Z^4
    -M20!TC((;]!``_ZR420!VC((;]!``_ZF420!XC((;]!``_Z:420!ZC((;]!``
    -M_Z.,20!\C((;]!``_Z",20"`C((;]!``_YV,20"$C((;]!``_YJ,20"(C((;
    -M]!``_Y>,20",C((;]!``_Y2,20"0C((;]!``_Y&,20"4C((;]!``_XZ,20"8
    -MC((;]!``_XN,20"<``40P`!%$"$``A#``$40(R>]_^```A"`K[,`#*^R``BO
    -ML0`$K[```*^_`!``@H`AC@(`"`"`D"$`X)@A$$``""81``B/OP`0C[,`#(^R
    -M``B/L0`$C[````/@``@GO0`@`B`@(0``*"$,`'"J)`8!'"9$'!@0@/_S)`(`
    -M!HR#``008O_P)`(``:X"``@F`P`\)`4``R0"``$DI?__K&(```2A__TD8P`(
    -M`F`X(28B``0F8P`@C.4``(SF``2,Z``(C.D`#*Q%``"L1@`$K$@`"*Q)``PD
    -MYP`0%./_]B1"`!",XP``C.4`!(SF``BL0P``K$4`!*Q&``BN)`!8#`!39P(@
    -M("$"("`A#`!2Q0``*"$,`'&T)B0`7!``_\N/OP`0``40P`!%$"$``A#``$40
    -M(P`"$(``@B`A)[W_\"0"``:OOP``$,(`#B2%``@LP@`'$$``!R0"``]`!!0PO_\K*@`+!``__N/OP``)(0`$`$$$"4P
    -M0@`#$$``'"4#`"``8!`AB0,``)D#``.)!@`$F08`!XD'``B9!P`+B0D`#)D)
    -M``^H@P``N(,``ZB&``2XA@`'J(<`"+B'``NHB0`,N(D`#R4(`!`5`O_N)(0`
    -M$($"``"@@@```*`@(0P`4L4D!0`!$`#_VX^_``"-`@``C08`!(T'``B-"0`,
    -MK((``*R&``2LAP`(K(D`#"4(`!`5`__V)(0`$!``_^T```````40P`!%$"$`
    -M`A#``$40(R>]__```A"`K[````""@"&OL@`(K[$`!*^_``PF$0`(CB(`>`"`
    -MD"$\!8`"/`2``B2$$)PDI1!P%$``#B0&`0<,`'&[)@0`9`(@("$``"@A#`!P
    -MJB0&`1RN```(C[\`#(^R``B/L0`$C[````/@``@GO0`0#`!P=``````F!0!D
    -M#``0X`)`("$0`/_M`````">]__"OL@`(K[$`!*^P``"OOP`,`("0(0``B"$D
    -MD``(C@(```(@*"$F$`$<)C$``11```H"0"`A*B(`!%1`__F.`@``C[\`#(^R
    -M``B/L0`$C[````/@``@GO0`0#`!1;``````0`/_U*B(`!">]__"OL``````H
    -M(20&`#BOOP`$#`!PJ@"`@"$,`'&T`@`@(8^_``2/L``````0(0/@``@GO0`0
    -M`^``"(R"`!0GO?_PK[$`!*^P``"OOP`(#`!PM0"`B"&.,``4$@``"0````".
    -M`@`@`%`8)@`#$`H40``"KB(`%*X@`!BN```@K@````P`<+H``````@`0(8^_
    -M``B/L0`$C[````/@``@GO0`0)[W_\*^Q``0`@(@AK[(`"*^P``"OOP`,`,"`
    -M(0P`<+4`H)`ACB(`*%!``!6N```@C@(`)*X0`""N`@``CB(`&%1```JL4@`@
    -MKC(`%`P`<+JN,``8C[\`#(^R``B/L0`$C[````/@``@GO0`0CD,`)(XB`!BL
    -M0P``$`#_]`````"N````$`#_[HXB`!@PQO__``800`!&$"$``A#``$00(91#
    -M`"P\`A!B-$)-TP`#&(``8@`9``40P```&!```QF"`$,0(21"`!4`0P`;4&``
    -M`0```]`#"A$`!C#`!2
    -M`/\D`@`!`D`H(0(@("$4
    -M8O_3)`8``0P`4G(``````E<0*Q!```("0!@A`N`8(1``_\LP=P#_)[W_\*^P
    -M```DD`"4`@`@(0``*"&OOP`$#`!PJB0&`'P,`'%<```````#*(``HR@A``4H
    -M0*X%`%2/OP`$C[````/@``@GO0`0``0F```%+@``!"8#``4N`P`&-@``!C8#
    -M`(40*@"F0"H40``(`(8X*A$```0`H!@A`,`8(0#$$"H`@A@*`^``"`!@$"$0
    -MX/_]`(`8(0#`&"$`IA`J$`#_^0"B&`N0IP``,(3__Q#@``L``!@A``,00`!%
    -M$"&40@`"`((0*Q1```4D9@`!,,/__P!G$"M40/_X``,00`/@``@`8!`A)[W_
    -MP*^^`#"OM0`DK[,`'*^Q`!2OOP`TK[<`+*^V`"BOM``@K[(`&*^P`!"4@AMR
    -ME*,`"HRW`%```A("`("8(0"@J"$P<0__,%X``8RV`$R,HP`H```0(9"%&`,2
    -MX``:D(08!XZB`#P``A)",$(``11```V.U``\CF(;V%!```N.H@`\D&(`!#!"
    -M``%40``'CJ(`/)!B```D`P`(,$(`#!!#`!T`````CJ(`/"0#_?\`0Q`DKJ(`
    -M/(YB'!12@@`.DL(`@);"`!Z/OP`TC[X`,(^W`"R/M@`HC[4`)(^T`""/LP`<
    -MC[(`&(^Q`!2/L``0`^``"">]`$!00/_SEL(`'I:D``J.A0,T#`!3D#"$#_\0
    -M`/_NC[\`-!"@``\F\`"4)`(``5""`0"2`@`]5(``"X($`":2`P`]``,00`!#
    -M$"$``A#``%00(8Q#`"@D`@`!4&(`\)*"``."!``F@@4`*`P`4WF"!@`I#`!Q
    -M7`!`D"$``RB`C@8`4`"C*"$`!2A``*8@(RR"`+D40`#;```8(20#``HN(@,A
    -M%$``!)(&`&$D8@`!``(6```"'@.2!P!B`D,0(P`"%@`"0Q@J``(6`SAC```D
    -MQ/__``"0(3#H`/\`0Y`*,(0`_P``8"$1```'``!((1?``+\!!A`K`(<0(S!$
    -M`/\0@`!H``"((0$P6"$`B1`J`(`P(11``!N1:`!C`)`0(21'`&.0\0``),;_
    -M_P#)4"H`$1!``%$8(0`#&,``="`A`%`8(8!B```"0A`J%$``"R3G__^08P`!
    -ME(0`+B0"`&0`0Q`C<((8`@!L$"L40``#``````!@8"$"($`A44#_ZI#Q``"B
    +M>(ZB`#"50P`(EF(<8E!B``.50P`&$`#_VB5"`!"68AQ@%&+_UR5"`!"50P`$
    +MEF(<7A1B_],E0@`0D4(``#!"``Q00/_/)4(`$(Z"`2PD0@`!$`#_\*Z"`2P"
    +MH"@A#``0!0(@,"%00/^!CK(`%!``_SF.H@`<$`#_?ZX@`$".8A?84$#_?8^_
    +M`$`,`',&)F0:K!``_WF/OP!`C(,`%!!@``@D!``!C&(`/`1#``4``"`AC&(`
    +M(!!```(````````@(0/@``@`@!`A)[W_\*^Q``2OOP`(`("((:^P``".(AO0
    +M$$``%"2$&'@,``ZR`````"8D&+`,``ZR``*`*R8D&.@,``ZR``*`"B8D&2`,
    +M``ZR``*`"E!```$``(`A`@`0(8^_``B/L0`$C[````/@``@GO0`0#``.L@``
    +M```0`/_W``*`*R>]__"OL```K[\`!`P`]_^"OLP`,`,"8(:^U`!2OM``0K[$`!*^P``"O
    +MOP`8K[(`"`"`H"$`H(@A#`!R&```J"$28`!"`F"`(8X"`#P``A9",$(``11`
    +M`%6.$@!0$D``5`*`("&.0@!4$$``40`````2H`!,C@(`+(Q#``",0@`@KJ,`
    +M`*ZB`"".!@`L)D0`7`(`*"&LP``@K,````P`4O``````CD(`>"1"``&N0@!X
    +M$J```@)@@"&.L``@5@#_XXX"`#P28``A`````)8C`#108``1CB(`&(YD`"B0
    +M@@`6,$4`#U"@``NF(``T``,1`J""`!>2(@`UD(,``3!"``\``A$``*(0)31C
    +M``B@@P`!H((`%HXB`!A40``=K%,`("0"``&N(@`LKC,`%*XU`!@````/CB(`
    +M+%1``!".9@`DCB4`)`P`2Z8"@"`A#`!R'0````"/OP`8C[4`%(^T`!"/LP`,
    +MC[(`"(^Q``2/L``````0(0/@``@GO0`@CB4`)`P`2Y\"@"`A$`#_[:X@`"R.
    +M(P`8CF(`)*QB```0`/_DKC4`&!``_[B,4P`@`H`@(0P`#:$"`"@ACH(;.%!`
    +M`!B.(@`<4@``%HXB`!R.`@`\``(60C!"``$40``)`H`@(8XF`!B.)P`PCB@`
    +M)`P`3`@"`"@A5$``"HXB`!P"@"`A#``IACP%@`".`@`P`H`@(3P%@``,`"E6
    +MKB(`,(XB`!PD0@`!$D``"JXB`!R.(@`DCD0`4``"$,``4A`AE$,`,"2$``&N
    +M1`!0)&,``:1#`#`0`/^7CA4`+">]__"OL@`(K[\`#*^Q``2OL```C*(`5!1`
    +M``<`@)`A)+$`7(XB`!P40``)CB8`%*X@`!BN(``4C[\`#(^R``B/L0`$C[``
    +M``/@``@GO0`0C,(`+(S%`%@"0"`AC%``(*Q```"L0``@#``/3P``."&.(@`<
    +M`@`P(21"__\40/_TKB(`'!``_^NN(``8)[W_X*^T`!"OLP`,K[$`!*^_`!2O
    +ML@`(K[```(S0`#",H@`DC,,`0(X2`%```A#``*"((0)"*"$D`@`"`("@(1!B
    +M`#DDLP`PCB,`%(QB`#P$0@`MC&(`((X"`#P\`P(`C@<`+`!#$"6N`@`\CB(`
    +M')9E``"69``")$+__ZXB`!R.0@!0CD,`5(SF`"`DI?__)$+__R2$__\D8___
    +MCC``%*9D``*F90``KD(`4*Y#`%04P``"KB8`%*X@`!BLX````@`P(:S@`"`"
    +M("@A```X(0P`#T\"@"`A`H`@(0P`#^("0"@A```0(8^_`!2/M``0C[,`#(^R
    +M``B/L0`$C[````/@``@GO0`@K&````!@*"&N(@`4`H`@(0P`"F.L8``@$`#_
    +MSHX"`#R4HP`PCD(`5"0&``&N9@`$`$,0(:Y"`%2F8P`"C@,`/#P%A_\TI?__
    +M``,6PC!"``\D0@`!,$(`#P`"%L``91@D`&(8):X#`#R,@AMH``,>PC!C``\`
    +M0Q`K5$``!8Y"`%2,@AJT5$``$8R"!8".0@!4EF,``B0%__\D0O__KD(`5(Z"
    +M!80D8___IF,``B1"``$,`%A=KH(%A`*`("$,``_B`D`H(1``_\8D`O__)$(`
    +M`:R"!8".`@`\``(6PC!"``\01@`&`````(X#`"B08@`!-$(`"!``_Y*@8@`!
    +M#``.^`(`*"$0`/_XIB(`-">]__"OL0`$K[```*^_``@`H(`AC@,`0(RE`#`D
    +M`@`!`("((1!B`$Z,I`!0CB(;:!!``$8``!`A4(``18^_``B,H@`HD$(``3!"
    +M``000``EC@,`(!!@`#T``!`AC'``+(X"`#",0@`HD$(`%C!"``\00``[)@0`
    +M"#""``\D`__P)$(`)P"#("0`0R@D`(40(0!$$"L40``'`(`8(;R1```DA``0
    +M`&40(0!$$"L00/_[``````(@("$"`"@A#`!/G"0&``$00``A)`+__XX"`#",
    +M0@`HD$(``3!"``040/_=C@,`(!!@`!D``!`AC'``+"0$__`F`P`(,&(`#R1"
    +M`"<`9!@D`$0H)`!E$"$`0Q`K%$``!P!@("&\<0``)&,`$`"%$"$`0Q`K$$#_
    +M^P`````"("`A`@`H(0P`3YPD!@`!)`/__P`"&`L`8!`AC[\`"(^Q``2/L```
    +M`^``"">]`!`0`/_Z```0(2>]_]"OL0`D`*"((:^R`"BOL``@K[\`+`P`]`#"OH@`$KZ``"*^@``ROH``0#`!R':^@`!2.!0!4`D`@(0P`"J0#
    +MH#`A#`!R&``````0`/_=K@``5">]__`D@@!4K[(`"*^Q``2OL```K[\`#`"`
    +M@"$`H(@A`$`@(1#@`"$`P)`A#`!R\0`````,`'(8`````(X$`$R,A0``$*``
    +M%XR"``2LH@`$C@(`2(R#``2LD0`(K((`!(X"`$BL90``K)(`#*R```"N!`!(
    +M#`!R':Q$```,`',&)@0`/```("&/OP`,C[(`"(^Q``2/L````(`0(0/@``@G
    +MO0`0$`#_ZJX"`%`,`'+_`````"0#``$40__S)`0``A``_]P`````)[W_\*^P
    +M````@(`A)(0`/*^_``ROL0`$K[(`"`P`E``2/H@``5$#_
    +M^"8$`#R/OP`4C[``$`/@``@GO0`@#``13P`````0`/_WCZ(``">]__`DI?__
    +MK[$`!*^_``ROL@`(K[```"RB`!D`@(@A$$``%(R2``0\`X`"``40@"1C#G``
    +M0Q`AC$(```!```@`````C(0```P`&QTD!0`1`$"`(29&!(``0"`A)`4!.`P`
    +M&U$`````CB0```P`&M`"`"@AC[\`#(^R``B/L0`$C[````/@``@GO0`0```P
    +M(0)`("$,`"Z$)`4``HXD```,`!L=)`4`$@!`@"$F1@2(`$`@(1``_^HD!0`(
    +MC(0```P`&QTD!0`3CB0```!`@"$D`@(`$`#_Y:X"```,`!.LC(0`!!``_^2/
    +MOP`,#``3Q(R$``00`/_@C[\`#">]_]"OLP`]`!`,
    +M`!$=`````!``__N/OP``)[W_\`"@("$``#`A)`4`&:^_```,`!$=```X(8^_
    +M```#X``()[T`$">]__"OOP`(K[$`!*^P``",D``$#`!RO`"`B"$`0"`A#`!R
    +MNB8%&UR.!!M]_^`D@@!$)(,`
    +M3*^Q``0`@(@AK[\`&*^U`!2OLP`,K[(`"*^T`!"OL```)(0`/*XB`$BN(P!0
    +M```H(:X@`$2N(`!,)C,`5`P```CP(@`(\
    +M"X`#)@J)`"2E1T0DYP[D)0A]`"5KB0@D!``!`B`P(0P`]`"`0`/_U)!4``B>]_]"OL``0`*"`(:^_`""OLP`]`!`GO?_0K[$`)*^_
    +M`"ROL@`HK[``((R"%^`00``F`("((8R"%]P00``C)`(``HR#'*@08@`@)!(`
    +M`1!R`!^/OP`L#`!R&`````".(AL<5$``!8XP&T".(ALD5$``((XB&]".,!M`
    +M)Z(`$`(@("$``"@A```P(0``."$``$`A``!((0``4"$D"P`!KZ(```P`60BO
    +ML@`$/`(`!`("@"06```+`B`@(0P`#5H"("`A#`!R':X@&R2/OP`LC[(`*(^Q
    +M`"2/L``@`^``"">]`#`,`"E6/`4`!!``__,`````4$``%(XB&)0``"@A``40
    +MP`!%$",``A#``%$0(8Q#&)0DH@`!,$4`_Q!@``,LI``$)`(``:XB&QP0@/_E
    +M`````(XB&QP40/_B``40P!``__$`11`C$$#_WB0"``$0`/_]_^`D
    +M`P`!K[,`#*^R``BOL0`$K[```*^_`!``H)`A`,"8(0"`@"$0HP!&``"((5"@
    +M`#",@ARH)`(``A"B`!,D`@`#$*(`#`````!2(``!KA(]__"OL```,+``_Z^_``ROL@`(K[$`!```D"$,`'(8`("((0P`
    +M]`!`,`#4X)!(`%A``_^\``I`*)$+__Q1`_^^N(ARPCB(]__"OL@`(K[$`
    +M!*^P``"OOP`,`("`(0P`]`!`0
    +M0``#`@`@(1``__2N$1RL)`4``@P`-3@D!@`!)!(`%A``__D``I`*$$```P(`
    +M("$0`/_JK@`]__"OL@`(K[$`!*^P``"OOP`,`*"((0"`@"$0H``W
    +M``"0(20"``$0H@`))`4`!"02__\"0!`AC[\`#(^R``B/L0`$C[````/@``@G
    +MO0`0#``U."0&``&.`Q?<)!(`%A!@``0``I`*C@(7X!!1`!D\!8``%D#_[R0"
    +M``&.`QRL4&(`#XX"'+`D`@`"%&+_Z@)`$"&.`ARP%$#_YP)`$"$"`"`A)`4`
    +M`@P`-3@D!@`!5$#_X"02`!80`/_?`D`0(11`__(D`@`"`@`@(1``__8D!0`!
    +M#``I5@(`("$,`#8+`@`@(0P`-CL"`"`A#`!R'0`````0`/_?`````(R"'*P4
    +M0``>`````(X"%]P00``%)@4;<(X#%^`D`@`!$&(`#``````"`"`A#``WV"0&
    +M``$00``$`$"0(202`!860/^^`D`0(0(`("$0`/_7)`4``PP`]
    +M__"OL0`$`("((22$``ROOP`(#`!R\:^P```,`'(8`````(XD`!2,A0``$*``
    +M$XR"``2LH@`$CB(`((R#``2,D``(K((`!(XB`""L90``KB0`(*R```"L@``(
    +M#`!R':Q$```"`!`AC[\`"(^Q``2/L````^``"">]`!`0`/_NKB(`&#"F``\G
    +MO?W@)`+_\"3#`$^OM`(0`&(8)`"@H"$`HB@D`*,0(:^Q`@2OOP(E`*`GI@"D#``;>P*`("$"@"`A)Z4`
    +MH`P`&WLGI@"H`H`@(2>E`*`,`!M[)Z8`K`*`("$GI@"P#``;>R>E`*`"("`A
    +M`F`H(0P`!\,GI@"T$J``!P+`("&.@@`(`J`H(:ZB``B/H@"T#``:T*ZB``R/
    +MOP(E
    +M`*`,`!M[)Z8`N(^F`+@"("`A`F`H(0P`!O`GIP"T$`#_Y``````"8"`A#`!9
    +M`2>E`+00`/_?``````*`("$GI0"@#``;>R>F`+R/I0"\`F`@(2>F`,```#@A
    +M#`!1<2>H`,2/I0#`#``;2@*@("&/H@#`$$``$8^E`+P"H"`A)Z4`R`P`&VHG
    +MI@#,CZ4`O(^G`,@"8"`A)Z8`T`P`47$GJ`#$CZ4`T`*@("$,`!MT`````!``
    +M_[\``````F`@(2>F`,`GIP#4#`!1<2>H`,2/I0#4`J`@(0P`&TH`````$`#_
    +MM``````GI0"@)Z8`V`P`&WL"@"`A`H`@(2>E`*`,`!M[)Z8`W(^B`-P00``,
    +M`H`@(2>E`*`,`!N%)Z8`X(^E`-B/I@#E`/@,`!MJ)Z8`_(^E`.R/IP#X`F`@(2>F`/`,`%F1
    +M)Z@`](^E`/`0`/^W`J`@(0)@("$GI@#P)ZE`+00`/]8``````)@("$,``=7)Z4`M!``_U,``````F`@(0P`!Y4GI0"T
    +M$`#_3@`````GI0"@)Z8!!`P`&WL"@"`A`H`@(2>E`*`,`!M[)Z8!"`*`("$G
    +MI0"@#``;>R>F`0P"@"`A)Z4`H`P`&X4GI@$0CZ4!!(^F`0B/IP$0#`!1]P)@
    +M("$0`/\W`````">E`*`GI@$4#``;>P*`("$"@"`A)Z4`H`P`&WLGI@$8`H`@
    +M(2>E`*`,`!M[)Z8!'(^E`12/I@$8CZ@!'`)@("$,`%(_```X(1``_R,`````
    +M)Z4`H`*`("$,`!M[)Z8!((^E`2`D`O__$*(`!0`````,`%*$`F`@(1``_Q<`
    +M````#`!2K`)@("$0`/\3``````P`R>F`3R/I0$\`F`@(0P`%!0GI@"T$`#_`P`````"@"`A)Z4`
    +MH`P`&WLGI@%$CZ4!1`P`!]T"8"`A$`#^^@`````GI0"@)Z8!2`P`&WL"@"`A
    +M`H`@(2>E`*`,`!M[)Z8!3(^E`4B/I@%,#``(%@)@("$0`/[L`````">E`*`G
    +MI@%0#``;>P*`("$"@"`A)Z4`H`P`&WLGI@%4`H`@(2>E`*`,`!M[)Z8!6`*`
    +M("$GI0"@#``;>R>F`5R/I0%0CZ8!5(^G`5B/J`%<#``(,@)@("$0`/[4````
    +M`">E`*`GI@%@#``;>P*`("$"@"`A)Z4`H`P`&WLGI@%D)[``$`*`("$GI0"@
    +M#``;A2>F`6@"`"`A```H(0P`<@TD!@`R>F`7"/I0%P#``IN`)@("$0`/ZA`````">D`#```"@A#`!R#20&``8"@"`A
    +M)Z4`H`P`&WLGI@%T`H`@(2>E`*`,`!M[)Z8!>`*`("$GI0"@#``;>R>F`7P"
    +M@"`A)Z4`H`P`&X4GI@&`CZ8!@)>E`#0``(`AE,<`%)3$``0DPP`(..(`!Q"D
    +M`#,`8H`+`,"((8^C`70L8@`$%$``&``#$,``0Q`A``(0P`!#$",``A"``F(0
    +M(21#^Y@D`@`'$.(`(B0"``2D8@$6)`(``Q#B`!HD`@`0$.(`&"0"`!%0X@`7
    +ME&(!%B3B__XL0@`"%$```B0$``@D!``$I&0!&`P`")4"8"`ACF(;5`)@("$"
    +M(#`A)$(``:YB&U2/I0%TCZ@!>`P`*=8"`#@A#``(?@)@("$0`/Y9`````)1B
    +M`18D0@`$$`#_Z*1B`1:D8`$8$`#_ZZ1@`1:7HP`RE,(``A1B_\P`P(@AEZ,`
    +M,)3"```48O_'``"((1``_\>/HP%T)Z4`H">F`80,`!M[`H`@(0*`("$GI0"@
    +M#``;>R>F`8@"@"`A)Z4`H`P`&WLGI@&,CZE`*`,`!M[)Z8!0(^E`4`,`%CP`F`@(1``_B$`````)Z4`
    +MH">F`9`,`!M[`H`@(0*`("$GI0"@#``;>R>F`90"@"`A)Z4`H`P`&WLGI@&8
    +M`H`@(2>E`*`,`!M[)Z8!G">E`*`GI@&<`H`@(0P`&WN/L`&<`H`@(2>E`*`,
    +M`!N%)Z8!H(^F`92/IP&8CZ@!H(^I`9`"8"`A`@!0(0P`42<``"@A$`#]_@``
    +M```GI0"@)Z8!I`P`&WL"@"`A`H`@(2>E`*`,`!N%)Z8!J(^E`:@,`"TE`F`@
    +M(1``_?$`````)[``.`)@("$,`"WP`@`H(0*@("$"`#`A)`4`"`P`&U$`````
    +M$`#]Y@`````,`"X'`F`@(1``_>(`````)`(``JYB&[0,`"X5`F`@(1``_=P`
    +M````)Z4`H">F`:P,`!M[`H`@(0*`("$GI0"@#``;>R>F`;`GI0"@)Z8!L`*`
    +M("$,`!M[C[`!L`*`("$GI0"@#``;A2>F`;2/HP&L)`+__Q!B`"4``Q#``$,0
    +M(0`"$,``0Q`CCZ4!M``"$(`"8A`A)$8`$`"F&"4P8P`#)$0`"!!@`!\DIP`@
    +M`.`8(8BB``"8H@`#B*<`!)BG``>(J``(F*@`"XBI``R8J0`/J,(``+C"``.H
    +MQP`$N,<`!ZC(``BXR``+J,D`#+C)``\DI0`0%*/_[B3&`!"`H@``H,(```P`
    +M4_D"`"@A%@#]H8^E`;0,`"XQ`F`@(1``_9T`````C*(``(RC``2,J``(C*D`
    +M#*S"``"LPP`$K,@`"*S)``PDI0`0%*?_]B3&`!`0`/_J``````*`("$GI0"@
    +M#``;>R>F`;B.@@`,$$``'X^C`;@D`@`%$&(`""0"``048OV$`F`@(0``,"$,
    +M`"Z$)`4`!!``_B$"H"`A`F`@(2>F`$`,`"Z$)`4`!8^B`$`GI@!8`J`@(:^B
    +M`%B/H@!$)`4`%*^B`%R/H@!(KZ(`8(^B`$ROH@!DEZ(`4J>B`&B7H@!6$`#_
    +M@J>B`&J/I0&X`F`@(0P`+H0``#`A$`#]90`````,`"\1`F`@(1``_@,"H"`A
    +M)Z4`H">F`;P,`!M[`H`@(0*`("$GI0"@#``;>R>F`<"/I0&\CZ8!P`P`,J0"
    +M8"`A$`#]4P`````,`#.0`F`@(1``_4\``````H`@(2>E`*`,`!M[)Z8!Z(^E
    +M`>@,`#/$`F`@(1``_48``````H`@(2>E`*`,`!M[)Z8![(YF'0"/I0'L#``S
    +M&`)@("$0`/T\KF(=`">E`*`GI@$T#``;>P*`("$"@"`A)Z4`H`P`&WLGI@$X
    +MCZ4!-(^F`3@,`#98`F`@(1``_2X`````)Z4`H">F`2P,`!M[`H`@(0*`("$G
    +MI0"@#``;>R>F`3"/I0$LCZ8!,`P`-F$"8"`A$`#](``````,`$E,`F`@(:YB
    +M!;`F91MP#``[?0)@("$0`/T8``````*`("$GI0"@#``;>R>F`<0"@"`A)Z4`
    +MH">F`<0,`!M[C[(!Q">E`*`GI@'(`H`@(0P`&WN7L0'&`H`@(2>E`*`,`!M[
    +M)Z8!S">P`<0"@"`A)Z4`H`P`&WLGI@'0`H`@(2>E`*`,`!M[`@`P(0(`,"$"
    +M@"`A)Z4`H`P`&WN/L`'$CZB`+0"8"`A`D`H(0(@
    +M,"$"`%`AKZ(```P`60BOH``$$`#\Z@`````"@"`A)Z4`H`P`&WLGI@'4)Z8!
    +MU`*`("$GI0"@#``;>Y.P`=>/I@'4`F`@(0P`-*("`"@A$`#\VP`````,`#KX
    +M`F`@(1``_-<``````H`@(2>E`*`,`!M[)Z8!V(^E`=@,`$*E`F`@(1``_,X`
    +M`````H`@(2>E`*`,`!M[)Z8!W(^B`=P"@"`A)Z4`H``"@,`"`H`C#``;>R>F
    +M`>``$(B`CZ(!X`)QB"$F,1G(KZ(`?`*`("$GI0"@KB(`!`P`&WLGI@'@CZ(!
    +MX`*`("$GI0"@KZ(`@">F`>`,`!M[KB(`"(^B`>`"@"`A)Z4`H*^B`(0GI@'@
    +M#``;>ZXB``R/H@'@`!"`P`*`("&OH@"0)Z4`H*XB`!`GI@'@#``;>P)P@"$F
    +M$!AXCZ(!X(X%`"0"8"`AKB(`&">F`'`,`$L]KZ(`=!``_)@``````H`@(2>E
    +M`*`,`!M[)Z8!)">E`*`GI@$D`H`@(0P`&WN/L`$D`H`@(2>E`*`,`!N%)Z8!
    +M*(^F`2@`$!#``%`0(XS#`````A"``%,0(:Q#&````
    +M``*`("$GI0"@#``;>R>F`?"7H@'R$`#\5Z9B&_0"P"`A#``;'0(`*"$40/PT
    +M`$"H(20"``(0`/Q7KZ(`M">]__"OL0`$K[\`"`"`B"$,`')AK[````!`("$,
    +M`')D```H(0P`%8@"("`A`$"`(0(@("$,`!6I`$`H(0P`&S$"`"`A$`#_]P``
    +M```GO?_PK[(`"*^Q``2OL```K[\`#`"`@"$,`!5'/!*``SP%@``\!X`"/`B`
    +M`SP+@`,`0(@A)DJ9J"2E9K@"`#`A).<0)"4(B:@E:YFP)`0``1!```@D"1``
    +M`B`0(8^_``R/L@`(C[$`!(^P```#X``()[T`$`P`H``0,`%K9`Z!((3P"@`*,5%/@/`*``HQ&4]B.`SB(
    +MDZ(``(^E``2L<0``H&(`"*QE``23H@`!C@0XB```D"&@@@`)C@(XB*Q&`!"L
    +M5``,/!.``HYP.(@,`'NZ`H`@(8YC.(@`$HB``C"`(:X"`!0"(X@ACB0`%`P`
    +M&S$F4@`!*D(``E1`__,\$X`"CF0XB`P`&NTD$@`//!"``HX".(@F4O__#`![
    +MNHQ$``R.!#B(#``;"@!`*"$&0__X/!"``HX".(B/OP`DC[0`((^S`!R/L@`8
    +MC[$`%(^P`!`#X``()[T`,">]_]`PH@`/)$(`320#__"OL@`8`*"0(0!#*"0"
    +M0Q@D`&40(0!#$"NOL0`4K[\`(`"`B"&OLP`]__"OOP``$.``#3"B`/\00``&`,`H
    +M(0P`&C4`````C[\```/@``@GO0`0C(0```P`%6\`P"@A$`#_^H^_```00``%
    +M`,`@(0P`&SP`````$`#_](^_```,`!LQ`,`@(1``__"/OP``)[W_\#"B`/^O
    +MOP``%$``!@#`*"$,`!LI`````(^_```#X``()[T`$(R"```,``FBC$0`!!``
    +M__J/OP``)[W_\*^_``",IP``C(0`!`"@,"$,`%MR```H(8^_```#X``()[T`
    +M$">]__"OOP``/`*``HQ".(P`H#`A$$``"Y"%`#.4P@`")$<`!`P`6W*,A``$
    +MC[\``"0$``$\`X`"K&0XC`/@``@GO0`0$`#_]R0'!R`D@@`<)[W_\*R``"0`
    +M`"@AK[\```P`]__"OL````("`(:^_``BOL0`$#`!R&`"@B"&.`@`D
    +MKB(``*X1`"0,`'(=)A``'`P`]`!`G
    +MO?_PK[\`!*^P```,`!KW`*"`(:Q0``2/OP`$C[```"0#`""L0P```^``"">]
    +M`!`GO?_PK*``!*^_```,`!L*`````(^_```#X``()[T`$">]__"OOP``/`*`
    +M`HQ".(@`@#`A```H(0P`6UR,1``$C[\```/@``@GO0`0)[W_\*^_```\`H`"
    +MC$,XB`"`,"$\`HB(D&4`,XQD``0T0HB(#`!;7*S"``"/OP```^``"">]`!",
    +M@@```((0(:Q%``",@@``)$(`!`/@``BL@@``)[W_\*^_``BOL0`$K[````"`
    +MB"&,A````*"`(20"__P")"`A`,`H(:R0```"`#`A)(0`!"80``,,`'(``@*`
    +M)(XB``"/OP`(`%`0(21"``2N(@``C[```(^Q``0#X``()[T`$(R#```D`@(`
    +M`$,0(Q"@``(`@R`AK*0``%3```&LP@```^``"`````",@P``)*4``R0"__P`
    +MHB@D`&48(0/@``BL@P``$*```@``&"&,HP```(,0(8Q"`"`0H``")&,`!*RC
    +M```#X``(K,(``(RB````@B`A$,```B2$`""LQ````^``"``````GO?_PK[\`
    +M!*^P```,`&U5`("`(20#``&N`P`,K@(``*X```BN```$C[\`!(^P```#X``(
    +M)[T`$">]__"OL```K[\`!(R"`#@`@(`A%$``)B0$``$,`&PL)`0``0P`;54`
    +M````K@(`+`P`;5@D!``"C@(`````*"$,`!3CC$0`!!1``!,`````C@(`,!1`
    +M``P``"`AC@(`.!1```4``"`AC[\`!(^P```#X``()[T`$`P`;'(`````$`#_
    +M^H^_``0,`&QD`````!``__..`@`X#`!M6(X$`"P,`&PL```@(1``_^V.`@`X
    +M#`!L<@`````0`/_8`````">]__"OL```K[\`!(R"`#@`@(`A%$``'20$``&.
    +M`@``)`4``0P`%..,1``$$$``!0````"/OP`$C[````/@``@GO0`0#`!M6(X$
    +M`"P,`&PL```@(8X"`#`40``()`0``8X"`#@00/_S```@(0P`;'(`````$`#_
    +M\(^_``0,`&QD`````!``__>.`@`X#`!L<@`````0`/_BC@(``">]__"OL```
    +MK[\`"*^Q``2,PP`H)`(``1!B``8`P(`AC[\`"(^Q``2/L````^``"">]`!"L
    +MP``\#`!REP`````,`!O*`@`@(8X"`"@40``@```@(1"``!``````C@(`/#P#
    +M``(T8TGP)$(``:X"`#R.`@`\`&(8*Q!@``<`````C@(``(Q"``2,41?H)`(`
    +M`1(B``H`````#``=#XX$``0D!``%#`!RK``````,`'*>`````!``_]N/OP`(
    +M#``;F@(`("$D!``+$`#_]JX1`"@,`!T6C@0`!`P`'3:.!``$/`,``@!`("$0
    +M0``.-&-)\(X"`#PD0@`!K@(`/(X"`#P`8A`K4$``"(X"`"B.`@``C$(`!(Q#
    +M%^@D`@`!$&+_S0````".`@`H%$#_Z0`````0`/_(`````">]__"OL0`$K[``
    +M``"@B"&OOP`(#`!RI0"`@"$"`"`A`B`P(0P`&_$``"@AC[\`"(^Q``2/L```
    +M)`(``0/@``@GO0`0)[W_\*^P```\!X```("`(3P(@``DB0`D)(H`""3G]__`D`P`!K[```*^_``BOL0`$$*,`
    +M$0"`@"%0H``2C((`*"0"``(0H@`,)`(``U"B``:,@@`HC[\`"(^Q``2/L```
    +M`^``"">]`!!40/_ZK(``*!``__F/OP`(K@``/!``__:/OP`(%$#_](^_``B,
    +M@@``C$(`!(Q1%^A6(__PC[$`!`P`'0B,A``$#`!RI20$``4,`!N:`@`@(:X1
    +M`"@,`'*L)`0`"Q``_^2/OP`()[W_\*^R``@`@)`A)`0`0*^Q``2OL```K[\`
    +M#`P`>[H`H(@A`$"`(1(``!0``!`A```H(20&`$`,`'(-`@`@(28$`"RN$@``
    +MKA$`!`P`&XRN```H#`!RK"0$``0,`!Q0`@`@(8X$``0\!8``)*5QI`P`'.H"
    +M`#`A`@`0(8^_``R/L@`(C[$`!(^P```#X``()[T`$">]__"OOP``C((`*!1`
    +M``0``"@AC[\```/@``@GO0`0`$#X"8R$`"P0`/_[C[\``">]__"OOP``C((`
    +M*!1```0D!0`!C[\```/@``@GO0`0`$#X"8R$`"P0`/_[C[\``">]__"OOP``
    +MC((`*!1```0D!0`"C[\```/@``@GO0`0`$#X"8R$`"P0`/_[C[\``">]__"O
    +MOP``C((`*!1```0D!0`#C[\```/@``@GO0`0`$#X"8R$`"P0`/_[C[\``">]
    +M__"OOP`$K[````"`@"&,A``$K@8`+#P&@`"N!0`H),9RZ`P`6T(``"@AC@0`
    +M!#P&@``DQG,8#`!;0B0%``&.!``$/`:``"3&`P`6T(D!0`#C[\`!(^P```#X``()[T`$">]__"OOP``#`!<,(R$``2/
    +MOP```^``"">]`!`GO?_PK[\```P`7#B,A``$C[\```/@``@GO0`0)[W_\*^_
    +M```,`%Q)C(0`!(^_```#X``()[T`$">]__"OOP`$K[````"`@"$,`%Q`C(0`
    +M!`P`'0\"`"`A#``=%@(`("&/OP`$C[````/@``@GO0`0)[W_\*^P``"OOP`$
    +M#``="`"`@"$,`%Q$C@0`!(^_``2/L````^``"">]`!`GO?_PK[\```P`7%V,
    +MA``$C[\```/@``@GO0`0C((`````*"&,0D`@,$8`_SP#@`(`!1"`)&,XV`!#
    +M("&4@@``)*4``1#"``4LHP`(5&#_^#P#@`(#X``(```0(0/@``B4@@`")`(4
    +M`*R"``PD`@F>I((`""0"``6D@@`8)`(`!*R"`&0D`@`>I((`("0""2JD@@!X
    +M)`(`!ZR"`'PD`@`#H((`@"0"``\D`P`")`4``20&`#R@@@!7)`(0`*R%`$R@
    +M@P"!K((`6*2&`%ZL@``$H(,`&J"``!NLA0!TK(```*R``&RL@`!PK(``4*R`
    +M`&BL@``XI(``8*2&`%RD@`!B`^``"*2``((GO?_@K[````"`@"$D!!W8K[,`
    +M#*^Q``2OOP`0K[(`"`P`>[H`H)@A$$``0`!`B"$`0"`A```H(0P`<@TD!AW8
    +M/`*@P#1"`*",0P```B`@(:XP```P8@#P``(1`C!C``^N(P1\#``=/:XB!'@`
    +M0!@A``"`(3P"@`(D4CB0`!`0P`!2$"&40@``$$,`!B0"``DF$``!*@(`"11`
    +M__<\`H`")`(`"1("`!4D`P`!#`![NB0$`,"N(AOX$$``$"0#__\``"@A)`8`
    +MP`P`<@T`0"`A#``=3R8D&V@`$!#``%(0(8Q"``0`0/@)`B`@(11```L`0(`A
    +MKG$```(`&"&/OP`0C[,`#(^R``B/L0`$C[````!@$"$#X``()[T`(`P`>\V.
    +M)!OX$`#_\ZX@&_@0`/_R)!```B>]__`D!0`.```P(:^R``BOL0`$K[```*^_
    +M``P,`!WA`("0(0!`B"$40``'``"`(8^_``R/L@`(C[$`!(^P```#X``()[T`
    +M$`(`*"$,`"FX`D`@(28"``$P4/__`A$0*Q1`__H"`"@A$`#_\H^_``R,@AOX
    +M+*,`%0"@0"$D1P`T$&``"@``*"$\`H`"``@8@"1"$(``8A`AC$(```!```@`
    +M`````&<0(8Q%```#X``(`*`0(3#"(`!00/_\E.4`2!``__J4Y0!$,,(@`%!`
    +M__>4Y0!*$`#_]93E`$8D`@`0$,(`#RS"`!$00``&)`(`$20"``-0PO_MC.4`
    +M3!``_^LD!0`!$,+_Z0``*"$D`@`@5,+_YB0%``$0`/_DC.4`4(R"&]`00/_A
    +MC.4`5(SB`%@0`/_>`*(H)"0"`!!0PO_;C.4`9"S"`!$00``&)`(`$20"``-4
    +MPO_5)`4``1``_].,Y0!<$,+_T0``*"$D`@`@5,+_SB0%``$0`/_,C.4`8">]
    +M_[`\!8`"/`:``J^P`#"OOP!(K[4`1*^T`$"OLP`\K[(`.*^Q`#0DPA$D)*,1
    +M'(RG$1R,:``$C$D`#(Q#``2,QA$DC$(`"```*"$`@(`AKZ<`"*^H``ROI@`8
    +MKZ,`'*^B`"`,`#K_KZD`)!1``&H`0"`AC@4``(RB0"`P0P#_,$0`#P`#&0(D
    +M`@`%I@,<]!!B`.^F!!SV-`*```"B$"&,0A@8```X(:8"'/@`!TB``3T0(8X#
    +M``",40`(```H(0!Q&"&,8P``K$,`$(X"````!1P``&48)0!1$"&L0P``C@(`
    +M`"2E``$LI`$``%$0(8Q"``!40P!()`0`%A2`__2.`@`````P(2>E`!B,HP``
    +M),8``0!1$"&L0P``C@@``"S$``0DI0`$`1$0(8Q"``!48@`Y)`0`%E2`__2.
    +M`@```3T0(8Q#``B,1``0).(``3!'__\!`Q@A+.(``JQD```40/_3``=(@`P`
    +M:J(D!`!DC@(``#0$@``D`P`'`$00(:Q#&`".`@``)`,<%@``."$`1!`AK$,8
    +MT(X#```DX@`!,$?__S0&@```9A@A/`(``2SD``BL8AB`5(#_^(X#``".`@``
    +M)`4`"`!&$"&,1!P```0F`C""``\``A$```0A`@P`6?X`@B`E`$`@(3!#`/"F
    +M`ASZ)`(`,!!B`)`P@@`/`@`@(20%`,$,`"RR`Z`P(1!```LD!``6C[\`2(^U
    +M`$2/M`!`C[,`/(^R`#B/L0`TC[``,`"`$"$#X``()[T`4">U``("`"`A)`4`
    +M'`P`++("H#`A%$#_\"0$`!:7H@`"%$``:R04!```%!!`)%'^@`P`>[H"("`A
    +M`$"8(1!`_^8D!``"`B`P(0!`("$,`'(-```H(8X"&_@D$0#``C08*ZQ3`+@0
    +M8``,`F"0(0(@*"$"`"`A`J`P(0P`++(F,0`!%$``"@(T&"N7H@`"ID(``!1@
    +M__8F4@`"`H`H(0P`(0$"8"`A$$``"@`````28``&)`4`%@P`>\T"8"`AC@(;
    +M^*Q``+@D!0`6$`#_PP"@("$,`'NZ)`0`.!!`__0`0(@A`$`@(0``*"$,`'(-
    +M)`8`.(X"&_@"("`A#``A#ZQ1```40/_JEZ(```(`("$"8"@A#``E]Z8B```4
    +M0/_D)B8``@(`("$,`"RR)`4`/Q1`_]\"`"`AC@4;^`P`(-`DI0"H%$#_V@``
    +M```,`!_F`@`@(11`_]8F!1NF#``L>P(`("&*`QNFF@,;J11@``4D`O__E@(;
    +MJA!``!`\`@`#)`+__U!B``F6`QNJE@(;II8$&ZB6`QNJ```H(:8"&ZRF`QNP
    +M$`#_R:8$&ZXT`O__5&+_]Y8"&Z8\`@`#-$)_OZH"&Z:Z`ANI)`*JJA``_^^F
    +M`ANJ,$+_\`(`("$D!0`;`J`P(0P`++(``J,`%$#_>R0$`!:7H@`"$`#_C`*"
    +MH"4L0@`%%$#_=20$`!80`/]N`@`@(2R"``(40/]P)`0`%A``_P\T`H``)[W_
    +M\*^Q``2OL```K[\`#*^R``B,@AOX`("((20$`"`,`'NZC%(`N!!``!<`0(`A
    +M`$`@(0``*"$,`'(-)`8`((XB&_@"`"@A`B`@(0P`2-NL4``$``"`(0(`*"$"
    +M("`A#``IN"80``$J`@"`%$#_^P(`*"&.)1OX#`!`!P(@("$40``/`````!)`
    +M``,`````#`![S0)`("$,`!^/`B`@(20$`!:/OP`,C[(`"(^Q``2/L````(`0
    +M(0/@``@GO0`0#``U"0(@("$,`"]G`B`@(8XD&_@\`X`")&,R8#P0@`(\!X``
    +M/`B``#P*@`.L@P`8KB(7Q"8)5U`DYTO0)0A-N"5*L0```"@A`B`P(0P`\T"0"`ACB,;^"0"``H``"`AK&(`:!``
    +M_]FL8`"X)[W_X*^T`!"OOP`4K[,`#*^R``BOL0`$K[```(R2&_B.4```$@``
    +M'0"`H"&.!``$%(``00````".!``(%(``.@````".!``,%(``,P````".!``0
    +M%(``+````````)@A`@"((8XB`!0F.(@`4#`![S0(`("&N0```CD0`!!2```T``````H`@(0P`
    +M0!0"0"@AC[\`%(^T`!"/LP`,C[(`"(^Q``2/L``````0(0/@``@GO0`@#`![
    +MS0`````0`/_QKD``!`P`>\T`````$`#_Y2YB``,,`'O-`````!``_]V.(@`<
    +M#`![S0``F"$0`/_4`@"((0P`>\T`````$`#_S(X$`!`,`'O-`````!``_\6.
    +M!``,#`![S0`````0`/^^C@0`"(R#&_@D`@`.)&,`-`/@``@``Q`+)[W_T*^T
    +M`""OL@`8K[``$*^_`"2OLP`C``",0@``KB,`-)1"```L0E`#
    +M%$``QB>F``0"0"`A#``LLB0%`,H40`">`$"@(9>B``0P0@_```(10C1"``&N
    +M`@`\CD(;^(Q"``"40@``+$)0`1!``*XGI@`"IZ```I9B`!*69``0EF,`%``"
    +M$(``@B`E``,8P)9E````@R`E-((``@!%(`J68P`"`(`H(32B`!"7I````$,H
    +M"C"B``$40``#K@0``"0"__T`HB@D,*(`"!1```0D`@D()`+_[P"B*"0D`@D(
    +MI@(`2)9"'/HP0@#P+$(`,!!``(NN!0`$ED,<]"0"``<08@`%)`()Q"0"``H0
    +M8@`")`()Q"0""JRF`@!*EZ@``B0"$SBF`@!$)`(7U*8"`$8Q`P`")`(``:X"
    +M`&2N``!@%&``"```("&60QST+&(`!E!```0D!``!)`(`!5!B`&F60QSVEDD<
    +M]*X$`%PD`@`!,23__RR#``:N`@!4K@``4!!@`%X``#`A)`(`!5""`%B60ASV
    +M,03__P`$$$(X0@`!)`<``3!"``$Q`P`!K@8`6*X"`$RN!P`(K@<`#!1@``,`
    +M`#`A,*(`"0`","L`!!#".$(``3!"``$Q`P`$K@8`$*X"`!048``#```P(3"B
    +M``D``C`KEF(`!HYD`!@`!1D",&,``:X&`!BN`P`@K@<`)*X"`"BN!P`<$(``
    +M!```*"&.8@`<5$```R0"``$D!0`!)`(``3$#`?"N`@`PK@4`+!1@``(``Q$"
    +M)`(`"C$#\``08``EK@(`-``#&P(D`@`!`&(0!*X"`#B.0AOXC$,``)>B``0P
    +M0@_```(A0I1B```L0E`#%$```ZX$`#PT@@`!K@(`/()B`""N`@!H@F(`(:X`
    +M`$"N`@!L)`(`"A!)``PD`@`##``?X0)`("$"@!`AC[\`)(^T`""/LP`]`#`0`/_TK@(`0!``_]XD`@"`+$(`"!1`_Z@Q!/__
    +M$`#_I20&``$D`@`"$&(``RQB``140/^5EDD<]!``_Y(D!``!$`#_?20""<0"
    +M0"`A#``LLB0%`,D40/_A`$"@(9>B``(0`/]-IF(`.`)`("$,`"RR)`4`RA1`
    +M_]D`0*`AEZ(`!#!"#````AE"K@,`/!``_SNGH@`$)[W_T*^S`!ROL@`8K[$`
    +M%*^P`!"OOP`@`*"0(0"`F"$``(@A`*"`(28E`+`"8"`A#``LL@.@,"$F,0`!
    +M`$`X(11```@J)``&EZ(``).C``$``A("H@,``*("``$4@/_R)A```I)#``LD
    +M`@#_$&(`"@``B"&B0``,C[\`((^S`!R/L@`8C[$`%(^P`!``X!`A`^``"">]
    +M`#`"42`A`E$H(X"&``"0H@`*)C$``2HC``6@@@``%&#_^*"F``H0`/_MHD``
    +M"R0'`,``Y1`K$$``!P``,"&4@@``).<``0#E&"L`PC`F%&#_^R2$``(XP___
    +M)`(`%@/@``@``Q`*)[W_\*^P````@(`AK[\`!`P`>[HD!`%8K@(`!!!``$(D
    +M`P`"`$`@(0``*"$,`'(-)`8!6`P`>[HD!`-DK@(`"!!``#DD`P`"`$`@(0``
    +M*"$,`'(-)`8#9(X)``@D`@`*)`@`":4B`!0D`@`#I2("'B4C`!PD`@`+)0C_
    +M_Z1B```%`?_])&,`-```0"$!(#@A/`.``CP"@`(`""!`)&,=)"1"'1P`@A`A
    +M`(,8(91&``"48P``)0@``0")("$D`@`+*04``Z2#`B"DA@(FI.(",J3B`LX4
    +MH/_N).<`-`P`>[HD!`"(K@(`#!!```\D`P`"`$`@(0``*"$,`'(-)`8`B`P`
    +M>[HD!`@`K@(`$!!```8D`P`"`$`@(0``*"$,`'(-)`8(````&"&/OP`$C[``
    +M``!@$"$#X``()[T`$">]_^"OOP`0K[,`#*^R``BOL0`$K[```(R"&_@`H$@A
    +M,,/__XQ3``"68@``+$(P`Q1``"F.<``(E@8`%```D"$"1A`K4$``$)8"`!0"
    +M`#@A``,00`!)$"&42```)E(``B1C``$Q!`#_``@2`@)&*"NDX@``I.0``C!C
    +M__\4H/_T).<`!)8"`!000``,``"0(0(`B"&6)0``EF0`````,"$,`"BX)E(`
    +M`98#`!2F(@```D,8*Q1@__IB8`!*8E``*6"@``)A```@`*2X(`"D$```H2
    +M`@`*&((`B2`E,0@`/S!"`#\P8P`_IB@`)*8D`!ZF(@`@IB,`(I8*```F$``"
    +M``H;`@`*$8(!`T`E,$(`/S%#`#^F*``DIB(`)J8C`"B6"@``)A```@`*0(``
    +M"AD"``H2@C$(`#\P8P`_IB@`+J8B`"JF(P`LE@H``"80``(`"B."``H8@@`*
    +M$@(!!$`E,$(`/S!C`#^F*``NIB(`,*8C`#(,`"B4EH0``)8G``80X``-```P
    +M(0(@*"&$H@`>),8``0#'("L``AA``&(8(0`#&,``8A@A``,80*2C`!X4@/_V
    +M)*4``B;6``$"UQ`K)C$`-!1`_[$F)&,`-R91`L@0`/^))D0")B>]_["OO@!`K[<`/*^V`#BOM0`T
    +MK[0`,*^R`"BOL``@K[\`1*^S`"ROL0`DC((;^#DC``$!(/`AC$0``##6__\!
    +M`*@AC((`!)2$````H+@A)$D!$*^B`!PD0@$*`$-("S#R__\``*`AKZ0`&`+`
    +M@"$7P`"C``!`(0/2$"L00``A`!(00@`0$$``58@ADB(``0`4&$"/I``8```P
    +M(0!]F"$00``7`$`H(0P`*+@`````)H,``3!T__^6(P```!0H0`"]B"$``QH"
    +MCZ0`&```,"&F8@``$&``"@!@*"$,`"BX`````"8#``$P]`!`,`'O-CB0``!``__8D`P`"E(,`%B>]__`D
    +M`MZM`(!@(:>B``*DHP`&IZ(```!@."$``#`A```@(0"'$`5@@`4``!((1!``'&DH@`$``D80`!I&"$``QB``&D8(0`)0(```QA`
    +M`0D0(0&#&"$``A"`C*H`")1D`!@`21`A``(0@`!*$"&D1```)&8`&)3#`!*D
    +M0P`"EZ,``C0"WJT08@!>```@(0$)&"$``QB``&D8(0`$$(``1!`A``-8@"2#
    +M``$``A"`,&3__P%J."$`1Q`A+(,`!!1@__.D0``&EZ,``)3$``(``Q"``$,0
    +M(0`"$(``1Q`AI$0`")>C``(``Q"``$,0(0`"$(``1Q`A)`,`%*1#``B7HP`"
    +M``,0@`!#$"$``A"``$<0(20#`".D0P`*EZ,``@`#$(``0Q`A``(0@`!'$"$D
    +M`P`_I$,`#)>D````!!"``$00(0`"$(`!8A`A`$H0(21$``0D`@`$I((``I3#
    +M``:4@@`$`$,0(:2"``:4PP`*`$,0(:2"``B4PP`.`$,0(:2"``J4P@`$I((`
    +M#)3"``BD@@`.E,(`#*2"`!"4P@`0I((`$I>D``(`!!"``$00(0`"$(`!8A`A
    +M`$H0(21$``0D`@`#I((``I3"`!2D@@`,E,(`%J2"``Z4P@`8I((`$)2B``0E
    +M(P`!,&G__P$B$"L40/^2``D80"0"``$#X``()[T`$`$)&"$``QB``&D8(0`$
    +M$(``1!`A``,X@"2#``$P9/__``(0@`#J&"$`0Q`A+(,`!!1@__.D0``&EZ0`
    +M```$$(``1!`A``(0@`#B$"$`2A`A)$0`!"0"``2D@@`"E,(``J2"``24PP`&
    +M`$,0(:2"``:4PP`*`$,0(:2"``B4PP`.`$,0(:2"``J4P@`$I((`#)3"``BD
    +M@@`.E,(`#*2"`!"4P@`0$`#_S:2"`!(GO?ZPK[`!(D`@`!``"0
    +M(0``J"$2@@!RC[$`!%*``&J.8P`,)`(``A*"`%TF(@!IIJ```!+@`#@``+`A
    +MEF(``(^E````$2!`)B,``0"%("$L0C`#,''__Q1``$^4D````!`2`J9"``B6
    +M10`($*``2"8B``$6@`!$EF0`````,"$,`"BX`````*9"``B68@``+$(P`Q1`
    +M`#H`$!C``!`9```0$((P0@`_,&,`/Z9#``2F0@`&EF(``(^E````$2!`)B,`
    +M`0"%("$L0C`#,''__Q1``".4D```ED,`!``0(P(`$!&"`&08)3!"`#\R!``_
    +MID,`!*9"``*F1```EJ(``"1"``&FH@``)M8``0+7$"L40/_*)E(`"B:4``$N
    +M@@`#%$#_NB0"``&/H@`(C[\`-(^^`#"D40``C[<`+(^V`"B/M0`DC[0`((^S
    +M`!R/L@`8C[$`%(^P`!`#X``()[T`0)9#``0`$"!"`!`K0@`0$<(`91@E,$(`
    +M/Q``_]TPA``_$`#_R``0$,(0`/^])`8``1``_]TP4?__$`#_L@`0$D(7P``$
    +M,%'__R8B``80`/_:,%'__XYB``PD%P`#)%4`4A``_YLD4@!4)B(`53!1__\`
    +M8*@A)!<`"!``_Y4D<@`")B(`93!1__\3P/_P)B(`!(YB``PD%P`")%4`6H@``)B,`""8D``]`#`D!@"0)`(`0!``_^H`0S`+`F`@
    +M(0P`)$<"@"@A`$"H(11`_^T`0!@A$`#_VY9#```GO?_0K[8`&*^S``ROL@`(
    +MK[\`(*^W`!ROM0`4K[0`$*^Q``2OL```C((;^`"@D"$`P)@AC$(``)14```D
    +M`@`/H*(`(BZ6,`,D`@`/%L`"+:2B`"8\`H`")%`+,H(92P```F,0`!,@(``0`"$<``@B`E`!`00J)$`&NB0@!P)J(``3!5
    +M__\NH@`#%$#^_P`5$(!2P``3CN(`%``1$$``4Q`AE%```"8Q``$`$2!``!`0
    +MPC(#``]`#``4Q`AE%````*`("$D!@`!
    +M#``HN#(%`/\F,0`!`!`J`@*`("$D!@`!#``HN*9"`0H`$1A`ID(!#`!S&"&4
    +M<```)C$``0`1($``$!'",@,`?S!"`#^F0P`*ID(`#@"3("&4D```)`8``0*`
    +M("$,`"BX,@4`_RZ#0`&F0@$.%&``!"8Q``$`$!(",$(`/Z9"`-P`$1!``%,0
    +M(910```NA$`")C$``0`0$4(P0@`_,@,`'Z9"`004@``&ID,!"``1$$``4Q`A
    +ME%```"8Q``&B4``B+H)0`!1`_XHFH@`!`!`2`@`0,\(P0@!_`!$80*9&`$ZF
    +M0@!$`',8(91P```F,0`!`!$H0#("`!\``A!``!`90@`0(L(`PC`E,&,`/Z)$
    +M`&RF1@!.ID,`X`"S*"&4L```)C$``3("``<``A%``((@)0`0$,*B1`!L$`#_
    +M;*)"`'$`$1!``%,0(910```"@"`A)`8``0P`*+@R!0#_)C$``0`0*@("@"`A
    +M)`8``0P`*+BF0@$0`!$80`!S&"&F0@$2E'````*`("$D!@`!#``HN#(%`/\N
    +M@T`!ID(!%!1@_U,F,0`!`!`2`C!"`#\0`/]/ID(`V@`0$,(P0@#_+H-`!A1@
    +M_Q"F0@`D`!`2PA``_PVF0@`F`%(0(20#``JD0P#2)`(`#Q``_Q"F0@`D,$(`
    +M!S(#``>F0P#\$`#^\*9"`0`6H/[O+H(P!#("`#\0`/[KID(`#``0$,(P0@`'
    +M,@,`!Z9#`/H0`/[EID(`_C!"``$0`/[1ID(`,#!"``$0`/[.ID(`+C!"``F0P#NID0`\!``_G2F0@#J`!`1`C!"``B```0
    +M`/_>,$/__XR"``",0D`(.$(``0/@``@L0@`!)[W_X*^S``ROL0`$K[```*^T
    +M`!"OL@`(K,```(R+```D`O__`*"8(8UI`(``P(`A`(!0(20%__\1(@`X``"(
    +M(8R#&T`\!`$%-(38,`$C&"0\`@"``21`)#$E``4`8F@D-0(``0!%0`L\$@`@
    +M,&<`!3!F`4`U`@!``'+()#$E`4`P;`"``&08)`!%0`LT8@`!`$<8"S1B`$`\
    +M%`/_/!@@`#$O`"`Q+@"`$:```@!&&`N-<0",`8,8)0(X("01H``"`'@0)0!$
    +M&`L`OO@!PK[<`;*^T`&"OL@!8K[$`5`#`D"&O
    +MOP!TK[8`:*^S`%ROL`!0`."((:^B`#0`@*`A`*"X(0`(J`JOH``$KZ``````
    +M,"$0X`!!``#P(93C``PL8@`A$$``$P`#$(`\`X`")&,1?`!#$"&,0@```$``
    +M"`````"4Y0`T)/``-B0"``6OH@`T)`(`:!"B`@,HH@!I$$`!_R0"`(`D`@`H
    +M4*(`#I("``6/OP!TC[X`<(^W`&R/M@!HC[4`9(^T`&"/LP!]`("2`@`%D@,`!)($``:2!0`'``(2``!B&"4`!"0``&08)0`%
    +M+@``91@E`'48)C!C__\``Q`G,$+__Z^B`!2OHP`$D@,``9("``"2!``"D@4`
    +M`P`#&@``0Q`E``0D``!$$"4`!2X``$40)0!5$"8``A@GKZ,`#*^B```20``4
    +M-`6``))"``.20P`"DD0``9)%``4``A8```,<`))&``221P```$,0)0`$(@``
    +M1!`E``4J``"F,"4`1_`E`![P0@`&%\`#PO`E``8P0C0%@``TQH``KZ4`1*^F
    +M`$@2(``%KZ``/)8C``PD`@`0$&(`*@*`("$``#`A`Z`X(0`7$,".@P```$80
    +M(8SE``P``A"`-`B(``!($"$DQ@`!`&(8(2S$``BLX@`(K&4``!2`__,DYP`(
    +MCH(````7(4"/HP```((0(0!($"&L0P``CH(``#0#B`0`@A`A`$,0(8^C``2L
    +M0P``CH(``#0#B!@`@A`A`$,0(:Q>``".@@```((@(30"B!P`@B`ACZ(`2*R"
    +M```0`/^1C[\`="0%`!,,`!WA)`8`$!!`_]0``#`A$D`!`R>D``@``"@A#`!R
    +M#20&`$`D`@`$)C``%*^B`#22`P`-D@(`#)($``Z2!0`/``,:``!#$"4`!"0`
    +M`$00)0`%+@``11`E`%40)J^B`"R2`P`+D@(`"I($``R2!0`-``,:``!#$"4`
    +M!"0``$00)0`%+@``11`E`%40)C!"__^OH@`DD@,`!Y("``:2!``(``,:`)(%
    +M``D`0Q`E``0D``!$$"6/I``$CZ,````%+@``11`E``0@)P!5$"8PA/__``,8
    +M)S0%@``"`)`AKZ(`'*^D`!2OHP`,KZ4`1*^@`#PR\___```P(0.@."$`$Q#`
    +MCH0```!&$"&,Y0`,-`.(```"$(``0Q`A),8``0""("$LPP`(K.(`"*R%```4
    +M8/_S).<`""8P`$8FX@!`)Z0`"```*"$D!@!`#`!R#3!3__^2`P`!D@0``I(B
    +M`$:2!0`#``,:``!#$"4`!"0``$00)0`%+@``11`EKZ(`#)(#``62`@`$D@0`
    +M!I(%``<``QH``$,0)0`$)```1!`E``4N``!%$"6OH@`<```P(0.@."$`$Q#`
    +MCH,```!&$"&,Y0`,``(0@#0(B```2!`A),8``0!B&"$LQ``(K.(`"*QE```4
    +M@/_S).<`"(Z"``"/HP```!>Q0`+"$"$`2!`AK$,``(Z"```T`X@$)Z0`"`+"
    +M$"$`0Q`ACZ,`!```*"$D!@!`K$,``";B`"`,`'(-,%/__R0"``2OH@`TDD,`
    +M#9)"``R21``.DD4`#P`#&@``0Q`E``0D``!$$"4`!2X``$40)0!5$":OH@`L
    +MDD,`"Y)"``J21``,DD4`#0`#&@``0Q`E``0D``!$$"4`!2X``$40)0!5$"8P
    +M0O__KZ(`)))#``>20@`&DD0`"))%``D``QH``$,0)0`$)```1!`E``4N``!%
    +M$"6/I``$`%40)H^C``"OH@`OI``4KZ,`#*^^`#ROH@!$,O/__P``,"$#H#@A`!,0
    +MP(Z$````1A`AC.4`##0#B````A"``$,0(23&``$`@B`A+,,`"*SB``BLA0``
    +M%&#_\R3G``@F,`!.`D`@(2;B`$```"@A)`8`0`P`<@TP4___D@,``9(B`$Z2
    +M!``"D@4``P`#&@``0Q`E``0D``!$$"4`!2X``$40):^B``R2`P`%D@(`!)($
    +M``:2!0`'``,:``!#$"4`!"0``$00)0`%+@``11`EKZ(`'```,"$#H#@A`!,0
    +MP(Z#````1A`AC.4`#``"$(`T"(@``$@0(23&``$`8A@A+,0`"*SB``BL90``
    +M%(#_\R3G``B.@@```!2`@`&
    +MD@0`")(%``D``QH``$,0)0`$)```1!`E``4N``!%$"4`51`F$`#]Z*^B`!R2
    +M`@`,D@0`#I(%``\``QH``$,0)0`$)```1!`E``4N``!%$"4`51`F$`#_VC!"
    +M`/^4Y0`*)`(`:!"B``TD\``4**(`:1!```8D`@"`)`(`*%"B_;ZOH``T$`#]
    +MO20"`&A4HOV[)`(`:!``_;HIP`(N*<`
    +M"Z"H``P#X``(`&`0(8R$&_@PI?__C(,`-!!E``(``!`AK(4`-`/@``@`````
    +M`^``"```$"$GO?_@K[$`%`.@,"$`H(@A)`4`'Z^R`!BOOP`<`("0(0P`++*O
    +ML``0`D`@(0.@,"$00``))`4`'B0$`!:/OP`B``"3HP`!`@*`(0`"$@*B(P`##``LLJ(B``(40/_G)`0`%I>B``"3HP`!
    +M/`4``@("@"$``A("```@(32E__VB(@`$$@#_W*(C``46!?_]_]"OOP`@K[,`'*^R`!BOL0`4K[``$(RC`!",I@`4
    +M`*"`(5!@``$```'-`,,`&XX"``P#H"@A`("((0``F!(```````````!B`!L`
    +M`)`2#``M\`````"/HP`$CZ(``(X&``2.!0`(``,=@``"$H(`8D@EC@,``(X(
    +M``PE(@`"),;__P!H("$F9___`((8*P3``*&N!```5&#_]XX#``!PR#@"C@(`
    +M$(X#`!@`Y#`A<*(@`JX&``0`AA`A$&``C*X"``B.)```-`6``#P#`!``A2`A
    +MC((`!`!#$"6L@@`$CB(``(X#`!0`11`AK$,`)(XB``".`P`8`$40(:Q#`#B.
    +M(P``C@(`"`!E&"$``A#`K&(`,(XB``".`P``-!*```!2$"&L0P`HCB,``)8&
    +M``X\$___`'(8(8QB`"`"("`A/`6```!3$"0`1A`EK&(`(`P`*88`````CB(;
    +M0(XD```\`__[-&/__P!#$"2N(AM`K((`H(XB'8B.)```/`7__P!#$"2N(AV(
    +MC@(`(`"2("&,@P`8-*4`_P`"$@``91@D,$+_``!B&"6L@P`8CB(;0(XD```\
    +M`P`$`$,0):XB&T`\!8``K((`H`P`*58"("`AC@,`'(X"``P`0Q`K5$```:X#
    +M``R.`@`0`$,0*U1```&N`P`0C@,`#(X"`!!08@`ZC@(`!(X"``2.(P``/`8`
    +M!P`"$,`TQO__)$+_Z`!R&"$`1A`DK&(`U(XC```\!0#_-*7__P!R&"&,8@#4
    +M/`<*`#P$`!@`11`D`$<0):QB`-2.(P``C[\`(`!R&"&,8@#4`$00):QB`-2.
    +M`@``CB,````"$,`D0O_H`$80)`!R&"&L8@#8CB,```!R&"&,8@#8`$40)`!'
    +M$"6L8@#8CB(``)8#``X`4A`AK$,`W(XD``".`P`0C[$`%`"2("&,@@#<``,<
    +M``!S&"2/L@`8C[,`'(^P`!`P0O__`$,0):R"`-P#X``()[T`,!``_\:N`@``
    +MCB,``#0"@``\!/_O`&(8(8QB``0TA/__`$00)*QB``00`/^!CB(``"2E__\H
    +MH@``)D;__Q``_UP`XB@+C((``#0&@```1A`AC$(`3*BB``"XH@`#C((```!&
    +M$"&,0P!0C$(`4*BB``2XH@`'B*(`!)BB``<00P`&`````(R"````1A`AC$(`
    +M3*BB``"XH@`#`^``"`````",@P``-`6``#P&`0``91@AC&(`(`!&$"6L8@`@
    +MC(,```!E&"&,8@`@`$80):QB`"`#X``(`````(R%```T!H```(`X(0"F$"&,
    +M1``$C*(`%#P#_Y\T8___-$(`(*RB`!2,X@```(,@)#P#`((`@R`E`$80(:Q$
    +M``2,XAMT)`,4`#!"-P!00P`#C.,```/@``@`````)`(#<*S@'0"L8A!P$`#_
    +M^@````",@AMT```8(3!"`@`00``UC(D<#)"K```18``.``!`(0"H$"&00@`!
    +M)0@``0$+4"HP1@!_,$(`@!!```0`PS@K5.```0!@,"$PPP#_%4#_]0"H$"&-
    +M)@``&,``"0``."$E)0`VD*(``!!#``4DI0`<).<``0#F$"I40/_[D*(``!C`
    +M``L``$`A)24`-P#H$"I40``"H*<``*"H``"-(@``)0@``0$"$"H40/_X)*4`
    +M'%!@``Z,@P````,00BQ"``-00``*C(,``(R$```T`H``/`,"``""("&,@@`$
    +M`$,0):R"``0#X``(`````#0"@``\!/W_`&(8(8QB``0TA/__`$00)*QB``0#
    +MX``(`````(R#```T`H```&(H(8RB&&0``A3",$,!`#!$`?\08``".((!_P`"
    +M(">,H@!0C*,`3`!#$"8#X``(`$00)B2C__\L8@`%`*#`(1!``#L`@'`A``,0
    +M@#P#@`(D8Q)$`$,0(8Q"````0``(`````(R"```T#X``)(T$@`!/$"&,1`"0
    +MC:(`3(VC`%B-QP2``$00(:VB`$R-P@``C:@`8(VD`%"-I0!4`$\0(8Q"`(R-
    +MJ0!DC:L`:`!B&"&MHP!8C`````#P"4>LT0H4?`*(`&0``$!```BE")`(`9`!E`!M0H``!
    +M```!S0``&!(0`/_2`$,@(U#`_]```"`AC((``#0#@```0Q`AC$4`[*S%``",
    +M@@```$,0(8Q$`/"LQ``$C<(```!#$"&,0@#TK,(`"(W"````0Q`AC$(`^*S"
    +M``R-P@```$,0(8Q#`.R,0@#P`&48)@!$$"8``Q@K``(0*ZS"`!`0`/^SK,,`
    +M%(R"```T`X```$,0(8Q"&&0``A,"`^``"#!"`'\PI?__)(0%O```&"&4@@``
    +M$$4`"22$`$@00``(``,4`"1C``$L8@!`5$#_^92"```#X``(```0(0`#%``#
    +MX``(``(4`R>]__"OL```)`4``@"`@"&OOP`$#``NA```,"&.`@``-`2``#P#
    +M``(`1!`AK$`!)(X"``"/OP`$`$00(:Q``2B.`@``K$``0(X"````1!`AK$,!
    +M,(X"``"/L```/`,"``!$$"&L0P$X`^``"">]`!`GO?_P```H(20&`$BOOP`$
    +MK[````P`<@T`@(`A/`(`/S1"_SBN`@!$)`(!]*X"`!`D`@!DK@(`'"0"`"BN
    +M`@`D/`,`/R0"``]`!`GO?_PK[\`!*^P
    +M``",D`6X/`(`0`"`0"&.`P`0`$,@(P!#$"H00``EK@``#*X``$".`P`8/`(`
    +M0`!#(",`0Q`J4$```JX$`$2N``!$C0(``(X#`$`T!X```$<0(:Q#`2R-`@``
    +MC@,`1`$`("$`1Q`AK$,!-(T"```\`P`")`4``@!'$"&L0P$PC0(``#P#`@``
    +M`#`A`$<0(:Q#`3@,`"Z$`````*X``#RN```XC[\`!(^P```#X``()[T`$!``
    +M_]RN!`!`)[W_\*^Q``2OOP`(K[```(R#%\``@(@AC)`%N"AB```D9`!_`&`H
    +M(0""*`L`!2G#``41P`!B$",H0@!`5$``!0"@("$D8P#^*((```!B(`L`!"'#
    +MCB(7Q!!``!2/OP`(D@(``Q!``$TD0@`!D@,`!"QB``(40`!$)&(``8X"`"0`
    +M1!`J4$``'XX"`""2`@`&$$``$B0"``&2`P`%+&(``A1```8D8@`!C[\`"(^Q
    +M``2/L````^``"">]`!`P1@#_`B`@(20%``2B`@`%#``Q60`````0`/_UC[\`
    +M"`(@("$D!0`"H@(`!@P`,5D``#`A`B`@(20%``6B```$$`#_\P``,"$`1!`J
    +M4$``"XXB&W22`@`&4$#_X9(#``6B```&`B`@(20%``(,`#%9)`8``1``_]J2
    +M`P`%,$(0`!!`_]N/OP`(D@(`!A!```@D`@`!D@(`!5!`_]6/OP`(H@``!0(@
    +M("$0`/_E)`4`!*("``8"("`A)`4``@P`,5D``#`A$`#_])("``4P1@#_`B`@
    +M(20%``40`/_-H@(`!#!&`/\"("`A)`4``1``_\BB`@`#C(,7P">]__"OOP``
    +M*&(``"1E`'\`8#`A`*(P"P`&,<,`!A'``&(0(RA"`$`40``JC(<%N"1C`/XH
    +MH@```&(H"P`%&<.,@A?$$$``#8^_``"0X@`#$$``'"1"``&,X@`@`$,0*E!`
    +M``^,@AMTD.,`!2QB``(40``$)&(``8^_```#X``()[T`$#!&`/\D!0`$H.(`
    +M!0P`,5D`````$`#_^(^_```P0A``$$#_]8^_``"0X@`%$$#_\B0%``2@X``%
    +M$`#_]```,"$P1@#_)`4``1``__"@X@`#$`#_V@#`&"$GO?_PK[(`"*^Q``2O
    +ML```K[\`#)2%&W`,`"\8`("`(0`"&,``8A@A``,8P`(#D"&60P6\E@(;<"91
    +M!;P"("`A$&(`+ZX1!;@,`"]%`````(X"&W26`QMP``(2`C!"``^F0P6\HB(`
    +M`I(F``,"`"`A#``Q620%``&2)@`$`@`@(0P`,5DD!0`%DB8`!@(`("$D!0`"
    +M#``Q62S&``&2)@`'`@`@(0P`,5DD!0`#DB8`!20%``0,`#%9`@`@(0P`+XH"
    +M`"`AC@(``#0$@``\`P`"`$00(:Q#`3".`@``C[\`#(^R``B/L0`$C[````!$
    +M$"$\`P(`K$,!.`/@``@GO0`0C@(;=)(C``(``A(",$(`#Q1B_\T`````$`#_
    +MU)(F``.,@Q?`)[W_\*^_```H8@``)&8`?P!@."$`PC@+``\C@0`#``#$(``0Q`A`$00*Q!``!L`9!`KC@(`%#P#$&(T8TW3<((0`@!#
    +M`!D``!`0``(1@@!%$"L40``)`````(X"`!QP@A`"`$,`&0``$!```A&"`$80
    +M*Q!```4`````#``OB@(@("$0`/^ZC[\`"`P`,*<"("`A$`#_^0`````00/^S
    +M/`,08HX"`!`T8TW3<((0`@!#`!D``!`0``(1@@!%$"L40``-`````(X"`!AP
    +M@A`"`$,`&0``$!```A&"`$80*U!`_Z./OP`(#``P)P(@("$0`/_B``````P`
    +M+[L"("`A$`#_W@````"L90$LCB(``#P#``(`1!`AK$,!,!``_Z^.`P!$)*7_
    +M_RRB``4GO?]P`(!H(1!``%(`P&`A/`.``@`%$(`D8Q-$`$,0(8Q"````0``(
    +M`````#P"@`(\!H`")$,2P(VE``",1!+`C&(`!(S#$L@T"H````Q(@`$]2"&O
    +MH@`$`*HH(:^C``BOI```C2,``(RD&%`\`O`/-$+__P""("0``QT`/`(/\`!B
    +M&"0`@R`E/`B``B3&$LBLI!A0C,(`!(T#$M"-I@``KZ(`#*^C`!``RC`AC2(`
    +M"(S%&%P\`__`/`0`/S1C?_\TA(````(3P`!$$"0`HR@D`*(H)3P'@`(E"!+0
    +MK,487(SC$MB-`@`$C:4``*^C`!BOH@`4`*HH(8TB`!",I!A<)`.`?P`"$<``
    +M@R`D,$)_@`""("6LI!A<).<2V(SC``2-I0``/`+\`Z^C`!P`JB@AC*086(TC
    +M`!@T0O__`((@)``#'(`\`@/\`&(8)`"#("6LI!A8`^``"">]`)`\`H`"/`B`
    +M`B1#$N",1!+@C&(`!(T#$N@`!F`KC:8````,6(`!?5@A-`Z``*^C`"BOH@`D
    +MKZ0`(`#.,"&-8@`@C,48;#P#_^`\!``?-&,__S2$P````A.``$00)`"C*"0`
    +MHB@EK,48;#P'@`(E"!+HC0(`!(SC$O"-I0``KZ(`+*^C`#``KB@AC*08;(UC
    +M`"@\`O`?-$+__P""("0``QU`/`(/X`!B&"0`@R`EK*08;#P&@`(DYQ+PC.(`
    +M!(S#$OB-J```KZ(`-*^C`#@!#D`AC6,`,(T$&&@\!X`"/`+_`3P)@`(DY1,`
    +M-$+__R3&$OB,Q@`$C*4`!"4J$PB,YQ,``((@)(TI$P@\`@#^``,<0`!B&"0`
    +M@R`EC4H`!*^F`#ROI0!$KZ<`0*^I`$BM!!AHC:4``(UD`#@\`H#_`*XH(8RC
    +M&&@T0O__``0F``!B&"0\`G\``((@)`!D&"6LHQAHC:4``(UD`$`D`__@`*XH
    +M(8RB&&@PA``?KZH`3`!#$"0`1!`EK*(8:(VD``"-9@!()`/`_P".("&,@AAL
    +M``8R`##&/P``0Q`D`$80):R"&&Q1@``(C:(``(VC````;A@AC&(8;#1"``&L
    +M8AAL$`#_B@`````D!/_^`$X0(8Q#&&P`9!@DK$,8;!``_X,`````/`*``B1#
    +M$Q",A0``C&8`!(Q$$Q``#!@K-`*````#&(``HB@A`'T8(:^D`%"OI@!4C&0`
    +M4(RB(@@D`__`,(0`/P!#$"0`1!`EK*(B"!``_VX`````/`*``B1#$QB,1!,8
    +MC&4`"(QB``2-I@````P8@*^D`%BOH@!*^I`'ROJP"$
    +M`*(H(8QB`&B,HQDD)`3_`0`"$$``9!@D,$(`_@!B&"6LHQDD$`#_,P````",
    +MA06XC(,``#0"@`",I@`T`&(8(8QJ`.PD!/__C&D`\(QG`/A0P``0K*D`,#P(
    +MOJ8`YA`K`.H8(Q1```HU"')1C*(`+(RD`#``:1@C`&88(P!B&"$`9!@A`&@`
    +M&0``&!```R/"K*D`,*RG`#2LJ@`L`^``"`"`$"&,@P``-`*``#"E``<`8A@A
    +MK&4`6*R%&T@#X``(K(`;3(R"&_@`@&`A,,8W`(Q"````H&@A)8X;:(Q$``0D
    +M`A4`$,(`-0``&"$LPA4!$$``!P`#$$`D`A(`$,(`,20"%`!0P@`!)`,``@`#
    +M$$``1!`AE$4`EI1&`+241`"0E$@`G)1#`*Z41P"ZE$D`HI1*`,``!2F`E$L`
    +MQI1"`*@`A2`E``8Q@``(0P``9A@E``<[``"(("4`"4R```(6``!G&"4`"E2`
    +M`(D@)0!J&"4`"UX``((@)20"``$1H@`-`&LH)3FB``(`HB`*C8(``#0#@`"M
    +MS0`X`$,0(:Q$&6"-@@```$,0(:Q%&60#X``(`````!``__4`@"@A$`#_TR0#
    +M``(0`/_1)`,``2>]__"OOP``C*H!$``'/@`Q"`#_``<^`Q%(`!DDJ0"4K*@!
    +M$(R"!9@D0@`!K((%F"0"``&A(@`_C((;4!1```,D`@`"4,(`!($B`":/OP``
    +M`^``"">]`!`D`P`!`&@P"B1"``(`XA`J%$#_^`#`*"$,`#*<`````!``__6/
    +MOP``C((;4!1`__*/OP``D2,`/X$B`#\D9@`!``8>`"A"``,00/_K``,>`R0"
    +M``$D!0`"`$HH"B0"``,48O_EH28`/Q``_^L`````C(,;="0"%``P8S<`$&(`
    +M`P`````#X``(`*`0(1"F__T`````$*``!8R#```D`@&,K&(0(SB```D`P`_`$40(:Q#&?0#X``(`````#0#@```0Q`A$`#_TB0#``^,
    +MA```/`/\_S1C__^,@D`0-`6```!#$"2L@D`0C.0``"0#__V,@D`0`$,0)*R"
    +M0!",X@``)`,`#`!%$"&L0QGPC.(``"0#``$`11`AK$,!!(SD```D`\!_`(4@
    +M(8R"`!P`0Q`D-$(3@*R"`!R,X@``)`,`?P!%$"&L0QATC.(``"0#``X`11`A
    +MK$,8>(SB```D`P#_`$40(:Q#&?00P``&C.(``"0#`!\`11`AK$,8<`/@``@`
    +M````)`,`#Q``__L`11`A)[W_\*^R``BOL0`$K[\`#*^P``",@@``-`.```"`
    +MB"$`0Q`AC$(`S#!"``$00``'``"0(8^_``R/L@`(C[$`!(^P```#X``()[T`
    +M$(XC```T$(``)`0`/`!P&"&,8@#,-$(``:QB`,P,`&JB`````(XB````4!`A
    +MC$(`S#!"``$00``-)!``"0P`:J(D!``"CB(``#0#@``F$/__`$,0(8Q"`,PP
    +M0@`!$$```R0"__\6`O_U`````"92``$J0@`"5$#_XXXC```0`/_;C[\`##P+
    +M_]\\#=`^/`S0/CP*&2\\"1DK-`B``#0'@``U:___-:U&2#6,9X@U2K44-2FU
    +M%!"@`!0`@#`AC(,```!H&"&,8@#`-$(`@*QB`,",@P``/`0`(`!H&"&,8@`$
    +M`$00):QB``2,P@```$@0(:Q-(@B,P@```$@0(:Q*&7`#X``(K,`;4(R#```D
    +M!/]_`&<8(8QB`,``1!`DK&(`P(S#````9Q@AC&(`!`!+$"2L8@`$C,(```!'
    +M$"&L3"((C,(```!'$"&L21EP)`(``0/@``BLPAM0C((;^)2#&^HD!@`!`(`X
    +M(1!F``>,0@``5&``/(SB``",0@`$C$(`-%!``#B,X@``C.(``#0%@``D`P`/
    +M`$40(:Q#&'",X@``)`,`#93D'/H`11`AK$,8=(SB```D`P`,,(0`\`!%$"&L
    +M0QAXC.(``"0#``4LA``P`$40(:Q&&?",X@```$40(:Q#&?04@`````"`,"$0:0`'C$(``!1@`#D`````C$(`!(Q"`#000``U`````(S#``"4
    +MQ1SZC&)`$#"E`/`LI0`P`$@0)*QB0!",Q```)`/__8R"0!``0Q`DK()`$(S"
    +M```D`\!_`$<0(:Q)`02,Q````(<@(8R"`!P`0Q`D-$(/@*R"`!R,P@``)`,`
    +M#P!'$"&L0QAPC,(``"0#`'\`1Q`AK$,8=(S"```D`P`.`$<0(:Q#&'B,P@``
    +M)`,`#`!'$"&L0QGPC,(``"0#`/\`1Q`AK$,9]!2@``:,P@``)`,`%`!'$"&L
    +M0QGX`^``"``````D`P`8`$<0(:Q#&?@#X``(`````">]_^"OL@`8K[$`%*^P
    +M`!"OOP`<`("`(8R$&W0D`B0`,+$`_S"#-P`08@`'`,"0(8^_`!R/L@`8C[$`
    +M%(^P`!`#X``()[T`((X"'8P40/_YC[\`'`P`4Y(`````C@8=T#P#@`(D8QU<
    +M/`2``@!#$"$DA!UD`,0@(9!%``"0@P```!$00`!1$"$`Q2@'`&(8(3"B`/]P
    +M8E`"``,80`(`("$XR0`!)&@!*J.E```0P``#)&<`2B1G`)4!"3@+]`!`0`/_O)$(\
    +M\">]_^`LH@`%K[,`#*^P``"OOP`0K[(`"*^Q``0`@(`A$$``Q"03`!8\`X`"
    +M``40@"1C$YP`0Q`AC$(```!```@`````C(0``#0"@``\`P`$`((@(8R"``0`
    +M0Q`EK((`!!#```\``)@AC@4``"0#W_\\!/_\C*)`$#2$__\`0Q`DK*)`$(X%
    +M```\`P`"C*)`!`!$$"0`0Q`EK*)`!```F"$"8!`AC[\`$(^S``R/L@`(C[$`
    +M!(^P```#X``()[T`(%#``!H``)@AC(0``#P#__PT8___C()`!```B"$`0Q`D
    +MK()`!(X"```\`P`!C$)`$`!#$"100``-``"8(0P`:J(D!`#(C@4``#P#__PT
    +M8___C*)`!"8Q``$J)``4`$,0)*RB0`14@/_PC@(``!9@_]PT`H``C@,``#P$
    +M__L`8A@AC&(`!#2$__\`1!`DK&(`!!``_]0"8!`AC(0``#0"@``\`P`$`((@
    +M(8R"``0`0Q`EK((`!%#`_\H``)@AC@0``#P#__PT8___C()`$#1"(`"L@D`0
    +MC@0``(R"0`0`0Q`D/`,``0!#$"6L@D`$$`#_O```F"$0P/^[`F`0(8R'```D
    +M`O_])`4``8SC0`PD!@`!``"((0!B&"2LXT`,C@,``(QB0!`T0B``K&)`$`P`
    +M,RD`````C@0``#P#__PT8___C()`!`!#$"0\`P`!`$,0):R"0`2.`@``/!(`
    +M`8Q"0!``4A`D5$#_G@``F"$,`&JB)`0`"HX$```\`__\-&/__XR"0`0F,0`!
    +M*B4!D`!#$"0`4A`EK()`!(X#``",8D`,-$(``:QB0`Q4H/_KC@(``!``_XP"
    +M8!`A$,#_B20"__Z,A0``/`3__(RC0`PTA/__``"((0!B&"2LHT`,C@,``(QB
    +M0`0`1!`DK&)`!(X"```\`P`!C$)`$`!#$"100``1``"8(0P`:J(D!``*C@0`
    +M`#P#__PT8___C()`!"8Q``$J)0&0`$,0)*R"0`2.`P``C&)`##1"``*L8D`,
    +M5*#_[(X"``".!@``/`/__#1C__^,PD`$`@`@(0``*"$`0Q`DK,)`!`P`,RD`
    +M`#`A$`#_70)@$"$0`/]:)!,`$8R"``"L10`,`^``"`````",@P``)`(`!*QB
    +M``@D`@`!K((7Y`/@``@`````)[W_\*^R``BOL```K[\`#*^Q``2,@P``)`(`
    +M(`"`@"&L8@`(C((;N#!"`$`00``%)!(#Z(R"'"`D`R<0.$(`!0!BD`H20``-
    +M``"((8X"```D!``*)C$``8Q"``@P0@`$$$``#0``$"$,`&JB``````(R$"M4
    +M0/_VC@(``"0"`!:/OP`,C[(`"(^Q``2/L````^``"">]`!"N`!?D$`#_^8^_
    +M``PGO?_PK[```*^_``2,@A?$%$``#`"`@"&.!```-`*``(^_``0`@B`AC((`
    +M2(^P```D`__?`$,0)*R"`$@#X``()[T`$`P`,%\`````$`#_\XX$``",@P``
    +M-`*```!B&"&,8@!(-$(`(*QB`$@#X``(`````(R"```T`X```$,0(:Q%`$",
    +M@@```$,0(:Q&`$0#X``(`````"S"``4`@$@A$$``-`"@0"$\`X`"``80@"1C
    +M$_@`0Q`AC$(```!```@`````,*4`/S$"!``THP!`C(0```"B&`HT!H``,04(
    +M`#1B`(``11@+`(8@(:TH&T2L@P`\C2(;1(TC```D!P`@,$4`0`#@("$P0@"`
    +M`&88(1"@``,``B`*/`("`@""("4T@@`(`$4@"ZQD`0R-(AM$`.`@(3!#`$`P
    +M0@"`%&``#P`"(`I4@``.C2,``(TB```D!/_OC$,`-`!D&"2L0P`TC2(``"0$
    +M__>,0P`T`&08)*Q#`#0#X``(`````(TC``",8@`T-$(`$*QB`#00`/_UC2(`
    +M`(R$&T2-)@``-`>```"%("4P@@`_,(4$`#1#`$``11@*-&(`@`#',"$PA0@`
    +M`$48"XS"`#R,P@$,K20;1*S#`#R-(AM$C2,``"0&`"`P10!``,`@(3!"`(``
    +M9Q@A$*```P`"(`H\`@("`((@)32"``@`12`+K&0!#(TB&T00`/_(`,`@(8R%
    +M&T0`"!`GC(8```"B*"0PH@`_,*0$`#1#`$``1!@*-`>``#1B`(``QS`A,*0(
    +M``!$&`N,P@`\C,(!#!``_]ZM)1M$,*0`/S$"!`"-)0``-(,`0`""&`HT!H``
    +M,00(`#1B`(``1!@+`*8H(:RC`#R-(P````@0@C!%`"`Q!`!``&88(1"```,`
    +MH#`A/`("`@"B,"4TP@`(`$0P"ZQF`0Q4@/^QC2,``%"@_Z.-(@``$`#_K8TC
    +M``",A!M$C28``#0'@``P@P`_,(4$`#1B`$``91`*,(0(`#1#`(``9!`+`,

    ]__``11`KK[\`!*^P````@$`A%$``!P"@&"&\L0`` +M)*4`$`!G$"$`11`K$$#_^P`````DT``0D@(`!S!"``$00`!+)`0`#8S'`"`D +M!/_P).,`"#!B``\D0@`G`&08)`!$*"0`91`A`$,0*Q1```<`8"`AO'$``"1C +M`!``A1`A`$,0*Q!`__L`````).(`$)!"``]`!",0P`\ +M$&``.*S"`$R.`@````(3PC!"`!\`8A`AD$(`!*#"`$:2`@`'``(00C!"``%4 +M0``/C0(;4)("``<``A#",$(``1!``"``````D,(`1#1"``&@P@!$D@(``@`" +M$4(P0@`!%$#_X20$`!J-`AM0$$``"@````"0PP!*C0(;2%!#``:M`!M,C0(; +M3"1"``$L0P`#$&``!ZT"&TR2`@`")`0`'0`"$0(P0@`!$`#_SP`"(`J0Q0!* +M#``RG`$`("$0`/_V`````)("``<``A%",$(``1!`_^``````D,(`1!``_]PT +M0@`"$`#_S0``$"&L@``(K(``#*R``!"L@``4)(0`"(R"``0D`_``,*4/_P!# +M$"0`11`E`^``"*R"``2,@@``C$(`"#!"``0#X``(``(0*R>]_Z"OO@!0K[<` +M3*^V`$BOM0!$K[0`0*^Q`#2OL``PK[\`5*^S`#ROL@`XC(,;^)2B``0`H*`A +MC&4`&(QC``"OI@`()(8<'*^C`!@`@(@AKZ4`'#!0``,``/`A``"P(:^@`!0D +MEQMH``"H(:^F`"02@`"A)`/__R0%`!,,`!WA)`8`$(Z#``2.)!W0/`4(`#!C +M"````B@*``.`"Q"0``2OI0`@KC`=T`P`-0D"("`ACZ8`"!#```2.(@``C$(1 +M0*^B`!2.(@``-`.```(@("$`0Q`AC$,`6"00``&OHP`0C$,`!#P"`B``8A@D +M#``T7:^C``P,`$E,`B`@(0(@("$,`#K_`H`H(8^D`!``0!@A`@0@"A1``'BO +MI``0CB(;^*Q0`!2.@@`$,$,W`"0"%0`08@*2+&(5`1!``H``26(QSZCB0``#0"@``P8P#P`((@(2QC`#`D`@`'K((8 +M`!!@`A\`````CB(=T!1``A@`````DB4=S!2@`A$"("`ACH4`!`P`2CL"("`A +MEB<<^"SB`$(40``P,.3__XXD``"6A0``-`*``#P#``(`@B`A-&.@`B0"";2L +M@Q@L$*(!\8^C`!B,8@`$/`-F9C1C9F>40@`D`$,`&``"%\,``!@0``,80P!B +M("..@@`$)`,4`#!"-P`00P'2-`.``(XB````0Q`AK$`93(XD```T!H``)`+] +M_P"&("&,@R(H/`7__C2E`_\`8A@DK(,B*(XC````9A@AC&(B*`!%$"0T0@@` +MK&(B*(XB```D`P`/`$80(:Q#`&`PY/__+((`0Q1```8L@@!$CB(``#0#@``` +M0Q`AK$`B5"R"`$140``.CB(``(XE```D`X`?/`3__XRB$C`TA'__`$,0)#1" +M`>"LHA(PCB,``(QB`#``1!`DK&(`,(XB```T`X```B`@(0!#$"$D`P`.K$,8 +M>`*`*"$#H#`A)`<`/PP`080D"``!$$``#B0#__^/OP!4C[X`4(^W`$R/M@!( +MC[4`1(^T`$"/LP`\C[(`.(^Q`#2/L``P`&`0(0/@``@GO0!@CZ0`'(^F`!@# +MP#@AC((`!(S%``0"("`A`H`P(0!`^`D#H$`ACH(`!#!"!``40`%Z`B`@(8^B +M`!@"("`A`H`P(0P`0".,10`$CB4=U!"@``>/HP`(CH(`!#P#``0`0Q`D%$`! +M:0````"/HP`($&``!`````".(@``CZ0`%*Q$$4"*XP`^FN,`08KB`#Z:X@!! +MBN0`/IKD`$&*Y@`^FN8`03!C_P```QH`CB4````"%@``!"("`$,0)3"$_P"6 +MXP!"`$00)0`&-@(T!X```$80)0"G*"&LH@``CZ8`##!B`/^.)`````,:`@`" +M$@".Y0!,`$,0)0#"&"4D`@`"$*(!/@"'("&/I0`@/`(0@`!E&"6/I@`D`&(0 +M):R"``2(PP!"F,,`18C"`$*8P@!%B,0`0IC$`$4`P"@AB*8`0IBF`$4P8_\` +M``,:```"%@``!"("`$,0)3"$_P``1!`E``8V`HXE````1A`ECZ8`)#00@``` +ML"@AE,,`1JRB``B.)```,&(`_P`"$@```QH"`$,0)0"0("&L@@`,CB(``(^C +M`!``4!`AK$,`6(Z"``0D`Q0`,$(W`%!#`0N.)1T`CB,``"0"__^/I0`,A0``EB(<^C!"`/`L0@`P%$``$(XE +M``".)AW0$,``#0`````T`H``.,8``0"B*"&,HQ@D)`(`#"0$``T`1B`+)`+_ +M``!B&"0`9!@EK*,8)(XE```T`X```*,8(8QB`%BN(!M,,$(`_ZXB&TB,8B(( +M,$(@`%!```.N(!M0)`(``:XB&U`T`H```*(0(8Z#``2,0AD4,&,"`!!@`+TP +M1#__/`.Z+@`$$(`T8XNC`$,`&0``$!```A$"CB0=T#00@```L!@A`((@!"0" +M``&L8A@<#`!JHB2$`&2.(@``)`,X`"02``$`4!`AC%,8"*Q#&`B.(@```%`0 +M(8Q"'"0P0@`0%$``E0````".(@``-`:``);D`"``1A`AK%,8"(XC````9A@A +MC&(88#1"``&L8AA@CB,```!F&"&,8AA@-$(``JQB&&!0@`""CB(;^(Z"``0D +M`Q(`,$(W`!!#`'PD`@`"CB4;^(RC`"P08@!X)`,``8XD``"LHP`L`(8@(8R" +M&2`T0O``K((9((XC```\!``!`&88(8QB&2``1!`EK&(9(`P`/?,"("`A``"0 +M(8XD```D`P`!`D,8!``2$(`F4@`!`$00(2Y$``JL0Q``5(#_^(XD``".(P`` +M/`(`"#1""*"N(AM`K&(`H(XE```\`P`'/`8`@(RB`*P"("`A`$,0):RB`*R. +M(AM`CB,```!&$"6N(AM`C&(`H`!&$"6L8@"@CB4``#P#(`",H@"L`$,0):RB +M`*P,`"QY`````!1``#\```````"0(8XB```T$(``)`0`"@!0$"&,0AA@,$(` +M`1!```8F4@`!#`!JH@`````N0@!D5$#_]HXB```,`#/Y`B`@(8XC```T`H`` +M/`3^?P!B&"&,8@`@-(3__P!$$"2L8@`@CB(;N#!"`$`40``?`H`H(0(@("$, +M`#/$```H(98C'/0L8@`&4$``#HXB```D`@`%4&(`")8B'/:.(@``-`.```!# +M$"$D`P!2K$,!"!``_J<``!@A+$(`"!1`__B.(@``/`,``31C`*H`4!`AK$,! +M&(XB```D`S(0`%`0(:Q#`1P0`/_NCB(```P`.KD"("`A$`#_X`(@("$,`"R[ +M`B`@(1``_\```)`ACB(;^!``_Y.L0``L#`!JHB0$`,@N0@`4$$#_:"92``&. +M(@``-`.```!#$"&,0APD,$(`$!1`__4`````$`#_8(XB```\`LS,-$+,S0"" +M`!D``!`0$`#_10`"$,("("`A#``S&"RF``$0`/[SCB,``(^B`"``8A@E$`#^ +MPSP"$((,`$KL`B`@(1``_I:/HP`(#`!!.@*`*"$0`/Z%CZ(`&(^C`!B.)0`` +M``0@(XQB``0`!"2`/`,`_(!"`"(`@R`D-`.````"$",``A&`,$(/P`"C*"$` +M1!`EK*(93!``_B..)```CZ8`&#P"9F8T0F9GC,,`!(1D`":48P`D`&08(P!B +M`!@``Q_#```0$``"$$,`0Q`C``(4`!``_@L``B0##``THB0&``$0`/WNCH4` +M!`P`2L$"("`A$`#]YY(E'@(```)@A)!(`*#P#@`(D8QUH +M`!,0P`!#$"&,1````@,8(8XB``",90``)K4``0!$$"$RHP`_)E+__R80`!@F +M206``$0`/_] +M)!X``1``__(D'@`%`(`X(8R$```T!H``)`/__`"&("&,@@#``$,0)#1"``*L +M@@#`C.0``"0#_\,`AB`AC((`P`!#$"0T0@`8K((`P(SB``",HP`$`$8P(8S" +M`,@P8R``,$3__SP")Q`48``#`((0)3P"*O@`@A`EK,(`R(RB``0P1B``,$(( +M`!!``!TT"(``C.0``"0#P```B"`AC((`%`!#$"0T0Q$P-$(/H`!F$`JL@@`4 +MC.(``(RC``0`2#`AC,(`Q#!C(``P1/__/`(%>!1@``,`@A`E/`(&!`""$"6L +MP@#$C*(`!(SE```D!`2P,$(@`"0#!2@`8B`*K*00<`/@``@``!`A)[W_\*^_ +M```,`#QF)`4``H^_```#X``()[T`$">]_^"OM@`8K[4`%*^T`!"OLP`,K[(` +M"*^P``"OOP`HD`@+J`$.@"S"C!@`D`@8`$&(`53"C +M!``V0@`!`$.0"C"B(``V0P`",*0(`!"``$P`8I`*C@(;N#!"`$!00``$K@`= +MC"0"``$V4@`0K@(=C#"B`0`D%0`#``*H"@``L"$"`"`A#``\9B0%`!,00``, +M`$"((0(@$"&/OP`]__"OL0`$K[```*^_ +M``B,BQOX)`(``0"`@"&-8P`L`*"((1!B`$`DA!MHCB(`!"0#$@`P0C<`$$,` +M!"0"``*-8P`L4&(`(XX%```"`"`A#``]O@(@*"&.(@`$,$(``11``!8D`P`8 +MC@,``#0"@```8A@AC&(88#1"``*L8AA@CB4`!#"B(``40``)`````)8"'/HP +M0@#P+$(`,!1```<``!@A,*($`!!```6/OP`(#`!)/@(`("$``!@AC[\`"(^Q +M``2/L````&`0(0/@``@GO0`0-`:``)"$`%<`IB@AC*,9(#P"__\T0@__``0C +M``!B&"0PA/```&08):RC&2".!```)`(``:UB`"P`AB`AC(,9(#P"``$`8A@E +MK(,9(!``_\L"`"`AC@(``#0#@```0Q`AC$(9(#P#``$`0Q`D5$#_NXXB``2M +M8``L```@(8X#```T`H``)(0``0!B*"&,JAP0+(<`"HRF'!2,J!P8$4```P`` +M```4P``(``880HRB&2`\`P`!`$,0):RB&2!4X/_PC@,````&&$(`"A!"`$,0 +M(0`"&<(08/^H``8APBB"``)40/^F`@`@(0`($",`0P`:4&```0```]_^"OLP`,K[(`"*^Q``2OL```K[\`$(R#````@(@A)!/__XQB``@D +M$``&``"0(31"`""L8@`(C(,``(QB"(`T0@/_K&((@#("``000``),@(``HXB +M``",0@`(,$(`!!1```0R`@`")`+_^P("@"0R`@`"$$``"C("``&.(@``C$(( +M0#!"`_\40``%,@(``20"__T"`H`D-A```3("``$00``-```P(8XD`````"@A +MC((*`"2E``$LHP`*,$(``P#","$48/_Z)(0`!!3```(D`O_^`@*`)!(```XD +M!``R#`!JHB92``$N0@`*%$#_US("``0"8!`AC[\`$(^S``R/L@`(C[$`!(^P +M```#X``()[T`(!``__<``)@A)[W_X*^S``PPH@`1)!/__Z^Q``2OL```K[\` +M$*^R``@`H(`A`("((1!``"<`I9@+```H(0P`-3@D!@`!$$``"0!`&"&/OP`0 +MC[,`#(^R``B/L0`$C[````!@$"$#X``()[T`((XB```"("`AK$``)(XB``", +M0@`D#``\'P`````00`!*)`+_[PP`:J(D!``/CB(``"0$``$V$``3C$(`#`P` +M;!\`````#`!K-@`````,`&L.``````P`:J(D!``*#`!L'P``("$,`&JB)`0` +M#XXB```D!``/,G,``XQ#``RL4$``#`!JHC(0``,``)`ACB(``"92``$"("`A +MC$)`````*"$`4Q`D$%``$B0&``$2```(``````P`:J(D!``R+D(G$%1`__.. +M(@``$`#_Q20#`!8,`#4X`````!1`__8`````CB(``*Q`0``0`/_R``````P` +M-3@`````5$``!(XB&_B.(@``C$(`P(XB&_B,0P!<)`(``U!B``..)```$`#_ +ML```&"$\`__Q-&/__XR"0!``0Q`D/`,`"`!#$"6L@D`0$`#_IP``&"$D!``/ +M#`!JH@("@"2.(@``C$(`#!``_\$`````)[W_X*^T`!"OLP`,K[(`"*^P``"O +MOP`4K[$`!)2F```\`\S,-&/,S3#0__\"`P`9C*4`!`"`D"$``*`A,*0@```` +MF"$``!@0``,8@@`#$(``0Q`A`@(0(S!"__\X0@`"$(``RBQ'``&.0AOXE$0` +M>#"B(``00`##CD(;^)1#`'HPQ?__`*00*Q1``#HD`@`.`&40*Q1``#]`"".0@``-`.```!#$"&,0R($-&,`$*Q# +M(@00`/_A`!,8@`"%`!@`!!?#```8$``#&$,`8A@C``,0@`!#$"%4@O_H)`(` +M#@`0$$`D0NZ@`$4`&"04``$``!@0$`#_OP`"%\,0X``$/`/,S"X"%3P40`!, +M)@+__C1CS,T"`P`9```8$``#&0(``Q"``$,0(0`"$(`"`A`C,$+__Q1```0\ +M`LS,+@(4`!!``#`\`LS,-$+,S0("`!D``"`0``08P@`#$(``0Q`A``(00`(" +M$",P0O__$$``%P`$&((``Q"``$,0(0("$",P0O__%$#_O20"``X\!&9F)@+M +M0#2$9F<`1``8``(7PR0%``@``"`0``0@0PP`6?X`@B`C`$"((20$``$,`%G^ +M)`4``A``_YP`0)@A/`1F9B8"[4`TA&9G`$0`&``"%\,D!0`(```@$``$((,` +M@B`C#`!9_@`$($``0(@A$`#_[R0$``(\!&9F)@+M0#2$9F<`1``8``(7PR0% +M``@``"`0``0@PP""(",,`%G^``0@@`!`B"$0`/_A)`0``S!0__\`$!"``%`0 +M(3P#__\T8T2```(00#P$4>L`0Q`A-(2%'P!$`!@``A?#)`4`"```(!``!"## +M`((@(PP`6?XDA``!`$"((1``_\T``"`A$`#_/I1#`'Z.0AOX$`#_-Y1$`'R, +MIP`$)`(5````,"$PXS<`$&(`)0``0"$L8A4!$$``)B0")``D`A(`$&(`(20" +M%`!08@`!)`8``HR#```T`H```&(8(8QB&&`P0@`"%$``%`````",A!OXC&(8 +M9``&&$",A`````(4PC!&`?^,@@`$,,0!``!B&"$0@``#A&,`C(,`````,"$0`/_:)`@``8R"&[B,@P```(`H(0`" +M$((P0@`!K&($((R"&[@P0@`$4$``"8RB&\"4@QST+&(`!E!``"2,HP``)`(` +M!5!B`!V4@ASVC*(;P(RC```\!``0``(2`C!"``>L8@8`C*,``#2$`@$``#@A +MC&(&`"2F'04T0@`(K&(&`(RB``"L1`8$C*(``*Q`!B",H@``K$<$`)#$``", +MH@``).<``2SC`("L1`0$%&#_^"3&``$#X``(`````"Q"``A40/_CC*(;P(RC +M``",8@0@-$(`0*QB!"`0`/_=C*(;P">]_\"OO@`PK[<`+*^V`"BOM0`DK[0` +M(*^R`!BOOP`TK[,`'*^Q`!2OL``0C,(`!(R#&_@PY___,$HW`"0"%0``H$@A +M`,"0(0"`J"$!`/`AKZ<``(QQ``0``*`A``"P(0``N"&OH``(KZ``#```*"$1 +M0@$VC',`("U"%0$00`$_)`(D`"0"$@`10@$V)`(4`%%"`2^5(@#VCZ(``#P$ +M@`(\`X`"``(P@``%*$`DA"TX)&,M4`"I*"$`Q"`A`,,8(3P"@`*,A```C&,` +M`)2G`-*,0BTTE*4`A*YD``2N8P`(KZ<`!*YB```F8P`,)`0`)SP"@`(D0BUH +M`,(0(8Q"```DA/__),8`&*QB```$@?_X)&,`!"9P``P"`"`A)`8``20'`2X, +M`#^F``!`(9?%```"`"`A)`8``B0'`0X,`#^F``!`(9?%``("`"`A)`8``B0' +M`0$,`#^F``!`(8Y"``0P0@0`5$``SHXB`!R.0@`$,$(0`!!``,`"P"@ACZ4` +M"`(`("$D!@`#)`]_^"OL@`(K[````"`D"$`X(`A`*`@(0#`*"&O +MLP`,K[$`!`$`F"$F$/__K[\`$`P`6?X`P(@A`$!`(3('``<:(``>`!`0P@`" +M$(``4H`A`/$@(20&``@H@@`)`,(@"B0"``$`XA@$`((0!"1C__\D0O__C@4` +M``!#$"8`$QC``&(0!`#H(`0`9"`$``(8)P""("0`HR@D`B<0(0#',",`I"@E +M)%'_^*X%````R$`&```X(1X@_^8F$``$C[\`$(^S``R/L@`(C[$`!(^P```# +MX``()[T`("3&__\GO?_PK[\```"@4"$PR``'``!@(0`&$,(`H$@A&*``'``` +M6"$``A"``$0P(0$)*"$HHP`))`(`"`!#*`HD`@`!`0(@!`"B$`0DA/__C,,` +M`"1"__\`1!`F``<@P`""$`0`8A@D`(,8!@$H$"$!`Q@&`6,8!`"H*",D2?_X +M`8-@)0%E6"$``$`A'2#_Z"3&``0!@"`A#`!9_@%`*"&/OP```^``"">]`!`G +MO?_P)`0`X*^_``2OL```#`![N@"@@"&N`@`@C[\`!(^P`````A@K`&`0(0/@ +M``@GO0`0)[W_\*^P``"OOP`$C*(`(`"@@"$40``%`$`@(8^_``2/L````^`` +M"">]`!`,`'O-`````!``__FN```@)[W_T*^W`!ROM@`8K[0`$*^S``ROL@`( +MK[$`!*^_`"2OO@`@K[4`%*^P``",@QOXC,(`!`"`B"&,9````,"X(0`"&P(P +M1C<```(2`C!4``$D`A4``*"0(92>```P"/OP`DC[X`((^W`!R/M@`8C[4`%(^T +M`!"/LP`,C[(`"(^Q``2/L````^``"">]`#`T`X```$,0(:Q`&>`0`/_QC[\` +M)!5`_^0KPE`!$`#_UHXF```0`/\4)!8``A``_Q(D%@`!$,(``R0")0!4PO\/ +MCB4``!``_PP``+`AC*8`!(R''=``@$@A,,8!`)2D```\`F0`/`/(``!F$`L` +MXA`&`$0`&U"```$```'-)`@`'P``4!(!"A`&,$(``51```6-)@``)0C__U4` +M__L!"A`&C28``"0"`"8`2$`C-`>``"0#`!<`QS`A`&@8(R0"``&,Q1@4`&(0 +M!"0#`!@`:!@C`4(0(3P$``$`8A`&-(3__P"D*"0``A1``*(H):S%&!2-)@`` +M)0/_\#P%__X`QS`AC,(8%#P$``$``QM`-*4?_S2$X```11`D`&08)`!#$"6L +MPA@4`^``"``````\`H`")[W_P"1"%10#H!@A)$0`0(Q%``",1@`$C$<`"(Q( +M``RL90``K&8`!*QG``BL:``,)$(`$!1$__8D8P`0`^``"">]`$`GO?\0K[X` +MX">^`!``!SP`K[<`W*^V`-BOL@#(K[$`Q`"@D"$`@(@A```H(0/`("$`P+@A +M)[8`D"0&`("OJ`"TK[\`Y*^T`-"OL`#`K[4`U``'A`,,`'(-K[,`S`+`("$` +M`"@A#`!R#20&`"".0@`$CB,;^```0"$P0B``C'0``!!``/ROH`"XAB(;Q)8C +M&\0"`"`A`%`0*E1```$`8"`A``04```"A`,J`@!`%$```@(`."$D!P`_``<4 +M```"A`,J`@`_4$``!)8C&\@6```()[4`LI8C&\@\`H`")$(R;``#&$``8A@A +MA&@``">U`+*OM0``CH8`#">S`+`"`$@A`B`@(0+`*"$"0#@A`H!0(0P`1=(" +M8%@A/`*``HQ"4YQ80``$CB(;^`P`07("P"`ACB(;^`)@,"$"H#@AC$(`&`+@ +M2"$"("`AC$(`"">E`!``0/@)`D!`(98C'/J7H@"N,&,`\"1"``0L8P`P%&`` +MOZ>B`*Z7HP"R)`(`/P/`("$`0Q`C,$7__P``,"&4@P"`),8``2C'`!``HQ@A +M,&+__RQ"`$`40``#I(,`@"0"`#^D@@"`%.#_]22$``*.(AOXC$,``*1%`"2, +M8@`$E$(`*"Q"``(00``G/`*``I8B'/@L0@!"$$``!X^B`+2.0@`$)`,4`#!" +M-P!00P!\ED,``(^B`+040``%-`6A@(^B`+@00``8/`*``C0%H8```#`A``80 +M@">C`!``0Q`AE$,``)1"``*.)`````,:```"$@`T0@#_-&,`_P`"%``P8___ +M),8``0!#."4`A2`A)*(`!"C#`""LAP``%&#_[3!%__\\`H`"C$)3G"A"``(0 +M0`!7`````)>C`):7I`"4EZ(`DC!C`#\PA``_``0D```#'@`P0@`_`&08)0`" +M$@``8A@EEZ(`D)>D`)R.)0``,$(`/P!B."67HP">EZ(`FC"$`#\P8P`_``0D +M```#'@`P0@`_`&08)0`"$@``8A@EEZ(`F#0&@```IB@A,$(`/ZRG&327I`"B +M`&(X)9>C`*27H@"N,(0`/S!C`#\`!"0```,>`#!"`#\`9!@E``(2`(XE```` +M8A@EEZ(`H`"F*"&LIQDX,$(`/P!B."67I`"JEZ,`K)>B`*B.)0``,&,`/S"$ +M`#\`!"0```,>`#!"`#\`IB@A`&08)0`"$@"LIR(T`&(8)9>B`*:.)0``C[\` +MY#!"`#\`8C@E`*8H(:RG(CB.(P``C[X`X(^W`-R/M@#8C[4`U(^T`-"/LP#, +MC[(`R(^Q`,2/L`#````0(0!F&"$D!``_K&09/`/@``@GO0#P#`!!D`)`0 +M`/^HEZ,`EB0"";008@`0/`-F9HZ"``0T8V9GE$(`)`!#`!@``A?#```8$``# +M&$,`8C@C`L`H(0(@("$,`$]_^`` +M!SP`)(4;<``'/`,#H#`AK[\`$`P`080``$`AC[\`$`/@``@GO0`@,(3__S"E +M__\PQO__``<\```(1```Q$@C`(50(P#%&",`!Q0#$,4`#``()`,!(@`84&`` +M`0```]_]"OMP`<,)?__P`'/``NX@`" +MK[8`&*^U`!2OM``0K[,`#*^R``BOL0`$K[\`(*^P````H(@A`,"P(0$`J"$` +M!Z0#``"8(202``$40``T```8(0``@"$`$A!``%$0(91"````4!`K$$``"@`3 +M$$`FXO__`D(0*A!```8`$Q!`)F(``29#``$P4___,'+__P`3$$``$AA``%8@ +M(0!V0"$`41`A`'$8(91F``"$AP``E$4``(4(```,`$*T`@`@(0`")```!"0# +M`!`80`!U&"$`E"`J%(``#*1B```N`@!`$$``"B8"``$"`!`A)@,``3!P__\` +M`A!``%40(2X#`$`48/_YI%0``"8"``$P4/__+@(`0!1`_]$`$A!`)`,``8^_ +M`""/MP`]^]"OO@0@K[\$)*^W!!ROM@08K[4$%*^T +M!!"OLP0,K[($"*^Q!`2OL`0`C0(`!(R#&_BOI`/(,$0W`"0"%0"OJ`/8KZ4# +MS*^F`]"OIP/4`2#P(8QC```0@@'&KZ`#W"R"%0$00`'()`(D`"0"$@`0@@'# +M)`(4`%""`;\D8P`LCZ0#U(^E`]"/I@/B`[@` +M`QQ```0D0)3%``8`!"0#``,<`Z^D`^"OHP/D``"H(0``B"$GI`.X`B40!S!" +M``$80``%+J,``A!@`.$FM0`!I)$``"2$``(F,0`!+B(`!!1`__8")1`'CZ@# +MW(^G`]B5!@`$A.0``(T%```GIP/`#`!"S">H`\2/M@/`CZ(#Q`!6$"L40`"` +M`!80@`!6$"$``A"``%80(0`"$("OH@/LKZ`#\(^C`]R/I`/LC&(`")>C`[H` +M1*@A-`+>K1!B`4*7L0.X)[(A0`(F(4`"XB&``R8 +MA@`/J&<``+AG``.H:``$N&@`!ZAE``BX90`+J&8`#+AF``\DA``0%(+_[B1C +M`!"7L0.Z`N`@(0`1@(`"$8`A`!"`@`(5@"&6%``&)@4`""80`!``%(A`#`!R +M``(@,"$"`"@A`B`P(0P`<@`"8"`AAJ<``@*`("$"X"@A`F`P(0P`0O0"0$`A +M$$``D`[@`@!`AB00``)D$``.) +M!0`$F04`!XD&``B9!@`+B0<`#)D'``^H9```N&0``ZAE``2X90`'J&8`"+AF +M``NH9P`,N&<`#R4(`!`5`O_N)&,`$(^H`_"/HP/LCZ(#Q";6``$E"`"`)&,` +M5`!6$"NOJ`/P$$#_B*^C`^R/IP/G`[H`1!`A +M``480`!D&"&45```-`+>K0"FJ",0X@"!E',`````B"$#H)`A`!6!@(^H`]@" +M$8`A`!"`0`(=@"&&1P$XE00``(8(`3@"@"@A#`!"M`)@,"&/HP/8AD<".(8( +M`CB49````H`H(:9"``@"8#`A#`!"M"8Q``$N(P!`ID(`B!1@_^DF4@`")`(` +M`A1``$6'HP$&CZ<#X`!G$"H40``$CZ@#Y`!H$"H00``ICZ4#S(^E`\P,`$-( +M)Z0`"`!`2"$``A_"EZ(`AI>E`[B/I@/0``(4```")\*/IP/4``(4`P$C&"$` +M1!`A``(00P`#&$.GQ0`"IZ(``*?%``"DPP``I.(``(^H`]2/HP/(E0(``(QD +M&_@D`P`_`&(8(Z2#`"2/OP0DC[X$((^W!!R/M@08C[4$%(^T!!"/LP0,C[($ +M"(^Q!`2/L`0``^``"">]!#`,`$-()Z0`B`!`2"$``A_"EZ(!!I>E`[H!(Q@A +M``(4```")\(``A0#`$00(0`"$$.GQ0`"CZ0#T*>B``"GQ0``CZ4#U``#&$.D +M@P``$`#_V:2B``"/I@/,)Z0`"">E`(@,`$.4)Z<``@!`2"&7HP`"``(GPI>B +M`(8``QP```,OP@`"%````C?"``,<`P`"%`.7J`.XEZ<#N@!E&"$`1A`ACZ4# +MT(^F`]0!)"`A``0@0P`#&$,``A!#I*0``*>C``"DP@``I\<``A``_[JGR``` +M``"((0.@@"$`%1&``%$0(0`"$$``71`AA$@!.(^B`]B&!P$X`H`H(91$```" +M8#`A#`!"M"8Q``$N(P!`I@(`"!1@__$F$``"CZ4#S`P`0T@GI``(`$!((0`" +M'\*7H@"&EZ4#N(^F`]0``A0```(GP@`"%`,`1!`ACZ0#T`$C&"$``A!#``,8 +M0Z2#``"GH@``I,(``*?%``(0`/^2I\4``(T"``"-!0`$C08`"(T'``RL8@`` +MK&4`!*QF``BL9P`,)0@`$!4$__8D8P`0$`#_-8^H`_",AP``C(@`!(R"``B, +MA@`,K&<``*QH``2L8@`(K&8`#"2$`!`4A?_V)&,`$!``_O:7L0.Z)[,!"`)@ +M("$`$8"``A&`(0`0@(`"%8`AEA0`!B8%``@GL@$@`!2(0`(@,"$,`'(`)A`` +M$`(`*"$"(#`A#`!R``)`("&&IP`")[`#.`*`("$"8"@A`D`P(0P`0O0"`$`A +M$$#_98^E`_`"`$`A`+T0(21#`3@P8@`#$$``%R>D`[@`@!`AB08``)D&``.) +M!P`$F0<`!XD$``B9!``+B04`#)D%``^H9@``N&8``ZAG``2X9P`'J&0`"+AD +M``NH90`,N&4`#R4(`!`5`O_N)&,`$!``_O*/J`/PC08``(T'``2-`@`(C04` +M#*QF``"L9P`$K&(`"*QE``PE"``0%03_]B1C`!`0`/[ECZ@#\"1C`"P0`/Y! +MKZ,#W!``__TD8P`@$((``R0")0`4@OX\CZ0#U!``__B +M``:4H@`*`2(8*@$C$`L``A0```),`Y>B``:/IP`@`2(8*@$C$`L``A0```(4 +M`P`'($``1"`C``0D```$3`.OH@`T!2``L`$@$"&/HP`D``(4```"3`,!(Q`J +M5$```0$@&"&6I!O*``,4`!"```,``DP#``040``"3`.7H@`$EZ,``I>D```! +M(B@J`2,P*@$D."H!)1`+`288"P$G(`NF`@`*I@,`#*8$``ZF"0`(I@D`!J8) +M``2F"0`"I@D``)9"```L0D``5$``#*8)`!XSPQ``$&``BHY"``240@`.`2(0 +M*E1```0!(!`A$&``@HY"``240@`.I@(`'I8"``Z/IP`HCJ0;^*3B``"6`P`` +M``,4```"%`.NH@6]`'"6YP!R`J`@(2;F`'0"@"@A#`!' +MYR>H`!"/I``PCZ<`+`"3&",`XQ`J`.(8"Y>B`!8``QP```-,`P$B&"H`0%`A +M`2,0"X^C`#0`8A`J$$``"(^G`"`!*A`J`2`@(0%"(`H`!!0```(4`Z^B`#2/ +MIP`@`2H0*@%"2`H`!Q!``2(0(P`"%````DP#!2``.`$@$"&/HP`D``(4```" +M3`,!(Q`J$$```@!@,"$!(#`AEZ4`$)>C`!27I``2``84```"3`,!)1`J`2(H +M"P$J,"H!(S@J`21`*@$@$"$!1A`*`2<8"P$H(`NF`@`0I@,`%*8$`!BF!0`< +MI@,`$J8$`!:F!0`:EJ(;RA!```R/I``H``(00*8"`!"F`@`6I@(`%*8"`!*6 +MHAO*``(00*8"`!BF`@`40@`,$`#_4```$"$0`/\A)N8``C)C`/@TOI``LCD4`$):$```,`$>I`*8H(0!`,"$`0"`A +M`L(H*S)C`/@D`@#@5&+^VP#`L"%4H``!`L`@(1``_M`PEO__C((;^`"@8"$G +MO?_@C$(``"0%``B,0@`$@$X`(HF"``"9@@`#B8,`!)F#``>)A``(F80`"XF( +M``R9B``/JZ(``+NB``.KHP`$NZ,`!ZND``B[I``+JZ@`#+NH``^)@@`0F8(` +M$XF#`!29@P`7B80`&)F$`!N)B``KI``8 +MNZ0`&ZNH`!R[J``?``580`%]&"&48@````!((0``:"$`3A`CI&(```%]0"&% +M`@``!$(``:4````D`@`($2(`.0`)$$``3!`AE$,``(4*```E(@`!,$G__Q%# +M`">5!```+2(`$%1`__$!?4`A`7T@(82"```H0@!`%$``!`%L$"$D`@`_I((` +M``%L$"&40@``A(0``"2E``$`1Q`C*$,````#$`L``A!``$80(91#````!"!` +M,*7__P"&("$LH@`/%$#_TJ2#```D!0`(``480`!]$"&41```)*(``3!%__\` +M;!@A+*(`#Q1`__BD9````^``"">]`"`10``%)((``2VB`#,40``")(+__R2" +M``&E`@``):(``3!-__\0`/_0``!((1``_\XD"0`/)[W_P*^S`"ROL@`HK[$` +M)#"2__^OOP`PK[``(`"@B"$D$P`_```@(0`$$,``41`AE$,````$$$`DA@`! +M$&``!0!=*"$PQ/__+((`"!1`__:DHP```("`(2>G`!`"0"`A)Z@`$@.@*"$, +M`$B(`@`P(1(```L``"`AEZ4`$``$$$``71`AE$(``!!%``4D@P`!,&3__P"0 +M$"L40/_Y``000)>C`!"7H@`2$&(`#P`$$,``41`AC$(`!!!```,`!!#``%$0 +M(913``("8!`AC[\`,(^S`"R/L@`HC[$`)(^P`"`#X``()[T`0!1R__$````` +M$`#_]`!1$"$GO?_`K[``(##P__^OM@`XK[4`-*^T`#"OLP`LK[(`*`"@F"&O +MOP`\K[$`)`#`D"$!`*@A``"@(0``L"$2```-```H(0`%$(``11`A``(00`!2 +M$"&41``()*,``0`%$$`P9?__`%T0(0"P&"L48/_UI$0``)9D```#H"@A)Z<` +M$">H`!(,`$B(`@`P(1(```X``"@AEZ<`$)>F`!(`!1!``%T0(91#```DI``! +M`&<0)A!F`#<`HJ`*,(7__P"P$"L40/_W``400``4@(``%HB``A2`(0(VB"$` +M$(!``!&(0`(RB"$"$H`AE@<`!I8H``:69```EZ4`$)>F`!(,`$A-``!((::B +M``:6!P`$EB@`!)9D``"7I0`0EZ8`$@P`2$T``$@AIJ(`!)8'``*6*``"EF0` +M`)>E`!"7I@`2#`!(30``2"&FH@`"E@<``)8H``"69```EZ4`$)>F`!(,`$A- +M``!((::B``"/OP`\C[8`.(^U`#2/M``PC[,`+(^R`"B/L0`DC[``(`/@``@G +MO0!`$`#_S0"@L"$PY___,0C__W#H$`(PBO__,*7__S#&__\D!`!D$$``'@`` +M&"$D`@`!$,4`*0!)(`L!11@C``,00`!#$"$``A#``$,0(0`"$(``Q1@C`$,` +M&E!@``$```'-```0$@`"%````AP#!&``&BAB`&540``,)`(`9%$@``)2"'/HDR``(,$(`\"Q"`#`40``/)&<`"(S$``0D`@!5K*(` +M$"0"``&LH@`8``00P`!$$"$``A"`)`,`%`!($"&LHP`,K*(`'`/@``BLI``` +MC&0`!"0"`".LH@`0)`(``:RB`!@`!!#``$00(0`"$(`D`P`4K*,`#!``__(` +M1Q`A)[W_\*^P``"OOP`$E((<^@"@@"$P0@#P+$(`,!1``"$D!0`'#`!*]P`` +M````0"`A)`8`)```."$,`#_<)`4``20#``$D!P!K```P(1!#`!`D!`!KC@4` +M!```0"$`Y1`K$$``!@"F&"L48``#`(4H*Q"@``./OP`$)`@``8^_``2/L``` +M`0`0(0/@``@GO0`0)`(`-R0'`%,D!`!3$`#_[:X"`!`,`$KW``````!`("$D +M!@`E```X(0P`/]PD!0`&.$0`/R0&`$``!#`*),,`-R3%`",`9"@+)`,`%``$ +M&`LD0@`$)`<`,@!$.`NN`P`,K@4`$!``_]:4``%$,``11`AC,0`!(S(`!```A"``.(0(21"``@`B!@K%&``'JS" +M`!P0H``:)`/__ZS$``B,PP``/`*``XQ$FE`D9___``<8P(S"`!P`9Q@A``,8 +M@`!D&"&LQP``C$4`$(QB`!B,Q``()&,`"`!%$",``A!``((@(P"($"NLPP`< +M%$```ZS$``A4X/_KC,,``"0#``$#X``(`&`0(8S)``P!)!`K%$#_^P``&"&, +MX@``)$+__Q"B__">]__"OL0`$K*``%`"@B"$D +M!0`'K[\`#*^R``BOL```#`!*]P"`@"$`0"`A)`4``20&`"0,`#_<```X(0!` +MD"$D`@`!4D(`!XXB`!R/OP`,C[(`"(^Q``2/L````^``"">]`!`"`"`A)`4` +M!PP`2O>$4````$`@(20%``0D!@`@#``_W```."$2$@`.`$`8(5(`_^ZN(``4 +M)`(``A("``<``Q!`)`(``Q8"_^F/OP`,``,00!``_^6N(@`4$`#__21"__L0 +M`/_AKB(`%">]_^"OM0`4,+4!`*^S``ROOP`8K[0`$*^R``BOL0`$K[```!*@ +M`'H`@)@AC)`<"(X"```80``B``"@(281`#"2)@`'DF0=S)(J``0`!A#``$80 +M(P`"$(``4!`AC$,`+#P"@`(D0E.@``,8@`!B&"&,8@``EF@=T@`$2$`T`X<` +M`21((0`*4(`"`"`A)`4`#@``."$`0/@)`4.0(0!`,"&.`P``CF(``":4``$" +M@Q@J`%(0(:Q&```48/_A)C$`'!:@``J/OP`8CG`<$(X"```80``&``"@(8X# +M`"PD`@`"$&(`"B81`#"/OP`8C[4`%(^T`!"/LP`,C[(`"(^Q``2/L````^`` +M"">]`""2)@`'DF0=S)(J``0`!A#``$80(P`"$(``4!`AC$,`+#P"@`(D55.@ +M``,8@`!U&"&,8@``EF@=T@`$2$`T`X<``21((0`*4(`"`"`A)`4`#@``."$` +M0/@)`4.0(0!`,"&.8@```@`@(20%``X`4A`AK$8``)(C``4D!P`!)I0``0`# +M$(`48``+`D*0(8X"```"@A`J$$#_T28Q`!R.(__\)`(``E!B_]>2)@`'$`#_ +MS(^_`!B2)@`'DF,=S)9H'=(`!A#``$80(P`"$(``4!`AC$(`+``#2$```A"` +M`%40(8Q"````0/@)`2-((0!`,"&.8@```%(0(:Q&```0`/_DC@(``!``_X>, +MD!P8C(<``#0"@`",B1W0`.(X(8SF`!PY*``!)`,`"20"`!,PQC^``&@0"SP% +M`!L\`P`V`&@H"P!&$"4`11`E/`,?@`!#$"6LX@`]`!`,`"E6/`6``!``__@``!`A$&#_[R1"__\0`/_Y +M`B`@(8S"`!2,QP`0)`,``0!#$`0`@$@A`,!`(0#C&`2,Q@`,)$+__SP$``\T +MA/P`)&/__P`"$H``1!`DC2<``#!C`_\`8A@E``8U`#P"#_``PC`D``4H@`!F +M&"4`Y3@AK.,00(TD``"-`P`@/`(`#S1"__\`8C@D$&```P"%("$\`@`0`.(X +M)8T"``2LAQ#`,$8`(#!"``000``&/`0`((TB````11`AC$,1``!D&"6L0Q$` +M$,``!@````"-(P```&48(8QB$0`T0@(`K&(1``/@``@`````)[W_\*^_``2O +ML```C(@;^(RP``B,HP`$C0<`""0"``$"`D@$`.DX)3!J``(P8P`!`*`P(:T' +M``@08``$`@`H(8T"``P`21`EK0(`#!%```0`````C0(`$`!)$"6M`@`0#`!/ +MH``````"`!`AC[\`!(^P```#X``()[T`$(R$&_@D`@`!`*(0!(R&``B,AP`, +MC(,`$``"$"<`PC`D`&(8)`#B."2L@P`0K(8`"`/@``BLAP`,C((````%*(`D +MI0@``$40(:Q&```#X``(`````(R#```D`@`!`*(0!*QB"$`#X``(`````(R" +M&_B,0P`()`(``0"B,`0`9A@D``4H@"2E"@`08``*```0(8R$````A1`AC$(` +M`#!"``,40``$`````(R""$``1A`D``(0*P/@``@`````)[W_\``&$$"OL@`( +MK[$`!*^P``"OOP`,`$80(0"`B"$``A#`C(0```!&$"$D`P`!`*,8!`"@D"$` +M`H"`K(,(@`(@("$,`$NL`D`H(280__\00``')`0`"@8"``:.(@``#`!JH@`` +M```0`/_V`B`@(8XB``"/OP`,C[(`"(^Q``2/L```K$`(@`/@``@GO0`0$*`` +M%0"@."&0H@`.``(1`C!"``$00``1C.(`"#P#W_\`!B`K-&/__P!#$"0`!"=` +M`$00):SB``B,YP`@4.``!XSB``B0X@`.``(1`C!"``%40/_RC.(`"(SB``@\ +M`]__``8@*S1C__\`0Q`D``0O0#P#_W\`11`E-&/__P!#$"0`!"7``$00)0/@ +M``BLX@`(``@0P`!($",GO?_```(0@*^^`#"OMP`LK[4`)*^T`""OLP`] +M`$`,`"F&/`6``!)@`!HD`__P)G0`"#*"``\D0@`G`$,H)`*#&"0`91`A`$,0 +M*Q1```<`8"`AO'$``"1C`!``A1`A`$,0*Q!`__L``````@`@(0)@*"$,`$^< +M)`8``:^B``B.@@``CH,`"``"C8(P=7__,C$``0(`("$,`"E6/`6``(Y#```\ +M`H!`CD4`#`!B&"2.1``(CZ(`"``%+0(PEG__``,8*Q1```LPI0`?4&``"@/` +M*"%6(`!*C\(`3(^C``0"MA`A`%<0(P!B$"L00``0`M<0(P/`*"$"`"`A#`!+ +MY"0&``&/HP`,$&#_N(^B``!00/^WCZ(`#(Q%`#`"`"`A#`!+Y```,"$0`/^Q +MCZ(`#`(`("$\!8``#``IA@*BJ"$28``<)F4`"#"B``^.A``()`/_\"1"`"<` +MHR@D`$,P)"0"@```@B`D,J-__P"F$"$`@R`E`$40*ZZ$``@40``'`*`8(;RQ +M```DI0`0`&80(0!%$"L00/_[``````)@*"$"`"`A#`!/G"0&``$L0@`!KZ(` +M#`(`("$,`"E6/`6``(^B``P00/_,`\`H(8Y$``".10`(/`+_OS1"__\\`W__ +M`((@)#1C__\D`H```(,@)`"B*"2N10`($`#_OJY$``"2`QW,E@@=THQ$`#P` +M`TA``2-((0"%$"&01@`$)`4`#@`&$,``1A`C``(0@`!$$"&,0P`L/`*``B1" +M4Z```QB``&(8(8QB````0/@))`<``1``_Z(`0+@A)[W_P*^T`""OL@`8K[$` +M%*^P`!"OOP`TK[X`,*^W`"ROM@`HK[4`)*^S`!R,@ALT`("0(8R^`"@`H(`A +M`,"@(22Q``B,LP!0C*0`3!1``!&OH```4F``!9/#``".8@`$%$``#`````"3 +MPP``,&(`#!1```N(@`,D\(`%HXC```\!/[_ +M,$(`#RQ"``$TA/__`&08)``"%@``8A@E$`#^SZXC```D`@!`$&+^L20#``,2 +M8/ZO)`)__X9C`1108OZL)`,``U3@_JHD`P`#CB(``#!"#_\H0@$!%$#^I20# +M``*.`@!8C$(`)"Q"``)00/ZACB0`!!``_IZ.0QO4,$(`0!!`_FPD`G__%H+^ +M:@````"60AOTK@(`.!``_F4`0*`A#`!3DHY$&W0``A"``%(0(1``_BN,51P$ +M)[W_T*^R``@`H)`A)*4`"#"B``^OM0`4K[,`#*^Q``2OL```K[\`(*^W`!RO +MM@`8K[0`$"0#__`D0@`GCE0`,`"C*"0`0S`D`*80(0!%$"L`@*@A)E``&":3 +M``B.E@!0CI<`*"21!(`40``'`*`8(;RQ```DI0`0`&80(0!%$"L00/_[```` +M``*@("$"0"@A#`!/G"0&``$00`!F)`,`#9("``..8P`,,$(``1!``*DP:0`? +M)`(``:Y"`$"6`@`&``(00C!"#_^F0@!&E@(``*9"`$22`@`"D@,``Z))`$HP +M0@`/``,9`@!#$"&F0@!(DF(`!#!"``$00`"2`````!+```4D"@`>@L(`NA1` +M``(`0%`A)`H`'I("``,P0@`!$$``:RE"_^P40``.CB,!""0"`2<08@!D``,0 +MP`!#$"$`"B'`/`-F9@!$$"$T8V9G`$,`&``"%\,``!@0``,8@P!B&".2`@`" +M,$(`#Q1```6N(P$(D@(``P`"$0(00``6`````(XD`'B.)0!\CF(``"2E``$` +M`A6"+*,``0"#("$P0@`!KB0`>*XE`'P40`!!```P(9("``(P0@`/$$``.``& +M&(```AB``'$8(8QB`,`D0@`!K&(`P)("``4``A'"$$``!`````".(@!<)$(` +M`:XB`%R2`@`#``(0PC!"``$40``,```8(8ZB&T0P0@`!$$``"8^_`""2X@`$ +M,$(``11```:/MP```!#$"4` +MB2`AK(((P(T#``",Y0`<`&D8(8QB"<`T1`$!-$(``0"%$`NL8@G`C.0`)%"` +M``J-!```C0(``#P#`/\T8___`(,8)#P$`0``9!@E`$D0(:Q#"0"-!```C.,` +M(#P"``\T0O__`(D@(1!@``,`8B@D/`(`$`"B*"6LA1#`C.(`(%!```N,Y0`$ +MC.(`!#!"`!!00``'C.4`!(T#````:1@AC&()P#1"`@"L8@G`C.4`!#"B``00 +M0``(,*(`((T"```\!``@`$D0(8Q#$0``9!@EK$,1`#"B`"`00``')`(``HT# +M````:1@AC&(1`#1"`@"L8A$`)`(``E%"`%>-`P``)`(``U%"`$B-`P``)`(` +M!%%"`#^-`P``,*(`"%!``!2-!```C.(`*%!``!&-!```C0,````+$$`D0@!0 +MK&(+`(SC`"B-`@``K$,+!(T#``"-`AL`K&(+"(T#````:1@AC&()P#1"$`"L +M8@G`C00``(T%&_@D!OP`C((`I(RC``P\!_P``$80)#!C`_\`0Q`EK((`I(T$ +M``",HP`,-.?__XR"`*@P8P/_`$80)`!#$"6L@@"HC00``(RC``R,@@"L,&,# +M_P!&$"0`0Q`EK((`K(T&``",H@`0/`0#_XS#`*0``A0``$00)`!G&"0`8A@E +MK,,`I(T#````:1@AC&(1`#1"`0"L8A$``^``"```````:1@AC&()P#1"`""L +M8@G`$`#_OC"B``@\!``$`&D8(8QB"<`T0@!BK&()P(T#````:1@AC&(1``!$ +M$"6L8A$`$`#_KR0"``0\!``E`&D8(8QB"<`T0@"BK&()P(T#````:1@AC&(1 +M``!$$"6L8A$`$`#_H"0"``,\!0`($`#_2S2E(*HGO?_PK[$`!*^P``"OOP`( +MC*(`A"0&``0`H(`A%$``!@"`B"&/OP`(C[$`!(^P```#X``()[T`$`P`2\", +MI0!LC@4`;`P`2Y$"("`A#`![S8X$`(00`/_SK@``A">]_^"OLP`,K[(`"*^Q +M``2OOP`0K[````"`F"$`P(@A$,``*222'!R.4`"$$@``+0`````F!``(```H +M(0P`<@TD!@`8E@(`#HX$`"B.)0`$CB8`##!"#_\,`'(``((@(98"``Z.)``, +ME@,`#C!"#_\`1!`A)`3P`#!"#_\`9!@D`&(8):8#``Z.,0``%B#_[0````"6 +M`@`.E@,`"JX2`$PP0@__)$(`!`!D&"0P0@__`&(8):8#``H"8"`A`@`H(0P` +M6@L``#`AC[\`$(^S``R/L@`(C[$`!(^P```#X``()[T`(`P`>[HD!`#<`$"` +M(0!`("$``"@A#`!R#20&`%PF`@!]_["OL``P`("`(:^S`#ROL0`TK[\`0*^R`#@#H"`A```H(281'!P` +MP)@A)`8`+`P`<@V.,@"$CB(`!(X&&_@``AA``&(8(3P"@`(D0C58``,8@`!B +M&"&,9``$C&4`"(QC```DA``!)`(`!:^B``BOI0`4KZ0`$*^C``R,PP`()`(` +M`B0&``0P8P`@`@`@(20%``448``=KZ(```P`4L(R" +M&_@0`/^IE$D`>HR"&_@0`/^FE$D`?(R"&_@0`/^CE$D`?HR"&_@0`/^@C$D` +M@(R"&_@0`/^=C$D`A(R"&_@0`/^:C$D`B(R"&_@0`/^7C$D`C(R"&_@0`/^4 +MC$D`D(R"&_@0`/^1C$D`E(R"&_@0`/^.C$D`F(R"&_@0`/^+C$D`G(R"&_@0 +M`/^(C$D`H``%$,``11`A``(0P`!%$",GO?_@``(0@*^S``ROL@`(K[$`!*^P +M``"OOP`0`(*`(8X"``@`@)`A`."8(1!```@F$0`(C[\`$(^S``R/L@`(C[$` +M!(^P```#X``()[T`(`(@("$``"@A#`!R#20&`1PF1!P<$(#_\R0"``:,@P`$ +M$&+_\"0"``&N`@`()@,`/"0%``,D`@`!)*7__ZQB```$H?_])&,`"`)@."$F +M(@`$)F,`((SE``",Y@`$C.@`"(SI``RL10``K$8`!*Q(``BL20`,).<`$!3C +M__8D0@`0C.,``(SE``2,Y@`(K$,``*Q%``2L1@`(KB0`6`P`5,T"("`A`B`@ +M(0P`4_D``"@A#`!S%R8D`%P0`/_+C[\`$``%$,``11`A``(0P`!%$",``A"` +M`((@(2>]__`D`@`&K[\``!#"``XDA0`(+,(`!Q!```)!P`(F0<`"XD)``R9"0`/J(,` +M`+B#``.HA@`$N(8`!ZB'``BXAP`+J(D`#+B)``\E"``0%0+_[B2$`!"!`@`` +MH((```"@("$,`%/Y)`4``1``_]N/OP``C0(``(T&``2-!P`(C0D`#*R"``"L +MA@`$K(<`"*R)``PE"``0%0/_]B2$`!`0`/_M```````%$,``11`A``(0P`!% +M$",GO?_P``(0@*^P````@H`AK[(`"*^Q``2OOP`,)A$`"(XB`'@`@)`A/`6` +M`CP$@`(DA!8X)*46#!1```XD!@$'#`!S'B8$`&0"("`A```H(0P`<@TD!@$< +MK@``"(^_``R/L@`(C[$`!(^P```#X``()[T`$`P`<=<`````)@4`9`P`$.0" +M0"`A$`#_[0`````GO?_PK[(`"*^Q``2OL```K[\`#`"`D"$``(@A))``"(X" +M```"("@A)A`!'"8Q``$40``*`D`@(2HB``140/_YC@(``(^_``R/L@`(C[$` +M!(^P```#X``()[T`$`P`4H0`````$`#_]2HB``0GO?_PK[``````*"$D!@`X +MK[\`!`P`<@T`@(`A#`!S%P(`("&/OP`$C[``````$"$#X``()[T`$`/@``B, +M@@`4)[W_\*^Q``2OL```K[\`"`P`]__"OL0`$`("((:^R``BOL```K[\`#`#`@"$,`'(8 +M`*"0(8XB`"A00``5K@``((X"`"2N$``@K@(``(XB`!A40``*K%(`(*XR`!0, +M`'(=KC``&(^_``R/L@`(C[$`!(^P```#X``()[T`$(Y#`"2.(@`8K$,``!`` +M__0`````K@```!``_^Z.(@`8,,;__P`&$,``1A`C``(0@`!$$"&40P`P/`L0 +M8C$(__\Q*?__)`(7<``%4,`U:TW3.08``0`)2$`D!0`$)`<`$`!#&`H1```) +M)`0`%"0"`%`D!0`()`0`*`!&(`L`YB@+)`(`0"0'`"``1C@+<&48`@#D("$` +M:P`9```8$``#&8(!0Q`A)$(`%0!#`!M08``!```!S0``$!(``````````'!% +M&`(`9!`A`$D0(0/@``@P0O__,,;__P`&$,``1A`C``(0@`!$$"&41``P)`,7 +M<#P"$&(`A!@+``,8P#1"3=,`8@`9``40P```&!```QF"`$,0(21"`!4`0P`; +M4&```0```OI```$,``!#"E`/^/ +MI@`$`,`H(3"E`/^OI0`$%.#_YP*P$"&2H@``%$``,P``H"$:P``2``"`(0`0 +M$,``4!`C``(0@`!3$"&,0P`H)`(``0*10"$FAP`!`@`H(0(@("$08@`<)`8` +M`28"``$P4`#_`A80*A1`__$`$!#`HC0`89)B`["B(@!B)N(``:(B`#R28P.O +M`N,0*U1```$"X!@AHB,`/8^_`#2/O@`PC[<`+(^V`"B/M0`DC[0`((^S`!R/ +ML@`8C[$`%(^P`!`#X``()[T`0*$0`&,,`%.F,/0`_P(7$"L00``"`@`8(0+@ +M&"$0`/_=,'<`_P``@"$00``D``#P(1K``!P``)`A`K`H(9"C``$`$A#``%(0 +M(X^G`````A"``%,P(3!B`(`P8P!_$&<`0@#`("%00``%D*,``8^I``00:0`^ +M)`(``9"C``&0P@`V,&,`?S!"`']08@`JC,,`*"9"``$P4@#_`E80*A1`_^<" +ML"@ADJ(``"8#``$P<`#_`@(0*Q1`_]X`````DB@`/```@"$""!`K$$``%8XI +M`#@`$!#``%`0(P`"$(`D!@`!`%,H(0(&$`0!(A`D`I$@(28'``$00``&)H,` +M`:"0`&.,H@`L)\0``1!&``@P=`#_,/``_P(($"L40/_N`!`0P*(T`&$0`/^C +MHCX`8A``__@PG@#_)`(``0)`*"$"("`A%&+_TR0&``$,`%.F``````)7$"L0 +M0``"`D`8(0+@&"$0`/_+,'<`_R0"``$0`/_"K((`*">]__"OL```))``E`(` +M("$``"@AK[\`!`P`<@TD!@!\#`!ROP```````RB``*,H(0`%*$"N!0!4C[\` +M!(^P```#X``()[T`$``$)@``!2X```0F`P`%+@,`!C8```8V`P"%$"H`ID`J +M%$``"`"&."H1```$`*`8(0#`&"$`Q!`J`((8"@/@``@`8!`A$.#__0"`&"$` +MP!@A`*80*A``__D`HA@+D*<``#"$__\0X``+```8(0`#$$``11`AE$(``@"" +M$"L40``%)&8``3##__\`9Q`K5$#_^``#$$`#X``(`&`0(2>]_\"OO@`PK[4` +M)*^S`!ROL0`4K[\`-*^W`"ROM@`HK[0`(*^R`!BOL``0C((;=)2C``J,MP!0 +M``(2`@"`F"$`H*@A,'$/_S!>``&,M@!,C*,`*```$"&0A1@#$N``&I"$&`>. +MH@`\``(20C!"``$40``-CM0`/(YB&]Q00``+CJ(`/)!B``0P0@`!5$``!XZB +M`#R08@``)`,`"#!"``P00P`=`````(ZB`#PD`_W_`$,0)*ZB`#R.8AP84H(` +M#I+"`("6P@`>C[\`-(^^`#"/MP`LC[8`*(^U`"2/M``@C[,`'(^R`!B/L0`4 +MC[``$`/@``@GO0!`4$#_\Y;"`!Z6I``*CH4#M`P`5/8PA`__$`#_[H^_`#00 +MH``/)O``E"0"``%0@@$"D@(`/52```N"!``FD@,`/0`#$,``0Q`C``(0@`!4 +M$"&,0P`L)`(``5!B`/*2@@`#@@0`)H(%`"@,`%3?@@8`*0P``Y*#`S``0Q`C -M)$+__Q``_PVB`@`]``(80`!B&"$``QC``'08(8QB`"@01/[[`````!``__62 -M@@`#)[W_L``*5@`Q:P#_K[X`0*^W`#ROM0`T`("X(:^T`#"OL0`D`*"H(:^_ -M`$2OM@`XK[,`+*^R`"BOL``@`,"((:^H```!(*`A``KV`PP`<5ROJP`$``,H -M@`"C*"$`!2!`KZ0`"*^@`!"2XQ@#$J`!"9+D&`>.H@!8)K``E!!@``2,4P`\ -M)`(``5""`8B28@,O`!&P0`+0D"&21``!CZ,``#""`/\08`$=KZ(`#"0"``$0 -M8@$3)(,`(Y("`#PF)0`!`*(0*A!``!D```````480`!E$"$``A#``%,0(21& -M`"@`<"`A`M$0(0`"$,``4Q`AC$,`*(S"```"T#@A)*4``11#``HDQ@`8D.,` -M`9""``$`0Q`K5$```:"#``&2`@`\`*(0*A1`_^\DA``"6B``%9("`#Z"`@`F -M@@0`)P`1&$``<"@A)$+__@!$&"J`I@```(,0"P`"%@```AX#),(``@!#$"H0 -M0`#@D*0``"2"``2@H@``)`0``:(1`%ROI``0D@(`/E!```,`$1!`$%$`#@`1 -M$$``4!`A@$,````#$(``0Q`A``(00`!`&"$D1``/*$(```""&`L``QD#H@,` -M*:(#`":B`P`HH@``/@`1D$`"4!`AD$(``2Q"`#T40``0CZ(`$!H@``X"41@A -MD@0`/0`#&,``!!!``$00(0`"$,``]`%`0`/^4H,(``#(F`/\F!P`]#`!2E0)@("&/I0`($`#_3JX%`%@D -M8P`"`,,0*A!`_Q\D@@`"$`#_'J"C```P8@#_+$(`911`_NNB0P`!)`(`9!`` -M_NBB0@`!*H,`"B0"``D`0Z`*/`*``B1"1!``%!B`CZ4`#`!B&"&,8P````40 -MP@""$",``QC"`$,0(:)"``&/J``$`N`@(0*@*"$"@#`A#``RXP/`."&2`@`H -MD@,`)I(%`#ZB`@`IH@,`**(>`":/H@`(,*0`_Q"```.N`@!0$)$`-"J"``)> -M@/\,`!&00)(#`%TD`@#_$$,``B1B``&B`@!=`M$0(0`"$,``4Q`A)$<`,(#B -M``0#PA`J5$#^_P`1D$".`@`P4B(`!8X"`"RN$0`PK@``+*X``#2.`@`LC@,` -M-"1"``$`?B`A*$,`!*X$`#048/[PK@(`+*X``"RN```T`M`H(22"``*`I@`` -M*$,``"2$``4`@Q`+``(0@R3#``(`0Q`J$$``!Y"C``"`X@`$`$80*A!```0D -M!``!)&+__Z"B```D!``!$`#^VJ^D`!!40``#H@4`/1``_\JB```^DD(``2Q" -M`"Y40``$H@``/B0"`!2B0@`!H@``/HYB`R2/HP`(``(00@!B$",0`/^]K@(` -M6"1"``$"(A`J$$#^=P`1L$"28@,P`!%`0`$1&"$"(B@A``400`!%$"$``QC` -M``(0P`!S&"$`4Q`AD&,`,)!"`#!08OYH`*"((8YG```DI0`!`*<0*A!`_F0` -MH#`A``400`!%$"$``A#``%,0(21$`#`!$1`A``(0P`!3$"&00P`PD((``!!B -M``]`"`0`/_TKB<;V*XG'#00`/_QK(`;V!``_^^N)QO( -M$`#_[:XG&V@0`/_KIB<;W!``_^FN)QO@$`#_YZR`!:@0`/_EKB<;U!``_^.N -M)QNT$`#_X:(G&[L0`/_?HB<;Y1``_]VN)QO,)(0;H@P`<)T`X"@A$`#_V``` -M```\$X`#CF2*M!"```8\`H`#C$**N!!&``H`````#`!Z:@`````,`'I7`D`@ -M(:YBBK0\`H`#K%**N#P3@`..9(JT5(```P(`*"$0`/_$)!0``@P`<)T"0#`A -MCF**M!``_[^N(AO\$`#_O:XG&VP0`/^[KB<;O!``_[FN)QN<$`#_MZ8G&\00 -M`/^UIB<;P!``_[.F)QO"$`#_L:8G&\8PX@#_$`#_KJR"&S@PX@#_$`#_JZR" -M&SP0`/^IKB<;-(R"``0`X"@A#``9T8Q$```40``"`$"@(:XP&^P0`/^@KC`; -MZ">]__"OL```K(4;"`"`@"&OOP`$#``4;20%``&.!1L(#``LN@(`("$"`"`A -M#``4;0``*"&/OP`$C[````/@``@GO0`0)[W_\*^_```,`&M,`````(^_```# -MX``()[T`$">]_]``H!`AK[```#P%@```@(`AK[\`)*^^`""OMP`XX$&`@"`"`A```H(0``,"$,`"SJ```X(1;@`!,`%B@K -M,B,W`"0")0"F$AMPIA,;?*(4&WZB%1M_IA$;]`#`,`''0)@07[`P`<5P`````)&,` -MR"QE`,B.!!A``$40(0!`,"$D"```)`D`R`P`<70`8#@A$`#_VP`````,`%)> -M`B`@(0`"&(``]`""4@AMR$`#_ZP`"BP(0`/_IE)$;, -MD1LL$`#_Y8R1&S`0`/_CC)$;2!``_^&,D1M,$`#_WXR1&U`0X/_=)!(`!B2% -M&Z@D!@`&#`!PG0#@("$0`/_7`````!``_]6,D1M4$`#_TR03``X0X/_1)!(` -M$`#@*"$,`"Q8)`8`$!``_\P`````$`#_RHR1&^P`@#@A```P(1"@``@``!@A -M`,<0!B3&``$P0@`!``,80`#%("L4@/_Z`&(8)0/@``@`8!`A)[W_\*^R``BO -ML0`$K[```*^_``R,H@!,)+``"`"@B"&020!`C$H`/*R@`!R,HP`<``D00`!) -M$"$``A#`K*,`&`!*0"&1!0`PC@,`#(X'``0D`O_@`&(8)#"E`!\D`N__`.(X -M)`!E&"6N!P`$K@,`#(T#`"@D`@`#`(`X(1!B`"L`P)`AC@,`"(X$``0\`O_P -M-$+__P!B&"0\`@$``((@)3P"``$`8A@EK@0`!*X#``B.(@`(/`,`/SP$X?\` -M0Q`E-(3__S)#``\`1!`D``,>0`!#$"6N(@`(C@(`!#P#_P\T8___`$,0)#P# -M`#``0Q`E/`,&``!#$"6N`@`$CB(`"(XD`"0\`P"``$,0):XB``BN)```C[\` -M#(^R``B/L0`$C[````/@``@GO0`0CB(`"#P#@``\!?X/`$,0):XB``B0A!T` -MC.8<5(X#``P`!!!``$00(0`"$,``1A`AD$(`,#2E__\`91@D,$(`'P`"%0`` -M8A@EK@,`#(T#`"@\`H`")$)$```#&(``8A@ACB4`"(QB```!0"`A,*4/_P$@ -M,"$`0/@)```X(8X#``@D!(``,$)__P!D&"0`8A@E$`#_L:X#``@GO?_@K[`` -M$`"@@"$#H"@AK[$`%*^_`!@,`"WM`("((5(```$```'-CZ,`!(^B```T"8`` -M``,=@``"$H(`8A@E`'`X(0#P$"$D0O__`%``&XXC``"6)1N"-`B```!I&"$R -M"O__```0$@``````````<%`X`JQG`"B.(@````<8P"1F__P`21`AK$8`+(XB -M```D9O^P`.4@(0!)$"&L1@`PCB(``"3C``$`92`*`$@0(:Q$`#2.(@``/`,` -M@`(#,"4`2!`AK$8`((XB&X@00``AC[\`&(XB``".)1N0`$@0(:Q*`0".)``` -MCB,;B`"(("&,@@$```,<`#!"__\`0Q`EK((!`(XB&XR.(P```.(0(0!H&"$P -M0O__K&(`_!"@``>.(@``/`0``@!($"&,0P#\`&08):Q#`/R.(@``/`0``0!) -M$"&,0P#\`&08):Q#`/R/OP`8C[$`%(^P`!`#X``()[T`(">]_]"OL@`(,)(` -M_Z^W`!ROM@`8K[4`%*^T`!"OLP`,K[```*^_`""OL0`$`*"@(0#`J"$`X+`A -M`0"X(0$@@"$!0)@A$D``#"0"``&/OP`@C[<`'(^V`!B/M0`4C[0`$(^S``R/ -ML@`(C[$`!(^P```#X``()[T`,`P`>EFH"("`A`@`0(1``_Z^NX```#`!Z:@(@("$0`/^K -M)`(``B>]__`LH@`$K[(`"*^Q``2OL```K[\`#`"@B"$`@(`A%$``"`#`D"$D -M`O__C[\`#(^R``B/L0`$C[````/@``@GO0`0#`!A$9"$``"2!````!$0@`!0 -M$"$,`&$BK%(`'!``__(``!`A,*4`_R>]__`LH@`*K[\``!!```TD!___/`.` -M`@`%$(`D8T1`)*4``0!#$"$0@``&,*4`_XQ'```,`&(NC(0`$"0'__\``C@* -MC[\```#@$"$#X``()[T`$#"E`/\GO?_P+*(``J^_```00``()`/__R2E``$0 -M@``%,*4`_PP`8E^,A``0)`/__P`"&`J/OP```&`0(0/@``@GO0`0)[W_\*^_ -M```\`H`"D$)$:`"`2"$`X%`A,*,`_Q!``!]_^"OL0`$K[\`%*^T`!"OLP`,K[(`"*^P```\`H`"D$)$ -M:!!```D`@(@AC[\`%(^T`!"/LP`,C[(`"(^Q``2/L````^``"">]`"".,@`4 -MD(0```P`83,F4P`(CE````P`84R2)```$@#_\8^_`!0,`&$SDB0``(Y"``". -M%```C$(``!1```*N0@``KE(`!`P`84R2)```D@(`!"0#``%00P`BC@(`"%1` -M``<"`"`AD@(`"5!``!N2!0`(4$,`$I(%``@"`"`A```H(0P`<*HD!@`,#`!A -M,Y(D``".8@`$K@```*YP``2L4```DB0```P`84P"@(`A%H#_W8^_`!00`/_, -MC[0`$(XB``R.)``$C@8`#`!`^`F.!P`0$`#_Z@(`("$0`/_YCB(`"``"$(`` -M41`AC$(`'%!`_^,"`"`A`$#X"8XD``00`/_?`@`@(2>]__"OOP``#`!A,Y"$ -M``"/OP`````0(0/@``@GO0`0)[W_\*^_```,`&%,D(0``(^_`````!`A`^`` -M"">]`!`\`H`"H$!$:`/@``@``!`A)`,``3P"@`*@0T1H`^``"```$"$GO?_P -MK[```*^_``0,`'"U`("`(0P`6L<"`"`A#`!F*8X$`!`,`%IS`@`@(0P`6L\" -M`"`A#`!PN@````"/OP`$C[``````$"$#X``()[T`$">]__"OOP``#`!H%HR$ -M`!"/OP```^``"">]`!`GO?_PK[$`!*^P```PT0#_,+``_P(`*"$"(#`AK[(` -M"*^_``P,`&'W`("0(0)`("$"`"@A%$``"0(@,"$``!@AC[\`#(^R``B/L0`$ -MC[````!@$"$#X``()[T`$`P`8A8`````%$#_]@!`&"$"0"`A`@`H(0P`8?<" -M(#`A%$#_\"0#``<0`/_N```8(2>]__"OOP``/`*``I!&10,PI0#_`*`X(0`` -M0"$``"@A#`!AYP``2"&/OP```^``"">]`!`PI0#_)[W_\`"@,"&OOP``#`!A -M8P``*"&/OP```^``"">]`!`GO?_PK[```#"P`/^OL0`$`@`H(:^_``@,`%LK -M`("((0(`,"$"("`A#`!:^P``*"$"("`A#`!;'@(`*"&/OP`(C[$`!(^P```# -MX``()[T`$">]__"OOP``/`*``I!#1&D`P#@A)`(`0#AC``(D!@(``$,P"S#G -M`/\PI0#_)`@``@P`8><``$@AC[\```/@``@GO0`0)[W_\##&`/^OOP``#`!A -M8S"E`/^/OP```^``"">]`!`GO?_PK[$`!*^P```PT0#_,+#__Z^R``@"`"@A -M`("0(:^_``P,`%M9`B`P(0)`("$"`"@A#`!:^P(@,"$"0"`A`@`H(0P`6T@" -M(#`AC[\`#(^R``B/L0`$C[````/@``@GO0`0)[W_\*^R``BOOP`,K[$`!*^P -M```0H``.`("0(9##``,D`@"!$&(`/2AB`((00``E)`(`@B0"`(`08@`+/!&` -M`@)`("$``"@A#`!C$@``,"&/OP`,C[(`"(^Q``2/L````^``"">]`!`F,$?" -M`@`P(0P`8J4D!0`&EB-'P@(`,"$"0"`A,&(`_P`"$@```QH"`$,0)0``*"$D -M!P`"IB)'P@P`8E\``````D`@(0``*"$``#`A#`!B+@``."$0`/_EC[\`#%1B -M_]\"0"`AD,,`!SP0@`(F$4?",&,`#S1E`!`"(#`A/`*``@P`8J6@0T?&E@-' -MP@(@,"$"0"`A,&(`_P`"$@```QH"`$,0)0``*"$D!P`"$`#_XJ8"1\(\`H`" -M)$9'P0``*"$D!P`!$`#_W*!`1\$GO?_@K[(`&*^P`!``H)`A`,"`(20%``$# -MH#`AK[$`%*^_`!P,`&*E`("((9>B```L0@`"$$``"@(@("$20``,C[\`')(# -M``-08``DE@,``"0"``)08@`+E@(```(@("$``"@A#`!C$@``,"&/OP`]`"`40/_V`B`@(9("``<\$(`#,$(`#S1%`!`#H#`A -M#`!BI:("BKR2!8J\`B`@(0``,"$TI0`0#`!BUP`````"("`A```H(0``,"$, -M`&)?```X(1``_^:/OP`<)`(``11B_]\"("`A`Z`P(0P`8J4D!0`&EZ(```(@ -M("$D!0`&,$+__0!`,"$0`/_KIZ(``">]_^"OL0`4K[``$*^_`!ROL@`8`,"` -M(1"@`$@`@(@AD,,``U!@`"*4PP``)`(``E!B``N4P@```B`@(0``*"$,`&,2 -M```P(8^_`!R/L@`8C[$`%(^P`!`#X``()[T`(!1`__<``"@AD-``!P.@,"$R -M$``/-A``$`P`8J4"`"@A`B`@(0(`*"$D!@`!#`!BUP`````"("`A```H(0`` -M,"$,`&)?```X(1``_^B/OP`<)!(``1!R`!B```" -M("`A)`4`!C1"``(`0#`A$`#_U:>B```\`H`"C$)$;%!`_\&/OP`]__"OL0`$K[\`"*^P```0H``-`("( -M(9##``$``"@A```P(0``."$\`H`##`!B7Z!#BKV/OP`(C[$`!(^P```#X``( -M)[T`$#P"@`.01HJ])`4``PP`8M]__"OL```K[\` -M!`#`."$`@(`A$*``$0``0"&4PP``)`(#`#!E_P`0H@!5**(#`1!``#0D`@8` -M)`(!`!"B`"HD`@(`$*(`"3P"@`("`"`A```H(0P`8Q(``#`AC[\`!(^P```# -MX``()[T`$)!"1&DD`P!`.$(``@!B*`LE!``!``@8P#P"@`(`:!@C)$9%'#"( -M`/\`9A@A``42`BT$``2@8@`7%(#_]:!E`!:4XP`$)`<`+@(`("$L8@`N`&(X -M"P``*"$,`&)?``````(`("$``"@A```P(0P`8BX``#@A$`#_WX^_``24PP`$ -M)`<`$CP&@`(L8@`2`&(X"Q``__`DQD3\$*(`%R0"!P`4HO_0`@`@(3P"@`*0 -M0D1I)`4`0"0#`@`X0@`"`&(H"R4$``$`"!C`/`*``@!H&",D1D6$,(@`_P!F -M&"$`!1("+00`!*!B`!<4@/_UH&4`%A``_]24XP`$E,,`!"0'``H\!H`"+&(` -M"@!B.`L0`/_1),9%$#!C`/\L8@`$%$``"#P"@`(\!H`"D,-$?)3G``0DQD1\ -M`.,0*Q``_\8`8C@*)$(P```#&(``8A@AC&8``)3G``0``"@AD,,```#C$"L0 -M`/^]`&(X"B>]__```"@AK[\```P`8Q(``#`AC[\```/@``@GO0`0)[W_X`"@ -M$"&OL``0K[\`%`.@,"$D!0`$%$``!0"`@"&/OP`4C[``$`/@``@GO0`@#`!B -MI0````"3HP`!/`*``B1&1\```"@A)`<``0(`("$,`&)?H$-'P`(`("$``"@A -M```P(0P`8BX``#@A$`#_[8^_`!0GO?_@K[$`%*^P`!"OOP`8`,"((1"@`!L` -M@(`AD,,``2QB``(00``=```H(11@`!\#H#`A)`4``0P`8J4#H#`AEZ(``"Q" -M``(00``3`@`@(20%``0,`&+7```P(0(`("$D!0`!)`8``0P`8M<``````@`@ -M(0``*"$``#`A#`!B7P``."&/OP`8C[$`%(^P`!`#X``()[T`(```*"$,`&,2 -M```P(1``__B/OP`8#`!BI20%``22)@`!EZ(``%!&``@D!0`!`@`@(0P`8M]_^"OL@`8K[$`%`"@ -MD"$`P(@A)`4``0.@,"&OL``0K[\`'`P`8J4`@(`AEZ(```(`("$``"@A%$`` -M%P``,"$60``'`````(^_`!R/L@`8C[$`%(^P`!`#X``()[T`()8G``22)@`' -M/`*``B1"1'0`PC`A#`!B7P`'."L"`"`A```H(0``,"$,`&(N```X(1``_^Z/ -MOP`<#`!C$@`````0`/_JC[\`'">]__"OOP``$*``"0#`2"&0PP`#)`(``0`` -M*"$``#`A$&(`!@``."$,`&,2`````(^_```#X``()[T`$)$C``<\`H`")$)$ -M=`!B&"&1*``!D&(`````*"$02``#```P(9$B``&@8@``#`!B7P`````0`/_P -MC[\``">]_^"OLP`,K[```*^_`!2OM``0K[(`"*^Q``0`P(`A$*``"`"`F"&0 -MT0`#)`(``@``*"$2(@`+```P(0P`8Q(`````C[\`%(^T`!"/LP`,C[(`"(^Q -M``2/L````^``"">]`"`\`H`"D$-%'9("``<\$H`")E1'Q`!#$"LD!0`%%$`` -M!`*`,"$``"@A$`#_ZP``,"$,`&*E`````)8&``261$?$```H(2S"``(P@P#_ -M`,*("P`$(@(``QH``&08)0*`,"$"(#@A`F`@(0P`8E^F0T?$`F`@(0``*"$` -M`#`A#`!B+@``."$0`/_7C[\`%">]_^"OLP`,K[(`"*^Q``2OL```K[\`$#P0 -M@`,`P)@AC@:*P`"`D"$`H(@A/`2``CP%@`(DA!&`#`!P="2E$9".`HK`)$(` -M`1(@``>N`HK`EF,``"0"``$08@`A)`(``E!B``B69@`&C[\`$(^S``R/L@`( -MC[$`!(^P```#X``()[T`(##%``\DH___,&+__RQ"``(00``$,&+__S#"`(`4 -M0``,,&+__RQ"``(00/_N,,(`@%1`_^V/OP`0`D`@(0``,"$,`%MA`````!`` -M_^>/OP`0`D`@(1``__HD!@`!)!```0(`*"$"0"`A#`!;820&``$F`@`!,%`` -M_RX"``,40/_Y`@`H(200``$"`"@A`D`@(0P`6V$``#`A)@(``3!0`/\N`@`# -M5$#_^0(`*"$0`/_.C[\`$">]__"OL```K[\`!!"@``<`@(`AD,(``A!```@` -M```````H(0P`8Q(``#`AC[\`!(^P```#X``()[T`$`P`7>X``````@`@(0`` -M*"$``#`A#`!B7P``."$0`/_UC[\`!#P"@`*00D7L$$```CP"@`*@2$1I`^`` -M"``````GO?_PK[```*^_``0\`H`"D$)%[```*"$40``%`("`(8^_``2/L``` -M`^``"">]`!`,`%LTC(0`$(X$`!`,`%LT)`4``0(`("$,`%I-)`4``A``__2/ -MOP`$)[W_\*^_```\`H`"D$)%[!1```0``"@AC[\```/@``@GO0`0#`!:30`` -M```0`/_[C[\```/@``@``````^``"``````GO?_@K[$`%*^P`!"OOP`8`*"( -M(12@`($`@(`A/`*``B1&1[B0P@`#,$,`8"0"`"`08@`)*&(`(1!``'(D`@!` -M4&``"I#&``*.!``0```H(0P`8Q(``#`AC[\`&(^Q`!2/L``0`^``"">]`"`L -MP@`-$$#_]3P#@`(`!A"`)&,1G`!#$"&,0@```$``"`````".!``0/`:``@(@ -M*"$,`%MZ),9'N!``_^V/OP`8C@0`$#P&@`("("@A#`!;QR3&1[@0`/_FC[\` -M&(X$`!`\!H`"`B`H(0P`7`LDQD>X$`#_WX^_`!B.!``0/`:``@(@*"$,`%QE -M),9'N!``_]B/OP`8C@0`$#P&@`("("@A#`!X$`#_RH^_`!B.!``0/`:``@(@*"$,`%T2),9'N!`` -M_\./OP`8C@0`$"0%``$,`&*E`Z`P(8X$`!`\!H`"`B`H(0P`72\DQD>XC@0` -M$">F``(,`&*E)`4``9>B```00/^REZ(``E1`_[&/OP`8`@`@(0P`6DTD!0`# -M$`#_K(^_`!B.!``0/`:``@(@*"$,`%UJ),9'N!``_Z6/OP`8C@0`$#P&@`(" -M("@A#`!=E"3&1[@0`/^>C[\`&(X$`!`\!H`"`B`H(0P`7;(DQD>X$`#_EX^_ -M`!@48O^1C@0`$`P`7CP"("@A$`#_D8^_`!B,A``0/`:``B3&1[@,`&(/```H -M(1``_WL\`H`")[W_\*^_```\`H`"D$)%[#"C`/\PZ@#_$$``"`#`*"$!`#@A -M`4`P(0$@0"$08``*+&(``Q1```0`8"@AC[\```/@``@GO0`0#`!:%0`````0 -M`/_[C[\```P`7H(`````$`#_]X^_```GO?_@K[$`!#"Q`/^OLP`,K[(`"`"` -MF"$`$9#``B`@(:^_`!`,`&$SK[````)1$"$``A"``%$0(SP#@`,D8Z&```(0 -M@`!#$"$D0P`8E&0`!!"```H"41`A-`+__Q""``8`!"("D&(`!3P#@`(D8T3\ -MH&0`":!B``@"41`A``(0@`!1$",\`X`#)&.A@``"$(``0Q`A)$,`&)1E``8P -MI/__4(``\B0#``,T`O__$((`[B2B``*D8@`&D&0`!SP#@`(D8T3\``(2`J!B -M``N@9``*/`*``@`1&$`D0D?@`&*`(9(%``&2!@``/`2``@P`<'0DA!'0D@(` -M`11``,X\!H`"`E$0(0`"$(``41`C/`.``R1CH8```A"``$,0(91$`"`0@``) -M)$,`(#0"__\0@@`&``0B`I!B``$\`X`")&-$_*!D``V@8@`,`E$0(0`"$(`` -M41`C/`.``R1DH8```C"``,00(21#`""48@`$)$+__RQ"`$`00``B`E$0(3P% -M@`(D@@`JD&,`!22D1(``PC`A)(0``@#$$"4D8P`",$(``Z"C1(`00`"6),,` -M0`!@$"&(PP``F,,``XC%``28Q0`'B,<`")C'``N(R``,F,@`#ZB#``"X@P`# -MJ(4`!+B%``>HAP`(N(<`"ZB(``RXB``/),8`$!3"_^XDA``0`E$0(0`"$(`` -M41`C/`.``R1HH8```CB``.@P(23#`""48@`&)$+__RQ"`"!00``IE,(`*)!C -M``<\!8`")0(`:B1C``(`XA`A)*1$Q*"C1,2(20``F$D``XA*``282@`'B$,` -M")A#``N(10`,F$4`#ZB)``*XB0`%J(H`!KB*``FH@P`*N(,`#:B%``ZXA0`1 -MB$D`$)A)`!.(2@`4F$H`%XA#`!B80P`;B$4`')A%`!^HB0`2N(D`%:B*`!:X -MB@`9J(,`&KB#`!VHA0`>N(4`(93"`"@D0O__+$(`$!!``!@DPP`HD&(``3P% -M@`(E`P"*)$(``@#C&"$DI$3HH*)$Z(AF``"89@`#B&<`!)AG``>(:``(F&@` -M"XAI``R8:0`/J(8``KB&``6HAP`&N(<`":B(``JXB``-J(D`#KB)`!$F9@`0 -M`B`@(0)@*"$,`&&()`<``Q!```DD`___C[\`$(^S``R/L@`(C[$`!(^P```` -M8!`A`^``"">]`"`D`P`!/`*``J!#1>R.9``0```H(0P`6QXD$``!CF0`$`P` -M6QXD!0`!CF0`$#(%__\,`%M()`8``28"``$``A8```*&`RH"``,40/_XCF0` -M$"00``$R!?__#`!;2```,"$F`@`!``(6```"A@,J`@`#5$#_^(YD`!`,`&%, -M`B`@(1``_]<``!@AC,D``(S*``2,P@`(C,4`#*R)``"LB@`$K((`"*R%``PD -MQ@`0%,/_]B2$`!`0`/]T`E$0(23&11R0P@`'D@0``#!"`-\T0P`@`$08"CP$ -M@`(`8"@A)(01Z`P`<'2@PP`'$`#_*`)1$"$D`P`#/`*``A``_Q>@0T4&)[W_ -M\*^_``2OL````("`(0P`83.0A```/`*``J!`1>P,`&*2C@0`$`P`84R2!``` -MC[\`!(^P`````!`A`^``"">]`!`GO?_@`(`0(20$`#2OM0`4K[0`$*^S``RO -ML@`(K[$`!*^P``"OOP`8`*"8(0#`H"$`X*@A`0"0(0P`>E]`""0@@`H`*(H)0/@``B@A0`H)[W_\`"`$"&OL```K[\`!`"@("$0 -MH``(,%``_PP`>FH`````/`*``@`0&(`D0D?0`&(8(:Q@``"/OP`$C[`````` -M$"$#X``()[T`$#"$`/\`!!C``&08(0`#&(`\`H`"`&08(R1"1]``!""`)[W_ -M\`""("$\`H`#K[$`!*^_``BOL```)$*A@``#&(",D````&(8(9!D`!L`X(@A -M/`B``CP'@`*N!0`@K@8`)"8)`!PDYX-@)0B#P```*"$"`#`A#`!Q"`(`4"&. -M`@`<%$``!P!`("&N,```C[\`"(^Q``2/L````^``"">]`!`,`'$F`````!`` -M__BN,```)[W_\*^P``"OOP`$$*``!`"@@"&,H@`<%$``!0!`("&/OP`$C[`` -M``/@``@GO0`0#`!Q+0`````,`'$?C@0`'!``__>N```<)[W_\*^P````H(`A -MK[\`"*^Q``0,`'%"`("((8X"`"``0/@)C@0`)`P`<5`"("`A#`!Q20(@("&2 -M!``HC[\`"*(``"B/L0`$C[```"0#``$D`@`"`&00"@/@``@GO0`0)[W_\*^_ -M``",P@`L`$#X"8S$`#"/OP```^``"">]`!`PA`#_%(``!``````\`H`#`^`` -M")!"H9L#X``(```0(3"$`/\4@``$`````#P"@`,#X``(C$*AE`/@``@``!`A -M,(0`_Q2```4`````/`*``XQ"H90#X``()$(!``/@``@``!`A)[W_\#"$`/\4 -M@``%K[\``#P"@`*,0D?4$$``!`````"/OP```^``"">]`!`,`'"U``````P` -M83,``"`A$`#_^8^_```GO?_P,(0`_Q2```6OOP``/`*``HQ"1]000``$```` -M`(^_```#X``()[T`$`P`<+H`````#`!A3```("$0`/_YC[\``">]__"OL``` -M,)``_Z^Q``2OOP`(#`!PM3P1@`,6```&DB**Q!!```L\`H`#DB**Q"1"``&B -M(HK$#`!PN@````"/OP`(C[$`!(^P```#X``()[T`$`P`<4*,1*&8$`#_])(B -MBL0GO?_PK[```*^_``0,`'"U,)``_Q8```8\!(`#D(**Q"1"__\P0P#_$&`` -M!Z""BL0,`'"Z`````(^_``2/L````^``"">]`!`\`H`##`!Q28Q$H9@0`/_V -M`````">]__`PI0#_K[\```P`8QHPQ@#_C[\```/@``@GO0`0)[W_\*^Q``2O -MOP`(K[```(R"`!@`@(@AC%````P`81&2!`"0C@(`'%1```^.`@`@KA$`'(XB -M`!B.`P`HKA$`(*Q```"2!`"0)&,``0P`82*N`P`HC[\`"(^Q``2/L````^`` -M"">]`!",0@`8$`#_\:Q1```GO?_@K[0`$#"4`/\N@@`"K[8`&*^U`!2OL0`$ -MK[\`'*^S``ROL@`(K[````"@L"$`P*@A,/$`_Q1```PD`P`/C[\`'(^V`!B/ -MM0`4C[0`$(^S``R/L@`(C[$`!(^P````8!`A`^``"">]`"`,`'I7)`0`H`!` -M@"$00/_Q)`,`"@``*"$D!@"@#`!PJ@!`("$"@"`A#`!A`*(4`)`"@"`A#`!@ -M^*X"``BB`@"1)`0'`"0"`/^B$0"3#`!Z5Z8"`(0`0(@A$$#_WB0#`*D`0"`A -M```H(20&!P`,`'"JK@(`&`P`>E]__"OOP`` -MC(,`%#$I`/^@90``C(,`%*!G``&,@P`4H&@``HR%`!2D9@`0#`!G(*RI`!2/ -MOP```^``"">]`!`GO?_PK[\`#*^R``BOL0`$K[````"`D"&0A`"0,+``_PP` -M81$PT0#_`@`H(0(@,"$,`&>%`D`@(9)$`)`,`&$B`$"`(0(`$"&/OP`,C[(` -M"(^Q``2/L````^``"">]`!`GO?_PK[\```P`9OXPI0#_C[\```/@``@GO0`0 -M)[W_\*^_``ROL@`(K[$`!*^P````@)`AD(0`D#"P`/\,`&$1,-$`_P(`*"$" -M(#`A#`!GDP)`("&21`"0#`!A(@!`@"$"`!`AC[\`#(^R``B/L0`$C[````/@ -M``@GO0`0)[W_X*^S``ROL@`(K[$`!*^P``"OOP`0`("((9"$`)``P)`A`."8 -M(0P`81$PL`#_CB(`*!!``!\"("`ACB,`'!!@``<`8"@AC&(`&(Q"```40``" -MKB(`'*X@`"".(@`HK'(`!"1"__^N(@`H)`(``:!P``"L]_^"OLP`,K[(`"*^Q``2OL```K[\` -M$`"`B"&0A`"0`,"`(0#@F"$,`&$1,+(`_XXB`"@00``A`````(XF`!P0P``7 -M)`(`H8S"`!B,0@``%$```JXB`!RN(``@CB(`*"0#``<``$)$+__ZXB`"@` -MP"@A`B`@(:#2``"LTP`(H,,``PP`95*@PP`!DB0`D`P`82(`0(`A)`(`H0`0 -M$`J/OP`0C[,`#(^R``B/L0`$C[````/@``@GO0`@#`!A(I(D`)`0`/_V)`(` -M`R>]__"OL```K[\`!`P`:"0`@(`A#`!Z:HX$`!`,`'IJC@0`&`P`>FJ.!`!T -M#`!Z:HX$`!0,`'IJ`@`@(8^_``2/L````^``"">]`!`GO?_PK[(`"*^Q``2O -ML```K[\`#`"`B"&0A`"0,+``_PP`81$`P)`A)@/__RQB``800``;,@(`$``# -M$(`\`X`")&,1^`!#$"&,0@```$``"`````"6(@"$ID(```P`82*2)`"0```0 -M(8^_``R/L@`(C[$`!(^P```#X``()[T`$!``__62(@"5$`#_\Y(B`)00`/_Q -MEB(`B!``_^^6(@"&$$``!3(%``\,`&A<`B`@(1``_^JF0@``#`!A(I(D`)`0 -M`/_I)`(``B>]__"OL@`(K[$`!*^P``"OOP`,`("0(9"$`)`PL0#_#`!A$3#0 -M__\F(___+&(`!Q!``",R(@`0``,0@#P#@`(D8Q(0`$,0(8Q"````0``(```` -M`*90`(0,`&$BDD0`D```$"&/OP`,C[(`"(^Q``2/L````^``"">]`!`R!0#_ -MHE``E0P`9O@"0"`A$`#_\@`````0`/_PHE``E!``_^ZF4`"($`#_[*90`(8" -M`"@A#`!H9@)`("$0`/_G`````!!```8R)0`/,@8`_PP`:(4"0"`A$`#_X``` -M```,`&$BDD0`D!``_]\D`@`")[W_\#"E`/^OOP``#`!H0##&`/^/OP```^`` -M"">]`!`GO?_@K[,`#*^R``BOL0`$K[\`%*^T`!"OL```C)0`"#"S`/\PQ@#_ -M`!,00(Z#`!@`1A`A``(1@`!BB"$2(``0`("0(3(B``\D0@!/)`/_\`!#*"0" -M(Q@D`&40(0!#$"L40``'`&`@(;QQ```D8P`0`(40(0!#$"L00/_[`````(XE -M`#PD`@`!$*(`"@``("&/OP`4C[0`$(^S``R/L@`(C[$`!(^P````@!`A`^`` -M"">]`"``!A$``%,0(0!%@`0"0"`A#`!D-P(`*"$40``(`!,0@`!4$"&N(``` -MC$,`@```("&L0P"`$`#_Z:X@`#P"0"`A#`!D*P(`*"$40/_D)`0`I1``__,` -M$Q"`)[W_\#"$`/^OL```K[\`!`P`80@`H(`AC$,``#!C`/\`0Q@AK@,`"(Q" -M`"0P0@`?+$,`!`!`*"$48``"H@(`DR0%``,PI`#_``0AP"2$"``,`'I7H@4` -MDP!`&"&N`@`P$$``(B0$`*@``A`C,$('_P!B$"$D!`@@#`!Z5ZX"`"P`0!@A -MK@(`-!!``!@D!`"J``(0(S!"`!\`8A`A)`0#``P`>E>N`@`XK@(`>!!```\D -M!``!D@0`D#P%@`(F!P"<`@`P(0P`8)HDI9BD)`(`_Z8"`(0"`"`A#`!CG:8` -M`(8\`H`"K%!'V```("&/OP`$C[````"`$"$#X``()[T`$">]_^"OL@`(K[$` -M!*^_`!BOM0`4K[0`$*^S``ROL````("((9"$`)`,`&$(CC,`"`!`D"&.8@`` -M)`/__@!#$"2N8@``)`(``JYB``".8@``,$(``A1`__TD`@`&KF(`:)(B`).. -M)``P```H(0`",<`DQ@@`#`!PJ@`"@$".)``T```H(20&"""N(``\#`!PJJX@ -M`$"2)@"3)B0`1```*"$,`'"J``8PP)(F`),``"@A)B0`7`P`<*H`!C#`KF`` -M;(XE`"P2```,``"@(0"@("$\`@!`-$*``":4``&L@@```I`8*R0"``&L@@`( -MK(``/!1@__]`!",0@`<$`#_\:Q1``",A@`(```@(:S%`'2,PP!T+(($``!E&"008``# -M)(0``11`__H``````^``"```$"&,A@`(```X(8S"```LZ`0`).<``31"0`"L -MP@``C,0`>(S"`'",PP```$00)3!C0``48``#`$40)!4`__,`````C,,``"0$ -MO_\``A`K`&08)`/@``BLPP``)[W_\*^E``"OI@`$CZ4``(^B``2/HP``C(8` -M"*RB``BL8``,C,(`````("$T0D``K,(``*S'`'",P@!X`$<0)!1```]_^"OL0`4K[``$*^_`!B0Z0``C((`")#H``&OI0``KZ8`!(Q# -M`!@`"8!``@B`(0`0$8``8A@AKZ,`"(^E``@`"$$`CZ8```$)0"$D!P`!`("( -M(0$'.`0,`&1-`!"`@`(1&"&,8@!$5$``#(QC`%R/H@``K&(`1`(1&"&/I``$ -MC[\`&(^Q`!2/L``0```0(:QD`%P#X``()[T`((^B```0`/_UK&(``">]_^"O -MOP`0D.@```#@8"&0YP`!C(D`"``($$``1U@AKZ4````+:("OI@`$KZ``"(TC -M`!@!I!`A`(!0(8Q$`%P`!SD```L1@`!B&"$`Z#@A)`(``:^C``P`XG`$KZ0` -M"```,"&-(@``+,@$``&J*"$T0D``K2(``(TB`'@`3C@D$.``!B3&``&/H@`( -MCZ,``(^D``2L0P``K*0`7(TB```P0D``%$```P`````5`/_M`````(TB```D -M`[__`$,0)!#@``6M(@``C[\`$```$"$#X``()[T`((^C``@`"Q"`CZ4``(^F -M``0`2A`AK$,`7`%`("$,`&1L`8`X(1``__./OP`0)[W_T*^S`!ROL@`8K[$` -M%*^_`""OL``0`*"0(8R#``B0I0```("((9)$``&,8P`8``400`!$$"$``A&` -M`&(8(:^C``"/HP````0A``"%("$D`@`!`()@!```6"$``)@ACD@`"!!@`!,` -M`%`ACZ0``(^E``"/H@``)`/_\`"#("0P0@`/)$(`3P!#$"0`@B`A`*,H)`"% -M$"L40``&`````+RQ```DI0`0`(40*Q!`__P`````CZ(``(Q#`#PD`@`!$&(` -M"20$`*&/OP`@C[,`'(^R`!B/L0`4C[``$`"`$"$#X``()[T`,(XP`#PM`D`! -M)`E```$"2`L2```Z`0E`(XX&`!R,P@``%$```JXB`#RN(`!`EB,`B@`)%``T -M18"`)&/__S1$`(`D`@`!K-$```(*F`JN`@``%0``**8C`(JN!0`$CD,`!(X$ -M``0D`H#_`&H8(0""("2LT@`()&=``"1B$``D92``)&8P`*X$``2N`@`,K@4` -M$*X&`!2N!P`8K@,`"!%@``(!25`AK7```!4`_]4"`%@A`8`H(0P`9#<"("`A -M%$``!P(@("$"8"@A`@`P(0P`9&P"0#@A$`#_P@``("$"8"@A`@`P(0P`9)8" -M0#@A$`#_O```("$0`/_9K@0`!!``_[@D!`"F)[W_\*^_```,`&37`````(^_ -M```#X``()[T`$">]__"OOP``#`!DUP````"/OP```^``"">]`!`GO?^PK[,` -M+*^_`$2OO@!`K[<`/*^V`#BOM0`TK[0`,*^R`"BOL0`DK[``((R"``BOH``( -MKZ``#*^B``",50!L`("8(:^@`!`2H``2KZ``%)""`),00``/``"@(20"``$" -M@A`$`J(0)#*%`/\D!@`!)I0``0``."$``$`A%$``I20)``B28@"3`H(0*Q1` -M__0D`@`!CZ,``(QU`'RL=0!\$J``C(^_`$2OH``$CZ0`!))B`),``*`A$$`` -M?P`$N"L`%Q"``%,0(21"`$2OH@`8`N#P(1+@`(TD`@`!)H,`$`!B$`0"HA`D -M4$``;))B`)./H@``CZ0`&(Q#`!@`'A&``&*P(1+``!",A0``,L(`#R1"`$\D -M`__P`$,P)`+#&"0`9A`A`$,0*Q1```<`8"`AO'$``"1C`!``AA`A`$,0*Q!` -M__L`````4*``5))B`),PH@`/)$(`+R0#__``0S`D`*,8)`!F$"$`0Q`K%$`` -M!P!@("&\<0``)&,`$`"&$"$`0Q`K$$#_^P````",H@`$,$(`@!!``!$````` -M5H``/Y)B`).,H@`$)`,`0``"%`(P0@!_5$,`.9)B`).,H@`$,$*``%!``#62 -M8@"3C*(`!"0#_W\`0Q`DK*(`!(RB`!R,0@`($$``!@````",0P`$C$0`"*^B -M`!"OHP`4KZ0`#(RB``",HP`$)`3_X#!C`&@48``[`$20)(RB``2/HP`(CZ0` -M#``"%`(P0G__`&(8(0"#(".OHP`(KZ0`##*0`/\R\0#_`F`@(0(`*"$,`&B7 -M`B`P(5)```>.9`"8CD(`'(^C`!",0@`($$,`"0````".9`"8CZ@`%(^I``P" -M`"@A`B`X(0P`7Q```#`AKZ``"!9`_Z\"0"@ADF(`DX^D`!@FE``!`H(0*R2$ -M``BOI``8%$#_B"?>``*/H@`$)$(``:^B``0L0@`"%$#_>8^D``2/OP!$C[X` -M0(^W`#R/M@`XC[4`-(^T`#"/LP`LC[(`*(^Q`"2/L``@`^``"">]`%"NP``, -M$`#_SC*0`/\0`/]U`H(0!`P`7Q".9`"8$`#_6I)B`),GO?_PK[$`!*^_``RO -ML@`(K[```)""`)`\`X`")&-'U``"$(",D@`(`$,0(20#``$`@(@AK$,``(Y0 -M``2.0@`(`@(0)!!``"@R`@!`KE``!!1``"$`````,@(`!!1``!H`````,@(` -M`A1``!,`````,@(``11```P`````,@(!`!!`_^T`````CD(`1#!"#``00/_I -M``````P`9IH"("`A$`#_Y0`````,`&5@`B`@(1``__,R`@$`#`!FZ@(@("$0 -M`/_L,@(``0P`9JH"("`A$`#_Y3("``(,`&9O`B`@(1``_]XR`@`$DB,`D#P" -M@`*/OP`,C[(`"(^Q``2/L```)$)'U``#&(``8A@AK&````/@``@GO0`0)[W_ -M\*^Q``2OOP`(K[```(R0``@`@(@AC(0`F```*"$``#`A```X(0P`7EL``$`A -MC@,`%#P"`?\T0O__`&(8)*X#`!2.`@!LK@(`;(X"`'RN`@!\C@(`6P``0"&/OP`(C[$`!(^P```#X``()[T`$">]__"OOP``E(,` -MA`"`$"&,A`"8I$,`CB0#`("D0P"$```H(0``,"$``#@A#`!><0``0"&/OP`` -M`^``"">]`!`GO?_PK[```*^_``BOL0`$C((```"`@"$00``"C)$`"*R```". -M(@!$,$(!`!1```T`````CB(`1#!"`@!00``#H@``DB0"``*B`@"2D@@`DHX$ -M`)@``"@A```P(0P`7E0``#@ACB(`1#!"`(!40``9E@(`A(XB`$0P0@"`%$`` -M!20"``*6`P"$)`(`@!!B``?@``0"$0`/_SC[\`"(X$`)@` -M`"@AI@(`CB0"`("F`@"$```P(0``."$,`%Z```!`(1``_]X`````)[W_\*^P -M````@(`A/`2``J^_``0,`'!T)(02+)8"`(R/OP`$)$(``:8"`(R/L````^`` -M"">]`!",@@`(``4N0*Q%`!0D`@`!`^``"*2"`(2,B0`(,*4`_P`%$<"-(P`8 -M`&(@(1"``!$D`@`!,((`#R1"`$\D`__P`$-`)`"#&"0`:!`A`$,0*Q1```<` -M8#@AO'$``"1C`!``Z!`A`$,0*Q!`__L`````)`(``0"B$`2(@P`HF(,`*XB% -M`"R8A0`OJ,,``+C#``.HQ0`$N,4`!P/@``BM(@!L)[W_X*^S``ROL0`$K[`` -M`*^_`!2OM``0K[(`"(R4``B0IP``D*8``8Z#`!@`!Q!``$80(0`"$8``0X@A -M`*"`(1(@`!``@)@A,B(`#R1"`$\D`__P`$,H)`(C&"0`91`A`$,0*Q1```<` -M8"`AO'$``"1C`!``A1`A`$,0*Q!`__L`````CB(`/``&&0``9Q@A)`0``0!D -MD`000``*```8(8^_`!2/M``0C[,`#(^R``B/L0`$C[````!@$"$#X``()[T` -M(`)@("$,`&0W`D`H(11``"H"8"`AD@,``B0"``$08@`BE@(`$!!@`!P````` -MC@,`%!!@``,``B0`/`(@``""("6N)```D@(``)($``$D`P#```(0@`!4$"$\ -M!@#``&0P"HQ%`(`D0P"`$(``"9("``(``A2``,(0)0"B$"6L8@``)`(``:XB -M`#P0`/_4```8(1``__@``A"```(4`#1"@``0`/_HKB(``#P#0````A0`$`#_ -M^P!#$"4,`&0K`D`H(11`_\8D`P"D$`#_TY(#``(PI0#_,,8`_P`%*$``IB@A -M``4H@`"D*"&,HP!$$&``!```$"&,8@`]_]"O -MLP`<,-,`_Z^R`!@`$Q$`,+(`_Z^U`"2OM``@K[$`%*^_`"BOL``0`("((0!2 -M$"$`$AA`)`0``0!$(`0`FJ.!``T#`!Z:HX$`'B2!`"0#`!@QHX%`)R/OP`$ -MC[````/@``@GO0`0C(0`"#"E`/\PQP#_``400(R&`!@`1Q`A``(1@`!&$"&, -M0@````48@`!D&"$\!@`!,$*``#3&``$00``%`&`H(8QB`(``1A`E`^``"*QB -M`(",8P"`/`(``22E`(`4X``"`&(0)31B``$#X``(K*(``(R"``@PI0#_``4H -M@`"B*"&,H@"`/`,``31C``$`0Q`D`^``"``"$"LGO?_PK[$`!*^_``BOL``` -MC)``"#P"`$`PL?__C@8`@```*"$D!P`U`,(0):X"`(`\!H`")`($`!(B``PD -MQD7PC@8`1"0#_]4`$1(``,,P)`#"$"6N`@!$C[\`"(^Q``2/L````^``"">] -M`!`,`&)?`````!``__..!@!$C(,`"#"E`/\\"``!/`?__@`%$(`PQ@#_-0@` -M`33G__X0P``%`$,@(8R"`(``2!`E`^``"*R"`(",@@"``$<0)`/@``BL@@"` -M)[W_X*^R``BOOP`0K[,`#*^Q``2OL```C((`"#"E`/\PQ@#_C$,`&``%*$`` -MIB@A``41@`"`D"$`8B`A$(``#S""``\D0@!/)`/_\`!#,"0`@Q@D`&80(0!# -M$"L40``'`&`@(;QQ```D8P`0`(80(0!#$"L00/_[```````%F(`"]`""L0`!<$@#_]JQ``$00`/_QC@(`&">]__`T`K]H$*(`!*^_``"/ -MOP```^``"">]`!`D`@`!5(+__(^_```,`&VM`````!``__B/OP``)[W_\"0$ -M``&OOP``#`!H^#0%OVB/OP```^``"">]`!`GO?_PK[\```"`*"&,A`"(#`!T -M[P`$((*/OP`````0(0/@``@GO0`0`^``"```$"$GO?_P/`*``J^P```D4$:< -M/`*``B1"1H`"`A`K$$``!:^_``2/OP`$C[````/@``@GO0`0C@(```!`^`DF -M$/_\/`*``B1"1H`"`A`K4$#_^HX"```0`/_TC[\`!``$$",`@B`D``04``!$ -M(",`!!&``((@(0`$$0``@B`A/`*``B1",!0`!":"`((@(0/@``B`@@``&(`` -M%"0(`!0H@R<1)`(G$`"#$`MP2#`"`((@(QC```M`!4@`0`)(`!"B__X`11@C -M/`<``P!`*"$$8``(-.<-0`##,",

    ] -M_^"OOP`0#`!I7``````00`!#C[\`$$"`X`````````````````!`@.@````` -M````````````/`.``+QI```\`H``)&,`$#1"#_\`0Q`K$$#_^@````!``H`` -M````````````````/`/__S1C__@`0Q`D-$(``T""@`````````````````!` -M@.``````````````````0(#H`````````````````#P#@`"\:```/`*``"1C -M`!`T0@__`$,0*Q!`__H`````0`*``````````````````#P#__\T8__X`$,0 -M)#1"``-`@H``````````````````0`*``*^B``"/H@``CZ(``"0#__P`0Q`D -MKZ(``(^B``!`@H``C[\`$`/@``@GO0`@/`2@P#2$`"",A0``)`+^_SP#H,`` -MHB@DK(4``(R%```D`OW_-&,`D`"B*"2LA0``C&4``#2E``$#X``(K&4``#P# -MH)`T8T``C&4``"0"__P\!*"0`*(H)*QE```TA$`$C(4``#P#__PT8___`*,H -M)#P"H)"LA0``-$*8<(Q%```TI0`/K$4``(R%```\`@`!`*,8)`!B*"4#X``( -MK(4``#P#H,`T8P`@C&(``#1"`P`#X``(K&(``#P%H,`TI0!@C*8``#P#__X\ -M`@`!``0A@#1C__\`@B`D`,,8)`!D,"6LI@``C*8``#P"``(`PC`E`^``"*RF -M```PA`#_``01@#P&H,`\!:#`,$<`0"0"``$TQ@!@$((`"C2E`&2,PP``)`+_ -MOS1C`#"LPP``C,,```!B$"0`1Q@E`^``"*S#``",HP``)`+__@!B&"00`/_S -MK*,``">]__"OL```K[\`!`P`:5PPD`#_`$`P(3P#H,`D`@`!$@(`%S1C`&`` -M$!`G/`.@P``0(<`T8P!@``(1P#!%`(`PA`"`C&,``!#```HD`O]_`&(0)`!% -M&"6/OP`$C[```#P"H,`T0@!@K$,```/@``@GO0`0`&(0)!``__<`1!@EC&,` -M`%#```,T8P$`)`+^_P!B&"0\`J#`-$(`8*Q#```0`/_B`!`0)R>]__"OOP`$ -M#`!I7*^P````0(`A/`*``@P`:>F01$8J/`*``@P`:@"01$8I/`*@P#P#[_\T -M0@!@-&/__XQ%```2```4/`(0``"C*"0\`J#`-$(`8#P#H,"L10``-&,`((QE -M```D`N__/`2@P`"B*"0TA`"0K&4``(R%``"/OP`$C[```#2E``*LA0```^`` -M"">]`!`0`/_M`*(H)4`(8```````-0@``4"(8`````````````/@``@````` -M/`.@`!"```XT8P0`**(`$!!```LD`O__)*7__Q"B``@`````D&(``"2E__\D -M8P`!H((``"0"__\4HO_Z)(0``0/@``@`````)[W_X`.@("&OOP`0#`!J620% -M``^3HP``C[\`$#P$@`(``Q!")(5'X#!"``$P8P`!H(-'X*"B``$#X``()[T` -M(">]_^`\`Z#`K[\`$#1C`)",8@``/`6@P#2E`&"OH@``CZ(``#P$_O\TA/__ -M-$(`!*^B``"/H@``K&(``(RB``"OH@``CZ(```!$$"2OH@``CZ(```P`:QVL -MH@``#`!IV0``("$,`&U)``````P`::L`````)`(#Z*^B``"/H@``)$+__Z^B -M``"/HP``)`+__Q1B__H\!*#`-(0`8(R"```\`__O-&/__Z^B``"/H@```$,0 -M)*^B``"/H@``#`!INZR"```,`&HJ``````P`:T0`````#`!K<0`````,`&IK -M`````#P"@`(,`&OU@$1&*`P`:E$`````C[\`$`/@``@GO0`@/`*@P#P%_^\T -M0@!@-*7__XQ#``!0@``#`&48)#P"`!``8A@E/`*@P#1"`&`#X``(K$,``">] -M__"OL```K[\`!`P`:5P`@(`A`$`P(3P#H,`D`@`5)`0`"0!0(`HT8P!H/`*@ -MP(QE```T0@!@K&0``(Q%```2```%/`*@P!#``",D`O[_-*4!`#P"H,`T0@!@ -MK$4``!(``!F,10``%,``%3P"$``\`N__-$+__P"B*"0\`J#`-$(`8*Q%``", -M10``%@``!H^_``10P``$-*4!`"0"_O\`HB@DC[\`!(^P```\`J#`-$(`8*Q% -M```#X``()[T`$!``_^X`HB@E4,#__3P"$``0`/_H/`+O_Q``_]X`HB@D/`:@ -MP#P"__TTQ@!@$(``!C1"__^,PP``/`(``@!B&"4#X``(K,,``(S#````8A@D -M`^``"*S#```\!J#`/`+^_S3&`&`0@``&-$+__XS#```\`@$``&(8)0/@``BL -MPP``C,,```!B&"0#X``(K,,``#P$H,`TA``@C(,``#P"__LT0O__`&(8)`/@ -M``BL@P``*((`!!!```L`````)`(``0"",`0`!A`G/`.@L8QC``!0H``"`&(8 -M)`!F&"4\`:"QK",```/@``@`````/`*@L31"``B,0P``)`(``0""$`0``C`G -M)`(``1"@``8`@A`$`&88)#P"H+$T0@`(`^``"*Q#```0`/_[`&(8)3P$H,`T -MA``@C(,``#P"__]_^"O -ML0`4K[``$*^_`!@,`&P^``````!`@"$\`H`#K%"A@"11H8`D`@`!$@(`40`` -M```6```"-`+P`*XB``0\$(`#)A"A@#P"H*"N`@`4)`(``JX"`!@F!@`<)`0` -M`20%``$,`&M2K@``$"8&`!XD!`!`#`!K4B0%``$F!@`@)`0`00P`:U(D!0`! -M)@8`(B0$`$(,`&M2)`4``28&`"0D!`!##`!K4B0%``&6`@`D)`4`("8&`"H` -M`A!"+$,`(`!#*`L,`&M2)`0`1"8&`"8D!`!D#`!K4B0%``&6`@`F)`4`$"8& -M`&H``A!"+$,`$`!#*`L,`&M2)`0`928&`"@D!`!U#`!K4B0%``&6`@`D)`4` -M""8&`(H``A!"+$,`"`!#*`L,`&M2)`0`=B8&``PD!``=#`!K4B0%``$F!@`* -M)`0`'B0%``$,`&M2)A``"`(`,"$D!``?#`!K4B0%``&/OP`8C[$`%(^P`!`# -MX``()[T`(`P`:]D#H"`AEZ(````"&@(0]`!`\`H`"`^`` -M"*Q$1BP\`H`"`^``"(Q"1BP\`E'K-$*%'P""`!D\`H`"```@$``$(8(#X``( -MK$1&,#P"@`(#X``(C$)&,#P"@`(#X``(C$)&-#P"@`(D0C!4``08@`!B&"$` -M!!!`)[W_\#P(H,`P1P`.+((`"*^_``2OL```-0@`8!1```4`@#`AC[\`!(^P -M```#X``()[T`$(T%```\`H`"K$9&-"0"__$`HA`D`$]`!`\`J$` -M.(0``@""("&4@@```^``"*2B```#@#@A/!R``R>]__"OOP```X`0(3P<@`,,`&M,)YS&L#P"O\``0``(`````">] -M__"OOP`$K[````.`@"$\'(`##`!L@B>]`!`#X``(```0(2>]_^"OL@`(K[```*^_`!"OLP`,K[$`!`"`@"$``"@A -M)!(``0``&"$#@)@A/!R``R>*(+__Q!``!,D`O__)`+_ -M_5""``(``"`A)(0``20#``$08``)``090#P"@`,D0HK(`&(8(3P"@``D0@,` -MK$,`%#P"@`*L1$8\`,#@(0/@``@`H!`A5(+_\22$``$\`H`"C$)&/!Q`_^XD -M1?__)`7__1``_^L`0B@+/`*``"1"`P"L0``4/`*``A``_^6L1$8\`X`0(3P< -M@`,GG,:P`^``"`!`X"$#@!`A/!R``R>]__"OOP``/`6` -M`I"B1D`00``$```@(8^_```#X``()[T`$#P"@``D0@,`C$(`-"0#``$`0/@) -MH*-&0!``__>/OP``)[W_\#P"@`"OOP``)$(#`(Q#`!0`!"8```0F`Q!@`!(P -MA0#_C&0``(QB``P`0/@)`````#P"@``D0P,`C&(`1!1```0``"`AC[\```/@ -M``@GO0`0K&``1`P`;:,`````$`#_^H^_``",0P`8$`#_[0`````GO?_PK[\` -M!*^P`````#`A/`>````&$(`DY0,`),8``3P#@`(`11`A)&.R8"C$`$"L0P`` -M5(#_]SP'@``\`@`(-$(`%:SB`P`\`H`")$*R"*RB`$`\`H`")$*R+*RB`!`\ -M`H`")$*Q-*RB`$@\`H`")$*T1*RB`"`\`H`")$*T6*RB`!P``#`AK*``3*R@ -M`#@``"@A``88P`!E&"$\`H`#)$**R``#&(``8A@A)*4``3P"@`(D0K)@**0` -M"*QB```4@/_U``88P"3&``$HP@`"%$#_\```*"$\$(``/`*``B80`P`D0K)H -MK@(`,#P"@`(D0K.8)`3__@P`;)JN`@`T#`!LYB0$__X,`'RO``````P`;)H` -M`"`A#`!LY@``("&N``!$C[\`!(^P```#X``()[T`$!"@``H``#`A)*7__P"% -M$"&`0P``)`(``Q!B``0D!@`!5*#_^B2E__\``#`A`^``"`#`$"$```%-`^`` -M"``````GO?_PK[\```P`:1@`````C[\```/@``@GO0`0)[W_\*^_``2OL``` -M/`*``HQ"1D040``5/`*``B101K@\`H`")$)&N!("``XD`P`!C@(`#`!`^`D" -M`"`A$$``#XX"`!@T0@`!K@(`&#P"@`(F$``@)$)&N%8"__:.`@`,)`,``3P" -M@`*L0T9$C[\`!(^P```#X``()[T`$"0#__X0`/_Q`$,0)">]__"OOP``#`!M -MV0`````,`&W;``````P`!H0`````#`!WP@`````#X``(``````/@``@````` -M)[W_\``$)@"OL```)`(`"@`$A@.OOP`$$@(`!R0$``T,`&TL`@`@(8^_``2/ -ML````^``"">]`!`,`&TL`````!``__<```````0F`">]__"OOP``#`!MW0`$ -M)@./OP```^``"">]`!`GO?_PK[```*^_``0`@(`AD(0````$)@`4@``$C[\` -M!(^P```#X``()[T`$``$)@,,`&W=)A```9($````!"8`5(#_^P`$)@,0`/_U -MC[\`!">]__`D!0`0)`8`*P``."&OOP``#`!N;P``0"&/OP```^``"">]`!`G -MO?^PK[4`-"0"`"`D%0`PK[X`0*^W`#ROM@`XK[0`,*^S`"ROL@`HK[\`1*^Q -M`"2OL``@`$BH"@"`D"$`H)@A`,#P(0#@N"$!(+`A``"@(0.T&"$FE``!*H(` -M(!1`__R@=0```E,0)11``"4``*`A)`(`,"04``&CH@```I80*@+"H`LD`@`M -M$N(`%@*=$"$FE/__!H``"(^_`$0"G1`A@$0```P`;=TFE/__!H'__`*=$"&/ -MOP!$C[X`0(^W`#R/M@`XC[4`-(^T`#"/LP`LC[(`*(^Q`"2/L``@`^``"">] -M`%"`0O__)H/__P!5$"8`8J`*`[00(1``_^:@5P``$$#_WP*6$"H``(`A`D`@ -M(0)@*"$"`#`A#``$XP/`."$\!(`")(02,`"#$"&00P```[00(0)`("$"8"@A -M`@`P(0/`."$,``-$H$,```!`D"$`0Q`E`&"8(11`_^LFE``!$`#_QP*6$"H` -MH%`A`,!8(0#@8"$`@!@A```0(2>]__`!`$@A`$`@(0!@*"$!0#`A`6`X(:^_ -M```,`&X5`8!`(8^_```#X``()[T`$"0'``$0@``9```0(9""`````AX`$&`` -M%`"`,"$`Q!`C*$((`0`".`H``QX#)`(`"A!B```%1@_^\`Q!`C`.`0(0/@``@` -M````)[W_@`"%$"6OO@!PK[<`;*^V`&BOM0!DK[0`8*^S`%ROL@!8K[\`=*^Q -M`%2OL`!0`("0(0"@F"$`P*@A`."P(0$`\"$#H*`A%$``&@``N"$D`@`P)[0` -M`:.B```2G0`(`N`0(2:4__^2@@``)O<``:*B```6G?_[)K4``0+@$"&BH``` -MC[\`=(^^`'"/MP!LC[8`:(^U`&2/M`!@C[,`7(^R`%B/L0!4C[``4`/@``@G -MO0"`$$#_Z0``````%H?#`D`@(0)@*"$"`#`A#``$XP+`."$#PQ`AD$(```)` -M("$"8"@AHH(```(`,"$,``-$`L`X(0!`D"$`0Q`E`&"8(11`_^XFE``!$`#_ -MU``````GO?]PK[X`@`"`\"$`P"`AK[<`?*^V`'BOM0!TK[0`<*^S`&ROL@!H -MK[\`A*^Q`&2OL`!@`,"@(0"@N"$,`&Z``."H(0``D"$``)@AK[T`1*^@`%00 -M0`%D``"P(8*"```FE``!$$``#@!`B"$D`@`E$B(`&`(@("$"X"@A`\#X"0`` -M``"/H@!4)$(``:^B`%2"@@``)I0``11`__0`0(@ACZ(`5(^_`(2/O@"`C[<` -M?(^V`'B/M0!TC[0`<(^S`&R/L@!HC[$`9(^P`&`#X``()[T`D(*1```D`@`M -M)I0``0``*"&OH`!0$B(!.J^@`$@D`@`P4B(!,X*1``"OH`!,)B+_T"Q"``H0 -M0``.)`(`+H^C`$@``Q"``$,0(0`"$$``41`A@I$``"1"_]"OH@!()B+_T"Q" -M``H40/_U)I0``20"`"X2(@$1CZ(`3"0"`&P2(@$'KZ``0"8B_[XP0P#_+&(` -M-Q!``!HF(O_;``,0@#P#@`(D8Q*D`$,0(8Q"````0``(`````!"@`/(D`O_\ -M)J(`!R0#__@`0Z@DCK(``(ZS``0FM0`()`(`9!(B`.`D`@!$$B(`W@`````D -M`@``)`/__P)"D"0"8Y@D)B+_VS!#`/\L8@!4$$``RP`#$(`\`X`")&,3@`!# -M$"&,0@```$``"``````D!``P`\#X"0+@*"$D!`!X`\#X"0+@*"$D`@`!)`,` -M"*^B`$ROHP!()B+_O#!$`/\L@@`U4$``$J^]`$0\`X`"``00@"1C%-``0Q`A -MC$(```!```@`````/`B``B4($D0"0"`A`F`H(0.@,"$D!P`*#`!NG0`````` -M0+`AK[T`1(^B`$B/HP!``%:`(R8"__\`0X`+CZ(`3!!```,D$0`@%&``.B01 -M`#"/H@!0%$``#H^B`$`"`!`A&$``"B80__\"("`A`\#X"0+@*"&/HP!4`@`0 -M(280__\D8P`!'$#_^*^C`%2/H@!`%$``(@!`("$"P!`A&$``#B;6__^/H@!$ -M`N`H(8!1```D0@`!KZ(`1`/`^`D"("`ACZ,`5`+`$"$FUO__)&,``1Q`__2O -MHP!4CZ(`4%!`_UF"@@```@`0(1A`_U4F$/__)`0`(`/`^`D"X"@ACZ,`5`(` -M$"$F$/__)&,``1Q`__BOHP!4$`#_2X*"```#P/@)`N`H(8^C`%0D8P`!$`#_ -MVJ^C`%0`8"`A`\#X"0+@*"&/HP!4KZ``0"1C``$0`/_`KZ,`5#P(@`(E"!(P -M`D`@(0)@*"$#H#`A$`#_JR0'`!`\"(`"$`#_^24($E`D!``E`\#X"0+@*"$0 -M`/^HCZ(`2(^V`$@6P``%)L;__R06`$`D`@`@`$6P"B;&__\8P/^=``"`(0`0 -M%H`$00`$``````(2*`<0```'`!(GPQ!```0"$R@&`!`0(P!2$`0`HB@E`A(@ -M!S"B``$#L!@A%$```B0$`#$D!``N)A```0(&$"H40/_LH&0``!``_X>OO0!$ -M)J(``R0#__P`0Z@D@K$``P+@*"$FM0`$$`#_``(@("$FH@`#)`/__`!#J"2. -MH@``)K4`!!!``!FOH@!$#`!N@(^D`$100``-/`2``H^C`$2`8@``$$#_<``` -ML"&/HP!$)M8``0!V$"&`0@``5$#__2;6``$0`/]ICZ(`2`P`;?!``_^VOH@!$/`*``A``__PD0A)\)`0`)0/`^`D"X"@A -M`B`@(0/`^`D"X"@ACZ,`5"1C``(0`/]3KZ,`5`9!_RG`!2OJ``@ -MKZD`)*^J`"@,`&[AKZL`+(^_```#X``()[T`,">]__`D`B=T$*(`!*^_``"/ -MOP```^``"">]`!`D`@`!5(+__(^_```,`&T;`````!``__B/OP``)[W_\"0$ -M``&OOP``#`!PAR0%)W2/OP```^``"">]`!`DQO__)`+__Q#"``@`@!@AD*(` -M`"3&__\DI0`!H&(``"0"__\4PO_Z)&,``0/@``@`@!`A),;__R0"__\0P@`& -M`(`8(23&__\D`O__H&4``!3"__PD8P`!`^``"`"`$"$\`X`"C&)&5"1"``$# -MX``(K&)&5#P#@`*,8D94)[W_\!!```:OOP``C&)&5"1"__\00``%```@(:QB -M1E2/OP```^``"">]`!`,`'>$`````!``__H`````)[W_\`"@$"$`P!@A`0!@ -M(0$@:"&OL0`$`6"((0#@6"&OL````(`H(0%`@"$"("`A`$`P(0!@."$!8$`A -M`8!((:^_``@,`'(H`:!0(:X1``"/OP`(C[$`!(^P```#X``()[T`$">]__"O -ML```K[\`!(R#`#0D`@`0$&(`!P"`@"$,`',.`@`@(8^_``2/L````^``"">] -M`!`,`')E`````!``__<`````/`*``XQ$G#0GO?_PK[\```P`=Q\DA``8C[\` -M``/@``@GO0`0/`*``P/@``B,0IPT)[W_\*^_```,`'/B`````(^_```#X``( -M)[T`$">]__``H!`A`,`8(0$`6"&OL0`$`4"((0#@4"&OL````(`H(0$@@"$" -M("`A`$`P(0!@."$!0$`AK[\`"`P`=1(!8$@AKA$``(^_``B/L0`$C[````/@ -M``@GO0`0)[W_\*^_```,`'4:`````(^_```#X``()[T`$">]__"OOP``#`!U -MB`````"/OP```^``"">]`!`GO?_PK[\```P`=:$`````C[\```/@``@GO0`0 -M)[W_\*^_```,`'6W`````(^_```#X``()[T`$">]__"OOP``#`!USP````"/ -MOP```^``"">]`!`GO?_PK[\```P`=>,`````C[\```/@``@GO0`0)[W_\*^_ -M```,`'8,`````(^_```#X``()[T`$">]__"OOP``#`!V,P````"/OP```^`` -M"">]`!`#X``(K*0``#P"@`(#X``(C$)&=#P"@`*,0D9TC$,`#`/@``B,0@`( -M)[W_\`"@$"$`P!@AK[$`!*^P```!`(@A`."`(0"`*"$`0#`A`&`X(:^_``@, -M`'X3`0`@(:X1``"/OP`(C[$`!(^P```#X``()[T`$">]__"OOP``#`!^-P`` -M``"/OP```^``"">]`!`GO?_PK[\``(R"`"@40``$`(`H(8^_```#X``()[T` -M$`P`?<2,A``($`#_^X^_```GO?_PK[\```P`>'$`````C[\```/@``@GO0`0 -M)[W_\*^_```,`'AT`````(^_```#X``()[T`$">]__"OOP``#`!XN@````"/ -MOP```^``"">]`!`GO?_PK[\```P`>1H`````C[\```/@``@GO0`0)[W_\*^_ -M```,`'DW`````(^_```#X``()[T`$">]__"OOP`$K[````P`>5L`H(`AK@(` -M`(^_``2/L````^``"">]`!`GO?_PK[\```P`>5T`````C[\```/@``@GO0`0 -M)[W_\*^_```,`'EC`````(^_```#X``()[T`$">]__"OOP``#`!Y:@````"/ -MOP```^``"">]`!`GO?_PK[\```P`>=\`````C[\```/@``@GO0`0)[W_\*^_ -M```,`'H-`````(^_```#X``()[T`$"0#``4\`H`#K$.<,#P"@`,GO?_PK$"< -M.#P"@`.OL```K[\`!`"`@"&L1)PT/`*``JQ`1E2.`@`0`$#X"8X$`!0,`'-Z -M`````!``__N.`@`0)[W_\`$J$"&OL0`$`("((:XF`!`DA``8`*`P(:XG`!2N -M(@`,KBD``*XJ``2N*0`(`B`H(:^_``ROL@`(K[````P`=]$!`)`A/`*``HQ% -M1G0F,`!(/`:``@(`("$DQM$D#`!^!@(`."$\`X`"E&1&4"0"``2N$0`L)(4` -M`:XB`#0D`@`!KB(`.*X@`#RN(`!XKB``?"8B`("D9490IB0`1"0#``4D8___ -MK$````1A__TD0@`$KC(`F`P`@40"("`A/`2``P(@*"$,`';M)(2]__`!*A`AK[$`!`"` -MB"&N)@`0)(0`&`"@,"&N)P`4KB(`#*XI``"N*@`$KBD`"`(@*"&OOP`,K[(` -M"*^P```,`'?1`0"0(3P"@`*,149T)C``2#P&@`("`"`A),;1)`P`?@8"`#@A -M/`.``I1D1E`D`@`$KA$`+"2%``&N(@`T)`(``:XB`#BN(``\KB``>*X@`'PF -M(@"`I&5&4*8D`$0D`P`%)&/__ZQ````$8?_])$(`!*XR`)@,`(%$`B`@(3P$ -M@`,"("@A#`!V[22$G#P"("`A#`"!*`(@*"&/OP`,C[(`"(^Q``2/L````^`` -M"">]`!`GO?_PK[```"2#`$BOOP`$C&(`*`"`@"$40``4`&`H(3P$@`,"`"@A -M#`!V[R2$G#R.`@`P4$```HX%`"".!0`LC@@`F(X)``"."@`$C@8`$(X'`!0, -M`'(H`@`@(8^_``2/L````^``"">]`!`,`'W$C&0`"!``_^L\!(`#)[W_\*^P -M````@(`A/`2``R2$G#ROOP`$#`!V[P(`*"$\`X`"C&)&5"1"``&L8D94/`*` -M`HQ$1DR,@P"<$'``'CP"@`*,0D9,%&+_^P!@("$\`X`"C&)&5"1"__\00``2 -M`````*QB1E0F!`!(#`!^(*8``$2.!``8)@,`&!"#``>/OP`$C&(`!*R"``2, -M8@`$K&,`!*Q$``"N`P`8C[````/@``@GO0`0#`!WA```("$0`/_M`````#P% -M@`*.`@"]`!`,`'>$`````!``__H`````)`/_^P"`*"&L@``X`$,0)#P$@`,D -MA)P\%$#_[*S"`#0,`'9[`````!``_^@`````)[W_\*^_````@#`A/`*``HQ# -M1E0D8P`!K$-&5(R"`#@00``))`/_^XR"`#0`@"@AK(``.`!#$"0\!(`#)(2< -M/!!```ZLP@`T/`.``HQB1E0D0O__$$``!0``("&L8D94C[\```/@``@GO0`0 -M#`!WA``````0`/_Z``````P`=GL`````$`#_\``````GO?_PK[\``#P"@`*, -M0T94)&,``:Q#1E2,@P!X+&(`"!!```H``Q"`/`.``B1C%?``0Q`AC$(```!` -M``@`````)`(`!*R"`'RL@`!X#`!RW@`````\`X`"C&)&5"1"__\00``%```` -M`*QB1E2/OP```^``"">]`!`,`'>$```@(1``__H`````)[W_\*^_``BOL0`$ -MK[```#P#@`.,<)PT/!&``HXB1E0D0@`!KB)&5(QBG#0D0P!(C&(`*!1``!$` -M8"@AC@(`-#P$@`,D`P`0`@`H(1!#``,DA)P\#`!VJJX#`#2.)$94#`!WA``` -M``"/OP`(C[$`!(^P```#X``()[T`$`P`?<2,9``($`#_[HX"`#0GO?_PK[`` -M`*^_``0\`H`#C$*<-!""`#L`@(`A/`*``HQ#1E0D8P`!K$-&5`P``@`@(3P#@`*,8D94)$+__Q!```8`````K&)&5(^_``2/L````^`` -M"">]`!`,`'>$```@(1``__D`````)(2]`!`,`'3F`````!`` -M__N/OP``)[W_\*^_``",I``L/`.``HQB1E0D0@`!K&)&5(R#`'@L8@`($$`` -M"@`#$(`\`X`")&,6,`!#$"&,0@```$``"``````D`@`'K((`?*R``'@,`'+> -M`````#P#@`*,8D94)$+__Q!```4`````K&)&5(^_```#X``()[T`$`P`=X0` -M`"`A$`#_^@`````0`/_N)`(``R>]__"OOP``/`.``XQBBW`D0@`!`$`@(0P` -M:5BL8HMP$`#_^CP#@`,\`H`#)$*+>`""$",GO?_P``(10Z^P`````H!``@*` -M(0`0$0`"`H`A`!`2``("@"$`$!0``@*`(0`0@",\`H`#)$*,&``02P`\!H`" -M/`B``@$B2"$E"!90```X(20*$``DQM&X)`4`'Z^_``BOL0`$#`!QZP"`B"$\ -M!(`#`B`H(0(`,"$,`';@)(2]`"`60/_X/`*``R1"BW@00/_U -M)%``H#P"@`,D0HMX$@+_\280_V`,`'*$`@`@(1``__H\`H`#)`(``12"_^@D -M`CJ8/`*``R11BW@``(`A#`!T>`(@("$F$/__)`+__Q8"__LF,0"@$`#_W20" -M.I@GO?_P)`0``:^_```,`'2@)`4ZF(^_```#X``()[T`$">]__```"`AK[\` -M``P`=*`D!3J8C[\```/@``@GO0`0`^``"``````\`H`")$+3?*R"```#X``( -MK(``!">]__"OOP``C((`!(R#````8/@)`$`@(8^_```#X``()[T`$">]__"O -MOP``/`*``XQ"G#0`@!@A`*`P(0!`("$,`'0Z`&`H(8^_```#X``()[T`$">] -M__`D`B[@$*(`!*^_``"/OP```^``"">]`!`D`@`!5(+__(^_```\!(`##`!T -MX22$G!@0`/_WC[\``">]__`D!``!K[\```P`=/LD!2[@C[\```/@``@GO0`0 -MK(``%*R%``"LA@`$K(@`"*R)``RLAP`0`^``"*R``!@GO?_PK[\```P`=:$` -M````C[\```/@``@GO0`0)[W_\*^P```\$(`#C@*<+!1```6OOP`$C[\`!(^P -M```#X``()[T`$$`(8````````0`@(3P!__\T(?_^`0%`)$"(8``````````` -M```````PA``!C@.<+(QB`!BN`IPLC&4`%*Q@`!1`"&```````#"$``$!!$`E -M0(A@`````````````````(QB``R,9@`0`$#X"8QD``".`IPL%$#_XH^_``00 -M`/_>C[```">]__"OOP``#`!U(0````"/OP```^``"">]`!!`"&````````$` -M*"$\`?__-"'__@$!0"1`B&``````````````````,*4``8R"`!0\!H`#)$(` -M`:R"`!2,@P`4)`(``1!B``H`````0`A@```````PI0`!`05`)4"(8``````` -M``````/@``@`````C,*<+*R"`!@0`/_TK,2<+">]__`PA``"$(``!:^_```0 -MH``#`*`@(0P`=5,`````/`.``HQB1E0D0O__$$``!0``("&L8D94C[\```/@ -M``@GO0`0#`!WA``````0`/_Z`````(R#```\`H`")$(Q>``#&(``8B@AC*(` -M`#P"@`(D0C)H`&(X(3P"@`(D0C'P`(`P(8RD````8A@A/`*``B1"MIA0@@`# -MC,(`"`/@``@`````K*(``(S"`!"L8@``$`#_^JSF``",@P``/`*``B1",7@` -M`QB``&(X(3P"@`(D0C)HC(4`"(SD````8C`A/`*``B1",?`0A0`#`&(8(0/@ -M``@`````/`*``B1"MIBLX@``K&```!``__FLP```/`2``XR"G"`40``1```` -M`$`(8````````0`8(3P!__\T(?_^`0%`)$"(8``````````````````P8P`! -M/`*``ZQ#G"@D`P`!/`*``ZQ#G"2,@IP@)$(``0/@``BL@IP@/`*``XQ#G"`D -M8___K$.<((Q"G"`40``,/`*``ZQ`G"0\`H`#C$*<*$`(8```````,$(``0$" -M0"5`B&```````````````````^``"`````!`"&````````$`,"$\`?__-"'_ -M_@$!0"1`B&``````````````````,,8``22"__HD`P`!/`6@P`!#&`0L@@`& -M$$``$S2E`!1``V``)`($``""$`0`0!`G`&(8)$"#8`````````````````!` -M"&```````##&``$!!D`E0(A@`````````````^``"`````",H@``,$(``0`# -M$`L0`/_SK*(``$`(8````````0`P(3P!__\T(?_^`0%`)$"(8``````````` -M```````PQ@`!)(+_^B0#``$\!:#``$,8!"R"``800``2-*4`%$`#8``D`@0` -M`((0!`!B&"5`@V``````````````````0`A@```````PQ@`!`09`)4"(8``` -M``````````/@``@`````C*(```!#$"40`/_TK*(``"R"``8D!0`$`((H"T`# -M:``D`@0``*(0!`!`$"<`8A@D0(-H`````````````^``"``````D`B[@$*(` -M`R0"``$#X``(`````!2"__T\`H`#K$"<)!``__H`````)[W_\"0$``&OOP`` -M#`!V0"0%+N"/OP```^``"">]`!`GO?_P```@(:^_```,`'9`)`4NX(^_```# -MX``()[T`$"0#``$\`H`"K$-&5"0%`!\D@P`$)*7__R0"__^L8```%*+__"1C -M``0D`P`%/`*``ZR```"L0YPP)`,``3P"@`,#X``(K$.<.">]__"OOP`$K[`` -M``"`@"$,`&DQC(0````"$(`"`H`AC@,`!(^_``2/L```)&+_Z``#$`H#X``( -M)[T`$">]_^"OL@`(K[$`!*^P``"OOP`0K[,`#(RS`"",HP`D`("`(0`3$(`` -MH)`A`&`@(11@`!X"`H@ACB(`!"9#`!@``"`A`'(@"R0#``$40``$`F,8!(X" -M````0Q`EK@(``(XC``148``+C&(`!*XD``0,`';1`D`@(8^_`!"/LP`,C[(` -M"(^Q``2/L````^``"">]`""L@P``K((`!(QB``2L9``$$`#_\JQ$```,`'=F -M`````!``_^&.(@`$C*<`("2C`!@`!1@*``<0@`"","&,P@`$`&`H(1!B`!(D -MR``$C&(``(QC``2L0P`$C*,`!*RE``2L8@``K*4``(T"```40``&)`(``8R# -M````XA`$``(0)P!B&"2L@P```^``"`````!08/_VC0(``(QC``!09?_RK,`` -M!(RB``2L8@`$C*(`!*RE``2L0P``K*4``!``_^JLPP`$/`6``XRCG#2,@@`@ -MC&,`(`!#$"H40``%)`,``8RBG#2,0@`T$$```P`````\`H`#K$.<.`/@``@` -M````/`*``R1"G#0`!C"``,(P(2>]__``H"`AK,4``*^_```,`',.`````(^_ -M```#X``()[T`$`/@``@``````^``"``````\`X`#C&*<,">]__"OOP``)$+_ -M_Q!```2L8IPPC[\```/@``@GO0`0#`!V_P`````0`/_[C[\``#P%@`.,HYPP -M/`*``Q1@`!:,1)PTC((`-!1``!,\`H`#C(,`("1"G#P``QB``&(8(8QB``10 -M0``$C&,`!(Q"``"L8@`$C&,`!"1B_^@``Q`*$$0``R0#``$\`H`#K$.<."0" -M``6LHIPP`^``"`````"LA0`(K(0`!`/@``BLA```)[W_\*^_```\`X`"C&)& -M5"1"``&L8D94)(3_Z(R"`#040``1/`*``XR#`"`D0IP\``,8@`!B&"&,8@`$ -M4$``!(QC``2,0@``K&(`!(QC``0D8O_H``,0"A!$``HD`P`!/`*``ZQ#G#@\ -M`H`"C$1&5`P`=X0DA/__C[\```/@``@GO0`0)`,`!3P"@`,0`/_VK$.<,(R& -M```DH@`8```8(13```0`11@+K(,```/@``BLI``DC,(`!*QF``"L8@`$C,(` -M!*S#``00`/_XK$,``(R#```08``,)&+_Z(QE``!0HP`)K(```(QB``2LH@`$ -MC&(`!*QC``2L10``K&,``*R%```D8O_H``,0"E1```&L0``D`^``"`````"L -MH``DC(,``"2B`!@`!1`*$$,`"@!`*"&,0@``C*,`!*Q#``2,HP`$K*4`!*QB -M``"LI0```^``"``````00/_]`````(Q#```08@`)`````(Q"``2L8@`$C*(` -M!*RE``2L0P``K*4```/@``BL@P```^``"*R````GO?_PK[$`!*^_``ROL@`( -MK[````"`B"$6(``%/!*``SP"@`.,0IPL%$``+P````".4)PTC@(`-!1```0\ -M`H`#C$*<.!!``!,`````/`2``PP`=FPDA)P\$@(`"0!`("$\`X`#C&*]`!`\`H`"K%%&5!``__B/OP`,#`!U3#P2@`,0 -M`/_/`````">]__"OOP``#`!WQ@`````\!(`#)[W_\*^_```,`'9L)(2]__"OL````,`H(:^_``0,`'<;`("` -M(:X``!BN```,K@``$(^_``2/L````^``"">]`!`GO?_PK[$`!*^_``ROL@`( -MK[```(R2``@`@(@A`+(0*A1```]`!`,`'/B`````!``__N/OP``)[W_\*^_```` -MH#`A#`!WWHRE`""/OP```^``"">]`!`GO?_PK[\```P`=_8`````C[\```/@ -M``@GO0`0)[W_\*^_```,`'@"`````(^_```#X``()[T`$">]__"OOP``#`!W -MW@``,"&/OP```^``"">]`!`GO?_PK[\```P`>`(`````C[\```/@``@GO0`0 -M)[W_\"0"*OBOL0`$K[```*^_``@`H(@A$*(`%@"`@"$D`BKX$B(`!@````"/ -MOP`(C[$`!(^P```#X``()[T`$!8`__H\`H`#)%&]__`D!``!K[\```P`>#PD!2KXC[\```/@``@GO0`0 -M)[W_\```("&OOP``#`!X/"0%*OB/OP```^``"">]`!"LA0```^``"*R```0G -MO?_PK[$`!*^P``"OOP`,K[(`"#P"@`,`@(`AC%*<-"01``$\`X`"C&)&5"1" -M``&L8D94C((``!!``!<\!(`#$B``!`````".`@``)$+__ZX"```\`X`"C&)& -M5"1"__\00``)`````*QB1E0"(!`AC[\`#(^R``B/L0`$C[````/@``@GO0`0 -M#`!WA```("$0`/_V`````(R#G#0D`@`!K&(`>(R"G#0,`'*ZK$``?`)`*"$, -M`'=$)@0`!#P"@`(,`'>$C$1&5(Y#`'PH8@`$%$``!BAD``94@``$``"((20" -M``808@`(`````(X"```40/_3`````!8@_^<\!(`#$`#_U``````,`'-Z```` -M`!``__>.`@``)[W_X*^Q``2OOP`0K[,`#*^R``BOL```/`6``P"`B"&,LIPT -M/`.``HQB1E0D0@`!K&)&5(RCG#0D`@`#``!`(0``2"&L8@!XC**<-*Q``'R, -MI)PT#`!^-R2$`$B.0@!\CB,``!1@``,L4``!%@``(CP#@`,\`H`#C$*<-"1% -M`$B,H@`H%$``&``````2```$`````(XB```D0O__KB(``#P#@`*,8D94)$+_ -M_Q!```H`````K&)&5`(`$"&/OP`0C[,`#(^R``B/L0`$C[````/@``@GO0`@ -M#`!WA```("$0`/_U``````P`?<2,I``($`#_Y@````",8IPT)!,``ZQ3`'B, -M8IPT#`!RNJQ``'PF)``$#`!W1`)`*"$\`H`"#`!WA(Q$1E2.0P!\*&(`!A!` -M``TD`@`&*&(`!%!```,``(`A4',``0``@"&.(@``%$#_R3P"@`,6`/_G/`.` -M`Q``_\4`````5&+_^8XB```,`'-Z`````!``__6.(@``)[W_\*^P``"OOP`$ -M)!```3P"@`*,0T94)&,``:Q#1E2,@@``&$``$21#__^L@P``/`.``HQB1E0D -M0O__$$``!P``("&L8D94`@`0(8^_``2/L````^``"">]`!`,`'>$`````!`` -M__@`````$`#_\```@"$GO?_PK[\`!*^P````@!@A/!"``HX"1E0D0@`!K@)& -M5(R"``",A0`$)(0`!"1"``$4H``.K&(``(X"1E0D0O__$$``!@``("&N`D94 -MC[\`!(^P```#X``()[T`$`P`=X0`````$`#_^0`````,`'=3`````"0#``>L -M0`!XK$,`?`P`]__"OOP``#`"!:B2$``B/OP```^``"">]`!`GO?_@K[,` -M#*^Q``2OOP`0K[(`"*^P```\`H`#`("((8Q2G#0D$P`!/`.``HQB1E0D0@`! -MK&)&5(R"``Q00``&CB,`#"9#`!B,8@`0)$(``:QB`!".(P`,)`(``E!B`%F. -M)0`0DB(``!1``"X\`X`#4F``%HXB``PD`@`!KC(`!*(B```\`X`"C&)&5"1" -M__\00``*`````*QB1E0"8!`AC[\`$(^S``R/L@`(C[$`!(^P```#X``()[T` -M(`P`=X0``"`A$`#_]0````!00``&CB,`#"9#`!B,8@`0)$+__ZQB`!".(P`, -M)`(``1!B``D`````CB,`#"0"``(48O_A``````P`>#4F1``8$`#_W0`````, -M`'@G)D0`&!``__:.(P`,C&*<-"00``&L4`!XC&*<-`P`"XF -M1``8$`#_I0`````GO?_PK[```*^_``0`@"@A)!```3P"@`*,0T94)&,``:Q# -M1E20@@``5$``$```@"$\`H`#C$*<-(R#``R@L```)$8`&`#`("$08``$K*(` -M!(S"`!`D0@`!K,(`$(RC``PD`@`"$&(`$``````\`X`"C&)&5"1"__\00``' -M```@(:QB1E0"`!`AC[\`!(^P```#X``()[T`$`P`=X0`````$`#_^``````, -M`'@NC*4`$!``_^X`````)[W_\*^P``"OOP`,K[(`"*^Q``0`@(`A/`*``HQ# -M1E0D8P`!K$-&5(R"``@40``K))(`"(X"``Q00``'C@,`#(X#``0D8P`8C&(` -M$"1"__^L8@`0C@,`#"0"``%08@`;C@0`!(X#``PD`@`"4&(`$XX$``2N```$ -MH@```#P#@`*,8D94)$+__Q!```@`````K&)&5(^_``R/L@`(C[$`!(^P```# -MX``()[T`$`P`=X0``"`A$`#_]P`````,`'@U)(0`&!``_^RN```$#`!X)R2$ -M`!@0`/_DC@,`#`P`=U,"0"`AC@,`#`!`B"$D`@`!4&(`"(X%``0D`@`'KB(` -M?*X@`'@,`'+>`B`@(1``_\J.`@`,)B0`&`P`>"`"0#`A$`#_]B0"``]`!`GO?_````H(20&`"ROL``PK[\` -M-`P`<*H`@(`A)`+__Z.B`"BOH@``KZ(`!*^B``BOH@`,KZ(`$*^B`!2OH@`8 -MKZ(`(*^B`"0\`H`"C$1&6*.@`!P\`X`"C&)&5"1"``&L8D94`Z`P(0P`@/4D -M!0!>#`"!S`````"/H@`$7$```:X"``"/H@`(7$```:X"``2/H@`,7$```:X" -M`!R/H@`07$```:X"`""/H@`87$```:X"`"@"`!`AC[\`-(^P`#`#X``()[T` -M0">]__`T`K>8K[$`!*^P``"OOP`(`*"((1"B``\`@(`A-`*WF!(B``6/OP`( -MC[$`!(^P```#X``()[T`$%8`__N/OP`(/`2``PP`@>4DA)S$$`#_]H^_``@\ -M!8`#)*6B(#P&@`0\!(`#)`(``0#%,",DA)S$%@+_Z@``."$,`(';`````!`` -M_^8)[W_\"0$``&OOP``#`!ZIS0%MYB/OP```^``"">]`!`GO?_P```@ -M(:^_```,`'JG-`6WF(^_```#X``()[T`$)""``PPI?__``4:`C1"`("@@@`, -M,$(`?Z"#``2@A0```^``"*""``PGO?_P/`6@P#P&__ROOP`$K[```#2E`"`0 -M@``;-,;__XR#```D`@`#-&,``P!@@"&L@P``C*,```!F&"2LHP``H@``!`P` -M:^2B`@`,/`,;3C1C@;4`0P`9`@`@(0``$!```A."#`!ZV@!`*"$D`@`'H@(` -M"(^_``2B```$C[````/@``@GO0`0/`*``A``_^0D1$9@$(``$#"E`/^,A``` -M`X`8(3P<@`,GG,:PD((`%#!"`"`00/_]`````*"%``"0@@`4,$(`(!!`__T` -M`````^``"`!@X"$\`H`"$`#_[R1$1F`0@``,/`*``HR$`````!@AD((`%#!" -M``$00``$`````)""```D`P`!H*(```/@``@`8!`A$`#_]"1$1F`GO?_@K[`` -M$*^_`!BOL0`4`("`(0.`B"$\'(`#)YS&L!"```T\`H`"`@`@(0P`>QT#H"@A -M$$#__0(`("$"(.`ADZ(``(^_`!B/L0`4C[``$`/@``@GO0`@$`#_\R101F`G -MO?_@K[(`"*^Q``2OL```K[\`$*^S``P`@(@A`*"0(0#`@"$#@)@A/!R``R>< -MQK`0@``5/`*``@(`$"$40``))A#__P)@X"&/OP`0C[,`#(^R``B/L0`$C[`` -M``/@``@GO0`@DD4```(@("$,`'L))E(``0(`$"$40/_Z)A#__Q``__`````` -M$`#_ZR111F`GO?_@K[(`"*^Q``2OL```K[\`$*^S``P`@(@A`*"0(0#`@"$# -M@)@A/!R``R>]`"`0`/_B)%%&8">]_\"OL@`(K[\`$*^S``ROL0`$K[```*^F`"BOIP`L -MKZ@`,*^I`#2OJ@`XKZL`/```D"$#@)@A/!R``R>]`$`TA``4C(,``"8B__H`11`$`&(8)1``__&L@P``C[``*`P`:^2, -MD0````(1`@!0`!M2```!```!S9(C``0"("`AHB``!#!P`/\``!`2,$+__PP` -M>MH`0"@AHC``!!``_]\`````C(,``#P"@`*,4D9LK$!&;)!B``0P4`#^H'`` -M!(R1``@J(@`&$$``"SP$H,!``V``)`($``(B$`0`0!`G`&(8)$"#8``````` -M`````!``_\H`````-(0`%(R%```F(__Z)`(``0!B$`0PHP`!```H(0!B*`H0 -M`/_`K(4``!``_[Z,D@`(C)(`!(^B`"@0`/^ZK((`!!``_YPD1$9@)[W_X*^P -M`!"OOP`8K[$`%`"`,"$`H(`A``!`(0.`B"$\'(`#)YS&L!"``"8D!P`$C,0` -M""B"``8`XB`*0`-H`"0"!```@A`$`$`0)P!B&"1`@V@````````````````` -MC,8```.@("$D!0`!D,(`"#!#``X09P`+K@```"0"``P08@`(``````(@X"&/ -MOP`8C[$`%(^P`!`!`!`A`^``"">]`""0P@``#`!MEJ.B```00/_U)`@``20" -M``$0`/_RK@(``#P"@`(0`/_9)$9&8">]__`\`H``K[(`"*^_``ROL0`$K[`` -M`"1"`P",0@`T`$#X"20$__\`0)`A/`*``HQ$1F@D`@`!/`6@P"2#__H`8A@$ -M*((`!A!``#,TI0`40`-@`"0"!```@A`$`$`0)P!B&"1`@V`````````````` -M````/!"``B801F`\$8``)C$#``P`>N0"`"`ACB(`-`!`^`D``"`ACB,`%#P" -M@`(D0NT0K'```*QB``0\`H`")$+MH*QB``@\`H`")$+L)*QB``P\`H`")$+L -ML*QB`!`\`H`")$+NX*QB`!0\`H`")$+PO*QB`!@\`H`")$+N,*QB`!R.(@`T -M`$#X"0)`("&/OP`,C[(`"(^Q``2/L````^``"">]`!",H@``,$(``0`#$`NL -MH@``$`#_TSP0@`(\`X`"C&)&<">]__`00``$K[\``(^_```#X``()[T`$"0" -M``$,`'QCK&)&]_]"O -ML@`8)`+__R2R__^OL0`4K[\`(*^S`!ROL``0$D(`:P"`B"$\`X`"C&)&5"1" -M``&L8D94CB0`"(XE``R.(P`0```0(0""("$`HR@A`*,P*P"&("$GLP`(KB0` -M"*XE``P"8"`A`B`H(:^@```,`((1KZ``"(^P``@2```B`B`@(5(```R.`P`8 -MC@,``%!P``BOH``(C@(`!*QB``2.`@`$KA``!*Q#``"N$```KZ,`"(X#`!B. -M(@`(`$,0*U1``&./HP``CB(`"%!B`%F.`P`]`!`,`'>$```@ -M(1``__@`````C@(`&(X#`!R.!@`@C@<`)`!G&"$`9R@K`$80(0!%$"&N`@`8 -MK@,`'`P`?ED"`"`ACB,``%1@``.,8@`$$`#_X:XP``"N`P``K@(`!(QB``2L -M<``$$`#_VZQ0``",@@`,`$,0*U1`__..(P``C((`#!``_\B.`@`,)[W_\*^_ -M```\`H`"C$-&5"1C``&L0T94C((``!"B`!8`````C*(``(RC``2L0P`$C*,` -M!*RE``2L8@``K*4``*R@`"@\`X`"C&)&5"1"__\00``%```@(:QB1E2/OP`` -M`^``"">]`!`,`'>$`````!``__H`````4*#_\JR@`"B,HP``4&7_[JR```", -MH@`$K&(`!(RB``2LI0`$K$,``*RE```0`/_FK(,``">]_^"OI0``)`4``:^_ -M`!2OL``0KZ8`!`P`?+P`@(`ACZ(``(^_`!2N`@`4CZ(`!*X"`!B/L``0`^`` -M"">]`"`GO?_PK[\```P`?,,`````C[\```/@``@GO0`0```0(0``&"&LA0`( -MK(8`#*R'`!"L@``HK(0`!*R$``"L@@`8K(,`'*R"`"`#X``(K(,`)```$"$` -M`!@AK(4`"*R&``RLAP`0K(``**R$``2LA```K((`&*R#`!RL@@`@`^``"*R# -M`"0GO?_PK[```*^_``2,@@`H`("`(11```T`@"@AC@,``!!P``>/OP`$C@(` -M!*QB``2.`@`$KA``!*Q#``"N$```C[````/@``@GO0`0#`!]Q(R$``@0`/_R -MC@,``">]_^"OM0`0K[0`#*^S``BOL@`$K[```*^_`!2,@@`H`("`(0"`*"$` -MP)`A`."8(0$`H"$40``0`2"H(8X$``BN$@`8KA,`'*X4`""N%0`D#`!]=@(` -M*"&/OP`4C[4`$(^T``R/LP`(C[(`!(^P```#X``()[T`(`P`?<2,A``($`#_ -M[XX$``@GO?_@K[(`"*^_`!2OM0`0K[0`#*^Q``2OL```C((`((R*`"0`0%@A -M`$H0)1!``!H`@)`AC((`"(R0`"",D0`DC)0`&(R5`!R,0P`,C$(`"`(`,"$` -M<1@A`'$@*P!0$"$`1!`A`%1`(P!U("L!!$`C`'5((R4E__\LHO__)03__P"" -M("$!:!`K%$``#0(@."$1:``)`4D0*X^_`!2/M0`0C[0`#(^R``B/L0`$C[`` -M``/@``@GO0`@4$#_^(^_`!0,``-$``````(C`!D``"`0```H$@*E."$````` -M`(``$W(B````Y1`K`.`H(7!P`````"`2`H0P(0#","$`P"`AKD0`&*Y%`!P0 -M`/_DC[\`%">]_^`\`H`"K[\`%*^P`!`D0T9XC&,`!(Q"1G@`@(`A`&`P(0!` -M*"&OHP`$#`!][Z^B```\"(`"/`F``B8$`!PE"/LD)2G[="0%``4D!@`!#`!U -M$@(`."$,`&OO`````#P#@`*L8D?<0(!(`````````````````$""6``````` -M```````````,`'6()@0`'`P`=@PD!``%/`*``JQ01G2/OP`4C[``$`/@``@G -MO0`@)[W_\*^_```,`&OO`````#P#@`*L8D?<0(!(`````````````````$"" -M6``````````````````,`'8S)`0`!8^_```D`@`#`^``"">]`!`GO?_PK[\` -M``P`?-@`P"`A/`2``PP`=O$DA)P\C[\```/@``@GO0`0)[W_\"0"-K"OL0`$ -MK[```*^_``@`H(@A$*(`$0"`@"$D`C:P$B(`!CP"@`./OP`(C[$`!(^P```# -MX``()[T`$!8`__HD4:#8#`!U&B8D`!P,`'W_`B`@(1``__6/OP`()`(``52" -M_^\D`C:P/`2``PP`?ITDA*#8$`#_ZB0"-K`GO?_P)`0``:^_```,`'[G)`4V -ML(^_```#X``()[T`$">]__```"`AK[\```P`?NMC@`8`.@8(8QB``0DZP`(-$(``1``_]NL8@`$+0("`!!``((` -M"!I"``@@P@`$$,`!@A`A)$H`"(V#``R-20`(``0@@B0"``$`@A`$`&(8):V# -M``RLZ@`,K.D`"*TG``RM1P`(*6,``"5B``,!8Q`*C88`#``"$(,D`P`!`$,@ -M!`#$$"M40``[C80`$`"&$"040``,``L0P``$($`D`O_\`6(0)`"&&"048``% -M)$L`!``$($``AA`D$$#__25K``0`"Q#``8(0(21)``@!8&@A`2!0(8U'``Q0 -MZ@`.)6L``8SB``0D`__^`$-`)`$%,",HP@`04$``/XSI``@$PP`U`.@8(8SG -M``Q4ZO_WC.(`!"5K``$Q8@`#%$#_[B5*``@QH@`#)2G_^!!``"4EK?__C2(` -M"!!)__LQH@`#C8,`#``$($``9!`K5$``"HV$`!`0@``'`(,0)%1`_]H`"Q#` -M``0@0`"#$"00`/_[)6L`!(V$`!`D`__^C((`!`!#$"0`11@K%&``!`!%,",H -MP@`04$```P"`."$0`/]Z``!8(33#``$`A2`A-*(``:SB``2MA``0K(,`!!`` -M_W(DZP`(C8(`#``$&"<`0Q`D$`#_VZV"``R,8@`$C.H`#(SI``@T0@`!).L` -M"*QB``00`/]DK4D`"(SJ``P`Y4`A-*(``0$&&"$TQ``!K4D`"*SB``2MB``8 -M).L`"*QF``"M!``$K0X`"!``_W*M*@`,$&``!@`((,(L8@`%$$``'BQB`!4` -M"!&")$0`.``$$,`!@A`A)$H`"(U)``@1*@`1)(,``XTB``0D`__^`$,0)`$" -M$"M00/]XC2H`#(TI``@1*@`&)`/__HTB``0`0Q`D`0(0*U1`__J-*0`($`#_ -M;HTJ``PH@@```&(@"XV#``P0`/]E``0@@Q1`_^0D9`!;+&(`51!```0L8@%5 -M``@3`A``_]XD1`!N$$``!"QB!54`"!/"$`#_V21$`'=00/_7)`0`?@`(%((0 -M`/_4)$0`?!!@``8`!5C"+&(`!1!``!TL8@`5``41@B1+`#@`"Q#``8(0(21* -M``B-1P`,4.K_'25K``&,X@`$)`/__@!#0"0!!3`C*,(`$%!```8E:___!,,` -M!@#H&"&,YP`,5.K_]XSB``00`/\/)6L``8QB``2,Z@`,C.D`"#1"``$0`/[_ -M).L`"!1`_^4D:P!;+&(`51!```0L8@%5``43`A``_]\D2P!N$$``!"QB!54` -M!1/"$`#_VB1+`'=00/_8)`L`?@`%%((0`/_5)$L`?`"`6"$0H`!````8(22I -M__B-)@`$)`+__HR$`!``PD`D`2A0(8U#``011`!U`&(8)#C"``$P0@`!K4,` -M!!!```H``&`AC*7_^"5B`!`!)4@CC20`"!""`&@!!4`AC2<`#*SD``BLAP`, -M`4,0(9!"``]_]"OL@`8K[\` -M**^U`"2OM``@K[,`'*^Q`!2OL``0`("0(3P"@`*,0T94)&,``0P`@&6L0T94 -M`$"H(8Y"!!`00``:)E0$$*^@```,`'=3`H`@(8Q3`$`"0"`A`$"`(0P`?S2. -M90```$"((0(`("$00``L`@`H(20"``>N`@!\#`!RWJX``'BN<0`$CD($$%1` -M_^XF5`00CZ(``!1``!<`````#`"!:@.@("$\`X`"C&)&5"1"__\00``,```` -M`*QB1E0"H!`AC[\`*(^U`"2/M``@C[,`'(^R`!B/L0`4C[``$`/@``@GO0`P -M#`!WA```("$0`/_S``````P`=U,#H"`A`$`H(0P`=T0"@"`ACZ(``!1`__D` -M````$`#_X0`````,`'=$`Z`@(1``_]B.0@00)[W_\*^_```\`X`"C&)&5"1" -M__\00``%```@(:QB1E2/OP```^``"">]`!`,`'>$`````!``__H`````)[W_ -M\*^P``"OOP`$#`!_%P"`@"&N``00C[\`!(^P```#X``()[T`$">]__"OL``` -MK[\`#*^R``BOL0`$`("`(3P"@`*,0T94)&,``:Q#1E2,@@00))($$!1``!," -M0(@A/`.``HQB1E0D0O__$$``"@````"L8D94#`"!:@)`("&/OP`,C[(`"(^Q -M``2/L````^``"">]`!`,`'>$```@(1``__4`````#`!W4P(@("$D`P`%K$,` -M?*Q``'@,`'+>`$`@(8X"!!`40/_W`````!``_^,`````C*<``!#@``8`@!@A -MC(8``%3```6,X@`$K(<``*R@```#X``(`````(S$``2LP@`$C&,``*SD``2L -M0P``$`#_]ZR'``!-96UO6YC179T1&ES<&%T8VA,;V]P`````%1A0@`!8 -M*(``6%2``%AH@`!9%(``68R``%H@@`!:/(``6G"``%J$@`!:F(``6JR``%L( -M@`!;6(``5^"``%N8@`!7X(``5^"``%?@@`!7X(``5^"``%NP@`!;V(``6_R` -M`%PT@`!D@`!X`"1)9#H@+R]D97!O="]S=R]B -M`Y*#`[``0Q`C +M)$+__Q``_PNB`@`]``(8P`!B&",``QB``'08(8QB`"P01/[Y`````!``__62 +M@@`#)[W_L``*5@`Q:P#_K[<`/*^V`#BOM0`T`("P(:^T`#"OL0`D`*"H(:^_ +M`$2OO@!`K[,`+*^R`"BOL``@`,"((:^H```!(*`A``J^`PP`.H@!8)K``E!!@``2,4P`\ +M)`(``5""`8^28@.O`!'P0`/0D"&21``!CZ,``#""`/\08`$CKZ(`#"0"``$0 +M8@$9)(,`(Y("`#PF)0`!`*(0*A!``!H`!1#``$40(P`"$(``4Q`A``480`!P +M("$D1@`L`!$0P`!1$",``A"``%,0(8Q#`"R,P@```]`X(22E``$40P`*),8` +M')#C``&0@@`!`$,0*U1```&@@P`!D@(`/`"B$"H40/_N)(0``EH@`!62`@`^ +M@@(`)H($`"<`$1A``'`H(21"__X`1!@J@*8```"#$`L``A8```(>`R3"``(` +M0Q`J$$``Y9"D```D@@`$H*(``"0$``&B$0!]`%`0`/^3H,(``#(F`/\F +M!P`]#`!3R0)@("&/I0`($`#_2JX%`%@D8P`"`,,0*A!`_QHD@@`"$`#_&:"C +M```P8@#_+$(`911`_N6B0P`!)`(`9!``_N*B0@`!*H,`"B0"``D`0Z`*/`*` +M`B1"4[``%!B`CZ4`#`!B&"&,8P````40P@""$",``QC"`$,0(:)"``&/J``$ +M`L`@(0*@*"$"@#`A#``RY@+@."&2`@`HD@,`)I(%`#ZB`@`IH@,`**(7`":/ +MH@`(,*0`_Q"```.N`@!0$)$`-2J"``)>@/\'`!&00)(#`%TD`@#_$$,``B1B +M``&B`@!=`!$0P`!1$",``A"``%,0(21'`#"`X@`(`N(0*E1`_OD`$9!`C@(` +M,%(B``6.`@`LKA$`,*X``"RN```TC@(`+(X#`#0D0@`!`'<@(2A#``2N!``T +M%&#^ZJX"`"RN```LK@``-`/0*"$D@@`"@*8``"A#```DA``%`(,0"P`"$(,D +MPP`"`$,0*A!```>0HP``@.(`"`!&$"H00``$)`0``21B__^@H@``)`0``1`` +M_M2OI``05$```Z(%`#T0`/_)H@``/I)"``$L0@`N5$``!*(``#XD`@`4HD(` +M`:(``#Z.8@.DCZ,`"``"$$(`8A`C$`#_O*X"`%@D0@`!`B(0*A!`_G``$?!` +MDF(#L``10,`!$1@C`B(H(0`%$,``11`C``,8@``"$(``]`"`0`/_Y`.`0(12@``,``````^`` +M"*R`!:@$H@`,C(,<(!B@``8D`@`%C(,<(%!B``2,@@6H`^``"`````",@@6H +M`$40(0/@``BL@@6H)`(`!11B__,`````$`#_]@`````DI?__)[W_X"RB`".O +MM0`4K[0`$*^R``BOL0`$K[```*^_`!BOLP`,`("((0#`D"$`X(`A`0"H(1!` +M``L``*`A/`.``@`%$(`D8Q98`$,0(8Q"````0``(``````P`+'$`X"@A`$"@ +M(5:@``&NM```C[\`&(^U`!2/M``0C[,`#(^R``B/L0`$C[````/@``@GO0`@ +M$`#_]*XG&]RN)QPX$`#_\:R`&]P0`/_OKB<;S!``_^VN)QMH$`#_ZZ8G&^`0 +M`/_IKB<;Y!``_^>L@`6H$`#_Y:XG&]@0`/_CKB<;N!``_^&B)QN_$`#_WZ(G +M&^D0`/_=KB<;T"2$&Z8,`'(``.`H(1``_]@`````/!.``XYDFE00@``&/`*` +M`XQ"FE@01@`*``````P`>\T`````#`![N@)`("&N8II4/`*``ZQ2FE@\$X`# +MCF2:5%2```,"`"@A$`#_Q"04``(,`'(``D`P(8YBFE00`/^_KB(<`!``_[VN +M)QML$`#_NZXG&\`0`/^YKB<;H!``_[>F)QO($`#_M:8G&\00`/^SIB<;QA`` +M_[&F)QO*,.(`_Q``_ZZL@ALX,.(`_Q``_ZNL@AL\$`#_J:XG&S2,@@`$`.`H +M(0P`&>2,1```%$```@!`H"&N,!OP$`#_H*XP&^P0`/^>KB<=U">]__"OL``` +MK(4;"`"`@"&OOP`$#``4<20%``&.!1L(#``LO0(`("$"`"`A#``4<0``*"&/ +MOP`$C[````/@``@GO0`0)[W_\*^_```,`&RO`````(^_```#X``()[T`$">] +M_]"OL0`$K[````"@B"$`@(`A/`6``*^_`"2OO@`@K[<`'*^V`!BOM0`4K[0` +M$*^S``ROL@`(`."8(3#2__\!`*`A`2"H(0%`\"$!8+`A#``IAH^W`#0,`'+> +MC@08"`(`("$``"@A```P(0P`+.T``#@A%N``$P`6*"LR(S<`)`(E`*82&W"F +M$QN`HA0;@J(5&X.N$1MT$&(`8```*"$D`A4`4&(``20%``&.!!A`#`!RWJX% +M&`0,`',E)@07[``6*"L,``I(`@`@(0P`")4"`"`A#`!REP`````,`'(8```` +M`"8%&W`#P#`A#``WV`(`("&/HP`P$L``.:QB```,`'(=``````P`]_^`LH@`/K[4`%*^T`!"OLP`,K[(`"*^Q``2OL```K[\` +M&`#`H"$`X(`A`0"H(0``B"$``)`A$$``4@``F"$\`X`"``40@"1C%N0`0Q`A +MC$(```!```@`````$.``'202`-``X!@A)((;'"2%&UR,1@``C$<`!(Q(``B, +M20`,K&8``*QG``2L:``(K&D`#"1"`!`41?_V)&,`$"2#&_@F`@!`)(0;:(R% +M``",A@`$C(<`"(R(``RL10``K$8`!*Q'``BL2``,)(0`$!2#__8D0@`0%F`` +M!P`````60``#`````%8```&N$0``5H```:Z2``!6H``!KK,``(^_`!B/M0`4 +MC[0`$(^S``R/L@`(C[$`!(^P```#X``()[T`((R"&W00`/_K``*+`A``_^F4 +MD1MP$`#_YXR1&RP0`/_EC)$;,!``_^.,D1M($`#_X8R1&TP0`/_?C)$;4!#@ +M_]TD$@`&)(4;K"0&``8,`'(``.`@(1``_]<`````$`#_U8R1&U00`/_3)!,` +M#A#@_]$D$@`0`.`H(0P`+%LD!@`0$`#_S``````0`/_*C)$;\`"`."$``#`A +M$*``"```&"$`QQ`&),8``3!"``$``QA``,4@*Q2`__H`8A@E`^``"`!@$"$G +MO?_PK[(`"*^Q``2OL```K[\`#(RB`$PDL``(`*"((9!*`$",2P`\K*``'(RC +M`!P`"A#``$H0(P`"$("LHP`8`$M`(9$%`#2.`P`,C@<`!"0"_^``8A@D,*4` +M'R0"[_\`XC@D`&48):X'``2N`P`,C0,`+"0"``,`@#@A$&(`*P#`D"&.`P`( +MC@0`!#P"__`T0O__`&(8)#P"`0``@B`E/`(``0!B&"6N!``$K@,`"(XB``@\ +M`P`_/`3A_P!#$"4TA/__,D,`#P!$$"0``QY``$,0):XB``B.`@`$/`/_#S1C +M__\`0Q`D/`,`,`!#$"4\`P8``$,0):X"``2.(@`(CB0`)#P#`(``0Q`EKB(` +M"*XD``"/OP`,C[(`"(^Q``2/L````^``"">]`!".(@`(/`.``#P%_@\`0Q`E +MKB(`")"$'02,YAQ8C@,`#``$$,``1!`C``(0@`!&$"&00@`T-*7__P!E&"0P +M0@`?``(5``!B&"6N`P`,C0,`+#P"@`*0Y!W,)$)3H``#&(``8A@ACB4`")3H +M'=*,8@````1(0`$D2"$PI0__`6`@(0%`,"$`0/@)```X(8X#``@D!(``,$)_ +M_P!D&"0`8A@E$`#_K:X#``@GO?_@K[``$`"@@"$#H"@AK[$`%*^_`!@,`"WP +M`("((5(```$```'-CZ,`!(^B```T"8````,=@``"$H(`8A@E`'`X(0#P$"$D +M0O__`%``&XXC``"6)1N&-`B```!I&"$R"O__```0$@``````````<%`X`JQG +M`"B.(@````<8P"1F__P`21`AK$8`+(XB```D9O^P`.4@(0!)$"&L1@`PCB(` +M`"3C``$`92`*`$@0(:Q$`#2.(@``/`,`@`(#,"4`2!`AK$8`((XB&XP00``A +MC[\`&(XB``".)1N4`$@0(:Q*`0".)```CB,;C`"(("&,@@$```,<`#!"__\` +M0Q`EK((!`(XB&Y".(P```.(0(0!H&"$P0O__K&(`_!"@``>.(@``/`0``@!( +M$"&,0P#\`&08):Q#`/R.(@``/`0``0!)$"&,0P#\`&08):Q#`/R/OP`8C[$` +M%(^P`!`#X``()[T`(">]_]"OL@`(,)(`_Z^W`!ROM@`8K[4`%*^T`!"OLP`, +MK[```*^_`""OL0`$`*"@(0#`J"$`X+`A`0"X(0$@@"$!0)@A$D``#"0"``&/ +MOP`@C[<`'(^V`!B/M0`4C[0`$(^S``R/L@`(C[$`!(^P```#X``()[T`,`P` +M>[HD!``L`$"((1(@__$D`@`"`B`@(0``*"$,`'(-)`8`+"0"``*N\0``/`:` +M`:("```D`@`*)B@`&"3&;X@``"`A```H(0(@."&B8@``KC0`!*XU``BN-@`, +M#`!AO*(@```,`'NZ)`0%$`!`@"$00``JKB(`%`!`("$``"@A#`!R#20&!1`F +M!P`(K@<`#*X0``2,Y@`$K@``"*X````"`"`A```H(22E``$D@@`0+*,`0*R` +M`!"LP@``)(0`%!1@__D`0#`A`B`@(0)`*"$,`&"3K.(`!!1```,`````$`#_ +MO```$"$,`&&K`B`@(8XE`!@,`&'J`D`@(8XD`!0,`'O-`$"`(0P`>\T"("`A +M`@`0(1``_Z^NX```#`![S0(@("$0`/^K)`(``B>]__`LH@`$K[(`"*^Q``2O +ML```K[\`#`"@B"$`@(`A%$``"`#`D"$D`O__C[\`#(^R``B/L0`$C[````/@ +M``@GO0`0#`!B=)"$``"2!````!$0@`!0$"$,`&*%K%(`'!``__(``!`A,*4` +M_R>]__`LH@`*K[\``!!```TD!___/`.``@`%$(`D8U/@)*4``0!#$"$0@``& +M,*4`_XQ'```,`&.1C(0`$"0'__\``C@*C[\```#@$"$#X``()[T`$#"E`/\G +MO?_P+*(``J^_```00``()`/__R2E``$0@``%,*4`_PP`8\*,A``0)`/__P`" +M&`J/OP```&`0(0/@``@GO0`0)[W_\*^_````@%@A,*,`_Q$``!@PQ@#_/`*` +M`I!"5`A00``5C6D`%%#```^,A``$)`(``5#"``2,A``$C[\```/@``@GO0`0 +MC6(`#"1E__\`X#`A,*4`_P!`^`D!`#@A$`#_]X^_``"-8@`($`#_^"1E__^- +M:0`4C20`"!"`_^\E*@`(C((``!1```*M(@`(K4H`!#C"``$L0@`!)&/__Z"# +M``B@@@`)H(``!*R'``RLB``0C2(`!*R```"L1```/`*``I!"5`@40/_]`!``0/@)C(0`!!``__N/ +MOP``C(8`%"0%``&,PP`($&#_]23'``B,8@``%$```JS"``BLYP`$)`(``:!B +M``2L:``(C,(`!(R$`!BL8```K,,`!`P`8>:L0P``$`#_YX^_```GO?_@K[,` +M#*^Q``2OL```K[\`%*^T`!"OL@`(`("((8XR`!20A```#`!BEB93``B.4``` +M#`!BKY(D```2```EC[\`%`P`8I:2)```CD(``(X4``",0@``%$```JY"``"N +M4@`$#`!BKY(D``"2`@`$)`,``5!#`">.`@`(5$``!P(`("&2`@`)4$``()(% +M``A00P`7D@4`"`(`("$``"@A#`!R#20&``P,`&*6DB0``(YB``2N````KG`` +M!*Q0``"2)```#`!BKP*`@"$6@/_=C[\`%(^T`!"/LP`,C[(`"(^Q``2/L``` +M`^``"">]`"".(@`,CB0`!(X&``P`0/@)C@<`$!``_^4"`"`A$`#_^8XB``@` +M`A"``%$0(8Q"`!Q00/_>`@`@(0!`^`F.)``$$`#_V@(`("$GO?_PK[\```P` +M8I:0A```C[\`````$"$#X``()[T`$">]__"OOP``#`!BKY"$``"/OP`````0 +M(0/@``@GO0`0/`*``J!`5`@#X``(```0(20#``$\`H`"H$-4"`/@``@``!`A +M)[W_\*^P``"OOP`$#`!R&`"`@"$,`%PP`@`@(0P`9XR.!``0#`!;X@(`("$, +M`%PX`@`@(0P`]`!`GO?_PK[\```P` +M:7F,A``0C[\```/@``@GO0`0)[W_\*^Q``2OL```,-$`_S"P`/\"`"@A`B`P +M(:^R``BOOP`,#`!C6@"`D"$"0"`A`@`H(11```D"(#`A```8(8^_``R/L@`( +MC[$`!(^P````8!`A`^``"">]`!`,`&-Y`````!1`__8`0!@A`D`@(0(`*"$, +M`&-:`B`P(11`__`D`P`'$`#_[@``&"$GO?_PK[\``#P"@`*01E2C,*4`_P"@ +M."$``$`A```H(0P`8TH``$@AC[\```/@``@GO0`0,*4`_R>]__``H#`AK[\` +M``P`8L8``"@AC[\```/@``@GO0`0)[W_\*^P```PL`#_K[$`!`(`*"&OOP`( +M#`!]`!`GO?_PK[\``#P"@`*00U0)`,`X(20"`$`X8P`")`8"``!# +M,`LPYP#_,*4`_R0(``(,`&-*``!((8^_```#X``()[T`$">]__`PQ@#_K[\` +M``P`8L8PI0#_C[\```/@``@GO0`0)[W_\*^Q``2OL```,-$`_S"P__^OL@`( +M`@`H(0"`D"&OOP`,#`!]__"OL@`(K[\`#*^Q +M``2OL```$*``#@"`D"&0PP`#)`(`@1!B`#TH8@""$$``)20"`((D`@"`$&(` +M"SP1@`("0"`A```H(0P`9'4``#`AC[\`#(^R``B/L0`$C[````/@``@GO0`0 +M)C!78@(`,"$,`&0()`4`!I8C5V("`#`A`D`@(3!B`/\``A(```,:`@!#$"4` +M`"@A)`<``J8B5V(,`&/"``````)`("$``"@A```P(0P`8Y$``#@A$`#_Y8^_ +M``Q48O_?`D`@(9##``<\$(`")A%78C!C``\T90`0`B`P(3P"@`(,`&0(H$-7 +M9I8#5V("(#`A`D`@(3!B`/\``A(```,:`@!#$"4``"@A)`<``A``_^*F`E=B +M/`*``B1&5V$``"@A)`<``1``_]R@0%=A)[W_X*^R`!BOL``0`*"0(0#`@"$D +M!0`!`Z`P(:^Q`!2OOP`<#`!D"`"`B"&7H@``+$(``A!```H"("`A$D``#(^_ +M`!R2`P`#4&``))8#```D`@`"4&(`"Y8"```"("`A```H(0P`9'4``#`AC[\` +M'(^R`!B/L0`4C[``$`/@``@GO0`@%$#_]@(@("&2`@`'/!"``S!"``\T10`0 +M`Z`P(0P`9`BB`IIB +M```"("`A)`4`!C!"__T`0#`A$`#_ZZ>B```GO?_@K[$`%*^P`!"OOP`]`"`40/_W```H(9#0``<# +MH#`A,A``#S80`!`,`&0(`@`H(0(@("$"`"@A)`8``0P`9#H``````B`@(0`` +M*"$``#`A#`!CP@``."$0`/_HC[\`'"02``$0<@`7)`(``E1B_]\"("`AD,(` +M!Q1`_]P\`H`"D$)4"11B_]H``"@A)`4``0P`9`@#H#`AEZ(``"Q"``,00/_1 +M/`.``I8"``:L]`!`\`H`#D$::720%``,,`&0Z)!```0(@("$D!0`!#`!D.B0&``$" +M`"@A`B`@(0P`7,HD!@`!)@(``3!0`/\N`@`#%$#_^0(`*"$D$``!`@`H(0(@ +M("$,`%S*```P(28"``$P4`#_+@(``Q1`__D"`"@A$`#_WX^_``@GO?_PK[`` +M`*^_``0`P#@A`("`(1"@`!$``$`AE,,``"0"`P`P9?\`$*(`52BB`P$00``T +M)`(&`"0"`0`0H@`J)`("`!"B``D\`H`"`@`@(0``*"$,`&1U```P(8^_``2/ +ML````^``"">]`!"00E0))`,`0#A"``(`8B@+)00``0`(&,`\`H`"`&@8(R1& +M5+PPB`#_`&88(0`%$@(M!``$H&(`%Q2`__6@90`6E.,`!"0'`"X"`"`A+&(` +M+@!B.`L``"@A#`!CP@`````"`"`A```H(0``,"$,`&.1```X(1``_]^/OP`$ +ME,,`!"0'`!(\!H`"+&(`$@!B.`L0`/_P),94G!"B`!] +M_^``H!`AK[``$*^_`!0#H#`A)`4`!!1```4`@(`AC[\`%(^P`!`#X``()[T` +M(`P`9`@`````DZ,``3P"@`(D1E=@```H(20'``$"`"`A#`!CPJ!#5V`"`"`A +M```H(0``,"$,`&.1```X(1``_^V/OP`4)[W_X*^Q`!2OL``0K[\`&`#`B"$0 +MH``;`("`(9##``$L8@`"$$``'0``*"$48``?`Z`P(20%``$,`&0(`Z`P(9>B +M```L0@`"$$``$P(`("$D!0`$#`!D.@``,"$"`"`A)`4``20&``$,`&0Z```` +M``(`("$``"@A```P(0P`8\(``#@AC[\`&(^Q`!2/L``0`^``"">]`"```"@A +M#`!D=0``,"$0`/_XC[\`&`P`9`@D!0`$DB8``9>B``!01@`()`4``0(`("$, +M`&0Z)`4`!`(`("$D!0`!$`#_XP``,"$``#`A$`#_X`(`("$GO?_@K[(`&*^Q +M`!0`H)`A`,"((20%``$#H#`AK[``$*^_`!P,`&0(`("`(9>B```"`"`A```H +M(11``!<``#`A%D``!P````"/OP`]`""6)P`$ +MDB8`!SP"@`(D0E04`,(P(0P`8\(`!S@K`@`@(0``*"$``#`A#`!CD0``."$0 +M`/_NC[\`'`P`9'4`````$`#_ZH^_`!PGO?_PK[\``!"@``D`P$@AD,,``R0" +M``$``"@A```P(1!B``8``#@A#`!D=0````"/OP```^``"">]`!"1(P`'/`*` +M`B1"5!0`8A@AD2@``9!B`````"@A$$@``P``,"&1(@`!H&(```P`8\(````` +M$`#_\(^_```GO?_@K[,`#*^P``"OOP`4K[0`$*^R``BOL0`$`,"`(1"@``@` +M@)@AD-$``R0"``(``"@A$B(`"P``,"$,`&1U`````(^_`!2/M``0C[,`#(^R +M``B/L0`$C[````/@``@GO0`@/`*``I!#5+V2`@`'/!*``B945V0`0Q`K)`4` +M!11```0"@#`A```H(1``_^L``#`A#`!D"`````"6!@`$ED179```*"$LP@`" +M,(,`_P#"B`L`!"("``,:``!D&"4"@#`A`B`X(0)@("$,`&/"ID-79`)@("$` +M`"@A```P(0P`8Y$``#@A$`#_UX^_`!0GO?_@K[,`#*^R``BOL0`$K[```*^_ +M`!`\$(`#`,"8(8X&FF``@)`A`*"((3P$@`(\!8`")(07(`P`<=]`"`PQ0`/)*/__S!B__\L0@`"$$``!#!B__\P +MP@"`%$``##!B__\L0@`"$$#_[C#"`(!40/_MC[\`$`)`("$``#`A#`!]`!`,`%]7``````(` +M("$``"@A```P(0P`8\(``#@A$`#_]8^_``0\`H`"D$)5C!!```(\`H`"H$A4 +M"0/@``@`````)[W_\*^P``"OOP`$/`*``I!"58P``"@A%$``!0"`@"&/OP`$ +MC[````/@``@GO0`0#`!]__"OOP``/`*``I!"58P40``$```H(8^_```#X``()[T`$`P` +M6[P`````$`#_^X^_```#X``(``````/@``@`````)[W_X*^Q`!2OL``0K[\` +M&`"@B"$4H`"!`("`(3P"@`(D1E=8D,(``S!#`&`D`@`@$&(`"2AB`"$00`!R +M)`(`0%!@``J0Q@`"C@0`$```*"$,`&1U```P(8^_`!B/L0`4C[``$`/@``@G +MO0`@+,(`#1!`__4\`X`"``80@"1C%SP`0Q`AC$(```!```@`````C@0`$#P& +M@`("("@A#`!>R3& +M5U@0`/_#C[\`&(X$`!`D!0`!#`!D"`.@,"&.!``0/`:``@(@*"$,`%Z8),97 +M6(X$`!`GI@`"#`!D""0%``&7H@``$$#_LI>B``)40/^QC[\`&`(`("$,`%N\ +M)`4``Q``_ZR/OP`8C@0`$#P&@`("("@A#`!>TR3&5U@0`/^EC[\`&(X$`!`\ +M!H`"`B`H(0P`7OTDQE=8$`#_GH^_`!B.!``0/`:``@(@*"$,`%\;),976!`` +M_Y>/OP`8%&+_D8X$`!`,`%^E`B`H(1``_Y&/OP`8C(0`$#P&@`(DQE=8#`!C +M<@``*"$0`/][/`*``B>]__"OOP``/`*``I!"58PPHP#_,.H`_Q!```@`P"@A +M`0`X(0%`,"$!($`A$&``"BQB``,40``$`&`H(8^_```#X``()[T`$`P`6X,` +M````$`#_^X^_```,`%_K`````!``__>/OP``)[W_X*^Q``0PL0#_K[,`#*^R +M``@`@)@A`!&0P`(@("&OOP`0#`!BEJ^P```"41`A``(0@`!1$",\`X`#)&.Q +M(``"$(``0Q`A)$,`&)1D``00@``*`E$0(30"__\0@@`&``0B`I!B``4\`X`" +M)&-4G*!D``F@8@`(`E$0(0`"$(``41`C/`.``R1CL2```A"``$,0(21#`!B4 +M9``&$(``"SP"@`(T`O__$((`"#P"@`*08@`'/`.``B1C5)P`!"("H&0`"Z!B +M``H\`H`"`!$80"1"5X``8H`AD@4``9(&```\!(`"#`!QUR2$%W"2`@`!%$`` +MSCP&@`("41`A``(0@`!1$",\`X`#)&.Q(``"$(``0Q`AE$0`(!"```DD0P`@ +M-`+__Q""``8`!"("D&(``3P#@`(D8U2(QP`(F,<`"XC(``R8R``/J(,``+B#``.HA0`$ +MN(4`!ZB'``BXAP`+J(@`#+B(``\DQ@`0%,+_[B2$`!`"41`A``(0@`!1$",\ +M`X`#)&BQ(``".(``Z#`A),,`()1B``8D0O__+$(`(%!``"F4P@`HD&,`!SP% +M@`(E`@!J)&,``@#B$"$DI%1DH*-49(A)``"820`#B$H`!)A*``>(0P`(F$,` +M"XA%``R810`/J(D``KB)``6HB@`&N(H`":B#``JX@P`-J(4`#KB%`!&(20`0 +MF$D`$XA*`!282@`7B$,`&)A#`!N(10`2!```,$(`WS1#`"``1!@*/`2``@!@ +M*"$DA!>(#`!QUZ##``<0`/\H`E$0(2>]__"OOP`$K[````"`@"$,`&*6D(0` +M`#P"@`*@0%6,#`!C]8X$`!`,`&*OD@0``(^_``2/L``````0(0/@``@GO0`0 +M)[W_X`"`$"$D!``TK[4`%*^T`!"OLP`,K[(`"*^Q``2OL```K[\`&`"@F"$` +MP*`A`."H(0$`D"$,`'NZ,%$`_P!`@"$2```/)`(``@(`("$``"@A#`!R#20& +M`#0\`H`")$)7<``1&(``8A@AKE```*X3`""N%``LKA4`,*QP`````!`AC[\` +M&(^U`!2/M``0C[,`#(^R``B/L0`$C[````/@``@GO0`@D((`*`"B*"4#X``( +MH(4`*">]__``@!`AK[```*^_``0`H"`A$*``"#!0`/\,`'O-`````#P"@`(` +M$!B`)$)7<`!B&"&L8```C[\`!(^P`````!`A`^``"">]`!`PA`#_``08P`!D +M&"$``QB`/`*``@!D&",D0E=P``0@@">]__``@B`A/`*``Z^Q``2OOP`(K[`` +M`"1"L2```QB`C)````!B&"&09``;`."((3P(@`(\!X`"K@4`(*X&`"0F"0`< +M).>(["4(B4P``"@A`@`P(0P`]__"OL```K[\`!!"@ +M``0`H(`AC*(`'!1```4`0"`AC[\`!(^P```#X``()[T`$`P`]__"OL````*"`(:^_``BOL0`$#`!RI0"`B"&.`@`@ +M`$#X"8X$`"0,`'*S`B`@(0P`]__"OOP``C,(`+`!`^`F,Q``PC[\```/@ +M``@GO0`0,(0`_Q2```0`````/`*``P/@``B00K$[`^``"```$"$PA`#_%(`` +M!``````\`H`#`^``"(Q"L30#X``(```0(3"$`/\4@``%`````#P"@`.,0K$T +M`^``""1"`0`#X``(```0(2>]__`PA`#_%(``!:^_```\`H`"C$)7=!!```0` +M````C[\```/@``@GO0`0#`!R&``````,`&*6```@(1``__F/OP``)[W_\#"$ +M`/\4@``%K[\``#P"@`*,0E=T$$``!`````"/OP```^``"">]`!`,`'(=```` +M``P`8J\``"`A$`#_^8^_```GO?_PK[```#"0`/^OL0`$K[\`"`P`]`!`,`'*EC$2Q.!``__22(IID)[W_\*^P``"OOP`$#`!R&#"0 +M`/\6```&/`2``Y""FF0D0O__,$,`_Q!@``>@@IID#`!R'0````"/OP`$C[`` +M``/@``@GO0`0/`*``PP`]__"OL0`$K[\`"*^P``",@@`8`("((8Q0```, +M`&)TD@0`D(X"`!Q40``/C@(`(*X1`!R.(@`8C@,`**X1`""L0```D@0`D"1C +M``$,`&*%K@,`*(^_``B/L0`$C[````/@``@GO0`0C$(`&!``__&L40``)[W_ +MX*^T`!`PE`#_+H(``J^V`!BOM0`4K[$`!*^_`!ROLP`,K[(`"*^P````H+`A +M`,"H(3#Q`/\40``,)`,`#X^_`!R/M@`8C[4`%(^T`!"/LP`,C[(`"(^Q``2/ +ML````&`0(0/@``@GO0`@#`![NB0$`*``0(`A$$#_\20#``H``"@A)`8`H`P` +M<@T`0"`A`H`@(0P`8F.B%`"0`H`@(0P`8ENN`@`(H@(`D20$!P`D`@#_HA$` +MDPP`>[JF`@"$`$"((1!`_]XD`P"I`$`@(0``*"$D!@<`#`!R#:X"`!@,`'NZ +M)`0#`*X"`'000/_4)`,``0!`D"&N```[HD!``<`$`@(20&`!P``"@A#`!R#:X"`!0"@"`A#`!DP`(`*"$40/^V)`,` +M+ZZP`````!@A$`#_LJX6`)@GO?_PK[\``(R#`!0Q*0#_H&4``(R#`!2@9P`! +MC(,`%*!H``*,A0`4I&8`$`P`:(.LJ0`4C[\```/@``@GO0`0)[W_\*^_``RO +ML@`(K[$`!*^P````@)`AD(0`D#"P`/\,`&)T,-$`_P(`*"$"(#`A#`!HZ`)` +M("&21`"0#`!BA0!`@"$"`!`AC[\`#(^R``B/L0`$C[````/@``@GO0`0)[W_ +M\*^_```,`&AA,*4`_X^_```#X``()[T`$">]__"OOP`,K[(`"*^Q``2OL``` +M`("0(9"$`)`PL`#_#`!B=##1`/\"`"@A`B`P(0P`:/8"0"`ADD0`D`P`8H4` +M0(`A`@`0(8^_``R/L@`(C[$`!(^P```#X``()[T`$">]_^"OLP`,K[(`"*^Q +M``2OL```K[\`$`"`B"&0A`"0`,"0(0#@F"$,`&)T,+``_XXB`"@00``?`B`@ +M(8XC`!P08``'`&`H(8QB`!B,0@``%$```JXB`!RN(``@CB(`**QR``0D0O__ +MKB(`*"0"``&@<```K',`"*!B``,,`&:\H&```9(D`)`,`&*%`$"`(20"`*(` +M$!`*C[\`$(^S``R/L@`(C[$`!(^P```#X``()[T`(`P`8H62)`"0$`#_]B0" +M``,GO?_@K[,`#*^R``BOL0`$K[```*^_`!``@(@AD(0`D`#`@"$`X)@A#`!B +M=#"R`/^.(@`H$$``(0````".)@`<$,``%R0"`*&,P@`8C$(``!1```*N(@`< +MKB``((XB`"@D`P`!K-``!"1"__^N(@`H`,`H(0(@("&@T@``K-,`"*##``,, +M`&:UH,,``9(D`)`,`&*%`$"`(20"`*$`$!`*C[\`$(^S``R/L@`(C[$`!(^P +M```#X``()[T`(`P`8H62)`"0$`#_]B0"``,GO?_PK[```*^_``0,`&F'`("` +M(0P`>\V.!``0#`![S8X$`!@,`'O-C@0`=`P`>\V.!``4#`![S0(`("&/OP`$ +MC[````/@``@GO0`0)[W_\*^R``BOL0`$K[```*^_``P`@(@AD(0`D#"P`/\, +M`&)T`,"0(28#__\L8@`&$$``&S("`!```Q"`/`.``B1C%Y@`0Q`AC$(```!` +M``@`````EB(`A*9"```,`&*%DB0`D```$"&/OP`,C[(`"(^Q``2/L````^`` +M"">]`!`0`/_UDB(`E1``__.2(@"4$`#_\98B`(@0`/_OEB(`AA!```4R!0`/ +M#`!IOP(@("$0`/_JID(```P`8H62)`"0$`#_Z20"``(GO?_PK[(`"*^Q``2O +ML```K[\`#`"`D"&0A`"0,+$`_PP`8G0PT/__)B/__RQB``<00``C,B(`$``# +M$(`\`X`")&,7L`!#$"&,0@```$``"`````"F4`"$#`!BA9)$`)```!`AC[\` +M#(^R``B/L0`$C[````/@``@GO0`0,@4`_Z)0`)4,`&A;`D`@(1``__(````` +M$`#_\*)0`)00`/_NIE``B!``_^RF4`"&`@`H(0P`:] +M__`PI0#_K[\```P`::,PQ@#_C[\```/@``@GO0`0)[W_X*^S``ROL@`(K[$` +M!*^_`!2OM``0K[```(R4``@PLP#_,,8`_P`3$$".@P`8`$80(0`"$8``8H@A +M$B``$`"`D"$R(@`/)$(`3R0#__``0R@D`B,8)`!E$"$`0Q`K%$``!P!@("&\ +M<0``)&,`$`"%$"$`0Q`K$$#_^P````".)0`\)`(``1"B``H``"`AC[\`%(^T +M`!"/LP`,C[(`"(^Q``2/L````(`0(0/@``@GO0`@``81``!3$"$`18`$`D`@ +M(0P`99H"`"@A%$``"``3$(``5!`AKB```(Q#`(```"`AK$,`@!``_^FN(``\ +M`D`@(0P`98X"`"@A%$#_Y"0$`*40`/_S`!,0@">]__`PA`#_K[```*^_``0, +M`&)K`*"`(8Q#```P8P#_`$,8(:X#``B,0@`D,$(`'RQ#``0`0"@A%&```J(" +M`),D!0`#,*0`_P`$(<`DA`@`#`![NJ(%`),`0!@AK@(`,!!``"(D!`"H``(0 +M(S!"!_\`8A`A)`0((`P`>[JN`@`L`$`8(:X"`#000``8)`0`J@`"$",P0@`? +M`&(0(20$`P`,`'NZK@(`.*X"`'@00``/)`0``9($`)`\!8`")@<`G`(`,"$, +M`&'])*6>,"0"`/^F`@"$`@`@(0P`90"F``"&/`*``JQ05W@``"`AC[\`!(^P +M````@!`A`^``"">]`!`GO?_@K[(`"*^Q``2OOP`8K[4`%*^T`!"OLP`,K[`` +M``"`B"&0A`"0#`!B:XXS``@`0)`ACF(``"0#__X`0Q`DKF(``"0"``*N8@`` +MCF(``#!"``(40/_])`(`!JYB`&B2(@"3CB0`,```*"$``C'`),8(``P`<@T` +M`H!`CB0`-```*"$D!@@@KB``/`P`<@VN(`!`DB8`DR8D`$0``"@A#`!R#0`& +M,,"2)@"3```H(28D`%P,`'(-``8PP*Y@`&R.)0`L$@``#```H"$`H"`A/`(` +M0#1"@``FE``!K((```*0&"LD`@`!K((`"*R``#P48/_W)(0`0*YE`!B.0@`$ +M,$(`$%!```2.,``XCF(`1*YB`$2.,``XCC(`>```H"&.`P`$)`*`_R05``$` +M8A@D/`*``B1"E<2N0@`$KA(`'*X#``2N%0``KE$```(`("$,`&5Q)I0``2Z" +M`$`F$``@%$#_[R92``P\`@!`-$(`0*YB`(".8P"`/`+__C1"__X`8A@D)`(! +M1ZYC`("N8@`()`(`_Z8B`(2F(`"&C[\`&*YU``"/M``0C[4`%(^S``R/L@`( +MC[$`!(^P```#X``()[T`(">]__"OL0`$K[\`"*^P``",@@`<`("((8Q0```, +M`&)TD@0`D(X"`#Q40``/C@(`0*X1`#R.(@`] +M__"OI0``KZ8`!(^E``"/H@`$CZ,``(R&``BLH@`(K&``#(S"`````"`A-$)` +M`*S"``"LQP!PC,(`>`!'$"040``'+(,$`!!@``4DA``!C,(``#!"0``40/_W +M`````(S#```L@@0`)`2__P!D&"2LPP```^``"">]`!`GO?_@K[$`%*^P`!"O +MOP`8D.D``(R"``B0Z``!KZ4``*^F``2,0P`8``F`0`((@"$`$!&``&(8(:^C +M``B/I0`(``A!`(^F```!"4`A)`<``0"`B"$!!S@$#`!EL``0@(`"$1@AC&(` +M1%1```R,8P!]`""/H@``$`#_]:QB```GO?_@K[\`$)#H````X&`AD.<``8R)``@` +M"!!``$=8(:^E````"VB`KZ8`!*^@``B-(P`8`:00(0"`4"&,1`!<``]`""/HP`(``L0@(^E``"/I@`$`$H0(:Q#`%P!0"`A#`!ESP&` +M."$0`/_SC[\`$">]_]"OLP`]`#".,``\+0)``20)0``!`D@+$@``.@$)0"..!@`< +MC,(``!1```*N(@`\KB``0)8C`(H`"10`-$6`@"1C__\T1`"`)`(``:S1```" +M"I@*K@(``!4``"BF(P"*K@4`!(Y#``2.!``$)`*`_P!J&"$`@B`DK-(`""1G +M0``D8A``)&4@`"1F,`"N!``$K@(`#*X%`!"N!@`4K@<`&*X#``@18``"`4E0 +M(:UP```5`/_5`@!8(0&`*"$,`&6:`B`@(11```<"("`A`F`H(0(`,"$,`&7/ +M`D`X(1``_\(``"`A`F`H(0(`,"$,`&7Y`D`X(1``_[P``"`A$`#_V:X$``00 +M`/^X)`0`IB>]__"OOP``#`!F.@````"/OP```^``"">]`!`GO?_PK[\```P` +M9CH`````C[\```/@``@GO0`0)[W_L*^S`"ROOP!$K[X`0*^W`#ROM@`XK[4` +M-*^T`#"OL@`HK[$`)*^P`"",@@`(KZ``"*^@``ROH@``C%4`;`"`F"&OH``0 +M$J``$J^@`!20@@"3$$``#P``H"$D`@`!`H(0!`*B$"0RA0#_)`8``2:4``$` +M`#@A``!`(11``*4D"0`(DF(`DP*"$"L40/_T)`(``8^C``",=0!\K'4`?!*@ +M`(R/OP!$KZ``!(^D``228@"3``"@(1!``'\`!+@K`!<0@`!3$"$D0@!$KZ(` +M&`+@\"$2X`"-)`(``2:#`!``8A`$`J(0)%!``&R28@"3CZ(``(^D`!B,0P`8 +M`!X1@`!BL"$2P``0C(4``#+"``\D0@!/)`/_\`!#,"0"PQ@D`&80(0!#$"L4 +M0``'`&`@(;QQ```D8P`0`(80(0!#$"L00/_[`````%"@`%228@"3,*(`#R1" +M`"\D`__P`$,P)`"C&"0`9A`A`$,0*Q1```<`8"`AO'$``"1C`!``AA`A`$,0 +M*Q!`__L`````C*(`!#!"`(`00``1`````%:``#^28@"3C*(`!"0#`$```A0" +M,$(`?U1#`#F28@"3C*(`!#!"@`!00``UDF(`DXRB``0D`_]_`$,0)*RB``2, +MH@`,@(`!)(C`)`\`H`"C[\`#(^R``B/L0`$C[```"1" +M5W0``QB``&(8(:Q@```#X``()[T`$">]__"OL0`$K[\`"*^P``",D``(`("( +M(8R$`)@``"@A```P(0``."$,`%_$``!`(8X#`!0\`@'_-$+__P!B&"2N`P`4 +MC@(`;*X"`&R.`@!\K@(`?(X"`'`40/_^)`+__ZX"`'2.`@!$,$(!`!!```0D +M`@`!KB(``"0"``.F(@"$CB0`F```*"$``#`A```X(0P`7\0``$`AC[\`"(^Q +M``2/L````^``"">]`!`GO?_PK[\``)2#`(0`@!`AC(0`F*1#`(XD`P"`I$,` +MA```*"$``#`A```X(0P`7]H``$`AC[\```/@``@GO0`0)[W_\*^P``"OOP`( +MK[$`!(R"````@(`A$$```HR1``BL@```CB(`1#!"`0`40``-`````(XB`$0P +M0@(`4$```Z(``)(D`@`"H@(`DI((`)*.!`"8```H(0``,"$,`%^]```X(8XB +M`$0P0@"`5$``&98"`(2.(@!$,$(`@!1```4D`@`"E@,`A"0"`(`08@`')`(` +M`J8"`(2/OP`(C[$`!(^P```#X``()[T`$)8"`(Z.!`"8```H(:8"`(0``#`A +M```X(0P`7^<``$`A$`#_\X^_``B.!`"8```H(:8"`(XD`@"`I@(`A```,"$` +M`#@A#`!?Z0``0"$0`/_>`````">]__"OL````("`(3P$@`*OOP`$#`!QUR2$ +M%\R6`@",C[\`!"1"``&F`@",C[````/@``@GO0`0C((`"``%+D"L10`4)`(` +M`0/@``BD@@"$C(D`"#"E`/\`!1'`C2,`&`!B("$0@``1)`(``3""``\D0@!/ +M)`/_\`!#0"0`@Q@D`&@0(0!#$"L40``'`&`X(;QQ```D8P`0`.@0(0!#$"L0 +M0/_[`````"0"``$`HA`$B(,`*)B#`"N(A0`LF(4`+ZC#``"XPP`#J,4`!+C% +M``<#X``(K2(`;">]_^"OLP`,K[$`!*^P``"OOP`4K[0`$*^R``B,E``(D*<` +M`)"F``&.@P`8``<00`!&$"$``A&``$.((0"@@"$2(``0`("8(3(B``\D0@!/ +M)`/_\`!#*"0"(Q@D`&40(0!#$"L40``'`&`@(;QQ```D8P`0`(40(0!#$"L0 +M0/_[`````(XB`#P`!AD``&<8(20$``$`9)`$$$``"@``&"&/OP`4C[0`$(^S +M``R/L@`(C[$`!(^P````8!`A`^``"">]`"`"8"`A#`!EF@)`*"$40``J`F`@ +M(9(#``(D`@`!$&(`(I8"`!`08``<`````(X#`!008``#``(D`#P"(```@B`E +MKB0``)("``"2!``!)`,`P``"$(``5!`A/`8`P`!D,`J,10"`)$,`@!"```F2 +M`@`"``(4@`#"$"4`HA`EK&(``"0"``&N(@`\$`#_U```&"$0`/_X``(0@``" +M%``T0H``$`#_Z*XB```\`T````(4`!``__L`0Q`E#`!EC@)`*"$40/_&)`,` +MI!``_].2`P`",*4`_S#&`/\`!2A``*8H(0`%*(``I"@AC*,`1!!@``0``!`A +MC&(`'(Q"``B00@`#`^``"``````GO?_0K[,`'##3`/^OL@`8`!,1`#"R`/^O +MM0`DK[0`(*^Q`!2OOP`HK[``$`"`B"$`4A`A`!(80"0$``$`1"`$`',8(8XE +M``BOH``(KZ``#*^C``"OI``$CZ(``(RC`!@``*@A``(1@`!B("$0@``0``"@ +M(3""``\D0@!/)`/_\`!#,"0`@Q@D`&80(0!#$"L40``'`&`H(;QQ```D8P`0 +M`*80(0!#$"L00/_[`````(R"`#P40`!#)`,`HX^B`````A"``%$0(8Q%`$00 +MH``]```8(3"B``\D0@`O)`/_\`!#,"0`HQ@D`&80(0!#$"L40``'`&`@(;QQ +M```D8P`0`(80(0!#$"L00/_[`````(RB`!R,0P`($&``!0````",=``$C&(` +M"`!@J"&OH@`,C*(``(RC``0D!/_@,&,`:!1@``L`1(`DC*(`!(^C``@``A0" +M,$)__P!B&"&OHP`(CZ(`#(^C``@`0Q`CKZ(`#`(@("$"0"@A#`!I^@)@,"%2 +M```:CB0`F(X"`!R,0@`($%4`"0````".)`"8CZD`#`)`*"$``#`A`F`X(0P` +M8'D"@$`AKZ``"!8`_\8"`"@A```8(8^_`"B/M0`DC[0`((^S`!R/L@`8C[$` +M%(^P`!``8!`A`^``"">]`#"/J0`,`D`H(0``,"$"8#@A#`!@>0*`0"$0`/_L +M`````(R"``@D!0`!C$(`1#!#`,`D`@"`4&(`!)2"`(0``"@A`^``"`"@$"%4 +M0__]```H(1``__L`````)[W_\*^_``2OL````("`(8R$``@D`_^XC((`"`!# +M$"2L@@`(C((``"0#__X`0Q`DK((``"0"``*L@@``#`![S8X$`#`,`'O-C@0` +M-`P`>\V.!`!XD@0`D`P`8BF.!0"]_^"OL@`(K[\`$*^S``ROL0`$ +MK[```(R"``@PI0#_,,8`_XQ#`!@`!2A``*8H(0`%$8``@)`A`&(@(1"```\P +M@@`/)$(`3R0#__``0S`D`(,8)`!F$"$`0Q`K%$``!P!@("&\<0``)&,`$`"& +M$"$`0Q`K$$#_^P``````!9B``G(0(8Q$`$00@``Q,((`#R1"`"\D`__P`$,P +M)`"#&"0`9A`A`$,0*Q1```<`8"@AO'$``"1C`!``IA`A`$,0*Q!`__L````` +MC(,``"0"_^``8H@D$B``"R8B`"``41`K`B`8(11```<"("@AO'$``"1C`!`D +MH@`@`$,0*Q!`__L`````C(,`'"0"``&L@@``K'(``*R```0,`&5QC'``"!(@ +M`!,"]__`D!``!K[\```P`:ELT!;]HC[\```/@ +M``@GO0`0)[W_\*^_````@"@AC(0`B`P`=E(`!"""C[\`````$"$#X``()[T` +M$`/@``@``!`A)[W_\#P"@`*OL```)%!6/#P"@`(D0E8@`@(0*Q!```6OOP`$ +MC[\`!(^P```#X``()[T`$(X"````0/@))A#__#P"@`(D0E8@`@(0*U!`__J. +M`@``$`#_](^_``0`!!`C`((@)``$%```1"`C``01@`""("$`!!$``((@(3P" +M@`(D0C7```0F@@""("$#X``(@((``!B``!0D"``4*(,G$20")Q``@Q`+<$@P +M`@""(",8P``+0`5(`$`"2``0HO_^`$48(SP'``,`0"@A!&``"#3G#4``PS`C +M',#_]P`````<@/_O*(,G$0/@``@`````$`#_^`!G&"$#X``(``````/@``@` +M````/`*@P#1"`*",0@```^``"#!"``\GO?_@K[\`$`P`:K\`````$$``0X^_ +M`!!`@.``````````````````0(#H`````````````````#P#@`"\:0``/`*` +M`"1C`!`T0@__`$,0*Q!`__H`````0`*``````````````````#P#__\T8__X +M`$,0)#1"``-`@H``````````````````0(#@`````````````````$"`Z``` +M```````````````\`X``O&@``#P"@``D8P`0-$(/_P!#$"L00/_Z`````$`" +M@``````````````````\`___-&/_^`!#$"0T0@`#0(*````````````````` +M`$`"@`"OH@``CZ(``(^B```D`__\`$,0)*^B``"/H@``0(*``(^_`!`#X``( +M)[T`(#P$H,`TA``@C(4``"0"_O\\`Z#``*(H)*R%``",A0``)`+]_S1C`)`` +MHB@DK(4``(QE```TI0`!`^``"*QE```\`Z"0-&-``(QE```D`O_\/`2@D`"B +M*"2L90``-(1`!(R%```\`__\-&/__P"C*"0\`J"0K(4``#1"F'",10``-*4` +M#ZQ%``",A0``/`(``0"C&"0`8B@E`^``"*R%```\`Z#`-&,`((QB```T0@,` +M`^``"*QB```\!:#`-*4`8(RF```\`__^/`(``0`$(8`T8___`((@)`##&"0` +M9#`EK*8``(RF```\`@`"`,(P)0/@``BLI@``,(0`_P`$$8`\!J#`/`6@P#!' +M`$`D`@`!-,8`8!""``HTI0!DC,,``"0"_[\T8P`PK,,``(S#````8A`D`$<8 +M)0/@``BLPP``C*,``"0"__X`8A@D$`#_\ZRC```GO?_PK[```*^_``0,`&J_ +M,)``_P!`,"$\`Z#`)`(``1("`!]_^`#H"`AK[\`$`P`:[PD!0`/DZ,``(^_`!`\!(`"``,00B2% +M5X`P0@`!,&,``:"#5X"@H@`!`^``"">]`"`GO?_@/`.@P*^_`!`T8P"0C&(` +M`#P%H,`TI0!@KZ(``(^B```\!/[_-(3__S1"``2OH@``CZ(``*QB``",H@`` +MKZ(``(^B````1!`DKZ(``(^B```,`&R`K*(```P`:SP``"`A#`!NK``````, +M`&L.`````"0"`^BOH@``CZ(``"1"__^OH@``CZ,``"0"__\48O_Z/`2@P#2$ +M`&",@@``/`/_[S1C__^OH@``CZ(```!#$"2OH@``CZ(```P`:QZL@@``#`!K +MC0`````,`&RG``````P`;-0`````#`!KS@`````\`H`"#`!M6(!$5<@,`&NT +M`````(^_`!`#X``()[T`(#P"H,`\!?_O-$(`8#2E__^,0P``4(```P!E&"0\ +M`@`0`&(8)3P"H,`T0@!@`^``"*Q#```GO?_PK[```*^_``0,`&J_`("`(0!` +M,"$\`Z#`)`(`%20$``D`4"`*-&,`:#P"H,",90``-$(`8*QD``",10``$@`` +M!3P"H,`0P``C)`+^_S2E`0`\`J#`-$(`8*Q%```2```9C$4``!3``!4\`A`` +M/`+O_S1"__\`HB@D/`*@P#1"`&"L10``C$4``!8```:/OP`$4,``!#2E`0`D +M`O[_`*(H)(^_``2/L```/`*@P#1"`&"L10```^``"">]`!`0`/_N`*(H)5#` +M__T\`A``$`#_Z#P"[_\0`/_>`*(H)#P&H,`\`O_]-,8`8!"```8T0O__C,,` +M`#P"``(`8A@E`^``"*S#``",PP```&(8)`/@``BLPP``/`:@P#P"_O\TQ@!@ +M$(``!C1"__^,PP``/`(!``!B&"4#X``(K,,``(S#````8A@D`^``"*S#```\ +M!*#`-(0`((R#```\`O_[-$+__P!B&"0#X``(K(,``"B"``000``+`````"0" +M``$`@C`$``80)SP#H+&,8P``4*```@!B&"0`9A@E/`&@L:PC```#X``(```` +M`#P"H+$T0@`(C$,``"0"``$`@A`$``(P)R0"``$0H``&`((0!`!F&"0\`J"Q +M-$(`"`/@``BL0P``$`#_^P!B&"4\!*#`-(0`((R#```\`O_W-$+__P!B&"0# +MX``(K(,``#P"H,`T0@`@)`,``:Q#```0`/_\/`*@P">]_^"OLP`,K[(`"*^Q +M``2OL```/`*``Z^_`!",0[$D``000`"@D"$`8H`A`,"8(12@``@``(@AC[\` +M$(^S``R/L@`(C[$`!(^P```#X``()[T`(``1($`"9"@A)C$``0P`;:H"!"`A +M`C(0*U1`__H`$2!`$`#_\8^_`!`GO?_@K[$`%*^P`!"OOP`8#`!MH0`````` +M0(`A/`*``ZQ0L2`D4;$@)`(``1("`%$`````%@```C0"\`"N(@`$/!"``R80 +ML2`\`J"@K@(`%"0"``*N`@`8)@8`'"0$``$D!0`!#`!LM:X``!`F!@`>)`0` +M0`P`;+4D!0`!)@8`("0$`$$,`&RU)`4``28&`"(D!`!"#`!LM20%``$F!@`D +M)`0`0PP`;+4D!0`!E@(`)"0%`"`F!@`J``(00BQ#`"``0R@+#`!LM20$`$0F +M!@`F)`0`9`P`;+4D!0`!E@(`)B0%`!`F!@!J``(00BQ#`!``0R@+#`!LM20$ +M`&4F!@`H)`0`=0P`;+4D!0`!E@(`)"0%``@F!@"*``(00BQ#``@`0R@+#`!L +MM20$`'8F!@`,)`0`'0P`;+4D!0`!)@8`"B0$`!XD!0`!#`!LM280``@"`#`A +M)`0`'PP`;+4D!0`!C[\`&(^Q`!2/L``0`^``"">]`"`,`&T\`Z`@(9>B```` +M`AH"$'#_K3P"``$D`@`"5&+_K#P0@`,0`/^H/`(`!">]__``@"@AK[\```P` +M;:HD!`AXC[\```/@``@GO0`0/`*``@/@``BL1%7,/`*``@/@``B,0E7,/`)1 +MZS1"A1\`@@`9/`*``@``(!``!"&"`^``"*Q$5=`\`H`"`^``"(Q"5=`\`H`" +M`^``"(Q"5=0\`H`")$(V```$&(``8A@A``000">]__`\"*#`,$<`#BR"``BO +MOP`$K[```#4(`&`40``%`(`P(8^_``2/L````^``"">]`!"-!0``/`*``JQ& +M5=0D`O_Q`*(0)`!'*"6,9```-*4``0P`;42M!0``/`*``"1"`P",1``4```H +M(1"```0D!B6`C((`%`!`^`F,A```#`!M1P`````,`&U*`$`@(4`(8``````` +M`0"`(3P!__\T(?_^`0%`)$"(8``````````````````,`&U2,A```3P#@`*L +M8E=\0(!(`````````````````$""6`````````````````!`"&```````#(0 +M``$!$$`E0(A@`````````````````!``_\>/OP`$/`*@LS1"`!R,0@``)[W_ +M\*^B``"/H@``,$(``0/@``@GO0`0/`*A`#B$``(`@B`AE((```/@``BDH@`` +M`X`X(3P<@`,GG-90``000`!$$"$``AF``$,0(0`"$(``1!`A``(0@`!$$"$\ +M`VC;``(A@#1CBZT`@P`8``07PP``&!```QL#`&(@(SP"%/@T0K6)`((`&``$ +M'\,``!`0``(30P!#*",`!1!``$40(0`"&8``0Q`A``(0@`!%$"$``A"``$40 +M(0`"$4``@B@C0`9(`$`#2```9A@C/`(``P1@``HT0@U``&40*A1`__D````` +M`(,@(UR`_^4\`A3X`.#@(0/@``@`````$`#_]@!B&"$GO?_PK[\```.`$"$\ +M'(`##`!LKR>4GG-90`@#@(8^_``2/L``````0(0/@``@GO0`0`^``"```$"$GO?_@K[(` +M"*^P``"OOP`0K[,`#*^Q``0`@(`A```H(202``$``!@A`X"8(3P<@`,GG-90 +M)`+__A""`#]`"",@@`4 +MC(0``!``__(D!0`$5(+_V"80``$\`H`"C$)5V!Q`_]4D4O__)!+__1``_](` +M0I`+/`*``"1"`P"L0``8/`*``A``_\RL1%78)`4``0``&"$#@#`A/!R``R>< +MUE`D`O_^$((`'BB"__\00``3)`+__R0"__U0@@`"```@(22$``$D`P`!$&`` +M"0`$&4`\`H`#)$*::`!B&"$\`H``)$(#`*Q#`!0\`H`"K$15W`#`X"$#X``( +M`*`0(52"__$DA``!/`*``HQ"5=P<0/_N)$7__R0%__T0`/_K`$(H"SP"@``D +M0@,`K$``%#P"@`(0`/_EK$15W`.`$"$\'(`#)YS64`/@``@`0.`A`X`0(3P< +M@`,GG-90`^``"`!`X"$GO?_PK[\``#P%@`*0HE7@$$``!```("&/OP```^`` +M"">]`!`\`H``)$(#`(Q"`#0D`P`!`$#X":"C5>`0`/_WC[\``">]__`\`H`` +MK[\``"1"`P",0P`4``0F```$)@,08``2,(4`_XQD``",8@`,`$#X"0`````\ +M`H``)$,#`(QB`$040``$```@(8^_```#X``()[T`$*Q@`$0,`&\&`````!`` +M__J/OP``C$,`&!``_^T`````)[W_\*^_``2OL``````P(3P'@```!A"`).4# +M`"3&``$\`X`"`$40(21CM^PHQ`!`K$,``%2`__<\!X``/`(`"#1"`!6LX@,` +M/`*``B1"MY2LH@!`/`*``B1"M[BLH@`0/`*``B1"ML"LH@!(/`*``B1"N="L +MH@`@/`*``B1"N>2LH@`<```P(:R@`$RLH``X```H(0`&&,``91@A/`*``R1" +MFF@``QB``&(8(22E``$\`H`")$*W["BD``BL8@``%(#_]0`&&,`DQ@`!*,(` +M`A1`__```"@A/!"``#P"@`(F$`,`)$*W]*X"`#`\`H`")$*Y)"0$__X,`&W] +MK@(`-`P`;DDD!/_^#`!^$@`````,`&W]```@(0P`;DD``"`AK@``1(^_``2/ +ML````^``"">]`!`0H``*```P(22E__\`A1`A@$,``"0"``,08@`$)`8``52@ +M__HDI?__```P(0/@``@`P!`A```!30/@``@`````)[W_\*^_```,`&I[```` +M`(^_```#X``()[T`$">]__"OOP`$K[```#P"@`*,0E7D%$``%3P"@`(D4%98 +M/`*``B1"5E@2`@`.)`,``8X"``P`0/@)`@`@(1!```^.`@`8-$(``:X"`!@\ +M`H`")A``("1"5EA6`O_VC@(`#"0#``$\`H`"K$-5Y(^_``2/L````^``"">] +M`!`D`__^$`#_\0!#$"0GO?_PK[\```P`;SP`````#`!O/@`````,``:$```` +M``P`>24``````^``"``````#X``(`````">]__``!"8`K[```"0"``H`!(8# +MK[\`!!("``]`!``!"8##`!O +M0"80``&2!`````0F`%2`__L`!"8#$`#_]8^_``0GO?_P)`4`$"0&`"L``#@A +MK[\```P`;](``$`AC[\```/@``@GO0`0)[W_L*^U`#0D`@`@)!4`,*^^`$"O +MMP`\K[8`.*^T`#"OLP`LK[(`**^_`$2OL0`DK[``(`!(J`H`@)`A`*"8(0#` +M\"$`X+@A`2"P(0``H"$#M!@A)I0``2J"`"`40/_\H'4```)3$"440``E``"@ +M(20"`#`D%``!HZ(```*6$"H"PJ`+)`(`+1+B`!8"G1`A)I3__P:```B/OP!$ +M`IT0(8!$```,`&]`)I3__P:!__P"G1`AC[\`1(^^`$"/MP`\C[8`.(^U`#2/ +MM``PC[,`+(^R`"B/L0`DC[``(`/@``@GO0!0@$+__R:#__\`51`F`&*@"@.T +M$"$0`/_FH%<``!!`_]\"EA`J``"`(0)`("$"8"@A`@`P(0P`!.,#P#@A/`2` +M`B2$%]``@Q`AD$,```.T$"$"0"`A`F`H(0(`,"$#P#@A#``#1*!#````0)`A +M`$,0)0!@F"$40/_K)I0``1``_\<"EA`J`*!0(0#`6"$`X&`A`(`8(0``$"$G +MO?_P`0!((0!`("$`8"@A`4`P(0%@."&OOP``#`!O>`&`0"&/OP```^``"">] +M`!`D!P`!$(``&0``$"&0@@````(>`!!@`!0`@#`A`,00(RA""`$``C@*``,> +M`R0"``H08@`')`(`#1!B``4D8O_@+$4`7R0"``A48@`!``4X"A#@``4DQ@`! +MD,(````"'@!48/_O`,00(P#@$"$#X``(`````">]_X``A1`EK[X`<*^W`&RO +MM@!HK[4`9*^T`&"OLP!T``&CH@``$IT`"`+@$"$FE/__DH(` +M`";W``&BH@``%IW_^R:U``$"X!`AHJ```(^_`'2/O@!PC[<`;(^V`&B/M0!D +MC[0`8(^S`%R/L@!8C[$`5(^P`%`#X``()[T`@!!`_^D``````!:'PP)`("$" +M8"@A`@`P(0P`!.,"P#@A`\,0(9!"```"0"`A`F`H(:*"```"`#`A#``#1`+` +M."$`0)`A`$,0)0!@F"$40/_N)I0``1``_]0`````)[W_<*^^`(``@/`A`,`@ +M(:^W`'ROM@!XK[4`=*^T`'"OLP!LK[(`:*^_`(2OL0!DK[``8`#`H"$`H+@A +M#`!OXP#@J"$``)`A``"8(:^]`$2OH`!4$$`!9```L"&"@@``)I0``1!```X` +M0(@A)`(`)1(B`!@"("`A`N`H(0/`^`D`````CZ(`5"1"``&OH@!4@H(``":4 +M``$40/_T`$"((8^B`%2/OP"$C[X`@(^W`'R/M@!XC[4`=(^T`'"/LP!LC[(` +M:(^Q`&2/L`!@`^``"">]`)""D0``)`(`+2:4``$``"@AKZ``4!(B`3JOH`!( +M)`(`,%(B`3."D0``KZ``3"8B_]`L0@`*$$``#B0"`"Z/HP!(``,0@`!#$"$` +M`A!``%$0(8*1```D0O_0KZ(`2"8B_]`L0@`*%$#_]2:4``$D`@`N$B(!$8^B +M`$PD`@!L$B(!!Z^@`$`F(O^^,$,`_RQB`#<00``:)B+_VP`#$(`\`X`")&,8 +M1`!#$"&,0@```$``"``````0H`#R)`+__":B```/`^`D"X"@A)`(``20#``BOH@!,KZ,`2"8B_[PP1`#_+((` +M-5!``!*OO0!$/`.``@`$$(`D8QIP`$,0(8Q"````0``(`````#P(@`(E"!?D +M`D`@(0)@*"$#H#`A)`<`"@P`<````````$"P(:^]`$2/H@!(CZ,`0`!6@",F +M`O__`$.`"X^B`$P00``#)!$`(!1@`#HD$0`PCZ(`4!1```Z/H@!``@`0(1A` +M``HF$/__`B`@(0/`^`D"X"@ACZ,`5`(`$"$F$/__)&,``1Q`__BOHP!4CZ(` +M0!1``"(`0"`A`L`0(1A```XFUO__CZ(`1`+@*"&`40``)$(``:^B`$0#P/@) +M`B`@(8^C`%0"P!`A)M;__R1C``$<0/_TKZ,`5(^B`%!00/]9@H(```(`$"$8 +M0/]5)A#__R0$`"`#P/@)`N`H(8^C`%0"`!`A)A#__R1C``$<0/_XKZ,`5!`` +M_TN"@@```\#X"0+@*"&/HP!4)&,``1``_]JOHP!4`&`@(0/`^`D"X"@ACZ,` +M5*^@`$`D8P`!$`#_P*^C`%0\"(`")0@7T`)`("$"8"@A`Z`P(1``_ZLD!P`0 +M/`B``A``__DE"!?P)`0`)0/`^`D"X"@A$`#_J(^B`$B/M@!(%L``!2;&__\D +M%@!`)`(`(`!%L`HFQO__&,#_G0``@"$`$!:`!$$`!``````"$B@'$```!P`2 +M)\,00``$`A,H!@`0$",`4A`$`*(H)0(2(`]_]"OOP``/`*``@"`&"&,1%7HKZ4` +M%*^F`!BOIP`<`&`P(0``*"$GIP`4KZ@`(*^I`"2OJ@`H#`!P1*^K`"R/OP`` +M`^``"">]`#`GO?_P)`(G=!"B``2OOP``C[\```/@``@GO0`0)`(``52"__R/ +MOP``#`!N?@`````0`/_XC[\``">]__`D!``!K[\```P`<>HD!2=TC[\```/@ +M``@GO0`0),;__R0"__\0P@`(`(`8(9"B```DQO__)*4``:!B```D`O__%,+_ +M^B1C``$#X``(`(`0(23&__\D`O__$,(`!@"`&"$DQO__)`+__Z!E```4PO_\ +M)&,``0/@``@`@!`A/`.``HQB5?0D0@`!`^``"*QB5?0\`X`"C&)5]">]__`0 +M0``&K[\``(QB5?0D0O__$$``!0``("&L8E7TC[\```/@``@GO0`0#`!XYP`` +M```0`/_Z`````">]__``H!`A`,`8(0$`8"$!(&@AK[$`!`%@B"$`X%@AK[`` +M``"`*"$!0(`A`B`@(0!`,"$`8#@A`6!`(0&`2"&OOP`(#`!SBP&@4"&N$0`` +MC[\`"(^Q``2/L````^``"">]`!`GO?_PK[```*^_``2,@P`T)`(`$!!B``<` +M@(`A#`!T<0(`("&/OP`$C[````/@``@GO0`0#`!SR``````0`/_W`````#P" +M@`.,1*O4)[W_\*^_```,`'B")(0`&(^_```#X``()[T`$#P"@`,#X``(C$*K +MU">]__"OOP``#`!U10````"/OP```^``"">]`!`GO?_P`*`0(0#`&"$!`%@A +MK[$`!`%`B"$`X%`AK[````"`*"$!((`A`B`@(0!`,"$`8#@A`4!`(:^_``@, +M`'9U`6!((:X1``"/OP`(C[$`!(^P```#X``()[T`$">]__"OOP``#`!V?0`` +M``"/OP```^``"">]`!`GO?_PK[\```P`=NL`````C[\```/@``@GO0`0)[W_ +M\*^_```,`'<$`````(^_```#X``()[T`$">]__"OOP``#`!W&@````"/OP`` +M`^``"">]`!`GO?_PK[\```P`=S(`````C[\```/@``@GO0`0)[W_\*^_```, +M`'=&`````(^_```#X``()[T`$">]__"OOP``#`!W;P````"/OP```^``"">] +M`!`GO?_PK[\```P`=Y8`````C[\```/@``@GO0`0`^``"*RD```\`H`"`^`` +M"(Q"5A0\`H`"C$)6%(Q#``P#X``(C$(`"">]__``H!`A`,`8(:^Q``2OL``` +M`0"((0#@@"$`@"@A`$`P(0!@."&OOP`(#`!_=@$`("&N$0``C[\`"(^Q``2/ +ML````^``"">]`!`GO?_PK[\```P`?YH`````C[\```/@``@GO0`0)[W_\*^_ +M``",@@`H%$``!`"`*"&/OP```^``"">]`!`,`'\GC(0`"!``__N/OP``)[W_ +M\*^_```,`'G4`````(^_```#X``()[T`$">]__"OOP``#`!YUP````"/OP`` +M`^``"">]`!`GO?_PK[\```P`>AT`````C[\```/@``@GO0`0)[W_\*^_```, +M`'I]`````(^_```#X``()[T`$">]__"OOP``#`!ZF@````"/OP```^``"">] +M`!`GO?_PK[\`!*^P```,`'J^`*"`(:X"``"/OP`$C[````/@``@GO0`0)[W_ +M\*^_```,`'K``````(^_```#X``()[T`$">]__"OOP``#`!ZQ@````"/OP`` +M`^``"">]`!`GO?_PK[\```P`>LT`````C[\```/@``@GO0`0)[W_\*^_```, +M`'M"`````(^_```#X``()[T`$">]__"OOP``#`![<`````"/OP```^``"">] +M`!`D`P`%/`*``ZQ#J]`\`H`#)[W_\*Q`J]@\`H`#K[```*^_``0`@(`AK$2K +MU#P"@`*L0%7TC@(`$`!`^`F.!``4#`!TW0`````0`/_[C@(`$">]__`!*A`A +MK[$`!`"`B"&N)@`0)(0`&`"@,"&N)P`4KB(`#*XI``"N*@`$KBD`"`(@*"&O +MOP`,K[(`"*^P```,`'DT`0"0(3P"@`*,1584)C``2#P&@`("`"`A),;6L`P` +M?VD"`#@A/`.``I1D5?`D`@`$KA$`+"2%``&N(@`T)`(``:XB`#BN(``\KB`` +M>*X@`'PF(@"`I&55\*8D`$0D`P`%)&/__ZQ````$8?_])$(`!*XR`)@,`(*G +M`B`@(3P$@`,"("@A#`!X4"2$J]P"("`A#`""BP(@*"&/OP`,C[(`"(^Q``2/ +ML````^``"">]`!`GO?_P`2H0(:^Q``0`@(@AKB8`$"2$`!@`H#`AKB<`%*XB +M``RN*0``KBH`!*XI``@"("@AK[\`#*^R``BOL```#`!Y-`$`D"$\`H`"C$56 +M%"8P`$@\!H`"`@`@(23&UK`,`']I`@`X(3P#@`*49%7P)`(`!*X1`"PDA0`! +MKB(`-"0"``&N(@`XKB``/*X@`'BN(`!\)B(`@*1E5?"F)`!$)`,`!21C__^L +M0```!&'__21"``2N,@"8#`""IP(@("$\!(`#`B`H(0P`>%`DA*O<`B`@(0P` +M@HL"("@AC[\`#(^R``B/L0`$C[````/@``@GO0`0)[W_\*^P```D@P!(K[\` +M!(QB`"@`@(`A%$``%`!@*"$\!(`#`@`H(0P`>%(DA*O]__"OL````("`(3P$@`,DA*O%("`"@A/`.``HQB5?0D0@`!K&)5]#P"@`*,1%7LC(,`G!!P`!X\`H`"C$)5 +M[!1B__L`8"`A/`.``HQB5?0D0O__$$``$@````"L8E7T)@0`2`P`?X.F``!$ +MC@0`&"8#`!@0@P`'C[\`!(QB``2L@@`$C&(`!*QC``2L1```K@,`&(^P```# +MX``()[T`$`P`>.<``"`A$`#_[0`````\!8`"C@(`G(RC5>P4]__"OOP`(K[$`!*^P```\`H`#C%"KU#P1@`*.(E7T)$(` +M`:XB5?2.`@`T/`2``R2$J]P00``2`@`H(8X"`#0T0@`!K@(`-(XB5?0D0O__ +M$$``!P``("&N(E7TC[\`"(^Q``2/L````^``"">]`!`,`'CG`````!``__@` +M````#`!X#0`````0`/_MC@(`-">]__"OL```K[\`"*^Q``0`@(`A/`.``HQB +M5?0D0@`!K&)5](R"`#0D`__\`$,8)#!"``,00``+))$`&*R#`#2.(@`,`(`H +M(11``!D`0"`AC@(`-#P$@`,"`"@A$$``$"2$J]P\`X`"C&)5]"1"__\00``' +M```@(:QB5?2/OP`(C[$`!(^P```#X``()[T`$`P`>.<`````$`#_^``````, +M`'?>`````!``_^X`````#`!XR0`````0`/_EKB``#">]__"OOP```(`P(3P" +M@`*,0U7T)&,``:Q#5?2,@P`X)`(``5!B`!&,@@`T$&```B1B__^L@@`X/`.` +M`HQB5?0D0O__$$``!0``("&L8E7TC[\```/@``@GO0`0#`!XYP`````0`/_Z +M`````"0#__L`@"@AK(``.`!#$"0\!(`#)(2KW!1`_^RLP@`T#`!WW@`````0 +M`/_H`````">]__"OOP```(`P(3P"@`*,0U7T)&,``:Q#5?2,@@`X$$``"20# +M__N,@@`T`(`H(:R``#@`0Q`D/`2``R2$J]P00``.K,(`-#P#@`*,8E7T)$+_ +M_Q!```4``"`AK&)5](^_```#X``()[T`$`P`>.<`````$`#_^@`````,`'?> +M`````!``__``````)[W_\*^_```\`H`"C$-5]"1C``&L0U7TC(,`>"QB``@0 +M0``*``,0@#P#@`(D8QN0`$,0(8Q"````0``(`````"0"``2L@@!\K(``>`P` +M=$$`````/`.``HQB5?0D0O__$$``!0````"L8E7TC[\```/@``@GO0`0#`!X +MYP``("$0`/_Z`````">]__"OOP`(K[$`!*^P```\`X`#C'"KU#P1@`*.(E7T +M)$(``:XB5?2,8JO4)$,`2(QB`"@40``1`&`H(8X"`#0\!(`#)`,`$`(`*"$0 +M0P`#)(2KW`P`>`VN`P`TCB15]`P`>.<`````C[\`"(^Q``2/L````^``"">] +M`!`,`'\GC&0`"!``_^Z.`@`T)[W_\*^P``"OOP`$/`*``XQ"J]00@@`[`("` +M(3P"@`*,0U7T)&,``:Q#5?0,`'28`@`@(28%`$B,H@`H%$``+0````".`P!\ +M)`(`!A!B`!``````C@,`>"QB``@00``,``,0@#P#@`(D8QNP`$,0(8Q"```` +M0``(`````(X"`#000``3/`2``R0"`!"N`@`T#`!T00(`("$\`X`"C&)5]"1" +M__\00``&`````*QB5?2/OP`$C[````/@``@GO0`0#`!XYP``("$0`/_Y```` +M`"2$J]P,`'@-`@`H(1``_^LD`@`0)`(`!JX"`'P0`/_HK@``>`P`?R>,I``( +M$`#_THX#`'P,`'3=`````!``_\,`````)[W_X*^R``BOL```K[\`$*^S``RO +ML0`$`("`(0"@D"$\`X`"C&)5]"1"``&L8E7TC((`-!!``$0``)@A,$(``5!` +M``D\!(`#))$`&(XS``P28``$`F`@(0P`>,D"`"@AKB``##P$@`,DA*O<#`!X +M4@(`*"&.`@`P4$``!JX2`"".`@`@`D(0*A!```*N$@`LKA(`(#P"@`,D4:O< +M`B`@(0P`>%`"`"@AC@(`-!!``"("("`A,$(``1!```8\`H`#$F``!`)@("$, +M`'BG`@`H(3P"@`.,0JO4$@(`%"0#``$,`'@T`@`@(3P#@`*,8E7T)$+__Q!` +M``D`````K&)5](^_`!"/LP`,C[(`"(^Q``2/L````^``"">]`"`,`'CG```@ +M(1``__8`````/`*``Q``_^VL0ZO8#`!WW@(`*"$0`/_D/`*``SP$@`,DA*O< +M#`!X#0(`*"$0`/_#/`2``R>]__`\`H`#K[\``(Q#J]0`@!`A/`2``Q!#``0D +MA*NXC[\```/@``@GO0`0#`!V20`````0`/_[C[\``">]__"OOP``C*0`+#P# +M@`*,8E7T)$(``:QB5?2,@P!X+&(`"!!```H``Q"`/`.``B1C&]``0Q`AC$(` +M``!```@`````)`(`!ZR"`'RL@`!X#`!T00`````\`X`"C&)5]"1"__\00``% +M`````*QB5?2/OP```^``"">]`!`,`'CG```@(1``__H`````$`#_[B0"``,G +MO?_PK[\``#P#@`.,8IL0)$(``0!`("$,`&J[K&*;$!``__H\`X`#/`*``R1" +MFQ@`@A`C)[W_\``"$4.OL`````*`0`("@"$`$!$``@*`(0`0$@`"`H`A`!`4 +M``("@"$`$(`C/`*``R1"F[@`$$L`/`:``CP(@`(!(D@A)0@;\```."$D"A`` +M),;71"0%`!^OOP`(K[$`!`P`]_^`D`CJ8K[,`#*^R``BOOP`0K[$`!*^P +M````H)@A$*(`&`"`D"$D`CJ8$F(`"`````"/OP`0C[,`#(^R``B/L0`$C[`` +M``/@``@GO0`@%D#_^#P"@`,D0IL8$$#_]210`*`\`H`#)$*;&!("__$F$/]@ +M#`!SYP(`("$0`/_Z/`*``R0"``$4@O_H)`(ZF#P"@`,D49L8``"`(0P`==L" +M("`A)A#__R0"__\6`O_[)C$`H!``_]TD`CJ8)[W_\"0$``&OOP``#`!V`R0% +M.IB/OP```^``"">]`!`GO?_P```@(:^_```,`'8#)`4ZF(^_```#X``()[T` +M$`/@``@`````/`*``B1"V0BL@@```^``"*R```0GO?_PK[\``(R"``2,@P`` +M`&#X"0!`("&/OP```^``"">]`!`GO?_PK[\``#P"@`.,0JO4`(`8(0"@,"$` +M0"`A#`!UG0!@*"&/OP```^``"">]`!`GO?_P)`(NX!"B``2OOP``C[\```/@ +M``@GO0`0)`(``52"__R/OP``/`2``PP`=D0DA*NX$`#_]X^_```GO?_P)`0` +M`:^_```,`'9>)`4NX(^_```#X``()[T`$*R``!2LA0``K(8`!*R(``BLB0`, +MK(<`$`/@``BL@``8)[W_\*^_```,`'<$`````(^_```#X``()[T`$">]__"O +ML```/!"``XX"J\P40``%K[\`!(^_``2/L````^``"">]`!!`"&````````$` +M("$\`?__-"'__@$!0"1`B&``````````````````,(0``8X#J\R,8@`8K@*K +MS(QE`!2L8``40`A@```````PA``!`01`)4"(8`````````````````",8@`, +MC&8`$`!`^`F,9```C@*KS!1`_^*/OP`$$`#_WH^P```GO?_PK[\```P`=H0` +M````C[\```/@``@GO0`00`A@```````!`"@A/`'__S0A__X!`4`D0(A@```` +M`````````````#"E``&,@@`4/`:``R1"``&L@@`4C(,`%"0"``$08@`*```` +M`$`(8```````,*4``0$%0"5`B&`````````````#X``(`````(S"J\RL@@`8 +M$`#_]*S$J\PGO?_P,(0``A"```6OOP``$*```P"@("$,`':V`````#P#@`*, +M8E7T)$+__Q!```4``"`AK&)5](^_```#X``()[T`$`P`>.<`````$`#_^@`` +M``",@P``/`*``B1"-R```QB``&(H(8RB```\`H`")$(X$`!B."$\`H`")$(W +MF`"`,"&,I````&(8(3P"@`(D0KPD4((``XS"``@#X``(`````*RB``",P@`0 +MK&(``!``__JLY@``C(,``#P"@`(D0C<@``,8@`!B."$\`H`")$(X$(R%``B, +MY````&(P(3P"@`(D0C>8$(4``P!B&"$#X``(`````#P"@`(D0KPDK.(``*Q@ +M```0`/_YK,```#P$@`.,@JO`%$``$0````!`"&````````$`&"$\`?__-"'_ +M_@$!0"1`B&``````````````````,&,``3P"@`.L0ZO()`,``3P"@`.L0ZO$ +MC(*KP"1"``$#X``(K(*KP#P"@`.,0ZO`)&/__ZQ#J\",0JO`%$``##P"@`.L +M0*O$/`*``XQ"J\A`"&```````#!"``$!`D`E0(A@``````````````````/@ +M``@`````0`A@```````!`#`A/`'__S0A__X!`4`D0(A@```````````````` +M`##&``$D@O_Z)`,``3P%H,``0Q@$+((`!A!``!,TI0`40`-@`"0"!```@A`$ +M`$`0)P!B&"1`@V``````````````````0`A@```````PQ@`!`09`)4"(8``` +M``````````/@``@`````C*(``#!"``$``Q`+$`#_\ZRB``!`"&````````$` +M,"$\`?__-"'__@$!0"1`B&``````````````````,,8``22"__HD`P`!/`6@ +MP`!#&`0L@@`&$$``$C2E`!1``V``)`($``""$`0`8A@E0(-@```````````` +M`````$`(8```````,,8``0$&0"5`B&`````````````#X``(`````(RB```` +M0Q`E$`#_]*RB```L@@`&)`4`!`""*`M``V@`)`($``"B$`0`0!`G`&(8)$"# +M:`````````````/@``@`````)`(NX!"B``,D`@`!`^``"``````4@O_]/`*` +M`ZQ`J\00`/_Z`````">]__`D!``!K[\```P`=Z,D!2[@C[\```/@``@GO0`0 +M)[W_\```("&OOP``#`!WHR0%+N"/OP```^``"">]`!`D`P`!/`*``JQ#5?0D +M!0`?)(,`!"2E__\D`O__K&```!2B__PD8P`$)`,`!3P"@`.L@```K$.KT"0# +M``$\`H`#`^``"*Q#J]@GO?_PK[\`!*^P````@(`A#`!JE(R$`````A"``@*` +M(8X#``2/OP`$C[```"1B_^@``Q`*`^``"">]`!`GO?_@K[(`"*^Q``2OL``` +MK[\`$*^S``R,LP`@C*,`)`"`@"$`$Q"``*"0(0!@("$48``>`@*((8XB``0F +M0P`8```@(0!R(`LD`P`!%$``!`)C&`2.`@```$,0):X"``".(P`$5&``"XQB +M``2N)``$#`!X-`)`("&/OP`0C[,`#(^R``B/L0`$C[````/@``@GO0`@K(,` +M`*R"``2,8@`$K&0`!!``__*L1```#`!XR0`````0`/_ACB(`!(RG`"`DHP`8 +M``48"@`'$(``@C`AC,(`!`!@*"$08@`2),@`!(QB``",8P`$K$,`!(RC``2L +MI0`$K&(``*RE``"-`@``%$``!B0"``&,@P```.(0!``"$"<`8A@DK(,```/@ +M``@`````4&#_]HT"``",8P``4&7_\JS```2,H@`$K&(`!(RB``2LI0`$K$,` +M`*RE```0`/_JK,,`!#P%@`.,HZO4C((`((QC`"``0Q`J%$``!20#``&,HJO4 +MC$(`-!!```,`````/`*``ZQ#J]@#X``(`````#P"@`,D0JO4``8P@`#","$G +MO?_P`*`@(:S%``"OOP``#`!T<0````"/OP```^``"">]`!`#X``(``````/@ +M``@`````/`.``XQBJ]`GO?_PK[\``"1"__\00``$K&*KT(^_```#X``()[T` +M$`P`>&(`````$`#_^X^_```\!8`#C*.KT#P"@`,48``6C$2KU(R"`#040``3 +M/`*``XR#`"`D0JO<``,8@`!B&"&,8@`$4$``!(QC``2,0@``K&(`!(QC``0D +M8O_H``,0"A!$``,D`P`!/`*``ZQ#J]@D`@`%K**KT`/@``@`````K(4`"*R$ +M``0#X``(K(0``">]__"OOP``/`.``HQB5?0D0@`!K&)5]"2$_^B,@@`T%$`` +M$3P"@`.,@P`@)$*KW``#&(``8A@AC&(`!%!```2,8P`$C$(``*QB``2,8P`$ +M)&+_Z``#$`H01``*)`,``3P"@`.L0ZO8/`*``HQ$5?0,`'CG)(3__X^_```# +MX``()[T`$"0#``4\`H`#$`#_]JQ#J]",A@``)*(`&```&"$4P``$`$48"ZR# +M```#X``(K*0`)(S"``2L9@``K&(`!(S"``2LPP`$$`#_^*Q#``",@P``$&`` +M#"1B_^B,90``4*,`":R```",8@`$K*(`!(QB``2L8P`$K$4``*QC``"LA0`` +M)&+_Z``#$`I40``!K$``)`/@``@`````K*``)(R#```DH@`8``40"A!#``H` +M0"@AC$(``(RC``2L0P`$C*,`!*RE``2L8@``K*4```/@``@`````$$#__0`` +M``",0P``$&(`"0````",0@`$K&(`!(RB``2LI0`$K$,``*RE```#X``(K(,` +M``/@``BL@```)[W_\*^Q``2OOP`,K[(`"*^P````@(@A%B``!3P2@`,\`H`# +MC$*KS!1``"\`````CE"KU(X"`#040``$/`*``XQ"J]@00``3`````#P$@`,, +M`'?/)(2KW!("``D`0"`A/`.``XQBK&`DA``,)@4`#"1"``$,``+^K&*L8*Y0 +MJ]0D`@`%/`.``ZQBJ]`\`H`#K$"KV!8@`!``````/`.``JQ@5?0\`H`#C$*K +MS!!```6/OP`,C&)5]"1"``$0`/_6K&)5](^R``B/L0`$C[````/@``@GO0`0 +M/`*``JQ15?00`/_XC[\`#`P`=J\\$H`#$`#_SP`````GO?_PK[\```P`>2D` +M````/`2``R>]__"OOP``#`!WSR2$J]P\`X`#K&"KV"1$``P\`X`##``##ZQB +MJ]0GO?_PK[````#`*"&OOP`$#`!X?@"`@"&N```8K@``#*X``!"/OP`$C[`` +M``/@``@GO0`0)[W_\*^Q``2OOP`,K[(`"*^P``",D@`(`("((0"R$"H40``' +M)(3_Z(^_``R/L@`(C[$`!(^P```#X``()[T`$(XP`!@,`'5%KB``&%(```&N +M,@`4)`(``1``__.N(@`8)[W_\*^_``",P@``%$``!`"@,"&/OP```^``"">] +M`!`,`'E!C*4`(!``__N/OP``)[W_\*^_``",@@`0`(`P(11```HDA/_HC,(` +M&!!```B/OP``C,,`%(S"``BLP``8`$,0*A1```0`8"@AC[\```/@``@GO0`0 +M#`!U10`````0`/_[C[\``">]__"OOP```*`P(0P`>4&,I0`@C[\```/@``@G +MO0`0)[W_\*^_```,`'E9`````(^_```#X``()[T`$">]__"OOP``#`!Y90`` +M``"/OP```^``"">]`!`GO?_PK[\```P`>4$``#`AC[\```/@``@GO0`0)[W_ +M\*^_```,`'EE`````(^_```#X``()[T`$">]__`D`BKXK[$`!*^P``"OOP`( +M`*"((1"B`!8`@(`A)`(J^!(B``8`````C[\`"(^Q``2/L````^``"">]`!`6 +M`/_Z/`*``R11J]PD`O_\$B+_]B8P`(0F(@`$$@+_\R80__P,`(+-`@`@(1`` +M__LF(@`$)`(``52"_^HD`BKX/`2``PP`=[TDA*O<$`#_Y20"*O@GO?_P)`0` +M`:^_```,`'F?)`4J^(^_```#X``()[T`$">]__```"`AK[\```P`>9\D!2KX +MC[\```/@``@GO0`0K(4```/@``BL@``$)[W_\*^Q``2OL```K[\`#*^R``@\ +M`H`#`("`(8Q2J]0D$0`!/`.``HQB5?0D0@`!K&)5](R"```00``7/`2``Q(@ +M``0`````C@(``"1"__^N`@``/`.``HQB5?0D0O__$$``"0````"L8E7T`B`0 +M(8^_``R/L@`(C[$`!(^P```#X``()[T`$`P`>.<``"`A$`#_]@````",@ZO4 +M)`(``:QB`'B,@JO4#`!T':Q``'P"0"@A#`!XIR8$``0\`H`"#`!XYXQ$5?2. +M0P!\*&(`!!1```8H9``&5(``!```B"$D`@`&$&(`"`````".`@``%$#_TP`` +M```6(/_G/`2``Q``_]0`````#`!TW0`````0`/_WC@(``">]_^"OL0`$K[\` +M$*^S``ROL@`(K[```#P%@`,`@(@AC+*KU#P#@`*,8E7T)$(``:QB5?2,HZO4 +M)`(``P``0"$``$@AK&(`>(RBJ]2L0`!\C*2KU`P`?YHDA`!(CD(`?(XC```4 +M8``#+%```18``"(\`X`#/`*``XQ"J]0D10!(C*(`*!1``!@`````$@``!``` +M``".(@``)$+__ZXB```\`X`"C&)5]"1"__\00``*`````*QB5?0"`!`AC[\` +M$(^S``R/L@`(C[$`!(^P```#X``()[T`(`P`>.<``"`A$`#_]0`````,`'\G +MC*0`"!``_^8`````C&*KU"03``.L4P!XC&*KU`P`=!VL0`!\)B0`!`P`>*<" +M0"@A/`*``@P`>.>,1%7TCD,`?"AB``800``-)`(`!BAB``100``#``"`(5!S +M``$``(`ACB(``!1`_\D\`H`#%@#_YSP#@`,0`/_%`````%1B__F.(@``#`!T +MW0`````0`/_UCB(``">]__"OL```K[\`!"00``$\`H`"C$-5]"1C``&L0U7T +MC((``!A``!$D0___K(,``#P#@`*,8E7T)$+__Q!```<``"`AK&)5]`(`$"&/ +MOP`$C[````/@``@GO0`0#`!XYP`````0`/_X`````!``__```(`A)[W_\*^_ +M``2OL````(`8(3P0@`*.`E7T)$(``:X"5?2,@@``C(4`!"2$``0D0@`!%*`` +M#JQB``".`E7T)$+__Q!```8``"`AK@)5](^_``2/L````^``"">]`!`,`'CG +M`````!``__D`````#`!XM@`````D`P`'K$``>*Q#`'P,`'1!`$`@(1``_^L` +M`````^``"(R"```D`@`!K((`#*R```B@@````^``"*R```0GO?_PK[\```P` +M@LTDA``(C[\```/@``@GO0`0)[W_X*^S``ROL0`$K[\`$*^R``BOL```/`*` +M`P"`B"&,4JO4)!,``3P#@`*,8E7T)$(``:QB5?2,@@`,4$``!HXC``PF0P`8 +MC&(`$"1"``&L8@`0CB,`#"0"``)08@!9CB4`$)(B```40``N/`.``U)@`!:. +M(@`,)`(``:XR``2B(@``/`.``HQB5?0D0O__$$``"@````"L8E7T`F`0(8^_ +M`!"/LP`,C[(`"(^Q``2/L````^``"">]`"`,`'CG```@(1``__4`````4$`` +M!HXC``PF0P`8C&(`$"1"__^L8@`0CB,`#"0"``$08@`)`````(XC``PD`@`" +M%&+_X0`````,`'F8)D0`&!``_]T`````#`!YBB9$`!@0`/_VCB,`#(QBJ]0D +M$``!K%``>(QBJ]0,`'0=K$``?`)`*"$,`'BG)B0`"(XB``P04``8`D`H(3P" +M@`(,`'CGC$15](Y#`'PH8@`$%$``!BAD``94@``$``"8(20"``808@`(```` +M`)(B```00/^Y`````!9@_^0\`X`#$`#_S(XB``P,`'3=`````!``__8````` +MCB0`!`P`>7LDA``8$`#_YCP"@`(,`'F1)D0`&!``_Z4`````)[W_\*^P``"O +MOP`$`(`H(200``$\`H`"C$-5]"1C``&L0U7TD((``%1``!```(`A/`*``XQ" +MJ]2,@P`,H+```"1&`!@`P"`A$&``!*RB``2,P@`0)$(``:S"`!",HP`,)`(` +M`A!B`!``````/`.``HQB5?0D0O__$$``!P``("&L8E7T`@`0(8^_``2/L``` +M`^``"">]`!`,`'CG`````!``__@`````#`!YD8RE`!`0`/_N`````">]__"O +ML```K[\`#*^R``BOL0`$`("`(3P"@`*,0U7T)&,``:Q#5?2,@@`(%$``*R22 +M``B.`@`,4$``!XX#``R.`P`$)&,`&(QB`!`D0O__K&(`$(X#``PD`@`!4&(` +M&XX$``2.`P`,)`(``E!B`!..!``$K@``!*(````\`X`"C&)5]"1"__\00``( +M`````*QB5?2/OP`,C[(`"(^Q``2/L````^``"">]`!`,`'CG```@(1``__<` +M````#`!YF"2$`!@0`/_LK@``!`P`>8HDA``8$`#_Y(X#``P,`'BV`D`@(8X# +M``P`0(@A)`(``5!B``B.!0`$)`(`!ZXB`'RN(`!X#`!T00(@("$0`/_*C@(` +M#"8D`!@,`'F#`D`P(1``__8D`@`')[W_\*^_``2OL```/`*``HQ&5?@`@"@A +M/`.``HQB5?0D0@`!K&)5]`P`@)<`P"`A#`"#+P!`@"$"`!`AC[\`!(^P```# +MX``()[T`$">]__"OOP`````P(1"```0`@"@A/`*``@P`@N*,1%7XC[\```/@ +M``@GO0`0)[W_P```*"$D!@`LK[``,*^_`#0,`'(-`("`(20"__^CH@`HKZ(` +M`*^B``2OH@`(KZ(`#*^B`!"OH@`4KZ(`&*^B`""OH@`D/`*``HQ$5?BCH``< +M/`.``HQB5?0D0@`!K&)5]`.@,"$,`()8)`4`7@P`@R\`````CZ(`!%Q```&N +M`@``CZ(`"%Q```&N`@`$CZ(`#%Q```&N`@`]`$`GO?_P-`*WF*^Q``2OL```K[\` +M"`"@B"$0H@`/`("`(30"MY@2(@`%C[\`"(^Q``2/L````^``"">]`!!6`/_[ +MC[\`"#P$@`,,`(-()(2L9!``__:/OP`(/`6``R2EL<`\!H`$/`2``R0"``$` +MQ3`C)(2L9!8"_^H``#@A#`"#/@`````0`/_G-`*WF">]__`D!``!K[\```P` +M?`HT!;>8C[\```/@``@GO0`0)[W_\```("&OOP``#`!\"C0%MYB/OP```^`` +M"">]`!"0@@`,,*7__P`%&@(T0@"`H((`##!"`'^@@P`$H(4```/@``B@@@`, +M)[W_\#P%H,`\!O_\K[\`!*^P```TI0`@$(``&S3&__^,@P``)`(``S1C``,` +M8(`AK(,``(RC````9A@DK*,``*(```0,`&U'H@(`##P#&TXT8X&U`$,`&0(` +M("$``!`0``(3@@P`?#T`0"@A)`(`!Z("``B/OP`$H@``!(^P```#X``()[T` +M$#P"@`(0`/_D)$16`!"``!`PI0#_C(0```.`&"$\'(`#)YS64)""`!0P0@`@ +M$$#__0````"@A0``D((`%#!"`"`00/_]``````/@``@`8.`A/`*``A``_^\D +M1%8`$(``##P"@`*,A``````8(9""`!0P0@`!$$``!`````"0@@``)`,``:"B +M```#X``(`&`0(1``__0D1%8`)[W_X*^P`!"OOP`8K[$`%`"`@"$#@(@A/!R` +M`R> +M/`*``HXC``0``Q"``$,0(0`"@$`"("`A#`!\@`)@*"$`0!@A)`0`9!1```HF +M$/__)`+__Q("``<\`H``)$(#`(Q"`$@`0/@)`````!``__("("`A`D#@(8^_ +M`!"/LP`,C[(`"(^Q``2/L````&`0(0/@``@GO0`@$`#_XB115@`GO?_`K[(` +M"*^_`!"OLP`,K[$`!*^P``"OI@`HKZ<`+*^H`#"OJ0`TKZH`.*^K`#P``)`A +M`X"8(3P<@`,GG-90$(``9#P"@`(LH@`($$``&CP#@`(`!1"`)&,;_`!#$"&, +M0@```$``"`````",@P``/`*``B0%``&L158,D&(`!#10``&@<``$C)$`""HB +M``800``2/`2@P$`#8``D`@0``B(0!`!B&"5`@V```````````````````F#@ +M(0)`$"&/OP`0C[,`#(^R``B/L0`$C[````/@``@GO0!`-(0`%(R#```F(O_Z +M`$40!`!B&"40`/_QK(,``(^P`"@,`&U'C)$````"$0(`4``;4@```0```]_^"OL``0K[\`&*^Q`!0`@#`A`*"`(0`` +M0"$#@(@A/!R``R>]`!`D`@`!#`!]QJQB5A`0`/_ZC[\````` +M$"$``!@AK(4`$*R```"L@@`(`^``"*R#``R,@@``$$``$0````",@P``4&`` +M#(R"``",90``4*,`"*R```",8@`$K*(`!(QB``2L8P`$K$4``*QC``"LA0`` +MC((``%1`__*,@P```^``"``````GO?_0K[(`&"0"__\DLO__K[$`%*^_`""O +MLP`]`#`,`'CG```@(1``_\P`````C@(`&(X#`!R.!@`@ +MC@<`)`!G&"$`9T`K`$80(0!($"&N`@`8K@,`'`P`?MD"`"@A$`#_L(X"``R. +M(@`,`$,0*Q1```2/HP``CB(`#!``_Z..`@`@5&```XQB``00`/^HK[```*X# +M``"N`@`$C&(`!*QP``00`/^BK%```">]__"OL0`$K[```*^_``@`@(@A`*"` +M(3P#@`*,8E7T)$(``:QB5?0D`@`!K*(`*(RC`!B,@@`(`$,0*U1``"V.(P`` +MC((`"%!B`#2,HP`]__"OOP``/`*``HQ#5?0D8P`!K$-5](R" +M```0H@`6`````(RB``",HP`$K$,`!(RC``2LI0`$K&(``*RE``"LH``H/`.` +M`HQB5?0D0O__$$``!0``("&L8E7TC[\```/@``@GO0`0#`!XYP`````0`/_Z +M`````%"@__*LH``HC*,``%!E_^ZL@```C*(`!*QB``2,H@`$K*4`!*Q#``"L +MI0``$`#_YJR#```GO?_@KZ4``"0%``&OOP`4K[``$*^F``0,`'X?`("`(8^B +M``"/OP`4K@(`%(^B``2N`@`8C[``$`/@``@GO0`@)[W_\*^_```,`'XF```` +M`(^_```#X``()[T`$```$"$``!@AK(4`"*R&``RLAP`0K(``**R$``2LA``` +MK((`&*R#`!RL@@`@`^``"*R#`"0``!`A```8(:R%``BLA@`,K(<`$*R``"BL +MA``$K(0``*R"`!BL@P`,A``($`#_\HX#```GO?_@K[4`$*^T``ROLP`( +MK[(`!*^P``"OOP`4C((`*`"`@"$`@"@A`,"0(0#@F"$!`*`A%$``$`$@J"&. +M!``(KA(`&*X3`!RN%``@KA4`)`P`?MD"`"@AC[\`%(^U`!"/M``,C[,`"(^R +M``2/L````^``"">]`"`,`'\GC(0`"!``_^^.!``()[W_X*^R``BOOP`4K[4` +M$*^T``ROL0`$K[```(R"`"",B@`D`$!8(0!*$"400``:`("0(8R"``B,D``@ +MC)$`)(R4`!B,E0`]__"OOP``#`!M4@`````\ +M`X`"K&)7?$"`2`````````````````!`@E@`````````````````#`!WEB0$ +M``6/OP``)`(``P/@``@GO0`0)[W_\*^_```,`'X[`,`@(3P$@`,,`'A4)(2K +MW(^_```#X``()[T`$">]__`D`C:PK[$`!*^P``"OOP`(`*"((1"B`!$`@(`A +M)`(VL!(B``8\`H`#C[\`"(^Q``2/L````^``"">]`!`6`/_Z)%&P>`P`=GTF +M)``<#`!_8@(@("$0`/_UC[\`""0"``%4@O_O)`(VL#P$@`,,`(``)(2P>!`` +M_^HD`C:P)[W_\"0$``&OOP``#`"`2B0%-K"/OP```^``"">]`!`GO?_P```@ +M(:^_```,`(!*)`4VL(^_```#X``()[T`$*R%``"LA@`$K(``#*R```@``$`A +M`(`X(24(``$DX@`(+0,`@*SB`!"LX@`4%&#_^@!`."$PHP`'4&```P``&"$D +M`@`(`$,8(R1B`!``PA`K4$```XR"``0#X``(K(````"C&"&L@P`0-$(``0/@ +M``BL8@`$C((```"`8"$00``=``!8(02@`!L`````)*4`"RBB`!=40``#)`4` +M$"0"__@`HB@D+*(!^!!``/``!1I"`*P0(21)``B-)P`,$.D`#P`%6,*,XP`$ +M)`+__HSJ``P`8D`D`.@8(8QB``2,Z0`().L`"#1"``&M20`(K&(`!*TJ``P# +MX``(`6`0(21)`!"-)P`,5.G_\(SC``0E:P`"C8<`&"6.`!`0[@`N)`/__HSB +M``0`0T`D`04P(RC"`!!40``.K8X`'`#E0"$TH@`!`088(33$``$DZP`(K.(` +M!*V(`!BL9@``K00`!*T.``BMB``<$`#_XZT.``P$P``'K8X`&`#H&"&,8@`$ +M).L`"#1"``$0`/_;K&(`!"T"`@`00`""``@:0@`((,(`!!#``8(0(21*``B- +M@P`,C4D`"``$(((D`@`!`((0!`!B&"6M@P`,K.H`#*SI``BM)P`,K4<`""EC +M```E8@`#`6,0"HV&``P``A"#)`,``0!#(`0`Q!`K5$``.XV$`!``AA`D%$`` +M#``+$,``!"!`)`+__`%B$"0`AA@D%&``!21+``0`!"!``(80)!!`__TE:P`$ +M``L0P`&"$"$D20`(`6!H(0$@4"&-1P`,4.H`#B5K``&,X@`$)`/__@!#0"0! +M!3`C*,(`$%!``#^,Z0`(!,,`-0#H&"&,YP`,5.K_]XSB``0E:P`!,6(``Q1` +M_^XE2@`(,:(``R4I__@00``E):W__XTB``@02?_[,:(``XV#``P`!"!``&00 +M*U1```J-A``0$(``!P"#$"140/_:``L0P``$($``@Q`D$`#_^R5K``2-A``0 +M)`/__HR"``0`0Q`D`$48*Q1@``0`13`C*,(`$%!```,`@#@A$`#_>@``6"$T +MPP`!`(4@(32B``&LX@`$K80`$*R#``00`/]R).L`"(V"``P`!!@G`$,0)!`` +M_]NM@@`,C&(`!(SJ``R,Z0`(-$(``23K``BL8@`$$`#_9*U)``B,Z@`,`.5` +M(32B``$!!A@A-,0``:U)``BLX@`$K8@`&"3K``BL9@``K00`!*T.``@0`/]R +MK2H`#!!@``8`""#"+&(`!1!``!XL8@`5``@1@B1$`#@`!!#``8(0(21*``B- +M20`($2H`$22#``.-(@`$)`/__@!#$"0!`A`K4$#_>(TJ``R-*0`($2H`!B0# +M__Z-(@`$`$,0)`$"$"M40/_ZC2D`"!``_VZ-*@`,*((```!B(`N-@P`,$`#_ +M90`$((,40/_D)&0`6RQB`%400``$+&(!50`($P(0`/_>)$0`;A!```0L8@55 +M``@3PA``_]DD1`!W4$#_UR0$`'X`"!2"$`#_U"1$`'P08``&``58PBQB``40 +M0``=+&(`%0`%$8(D2P`X``L0P`&"$"$D2@`(C4<`#%#J_QTE:P`!C.(`!"0# +M__X`0T`D`04P(RC"`!!00``&)6O__P3#``8`Z!@AC.<`#%3J__>,X@`$$`#_ +M#R5K``&,8@`$C.H`#(SI``@T0@`!$`#^_R3K``@40/_E)&L`6RQB`%400``$ +M+&(!50`%$P(0`/_?)$L`;A!```0L8@55``43PA``_]HD2P!W4$#_V"0+`'X` +M!12"$`#_U21+`'P`@%@A$*``0```&"$DJ?_XC28`!"0"__Z,A``0`,)`)`$H +M4"&-0P`$$40`=0!B&"0XP@`!,$(``:U#``000``*``!@(8RE__@E8@`0`25( +M(XTD``@0@@!H`05`(8TG``RLY``(K(<`#`%#$"&00@`'.$(``3!"``$00``, +M-0(``16```4!`T`AC4,`""5B`!!08@!4)`P``8U&``B-1P`,K.8`"*S'``PU +M`@`!`2@8(:TB``05@``3K&@``"T"`@!00``3``@:0@`((,(`!!#``6(0(21' +M``B-8P`,C.8`"``$(((D`@`!`((0!`!B&"6M8P`,K2<`#*TF``BLR0`,K.D` +M""0#``$#X``(`&`0(1!@``8`""#"+&(`!1!``!\L8@`5``@1@B1$`#@`!!#` +M`6(0(21'``B,Y@`($,<`$B2#``.,P@`$)`/__@!#$"0!`A`K4$#_YXS'``R, +MQ@`(4,?_Y(S'``R,P@`$)`/__@!#$"0!`A`K5$#_^8S&``@0`/_*S#`)"LP@",K,D`=*S``(2LP`"`K,,`?`/@``BL +MA@`,)[W_\*^_```\`X`"C&)5]"1"``&L8E7T/`*``HQ"5>P40``1`$`8(:R$ +M`)P\`H`"K$15[#P#@`*,8E7T)$+__Q!```4`````K&)5](^_```#X``()[T` +M$`P`>.<``"`A$`#_^@`````0@__P/`*``HQ"5>R,8P"<%&+_^P`````0@__K +M/`*``HQB`)RL@@"<$`#_YJQD`)R,@@``$$``$0````",@P``4&``#(R"``", +M90``4*,`"*R```",8@`$K*(`!(QB``2L8P`$K$4``*QC``"LA0``C((``%1` +M__*,@P```^``"``````GO?_0K[(`&*^_`"BOM0`DK[0`(*^S`!ROL0`4K[`` +M$`"`D"$\`H`"C$-5]"1C``$,`('(K$-5]`!`J"&.0@00$$``&B94!!"OH``` +M#`!XM@*`("&,4P!``D`@(0!`@"$,`("7CF4```!`B"$"`"`A$$``+`(`*"$D +M`@`'K@(`?`P`=$&N``!XKG$`!(Y"!!!40/_N)E0$$(^B```40``7``````P` +M@LT#H"`A/`.``HQB5?0D0O__$$``#`````"L8E7T`J`0(8^_`"B/M0`DC[0` +M((^S`!R/L@`8C[$`%(^P`!`#X``()[T`,`P`>.<``"`A$`#_\P`````,`'BV +M`Z`@(0!`*"$,`'BG`H`@(8^B```40/_Y`````!``_^$`````#`!XIP.@("$0 +M`/_8CD($$">]__"OOP``/`.``HQB5?0D0O__$$``!0``("&L8E7TC[\```/@ +M``@GO0`0#`!XYP`````0`/_Z`````">]__"OL```K[\`!`P`@'H`@(`AK@`$ +M$(^_``2/L````^``"">]`!`GO?_PK[```*^_``ROL@`(K[$`!`"`@"$\`H`" +MC$-5]"1C``&L0U7TC(($$"22!!`40``3`D"((3P#@`*,8E7T)$+__Q!```H` +M````K&)5]`P`@LT"0"`AC[\`#(^R``B/L0`$C[````/@``@GO0`0#`!XYP`` +M("$0`/_U``````P`>+8"("`A)`,`!:Q#`'RL0`!X#`!T00!`("&.`@00%$#_ +M]P`````0`/_C`````(RG```0X``&`(`8(8R&``!4P``%C.(`!*R'``"LH``` +M`^``"`````",Q``$K,(`!(QC``"LY``$K$,``!``__>LAP```````$UE;6]R +M>2!UF4@5'@Z("5D("!2 +M>#H@)61="@H``%1!4D=?=V1C5'A-X@`!WN(``=[B``'>X@`!W +MN(``=[B``'>X@`!WN(``=[B``'>X@`!WN(``=[B``'>X@`!WN(``=[B``'>X +M@`!WN(``=\B``'?<@`!W\(``>$PD260Z("\O9&5P;W0O4-A8VAE +M+F,C."`D``"``+#8@`"H%(``I^2``+$@@`"H%(``J!2``*@4@`"H%(``J!2` +M`*@4@`"H%(``J!2``*@4@`"H%(``J!2``*@4@`"Q1(``L52``*@4@`"H%(`` +MJ!2``*@4@`"H%(``J!2``*@4@`"H%(``J!2``*@4@`"H%(``J!2``*@4@`"H +M%(``L50D260Z("\O9&5P;W0OL@`"G?(``L+B``*>L@`"GK(``IZR` -M`*>L@`"GK(``IZR``*>L@`"GK(``IZR``*>L@`"GK(``IZR``+#<@`"P[(`` -MIZR``*>L@`"GK(``IZR``*>L@`"GK(``IZR``*>L@`"GK(``IZR``*>L@`"G -MK(``IZR``*>L@`"P["1)9#H@+R]D97!O="]S=R]BR``4'T@`%!_(`!0@2``4(0@`%"&(`!0B2``4(P -M@`%"/(`!0DB``4)4@`%"8(`!0FR``4)X@`%"A(`!0I"``4*<@`%"J(`!0K2` -M`4+`@`%"X(`!0NR``4+X@`%#!(`!0Q"``4,<@`%#*(`!0S2``4-`@`%#3(`! -M0UB``4-D@`%#<"XN+RXN+RXN+RXN+RXN+VAA;"]W9&,O=&%R9V5T+W-R8R]A -M(`!7'B``5T(@`%<>(`!71R``5V`@`%=B(`! -M79"``5V8@`%=H(`!7:B``5VP@`%<>(`!7;B``5W$@`%=T(`!7=B``5WT@`%@ -MY(`!8B2``6'`@`%AS(`!8B2``6'4@`%AW(`!8>2``6'L@`%A](`!8?R``6(< -M@`%B)(`!8BR``6)(55-".B5S(%LE9%T*`````'9E;F1OIB` -M`7JT@`%Z4(`!>M"``7I0@`%Z[(`!>PB``7LD@`%[0(`!>UR``7NX@`%[U(`! -M>_!/=F5R:61E(#H@)60@96X@.B`E9`H```!#;VYF:6<@.B`E>`H`````@`&* -MZ(`!BO"``8L4@`&+'(`!BR2``8LL@`&+L(`!B[2``8O8@`&+\(`!B_B``8P` -M@`&,"$4*```P,3(S-#4V-S@Y04)#1$5&`````#`Q,C,T-38W.#D``#`Q,C,T +M4&]W97(N8R,U("0`@`#5H(``UCB``-4D@`#6E(``UU@D260Z("\O9&5P;W0O +M(@`%'E(`!1Z"``4>L@`%'N(`! +M1\2``4?0+BXO+BXO+BXO+BXO+BXO:&%L+W=D8R]T87)G970O(`! +M@91/=F5R:61E(#H@)60@96X@.B`E9`H```!#;VYF:6<@.B`E>`H`````@`&0 +M=(`!D'R``9"@@`&0J(`!D+"``9"X@`&1/(`!D4"``9%D@`&1?(`!D82``9&, +M@`&1E$4*```P,3(S-#4V-S@Y04)#1$5&`````#`Q,C,T-38W.#D``#`Q,C,T M-38W.#EA8F-D968`````/$YO="!A('-T_8 -M@`'OF(`![YB``>^8@`'P((`![TR``?"<@`'PI``!`@(#`P,#!`0$!`0$!`0% +M("`@(````"4P-%@@````("`@("````"``=-`@`'3+(`!TRR``=,L@`'30(`! +MTT"``=-`@`'30(`!U'R``=3D@`'4Y(`!U.2``=28@`'4F(`!U)B``=28@`'7 +M"(`!UPB``=;T@`'7/(`!UPB``=<(@`'7"(`!UPA)9&QE(%1HBTX`WHM.`-Z+3@``"86'Z`#2Y^@`TN?N@-+G[H -M#2Y^@`TN``"87#$W9EXQ-V9>,3=F7C$W9EXQ-V9>``"88```G1```)T0``"= -M&```G1@``)T0``"89``!S@```X$"#WN!`@][@-$/>X$!#WN!`0``"B -M!```````````````"`````@````(``"B"-:^1XC6OD>(T#Y'B-`^1XC0/D>( -M``"B#&0L`4!D+`%`9$+!8&1"P6!D0L%@``"B'!B#@`H8@X`*&&.`"AB#@`H8 -M@X`*``"B,````````````````````0@`````````#``````````T````!0`` -M`$``````````1`````@```!(````"````$P````0````4`````````!4```` -M'P``"``````````(!`````````@(````````"`P````````($`````````@4 -M````````"!@````````('`````````@@````````""0````````2,``````` -M`!)P````````$#@````````0>````````!"X````````$/@````````1.``` -M`````!%X````````$;@````````1^````````!(X````````$G@````````2 -MN````````!+X````````$S@````````3>````````!.X````````$_@````` -M```4.````````!1X````````%+@````````4^````````!4X````````%7@` -M```````5N````````!7X````````%C@````````6>````````!:X```````` -M%O@````````7.````````!=X````````%[@````````7^````````!`\```` -M````$'P````````0O````````!#\````````$3P````````1?````````!&\ -M````````$?P````````2/````````!)\````````$KP````````2_``````` -M`!,\````````$WP````````3O````````!/\````````%#P````````4?``` -M`````(`$````````@`@```````"`#````````(`8````````@"````````"` -M)````````(`H````,```@"P`!___``"`,`'___\``(`T````,0``@#@````` -M``"`/````````(!(````````@%0```````"`6````````(!<___'_P``@&`` -M```/``"`@````````("$````````@(@```````"`C````````("0```````` -M@)0```````"`F````````(#`*H(P&@``@,0%W`'@``"`R!]`)Q```(#,`?0` -M````@-```!X<``"`U``"JJH``(#8`@!550``@-P```````"`X/____\``(#D -M``#__P``@.@```````"`[````````(#P````````@/0```````"`^``````` -M`(#\````B```AP````````"'!````(P``(<(````Y```APP```+5``"'$``` -M`````(<4````````AQ@```"@``"''````'1P``)@(````````F`RMA(X9``"8$'THX````)@4G`J?:P``F!P````` -M``"8+``"H`(``)@\``(!````F$`@:@%Z``"83!*$(SP``)A4```(60``F0`` -M``````"9!````````)D(````````F0P`@`````"9$`````$``)D<```,@``` -MF2`%$`````"9*`````$``)DL````!```F3```$B"``"9-!X?("(``)DX"@L, -M#0``F3P````_``"90`````0``)E(DH"R$@``F51=4.&(``"96````/\``)E< -M`$MJC@``F6@```/.``"92JJJJJ``"9Z#Q& -M9'@``)GL````J@``HA``@&,S``"B%``0;!```*(8`)Q`8```HB`!B##&``"B -M)```!````*(H```)M0``HBP```````"B-"`@("```*(X("`@(```HCP3R(FO -M``"B0#A)"B```*)$``![M@``HD@/_S_\``"B3````````*)0````````HE0` -M``````";`````````)L$`````0``FP@````"``";#`````,``)L0````!``` -MFQ0````%``";&`````@``)L<````"0``FR`````*``";)`````L``)LH```` -M#```FRP````-``";,````!```)LT````$0``FS@````2``";/````!,``)M` -M````%```FT0````5``";2````!@``)M,````&0``FU`````:``";5````!L` -M`)M8````'```FUP````=``";8````"```)MD````(0``FV@````B``";;``` -M`",``)MP````)```FW0````E``";>````"@``)M\````*0``FX`````J``"; -MA````"L``)N(````+```FXP````M``";D````#```)N4````,0``FY@````R -M``";G````#,``)N@````-```FZ0````U``";J````#4``)NL````-0``F[`` -M```U``";M````#4``)NX````-0``F[P````U``";P````#4``)O$````-0`` -MF\@````U``";S````#4``)O0````-0``F]0````U``";V````#4``)O<```` -M-0``F^`````U``";Y````#4``)OH````-0``F^P````U``";\````#4``)OT -M````-0``F_@````0``";_````!H``)H`````!P````<``)H$````1P```$<` -M`)H(````AP```(<``)H,```!H````:```)H0```!X````>```)H4````(``` -M`"```)H8````8````&```)H<```!H0```:$``)H@```!X0```>$``)HD```` -M(0```"$``)HH````80```&$``)HL```!8@```6(``)HP```!H@```:(``)HT -M```!X@```>(``)HX````(@```"(``)H\````8@```&(``)I````!8P```6,` -M`)I$```!HP```:,``)I(```!XP```>,``)I,````(P```",``)I0````8P`` -M`&,``)I4```!A````80``)I8```!Q````<0``)I<````!`````0``)I@```! -MZ@````L``)ID````*@```$L``)IH````:@```(L``)IL````J@```:P``)IP -M```!JP```>P``)IT```!ZP```"P``)IX````*P```!(``)I\````:P```%(` -M`)J`````JP```)(``)J$```!K````9,``)J(```![````=,``)J,````+``` -M`!,``)J0````.@```%,``)J4````>@```),``)J8````N@```90``)J<```! -MNP```=0``)J@```!^P```!0``)JD````.P```#H``)JH````>P```'H``)JL -M````NP```+H``)JP```!O````;L``)JT```!_````?L``)JX````/````#L` -M`)J\````?````'L``)K`````O````+L``)K$````_````;P``)K(````_``` -M`?P``)K,````_````#P``)K0````_````'P``)K4````_````+P``)K8```` -M_````/P``)K<````_````/P``)K@````_````/P``)KD````_````/P``)KH -M````_````/P``)KL````_````/P``)KP````_````/P``)KT````_````/P` -M`)KX````_````/P``)K\````_````/P``)C4````(```F-`#!@0(`P<$"`,& -M!`@#!@0(`P<$"```F-P`H,#``*#`P`#@P,``X,#``.#`P```F)P*````"@`` -M``H````*````"@``````F)P`````````````````````````````F)P`@``` -M`(````"`````@````(``````F)P`*@```"H````J````*@```"H`````F)P` -M`0````$````!`````0````$`````F)P````````````````````````````` -MF)P`&````!@````8````&````!@`````F)P`8````&````!N````;@```&X` -M````F)P`QP```,<```#'````QP```,<`````F)P`2P```$L```!+````2P`` -M`$L`````F)P$2```!$@```1(```$2```!$@`````F)P`3````$P```!,```` -M3````$P`````F)P`Y````.0```#D````Y````.0`````F)P````````````` -M````````````````F)P`_````/P```#\````_````/P`````F)P`_P```/\` -M``#_````_P```/\`````F)P$/P``!#\```0_```$/P``!#\`````F)P,#``` -M#`P```P,```,#```#`P`````F)P"&0```AD```(9```"&0```AD`````F)P` -M)````"0````D````)````"0`````F)P`M````+0```"T````M````+0````` -MF)P`F0```)D```"9````F0```)D`````F)P`4````%````!0````4````%`` -M````F)P`*@```"H````J````*@```"H`````F)P`$@```!(````2````$@`` -M`!(`````F)S`,@``P#(``,`R``#`,@``P#(`````F)P!=````70```%T```! -M=````70`````F)P`$0```!$````1````$0```!$`````F)R&*```AB@``(8H -M``"&*```AB@`````F)PQA```,80``#&$```QA```,80`````F)P`\@"``/(` -M@`#R`(``\@"``/(`@```F)P`)P`9`"<`&0`G`!D`)P`9`"<`&0``F)P````# -M`````P````,````#`````P``F)P`````````````````````````````F)P` -M``"R````L@```+(```"R````L@``F)P`L"&$`+`AA`"P(80`L"&$`+`AA``` -MF)P`026D`$$EI`!!):0`026D`$$EI```F)P`$9(@`!&2(``1DB``$9(@`!&2 -M(```F)P`&D@``!I(```:2```&D@``!I(````F-@`"P(P``L",``+`C``"P(P -M``L",```F)P```"4````E````)0```"4````E```F)P```"1````D0```)$` -M``"1````D0``F)P````2````$@```!(````2````$@``F)P```"`````@``` -M`(````"`````@```F)P```#9````V0```-D```#9````V0``F)P```!@```` -M8````&````!@````8```F)P```#P````\````/````#P````\```F)P```"B -M````H@```*(```"B````H@``F)P```!2````4@```%(```!2````4@``F)P` -M``#4````U````-0```#4````U```F)P``!3,```4S```%,P``!3,```4S``` -MF)P```2,```$C```!(P```2,```$C```F,0````#`````P````,````#```` -M`X``\02``/5L@`$,<`````,`!@`)`#\```````D````$``0``0`!``$````` -M``````````9&1S@```````````````````0````!``$```````````````1& -M1S<```````````````````,``0`!``$```````````````-&1S8````````` -M``````````0```````$```````````````%&1S4```````````````````0` -M`0`!``````````````````!&1S0```````````````````0````!```````` -M`````/____Y&1S,```````````````````,``0`!`````````````/____U& -M1S(```````````````````0``````````````````/____Q&1S$````````` -M``````````(``0`!`````````````/____I&1S`````````````````````` -M````````````````````````````````````````````````"`````$``P`` -M````````````````````!D9'-P```````````````````@`````````````` -M`````````$9'-@```````````````````0``````````````````_____49' -M-0``````````````````````````````````````____^D9'-``````````` -M```````````!``$`````````````____^$9',P`````````````````````! -M``$````!``$`````____]D9',@`````````````````````!`````0`!``$` -M````____\T9',0`````````````````````!`````0`!`````0``____\$9' -M,``````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````" -M````!`````H````!`````P````H````"````!0````H````"````!`````H` -M```"`````P````H``````````@````,```````````````"``D1X@`)$@(`" -M1,2``D3H@`)$?/\``0P"!@`-`P`'``````X*!```"```&0``````%1L/'PL% -M```````)```8```4&AX`````%P`3'0`6$AP1$``"8EH``/#<*``$```!;C8` -M``@``&=(``!G2```9T@``&=(``!G2` +M50!:`%\`9```````"@`4`!X`*``R`#P`1@!0`%H`9```*%`6+%@H```)#14` +M````,```@!4``(`5``"`%0``@!4``(`5```00``O_`\`+_P/`"_\'P`O_`\` +M+_P/```01``O_`\`+_P/`"_\'P`O_`\`+_P/```02``O_`\`+_P/`"_\'P`O +M_`\`+_P/```03``O_`\`+_P/`"_\'P`O_`\`+_P/```04``O_`\`+_P/`"_\ +M'P`O_`\`+_P/```05``O_`\`+_P/`"_\'P`O_`\`+_P/```06``O_`\`+_P/ +M`"_\'P`O_`\`+_P/```07``O_`\`+_P/`"_\'P`O_`\`+_P/```08``O_`\` +M+_P/`"_\'P`O_`\`+_P/```09``O_`\`+_P/`"_\'P`O_`\`+_P/```0,``` +M`C````'@````L````6````'@```0<````6@```'@```!N````8P```'@```0 +ML```#F```!&````?'```/C@``!&````0\```H.```4!H``!8@```L.```4!H +M``"`%`/H`^@&X`;@!"`$(`A`"$`&X`;@``"`'!*-DZ<)B!//!.`3E1+@$ZL) +MB!//``"8!``````````#```````````````#``"8(`("`@`"`@(``@$"``(" +M`@`"`@(```"8)```#@X```X.```'!P``#@X```X.``"8*`H"``$*`@`!!0(! +M``H"``$*`@`!``"8-```#@X```X.```.#@``#@X```X.``"8.`````<````' +M````"P````L````+``"81!-R%AP3BTX`WHM.`-Z+3@``"86'Z` +M#2Y^@`TN?N@-+G[H#2Y^@`TN``"87#$W9EXQ-V9>,3=F7C$W9EXQ-V9>``"8 +M8```G1```)T0``"=&```G1@``)T0``"89``!S@```X$"#WN!`@][@- +M$/>X$!#WN!`0``"B!```````````````"`````@````(``"B"-:^1XC6OD>( +MT#Y'B-`^1XC0/D>(``"B#&0L`4!D+`%`9$+!8&1"P6!D0L%@``"B'!B#@`H8 +M@X`*&&.`"AB#@`H8@X`*``"B,````````````````````0@`````````#``` +M```````T````!0```$``````````1`````@```!(````"````$P````0```` +M4`````````!4````'P``"``````````(!`````````@(````````"`P````` +M```($`````````@4````````"!@````````('`````````@@````````""0` +M```````2,````````!)P````````$#@````````0>````````!"X```````` +M$/@````````1.````````!%X````````$;@````````1^````````!(X```` +M````$G@````````2N````````!+X````````$S@````````3>````````!.X +M````````$_@````````4.````````!1X````````%+@````````4^``````` +M`!4X````````%7@````````5N````````!7X````````%C@````````6>``` +M`````!:X````````%O@````````7.````````!=X````````%[@````````7 +M^````````!`\````````$'P````````0O````````!#\````````$3P````` +M```1?````````!&\````````$?P````````2/````````!)\````````$KP` +M```````2_````````!,\````````$WP````````3O````````!/\```````` +M%#P````````4?````````(`$````````@`@```````"`#````````(`8```` +M````@"````````"`)````````(`H````,```@"P`!___``"`,`'___\``(`T +M````,0``@#@```````"`/````````(!(````````@%0```````"`6``````` +M`(!<___'_P``@&`````/``"`@````````("$````````@(@```````"`C``` +M`````("0````````@)0```````"`F````````(#`*H(P&@``@,0%W`'@``"` +MR!]`)Q```(#,`?0`````@-```!X<``"`U``"JJH``(#8`@!550``@-P````` +M``"`X/____\``(#D``#__P``@.@```````"`[````````(#P````````@/0` +M``````"`^````````(#\````B```AP````````"'!````(P``(<(````Y``` +MAPP```+5``"'$````````(<4````````AQ@```"@``"''````'1P``)@(````````F`RMA(X9``"8$'THX````)@4 +MG`J?:P``F!P```````"8+``"H`(``)@\``(!````F$`@:@%Z``"83!*$(SP` +M`)A4```(60``F0````````"9!````````)D(````````F0P`@`````"9$``` +M``$``)D<```,@```F2`%$`````"9*`````$``)DL````!```F3```$B"``"9 +M-!X?("(``)DX"@L,#0``F3P````_``"90`````0``)E(DH"R$@``F51=4.&( +M``"96````/\``)E<`$MJC@``F6@```/.``"92JJJJJ``"9Z#Q&9'@``)GL````J@``HA``@&,S``"B%``0;!```*(8`)Q` +M8```HB`!B##&``"B)```!````*(H```)M0``HBP```````"B-"`@("```*(X +M("`@(```HCP3R(FO``"B0#A)"B```*)$``![M@``HD@/_S_\``"B3``````` +M`*)0````````HE0```````";`````````)L$`````0``FP@````"``";#``` +M``,``)L0````!```FQ0````%``";&`````@``)L<````"0``FR`````*``"; +M)`````L``)LH````#```FRP````-``";,````!```)LT````$0``FS@````2 +M``";/````!,``)M`````%```FT0````5``";2````!@``)M,````&0``FU`` +M```:``";5````!L``)M8````'```FUP````=``";8````"```)MD````(0`` +MFV@````B``";;````",``)MP````)```FW0````E``";>````"@``)M\```` +M*0``FX`````J``";A````"L``)N(````+```FXP````M``";D````#```)N4 +M````,0``FY@````R``";G````#,``)N@````-```FZ0````U``";J````#4` +M`)NL````-0``F[`````U``";M````#4``)NX````-0``F[P````U``";P``` +M`#4``)O$````-0``F\@````U``";S````#4``)O0````-0``F]0````U``"; +MV````#4``)O<````-0``F^`````U``";Y````#4``)OH````-0``F^P````U +M``";\````#4``)OT````-0``F_@````0``";_````!H``)H`````!P````<` +M`)H$````1P```$<``)H(````AP```(<``)H,```!H````:```)H0```!X``` +M`>```)H4````(````"```)H8````8````&```)H<```!H0```:$``)H@```! +MX0```>$``)HD````(0```"$``)HH````80```&$``)HL```!8@```6(``)HP +M```!H@```:(``)HT```!X@```>(``)HX````(@```"(``)H\````8@```&(` +M`)I````!8P```6,``)I$```!HP```:,``)I(```!XP```>,``)I,````(P`` +M`",``)I0````8P```&,``)I4```!A````80``)I8```!Q````<0``)I<```` +M!`````0``)I@```!Z@````L``)ID````*@```$L``)IH````:@```(L``)IL +M````J@```:P``)IP```!JP```>P``)IT```!ZP```"P``)IX````*P```!(` +M`)I\````:P```%(``)J`````JP```)(``)J$```!K````9,``)J(```![``` +M`=,``)J,````+````!,``)J0````.@```%,``)J4````>@```),``)J8```` +MN@```90``)J<```!NP```=0``)J@```!^P```!0``)JD````.P```#H``)JH +M````>P```'H``)JL````NP```+H``)JP```!O````;L``)JT```!_````?L` +M`)JX````/````#L``)J\````?````'L``)K`````O````+L``)K$````_``` +M`;P``)K(````_````?P``)K,````_````#P``)K0````_````'P``)K4```` +M_````+P``)K8````_````/P``)K<````_````/P``)K@````_````/P``)KD +M````_````/P``)KH````_````/P``)KL````_````/P``)KP````_````/P` +M`)KT````_````/P``)KX````_````/P``)K\````_````/P``)C4````(``` +MF-`#!@0(`P<$"`,&!`@#!@0(`P<$"```F-P`H,#``*#`P`#@P,``X,#``.#` +MP```F)P*````"@````H````*````"@``````F)P````````````````````` +M````````F)P`@````(````"`````@````(``````F)P`*@```"H````J```` +M*@```"H`````F)P``0````$````!`````0````$`````F)P````````````` +M````````````````F)P`&````!@````8````&````!@`````F)P`8````&`` +M``!N````;@```&X`````F)P`QP```,<```#'````QP```,<`````F)P`2P`` +M`$L```!+````2P```$L`````F)P$2```!$@```1(```$2```!$@`````F)P` +M3````$P```!,````3````$P`````F)P`Y````.0```#D````Y````.0````` +MF)P`````````````````````````````F)P`_````/P```#\````_````/P` +M````F)P`_P```/\```#_````_P```/\`````F)P$/P``!#\```0_```$/P`` +M!#\`````F)P,#```#`P```P,```,#```#`P`````F)P"&0```AD```(9```" +M&0```AD`````F)P`)````"0````D````)````"0`````F)P`M````+0```"T +M````M````+0`````F)P`F0```)D```"9````F0```)D`````F)P`4````%`` +M``!0````4````%``````F)P`*@```"H````J````*@```"H`````F)P`$@`` +M`!(````2````$@```!(`````F)S`,@``P#(``,`R``#`,@``P#(`````F)P! +M=````70```%T```!=````70`````F)P`$0```!$````1````$0```!$````` +MF)R&*```AB@``(8H``"&*```AB@`````F)PQA```,80``#&$```QA```,80` +M````F)P`\@"``/(`@`#R`(``\@"``/(`@```F)P`)P`9`"<`&0`G`!D`)P`9 +M`"<`&0``F)P````#`````P````,````#`````P``F)P````````````````` +M````````````F)P```"R````L@```+(```"R````L@``F)P`L"&$`+`AA`"P +M(80`L"&$`+`AA```F)P`026D`$$EI`!!):0`026D`$$EI```F)P`$9(@`!&2 +M(``1DB``$9(@`!&2(```F)P`&D@``!I(```:2```&D@``!I(````F-@`"P(P +M``L",``+`C``"P(P``L",```F)P```"4````E````)0```"4````E```F)P` +M``"1````D0```)$```"1````D0``F)P````2````$@```!(````2````$@`` +MF)P```"`````@````(````"`````@```F)P```#9````V0```-D```#9```` +MV0``F)P```!@````8````&````!@````8```F)P```#P````\````/````#P +M````\```F)P```"B````H@```*(```"B````H@``F)P```!2````4@```%(` +M``!2````4@``F)P```#4````U````-0```#4````U```F)P``!3,```4S``` +M%,P``!3,```4S```F)P```2,```$C```!(P```2,```$C```F,0````#```` +M`P````,````#`````X``\V"``/BD@`$/J`````,`!@`)`#\```````D````$ +M``0``0`!``$```````````````9&1S@```````````````````0````!``$` +M``````````````1&1S<```````````````````,``0`!``$````````````` +M``-&1S8```````````````````0```````$```````````````%&1S4````` +M``````````````0``0`!``````````````````!&1S0````````````````` +M``0````!`````````````/____Y&1S,```````````````````,``0`!```` +M`````````/____U&1S(```````````````````0``````````````````/__ +M__Q&1S$```````````````````(``0`!`````````````/____I&1S`````` +M```````````````````````````````````````````````````````````` +M````"`````$``P``````````````````````!D9'-P`````````````````` +M`@```````````````````````$9'-@```````````````````0`````````` +M````````_____49'-0``````````````````````````````````````____ +M^D9'-``````````````````````!``$`````````````____^$9',P`````` +M```````````````!``$````!``$`````____]D9',@`````````````````` +M```!`````0`!``$`````____\T9',0`````````````````````!`````0`! +M`````0``____\$9',``````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````"````!`````H````!`````P````H````"````!0````H` +M```"````!`````H````"`````P````H``````````@````,````````````` +M``"``E08@`)4((`"5&2``E2(@`)4'/\``0P"!@`-`P`'``````X*!```"``` +M&0``````%1L/'PL%```````)```8```4&AX`````%P`3'0`6$AP1$``"8EH` +M`/#<*``$```!;C8``$@`%```@`!X -M2``5``"``'A(`!8``(``>$@`%P``@`!X2``8``"``'A(`!D``(``>$@`4``3 -M`%$`$P!3`!,`5@`3`%4`$P!5`!,`@``3`($`$P```,(```#$````Q0```-`` -M``#:````Y````,(```##````U````/(```$-```!*``````````````````` -M`!#_``````````````````````````````````````````````$`````%W`5 -M&`L`C``"`0`\`#P```````$`````(R@>>`\`$@`#`0`\`#P```````$````` -M+N`G$`H`F`($`@`P`#````````$`````1E`V3`X`)`(&`@`P`#````````$` -M````7`!X```````$````!1E!I%`X`)`H& -M`@`>`!X```````$````!7<"!L`D`L`P*`P`:`!H```````$````!C*"J4`T` -M2`P.`P`:`!H```````$````!NX#(9`@`8`P3`P`:`!H```````$````!TO#7 -M/`P`;`P7`P`:`!H````````````````````````````````````````````` +M``````````````````"``K"P```````3``"``'B4$1,``(``>)0`,```@`!X +ME``4``"``'B4`!4``(``>)0`%@``@`!XE``7``"``'B4`!@``(``>)0`&0`` +M@`!XE`!0`!,`40`3`%,`$P!6`!,`50`3`%4`$P"``!,`@0`3````P@```,0` +M``#%````T````-H```#D````P@```,,```#4````\@```0T```$H```````` +M````````````$/\````````````````````````````````````````````` +M`0````$`````%W`5&`L`C``"`0`\`#P```````$````!`````",H'G@/`!(` +M`P$`/``\```````!`````0`````NX"<0"@"8`@0"`#``,````````0````$` +M````1E`V3`X`)`(&`@`P`#````````$````!`````%W`0Y0)`+`$"@,`+``L +M```````!`````0````",H%G8#0!(!`X#`"P`+````````0````$`````NX!K +M"`@`8`03`P`L`"P```````$````!`````-+P```````!`````0`` +M``%&4&D4#@`D"@8"`!X`'@```````0````$````!7<"!L`D`L`P*`P`:`!H` +M``````$````!`````8R@JE`-`$@,#@,`&@`:```````!`````0````&[@,AD +M"`!@#!,#`!H`&@```````0````$````!TO#7/`P`;`P7`P`:`!H````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````````!D```` +M,@4+,@<(```````````````````(_P`````````````````````````````` +M```````````````!`````0`````+N`J,"P"&``(!`'@`>````````0````$` +M````$90//`\`"0`#`0!X`'@```````$````!`````!=P$X@*`(P"!`(`8`!@ +M```````!`````0`````C*!LF#@`2`@8"`&``8````````0````$`````+N`A +MR@D`F`0*`P!8`%@```````$````!`````$90+.P-`"0$#@,`6`!8```````! +M`````0````!=P#6$"``P!!,#`%@`6````````0````$`````:7@Y.@P`-@07 +M`P!8`%@````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````&0````R````!P````````````````````C_```````````````` +M``````````````````````````````$````!``````7>#P`$``,!`/``\````````0````$`````"[@) +MQ`H`A@($`@#``,````````$````!`````!&4#9,.``D"!@(`P`#````````! +M`````0`````7`!X```````$````!`````5W`0Y0)`+`$#@,`&@`:```````!`````0`` +M``&,H%G8#0!(!!$#`!H`&@```````0````$````!NX!K"`@`8`06`P`:`!H` +M``````$````!`````=+P`!X```````$````!`````490:10. +M`"0-!@(`'@`>```````!`````0````%=P(&P"0"P#PH#`!H`&@```````0`` +M``$````!C*"J4`T`2`\.`P`:`!H```````$````!`````;N`R&0(`&`/$P,` +M&@`:```````!`````0````'2\-<\#`!L#Q<#`!H`&@`````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -3258,47 +3378,10 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M`````````````````````````````````````````````````````&0````R -M!0LR!P@```````````````````C_```````````````````````````````` -M``````````````$````!%W`5&`L`C``"`0`B`"(```````$````!(R@>>`\` -M$@`$`0`B`"(```````$````!+N`G$`H`F`('`@`>`!X```````$````!1E`V -M3`X`)`()`@`>`!X```````$````!7>`\`$@0#`0`\`#P```````$`````+N`G -M=`H`&`8$`0`P`#````````$`````1E`W%`X`)`8&`@`P`#````````$````` -M7`!X` -M``````$````!1E!I%`X`)`T&`@`>`!X```````$````!7<"!L`D`L`\*`P`: -M`!H```````$````!C*"J4`T`2`\.`P`:`!H```````$````!NX#(9`@`8`\3 -M`P`:`!H```````$````!TO#7/`P`;`\7`P`:`!H````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````&0````R"0XR"P<````` -M``````````````3_```````````````````````````````````````````` -M``$````"`^@#A!L`@@```0$Z`3H```````$````"!]`'"!H$A`$!`0$"`*(` -M``````$````"%7P0S!D$BP$"`@$"`*(```````$````"*O@;O!@$E@$$9`$" -M`*(````````````````````````````````````````````````````````` +M"0XR"P<```````````````````3_```````````````````````````````` +M``````````````$````!`````@/H`X0;`((```$!.@$Z```````!`````0`` +M``('T`<(&@2$`0$!`0(`H@```````0````$````"%7P0S!D$BP$"`@$"`*(` +M``````$````!`````BKX&[P8!)8!!&0!`@"B```````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -3313,16 +3396,20 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M`````,@```!D`````P````````````````8``&P`V`&\`XP%5`JP```````` M```````````````````````````````````````````````````````````` -M````````#?\``````````````````````````````````````````````0`` -M``,`^@#(`P`!`/&$@`'"5(`!ZTB``=-<@`'\/(`!V4B``>&D```` -M`#P$@``DA````^`((3P%@``DI0``/!^``B?_1N``OR@B!!$``0``````OR@@ -M`"#X(0/@,"$#X`@A/!J``B=:1W@\'X`")_]'#`-?T"($$0`!``````-?T"`` -M(/@A`T#X"0``````P$`A`^`((3P)@`(E*4=D/!^``B?_1T`!/T@B!!$``0`` -M```!/T@@`"#X(0$H0"(\`H`")$)'7`!```@`````!!$``0`````#Z$`B`0#X -M(0/@``@```````````"`0"$`H$@A/`N``B5K1W2-(@``K0(``"4I``0E"``$ -0%0O_^P`````#X``(```````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````````,@```!D +M````#`````"``D^<``````````"``4Q,@`%-`(`!362``4W8`````````!D` +M```R````2P```%````!3````50```%<```!8````6@```@````<@```"```` +M!R````(````"`````@````(````"`````@````(````"```````````````` +M```````$`PD$!`,@`#8#00!T`&@`90!R`&\` Date: Sat, 17 Apr 2010 23:14:06 +0000 Subject: [PATCH 2008/2592] MFC r202610: adds a hardware specific configuration file for uath(4). Pointed by: sam Reviewed by: imp, thompsa --- etc/devd/Makefile | 2 +- etc/devd/uath.conf | 120 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 etc/devd/uath.conf diff --git a/etc/devd/Makefile b/etc/devd/Makefile index f2bb1844917..ad434f270e3 100644 --- a/etc/devd/Makefile +++ b/etc/devd/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -FILES= asus.conf +FILES= asus.conf uath.conf NO_OBJ= FILESDIR= /etc/devd diff --git a/etc/devd/uath.conf b/etc/devd/uath.conf new file mode 100644 index 00000000000..33bee69bb17 --- /dev/null +++ b/etc/devd/uath.conf @@ -0,0 +1,120 @@ +# $FreeBSD$ +# +# Atheros USB wireless network device specific devd events + +# Accton +# SMCWUSB-G and SMCWUSBT-G2 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x083a"; + match "product" "(0x4505|0x4507)"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# Atheros Communications +# AR5523 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x168c"; + match "product" "0x0002"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# Atheros Communications +# AR5523 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x0cf3"; + match "product" "(0x0002|0x0004|0x0006)"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# Conceptronic +# AR5523 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x0d8e"; + match "product" "(0x7802|0x7812)"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# D-Link +# DWL-AG132, DWL-G132 and DWL-AG122 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x2001"; + match "product" "(0x3a01|0x3a03|0x3a05)"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# D-Link +# DWA-120 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x07d1"; + match "product" "0x3a0c"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# Gigaset +# SMCWUSBT-G +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x1690"; + match "product" "(0x0711|0x0713)"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# Global Sun Technology +# AR5523 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x16ab"; + match "product" "(0x7802|0x7812)"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# BayNETGEAR +# WG111U +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x0846"; + match "product" "0x4301"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# Netgear +# WG111T and WPN111 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x1385"; + match "product" "(0x4251|0x5f01)"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# U-MEDIA Communications +# TEW-444UB and AR5523 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x157e"; + match "product" "(0x3007|0x3206)"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# Wistron NeWeb +# AR5523 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x1435"; + match "product" "(0x0827|0x0829)"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; + +# Z-Com +# AR5523 +attach 100 { + device-name "ugen[0-9.]+"; + match "vendor" "0x0cde"; + match "product" "0x0013"; + action "/usr/sbin/uathload -d /dev/$device-name"; +}; From 88a85a4c47df1daac68071ee4dc301e6f0ad59da Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Sat, 17 Apr 2010 23:48:07 +0000 Subject: [PATCH 2009/2592] MFC r205140: fixes a broken software beacon miss handler. There is a race to check vap->iv_bmiss_count == 0 in ieee80211_swbmiss because iv_swbmiss_task is enqueued by taskqueue. Reviewed by: rpaulo --- sys/net80211/ieee80211_proto.c | 2 -- sys/net80211/ieee80211_sta.c | 2 ++ sys/net80211/ieee80211_tdma.c | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 9aabfcff8c6..edac51981f9 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -1432,8 +1432,6 @@ ieee80211_swbmiss(void *arg) } else if (vap->iv_swbmiss_count == 0) { if (vap->iv_bmiss != NULL) ieee80211_runtask(ic, &vap->iv_swbmiss_task); - if (vap->iv_bmiss_count == 0) /* don't re-arm timer */ - return; } else vap->iv_swbmiss_count = 0; callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period, diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index 26d6f157373..cc679bfb3be 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -141,6 +141,8 @@ sta_beacon_miss(struct ieee80211vap *vap) vap->iv_bss->ni_essid, vap->iv_bss->ni_esslen); return; } + + callout_stop(&vap->iv_swbmiss); vap->iv_bmiss_count = 0; vap->iv_stats.is_beacon_miss++; if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) { diff --git a/sys/net80211/ieee80211_tdma.c b/sys/net80211/ieee80211_tdma.c index 43f32f7fd98..8c191ab92b5 100644 --- a/sys/net80211/ieee80211_tdma.c +++ b/sys/net80211/ieee80211_tdma.c @@ -295,6 +295,8 @@ tdma_beacon_miss(struct ieee80211vap *vap) "beacon miss, mode %u state %s\n", vap->iv_opmode, ieee80211_state_name[vap->iv_state]); + callout_stop(&vap->iv_swbmiss); + if (ts->tdma_peer != NULL) { /* XXX? can this be null? */ ieee80211_notify_node_leave(vap->iv_bss); ts->tdma_peer = NULL; From 7a1b7e33b4df39a1e11776e9f6b55ef92c857dc3 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 18 Apr 2010 00:57:30 +0000 Subject: [PATCH 2010/2592] MFC r206664: Allow option aliasing. Lines of the form: OLD_OPT = NEW_OPT in options* files will now map OLD_OPT to NEW_OPT with a friendly message. This is indented for situations where we need to preserve an interface in the config file in an upwards compatible fashion on a stable branch. Reviewed by: nwhitehorn@ MFC after: 3 days --- usr.sbin/config/config.h | 2 ++ usr.sbin/config/mkoptions.c | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h index d55c96b00a9..ec199862ae7 100644 --- a/usr.sbin/config/config.h +++ b/usr.sbin/config/config.h @@ -129,6 +129,8 @@ SLIST_HEAD(opt_head, opt) opt, mkopt, rmopts; struct opt_list { char *o_name; char *o_file; + int o_flags; +#define OL_ALIAS 1 SLIST_ENTRY(opt_list) o_next; }; diff --git a/usr.sbin/config/mkoptions.c b/usr.sbin/config/mkoptions.c index 5cd9d61a824..1a6ccc8fec0 100644 --- a/usr.sbin/config/mkoptions.c +++ b/usr.sbin/config/mkoptions.c @@ -94,6 +94,17 @@ options(void) SLIST_INSERT_HEAD(&opt, op, op_next); read_options(); + SLIST_FOREACH(op, &opt, op_next) { + SLIST_FOREACH(ol, &otab, o_next) { + if (eq(op->op_name, ol->o_name) && + (ol->o_flags & OL_ALIAS)) { + printf("Mapping option %s to %s.\n", + op->op_name, ol->o_file); + op->op_name = ol->o_file; + break; + } + } + } SLIST_FOREACH(ol, &otab, o_next) do_option(ol->o_name); SLIST_FOREACH(op, &opt, op_next) { @@ -124,7 +135,6 @@ do_option(char *name) int tidy; file = tooption(name); - /* * Check to see if the option was specified.. */ @@ -292,6 +302,7 @@ read_options(void) struct opt_list *po; int first = 1; char genopt[MAXPATHLEN]; + int flags = 0; SLIST_INIT(&otab); (void) snprintf(fname, sizeof(fname), "../../conf/options"); @@ -301,6 +312,7 @@ openit: return; } next: + flags = 0; wd = get_word(fp); if (wd == (char *)EOF) { (void) fclose(fp); @@ -332,6 +344,18 @@ next: (void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s)); val = genopt; free(s); + } else if (eq(val, "=")) { + val = get_word(fp); + if (val == (char *)EOF) { + printf("%s: unexpected end of file\n", fname); + exit(1); + } + if (val == 0) { + printf("%s: Expected a right hand side at %s\n", fname, + this); + exit(1); + } + flags |= OL_ALIAS; } val = ns(val); @@ -348,6 +372,7 @@ next: err(EXIT_FAILURE, "calloc"); po->o_name = this; po->o_file = val; + po->o_flags = flags; SLIST_INSERT_HEAD(&otab, po, o_next); goto next; From 11b893bdc58413475f185a0353dea15c3ad7ab3b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 18 Apr 2010 01:15:47 +0000 Subject: [PATCH 2011/2592] Remap COMPAT_IA32 to COMPAT_FREEBSD32 to ease the transition of this option and not break 8.0 config files later in the 8.x branch. # Yes, this is a direct commit, since this is not relevant to head. --- sys/conf/options.amd64 | 1 + sys/conf/options.ia64 | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64 index 20a49a188c6..4f501f61cf6 100644 --- a/sys/conf/options.amd64 +++ b/sys/conf/options.amd64 @@ -11,6 +11,7 @@ MP_WATCHDOG # Options for emulators. These should only be used at config time, so # they are handled like options for static filesystems # (see src/sys/conf/options), except for broken debugging options. +COMPAT_IA32 = COMPAT_FREEBSD32 COMPAT_FREEBSD32 opt_compat.h #IBCS2 opt_dontuse.h #COMPAT_LINUX opt_dontuse.h diff --git a/sys/conf/options.ia64 b/sys/conf/options.ia64 index 603c5ed011f..cc70feb7c7a 100644 --- a/sys/conf/options.ia64 +++ b/sys/conf/options.ia64 @@ -9,6 +9,7 @@ LOG2_PAGE_SIZE opt_global.h UWX_TRACE_ENABLE opt_global.h +COMPAT_IA32 = COMPAT_FREEBSD32 COMPAT_FREEBSD32 opt_compat.h EXCEPTION_TRACING opt_xtrace.h From b7a43116e94cd88e4f8b5ee42da3187a1a7b62cd Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sun, 18 Apr 2010 03:52:41 +0000 Subject: [PATCH 2012/2592] MFC ir206152, r206153, r206154: - Stop adding trailing '\n'. The servent_unpack() doesn't expect lines terminated with '\n'. - Treat '+' as special only when in compat mode, and simplify the logic bit. - Reduce duplicate code. --- lib/libc/net/getservent.c | 106 +++++++++++++------------------------- 1 file changed, 35 insertions(+), 71 deletions(-) diff --git a/lib/libc/net/getservent.c b/lib/libc/net/getservent.c index ebb7a7d3dac..3dcad3fa407 100644 --- a/lib/libc/net/getservent.c +++ b/lib/libc/net/getservent.c @@ -207,6 +207,32 @@ servent_unpack(char *p, struct servent *serv, char **aliases, return 0; } +static int +parse_result(struct servent *serv, char *buffer, size_t bufsize, + char *resultbuf, size_t resultbuflen, int *errnop) +{ + char **aliases; + int aliases_size; + + if (bufsize <= resultbuflen + _ALIGNBYTES + sizeof(char *)) { + *errnop = ERANGE; + return (NS_RETURN); + } + aliases = (char **)_ALIGN(&buffer[resultbuflen + 1]); + aliases_size = (buffer + bufsize - (char *)aliases) / sizeof(char *); + if (aliases_size < 1) { + *errnop = ERANGE; + return (NS_RETURN); + } + + memcpy(buffer, resultbuf, resultbuflen); + buffer[resultbuflen] = '\0'; + + if (servent_unpack(buffer, serv, aliases, aliases_size, errnop) != 0) + return ((*errnop == 0) ? NS_NOTFOUND : NS_RETURN); + return (NS_SUCCESS); +} + /* files backend implementation */ static void files_endstate(void *p) @@ -258,8 +284,6 @@ files_servent(void *retval, void *mdata, va_list ap) size_t bufsize; int *errnop; - char **aliases; - int aliases_size; size_t linesize; char *line; char **cp; @@ -315,28 +339,8 @@ files_servent(void *retval, void *mdata, va_list ap) break; } - if (*line=='+') { - if (serv_mdata->compat_mode != 0) - st->compat_mode_active = 1; - } else { - if (bufsize <= linesize + _ALIGNBYTES + - sizeof(char *)) { - *errnop = ERANGE; - rv = NS_RETURN; - break; - } - aliases = (char **)_ALIGN(&buffer[linesize+1]); - aliases_size = (buffer + bufsize - - (char *)aliases) / sizeof(char *); - if (aliases_size < 1) { - *errnop = ERANGE; - rv = NS_RETURN; - break; - } - - memcpy(buffer, line, linesize); - buffer[linesize] = '\0'; - } + if (*line=='+' && serv_mdata->compat_mode != 0) + st->compat_mode_active = 1; } if (st->compat_mode_active != 0) { @@ -367,18 +371,12 @@ files_servent(void *retval, void *mdata, va_list ap) continue; } - rv = servent_unpack(buffer, serv, aliases, aliases_size, + rv = parse_result(serv, buffer, bufsize, line, linesize, errnop); - if (rv !=0 ) { - if (*errnop == 0) { - rv = NS_NOTFOUND; - continue; - } - else { - rv = NS_RETURN; - break; - } - } + if (rv == NS_NOTFOUND) + continue; + if (rv == NS_RETURN) + break; rv = NS_NOTFOUND; switch (serv_mdata->how) { @@ -486,9 +484,6 @@ nis_servent(void *retval, void *mdata, va_list ap) size_t bufsize; int *errnop; - char **aliases; - int aliases_size; - name = NULL; proto = NULL; how = (enum nss_lookup_type)mdata; @@ -594,39 +589,8 @@ nis_servent(void *retval, void *mdata, va_list ap) break; }; - /* we need a room for additional \n symbol */ - if (bufsize <= - resultbuflen + 1 + _ALIGNBYTES + sizeof(char *)) { - *errnop = ERANGE; - rv = NS_RETURN; - break; - } - - aliases = (char **)_ALIGN(&buffer[resultbuflen + 2]); - aliases_size = - (buffer + bufsize - (char *)aliases) / sizeof(char *); - if (aliases_size < 1) { - *errnop = ERANGE; - rv = NS_RETURN; - break; - } - - /* - * servent_unpack expects lines terminated with \n -- - * make it happy - */ - memcpy(buffer, resultbuf, resultbuflen); - buffer[resultbuflen] = '\n'; - buffer[resultbuflen + 1] = '\0'; - - if (servent_unpack(buffer, serv, aliases, aliases_size, - errnop) != 0) { - if (*errnop == 0) - rv = NS_NOTFOUND; - else - rv = NS_RETURN; - } else - rv = NS_SUCCESS; + rv = parse_result(serv, buffer, bufsize, resultbuf, + resultbuflen, errnop); free(resultbuf); } while (!(rv & NS_TERMINATE) && how == nss_lt_all); From 4deeadcb9bd9c7b5c2f1c08b9c75c80636d0fa38 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sun, 18 Apr 2010 04:07:32 +0000 Subject: [PATCH 2013/2592] MFC r206155, r206267: Add capability to use a db version of services. It is enabled by specifying `db' as source of services in /etc/nsswitch.conf. --- include/netdb.h | 1 + include/nsswitch.h | 1 + lib/libc/net/getservent.c | 200 +++++++++++++++++++++++++++++++++ lib/libc/net/nsdispatch.3 | 3 +- share/man/man5/nsswitch.conf.5 | 4 +- share/man/man5/services.5 | 16 ++- 6 files changed, 222 insertions(+), 3 deletions(-) diff --git a/include/netdb.h b/include/netdb.h index 1c9ef27bacc..c15b2845b4f 100644 --- a/include/netdb.h +++ b/include/netdb.h @@ -86,6 +86,7 @@ typedef __uint32_t uint32_t; #define _PATH_NETWORKS "/etc/networks" #define _PATH_PROTOCOLS "/etc/protocols" #define _PATH_SERVICES "/etc/services" +#define _PATH_SERVICES_DB "/var/db/services.db" #define h_errno (*__h_errno()) diff --git a/include/nsswitch.h b/include/nsswitch.h index 9069ac11b49..8aea5ad12d7 100644 --- a/include/nsswitch.h +++ b/include/nsswitch.h @@ -65,6 +65,7 @@ * currently implemented sources */ #define NSSRC_FILES "files" /* local files */ +#define NSSRC_DB "db" /* database */ #define NSSRC_DNS "dns" /* DNS; IN for hosts, HS for others */ #define NSSRC_NIS "nis" /* YP/NIS */ #define NSSRC_COMPAT "compat" /* passwd,group in YP compat mode */ diff --git a/lib/libc/net/getservent.c b/lib/libc/net/getservent.c index 3dcad3fa407..3228bdc2eea 100644 --- a/lib/libc/net/getservent.c +++ b/lib/libc/net/getservent.c @@ -37,7 +37,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include #include @@ -94,6 +96,19 @@ NSS_TLS_HANDLING(files); static int files_servent(void *, void *, va_list); static int files_setservent(void *, void *, va_list); +/* db backend declarations */ +struct db_state +{ + DB *db; + int stayopen; + int keynum; +}; +static void db_endstate(void *); +NSS_TLS_HANDLING(db); + +static int db_servent(void *, void *, va_list); +static int db_setservent(void *, void *, va_list); + #ifdef YP /* nis backend declarations */ static int nis_servent(void *, void *, va_list); @@ -263,6 +278,8 @@ files_servent(void *retval, void *mdata, va_list ap) { NULL, 0 } }; ns_dtab compat_dtab[] = { + { NSSRC_DB, db_servent, + (void *)((struct servent_mdata *)mdata)->how }, #ifdef YP { NSSRC_NIS, nis_servent, (void *)((struct servent_mdata *)mdata)->how }, @@ -452,6 +469,183 @@ files_setservent(void *retval, void *mdata, va_list ap) return (NS_UNAVAIL); } +/* db backend implementation */ +static void +db_endstate(void *p) +{ + DB *db; + + if (p == NULL) + return; + + db = ((struct db_state *)p)->db; + if (db != NULL) + db->close(db); + + free(p); +} + +static int +db_servent(void *retval, void *mdata, va_list ap) +{ + char buf[BUFSIZ]; + DBT key, data, *result; + DB *db; + + struct db_state *st; + int rv; + int stayopen; + + enum nss_lookup_type how; + char *name; + char *proto; + int port; + + struct servent *serv; + char *buffer; + size_t bufsize; + int *errnop; + + name = NULL; + proto = NULL; + how = (enum nss_lookup_type)mdata; + switch (how) { + case nss_lt_name: + name = va_arg(ap, char *); + proto = va_arg(ap, char *); + break; + case nss_lt_id: + port = va_arg(ap, int); + proto = va_arg(ap, char *); + break; + case nss_lt_all: + break; + default: + return NS_NOTFOUND; + }; + + serv = va_arg(ap, struct servent *); + buffer = va_arg(ap, char *); + bufsize = va_arg(ap, size_t); + errnop = va_arg(ap,int *); + + *errnop = db_getstate(&st); + if (*errnop != 0) + return (NS_UNAVAIL); + + if (how == nss_lt_all && st->keynum < 0) + return (NS_NOTFOUND); + + if (st->db == NULL) { + st->db = dbopen(_PATH_SERVICES_DB, O_RDONLY, 0, DB_HASH, NULL); + if (st->db == NULL) { + *errnop = errno; + return (NS_UNAVAIL); + } + } + + stayopen = (how == nss_lt_all) ? 1 : st->stayopen; + db = st->db; + + do { + switch (how) { + case nss_lt_name: + key.data = buf; + if (proto == NULL) + key.size = snprintf(buf, sizeof(buf), + "\376%s", name); + else + key.size = snprintf(buf, sizeof(buf), + "\376%s/%s", name, proto); + key.size++; + if (db->get(db, &key, &data, 0) != 0 || + db->get(db, &data, &key, 0) != 0) { + rv = NS_NOTFOUND; + goto db_fin; + } + result = &key; + break; + case nss_lt_id: + key.data = buf; + port = htons(port); + if (proto == NULL) + key.size = snprintf(buf, sizeof(buf), + "\377%d", port); + else + key.size = snprintf(buf, sizeof(buf), + "\377%d/%s", port, proto); + key.size++; + if (db->get(db, &key, &data, 0) != 0 || + db->get(db, &data, &key, 0) != 0) { + rv = NS_NOTFOUND; + goto db_fin; + } + result = &key; + break; + case nss_lt_all: + key.data = buf; + key.size = snprintf(buf, sizeof(buf), "%d", + st->keynum++); + key.size++; + if (db->get(db, &key, &data, 0) != 0) { + st->keynum = -1; + rv = NS_NOTFOUND; + goto db_fin; + } + result = &data; + break; + } + + rv = parse_result(serv, buffer, bufsize, result->data, + result->size - 1, errnop); + + } while (!(rv & NS_TERMINATE) && how == nss_lt_all); + +db_fin: + if (!stayopen && st->db != NULL) { + db->close(db); + st->db = NULL; + } + + if (rv == NS_SUCCESS && retval != NULL) + *(struct servent **)retval = serv; + + return (rv); +} + +static int +db_setservent(void *retval, void *mdata, va_list ap) +{ + DB *db; + struct db_state *st; + int rv; + int f; + + rv = db_getstate(&st); + if (rv != 0) + return (NS_UNAVAIL); + + switch ((enum constants)mdata) { + case SETSERVENT: + f = va_arg(ap, int); + st->stayopen |= f; + st->keynum = 0; + break; + case ENDSERVENT: + db = st->db; + if (db != NULL) { + db->close(db); + st->db = NULL; + } + st->stayopen = 0; + break; + default: + break; + }; + + return (NS_UNAVAIL); +} + /* nis backend implementation */ #ifdef YP static void @@ -638,6 +832,7 @@ compat_setservent(void *retval, void *mdata, va_list ap) { NULL, 0 } }; ns_dtab compat_dtab[] = { + { NSSRC_DB, db_setservent, mdata }, #ifdef YP { NSSRC_NIS, nis_setservent, mdata }, #endif @@ -924,6 +1119,7 @@ getservbyname_r(const char *name, const char *proto, struct servent *serv, #endif /* NS_CACHING */ static const ns_dtab dtab[] = { { NSSRC_FILES, files_servent, (void *)&mdata }, + { NSSRC_DB, db_servent, (void *)nss_lt_name }, #ifdef YP { NSSRC_NIS, nis_servent, (void *)nss_lt_name }, #endif @@ -960,6 +1156,7 @@ getservbyport_r(int port, const char *proto, struct servent *serv, #endif static const ns_dtab dtab[] = { { NSSRC_FILES, files_servent, (void *)&mdata }, + { NSSRC_DB, db_servent, (void *)nss_lt_id }, #ifdef YP { NSSRC_NIS, nis_servent, (void *)nss_lt_id }, #endif @@ -995,6 +1192,7 @@ getservent_r(struct servent *serv, char *buffer, size_t bufsize, #endif static const ns_dtab dtab[] = { { NSSRC_FILES, files_servent, (void *)&mdata }, + { NSSRC_DB, db_servent, (void *)nss_lt_all }, #ifdef YP { NSSRC_NIS, nis_servent, (void *)nss_lt_all }, #endif @@ -1027,6 +1225,7 @@ setservent(int stayopen) #endif static const ns_dtab dtab[] = { { NSSRC_FILES, files_setservent, (void *)SETSERVENT }, + { NSSRC_DB, db_setservent, (void *)SETSERVENT }, #ifdef YP { NSSRC_NIS, nis_setservent, (void *)SETSERVENT }, #endif @@ -1051,6 +1250,7 @@ endservent() #endif static const ns_dtab dtab[] = { { NSSRC_FILES, files_setservent, (void *)ENDSERVENT }, + { NSSRC_DB, db_setservent, (void *)ENDSERVENT }, #ifdef YP { NSSRC_NIS, nis_setservent, (void *)ENDSERVENT }, #endif diff --git a/lib/libc/net/nsdispatch.3 b/lib/libc/net/nsdispatch.3 index cf15002795b..8ae7540d9be 100644 --- a/lib/libc/net/nsdispatch.3 +++ b/lib/libc/net/nsdispatch.3 @@ -32,7 +32,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 22, 2007 +.Dd April 4, 2010 .Dt NSDISPATCH 3 .Os .Sh NAME @@ -176,6 +176,7 @@ While there is support for arbitrary sources, the following .Bl -column NSSRC_COMPAT compat -offset indent .It Sy "#define value" .It Dv NSSRC_FILES Ta """files"" +.It Dv NSSRC_DB Ta """db"" .It Dv NSSRC_DNS Ta """dns"" .It Dv NSSRC_NIS Ta """nis"" .It Dv NSSRC_COMPAT Ta """compat"" diff --git a/share/man/man5/nsswitch.conf.5 b/share/man/man5/nsswitch.conf.5 index f6940bd31b7..c28720b2f16 100644 --- a/share/man/man5/nsswitch.conf.5 +++ b/share/man/man5/nsswitch.conf.5 @@ -33,7 +33,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 23, 2008 +.Dd April 4, 2010 .Dt NSSWITCH.CONF 5 .Os .Sh NAME @@ -72,6 +72,8 @@ Local files, such as .Pa /etc/hosts , and .Pa /etc/passwd . +.It db +Local database. .It dns Internet Domain Name System. .Dq hosts diff --git a/share/man/man5/services.5 b/share/man/man5/services.5 index 40320f9ffe8..55e0c9d73d2 100644 --- a/share/man/man5/services.5 +++ b/share/man/man5/services.5 @@ -32,7 +32,7 @@ .\" @(#)services.5 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd June 5, 1993 +.Dd April 4, 2010 .Dt SERVICES 5 .Os .Sh NAME @@ -65,6 +65,18 @@ not interpreted by the routines which search the file. Service names may contain any printable character other than a field delimiter, newline, or comment character. +.Pp +If +.Dq db +is specified as source in the +.Xr nsswitch.conf 5 , +.Pa /var/db/services.db +is searched. +The database in +.Pa /var/db/services.db +needs to be updated with +.Xr services_mkdb 8 +after changes to the services file have been applied. .Sh NIS INTERACTION Access to the NIS .Pa services.byname @@ -84,6 +96,8 @@ file resides in .El .Sh SEE ALSO .Xr getservent 3 +.Xr nsswitch.conf 5 +.Xr services_mkdb 8 .Sh HISTORY The .Nm From 81a33b9c2c161a982485d546dd48c7c6acde468a Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sun, 18 Apr 2010 04:15:21 +0000 Subject: [PATCH 2014/2592] MFC r206156, r206159, r206163: services_mkdb; generate db file from services(5) to increase speed of getserv*() --- usr.sbin/Makefile | 1 + usr.sbin/services_mkdb/Makefile | 10 + usr.sbin/services_mkdb/services_mkdb.8 | 97 ++++++ usr.sbin/services_mkdb/services_mkdb.c | 429 +++++++++++++++++++++++++ usr.sbin/services_mkdb/uniq.c | 159 +++++++++ 5 files changed, 696 insertions(+) create mode 100644 usr.sbin/services_mkdb/Makefile create mode 100644 usr.sbin/services_mkdb/services_mkdb.8 create mode 100644 usr.sbin/services_mkdb/services_mkdb.c create mode 100644 usr.sbin/services_mkdb/uniq.c diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 5df3ca20229..4cb5709a8b9 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -168,6 +168,7 @@ SUBDIR= ${_ac} \ ${_sade} \ ${_sendmail} \ service \ + services_mkdb \ setfib \ setfmac \ setpmac \ diff --git a/usr.sbin/services_mkdb/Makefile b/usr.sbin/services_mkdb/Makefile new file mode 100644 index 00000000000..659cdb8163e --- /dev/null +++ b/usr.sbin/services_mkdb/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +PROG= services_mkdb +MAN= services_mkdb.8 +SRCS= services_mkdb.c uniq.c + +DPADD+= ${LIBUTIL} +LDADD+= -lutil + +.include diff --git a/usr.sbin/services_mkdb/services_mkdb.8 b/usr.sbin/services_mkdb/services_mkdb.8 new file mode 100644 index 00000000000..6468fd27408 --- /dev/null +++ b/usr.sbin/services_mkdb/services_mkdb.8 @@ -0,0 +1,97 @@ +.\" $NetBSD: services_mkdb.8,v 1.9 2009/05/13 22:36:39 wiz Exp $ +.\" +.\" Copyright (c) 1999 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Luke Mewburn. +.\" +.\" 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 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. +.\" +.\" $FreeBSD$ +.\" +.Dd April 4, 2010 +.Dt SERVICES_MKDB 8 +.Os +.Sh NAME +.Nm services_mkdb +.Nd generate the services databases +.Sh SYNOPSIS +.Nm +.Op Fl q +.Op Fl o Ar database +.Op file +.Nm +.Fl u +.Op file +.Sh DESCRIPTION +.Nm +creates a +.Xr db 3 +database for the specified file. +If no file is specified, then +.Pa /etc/services +is used. +The database is installed into +.Pa /var/db/services.db . +The file must be in the correct format (see +.Xr services 5 ) . +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl o Ar database +Put the output databases in the named file. +.It Fl q +Don't warn about duplicate services. +.It Fl u +Print the services file to stdout, omitting duplicate entries and comments. +.El +.Pp +The databases are used by the C library services routines (see +.Xr getservent 3 ) . +.Pp +.Nm +exits zero on success, non-zero on failure. +.Sh FILES +.Bl -tag -width 24n -compact +.It Pa /var/db/services.db +The current services database. +.It Pa /var/db/services.db.tmp +A temporary file. +.It Pa /etc/services +The current services file. +.El +.Sh SEE ALSO +.Xr db 3 , +.Xr getservent 3 , +.Xr services 5 +.Sh BUGS +Because +.Nm +guarantees not to install a partial destination file it must +build a temporary file in the same file system and if successful use +.Xr rename 2 +to install over the destination file. +.Pp +If +.Nm +fails it will leave the previous version of the destination file intact. diff --git a/usr.sbin/services_mkdb/services_mkdb.c b/usr.sbin/services_mkdb/services_mkdb.c new file mode 100644 index 00000000000..f4cf62ac414 --- /dev/null +++ b/usr.sbin/services_mkdb/services_mkdb.c @@ -0,0 +1,429 @@ +/* $NetBSD: services_mkdb.c,v 1.14 2008/04/28 20:24:17 martin Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Christos Zoulas. + * + * 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 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char tname[MAXPATHLEN]; + +#define PMASK 0xffff +#define PROTOMAX 5 + +extern void uniq(const char *); + +static void add(DB *, StringList *, size_t, const char *, size_t *, int); +static StringList ***parseservices(const char *, StringList *); +static void cleanup(void); +static void store(DB *, DBT *, DBT *, int); +static void killproto(DBT *); +static char *getstring(const char *, size_t, char **, const char *); +static size_t getprotoindex(StringList *, const char *); +static const char *getprotostr(StringList *, size_t); +static const char *mkaliases(StringList *, char *, size_t); +static void usage(void); + +const HASHINFO hinfo = { + .bsize = 256, + .ffactor = 4, + .nelem = 32768, + .cachesize = 1024, + .hash = NULL, + .lorder = 0 +}; + + +int +main(int argc, char *argv[]) +{ + DB *db; + int ch; + const char *fname = _PATH_SERVICES; + const char *dbname = _PATH_SERVICES_DB; + int warndup = 1; + int unique = 0; + int otherflag = 0; + size_t cnt = 0; + StringList *sl, ***svc; + size_t port, proto; + + setprogname(argv[0]); + + while ((ch = getopt(argc, argv, "qo:u")) != -1) + switch (ch) { + case 'q': + otherflag = 1; + warndup = 0; + break; + case 'o': + otherflag = 1; + dbname = optarg; + break; + case 'u': + unique++; + break; + case '?': + default: + usage(); + } + + argc -= optind; + argv += optind; + + if (argc > 1 || (unique && otherflag)) + usage(); + if (argc == 1) + fname = argv[0]; + + if (unique) + uniq(fname); + + svc = parseservices(fname, sl = sl_init()); + + if (atexit(cleanup)) + err(1, "Cannot install exit handler"); + + (void)snprintf(tname, sizeof(tname), "%s.tmp", dbname); + db = dbopen(tname, O_RDWR | O_CREAT | O_EXCL, + (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), DB_HASH, &hinfo); + if (!db) + err(1, "Error opening temporary database `%s'", tname); + + + for (port = 0; port < PMASK + 1; port++) { + if (svc[port] == NULL) + continue; + + for (proto = 0; proto < PROTOMAX; proto++) { + StringList *s; + if ((s = svc[port][proto]) == NULL) + continue; + add(db, s, port, getprotostr(sl, proto), &cnt, warndup); + } + + free(svc[port]); + } + + free(svc); + sl_free(sl, 1); + + if ((db->close)(db)) + err(1, "Error closing temporary database `%s'", tname); + + if (rename(tname, dbname) == -1) + err(1, "Cannot rename `%s' to `%s'", tname, dbname); + + return 0; +} + +static void +add(DB *db, StringList *sl, size_t port, const char *proto, size_t *cnt, + int warndup) +{ + size_t i; + char keyb[BUFSIZ], datab[BUFSIZ], abuf[BUFSIZ]; + DBT data, key; + key.data = keyb; + data.data = datab; + +#ifdef DEBUG + (void)printf("add %s %zu %s [ ", sl->sl_str[0], port, proto); + for (i = 1; i < sl->sl_cur; i++) + (void)printf("%s ", sl->sl_str[i]); + (void)printf("]\n"); +#endif + + /* key `indirect key', data `full line' */ + data.size = snprintf(datab, sizeof(datab), "%zu", (*cnt)++) + 1; + key.size = snprintf(keyb, sizeof(keyb), "%s %zu/%s %s", + sl->sl_str[0], port, proto, mkaliases(sl, abuf, sizeof(abuf))) + 1; + store(db, &data, &key, warndup); + + /* key `\377port/proto', data = `indirect key' */ + key.size = snprintf(keyb, sizeof(keyb), "\377%zu/%s", + port, proto) + 1; + store(db, &key, &data, warndup); + + /* key `\377port', data = `indirect key' */ + killproto(&key); + store(db, &key, &data, warndup); + + /* add references for service and all aliases */ + for (i = 0; i < sl->sl_cur; i++) { + /* key `\376service/proto', data = `indirect key' */ + key.size = snprintf(keyb, sizeof(keyb), "\376%s/%s", + sl->sl_str[i], proto) + 1; + store(db, &key, &data, warndup); + + /* key `\376service', data = `indirect key' */ + killproto(&key); + store(db, &key, &data, warndup); + } + sl_free(sl, 1); +} + +static StringList *** +parseservices(const char *fname, StringList *sl) +{ + size_t len, line, pindex; + FILE *fp; + StringList ***svc, *s; + char *p, *ep; + + if ((fp = fopen(fname, "r")) == NULL) + err(1, "Cannot open `%s'", fname); + + line = 0; + if ((svc = calloc(PMASK + 1, sizeof(StringList **))) == NULL) + err(1, "Cannot allocate %zu bytes", (size_t)(PMASK + 1)); + + /* XXX: change NULL to "\0\0#" when fparseln fixed */ + for (; (p = fparseln(fp, &len, &line, NULL, 0)) != NULL; free(p)) { + char *name, *port, *proto, *aliases, *cp, *alias; + unsigned long pnum; + + if (len == 0) + continue; + + for (cp = p; *cp && isspace((unsigned char)*cp); cp++) + continue; + + if (*cp == '\0' || *cp == '#') + continue; + + if ((name = getstring(fname, line, &cp, "name")) == NULL) + continue; + + if ((port = getstring(fname, line, &cp, "port")) == NULL) + continue; + + if (cp) { + for (aliases = cp; *cp && *cp != '#'; cp++) + continue; + + if (*cp) + *cp = '\0'; + } else + aliases = NULL; + + proto = strchr(port, '/'); + if (proto == NULL || proto[1] == '\0') { + warnx("%s, %zu: no protocol found", fname, line); + continue; + } + *proto++ = '\0'; + + errno = 0; + pnum = strtoul(port, &ep, 0); + if (*port == '\0' || *ep != '\0') { + warnx("%s, %zu: invalid port `%s'", fname, line, port); + continue; + } + if ((errno == ERANGE && pnum == ULONG_MAX) || pnum > PMASK) { + warnx("%s, %zu: port too big `%s'", fname, line, port); + continue; + } + + if (svc[pnum] == NULL) { + svc[pnum] = calloc(PROTOMAX, sizeof(StringList *)); + if (svc[pnum] == NULL) + err(1, "Cannot allocate %zu bytes", + (size_t)PROTOMAX); + } + + pindex = getprotoindex(sl, proto); + if (svc[pnum][pindex] == NULL) + s = svc[pnum][pindex] = sl_init(); + else + s = svc[pnum][pindex]; + + /* build list of aliases */ + if (sl_find(s, name) == NULL) { + char *p2; + + if ((p2 = strdup(name)) == NULL) + err(1, "Cannot copy string"); + (void)sl_add(s, p2); + } + + if (aliases) { + while ((alias = strsep(&aliases, " \t")) != NULL) { + if (alias[0] == '\0') + continue; + if (sl_find(s, alias) == NULL) { + char *p2; + + if ((p2 = strdup(alias)) == NULL) + err(1, "Cannot copy string"); + (void)sl_add(s, p2); + } + } + } + } + (void)fclose(fp); + return svc; +} + +/* + * cleanup(): Remove temporary files upon exit + */ +static void +cleanup(void) +{ + if (tname[0]) + (void)unlink(tname); +} + +static char * +getstring(const char *fname, size_t line, char **cp, const char *tag) +{ + char *str; + + while ((str = strsep(cp, " \t")) != NULL && *str == '\0') + continue; + + if (str == NULL) + warnx("%s, %zu: no %s found", fname, line, tag); + + return str; +} + +static void +killproto(DBT *key) +{ + char *p, *d = key->data; + + if ((p = strchr(d, '/')) == NULL) + abort(); + *p++ = '\0'; + key->size = p - d; +} + +static void +store(DB *db, DBT *key, DBT *data, int warndup) +{ +#ifdef DEBUG + int k = key->size - 1; + int d = data->size - 1; + (void)printf("store [%*.*s] [%*.*s]\n", + k, k, (char *)key->data + 1, + d, d, (char *)data->data + 1); +#endif + switch ((db->put)(db, key, data, R_NOOVERWRITE)) { + case 0: + break; + case 1: + if (warndup) + warnx("duplicate service `%s'", + &((char *)key->data)[1]); + break; + case -1: + err(1, "put"); + break; + default: + abort(); + break; + } +} + +static size_t +getprotoindex(StringList *sl, const char *str) +{ + size_t i; + char *p; + + for (i= 0; i < sl->sl_cur; i++) + if (strcmp(sl->sl_str[i], str) == 0) + return i; + + if (i == PROTOMAX) + errx(1, "Ran out of protocols adding `%s';" + " recompile with larger PROTOMAX", str); + if ((p = strdup(str)) == NULL) + err(1, "Cannot copy string"); + (void)sl_add(sl, p); + return i; +} + +static const char * +getprotostr(StringList *sl, size_t i) +{ + assert(i < sl->sl_cur); + return sl->sl_str[i]; +} + +static const char * +mkaliases(StringList *sl, char *buf, size_t len) +{ + size_t nc, i, pos; + + buf[0] = 0; + for (i = 1, pos = 0; i < sl->sl_cur; i++) { + nc = strlcpy(buf + pos, sl->sl_str[i], len); + if (nc >= len) + goto out; + pos += nc; + len -= nc; + nc = strlcpy(buf + pos, " ", len); + if (nc >= len) + goto out; + pos += nc; + len -= nc; + } + return buf; +out: + warn("aliases for `%s' truncated", sl->sl_str[0]); + return buf; +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage:\t%s [-q] [-o ] []\n" + "\t%s -u []\n", getprogname(), getprogname()); + exit(1); +} diff --git a/usr.sbin/services_mkdb/uniq.c b/usr.sbin/services_mkdb/uniq.c new file mode 100644 index 00000000000..0674b4bbc40 --- /dev/null +++ b/usr.sbin/services_mkdb/uniq.c @@ -0,0 +1,159 @@ +/* $NetBSD: uniq.c,v 1.4 2008/04/28 20:24:17 martin Exp $ */ + +/*- + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 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. + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +extern const HASHINFO hinfo; + +void uniq(const char *); +static int comp(const char *, char **, size_t *); + +/* + * Preserve only unique content lines in a file. Input lines that have + * content [alphanumeric characters before a comment] are white-space + * normalized and have their comments removed. Then they are placed + * in a hash table, and only the first instance of them is printed. + * Comment lines without any alphanumeric content are always printed + * since they are there to make the file "pretty". Comment lines with + * alphanumeric content are also placed into the hash table and only + * printed once. + */ +void +uniq(const char *fname) +{ + DB *db; + DBT key; + static const DBT data = { NULL, 0 }; + FILE *fp; + char *line; + size_t len; + + if ((db = dbopen(NULL, O_RDWR, 0, DB_HASH, &hinfo)) == NULL) + err(1, "Cannot create in memory database"); + + if ((fp = fopen(fname, "r")) == NULL) + err(1, "Cannot open `%s'", fname); + while ((line = fgetln(fp, &len)) != NULL) { + size_t complen = len; + char *compline; + if (!comp(line, &compline, &complen)) { + (void)fprintf(stdout, "%*.*s", (int)len, (int)len, + line); + continue; + } + key.data = compline; + key.size = complen; + switch ((db->put)(db, &key, &data, R_NOOVERWRITE)) { + case 0: + (void)fprintf(stdout, "%*.*s", (int)len, (int)len, + line); + break; + case 1: + break; + case -1: + err(1, "put"); + default: + abort(); + break; + } + } + (void)fflush(stdout); + exit(0); +} + +/* + * normalize whitespace in the original line and place a new string + * with whitespace converted to a single space in compline. If the line + * contains just comments, we preserve them. If it contains data and + * comments, we kill the comments. Return 1 if the line had actual + * contents, or 0 if it was just a comment without alphanumeric characters. + */ +static int +comp(const char *origline, char **compline, size_t *len) +{ + const unsigned char *p; + unsigned char *q; + char *cline; + size_t l = *len, complen; + int hasalnum, iscomment; + + /* Eat leading space */ + for (p = (const unsigned char *)origline; l && *p && isspace(*p); + p++, l--) + continue; + if ((cline = malloc(l + 1)) == NULL) + err(1, "Cannot allocate %zu bytes", l + 1); + (void)memcpy(cline, p, l); + cline[l] = '\0'; + if (*cline == '\0') + return 0; + + complen = 0; + hasalnum = 0; + iscomment = 0; + + for (q = (unsigned char *)cline; l && *p; p++, l--) { + if (isspace(*p)) { + if (complen && isspace(q[-1])) + continue; + *q++ = ' '; + complen++; + } else { + if (!iscomment && *p == '#') { + if (hasalnum) + break; + iscomment = 1; + } else + hasalnum |= isalnum(*p); + *q++ = *p; + complen++; + } + } + + /* Eat trailing space */ + while (complen && isspace(q[-1])) { + --q; + --complen; + } + *q = '\0'; + *compline = cline; + *len = complen; + return hasalnum; +} From c9975476bf82778a67110cbf99b1b6b031201b98 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 18 Apr 2010 04:35:16 +0000 Subject: [PATCH 2015/2592] MFC r206671: Fix typo. --- sys/kern/vfs_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 78548033ea2..533ec97875d 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -610,7 +610,7 @@ cache_enter(dvp, vp, cnp) CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr); VNASSERT(vp == NULL || (vp->v_iflag & VI_DOOMED) == 0, vp, - ("cahe_enter: Adding a doomed vnode")); + ("cache_enter: Adding a doomed vnode")); if (!doingcache) return; From 5675cbea9733c74fab6d98cc6d76748d3d69950c Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 10:29:26 +0000 Subject: [PATCH 2016/2592] MFC r205846: Fix references. --- share/man/man9/ieee80211.9 | 19 +++++++++++++------ share/man/man9/ieee80211_crypto.9 | 3 ++- share/man/man9/ieee80211_node.9 | 4 ++-- share/man/man9/ieee80211_output.9 | 4 ++-- share/man/man9/ieee80211_scan.9 | 4 ++-- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/share/man/man9/ieee80211.9 b/share/man/man9/ieee80211.9 index ba0137dec5d..ae92d5e5965 100644 --- a/share/man/man9/ieee80211.9 +++ b/share/man/man9/ieee80211.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 4, 2009 +.Dd March 29, 2010 .Dt NET80211 9 .Os .Sh NAME @@ -551,11 +551,18 @@ Device supports Reduced Inter Frame Spacing (RIFS). .Sh SEE ALSO .Xr ioctl 2 , .Xr ndis 4 , +.Xr ieee80211_amrr 9 , +.Xr ieee80211_beacon 9 , +.Xr ieee80211_bmiss 9 , +.Xr ieee80211_crypto 9 , +.Xr ieee80211_ddb 9 , .Xr ieee80211_input 9 , -.Xr ieee80211_input_all 9 , -.Xr ieee80211_scan_next 9 , -.Xr ieee80211_recv_action 9 , -.Xr ieee80211_send_action 9 , -.Xr ieee80211_radiotap_attach 9 , +.Xr ieee80211_node 9 , +.Xr ieee80211_output 9 , +.Xr ieee80211_proto 9 , +.Xr ieee80211_radiotap 9 , +.Xr ieee80211_regdomain 9 , +.Xr ieee80211_scan 9 , +.Xr ieee80211_vap 9 , .Xr ifnet 9 , .Xr malloc 9 diff --git a/share/man/man9/ieee80211_crypto.9 b/share/man/man9/ieee80211_crypto.9 index 92fe6bba995..e21bc26ea03 100644 --- a/share/man/man9/ieee80211_crypto.9 +++ b/share/man/man9/ieee80211_crypto.9 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" $Id: ieee80211_crypto.9,v 1.3 2004/03/04 10:42:56 bruce Exp $ .\" -.Dd August 4, 2009 +.Dd March 29, 2010 .Dt IEEE80211_CRYPTO 9 .Os .Sh NAME @@ -253,6 +253,7 @@ and These calls also synchronize hardware key state update when receive traffic is active. .Sh SEE ALSO +.Xr ieee80211 9 , .Xr ioctl 2 , .Xr wlan_ccmp 4 , .Xr wlan_tkip 4 , diff --git a/share/man/man9/ieee80211_node.9 b/share/man/man9/ieee80211_node.9 index 5d9d4adbe55..be0b506a02f 100644 --- a/share/man/man9/ieee80211_node.9 +++ b/share/man/man9/ieee80211_node.9 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 4, 2009 +.Dd March 29, 2010 .Dt IEEE80211_NODE 9 .Os .Sh NAME @@ -246,6 +246,6 @@ If the specified index is .Dv IEEE80211_KEYIX_NONE then a normal lookup is done without a table update. .Sh SEE ALSO -.Xr ddb 9 +.Xr ddb 9 , .Xr ieee80211 9 , .Xr ieee80211_proto 9 diff --git a/share/man/man9/ieee80211_output.9 b/share/man/man9/ieee80211_output.9 index 61e480034d3..82393bdaa2d 100644 --- a/share/man/man9/ieee80211_output.9 +++ b/share/man/man9/ieee80211_output.9 @@ -27,7 +27,7 @@ .\" $FreeBSD$ .\" $Id: ieee80211_output.9,v 1.5 2004/03/04 12:31:18 bruce Exp $ .\" -.Dd August 4, 2009 +.Dd March 29, 2010 .Dt IEEE80211_OUTPUT 9 .Os .Sh NAME @@ -189,6 +189,6 @@ a device may not report if an ACK frame is received and/or a device may queue transmit requests in its hardware and only report status on whether the frame was successfully queued. .Sh SEE ALSO -.Xr bpf 4 +.Xr bpf 4 , .Xr ieee80211 9 , .Xr ifnet 9 diff --git a/share/man/man9/ieee80211_scan.9 b/share/man/man9/ieee80211_scan.9 index 018f70f8d74..b2b77cf8626 100644 --- a/share/man/man9/ieee80211_scan.9 +++ b/share/man/man9/ieee80211_scan.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 20, 2010 +.Dd March 29, 2010 .Dt IEEE80211_SCAN 9 .Os .Sh NAME @@ -346,5 +346,5 @@ applications through the request. .Sh SEE ALSO .Xr ioctl 2 , -.Xr ieee80211 9 . +.Xr ieee80211 9 , .Xr ieee80211_proto 9 From cbd7ba79f01594596c5d036dc5f8ecf9c50474e6 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 10:36:49 +0000 Subject: [PATCH 2017/2592] MFC r201115: Line discipline support is gone; update tty(4) manual page to reflect this. Reviewed by: ed --- share/man/man4/tty.4 | 72 +++++--------------------------------------- 1 file changed, 8 insertions(+), 64 deletions(-) diff --git a/share/man/man4/tty.4 b/share/man/man4/tty.4 index ba0379eb09a..af7ecbeb0ff 100644 --- a/share/man/man4/tty.4 +++ b/share/man/man4/tty.4 @@ -88,47 +88,6 @@ The remainder of this man page is concerned with describing details of using and controlling terminal devices at a low level, such as that possibly required by a program wishing to provide features similar to those provided by the system. -.Ss Line disciplines -A terminal file is used like any other file in the system in that -it can be opened, read, and written to using standard system -calls. -For each existing terminal file, there is a software processing module -called a -.Em "line discipline" -is associated with it. -The -.Em "line discipline" -essentially glues the low level device driver code with the high -level generic interface routines (such as -.Xr read 2 -and -.Xr write 2 ) , -and is responsible for implementing the semantics associated -with the device. -When a terminal file is first opened by a program, the default -.Em "line discipline" -called the -.Dv termios -line discipline is associated with the file. -This is the primary -line discipline that is used in most cases and provides the semantics -that users normally associate with a terminal. -When the -.Dv termios -line discipline is in effect, the terminal file behaves and is -operated according to the rules described in -.Xr termios 4 . -Please refer to that man page for a full description of the terminal -semantics. -The operations described here -generally represent features common -across all -.Em "line disciplines" , -however some of these calls may not -make sense in conjunction with a line discipline other than -.Dv termios , -and some may not be supported by the underlying -hardware (or lack thereof, as in the case of ptys). .Ss Terminal File Operations All of the following operations are invoked using the .Xr ioctl 2 @@ -154,39 +113,24 @@ parameter (if any) are listed. For example, the first entry says .Pp -.D1 Em "TIOCSETD int *ldisc" +.D1 Em "TIOCSPGRP int *tpgrp" .Pp and would be called on the terminal associated with file descriptor zero by the following code fragment: .Bd -literal - int ldisc; + int pgrp; - ldisc = TTYDISC; - ioctl(0, TIOCSETD, &ldisc); + pgrp = getpgrp(); + ioctl(0, TIOCSPGRP, &pgrp); .Ed .Ss Terminal File Request Descriptions .Bl -tag -width TIOCGWINSZ .It Dv TIOCSETD Fa int *ldisc -Change to the new line discipline pointed to by +This call is obsolete but left for compatibility. +Before +.Fx 8.0 , +it would change to the new line discipline pointed to by .Fa ldisc . -The available line disciplines are listed in -.In sys/ttycom.h -and currently are: -.Pp -.Bl -tag -width NETGRAPHDISC -compact -.It TTYDISC -Termios interactive line discipline. -.It TABLDISC -Tablet line discipline. -.It SLIPDISC -Serial IP line discipline. -.It PPPDISC -PPP line discipline. -.It NETGRAPHDISC -Netgraph -.Xr ng_tty 4 -line discipline. -.El .Pp .It Dv TIOCGETD Fa int *ldisc Return the current line discipline in the integer pointed to by From 875d570a9115e75a2a18ea5118cf35e415daae22 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 10:38:17 +0000 Subject: [PATCH 2018/2592] MFC r201114: Add references to termios-related stuff. --- share/man/man4/termios.4 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/share/man/man4/termios.4 b/share/man/man4/termios.4 index cda16731235..ae07387451c 100644 --- a/share/man/man4/termios.4 +++ b/share/man/man4/termios.4 @@ -1577,3 +1577,10 @@ after is set according to the values in the header .In sys/ttydefaults.h . +.Sh SEE ALSO +.Xr stty 1 , +.Xr tcgetsid 3 , +.Xr tcsendbreak 3 , +.Xr tcsetattr 3 , +.Xr tcsetsid 3 , +.Xr tty 4 From 1bd4d5ddec6e5455eb1a322bdabb5c73ca25abe4 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 10:42:42 +0000 Subject: [PATCH 2019/2592] MFC r201118: Bump manual page dates. --- share/man/man4/termios.4 | 2 +- share/man/man4/tty.4 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man4/termios.4 b/share/man/man4/termios.4 index ae07387451c..5e589b102ff 100644 --- a/share/man/man4/termios.4 +++ b/share/man/man4/termios.4 @@ -32,7 +32,7 @@ .\" @(#)termios.4 8.4 (Berkeley) 4/19/94 .\" $FreeBSD$ .\" -.Dd August 20, 2008 +.Dd December 26, 2009 .Dt TERMIOS 4 .Os .Sh NAME diff --git a/share/man/man4/tty.4 b/share/man/man4/tty.4 index af7ecbeb0ff..6e7c8527684 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 December 26, 2009 .Dt TTY 4 .Os .Sh NAME From ff6dfec6dec7125f32e76d0d1fc6a3c5cdaa93c1 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 16:36:38 +0000 Subject: [PATCH 2020/2592] MFC r197859: '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 fa92a1d87a1..47ed32d8e5d 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 bfc6b188ec7552430a13c232e72d9be756a5bb3c Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 16:37:38 +0000 Subject: [PATCH 2021/2592] MFC r197867: 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 47ed32d8e5d..eb0a1fea75c 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 0718d64da3455b863cfafe62e6455148ca29503e Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 19:21:08 +0000 Subject: [PATCH 2022/2592] MFC r200796: Implement NFSv4 ACL support for UFS. Reviewed by: rwatson --- sbin/dumpfs/dumpfs.c | 5 +- sbin/mount/mntopts.h | 4 +- sbin/mount/mount.8 | 14 ++- sbin/mount/mount.c | 2 + sbin/tunefs/tunefs.8 | 5 +- sbin/tunefs/tunefs.c | 60 +++++++++-- sys/sys/mount.h | 9 +- sys/ufs/ffs/ffs_vfsops.c | 42 +++++++- sys/ufs/ffs/fs.h | 30 +++--- sys/ufs/ufs/acl.h | 2 + sys/ufs/ufs/ufs_acl.c | 222 ++++++++++++++++++++++++++++++++++++++- sys/ufs/ufs/ufs_lookup.c | 127 ++++++++++++++++++---- sys/ufs/ufs/ufs_vnops.c | 188 +++++++++++++++++++++++++++------ 13 files changed, 619 insertions(+), 91 deletions(-) diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c index 56463598883..e4b59950401 100644 --- a/sbin/dumpfs/dumpfs.c +++ b/sbin/dumpfs/dumpfs.c @@ -251,8 +251,11 @@ dumpfs(const char *name) printf("gjournal "); if (fsflags & FS_FLAGS_UPDATED) printf("fs_flags expanded "); + if (fsflags & FS_NFS4ACLS) + printf("nfsv4acls "); fsflags &= ~(FS_UNCLEAN | FS_DOSOFTDEP | FS_NEEDSFSCK | FS_INDEXDIRS | - FS_ACLS | FS_MULTILABEL | FS_GJOURNAL | FS_FLAGS_UPDATED); + FS_ACLS | FS_MULTILABEL | FS_GJOURNAL | FS_FLAGS_UPDATED | + FS_NFS4ACLS); if (fsflags != 0) printf("unknown flags (%#x)", fsflags); putchar('\n'); diff --git a/sbin/mount/mntopts.h b/sbin/mount/mntopts.h index 2fcbbddbbc1..2903d553f4e 100644 --- a/sbin/mount/mntopts.h +++ b/sbin/mount/mntopts.h @@ -54,6 +54,7 @@ struct mntopt { #define MOPT_SNAPSHOT { "snapshot", 0, MNT_SNAPSHOT, 0 } #define MOPT_MULTILABEL { "multilabel", 0, MNT_MULTILABEL, 0 } #define MOPT_ACLS { "acls", 0, MNT_ACLS, 0 } +#define MOPT_NFS4ACLS { "nfsv4acls", 0, MNT_NFS4ACLS, 0 } /* Control flags. */ #define MOPT_FORCE { "force", 0, MNT_FORCE, 0 } @@ -87,7 +88,8 @@ struct mntopt { MOPT_NOCLUSTERR, \ MOPT_NOCLUSTERW, \ MOPT_MULTILABEL, \ - MOPT_ACLS + MOPT_ACLS, \ + MOPT_NFS4ACLS void getmntopts(const char *, const struct mntopt *, int *, int *); void rmslashes(char *, char *); diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8 index 3efc9f1f6e5..ea014554dd6 100644 --- a/sbin/mount/mount.8 +++ b/sbin/mount/mount.8 @@ -120,11 +120,14 @@ takes effect. The following options are available: .Bl -tag -width indent .It Cm acls -Enable Access Control Lists, or ACLS, which can be customized via the +Enable POSIX.1e Access Control Lists, or ACLs, which can be customized via the .Xr setfacl 1 and .Xr getfacl 1 commands. +This flag is mutually exclusive with +.Cm nfsv4acls +flag. .It Cm async All .Tn I/O @@ -186,6 +189,15 @@ See .Xr mac 4 for more information, which cause the multilabel mount flag to be set automatically at mount-time. +.It Cm nfsv4acls +Enable NFSv4 ACLs, which can be customized via the +.Xr setfacl 1 +and +.Xr getfacl 1 +commands. +This flag is mutually exclusive with +.Cm acls +flag. .It Cm noasync Metadata I/O should be done synchronously, while data I/O should be done asynchronously. diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c index 1a6903d3c25..b39a7d119e3 100644 --- a/sbin/mount/mount.c +++ b/sbin/mount/mount.c @@ -111,6 +111,7 @@ static struct opt { { MNT_SOFTDEP, "soft-updates" }, { MNT_MULTILABEL, "multilabel" }, { MNT_ACLS, "acls" }, + { MNT_NFS4ACLS, "nfsv4acls" }, { MNT_GJOURNAL, "gjournal" }, { 0, NULL } }; @@ -918,6 +919,7 @@ flags2opts(int flags) if (flags & MNT_SUIDDIR) res = catopt(res, "suiddir"); if (flags & MNT_MULTILABEL) res = catopt(res, "multilabel"); if (flags & MNT_ACLS) res = catopt(res, "acls"); + if (flags & MNT_NFS4ACLS) res = catopt(res, "nfsv4acls"); return (res); } diff --git a/sbin/tunefs/tunefs.8 b/sbin/tunefs/tunefs.8 index 06e47cae864..46875c4eb04 100644 --- a/sbin/tunefs/tunefs.8 +++ b/sbin/tunefs/tunefs.8 @@ -44,6 +44,7 @@ .Op Fl L Ar volname .Op Fl l Cm enable | disable .Op Fl m Ar minfree +.Op Fl N Cm enable | disable .Op Fl n Cm enable | disable .Op Fl o Cm space | time .Op Fl p @@ -70,7 +71,7 @@ this option will cause all backups to be modified as well as the primary super-block. This is potentially dangerous - use with caution. .It Fl a Cm enable | disable -Turn on/off the administrative ACL enable flag. +Turn on/off the administrative POSIX.1e ACL enable flag. .It Fl e Ar maxbpg Indicate the maximum number of blocks any single file can allocate out of a cylinder group before it is forced to begin @@ -114,6 +115,8 @@ factor of three over the performance obtained at a 10% threshold. If the value is raised above the current usage level, users will be unable to allocate files until enough files have been deleted to get under the higher threshold. +.It Fl N Cm enable | disable +Turn on/off the administrative NFSv4 ACL enable flag. .It Fl n Cm enable | disable Turn on/off soft updates. .It Fl o Cm space | time diff --git a/sbin/tunefs/tunefs.c b/sbin/tunefs/tunefs.c index 57dfbcb7ce0..e4adb5267eb 100644 --- a/sbin/tunefs/tunefs.c +++ b/sbin/tunefs/tunefs.c @@ -76,12 +76,12 @@ void printfs(void); int main(int argc, char *argv[]) { - char *avalue, *Jvalue, *Lvalue, *lvalue, *nvalue; + char *avalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue; const char *special, *on; const char *name; int active; int Aflag, aflag, eflag, evalue, fflag, fvalue, Jflag, Lflag, lflag; - int mflag, mvalue, nflag, oflag, ovalue, pflag, sflag, svalue; + int mflag, mvalue, Nflag, nflag, oflag, ovalue, pflag, sflag, svalue; int ch, found_arg, i; const char *chg[2]; struct ufs_args args; @@ -90,12 +90,12 @@ main(int argc, char *argv[]) if (argc < 3) usage(); Aflag = aflag = eflag = fflag = Jflag = Lflag = lflag = mflag = 0; - nflag = oflag = pflag = sflag = 0; - avalue = Jvalue = Lvalue = lvalue = nvalue = NULL; + Nflag = nflag = oflag = pflag = sflag = 0; + avalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL; evalue = fvalue = mvalue = ovalue = svalue = 0; active = 0; found_arg = 0; /* At least one arg is required. */ - while ((ch = getopt(argc, argv, "Aa:e:f:J:L:l:m:n:o:ps:")) != -1) + while ((ch = getopt(argc, argv, "Aa:e:f:J:L:l:m:N:n:o:ps:")) != -1) switch (ch) { case 'A': @@ -105,7 +105,7 @@ main(int argc, char *argv[]) case 'a': found_arg = 1; - name = "ACLs"; + name = "POSIX.1e ACLs"; avalue = optarg; if (strcmp(avalue, "enable") && strcmp(avalue, "disable")) { @@ -187,6 +187,18 @@ main(int argc, char *argv[]) mflag = 1; break; + case 'N': + found_arg = 1; + name = "NFSv4 ACLs"; + Nvalue = optarg; + if (strcmp(Nvalue, "enable") && + strcmp(Nvalue, "disable")) { + errx(10, "bad %s (options are %s)", + name, "`enable' or `disable'"); + } + Nflag = 1; + break; + case 'n': found_arg = 1; name = "soft updates"; @@ -255,10 +267,13 @@ main(int argc, char *argv[]) strlcpy(sblock.fs_volname, Lvalue, MAXVOLLEN); } if (aflag) { - name = "ACLs"; + name = "POSIX.1e ACLs"; if (strcmp(avalue, "enable") == 0) { if (sblock.fs_flags & FS_ACLS) { warnx("%s remains unchanged as enabled", name); + } else if (sblock.fs_flags & FS_NFS4ACLS) { + warnx("%s and NFSv4 ACLs are mutually " + "exclusive", name); } else { sblock.fs_flags |= FS_ACLS; warnx("%s set", name); @@ -349,6 +364,29 @@ main(int argc, char *argv[]) warnx(OPTWARN, "space", "<", MINFREE); } } + if (Nflag) { + name = "NFSv4 ACLs"; + if (strcmp(Nvalue, "enable") == 0) { + if (sblock.fs_flags & FS_NFS4ACLS) { + warnx("%s remains unchanged as enabled", name); + } else if (sblock.fs_flags & FS_ACLS) { + warnx("%s and POSIX.1e ACLs are mutually " + "exclusive", name); + } else { + sblock.fs_flags |= FS_NFS4ACLS; + warnx("%s set", name); + } + } else if (strcmp(Nvalue, "disable") == 0) { + if ((~sblock.fs_flags & FS_NFS4ACLS) == + FS_NFS4ACLS) { + warnx("%s remains unchanged as disabled", + name); + } else { + sblock.fs_flags &= ~FS_NFS4ACLS; + warnx("%s cleared", name); + } + } + } if (nflag) { name = "soft updates"; if (strcmp(nvalue, "enable") == 0) { @@ -423,16 +461,18 @@ usage(void) fprintf(stderr, "%s\n%s\n%s\n%s\n", "usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]", " [-J enable | disable ] [-L volname] [-l enable | disable]", -" [-m minfree] [-n enable | disable] [-o space | time] [-p]", -" [-s avgfpdir] special | filesystem"); +" [-m minfree] [-N enable | disable] [-n enable | disable]", +" [-o space | time] [-p] [-s avgfpdir] special | filesystem"); exit(2); } void printfs(void) { - warnx("ACLs: (-a) %s", + warnx("POSIX.1e ACLs: (-a) %s", (sblock.fs_flags & FS_ACLS)? "enabled" : "disabled"); + warnx("NFSv4 ACLs: (-N) %s", + (sblock.fs_flags & FS_NFS4ACLS)? "enabled" : "disabled"); warnx("MAC multilabel: (-l) %s", (sblock.fs_flags & FS_MULTILABEL)? "enabled" : "disabled"); warnx("soft updates: (-n) %s", diff --git a/sys/sys/mount.h b/sys/sys/mount.h index dbf8c20fcc8..b8264130a17 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -239,6 +239,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp); #define MNT_NOATIME 0x10000000 /* disable update of file access time */ #define MNT_NOCLUSTERR 0x40000000 /* disable cluster read */ #define MNT_NOCLUSTERW 0x80000000 /* disable cluster write */ +#define MNT_NFS4ACLS 0x00000010 /* * NFS export related mount flags. @@ -274,7 +275,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp); MNT_ROOTFS | MNT_NOATIME | MNT_NOCLUSTERR| \ MNT_NOCLUSTERW | MNT_SUIDDIR | MNT_SOFTDEP | \ MNT_IGNORE | MNT_EXPUBLIC | MNT_NOSYMFOLLOW | \ - MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS) + MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS | MNT_NFS4ACLS) /* Mask of flags that can be updated. */ #define MNT_UPDATEMASK (MNT_NOSUID | MNT_NOEXEC | \ @@ -282,7 +283,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp); MNT_NOATIME | \ MNT_NOSYMFOLLOW | MNT_IGNORE | \ MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | \ - MNT_ACLS | MNT_USER) + MNT_ACLS | MNT_USER | MNT_NFS4ACLS) /* * External filesystem command modifier flags. @@ -299,10 +300,6 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp); #define MNT_BYFSID 0x08000000 /* specify filesystem by ID. */ #define MNT_CMDFLAGS (MNT_UPDATE | MNT_DELEXPORT | MNT_RELOAD | \ MNT_FORCE | MNT_SNAPSHOT | MNT_BYFSID) -/* - * Still available. - */ -#define MNT_SPARE_0x00000010 0x00000010 /* * Internal filesystem control flags stored in mnt_kern_flag. * diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 368f3112ced..a18461e65fe 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -128,7 +128,7 @@ static struct buf_ops ffs_ops = { static const char *ffs_opts[] = { "acls", "async", "noatime", "noclusterr", "noclusterw", "noexec", "export", "force", "from", "multilabel", "snapshot", "nosuid", "suiddir", "nosymfollow", "sync", - "union", NULL }; + "union", "nfsv4acls", NULL }; static int ffs_mount(struct mount *mp) @@ -177,6 +177,15 @@ ffs_mount(struct mount *mp) vfs_deleteopt(mp->mnt_opt, "snapshot"); } + if (vfs_getopt(mp->mnt_optnew, "nfsv4acls", NULL, NULL) == 0) { + if (mntorflags & MNT_ACLS) { + printf("WARNING: \"acls\" and \"nfsv4acls\" " + "options are mutually exclusive\n"); + return (EINVAL); + } + mntorflags |= MNT_NFS4ACLS; + } + MNT_ILOCK(mp); mp->mnt_flag = (mp->mnt_flag | mntorflags) & ~mntandnotflags; MNT_IUNLOCK(mp); @@ -360,6 +369,13 @@ ffs_mount(struct mount *mp) MNT_IUNLOCK(mp); } + if ((fs->fs_flags & FS_NFS4ACLS) != 0) { + /* XXX: Set too late ? */ + MNT_ILOCK(mp); + mp->mnt_flag |= MNT_NFS4ACLS; + MNT_IUNLOCK(mp); + } + /* * If this is a snapshot request, take the snapshot. */ @@ -833,7 +849,13 @@ ffs_mountfs(devvp, mp, td) if ((fs->fs_flags & FS_ACLS) != 0) { #ifdef UFS_ACL MNT_ILOCK(mp); + + if (mp->mnt_flag & MNT_NFS4ACLS) + printf("WARNING: ACLs flag on fs conflicts with " + "\"nfsv4acls\" mount option; option ignored\n"); + mp->mnt_flag &= ~MNT_NFS4ACLS; mp->mnt_flag |= MNT_ACLS; + MNT_IUNLOCK(mp); #else printf( @@ -841,6 +863,24 @@ ffs_mountfs(devvp, mp, td) mp->mnt_stat.f_mntonname); #endif } + if ((fs->fs_flags & FS_NFS4ACLS) != 0) { +#ifdef UFS_ACL + MNT_ILOCK(mp); + + if (mp->mnt_flag & MNT_ACLS) + printf("WARNING: NFSv4 ACLs flag on fs conflicts with " + "\"acls\" mount option; option ignored\n"); + mp->mnt_flag &= ~MNT_ACLS; + mp->mnt_flag |= MNT_NFS4ACLS; + + MNT_IUNLOCK(mp); +#else + printf( +"WARNING: %s: NFSv4 ACLs flag on fs but no ACLs support\n", + mp->mnt_stat.f_mntonname); +#endif + } + ump->um_mountp = mp; ump->um_dev = dev; ump->um_devvp = devvp; diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h index 5be5e4b5bc8..46b2064d7d6 100644 --- a/sys/ufs/ffs/fs.h +++ b/sys/ufs/ffs/fs.h @@ -393,22 +393,24 @@ CTASSERT(sizeof(struct fs) == 1376); * flag to indicate that the indicies need to be rebuilt (by fsck) before * they can be used. * - * FS_ACLS indicates that ACLs are administratively enabled for the - * file system, so they should be loaded from extended attributes, + * FS_ACLS indicates that POSIX.1e ACLs are administratively enabled + * for the file system, so they should be loaded from extended attributes, * observed for access control purposes, and be administered by object - * owners. FS_MULTILABEL indicates that the TrustedBSD MAC Framework - * should attempt to back MAC labels into extended attributes on the - * file system rather than maintain a single mount label for all - * objects. + * owners. FS_NFS4ACLS indicates that NFSv4 ACLs are administratively + * enabled. This flag is mutually exclusive with FS_ACLS. FS_MULTILABEL + * indicates that the TrustedBSD MAC Framework should attempt to back MAC + * labels into extended attributes on the file system rather than maintain + * a single mount label for all objects. */ -#define FS_UNCLEAN 0x01 /* filesystem not clean at mount */ -#define FS_DOSOFTDEP 0x02 /* filesystem using soft dependencies */ -#define FS_NEEDSFSCK 0x04 /* filesystem needs sync fsck before mount */ -#define FS_INDEXDIRS 0x08 /* kernel supports indexed directories */ -#define FS_ACLS 0x10 /* file system has ACLs enabled */ -#define FS_MULTILABEL 0x20 /* file system is MAC multi-label */ -#define FS_GJOURNAL 0x40 /* gjournaled file system */ -#define FS_FLAGS_UPDATED 0x80 /* flags have been moved to new location */ +#define FS_UNCLEAN 0x0001 /* filesystem not clean at mount */ +#define FS_DOSOFTDEP 0x0002 /* filesystem using soft dependencies */ +#define FS_NEEDSFSCK 0x0004 /* filesystem needs sync fsck before mount */ +#define FS_INDEXDIRS 0x0008 /* kernel supports indexed directories */ +#define FS_ACLS 0x0010 /* file system has POSIX.1e ACLs enabled */ +#define FS_MULTILABEL 0x0020 /* file system is MAC multi-label */ +#define FS_GJOURNAL 0x0040 /* gjournaled file system */ +#define FS_FLAGS_UPDATED 0x0080 /* flags have been moved to new location */ +#define FS_NFS4ACLS 0x0100 /* file system has NFSv4 ACLs enabled */ /* * Macros to access bits in the fs_active array. diff --git a/sys/ufs/ufs/acl.h b/sys/ufs/ufs/acl.h index b53e3284df1..235261e5164 100644 --- a/sys/ufs/ufs/acl.h +++ b/sys/ufs/ufs/acl.h @@ -37,6 +37,8 @@ #ifdef _KERNEL +int ufs_getacl_nfs4_internal(struct vnode *vp, struct acl *aclp, struct thread *td); +int ufs_setacl_nfs4_internal(struct vnode *vp, struct acl *aclp, struct thread *td); void ufs_sync_acl_from_inode(struct inode *ip, struct acl *acl); void ufs_sync_inode_from_acl(struct acl *acl, struct inode *ip); diff --git a/sys/ufs/ufs/ufs_acl.c b/sys/ufs/ufs/ufs_acl.c index c04a5d2ffaa..1a0030cf2bd 100644 --- a/sys/ufs/ufs/ufs_acl.c +++ b/sys/ufs/ufs/ufs_acl.c @@ -140,6 +140,81 @@ ufs_sync_inode_from_acl(struct acl *acl, struct inode *ip) DIP_SET(ip, i_mode, ip->i_mode); } +/* + * Retrieve NFSv4 ACL, skipping access checks. Must be used in UFS code + * instead of VOP_GETACL() when we don't want to be restricted by the user + * not having ACL_READ_ACL permission, e.g. when calculating inherited ACL + * or in ufs_vnops.c:ufs_accessx(). + */ +int +ufs_getacl_nfs4_internal(struct vnode *vp, struct acl *aclp, struct thread *td) +{ + int error, len; + struct inode *ip = VTOI(vp); + + len = sizeof(*aclp); + bzero(aclp, len); + + error = vn_extattr_get(vp, IO_NODELOCKED, + NFS4_ACL_EXTATTR_NAMESPACE, NFS4_ACL_EXTATTR_NAME, + &len, (char *) aclp, td); + aclp->acl_maxcnt = ACL_MAX_ENTRIES; + if (error == ENOATTR) { + /* + * Legitimately no ACL set on object, purely + * emulate it through the inode. + */ + acl_nfs4_sync_acl_from_mode(aclp, ip->i_mode, ip->i_uid); + + return (0); + } + + if (error) + return (error); + + if (len != sizeof(*aclp)) { + /* + * A short (or long) read, meaning that for + * some reason the ACL is corrupted. Return + * EPERM since the object DAC protections + * are unsafe. + */ + printf("ufs_getacl_nfs4(): Loaded invalid ACL (" + "%d bytes), inumber %d on %s\n", len, + ip->i_number, ip->i_fs->fs_fsmnt); + + return (EPERM); + } + + error = acl_nfs4_check(aclp, vp->v_type == VDIR); + if (error) { + printf("ufs_getacl_nfs4(): Loaded invalid ACL " + "(failed acl_nfs4_check), inumber %d on %s\n", + ip->i_number, ip->i_fs->fs_fsmnt); + + return (EPERM); + } + + return (0); +} + +static int +ufs_getacl_nfs4(struct vop_getacl_args *ap) +{ + int error; + + if ((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 0) + return (EINVAL); + + error = VOP_ACCESSX(ap->a_vp, VREAD_ACL, ap->a_td->td_ucred, ap->a_td); + if (error) + return (error); + + error = ufs_getacl_nfs4_internal(ap->a_vp, ap->a_aclp, ap->a_td); + + return (error); +} + /* * Read POSIX.1e ACL from an EA. Return error if its not found * or if any other error has occured. @@ -209,7 +284,7 @@ ufs_getacl_posix1e(struct vop_getacl_args *ap) * ACLs, remove this check. */ if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) - return (EOPNOTSUPP); + return (EINVAL); old = malloc(sizeof(*old), M_ACL, M_WAITOK | M_ZERO); @@ -285,9 +360,117 @@ ufs_getacl(ap) } */ *ap; { + if ((ap->a_vp->v_mount->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS)) == 0) + return (EOPNOTSUPP); + + if (ap->a_type == ACL_TYPE_NFS4) + return (ufs_getacl_nfs4(ap)); + return (ufs_getacl_posix1e(ap)); } +/* + * Set NFSv4 ACL without doing any access checking. This is required + * e.g. by the UFS code that implements ACL inheritance, or from + * ufs_vnops.c:ufs_chmod(), as some of the checks have to be skipped + * in that case, and others are redundant. + */ +int +ufs_setacl_nfs4_internal(struct vnode *vp, struct acl *aclp, struct thread *td) +{ + int error; + mode_t mode; + struct inode *ip = VTOI(vp); + + KASSERT(acl_nfs4_check(aclp, vp->v_type == VDIR) == 0, + ("invalid ACL passed to ufs_setacl_nfs4_internal")); + + if (acl_nfs4_is_trivial(aclp, ip->i_uid)) { + error = vn_extattr_rm(vp, IO_NODELOCKED, + NFS4_ACL_EXTATTR_NAMESPACE, NFS4_ACL_EXTATTR_NAME, td); + + /* + * An attempt to remove ACL from a file that didn't have + * any extended entries is not an error. + */ + if (error == ENOATTR) + error = 0; + + } else { + error = vn_extattr_set(vp, IO_NODELOCKED, + NFS4_ACL_EXTATTR_NAMESPACE, NFS4_ACL_EXTATTR_NAME, + sizeof(*aclp), (char *) aclp, td); + } + + /* + * Map lack of attribute definition in UFS_EXTATTR into lack of + * support for ACLs on the filesystem. + */ + if (error == ENOATTR) + return (EOPNOTSUPP); + + if (error) + return (error); + + mode = ip->i_mode; + + acl_nfs4_sync_mode_from_acl(&mode, aclp); + + ip->i_mode &= ACL_PRESERVE_MASK; + ip->i_mode |= mode; + DIP_SET(ip, i_mode, ip->i_mode); + ip->i_flag |= IN_CHANGE; + + VN_KNOTE_UNLOCKED(vp, NOTE_ATTRIB); + + return (0); +} + +static int +ufs_setacl_nfs4(struct vop_setacl_args *ap) +{ + int error; + struct inode *ip = VTOI(ap->a_vp); + + if ((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 0) + return (EINVAL); + + if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) + return (EROFS); + + if (ap->a_aclp == NULL) + return (EINVAL); + + error = VOP_ACLCHECK(ap->a_vp, ap->a_type, ap->a_aclp, ap->a_cred, + ap->a_td); + if (error) + return (error); + + /* + * Authorize the ACL operation. + */ + if (ip->i_flags & (IMMUTABLE | APPEND)) + return (EPERM); + + /* + * Must hold VWRITE_ACL or have appropriate privilege. + */ + if ((error = VOP_ACCESSX(ap->a_vp, VWRITE_ACL, ap->a_cred, ap->a_td))) + return (error); + + /* + * With NFSv4 ACLs, chmod(2) may need to add additional entries. + * Make sure it has enough room for that - splitting every entry + * into two and appending "canonical six" entries at the end. + */ + if (ap->a_aclp->acl_cnt > (ACL_MAX_ENTRIES - 6) / 2) + return (ENOSPC); + + error = ufs_setacl_nfs4_internal(ap->a_vp, ap->a_aclp, ap->a_td); + + return (0); +} + /* * Set the ACL on a file. * @@ -305,7 +488,7 @@ ufs_setacl_posix1e(struct vop_setacl_args *ap) struct oldacl *old; if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) - return (EOPNOTSUPP); + return (EINVAL); /* * If this is a set operation rather than a delete operation, @@ -425,16 +608,43 @@ ufs_setacl(ap) struct thread *td; } */ *ap; { + if ((ap->a_vp->v_mount->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS)) == 0) + return (EOPNOTSUPP); + + if (ap->a_type == ACL_TYPE_NFS4) + return (ufs_setacl_nfs4(ap)); return (ufs_setacl_posix1e(ap)); } +static int +ufs_aclcheck_nfs4(struct vop_aclcheck_args *ap) +{ + int is_directory = 0; + + if ((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 0) + return (EINVAL); + + /* + * With NFSv4 ACLs, chmod(2) may need to add additional entries. + * Make sure it has enough room for that - splitting every entry + * into two and appending "canonical six" entries at the end. + */ + if (ap->a_aclp->acl_cnt > (ACL_MAX_ENTRIES - 6) / 2) + return (ENOSPC); + + if (ap->a_vp->v_type == VDIR) + is_directory = 1; + + return (acl_nfs4_check(ap->a_aclp, is_directory)); +} + static int ufs_aclcheck_posix1e(struct vop_aclcheck_args *ap) { if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) - return (EOPNOTSUPP); + return (EINVAL); /* * Verify we understand this type of ACL, and that it applies @@ -474,6 +684,12 @@ ufs_aclcheck(ap) } */ *ap; { + if ((ap->a_vp->v_mount->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS)) == 0) + return (EOPNOTSUPP); + + if (ap->a_type == ACL_TYPE_NFS4) + return (ufs_aclcheck_nfs4(ap)); + return (ufs_aclcheck_posix1e(ap)); } diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index ea73b1ff861..a19068ee075 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -80,6 +80,61 @@ SYSCTL_INT(_debug, OID_AUTO, dircheck, CTLFLAG_RW, &dirchk, 0, ""); static int ufs_lookup_(struct vnode *, struct vnode **, struct componentname *, ino_t *); +static int +ufs_delete_denied(struct vnode *vdp, struct vnode *tdp, struct ucred *cred, + struct thread *td) +{ + int error; + +#ifdef UFS_ACL + /* + * NFSv4 Minor Version 1, draft-ietf-nfsv4-minorversion1-03.txt + * + * 3.16.2.1. ACE4_DELETE vs. ACE4_DELETE_CHILD + */ + + /* + * XXX: Is this check required? + */ + error = VOP_ACCESS(vdp, VEXEC, cred, td); + if (error) + return (error); + + error = VOP_ACCESSX(tdp, VDELETE, cred, td); + if (error == 0) + return (0); + + error = VOP_ACCESSX(vdp, VDELETE_CHILD, cred, td); + if (error == 0) + return (0); + + error = VOP_ACCESSX(vdp, VEXPLICIT_DENY | VDELETE_CHILD, cred, td); + if (error) + return (error); + +#endif /* !UFS_ACL */ + + /* + * Standard Unix access control - delete access requires VWRITE. + */ + error = VOP_ACCESS(vdp, VWRITE, cred, td); + if (error) + return (error); + + /* + * If directory is "sticky", then user must own + * the directory, or the file in it, else she + * may not delete it (unless she's root). This + * implements append-only directories. + */ + if ((VTOI(vdp)->i_mode & ISVTX) && + VOP_ACCESS(vdp, VADMIN, cred, td) && + VOP_ACCESS(tdp, VADMIN, cred, td)) + return (EPERM); + + return (0); +} + /* * Convert a component of a pathname into a pointer to a locked inode. * This is a very central and rather complicated routine. @@ -410,8 +465,13 @@ notfound: /* * Access for write is interpreted as allowing * creation of files in the directory. + * + * XXX: Fix the comment above. */ - error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_thread); + if (flags & WILLBEDIR) + error = VOP_ACCESSX(vdp, VWRITE | VAPPEND, cred, cnp->cn_thread); + else + error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_thread); if (error) return (error); /* @@ -498,12 +558,17 @@ found: if (nameiop == DELETE && (flags & ISLASTCN)) { if (flags & LOCKPARENT) ASSERT_VOP_ELOCKED(vdp, __FUNCTION__); - /* - * Write access to directory required to delete files. - */ - error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_thread); - if (error) + if ((error = VFS_VGET(vdp->v_mount, ino, + LK_EXCLUSIVE, &tdp)) != 0) return (error); + + error = ufs_delete_denied(vdp, tdp, cred, cnp->cn_thread); + if (error) { + vput(tdp); + return (error); + } + + /* * Return pointer to current entry in dp->i_offset, * and distance past previous entry (if there @@ -523,23 +588,10 @@ found: if (dp->i_number == ino) { VREF(vdp); *vpp = vdp; + vput(tdp); return (0); } - if ((error = VFS_VGET(vdp->v_mount, ino, - LK_EXCLUSIVE, &tdp)) != 0) - return (error); - /* - * If directory is "sticky", then user must own - * the directory, or the file in it, else she - * may not delete it (unless she's root). This - * implements append-only directories. - */ - if ((dp->i_mode & ISVTX) && - VOP_ACCESS(vdp, VADMIN, cred, cnp->cn_thread) && - VOP_ACCESS(tdp, VADMIN, cred, cnp->cn_thread)) { - vput(tdp); - return (EPERM); - } + *vpp = tdp; return (0); } @@ -551,7 +603,11 @@ found: * regular file, or empty directory. */ if (nameiop == RENAME && (flags & ISLASTCN)) { - if ((error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_thread))) + if (flags & WILLBEDIR) + error = VOP_ACCESSX(vdp, VWRITE | VAPPEND, cred, cnp->cn_thread); + else + error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_thread); + if (error) return (error); /* * Careful about locking second inode. @@ -563,6 +619,33 @@ found: if ((error = VFS_VGET(vdp->v_mount, ino, LK_EXCLUSIVE, &tdp)) != 0) return (error); + + error = ufs_delete_denied(vdp, tdp, cred, cnp->cn_thread); + if (error) { + vput(tdp); + return (error); + } + +#ifdef SunOS_doesnt_do_that + /* + * The only purpose of this check is to return the correct + * error. Assume that we want to rename directory "a" + * to a file "b", and that we have no ACL_WRITE_DATA on + * a containing directory, but we _do_ have ACL_APPEND_DATA. + * In that case, the VOP_ACCESS check above will return 0, + * and the operation will fail with ENOTDIR instead + * of EACCESS. + */ + if (tdp->v_type == VDIR) + error = VOP_ACCESSX(vdp, VWRITE | VAPPEND, cred, cnp->cn_thread); + else + error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_thread); + if (error) { + vput(tdp); + return (error); + } +#endif + *vpp = tdp; cnp->cn_flags |= SAVENAME; return (0); diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 08b77ae0729..2d8f276c927 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -88,7 +88,7 @@ __FBSDID("$FreeBSD$"); #include -static vop_access_t ufs_access; +static vop_accessx_t ufs_accessx; static int ufs_chmod(struct vnode *, int, struct ucred *, struct thread *); static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *, struct thread *); static vop_close_t ufs_close; @@ -298,8 +298,8 @@ ufs_close(ap) } static int -ufs_access(ap) - struct vop_access_args /* { +ufs_accessx(ap) + struct vop_accessx_args /* { struct vnode *a_vp; accmode_t a_accmode; struct ucred *a_cred; @@ -315,6 +315,7 @@ ufs_access(ap) #endif #ifdef UFS_ACL struct acl *acl; + acl_type_t type; #endif /* @@ -322,7 +323,7 @@ ufs_access(ap) * unless the file is a socket, fifo, or a block or * character device resident on the filesystem. */ - if (accmode & VWRITE) { + if (accmode & VMODIFY_PERMS) { switch (vp->v_type) { case VDIR: case VLNK: @@ -367,41 +368,63 @@ relock: } } - /* If immutable bit set, nobody gets to write it. */ - if ((accmode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT))) + /* + * If immutable bit set, nobody gets to write it. "& ~VADMIN_PERMS" + * is here, because without it, * it would be impossible for the owner + * to remove the IMMUTABLE flag. + */ + if ((accmode & (VMODIFY_PERMS & ~VADMIN_PERMS)) && + (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT))) return (EPERM); #ifdef UFS_ACL - if ((vp->v_mount->mnt_flag & MNT_ACLS) != 0) { + if ((vp->v_mount->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS)) != 0) { + if (vp->v_mount->mnt_flag & MNT_NFS4ACLS) + type = ACL_TYPE_NFS4; + else + type = ACL_TYPE_ACCESS; + acl = acl_alloc(M_WAITOK); - error = VOP_GETACL(vp, ACL_TYPE_ACCESS, acl, ap->a_cred, - ap->a_td); + if (type == ACL_TYPE_NFS4) + error = ufs_getacl_nfs4_internal(vp, acl, ap->a_td); + else + error = VOP_GETACL(vp, type, acl, ap->a_cred, ap->a_td); switch (error) { - case EOPNOTSUPP: - error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, - ip->i_gid, ap->a_accmode, ap->a_cred, NULL); - break; case 0: - error = vaccess_acl_posix1e(vp->v_type, ip->i_uid, - ip->i_gid, acl, ap->a_accmode, ap->a_cred, NULL); + if (type == ACL_TYPE_NFS4) { + error = vaccess_acl_nfs4(vp->v_type, ip->i_uid, + ip->i_gid, acl, accmode, ap->a_cred, NULL); + } else { + error = vfs_unixify_accmode(&accmode); + if (error == 0) + error = vaccess_acl_posix1e(vp->v_type, ip->i_uid, + ip->i_gid, acl, accmode, ap->a_cred, NULL); + } break; default: - printf( -"ufs_access(): Error retrieving ACL on object (%d).\n", - error); + if (error != EOPNOTSUPP) + printf( +"ufs_accessx(): Error retrieving ACL on object (%d).\n", + error); /* * XXX: Fall back until debugged. Should * eventually possibly log an error, and return * EPERM for safety. */ - error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, - ip->i_gid, ap->a_accmode, ap->a_cred, NULL); + error = vfs_unixify_accmode(&accmode); + if (error == 0) + error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, + ip->i_gid, accmode, ap->a_cred, NULL); } acl_free(acl); - } else + + return (error); + } #endif /* !UFS_ACL */ + error = vfs_unixify_accmode(&accmode); + if (error == 0) error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, - ap->a_accmode, ap->a_cred, NULL); + accmode, ap->a_cred, NULL); return (error); } @@ -608,11 +631,20 @@ ufs_setattr(ap) * check succeeds. */ if (vap->va_vaflags & VA_UTIMES_NULL) { - error = VOP_ACCESS(vp, VADMIN, cred, td); + /* + * NFSv4.1, draft 21, 6.2.1.3.1, Discussion of Mask Attributes + * + * "A user having ACL_WRITE_DATA or ACL_WRITE_ATTRIBUTES + * will be allowed to set the times [..] to the current + * server time." + * + * XXX: Calling it four times seems a little excessive. + */ + error = VOP_ACCESSX(vp, VWRITE_ATTRIBUTES, cred, td); if (error) error = VOP_ACCESS(vp, VWRITE, cred, td); } else - error = VOP_ACCESS(vp, VADMIN, cred, td); + error = VOP_ACCESSX(vp, VWRITE_ATTRIBUTES, cred, td); if (error) return (error); if (vap->va_atime.tv_sec != VNOVAL) @@ -652,6 +684,32 @@ ufs_setattr(ap) return (error); } +#ifdef UFS_ACL +static int +ufs_update_nfs4_acl_after_mode_change(struct vnode *vp, int mode, + int file_owner_id, struct ucred *cred, struct thread *td) +{ + int error; + struct acl *aclp; + + aclp = acl_alloc(M_WAITOK); + error = ufs_getacl_nfs4_internal(vp, aclp, td); + /* + * We don't have to handle EOPNOTSUPP here, as the filesystem claims + * it supports ACLs. + */ + if (error) + goto out; + + acl_nfs4_sync_acl_from_mode(aclp, mode, file_owner_id); + error = ufs_setacl_nfs4_internal(vp, aclp, td); + +out: + acl_free(aclp); + return (error); +} +#endif /* UFS_ACL */ + /* * Mark this file's access time for update for vfs_mark_atime(). This * is called from execve() and mmap(). @@ -689,7 +747,7 @@ ufs_chmod(vp, mode, cred, td) * To modify the permissions on a file, must possess VADMIN * for that file. */ - if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) + if ((error = VOP_ACCESSX(vp, VWRITE_ACL, cred, td))) return (error); /* * Privileged processes may set the sticky bit on non-directories, @@ -706,11 +764,25 @@ ufs_chmod(vp, mode, cred, td) if (error) return (error); } + + /* + * Deny setting setuid if we are not the file owner. + */ + if ((mode & ISUID) && ip->i_uid != cred->cr_uid) { + error = priv_check_cred(cred, PRIV_VFS_ADMIN, 0); + if (error) + return (error); + } + ip->i_mode &= ~ALLPERMS; ip->i_mode |= (mode & ALLPERMS); DIP_SET(ip, i_mode, ip->i_mode); ip->i_flag |= IN_CHANGE; - return (0); +#ifdef UFS_ACL + if ((vp->v_mount->mnt_flag & MNT_NFS4ACLS) != 0) + error = ufs_update_nfs4_acl_after_mode_change(vp, mode, ip->i_uid, cred, td); +#endif + return (error); } /* @@ -742,14 +814,14 @@ ufs_chown(vp, uid, gid, cred, td) * To modify the ownership of a file, must possess VADMIN for that * file. */ - if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) + if ((error = VOP_ACCESSX(vp, VWRITE_OWNER, cred, td))) return (error); /* * To change the owner of a file, or change the group of a file to a * group of which we are not a member, the caller must have * privilege. */ - if ((uid != ip->i_uid || + if (((uid != ip->i_uid && uid != cred->cr_uid) || (gid != ip->i_gid && !groupmember(gid, cred))) && (error = priv_check_cred(cred, PRIV_VFS_CHOWN, 0))) return (error); @@ -1397,6 +1469,33 @@ out: return (error); } +#ifdef UFS_ACL +static int +ufs_do_nfs4_acl_inheritance(struct vnode *dvp, struct vnode *tvp, + mode_t child_mode, struct ucred *cred, struct thread *td) +{ + int error; + struct acl *parent_aclp, *child_aclp; + + parent_aclp = acl_alloc(M_WAITOK); + child_aclp = acl_alloc(M_WAITOK | M_ZERO); + + error = ufs_getacl_nfs4_internal(dvp, parent_aclp, td); + if (error) + goto out; + acl_nfs4_compute_inherited_acl(parent_aclp, child_aclp, + child_mode, VTOI(tvp)->i_uid, tvp->v_type == VDIR); + error = ufs_setacl_nfs4_internal(tvp, child_aclp, td); + if (error) + goto out; +out: + acl_free(parent_aclp); + acl_free(child_aclp); + + return (error); +} +#endif + /* * Mkdir system call */ @@ -1630,6 +1729,13 @@ ufs_mkdir(ap) acl_free(dacl); dacl = acl = NULL; } + + if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) { + error = ufs_do_nfs4_acl_inheritance(dvp, tvp, dmode, + cnp->cn_cred, cnp->cn_thread); + if (error) + goto bad; + } #endif /* !UFS_ACL */ /* @@ -2117,6 +2223,7 @@ ufsfifo_pathconf(ap) switch (ap->a_name) { case _PC_ACL_EXTENDED: + case _PC_ACL_NFS4: case _PC_ACL_PATH_MAX: case _PC_MAC_PRESENT: return (ufs_pathconf(ap)); @@ -2169,9 +2276,21 @@ ufs_pathconf(ap) *ap->a_retval = 0; #endif break; + + case _PC_ACL_NFS4: +#ifdef UFS_ACL + if (ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) + *ap->a_retval = 1; + else + *ap->a_retval = 0; +#else + *ap->a_retval = 0; +#endif + break; + case _PC_ACL_PATH_MAX: #ifdef UFS_ACL - if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS) + if (ap->a_vp->v_mount->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS)) *ap->a_retval = ACL_MAX_ENTRIES; else *ap->a_retval = 3; @@ -2466,6 +2585,13 @@ ufs_makeinode(mode, dvp, vpp, cnp) } acl_free(acl); } + + if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) { + error = ufs_do_nfs4_acl_inheritance(dvp, tvp, mode, + cnp->cn_cred, cnp->cn_thread); + if (error) + goto bad; + } #endif /* !UFS_ACL */ ufs_makedirentry(ip, cnp, &newdir); error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL); @@ -2496,7 +2622,7 @@ struct vop_vector ufs_vnodeops = { .vop_read = VOP_PANIC, .vop_reallocblks = VOP_PANIC, .vop_write = VOP_PANIC, - .vop_access = ufs_access, + .vop_accessx = ufs_accessx, .vop_bmap = ufs_bmap, .vop_cachedlookup = ufs_lookup, .vop_close = ufs_close, @@ -2540,7 +2666,7 @@ struct vop_vector ufs_vnodeops = { struct vop_vector ufs_fifoops = { .vop_default = &fifo_specops, .vop_fsync = VOP_PANIC, - .vop_access = ufs_access, + .vop_accessx = ufs_accessx, .vop_close = ufsfifo_close, .vop_getattr = ufs_getattr, .vop_inactive = ufs_inactive, From e7e223603dfb2c23413baea7fb0b044ec4ec4e72 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 19:40:52 +0000 Subject: [PATCH 2023/2592] MFC r200811: Add regression test for NFSv4 ACLs on UFS. --- tools/regression/acltools/02.t | 86 ++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tools/regression/acltools/02.t diff --git a/tools/regression/acltools/02.t b/tools/regression/acltools/02.t new file mode 100644 index 00000000000..431375ed5b7 --- /dev/null +++ b/tools/regression/acltools/02.t @@ -0,0 +1,86 @@ +#!/bin/sh +# +# Copyright (c) 2008, 2009 Edward Tomasz Napierała +# 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$ +# + +# This is a wrapper script to run tools-nfs4.test. +# +# If any of the tests fails, here is how to debug it: go to +# the directory with problematic filesystem mounted on it, +# and do /path/to/test run /path/to/test tools-nfs4.test, e.g. +# +# /usr/src/tools/regression/acltools/run /usr/src/tools/regression/acltools/tools-nfs4.test +# +# Output should be obvious. + +echo "1..4" + +if [ `whoami` != "root" ]; then + echo "not ok 1 - you need to be root to run this test." + exit 1 +fi + +TESTDIR=`dirname $0` + +# Set up the test filesystem. +MD=`mdconfig -at swap -s 10m` +MNT=`mktemp -dt acltools` +newfs /dev/$MD > /dev/null +mount -o nfsv4acls /dev/$MD $MNT +if [ $? -ne 0 ]; then + echo "not ok 1 - mount failed." + exit 1 +fi + +echo "ok 1" + +cd $MNT + +# First, check whether we can crash the kernel by creating too many +# entries. For some reason this won't work in the test file. +touch xxx +setfacl -x5 xxx +while :; do setfacl -a0 u:42:rwx:allow xxx 2> /dev/null; if [ $? -ne 0 ]; then break; fi; done +chmod 600 xxx +rm xxx +echo "ok 2" + +perl $TESTDIR/run $TESTDIR/tools-nfs4.test > /dev/null + +if [ $? -eq 0 ]; then + echo "ok 3" +else + echo "not ok 3" +fi + +cd / +umount -f $MNT +rmdir $MNT +mdconfig -du $MD + +echo "ok 4" + From 8fce74fce5fdef066a7022526716a1a785778c65 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 19:44:54 +0000 Subject: [PATCH 2024/2592] MFC r200829: Cosmetic fixes. --- sys/sys/acl.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/sys/acl.h b/sys/sys/acl.h index 855e85c7ce6..80a3fe61637 100644 --- a/sys/sys/acl.h +++ b/sys/sys/acl.h @@ -99,13 +99,13 @@ struct oldacl { * Current "struct acl". */ struct acl_entry { - acl_tag_t ae_tag; - uid_t ae_id; - acl_perm_t ae_perm; - /* "allow" or "deny". Unused in POSIX ACLs. */ + acl_tag_t ae_tag; + uid_t ae_id; + acl_perm_t ae_perm; + /* NFSv4 entry type, "allow" or "deny". Unused in POSIX.1e ACLs. */ acl_entry_type_t ae_entry_type; - /* Flags control inheritance. Unused in POSIX ACLs. */ - acl_flag_t ae_flags; + /* NFSv4 ACL inheritance. Unused in POSIX.1e ACLs. */ + acl_flag_t ae_flags; }; typedef struct acl_entry *acl_entry_t; From a515de671b4187e929d20072911d4b0f45fb32c6 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 19:51:46 +0000 Subject: [PATCH 2025/2592] MFC r206160 by jh@: Add missing MNT_NFS4ACLS. --- sys/kern/vfs_subr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 51ec34e8bb1..0265b747377 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2799,6 +2799,7 @@ DB_SHOW_COMMAND(mount, db_show_mount) MNT_FLAG(MNT_NOATIME); MNT_FLAG(MNT_NOCLUSTERR); MNT_FLAG(MNT_NOCLUSTERW); + MNT_FLAG(MNT_NFS4ACLS); MNT_FLAG(MNT_EXRDONLY); MNT_FLAG(MNT_EXPORTED); MNT_FLAG(MNT_DEFEXPORTED); From 1d908ad75f043a78dea6ac6c6fa9eb31909d3043 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 20:23:08 +0000 Subject: [PATCH 2026/2592] MFC r204075: Style nits. --- sbin/ggate/ggated/ggated.c | 2 +- sbin/ggate/shared/ggate.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sbin/ggate/ggated/ggated.c b/sbin/ggate/ggated/ggated.c index 3b2a0a574c9..2997a9cf2c6 100644 --- a/sbin/ggate/ggated/ggated.c +++ b/sbin/ggate/ggated/ggated.c @@ -10,7 +10,7 @@ * 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 AUTHORS 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 diff --git a/sbin/ggate/shared/ggate.c b/sbin/ggate/shared/ggate.c index dd40790120d..cf9b9ca1574 100644 --- a/sbin/ggate/shared/ggate.c +++ b/sbin/ggate/shared/ggate.c @@ -10,7 +10,7 @@ * 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 AUTHORS 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 @@ -159,7 +159,7 @@ g_gate_sectorsize(int fd) g_gate_xlog("fstat(): %s.", strerror(errno)); if (S_ISCHR(sb.st_mode)) { if (ioctl(fd, DIOCGSECTORSIZE, &secsize) == -1) { - g_gate_xlog("Can't get sector size: %s.", + g_gate_xlog("Can't get sector size: %s.", strerror(errno)); } } else if (S_ISREG(sb.st_mode)) { @@ -174,7 +174,7 @@ void g_gate_open_device(void) { - g_gate_devfd = open("/dev/" G_GATE_CTL_NAME, O_RDWR, 0); + g_gate_devfd = open("/dev/" G_GATE_CTL_NAME, O_RDWR); if (g_gate_devfd == -1) err(EXIT_FAILURE, "open(/dev/%s)", G_GATE_CTL_NAME); } @@ -281,7 +281,7 @@ g_gate_socket_settings(int sfd) /* Socket settings. */ on = 1; if (nagle) { - if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &on, + if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == -1) { g_gate_xlog("setsockopt() error: %s.", strerror(errno)); } From 93df368f6cbbbc5315b871b5a227bc7a815fff03 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 18 Apr 2010 20:34:46 +0000 Subject: [PATCH 2027/2592] MFC r202934: Move out code that does POSIX.1e ACL inheritance into separate routines. Reviewed by: rwatson --- sys/ufs/ufs/ufs_vnops.c | 357 +++++++++++++++++++--------------------- 1 file changed, 171 insertions(+), 186 deletions(-) diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 2d8f276c927..9d4d93dbc8f 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1470,6 +1470,163 @@ out: } #ifdef UFS_ACL +static int +ufs_do_posix1e_acl_inheritance_dir(struct vnode *dvp, struct vnode *tvp, + mode_t dmode, struct ucred *cred, struct thread *td) +{ + int error; + struct inode *ip = VTOI(tvp); + struct acl *dacl, *acl; + + acl = acl_alloc(M_WAITOK); + dacl = acl_alloc(M_WAITOK); + + /* + * Retrieve default ACL from parent, if any. + */ + error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred, td); + switch (error) { + case 0: + /* + * Retrieved a default ACL, so merge mode and ACL if + * necessary. If the ACL is empty, fall through to + * the "not defined or available" case. + */ + if (acl->acl_cnt != 0) { + dmode = acl_posix1e_newfilemode(dmode, acl); + ip->i_mode = dmode; + DIP_SET(ip, i_mode, dmode); + *dacl = *acl; + ufs_sync_acl_from_inode(ip, acl); + break; + } + /* FALLTHROUGH */ + + case EOPNOTSUPP: + /* + * Just use the mode as-is. + */ + ip->i_mode = dmode; + DIP_SET(ip, i_mode, dmode); + error = 0; + goto out; + + default: + goto out; + } + + /* + * XXX: If we abort now, will Soft Updates notify the extattr + * code that the EAs for the file need to be released? + */ + error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cred, td); + if (error == 0) + error = VOP_SETACL(tvp, ACL_TYPE_DEFAULT, dacl, cred, td); + switch (error) { + case 0: + break; + + case EOPNOTSUPP: + /* + * XXX: This should not happen, as EOPNOTSUPP above + * was supposed to free acl. + */ + printf("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()\n"); + /* + panic("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()"); + */ + break; + + default: + goto out; + } + +out: + acl_free(acl); + acl_free(dacl); + + return (error); +} + +static int +ufs_do_posix1e_acl_inheritance_file(struct vnode *dvp, struct vnode *tvp, + mode_t mode, struct ucred *cred, struct thread *td) +{ + int error; + struct inode *ip = VTOI(tvp); + struct acl *acl; + + acl = acl_alloc(M_WAITOK); + + /* + * Retrieve default ACL for parent, if any. + */ + error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred, td); + switch (error) { + case 0: + /* + * Retrieved a default ACL, so merge mode and ACL if + * necessary. + */ + if (acl->acl_cnt != 0) { + /* + * Two possible ways for default ACL to not + * be present. First, the EA can be + * undefined, or second, the default ACL can + * be blank. If it's blank, fall through to + * the it's not defined case. + */ + mode = acl_posix1e_newfilemode(mode, acl); + ip->i_mode = mode; + DIP_SET(ip, i_mode, mode); + ufs_sync_acl_from_inode(ip, acl); + break; + } + /* FALLTHROUGH */ + + case EOPNOTSUPP: + /* + * Just use the mode as-is. + */ + ip->i_mode = mode; + DIP_SET(ip, i_mode, mode); + error = 0; + goto out; + + default: + goto out; + } + + /* + * XXX: If we abort now, will Soft Updates notify the extattr + * code that the EAs for the file need to be released? + */ + error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cred, td); + switch (error) { + case 0: + break; + + case EOPNOTSUPP: + /* + * XXX: This should not happen, as EOPNOTSUPP above was + * supposed to free acl. + */ + printf("ufs_makeinode: VOP_GETACL() but no " + "VOP_SETACL()\n"); + /* panic("ufs_makeinode: VOP_GETACL() but no " + "VOP_SETACL()"); */ + break; + + default: + goto out; + } + +out: + acl_free(acl); + + return (error); +} + static int ufs_do_nfs4_acl_inheritance(struct vnode *dvp, struct vnode *tvp, mode_t child_mode, struct ucred *cred, struct thread *td) @@ -1516,9 +1673,6 @@ ufs_mkdir(ap) struct buf *bp; struct dirtemplate dirtemplate, *dtp; struct direct newdir; -#ifdef UFS_ACL - struct acl *acl, *dacl; -#endif int error, dmode; long blkoff; @@ -1607,59 +1761,8 @@ ufs_mkdir(ap) #endif #endif /* !SUIDDIR */ ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; -#ifdef UFS_ACL - acl = dacl = NULL; - if ((dvp->v_mount->mnt_flag & MNT_ACLS) != 0) { - acl = acl_alloc(M_WAITOK); - dacl = acl_alloc(M_WAITOK); - - /* - * Retrieve default ACL from parent, if any. - */ - error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred, - cnp->cn_thread); - switch (error) { - case 0: - /* - * Retrieved a default ACL, so merge mode and ACL if - * necessary. If the ACL is empty, fall through to - * the "not defined or available" case. - */ - if (acl->acl_cnt != 0) { - dmode = acl_posix1e_newfilemode(dmode, acl); - ip->i_mode = dmode; - DIP_SET(ip, i_mode, dmode); - *dacl = *acl; - ufs_sync_acl_from_inode(ip, acl); - break; - } - /* FALLTHROUGH */ - - case EOPNOTSUPP: - /* - * Just use the mode as-is. - */ - ip->i_mode = dmode; - DIP_SET(ip, i_mode, dmode); - acl_free(acl); - acl_free(dacl); - dacl = acl = NULL; - break; - - default: - UFS_VFREE(tvp, ip->i_number, dmode); - vput(tvp); - acl_free(acl); - acl_free(dacl); - return (error); - } - } else { -#endif /* !UFS_ACL */ - ip->i_mode = dmode; - DIP_SET(ip, i_mode, dmode); -#ifdef UFS_ACL - } -#endif + ip->i_mode = dmode; + DIP_SET(ip, i_mode, dmode); tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */ ip->i_effnlink = 2; ip->i_nlink = 2; @@ -1694,43 +1797,12 @@ ufs_mkdir(ap) } #endif #ifdef UFS_ACL - if (acl != NULL) { - /* - * XXX: If we abort now, will Soft Updates notify the extattr - * code that the EAs for the file need to be released? - */ - error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cnp->cn_cred, - cnp->cn_thread); - if (error == 0) - error = VOP_SETACL(tvp, ACL_TYPE_DEFAULT, dacl, - cnp->cn_cred, cnp->cn_thread); - switch (error) { - case 0: - break; - - case EOPNOTSUPP: - /* - * XXX: This should not happen, as EOPNOTSUPP above - * was supposed to free acl. - */ - printf("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()\n"); - /* - panic("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()"); - */ - break; - - default: - acl_free(acl); - acl_free(dacl); - dacl = acl = NULL; + if (dvp->v_mount->mnt_flag & MNT_ACLS) { + error = ufs_do_posix1e_acl_inheritance_dir(dvp, tvp, dmode, + cnp->cn_cred, cnp->cn_thread); + if (error) goto bad; - } - acl_free(acl); - acl_free(dacl); - dacl = acl = NULL; - } - - if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) { + } else if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) { error = ufs_do_nfs4_acl_inheritance(dvp, tvp, dmode, cnp->cn_cred, cnp->cn_thread); if (error) @@ -1797,12 +1869,6 @@ bad: if (error == 0) { *ap->a_vpp = tvp; } else { -#ifdef UFS_ACL - if (acl != NULL) - acl_free(acl); - if (dacl != NULL) - acl_free(dacl); -#endif dp->i_effnlink--; dp->i_nlink--; DIP_SET(dp, i_nlink, dp->i_nlink); @@ -2387,9 +2453,6 @@ ufs_makeinode(mode, dvp, vpp, cnp) struct inode *ip, *pdir; struct direct newdir; struct vnode *tvp; -#ifdef UFS_ACL - struct acl *acl; -#endif int error; pdir = VTOI(dvp); @@ -2469,62 +2532,8 @@ ufs_makeinode(mode, dvp, vpp, cnp) #endif #endif /* !SUIDDIR */ ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; -#ifdef UFS_ACL - acl = NULL; - if ((dvp->v_mount->mnt_flag & MNT_ACLS) != 0) { - acl = acl_alloc(M_WAITOK); - - /* - * Retrieve default ACL for parent, if any. - */ - error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred, - cnp->cn_thread); - switch (error) { - case 0: - /* - * Retrieved a default ACL, so merge mode and ACL if - * necessary. - */ - if (acl->acl_cnt != 0) { - /* - * Two possible ways for default ACL to not - * be present. First, the EA can be - * undefined, or second, the default ACL can - * be blank. If it's blank, fall through to - * the it's not defined case. - */ - mode = acl_posix1e_newfilemode(mode, acl); - ip->i_mode = mode; - DIP_SET(ip, i_mode, mode); - ufs_sync_acl_from_inode(ip, acl); - break; - } - /* FALLTHROUGH */ - - case EOPNOTSUPP: - /* - * Just use the mode as-is. - */ - ip->i_mode = mode; - DIP_SET(ip, i_mode, mode); - acl_free(acl); - acl = NULL; - break; - - default: - UFS_VFREE(tvp, ip->i_number, mode); - vput(tvp); - acl_free(acl); - acl = NULL; - return (error); - } - } else { -#endif - ip->i_mode = mode; - DIP_SET(ip, i_mode, mode); -#ifdef UFS_ACL - } -#endif + ip->i_mode = mode; + DIP_SET(ip, i_mode, mode); tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ ip->i_effnlink = 1; ip->i_nlink = 1; @@ -2557,36 +2566,12 @@ ufs_makeinode(mode, dvp, vpp, cnp) } #endif #ifdef UFS_ACL - if (acl != NULL) { - /* - * XXX: If we abort now, will Soft Updates notify the extattr - * code that the EAs for the file need to be released? - */ - error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cnp->cn_cred, - cnp->cn_thread); - switch (error) { - case 0: - break; - - case EOPNOTSUPP: - /* - * XXX: This should not happen, as EOPNOTSUPP above was - * supposed to free acl. - */ - printf("ufs_makeinode: VOP_GETACL() but no " - "VOP_SETACL()\n"); - /* panic("ufs_makeinode: VOP_GETACL() but no " - "VOP_SETACL()"); */ - break; - - default: - acl_free(acl); + if (dvp->v_mount->mnt_flag & MNT_ACLS) { + error = ufs_do_posix1e_acl_inheritance_file(dvp, tvp, mode, + cnp->cn_cred, cnp->cn_thread); + if (error) goto bad; - } - acl_free(acl); - } - - if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) { + } else if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) { error = ufs_do_nfs4_acl_inheritance(dvp, tvp, mode, cnp->cn_cred, cnp->cn_thread); if (error) From 2b98f8400dac09ef28f1f39097629d4d12f07e6a Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 21:14:49 +0000 Subject: [PATCH 2028/2592] MFC r204076,r204077,r204083,r205279: r204076: Please welcome HAST - Highly Avalable Storage. HAST allows to transparently store data on two physically separated machines connected over the TCP/IP network. HAST works in Primary-Secondary (Master-Backup, Master-Slave) configuration, which means that only one of the cluster nodes can be active at any given time. Only Primary node is able to handle I/O requests to HAST-managed devices. Currently HAST is limited to two cluster nodes in total. HAST operates on block level - it provides disk-like devices in /dev/hast/ directory for use by file systems and/or applications. Working on block level makes it transparent for file systems and applications. There in no difference between using HAST-provided device and raw disk, partition, etc. All of them are just regular GEOM providers in FreeBSD. For more information please consult hastd(8), hastctl(8) and hast.conf(5) manual pages, as well as http://wiki.FreeBSD.org/HAST. Sponsored by: FreeBSD Foundation Sponsored by: OMCnet Internet Service GmbH Sponsored by: TransIP BV r204077: Remove some lines left over by accident. r204083: Add missing KEYWORD line. Pointed out by: dougb r205279 sys: Simplify loops. --- etc/defaults/rc.conf | 3 + etc/rc.d/Makefile | 2 +- etc/rc.d/hastd | 28 + sbin/Makefile | 2 + sbin/ggate/ggatec/ggatec.c | 2 +- sbin/ggate/ggatel/ggatel.c | 2 +- sbin/hastctl/Makefile | 36 + sbin/hastctl/hastctl.8 | 217 ++++ sbin/hastctl/hastctl.c | 526 +++++++++ sbin/hastd/Makefile | 37 + sbin/hastd/activemap.c | 691 +++++++++++ sbin/hastd/activemap.h | 69 ++ sbin/hastd/control.c | 426 +++++++ sbin/hastd/control.h | 44 + sbin/hastd/ebuf.c | 252 ++++ sbin/hastd/ebuf.h | 51 + sbin/hastd/hast.conf.5 | 267 +++++ sbin/hastd/hast.h | 190 ++++ sbin/hastd/hast_proto.c | 401 +++++++ sbin/hastd/hast_proto.h | 48 + sbin/hastd/hastd.8 | 232 ++++ sbin/hastd/hastd.c | 522 +++++++++ sbin/hastd/hastd.h | 48 + sbin/hastd/hooks.c | 148 +++ sbin/hastd/hooks.h | 40 + sbin/hastd/metadata.c | 222 ++++ sbin/hastd/metadata.h | 48 + sbin/hastd/nv.c | 882 ++++++++++++++ sbin/hastd/nv.h | 158 +++ sbin/hastd/parse.y | 507 +++++++++ sbin/hastd/pjdlog.c | 367 ++++++ sbin/hastd/pjdlog.h | 88 ++ sbin/hastd/primary.c | 1769 +++++++++++++++++++++++++++++ sbin/hastd/proto.c | 261 +++++ sbin/hastd/proto.h | 54 + sbin/hastd/proto_common.c | 85 ++ sbin/hastd/proto_impl.h | 75 ++ sbin/hastd/proto_socketpair.c | 272 +++++ sbin/hastd/proto_tcp4.c | 447 ++++++++ sbin/hastd/proto_uds.c | 330 ++++++ sbin/hastd/rangelock.c | 137 +++ sbin/hastd/rangelock.h | 46 + sbin/hastd/secondary.c | 697 ++++++++++++ sbin/hastd/subr.c | 118 ++ sbin/hastd/subr.h | 51 + sbin/hastd/synch.h | 162 +++ sbin/hastd/token.l | 66 ++ share/examples/Makefile | 6 + share/examples/hast/ucarp.sh | 69 ++ share/examples/hast/ucarp_down.sh | 98 ++ share/examples/hast/ucarp_up.sh | 105 ++ share/examples/hast/vip-down.sh | 5 + share/examples/hast/vip-up.sh | 7 + share/man/man5/rc.conf.5 | 21 + sys/geom/gate/g_gate.c | 218 ++-- sys/geom/gate/g_gate.h | 18 +- 56 files changed, 11577 insertions(+), 96 deletions(-) create mode 100644 etc/rc.d/hastd create mode 100644 sbin/hastctl/Makefile create mode 100644 sbin/hastctl/hastctl.8 create mode 100644 sbin/hastctl/hastctl.c create mode 100644 sbin/hastd/Makefile create mode 100644 sbin/hastd/activemap.c create mode 100644 sbin/hastd/activemap.h create mode 100644 sbin/hastd/control.c create mode 100644 sbin/hastd/control.h create mode 100644 sbin/hastd/ebuf.c create mode 100644 sbin/hastd/ebuf.h create mode 100644 sbin/hastd/hast.conf.5 create mode 100644 sbin/hastd/hast.h create mode 100644 sbin/hastd/hast_proto.c create mode 100644 sbin/hastd/hast_proto.h create mode 100644 sbin/hastd/hastd.8 create mode 100644 sbin/hastd/hastd.c create mode 100644 sbin/hastd/hastd.h create mode 100644 sbin/hastd/hooks.c create mode 100644 sbin/hastd/hooks.h create mode 100644 sbin/hastd/metadata.c create mode 100644 sbin/hastd/metadata.h create mode 100644 sbin/hastd/nv.c create mode 100644 sbin/hastd/nv.h create mode 100644 sbin/hastd/parse.y create mode 100644 sbin/hastd/pjdlog.c create mode 100644 sbin/hastd/pjdlog.h create mode 100644 sbin/hastd/primary.c create mode 100644 sbin/hastd/proto.c create mode 100644 sbin/hastd/proto.h create mode 100644 sbin/hastd/proto_common.c create mode 100644 sbin/hastd/proto_impl.h create mode 100644 sbin/hastd/proto_socketpair.c create mode 100644 sbin/hastd/proto_tcp4.c create mode 100644 sbin/hastd/proto_uds.c create mode 100644 sbin/hastd/rangelock.c create mode 100644 sbin/hastd/rangelock.h create mode 100644 sbin/hastd/secondary.c create mode 100644 sbin/hastd/subr.c create mode 100644 sbin/hastd/subr.h create mode 100644 sbin/hastd/synch.h create mode 100644 sbin/hastd/token.l create mode 100755 share/examples/hast/ucarp.sh create mode 100755 share/examples/hast/ucarp_down.sh create mode 100755 share/examples/hast/ucarp_up.sh create mode 100755 share/examples/hast/vip-down.sh create mode 100755 share/examples/hast/vip-up.sh diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index c9bea689974..c0743ccd58c 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -258,6 +258,9 @@ syslogd_flags="-s" # Flags to syslogd (if enabled). inetd_enable="NO" # Run the network daemon dispatcher (YES/NO). inetd_program="/usr/sbin/inetd" # path to inetd, if you want a different one. inetd_flags="-wW -C 60" # Optional flags to inetd +hastd_enable="NO" # Run the HAST daemon (YES/NO). +hastd_program="/sbin/hastd" # path to hastd, if you want a different one. +hastd_flags="" # Optional flags to hastd. # # named. It may be possible to run named in a sandbox, man security for # details. diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 6c12ad0844e..22028a3a380 100755 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -12,7 +12,7 @@ FILES= DAEMON FILESYSTEMS LOGIN NETWORKING SERVERS \ encswap \ fsck ftp-proxy ftpd \ gbde geli geli2 gssd \ - hcsecd \ + hastd hcsecd \ hostapd hostid hostid_save hostname \ inetd initrandom \ ip6addrctl ipfilter ipfs ipfw ipmon \ diff --git a/etc/rc.d/hastd b/etc/rc.d/hastd new file mode 100644 index 00000000000..11006788e68 --- /dev/null +++ b/etc/rc.d/hastd @@ -0,0 +1,28 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: hastd +# REQUIRE: NETWORKING syslogd +# BEFORE: DAEMON +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="hastd" +rcvar=`set_rcvar` +pidfile="/var/run/${name}.pid" +command="/sbin/${name}" +hastctl="/sbin/hastctl" +required_files="/etc/hast.conf" +stop_precmd="hastd_stop_precmd" +required_modules="geom_gate:g_gate" + +hastd_stop_precmd() +{ + ${hastctl} role init all +} + +load_rc_config $name +run_rc_command "$1" diff --git a/sbin/Makefile b/sbin/Makefile index 8ece390460d..72f4bff7782 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -36,6 +36,8 @@ SUBDIR= adjkerntz \ ggate \ growfs \ gvinum \ + hastctl \ + hastd \ ifconfig \ init \ ${_ipf} \ diff --git a/sbin/ggate/ggatec/ggatec.c b/sbin/ggate/ggatec/ggatec.c index e421614dc6a..660bd8ab469 100644 --- a/sbin/ggate/ggatec/ggatec.c +++ b/sbin/ggate/ggatec/ggatec.c @@ -59,7 +59,7 @@ enum { UNSET, CREATE, DESTROY, LIST, RESCUE } action = UNSET; static const char *path = NULL; static const char *host = NULL; -static int unit = -1; +static int unit = G_GATE_UNIT_AUTO; static unsigned flags = 0; static int force = 0; static unsigned queue_size = G_GATE_QUEUE_SIZE; diff --git a/sbin/ggate/ggatel/ggatel.c b/sbin/ggate/ggatel/ggatel.c index 03979c3f9f7..6a3f26e3b89 100644 --- a/sbin/ggate/ggatel/ggatel.c +++ b/sbin/ggate/ggatel/ggatel.c @@ -50,7 +50,7 @@ enum { UNSET, CREATE, DESTROY, LIST, RESCUE } action = UNSET; static const char *path = NULL; -static int unit = -1; +static int unit = G_GATE_UNIT_AUTO; static unsigned flags = 0; static int force = 0; static unsigned queue_size = G_GATE_QUEUE_SIZE; diff --git a/sbin/hastctl/Makefile b/sbin/hastctl/Makefile new file mode 100644 index 00000000000..43c8c201b17 --- /dev/null +++ b/sbin/hastctl/Makefile @@ -0,0 +1,36 @@ +# $FreeBSD$ + +.include + +.PATH: ${.CURDIR}/../hastd + +PROG= hastctl +SRCS= activemap.c +SRCS+= ebuf.c +SRCS+= hast_proto.c hastctl.c +SRCS+= metadata.c +SRCS+= nv.c +SRCS+= parse.y pjdlog.c +SRCS+= proto.c proto_common.c proto_tcp4.c proto_uds.c +SRCS+= token.l +SRCS+= subr.c +SRCS+= y.tab.h +WARNS?= 6 +MAN= hastctl.8 + +CFLAGS+=-I${.CURDIR}/../hastd +CFLAGS+=-DINET +.if ${MK_INET6_SUPPORT} != "no" +CFLAGS+=-DINET6 +.endif +# This is needed to have WARNS > 1. +CFLAGS+=-DYY_NO_UNPUT + +DPADD= ${LIBCRYPTO} ${LIBL} +LDADD= -lcrypto -ll + +YFLAGS+=-v + +CLEANFILES=y.tab.c y.tab.h y.output + +.include diff --git a/sbin/hastctl/hastctl.8 b/sbin/hastctl/hastctl.8 new file mode 100644 index 00000000000..bf03c2eb5a2 --- /dev/null +++ b/sbin/hastctl/hastctl.8 @@ -0,0 +1,217 @@ +.\" Copyright (c) 2010 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Pawel Jakub Dawidek under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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 AUTHORS 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 AUTHORS 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 February 1, 2010 +.Dt HASTCTL 8 +.Os +.Sh NAME +.Nm hastctl +.Nd "Highly Available Storage control utility" +.Sh SYNOPSIS +.Nm +.Cm create +.Op Fl d +.Op Fl c Ar config +.Op Fl e Ar extentsize +.Op Fl k Ar keepdirty +.Op Fl m Ar mediasize +.Ar name ... +.Nm +.Cm role +.Op Fl d +.Op Fl c Ar config +.Aq init | primary | secondary +.Ar all | name ... +.Nm +.Cm status +.Op Fl d +.Op Fl c Ar config +.Op Ar all | name ... +.Nm +.Cm dump +.Op Fl d +.Op Fl c Ar config +.Op Ar all | name ... +.Sh DESCRIPTION +The +.Nm +utility is used to control the behaviour of the +.Xr hastd 8 +daemon. +.Pp +This utility should be used by HA software like +.Nm heartbeat +or +.Nm ucarp +to setup HAST resources role when changing from primary mode to +secondary or vice versa. +Be aware that if a file system like UFS exists on HAST provider and +primary node dies, file system has to be checked for inconsistencies +with the +.Xr fsck 8 +utility after switching secondary node to primary role. +.Pp +The first argument to +.Nm +indicates an action to be performed: +.Bl -tag -width ".Cm create" +.It Cm create +Initialize local provider configured for the given resource. +Additional options include: +.Bl -tag -width ".Fl e Ar extentsize" +.It Fl e Ar extentsize +Size of an extent. +Extent is a block which is used for synchronization. +.Nm +maintains a map of dirty extents and extent is the smallest region that +can be marked as dirty. +If any part of an extent is modified, entire extent will be synchronized +when nodes connect. +If extent size is too small, there will be too much disk activity +related to dirty map updates, which will degrade performance of the +given resource. +If extent size is too large, synchronization, even in case of short +outage, can take a long time increasing the risk of loosing up-to-date +node before synchronization process is completed. +The default extent size is +.Va 2MB . +.It Fl k Ar keepdirty +Maximum number of dirty extents to keep dirty all the time. +Most recently used extents are kept dirty to reduce number of metadata +updates. +The default numer of most recently used extents which will be kept +dirty is +.Va 64 . +.It Fl m Ar mediasize +Size of the smaller provider used as backend storage on both nodes. +This option can be omitted if node providers have the same size on both +sides. +.El +.It Cm role +Change role of the given resource. +The role can be one of: +.Bl -tag -width ".Cm secondary" +.It Cm init +Resource is turned off. +.It Cm primary +Local +.Xr hastd 8 +daemon will act as primary node for the given resource. +System on which resource role is set to primary can use +.Pa /dev/hast/ +GEOM provider. +.It Cm secondary +Local +.Xr hastd 8 +daemon will act as secondary node for the given resource - it will wait +for connection from the primary node and will handle I/O requests +received from it. +GEOM provider +.Pa /dev/hast/ +will not be created on secondary node. +.El +.It Cm status +Present status of the configured resources. +.It Cm dump +Dump metadata stored on local component for the configured resources. +.El +.Pp +In addition, every subcommand can be followed by the following options: +.Bl -tag -width ".Fl c Ar config" +.It Fl c Ar config +Specify alternative location of the configuration file. +The default location is +.Pa /etc/hast.conf . +.It Fl d +Print debugging information. +This option can be specified multiple times to raise the verbosity +level. +.El +.Sh EXIT STATUS +Exit status is 0 on success, or one of the values described in +.Xr sysexits 3 +on failure. +.Sh EXAMPLES +Initialize HAST provider, create file system on it and mount it. +.Bd -literal -offset indent +nodeB# hastctl create shared +nodeB# hastd +nodeB# hastctl role secondary shared + +nodeB# hastctl create shared +nodeA# hastd +nodeA# hastctl role primary shared +nodeA# newfs -U /dev/hast/shared +nodeA# mount -o noatime /dev/hast/shared /shared +nodeA# application_start +.Ed +.Pp +Switch roles for the +.Nm shared +HAST resource. +.Bd -literal -offset indent +nodeA# application_stop +nodeA# umount -f /shared +nodeA# hastctl role secondary shared + +nodeB# hastctl role primary shared +nodeB# fsck -t ufs /dev/hast/shared +nodeB# mount -o noatime /dev/hast/shared /shared +nodeB# application_start +.Ed +.Sh FILES +.Bl -tag -width ".Pa /var/run/hastctl" -compact +.It Pa /etc/hast.conf +Configuration file for +.Nm +and +.Xr hastd 8 . +.It Pa /var/run/hastctl +Control socket used by +.Nm +to communicate with the +.Xr hastd 8 +daemon. +.El +.Sh SEE ALSO +.Xr sysexits 3 , +.Xr geom 4 , +.Xr hast.conf 5 , +.Xr fsck 8 , +.Xr ggatec 8 , +.Xr ggatel 8 , +.Xr hastd 8 , +.Xr mount 8 , +.Xr newfs 8 . +.Sh AUTHORS +The +.Nm +was developed by +.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org +under sponsorship of the FreeBSD Foundation. diff --git a/sbin/hastctl/hastctl.c b/sbin/hastctl/hastctl.c new file mode 100644 index 00000000000..8499528f986 --- /dev/null +++ b/sbin/hastctl/hastctl.c @@ -0,0 +1,526 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "hast.h" +#include "hast_proto.h" +#include "metadata.h" +#include "nv.h" +#include "pjdlog.h" +#include "proto.h" +#include "subr.h" + +/* Path to configuration file. */ +static const char *cfgpath = HAST_CONFIG; +/* Hastd configuration. */ +static struct hastd_config *cfg; +/* Control connection. */ +static struct proto_conn *controlconn; + +enum { + CMD_INVALID, + CMD_CREATE, + CMD_ROLE, + CMD_STATUS, + CMD_DUMP +}; + +static __dead2 void +usage(void) +{ + + fprintf(stderr, + "usage: %s create [-d] [-c config] [-e extentsize] [-k keepdirty]\n" + "\t\t[-m mediasize] name ...\n", + getprogname()); + fprintf(stderr, + " %s role [-d] [-c config] all | name ...\n", + getprogname()); + fprintf(stderr, + " %s status [-d] [-c config] [all | name ...]\n", + getprogname()); + fprintf(stderr, + " %s dump [-d] [-c config] [all | name ...]\n", + getprogname()); + exit(EX_USAGE); +} + +static int +create_one(struct hast_resource *res, intmax_t mediasize, intmax_t extentsize, + intmax_t keepdirty) +{ + unsigned char *buf; + size_t mapsize; + int ec; + + ec = 0; + pjdlog_prefix_set("[%s] ", res->hr_name); + + if (provinfo(res, true) < 0) { + ec = EX_NOINPUT; + goto end; + } + if (mediasize == 0) + mediasize = res->hr_local_mediasize; + else if (mediasize > res->hr_local_mediasize) { + pjdlog_error("Provided mediasize is larger than provider %s size.", + res->hr_localpath); + ec = EX_DATAERR; + goto end; + } + if (!powerof2(res->hr_local_sectorsize)) { + pjdlog_error("Sector size of provider %s is not power of 2 (%u).", + res->hr_localpath, res->hr_local_sectorsize); + ec = EX_DATAERR; + goto end; + } + if (extentsize == 0) + extentsize = HAST_EXTENTSIZE; + if (extentsize < res->hr_local_sectorsize) { + pjdlog_error("Extent size (%jd) is less than sector size (%u).", + (intmax_t)extentsize, res->hr_local_sectorsize); + ec = EX_DATAERR; + goto end; + } + if ((extentsize % res->hr_local_sectorsize) != 0) { + pjdlog_error("Extent size (%jd) is not multiple of sector size (%u).", + (intmax_t)extentsize, res->hr_local_sectorsize); + ec = EX_DATAERR; + goto end; + } + mapsize = activemap_calc_ondisk_size(mediasize - METADATA_SIZE, + extentsize, res->hr_local_sectorsize); + if (keepdirty == 0) + keepdirty = HAST_KEEPDIRTY; + res->hr_datasize = mediasize - METADATA_SIZE - mapsize; + res->hr_extentsize = extentsize; + res->hr_keepdirty = keepdirty; + + res->hr_localoff = METADATA_SIZE + mapsize; + + if (metadata_write(res) < 0) { + ec = EX_IOERR; + goto end; + } + buf = calloc(1, mapsize); + if (buf == NULL) { + pjdlog_error("Unable to allocate %zu bytes of memory for initial bitmap.", + mapsize); + ec = EX_TEMPFAIL; + goto end; + } + if (pwrite(res->hr_localfd, buf, mapsize, METADATA_SIZE) != + (ssize_t)mapsize) { + pjdlog_errno(LOG_ERR, "Unable to store initial bitmap on %s", + res->hr_localpath); + free(buf); + ec = EX_IOERR; + goto end; + } + free(buf); +end: + if (res->hr_localfd >= 0) + close(res->hr_localfd); + pjdlog_prefix_set("%s", ""); + return (ec); +} + +static void +control_create(int argc, char *argv[], intmax_t mediasize, intmax_t extentsize, + intmax_t keepdirty) +{ + struct hast_resource *res; + int ec, ii, ret; + + /* Initialize the given resources. */ + if (argc < 1) + usage(); + ec = 0; + for (ii = 0; ii < argc; ii++) { + TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { + if (strcmp(argv[ii], res->hr_name) == 0) + break; + } + if (res == NULL) { + pjdlog_error("Unknown resource %s.", argv[ii]); + if (ec == 0) + ec = EX_DATAERR; + continue; + } + ret = create_one(res, mediasize, extentsize, keepdirty); + if (ret != 0 && ec == 0) + ec = ret; + } + exit(ec); +} + +static int +dump_one(struct hast_resource *res) +{ + int ret; + + ret = metadata_read(res, false); + if (ret != 0) + return (ret); + + printf("resource: %s\n", res->hr_name); + printf(" datasize: %ju\n", (uintmax_t)res->hr_datasize); + printf(" extentsize: %d\n", res->hr_extentsize); + printf(" keepdirty: %d\n", res->hr_keepdirty); + printf(" localoff: %ju\n", (uintmax_t)res->hr_localoff); + printf(" resuid: %ju\n", (uintmax_t)res->hr_resuid); + printf(" localcnt: %ju\n", (uintmax_t)res->hr_primary_localcnt); + printf(" remotecnt: %ju\n", (uintmax_t)res->hr_primary_remotecnt); + printf(" prevrole: %s\n", role2str(res->hr_previous_role)); + + return (0); +} + +static void +control_dump(int argc, char *argv[]) +{ + struct hast_resource *res; + int ec, ret; + + /* Dump metadata of the given resource(s). */ + + ec = 0; + if (argc == 0 || (argc == 1 && strcmp(argv[0], "all") == 0)) { + TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { + ret = dump_one(res); + if (ret != 0 && ec == 0) + ec = ret; + } + } else { + int ii; + + for (ii = 0; ii < argc; ii++) { + TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { + if (strcmp(argv[ii], res->hr_name) == 0) + break; + } + if (res == NULL) { + pjdlog_error("Unknown resource %s.", argv[ii]); + if (ec == 0) + ec = EX_DATAERR; + continue; + } + ret = dump_one(res); + if (ret != 0 && ec == 0) + ec = ret; + } + } + exit(ec); +} + +static int +control_set_role(struct nv *nv, const char *newrole) +{ + const char *res, *oldrole; + unsigned int ii; + int error, ret; + + ret = 0; + + for (ii = 0; ; ii++) { + res = nv_get_string(nv, "resource%u", ii); + if (res == NULL) + break; + pjdlog_prefix_set("[%s] ", res); + error = nv_get_int16(nv, "error%u", ii); + if (error != 0) { + if (ret == 0) + ret = error; + pjdlog_warning("Received error %d from hastd.", error); + continue; + } + oldrole = nv_get_string(nv, "role%u", ii); + if (strcmp(oldrole, newrole) == 0) + pjdlog_debug(2, "Role unchanged (%s).", oldrole); + else { + pjdlog_debug(1, "Role changed from %s to %s.", oldrole, + newrole); + } + } + pjdlog_prefix_set("%s", ""); + return (ret); +} + +static int +control_status(struct nv *nv) +{ + unsigned int ii; + const char *str; + int error, ret; + + ret = 0; + + for (ii = 0; ; ii++) { + str = nv_get_string(nv, "resource%u", ii); + if (str == NULL) + break; + printf("%s:\n", str); + error = nv_get_int16(nv, "error%u", ii); + if (error != 0) { + if (ret == 0) + ret = error; + printf(" error: %d\n", error); + continue; + } + printf(" role: %s\n", nv_get_string(nv, "role%u", ii)); + printf(" provname: %s\n", + nv_get_string(nv, "provname%u", ii)); + printf(" localpath: %s\n", + nv_get_string(nv, "localpath%u", ii)); + printf(" extentsize: %u\n", + (unsigned int)nv_get_uint32(nv, "extentsize%u", ii)); + printf(" keepdirty: %u\n", + (unsigned int)nv_get_uint32(nv, "keepdirty%u", ii)); + printf(" remoteaddr: %s\n", + nv_get_string(nv, "remoteaddr%u", ii)); + printf(" replication: %s\n", + nv_get_string(nv, "replication%u", ii)); + str = nv_get_string(nv, "status%u", ii); + if (str != NULL) + printf(" status: %s\n", str); + printf(" dirty: %ju bytes\n", + (uintmax_t)nv_get_uint64(nv, "dirty%u", ii)); + } + return (ret); +} + +static int +numfromstr(const char *str, intmax_t *nump) +{ + intmax_t num; + char *suffix; + int rerrno; + + rerrno = errno; + errno = 0; + num = strtoimax(str, &suffix, 0); + if (errno == 0 && *suffix != '\0') + errno = EINVAL; + if (errno != 0) + return (-1); + *nump = num; + errno = rerrno; + return (0); +} + +int +main(int argc, char *argv[]) +{ + struct nv *nv; + intmax_t mediasize, extentsize, keepdirty; + int cmd, debug, error, ii; + const char *optstr; + + debug = 0; + mediasize = extentsize = keepdirty = 0; + + if (argc == 1) + usage(); + + if (strcmp(argv[1], "create") == 0) { + cmd = CMD_CREATE; + optstr = "c:de:k:m:h"; + } else if (strcmp(argv[1], "role") == 0) { + cmd = CMD_ROLE; + optstr = "c:dh"; + } else if (strcmp(argv[1], "status") == 0) { + cmd = CMD_STATUS; + optstr = "c:dh"; + } else if (strcmp(argv[1], "dump") == 0) { + cmd = CMD_DUMP; + optstr = "c:dh"; + } else + usage(); + + argc--; + argv++; + + for (;;) { + int ch; + + ch = getopt(argc, argv, optstr); + if (ch == -1) + break; + switch (ch) { + case 'c': + cfgpath = optarg; + break; + case 'd': + debug++; + break; + case 'e': + if (numfromstr(optarg, &extentsize) < 0) + err(1, "Invalid extentsize"); + break; + case 'k': + if (numfromstr(optarg, &keepdirty) < 0) + err(1, "Invalid keepdirty"); + break; + case 'm': + if (numfromstr(optarg, &mediasize) < 0) + err(1, "Invalid mediasize"); + break; + case 'h': + default: + usage(); + } + } + argc -= optind; + argv += optind; + + switch (cmd) { + case CMD_CREATE: + case CMD_ROLE: + if (argc == 0) + usage(); + break; + } + + pjdlog_debug_set(debug); + + cfg = yy_config_parse(cfgpath); + assert(cfg != NULL); + + switch (cmd) { + case CMD_CREATE: + control_create(argc, argv, mediasize, extentsize, keepdirty); + /* NOTREACHED */ + assert(!"What are we doing here?!"); + break; + case CMD_DUMP: + /* Dump metadata from local component of the given resource. */ + control_dump(argc, argv); + /* NOTREACHED */ + assert(!"What are we doing here?!"); + break; + case CMD_ROLE: + /* Change role for the given resources. */ + if (argc < 2) + usage(); + nv = nv_alloc(); + nv_add_uint8(nv, HASTCTL_CMD_SETROLE, "cmd"); + if (strcmp(argv[0], "init") == 0) + nv_add_uint8(nv, HAST_ROLE_INIT, "role"); + else if (strcmp(argv[0], "primary") == 0) + nv_add_uint8(nv, HAST_ROLE_PRIMARY, "role"); + else if (strcmp(argv[0], "secondary") == 0) + nv_add_uint8(nv, HAST_ROLE_SECONDARY, "role"); + else + usage(); + for (ii = 0; ii < argc - 1; ii++) + nv_add_string(nv, argv[ii + 1], "resource%d", ii); + break; + case CMD_STATUS: + /* Obtain status of the given resources. */ + nv = nv_alloc(); + nv_add_uint8(nv, HASTCTL_CMD_STATUS, "cmd"); + if (argc == 0) + nv_add_string(nv, "all", "resource%d", 0); + else { + for (ii = 0; ii < argc; ii++) + nv_add_string(nv, argv[ii], "resource%d", ii); + } + break; + default: + assert(!"Impossible role!"); + } + + /* Setup control connection... */ + if (proto_client(cfg->hc_controladdr, &controlconn) < 0) { + pjdlog_exit(EX_OSERR, + "Unable to setup control connection to %s", + cfg->hc_controladdr); + } + /* ...and connect to hastd. */ + if (proto_connect(controlconn) < 0) { + pjdlog_exit(EX_OSERR, "Unable to connect to hastd via %s", + cfg->hc_controladdr); + } + /* Send the command to the server... */ + if (hast_proto_send(NULL, controlconn, nv, NULL, 0) < 0) { + pjdlog_exit(EX_UNAVAILABLE, + "Unable to send command to hastd via %s", + cfg->hc_controladdr); + } + nv_free(nv); + /* ...and receive reply. */ + if (hast_proto_recv(NULL, controlconn, &nv, NULL, 0) < 0) { + pjdlog_exit(EX_UNAVAILABLE, + "cannot receive reply from hastd via %s", + cfg->hc_controladdr); + } + + error = nv_get_int16(nv, "error"); + if (error != 0) { + pjdlog_exitx(EX_SOFTWARE, "Error %d received from hastd.", + error); + } + nv_set_error(nv, 0); + + switch (cmd) { + case CMD_ROLE: + error = control_set_role(nv, argv[0]); + break; + case CMD_STATUS: + error = control_status(nv); + break; + default: + assert(!"Impossible role!"); + } + + exit(error); +} diff --git a/sbin/hastd/Makefile b/sbin/hastd/Makefile new file mode 100644 index 00000000000..16a0b8f035b --- /dev/null +++ b/sbin/hastd/Makefile @@ -0,0 +1,37 @@ +# $FreeBSD$ + +.include + +PROG= hastd +SRCS= activemap.c +SRCS+= control.c +SRCS+= ebuf.c +SRCS+= hast_proto.c hastd.c hooks.c +SRCS+= metadata.c +SRCS+= nv.c +SRCS+= secondary.c +SRCS+= parse.y pjdlog.c primary.c +SRCS+= proto.c proto_common.c proto_socketpair.c proto_tcp4.c proto_uds.c +SRCS+= rangelock.c +SRCS+= subr.c +SRCS+= token.l +SRCS+= y.tab.h +WARNS?= 6 +MAN= hastd.8 hast.conf.5 + +CFLAGS+=-I${.CURDIR} +CFLAGS+=-DINET +.if ${MK_INET6_SUPPORT} != "no" +CFLAGS+=-DINET6 +.endif +# This is needed to have WARNS > 1. +CFLAGS+=-DYY_NO_UNPUT + +DPADD= ${LIBCRYPTO} ${LIBGEOM} ${LIBL} ${LIBPTHREAD} ${LIBUTIL} +LDADD= -lcrypto -lgeom -ll -lpthread -lutil + +YFLAGS+=-v + +CLEANFILES=y.tab.c y.tab.h y.output + +.include diff --git a/sbin/hastd/activemap.c b/sbin/hastd/activemap.c new file mode 100644 index 00000000000..10eb6410305 --- /dev/null +++ b/sbin/hastd/activemap.c @@ -0,0 +1,691 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 /* powerof2() */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define ACTIVEMAP_MAGIC 0xac71e4 +struct activemap { + int am_magic; /* Magic value. */ + off_t am_mediasize; /* Media size in bytes. */ + uint32_t am_extentsize; /* Extent size in bytes, + must be power of 2. */ + uint8_t am_extentshift;/* 2 ^ extentbits == extentsize */ + int am_nextents; /* Number of extents. */ + size_t am_mapsize; /* Bitmap size in bytes. */ + uint16_t *am_memtab; /* An array that holds number of pending + writes per extent. */ + bitstr_t *am_diskmap; /* On-disk bitmap of dirty extents. */ + bitstr_t *am_memmap; /* In-memory bitmap of dirty extents. */ + size_t am_diskmapsize; /* Map size rounded up to sector size. */ + uint64_t am_ndirty; /* Number of dirty regions. */ + bitstr_t *am_syncmap; /* Bitmap of extents to sync. */ + off_t am_syncoff; /* Next synchronization offset. */ + TAILQ_HEAD(skeepdirty, keepdirty) am_keepdirty; /* List of extents that + we keep dirty to reduce bitmap + updates. */ + int am_nkeepdirty; /* Number of am_keepdirty elements. */ + int am_nkeepdirty_limit; /* Maximum number of am_keepdirty + elements. */ +}; + +struct keepdirty { + int kd_extent; + TAILQ_ENTRY(keepdirty) kd_next; +}; + +/* + * Helper function taken from sys/systm.h to calculate extentshift. + */ +static uint32_t +bitcount32(uint32_t x) +{ + + x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1); + x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x = (x + (x >> 8)); + x = (x + (x >> 16)) & 0x000000ff; + return (x); +} + +static __inline int +off2ext(const struct activemap *amp, off_t offset) +{ + int extent; + + assert(offset >= 0 && offset < amp->am_mediasize); + extent = (offset >> amp->am_extentshift); + assert(extent >= 0 && extent < amp->am_nextents); + return (extent); +} + +static __inline off_t +ext2off(const struct activemap *amp, int extent) +{ + off_t offset; + + assert(extent >= 0 && extent < amp->am_nextents); + offset = ((off_t)extent << amp->am_extentshift); + assert(offset >= 0 && offset < amp->am_mediasize); + return (offset); +} + +/* + * Function calculates number of requests needed to synchronize the given + * extent. + */ +static __inline int +ext2reqs(const struct activemap *amp, int ext) +{ + off_t left; + + if (ext < amp->am_nextents - 1) + return (((amp->am_extentsize - 1) / MAXPHYS) + 1); + + assert(ext == amp->am_nextents - 1); + left = amp->am_mediasize % amp->am_extentsize; + if (left == 0) + left = amp->am_extentsize; + return (((left - 1) / MAXPHYS) + 1); +} + +/* + * Initialize activemap structure and allocate memory for internal needs. + * Function returns 0 on success and -1 if any of the allocations failed. + */ +int +activemap_init(struct activemap **ampp, uint64_t mediasize, uint32_t extentsize, + uint32_t sectorsize, uint32_t keepdirty) +{ + struct activemap *amp; + + assert(ampp != NULL); + assert(mediasize > 0); + assert(extentsize > 0); + assert(powerof2(extentsize)); + assert(sectorsize > 0); + assert(powerof2(sectorsize)); + assert(keepdirty > 0); + + amp = malloc(sizeof(*amp)); + if (amp == NULL) + return (-1); + + amp->am_mediasize = mediasize; + amp->am_nkeepdirty_limit = keepdirty; + amp->am_extentsize = extentsize; + amp->am_extentshift = bitcount32(extentsize - 1); + amp->am_nextents = ((mediasize - 1) / extentsize) + 1; + amp->am_mapsize = sizeof(bitstr_t) * bitstr_size(amp->am_nextents); + amp->am_diskmapsize = roundup2(amp->am_mapsize, sectorsize); + amp->am_ndirty = 0; + amp->am_syncoff = -2; + TAILQ_INIT(&->am_keepdirty); + amp->am_nkeepdirty = 0; + + amp->am_memtab = calloc(amp->am_nextents, sizeof(amp->am_memtab[0])); + amp->am_diskmap = calloc(1, amp->am_diskmapsize); + amp->am_memmap = bit_alloc(amp->am_nextents); + amp->am_syncmap = bit_alloc(amp->am_nextents); + + /* + * Check to see if any of the allocations above failed. + */ + if (amp->am_memtab == NULL || amp->am_diskmap == NULL || + amp->am_memmap == NULL || amp->am_syncmap == NULL) { + if (amp->am_memtab != NULL) + free(amp->am_memtab); + if (amp->am_diskmap != NULL) + free(amp->am_diskmap); + if (amp->am_memmap != NULL) + free(amp->am_memmap); + if (amp->am_syncmap != NULL) + free(amp->am_syncmap); + amp->am_magic = 0; + free(amp); + errno = ENOMEM; + return (-1); + } + + amp->am_magic = ACTIVEMAP_MAGIC; + *ampp = amp; + + return (0); +} + +static struct keepdirty * +keepdirty_find(struct activemap *amp, int extent) +{ + struct keepdirty *kd; + + TAILQ_FOREACH(kd, &->am_keepdirty, kd_next) { + if (kd->kd_extent == extent) + break; + } + return (kd); +} + +static void +keepdirty_add(struct activemap *amp, int extent) +{ + struct keepdirty *kd; + + kd = keepdirty_find(amp, extent); + if (kd != NULL) { + /* + * Only move element at the begining. + */ + TAILQ_REMOVE(&->am_keepdirty, kd, kd_next); + TAILQ_INSERT_HEAD(&->am_keepdirty, kd, kd_next); + return; + } + /* + * Add new element, but first remove the most unused one if + * we have too many. + */ + if (amp->am_nkeepdirty >= amp->am_nkeepdirty_limit) { + kd = TAILQ_LAST(&->am_keepdirty, skeepdirty); + assert(kd != NULL); + TAILQ_REMOVE(&->am_keepdirty, kd, kd_next); + amp->am_nkeepdirty--; + assert(amp->am_nkeepdirty > 0); + } + if (kd == NULL) + kd = malloc(sizeof(*kd)); + /* We can ignore allocation failure. */ + if (kd != NULL) { + kd->kd_extent = extent; + amp->am_nkeepdirty++; + TAILQ_INSERT_HEAD(&->am_keepdirty, kd, kd_next); + } +} + +static void +keepdirty_fill(struct activemap *amp) +{ + struct keepdirty *kd; + + TAILQ_FOREACH(kd, &->am_keepdirty, kd_next) + bit_set(amp->am_diskmap, kd->kd_extent); +} + +static void +keepdirty_free(struct activemap *amp) +{ + struct keepdirty *kd; + + while ((kd = TAILQ_FIRST(&->am_keepdirty)) != NULL) { + TAILQ_REMOVE(&->am_keepdirty, kd, kd_next); + amp->am_nkeepdirty--; + free(kd); + } + assert(amp->am_nkeepdirty == 0); +} + +/* + * Function frees resources allocated by activemap_init() function. + */ +void +activemap_free(struct activemap *amp) +{ + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + + amp->am_magic = 0; + + keepdirty_free(amp); + free(amp->am_memtab); + free(amp->am_diskmap); + free(amp->am_memmap); + free(amp->am_syncmap); +} + +/* + * Function should be called before we handle write requests. It updates + * internal structures and returns true if on-disk metadata should be updated. + */ +bool +activemap_write_start(struct activemap *amp, off_t offset, off_t length) +{ + bool modified; + off_t end; + int ext; + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + assert(length > 0); + + modified = false; + end = offset + length - 1; + + for (ext = off2ext(amp, offset); ext <= off2ext(amp, end); ext++) { + /* + * If the number of pending writes is increased from 0, + * we have to mark the extent as dirty also in on-disk bitmap. + * By returning true we inform the caller that on-disk bitmap + * was modified and has to be flushed to disk. + */ + if (amp->am_memtab[ext]++ == 0) { + assert(!bit_test(amp->am_memmap, ext)); + bit_set(amp->am_memmap, ext); + amp->am_ndirty++; + modified = true; + } + keepdirty_add(amp, ext); + } + + return (modified); +} + +/* + * Function should be called after receiving write confirmation. It updates + * internal structures and returns true if on-disk metadata should be updated. + */ +bool +activemap_write_complete(struct activemap *amp, off_t offset, off_t length) +{ + bool modified; + off_t end; + int ext; + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + assert(length > 0); + + modified = false; + end = offset + length - 1; + + for (ext = off2ext(amp, offset); ext <= off2ext(amp, end); ext++) { + /* + * If the number of pending writes goes down to 0, we have to + * mark the extent as clean also in on-disk bitmap. + * By returning true we inform the caller that on-disk bitmap + * was modified and has to be flushed to disk. + */ + assert(amp->am_memtab[ext] > 0); + assert(bit_test(amp->am_memmap, ext)); + if (--amp->am_memtab[ext] == 0) { + bit_clear(amp->am_memmap, ext); + amp->am_ndirty--; + modified = true; + } + } + + return (modified); +} + +/* + * Function should be called after finishing synchronization of one extent. + * It returns true if on-disk metadata should be updated. + */ +bool +activemap_extent_complete(struct activemap *amp, int extent) +{ + bool modified; + int reqs; + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + assert(extent >= 0 && extent < amp->am_nextents); + + modified = false; + + reqs = ext2reqs(amp, extent); + assert(amp->am_memtab[extent] >= reqs); + amp->am_memtab[extent] -= reqs; + assert(bit_test(amp->am_memmap, extent)); + if (amp->am_memtab[extent] == 0) { + bit_clear(amp->am_memmap, extent); + amp->am_ndirty--; + modified = true; + } + + return (modified); +} + +/* + * Function returns number of dirty regions. + */ +uint64_t +activemap_ndirty(const struct activemap *amp) +{ + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + + return (amp->am_ndirty); +} + +/* + * Function compare on-disk bitmap and in-memory bitmap and returns true if + * they differ and should be flushed to the disk. + */ +bool +activemap_differ(const struct activemap *amp) +{ + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + + return (memcmp(amp->am_diskmap, amp->am_memmap, + amp->am_mapsize) != 0); +} + +/* + * Function returns number of bytes used by bitmap. + */ +size_t +activemap_size(const struct activemap *amp) +{ + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + + return (amp->am_mapsize); +} + +/* + * Function returns number of bytes needed for storing on-disk bitmap. + * This is the same as activemap_size(), but rounded up to sector size. + */ +size_t +activemap_ondisk_size(const struct activemap *amp) +{ + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + + return (amp->am_diskmapsize); +} + +/* + * Function copies the given buffer read from disk to the internal bitmap. + */ +void +activemap_copyin(struct activemap *amp, const unsigned char *buf, size_t size) +{ + int ext; + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + assert(size >= amp->am_mapsize); + + memcpy(amp->am_diskmap, buf, amp->am_mapsize); + memcpy(amp->am_memmap, buf, amp->am_mapsize); + memcpy(amp->am_syncmap, buf, amp->am_mapsize); + + bit_ffs(amp->am_memmap, amp->am_nextents, &ext); + if (ext == -1) { + /* There are no dirty extents, so we can leave now. */ + return; + } + /* + * Set synchronization offset to the first dirty extent. + */ + activemap_sync_rewind(amp); + /* + * We have dirty extents and we want them to stay that way until + * we synchronize, so we set number of pending writes to number + * of requests needed to synchronize one extent. + */ + amp->am_ndirty = 0; + for (; ext < amp->am_nextents; ext++) { + if (bit_test(amp->am_memmap, ext)) { + amp->am_memtab[ext] = ext2reqs(amp, ext); + amp->am_ndirty++; + } + } +} + +/* + * Function merges the given bitmap with existng one. + */ +void +activemap_merge(struct activemap *amp, const unsigned char *buf, size_t size) +{ + bitstr_t *remmap = __DECONST(bitstr_t *, buf); + int ext; + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + assert(size >= amp->am_mapsize); + + bit_ffs(remmap, amp->am_nextents, &ext); + if (ext == -1) { + /* There are no dirty extents, so we can leave now. */ + return; + } + /* + * We have dirty extents and we want them to stay that way until + * we synchronize, so we set number of pending writes to number + * of requests needed to synchronize one extent. + */ + for (; ext < amp->am_nextents; ext++) { + /* Local extent already dirty. */ + if (bit_test(amp->am_syncmap, ext)) + continue; + /* Remote extent isn't dirty. */ + if (!bit_test(remmap, ext)) + continue; + bit_set(amp->am_syncmap, ext); + bit_set(amp->am_memmap, ext); + bit_set(amp->am_diskmap, ext); + if (amp->am_memtab[ext] == 0) + amp->am_ndirty++; + amp->am_memtab[ext] = ext2reqs(amp, ext); + } + /* + * Set synchronization offset to the first dirty extent. + */ + activemap_sync_rewind(amp); +} + +/* + * Function returns pointer to internal bitmap that should be written to disk. + */ +const unsigned char * +activemap_bitmap(struct activemap *amp, size_t *sizep) +{ + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + + if (sizep != NULL) + *sizep = amp->am_diskmapsize; + memcpy(amp->am_diskmap, amp->am_memmap, amp->am_mapsize); + keepdirty_fill(amp); + return ((const unsigned char *)amp->am_diskmap); +} + +/* + * Function calculates size needed to store bitmap on disk. + */ +size_t +activemap_calc_ondisk_size(uint64_t mediasize, uint32_t extentsize, + uint32_t sectorsize) +{ + uint64_t nextents, mapsize; + + assert(mediasize > 0); + assert(extentsize > 0); + assert(powerof2(extentsize)); + assert(sectorsize > 0); + assert(powerof2(sectorsize)); + + nextents = ((mediasize - 1) / extentsize) + 1; + mapsize = sizeof(bitstr_t) * bitstr_size(nextents); + return (roundup2(mapsize, sectorsize)); +} + +/* + * Set synchronization offset to the first dirty extent. + */ +void +activemap_sync_rewind(struct activemap *amp) +{ + int ext; + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + + bit_ffs(amp->am_syncmap, amp->am_nextents, &ext); + if (ext == -1) { + /* There are no extents to synchronize. */ + amp->am_syncoff = -2; + return; + } + /* + * Mark that we want to start synchronization from the begining. + */ + amp->am_syncoff = -1; +} + +/* + * Return next offset of where we should synchronize. + */ +off_t +activemap_sync_offset(struct activemap *amp, off_t *lengthp, int *syncextp) +{ + off_t syncoff, left; + int ext; + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + assert(lengthp != NULL); + assert(syncextp != NULL); + + *syncextp = -1; + + if (amp->am_syncoff == -2) + return (-1); + + if (amp->am_syncoff >= 0 && + (amp->am_syncoff + MAXPHYS >= amp->am_mediasize || + off2ext(amp, amp->am_syncoff) != + off2ext(amp, amp->am_syncoff + MAXPHYS))) { + /* + * We are about to change extent, so mark previous one as clean. + */ + ext = off2ext(amp, amp->am_syncoff); + bit_clear(amp->am_syncmap, ext); + *syncextp = ext; + amp->am_syncoff = -1; + } + + if (amp->am_syncoff == -1) { + /* + * Let's find first extent to synchronize. + */ + bit_ffs(amp->am_syncmap, amp->am_nextents, &ext); + if (ext == -1) { + amp->am_syncoff = -2; + return (-1); + } + amp->am_syncoff = ext2off(amp, ext); + } else { + /* + * We don't change extent, so just increase offset. + */ + amp->am_syncoff += MAXPHYS; + if (amp->am_syncoff >= amp->am_mediasize) { + amp->am_syncoff = -2; + return (-1); + } + } + + syncoff = amp->am_syncoff; + left = ext2off(amp, off2ext(amp, syncoff)) + + amp->am_extentsize - syncoff; + if (syncoff + left > amp->am_mediasize) + left = amp->am_mediasize - syncoff; + if (left > MAXPHYS) + left = MAXPHYS; + + assert(left >= 0 && left <= MAXPHYS); + assert(syncoff >= 0 && syncoff < amp->am_mediasize); + assert(syncoff + left >= 0 && syncoff + left <= amp->am_mediasize); + + *lengthp = left; + return (syncoff); +} + +/* + * Mark extent(s) containing the given region for synchronization. + * Most likely one of the components is unavailable. + */ +bool +activemap_need_sync(struct activemap *amp, off_t offset, off_t length) +{ + bool modified; + off_t end; + int ext; + + assert(amp->am_magic == ACTIVEMAP_MAGIC); + + modified = false; + end = offset + length - 1; + + for (ext = off2ext(amp, offset); ext <= off2ext(amp, end); ext++) { + if (bit_test(amp->am_syncmap, ext)) { + /* Already marked for synchronization. */ + assert(bit_test(amp->am_memmap, ext)); + continue; + } + bit_set(amp->am_syncmap, ext); + if (!bit_test(amp->am_memmap, ext)) { + bit_set(amp->am_memmap, ext); + amp->am_ndirty++; + } + amp->am_memtab[ext] += ext2reqs(amp, ext); + modified = true; + } + + return (modified); +} + +void +activemap_dump(const struct activemap *amp) +{ + int bit; + + printf("M: "); + for (bit = 0; bit < amp->am_nextents; bit++) + printf("%d", bit_test(amp->am_memmap, bit) ? 1 : 0); + printf("\n"); + printf("D: "); + for (bit = 0; bit < amp->am_nextents; bit++) + printf("%d", bit_test(amp->am_diskmap, bit) ? 1 : 0); + printf("\n"); + printf("S: "); + for (bit = 0; bit < amp->am_nextents; bit++) + printf("%d", bit_test(amp->am_syncmap, bit) ? 1 : 0); + printf("\n"); +} diff --git a/sbin/hastd/activemap.h b/sbin/hastd/activemap.h new file mode 100644 index 00000000000..42f0221dc49 --- /dev/null +++ b/sbin/hastd/activemap.h @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _ACTIVEMAP_H_ +#define _ACTIVEMAP_H_ + +#include +#include + +struct activemap; + +int activemap_init(struct activemap **ampp, uint64_t mediasize, + uint32_t extentsize, uint32_t sectorsize, uint32_t keepdirty); +void activemap_free(struct activemap *amp); + +bool activemap_write_start(struct activemap *amp, off_t offset, off_t length); +bool activemap_write_complete(struct activemap *amp, off_t offset, + off_t length); +bool activemap_extent_complete(struct activemap *amp, int extent); +uint64_t activemap_ndirty(const struct activemap *amp); + +bool activemap_differ(const struct activemap *amp); +size_t activemap_size(const struct activemap *amp); +size_t activemap_ondisk_size(const struct activemap *amp); +void activemap_copyin(struct activemap *amp, const unsigned char *buf, + size_t size); +void activemap_merge(struct activemap *amp, const unsigned char *buf, + size_t size); +const unsigned char *activemap_bitmap(struct activemap *amp, size_t *sizep); + +size_t activemap_calc_ondisk_size(uint64_t mediasize, uint32_t extentsize, + uint32_t sectorsize); + +void activemap_sync_rewind(struct activemap *amp); +off_t activemap_sync_offset(struct activemap *amp, off_t *lengthp, + int *syncextp); +bool activemap_need_sync(struct activemap *amp, off_t offset, off_t length); + +void activemap_dump(const struct activemap *amp); + +#endif /* !_ACTIVEMAP_H_ */ diff --git a/sbin/hastd/control.c b/sbin/hastd/control.c new file mode 100644 index 00000000000..0ad39b40d00 --- /dev/null +++ b/sbin/hastd/control.c @@ -0,0 +1,426 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "hast.h" +#include "hastd.h" +#include "hast_proto.h" +#include "nv.h" +#include "pjdlog.h" +#include "proto.h" +#include "subr.h" + +#include "control.h" + +static void +control_set_role(struct hastd_config *cfg, struct nv *nvout, uint8_t role, + struct hast_resource *res, const char *name, unsigned int no) +{ + + assert(cfg != NULL); + assert(nvout != NULL); + assert(name != NULL); + + /* Name is always needed. */ + nv_add_string(nvout, name, "resource%u", no); + + if (res == NULL) { + TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { + if (strcmp(res->hr_name, name) == 0) + break; + } + if (res == NULL) { + nv_add_int16(nvout, EHAST_NOENTRY, "error%u", no); + return; + } + } + assert(res != NULL); + + /* Send previous role back. */ + nv_add_string(nvout, role2str(res->hr_role), "role%u", no); + + /* Nothing changed, return here. */ + if (role == res->hr_role) + return; + + pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role)); + pjdlog_info("Role changed to %s.", role2str(role)); + + /* Change role to the new one. */ + res->hr_role = role; + pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role)); + + /* + * If previous role was primary or secondary we have to kill process + * doing that work. + */ + if (res->hr_workerpid != 0) { + if (kill(res->hr_workerpid, SIGTERM) < 0) { + pjdlog_errno(LOG_WARNING, + "Unable to kill worker process %u", + (unsigned int)res->hr_workerpid); + } else if (waitpid(res->hr_workerpid, NULL, 0) != + res->hr_workerpid) { + pjdlog_errno(LOG_WARNING, + "Error while waiting for worker process %u", + (unsigned int)res->hr_workerpid); + } else { + pjdlog_debug(1, "Worker process %u stopped.", + (unsigned int)res->hr_workerpid); + } + res->hr_workerpid = 0; + } + + /* Start worker process if we are changing to primary. */ + if (role == HAST_ROLE_PRIMARY) + hastd_primary(res); + pjdlog_prefix_set("%s", ""); +} + +static void +control_status_worker(struct hast_resource *res, struct nv *nvout, + unsigned int no) +{ + struct nv *cnvin, *cnvout; + const char *str; + int error; + + cnvin = cnvout = NULL; + error = 0; + + /* + * Prepare and send command to worker process. + */ + cnvout = nv_alloc(); + nv_add_uint8(cnvout, HASTCTL_STATUS, "cmd"); + error = nv_error(cnvout); + if (error != 0) { + /* LOG */ + goto end; + } + if (hast_proto_send(res, res->hr_ctrl, cnvout, NULL, 0) < 0) { + error = errno; + /* LOG */ + goto end; + } + + /* + * Receive response. + */ + if (hast_proto_recv_hdr(res->hr_ctrl, &cnvin) < 0) { + error = errno; + /* LOG */ + goto end; + } + + error = nv_get_int64(cnvin, "error"); + if (error != 0) + goto end; + + if ((str = nv_get_string(cnvin, "status")) == NULL) { + error = ENOENT; + /* LOG */ + goto end; + } + nv_add_string(nvout, str, "status%u", no); + nv_add_uint64(nvout, nv_get_uint64(cnvin, "dirty"), "dirty%u", no); + nv_add_uint32(nvout, nv_get_uint32(cnvin, "extentsize"), + "extentsize%u", no); + nv_add_uint32(nvout, nv_get_uint32(cnvin, "keepdirty"), + "keepdirty%u", no); +end: + if (cnvin != NULL) + nv_free(cnvin); + if (cnvout != NULL) + nv_free(cnvout); + if (error != 0) + nv_add_int16(nvout, error, "error"); +} + +static void +control_status(struct hastd_config *cfg, struct nv *nvout, + struct hast_resource *res, const char *name, unsigned int no) +{ + + assert(cfg != NULL); + assert(nvout != NULL); + assert(name != NULL); + + /* Name is always needed. */ + nv_add_string(nvout, name, "resource%u", no); + + if (res == NULL) { + TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { + if (strcmp(res->hr_name, name) == 0) + break; + } + if (res == NULL) { + nv_add_int16(nvout, EHAST_NOENTRY, "error%u", no); + return; + } + } + assert(res != NULL); + nv_add_string(nvout, res->hr_provname, "provname%u", no); + nv_add_string(nvout, res->hr_localpath, "localpath%u", no); + nv_add_string(nvout, res->hr_remoteaddr, "remoteaddr%u", no); + switch (res->hr_replication) { + case HAST_REPLICATION_FULLSYNC: + nv_add_string(nvout, "fullsync", "replication%u", no); + break; + case HAST_REPLICATION_MEMSYNC: + nv_add_string(nvout, "memsync", "replication%u", no); + break; + case HAST_REPLICATION_ASYNC: + nv_add_string(nvout, "async", "replication%u", no); + break; + default: + nv_add_string(nvout, "unknown", "replication%u", no); + break; + } + nv_add_string(nvout, role2str(res->hr_role), "role%u", no); + + switch (res->hr_role) { + case HAST_ROLE_PRIMARY: + assert(res->hr_workerpid != 0); + /* FALLTHROUGH */ + case HAST_ROLE_SECONDARY: + if (res->hr_workerpid != 0) + break; + /* FALLTHROUGH */ + default: + return; + } + + /* + * If we are here, it means that we have a worker process, which we + * want to ask some questions. + */ + control_status_worker(res, nvout, no); +} + +void +control_handle(struct hastd_config *cfg) +{ + struct proto_conn *conn; + struct nv *nvin, *nvout; + unsigned int ii; + const char *str; + uint8_t cmd, role; + int error; + + if (proto_accept(cfg->hc_controlconn, &conn) < 0) { + pjdlog_errno(LOG_ERR, "Unable to accept control connection"); + return; + } + + nvin = nvout = NULL; + role = HAST_ROLE_UNDEF; + + if (hast_proto_recv_hdr(conn, &nvin) < 0) { + pjdlog_errno(LOG_ERR, "Unable to receive control header"); + nvin = NULL; + goto close; + } + + /* Obtain command code. 0 means that nv_get_uint8() failed. */ + cmd = nv_get_uint8(nvin, "cmd"); + if (cmd == 0) { + pjdlog_error("Control header is missing 'cmd' field."); + error = EHAST_INVALID; + goto close; + } + + /* Allocate outgoing nv structure. */ + nvout = nv_alloc(); + if (nvout == NULL) { + pjdlog_error("Unable to allocate header for control response."); + error = EHAST_NOMEMORY; + goto close; + } + + error = 0; + + str = nv_get_string(nvin, "resource0"); + if (str == NULL) { + pjdlog_error("Control header is missing 'resource0' field."); + error = EHAST_INVALID; + goto fail; + } + if (cmd == HASTCTL_SET_ROLE) { + role = nv_get_uint8(nvin, "role"); + switch (role) { + case HAST_ROLE_INIT: /* Is that valid to set, hmm? */ + case HAST_ROLE_PRIMARY: + case HAST_ROLE_SECONDARY: + break; + default: + pjdlog_error("Invalid role received (%hhu).", role); + error = EHAST_INVALID; + goto fail; + } + } + if (strcmp(str, "all") == 0) { + struct hast_resource *res; + + /* All configured resources. */ + + ii = 0; + TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { + switch (cmd) { + case HASTCTL_SET_ROLE: + control_set_role(cfg, nvout, role, res, + res->hr_name, ii++); + break; + case HASTCTL_STATUS: + control_status(cfg, nvout, res, res->hr_name, + ii++); + break; + default: + pjdlog_error("Invalid command received (%hhu).", + cmd); + error = EHAST_UNIMPLEMENTED; + goto fail; + } + } + } else { + /* Only selected resources. */ + + for (ii = 0; ; ii++) { + str = nv_get_string(nvin, "resource%u", ii); + if (str == NULL) + break; + switch (cmd) { + case HASTCTL_SET_ROLE: + control_set_role(cfg, nvout, role, NULL, str, + ii); + break; + case HASTCTL_STATUS: + control_status(cfg, nvout, NULL, str, ii); + break; + default: + pjdlog_error("Invalid command received (%hhu).", + cmd); + error = EHAST_UNIMPLEMENTED; + goto fail; + } + } + } + if (nv_error(nvout) != 0) + goto close; +fail: + if (error != 0) + nv_add_int16(nvout, error, "error"); + + if (hast_proto_send(NULL, conn, nvout, NULL, 0) < 0) + pjdlog_errno(LOG_ERR, "Unable to send control response"); +close: + if (nvin != NULL) + nv_free(nvin); + if (nvout != NULL) + nv_free(nvout); + proto_close(conn); +} + +/* + * Thread handles control requests from the parent. + */ +void * +ctrl_thread(void *arg) +{ + struct hast_resource *res = arg; + struct nv *nvin, *nvout; + uint8_t cmd; + + for (;;) { + if (hast_proto_recv_hdr(res->hr_ctrl, &nvin) < 0) { + if (sigexit_received) + pthread_exit(NULL); + pjdlog_errno(LOG_ERR, + "Unable to receive control message"); + continue; + } + cmd = nv_get_uint8(nvin, "cmd"); + if (cmd == 0) { + pjdlog_error("Control message is missing 'cmd' field."); + nv_free(nvin); + continue; + } + nv_free(nvin); + nvout = nv_alloc(); + switch (cmd) { + case HASTCTL_STATUS: + if (res->hr_remotein != NULL && + res->hr_remoteout != NULL) { + nv_add_string(nvout, "complete", "status"); + } else { + nv_add_string(nvout, "degraded", "status"); + } + nv_add_uint32(nvout, (uint32_t)res->hr_extentsize, + "extentsize"); + if (res->hr_role == HAST_ROLE_PRIMARY) { + nv_add_uint32(nvout, + (uint32_t)res->hr_keepdirty, "keepdirty"); + nv_add_uint64(nvout, + (uint64_t)(activemap_ndirty(res->hr_amp) * + res->hr_extentsize), "dirty"); + } else { + nv_add_uint32(nvout, (uint32_t)0, "keepdirty"); + nv_add_uint64(nvout, (uint64_t)0, "dirty"); + } + break; + default: + nv_add_int16(nvout, EINVAL, "error"); + break; + } + if (nv_error(nvout) != 0) { + pjdlog_error("Unable to create answer on control message."); + nv_free(nvout); + continue; + } + if (hast_proto_send(NULL, res->hr_ctrl, nvout, NULL, 0) < 0) { + pjdlog_errno(LOG_ERR, + "Unable to send reply to control message"); + } + nv_free(nvout); + } + /* NOTREACHED */ + return (NULL); +} diff --git a/sbin/hastd/control.h b/sbin/hastd/control.h new file mode 100644 index 00000000000..15ea290ea55 --- /dev/null +++ b/sbin/hastd/control.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _CONTROL_H_ +#define _CONTROL_H_ + +#define HASTCTL_SET_ROLE 1 +#define HASTCTL_STATUS 2 + +struct hastd_config; + +void control_handle(struct hastd_config *cfg); + +void *ctrl_thread(void *arg); + +#endif /* !_CONTROL_H_ */ diff --git a/sbin/hastd/ebuf.c b/sbin/hastd/ebuf.c new file mode 100644 index 00000000000..47b7530e2ea --- /dev/null +++ b/sbin/hastd/ebuf.c @@ -0,0 +1,252 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "ebuf.h" + +#define EBUF_MAGIC 0xeb0f41c +struct ebuf { + /* Magic to assert the caller uses valid structure. */ + int eb_magic; + /* Address where we did the allocation. */ + unsigned char *eb_start; + /* Allocation end address. */ + unsigned char *eb_end; + /* Start of real data. */ + unsigned char *eb_used; + /* Size of real data. */ + size_t eb_size; +}; + +static int ebuf_head_extent(struct ebuf *eb, size_t size); +static int ebuf_tail_extent(struct ebuf *eb, size_t size); + +struct ebuf * +ebuf_alloc(size_t size) +{ + struct ebuf *eb; + int rerrno; + + eb = malloc(sizeof(*eb)); + if (eb == NULL) + return (NULL); + size += PAGE_SIZE; + eb->eb_start = malloc(size); + if (eb->eb_start == NULL) { + rerrno = errno; + free(eb); + errno = rerrno; + return (NULL); + } + eb->eb_end = eb->eb_start + size; + /* + * We set start address for real data not at the first entry, because + * we want to be able to add data at the front. + */ + eb->eb_used = eb->eb_start + PAGE_SIZE / 4; + eb->eb_size = 0; + eb->eb_magic = EBUF_MAGIC; + + return (eb); +} + +void +ebuf_free(struct ebuf *eb) +{ + + assert(eb != NULL && eb->eb_magic == EBUF_MAGIC); + + eb->eb_magic = 0; + + free(eb->eb_start); + free(eb); +} + +int +ebuf_add_head(struct ebuf *eb, const void *data, size_t size) +{ + + assert(eb != NULL && eb->eb_magic == EBUF_MAGIC); + + if (size > (size_t)(eb->eb_used - eb->eb_start)) { + /* + * We can't add more entries at the front, so we have to extend + * our buffer. + */ + if (ebuf_head_extent(eb, size) < 0) + return (-1); + } + assert(size <= (size_t)(eb->eb_used - eb->eb_start)); + + eb->eb_size += size; + eb->eb_used -= size; + /* + * If data is NULL the caller just wants to reserve place. + */ + if (data != NULL) + bcopy(data, eb->eb_used, size); + + return (0); +} + +int +ebuf_add_tail(struct ebuf *eb, const void *data, size_t size) +{ + + assert(eb != NULL && eb->eb_magic == EBUF_MAGIC); + + if (size > (size_t)(eb->eb_end - (eb->eb_used + eb->eb_size))) { + /* + * We can't add more entries at the back, so we have to extend + * our buffer. + */ + if (ebuf_tail_extent(eb, size) < 0) + return (-1); + } + assert(size <= (size_t)(eb->eb_end - (eb->eb_used + eb->eb_size))); + + /* + * If data is NULL the caller just wants to reserve place. + */ + if (data != NULL) + bcopy(data, eb->eb_used + eb->eb_size, size); + eb->eb_size += size; + + return (0); +} + +void +ebuf_del_head(struct ebuf *eb, size_t size) +{ + + assert(eb != NULL && eb->eb_magic == EBUF_MAGIC); + assert(size <= eb->eb_size); + + eb->eb_used += size; + eb->eb_size -= size; +} + +void +ebuf_del_tail(struct ebuf *eb, size_t size) +{ + + assert(eb != NULL && eb->eb_magic == EBUF_MAGIC); + assert(size <= eb->eb_size); + + eb->eb_size -= size; +} + +/* + * Return pointer to the data and data size. + */ +void * +ebuf_data(struct ebuf *eb, size_t *sizep) +{ + + assert(eb != NULL && eb->eb_magic == EBUF_MAGIC); + + if (sizep != NULL) + *sizep = eb->eb_size; + return (eb->eb_size > 0 ? eb->eb_used : NULL); +} + +/* + * Return data size. + */ +size_t +ebuf_size(struct ebuf *eb) +{ + + assert(eb != NULL && eb->eb_magic == EBUF_MAGIC); + + return (eb->eb_size); +} + +/* + * Function adds size + (PAGE_SIZE / 4) bytes at the front of the buffer.. + */ +static int +ebuf_head_extent(struct ebuf *eb, size_t size) +{ + unsigned char *newstart, *newused; + size_t newsize; + + assert(eb != NULL && eb->eb_magic == EBUF_MAGIC); + + newsize = eb->eb_end - eb->eb_start + (PAGE_SIZE / 4) + size; + + newstart = malloc(newsize); + if (newstart == NULL) + return (-1); + newused = + newstart + (PAGE_SIZE / 4) + size + (eb->eb_used - eb->eb_start); + + bcopy(eb->eb_used, newused, eb->eb_size); + + eb->eb_start = newstart; + eb->eb_used = newused; + eb->eb_end = newstart + newsize; + + return (0); +} + +/* + * Function adds size + ((3 * PAGE_SIZE) / 4) bytes at the back. + */ +static int +ebuf_tail_extent(struct ebuf *eb, size_t size) +{ + unsigned char *newstart; + size_t newsize; + + assert(eb != NULL && eb->eb_magic == EBUF_MAGIC); + + newsize = eb->eb_end - eb->eb_start + size + ((3 * PAGE_SIZE) / 4); + + newstart = realloc(eb->eb_start, newsize); + if (newstart == NULL) + return (-1); + + eb->eb_used = newstart + (eb->eb_used - eb->eb_start); + eb->eb_start = newstart; + eb->eb_end = newstart + newsize; + + return (0); +} diff --git a/sbin/hastd/ebuf.h b/sbin/hastd/ebuf.h new file mode 100644 index 00000000000..06275e7c909 --- /dev/null +++ b/sbin/hastd/ebuf.h @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _EBUF_H_ +#define _EBUF_H_ + +#include /* size_t */ + +struct ebuf; + +struct ebuf *ebuf_alloc(size_t size); +void ebuf_free(struct ebuf *eb); + +int ebuf_add_head(struct ebuf *eb, const void *data, size_t size); +int ebuf_add_tail(struct ebuf *eb, const void *data, size_t size); + +void ebuf_del_head(struct ebuf *eb, size_t size); +void ebuf_del_tail(struct ebuf *eb, size_t size); + +void *ebuf_data(struct ebuf *eb, size_t *sizep); +size_t ebuf_size(struct ebuf *eb); + +#endif /* !_EBUF_H_ */ diff --git a/sbin/hastd/hast.conf.5 b/sbin/hastd/hast.conf.5 new file mode 100644 index 00000000000..5734ee8ef3d --- /dev/null +++ b/sbin/hastd/hast.conf.5 @@ -0,0 +1,267 @@ +.\" Copyright (c) 2010 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Pawel Jakub Dawidek under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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 AUTHORS 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 AUTHORS 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 February 1, 2010 +.Dt HAST.CONF 5 +.Os +.Sh NAME +.Nm hast.conf +.Nd configuration file for the +.Xr hastd 8 +deamon and the +.Xr hastctl 8 +utility. +.Sh DESCRIPTION +The +.Nm +file is used by both +.Xr hastd 8 +daemon +and +.Xr hastctl 8 +control utility. +Configuration file is designed in a way that exactly the same file can be +(and should be) used on both HAST nodes. +Every line starting with # is treated as comment and ignored. +.Sh CONFIGURATION FILE SYNTAX +General syntax of the +.Nm +file is following: +.Bd -literal -offset indent +# Global section +control +listen +replication + +on { + # Node section + control + listen +} + +on { + # Node section + control + listen +} + +resource { + # Resource section + replication + name + local + + on { + # Resource-node section + name + # Required + local + # Required + remote + } + on { + # Resource-node section + name + # Required + local + # Required + remote + } +} +.Ed +.Pp +Most of the various available configuration parameters are optional. +If parameter is not defined in the particular section, it will be +inherited from the parent section. +For example, if the +.Ic listen +parameter is not defined in the node section, it will be inherited from +the global section. +In case the global section does not define the +.Ic listen +parameter at all, the default value will be used. +.Sh CONFIGURATION FILE DESCRIPTION +The +.Aq node +argument can be replaced either by a full hostname as obtained by +.Xr gethostname 3 , +only first part of the hostname, or by node's UUID as found in the +.Va kern.hostuuid +.Xr sysctl 8 +variable. +.Pp +The following statements are available: +.Bl -tag -width ".Ic xxxx" +.It Ic control Aq addr +.Pp +Address for communication with +.Xr hastctl 8 . +Each of the following examples defines the same control address: +.Bd -literal -offset indent +uds:///var/run/hastctl +unix:///var/run/hastctl +/var/run/hastctl +.Ed +.Pp +The default value is +.Pa uds:///var/run/hastctl . +.It Ic listen Aq addr +.Pp +Address to listen on in form of: +.Bd -literal -offset indent +protocol://protocol-specific-address +.Ed +.Pp +Each of the following examples defines the same listen address: +.Bd -literal -offset indent +0.0.0.0 +0.0.0.0:8457 +tcp://0.0.0.0 +tcp://0.0.0.0:8457 +tcp4://0.0.0.0 +tcp4://0.0.0.0:8457 +.Ed +.Pp +The default value is +.Pa tcp4://0.0.0.0:8457 . +.It Ic replication Aq mode +.Pp +Replication mode should be one of the following: +.Bl -tag -width ".Ic xxxx" +.It Ic memsync +.Pp +Report the write operation as completed when local write completes and +when the remote node acknowledges the data receipt, but before it +actually stores the data. +The data on remote node will be stored directly after sending +acknowledgement. +This mode is intended to reduce latency, but still provides a very good +reliability. +The only situation where some small amount of data could be lost is when +the data is stored on primary node and sent to the secondary. +Secondary node then acknowledges data receipt and primary reports +success to an application. +However, it may happen that the seconderay goes down before the received +data is really stored locally. +Before secondary node returns, primary node dies entirely. +When the secondary node comes back to life it becomes the new primary. +Unfortunately some small amount of data which was confirmed to be stored +to the application was lost. +The risk of such a situation is very small, which is the reason for this +mode to be the default. +.It Ic fullsync +.Pp +Mark the write operation as completed when local as well as remote +write completes. +This is the safest and the slowest replication mode. +The +.Ic fullsync +replication mode is currently not implemented. +.It Ic async +.Pp +The write operation is reported as complete right after the local write +completes. +This is the fastest and the most dangerous replication mode. +This mode should be used when replicating to a distant node where +latency is too high for other modes. +The +.Ic async +replication mode is currently not implemented. +.El +.It Ic name Aq name +.Pp +GEOM provider name that will appear as +.Pa /dev/hast/ . +If name is not defined, resource name will be used as provider name. +.It Ic local Aq path +.Pp +Path to the local component which will be used as backend provider for +the resource. +This can be either GEOM provider or regular file. +.It Ic remote Aq addr +.Pp +Address of the remote +.Nm hastd +daemon. +Format is the same as for the +.Ic listen +statement. +When operating as a primary node this address will be used to connect to +the secondary node. +When operating as a secondary node only connections from this address +will be accepted. +.El +.Sh EXAMPLES +The example configuration file can look as follows: +.Bd -literal -offset indent +resource shared { + local /dev/da0 + + on hasta { + remote tcp4://10.0.0.2 + } + on hastb { + remote tcp4://10.0.0.1 + } +} +resource tank { + on hasta { + local /dev/mirror/tanka + remote tcp4://10.0.0.2 + } + on hastb { + local /dev/mirror/tankb + remote tcp4://10.0.0.1 + } +} +.Ed +.Sh FILES +.Bl -tag -width ".Pa /var/run/hastctl" -compact +.It Pa /etc/hast.conf +The default +.Nm +configuration file. +.It Pa /var/run/hastctl +Control socket used by the +.Xr hastctl 8 +control utility to communicate with the +.Xr hastd 8 +daemon. +.El +.Sh SEE ALSO +.Xr gethostname 3 , +.Xr geom 4 , +.Xr hastctl 8 , +.Xr hastd 8 . +.Sh AUTHORS +The +.Nm +was written by +.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org +under sponsorship of the FreeBSD Foundation. diff --git a/sbin/hastd/hast.h b/sbin/hastd/hast.h new file mode 100644 index 00000000000..c5220b53be9 --- /dev/null +++ b/sbin/hastd/hast.h @@ -0,0 +1,190 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _HAST_H_ +#define _HAST_H_ + +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include + +#include "proto.h" + +#define HAST_PROTO_VERSION 0 + +#define EHAST_OK 0 +#define EHAST_NOENTRY 1 +#define EHAST_INVALID 2 +#define EHAST_NOMEMORY 3 +#define EHAST_UNIMPLEMENTED 4 + +#define HASTCTL_CMD_UNKNOWN 0 +#define HASTCTL_CMD_SETROLE 1 +#define HASTCTL_CMD_STATUS 2 + +#define HAST_ROLE_UNDEF 0 +#define HAST_ROLE_INIT 1 +#define HAST_ROLE_PRIMARY 2 +#define HAST_ROLE_SECONDARY 3 + +#define HAST_SYNCSRC_UNDEF 0 +#define HAST_SYNCSRC_PRIMARY 1 +#define HAST_SYNCSRC_SECONDARY 2 + +#define HIO_UNDEF 0 +#define HIO_READ 1 +#define HIO_WRITE 2 +#define HIO_DELETE 3 +#define HIO_FLUSH 4 + +#define HAST_CONFIG "/etc/hast.conf" +#define HAST_CONTROL "/var/run/hastctl" +#define HASTD_PORT 8457 +#define HASTD_LISTEN "tcp4://0.0.0.0:8457" +#define HASTD_PIDFILE "/var/run/hastd.pid" + +/* Default extent size. */ +#define HAST_EXTENTSIZE 2097152 +/* Default maximum number of extents that are kept dirty. */ +#define HAST_KEEPDIRTY 64 + +#define HAST_ADDRSIZE 1024 +#define HAST_TOKEN_SIZE 16 + +struct hastd_config { + /* Address to communicate with hastctl(8). */ + char hc_controladdr[HAST_ADDRSIZE]; + /* Protocol-specific data. */ + struct proto_conn *hc_controlconn; + /* Address to listen on. */ + char hc_listenaddr[HAST_ADDRSIZE]; + /* Protocol-specific data. */ + struct proto_conn *hc_listenconn; + /* List of resources. */ + TAILQ_HEAD(, hast_resource) hc_resources; +}; + +#define HAST_REPLICATION_FULLSYNC 0 +#define HAST_REPLICATION_MEMSYNC 1 +#define HAST_REPLICATION_ASYNC 2 + +/* + * Structure that describes single resource. + */ +struct hast_resource { + /* Resource name. */ + char hr_name[NAME_MAX]; + /* Replication mode (HAST_REPLICATION_*). */ + int hr_replication; + /* Provider name that will appear in /dev/hast/. */ + char hr_provname[NAME_MAX]; + /* Synchronization extent size. */ + int hr_extentsize; + /* Maximum number of extents that are kept dirty. */ + int hr_keepdirty; + + /* Path to local component. */ + char hr_localpath[PATH_MAX]; + /* Descriptor to access local component. */ + int hr_localfd; + /* Offset into local component. */ + off_t hr_localoff; + /* Size of usable space. */ + off_t hr_datasize; + /* Size of entire local provider. */ + off_t hr_local_mediasize; + /* Sector size of local provider. */ + unsigned int hr_local_sectorsize; + + /* Descriptor for /dev/ggctl communication. */ + int hr_ggatefd; + /* Unit number for ggate communication. */ + int hr_ggateunit; + + /* Address of the remote component. */ + char hr_remoteaddr[HAST_ADDRSIZE]; + /* Connection for incoming data. */ + struct proto_conn *hr_remotein; + /* Connection for outgoing data. */ + struct proto_conn *hr_remoteout; + /* Token to verify both in and out connection are coming from + the same node (not necessarily from the same address). */ + unsigned char hr_token[HAST_TOKEN_SIZE]; + + /* Resource unique identifier. */ + uint64_t hr_resuid; + /* Primary's local modification count. */ + uint64_t hr_primary_localcnt; + /* Primary's remote modification count. */ + uint64_t hr_primary_remotecnt; + /* Secondary's local modification count. */ + uint64_t hr_secondary_localcnt; + /* Secondary's remote modification count. */ + uint64_t hr_secondary_remotecnt; + /* Synchronization source. */ + uint8_t hr_syncsrc; + + /* Resource role: HAST_ROLE_{INIT,PRIMARY,SECONDARY}. */ + int hr_role; + /* Previous resource role: HAST_ROLE_{INIT,PRIMARY,SECONDARY}. */ + int hr_previous_role; + /* PID of child worker process. 0 - no child. */ + pid_t hr_workerpid; + /* Control connection between parent and child. */ + struct proto_conn *hr_ctrl; + + /* Activemap structure. */ + struct activemap *hr_amp; + /* Locked used to synchronize access to hr_amp. */ + pthread_mutex_t hr_amp_lock; + + /* Next resource. */ + TAILQ_ENTRY(hast_resource) hr_next; +}; + +struct hastd_config *yy_config_parse(const char *config); +void yy_config_free(struct hastd_config *config); + +void yyerror(const char *); +int yylex(void); +int yyparse(void); + +#endif /* !_HAST_H_ */ diff --git a/sbin/hastd/hast_proto.c b/sbin/hastd/hast_proto.c new file mode 100644 index 00000000000..6e660069ef9 --- /dev/null +++ b/sbin/hastd/hast_proto.c @@ -0,0 +1,401 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "hast_proto.h" + +struct hast_main_header { + /* Protocol version. */ + uint8_t version; + /* Size of nv headers. */ + uint32_t size; +} __packed; + +typedef int hps_send_t(struct hast_resource *, struct nv *nv, void **, size_t *, bool *); +typedef int hps_recv_t(struct hast_resource *, struct nv *nv, void **, size_t *, bool *); + +struct hast_pipe_stage { + const char *hps_name; + hps_send_t *hps_send; + hps_recv_t *hps_recv; +}; + +static int compression_send(struct hast_resource *res, struct nv *nv, + void **datap, size_t *sizep, bool *freedatap); +static int compression_recv(struct hast_resource *res, struct nv *nv, + void **datap, size_t *sizep, bool *freedatap); +static int checksum_send(struct hast_resource *res, struct nv *nv, + void **datap, size_t *sizep, bool *freedatap); +static int checksum_recv(struct hast_resource *res, struct nv *nv, + void **datap, size_t *sizep, bool *freedatap); + +static struct hast_pipe_stage pipeline[] = { + { "compression", compression_send, compression_recv }, + { "checksum", checksum_send, checksum_recv } +}; + +static int +compression_send(struct hast_resource *res, struct nv *nv, void **datap, + size_t *sizep, bool *freedatap) +{ + unsigned char *newbuf; + + res = res; /* TODO */ + + /* + * TODO: For now we emulate compression. + * At 80% probability we succeed to compress data, which means we + * allocate new buffer, copy the data over set *freedatap to true. + */ + + if (arc4random_uniform(100) < 80) { + uint32_t *origsize; + + /* + * Compression succeeded (but we will grow by 4 bytes, not + * shrink for now). + */ + newbuf = malloc(sizeof(uint32_t) + *sizep); + if (newbuf == NULL) + return (-1); + origsize = (void *)newbuf; + *origsize = htole32((uint32_t)*sizep); + nv_add_string(nv, "null", "compression"); + if (nv_error(nv) != 0) { + free(newbuf); + errno = nv_error(nv); + return (-1); + } + bcopy(*datap, newbuf + sizeof(uint32_t), *sizep); + if (*freedatap) + free(*datap); + *freedatap = true; + *datap = newbuf; + *sizep = sizeof(uint32_t) + *sizep; + } else { + /* + * Compression failed, so we leave everything as it was. + * It is not critical for compression to succeed. + */ + } + + return (0); +} + +static int +compression_recv(struct hast_resource *res, struct nv *nv, void **datap, + size_t *sizep, bool *freedatap) +{ + unsigned char *newbuf; + const char *algo; + size_t origsize; + + res = res; /* TODO */ + + /* + * TODO: For now we emulate compression. + */ + + algo = nv_get_string(nv, "compression"); + if (algo == NULL) + return (0); /* No compression. */ + if (strcmp(algo, "null") != 0) { + pjdlog_error("Unknown compression algorithm '%s'.", algo); + return (-1); /* Unknown compression algorithm. */ + } + + origsize = le32toh(*(uint32_t *)*datap); + newbuf = malloc(origsize); + if (newbuf == NULL) + return (-1); + bcopy((unsigned char *)*datap + sizeof(uint32_t), newbuf, origsize); + if (*freedatap) + free(*datap); + *freedatap = true; + *datap = newbuf; + *sizep = origsize; + + return (0); +} + +static int +checksum_send(struct hast_resource *res, struct nv *nv, void **datap, + size_t *sizep, bool *freedatap __unused) +{ + unsigned char hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX ctx; + + res = res; /* TODO */ + + SHA256_Init(&ctx); + SHA256_Update(&ctx, *datap, *sizep); + SHA256_Final(hash, &ctx); + + nv_add_string(nv, "sha256", "checksum"); + nv_add_uint8_array(nv, hash, sizeof(hash), "hash"); + + return (0); +} + +static int +checksum_recv(struct hast_resource *res, struct nv *nv, void **datap, + size_t *sizep, bool *freedatap __unused) +{ + unsigned char chash[SHA256_DIGEST_LENGTH]; + const unsigned char *rhash; + SHA256_CTX ctx; + const char *algo; + size_t size; + + res = res; /* TODO */ + + algo = nv_get_string(nv, "checksum"); + if (algo == NULL) + return (0); /* No checksum. */ + if (strcmp(algo, "sha256") != 0) { + pjdlog_error("Unknown checksum algorithm '%s'.", algo); + return (-1); /* Unknown checksum algorithm. */ + } + rhash = nv_get_uint8_array(nv, &size, "hash"); + if (rhash == NULL) { + pjdlog_error("Checksum algorithm is present, but hash is missing."); + return (-1); /* Hash not found. */ + } + if (size != sizeof(chash)) { + pjdlog_error("Invalid hash size (%zu) for %s, should be %zu.", + size, algo, sizeof(chash)); + return (-1); /* Different hash size. */ + } + + SHA256_Init(&ctx); + SHA256_Update(&ctx, *datap, *sizep); + SHA256_Final(chash, &ctx); + + if (bcmp(rhash, chash, sizeof(chash)) != 0) { + pjdlog_error("Hash mismatch."); + return (-1); /* Hash mismatch. */ + } + + return (0); +} + +/* + * Send the given nv structure via conn. + * We keep headers in nv structure and pass data in separate argument. + * There can be no data at all (data is NULL then). + */ +int +hast_proto_send(struct hast_resource *res, struct proto_conn *conn, + struct nv *nv, const void *data, size_t size) +{ + struct hast_main_header hdr; + struct ebuf *eb; + bool freedata; + void *dptr, *hptr; + size_t hsize; + int ret; + + dptr = (void *)(uintptr_t)data; + freedata = false; + ret = -1; + + if (data != NULL) { +if (false) { + unsigned int ii; + + for (ii = 0; ii < sizeof(pipeline) / sizeof(pipeline[0]); + ii++) { + ret = pipeline[ii].hps_send(res, nv, &dptr, &size, + &freedata); + if (ret == -1) + goto end; + } + ret = -1; +} + nv_add_uint32(nv, size, "size"); + if (nv_error(nv) != 0) { + errno = nv_error(nv); + goto end; + } + } + + eb = nv_hton(nv); + if (eb == NULL) + goto end; + + hdr.version = HAST_PROTO_VERSION; + hdr.size = htole32((uint32_t)ebuf_size(eb)); + if (ebuf_add_head(eb, &hdr, sizeof(hdr)) < 0) + goto end; + + hptr = ebuf_data(eb, &hsize); + if (proto_send(conn, hptr, hsize) < 0) + goto end; + if (data != NULL && proto_send(conn, dptr, size) < 0) + goto end; + + ret = 0; +end: + if (freedata) + free(dptr); + return (ret); +} + +int +hast_proto_recv_hdr(struct proto_conn *conn, struct nv **nvp) +{ + struct hast_main_header hdr; + struct nv *nv; + struct ebuf *eb; + void *hptr; + + eb = NULL; + nv = NULL; + + if (proto_recv(conn, &hdr, sizeof(hdr)) < 0) + goto fail; + + if (hdr.version != HAST_PROTO_VERSION) { + errno = ERPCMISMATCH; + goto fail; + } + + hdr.size = le32toh(hdr.size); + + eb = ebuf_alloc(hdr.size); + if (eb == NULL) + goto fail; + if (ebuf_add_tail(eb, NULL, hdr.size) < 0) + goto fail; + hptr = ebuf_data(eb, NULL); + assert(hptr != NULL); + if (proto_recv(conn, hptr, hdr.size) < 0) + goto fail; + nv = nv_ntoh(eb); + if (nv == NULL) + goto fail; + + *nvp = nv; + return (0); +fail: + if (nv != NULL) + nv_free(nv); + else if (eb != NULL) + ebuf_free(eb); + return (-1); +} + +int +hast_proto_recv_data(struct hast_resource *res, struct proto_conn *conn, + struct nv *nv, void *data, size_t size) +{ + unsigned int ii; + bool freedata; + size_t dsize; + void *dptr; + int ret; + + assert(data != NULL); + assert(size > 0); + + ret = -1; + freedata = false; + dptr = data; + + dsize = nv_get_uint32(nv, "size"); + if (dsize == 0) + (void)nv_set_error(nv, 0); + else { + if (proto_recv(conn, data, dsize) < 0) + goto end; +if (false) { + for (ii = sizeof(pipeline) / sizeof(pipeline[0]); ii > 0; + ii--) { + assert(!"to be verified"); + ret = pipeline[ii - 1].hps_recv(res, nv, &dptr, + &dsize, &freedata); + if (ret == -1) + goto end; + } + ret = -1; + if (dsize < size) + goto end; + /* TODO: 'size' doesn't seem right here. It is maximum data size. */ + if (dptr != data) + bcopy(dptr, data, dsize); +} + } + + ret = 0; +end: +if (ret < 0) printf("%s:%u %s\n", __func__, __LINE__, strerror(errno)); + if (freedata) + free(dptr); + return (ret); +} + +int +hast_proto_recv(struct hast_resource *res, struct proto_conn *conn, + struct nv **nvp, void *data, size_t size) +{ + struct nv *nv; + size_t dsize; + int ret; + + ret = hast_proto_recv_hdr(conn, &nv); + if (ret < 0) + return (ret); + dsize = nv_get_uint32(nv, "size"); + if (dsize == 0) + (void)nv_set_error(nv, 0); + else + ret = hast_proto_recv_data(res, conn, nv, data, size); + if (ret < 0) + nv_free(nv); + else + *nvp = nv; + return (ret); +} diff --git a/sbin/hastd/hast_proto.h b/sbin/hastd/hast_proto.h new file mode 100644 index 00000000000..3894e383808 --- /dev/null +++ b/sbin/hastd/hast_proto.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _HAST_PROTO_H_ +#define _HAST_PROTO_H_ + +#include /* size_t */ + +#include +#include + +int hast_proto_send(struct hast_resource *res, struct proto_conn *conn, + struct nv *nv, const void *data, size_t size); +int hast_proto_recv(struct hast_resource *res, struct proto_conn *conn, + struct nv **nvp, void *data, size_t size); +int hast_proto_recv_hdr(struct proto_conn *conn, struct nv **nvp); +int hast_proto_recv_data(struct hast_resource *res, struct proto_conn *conn, + struct nv *nv, void *data, size_t size); + +#endif /* !_HAST_PROTO_H_ */ diff --git a/sbin/hastd/hastd.8 b/sbin/hastd/hastd.8 new file mode 100644 index 00000000000..276b3d301ab --- /dev/null +++ b/sbin/hastd/hastd.8 @@ -0,0 +1,232 @@ +.\" Copyright (c) 2010 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Pawel Jakub Dawidek under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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 AUTHORS 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 AUTHORS 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 February 1, 2010 +.Dt HASTD 8 +.Os +.Sh NAME +.Nm hastd +.Nd "Highly Available Storage daemon" +.Sh SYNOPSIS +.Nm +.Op Fl dFh +.Op Fl c Ar config +.Op Fl P Ar pidfile +.Sh DESCRIPTION +The +.Nm +daemon is responsible for managing highly available GEOM providers. +.Pp +.Nm +allows to transparently store data on two physically separated machines +connected over the TCP/IP network. +Only one machine (cluster node) can actively use storage provided by +.Nm . +This machine is called primary. +The +.Nm +daemon operates on block level, which makes it transparent for file +systems and applications. +.Pp +There is one main +.Nm +daemon which starts new worker process as soon as a role for the given +resource is changed to primary or as soon as a role for the given +resource is changed to secondary and remote (primary) node will +successfully connect to it. +Every worker process gets a new process title (see +.Xr setproctitle 3 ) , +which describes its role and resource it controls. +The exact format is: +.Bd -literal -offset indent +hastd: () +.Ed +.Pp +When (and only when) +.Nm +operates in primary role for the given resource, corresponding +.Pa /dev/hast/ +disk-like device (GEOM provider) is created. +File systems and applications can use this provider to send I/O +requests to. +Every write, delete and flush operation +.Dv ( BIO_WRITE , BIO_DELETE , BIO_FLUSH ) +is send to local component and synchronously replicated +to the remote (secondary) node if it is available. +Read operations +.Dv ( BIO_READ ) +are handled locally unless I/O error occurs or local version of the data +is not up-to-date yet (synchronization is in progress). +.Pp +The +.Nm +daemon uses the GEOM Gate class to receive I/O requests from the +in-kernel GEOM infrastructure. +The +.Nm geom_gate.ko +module is loaded automatically if the kernel was not compiled with the +following option: +.Bd -ragged -offset indent +.Cd "options GEOM_GATE" +.Ed +.Pp +The connection between two +.Nm +daemons is always initiated from the one running as primary to the one +running as secondary. +When primary +.Nm +is unable to connect or connection fails, it will try to re-establish +connection every few seconds. +Once connection is established, primary +.Nm +will synchronize every extent that was modified during connection outage +to the secondary +.Nm . +.Pp +It is possible that in case of connection outage between the nodes +.Nm +primary role for the given resource will be configured on both nodes. +This in turn leads to incompatible data modifications. +Such condition is called split-brain and cannot be automatically +resolved by the +.Nm +daemon as this will lead most likely to data corruption or lost of +important changes. +Even though it cannot be fixed by +.Nm +itself, it will be detected and further connection between independently +modified nodes will not be possible. +Once this situation is manually resolved by an administrator, resource +on one of the nodes can be initialized (erasing local data), which makes +connection to the remote node possible again. +Connection of freshly initialized component will trigger full resource +synchronization. +.Pp +The +.Nm +daemon itself never picks his role up automatically. +The role has to be configured with the +.Xr hastctl 8 +control utility by additional software like +.Nm ucarp +or +.Nm heartbeat +that can reliably manage role separation and switch secondary node to +primary role in case of original primary failure. +.Pp +The +.Nm +daemon can be started with the following command line arguments: +.Bl -tag -width ".Fl P Ar pidfile" +.It Fl c Ar config +Specify alternative location of the configuration file. +The default location is +.Pa /etc/hast.conf . +.It Fl d +Print or log debugging information. +This option can be specified multiple times to raise the verbosity +level. +.It Fl F +Start the +.Nm +daemon in the foreground. +By default +.Nm +starts in the background. +.It Fl h +Print the +.Nm +usage message. +.It Fl P Ar pidfile +Specify alternative location of a file where main process PID will be +stored. +The default location is +.Pa /var/run/hastd.pid . +.El +.Sh EXIT STATUS +Exit status is 0 on success, or one of the values described in +.Xr sysexits 3 +on failure. +.Sh EXAMPLES +Launch +.Nm +on both nodes. +Set role for resource +.Nm shared +to primary on +.Nm nodeA +and to secondary on +.Nm nodeB . +Create file system on +.Pa /dev/hast/shared +provider and mount it. +.Bd -literal -offset indent +nodeB# hastd +nodeB# hastctl role secondary shared + +nodeA# hastd +nodeA# hastctl role primary shared +nodeA# newfs -U /dev/hast/shared +nodeA# mount -o noatime /dev/hast/shared /shared +.Ed +.Sh FILES +.Bl -tag -width ".Pa /var/run/hastctl" -compact +.It Pa /etc/hast.conf +The configuration file for +.Nm +and +.Xr hastctl 8 . +.It Pa /var/run/hastctl +Control socket used by the +.Xr hastctl 8 +control utility to communicate with +.Nm . +.It Pa /var/run/hastd.pid +The default location of the +.Nm +PID file. +.El +.Sh SEE ALSO +.Xr sysexits 3 , +.Xr geom 4 , +.Xr hast.conf 5 , +.Xr ggatec 8 , +.Xr ggated 8 , +.Xr ggatel 8 , +.Xr hastctl 8 , +.Xr mount 8 , +.Xr newfs 8 , +.Xr g_bio 9 . +.Sh AUTHORS +The +.Nm +was developed by +.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org +under sponsorship of the FreeBSD Foundation. diff --git a/sbin/hastd/hastd.c b/sbin/hastd/hastd.c new file mode 100644 index 00000000000..19f08936c2d --- /dev/null +++ b/sbin/hastd/hastd.c @@ -0,0 +1,522 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "control.h" +#include "hast.h" +#include "hast_proto.h" +#include "hastd.h" +#include "subr.h" + +/* Path to configuration file. */ +static const char *cfgpath = HAST_CONFIG; +/* Hastd configuration. */ +static struct hastd_config *cfg; +/* Was SIGCHLD signal received? */ +static bool sigchld_received = false; +/* Was SIGHUP signal received? */ +static bool sighup_received = false; +/* Was SIGINT or SIGTERM signal received? */ +bool sigexit_received = false; +/* PID file handle. */ +struct pidfh *pfh; + +static void +usage(void) +{ + + errx(EX_USAGE, "[-dFh] [-c config] [-P pidfile]"); +} + +static void +sighandler(int sig) +{ + + switch (sig) { + case SIGCHLD: + sigchld_received = true; + break; + case SIGHUP: + sighup_received = true; + break; + default: + assert(!"invalid condition"); + } +} + +static void +g_gate_load(void) +{ + + if (modfind("g_gate") == -1) { + /* Not present in kernel, try loading it. */ + if (kldload("geom_gate") == -1 || modfind("g_gate") == -1) { + if (errno != EEXIST) { + pjdlog_exit(EX_OSERR, + "Unable to load geom_gate module"); + } + } + } +} + +static void +child_exit(void) +{ + struct hast_resource *res; + int status; + pid_t pid; + + while ((pid = wait3(&status, WNOHANG, NULL)) > 0) { + /* Find resource related to the process that just exited. */ + TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { + if (pid == res->hr_workerpid) + break; + } + if (res == NULL) { + /* + * This can happen when new connection arrives and we + * cancel child responsible for the old one. + */ + continue; + } + pjdlog_prefix_set("[%s] (%s) ", res->hr_name, + role2str(res->hr_role)); + if (WEXITSTATUS(status) == 0) { + pjdlog_debug(1, + "Worker process exited gracefully (pid=%u).", + (unsigned int)pid); + } else { + pjdlog_error("Worker process failed (pid=%u, status=%d).", + (unsigned int)pid, WEXITSTATUS(status)); + } + res->hr_workerpid = 0; + if (res->hr_role == HAST_ROLE_PRIMARY) { + sleep(1); + pjdlog_info("Restarting worker process."); + hastd_primary(res); + } + pjdlog_prefix_set("%s", ""); + } +} + +static void +hastd_reload(void) +{ + + /* TODO */ + pjdlog_warning("Configuration reload is not implemented."); +} + +static void +listen_accept(void) +{ + struct hast_resource *res; + struct proto_conn *conn; + struct nv *nvin, *nvout, *nverr; + const char *resname; + const unsigned char *token; + char laddr[256], raddr[256]; + size_t size; + pid_t pid; + int status; + + proto_local_address(cfg->hc_listenconn, laddr, sizeof(laddr)); + pjdlog_debug(1, "Accepting connection to %s.", laddr); + + if (proto_accept(cfg->hc_listenconn, &conn) < 0) { + pjdlog_errno(LOG_ERR, "Unable to accept connection %s", laddr); + return; + } + + proto_local_address(conn, laddr, sizeof(laddr)); + proto_remote_address(conn, raddr, sizeof(raddr)); + pjdlog_info("Connection from %s to %s.", laddr, raddr); + + nvin = nvout = nverr = NULL; + + /* + * Before receiving any data see if remote host have access to any + * resource. + */ + TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { + if (proto_address_match(conn, res->hr_remoteaddr)) + break; + } + if (res == NULL) { + pjdlog_error("Client %s isn't known.", raddr); + goto close; + } + /* Ok, remote host can access at least one resource. */ + + if (hast_proto_recv_hdr(conn, &nvin) < 0) { + pjdlog_errno(LOG_ERR, "Unable to receive header from %s", + raddr); + goto close; + } + + resname = nv_get_string(nvin, "resource"); + if (resname == NULL) { + pjdlog_error("No 'resource' field in the header received from %s.", + raddr); + goto close; + } + pjdlog_debug(2, "%s: resource=%s", raddr, resname); + token = nv_get_uint8_array(nvin, &size, "token"); + /* + * NULL token means that this is first conection. + */ + if (token != NULL && size != sizeof(res->hr_token)) { + pjdlog_error("Received token of invalid size from %s (expected %zu, got %zu).", + raddr, sizeof(res->hr_token), size); + goto close; + } + + /* + * From now on we want to send errors to the remote node. + */ + nverr = nv_alloc(); + + /* Find resource related to this connection. */ + TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { + if (strcmp(resname, res->hr_name) == 0) + break; + } + /* Have we found the resource? */ + if (res == NULL) { + pjdlog_error("No resource '%s' as requested by %s.", + resname, raddr); + nv_add_stringf(nverr, "errmsg", "Resource not configured."); + goto fail; + } + + /* Now that we know resource name setup log prefix. */ + pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role)); + + /* Does the remote host have access to this resource? */ + if (!proto_address_match(conn, res->hr_remoteaddr)) { + pjdlog_error("Client %s has no access to the resource.", raddr); + nv_add_stringf(nverr, "errmsg", "No access to the resource."); + goto fail; + } + /* Is the resource marked as secondary? */ + if (res->hr_role != HAST_ROLE_SECONDARY) { + pjdlog_error("We act as %s for the resource and not as %s as requested by %s.", + role2str(res->hr_role), role2str(HAST_ROLE_SECONDARY), + raddr); + nv_add_stringf(nverr, "errmsg", + "Remote node acts as %s for the resource and not as %s.", + role2str(res->hr_role), role2str(HAST_ROLE_SECONDARY)); + goto fail; + } + /* Does token (if exists) match? */ + if (token != NULL && memcmp(token, res->hr_token, + sizeof(res->hr_token)) != 0) { + pjdlog_error("Token received from %s doesn't match.", raddr); + nv_add_stringf(nverr, "errmsg", "Toke doesn't match."); + goto fail; + } + /* + * If there is no token, but we have half-open connection + * (only remotein) or full connection (worker process is running) + * we have to cancel those and accept the new connection. + */ + if (token == NULL) { + assert(res->hr_remoteout == NULL); + pjdlog_debug(1, "Initial connection from %s.", raddr); + if (res->hr_workerpid != 0) { + assert(res->hr_remotein == NULL); + pjdlog_debug(1, + "Worker process exists (pid=%u), stopping it.", + (unsigned int)res->hr_workerpid); + /* Stop child process. */ + if (kill(res->hr_workerpid, SIGINT) < 0) { + pjdlog_errno(LOG_ERR, + "Unable to stop worker process (pid=%u)", + (unsigned int)res->hr_workerpid); + /* + * Other than logging the problem we + * ignore it - nothing smart to do. + */ + } + /* Wait for it to exit. */ + else if ((pid = waitpid(res->hr_workerpid, + &status, 0)) != res->hr_workerpid) { + pjdlog_errno(LOG_ERR, + "Waiting for worker process (pid=%u) failed", + (unsigned int)res->hr_workerpid); + /* See above. */ + } else if (status != 0) { + pjdlog_error("Worker process (pid=%u) exited ungracefully: status=%d.", + (unsigned int)res->hr_workerpid, status); + /* See above. */ + } else { + pjdlog_debug(1, + "Worker process (pid=%u) exited gracefully.", + (unsigned int)res->hr_workerpid); + } + res->hr_workerpid = 0; + } else if (res->hr_remotein != NULL) { + char oaddr[256]; + + proto_remote_address(conn, oaddr, sizeof(oaddr)); + pjdlog_debug(1, + "Canceling half-open connection from %s on connection from %s.", + oaddr, raddr); + proto_close(res->hr_remotein); + res->hr_remotein = NULL; + } + } + + /* + * Checks and cleanups are done. + */ + + if (token == NULL) { + arc4random_buf(res->hr_token, sizeof(res->hr_token)); + nvout = nv_alloc(); + nv_add_uint8_array(nvout, res->hr_token, + sizeof(res->hr_token), "token"); + if (nv_error(nvout) != 0) { + pjdlog_common(LOG_ERR, 0, nv_error(nvout), + "Unable to prepare return header for %s", raddr); + nv_add_stringf(nverr, "errmsg", + "Remote node was unable to prepare return header: %s.", + strerror(nv_error(nvout))); + goto fail; + } + if (hast_proto_send(NULL, conn, nvout, NULL, 0) < 0) { + int error = errno; + + pjdlog_errno(LOG_ERR, "Unable to send response to %s", + raddr); + nv_add_stringf(nverr, "errmsg", + "Remote node was unable to send response: %s.", + strerror(error)); + goto fail; + } + res->hr_remotein = conn; + pjdlog_debug(1, "Incoming connection from %s configured.", + raddr); + } else { + res->hr_remoteout = conn; + pjdlog_debug(1, "Outgoing connection to %s configured.", raddr); + hastd_secondary(res, nvin); + } + nv_free(nvin); + nv_free(nvout); + nv_free(nverr); + pjdlog_prefix_set("%s", ""); + return; +fail: + if (nv_error(nverr) != 0) { + pjdlog_common(LOG_ERR, 0, nv_error(nverr), + "Unable to prepare error header for %s", raddr); + goto close; + } + if (hast_proto_send(NULL, conn, nverr, NULL, 0) < 0) { + pjdlog_errno(LOG_ERR, "Unable to send error to %s", raddr); + goto close; + } +close: + if (nvin != NULL) + nv_free(nvin); + if (nvout != NULL) + nv_free(nvout); + if (nverr != NULL) + nv_free(nverr); + proto_close(conn); + pjdlog_prefix_set("%s", ""); +} + +static void +main_loop(void) +{ + fd_set rfds, wfds; + int fd, maxfd, ret; + + for (;;) { + if (sigchld_received) { + sigchld_received = false; + child_exit(); + } + if (sighup_received) { + sighup_received = false; + hastd_reload(); + } + + maxfd = 0; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + /* Setup descriptors for select(2). */ +#define SETUP_FD(conn) do { \ + fd = proto_descriptor(conn); \ + if (fd >= 0) { \ + maxfd = fd > maxfd ? fd : maxfd; \ + FD_SET(fd, &rfds); \ + FD_SET(fd, &wfds); \ + } \ +} while (0) + SETUP_FD(cfg->hc_controlconn); + SETUP_FD(cfg->hc_listenconn); +#undef SETUP_FD + + ret = select(maxfd + 1, &rfds, &wfds, NULL, NULL); + if (ret == -1) { + if (errno == EINTR) + continue; + KEEP_ERRNO((void)pidfile_remove(pfh)); + pjdlog_exit(EX_OSERR, "select() failed"); + } + +#define ISSET_FD(conn) \ + (FD_ISSET((fd = proto_descriptor(conn)), &rfds) || FD_ISSET(fd, &wfds)) + if (ISSET_FD(cfg->hc_controlconn)) + control_handle(cfg); + if (ISSET_FD(cfg->hc_listenconn)) + listen_accept(); +#undef ISSET_FD + } +} + +int +main(int argc, char *argv[]) +{ + const char *pidfile; + pid_t otherpid; + bool foreground; + int debuglevel; + + g_gate_load(); + + foreground = false; + debuglevel = 0; + pidfile = HASTD_PIDFILE; + + for (;;) { + int ch; + + ch = getopt(argc, argv, "c:dFhP:"); + if (ch == -1) + break; + switch (ch) { + case 'c': + cfgpath = optarg; + break; + case 'd': + debuglevel++; + break; + case 'F': + foreground = true; + break; + case 'P': + pidfile = optarg; + break; + case 'h': + default: + usage(); + } + } + argc -= optind; + argv += optind; + + pjdlog_debug_set(debuglevel); + + pfh = pidfile_open(pidfile, 0600, &otherpid); + if (pfh == NULL) { + if (errno == EEXIST) { + pjdlog_exitx(EX_TEMPFAIL, + "Another hastd is already running, pid: %jd.", + (intmax_t)otherpid); + } + /* If we cannot create pidfile from other reasons, only warn. */ + pjdlog_errno(LOG_WARNING, "Cannot open or create pidfile"); + } + + cfg = yy_config_parse(cfgpath); + assert(cfg != NULL); + + signal(SIGHUP, sighandler); + signal(SIGCHLD, sighandler); + + /* Listen on control address. */ + if (proto_server(cfg->hc_controladdr, &cfg->hc_controlconn) < 0) { + KEEP_ERRNO((void)pidfile_remove(pfh)); + pjdlog_exit(EX_OSERR, "Unable to listen on control address %s", + cfg->hc_controladdr); + } + /* Listen for remote connections. */ + if (proto_server(cfg->hc_listenaddr, &cfg->hc_listenconn) < 0) { + KEEP_ERRNO((void)pidfile_remove(pfh)); + pjdlog_exit(EX_OSERR, "Unable to listen on address %s", + cfg->hc_listenaddr); + } + + if (!foreground) { + if (daemon(0, 0) < 0) { + KEEP_ERRNO((void)pidfile_remove(pfh)); + pjdlog_exit(EX_OSERR, "Unable to daemonize"); + } + + /* Start logging to syslog. */ + pjdlog_mode_set(PJDLOG_MODE_SYSLOG); + + /* Write PID to a file. */ + if (pidfile_write(pfh) < 0) { + pjdlog_errno(LOG_WARNING, + "Unable to write PID to a file"); + } + } + + main_loop(); + + exit(0); +} diff --git a/sbin/hastd/hastd.h b/sbin/hastd/hastd.h new file mode 100644 index 00000000000..199de8c94d5 --- /dev/null +++ b/sbin/hastd/hastd.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _HASTD_H_ +#define _HASTD_H_ + +#include +#include + +#include + +#include "hast.h" + +extern bool sigexit_received; +extern struct pidfh *pfh; + +void hastd_primary(struct hast_resource *res); +void hastd_secondary(struct hast_resource *res, struct nv *nvin); + +#endif /* !_HASTD_H_ */ diff --git a/sbin/hastd/hooks.c b/sbin/hastd/hooks.c new file mode 100644 index 00000000000..1fdeb750085 --- /dev/null +++ b/sbin/hastd/hooks.c @@ -0,0 +1,148 @@ +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "hooks.h" + +static void +descriptors(void) +{ + long maxfd; + int fd; + + /* + * Close all descriptors. + */ + maxfd = sysconf(_SC_OPEN_MAX); + if (maxfd < 0) { + pjdlog_errno(LOG_WARNING, "sysconf(_SC_OPEN_MAX) failed"); + maxfd = 1024; + } + for (fd = 0; fd <= maxfd; fd++) + close(fd); + /* + * Redirect stdin, stdout and stderr to /dev/null. + */ + fd = open(_PATH_DEVNULL, O_RDONLY); + if (fd < 0) { + pjdlog_errno(LOG_WARNING, "Unable to open %s for reading", + _PATH_DEVNULL); + } else if (fd != STDIN_FILENO) { + if (dup2(fd, STDIN_FILENO) < 0) { + pjdlog_errno(LOG_WARNING, + "Unable to duplicate descriptor for stdin"); + } + close(fd); + } + fd = open(_PATH_DEVNULL, O_WRONLY); + if (fd < 0) { + pjdlog_errno(LOG_WARNING, "Unable to open %s for writing", + _PATH_DEVNULL); + } else { + if (fd != STDOUT_FILENO && dup2(fd, STDOUT_FILENO) < 0) { + pjdlog_errno(LOG_WARNING, + "Unable to duplicate descriptor for stdout"); + } + if (fd != STDERR_FILENO && dup2(fd, STDERR_FILENO) < 0) { + pjdlog_errno(LOG_WARNING, + "Unable to duplicate descriptor for stderr"); + } + if (fd != STDOUT_FILENO && fd != STDERR_FILENO) + close(fd); + } +} + +int +hook_exec(const char *path, ...) +{ + va_list ap; + int ret; + + va_start(ap, path); + ret = hook_execv(path, ap); + va_end(ap); + return (ret); +} + +int +hook_execv(const char *path, va_list ap) +{ + char *args[64]; + unsigned int ii; + pid_t pid, wpid; + int status; + + if (path == NULL || path[0] == '\0') + return (0); + + memset(args, 0, sizeof(args)); + args[0] = basename(path); + for (ii = 1; ii < sizeof(args) / sizeof(args[0]); ii++) { + args[ii] = va_arg(ap, char *); + if (args[ii] == NULL) + break; + } + assert(ii < sizeof(args) / sizeof(args[0])); + + pid = fork(); + switch (pid) { + case -1: /* Error. */ + pjdlog_errno(LOG_ERR, "Unable to fork %s", path); + return (-1); + case 0: /* Child. */ + descriptors(); + execv(path, args); + pjdlog_errno(LOG_ERR, "Unable to execute %s", path); + exit(EX_SOFTWARE); + default: /* Parent. */ + break; + } + + wpid = waitpid(pid, &status, 0); + assert(wpid == pid); + + return (WEXITSTATUS(status)); +} diff --git a/sbin/hastd/hooks.h b/sbin/hastd/hooks.h new file mode 100644 index 00000000000..799b781d319 --- /dev/null +++ b/sbin/hastd/hooks.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _HOOKS_H_ +#define _HOOKS_H_ + +#include + +int hook_exec(const char *path, ...); +int hook_execv(const char *path, va_list ap); + +#endif /* !_HOOKS_H_ */ diff --git a/sbin/hastd/metadata.c b/sbin/hastd/metadata.c new file mode 100644 index 00000000000..9bca66bbbe1 --- /dev/null +++ b/sbin/hastd/metadata.c @@ -0,0 +1,222 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "metadata.h" + +int +metadata_read(struct hast_resource *res, bool openrw) +{ + unsigned char *buf; + struct ebuf *eb; + struct nv *nv; + ssize_t done; + const char *str; + int rerrno; + bool opened_here; + + opened_here = false; + rerrno = 0; + + /* + * Is this first metadata_read() call for this resource? + */ + if (res->hr_localfd == -1) { + if (provinfo(res, openrw) < 0) { + rerrno = errno; + goto fail; + } + opened_here = true; + pjdlog_debug(1, "Obtained info about %s.", res->hr_localpath); + if (openrw) { + if (flock(res->hr_localfd, LOCK_EX | LOCK_NB) < 0) { + rerrno = errno; + if (errno == EOPNOTSUPP) { + pjdlog_warning("Unable to lock %s (operation not supported), but continuing.", + res->hr_localpath); + } else { + pjdlog_errno(LOG_ERR, + "Unable to lock %s", + res->hr_localpath); + goto fail; + } + } + pjdlog_debug(1, "Locked %s.", res->hr_localpath); + } + } + + eb = ebuf_alloc(METADATA_SIZE); + if (eb == NULL) { + rerrno = errno; + pjdlog_errno(LOG_ERR, + "Unable to allocate memory to read metadata"); + goto fail; + } + if (ebuf_add_tail(eb, NULL, METADATA_SIZE) < 0) { + rerrno = errno; + pjdlog_errno(LOG_ERR, + "Unable to allocate memory to read metadata"); + goto fail; + } + buf = ebuf_data(eb, NULL); + assert(buf != NULL); + done = pread(res->hr_localfd, buf, METADATA_SIZE, 0); + if (done < 0 || done != METADATA_SIZE) { + rerrno = errno; + pjdlog_errno(LOG_ERR, "Unable to read metadata"); + ebuf_free(eb); + goto fail; + } + nv = nv_ntoh(eb); + if (nv == NULL) { + rerrno = errno; + pjdlog_errno(LOG_ERR, "Metadata read from %s is invalid", + res->hr_localpath); + ebuf_free(eb); + goto fail; + } + + str = nv_get_string(nv, "resource"); + if (strcmp(str, res->hr_name) != 0) { + pjdlog_error("Provider %s is not part of resource %s.", + res->hr_localpath, res->hr_name); + nv_free(nv); + goto fail; + } + + res->hr_datasize = nv_get_uint64(nv, "datasize"); + res->hr_extentsize = (int)nv_get_uint32(nv, "extentsize"); + res->hr_keepdirty = (int)nv_get_uint32(nv, "keepdirty"); + res->hr_localoff = nv_get_uint64(nv, "offset"); + res->hr_resuid = nv_get_uint64(nv, "resuid"); + if (res->hr_role != HAST_ROLE_PRIMARY) { + /* Secondary or init role. */ + res->hr_secondary_localcnt = nv_get_uint64(nv, "localcnt"); + res->hr_secondary_remotecnt = nv_get_uint64(nv, "remotecnt"); + } + if (res->hr_role != HAST_ROLE_SECONDARY) { + /* Primary or init role. */ + res->hr_primary_localcnt = nv_get_uint64(nv, "localcnt"); + res->hr_primary_remotecnt = nv_get_uint64(nv, "remotecnt"); + } + str = nv_get_string(nv, "prevrole"); + if (str != NULL) { + if (strcmp(str, "primary") == 0) + res->hr_previous_role = HAST_ROLE_PRIMARY; + else if (strcmp(str, "secondary") == 0) + res->hr_previous_role = HAST_ROLE_SECONDARY; + } + + if (nv_error(nv) != 0) { + errno = rerrno = nv_error(nv); + pjdlog_errno(LOG_ERR, "Unable to read metadata from %s", + res->hr_localpath); + nv_free(nv); + goto fail; + } + return (0); +fail: + if (opened_here) { + close(res->hr_localfd); + res->hr_localfd = -1; + } + errno = rerrno; + return (-1); +} + +int +metadata_write(struct hast_resource *res) +{ + struct ebuf *eb; + struct nv *nv; + unsigned char *buf, *ptr; + size_t size; + ssize_t done; + + buf = calloc(1, METADATA_SIZE); + if (buf == NULL) { + pjdlog_error("Unable to allocate %zu bytes for metadata.", + (size_t)METADATA_SIZE); + return (-1); + } + + nv = nv_alloc(); + nv_add_string(nv, res->hr_name, "resource"); + nv_add_uint64(nv, (uint64_t)res->hr_datasize, "datasize"); + nv_add_uint32(nv, (uint32_t)res->hr_extentsize, "extentsize"); + nv_add_uint32(nv, (uint32_t)res->hr_keepdirty, "keepdirty"); + nv_add_uint64(nv, (uint64_t)res->hr_localoff, "offset"); + nv_add_uint64(nv, res->hr_resuid, "resuid"); + if (res->hr_role == HAST_ROLE_PRIMARY || + res->hr_role == HAST_ROLE_INIT) { + nv_add_uint64(nv, res->hr_primary_localcnt, "localcnt"); + nv_add_uint64(nv, res->hr_primary_remotecnt, "remotecnt"); + } else /* if (res->hr_role == HAST_ROLE_SECONDARY) */ { + assert(res->hr_role == HAST_ROLE_SECONDARY); + nv_add_uint64(nv, res->hr_secondary_localcnt, "localcnt"); + nv_add_uint64(nv, res->hr_secondary_remotecnt, "remotecnt"); + } + nv_add_string(nv, role2str(res->hr_role), "prevrole"); + if (nv_error(nv) != 0) { + pjdlog_error("Unable to create metadata."); + goto fail; + } + res->hr_previous_role = res->hr_role; + eb = nv_hton(nv); + assert(eb != NULL); + ptr = ebuf_data(eb, &size); + assert(ptr != NULL); + assert(size < METADATA_SIZE); + bcopy(ptr, buf, size); + done = pwrite(res->hr_localfd, buf, METADATA_SIZE, 0); + if (done < 0 || done != METADATA_SIZE) { + pjdlog_errno(LOG_ERR, "Unable to write metadata"); + goto fail; + } + + return (0); +fail: + free(buf); + nv_free(nv); + return (-1); +} diff --git a/sbin/hastd/metadata.h b/sbin/hastd/metadata.h new file mode 100644 index 00000000000..83d35f4c2f2 --- /dev/null +++ b/sbin/hastd/metadata.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _METADATA_H_ +#define _METADATA_H_ + +#include + +#include + +/* + * Maximum size of metadata. + * XXX: We should take sector size into account. + */ +#define METADATA_SIZE 4096 + +int metadata_read(struct hast_resource *res, bool openrw); +int metadata_write(struct hast_resource *res); + +#endif /* !_METADATA_H_ */ diff --git a/sbin/hastd/nv.c b/sbin/hastd/nv.c new file mode 100644 index 00000000000..0b4e362c9e4 --- /dev/null +++ b/sbin/hastd/nv.c @@ -0,0 +1,882 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 + +#define NV_MAGIC 0xaea1e +struct nv { + int nv_magic; + int nv_error; + struct ebuf *nv_ebuf; +}; + +struct nvhdr { + uint8_t nvh_type; + uint8_t nvh_namesize; + uint32_t nvh_dsize; + char nvh_name[0]; +} __packed; +#define NVH_DATA(nvh) ((unsigned char *)nvh + NVH_HSIZE(nvh)) +#define NVH_HSIZE(nvh) \ + (sizeof(struct nvhdr) + roundup2((nvh)->nvh_namesize, 8)) +#define NVH_DSIZE(nvh) \ + (((nvh)->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST ? \ + (nvh)->nvh_dsize : \ + le32toh((nvh)->nvh_dsize)) +#define NVH_SIZE(nvh) (NVH_HSIZE(nvh) + roundup2(NVH_DSIZE(nvh), 8)) + +#define NV_CHECK(nv) do { \ + assert((nv) != NULL); \ + assert((nv)->nv_magic == NV_MAGIC); \ +} while (0) + +static void nv_add(struct nv *nv, const unsigned char *value, size_t vsize, + int type, const char *name); +static void nv_addv(struct nv *nv, const unsigned char *value, size_t vsize, + int type, const char *namefmt, va_list nameap); +static struct nvhdr *nv_find(struct nv *nv, int type, const char *namefmt, + va_list nameap); +static void nv_swap(struct nvhdr *nvh, bool tohost); + +/* + * Allocate and initialize new nv structure. + * Return NULL in case of malloc(3) failure. + */ +struct nv * +nv_alloc(void) +{ + struct nv *nv; + + nv = malloc(sizeof(*nv)); + if (nv == NULL) + return (NULL); + nv->nv_ebuf = ebuf_alloc(0); + if (nv->nv_ebuf == NULL) { + free(nv); + return (NULL); + } + nv->nv_error = 0; + nv->nv_magic = NV_MAGIC; + return (nv); +} + +/* + * Free the given nv structure. + */ +void +nv_free(struct nv *nv) +{ + + if (nv == NULL) + return; + + NV_CHECK(nv); + + nv->nv_magic = 0; + ebuf_free(nv->nv_ebuf); + free(nv); +} + +/* + * Return error for the given nv structure. + */ +int +nv_error(const struct nv *nv) +{ + + if (nv == NULL) + return (ENOMEM); + + NV_CHECK(nv); + + return (nv->nv_error); +} + +/* + * Set error for the given nv structure and return previous error. + */ +int +nv_set_error(struct nv *nv, int error) +{ + int preverr; + + if (nv == NULL) + return (ENOMEM); + + NV_CHECK(nv); + + preverr = nv->nv_error; + nv->nv_error = error; + return (preverr); +} + +/* + * Validate correctness of the entire nv structure and all its elements. + * If extrap is not NULL, store number of extra bytes at the end of the buffer. + */ +int +nv_validate(struct nv *nv, size_t *extrap) +{ + struct nvhdr *nvh; + unsigned char *data, *ptr; + size_t dsize, size, vsize; + int error; + + if (nv == NULL) { + errno = ENOMEM; + return (-1); + } + + NV_CHECK(nv); + assert(nv->nv_error == 0); + + /* TODO: Check that names are unique? */ + + error = 0; + ptr = ebuf_data(nv->nv_ebuf, &size); + while (size > 0) { + /* + * Zeros at the end of the buffer are acceptable. + */ + if (ptr[0] == '\0') + break; + /* + * Minimum size at this point is size of nvhdr structure, one + * character long name plus terminating '\0'. + */ + if (size < sizeof(*nvh) + 2) { + error = EINVAL; + break; + } + nvh = (struct nvhdr *)ptr; + if (size < NVH_HSIZE(nvh)) { + error = EINVAL; + break; + } + if (nvh->nvh_name[nvh->nvh_namesize - 1] != '\0') { + error = EINVAL; + break; + } + if (strlen(nvh->nvh_name) != + (size_t)(nvh->nvh_namesize - 1)) { + error = EINVAL; + break; + } + if ((nvh->nvh_type & NV_TYPE_MASK) < NV_TYPE_FIRST || + (nvh->nvh_type & NV_TYPE_MASK) > NV_TYPE_LAST) { + error = EINVAL; + break; + } + dsize = NVH_DSIZE(nvh); + if (dsize == 0) { + error = EINVAL; + break; + } + if (size < NVH_SIZE(nvh)) { + error = EINVAL; + break; + } + vsize = 0; + switch (nvh->nvh_type & NV_TYPE_MASK) { + case NV_TYPE_INT8: + case NV_TYPE_UINT8: + if (vsize == 0) + vsize = 1; + /* FALLTHOUGH */ + case NV_TYPE_INT16: + case NV_TYPE_UINT16: + if (vsize == 0) + vsize = 2; + /* FALLTHOUGH */ + case NV_TYPE_INT32: + case NV_TYPE_UINT32: + if (vsize == 0) + vsize = 4; + /* FALLTHOUGH */ + case NV_TYPE_INT64: + case NV_TYPE_UINT64: + if (vsize == 0) + vsize = 8; + if (dsize != vsize) { + error = EINVAL; + break; + } + break; + case NV_TYPE_INT8_ARRAY: + case NV_TYPE_UINT8_ARRAY: + break; + case NV_TYPE_INT16_ARRAY: + case NV_TYPE_UINT16_ARRAY: + if (vsize == 0) + vsize = 2; + /* FALLTHOUGH */ + case NV_TYPE_INT32_ARRAY: + case NV_TYPE_UINT32_ARRAY: + if (vsize == 0) + vsize = 4; + /* FALLTHOUGH */ + case NV_TYPE_INT64_ARRAY: + case NV_TYPE_UINT64_ARRAY: + if (vsize == 0) + vsize = 8; + if ((dsize % vsize) != 0) { + error = EINVAL; + break; + } + break; + case NV_TYPE_STRING: + data = NVH_DATA(nvh); + if (data[dsize - 1] != '\0') { + error = EINVAL; + break; + } + if (strlen((char *)data) != dsize - 1) { + error = EINVAL; + break; + } + break; + default: + assert(!"invalid condition"); + } + if (error != 0) + break; + ptr += NVH_SIZE(nvh); + size -= NVH_SIZE(nvh); + } + if (error != 0) { + errno = error; + if (nv->nv_error == 0) + nv->nv_error = error; + return (-1); + } + if (extrap != NULL) + *extrap = size; + return (0); +} + +/* + * Convert the given nv structure to network byte order and return ebuf + * structure. + */ +struct ebuf * +nv_hton(struct nv *nv) +{ + struct nvhdr *nvh; + unsigned char *ptr; + size_t size; + + NV_CHECK(nv); + assert(nv->nv_error == 0); + + ptr = ebuf_data(nv->nv_ebuf, &size); + while (size > 0) { + /* + * Minimum size at this point is size of nvhdr structure, + * one character long name plus terminating '\0'. + */ + assert(size >= sizeof(*nvh) + 2); + nvh = (struct nvhdr *)ptr; + assert(NVH_SIZE(nvh) <= size); + nv_swap(nvh, false); + ptr += NVH_SIZE(nvh); + size -= NVH_SIZE(nvh); + } + + return (nv->nv_ebuf); +} + +/* + * Create nv structure based on ebuf received from the network. + */ +struct nv * +nv_ntoh(struct ebuf *eb) +{ + struct nv *nv; + size_t extra; + int rerrno; + + assert(eb != NULL); + + nv = malloc(sizeof(*nv)); + if (nv == NULL) + return (NULL); + nv->nv_error = 0; + nv->nv_ebuf = eb; + nv->nv_magic = NV_MAGIC; + + if (nv_validate(nv, &extra) < 0) { + rerrno = errno; + nv->nv_magic = 0; + free(nv); + errno = rerrno; + return (NULL); + } + /* + * Remove extra zeros at the end of the buffer. + */ + ebuf_del_tail(eb, extra); + + return (nv); +} + +#define NV_DEFINE_ADD(type, TYPE) \ +void \ +nv_add_##type(struct nv *nv, type##_t value, const char *namefmt, ...) \ +{ \ + va_list nameap; \ + \ + va_start(nameap, namefmt); \ + nv_addv(nv, (unsigned char *)&value, sizeof(value), \ + NV_TYPE_##TYPE, namefmt, nameap); \ + va_end(nameap); \ +} + +NV_DEFINE_ADD(int8, INT8) +NV_DEFINE_ADD(uint8, UINT8) +NV_DEFINE_ADD(int16, INT16) +NV_DEFINE_ADD(uint16, UINT16) +NV_DEFINE_ADD(int32, INT32) +NV_DEFINE_ADD(uint32, UINT32) +NV_DEFINE_ADD(int64, INT64) +NV_DEFINE_ADD(uint64, UINT64) + +#undef NV_DEFINE_ADD + +#define NV_DEFINE_ADD_ARRAY(type, TYPE) \ +void \ +nv_add_##type##_array(struct nv *nv, const type##_t *value, \ + size_t nsize, const char *namefmt, ...) \ +{ \ + va_list nameap; \ + \ + va_start(nameap, namefmt); \ + nv_addv(nv, (const unsigned char *)value, \ + sizeof(value[0]) * nsize, NV_TYPE_##TYPE##_ARRAY, namefmt, \ + nameap); \ + va_end(nameap); \ +} + +NV_DEFINE_ADD_ARRAY(int8, INT8) +NV_DEFINE_ADD_ARRAY(uint8, UINT8) +NV_DEFINE_ADD_ARRAY(int16, INT16) +NV_DEFINE_ADD_ARRAY(uint16, UINT16) +NV_DEFINE_ADD_ARRAY(int32, INT32) +NV_DEFINE_ADD_ARRAY(uint32, UINT32) +NV_DEFINE_ADD_ARRAY(int64, INT64) +NV_DEFINE_ADD_ARRAY(uint64, UINT64) + +#undef NV_DEFINE_ADD_ARRAY + +void +nv_add_string(struct nv *nv, const char *value, const char *namefmt, ...) +{ + va_list nameap; + size_t size; + + size = strlen(value) + 1; + + va_start(nameap, namefmt); + nv_addv(nv, (const unsigned char *)value, size, NV_TYPE_STRING, + namefmt, nameap); + va_end(nameap); +} + +void +nv_add_stringf(struct nv *nv, const char *name, const char *valuefmt, ...) +{ + va_list valueap; + + va_start(valueap, valuefmt); + nv_add_stringv(nv, name, valuefmt, valueap); + va_end(valueap); +} + +void +nv_add_stringv(struct nv *nv, const char *name, const char *valuefmt, + va_list valueap) +{ + char *value; + ssize_t size; + + size = vasprintf(&value, valuefmt, valueap); + if (size < 0) { + if (nv->nv_error == 0) + nv->nv_error = ENOMEM; + return; + } + size++; + nv_add(nv, (const unsigned char *)value, size, NV_TYPE_STRING, name); + free(value); +} + +#define NV_DEFINE_GET(type, TYPE) \ +type##_t \ +nv_get_##type(struct nv *nv, const char *namefmt, ...) \ +{ \ + struct nvhdr *nvh; \ + va_list nameap; \ + type##_t value; \ + \ + va_start(nameap, namefmt); \ + nvh = nv_find(nv, NV_TYPE_##TYPE, namefmt, nameap); \ + va_end(nameap); \ + if (nvh == NULL) \ + return (0); \ + assert((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST); \ + assert(sizeof(value) == nvh->nvh_dsize); \ + bcopy(NVH_DATA(nvh), &value, sizeof(value)); \ + \ + return (value); \ +} + +NV_DEFINE_GET(int8, INT8) +NV_DEFINE_GET(uint8, UINT8) +NV_DEFINE_GET(int16, INT16) +NV_DEFINE_GET(uint16, UINT16) +NV_DEFINE_GET(int32, INT32) +NV_DEFINE_GET(uint32, UINT32) +NV_DEFINE_GET(int64, INT64) +NV_DEFINE_GET(uint64, UINT64) + +#undef NV_DEFINE_GET + +#define NV_DEFINE_GET_ARRAY(type, TYPE) \ +const type##_t * \ +nv_get_##type##_array(struct nv *nv, size_t *sizep, \ + const char *namefmt, ...) \ +{ \ + struct nvhdr *nvh; \ + va_list nameap; \ + \ + va_start(nameap, namefmt); \ + nvh = nv_find(nv, NV_TYPE_##TYPE##_ARRAY, namefmt, nameap); \ + va_end(nameap); \ + if (nvh == NULL) \ + return (NULL); \ + assert((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST); \ + assert((nvh->nvh_dsize % sizeof(type##_t)) == 0); \ + if (sizep != NULL) \ + *sizep = nvh->nvh_dsize / sizeof(type##_t); \ + return ((type##_t *)(void *)NVH_DATA(nvh)); \ +} + +NV_DEFINE_GET_ARRAY(int8, INT8) +NV_DEFINE_GET_ARRAY(uint8, UINT8) +NV_DEFINE_GET_ARRAY(int16, INT16) +NV_DEFINE_GET_ARRAY(uint16, UINT16) +NV_DEFINE_GET_ARRAY(int32, INT32) +NV_DEFINE_GET_ARRAY(uint32, UINT32) +NV_DEFINE_GET_ARRAY(int64, INT64) +NV_DEFINE_GET_ARRAY(uint64, UINT64) + +#undef NV_DEFINE_GET_ARRAY + +const char * +nv_get_string(struct nv *nv, const char *namefmt, ...) +{ + struct nvhdr *nvh; + va_list nameap; + char *str; + + va_start(nameap, namefmt); + nvh = nv_find(nv, NV_TYPE_STRING, namefmt, nameap); + va_end(nameap); + if (nvh == NULL) + return (NULL); + assert((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST); + assert(nvh->nvh_dsize >= 1); + str = NVH_DATA(nvh); + assert(str[nvh->nvh_dsize - 1] == '\0'); + assert(strlen(str) == nvh->nvh_dsize - 1); + return (str); +} + +/* + * Dump content of the nv structure. + */ +void +nv_dump(struct nv *nv) +{ + struct nvhdr *nvh; + unsigned char *data, *ptr; + size_t dsize, size; + unsigned int ii; + bool swap; + + if (nv_validate(nv, NULL) < 0) { + printf("error: %d\n", errno); + return; + } + + NV_CHECK(nv); + assert(nv->nv_error == 0); + + ptr = ebuf_data(nv->nv_ebuf, &size); + while (size > 0) { + assert(size >= sizeof(*nvh) + 2); + nvh = (struct nvhdr *)ptr; + assert(size >= NVH_SIZE(nvh)); + swap = ((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_NETWORK); + dsize = NVH_DSIZE(nvh); + data = NVH_DATA(nvh); + printf(" %s", nvh->nvh_name); + switch (nvh->nvh_type & NV_TYPE_MASK) { + case NV_TYPE_INT8: + printf("(int8): %jd", (intmax_t)(*(int8_t *)data)); + break; + case NV_TYPE_UINT8: + printf("(uint8): %ju", (uintmax_t)(*(uint8_t *)data)); + break; + case NV_TYPE_INT16: + printf("(int16): %jd", swap ? + (intmax_t)le16toh(*(int16_t *)(void *)data) : + (intmax_t)*(int16_t *)(void *)data); + break; + case NV_TYPE_UINT16: + printf("(uint16): %ju", swap ? + (uintmax_t)le16toh(*(uint16_t *)(void *)data) : + (uintmax_t)*(uint16_t *)(void *)data); + break; + case NV_TYPE_INT32: + printf("(int32): %jd", swap ? + (intmax_t)le32toh(*(int32_t *)(void *)data) : + (intmax_t)*(int32_t *)(void *)data); + break; + case NV_TYPE_UINT32: + printf("(uint32): %ju", swap ? + (uintmax_t)le32toh(*(uint32_t *)(void *)data) : + (uintmax_t)*(uint32_t *)(void *)data); + break; + case NV_TYPE_INT64: + printf("(int64): %jd", swap ? + (intmax_t)le64toh(*(int64_t *)(void *)data) : + (intmax_t)*(int64_t *)(void *)data); + break; + case NV_TYPE_UINT64: + printf("(uint64): %ju", swap ? + (uintmax_t)le64toh(*(uint64_t *)(void *)data) : + (uintmax_t)*(uint64_t *)(void *)data); + break; + case NV_TYPE_INT8_ARRAY: + printf("(int8 array):"); + for (ii = 0; ii < dsize; ii++) + printf(" %jd", (intmax_t)((int8_t *)data)[ii]); + break; + case NV_TYPE_UINT8_ARRAY: + printf("(uint8 array):"); + for (ii = 0; ii < dsize; ii++) + printf(" %ju", (uintmax_t)((uint8_t *)data)[ii]); + break; + case NV_TYPE_INT16_ARRAY: + printf("(int16 array):"); + for (ii = 0; ii < dsize / 2; ii++) { + printf(" %jd", swap ? + (intmax_t)le16toh(((int16_t *)(void *)data)[ii]) : + (intmax_t)((int16_t *)(void *)data)[ii]); + } + break; + case NV_TYPE_UINT16_ARRAY: + printf("(uint16 array):"); + for (ii = 0; ii < dsize / 2; ii++) { + printf(" %ju", swap ? + (uintmax_t)le16toh(((uint16_t *)(void *)data)[ii]) : + (uintmax_t)((uint16_t *)(void *)data)[ii]); + } + break; + case NV_TYPE_INT32_ARRAY: + printf("(int32 array):"); + for (ii = 0; ii < dsize / 4; ii++) { + printf(" %jd", swap ? + (intmax_t)le32toh(((int32_t *)(void *)data)[ii]) : + (intmax_t)((int32_t *)(void *)data)[ii]); + } + break; + case NV_TYPE_UINT32_ARRAY: + printf("(uint32 array):"); + for (ii = 0; ii < dsize / 4; ii++) { + printf(" %ju", swap ? + (uintmax_t)le32toh(((uint32_t *)(void *)data)[ii]) : + (uintmax_t)((uint32_t *)(void *)data)[ii]); + } + break; + case NV_TYPE_INT64_ARRAY: + printf("(int64 array):"); + for (ii = 0; ii < dsize / 8; ii++) { + printf(" %ju", swap ? + (uintmax_t)le64toh(((uint64_t *)(void *)data)[ii]) : + (uintmax_t)((uint64_t *)(void *)data)[ii]); + } + break; + case NV_TYPE_UINT64_ARRAY: + printf("(uint64 array):"); + for (ii = 0; ii < dsize / 8; ii++) { + printf(" %ju", swap ? + (uintmax_t)le64toh(((uint64_t *)(void *)data)[ii]) : + (uintmax_t)((uint64_t *)(void *)data)[ii]); + } + break; + case NV_TYPE_STRING: + printf("(string): %s", (char *)data); + break; + default: + assert(!"invalid condition"); + } + printf("\n"); + ptr += NVH_SIZE(nvh); + size -= NVH_SIZE(nvh); + } +} + +/* + * Local routines below. + */ + +static void +nv_add(struct nv *nv, const unsigned char *value, size_t vsize, int type, + const char *name) +{ + static unsigned char align[7]; + struct nvhdr *nvh; + size_t namesize; + + if (nv == NULL) { + errno = ENOMEM; + return; + } + + NV_CHECK(nv); + + namesize = strlen(name) + 1; + + nvh = malloc(sizeof(*nvh) + roundup2(namesize, 8)); + if (nvh == NULL) { + if (nv->nv_error == 0) + nv->nv_error = ENOMEM; + return; + } + nvh->nvh_type = NV_ORDER_HOST | type; + nvh->nvh_namesize = (uint8_t)namesize; + nvh->nvh_dsize = (uint32_t)vsize; + bcopy(name, nvh->nvh_name, namesize); + + /* Add header first. */ + if (ebuf_add_tail(nv->nv_ebuf, nvh, NVH_HSIZE(nvh)) < 0) { + assert(errno != 0); + if (nv->nv_error == 0) + nv->nv_error = errno; + return; + } + /* Add the actual data. */ + if (ebuf_add_tail(nv->nv_ebuf, value, vsize) < 0) { + assert(errno != 0); + if (nv->nv_error == 0) + nv->nv_error = errno; + return; + } + /* Align the data (if needed). */ + vsize = roundup2(vsize, 8) - vsize; + if (vsize == 0) + return; + assert(vsize > 0 && vsize <= sizeof(align)); + if (ebuf_add_tail(nv->nv_ebuf, align, vsize) < 0) { + assert(errno != 0); + if (nv->nv_error == 0) + nv->nv_error = errno; + return; + } +} + +static void +nv_addv(struct nv *nv, const unsigned char *value, size_t vsize, int type, + const char *namefmt, va_list nameap) +{ + char name[255]; + size_t namesize; + + namesize = vsnprintf(name, sizeof(name), namefmt, nameap); + assert(namesize > 0 && namesize < sizeof(name)); + + nv_add(nv, value, vsize, type, name); +} + +static struct nvhdr * +nv_find(struct nv *nv, int type, const char *namefmt, va_list nameap) +{ + char name[255]; + struct nvhdr *nvh; + unsigned char *ptr; + size_t size, namesize; + + if (nv == NULL) { + errno = ENOMEM; + return (NULL); + } + + NV_CHECK(nv); + + namesize = vsnprintf(name, sizeof(name), namefmt, nameap); + assert(namesize > 0 && namesize < sizeof(name)); + namesize++; + + ptr = ebuf_data(nv->nv_ebuf, &size); + while (size > 0) { + assert(size >= sizeof(*nvh) + 2); + nvh = (struct nvhdr *)ptr; + assert(size >= NVH_SIZE(nvh)); + nv_swap(nvh, true); + if (strcmp(nvh->nvh_name, name) == 0) { + if ((nvh->nvh_type & NV_TYPE_MASK) != type) { + errno = EINVAL; + if (nv->nv_error == 0) + nv->nv_error = EINVAL; + return (NULL); + } + return (nvh); + } + ptr += NVH_SIZE(nvh); + size -= NVH_SIZE(nvh); + } + errno = ENOENT; + if (nv->nv_error == 0) + nv->nv_error = ENOENT; + return (NULL); +} + +static void +nv_swap(struct nvhdr *nvh, bool tohost) +{ + unsigned char *data, *end, *p; + size_t vsize; + + data = NVH_DATA(nvh); + if (tohost) { + if ((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST) + return; + nvh->nvh_dsize = le32toh(nvh->nvh_dsize); + end = data + nvh->nvh_dsize; + nvh->nvh_type &= ~NV_ORDER_MASK; + nvh->nvh_type |= NV_ORDER_HOST; + } else { + if ((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_NETWORK) + return; + end = data + nvh->nvh_dsize; + nvh->nvh_dsize = htole32(nvh->nvh_dsize); + nvh->nvh_type &= ~NV_ORDER_MASK; + nvh->nvh_type |= NV_ORDER_NETWORK; + } + + vsize = 0; + + switch (nvh->nvh_type & NV_TYPE_MASK) { + case NV_TYPE_INT8: + case NV_TYPE_UINT8: + case NV_TYPE_INT8_ARRAY: + case NV_TYPE_UINT8_ARRAY: + break; + case NV_TYPE_INT16: + case NV_TYPE_UINT16: + case NV_TYPE_INT16_ARRAY: + case NV_TYPE_UINT16_ARRAY: + if (vsize == 0) + vsize = 2; + /* FALLTHOUGH */ + case NV_TYPE_INT32: + case NV_TYPE_UINT32: + case NV_TYPE_INT32_ARRAY: + case NV_TYPE_UINT32_ARRAY: + if (vsize == 0) + vsize = 4; + /* FALLTHOUGH */ + case NV_TYPE_INT64: + case NV_TYPE_UINT64: + case NV_TYPE_INT64_ARRAY: + case NV_TYPE_UINT64_ARRAY: + if (vsize == 0) + vsize = 8; + for (p = data; p < end; p += vsize) { + if (tohost) { + switch (vsize) { + case 2: + *(uint16_t *)(void *)p = + le16toh(*(uint16_t *)(void *)p); + break; + case 4: + *(uint32_t *)(void *)p = + le32toh(*(uint32_t *)(void *)p); + break; + case 8: + *(uint64_t *)(void *)p = + le64toh(*(uint64_t *)(void *)p); + break; + default: + assert(!"invalid condition"); + } + } else { + switch (vsize) { + case 2: + *(uint16_t *)(void *)p = + htole16(*(uint16_t *)(void *)p); + break; + case 4: + *(uint32_t *)(void *)p = + htole32(*(uint32_t *)(void *)p); + break; + case 8: + *(uint64_t *)(void *)p = + htole64(*(uint64_t *)(void *)p); + break; + default: + assert(!"invalid condition"); + } + } + } + break; + case NV_TYPE_STRING: + break; + default: + assert(!"unrecognized type"); + } +} diff --git a/sbin/hastd/nv.h b/sbin/hastd/nv.h new file mode 100644 index 00000000000..16775480b02 --- /dev/null +++ b/sbin/hastd/nv.h @@ -0,0 +1,158 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _NV_H_ +#define _NV_H_ + +#include + +#include +#include +#include +#include + +#include + +#define NV_TYPE_INT8 1 +#define NV_TYPE_UINT8 2 +#define NV_TYPE_INT16 3 +#define NV_TYPE_UINT16 4 +#define NV_TYPE_INT32 5 +#define NV_TYPE_UINT32 6 +#define NV_TYPE_INT64 7 +#define NV_TYPE_UINT64 8 +#define NV_TYPE_INT8_ARRAY 9 +#define NV_TYPE_UINT8_ARRAY 10 +#define NV_TYPE_INT16_ARRAY 11 +#define NV_TYPE_UINT16_ARRAY 12 +#define NV_TYPE_INT32_ARRAY 13 +#define NV_TYPE_UINT32_ARRAY 14 +#define NV_TYPE_INT64_ARRAY 15 +#define NV_TYPE_UINT64_ARRAY 16 +#define NV_TYPE_STRING 17 + +#define NV_TYPE_MASK 0x7f +#define NV_TYPE_FIRST NV_TYPE_INT8 +#define NV_TYPE_LAST NV_TYPE_STRING + +#define NV_ORDER_NETWORK 0x00 +#define NV_ORDER_HOST 0x80 + +#define NV_ORDER_MASK 0x80 + +struct nv; + +struct nv *nv_alloc(void); +void nv_free(struct nv *nv); +int nv_error(const struct nv *nv); +int nv_set_error(struct nv *nv, int error); +int nv_validate(struct nv *nv, size_t *extrap); + +struct ebuf *nv_hton(struct nv *nv); +struct nv *nv_ntoh(struct ebuf *eb); + +void nv_add_int8(struct nv *nv, int8_t value, const char *namefmt, ...) + __printflike(3, 4); +void nv_add_uint8(struct nv *nv, uint8_t value, const char *namefmt, ...) + __printflike(3, 4); +void nv_add_int16(struct nv *nv, int16_t value, const char *namefmt, ...) + __printflike(3, 4); +void nv_add_uint16(struct nv *nv, uint16_t value, const char *namefmt, ...) + __printflike(3, 4); +void nv_add_int32(struct nv *nv, int32_t value, const char *namefmt, ...) + __printflike(3, 4); +void nv_add_uint32(struct nv *nv, uint32_t value, const char *namefmt, ...) + __printflike(3, 4); +void nv_add_int64(struct nv *nv, int64_t value, const char *namefmt, ...) + __printflike(3, 4); +void nv_add_uint64(struct nv *nv, uint64_t value, const char *namefmt, ...) + __printflike(3, 4); +void nv_add_int8_array(struct nv *nv, const int8_t *value, size_t size, + const char *namefmt, ...) __printflike(4, 5); +void nv_add_uint8_array(struct nv *nv, const uint8_t *value, size_t size, + const char *namefmt, ...) __printflike(4, 5); +void nv_add_int16_array(struct nv *nv, const int16_t *value, size_t size, + const char *namefmt, ...) __printflike(4, 5); +void nv_add_uint16_array(struct nv *nv, const uint16_t *value, size_t size, + const char *namefmt, ...) __printflike(4, 5); +void nv_add_int32_array(struct nv *nv, const int32_t *value, size_t size, + const char *namefmt, ...) __printflike(4, 5); +void nv_add_uint32_array(struct nv *nv, const uint32_t *value, size_t size, + const char *namefmt, ...) __printflike(4, 5); +void nv_add_int64_array(struct nv *nv, const int64_t *value, size_t size, + const char *namefmt, ...) __printflike(4, 5); +void nv_add_uint64_array(struct nv *nv, const uint64_t *value, size_t size, + const char *namefmt, ...) __printflike(4, 5); +void nv_add_string(struct nv *nv, const char *value, const char *namefmt, ...) + __printflike(3, 4); +void nv_add_stringf(struct nv *nv, const char *name, const char *valuefmt, ...) + __printflike(3, 4); +void nv_add_stringv(struct nv *nv, const char *name, const char *valuefmt, + va_list valueap) __printflike(3, 0); + +int8_t nv_get_int8(struct nv *nv, const char *namefmt, ...) + __printflike(2, 3); +uint8_t nv_get_uint8(struct nv *nv, const char *namefmt, ...) + __printflike(2, 3); +int16_t nv_get_int16(struct nv *nv, const char *namefmt, ...) + __printflike(2, 3); +uint16_t nv_get_uint16(struct nv *nv, const char *namefmt, ...) + __printflike(2, 3); +int32_t nv_get_int32(struct nv *nv, const char *namefmt, ...) + __printflike(2, 3); +uint32_t nv_get_uint32(struct nv *nv, const char *namefmt, ...) + __printflike(2, 3); +int64_t nv_get_int64(struct nv *nv, const char *namefmt, ...) + __printflike(2, 3); +uint64_t nv_get_uint64(struct nv *nv, const char *namefmt, ...) + __printflike(2, 3); +const int8_t *nv_get_int8_array(struct nv *nv, size_t *sizep, + const char *namefmt, ...) __printflike(3, 4); +const uint8_t *nv_get_uint8_array(struct nv *nv, size_t *sizep, + const char *namefmt, ...) __printflike(3, 4); +const int16_t *nv_get_int16_array(struct nv *nv, size_t *sizep, + const char *namefmt, ...) __printflike(3, 4); +const uint16_t *nv_get_uint16_array(struct nv *nv, size_t *sizep, + const char *namefmt, ...) __printflike(3, 4); +const int32_t *nv_get_int32_array(struct nv *nv, size_t *sizep, + const char *namefmt, ...) __printflike(3, 4); +const uint32_t *nv_get_uint32_array(struct nv *nv, size_t *sizep, + const char *namefmt, ...) __printflike(3, 4); +const int64_t *nv_get_int64_array(struct nv *nv, size_t *sizep, + const char *namefmt, ...) __printflike(3, 4); +const uint64_t *nv_get_uint64_array(struct nv *nv, size_t *sizep, + const char *namefmt, ...) __printflike(3, 4); +const char *nv_get_string(struct nv *nv, const char *namefmt, ...) + __printflike(2, 3); + +void nv_dump(struct nv *nv); + +#endif /* !_NV_H_ */ diff --git a/sbin/hastd/parse.y b/sbin/hastd/parse.y new file mode 100644 index 00000000000..67553208ac6 --- /dev/null +++ b/sbin/hastd/parse.y @@ -0,0 +1,507 @@ +%{ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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$ + */ + +#include /* MAXHOSTNAMELEN */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "hast.h" + +extern int depth; +extern int lineno; + +extern FILE *yyin; +extern char *yytext; + +static struct hastd_config lconfig; +static struct hast_resource *curres; +static bool mynode; + +static char depth0_control[HAST_ADDRSIZE]; +static char depth0_listen[HAST_ADDRSIZE]; +static int depth0_replication; + +static char depth1_provname[PATH_MAX]; +static char depth1_localpath[PATH_MAX]; + +static bool +isitme(const char *name) +{ + char buf[MAXHOSTNAMELEN]; + char *pos; + size_t bufsize; + + /* + * First check if the give name matches our full hostname. + */ + if (gethostname(buf, sizeof(buf)) < 0) + err(EX_OSERR, "gethostname() failed"); + if (strcmp(buf, name) == 0) + return (true); + + /* + * Now check if it matches first part of the host name. + */ + pos = strchr(buf, '.'); + if (pos != NULL && pos != buf && strncmp(buf, name, pos - buf) == 0) + return (true); + + /* + * At the end check if name is equal to our host's UUID. + */ + bufsize = sizeof(buf); + if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) + err(EX_OSERR, "sysctlbyname(kern.hostuuid) failed"); + if (strcasecmp(buf, name) == 0) + return (true); + + /* + * Looks like this isn't about us. + */ + return (false); +} + +void +yyerror(const char *str) +{ + + fprintf(stderr, "error at line %d near '%s': %s\n", + lineno, yytext, str); +} + +struct hastd_config * +yy_config_parse(const char *config) +{ + int ret; + + curres = NULL; + mynode = false; + + depth0_replication = HAST_REPLICATION_MEMSYNC; + strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); + strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen)); + + TAILQ_INIT(&lconfig.hc_resources); + + yyin = fopen(config, "r"); + if (yyin == NULL) + err(EX_OSFILE, "cannot open configuration file %s", config); + ret = yyparse(); + fclose(yyin); + if (ret != 0) { + yy_config_free(&lconfig); + exit(EX_CONFIG); + } + + /* + * Let's see if everything is set up. + */ + if (lconfig.hc_controladdr[0] == '\0') { + strlcpy(lconfig.hc_controladdr, depth0_control, + sizeof(lconfig.hc_controladdr)); + } + if (lconfig.hc_listenaddr[0] == '\0') { + strlcpy(lconfig.hc_listenaddr, depth0_listen, + sizeof(lconfig.hc_listenaddr)); + } + TAILQ_FOREACH(curres, &lconfig.hc_resources, hr_next) { + assert(curres->hr_provname[0] != '\0'); + assert(curres->hr_localpath[0] != '\0'); + assert(curres->hr_remoteaddr[0] != '\0'); + + if (curres->hr_replication == -1) { + /* + * Replication is not set at resource-level. + * Use global or default setting. + */ + curres->hr_replication = depth0_replication; + } + } + + return (&lconfig); +} + +void +yy_config_free(struct hastd_config *config) +{ + struct hast_resource *res; + + while ((res = TAILQ_FIRST(&config->hc_resources)) != NULL) { + TAILQ_REMOVE(&config->hc_resources, res, hr_next); + free(res); + } +} +%} + +%token CONTROL LISTEN PORT REPLICATION EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON +%token FULLSYNC MEMSYNC ASYNC +%token NUM STR OB CB + +%type replication_type + +%union +{ + int num; + char *str; +} + +%token NUM +%token STR + +%% + +statements: + | + statements statement + ; + +statement: + control_statement + | + listen_statement + | + replication_statement + | + node_statement + | + resource_statement + ; + +control_statement: CONTROL STR + { + switch (depth) { + case 0: + if (strlcpy(depth0_control, $2, + sizeof(depth0_control)) >= + sizeof(depth0_control)) { + errx(EX_CONFIG, "control argument too long"); + } + break; + case 1: + if (mynode) { + if (strlcpy(lconfig.hc_controladdr, $2, + sizeof(lconfig.hc_controladdr)) >= + sizeof(lconfig.hc_controladdr)) { + errx(EX_CONFIG, + "control argument too long"); + } + } + break; + default: + assert(!"control at wrong depth level"); + } + } + ; + +listen_statement: LISTEN STR + { + switch (depth) { + case 0: + if (strlcpy(depth0_listen, $2, + sizeof(depth0_listen)) >= + sizeof(depth0_listen)) { + errx(EX_CONFIG, "listen argument too long"); + } + break; + case 1: + if (mynode) { + if (strlcpy(lconfig.hc_listenaddr, $2, + sizeof(lconfig.hc_listenaddr)) >= + sizeof(lconfig.hc_listenaddr)) { + errx(EX_CONFIG, + "listen argument too long"); + } + } + break; + default: + assert(!"listen at wrong depth level"); + } + } + ; + +replication_statement: REPLICATION replication_type + { + switch (depth) { + case 0: + depth0_replication = $2; + break; + case 1: + if (curres != NULL) + curres->hr_replication = $2; + break; + default: + assert(!"replication at wrong depth level"); + } + } + ; + +replication_type: + FULLSYNC { $$ = HAST_REPLICATION_FULLSYNC; } + | + MEMSYNC { $$ = HAST_REPLICATION_MEMSYNC; } + | + ASYNC { $$ = HAST_REPLICATION_ASYNC; } + ; + +node_statement: ON node_start OB node_entries CB + { + mynode = false; + } + ; + +node_start: STR + { + if (isitme($1)) + mynode = true; + } + ; + +node_entries: + | + node_entries node_entry + ; + +node_entry: + control_statement + | + listen_statement + ; + +resource_statement: RESOURCE resource_start OB resource_entries CB + { + if (curres != NULL) { + /* + * Let's see there are some resource-level settings + * that we can use for node-level settings. + */ + if (curres->hr_provname[0] == '\0' && + depth1_provname[0] != '\0') { + /* + * Provider name is not set at node-level, + * but is set at resource-level, use it. + */ + strlcpy(curres->hr_provname, depth1_provname, + sizeof(curres->hr_provname)); + } + if (curres->hr_localpath[0] == '\0' && + depth1_localpath[0] != '\0') { + /* + * Path to local provider is not set at + * node-level, but is set at resource-level, + * use it. + */ + strlcpy(curres->hr_localpath, depth1_localpath, + sizeof(curres->hr_localpath)); + } + + /* + * If provider name is not given, use resource name + * as provider name. + */ + if (curres->hr_provname[0] == '\0') { + strlcpy(curres->hr_provname, curres->hr_name, + sizeof(curres->hr_provname)); + } + + /* + * Remote address has to be configured at this point. + */ + if (curres->hr_remoteaddr[0] == '\0') { + errx(EX_CONFIG, + "remote address not configured for resource %s", + curres->hr_name); + } + /* + * Path to local provider has to be configured at this + * point. + */ + if (curres->hr_localpath[0] == '\0') { + errx(EX_CONFIG, + "path local component not configured for resource %s", + curres->hr_name); + } + + /* Put it onto resource list. */ + TAILQ_INSERT_TAIL(&lconfig.hc_resources, curres, hr_next); + curres = NULL; + } + } + ; + +resource_start: STR + { + /* + * Clear those, so we can tell if they were set at + * resource-level or not. + */ + depth1_provname[0] = '\0'; + depth1_localpath[0] = '\0'; + + curres = calloc(1, sizeof(*curres)); + if (curres == NULL) { + errx(EX_TEMPFAIL, + "cannot allocate memory for resource"); + } + if (strlcpy(curres->hr_name, $1, + sizeof(curres->hr_name)) >= + sizeof(curres->hr_name)) { + errx(EX_CONFIG, + "resource name (%s) too long", $1); + } + curres->hr_role = HAST_ROLE_INIT; + curres->hr_previous_role = HAST_ROLE_INIT; + curres->hr_replication = -1; + curres->hr_provname[0] = '\0'; + curres->hr_localpath[0] = '\0'; + curres->hr_localfd = -1; + curres->hr_remoteaddr[0] = '\0'; + curres->hr_ggateunit = -1; + } + ; + +resource_entries: + | + resource_entries resource_entry + ; + +resource_entry: + replication_statement + | + name_statement + | + local_statement + | + resource_node_statement + ; + +name_statement: NAME STR + { + switch (depth) { + case 1: + if (strlcpy(depth1_provname, $2, + sizeof(depth1_provname)) >= + sizeof(depth1_provname)) { + errx(EX_CONFIG, "name argument too long"); + } + break; + case 2: + if (mynode) { + assert(curres != NULL); + if (strlcpy(curres->hr_provname, $2, + sizeof(curres->hr_provname)) >= + sizeof(curres->hr_provname)) { + errx(EX_CONFIG, + "name argument too long"); + } + } + break; + default: + assert(!"name at wrong depth level"); + } + } + ; + +local_statement: LOCAL STR + { + switch (depth) { + case 1: + if (strlcpy(depth1_localpath, $2, + sizeof(depth1_localpath)) >= + sizeof(depth1_localpath)) { + errx(EX_CONFIG, "local argument too long"); + } + break; + case 2: + if (mynode) { + assert(curres != NULL); + if (strlcpy(curres->hr_localpath, $2, + sizeof(curres->hr_localpath)) >= + sizeof(curres->hr_localpath)) { + errx(EX_CONFIG, + "local argument too long"); + } + } + break; + default: + assert(!"local at wrong depth level"); + } + } + ; + +resource_node_statement:ON resource_node_start OB resource_node_entries CB + { + mynode = false; + } + ; + +resource_node_start: STR + { + if (curres != NULL && isitme($1)) + mynode = true; + } + ; + +resource_node_entries: + | + resource_node_entries resource_node_entry + ; + +resource_node_entry: + name_statement + | + local_statement + | + remote_statement + ; + +remote_statement: REMOTE STR + { + assert(depth == 2); + if (mynode) { + assert(curres != NULL); + if (strlcpy(curres->hr_remoteaddr, $2, + sizeof(curres->hr_remoteaddr)) >= + sizeof(curres->hr_remoteaddr)) { + errx(EX_CONFIG, "remote argument too long"); + } + } + } + ; diff --git a/sbin/hastd/pjdlog.c b/sbin/hastd/pjdlog.c new file mode 100644 index 00000000000..38c5539ad0c --- /dev/null +++ b/sbin/hastd/pjdlog.c @@ -0,0 +1,367 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include "pjdlog.h" + +static int pjdlog_mode = PJDLOG_MODE_STD; +static int pjdlog_debug_level = 0; +static char pjdlog_prefix[128]; + +/* + * Configure where the logs should go. + * By default they are send to stdout/stderr, but after going into background + * (eg. by calling daemon(3)) application is responsible for changing mode to + * PJDLOG_MODE_SYSLOG, so logs will be send to syslog. + */ +void +pjdlog_mode_set(int mode) +{ + + assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG); + + pjdlog_mode = mode; +} + +/* + * Return current mode. + */ +int +pjdlog_mode_get(void) +{ + + return (pjdlog_mode); +} + +/* + * Set debug level. All the logs above the level specified here will be + * ignored. + */ +void +pjdlog_debug_set(int level) +{ + + assert(level >= 0); + + pjdlog_debug_level = level; +} + +/* + * Return current debug level. + */ +int +pjdlog_debug_get(void) +{ + + return (pjdlog_debug_level); +} + +/* + * Set prefix that will be used before each log. + * Setting prefix to NULL will remove it. + */ +void +pjdlog_prefix_set(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + pjdlog_prefix_setv(fmt, ap); + va_end(ap); +} + +/* + * Set prefix that will be used before each log. + * Setting prefix to NULL will remove it. + */ +void +pjdlog_prefix_setv(const char *fmt, va_list ap) +{ + + assert(fmt != NULL); + + vsnprintf(pjdlog_prefix, sizeof(pjdlog_prefix), fmt, ap); +} + +/* + * Convert log level into string. + */ +static const char * +pjdlog_level_string(int loglevel) +{ + + switch (loglevel) { + case LOG_EMERG: + return ("EMERG"); + case LOG_ALERT: + return ("ALERT"); + case LOG_CRIT: + return ("CRIT"); + case LOG_ERR: + return ("ERROR"); + case LOG_WARNING: + return ("WARNING"); + case LOG_NOTICE: + return ("NOTICE"); + case LOG_INFO: + return ("INFO"); + case LOG_DEBUG: + return ("DEBUG"); + } + assert(!"Invalid log level."); + abort(); /* XXX: gcc */ +} + +/* + * Common log routine. + */ +void +pjdlog_common(int loglevel, int debuglevel, int error, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + pjdlogv_common(loglevel, debuglevel, error, fmt, ap); + va_end(ap); +} + +/* + * Common log routine, which can handle regular log level as well as debug + * level. We decide here where to send the logs (stdout/stderr or syslog). + */ +void +pjdlogv_common(int loglevel, int debuglevel, int error, const char *fmt, + va_list ap) +{ + + assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT || + loglevel == LOG_CRIT || loglevel == LOG_ERR || + loglevel == LOG_WARNING || loglevel == LOG_NOTICE || + loglevel == LOG_INFO || loglevel == LOG_DEBUG); + assert(loglevel != LOG_DEBUG || debuglevel > 0); + assert(error >= -1); + + /* Ignore debug above configured level. */ + if (loglevel == LOG_DEBUG && debuglevel > pjdlog_debug_level) + return; + + switch (pjdlog_mode) { + case PJDLOG_MODE_STD: + { + FILE *out; + + /* + * We send errors and warning to stderr and the rest to stdout. + */ + switch (loglevel) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + case LOG_WARNING: + out = stderr; + break; + case LOG_NOTICE: + case LOG_INFO: + case LOG_DEBUG: + out = stdout; + break; + default: + assert(!"Invalid loglevel."); + abort(); /* XXX: gcc */ + } + + fprintf(out, "[%s]", pjdlog_level_string(loglevel)); + /* Attach debuglevel if this is debug log. */ + if (loglevel == LOG_DEBUG) + fprintf(out, "[%d]", debuglevel); + fprintf(out, " "); + fprintf(out, "%s", pjdlog_prefix); + vfprintf(out, fmt, ap); + if (error != -1) + fprintf(out, ": %s.", strerror(error)); + fprintf(out, "\n"); + break; + } + case PJDLOG_MODE_SYSLOG: + { + char log[1024]; + int len; + + len = snprintf(log, sizeof(log), "%s", pjdlog_prefix); + if ((size_t)len < sizeof(log)) + len = vsnprintf(log + len, sizeof(log) - len, fmt, ap); + if (error != -1 && (size_t)len < sizeof(log)) { + (void)snprintf(log + len, sizeof(log) - len, ": %s.", + strerror(error)); + } + syslog(loglevel, "%s", log); + break; + } + default: + assert(!"Invalid mode."); + } +} + +/* + * Regular logs. + */ +void +pjdlogv(int loglevel, const char *fmt, va_list ap) +{ + + /* LOG_DEBUG is invalid here, pjdlogv?_debug() should be used. */ + assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT || + loglevel == LOG_CRIT || loglevel == LOG_ERR || + loglevel == LOG_WARNING || loglevel == LOG_NOTICE || + loglevel == LOG_INFO); + + pjdlogv_common(loglevel, 0, -1, fmt, ap); +} + +/* + * Regular logs. + */ +void +pjdlog(int loglevel, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + pjdlogv(loglevel, fmt, ap); + va_end(ap); +} + +/* + * Debug logs. + */ +void +pjdlogv_debug(int debuglevel, const char *fmt, va_list ap) +{ + + pjdlogv_common(LOG_DEBUG, debuglevel, -1, fmt, ap); +} + +/* + * Debug logs. + */ +void +pjdlog_debug(int debuglevel, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + pjdlogv_debug(debuglevel, fmt, ap); + va_end(ap); +} + +/* + * Error logs with errno logging. + */ +void +pjdlogv_errno(int loglevel, const char *fmt, va_list ap) +{ + + pjdlogv_common(loglevel, 0, errno, fmt, ap); +} + +/* + * Error logs with errno logging. + */ +void +pjdlog_errno(int loglevel, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + pjdlogv_errno(loglevel, fmt, ap); + va_end(ap); +} + +/* + * Log error, errno and exit. + */ +void +pjdlogv_exit(int exitcode, const char *fmt, va_list ap) +{ + + pjdlogv_errno(LOG_ERR, fmt, ap); + exit(exitcode); +} + +/* + * Log error, errno and exit. + */ +void +pjdlog_exit(int exitcode, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + pjdlogv_exit(exitcode, fmt, ap); + /* NOTREACHED */ + va_end(ap); +} + +/* + * Log error and exit. + */ +void +pjdlogv_exitx(int exitcode, const char *fmt, va_list ap) +{ + + pjdlogv(LOG_ERR, fmt, ap); + exit(exitcode); +} + +/* + * Log error and exit. + */ +void +pjdlog_exitx(int exitcode, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + pjdlogv_exitx(exitcode, fmt, ap); + /* NOTREACHED */ + va_end(ap); +} diff --git a/sbin/hastd/pjdlog.h b/sbin/hastd/pjdlog.h new file mode 100644 index 00000000000..2136b12f42a --- /dev/null +++ b/sbin/hastd/pjdlog.h @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _PJDLOG_H_ +#define _PJDLOG_H_ + +#include + +#include +#include +#include + +#define PJDLOG_MODE_STD 0 +#define PJDLOG_MODE_SYSLOG 1 + +void pjdlog_mode_set(int mode); +int pjdlog_mode_get(void); + +void pjdlog_debug_set(int level); +int pjdlog_debug_get(void); + +void pjdlog_prefix_set(const char *fmt, ...) __printflike(1, 2); +void pjdlog_prefix_setv(const char *fmt, va_list ap) __printflike(1, 0); + +void pjdlog_common(int loglevel, int debuglevel, int error, const char *fmt, + ...) __printflike(4, 5); +void pjdlogv_common(int loglevel, int debuglevel, int error, const char *fmt, + va_list ap) __printflike(4, 0); + +void pjdlog(int loglevel, const char *fmt, ...) __printflike(2, 3); +void pjdlogv(int loglevel, const char *fmt, va_list ap) __printflike(2, 0); + +#define pjdlogv_emergency(fmt, ap) pjdlogv(LOG_EMERG, (fmt), (ap)) +#define pjdlog_emergency(...) pjdlog(LOG_EMERG, __VA_ARGS__) +#define pjdlogv_alert(fmt, ap) pjdlogv(LOG_ALERT, (fmt), (ap)) +#define pjdlog_alert(...) pjdlog(LOG_ALERT, __VA_ARGS__) +#define pjdlogv_critical(fmt, ap) pjdlogv(LOG_CRIT, (fmt), (ap)) +#define pjdlog_critical(...) pjdlog(LOG_CRIT, __VA_ARGS__) +#define pjdlogv_error(fmt, ap) pjdlogv(LOG_ERR, (fmt), (ap)) +#define pjdlog_error(...) pjdlog(LOG_ERR, __VA_ARGS__) +#define pjdlogv_warning(fmt, ap) pjdlogv(LOG_WARNING, (fmt), (ap)) +#define pjdlog_warning(...) pjdlog(LOG_WARNING, __VA_ARGS__) +#define pjdlogv_notice(fmt, ap) pjdlogv(LOG_NOTICE, (fmt), (ap)) +#define pjdlog_notice(...) pjdlog(LOG_NOTICE, __VA_ARGS__) +#define pjdlogv_info(fmt, ap) pjdlogv(LOG_INFO, (fmt), (ap)) +#define pjdlog_info(...) pjdlog(LOG_INFO, __VA_ARGS__) + +void pjdlog_debug(int debuglevel, const char *fmt, ...) __printflike(2, 3); +void pjdlogv_debug(int debuglevel, const char *fmt, va_list ap) __printflike(2, 0); + +void pjdlog_errno(int loglevel, const char *fmt, ...) __printflike(2, 3); +void pjdlogv_errno(int loglevel, const char *fmt, va_list ap) __printflike(2, 0); + +void pjdlog_exit(int exitcode, const char *fmt, ...) __printflike(2, 3) __dead2; +void pjdlogv_exit(int exitcode, const char *fmt, va_list ap) __printflike(2, 0) __dead2; + +void pjdlog_exitx(int exitcode, const char *fmt, ...) __printflike(2, 3) __dead2; +void pjdlogv_exitx(int exitcode, const char *fmt, va_list ap) __printflike(2, 0) __dead2; + +#endif /* !_PJDLOG_H_ */ diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c new file mode 100644 index 00000000000..ed6e91ca8b8 --- /dev/null +++ b/sbin/hastd/primary.c @@ -0,0 +1,1769 @@ +/*- + * Copyright (c) 2009 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 +#include + +#include "control.h" +#include "hast.h" +#include "hast_proto.h" +#include "hastd.h" +#include "metadata.h" +#include "proto.h" +#include "pjdlog.h" +#include "subr.h" +#include "synch.h" + +struct hio { + /* + * Number of components we are still waiting for. + * When this field goes to 0, we can send the request back to the + * kernel. Each component has to decrease this counter by one + * even on failure. + */ + unsigned int hio_countdown; + /* + * Each component has a place to store its own error. + * Once the request is handled by all components we can decide if the + * request overall is successful or not. + */ + int *hio_errors; + /* + * Structure used to comunicate with GEOM Gate class. + */ + struct g_gate_ctl_io hio_ggio; + TAILQ_ENTRY(hio) *hio_next; +}; +#define hio_free_next hio_next[0] +#define hio_done_next hio_next[0] + +/* + * Free list holds unused structures. When free list is empty, we have to wait + * until some in-progress requests are freed. + */ +static TAILQ_HEAD(, hio) hio_free_list; +static pthread_mutex_t hio_free_list_lock; +static pthread_cond_t hio_free_list_cond; +/* + * There is one send list for every component. One requests is placed on all + * send lists - each component gets the same request, but each component is + * responsible for managing his own send list. + */ +static TAILQ_HEAD(, hio) *hio_send_list; +static pthread_mutex_t *hio_send_list_lock; +static pthread_cond_t *hio_send_list_cond; +/* + * There is one recv list for every component, although local components don't + * use recv lists as local requests are done synchronously. + */ +static TAILQ_HEAD(, hio) *hio_recv_list; +static pthread_mutex_t *hio_recv_list_lock; +static pthread_cond_t *hio_recv_list_cond; +/* + * Request is placed on done list by the slowest component (the one that + * decreased hio_countdown from 1 to 0). + */ +static TAILQ_HEAD(, hio) hio_done_list; +static pthread_mutex_t hio_done_list_lock; +static pthread_cond_t hio_done_list_cond; +/* + * Structure below are for interaction with sync thread. + */ +static bool sync_inprogress; +static pthread_mutex_t sync_lock; +static pthread_cond_t sync_cond; +/* + * The lock below allows to synchornize access to remote connections. + */ +static pthread_rwlock_t *hio_remote_lock; +static pthread_mutex_t hio_guard_lock; +static pthread_cond_t hio_guard_cond; + +/* + * Lock to synchronize metadata updates. Also synchronize access to + * hr_primary_localcnt and hr_primary_remotecnt fields. + */ +static pthread_mutex_t metadata_lock; + +/* + * Maximum number of outstanding I/O requests. + */ +#define HAST_HIO_MAX 256 +/* + * Number of components. At this point there are only two components: local + * and remote, but in the future it might be possible to use multiple local + * and remote components. + */ +#define HAST_NCOMPONENTS 2 +/* + * Number of seconds to sleep before next reconnect try. + */ +#define RECONNECT_SLEEP 5 + +#define ISCONNECTED(res, no) \ + ((res)->hr_remotein != NULL && (res)->hr_remoteout != NULL) + +#define QUEUE_INSERT1(hio, name, ncomp) do { \ + bool _wakeup; \ + \ + mtx_lock(&hio_##name##_list_lock[(ncomp)]); \ + _wakeup = TAILQ_EMPTY(&hio_##name##_list[(ncomp)]); \ + TAILQ_INSERT_TAIL(&hio_##name##_list[(ncomp)], (hio), \ + hio_next[(ncomp)]); \ + mtx_unlock(&hio_##name##_list_lock[ncomp]); \ + if (_wakeup) \ + cv_signal(&hio_##name##_list_cond[(ncomp)]); \ +} while (0) +#define QUEUE_INSERT2(hio, name) do { \ + bool _wakeup; \ + \ + mtx_lock(&hio_##name##_list_lock); \ + _wakeup = TAILQ_EMPTY(&hio_##name##_list); \ + TAILQ_INSERT_TAIL(&hio_##name##_list, (hio), hio_##name##_next);\ + mtx_unlock(&hio_##name##_list_lock); \ + if (_wakeup) \ + cv_signal(&hio_##name##_list_cond); \ +} while (0) +#define QUEUE_TAKE1(hio, name, ncomp) do { \ + mtx_lock(&hio_##name##_list_lock[(ncomp)]); \ + while (((hio) = TAILQ_FIRST(&hio_##name##_list[(ncomp)])) == NULL) { \ + cv_wait(&hio_##name##_list_cond[(ncomp)], \ + &hio_##name##_list_lock[(ncomp)]); \ + } \ + TAILQ_REMOVE(&hio_##name##_list[(ncomp)], (hio), \ + hio_next[(ncomp)]); \ + mtx_unlock(&hio_##name##_list_lock[(ncomp)]); \ +} while (0) +#define QUEUE_TAKE2(hio, name) do { \ + mtx_lock(&hio_##name##_list_lock); \ + while (((hio) = TAILQ_FIRST(&hio_##name##_list)) == NULL) { \ + cv_wait(&hio_##name##_list_cond, \ + &hio_##name##_list_lock); \ + } \ + TAILQ_REMOVE(&hio_##name##_list, (hio), hio_##name##_next); \ + mtx_unlock(&hio_##name##_list_lock); \ +} while (0) + +#define SYNCREQ(hio) do { (hio)->hio_ggio.gctl_unit = -1; } while (0) +#define ISSYNCREQ(hio) ((hio)->hio_ggio.gctl_unit == -1) +#define SYNCREQDONE(hio) do { (hio)->hio_ggio.gctl_unit = -2; } while (0) +#define ISSYNCREQDONE(hio) ((hio)->hio_ggio.gctl_unit == -2) + +static struct hast_resource *gres; + +static pthread_mutex_t range_lock; +static struct rangelocks *range_regular; +static bool range_regular_wait; +static pthread_cond_t range_regular_cond; +static struct rangelocks *range_sync; +static bool range_sync_wait; +static pthread_cond_t range_sync_cond; + +static void *ggate_recv_thread(void *arg); +static void *local_send_thread(void *arg); +static void *remote_send_thread(void *arg); +static void *remote_recv_thread(void *arg); +static void *ggate_send_thread(void *arg); +static void *sync_thread(void *arg); +static void *guard_thread(void *arg); + +static void sighandler(int sig); + +static void +cleanup(struct hast_resource *res) +{ + int rerrno; + + /* Remember errno. */ + rerrno = errno; + + /* + * Close descriptor to /dev/hast/ + * to work-around race in the kernel. + */ + close(res->hr_localfd); + + /* Destroy ggate provider if we created one. */ + if (res->hr_ggateunit >= 0) { + struct g_gate_ctl_destroy ggiod; + + ggiod.gctl_version = G_GATE_VERSION; + ggiod.gctl_unit = res->hr_ggateunit; + ggiod.gctl_force = 1; + if (ioctl(res->hr_ggatefd, G_GATE_CMD_DESTROY, &ggiod) < 0) { + pjdlog_warning("Unable to destroy hast/%s device", + res->hr_provname); + } + res->hr_ggateunit = -1; + } + + /* Restore errno. */ + errno = rerrno; +} + +static void +primary_exit(int exitcode, const char *fmt, ...) +{ + va_list ap; + + assert(exitcode != EX_OK); + va_start(ap, fmt); + pjdlogv_errno(LOG_ERR, fmt, ap); + va_end(ap); + cleanup(gres); + exit(exitcode); +} + +static void +primary_exitx(int exitcode, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + pjdlogv(exitcode == EX_OK ? LOG_INFO : LOG_ERR, fmt, ap); + va_end(ap); + cleanup(gres); + exit(exitcode); +} + +static int +hast_activemap_flush(struct hast_resource *res) +{ + const unsigned char *buf; + size_t size; + + buf = activemap_bitmap(res->hr_amp, &size); + assert(buf != NULL); + assert((size % res->hr_local_sectorsize) == 0); + if (pwrite(res->hr_localfd, buf, size, METADATA_SIZE) != + (ssize_t)size) { + KEEP_ERRNO(pjdlog_errno(LOG_ERR, + "Unable to flush activemap to disk")); + return (-1); + } + return (0); +} + +static void +init_environment(struct hast_resource *res __unused) +{ + struct hio *hio; + unsigned int ii, ncomps; + + /* + * In the future it might be per-resource value. + */ + ncomps = HAST_NCOMPONENTS; + + /* + * Allocate memory needed by lists. + */ + hio_send_list = malloc(sizeof(hio_send_list[0]) * ncomps); + if (hio_send_list == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate %zu bytes of memory for send lists.", + sizeof(hio_send_list[0]) * ncomps); + } + hio_send_list_lock = malloc(sizeof(hio_send_list_lock[0]) * ncomps); + if (hio_send_list_lock == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate %zu bytes of memory for send list locks.", + sizeof(hio_send_list_lock[0]) * ncomps); + } + hio_send_list_cond = malloc(sizeof(hio_send_list_cond[0]) * ncomps); + if (hio_send_list_cond == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate %zu bytes of memory for send list condition variables.", + sizeof(hio_send_list_cond[0]) * ncomps); + } + hio_recv_list = malloc(sizeof(hio_recv_list[0]) * ncomps); + if (hio_recv_list == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate %zu bytes of memory for recv lists.", + sizeof(hio_recv_list[0]) * ncomps); + } + hio_recv_list_lock = malloc(sizeof(hio_recv_list_lock[0]) * ncomps); + if (hio_recv_list_lock == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate %zu bytes of memory for recv list locks.", + sizeof(hio_recv_list_lock[0]) * ncomps); + } + hio_recv_list_cond = malloc(sizeof(hio_recv_list_cond[0]) * ncomps); + if (hio_recv_list_cond == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate %zu bytes of memory for recv list condition variables.", + sizeof(hio_recv_list_cond[0]) * ncomps); + } + hio_remote_lock = malloc(sizeof(hio_remote_lock[0]) * ncomps); + if (hio_remote_lock == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate %zu bytes of memory for remote connections locks.", + sizeof(hio_remote_lock[0]) * ncomps); + } + + /* + * Initialize lists, their locks and theirs condition variables. + */ + TAILQ_INIT(&hio_free_list); + mtx_init(&hio_free_list_lock); + cv_init(&hio_free_list_cond); + for (ii = 0; ii < HAST_NCOMPONENTS; ii++) { + TAILQ_INIT(&hio_send_list[ii]); + mtx_init(&hio_send_list_lock[ii]); + cv_init(&hio_send_list_cond[ii]); + TAILQ_INIT(&hio_recv_list[ii]); + mtx_init(&hio_recv_list_lock[ii]); + cv_init(&hio_recv_list_cond[ii]); + rw_init(&hio_remote_lock[ii]); + } + TAILQ_INIT(&hio_done_list); + mtx_init(&hio_done_list_lock); + cv_init(&hio_done_list_cond); + mtx_init(&hio_guard_lock); + cv_init(&hio_guard_cond); + mtx_init(&metadata_lock); + + /* + * Allocate requests pool and initialize requests. + */ + for (ii = 0; ii < HAST_HIO_MAX; ii++) { + hio = malloc(sizeof(*hio)); + if (hio == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate %zu bytes of memory for hio request.", + sizeof(*hio)); + } + hio->hio_countdown = 0; + hio->hio_errors = malloc(sizeof(hio->hio_errors[0]) * ncomps); + if (hio->hio_errors == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable allocate %zu bytes of memory for hio errors.", + sizeof(hio->hio_errors[0]) * ncomps); + } + hio->hio_next = malloc(sizeof(hio->hio_next[0]) * ncomps); + if (hio->hio_next == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable allocate %zu bytes of memory for hio_next field.", + sizeof(hio->hio_next[0]) * ncomps); + } + hio->hio_ggio.gctl_version = G_GATE_VERSION; + hio->hio_ggio.gctl_data = malloc(MAXPHYS); + if (hio->hio_ggio.gctl_data == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate %zu bytes of memory for gctl_data.", + MAXPHYS); + } + hio->hio_ggio.gctl_length = MAXPHYS; + hio->hio_ggio.gctl_error = 0; + TAILQ_INSERT_HEAD(&hio_free_list, hio, hio_free_next); + } + + /* + * Turn on signals handling. + */ + signal(SIGINT, sighandler); + signal(SIGTERM, sighandler); +} + +static void +init_local(struct hast_resource *res) +{ + unsigned char *buf; + size_t mapsize; + + if (metadata_read(res, true) < 0) + exit(EX_NOINPUT); + mtx_init(&res->hr_amp_lock); + if (activemap_init(&res->hr_amp, res->hr_datasize, res->hr_extentsize, + res->hr_local_sectorsize, res->hr_keepdirty) < 0) { + primary_exit(EX_TEMPFAIL, "Unable to create activemap"); + } + mtx_init(&range_lock); + cv_init(&range_regular_cond); + if (rangelock_init(&range_regular) < 0) + primary_exit(EX_TEMPFAIL, "Unable to create regular range lock"); + cv_init(&range_sync_cond); + if (rangelock_init(&range_sync) < 0) + primary_exit(EX_TEMPFAIL, "Unable to create sync range lock"); + mapsize = activemap_ondisk_size(res->hr_amp); + buf = calloc(1, mapsize); + if (buf == NULL) { + primary_exitx(EX_TEMPFAIL, + "Unable to allocate buffer for activemap."); + } + if (pread(res->hr_localfd, buf, mapsize, METADATA_SIZE) != + (ssize_t)mapsize) { + primary_exit(EX_NOINPUT, "Unable to read activemap"); + } + activemap_copyin(res->hr_amp, buf, mapsize); + if (res->hr_resuid != 0) + return; + /* + * We're using provider for the first time, so we have to generate + * resource unique identifier and initialize local and remote counts. + */ + arc4random_buf(&res->hr_resuid, sizeof(res->hr_resuid)); + res->hr_primary_localcnt = 1; + res->hr_primary_remotecnt = 0; + if (metadata_write(res) < 0) + exit(EX_NOINPUT); +} + +static void +init_remote(struct hast_resource *res) +{ + struct nv *nvout, *nvin; + const unsigned char *token; + unsigned char *map; + const char *errmsg; + int32_t extentsize; + int64_t datasize; + uint32_t mapsize; + size_t size; + + /* Prepare outgoing connection with remote node. */ + if (proto_client(res->hr_remoteaddr, &res->hr_remoteout) < 0) { + primary_exit(EX_OSERR, "Unable to create connection to %s", + res->hr_remoteaddr); + } + /* Try to connect, but accept failure. */ + if (proto_connect(res->hr_remoteout) < 0) { + pjdlog_errno(LOG_WARNING, "Unable to connect to %s", + res->hr_remoteaddr); + goto close; + } + /* + * First handshake step. + * Setup outgoing connection with remote node. + */ + nvout = nv_alloc(); + nv_add_string(nvout, res->hr_name, "resource"); + if (nv_error(nvout) != 0) { + pjdlog_common(LOG_WARNING, 0, nv_error(nvout), + "Unable to allocate header for connection with %s", + res->hr_remoteaddr); + nv_free(nvout); + goto close; + } + if (hast_proto_send(res, res->hr_remoteout, nvout, NULL, 0) < 0) { + pjdlog_errno(LOG_WARNING, + "Unable to send handshake header to %s", + res->hr_remoteaddr); + nv_free(nvout); + goto close; + } + nv_free(nvout); + if (hast_proto_recv_hdr(res->hr_remoteout, &nvin) < 0) { + pjdlog_errno(LOG_WARNING, + "Unable to receive handshake header from %s", + res->hr_remoteaddr); + goto close; + } + errmsg = nv_get_string(nvin, "errmsg"); + if (errmsg != NULL) { + pjdlog_warning("%s", errmsg); + nv_free(nvin); + goto close; + } + token = nv_get_uint8_array(nvin, &size, "token"); + if (token == NULL) { + pjdlog_warning("Handshake header from %s has no 'token' field.", + res->hr_remoteaddr); + nv_free(nvin); + goto close; + } + if (size != sizeof(res->hr_token)) { + pjdlog_warning("Handshake header from %s contains 'token' of wrong size (got %zu, expected %zu).", + res->hr_remoteaddr, size, sizeof(res->hr_token)); + nv_free(nvin); + goto close; + } + bcopy(token, res->hr_token, sizeof(res->hr_token)); + nv_free(nvin); + + /* + * Second handshake step. + * Setup incoming connection with remote node. + */ + if (proto_client(res->hr_remoteaddr, &res->hr_remotein) < 0) { + pjdlog_errno(LOG_WARNING, "Unable to create connection to %s", + res->hr_remoteaddr); + } + /* Try to connect, but accept failure. */ + if (proto_connect(res->hr_remotein) < 0) { + pjdlog_errno(LOG_WARNING, "Unable to connect to %s", + res->hr_remoteaddr); + goto close; + } + nvout = nv_alloc(); + nv_add_string(nvout, res->hr_name, "resource"); + nv_add_uint8_array(nvout, res->hr_token, sizeof(res->hr_token), + "token"); + nv_add_uint64(nvout, res->hr_resuid, "resuid"); + nv_add_uint64(nvout, res->hr_primary_localcnt, "localcnt"); + nv_add_uint64(nvout, res->hr_primary_remotecnt, "remotecnt"); + if (nv_error(nvout) != 0) { + pjdlog_common(LOG_WARNING, 0, nv_error(nvout), + "Unable to allocate header for connection with %s", + res->hr_remoteaddr); + nv_free(nvout); + goto close; + } + if (hast_proto_send(res, res->hr_remotein, nvout, NULL, 0) < 0) { + pjdlog_errno(LOG_WARNING, + "Unable to send handshake header to %s", + res->hr_remoteaddr); + nv_free(nvout); + goto close; + } + nv_free(nvout); + if (hast_proto_recv_hdr(res->hr_remoteout, &nvin) < 0) { + pjdlog_errno(LOG_WARNING, + "Unable to receive handshake header from %s", + res->hr_remoteaddr); + goto close; + } + errmsg = nv_get_string(nvin, "errmsg"); + if (errmsg != NULL) { + pjdlog_warning("%s", errmsg); + nv_free(nvin); + goto close; + } + datasize = nv_get_int64(nvin, "datasize"); + if (datasize != res->hr_datasize) { + pjdlog_warning("Data size differs between nodes (local=%jd, remote=%jd).", + (intmax_t)res->hr_datasize, (intmax_t)datasize); + nv_free(nvin); + goto close; + } + extentsize = nv_get_int32(nvin, "extentsize"); + if (extentsize != res->hr_extentsize) { + pjdlog_warning("Extent size differs between nodes (local=%zd, remote=%zd).", + (ssize_t)res->hr_extentsize, (ssize_t)extentsize); + nv_free(nvin); + goto close; + } + res->hr_secondary_localcnt = nv_get_uint64(nvin, "localcnt"); + res->hr_secondary_remotecnt = nv_get_uint64(nvin, "remotecnt"); + res->hr_syncsrc = nv_get_uint8(nvin, "syncsrc"); + map = NULL; + mapsize = nv_get_uint32(nvin, "mapsize"); + if (mapsize > 0) { + map = malloc(mapsize); + if (map == NULL) { + pjdlog_error("Unable to allocate memory for remote activemap (mapsize=%ju).", + (uintmax_t)mapsize); + nv_free(nvin); + goto close; + } + /* + * Remote node have some dirty extents on its own, lets + * download its activemap. + */ + if (hast_proto_recv_data(res, res->hr_remoteout, nvin, map, + mapsize) < 0) { + pjdlog_errno(LOG_ERR, + "Unable to receive remote activemap"); + nv_free(nvin); + free(map); + goto close; + } + /* + * Merge local and remote bitmaps. + */ + activemap_merge(res->hr_amp, map, mapsize); + free(map); + /* + * Now that we merged bitmaps from both nodes, flush it to the + * disk before we start to synchronize. + */ + (void)hast_activemap_flush(res); + } + pjdlog_info("Connected to %s.", res->hr_remoteaddr); + mtx_lock(&sync_lock); + sync_inprogress = true; + mtx_unlock(&sync_lock); + cv_signal(&sync_cond); + return; +close: + proto_close(res->hr_remoteout); + res->hr_remoteout = NULL; + if (res->hr_remotein != NULL) { + proto_close(res->hr_remotein); + res->hr_remotein = NULL; + } +} + +static void +init_ggate(struct hast_resource *res) +{ + struct g_gate_ctl_create ggiocreate; + struct g_gate_ctl_cancel ggiocancel; + + /* + * We communicate with ggate via /dev/ggctl. Open it. + */ + res->hr_ggatefd = open("/dev/" G_GATE_CTL_NAME, O_RDWR); + if (res->hr_ggatefd < 0) + primary_exit(EX_OSFILE, "Unable to open /dev/" G_GATE_CTL_NAME); + /* + * Create provider before trying to connect, as connection failure + * is not critical, but may take some time. + */ + ggiocreate.gctl_version = G_GATE_VERSION; + ggiocreate.gctl_mediasize = res->hr_datasize; + ggiocreate.gctl_sectorsize = res->hr_local_sectorsize; + ggiocreate.gctl_flags = 0; + ggiocreate.gctl_maxcount = 128; + ggiocreate.gctl_timeout = 0; + ggiocreate.gctl_unit = G_GATE_NAME_GIVEN; + snprintf(ggiocreate.gctl_name, sizeof(ggiocreate.gctl_name), "hast/%s", + res->hr_provname); + bzero(ggiocreate.gctl_info, sizeof(ggiocreate.gctl_info)); + if (ioctl(res->hr_ggatefd, G_GATE_CMD_CREATE, &ggiocreate) == 0) { + pjdlog_info("Device hast/%s created.", res->hr_provname); + res->hr_ggateunit = ggiocreate.gctl_unit; + return; + } + if (errno != EEXIST) { + primary_exit(EX_OSERR, "Unable to create hast/%s device", + res->hr_provname); + } + pjdlog_debug(1, + "Device hast/%s already exists, we will try to take it over.", + res->hr_provname); + /* + * If we received EEXIST, we assume that the process who created the + * provider died and didn't clean up. In that case we will start from + * where he left of. + */ + ggiocancel.gctl_version = G_GATE_VERSION; + ggiocancel.gctl_unit = G_GATE_NAME_GIVEN; + snprintf(ggiocancel.gctl_name, sizeof(ggiocancel.gctl_name), "hast/%s", + res->hr_provname); + if (ioctl(res->hr_ggatefd, G_GATE_CMD_CANCEL, &ggiocancel) == 0) { + pjdlog_info("Device hast/%s recovered.", res->hr_provname); + res->hr_ggateunit = ggiocancel.gctl_unit; + return; + } + primary_exit(EX_OSERR, "Unable to take over hast/%s device", + res->hr_provname); +} + +void +hastd_primary(struct hast_resource *res) +{ + pthread_t td; + pid_t pid; + int error; + + gres = res; + + /* + * Create communication channel between parent and child. + */ + if (proto_client("socketpair://", &res->hr_ctrl) < 0) { + KEEP_ERRNO((void)pidfile_remove(pfh)); + primary_exit(EX_OSERR, + "Unable to create control sockets between parent and child"); + } + + pid = fork(); + if (pid < 0) { + KEEP_ERRNO((void)pidfile_remove(pfh)); + primary_exit(EX_OSERR, "Unable to fork"); + } + + if (pid > 0) { + /* This is parent. */ + res->hr_workerpid = pid; + return; + } + (void)pidfile_close(pfh); + + setproctitle("%s (primary)", res->hr_name); + + init_local(res); + init_remote(res); + init_ggate(res); + init_environment(res); + error = pthread_create(&td, NULL, ggate_recv_thread, res); + assert(error == 0); + error = pthread_create(&td, NULL, local_send_thread, res); + assert(error == 0); + error = pthread_create(&td, NULL, remote_send_thread, res); + assert(error == 0); + error = pthread_create(&td, NULL, remote_recv_thread, res); + assert(error == 0); + error = pthread_create(&td, NULL, ggate_send_thread, res); + assert(error == 0); + error = pthread_create(&td, NULL, sync_thread, res); + assert(error == 0); + error = pthread_create(&td, NULL, ctrl_thread, res); + assert(error == 0); + (void)guard_thread(res); +} + +static void +reqlog(int loglevel, int debuglevel, struct g_gate_ctl_io *ggio, const char *fmt, ...) +{ + char msg[1024]; + va_list ap; + int len; + + va_start(ap, fmt); + len = vsnprintf(msg, sizeof(msg), fmt, ap); + va_end(ap); + if ((size_t)len < sizeof(msg)) { + switch (ggio->gctl_cmd) { + case BIO_READ: + (void)snprintf(msg + len, sizeof(msg) - len, + "READ(%ju, %ju).", (uintmax_t)ggio->gctl_offset, + (uintmax_t)ggio->gctl_length); + break; + case BIO_DELETE: + (void)snprintf(msg + len, sizeof(msg) - len, + "DELETE(%ju, %ju).", (uintmax_t)ggio->gctl_offset, + (uintmax_t)ggio->gctl_length); + break; + case BIO_FLUSH: + (void)snprintf(msg + len, sizeof(msg) - len, "FLUSH."); + break; + case BIO_WRITE: + (void)snprintf(msg + len, sizeof(msg) - len, + "WRITE(%ju, %ju).", (uintmax_t)ggio->gctl_offset, + (uintmax_t)ggio->gctl_length); + break; + default: + (void)snprintf(msg + len, sizeof(msg) - len, + "UNKNOWN(%u).", (unsigned int)ggio->gctl_cmd); + break; + } + } + pjdlog_common(loglevel, debuglevel, -1, "%s", msg); +} + +static void +remote_close(struct hast_resource *res, int ncomp) +{ + + rw_wlock(&hio_remote_lock[ncomp]); + /* + * A race is possible between dropping rlock and acquiring wlock - + * another thread can close connection in-between. + */ + if (!ISCONNECTED(res, ncomp)) { + assert(res->hr_remotein == NULL); + assert(res->hr_remoteout == NULL); + rw_unlock(&hio_remote_lock[ncomp]); + return; + } + + assert(res->hr_remotein != NULL); + assert(res->hr_remoteout != NULL); + + pjdlog_debug(2, "Closing old incoming connection to %s.", + res->hr_remoteaddr); + proto_close(res->hr_remotein); + res->hr_remotein = NULL; + pjdlog_debug(2, "Closing old outgoing connection to %s.", + res->hr_remoteaddr); + proto_close(res->hr_remoteout); + res->hr_remoteout = NULL; + + rw_unlock(&hio_remote_lock[ncomp]); + + /* + * Stop synchronization if in-progress. + */ + mtx_lock(&sync_lock); + if (sync_inprogress) + sync_inprogress = false; + mtx_unlock(&sync_lock); + + /* + * Wake up guard thread, so it can immediately start reconnect. + */ + mtx_lock(&hio_guard_lock); + cv_signal(&hio_guard_cond); + mtx_unlock(&hio_guard_lock); +} + +/* + * Thread receives ggate I/O requests from the kernel and passes them to + * appropriate threads: + * WRITE - always goes to both local_send and remote_send threads + * READ (when the block is up-to-date on local component) - + * only local_send thread + * READ (when the block isn't up-to-date on local component) - + * only remote_send thread + * DELETE - always goes to both local_send and remote_send threads + * FLUSH - always goes to both local_send and remote_send threads + */ +static void * +ggate_recv_thread(void *arg) +{ + struct hast_resource *res = arg; + struct g_gate_ctl_io *ggio; + struct hio *hio; + unsigned int ii, ncomp, ncomps; + int error; + + ncomps = HAST_NCOMPONENTS; + + for (;;) { + pjdlog_debug(2, "ggate_recv: Taking free request."); + QUEUE_TAKE2(hio, free); + pjdlog_debug(2, "ggate_recv: (%p) Got free request.", hio); + ggio = &hio->hio_ggio; + ggio->gctl_unit = res->hr_ggateunit; + ggio->gctl_length = MAXPHYS; + ggio->gctl_error = 0; + pjdlog_debug(2, + "ggate_recv: (%p) Waiting for request from the kernel.", + hio); + if (ioctl(res->hr_ggatefd, G_GATE_CMD_START, ggio) < 0) { + if (sigexit_received) + pthread_exit(NULL); + primary_exit(EX_OSERR, "G_GATE_CMD_START failed"); + } + error = ggio->gctl_error; + switch (error) { + case 0: + break; + case ECANCELED: + /* Exit gracefully. */ + if (!sigexit_received) { + pjdlog_debug(2, + "ggate_recv: (%p) Received cancel from the kernel.", + hio); + pjdlog_info("Received cancel from the kernel, exiting."); + } + pthread_exit(NULL); + case ENOMEM: + /* + * Buffer too small? Impossible, we allocate MAXPHYS + * bytes - request can't be bigger than that. + */ + /* FALLTHROUGH */ + case ENXIO: + default: + primary_exitx(EX_OSERR, "G_GATE_CMD_START failed: %s.", + strerror(error)); + } + for (ii = 0; ii < ncomps; ii++) + hio->hio_errors[ii] = EINVAL; + reqlog(LOG_DEBUG, 2, ggio, + "ggate_recv: (%p) Request received from the kernel: ", + hio); + /* + * Inform all components about new write request. + * For read request prefer local component unless the given + * range is out-of-date, then use remote component. + */ + switch (ggio->gctl_cmd) { + case BIO_READ: + pjdlog_debug(2, + "ggate_recv: (%p) Moving request to the send queue.", + hio); + refcount_init(&hio->hio_countdown, 1); + mtx_lock(&metadata_lock); + if (res->hr_syncsrc == HAST_SYNCSRC_UNDEF || + res->hr_syncsrc == HAST_SYNCSRC_PRIMARY) { + /* + * This range is up-to-date on local component, + * so handle request locally. + */ + /* Local component is 0 for now. */ + ncomp = 0; + } else /* if (res->hr_syncsrc == + HAST_SYNCSRC_SECONDARY) */ { + assert(res->hr_syncsrc == + HAST_SYNCSRC_SECONDARY); + /* + * This range is out-of-date on local component, + * so send request to the remote node. + */ + /* Remote component is 1 for now. */ + ncomp = 1; + } + mtx_unlock(&metadata_lock); + QUEUE_INSERT1(hio, send, ncomp); + break; + case BIO_WRITE: + for (;;) { + mtx_lock(&range_lock); + if (rangelock_islocked(range_sync, + ggio->gctl_offset, ggio->gctl_length)) { + pjdlog_debug(2, + "regular: Range offset=%jd length=%zu locked.", + (intmax_t)ggio->gctl_offset, + (size_t)ggio->gctl_length); + range_regular_wait = true; + cv_wait(&range_regular_cond, &range_lock); + range_regular_wait = false; + mtx_unlock(&range_lock); + continue; + } + if (rangelock_add(range_regular, + ggio->gctl_offset, ggio->gctl_length) < 0) { + mtx_unlock(&range_lock); + pjdlog_debug(2, + "regular: Range offset=%jd length=%zu is already locked, waiting.", + (intmax_t)ggio->gctl_offset, + (size_t)ggio->gctl_length); + sleep(1); + continue; + } + mtx_unlock(&range_lock); + break; + } + mtx_lock(&res->hr_amp_lock); + if (activemap_write_start(res->hr_amp, + ggio->gctl_offset, ggio->gctl_length)) { + (void)hast_activemap_flush(res); + } + mtx_unlock(&res->hr_amp_lock); + /* FALLTHROUGH */ + case BIO_DELETE: + case BIO_FLUSH: + pjdlog_debug(2, + "ggate_recv: (%p) Moving request to the send queues.", + hio); + refcount_init(&hio->hio_countdown, ncomps); + for (ii = 0; ii < ncomps; ii++) + QUEUE_INSERT1(hio, send, ii); + break; + } + } + /* NOTREACHED */ + return (NULL); +} + +/* + * Thread reads from or writes to local component. + * If local read fails, it redirects it to remote_send thread. + */ +static void * +local_send_thread(void *arg) +{ + struct hast_resource *res = arg; + struct g_gate_ctl_io *ggio; + struct hio *hio; + unsigned int ncomp, rncomp; + ssize_t ret; + + /* Local component is 0 for now. */ + ncomp = 0; + /* Remote component is 1 for now. */ + rncomp = 1; + + for (;;) { + pjdlog_debug(2, "local_send: Taking request."); + QUEUE_TAKE1(hio, send, ncomp); + pjdlog_debug(2, "local_send: (%p) Got request.", hio); + ggio = &hio->hio_ggio; + switch (ggio->gctl_cmd) { + case BIO_READ: + ret = pread(res->hr_localfd, ggio->gctl_data, + ggio->gctl_length, + ggio->gctl_offset + res->hr_localoff); + if (ret == ggio->gctl_length) + hio->hio_errors[ncomp] = 0; + else { + /* + * If READ failed, try to read from remote node. + */ + QUEUE_INSERT1(hio, send, rncomp); + continue; + } + break; + case BIO_WRITE: + ret = pwrite(res->hr_localfd, ggio->gctl_data, + ggio->gctl_length, + ggio->gctl_offset + res->hr_localoff); + if (ret < 0) + hio->hio_errors[ncomp] = errno; + else if (ret != ggio->gctl_length) + hio->hio_errors[ncomp] = EIO; + else + hio->hio_errors[ncomp] = 0; + break; + case BIO_DELETE: + ret = g_delete(res->hr_localfd, + ggio->gctl_offset + res->hr_localoff, + ggio->gctl_length); + if (ret < 0) + hio->hio_errors[ncomp] = errno; + else + hio->hio_errors[ncomp] = 0; + break; + case BIO_FLUSH: + ret = g_flush(res->hr_localfd); + if (ret < 0) + hio->hio_errors[ncomp] = errno; + else + hio->hio_errors[ncomp] = 0; + break; + } + if (refcount_release(&hio->hio_countdown)) { + if (ISSYNCREQ(hio)) { + mtx_lock(&sync_lock); + SYNCREQDONE(hio); + mtx_unlock(&sync_lock); + cv_signal(&sync_cond); + } else { + pjdlog_debug(2, + "local_send: (%p) Moving request to the done queue.", + hio); + QUEUE_INSERT2(hio, done); + } + } + } + /* NOTREACHED */ + return (NULL); +} + +/* + * Thread sends request to secondary node. + */ +static void * +remote_send_thread(void *arg) +{ + struct hast_resource *res = arg; + struct g_gate_ctl_io *ggio; + struct hio *hio; + struct nv *nv; + unsigned int ncomp; + bool wakeup; + uint64_t offset, length; + uint8_t cmd; + void *data; + + /* Remote component is 1 for now. */ + ncomp = 1; + + for (;;) { + pjdlog_debug(2, "remote_send: Taking request."); + QUEUE_TAKE1(hio, send, ncomp); + pjdlog_debug(2, "remote_send: (%p) Got request.", hio); + ggio = &hio->hio_ggio; + switch (ggio->gctl_cmd) { + case BIO_READ: + cmd = HIO_READ; + data = NULL; + offset = ggio->gctl_offset; + length = ggio->gctl_length; + break; + case BIO_WRITE: + cmd = HIO_WRITE; + data = ggio->gctl_data; + offset = ggio->gctl_offset; + length = ggio->gctl_length; + break; + case BIO_DELETE: + cmd = HIO_DELETE; + data = NULL; + offset = ggio->gctl_offset; + length = ggio->gctl_length; + break; + case BIO_FLUSH: + cmd = HIO_FLUSH; + data = NULL; + offset = 0; + length = 0; + break; + default: + assert(!"invalid condition"); + abort(); + } + nv = nv_alloc(); + nv_add_uint8(nv, cmd, "cmd"); + nv_add_uint64(nv, (uint64_t)ggio->gctl_seq, "seq"); + nv_add_uint64(nv, offset, "offset"); + nv_add_uint64(nv, length, "length"); + if (nv_error(nv) != 0) { + hio->hio_errors[ncomp] = nv_error(nv); + pjdlog_debug(2, + "remote_send: (%p) Unable to prepare header to send.", + hio); + reqlog(LOG_ERR, 0, ggio, + "Unable to prepare header to send (%s): ", + strerror(nv_error(nv))); + /* Move failed request immediately to the done queue. */ + goto done_queue; + } + pjdlog_debug(2, + "remote_send: (%p) Moving request to the recv queue.", + hio); + /* + * Protect connection from disappearing. + */ + rw_rlock(&hio_remote_lock[ncomp]); + if (!ISCONNECTED(res, ncomp)) { + rw_unlock(&hio_remote_lock[ncomp]); + hio->hio_errors[ncomp] = ENOTCONN; + goto done_queue; + } + /* + * Move the request to recv queue before sending it, because + * in different order we can get reply before we move request + * to recv queue. + */ + mtx_lock(&hio_recv_list_lock[ncomp]); + wakeup = TAILQ_EMPTY(&hio_recv_list[ncomp]); + TAILQ_INSERT_TAIL(&hio_recv_list[ncomp], hio, hio_next[ncomp]); + mtx_unlock(&hio_recv_list_lock[ncomp]); + if (hast_proto_send(res, res->hr_remoteout, nv, data, + data != NULL ? length : 0) < 0) { + hio->hio_errors[ncomp] = errno; + rw_unlock(&hio_remote_lock[ncomp]); + remote_close(res, ncomp); + pjdlog_debug(2, + "remote_send: (%p) Unable to send request.", hio); + reqlog(LOG_ERR, 0, ggio, + "Unable to send request (%s): ", + strerror(hio->hio_errors[ncomp])); + /* + * Take request back from the receive queue and move + * it immediately to the done queue. + */ + mtx_lock(&hio_recv_list_lock[ncomp]); + TAILQ_REMOVE(&hio_recv_list[ncomp], hio, hio_next[ncomp]); + mtx_unlock(&hio_recv_list_lock[ncomp]); + goto done_queue; + } + rw_unlock(&hio_remote_lock[ncomp]); + nv_free(nv); + if (wakeup) + cv_signal(&hio_recv_list_cond[ncomp]); + continue; +done_queue: + nv_free(nv); + if (ISSYNCREQ(hio)) { + if (!refcount_release(&hio->hio_countdown)) + continue; + mtx_lock(&sync_lock); + SYNCREQDONE(hio); + mtx_unlock(&sync_lock); + cv_signal(&sync_cond); + continue; + } + if (ggio->gctl_cmd == BIO_WRITE) { + mtx_lock(&res->hr_amp_lock); + if (activemap_need_sync(res->hr_amp, ggio->gctl_offset, + ggio->gctl_length)) { + (void)hast_activemap_flush(res); + } + mtx_unlock(&res->hr_amp_lock); + } + if (!refcount_release(&hio->hio_countdown)) + continue; + pjdlog_debug(2, + "remote_send: (%p) Moving request to the done queue.", + hio); + QUEUE_INSERT2(hio, done); + } + /* NOTREACHED */ + return (NULL); +} + +/* + * Thread receives answer from secondary node and passes it to ggate_send + * thread. + */ +static void * +remote_recv_thread(void *arg) +{ + struct hast_resource *res = arg; + struct g_gate_ctl_io *ggio; + struct hio *hio; + struct nv *nv; + unsigned int ncomp; + uint64_t seq; + int error; + + /* Remote component is 1 for now. */ + ncomp = 1; + + for (;;) { + /* Wait until there is anything to receive. */ + mtx_lock(&hio_recv_list_lock[ncomp]); + while (TAILQ_EMPTY(&hio_recv_list[ncomp])) { + pjdlog_debug(2, "remote_recv: No requests, waiting."); + cv_wait(&hio_recv_list_cond[ncomp], + &hio_recv_list_lock[ncomp]); + } + mtx_unlock(&hio_recv_list_lock[ncomp]); + rw_rlock(&hio_remote_lock[ncomp]); + if (!ISCONNECTED(res, ncomp)) { + rw_unlock(&hio_remote_lock[ncomp]); + /* + * Connection is dead, so move all pending requests to + * the done queue (one-by-one). + */ + mtx_lock(&hio_recv_list_lock[ncomp]); + hio = TAILQ_FIRST(&hio_recv_list[ncomp]); + assert(hio != NULL); + TAILQ_REMOVE(&hio_recv_list[ncomp], hio, + hio_next[ncomp]); + mtx_unlock(&hio_recv_list_lock[ncomp]); + goto done_queue; + } + if (hast_proto_recv_hdr(res->hr_remotein, &nv) < 0) { + pjdlog_errno(LOG_ERR, + "Unable to receive reply header"); + rw_unlock(&hio_remote_lock[ncomp]); + remote_close(res, ncomp); + continue; + } + rw_unlock(&hio_remote_lock[ncomp]); + seq = nv_get_uint64(nv, "seq"); + if (seq == 0) { + pjdlog_error("Header contains no 'seq' field."); + nv_free(nv); + continue; + } + mtx_lock(&hio_recv_list_lock[ncomp]); + TAILQ_FOREACH(hio, &hio_recv_list[ncomp], hio_next[ncomp]) { + if (hio->hio_ggio.gctl_seq == seq) { + TAILQ_REMOVE(&hio_recv_list[ncomp], hio, + hio_next[ncomp]); + break; + } + } + mtx_unlock(&hio_recv_list_lock[ncomp]); + if (hio == NULL) { + pjdlog_error("Found no request matching received 'seq' field (%ju).", + (uintmax_t)seq); + nv_free(nv); + continue; + } + error = nv_get_int16(nv, "error"); + if (error != 0) { + /* Request failed on remote side. */ + hio->hio_errors[ncomp] = 0; + nv_free(nv); + goto done_queue; + } + ggio = &hio->hio_ggio; + switch (ggio->gctl_cmd) { + case BIO_READ: + rw_rlock(&hio_remote_lock[ncomp]); + if (!ISCONNECTED(res, ncomp)) { + rw_unlock(&hio_remote_lock[ncomp]); + nv_free(nv); + goto done_queue; + } + if (hast_proto_recv_data(res, res->hr_remotein, nv, + ggio->gctl_data, ggio->gctl_length) < 0) { + hio->hio_errors[ncomp] = errno; + pjdlog_errno(LOG_ERR, + "Unable to receive reply data"); + rw_unlock(&hio_remote_lock[ncomp]); + nv_free(nv); + remote_close(res, ncomp); + goto done_queue; + } + rw_unlock(&hio_remote_lock[ncomp]); + break; + case BIO_WRITE: + case BIO_DELETE: + case BIO_FLUSH: + break; + default: + assert(!"invalid condition"); + abort(); + } + hio->hio_errors[ncomp] = 0; + nv_free(nv); +done_queue: + if (refcount_release(&hio->hio_countdown)) { + if (ISSYNCREQ(hio)) { + mtx_lock(&sync_lock); + SYNCREQDONE(hio); + mtx_unlock(&sync_lock); + cv_signal(&sync_cond); + } else { + pjdlog_debug(2, + "remote_recv: (%p) Moving request to the done queue.", + hio); + QUEUE_INSERT2(hio, done); + } + } + } + /* NOTREACHED */ + return (NULL); +} + +/* + * Thread sends answer to the kernel. + */ +static void * +ggate_send_thread(void *arg) +{ + struct hast_resource *res = arg; + struct g_gate_ctl_io *ggio; + struct hio *hio; + unsigned int ii, ncomp, ncomps; + + ncomps = HAST_NCOMPONENTS; + + for (;;) { + pjdlog_debug(2, "ggate_send: Taking request."); + QUEUE_TAKE2(hio, done); + pjdlog_debug(2, "ggate_send: (%p) Got request.", hio); + ggio = &hio->hio_ggio; + for (ii = 0; ii < ncomps; ii++) { + if (hio->hio_errors[ii] == 0) { + /* + * One successful request is enough to declare + * success. + */ + ggio->gctl_error = 0; + break; + } + } + if (ii == ncomps) { + /* + * None of the requests were successful. + * Use first error. + */ + ggio->gctl_error = hio->hio_errors[0]; + } + if (ggio->gctl_error == 0 && ggio->gctl_cmd == BIO_WRITE) { + mtx_lock(&res->hr_amp_lock); + activemap_write_complete(res->hr_amp, + ggio->gctl_offset, ggio->gctl_length); + mtx_unlock(&res->hr_amp_lock); + } + if (ggio->gctl_cmd == BIO_WRITE) { + /* + * Unlock range we locked. + */ + mtx_lock(&range_lock); + rangelock_del(range_regular, ggio->gctl_offset, + ggio->gctl_length); + if (range_sync_wait) + cv_signal(&range_sync_cond); + mtx_unlock(&range_lock); + /* + * Bump local count if this is first write after + * connection failure with remote node. + */ + ncomp = 1; + rw_rlock(&hio_remote_lock[ncomp]); + if (!ISCONNECTED(res, ncomp)) { + mtx_lock(&metadata_lock); + if (res->hr_primary_localcnt == + res->hr_secondary_remotecnt) { + res->hr_primary_localcnt++; + pjdlog_debug(1, + "Increasing localcnt to %ju.", + (uintmax_t)res->hr_primary_localcnt); + (void)metadata_write(res); + } + mtx_unlock(&metadata_lock); + } + rw_unlock(&hio_remote_lock[ncomp]); + } + if (ioctl(res->hr_ggatefd, G_GATE_CMD_DONE, ggio) < 0) + primary_exit(EX_OSERR, "G_GATE_CMD_DONE failed"); + pjdlog_debug(2, + "ggate_send: (%p) Moving request to the free queue.", hio); + QUEUE_INSERT2(hio, free); + } + /* NOTREACHED */ + return (NULL); +} + +/* + * Thread synchronize local and remote components. + */ +static void * +sync_thread(void *arg __unused) +{ + struct hast_resource *res = arg; + struct hio *hio; + struct g_gate_ctl_io *ggio; + unsigned int ii, ncomp, ncomps; + off_t offset, length, synced; + bool dorewind; + int syncext; + + ncomps = HAST_NCOMPONENTS; + dorewind = true; + synced = 0; + + for (;;) { + mtx_lock(&sync_lock); + while (!sync_inprogress) { + dorewind = true; + synced = 0; + cv_wait(&sync_cond, &sync_lock); + } + mtx_unlock(&sync_lock); + /* + * Obtain offset at which we should synchronize. + * Rewind synchronization if needed. + */ + mtx_lock(&res->hr_amp_lock); + if (dorewind) + activemap_sync_rewind(res->hr_amp); + offset = activemap_sync_offset(res->hr_amp, &length, &syncext); + if (syncext != -1) { + /* + * We synchronized entire syncext extent, we can mark + * it as clean now. + */ + if (activemap_extent_complete(res->hr_amp, syncext)) + (void)hast_activemap_flush(res); + } + mtx_unlock(&res->hr_amp_lock); + if (dorewind) { + dorewind = false; + if (offset < 0) + pjdlog_info("Nodes are in sync."); + else { + pjdlog_info("Synchronization started. %ju bytes to go.", + (uintmax_t)(res->hr_extentsize * + activemap_ndirty(res->hr_amp))); + } + } + if (offset < 0) { + mtx_lock(&sync_lock); + sync_inprogress = false; + mtx_unlock(&sync_lock); + pjdlog_debug(1, "Nothing to synchronize."); + /* + * Synchronization complete, make both localcnt and + * remotecnt equal. + */ + ncomp = 1; + rw_rlock(&hio_remote_lock[ncomp]); + if (ISCONNECTED(res, ncomp)) { + if (synced > 0) { + pjdlog_info("Synchronization complete. " + "%jd bytes synchronized.", + (intmax_t)synced); + } + mtx_lock(&metadata_lock); + res->hr_syncsrc = HAST_SYNCSRC_UNDEF; + res->hr_primary_localcnt = + res->hr_secondary_localcnt; + res->hr_primary_remotecnt = + res->hr_secondary_remotecnt; + pjdlog_debug(1, + "Setting localcnt to %ju and remotecnt to %ju.", + (uintmax_t)res->hr_primary_localcnt, + (uintmax_t)res->hr_secondary_localcnt); + (void)metadata_write(res); + mtx_unlock(&metadata_lock); + } else if (synced > 0) { + pjdlog_info("Synchronization interrupted. " + "%jd bytes synchronized so far.", + (intmax_t)synced); + } + rw_unlock(&hio_remote_lock[ncomp]); + continue; + } + pjdlog_debug(2, "sync: Taking free request."); + QUEUE_TAKE2(hio, free); + pjdlog_debug(2, "sync: (%p) Got free request.", hio); + /* + * Lock the range we are going to synchronize. We don't want + * race where someone writes between our read and write. + */ + for (;;) { + mtx_lock(&range_lock); + if (rangelock_islocked(range_regular, offset, length)) { + pjdlog_debug(2, + "sync: Range offset=%jd length=%jd locked.", + (intmax_t)offset, (intmax_t)length); + range_sync_wait = true; + cv_wait(&range_sync_cond, &range_lock); + range_sync_wait = false; + mtx_unlock(&range_lock); + continue; + } + if (rangelock_add(range_sync, offset, length) < 0) { + mtx_unlock(&range_lock); + pjdlog_debug(2, + "sync: Range offset=%jd length=%jd is already locked, waiting.", + (intmax_t)offset, (intmax_t)length); + sleep(1); + continue; + } + mtx_unlock(&range_lock); + break; + } + /* + * First read the data from synchronization source. + */ + SYNCREQ(hio); + ggio = &hio->hio_ggio; + ggio->gctl_cmd = BIO_READ; + ggio->gctl_offset = offset; + ggio->gctl_length = length; + ggio->gctl_error = 0; + for (ii = 0; ii < ncomps; ii++) + hio->hio_errors[ii] = EINVAL; + reqlog(LOG_DEBUG, 2, ggio, "sync: (%p) Sending sync request: ", + hio); + pjdlog_debug(2, "sync: (%p) Moving request to the send queue.", + hio); + mtx_lock(&metadata_lock); + if (res->hr_syncsrc == HAST_SYNCSRC_PRIMARY) { + /* + * This range is up-to-date on local component, + * so handle request locally. + */ + /* Local component is 0 for now. */ + ncomp = 0; + } else /* if (res->hr_syncsrc == HAST_SYNCSRC_SECONDARY) */ { + assert(res->hr_syncsrc == HAST_SYNCSRC_SECONDARY); + /* + * This range is out-of-date on local component, + * so send request to the remote node. + */ + /* Remote component is 1 for now. */ + ncomp = 1; + } + mtx_unlock(&metadata_lock); + refcount_init(&hio->hio_countdown, 1); + QUEUE_INSERT1(hio, send, ncomp); + + /* + * Let's wait for READ to finish. + */ + mtx_lock(&sync_lock); + while (!ISSYNCREQDONE(hio)) + cv_wait(&sync_cond, &sync_lock); + mtx_unlock(&sync_lock); + + if (hio->hio_errors[ncomp] != 0) { + pjdlog_error("Unable to read synchronization data: %s.", + strerror(hio->hio_errors[ncomp])); + goto free_queue; + } + + /* + * We read the data from synchronization source, now write it + * to synchronization target. + */ + SYNCREQ(hio); + ggio->gctl_cmd = BIO_WRITE; + for (ii = 0; ii < ncomps; ii++) + hio->hio_errors[ii] = EINVAL; + reqlog(LOG_DEBUG, 2, ggio, "sync: (%p) Sending sync request: ", + hio); + pjdlog_debug(2, "sync: (%p) Moving request to the send queue.", + hio); + mtx_lock(&metadata_lock); + if (res->hr_syncsrc == HAST_SYNCSRC_PRIMARY) { + /* + * This range is up-to-date on local component, + * so we update remote component. + */ + /* Remote component is 1 for now. */ + ncomp = 1; + } else /* if (res->hr_syncsrc == HAST_SYNCSRC_SECONDARY) */ { + assert(res->hr_syncsrc == HAST_SYNCSRC_SECONDARY); + /* + * This range is out-of-date on local component, + * so we update it. + */ + /* Local component is 0 for now. */ + ncomp = 0; + } + mtx_unlock(&metadata_lock); + + pjdlog_debug(2, "sync: (%p) Moving request to the send queues.", + hio); + refcount_init(&hio->hio_countdown, 1); + QUEUE_INSERT1(hio, send, ncomp); + + /* + * Let's wait for WRITE to finish. + */ + mtx_lock(&sync_lock); + while (!ISSYNCREQDONE(hio)) + cv_wait(&sync_cond, &sync_lock); + mtx_unlock(&sync_lock); + + if (hio->hio_errors[ncomp] != 0) { + pjdlog_error("Unable to write synchronization data: %s.", + strerror(hio->hio_errors[ncomp])); + goto free_queue; + } +free_queue: + mtx_lock(&range_lock); + rangelock_del(range_sync, offset, length); + if (range_regular_wait) + cv_signal(&range_regular_cond); + mtx_unlock(&range_lock); + + synced += length; + + pjdlog_debug(2, "sync: (%p) Moving request to the free queue.", + hio); + QUEUE_INSERT2(hio, free); + } + /* NOTREACHED */ + return (NULL); +} + +static void +sighandler(int sig) +{ + bool unlock; + + switch (sig) { + case SIGINT: + case SIGTERM: + sigexit_received = true; + break; + default: + assert(!"invalid condition"); + } + /* + * XXX: Racy, but if we cannot obtain hio_guard_lock here, we don't + * want to risk deadlock. + */ + unlock = mtx_trylock(&hio_guard_lock); + cv_signal(&hio_guard_cond); + if (unlock) + mtx_unlock(&hio_guard_lock); +} + +/* + * Thread guards remote connections and reconnects when needed, handles + * signals, etc. + */ +static void * +guard_thread(void *arg) +{ + struct hast_resource *res = arg; + unsigned int ii, ncomps; + int timeout; + + ncomps = HAST_NCOMPONENTS; + /* The is only one remote component for now. */ +#define ISREMOTE(no) ((no) == 1) + + for (;;) { + if (sigexit_received) { + primary_exitx(EX_OK, + "Termination signal received, exiting."); + } + /* + * If all the connection will be fine, we will sleep until + * someone wakes us up. + * If any of the connections will be broken and we won't be + * able to connect, we will sleep only for RECONNECT_SLEEP + * seconds so we can retry soon. + */ + timeout = 0; + pjdlog_debug(2, "remote_guard: Checking connections."); + mtx_lock(&hio_guard_lock); + for (ii = 0; ii < ncomps; ii++) { + if (!ISREMOTE(ii)) + continue; + rw_rlock(&hio_remote_lock[ii]); + if (ISCONNECTED(res, ii)) { + assert(res->hr_remotein != NULL); + assert(res->hr_remoteout != NULL); + rw_unlock(&hio_remote_lock[ii]); + pjdlog_debug(2, + "remote_guard: Connection to %s is ok.", + res->hr_remoteaddr); + } else { + assert(res->hr_remotein == NULL); + assert(res->hr_remoteout == NULL); + /* + * Upgrade the lock. It doesn't have to be + * atomic as no other thread can change + * connection status from disconnected to + * connected. + */ + rw_unlock(&hio_remote_lock[ii]); + rw_wlock(&hio_remote_lock[ii]); + assert(res->hr_remotein == NULL); + assert(res->hr_remoteout == NULL); + pjdlog_debug(2, + "remote_guard: Reconnecting to %s.", + res->hr_remoteaddr); + init_remote(res); + if (ISCONNECTED(res, ii)) { + pjdlog_info("Successfully reconnected to %s.", + res->hr_remoteaddr); + } else { + /* Both connections should be NULL. */ + assert(res->hr_remotein == NULL); + assert(res->hr_remoteout == NULL); + pjdlog_debug(2, + "remote_guard: Reconnect to %s failed.", + res->hr_remoteaddr); + timeout = RECONNECT_SLEEP; + } + rw_unlock(&hio_remote_lock[ii]); + } + } + (void)cv_timedwait(&hio_guard_cond, &hio_guard_lock, timeout); + mtx_unlock(&hio_guard_lock); + } +#undef ISREMOTE + /* NOTREACHED */ + return (NULL); +} diff --git a/sbin/hastd/proto.c b/sbin/hastd/proto.c new file mode 100644 index 00000000000..103f20ce9fd --- /dev/null +++ b/sbin/hastd/proto.c @@ -0,0 +1,261 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "proto.h" +#include "proto_impl.h" + +#define PROTO_CONN_MAGIC 0x907041c +struct proto_conn { + int pc_magic; + struct hast_proto *pc_proto; + void *pc_ctx; + int pc_side; +#define PROTO_SIDE_CLIENT 0 +#define PROTO_SIDE_SERVER_LISTEN 1 +#define PROTO_SIDE_SERVER_WORK 2 +}; + +static LIST_HEAD(, hast_proto) protos = LIST_HEAD_INITIALIZER(protos); + +void +proto_register(struct hast_proto *proto) +{ + + LIST_INSERT_HEAD(&protos, proto, hp_next); +} + +static int +proto_common_setup(const char *addr, struct proto_conn **connp, int side) +{ + struct hast_proto *proto; + struct proto_conn *conn; + void *ctx; + int ret; + + assert(side == PROTO_SIDE_CLIENT || side == PROTO_SIDE_SERVER_LISTEN); + + conn = malloc(sizeof(*conn)); + if (conn == NULL) + return (-1); + + LIST_FOREACH(proto, &protos, hp_next) { + if (side == PROTO_SIDE_CLIENT) + ret = proto->hp_client(addr, &ctx); + else /* if (side == PROTO_SIDE_SERVER_LISTEN) */ + ret = proto->hp_server(addr, &ctx); + /* + * ret == 0 - success + * ret == -1 - addr is not for this protocol + * ret > 0 - right protocol, but an error occured + */ + if (ret >= 0) + break; + } + if (proto == NULL) { + /* Unrecognized address. */ + free(conn); + errno = EINVAL; + return (-1); + } + if (ret > 0) { + /* An error occured. */ + free(conn); + errno = ret; + return (-1); + } + conn->pc_proto = proto; + conn->pc_ctx = ctx; + conn->pc_side = side; + conn->pc_magic = PROTO_CONN_MAGIC; + *connp = conn; + return (0); +} + +int +proto_client(const char *addr, struct proto_conn **connp) +{ + + return (proto_common_setup(addr, connp, PROTO_SIDE_CLIENT)); +} + +int +proto_connect(struct proto_conn *conn) +{ + int ret; + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_side == PROTO_SIDE_CLIENT); + assert(conn->pc_proto != NULL); + + ret = conn->pc_proto->hp_connect(conn->pc_ctx); + if (ret != 0) { + errno = ret; + return (-1); + } + + return (0); +} + +int +proto_server(const char *addr, struct proto_conn **connp) +{ + + return (proto_common_setup(addr, connp, PROTO_SIDE_SERVER_LISTEN)); +} + +int +proto_accept(struct proto_conn *conn, struct proto_conn **newconnp) +{ + struct proto_conn *newconn; + int ret; + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_side == PROTO_SIDE_SERVER_LISTEN); + assert(conn->pc_proto != NULL); + + newconn = malloc(sizeof(*newconn)); + if (newconn == NULL) + return (-1); + + ret = conn->pc_proto->hp_accept(conn->pc_ctx, &newconn->pc_ctx); + if (ret != 0) { + free(newconn); + errno = ret; + return (-1); + } + + newconn->pc_proto = conn->pc_proto; + newconn->pc_side = PROTO_SIDE_SERVER_WORK; + newconn->pc_magic = PROTO_CONN_MAGIC; + *newconnp = newconn; + + return (0); +} + +int +proto_send(struct proto_conn *conn, const void *data, size_t size) +{ + int ret; + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_proto != NULL); + + ret = conn->pc_proto->hp_send(conn->pc_ctx, data, size); + if (ret != 0) { + errno = ret; + return (-1); + } + return (0); +} + +int +proto_recv(struct proto_conn *conn, void *data, size_t size) +{ + int ret; + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_proto != NULL); + + ret = conn->pc_proto->hp_recv(conn->pc_ctx, data, size); + if (ret != 0) { + errno = ret; + return (-1); + } + return (0); +} + +int +proto_descriptor(const struct proto_conn *conn) +{ + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_proto != NULL); + + return (conn->pc_proto->hp_descriptor(conn->pc_ctx)); +} + +bool +proto_address_match(const struct proto_conn *conn, const char *addr) +{ + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_proto != NULL); + + return (conn->pc_proto->hp_address_match(conn->pc_ctx, addr)); +} + +void +proto_local_address(const struct proto_conn *conn, char *addr, size_t size) +{ + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_proto != NULL); + + conn->pc_proto->hp_local_address(conn->pc_ctx, addr, size); +} + +void +proto_remote_address(const struct proto_conn *conn, char *addr, size_t size) +{ + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_proto != NULL); + + conn->pc_proto->hp_remote_address(conn->pc_ctx, addr, size); +} + +void +proto_close(struct proto_conn *conn) +{ + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_proto != NULL); + + conn->pc_proto->hp_close(conn->pc_ctx); + conn->pc_magic = 0; + free(conn); +} diff --git a/sbin/hastd/proto.h b/sbin/hastd/proto.h new file mode 100644 index 00000000000..cb196d8da86 --- /dev/null +++ b/sbin/hastd/proto.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _PROTO_H_ +#define _PROTO_H_ + +#include /* bool */ +#include /* size_t */ + +struct proto_conn; + +int proto_client(const char *addr, struct proto_conn **connp); +int proto_connect(struct proto_conn *conn); +int proto_server(const char *addr, struct proto_conn **connp); +int proto_accept(struct proto_conn *conn, struct proto_conn **newconnp); +int proto_send(struct proto_conn *conn, const void *data, size_t size); +int proto_recv(struct proto_conn *conn, void *data, size_t size); +int proto_descriptor(const struct proto_conn *conn); +bool proto_address_match(const struct proto_conn *conn, const char *addr); +void proto_local_address(const struct proto_conn *conn, char *addr, + size_t size); +void proto_remote_address(const struct proto_conn *conn, char *addr, + size_t size); +void proto_close(struct proto_conn *conn); + +#endif /* !_PROTO_H_ */ diff --git a/sbin/hastd/proto_common.c b/sbin/hastd/proto_common.c new file mode 100644 index 00000000000..22102d86e82 --- /dev/null +++ b/sbin/hastd/proto_common.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "proto_impl.h" + +/* Maximum size of packet we want to use when sending data. */ +#ifndef MAX_SEND_SIZE +//#define MAX_SEND_SIZE 32768 +#define MAX_SEND_SIZE 131072 +#endif + +int +proto_common_send(int fd, const unsigned char *data, size_t size) +{ + ssize_t done; + size_t sendsize; + + do { + sendsize = size < MAX_SEND_SIZE ? size : MAX_SEND_SIZE; + done = send(fd, data, sendsize, MSG_NOSIGNAL); + if (done == 0) + return (ENOTCONN); + else if (done < 0) { + if (errno == EAGAIN) + continue; + return (errno); + } + data += done; + size -= done; + } while (size > 0); + + return (0); +} + +int +proto_common_recv(int fd, unsigned char *data, size_t size) +{ + ssize_t done; + + do { + done = recv(fd, data, size, MSG_WAITALL); + } while (done == -1 && errno == EAGAIN); + if (done == 0) + return (ENOTCONN); + else if (done < 0) + return (errno); + return (0); +} diff --git a/sbin/hastd/proto_impl.h b/sbin/hastd/proto_impl.h new file mode 100644 index 00000000000..ea6548d5804 --- /dev/null +++ b/sbin/hastd/proto_impl.h @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _PROTO_IMPL_H_ +#define _PROTO_IMPL_H_ + +#include + +#include /* bool */ +#include /* size_t */ + +#define __constructor __attribute__((constructor)) + +typedef int hp_client_t(const char *, void **); +typedef int hp_connect_t(void *); +typedef int hp_server_t(const char *, void **); +typedef int hp_accept_t(void *, void **); +typedef int hp_send_t(void *, const unsigned char *, size_t); +typedef int hp_recv_t(void *, unsigned char *, size_t); +typedef int hp_descriptor_t(const void *); +typedef bool hp_address_match_t(const void *, const char *); +typedef void hp_local_address_t(const void *, char *, size_t); +typedef void hp_remote_address_t(const void *, char *, size_t); +typedef void hp_close_t(void *); + +struct hast_proto { + const char *hp_name; + hp_client_t *hp_client; + hp_connect_t *hp_connect; + hp_server_t *hp_server; + hp_accept_t *hp_accept; + hp_send_t *hp_send; + hp_recv_t *hp_recv; + hp_descriptor_t *hp_descriptor; + hp_address_match_t *hp_address_match; + hp_local_address_t *hp_local_address; + hp_remote_address_t *hp_remote_address; + hp_close_t *hp_close; + LIST_ENTRY(hast_proto) hp_next; +}; + +void proto_register(struct hast_proto *proto); + +int proto_common_send(int fd, const unsigned char *data, size_t size); +int proto_common_recv(int fd, unsigned char *data, size_t size); + +#endif /* !_PROTO_IMPL_H_ */ diff --git a/sbin/hastd/proto_socketpair.c b/sbin/hastd/proto_socketpair.c new file mode 100644 index 00000000000..0e2cfa250ef --- /dev/null +++ b/sbin/hastd/proto_socketpair.c @@ -0,0 +1,272 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "hast.h" +#include "proto_impl.h" + +#define SP_CTX_MAGIC 0x50c3741 +struct sp_ctx { + int sp_magic; + int sp_fd[2]; + int sp_side; +#define SP_SIDE_UNDEF 0 +#define SP_SIDE_CLIENT 1 +#define SP_SIDE_SERVER 2 +}; + +static void sp_close(void *ctx); + +static int +sp_client(const char *addr, void **ctxp) +{ + struct sp_ctx *spctx; + int ret; + + if (strcmp(addr, "socketpair://") != 0) + return (-1); + + spctx = malloc(sizeof(*spctx)); + if (spctx == NULL) + return (errno); + + if (socketpair(PF_UNIX, SOCK_STREAM, 0, spctx->sp_fd) < 0) { + ret = errno; + free(spctx); + return (ret); + } + + spctx->sp_side = SP_SIDE_UNDEF; + spctx->sp_magic = SP_CTX_MAGIC; + *ctxp = spctx; + + return (0); +} + +static int +sp_connect(void *ctx __unused) +{ + + assert(!"proto_connect() not supported on socketpairs"); + abort(); +} + +static int +sp_server(const char *addr __unused, void **ctxp __unused) +{ + + assert(!"proto_server() not supported on socketpairs"); + abort(); +} + +static int +sp_accept(void *ctx __unused, void **newctxp __unused) +{ + + assert(!"proto_server() not supported on socketpairs"); + abort(); +} + +static int +sp_send(void *ctx, const unsigned char *data, size_t size) +{ + struct sp_ctx *spctx = ctx; + int fd; + + assert(spctx != NULL); + assert(spctx->sp_magic == SP_CTX_MAGIC); + + switch (spctx->sp_side) { + case SP_SIDE_UNDEF: + /* + * If the first operation done by the caller is proto_send(), + * we assume this the client. + */ + /* FALLTHROUGH */ + spctx->sp_side = SP_SIDE_CLIENT; + /* Close other end. */ + close(spctx->sp_fd[1]); + case SP_SIDE_CLIENT: + assert(spctx->sp_fd[0] >= 0); + fd = spctx->sp_fd[0]; + break; + case SP_SIDE_SERVER: + assert(spctx->sp_fd[1] >= 0); + fd = spctx->sp_fd[1]; + break; + default: + abort(); + } + + return (proto_common_send(fd, data, size)); +} + +static int +sp_recv(void *ctx, unsigned char *data, size_t size) +{ + struct sp_ctx *spctx = ctx; + int fd; + + assert(spctx != NULL); + assert(spctx->sp_magic == SP_CTX_MAGIC); + + switch (spctx->sp_side) { + case SP_SIDE_UNDEF: + /* + * If the first operation done by the caller is proto_recv(), + * we assume this the server. + */ + /* FALLTHROUGH */ + spctx->sp_side = SP_SIDE_SERVER; + /* Close other end. */ + close(spctx->sp_fd[0]); + case SP_SIDE_SERVER: + assert(spctx->sp_fd[1] >= 0); + fd = spctx->sp_fd[1]; + break; + case SP_SIDE_CLIENT: + assert(spctx->sp_fd[0] >= 0); + fd = spctx->sp_fd[0]; + break; + default: + abort(); + } + + return (proto_common_recv(fd, data, size)); +} + +static int +sp_descriptor(const void *ctx) +{ + const struct sp_ctx *spctx = ctx; + + assert(spctx != NULL); + assert(spctx->sp_magic == SP_CTX_MAGIC); + assert(spctx->sp_side == SP_SIDE_CLIENT || + spctx->sp_side == SP_SIDE_SERVER); + + switch (spctx->sp_side) { + case SP_SIDE_CLIENT: + assert(spctx->sp_fd[0] >= 0); + return (spctx->sp_fd[0]); + case SP_SIDE_SERVER: + assert(spctx->sp_fd[1] >= 0); + return (spctx->sp_fd[1]); + } + + abort(); +} + +static bool +sp_address_match(const void *ctx __unused, const char *addr __unused) +{ + + assert(!"proto_address_match() not supported on socketpairs"); + abort(); +} + +static void +sp_local_address(const void *ctx __unused, char *addr __unused, + size_t size __unused) +{ + + assert(!"proto_local_address() not supported on socketpairs"); + abort(); +} + +static void +sp_remote_address(const void *ctx __unused, char *addr __unused, + size_t size __unused) +{ + + assert(!"proto_remote_address() not supported on socketpairs"); + abort(); +} + +static void +sp_close(void *ctx) +{ + struct sp_ctx *spctx = ctx; + + assert(spctx != NULL); + assert(spctx->sp_magic == SP_CTX_MAGIC); + + switch (spctx->sp_side) { + case SP_SIDE_UNDEF: + close(spctx->sp_fd[0]); + close(spctx->sp_fd[1]); + break; + case SP_SIDE_CLIENT: + close(spctx->sp_fd[0]); + break; + case SP_SIDE_SERVER: + close(spctx->sp_fd[1]); + break; + default: + abort(); + } + + spctx->sp_magic = 0; + free(spctx); +} + +static struct hast_proto sp_proto = { + .hp_name = "socketpair", + .hp_client = sp_client, + .hp_connect = sp_connect, + .hp_server = sp_server, + .hp_accept = sp_accept, + .hp_send = sp_send, + .hp_recv = sp_recv, + .hp_descriptor = sp_descriptor, + .hp_address_match = sp_address_match, + .hp_local_address = sp_local_address, + .hp_remote_address = sp_remote_address, + .hp_close = sp_close +}; + +static __constructor void +sp_ctor(void) +{ + + proto_register(&sp_proto); +} diff --git a/sbin/hastd/proto_tcp4.c b/sbin/hastd/proto_tcp4.c new file mode 100644 index 00000000000..2fba9967e40 --- /dev/null +++ b/sbin/hastd/proto_tcp4.c @@ -0,0 +1,447 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 /* MAXHOSTNAMELEN */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hast.h" +#include "pjdlog.h" +#include "proto_impl.h" + +#define TCP4_CTX_MAGIC 0x7c441c +struct tcp4_ctx { + int tc_magic; + struct sockaddr_in tc_sin; + int tc_fd; + int tc_side; +#define TCP4_SIDE_CLIENT 0 +#define TCP4_SIDE_SERVER_LISTEN 1 +#define TCP4_SIDE_SERVER_WORK 2 +}; + +static void tcp4_close(void *ctx); + +static in_addr_t +str2ip(const char *str) +{ + struct hostent *hp; + in_addr_t ip; + + ip = inet_addr(str); + if (ip != INADDR_NONE) { + /* It is a valid IP address. */ + return (ip); + } + /* Check if it is a valid host name. */ + hp = gethostbyname(str); + if (hp == NULL) + return (INADDR_NONE); + return (((struct in_addr *)(void *)hp->h_addr)->s_addr); +} + +/* + * Function converts the given string to unsigned number. + */ +static int +numfromstr(const char *str, intmax_t minnum, intmax_t maxnum, intmax_t *nump) +{ + intmax_t digit, num; + + if (str[0] == '\0') + goto invalid; /* Empty string. */ + num = 0; + for (; *str != '\0'; str++) { + if (*str < '0' || *str > '9') + goto invalid; /* Non-digit character. */ + digit = *str - '0'; + if (num > num * 10 + digit) + goto invalid; /* Overflow. */ + num = num * 10 + digit; + if (num > maxnum) + goto invalid; /* Too big. */ + } + if (num < minnum) + goto invalid; /* Too small. */ + *nump = num; + return (0); +invalid: + errno = EINVAL; + return (-1); +} + +static int +tcp4_addr(const char *addr, struct sockaddr_in *sinp) +{ + char iporhost[MAXHOSTNAMELEN]; + const char *pp; + size_t size; + in_addr_t ip; + + if (addr == NULL) + return (-1); + + if (strncasecmp(addr, "tcp4://", 7) == 0) + addr += 7; + else if (strncasecmp(addr, "tcp://", 6) == 0) + addr += 6; + else if (addr[0] != '/' && /* If this is not path... */ + strstr(addr, "://") == NULL)/* ...and has no prefix... */ + ; /* ...tcp4 is the default. */ + else + return (-1); + + sinp->sin_family = AF_INET; + sinp->sin_len = sizeof(*sinp); + /* Extract optional port. */ + pp = strrchr(addr, ':'); + if (pp == NULL) { + /* Port not given, use the default. */ + sinp->sin_port = htons(HASTD_PORT); + } else { + intmax_t port; + + if (numfromstr(pp + 1, 1, 65535, &port) < 0) + return (errno); + sinp->sin_port = htons(port); + } + /* Extract host name or IP address. */ + if (pp == NULL) { + size = sizeof(iporhost); + if (strlcpy(iporhost, addr, size) >= size) + return (ENAMETOOLONG); + } else { + size = (size_t)(pp - addr + 1); + if (size > sizeof(iporhost)) + return (ENAMETOOLONG); + strlcpy(iporhost, addr, size); + } + /* Convert string (IP address or host name) to in_addr_t. */ + ip = str2ip(iporhost); + if (ip == INADDR_NONE) + return (EINVAL); + sinp->sin_addr.s_addr = ip; + + return (0); +} + +static int +tcp4_common_setup(const char *addr, void **ctxp, int side) +{ + struct tcp4_ctx *tctx; + int ret, val; + + tctx = malloc(sizeof(*tctx)); + if (tctx == NULL) + return (errno); + + /* Parse given address. */ + if ((ret = tcp4_addr(addr, &tctx->tc_sin)) != 0) { + free(tctx); + return (ret); + } + + tctx->tc_fd = socket(AF_INET, SOCK_STREAM, 0); + if (tctx->tc_fd == -1) { + ret = errno; + free(tctx); + return (ret); + } + + /* Socket settings. */ + val = 1; + if (setsockopt(tctx->tc_fd, IPPROTO_TCP, TCP_NODELAY, &val, + sizeof(val)) == -1) { + pjdlog_warning("Unable to set TCP_NOELAY on %s", addr); + } + val = 131072; + if (setsockopt(tctx->tc_fd, SOL_SOCKET, SO_SNDBUF, &val, + sizeof(val)) == -1) { + pjdlog_warning("Unable to set send buffer size on %s", addr); + } + val = 131072; + if (setsockopt(tctx->tc_fd, SOL_SOCKET, SO_RCVBUF, &val, + sizeof(val)) == -1) { + pjdlog_warning("Unable to set receive buffer size on %s", addr); + } + + tctx->tc_side = side; + tctx->tc_magic = TCP4_CTX_MAGIC; + *ctxp = tctx; + + return (0); +} + +static int +tcp4_client(const char *addr, void **ctxp) +{ + + return (tcp4_common_setup(addr, ctxp, TCP4_SIDE_CLIENT)); +} + +static int +tcp4_connect(void *ctx) +{ + struct tcp4_ctx *tctx = ctx; + + assert(tctx != NULL); + assert(tctx->tc_magic == TCP4_CTX_MAGIC); + assert(tctx->tc_side == TCP4_SIDE_CLIENT); + assert(tctx->tc_fd >= 0); + + if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin, + sizeof(tctx->tc_sin)) < 0) { + return (errno); + } + + return (0); +} + +static int +tcp4_server(const char *addr, void **ctxp) +{ + struct tcp4_ctx *tctx; + int ret, val; + + ret = tcp4_common_setup(addr, ctxp, TCP4_SIDE_SERVER_LISTEN); + if (ret != 0) + return (ret); + + tctx = *ctxp; + + val = 1; + /* Ignore failure. */ + (void)setsockopt(tctx->tc_fd, SOL_SOCKET, SO_REUSEADDR, &val, + sizeof(val)); + + if (bind(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin, + sizeof(tctx->tc_sin)) < 0) { + ret = errno; + tcp4_close(tctx); + return (ret); + } + if (listen(tctx->tc_fd, 8) < 0) { + ret = errno; + tcp4_close(tctx); + return (ret); + } + + return (0); +} + +static int +tcp4_accept(void *ctx, void **newctxp) +{ + struct tcp4_ctx *tctx = ctx; + struct tcp4_ctx *newtctx; + socklen_t fromlen; + int ret; + + assert(tctx != NULL); + assert(tctx->tc_magic == TCP4_CTX_MAGIC); + assert(tctx->tc_side == TCP4_SIDE_SERVER_LISTEN); + assert(tctx->tc_fd >= 0); + + newtctx = malloc(sizeof(*newtctx)); + if (newtctx == NULL) + return (errno); + + fromlen = sizeof(tctx->tc_sin); + newtctx->tc_fd = accept(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin, + &fromlen); + if (newtctx->tc_fd < 0) { + ret = errno; + free(newtctx); + return (ret); + } + + newtctx->tc_side = TCP4_SIDE_SERVER_WORK; + newtctx->tc_magic = TCP4_CTX_MAGIC; + *newctxp = newtctx; + + return (0); +} + +static int +tcp4_send(void *ctx, const unsigned char *data, size_t size) +{ + struct tcp4_ctx *tctx = ctx; + + assert(tctx != NULL); + assert(tctx->tc_magic == TCP4_CTX_MAGIC); + assert(tctx->tc_fd >= 0); + + return (proto_common_send(tctx->tc_fd, data, size)); +} + +static int +tcp4_recv(void *ctx, unsigned char *data, size_t size) +{ + struct tcp4_ctx *tctx = ctx; + + assert(tctx != NULL); + assert(tctx->tc_magic == TCP4_CTX_MAGIC); + assert(tctx->tc_fd >= 0); + + return (proto_common_recv(tctx->tc_fd, data, size)); +} + +static int +tcp4_descriptor(const void *ctx) +{ + const struct tcp4_ctx *tctx = ctx; + + assert(tctx != NULL); + assert(tctx->tc_magic == TCP4_CTX_MAGIC); + + return (tctx->tc_fd); +} + +static void +sin2str(struct sockaddr_in *sinp, char *addr, size_t size) +{ + in_addr_t ip; + unsigned int port; + + assert(addr != NULL); + assert(sinp->sin_family == AF_INET); + + ip = ntohl(sinp->sin_addr.s_addr); + port = ntohs(sinp->sin_port); + snprintf(addr, size, "tcp4://%u.%u.%u.%u:%u", ((ip >> 24) & 0xff), + ((ip >> 16) & 0xff), ((ip >> 8) & 0xff), (ip & 0xff), port); +} + +static bool +tcp4_address_match(const void *ctx, const char *addr) +{ + const struct tcp4_ctx *tctx = ctx; + struct sockaddr_in sin; + socklen_t sinlen; + in_addr_t ip1, ip2; + + assert(tctx != NULL); + assert(tctx->tc_magic == TCP4_CTX_MAGIC); + + if (tcp4_addr(addr, &sin) != 0) + return (false); + ip1 = sin.sin_addr.s_addr; + + sinlen = sizeof(sin); + if (getpeername(tctx->tc_fd, (struct sockaddr *)&sin, &sinlen) < 0) + return (false); + ip2 = sin.sin_addr.s_addr; + + return (ip1 == ip2); +} + +static void +tcp4_local_address(const void *ctx, char *addr, size_t size) +{ + const struct tcp4_ctx *tctx = ctx; + struct sockaddr_in sin; + socklen_t sinlen; + + assert(tctx != NULL); + assert(tctx->tc_magic == TCP4_CTX_MAGIC); + + sinlen = sizeof(sin); + if (getsockname(tctx->tc_fd, (struct sockaddr *)&sin, &sinlen) < 0) { + strlcpy(addr, "N/A", size); + return; + } + sin2str(&sin, addr, size); +} + +static void +tcp4_remote_address(const void *ctx, char *addr, size_t size) +{ + const struct tcp4_ctx *tctx = ctx; + struct sockaddr_in sin; + socklen_t sinlen; + + assert(tctx != NULL); + assert(tctx->tc_magic == TCP4_CTX_MAGIC); + + sinlen = sizeof(sin); + if (getpeername(tctx->tc_fd, (struct sockaddr *)&sin, &sinlen) < 0) { + strlcpy(addr, "N/A", size); + return; + } + sin2str(&sin, addr, size); +} + +static void +tcp4_close(void *ctx) +{ + struct tcp4_ctx *tctx = ctx; + + assert(tctx != NULL); + assert(tctx->tc_magic == TCP4_CTX_MAGIC); + + if (tctx->tc_fd >= 0) + close(tctx->tc_fd); + tctx->tc_magic = 0; + free(tctx); +} + +static struct hast_proto tcp4_proto = { + .hp_name = "tcp4", + .hp_client = tcp4_client, + .hp_connect = tcp4_connect, + .hp_server = tcp4_server, + .hp_accept = tcp4_accept, + .hp_send = tcp4_send, + .hp_recv = tcp4_recv, + .hp_descriptor = tcp4_descriptor, + .hp_address_match = tcp4_address_match, + .hp_local_address = tcp4_local_address, + .hp_remote_address = tcp4_remote_address, + .hp_close = tcp4_close +}; + +static __constructor void +tcp4_ctor(void) +{ + + proto_register(&tcp4_proto); +} diff --git a/sbin/hastd/proto_uds.c b/sbin/hastd/proto_uds.c new file mode 100644 index 00000000000..0fac82f24d0 --- /dev/null +++ b/sbin/hastd/proto_uds.c @@ -0,0 +1,330 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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$"); + +/* UDS - UNIX Domain Socket */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "hast.h" +#include "proto_impl.h" + +#define UDS_CTX_MAGIC 0xd541c +struct uds_ctx { + int uc_magic; + struct sockaddr_un uc_sun; + int uc_fd; + int uc_side; +#define UDS_SIDE_CLIENT 0 +#define UDS_SIDE_SERVER_LISTEN 1 +#define UDS_SIDE_SERVER_WORK 2 +}; + +static void uds_close(void *ctx); + +static int +uds_addr(const char *addr, struct sockaddr_un *sunp) +{ + + if (addr == NULL) + return (-1); + + if (strncasecmp(addr, "uds://", 6) == 0) + addr += 6; + else if (strncasecmp(addr, "unix://", 7) == 0) + addr += 7; + else if (addr[0] == '/' && /* If it starts from /... */ + strstr(addr, "://") == NULL)/* ...and there is no prefix... */ + ; /* ...we assume its us. */ + else + return (-1); + + sunp->sun_family = AF_UNIX; + if (strlcpy(sunp->sun_path, addr, sizeof(sunp->sun_path)) >= + sizeof(sunp->sun_path)) { + return (ENAMETOOLONG); + } + sunp->sun_len = SUN_LEN(sunp); + + return (0); +} + +static int +uds_common_setup(const char *addr, void **ctxp, int side) +{ + struct uds_ctx *uctx; + int ret; + + uctx = malloc(sizeof(*uctx)); + if (uctx == NULL) + return (errno); + + /* Parse given address. */ + if ((ret = uds_addr(addr, &uctx->uc_sun)) != 0) { + free(uctx); + return (ret); + } + + uctx->uc_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (uctx->uc_fd == -1) { + ret = errno; + free(uctx); + return (ret); + } + + uctx->uc_side = side; + uctx->uc_magic = UDS_CTX_MAGIC; + *ctxp = uctx; + + return (0); +} + +static int +uds_client(const char *addr, void **ctxp) +{ + + return (uds_common_setup(addr, ctxp, UDS_SIDE_CLIENT)); +} + +static int +uds_connect(void *ctx) +{ + struct uds_ctx *uctx = ctx; + + assert(uctx != NULL); + assert(uctx->uc_magic == UDS_CTX_MAGIC); + assert(uctx->uc_side == UDS_SIDE_CLIENT); + assert(uctx->uc_fd >= 0); + + if (connect(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun, + sizeof(uctx->uc_sun)) < 0) { + return (errno); + } + + return (0); +} + +static int +uds_server(const char *addr, void **ctxp) +{ + struct uds_ctx *uctx; + int ret; + + ret = uds_common_setup(addr, ctxp, UDS_SIDE_SERVER_LISTEN); + if (ret != 0) + return (ret); + + uctx = *ctxp; + + unlink(uctx->uc_sun.sun_path); + if (bind(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun, + sizeof(uctx->uc_sun)) < 0) { + ret = errno; + uds_close(uctx); + return (ret); + } + if (listen(uctx->uc_fd, 8) < 0) { + ret = errno; + uds_close(uctx); + return (ret); + } + + return (0); +} + +static int +uds_accept(void *ctx, void **newctxp) +{ + struct uds_ctx *uctx = ctx; + struct uds_ctx *newuctx; + socklen_t fromlen; + int ret; + + assert(uctx != NULL); + assert(uctx->uc_magic == UDS_CTX_MAGIC); + assert(uctx->uc_side == UDS_SIDE_SERVER_LISTEN); + assert(uctx->uc_fd >= 0); + + newuctx = malloc(sizeof(*newuctx)); + if (newuctx == NULL) + return (errno); + + fromlen = sizeof(uctx->uc_sun); + newuctx->uc_fd = accept(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun, + &fromlen); + if (newuctx->uc_fd < 0) { + ret = errno; + free(newuctx); + return (ret); + } + + newuctx->uc_side = UDS_SIDE_SERVER_WORK; + newuctx->uc_magic = UDS_CTX_MAGIC; + *newctxp = newuctx; + + return (0); +} + +static int +uds_send(void *ctx, const unsigned char *data, size_t size) +{ + struct uds_ctx *uctx = ctx; + + assert(uctx != NULL); + assert(uctx->uc_magic == UDS_CTX_MAGIC); + assert(uctx->uc_fd >= 0); + + return (proto_common_send(uctx->uc_fd, data, size)); +} + +static int +uds_recv(void *ctx, unsigned char *data, size_t size) +{ + struct uds_ctx *uctx = ctx; + + assert(uctx != NULL); + assert(uctx->uc_magic == UDS_CTX_MAGIC); + assert(uctx->uc_fd >= 0); + + return (proto_common_recv(uctx->uc_fd, data, size)); +} + +static int +uds_descriptor(const void *ctx) +{ + const struct uds_ctx *uctx = ctx; + + assert(uctx != NULL); + assert(uctx->uc_magic == UDS_CTX_MAGIC); + + return (uctx->uc_fd); +} + +static bool +uds_address_match(const void *ctx __unused, const char *addr __unused) +{ + + assert(!"proto_address_match() not supported on UNIX domain sockets"); + abort(); +} + +static void +uds_local_address(const void *ctx, char *addr, size_t size) +{ + const struct uds_ctx *uctx = ctx; + struct sockaddr_un sun; + socklen_t sunlen; + + assert(uctx != NULL); + assert(uctx->uc_magic == UDS_CTX_MAGIC); + assert(addr != NULL); + + sunlen = sizeof(sun); + if (getsockname(uctx->uc_fd, (struct sockaddr *)&sun, &sunlen) < 0) { + strlcpy(addr, "N/A", size); + return; + } + assert(sun.sun_family == AF_UNIX); + if (sun.sun_path[0] == '\0') { + strlcpy(addr, "N/A", size); + return; + } + snprintf(addr, size, "uds://%s", sun.sun_path); +} + +static void +uds_remote_address(const void *ctx, char *addr, size_t size) +{ + const struct uds_ctx *uctx = ctx; + struct sockaddr_un sun; + socklen_t sunlen; + + assert(uctx != NULL); + assert(uctx->uc_magic == UDS_CTX_MAGIC); + assert(addr != NULL); + + sunlen = sizeof(sun); + if (getpeername(uctx->uc_fd, (struct sockaddr *)&sun, &sunlen) < 0) { + strlcpy(addr, "N/A", size); + return; + } + assert(sun.sun_family == AF_UNIX); + if (sun.sun_path[0] == '\0') { + strlcpy(addr, "N/A", size); + return; + } + snprintf(addr, size, "uds://%s", sun.sun_path); +} + +static void +uds_close(void *ctx) +{ + struct uds_ctx *uctx = ctx; + + assert(uctx != NULL); + assert(uctx->uc_magic == UDS_CTX_MAGIC); + + if (uctx->uc_fd >= 0) + close(uctx->uc_fd); + unlink(uctx->uc_sun.sun_path); + uctx->uc_magic = 0; + free(uctx); +} + +static struct hast_proto uds_proto = { + .hp_name = "uds", + .hp_client = uds_client, + .hp_connect = uds_connect, + .hp_server = uds_server, + .hp_accept = uds_accept, + .hp_send = uds_send, + .hp_recv = uds_recv, + .hp_descriptor = uds_descriptor, + .hp_address_match = uds_address_match, + .hp_local_address = uds_local_address, + .hp_remote_address = uds_remote_address, + .hp_close = uds_close +}; + +static __constructor void +uds_ctor(void) +{ + + proto_register(&uds_proto); +} diff --git a/sbin/hastd/rangelock.c b/sbin/hastd/rangelock.c new file mode 100644 index 00000000000..02247d6e3b4 --- /dev/null +++ b/sbin/hastd/rangelock.c @@ -0,0 +1,137 @@ +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "rangelock.h" + +#define RANGELOCKS_MAGIC 0x94310c +struct rangelocks { + int rls_magic; /* Magic value. */ + TAILQ_HEAD(, rlock) rls_locks; /* List of locked ranges. */ +}; + +struct rlock { + off_t rl_start; + off_t rl_end; + TAILQ_ENTRY(rlock) rl_next; +}; + +int +rangelock_init(struct rangelocks **rlsp) +{ + struct rangelocks *rls; + + assert(rlsp != NULL); + + rls = malloc(sizeof(*rls)); + if (rls == NULL) + return (-1); + + TAILQ_INIT(&rls->rls_locks); + + rls->rls_magic = RANGELOCKS_MAGIC; + *rlsp = rls; + + return (0); +} + +void +rangelock_free(struct rangelocks *rls) +{ + struct rlock *rl; + + assert(rls->rls_magic == RANGELOCKS_MAGIC); + + rls->rls_magic = 0; + + while ((rl = TAILQ_FIRST(&rls->rls_locks)) != NULL) { + TAILQ_REMOVE(&rls->rls_locks, rl, rl_next); + free(rl); + } + free(rls); +} + +int +rangelock_add(struct rangelocks *rls, off_t offset, off_t length) +{ + struct rlock *rl; + + assert(rls->rls_magic == RANGELOCKS_MAGIC); + + rl = malloc(sizeof(*rl)); + if (rl == NULL) + return (-1); + rl->rl_start = offset; + rl->rl_end = offset + length; + TAILQ_INSERT_TAIL(&rls->rls_locks, rl, rl_next); + return (0); +} + +void +rangelock_del(struct rangelocks *rls, off_t offset, off_t length) +{ + struct rlock *rl; + + assert(rls->rls_magic == RANGELOCKS_MAGIC); + + TAILQ_FOREACH(rl, &rls->rls_locks, rl_next) { + if (rl->rl_start == offset && rl->rl_end == offset + length) + break; + } + assert(rl != NULL); + TAILQ_REMOVE(&rls->rls_locks, rl, rl_next); + free(rl); +} + +bool +rangelock_islocked(struct rangelocks *rls, off_t offset, off_t length) +{ + struct rlock *rl; + + assert(rls->rls_magic == RANGELOCKS_MAGIC); + + TAILQ_FOREACH(rl, &rls->rls_locks, rl_next) { + if (rl->rl_start >= offset && rl->rl_start < offset + length) + break; + else if (rl->rl_end > offset && rl->rl_end <= offset + length) + break; + else if (rl->rl_start < offset && rl->rl_end > offset + length) + break; + } + return (rl != NULL); +} diff --git a/sbin/hastd/rangelock.h b/sbin/hastd/rangelock.h new file mode 100644 index 00000000000..2ad9895c507 --- /dev/null +++ b/sbin/hastd/rangelock.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _RANGELOCK_H_ +#define _RANGELOCK_H_ + +#include +#include + +struct rangelocks; + +int rangelock_init(struct rangelocks **rlsp); +void rangelock_free(struct rangelocks *rls); +int rangelock_add(struct rangelocks *rls, off_t offset, off_t length); +void rangelock_del(struct rangelocks *rls, off_t offset, off_t length); +bool rangelock_islocked(struct rangelocks *rls, off_t offset, off_t length); + +#endif /* !_RANGELOCK_H_ */ diff --git a/sbin/hastd/secondary.c b/sbin/hastd/secondary.c new file mode 100644 index 00000000000..6af95b5d69e --- /dev/null +++ b/sbin/hastd/secondary.c @@ -0,0 +1,697 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "control.h" +#include "hast.h" +#include "hast_proto.h" +#include "hastd.h" +#include "metadata.h" +#include "proto.h" +#include "subr.h" +#include "synch.h" + +struct hio { + uint64_t hio_seq; + int hio_error; + struct nv *hio_nv; + void *hio_data; + uint8_t hio_cmd; + uint64_t hio_offset; + uint64_t hio_length; + TAILQ_ENTRY(hio) hio_next; +}; + +/* + * Free list holds unused structures. When free list is empty, we have to wait + * until some in-progress requests are freed. + */ +static TAILQ_HEAD(, hio) hio_free_list; +static pthread_mutex_t hio_free_list_lock; +static pthread_cond_t hio_free_list_cond; +/* + * Disk thread (the one that do I/O requests) takes requests from this list. + */ +static TAILQ_HEAD(, hio) hio_disk_list; +static pthread_mutex_t hio_disk_list_lock; +static pthread_cond_t hio_disk_list_cond; +/* + * There is one recv list for every component, although local components don't + * use recv lists as local requests are done synchronously. + */ +static TAILQ_HEAD(, hio) hio_send_list; +static pthread_mutex_t hio_send_list_lock; +static pthread_cond_t hio_send_list_cond; + +/* + * Maximum number of outstanding I/O requests. + */ +#define HAST_HIO_MAX 256 + +static void *recv_thread(void *arg); +static void *disk_thread(void *arg); +static void *send_thread(void *arg); + +static void +init_environment(void) +{ + struct hio *hio; + unsigned int ii; + + /* + * Initialize lists, their locks and theirs condition variables. + */ + TAILQ_INIT(&hio_free_list); + mtx_init(&hio_free_list_lock); + cv_init(&hio_free_list_cond); + TAILQ_INIT(&hio_disk_list); + mtx_init(&hio_disk_list_lock); + cv_init(&hio_disk_list_cond); + TAILQ_INIT(&hio_send_list); + mtx_init(&hio_send_list_lock); + cv_init(&hio_send_list_cond); + + /* + * Allocate requests pool and initialize requests. + */ + for (ii = 0; ii < HAST_HIO_MAX; ii++) { + hio = malloc(sizeof(*hio)); + if (hio == NULL) { + errx(EX_TEMPFAIL, "cannot allocate %zu bytes of memory " + "for hio request", sizeof(*hio)); + } + hio->hio_error = 0; + hio->hio_data = malloc(MAXPHYS); + if (hio->hio_data == NULL) { + errx(EX_TEMPFAIL, "cannot allocate %zu bytes of memory " + "for gctl_data", (size_t)MAXPHYS); + } + TAILQ_INSERT_HEAD(&hio_free_list, hio, hio_next); + } +} + +static void +init_local(struct hast_resource *res) +{ + + if (metadata_read(res, true) < 0) + exit(EX_NOINPUT); +} + +static void +init_remote(struct hast_resource *res, struct nv *nvin) +{ + uint64_t resuid; + struct nv *nvout; + unsigned char *map; + size_t mapsize; + + map = NULL; + mapsize = 0; + nvout = nv_alloc(); + nv_add_int64(nvout, (int64_t)res->hr_datasize, "datasize"); + nv_add_int32(nvout, (int32_t)res->hr_extentsize, "extentsize"); + resuid = nv_get_uint64(nvin, "resuid"); + res->hr_primary_localcnt = nv_get_uint64(nvin, "localcnt"); + res->hr_primary_remotecnt = nv_get_uint64(nvin, "remotecnt"); + nv_add_uint64(nvout, res->hr_secondary_localcnt, "localcnt"); + nv_add_uint64(nvout, res->hr_secondary_remotecnt, "remotecnt"); + mapsize = activemap_calc_ondisk_size(res->hr_local_mediasize - + METADATA_SIZE, res->hr_extentsize, res->hr_local_sectorsize); + map = malloc(mapsize); + if (map == NULL) { + pjdlog_exitx(EX_TEMPFAIL, + "Unable to allocate memory (%zu bytes) for activemap.", + mapsize); + } + nv_add_uint32(nvout, (uint32_t)mapsize, "mapsize"); + /* + * When we work as primary and secondary is missing we will increase + * localcnt in our metadata. When secondary is connected and synced + * we make localcnt be equal to remotecnt, which means nodes are more + * or less in sync. + * Split-brain condition is when both nodes are not able to communicate + * and are both configured as primary nodes. In turn, they can both + * make incompatible changes to the data and we have to detect that. + * Under split-brain condition we will increase our localcnt on first + * write and remote node will increase its localcnt on first write. + * When we connect we can see that primary's localcnt is greater than + * our remotecnt (primary was modified while we weren't watching) and + * our localcnt is greater than primary's remotecnt (we were modified + * while primary wasn't watching). + * There are many possible combinations which are all gathered below. + * Don't pay too much attention to exact numbers, the more important + * is to compare them. We compare secondary's local with primary's + * remote and secondary's remote with primary's local. + * Note that every case where primary's localcnt is smaller than + * secondary's remotecnt and where secondary's localcnt is smaller than + * primary's remotecnt should be impossible in practise. We will perform + * full synchronization then. Those cases are marked with an asterisk. + * Regular synchronization means that only extents marked as dirty are + * synchronized (regular synchronization). + * + * SECONDARY METADATA PRIMARY METADATA + * local=3 remote=3 local=2 remote=2* ?! Full sync from secondary. + * local=3 remote=3 local=2 remote=3* ?! Full sync from primary. + * local=3 remote=3 local=2 remote=4* ?! Full sync from primary. + * local=3 remote=3 local=3 remote=2 Primary is out-of-date, + * regular sync from secondary. + * local=3 remote=3 local=3 remote=3 Regular sync just in case. + * local=3 remote=3 local=3 remote=4* ?! Full sync from primary. + * local=3 remote=3 local=4 remote=2 Split-brain condition. + * local=3 remote=3 local=4 remote=3 Secondary out-of-date, + * regular sync from primary. + * local=3 remote=3 local=4 remote=4* ?! Full sync from primary. + */ + if (res->hr_resuid == 0) { + /* + * Provider is used for the first time. Initialize everything. + */ + assert(res->hr_secondary_localcnt == 0); + res->hr_resuid = resuid; + if (metadata_write(res) < 0) + exit(EX_NOINPUT); + memset(map, 0xff, mapsize); + nv_add_uint8(nvout, HAST_SYNCSRC_PRIMARY, "syncsrc"); + } else if ( + /* Is primary is out-of-date? */ + (res->hr_secondary_localcnt > res->hr_primary_remotecnt && + res->hr_secondary_remotecnt == res->hr_primary_localcnt) || + /* Node are more or less in sync? */ + (res->hr_secondary_localcnt == res->hr_primary_remotecnt && + res->hr_secondary_remotecnt == res->hr_primary_localcnt) || + /* Is secondary is out-of-date? */ + (res->hr_secondary_localcnt == res->hr_primary_remotecnt && + res->hr_secondary_remotecnt < res->hr_primary_localcnt)) { + /* + * Nodes are more or less in sync or one of the nodes is + * out-of-date. + * It doesn't matter at this point which one, we just have to + * send out local bitmap to the remote node. + */ + if (pread(res->hr_localfd, map, mapsize, METADATA_SIZE) != + (ssize_t)mapsize) { + pjdlog_exit(LOG_ERR, "Unable to read activemap"); + } + if (res->hr_secondary_localcnt > res->hr_primary_remotecnt && + res->hr_secondary_remotecnt == res->hr_primary_localcnt) { + /* Primary is out-of-date, sync from secondary. */ + nv_add_uint8(nvout, HAST_SYNCSRC_SECONDARY, "syncsrc"); + } else { + /* + * Secondary is out-of-date or counts match. + * Sync from primary. + */ + nv_add_uint8(nvout, HAST_SYNCSRC_PRIMARY, "syncsrc"); + } + } else if (res->hr_secondary_localcnt > res->hr_primary_remotecnt && + res->hr_primary_localcnt > res->hr_secondary_remotecnt) { + /* + * Not good, we have split-brain condition. + */ + pjdlog_error("Split-brain detected, exiting."); + nv_add_string(nvout, "Split-brain condition!", "errmsg"); + free(map); + map = NULL; + mapsize = 0; + } else /* if (res->hr_secondary_localcnt < res->hr_primary_remotecnt || + res->hr_primary_localcnt < res->hr_secondary_remotecnt) */ { + /* + * This should never happen in practise, but we will perform + * full synchronization. + */ + assert(res->hr_secondary_localcnt < res->hr_primary_remotecnt || + res->hr_primary_localcnt < res->hr_secondary_remotecnt); + mapsize = activemap_calc_ondisk_size(res->hr_local_mediasize - + METADATA_SIZE, res->hr_extentsize, + res->hr_local_sectorsize); + memset(map, 0xff, mapsize); + if (res->hr_secondary_localcnt > res->hr_primary_remotecnt) { + /* In this one of five cases sync from secondary. */ + nv_add_uint8(nvout, HAST_SYNCSRC_SECONDARY, "syncsrc"); + } else { + /* For the rest four cases sync from primary. */ + nv_add_uint8(nvout, HAST_SYNCSRC_PRIMARY, "syncsrc"); + } + pjdlog_warning("This should never happen, asking for full synchronization (primary(local=%ju, remote=%ju), secondary(local=%ju, remote=%ju)).", + (uintmax_t)res->hr_primary_localcnt, + (uintmax_t)res->hr_primary_remotecnt, + (uintmax_t)res->hr_secondary_localcnt, + (uintmax_t)res->hr_secondary_remotecnt); + } + if (hast_proto_send(res, res->hr_remotein, nvout, map, mapsize) < 0) { + pjdlog_errno(LOG_WARNING, "Unable to send activemap to %s", + res->hr_remoteaddr); + nv_free(nvout); + exit(EX_TEMPFAIL); + } + if (res->hr_secondary_localcnt > res->hr_primary_remotecnt && + res->hr_primary_localcnt > res->hr_secondary_remotecnt) { + /* Exit on split-brain. */ + exit(EX_CONFIG); + } +} + +void +hastd_secondary(struct hast_resource *res, struct nv *nvin) +{ + pthread_t td; + pid_t pid; + int error; + + /* + * Create communication channel between parent and child. + */ + if (proto_client("socketpair://", &res->hr_ctrl) < 0) { + KEEP_ERRNO((void)pidfile_remove(pfh)); + pjdlog_exit(EX_OSERR, + "Unable to create control sockets between parent and child"); + } + + pid = fork(); + if (pid < 0) { + KEEP_ERRNO((void)pidfile_remove(pfh)); + pjdlog_exit(EX_OSERR, "Unable to fork"); + } + + if (pid > 0) { + /* This is parent. */ + proto_close(res->hr_remotein); + res->hr_remotein = NULL; + proto_close(res->hr_remoteout); + res->hr_remoteout = NULL; + res->hr_workerpid = pid; + return; + } + (void)pidfile_close(pfh); + + setproctitle("%s (secondary)", res->hr_name); + + init_local(res); + init_remote(res, nvin); + init_environment(); + + error = pthread_create(&td, NULL, recv_thread, res); + assert(error == 0); + error = pthread_create(&td, NULL, disk_thread, res); + assert(error == 0); + error = pthread_create(&td, NULL, send_thread, res); + assert(error == 0); + (void)ctrl_thread(res); +} + +static void +reqlog(int loglevel, int debuglevel, int error, struct hio *hio, const char *fmt, ...) +{ + char msg[1024]; + va_list ap; + int len; + + va_start(ap, fmt); + len = vsnprintf(msg, sizeof(msg), fmt, ap); + va_end(ap); + if ((size_t)len < sizeof(msg)) { + switch (hio->hio_cmd) { + case HIO_READ: + (void)snprintf(msg + len, sizeof(msg) - len, + "READ(%ju, %ju).", (uintmax_t)hio->hio_offset, + (uintmax_t)hio->hio_length); + break; + case HIO_DELETE: + (void)snprintf(msg + len, sizeof(msg) - len, + "DELETE(%ju, %ju).", (uintmax_t)hio->hio_offset, + (uintmax_t)hio->hio_length); + break; + case HIO_FLUSH: + (void)snprintf(msg + len, sizeof(msg) - len, "FLUSH."); + break; + case HIO_WRITE: + (void)snprintf(msg + len, sizeof(msg) - len, + "WRITE(%ju, %ju).", (uintmax_t)hio->hio_offset, + (uintmax_t)hio->hio_length); + break; + default: + (void)snprintf(msg + len, sizeof(msg) - len, + "UNKNOWN(%u).", (unsigned int)hio->hio_cmd); + break; + } + } + pjdlog_common(loglevel, debuglevel, error, "%s", msg); +} + +static int +requnpack(struct hast_resource *res, struct hio *hio) +{ + + hio->hio_cmd = nv_get_uint8(hio->hio_nv, "cmd"); + if (hio->hio_cmd == 0) { + pjdlog_error("Header contains no 'cmd' field."); + hio->hio_error = EINVAL; + goto end; + } + switch (hio->hio_cmd) { + case HIO_READ: + case HIO_WRITE: + case HIO_DELETE: + hio->hio_offset = nv_get_uint64(hio->hio_nv, "offset"); + if (nv_error(hio->hio_nv) != 0) { + pjdlog_error("Header is missing 'offset' field."); + hio->hio_error = EINVAL; + goto end; + } + hio->hio_length = nv_get_uint64(hio->hio_nv, "length"); + if (nv_error(hio->hio_nv) != 0) { + pjdlog_error("Header is missing 'length' field."); + hio->hio_error = EINVAL; + goto end; + } + if (hio->hio_length == 0) { + pjdlog_error("Data length is zero."); + hio->hio_error = EINVAL; + goto end; + } + if (hio->hio_length > MAXPHYS) { + pjdlog_error("Data length is too large (%ju > %ju).", + (uintmax_t)hio->hio_length, (uintmax_t)MAXPHYS); + hio->hio_error = EINVAL; + goto end; + } + if ((hio->hio_offset % res->hr_local_sectorsize) != 0) { + pjdlog_error("Offset %ju is not multiple of sector size.", + (uintmax_t)hio->hio_offset); + hio->hio_error = EINVAL; + goto end; + } + if ((hio->hio_length % res->hr_local_sectorsize) != 0) { + pjdlog_error("Length %ju is not multiple of sector size.", + (uintmax_t)hio->hio_length); + hio->hio_error = EINVAL; + goto end; + } + if (hio->hio_offset + hio->hio_length > + (uint64_t)res->hr_datasize) { + pjdlog_error("Data offset is too large (%ju > %ju).", + (uintmax_t)(hio->hio_offset + hio->hio_length), + (uintmax_t)res->hr_datasize); + hio->hio_error = EINVAL; + goto end; + } + break; + default: + pjdlog_error("Header contains invalid 'cmd' (%hhu).", + hio->hio_cmd); + hio->hio_error = EINVAL; + goto end; + } + hio->hio_error = 0; +end: + return (hio->hio_error); +} + +/* + * Thread receives requests from the primary node. + */ +static void * +recv_thread(void *arg) +{ + struct hast_resource *res = arg; + struct hio *hio; + bool wakeup; + + for (;;) { + pjdlog_debug(2, "recv: Taking free request."); + mtx_lock(&hio_free_list_lock); + while ((hio = TAILQ_FIRST(&hio_free_list)) == NULL) { + pjdlog_debug(2, "recv: No free requests, waiting."); + cv_wait(&hio_free_list_cond, &hio_free_list_lock); + } + TAILQ_REMOVE(&hio_free_list, hio, hio_next); + mtx_unlock(&hio_free_list_lock); + pjdlog_debug(2, "recv: (%p) Got request.", hio); + if (hast_proto_recv_hdr(res->hr_remotein, &hio->hio_nv) < 0) { + pjdlog_exit(EX_TEMPFAIL, + "Unable to receive request header"); + } + if (requnpack(res, hio) != 0) + goto send_queue; + reqlog(LOG_DEBUG, 2, -1, hio, + "recv: (%p) Got request header: ", hio); + if (hio->hio_cmd == HIO_WRITE) { + if (hast_proto_recv_data(res, res->hr_remotein, + hio->hio_nv, hio->hio_data, MAXPHYS) < 0) { + pjdlog_exit(EX_TEMPFAIL, + "Unable to receive reply data"); + } + } + pjdlog_debug(2, "recv: (%p) Moving request to the disk queue.", + hio); + mtx_lock(&hio_disk_list_lock); + wakeup = TAILQ_EMPTY(&hio_disk_list); + TAILQ_INSERT_TAIL(&hio_disk_list, hio, hio_next); + mtx_unlock(&hio_disk_list_lock); + if (wakeup) + cv_signal(&hio_disk_list_cond); + continue; +send_queue: + pjdlog_debug(2, "recv: (%p) Moving request to the send queue.", + hio); + mtx_lock(&hio_send_list_lock); + wakeup = TAILQ_EMPTY(&hio_send_list); + TAILQ_INSERT_TAIL(&hio_send_list, hio, hio_next); + mtx_unlock(&hio_send_list_lock); + if (wakeup) + cv_signal(&hio_send_list_cond); + } + /* NOTREACHED */ + return (NULL); +} + +/* + * Thread reads from or writes to local component and also handles DELETE and + * FLUSH requests. + */ +static void * +disk_thread(void *arg) +{ + struct hast_resource *res = arg; + struct hio *hio; + ssize_t ret; + bool clear_activemap, wakeup; + + clear_activemap = true; + + for (;;) { + pjdlog_debug(2, "disk: Taking request."); + mtx_lock(&hio_disk_list_lock); + while ((hio = TAILQ_FIRST(&hio_disk_list)) == NULL) { + pjdlog_debug(2, "disk: No requests, waiting."); + cv_wait(&hio_disk_list_cond, &hio_disk_list_lock); + } + TAILQ_REMOVE(&hio_disk_list, hio, hio_next); + mtx_unlock(&hio_disk_list_lock); + while (clear_activemap) { + unsigned char *map; + size_t mapsize; + + /* + * When first request is received, it means that primary + * already received our activemap, merged it and stored + * locally. We can now safely clear our activemap. + */ + mapsize = + activemap_calc_ondisk_size(res->hr_local_mediasize - + METADATA_SIZE, res->hr_extentsize, + res->hr_local_sectorsize); + map = calloc(1, mapsize); + if (map == NULL) { + pjdlog_warning("Unable to allocate memory to clear local activemap."); + break; + } + if (pwrite(res->hr_localfd, map, mapsize, + METADATA_SIZE) != (ssize_t)mapsize) { + pjdlog_errno(LOG_WARNING, + "Unable to store cleared activemap"); + free(map); + break; + } + free(map); + clear_activemap = false; + pjdlog_debug(1, "Local activemap cleared."); + } + reqlog(LOG_DEBUG, 2, -1, hio, "disk: (%p) Got request: ", hio); + /* Handle the actual request. */ + switch (hio->hio_cmd) { + case HIO_READ: + ret = pread(res->hr_localfd, hio->hio_data, + hio->hio_length, + hio->hio_offset + res->hr_localoff); + if (ret < 0) + hio->hio_error = errno; + else if (ret != (int64_t)hio->hio_length) + hio->hio_error = EIO; + else + hio->hio_error = 0; + break; + case HIO_WRITE: + ret = pwrite(res->hr_localfd, hio->hio_data, + hio->hio_length, + hio->hio_offset + res->hr_localoff); + if (ret < 0) + hio->hio_error = errno; + else if (ret != (int64_t)hio->hio_length) + hio->hio_error = EIO; + else + hio->hio_error = 0; + break; + case HIO_DELETE: + ret = g_delete(res->hr_localfd, + hio->hio_offset + res->hr_localoff, + hio->hio_length); + if (ret < 0) + hio->hio_error = errno; + else + hio->hio_error = 0; + break; + case HIO_FLUSH: + ret = g_flush(res->hr_localfd); + if (ret < 0) + hio->hio_error = errno; + else + hio->hio_error = 0; + break; + } + if (hio->hio_error != 0) { + reqlog(LOG_ERR, 0, hio->hio_error, hio, + "Request failed: "); + } + pjdlog_debug(2, "disk: (%p) Moving request to the send queue.", + hio); + mtx_lock(&hio_send_list_lock); + wakeup = TAILQ_EMPTY(&hio_send_list); + TAILQ_INSERT_TAIL(&hio_send_list, hio, hio_next); + mtx_unlock(&hio_send_list_lock); + if (wakeup) + cv_signal(&hio_send_list_cond); + } + /* NOTREACHED */ + return (NULL); +} + +/* + * Thread sends requests back to primary node. + */ +static void * +send_thread(void *arg) +{ + struct hast_resource *res = arg; + struct nv *nvout; + struct hio *hio; + void *data; + size_t length; + bool wakeup; + + for (;;) { + pjdlog_debug(2, "send: Taking request."); + mtx_lock(&hio_send_list_lock); + while ((hio = TAILQ_FIRST(&hio_send_list)) == NULL) { + pjdlog_debug(2, "send: No requests, waiting."); + cv_wait(&hio_send_list_cond, &hio_send_list_lock); + } + TAILQ_REMOVE(&hio_send_list, hio, hio_next); + mtx_unlock(&hio_send_list_lock); + reqlog(LOG_DEBUG, 2, -1, hio, "send: (%p) Got request: ", hio); + nvout = nv_alloc(); + /* Copy sequence number. */ + nv_add_uint64(nvout, nv_get_uint64(hio->hio_nv, "seq"), "seq"); + switch (hio->hio_cmd) { + case HIO_READ: + if (hio->hio_error == 0) { + data = hio->hio_data; + length = hio->hio_length; + break; + } + /* + * We send no data in case of an error. + */ + /* FALLTHROUGH */ + case HIO_DELETE: + case HIO_FLUSH: + case HIO_WRITE: + data = NULL; + length = 0; + break; + default: + abort(); + break; + } + if (hio->hio_error != 0) + nv_add_int16(nvout, hio->hio_error, "error"); + if (hast_proto_send(res, res->hr_remoteout, nvout, data, + length) < 0) { + pjdlog_exit(EX_TEMPFAIL, "Unable to send reply."); + } + nv_free(nvout); + pjdlog_debug(2, "disk: (%p) Moving request to the free queue.", + hio); + nv_free(hio->hio_nv); + hio->hio_error = 0; + mtx_lock(&hio_free_list_lock); + wakeup = TAILQ_EMPTY(&hio_free_list); + TAILQ_INSERT_TAIL(&hio_free_list, hio, hio_next); + mtx_unlock(&hio_free_list_lock); + if (wakeup) + cv_signal(&hio_free_list_cond); + } + /* NOTREACHED */ + return (NULL); +} diff --git a/sbin/hastd/subr.c b/sbin/hastd/subr.c new file mode 100644 index 00000000000..16ea93f12e2 --- /dev/null +++ b/sbin/hastd/subr.c @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 "hast.h" +#include "subr.h" + +int +provinfo(struct hast_resource *res, bool dowrite) +{ + struct stat sb; + + assert(res->hr_localpath != NULL && res->hr_localpath[0] != '\0'); + + if (res->hr_localfd == -1) { + res->hr_localfd = open(res->hr_localpath, + dowrite ? O_RDWR : O_RDONLY); + if (res->hr_localfd < 0) { + KEEP_ERRNO(pjdlog_errno(LOG_ERR, "Unable to open %s", + res->hr_localpath)); + return (-1); + } + } + if (fstat(res->hr_localfd, &sb) < 0) { + KEEP_ERRNO(pjdlog_errno(LOG_ERR, "Unable to stat %s", + res->hr_localpath)); + return (-1); + } + if (S_ISCHR(sb.st_mode)) { + /* + * If this is character device, it is most likely GEOM provider. + */ + if (ioctl(res->hr_localfd, DIOCGMEDIASIZE, + &res->hr_local_mediasize) < 0) { + KEEP_ERRNO(pjdlog_errno(LOG_ERR, + "Unable obtain provider %s mediasize", + res->hr_localpath)); + return (-1); + } + if (ioctl(res->hr_localfd, DIOCGSECTORSIZE, + &res->hr_local_sectorsize) < 0) { + KEEP_ERRNO(pjdlog_errno(LOG_ERR, + "Unable obtain provider %s sectorsize", + res->hr_localpath)); + return (-1); + } + } else if (S_ISREG(sb.st_mode)) { + /* + * We also support regular files for which we hardcode + * sector size of 512 bytes. + */ + res->hr_local_mediasize = sb.st_size; + res->hr_local_sectorsize = 512; + } else { + /* + * We support no other file types. + */ + pjdlog_error("%s is neither GEOM provider nor regular file.", + res->hr_localpath); + errno = EFTYPE; + return (-1); + } + return (0); +} + +const char * +role2str(int role) +{ + + switch (role) { + case HAST_ROLE_INIT: + return ("init"); + case HAST_ROLE_PRIMARY: + return ("primary"); + case HAST_ROLE_SECONDARY: + return ("secondary"); + } + return ("unknown"); +} diff --git a/sbin/hastd/subr.h b/sbin/hastd/subr.h new file mode 100644 index 00000000000..c486f5c608d --- /dev/null +++ b/sbin/hastd/subr.h @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _SUBR_H_ +#define _SUBR_H_ + +#include +#include + +#include "hast.h" + +#define KEEP_ERRNO(work) do { \ + int _rerrno; \ + \ + _rerrno = errno; \ + work; \ + errno = _rerrno; \ +} while (0) + +int provinfo(struct hast_resource *res, bool dowrite); +const char *role2str(int role); + +#endif /* !_SUBR_H_ */ diff --git a/sbin/hastd/synch.h b/sbin/hastd/synch.h new file mode 100644 index 00000000000..7269aea6607 --- /dev/null +++ b/sbin/hastd/synch.h @@ -0,0 +1,162 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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 _SYNCH_H_ +#define _SYNCH_H_ + +#include +#include +#include +#include + +static __inline void +mtx_init(pthread_mutex_t *lock) +{ + int error; + + error = pthread_mutex_init(lock, NULL); + assert(error == 0); +} +static __inline void +mtx_lock(pthread_mutex_t *lock) +{ + int error; + + error = pthread_mutex_lock(lock); + assert(error == 0); +} +static __inline bool +mtx_trylock(pthread_mutex_t *lock) +{ + int error; + + error = pthread_mutex_trylock(lock); + assert(error == 0 || error == EBUSY); + return (error == 0); +} +static __inline void +mtx_unlock(pthread_mutex_t *lock) +{ + int error; + + error = pthread_mutex_unlock(lock); + assert(error == 0); +} + +static __inline void +rw_init(pthread_rwlock_t *lock) +{ + int error; + + error = pthread_rwlock_init(lock, NULL); + assert(error == 0); +} +static __inline void +rw_rlock(pthread_rwlock_t *lock) +{ + int error; + + error = pthread_rwlock_rdlock(lock); + assert(error == 0); +} +static __inline void +rw_wlock(pthread_rwlock_t *lock) +{ + int error; + + error = pthread_rwlock_wrlock(lock); + assert(error == 0); +} +static __inline void +rw_unlock(pthread_rwlock_t *lock) +{ + int error; + + error = pthread_rwlock_unlock(lock); + assert(error == 0); +} + +static __inline void +cv_init(pthread_cond_t *cv) +{ + pthread_condattr_t attr; + int error; + + error = pthread_condattr_init(&attr); + assert(error == 0); + error = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + assert(error == 0); + error = pthread_cond_init(cv, &attr); + assert(error == 0); +} +static __inline void +cv_wait(pthread_cond_t *cv, pthread_mutex_t *lock) +{ + int error; + + error = pthread_cond_wait(cv, lock); + assert(error == 0); +} +static __inline bool +cv_timedwait(pthread_cond_t *cv, pthread_mutex_t *lock, int timeout) +{ + struct timespec ts; + int error; + + if (timeout == 0) { + cv_wait(cv, lock); + return (false); + } + + error = clock_gettime(CLOCK_MONOTONIC, &ts); + assert(error == 0); + ts.tv_sec += timeout; + error = pthread_cond_timedwait(cv, lock, &ts); + assert(error == 0 || error == ETIMEDOUT); + return (error == ETIMEDOUT); +} +static __inline void +cv_signal(pthread_cond_t *cv) +{ + int error; + + error = pthread_cond_signal(cv); + assert(error == 0); +} +static __inline void +cv_broadcast(pthread_cond_t *cv) +{ + int error; + + error = pthread_cond_broadcast(cv); + assert(error == 0); +} +#endif /* !_SYNCH_H_ */ diff --git a/sbin/hastd/token.l b/sbin/hastd/token.l new file mode 100644 index 00000000000..7b80384e28b --- /dev/null +++ b/sbin/hastd/token.l @@ -0,0 +1,66 @@ +%{ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHORS 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 AUTHORS 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$ + */ + +#include +#include + +#include "hast.h" + +#include "y.tab.h" + +int depth; +int lineno; + +#define DP do { } while (0) +%} + +%% +control { DP; return CONTROL; } +listen { DP; return LISTEN; } +port { DP; return PORT; } +replication { DP; return REPLICATION; } +resource { DP; return RESOURCE; } +name { DP; return NAME; } +local { DP; return LOCAL; } +remote { DP; return REMOTE; } +on { DP; return ON; } +fullsync { DP; return FULLSYNC; } +memsync { DP; return MEMSYNC; } +async { DP; return ASYNC; } +[0-9]+ { DP; yylval.num = atoi(yytext); return NUM; } +[a-zA-Z0-9\.\-_/\:]+ { DP; yylval.str = strdup(yytext); return STR; } +\{ { DP; depth++; return OB; } +\} { DP; depth--; return CB; } +#.*$ /* ignore comments */; +\n { lineno++; } +[ \t]+ /* ignore whitespace */; +%% diff --git a/share/examples/Makefile b/share/examples/Makefile index 315eb913519..99d92c0d99a 100644 --- a/share/examples/Makefile +++ b/share/examples/Makefile @@ -13,6 +13,7 @@ LDIRS= BSD_daemon \ drivers \ etc \ find_interface \ + hast \ ibcs2 \ ipfw \ kld \ @@ -69,6 +70,11 @@ XFILES= BSD_daemon/FreeBSD.pfa \ find_interface/Makefile \ find_interface/README \ find_interface/find_interface.c \ + hast/ucarp.sh \ + hast/ucarp_down.sh \ + hast/ucarp_up.sh \ + hast/vip-down.sh \ + hast/vip-up.sh \ ibcs2/README \ ibcs2/hello.uu \ ipfw/change_rules.sh \ diff --git a/share/examples/hast/ucarp.sh b/share/examples/hast/ucarp.sh new file mode 100755 index 00000000000..6a02c89fe97 --- /dev/null +++ b/share/examples/hast/ucarp.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# +# Copyright (c) 2010 The FreeBSD Foundation +# All rights reserved. +# +# This software was developed by Pawel Jakub Dawidek under sponsorship from +# the FreeBSD Foundation. +# +# 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 AUTHORS 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 AUTHORS 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$ + +# Shared IP address, unused for now. +addr="10.99.0.3" +# Password for UCARP communication. +pass="password" +# First node IP and interface for UCARP communication. +nodea_srcip="10.99.0.1" +nodea_ifnet="bge0" +# Second node IP and interface for UCARP communication. +nodeb_srcip="10.99.0.2" +nodeb_ifnet="em3" + +export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + +vhid="1" +upscript="/root/hast/sbin/hastd/vip-up.sh" +downscript="/root/hast/sbin/hastd/vip-down.sh" + +ifconfig "${nodea_ifnet}" 2>/dev/null | grep -q "inet ${nodea_srcip} " +if [ $? -eq 0 ]; then + srcip="${nodea_srcip}" + ifnet="${nodea_ifnet}" + node="node A" +fi +ifconfig "${nodeb_ifnet}" 2>/dev/null | grep -q "inet ${nodeb_srcip} " +if [ $? -eq 0 ]; then + if [ -n "${srcip}" -o -n "${ifnet}" ]; then + echo "Unable to determine which node is this (both match)." >/dev/stderr + exit 1 + fi + srcip="${nodeb_srcip}" + ifnet="${nodeb_ifnet}" + node="node B" +fi +if [ -z "${srcip}" -o -z "${ifnet}" ]; then + echo "Unable to determine which node is this (none match)." >/dev/stderr + exit 1 +fi +ucarp -i ${ifnet} -s ${srcip} -v ${vhid} -a ${addr} -p ${pass} -u "${upscript}" -d "${downscript}" diff --git a/share/examples/hast/ucarp_down.sh b/share/examples/hast/ucarp_down.sh new file mode 100755 index 00000000000..a5b34281e3b --- /dev/null +++ b/share/examples/hast/ucarp_down.sh @@ -0,0 +1,98 @@ +#!/bin/sh +# +# Copyright (c) 2010 The FreeBSD Foundation +# All rights reserved. +# +# This software was developed by Pawel Jakub Dawidek under sponsorship from +# the FreeBSD Foundation. +# +# 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 AUTHORS 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 AUTHORS 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$ + +# Resource name as defined in /etc/hast.conf. +resource="test" +# Supported file system types: UFS, ZFS +fstype="UFS" +# ZFS pool name. Required only when fstype == ZFS. +pool="test" +# File system mount point. Required only when fstype == UFS. +mountpoint="/mnt/test" +# Name of HAST provider as defined in /etc/hast.conf. +# Required only when fstype == UFS. +device="/dev/hast/${resource}" + +export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + +# KIll UP script if it still runs in the background. +sig="TERM" +for i in `jot 30`; do + pgid=`pgrep -f ucarp_up.sh | head -1` + [ -n "${pgid}" ] || break + kill -${sig} -- -${pgid} + sig="KILL" + sleep 1 +done +if [ -n "${pgid}" ]; then + logger -p local0.error -t hast "UCARP UP process for resource ${resource} is still running after 30 seconds." + exit 1 +fi +logger -p local0.debug -t hast "UCARP UP is not running." + +case "${fstype}" in +UFS) + mount | egrep -q "^${device} on " + if [ $? -eq 0 ]; then + # Forcibly unmount file system. + out=`umount -f "${mountpoint}" 2>&1` + if [ $? -ne 0 ]; then + logger -p local0.error -t hast "Unable to unmount file system for resource ${resource}: ${out}." + exit 1 + fi + logger -p local0.debug -t hast "File system for resource ${resource} unmounted." + fi + ;; +ZFS) + zpool list | egrep -q "^${pool} " + if [ $? -eq 0 ]; then + # Forcibly export file pool. + out=`zpool export -f "${pool}" 2>&1` + if [ $? -ne 0 ]; then + logger -p local0.error -t hast "Unable to export pool for resource ${resource}: ${out}." + exit 1 + fi + logger -p local0.debug -t hast "ZFS pool for resource ${resource} exported." + fi + ;; +esac + +# Change role to secondary for our resource. +out=`hastctl role secondary "${resource}" 2>&1` +if [ $? -ne 0 ]; then + logger -p local0.error -t hast "Unable to change to role to secondary for resource ${resource}: ${out}." + exit 1 +fi +logger -p local0.debug -t hast "Role for resource ${resource} changed to secondary." + +logger -p local0.info -t hast "Successfully switched to secondary for resource ${resource}." + +exit 0 diff --git a/share/examples/hast/ucarp_up.sh b/share/examples/hast/ucarp_up.sh new file mode 100755 index 00000000000..9e56040bebd --- /dev/null +++ b/share/examples/hast/ucarp_up.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# +# Copyright (c) 2010 The FreeBSD Foundation +# All rights reserved. +# +# This software was developed by Pawel Jakub Dawidek under sponsorship from +# the FreeBSD Foundation. +# +# 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 AUTHORS 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 AUTHORS 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$ + +# Resource name as defined in /etc/hast.conf. +resource="test" +# Supported file system types: UFS, ZFS +fstype="UFS" +# ZFS pool name. Required only when fstype == ZFS. +pool="test" +# File system mount point. Required only when fstype == UFS. +mountpoint="/mnt/test" +# Name of HAST provider as defined in /etc/hast.conf. +device="/dev/hast/${resource}" + +export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + +# If there is secondary worker process, it means that remote primary process is +# still running. We have to wait for it to terminate. +for i in `jot 30`; do + pgrep -f "hastd: ${resource} \(secondary\)" >/dev/null 2>&1 || break + sleep 1 +done +if pgrep -f "hastd: ${resource} \(secondary\)" >/dev/null 2>&1; then + logger -p local0.error -t hast "Secondary process for resource ${resource} is still running after 30 seconds." + exit 1 +fi +logger -p local0.debug -t hast "Secondary process in not running." + +# Change role to primary for our resource. +out=`hastctl role primary "${resource}" 2>&1` +if [ $? -ne 0 ]; then + logger -p local0.error -t hast "Unable to change to role to primary for resource ${resource}: ${out}." + exit 1 +fi +# Wait few seconds for provider to appear. +for i in `jot 50`; do + [ -c "${device}" ] && break + sleep 0.1 +done +if [ ! -c "${device}" ]; then + logger -p local0.error -t hast "Device ${device} didn't appear." + exit 1 +fi +logger -p local0.debug -t hast "Role for resource ${resource} changed to primary." + +case "${fstype}" in +UFS) + # Check the file system. + fsck -y -t ufs "${device}" >/dev/null 2>&1 + if [ $? -ne 0 ]; then + logger -p local0.error -t hast "File system check for resource ${resource} failed." + exit 1 + fi + logger -p local0.debug -t hast "File system check for resource ${resource} finished." + # Mount the file system. + out=`mount -t ufs "${device}" "${mountpoint}" 2>&1` + if [ $? -ne 0 ]; then + logger -p local0.error -t hast "File system mount for resource ${resource} failed: ${out}." + exit 1 + fi + logger -p local0.debug -t hast "File system for resource ${resource} mounted." + ;; +ZFS) + # Import ZFS pool. Do it forcibly as it remembers hostid of + # the other cluster node. + out=`zpool import -f "${pool}" 2>&1` + if [ $? -ne 0 ]; then + logger -p local0.error -t hast "ZFS pool import for resource ${resource} failed: ${out}." + exit 1 + fi + logger -p local0.debug -t hast "ZFS pool for resource ${resource} imported." + ;; +esac + +logger -p local0.info -t hast "Successfully switched to primary for resource ${resource}." + +exit 0 diff --git a/share/examples/hast/vip-down.sh b/share/examples/hast/vip-down.sh new file mode 100755 index 00000000000..5e47609d9e9 --- /dev/null +++ b/share/examples/hast/vip-down.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# $FreeBSD$ + +/root/hast/sbin/hastd/ucarp_down.sh +exit 0 diff --git a/share/examples/hast/vip-up.sh b/share/examples/hast/vip-up.sh new file mode 100755 index 00000000000..61dabe9c3da --- /dev/null +++ b/share/examples/hast/vip-up.sh @@ -0,0 +1,7 @@ +#!/bin/sh +# $FreeBSD$ + +set -m +/root/hast/sbin/hastd/ucarp_up.sh & +set +m +exit 0 diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index 5c55b9097bd..07f2fb81665 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -1645,6 +1645,27 @@ is set to .Dq Li YES , these are the flags to pass to .Xr inetd 8 . +.It Va hastd_enable +.Pq Vt bool +If set to +.Dq Li YES , +run the +.Xr hastd 8 +daemon. +.It Va hastd_program +.Pq Vt str +Path to +.Xr hastd 8 +(default +.Pa /sbin/hastd ) . +.It Va hastd_flags +.Pq Vt str +If +.Va hastd_enable +is set to +.Dq Li YES , +these are the flags to pass to +.Xr hastd 8 . .It Va named_enable .Pq Vt bool If set to diff --git a/sys/geom/gate/g_gate.c b/sys/geom/gate/g_gate.c index 26df0f41855..dd69a87ebfa 100644 --- a/sys/geom/gate/g_gate.c +++ b/sys/geom/gate/g_gate.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2004-2006 Pawel Jakub Dawidek + * Copyright (c) 2009-2010 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Pawel Jakub Dawidek + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -53,9 +57,14 @@ static MALLOC_DEFINE(M_GATE, "gg_data", "GEOM Gate Data"); SYSCTL_DECL(_kern_geom); SYSCTL_NODE(_kern_geom, OID_AUTO, gate, CTLFLAG_RW, 0, "GEOM_GATE stuff"); -static u_int g_gate_debug = 0; -SYSCTL_UINT(_kern_geom_gate, OID_AUTO, debug, CTLFLAG_RW, &g_gate_debug, 0, +static int g_gate_debug = 0; +TUNABLE_INT("kern.geom.gate.debug", &g_gate_debug); +SYSCTL_INT(_kern_geom_gate, OID_AUTO, debug, CTLFLAG_RW, &g_gate_debug, 0, "Debug level"); +static u_int g_gate_maxunits = 256; +TUNABLE_INT("kern.geom.gate.maxunits", &g_gate_maxunits); +SYSCTL_UINT(_kern_geom_gate, OID_AUTO, maxunits, CTLFLAG_RDTUN, + &g_gate_maxunits, 0, "Maximum number of ggate devices"); struct g_class g_gate_class = { .name = G_GATE_CLASS_NAME, @@ -71,10 +80,9 @@ static struct cdevsw g_gate_cdevsw = { }; -static LIST_HEAD(, g_gate_softc) g_gate_list = - LIST_HEAD_INITIALIZER(g_gate_list); -static struct mtx g_gate_list_mtx; - +static struct g_gate_softc **g_gate_units; +static u_int g_gate_nunits; +static struct mtx g_gate_units_lock; static int g_gate_destroy(struct g_gate_softc *sc, boolean_t force) @@ -84,13 +92,13 @@ g_gate_destroy(struct g_gate_softc *sc, boolean_t force) struct bio *bp; g_topology_assert(); - mtx_assert(&g_gate_list_mtx, MA_OWNED); + mtx_assert(&g_gate_units_lock, MA_OWNED); pp = sc->sc_provider; if (!force && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { - mtx_unlock(&g_gate_list_mtx); + mtx_unlock(&g_gate_units_lock); return (EBUSY); } - mtx_unlock(&g_gate_list_mtx); + mtx_unlock(&g_gate_units_lock); mtx_lock(&sc->sc_queue_mtx); if ((sc->sc_flags & G_GATE_FLAG_DESTROY) == 0) sc->sc_flags |= G_GATE_FLAG_DESTROY; @@ -101,38 +109,29 @@ g_gate_destroy(struct g_gate_softc *sc, boolean_t force) g_orphan_provider(pp, ENXIO); callout_drain(&sc->sc_callout); mtx_lock(&sc->sc_queue_mtx); - for (;;) { - bp = bioq_first(&sc->sc_inqueue); - if (bp != NULL) { - bioq_remove(&sc->sc_inqueue, bp); - sc->sc_queue_count--; - G_GATE_LOGREQ(1, bp, "Request canceled."); - g_io_deliver(bp, ENXIO); - } else { - break; - } + while ((bp = bioq_first(&sc->sc_inqueue)) != NULL) { + bioq_remove(&sc->sc_inqueue, bp); + sc->sc_queue_count--; + G_GATE_LOGREQ(1, bp, "Request canceled."); + g_io_deliver(bp, ENXIO); } - for (;;) { - bp = bioq_first(&sc->sc_outqueue); - if (bp != NULL) { - bioq_remove(&sc->sc_outqueue, bp); - sc->sc_queue_count--; - G_GATE_LOGREQ(1, bp, "Request canceled."); - g_io_deliver(bp, ENXIO); - } else { - break; - } + while ((bp = bioq_first(&sc->sc_outqueue)) != NULL) { + bioq_remove(&sc->sc_outqueue, bp); + sc->sc_queue_count--; + G_GATE_LOGREQ(1, bp, "Request canceled."); + g_io_deliver(bp, ENXIO); } mtx_unlock(&sc->sc_queue_mtx); g_topology_unlock(); - mtx_lock(&g_gate_list_mtx); + mtx_lock(&g_gate_units_lock); /* One reference is ours. */ sc->sc_ref--; - while (sc->sc_ref > 0) { - msleep(&sc->sc_ref, &g_gate_list_mtx, 0, "gg:destroy", 0); - } - LIST_REMOVE(sc, sc_next); - mtx_unlock(&g_gate_list_mtx); + while (sc->sc_ref > 0) + msleep(&sc->sc_ref, &g_gate_units_lock, 0, "gg:destroy", 0); + g_gate_units[sc->sc_unit] = NULL; + KASSERT(g_gate_nunits > 0, ("negative g_gate_nunits?")); + g_gate_nunits--; + mtx_unlock(&g_gate_units_lock); mtx_destroy(&sc->sc_queue_mtx); g_topology_lock(); G_GATE_DEBUG(0, "Device %s destroyed.", gp->name); @@ -196,7 +195,7 @@ g_gate_start(struct bio *bp) if (sc->sc_queue_count > sc->sc_queue_size) { mtx_unlock(&sc->sc_queue_mtx); G_GATE_LOGREQ(1, bp, "Queue full, request canceled."); - g_io_deliver(bp, EIO); + g_io_deliver(bp, ENOMEM); return; } @@ -211,18 +210,29 @@ g_gate_start(struct bio *bp) } static struct g_gate_softc * -g_gate_hold(u_int unit) +g_gate_hold(u_int unit, const char *name) { - struct g_gate_softc *sc; + struct g_gate_softc *sc = NULL; - mtx_lock(&g_gate_list_mtx); - LIST_FOREACH(sc, &g_gate_list, sc_next) { - if (sc->sc_unit == unit) + mtx_lock(&g_gate_units_lock); + if (unit >= 0 && unit < g_gate_maxunits) + sc = g_gate_units[unit]; + else if (unit == G_GATE_NAME_GIVEN) { + KASSERT(name != NULL, ("name is NULL")); + for (unit = 0; unit < g_gate_maxunits; unit++) { + if (g_gate_units[unit] == NULL) + continue; + if (strcmp(name, + g_gate_units[unit]->sc_provider->name) != 0) { + continue; + } + sc = g_gate_units[unit]; break; + } } if (sc != NULL) sc->sc_ref++; - mtx_unlock(&g_gate_list_mtx); + mtx_unlock(&g_gate_units_lock); return (sc); } @@ -231,40 +241,34 @@ g_gate_release(struct g_gate_softc *sc) { g_topology_assert_not(); - mtx_lock(&g_gate_list_mtx); + mtx_lock(&g_gate_units_lock); sc->sc_ref--; KASSERT(sc->sc_ref >= 0, ("Negative sc_ref for %s.", sc->sc_name)); - if (sc->sc_ref == 0 && (sc->sc_flags & G_GATE_FLAG_DESTROY) != 0) { + if (sc->sc_ref == 0 && (sc->sc_flags & G_GATE_FLAG_DESTROY) != 0) wakeup(&sc->sc_ref); - mtx_unlock(&g_gate_list_mtx); - } else { - mtx_unlock(&g_gate_list_mtx); - } + mtx_unlock(&g_gate_units_lock); } static int -g_gate_getunit(int unit) +g_gate_getunit(int unit, int *errorp) { - struct g_gate_softc *sc; - mtx_assert(&g_gate_list_mtx, MA_OWNED); + mtx_assert(&g_gate_units_lock, MA_OWNED); if (unit >= 0) { - LIST_FOREACH(sc, &g_gate_list, sc_next) { - if (sc->sc_unit == unit) - return (-1); - } + if (unit >= g_gate_maxunits) + *errorp = EINVAL; + else if (g_gate_units[unit] == NULL) + return (unit); + else + *errorp = EEXIST; } else { - unit = 0; -once_again: - LIST_FOREACH(sc, &g_gate_list, sc_next) { - if (sc->sc_unit == unit) { - if (++unit > 666) - return (-1); - goto once_again; - } + for (unit = 0; unit < g_gate_maxunits; unit++) { + if (g_gate_units[unit] == NULL) + return (unit); } + *errorp = ENFILE; } - return (unit); + return (-1); } static void @@ -276,7 +280,7 @@ g_gate_guard(void *arg) sc = arg; binuptime(&curtime); - g_gate_hold(sc->sc_unit); + g_gate_hold(sc->sc_unit, NULL); mtx_lock(&sc->sc_queue_mtx); TAILQ_FOREACH_SAFE(bp, &sc->sc_inqueue.queue, bio_queue, bp2) { if (curtime.sec - bp->bio_t0.sec < 5) @@ -311,7 +315,7 @@ g_gate_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, sc = gp->softc; if (sc == NULL || pp != NULL || cp != NULL) return; - g_gate_hold(sc->sc_unit); + g_gate_hold(sc->sc_unit, NULL); if ((sc->sc_flags & G_GATE_FLAG_READONLY) != 0) { sbuf_printf(sb, "%s%s\n", indent, "read-only"); } else if ((sc->sc_flags & G_GATE_FLAG_WRITEONLY) != 0) { @@ -328,6 +332,7 @@ g_gate_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, sbuf_printf(sb, "%s%u\n", indent, sc->sc_queue_size); sbuf_printf(sb, "%s%u\n", indent, sc->sc_ref); + sbuf_printf(sb, "%s%d\n", indent, sc->sc_unit); g_topology_unlock(); g_gate_release(sc); g_topology_lock(); @@ -339,6 +344,8 @@ g_gate_create(struct g_gate_ctl_create *ggio) struct g_gate_softc *sc; struct g_geom *gp; struct g_provider *pp; + char name[NAME_MAX]; + int error = 0, unit; if (ggio->gctl_mediasize == 0) { G_GATE_DEBUG(1, "Invalid media size."); @@ -357,15 +364,22 @@ g_gate_create(struct g_gate_ctl_create *ggio) G_GATE_DEBUG(1, "Invalid flags."); return (EINVAL); } - if (ggio->gctl_unit < -1) { + if (ggio->gctl_unit != G_GATE_UNIT_AUTO && + ggio->gctl_unit != G_GATE_NAME_GIVEN && + ggio->gctl_unit < 0) { G_GATE_DEBUG(1, "Invalid unit number."); return (EINVAL); } + if (ggio->gctl_unit == G_GATE_NAME_GIVEN && + ggio->gctl_name[0] == '\0') { + G_GATE_DEBUG(1, "No device name."); + return (EINVAL); + } sc = malloc(sizeof(*sc), M_GATE, M_WAITOK | M_ZERO); sc->sc_flags = (ggio->gctl_flags & G_GATE_USERFLAGS); strlcpy(sc->sc_info, ggio->gctl_info, sizeof(sc->sc_info)); - sc->sc_seq = 0; + sc->sc_seq = 1; bioq_init(&sc->sc_inqueue); bioq_init(&sc->sc_outqueue); mtx_init(&sc->sc_queue_mtx, "gg:queue", NULL, MTX_DEF); @@ -375,26 +389,44 @@ g_gate_create(struct g_gate_ctl_create *ggio) sc->sc_queue_size = G_GATE_MAX_QUEUE_SIZE; sc->sc_timeout = ggio->gctl_timeout; callout_init(&sc->sc_callout, CALLOUT_MPSAFE); - mtx_lock(&g_gate_list_mtx); - ggio->gctl_unit = g_gate_getunit(ggio->gctl_unit); - if (ggio->gctl_unit == -1) { - mtx_unlock(&g_gate_list_mtx); + mtx_lock(&g_gate_units_lock); + sc->sc_unit = g_gate_getunit(ggio->gctl_unit, &error); + if (sc->sc_unit < 0) { + mtx_unlock(&g_gate_units_lock); mtx_destroy(&sc->sc_queue_mtx); free(sc, M_GATE); - return (EBUSY); + return (error); } - sc->sc_unit = ggio->gctl_unit; - LIST_INSERT_HEAD(&g_gate_list, sc, sc_next); - mtx_unlock(&g_gate_list_mtx); + if (ggio->gctl_unit == G_GATE_NAME_GIVEN) + snprintf(name, sizeof(name), "%s", ggio->gctl_name); + else { + snprintf(name, sizeof(name), "%s%d", G_GATE_PROVIDER_NAME, + sc->sc_unit); + } + /* Check for name collision. */ + for (unit = 0; unit < g_gate_maxunits; unit++) { + if (g_gate_units[unit] == NULL) + continue; + if (strcmp(name, g_gate_units[unit]->sc_provider->name) != 0) + continue; + mtx_unlock(&g_gate_units_lock); + mtx_destroy(&sc->sc_queue_mtx); + free(sc, M_GATE); + return (EEXIST); + } + g_gate_units[sc->sc_unit] = sc; + g_gate_nunits++; + mtx_unlock(&g_gate_units_lock); + + ggio->gctl_unit = sc->sc_unit; g_topology_lock(); - gp = g_new_geomf(&g_gate_class, "%s%d", G_GATE_PROVIDER_NAME, - sc->sc_unit); + gp = g_new_geomf(&g_gate_class, "%s", name); gp->start = g_gate_start; gp->access = g_gate_access; gp->dumpconf = g_gate_dumpconf; gp->softc = sc; - pp = g_new_providerf(gp, "%s%d", G_GATE_PROVIDER_NAME, sc->sc_unit); + pp = g_new_providerf(gp, "%s", name); pp->mediasize = ggio->gctl_mediasize; pp->sectorsize = ggio->gctl_sectorsize; sc->sc_provider = pp; @@ -446,11 +478,11 @@ g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct threa struct g_gate_ctl_destroy *ggio = (void *)addr; G_GATE_CHECK_VERSION(ggio); - sc = g_gate_hold(ggio->gctl_unit); + sc = g_gate_hold(ggio->gctl_unit, ggio->gctl_name); if (sc == NULL) return (ENXIO); g_topology_lock(); - mtx_lock(&g_gate_list_mtx); + mtx_lock(&g_gate_units_lock); error = g_gate_destroy(sc, ggio->gctl_force); g_topology_unlock(); if (error != 0) @@ -463,7 +495,7 @@ g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct threa struct bio *tbp, *lbp; G_GATE_CHECK_VERSION(ggio); - sc = g_gate_hold(ggio->gctl_unit); + sc = g_gate_hold(ggio->gctl_unit, ggio->gctl_name); if (sc == NULL) return (ENXIO); lbp = NULL; @@ -491,6 +523,8 @@ g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct threa break; } } + if (ggio->gctl_unit == G_GATE_NAME_GIVEN) + ggio->gctl_unit = sc->sc_unit; mtx_unlock(&sc->sc_queue_mtx); g_gate_release(sc); return (error); @@ -500,7 +534,7 @@ g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct threa struct g_gate_ctl_io *ggio = (void *)addr; G_GATE_CHECK_VERSION(ggio); - sc = g_gate_hold(ggio->gctl_unit); + sc = g_gate_hold(ggio->gctl_unit, NULL); if (sc == NULL) return (ENXIO); error = 0; @@ -561,7 +595,7 @@ start_end: struct g_gate_ctl_io *ggio = (void *)addr; G_GATE_CHECK_VERSION(ggio); - sc = g_gate_hold(ggio->gctl_unit); + sc = g_gate_hold(ggio->gctl_unit, NULL); if (sc == NULL) return (ENOENT); error = 0; @@ -631,20 +665,24 @@ g_gate_modevent(module_t mod, int type, void *data) switch (type) { case MOD_LOAD: - mtx_init(&g_gate_list_mtx, "gg_list_lock", NULL, MTX_DEF); + mtx_init(&g_gate_units_lock, "gg_units_lock", NULL, MTX_DEF); + g_gate_units = malloc(g_gate_maxunits * sizeof(g_gate_units[0]), + M_GATE, M_WAITOK | M_ZERO); + g_gate_nunits = 0; g_gate_device(); break; case MOD_UNLOAD: - mtx_lock(&g_gate_list_mtx); - if (!LIST_EMPTY(&g_gate_list)) { - mtx_unlock(&g_gate_list_mtx); + mtx_lock(&g_gate_units_lock); + if (g_gate_nunits > 0) { + mtx_unlock(&g_gate_units_lock); error = EBUSY; break; } - mtx_unlock(&g_gate_list_mtx); - mtx_destroy(&g_gate_list_mtx); + mtx_unlock(&g_gate_units_lock); + mtx_destroy(&g_gate_units_lock); if (status_dev != 0) destroy_dev(status_dev); + free(g_gate_units, M_GATE); break; default: return (EOPNOTSUPP); diff --git a/sys/geom/gate/g_gate.h b/sys/geom/gate/g_gate.h index cd2564d937b..4f413488e01 100644 --- a/sys/geom/gate/g_gate.h +++ b/sys/geom/gate/g_gate.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004-2006 Pawel Jakub Dawidek + * Copyright (c) 2004-2009 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,7 @@ #define G_GATE_MOD_NAME "ggate" #define G_GATE_CTL_NAME "ggctl" -#define G_GATE_VERSION 1 +#define G_GATE_VERSION 2 /* * Maximum number of request that can be stored in @@ -54,6 +54,15 @@ #define G_GATE_FLAG_DESTROY 0x1000 #define G_GATE_USERFLAGS (G_GATE_FLAG_READONLY | G_GATE_FLAG_WRITEONLY) +/* + * Pick unit number automatically in /dev/ggate. + */ +#define G_GATE_UNIT_AUTO (-1) +/* + * Full provider name is given, so don't use ggate. + */ +#define G_GATE_NAME_GIVEN (-2) + #define G_GATE_CMD_CREATE _IOWR('m', 0, struct g_gate_ctl_create) #define G_GATE_CMD_DESTROY _IOWR('m', 1, struct g_gate_ctl_destroy) #define G_GATE_CMD_CANCEL _IOWR('m', 2, struct g_gate_ctl_cancel) @@ -120,20 +129,23 @@ struct g_gate_ctl_create { u_int gctl_flags; u_int gctl_maxcount; u_int gctl_timeout; + char gctl_name[NAME_MAX]; char gctl_info[G_GATE_INFOSIZE]; - int gctl_unit; /* out */ + int gctl_unit; /* in/out */ }; struct g_gate_ctl_destroy { u_int gctl_version; int gctl_unit; int gctl_force; + char gctl_name[NAME_MAX]; }; struct g_gate_ctl_cancel { u_int gctl_version; int gctl_unit; uintptr_t gctl_seq; + char gctl_name[NAME_MAX]; }; struct g_gate_ctl_io { From c44c50cd5c8b713f7d4b2e47a510b5cb3cc29cfc Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 21:18:32 +0000 Subject: [PATCH 2029/2592] MFC r204177,r205738,r206669,r206696,r206697: r204177: Changing proto_socketpair.c compilation and linking order revealed a problem - we should simply ignore proto_server() if address doesn't start with socketpair://, and not abort. r205738: Don't hold connection lock when doing reconnects as it makes I/Os wait for connection timeouts. Reported by: Kevin Day r206669: Increase ggate queue size to maximum value. HAST was not able to stand heavy random load. Reported by: Hiroyuki Yamagami r206696: Fix control socket leak when worker process exits. Submitted by: Mikolaj Golub r206697: Fix log size calculation which caused message truncation. Submitted by: Mikolaj Golub --- sbin/hastd/hastd.c | 1 + sbin/hastd/pjdlog.c | 2 +- sbin/hastd/primary.c | 78 +++++++++++++++++++++++------------ sbin/hastd/proto_socketpair.c | 5 ++- 4 files changed, 57 insertions(+), 29 deletions(-) diff --git a/sbin/hastd/hastd.c b/sbin/hastd/hastd.c index 19f08936c2d..957885d7ac1 100644 --- a/sbin/hastd/hastd.c +++ b/sbin/hastd/hastd.c @@ -137,6 +137,7 @@ child_exit(void) pjdlog_error("Worker process failed (pid=%u, status=%d).", (unsigned int)pid, WEXITSTATUS(status)); } + proto_close(res->hr_ctrl); res->hr_workerpid = 0; if (res->hr_role == HAST_ROLE_PRIMARY) { sleep(1); diff --git a/sbin/hastd/pjdlog.c b/sbin/hastd/pjdlog.c index 38c5539ad0c..9f8b3f499de 100644 --- a/sbin/hastd/pjdlog.c +++ b/sbin/hastd/pjdlog.c @@ -228,7 +228,7 @@ pjdlogv_common(int loglevel, int debuglevel, int error, const char *fmt, len = snprintf(log, sizeof(log), "%s", pjdlog_prefix); if ((size_t)len < sizeof(log)) - len = vsnprintf(log + len, sizeof(log) - len, fmt, ap); + len += vsnprintf(log + len, sizeof(log) - len, fmt, ap); if (error != -1 && (size_t)len < sizeof(log)) { (void)snprintf(log + len, sizeof(log) - len, ": %s.", strerror(error)); diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c index ed6e91ca8b8..09151546772 100644 --- a/sbin/hastd/primary.c +++ b/sbin/hastd/primary.c @@ -460,9 +460,11 @@ init_local(struct hast_resource *res) exit(EX_NOINPUT); } -static void -init_remote(struct hast_resource *res) +static bool +init_remote(struct hast_resource *res, struct proto_conn **inp, + struct proto_conn **outp) { + struct proto_conn *in, *out; struct nv *nvout, *nvin; const unsigned char *token; unsigned char *map; @@ -472,13 +474,17 @@ init_remote(struct hast_resource *res) uint32_t mapsize; size_t size; + assert((inp == NULL && outp == NULL) || (inp != NULL && outp != NULL)); + + in = out = NULL; + /* Prepare outgoing connection with remote node. */ - if (proto_client(res->hr_remoteaddr, &res->hr_remoteout) < 0) { + if (proto_client(res->hr_remoteaddr, &out) < 0) { primary_exit(EX_OSERR, "Unable to create connection to %s", res->hr_remoteaddr); } /* Try to connect, but accept failure. */ - if (proto_connect(res->hr_remoteout) < 0) { + if (proto_connect(out) < 0) { pjdlog_errno(LOG_WARNING, "Unable to connect to %s", res->hr_remoteaddr); goto close; @@ -496,7 +502,7 @@ init_remote(struct hast_resource *res) nv_free(nvout); goto close; } - if (hast_proto_send(res, res->hr_remoteout, nvout, NULL, 0) < 0) { + if (hast_proto_send(res, out, nvout, NULL, 0) < 0) { pjdlog_errno(LOG_WARNING, "Unable to send handshake header to %s", res->hr_remoteaddr); @@ -504,7 +510,7 @@ init_remote(struct hast_resource *res) goto close; } nv_free(nvout); - if (hast_proto_recv_hdr(res->hr_remoteout, &nvin) < 0) { + if (hast_proto_recv_hdr(out, &nvin) < 0) { pjdlog_errno(LOG_WARNING, "Unable to receive handshake header from %s", res->hr_remoteaddr); @@ -536,12 +542,12 @@ init_remote(struct hast_resource *res) * Second handshake step. * Setup incoming connection with remote node. */ - if (proto_client(res->hr_remoteaddr, &res->hr_remotein) < 0) { + if (proto_client(res->hr_remoteaddr, &in) < 0) { pjdlog_errno(LOG_WARNING, "Unable to create connection to %s", res->hr_remoteaddr); } /* Try to connect, but accept failure. */ - if (proto_connect(res->hr_remotein) < 0) { + if (proto_connect(in) < 0) { pjdlog_errno(LOG_WARNING, "Unable to connect to %s", res->hr_remoteaddr); goto close; @@ -560,7 +566,7 @@ init_remote(struct hast_resource *res) nv_free(nvout); goto close; } - if (hast_proto_send(res, res->hr_remotein, nvout, NULL, 0) < 0) { + if (hast_proto_send(res, in, nvout, NULL, 0) < 0) { pjdlog_errno(LOG_WARNING, "Unable to send handshake header to %s", res->hr_remoteaddr); @@ -568,7 +574,7 @@ init_remote(struct hast_resource *res) goto close; } nv_free(nvout); - if (hast_proto_recv_hdr(res->hr_remoteout, &nvin) < 0) { + if (hast_proto_recv_hdr(out, &nvin) < 0) { pjdlog_errno(LOG_WARNING, "Unable to receive handshake header from %s", res->hr_remoteaddr); @@ -611,7 +617,7 @@ init_remote(struct hast_resource *res) * Remote node have some dirty extents on its own, lets * download its activemap. */ - if (hast_proto_recv_data(res, res->hr_remoteout, nvin, map, + if (hast_proto_recv_data(res, out, nvin, map, mapsize) < 0) { pjdlog_errno(LOG_ERR, "Unable to receive remote activemap"); @@ -631,18 +637,29 @@ init_remote(struct hast_resource *res) (void)hast_activemap_flush(res); } pjdlog_info("Connected to %s.", res->hr_remoteaddr); + if (inp != NULL && outp != NULL) { + *inp = in; + *outp = out; + } else { + res->hr_remotein = in; + res->hr_remoteout = out; + } + return (true); +close: + proto_close(out); + if (in != NULL) + proto_close(in); + return (false); +} + +static void +sync_start(void) +{ + mtx_lock(&sync_lock); sync_inprogress = true; mtx_unlock(&sync_lock); cv_signal(&sync_cond); - return; -close: - proto_close(res->hr_remoteout); - res->hr_remoteout = NULL; - if (res->hr_remotein != NULL) { - proto_close(res->hr_remotein); - res->hr_remotein = NULL; - } } static void @@ -665,7 +682,7 @@ init_ggate(struct hast_resource *res) ggiocreate.gctl_mediasize = res->hr_datasize; ggiocreate.gctl_sectorsize = res->hr_local_sectorsize; ggiocreate.gctl_flags = 0; - ggiocreate.gctl_maxcount = 128; + ggiocreate.gctl_maxcount = G_GATE_MAX_QUEUE_SIZE; ggiocreate.gctl_timeout = 0; ggiocreate.gctl_unit = G_GATE_NAME_GIVEN; snprintf(ggiocreate.gctl_name, sizeof(ggiocreate.gctl_name), "hast/%s", @@ -735,7 +752,8 @@ hastd_primary(struct hast_resource *res) setproctitle("%s (primary)", res->hr_name); init_local(res); - init_remote(res); + if (init_remote(res, NULL, NULL)) + sync_start(); init_ggate(res); init_environment(res); error = pthread_create(&td, NULL, ggate_recv_thread, res); @@ -1695,6 +1713,7 @@ static void * guard_thread(void *arg) { struct hast_resource *res = arg; + struct proto_conn *in, *out; unsigned int ii, ncomps; int timeout; @@ -1738,26 +1757,31 @@ guard_thread(void *arg) * connected. */ rw_unlock(&hio_remote_lock[ii]); - rw_wlock(&hio_remote_lock[ii]); - assert(res->hr_remotein == NULL); - assert(res->hr_remoteout == NULL); pjdlog_debug(2, "remote_guard: Reconnecting to %s.", res->hr_remoteaddr); - init_remote(res); - if (ISCONNECTED(res, ii)) { + in = out = NULL; + if (init_remote(res, &in, &out)) { + rw_wlock(&hio_remote_lock[ii]); + assert(res->hr_remotein == NULL); + assert(res->hr_remoteout == NULL); + assert(in != NULL && out != NULL); + res->hr_remotein = in; + res->hr_remoteout = out; + rw_unlock(&hio_remote_lock[ii]); pjdlog_info("Successfully reconnected to %s.", res->hr_remoteaddr); + sync_start(); } else { /* Both connections should be NULL. */ assert(res->hr_remotein == NULL); assert(res->hr_remoteout == NULL); + assert(in == NULL && out == NULL); pjdlog_debug(2, "remote_guard: Reconnect to %s failed.", res->hr_remoteaddr); timeout = RECONNECT_SLEEP; } - rw_unlock(&hio_remote_lock[ii]); } } (void)cv_timedwait(&hio_guard_cond, &hio_guard_lock, timeout); diff --git a/sbin/hastd/proto_socketpair.c b/sbin/hastd/proto_socketpair.c index 0e2cfa250ef..08d0c667a06 100644 --- a/sbin/hastd/proto_socketpair.c +++ b/sbin/hastd/proto_socketpair.c @@ -91,9 +91,12 @@ sp_connect(void *ctx __unused) } static int -sp_server(const char *addr __unused, void **ctxp __unused) +sp_server(const char *addr, void **ctxp __unused) { + if (strcmp(addr, "socketpair://") != 0) + return (-1); + assert(!"proto_server() not supported on socketpairs"); abort(); } From e47ff61723e65b96d115d9051bc471274a0408e4 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 21:24:23 +0000 Subject: [PATCH 2030/2592] MFC r206666: Flush disk write cache after storing and clearing metadata. --- sbin/geom/misc/subr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sbin/geom/misc/subr.c b/sbin/geom/misc/subr.c index 64df7c6845e..21deac8bf52 100644 --- a/sbin/geom/misc/subr.c +++ b/sbin/geom/misc/subr.c @@ -236,6 +236,7 @@ g_metadata_store(const char *name, u_char *md, size_t size) error = errno; goto out; } + (void)ioctl(fd, DIOCGFLUSH, NULL); out: if (sector != NULL) free(sector); @@ -293,6 +294,7 @@ g_metadata_clear(const char *name, const char *magic) error = errno; goto out; } + (void)ioctl(fd, DIOCGFLUSH, NULL); out: if (sector != NULL) free(sector); From 48ed64d02743ab188f7946d6f6627aa19b643a67 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 21:26:59 +0000 Subject: [PATCH 2031/2592] MFC r206665: Use lower priority for GELI worker threads. This improves system responsiveness under heavy GELI load. --- sys/geom/eli/g_eli.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 2a405c5b502..a3746c09e1a 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -340,7 +340,7 @@ g_eli_worker(void *arg) } #endif thread_lock(curthread); - sched_prio(curthread, PRIBIO); + sched_prio(curthread, PUSER); if (sc->sc_crypto == G_ELI_CRYPTO_SW && g_eli_threads == 0) sched_bind(curthread, wr->w_number); thread_unlock(curthread); @@ -361,8 +361,7 @@ g_eli_worker(void *arg) mtx_unlock(&sc->sc_queue_mtx); kproc_exit(0); } - msleep(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, - "geli:w", 0); + msleep(sc, &sc->sc_queue_mtx, PDROP, "geli:w", 0); continue; } mtx_unlock(&sc->sc_queue_mtx); From 3a482ccc5e0f656ad7bfec793e8c2c2881cb59a6 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 21:36:34 +0000 Subject: [PATCH 2032/2592] MFC r203504,r204067,r204073,r204101,r204804,r205079,r205080,r205132,r205133, r205134,r205231,r205253,r205264,r205346,r206051,r206667,r206792,r206793, r206794,r206795,r206796,r206797: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit r203504: Open provider for writting when we find the right one. Opening too much providers for writing provokes huge traffic related to taste events send by GEOM on close. This can lead to various problems with opening GEOM providers that are created on top of other GEOM providers. Reorted by: Kurt Touet , mr Tested by: mr, Baginski Darren r204067: Update comment. We also look for GPT partitions. r204073: Add tunable and sysctl to skip hostid check on pool import. r204101: Don't set f_bsize to recordsize. It might confuse some software (like squid). Submitted by: Alexander Zagrebin r204804: Remove racy assertion. Reported by: Attila Nagy Obtained from: OpenSolaris, Bug ID 6827260 r205079: Remove bogus assertion. Reported by: Johan Ström Obtained from: OpenSolaris, Bug ID 6920880 r205080: Force commit to correct Bug ID: Obtained from: OpenSolaris, Bug ID 6920880 r205132: Don't bottleneck on acquiring the stream locks - this avoids a massive drop off in throughput with large numbers of simultaneous reads r205133: fix compilation under ZIO_USE_UMA r205134: make UMA the default allocator for ZFS buffers - this avoids a great deal of contention in kmem_alloc r205231: - reduce contention by breaking up ARC state locks in to 16 for data and 16 for metadata - export L2ARC tunables as sysctls - add several kstats to track L2ARC state more precisely - avoid holding a contended lock when atomically incrementing a contended counter (no lock protection needed for atomics) r205253: use CACHE_LINE_SIZE instead of hardcoding 128 for lock pad pointed out by Marius Nuennerich and jhb@ r205264: - cache line align arcs_lock array (h/t Marius Nuennerich) - fix ARCS_LOCK_PAD to use architecture defined CACHE_LINE_SIZE - cache line align buf_hash_table ht_locks array r205346: The same code is used to import and to create pool. The order of operations is the following: 1. Try to open vdev by remembered path and guid. 2. If 1 failed, try to find vdev which guid matches and ignore the path. 3. If 2 failed this means either that the vdev we're looking for is gone or that pool is being created and vdev doesn't contain proper guid yet. To be able to handle pool creation we open vdev by path anyway. Because of 3 it is possible that we open wrong vdev on import which can lead to confusions. The solution for this is to check spa_load_state. On pool creation it will be equal to SPA_LOAD_NONE and we can open vdev only by path immediately and if it is not equal to SPA_LOAD_NONE we first open by path+guid and when that fails, we open by guid. We no longer open wrong vdev on import. r206051: IOCPARM_MAX defines maximum size of a structure that can be passed directly to ioctl(2). Because of how ioctl command is build using _IO*() macros we have only 13 bits to encode structure size. So the structure can be up to 8kB-1. Currently we define IOCPARM_MAX as PAGE_SIZE. This is IMHO wrong for three main reasons: 1. It is confusing on archs with page size larger than 8kB (not really sure if we support such archs (sparc64?)), as even if PAGE_SIZE is bigger than 8kB, we won't be able to encode anything larger in ioctl command. 2. It is a waste. Why the structure can be only 4kB on most archs if we have 13 bits dedicated for that, not 12? 3. It shouldn't depend on architecture and page size. My ioctl command can work on one arch, but can't on the other? Increase IOCPARM_MAX to 8kB and make it independed of PAGE_SIZE and architecture it is compiled for. This allows to use all the bits on all the archs for size. Note that this doesn't mean we will copy more on every ioctl(2) call. No. We still copyin(9)/copyout(9) only exact number of bytes encoded in ioctl command. Practical use for this change is ZFS. zfs_cmd_t structure used for ZFS ioctls is larger than 4kB. Silence on: arch@ r206667: Fix 3-way deadlock that can happen because of ZFS and vnode lock order reversal. thread0 (vfs_fhtovp) thread1 (vop_getattr) thread2 (zfs_recv) -------------------- --------------------- ------------------ vn_lock rrw_enter_read rrw_enter_write (hangs) rrw_enter_read (hangs) vn_lock (hangs) Reported by: Attila Nagy r206792: Set ARC_L2_WRITING on L2ARC header creation. Obtained from: OpenSolaris r206793: Remove racy assertion. Obtained from: OpenSolaris r206794: Extend locks scope to match OpenSolaris. r206795: Add missing list and lock destruction. r206796: Style fixes. r206797: Restore previous order. --- sys/boot/zfs/zfs.c | 2 +- .../opensolaris/uts/common/fs/zfs/arc.c | 499 +++++++++++++----- .../opensolaris/uts/common/fs/zfs/dbuf.c | 3 - .../uts/common/fs/zfs/dmu_zfetch.c | 28 +- .../opensolaris/uts/common/fs/zfs/spa.c | 10 +- .../opensolaris/uts/common/fs/zfs/vdev_geom.c | 74 ++- .../uts/common/fs/zfs/zfs_vfsops.c | 22 +- .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 6 +- .../opensolaris/uts/common/fs/zfs/zio.c | 10 +- sys/modules/zfs/Makefile | 4 +- sys/sys/ioccom.h | 5 +- 11 files changed, 466 insertions(+), 197 deletions(-) diff --git a/sys/boot/zfs/zfs.c b/sys/boot/zfs/zfs.c index 52df7738ff3..99bb60a0696 100644 --- a/sys/boot/zfs/zfs.c +++ b/sys/boot/zfs/zfs.c @@ -397,7 +397,7 @@ zfs_dev_init(void) /* * Open all the disks we can find and see if we can reconstruct * ZFS pools from them. Bogusly assumes that the disks are named - * diskN or diskNsM. + * diskN, diskNpM or diskNsM. */ zfs_init(); for (unit = 0; unit < 32 /* XXX */; unit++) { 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 83a4c97f8af..ceb4c87f2f6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -186,6 +186,11 @@ SYSCTL_QUAD(_vfs_zfs, OID_AUTO, arc_min, CTLFLAG_RDTUN, &zfs_arc_min, 0, SYSCTL_INT(_vfs_zfs, OID_AUTO, mdcomp_disable, CTLFLAG_RDTUN, &zfs_mdcomp_disable, 0, "Disable metadata compression"); +#ifdef ZIO_USE_UMA +extern kmem_cache_t *zio_buf_cache[]; +extern kmem_cache_t *zio_data_buf_cache[]; +#endif + /* * Note that buffers can be in one of 6 states: * ARC_anon - anonymous (discussed below) @@ -218,13 +223,31 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, mdcomp_disable, CTLFLAG_RDTUN, * second level ARC benefit from these fast lookups. */ +#define ARCS_LOCK_PAD CACHE_LINE_SIZE +struct arcs_lock { + kmutex_t arcs_lock; +#ifdef _KERNEL + unsigned char pad[(ARCS_LOCK_PAD - sizeof (kmutex_t))]; +#endif +}; + +/* + * must be power of two for mask use to work + * + */ +#define ARC_BUFC_NUMDATALISTS 16 +#define ARC_BUFC_NUMMETADATALISTS 16 +#define ARC_BUFC_NUMLISTS (ARC_BUFC_NUMMETADATALISTS + ARC_BUFC_NUMDATALISTS) + typedef struct arc_state { - list_t arcs_list[ARC_BUFC_NUMTYPES]; /* list of evictable buffers */ uint64_t arcs_lsize[ARC_BUFC_NUMTYPES]; /* amount of evictable data */ uint64_t arcs_size; /* total amount of data in this state */ - kmutex_t arcs_mtx; + list_t arcs_lists[ARC_BUFC_NUMLISTS]; /* list of evictable buffers */ + struct arcs_lock arcs_locks[ARC_BUFC_NUMLISTS] __aligned(CACHE_LINE_SIZE); } arc_state_t; +#define ARCS_LOCK(s, i) (&((s)->arcs_locks[(i)].arcs_lock)) + /* The 6 states: */ static arc_state_t ARC_anon; static arc_state_t ARC_mru; @@ -248,7 +271,9 @@ typedef struct arc_stats { kstat_named_t arcstat_mru_ghost_hits; kstat_named_t arcstat_mfu_hits; kstat_named_t arcstat_mfu_ghost_hits; + kstat_named_t arcstat_allocated; kstat_named_t arcstat_deleted; + kstat_named_t arcstat_stolen; kstat_named_t arcstat_recycle_miss; kstat_named_t arcstat_mutex_miss; kstat_named_t arcstat_evict_skip; @@ -280,6 +305,19 @@ typedef struct arc_stats { kstat_named_t arcstat_l2_size; kstat_named_t arcstat_l2_hdr_size; kstat_named_t arcstat_memory_throttle_count; + kstat_named_t arcstat_l2_write_trylock_fail; + kstat_named_t arcstat_l2_write_passed_headroom; + kstat_named_t arcstat_l2_write_spa_mismatch; + kstat_named_t arcstat_l2_write_in_l2; + kstat_named_t arcstat_l2_write_hdr_io_in_progress; + kstat_named_t arcstat_l2_write_not_cacheable; + kstat_named_t arcstat_l2_write_full; + kstat_named_t arcstat_l2_write_buffer_iter; + kstat_named_t arcstat_l2_write_pios; + kstat_named_t arcstat_l2_write_bytes_written; + kstat_named_t arcstat_l2_write_buffer_bytes_scanned; + kstat_named_t arcstat_l2_write_buffer_list_iter; + kstat_named_t arcstat_l2_write_buffer_list_null_iter; } arc_stats_t; static arc_stats_t arc_stats = { @@ -297,7 +335,9 @@ static arc_stats_t arc_stats = { { "mru_ghost_hits", KSTAT_DATA_UINT64 }, { "mfu_hits", KSTAT_DATA_UINT64 }, { "mfu_ghost_hits", KSTAT_DATA_UINT64 }, + { "allocated", KSTAT_DATA_UINT64 }, { "deleted", KSTAT_DATA_UINT64 }, + { "stolen", KSTAT_DATA_UINT64 }, { "recycle_miss", KSTAT_DATA_UINT64 }, { "mutex_miss", KSTAT_DATA_UINT64 }, { "evict_skip", KSTAT_DATA_UINT64 }, @@ -328,7 +368,20 @@ static arc_stats_t arc_stats = { { "l2_io_error", KSTAT_DATA_UINT64 }, { "l2_size", KSTAT_DATA_UINT64 }, { "l2_hdr_size", KSTAT_DATA_UINT64 }, - { "memory_throttle_count", KSTAT_DATA_UINT64 } + { "memory_throttle_count", KSTAT_DATA_UINT64 }, + { "l2_write_trylock_fail", KSTAT_DATA_UINT64 }, + { "l2_write_passed_headroom", KSTAT_DATA_UINT64 }, + { "l2_write_spa_mismatch", KSTAT_DATA_UINT64 }, + { "l2_write_in_l2", KSTAT_DATA_UINT64 }, + { "l2_write_io_in_progress", KSTAT_DATA_UINT64 }, + { "l2_write_not_cacheable", KSTAT_DATA_UINT64 }, + { "l2_write_full", KSTAT_DATA_UINT64 }, + { "l2_write_buffer_iter", KSTAT_DATA_UINT64 }, + { "l2_write_pios", KSTAT_DATA_UINT64 }, + { "l2_write_bytes_written", KSTAT_DATA_UINT64 }, + { "l2_write_buffer_bytes_scanned", KSTAT_DATA_UINT64 }, + { "l2_write_buffer_list_iter", KSTAT_DATA_UINT64 }, + { "l2_write_buffer_list_null_iter", KSTAT_DATA_UINT64 } }; #define ARCSTAT(stat) (arc_stats.stat.value.ui64) @@ -336,7 +389,7 @@ static arc_stats_t arc_stats = { #define ARCSTAT_INCR(stat, val) \ atomic_add_64(&arc_stats.stat.value.ui64, (val)); -#define ARCSTAT_BUMP(stat) ARCSTAT_INCR(stat, 1) +#define ARCSTAT_BUMP(stat) ARCSTAT_INCR(stat, 1) #define ARCSTAT_BUMPDOWN(stat) ARCSTAT_INCR(stat, -1) #define ARCSTAT_MAX(stat, val) { \ @@ -370,7 +423,7 @@ static arc_stats_t arc_stats = { } kstat_t *arc_ksp; -static arc_state_t *arc_anon; +static arc_state_t *arc_anon; static arc_state_t *arc_mru; static arc_state_t *arc_mru_ghost; static arc_state_t *arc_mfu; @@ -514,7 +567,7 @@ static void arc_evict_ghost(arc_state_t *state, spa_t *spa, int64_t bytes); * Hash table routines */ -#define HT_LOCK_PAD 128 +#define HT_LOCK_PAD CACHE_LINE_SIZE struct ht_lock { kmutex_t ht_lock; @@ -527,7 +580,7 @@ struct ht_lock { typedef struct buf_hash_table { uint64_t ht_mask; arc_buf_hdr_t **ht_table; - struct ht_lock ht_locks[BUF_LOCKS]; + struct ht_lock ht_locks[BUF_LOCKS] __aligned(CACHE_LINE_SIZE); } buf_hash_table_t; static buf_hash_table_t buf_hash_table; @@ -541,13 +594,19 @@ static buf_hash_table_t buf_hash_table; uint64_t zfs_crc64_table[256]; +#ifdef ZIO_USE_UMA +extern kmem_cache_t *zio_buf_cache[]; +extern kmem_cache_t *zio_data_buf_cache[]; +#endif + /* * Level 2 ARC */ -#define L2ARC_WRITE_SIZE (8 * 1024 * 1024) /* initial write max */ -#define L2ARC_HEADROOM 4 /* num of writes */ +#define L2ARC_WRITE_SIZE (64 * 1024 * 1024) /* initial write max */ +#define L2ARC_HEADROOM 128 /* num of writes */ #define L2ARC_FEED_SECS 1 /* caching interval */ +#define L2ARC_FEED_SECS_SHIFT 1 /* caching interval shift */ #define l2arc_writes_sent ARCSTAT(arcstat_l2_writes_sent) #define l2arc_writes_done ARCSTAT(arcstat_l2_writes_done) @@ -559,7 +618,66 @@ uint64_t l2arc_write_max = L2ARC_WRITE_SIZE; /* default max write size */ uint64_t l2arc_write_boost = L2ARC_WRITE_SIZE; /* extra write during warmup */ uint64_t l2arc_headroom = L2ARC_HEADROOM; /* number of dev writes */ uint64_t l2arc_feed_secs = L2ARC_FEED_SECS; /* interval seconds */ -boolean_t l2arc_noprefetch = B_TRUE; /* don't cache prefetch bufs */ +uint64_t l2arc_feed_secs_shift = L2ARC_FEED_SECS_SHIFT; /* interval seconds shift */ +boolean_t l2arc_noprefetch = B_FALSE; /* don't cache prefetch bufs */ + + +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_write_max, CTLFLAG_RW, + &l2arc_write_max, 0, "max write size"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_write_boost, CTLFLAG_RW, + &l2arc_write_boost, 0, "extra write during warmup"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_headroom, CTLFLAG_RW, + &l2arc_headroom, 0, "number of dev writes"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_feed_secs, CTLFLAG_RW, + &l2arc_feed_secs, 0, "interval seconds"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_feed_secs_shift, CTLFLAG_RW, + &l2arc_feed_secs_shift, 0, "power of 2 division of feed seconds"); + +SYSCTL_INT(_vfs_zfs, OID_AUTO, l2arc_noprefetch, CTLFLAG_RW, + &l2arc_noprefetch, 0, "don't cache prefetch bufs"); + + +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, anon_size, CTLFLAG_RD, + &ARC_anon.arcs_size, 0, "size of anonymous state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, anon_metadata_lsize, CTLFLAG_RD, + &ARC_anon.arcs_lsize[ARC_BUFC_METADATA], 0, "size of anonymous state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, anon_data_lsize, CTLFLAG_RD, + &ARC_anon.arcs_lsize[ARC_BUFC_DATA], 0, "size of anonymous state"); + +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_size, CTLFLAG_RD, + &ARC_mru.arcs_size, 0, "size of mru state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_metadata_lsize, CTLFLAG_RD, + &ARC_mru.arcs_lsize[ARC_BUFC_METADATA], 0, "size of metadata in mru state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_data_lsize, CTLFLAG_RD, + &ARC_mru.arcs_lsize[ARC_BUFC_DATA], 0, "size of data in mru state"); + +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_ghost_size, CTLFLAG_RD, + &ARC_mru_ghost.arcs_size, 0, "size of mru ghost state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_ghost_metadata_lsize, CTLFLAG_RD, + &ARC_mru_ghost.arcs_lsize[ARC_BUFC_METADATA], 0, + "size of metadata in mru ghost state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_ghost_data_lsize, CTLFLAG_RD, + &ARC_mru_ghost.arcs_lsize[ARC_BUFC_DATA], 0, + "size of data in mru ghost state"); + +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_size, CTLFLAG_RD, + &ARC_mfu.arcs_size, 0, "size of mfu state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_metadata_lsize, CTLFLAG_RD, + &ARC_mfu.arcs_lsize[ARC_BUFC_METADATA], 0, "size of metadata in mfu state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_data_lsize, CTLFLAG_RD, + &ARC_mfu.arcs_lsize[ARC_BUFC_DATA], 0, "size of data in mfu state"); + +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_ghost_size, CTLFLAG_RD, + &ARC_mfu_ghost.arcs_size, 0, "size of mfu ghost state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_ghost_metadata_lsize, CTLFLAG_RD, + &ARC_mfu_ghost.arcs_lsize[ARC_BUFC_METADATA], 0, + "size of metadata in mfu ghost state"); +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_ghost_data_lsize, CTLFLAG_RD, + &ARC_mfu_ghost.arcs_lsize[ARC_BUFC_DATA], 0, + "size of data in mfu ghost state"); + +SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2c_only_size, CTLFLAG_RD, + &ARC_l2c_only.arcs_size, 0, "size of mru state"); /* * L2ARC Internals @@ -952,19 +1070,39 @@ arc_buf_freeze(arc_buf_t *buf) arc_cksum_compute(buf, B_FALSE); } +static void +get_buf_info(arc_buf_hdr_t *ab, arc_state_t *state, list_t **list, kmutex_t **lock) +{ + uint64_t buf_hashid = buf_hash(ab->b_spa, &ab->b_dva, ab->b_birth); + + if (ab->b_type == ARC_BUFC_METADATA) + buf_hashid &= (ARC_BUFC_NUMMETADATALISTS - 1); + else { + buf_hashid &= (ARC_BUFC_NUMDATALISTS - 1); + buf_hashid += ARC_BUFC_NUMMETADATALISTS; + } + + *list = &state->arcs_lists[buf_hashid]; + *lock = ARCS_LOCK(state, buf_hashid); +} + + static void add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) { + ASSERT(MUTEX_HELD(hash_lock)); if ((refcount_add(&ab->b_refcnt, tag) == 1) && (ab->b_state != arc_anon)) { uint64_t delta = ab->b_size * ab->b_datacnt; - list_t *list = &ab->b_state->arcs_list[ab->b_type]; uint64_t *size = &ab->b_state->arcs_lsize[ab->b_type]; + list_t *list; + kmutex_t *lock; - ASSERT(!MUTEX_HELD(&ab->b_state->arcs_mtx)); - mutex_enter(&ab->b_state->arcs_mtx); + get_buf_info(ab, ab->b_state, &list, &lock); + ASSERT(!MUTEX_HELD(lock)); + mutex_enter(lock); ASSERT(list_link_active(&ab->b_arc_node)); list_remove(list, ab); if (GHOST_STATE(ab->b_state)) { @@ -975,7 +1113,7 @@ add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) ASSERT(delta > 0); ASSERT3U(*size, >=, delta); atomic_add_64(size, -delta); - mutex_exit(&ab->b_state->arcs_mtx); + mutex_exit(lock); /* remove the prefetch flag if we get a reference */ if (ab->b_flags & ARC_PREFETCH) ab->b_flags &= ~ARC_PREFETCH; @@ -994,14 +1132,17 @@ remove_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) if (((cnt = refcount_remove(&ab->b_refcnt, tag)) == 0) && (state != arc_anon)) { uint64_t *size = &state->arcs_lsize[ab->b_type]; + list_t *list; + kmutex_t *lock; - ASSERT(!MUTEX_HELD(&state->arcs_mtx)); - mutex_enter(&state->arcs_mtx); + get_buf_info(ab, state, &list, &lock); + ASSERT(!MUTEX_HELD(lock)); + mutex_enter(lock); ASSERT(!list_link_active(&ab->b_arc_node)); - list_insert_head(&state->arcs_list[ab->b_type], ab); + list_insert_head(list, ab); ASSERT(ab->b_datacnt > 0); atomic_add_64(size, ab->b_size * ab->b_datacnt); - mutex_exit(&state->arcs_mtx); + mutex_exit(lock); } return (cnt); } @@ -1016,6 +1157,8 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) arc_state_t *old_state = ab->b_state; int64_t refcnt = refcount_count(&ab->b_refcnt); uint64_t from_delta, to_delta; + list_t *list; + kmutex_t *lock; ASSERT(MUTEX_HELD(hash_lock)); ASSERT(new_state != old_state); @@ -1030,14 +1173,16 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) */ if (refcnt == 0) { if (old_state != arc_anon) { - int use_mutex = !MUTEX_HELD(&old_state->arcs_mtx); + int use_mutex; uint64_t *size = &old_state->arcs_lsize[ab->b_type]; + get_buf_info(ab, old_state, &list, &lock); + use_mutex = !MUTEX_HELD(lock); if (use_mutex) - mutex_enter(&old_state->arcs_mtx); + mutex_enter(lock); ASSERT(list_link_active(&ab->b_arc_node)); - list_remove(&old_state->arcs_list[ab->b_type], ab); + list_remove(list, ab); /* * If prefetching out of the ghost cache, @@ -1052,16 +1197,18 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) atomic_add_64(size, -from_delta); if (use_mutex) - mutex_exit(&old_state->arcs_mtx); + mutex_exit(lock); } if (new_state != arc_anon) { - int use_mutex = !MUTEX_HELD(&new_state->arcs_mtx); + int use_mutex; uint64_t *size = &new_state->arcs_lsize[ab->b_type]; + get_buf_info(ab, new_state, &list, &lock); + use_mutex = !MUTEX_HELD(lock); if (use_mutex) - mutex_enter(&new_state->arcs_mtx); + mutex_enter(lock); - list_insert_head(&new_state->arcs_list[ab->b_type], ab); + list_insert_head(list, ab); /* ghost elements have a ghost size */ if (GHOST_STATE(new_state)) { @@ -1072,7 +1219,7 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) atomic_add_64(size, to_delta); if (use_mutex) - mutex_exit(&new_state->arcs_mtx); + mutex_exit(lock); } } @@ -1462,21 +1609,48 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle, { arc_state_t *evicted_state; uint64_t bytes_evicted = 0, skipped = 0, missed = 0; + int64_t bytes_remaining; arc_buf_hdr_t *ab, *ab_prev = NULL; - list_t *list = &state->arcs_list[type]; + list_t *evicted_list, *list, *evicted_list_start, *list_start; + kmutex_t *lock, *evicted_lock; kmutex_t *hash_lock; boolean_t have_lock; void *stolen = NULL; + static int evict_metadata_offset, evict_data_offset; + int i, idx, offset, list_count, count; ASSERT(state == arc_mru || state == arc_mfu); evicted_state = (state == arc_mru) ? arc_mru_ghost : arc_mfu_ghost; - mutex_enter(&state->arcs_mtx); - mutex_enter(&evicted_state->arcs_mtx); + if (type == ARC_BUFC_METADATA) { + offset = 0; + list_count = ARC_BUFC_NUMMETADATALISTS; + list_start = &state->arcs_lists[0]; + evicted_list_start = &evicted_state->arcs_lists[0]; + idx = evict_metadata_offset; + } else { + offset = ARC_BUFC_NUMMETADATALISTS; + list_start = &state->arcs_lists[offset]; + evicted_list_start = &evicted_state->arcs_lists[offset]; + list_count = ARC_BUFC_NUMDATALISTS; + idx = evict_data_offset; + } + bytes_remaining = evicted_state->arcs_lsize[type]; + count = 0; + +evict_start: + list = &list_start[idx]; + evicted_list = &evicted_list_start[idx]; + lock = ARCS_LOCK(state, (offset + idx)); + evicted_lock = ARCS_LOCK(evicted_state, (offset + idx)); + + mutex_enter(lock); + mutex_enter(evicted_lock); for (ab = list_tail(list); ab; ab = ab_prev) { ab_prev = list_prev(list, ab); + bytes_remaining -= (ab->b_size * ab->b_datacnt); /* prefetch buffers have a minimum lifespan */ if (HDR_IO_IN_PROGRESS(ab) || (spa && ab->b_spa != spa) || @@ -1536,17 +1710,35 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle, mutex_exit(hash_lock); if (bytes >= 0 && bytes_evicted >= bytes) break; + if (bytes_remaining > 0) { + mutex_exit(evicted_lock); + mutex_exit(lock); + idx = ((idx + 1) & (list_count - 1)); + count++; + goto evict_start; + } } else { missed += 1; } } - mutex_exit(&evicted_state->arcs_mtx); - mutex_exit(&state->arcs_mtx); + mutex_exit(evicted_lock); + mutex_exit(lock); - if (bytes_evicted < bytes) - dprintf("only evicted %lld bytes from %x", - (longlong_t)bytes_evicted, state); + idx = ((idx + 1) & (list_count - 1)); + count++; + + if (bytes_evicted < bytes) { + if (count < list_count) + goto evict_start; + else + dprintf("only evicted %lld bytes from %x", + (longlong_t)bytes_evicted, state); + } + if (type == ARC_BUFC_METADATA) + evict_metadata_offset = idx; + else + evict_data_offset = idx; if (skipped) ARCSTAT_INCR(arcstat_evict_skip, skipped); @@ -1574,6 +1766,8 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle, arc_evict_ghost(arc_mfu_ghost, NULL, todelete); } } + if (stolen) + ARCSTAT_BUMP(arcstat_stolen); return (stolen); } @@ -1586,14 +1780,28 @@ static void arc_evict_ghost(arc_state_t *state, spa_t *spa, int64_t bytes) { arc_buf_hdr_t *ab, *ab_prev; - list_t *list = &state->arcs_list[ARC_BUFC_DATA]; - kmutex_t *hash_lock; + list_t *list, *list_start; + kmutex_t *hash_lock, *lock; uint64_t bytes_deleted = 0; uint64_t bufs_skipped = 0; + static int evict_offset; + int list_count, idx = evict_offset; + int offset, count = 0; ASSERT(GHOST_STATE(state)); -top: - mutex_enter(&state->arcs_mtx); + + /* + * data lists come after metadata lists + */ + list_start = &state->arcs_lists[ARC_BUFC_NUMMETADATALISTS]; + list_count = ARC_BUFC_NUMDATALISTS; + offset = ARC_BUFC_NUMMETADATALISTS; + +evict_start: + list = &list_start[idx]; + lock = ARCS_LOCK(state, idx + offset); + + mutex_enter(lock); for (ab = list_tail(list); ab; ab = ab_prev) { ab_prev = list_prev(list, ab); if (spa && ab->b_spa != spa) @@ -1623,20 +1831,31 @@ top: break; } else { if (bytes < 0) { - mutex_exit(&state->arcs_mtx); + /* + * we're draining the ARC, retry + */ + mutex_exit(lock); mutex_enter(hash_lock); mutex_exit(hash_lock); - goto top; + goto evict_start; } bufs_skipped += 1; } } - mutex_exit(&state->arcs_mtx); + mutex_exit(lock); + idx = ((idx + 1) & (ARC_BUFC_NUMDATALISTS - 1)); + count++; - if (list == &state->arcs_list[ARC_BUFC_DATA] && + if (count < list_count) + goto evict_start; + + evict_offset = idx; + if ((uintptr_t)list > (uintptr_t)&state->arcs_lists[ARC_BUFC_NUMMETADATALISTS] && (bytes < 0 || bytes_deleted < bytes)) { - list = &state->arcs_list[ARC_BUFC_METADATA]; - goto top; + list_start = &state->arcs_lists[0]; + list_count = ARC_BUFC_NUMMETADATALISTS; + offset = count = 0; + goto evict_start; } if (bufs_skipped) { @@ -1718,7 +1937,7 @@ arc_do_user_evicts(void) /* * Move list over to avoid LOR */ -restart: +restart: mutex_enter(&arc_eviction_mtx); tmp_arc_eviction_list = arc_eviction_list; arc_eviction_list = NULL; @@ -1750,22 +1969,22 @@ restart: void arc_flush(spa_t *spa) { - while (list_head(&arc_mru->arcs_list[ARC_BUFC_DATA])) { + while (arc_mru->arcs_lsize[ARC_BUFC_DATA]) { (void) arc_evict(arc_mru, spa, -1, FALSE, ARC_BUFC_DATA); if (spa) break; } - while (list_head(&arc_mru->arcs_list[ARC_BUFC_METADATA])) { + while (arc_mru->arcs_lsize[ARC_BUFC_METADATA]) { (void) arc_evict(arc_mru, spa, -1, FALSE, ARC_BUFC_METADATA); if (spa) break; } - while (list_head(&arc_mfu->arcs_list[ARC_BUFC_DATA])) { + while (arc_mfu->arcs_lsize[ARC_BUFC_DATA]) { (void) arc_evict(arc_mfu, spa, -1, FALSE, ARC_BUFC_DATA); if (spa) break; } - while (list_head(&arc_mfu->arcs_list[ARC_BUFC_METADATA])) { + while (arc_mfu->arcs_lsize[ARC_BUFC_METADATA]) { (void) arc_evict(arc_mfu, spa, -1, FALSE, ARC_BUFC_METADATA); if (spa) break; @@ -1829,7 +2048,7 @@ arc_reclaim_needed(void) return (0); /* - * If pages are needed or we're within 2048 pages + * If pages are needed or we're within 2048 pages * of needing to page need to reclaim */ if (vm_pages_needed || (vm_paging_target() > -2048)) @@ -1896,8 +2115,6 @@ arc_kmem_reap_now(arc_reclaim_strategy_t strat) size_t i; kmem_cache_t *prev_cache = NULL; kmem_cache_t *prev_data_cache = NULL; - extern kmem_cache_t *zio_buf_cache[]; - extern kmem_cache_t *zio_data_buf_cache[]; #endif #ifdef _KERNEL @@ -2203,6 +2420,7 @@ out: arc_anon->arcs_size + arc_mru->arcs_size > arc_p) arc_p = MIN(arc_c, arc_p + size); } + ARCSTAT_BUMP(arcstat_allocated); } /* @@ -2502,7 +2720,6 @@ arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_buf_t *pbuf, uint32_t *arc_flags, const zbookmark_t *zb) { int err; - arc_buf_hdr_t *hdr = pbuf->b_hdr; ASSERT(!refcount_is_zero(&pbuf->b_hdr->b_refcnt)); ASSERT3U((char *)bp - (char *)pbuf->b_data, <, pbuf->b_hdr->b_size); @@ -2510,8 +2727,6 @@ arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_buf_t *pbuf, err = arc_read_nolock(pio, spa, bp, done, private, priority, zio_flags, arc_flags, zb); - - ASSERT3P(hdr, ==, pbuf->b_hdr); rw_exit(&pbuf->b_lock); return (err); } @@ -2728,7 +2943,7 @@ top: * released by l2arc_read_done(). */ rzio = zio_read_phys(pio, vd, addr, size, - buf->b_data, ZIO_CHECKSUM_OFF, + buf->b_data, ZIO_CHECKSUM_OFF, l2arc_read_done, cb, priority, zio_flags | ZIO_FLAG_DONT_CACHE | ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | @@ -2823,6 +3038,8 @@ arc_buf_evict(arc_buf_t *buf) arc_buf_hdr_t *hdr; kmutex_t *hash_lock; arc_buf_t **bufp; + list_t *list, *evicted_list; + kmutex_t *lock, *evicted_lock; rw_enter(&buf->b_lock, RW_WRITER); hdr = buf->b_hdr; @@ -2871,16 +3088,18 @@ arc_buf_evict(arc_buf_t *buf) evicted_state = (old_state == arc_mru) ? arc_mru_ghost : arc_mfu_ghost; - mutex_enter(&old_state->arcs_mtx); - mutex_enter(&evicted_state->arcs_mtx); + get_buf_info(hdr, old_state, &list, &lock); + get_buf_info(hdr, evicted_state, &evicted_list, &evicted_lock); + mutex_enter(lock); + mutex_enter(evicted_lock); arc_change_state(evicted_state, hdr, hash_lock); ASSERT(HDR_IN_HASH_TABLE(hdr)); hdr->b_flags |= ARC_IN_HASH_TABLE; hdr->b_flags &= ~ARC_BUF_AVAILABLE; - mutex_exit(&evicted_state->arcs_mtx); - mutex_exit(&old_state->arcs_mtx); + mutex_exit(evicted_lock); + mutex_exit(lock); } mutex_exit(hash_lock); rw_exit(&buf->b_lock); @@ -3426,7 +3645,8 @@ void arc_init(void) { int prefetch_tunable_set = 0; - + int i; + mutex_init(&arc_reclaim_thr_lock, NULL, MUTEX_DEFAULT, NULL); cv_init(&arc_reclaim_thr_cv, NULL, CV_DEFAULT, NULL); mutex_init(&arc_lowmem_lock, NULL, MUTEX_DEFAULT, NULL); @@ -3494,33 +3714,33 @@ arc_init(void) arc_l2c_only = &ARC_l2c_only; arc_size = 0; - mutex_init(&arc_anon->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_mru->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_mru_ghost->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_mfu->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_mfu_ghost->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_l2c_only->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); + for (i = 0; i < ARC_BUFC_NUMLISTS; i++) { + mutex_init(&arc_anon->arcs_locks[i].arcs_lock, + NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_mru->arcs_locks[i].arcs_lock, + NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_mru_ghost->arcs_locks[i].arcs_lock, + NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_mfu->arcs_locks[i].arcs_lock, + NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_mfu_ghost->arcs_locks[i].arcs_lock, + NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_l2c_only->arcs_locks[i].arcs_lock, + NULL, MUTEX_DEFAULT, NULL); - list_create(&arc_mru->arcs_list[ARC_BUFC_METADATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mru->arcs_list[ARC_BUFC_DATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mfu->arcs_list[ARC_BUFC_METADATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mfu->arcs_list[ARC_BUFC_DATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_l2c_only->arcs_list[ARC_BUFC_METADATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_l2c_only->arcs_list[ARC_BUFC_DATA], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mru->arcs_lists[i], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mru_ghost->arcs_lists[i], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mfu->arcs_lists[i], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mfu_ghost->arcs_lists[i], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mfu_ghost->arcs_lists[i], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_l2c_only->arcs_lists[i], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + } buf_init(); @@ -3557,7 +3777,7 @@ arc_init(void) #ifdef _KERNEL if (TUNABLE_INT_FETCH("vfs.zfs.prefetch_disable", &zfs_prefetch_disable)) prefetch_tunable_set = 1; - + #ifdef __i386__ if (prefetch_tunable_set == 0) { printf("ZFS NOTICE: Prefetch is disabled by default on i386 " @@ -3566,7 +3786,7 @@ arc_init(void) "to /boot/loader.conf.\n"); zfs_prefetch_disable=1; } -#else +#else if ((((uint64_t)physmem * PAGESIZE) < (1ULL << 32)) && prefetch_tunable_set == 0) { printf("ZFS NOTICE: Prefetch is disabled by default if less " @@ -3575,7 +3795,7 @@ arc_init(void) "to /boot/loader.conf.\n"); zfs_prefetch_disable=1; } -#endif +#endif /* Warn about ZFS memory and address space requirements. */ if (((uint64_t)physmem * PAGESIZE) < (256 + 128 + 64) * (1 << 20)) { printf("ZFS WARNING: Recommended minimum RAM size is 512MB; " @@ -3594,6 +3814,7 @@ arc_init(void) void arc_fini(void) { + int i; mutex_enter(&arc_reclaim_thr_lock); arc_thread_exit = 1; @@ -3615,20 +3836,20 @@ arc_fini(void) mutex_destroy(&arc_reclaim_thr_lock); cv_destroy(&arc_reclaim_thr_cv); - list_destroy(&arc_mru->arcs_list[ARC_BUFC_METADATA]); - list_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA]); - list_destroy(&arc_mfu->arcs_list[ARC_BUFC_METADATA]); - list_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA]); - list_destroy(&arc_mru->arcs_list[ARC_BUFC_DATA]); - list_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA]); - list_destroy(&arc_mfu->arcs_list[ARC_BUFC_DATA]); - list_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA]); + for (i = 0; i < ARC_BUFC_NUMLISTS; i++) { + list_destroy(&arc_mru->arcs_lists[i]); + list_destroy(&arc_mru_ghost->arcs_lists[i]); + list_destroy(&arc_mfu->arcs_lists[i]); + list_destroy(&arc_mfu_ghost->arcs_lists[i]); + list_destroy(&arc_l2c_only->arcs_lists[i]); - mutex_destroy(&arc_anon->arcs_mtx); - mutex_destroy(&arc_mru->arcs_mtx); - mutex_destroy(&arc_mru_ghost->arcs_mtx); - mutex_destroy(&arc_mfu->arcs_mtx); - mutex_destroy(&arc_mfu_ghost->arcs_mtx); + mutex_destroy(&arc_anon->arcs_locks[i].arcs_lock); + mutex_destroy(&arc_mru->arcs_locks[i].arcs_lock); + mutex_destroy(&arc_mru_ghost->arcs_locks[i].arcs_lock); + mutex_destroy(&arc_mfu->arcs_locks[i].arcs_lock); + mutex_destroy(&arc_mfu_ghost->arcs_locks[i].arcs_lock); + mutex_destroy(&arc_l2c_only->arcs_locks[i].arcs_lock); + } mutex_destroy(&zfs_write_limit_lock); @@ -4024,26 +4245,27 @@ static list_t * l2arc_list_locked(int list_num, kmutex_t **lock) { list_t *list; + int idx; - ASSERT(list_num >= 0 && list_num <= 3); + ASSERT(list_num >= 0 && list_num < 2 * ARC_BUFC_NUMLISTS); - switch (list_num) { - case 0: - list = &arc_mfu->arcs_list[ARC_BUFC_METADATA]; - *lock = &arc_mfu->arcs_mtx; - break; - case 1: - list = &arc_mru->arcs_list[ARC_BUFC_METADATA]; - *lock = &arc_mru->arcs_mtx; - break; - case 2: - list = &arc_mfu->arcs_list[ARC_BUFC_DATA]; - *lock = &arc_mfu->arcs_mtx; - break; - case 3: - list = &arc_mru->arcs_list[ARC_BUFC_DATA]; - *lock = &arc_mru->arcs_mtx; - break; + if (list_num < ARC_BUFC_NUMMETADATALISTS) { + idx = list_num; + list = &arc_mfu->arcs_lists[idx]; + *lock = ARCS_LOCK(arc_mfu, idx); + } else if (list_num < ARC_BUFC_NUMMETADATALISTS * 2) { + idx = list_num - ARC_BUFC_NUMMETADATALISTS; + list = &arc_mru->arcs_lists[idx]; + *lock = ARCS_LOCK(arc_mru, idx); + } else if (list_num < (ARC_BUFC_NUMMETADATALISTS * 2 + + ARC_BUFC_NUMDATALISTS)) { + idx = list_num - ARC_BUFC_NUMMETADATALISTS; + list = &arc_mfu->arcs_lists[idx]; + *lock = ARCS_LOCK(arc_mfu, idx); + } else { + idx = list_num - ARC_BUFC_NUMLISTS; + list = &arc_mru->arcs_lists[idx]; + *lock = ARCS_LOCK(arc_mru, idx); } ASSERT(!(MUTEX_HELD(*lock))); @@ -4210,13 +4432,15 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) head = kmem_cache_alloc(hdr_cache, KM_PUSHPAGE); head->b_flags |= ARC_L2_WRITE_HEAD; + ARCSTAT_BUMP(arcstat_l2_write_buffer_iter); /* * Copy buffers for L2ARC writing. */ mutex_enter(&l2arc_buflist_mtx); - for (try = 0; try <= 3; try++) { + for (try = 0; try < 2 * ARC_BUFC_NUMLISTS; try++) { list = l2arc_list_locked(try, &list_lock); passed_sz = 0; + ARCSTAT_BUMP(arcstat_l2_write_buffer_list_iter); /* * L2ARC fast warmup. @@ -4229,52 +4453,65 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) ab = list_head(list); else ab = list_tail(list); + if (ab == NULL) + ARCSTAT_BUMP(arcstat_l2_write_buffer_list_null_iter); for (; ab; ab = ab_prev) { if (arc_warm == B_FALSE) ab_prev = list_next(list, ab); else ab_prev = list_prev(list, ab); + ARCSTAT_INCR(arcstat_l2_write_buffer_bytes_scanned, ab->b_size); hash_lock = HDR_LOCK(ab); have_lock = MUTEX_HELD(hash_lock); if (!have_lock && !mutex_tryenter(hash_lock)) { + ARCSTAT_BUMP(arcstat_l2_write_trylock_fail); /* * Skip this buffer rather than waiting. */ continue; } + if (ab->b_l2hdr != NULL) { + /* + * Already in L2ARC. + */ + mutex_exit(hash_lock); + ARCSTAT_BUMP(arcstat_l2_write_in_l2); + continue; + } + passed_sz += ab->b_size; if (passed_sz > headroom) { /* * Searched too far. */ mutex_exit(hash_lock); + ARCSTAT_BUMP(arcstat_l2_write_passed_headroom); break; } if (ab->b_spa != spa) { mutex_exit(hash_lock); + ARCSTAT_BUMP(arcstat_l2_write_spa_mismatch); continue; } - if (ab->b_l2hdr != NULL) { - /* - * Already in L2ARC. - */ + if (HDR_IO_IN_PROGRESS(ab)) { mutex_exit(hash_lock); + ARCSTAT_BUMP(arcstat_l2_write_hdr_io_in_progress); continue; } - - if (HDR_IO_IN_PROGRESS(ab) || !HDR_L2CACHE(ab)) { + if (!HDR_L2CACHE(ab)) { mutex_exit(hash_lock); + ARCSTAT_BUMP(arcstat_l2_write_not_cacheable); continue; } - if ((write_sz + ab->b_size) > target_sz) { full = B_TRUE; mutex_exit(hash_lock); + ARCSTAT_BUMP(arcstat_l2_write_full); break; } @@ -4298,8 +4535,10 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) cb->l2wcb_head = head; pio = zio_root(spa, l2arc_write_done, cb, ZIO_FLAG_CANFAIL); + ARCSTAT_BUMP(arcstat_l2_write_pios); } + ARCSTAT_INCR(arcstat_l2_write_bytes_written, ab->b_size); /* * Create and add a new L2ARC header. */ @@ -4395,7 +4634,7 @@ l2arc_feed_thread(void *dummy __unused) */ CALLB_CPR_SAFE_BEGIN(&cpr); (void) cv_timedwait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock, - hz * l2arc_feed_secs); + hz * l2arc_feed_secs >> l2arc_feed_secs_shift); CALLB_CPR_SAFE_END(&cpr, &l2arc_feed_thr_lock); /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c index 2494c1e7f9d..3bf0939a521 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c @@ -2210,9 +2210,6 @@ dbuf_write_ready(zio_t *zio, arc_buf_t *buf, void *vdb) for (i = db->db.db_size >> SPA_BLKPTRSHIFT; i > 0; i--, ibp++) { if (BP_IS_HOLE(ibp)) continue; - ASSERT3U(BP_GET_LSIZE(ibp), ==, - db->db_level == 1 ? dn->dn_datablksz : - (1<dn_phys->dn_indblkshift)); fill += ibp->blk_fill; } } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c index cddc64d80aa..5cc56a9f5d8 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c @@ -49,11 +49,11 @@ uint32_t zfetch_block_cap = 256; uint64_t zfetch_array_rd_sz = 1024 * 1024; SYSCTL_DECL(_vfs_zfs); -SYSCTL_INT(_vfs_zfs, OID_AUTO, prefetch_disable, CTLFLAG_RDTUN, +SYSCTL_INT(_vfs_zfs, OID_AUTO, prefetch_disable, CTLFLAG_RW, &zfs_prefetch_disable, 0, "Disable prefetch"); SYSCTL_NODE(_vfs_zfs, OID_AUTO, zfetch, CTLFLAG_RW, 0, "ZFS ZFETCH"); TUNABLE_INT("vfs.zfs.zfetch.max_streams", &zfetch_max_streams); -SYSCTL_UINT(_vfs_zfs_zfetch, OID_AUTO, max_streams, CTLFLAG_RDTUN, +SYSCTL_UINT(_vfs_zfs_zfetch, OID_AUTO, max_streams, CTLFLAG_RW, &zfetch_max_streams, 0, "Max # of streams per zfetch"); TUNABLE_INT("vfs.zfs.zfetch.min_sec_reap", &zfetch_min_sec_reap); SYSCTL_UINT(_vfs_zfs_zfetch, OID_AUTO, min_sec_reap, CTLFLAG_RDTUN, @@ -338,8 +338,10 @@ top: reset = !prefetched && zs->zst_len > 1; - mutex_enter(&zs->zst_lock); - + if (mutex_tryenter(&zs->zst_lock) == 0) { + rc = 1; + goto out; + } if (zh->zst_offset != zs->zst_offset + zs->zst_len) { mutex_exit(&zs->zst_lock); goto top; @@ -363,8 +365,10 @@ top: reset = !prefetched && zs->zst_len > 1; - mutex_enter(&zs->zst_lock); - + if (mutex_tryenter(&zs->zst_lock) == 0) { + rc = 1; + goto out; + } if (zh->zst_offset != zs->zst_offset - zh->zst_len) { mutex_exit(&zs->zst_lock); goto top; @@ -391,8 +395,10 @@ top: zs->zst_len) && (zs->zst_len != zs->zst_stride)) { /* strided forward access */ - mutex_enter(&zs->zst_lock); - + if (mutex_tryenter(&zs->zst_lock) == 0) { + rc = 1; + goto out; + } if ((zh->zst_offset - zs->zst_offset - zs->zst_stride >= zs->zst_len) || (zs->zst_len == zs->zst_stride)) { mutex_exit(&zs->zst_lock); @@ -408,8 +414,10 @@ top: zs->zst_len) && (zs->zst_len != zs->zst_stride)) { /* strided reverse access */ - mutex_enter(&zs->zst_lock); - + if (mutex_tryenter(&zs->zst_lock) == 0) { + rc = 1; + goto out; + } if ((zh->zst_offset - zs->zst_offset + zs->zst_stride >= zs->zst_len) || (zs->zst_len == zs->zst_stride)) { mutex_exit(&zs->zst_lock); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c index 163b2157224..90861bab4c7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -62,6 +62,14 @@ #include "zfs_prop.h" #include "zfs_comutil.h" +/* Check hostid on import? */ +static int check_hostid = 1; + +SYSCTL_DECL(_vfs_zfs); +TUNABLE_INT("vfs.zfs.check_hostid", &check_hostid); +SYSCTL_INT(_vfs_zfs, OID_AUTO, check_hostid, CTLFLAG_RW, &check_hostid, 0, + "Check hostid on import?"); + int zio_taskq_threads[ZIO_TYPES][ZIO_TASKQ_TYPES] = { /* ISSUE INTR */ { 1, 1 }, /* ZIO_TYPE_NULL */ @@ -1168,7 +1176,7 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) ZPOOL_CONFIG_HOSTNAME, &hostname) == 0); (void) ddi_strtoul(hw_serial, NULL, 10, &myhostid); - if (hostid != 0 && myhostid != 0 && + if (check_hostid && hostid != 0 && myhostid != 0 && (unsigned long)hostid != myhostid) { cmn_err(CE_WARN, "pool '%s' could not be " "loaded as it was last accessed by " 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 4c41f90253e..819473e34aa 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 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -102,7 +103,7 @@ vdev_geom_orphan(struct g_consumer *cp) } static struct g_consumer * -vdev_geom_attach(struct g_provider *pp, int write) +vdev_geom_attach(struct g_provider *pp) { struct g_geom *gp; struct g_consumer *cp; @@ -126,7 +127,7 @@ vdev_geom_attach(struct g_provider *pp, int write) g_wither_geom(gp, ENXIO); return (NULL); } - if (g_access(cp, 1, write, 1) != 0) { + if (g_access(cp, 1, 0, 1) != 0) { g_wither_geom(gp, ENXIO); return (NULL); } @@ -145,14 +146,14 @@ vdev_geom_attach(struct g_provider *pp, int write) g_destroy_consumer(cp); return (NULL); } - if (g_access(cp, 1, write, 1) != 0) { + if (g_access(cp, 1, 0, 1) != 0) { g_detach(cp); g_destroy_consumer(cp); return (NULL); } ZFS_LOG(1, "Created consumer for %s.", pp->name); } else { - if (g_access(cp, 1, cp->acw > 0 ? 0 : write, 1) != 0) + if (g_access(cp, 1, 0, 1) != 0) return (NULL); ZFS_LOG(1, "Used existing consumer for %s.", pp->name); } @@ -342,7 +343,6 @@ vdev_geom_read_guid(struct g_consumer *cp) struct vdev_geom_find { uint64_t guid; - int write; struct g_consumer *cp; }; @@ -394,10 +394,10 @@ vdev_geom_attach_by_guid_event(void *arg, int flags __unused) g_detach(zcp); if (guid != ap->guid) continue; - ap->cp = vdev_geom_attach(pp, ap->write); + ap->cp = vdev_geom_attach(pp); if (ap->cp == NULL) { - printf("ZFS WARNING: Cannot open %s " - "for writting.\n", pp->name); + printf("ZFS WARNING: Unable to attach to %s.", + pp->name); continue; } goto end; @@ -411,14 +411,13 @@ end: } static struct g_consumer * -vdev_geom_attach_by_guid(uint64_t guid, int write) +vdev_geom_attach_by_guid(uint64_t guid) { struct vdev_geom_find *ap; struct g_consumer *cp; ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); ap->guid = guid; - ap->write = write; g_waitfor_event(vdev_geom_attach_by_guid_event, ap, M_WAITOK, NULL); cp = ap->cp; kmem_free(ap, sizeof(*ap)); @@ -433,7 +432,7 @@ vdev_geom_open_by_guid(vdev_t *vd) size_t len; ZFS_LOG(1, "Searching by guid [%ju].", (uintmax_t)vd->vdev_guid); - cp = vdev_geom_attach_by_guid(vd->vdev_guid, !!(spa_mode & FWRITE)); + cp = vdev_geom_attach_by_guid(vd->vdev_guid); if (cp != NULL) { len = strlen(cp->provider->name) + strlen("/dev/") + 1; buf = kmem_alloc(len, KM_SLEEP); @@ -464,7 +463,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid) pp = g_provider_by_name(vd->vdev_path + sizeof("/dev/") - 1); if (pp != NULL) { ZFS_LOG(1, "Found provider by name %s.", vd->vdev_path); - cp = vdev_geom_attach(pp, !!(spa_mode & FWRITE)); + cp = vdev_geom_attach(pp); if (cp != NULL && check_guid) { g_topology_unlock(); guid = vdev_geom_read_guid(cp); @@ -492,7 +491,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) vdev_geom_ctx_t *ctx; struct g_provider *pp; struct g_consumer *cp; - int owned; + int error, owned; /* * We must have a pathname, and it must be absolute. @@ -506,26 +505,47 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) if ((owned = mtx_owned(&Giant))) mtx_unlock(&Giant); - cp = vdev_geom_open_by_path(vd, 1); - if (cp == NULL) { - /* - * The device at vd->vdev_path doesn't have the expected guid. - * The disks might have merely moved around so try all other - * geom providers to find one with the right guid. - */ - cp = vdev_geom_open_by_guid(vd); - } - if (cp == NULL) + error = 0; + + /* + * If we're creating pool, just find GEOM provider by its name + * and ignore GUID mismatches. + */ + if (vd->vdev_spa->spa_load_state == SPA_LOAD_NONE) cp = vdev_geom_open_by_path(vd, 0); + else { + cp = vdev_geom_open_by_path(vd, 1); + if (cp == NULL) { + /* + * The device at vd->vdev_path doesn't have the + * expected guid. The disks might have merely + * moved around so try all other GEOM providers + * to find one with the right guid. + */ + cp = vdev_geom_open_by_guid(vd); + } + } + if (cp == NULL) { ZFS_LOG(1, "Provider %s not found.", vd->vdev_path); - vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; - if (owned) - mtx_lock(&Giant); - return (EACCES); + error = ENOENT; + } else if (cp->acw == 0 && (spa_mode & FWRITE) != 0) { + g_topology_lock(); + error = g_access(cp, 0, 1, 0); + if (error != 0) { + printf("ZFS WARNING: Unable to open %s for writing (error=%d).", + vd->vdev_path, error); + vdev_geom_detach(cp, 0); + cp = NULL; + } + g_topology_unlock(); } if (owned) mtx_lock(&Giant); + if (cp == NULL) { + vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; + return (error); + } cp->private = vd; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index 1132483d48e..07c9b61bd32 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -214,7 +214,7 @@ blksz_changed_cb(void *arg, uint64_t newval) newval = SPA_MAXBLOCKSIZE; zfsvfs->z_max_blksz = newval; - zfsvfs->z_vfs->vfs_bsize = newval; + zfsvfs->z_vfs->mnt_stat.f_iosize = newval; } static void @@ -577,7 +577,8 @@ zfs_domount(vfs_t *vfsp, char *osname) if (error = dsl_prop_get_integer(osname, "recordsize", &recordsize, NULL)) goto out; - zfsvfs->z_vfs->vfs_bsize = recordsize; + zfsvfs->z_vfs->vfs_bsize = SPA_MINBLOCKSIZE; + zfsvfs->z_vfs->mnt_stat.f_iosize = recordsize; vfsp->vfs_data = zfsvfs; vfsp->mnt_flag |= MNT_LOCAL; @@ -817,8 +818,8 @@ zfs_statfs(vfs_t *vfsp, struct statfs *statp) * We report the fragsize as the smallest block size we support, * and we report our blocksize as the filesystem's maximum blocksize. */ - statp->f_bsize = zfsvfs->z_vfs->vfs_bsize; - statp->f_iosize = zfsvfs->z_vfs->vfs_bsize; + statp->f_bsize = SPA_MINBLOCKSIZE; + statp->f_iosize = zfsvfs->z_vfs->mnt_stat.f_iosize; /* * The following report "total" blocks of various kinds in the @@ -826,7 +827,7 @@ zfs_statfs(vfs_t *vfsp, struct statfs *statp) * "fragment" size. */ - statp->f_blocks = (refdbytes + availbytes) / statp->f_bsize; + statp->f_blocks = (refdbytes + availbytes) >> SPA_MINBLOCKSHIFT; statp->f_bfree = availbytes / statp->f_bsize; statp->f_bavail = statp->f_bfree; /* no root reservation */ @@ -867,13 +868,15 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp) ZFS_ENTER_NOERROR(zfsvfs); error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); + + ZFS_EXIT(zfsvfs); + if (error == 0) { *vpp = ZTOV(rootzp); error = vn_lock(*vpp, flags); (*vpp)->v_vflag |= VV_ROOT; } - ZFS_EXIT(zfsvfs); return (error); } @@ -1142,13 +1145,13 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp) VN_RELE(ZTOV(zp)); err = EINVAL; } + ZFS_EXIT(zfsvfs); if (err != 0) *vpp = NULL; else { *vpp = ZTOV(zp); vn_lock(*vpp, flags); } - ZFS_EXIT(zfsvfs); return (err); } @@ -1236,8 +1239,8 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp) } else { VN_HOLD(*vpp); } - vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); ZFS_EXIT(zfsvfs); + vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); return (0); } @@ -1258,10 +1261,11 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp) return (EINVAL); } + ZFS_EXIT(zfsvfs); + *vpp = ZTOV(zp); vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); vnode_create_vobject(*vpp, zp->z_phys->zp_size, curthread); - ZFS_EXIT(zfsvfs); return (0); } 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 4f61f5f3f5e..59a58dd7a5a 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 @@ -1209,15 +1209,17 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp, ltype = VOP_ISLOCKED(dvp); VOP_UNLOCK(dvp, 0); } + ZFS_EXIT(zfsvfs); error = vn_lock(*vpp, cnp->cn_lkflags); if (cnp->cn_flags & ISDOTDOT) vn_lock(dvp, ltype | LK_RETRY); if (error != 0) { VN_RELE(*vpp); *vpp = NULL; - ZFS_EXIT(zfsvfs); return (error); } + } else { + ZFS_EXIT(zfsvfs); } #ifdef FREEBSD_NAMECACHE @@ -1237,8 +1239,6 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp, } #endif - ZFS_EXIT(zfsvfs); - return (error); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index 4650d42b7c2..e7227f2a589 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -90,13 +90,6 @@ zio_init(void) { #ifdef ZIO_USE_UMA size_t c; -#endif -#if 0 - vmem_t *data_alloc_arena = NULL; - -#ifdef _KERNEL - data_alloc_arena = zio_alloc_arena; -#endif #endif zio_cache = kmem_cache_create("zio_cache", sizeof (zio_t), 0, NULL, NULL, NULL, NULL, NULL, 0); @@ -132,8 +125,7 @@ zio_init(void) (void) sprintf(name, "zio_data_buf_%lu", (ulong_t)size); zio_data_buf_cache[c] = kmem_cache_create(name, size, - align, NULL, NULL, NULL, NULL, data_alloc_arena, - KMC_NODEBUG); + align, NULL, NULL, NULL, NULL, NULL, KMC_NODEBUG); } } diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index c95a8409ed4..45540887e64 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -63,8 +63,8 @@ ZFS_SRCS= ${ZFS_OBJS:C/.o$/.c/} SRCS+= ${ZFS_SRCS} SRCS+= vdev_geom.c -# Use UMA for ZIO allocation. This is not stable. -#CFLAGS+=-DZIO_USE_UMA +# Use UMA for ZIO allocation. +CFLAGS+=-DZIO_USE_UMA # Use FreeBSD's namecache. CFLAGS+=-DFREEBSD_NAMECACHE diff --git a/sys/sys/ioccom.h b/sys/sys/ioccom.h index be2ce66b3f7..5669088dc9c 100644 --- a/sys/sys/ioccom.h +++ b/sys/sys/ioccom.h @@ -38,12 +38,13 @@ * any in or out parameters in the upper word. The high 3 bits of the * upper word are used to encode the in/out status of the parameter. */ -#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ +#define IOCPARM_SHIFT 13 /* number of bits for ioctl size */ +#define IOCPARM_MASK ((1 << IOCPARM_SHIFT) - 1) /* parameter length mask */ #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) #define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16)) #define IOCGROUP(x) (((x) >> 8) & 0xff) -#define IOCPARM_MAX PAGE_SIZE /* max size of ioctl, mult. of PAGE_SIZE */ +#define IOCPARM_MAX (1 << IOCPARM_SHIFT) /* max size of ioctl */ #define IOC_VOID 0x20000000 /* no parameters */ #define IOC_OUT 0x40000000 /* copy out parameters */ #define IOC_IN 0x80000000 /* copy in parameters */ From cf66cfa0b13e8d717f8c970decea57775709a034 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 18 Apr 2010 22:51:15 +0000 Subject: [PATCH 2033/2592] MFC: r206170 Harden the experimental NFS server a little, by adding extra checks in the readdir functions for non-positive byte count arguments. For the negative case, set it to the maximum allowable, since it was actually a large positive value (unsigned) on the wire. Also, fix up the readdir function comment a bit. --- sys/fs/nfsserver/nfs_nfsdport.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 8faddfaf3c0..d5607f9cedc 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -1397,24 +1397,16 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct vnode *vp, * nfs readdir service * - mallocs what it thinks is enough to read * count rounded up to a multiple of DIRBLKSIZ <= NFS_MAXREADDIR - * - calls nfsvno_readdir() + * - calls VOP_READDIR() * - loops around building the reply * if the output generated exceeds count break out of loop * The NFSM_CLGET macro is used here so that the reply will be packed * tightly in mbuf clusters. - * - it only knows that it has encountered eof when the nfsvno_readdir() - * reads nothing - * - as such one readdir rpc will return eof false although you are there - * and then the next will return eof * - it trims out records with d_fileno == 0 * this doesn't matter for Unix clients, but they might confuse clients * for other os'. * - it trims out records with d_type == DT_WHT * these cannot be seen through NFS (unless we extend the protocol) - * NB: It is tempting to set eof to true if the nfsvno_readdir() reads less - * than requested, but this may not apply to all filesystems. For - * example, client NFS does not { although it is never remote mounted - * anyhow } * The alternate call nfsrvd_readdirplus() does lookups as well. * PS: The NFS protocol spec. does not clarify what the "count" byte * argument is a count of.. just name strings and file id's or the @@ -1456,7 +1448,7 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram, } toff = off; cnt = fxdr_unsigned(int, *tl); - if (cnt > NFS_SRVMAXDATA(nd)) + if (cnt > NFS_SRVMAXDATA(nd) || cnt < 0) cnt = NFS_SRVMAXDATA(nd); siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); fullsiz = siz; @@ -1474,6 +1466,13 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram, nd->nd_repstat = NFSERR_BAD_COOKIE; #endif } + if (nd->nd_repstat == 0 && cnt == 0) { + if (nd->nd_flag & ND_NFSV2) + /* NFSv2 does not have NFSERR_TOOSMALL */ + nd->nd_repstat = EPERM; + else + nd->nd_repstat = NFSERR_TOOSMALL; + } if (!nd->nd_repstat) nd->nd_repstat = nfsvno_accchk(vp, VEXEC, nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE, @@ -1696,7 +1695,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, * Use the server's maximum data transfer size as the upper bound * on reply datalen. */ - if (cnt > NFS_SRVMAXDATA(nd)) + if (cnt > NFS_SRVMAXDATA(nd) || cnt < 0) cnt = NFS_SRVMAXDATA(nd); /* @@ -1705,7 +1704,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, * so I set it to cnt for that case. I also round it up to the * next multiple of DIRBLKSIZ. */ - if (siz == 0) + if (siz <= 0) siz = cnt; siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); From a3c8a78f40a5312b72023828bb8fea174e010ec8 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 19 Apr 2010 04:54:34 +0000 Subject: [PATCH 2034/2592] MFC r204080: Create a directory for hast's examples. --- etc/mtree/BSD.usr.dist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index e2032b1e17b..bc440c8b2ca 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -211,6 +211,8 @@ .. find_interface .. + hast + .. hostapd .. ibcs2 From 40a16c07eae393a970fcaa5bf83ac0256f216d26 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 19 Apr 2010 14:23:15 +0000 Subject: [PATCH 2035/2592] MFC r204352: Fixed static linkage. --- sbin/hastd/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sbin/hastd/Makefile b/sbin/hastd/Makefile index 16a0b8f035b..43118075e94 100644 --- a/sbin/hastd/Makefile +++ b/sbin/hastd/Makefile @@ -27,8 +27,9 @@ CFLAGS+=-DINET6 # This is needed to have WARNS > 1. CFLAGS+=-DYY_NO_UNPUT -DPADD= ${LIBCRYPTO} ${LIBGEOM} ${LIBL} ${LIBPTHREAD} ${LIBUTIL} -LDADD= -lcrypto -lgeom -ll -lpthread -lutil +DPADD= ${LIBCRYPTO} ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} ${LIBL} \ + ${LIBPTHREAD} ${LIBUTIL} +LDADD= -lcrypto -lgeom -lbsdxml -lsbuf -ll -lpthread -lutil YFLAGS+=-v From 6867f9762564aa9d55c4d53705a180039ba4f0e9 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 19 Apr 2010 18:19:59 +0000 Subject: [PATCH 2036/2592] MFC r196987: Remove useless variable assignment. --- sys/ufs/ufs/ufs_acl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/ufs/ufs/ufs_acl.c b/sys/ufs/ufs/ufs_acl.c index 1a0030cf2bd..c244e871cac 100644 --- a/sys/ufs/ufs/ufs_acl.c +++ b/sys/ufs/ufs/ufs_acl.c @@ -330,9 +330,6 @@ ufs_getacl_posix1e(struct vop_getacl_args *ap) old->acl_cnt = 0; break; } - - error = 0; - /* FALLTHROUGH */ case 0: error = acl_copy_oldacl_into_acl(old, ap->a_aclp); From 49ea01c1ce986d3e9579937c2f06970a558d7fe1 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 19 Apr 2010 18:22:21 +0000 Subject: [PATCH 2037/2592] MFC r202971: Return proper error code. Found with: clang --- sys/ufs/ufs/ufs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/ufs/ufs/ufs_acl.c b/sys/ufs/ufs/ufs_acl.c index c244e871cac..8ed1c0b2110 100644 --- a/sys/ufs/ufs/ufs_acl.c +++ b/sys/ufs/ufs/ufs_acl.c @@ -465,7 +465,7 @@ ufs_setacl_nfs4(struct vop_setacl_args *ap) error = ufs_setacl_nfs4_internal(ap->a_vp, ap->a_aclp, ap->a_td); - return (0); + return (error); } /* From 8cfb2407c2c21d75e3fffdf142a92bfc363f226f Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Mon, 19 Apr 2010 21:01:24 +0000 Subject: [PATCH 2038/2592] MFC of tzdata2010i, r206868 - Marocco does have DST this year between May and August. - Historical data for Taiwan - Argentina / San Luis does not do DST this year. --- share/zoneinfo/africa | 40 +++++++++++++++++++++++++-- share/zoneinfo/asia | 55 +++++++++++++++++++++++++++++++++---- share/zoneinfo/southamerica | 27 ++++++++++++++++-- 3 files changed, 111 insertions(+), 11 deletions(-) diff --git a/share/zoneinfo/africa b/share/zoneinfo/africa index ad89bb743c1..8cae7a682b0 100644 --- a/share/zoneinfo/africa +++ b/share/zoneinfo/africa @@ -1,5 +1,5 @@ #

    -# @(#)africa	8.23
    +# @(#)africa	8.26
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -680,6 +680,21 @@ Zone	Indian/Mayotte	3:00:56 -	LMT	1911 Jul	# Mamoutzou
     # http://www.worldtimezone.com/dst_news/dst_news_morocco03.html
     # 
     
    +# From Steffen Thorsen (2010-04-13):
    +# Several news media in Morocco report that the Ministry of Modernization
    +# of Public Sectors has announced that Morocco will have DST from
    +# 2010-05-02 to 2010-08-08.
    +#
    +# Example:
    +# 
    +# http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html
    +# 
    +# (French)
    +# Our page:
    +# 
    +# http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html
    +# 
    +
     # RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
     
     Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
    @@ -701,6 +716,8 @@ Rule	Morocco	2008	only	-	Jun	 1	 0:00	1:00	S
     Rule	Morocco	2008	only	-	Sep	 1	 0:00	0	-
     Rule	Morocco	2009	only	-	Jun	 1	 0:00	1:00	S
     Rule	Morocco	2009	only	-	Aug	 21	 0:00	0	-
    +Rule	Morocco	2010	only	-	May	 2	 0:00	1:00	S
    +Rule	Morocco	2010	only	-	Aug	 8	 0:00	0	-
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
     Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
     			 0:00	Morocco	WE%sT	1984 Mar 16
    @@ -942,6 +959,24 @@ Zone	Africa/Lome	0:04:52 -	LMT	1893
     # Therefore, the standard time will be kept unchanged the whole year long."
     # So foregoing DST seems to be an exception (albeit one that may be repeated in the  future).
     
    +# From Alexander Krivenyshev (2010-03-27):
    +# According to some news reports Tunis confirmed not to use DST in 2010
    +#
    +# (translation):
    +# "The Tunisian government has decided to abandon DST, which was scheduled on
    +# Sunday...
    +# Tunisian authorities had suspended the DST for the first time last year also
    +# coincided with the month of Ramadan..."
    +#
    +# (in Arabic)
    +# 
    +# http://www.moheet.com/show_news.aspx?nid=358861&pg=1
    +# 
    +# http://www.almadenahnews.com/newss/news.php?c=118&id=38036
    +# or
    +# 
    +# http://www.worldtimezone.com/dst_news/dst_news_tunis02.html
    +
     # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
     Rule	Tunisia	1939	only	-	Apr	15	23:00s	1:00	S
     Rule	Tunisia	1939	only	-	Nov	18	23:00s	0	-
    @@ -968,8 +1003,7 @@ Rule	Tunisia	2005	only	-	May	 1	 0:00s	1:00	S
     Rule	Tunisia	2005	only	-	Sep	30	 1:00s	0	-
     Rule	Tunisia	2006	2008	-	Mar	lastSun	 2:00s	1:00	S
     Rule	Tunisia	2006	2008	-	Oct	lastSun	 2:00s	0	-
    -Rule	Tunisia	2010	max	-	Mar	lastSun	 2:00s	1:00	S
    -Rule	Tunisia	2010	max	-	Oct	lastSun	 2:00s	0	-
    +
     # Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
     # more precise 0:09:21.
     # Shanks & Pottenger say the 1911 switch was on Mar 9; go with Howse's Mar 11.
    diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia
    index 8cafc5973e2..78ff2ffedcf 100644
    --- a/share/zoneinfo/asia
    +++ b/share/zoneinfo/asia
    @@ -1,4 +1,4 @@
    -# @(#)asia	8.58
    +# @(#)asia	8.60
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -566,6 +566,28 @@ Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
     # was still controlled by Japan.  This is hard to believe, but we don't
     # have any other information.
     
    +# From smallufo (2010-04-03):
    +# According to Taiwan's CWB,
    +# 
    +# http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm
    +# 
    +# Taipei has DST in 1979 between July 1st and Sep 30.
    +
    +# From Arthur David Olson (2010-04-07):
    +# Here's Google's translation of the table at the bottom of the "summert.htm" page:
    +# Decade 	                                                    Name                      Start and end date
    +# Republic of China 34 years to 40 years (AD 1945-1951 years) Summer Time               May 1 to September 30 
    +# 41 years of the Republic of China (AD 1952)                 Daylight Saving Time      March 1 to October 31 
    +# Republic of China 42 years to 43 years (AD 1953-1954 years) Daylight Saving Time      April 1 to October 31 
    +# In the 44 years to 45 years (AD 1955-1956 years)            Daylight Saving Time      April 1 to September 30 
    +# Republic of China 46 years to 48 years (AD 1957-1959)       Summer Time               April 1 to September 30 
    +# Republic of China 49 years to 50 years (AD 1960-1961)       Summer Time               June 1 to September 30 
    +# Republic of China 51 years to 62 years (AD 1962-1973 years) Stop Summer Time 
    +# Republic of China 63 years to 64 years (1974-1975 AD)       Daylight Saving Time      April 1 to September 30 
    +# Republic of China 65 years to 67 years (1976-1978 AD)       Stop Daylight Saving Time 
    +# Republic of China 68 years (AD 1979)                        Daylight Saving Time      July 1 to September 30 
    +# Republic of China since 69 years (AD 1980)                  Stop Daylight Saving Time
    +
     # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
     Rule	Taiwan	1945	1951	-	May	1	0:00	1:00	D
     Rule	Taiwan	1945	1951	-	Oct	1	0:00	0	S
    @@ -576,8 +598,9 @@ Rule	Taiwan	1955	1961	-	Oct	1	0:00	0	S
     Rule	Taiwan	1960	1961	-	Jun	1	0:00	1:00	D
     Rule	Taiwan	1974	1975	-	Apr	1	0:00	1:00	D
     Rule	Taiwan	1974	1975	-	Oct	1	0:00	0	S
    -Rule	Taiwan	1980	only	-	Jun	30	0:00	1:00	D
    -Rule	Taiwan	1980	only	-	Sep	30	0:00	0	S
    +Rule	Taiwan	1979	only	-	Jun	30	0:00	1:00	D
    +Rule	Taiwan	1979	only	-	Sep	30	0:00	0	S
    +
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
     Zone	Asia/Taipei	8:06:00 -	LMT	1896 # or Taibei or T'ai-pei
     			8:00	Taiwan	C%sT
    @@ -1912,13 +1935,35 @@ Zone	Asia/Muscat	3:54:20 -	LMT	1920
     # [T]he German Consulate General in Karachi reported me today that Pakistan
     # will go back to standard time on 1st of November.
     
    +# From Steffen Thorsen (2010-03-26):
    +# Steffen Thorsen wrote:
    +# > On Thursday (2010-03-25) it was announced that DST would start in
    +# > Pakistan on 2010-04-01.
    +# >
    +# > Then today, the president said that they might have to revert the
    +# > decision if it is not supported by the parliament. So at the time
    +# > being, it seems unclear if DST will be actually observed or not - but
    +# > April 1 could be a more likely date than April 15.
    +# Now, it seems that the decision to not observe DST in final:
    +#
    +# "Govt Withdraws Plan To Advance Clocks"
    +# 
    +# http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041
    +# 
    +#
    +# "People laud PM's announcement to end DST"
    +# 
    +# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2
    +# 
    +
     # 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	max	-	Apr	15	0:00	1:00	S
    -Rule Pakistan	2009	max	-	Nov	1	0:00	0	-
    +Rule Pakistan	2009	only	-	Apr	15	0:00	1:00	S
    +Rule Pakistan	2009	only	-	Nov	1	0:00	0	-
    +
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
     Zone	Asia/Karachi	4:28:12 -	LMT	1907
     			5:30	-	IST	1942 Sep
    diff --git a/share/zoneinfo/southamerica b/share/zoneinfo/southamerica
    index 8db45ccda9a..7355022929d 100644
    --- a/share/zoneinfo/southamerica
    +++ b/share/zoneinfo/southamerica
    @@ -1,5 +1,5 @@
     # 
    -# @(#)southamerica	8.43
    +# @(#)southamerica	8.44
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     
    @@ -437,6 +437,27 @@ Rule	Arg	2008	only	-	Oct	Sun>=15	0:00	1:00	S
     # of the country calls it "ART".
     # ...
     
    +# From Alexander Krivenyshev (2010-04-09):
    +# According to news reports from El Diario de la Republica Province San
    +# Luis, Argentina (standard time UTC-04) will keep Daylight Saving Time
    +# after April 11, 2010--will continue to have same time as rest of
    +# Argentina (UTC-3) (no DST).
    +#
    +# Confirmaron la prórroga del huso horario de verano (Spanish)
    +# 
    +# http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9
    +# 
    +# or (some English translation):
    +# 
    +# http://www.worldtimezone.com/dst_news/dst_news_argentina08.html
    +# 
    +
    +# From Mariano Absatz (2010-04-12):
    +# yes...I can confirm this...and given that San Luis keeps calling
    +# UTC-03:00 "summer time", we should't just let San Luis go back to "Arg"
    +# rules...San Luis is still using "Western ARgentina Time" and it got
    +# stuck on Summer daylight savings time even though the summer is over.
    +
     # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
     #
     # Buenos Aires (BA), Capital Federal (CF),
    @@ -570,8 +591,8 @@ Zone America/Argentina/Mendoza -4:35:16 - LMT	1894 Oct 31
     #
     # 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
    +Rule	SanLuis	2008	2009	-	Mar	Sun>=8	0:00	0	-
    +Rule	SanLuis	2007	2009	-	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
    
    From 0c58adb2fa076ef00271be9fd75d66bd3cb989f2 Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Tue, 20 Apr 2010 01:25:18 +0000
    Subject: [PATCH 2039/2592] MFC: r206236 Harden the experimental NFS server a
     little, by adding range checks on the length of the client's open/lock owner
     name. Also, add free()'s for one case where they were missing and would have
     caused a leak if NFSERR_BADXDR had been replied. Probably never happens, but
     the leak is now plugged, just in case.
    
    ---
     sys/fs/nfsserver/nfs_nfsdserv.c | 22 ++++++++++++++++++++++
     1 file changed, 22 insertions(+)
    
    diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
    index 9a362873e72..50fa822b512 100644
    --- a/sys/fs/nfsserver/nfs_nfsdserv.c
    +++ b/sys/fs/nfsserver/nfs_nfsdserv.c
    @@ -2086,6 +2086,10 @@ nfsrvd_lock(struct nfsrv_descript *nd, __unused int isdgram,
     	if (flags & NFSLCK_OPENTOLOCK) {
     		NFSM_DISSECT(tl, u_int32_t *, 5 * NFSX_UNSIGNED + NFSX_STATEID);
     		i = fxdr_unsigned(int, *(tl+4+(NFSX_STATEID / NFSX_UNSIGNED)));
    +		if (i <= 0 || i > NFSV4_OPAQUELIMIT) {
    +			nd->nd_repstat = NFSERR_BADXDR;
    +			goto nfsmout;
    +		}
     		MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + i,
     			M_NFSDSTATE, M_WAITOK);
     		stp->ls_ownerlen = i;
    @@ -2229,6 +2233,10 @@ nfsrvd_lockt(struct nfsrv_descript *nd, __unused int isdgram,
     
     	NFSM_DISSECT(tl, u_int32_t *, 8 * NFSX_UNSIGNED);
     	i = fxdr_unsigned(int, *(tl + 7));
    +	if (i <= 0 || i > NFSV4_OPAQUELIMIT) {
    +		nd->nd_repstat = NFSERR_BADXDR;
    +		goto nfsmout;
    +	}
     	MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + i,
     	    M_NFSDSTATE, M_WAITOK);
     	stp->ls_ownerlen = i;
    @@ -2350,6 +2358,8 @@ nfsrvd_locku(struct nfsrv_descript *nd, __unused int isdgram,
     		break;
     	default:
     		nd->nd_repstat = NFSERR_BADXDR;
    +		free(stp, M_NFSDSTATE);
    +		free(lop, M_NFSDLOCK);
     		goto nfsmout;
     	};
     	stp->ls_ownerlen = 0;
    @@ -2439,6 +2449,14 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
     	named.ni_cnd.cn_nameiop = 0;
     	NFSM_DISSECT(tl, u_int32_t *, 6 * NFSX_UNSIGNED);
     	i = fxdr_unsigned(int, *(tl + 5));
    +	if (i <= 0 || i > NFSV4_OPAQUELIMIT) {
    +		nd->nd_repstat = NFSERR_BADXDR;
    +		vrele(dp);
    +#ifdef NFS4_ACL_EXTATTR_NAME
    +		acl_free(aclp);
    +#endif
    +		return (0);
    +	}
     	MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + i,
     	    M_NFSDSTATE, M_WAITOK);
     	stp->ls_ownerlen = i;
    @@ -3391,6 +3409,10 @@ nfsrvd_releaselckown(struct nfsrv_descript *nd, __unused int isdgram,
     	}
     	NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
     	len = fxdr_unsigned(int, *(tl + 2));
    +	if (len <= 0 || len > NFSV4_OPAQUELIMIT) {
    +		nd->nd_repstat = NFSERR_BADXDR;
    +		return (0);
    +	}
     	MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + len,
     	    M_NFSDSTATE, M_WAITOK);
     	stp->ls_ownerlen = len;
    
    From 66df5bde4d2356da18b3d349d8d28fe05aec2f54 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 20 Apr 2010 08:19:43 +0000
    Subject: [PATCH 2040/2592] MFC r206553: Change printf() calls to uprintf() for
     sigreturn() and trap() complaints about inacessible or wrong mcontext, and
     for dreaded "kernel trap with interrupts disabled" situation. The later is
     changed when trap is generated from user mode (shall never be ?).
    
    Normalize the messages to include both pid and thread name.
    ---
     sys/amd64/amd64/machdep.c    | 17 ++++++++++-------
     sys/amd64/amd64/trap.c       |  2 +-
     sys/amd64/ia32/ia32_signal.c | 12 ++++++++----
     sys/i386/i386/machdep.c      | 12 ++++++++----
     sys/i386/i386/trap.c         |  4 ++--
     5 files changed, 29 insertions(+), 18 deletions(-)
    
    diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
    index c4130a453f9..76713767ea2 100644
    --- a/sys/amd64/amd64/machdep.c
    +++ b/sys/amd64/amd64/machdep.c
    @@ -422,13 +422,14 @@ sigreturn(td, uap)
     
     	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
     	if (error != 0) {
    -		printf("sigreturn (pid %d): copyin failed\n", p->p_pid);
    +		uprintf("pid %d (%s): sigreturn copyin failed\n",
    +		    p->p_pid, td->td_name);
     		return (error);
     	}
     	ucp = &uc;
     	if ((ucp->uc_mcontext.mc_flags & ~_MC_FLAG_MASK) != 0) {
    -		printf("sigreturn (pid %d): mc_flags %x\n", p->p_pid,
    -		    ucp->uc_mcontext.mc_flags);
    +		uprintf("pid %d (%s): sigreturn mc_flags %x\n", p->p_pid,
    +		    td->td_name, ucp->uc_mcontext.mc_flags);
     		return (EINVAL);
     	}
     	regs = td->td_frame;
    @@ -447,8 +448,8 @@ sigreturn(td, uap)
     	 * one less debugger trap, so allowing it is fairly harmless.
     	 */
     	if (!EFL_SECURE(rflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
    -		printf("sigreturn (pid %d): rflags = 0x%lx\n", p->p_pid,
    -		    rflags);
    +		uprintf("pid %d (%s): sigreturn rflags = 0x%lx\n", p->p_pid,
    +		    td->td_name, rflags);
     		return (EINVAL);
     	}
     
    @@ -459,7 +460,8 @@ sigreturn(td, uap)
     	 */
     	cs = ucp->uc_mcontext.mc_cs;
     	if (!CS_SECURE(cs)) {
    -		printf("sigreturn (pid %d): cs = 0x%x\n", p->p_pid, cs);
    +		uprintf("pid %d (%s): sigreturn cs = 0x%x\n", p->p_pid,
    +		    td->td_name, cs);
     		ksiginfo_init_trap(&ksi);
     		ksi.ksi_signo = SIGBUS;
     		ksi.ksi_code = BUS_OBJERR;
    @@ -471,7 +473,8 @@ sigreturn(td, uap)
     
     	ret = set_fpcontext(td, &ucp->uc_mcontext);
     	if (ret != 0) {
    -		printf("sigreturn (pid %d): set_fpcontext\n", p->p_pid);
    +		uprintf("pid %d (%s): sigreturn set_fpcontext err %d\n",
    +		    p->p_pid, td->td_name, ret);
     		return (ret);
     	}
     	bcopy(&ucp->uc_mcontext.mc_rdi, regs, sizeof(*regs));
    diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
    index 4b5d8c7b48f..8492f4e719b 100644
    --- a/sys/amd64/amd64/trap.c
    +++ b/sys/amd64/amd64/trap.c
    @@ -303,7 +303,7 @@ trap(struct trapframe *frame)
     		 * enabled later.
     		 */
     		if (ISPL(frame->tf_cs) == SEL_UPL)
    -			printf(
    +			uprintf(
     			    "pid %ld (%s): trap %d with interrupts disabled\n",
     			    (long)curproc->p_pid, curthread->td_name, type);
     		else if (type != T_NMI && type != T_BPTFLT &&
    diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
    index 10ec641bc61..241698818c3 100644
    --- a/sys/amd64/ia32/ia32_signal.c
    +++ b/sys/amd64/ia32/ia32_signal.c
    @@ -565,7 +565,8 @@ freebsd4_freebsd32_sigreturn(td, uap)
     	 * one less debugger trap, so allowing it is fairly harmless.
     	 */
     	if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
    -		printf("freebsd4_freebsd32_sigreturn: eflags = 0x%x\n", eflags);
    +		uprintf("pid %d (%s): freebsd4_freebsd32_sigreturn eflags = 0x%x\n",
    +		    td->td_proc->p_pid, td->td_name, eflags);
     		return (EINVAL);
     	}
     
    @@ -576,7 +577,8 @@ freebsd4_freebsd32_sigreturn(td, uap)
     	 */
     	cs = ucp->uc_mcontext.mc_cs;
     	if (!CS_SECURE(cs)) {
    -		printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
    +		uprintf("pid %d (%s): freebsd4_sigreturn cs = 0x%x\n",
    +		    td->td_proc->p_pid, td->td_name, cs);
     		ksiginfo_init_trap(&ksi);
     		ksi.ksi_signo = SIGBUS;
     		ksi.ksi_code = BUS_OBJERR;
    @@ -647,7 +649,8 @@ freebsd32_sigreturn(td, uap)
     	 * one less debugger trap, so allowing it is fairly harmless.
     	 */
     	if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
    -		printf("freebsd32_sigreturn: eflags = 0x%x\n", eflags);
    +		uprintf("pid %d (%s): freebsd32_sigreturn eflags = 0x%x\n",
    +		    td->td_proc->p_pid, td->td_name, eflags);
     		return (EINVAL);
     	}
     
    @@ -658,7 +661,8 @@ freebsd32_sigreturn(td, uap)
     	 */
     	cs = ucp->uc_mcontext.mc_cs;
     	if (!CS_SECURE(cs)) {
    -		printf("sigreturn: cs = 0x%x\n", cs);
    +		uprintf("pid %d (%s): sigreturn cs = 0x%x\n",
    +		    td->td_proc->p_pid, td->td_name, cs);
     		ksiginfo_init_trap(&ksi);
     		ksi.ksi_signo = SIGBUS;
     		ksi.ksi_code = BUS_OBJERR;
    diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
    index 801af7c97f4..234053a19c0 100644
    --- a/sys/i386/i386/machdep.c
    +++ b/sys/i386/i386/machdep.c
    @@ -944,7 +944,8 @@ freebsd4_sigreturn(td, uap)
     		 * one less debugger trap, so allowing it is fairly harmless.
     		 */
     		if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
    -			printf("freebsd4_sigreturn: eflags = 0x%x\n", eflags);
    +			uprintf("pid %d (%s): freebsd4_sigreturn eflags = 0x%x\n",
    +			    td->td_proc->p_pid, td->td_name, eflags);
     	    		return (EINVAL);
     		}
     
    @@ -955,7 +956,8 @@ freebsd4_sigreturn(td, uap)
     		 */
     		cs = ucp->uc_mcontext.mc_cs;
     		if (!CS_SECURE(cs)) {
    -			printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
    +			uprintf("pid %d (%s): freebsd4_sigreturn cs = 0x%x\n",
    +			    td->td_proc->p_pid, td->td_name, cs);
     			ksiginfo_init_trap(&ksi);
     			ksi.ksi_signo = SIGBUS;
     			ksi.ksi_code = BUS_OBJERR;
    @@ -1056,7 +1058,8 @@ sigreturn(td, uap)
     		 * one less debugger trap, so allowing it is fairly harmless.
     		 */
     		if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
    -			printf("sigreturn: eflags = 0x%x\n", eflags);
    +			uprintf("pid %d (%s): sigreturn eflags = 0x%x\n",
    +			    td->td_proc->p_pid, td->td_name, eflags);
     	    		return (EINVAL);
     		}
     
    @@ -1067,7 +1070,8 @@ sigreturn(td, uap)
     		 */
     		cs = ucp->uc_mcontext.mc_cs;
     		if (!CS_SECURE(cs)) {
    -			printf("sigreturn: cs = 0x%x\n", cs);
    +			uprintf("pid %d (%s): sigreturn cs = 0x%x\n",
    +			    td->td_proc->p_pid, td->td_name, cs);
     			ksiginfo_init_trap(&ksi);
     			ksi.ksi_signo = SIGBUS;
     			ksi.ksi_code = BUS_OBJERR;
    diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
    index e3d53f32d62..237be83fc5f 100644
    --- a/sys/i386/i386/trap.c
    +++ b/sys/i386/i386/trap.c
    @@ -277,7 +277,7 @@ trap(struct trapframe *frame)
     		 * enabled later.
     		 */
     		if (ISPL(frame->tf_cs) == SEL_UPL || (frame->tf_eflags & PSL_VM))
    -			printf(
    +			uprintf(
     			    "pid %ld (%s): trap %d with interrupts disabled\n",
     			    (long)curproc->p_pid, curthread->td_name, type);
     		else if (type != T_BPTFLT && type != T_TRCTRAP &&
    @@ -507,7 +507,7 @@ trap(struct trapframe *frame)
     			if (npxdna())
     				goto userout;
     #endif
    -			printf("pid %d killed due to lack of floating point\n",
    +			uprintf("pid %d killed due to lack of floating point\n",
     				p->p_pid);
     			i = SIGKILL;
     			ucode = 0;
    
    From 288a242625e882b7513fafaac96150bfe691f617 Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Tue, 20 Apr 2010 12:07:16 +0000
    Subject: [PATCH 2041/2592] MFC r206427, r206706, r206771:   ubthidhci rc.d
     script to switch an USB bluetooth dongle from HID to   HCI mode.
    
    ---
     etc/defaults/rc.conf     |  5 +++++
     etc/rc.d/Makefile        |  4 ++++
     etc/rc.d/ubthidhci       | 40 ++++++++++++++++++++++++++++++++++++++++
     share/man/man5/rc.conf.5 | 21 +++++++++++++++++++++
     4 files changed, 70 insertions(+)
     create mode 100755 etc/rc.d/ubthidhci
    
    diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
    index c0743ccd58c..34a44fc3ae5 100644
    --- a/etc/defaults/rc.conf
    +++ b/etc/defaults/rc.conf
    @@ -433,6 +433,11 @@ rfcomm_pppd_server_two_channel="3"	# Override local channel for 'two'
     #rfcomm_pppd_server_two_register_sp="NO"	# Override SP and DUN register
     #rfcomm_pppd_server_two_register_dun="NO"	# for 'two'
     
    +ubthidhci_enable="NO"		# Switch an USB BT controller present on
    +#ubthidhci_busnum="3"		# bus 3 and addr 2 from HID mode to HCI mode.
    +#ubthidhci_addr="2"		# Check usbconfig list to find the correct
    +				# numbers for your system.
    +
     ### Miscellaneous network options: ###
     icmp_bmcastecho="NO"	# respond to broadcast ping packets
     
    diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile
    index 22028a3a380..a2a347d2d20 100755
    --- a/etc/rc.d/Makefile
    +++ b/etc/rc.d/Makefile
    @@ -50,6 +50,10 @@ FILES+=	sshd
     FILES+= nscd
     .endif
     
    +.if ${MK_BLUETOOTH} != "no"
    +FILES+=	ubthidhci
    +.endif
    +
     FILESDIR=	/etc/rc.d
     FILESMODE=	${BINMODE}
     
    diff --git a/etc/rc.d/ubthidhci b/etc/rc.d/ubthidhci
    new file mode 100755
    index 00000000000..67d734603e8
    --- /dev/null
    +++ b/etc/rc.d/ubthidhci
    @@ -0,0 +1,40 @@
    +#!/bin/sh
    +#
    +# $FreeBSD$
    +#
    +
    +# PROVIDE: ubthidhci
    +# REQUIRE: DAEMON 
    +# BEFORE: bluetooth 
    +# KEYWORD: nojail shutdown
    +
    +. /etc/rc.subr
    +
    +name="ubthidhci"
    +command="/usr/sbin/usbconfig"
    +rcvar=`set_rcvar`
    +start_precmd="ubthidhci_prestart"
    +
    +ubthidhci_prestart()
    +{
    +
    +	if [ -z ${ubthidhci_busnum} ]; then
    +		warn ubthidhci_busnum is not set
    +		return 1
    +	fi
    +	if [ -z ${ubthidhci_addr} ]; then
    +		warn ubthidhci_addr is not set
    +		return 1
    +	fi
    +}
    +
    +load_rc_config $name
    +#
    +# We discard the output because:
    +# 1) we don't want it to show up during boot; and
    +# 2) the request usually returns an error, but that doesn't mean it failed
    +#
    +# NB: 0x40 is UT_VENDOR
    +command_args="-u ${ubthidhci_busnum} -a ${ubthidhci_addr} do_request 0x40 0 0 0 0 > /dev/null 2>&1"
    +
    +run_rc_command "$1"
    diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
    index 07f2fb81665..fea59a8a2d8 100644
    --- a/share/man/man5/rc.conf.5
    +++ b/share/man/man5/rc.conf.5
    @@ -4143,6 +4143,26 @@ if it should register Dial-Up Networking service on the speficied
     RFCOMM channel.
     Default
     .Dq Li NO .
    +.It Va ubthidhci_enable
    +.Pq Vt bool
    +If set to
    +.Dq Li YES ,
    +change the USB Bluetooth controller from HID mode to HCI mode.
    +You also need to specify the location of USB Bluetooth controller with the
    +.Va ubthidhci_busnum
    +and
    +.Va ubthidhci_addr
    +variables.
    +.It Va ubthidhci_busnum
    +Bus number where the USB Bluetooth controller is located.
    +Check the output of
    +.Xr usbconfig 1
    +on your system to find this information.
    +.It Va ubthidhci_addr
    +Bus address of the USB Bluetooth controller.
    +Check the output of
    +.Xr usbconfig 1
    +on your system to find this information.
     .El
     .Sh FILES
     .Bl -tag -width ".Pa /etc/defaults/rc.conf" -compact
    @@ -4158,6 +4178,7 @@ Default
     .Xr kbdcontrol 1 ,
     .Xr makewhatis 1 ,
     .Xr sh 1 ,
    +.Xr usbconfig 1 ,
     .Xr vi 1 ,
     .Xr vidcontrol 1 ,
     .Xr bridge 4 ,
    
    From 31a3c43a0fc71c51f8710222bd39e55473f5b310 Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Tue, 20 Apr 2010 15:23:12 +0000
    Subject: [PATCH 2042/2592] MFC geom_sched code, a geom-based disk scheduling
     framework.
    
    ---
     sbin/geom/class/Makefile                      |    1 +
     sbin/geom/class/sched/Makefile                |   18 +
     sbin/geom/class/sched/geom_sched.c            |  124 ++
     sbin/geom/class/sched/gsched.8                |  163 ++
     sys/geom/sched/README                         |  162 ++
     sys/geom/sched/g_sched.c                      | 1902 +++++++++++++++++
     sys/geom/sched/g_sched.h                      |  138 ++
     sys/geom/sched/gs_rr.c                        |  686 ++++++
     sys/geom/sched/gs_scheduler.h                 |  237 ++
     sys/geom/sched/subr_disk.c                    |  209 ++
     sys/modules/geom/Makefile                     |    1 +
     sys/modules/geom/geom_sched/Makefile          |    5 +
     sys/modules/geom/geom_sched/Makefile.inc      |    9 +
     sys/modules/geom/geom_sched/gs_sched/Makefile |    6 +
     .../geom/geom_sched/gsched_rr/Makefile        |    9 +
     15 files changed, 3670 insertions(+)
     create mode 100644 sbin/geom/class/sched/Makefile
     create mode 100644 sbin/geom/class/sched/geom_sched.c
     create mode 100644 sbin/geom/class/sched/gsched.8
     create mode 100644 sys/geom/sched/README
     create mode 100644 sys/geom/sched/g_sched.c
     create mode 100644 sys/geom/sched/g_sched.h
     create mode 100644 sys/geom/sched/gs_rr.c
     create mode 100644 sys/geom/sched/gs_scheduler.h
     create mode 100644 sys/geom/sched/subr_disk.c
     create mode 100644 sys/modules/geom/geom_sched/Makefile
     create mode 100644 sys/modules/geom/geom_sched/Makefile.inc
     create mode 100644 sys/modules/geom/geom_sched/gs_sched/Makefile
     create mode 100644 sys/modules/geom/geom_sched/gsched_rr/Makefile
    
    diff --git a/sbin/geom/class/Makefile b/sbin/geom/class/Makefile
    index 7b556a8f2d3..0be19e38de1 100644
    --- a/sbin/geom/class/Makefile
    +++ b/sbin/geom/class/Makefile
    @@ -14,6 +14,7 @@ SUBDIR+=multipath
     SUBDIR+=nop
     SUBDIR+=part
     SUBDIR+=raid3
    +SUBDIR+=sched
     SUBDIR+=shsec
     SUBDIR+=stripe
     SUBDIR+=virstor
    diff --git a/sbin/geom/class/sched/Makefile b/sbin/geom/class/sched/Makefile
    new file mode 100644
    index 00000000000..6656cdd466f
    --- /dev/null
    +++ b/sbin/geom/class/sched/Makefile
    @@ -0,0 +1,18 @@
    +# GEOM_LIBRARY_PATH
    +# $FreeBSD$
    +
    +.PATH: ${.CURDIR}/../../misc
    +#CFLAGS += -I/usr/src/sbin/geom
    +
    +CLASS=sched
    +
    +WARNS?= 6
    +CLASS_DIR?=/lib/geom
    +
    +SHLIBDIR?=${CLASS_DIR}
    +SHLIB_NAME?=geom_${CLASS}.so
    +LINKS=  ${BINDIR}/geom ${BINDIR}/g${CLASS}
    +MAN=    g${CLASS}.8
    +SRCS+=  geom_${CLASS}.c subr.c
    +
    +.include 
    diff --git a/sbin/geom/class/sched/geom_sched.c b/sbin/geom/class/sched/geom_sched.c
    new file mode 100644
    index 00000000000..ca05350805b
    --- /dev/null
    +++ b/sbin/geom/class/sched/geom_sched.c
    @@ -0,0 +1,124 @@
    +/*-
    + * Copyright (c) 2009 Fabio Checconi
    + * Copyright (c) 2010 Luigi Rizzo, Universita` di Pisa
    + * 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 AUTHORS 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 AUTHORS 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.
    + */
    +
    +/*
    + * $Id$
    + * $FreeBSD$
    + *
    + * This file implements the userspace library used by the 'geom'
    + * command to load and manipulate disk schedulers.
    + */
    +  
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +#include "core/geom.h"
    +#include "misc/subr.h"
    +
    +#define	G_SCHED_VERSION	0
    +
    +uint32_t lib_version = G_LIB_VERSION;
    +uint32_t version = G_SCHED_VERSION;
    +
    +/*
    + * storage for parameters used by this geom class.
    + * Right now only the scheduler name is used.
    + */
    +static char algo[] = "rr";	/* default scheduler */
    +
    +/*
    + * Adapt to differences in geom library.
    + * in V1 struct g_command misses gc_argname, eld, and G_BOOL is undefined
    + */
    +#if G_LIB_VERSION == 1
    +#define G_ARGNAME
    +#define G_TYPE_BOOL	G_TYPE_NUMBER
    +#else
    +#define G_ARGNAME	NULL,
    +#endif
    +
    +static void
    +gcmd_createinsert(struct gctl_req *req, unsigned flags __unused)
    +{
    +	const char *reqalgo;
    +	char name[64];
    +
    +	if (gctl_has_param(req, "algo"))
    +		reqalgo = gctl_get_ascii(req, "algo");
    +	else
    +		reqalgo = algo;
    +
    +	snprintf(name, sizeof(name), "gsched_%s", reqalgo);
    +	/*
    +	 * Do not complain about errors here, gctl_issue()
    +	 * will fail anyway.
    +	 */
    +	if (modfind(name) < 0)
    +		kldload(name);
    +	gctl_issue(req);
    +}
    +
    +struct g_command class_commands[] = {
    +	{ "create", G_FLAG_VERBOSE | G_FLAG_LOADKLD, gcmd_createinsert,
    +	    {
    +		{ 'a', "algo", algo, G_TYPE_STRING },
    +		G_OPT_SENTINEL
    +	    },
    +	    G_ARGNAME "[-v] [-a algorithm_name] dev ..."
    +	},
    +	{ "insert", G_FLAG_VERBOSE | G_FLAG_LOADKLD, gcmd_createinsert,
    +	    {
    +		{ 'a', "algo", algo, G_TYPE_STRING },
    +		G_OPT_SENTINEL
    +	    },
    +	    G_ARGNAME "[-v] [-a algorithm_name] dev ..."
    +	},
    +	{ "configure", G_FLAG_VERBOSE, NULL,
    +	    {
    +		{ 'a', "algo", algo, G_TYPE_STRING },
    +		G_OPT_SENTINEL
    +	    },
    +	    G_ARGNAME "[-v] [-a algorithm_name] prov ..."
    +	},
    +	{ "destroy", G_FLAG_VERBOSE, NULL,
    +	    {
    +		{ 'f', "force", NULL, G_TYPE_BOOL },
    +		G_OPT_SENTINEL
    +	    },
    +	    G_ARGNAME "[-fv] prov ..."
    +	},
    +	{ "reset", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
    +	    G_ARGNAME "[-v] prov ..."
    +	},
    +	G_CMD_SENTINEL
    +};
    diff --git a/sbin/geom/class/sched/gsched.8 b/sbin/geom/class/sched/gsched.8
    new file mode 100644
    index 00000000000..cde948559f4
    --- /dev/null
    +++ b/sbin/geom/class/sched/gsched.8
    @@ -0,0 +1,163 @@
    +.\" Copyright (c) 2009-2010 Fabio Checconi
    +.\" Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
    +.\" 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 AUTHORS 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 AUTHORS 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 April 12, 2010
    +.Dt GSCHED 8
    +.Os
    +.Sh NAME
    +.Nm gsched
    +.Nd "control utility for disk scheduler GEOM class"
    +.Sh SYNOPSIS
    +.Nm
    +.Cm create
    +.Op Fl v
    +.Op Fl a Ar algorithm
    +.Ar provider ...
    +.Nm
    +.Cm insert
    +.Op Fl v
    +.Op Fl a Ar algorithm
    +.Ar provider ...
    +.Nm
    +.Cm configure
    +.Op Fl v
    +.Op Fl a Ar algorithm
    +.Ar node ...
    +.Nm
    +.Cm destroy
    +.Op Fl fv
    +.Ar node ...
    +.Nm
    +.Cm reset
    +.Op Fl v
    +.Ar node ...
    +.Nm
    +.Cm { list | status | load | unload }
    +.Sh DESCRIPTION
    +The
    +.Nm
    +utility (also callable as
    +.Nm geom sched ... )
    +changes the scheduling policy of the requests going to a provider.
    +.Pp
    +The first argument to
    +.Nm
    +indicates an action to be performed:
    +.Bl -tag -width ".Cm configure"
    +.It Cm create
    +Create a new provider and geom node using the specified scheduling algorithm.
    +.Ar algorithm
    +is the name of the scheduling algorithm used for the provider.
    +Available algorithms include:
    +.Ar rr ,
    +which implements anticipatory scheduling with round robin service
    +among clients;
    +.Ar as ,
    +which implements a simple form of anticipatory scheduling with
    +no per-client queue.
    +.Pp
    +If the operation succeeds, the new provider should appear with name
    +.Pa /dev/ Ns Ao Ar dev Ac Ns Pa .sched. .
    +The kernel module
    +.Pa geom_sched.ko
    +will be loaded if it is not loaded already.
    +.It Cm insert
    +Operates as "create", but the insertion is "transparent",
    +i.e. the existing provider is rerouted to the newly created geom,
    +which in turn forwards requests to the existing geom.
    +This operation allows one to start/stop a scheduling service
    +on an already existing provider.
    +.Pp
    +A subsequent 'destroy' will remove the newly created geom and
    +hook the provider back to the original geom.
    +.Ar algorithm
    +.It Cm configure
    +Configure existing scheduling provider.  It supports the same options
    +as the 
    +.Nm create
    +command.
    +.It Cm destroy
    +Destroy the geom specified in the parameter.
    +.It Cm reset
    +Do nothing.
    +.It Cm list | status | load | unload
    +See
    +.Xr geom 8 .
    +.El
    +.Pp
    +Additional options:
    +.Bl -tag -width ".Fl f"
    +.It Fl f
    +Force the removal of the specified provider.
    +.It Fl v
    +Be more verbose.
    +.El
    +.Sh SYSCTL VARIABLES
    +The following
    +.Xr sysctl 8
    +variables can be used to control the behavior of the
    +.Nm SCHED
    +GEOM class.
    +The default value is shown next to each variable.
    +.Bl -tag -width indent
    +.It Va kern.geom.sched.debug : No 0
    +Debug level of the
    +.Nm SCHED
    +GEOM class.
    +This can be set to a number between 0 and 2 inclusive.
    +If set to 0 minimal debug information is printed, and if set to 2 the
    +maximum amount of debug information is printed.
    +.El
    +.Sh EXIT STATUS
    +Exit status is 0 on success, and 1 if the command fails.
    +.Sh EXAMPLES
    +The following example shows how to create a scheduling provider for disk
    +.Pa /dev/da0
    +, and how to destroy it.
    +.Bd -literal -offset indent
    +# Load the geom_sched module:
    +kldload geom_sched
    +# Load some scheduler classes used by geom_sched:
    +kldload gsched_rr gsched_as
    +# Configure device ad0 to use scheduler 'rr':
    +geom sched insert -s rr ad0
    +# Now provider ad0 uses the 'rr' algorithm;
    +# the new geom is ad0.sched.
    +# Remove the scheduler on the device:
    +geom sched destroy -v ad0.sched.
    +.Ed
    +.Pp
    +.Sh SEE ALSO
    +.Xr geom 4 ,
    +.Xr geom 8
    +.Sh HISTORY
    +The
    +.Nm
    +utility appeared in April 2010.
    +.Sh AUTHORS
    +.An Fabio Checconi Aq fabio@FreeBSD.org
    +.An Luigi Rizzo Aq luigi@FreeBSD.org
    diff --git a/sys/geom/sched/README b/sys/geom/sched/README
    new file mode 100644
    index 00000000000..1b52d901162
    --- /dev/null
    +++ b/sys/geom/sched/README
    @@ -0,0 +1,162 @@
    +
    +	--- GEOM BASED DISK SCHEDULERS FOR FREEBSD ---
    +
    +This code contains a framework for GEOM-based disk schedulers and a
    +couple of sample scheduling algorithms that use the framework and
    +implement two forms of "anticipatory scheduling" (see below for more
    +details).
    +
    +As a quick example of what this code can give you, try to run "dd",
    +"tar", or some other program with highly SEQUENTIAL access patterns,
    +together with "cvs", "cvsup", "svn" or other highly RANDOM access patterns
    +(this is not a made-up example: it is pretty common for developers
    +to have one or more apps doing random accesses, and others that do
    +sequential accesses e.g., loading large binaries from disk, checking
    +the integrity of tarballs, watching media streams and so on).
    +
    +These are the results we get on a local machine (AMD BE2400 dual
    +core CPU, SATA 250GB disk):
    +
    +    /mnt is a partition mounted on /dev/ad0s1f
    +
    +    cvs: 	cvs -d /mnt/home/ncvs-local update -Pd /mnt/ports
    +    dd-read:	dd bs=128k of=/dev/null if=/dev/ad0 (or ad0-sched-)
    +    dd-writew	dd bs=128k if=/dev/zero of=/mnt/largefile
    +
    +			NO SCHEDULER		RR SCHEDULER
    +                	dd	cvs		dd	cvs
    +
    +    dd-read only        72 MB/s	----		72 MB/s	---
    +    dd-write only	55 MB/s	---		55 MB/s	---
    +    dd-read+cvs		 6 MB/s	ok    		30 MB/s	ok
    +    dd-write+cvs	55 MB/s slooow		14 MB/s	ok
    +
    +As you can see, when a cvs is running concurrently with dd, the
    +performance drops dramatically, and depending on read or write mode,
    +one of the two is severely penalized.  The use of the RR scheduler
    +in this example makes the dd-reader go much faster when competing
    +with cvs, and lets cvs progress when competing with a writer.
    +
    +To try it out:
    +
    +1. USERS OF FREEBSD 7, PLEASE READ CAREFULLY THE FOLLOWING:
    +
    +    On loading, this module patches one kernel function (g_io_request())
    +    so that I/O requests ("bio's") carry a classification tag, useful
    +    for scheduling purposes.
    +
    +    ON FREEBSD 7, the tag is stored in an existing (though rarely used)
    +    field of the "struct bio", a solution which makes this module
    +    incompatible with other modules using it, such as ZFS and gjournal.
    +    Additionally, g_io_request() is patched in-memory to add a call
    +    to the function that initializes this field (i386/amd64 only;
    +    for other architectures you need to manually patch sys/geom/geom_io.c).
    +    See details in the file g_sched.c.
    +
    +    On FreeBSD 8.0 and above, the above trick is not necessary,
    +    as the struct bio contains dedicated fields for the classifier,
    +    and hooks for request classifiers.
    +
    +    If you don't like the above, don't run this code.
    +
    +2. PLEASE MAKE SURE THAT THE DISK THAT YOU WILL BE USING FOR TESTS
    +   DOES NOT CONTAIN PRECIOUS DATA.
    +    This is experimental code, so we make no guarantees, though
    +    I am routinely using it on my desktop and laptop.
    +
    +3. EXTRACT AND BUILD THE PROGRAMS
    +    A 'make install' in the directory should work (with root privs),
    +    or you can even try the binary modules.
    +    If you want to build the modules yourself, look at the Makefile.
    +
    +4. LOAD THE MODULE, CREATE A GEOM NODE, RUN TESTS
    +
    +    The scheduler's module must be loaded first:
    +
    +      # kldload gsched_rr
    +
    +    substitute with gsched_as to test AS.  Then, supposing that you are
    +    using /dev/ad0 for testing, a scheduler can be attached to it with:
    +
    +      # geom sched insert ad0
    +
    +    The scheduler is inserted transparently in the geom chain, so
    +    mounted partitions and filesystems will keep working, but
    +    now requests will go through the scheduler.
    +
    +    To change scheduler on-the-fly, you can reconfigure the geom:
    +
    +      # geom sched configure -a as ad0.sched.
    +
    +    assuming that gsched_as was loaded previously.
    +
    +5. SCHEDULER REMOVAL
    +
    +    In principle it is possible to remove the scheduler module
    +    even on an active chain by doing
    +
    +	# geom sched destroy ad0.sched.
    +
    +    However, there is some race in the geom subsystem which makes
    +    the removal unsafe if there are active requests on a chain.
    +    So, in order to reduce the risk of data losses, make sure
    +    you don't remove a scheduler from a chain with ongoing transactions.
    +
    +--- NOTES ON THE SCHEDULERS ---
    +
    +The important contribution of this code is the framework to experiment
    +with different scheduling algorithms.  'Anticipatory scheduling'
    +is a very powerful technique based on the following reasoning:
    +
    +    The disk throughput is much better if it serves sequential requests.
    +    If we have a mix of sequential and random requests, and we see a
    +    non-sequential request, do not serve it immediately but instead wait
    +    a little bit (2..5ms) to see if there is another one coming that
    +    the disk can serve more efficiently.
    +
    +There are many details that should be added to make sure that the
    +mechanism is effective with different workloads and systems, to
    +gain a few extra percent in performance, to improve fairness,
    +insulation among processes etc.  A discussion of the vast literature
    +on the subject is beyond the purpose of this short note.
    +
    +--------------------------------------------------------------------------
    +
    +TRANSPARENT INSERT/DELETE
    +
    +geom_sched is an ordinary geom module, however it is convenient
    +to plug it transparently into the geom graph, so that one can
    +enable or disable scheduling on a mounted filesystem, and the
    +names in /etc/fstab do not depend on the presence of the scheduler.
    +
    +To understand how this works in practice, remember that in GEOM
    +we have "providers" and "geom" objects.
    +Say that we want to hook a scheduler on provider "ad0",
    +accessible through pointer 'pp'. Originally, pp is attached to
    +geom "ad0" (same name, different object) accessible through pointer old_gp
    +
    +  BEFORE	---> [ pp    --> old_gp ...]
    +
    +A normal "geom sched create ad0" call would create a new geom node
    +on top of provider ad0/pp, and export a newly created provider
    +("ad0.sched." accessible through pointer newpp).
    +
    +  AFTER create  ---> [ newpp --> gp --> cp ] ---> [ pp    --> old_gp ... ]
    +
    +On top of newpp, a whole tree will be created automatically, and we
    +can e.g. mount partitions on /dev/ad0.sched.s1d, and those requests
    +will go through the scheduler, whereas any partition mounted on
    +the pre-existing device entries will not go through the scheduler.
    +
    +With the transparent insert mechanism, the original provider "ad0"/pp
    +is hooked to the newly created geom, as follows:
    +
    +  AFTER insert  ---> [ pp    --> gp --> cp ] ---> [ newpp --> old_gp ... ]
    +
    +so anything that was previously using provider pp will now have
    +the requests routed through the scheduler node.
    +
    +A removal ("geom sched destroy ad0.sched.") will restore the original
    +configuration.
    +
    +# $FreeBSD$
    diff --git a/sys/geom/sched/g_sched.c b/sys/geom/sched/g_sched.c
    new file mode 100644
    index 00000000000..8b0e68ac44a
    --- /dev/null
    +++ b/sys/geom/sched/g_sched.c
    @@ -0,0 +1,1902 @@
    +/*-
    + * Copyright (c) 2009-2010 Fabio Checconi
    + * Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
    + * 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 AUTHORS 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 AUTHORS 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.
    + */
    +
    +/*
    + * $Id$
    + * $FreeBSD$
    + *
    + * Main control module for geom-based disk schedulers ('sched').
    + *
    + * USER VIEW
    + * A 'sched' node is typically inserted transparently between
    + * an existing provider pp and its original geom gp
    + *
    + *	[pp --> gp  ..]
    + *
    + * using the command "geom sched insert " and
    + * resulting in the following topology
    + *
    + *	[pp --> sched_gp --> cp]   [new_pp --> gp ... ]
    + *
    + * Deletion "geom sched destroy .sched." restores the
    + * original chain. The normal "geom sched create "
    + * is also supported.
    + *
    + * INTERNALS
    + * Internally, the 'sched' uses the following data structures
    + *
    + *   geom{}         g_sched_softc{}      g_gsched{}
    + * +----------+    +---------------+   +-------------+
    + * |  softc *-|--->| sc_gsched   *-|-->|  gs_init    |
    + * |  ...     |    |               |   |  gs_fini    |
    + * |          |    | [ hash table] |   |  gs_start   |
    + * +----------+    |               |   |  ...        |
    + *                 |               |   +-------------+
    + *                 |               |
    + *                 |               |     g_*_softc{}
    + *                 |               |   +-------------+
    + *                 | sc_data     *-|-->|             |
    + *                 +---------------+   |  algorithm- |
    + *                                     |  specific   |
    + *                                     +-------------+
    + *
    + * A g_sched_softc{} is created with a "geom sched insert" call.
    + * In turn this instantiates a specific scheduling algorithm,
    + * which sets sc_gsched to point to the algorithm callbacks,
    + * and calls gs_init() to create the g_*_softc{} .
    + * The other callbacks (gs_start, gs_next, ...) are invoked
    + * as needed 
    + *
    + * g_sched_softc{} is defined in g_sched.h and mostly used here;
    + * g_gsched{}, and the gs_callbacks, are documented in gs_scheduler.h;
    + * g_*_softc{} is defined/implemented by each algorithm (gs_*.c)
    + *
    + * DATA MOVING
    + * When a bio is received on the provider, it goes to the
    + * g_sched_start() which calls gs_start() to initially queue it;
    + * then we call g_sched_dispatch() that loops around gs_next()
    + * to select zero or more bio's to be sent downstream.
    + *
    + * g_sched_dispatch() can also be called as a result of a timeout,
    + * e.g. when doing anticipation or pacing requests.
    + *
    + * When a bio comes back, it goes to g_sched_done() which in turn
    + * calls gs_done(). The latter does any necessary housekeeping in
    + * the scheduling algorithm, and may decide to call g_sched_dispatch()
    + * to send more bio's downstream.
    + *
    + * If an algorithm needs per-flow queues, these are created
    + * calling gs_init_class() and destroyed with gs_fini_class(),
    + * and they are also inserted in the hash table implemented in
    + * the g_sched_softc{}
    + *
    + * If an algorithm is replaced, or a transparently-inserted node is
    + * removed with "geom sched destroy", we need to remove all references
    + * to the g_*_softc{} and g_sched_softc from the bio's still in
    + * the scheduler. g_sched_forced_dispatch() helps doing this.
    + * XXX need to explain better.
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 		/* we access curthread */
    +#include 
    +#include "gs_scheduler.h"
    +#include "g_sched.h"		/* geom hooks */
    +
    +/*
    + * Size of the per-geom hash table storing traffic classes.
    + * We may decide to change it at a later time, it has no ABI
    + * implications as it is only used for run-time allocations.
    + */
    +#define G_SCHED_HASH_SIZE	32
    +
    +static int g_sched_destroy(struct g_geom *gp, boolean_t force);
    +static int g_sched_destroy_geom(struct gctl_req *req,
    +    struct g_class *mp, struct g_geom *gp);
    +static void g_sched_config(struct gctl_req *req, struct g_class *mp,
    +    const char *verb);
    +static struct g_geom *g_sched_taste(struct g_class *mp,
    +    struct g_provider *pp, int flags __unused);
    +static void g_sched_dumpconf(struct sbuf *sb, const char *indent,
    +    struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp);
    +static void g_sched_init(struct g_class *mp);
    +static void g_sched_fini(struct g_class *mp);
    +
    +struct g_class g_sched_class = {
    +	.name = G_SCHED_CLASS_NAME,
    +	.version = G_VERSION,
    +	.ctlreq = g_sched_config,
    +	.taste = g_sched_taste,
    +	.destroy_geom = g_sched_destroy_geom,
    +	.init = g_sched_init,
    +	.fini = g_sched_fini
    +};
    +
    +MALLOC_DEFINE(M_GEOM_SCHED, "GEOM_SCHED", "Geom schedulers data structures");
    +
    +/*
    + * Global variables describing the state of the geom_sched module.
    + * There is only one static instance of this structure.
    + */
    +LIST_HEAD(gs_list, g_gsched);	/* type, link field */
    +struct geom_sched_vars {
    +	struct mtx	gs_mtx;
    +	struct gs_list	gs_scheds;	/* list of algorithms */
    +	u_int		gs_debug;
    +	u_int		gs_sched_count;	/* how many algorithms ? */
    +	u_int 		gs_patched;	/* g_io_request was patched */
    +
    +	u_int		gs_initialized;
    +	u_int		gs_expire_secs;	/* expiration of hash entries */
    +
    +	struct bio_queue_head gs_pending;
    +	u_int		gs_npending;
    +
    +	/* The following are for stats, usually protected by gs_mtx. */
    +	u_long		gs_requests;	/* total requests */
    +	u_long		gs_done;	/* total done */
    +	u_int 		gs_in_flight;	/* requests in flight */
    +	u_int 		gs_writes_in_flight;
    +	u_int 		gs_bytes_in_flight;
    +	u_int 		gs_write_bytes_in_flight;
    +
    +	char		gs_names[256];	/* names of schedulers */
    +};
    +
    +static struct geom_sched_vars me = {
    +	.gs_expire_secs = 10,
    +};
    +
    +SYSCTL_DECL(_kern_geom);
    +SYSCTL_NODE(_kern_geom, OID_AUTO, sched, CTLFLAG_RW, 0,
    +    "GEOM_SCHED stuff");
    +
    +SYSCTL_INT(_kern_geom_sched, OID_AUTO, in_flight_wb, CTLFLAG_RD,
    +    &me.gs_write_bytes_in_flight, 0, "Write bytes in flight");
    +
    +SYSCTL_INT(_kern_geom_sched, OID_AUTO, in_flight_b, CTLFLAG_RD,
    +    &me.gs_bytes_in_flight, 0, "Bytes in flight");
    +
    +SYSCTL_UINT(_kern_geom_sched, OID_AUTO, in_flight_w, CTLFLAG_RD,
    +    &me.gs_writes_in_flight, 0, "Write Requests in flight");
    +
    +SYSCTL_UINT(_kern_geom_sched, OID_AUTO, in_flight, CTLFLAG_RD,
    +    &me.gs_in_flight, 0, "Requests in flight");
    +
    +SYSCTL_ULONG(_kern_geom_sched, OID_AUTO, done, CTLFLAG_RD,
    +    &me.gs_done, 0, "Total done");
    +
    +SYSCTL_ULONG(_kern_geom_sched, OID_AUTO, requests, CTLFLAG_RD,
    +    &me.gs_requests, 0, "Total requests");
    +
    +SYSCTL_STRING(_kern_geom_sched, OID_AUTO, algorithms, CTLFLAG_RD,
    +    &me.gs_names, 0, "Algorithm names");
    +
    +SYSCTL_UINT(_kern_geom_sched, OID_AUTO, alg_count, CTLFLAG_RD,
    +    &me.gs_sched_count, 0, "Number of algorithms");
    +
    +SYSCTL_UINT(_kern_geom_sched, OID_AUTO, debug, CTLFLAG_RW,
    +    &me.gs_debug, 0, "Debug level");
    +
    +SYSCTL_UINT(_kern_geom_sched, OID_AUTO, expire_secs, CTLFLAG_RW,
    +    &me.gs_expire_secs, 0, "Expire time in seconds");
    +
    +/*
    + * g_sched calls the scheduler algorithms with this lock held.
    + * The locking functions are exposed so the scheduler algorithms can also
    + * protect themselves e.g. when running a callout handler.
    + */
    +void
    +g_sched_lock(struct g_geom *gp)
    +{
    +	struct g_sched_softc *sc = gp->softc;
    +
    +	mtx_lock(&sc->sc_mtx);
    +}
    +
    +void
    +g_sched_unlock(struct g_geom *gp)
    +{
    +	struct g_sched_softc *sc = gp->softc;
    +
    +	mtx_unlock(&sc->sc_mtx);
    +}
    +
    +/*
    + * Support functions to handle references to the module,
    + * which are coming from devices using this scheduler.
    + */
    +static inline void
    +g_gsched_ref(struct g_gsched *gsp)
    +{
    +
    +	atomic_add_int(&gsp->gs_refs, 1);
    +}
    +
    +static inline void
    +g_gsched_unref(struct g_gsched *gsp)
    +{
    +
    +	atomic_add_int(&gsp->gs_refs, -1);
    +}
    +
    +/*
    + * Update the stats when this request is done.
    + */
    +static void
    +g_sched_update_stats(struct bio *bio)
    +{
    +
    +	me.gs_done++;
    +	me.gs_in_flight--;
    +	me.gs_bytes_in_flight -= bio->bio_length;
    +	if (bio->bio_cmd & BIO_WRITE) {
    +		me.gs_writes_in_flight--;
    +		me.gs_write_bytes_in_flight -= bio->bio_length;
    +	}
    +}
    +
    +/*
    + * Dispatch any pending request.
    + */
    +static void
    +g_sched_forced_dispatch(struct g_geom *gp)
    +{
    +	struct g_sched_softc *sc = gp->softc;
    +	struct g_gsched *gsp = sc->sc_gsched;
    +	struct bio *bp;
    +
    +	KASSERT(mtx_owned(&sc->sc_mtx),
    +	    ("sc_mtx not owned during forced dispatch"));
    +
    +	while ((bp = gsp->gs_next(sc->sc_data, 1)) != NULL)
    +		g_io_request(bp, LIST_FIRST(&gp->consumer));
    +}
    +
    +/*
    + * The main dispatch loop, called either here after the start
    + * routine, or by scheduling algorithms when they receive a timeout
    + * or a 'done' notification.  Does not share code with the forced
    + * dispatch path, since the gs_done() callback can call us.
    + */
    +void
    +g_sched_dispatch(struct g_geom *gp)
    +{
    +	struct g_sched_softc *sc = gp->softc;
    +	struct g_gsched *gsp = sc->sc_gsched;
    +	struct bio *bp;
    +
    +	KASSERT(mtx_owned(&sc->sc_mtx), ("sc_mtx not owned during dispatch"));
    +
    +	if ((sc->sc_flags & G_SCHED_FLUSHING))
    +		return;
    +
    +	while ((bp = gsp->gs_next(sc->sc_data, 0)) != NULL)
    +		g_io_request(bp, LIST_FIRST(&gp->consumer));
    +}
    +
    +/*
    + * Recent (8.0 and above) versions of FreeBSD have support to
    + * register classifiers of disk requests. The classifier is
    + * invoked by g_io_request(), and stores the information into
    + * bp->bio_classifier1.
    + *
    + * Support for older versions, which is left here only for
    + * documentation purposes, relies on two hacks:
    + * 1. classification info is written into the bio_caller1
    + *    field of the topmost node in the bio chain. This field
    + *    is rarely used, but this module is incompatible with
    + *    those that use bio_caller1 for other purposes,
    + *    such as ZFS and gjournal;
    + * 2. g_io_request() is patched in-memory when the module is
    + *    loaded, so that the function calls a classifier as its
    + *    first thing. g_io_request() is restored when the module
    + *    is unloaded. This functionality is only supported for
    + *    x86 and amd64, other architectures need source code changes.
    + */
    +
    +/*
    + * Lookup the identity of the issuer of the original request.
    + * In the current implementation we use the curthread of the
    + * issuer, but different mechanisms may be implemented later
    + * so we do not make assumptions on the return value which for
    + * us is just an opaque identifier.
    + */
    +
    +static inline u_long
    +g_sched_classify(struct bio *bp)
    +{
    +
    +#if __FreeBSD_version > 800098
    +	/* we have classifier fields in the struct bio */
    +#define HAVE_BIO_CLASSIFIER
    +	return ((u_long)bp->bio_classifier1);
    +#else
    +#warning old version!!!
    +	while (bp->bio_parent != NULL)
    +		bp = bp->bio_parent;
    +
    +	return ((u_long)bp->bio_caller1);
    +#endif
    +}
    +
    +/* Return the hash chain for the given key. */
    +static inline struct g_hash *
    +g_sched_hash(struct g_sched_softc *sc, u_long key)
    +{
    +
    +	return (&sc->sc_hash[key & sc->sc_mask]);
    +}
    +
    +/*
    + * Helper function for the children classes, which takes
    + * a geom and a bio and returns the private descriptor
    + * associated to the request.  This involves fetching
    + * the classification field and [al]locating the
    + * corresponding entry in the hash table.
    + */
    +void *
    +g_sched_get_class(struct g_geom *gp, struct bio *bp)
    +{
    +	struct g_sched_softc *sc;
    +	struct g_sched_class *gsc;
    +	struct g_gsched *gsp;
    +	struct g_hash *bucket;
    +	u_long key;
    +
    +	sc = gp->softc;
    +	key = g_sched_classify(bp);
    +	bucket = g_sched_hash(sc, key);
    +	LIST_FOREACH(gsc, bucket, gsc_clist) {
    +		if (key == gsc->gsc_key) {
    +			gsc->gsc_refs++;
    +			return (gsc->gsc_priv);
    +		}
    +	}
    +
    +	gsp = sc->sc_gsched;
    +	gsc = malloc(sizeof(*gsc) + gsp->gs_priv_size,
    +	    M_GEOM_SCHED, M_NOWAIT | M_ZERO);
    +	if (!gsc)
    +		return (NULL);
    +
    +	if (gsp->gs_init_class(sc->sc_data, gsc->gsc_priv)) {
    +		free(gsc, M_GEOM_SCHED);
    +		return (NULL);
    +	}
    +
    +	gsc->gsc_refs = 2;	/* 1 for the hash table, 1 for the caller. */
    +	gsc->gsc_key = key;
    +	LIST_INSERT_HEAD(bucket, gsc, gsc_clist);
    +
    +	gsc->gsc_expire = ticks + me.gs_expire_secs * hz;
    +
    +	return (gsc->gsc_priv);
    +}
    +
    +/*
    + * Release a reference to the per-client descriptor,
    + */
    +void
    +g_sched_put_class(struct g_geom *gp, void *priv)
    +{
    +	struct g_sched_class *gsc;
    +	struct g_sched_softc *sc;
    +
    +	gsc = g_sched_priv2class(priv);
    +	gsc->gsc_expire = ticks + me.gs_expire_secs * hz;
    +
    +	if (--gsc->gsc_refs > 0)
    +		return;
    +
    +	sc = gp->softc;
    +	sc->sc_gsched->gs_fini_class(sc->sc_data, priv);
    +
    +	LIST_REMOVE(gsc, gsc_clist);
    +	free(gsc, M_GEOM_SCHED);
    +}
    +
    +static void
    +g_sched_hash_fini(struct g_geom *gp, struct g_hash *hp, u_long mask,
    +    struct g_gsched *gsp, void *data)
    +{
    +	struct g_sched_class *cp, *cp2;
    +	int i;
    +
    +	if (!hp)
    +		return;
    +
    +	if (data && gsp->gs_hash_unref)
    +		gsp->gs_hash_unref(data);
    +
    +	for (i = 0; i < G_SCHED_HASH_SIZE; i++) {
    +		LIST_FOREACH_SAFE(cp, &hp[i], gsc_clist, cp2)
    +			g_sched_put_class(gp, cp->gsc_priv);
    +	}
    +
    +	hashdestroy(hp, M_GEOM_SCHED, mask);
    +}
    +
    +static struct g_hash *
    +g_sched_hash_init(struct g_gsched *gsp, u_long *mask, int flags)
    +{
    +	struct g_hash *hash;
    +
    +	if (gsp->gs_priv_size == 0)
    +		return (NULL);
    +
    +	hash = hashinit_flags(G_SCHED_HASH_SIZE, M_GEOM_SCHED, mask, flags);
    +
    +	return (hash);
    +}
    +
    +static void
    +g_sched_flush_classes(struct g_geom *gp)
    +{
    +	struct g_sched_softc *sc;
    +	struct g_sched_class *cp, *cp2;
    +	int i;
    +
    +	sc = gp->softc;
    +
    +	if (!sc->sc_hash || ticks - sc->sc_flush_ticks <= 0)
    +		return;
    +
    +	for (i = 0; i < G_SCHED_HASH_SIZE; i++) {
    +		LIST_FOREACH_SAFE(cp, &sc->sc_hash[i], gsc_clist, cp2) {
    +			if (cp->gsc_refs == 1 && ticks - cp->gsc_expire > 0)
    +				g_sched_put_class(gp, cp->gsc_priv);
    +		}
    +	}
    +
    +	sc->sc_flush_ticks = ticks + me.gs_expire_secs * hz;
    +}
    +
    +/*
    + * Wait for the completion of any outstanding request.  To ensure
    + * that this does not take forever the caller has to make sure that
    + * no new request enter the scehduler before calling us.
    + *
    + * Must be called with the gp mutex held and topology locked.
    + */
    +static int
    +g_sched_wait_pending(struct g_geom *gp)
    +{
    +	struct g_sched_softc *sc = gp->softc;
    +	int endticks = ticks + hz;
    +
    +	g_topology_assert();
    +
    +	while (sc->sc_pending && endticks - ticks >= 0)
    +		msleep(gp, &sc->sc_mtx, 0, "sched_wait_pending", hz / 4);
    +
    +	return (sc->sc_pending ? ETIMEDOUT : 0);
    +}
    +
    +static int
    +g_sched_remove_locked(struct g_geom *gp, struct g_gsched *gsp)
    +{
    +	struct g_sched_softc *sc = gp->softc;
    +	int error;
    +
    +	/* Set the flushing flag: new bios will not enter the scheduler. */
    +	sc->sc_flags |= G_SCHED_FLUSHING;
    +
    +	g_sched_forced_dispatch(gp);
    +	error = g_sched_wait_pending(gp);
    +	if (error)
    +		goto failed;
    +	
    +	/* No more requests pending or in flight from the old gsp. */
    +
    +	g_sched_hash_fini(gp, sc->sc_hash, sc->sc_mask, gsp, sc->sc_data);
    +	sc->sc_hash = NULL;
    +
    +	/*
    +	 * Avoid deadlock here by releasing the gp mutex and reacquiring
    +	 * it once done.  It should be safe, since no reconfiguration or
    +	 * destruction can take place due to the geom topology lock; no
    +	 * new request can use the current sc_data since we flagged the
    +	 * geom as being flushed.
    +	 */
    +	g_sched_unlock(gp);
    +	gsp->gs_fini(sc->sc_data);
    +	g_sched_lock(gp);
    +
    +	sc->sc_gsched = NULL;
    +	sc->sc_data = NULL;
    +	g_gsched_unref(gsp);
    +
    +failed:
    +	sc->sc_flags &= ~G_SCHED_FLUSHING;
    +
    +	return (error);
    +}
    +
    +static int
    +g_sched_remove(struct g_geom *gp, struct g_gsched *gsp)
    +{
    +	int error;
    +
    +	g_sched_lock(gp);
    +	error = g_sched_remove_locked(gp, gsp); /* gsp is surely non-null */
    +	g_sched_unlock(gp);
    +
    +	return (error);
    +}
    +
    +/*
    + * Support function for create/taste -- locate the desired
    + * algorithm and grab a reference to it.
    + */
    +static struct g_gsched *
    +g_gsched_find(const char *name)
    +{
    +	struct g_gsched *gsp = NULL;
    +
    +	mtx_lock(&me.gs_mtx);
    +	LIST_FOREACH(gsp, &me.gs_scheds, glist) {
    +		if (strcmp(name, gsp->gs_name) == 0) {
    +			g_gsched_ref(gsp);
    +			break;
    +		}
    +	}
    +	mtx_unlock(&me.gs_mtx);
    +
    +	return (gsp);
    +}
    +
    +/*
    + * Rebuild the list of scheduler names.
    + * To be called with me.gs_mtx lock held.
    + */
    +static void
    +g_gsched_build_names(struct g_gsched *gsp)
    +{
    +	int pos, l;
    +	struct g_gsched *cur;
    +
    +	pos = 0;
    +	LIST_FOREACH(cur, &me.gs_scheds, glist) {
    +		l = strlen(cur->gs_name);
    +		if (l + pos + 1 + 1 < sizeof(me.gs_names)) {
    +			if (pos != 0)
    +				me.gs_names[pos++] = ' ';
    +			strcpy(me.gs_names + pos, cur->gs_name);
    +			pos += l;
    +		}
    +	}
    +	me.gs_names[pos] = '\0';
    +}
    +
    +/*
    + * Register or unregister individual scheduling algorithms.
    + */
    +static int
    +g_gsched_register(struct g_gsched *gsp)
    +{
    +	struct g_gsched *cur;
    +	int error = 0;
    +
    +	mtx_lock(&me.gs_mtx);
    +	LIST_FOREACH(cur, &me.gs_scheds, glist) {
    +		if (strcmp(gsp->gs_name, cur->gs_name) == 0)
    +			break;
    +	}
    +	if (cur != NULL) {
    +		G_SCHED_DEBUG(0, "A scheduler named %s already"
    +		    "exists.", gsp->gs_name);
    +		error = EEXIST;
    +	} else {
    +		LIST_INSERT_HEAD(&me.gs_scheds, gsp, glist);
    +		gsp->gs_refs = 1;
    +		me.gs_sched_count++;
    +		g_gsched_build_names(gsp);
    +	}
    +	mtx_unlock(&me.gs_mtx);
    +
    +	return (error);
    +}
    +
    +struct g_gsched_unregparm {
    +	struct g_gsched *gup_gsp;
    +	int		gup_error;
    +};
    +
    +static void
    +g_gsched_unregister(void *arg, int flag)
    +{
    +	struct g_gsched_unregparm *parm = arg;
    +	struct g_gsched *gsp = parm->gup_gsp, *cur, *tmp;
    +	struct g_sched_softc *sc;
    +	struct g_geom *gp, *gp_tmp;
    +	int error;
    +
    +	parm->gup_error = 0;
    +
    +	g_topology_assert();
    +
    +	if (flag == EV_CANCEL)
    +		return;
    +
    +	mtx_lock(&me.gs_mtx);
    +
    +	LIST_FOREACH_SAFE(gp, &g_sched_class.geom, geom, gp_tmp) {
    +		if (gp->class != &g_sched_class)
    +			continue;	/* Should not happen. */
    +
    +		sc = gp->softc;
    +		if (sc->sc_gsched == gsp) {
    +			error = g_sched_remove(gp, gsp);
    +			if (error)
    +				goto failed;
    +		}
    +	}
    +		
    +	LIST_FOREACH_SAFE(cur, &me.gs_scheds, glist, tmp) {
    +		if (cur != gsp)
    +			continue;
    +
    +		if (gsp->gs_refs != 1) {
    +			G_SCHED_DEBUG(0, "%s still in use.",
    +			    gsp->gs_name);
    +			parm->gup_error = EBUSY;
    +		} else {
    +			LIST_REMOVE(gsp, glist);
    +			me.gs_sched_count--;
    +			g_gsched_build_names(gsp);
    +		}
    +		break;
    +	}
    +
    +	if (cur == NULL) {
    +		G_SCHED_DEBUG(0, "%s not registered.", gsp->gs_name);
    +		parm->gup_error = ENOENT;
    +	}
    +
    +failed:
    +	mtx_unlock(&me.gs_mtx);
    +}
    +
    +static inline void
    +g_gsched_global_init(void)
    +{
    +
    +	if (!me.gs_initialized) {
    +		G_SCHED_DEBUG(0, "Initializing global data.");
    +		mtx_init(&me.gs_mtx, "gsched", NULL, MTX_DEF);
    +		LIST_INIT(&me.gs_scheds);
    +		gs_bioq_init(&me.gs_pending);
    +		me.gs_initialized = 1;
    +	}
    +}
    +
    +/*
    + * Module event called when a scheduling algorithm module is loaded or
    + * unloaded.
    + */
    +int
    +g_gsched_modevent(module_t mod, int cmd, void *arg)
    +{
    +	struct g_gsched *gsp = arg;
    +	struct g_gsched_unregparm parm;
    +	int error;
    +
    +	G_SCHED_DEBUG(0, "Modevent %d.", cmd);
    +
    +	/*
    +	 * If the module is loaded at boot, the geom thread that calls
    +	 * g_sched_init() might actually run after g_gsched_modevent(),
    +	 * so make sure that the module is properly initialized.
    +	 */
    +	g_gsched_global_init();
    +
    +	error = EOPNOTSUPP;
    +	switch (cmd) {
    +	case MOD_LOAD:
    +		error = g_gsched_register(gsp);
    +		G_SCHED_DEBUG(0, "Loaded module %s error %d.",
    +		    gsp->gs_name, error);
    +		if (error == 0)
    +			g_retaste(&g_sched_class);
    +		break;
    +
    +	case MOD_UNLOAD:
    +		parm.gup_gsp = gsp;
    +		parm.gup_error = 0;
    +
    +		error = g_waitfor_event(g_gsched_unregister,
    +		    &parm, M_WAITOK, NULL);
    +		if (error == 0)
    +			error = parm.gup_error;
    +		G_SCHED_DEBUG(0, "Unloaded module %s error %d.",
    +		    gsp->gs_name, error);
    +		break;
    +	};
    +
    +	return (error);
    +}
    +
    +#ifdef KTR
    +#define	TRC_BIO_EVENT(e, bp)	g_sched_trace_bio_ ## e (bp)
    +static inline int
    +g_sched_issuer_pid(struct bio *bp)
    +{
    +	struct thread *thread = g_sched_issuer(bp);
    +
    +	return (thread->td_tid);
    +}
    +
    +static inline char
    +g_sched_type(struct bio *bp)
    +{
    +
    +	if (0 != (bp->bio_cmd & BIO_READ))
    +		return ('R');
    +	else if (0 != (bp->bio_cmd & BIO_WRITE))
    +		return ('W');
    +	return ('U');
    +}
    +
    +static inline void
    +g_sched_trace_bio_START(struct bio *bp)
    +{
    +
    +	CTR5(KTR_GSCHED, "S %d %c %lu/%lu %lu", g_sched_issuer_pid(bp),
    +	    g_sched_type(bp), bp->bio_offset / ULONG_MAX,
    +	    bp->bio_offset, bp->bio_length);
    +}
    +
    +static inline void
    +g_sched_trace_bio_DONE(struct bio *bp)
    +{
    +
    +	CTR5(KTR_GSCHED, "D %d %c %lu/%lu %lu", g_sched_issuer_pid(bp),
    +	    g_sched_type(bp), bp->bio_offset / ULONG_MAX,
    +	    bp->bio_offset, bp->bio_length);
    +}
    +#else
    +#define	TRC_BIO_EVENT(e, bp)
    +#endif
    +
    +/*
    + * g_sched_done() and g_sched_start() dispatch the geom requests to
    + * the scheduling algorithm in use.
    + */
    +static void
    +g_sched_done(struct bio *bio)
    +{
    +	struct g_geom *gp = bio->bio_caller2;
    +	struct g_sched_softc *sc = gp->softc;
    +
    +	TRC_BIO_EVENT(DONE, bio);
    +
    +	KASSERT(bio->bio_caller1, ("null bio_caller1 in g_sched_done"));
    +
    +	g_sched_lock(gp);
    +
    +	g_sched_update_stats(bio);
    +	sc->sc_gsched->gs_done(sc->sc_data, bio);
    +	if (!--sc->sc_pending)
    +		wakeup(gp);
    +
    +	g_sched_flush_classes(gp);
    +	g_sched_unlock(gp);
    +
    +	g_std_done(bio);
    +}
    +
    +static void
    +g_sched_start(struct bio *bp)
    +{
    +	struct g_geom *gp = bp->bio_to->geom;
    +	struct g_sched_softc *sc = gp->softc;
    +	struct bio *cbp;
    +
    +	TRC_BIO_EVENT(START, bp);
    +	G_SCHED_LOGREQ(bp, "Request received.");
    +
    +	cbp = g_clone_bio(bp);
    +	if (cbp == NULL) {
    +		g_io_deliver(bp, ENOMEM);
    +		return;
    +	}
    +	cbp->bio_done = g_sched_done;
    +	cbp->bio_to = LIST_FIRST(&gp->provider);
    +	KASSERT(cbp->bio_to != NULL, ("NULL provider"));
    +
    +	/* We only schedule reads and writes. */
    +	if (0 == (bp->bio_cmd & (BIO_READ | BIO_WRITE)))
    +		goto bypass;
    +
    +	G_SCHED_LOGREQ(cbp, "Sending request.");
    +
    +	g_sched_lock(gp);
    +	/*
    +	 * Call the algorithm's gs_start to queue the request in the
    +	 * scheduler. If gs_start fails then pass the request down,
    +	 * otherwise call g_sched_dispatch() which tries to push
    +	 * one or more requests down.
    +	 */
    +	if (!sc->sc_gsched || (sc->sc_flags & G_SCHED_FLUSHING) ||
    +	    sc->sc_gsched->gs_start(sc->sc_data, cbp)) {
    +		g_sched_unlock(gp);
    +		goto bypass;
    +	}
    +	/*
    +	 * We use bio_caller1 to mark requests that are scheduled
    +	 * so make sure it is not NULL.
    +	 */
    +	if (cbp->bio_caller1 == NULL)
    +		cbp->bio_caller1 = &me;	/* anything not NULL */
    +
    +	cbp->bio_caller2 = gp;
    +	sc->sc_pending++;
    +
    +	/* Update general stats. */
    +	me.gs_in_flight++;
    +	me.gs_requests++;
    +	me.gs_bytes_in_flight += bp->bio_length;
    +	if (bp->bio_cmd & BIO_WRITE) {
    +		me.gs_writes_in_flight++;
    +		me.gs_write_bytes_in_flight += bp->bio_length;
    +	}
    +	g_sched_dispatch(gp);
    +	g_sched_unlock(gp);
    +	return;
    +
    +bypass:
    +	cbp->bio_done = g_std_done;
    +	cbp->bio_caller1 = NULL; /* not scheduled */
    +	g_io_request(cbp, LIST_FIRST(&gp->consumer));
    +}
    +
    +/*
    + * The next few functions are the geom glue.
    + */
    +static void
    +g_sched_orphan(struct g_consumer *cp)
    +{
    +
    +	g_topology_assert();
    +	g_sched_destroy(cp->geom, 1);
    +}
    +
    +static int
    +g_sched_access(struct g_provider *pp, int dr, int dw, int de)
    +{
    +	struct g_geom *gp;
    +	struct g_consumer *cp;
    +	int error;
    +
    +	gp = pp->geom;
    +	cp = LIST_FIRST(&gp->consumer);
    +	error = g_access(cp, dr, dw, de);
    +
    +	return (error);
    +}
    +
    +static void
    +g_sched_temporary_start(struct bio *bio)
    +{
    +
    +	mtx_lock(&me.gs_mtx);
    +	me.gs_npending++;
    +	gs_bioq_disksort(&me.gs_pending, bio);
    +	mtx_unlock(&me.gs_mtx);
    +}
    +
    +static void
    +g_sched_flush_pending(g_start_t *start)
    +{
    +	struct bio *bp;
    +
    +	while ((bp = gs_bioq_takefirst(&me.gs_pending)))
    +		start(bp);
    +}
    +
    +static int
    +g_insert_proxy(struct g_geom *gp, struct g_provider *newpp,
    +    struct g_geom *dstgp, struct g_provider *pp, struct g_consumer *cp)
    +{
    +	struct g_sched_softc *sc = gp->softc;
    +	g_start_t *saved_start, *flush = g_sched_start;
    +	int error = 0, endticks = ticks + hz;
    +
    +	g_cancel_event(newpp);	/* prevent taste() */
    +	/* copy private fields */
    +	newpp->private = pp->private;
    +	newpp->index = pp->index;
    +
    +	/* Queue all the early requests coming for us. */
    +	me.gs_npending = 0;
    +	saved_start = pp->geom->start;
    +	dstgp->start = g_sched_temporary_start;
    +
    +	while (pp->nstart - pp->nend != me.gs_npending &&
    +	    endticks - ticks >= 0)
    +		tsleep(pp, PRIBIO, "-", hz/10);
    +
    +	if (pp->nstart - pp->nend != me.gs_npending) {
    +		flush = saved_start;
    +		error = ETIMEDOUT;
    +		goto fail;
    +	}
    +
    +	/* link pp to this geom */
    +	LIST_REMOVE(pp, provider);
    +	pp->geom = gp;
    +	LIST_INSERT_HEAD(&gp->provider, pp, provider);
    +
    +	/*
    +	 * replicate the counts from the parent in the
    +	 * new provider and consumer nodes
    +	 */
    +	cp->acr = newpp->acr = pp->acr;
    +	cp->acw = newpp->acw = pp->acw;
    +	cp->ace = newpp->ace = pp->ace;
    +	sc->sc_flags |= G_SCHED_PROXYING;
    +
    +fail:
    +	dstgp->start = saved_start;
    +
    +	g_sched_flush_pending(flush);
    +
    +	return (error);
    +}
    +
    +/*
    + * Create a geom node for the device passed as *pp.
    + * If successful, add a reference to this gsp.
    + */
    +static int
    +g_sched_create(struct gctl_req *req, struct g_class *mp,
    +    struct g_provider *pp, struct g_gsched *gsp, int proxy)
    +{
    +	struct g_sched_softc *sc = NULL;
    +	struct g_geom *gp, *dstgp;
    +	struct g_provider *newpp = NULL;
    +	struct g_consumer *cp = NULL;
    +	char name[64];
    +	int error;
    +
    +	g_topology_assert();
    +
    +	snprintf(name, sizeof(name), "%s%s", pp->name, G_SCHED_SUFFIX);
    +	LIST_FOREACH(gp, &mp->geom, geom) {
    +		if (strcmp(gp->name, name) == 0) {
    +			gctl_error(req, "Geom %s already exists.",
    +			    name);
    +			return (EEXIST);
    +		}
    +	}
    +
    +	gp = g_new_geomf(mp, name);
    +	dstgp = proxy ? pp->geom : gp; /* where do we link the provider */
    +	if (gp == NULL) {
    +		gctl_error(req, "Cannot create geom %s.", name);
    +		error = ENOMEM;
    +		goto fail;
    +	}
    +
    +	sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO);
    +	sc->sc_gsched = gsp;
    +	sc->sc_data = gsp->gs_init(gp);
    +	if (sc->sc_data == NULL) {
    +		error = ENOMEM;
    +		goto fail;
    +	}
    +
    +	sc->sc_hash = g_sched_hash_init(gsp, &sc->sc_mask, HASH_WAITOK);
    +
    +	/*
    +	 * Do not initialize the flush mechanism, will be initialized
    +	 * on the first insertion on the hash table.
    +	 */
    +
    +	mtx_init(&sc->sc_mtx, "g_sched_mtx", NULL, MTX_DEF);
    +
    +	gp->softc = sc;
    +	gp->start = g_sched_start;
    +	gp->orphan = g_sched_orphan;
    +	gp->access = g_sched_access;
    +	gp->dumpconf = g_sched_dumpconf;
    +
    +	newpp = g_new_providerf(dstgp, gp->name);
    +	if (newpp == NULL) {
    +		gctl_error(req, "Cannot create provider %s.", name);
    +		error = ENOMEM;
    +		goto fail;
    +	}
    +
    +	newpp->mediasize = pp->mediasize;
    +	newpp->sectorsize = pp->sectorsize;
    +
    +	cp = g_new_consumer(gp);
    +	if (cp == NULL) {
    +		gctl_error(req, "Cannot create consumer for %s.",
    +		    gp->name);
    +		error = ENOMEM;
    +		goto fail;
    +	}
    +
    +	error = g_attach(cp, proxy ? newpp : pp);
    +	if (error != 0) {
    +		gctl_error(req, "Cannot attach to provider %s.",
    +		    pp->name);
    +		goto fail;
    +	}
    +
    +	g_error_provider(newpp, 0);
    +	if (proxy) {
    +		error = g_insert_proxy(gp, newpp, dstgp, pp, cp);
    +		if (error)
    +			goto fail;
    +	}
    +	G_SCHED_DEBUG(0, "Device %s created.", gp->name);
    +
    +	g_gsched_ref(gsp);
    +
    +	return (0);
    +
    +fail:
    +	if (cp != NULL) {
    +		if (cp->provider != NULL)
    +			g_detach(cp);
    +		g_destroy_consumer(cp);
    +	}
    +
    +	if (newpp != NULL)
    +		g_destroy_provider(newpp);
    +
    +	if (sc && sc->sc_hash) {
    +		g_sched_hash_fini(gp, sc->sc_hash, sc->sc_mask,
    +		    gsp, sc->sc_data);
    +	}
    +
    +	if (sc && sc->sc_data)
    +		gsp->gs_fini(sc->sc_data);
    +
    +	if (gp != NULL) {
    +		if (gp->softc != NULL)
    +			g_free(gp->softc);
    +		g_destroy_geom(gp);
    +	}
    +
    +	return (error);
    +}
    +
    +/*
    + * Support for dynamic switching of scheduling algorithms.
    + * First initialize the data structures for the new algorithm,
    + * then call g_sched_remove_locked() to flush all references
    + * to the old one, finally link the new algorithm.
    + */
    +static int
    +g_sched_change_algo(struct gctl_req *req, struct g_class *mp,
    +    struct g_provider *pp, struct g_gsched *gsp)
    +{
    +	struct g_sched_softc *sc;
    +	struct g_geom *gp;
    +	struct g_hash *newh;
    +	void *data;
    +	u_long mask;
    +	int error = 0;
    +
    +	gp = pp->geom;
    +	sc = gp->softc;
    +
    +	data = gsp->gs_init(gp);
    +	if (data == NULL)
    +		return (ENOMEM);
    +
    +	newh = g_sched_hash_init(gsp, &mask, HASH_WAITOK);
    +	if (gsp->gs_priv_size && !newh) {
    +		error = ENOMEM;
    +		goto fail;
    +	}
    +
    +	g_sched_lock(gp);
    +	if (sc->sc_gsched) {	/* can be NULL in some cases */
    +		error = g_sched_remove_locked(gp, sc->sc_gsched);
    +		if (error)
    +			goto fail;
    +	}
    +
    +	g_gsched_ref(gsp);
    +	sc->sc_gsched = gsp;
    +	sc->sc_data = data;
    +	sc->sc_hash = newh;
    +	sc->sc_mask = mask;
    +
    +	g_sched_unlock(gp);
    +
    +	return (0);
    +
    +fail:
    +	if (newh)
    +		g_sched_hash_fini(gp, newh, mask, gsp, data);
    +
    +	if (data)
    +		gsp->gs_fini(data);
    +
    +	g_sched_unlock(gp);
    +
    +	return (error);
    +}
    +
    +/*
    + * Stop the request flow directed to the proxy, redirecting the new
    + * requests to the me.gs_pending queue.
    + */
    +static struct g_provider *
    +g_detach_proxy(struct g_geom *gp)
    +{
    +	struct g_consumer *cp;
    +	struct g_provider *pp, *newpp;
    +
    +	do {
    +		pp = LIST_FIRST(&gp->provider);
    +		if (pp == NULL)
    +			break;
    +		cp = LIST_FIRST(&gp->consumer);
    +		if (cp == NULL)
    +			break;
    +		newpp = cp->provider;
    +		if (newpp == NULL)
    +			break;
    +
    +		me.gs_npending = 0;
    +		pp->geom->start = g_sched_temporary_start;
    +
    +		return (pp);
    +	} while (0);
    +	printf("%s error detaching proxy %s\n", __FUNCTION__, gp->name);
    +
    +	return (NULL);
    +}
    +
    +static void
    +g_sched_blackhole(struct bio *bp)
    +{
    +
    +	g_io_deliver(bp, ENXIO);
    +}
    +
    +static inline void
    +g_reparent_provider(struct g_provider *pp, struct g_geom *gp,
    +    struct g_provider *newpp)
    +{
    +
    +	LIST_REMOVE(pp, provider);
    +	if (newpp) {
    +		pp->private = newpp->private;
    +		pp->index = newpp->index;
    +	}
    +	pp->geom = gp;
    +	LIST_INSERT_HEAD(&gp->provider, pp, provider);
    +}
    +
    +static inline void
    +g_unproxy_provider(struct g_provider *oldpp, struct g_provider *newpp)
    +{
    +	struct g_geom *gp = oldpp->geom;
    +
    +	g_reparent_provider(oldpp, newpp->geom, newpp);
    +
    +	/*
    +	 * Hackish: let the system destroy the old provider for us, just
    +	 * in case someone attached a consumer to it, in which case a
    +	 * direct call to g_destroy_provider() would not work.
    +	 */
    +	g_reparent_provider(newpp, gp, NULL);
    +}
    +
    +/*
    + * Complete the proxy destruction, linking the old provider to its
    + * original geom, and destroying the proxy provider.  Also take care
    + * of issuing the pending requests collected in me.gs_pending (if any).
    + */
    +static int
    +g_destroy_proxy(struct g_geom *gp, struct g_provider *oldpp)
    +{
    +	struct g_consumer *cp;
    +	struct g_provider *newpp;
    +
    +	do {
    +		cp = LIST_FIRST(&gp->consumer);
    +		if (cp == NULL)
    +			break;
    +		newpp = cp->provider;
    +		if (newpp == NULL)
    +			break;
    +
    +		/* Relink the provider to its original geom. */
    +		g_unproxy_provider(oldpp, newpp);
    +
    +		/* Detach consumer from provider, and destroy provider. */
    +		cp->acr = newpp->acr = 0;
    +		cp->acw = newpp->acw = 0;
    +		cp->ace = newpp->ace = 0;
    +		g_detach(cp);
    +
    +		/* Send the pending bios through the right start function. */
    +		g_sched_flush_pending(oldpp->geom->start);
    +
    +		return (0);
    +	} while (0);
    +	printf("%s error destroying proxy %s\n", __FUNCTION__, gp->name);
    +
    +	/* We cannot send the pending bios anywhere... */
    +	g_sched_flush_pending(g_sched_blackhole);
    +
    +	return (EINVAL);
    +}
    +
    +static int
    +g_sched_destroy(struct g_geom *gp, boolean_t force)
    +{
    +	struct g_provider *pp, *oldpp = NULL;
    +	struct g_sched_softc *sc;
    +	struct g_gsched *gsp;
    +	int error;
    +
    +	g_topology_assert();
    +	sc = gp->softc;
    +	if (sc == NULL)
    +		return (ENXIO);
    +	if (!(sc->sc_flags & G_SCHED_PROXYING)) {
    +		pp = LIST_FIRST(&gp->provider);
    +		if (pp && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
    +			const char *msg = force ?
    +				"but we force removal" : "cannot remove";
    +
    +			G_SCHED_DEBUG(!force,
    +			    "Device %s is still open (r%dw%de%d), %s.",
    +			    pp->name, pp->acr, pp->acw, pp->ace, msg);
    +			if (!force)
    +				return (EBUSY);
    +		} else {
    +			G_SCHED_DEBUG(0, "Device %s removed.", gp->name);
    +		}
    +	} else
    +		oldpp = g_detach_proxy(gp);
    +
    +	gsp = sc->sc_gsched;
    +	if (gsp) {
    +		/*
    +		 * XXX bad hack here: force a dispatch to release
    +		 * any reference to the hash table still held by
    +		 * the scheduler.
    +		 */
    +		g_sched_lock(gp);
    +		/*
    +		 * We are dying here, no new requests should enter
    +		 * the scheduler.  This is granted by the topolgy,
    +		 * either in case we were proxying (new bios are
    +		 * being redirected) or not (see the access check
    +		 * above).
    +		 */
    +		g_sched_forced_dispatch(gp);
    +		error = g_sched_wait_pending(gp);
    +
    +		if (error) {
    +			/*
    +			 * Not all the requests came home: this might happen
    +			 * under heavy load, or if we were waiting for any
    +			 * bio which is served in the event path (see
    +			 * geom_slice.c for an example of how this can
    +			 * happen).  Try to restore a working configuration
    +			 * if we can fail.
    +			 */
    +			if ((sc->sc_flags & G_SCHED_PROXYING) && oldpp) {
    +				g_sched_flush_pending(force ?
    +				    g_sched_blackhole : g_sched_start);
    +			}
    +
    +			/*
    +			 * In the forced destroy case there is not so much
    +			 * we can do, we have pending bios that will call
    +			 * g_sched_done() somehow, and we don't want them
    +			 * to crash the system using freed memory.  We tell
    +			 * the user that something went wrong, and leak some
    +			 * memory here.
    +			 * Note: the callers using force = 1 ignore the
    +			 * return value.
    +			 */
    +			if (force) {
    +				G_SCHED_DEBUG(0, "Pending requests while "
    +				    " destroying geom, some memory leaked.");
    +			}
    +
    +			return (error);
    +		}
    +
    +		g_sched_unlock(gp);
    +		g_sched_hash_fini(gp, sc->sc_hash, sc->sc_mask,
    +		    gsp, sc->sc_data);
    +		sc->sc_hash = NULL;
    +		gsp->gs_fini(sc->sc_data);
    +		g_gsched_unref(gsp);
    +		sc->sc_gsched = NULL;
    +	}
    +
    +	if ((sc->sc_flags & G_SCHED_PROXYING) && oldpp) {
    +		error = g_destroy_proxy(gp, oldpp);
    +
    +		if (error) {
    +			if (force) {
    +				G_SCHED_DEBUG(0, "Unrecoverable error while "
    +				    "destroying a proxy geom, leaking some "
    +				    " memory.");
    +			}
    +
    +			return (error);
    +		}
    +	}
    +
    +	mtx_destroy(&sc->sc_mtx);
    +
    +	g_free(gp->softc);
    +	gp->softc = NULL;
    +	g_wither_geom(gp, ENXIO);
    +
    +	return (error);
    +}
    +
    +static int
    +g_sched_destroy_geom(struct gctl_req *req, struct g_class *mp,
    +    struct g_geom *gp)
    +{
    +
    +	return (g_sched_destroy(gp, 0));
    +}
    +
    +/*
    + * Functions related to the classification of requests.
    + *
    + * On recent FreeBSD versions (8.0 and above), we store a reference
    + * to the issuer of a request in bp->bio_classifier1 as soon
    + * as the bio is posted to the geom queue (and not later, because
    + * requests are managed by the g_down thread afterwards).
    + *
    + * On older versions of the system (but this code is not used
    + * in any existing release), we [ab]use the caller1 field in the
    + * root element of the bio tree to store the classification info.
    + * The marking is done at the beginning of g_io_request()
    + * and only if we find that the field is NULL.
    + *
    + * To avoid rebuilding the kernel, this module will patch the
    + * initial part of g_io_request() so it jumps to some hand-coded
    + * assembly that does the marking and then executes the original
    + * body of g_io_request().
    + *
    + * fake_ioreq[] is architecture-specific machine code
    + * that implements the above. CODE_SIZE, STORE_SIZE etc.
    + * are constants used in the patching routine. Look at the
    + * code in g_ioreq_patch() for the details.
    + */
    +
    +#ifndef HAVE_BIO_CLASSIFIER
    +/*
    + * Support for old FreeBSD versions
    + */
    +#if defined(__i386__)
    +#define	CODE_SIZE	29
    +#define	STORE_SIZE	5
    +#define	EPILOGUE	5
    +#define	SIZE		(CODE_SIZE + STORE_SIZE + EPILOGUE)
    +
    +static u_char fake_ioreq[SIZE] = {
    +	0x8b, 0x44, 0x24, 0x04,		/* mov bp, %eax */
    +	/* 1: */
    +	0x89, 0xc2,			/* mov %eax, %edx # edx = bp */
    +	0x8b, 0x40, 0x64,		/* mov bp->bio_parent, %eax */
    +	0x85, 0xc0,			/* test %eax, %eax */
    +	0x75, 0xf7,			/* jne 1b */
    +	0x8b, 0x42, 0x30,		/* mov bp->bp_caller1, %eax */
    +	0x85, 0xc0,			/* test %eax, %eax */
    +	0x75, 0x09,			/* jne 2f */
    +	0x64, 0xa1, 0x00, 0x00,		/* mov %fs:0, %eax */
    +	0x00, 0x00,
    +	0x89, 0x42, 0x30,		/* mov %eax, bp->bio_caller1 */
    +	/* 2: */
    +        0x55, 0x89, 0xe5, 0x57, 0x56,
    +	0xe9, 0x00, 0x00, 0x00, 0x00,	/* jmp back... */
    +};
    +#elif defined(__amd64)
    +#define	CODE_SIZE	38
    +#define	STORE_SIZE	6
    +#define	EPILOGUE	5
    +#define	SIZE		(CODE_SIZE + STORE_SIZE + EPILOGUE)
    +
    +static u_char fake_ioreq[SIZE] = {
    +	0x48, 0x89, 0xf8,		/* mov bp, %rax */
    +	/* 1: */
    +	0x48, 0x89, 0xc2,		/* mov %rax, %rdx # rdx = bp */
    +	0x48, 0x8b, 0x82, 0xa8,		/* mov bp->bio_parent, %rax */
    +	0x00, 0x00, 0x00,
    +	0x48, 0x85, 0xc0,		/* test %rax, %rax */
    +	0x75, 0xf1,			/* jne 1b */
    +	0x48, 0x83, 0x7a, 0x58,		/* cmp $0, bp->bp_caller1 */
    +	0x00,
    +	0x75, 0x0d,			/* jne 2f */
    +	0x65, 0x48, 0x8b, 0x04,		/* mov %gs:0, %rax */
    +	0x25, 0x00, 0x00, 0x00,
    +	0x00,
    +	0x48, 0x89, 0x42, 0x58,		/* mov %rax, bp->bio_caller1 */
    +	/* 2: */
    +	0x55, 0x48, 0x89, 0xe5, 0x41, 0x56,
    +	0xe9, 0x00, 0x00, 0x00, 0x00,	/* jmp back... */
    +};
    +#else /* neither x86 nor amd64 */
    +static void
    +g_new_io_request(struct bio *bp, struct g_consumer *cp)
    +{
    +	struct bio *top = bp;
    +
    +        /*
    +         * bio classification: if bio_caller1 is available in the
    +         * root of the 'struct bio' tree, store there the thread id
    +         * of the thread that originated the request.
    +         * More sophisticated classification schemes can be used.
    +         */
    +	while (top->bio_parent)
    +		top = top->bio_parent;
    +
    +	if (top->bio_caller1 == NULL)
    +		top->bio_caller1 = curthread;
    +}
    +
    +#error please add the code above in g_new_io_request() to the beginning of \
    +	/sys/geom/geom_io.c::g_io_request(), and remove this line.
    +#endif /* end of arch-specific code */
    +
    +static int
    +g_ioreq_patch(void)
    +{
    +	u_char *original;
    +	u_long ofs;
    +	int found;
    +
    +	if (me.gs_patched)
    +		return (-1);
    +
    +	original = (u_char *)g_io_request;
    +
    +	found = !bcmp(original, fake_ioreq + CODE_SIZE, STORE_SIZE);
    +	if (!found)
    +		return (-1);
    +
    +	/* Jump back to the original + STORE_SIZE. */
    +	ofs = (original + STORE_SIZE) - (fake_ioreq + SIZE);
    +	bcopy(&ofs, fake_ioreq + CODE_SIZE + STORE_SIZE + 1, 4);
    +
    +	/* Patch the original address with a jump to the trampoline. */
    +	*original = 0xe9;     /* jump opcode */
    +	ofs = fake_ioreq - (original + 5);
    +	bcopy(&ofs, original + 1, 4);
    +
    +	me.gs_patched = 1;
    +
    +	return (0);
    +}
    +
    +/*
    + * Restore the original code, this is easy.
    + */
    +static void
    +g_ioreq_restore(void)
    +{
    +	u_char *original;
    +
    +	if (me.gs_patched) {
    +		original = (u_char *)g_io_request;
    +		bcopy(fake_ioreq + CODE_SIZE, original, STORE_SIZE);
    +		me.gs_patched = 0;
    +	}
    +}
    +
    +static inline void
    +g_classifier_ini(void)
    +{
    +
    +	g_ioreq_patch();
    +}
    +
    +static inline void
    +g_classifier_fini(void)
    +{
    +
    +	g_ioreq_restore();
    +}
    +
    +/*--- end of support code for older FreeBSD versions */
    +
    +#else /* HAVE_BIO_CLASSIFIER */
    +
    +/*
    + * Classifier support for recent FreeBSD versions: we use
    + * a very simple classifier, only use curthread to tag a request.
    + * The classifier is registered at module load, and unregistered
    + * at module unload.
    + */
    +static int
    +g_sched_tag(void *arg, struct bio *bp)
    +{
    +
    +	bp->bio_classifier1 = curthread;
    +	return (1);
    +}
    +
    +static struct g_classifier_hook g_sched_classifier = {
    +	.func =	g_sched_tag,
    +};
    +
    +static inline void
    +g_classifier_ini(void)
    +{
    +
    +	g_register_classifier(&g_sched_classifier);
    +}
    +
    +static inline void
    +g_classifier_fini(void)
    +{
    +
    +	g_unregister_classifier(&g_sched_classifier);
    +}
    +#endif /* HAVE_BIO_CLASSIFIER */
    +
    +static void
    +g_sched_init(struct g_class *mp)
    +{
    +
    +	g_gsched_global_init();
    +
    +	G_SCHED_DEBUG(0, "Loading: mp = %p, g_sched_class = %p.",
    +	    mp, &g_sched_class);
    +
    +	/* Patch g_io_request to store classification info in the bio. */
    +	g_classifier_ini();
    +}
    +
    +static void
    +g_sched_fini(struct g_class *mp)
    +{
    +
    +	g_classifier_fini();
    +
    +	G_SCHED_DEBUG(0, "Unloading...");
    +
    +	KASSERT(LIST_EMPTY(&me.gs_scheds), ("still registered schedulers"));
    +	mtx_destroy(&me.gs_mtx);
    +}
    +
    +/*
    + * Read the i-th argument for a request, skipping the /dev/
    + * prefix if present.
    + */
    +static const char *
    +g_sched_argi(struct gctl_req *req, int i)
    +{
    +	static const char *dev_prefix = "/dev/";
    +	const char *name;
    +	char param[16];
    +	int l = strlen(dev_prefix);
    +
    +	snprintf(param, sizeof(param), "arg%d", i);
    +	name = gctl_get_asciiparam(req, param);
    +	if (name == NULL)
    +		gctl_error(req, "No 'arg%d' argument", i);
    +	else if (strncmp(name, dev_prefix, l) == 0)
    +		name += l;
    +	return (name);
    +}
    +
    +/*
    + * Fetch nargs and do appropriate checks.
    + */
    +static int
    +g_sched_get_nargs(struct gctl_req *req)
    +{
    +	int *nargs;
    +
    +	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
    +	if (nargs == NULL) {
    +		gctl_error(req, "No 'nargs' argument");
    +		return (0);
    +	}
    +	if (*nargs <= 0)
    +		gctl_error(req, "Missing device(s).");
    +	return (*nargs);
    +}
    +
    +/*
    + * Check whether we should add the class on certain volumes when
    + * this geom is created. Right now this is under control of a kenv
    + * variable containing the names of all devices that we care about.
    + * Probably we should only support transparent insertion as the
    + * preferred mode of operation.
    + */
    +static struct g_geom *
    +g_sched_taste(struct g_class *mp, struct g_provider *pp,
    +		int flags __unused)
    +{
    +	struct g_gsched *gsp = NULL;	/* the . algorithm we want */
    +	const char *s;			/* generic string pointer */
    +	const char *taste_names;	/* devices we like */
    +	int l;
    +    
    +        g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__,
    +	    mp->name, pp->name);
    +        g_topology_assert();
    + 
    +        G_SCHED_DEBUG(2, "Tasting %s.", pp->name);
    +
    +	do {
    +		/* do not taste on ourselves */
    +		if (pp->geom->class == mp)
    +                	break;
    +
    +		taste_names = getenv("geom.sched.taste");
    +		if (taste_names == NULL)
    +			break;
    +
    +		l = strlen(pp->name);
    +		for (s = taste_names; *s &&
    +		    (s = strstr(s, pp->name)); s++) {
    +			/* further checks for an exact match */
    +			if ( (s == taste_names || s[-1] == ' ') &&
    +			     (s[l] == '\0' || s[l] == ' ') )
    +				break;
    +		}
    +		if (s == NULL)
    +			break;
    +		G_SCHED_DEBUG(0, "Attach device %s match [%s]\n",
    +		    pp->name, s);
    +
    +		/* look up the provider name in the list */
    +		s = getenv("geom.sched.algo");
    +		if (s == NULL)
    +			s = "rr";
    +
    +		gsp = g_gsched_find(s);	/* also get a reference */
    +		if (gsp == NULL) {
    +			G_SCHED_DEBUG(0, "Bad '%s' algorithm.", s);
    +			break;
    +		}
    +
    +		/* XXX create with 1 as last argument ? */
    +		g_sched_create(NULL, mp, pp, gsp, 0);
    +		g_gsched_unref(gsp);
    +	} while (0);
    +	return NULL;
    +}
    +
    +static void
    +g_sched_ctl_create(struct gctl_req *req, struct g_class *mp, int proxy)
    +{
    +	struct g_provider *pp;
    +	struct g_gsched *gsp;
    +	const char *name;
    +	int i, nargs;
    +
    +	g_topology_assert();
    +
    +	name = gctl_get_asciiparam(req, "algo");
    +	if (name == NULL) {
    +		gctl_error(req, "No '%s' argument", "algo");
    +		return;
    +	}
    +
    +	gsp = g_gsched_find(name);	/* also get a reference */
    +	if (gsp == NULL) {
    +		gctl_error(req, "Bad algorithm '%s'", name);
    +		return;
    +	}
    +
    +	nargs = g_sched_get_nargs(req);
    +
    +	/*
    +	 * Run on the arguments, and break on any error.
    +	 * We look for a device name, but skip the /dev/ prefix if any.
    +	 */
    +	for (i = 0; i < nargs; i++) {
    +		name = g_sched_argi(req, i);
    +		if (name == NULL)
    +			break;
    +		pp = g_provider_by_name(name);
    +		if (pp == NULL) {
    +			G_SCHED_DEBUG(1, "Provider %s is invalid.", name);
    +			gctl_error(req, "Provider %s is invalid.", name);
    +			break;
    +		}
    +		if (g_sched_create(req, mp, pp, gsp, proxy) != 0)
    +			break;
    +	}
    +
    +	g_gsched_unref(gsp);
    +}
    +
    +static void
    +g_sched_ctl_configure(struct gctl_req *req, struct g_class *mp)
    +{
    +	struct g_provider *pp;
    +	struct g_gsched *gsp;
    +	const char *name;
    +	int i, nargs;
    +
    +	g_topology_assert();
    +
    +	name = gctl_get_asciiparam(req, "algo");
    +	if (name == NULL) {
    +		gctl_error(req, "No '%s' argument", "algo");
    +		return;
    +	}
    +
    +	gsp = g_gsched_find(name);	/* also get a reference */
    +	if (gsp == NULL) {
    +		gctl_error(req, "Bad algorithm '%s'", name);
    +		return;
    +	}
    +
    +	nargs = g_sched_get_nargs(req);
    +
    +	/*
    +	 * Run on the arguments, and break on any error.
    +	 * We look for a device name, but skip the /dev/ prefix if any.
    +	 */
    +	for (i = 0; i < nargs; i++) {
    +		name = g_sched_argi(req, i);
    +		if (name == NULL)
    +			break;
    +		pp = g_provider_by_name(name);
    +		if (pp == NULL || pp->geom->class != mp) {
    +			G_SCHED_DEBUG(1, "Provider %s is invalid.", name);
    +			gctl_error(req, "Provider %s is invalid.", name);
    +			break;
    +		}
    +		if (g_sched_change_algo(req, mp, pp, gsp) != 0)
    +			break;
    +	}
    +
    +	g_gsched_unref(gsp);
    +}
    +
    +static struct g_geom *
    +g_sched_find_geom(struct g_class *mp, const char *name)
    +{
    +	struct g_geom *gp;
    +
    +	LIST_FOREACH(gp, &mp->geom, geom) {
    +		if (strcmp(gp->name, name) == 0)
    +			return (gp);
    +	}
    +	return (NULL);
    +}
    +
    +static void
    +g_sched_ctl_destroy(struct gctl_req *req, struct g_class *mp)
    +{
    +	int nargs, *force, error, i;
    +	struct g_geom *gp;
    +	const char *name;
    +
    +	g_topology_assert();
    +
    +	nargs = g_sched_get_nargs(req);
    +
    +	force = gctl_get_paraml(req, "force", sizeof(*force));
    +	if (force == NULL) {
    +		gctl_error(req, "No 'force' argument");
    +		return;
    +	}
    +
    +	for (i = 0; i < nargs; i++) {
    +		name = g_sched_argi(req, i);
    +		if (name == NULL)
    +			break;
    +
    +		gp = g_sched_find_geom(mp, name);
    +		if (gp == NULL) {
    +			G_SCHED_DEBUG(1, "Device %s is invalid.", name);
    +			gctl_error(req, "Device %s is invalid.", name);
    +			break;
    +		}
    +
    +		error = g_sched_destroy(gp, *force);
    +		if (error != 0) {
    +			gctl_error(req, "Cannot destroy device %s (error=%d).",
    +			    gp->name, error);
    +			break;
    +		}
    +	}
    +}
    +
    +static void
    +g_sched_config(struct gctl_req *req, struct g_class *mp, const char *verb)
    +{
    +	uint32_t *version;
    +
    +	g_topology_assert();
    +
    +	version = gctl_get_paraml(req, "version", sizeof(*version));
    +	if (version == NULL) {
    +		gctl_error(req, "No '%s' argument.", "version");
    +		return;
    +	}
    +
    +	if (*version != G_SCHED_VERSION) {
    +		gctl_error(req, "Userland and kernel parts are "
    +		    "out of sync.");
    +		return;
    +	}
    +
    +	if (strcmp(verb, "create") == 0) {
    +		g_sched_ctl_create(req, mp, 0);
    +		return;
    +	} else if (strcmp(verb, "insert") == 0) {
    +		g_sched_ctl_create(req, mp, 1);
    +		return;
    +	} else if (strcmp(verb, "configure") == 0) {
    +		g_sched_ctl_configure(req, mp);
    +		return;
    +	} else if (strcmp(verb, "destroy") == 0) {
    +		g_sched_ctl_destroy(req, mp);
    +		return;
    +	}
    +
    +	gctl_error(req, "Unknown verb.");
    +}
    +
    +static void
    +g_sched_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
    +    struct g_consumer *cp, struct g_provider *pp)
    +{
    +	struct g_sched_softc *sc = gp->softc;
    +	struct g_gsched *gsp = sc->sc_gsched;
    +	if (indent == NULL) {	/* plaintext */
    +		sbuf_printf(sb, " algo %s", gsp ? gsp->gs_name : "--");
    +	}
    +	if (gsp->gs_dumpconf)
    +		gsp->gs_dumpconf(sb, indent, gp, cp, pp);
    +}
    +
    +DECLARE_GEOM_CLASS(g_sched_class, g_sched);
    +MODULE_VERSION(geom_sched, 0);
    diff --git a/sys/geom/sched/g_sched.h b/sys/geom/sched/g_sched.h
    new file mode 100644
    index 00000000000..3a34e2922b1
    --- /dev/null
    +++ b/sys/geom/sched/g_sched.h
    @@ -0,0 +1,138 @@
    +/*-
    + * Copyright (c) 2009-2010 Fabio Checconi
    + * Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
    + * 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 AUTHORS 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 AUTHORS 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	_G_SCHED_H_
    +#define	_G_SCHED_H_
    +
    +/*
    + * $Id$
    + * $FreeBSD$
    + *
    + * Header for the geom_sched class (userland library and kernel part).
    + * See g_sched.c for documentation.
    + * The userland code only needs the three G_SCHED_* values below.
    + */
    +
    +#define	G_SCHED_CLASS_NAME	"SCHED"
    +#define	G_SCHED_VERSION		0
    +#define	G_SCHED_SUFFIX		".sched."
    +
    +#ifdef _KERNEL
    +#define	G_SCHED_DEBUG(lvl, ...)	do {				\
    +	if (me.gs_debug >= (lvl)) {				\
    +		printf("GEOM_SCHED");				\
    +		if (me.gs_debug > 0)				\
    +			printf("[%u]", lvl);			\
    +		printf(": ");					\
    +		printf(__VA_ARGS__);				\
    +		printf("\n");					\
    +	}							\
    +} while (0)
    +
    +#define	G_SCHED_LOGREQ(bp, ...)	do {				\
    +	if (me.gs_debug >= 2) {					\
    +		printf("GEOM_SCHED[2]: ");			\
    +		printf(__VA_ARGS__);				\
    +		printf(" ");					\
    +		g_print_bio(bp);				\
    +		printf("\n");					\
    +	}							\
    +} while (0)
    +
    +LIST_HEAD(g_hash, g_sched_class);
    +
    +/*
    + * Descriptor of a scheduler.
    + * In addition to the obvious fields, sc_flushing and sc_pending
    + * support dynamic switching of scheduling algorithm.
    + * Normally, sc_flushing is 0, and requests that are scheduled are
    + * also added to the sc_pending queue, and removed when we receive
    + * the 'done' event.
    + *
    + * When we are transparently inserted on an existing provider,
    + * sc_proxying is set. The detach procedure is slightly different.
    + *
    + * When switching schedulers, sc_flushing is set so requests bypass us,
    + * and at the same time we update the pointer in the pending bios
    + * to ignore us when they return up.
    + * XXX it would be more efficient to implement sc_pending with
    + * a generation number: the softc generation is increased when
    + * we change scheduling algorithm, we store the current generation
    + * number in the pending bios, and when they come back we ignore
    + * the done() call if the generation number do not match.
    + */
    +struct g_sched_softc {
    +	/*
    +	 * Generic fields used by any scheduling algorithm:
    +	 * a mutex, the class descriptor, flags, list of pending
    +	 * requests (used when flushing the module) and support
    +	 * for hash tables where we store per-flow queues.
    +	 */
    +	struct mtx	sc_mtx;
    +	struct g_gsched	*sc_gsched;	/* Scheduler descriptor. */
    +	int		sc_pending;	/* Pending requests. */
    +	int		sc_flags;	/* Various flags. */
    +
    +	/*
    +	 * Hash tables to store per-flow queues are generally useful
    +	 * so we handle them in the common code.
    +	 * sc_hash and sc_mask are parameters of the hash table,
    +	 * the last two fields are used to periodically remove
    +	 * expired items from the hash table.
    +	 */
    +	struct g_hash	*sc_hash;
    +	u_long		sc_mask;
    +	int		sc_flush_ticks;	/* Next tick for a flush. */
    +	int		sc_flush_bucket; /* Next bucket to flush. */
    +
    +	/*
    +	 * Pointer to the algorithm's private data, which is the value
    +	 * returned by sc_gsched->gs_init() . A NULL here means failure.
    +	 * XXX intptr_t might be more appropriate.
    +	 */
    +	void		*sc_data;
    +};
    +
    +#define	G_SCHED_PROXYING	1
    +#define	G_SCHED_FLUSHING	2
    +
    +/*
    + * Temporary- our own version of the disksort, because the
    + * version in 7.x and 8.x before march 2009 is buggy.
    + */
    +void gs_bioq_init(struct bio_queue_head *);
    +void gs_bioq_remove(struct bio_queue_head *, struct bio *);
    +void gs_bioq_flush(struct bio_queue_head *, struct devstat *, int);
    +void gs_bioq_insert_head(struct bio_queue_head *, struct bio *);
    +void gs_bioq_insert_tail(struct bio_queue_head *, struct bio *);
    +struct bio *gs_bioq_first(struct bio_queue_head *);
    +struct bio *gs_bioq_takefirst(struct bio_queue_head *);
    +void gs_bioq_disksort(struct bio_queue_head *, struct bio *);
    +
    +#endif	/* _KERNEL */
    +
    +#endif	/* _G_SCHED_H_ */
    diff --git a/sys/geom/sched/gs_rr.c b/sys/geom/sched/gs_rr.c
    new file mode 100644
    index 00000000000..c4b1990760d
    --- /dev/null
    +++ b/sys/geom/sched/gs_rr.c
    @@ -0,0 +1,686 @@
    +/*-
    + * Copyright (c) 2009-2010 Fabio Checconi
    + * Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
    + * 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.
    + */
    +
    +/*
    + * $Id$
    + * $FreeBSD$
    + *
    + * A round-robin (RR) anticipatory scheduler, with per-client queues.
    + *
    + * The goal of this implementation is to improve throughput compared
    + * to the pure elevator algorithm, and insure some fairness among
    + * clients.
    + * 
    + * Requests coming from the same client are put in the same queue.
    + * We use anticipation to help reducing seeks, and each queue
    + * is never served continuously for more than a given amount of
    + * time or data. Queues are then served in a round-robin fashion.
    + *
    + * Each queue can be in any of the following states:
    + *     READY	immediately serve the first pending request;
    + *     BUSY	one request is under service, wait for completion;
    + *     IDLING	do not serve incoming requests immediately, unless
    + * 		they are "eligible" as defined later.
    + *
    + * Scheduling is made looking at the status of all queues,
    + * and the first one in round-robin order is privileged.
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include "gs_scheduler.h"
    +
    +/* possible states of the scheduler */
    +enum g_rr_state {
    +	G_QUEUE_READY = 0,	/* Ready to dispatch. */
    +	G_QUEUE_BUSY,		/* Waiting for a completion. */
    +	G_QUEUE_IDLING		/* Waiting for a new request. */
    +};
    +
    +/* possible queue flags */
    +enum g_rr_flags {
    +	G_FLAG_COMPLETED = 1,	/* Completed a req. in the current budget. */
    +};
    +
    +struct g_rr_softc;
    +
    +/*
    + * Queue descriptor, containing reference count, scheduling
    + * state, a queue of pending requests, configuration parameters.
    + * Queues with pending request(s) and not under service are also
    + * stored in a Round Robin (RR) list.
    + */
    +struct g_rr_queue {
    +	struct g_rr_softc *q_sc;	/* link to the parent */
    +
    +	enum g_rr_state	q_status;
    +	unsigned int	q_service;	/* service received so far */
    +	int		q_slice_end;	/* actual slice end in ticks */
    +	enum g_rr_flags	q_flags;	/* queue flags */
    +	struct bio_queue_head q_bioq;
    +
    +	/* Scheduling parameters */
    +	unsigned int	q_budget;	/* slice size in bytes */
    +	unsigned int	q_slice_duration; /* slice size in ticks */
    +	unsigned int	q_wait_ticks;	/* wait time for anticipation */
    +
    +	/* Stats to drive the various heuristics. */
    +	struct g_savg	q_thinktime;	/* Thinktime average. */
    +	struct g_savg	q_seekdist;	/* Seek distance average. */
    +
    +	int		q_bionum;	/* Number of requests. */
    +
    +	off_t		q_lastoff;	/* Last submitted req. offset. */
    +	int		q_lastsub;	/* Last submitted req. time. */
    +
    +	/* Expiration deadline for an empty queue. */
    +	int		q_expire;
    +
    +	TAILQ_ENTRY(g_rr_queue) q_tailq; /* RR list link field */
    +};
    +
    +/* List types. */
    +TAILQ_HEAD(g_rr_tailq, g_rr_queue);
    +
    +/* list of scheduler instances */
    +LIST_HEAD(g_scheds, g_rr_softc);
    +
    +/* Default quantum for RR between queues. */
    +#define	G_RR_DEFAULT_BUDGET	0x00800000
    +
    +/*
    + * Per device descriptor, holding the Round Robin list of queues
    + * accessing the disk, a reference to the geom, and the timer.
    + */
    +struct g_rr_softc {
    +	struct g_geom	*sc_geom;
    +
    +	/*
    +	 * sc_active is the queue we are anticipating for.
    +	 * It is set only in gs_rr_next(), and possibly cleared
    +	 * only in gs_rr_next() or on a timeout.
    +	 * The active queue is never in the Round Robin list
    +	 * even if it has requests queued.
    +	 */
    +	struct g_rr_queue *sc_active;
    +	struct callout	sc_wait;	/* timer for sc_active */
    +
    +	struct g_rr_tailq sc_rr_tailq;	/* the round-robin list */
    +	int		sc_nqueues;	/* number of queues */
    +
    +	/* Statistics */
    +	int		sc_in_flight;	/* requests in the driver */
    +
    +	LIST_ENTRY(g_rr_softc)	sc_next;
    +};
    +
    +/* Descriptor for bounded values, min and max are constant. */
    +struct x_bound {		
    +	const int	x_min;
    +	int		x_cur;
    +	const int	x_max;
    +};
    +
    +/*
    + * parameters, config and stats
    + */
    +struct g_rr_params {
    +	int	queues;			/* total number of queues */
    +	int	w_anticipate;		/* anticipate writes */
    +	int	bypass;			/* bypass scheduling writes */
    +
    +	int	units;			/* how many instances */
    +	/* sc_head is used for debugging */
    +	struct g_scheds	sc_head;	/* first scheduler instance */
    +
    +	struct x_bound queue_depth;	/* max parallel requests */
    +	struct x_bound wait_ms;		/* wait time, milliseconds */
    +	struct x_bound quantum_ms;	/* quantum size, milliseconds */
    +	struct x_bound quantum_kb;	/* quantum size, Kb (1024 bytes) */
    +
    +	/* statistics */
    +	int	wait_hit;		/* success in anticipation */
    +	int	wait_miss;		/* failure in anticipation */
    +};
    +
    +/*
    + * Default parameters for the scheduler.  The quantum sizes target
    + * a 80MB/s disk; if the hw is faster or slower the minimum of the
    + * two will have effect: the clients will still be isolated but
    + * the fairness may be limited.  A complete solution would involve
    + * the on-line measurement of the actual disk throughput to derive
    + * these parameters.  Or we may just choose to ignore service domain
    + * fairness and accept what can be achieved with time-only budgets.
    + */
    +static struct g_rr_params me = {
    +	.sc_head = LIST_HEAD_INITIALIZER(&me.sc_head),
    +	.w_anticipate =	1,
    +	.queue_depth =	{ 1,	1,	50 },
    +	.wait_ms =	{ 1, 	10,	30 },
    +	.quantum_ms =	{ 1, 	100,	500 },
    +	.quantum_kb =	{ 16, 	8192,	65536 },
    +};
    +
    +struct g_rr_params *gs_rr_me = &me;
    +
    +SYSCTL_DECL(_kern_geom_sched);
    +SYSCTL_NODE(_kern_geom_sched, OID_AUTO, rr, CTLFLAG_RW, 0,
    +    "GEOM_SCHED ROUND ROBIN stuff");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, units, CTLFLAG_RD,
    +    &me.units, 0, "Scheduler instances");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, queues, CTLFLAG_RD,
    +    &me.queues, 0, "Total rr queues");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, wait_ms, CTLFLAG_RW,
    +    &me.wait_ms.x_cur, 0, "Wait time milliseconds");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, quantum_ms, CTLFLAG_RW,
    +    &me.quantum_ms.x_cur, 0, "Quantum size milliseconds");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, bypass, CTLFLAG_RW,
    +    &me.bypass, 0, "Bypass scheduler");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, w_anticipate, CTLFLAG_RW,
    +    &me.w_anticipate, 0, "Do anticipation on writes");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, quantum_kb, CTLFLAG_RW,
    +    &me.quantum_kb.x_cur, 0, "Quantum size Kbytes");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, queue_depth, CTLFLAG_RW,
    +    &me.queue_depth.x_cur, 0, "Maximum simultaneous requests");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, wait_hit, CTLFLAG_RW,
    +    &me.wait_hit, 0, "Hits in anticipation");
    +SYSCTL_UINT(_kern_geom_sched_rr, OID_AUTO, wait_miss, CTLFLAG_RW,
    +    &me.wait_miss, 0, "Misses in anticipation");
    +
    +#ifdef DEBUG_QUEUES
    +/* print the status of a queue */
    +static void
    +gs_rr_dump_q(struct g_rr_queue *qp, int index)
    +{
    +	int l = 0;
    +	struct bio *bp;
    +
    +	TAILQ_FOREACH(bp, &(qp->q_bioq.queue), bio_queue) {
    +		l++;
    +	}
    +	printf("--- rr queue %d %p status %d len %d ---\n",
    +	    index, qp, qp->q_status, l);
    +}
    +
    +/*
    + * Dump the scheduler status when writing to this sysctl variable.
    + * XXX right now we only dump the status of the last instance created.
    + * not a severe issue because this is only for debugging
    + */
    +static int
    +gs_rr_sysctl_status(SYSCTL_HANDLER_ARGS)
    +{
    +        int error, val = 0;
    +	struct g_rr_softc *sc;
    +
    +        error = sysctl_handle_int(oidp, &val, 0, req);
    +        if (error || !req->newptr )
    +                return (error);
    +
    +        printf("called %s\n", __FUNCTION__);
    +
    +	LIST_FOREACH(sc, &me.sc_head, sc_next) {
    +		int i, tot = 0;
    +		printf("--- sc %p active %p nqueues %d "
    +		    "callout %d in_flight %d ---\n",
    +		    sc, sc->sc_active, sc->sc_nqueues,
    +		    callout_active(&sc->sc_wait),
    +		    sc->sc_in_flight);
    +		for (i = 0; i < G_RR_HASH_SIZE; i++) {
    +			struct g_rr_queue *qp;
    +			LIST_FOREACH(qp, &sc->sc_hash[i], q_hash) {
    +				gs_rr_dump_q(qp, tot);
    +				tot++;
    +			}
    +		}
    +	}
    +        return (0);
    +}
    +
    +SYSCTL_PROC(_kern_geom_sched_rr, OID_AUTO, status,
    +	CTLTYPE_UINT | CTLFLAG_RW,
    +    0, sizeof(int), gs_rr_sysctl_status, "I", "status");
    +
    +#endif	/* DEBUG_QUEUES */
    +
    +/*
    + * Get a bounded value, optionally convert to a min of t_min ticks.
    + */
    +static int
    +get_bounded(struct x_bound *v, int t_min)
    +{
    +	int x;
    +
    +	x = v->x_cur;
    +	if (x < v->x_min)
    +		x = v->x_min;
    +	else if (x > v->x_max)
    +		x = v->x_max;
    +	if (t_min) {
    +		x = x * hz / 1000;	/* convert to ticks */
    +		if (x < t_min)
    +			x = t_min;
    +	}
    +	return x;
    +}
    +
    +/*
    + * Get a reference to the queue for bp, using the generic
    + * classification mechanism.
    + */
    +static struct g_rr_queue *
    +g_rr_queue_get(struct g_rr_softc *sc, struct bio *bp)
    +{
    +
    +	return (g_sched_get_class(sc->sc_geom, bp));
    +}
    +
    +static int
    +g_rr_init_class(void *data, void *priv)
    +{
    +	struct g_rr_softc *sc = data;
    +	struct g_rr_queue *qp = priv;
    +
    +	gs_bioq_init(&qp->q_bioq);
    +
    +	/*
    +	 * Set the initial parameters for the client:
    +	 * slice size in bytes and ticks, and wait ticks.
    +	 * Right now these are constant, but we could have
    +	 * autoconfiguration code to adjust the values based on
    +	 * the actual workload.
    +	 */
    +	qp->q_budget = 1024 * get_bounded(&me.quantum_kb, 0);
    +	qp->q_slice_duration = get_bounded(&me.quantum_ms, 2);
    +	qp->q_wait_ticks = get_bounded(&me.wait_ms, 2);
    +
    +	qp->q_sc = sc;		/* link to the parent */
    +	qp->q_sc->sc_nqueues++;
    +	me.queues++;
    +
    +	return (0);
    +}
    +
    +/*
    + * Release a reference to the queue.
    + */
    +static void
    +g_rr_queue_put(struct g_rr_queue *qp)
    +{
    +
    +	g_sched_put_class(qp->q_sc->sc_geom, qp);
    +}
    +
    +static void
    +g_rr_fini_class(void *data, void *priv)
    +{
    +	struct g_rr_queue *qp = priv;
    +
    +	KASSERT(gs_bioq_first(&qp->q_bioq) == NULL,
    +			("released nonempty queue"));
    +	qp->q_sc->sc_nqueues--;
    +	me.queues--;
    +}
    +
    +static inline int
    +g_rr_queue_expired(struct g_rr_queue *qp)
    +{
    +
    +	if (qp->q_service >= qp->q_budget)
    +		return (1);
    +
    +	if ((qp->q_flags & G_FLAG_COMPLETED) &&
    +	    ticks - qp->q_slice_end >= 0)
    +		return (1);
    +
    +	return (0);
    +}
    +
    +static inline int
    +g_rr_should_anticipate(struct g_rr_queue *qp, struct bio *bp)
    +{
    +	int wait = get_bounded(&me.wait_ms, 2);
    +
    +	if (!me.w_anticipate && (bp->bio_cmd & BIO_WRITE))
    +		return (0);
    +
    +	if (g_savg_valid(&qp->q_thinktime) &&
    +	    g_savg_read(&qp->q_thinktime) > wait)
    +		return (0);
    +
    +	if (g_savg_valid(&qp->q_seekdist) &&
    +	    g_savg_read(&qp->q_seekdist) > 8192)
    +		return (0);
    +
    +	return (1);
    +}
    +
    +/*
    + * Called on a request arrival, timeout or completion.
    + * Try to serve a request among those queued.
    + */
    +static struct bio *
    +g_rr_next(void *data, int force)
    +{
    +	struct g_rr_softc *sc = data;
    +	struct g_rr_queue *qp;
    +	struct bio *bp, *next;
    +	int expired;
    +
    +	qp = sc->sc_active;
    +	if (me.bypass == 0 && !force) {
    +		if (sc->sc_in_flight >= get_bounded(&me.queue_depth, 0))
    +			return (NULL);
    +
    +		/* Try with the queue under service first. */
    +		if (qp != NULL && qp->q_status != G_QUEUE_READY) {
    +			/*
    +			 * Queue is anticipating, ignore request.
    +			 * We should check that we are not past
    +			 * the timeout, but in that case the timeout
    +			 * will fire immediately afterwards so we
    +			 * don't bother.
    +			 */
    +			return (NULL);
    +		}
    +	} else if (qp != NULL && qp->q_status != G_QUEUE_READY) {
    +		g_rr_queue_put(qp);
    +		sc->sc_active = qp = NULL;
    +	}
    +
    +	/*
    +	 * No queue under service, look for the first in RR order.
    +	 * If we find it, select if as sc_active, clear service
    +	 * and record the end time of the slice.
    +	 */
    +	if (qp == NULL) {
    +		qp = TAILQ_FIRST(&sc->sc_rr_tailq);
    +		if (qp == NULL)
    +			return (NULL); /* no queues at all, return */
    +		/* otherwise select the new queue for service. */
    +		TAILQ_REMOVE(&sc->sc_rr_tailq, qp, q_tailq);
    +		sc->sc_active = qp;
    +		qp->q_service = 0;
    +		qp->q_flags &= ~G_FLAG_COMPLETED;
    +	}
    +
    +	bp = gs_bioq_takefirst(&qp->q_bioq);	/* surely not NULL */
    +	qp->q_service += bp->bio_length;	/* charge the service */
    +
    +	/*
    +	 * The request at the head of the active queue is always
    +	 * dispatched, and gs_rr_next() will be called again
    +	 * immediately.
    +	 * We need to prepare for what to do next:
    +	 *
    +	 * 1. have we reached the end of the (time or service) slice ?
    +	 *    If so, clear sc_active and possibly requeue the previous
    +	 *    active queue if it has more requests pending;
    +	 * 2. do we have more requests in sc_active ?
    +	 *    If yes, do not anticipate, as gs_rr_next() will run again;
    +	 *    if no, decide whether or not to anticipate depending
    +	 *    on read or writes (e.g., anticipate only on reads).
    +	 */
    +	expired = g_rr_queue_expired(qp);	/* are we expired ? */
    +	next = gs_bioq_first(&qp->q_bioq);	/* do we have one more ? */
    + 	if (expired) {
    +		sc->sc_active = NULL;
    +		/* Either requeue or release reference. */
    +		if (next != NULL)
    +			TAILQ_INSERT_TAIL(&sc->sc_rr_tailq, qp, q_tailq);
    +		else
    +			g_rr_queue_put(qp);
    +	} else if (next != NULL) {
    +		qp->q_status = G_QUEUE_READY;
    +	} else {
    +		if (!force && g_rr_should_anticipate(qp, bp)) {
    +			/* anticipate */
    +			qp->q_status = G_QUEUE_BUSY;
    +		} else {
    +			/* do not anticipate, release reference */
    +			g_rr_queue_put(qp);
    +			sc->sc_active = NULL;
    +		}
    +	}
    +	/* If sc_active != NULL, its q_status is always correct. */
    +
    +	sc->sc_in_flight++;
    +
    +	return (bp);
    +}
    +
    +static inline void
    +g_rr_update_thinktime(struct g_rr_queue *qp)
    +{
    +	int delta = ticks - qp->q_lastsub, wait = get_bounded(&me.wait_ms, 2);
    +
    +	if (qp->q_sc->sc_active != qp)
    +		return;
    +
    +	qp->q_lastsub = ticks;
    +	delta = (delta > 2 * wait) ? 2 * wait : delta;
    +	if (qp->q_bionum > 7)
    +		g_savg_add_sample(&qp->q_thinktime, delta);
    +}
    +
    +static inline void
    +g_rr_update_seekdist(struct g_rr_queue *qp, struct bio *bp)
    +{
    +	off_t dist;
    +
    +	if (qp->q_lastoff > bp->bio_offset)
    +		dist = qp->q_lastoff - bp->bio_offset;
    +	else
    +		dist = bp->bio_offset - qp->q_lastoff;
    +
    +	if (dist > (8192 * 8))
    +		dist = 8192 * 8;
    +
    +	qp->q_lastoff = bp->bio_offset + bp->bio_length;
    +
    +	if (qp->q_bionum > 7)
    +		g_savg_add_sample(&qp->q_seekdist, dist);
    +}
    +
    +/*
    + * Called when a real request for disk I/O arrives.
    + * Locate the queue associated with the client.
    + * If the queue is the one we are anticipating for, reset its timeout;
    + * if the queue is not in the round robin list, insert it in the list.
    + * On any error, do not queue the request and return -1, the caller
    + * will take care of this request.
    + */
    +static int
    +g_rr_start(void *data, struct bio *bp)
    +{
    +	struct g_rr_softc *sc = data;
    +	struct g_rr_queue *qp;
    +
    +	if (me.bypass)
    +		return (-1);	/* bypass the scheduler */
    +
    +	/* Get the queue for the request. */
    +	qp = g_rr_queue_get(sc, bp);
    +	if (qp == NULL)
    +		return (-1); /* allocation failed, tell upstream */
    +
    +	if (gs_bioq_first(&qp->q_bioq) == NULL) {
    +		/*
    +		 * We are inserting into an empty queue.
    +		 * Reset its state if it is sc_active,
    +		 * otherwise insert it in the RR list.
    +		 */
    +		if (qp == sc->sc_active) {
    +			qp->q_status = G_QUEUE_READY;
    +			callout_stop(&sc->sc_wait);
    +		} else {
    +			g_sched_priv_ref(qp);
    +			TAILQ_INSERT_TAIL(&sc->sc_rr_tailq, qp, q_tailq);
    +		}
    +	}
    +
    +	qp->q_bionum = 1 + qp->q_bionum - (qp->q_bionum >> 3);
    +
    +	g_rr_update_thinktime(qp);
    +	g_rr_update_seekdist(qp, bp);
    +
    +	/* Inherit the reference returned by g_rr_queue_get(). */
    +	bp->bio_caller1 = qp;
    +	gs_bioq_disksort(&qp->q_bioq, bp);
    +
    +	return (0);
    +}
    +
    +/*
    + * Callout executed when a queue times out anticipating a new request.
    + */
    +static void
    +g_rr_wait_timeout(void *data)
    +{
    +	struct g_rr_softc *sc = data;
    +	struct g_geom *geom = sc->sc_geom;
    +
    +	g_sched_lock(geom);
    +	/*
    +	 * We can race with other events, so check if
    +	 * sc_active is still valid.
    +	 */
    +	if (sc->sc_active != NULL) {
    +		/* Release the reference to the queue. */
    +		g_rr_queue_put(sc->sc_active);
    +		sc->sc_active = NULL;
    +		me.wait_hit--;
    +		me.wait_miss++;	/* record the miss */
    +	}
    +	g_sched_dispatch(geom);
    +	g_sched_unlock(geom);
    +}
    +
    +/*
    + * Module glue: allocate descriptor, initialize its fields.
    + */
    +static void *
    +g_rr_init(struct g_geom *geom)
    +{
    +	struct g_rr_softc *sc;
    +
    +	/* XXX check whether we can sleep */
    +	sc = malloc(sizeof *sc, M_GEOM_SCHED, M_NOWAIT | M_ZERO);
    +	sc->sc_geom = geom;
    +	TAILQ_INIT(&sc->sc_rr_tailq);
    +	callout_init(&sc->sc_wait, CALLOUT_MPSAFE);
    +	LIST_INSERT_HEAD(&me.sc_head, sc, sc_next);
    +	me.units++;
    +
    +	return (sc);
    +}
    +
    +/*
    + * Module glue -- drain the callout structure, destroy the
    + * hash table and its element, and free the descriptor.
    + */
    +static void
    +g_rr_fini(void *data)
    +{
    +	struct g_rr_softc *sc = data;
    +
    +	callout_drain(&sc->sc_wait);
    +	KASSERT(sc->sc_active == NULL, ("still a queue under service"));
    +	KASSERT(TAILQ_EMPTY(&sc->sc_rr_tailq), ("still scheduled queues"));
    +
    +	LIST_REMOVE(sc, sc_next);
    +	me.units--;
    +	free(sc, M_GEOM_SCHED);
    +}
    +
    +/*
    + * Called when the request under service terminates.
    + * Start the anticipation timer if needed.
    + */
    +static void
    +g_rr_done(void *data, struct bio *bp)
    +{
    +	struct g_rr_softc *sc = data;
    +	struct g_rr_queue *qp;
    +
    +	sc->sc_in_flight--;
    +
    +	qp = bp->bio_caller1;
    +	if (qp == sc->sc_active && qp->q_status == G_QUEUE_BUSY) {
    +		if (!(qp->q_flags & G_FLAG_COMPLETED)) {
    +			qp->q_flags |= G_FLAG_COMPLETED;
    +			/* in case we want to make the slice adaptive */
    +			qp->q_slice_duration = get_bounded(&me.quantum_ms, 2);
    +			qp->q_slice_end = ticks + qp->q_slice_duration;
    +		}
    +
    +		/* The queue is trying anticipation, start the timer. */
    +		qp->q_status = G_QUEUE_IDLING;
    +		/* may make this adaptive */
    +		qp->q_wait_ticks = get_bounded(&me.wait_ms, 2);
    +		me.wait_hit++;
    +		callout_reset(&sc->sc_wait, qp->q_wait_ticks,
    +		    g_rr_wait_timeout, sc);
    +	} else
    +		g_sched_dispatch(sc->sc_geom);
    +
    +	/* Release a reference to the queue. */
    +	g_rr_queue_put(qp);
    +}
    +
    +static void
    +g_rr_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
    +    struct g_consumer *cp, struct g_provider *pp)
    +{
    +	if (indent == NULL) {   /* plaintext */
    +		sbuf_printf(sb, " units %d queues %d",
    +			me.units, me.queues);
    +        }
    +}
    +
    +static struct g_gsched g_rr = {
    +	.gs_name = "rr",
    +	.gs_priv_size = sizeof(struct g_rr_queue),
    +	.gs_init = g_rr_init,
    +	.gs_fini = g_rr_fini,
    +	.gs_start = g_rr_start,
    +	.gs_done = g_rr_done,
    +	.gs_next = g_rr_next,
    +	.gs_dumpconf = g_rr_dumpconf,
    +	.gs_init_class = g_rr_init_class,
    +	.gs_fini_class = g_rr_fini_class,
    +};
    +
    +DECLARE_GSCHED_MODULE(rr, &g_rr);
    diff --git a/sys/geom/sched/gs_scheduler.h b/sys/geom/sched/gs_scheduler.h
    new file mode 100644
    index 00000000000..31e47e62ce7
    --- /dev/null
    +++ b/sys/geom/sched/gs_scheduler.h
    @@ -0,0 +1,237 @@
    +/*-
    + * Copyright (c) 2009-2010 Fabio Checconi
    + * Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
    + * 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 AUTHORS 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 AUTHORS 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.
    + */
    +
    +/*
    + * $Id$
    + * $FreeBSD$
    + *
    + * Prototypes for GEOM-based disk scheduling algorithms.
    + * See g_sched.c for generic documentation.
    + *
    + * This file is used by the kernel modules implementing the various
    + * scheduling algorithms. They should provide all the methods
    + * defined in struct g_gsched, and also invoke the macro
    + *	DECLARE_GSCHED_MODULE
    + * which registers the scheduling algorithm with the geom_sched module.
    + *
    + * The various scheduling algorithms do not need to know anything
    + * about geom, they only need to handle the 'bio' requests they
    + * receive, pass them down when needed, and use the locking interface
    + * defined below.
    + */
    +
    +#ifndef	_G_GSCHED_H_
    +#define	_G_GSCHED_H_
    +
    +#ifdef _KERNEL
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include "g_sched.h"
    +
    +/*
    + * This is the interface exported to scheduling modules.
    + *
    + * gs_init() is called when our scheduling algorithm
    + *    starts being used by a geom 'sched'
    + *
    + * gs_fini() is called when the algorithm is released.
    + *
    + * gs_start() is called when a new request comes in. It should
    + *    enqueue the request and return 0 if success, or return non-zero
    + *    in case of failure (meaning the request is passed down).
    + *    The scheduler can use bio->bio_caller1 to store a non-null
    + *    pointer meaning the request is under its control.
    + *
    + * gs_next() is called in a loop by g_sched_dispatch(), right after
    + *    gs_start(), or on timeouts or 'done' events. It should return
    + *    immediately, either a pointer to the bio to be served or NULL
    + *    if no bio should be served now.  If force is specified, a
    + *    work-conserving behavior is expected.
    + *
    + * gs_done() is called when a request under service completes.
    + *    In turn the scheduler may decide to call the dispatch loop
    + *    to serve other pending requests (or make sure there is a pending
    + *    timeout to avoid stalls).
    + *
    + * gs_init_class() is called when a new client (as determined by
    + *    the classifier) starts being used.
    + *
    + * gs_hash_unref() is called right before the class hashtable is
    + *    destroyed; after this call, the scheduler is supposed to hold no
    + *    more references to the elements in the table.
    + */
    +
    +/* Forward declarations for prototypes. */
    +struct g_geom;
    +struct g_sched_class;
    +
    +typedef void *gs_init_t (struct g_geom *geom);
    +typedef void gs_fini_t (void *data);
    +typedef int gs_start_t (void *data, struct bio *bio);
    +typedef void gs_done_t (void *data, struct bio *bio);
    +typedef struct bio *gs_next_t (void *data, int force);
    +typedef int gs_init_class_t (void *data, void *priv);
    +typedef void gs_fini_class_t (void *data, void *priv);
    +typedef void gs_hash_unref_t (void *data);
    +
    +struct g_gsched {
    +	const char	*gs_name;
    +	int		gs_refs;
    +	int		gs_priv_size;
    +
    +	gs_init_t	*gs_init;
    +	gs_fini_t	*gs_fini;
    +	gs_start_t	*gs_start;
    +	gs_done_t	*gs_done;
    +	gs_next_t	*gs_next;
    +	g_dumpconf_t	*gs_dumpconf;
    +
    +	gs_init_class_t	*gs_init_class;
    +	gs_fini_class_t	*gs_fini_class;
    +	gs_hash_unref_t *gs_hash_unref;
    +
    +	LIST_ENTRY(g_gsched) glist;
    +};
    +
    +#define	KTR_GSCHED	KTR_SPARE4
    +
    +MALLOC_DECLARE(M_GEOM_SCHED);
    +
    +/*
    + * Basic classification mechanism.  Each request is associated to
    + * a g_sched_class, and each scheduler has the opportunity to set
    + * its own private data for the given (class, geom) pair.  The
    + * private data have a base type of g_sched_private, and are
    + * extended at the end with the actual private fields of each
    + * scheduler.
    + */
    +struct g_sched_class {
    +	int	gsc_refs;
    +	int	gsc_expire;
    +	u_long	gsc_key;
    +	LIST_ENTRY(g_sched_class) gsc_clist;
    +
    +	void	*gsc_priv[0];
    +};
    +
    +/*
    + * Manipulate the classifier's data.  g_sched_get_class() gets a reference
    + * to the the class corresponding to bp in gp, allocating and initializing
    + * it if necessary.  g_sched_put_class() releases the reference.
    + * The returned value points to the private data for the class.
    + */
    +void *g_sched_get_class(struct g_geom *gp, struct bio *bp);
    +void g_sched_put_class(struct g_geom *gp, void *priv);
    +
    +static inline struct g_sched_class *
    +g_sched_priv2class(void *priv)
    +{
    +
    +	return ((struct g_sched_class *)((u_long)priv -
    +	    offsetof(struct g_sched_class, gsc_priv)));
    +}
    +
    +static inline void
    +g_sched_priv_ref(void *priv)
    +{
    +	struct g_sched_class *gsc;
    +
    +	gsc = g_sched_priv2class(priv);
    +	gsc->gsc_refs++;
    +}
    +
    +/*
    + * Locking interface.  When each operation registered with the
    + * scheduler is invoked, a per-instance lock is taken to protect
    + * the data associated with it.  If the scheduler needs something
    + * else to access the same data (e.g., a callout) it must use
    + * these functions.
    + */
    +void g_sched_lock(struct g_geom *gp);
    +void g_sched_unlock(struct g_geom *gp);
    +
    +/*
    + * Restart request dispatching.  Must be called with the per-instance
    + * mutex held.
    + */
    +void g_sched_dispatch(struct g_geom *geom);
    +
    +/*
    + * Simple gathering of statistical data, used by schedulers to collect
    + * info on process history.  Just keep an exponential average of the
    + * samples, with some extra bits of precision.
    + */
    +struct g_savg {
    +	uint64_t	gs_avg;
    +	unsigned int	gs_smpl;
    +};
    +
    +static inline void
    +g_savg_add_sample(struct g_savg *ss, uint64_t sample)
    +{
    +
    +	/* EMA with alpha = 0.125, fixed point, 3 bits of precision. */
    +	ss->gs_avg = sample + ss->gs_avg - (ss->gs_avg >> 3);
    +	ss->gs_smpl = 1 + ss->gs_smpl - (ss->gs_smpl >> 3);
    +}
    +
    +static inline int
    +g_savg_valid(struct g_savg *ss)
    +{
    +
    +	/* We want at least 8 samples to deem an average as valid. */
    +	return (ss->gs_smpl > 7);
    +}
    +
    +static inline uint64_t
    +g_savg_read(struct g_savg *ss)
    +{
    +
    +	return (ss->gs_avg / ss->gs_smpl);
    +}
    +
    +/*
    + * Declaration of a scheduler module.
    + */
    +int g_gsched_modevent(module_t mod, int cmd, void *arg);
    +
    +#define	DECLARE_GSCHED_MODULE(name, gsched)			\
    +	static moduledata_t name##_mod = {			\
    +		#name,						\
    +		g_gsched_modevent,				\
    +		gsched,						\
    +	};							\
    +	DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); \
    +	MODULE_DEPEND(name, geom_sched, 0, 0, 0);
    +
    +#endif	/* _KERNEL */
    +
    +#endif	/* _G_GSCHED_H_ */
    diff --git a/sys/geom/sched/subr_disk.c b/sys/geom/sched/subr_disk.c
    new file mode 100644
    index 00000000000..008eaab1c94
    --- /dev/null
    +++ b/sys/geom/sched/subr_disk.c
    @@ -0,0 +1,209 @@
    +/*-
    + * ----------------------------------------------------------------------------
    + * "THE BEER-WARE LICENSE" (Revision 42):
    + *  wrote this file.  As long as you retain this notice you
    + * can do whatever you want with this stuff. If we meet some day, and you think
    + * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
    + * ----------------------------------------------------------------------------
    + *
    + * The bioq_disksort() (and the specification of the bioq API)
    + * have been written by Luigi Rizzo and Fabio Checconi under the same
    + * license as above.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +//#include "opt_geom.h"
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include "g_sched.h"
    +
    +/*
    + * BIO queue implementation
    + *
    + * Please read carefully the description below before making any change
    + * to the code, or you might change the behaviour of the data structure
    + * in undesirable ways.
    + *
    + * A bioq stores disk I/O request (bio), normally sorted according to
    + * the distance of the requested position (bio->bio_offset) from the
    + * current head position (bioq->last_offset) in the scan direction, i.e.
    + *
    + * 	(uoff_t)(bio_offset - last_offset)
    + *
    + * Note that the cast to unsigned (uoff_t) is fundamental to insure
    + * that the distance is computed in the scan direction.
    + *
    + * The main methods for manipulating the bioq are:
    + *
    + *   bioq_disksort()	performs an ordered insertion;
    + *
    + *   bioq_first()	return the head of the queue, without removing;
    + *
    + *   bioq_takefirst()	return and remove the head of the queue,
    + *		updating the 'current head position' as
    + *		bioq->last_offset = bio->bio_offset + bio->bio_length;
    + *
    + * When updating the 'current head position', we assume that the result of
    + * bioq_takefirst() is dispatched to the device, so bioq->last_offset
    + * represents the head position once the request is complete.
    + *
    + * If the bioq is manipulated using only the above calls, it starts
    + * with a sorted sequence of requests with bio_offset >= last_offset,
    + * possibly followed by another sorted sequence of requests with
    + * 0 <= bio_offset < bioq->last_offset 
    + *
    + * NOTE: historical behaviour was to ignore bio->bio_length in the
    + *	update, but its use tracks the head position in a better way.
    + *	Historical behaviour was also to update the head position when
    + *	the request under service is complete, rather than when the
    + *	request is extracted from the queue. However, the current API
    + *	has no method to update the head position; secondly, once
    + *	a request has been submitted to the disk, we have no idea of
    + *	the actual head position, so the final one is our best guess.
    + *
    + * --- Direct queue manipulation ---
    + *
    + * A bioq uses an underlying TAILQ to store requests, so we also
    + * export methods to manipulate the TAILQ, in particular:
    + *
    + * bioq_insert_tail()	insert an entry at the end.
    + *		It also creates a 'barrier' so all subsequent
    + *		insertions through bioq_disksort() will end up
    + *		after this entry;
    + *
    + * bioq_insert_head()	insert an entry at the head, update
    + *		bioq->last_offset = bio->bio_offset so that
    + *		all subsequent insertions through bioq_disksort()
    + *		will end up after this entry;
    + *
    + * bioq_remove()	remove a generic element from the queue, act as
    + *		bioq_takefirst() if invoked on the head of the queue.
    + *
    + * The semantic of these methods is the same of the operations
    + * on the underlying TAILQ, but with additional guarantees on
    + * subsequent bioq_disksort() calls. E.g. bioq_insert_tail()
    + * can be useful for making sure that all previous ops are flushed
    + * to disk before continuing.
    + *
    + * Updating bioq->last_offset on a bioq_insert_head() guarantees
    + * that the bio inserted with the last bioq_insert_head() will stay
    + * at the head of the queue even after subsequent bioq_disksort().
    + *
    + * Note that when the direct queue manipulation functions are used,
    + * the queue may contain multiple inversion points (i.e. more than
    + * two sorted sequences of requests).
    + *
    + */
    +
    +void
    +gs_bioq_init(struct bio_queue_head *head)
    +{
    +
    +	TAILQ_INIT(&head->queue);
    +	head->last_offset = 0;
    +	head->insert_point = NULL;
    +}
    +
    +void
    +gs_bioq_remove(struct bio_queue_head *head, struct bio *bp)
    +{
    +
    +	if (bp == TAILQ_FIRST(&head->queue))
    +		head->last_offset = bp->bio_offset + bp->bio_length;
    +
    +	if (bp == head->insert_point)
    +		head->insert_point = NULL;
    +
    +	TAILQ_REMOVE(&head->queue, bp, bio_queue);
    +}
    +
    +void
    +gs_bioq_flush(struct bio_queue_head *head, struct devstat *stp, int error)
    +{
    +	struct bio *bp;
    +
    +	while ((bp = gs_bioq_takefirst(head)) != NULL)
    +		biofinish(bp, stp, error);
    +}
    +
    +void
    +gs_bioq_insert_head(struct bio_queue_head *head, struct bio *bp)
    +{
    +
    +	head->last_offset = bp->bio_offset;
    +	TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue);
    +}
    +
    +void
    +gs_bioq_insert_tail(struct bio_queue_head *head, struct bio *bp)
    +{
    +
    +	TAILQ_INSERT_TAIL(&head->queue, bp, bio_queue);
    +	head->insert_point = bp;
    +}
    +
    +struct bio *
    +gs_bioq_first(struct bio_queue_head *head)
    +{
    +
    +	return (TAILQ_FIRST(&head->queue));
    +}
    +
    +struct bio *
    +gs_bioq_takefirst(struct bio_queue_head *head)
    +{
    +	struct bio *bp;
    +
    +	bp = TAILQ_FIRST(&head->queue);
    +	if (bp != NULL)
    +		gs_bioq_remove(head, bp);
    +	return (bp);
    +}
    +
    +/*
    + * Compute the sorting key. The cast to unsigned is
    + * fundamental for correctness, see the description
    + * near the beginning of the file.
    + */
    +static inline uoff_t
    +gs_bioq_bio_key(struct bio_queue_head *head, struct bio *bp)
    +{
    +
    +	return ((uoff_t)(bp->bio_offset - head->last_offset));
    +}
    +
    +/*
    + * Seek sort for disks.
    + *
    + * Sort all requests in a single queue while keeping
    + * track of the current position of the disk with last_offset.
    + * See above for details.
    + */
    +void
    +gs_bioq_disksort(struct bio_queue_head *head, struct bio *bp)
    +{
    +	struct bio *cur, *prev = NULL;
    +	uoff_t key = gs_bioq_bio_key(head, bp);
    +
    +	cur = TAILQ_FIRST(&head->queue);
    +
    +	if (head->insert_point)
    +		cur = head->insert_point;
    +
    +	while (cur != NULL && key >= gs_bioq_bio_key(head, cur)) {
    +		prev = cur;
    +		cur = TAILQ_NEXT(cur, bio_queue);
    +	}
    +
    +	if (prev == NULL)
    +		TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue);
    +	else
    +		TAILQ_INSERT_AFTER(&head->queue, prev, bp, bio_queue);
    +}
    diff --git a/sys/modules/geom/Makefile b/sys/modules/geom/Makefile
    index 183e46e9420..1bb59948eca 100644
    --- a/sys/modules/geom/Makefile
    +++ b/sys/modules/geom/Makefile
    @@ -18,6 +18,7 @@ SUBDIR=	geom_bde \
     	geom_part \
     	geom_pc98 \
     	geom_raid3 \
    +	geom_sched \
     	geom_shsec \
     	geom_stripe \
     	geom_sunlabel \
    diff --git a/sys/modules/geom/geom_sched/Makefile b/sys/modules/geom/geom_sched/Makefile
    new file mode 100644
    index 00000000000..5937fa04d9c
    --- /dev/null
    +++ b/sys/modules/geom/geom_sched/Makefile
    @@ -0,0 +1,5 @@
    +# $FreeBSD$
    +
    +SUBDIR=	gs_sched gsched_rr
    +
    +.include 
    diff --git a/sys/modules/geom/geom_sched/Makefile.inc b/sys/modules/geom/geom_sched/Makefile.inc
    new file mode 100644
    index 00000000000..808d6eba89a
    --- /dev/null
    +++ b/sys/modules/geom/geom_sched/Makefile.inc
    @@ -0,0 +1,9 @@
    +# $FreeBSD$
    +# included by geom_sched children
    +
    +.PATH: ${.CURDIR}/../../../../geom/sched
    +
    +# 6.x needs this path
    +#CFLAGS += -I${.CURDIR}/../../../../geom/sched
    +
    +# .include 
    diff --git a/sys/modules/geom/geom_sched/gs_sched/Makefile b/sys/modules/geom/geom_sched/gs_sched/Makefile
    new file mode 100644
    index 00000000000..5739365a380
    --- /dev/null
    +++ b/sys/modules/geom/geom_sched/gs_sched/Makefile
    @@ -0,0 +1,6 @@
    +# $FreeBSD$
    +KMOD=   geom_sched
    +SRCS=   g_sched.c subr_disk.c
    +
    +# ../Makefile.inc automatically included
    +.include 
    diff --git a/sys/modules/geom/geom_sched/gsched_rr/Makefile b/sys/modules/geom/geom_sched/gsched_rr/Makefile
    new file mode 100644
    index 00000000000..42092771f8c
    --- /dev/null
    +++ b/sys/modules/geom/geom_sched/gsched_rr/Makefile
    @@ -0,0 +1,9 @@
    +# $FreeBSD$
    +
    +KMOD=   gsched_rr
    +SRCS=   gs_rr.c
    +# hash.h on 6.x has a (char *) cast on a const pointer
    +#CWARNFLAGS=
    +
    +# ../Makefile.inc automatically included
    +.include 
    
    From 66e29ee3f51f75490f2d1632b9596357a4029a8a Mon Sep 17 00:00:00 2001
    From: Rebecca Cran 
    Date: Tue, 20 Apr 2010 18:46:00 +0000
    Subject: [PATCH 2043/2592] MFC r204820:
    
    Install /etc/termcap.small .
    
    PR:	conf/78419
    Submitted by:	Eygene A.Ryabinkin 
    Approved by:	rrs (mentor)
    ---
     etc/Makefile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/etc/Makefile b/etc/Makefile
    index 36828e82a43..15e5a37f0f9 100644
    --- a/etc/Makefile
    +++ b/etc/Makefile
    @@ -18,7 +18,7 @@ BIN1=	auth.conf \
     	rc rc.bsdextended rc.firewall rc.initdiskless \
     	rc.sendmail rc.shutdown \
     	rc.subr remote rpc services shells \
    -	sysctl.conf syslog.conf \
    +	sysctl.conf syslog.conf termcap.small \
     	etc.${MACHINE_ARCH}/ttys
     
     OPENBSMDIR=			${.CURDIR}/../contrib/openbsm
    
    From 8bce49fc334b2596d1eea04f62f4890a3adb93cf Mon Sep 17 00:00:00 2001
    From: Rebecca Cran 
    Date: Tue, 20 Apr 2010 20:19:19 +0000
    Subject: [PATCH 2044/2592] MFC r205119 and r206056:
    
    Prevent the SIZE field being corrupted when a process allocates more than
    2TB.
    
    PR:	bin/129706
    Submitted by:	brucec
    Approved by: 	rrs (mentor)
    ---
     contrib/top/utils.c | 2 +-
     contrib/top/utils.h | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/contrib/top/utils.c b/contrib/top/utils.c
    index 906170ad67a..a38b2178fcc 100644
    --- a/contrib/top/utils.c
    +++ b/contrib/top/utils.c
    @@ -476,7 +476,7 @@ int amt;
     
     char *format_k2(amt)
     
    -int amt;
    +unsigned long long amt;
     
     {
         static char retarray[NUM_STRINGS][16];
    diff --git a/contrib/top/utils.h b/contrib/top/utils.h
    index 6717092002f..12a6c76c649 100644
    --- a/contrib/top/utils.h
    +++ b/contrib/top/utils.h
    @@ -21,4 +21,4 @@ long percentages();
     char *errmsg();
     char *format_time();
     char *format_k();
    -char *format_k2();
    +char *format_k2(unsigned long long);
    
    From accfa147723aac16d1874d90187ea390f654cc4d Mon Sep 17 00:00:00 2001
    From: Rebecca Cran 
    Date: Tue, 20 Apr 2010 20:24:00 +0000
    Subject: [PATCH 2045/2592] MFC r205118:
    
    Free the memory allocated via strdup.
    
    PR:	bin/113881
    Submitted by:	Alexander Drozdov (dzal_mail at mtu-net.ru)
    Approved by:	rrs (mentor)
    ---
     sbin/sysctl/sysctl.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
    index 3c1f3648ed7..f1b2473fec9 100644
    --- a/sbin/sysctl/sysctl.c
    +++ b/sbin/sysctl/sysctl.c
    @@ -379,6 +379,7 @@ S_timeval(int l2, void *p)
     		if (*p2 == '\n')
     			*p2 = '\0';
     	fputs(p1, stdout);
    +	free(p1);
     	return (0);
     }
     
    
    From 5c07bd7cf57b03c41103c9aa09c1d438dc67acd7 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:24:32 +0000
    Subject: [PATCH 2046/2592] MFC r201978:   Merge from projects/mips to head by
     hand:
    
      Merge the siba bus device.  This was moved from mips to dev because
      siba bus can be in other architectures, like ARM.
    
    MFC r202056:
      Move this to the right location.  Grump.
    
    MFC r202057:
      This was somehow copied to the wrong place :(.  Remove the spare copy.
    
    Approved by:	imp
    ---
     sys/dev/siba/siba_cc.c | 154 +++++++++++++++++++++++++++++++++++++++++
     1 file changed, 154 insertions(+)
     create mode 100644 sys/dev/siba/siba_cc.c
    
    diff --git a/sys/dev/siba/siba_cc.c b/sys/dev/siba/siba_cc.c
    new file mode 100644
    index 00000000000..cd78f0b0244
    --- /dev/null
    +++ b/sys/dev/siba/siba_cc.c
    @@ -0,0 +1,154 @@
    +/*-
    + * Copyright (c) 2007 Bruce M. Simpson.
    + * 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.
    + */
    +
    +/*
    + * Child driver for ChipCommon core.
    + * This is not MI code at the moment.
    + * Two 16C550 compatible UARTs live here. On the WGT634U, uart1 is the
    + * system console, and uart0 is not pinned out.
    + *  Because their presence is conditional, they should probably
    + *  be attached from here.
    + * GPIO lives here.
    + * The hardware watchdog lives here.
    + * Clock control registers live here.
    + *  You don't need to read them to determine the clock speed on the 5365,
    + *  which is always 200MHz and thus may be hardcoded (for now).
    + * Flash config registers live here. There may or may not be system flash.
    + * The external interface bus lives here (conditionally).
    + * There is a JTAG interface here which may be used to attach probes to
    + * the SoC for debugging.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +static int	siba_cc_attach(device_t);
    +static int	siba_cc_probe(device_t);
    +static void	siba_cc_intr(void *v);
    +
    +static int
    +siba_cc_probe(device_t dev)
    +{
    +
    +	if (siba_get_vendor(dev) == SIBA_VID_BROADCOM &&
    +	    siba_get_device(dev) == SIBA_DEVID_CHIPCOMMON) {
    +		device_set_desc(dev, "ChipCommon core");
    +		return (BUS_PROBE_DEFAULT);
    +	}
    +
    +	return (ENXIO);
    +}
    +
    +struct siba_cc_softc {
    +	void *notused;
    +};
    +
    +static int
    +siba_cc_attach(device_t dev)
    +{
    +	//struct siba_cc_softc *sc = device_get_softc(dev);
    +	struct resource *mem;
    +	struct resource *irq;
    +	int rid;
    +
    +	/*
    +	 * Allocate the resources which the parent bus has already
    +	 * determined for us.
    +	 * TODO: interrupt routing
    +	 */
    +#define MIPS_MEM_RID 0x20
    +	rid = MIPS_MEM_RID;
    +	mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
    +	if (mem == NULL) {
    +		device_printf(dev, "unable to allocate memory\n");
    +		return (ENXIO);
    +	}
    +
    +	rid = 0;
    +	irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 0);
    +	if (irq == NULL) {
    +		device_printf(dev, "unable to allocate irq\n");
    +		return (ENXIO);
    +	}
    +
    +	/* now setup the interrupt */
    +	/* may be fast, exclusive or mpsafe at a later date */
    +
    +	/*
    +	 * XXX is this interrupt line in ChipCommon used for anything
    +	 * other than the uart? in that case we shouldn't hog it ourselves
    +	 * and let uart claim it to avoid polled mode.
    +	 */
    +	int err;
    +	void *cookie;
    +	err = bus_setup_intr(dev, irq, INTR_TYPE_TTY, NULL, siba_cc_intr, NULL,
    +	    &cookie);
    +	if (err != 0) {
    +		device_printf(dev, "unable to setup intr\n");
    +		return (ENXIO);
    +	}
    +
    +	/* TODO: attach uart child */
    +
    +	return (0);
    +}
    +
    +static void
    +siba_cc_intr(void *v)
    +{
    +
    +}
    +
    +static device_method_t siba_cc_methods[] = {
    +	/* Device interface */
    +	DEVMETHOD(device_attach,	siba_cc_attach),
    +	DEVMETHOD(device_probe,		siba_cc_probe),
    +
    +	{0, 0},
    +};
    +
    +static driver_t siba_cc_driver = {
    +	"siba_cc",
    +	siba_cc_methods,
    +	sizeof(struct siba_softc),
    +};
    +static devclass_t siba_cc_devclass;
    +
    +DRIVER_MODULE(siba_cc, siba, siba_cc_driver, siba_cc_devclass, 0, 0);
    
    From 4b1a8666b998afecad5404e660bb875d69de409d Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:29:53 +0000
    Subject: [PATCH 2047/2592] MFC r203319:   Adds siba_bwn module which is used
     with bwn(4).  Main purpose of this   module is to distinguish parts of
     Silicon Backplane and of Broadcom   Wireless.
    
    ---
     sys/dev/siba/siba.c           |  106 +-
     sys/dev/siba/siba_bwn.c       |  366 ++++++
     sys/dev/siba/siba_cc.c        |    4 +-
     sys/dev/siba/siba_core.c      | 2007 +++++++++++++++++++++++++++++++++
     sys/dev/siba/siba_ids.h       |   48 +-
     sys/dev/siba/siba_pcib.c      |   19 +-
     sys/dev/siba/sibareg.h        |  397 ++++++-
     sys/dev/siba/sibavar.h        |  359 +++++-
     sys/modules/siba_bwn/Makefile |    9 +
     9 files changed, 3160 insertions(+), 155 deletions(-)
     create mode 100644 sys/dev/siba/siba_bwn.c
     create mode 100644 sys/dev/siba/siba_core.c
     create mode 100644 sys/modules/siba_bwn/Makefile
    
    diff --git a/sys/dev/siba/siba.c b/sys/dev/siba/siba.c
    index 04a53095921..541585b47e7 100644
    --- a/sys/dev/siba/siba.c
    +++ b/sys/dev/siba/siba.c
    @@ -37,9 +37,9 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#include 
    -#include 
     #include 
    +#include 
    +#include 
     
     /*
      * TODO: De-mipsify this code.
    @@ -77,7 +77,7 @@ static struct siba_devid siba_devids[] = {
     	  "MIPS core" },
     	{ SIBA_VID_BROADCOM,	SIBA_DEVID_ETHERNET,	SIBA_REV_ANY,
     	  "Ethernet core" },
    -	{ SIBA_VID_BROADCOM,	SIBA_DEVID_USB,		SIBA_REV_ANY,
    +	{ SIBA_VID_BROADCOM,	SIBA_DEVID_USB11_HOSTDEV, SIBA_REV_ANY,
     	  "USB host controller" },
     	{ SIBA_VID_BROADCOM,	SIBA_DEVID_IPSEC,	SIBA_REV_ANY,
     	  "IPSEC accelerator" },
    @@ -103,7 +103,6 @@ static struct siba_devid *
     static struct resource_list *
     		siba_get_reslist(device_t, device_t);
     static uint8_t	siba_getirq(uint16_t);
    -static uint8_t	siba_getncores(uint16_t);
     static int	siba_print_all_resources(device_t dev);
     static int	siba_print_child(device_t, device_t);
     static int	siba_probe(device_t);
    @@ -112,30 +111,7 @@ int		siba_read_ivar(device_t, device_t, int, uintptr_t *);
     static struct siba_devinfo *
     		siba_setup_devinfo(device_t, uint8_t);
     int		siba_write_ivar(device_t, device_t, int, uintptr_t);
    -
    -/*
    - * Earlier ChipCommon revisions have hardcoded number of cores
    - * present dependent on the ChipCommon ID.
    - */
    -static uint8_t
    -siba_getncores(uint16_t ccid)
    -{
    -	uint8_t ncores;
    -
    -	switch (ccid) {
    -	case SIBA_CCID_SENTRY5:
    -		ncores = 7;
    -		break;
    -	case SIBA_CCID_BCM4710:
    -	case SIBA_CCID_BCM4704:
    -		ncores = 9;
    -		break;
    -	default:
    -		ncores = 0;
    -	}
    -
    -	return (ncores);
    -}
    +uint8_t		siba_getncores(device_t, uint16_t);
     
     /*
      * On the Sentry5, the system bus IRQs are the same as the
    @@ -156,7 +132,7 @@ siba_getirq(uint16_t devid)
     	case SIBA_DEVID_IPSEC:
     		irq = 2;
     		break;
    -	case SIBA_DEVID_USB:
    +	case SIBA_DEVID_USB11_HOSTDEV:
     		irq = 3;
     		break;
     	case SIBA_DEVID_PCI:
    @@ -188,7 +164,7 @@ siba_probe(device_t dev)
     	uint16_t ccid;
     	int rid;
     
    -	sc->sc_dev = dev;
    +	sc->siba_dev = dev;
     
     	//rman_debug = 1;	/* XXX */
     
    @@ -197,24 +173,24 @@ siba_probe(device_t dev)
     	 * was compiled with.
     	 */
     	rid = MIPS_MEM_RID;
    -	sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
    +	sc->siba_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
     	    RF_ACTIVE);
    -	if (sc->sc_mem == NULL) {
    +	if (sc->siba_mem_res == NULL) {
     		device_printf(dev, "unable to allocate probe aperture\n");
     		return (ENXIO);
     	}
    -	sc->sc_bt = rman_get_bustag(sc->sc_mem);
    -	sc->sc_bh = rman_get_bushandle(sc->sc_mem);
    -	sc->sc_maddr = rman_get_start(sc->sc_mem);
    -	sc->sc_msize = rman_get_size(sc->sc_mem);
    +	sc->siba_mem_bt = rman_get_bustag(sc->siba_mem_res);
    +	sc->siba_mem_bh = rman_get_bushandle(sc->siba_mem_res);
    +	sc->siba_maddr = rman_get_start(sc->siba_mem_res);
    +	sc->siba_msize = rman_get_size(sc->siba_mem_res);
     
     	if (siba_debug) {
     		device_printf(dev, "start %08x len %08x\n",
    -		    sc->sc_maddr, sc->sc_msize);
    +		    sc->siba_maddr, sc->siba_msize);
     	}
     
    -	idlo = siba_read_4(sc, 0, SIBA_CORE_IDLO);
    -	idhi = siba_read_4(sc, 0, SIBA_CORE_IDHI);
    +	idlo = siba_mips_read_4(sc, 0, SIBA_IDLOW);
    +	idhi = siba_mips_read_4(sc, 0, SIBA_IDHIGH);
     	ccid = ((idhi & 0x8ff0) >> 4);
     	if (siba_debug) {
     		device_printf(dev, "idlo = %08x\n", idlo);
    @@ -256,7 +232,7 @@ siba_probe(device_t dev)
     	uint16_t cc_id;
     	uint16_t cc_rev;
     
    -	ccidreg = siba_read_4(sc, 0, SIBA_CC_CCID);
    +	ccidreg = siba_mips_read_4(sc, 0, SIBA_CC_CHIPID);
     	cc_id = (ccidreg & SIBA_CC_IDMASK);
     	cc_rev = (ccidreg & SIBA_CC_REVMASK) >> SIBA_CC_REVSHIFT;
     	if (siba_debug) {
    @@ -264,9 +240,9 @@ siba_probe(device_t dev)
     		     ccidreg, cc_id, cc_rev);
     	}
     
    -	sc->sc_ncores = siba_getncores(cc_id);
    +	sc->siba_ncores = siba_getncores(dev, cc_id);
     	if (siba_debug) {
    -		device_printf(dev, "%d cores detected.\n", sc->sc_ncores);
    +		device_printf(dev, "%d cores detected.\n", sc->siba_ncores);
     	}
     
     	/*
    @@ -275,36 +251,38 @@ siba_probe(device_t dev)
     	 */
     	rid = MIPS_MEM_RID;
     	int result;
    -	result = bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->sc_mem);
    +	result = bus_release_resource(dev, SYS_RES_MEMORY, rid,
    +	    sc->siba_mem_res);
     	if (result != 0) {
     		device_printf(dev, "error %d releasing resource\n", result);
     		return (ENXIO);
     	}
     
     	uint32_t total;
    -	total = sc->sc_ncores * SIBA_CORE_LEN;
    +	total = sc->siba_ncores * SIBA_CORE_LEN;
     
     	/* XXX Don't allocate the entire window until we
     	 * enumerate the bus. Once the bus has been enumerated,
     	 * and instance variables/children instantiated + populated,
     	 * release the resource so children may attach.
     	 */
    -	sc->sc_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
    -	    sc->sc_maddr, sc->sc_maddr + total - 1, total, RF_ACTIVE);
    -	if (sc->sc_mem == NULL) {
    +	sc->siba_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
    +	    sc->siba_maddr, sc->siba_maddr + total - 1, total, RF_ACTIVE);
    +	if (sc->siba_mem_res == NULL) {
     		device_printf(dev, "unable to allocate entire aperture\n");
     		return (ENXIO);
     	}
    -	sc->sc_bt = rman_get_bustag(sc->sc_mem);
    -	sc->sc_bh = rman_get_bushandle(sc->sc_mem);
    -	sc->sc_maddr = rman_get_start(sc->sc_mem);
    -	sc->sc_msize = rman_get_size(sc->sc_mem);
    +	sc->siba_mem_bt = rman_get_bustag(sc->siba_mem_res);
    +	sc->siba_mem_bh = rman_get_bushandle(sc->siba_mem_res);
    +	sc->siba_maddr = rman_get_start(sc->siba_mem_res);
    +	sc->siba_msize = rman_get_size(sc->siba_mem_res);
     
     	if (siba_debug) {
     		device_printf(dev, "after remapping: start %08x len %08x\n",
    -		    sc->sc_maddr, sc->sc_msize);
    +		    sc->siba_maddr, sc->siba_msize);
     	}
    -	bus_set_resource(dev, SYS_RES_MEMORY, rid, sc->sc_maddr, sc->sc_msize);
    +	bus_set_resource(dev, SYS_RES_MEMORY, rid, sc->siba_maddr,
    +	    sc->siba_msize);
     
     	/*
     	 * We need a manager for the space we claim on nexus to
    @@ -313,12 +291,13 @@ siba_probe(device_t dev)
     	 * otherwise it may be claimed elsewhere.
     	 * XXX move to softc
     	 */
    -	mem_rman.rm_start = sc->sc_maddr;
    -	mem_rman.rm_end = sc->sc_maddr + sc->sc_msize - 1;
    +	mem_rman.rm_start = sc->siba_maddr;
    +	mem_rman.rm_end = sc->siba_maddr + sc->siba_msize - 1;
     	mem_rman.rm_type = RMAN_ARRAY;
     	mem_rman.rm_descr = "SiBa I/O memory addresses";
     	if (rman_init(&mem_rman) != 0 ||
    -	    rman_manage_region(&mem_rman, mem_rman.rm_start, mem_rman.rm_end) != 0) {
    +	    rman_manage_region(&mem_rman, mem_rman.rm_start,
    +		mem_rman.rm_end) != 0) {
     		panic("%s: mem_rman", __func__);
     	}
     
    @@ -344,7 +323,7 @@ siba_attach(device_t dev)
     	 * NB: only one core may be mapped at any time if the siba bus
     	 * is the child of a PCI or PCMCIA bus.
     	 */
    -	for (idx = 0; idx < sc->sc_ncores; idx++) {
    +	for (idx = 0; idx < sc->siba_ncores; idx++) {
     		sdi = siba_setup_devinfo(dev, idx);
     		child = device_add_child(dev, NULL, -1);
     		if (child == NULL)
    @@ -483,13 +462,14 @@ siba_setup_devinfo(device_t dev, uint8_t idx)
     	sdi = malloc(sizeof(*sdi), M_DEVBUF, M_WAITOK | M_ZERO);
     	resource_list_init(&sdi->sdi_rl);
     
    -	idlo = siba_read_4(sc, idx, SIBA_CORE_IDLO);
    -	idhi = siba_read_4(sc, idx, SIBA_CORE_IDHI);
    +	idlo = siba_mips_read_4(sc, idx, SIBA_IDLOW);
    +	idhi = siba_mips_read_4(sc, idx, SIBA_IDHIGH);
     
    -	vendorid = (idhi & SIBA_IDHIGH_VC) >> SIBA_IDHIGH_VC_SHIFT;
    +	vendorid = (idhi & SIBA_IDHIGH_VENDORMASK) >>
    +	    SIBA_IDHIGH_VENDOR_SHIFT;
     	devid = ((idhi & 0x8ff0) >> 4);
    -	rev = (idhi & SIBA_IDHIGH_RCLO);
    -	rev |= (idhi & SIBA_IDHIGH_RCHI) >> SIBA_IDHIGH_RCHI_SHIFT;
    +	rev = (idhi & SIBA_IDHIGH_REVLO);
    +	rev |= (idhi & SIBA_IDHIGH_REVHI) >> SIBA_IDHIGH_REVHI_SHIFT;
     
     	sdi->sdi_vid = vendorid;
     	sdi->sdi_devid = devid;
    @@ -500,7 +480,7 @@ siba_setup_devinfo(device_t dev, uint8_t idx)
     	/*
     	 * Determine memory window on bus and irq if one is needed.
     	 */
    -	baseaddr = sc->sc_maddr + (idx * SIBA_CORE_LEN);
    +	baseaddr = sc->siba_maddr + (idx * SIBA_CORE_LEN);
     	resource_list_add(&sdi->sdi_rl, SYS_RES_MEMORY,
     	    MIPS_MEM_RID, /* XXX */
     	    baseaddr, baseaddr + SIBA_CORE_LEN - 1, SIBA_CORE_LEN);
    diff --git a/sys/dev/siba/siba_bwn.c b/sys/dev/siba/siba_bwn.c
    new file mode 100644
    index 00000000000..a5513bdb4e1
    --- /dev/null
    +++ b/sys/dev/siba/siba_bwn.c
    @@ -0,0 +1,366 @@
    +/*-
    + * Copyright (c) 2009-2010 Weongyo Jeong 
    + * 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.
    + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    + *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
    + *    redistribution must be conditioned upon including a substantially
    + *    similar Disclaimer requirement for further binary redistribution.
    + *
    + * NO WARRANTY
    + * 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 NONINFRINGEMENT, MERCHANTIBILITY
    + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +/*
    + * Sonics Silicon Backplane front-end for bwn(4).
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +/*
    + * PCI glue.
    + */
    +
    +struct siba_bwn_softc {
    +	/* Child driver using MSI. */
    +	device_t			ssc_msi_child;
    +	struct siba_softc		ssc_siba;
    +};
    +
    +#define	BS_BAR				0x10
    +#define	PCI_VENDOR_BROADCOM		0x14e4
    +#define	N(a)				(sizeof(a) / sizeof(a[0]))
    +
    +static const struct siba_dev {
    +	uint16_t	vid;
    +	uint16_t	did;
    +	const char	*desc;
    +} siba_devices[] = {
    +	{ PCI_VENDOR_BROADCOM, 0x4301, "Broadcom BCM4301 802.11b Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4306, "Unknown" },
    +	{ PCI_VENDOR_BROADCOM, 0x4307, "Broadcom BCM4307 802.11b Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4311, "Broadcom BCM4311 802.11b/g Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4312,
    +	  "Broadcom BCM4312 802.11a/b/g Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4315, "Broadcom BCM4312 802.11b/g Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4318, "Broadcom BCM4318 802.11b/g Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4319,
    +	  "Broadcom BCM4318 802.11a/b/g Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4320, "Broadcom BCM4306 802.11b/g Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4321, "Broadcom BCM4306 802.11a Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4324,
    +	  "Broadcom BCM4309 802.11a/b/g Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4325, "Broadcom BCM4306 802.11b/g Wireless" },
    +	{ PCI_VENDOR_BROADCOM, 0x4328, "Unknown" },
    +	{ PCI_VENDOR_BROADCOM, 0x4329, "Unknown" },
    +	{ PCI_VENDOR_BROADCOM, 0x432b, "Unknown" }
    +};
    +
    +device_t	siba_add_child(device_t, struct siba_softc *, int, const char *,
    +		    int);
    +int		siba_core_attach(struct siba_softc *);
    +int		siba_core_detach(struct siba_softc *);
    +int		siba_core_suspend(struct siba_softc *);
    +int		siba_core_resume(struct siba_softc *);
    +
    +static int
    +siba_bwn_probe(device_t dev)
    +{
    +	int i;
    +	uint16_t did, vid;
    +
    +	did = pci_get_device(dev);
    +	vid = pci_get_vendor(dev);
    +
    +	for (i = 0; i < N(siba_devices); i++) {
    +		if (siba_devices[i].did == did && siba_devices[i].vid == vid) {
    +			device_set_desc(dev, siba_devices[i].desc);
    +			return (BUS_PROBE_DEFAULT);
    +		}
    +	}
    +	return (ENXIO);
    +}
    +
    +static int
    +siba_bwn_attach(device_t dev)
    +{
    +	struct siba_bwn_softc *ssc = device_get_softc(dev);
    +	struct siba_softc *siba = &ssc->ssc_siba;
    +
    +	siba->siba_dev = dev;
    +	siba->siba_type = SIBA_TYPE_PCI;
    +
    +	/*
    +	 * Enable bus mastering.
    +	 */
    +	pci_enable_busmaster(dev);
    +
    +	/* 
    +	 * Setup memory-mapping of PCI registers.
    +	 */
    +	siba->siba_mem_rid = SIBA_PCIR_BAR;
    +	siba->siba_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
    +		&siba->siba_mem_rid, RF_ACTIVE);
    +	if (siba->siba_mem_res == NULL) {
    +		device_printf(dev, "cannot map register space\n");
    +		return (ENXIO);
    +	}
    +	siba->siba_mem_bt = rman_get_bustag(siba->siba_mem_res);
    +	siba->siba_mem_bh = rman_get_bushandle(siba->siba_mem_res);
    +
    +	/* Get more PCI information */
    +	siba->siba_pci_did = pci_get_device(dev);
    +	siba->siba_pci_vid = pci_get_vendor(dev);
    +	siba->siba_pci_subvid = pci_get_subvendor(dev);
    +	siba->siba_pci_subdid = pci_get_subdevice(dev);
    +
    +	return (siba_core_attach(siba));
    +}
    +
    +static int
    +siba_bwn_detach(device_t dev)
    +{
    +	struct siba_bwn_softc *ssc = device_get_softc(dev);
    +	struct siba_softc *siba = &ssc->ssc_siba;
    +
    +	/* check if device was removed */
    +	siba->siba_invalid = !bus_child_present(dev);
    +
    +	pci_disable_busmaster(dev);
    +	bus_generic_detach(dev);
    +	siba_core_detach(siba);
    +
    +	bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, siba->siba_mem_res);
    +
    +	return (0);
    +}
    +
    +static int
    +siba_bwn_shutdown(device_t dev)
    +{
    +	device_t *devlistp;
    +	int devcnt, error = 0, i;
    +
    +	error = device_get_children(dev, &devlistp, &devcnt);
    +	if (error != 0)
    +		return (error);
    +
    +	for (i = 0 ; i < devcnt ; i++)
    +		device_shutdown(devlistp[i]);
    +	free(devlistp, M_TEMP);
    +	return (0);
    +}
    +
    +static int
    +siba_bwn_suspend(device_t dev)
    +{
    +	struct siba_bwn_softc *ssc = device_get_softc(dev);
    +	struct siba_softc *siba = &ssc->ssc_siba;
    +	device_t *devlistp;
    +	int devcnt, error = 0, i, j;
    +
    +	error = device_get_children(dev, &devlistp, &devcnt);
    +	if (error != 0)
    +		return (error);
    +
    +	for (i = 0 ; i < devcnt ; i++) {
    +		error = DEVICE_SUSPEND(devlistp[i]);
    +		if (error) {
    +			for (j = 0; j < i; i++)
    +				DEVICE_RESUME(devlistp[j]);
    +			return (error);
    +		}
    +	}
    +	free(devlistp, M_TEMP);
    +	return (siba_core_suspend(siba));
    +}
    +
    +static int
    +siba_bwn_resume(device_t dev)
    +{
    +	struct siba_bwn_softc *ssc = device_get_softc(dev);
    +	struct siba_softc *siba = &ssc->ssc_siba;
    +	device_t *devlistp;
    +	int devcnt, error = 0, i;
    +
    +	error = siba_core_resume(siba);
    +	if (error != 0)
    +		return (error);
    +
    +	error = device_get_children(dev, &devlistp, &devcnt);
    +	if (error != 0)
    +		return (error);
    +
    +	for (i = 0 ; i < devcnt ; i++)
    +		DEVICE_RESUME(devlistp[i]);
    +	free(devlistp, M_TEMP);
    +	return (0);
    +}
    +
    +static device_t
    +siba_bwn_add_child(device_t dev, int order, const char *name, int unit)
    +{
    +	struct siba_bwn_softc *ssc = device_get_softc(dev);
    +	struct siba_softc *siba = &ssc->ssc_siba;
    +
    +	return (siba_add_child(dev, siba, order, name, unit));
    +}
    +
    +/* proxying to the parent */
    +static struct resource *
    +siba_bwn_alloc_resource(device_t dev, device_t child, int type, int *rid,
    +    u_long start, u_long end, u_long count, u_int flags)
    +{
    +
    +	return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
    +	    type, rid, start, end, count, flags));
    +}
    +
    +/* proxying to the parent */
    +static int
    +siba_bwn_release_resource(device_t dev, device_t child, int type,
    +    int rid, struct resource *r)
    +{
    +
    +	return (BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, type,
    +	    rid, r));
    +}
    +
    +/* proxying to the parent */
    +static int
    +siba_bwn_setup_intr(device_t dev, device_t child, struct resource *irq,
    +    int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
    +    void **cookiep)
    +{
    +
    +	return (BUS_SETUP_INTR(device_get_parent(dev), dev, irq, flags,
    +	    filter, intr, arg, cookiep));
    +}
    +
    +/* proxying to the parent */
    +static int
    +siba_bwn_teardown_intr(device_t dev, device_t child, struct resource *irq,
    +    void *cookie)
    +{
    +
    +	return (BUS_TEARDOWN_INTR(device_get_parent(dev), dev, irq, cookie));
    +}
    +
    +static int
    +siba_bwn_find_extcap(device_t dev, device_t child, int capability,
    +    int *capreg)
    +{
    +
    +	return (pci_find_extcap(dev, capability, capreg));
    +}
    +
    +static int
    +siba_bwn_alloc_msi(device_t dev, device_t child, int *count)
    +{
    +	struct siba_bwn_softc *ssc;
    +	int error;
    +
    +	ssc = device_get_softc(dev);
    +	if (ssc->ssc_msi_child != NULL)
    +		return (EBUSY);
    +	error = pci_alloc_msi(dev, count);
    +	if (error == 0)
    +		ssc->ssc_msi_child = child;
    +	return (error);
    +}
    +
    +static int
    +siba_bwn_release_msi(device_t dev, device_t child)
    +{
    +	struct siba_bwn_softc *ssc;
    +	int error;
    +
    +	ssc = device_get_softc(dev);
    +	if (ssc->ssc_msi_child != child)
    +		return (ENXIO);
    +	error = pci_release_msi(dev);
    +	if (error == 0)
    +		ssc->ssc_msi_child = NULL;
    +	return (error);
    +}
    +
    +static int
    +siba_bwn_msi_count(device_t dev, device_t child)
    +{
    +
    +	return (pci_msi_count(dev));
    +}
    +
    +static device_method_t siba_bwn_methods[] = {
    +	/* Device interface */
    +	DEVMETHOD(device_probe,		siba_bwn_probe),
    +	DEVMETHOD(device_attach,	siba_bwn_attach),
    +	DEVMETHOD(device_detach,	siba_bwn_detach),
    +	DEVMETHOD(device_shutdown,	siba_bwn_shutdown),
    +	DEVMETHOD(device_suspend,	siba_bwn_suspend),
    +	DEVMETHOD(device_resume,	siba_bwn_resume),
    +
    +	/* Bus interface */
    +	DEVMETHOD(bus_add_child,	siba_bwn_add_child),
    +	DEVMETHOD(bus_alloc_resource,   siba_bwn_alloc_resource),
    +	DEVMETHOD(bus_release_resource, siba_bwn_release_resource),
    +	DEVMETHOD(bus_setup_intr,       siba_bwn_setup_intr),
    +	DEVMETHOD(bus_teardown_intr,    siba_bwn_teardown_intr),
    +
    +	/* PCI interface */
    +	DEVMETHOD(pci_find_extcap,	siba_bwn_find_extcap),
    +	DEVMETHOD(pci_alloc_msi,	siba_bwn_alloc_msi),
    +	DEVMETHOD(pci_release_msi,	siba_bwn_release_msi),
    +	DEVMETHOD(pci_msi_count,	siba_bwn_msi_count),
    +
    +	{ 0,0 }
    +};
    +static driver_t siba_bwn_driver = {
    +	"siba_bwn",
    +	siba_bwn_methods,
    +	sizeof(struct siba_bwn_softc)
    +};
    +static devclass_t siba_bwn_devclass;
    +DRIVER_MODULE(siba_bwn, pci, siba_bwn_driver, siba_bwn_devclass, 0, 0);
    +MODULE_VERSION(siba_bwn, 1);
    diff --git a/sys/dev/siba/siba_cc.c b/sys/dev/siba/siba_cc.c
    index cd78f0b0244..db0aac507be 100644
    --- a/sys/dev/siba/siba_cc.c
    +++ b/sys/dev/siba/siba_cc.c
    @@ -55,9 +55,9 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#include 
    -#include 
     #include 
    +#include 
    +#include 
     
     static int	siba_cc_attach(device_t);
     static int	siba_cc_probe(device_t);
    diff --git a/sys/dev/siba/siba_core.c b/sys/dev/siba/siba_core.c
    new file mode 100644
    index 00000000000..b2168f55971
    --- /dev/null
    +++ b/sys/dev/siba/siba_core.c
    @@ -0,0 +1,2007 @@
    +/*-
    + * Copyright (c) 2009-2010 Weongyo Jeong 
    + * 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.
    + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    + *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
    + *    redistribution must be conditioned upon including a substantially
    + *    similar Disclaimer requirement for further binary redistribution.
    + *
    + * NO WARRANTY
    + * 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 NONINFRINGEMENT, MERCHANTIBILITY
    + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +/*
    + * the Sonics Silicon Backplane driver.
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +#ifdef SIBA_DEBUG
    +enum {
    +	SIBA_DEBUG_SCAN		= 0x00000001,	/* scan */
    +	SIBA_DEBUG_PMU		= 0x00000002,	/* PMU */
    +	SIBA_DEBUG_PLL		= 0x00000004,	/* PLL */
    +	SIBA_DEBUG_SWITCHCORE	= 0x00000008,	/* switching core */
    +	SIBA_DEBUG_SPROM	= 0x00000010,	/* SPROM */
    +	SIBA_DEBUG_CORE		= 0x00000020,	/* handling cores */
    +	SIBA_DEBUG_ANY		= 0xffffffff
    +};
    +#define DPRINTF(siba, m, fmt, ...) do {			\
    +	if (siba->siba_debug & (m))			\
    +		printf(fmt, __VA_ARGS__);		\
    +} while (0)
    +#else
    +#define DPRINTF(siba, m, fmt, ...) do { (void) siba; } while (0)
    +#endif
    +#define	N(a)			(sizeof(a) / sizeof(a[0]))
    +
    +static void	siba_pci_gpio(struct siba_softc *, uint32_t, int);
    +static void	siba_scan(struct siba_softc *);
    +static int	siba_switchcore(struct siba_softc *, uint8_t);
    +static int	siba_pci_switchcore_sub(struct siba_softc *, uint8_t);
    +static uint32_t	siba_scan_read_4(struct siba_softc *, uint8_t, uint16_t);
    +static uint16_t	siba_dev2chipid(struct siba_softc *);
    +static uint16_t	siba_pci_read_2(struct siba_dev_softc *, uint16_t);
    +static uint32_t	siba_pci_read_4(struct siba_dev_softc *, uint16_t);
    +static void	siba_pci_write_2(struct siba_dev_softc *, uint16_t, uint16_t);
    +static void	siba_pci_write_4(struct siba_dev_softc *, uint16_t, uint32_t);
    +static void	siba_cc_clock(struct siba_cc *,
    +		    enum siba_clock);
    +static void	siba_cc_pmu_init(struct siba_cc *);
    +static void	siba_cc_power_init(struct siba_cc *);
    +static void	siba_cc_powerup_delay(struct siba_cc *);
    +static int	siba_cc_clockfreq(struct siba_cc *, int);
    +static void	siba_cc_pmu1_pll0_init(struct siba_cc *, uint32_t);
    +static void	siba_cc_pmu0_pll0_init(struct siba_cc *, uint32_t);
    +static enum siba_clksrc siba_cc_clksrc(struct siba_cc *);
    +static const struct siba_cc_pmu1_plltab *siba_cc_pmu1_plltab_find(uint32_t);
    +static uint32_t	siba_cc_pll_read(struct siba_cc *, uint32_t);
    +static void	siba_cc_pll_write(struct siba_cc *, uint32_t,
    +		    uint32_t);
    +static const struct siba_cc_pmu0_plltab *
    +		siba_cc_pmu0_plltab_findentry(uint32_t);
    +static int	siba_pci_sprom(struct siba_softc *, struct siba_sprom *);
    +static int	siba_sprom_read(struct siba_softc *, uint16_t *, uint16_t);
    +static int	sprom_check_crc(const uint16_t *, size_t);
    +static uint8_t	siba_crc8(uint8_t, uint8_t);
    +static void	siba_sprom_r123(struct siba_sprom *, const uint16_t *);
    +static void	siba_sprom_r45(struct siba_sprom *, const uint16_t *);
    +static void	siba_sprom_r8(struct siba_sprom *, const uint16_t *);
    +static int8_t	siba_sprom_r123_antgain(uint8_t, const uint16_t *, uint16_t,
    +		    uint16_t);
    +static uint32_t	siba_tmslow_reject_bitmask(struct siba_dev_softc *);
    +static uint32_t	siba_pcicore_read_4(struct siba_pci *, uint16_t);
    +static void	siba_pcicore_write_4(struct siba_pci *, uint16_t, uint32_t);
    +static uint32_t	siba_pcie_read(struct siba_pci *, uint32_t);
    +static void	siba_pcie_write(struct siba_pci *, uint32_t, uint32_t);
    +static void	siba_pcie_mdio_write(struct siba_pci *, uint8_t, uint8_t,
    +		    uint16_t);
    +static void	siba_pci_read_multi_1(struct siba_dev_softc *, void *, size_t,
    +		    uint16_t);
    +static void	siba_pci_read_multi_2(struct siba_dev_softc *, void *, size_t,
    +		    uint16_t);
    +static void	siba_pci_read_multi_4(struct siba_dev_softc *, void *, size_t,
    +		    uint16_t);
    +static void	siba_pci_write_multi_1(struct siba_dev_softc *, const void *,
    +		    size_t, uint16_t);
    +static void	siba_pci_write_multi_2(struct siba_dev_softc *, const void *,
    +		    size_t, uint16_t);
    +static void	siba_pci_write_multi_4(struct siba_dev_softc *, const void *,
    +		    size_t, uint16_t);
    +static const char *siba_core_name(uint16_t);
    +static void	siba_pcicore_init(struct siba_pci *);
    +device_t	siba_add_child(device_t, struct siba_softc *, int, const char *,
    +		    int);
    +int		siba_core_attach(struct siba_softc *);
    +int		siba_core_detach(struct siba_softc *);
    +int		siba_core_suspend(struct siba_softc *);
    +int		siba_core_resume(struct siba_softc *);
    +uint8_t		siba_getncores(device_t, uint16_t);
    +
    +static const struct siba_bus_ops siba_pci_ops = {
    +	.read_2		= siba_pci_read_2,
    +	.read_4		= siba_pci_read_4,
    +	.write_2	= siba_pci_write_2,
    +	.write_4	= siba_pci_write_4,
    +	.read_multi_1	= siba_pci_read_multi_1,
    +	.read_multi_2	= siba_pci_read_multi_2,
    +	.read_multi_4	= siba_pci_read_multi_4,
    +	.write_multi_1	= siba_pci_write_multi_1,
    +	.write_multi_2	= siba_pci_write_multi_2,
    +	.write_multi_4	= siba_pci_write_multi_4,
    +};
    +
    +static const struct siba_cc_pmu_res_updown siba_cc_pmu_4325_updown[] =
    +    SIBA_CC_PMU_4325_RES_UPDOWN;
    +static const struct siba_cc_pmu_res_depend siba_cc_pmu_4325_depend[] =
    +    SIBA_CC_PMU_4325_RES_DEPEND;
    +static const struct siba_cc_pmu_res_updown siba_cc_pmu_4328_updown[] =
    +    SIBA_CC_PMU_4328_RES_UPDOWN;
    +static const struct siba_cc_pmu_res_depend siba_cc_pmu_4328_depend[] =
    +    SIBA_CC_PMU_4328_RES_DEPEND;
    +static const struct siba_cc_pmu0_plltab siba_cc_pmu0_plltab[] =
    +    SIBA_CC_PMU0_PLLTAB_ENTRY;
    +static const struct siba_cc_pmu1_plltab siba_cc_pmu1_plltab[] =
    +    SIBA_CC_PMU1_PLLTAB_ENTRY;
    +
    +int
    +siba_core_attach(struct siba_softc *siba)
    +{
    +	struct siba_cc *scc;
    +	int error;
    +
    +	KASSERT(siba->siba_type == SIBA_TYPE_PCI,
    +	    ("unsupported BUS type (%#x)", siba->siba_type));
    +
    +	siba->siba_ops = &siba_pci_ops;
    +
    +	siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 1);
    +	siba_scan(siba);
    +
    +	/* XXX init PCI or PCMCIA host devices */
    +
    +	siba_powerup(siba, 0);
    +
    +	/* init ChipCommon */
    +	scc = &siba->siba_cc;
    +	if (scc->scc_dev != NULL) {
    +		siba_cc_pmu_init(scc);
    +		siba_cc_power_init(scc);
    +		siba_cc_clock(scc, SIBA_CLOCK_FAST);
    +		siba_cc_powerup_delay(scc);
    +	}
    +
    +	/* fetch various internal informations for PCI */
    +	siba->siba_board_vendor = pci_read_config(siba->siba_dev,
    +	    PCIR_SUBVEND_0, 2);
    +	siba->siba_board_type = pci_read_config(siba->siba_dev, PCIR_SUBDEV_0,
    +	    2);
    +	siba->siba_board_rev = pci_read_config(siba->siba_dev, PCIR_REVID, 2);
    +	error = siba_pci_sprom(siba, &siba->siba_sprom);
    +	if (error) {
    +		siba_powerdown(siba);
    +		return (error);
    +	}
    +
    +	siba_powerdown(siba);
    +	return (0);
    +}
    +
    +int
    +siba_core_detach(struct siba_softc *siba)
    +{
    +	device_t *devlistp;
    +	int devcnt, error = 0, i;
    +
    +	error = device_get_children(siba->siba_dev, &devlistp, &devcnt);
    +	if (error != 0)
    +		return (0);
    +
    +	for ( i = 0 ; i < devcnt ; i++)
    +		device_delete_child(siba->siba_dev, devlistp[i]);
    +	free(devlistp, M_TEMP);
    +	return (0);
    +}
    +
    +static void
    +siba_pci_gpio(struct siba_softc *siba, uint32_t what, int on)
    +{
    +	uint32_t in, out;
    +	uint16_t status;
    +
    +	if (siba->siba_type != SIBA_TYPE_PCI)
    +		return;
    +
    +	out = pci_read_config(siba->siba_dev, SIBA_GPIO_OUT, 4);
    +	if (on == 0) {
    +		if (what & SIBA_GPIO_PLL)
    +			out |= SIBA_GPIO_PLL;
    +		if (what & SIBA_GPIO_CRYSTAL)
    +			out &= ~SIBA_GPIO_CRYSTAL;
    +		pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4);
    +		pci_write_config(siba->siba_dev, SIBA_GPIO_OUT_EN,
    +		    pci_read_config(siba->siba_dev,
    +			SIBA_GPIO_OUT_EN, 4) | what, 4);
    +		return;
    +	}
    +
    +	in = pci_read_config(siba->siba_dev, SIBA_GPIO_IN, 4);
    +	if ((in & SIBA_GPIO_CRYSTAL) != SIBA_GPIO_CRYSTAL) {
    +		if (what & SIBA_GPIO_CRYSTAL) {
    +			out |= SIBA_GPIO_CRYSTAL;
    +			if (what & SIBA_GPIO_PLL)
    +				out |= SIBA_GPIO_PLL;
    +			pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4);
    +			pci_write_config(siba->siba_dev,
    +			    SIBA_GPIO_OUT_EN, pci_read_config(siba->siba_dev,
    +				SIBA_GPIO_OUT_EN, 4) | what, 4);
    +			DELAY(1000);
    +		}
    +		if (what & SIBA_GPIO_PLL) {
    +			out &= ~SIBA_GPIO_PLL;
    +			pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4);
    +			DELAY(5000);
    +		}
    +	}
    +
    +	status = pci_read_config(siba->siba_dev, PCIR_STATUS, 2);
    +	status &= ~PCIM_STATUS_STABORT;
    +	pci_write_config(siba->siba_dev, PCIR_STATUS, status, 2);
    +}
    +
    +static void
    +siba_scan(struct siba_softc *siba)
    +{
    +	struct siba_dev_softc *sd;
    +	uint32_t idhi, tmp;
    +	int base, dev_i = 0, error, i, is_pcie, n_80211 = 0, n_cc = 0,
    +	    n_pci = 0;
    +
    +	KASSERT(siba->siba_type == SIBA_TYPE_PCI,
    +	    ("unsupported BUS type (%#x)", siba->siba_type));
    +
    +	siba->siba_ndevs = 0;
    +	error = siba_switchcore(siba, 0); /* need the first core */
    +	if (error)
    +		return;
    +
    +	idhi = siba_scan_read_4(siba, 0, SIBA_IDHIGH);
    +	if (SIBA_IDHIGH_CORECODE(idhi) == SIBA_DEVID_CHIPCOMMON) {
    +		tmp = siba_scan_read_4(siba, 0, SIBA_CC_CHIPID);
    +		siba->siba_chipid = SIBA_CC_ID(tmp);
    +		siba->siba_chiprev = SIBA_CC_REV(tmp);
    +		siba->siba_chippkg = SIBA_CC_PKG(tmp);
    +		if (SIBA_IDHIGH_REV(idhi) >= 4)
    +			siba->siba_ndevs = SIBA_CC_NCORES(tmp);
    +		siba->siba_cc.scc_caps = siba_scan_read_4(siba, 0,
    +		    SIBA_CC_CAPS);
    +	} else {
    +		if (siba->siba_type == SIBA_TYPE_PCI) {
    +			siba->siba_chipid = siba_dev2chipid(siba);
    +			siba->siba_chiprev = pci_read_config(siba->siba_dev,
    +			    PCIR_REVID, 2);
    +			siba->siba_chippkg = 0;
    +		} else {
    +			siba->siba_chipid = 0x4710;
    +			siba->siba_chiprev = 0;
    +			siba->siba_chippkg = 0;
    +		}
    +	}
    +	if (siba->siba_ndevs == 0)
    +		siba->siba_ndevs = siba_getncores(siba->siba_dev,
    +		    siba->siba_chipid);
    +	if (siba->siba_ndevs > SIBA_MAX_CORES) {
    +		device_printf(siba->siba_dev,
    +		    "too many siba cores (max %d %d)\n",
    +		    SIBA_MAX_CORES, siba->siba_ndevs);
    +		return;
    +	}
    +
    +	/* looking basic information about each cores/devices */
    +	for (i = 0; i < siba->siba_ndevs; i++) {
    +		error = siba_switchcore(siba, i);
    +		if (error)
    +			return;
    +		sd = &(siba->siba_devs[dev_i]);
    +		idhi = siba_scan_read_4(siba, i, SIBA_IDHIGH);
    +		sd->sd_bus = siba;
    +		sd->sd_id.sd_device = SIBA_IDHIGH_CORECODE(idhi);
    +		sd->sd_id.sd_rev = SIBA_IDHIGH_REV(idhi);
    +		sd->sd_id.sd_vendor = SIBA_IDHIGH_VENDOR(idhi);
    +		sd->sd_ops = siba->siba_ops;
    +		sd->sd_coreidx = i;
    +
    +		DPRINTF(siba, SIBA_DEBUG_SCAN,
    +		    "core %d (%s) found (cc %#xrev %#x vendor %#x)\n",
    +		    i, siba_core_name(sd->sd_id.sd_device),
    +		    sd->sd_id.sd_device, sd->sd_id.sd_rev, sd->sd_id.vendor);
    +
    +		switch (sd->sd_id.sd_device) {
    +		case SIBA_DEVID_CHIPCOMMON:
    +			n_cc++;
    +			if (n_cc > 1) {
    +				device_printf(siba->siba_dev,
    +				    "warn: multiple ChipCommon\n");
    +				break;
    +			}
    +			siba->siba_cc.scc_dev = sd;
    +			break;
    +		case SIBA_DEVID_80211:
    +			n_80211++;
    +			if (n_80211 > 1) {
    +				device_printf(siba->siba_dev,
    +				    "warn: multiple 802.11 core\n");
    +				continue;
    +			}
    +			break;
    +		case SIBA_DEVID_PCI:
    +		case SIBA_DEVID_PCIE:
    +			n_pci++;
    +			error = pci_find_extcap(siba->siba_dev, PCIY_EXPRESS,
    +			    &base);
    +			is_pcie = (error == 0) ? 1 : 0;
    +
    +			if (n_pci > 1) {
    +				device_printf(siba->siba_dev,
    +				    "warn: multiple PCI(E) cores\n");
    +				break;
    +			}
    +			if (sd->sd_id.sd_device == SIBA_DEVID_PCI &&
    +			    is_pcie == 1)
    +				continue;
    +			if (sd->sd_id.sd_device == SIBA_DEVID_PCIE &&
    +			    is_pcie == 0)
    +				continue;
    +			siba->siba_pci.spc_dev = sd;
    +			break;
    +		case SIBA_DEVID_MODEM:
    +		case SIBA_DEVID_PCMCIA:
    +			break;
    +		default:
    +			device_printf(siba->siba_dev,
    +			    "unsupported coreid (%s)\n",
    +			    siba_core_name(sd->sd_id.sd_device));
    +			break;
    +		}
    +		dev_i++;
    +	}
    +	siba->siba_ndevs = dev_i;
    +}
    +
    +static int
    +siba_switchcore(struct siba_softc *siba, uint8_t idx)
    +{
    +
    +	switch (siba->siba_type) {
    +	case SIBA_TYPE_PCI:
    +		return (siba_pci_switchcore_sub(siba, idx));
    +	default:
    +		KASSERT(0 == 1,
    +		    ("%s: unsupported bustype %#x", __func__,
    +		    siba->siba_type));
    +	}
    +	return (0);
    +}
    +
    +static int
    +siba_pci_switchcore_sub(struct siba_softc *siba, uint8_t idx)
    +{
    +#define RETRY_MAX	50
    +	int i;
    +	uint32_t dir;
    +
    +	dir = SIBA_REGWIN(idx);
    +
    +	for (i = 0; i < RETRY_MAX; i++) {
    +		pci_write_config(siba->siba_dev, SIBA_BAR0, dir, 4);
    +		if (pci_read_config(siba->siba_dev, SIBA_BAR0, 4) == dir)
    +			return (0);
    +		DELAY(10);
    +	}
    +	return (ENODEV);
    +#undef RETRY_MAX
    +}
    +
    +static int
    +siba_pci_switchcore(struct siba_softc *siba, struct siba_dev_softc *sd)
    +{
    +	int error;
    +
    +	DPRINTF(siba, SIBA_DEBUG_SWITCHCORE, "Switching to %s core, index %d\n",
    +	    siba_core_name(sd->sd_id.sd_device), sd->sd_coreidx);
    +
    +	error = siba_pci_switchcore_sub(siba, sd->sd_coreidx);
    +	if (error == 0)
    +		siba->siba_curdev = sd;
    +
    +	return (error);
    +}
    +
    +static uint32_t
    +siba_scan_read_4(struct siba_softc *siba, uint8_t coreidx,
    +    uint16_t offset)
    +{
    +
    +	(void)coreidx;
    +	KASSERT(siba->siba_type == SIBA_TYPE_PCI,
    +	    ("unsupported BUS type (%#x)", siba->siba_type));
    +
    +	return (SIBA_READ_4(siba, offset));
    +}
    +
    +static uint16_t
    +siba_dev2chipid(struct siba_softc *siba)
    +{
    +	uint16_t chipid = 0;
    +
    +	switch (siba->siba_pci_did) {
    +	case 0x4301:
    +		chipid = 0x4301;
    +		break;
    +	case 0x4305:
    +	case 0x4306:
    +	case 0x4307:
    +		chipid = 0x4307;
    +		break;
    +	case 0x4403:
    +		chipid = 0x4402;
    +		break;
    +	case 0x4610:
    +	case 0x4611:
    +	case 0x4612:
    +	case 0x4613:
    +	case 0x4614:
    +	case 0x4615:
    +		chipid = 0x4610;
    +		break;
    +	case 0x4710:
    +	case 0x4711:
    +	case 0x4712:
    +	case 0x4713:
    +	case 0x4714:
    +	case 0x4715:
    +		chipid = 0x4710;
    +		break;
    +	case 0x4320:
    +	case 0x4321:
    +	case 0x4322:
    +	case 0x4323:
    +	case 0x4324:
    +	case 0x4325:
    +		chipid = 0x4309;
    +		break;
    +	case PCI_DEVICE_ID_BCM4401:
    +	case PCI_DEVICE_ID_BCM4401B0:
    +	case PCI_DEVICE_ID_BCM4401B1:
    +		chipid = 0x4401;
    +		break;
    +	default:
    +		device_printf(siba->siba_dev, "unknown PCI did (%d)\n",
    +		    siba->siba_pci_did);
    +	}
    +
    +	return (chipid);
    +}
    +
    +/*
    + * Earlier ChipCommon revisions have hardcoded number of cores
    + * present dependent on the ChipCommon ID.
    + */
    +uint8_t
    +siba_getncores(device_t dev, uint16_t chipid)
    +{
    +	switch (chipid) {
    +	case 0x4401:
    +	case 0x4402:
    +		return (3);
    +	case 0x4301:
    +	case 0x4307:
    +		return (5);
    +	case 0x4306:
    +		return (6);
    +	case SIBA_CCID_SENTRY5:
    +		return (7);
    +	case 0x4310:
    +		return (8);
    +	case SIBA_CCID_BCM4710:
    +	case 0x4610:
    +	case SIBA_CCID_BCM4704:
    +		return (9);
    +	default:
    +		device_printf(dev, "unknown the chipset ID %#x\n", chipid);
    +	}
    +
    +	return (1);
    +}
    +
    +static const char *
    +siba_core_name(uint16_t coreid)
    +{
    +
    +	switch (coreid) {
    +	case SIBA_DEVID_CHIPCOMMON:
    +		return ("ChipCommon");
    +	case SIBA_DEVID_ILINE20:
    +		return ("ILine 20");
    +	case SIBA_DEVID_SDRAM:
    +		return ("SDRAM");
    +	case SIBA_DEVID_PCI:
    +		return ("PCI");
    +	case SIBA_DEVID_MIPS:
    +		return ("MIPS");
    +	case SIBA_DEVID_ETHERNET:
    +		return ("Fast Ethernet");
    +	case SIBA_DEVID_MODEM:
    +		return ("Modem");
    +	case SIBA_DEVID_USB11_HOSTDEV:
    +		return ("USB 1.1 Hostdev");
    +	case SIBA_DEVID_ADSL:
    +		return ("ADSL");
    +	case SIBA_DEVID_ILINE100:
    +		return ("ILine 100");
    +	case SIBA_DEVID_IPSEC:
    +		return ("IPSEC");
    +	case SIBA_DEVID_PCMCIA:
    +		return ("PCMCIA");
    +	case SIBA_DEVID_INTERNAL_MEM:
    +		return ("Internal Memory");
    +	case SIBA_DEVID_SDRAMDDR:
    +		return ("MEMC SDRAM");
    +	case SIBA_DEVID_EXTIF:
    +		return ("EXTIF");
    +	case SIBA_DEVID_80211:
    +		return ("IEEE 802.11");
    +	case SIBA_DEVID_MIPS_3302:
    +		return ("MIPS 3302");
    +	case SIBA_DEVID_USB11_HOST:
    +		return ("USB 1.1 Host");
    +	case SIBA_DEVID_USB11_DEV:
    +		return ("USB 1.1 Device");
    +	case SIBA_DEVID_USB20_HOST:
    +		return ("USB 2.0 Host");
    +	case SIBA_DEVID_USB20_DEV:
    +		return ("USB 2.0 Device");
    +	case SIBA_DEVID_SDIO_HOST:
    +		return ("SDIO Host");
    +	case SIBA_DEVID_ROBOSWITCH:
    +		return ("Roboswitch");
    +	case SIBA_DEVID_PARA_ATA:
    +		return ("PATA");
    +	case SIBA_DEVID_SATA_XORDMA:
    +		return ("SATA XOR-DMA");
    +	case SIBA_DEVID_ETHERNET_GBIT:
    +		return ("GBit Ethernet");
    +	case SIBA_DEVID_PCIE:
    +		return ("PCI-Express");
    +	case SIBA_DEVID_MIMO_PHY:
    +		return ("MIMO PHY");
    +	case SIBA_DEVID_SRAM_CTRLR:
    +		return ("SRAM Controller");
    +	case SIBA_DEVID_MINI_MACPHY:
    +		return ("Mini MACPHY");
    +	case SIBA_DEVID_ARM_1176:
    +		return ("ARM 1176");
    +	case SIBA_DEVID_ARM_7TDMI:
    +		return ("ARM 7TDMI");
    +	}
    +	return ("unknown");
    +}
    +
    +static uint16_t
    +siba_pci_read_2(struct siba_dev_softc *sd, uint16_t offset)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0)
    +		return (0xffff);
    +
    +	return (SIBA_READ_2(siba, offset));
    +}
    +
    +static uint32_t
    +siba_pci_read_4(struct siba_dev_softc *sd, uint16_t offset)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0)
    +		return (0xffff);
    +
    +	return (SIBA_READ_4(siba, offset));
    +}
    +
    +static void
    +siba_pci_write_2(struct siba_dev_softc *sd, uint16_t offset, uint16_t value)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0)
    +		return;
    +
    +	SIBA_WRITE_2(siba, offset, value);
    +}
    +
    +static void
    +siba_pci_write_4(struct siba_dev_softc *sd, uint16_t offset, uint32_t value)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0)
    +		return;
    +
    +	SIBA_WRITE_4(siba, offset, value);
    +}
    +
    +static void
    +siba_pci_read_multi_1(struct siba_dev_softc *sd, void *buffer, size_t count,
    +    uint16_t offset)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) {
    +		memset(buffer, 0xff, count);
    +		return;
    +	}
    +
    +	SIBA_READ_MULTI_1(siba, offset, buffer, count);
    +}
    +
    +static void
    +siba_pci_read_multi_2(struct siba_dev_softc *sd, void *buffer, size_t count,
    +    uint16_t offset)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) {
    +		memset(buffer, 0xff, count);
    +		return;
    +	}
    +
    +	KASSERT(!(count & 1), ("%s:%d: fail", __func__, __LINE__));
    +	SIBA_READ_MULTI_2(siba, offset, buffer, count >> 1);
    +}
    +
    +static void
    +siba_pci_read_multi_4(struct siba_dev_softc *sd, void *buffer, size_t count,
    +    uint16_t offset)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) {
    +		memset(buffer, 0xff, count);
    +		return;
    +	}
    +
    +	KASSERT(!(count & 3), ("%s:%d: fail", __func__, __LINE__));
    +	SIBA_READ_MULTI_4(siba, offset, buffer, count >> 2);
    +}
    +
    +static void
    +siba_pci_write_multi_1(struct siba_dev_softc *sd, const void *buffer,
    +    size_t count, uint16_t offset)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0)
    +		return;
    +
    +	SIBA_WRITE_MULTI_1(siba, offset, buffer, count);
    +}
    +
    +static void
    +siba_pci_write_multi_2(struct siba_dev_softc *sd, const void *buffer,
    +    size_t count, uint16_t offset)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0)
    +		return;
    +
    +	KASSERT(!(count & 1), ("%s:%d: fail", __func__, __LINE__));
    +	SIBA_WRITE_MULTI_2(siba, offset, buffer, count >> 1);
    +}
    +
    +static void
    +siba_pci_write_multi_4(struct siba_dev_softc *sd, const void *buffer,
    +    size_t count, uint16_t offset)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0)
    +		return;
    +
    +	KASSERT(!(count & 3), ("%s:%d: fail", __func__, __LINE__));
    +	SIBA_WRITE_MULTI_4(siba, offset, buffer, count >> 2);
    +}
    +
    +void
    +siba_powerup(struct siba_softc *siba, int dynamic)
    +{
    +
    +	siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 1);
    +	siba_cc_clock(&siba->siba_cc,
    +	    (dynamic != 0) ? SIBA_CLOCK_DYNAMIC : SIBA_CLOCK_FAST);
    +}
    +
    +static void
    +siba_cc_clock(struct siba_cc *scc, enum siba_clock clock)
    +{
    +	struct siba_dev_softc *sd = scc->scc_dev;
    +	struct siba_softc *siba;
    +	uint32_t tmp;
    +
    +	if (sd == NULL)
    +		return;
    +	siba = sd->sd_bus;
    +	/*
    +	 * chipcommon < r6 (no dynamic clock control)
    +	 * chipcommon >= r10 (unknown)
    +	 */
    +	if (sd->sd_id.sd_rev < 6 || sd->sd_id.sd_rev >= 10 ||
    +	    (scc->scc_caps & SIBA_CC_CAPS_PWCTL) == 0)
    +		return;
    +
    +	switch (clock) {
    +	case SIBA_CLOCK_DYNAMIC:
    +		tmp = SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) &
    +		    ~(SIBA_CC_CLKSLOW_ENXTAL | SIBA_CC_CLKSLOW_FSLOW |
    +		    SIBA_CC_CLKSLOW_IPLL);
    +		if ((tmp & SIBA_CC_CLKSLOW_SRC) != SIBA_CC_CLKSLOW_SRC_CRYSTAL)
    +			tmp |= SIBA_CC_CLKSLOW_ENXTAL;
    +		SIBA_CC_WRITE32(scc, SIBA_CC_CLKSLOW, tmp);
    +		if (tmp & SIBA_CC_CLKSLOW_ENXTAL)
    +			siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL, 0);
    +		break;
    +	case SIBA_CLOCK_SLOW:
    +		SIBA_CC_WRITE32(scc, SIBA_CC_CLKSLOW,
    +		    SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) |
    +		    SIBA_CC_CLKSLOW_FSLOW);
    +		break;
    +	case SIBA_CLOCK_FAST:
    +		/* crystal on */
    +		siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL, 1);
    +		SIBA_CC_WRITE32(scc, SIBA_CC_CLKSLOW,
    +		    (SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) |
    +			SIBA_CC_CLKSLOW_IPLL) & ~SIBA_CC_CLKSLOW_FSLOW);
    +		break;
    +	default:
    +		KASSERT(0 == 1,
    +		    ("%s: unsupported clock %#x", __func__, clock));
    +	}
    +}
    +
    +uint16_t
    +siba_read_2(struct siba_dev_softc *sd, uint16_t offset)
    +{
    +
    +	return (sd->sd_ops->read_2(sd, offset));
    +}
    +
    +uint32_t
    +siba_read_4(struct siba_dev_softc *sd, uint16_t offset)
    +{
    +
    +	return (sd->sd_ops->read_4(sd, offset));
    +}
    +
    +void
    +siba_write_2(struct siba_dev_softc *sd, uint16_t offset, uint16_t value)
    +{
    +
    +	sd->sd_ops->write_2(sd, offset, value);
    +}
    +
    +void
    +siba_write_4(struct siba_dev_softc *sd, uint16_t offset, uint32_t value)
    +{
    +
    +	sd->sd_ops->write_4(sd, offset, value);
    +}
    +
    +void
    +siba_read_multi_1(struct siba_dev_softc *sd, void *buffer, size_t count,
    +    uint16_t offset)
    +{
    +
    +	sd->sd_ops->read_multi_1(sd, buffer, count, offset);
    +}
    +
    +void
    +siba_read_multi_2(struct siba_dev_softc *sd, void *buffer, size_t count,
    +    uint16_t offset)
    +{
    +
    +	sd->sd_ops->read_multi_2(sd, buffer, count, offset);
    +}
    +
    +void
    +siba_read_multi_4(struct siba_dev_softc *sd, void *buffer, size_t count,
    +    uint16_t offset)
    +{
    +
    +	sd->sd_ops->read_multi_4(sd, buffer, count, offset);
    +}
    +
    +void
    +siba_write_multi_1(struct siba_dev_softc *sd, const void *buffer,
    +    size_t count, uint16_t offset)
    +{
    +
    +	sd->sd_ops->write_multi_1(sd, buffer, count, offset);
    +}
    +
    +void
    +siba_write_multi_2(struct siba_dev_softc *sd, const void *buffer,
    +    size_t count, uint16_t offset)
    +{
    +
    +	sd->sd_ops->write_multi_2(sd, buffer, count, offset);
    +}
    +
    +void
    +siba_write_multi_4(struct siba_dev_softc *sd, const void *buffer,
    +    size_t count, uint16_t offset)
    +{
    +
    +	sd->sd_ops->write_multi_4(sd, buffer, count, offset);
    +}
    +
    +static void
    +siba_cc_pmu_init(struct siba_cc *scc)
    +{
    +	const struct siba_cc_pmu_res_updown *updown = NULL;
    +	const struct siba_cc_pmu_res_depend *depend = NULL;
    +	struct siba_dev_softc *sd = scc->scc_dev;
    +	struct siba_softc *siba = sd->sd_bus;
    +	uint32_t min = 0, max = 0, pmucap;
    +	unsigned int i, updown_size, depend_size;
    +
    +	if ((scc->scc_caps & SIBA_CC_CAPS_PMU) == 0)
    +		return;
    +
    +	pmucap = SIBA_CC_READ32(scc, SIBA_CC_PMUCAPS);
    +	scc->scc_pmu.rev = (pmucap & SIBA_CC_PMUCAPS_REV);
    +
    +	DPRINTF(siba, SIBA_DEBUG_PMU, "PMU(r%u) found (caps %#x)\n",
    +	    scc->scc_pmu.rev, pmucap);
    +
    +	if (scc->scc_pmu.rev >= 1) {
    +		if (siba->siba_chiprev < 2 && siba->siba_chipid == 0x4325)
    +			SIBA_CC_MASK32(scc, SIBA_CC_PMUCTL,
    +			    ~SIBA_CC_PMUCTL_NOILP);
    +		else
    +			SIBA_CC_SET32(scc, SIBA_CC_PMUCTL,
    +			    SIBA_CC_PMUCTL_NOILP);
    +	}
    +
    +	/* initialize PLL & PMU resources */
    +	switch (siba->siba_chipid) {
    +	case 0x4312:
    +		siba_cc_pmu1_pll0_init(scc, 0 /* use default */);
    +		/* use the default: min = 0xcbb max = 0x7ffff */
    +		break;
    +	case 0x4325:
    +		siba_cc_pmu1_pll0_init(scc, 0 /* use default */);
    +
    +		updown = siba_cc_pmu_4325_updown;
    +		updown_size = N(siba_cc_pmu_4325_updown);
    +		depend = siba_cc_pmu_4325_depend;
    +		depend_size = N(siba_cc_pmu_4325_depend);
    +
    +		min = (1 << SIBA_CC_PMU_4325_BURST) |
    +		    (1 << SIBA_CC_PMU_4325_LN);
    +		if (SIBA_CC_READ32(scc, SIBA_CC_CHIPSTAT) &
    +		    SIBA_CC_CHST_4325_PMUTOP_2B)
    +			min |= (1 << SIBA_CC_PMU_4325_CLBURST);
    +		max = 0xfffff;
    +		break;
    +	case 0x4328:
    +		siba_cc_pmu0_pll0_init(scc, 0 /* use default */);
    +
    +		updown = siba_cc_pmu_4328_updown;
    +		updown_size = N(siba_cc_pmu_4328_updown);
    +		depend = siba_cc_pmu_4328_depend;
    +		depend_size = N(siba_cc_pmu_4328_depend);
    +
    +		min = (1 << SIBA_CC_PMU_4328_EXT_SWITCH_PWM) |
    +			  (1 << SIBA_CC_PMU_4328_BB_SWITCH_PWM) |
    +			  (1 << SIBA_CC_PMU_4328_CRYSTAL_EN);
    +
    +		max = 0xfffff;
    +		break;
    +	case 0x5354:
    +		siba_cc_pmu0_pll0_init(scc, 0 /* use default */);
    +
    +		max = 0xfffff;
    +		break;
    +	default:
    +		device_printf(siba->siba_dev,
    +		    "unknown chipid %#x for PLL & PMU init\n",
    +		    siba->siba_chipid);
    +	}
    +
    +	if (updown) {
    +		for (i = 0; i < updown_size; i++) {
    +			SIBA_CC_WRITE32(scc, SIBA_CC_PMU_TABSEL,
    +			    updown[i].res);
    +			SIBA_CC_WRITE32(scc, SIBA_CC_PMU_UPDNTM,
    +			    updown[i].updown);
    +		}
    +	}
    +	if (depend) {
    +		for (i = 0; i < depend_size; i++) {
    +			SIBA_CC_WRITE32(scc, SIBA_CC_PMU_TABSEL,
    +			    depend[i].res);
    +			switch (depend[i].task) {
    +			case SIBA_CC_PMU_DEP_SET:
    +				SIBA_CC_WRITE32(scc, SIBA_CC_PMU_DEPMSK,
    +				    depend[i].depend);
    +				break;
    +			case SIBA_CC_PMU_DEP_ADD:
    +				SIBA_CC_SET32(scc, SIBA_CC_PMU_DEPMSK,
    +				    depend[i].depend);
    +				break;
    +			case SIBA_CC_PMU_DEP_REMOVE:
    +				SIBA_CC_MASK32(scc, SIBA_CC_PMU_DEPMSK,
    +				    ~(depend[i].depend));
    +				break;
    +			default:
    +				KASSERT(0 == 1,
    +				    ("%s:%d: assertion failed",
    +					__func__, __LINE__));
    +			}
    +		}
    +	}
    +
    +	if (min)
    +		SIBA_CC_WRITE32(scc, SIBA_CC_PMU_MINRES, min);
    +	if (max)
    +		SIBA_CC_WRITE32(scc, SIBA_CC_PMU_MAXRES, max);
    +}
    +
    +static void
    +siba_cc_power_init(struct siba_cc *scc)
    +{
    +	struct siba_softc *siba = scc->scc_dev->sd_bus;
    +	int maxfreq;
    +
    +	if (siba->siba_chipid == 0x4321) {
    +		if (siba->siba_chiprev == 0)
    +			SIBA_CC_WRITE32(scc, SIBA_CC_CHIPCTL, 0x3a4);
    +		else if (siba->siba_chiprev == 1)
    +			SIBA_CC_WRITE32(scc, SIBA_CC_CHIPCTL, 0xa4);
    +	}
    +
    +	if ((scc->scc_caps & SIBA_CC_CAPS_PWCTL) == 0)
    +		return;
    +
    +	if (scc->scc_dev->sd_id.sd_rev >= 10)
    +		SIBA_CC_WRITE32(scc, SIBA_CC_CLKSYSCTL,
    +		    (SIBA_CC_READ32(scc, SIBA_CC_CLKSYSCTL) &
    +		    0xffff) | 0x40000);
    +	else {
    +		maxfreq = siba_cc_clockfreq(scc, 1);
    +		SIBA_CC_WRITE32(scc, SIBA_CC_PLLONDELAY,
    +		    (maxfreq * 150 + 999999) / 1000000);
    +		SIBA_CC_WRITE32(scc, SIBA_CC_FREFSELDELAY,
    +		    (maxfreq * 15 + 999999) / 1000000);
    +	}
    +}
    +
    +static void
    +siba_cc_powerup_delay(struct siba_cc *scc)
    +{
    +	struct siba_softc *siba = scc->scc_dev->sd_bus;
    +	int min;
    +
    +	if (siba->siba_type != SIBA_TYPE_PCI ||
    +	    !(scc->scc_caps & SIBA_CC_CAPS_PWCTL))
    +		return;
    +
    +	min = siba_cc_clockfreq(scc, 0);
    +	scc->scc_powerup_delay =
    +	    (((SIBA_CC_READ32(scc, SIBA_CC_PLLONDELAY) + 2) * 1000000) +
    +	    (min - 1)) / min;
    +}
    +
    +static int
    +siba_cc_clockfreq(struct siba_cc *scc, int max)
    +{
    +	enum siba_clksrc src;
    +	int div = 1, limit = 0;
    +
    +	src = siba_cc_clksrc(scc);
    +	if (scc->scc_dev->sd_id.sd_rev < 6) {
    +		div = (src == SIBA_CC_CLKSRC_PCI) ? 64 :
    +		    (src == SIBA_CC_CLKSRC_CRYSTAL) ? 32 : 1;
    +		KASSERT(div != 1,
    +		    ("%s: unknown clock %d", __func__, src));
    +	} else if (scc->scc_dev->sd_id.sd_rev < 10) {
    +		switch (src) {
    +		case SIBA_CC_CLKSRC_CRYSTAL:
    +		case SIBA_CC_CLKSRC_PCI:
    +			div = ((SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) >> 16) +
    +			    1) * 4;
    +			break;
    +		case SIBA_CC_CLKSRC_LOWPW:
    +			break;
    +		}
    +	} else
    +		div = ((SIBA_CC_READ32(scc, SIBA_CC_CLKSYSCTL) >> 16) + 1) * 4;
    +
    +	switch (src) {
    +	case SIBA_CC_CLKSRC_CRYSTAL:
    +		limit = (max) ? 20200000 : 19800000;
    +		break;
    +	case SIBA_CC_CLKSRC_LOWPW:
    +		limit = (max) ? 43000 : 25000;
    +		break;
    +	case SIBA_CC_CLKSRC_PCI:
    +		limit = (max) ? 34000000 : 25000000;
    +		break;
    +	}
    +
    +	return (limit / div);
    +}
    +
    +static void
    +siba_cc_pmu1_pll0_init(struct siba_cc *scc, uint32_t freq)
    +{
    +	struct siba_dev_softc *sd = scc->scc_dev;
    +	struct siba_softc *siba = sd->sd_bus;
    +	const struct siba_cc_pmu1_plltab *e = NULL;
    +	uint32_t bufsth = 0, pll, pmu;
    +	unsigned int i;
    +
    +	KASSERT(freq == 0, ("%s:%d: assertion vail", __func__, __LINE__));
    +	if (siba->siba_chipid == 0x4312) {
    +		scc->scc_pmu.freq = 20000;
    +		return;
    +	}
    +
    +	e = siba_cc_pmu1_plltab_find(SIBA_CC_PMU1_DEFAULT_FREQ);
    +	KASSERT(e != NULL, ("%s:%d: assertion vail", __func__, __LINE__));
    +	scc->scc_pmu.freq = e->freq;
    +
    +	pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL);
    +	if (SIBA_CC_PMUCTL_XF_VAL(pmu) == e->xf)
    +		return;
    +
    +	DPRINTF(siba, SIBA_DEBUG_PLL, "change PLL value to %u.%03u MHz\n",
    +	    (e->freq / 1000), (e->freq % 1000));
    +
    +	/* turn PLL off */
    +	switch (siba->siba_chipid) {
    +	case 0x4325:
    +		bufsth = 0x222222;
    +		SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES,
    +		    ~((1 << SIBA_CC_PMU_4325_BBPLL_PWR) |
    +		      (1 << SIBA_CC_PMU_4325_HT)));
    +		SIBA_CC_MASK32(scc, SIBA_CC_PMU_MAXRES,
    +		    ~((1 << SIBA_CC_PMU_4325_BBPLL_PWR) |
    +		      (1 << SIBA_CC_PMU_4325_HT)));
    +		break;
    +	default:
    +		KASSERT(0 == 1,
    +		    ("%s:%d: assertion failed", __func__, __LINE__));
    +	}
    +	for (i = 0; i < 1500; i++) {
    +		if (!(SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS) &
    +		      SIBA_CC_CLKCTLSTATUS_HT))
    +			break;
    +		DELAY(10);
    +	}
    +	if (SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS) & SIBA_CC_CLKCTLSTATUS_HT)
    +		device_printf(siba->siba_dev, "failed to turn PLL off!\n");
    +
    +	pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL0);
    +	pll &= ~(SIBA_CC_PMU1_PLL0_P1DIV | SIBA_CC_PMU1_PLL0_P2DIV);
    +	pll |= ((uint32_t)e->p1div << 20) & SIBA_CC_PMU1_PLL0_P1DIV;
    +	pll |= ((uint32_t)e->p2div << 24) & SIBA_CC_PMU1_PLL0_P2DIV;
    +	siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL0, pll);
    +
    +	pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL2);
    +	pll &= ~(SIBA_CC_PMU1_PLL2_NDIVINT | SIBA_CC_PMU1_PLL2_NDIVMODE);
    +	pll |= ((uint32_t)e->ndiv_int << 20) & SIBA_CC_PMU1_PLL2_NDIVINT;
    +	pll |= (1 << 17) & SIBA_CC_PMU1_PLL2_NDIVMODE;
    +	siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL2, pll);
    +
    +	pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL3);
    +	pll &= ~SIBA_CC_PMU1_PLL3_NDIVFRAC;
    +	pll |= ((uint32_t)e->ndiv_frac << 0) & SIBA_CC_PMU1_PLL3_NDIVFRAC;
    +	siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL3, pll);
    +
    +	if (bufsth) {
    +		pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL5);
    +		pll &= ~SIBA_CC_PMU1_PLL5_CLKDRV;
    +		pll |= (bufsth << 8) & SIBA_CC_PMU1_PLL5_CLKDRV;
    +		siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL5, pll);
    +	}
    +
    +	pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL);
    +	pmu &= ~(SIBA_CC_PMUCTL_ILP | SIBA_CC_PMUCTL_XF);
    +	pmu |= ((((uint32_t)e->freq + 127) / 128 - 1) << 16) &
    +	    SIBA_CC_PMUCTL_ILP;
    +	pmu |= ((uint32_t)e->xf << 2) & SIBA_CC_PMUCTL_XF;
    +	SIBA_CC_WRITE32(scc, SIBA_CC_PMUCTL, pmu);
    +}
    +
    +static void
    +siba_cc_pmu0_pll0_init(struct siba_cc *scc, uint32_t xtalfreq)
    +{
    +	struct siba_dev_softc *sd = scc->scc_dev;
    +	struct siba_softc *siba = sd->sd_bus;
    +	const struct siba_cc_pmu0_plltab *e = NULL;
    +	uint32_t pmu, tmp, pll;
    +	unsigned int i;
    +
    +	if ((siba->siba_chipid == 0x5354) && !xtalfreq)
    +		xtalfreq = 25000;
    +	if (xtalfreq)
    +		e = siba_cc_pmu0_plltab_findentry(xtalfreq);
    +	if (!e)
    +		e = siba_cc_pmu0_plltab_findentry(
    +		    SIBA_CC_PMU0_DEFAULT_XTALFREQ);
    +	KASSERT(e != NULL, ("%s:%d: fail", __func__, __LINE__));
    +	xtalfreq = e->freq;
    +	scc->scc_pmu.freq = e->freq;
    +
    +	pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL);
    +	if (((pmu & SIBA_CC_PMUCTL_XF) >> 2) == e->xf)
    +		return;
    +
    +	DPRINTF(siba, SIBA_DEBUG_PLL, "change PLL value to %u.%03u mhz\n",
    +	    (xtalfreq / 1000), (xtalfreq % 1000));
    +
    +	KASSERT(siba->siba_chipid == 0x4328 || siba->siba_chipid == 0x5354,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	switch (siba->siba_chipid) {
    +	case 0x4328:
    +		SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES,
    +		    ~(1 << SIBA_CC_PMU_4328_BB_PLL_PU));
    +		SIBA_CC_MASK32(scc, SIBA_CC_PMU_MAXRES,
    +		    ~(1 << SIBA_CC_PMU_4328_BB_PLL_PU));
    +		break;
    +	case 0x5354:
    +		SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES,
    +		    ~(1 << SIBA_CC_PMU_5354_BB_PLL_PU));
    +		SIBA_CC_MASK32(scc, SIBA_CC_PMU_MAXRES,
    +		    ~(1 << SIBA_CC_PMU_5354_BB_PLL_PU));
    +		break;
    +	}
    +	for (i = 1500; i; i--) {
    +		tmp = SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS);
    +		if (!(tmp & SIBA_CC_CLKCTLSTATUS_HT))
    +			break;
    +		DELAY(10);
    +	}
    +	tmp = SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS);
    +	if (tmp & SIBA_CC_CLKCTLSTATUS_HT)
    +		device_printf(siba->siba_dev, "failed to turn PLL off!\n");
    +
    +	/* set PDIV */
    +	pll = siba_cc_pll_read(scc, SIBA_CC_PMU0_PLL0);
    +	if (xtalfreq >= SIBA_CC_PMU0_PLL0_PDIV_FREQ)
    +		pll |= SIBA_CC_PMU0_PLL0_PDIV_MSK;
    +	else
    +		pll &= ~SIBA_CC_PMU0_PLL0_PDIV_MSK;
    +	siba_cc_pll_write(scc, SIBA_CC_PMU0_PLL0, pll);
    +
    +	/* set WILD */
    +	pll = siba_cc_pll_read(scc, SIBA_CC_PMU0_PLL1);
    +	pll &= ~(SIBA_CC_PMU0_PLL1_STOPMOD | SIBA_CC_PMU0_PLL1_IMSK |
    +	    SIBA_CC_PMU0_PLL1_FMSK);
    +	pll |= ((uint32_t)e->wb_int << 28) & SIBA_CC_PMU0_PLL1_IMSK;
    +	pll |= ((uint32_t)e->wb_frac << 8) & SIBA_CC_PMU0_PLL1_FMSK;
    +	if (e->wb_frac == 0)
    +		pll |= SIBA_CC_PMU0_PLL1_STOPMOD;
    +	siba_cc_pll_write(scc, SIBA_CC_PMU0_PLL1, pll);
    +
    +	/* set WILD */
    +	pll = siba_cc_pll_read(scc, SIBA_CC_PMU0_PLL2);
    +	pll &= ~SIBA_CC_PMU0_PLL2_IMSKHI;
    +	pll |= (((uint32_t)e->wb_int >> 4) << 0) & SIBA_CC_PMU0_PLL2_IMSKHI;
    +	siba_cc_pll_write(scc, SIBA_CC_PMU0_PLL2, pll);
    +
    +	/* set freq and divisor. */
    +	pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL);
    +	pmu &= ~SIBA_CC_PMUCTL_ILP;
    +	pmu |= (((xtalfreq + 127) / 128 - 1) << 16) & SIBA_CC_PMUCTL_ILP;
    +	pmu &= ~SIBA_CC_PMUCTL_XF;
    +	pmu |= ((uint32_t)e->xf << 2) & SIBA_CC_PMUCTL_XF;
    +	SIBA_CC_WRITE32(scc, SIBA_CC_PMUCTL, pmu);
    +}
    +
    +static enum siba_clksrc
    +siba_cc_clksrc(struct siba_cc *scc)
    +{
    +	struct siba_dev_softc *sd = scc->scc_dev;
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	if (sd->sd_id.sd_rev < 6) {
    +		if (siba->siba_type == SIBA_TYPE_PCI) {
    +			if (pci_read_config(siba->siba_dev, SIBA_GPIO_OUT, 4) &
    +			    0x10)
    +				return (SIBA_CC_CLKSRC_PCI);
    +			return (SIBA_CC_CLKSRC_CRYSTAL);
    +		}
    +		if (siba->siba_type == SIBA_TYPE_SSB ||
    +		    siba->siba_type == SIBA_TYPE_PCMCIA)
    +			return (SIBA_CC_CLKSRC_CRYSTAL);
    +	}
    +	if (sd->sd_id.sd_rev < 10) {
    +		switch (SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) & 0x7) {
    +		case 0:
    +			return (SIBA_CC_CLKSRC_LOWPW);
    +		case 1:
    +			return (SIBA_CC_CLKSRC_CRYSTAL);
    +		case 2:
    +			return (SIBA_CC_CLKSRC_PCI);
    +		default:
    +			break;
    +		}
    +	}
    +
    +	return (SIBA_CC_CLKSRC_CRYSTAL);
    +}
    +
    +static const struct siba_cc_pmu1_plltab *
    +siba_cc_pmu1_plltab_find(uint32_t crystalfreq)
    +{
    +	const struct siba_cc_pmu1_plltab *e;
    +	unsigned int i;
    +
    +	for (i = 0; i < N(siba_cc_pmu1_plltab); i++) {
    +		e = &siba_cc_pmu1_plltab[i];
    +		if (crystalfreq == e->freq)
    +			return (e);
    +	}
    +
    +	return (NULL);
    +}
    +
    +static uint32_t
    +siba_cc_pll_read(struct siba_cc *scc, uint32_t offset)
    +{
    +
    +	SIBA_CC_WRITE32(scc, SIBA_CC_PLLCTL_ADDR, offset);
    +	return (SIBA_CC_READ32(scc, SIBA_CC_PLLCTL_DATA));
    +}
    +
    +static void
    +siba_cc_pll_write(struct siba_cc *scc, uint32_t offset, uint32_t value)
    +{
    +
    +	SIBA_CC_WRITE32(scc, SIBA_CC_PLLCTL_ADDR, offset);
    +	SIBA_CC_WRITE32(scc, SIBA_CC_PLLCTL_DATA, value);
    +}
    +
    +static const struct siba_cc_pmu0_plltab *
    +siba_cc_pmu0_plltab_findentry(uint32_t crystalfreq)
    +{
    +	const struct siba_cc_pmu0_plltab *e;
    +	unsigned int i;
    +
    +	for (i = 0; i < N(siba_cc_pmu0_plltab); i++) {
    +		e = &siba_cc_pmu0_plltab[i];
    +		if (e->freq == crystalfreq)
    +			return (e);
    +	}
    +
    +	return (NULL);
    +}
    +
    +static int
    +siba_pci_sprom(struct siba_softc *siba, struct siba_sprom *sprom)
    +{
    +	int error = ENOMEM;
    +	uint16_t *buf;
    +
    +	buf = malloc(SIBA_SPROMSIZE_R123 * sizeof(uint16_t),
    +	    M_DEVBUF, M_NOWAIT | M_ZERO);
    +	if (buf == NULL)
    +		return (ENOMEM);
    +	siba_sprom_read(siba, buf, SIBA_SPROMSIZE_R123);
    +	error = sprom_check_crc(buf, siba->siba_spromsize);
    +	if (error) {
    +		free(buf, M_DEVBUF);
    +		buf = malloc(SIBA_SPROMSIZE_R4 * sizeof(uint16_t),
    +		    M_DEVBUF, M_NOWAIT | M_ZERO);
    +		if (buf == NULL)
    +			return (ENOMEM);
    +		siba_sprom_read(siba, buf, SIBA_SPROMSIZE_R4);
    +		error = sprom_check_crc(buf, siba->siba_spromsize);
    +		if (error)
    +			device_printf(siba->siba_dev, "warn: bad SPROM CRC\n");
    +	}
    +
    +	bzero(sprom, sizeof(*sprom));
    +
    +	sprom->rev = buf[siba->siba_spromsize - 1] & 0x00FF;
    +	DPRINTF(siba, SIBA_DEBUG_SPROM, "SPROM rev %d\n",
    +	    sprom->rev);
    +	memset(sprom->mac_eth, 0xff, 6);
    +	memset(sprom->mac_80211a, 0xff, 6);
    +	if ((siba->siba_chipid & 0xff00) == 0x4400) {
    +		sprom->rev = 1;
    +		siba_sprom_r123(sprom, buf);
    +	} else if (siba->siba_chipid == 0x4321) {
    +		sprom->rev = 4;
    +		siba_sprom_r45(sprom, buf);
    +	} else {
    +		switch (sprom->rev) {
    +		case 1:
    +		case 2:
    +		case 3:
    +			siba_sprom_r123(sprom, buf);
    +			break;
    +		case 4:
    +		case 5:
    +			siba_sprom_r45(sprom, buf);
    +			break;
    +		case 8:
    +			siba_sprom_r8(sprom, buf);
    +			break;
    +		default:
    +			device_printf(siba->siba_dev,
    +			    "unknown SPROM revision %d.\n", sprom->rev);
    +			siba_sprom_r123(sprom, buf);
    +		}
    +	}
    +
    +	if (sprom->bf_lo == 0xffff)
    +		sprom->bf_lo = 0;
    +	if (sprom->bf_hi == 0xffff)
    +		sprom->bf_hi = 0;
    +
    +	free(buf, M_DEVBUF);
    +	return (error);
    +}
    +
    +static int
    +siba_sprom_read(struct siba_softc *siba, uint16_t *sprom, uint16_t len)
    +{
    +	int i;
    +
    +	for (i = 0; i < len; i++)
    +		sprom[i] = SIBA_READ_2(siba, SIBA_SPROM_BASE + (i * 2));
    +
    +	siba->siba_spromsize = len;
    +	return (0);
    +}
    +
    +static int
    +sprom_check_crc(const uint16_t *sprom, size_t size)
    +{
    +	int word;
    +	uint8_t crc0, crc1 = 0xff;
    +
    +	crc0 = (sprom[size - 1] & SIBA_SPROM_REV_CRC) >> 8;
    +	for (word = 0; word < size - 1; word++) {
    +		crc1 = siba_crc8(crc1, sprom[word] & 0x00ff);
    +		crc1 = siba_crc8(crc1, (sprom[word] & 0xff00) >> 8);
    +	}
    +	crc1 = siba_crc8(crc1, sprom[size - 1] & 0x00ff);
    +	crc1 ^= 0xff;
    +
    +	return ((crc0 != crc1) ? EPROTO : 0);
    +}
    +
    +static uint8_t
    +siba_crc8(uint8_t crc, uint8_t data)
    +{
    +	static const uint8_t ct[] = {
    +		0x00, 0xf7, 0xb9, 0x4e, 0x25, 0xd2, 0x9c, 0x6b,
    +		0x4a, 0xbd, 0xf3, 0x04, 0x6f, 0x98, 0xd6, 0x21,
    +		0x94, 0x63, 0x2d, 0xda, 0xb1, 0x46, 0x08, 0xff,
    +		0xde, 0x29, 0x67, 0x90, 0xfb, 0x0c, 0x42, 0xb5,
    +		0x7f, 0x88, 0xc6, 0x31, 0x5a, 0xad, 0xe3, 0x14,
    +		0x35, 0xc2, 0x8c, 0x7b, 0x10, 0xe7, 0xa9, 0x5e,
    +		0xeb, 0x1c, 0x52, 0xa5, 0xce, 0x39, 0x77, 0x80,
    +		0xa1, 0x56, 0x18, 0xef, 0x84, 0x73, 0x3d, 0xca,
    +		0xfe, 0x09, 0x47, 0xb0, 0xdb, 0x2c, 0x62, 0x95,
    +		0xb4, 0x43, 0x0d, 0xfa, 0x91, 0x66, 0x28, 0xdf,
    +		0x6a, 0x9d, 0xd3, 0x24, 0x4f, 0xb8, 0xf6, 0x01,
    +		0x20, 0xd7, 0x99, 0x6e, 0x05, 0xf2, 0xbc, 0x4b,
    +		0x81, 0x76, 0x38, 0xcf, 0xa4, 0x53, 0x1d, 0xea,
    +		0xcb, 0x3c, 0x72, 0x85, 0xee, 0x19, 0x57, 0xa0,
    +		0x15, 0xe2, 0xac, 0x5b, 0x30, 0xc7, 0x89, 0x7e,
    +		0x5f, 0xa8, 0xe6, 0x11, 0x7a, 0x8d, 0xc3, 0x34,
    +		0xab, 0x5c, 0x12, 0xe5, 0x8e, 0x79, 0x37, 0xc0,
    +		0xe1, 0x16, 0x58, 0xaf, 0xc4, 0x33, 0x7d, 0x8a,
    +		0x3f, 0xc8, 0x86, 0x71, 0x1a, 0xed, 0xa3, 0x54,
    +		0x75, 0x82, 0xcc, 0x3b, 0x50, 0xa7, 0xe9, 0x1e,
    +		0xd4, 0x23, 0x6d, 0x9a, 0xf1, 0x06, 0x48, 0xbf,
    +		0x9e, 0x69, 0x27, 0xd0, 0xbb, 0x4c, 0x02, 0xf5,
    +		0x40, 0xb7, 0xf9, 0x0e, 0x65, 0x92, 0xdc, 0x2b,
    +		0x0a, 0xfd, 0xb3, 0x44, 0x2f, 0xd8, 0x96, 0x61,
    +		0x55, 0xa2, 0xec, 0x1b, 0x70, 0x87, 0xc9, 0x3e,
    +		0x1f, 0xe8, 0xa6, 0x51, 0x3a, 0xcd, 0x83, 0x74,
    +		0xc1, 0x36, 0x78, 0x8f, 0xe4, 0x13, 0x5d, 0xaa,
    +		0x8b, 0x7c, 0x32, 0xc5, 0xae, 0x59, 0x17, 0xe0,
    +		0x2a, 0xdd, 0x93, 0x64, 0x0f, 0xf8, 0xb6, 0x41,
    +		0x60, 0x97, 0xd9, 0x2e, 0x45, 0xb2, 0xfc, 0x0b,
    +		0xbe, 0x49, 0x07, 0xf0, 0x9b, 0x6c, 0x22, 0xd5,
    +		0xf4, 0x03, 0x4d, 0xba, 0xd1, 0x26, 0x68, 0x9f,
    +	};
    +	return (ct[crc ^ data]);
    +}
    +
    +#define	SIBA_LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask))
    +#define SIBA_OFFSET(offset)	\
    +	(((offset) - SIBA_SPROM_BASE) / sizeof(uint16_t))
    +#define	SIBA_SHIFTOUT_SUB(__x, __mask)					\
    +	(((__x) & (__mask)) / SIBA_LOWEST_SET_BIT(__mask))
    +#define	SIBA_SHIFTOUT(_var, _offset, _mask)				\
    +	out->_var = SIBA_SHIFTOUT_SUB(in[SIBA_OFFSET(_offset)], (_mask))
    +
    +static void
    +siba_sprom_r123(struct siba_sprom *out, const uint16_t *in)
    +{
    +	int i;
    +	uint16_t v;
    +	int8_t gain;
    +	uint16_t loc[3];
    +
    +	if (out->rev == 3)
    +		loc[0] = SIBA_SPROM3_MAC_80211BG;
    +	else {
    +		loc[0] = SIBA_SPROM1_MAC_80211BG;
    +		loc[1] = SIBA_SPROM1_MAC_ETH;
    +		loc[2] = SIBA_SPROM1_MAC_80211A;
    +	}
    +	for (i = 0; i < 3; i++) {
    +		v = in[SIBA_OFFSET(loc[0]) + i];
    +		*(((uint16_t *)out->mac_80211bg) + i) = htobe16(v);
    +	}
    +	if (out->rev < 3) {
    +		for (i = 0; i < 3; i++) {
    +			v = in[SIBA_OFFSET(loc[1]) + i];
    +			*(((uint16_t *)out->mac_eth) + i) = htobe16(v);
    +		}
    +		for (i = 0; i < 3; i++) {
    +			v = in[SIBA_OFFSET(loc[2]) + i];
    +			*(((uint16_t *)out->mac_80211a) + i) = htobe16(v);
    +		}
    +	}
    +	SIBA_SHIFTOUT(mii_eth0, SIBA_SPROM1_ETHPHY,
    +	    SIBA_SPROM1_ETHPHY_MII_ETH0);
    +	SIBA_SHIFTOUT(mii_eth1, SIBA_SPROM1_ETHPHY,
    +	    SIBA_SPROM1_ETHPHY_MII_ETH1);
    +	SIBA_SHIFTOUT(mdio_eth0, SIBA_SPROM1_ETHPHY,
    +	    SIBA_SPROM1_ETHPHY_MDIO_ETH0);
    +	SIBA_SHIFTOUT(mdio_eth1, SIBA_SPROM1_ETHPHY,
    +	    SIBA_SPROM1_ETHPHY_MDIO_ETH1);
    +	SIBA_SHIFTOUT(brev, SIBA_SPROM1_BOARDINFO, SIBA_SPROM1_BOARDINFO_BREV);
    +	SIBA_SHIFTOUT(ccode, SIBA_SPROM1_BOARDINFO,
    +	    SIBA_SPROM1_BOARDINFO_CCODE);
    +	SIBA_SHIFTOUT(ant_a, SIBA_SPROM1_BOARDINFO, SIBA_SPROM1_BOARDINFO_ANTA);
    +	SIBA_SHIFTOUT(ant_bg, SIBA_SPROM1_BOARDINFO,
    +	    SIBA_SPROM1_BOARDINFO_ANTBG);
    +	SIBA_SHIFTOUT(pa0b0, SIBA_SPROM1_PA0B0, 0xffff);
    +	SIBA_SHIFTOUT(pa0b1, SIBA_SPROM1_PA0B1, 0xffff);
    +	SIBA_SHIFTOUT(pa0b2, SIBA_SPROM1_PA0B2, 0xffff);
    +	SIBA_SHIFTOUT(pa1b0, SIBA_SPROM1_PA1B0, 0xffff);
    +	SIBA_SHIFTOUT(pa1b1, SIBA_SPROM1_PA1B1, 0xffff);
    +	SIBA_SHIFTOUT(pa1b2, SIBA_SPROM1_PA1B2, 0xffff);
    +	SIBA_SHIFTOUT(gpio0, SIBA_SPROM1_GPIOA, SIBA_SPROM1_GPIOA_P0);
    +	SIBA_SHIFTOUT(gpio1, SIBA_SPROM1_GPIOA, SIBA_SPROM1_GPIOA_P1);
    +	SIBA_SHIFTOUT(gpio2, SIBA_SPROM1_GPIOB, SIBA_SPROM1_GPIOB_P2);
    +	SIBA_SHIFTOUT(gpio3, SIBA_SPROM1_GPIOB, SIBA_SPROM1_GPIOB_P3);
    +	SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM1_MAXPWR, SIBA_SPROM1_MAXPWR_A);
    +	SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM1_MAXPWR, SIBA_SPROM1_MAXPWR_BG);
    +	SIBA_SHIFTOUT(tssi_a, SIBA_SPROM1_TSSI, SIBA_SPROM1_TSSI_A);
    +	SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM1_TSSI, SIBA_SPROM1_TSSI_BG);
    +	SIBA_SHIFTOUT(bf_lo, SIBA_SPROM1_BFLOW, 0xffff);
    +	if (out->rev >= 2)
    +		SIBA_SHIFTOUT(bf_hi, SIBA_SPROM2_BFHIGH, 0xffff);
    +
    +	/* antenna gain */
    +	gain = siba_sprom_r123_antgain(out->rev, in, SIBA_SPROM1_AGAIN_BG, 0);
    +	out->again.ghz24.a0 = out->again.ghz24.a1 = gain;
    +	out->again.ghz24.a2 = out->again.ghz24.a3 = gain;
    +	gain = siba_sprom_r123_antgain(out->rev, in, SIBA_SPROM1_AGAIN_A, 8);
    +	out->again.ghz5.a0 = out->again.ghz5.a1 = gain;
    +	out->again.ghz5.a2 = out->again.ghz5.a3 = gain;
    +}
    +
    +static void
    +siba_sprom_r45(struct siba_sprom *out, const uint16_t *in)
    +{
    +	int i;
    +	uint16_t v;
    +	uint16_t mac_80211bg_offset;
    +
    +	if (out->rev == 4)
    +		mac_80211bg_offset = SIBA_SPROM4_MAC_80211BG;
    +	else
    +		mac_80211bg_offset = SIBA_SPROM5_MAC_80211BG;
    +	for (i = 0; i < 3; i++) {
    +		v = in[SIBA_OFFSET(mac_80211bg_offset) + i];
    +		*(((uint16_t *)out->mac_80211bg) + i) = htobe16(v);
    +	}
    +	SIBA_SHIFTOUT(mii_eth0, SIBA_SPROM4_ETHPHY, SIBA_SPROM4_ETHPHY_ET0A);
    +	SIBA_SHIFTOUT(mii_eth1, SIBA_SPROM4_ETHPHY, SIBA_SPROM4_ETHPHY_ET1A);
    +	if (out->rev == 4) {
    +		SIBA_SHIFTOUT(ccode, SIBA_SPROM4_CCODE, 0xffff);
    +		SIBA_SHIFTOUT(bf_lo, SIBA_SPROM4_BFLOW, 0xffff);
    +		SIBA_SHIFTOUT(bf_hi, SIBA_SPROM4_BFHIGH, 0xffff);
    +	} else {
    +		SIBA_SHIFTOUT(ccode, SIBA_SPROM5_CCODE, 0xffff);
    +		SIBA_SHIFTOUT(bf_lo, SIBA_SPROM5_BFLOW, 0xffff);
    +		SIBA_SHIFTOUT(bf_hi, SIBA_SPROM5_BFHIGH, 0xffff);
    +	}
    +	SIBA_SHIFTOUT(ant_a, SIBA_SPROM4_ANTAVAIL, SIBA_SPROM4_ANTAVAIL_A);
    +	SIBA_SHIFTOUT(ant_bg, SIBA_SPROM4_ANTAVAIL, SIBA_SPROM4_ANTAVAIL_BG);
    +	SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM4_MAXP_BG, SIBA_SPROM4_MAXP_BG_MASK);
    +	SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM4_MAXP_BG, SIBA_SPROM4_TSSI_BG);
    +	SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM4_MAXP_A, SIBA_SPROM4_MAXP_A_MASK);
    +	SIBA_SHIFTOUT(tssi_a, SIBA_SPROM4_MAXP_A, SIBA_SPROM4_TSSI_A);
    +	if (out->rev == 4) {
    +		SIBA_SHIFTOUT(gpio0, SIBA_SPROM4_GPIOA, SIBA_SPROM4_GPIOA_P0);
    +		SIBA_SHIFTOUT(gpio1, SIBA_SPROM4_GPIOA, SIBA_SPROM4_GPIOA_P1);
    +		SIBA_SHIFTOUT(gpio2, SIBA_SPROM4_GPIOB, SIBA_SPROM4_GPIOB_P2);
    +		SIBA_SHIFTOUT(gpio3, SIBA_SPROM4_GPIOB, SIBA_SPROM4_GPIOB_P3);
    +	} else {
    +		SIBA_SHIFTOUT(gpio0, SIBA_SPROM5_GPIOA, SIBA_SPROM5_GPIOA_P0);
    +		SIBA_SHIFTOUT(gpio1, SIBA_SPROM5_GPIOA, SIBA_SPROM5_GPIOA_P1);
    +		SIBA_SHIFTOUT(gpio2, SIBA_SPROM5_GPIOB, SIBA_SPROM5_GPIOB_P2);
    +		SIBA_SHIFTOUT(gpio3, SIBA_SPROM5_GPIOB, SIBA_SPROM5_GPIOB_P3);
    +	}
    +
    +	/* antenna gain */
    +	SIBA_SHIFTOUT(again.ghz24.a0, SIBA_SPROM4_AGAIN01, SIBA_SPROM4_AGAIN0);
    +	SIBA_SHIFTOUT(again.ghz24.a1, SIBA_SPROM4_AGAIN01, SIBA_SPROM4_AGAIN1);
    +	SIBA_SHIFTOUT(again.ghz24.a2, SIBA_SPROM4_AGAIN23, SIBA_SPROM4_AGAIN2);
    +	SIBA_SHIFTOUT(again.ghz24.a3, SIBA_SPROM4_AGAIN23, SIBA_SPROM4_AGAIN3);
    +	bcopy(&out->again.ghz24, &out->again.ghz5, sizeof(out->again.ghz5));
    +}
    +
    +static void
    +siba_sprom_r8(struct siba_sprom *out, const uint16_t *in)
    +{
    +	int i;
    +	uint16_t v;
    +
    +	for (i = 0; i < 3; i++) {
    +		v = in[SIBA_OFFSET(SIBA_SPROM1_MAC_80211BG) + i];
    +		*(((uint16_t *)out->mac_80211bg) + i) = htobe16(v);
    +	}
    +	SIBA_SHIFTOUT(ccode, SIBA_SPROM8_CCODE, 0xffff);
    +	SIBA_SHIFTOUT(bf_lo, SIBA_SPROM8_BFLOW, 0xffff);
    +	SIBA_SHIFTOUT(bf_hi, SIBA_SPROM8_BFHIGH, 0xffff);
    +	SIBA_SHIFTOUT(ant_a, SIBA_SPROM8_ANTAVAIL, SIBA_SPROM8_ANTAVAIL_A);
    +	SIBA_SHIFTOUT(ant_bg, SIBA_SPROM8_ANTAVAIL, SIBA_SPROM8_ANTAVAIL_BG);
    +	SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM8_MAXP_BG, SIBA_SPROM8_MAXP_BG_MASK);
    +	SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM8_MAXP_BG, SIBA_SPROM8_TSSI_BG);
    +	SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM8_MAXP_A, SIBA_SPROM8_MAXP_A_MASK);
    +	SIBA_SHIFTOUT(tssi_a, SIBA_SPROM8_MAXP_A, SIBA_SPROM8_TSSI_A);
    +	SIBA_SHIFTOUT(gpio0, SIBA_SPROM8_GPIOA, SIBA_SPROM8_GPIOA_P0);
    +	SIBA_SHIFTOUT(gpio1, SIBA_SPROM8_GPIOA, SIBA_SPROM8_GPIOA_P1);
    +	SIBA_SHIFTOUT(gpio2, SIBA_SPROM8_GPIOB, SIBA_SPROM8_GPIOB_P2);
    +	SIBA_SHIFTOUT(gpio3, SIBA_SPROM8_GPIOB, SIBA_SPROM8_GPIOB_P3);
    +
    +	/* antenna gain */
    +	SIBA_SHIFTOUT(again.ghz24.a0, SIBA_SPROM8_AGAIN01, SIBA_SPROM8_AGAIN0);
    +	SIBA_SHIFTOUT(again.ghz24.a1, SIBA_SPROM8_AGAIN01, SIBA_SPROM8_AGAIN1);
    +	SIBA_SHIFTOUT(again.ghz24.a2, SIBA_SPROM8_AGAIN23, SIBA_SPROM8_AGAIN2);
    +	SIBA_SHIFTOUT(again.ghz24.a3, SIBA_SPROM8_AGAIN23, SIBA_SPROM8_AGAIN3);
    +	bcopy(&out->again.ghz24, &out->again.ghz5, sizeof(out->again.ghz5));
    +}
    +
    +static int8_t
    +siba_sprom_r123_antgain(uint8_t sprom_revision, const uint16_t *in,
    +    uint16_t mask, uint16_t shift)
    +{
    +	uint16_t v;
    +	uint8_t gain;
    +
    +	v = in[SIBA_OFFSET(SIBA_SPROM1_AGAIN)];
    +	gain = (v & mask) >> shift;
    +	gain = (gain == 0xff) ? 2 : (sprom_revision == 1) ? gain << 2 :
    +	    ((gain & 0xc0) >> 6) | ((gain & 0x3f) << 2);
    +
    +	return ((int8_t)gain);
    +}
    +
    +#undef SIBA_LOWEST_SET_BIT
    +#undef SIBA_OFFSET
    +#undef SIBA_SHIFTOUT_SUB
    +#undef SIBA_SHIFTOUT
    +
    +int
    +siba_powerdown(struct siba_softc *siba)
    +{
    +	struct siba_cc *scc;
    +
    +	if (siba->siba_type == SIBA_TYPE_SSB)
    +		return (0);
    +
    +	scc = &siba->siba_cc;
    +	if (!scc->scc_dev || scc->scc_dev->sd_id.sd_rev < 5)
    +		return (0);
    +	siba_cc_clock(scc, SIBA_CLOCK_SLOW);
    +	siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 0);
    +	return (0);
    +}
    +
    +static void
    +siba_pcicore_init(struct siba_pci *spc)
    +{
    +	struct siba_dev_softc *sd = spc->spc_dev;
    +	struct siba_softc *siba;
    +
    +	if (sd == NULL)
    +		return;
    +
    +	siba = sd->sd_bus;
    +	if (!siba_dev_isup(sd))
    +		siba_dev_up(sd, 0);
    +
    +	KASSERT(spc->spc_hostmode == 0,
    +	    ("%s:%d: hostmode", __func__, __LINE__));
    +	/* disable PCI interrupt */
    +	siba_write_4(spc->spc_dev, SIBA_INTR_MASK, 0);
    +}
    +
    +int
    +siba_dev_isup(struct siba_dev_softc *sd)
    +{
    +	uint32_t reject, val;
    +
    +	reject = siba_tmslow_reject_bitmask(sd);
    +	val = siba_read_4(sd, SIBA_TGSLOW);
    +	val &= SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_RESET | reject;
    +
    +	return (val == SIBA_TGSLOW_CLOCK);
    +}
    +
    +void
    +siba_dev_up(struct siba_dev_softc *sd, uint32_t flags)
    +{
    +	uint32_t val;
    +
    +	siba_dev_down(sd, flags);
    +	siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_RESET | SIBA_TGSLOW_CLOCK |
    +	    SIBA_TGSLOW_FGC | flags);
    +	siba_read_4(sd, SIBA_TGSLOW);
    +	DELAY(1);
    +
    +	if (siba_read_4(sd, SIBA_TGSHIGH) & SIBA_TGSHIGH_SERR)
    +		siba_write_4(sd, SIBA_TGSHIGH, 0);
    +
    +	val = siba_read_4(sd, SIBA_IAS);
    +	if (val & (SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT)) {
    +		val &= ~(SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT);
    +		siba_write_4(sd, SIBA_IAS, val);
    +	}
    +
    +	siba_write_4(sd, SIBA_TGSLOW,
    +	    SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_FGC | flags);
    +	siba_read_4(sd, SIBA_TGSLOW);
    +	DELAY(1);
    +
    +	siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_CLOCK | flags);
    +	siba_read_4(sd, SIBA_TGSLOW);
    +	DELAY(1);
    +}
    +
    +static uint32_t
    +siba_tmslow_reject_bitmask(struct siba_dev_softc *sd)
    +{
    +	uint32_t rev = siba_read_4(sd, SIBA_IDLOW) & SIBA_IDLOW_SSBREV;
    +
    +	switch (rev) {
    +	case SIBA_IDLOW_SSBREV_22:
    +		return (SIBA_TGSLOW_REJECT_22);
    +	case SIBA_IDLOW_SSBREV_23:
    +		return (SIBA_TGSLOW_REJECT_23);
    +	case SIBA_IDLOW_SSBREV_24:
    +	case SIBA_IDLOW_SSBREV_25:
    +	case SIBA_IDLOW_SSBREV_26:
    +	case SIBA_IDLOW_SSBREV_27:
    +		return (SIBA_TGSLOW_REJECT_23);
    +	default:
    +		KASSERT(0 == 1,
    +		    ("%s:%d: unknown backplane rev %#x\n",
    +			__func__, __LINE__, rev));
    +	}
    +	return (SIBA_TGSLOW_REJECT_22 | SIBA_TGSLOW_REJECT_23);
    +}
    +
    +void
    +siba_dev_down(struct siba_dev_softc *sd, uint32_t flags)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +	uint32_t reject, val;
    +	int i;
    +
    +	if (siba_read_4(sd, SIBA_TGSLOW) & SIBA_TGSLOW_RESET)
    +		return;
    +
    +	reject = siba_tmslow_reject_bitmask(sd);
    +	siba_write_4(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_CLOCK);
    +
    +	for (i = 0; i < 1000; i++) {
    +		val = siba_read_4(sd, SIBA_TGSLOW);
    +		if (val & reject)
    +			break;
    +		DELAY(10);
    +	}
    +	if ((val & reject) == 0) {
    +		device_printf(siba->siba_dev, "timeout (bit %#x reg %#x)\n",
    +		    reject, SIBA_TGSLOW);
    +	}
    +	for (i = 0; i < 1000; i++) {
    +		val = siba_read_4(sd, SIBA_TGSHIGH);
    +		if (!(val & SIBA_TGSHIGH_BUSY))
    +			break;
    +		DELAY(10);
    +	}
    +	if ((val & SIBA_TGSHIGH_BUSY) != 0) {
    +		device_printf(siba->siba_dev, "timeout (bit %#x reg %#x)\n",
    +		    SIBA_TGSHIGH_BUSY, SIBA_TGSHIGH);
    +	}
    +
    +	siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_FGC | SIBA_TGSLOW_CLOCK |
    +	    reject | SIBA_TGSLOW_RESET | flags);
    +	siba_read_4(sd, SIBA_TGSLOW);
    +	DELAY(1);
    +	siba_write_4(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_RESET | flags);
    +	siba_read_4(sd, SIBA_TGSLOW);
    +	DELAY(1);
    +}
    +
    +static void
    +siba_pcicore_setup(struct siba_pci *spc, struct siba_dev_softc *sd)
    +{
    +	struct siba_dev_softc *psd = spc->spc_dev;
    +	struct siba_softc *siba = psd->sd_bus;
    +	uint32_t tmp;
    +
    +	if (psd->sd_id.sd_device == SIBA_DEVID_PCI) {
    +		siba_pcicore_write_4(spc, SIBA_PCICORE_SBTOPCI2,
    +		    siba_pcicore_read_4(spc, SIBA_PCICORE_SBTOPCI2) |
    +		    SIBA_PCICORE_SBTOPCI_PREF | SIBA_PCICORE_SBTOPCI_BURST);
    +
    +		if (psd->sd_id.sd_rev < 5) {
    +			tmp = siba_read_4(psd, SIBA_IMCFGLO);
    +			tmp &= ~SIBA_IMCFGLO_SERTO;
    +			tmp = (tmp | 2) & ~SIBA_IMCFGLO_REQTO;
    +			tmp |= 3 << 4 /* SIBA_IMCFGLO_REQTO_SHIFT */;
    +			siba_write_4(psd, SIBA_IMCFGLO, tmp);
    +
    +			/* broadcast value */
    +			sd = (siba->siba_cc.scc_dev != NULL) ?
    +			    siba->siba_cc.scc_dev : siba->siba_pci.spc_dev;
    +			if (sd != NULL) {
    +				siba_write_4(sd, SIBA_PCICORE_BCAST_ADDR,
    +				    0xfd8);
    +				siba_read_4(sd, SIBA_PCICORE_BCAST_ADDR);
    +				siba_write_4(sd, SIBA_PCICORE_BCAST_DATA, 0);
    +				siba_read_4(sd, SIBA_PCICORE_BCAST_DATA);
    +			}
    +		} else if (psd->sd_id.sd_rev >= 11) {
    +			tmp = siba_pcicore_read_4(spc, SIBA_PCICORE_SBTOPCI2);
    +			tmp |= SIBA_PCICORE_SBTOPCI_MRM;
    +			siba_pcicore_write_4(spc, SIBA_PCICORE_SBTOPCI2, tmp);
    +		}
    +	} else {
    +		KASSERT(psd->sd_id.sd_device == SIBA_DEVID_PCIE, ("only PCIE"));
    +		if ((psd->sd_id.sd_rev == 0) || (psd->sd_id.sd_rev == 1))
    +			siba_pcie_write(spc, 0x4,
    +			    siba_pcie_read(spc, 0x4) | 0x8);
    +		if (psd->sd_id.sd_rev == 0) {
    +			siba_pcie_mdio_write(spc, 0x1f, 2, 0x8128); /* Timer */
    +			siba_pcie_mdio_write(spc, 0x1f, 6, 0x0100); /* CDR */
    +			siba_pcie_mdio_write(spc, 0x1f, 7, 0x1466); /* CDR BW */
    +		} else if (psd->sd_id.sd_rev == 1)
    +			siba_pcie_write(spc, 0x100,
    +			    siba_pcie_read(spc, 0x100) | 0x40);
    +	}
    +	spc->spc_inited = 1;
    +}
    +
    +void
    +siba_pcicore_intr(struct siba_pci *spc, struct siba_dev_softc *sd)
    +{
    +	struct siba_dev_softc *psd = spc->spc_dev;
    +	struct siba_softc *siba;
    +	uint32_t tmp;
    +
    +	if (sd->sd_bus->siba_type != SIBA_TYPE_PCI || !psd)
    +		return;
    +
    +	siba = psd->sd_bus;
    +	/* enable interrupts */
    +	if (siba->siba_dev != NULL &&
    +	    (psd->sd_id.sd_rev >= 6 || psd->sd_id.sd_device == SIBA_DEVID_PCIE)) {
    +		tmp = pci_read_config(siba->siba_dev, SIBA_IRQMASK, 4);
    +		tmp |= (1 << sd->sd_coreidx) << 8;
    +		pci_write_config(siba->siba_dev, SIBA_IRQMASK, tmp, 4);
    +	} else {
    +		tmp = siba_read_4(sd, SIBA_TPS);
    +		tmp &= SIBA_TPS_BPFLAG;
    +		siba_write_4(psd, SIBA_INTR_MASK,
    +		    siba_read_4(psd, SIBA_INTR_MASK) | (1 << tmp));
    +	}
    +
    +	/* setup PCIcore */
    +	if (spc->spc_inited == 0)
    +		siba_pcicore_setup(spc, sd);
    +}
    +
    +static uint32_t
    +siba_pcicore_read_4(struct siba_pci *spc, uint16_t offset)
    +{
    +
    +	return (siba_read_4(spc->spc_dev, offset));
    +}
    +
    +static void
    +siba_pcicore_write_4(struct siba_pci *spc, uint16_t offset, uint32_t value)
    +{
    +
    +	siba_write_4(spc->spc_dev, offset, value);
    +}
    +
    +static uint32_t
    +siba_pcie_read(struct siba_pci *spc, uint32_t address)
    +{
    +
    +	siba_pcicore_write_4(spc, 0x130, address);
    +	return (siba_pcicore_read_4(spc, 0x134));
    +}
    +
    +static void
    +siba_pcie_write(struct siba_pci *spc, uint32_t address, uint32_t data)
    +{
    +
    +	siba_pcicore_write_4(spc, 0x130, address);
    +	siba_pcicore_write_4(spc, 0x134, data);
    +}
    +
    +static void
    +siba_pcie_mdio_write(struct siba_pci *spc, uint8_t device, uint8_t address,
    +    uint16_t data)
    +{
    +	int i;
    +
    +	siba_pcicore_write_4(spc, SIBA_PCICORE_MDIO_CTL, 0x80 | 0x2);
    +	siba_pcicore_write_4(spc, SIBA_PCICORE_MDIO_DATA,
    +	    (1 << 30) | (1 << 28) |
    +	    ((uint32_t)device << 22) | ((uint32_t)address << 18) |
    +	    (1 << 17) | data);
    +	DELAY(10);
    +	for (i = 0; i < 10; i++) {
    +		if (siba_pcicore_read_4(spc, SIBA_PCICORE_MDIO_CTL) & 0x100)
    +			break;
    +		DELAY(1000);
    +	}
    +	siba_pcicore_write_4(spc, SIBA_PCICORE_MDIO_CTL, 0);
    +}
    +
    +uint32_t
    +siba_dma_translation(struct siba_dev_softc *sd)
    +{
    +
    +	KASSERT(sd->sd_bus->siba_type == SIBA_TYPE_PCI,
    +	    ("unsupported bustype %d\n", sd->sd_bus->siba_type));
    +	return (SIBA_PCI_DMA);
    +}
    +
    +void
    +siba_barrier(struct siba_dev_softc *sd, int flags)
    +{
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	SIBA_BARRIER(siba, flags);
    +}
    +
    +/*
    + * Attach it as child.
    + */
    +device_t
    +siba_add_child(device_t dev, struct siba_softc *siba, int order,
    +    const char *name, int unit)
    +{
    +	struct siba_dev_softc *sd;
    +	device_t child;
    +	int idx = 0, i;
    +
    +	child = device_add_child(dev, name, unit);
    +	if (child == NULL)
    +		return (NULL);
    +
    +	siba_powerup(siba, 0);
    +	siba_pcicore_init(&siba->siba_pci);
    +	siba_powerdown(siba);
    +
    +	for (i = 0; i < siba->siba_ndevs; i++) {
    +		sd = &(siba->siba_devs[i]);
    +
    +		if (sd->sd_id.sd_device != SIBA_DEVID_80211) {
    +			DPRINTF(siba, SIBA_DEBUG_CORE,
    +			    "skip to register coreid %#x (%s)\n",
    +			    sd->sd_id.sd_device,
    +			    siba_core_name(sd->sd_id.sd_device));
    +			continue;
    +		}
    +
    +		DPRINTF(siba, SIBA_DEBUG_CORE,
    +		    "siba: attaching coreid %#x (%s) idx %d\n",
    +		    sd->sd_id.sd_device,
    +		    siba_core_name(sd->sd_id.sd_device), idx);
    +
    +		KASSERT(sd->sd_id.sd_device == SIBA_DEVID_80211,
    +		    ("%s:%d: SIBA_DEVID_80211 is only supportted currently.",
    +			__func__, __LINE__));
    +
    +		device_set_ivars(child, sd);
    +		device_probe_and_attach(child);
    +		idx++;
    +	}
    +	return (child);
    +}
    +
    +static void
    +siba_cc_suspend(struct siba_cc *scc)
    +{
    +
    +	siba_cc_clock(scc, SIBA_CLOCK_SLOW);
    +}
    +
    +static void
    +siba_cc_resume(struct siba_cc *scc)
    +{
    +
    +	siba_cc_power_init(scc);
    +	siba_cc_clock(scc, SIBA_CLOCK_FAST);
    +}
    +
    +int
    +siba_core_suspend(struct siba_softc *siba)
    +{
    +
    +	siba_cc_suspend(&siba->siba_cc);
    +	siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 0);
    +	return (0);
    +}
    +
    +int
    +siba_core_resume(struct siba_softc *siba)
    +{
    +
    +	siba->siba_pci.spc_inited = 0;
    +	siba->siba_curdev = NULL;
    +
    +	siba_powerup(siba, 0);
    +	/* XXX setup H/W for PCMCIA??? */
    +	siba_cc_resume(&siba->siba_cc);
    +	siba_powerdown(siba);
    +
    +	return (0);
    +}
    diff --git a/sys/dev/siba/siba_ids.h b/sys/dev/siba/siba_ids.h
    index c7acd20316a..b5aaf3419c7 100644
    --- a/sys/dev/siba/siba_ids.h
    +++ b/sys/dev/siba/siba_ids.h
    @@ -39,23 +39,45 @@ struct siba_devid {
     	uint8_t		 sd_rev;
     	char		*sd_desc;
     };
    +#define	SIBA_DEV(_vendor, _cid, _rev, _msg)			\
    +	{ SIBA_VID_##_vendor, SIBA_DEVID_##_cid, _rev, _msg }
     
     /*
      * Device IDs
      */
    -#define SIBA_DEVID_ANY		0xffff
    -#define SIBA_DEVID_CHIPCOMMON	0x0800
    -#define SIBA_DEVID_INSIDELINE	0x0801
    -#define SIBA_DEVID_SDRAM	0x0803
    -#define SIBA_DEVID_PCI		0x0804
    -#define SIBA_DEVID_MIPS		0x0805
    -#define SIBA_DEVID_ETHERNET	0x0806
    -#define SIBA_DEVID_MODEM	0x0807
    -#define SIBA_DEVID_USB		0x0808
    -#define SIBA_DEVID_IPSEC	0x080b
    -#define SIBA_DEVID_SDRAMDDR	0x080f
    -#define SIBA_DEVID_EXTIF	0x0811
    -#define SIBA_DEVID_MIPS_3302	0x0816
    +#define SIBA_DEVID_ANY			0xffff
    +#define	SIBA_DEVID_CHIPCOMMON		0x800
    +#define	SIBA_DEVID_ILINE20		0x801
    +#define	SIBA_DEVID_SDRAM		0x803
    +#define	SIBA_DEVID_PCI			0x804
    +#define	SIBA_DEVID_MIPS			0x805
    +#define	SIBA_DEVID_ETHERNET		0x806
    +#define	SIBA_DEVID_MODEM		0x807
    +#define	SIBA_DEVID_USB11_HOSTDEV	0x808
    +#define	SIBA_DEVID_ADSL			0x809
    +#define	SIBA_DEVID_ILINE100		0x80a
    +#define	SIBA_DEVID_IPSEC		0x80b
    +#define	SIBA_DEVID_PCMCIA		0x80d
    +#define	SIBA_DEVID_INTERNAL_MEM		0x80e
    +#define	SIBA_DEVID_SDRAMDDR		0x80f
    +#define	SIBA_DEVID_EXTIF		0x811
    +#define	SIBA_DEVID_80211		0x812
    +#define	SIBA_DEVID_MIPS_3302		0x816
    +#define	SIBA_DEVID_USB11_HOST		0x817
    +#define	SIBA_DEVID_USB11_DEV		0x818
    +#define	SIBA_DEVID_USB20_HOST		0x819
    +#define	SIBA_DEVID_USB20_DEV		0x81a
    +#define	SIBA_DEVID_SDIO_HOST		0x81b
    +#define	SIBA_DEVID_ROBOSWITCH		0x81c
    +#define	SIBA_DEVID_PARA_ATA		0x81d
    +#define	SIBA_DEVID_SATA_XORDMA		0x81e
    +#define	SIBA_DEVID_ETHERNET_GBIT	0x81f
    +#define	SIBA_DEVID_PCIE			0x820
    +#define	SIBA_DEVID_MIMO_PHY		0x821
    +#define	SIBA_DEVID_SRAM_CTRLR		0x822
    +#define	SIBA_DEVID_MINI_MACPHY		0x823
    +#define	SIBA_DEVID_ARM_1176		0x824
    +#define	SIBA_DEVID_ARM_7TDMI		0x825
     
     /*
      * Vendor IDs
    diff --git a/sys/dev/siba/siba_pcib.c b/sys/dev/siba/siba_pcib.c
    index d43f54c9c0a..5175aa7ee0b 100644
    --- a/sys/dev/siba/siba_pcib.c
    +++ b/sys/dev/siba/siba_pcib.c
    @@ -55,9 +55,9 @@ __FBSDID("$FreeBSD$");
     
     #include "pcib_if.h"
     
    -#include 
    -#include 
     #include 
    +#include 
    +#include 
     #include 
     
     #ifndef MIPS_MEM_RID
    @@ -79,10 +79,6 @@ __FBSDID("$FreeBSD$");
     #define SBPCI_CFGBASE			0x0C000000
     #define SBPCI_CFGSIZE			0x01000000
     
    -#define SBPCI_SBTOPCI0 0x100
    -#define SBPCI_SBTOPCI1 0x104
    -#define SBPCI_SBTOPCI2 0x108
    -
     /*
      * TODO: implement type 1 config space access (ie beyond bus 0)
      * we may need to tweak the windows to do this
    @@ -187,9 +183,12 @@ siba_pcib_attach(device_t dev)
     	 * XXX we need to be able to do type 1 too.
     	 * we probably don't need to be able to do i/o cycles.
     	 */
    -	SBPCI_WRITE_4(sc, SBPCI_SBTOPCI0, 1);	/* I/O read/write window */
    -	SBPCI_WRITE_4(sc, SBPCI_SBTOPCI1, 2);	/* type 0 configuration only */
    -	SBPCI_WRITE_4(sc, SBPCI_SBTOPCI2, 1 << 30); /* memory only */
    +
    +	/* I/O read/write window */
    +	SBPCI_WRITE_4(sc, SIBA_PCICORE_SBTOPCI0, 1);
    +	/* type 0 configuration only */
    +	SBPCI_WRITE_4(sc, SIBA_PCICORE_SBTOPCI1, 2);
    +	SBPCI_WRITE_4(sc, SIBA_PCICORE_SBTOPCI2, 1 << 30); /* memory only */
     	DELAY(500);
     
     	/* XXX resource managers */
    @@ -365,7 +364,7 @@ siba_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
     	/*
     	 * The configuration tag on the broadcom is weird.
     	 */
    -	SBPCI_WRITE_4(sc, SBPCI_SBTOPCI1, 2);	/* XXX again??? */
    +	SBPCI_WRITE_4(sc, SIBA_PCICORE_SBTOPCI1, 2);	/* XXX again??? */
     	cfgtag = ((1 << slot) << 16) | (func << 8);
     	cfgaddr = SBPCI_CFGBASE | cfgtag | (reg & ~3);
     
    diff --git a/sys/dev/siba/sibareg.h b/sys/dev/siba/sibareg.h
    index dc1b7f7d75b..9aa9e7cf778 100644
    --- a/sys/dev/siba/sibareg.h
    +++ b/sys/dev/siba/sibareg.h
    @@ -34,40 +34,383 @@
     #ifndef _SIBA_SIBAREG_H_
     #define _SIBA_SIBAREG_H_
     
    +#define	PCI_DEVICE_ID_BCM4401		0x4401
    +#define	PCI_DEVICE_ID_BCM4401B0		0x4402
    +#define	PCI_DEVICE_ID_BCM4401B1		0x170c
    +#define	SIBA_PCIR_BAR			PCIR_BAR(0)
    +#define	SIBA_CCID_BCM4710		0x4710
    +#define	SIBA_CCID_BCM4704		0x4704
    +#define	SIBA_CCID_SENTRY5		0x5365
    +
    +/*
    + * ChipCommon registers.
    + */
    +#define	SIBA_CC_CHIPID			0x0000
    +#define	SIBA_CC_IDMASK			0x0000ffff
    +#define	SIBA_CC_ID(id)			(id & SIBA_CC_IDMASK)
    +#define	SIBA_CC_REVMASK			0x000f0000
    +#define	SIBA_CC_REVSHIFT		16
    +#define	SIBA_CC_REV(id)							\
    +	((id & SIBA_CC_REVMASK) >> SIBA_CC_REVSHIFT)
    +#define	SIBA_CC_PKGMASK			0x00F00000
    +#define	SIBA_CC_PKGSHIFT		20
    +#define	SIBA_CC_PKG(id)							\
    +	((id & SIBA_CC_PKGMASK) >> SIBA_CC_PKGSHIFT)
    +#define	SIBA_CC_NCORESMASK		0x0F000000
    +#define	SIBA_CC_NCORESSHIFT		24
    +#define	SIBA_CC_NCORES(id)						\
    +	((id & SIBA_CC_NCORESMASK) >> SIBA_CC_NCORESSHIFT)
    +#define	SIBA_CC_CAPS			0x0004
    +#define	SIBA_CC_CAPS_PWCTL		0x00040000
    +#define	SIBA_CC_CAPS_PMU		0x10000000	/* PMU (rev >= 20) */
    +#define	SIBA_CC_CHIPCTL			0x0028		/* rev >= 11 */
    +#define	SIBA_CC_CHIPSTAT		0x002C		/* rev >= 11 */
    +#define	SIBA_CC_BCAST_ADDR		0x0050		/* Broadcast Address */
    +#define	SIBA_CC_BCAST_DATA		0x0054		/* Broadcast Data */
    +#define	SIBA_CC_PLLONDELAY		0x00B0		/* Rev >= 4 only */
    +#define	SIBA_CC_FREFSELDELAY		0x00B4		/* Rev >= 4 only */
    +#define	SIBA_CC_CLKSLOW			0x00b8		/* 6 <= Rev <= 9 only */
    +#define	SIBA_CC_CLKSLOW_SRC		0x00000007
    +#define	SIBA_CC_CLKSLOW_SRC_CRYSTAL	0x00000001
    +#define	SIBA_CC_CLKSLOW_FSLOW		0x00000800
    +#define	SIBA_CC_CLKSLOW_IPLL		0x00001000
    +#define	SIBA_CC_CLKSLOW_ENXTAL		0x00002000
    +#define	SIBA_CC_CLKSYSCTL		0x00C0		/* Rev >= 3 only */
    +#define	SIBA_CC_CLKCTLSTATUS		0x01e0
    +#define	SIBA_CC_CLKCTLSTATUS_HT		0x00010000
    +#define	SIBA_CC_UART0			0x0300		/* offset of UART0 */
    +#define	SIBA_CC_UART1			0x0400		/* offset of UART1 */
    +#define	SIBA_CC_PMUCTL			0x0600		/* PMU control */
    +#define	SIBA_CC_PMUCTL_ILP		0xffff0000	/* mask */
    +#define	SIBA_CC_PMUCTL_NOILP		0x00000200
    +#define	SIBA_CC_PMUCTL_XF		0x0000007c	/* crystal freq */
    +#define	SIBA_CC_PMUCTL_XF_VAL(id)	((id & 0x0000007c) >> 2)
    +#define	SIBA_CC_PMUCAPS			0x0604
    +#define	SIBA_CC_PMUCAPS_REV		0x000000ff
    +#define	SIBA_CC_PMU_MINRES		0x0618
    +#define	SIBA_CC_PMU_MAXRES		0x061c
    +#define	SIBA_CC_PMU_TABSEL		0x0620
    +#define	SIBA_CC_PMU_DEPMSK		0x0624
    +#define	SIBA_CC_PMU_UPDNTM		0x0628
    +#define	SIBA_CC_PLLCTL_ADDR		0x0660
    +#define	SIBA_CC_PLLCTL_DATA		0x0664
    +
    +#define	SIBA_CC_PMU0_PLL0		0
    +#define	SIBA_CC_PMU0_PLL0_PDIV_MSK	0x00000001
    +#define	SIBA_CC_PMU0_PLL0_PDIV_FREQ	25000
    +#define	SIBA_CC_PMU0_PLL1		1
    +#define	SIBA_CC_PMU0_PLL1_IMSK		0xf0000000
    +#define	SIBA_CC_PMU0_PLL1_FMSK		0x0fffff00
    +#define	SIBA_CC_PMU0_PLL1_STOPMOD	0x00000040
    +#define	SIBA_CC_PMU0_PLL2		2
    +#define	SIBA_CC_PMU0_PLL2_IMSKHI	0x0000000f
    +#define	SIBA_CC_PMU1_PLL0		0
    +#define	SIBA_CC_PMU1_PLL0_P1DIV		0x00f00000
    +#define	SIBA_CC_PMU1_PLL0_P2DIV		0x0f000000
    +#define	SIBA_CC_PMU1_PLL2		2
    +#define	SIBA_CC_PMU1_PLL2_NDIVMODE	0x000e0000
    +#define	SIBA_CC_PMU1_PLL2_NDIVINT	0x1ff00000
    +#define	SIBA_CC_PMU1_PLL3		3
    +#define	SIBA_CC_PMU1_PLL3_NDIVFRAC	0x00ffffff
    +#define	SIBA_CC_PMU1_PLL5		5
    +#define	SIBA_CC_PMU1_PLL5_CLKDRV	0xffffff00
    +
    +#define	SIBA_CC_PMU0_DEFAULT_XTALFREQ	20000
    +#define	SIBA_CC_PMU1_DEFAULT_FREQ	15360
    +
    +#define	SIBA_CC_PMU1_PLLTAB_ENTRY					\
    +{									\
    +	{ 12000,  1, 3, 22,  0x9, 0xffffef },				\
    +	{ 13000,  2, 1,  6,  0xb, 0x483483 },				\
    +	{ 14400,  3, 1, 10,  0xa, 0x1c71c7 },				\
    +	{ 15360,  4, 1,  5,  0xb, 0x755555 },				\
    +	{ 16200,  5, 1, 10,  0x5, 0x6e9e06 },				\
    +	{ 16800,  6, 1, 10,  0x5, 0x3cf3cf },				\
    +	{ 19200,  7, 1,  9,  0x5, 0x17b425 },				\
    +	{ 19800,  8, 1, 11,  0x4, 0xa57eb },				\
    +	{ 20000,  9, 1, 11,  0x4, 0 },					\
    +	{ 24000, 10, 3, 11,  0xa, 0 },					\
    +	{ 25000, 11, 5, 16,  0xb, 0 },					\
    +	{ 26000, 12, 1,  2, 0x10, 0xec4ec4 },				\
    +	{ 30000, 13, 3,  8,  0xb, 0 },					\
    +	{ 38400, 14, 1,  5,  0x4, 0x955555 },				\
    +	{ 40000, 15, 1,  2,  0xb, 0 }					\
    +}
    +
    +#define	SIBA_CC_PMU0_PLLTAB_ENTRY					\
    +{									\
    +	{ 12000,  1, 73, 349525, }, { 13000,  2, 67, 725937, },		\
    +	{ 14400,  3, 61, 116508, }, { 15360,  4, 57, 305834, },		\
    +	{ 16200,  5, 54, 336579, }, { 16800,  6, 52, 399457, },		\
    +	{ 19200,  7, 45, 873813, }, { 19800,  8, 44, 466033, },		\
    +	{ 20000,  9, 44, 0,      }, { 25000, 10, 70, 419430, },		\
    +	{ 26000, 11, 67, 725937, }, { 30000, 12, 58, 699050, },		\
    +	{ 38400, 13, 45, 873813, }, { 40000, 14, 45, 0,      },		\
    +}
    +
    +#define	SIBA_CC_PMU_4325_BURST		1
    +#define	SIBA_CC_PMU_4325_CLBURST	3
    +#define	SIBA_CC_PMU_4325_LN		10
    +#define	SIBA_CC_PMU_4325_CRYSTAL	13
    +#define	SIBA_CC_PMU_4325_RX_PWR		15
    +#define	SIBA_CC_PMU_4325_TX_PWR		16
    +#define	SIBA_CC_PMU_4325_LOGEN_PWR	18
    +#define	SIBA_CC_PMU_4325_AFE_PWR	19
    +#define	SIBA_CC_PMU_4325_BBPLL_PWR	20
    +#define	SIBA_CC_PMU_4325_HT		21
    +#define	SIBA_CC_PMU_4328_EXT_SWITCH_PWM	0
    +#define	SIBA_CC_PMU_4328_BB_SWITCH_PWM	1
    +#define	SIBA_CC_PMU_4328_BB_SWITCH_BURST	2
    +#define	SIBA_CC_PMU_4328_BB_EXT_SWITCH_BURST	3
    +#define	SIBA_CC_PMU_4328_ILP_REQUEST	4
    +#define	SIBA_CC_PMU_4328_RADSWITCH_PWM	5	/* radio switch */
    +#define	SIBA_CC_PMU_4328_RADSWITCH_BURST	6
    +#define	SIBA_CC_PMU_4328_ROM_SWITCH	7
    +#define	SIBA_CC_PMU_4328_PA_REF		8
    +#define	SIBA_CC_PMU_4328_RADIO		9
    +#define	SIBA_CC_PMU_4328_AFE		10
    +#define	SIBA_CC_PMU_4328_PLL		11
    +#define	SIBA_CC_PMU_4328_BG_FILTBYP	12
    +#define	SIBA_CC_PMU_4328_TX_FILTBYP	13
    +#define	SIBA_CC_PMU_4328_RX_FILTBYP	14
    +#define	SIBA_CC_PMU_4328_CRYSTAL_PU	15
    +#define	SIBA_CC_PMU_4328_CRYSTAL_EN	16
    +#define	SIBA_CC_PMU_4328_BB_PLL_FILTBYP	17
    +#define	SIBA_CC_PMU_4328_RF_PLL_FILTBYP	18
    +#define	SIBA_CC_PMU_4328_BB_PLL_PU	19
    +#define	SIBA_CC_PMU_5354_BB_PLL_PU	19
    +
    +#define	SIBA_CC_PMU_4325_RES_UPDOWN					\
    +{									\
    +	{ SIBA_CC_PMU_4325_CRYSTAL, 0x1501 }				\
    +}
    +
    +#define	SIBA_CC_PMU_4325_RES_DEPEND					\
    +{									\
    +	{ SIBA_CC_PMU_4325_HT, SIBA_CC_PMU_DEP_ADD,			\
    +	  ((1 << SIBA_CC_PMU_4325_RX_PWR) |				\
    +	   (1 << SIBA_CC_PMU_4325_TX_PWR) |				\
    +	   (1 << SIBA_CC_PMU_4325_LOGEN_PWR) |				\
    +	   (1 << SIBA_CC_PMU_4325_AFE_PWR)) }				\
    +}
    +
    +#define	SIBA_CC_PMU_4328_RES_UPDOWN					\
    +{									\
    +	{ SIBA_CC_PMU_4328_EXT_SWITCH_PWM, 0x0101 },			\
    +	{ SIBA_CC_PMU_4328_BB_SWITCH_PWM, 0x1f01 },			\
    +	{ SIBA_CC_PMU_4328_BB_SWITCH_BURST, 0x010f },			\
    +	{ SIBA_CC_PMU_4328_BB_EXT_SWITCH_BURST, 0x0101 },		\
    +	{ SIBA_CC_PMU_4328_ILP_REQUEST, 0x0202 },			\
    +	{ SIBA_CC_PMU_4328_RADSWITCH_PWM, 0x0f01 },			\
    +	{ SIBA_CC_PMU_4328_RADSWITCH_BURST, 0x0f01 },			\
    +	{ SIBA_CC_PMU_4328_ROM_SWITCH, 0x0101 },			\
    +	{ SIBA_CC_PMU_4328_PA_REF, 0x0f01 },				\
    +	{ SIBA_CC_PMU_4328_RADIO, 0x0f01 },				\
    +	{ SIBA_CC_PMU_4328_AFE, 0x0f01 },				\
    +	{ SIBA_CC_PMU_4328_PLL, 0x0f01 },				\
    +	{ SIBA_CC_PMU_4328_BG_FILTBYP, 0x0101 },			\
    +	{ SIBA_CC_PMU_4328_TX_FILTBYP, 0x0101 },			\
    +	{ SIBA_CC_PMU_4328_RX_FILTBYP, 0x0101 },			\
    +	{ SIBA_CC_PMU_4328_CRYSTAL_PU, 0x0101 },			\
    +	{ SIBA_CC_PMU_4328_CRYSTAL_EN, 0xa001 },			\
    +	{ SIBA_CC_PMU_4328_BB_PLL_FILTBYP, 0x0101 },			\
    +	{ SIBA_CC_PMU_4328_RF_PLL_FILTBYP, 0x0101 },			\
    +	{ SIBA_CC_PMU_4328_BB_PLL_PU, 0x0701 },				\
    +}
    +
    +#define	SIBA_CC_PMU_4328_RES_DEPEND					\
    +{									\
    +	{ SIBA_CC_PMU_4328_ILP_REQUEST, SIBA_CC_PMU_DEP_SET,		\
    +	  ((1 << SIBA_CC_PMU_4328_EXT_SWITCH_PWM) |			\
    +	   (1 << SIBA_CC_PMU_4328_BB_SWITCH_PWM)) },			\
    +}
    +
    +#define	SIBA_CC_CHST_4325_PMUTOP_2B	0x00000200
    +
    +#define	SIBA_BAR0			0x80
    +#define	SIBA_IRQMASK			0x94
    +#define	SIBA_GPIO_IN			0xb0
    +#define	SIBA_GPIO_OUT			0xb4
    +#define	SIBA_GPIO_OUT_EN		0xb8
    +#define	SIBA_GPIO_CRYSTAL		0x40
    +#define	SIBA_GPIO_PLL			0x80
    +
    +#define	SIBA_REGWIN(x)							\
    +	(SIBA_ENUM_START + ((x) * SIBA_CORE_LEN))
     #define SIBA_CORE_LEN		0x00001000	/* Size of cfg per core */
     #define SIBA_CFG_END		0x00010000	/* Upper bound of cfg space */
     #define SIBA_MAX_CORES		(SIBA_CFG_END/SIBA_CORE_LEN)	/* #max cores */
    +#define	SIBA_ENUM_START			0x18000000U
    +#define	SIBA_ENUM_END			0x18010000U
     
    -/* offset of high ID register */
    -#define SIBA_CORE_IDLO		0x00000ff8
    -#define SIBA_CORE_IDHI		0x00000ffc
    +#define	SIBA_DMA_TRANSLATION_MASK	0xc0000000
     
    -/*
    - * Offsets of ChipCommon core registers.
    - * XXX: move to siba_cc
    - */
    -#define SIBA_CC_UART0	0x00000300	/* offset of UART0 */
    -#define SIBA_CC_UART1	0x00000400	/* offset of UART1 */
    +#define	SIBA_PCI_DMA			0x40000000U
    +#define	SIBA_TPS			0x0f18
    +#define	SIBA_TPS_BPFLAG			0x0000003f
    +#define	SIBA_IAS			0x0f90     /* Initiator Agent State */
    +#define	SIBA_IAS_INBAND_ERR		0x00020000
    +#define	SIBA_IAS_TIMEOUT		0x00040000
    +#define	SIBA_INTR_MASK			0x0f94
    +#define	SIBA_TGSLOW			0x0f98
    +#define	SIBA_TGSLOW_RESET		0x00000001	/* target state low */
    +#define	SIBA_TGSLOW_REJECT_22		0x00000002
    +#define	SIBA_TGSLOW_REJECT_23		0x00000004
    +#define	SIBA_TGSLOW_CLOCK		0x00010000
    +#define	SIBA_TGSLOW_FGC			0x00020000
    +#define	SIBA_TGSHIGH			0x0f9c
    +#define	SIBA_TGSHIGH_SERR		0x00000001
    +#define	SIBA_TGSHIGH_BUSY		0x00000004
    +#define	SIBA_TGSHIGH_DMA64		0x10000000
    +#define	SIBA_IMCFGLO			0x0fa8
    +#define	SIBA_IMCFGLO_SERTO		0x00000007
    +#define	SIBA_IMCFGLO_REQTO		0x00000070
    +#define	SIBA_IDLOW			0x0ff8
    +#define	SIBA_IDLOW_SSBREV		0xf0000000
    +#define	SIBA_IDLOW_SSBREV_22		0x00000000
    +#define	SIBA_IDLOW_SSBREV_23		0x10000000
    +#define	SIBA_IDLOW_SSBREV_24		0x40000000
    +#define	SIBA_IDLOW_SSBREV_25		0x50000000
    +#define	SIBA_IDLOW_SSBREV_26		0x60000000
    +#define	SIBA_IDLOW_SSBREV_27		0x70000000
    +#define	SIBA_IDHIGH			0x0ffc
    +#define	SIBA_IDHIGH_CORECODEMASK	0x00008FF0 /* Core Code */
    +#define	SIBA_IDHIGH_CORECODE_SHIFT	4
    +#define	SIBA_IDHIGH_CORECODE(id)					\
    +	((id & SIBA_IDHIGH_CORECODEMASK) >> SIBA_IDHIGH_CORECODE_SHIFT)
    +/* Revision Code (low part) */
    +#define	SIBA_IDHIGH_REVLO		0x0000000f
    +/* Revision Code (high part) */
    +#define	SIBA_IDHIGH_REVHI		0x00007000
    +#define	SIBA_IDHIGH_REVHI_SHIFT	8
    +#define	SIBA_IDHIGH_REV(id)						\
    +	((id & SIBA_IDHIGH_REVLO) | ((id & SIBA_IDHIGH_REVHI) >>	\
    +	    SIBA_IDHIGH_REVHI_SHIFT))
    +#define	SIBA_IDHIGH_VENDORMASK		0xFFFF0000 /* Vendor Code */
    +#define	SIBA_IDHIGH_VENDOR_SHIFT	16
    +#define	SIBA_IDHIGH_VENDOR(id)						\
    +	((id & SIBA_IDHIGH_VENDORMASK) >> SIBA_IDHIGH_VENDOR_SHIFT)
     
    -#define SIBA_CC_CCID 0x0000
    -#define  SIBA_CC_IDMASK 0x0000FFFF
    -#define  SIBA_CC_REVMASK 0x000F0000
    -#define  SIBA_CC_REVSHIFT 16
    -#define  SIBA_CC_PACKMASK 0x00F00000
    -#define  SIBA_CC_PACKSHIFT 20
    -#define  SIBA_CC_NRCORESMASK 0x0F000000
    -#define  SIBA_CC_NRCORESSHIFT 24
    +#define	SIBA_SPROMSIZE_R123		64
    +#define	SIBA_SPROMSIZE_R4		220
    +#define	SIBA_SPROM_BASE			0x1000
    +#define	SIBA_SPROM_REV_CRC		0xff00
    +#define	SIBA_SPROM1_MAC_80211BG		0x1048
    +#define	SIBA_SPROM1_MAC_ETH		0x104e
    +#define	SIBA_SPROM1_MAC_80211A		0x1054
    +#define	SIBA_SPROM1_ETHPHY		0x105a
    +#define	SIBA_SPROM1_ETHPHY_MII_ETH0	0x001f
    +#define	SIBA_SPROM1_ETHPHY_MII_ETH1	0x03e0
    +#define	SIBA_SPROM1_ETHPHY_MDIO_ETH0	(1 << 14)
    +#define	SIBA_SPROM1_ETHPHY_MDIO_ETH1	(1 << 15)
    +#define	SIBA_SPROM1_BOARDINFO		0x105c
    +#define	SIBA_SPROM1_BOARDINFO_BREV	0x00ff
    +#define	SIBA_SPROM1_BOARDINFO_CCODE	0x0f00
    +#define	SIBA_SPROM1_BOARDINFO_ANTBG	0x3000
    +#define	SIBA_SPROM1_BOARDINFO_ANTA	0xc000
    +#define	SIBA_SPROM1_PA0B0		0x105e
    +#define	SIBA_SPROM1_PA0B1		0x1060
    +#define	SIBA_SPROM1_PA0B2		0x1062
    +#define	SIBA_SPROM1_GPIOA		0x1064
    +#define	SIBA_SPROM1_GPIOA_P0		0x00ff
    +#define	SIBA_SPROM1_GPIOA_P1		0xff00
    +#define	SIBA_SPROM1_GPIOB		0x1066
    +#define	SIBA_SPROM1_GPIOB_P2		0x00ff
    +#define	SIBA_SPROM1_GPIOB_P3		0xff00
    +#define	SIBA_SPROM1_MAXPWR		0x1068
    +#define	SIBA_SPROM1_MAXPWR_BG		0x00ff
    +#define	SIBA_SPROM1_MAXPWR_A		0xff00
    +#define	SIBA_SPROM1_PA1B0		0x106a
    +#define	SIBA_SPROM1_PA1B1		0x106c
    +#define	SIBA_SPROM1_PA1B2		0x106e
    +#define	SIBA_SPROM1_TSSI		0x1070
    +#define	SIBA_SPROM1_TSSI_BG		0x00ff
    +#define	SIBA_SPROM1_TSSI_A		0xff00
    +#define	SIBA_SPROM1_BFLOW		0x1072
    +#define	SIBA_SPROM1_AGAIN		0x1074
    +#define	SIBA_SPROM1_AGAIN_BG		0x00ff
    +#define	SIBA_SPROM1_AGAIN_A		0xff00
    +#define	SIBA_SPROM2_BFHIGH		0x1038
    +#define	SIBA_SPROM3_MAC_80211BG		0x104a
    +#define	SIBA_SPROM4_MAC_80211BG		0x104c
    +#define	SIBA_SPROM4_ETHPHY		0x105a
    +#define	SIBA_SPROM4_ETHPHY_ET0A		0x001f
    +#define	SIBA_SPROM4_ETHPHY_ET1A		0x03e0
    +#define	SIBA_SPROM4_CCODE		0x1052
    +#define	SIBA_SPROM4_ANTAVAIL		0x105d
    +#define	SIBA_SPROM4_ANTAVAIL_A		0x00ff
    +#define	SIBA_SPROM4_ANTAVAIL_BG		0xff00
    +#define	SIBA_SPROM4_BFLOW		0x1044
    +#define	SIBA_SPROM4_AGAIN01		0x105e
    +#define	SIBA_SPROM4_AGAIN0		0x00ff
    +#define	SIBA_SPROM4_AGAIN1		0xff00
    +#define	SIBA_SPROM4_AGAIN23		0x1060
    +#define	SIBA_SPROM4_AGAIN2		0x00ff
    +#define	SIBA_SPROM4_AGAIN3		0xff00
    +#define	SIBA_SPROM4_BFHIGH		0x1046
    +#define	SIBA_SPROM4_MAXP_BG		0x1080
    +#define	SIBA_SPROM4_MAXP_BG_MASK	0x00ff
    +#define	SIBA_SPROM4_TSSI_BG		0xff00
    +#define	SIBA_SPROM4_MAXP_A		0x108a
    +#define	SIBA_SPROM4_MAXP_A_MASK		0x00ff
    +#define	SIBA_SPROM4_TSSI_A		0xff00
    +#define	SIBA_SPROM4_GPIOA		0x1056
    +#define	SIBA_SPROM4_GPIOA_P0		0x00ff
    +#define	SIBA_SPROM4_GPIOA_P1		0xff00
    +#define	SIBA_SPROM4_GPIOB		0x1058
    +#define	SIBA_SPROM4_GPIOB_P2		0x00ff
    +#define	SIBA_SPROM4_GPIOB_P3		0xff00
    +#define	SIBA_SPROM5_BFLOW		0x104a
    +#define	SIBA_SPROM5_BFHIGH		0x104c
    +#define	SIBA_SPROM5_MAC_80211BG		0x1052
    +#define	SIBA_SPROM5_CCODE		0x1044
    +#define	SIBA_SPROM5_GPIOA		0x1076
    +#define	SIBA_SPROM5_GPIOA_P0		0x00ff
    +#define	SIBA_SPROM5_GPIOA_P1		0xff00
    +#define	SIBA_SPROM5_GPIOB		0x1078
    +#define	SIBA_SPROM5_GPIOB_P2		0x00ff
    +#define	SIBA_SPROM5_GPIOB_P3		0xff00
    +#define	SIBA_SPROM8_BFLOW		0x1084
    +#define	SIBA_SPROM8_BFHIGH		0x1086
    +#define	SIBA_SPROM8_CCODE		0x1092
    +#define	SIBA_SPROM8_ANTAVAIL		0x109c
    +#define	SIBA_SPROM8_ANTAVAIL_A		0xff00
    +#define	SIBA_SPROM8_ANTAVAIL_BG		0x00ff
    +#define	SIBA_SPROM8_AGAIN01		0x109e
    +#define	SIBA_SPROM8_AGAIN0		0x00ff
    +#define	SIBA_SPROM8_AGAIN1		0xff00
    +#define	SIBA_SPROM8_AGAIN23		0x10a0
    +#define	SIBA_SPROM8_AGAIN2		0x00ff
    +#define	SIBA_SPROM8_AGAIN3		0xff00
    +#define	SIBA_SPROM8_GPIOA		0x1096
    +#define	SIBA_SPROM8_GPIOA_P0		0x00ff
    +#define	SIBA_SPROM8_GPIOA_P1		0xff00
    +#define	SIBA_SPROM8_GPIOB		0x1098
    +#define	SIBA_SPROM8_GPIOB_P2		0x00ff
    +#define	SIBA_SPROM8_GPIOB_P3		0xff00
    +#define	SIBA_SPROM8_MAXP_BG		0x10c0
    +#define	SIBA_SPROM8_MAXP_BG_MASK	0x00ff
    +#define	SIBA_SPROM8_TSSI_BG		0xff00
    +#define	SIBA_SPROM8_MAXP_A		0x10c8
    +#define	SIBA_SPROM8_MAXP_A_MASK		0x00ff
    +#define	SIBA_SPROM8_TSSI_A		0xff00
     
    -#define  SIBA_IDHIGH_RCLO	0x0000000F /* Revision Code (low part) */
    -#define  SIBA_IDHIGH_CC		0x00008FF0 /* Core Code */
    -#define  SIBA_IDHIGH_CC_SHIFT	4
    -#define  SIBA_IDHIGH_RCHI	0x00007000 /* Revision Code (high part) */
    -#define  SIBA_IDHIGH_RCHI_SHIFT	8
    -#define  SIBA_IDHIGH_VC		0xFFFF0000 /* Vendor Code */
    -#define  SIBA_IDHIGH_VC_SHIFT	16
    +#define	SIBA_BOARDVENDOR_DELL		0x1028
    +#define	SIBA_BOARDVENDOR_BCM		0x14e4
    +#define	SIBA_BOARD_BCM4309G		0x0421
    +#define	SIBA_BOARD_MP4318		0x044a
    +#define	SIBA_BOARD_BU4306		0x0416
    +#define	SIBA_BOARD_BU4309		0x040a
     
    -#define SIBA_CCID_BCM4710	0x4710
    -#define SIBA_CCID_BCM4704	0x4704
    -#define SIBA_CCID_SENTRY5	0x5365
    +#define	SIBA_PCICORE_BCAST_ADDR		SIBA_CC_BCAST_ADDR
    +#define	SIBA_PCICORE_BCAST_DATA		SIBA_CC_BCAST_DATA
    +#define	SIBA_PCICORE_SBTOPCI0		0x0100
    +#define	SIBA_PCICORE_SBTOPCI1		0x0104
    +#define	SIBA_PCICORE_SBTOPCI2		0x0108
    +#define	SIBA_PCICORE_MDIO_CTL		0x0128
    +#define	SIBA_PCICORE_MDIO_DATA		0x012c
    +#define	SIBA_PCICORE_SBTOPCI_PREF	0x00000004
    +#define	SIBA_PCICORE_SBTOPCI_BURST	0x00000008
    +#define	SIBA_PCICORE_SBTOPCI_MRM	0x00000020
     
     #endif /* _SIBA_SIBAREG_H_ */
    diff --git a/sys/dev/siba/sibavar.h b/sys/dev/siba/sibavar.h
    index f9c231b8f4c..93d4ff75128 100644
    --- a/sys/dev/siba/sibavar.h
    +++ b/sys/dev/siba/sibavar.h
    @@ -31,46 +31,8 @@
     
     #include 
     
    -struct siba_softc {
    -	device_t		 sc_dev;	/* Device ID */
    -	struct resource		*sc_mem;	/* Memory window on nexus */
    -
    -	bus_space_tag_t		 sc_bt;
    -	bus_space_handle_t	 sc_bh;
    -	bus_addr_t		 sc_maddr;
    -	bus_size_t		 sc_msize;
    -
    -	uint8_t			 sc_ncores;
    -};
    -
    -struct siba_devinfo {
    -	struct resource_list	 sdi_rl;
    -	/*devhandle_t		 sdi_devhandle; XXX*/
    -	/*struct rman sdi_intr_rman;*/
    -
    -	/* Accessors are needed for ivars below. */
    -	uint16_t		 sdi_vid;
    -	uint16_t		 sdi_devid;
    -	uint8_t			 sdi_rev;
    -	uint8_t			 sdi_idx;	/* core index on bus */
    -	uint8_t			 sdi_irq;	/* TODO */
    -};
    -
    -#define siba_read_2(sc, core, reg)				\
    -	bus_space_read_2((sc)->sc_bt, (sc)->sc_bh,		\
    -			 (core * SIBA_CORE_LEN) + (reg))
    -
    -#define siba_read_4(sc, core, reg)				\
    -	bus_space_read_4((sc)->sc_bt, (sc)->sc_bh,		\
    -			 (core * SIBA_CORE_LEN) + (reg))
    -
    -#define siba_write_2(sc, core, reg, val)			\
    -	bus_space_write_2((sc)->sc_bt, (sc)->sc_bh,		\
    -			 (core * SIBA_CORE_LEN) + (reg), (val))
    -
    -#define siba_write_4(sc, core, reg, val)			\
    -	bus_space_write_4((sc)->sc_bt, (sc)->sc_bh,		\
    -			 (core * SIBA_CORE_LEN) + (reg), (val))
    +struct siba_softc;
    +struct siba_dev_softc;
     
     enum siba_device_ivars {
     	SIBA_IVAR_VENDOR,
    @@ -89,4 +51,321 @@ SIBA_ACCESSOR(core_index,	CORE_INDEX,	uint8_t)
     
     #undef SIBA_ACCESSOR
     
    +/* XXX just for SPROM1? */
    +enum {
    +	SIBA_CCODE_WORLD,
    +	SIBA_CCODE_THAILAND,
    +	SIBA_CCODE_ISRAEL,
    +	SIBA_CCODE_JORDAN,
    +	SIBA_CCODE_CHINA,
    +	SIBA_CCODE_JAPAN,
    +	SIBA_CCODE_USA_CANADA_ANZ,
    +	SIBA_CCODE_EUROPE,
    +	SIBA_CCODE_USA_LOW,
    +	SIBA_CCODE_JAPAN_HIGH,
    +	SIBA_CCODE_ALL,
    +	SIBA_CCODE_NONE,
    +};
    +
    +#define siba_mips_read_2(sc, core, reg)				\
    +	bus_space_read_2((sc)->siba_mem_bt, (sc)->siba_mem_bh,	\
    +			 (core * SIBA_CORE_LEN) + (reg))
    +
    +#define siba_mips_read_4(sc, core, reg)				\
    +	bus_space_read_4((sc)->siba_mem_bt, (sc)->siba_mem_bh,	\
    +			 (core * SIBA_CORE_LEN) + (reg))
    +
    +#define siba_mips_write_2(sc, core, reg, val)			\
    +	bus_space_write_2((sc)->siba_mem_bt, (sc)->siba_mem_bh,	\
    +			 (core * SIBA_CORE_LEN) + (reg), (val))
    +
    +#define siba_mips_write_4(sc, core, reg, val)			\
    +	bus_space_write_4((sc)->siba_mem_bt, (sc)->siba_mem_bh,	\
    +			 (core * SIBA_CORE_LEN) + (reg), (val))
    +
    +#define	SIBA_READ_4(siba, reg)		\
    +	bus_space_read_4((siba)->siba_mem_bt, (siba)->siba_mem_bh, (reg))
    +#define	SIBA_READ_2(siba, reg)		\
    +	bus_space_read_2((siba)->siba_mem_bt, (siba)->siba_mem_bh, (reg))
    +#define	SIBA_READ_MULTI_1(siba, reg, addr, count)			\
    +	bus_space_read_multi_1((siba)->siba_mem_bt, (siba)->siba_mem_bh,\
    +	    (reg), (addr), (count))
    +#define	SIBA_READ_MULTI_2(siba, reg, addr, count)			\
    +	bus_space_read_multi_2((siba)->siba_mem_bt, (siba)->siba_mem_bh,\
    +	    (reg), (addr), (count))
    +#define	SIBA_READ_MULTI_4(siba, reg, addr, count)			\
    +	bus_space_read_multi_4((siba)->siba_mem_bt, (siba)->siba_mem_bh,\
    +	    (reg), (addr), (count))
    +
    +#define	SIBA_WRITE_4(siba, reg, val)	\
    +	bus_space_write_4((siba)->siba_mem_bt, (siba)->siba_mem_bh,	\
    +	    (reg), (val))
    +#define	SIBA_WRITE_2(siba, reg, val)	\
    +	bus_space_write_2((siba)->siba_mem_bt, (siba)->siba_mem_bh,	\
    +	    (reg), (val))
    +#define	SIBA_WRITE_MULTI_1(siba, reg, addr, count)			\
    +	bus_space_write_multi_1((siba)->siba_mem_bt, (siba)->siba_mem_bh,\
    +	    (reg), (addr), (count))
    +#define	SIBA_WRITE_MULTI_2(siba, reg, addr, count)			\
    +	bus_space_write_multi_2((siba)->siba_mem_bt, (siba)->siba_mem_bh,\
    +	    (reg), (addr), (count))
    +#define	SIBA_WRITE_MULTI_4(siba, reg, addr, count)			\
    +	bus_space_write_multi_4((siba)->siba_mem_bt, (siba)->siba_mem_bh,\
    +	    (reg), (addr), (count))
    +
    +#define	SIBA_BARRIER(siba, flags)					\
    +	bus_space_barrier((siba)->siba_mem_bt, (siba)->siba_mem_bh, (0),\
    +	    (0), (flags))
    +
    +#define	SIBA_SETBITS_4(siba, reg, bits)	\
    +	SIBA_WRITE_4((siba), (reg), SIBA_READ_4((siba), (reg)) | (bits))
    +#define	SIBA_SETBITS_2(siba, reg, bits)	\
    +	SIBA_WRITE_2((siba), (reg), SIBA_READ_2((siba), (reg)) | (bits))
    +
    +#define	SIBA_FILT_SETBITS_4(siba, reg, filt, bits) \
    +	SIBA_WRITE_4((siba), (reg), (SIBA_READ_4((siba),	\
    +	    (reg)) & (filt)) | (bits))
    +#define	SIBA_FILT_SETBITS_2(siba, reg, filt, bits)	\
    +	SIBA_WRITE_2((siba), (reg), (SIBA_READ_2((siba),	\
    +	    (reg)) & (filt)) | (bits))
    +
    +#define	SIBA_CLRBITS_4(siba, reg, bits)	\
    +	SIBA_WRITE_4((siba), (reg), SIBA_READ_4((siba), (reg)) & ~(bits))
    +#define	SIBA_CLRBITS_2(siba, reg, bits)	\
    +	SIBA_WRITE_2((siba), (reg), SIBA_READ_2((siba), (reg)) & ~(bits))
    +
    +#define	SIBA_CC_READ32(scc, offset) \
    +	siba_read_4((scc)->scc_dev, offset)
    +#define	SIBA_CC_WRITE32(scc, offset, val) \
    +	siba_write_4((scc)->scc_dev, offset, val)
    +#define	SIBA_CC_MASK32(scc, offset, mask) \
    +	SIBA_CC_WRITE32(scc, offset, SIBA_CC_READ32(scc, offset) & (mask))
    +#define	SIBA_CC_SET32(scc, offset, set) \
    +	SIBA_CC_WRITE32(scc, offset, SIBA_CC_READ32(scc, offset) | (set))
    +#define	SIBA_CC_MASKSET32(scc, offset, mask, set)	\
    +	SIBA_CC_WRITE32(scc, offset,			\
    +	    (SIBA_CC_READ32(scc, offset) & (mask)) | (set))
    +
    +enum siba_type {
    +	SIBA_TYPE_SSB,
    +	SIBA_TYPE_PCI,
    +	SIBA_TYPE_PCMCIA,
    +};
    +
    +enum siba_clock {
    +	SIBA_CLOCK_DYNAMIC,
    +	SIBA_CLOCK_SLOW,
    +	SIBA_CLOCK_FAST,
    +};
    +
    +enum siba_clksrc {
    +	SIBA_CC_CLKSRC_PCI,
    +	SIBA_CC_CLKSRC_CRYSTAL,
    +	SIBA_CC_CLKSRC_LOWPW,
    +};
    +
    +struct siba_cc_pmu0_plltab {
    +	uint16_t		freq;	/* in kHz.*/
    +	uint8_t			xf;	/* crystal frequency */
    +	uint8_t			wb_int;
    +	uint32_t		wb_frac;
    +};
    +
    +struct siba_cc_pmu1_plltab {
    +	uint16_t		freq;
    +	uint8_t			xf;
    +	uint8_t			p1div;
    +	uint8_t			p2div;
    +	uint8_t			ndiv_int;
    +	uint32_t		ndiv_frac;
    +};
    +
    +struct siba_cc_pmu_res_updown {
    +	uint8_t			res;
    +	uint16_t		updown;
    +};
    +
    +#define	SIBA_CC_PMU_DEP_SET	1
    +#define	SIBA_CC_PMU_DEP_ADD	2
    +#define	SIBA_CC_PMU_DEP_REMOVE	3
    +
    +struct siba_cc_pmu_res_depend {
    +	uint8_t			res;
    +	uint8_t			task;
    +	uint32_t		depend;
    +};
    +
    +struct siba_sprom {
    +	uint8_t			rev;		/* revision */
    +	uint8_t			mac_80211bg[6];	/* address for 802.11b/g */
    +	uint8_t			mac_eth[6];	/* address for Ethernet */
    +	uint8_t			mac_80211a[6];	/* address for 802.11a */
    +	uint8_t			mii_eth0;	/* MII address for eth0 */
    +	uint8_t			mii_eth1;	/* MII address for eth1 */
    +	uint8_t			mdio_eth0;	/* MDIO for eth0 */
    +	uint8_t			mdio_eth1;	/* MDIO for eth1 */
    +	uint8_t			brev;		/* board revision */
    +	uint8_t			ccode;		/* Country Code */
    +	uint8_t			ant_a;		/* A-PHY antenna */
    +	uint8_t			ant_bg;		/* B/G-PHY antenna */
    +	uint16_t		pa0b0;
    +	uint16_t		pa0b1;
    +	uint16_t		pa0b2;
    +	uint16_t		pa1b0;
    +	uint16_t		pa1b1;
    +	uint16_t		pa1b2;
    +	uint8_t			gpio0;
    +	uint8_t			gpio1;
    +	uint8_t			gpio2;
    +	uint8_t			gpio3;
    +	uint16_t		maxpwr_a;	/* A-PHY Max Power */
    +	uint16_t		maxpwr_bg;	/* BG-PHY Max Power */
    +	uint8_t			tssi_a;		/* Idle TSSI */
    +	uint8_t			tssi_bg;	/* Idle TSSI */
    +	uint16_t		bf_lo;		/* boardflags */
    +	uint16_t		bf_hi;		/* boardflags */
    +	struct {
    +		struct {
    +			int8_t a0, a1, a2, a3;
    +		} ghz24;
    +		struct {
    +			int8_t a0, a1, a2, a3;
    +		} ghz5;
    +	} again;	/* antenna gain */
    +};
    +
    +struct siba_cc_pmu {
    +	uint8_t				rev;	/* PMU rev */
    +	uint32_t			freq;	/* crystal freq in kHz */
    +};
    +
    +struct siba_cc {
    +	struct siba_dev_softc		*scc_dev;
    +	uint32_t			scc_caps;
    +	struct siba_cc_pmu		scc_pmu;
    +	uint16_t			scc_powerup_delay;
    +};
    +
    +struct siba_pci {
    +	struct siba_dev_softc		*spc_dev;
    +	uint8_t				spc_inited;
    +	uint8_t				spc_hostmode;
    +};
    +
    +struct siba_bus_ops {
    +	uint16_t		(*read_2)(struct siba_dev_softc *,
    +				    uint16_t);
    +	uint32_t		(*read_4)(struct siba_dev_softc *,
    +				    uint16_t);
    +	void			(*write_2)(struct siba_dev_softc *,
    +				    uint16_t, uint16_t);
    +	void			(*write_4)(struct siba_dev_softc *,
    +				    uint16_t, uint32_t);
    +	void			(*read_multi_1)(struct siba_dev_softc *,
    +				    void *, size_t, uint16_t);
    +	void			(*read_multi_2)(struct siba_dev_softc *,
    +				    void *, size_t, uint16_t);
    +	void			(*read_multi_4)(struct siba_dev_softc *,
    +				    void *, size_t, uint16_t);
    +	void			(*write_multi_1)(struct siba_dev_softc *,
    +				    const void *, size_t, uint16_t);
    +	void			(*write_multi_2)(struct siba_dev_softc *,
    +				    const void *, size_t, uint16_t);
    +	void			(*write_multi_4)(struct siba_dev_softc *,
    +				    const void *, size_t, uint16_t);
    +};
    +
    +struct siba_dev_softc {
    +	struct siba_softc		*sd_bus;
    +	struct siba_devid		sd_id;
    +	const struct siba_bus_ops	*sd_ops;
    +
    +	uint8_t				sd_coreidx;
    +};
    +
    +struct siba_devinfo {
    +	struct resource_list		 sdi_rl;
    +	/*devhandle_t			 sdi_devhandle; XXX*/
    +	/*struct rman sdi_intr_rman;*/
    +
    +	/* Accessors are needed for ivars below. */
    +	uint16_t			 sdi_vid;
    +	uint16_t			 sdi_devid;
    +	uint8_t				 sdi_rev;
    +	uint8_t				 sdi_idx;	/* core index on bus */
    +	uint8_t				 sdi_irq;	/* TODO */
    +};
    +
    +struct siba_softc {
    +	/*
    +	 * common variables which used for siba(4) bus and siba_bwn bridge.
    +	 */
    +	device_t			siba_dev;	/* Device ID */
    +	struct resource			*siba_mem_res;
    +	bus_space_tag_t			siba_mem_bt;
    +	bus_space_handle_t		siba_mem_bh;
    +	bus_addr_t			siba_maddr;
    +	bus_size_t			siba_msize;
    +	uint8_t				siba_ncores;
    +
    +	/*
    +	 * the following variables are only used for siba_bwn bridge.
    +	 */
    +
    +	enum siba_type			siba_type;
    +	int				siba_invalid;
    +
    +	struct siba_dev_softc		*siba_curdev;	/* only for PCI */
    +	struct siba_dev_softc		siba_devs[SIBA_MAX_CORES];
    +	int				siba_ndevs;
    +
    +	uint16_t			siba_pci_vid;
    +	uint16_t			siba_pci_did;
    +	uint16_t			siba_pci_subvid;
    +	uint16_t			siba_pci_subdid;
    +	int				siba_mem_rid;
    +
    +	uint16_t			siba_chipid;	/* for CORE 0 */
    +	uint16_t			siba_chiprev;
    +	uint8_t				siba_chippkg;
    +
    +	struct siba_cc			siba_cc;		/* ChipCommon */
    +	struct siba_pci			siba_pci;	/* PCI-core */
    +	const struct siba_bus_ops	*siba_ops;
    +
    +	/* board informations */
    +	uint16_t			siba_board_vendor;
    +	uint16_t			siba_board_type;
    +	uint16_t			siba_board_rev;
    +	struct siba_sprom		siba_sprom;	/* SPROM */
    +	uint16_t			siba_spromsize;	/* in word size */
    +};
    +
    +void		siba_powerup(struct siba_softc *, int);
    +uint16_t	siba_read_2(struct siba_dev_softc *, uint16_t);
    +void		siba_write_2(struct siba_dev_softc *, uint16_t, uint16_t);
    +uint32_t	siba_read_4(struct siba_dev_softc *, uint16_t);
    +void		siba_write_4(struct siba_dev_softc *, uint16_t, uint32_t);
    +void		siba_dev_up(struct siba_dev_softc *, uint32_t);
    +void		siba_dev_down(struct siba_dev_softc *, uint32_t);
    +int		siba_powerdown(struct siba_softc *);
    +int		siba_dev_isup(struct siba_dev_softc *);
    +void		siba_pcicore_intr(struct siba_pci *, struct siba_dev_softc *);
    +uint32_t	siba_dma_translation(struct siba_dev_softc *);
    +void		*siba_dma_alloc_consistent(struct siba_dev_softc *, size_t,
    +		    bus_addr_t *);
    +void		siba_read_multi_1(struct siba_dev_softc *, void *, size_t,
    +		    uint16_t);
    +void		siba_read_multi_2(struct siba_dev_softc *, void *, size_t,
    +		    uint16_t);
    +void		siba_read_multi_4(struct siba_dev_softc *, void *, size_t,
    +		    uint16_t);
    +void		siba_write_multi_1(struct siba_dev_softc *, const void *,
    +		    size_t, uint16_t);
    +void		siba_write_multi_2(struct siba_dev_softc *, const void *,
    +		    size_t, uint16_t);
    +void		siba_write_multi_4(struct siba_dev_softc *, const void *,
    +		    size_t, uint16_t);
    +void		siba_barrier(struct siba_dev_softc *, int);
    +
     #endif /* _SIBA_SIBAVAR_H_ */
    diff --git a/sys/modules/siba_bwn/Makefile b/sys/modules/siba_bwn/Makefile
    new file mode 100644
    index 00000000000..433d37fe261
    --- /dev/null
    +++ b/sys/modules/siba_bwn/Makefile
    @@ -0,0 +1,9 @@
    +# $FreeBSD$
    +
    +.PATH: ${.CURDIR}/../../dev/siba
    +
    +KMOD=	siba_bwn
    +SRCS=	siba_core.c siba_bwn.c sibareg.h sibavar.h
    +SRCS+=	device_if.h bus_if.h pci_if.h
    +
    +.include 
    
    From 509fc65cb080198103adef63d815d734f4fb6c2c Mon Sep 17 00:00:00 2001
    From: Luigi Rizzo 
    Date: Tue, 20 Apr 2010 21:33:14 +0000
    Subject: [PATCH 2048/2592] MFC r206551 (forgotten in previous commit): fix
     builds with ktr
    
    ---
     sys/geom/sched/g_sched.c | 15 ++++-----------
     1 file changed, 4 insertions(+), 11 deletions(-)
    
    diff --git a/sys/geom/sched/g_sched.c b/sys/geom/sched/g_sched.c
    index 8b0e68ac44a..6f339b92d9e 100644
    --- a/sys/geom/sched/g_sched.c
    +++ b/sys/geom/sched/g_sched.c
    @@ -754,13 +754,6 @@ g_gsched_modevent(module_t mod, int cmd, void *arg)
     
     #ifdef KTR
     #define	TRC_BIO_EVENT(e, bp)	g_sched_trace_bio_ ## e (bp)
    -static inline int
    -g_sched_issuer_pid(struct bio *bp)
    -{
    -	struct thread *thread = g_sched_issuer(bp);
    -
    -	return (thread->td_tid);
    -}
     
     static inline char
     g_sched_type(struct bio *bp)
    @@ -777,7 +770,7 @@ static inline void
     g_sched_trace_bio_START(struct bio *bp)
     {
     
    -	CTR5(KTR_GSCHED, "S %d %c %lu/%lu %lu", g_sched_issuer_pid(bp),
    +	CTR5(KTR_GSCHED, "S %lu %c %lu/%lu %lu", g_sched_classify(bp),
     	    g_sched_type(bp), bp->bio_offset / ULONG_MAX,
     	    bp->bio_offset, bp->bio_length);
     }
    @@ -786,13 +779,13 @@ static inline void
     g_sched_trace_bio_DONE(struct bio *bp)
     {
     
    -	CTR5(KTR_GSCHED, "D %d %c %lu/%lu %lu", g_sched_issuer_pid(bp),
    +	CTR5(KTR_GSCHED, "D %lu %c %lu/%lu %lu", g_sched_classify(bp),
     	    g_sched_type(bp), bp->bio_offset / ULONG_MAX,
     	    bp->bio_offset, bp->bio_length);
     }
    -#else
    +#else /* !KTR */
     #define	TRC_BIO_EVENT(e, bp)
    -#endif
    +#endif /* !KTR */
     
     /*
      * g_sched_done() and g_sched_start() dispatch the geom requests to
    
    From f90970557d510375352a3c6d85744323a39b3bb4 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:35:48 +0000
    Subject: [PATCH 2049/2592] MFC r203320:   Hook up the siba_bwn module to the
     build.
    
    ---
     sys/modules/Makefile | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/modules/Makefile b/sys/modules/Makefile
    index aebdcea188c..dc088d22d27 100644
    --- a/sys/modules/Makefile
    +++ b/sys/modules/Makefile
    @@ -248,6 +248,7 @@ SUBDIR=	${_3dfx} \
     	sdhci \
     	sem \
     	sf \
    +	siba_bwn \
     	siis \
     	sis \
     	sk \
    
    From a9a1ff5e807ae39fb672c30e2f94dfbdbe22fc60 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:37:47 +0000
    Subject: [PATCH 2050/2592] MFC r203944:   supports SPROM rev8 informations
     properly which are used to support   low-power PHY of bwn(4) and LDO voltage
     adjustments.
    
    ---
     sys/dev/siba/siba_core.c | 121 ++++++++++++++++++++++++++++++++++++++-
     sys/dev/siba/sibareg.h   |  62 +++++++++++++++++---
     sys/dev/siba/sibavar.h   |  37 ++++++++++++
     3 files changed, 212 insertions(+), 8 deletions(-)
    
    diff --git a/sys/dev/siba/siba_core.c b/sys/dev/siba/siba_core.c
    index b2168f55971..d19771dac9d 100644
    --- a/sys/dev/siba/siba_core.c
    +++ b/sys/dev/siba/siba_core.c
    @@ -1457,6 +1457,9 @@ siba_crc8(uint8_t crc, uint8_t data)
     	(((__x) & (__mask)) / SIBA_LOWEST_SET_BIT(__mask))
     #define	SIBA_SHIFTOUT(_var, _offset, _mask)				\
     	out->_var = SIBA_SHIFTOUT_SUB(in[SIBA_OFFSET(_offset)], (_mask))
    +#define SIBA_SHIFTOUT_4(_var, _offset, _mask, _shift)			\
    +	out->_var = ((((uint32_t)in[SIBA_OFFSET((_offset)+2)] << 16 |	\
    +	    in[SIBA_OFFSET(_offset)]) & (_mask)) >> (_shift))
     
     static void
     siba_sprom_r123(struct siba_sprom *out, const uint16_t *in)
    @@ -1511,6 +1514,7 @@ siba_sprom_r123(struct siba_sprom *out, const uint16_t *in)
     	SIBA_SHIFTOUT(gpio1, SIBA_SPROM1_GPIOA, SIBA_SPROM1_GPIOA_P1);
     	SIBA_SHIFTOUT(gpio2, SIBA_SPROM1_GPIOB, SIBA_SPROM1_GPIOB_P2);
     	SIBA_SHIFTOUT(gpio3, SIBA_SPROM1_GPIOB, SIBA_SPROM1_GPIOB_P3);
    +
     	SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM1_MAXPWR, SIBA_SPROM1_MAXPWR_A);
     	SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM1_MAXPWR, SIBA_SPROM1_MAXPWR_BG);
     	SIBA_SHIFTOUT(tssi_a, SIBA_SPROM1_TSSI, SIBA_SPROM1_TSSI_A);
    @@ -1587,22 +1591,61 @@ siba_sprom_r8(struct siba_sprom *out, const uint16_t *in)
     	uint16_t v;
     
     	for (i = 0; i < 3; i++) {
    -		v = in[SIBA_OFFSET(SIBA_SPROM1_MAC_80211BG) + i];
    +		v = in[SIBA_OFFSET(SIBA_SPROM8_MAC_80211BG) + i];
     		*(((uint16_t *)out->mac_80211bg) + i) = htobe16(v);
     	}
     	SIBA_SHIFTOUT(ccode, SIBA_SPROM8_CCODE, 0xffff);
     	SIBA_SHIFTOUT(bf_lo, SIBA_SPROM8_BFLOW, 0xffff);
     	SIBA_SHIFTOUT(bf_hi, SIBA_SPROM8_BFHIGH, 0xffff);
    +	SIBA_SHIFTOUT(bf2_lo, SIBA_SPROM8_BFL2LO, 0xffff);
    +	SIBA_SHIFTOUT(bf2_hi, SIBA_SPROM8_BFL2HI, 0xffff);
     	SIBA_SHIFTOUT(ant_a, SIBA_SPROM8_ANTAVAIL, SIBA_SPROM8_ANTAVAIL_A);
     	SIBA_SHIFTOUT(ant_bg, SIBA_SPROM8_ANTAVAIL, SIBA_SPROM8_ANTAVAIL_BG);
     	SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM8_MAXP_BG, SIBA_SPROM8_MAXP_BG_MASK);
     	SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM8_MAXP_BG, SIBA_SPROM8_TSSI_BG);
     	SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM8_MAXP_A, SIBA_SPROM8_MAXP_A_MASK);
     	SIBA_SHIFTOUT(tssi_a, SIBA_SPROM8_MAXP_A, SIBA_SPROM8_TSSI_A);
    +	SIBA_SHIFTOUT(maxpwr_ah, SIBA_SPROM8_MAXP_AHL,
    +	    SIBA_SPROM8_MAXP_AH_MASK);
    +	SIBA_SHIFTOUT(maxpwr_al, SIBA_SPROM8_MAXP_AHL,
    +	    SIBA_SPROM8_MAXP_AL_MASK);
     	SIBA_SHIFTOUT(gpio0, SIBA_SPROM8_GPIOA, SIBA_SPROM8_GPIOA_P0);
     	SIBA_SHIFTOUT(gpio1, SIBA_SPROM8_GPIOA, SIBA_SPROM8_GPIOA_P1);
     	SIBA_SHIFTOUT(gpio2, SIBA_SPROM8_GPIOB, SIBA_SPROM8_GPIOB_P2);
     	SIBA_SHIFTOUT(gpio3, SIBA_SPROM8_GPIOB, SIBA_SPROM8_GPIOB_P3);
    +	SIBA_SHIFTOUT(tri2g, SIBA_SPROM8_TRI25G, SIBA_SPROM8_TRI2G);
    +	SIBA_SHIFTOUT(tri5g, SIBA_SPROM8_TRI25G, SIBA_SPROM8_TRI5G);
    +	SIBA_SHIFTOUT(tri5gl, SIBA_SPROM8_TRI5GHL, SIBA_SPROM8_TRI5GL);
    +	SIBA_SHIFTOUT(tri5gh, SIBA_SPROM8_TRI5GHL, SIBA_SPROM8_TRI5GH);
    +	SIBA_SHIFTOUT(rxpo2g, SIBA_SPROM8_RXPO, SIBA_SPROM8_RXPO2G);
    +	SIBA_SHIFTOUT(rxpo5g, SIBA_SPROM8_RXPO, SIBA_SPROM8_RXPO5G);
    +	SIBA_SHIFTOUT(rssismf2g, SIBA_SPROM8_RSSIPARM2G, SIBA_SPROM8_RSSISMF2G);
    +	SIBA_SHIFTOUT(rssismc2g, SIBA_SPROM8_RSSIPARM2G, SIBA_SPROM8_RSSISMC2G);
    +	SIBA_SHIFTOUT(rssisav2g, SIBA_SPROM8_RSSIPARM2G, SIBA_SPROM8_RSSISAV2G);
    +	SIBA_SHIFTOUT(bxa2g, SIBA_SPROM8_RSSIPARM2G, SIBA_SPROM8_BXA2G);
    +	SIBA_SHIFTOUT(rssismf5g, SIBA_SPROM8_RSSIPARM5G, SIBA_SPROM8_RSSISMF5G);
    +	SIBA_SHIFTOUT(rssismc5g, SIBA_SPROM8_RSSIPARM5G, SIBA_SPROM8_RSSISMC5G);
    +	SIBA_SHIFTOUT(rssisav5g, SIBA_SPROM8_RSSIPARM5G, SIBA_SPROM8_RSSISAV5G);
    +	SIBA_SHIFTOUT(bxa5g, SIBA_SPROM8_RSSIPARM5G, SIBA_SPROM8_BXA5G);
    +
    +	SIBA_SHIFTOUT(pa0b0, SIBA_SPROM8_PA0B0, 0xffff);
    +	SIBA_SHIFTOUT(pa0b1, SIBA_SPROM8_PA0B1, 0xffff);
    +	SIBA_SHIFTOUT(pa0b2, SIBA_SPROM8_PA0B2, 0xffff);
    +	SIBA_SHIFTOUT(pa1b0, SIBA_SPROM8_PA1B0, 0xffff);
    +	SIBA_SHIFTOUT(pa1b1, SIBA_SPROM8_PA1B1, 0xffff);
    +	SIBA_SHIFTOUT(pa1b2, SIBA_SPROM8_PA1B2, 0xffff);
    +	SIBA_SHIFTOUT(pa1lob0, SIBA_SPROM8_PA1LOB0, 0xffff);
    +	SIBA_SHIFTOUT(pa1lob1, SIBA_SPROM8_PA1LOB1, 0xffff);
    +	SIBA_SHIFTOUT(pa1lob2, SIBA_SPROM8_PA1LOB2, 0xffff);
    +	SIBA_SHIFTOUT(pa1hib0, SIBA_SPROM8_PA1HIB0, 0xffff);
    +	SIBA_SHIFTOUT(pa1hib1, SIBA_SPROM8_PA1HIB1, 0xffff);
    +	SIBA_SHIFTOUT(pa1hib2, SIBA_SPROM8_PA1HIB2, 0xffff);
    +	SIBA_SHIFTOUT(cck2gpo, SIBA_SPROM8_CCK2GPO, 0xffff);
    +
    +	SIBA_SHIFTOUT_4(ofdm2gpo, SIBA_SPROM8_OFDM2GPO, 0xffffffff, 0);
    +	SIBA_SHIFTOUT_4(ofdm5glpo, SIBA_SPROM8_OFDM5GLPO, 0xffffffff, 0);
    +	SIBA_SHIFTOUT_4(ofdm5gpo, SIBA_SPROM8_OFDM5GPO, 0xffffffff, 0);
    +	SIBA_SHIFTOUT_4(ofdm5ghpo, SIBA_SPROM8_OFDM5GHPO, 0xffffffff, 0);
     
     	/* antenna gain */
     	SIBA_SHIFTOUT(again.ghz24.a0, SIBA_SPROM8_AGAIN01, SIBA_SPROM8_AGAIN0);
    @@ -2005,3 +2048,79 @@ siba_core_resume(struct siba_softc *siba)
     
     	return (0);
     }
    +
    +static void
    +siba_cc_regctl_setmask(struct siba_cc *cc, uint32_t offset, uint32_t mask,
    +    uint32_t set)
    +{
    +
    +	SIBA_CC_READ32(cc, SIBA_CC_REGCTL_ADDR);
    +	SIBA_CC_WRITE32(cc, SIBA_CC_REGCTL_ADDR, offset);
    +	SIBA_CC_READ32(cc, SIBA_CC_REGCTL_ADDR);
    +	SIBA_CC_WRITE32(cc, SIBA_CC_REGCTL_DATA,
    +	    (SIBA_CC_READ32(cc, SIBA_CC_REGCTL_DATA) & mask) | set);
    +	SIBA_CC_READ32(cc, SIBA_CC_REGCTL_DATA);
    +}
    +
    +void
    +siba_cc_pmu_set_ldovolt(struct siba_cc *scc, int id, uint32_t volt)
    +{
    +	struct siba_softc *siba = scc->scc_dev->sd_bus;
    +	uint32_t *p = NULL, info[5][3] = {
    +		{ 2, 25,  0xf },
    +		{ 3,  1,  0xf },
    +		{ 3,  9,  0xf },
    +		{ 3, 17, 0x3f },
    +		{ 0, 21, 0x3f }
    +	};
    +
    +	if (siba->siba_chipid == 0x4312) {
    +		if (id != SIBA_LDO_PAREF)
    +			return;
    +		p = info[4];
    +		siba_cc_regctl_setmask(scc, p[0], ~(p[2] << p[1]),
    +		    (volt & p[2]) << p[1]);
    +		return;
    +	}
    +	if (siba->siba_chipid == 0x4328 || siba->siba_chipid == 0x5354) {
    +		switch (id) {
    +		case SIBA_LDO_PAREF:
    +			p = info[3];
    +			break;
    +		case SIBA_LDO_VOLT1:
    +			p = info[0];
    +			break;
    +		case SIBA_LDO_VOLT2:
    +			p = info[1];
    +			break;
    +		case SIBA_LDO_VOLT3:
    +			p = info[2];
    +			break;
    +		default:
    +			KASSERT(0 == 1,
    +			    ("%s: unsupported voltage ID %#x", __func__, id));
    +			return;
    +		}
    +		siba_cc_regctl_setmask(scc, p[0], ~(p[2] << p[1]),
    +		    (volt & p[2]) << p[1]);
    +	}
    +}
    +
    +void
    +siba_cc_pmu_set_ldoparef(struct siba_cc *scc, uint8_t on)
    +{
    +	struct siba_softc *siba = scc->scc_dev->sd_bus;
    +	int ldo;
    +
    +	ldo = ((siba->siba_chipid == 0x4312) ? SIBA_CC_PMU_4312_PA_REF :
    +	    ((siba->siba_chipid == 0x4328) ? SIBA_CC_PMU_4328_PA_REF :
    +	    ((siba->siba_chipid == 0x5354) ? SIBA_CC_PMU_5354_PA_REF : -1)));
    +	if (ldo == -1)
    +		return;
    +
    +	if (on)
    +		SIBA_CC_SET32(scc, SIBA_CC_PMU_MINRES, 1 << ldo);
    +	else
    +		SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, ~(1 << ldo));
    +	SIBA_CC_READ32(scc, SIBA_CC_PMU_MINRES);
    +}
    diff --git a/sys/dev/siba/sibareg.h b/sys/dev/siba/sibareg.h
    index 9aa9e7cf778..c2a4fdbfbd7 100644
    --- a/sys/dev/siba/sibareg.h
    +++ b/sys/dev/siba/sibareg.h
    @@ -32,7 +32,7 @@
      */
     
     #ifndef _SIBA_SIBAREG_H_
    -#define _SIBA_SIBAREG_H_
    +#define	_SIBA_SIBAREG_H_
     
     #define	PCI_DEVICE_ID_BCM4401		0x4401
     #define	PCI_DEVICE_ID_BCM4401B0		0x4402
    @@ -92,6 +92,8 @@
     #define	SIBA_CC_PMU_TABSEL		0x0620
     #define	SIBA_CC_PMU_DEPMSK		0x0624
     #define	SIBA_CC_PMU_UPDNTM		0x0628
    +#define	SIBA_CC_REGCTL_ADDR		0x0658
    +#define	SIBA_CC_REGCTL_DATA		0x065c
     #define	SIBA_CC_PLLCTL_ADDR		0x0660
     #define	SIBA_CC_PLLCTL_DATA		0x0664
     
    @@ -148,6 +150,7 @@
     	{ 38400, 13, 45, 873813, }, { 40000, 14, 45, 0,      },		\
     }
     
    +#define	SIBA_CC_PMU_4312_PA_REF		2
     #define	SIBA_CC_PMU_4325_BURST		1
     #define	SIBA_CC_PMU_4325_CLBURST	3
     #define	SIBA_CC_PMU_4325_LN		10
    @@ -178,6 +181,7 @@
     #define	SIBA_CC_PMU_4328_BB_PLL_FILTBYP	17
     #define	SIBA_CC_PMU_4328_RF_PLL_FILTBYP	18
     #define	SIBA_CC_PMU_4328_BB_PLL_PU	19
    +#define	SIBA_CC_PMU_5354_PA_REF		8
     #define	SIBA_CC_PMU_5354_BB_PLL_PU	19
     
     #define	SIBA_CC_PMU_4325_RES_UPDOWN					\
    @@ -237,9 +241,9 @@
     
     #define	SIBA_REGWIN(x)							\
     	(SIBA_ENUM_START + ((x) * SIBA_CORE_LEN))
    -#define SIBA_CORE_LEN		0x00001000	/* Size of cfg per core */
    -#define SIBA_CFG_END		0x00010000	/* Upper bound of cfg space */
    -#define SIBA_MAX_CORES		(SIBA_CFG_END/SIBA_CORE_LEN)	/* #max cores */
    +#define	SIBA_CORE_LEN		0x00001000	/* Size of cfg per core */
    +#define	SIBA_CFG_END		0x00010000	/* Upper bound of cfg space */
    +#define	SIBA_MAX_CORES		(SIBA_CFG_END/SIBA_CORE_LEN)	/* #max cores */
     #define	SIBA_ENUM_START			0x18000000U
     #define	SIBA_ENUM_END			0x18010000U
     
    @@ -372,6 +376,9 @@
     #define	SIBA_SPROM5_GPIOB_P3		0xff00
     #define	SIBA_SPROM8_BFLOW		0x1084
     #define	SIBA_SPROM8_BFHIGH		0x1086
    +#define	SIBA_SPROM8_BFL2LO		0x1088
    +#define	SIBA_SPROM8_BFL2HI		0x108a
    +#define	SIBA_SPROM8_MAC_80211BG		0x108c
     #define	SIBA_SPROM8_CCODE		0x1092
     #define	SIBA_SPROM8_ANTAVAIL		0x109c
     #define	SIBA_SPROM8_ANTAVAIL_A		0xff00
    @@ -379,21 +386,60 @@
     #define	SIBA_SPROM8_AGAIN01		0x109e
     #define	SIBA_SPROM8_AGAIN0		0x00ff
     #define	SIBA_SPROM8_AGAIN1		0xff00
    -#define	SIBA_SPROM8_AGAIN23		0x10a0
    -#define	SIBA_SPROM8_AGAIN2		0x00ff
    -#define	SIBA_SPROM8_AGAIN3		0xff00
     #define	SIBA_SPROM8_GPIOA		0x1096
     #define	SIBA_SPROM8_GPIOA_P0		0x00ff
     #define	SIBA_SPROM8_GPIOA_P1		0xff00
     #define	SIBA_SPROM8_GPIOB		0x1098
     #define	SIBA_SPROM8_GPIOB_P2		0x00ff
     #define	SIBA_SPROM8_GPIOB_P3		0xff00
    +#define	SIBA_SPROM8_AGAIN23		0x10a0
    +#define	SIBA_SPROM8_AGAIN2		0x00ff
    +#define	SIBA_SPROM8_AGAIN3		0xff00
    +#define	SIBA_SPROM8_RSSIPARM2G		0x10a4
    +#define	SIBA_SPROM8_RSSISMF2G		0x000f
    +#define	SIBA_SPROM8_RSSISMC2G		0x00f0
    +#define	SIBA_SPROM8_RSSISAV2G		0x0700	/* BITMASK */
    +#define	SIBA_SPROM8_BXA2G		0x1800	/* BITMASK */
    +#define	SIBA_SPROM8_RSSIPARM5G		0x10a6
    +#define	SIBA_SPROM8_RSSISMF5G		0x000f
    +#define	SIBA_SPROM8_RSSISMC5G		0x00f0
    +#define	SIBA_SPROM8_RSSISAV5G		0x0700	/* BITMASK */
    +#define	SIBA_SPROM8_BXA5G		0x1800	/* BITMASK */
    +#define	SIBA_SPROM8_TRI25G		0x10a8
    +#define	SIBA_SPROM8_TRI2G		0x00ff
    +#define	SIBA_SPROM8_TRI5G		0xff00
    +#define	SIBA_SPROM8_TRI5GHL		0x10aa
    +#define	SIBA_SPROM8_TRI5GL		0x00ff
    +#define	SIBA_SPROM8_TRI5GH		0xff00
    +#define	SIBA_SPROM8_RXPO		0x10ac
    +#define	SIBA_SPROM8_RXPO2G		0x00ff
    +#define	SIBA_SPROM8_RXPO5G		0xff00
     #define	SIBA_SPROM8_MAXP_BG		0x10c0
     #define	SIBA_SPROM8_MAXP_BG_MASK	0x00ff
     #define	SIBA_SPROM8_TSSI_BG		0xff00
    +#define	SIBA_SPROM8_PA0B0		0x10c2
    +#define	SIBA_SPROM8_PA0B1		0x10c4
    +#define	SIBA_SPROM8_PA0B2		0x10c6
     #define	SIBA_SPROM8_MAXP_A		0x10c8
     #define	SIBA_SPROM8_MAXP_A_MASK		0x00ff
     #define	SIBA_SPROM8_TSSI_A		0xff00
    +#define	SIBA_SPROM8_MAXP_AHL		0x10ca
    +#define	SIBA_SPROM8_MAXP_AH_MASK	0x00ff
    +#define	SIBA_SPROM8_MAXP_AL_MASK	0xff00
    +#define	SIBA_SPROM8_PA1B0		0x10cc
    +#define	SIBA_SPROM8_PA1B1		0x10ce
    +#define	SIBA_SPROM8_PA1B2		0x10d0
    +#define	SIBA_SPROM8_PA1LOB0		0x10d2
    +#define	SIBA_SPROM8_PA1LOB1		0x10d4
    +#define	SIBA_SPROM8_PA1LOB2		0x10d6
    +#define	SIBA_SPROM8_PA1HIB0		0x10d8
    +#define	SIBA_SPROM8_PA1HIB1		0x10da
    +#define	SIBA_SPROM8_PA1HIB2		0x10dc
    +#define	SIBA_SPROM8_CCK2GPO		0x1140
    +#define	SIBA_SPROM8_OFDM2GPO		0x1142
    +#define	SIBA_SPROM8_OFDM5GPO		0x1146
    +#define	SIBA_SPROM8_OFDM5GLPO		0x114a
    +#define	SIBA_SPROM8_OFDM5GHPO		0x114e
     
     #define	SIBA_BOARDVENDOR_DELL		0x1028
     #define	SIBA_BOARDVENDOR_BCM		0x14e4
    @@ -413,4 +459,6 @@
     #define	SIBA_PCICORE_SBTOPCI_BURST	0x00000008
     #define	SIBA_PCICORE_SBTOPCI_MRM	0x00000020
     
    +#define	SIBA_CHIPPACK_BCM4712S     1       /* Small 200pin 4712 */
    +
     #endif /* _SIBA_SIBAREG_H_ */
    diff --git a/sys/dev/siba/sibavar.h b/sys/dev/siba/sibavar.h
    index 93d4ff75128..307903b9920 100644
    --- a/sys/dev/siba/sibavar.h
    +++ b/sys/dev/siba/sibavar.h
    @@ -214,16 +214,46 @@ struct siba_sprom {
     	uint16_t		pa1b0;
     	uint16_t		pa1b1;
     	uint16_t		pa1b2;
    +	uint16_t		pa1lob0;
    +	uint16_t		pa1lob1;
    +	uint16_t		pa1lob2;
    +	uint16_t		pa1hib0;
    +	uint16_t		pa1hib1;
    +	uint16_t		pa1hib2;
     	uint8_t			gpio0;
     	uint8_t			gpio1;
     	uint8_t			gpio2;
     	uint8_t			gpio3;
    +	uint16_t		maxpwr_al;
     	uint16_t		maxpwr_a;	/* A-PHY Max Power */
    +	uint16_t		maxpwr_ah;
     	uint16_t		maxpwr_bg;	/* BG-PHY Max Power */
    +	uint8_t			rxpo2g;
    +	uint8_t			rxpo5g;
     	uint8_t			tssi_a;		/* Idle TSSI */
     	uint8_t			tssi_bg;	/* Idle TSSI */
    +	uint8_t			tri2g;
    +	uint8_t			tri5gl;
    +	uint8_t			tri5g;
    +	uint8_t			tri5gh;
    +	uint8_t			rssisav2g;
    +	uint8_t			rssismc2g;
    +	uint8_t			rssismf2g;
    +	uint8_t			bxa2g;
    +	uint8_t			rssisav5g;
    +	uint8_t			rssismc5g;
    +	uint8_t			rssismf5g;
    +	uint8_t			bxa5g;
    +	uint16_t		cck2gpo;
    +	uint32_t		ofdm2gpo;
    +	uint32_t		ofdm5glpo;
    +	uint32_t		ofdm5gpo;
    +	uint32_t		ofdm5ghpo;
     	uint16_t		bf_lo;		/* boardflags */
     	uint16_t		bf_hi;		/* boardflags */
    +	uint16_t		bf2_lo;
    +	uint16_t		bf2_hi;
    +
     	struct {
     		struct {
     			int8_t a0, a1, a2, a3;
    @@ -234,6 +264,11 @@ struct siba_sprom {
     	} again;	/* antenna gain */
     };
     
    +#define	SIBA_LDO_PAREF			0
    +#define	SIBA_LDO_VOLT1			1
    +#define	SIBA_LDO_VOLT2			2
    +#define	SIBA_LDO_VOLT3			3
    +
     struct siba_cc_pmu {
     	uint8_t				rev;	/* PMU rev */
     	uint32_t			freq;	/* crystal freq in kHz */
    @@ -367,5 +402,7 @@ void		siba_write_multi_2(struct siba_dev_softc *, const void *,
     void		siba_write_multi_4(struct siba_dev_softc *, const void *,
     		    size_t, uint16_t);
     void		siba_barrier(struct siba_dev_softc *, int);
    +void		siba_cc_pmu_set_ldovolt(struct siba_cc *, int, uint32_t);
    +void		siba_cc_pmu_set_ldoparef(struct siba_cc *, uint8_t);
     
     #endif /* _SIBA_SIBAVAR_H_ */
    
    From 3e1e21c9a41bfe4796c2c64a7396185f94549dc5 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:40:09 +0000
    Subject: [PATCH 2051/2592] MFC r203945:   adds bwn(4) driver for supporting
     Broadcom BCM43xx chipsets.
    
        o uses v4 firmware instead of v3.  A port will be committed to
          create the bwn firmware module.
        o supports B/G and LP(low power) PHYs.
        o supports 32 / 64 bits DMA operations.
        o tested on big / little endian machines so should work on all
          architectures.
    
      It'd not connected to the build until the firmware port is committed.
    ---
     sys/dev/bwn/if_bwn.c     | 14317 +++++++++++++++++++++++++++++++++++++
     sys/dev/bwn/if_bwnreg.h  |   998 +++
     sys/dev/bwn/if_bwnvar.h  |   957 +++
     sys/modules/bwn/Makefile |     9 +
     4 files changed, 16281 insertions(+)
     create mode 100644 sys/dev/bwn/if_bwn.c
     create mode 100644 sys/dev/bwn/if_bwnreg.h
     create mode 100644 sys/dev/bwn/if_bwnvar.h
     create mode 100644 sys/modules/bwn/Makefile
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    new file mode 100644
    index 00000000000..6120474f175
    --- /dev/null
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -0,0 +1,14317 @@
    +/*-
    + * Copyright (c) 2009-2010 Weongyo Jeong 
    + * 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.
    + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    + *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
    + *    redistribution must be conditioned upon including a substantially
    + *    similar Disclaimer requirement for further binary redistribution.
    + *
    + * NO WARRANTY
    + * 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 NONINFRINGEMENT, MERCHANTIBILITY
    + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
    + */
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +/*
    + * The Broadcom Wireless LAN controller driver.
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +
    +SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters");
    +
    +/*
    + * Tunable & sysctl variables.
    + */
    +
    +#ifdef BWN_DEBUG
    +static	int bwn_debug = 0;
    +SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
    +    "Broadcom debugging printfs");
    +TUNABLE_INT("hw.bwn.debug", &bwn_debug);
    +enum {
    +	BWN_DEBUG_XMIT		= 0x00000001,	/* basic xmit operation */
    +	BWN_DEBUG_RECV		= 0x00000002,	/* basic recv operation */
    +	BWN_DEBUG_STATE		= 0x00000004,	/* 802.11 state transitions */
    +	BWN_DEBUG_TXPOW		= 0x00000008,	/* tx power processing */
    +	BWN_DEBUG_RESET		= 0x00000010,	/* reset processing */
    +	BWN_DEBUG_OPS		= 0x00000020,	/* bwn_ops processing */
    +	BWN_DEBUG_BEACON	= 0x00000040,	/* beacon handling */
    +	BWN_DEBUG_WATCHDOG	= 0x00000080,	/* watchdog timeout */
    +	BWN_DEBUG_INTR		= 0x00000100,	/* ISR */
    +	BWN_DEBUG_CALIBRATE	= 0x00000200,	/* periodic calibration */
    +	BWN_DEBUG_NODE		= 0x00000400,	/* node management */
    +	BWN_DEBUG_LED		= 0x00000800,	/* led management */
    +	BWN_DEBUG_CMD		= 0x00001000,	/* cmd submission */
    +	BWN_DEBUG_LO		= 0x00002000,	/* LO */
    +	BWN_DEBUG_FW		= 0x00004000,	/* firmware */
    +	BWN_DEBUG_WME		= 0x00008000,	/* WME */
    +	BWN_DEBUG_RF		= 0x00010000,	/* RF */
    +	BWN_DEBUG_FATAL		= 0x80000000,	/* fatal errors */
    +	BWN_DEBUG_ANY		= 0xffffffff
    +};
    +#define	DPRINTF(sc, m, fmt, ...) do {			\
    +	if (sc->sc_debug & (m))				\
    +		printf(fmt, __VA_ARGS__);		\
    +} while (0)
    +#else
    +#define	DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
    +#endif
    +
    +static int	bwn_bfp = 0;		/* use "Bad Frames Preemption" */
    +SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
    +    "uses Bad Frames Preemption");
    +static int	bwn_bluetooth = 1;
    +SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
    +    "turns on Bluetooth Coexistence");
    +static int	bwn_hwpctl = 0;
    +SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
    +    "uses H/W power control");
    +static int	bwn_msi_disable = 0;		/* MSI disabled  */
    +TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
    +static int	bwn_usedma = 1;
    +SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
    +    "uses DMA");
    +TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
    +static int	bwn_wme = 1;
    +SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
    +    "uses WME support");
    +
    +static int	bwn_attach_pre(struct bwn_softc *);
    +static int	bwn_attach_post(struct bwn_softc *);
    +static void	bwn_sprom_bugfixes(struct siba_softc *);
    +static void	bwn_init(void *);
    +static int	bwn_init_locked(struct bwn_softc *);
    +static int	bwn_ioctl(struct ifnet *, u_long, caddr_t);
    +static void	bwn_start(struct ifnet *);
    +static int	bwn_attach_core(struct bwn_mac *);
    +static void	bwn_reset_core(struct bwn_mac *, uint32_t);
    +static int	bwn_phy_getinfo(struct bwn_mac *, int);
    +static int	bwn_chiptest(struct bwn_mac *);
    +static int	bwn_setup_channels(struct bwn_mac *, int, int);
    +static int	bwn_phy_g_attach(struct bwn_mac *);
    +static void	bwn_phy_g_detach(struct bwn_mac *);
    +static void	bwn_phy_g_init_pre(struct bwn_mac *);
    +static int	bwn_phy_g_prepare_hw(struct bwn_mac *);
    +static int	bwn_phy_g_init(struct bwn_mac *);
    +static void	bwn_phy_g_exit(struct bwn_mac *);
    +static uint16_t	bwn_phy_g_read(struct bwn_mac *, uint16_t);
    +static void	bwn_phy_g_write(struct bwn_mac *, uint16_t,
    +		    uint16_t);
    +static uint16_t	bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
    +static void	bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
    +		    uint16_t);
    +static int	bwn_phy_g_hwpctl(struct bwn_mac *);
    +static void	bwn_phy_g_rf_onoff(struct bwn_mac *, int);
    +static int	bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
    +static uint32_t	bwn_phy_g_get_default_chan(struct bwn_mac *);
    +static void	bwn_phy_g_set_antenna(struct bwn_mac *, int);
    +static int	bwn_phy_g_im(struct bwn_mac *, int);
    +static int	bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
    +static void	bwn_phy_g_set_txpwr(struct bwn_mac *);
    +static void	bwn_phy_g_task_15s(struct bwn_mac *);
    +static void	bwn_phy_g_task_60s(struct bwn_mac *);
    +static uint16_t	bwn_phy_g_txctl(struct bwn_mac *);
    +static void	bwn_phy_switch_analog(struct bwn_mac *, int);
    +static uint16_t	bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
    +static void	bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
    +		    uint16_t);
    +static uint32_t	bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
    +static void	bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
    +		    uint32_t);
    +static void	bwn_shm_ctlword(struct bwn_mac *, uint16_t,
    +		    uint16_t);
    +static void	bwn_addchannels(struct ieee80211_channel [], int, int *,
    +		    const struct bwn_channelinfo *, int);
    +static int	bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
    +		    const struct ieee80211_bpf_params *);
    +static void	bwn_newassoc(struct ieee80211_node *, int);
    +static void	bwn_updateslot(struct ifnet *);
    +static void	bwn_update_promisc(struct ifnet *);
    +static void	bwn_wme_init(struct bwn_mac *);
    +static int	bwn_wme_update(struct ieee80211com *);
    +static struct ieee80211_node *bwn_node_alloc(struct ieee80211vap *,
    +		    const uint8_t [IEEE80211_ADDR_LEN]);
    +static void	bwn_wme_clear(struct bwn_softc *);
    +static void	bwn_wme_load(struct bwn_mac *);
    +static void	bwn_wme_loadparams(struct bwn_mac *,
    +		    const struct wmeParams *, uint16_t);
    +static void	bwn_node_cleanup(struct ieee80211_node *);
    +static void	bwn_scan_start(struct ieee80211com *);
    +static void	bwn_scan_end(struct ieee80211com *);
    +static void	bwn_set_channel(struct ieee80211com *);
    +static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
    +		    const char [IFNAMSIZ], int, int,
    +		    int, const uint8_t [IEEE80211_ADDR_LEN],
    +		    const uint8_t [IEEE80211_ADDR_LEN]);
    +static void	bwn_vap_delete(struct ieee80211vap *);
    +static void	bwn_stop(struct bwn_softc *, int);
    +static void	bwn_stop_locked(struct bwn_softc *, int);
    +static int	bwn_core_init(struct bwn_mac *);
    +static void	bwn_core_start(struct bwn_mac *);
    +static void	bwn_core_exit(struct bwn_mac *);
    +static void	bwn_fix_imcfglobug(struct bwn_mac *);
    +static void	bwn_bt_disable(struct bwn_mac *);
    +static int	bwn_chip_init(struct bwn_mac *);
    +static uint64_t	bwn_hf_read(struct bwn_mac *);
    +static void	bwn_hf_write(struct bwn_mac *, uint64_t);
    +static void	bwn_set_txretry(struct bwn_mac *, int, int);
    +static void	bwn_rate_init(struct bwn_mac *);
    +static void	bwn_set_phytxctl(struct bwn_mac *);
    +static void	bwn_spu_setdelay(struct bwn_mac *, int);
    +static void	bwn_bt_enable(struct bwn_mac *);
    +static void	bwn_set_macaddr(struct bwn_mac *);
    +static void	bwn_crypt_init(struct bwn_mac *);
    +static void	bwn_chip_exit(struct bwn_mac *);
    +static int	bwn_fw_fillinfo(struct bwn_mac *);
    +static int	bwn_fw_loaducode(struct bwn_mac *);
    +static int	bwn_gpio_init(struct bwn_mac *);
    +static int	bwn_fw_loadinitvals(struct bwn_mac *);
    +static int	bwn_phy_init(struct bwn_mac *);
    +static void	bwn_set_txantenna(struct bwn_mac *, int);
    +static void	bwn_set_opmode(struct bwn_mac *);
    +static void	bwn_gpio_cleanup(struct bwn_mac *);
    +static void	bwn_rate_write(struct bwn_mac *, uint16_t, int);
    +static uint8_t	bwn_plcp_getcck(const uint8_t);
    +static uint8_t	bwn_plcp_getofdm(const uint8_t);
    +static void	bwn_pio_init(struct bwn_mac *);
    +static uint16_t	bwn_pio_idx2base(struct bwn_mac *, int);
    +static void	bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
    +		    int);
    +static void	bwn_pio_setupqueue_rx(struct bwn_mac *,
    +		    struct bwn_pio_rxqueue *, int);
    +static void	bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
    +static uint16_t	bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
    +		    uint16_t);
    +static void	bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
    +static int	bwn_pio_rx(struct bwn_pio_rxqueue *);
    +static uint8_t	bwn_pio_rxeof(struct bwn_pio_rxqueue *);
    +static void	bwn_pio_handle_txeof(struct bwn_mac *,
    +		    const struct bwn_txstatus *);
    +static uint16_t	bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
    +static uint32_t	bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
    +static void	bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
    +		    uint16_t);
    +static void	bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
    +		    uint32_t);
    +static int	bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
    +		    struct mbuf *);
    +static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
    +static uint32_t	bwn_pio_write_multi_4(struct bwn_mac *,
    +		    struct bwn_pio_txqueue *, uint32_t, const void *, int);
    +static void	bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
    +		    uint16_t, uint32_t);
    +static uint16_t	bwn_pio_write_multi_2(struct bwn_mac *,
    +		    struct bwn_pio_txqueue *, uint16_t, const void *, int);
    +static uint16_t	bwn_pio_write_mbuf_2(struct bwn_mac *,
    +		    struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
    +static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
    +		    uint16_t, struct bwn_pio_txpkt **);
    +static void	bwn_dma_init(struct bwn_mac *);
    +static void	bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
    +static int	bwn_dma_mask2type(uint64_t);
    +static uint64_t	bwn_dma_mask(struct bwn_mac *);
    +static uint16_t	bwn_dma_base(int, int);
    +static void	bwn_dma_ringfree(struct bwn_dma_ring **);
    +static void	bwn_dma_32_getdesc(struct bwn_dma_ring *,
    +		    int, struct bwn_dmadesc_generic **,
    +		    struct bwn_dmadesc_meta **);
    +static void	bwn_dma_32_setdesc(struct bwn_dma_ring *,
    +		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
    +		    int, int);
    +static void	bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
    +static void	bwn_dma_32_suspend(struct bwn_dma_ring *);
    +static void	bwn_dma_32_resume(struct bwn_dma_ring *);
    +static int	bwn_dma_32_get_curslot(struct bwn_dma_ring *);
    +static void	bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
    +static void	bwn_dma_64_getdesc(struct bwn_dma_ring *,
    +		    int, struct bwn_dmadesc_generic **,
    +		    struct bwn_dmadesc_meta **);
    +static void	bwn_dma_64_setdesc(struct bwn_dma_ring *,
    +		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
    +		    int, int);
    +static void	bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
    +static void	bwn_dma_64_suspend(struct bwn_dma_ring *);
    +static void	bwn_dma_64_resume(struct bwn_dma_ring *);
    +static int	bwn_dma_64_get_curslot(struct bwn_dma_ring *);
    +static void	bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
    +static int	bwn_dma_allocringmemory(struct bwn_dma_ring *);
    +static void	bwn_dma_setup(struct bwn_dma_ring *);
    +static void	bwn_dma_free_ringmemory(struct bwn_dma_ring *);
    +static void	bwn_dma_cleanup(struct bwn_dma_ring *);
    +static void	bwn_dma_free_descbufs(struct bwn_dma_ring *);
    +static int	bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
    +static void	bwn_dma_rx(struct bwn_dma_ring *);
    +static int	bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
    +static void	bwn_dma_free_descbuf(struct bwn_dma_ring *,
    +		    struct bwn_dmadesc_meta *);
    +static void	bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
    +static int	bwn_dma_gettype(struct bwn_mac *);
    +static void	bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
    +static int	bwn_dma_freeslot(struct bwn_dma_ring *);
    +static int	bwn_dma_nextslot(struct bwn_dma_ring *, int);
    +static void	bwn_dma_rxeof(struct bwn_dma_ring *, int *);
    +static int	bwn_dma_newbuf(struct bwn_dma_ring *,
    +		    struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
    +		    int);
    +static void	bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
    +		    bus_size_t, int);
    +static uint8_t	bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
    +static void	bwn_dma_handle_txeof(struct bwn_mac *,
    +		    const struct bwn_txstatus *);
    +static int	bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
    +		    struct mbuf *);
    +static int	bwn_dma_getslot(struct bwn_dma_ring *);
    +static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
    +		    uint8_t);
    +static int	bwn_dma_attach(struct bwn_mac *);
    +static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
    +		    int, int, int);
    +static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
    +		    const struct bwn_txstatus *, uint16_t, int *);
    +static void	bwn_dma_free(struct bwn_mac *);
    +static void	bwn_phy_g_init_sub(struct bwn_mac *);
    +static uint8_t	bwn_has_hwpctl(struct bwn_mac *);
    +static void	bwn_phy_init_b5(struct bwn_mac *);
    +static void	bwn_phy_init_b6(struct bwn_mac *);
    +static void	bwn_phy_init_a(struct bwn_mac *);
    +static void	bwn_loopback_calcgain(struct bwn_mac *);
    +static uint16_t	bwn_rf_init_bcm2050(struct bwn_mac *);
    +static void	bwn_lo_g_init(struct bwn_mac *);
    +static void	bwn_lo_g_adjust(struct bwn_mac *);
    +static void	bwn_lo_get_powervector(struct bwn_mac *);
    +static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
    +		    const struct bwn_bbatt *, const struct bwn_rfatt *);
    +static void	bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
    +static void	bwn_phy_hwpctl_init(struct bwn_mac *);
    +static void	bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
    +static void	bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
    +		    const struct bwn_bbatt *, const struct bwn_rfatt *,
    +		    uint8_t);
    +static void	bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
    +static uint16_t	bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
    +static void	bwn_spu_workaround(struct bwn_mac *, uint8_t);
    +static void	bwn_wa_init(struct bwn_mac *);
    +static void	bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
    +		    uint16_t);
    +static void	bwn_dummy_transmission(struct bwn_mac *, int, int);
    +static void	bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
    +		    uint32_t);
    +static void	bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
    +		    uint16_t);
    +static void	bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
    +static void	bwn_mac_suspend(struct bwn_mac *);
    +static void	bwn_mac_enable(struct bwn_mac *);
    +static void	bwn_psctl(struct bwn_mac *, uint32_t);
    +static int16_t	bwn_nrssi_read(struct bwn_mac *, uint16_t);
    +static void	bwn_nrssi_offset(struct bwn_mac *);
    +static void	bwn_nrssi_threshold(struct bwn_mac *);
    +static void	bwn_nrssi_slope_11g(struct bwn_mac *);
    +static void	bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
    +		    int16_t);
    +static void	bwn_set_original_gains(struct bwn_mac *);
    +static void	bwn_hwpctl_early_init(struct bwn_mac *);
    +static void	bwn_hwpctl_init_gphy(struct bwn_mac *);
    +static uint16_t	bwn_phy_g_chan2freq(uint8_t);
    +static int	bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
    +static int	bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
    +		    const char *, struct bwn_fwfile *);
    +static void	bwn_release_firmware(struct bwn_mac *);
    +static void	bwn_do_release_fw(struct bwn_fwfile *);
    +static uint16_t	bwn_fwcaps_read(struct bwn_mac *);
    +static int	bwn_fwinitvals_write(struct bwn_mac *,
    +		    const struct bwn_fwinitvals *, size_t, size_t);
    +static int	bwn_switch_channel(struct bwn_mac *, int);
    +static uint16_t	bwn_ant2phy(int);
    +static void	bwn_mac_write_bssid(struct bwn_mac *);
    +static void	bwn_mac_setfilter(struct bwn_mac *, uint16_t,
    +		    const uint8_t *);
    +static void	bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
    +		    const uint8_t *, size_t, const uint8_t *);
    +static void	bwn_key_macwrite(struct bwn_mac *, uint8_t,
    +		    const uint8_t *);
    +static void	bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
    +		    const uint8_t *);
    +static void	bwn_phy_exit(struct bwn_mac *);
    +static void	bwn_core_stop(struct bwn_mac *);
    +static int	bwn_switch_band(struct bwn_softc *,
    +		    struct ieee80211_channel *);
    +static void	bwn_phy_reset(struct bwn_mac *);
    +static int	bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
    +static void	bwn_set_pretbtt(struct bwn_mac *);
    +static int	bwn_intr(void *);
    +static void	bwn_intrtask(void *, int);
    +static void	bwn_restart(struct bwn_mac *, const char *);
    +static void	bwn_intr_ucode_debug(struct bwn_mac *);
    +static void	bwn_intr_tbtt_indication(struct bwn_mac *);
    +static void	bwn_intr_atim_end(struct bwn_mac *);
    +static void	bwn_intr_beacon(struct bwn_mac *);
    +static void	bwn_intr_pmq(struct bwn_mac *);
    +static void	bwn_intr_noise(struct bwn_mac *);
    +static void	bwn_intr_txeof(struct bwn_mac *);
    +static void	bwn_hwreset(void *, int);
    +static void	bwn_handle_fwpanic(struct bwn_mac *);
    +static void	bwn_load_beacon0(struct bwn_mac *);
    +static void	bwn_load_beacon1(struct bwn_mac *);
    +static uint32_t	bwn_jssi_read(struct bwn_mac *);
    +static void	bwn_noise_gensample(struct bwn_mac *);
    +static void	bwn_handle_txeof(struct bwn_mac *,
    +		    const struct bwn_txstatus *);
    +static void	bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
    +static void	bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
    +static void	bwn_start_locked(struct ifnet *);
    +static int	bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
    +		    struct mbuf *);
    +static int	bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
    +static int	bwn_set_txhdr(struct bwn_mac *,
    +		    struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
    +		    uint16_t);
    +static void	bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
    +		    const uint8_t);
    +static uint8_t	bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
    +static uint8_t	bwn_get_fbrate(uint8_t);
    +static int	bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
    +static void	bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
    +static void	bwn_phy_lock(struct bwn_mac *);
    +static void	bwn_phy_unlock(struct bwn_mac *);
    +static void	bwn_rf_lock(struct bwn_mac *);
    +static void	bwn_rf_unlock(struct bwn_mac *);
    +static void	bwn_txpwr(void *, int);
    +static void	bwn_tasks(void *);
    +static void	bwn_task_15s(struct bwn_mac *);
    +static void	bwn_task_30s(struct bwn_mac *);
    +static void	bwn_task_60s(struct bwn_mac *);
    +static int	bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
    +		    uint8_t);
    +static int	bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
    +static void	bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
    +		    const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
    +		    int, int);
    +static void	bwn_tsf_read(struct bwn_mac *, uint64_t *);
    +static void	bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
    +static void	bwn_set_slot_time(struct bwn_mac *, uint16_t);
    +static void	bwn_watchdog(void *);
    +static void	bwn_dma_stop(struct bwn_mac *);
    +static void	bwn_pio_stop(struct bwn_mac *);
    +static void	bwn_dma_ringstop(struct bwn_dma_ring **);
    +static void	bwn_led_attach(struct bwn_mac *);
    +static void	bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
    +static void	bwn_led_event(struct bwn_mac *, int);
    +static void	bwn_led_blink_start(struct bwn_mac *, int, int);
    +static void	bwn_led_blink_next(void *);
    +static void	bwn_led_blink_end(void *);
    +static void	bwn_rfswitch(void *);
    +static void	bwn_rf_turnon(struct bwn_mac *);
    +static void	bwn_rf_turnoff(struct bwn_mac *);
    +static void	bwn_phy_lp_init_pre(struct bwn_mac *);
    +static int	bwn_phy_lp_init(struct bwn_mac *);
    +static uint16_t	bwn_phy_lp_read(struct bwn_mac *, uint16_t);
    +static void	bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
    +static void	bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
    +		    uint16_t);
    +static uint16_t	bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
    +static void	bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
    +static void	bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
    +static int	bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
    +static uint32_t	bwn_phy_lp_get_default_chan(struct bwn_mac *);
    +static void	bwn_phy_lp_set_antenna(struct bwn_mac *, int);
    +static void	bwn_phy_lp_task_60s(struct bwn_mac *);
    +static void	bwn_phy_lp_readsprom(struct bwn_mac *);
    +static void	bwn_phy_lp_bbinit(struct bwn_mac *);
    +static void	bwn_phy_lp_txpctl_init(struct bwn_mac *);
    +static void	bwn_phy_lp_calib(struct bwn_mac *);
    +static void	bwn_phy_lp_switch_analog(struct bwn_mac *, int);
    +static int	bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
    +static int	bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
    +static void	bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
    +static void	bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
    +static void	bwn_phy_lp_digflt_save(struct bwn_mac *);
    +static void	bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
    +static void	bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
    +static void	bwn_phy_lp_bugfix(struct bwn_mac *);
    +static void	bwn_phy_lp_digflt_restore(struct bwn_mac *);
    +static void	bwn_phy_lp_tblinit(struct bwn_mac *);
    +static void	bwn_phy_lp_bbinit_r2(struct bwn_mac *);
    +static void	bwn_phy_lp_bbinit_r01(struct bwn_mac *);
    +static void	bwn_phy_lp_b2062_init(struct bwn_mac *);
    +static void	bwn_phy_lp_b2063_init(struct bwn_mac *);
    +static void	bwn_phy_lp_rxcal_r2(struct bwn_mac *);
    +static void	bwn_phy_lp_rccal_r12(struct bwn_mac *);
    +static void	bwn_phy_lp_set_rccap(struct bwn_mac *);
    +static uint32_t	bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
    +static void	bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
    +static void	bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
    +static void	bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
    +		    const void *);
    +static void	bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
    +static struct bwn_txgain
    +		bwn_phy_lp_get_txgain(struct bwn_mac *);
    +static uint8_t	bwn_phy_lp_get_bbmult(struct bwn_mac *);
    +static void	bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
    +static void	bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
    +static void	bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
    +static void	bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
    +static void	bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
    +static int	bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
    +static void	bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
    +static void	bwn_phy_lp_tblinit_r01(struct bwn_mac *);
    +static void	bwn_phy_lp_tblinit_r2(struct bwn_mac *);
    +static void	bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
    +static void	bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
    +static void	bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
    +static void	bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
    +static int	bwn_phy_lp_loopback(struct bwn_mac *);
    +static void	bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
    +static void	bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
    +		    int);
    +static uint8_t	bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
    +		    struct bwn_phy_lp_iq_est *);
    +static void	bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
    +static uint32_t	bwn_tab_read(struct bwn_mac *, uint32_t);
    +static void	bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
    +static void	bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
    +static void	bwn_phy_lp_set_txgain_override(struct bwn_mac *);
    +static uint16_t	bwn_phy_lp_get_pa_gain(struct bwn_mac *);
    +static uint8_t	bwn_nbits(int32_t);
    +static void	bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
    +		    struct bwn_txgain_entry *);
    +static void	bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
    +		    struct bwn_txgain_entry);
    +static void	bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
    +		    struct bwn_txgain_entry);
    +static void	bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
    +		    struct bwn_txgain_entry);
    +
    +static struct resource_spec bwn_res_spec_legacy[] = {
    +	{ SYS_RES_IRQ,		0,		RF_ACTIVE | RF_SHAREABLE },
    +	{ -1,			0,		0 }
    +};
    +
    +static struct resource_spec bwn_res_spec_msi[] = {
    +	{ SYS_RES_IRQ,		1,		RF_ACTIVE },
    +	{ -1,			0,		0 }
    +};
    +
    +static const struct bwn_channelinfo bwn_chantable_bg = {
    +	.channels = {
    +		{ 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
    +		{ 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
    +		{ 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
    +		{ 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
    +		{ 2472, 13, 30 }, { 2484, 14, 30 } },
    +	.nchannels = 14
    +};
    +
    +static const struct bwn_channelinfo bwn_chantable_a = {
    +	.channels = {
    +		{ 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
    +		{ 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
    +		{ 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
    +		{ 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
    +		{ 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
    +		{ 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
    +		{ 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
    +		{ 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
    +		{ 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
    +		{ 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
    +		{ 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
    +		{ 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
    +		{ 6080, 216, 30 } },
    +	.nchannels = 37
    +};
    +
    +static const struct bwn_channelinfo bwn_chantable_n = {
    +	.channels = {
    +		{ 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
    +		{ 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
    +		{ 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
    +		{ 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
    +		{ 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
    +		{ 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
    +		{ 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
    +		{ 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
    +		{ 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
    +		{ 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
    +		{ 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
    +		{ 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
    +		{ 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
    +		{ 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
    +		{ 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
    +		{ 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
    +		{ 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
    +		{ 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
    +		{ 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
    +		{ 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
    +		{ 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
    +		{ 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
    +		{ 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
    +		{ 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
    +		{ 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
    +		{ 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
    +		{ 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
    +		{ 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
    +		{ 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
    +		{ 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
    +		{ 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
    +		{ 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
    +		{ 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
    +		{ 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
    +		{ 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
    +		{ 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
    +		{ 6130, 226, 30 }, { 6140, 228, 30 } },
    +	.nchannels = 110
    +};
    +
    +static const uint8_t bwn_b2063_chantable_data[33][12] = {
    +	{ 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
    +	{ 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
    +	{ 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
    +	{ 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
    +	{ 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
    +	{ 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
    +	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
    +	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
    +	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
    +	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
    +	{ 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
    +	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
    +	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
    +	{ 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
    +	{ 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
    +	{ 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
    +	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
    +	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
    +	{ 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
    +	{ 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
    +	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
    +	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
    +	{ 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
    +	{ 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
    +	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
    +	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
    +	{ 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
    +	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
    +	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
    +	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
    +	{ 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
    +	{ 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
    +	{ 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
    +};
    +
    +static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
    +	{ 1, 2412, bwn_b2063_chantable_data[0] },
    +	{ 2, 2417, bwn_b2063_chantable_data[0] },
    +	{ 3, 2422, bwn_b2063_chantable_data[0] },
    +	{ 4, 2427, bwn_b2063_chantable_data[1] },
    +	{ 5, 2432, bwn_b2063_chantable_data[1] },
    +	{ 6, 2437, bwn_b2063_chantable_data[1] },
    +	{ 7, 2442, bwn_b2063_chantable_data[1] },
    +	{ 8, 2447, bwn_b2063_chantable_data[1] },
    +	{ 9, 2452, bwn_b2063_chantable_data[2] },
    +	{ 10, 2457, bwn_b2063_chantable_data[2] },
    +	{ 11, 2462, bwn_b2063_chantable_data[3] },
    +	{ 12, 2467, bwn_b2063_chantable_data[3] },
    +	{ 13, 2472, bwn_b2063_chantable_data[3] },
    +	{ 14, 2484, bwn_b2063_chantable_data[4] },
    +	{ 34, 5170, bwn_b2063_chantable_data[5] },
    +	{ 36, 5180, bwn_b2063_chantable_data[6] },
    +	{ 38, 5190, bwn_b2063_chantable_data[7] },
    +	{ 40, 5200, bwn_b2063_chantable_data[8] },
    +	{ 42, 5210, bwn_b2063_chantable_data[9] },
    +	{ 44, 5220, bwn_b2063_chantable_data[10] },
    +	{ 46, 5230, bwn_b2063_chantable_data[11] },
    +	{ 48, 5240, bwn_b2063_chantable_data[12] },
    +	{ 52, 5260, bwn_b2063_chantable_data[13] },
    +	{ 56, 5280, bwn_b2063_chantable_data[14] },
    +	{ 60, 5300, bwn_b2063_chantable_data[14] },
    +	{ 64, 5320, bwn_b2063_chantable_data[15] },
    +	{ 100, 5500, bwn_b2063_chantable_data[16] },
    +	{ 104, 5520, bwn_b2063_chantable_data[17] },
    +	{ 108, 5540, bwn_b2063_chantable_data[18] },
    +	{ 112, 5560, bwn_b2063_chantable_data[19] },
    +	{ 116, 5580, bwn_b2063_chantable_data[20] },
    +	{ 120, 5600, bwn_b2063_chantable_data[21] },
    +	{ 124, 5620, bwn_b2063_chantable_data[21] },
    +	{ 128, 5640, bwn_b2063_chantable_data[22] },
    +	{ 132, 5660, bwn_b2063_chantable_data[22] },
    +	{ 136, 5680, bwn_b2063_chantable_data[22] },
    +	{ 140, 5700, bwn_b2063_chantable_data[23] },
    +	{ 149, 5745, bwn_b2063_chantable_data[23] },
    +	{ 153, 5765, bwn_b2063_chantable_data[23] },
    +	{ 157, 5785, bwn_b2063_chantable_data[23] },
    +	{ 161, 5805, bwn_b2063_chantable_data[23] },
    +	{ 165, 5825, bwn_b2063_chantable_data[23] },
    +	{ 184, 4920, bwn_b2063_chantable_data[24] },
    +	{ 188, 4940, bwn_b2063_chantable_data[25] },
    +	{ 192, 4960, bwn_b2063_chantable_data[26] },
    +	{ 196, 4980, bwn_b2063_chantable_data[27] },
    +	{ 200, 5000, bwn_b2063_chantable_data[28] },
    +	{ 204, 5020, bwn_b2063_chantable_data[29] },
    +	{ 208, 5040, bwn_b2063_chantable_data[30] },
    +	{ 212, 5060, bwn_b2063_chantable_data[31] },
    +	{ 216, 5080, bwn_b2063_chantable_data[32] }
    +};
    +
    +static const uint8_t bwn_b2062_chantable_data[22][12] = {
    +	{ 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
    +	{ 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
    +	{ 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
    +	{ 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
    +	{ 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
    +	{ 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
    +	{ 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
    +	{ 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
    +	{ 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
    +	{ 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
    +	{ 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
    +};
    +
    +static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
    +	{ 1, 2412, bwn_b2062_chantable_data[0] },
    +	{ 2, 2417, bwn_b2062_chantable_data[0] },
    +	{ 3, 2422, bwn_b2062_chantable_data[0] },
    +	{ 4, 2427, bwn_b2062_chantable_data[0] },
    +	{ 5, 2432, bwn_b2062_chantable_data[0] },
    +	{ 6, 2437, bwn_b2062_chantable_data[0] },
    +	{ 7, 2442, bwn_b2062_chantable_data[0] },
    +	{ 8, 2447, bwn_b2062_chantable_data[0] },
    +	{ 9, 2452, bwn_b2062_chantable_data[0] },
    +	{ 10, 2457, bwn_b2062_chantable_data[0] },
    +	{ 11, 2462, bwn_b2062_chantable_data[0] },
    +	{ 12, 2467, bwn_b2062_chantable_data[0] },
    +	{ 13, 2472, bwn_b2062_chantable_data[0] },
    +	{ 14, 2484, bwn_b2062_chantable_data[0] },
    +	{ 34, 5170, bwn_b2062_chantable_data[1] },
    +	{ 38, 5190, bwn_b2062_chantable_data[2] },
    +	{ 42, 5210, bwn_b2062_chantable_data[2] },
    +	{ 46, 5230, bwn_b2062_chantable_data[3] },
    +	{ 36, 5180, bwn_b2062_chantable_data[4] },
    +	{ 40, 5200, bwn_b2062_chantable_data[5] },
    +	{ 44, 5220, bwn_b2062_chantable_data[6] },
    +	{ 48, 5240, bwn_b2062_chantable_data[3] },
    +	{ 52, 5260, bwn_b2062_chantable_data[3] },
    +	{ 56, 5280, bwn_b2062_chantable_data[3] },
    +	{ 60, 5300, bwn_b2062_chantable_data[7] },
    +	{ 64, 5320, bwn_b2062_chantable_data[8] },
    +	{ 100, 5500, bwn_b2062_chantable_data[9] },
    +	{ 104, 5520, bwn_b2062_chantable_data[10] },
    +	{ 108, 5540, bwn_b2062_chantable_data[10] },
    +	{ 112, 5560, bwn_b2062_chantable_data[10] },
    +	{ 116, 5580, bwn_b2062_chantable_data[11] },
    +	{ 120, 5600, bwn_b2062_chantable_data[12] },
    +	{ 124, 5620, bwn_b2062_chantable_data[12] },
    +	{ 128, 5640, bwn_b2062_chantable_data[12] },
    +	{ 132, 5660, bwn_b2062_chantable_data[12] },
    +	{ 136, 5680, bwn_b2062_chantable_data[12] },
    +	{ 140, 5700, bwn_b2062_chantable_data[12] },
    +	{ 149, 5745, bwn_b2062_chantable_data[12] },
    +	{ 153, 5765, bwn_b2062_chantable_data[12] },
    +	{ 157, 5785, bwn_b2062_chantable_data[12] },
    +	{ 161, 5805, bwn_b2062_chantable_data[12] },
    +	{ 165, 5825, bwn_b2062_chantable_data[12] },
    +	{ 184, 4920, bwn_b2062_chantable_data[13] },
    +	{ 188, 4940, bwn_b2062_chantable_data[14] },
    +	{ 192, 4960, bwn_b2062_chantable_data[15] },
    +	{ 196, 4980, bwn_b2062_chantable_data[16] },
    +	{ 200, 5000, bwn_b2062_chantable_data[17] },
    +	{ 204, 5020, bwn_b2062_chantable_data[18] },
    +	{ 208, 5040, bwn_b2062_chantable_data[19] },
    +	{ 212, 5060, bwn_b2062_chantable_data[20] },
    +	{ 216, 5080, bwn_b2062_chantable_data[21] }
    +};
    +
    +/* for LP PHY */
    +static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
    +	{  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
    +	{  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
    +	{  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
    +	{ 13, -66, 13 }, { 14, -66, 13 },
    +};
    +
    +/* for LP PHY */
    +static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
    +	{   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
    +	{   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
    +	{   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
    +	{  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
    +	{  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
    +	{  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
    +	{  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
    +	{ 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
    +	{ 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
    +	{ 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
    +	{ 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
    +	{ 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
    +	{ 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
    +};
    +
    +static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
    +
    +static const uint8_t bwn_tab_sigsq_tbl[] = {
    +	0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
    +	0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
    +	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
    +	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
    +	0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
    +	0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
    +};
    +
    +static const uint8_t bwn_tab_pllfrac_tbl[] = {
    +	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
    +	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    +};
    +
    +static const uint16_t bwn_tabl_iqlocal_tbl[] = {
    +	0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
    +	0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
    +	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
    +	0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
    +	0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
    +	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
    +	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +};
    +
    +static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
    +static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
    +static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
    +static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
    +static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
    +const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
    +
    +#define	VENDOR_LED_ACT(vendor)				\
    +{							\
    +	.vid = PCI_VENDOR_##vendor,			\
    +	.led_act = { BWN_VENDOR_LED_ACT_##vendor }	\
    +}
    +
    +static const struct {
    +	uint16_t	vid;
    +	uint8_t		led_act[BWN_LED_MAX];
    +} bwn_vendor_led_act[] = {
    +	VENDOR_LED_ACT(COMPAQ),
    +	VENDOR_LED_ACT(ASUSTEK)
    +};
    +
    +static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
    +	{ BWN_VENDOR_LED_ACT_DEFAULT };
    +
    +#undef VENDOR_LED_ACT
    +
    +static const struct {
    +	int		on_dur;
    +	int		off_dur;
    +} bwn_led_duration[109] = {
    +	[0]	= { 400, 100 },
    +	[2]	= { 150, 75 },
    +	[4]	= { 90, 45 },
    +	[11]	= { 66, 34 },
    +	[12]	= { 53, 26 },
    +	[18]	= { 42, 21 },
    +	[22]	= { 35, 17 },
    +	[24]	= { 32, 16 },
    +	[36]	= { 21, 10 },
    +	[48]	= { 16, 8 },
    +	[72]	= { 11, 5 },
    +	[96]	= { 9, 4 },
    +	[108]	= { 7, 3 }
    +};
    +
    +static const uint16_t bwn_wme_shm_offsets[] = {
    +	[0] = BWN_WME_BESTEFFORT,
    +	[1] = BWN_WME_BACKGROUND,
    +	[2] = BWN_WME_VOICE,
    +	[3] = BWN_WME_VIDEO,
    +};
    +
    +static const struct siba_devid bwn_devs[] = {
    +	SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
    +	SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
    +	SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
    +	SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
    +	SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
    +	SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
    +	SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
    +	SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
    +	SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
    +};
    +
    +static int
    +bwn_probe(device_t dev)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	int i;
    +
    +	for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
    +		if (sd->sd_id.sd_vendor == bwn_devs[i].sd_vendor &&
    +		    sd->sd_id.sd_device == bwn_devs[i].sd_device &&
    +		    sd->sd_id.sd_rev == bwn_devs[i].sd_rev)
    +			return (BUS_PROBE_DEFAULT);
    +	}
    +
    +	return (ENXIO);
    +}
    +
    +static int
    +bwn_attach(device_t dev)
    +{
    +	struct bwn_mac *mac;
    +	struct bwn_softc *sc = device_get_softc(dev);
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
    +	int error, i, msic, reg;
    +
    +	sc->sc_dev = dev;
    +	sc->sc_sd = sd;
    +#ifdef BWN_DEBUG
    +	sc->sc_debug = bwn_debug;
    +#endif
    +
    +	if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
    +		error = bwn_attach_pre(sc);
    +		if (error != 0)
    +			return (error);
    +		bwn_sprom_bugfixes(sd->sd_bus);
    +		sc->sc_flags |= BWN_FLAG_ATTACHED;
    +	}
    +
    +	if (!TAILQ_EMPTY(&sc->sc_maclist)) {
    +		if (siba->siba_pci_did != 0x4313 &&
    +		    siba->siba_pci_did != 0x431a &&
    +		    siba->siba_pci_did != 0x4321) {
    +			device_printf(sc->sc_dev,
    +			    "skip 802.11 cores\n");
    +			return (ENODEV);
    +		}
    +	}
    +
    +	mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
    +	    M_NOWAIT | M_ZERO);
    +	if (mac == NULL)
    +		return (ENOMEM);
    +	mac->mac_sc = sc;
    +	mac->mac_sd = sd;
    +	mac->mac_status = BWN_MAC_STATUS_UNINIT;
    +	if (bwn_bfp != 0)
    +		mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
    +
    +	TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
    +	TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
    +	TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
    +
    +	error = bwn_attach_core(mac);
    +	if (error)
    +		goto fail0;
    +	bwn_led_attach(mac);
    +
    +	device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
    +	    "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
    +	    sd->sd_bus->siba_chipid, sd->sd_id.sd_rev,
    +	    mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
    +	    mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
    +	    mac->mac_phy.rf_rev);
    +	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
    +		device_printf(sc->sc_dev, "DMA (%d bits)\n",
    +		    mac->mac_method.dma.dmatype);
    +	else
    +		device_printf(sc->sc_dev, "PIO\n");
    +
    +	/*
    +	 * setup PCI resources and interrupt.
    +	 */
    +	if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
    +		msic = pci_msi_count(dev);
    +		if (bootverbose)
    +			device_printf(sc->sc_dev, "MSI count : %d\n", msic);
    +	} else
    +		msic = 0;
    +
    +	mac->mac_intr_spec = bwn_res_spec_legacy;
    +	if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
    +		if (pci_alloc_msi(dev, &msic) == 0) {
    +			device_printf(sc->sc_dev,
    +			    "Using %d MSI messages\n", msic);
    +			mac->mac_intr_spec = bwn_res_spec_msi;
    +			mac->mac_msi = 1;
    +		}
    +	}
    +
    +	error = bus_alloc_resources(dev, mac->mac_intr_spec,
    +	    mac->mac_res_irq);
    +	if (error) {
    +		device_printf(sc->sc_dev,
    +		    "couldn't allocate IRQ resources (%d)\n", error);
    +		goto fail1;
    +	}
    +
    +	if (mac->mac_msi == 0)
    +		error = bus_setup_intr(dev, mac->mac_res_irq[0],
    +		    INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
    +		    &mac->mac_intrhand[0]);
    +	else {
    +		for (i = 0; i < BWN_MSI_MESSAGES; i++) {
    +			error = bus_setup_intr(dev, mac->mac_res_irq[i],
    +			    INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
    +			    &mac->mac_intrhand[i]);
    +			if (error != 0) {
    +				device_printf(sc->sc_dev,
    +				    "couldn't setup interrupt (%d)\n", error);
    +				break;
    +			}
    +		}
    +	}
    +
    +	TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
    +
    +	/*
    +	 * calls attach-post routine
    +	 */
    +	if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
    +		bwn_attach_post(sc);
    +
    +	return (0);
    +fail1:
    +	if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
    +		pci_release_msi(dev);
    +fail0:
    +	free(mac, M_DEVBUF);
    +	return (error);
    +}
    +
    +static int
    +bwn_is_valid_ether_addr(uint8_t *addr)
    +{
    +	char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
    +
    +	if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
    +		return (FALSE);
    +
    +	return (TRUE);
    +}
    +
    +static int
    +bwn_attach_post(struct bwn_softc *sc)
    +{
    +	struct ieee80211com *ic;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct siba_dev_softc *sd = sc->sc_sd;
    +	struct siba_sprom *sprom = &sd->sd_bus->siba_sprom;
    +#ifdef BWN_DEBUG
    +	device_t dev = sc->sc_dev;
    +#endif
    +
    +	ic = ifp->if_l2com;
    +	ic->ic_ifp = ifp;
    +	/* XXX not right but it's not used anywhere important */
    +	ic->ic_phytype = IEEE80211_T_OFDM;
    +	ic->ic_opmode = IEEE80211_M_STA;
    +	ic->ic_caps =
    +		  IEEE80211_C_STA		/* station mode supported */
    +		| IEEE80211_C_MONITOR		/* monitor mode */
    +		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
    +		| IEEE80211_C_SHSLOT		/* short slot time supported */
    +		| IEEE80211_C_WME		/* WME/WMM supported */
    +		| IEEE80211_C_WPA		/* capable of WPA1+WPA2 */
    +		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
    +		| IEEE80211_C_TXPMGT		/* capable of txpow mgt */
    +		;
    +
    +	/* call MI attach routine. */
    +	ieee80211_ifattach(ic,
    +	    bwn_is_valid_ether_addr(sprom->mac_80211a) ? sprom->mac_80211a :
    +	    sprom->mac_80211bg);
    +
    +	ic->ic_headroom = sizeof(struct bwn_txhdr);
    +
    +	/* override default methods */
    +	ic->ic_raw_xmit = bwn_raw_xmit;
    +	ic->ic_newassoc = bwn_newassoc;
    +	ic->ic_updateslot = bwn_updateslot;
    +	ic->ic_update_promisc = bwn_update_promisc;
    +	ic->ic_wme.wme_update = bwn_wme_update;
    +
    +	ic->ic_node_alloc = bwn_node_alloc;
    +	sc->sc_node_cleanup = ic->ic_node_cleanup;
    +	ic->ic_node_cleanup = bwn_node_cleanup;
    +
    +	ic->ic_scan_start = bwn_scan_start;
    +	ic->ic_scan_end = bwn_scan_end;
    +	ic->ic_set_channel = bwn_set_channel;
    +
    +	ic->ic_vap_create = bwn_vap_create;
    +	ic->ic_vap_delete = bwn_vap_delete;
    +
    +	ieee80211_radiotap_attach(ic,
    +	    &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
    +	    BWN_TX_RADIOTAP_PRESENT,
    +	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
    +	    BWN_RX_RADIOTAP_PRESENT);
    +
    +#ifdef BWN_DEBUG
    +	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    +	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
    +#endif
    +
    +	if (bootverbose)
    +		ieee80211_announce(ic);
    +	return (0);
    +}
    +
    +static void
    +bwn_phy_detach(struct bwn_mac *mac)
    +{
    +
    +	if (mac->mac_phy.detach != NULL)
    +		mac->mac_phy.detach(mac);
    +}
    +
    +static int
    +bwn_detach(device_t dev)
    +{
    +	struct bwn_softc *sc = device_get_softc(dev);
    +	struct bwn_mac *mac = sc->sc_curmac;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	int i;
    +
    +	sc->sc_flags |= BWN_FLAG_INVALID;
    +
    +	if (device_is_attached(sc->sc_dev)) {
    +		bwn_stop(sc, 1);
    +		bwn_dma_free(mac);
    +		callout_drain(&sc->sc_led_blink_ch);
    +		callout_drain(&sc->sc_rfswitch_ch);
    +		callout_drain(&sc->sc_task_ch);
    +		callout_drain(&sc->sc_watchdog_ch);
    +		bwn_phy_detach(mac);
    +		if (ifp != NULL) {
    +			ieee80211_draintask(ic, &mac->mac_hwreset);
    +			ieee80211_draintask(ic, &mac->mac_txpower);
    +			ieee80211_ifdetach(ic);
    +			if_free(ifp);
    +		}
    +	}
    +	taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
    +	taskqueue_free(sc->sc_tq);
    +
    +	for (i = 0; i < BWN_MSI_MESSAGES; i++) {
    +		if (mac->mac_intrhand[i] != NULL) {
    +			bus_teardown_intr(dev, mac->mac_res_irq[i],
    +			    mac->mac_intrhand[i]);
    +			mac->mac_intrhand[i] = NULL;
    +		}
    +	}
    +	bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
    +	if (mac->mac_msi != 0)
    +		pci_release_msi(dev);
    +
    +	BWN_LOCK_DESTROY(sc);
    +	return (0);
    +}
    +
    +static int
    +bwn_attach_pre(struct bwn_softc *sc)
    +{
    +	struct ifnet *ifp;
    +	int error = 0;
    +
    +	BWN_LOCK_INIT(sc);
    +	TAILQ_INIT(&sc->sc_maclist);
    +	callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
    +	callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
    +	callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
    +
    +	sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
    +		taskqueue_thread_enqueue, &sc->sc_tq);
    +	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
    +		"%s taskq", device_get_nameunit(sc->sc_dev));
    +
    +	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
    +	if (ifp == NULL) {
    +		device_printf(sc->sc_dev, "can not if_alloc()\n");
    +		error = ENOSPC;
    +		goto fail;
    +	}
    +
    +	/* set these up early for if_printf use */
    +	if_initname(ifp, device_get_name(sc->sc_dev),
    +	    device_get_unit(sc->sc_dev));
    +
    +	ifp->if_softc = sc;
    +	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    +	ifp->if_init = bwn_init;
    +	ifp->if_ioctl = bwn_ioctl;
    +	ifp->if_start = bwn_start;
    +	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
    +	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
    +	IFQ_SET_READY(&ifp->if_snd);
    +
    +	return (0);
    +
    +fail:	BWN_LOCK_DESTROY(sc);
    +	return (error);
    +}
    +
    +static void
    +bwn_sprom_bugfixes(struct siba_softc *siba)
    +{
    +#define	BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)		\
    +	((siba->siba_pci_vid == PCI_VENDOR_##_vendor) &&		\
    +	 (siba->siba_pci_did == _device) &&				\
    +	 (siba->siba_pci_subvid == PCI_VENDOR_##_subvendor) &&		\
    +	 (siba->siba_pci_subdid == _subdevice))
    +
    +	if (siba->siba_board_vendor == PCI_VENDOR_APPLE &&
    +	    siba->siba_board_type == 0x4e && siba->siba_board_rev > 0x40)
    +		siba->siba_sprom.bf_lo |= BWN_BFL_PACTRL;
    +	if (siba->siba_board_vendor == SIBA_BOARDVENDOR_DELL &&
    +	    siba->siba_chipid == 0x4301 && siba->siba_board_rev == 0x74)
    +		siba->siba_sprom.bf_lo |= BWN_BFL_BTCOEXIST;
    +	if (siba->siba_type == SIBA_TYPE_PCI) {
    +		if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
    +		    BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
    +		    BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
    +		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
    +		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
    +		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
    +		    BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
    +			siba->siba_sprom.bf_lo &= ~BWN_BFL_BTCOEXIST;
    +	}
    +#undef	BWN_ISDEV
    +}
    +
    +static int
    +bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
    +{
    +#define	IS_RUNNING(ifp) \
    +	((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
    +	struct bwn_softc *sc = ifp->if_softc;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	struct ifreq *ifr = (struct ifreq *)data;
    +	int error = 0, startall;
    +
    +	switch (cmd) {
    +	case SIOCSIFFLAGS:
    +		startall = 0;
    +		if (IS_RUNNING(ifp)) {
    +			bwn_update_promisc(ifp);
    +		} else if (ifp->if_flags & IFF_UP) {
    +			if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
    +				bwn_init(sc);
    +				startall = 1;
    +			}
    +		} else
    +			bwn_stop(sc, 1);
    +		if (startall)
    +			ieee80211_start_all(ic);
    +		break;
    +	case SIOCGIFMEDIA:
    +		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
    +		break;
    +	case SIOCGIFADDR:
    +		error = ether_ioctl(ifp, cmd, data);
    +		break;
    +	default:
    +		error = EINVAL;
    +		break;
    +	}
    +	return (error);
    +}
    +
    +static void
    +bwn_start(struct ifnet *ifp)
    +{
    +	struct bwn_softc *sc = ifp->if_softc;
    +
    +	BWN_LOCK(sc);
    +	bwn_start_locked(ifp);
    +	BWN_UNLOCK(sc);
    +}
    +
    +static void
    +bwn_start_locked(struct ifnet *ifp)
    +{
    +	struct bwn_softc *sc = ifp->if_softc;
    +	struct bwn_mac *mac = sc->sc_curmac;
    +	struct ieee80211_frame *wh;
    +	struct ieee80211_node *ni;
    +	struct ieee80211_key *k;
    +	struct mbuf *m;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
    +	    mac->mac_status < BWN_MAC_STATUS_STARTED)
    +		return;
    +
    +	for (;;) {
    +		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);	/* XXX: LOCK */
    +		if (m == NULL)
    +			break;
    +
    +		if (bwn_tx_isfull(sc, m))
    +			break;
    +		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
    +		if (ni == NULL) {
    +			device_printf(sc->sc_dev, "unexpected NULL ni\n");
    +			m_freem(m);
    +			ifp->if_oerrors++;
    +			continue;
    +		}
    +		KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
    +		wh = mtod(m, struct ieee80211_frame *);
    +		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
    +			k = ieee80211_crypto_encap(ni, m);
    +			if (k == NULL) {
    +				ieee80211_free_node(ni);
    +				m_freem(m);
    +				ifp->if_oerrors++;
    +				continue;
    +			}
    +		}
    +		wh = NULL;	/* Catch any invalid use */
    +
    +		if (bwn_tx_start(sc, ni, m) != 0) {
    +			if (ni != NULL)
    +				ieee80211_free_node(ni);
    +			ifp->if_oerrors++;
    +			continue;
    +		}
    +
    +		sc->sc_watchdog_timer = 5;
    +	}
    +}
    +
    +static int
    +bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
    +{
    +	struct bwn_dma_ring *dr;
    +	struct bwn_mac *mac = sc->sc_curmac;
    +	struct bwn_pio_txqueue *tq;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
    +		dr = bwn_dma_select(mac, M_WME_GETAC(m));
    +		if (dr->dr_stop == 1 ||
    +		    bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
    +			dr->dr_stop = 1;
    +			goto full;
    +		}
    +	} else {
    +		tq = bwn_pio_select(mac, M_WME_GETAC(m));
    +		if (tq->tq_free == 0 || pktlen > tq->tq_size ||
    +		    pktlen > (tq->tq_size - tq->tq_used)) {
    +			tq->tq_stop = 1;
    +			goto full;
    +		}
    +	}
    +	return (0);
    +full:
    +	IFQ_DRV_PREPEND(&ifp->if_snd, m);
    +	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +	return (1);
    +}
    +
    +static int
    +bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
    +{
    +	struct bwn_mac *mac = sc->sc_curmac;
    +	int error;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
    +		m_freem(m);
    +		return (ENXIO);
    +	}
    +
    +	error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
    +	    bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
    +	if (error) {
    +		m_freem(m);
    +		return (error);
    +	}
    +	return (0);
    +}
    +
    +static int
    +bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
    +{
    +	struct bwn_pio_txpkt *tp;
    +	struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_txhdr txhdr;
    +	struct mbuf *m_new;
    +	uint32_t ctl32;
    +	int error;
    +	uint16_t ctl16;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	/* XXX TODO send packets after DTIM */
    +
    +	KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
    +	tp = TAILQ_FIRST(&tq->tq_pktlist);
    +	tp->tp_ni = ni;
    +	tp->tp_m = m;
    +
    +	error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
    +	if (error) {
    +		device_printf(sc->sc_dev, "tx fail\n");
    +		return (error);
    +	}
    +
    +	TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
    +	tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
    +	tq->tq_free--;
    +
    +	if (mac->mac_sd->sd_id.sd_rev >= 8) {
    +		/*
    +		 * XXX please removes m_defrag(9)
    +		 */
    +		m_new = m_defrag(m, M_DONTWAIT);
    +		if (m_new == NULL) {
    +			device_printf(sc->sc_dev,
    +			    "%s: can't defrag TX buffer\n",
    +			    __func__);
    +			return (ENOBUFS);
    +		}
    +		if (m_new->m_next != NULL)
    +			device_printf(sc->sc_dev,
    +			    "TODO: fragmented packets for PIO\n");
    +		tp->tp_m = m_new;
    +
    +		/* send HEADER */
    +		ctl32 = bwn_pio_write_multi_4(mac, tq,
    +		    (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
    +			BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
    +		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
    +		/* send BODY */
    +		ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
    +		    mtod(m_new, const void *), m_new->m_pkthdr.len);
    +		bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
    +		    ctl32 | BWN_PIO8_TXCTL_EOF);
    +	} else {
    +		ctl16 = bwn_pio_write_multi_2(mac, tq,
    +		    (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
    +			BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
    +		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
    +		ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
    +		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
    +		    ctl16 | BWN_PIO_TXCTL_EOF);
    +	}
    +
    +	return (0);
    +}
    +
    +static struct bwn_pio_txqueue *
    +bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
    +{
    +
    +	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
    +		return (&mac->mac_method.pio.wme[WME_AC_BE]);
    +
    +	switch (prio) {
    +	case 0:
    +		return (&mac->mac_method.pio.wme[WME_AC_BE]);
    +	case 1:
    +		return (&mac->mac_method.pio.wme[WME_AC_BK]);
    +	case 2:
    +		return (&mac->mac_method.pio.wme[WME_AC_VI]);
    +	case 3:
    +		return (&mac->mac_method.pio.wme[WME_AC_VO]);
    +	}
    +	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +}
    +
    +static int
    +bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
    +{
    +#define	BWN_GET_TXHDRCACHE(slot)					\
    +	&(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +	struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
    +	struct bwn_dmadesc_generic *desc;
    +	struct bwn_dmadesc_meta *mt;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
    +	int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
    +
    +	BWN_ASSERT_LOCKED(sc);
    +	KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
    +
    +	/* XXX send after DTIM */
    +
    +	slot = bwn_dma_getslot(dr);
    +	dr->getdesc(dr, slot, &desc, &mt);
    +	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	error = bwn_set_txhdr(dr->dr_mac, ni, m,
    +	    (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
    +	    BWN_DMA_COOKIE(dr, slot));
    +	if (error)
    +		goto fail;
    +	error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
    +	    BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
    +	    &mt->mt_paddr, BUS_DMA_NOWAIT);
    +	if (error) {
    +		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
    +		    __func__, error);
    +		goto fail;
    +	}
    +	bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
    +	    BUS_DMASYNC_PREWRITE);
    +	dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
    +	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
    +	    BUS_DMASYNC_PREWRITE);
    +
    +	slot = bwn_dma_getslot(dr);
    +	dr->getdesc(dr, slot, &desc, &mt);
    +	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
    +	    mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
    +	mt->mt_m = m;
    +	mt->mt_ni = ni;
    +
    +	error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
    +	    bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
    +	if (error && error != EFBIG) {
    +		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
    +		    __func__, error);
    +		goto fail;
    +	}
    +	if (error) {    /* error == EFBIG */
    +		struct mbuf *m_new;
    +
    +		m_new = m_defrag(m, M_DONTWAIT);
    +		if (m_new == NULL) {
    +			if_printf(ifp, "%s: can't defrag TX buffer\n",
    +			    __func__);
    +			error = ENOBUFS;
    +			goto fail;
    +		} else {
    +			m = m_new;
    +		}
    +
    +		mt->mt_m = m;
    +		error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
    +		    m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
    +		if (error) {
    +			if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
    +			    __func__, error);
    +			goto fail;
    +		}
    +	}
    +	bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
    +	dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
    +	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
    +	    BUS_DMASYNC_PREWRITE);
    +
    +	/* XXX send after DTIM */
    +
    +	dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
    +	return (0);
    +fail:
    +	dr->dr_curslot = backup[0];
    +	dr->dr_usedslot = backup[1];
    +	return (error);
    +#undef BWN_GET_TXHDRCACHE
    +}
    +
    +static void
    +bwn_watchdog(void *arg)
    +{
    +	struct bwn_softc *sc = arg;
    +	struct ifnet *ifp = sc->sc_ifp;
    +
    +	if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
    +		if_printf(ifp, "device timeout\n");
    +		ifp->if_oerrors++;
    +	}
    +	callout_schedule(&sc->sc_watchdog_ch, hz);
    +}
    +
    +static int
    +bwn_attach_core(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	int error, have_bg = 0, have_a = 0;
    +	uint32_t high;
    +
    +	KASSERT(sd->sd_id.sd_rev >= 5,
    +	    ("unsupported revision %d", sd->sd_id.sd_rev));
    +
    +	siba_powerup(siba, 0);
    +
    +	high = siba_read_4(sd, SIBA_TGSHIGH);
    +	bwn_reset_core(mac,
    +	    (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
    +	error = bwn_phy_getinfo(mac, high);
    +	if (error)
    +		goto fail;
    +
    +	have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
    +	have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
    +	if (siba->siba_pci_did != 0x4312 && siba->siba_pci_did != 0x4319 &&
    +	    siba->siba_pci_did != 0x4324) {
    +		have_a = have_bg = 0;
    +		if (mac->mac_phy.type == BWN_PHYTYPE_A)
    +			have_a = 1;
    +		else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
    +		    mac->mac_phy.type == BWN_PHYTYPE_N ||
    +		    mac->mac_phy.type == BWN_PHYTYPE_LP)
    +			have_bg = 1;
    +		else
    +			KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
    +			    mac->mac_phy.type));
    +	}
    +	/* XXX turns off PHY A because it's not supported */
    +	if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
    +	    mac->mac_phy.type != BWN_PHYTYPE_N) {
    +		have_a = 0;
    +		have_bg = 1;
    +	}
    +
    +	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
    +		mac->mac_phy.attach = bwn_phy_g_attach;
    +		mac->mac_phy.detach = bwn_phy_g_detach;
    +		mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
    +		mac->mac_phy.init_pre = bwn_phy_g_init_pre;
    +		mac->mac_phy.init = bwn_phy_g_init;
    +		mac->mac_phy.exit = bwn_phy_g_exit;
    +		mac->mac_phy.phy_read = bwn_phy_g_read;
    +		mac->mac_phy.phy_write = bwn_phy_g_write;
    +		mac->mac_phy.rf_read = bwn_phy_g_rf_read;
    +		mac->mac_phy.rf_write = bwn_phy_g_rf_write;
    +		mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
    +		mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
    +		mac->mac_phy.switch_analog = bwn_phy_switch_analog;
    +		mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
    +		mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
    +		mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
    +		mac->mac_phy.set_im = bwn_phy_g_im;
    +		mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
    +		mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
    +		mac->mac_phy.task_15s = bwn_phy_g_task_15s;
    +		mac->mac_phy.task_60s = bwn_phy_g_task_60s;
    +	} else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
    +		mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
    +		mac->mac_phy.init = bwn_phy_lp_init;
    +		mac->mac_phy.phy_read = bwn_phy_lp_read;
    +		mac->mac_phy.phy_write = bwn_phy_lp_write;
    +		mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
    +		mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
    +		mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
    +		mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
    +		mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
    +		mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
    +		mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
    +		mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
    +		mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
    +	} else {
    +		device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
    +		    mac->mac_phy.type);
    +		error = ENXIO;
    +		goto fail;
    +	}
    +
    +	mac->mac_phy.gmode = have_bg;
    +	if (mac->mac_phy.attach != NULL) {
    +		error = mac->mac_phy.attach(mac);
    +		if (error) {
    +			device_printf(sc->sc_dev, "failed\n");
    +			goto fail;
    +		}
    +	}
    +
    +	bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
    +
    +	error = bwn_chiptest(mac);
    +	if (error)
    +		goto fail;
    +	error = bwn_setup_channels(mac, have_bg, have_a);
    +	if (error) {
    +		device_printf(sc->sc_dev, "failed to setup channels\n");
    +		goto fail;
    +	}
    +
    +	if (sc->sc_curmac == NULL)
    +		sc->sc_curmac = mac;
    +
    +	error = bwn_dma_attach(mac);
    +	if (error != 0) {
    +		device_printf(sc->sc_dev, "failed to initialize DMA\n");
    +		goto fail;
    +	}
    +
    +	mac->mac_phy.switch_analog(mac, 0);
    +
    +	siba_dev_down(sd, 0);
    +fail:
    +	siba_powerdown(siba);
    +	return (error);
    +}
    +
    +static void
    +bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
    +{
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	uint32_t low, ctl;
    +
    +	flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
    +
    +	siba_dev_up(sd, flags);
    +	DELAY(2000);
    +
    +	low = (siba_read_4(sd, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
    +	    ~BWN_TGSLOW_PHYRESET;
    +	siba_write_4(sd, SIBA_TGSLOW, low);
    +	siba_read_4(sd, SIBA_TGSLOW);
    +	DELAY(1000);
    +	siba_write_4(sd, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
    +	siba_read_4(sd, SIBA_TGSLOW);
    +	DELAY(1000);
    +
    +	if (mac->mac_phy.switch_analog != NULL)
    +		mac->mac_phy.switch_analog(mac, 1);
    +
    +	ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
    +	if (flags & BWN_TGSLOW_SUPPORT_G)
    +		ctl |= BWN_MACCTL_GMODE;
    +	BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
    +}
    +
    +static int
    +bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	uint32_t tmp;
    +
    +	/* PHY */
    +	tmp = BWN_READ_2(mac, BWN_PHYVER);
    +	phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
    +	phy->rf_on = 1;
    +	phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
    +	phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
    +	phy->rev = (tmp & BWN_PHYVER_VERSION);
    +	if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
    +	    (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
    +		phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
    +	    (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
    +	    (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
    +	    (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
    +		goto unsupphy;
    +
    +	/* RADIO */
    +	if (siba->siba_chipid == 0x4317) {
    +		if (siba->siba_chiprev == 0)
    +			tmp = 0x3205017f;
    +		else if (siba->siba_chiprev == 1)
    +			tmp = 0x4205017f;
    +		else
    +			tmp = 0x5205017f;
    +	} else {
    +		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
    +		tmp = BWN_READ_2(mac, BWN_RFDATALO);
    +		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
    +		tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
    +	}
    +	phy->rf_rev = (tmp & 0xf0000000) >> 28;
    +	phy->rf_ver = (tmp & 0x0ffff000) >> 12;
    +	phy->rf_manuf = (tmp & 0x00000fff);
    +	if (phy->rf_manuf != 0x17f)	/* 0x17f is broadcom */
    +		goto unsupradio;
    +	if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
    +	     phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
    +	    (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
    +	    (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
    +	    (phy->type == BWN_PHYTYPE_N &&
    +	     phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
    +	    (phy->type == BWN_PHYTYPE_LP &&
    +	     phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
    +		goto unsupradio;
    +
    +	return (0);
    +unsupphy:
    +	device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
    +	    "analog %#x)\n",
    +	    phy->type, phy->rev, phy->analog);
    +	return (ENXIO);
    +unsupradio:
    +	device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
    +	    "rev %#x)\n",
    +	    phy->rf_manuf, phy->rf_ver, phy->rf_rev);
    +	return (ENXIO);
    +}
    +
    +static int
    +bwn_chiptest(struct bwn_mac *mac)
    +{
    +#define	TESTVAL0	0x55aaaa55
    +#define	TESTVAL1	0xaa5555aa
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	uint32_t v, backup;
    +
    +	BWN_LOCK(sc);
    +
    +	backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
    +
    +	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
    +	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
    +		goto error;
    +	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
    +	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
    +		goto error;
    +
    +	bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
    +
    +	if ((sd->sd_id.sd_rev >= 3) && (sd->sd_id.sd_rev <= 10)) {
    +		BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
    +		BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
    +		if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
    +			goto error;
    +		if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
    +			goto error;
    +	}
    +	BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
    +
    +	v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
    +	if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
    +		goto error;
    +
    +	BWN_UNLOCK(sc);
    +	return (0);
    +error:
    +	BWN_UNLOCK(sc);
    +	device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
    +	return (ENODEV);
    +}
    +
    +#define	IEEE80211_CHAN_HTG	(IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
    +#define	IEEE80211_CHAN_HTA	(IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
    +
    +static int
    +bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +
    +	memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
    +	ic->ic_nchans = 0;
    +
    +	if (have_bg)
    +		bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
    +		    &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
    +	if (mac->mac_phy.type == BWN_PHYTYPE_N) {
    +		if (have_a)
    +			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
    +			    &ic->ic_nchans, &bwn_chantable_n,
    +			    IEEE80211_CHAN_HTA);
    +	} else {
    +		if (have_a)
    +			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
    +			    &ic->ic_nchans, &bwn_chantable_a,
    +			    IEEE80211_CHAN_A);
    +	}
    +
    +	mac->mac_phy.supports_2ghz = have_bg;
    +	mac->mac_phy.supports_5ghz = have_a;
    +
    +	return (ic->ic_nchans == 0 ? ENXIO : 0);
    +}
    +
    +static uint32_t
    +bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint32_t ret;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if (way == BWN_SHARED) {
    +		KASSERT((offset & 0x0001) == 0,
    +		    ("%s:%d warn", __func__, __LINE__));
    +		if (offset & 0x0003) {
    +			bwn_shm_ctlword(mac, way, offset >> 2);
    +			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
    +			ret <<= 16;
    +			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
    +			ret |= BWN_READ_2(mac, BWN_SHM_DATA);
    +			goto out;
    +		}
    +		offset >>= 2;
    +	}
    +	bwn_shm_ctlword(mac, way, offset);
    +	ret = BWN_READ_4(mac, BWN_SHM_DATA);
    +out:
    +	return (ret);
    +}
    +
    +static uint16_t
    +bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint16_t ret;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if (way == BWN_SHARED) {
    +		KASSERT((offset & 0x0001) == 0,
    +		    ("%s:%d warn", __func__, __LINE__));
    +		if (offset & 0x0003) {
    +			bwn_shm_ctlword(mac, way, offset >> 2);
    +			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
    +			goto out;
    +		}
    +		offset >>= 2;
    +	}
    +	bwn_shm_ctlword(mac, way, offset);
    +	ret = BWN_READ_2(mac, BWN_SHM_DATA);
    +out:
    +
    +	return (ret);
    +}
    +
    +static void
    +bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
    +    uint16_t offset)
    +{
    +	uint32_t control;
    +
    +	control = way;
    +	control <<= 16;
    +	control |= offset;
    +	BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
    +}
    +
    +static void
    +bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
    +    uint32_t value)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if (way == BWN_SHARED) {
    +		KASSERT((offset & 0x0001) == 0,
    +		    ("%s:%d warn", __func__, __LINE__));
    +		if (offset & 0x0003) {
    +			bwn_shm_ctlword(mac, way, offset >> 2);
    +			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
    +				    (value >> 16) & 0xffff);
    +			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
    +			BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
    +			return;
    +		}
    +		offset >>= 2;
    +	}
    +	bwn_shm_ctlword(mac, way, offset);
    +	BWN_WRITE_4(mac, BWN_SHM_DATA, value);
    +}
    +
    +static void
    +bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
    +    uint16_t value)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if (way == BWN_SHARED) {
    +		KASSERT((offset & 0x0001) == 0,
    +		    ("%s:%d warn", __func__, __LINE__));
    +		if (offset & 0x0003) {
    +			bwn_shm_ctlword(mac, way, offset >> 2);
    +			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
    +			return;
    +		}
    +		offset >>= 2;
    +	}
    +	bwn_shm_ctlword(mac, way, offset);
    +	BWN_WRITE_2(mac, BWN_SHM_DATA, value);
    +}
    +
    +static void
    +bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
    +    int txpow)
    +{
    +
    +	c->ic_freq = freq;
    +	c->ic_flags = flags;
    +	c->ic_ieee = ieee;
    +	c->ic_minpower = 0;
    +	c->ic_maxpower = 2 * txpow;
    +	c->ic_maxregpower = txpow;
    +}
    +
    +static void
    +bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
    +    const struct bwn_channelinfo *ci, int flags)
    +{
    +	struct ieee80211_channel *c;
    +	int i;
    +
    +	c = &chans[*nchans];
    +
    +	for (i = 0; i < ci->nchannels; i++) {
    +		const struct bwn_channel *hc;
    +
    +		hc = &ci->channels[i];
    +		if (*nchans >= maxchans)
    +			break;
    +		bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
    +		c++, (*nchans)++;
    +		if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
    +			/* g channel have a separate b-only entry */
    +			if (*nchans >= maxchans)
    +				break;
    +			c[0] = c[-1];
    +			c[-1].ic_flags = IEEE80211_CHAN_B;
    +			c++, (*nchans)++;
    +		}
    +		if (flags == IEEE80211_CHAN_HTG) {
    +			/* HT g channel have a separate g-only entry */
    +			if (*nchans >= maxchans)
    +				break;
    +			c[-1].ic_flags = IEEE80211_CHAN_G;
    +			c[0] = c[-1];
    +			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
    +			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
    +			c++, (*nchans)++;
    +		}
    +		if (flags == IEEE80211_CHAN_HTA) {
    +			/* HT a channel have a separate a-only entry */
    +			if (*nchans >= maxchans)
    +				break;
    +			c[-1].ic_flags = IEEE80211_CHAN_A;
    +			c[0] = c[-1];
    +			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
    +			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
    +			c++, (*nchans)++;
    +		}
    +	}
    +}
    +
    +static int
    +bwn_phy_g_attach(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_sprom *sprom = &sd->sd_bus->siba_sprom;
    +	unsigned int i;
    +	int16_t pab0 = (int16_t)(sprom->pa0b0), pab1 = (int16_t)(sprom->pa0b1),
    +	    pab2 = (int16_t)(sprom->pa0b2);
    +	static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
    +	int8_t bg = (int8_t)sprom->tssi_bg;
    +
    +	if ((sd->sd_bus->siba_chipid == 0x4301) && (phy->rf_ver != 0x2050))
    +		device_printf(sc->sc_dev, "not supported anymore\n");
    +
    +	pg->pg_flags = 0;
    +	if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
    +	    pab2 == -1) {
    +		pg->pg_idletssi = 52;
    +		pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
    +		return (0);
    +	}
    +
    +	pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
    +	pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
    +	if (pg->pg_tssi2dbm == NULL) {
    +		device_printf(sc->sc_dev, "failed to allocate buffer\n");
    +		return (ENOMEM);
    +	}
    +	for (i = 0; i < 64; i++) {
    +		int32_t m1, m2, f, q, delta;
    +		int8_t j = 0;
    +
    +		m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
    +		m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
    +		f = 256;
    +
    +		do {
    +			if (j > 15) {
    +				device_printf(sc->sc_dev,
    +				    "failed to generate tssi2dBm\n");
    +				free(pg->pg_tssi2dbm, M_DEVBUF);
    +				return (ENOMEM);
    +			}
    +			q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
    +			    f, 2048);
    +			delta = abs(q - f);
    +			f = q;
    +			j++;
    +		} while (delta >= 2);
    +
    +		pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
    +		    128);
    +	}
    +
    +	pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
    +	return (0);
    +}
    +
    +static void
    +bwn_phy_g_detach(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
    +
    +	if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
    +		free(pg->pg_tssi2dbm, M_DEVBUF);
    +		pg->pg_tssi2dbm = NULL;
    +	}
    +	pg->pg_flags = 0;
    +}
    +
    +static void
    +bwn_phy_g_init_pre(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	void *tssi2dbm;
    +	int idletssi;
    +	unsigned int i;
    +
    +	tssi2dbm = pg->pg_tssi2dbm;
    +	idletssi = pg->pg_idletssi;
    +
    +	memset(pg, 0, sizeof(*pg));
    +
    +	pg->pg_tssi2dbm = tssi2dbm;
    +	pg->pg_idletssi = idletssi;
    +
    +	memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
    +
    +	for (i = 0; i < N(pg->pg_nrssi); i++)
    +		pg->pg_nrssi[i] = -1000;
    +	for (i = 0; i < N(pg->pg_nrssi_lt); i++)
    +		pg->pg_nrssi_lt[i] = i;
    +	pg->pg_lofcal = 0xffff;
    +	pg->pg_initval = 0xffff;
    +	pg->pg_immode = BWN_IMMODE_NONE;
    +	pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
    +	pg->pg_avgtssi = 0xff;
    +
    +	pg->pg_loctl.tx_bias = 0xff;
    +	TAILQ_INIT(&pg->pg_loctl.calib_list);
    +}
    +
    +static int
    +bwn_phy_g_prepare_hw(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
    +	struct siba_softc *bus = mac->mac_sd->sd_bus;
    +	static const struct bwn_rfatt rfatt0[] = {
    +		{ 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 },	{ 9, 0 }, { 2, 0 },
    +		{ 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
    +		{ 3, 1 }, { 4, 1 }
    +	};
    +	static const struct bwn_rfatt rfatt1[] = {
    +		{ 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
    +		{ 14, 1 }
    +	};
    +	static const struct bwn_rfatt rfatt2[] = {
    +		{ 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
    +		{ 9, 1 }
    +	};
    +	static const struct bwn_bbatt bbatt_0[] = {
    +		{ 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
    +	};
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
    +
    +	if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
    +		pg->pg_bbatt.att = 0;
    +	else
    +		pg->pg_bbatt.att = 2;
    +
    +	/* prepare Radio Attenuation */
    +	pg->pg_rfatt.padmix = 0;
    +
    +	if (bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM &&
    +	    bus->siba_board_type == SIBA_BOARD_BCM4309G) {
    +		if (bus->siba_board_rev < 0x43) {
    +			pg->pg_rfatt.att = 2;
    +			goto done;
    +		} else if (bus->siba_board_rev < 0x51) {
    +			pg->pg_rfatt.att = 3;
    +			goto done;
    +		}
    +	}
    +
    +	if (phy->type == BWN_PHYTYPE_A) {
    +		pg->pg_rfatt.att = 0x60;
    +		goto done;
    +	}
    +
    +	switch (phy->rf_ver) {
    +	case 0x2050:
    +		switch (phy->rf_rev) {
    +		case 0:
    +			pg->pg_rfatt.att = 5;
    +			goto done;
    +		case 1:
    +			if (phy->type == BWN_PHYTYPE_G) {
    +				if (bus->siba_board_vendor ==
    +				    SIBA_BOARDVENDOR_BCM &&
    +				    bus->siba_board_type ==
    +				    SIBA_BOARD_BCM4309G &&
    +				    bus->siba_board_rev >= 30)
    +					pg->pg_rfatt.att = 3;
    +				else if (bus->siba_board_vendor ==
    +				    SIBA_BOARDVENDOR_BCM &&
    +				    bus->siba_board_type == SIBA_BOARD_BU4306)
    +					pg->pg_rfatt.att = 3;
    +				else
    +					pg->pg_rfatt.att = 1;
    +			} else {
    +				if (bus->siba_board_vendor ==
    +				    SIBA_BOARDVENDOR_BCM &&
    +				    bus->siba_board_type ==
    +				    SIBA_BOARD_BCM4309G &&
    +				    bus->siba_board_rev >= 30)
    +					pg->pg_rfatt.att = 7;
    +				else
    +					pg->pg_rfatt.att = 6;
    +			}
    +			goto done;
    +		case 2:
    +			if (phy->type == BWN_PHYTYPE_G) {
    +				if (bus->siba_board_vendor ==
    +				    SIBA_BOARDVENDOR_BCM &&
    +				    bus->siba_board_type ==
    +				    SIBA_BOARD_BCM4309G &&
    +				    bus->siba_board_rev >= 30)
    +					pg->pg_rfatt.att = 3;
    +				else if (bus->siba_board_vendor ==
    +				    SIBA_BOARDVENDOR_BCM &&
    +				    bus->siba_board_type == SIBA_BOARD_BU4306)
    +					pg->pg_rfatt.att = 5;
    +				else if (bus->siba_chipid == 0x4320)
    +					pg->pg_rfatt.att = 4;
    +				else
    +					pg->pg_rfatt.att = 3;
    +			} else
    +				pg->pg_rfatt.att = 6;
    +			goto done;
    +		case 3:
    +			pg->pg_rfatt.att = 5;
    +			goto done;
    +		case 4:
    +		case 5:
    +			pg->pg_rfatt.att = 1;
    +			goto done;
    +		case 6:
    +		case 7:
    +			pg->pg_rfatt.att = 5;
    +			goto done;
    +		case 8:
    +			pg->pg_rfatt.att = 0xa;
    +			pg->pg_rfatt.padmix = 1;
    +			goto done;
    +		case 9:
    +		default:
    +			pg->pg_rfatt.att = 5;
    +			goto done;
    +		}
    +		break;
    +	case 0x2053:
    +		switch (phy->rf_rev) {
    +		case 1:
    +			pg->pg_rfatt.att = 6;
    +			goto done;
    +		}
    +		break;
    +	}
    +	pg->pg_rfatt.att = 5;
    +done:
    +	pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
    +
    +	if (!bwn_has_hwpctl(mac)) {
    +		lo->rfatt.array = rfatt0;
    +		lo->rfatt.len = N(rfatt0);
    +		lo->rfatt.min = 0;
    +		lo->rfatt.max = 9;
    +		goto genbbatt;
    +	}
    +	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
    +		lo->rfatt.array = rfatt1;
    +		lo->rfatt.len = N(rfatt1);
    +		lo->rfatt.min = 0;
    +		lo->rfatt.max = 14;
    +		goto genbbatt;
    +	}
    +	lo->rfatt.array = rfatt2;
    +	lo->rfatt.len = N(rfatt2);
    +	lo->rfatt.min = 0;
    +	lo->rfatt.max = 9;
    +genbbatt:
    +	lo->bbatt.array = bbatt_0;
    +	lo->bbatt.len = N(bbatt_0);
    +	lo->bbatt.min = 0;
    +	lo->bbatt.max = 8;
    +
    +	BWN_READ_4(mac, BWN_MACCTL);
    +	if (phy->rev == 1) {
    +		phy->gmode = 0;
    +		bwn_reset_core(mac, 0);
    +		bwn_phy_g_init_sub(mac);
    +		phy->gmode = 1;
    +		bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
    +	}
    +	return (0);
    +}
    +
    +static uint16_t
    +bwn_phy_g_txctl(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +
    +	if (phy->rf_ver != 0x2050)
    +		return (0);
    +	if (phy->rf_rev == 1)
    +		return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
    +	if (phy->rf_rev < 6)
    +		return (BWN_TXCTL_PA2DB);
    +	if (phy->rf_rev == 8)
    +		return (BWN_TXCTL_TXMIX);
    +	return (0);
    +}
    +
    +static int
    +bwn_phy_g_init(struct bwn_mac *mac)
    +{
    +
    +	bwn_phy_g_init_sub(mac);
    +	return (0);
    +}
    +
    +static void
    +bwn_phy_g_exit(struct bwn_mac *mac)
    +{
    +	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
    +	struct bwn_lo_calib *cal, *tmp;
    +
    +	if (lo == NULL)
    +		return;
    +	TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
    +		TAILQ_REMOVE(&lo->calib_list, cal, list);
    +		free(cal, M_DEVBUF);
    +	}
    +}
    +
    +static uint16_t
    +bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
    +{
    +
    +	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
    +	return (BWN_READ_2(mac, BWN_PHYDATA));
    +}
    +
    +static void
    +bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
    +{
    +
    +	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
    +	BWN_WRITE_2(mac, BWN_PHYDATA, value);
    +}
    +
    +static uint16_t
    +bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
    +{
    +
    +	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
    +	BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
    +	return (BWN_READ_2(mac, BWN_RFDATALO));
    +}
    +
    +static void
    +bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
    +{
    +
    +	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
    +	BWN_WRITE_2(mac, BWN_RFCTL, reg);
    +	BWN_WRITE_2(mac, BWN_RFDATALO, value);
    +}
    +
    +static int
    +bwn_phy_g_hwpctl(struct bwn_mac *mac)
    +{
    +
    +	return (mac->mac_phy.rev >= 6);
    +}
    +
    +static void
    +bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	unsigned int channel;
    +	uint16_t rfover, rfoverval;
    +
    +	if (on) {
    +		if (phy->rf_on)
    +			return;
    +
    +		BWN_PHY_WRITE(mac, 0x15, 0x8000);
    +		BWN_PHY_WRITE(mac, 0x15, 0xcc00);
    +		BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
    +		if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
    +			    pg->pg_radioctx_over);
    +			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +			    pg->pg_radioctx_overval);
    +			pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
    +		}
    +		channel = phy->chan;
    +		bwn_phy_g_switch_chan(mac, 6, 1);
    +		bwn_phy_g_switch_chan(mac, channel, 0);
    +		return;
    +	}
    +
    +	rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
    +	rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
    +	pg->pg_radioctx_over = rfover;
    +	pg->pg_radioctx_overval = rfoverval;
    +	pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
    +	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
    +}
    +
    +static int
    +bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
    +{
    +
    +	if ((newchan < 1) || (newchan > 14))
    +		return (EINVAL);
    +	bwn_phy_g_switch_chan(mac, newchan, 0);
    +
    +	return (0);
    +}
    +
    +static uint32_t
    +bwn_phy_g_get_default_chan(struct bwn_mac *mac)
    +{
    +
    +	return (1);
    +}
    +
    +static void
    +bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	uint64_t hf;
    +	int autodiv = 0;
    +	uint16_t tmp;
    +
    +	if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
    +		autodiv = 1;
    +
    +	hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
    +	bwn_hf_write(mac, hf);
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
    +	    (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
    +	    ((autodiv ? BWN_ANTAUTO1 : antenna)
    +		<< BWN_PHY_BBANDCFG_RXANT_SHIFT));
    +
    +	if (autodiv) {
    +		tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
    +		if (antenna == BWN_ANTAUTO1)
    +			tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
    +		else
    +			tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
    +		BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
    +	}
    +	tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
    +	if (autodiv)
    +		tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
    +	else
    +		tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
    +	BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
    +	if (phy->rev >= 2) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
    +		    BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
    +		BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
    +		    (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
    +		    0x15);
    +		if (phy->rev == 2)
    +			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
    +		else
    +			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
    +			    (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
    +			    8);
    +	}
    +	if (phy->rev >= 6)
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
    +
    +	hf |= BWN_HF_UCODE_ANTDIV_HELPER;
    +	bwn_hf_write(mac, hf);
    +}
    +
    +static int
    +bwn_phy_g_im(struct bwn_mac *mac, int mode)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
    +	KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
    +
    +	if (phy->rev == 0 || !phy->gmode)
    +		return (ENODEV);
    +
    +	pg->pg_aci_wlan_automatic = 0;
    +	return (0);
    +}
    +
    +static int
    +bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct siba_softc *siba = mac->mac_sd->sd_bus;
    +	unsigned int tssi;
    +	int cck, ofdm;
    +	int power;
    +	int rfatt, bbatt;
    +	unsigned int max;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
    +
    +	cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
    +	ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
    +	if (cck < 0 && ofdm < 0) {
    +		if (ignore_tssi == 0)
    +			return (BWN_TXPWR_RES_DONE);
    +		cck = 0;
    +		ofdm = 0;
    +	}
    +	tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
    +	if (pg->pg_avgtssi != 0xff)
    +		tssi = (tssi + pg->pg_avgtssi) / 2;
    +	pg->pg_avgtssi = tssi;
    +	KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
    +
    +	max = siba->siba_sprom.maxpwr_bg;
    +	if (siba->siba_sprom.bf_lo & BWN_BFL_PACTRL)
    +		max -= 3;
    +	if (max >= 120) {
    +		device_printf(sc->sc_dev, "invalid max TX-power value\n");
    +		siba->siba_sprom.maxpwr_bg = max = 80;
    +	}
    +
    +	power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
    +	    (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
    +	     tssi, 0x00), 0x3f)]);
    +	if (power == 0)
    +		return (BWN_TXPWR_RES_DONE);
    +
    +	rfatt = -((power + 7) / 8);
    +	bbatt = (-(power / 2)) - (4 * rfatt);
    +	if ((rfatt == 0) && (bbatt == 0))
    +		return (BWN_TXPWR_RES_DONE);
    +	pg->pg_bbatt_delta = bbatt;
    +	pg->pg_rfatt_delta = rfatt;
    +	return (BWN_TXPWR_RES_NEED_ADJUST);
    +}
    +
    +static void
    +bwn_phy_g_set_txpwr(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	int rfatt, bbatt;
    +	uint8_t txctl;
    +
    +	bwn_mac_suspend(mac);
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	bbatt = pg->pg_bbatt.att;
    +	bbatt += pg->pg_bbatt_delta;
    +	rfatt = pg->pg_rfatt.att;
    +	rfatt += pg->pg_rfatt_delta;
    +
    +	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
    +	txctl = pg->pg_txctl;
    +	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
    +		if (rfatt <= 1) {
    +			if (txctl == 0) {
    +				txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
    +				rfatt += 2;
    +				bbatt += 2;
    +			} else if (mac->mac_sd->sd_bus->siba_sprom.
    +				   bf_lo &
    +				   BWN_BFL_PACTRL) {
    +				bbatt += 4 * (rfatt - 2);
    +				rfatt = 2;
    +			}
    +		} else if (rfatt > 4 && txctl) {
    +			txctl = 0;
    +			if (bbatt < 3) {
    +				rfatt -= 3;
    +				bbatt += 2;
    +			} else {
    +				rfatt -= 2;
    +				bbatt -= 2;
    +			}
    +		}
    +	}
    +	pg->pg_txctl = txctl;
    +	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
    +	pg->pg_rfatt.att = rfatt;
    +	pg->pg_bbatt.att = bbatt;
    +
    +	DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
    +
    +	bwn_phy_lock(mac);
    +	bwn_rf_lock(mac);
    +	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
    +	    pg->pg_txctl);
    +	bwn_rf_unlock(mac);
    +	bwn_phy_unlock(mac);
    +
    +	bwn_mac_enable(mac);
    +}
    +
    +static void
    +bwn_phy_g_task_15s(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
    +	unsigned long expire, now;
    +	struct bwn_lo_calib *cal, *tmp;
    +	uint8_t expired = 0;
    +
    +	bwn_mac_suspend(mac);
    +
    +	if (lo == NULL)
    +		goto fail;
    +
    +	BWN_GETTIME(now);
    +	if (bwn_has_hwpctl(mac)) {
    +		expire = now - BWN_LO_PWRVEC_EXPIRE;
    +		if (time_before(lo->pwr_vec_read_time, expire)) {
    +			bwn_lo_get_powervector(mac);
    +			bwn_phy_g_dc_lookup_init(mac, 0);
    +		}
    +		goto fail;
    +	}
    +
    +	expire = now - BWN_LO_CALIB_EXPIRE;
    +	TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
    +		if (!time_before(cal->calib_time, expire))
    +			continue;
    +		if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
    +		    BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
    +			KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
    +			expired = 1;
    +		}
    +
    +		DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
    +		    cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
    +		    cal->ctl.i, cal->ctl.q);
    +
    +		TAILQ_REMOVE(&lo->calib_list, cal, list);
    +		free(cal, M_DEVBUF);
    +	}
    +	if (expired || TAILQ_EMPTY(&lo->calib_list)) {
    +		cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
    +		    &pg->pg_rfatt);
    +		if (cal == NULL) {
    +			device_printf(sc->sc_dev,
    +			    "failed to recalibrate LO\n");
    +			goto fail;
    +		}
    +		TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
    +		bwn_lo_write(mac, &cal->ctl);
    +	}
    +
    +fail:
    +	bwn_mac_enable(mac);
    +}
    +
    +static void
    +bwn_phy_g_task_60s(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	uint8_t old = phy->chan;
    +
    +	if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI))
    +		return;
    +
    +	bwn_mac_suspend(mac);
    +	bwn_nrssi_slope_11g(mac);
    +	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
    +		bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
    +		bwn_switch_channel(mac, old);
    +	}
    +	bwn_mac_enable(mac);
    +}
    +
    +static void
    +bwn_phy_switch_analog(struct bwn_mac *mac, int on)
    +{
    +
    +	BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
    +}
    +
    +static int
    +bwn_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 bwn_softc *sc = ifp->if_softc;
    +	struct bwn_mac *mac = sc->sc_curmac;
    +
    +	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
    +	    mac->mac_status < BWN_MAC_STATUS_STARTED) {
    +		ieee80211_free_node(ni);
    +		m_freem(m);
    +		return (ENETDOWN);
    +	}
    +
    +	BWN_LOCK(sc);
    +	if (bwn_tx_isfull(sc, m)) {
    +		ieee80211_free_node(ni);
    +		m_freem(m);
    +		ifp->if_oerrors++;
    +		BWN_UNLOCK(sc);
    +		return (ENOBUFS);
    +	}
    +
    +	if (bwn_tx_start(sc, ni, m) != 0) {
    +		if (ni != NULL)
    +			ieee80211_free_node(ni);
    +		ifp->if_oerrors++;
    +	}
    +	sc->sc_watchdog_timer = 5;
    +	BWN_UNLOCK(sc);
    +	return (0);
    +}
    +
    +/*
    + * Setup driver-specific state for a newly associated node.
    + * Note that we're called also on a re-associate, the isnew
    + * param tells us if this is the first time or not.
    + */
    +static void
    +bwn_newassoc(struct ieee80211_node *ni, int isnew)
    +{
    +	struct ieee80211vap *vap = ni->ni_vap;
    +
    +	ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr,
    +	    &BWN_NODE(ni)->bn_amn, ni);
    +}
    +
    +/*
    + * Callback from the 802.11 layer to update the slot time
    + * based on the current setting.  We use it to notify the
    + * firmware of ERP changes and the f/w takes care of things
    + * like slot time and preamble.
    + */
    +static void
    +bwn_updateslot(struct ifnet *ifp)
    +{
    +	struct bwn_softc *sc = ifp->if_softc;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	struct bwn_mac *mac;
    +
    +	BWN_LOCK(sc);
    +	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    +		mac = (struct bwn_mac *)sc->sc_curmac;
    +		bwn_set_slot_time(mac,
    +		    (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
    +	}
    +	BWN_UNLOCK(sc);
    +}
    +
    +/*
    + * Callback from the 802.11 layer after a promiscuous mode change.
    + * Note this interface does not check the operating mode as this
    + * is an internal callback and we are expected to honor the current
    + * state (e.g. this is used for setting the interface in promiscuous
    + * mode when operating in hostap mode to do ACS).
    + */
    +static void
    +bwn_update_promisc(struct ifnet *ifp)
    +{
    +	struct bwn_softc *sc = ifp->if_softc;
    +	struct bwn_mac *mac = sc->sc_curmac;
    +
    +	BWN_LOCK(sc);
    +	mac = sc->sc_curmac;
    +	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
    +		if (ifp->if_flags & IFF_PROMISC)
    +			sc->sc_filters |= BWN_MACCTL_PROMISC;
    +		else
    +			sc->sc_filters &= ~BWN_MACCTL_PROMISC;
    +		bwn_set_opmode(mac);
    +	}
    +	BWN_UNLOCK(sc);
    +}
    +
    +/*
    + * Callback from the 802.11 layer to update WME parameters.
    + */
    +static int
    +bwn_wme_update(struct ieee80211com *ic)
    +{
    +	struct bwn_softc *sc = ic->ic_ifp->if_softc;
    +	struct bwn_mac *mac = sc->sc_curmac;
    +	struct wmeParams *wmep;
    +	int i;
    +
    +	BWN_LOCK(sc);
    +	mac = sc->sc_curmac;
    +	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
    +		bwn_mac_suspend(mac);
    +		for (i = 0; i < N(sc->sc_wmeParams); i++) {
    +			wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
    +			bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
    +		}
    +		bwn_mac_enable(mac);
    +	}
    +	BWN_UNLOCK(sc);
    +	return (0);
    +}
    +
    +static struct ieee80211_node *
    +bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
    +{
    +	struct ieee80211com *ic = vap->iv_ic;
    +	struct bwn_softc *sc = ic->ic_ifp->if_softc;
    +	const size_t space = sizeof(struct bwn_node);
    +	struct bwn_node *bn;
    +
    +	bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO);
    +	if (bn == NULL) {
    +		/* XXX stat+msg */
    +		return (NULL);
    +	}
    +	DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn);
    +	return (&bn->bn_node);
    +}
    +
    +static void
    +bwn_node_cleanup(struct ieee80211_node *ni)
    +{
    +	struct ieee80211com *ic = ni->ni_ic;
    +	struct bwn_softc *sc = ic->ic_ifp->if_softc;
    +
    +	sc->sc_node_cleanup(ni);
    +}
    +
    +static void
    +bwn_scan_start(struct ieee80211com *ic)
    +{
    +	struct ifnet *ifp = ic->ic_ifp;
    +	struct bwn_softc *sc = ifp->if_softc;
    +	struct bwn_mac *mac;
    +
    +	BWN_LOCK(sc);
    +	mac = sc->sc_curmac;
    +	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
    +		sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
    +		bwn_set_opmode(mac);
    +		/* disable CFP update during scan */
    +		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
    +	}
    +	BWN_UNLOCK(sc);
    +}
    +
    +static void
    +bwn_scan_end(struct ieee80211com *ic)
    +{
    +	struct ifnet *ifp = ic->ic_ifp;
    +	struct bwn_softc *sc = ifp->if_softc;
    +	struct bwn_mac *mac;
    +
    +	BWN_LOCK(sc);
    +	mac = sc->sc_curmac;
    +	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
    +		sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
    +		bwn_set_opmode(mac);
    +		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
    +	}
    +	BWN_UNLOCK(sc);
    +}
    +
    +static void
    +bwn_set_channel(struct ieee80211com *ic)
    +{
    +	struct ifnet *ifp = ic->ic_ifp;
    +	struct bwn_softc *sc = ifp->if_softc;
    +	struct bwn_mac *mac = sc->sc_curmac;
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	int chan, error;
    +
    +	BWN_LOCK(sc);
    +
    +	error = bwn_switch_band(sc, ic->ic_curchan);
    +	if (error)
    +		goto fail;;
    +	bwn_mac_suspend(mac);
    +	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
    +	chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
    +	if (chan != phy->chan)
    +		bwn_switch_channel(mac, chan);
    +
    +	/* TX power level */
    +	if (ic->ic_curchan->ic_maxpower != 0 &&
    +	    ic->ic_curchan->ic_maxpower != phy->txpower) {
    +		phy->txpower = ic->ic_curchan->ic_maxpower / 2;
    +		bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
    +		    BWN_TXPWR_IGNORE_TSSI);
    +	}
    +
    +	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
    +	if (phy->set_antenna)
    +		phy->set_antenna(mac, BWN_ANT_DEFAULT);
    +
    +	if (sc->sc_rf_enabled != phy->rf_on) {
    +		if (sc->sc_rf_enabled) {
    +			bwn_rf_turnon(mac);
    +			if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
    +				device_printf(sc->sc_dev,
    +				    "please turns on the RF switch\n");
    +		} else
    +			bwn_rf_turnoff(mac);
    +	}
    +
    +	bwn_mac_enable(mac);
    +
    +fail:
    +	/*
    +	 * Setup radio tap channel freq and flags
    +	 */
    +	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
    +		htole16(ic->ic_curchan->ic_freq);
    +	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
    +		htole16(ic->ic_curchan->ic_flags & 0xffff);
    +
    +	BWN_UNLOCK(sc);
    +}
    +
    +static struct ieee80211vap *
    +bwn_vap_create(struct ieee80211com *ic,
    +	const char name[IFNAMSIZ], int unit, int opmode, int flags,
    +	const uint8_t bssid[IEEE80211_ADDR_LEN],
    +	const uint8_t mac0[IEEE80211_ADDR_LEN])
    +{
    +	struct ifnet *ifp = ic->ic_ifp;
    +	struct bwn_softc *sc = ifp->if_softc;
    +	struct ieee80211vap *vap;
    +	struct bwn_vap *bvp;
    +	uint8_t mac[IEEE80211_ADDR_LEN];
    +
    +	IEEE80211_ADDR_COPY(mac, mac0);
    +	switch (opmode) {
    +	case IEEE80211_M_HOSTAP:
    +	case IEEE80211_M_MBSS:
    +	case IEEE80211_M_STA:
    +	case IEEE80211_M_WDS:
    +	case IEEE80211_M_MONITOR:
    +	case IEEE80211_M_IBSS:
    +	case IEEE80211_M_AHDEMO:
    +		break;
    +	default:
    +		return (NULL);
    +	}
    +
    +	IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
    +
    +	bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
    +	    M_80211_VAP, M_NOWAIT | M_ZERO);
    +	if (bvp == NULL) {
    +		device_printf(sc->sc_dev, "failed to allocate a buffer\n");
    +		return (NULL);
    +	}
    +	vap = &bvp->bv_vap;
    +	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
    +	IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
    +	/* override with driver methods */
    +	bvp->bv_newstate = vap->iv_newstate;
    +	vap->iv_newstate = bwn_newstate;
    +
    +	/* override max aid so sta's cannot assoc when we're out of sta id's */
    +	vap->iv_max_aid = BWN_STAID_MAX;
    +
    +	ieee80211_amrr_init(&bvp->bv_amrr, vap,
    +	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
    +	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
    +	    500 /*ms*/);
    +
    +	/* complete setup */
    +	ieee80211_vap_attach(vap, ieee80211_media_change,
    +	    ieee80211_media_status);
    +	return (vap);
    +}
    +
    +static void
    +bwn_vap_delete(struct ieee80211vap *vap)
    +{
    +	struct bwn_vap *bvp = BWN_VAP(vap);
    +
    +	ieee80211_amrr_cleanup(&bvp->bv_amrr);
    +	ieee80211_vap_detach(vap);
    +	free(bvp, M_80211_VAP);
    +}
    +
    +static void
    +bwn_init(void *arg)
    +{
    +	struct bwn_softc *sc = arg;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	int error = 0;
    +
    +	DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
    +		__func__, ifp->if_flags);
    +
    +	BWN_LOCK(sc);
    +	error = bwn_init_locked(sc);
    +	BWN_UNLOCK(sc);
    +
    +	if (error == 0)
    +		ieee80211_start_all(ic);	/* start all vap's */
    +}
    +
    +static int
    +bwn_init_locked(struct bwn_softc *sc)
    +{
    +	struct bwn_mac *mac;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	int error;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
    +	sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
    +	sc->sc_filters = 0;
    +	bwn_wme_clear(sc);
    +	sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
    +	sc->sc_rf_enabled = 1;
    +
    +	mac = sc->sc_curmac;
    +	if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
    +		error = bwn_core_init(mac);
    +		if (error != 0)
    +			return (error);
    +	}
    +	if (mac->mac_status == BWN_MAC_STATUS_INITED)
    +		bwn_core_start(mac);
    +
    +	bwn_set_opmode(mac);
    +	bwn_set_pretbtt(mac);
    +	bwn_spu_setdelay(mac, 0);
    +	bwn_set_macaddr(mac);
    +
    +	ifp->if_drv_flags |= IFF_DRV_RUNNING;
    +	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
    +	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
    +
    +	return (0);
    +}
    +
    +static void
    +bwn_stop(struct bwn_softc *sc, int statechg)
    +{
    +
    +	BWN_LOCK(sc);
    +	bwn_stop_locked(sc, statechg);
    +	BWN_UNLOCK(sc);
    +}
    +
    +static void
    +bwn_stop_locked(struct bwn_softc *sc, int statechg)
    +{
    +	struct bwn_mac *mac = sc->sc_curmac;
    +	struct ifnet *ifp = sc->sc_ifp;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
    +		/* XXX FIXME opmode not based on VAP */
    +		bwn_set_opmode(mac);
    +		bwn_set_macaddr(mac);
    +	}
    +
    +	if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
    +		bwn_core_stop(mac);
    +
    +	callout_stop(&sc->sc_led_blink_ch);
    +	sc->sc_led_blinking = 0;
    +
    +	bwn_core_exit(mac);
    +	sc->sc_rf_enabled = 0;
    +
    +	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
    +}
    +
    +static void
    +bwn_wme_clear(struct bwn_softc *sc)
    +{
    +#define	MS(_v, _f)	(((_v) & _f) >> _f##_S)
    +	struct wmeParams *p;
    +	unsigned int i;
    +
    +	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	for (i = 0; i < N(sc->sc_wmeParams); i++) {
    +		p = &(sc->sc_wmeParams[i]);
    +
    +		switch (bwn_wme_shm_offsets[i]) {
    +		case BWN_WME_VOICE:
    +			p->wmep_txopLimit = 0;
    +			p->wmep_aifsn = 2;
    +			/* XXX FIXME: log2(cwmin) */
    +			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
    +			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
    +			break;
    +		case BWN_WME_VIDEO:
    +			p->wmep_txopLimit = 0;
    +			p->wmep_aifsn = 2;
    +			/* XXX FIXME: log2(cwmin) */
    +			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
    +			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
    +			break;
    +		case BWN_WME_BESTEFFORT:
    +			p->wmep_txopLimit = 0;
    +			p->wmep_aifsn = 3;
    +			/* XXX FIXME: log2(cwmin) */
    +			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
    +			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
    +			break;
    +		case BWN_WME_BACKGROUND:
    +			p->wmep_txopLimit = 0;
    +			p->wmep_aifsn = 7;
    +			/* XXX FIXME: log2(cwmin) */
    +			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
    +			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
    +			break;
    +		default:
    +			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +		}
    +	}
    +}
    +
    +static int
    +bwn_core_init(struct bwn_mac *mac)
    +{
    +#ifdef BWN_DEBUG
    +	struct bwn_softc *sc = mac->mac_sc;
    +#endif
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct siba_sprom *sprom = &siba->siba_sprom;
    +	uint64_t hf;
    +	int error;
    +
    +	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	siba_powerup(siba, 0);
    +	if (!siba_dev_isup(sd))
    +		bwn_reset_core(mac,
    +		    mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
    +
    +	mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
    +	mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
    +	mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
    +	BWN_GETTIME(mac->mac_phy.nexttime);
    +	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
    +	bzero(&mac->mac_stats, sizeof(mac->mac_stats));
    +	mac->mac_stats.link_noise = -95;
    +	mac->mac_reason_intr = 0;
    +	bzero(mac->mac_reason, sizeof(mac->mac_reason));
    +	mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
    +#ifdef BWN_DEBUG
    +	if (sc->sc_debug & BWN_DEBUG_XMIT)
    +		mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
    +#endif
    +	mac->mac_suspended = 1;
    +	mac->mac_task_state = 0;
    +	memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
    +
    +	mac->mac_phy.init_pre(mac);
    +
    +	siba_pcicore_intr(&siba->siba_pci, sd);
    +
    +	bwn_fix_imcfglobug(mac);
    +	bwn_bt_disable(mac);
    +	if (mac->mac_phy.prepare_hw) {
    +		error = mac->mac_phy.prepare_hw(mac);
    +		if (error)
    +			goto fail0;
    +	}
    +	error = bwn_chip_init(mac);
    +	if (error)
    +		goto fail0;
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
    +	    mac->mac_sd->sd_id.sd_rev);
    +	hf = bwn_hf_read(mac);
    +	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
    +		hf |= BWN_HF_GPHY_SYM_WORKAROUND;
    +		if (sprom->bf_lo & BWN_BFL_PACTRL)
    +			hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
    +		if (mac->mac_phy.rev == 1)
    +			hf |= BWN_HF_GPHY_DC_CANCELFILTER;
    +	}
    +	if (mac->mac_phy.rf_ver == 0x2050) {
    +		if (mac->mac_phy.rf_rev < 6)
    +			hf |= BWN_HF_FORCE_VCO_RECALC;
    +		if (mac->mac_phy.rf_rev == 6)
    +			hf |= BWN_HF_4318_TSSI;
    +	}
    +	if (sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW)
    +		hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
    +	if ((siba->siba_type == SIBA_TYPE_PCI) &&
    +	    (siba->siba_pci.spc_dev->sd_id.sd_rev <= 10))
    +		hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
    +	hf &= ~BWN_HF_SKIP_CFP_UPDATE;
    +	bwn_hf_write(mac, hf);
    +
    +	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
    +
    +	bwn_rate_init(mac);
    +	bwn_set_phytxctl(mac);
    +
    +	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
    +	    (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
    +	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
    +
    +	if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
    +		bwn_pio_init(mac);
    +	else
    +		bwn_dma_init(mac);
    +	if (error)
    +		goto fail1;
    +	bwn_wme_init(mac);
    +	bwn_spu_setdelay(mac, 1);
    +	bwn_bt_enable(mac);
    +
    +	siba_powerup(siba, !(sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW));
    +	bwn_set_macaddr(mac);
    +	bwn_crypt_init(mac);
    +
    +	/* XXX LED initializatin */
    +
    +	mac->mac_status = BWN_MAC_STATUS_INITED;
    +
    +	return (error);
    +
    +fail1:
    +	bwn_chip_exit(mac);
    +fail0:
    +	siba_powerdown(siba);
    +	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	return (error);
    +}
    +
    +static void
    +bwn_core_start(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint32_t tmp;
    +
    +	KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	if (mac->mac_sd->sd_id.sd_rev < 5)
    +		return;
    +
    +	while (1) {
    +		tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
    +		if (!(tmp & 0x00000001))
    +			break;
    +		tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
    +	}
    +
    +	bwn_mac_enable(mac);
    +	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
    +	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
    +
    +	mac->mac_status = BWN_MAC_STATUS_STARTED;
    +}
    +
    +static void
    +bwn_core_exit(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint32_t macctl;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	if (mac->mac_status != BWN_MAC_STATUS_INITED)
    +		return;
    +	mac->mac_status = BWN_MAC_STATUS_UNINIT;
    +
    +	macctl = BWN_READ_4(mac, BWN_MACCTL);
    +	macctl &= ~BWN_MACCTL_MCODE_RUN;
    +	macctl |= BWN_MACCTL_MCODE_JMP0;
    +	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
    +
    +	bwn_dma_stop(mac);
    +	bwn_pio_stop(mac);
    +	bwn_chip_exit(mac);
    +	mac->mac_phy.switch_analog(mac, 0);
    +	siba_dev_down(mac->mac_sd, 0);
    +	siba_powerdown(mac->mac_sd->sd_bus);
    +}
    +
    +static void
    +bwn_fix_imcfglobug(struct bwn_mac *mac)
    +{
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	uint32_t tmp;
    +
    +	if (siba->siba_pci.spc_dev == NULL)
    +		return;
    +	if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI ||
    +	    siba->siba_pci.spc_dev->sd_id.sd_rev > 5)
    +		return;
    +
    +	tmp = siba_read_4(sd, SIBA_IMCFGLO) &
    +	    ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO);
    +	switch (siba->siba_type) {
    +	case SIBA_TYPE_PCI:
    +	case SIBA_TYPE_PCMCIA:
    +		tmp |= 0x32;
    +		break;
    +	case SIBA_TYPE_SSB:
    +		tmp |= 0x53;
    +		break;
    +	}
    +	siba_write_4(sd, SIBA_IMCFGLO, tmp);
    +}
    +
    +static void
    +bwn_bt_disable(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +
    +	(void)sc;
    +	/* XXX do nothing yet */
    +}
    +
    +static int
    +bwn_chip_init(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	uint32_t macctl;
    +	int error;
    +
    +	macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
    +	if (phy->gmode)
    +		macctl |= BWN_MACCTL_GMODE;
    +	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
    +
    +	error = bwn_fw_fillinfo(mac);
    +	if (error)
    +		return (error);
    +	error = bwn_fw_loaducode(mac);
    +	if (error)
    +		return (error);
    +
    +	error = bwn_gpio_init(mac);
    +	if (error)
    +		return (error);
    +
    +	error = bwn_fw_loadinitvals(mac);
    +	if (error) {
    +		bwn_gpio_cleanup(mac);
    +		return (error);
    +	}
    +	phy->switch_analog(mac, 1);
    +	error = bwn_phy_init(mac);
    +	if (error) {
    +		bwn_gpio_cleanup(mac);
    +		return (error);
    +	}
    +	if (phy->set_im)
    +		phy->set_im(mac, BWN_IMMODE_NONE);
    +	if (phy->set_antenna)
    +		phy->set_antenna(mac, BWN_ANT_DEFAULT);
    +	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
    +
    +	if (phy->type == BWN_PHYTYPE_B)
    +		BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
    +	BWN_WRITE_4(mac, 0x0100, 0x01000000);
    +	if (mac->mac_sd->sd_id.sd_rev < 5)
    +		BWN_WRITE_4(mac, 0x010c, 0x01000000);
    +
    +	BWN_WRITE_4(mac, BWN_MACCTL,
    +	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
    +	BWN_WRITE_4(mac, BWN_MACCTL,
    +	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
    +	bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
    +
    +	bwn_set_opmode(mac);
    +	if (mac->mac_sd->sd_id.sd_rev < 3) {
    +		BWN_WRITE_2(mac, 0x060e, 0x0000);
    +		BWN_WRITE_2(mac, 0x0610, 0x8000);
    +		BWN_WRITE_2(mac, 0x0604, 0x0000);
    +		BWN_WRITE_2(mac, 0x0606, 0x0200);
    +	} else {
    +		BWN_WRITE_4(mac, 0x0188, 0x80000000);
    +		BWN_WRITE_4(mac, 0x018c, 0x02000000);
    +	}
    +	BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
    +	BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
    +	BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
    +	BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
    +	BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
    +	BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
    +	BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
    +	siba_write_4(mac->mac_sd, SIBA_TGSLOW,
    +	    siba_read_4(mac->mac_sd, SIBA_TGSLOW) | 0x00100000);
    +	BWN_WRITE_2(mac, BWN_POWERUP_DELAY,
    +	    mac->mac_sd->sd_bus->siba_cc.scc_powerup_delay);
    +	return (error);
    +}
    +
    +/* read hostflags */
    +static uint64_t
    +bwn_hf_read(struct bwn_mac *mac)
    +{
    +	uint64_t ret;
    +
    +	ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
    +	ret <<= 16;
    +	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
    +	ret <<= 16;
    +	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
    +	return (ret);
    +}
    +
    +static void
    +bwn_hf_write(struct bwn_mac *mac, uint64_t value)
    +{
    +
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
    +	    (value & 0x00000000ffffull));
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
    +	    (value & 0x0000ffff0000ull) >> 16);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
    +	    (value & 0xffff00000000ULL) >> 32);
    +}
    +
    +static void
    +bwn_set_txretry(struct bwn_mac *mac, int s, int l)
    +{
    +
    +	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
    +	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
    +}
    +
    +static void
    +bwn_rate_init(struct bwn_mac *mac)
    +{
    +
    +	switch (mac->mac_phy.type) {
    +	case BWN_PHYTYPE_A:
    +	case BWN_PHYTYPE_G:
    +	case BWN_PHYTYPE_LP:
    +	case BWN_PHYTYPE_N:
    +		bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
    +		bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
    +		bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
    +		bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
    +		bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
    +		bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
    +		bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
    +		if (mac->mac_phy.type == BWN_PHYTYPE_A)
    +			break;
    +		/* FALLTHROUGH */
    +	case BWN_PHYTYPE_B:
    +		bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
    +		bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
    +		bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
    +		bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
    +		break;
    +	default:
    +		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	}
    +}
    +
    +static void
    +bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
    +{
    +	uint16_t offset;
    +
    +	if (ofdm) {
    +		offset = 0x480;
    +		offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
    +	} else {
    +		offset = 0x4c0;
    +		offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
    +	}
    +	bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
    +	    bwn_shm_read_2(mac, BWN_SHARED, offset));
    +}
    +
    +static uint8_t
    +bwn_plcp_getcck(const uint8_t bitrate)
    +{
    +
    +	switch (bitrate) {
    +	case BWN_CCK_RATE_1MB:
    +		return (0x0a);
    +	case BWN_CCK_RATE_2MB:
    +		return (0x14);
    +	case BWN_CCK_RATE_5MB:
    +		return (0x37);
    +	case BWN_CCK_RATE_11MB:
    +		return (0x6e);
    +	}
    +	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	return (0);
    +}
    +
    +static uint8_t
    +bwn_plcp_getofdm(const uint8_t bitrate)
    +{
    +
    +	switch (bitrate) {
    +	case BWN_OFDM_RATE_6MB:
    +		return (0xb);
    +	case BWN_OFDM_RATE_9MB:
    +		return (0xf);
    +	case BWN_OFDM_RATE_12MB:
    +		return (0xa);
    +	case BWN_OFDM_RATE_18MB:
    +		return (0xe);
    +	case BWN_OFDM_RATE_24MB:
    +		return (0x9);
    +	case BWN_OFDM_RATE_36MB:
    +		return (0xd);
    +	case BWN_OFDM_RATE_48MB:
    +		return (0x8);
    +	case BWN_OFDM_RATE_54MB:
    +		return (0xc);
    +	}
    +	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	return (0);
    +}
    +
    +static void
    +bwn_set_phytxctl(struct bwn_mac *mac)
    +{
    +	uint16_t ctl;
    +
    +	ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
    +	    BWN_TX_PHY_TXPWR);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
    +}
    +
    +static void
    +bwn_pio_init(struct bwn_mac *mac)
    +{
    +	struct bwn_pio *pio = &mac->mac_method.pio;
    +
    +	BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
    +	    & ~BWN_MACCTL_BIGENDIAN);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
    +
    +	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
    +	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
    +	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
    +	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
    +	bwn_pio_set_txqueue(mac, &pio->mcast, 4);
    +	bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
    +}
    +
    +static void
    +bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
    +    int index)
    +{
    +	struct bwn_pio_txpkt *tp;
    +	unsigned int i;
    +
    +	tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
    +	tq->tq_index = index;
    +
    +	tq->tq_free = BWN_PIO_MAX_TXPACKETS;
    +	if (mac->mac_sd->sd_id.sd_rev >= 8)
    +		tq->tq_size = 1920;
    +	else {
    +		tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
    +		tq->tq_size -= 80;
    +	}
    +
    +	TAILQ_INIT(&tq->tq_pktlist);
    +	for (i = 0; i < N(tq->tq_pkts); i++) {
    +		tp = &(tq->tq_pkts[i]);
    +		tp->tp_index = i;
    +		tp->tp_queue = tq;
    +		TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
    +	}
    +}
    +
    +static uint16_t
    +bwn_pio_idx2base(struct bwn_mac *mac, int index)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	static const uint16_t bases[] = {
    +		BWN_PIO_BASE0,
    +		BWN_PIO_BASE1,
    +		BWN_PIO_BASE2,
    +		BWN_PIO_BASE3,
    +		BWN_PIO_BASE4,
    +		BWN_PIO_BASE5,
    +		BWN_PIO_BASE6,
    +		BWN_PIO_BASE7,
    +	};
    +	static const uint16_t bases_rev11[] = {
    +		BWN_PIO11_BASE0,
    +		BWN_PIO11_BASE1,
    +		BWN_PIO11_BASE2,
    +		BWN_PIO11_BASE3,
    +		BWN_PIO11_BASE4,
    +		BWN_PIO11_BASE5,
    +	};
    +
    +	if (mac->mac_sd->sd_id.sd_rev >= 11) {
    +		if (index >= N(bases_rev11))
    +			device_printf(sc->sc_dev, "%s: warning\n", __func__);
    +		return (bases_rev11[index]);
    +	}
    +	if (index >= N(bases))
    +		device_printf(sc->sc_dev, "%s: warning\n", __func__);
    +	return (bases[index]);
    +}
    +
    +static void
    +bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
    +    int index)
    +{
    +
    +	prq->prq_mac = mac;
    +	prq->prq_rev = mac->mac_sd->sd_id.sd_rev;
    +	prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
    +	bwn_dma_rxdirectfifo(mac, index, 1);
    +}
    +
    +static void
    +bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
    +{
    +	if (tq == NULL)
    +		return;
    +	bwn_pio_cancel_tx_packets(tq);
    +}
    +
    +static void
    +bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
    +{
    +
    +	bwn_destroy_pioqueue_tx(pio);
    +}
    +
    +static uint16_t
    +bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
    +    uint16_t offset)
    +{
    +
    +	return (BWN_READ_2(mac, tq->tq_base + offset));
    +}
    +
    +static void
    +bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
    +{
    +	uint32_t ctl;
    +	int type;
    +	uint16_t base;
    +
    +	type = bwn_dma_mask2type(bwn_dma_mask(mac));
    +	base = bwn_dma_base(type, idx);
    +	if (type == BWN_DMA_64BIT) {
    +		ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
    +		ctl &= ~BWN_DMA64_RXDIRECTFIFO;
    +		if (enable)
    +			ctl |= BWN_DMA64_RXDIRECTFIFO;
    +		BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
    +	} else {
    +		ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
    +		ctl &= ~BWN_DMA32_RXDIRECTFIFO;
    +		if (enable)
    +			ctl |= BWN_DMA32_RXDIRECTFIFO;
    +		BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
    +	}
    +}
    +
    +static uint64_t
    +bwn_dma_mask(struct bwn_mac *mac)
    +{
    +	uint32_t tmp;
    +	uint16_t base;
    +
    +	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
    +	if (tmp & SIBA_TGSHIGH_DMA64)
    +		return (BWN_DMA_BIT_MASK(64));
    +	base = bwn_dma_base(0, 0);
    +	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
    +	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
    +	if (tmp & BWN_DMA32_TXADDREXT_MASK)
    +		return (BWN_DMA_BIT_MASK(32));
    +
    +	return (BWN_DMA_BIT_MASK(30));
    +}
    +
    +static int
    +bwn_dma_mask2type(uint64_t dmamask)
    +{
    +
    +	if (dmamask == BWN_DMA_BIT_MASK(30))
    +		return (BWN_DMA_30BIT);
    +	if (dmamask == BWN_DMA_BIT_MASK(32))
    +		return (BWN_DMA_32BIT);
    +	if (dmamask == BWN_DMA_BIT_MASK(64))
    +		return (BWN_DMA_64BIT);
    +	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	return (BWN_DMA_30BIT);
    +}
    +
    +static void
    +bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
    +{
    +	struct bwn_pio_txpkt *tp;
    +	unsigned int i;
    +
    +	for (i = 0; i < N(tq->tq_pkts); i++) {
    +		tp = &(tq->tq_pkts[i]);
    +		if (tp->tp_m) {
    +			m_freem(tp->tp_m);
    +			tp->tp_m = NULL;
    +		}
    +	}
    +}
    +
    +static uint16_t
    +bwn_dma_base(int type, int controller_idx)
    +{
    +	static const uint16_t map64[] = {
    +		BWN_DMA64_BASE0,
    +		BWN_DMA64_BASE1,
    +		BWN_DMA64_BASE2,
    +		BWN_DMA64_BASE3,
    +		BWN_DMA64_BASE4,
    +		BWN_DMA64_BASE5,
    +	};
    +	static const uint16_t map32[] = {
    +		BWN_DMA32_BASE0,
    +		BWN_DMA32_BASE1,
    +		BWN_DMA32_BASE2,
    +		BWN_DMA32_BASE3,
    +		BWN_DMA32_BASE4,
    +		BWN_DMA32_BASE5,
    +	};
    +
    +	if (type == BWN_DMA_64BIT) {
    +		KASSERT(controller_idx >= 0 && controller_idx < N(map64),
    +		    ("%s:%d: fail", __func__, __LINE__));
    +		return (map64[controller_idx]);
    +	}
    +	KASSERT(controller_idx >= 0 && controller_idx < N(map32),
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	return (map32[controller_idx]);
    +}
    +
    +static void
    +bwn_dma_init(struct bwn_mac *mac)
    +{
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +
    +	/* setup TX DMA channels. */
    +	bwn_dma_setup(dma->wme[WME_AC_BK]);
    +	bwn_dma_setup(dma->wme[WME_AC_BE]);
    +	bwn_dma_setup(dma->wme[WME_AC_VI]);
    +	bwn_dma_setup(dma->wme[WME_AC_VO]);
    +	bwn_dma_setup(dma->mcast);
    +	/* setup RX DMA channel. */
    +	bwn_dma_setup(dma->rx);
    +}
    +
    +static struct bwn_dma_ring *
    +bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
    +    int for_tx, int type)
    +{
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +	struct bwn_dma_ring *dr;
    +	struct bwn_dmadesc_generic *desc;
    +	struct bwn_dmadesc_meta *mt;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	int error, i;
    +
    +	dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
    +	if (dr == NULL)
    +		goto out;
    +	dr->dr_numslots = BWN_RXRING_SLOTS;
    +	if (for_tx)
    +		dr->dr_numslots = BWN_TXRING_SLOTS;
    +
    +	dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
    +	    M_DEVBUF, M_NOWAIT | M_ZERO);
    +	if (dr->dr_meta == NULL)
    +		goto fail0;
    +
    +	dr->dr_type = type;
    +	dr->dr_mac = mac;
    +	dr->dr_base = bwn_dma_base(type, controller_index);
    +	dr->dr_index = controller_index;
    +	if (type == BWN_DMA_64BIT) {
    +		dr->getdesc = bwn_dma_64_getdesc;
    +		dr->setdesc = bwn_dma_64_setdesc;
    +		dr->start_transfer = bwn_dma_64_start_transfer;
    +		dr->suspend = bwn_dma_64_suspend;
    +		dr->resume = bwn_dma_64_resume;
    +		dr->get_curslot = bwn_dma_64_get_curslot;
    +		dr->set_curslot = bwn_dma_64_set_curslot;
    +	} else {
    +		dr->getdesc = bwn_dma_32_getdesc;
    +		dr->setdesc = bwn_dma_32_setdesc;
    +		dr->start_transfer = bwn_dma_32_start_transfer;
    +		dr->suspend = bwn_dma_32_suspend;
    +		dr->resume = bwn_dma_32_resume;
    +		dr->get_curslot = bwn_dma_32_get_curslot;
    +		dr->set_curslot = bwn_dma_32_set_curslot;
    +	}
    +	if (for_tx) {
    +		dr->dr_tx = 1;
    +		dr->dr_curslot = -1;
    +	} else {
    +		if (dr->dr_index == 0) {
    +			dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
    +			dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
    +		} else
    +			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	}
    +
    +	error = bwn_dma_allocringmemory(dr);
    +	if (error)
    +		goto fail2;
    +
    +	if (for_tx) {
    +		/*
    +		 * Assumption: BWN_TXRING_SLOTS can be divided by
    +		 * BWN_TX_SLOTS_PER_FRAME
    +		 */
    +		KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
    +		    ("%s:%d: fail", __func__, __LINE__));
    +
    +		dr->dr_txhdr_cache =
    +		    malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
    +			BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
    +		KASSERT(dr->dr_txhdr_cache != NULL,
    +		    ("%s:%d: fail", __func__, __LINE__));
    +
    +		/*
    +		 * Create TX ring DMA stuffs
    +		 */
    +		error = bus_dma_tag_create(dma->parent_dtag,
    +				    BWN_ALIGN, 0,
    +				    BUS_SPACE_MAXADDR,
    +				    BUS_SPACE_MAXADDR,
    +				    NULL, NULL,
    +				    BWN_HDRSIZE(mac),
    +				    1,
    +				    BUS_SPACE_MAXSIZE_32BIT,
    +				    0,
    +				    NULL, NULL,
    +				    &dr->dr_txring_dtag);
    +		if (error) {
    +			device_printf(sc->sc_dev,
    +			    "can't create TX ring DMA tag: TODO frees\n");
    +			goto fail1;
    +		}
    +
    +		for (i = 0; i < dr->dr_numslots; i += 2) {
    +			dr->getdesc(dr, i, &desc, &mt);
    +
    +			mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
    +			mt->mt_m = NULL;
    +			mt->mt_ni = NULL;
    +			mt->mt_islast = 0;
    +			error = bus_dmamap_create(dr->dr_txring_dtag, 0,
    +			    &mt->mt_dmap);
    +			if (error) {
    +				device_printf(sc->sc_dev,
    +				     "can't create RX buf DMA map\n");
    +				goto fail1;
    +			}
    +
    +			dr->getdesc(dr, i + 1, &desc, &mt);
    +
    +			mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
    +			mt->mt_m = NULL;
    +			mt->mt_ni = NULL;
    +			mt->mt_islast = 1;
    +			error = bus_dmamap_create(dma->txbuf_dtag, 0,
    +			    &mt->mt_dmap);
    +			if (error) {
    +				device_printf(sc->sc_dev,
    +				     "can't create RX buf DMA map\n");
    +				goto fail1;
    +			}
    +		}
    +	} else {
    +		error = bus_dmamap_create(dma->rxbuf_dtag, 0,
    +		    &dr->dr_spare_dmap);
    +		if (error) {
    +			device_printf(sc->sc_dev,
    +			    "can't create RX buf DMA map\n");
    +			goto out;		/* XXX wrong! */
    +		}
    +
    +		for (i = 0; i < dr->dr_numslots; i++) {
    +			dr->getdesc(dr, i, &desc, &mt);
    +
    +			error = bus_dmamap_create(dma->rxbuf_dtag, 0,
    +			    &mt->mt_dmap);
    +			if (error) {
    +				device_printf(sc->sc_dev,
    +				    "can't create RX buf DMA map\n");
    +				goto out;	/* XXX wrong! */
    +			}
    +			error = bwn_dma_newbuf(dr, desc, mt, 1);
    +			if (error) {
    +				device_printf(sc->sc_dev,
    +				    "failed to allocate RX buf\n");
    +				goto out;	/* XXX wrong! */
    +			}
    +		}
    +
    +		bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
    +		    BUS_DMASYNC_PREWRITE);
    +
    +		dr->dr_usedslot = dr->dr_numslots;
    +	}
    +
    +      out:
    +	return (dr);
    +
    +fail2:
    +	free(dr->dr_txhdr_cache, M_DEVBUF);
    +fail1:
    +	free(dr->dr_meta, M_DEVBUF);
    +fail0:
    +	free(dr, M_DEVBUF);
    +	return (NULL);
    +}
    +
    +static void
    +bwn_dma_ringfree(struct bwn_dma_ring **dr)
    +{
    +
    +	if (dr == NULL)
    +		return;
    +
    +	bwn_dma_free_descbufs(*dr);
    +	bwn_dma_free_ringmemory(*dr);
    +
    +	free((*dr)->dr_txhdr_cache, M_DEVBUF);
    +	free((*dr)->dr_meta, M_DEVBUF);
    +	free(*dr, M_DEVBUF);
    +
    +	*dr = NULL;
    +}
    +
    +static void
    +bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
    +    struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
    +{
    +	struct bwn_dmadesc32 *desc;
    +
    +	*meta = &(dr->dr_meta[slot]);
    +	desc = dr->dr_ring_descbase;
    +	desc = &(desc[slot]);
    +
    +	*gdesc = (struct bwn_dmadesc_generic *)desc;
    +}
    +
    +static void
    +bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
    +    struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
    +    int start, int end, int irq)
    +{
    +	struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
    +	uint32_t addr, addrext, ctl;
    +	int slot;
    +
    +	slot = (int)(&(desc->dma.dma32) - descbase);
    +	KASSERT(slot >= 0 && slot < dr->dr_numslots,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
    +	addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
    +	addr |= siba_dma_translation(dr->dr_mac->mac_sd);
    +	ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
    +	if (slot == dr->dr_numslots - 1)
    +		ctl |= BWN_DMA32_DCTL_DTABLEEND;
    +	if (start)
    +		ctl |= BWN_DMA32_DCTL_FRAMESTART;
    +	if (end)
    +		ctl |= BWN_DMA32_DCTL_FRAMEEND;
    +	if (irq)
    +		ctl |= BWN_DMA32_DCTL_IRQ;
    +	ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
    +	    & BWN_DMA32_DCTL_ADDREXT_MASK;
    +
    +	desc->dma.dma32.control = htole32(ctl);
    +	desc->dma.dma32.address = htole32(addr);
    +}
    +
    +static void
    +bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
    +{
    +
    +	BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
    +	    (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
    +}
    +
    +static void
    +bwn_dma_32_suspend(struct bwn_dma_ring *dr)
    +{
    +
    +	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
    +	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
    +}
    +
    +static void
    +bwn_dma_32_resume(struct bwn_dma_ring *dr)
    +{
    +
    +	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
    +	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
    +}
    +
    +static int
    +bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
    +{
    +	uint32_t val;
    +
    +	val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
    +	val &= BWN_DMA32_RXDPTR;
    +
    +	return (val / sizeof(struct bwn_dmadesc32));
    +}
    +
    +static void
    +bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
    +{
    +
    +	BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
    +	    (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
    +}
    +
    +static void
    +bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
    +    struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
    +{
    +	struct bwn_dmadesc64 *desc;
    +
    +	*meta = &(dr->dr_meta[slot]);
    +	desc = dr->dr_ring_descbase;
    +	desc = &(desc[slot]);
    +
    +	*gdesc = (struct bwn_dmadesc_generic *)desc;
    +}
    +
    +static void
    +bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
    +    struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
    +    int start, int end, int irq)
    +{
    +	struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
    +	int slot;
    +	uint32_t ctl0 = 0, ctl1 = 0;
    +	uint32_t addrlo, addrhi;
    +	uint32_t addrext;
    +
    +	slot = (int)(&(desc->dma.dma64) - descbase);
    +	KASSERT(slot >= 0 && slot < dr->dr_numslots,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	addrlo = (uint32_t) (dmaaddr & 0xffffffff);
    +	addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
    +	addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
    +	    30;
    +	addrhi |= (siba_dma_translation(dr->dr_mac->mac_sd) << 1);
    +	if (slot == dr->dr_numslots - 1)
    +		ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
    +	if (start)
    +		ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
    +	if (end)
    +		ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
    +	if (irq)
    +		ctl0 |= BWN_DMA64_DCTL0_IRQ;
    +	ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
    +	ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
    +	    & BWN_DMA64_DCTL1_ADDREXT_MASK;
    +
    +	desc->dma.dma64.control0 = htole32(ctl0);
    +	desc->dma.dma64.control1 = htole32(ctl1);
    +	desc->dma.dma64.address_low = htole32(addrlo);
    +	desc->dma.dma64.address_high = htole32(addrhi);
    +}
    +
    +static void
    +bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
    +{
    +
    +	BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
    +	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
    +}
    +
    +static void
    +bwn_dma_64_suspend(struct bwn_dma_ring *dr)
    +{
    +
    +	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
    +	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
    +}
    +
    +static void
    +bwn_dma_64_resume(struct bwn_dma_ring *dr)
    +{
    +
    +	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
    +	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
    +}
    +
    +static int
    +bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
    +{
    +	uint32_t val;
    +
    +	val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
    +	val &= BWN_DMA64_RXSTATDPTR;
    +
    +	return (val / sizeof(struct bwn_dmadesc64));
    +}
    +
    +static void
    +bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
    +{
    +
    +	BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
    +	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
    +}
    +
    +static int
    +bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
    +{
    +	struct bwn_mac *mac = dr->dr_mac;
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	int error;
    +
    +	error = bus_dma_tag_create(dma->parent_dtag,
    +			    BWN_ALIGN, 0,
    +			    BUS_SPACE_MAXADDR,
    +			    BUS_SPACE_MAXADDR,
    +			    NULL, NULL,
    +			    BWN_DMA_RINGMEMSIZE,
    +			    1,
    +			    BUS_SPACE_MAXSIZE_32BIT,
    +			    0,
    +			    NULL, NULL,
    +			    &dr->dr_ring_dtag);
    +	if (error) {
    +		device_printf(sc->sc_dev,
    +		    "can't create TX ring DMA tag: TODO frees\n");
    +		return (-1);
    +	}
    +
    +	error = bus_dmamem_alloc(dr->dr_ring_dtag,
    +	    &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
    +	    &dr->dr_ring_dmap);
    +	if (error) {
    +		device_printf(sc->sc_dev,
    +		    "can't allocate DMA mem: TODO frees\n");
    +		return (-1);
    +	}
    +	error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
    +	    dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
    +	    bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
    +	if (error) {
    +		device_printf(sc->sc_dev,
    +		    "can't load DMA mem: TODO free\n");
    +		return (-1);
    +	}
    +
    +	return (0);
    +}
    +
    +static void
    +bwn_dma_setup(struct bwn_dma_ring *dr)
    +{
    +	uint64_t ring64;
    +	uint32_t addrext, ring32, value;
    +	uint32_t trans = siba_dma_translation(dr->dr_mac->mac_sd);
    +
    +	if (dr->dr_tx) {
    +		dr->dr_curslot = -1;
    +
    +		if (dr->dr_type == BWN_DMA_64BIT) {
    +			ring64 = (uint64_t)(dr->dr_ring_dmabase);
    +			addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
    +			    >> 30;
    +			value = BWN_DMA64_TXENABLE;
    +			value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
    +			    & BWN_DMA64_TXADDREXT_MASK;
    +			BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
    +			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
    +			    (ring64 & 0xffffffff));
    +			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
    +			    ((ring64 >> 32) &
    +			    ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
    +		} else {
    +			ring32 = (uint32_t)(dr->dr_ring_dmabase);
    +			addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
    +			value = BWN_DMA32_TXENABLE;
    +			value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
    +			    & BWN_DMA32_TXADDREXT_MASK;
    +			BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
    +			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
    +			    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
    +		}
    +		return;
    +	}
    +
    +	/*
    +	 * set for RX
    +	 */
    +	dr->dr_usedslot = dr->dr_numslots;
    +
    +	if (dr->dr_type == BWN_DMA_64BIT) {
    +		ring64 = (uint64_t)(dr->dr_ring_dmabase);
    +		addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
    +		value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
    +		value |= BWN_DMA64_RXENABLE;
    +		value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
    +		    & BWN_DMA64_RXADDREXT_MASK;
    +		BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
    +		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
    +		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
    +		    ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
    +		    | (trans << 1));
    +		BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
    +		    sizeof(struct bwn_dmadesc64));
    +	} else {
    +		ring32 = (uint32_t)(dr->dr_ring_dmabase);
    +		addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
    +		value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
    +		value |= BWN_DMA32_RXENABLE;
    +		value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
    +		    & BWN_DMA32_RXADDREXT_MASK;
    +		BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
    +		BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
    +		    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
    +		BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
    +		    sizeof(struct bwn_dmadesc32));
    +	}
    +}
    +
    +static void
    +bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
    +{
    +
    +	bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
    +	bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
    +	    dr->dr_ring_dmap);
    +}
    +
    +static void
    +bwn_dma_cleanup(struct bwn_dma_ring *dr)
    +{
    +
    +	if (dr->dr_tx) {
    +		bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
    +		if (dr->dr_type == BWN_DMA_64BIT) {
    +			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
    +			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
    +		} else
    +			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
    +	} else {
    +		bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
    +		if (dr->dr_type == BWN_DMA_64BIT) {
    +			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
    +			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
    +		} else
    +			BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
    +	}
    +}
    +
    +static void
    +bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
    +{
    +	struct bwn_dmadesc_generic *desc;
    +	struct bwn_dmadesc_meta *meta;
    +	struct bwn_mac *mac = dr->dr_mac;
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	int i;
    +
    +	if (!dr->dr_usedslot)
    +		return;
    +	for (i = 0; i < dr->dr_numslots; i++) {
    +		dr->getdesc(dr, i, &desc, &meta);
    +
    +		if (meta->mt_m == NULL) {
    +			if (!dr->dr_tx)
    +				device_printf(sc->sc_dev, "%s: not TX?\n",
    +				    __func__);
    +			continue;
    +		}
    +		if (dr->dr_tx) {
    +			if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
    +				bus_dmamap_unload(dr->dr_txring_dtag,
    +				    meta->mt_dmap);
    +			else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
    +				bus_dmamap_unload(dma->txbuf_dtag,
    +				    meta->mt_dmap);
    +		} else
    +			bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
    +		bwn_dma_free_descbuf(dr, meta);
    +	}
    +}
    +
    +static int
    +bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
    +    int type)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint32_t value;
    +	int i;
    +	uint16_t offset;
    +
    +	for (i = 0; i < 10; i++) {
    +		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
    +		    BWN_DMA32_TXSTATUS;
    +		value = BWN_READ_4(mac, base + offset);
    +		if (type == BWN_DMA_64BIT) {
    +			value &= BWN_DMA64_TXSTAT;
    +			if (value == BWN_DMA64_TXSTAT_DISABLED ||
    +			    value == BWN_DMA64_TXSTAT_IDLEWAIT ||
    +			    value == BWN_DMA64_TXSTAT_STOPPED)
    +				break;
    +		} else {
    +			value &= BWN_DMA32_TXSTATE;
    +			if (value == BWN_DMA32_TXSTAT_DISABLED ||
    +			    value == BWN_DMA32_TXSTAT_IDLEWAIT ||
    +			    value == BWN_DMA32_TXSTAT_STOPPED)
    +				break;
    +		}
    +		DELAY(1000);
    +	}
    +	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
    +	BWN_WRITE_4(mac, base + offset, 0);
    +	for (i = 0; i < 10; i++) {
    +		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
    +						   BWN_DMA32_TXSTATUS;
    +		value = BWN_READ_4(mac, base + offset);
    +		if (type == BWN_DMA_64BIT) {
    +			value &= BWN_DMA64_TXSTAT;
    +			if (value == BWN_DMA64_TXSTAT_DISABLED) {
    +				i = -1;
    +				break;
    +			}
    +		} else {
    +			value &= BWN_DMA32_TXSTATE;
    +			if (value == BWN_DMA32_TXSTAT_DISABLED) {
    +				i = -1;
    +				break;
    +			}
    +		}
    +		DELAY(1000);
    +	}
    +	if (i != -1) {
    +		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
    +		return (ENODEV);
    +	}
    +	DELAY(1000);
    +
    +	return (0);
    +}
    +
    +static int
    +bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
    +    int type)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint32_t value;
    +	int i;
    +	uint16_t offset;
    +
    +	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
    +	BWN_WRITE_4(mac, base + offset, 0);
    +	for (i = 0; i < 10; i++) {
    +		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
    +		    BWN_DMA32_RXSTATUS;
    +		value = BWN_READ_4(mac, base + offset);
    +		if (type == BWN_DMA_64BIT) {
    +			value &= BWN_DMA64_RXSTAT;
    +			if (value == BWN_DMA64_RXSTAT_DISABLED) {
    +				i = -1;
    +				break;
    +			}
    +		} else {
    +			value &= BWN_DMA32_RXSTATE;
    +			if (value == BWN_DMA32_RXSTAT_DISABLED) {
    +				i = -1;
    +				break;
    +			}
    +		}
    +		DELAY(1000);
    +	}
    +	if (i != -1) {
    +		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
    +		return (ENODEV);
    +	}
    +
    +	return (0);
    +}
    +
    +static void
    +bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
    +    struct bwn_dmadesc_meta *meta)
    +{
    +
    +	if (meta->mt_m != NULL) {
    +		m_freem(meta->mt_m);
    +		meta->mt_m = NULL;
    +	}
    +	if (meta->mt_ni != NULL) {
    +		ieee80211_free_node(meta->mt_ni);
    +		meta->mt_ni = NULL;
    +	}
    +}
    +
    +static void
    +bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
    +{
    +	struct bwn_rxhdr4 *rxhdr;
    +	unsigned char *frame;
    +
    +	rxhdr = mtod(m, struct bwn_rxhdr4 *);
    +	rxhdr->frame_len = 0;
    +
    +	KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
    +	    sizeof(struct bwn_plcp6) + 2,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	frame = mtod(m, char *) + dr->dr_frameoffset;
    +	memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
    +}
    +
    +static uint8_t
    +bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
    +{
    +	unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
    +
    +	return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
    +	    == 0xff);
    +}
    +
    +static void
    +bwn_wme_init(struct bwn_mac *mac)
    +{
    +
    +	bwn_wme_load(mac);
    +
    +	/* enable WME support. */
    +	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
    +	BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
    +	    BWN_IFSCTL_USE_EDCF);
    +}
    +
    +static void
    +bwn_spu_setdelay(struct bwn_mac *mac, int idle)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	uint16_t delay;	/* microsec */
    +
    +	delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
    +	if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
    +		delay = 500;
    +	if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
    +		delay = max(delay, (uint16_t)2400);
    +
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
    +}
    +
    +static void
    +bwn_bt_enable(struct bwn_mac *mac)
    +{
    +	struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom;
    +	uint64_t hf;
    +
    +	if (bwn_bluetooth == 0)
    +		return;
    +	if ((sprom->bf_lo & BWN_BFL_BTCOEXIST) == 0)
    +		return;
    +	if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
    +		return;
    +
    +	hf = bwn_hf_read(mac);
    +	if (sprom->bf_lo & BWN_BFL_BTCMOD)
    +		hf |= BWN_HF_BT_COEXISTALT;
    +	else
    +		hf |= BWN_HF_BT_COEXIST;
    +	bwn_hf_write(mac, hf);
    +}
    +
    +static void
    +bwn_set_macaddr(struct bwn_mac *mac)
    +{
    +
    +	bwn_mac_write_bssid(mac);
    +	bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
    +}
    +
    +static void
    +bwn_clear_keys(struct bwn_mac *mac)
    +{
    +	int i;
    +
    +	for (i = 0; i < mac->mac_max_nr_keys; i++) {
    +		KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
    +		    ("%s:%d: fail", __func__, __LINE__));
    +
    +		bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
    +		    NULL, BWN_SEC_KEYSIZE, NULL);
    +		if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
    +			bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
    +			    NULL, BWN_SEC_KEYSIZE, NULL);
    +		}
    +		mac->mac_key[i].keyconf = NULL;
    +	}
    +}
    +
    +static void
    +bwn_crypt_init(struct bwn_mac *mac)
    +{
    +
    +	mac->mac_max_nr_keys = (mac->mac_sd->sd_id.sd_rev >= 5) ? 58 : 20;
    +	KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
    +	mac->mac_ktp *= 2;
    +	if (mac->mac_sd->sd_id.sd_rev >= 5) {
    +		BWN_WRITE_2(mac, BWN_RCMTA_COUNT,
    +		    mac->mac_max_nr_keys - 8);
    +	}
    +	bwn_clear_keys(mac);
    +}
    +
    +static void
    +bwn_chip_exit(struct bwn_mac *mac)
    +{
    +
    +	bwn_phy_exit(mac);
    +	bwn_gpio_cleanup(mac);
    +}
    +
    +static int
    +bwn_fw_fillinfo(struct bwn_mac *mac)
    +{
    +	int error;
    +
    +	error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
    +	if (error == 0)
    +		return (0);
    +	error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
    +	if (error == 0)
    +		return (0);
    +	return (error);
    +}
    +
    +static int
    +bwn_gpio_init(struct bwn_mac *mac)
    +{
    +	struct siba_softc *bus = mac->mac_sd->sd_bus;
    +	struct siba_dev_softc *sd;
    +	uint32_t mask = 0x0000001f, set = 0x0000000f;
    +
    +	BWN_WRITE_4(mac, BWN_MACCTL,
    +	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
    +	BWN_WRITE_2(mac, BWN_GPIO_MASK,
    +	    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
    +
    +	if (bus->siba_chipid == 0x4301) {
    +		mask |= 0x0060;
    +		set |= 0x0060;
    +	}
    +	if (bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) {
    +		BWN_WRITE_2(mac, BWN_GPIO_MASK,
    +		    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
    +		mask |= 0x0200;
    +		set |= 0x0200;
    +	}
    +	if (mac->mac_sd->sd_id.sd_rev >= 2)
    +		mask |= 0x0010;
    +	sd = (bus->siba_cc.scc_dev != NULL) ? bus->siba_cc.scc_dev :
    +	    bus->siba_pci.spc_dev;
    +	if (sd == NULL)
    +		return (0);
    +	siba_write_4(sd, BWN_GPIOCTL,
    +	    (siba_read_4(sd, BWN_GPIOCTL) & mask) | set);
    +
    +	return (0);
    +}
    +
    +static int
    +bwn_fw_loadinitvals(struct bwn_mac *mac)
    +{
    +#define	GETFWOFFSET(fwp, offset)				\
    +	((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
    +	const size_t hdr_len = sizeof(struct bwn_fwhdr);
    +	const struct bwn_fwhdr *hdr;
    +	struct bwn_fw *fw = &mac->mac_fw;
    +	int error;
    +
    +	hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
    +	error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
    +	    be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
    +	if (error)
    +		return (error);
    +	if (fw->initvals_band.fw) {
    +		hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
    +		error = bwn_fwinitvals_write(mac,
    +		    GETFWOFFSET(fw->initvals_band, hdr_len),
    +		    be32toh(hdr->size),
    +		    fw->initvals_band.fw->datasize - hdr_len);
    +	}
    +	return (error);
    +#undef GETFWOFFSET
    +}
    +
    +static int
    +bwn_phy_init(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	int error;
    +
    +	mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
    +	mac->mac_phy.rf_onoff(mac, 1);
    +	error = mac->mac_phy.init(mac);
    +	if (error) {
    +		device_printf(sc->sc_dev, "PHY init failed\n");
    +		goto fail0;
    +	}
    +	error = bwn_switch_channel(mac,
    +	    mac->mac_phy.get_default_chan(mac));
    +	if (error) {
    +		device_printf(sc->sc_dev,
    +		    "failed to switch default channel\n");
    +		goto fail1;
    +	}
    +	return (0);
    +fail1:
    +	if (mac->mac_phy.exit)
    +		mac->mac_phy.exit(mac);
    +fail0:
    +	mac->mac_phy.rf_onoff(mac, 0);
    +
    +	return (error);
    +}
    +
    +static void
    +bwn_set_txantenna(struct bwn_mac *mac, int antenna)
    +{
    +	uint16_t ant;
    +	uint16_t tmp;
    +
    +	ant = bwn_ant2phy(antenna);
    +
    +	/* For ACK/CTS */
    +	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
    +	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
    +	/* For Probe Resposes */
    +	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
    +	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
    +}
    +
    +static void
    +bwn_set_opmode(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	uint32_t ctl;
    +	uint16_t cfp_pretbtt;
    +
    +	ctl = BWN_READ_4(mac, BWN_MACCTL);
    +	ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
    +	    BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
    +	    BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
    +	ctl |= BWN_MACCTL_STA;
    +
    +	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
    +	    ic->ic_opmode == IEEE80211_M_MBSS)
    +		ctl |= BWN_MACCTL_HOSTAP;
    +	else if (ic->ic_opmode == IEEE80211_M_IBSS)
    +		ctl &= ~BWN_MACCTL_STA;
    +	ctl |= sc->sc_filters;
    +
    +	if (mac->mac_sd->sd_id.sd_rev <= 4)
    +		ctl |= BWN_MACCTL_PROMISC;
    +
    +	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
    +
    +	cfp_pretbtt = 2;
    +	if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
    +		if (mac->mac_sd->sd_bus->siba_chipid == 0x4306 &&
    +		    mac->mac_sd->sd_bus->siba_chiprev == 3)
    +			cfp_pretbtt = 100;
    +		else
    +			cfp_pretbtt = 50;
    +	}
    +	BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
    +}
    +
    +static void
    +bwn_gpio_cleanup(struct bwn_mac *mac)
    +{
    +	struct siba_softc *bus = mac->mac_sd->sd_bus;
    +	struct siba_dev_softc *gpiodev, *pcidev = NULL;
    +
    +	pcidev = bus->siba_pci.spc_dev;
    +	gpiodev = bus->siba_cc.scc_dev ? bus->siba_cc.scc_dev : pcidev;
    +	if (!gpiodev)
    +		return;
    +	siba_write_4(gpiodev, BWN_GPIOCTL, 0);
    +}
    +
    +static int
    +bwn_dma_gettype(struct bwn_mac *mac)
    +{
    +	uint32_t tmp;
    +	uint16_t base;
    +
    +	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
    +	if (tmp & SIBA_TGSHIGH_DMA64)
    +		return (BWN_DMA_64BIT);
    +	base = bwn_dma_base(0, 0);
    +	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
    +	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
    +	if (tmp & BWN_DMA32_TXADDREXT_MASK)
    +		return (BWN_DMA_32BIT);
    +
    +	return (BWN_DMA_30BIT);
    +}
    +
    +static void
    +bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
    +{
    +	if (!error) {
    +		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
    +		*((bus_addr_t *)arg) = seg->ds_addr;
    +	}
    +}
    +
    +static void
    +bwn_phy_g_init_sub(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	uint16_t i, tmp;
    +
    +	if (phy->rev == 1)
    +		bwn_phy_init_b5(mac);
    +	else
    +		bwn_phy_init_b6(mac);
    +
    +	if (phy->rev >= 2 || phy->gmode)
    +		bwn_phy_init_a(mac);
    +
    +	if (phy->rev >= 2) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
    +		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
    +	}
    +	if (phy->rev == 2) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
    +	}
    +	if (phy->rev > 5) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
    +	}
    +	if (phy->gmode || phy->rev >= 2) {
    +		tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
    +		tmp &= BWN_PHYVER_VERSION;
    +		if (tmp == 3 || tmp == 5) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
    +			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
    +		}
    +		if (tmp == 5) {
    +			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
    +			    0x1f00);
    +		}
    +	}
    +	if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
    +	if (phy->rf_rev == 8) {
    +		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
    +		BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
    +	}
    +	if (BWN_HAS_LOOPBACK(phy))
    +		bwn_loopback_calcgain(mac);
    +
    +	if (phy->rf_rev != 8) {
    +		if (pg->pg_initval == 0xffff)
    +			pg->pg_initval = bwn_rf_init_bcm2050(mac);
    +		else
    +			BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
    +	}
    +	bwn_lo_g_init(mac);
    +	if (BWN_HAS_TXMAG(phy)) {
    +		BWN_RF_WRITE(mac, 0x52,
    +		    (BWN_RF_READ(mac, 0x52) & 0xff00)
    +		    | pg->pg_loctl.tx_bias |
    +		    pg->pg_loctl.tx_magn);
    +	} else {
    +		BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
    +	}
    +	if (phy->rev >= 6) {
    +		BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
    +		    (pg->pg_loctl.tx_bias << 12));
    +	}
    +	if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL)
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
    +	else
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
    +	if (phy->rev < 2)
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
    +	else
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
    +	if (phy->gmode || phy->rev >= 2) {
    +		bwn_lo_g_adjust(mac);
    +		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
    +	}
    +
    +	if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) {
    +		for (i = 0; i < 64; i++) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
    +			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
    +			    (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
    +			    -32), 31));
    +		}
    +		bwn_nrssi_threshold(mac);
    +	} else if (phy->gmode || phy->rev >= 2) {
    +		if (pg->pg_nrssi[0] == -1000) {
    +			KASSERT(pg->pg_nrssi[1] == -1000,
    +			    ("%s:%d: fail", __func__, __LINE__));
    +			bwn_nrssi_slope_11g(mac);
    +		} else
    +			bwn_nrssi_threshold(mac);
    +	}
    +	if (phy->rf_rev == 8)
    +		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
    +	bwn_phy_hwpctl_init(mac);
    +	if ((mac->mac_sd->sd_bus->siba_chipid == 0x4306
    +	     && mac->mac_sd->sd_bus->siba_chippkg == 2) || 0) {
    +		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
    +		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
    +	}
    +}
    +
    +static uint8_t
    +bwn_has_hwpctl(struct bwn_mac *mac)
    +{
    +
    +	if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
    +		return (0);
    +	return (mac->mac_phy.use_hwpctl(mac));
    +}
    +
    +static void
    +bwn_phy_init_b5(struct bwn_mac *mac)
    +{
    +	struct siba_softc *bus = mac->mac_sd->sd_bus;
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	uint16_t offset, value;
    +	uint8_t old_channel;
    +
    +	if (phy->analog == 1)
    +		BWN_RF_SET(mac, 0x007a, 0x0050);
    +	if ((bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM) &&
    +	    (bus->siba_board_type != SIBA_BOARD_BU4306)) {
    +		value = 0x2120;
    +		for (offset = 0x00a8; offset < 0x00c7; offset++) {
    +			BWN_PHY_WRITE(mac, offset, value);
    +			value += 0x202;
    +		}
    +	}
    +	BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
    +	if (phy->rf_ver == 0x2050)
    +		BWN_PHY_WRITE(mac, 0x0038, 0x0667);
    +
    +	if (phy->gmode || phy->rev >= 2) {
    +		if (phy->rf_ver == 0x2050) {
    +			BWN_RF_SET(mac, 0x007a, 0x0020);
    +			BWN_RF_SET(mac, 0x0051, 0x0004);
    +		}
    +		BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
    +
    +		BWN_PHY_SET(mac, 0x0802, 0x0100);
    +		BWN_PHY_SET(mac, 0x042b, 0x2000);
    +
    +		BWN_PHY_WRITE(mac, 0x001c, 0x186a);
    +
    +		BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
    +		BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
    +		BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
    +	}
    +
    +	if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
    +		BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
    +
    +	if (phy->analog == 1) {
    +		BWN_PHY_WRITE(mac, 0x0026, 0xce00);
    +		BWN_PHY_WRITE(mac, 0x0021, 0x3763);
    +		BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
    +		BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
    +		BWN_PHY_WRITE(mac, 0x0024, 0x037e);
    +	} else
    +		BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
    +	BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
    +	BWN_WRITE_2(mac, 0x03ec, 0x3f22);
    +
    +	if (phy->analog == 1)
    +		BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
    +	else
    +		BWN_PHY_WRITE(mac, 0x0020, 0x301c);
    +
    +	if (phy->analog == 0)
    +		BWN_WRITE_2(mac, 0x03e4, 0x3000);
    +
    +	old_channel = phy->chan;
    +	bwn_phy_g_switch_chan(mac, 7, 0);
    +
    +	if (phy->rf_ver != 0x2050) {
    +		BWN_RF_WRITE(mac, 0x0075, 0x0080);
    +		BWN_RF_WRITE(mac, 0x0079, 0x0081);
    +	}
    +
    +	BWN_RF_WRITE(mac, 0x0050, 0x0020);
    +	BWN_RF_WRITE(mac, 0x0050, 0x0023);
    +
    +	if (phy->rf_ver == 0x2050) {
    +		BWN_RF_WRITE(mac, 0x0050, 0x0020);
    +		BWN_RF_WRITE(mac, 0x005a, 0x0070);
    +	}
    +
    +	BWN_RF_WRITE(mac, 0x005b, 0x007b);
    +	BWN_RF_WRITE(mac, 0x005c, 0x00b0);
    +	BWN_RF_SET(mac, 0x007a, 0x0007);
    +
    +	bwn_phy_g_switch_chan(mac, old_channel, 0);
    +	BWN_PHY_WRITE(mac, 0x0014, 0x0080);
    +	BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
    +	BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
    +
    +	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
    +	    pg->pg_txctl);
    +
    +	if (phy->rf_ver == 0x2050)
    +		BWN_RF_WRITE(mac, 0x005d, 0x000d);
    +
    +	BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
    +}
    +
    +static void
    +bwn_loopback_calcgain(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	uint16_t backup_phy[16] = { 0 };
    +	uint16_t backup_radio[3];
    +	uint16_t backup_bband;
    +	uint16_t i, j, loop_i_max;
    +	uint16_t trsw_rx;
    +	uint16_t loop1_outer_done, loop1_inner_done;
    +
    +	backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
    +	backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
    +	backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
    +	backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
    +	if (phy->rev != 1) {
    +		backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
    +		backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
    +	}
    +	backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
    +	backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
    +	backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
    +	backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
    +	backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
    +	backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
    +	backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
    +	backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
    +	backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
    +	backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
    +	backup_bband = pg->pg_bbatt.att;
    +	backup_radio[0] = BWN_RF_READ(mac, 0x52);
    +	backup_radio[1] = BWN_RF_READ(mac, 0x43);
    +	backup_radio[2] = BWN_RF_READ(mac, 0x7a);
    +
    +	BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
    +	BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
    +	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
    +	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
    +	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
    +	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
    +	if (phy->rev != 1) {
    +		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
    +		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
    +		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
    +		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
    +	}
    +	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
    +	BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
    +	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
    +
    +	BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
    +	if (phy->rev != 1) {
    +		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
    +		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
    +	}
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
    +
    +	if (phy->rf_rev == 8)
    +		BWN_RF_WRITE(mac, 0x43, 0x000f);
    +	else {
    +		BWN_RF_WRITE(mac, 0x52, 0);
    +		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
    +	}
    +	bwn_phy_g_set_bbatt(mac, 11);
    +
    +	if (phy->rev >= 3)
    +		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
    +	else
    +		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
    +	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
    +
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
    +
    +	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
    +	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
    +
    +	if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) {
    +		if (phy->rev >= 7) {
    +			BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
    +			BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
    +		}
    +	}
    +	BWN_RF_MASK(mac, 0x7a, 0x00f7);
    +
    +	j = 0;
    +	loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
    +	for (i = 0; i < loop_i_max; i++) {
    +		for (j = 0; j < 16; j++) {
    +			BWN_RF_WRITE(mac, 0x43, i);
    +			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
    +			    (j << 8));
    +			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
    +			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
    +			DELAY(20);
    +			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
    +				goto done0;
    +		}
    +	}
    +done0:
    +	loop1_outer_done = i;
    +	loop1_inner_done = j;
    +	if (j >= 8) {
    +		BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
    +		trsw_rx = 0x1b;
    +		for (j = j - 8; j < 16; j++) {
    +			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
    +			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
    +			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
    +			DELAY(20);
    +			trsw_rx -= 3;
    +			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
    +				goto done1;
    +		}
    +	} else
    +		trsw_rx = 0x18;
    +done1:
    +
    +	if (phy->rev != 1) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
    +		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
    +	}
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
    +
    +	bwn_phy_g_set_bbatt(mac, backup_bband);
    +
    +	BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
    +	BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
    +	BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
    +	DELAY(10);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
    +
    +	pg->pg_max_lb_gain =
    +	    ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
    +	pg->pg_trsw_rx_gain = trsw_rx * 2;
    +}
    +
    +static uint16_t
    +bwn_rf_init_bcm2050(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	uint32_t tmp1 = 0, tmp2 = 0;
    +	uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
    +	    analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
    +	    radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
    +	static const uint8_t rcc_table[] = {
    +		0x02, 0x03, 0x01, 0x0f,
    +		0x06, 0x07, 0x05, 0x0f,
    +		0x0a, 0x0b, 0x09, 0x0f,
    +		0x0e, 0x0f, 0x0d, 0x0f,
    +	};
    +
    +	radio0 = BWN_RF_READ(mac, 0x43);
    +	radio1 = BWN_RF_READ(mac, 0x51);
    +	radio2 = BWN_RF_READ(mac, 0x52);
    +	pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
    +	cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
    +	cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
    +	cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
    +
    +	if (phy->type == BWN_PHYTYPE_B) {
    +		cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
    +		reg0 = BWN_READ_2(mac, 0x3ec);
    +
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
    +		BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
    +	} else if (phy->gmode || phy->rev >= 2) {
    +		rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
    +		rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
    +		analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
    +		analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
    +		crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
    +		classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
    +
    +		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
    +		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
    +		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
    +		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
    +		if (BWN_HAS_LOOPBACK(phy)) {
    +			lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
    +			loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
    +			if (phy->rev >= 3)
    +				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
    +			else
    +				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
    +			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
    +		}
    +
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
    +			BWN_LPD(0, 1, 1)));
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
    +		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
    +	}
    +	BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
    +
    +	syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
    +	BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
    +	reg1 = BWN_READ_2(mac, 0x3e6);
    +	reg2 = BWN_READ_2(mac, 0x3f4);
    +
    +	if (phy->analog == 0)
    +		BWN_WRITE_2(mac, 0x03e6, 0x0122);
    +	else {
    +		if (phy->analog >= 2)
    +			BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
    +		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
    +		    (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
    +	}
    +
    +	reg = BWN_RF_READ(mac, 0x60);
    +	index = (reg & 0x001e) >> 1;
    +	rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
    +
    +	if (phy->type == BWN_PHYTYPE_B)
    +		BWN_RF_WRITE(mac, 0x78, 0x26);
    +	if (phy->gmode || phy->rev >= 2) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
    +			BWN_LPD(0, 1, 1)));
    +	}
    +	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
    +	if (phy->gmode || phy->rev >= 2) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
    +			BWN_LPD(0, 0, 1)));
    +	}
    +	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
    +	BWN_RF_SET(mac, 0x51, 0x0004);
    +	if (phy->rf_rev == 8)
    +		BWN_RF_WRITE(mac, 0x43, 0x1f);
    +	else {
    +		BWN_RF_WRITE(mac, 0x52, 0);
    +		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
    +	}
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
    +
    +	for (i = 0; i < 16; i++) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
    +		if (phy->gmode || phy->rev >= 2) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +			    bwn_rf_2050_rfoverval(mac,
    +				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
    +		}
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
    +		DELAY(10);
    +		if (phy->gmode || phy->rev >= 2) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +			    bwn_rf_2050_rfoverval(mac,
    +				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
    +		}
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
    +		DELAY(10);
    +		if (phy->gmode || phy->rev >= 2) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +			    bwn_rf_2050_rfoverval(mac,
    +				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
    +		}
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
    +		DELAY(20);
    +		tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
    +		if (phy->gmode || phy->rev >= 2) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +			    bwn_rf_2050_rfoverval(mac,
    +				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
    +		}
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
    +	}
    +	DELAY(10);
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
    +	tmp1++;
    +	tmp1 >>= 9;
    +
    +	for (i = 0; i < 16; i++) {
    +		radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
    +		BWN_RF_WRITE(mac, 0x78, radio78);
    +		DELAY(10);
    +		for (j = 0; j < 16; j++) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
    +			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
    +			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
    +			if (phy->gmode || phy->rev >= 2) {
    +				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +				    bwn_rf_2050_rfoverval(mac,
    +					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
    +			}
    +			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
    +			DELAY(10);
    +			if (phy->gmode || phy->rev >= 2) {
    +				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +				    bwn_rf_2050_rfoverval(mac,
    +					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
    +			}
    +			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
    +			DELAY(10);
    +			if (phy->gmode || phy->rev >= 2) {
    +				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +				    bwn_rf_2050_rfoverval(mac,
    +					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
    +			}
    +			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
    +			DELAY(10);
    +			tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
    +			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
    +			if (phy->gmode || phy->rev >= 2) {
    +				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
    +				    bwn_rf_2050_rfoverval(mac,
    +					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
    +			}
    +			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
    +		}
    +		tmp2++;
    +		tmp2 >>= 8;
    +		if (tmp1 < tmp2)
    +			break;
    +	}
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
    +	BWN_RF_WRITE(mac, 0x51, radio1);
    +	BWN_RF_WRITE(mac, 0x52, radio2);
    +	BWN_RF_WRITE(mac, 0x43, radio0);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
    +	BWN_WRITE_2(mac, 0x3e6, reg1);
    +	if (phy->analog != 0)
    +		BWN_WRITE_2(mac, 0x3f4, reg2);
    +	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
    +	bwn_spu_workaround(mac, phy->chan);
    +	if (phy->type == BWN_PHYTYPE_B) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
    +		BWN_WRITE_2(mac, 0x3ec, reg0);
    +	} else if (phy->gmode) {
    +		BWN_WRITE_2(mac, BWN_PHY_RADIO,
    +			    BWN_READ_2(mac, BWN_PHY_RADIO)
    +			    & 0x7fff);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
    +		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
    +		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
    +			      analogoverval);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
    +		if (BWN_HAS_LOOPBACK(phy)) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
    +			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
    +		}
    +	}
    +
    +	return ((i > 15) ? radio78 : rcc);
    +}
    +
    +static void
    +bwn_phy_init_b6(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	uint16_t offset, val;
    +	uint8_t old_channel;
    +
    +	KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	BWN_PHY_WRITE(mac, 0x003e, 0x817a);
    +	BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
    +	if (phy->rf_rev == 4 || phy->rf_rev == 5) {
    +		BWN_RF_WRITE(mac, 0x51, 0x37);
    +		BWN_RF_WRITE(mac, 0x52, 0x70);
    +		BWN_RF_WRITE(mac, 0x53, 0xb3);
    +		BWN_RF_WRITE(mac, 0x54, 0x9b);
    +		BWN_RF_WRITE(mac, 0x5a, 0x88);
    +		BWN_RF_WRITE(mac, 0x5b, 0x88);
    +		BWN_RF_WRITE(mac, 0x5d, 0x88);
    +		BWN_RF_WRITE(mac, 0x5e, 0x88);
    +		BWN_RF_WRITE(mac, 0x7d, 0x88);
    +		bwn_hf_write(mac,
    +		    bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
    +	}
    +	if (phy->rf_rev == 8) {
    +		BWN_RF_WRITE(mac, 0x51, 0);
    +		BWN_RF_WRITE(mac, 0x52, 0x40);
    +		BWN_RF_WRITE(mac, 0x53, 0xb7);
    +		BWN_RF_WRITE(mac, 0x54, 0x98);
    +		BWN_RF_WRITE(mac, 0x5a, 0x88);
    +		BWN_RF_WRITE(mac, 0x5b, 0x6b);
    +		BWN_RF_WRITE(mac, 0x5c, 0x0f);
    +		if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_ALTIQ) {
    +			BWN_RF_WRITE(mac, 0x5d, 0xfa);
    +			BWN_RF_WRITE(mac, 0x5e, 0xd8);
    +		} else {
    +			BWN_RF_WRITE(mac, 0x5d, 0xf5);
    +			BWN_RF_WRITE(mac, 0x5e, 0xb8);
    +		}
    +		BWN_RF_WRITE(mac, 0x0073, 0x0003);
    +		BWN_RF_WRITE(mac, 0x007d, 0x00a8);
    +		BWN_RF_WRITE(mac, 0x007c, 0x0001);
    +		BWN_RF_WRITE(mac, 0x007e, 0x0008);
    +	}
    +	for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
    +		BWN_PHY_WRITE(mac, offset, val);
    +		val -= 0x0202;
    +	}
    +	for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
    +		BWN_PHY_WRITE(mac, offset, val);
    +		val -= 0x0202;
    +	}
    +	for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
    +		BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
    +		val += 0x0202;
    +	}
    +	if (phy->type == BWN_PHYTYPE_G) {
    +		BWN_RF_SET(mac, 0x007a, 0x0020);
    +		BWN_RF_SET(mac, 0x0051, 0x0004);
    +		BWN_PHY_SET(mac, 0x0802, 0x0100);
    +		BWN_PHY_SET(mac, 0x042b, 0x2000);
    +		BWN_PHY_WRITE(mac, 0x5b, 0);
    +		BWN_PHY_WRITE(mac, 0x5c, 0);
    +	}
    +
    +	old_channel = phy->chan;
    +	bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
    +
    +	BWN_RF_WRITE(mac, 0x0050, 0x0020);
    +	BWN_RF_WRITE(mac, 0x0050, 0x0023);
    +	DELAY(40);
    +	if (phy->rf_rev < 6 || phy->rf_rev == 8) {
    +		BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
    +		BWN_RF_WRITE(mac, 0x50, 0x20);
    +	}
    +	if (phy->rf_rev <= 2) {
    +		BWN_RF_WRITE(mac, 0x7c, 0x20);
    +		BWN_RF_WRITE(mac, 0x5a, 0x70);
    +		BWN_RF_WRITE(mac, 0x5b, 0x7b);
    +		BWN_RF_WRITE(mac, 0x5c, 0xb0);
    +	}
    +	BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
    +
    +	bwn_phy_g_switch_chan(mac, old_channel, 0);
    +
    +	BWN_PHY_WRITE(mac, 0x0014, 0x0200);
    +	if (phy->rf_rev >= 6)
    +		BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
    +	else
    +		BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
    +	BWN_PHY_WRITE(mac, 0x0038, 0x0668);
    +	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
    +	    pg->pg_txctl);
    +	if (phy->rf_rev <= 5)
    +		BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
    +	if (phy->rf_rev <= 2)
    +		BWN_RF_WRITE(mac, 0x005d, 0x000d);
    +
    +	if (phy->analog == 4) {
    +		BWN_WRITE_2(mac, 0x3e4, 9);
    +		BWN_PHY_MASK(mac, 0x61, 0x0fff);
    +	} else
    +		BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
    +	if (phy->type == BWN_PHYTYPE_B)
    +		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	else if (phy->type == BWN_PHYTYPE_G)
    +		BWN_WRITE_2(mac, 0x03e6, 0x0);
    +}
    +
    +static void
    +bwn_phy_init_a(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	if (phy->rev >= 6) {
    +		if (phy->type == BWN_PHYTYPE_A)
    +			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
    +		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
    +			BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
    +		else
    +			BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
    +	}
    +
    +	bwn_wa_init(mac);
    +
    +	if (phy->type == BWN_PHYTYPE_G &&
    +	    (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL))
    +		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
    +}
    +
    +static void
    +bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
    +{
    +	int i;
    +
    +	for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
    +}
    +
    +static void
    +bwn_wa_agc(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +
    +	if (phy->rev == 1) {
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
    +		BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
    +	} else {
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
    +	}
    +
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
    +	    0x5700);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
    +	BWN_RF_SET(mac, 0x7a, 0x0008);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
    +	if (phy->rev == 1)
    +		BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
    +	if (phy->rev == 1) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
    +	} else {
    +		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
    +		if (phy->rev >= 6) {
    +			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
    +			BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
    +			    (uint16_t)~0xf000, 0x3000);
    +		}
    +	}
    +	BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
    +	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
    +	if (phy->rev == 1) {
    +		BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
    +	} else {
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
    +	}
    +	if (phy->rev >= 6) {
    +		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
    +		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
    +	}
    +	BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
    +}
    +
    +static void
    +bwn_wa_grev1(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	int i;
    +	static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
    +	static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
    +	static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
    +
    +	/* init CRSTHRES and ANTDWELL */
    +	if (phy->rev == 1) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
    +	} else if (phy->rev == 2) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
    +		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
    +	} else {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
    +		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
    +	}
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
    +	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
    +
    +	/* XXX support PHY-A??? */
    +	for (i = 0; i < N(bwn_tab_finefreqg); i++)
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
    +		    bwn_tab_finefreqg[i]);
    +
    +	/* XXX support PHY-A??? */
    +	if (phy->rev == 1)
    +		for (i = 0; i < N(bwn_tab_noise_g1); i++)
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
    +			    bwn_tab_noise_g1[i]);
    +	else
    +		for (i = 0; i < N(bwn_tab_noise_g2); i++)
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
    +			    bwn_tab_noise_g2[i]);
    +
    +
    +	for (i = 0; i < N(bwn_tab_rotor); i++)
    +		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
    +		    bwn_tab_rotor[i]);
    +
    +	/* XXX support PHY-A??? */
    +	if (phy->rev >= 6) {
    +		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
    +		    BWN_PHY_ENCORE_EN)
    +			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
    +		else
    +			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
    +	} else
    +		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
    +
    +	for (i = 0; i < N(bwn_tab_retard); i++)
    +		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
    +		    bwn_tab_retard[i]);
    +
    +	if (phy->rev == 1) {
    +		for (i = 0; i < 16; i++)
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
    +			    i, 0x0020);
    +	} else {
    +		for (i = 0; i < 32; i++)
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
    +	}
    +
    +	bwn_wa_agc(mac);
    +}
    +
    +static void
    +bwn_wa_grev26789(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	int i;
    +	static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
    +	uint16_t ofdmrev;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
    +
    +	bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
    +
    +	/* init CRSTHRES and ANTDWELL */
    +	if (phy->rev == 1)
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
    +	else if (phy->rev == 2) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
    +		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
    +	} else {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
    +		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
    +	}
    +
    +	for (i = 0; i < 64; i++)
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
    +
    +	/* XXX support PHY-A??? */
    +	if (phy->rev == 1)
    +		for (i = 0; i < N(bwn_tab_noise_g1); i++)
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
    +			    bwn_tab_noise_g1[i]);
    +	else
    +		for (i = 0; i < N(bwn_tab_noise_g2); i++)
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
    +			    bwn_tab_noise_g2[i]);
    +
    +	/* XXX support PHY-A??? */
    +	if (phy->rev >= 6) {
    +		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
    +		    BWN_PHY_ENCORE_EN)
    +			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
    +		else
    +			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
    +	} else
    +		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
    +
    +	for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
    +		    bwn_tab_sigmasqr2[i]);
    +
    +	if (phy->rev == 1) {
    +		for (i = 0; i < 16; i++)
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
    +			    0x0020);
    +	} else {
    +		for (i = 0; i < 32; i++)
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
    +	}
    +
    +	bwn_wa_agc(mac);
    +
    +	ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
    +	if (ofdmrev > 2) {
    +		if (phy->type == BWN_PHYTYPE_A)
    +			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
    +		else
    +			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
    +	} else {
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
    +		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
    +	}
    +
    +	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
    +	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
    +}
    +
    +static void
    +bwn_wa_init(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct siba_softc *bus = mac->mac_sd->sd_bus;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
    +
    +	switch (phy->rev) {
    +	case 1:
    +		bwn_wa_grev1(mac);
    +		break;
    +	case 2:
    +	case 6:
    +	case 7:
    +	case 8:
    +	case 9:
    +		bwn_wa_grev26789(mac);
    +		break;
    +	default:
    +		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	}
    +
    +	if (bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM ||
    +	    bus->siba_board_type != SIBA_BOARD_BU4306 ||
    +	    bus->siba_board_rev != 0x17) {
    +		if (phy->rev < 2) {
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
    +			    0x0002);
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
    +			    0x0001);
    +		} else {
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
    +			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
    +			if ((bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) &&
    +			    (phy->rev >= 7)) {
    +				BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
    +				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
    +				    0x0020, 0x0001);
    +				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
    +				    0x0021, 0x0001);
    +				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
    +				    0x0022, 0x0001);
    +				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
    +				    0x0023, 0x0000);
    +				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
    +				    0x0000, 0x0000);
    +				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
    +				    0x0003, 0x0002);
    +			}
    +		}
    +	}
    +	if (bus->siba_sprom.bf_lo & BWN_BFL_FEM) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
    +		BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
    +	}
    +
    +	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
    +	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
    +}
    +
    +static void
    +bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
    +    uint16_t value)
    +{
    +	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
    +	uint16_t addr;
    +
    +	addr = table + offset;
    +	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
    +	    (addr - 1 != pg->pg_ofdmtab_addr)) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
    +		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
    +	}
    +	pg->pg_ofdmtab_addr = addr;
    +	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
    +}
    +
    +static void
    +bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
    +    uint32_t value)
    +{
    +	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
    +	uint16_t addr;
    +
    +	addr = table + offset;
    +	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
    +	    (addr - 1 != pg->pg_ofdmtab_addr)) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
    +		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
    +	}
    +	pg->pg_ofdmtab_addr = addr;
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
    +	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
    +}
    +
    +static void
    +bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
    +    uint16_t value)
    +{
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
    +	BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
    +}
    +
    +static void
    +bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	unsigned int i, max_loop;
    +	uint16_t value;
    +	uint32_t buffer[5] = {
    +		0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
    +	};
    +
    +	if (ofdm) {
    +		max_loop = 0x1e;
    +		buffer[0] = 0x000201cc;
    +	} else {
    +		max_loop = 0xfa;
    +		buffer[0] = 0x000b846e;
    +	}
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	for (i = 0; i < 5; i++)
    +		bwn_ram_write(mac, i * 4, buffer[i]);
    +
    +	BWN_WRITE_2(mac, 0x0568, 0x0000);
    +	BWN_WRITE_2(mac, 0x07c0,
    +	    (mac->mac_sd->sd_id.sd_rev < 11) ? 0x0000 : 0x0100);
    +	value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
    +	BWN_WRITE_2(mac, 0x050c, value);
    +	if (phy->type == BWN_PHYTYPE_LP)
    +		BWN_WRITE_2(mac, 0x0514, 0x1a02);
    +	BWN_WRITE_2(mac, 0x0508, 0x0000);
    +	BWN_WRITE_2(mac, 0x050a, 0x0000);
    +	BWN_WRITE_2(mac, 0x054c, 0x0000);
    +	BWN_WRITE_2(mac, 0x056a, 0x0014);
    +	BWN_WRITE_2(mac, 0x0568, 0x0826);
    +	BWN_WRITE_2(mac, 0x0500, 0x0000);
    +	if (phy->type == BWN_PHYTYPE_LP)
    +		BWN_WRITE_2(mac, 0x0502, 0x0050);
    +	else
    +		BWN_WRITE_2(mac, 0x0502, 0x0030);
    +
    +	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
    +		BWN_RF_WRITE(mac, 0x0051, 0x0017);
    +	for (i = 0x00; i < max_loop; i++) {
    +		value = BWN_READ_2(mac, 0x050e);
    +		if (value & 0x0080)
    +			break;
    +		DELAY(10);
    +	}
    +	for (i = 0x00; i < 0x0a; i++) {
    +		value = BWN_READ_2(mac, 0x050e);
    +		if (value & 0x0400)
    +			break;
    +		DELAY(10);
    +	}
    +	for (i = 0x00; i < 0x19; i++) {
    +		value = BWN_READ_2(mac, 0x0690);
    +		if (!(value & 0x0100))
    +			break;
    +		DELAY(10);
    +	}
    +	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
    +		BWN_RF_WRITE(mac, 0x0051, 0x0037);
    +}
    +
    +static void
    +bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
    +{
    +	uint32_t macctl;
    +
    +	KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
    +
    +	macctl = BWN_READ_4(mac, BWN_MACCTL);
    +	if (macctl & BWN_MACCTL_BIGENDIAN)
    +		printf("TODO: need swap\n");
    +
    +	BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
    +	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
    +	BWN_WRITE_4(mac, BWN_RAM_DATA, val);
    +}
    +
    +static void
    +bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	uint16_t value;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	value = (uint8_t) (ctl->q);
    +	value |= ((uint8_t) (ctl->i)) << 8;
    +	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
    +}
    +
    +static uint16_t
    +bwn_lo_calcfeed(struct bwn_mac *mac,
    +    uint16_t lna, uint16_t pga, uint16_t trsw_rx)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	uint16_t rfover;
    +	uint16_t feedthrough;
    +
    +	if (phy->gmode) {
    +		lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
    +		pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
    +
    +		KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
    +		    ("%s:%d: fail", __func__, __LINE__));
    +		KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
    +		    ("%s:%d: fail", __func__, __LINE__));
    +
    +		trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
    +
    +		rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
    +		if ((mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA)
    +		    && phy->rev > 6)
    +			rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
    +
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
    +		DELAY(10);
    +		rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
    +		DELAY(10);
    +		rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
    +		DELAY(10);
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
    +	} else {
    +		pga |= BWN_PHY_PGACTL_UNKNOWN;
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
    +		DELAY(10);
    +		pga |= BWN_PHY_PGACTL_LOWBANDW;
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
    +		DELAY(10);
    +		pga |= BWN_PHY_PGACTL_LPF;
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
    +	}
    +	DELAY(21);
    +	feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
    +
    +	return (feedthrough);
    +}
    +
    +static uint16_t
    +bwn_lo_txctl_regtable(struct bwn_mac *mac,
    +    uint16_t *value, uint16_t *pad_mix_gain)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	uint16_t reg, v, padmix;
    +
    +	if (phy->type == BWN_PHYTYPE_B) {
    +		v = 0x30;
    +		if (phy->rf_rev <= 5) {
    +			reg = 0x43;
    +			padmix = 0;
    +		} else {
    +			reg = 0x52;
    +			padmix = 5;
    +		}
    +	} else {
    +		if (phy->rev >= 2 && phy->rf_rev == 8) {
    +			reg = 0x43;
    +			v = 0x10;
    +			padmix = 2;
    +		} else {
    +			reg = 0x52;
    +			v = 0x30;
    +			padmix = 5;
    +		}
    +	}
    +	if (value)
    +		*value = v;
    +	if (pad_mix_gain)
    +		*pad_mix_gain = padmix;
    +
    +	return (reg);
    +}
    +
    +static void
    +bwn_lo_measure_txctl_values(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
    +	uint16_t reg, mask;
    +	uint16_t trsw_rx, pga;
    +	uint16_t rf_pctl_reg;
    +
    +	static const uint8_t tx_bias_values[] = {
    +		0x09, 0x08, 0x0a, 0x01, 0x00,
    +		0x02, 0x05, 0x04, 0x06,
    +	};
    +	static const uint8_t tx_magn_values[] = {
    +		0x70, 0x40,
    +	};
    +
    +	if (!BWN_HAS_LOOPBACK(phy)) {
    +		rf_pctl_reg = 6;
    +		trsw_rx = 2;
    +		pga = 0;
    +	} else {
    +		int lb_gain;
    +
    +		trsw_rx = 0;
    +		lb_gain = pg->pg_max_lb_gain / 2;
    +		if (lb_gain > 10) {
    +			rf_pctl_reg = 0;
    +			pga = abs(10 - lb_gain) / 6;
    +			pga = MIN(MAX(pga, 0), 15);
    +		} else {
    +			int cmp_val;
    +			int tmp;
    +
    +			pga = 0;
    +			cmp_val = 0x24;
    +			if ((phy->rev >= 2) &&
    +			    (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
    +				cmp_val = 0x3c;
    +			tmp = lb_gain;
    +			if ((10 - lb_gain) < cmp_val)
    +				tmp = (10 - lb_gain);
    +			if (tmp < 0)
    +				tmp += 6;
    +			else
    +				tmp += 3;
    +			cmp_val /= 4;
    +			tmp /= 4;
    +			if (tmp >= cmp_val)
    +				rf_pctl_reg = cmp_val;
    +			else
    +				rf_pctl_reg = tmp;
    +		}
    +	}
    +	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
    +	bwn_phy_g_set_bbatt(mac, 2);
    +
    +	reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
    +	mask = ~mask;
    +	BWN_RF_MASK(mac, reg, mask);
    +
    +	if (BWN_HAS_TXMAG(phy)) {
    +		int i, j;
    +		int feedthrough;
    +		int min_feedth = 0xffff;
    +		uint8_t tx_magn, tx_bias;
    +
    +		for (i = 0; i < N(tx_magn_values); i++) {
    +			tx_magn = tx_magn_values[i];
    +			BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
    +			for (j = 0; j < N(tx_bias_values); j++) {
    +				tx_bias = tx_bias_values[j];
    +				BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
    +				feedthrough = bwn_lo_calcfeed(mac, 0, pga,
    +				    trsw_rx);
    +				if (feedthrough < min_feedth) {
    +					lo->tx_bias = tx_bias;
    +					lo->tx_magn = tx_magn;
    +					min_feedth = feedthrough;
    +				}
    +				if (lo->tx_bias == 0)
    +					break;
    +			}
    +			BWN_RF_WRITE(mac, 0x52,
    +					  (BWN_RF_READ(mac, 0x52)
    +					   & 0xff00) | lo->tx_bias | lo->
    +					  tx_magn);
    +		}
    +	} else {
    +		lo->tx_magn = 0;
    +		lo->tx_bias = 0;
    +		BWN_RF_MASK(mac, 0x52, 0xfff0);
    +	}
    +
    +	BWN_GETTIME(lo->txctl_measured_time);
    +}
    +
    +static void
    +bwn_lo_get_powervector(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
    +	int i;
    +	uint64_t tmp;
    +	uint64_t power_vector = 0;
    +
    +	for (i = 0; i < 8; i += 2) {
    +		tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
    +		power_vector |= (tmp << (i * 8));
    +		bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
    +	}
    +	if (power_vector)
    +		lo->power_vector = power_vector;
    +
    +	BWN_GETTIME(lo->pwr_vec_read_time);
    +}
    +
    +static void
    +bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
    +    int use_trsw_rx)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	uint16_t tmp;
    +
    +	if (max_rx_gain < 0)
    +		max_rx_gain = 0;
    +
    +	if (BWN_HAS_LOOPBACK(phy)) {
    +		int trsw_rx = 0;
    +		int trsw_rx_gain;
    +
    +		if (use_trsw_rx) {
    +			trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
    +			if (max_rx_gain >= trsw_rx_gain) {
    +				trsw_rx_gain = max_rx_gain - trsw_rx_gain;
    +				trsw_rx = 0x20;
    +			}
    +		} else
    +			trsw_rx_gain = max_rx_gain;
    +		if (trsw_rx_gain < 9) {
    +			pg->pg_lna_lod_gain = 0;
    +		} else {
    +			pg->pg_lna_lod_gain = 1;
    +			trsw_rx_gain -= 8;
    +		}
    +		trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
    +		pg->pg_pga_gain = trsw_rx_gain / 3;
    +		if (pg->pg_pga_gain >= 5) {
    +			pg->pg_pga_gain -= 5;
    +			pg->pg_lna_gain = 2;
    +		} else
    +			pg->pg_lna_gain = 0;
    +	} else {
    +		pg->pg_lna_gain = 0;
    +		pg->pg_trsw_rx_gain = 0x20;
    +		if (max_rx_gain >= 0x14) {
    +			pg->pg_lna_lod_gain = 1;
    +			pg->pg_pga_gain = 2;
    +		} else if (max_rx_gain >= 0x12) {
    +			pg->pg_lna_lod_gain = 1;
    +			pg->pg_pga_gain = 1;
    +		} else if (max_rx_gain >= 0xf) {
    +			pg->pg_lna_lod_gain = 1;
    +			pg->pg_pga_gain = 0;
    +		} else {
    +			pg->pg_lna_lod_gain = 0;
    +			pg->pg_pga_gain = 0;
    +		}
    +	}
    +
    +	tmp = BWN_RF_READ(mac, 0x7a);
    +	if (pg->pg_lna_lod_gain == 0)
    +		tmp &= ~0x0008;
    +	else
    +		tmp |= 0x0008;
    +	BWN_RF_WRITE(mac, 0x7a, tmp);
    +}
    +
    +static void
    +bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
    +{
    +	struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom;
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
    +	struct timespec ts;
    +	uint16_t tmp;
    +
    +	if (bwn_has_hwpctl(mac)) {
    +		sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
    +		sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
    +		sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
    +		sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
    +		sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
    +
    +		BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
    +		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
    +		BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
    +		BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
    +	}
    +	if (phy->type == BWN_PHYTYPE_B &&
    +	    phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
    +	}
    +	if (phy->rev >= 2) {
    +		sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
    +		sav->phy_analogoverval =
    +		    BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
    +		sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
    +		sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
    +		sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
    +		sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
    +		sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
    +
    +		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
    +		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
    +		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
    +		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
    +		if (phy->type == BWN_PHYTYPE_G) {
    +			if ((phy->rev >= 7) &&
    +			    (sprom->bf_lo & BWN_BFL_EXTLNA)) {
    +				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
    +			} else {
    +				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
    +			}
    +		} else {
    +			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
    +		}
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
    +	}
    +	sav->reg0 = BWN_READ_2(mac, 0x3f4);
    +	sav->reg1 = BWN_READ_2(mac, 0x3e2);
    +	sav->rf0 = BWN_RF_READ(mac, 0x43);
    +	sav->rf1 = BWN_RF_READ(mac, 0x7a);
    +	sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
    +	sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
    +	sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
    +	sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
    +
    +	if (!BWN_HAS_TXMAG(phy)) {
    +		sav->rf2 = BWN_RF_READ(mac, 0x52);
    +		sav->rf2 &= 0x00f0;
    +	}
    +	if (phy->type == BWN_PHYTYPE_B) {
    +		sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
    +		sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
    +	} else {
    +		BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
    +			    | 0x8000);
    +	}
    +	BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
    +		    & 0xf000);
    +
    +	tmp =
    +	    (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
    +	BWN_PHY_WRITE(mac, tmp, 0x007f);
    +
    +	tmp = sav->phy_syncctl;
    +	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
    +	tmp = sav->rf1;
    +	BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
    +	if (phy->type == BWN_PHYTYPE_G ||
    +	    (phy->type == BWN_PHYTYPE_B &&
    +	     phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
    +	} else
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
    +	if (phy->rev >= 2)
    +		bwn_dummy_transmission(mac, 0, 1);
    +	bwn_phy_g_switch_chan(mac, 6, 0);
    +	BWN_RF_READ(mac, 0x51);
    +	if (phy->type == BWN_PHYTYPE_G)
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
    +
    +	nanouptime(&ts);
    +	if (time_before(lo->txctl_measured_time,
    +	    (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
    +		bwn_lo_measure_txctl_values(mac);
    +
    +	if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
    +		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
    +	else {
    +		if (phy->type == BWN_PHYTYPE_B)
    +			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
    +		else
    +			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
    +	}
    +}
    +
    +static void
    +bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	uint16_t tmp;
    +
    +	if (phy->rev >= 2) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
    +		tmp = (pg->pg_pga_gain << 8);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
    +		DELAY(5);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
    +		DELAY(2);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
    +	} else {
    +		tmp = (pg->pg_pga_gain | 0xefa0);
    +		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
    +	}
    +	if (phy->type == BWN_PHYTYPE_G) {
    +		if (phy->rev >= 3)
    +			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
    +		else
    +			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
    +		if (phy->rev >= 2)
    +			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
    +		else
    +			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
    +	}
    +	BWN_WRITE_2(mac, 0x3f4, sav->reg0);
    +	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
    +	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
    +	BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
    +	BWN_RF_WRITE(mac, 0x43, sav->rf0);
    +	BWN_RF_WRITE(mac, 0x7a, sav->rf1);
    +	if (!BWN_HAS_TXMAG(phy)) {
    +		tmp = sav->rf2;
    +		BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
    +	}
    +	BWN_WRITE_2(mac, 0x3e2, sav->reg1);
    +	if (phy->type == BWN_PHYTYPE_B &&
    +	    phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
    +	}
    +	if (phy->rev >= 2) {
    +		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
    +		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
    +			      sav->phy_analogoverval);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
    +	}
    +	if (bwn_has_hwpctl(mac)) {
    +		tmp = (sav->phy_lomask & 0xbfff);
    +		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
    +		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
    +		BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
    +		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
    +		BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
    +	}
    +	bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
    +}
    +
    +static int
    +bwn_lo_probe_loctl(struct bwn_mac *mac,
    +    struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_loctl orig, test;
    +	struct bwn_loctl prev = { -100, -100 };
    +	static const struct bwn_loctl modifiers[] = {
    +		{  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
    +		{ -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
    +	};
    +	int begin, end, lower = 0, i;
    +	uint16_t feedth;
    +
    +	if (d->curstate == 0) {
    +		begin = 1;
    +		end = 8;
    +	} else if (d->curstate % 2 == 0) {
    +		begin = d->curstate - 1;
    +		end = d->curstate + 1;
    +	} else {
    +		begin = d->curstate - 2;
    +		end = d->curstate + 2;
    +	}
    +	if (begin < 1)
    +		begin += 8;
    +	if (end > 8)
    +		end -= 8;
    +
    +	memcpy(&orig, probe, sizeof(struct bwn_loctl));
    +	i = begin;
    +	d->curstate = i;
    +	while (1) {
    +		KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
    +		memcpy(&test, &orig, sizeof(struct bwn_loctl));
    +		test.i += modifiers[i - 1].i * d->multipler;
    +		test.q += modifiers[i - 1].q * d->multipler;
    +		if ((test.i != prev.i || test.q != prev.q) &&
    +		    (abs(test.i) <= 16 && abs(test.q) <= 16)) {
    +			bwn_lo_write(mac, &test);
    +			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
    +			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
    +			if (feedth < d->feedth) {
    +				memcpy(probe, &test,
    +				    sizeof(struct bwn_loctl));
    +				lower = 1;
    +				d->feedth = feedth;
    +				if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
    +					break;
    +			}
    +		}
    +		memcpy(&prev, &test, sizeof(prev));
    +		if (i == end)
    +			break;
    +		if (i == 8)
    +			i = 1;
    +		else
    +			i++;
    +		d->curstate = i;
    +	}
    +
    +	return (lower);
    +}
    +
    +static void
    +bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_lo_g_sm d;
    +	struct bwn_loctl probe;
    +	int lower, repeat, cnt = 0;
    +	uint16_t feedth;
    +
    +	d.nmeasure = 0;
    +	d.multipler = 1;
    +	if (BWN_HAS_LOOPBACK(phy))
    +		d.multipler = 3;
    +
    +	memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
    +	repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
    +
    +	do {
    +		bwn_lo_write(mac, &d.loctl);
    +		feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
    +		    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
    +		if (feedth < 0x258) {
    +			if (feedth >= 0x12c)
    +				*rxgain += 6;
    +			else
    +				*rxgain += 3;
    +			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
    +			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
    +		}
    +		d.feedth = feedth;
    +		d.curstate = 0;
    +		do {
    +			KASSERT(d.curstate >= 0 && d.curstate <= 8,
    +			    ("%s:%d: fail", __func__, __LINE__));
    +			memcpy(&probe, &d.loctl,
    +			       sizeof(struct bwn_loctl));
    +			lower = bwn_lo_probe_loctl(mac, &probe, &d);
    +			if (!lower)
    +				break;
    +			if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
    +				break;
    +			memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
    +			d.nmeasure++;
    +		} while (d.nmeasure < 24);
    +		memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
    +
    +		if (BWN_HAS_LOOPBACK(phy)) {
    +			if (d.feedth > 0x1194)
    +				*rxgain -= 6;
    +			else if (d.feedth < 0x5dc)
    +				*rxgain += 3;
    +			if (cnt == 0) {
    +				if (d.feedth <= 0x5dc) {
    +					d.multipler = 1;
    +					cnt++;
    +				} else
    +					d.multipler = 2;
    +			} else if (cnt == 2)
    +				d.multipler = 1;
    +		}
    +		bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
    +	} while (++cnt < repeat);
    +}
    +
    +static struct bwn_lo_calib *
    +bwn_lo_calibset(struct bwn_mac *mac,
    +    const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_loctl loctl = { 0, 0 };
    +	struct bwn_lo_calib *cal;
    +	struct bwn_lo_g_value sval;
    +	int rxgain;
    +	uint16_t pad, reg, value;
    +
    +	sval.old_channel = phy->chan;
    +	bwn_mac_suspend(mac);
    +	bwn_lo_save(mac, &sval);
    +
    +	reg = bwn_lo_txctl_regtable(mac, &value, &pad);
    +	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
    +	BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
    +
    +	rxgain = (rfatt->att * 2) + (bbatt->att / 2);
    +	if (rfatt->padmix)
    +		rxgain -= pad;
    +	if (BWN_HAS_LOOPBACK(phy))
    +		rxgain += pg->pg_max_lb_gain;
    +	bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
    +	bwn_phy_g_set_bbatt(mac, bbatt->att);
    +	bwn_lo_probe_sm(mac, &loctl, &rxgain);
    +
    +	bwn_lo_restore(mac, &sval);
    +	bwn_mac_enable(mac);
    +
    +	cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
    +	if (!cal) {
    +		device_printf(mac->mac_sc->sc_dev, "out of memory\n");
    +		return (NULL);
    +	}
    +	memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
    +	memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
    +	memcpy(&cal->ctl, &loctl, sizeof(loctl));
    +
    +	BWN_GETTIME(cal->calib_time);
    +
    +	return (cal);
    +}
    +
    +static struct bwn_lo_calib *
    +bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
    +    const struct bwn_rfatt *rfatt)
    +{
    +	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
    +	struct bwn_lo_calib *c;
    +
    +	TAILQ_FOREACH(c, &lo->calib_list, list) {
    +		if (!BWN_BBATTCMP(&c->bbatt, bbatt))
    +			continue;
    +		if (!BWN_RFATTCMP(&c->rfatt, rfatt))
    +			continue;
    +		return (c);
    +	}
    +
    +	c = bwn_lo_calibset(mac, bbatt, rfatt);
    +	if (!c)
    +		return (NULL);
    +	TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
    +
    +	return (c);
    +}
    +
    +static void
    +bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
    +	const struct bwn_rfatt *rfatt;
    +	const struct bwn_bbatt *bbatt;
    +	uint64_t pvector;
    +	int i;
    +	int rf_offset, bb_offset;
    +	uint8_t changed = 0;
    +
    +	KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
    +	KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	pvector = lo->power_vector;
    +	if (!update && !pvector)
    +		return;
    +
    +	bwn_mac_suspend(mac);
    +
    +	for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
    +		struct bwn_lo_calib *cal;
    +		int idx;
    +		uint16_t val;
    +
    +		if (!update && !(pvector & (((uint64_t)1ULL) << i)))
    +			continue;
    +		bb_offset = i / lo->rfatt.len;
    +		rf_offset = i % lo->rfatt.len;
    +		bbatt = &(lo->bbatt.array[bb_offset]);
    +		rfatt = &(lo->rfatt.array[rf_offset]);
    +
    +		cal = bwn_lo_calibset(mac, bbatt, rfatt);
    +		if (!cal) {
    +			device_printf(sc->sc_dev, "LO: Could not "
    +			    "calibrate DC table entry\n");
    +			continue;
    +		}
    +		val = (uint8_t)(cal->ctl.q);
    +		val |= ((uint8_t)(cal->ctl.i)) << 4;
    +		free(cal, M_DEVBUF);
    +
    +		idx = i / 2;
    +		if (i % 2)
    +			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
    +			    | ((val & 0x00ff) << 8);
    +		else
    +			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
    +			    | (val & 0x00ff);
    +		changed = 1;
    +	}
    +	if (changed) {
    +		for (i = 0; i < BWN_DC_LT_SIZE; i++)
    +			BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
    +	}
    +	bwn_mac_enable(mac);
    +}
    +
    +static void
    +bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
    +{
    +
    +	if (!rf->padmix)
    +		return;
    +	if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
    +		rf->att = 4;
    +}
    +
    +static void
    +bwn_lo_g_adjust(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
    +	struct bwn_lo_calib *cal;
    +	struct bwn_rfatt rf;
    +
    +	memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
    +	bwn_lo_fixup_rfatt(&rf);
    +
    +	cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
    +	if (!cal)
    +		return;
    +	bwn_lo_write(mac, &cal->ctl);
    +}
    +
    +static void
    +bwn_lo_g_init(struct bwn_mac *mac)
    +{
    +
    +	if (!bwn_has_hwpctl(mac))
    +		return;
    +
    +	bwn_lo_get_powervector(mac);
    +	bwn_phy_g_dc_lookup_init(mac, 1);
    +}
    +
    +static void
    +bwn_mac_suspend(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	int i;
    +	uint32_t tmp;
    +
    +	KASSERT(mac->mac_suspended >= 0,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	if (mac->mac_suspended == 0) {
    +		bwn_psctl(mac, BWN_PS_AWAKE);
    +		BWN_WRITE_4(mac, BWN_MACCTL,
    +			    BWN_READ_4(mac, BWN_MACCTL)
    +			    & ~BWN_MACCTL_ON);
    +		BWN_READ_4(mac, BWN_MACCTL);
    +		for (i = 35; i; i--) {
    +			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
    +			if (tmp & BWN_INTR_MAC_SUSPENDED)
    +				goto out;
    +			DELAY(10);
    +		}
    +		for (i = 40; i; i--) {
    +			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
    +			if (tmp & BWN_INTR_MAC_SUSPENDED)
    +				goto out;
    +			DELAY(1000);
    +		}
    +		device_printf(sc->sc_dev, "MAC suspend failed\n");
    +	}
    +out:
    +	mac->mac_suspended++;
    +}
    +
    +static void
    +bwn_mac_enable(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint16_t state;
    +
    +	state = bwn_shm_read_2(mac, BWN_SHARED,
    +	    BWN_SHARED_UCODESTAT);
    +	if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
    +	    state != BWN_SHARED_UCODESTAT_SLEEP)
    +		device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
    +
    +	mac->mac_suspended--;
    +	KASSERT(mac->mac_suspended >= 0,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	if (mac->mac_suspended == 0) {
    +		BWN_WRITE_4(mac, BWN_MACCTL,
    +		    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
    +		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
    +		BWN_READ_4(mac, BWN_MACCTL);
    +		BWN_READ_4(mac, BWN_INTR_REASON);
    +		bwn_psctl(mac, 0);
    +	}
    +}
    +
    +static void
    +bwn_psctl(struct bwn_mac *mac, uint32_t flags)
    +{
    +	int i;
    +	uint16_t ucstat;
    +
    +	KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	/* XXX forcibly awake and hwps-off */
    +
    +	BWN_WRITE_4(mac, BWN_MACCTL,
    +	    (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
    +	    ~BWN_MACCTL_HWPS);
    +	BWN_READ_4(mac, BWN_MACCTL);
    +	if (mac->mac_sd->sd_id.sd_rev >= 5) {
    +		for (i = 0; i < 100; i++) {
    +			ucstat = bwn_shm_read_2(mac, BWN_SHARED,
    +			    BWN_SHARED_UCODESTAT);
    +			if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
    +				break;
    +			DELAY(10);
    +		}
    +	}
    +}
    +
    +static int16_t
    +bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
    +{
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
    +	return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
    +}
    +
    +static void
    +bwn_nrssi_threshold(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct siba_softc *siba = mac->mac_sd->sd_bus;
    +	int32_t a, b;
    +	int16_t tmp16;
    +	uint16_t tmpu16;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
    +
    +	if (phy->gmode && (siba->siba_sprom.bf_lo & BWN_BFL_RSSI)) {
    +		if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
    +			a = 0x13;
    +			b = 0x12;
    +		} else {
    +			a = 0xe;
    +			b = 0x11;
    +		}
    +
    +		a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
    +		a += (pg->pg_nrssi[0] << 6);
    +		a += (a < 32) ? 31 : 32;
    +		a = a >> 6;
    +		a = MIN(MAX(a, -31), 31);
    +
    +		b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
    +		b += (pg->pg_nrssi[0] << 6);
    +		if (b < 32)
    +			b += 31;
    +		else
    +			b += 32;
    +		b = b >> 6;
    +		b = MIN(MAX(b, -31), 31);
    +
    +		tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
    +		tmpu16 |= ((uint32_t)b & 0x0000003f);
    +		tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
    +		BWN_PHY_WRITE(mac, 0x048a, tmpu16);
    +		return;
    +	}
    +
    +	tmp16 = bwn_nrssi_read(mac, 0x20);
    +	if (tmp16 >= 0x20)
    +		tmp16 -= 0x40;
    +	BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
    +}
    +
    +static void
    +bwn_nrssi_slope_11g(struct bwn_mac *mac)
    +{
    +#define	SAVE_RF_MAX		3
    +#define	SAVE_PHY_COMM_MAX	4
    +#define	SAVE_PHY3_MAX		8
    +	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
    +		{ 0x7a, 0x52, 0x43 };
    +	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
    +		{ 0x15, 0x5a, 0x59, 0x58 };
    +	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
    +		0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
    +		0x0801, 0x0060, 0x0014, 0x0478
    +	};
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	int32_t i, tmp32, phy3_idx = 0;
    +	uint16_t delta, tmp;
    +	uint16_t save_rf[SAVE_RF_MAX];
    +	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
    +	uint16_t save_phy3[SAVE_PHY3_MAX];
    +	uint16_t ant_div, phy0, chan_ex;
    +	int16_t nrssi0, nrssi1;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	if (phy->rf_rev >= 9)
    +		return;
    +	if (phy->rf_rev == 8)
    +		bwn_nrssi_offset(mac);
    +
    +	BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
    +	BWN_PHY_MASK(mac, 0x0802, 0xfffc);
    +
    +	/*
    +	 * Save RF/PHY registers for later restoration
    +	 */
    +	ant_div = BWN_READ_2(mac, 0x03e2);
    +	BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
    +	for (i = 0; i < SAVE_RF_MAX; ++i)
    +		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
    +	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
    +		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
    +
    +	phy0 = BWN_READ_2(mac, BWN_PHY0);
    +	chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
    +	if (phy->rev >= 3) {
    +		for (i = 0; i < SAVE_PHY3_MAX; ++i)
    +			save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
    +		BWN_PHY_WRITE(mac, 0x002e, 0);
    +		BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
    +		switch (phy->rev) {
    +		case 4:
    +		case 6:
    +		case 7:
    +			BWN_PHY_SET(mac, 0x0478, 0x0100);
    +			BWN_PHY_SET(mac, 0x0801, 0x0040);
    +			break;
    +		case 3:
    +		case 5:
    +			BWN_PHY_MASK(mac, 0x0801, 0xffbf);
    +			break;
    +		}
    +		BWN_PHY_SET(mac, 0x0060, 0x0040);
    +		BWN_PHY_SET(mac, 0x0014, 0x0200);
    +	}
    +	/*
    +	 * Calculate nrssi0
    +	 */
    +	BWN_RF_SET(mac, 0x007a, 0x0070);
    +	bwn_set_all_gains(mac, 0, 8, 0);
    +	BWN_RF_MASK(mac, 0x007a, 0x00f7);
    +	if (phy->rev >= 2) {
    +		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
    +		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
    +	}
    +	BWN_RF_SET(mac, 0x007a, 0x0080);
    +	DELAY(20);
    +
    +	nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
    +	if (nrssi0 >= 0x0020)
    +		nrssi0 -= 0x0040;
    +
    +	/*
    +	 * Calculate nrssi1
    +	 */
    +	BWN_RF_MASK(mac, 0x007a, 0x007f);
    +	if (phy->rev >= 2)
    +		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
    +
    +	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
    +	    BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
    +	BWN_RF_SET(mac, 0x007a, 0x000f);
    +	BWN_PHY_WRITE(mac, 0x0015, 0xf330);
    +	if (phy->rev >= 2) {
    +		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
    +		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
    +	}
    +
    +	bwn_set_all_gains(mac, 3, 0, 1);
    +	if (phy->rf_rev == 8) {
    +		BWN_RF_WRITE(mac, 0x0043, 0x001f);
    +	} else {
    +		tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
    +		BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
    +		tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
    +		BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
    +	}
    +	BWN_PHY_WRITE(mac, 0x005a, 0x0480);
    +	BWN_PHY_WRITE(mac, 0x0059, 0x0810);
    +	BWN_PHY_WRITE(mac, 0x0058, 0x000d);
    +	DELAY(20);
    +	nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
    +
    +	/*
    +	 * Install calculated narrow RSSI values
    +	 */
    +	if (nrssi1 >= 0x0020)
    +		nrssi1 -= 0x0040;
    +	if (nrssi0 == nrssi1)
    +		pg->pg_nrssi_slope = 0x00010000;
    +	else
    +		pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
    +	if (nrssi0 >= -4) {
    +		pg->pg_nrssi[0] = nrssi1;
    +		pg->pg_nrssi[1] = nrssi0;
    +	}
    +
    +	/*
    +	 * Restore saved RF/PHY registers
    +	 */
    +	if (phy->rev >= 3) {
    +		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
    +			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
    +			    save_phy3[phy3_idx]);
    +		}
    +	}
    +	if (phy->rev >= 2) {
    +		BWN_PHY_MASK(mac, 0x0812, 0xffcf);
    +		BWN_PHY_MASK(mac, 0x0811, 0xffcf);
    +	}
    +
    +	for (i = 0; i < SAVE_RF_MAX; ++i)
    +		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
    +
    +	BWN_WRITE_2(mac, 0x03e2, ant_div);
    +	BWN_WRITE_2(mac, 0x03e6, phy0);
    +	BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
    +
    +	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
    +		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
    +
    +	bwn_spu_workaround(mac, phy->chan);
    +	BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
    +	bwn_set_original_gains(mac);
    +	BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
    +	if (phy->rev >= 3) {
    +		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
    +			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
    +			    save_phy3[phy3_idx]);
    +		}
    +	}
    +
    +	delta = 0x1f - pg->pg_nrssi[0];
    +	for (i = 0; i < 64; i++) {
    +		tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
    +		tmp32 = MIN(MAX(tmp32, 0), 0x3f);
    +		pg->pg_nrssi_lt[i] = tmp32;
    +	}
    +
    +	bwn_nrssi_threshold(mac);
    +#undef SAVE_RF_MAX
    +#undef SAVE_PHY_COMM_MAX
    +#undef SAVE_PHY3_MAX
    +}
    +
    +static void
    +bwn_nrssi_offset(struct bwn_mac *mac)
    +{
    +#define	SAVE_RF_MAX		2
    +#define	SAVE_PHY_COMM_MAX	10
    +#define	SAVE_PHY6_MAX		8
    +	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
    +		{ 0x7a, 0x43 };
    +	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
    +		0x0001, 0x0811, 0x0812, 0x0814,
    +		0x0815, 0x005a, 0x0059, 0x0058,
    +		0x000a, 0x0003
    +	};
    +	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
    +		0x002e, 0x002f, 0x080f, 0x0810,
    +		0x0801, 0x0060, 0x0014, 0x0478
    +	};
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	int i, phy6_idx = 0;
    +	uint16_t save_rf[SAVE_RF_MAX];
    +	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
    +	uint16_t save_phy6[SAVE_PHY6_MAX];
    +	int16_t nrssi;
    +	uint16_t saved = 0xffff;
    +
    +	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
    +		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
    +	for (i = 0; i < SAVE_RF_MAX; ++i)
    +		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
    +
    +	BWN_PHY_MASK(mac, 0x0429, 0x7fff);
    +	BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
    +	BWN_PHY_SET(mac, 0x0811, 0x000c);
    +	BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
    +	BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
    +	if (phy->rev >= 6) {
    +		for (i = 0; i < SAVE_PHY6_MAX; ++i)
    +			save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
    +
    +		BWN_PHY_WRITE(mac, 0x002e, 0);
    +		BWN_PHY_WRITE(mac, 0x002f, 0);
    +		BWN_PHY_WRITE(mac, 0x080f, 0);
    +		BWN_PHY_WRITE(mac, 0x0810, 0);
    +		BWN_PHY_SET(mac, 0x0478, 0x0100);
    +		BWN_PHY_SET(mac, 0x0801, 0x0040);
    +		BWN_PHY_SET(mac, 0x0060, 0x0040);
    +		BWN_PHY_SET(mac, 0x0014, 0x0200);
    +	}
    +	BWN_RF_SET(mac, 0x007a, 0x0070);
    +	BWN_RF_SET(mac, 0x007a, 0x0080);
    +	DELAY(30);
    +
    +	nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
    +	if (nrssi >= 0x20)
    +		nrssi -= 0x40;
    +	if (nrssi == 31) {
    +		for (i = 7; i >= 4; i--) {
    +			BWN_RF_WRITE(mac, 0x007b, i);
    +			DELAY(20);
    +			nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
    +			    0x003f);
    +			if (nrssi >= 0x20)
    +				nrssi -= 0x40;
    +			if (nrssi < 31 && saved == 0xffff)
    +				saved = i;
    +		}
    +		if (saved == 0xffff)
    +			saved = 4;
    +	} else {
    +		BWN_RF_MASK(mac, 0x007a, 0x007f);
    +		if (phy->rev != 1) {
    +			BWN_PHY_SET(mac, 0x0814, 0x0001);
    +			BWN_PHY_MASK(mac, 0x0815, 0xfffe);
    +		}
    +		BWN_PHY_SET(mac, 0x0811, 0x000c);
    +		BWN_PHY_SET(mac, 0x0812, 0x000c);
    +		BWN_PHY_SET(mac, 0x0811, 0x0030);
    +		BWN_PHY_SET(mac, 0x0812, 0x0030);
    +		BWN_PHY_WRITE(mac, 0x005a, 0x0480);
    +		BWN_PHY_WRITE(mac, 0x0059, 0x0810);
    +		BWN_PHY_WRITE(mac, 0x0058, 0x000d);
    +		if (phy->rev == 0)
    +			BWN_PHY_WRITE(mac, 0x0003, 0x0122);
    +		else
    +			BWN_PHY_SET(mac, 0x000a, 0x2000);
    +		if (phy->rev != 1) {
    +			BWN_PHY_SET(mac, 0x0814, 0x0004);
    +			BWN_PHY_MASK(mac, 0x0815, 0xfffb);
    +		}
    +		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
    +		BWN_RF_SET(mac, 0x007a, 0x000f);
    +		bwn_set_all_gains(mac, 3, 0, 1);
    +		BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
    +		DELAY(30);
    +		nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
    +		if (nrssi >= 0x20)
    +			nrssi -= 0x40;
    +		if (nrssi == -32) {
    +			for (i = 0; i < 4; i++) {
    +				BWN_RF_WRITE(mac, 0x007b, i);
    +				DELAY(20);
    +				nrssi = (int16_t)((BWN_PHY_READ(mac,
    +				    0x047f) >> 8) & 0x003f);
    +				if (nrssi >= 0x20)
    +					nrssi -= 0x40;
    +				if (nrssi > -31 && saved == 0xffff)
    +					saved = i;
    +			}
    +			if (saved == 0xffff)
    +				saved = 3;
    +		} else
    +			saved = 0;
    +	}
    +	BWN_RF_WRITE(mac, 0x007b, saved);
    +
    +	/*
    +	 * Restore saved RF/PHY registers
    +	 */
    +	if (phy->rev >= 6) {
    +		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
    +			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
    +			    save_phy6[phy6_idx]);
    +		}
    +	}
    +	if (phy->rev != 1) {
    +		for (i = 3; i < 5; i++)
    +			BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
    +			    save_phy_comm[i]);
    +	}
    +	for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
    +		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
    +
    +	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
    +		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
    +
    +	BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
    +	BWN_PHY_SET(mac, 0x0429, 0x8000);
    +	bwn_set_original_gains(mac);
    +	if (phy->rev >= 6) {
    +		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
    +			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
    +			    save_phy6[phy6_idx]);
    +		}
    +	}
    +
    +	BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
    +	BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
    +	BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
    +}
    +
    +static void
    +bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
    +    int16_t third)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	uint16_t i;
    +	uint16_t start = 0x08, end = 0x18;
    +	uint16_t tmp;
    +	uint16_t table;
    +
    +	if (phy->rev <= 1) {
    +		start = 0x10;
    +		end = 0x20;
    +	}
    +
    +	table = BWN_OFDMTAB_GAINX;
    +	if (phy->rev <= 1)
    +		table = BWN_OFDMTAB_GAINX_R1;
    +	for (i = 0; i < 4; i++)
    +		bwn_ofdmtab_write_2(mac, table, i, first);
    +
    +	for (i = start; i < end; i++)
    +		bwn_ofdmtab_write_2(mac, table, i, second);
    +
    +	if (third != -1) {
    +		tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
    +		BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
    +		BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
    +		BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
    +	}
    +	bwn_dummy_transmission(mac, 0, 1);
    +}
    +
    +static void
    +bwn_set_original_gains(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	uint16_t i, tmp;
    +	uint16_t table;
    +	uint16_t start = 0x0008, end = 0x0018;
    +
    +	if (phy->rev <= 1) {
    +		start = 0x0010;
    +		end = 0x0020;
    +	}
    +
    +	table = BWN_OFDMTAB_GAINX;
    +	if (phy->rev <= 1)
    +		table = BWN_OFDMTAB_GAINX_R1;
    +	for (i = 0; i < 4; i++) {
    +		tmp = (i & 0xfffc);
    +		tmp |= (i & 0x0001) << 1;
    +		tmp |= (i & 0x0002) >> 1;
    +
    +		bwn_ofdmtab_write_2(mac, table, i, tmp);
    +	}
    +
    +	for (i = start; i < end; i++)
    +		bwn_ofdmtab_write_2(mac, table, i, i - start);
    +
    +	BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
    +	BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
    +	BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
    +	bwn_dummy_transmission(mac, 0, 1);
    +}
    +
    +static void
    +bwn_phy_hwpctl_init(struct bwn_mac *mac)
    +{
    +	struct siba_softc *bus = mac->mac_sd->sd_bus;
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_rfatt old_rfatt, rfatt;
    +	struct bwn_bbatt old_bbatt, bbatt;
    +	uint8_t old_txctl = 0;
    +
    +	KASSERT(phy->type == BWN_PHYTYPE_G,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	if ((bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM) &&
    +	    (bus->siba_board_type == SIBA_BOARD_BU4306))
    +		return;
    +
    +	BWN_PHY_WRITE(mac, 0x0028, 0x8018);
    +
    +	BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
    +
    +	if (!phy->gmode)
    +		return;
    +	bwn_hwpctl_early_init(mac);
    +	if (pg->pg_curtssi == 0) {
    +		if (phy->rf_ver == 0x2050 && phy->analog == 0) {
    +			BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
    +		} else {
    +			memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
    +			memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
    +			old_txctl = pg->pg_txctl;
    +
    +			bbatt.att = 11;
    +			if (phy->rf_rev == 8) {
    +				rfatt.att = 15;
    +				rfatt.padmix = 1;
    +			} else {
    +				rfatt.att = 9;
    +				rfatt.padmix = 0;
    +			}
    +			bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
    +		}
    +		bwn_dummy_transmission(mac, 0, 1);
    +		pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
    +		if (phy->rf_ver == 0x2050 && phy->analog == 0)
    +			BWN_RF_MASK(mac, 0x0076, 0xff7b);
    +		else
    +			bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
    +			    &old_rfatt, old_txctl);
    +	}
    +	bwn_hwpctl_init_gphy(mac);
    +
    +	/* clear TSSI */
    +	bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
    +	bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
    +	bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
    +	bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
    +}
    +
    +static void
    +bwn_hwpctl_early_init(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +
    +	if (!bwn_has_hwpctl(mac)) {
    +		BWN_PHY_WRITE(mac, 0x047a, 0xc111);
    +		return;
    +	}
    +
    +	BWN_PHY_MASK(mac, 0x0036, 0xfeff);
    +	BWN_PHY_WRITE(mac, 0x002f, 0x0202);
    +	BWN_PHY_SET(mac, 0x047c, 0x0002);
    +	BWN_PHY_SET(mac, 0x047a, 0xf000);
    +	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
    +		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
    +		BWN_PHY_SET(mac, 0x005d, 0x8000);
    +		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
    +		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
    +		BWN_PHY_SET(mac, 0x0036, 0x0400);
    +	} else {
    +		BWN_PHY_SET(mac, 0x0036, 0x0200);
    +		BWN_PHY_SET(mac, 0x0036, 0x0400);
    +		BWN_PHY_MASK(mac, 0x005d, 0x7fff);
    +		BWN_PHY_MASK(mac, 0x004f, 0xfffe);
    +		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
    +		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
    +		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
    +	}
    +}
    +
    +static void
    +bwn_hwpctl_init_gphy(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
    +	int i;
    +	uint16_t nr_written = 0, tmp, value;
    +	uint8_t rf, bb;
    +
    +	if (!bwn_has_hwpctl(mac)) {
    +		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
    +		return;
    +	}
    +
    +	BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
    +	    (pg->pg_idletssi - pg->pg_curtssi));
    +	BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
    +	    (pg->pg_idletssi - pg->pg_curtssi));
    +
    +	for (i = 0; i < 32; i++)
    +		bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
    +	for (i = 32; i < 64; i++)
    +		bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
    +	for (i = 0; i < 64; i += 2) {
    +		value = (uint16_t) pg->pg_tssi2dbm[i];
    +		value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
    +		BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
    +	}
    +
    +	for (rf = 0; rf < lo->rfatt.len; rf++) {
    +		for (bb = 0; bb < lo->bbatt.len; bb++) {
    +			if (nr_written >= 0x40)
    +				return;
    +			tmp = lo->bbatt.array[bb].att;
    +			tmp <<= 8;
    +			if (phy->rf_rev == 8)
    +				tmp |= 0x50;
    +			else
    +				tmp |= 0x40;
    +			tmp |= lo->rfatt.array[rf].att;
    +			BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
    +			nr_written++;
    +		}
    +	}
    +
    +	BWN_PHY_MASK(mac, 0x0060, 0xffbf);
    +	BWN_PHY_WRITE(mac, 0x0014, 0x0000);
    +
    +	KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
    +	BWN_PHY_SET(mac, 0x0478, 0x0800);
    +	BWN_PHY_MASK(mac, 0x0478, 0xfeff);
    +	BWN_PHY_MASK(mac, 0x0801, 0xffbf);
    +
    +	bwn_phy_g_dc_lookup_init(mac, 1);
    +	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
    +}
    +
    +static void
    +bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
    +{
    +	struct siba_softc *siba = mac->mac_sd->sd_bus;
    +
    +	if (spu != 0)
    +		bwn_spu_workaround(mac, channel);
    +
    +	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
    +
    +	if (channel == 14) {
    +		if (siba->siba_sprom.ccode == SIBA_CCODE_JAPAN)
    +			bwn_hf_write(mac,
    +			    bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
    +		else
    +			bwn_hf_write(mac,
    +			    bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
    +		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
    +		    BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
    +		return;
    +	}
    +
    +	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
    +	    BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
    +}
    +
    +static uint16_t
    +bwn_phy_g_chan2freq(uint8_t channel)
    +{
    +	static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
    +
    +	KASSERT(channel >= 1 && channel <= 14,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	return (bwn_phy_g_rf_channels[channel - 1]);
    +}
    +
    +static void
    +bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
    +    const struct bwn_rfatt *rfatt, uint8_t txctl)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
    +	uint16_t bb, rf;
    +	uint16_t tx_bias, tx_magn;
    +
    +	bb = bbatt->att;
    +	rf = rfatt->att;
    +	tx_bias = lo->tx_bias;
    +	tx_magn = lo->tx_magn;
    +	if (tx_bias == 0xff)
    +		tx_bias = 0;
    +
    +	pg->pg_txctl = txctl;
    +	memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
    +	pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
    +	memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
    +	bwn_phy_g_set_bbatt(mac, bb);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
    +	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
    +		BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
    +	else {
    +		BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
    +		BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
    +	}
    +	if (BWN_HAS_TXMAG(phy))
    +		BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
    +	else
    +		BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
    +	bwn_lo_g_adjust(mac);
    +}
    +
    +static void
    +bwn_phy_g_set_bbatt(struct bwn_mac *mac,
    +    uint16_t bbatt)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +
    +	if (phy->analog == 0) {
    +		BWN_WRITE_2(mac, BWN_PHY0,
    +		    (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
    +		return;
    +	}
    +	if (phy->analog > 1) {
    +		BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
    +		return;
    +	}
    +	BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
    +}
    +
    +static uint16_t
    +bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct siba_sprom *sprom = &(mac->mac_sd->sd_bus->siba_sprom);
    +	int max_lb_gain;
    +	uint16_t extlna;
    +	uint16_t i;
    +
    +	if (phy->gmode == 0)
    +		return (0);
    +
    +	if (BWN_HAS_LOOPBACK(phy)) {
    +		max_lb_gain = pg->pg_max_lb_gain;
    +		max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
    +		if (max_lb_gain >= 0x46) {
    +			extlna = 0x3000;
    +			max_lb_gain -= 0x46;
    +		} else if (max_lb_gain >= 0x3a) {
    +			extlna = 0x1000;
    +			max_lb_gain -= 0x3a;
    +		} else if (max_lb_gain >= 0x2e) {
    +			extlna = 0x2000;
    +			max_lb_gain -= 0x2e;
    +		} else {
    +			extlna = 0;
    +			max_lb_gain -= 0x10;
    +		}
    +
    +		for (i = 0; i < 16; i++) {
    +			max_lb_gain -= (i * 6);
    +			if (max_lb_gain < 6)
    +				break;
    +		}
    +
    +		if ((phy->rev < 7) || !(sprom->bf_lo & BWN_BFL_EXTLNA)) {
    +			if (reg == BWN_PHY_RFOVER) {
    +				return (0x1b3);
    +			} else if (reg == BWN_PHY_RFOVERVAL) {
    +				extlna |= (i << 8);
    +				switch (lpd) {
    +				case BWN_LPD(0, 1, 1):
    +					return (0x0f92);
    +				case BWN_LPD(0, 0, 1):
    +				case BWN_LPD(1, 0, 1):
    +					return (0x0092 | extlna);
    +				case BWN_LPD(1, 0, 0):
    +					return (0x0093 | extlna);
    +				}
    +				KASSERT(0 == 1,
    +				    ("%s:%d: fail", __func__, __LINE__));
    +			}
    +			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +		} else {
    +			if (reg == BWN_PHY_RFOVER)
    +				return (0x9b3);
    +			if (reg == BWN_PHY_RFOVERVAL) {
    +				if (extlna)
    +					extlna |= 0x8000;
    +				extlna |= (i << 8);
    +				switch (lpd) {
    +				case BWN_LPD(0, 1, 1):
    +					return (0x8f92);
    +				case BWN_LPD(0, 0, 1):
    +					return (0x8092 | extlna);
    +				case BWN_LPD(1, 0, 1):
    +					return (0x2092 | extlna);
    +				case BWN_LPD(1, 0, 0):
    +					return (0x2093 | extlna);
    +				}
    +				KASSERT(0 == 1,
    +				    ("%s:%d: fail", __func__, __LINE__));
    +			}
    +			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +		}
    +		return (0);
    +	}
    +
    +	if ((phy->rev < 7) ||
    +	    !(sprom->bf_lo & BWN_BFL_EXTLNA)) {
    +		if (reg == BWN_PHY_RFOVER) {
    +			return (0x1b3);
    +		} else if (reg == BWN_PHY_RFOVERVAL) {
    +			switch (lpd) {
    +			case BWN_LPD(0, 1, 1):
    +				return (0x0fb2);
    +			case BWN_LPD(0, 0, 1):
    +				return (0x00b2);
    +			case BWN_LPD(1, 0, 1):
    +				return (0x30b2);
    +			case BWN_LPD(1, 0, 0):
    +				return (0x30b3);
    +			}
    +			KASSERT(0 == 1,
    +			    ("%s:%d: fail", __func__, __LINE__));
    +		}
    +		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	} else {
    +		if (reg == BWN_PHY_RFOVER) {
    +			return (0x9b3);
    +		} else if (reg == BWN_PHY_RFOVERVAL) {
    +			switch (lpd) {
    +			case BWN_LPD(0, 1, 1):
    +				return (0x8fb2);
    +			case BWN_LPD(0, 0, 1):
    +				return (0x80b2);
    +			case BWN_LPD(1, 0, 1):
    +				return (0x20b2);
    +			case BWN_LPD(1, 0, 0):
    +				return (0x20b3);
    +			}
    +			KASSERT(0 == 1,
    +			    ("%s:%d: fail", __func__, __LINE__));
    +		}
    +		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	}
    +	return (0);
    +}
    +
    +static void
    +bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
    +{
    +
    +	if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
    +		return;
    +	BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
    +	    bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
    +	DELAY(1000);
    +	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
    +}
    +
    +static int
    +bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_fw *fw = &mac->mac_fw;
    +	const uint8_t rev = mac->mac_sd->sd_id.sd_rev;
    +	const char *filename;
    +	uint32_t high;
    +	int error;
    +
    +	/* microcode */
    +	if (rev >= 5 && rev <= 10)
    +		filename = "ucode5";
    +	else if (rev >= 11 && rev <= 12)
    +		filename = "ucode11";
    +	else if (rev == 13)
    +		filename = "ucode13";
    +	else if (rev == 14)
    +		filename = "ucode14";
    +	else if (rev >= 15)
    +		filename = "ucode15";
    +	else {
    +		device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
    +		bwn_release_firmware(mac);
    +		return (EOPNOTSUPP);
    +	}
    +	error = bwn_fw_get(mac, type, filename, &fw->ucode);
    +	if (error) {
    +		bwn_release_firmware(mac);
    +		return (error);
    +	}
    +
    +	/* PCM */
    +	KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
    +	if (rev >= 5 && rev <= 10) {
    +		error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
    +		if (error == ENOENT)
    +			fw->no_pcmfile = 1;
    +		else if (error) {
    +			bwn_release_firmware(mac);
    +			return (error);
    +		}
    +	} else if (rev < 11) {
    +		device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
    +		return (EOPNOTSUPP);
    +	}
    +
    +	/* initvals */
    +	high = siba_read_4(mac->mac_sd, SIBA_TGSHIGH);
    +	switch (mac->mac_phy.type) {
    +	case BWN_PHYTYPE_A:
    +		if (rev < 5 || rev > 10)
    +			goto fail1;
    +		if (high & BWN_TGSHIGH_HAVE_2GHZ)
    +			filename = "a0g1initvals5";
    +		else
    +			filename = "a0g0initvals5";
    +		break;
    +	case BWN_PHYTYPE_G:
    +		if (rev >= 5 && rev <= 10)
    +			filename = "b0g0initvals5";
    +		else if (rev >= 13)
    +			filename = "b0g0initvals13";
    +		else
    +			goto fail1;
    +		break;
    +	case BWN_PHYTYPE_LP:
    +		if (rev == 13)
    +			filename = "lp0initvals13";
    +		else if (rev == 14)
    +			filename = "lp0initvals14";
    +		else if (rev >= 15)
    +			filename = "lp0initvals15";
    +		else
    +			goto fail1;
    +		break;
    +	case BWN_PHYTYPE_N:
    +		if (rev >= 11 && rev <= 12)
    +			filename = "n0initvals11";
    +		else
    +			goto fail1;
    +		break;
    +	default:
    +		goto fail1;
    +	}
    +	error = bwn_fw_get(mac, type, filename, &fw->initvals);
    +	if (error) {
    +		bwn_release_firmware(mac);
    +		return (error);
    +	}
    +
    +	/* bandswitch initvals */
    +	switch (mac->mac_phy.type) {
    +	case BWN_PHYTYPE_A:
    +		if (rev >= 5 && rev <= 10) {
    +			if (high & BWN_TGSHIGH_HAVE_2GHZ)
    +				filename = "a0g1bsinitvals5";
    +			else
    +				filename = "a0g0bsinitvals5";
    +		} else if (rev >= 11)
    +			filename = NULL;
    +		else
    +			goto fail1;
    +		break;
    +	case BWN_PHYTYPE_G:
    +		if (rev >= 5 && rev <= 10)
    +			filename = "b0g0bsinitvals5";
    +		else if (rev >= 11)
    +			filename = NULL;
    +		else
    +			goto fail1;
    +		break;
    +	case BWN_PHYTYPE_LP:
    +		if (rev == 13)
    +			filename = "lp0bsinitvals13";
    +		else if (rev == 14)
    +			filename = "lp0bsinitvals14";
    +		else if (rev >= 15)
    +			filename = "lp0bsinitvals15";
    +		else
    +			goto fail1;
    +		break;
    +	case BWN_PHYTYPE_N:
    +		if (rev >= 11 && rev <= 12)
    +			filename = "n0bsinitvals11";
    +		else
    +			goto fail1;
    +		break;
    +	default:
    +		goto fail1;
    +	}
    +	error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
    +	if (error) {
    +		bwn_release_firmware(mac);
    +		return (error);
    +	}
    +	return (0);
    +fail1:
    +	device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
    +	bwn_release_firmware(mac);
    +	return (EOPNOTSUPP);
    +}
    +
    +static int
    +bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
    +    const char *name, struct bwn_fwfile *bfw)
    +{
    +	const struct bwn_fwhdr *hdr;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	const struct firmware *fw;
    +	char namebuf[64];
    +
    +	if (name == NULL) {
    +		bwn_do_release_fw(bfw);
    +		return (0);
    +	}
    +	if (bfw->filename != NULL) {
    +		if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
    +			return (0);
    +		bwn_do_release_fw(bfw);
    +	}
    +
    +	snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s",
    +	    (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", name);
    +	/* XXX Sleeping on "fwload" with the non-sleepable locks held */
    +	fw = firmware_get(namebuf);
    +	if (fw == NULL) {
    +		device_printf(sc->sc_dev, "the fw file(%s) not found\n",
    +		    namebuf);
    +		return (ENOENT);
    +	}
    +	if (fw->datasize < sizeof(struct bwn_fwhdr))
    +		goto fail;
    +	hdr = (const struct bwn_fwhdr *)(fw->data);
    +	switch (hdr->type) {
    +	case BWN_FWTYPE_UCODE:
    +	case BWN_FWTYPE_PCM:
    +		if (be32toh(hdr->size) !=
    +		    (fw->datasize - sizeof(struct bwn_fwhdr)))
    +			goto fail;
    +		/* FALLTHROUGH */
    +	case BWN_FWTYPE_IV:
    +		if (hdr->ver != 1)
    +			goto fail;
    +		break;
    +	default:
    +		goto fail;
    +	}
    +	bfw->filename = name;
    +	bfw->fw = fw;
    +	bfw->type = type;
    +	return (0);
    +fail:
    +	device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
    +	if (fw != NULL)
    +		firmware_put(fw, FIRMWARE_UNLOAD);
    +	return (EPROTO);
    +}
    +
    +static void
    +bwn_release_firmware(struct bwn_mac *mac)
    +{
    +
    +	bwn_do_release_fw(&mac->mac_fw.ucode);
    +	bwn_do_release_fw(&mac->mac_fw.pcm);
    +	bwn_do_release_fw(&mac->mac_fw.initvals);
    +	bwn_do_release_fw(&mac->mac_fw.initvals_band);
    +}
    +
    +static void
    +bwn_do_release_fw(struct bwn_fwfile *bfw)
    +{
    +
    +	if (bfw->fw != NULL)
    +		firmware_put(bfw->fw, FIRMWARE_UNLOAD);
    +	bfw->fw = NULL;
    +	bfw->filename = NULL;
    +}
    +
    +static int
    +bwn_fw_loaducode(struct bwn_mac *mac)
    +{
    +#define	GETFWOFFSET(fwp, offset)	\
    +	((const uint32_t *)((const char *)fwp.fw->data + offset))
    +#define	GETFWSIZE(fwp, offset)	\
    +	((fwp.fw->datasize - offset) / sizeof(uint32_t))
    +	struct bwn_softc *sc = mac->mac_sc;
    +	const uint32_t *data;
    +	unsigned int i;
    +	uint32_t ctl;
    +	uint16_t date, fwcaps, time;
    +	int error = 0;
    +
    +	ctl = BWN_READ_4(mac, BWN_MACCTL);
    +	ctl |= BWN_MACCTL_MCODE_JMP0;
    +	KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
    +	    __LINE__));
    +	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
    +	for (i = 0; i < 64; i++)
    +		bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
    +	for (i = 0; i < 4096; i += 2)
    +		bwn_shm_write_2(mac, BWN_SHARED, i, 0);
    +
    +	data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
    +	bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
    +	for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
    +	     i++) {
    +		BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
    +		DELAY(10);
    +	}
    +
    +	if (mac->mac_fw.pcm.fw) {
    +		data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
    +		bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
    +		BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
    +		bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
    +		for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
    +		    sizeof(struct bwn_fwhdr)); i++) {
    +			BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
    +			DELAY(10);
    +		}
    +	}
    +
    +	BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
    +	BWN_WRITE_4(mac, BWN_MACCTL,
    +	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
    +	    BWN_MACCTL_MCODE_RUN);
    +
    +	for (i = 0; i < 21; i++) {
    +		if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
    +			break;
    +		if (i >= 20) {
    +			device_printf(sc->sc_dev, "ucode timeout\n");
    +			error = ENXIO;
    +			goto error;
    +		}
    +		DELAY(50000);
    +	}
    +	BWN_READ_4(mac, BWN_INTR_REASON);
    +
    +	mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
    +	if (mac->mac_fw.rev <= 0x128) {
    +		device_printf(sc->sc_dev, "the firmware is too old\n");
    +		error = EOPNOTSUPP;
    +		goto error;
    +	}
    +	mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
    +	    BWN_SHARED_UCODE_PATCH);
    +	date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
    +	mac->mac_fw.opensource = (date == 0xffff);
    +	if (bwn_wme != 0)
    +		mac->mac_flags |= BWN_MAC_FLAG_WME;
    +	mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
    +
    +	time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
    +	if (mac->mac_fw.opensource == 0) {
    +		device_printf(sc->sc_dev,
    +		    "firmware version (rev %u patch %u date %#x time %#x)\n",
    +		    mac->mac_fw.rev, mac->mac_fw.patch, date, time);
    +		if (mac->mac_fw.no_pcmfile)
    +			device_printf(sc->sc_dev,
    +			    "no HW crypto acceleration due to pcm5\n");
    +	} else {
    +		mac->mac_fw.patch = time;
    +		fwcaps = bwn_fwcaps_read(mac);
    +		if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
    +			device_printf(sc->sc_dev,
    +			    "disabling HW crypto acceleration\n");
    +			mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
    +		}
    +		if (!(fwcaps & BWN_FWCAPS_WME)) {
    +			device_printf(sc->sc_dev, "disabling WME support\n");
    +			mac->mac_flags &= ~BWN_MAC_FLAG_WME;
    +		}
    +	}
    +
    +	if (BWN_ISOLDFMT(mac))
    +		device_printf(sc->sc_dev, "using old firmware image\n");
    +
    +	return (0);
    +
    +error:
    +	BWN_WRITE_4(mac, BWN_MACCTL,
    +	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
    +	    BWN_MACCTL_MCODE_JMP0);
    +
    +	return (error);
    +#undef GETFWSIZE
    +#undef GETFWOFFSET
    +}
    +
    +/* OpenFirmware only */
    +static uint16_t
    +bwn_fwcaps_read(struct bwn_mac *mac)
    +{
    +
    +	KASSERT(mac->mac_fw.opensource == 1,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
    +}
    +
    +static int
    +bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
    +    size_t count, size_t array_size)
    +{
    +#define	GET_NEXTIV16(iv)						\
    +	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
    +	    sizeof(uint16_t) + sizeof(uint16_t)))
    +#define	GET_NEXTIV32(iv)						\
    +	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
    +	    sizeof(uint16_t) + sizeof(uint32_t)))
    +	struct bwn_softc *sc = mac->mac_sc;
    +	const struct bwn_fwinitvals *iv;
    +	uint16_t offset;
    +	size_t i;
    +	uint8_t bit32;
    +
    +	KASSERT(sizeof(struct bwn_fwinitvals) == 6,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	iv = ivals;
    +	for (i = 0; i < count; i++) {
    +		if (array_size < sizeof(iv->offset_size))
    +			goto fail;
    +		array_size -= sizeof(iv->offset_size);
    +		offset = be16toh(iv->offset_size);
    +		bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
    +		offset &= BWN_FWINITVALS_OFFSET_MASK;
    +		if (offset >= 0x1000)
    +			goto fail;
    +		if (bit32) {
    +			if (array_size < sizeof(iv->data.d32))
    +				goto fail;
    +			array_size -= sizeof(iv->data.d32);
    +			BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
    +			iv = GET_NEXTIV32(iv);
    +		} else {
    +
    +			if (array_size < sizeof(iv->data.d16))
    +				goto fail;
    +			array_size -= sizeof(iv->data.d16);
    +			BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
    +
    +			iv = GET_NEXTIV16(iv);
    +		}
    +	}
    +	if (array_size != 0)
    +		goto fail;
    +	return (0);
    +fail:
    +	device_printf(sc->sc_dev, "initvals: invalid format\n");
    +	return (EPROTO);
    +#undef GET_NEXTIV16
    +#undef GET_NEXTIV32
    +}
    +
    +static int
    +bwn_switch_channel(struct bwn_mac *mac, int chan)
    +{
    +	struct bwn_phy *phy = &(mac->mac_phy);
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	uint16_t channelcookie, savedcookie;
    +	int error;
    +
    +	if (chan == 0xffff)
    +		chan = phy->get_default_chan(mac);
    +
    +	channelcookie = chan;
    +	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
    +		channelcookie |= 0x100;
    +	savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
    +	error = phy->switch_channel(mac, chan);
    +	if (error)
    +		goto fail;
    +
    +	mac->mac_phy.chan = chan;
    +	DELAY(8000);
    +	return (0);
    +fail:
    +	device_printf(sc->sc_dev, "failed to switch channel\n");
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
    +	return (error);
    +}
    +
    +static uint16_t
    +bwn_ant2phy(int antenna)
    +{
    +
    +	switch (antenna) {
    +	case BWN_ANT0:
    +		return (BWN_TX_PHY_ANT0);
    +	case BWN_ANT1:
    +		return (BWN_TX_PHY_ANT1);
    +	case BWN_ANT2:
    +		return (BWN_TX_PHY_ANT2);
    +	case BWN_ANT3:
    +		return (BWN_TX_PHY_ANT3);
    +	case BWN_ANTAUTO:
    +		return (BWN_TX_PHY_ANT01AUTO);
    +	}
    +	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	return (0);
    +}
    +
    +static void
    +bwn_wme_load(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	int i;
    +
    +	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	bwn_mac_suspend(mac);
    +	for (i = 0; i < N(sc->sc_wmeParams); i++)
    +		bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
    +		    bwn_wme_shm_offsets[i]);
    +	bwn_mac_enable(mac);
    +}
    +
    +static void
    +bwn_wme_loadparams(struct bwn_mac *mac,
    +    const struct wmeParams *p, uint16_t shm_offset)
    +{
    +#define	SM(_v, _f)      (((_v) << _f##_S) & _f)
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint16_t params[BWN_NR_WMEPARAMS];
    +	int slot, tmp;
    +	unsigned int i;
    +
    +	slot = BWN_READ_2(mac, BWN_RNG) &
    +	    SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
    +
    +	memset(¶ms, 0, sizeof(params));
    +
    +	DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
    +	    "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
    +	    p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
    +
    +	params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
    +	params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
    +	params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
    +	params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
    +	params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
    +	params[BWN_WMEPARAM_BSLOTS] = slot;
    +	params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
    +
    +	for (i = 0; i < N(params); i++) {
    +		if (i == BWN_WMEPARAM_STATUS) {
    +			tmp = bwn_shm_read_2(mac, BWN_SHARED,
    +			    shm_offset + (i * 2));
    +			tmp |= 0x100;
    +			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
    +			    tmp);
    +		} else {
    +			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
    +			    params[i]);
    +		}
    +	}
    +}
    +
    +static void
    +bwn_mac_write_bssid(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint32_t tmp;
    +	int i;
    +	uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
    +
    +	bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
    +	memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
    +	memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
    +	    IEEE80211_ADDR_LEN);
    +
    +	for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
    +		tmp = (uint32_t) (mac_bssid[i + 0]);
    +		tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
    +		tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
    +		tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
    +		bwn_ram_write(mac, 0x20 + i, tmp);
    +	}
    +}
    +
    +static void
    +bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
    +    const uint8_t *macaddr)
    +{
    +	static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
    +	uint16_t data;
    +
    +	if (!mac)
    +		macaddr = zero;
    +
    +	offset |= 0x0020;
    +	BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
    +
    +	data = macaddr[0];
    +	data |= macaddr[1] << 8;
    +	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
    +	data = macaddr[2];
    +	data |= macaddr[3] << 8;
    +	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
    +	data = macaddr[4];
    +	data |= macaddr[5] << 8;
    +	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
    +}
    +
    +static void
    +bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
    +    const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
    +{
    +	uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
    +	uint8_t per_sta_keys_start = 8;
    +
    +	if (BWN_SEC_NEWAPI(mac))
    +		per_sta_keys_start = 4;
    +
    +	KASSERT(index < mac->mac_max_nr_keys,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	KASSERT(key_len <= BWN_SEC_KEYSIZE,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	if (index >= per_sta_keys_start)
    +		bwn_key_macwrite(mac, index, NULL);
    +	if (key)
    +		memcpy(buf, key, key_len);
    +	bwn_key_write(mac, index, algorithm, buf);
    +	if (index >= per_sta_keys_start)
    +		bwn_key_macwrite(mac, index, mac_addr);
    +
    +	mac->mac_key[index].algorithm = algorithm;
    +}
    +
    +static void
    +bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
    +{
    +	uint32_t addrtmp[2] = { 0, 0 };
    +	uint8_t start = 8;
    +
    +	if (BWN_SEC_NEWAPI(mac))
    +		start = 4;
    +
    +	KASSERT(index >= start,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	index -= start;
    +
    +	if (addr) {
    +		addrtmp[0] = addr[0];
    +		addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
    +		addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
    +		addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
    +		addrtmp[1] = addr[4];
    +		addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
    +	}
    +
    +	if (mac->mac_sd->sd_id.sd_rev >= 5) {
    +		bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
    +		bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
    +	} else {
    +		if (index >= 8) {
    +			bwn_shm_write_4(mac, BWN_SHARED,
    +			    BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
    +			bwn_shm_write_2(mac, BWN_SHARED,
    +			    BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
    +		}
    +	}
    +}
    +
    +static void
    +bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
    +    const uint8_t *key)
    +{
    +	unsigned int i;
    +	uint32_t offset;
    +	uint16_t kidx, value;
    +
    +	kidx = BWN_SEC_KEY2FW(mac, index);
    +	bwn_shm_write_2(mac, BWN_SHARED,
    +	    BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
    +
    +	offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
    +	for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
    +		value = key[i];
    +		value |= (uint16_t)(key[i + 1]) << 8;
    +		bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
    +	}
    +}
    +
    +static void
    +bwn_phy_exit(struct bwn_mac *mac)
    +{
    +
    +	mac->mac_phy.rf_onoff(mac, 0);
    +	if (mac->mac_phy.exit != NULL)
    +		mac->mac_phy.exit(mac);
    +}
    +
    +static void
    +bwn_dma_free(struct bwn_mac *mac)
    +{
    +	struct bwn_dma *dma;
    +
    +	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
    +		return;
    +	dma = &mac->mac_method.dma;
    +
    +	bwn_dma_ringfree(&dma->rx);
    +	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
    +	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
    +	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
    +	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
    +	bwn_dma_ringfree(&dma->mcast);
    +}
    +
    +static void
    +bwn_core_stop(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
    +		return;
    +
    +	callout_stop(&sc->sc_rfswitch_ch);
    +	callout_stop(&sc->sc_task_ch);
    +	callout_stop(&sc->sc_watchdog_ch);
    +	sc->sc_watchdog_timer = 0;
    +	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
    +	BWN_READ_4(mac, BWN_INTR_MASK);
    +	bwn_mac_suspend(mac);
    +
    +	mac->mac_status = BWN_MAC_STATUS_INITED;
    +}
    +
    +static int
    +bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
    +{
    +	struct bwn_mac *up_dev = NULL;
    +	struct bwn_mac *down_dev;
    +	struct bwn_mac *mac;
    +	int err, status;
    +	uint8_t gmode;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
    +		if (IEEE80211_IS_CHAN_2GHZ(chan) &&
    +		    mac->mac_phy.supports_2ghz) {
    +			up_dev = mac;
    +			gmode = 1;
    +		} else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
    +		    mac->mac_phy.supports_5ghz) {
    +			up_dev = mac;
    +			gmode = 0;
    +		} else {
    +			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +			return (EINVAL);
    +		}
    +		if (up_dev != NULL)
    +			break;
    +	}
    +	if (up_dev == NULL) {
    +		device_printf(sc->sc_dev, "Could not find a device\n");
    +		return (ENODEV);
    +	}
    +	if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
    +		return (0);
    +
    +	device_printf(sc->sc_dev, "switching to %s-GHz band\n",
    +	    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
    +
    +	down_dev = sc->sc_curmac;;
    +	status = down_dev->mac_status;
    +	if (status >= BWN_MAC_STATUS_STARTED)
    +		bwn_core_stop(down_dev);
    +	if (status >= BWN_MAC_STATUS_INITED)
    +		bwn_core_exit(down_dev);
    +
    +	if (down_dev != up_dev)
    +		bwn_phy_reset(down_dev);
    +
    +	up_dev->mac_phy.gmode = gmode;
    +	if (status >= BWN_MAC_STATUS_INITED) {
    +		err = bwn_core_init(up_dev);
    +		if (err) {
    +			device_printf(sc->sc_dev,
    +			    "fatal: failed to initialize for %s-GHz\n",
    +			    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
    +			goto fail;
    +		}
    +	}
    +	if (status >= BWN_MAC_STATUS_STARTED)
    +		bwn_core_start(up_dev);
    +	KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
    +	sc->sc_curmac = up_dev;
    +
    +	return (0);
    +fail:
    +	sc->sc_curmac = NULL;
    +	return (err);
    +}
    +
    +static void
    +bwn_rf_turnon(struct bwn_mac *mac)
    +{
    +
    +	bwn_mac_suspend(mac);
    +	mac->mac_phy.rf_onoff(mac, 1);
    +	mac->mac_phy.rf_on = 1;
    +	bwn_mac_enable(mac);
    +}
    +
    +static void
    +bwn_rf_turnoff(struct bwn_mac *mac)
    +{
    +
    +	bwn_mac_suspend(mac);
    +	mac->mac_phy.rf_onoff(mac, 0);
    +	mac->mac_phy.rf_on = 0;
    +	bwn_mac_enable(mac);
    +}
    +
    +static void
    +bwn_phy_reset(struct bwn_mac *mac)
    +{
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +
    +	siba_write_4(sd, SIBA_TGSLOW,
    +	    ((siba_read_4(sd, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
    +	     BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
    +	DELAY(1000);
    +	siba_write_4(sd, SIBA_TGSLOW,
    +	    (siba_read_4(sd, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
    +	    BWN_TGSLOW_PHYRESET);
    +	DELAY(1000);
    +}
    +
    +static int
    +bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
    +{
    +	struct bwn_vap *bvp = BWN_VAP(vap);
    +	struct ieee80211com *ic= vap->iv_ic;
    +	struct ifnet *ifp = ic->ic_ifp;
    +	enum ieee80211_state ostate = vap->iv_state;
    +	struct bwn_softc *sc = ifp->if_softc;
    +	struct bwn_mac *mac = sc->sc_curmac;
    +	int error;
    +
    +	DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
    +	    ieee80211_state_name[vap->iv_state],
    +	    ieee80211_state_name[nstate]);
    +
    +	error = bvp->bv_newstate(vap, nstate, arg);
    +	if (error != 0)
    +		return (error);
    +
    +	BWN_LOCK(sc);
    +
    +	bwn_led_newstate(mac, nstate);
    +
    +	/*
    +	 * Clear the BSSID when we stop a STA
    +	 */
    +	if (vap->iv_opmode == IEEE80211_M_STA) {
    +		if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
    +			/*
    +			 * Clear out the BSSID.  If we reassociate to
    +			 * the same AP, this will reinialize things
    +			 * correctly...
    +			 */
    +			if (ic->ic_opmode == IEEE80211_M_STA &&
    +			    (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
    +				memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
    +				bwn_set_macaddr(mac);
    +			}
    +		}
    +	}
    +
    +	if (vap->iv_opmode == IEEE80211_M_MONITOR) {
    +		/* XXX nothing to do? */
    +	} else if (nstate == IEEE80211_S_RUN) {
    +		memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
    +		memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
    +		bwn_set_opmode(mac);
    +		bwn_set_pretbtt(mac);
    +		bwn_spu_setdelay(mac, 0);
    +		bwn_set_macaddr(mac);
    +	}
    +
    +	BWN_UNLOCK(sc);
    +
    +	return (error);
    +}
    +
    +static void
    +bwn_set_pretbtt(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	uint16_t pretbtt;
    +
    +	if (ic->ic_opmode == IEEE80211_M_IBSS)
    +		pretbtt = 2;
    +	else
    +		pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
    +	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
    +	BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
    +}
    +
    +static int
    +bwn_intr(void *arg)
    +{
    +	struct bwn_mac *mac = arg;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct siba_softc *siba = mac->mac_sd->sd_bus;
    +	uint32_t reason;
    +
    +	if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid)
    +		return (FILTER_STRAY);
    +
    +	reason = BWN_READ_4(mac, BWN_INTR_REASON);
    +	if (reason == 0xffffffff)	/* shared IRQ */
    +		return (FILTER_STRAY);
    +	reason &= mac->mac_intr_mask;
    +	if (reason == 0)
    +		return (FILTER_HANDLED);
    +
    +	mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
    +	mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
    +	mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
    +	mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
    +	mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
    +	BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
    +	BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
    +	BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
    +	BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
    +	BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
    +	BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
    +
    +	/* Disable interrupts. */
    +	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
    +
    +	mac->mac_reason_intr = reason;
    +
    +	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
    +	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
    +
    +	taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
    +	return (FILTER_HANDLED);
    +}
    +
    +static void
    +bwn_intrtask(void *arg, int npending)
    +{
    +	struct bwn_mac *mac = arg;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct siba_softc *siba = mac->mac_sd->sd_bus;
    +	uint32_t merged = 0;
    +	int i, tx = 0, rx = 0;
    +
    +	BWN_LOCK(sc);
    +	if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) {
    +		BWN_UNLOCK(sc);
    +		return;
    +	}
    +
    +	for (i = 0; i < N(mac->mac_reason); i++)
    +		merged |= mac->mac_reason[i];
    +
    +	if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
    +		device_printf(sc->sc_dev, "MAC trans error\n");
    +
    +	if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
    +		DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
    +		mac->mac_phy.txerrors--;
    +		if (mac->mac_phy.txerrors == 0) {
    +			mac->mac_phy.txerrors = BWN_TXERROR_MAX;
    +			bwn_restart(mac, "PHY TX errors");
    +		}
    +	}
    +
    +	if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
    +		if (merged & BWN_DMAINTR_FATALMASK) {
    +			device_printf(sc->sc_dev,
    +			    "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
    +			    mac->mac_reason[0], mac->mac_reason[1],
    +			    mac->mac_reason[2], mac->mac_reason[3],
    +			    mac->mac_reason[4], mac->mac_reason[5]);
    +			bwn_restart(mac, "DMA error");
    +			BWN_UNLOCK(sc);
    +			return;
    +		}
    +		if (merged & BWN_DMAINTR_NONFATALMASK) {
    +			device_printf(sc->sc_dev,
    +			    "DMA error: %#x %#x %#x %#x %#x %#x\n",
    +			    mac->mac_reason[0], mac->mac_reason[1],
    +			    mac->mac_reason[2], mac->mac_reason[3],
    +			    mac->mac_reason[4], mac->mac_reason[5]);
    +		}
    +	}
    +
    +	if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
    +		bwn_intr_ucode_debug(mac);
    +	if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
    +		bwn_intr_tbtt_indication(mac);
    +	if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
    +		bwn_intr_atim_end(mac);
    +	if (mac->mac_reason_intr & BWN_INTR_BEACON)
    +		bwn_intr_beacon(mac);
    +	if (mac->mac_reason_intr & BWN_INTR_PMQ)
    +		bwn_intr_pmq(mac);
    +	if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
    +		bwn_intr_noise(mac);
    +
    +	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
    +		if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
    +			bwn_dma_rx(mac->mac_method.dma.rx);
    +			rx = 1;
    +		}
    +	} else
    +		rx = bwn_pio_rx(&mac->mac_method.pio.rx);
    +
    +	KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
    +	KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
    +	KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
    +	KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
    +	KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
    +
    +	if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
    +		bwn_intr_txeof(mac);
    +		tx = 1;
    +	}
    +
    +	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
    +
    +	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
    +		int evt = BWN_LED_EVENT_NONE;
    +
    +		if (tx && rx) {
    +			if (sc->sc_rx_rate > sc->sc_tx_rate)
    +				evt = BWN_LED_EVENT_RX;
    +			else
    +				evt = BWN_LED_EVENT_TX;
    +		} else if (tx) {
    +			evt = BWN_LED_EVENT_TX;
    +		} else if (rx) {
    +			evt = BWN_LED_EVENT_RX;
    +		} else if (rx == 0) {
    +			evt = BWN_LED_EVENT_POLL;
    +		}
    +
    +		if (evt != BWN_LED_EVENT_NONE)
    +			bwn_led_event(mac, evt);
    +       }
    +
    +	if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
    +		if (!IFQ_IS_EMPTY(&ifp->if_snd))
    +			bwn_start_locked(ifp);
    +	}
    +
    +	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
    +	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
    +
    +	BWN_UNLOCK(sc);
    +}
    +
    +static void
    +bwn_restart(struct bwn_mac *mac, const char *msg)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +
    +	if (mac->mac_status < BWN_MAC_STATUS_INITED)
    +		return;
    +
    +	device_printf(sc->sc_dev, "HW reset: %s\n", msg);
    +	ieee80211_runtask(ic, &mac->mac_hwreset);
    +}
    +
    +static void
    +bwn_intr_ucode_debug(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint16_t reason;
    +
    +	if (mac->mac_fw.opensource == 0)
    +		return;
    +
    +	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
    +	switch (reason) {
    +	case BWN_DEBUGINTR_PANIC:
    +		bwn_handle_fwpanic(mac);
    +		break;
    +	case BWN_DEBUGINTR_DUMP_SHM:
    +		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
    +		break;
    +	case BWN_DEBUGINTR_DUMP_REGS:
    +		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
    +		break;
    +	case BWN_DEBUGINTR_MARKER:
    +		device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
    +		break;
    +	default:
    +		device_printf(sc->sc_dev,
    +		    "ucode debug unknown reason: %#x\n", reason);
    +	}
    +
    +	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
    +	    BWN_DEBUGINTR_ACK);
    +}
    +
    +static void
    +bwn_intr_tbtt_indication(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +
    +	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
    +		bwn_psctl(mac, 0);
    +	if (ic->ic_opmode == IEEE80211_M_IBSS)
    +		mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
    +}
    +
    +static void
    +bwn_intr_atim_end(struct bwn_mac *mac)
    +{
    +
    +	if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
    +		BWN_WRITE_4(mac, BWN_MACCMD,
    +		    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
    +		mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
    +	}
    +}
    +
    +static void
    +bwn_intr_beacon(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +	uint32_t cmd, beacon0, beacon1;
    +
    +	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
    +	    ic->ic_opmode == IEEE80211_M_MBSS)
    +		return;
    +
    +	mac->mac_intr_mask &= ~BWN_INTR_BEACON;
    +
    +	cmd = BWN_READ_4(mac, BWN_MACCMD);
    +	beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
    +	beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
    +
    +	if (beacon0 && beacon1) {
    +		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
    +		mac->mac_intr_mask |= BWN_INTR_BEACON;
    +		return;
    +	}
    +
    +	if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
    +		sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
    +		bwn_load_beacon0(mac);
    +		bwn_load_beacon1(mac);
    +		cmd = BWN_READ_4(mac, BWN_MACCMD);
    +		cmd |= BWN_MACCMD_BEACON0_VALID;
    +		BWN_WRITE_4(mac, BWN_MACCMD, cmd);
    +	} else {
    +		if (!beacon0) {
    +			bwn_load_beacon0(mac);
    +			cmd = BWN_READ_4(mac, BWN_MACCMD);
    +			cmd |= BWN_MACCMD_BEACON0_VALID;
    +			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
    +		} else if (!beacon1) {
    +			bwn_load_beacon1(mac);
    +			cmd = BWN_READ_4(mac, BWN_MACCMD);
    +			cmd |= BWN_MACCMD_BEACON1_VALID;
    +			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
    +		}
    +	}
    +}
    +
    +static void
    +bwn_intr_pmq(struct bwn_mac *mac)
    +{
    +	uint32_t tmp;
    +
    +	while (1) {
    +		tmp = BWN_READ_4(mac, BWN_PS_STATUS);
    +		if (!(tmp & 0x00000008))
    +			break;
    +	}
    +	BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
    +}
    +
    +static void
    +bwn_intr_noise(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
    +	uint16_t tmp;
    +	uint8_t noise[4];
    +	uint8_t i, j;
    +	int32_t average;
    +
    +	if (mac->mac_phy.type != BWN_PHYTYPE_G)
    +		return;
    +
    +	KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
    +	*((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
    +	if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
    +	    noise[3] == 0x7f)
    +		goto new;
    +
    +	KASSERT(mac->mac_noise.noi_nsamples < 8,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	i = mac->mac_noise.noi_nsamples;
    +	noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
    +	noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
    +	noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
    +	noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
    +	mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
    +	mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
    +	mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
    +	mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
    +	mac->mac_noise.noi_nsamples++;
    +	if (mac->mac_noise.noi_nsamples == 8) {
    +		average = 0;
    +		for (i = 0; i < 8; i++) {
    +			for (j = 0; j < 4; j++)
    +				average += mac->mac_noise.noi_samples[i][j];
    +		}
    +		average = (((average / 32) * 125) + 64) / 128;
    +		tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
    +		if (tmp >= 8)
    +			average += 2;
    +		else
    +			average -= 25;
    +		average -= (tmp == 8) ? 72 : 48;
    +
    +		mac->mac_stats.link_noise = average;
    +		mac->mac_noise.noi_running = 0;
    +		return;
    +	}
    +new:
    +	bwn_noise_gensample(mac);
    +}
    +
    +static int
    +bwn_pio_rx(struct bwn_pio_rxqueue *prq)
    +{
    +	struct bwn_mac *mac = prq->prq_mac;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	unsigned int i;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
    +		return (0);
    +
    +	for (i = 0; i < 5000; i++) {
    +		if (bwn_pio_rxeof(prq) == 0)
    +			break;
    +	}
    +	if (i >= 5000)
    +		device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
    +	return ((i > 0) ? 1 : 0);
    +}
    +
    +static void
    +bwn_dma_rx(struct bwn_dma_ring *dr)
    +{
    +	int slot, curslot;
    +
    +	KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
    +	curslot = dr->get_curslot(dr);
    +	KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	slot = dr->dr_curslot;
    +	for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
    +		bwn_dma_rxeof(dr, &slot);
    +
    +	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
    +	    BUS_DMASYNC_PREWRITE);
    +
    +	dr->set_curslot(dr, slot);
    +	dr->dr_curslot = slot;
    +}
    +
    +static void
    +bwn_intr_txeof(struct bwn_mac *mac)
    +{
    +	struct bwn_txstatus stat;
    +	uint32_t stat0, stat1;
    +	uint16_t tmp;
    +
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
    +
    +	while (1) {
    +		stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
    +		if (!(stat0 & 0x00000001))
    +			break;
    +		stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
    +
    +		stat.cookie = (stat0 >> 16);
    +		stat.seq = (stat1 & 0x0000ffff);
    +		stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
    +		tmp = (stat0 & 0x0000ffff);
    +		stat.framecnt = ((tmp & 0xf000) >> 12);
    +		stat.rtscnt = ((tmp & 0x0f00) >> 8);
    +		stat.sreason = ((tmp & 0x001c) >> 2);
    +		stat.pm = (tmp & 0x0080) ? 1 : 0;
    +		stat.im = (tmp & 0x0040) ? 1 : 0;
    +		stat.ampdu = (tmp & 0x0020) ? 1 : 0;
    +		stat.ack = (tmp & 0x0002) ? 1 : 0;
    +
    +		bwn_handle_txeof(mac, &stat);
    +	}
    +}
    +
    +static void
    +bwn_hwreset(void *arg, int npending)
    +{
    +	struct bwn_mac *mac = arg;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	int error = 0;
    +	int prev_status;
    +
    +	BWN_LOCK(sc);
    +
    +	prev_status = mac->mac_status;
    +	if (prev_status >= BWN_MAC_STATUS_STARTED)
    +		bwn_core_stop(mac);
    +	if (prev_status >= BWN_MAC_STATUS_INITED)
    +		bwn_core_exit(mac);
    +
    +	if (prev_status >= BWN_MAC_STATUS_INITED) {
    +		error = bwn_core_init(mac);
    +		if (error)
    +			goto out;
    +	}
    +	if (prev_status >= BWN_MAC_STATUS_STARTED)
    +		bwn_core_start(mac);
    +out:
    +	if (error) {
    +		device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
    +		sc->sc_curmac = NULL;
    +	}
    +	BWN_UNLOCK(sc);
    +}
    +
    +static void
    +bwn_handle_fwpanic(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint16_t reason;
    +
    +	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
    +	device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
    +
    +	if (reason == BWN_FWPANIC_RESTART)
    +		bwn_restart(mac, "ucode panic");
    +}
    +
    +static void
    +bwn_load_beacon0(struct bwn_mac *mac)
    +{
    +
    +	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +}
    +
    +static void
    +bwn_load_beacon1(struct bwn_mac *mac)
    +{
    +
    +	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +}
    +
    +static uint32_t
    +bwn_jssi_read(struct bwn_mac *mac)
    +{
    +	uint32_t val = 0;
    +
    +	val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
    +	val <<= 16;
    +	val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
    +
    +	return (val);
    +}
    +
    +static void
    +bwn_noise_gensample(struct bwn_mac *mac)
    +{
    +	uint32_t jssi = 0x7f7f7f7f;
    +
    +	bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
    +	bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
    +	BWN_WRITE_4(mac, BWN_MACCMD,
    +	    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
    +}
    +
    +static int
    +bwn_dma_freeslot(struct bwn_dma_ring *dr)
    +{
    +	struct bwn_mac *mac = dr->dr_mac;
    +
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
    +
    +	return (dr->dr_numslots - dr->dr_usedslot);
    +}
    +
    +static int
    +bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
    +{
    +	struct bwn_mac *mac = dr->dr_mac;
    +
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
    +
    +	KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	if (slot == dr->dr_numslots - 1)
    +		return (0);
    +	return (slot + 1);
    +}
    +
    +static void
    +bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
    +{
    +	struct bwn_mac *mac = dr->dr_mac;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +	struct bwn_dmadesc_generic *desc;
    +	struct bwn_dmadesc_meta *meta;
    +	struct bwn_rxhdr4 *rxhdr;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct mbuf *m;
    +	uint32_t macstat;
    +	int32_t tmp;
    +	int cnt = 0;
    +	uint16_t len;
    +
    +	dr->getdesc(dr, *slot, &desc, &meta);
    +
    +	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
    +	m = meta->mt_m;
    +
    +	if (bwn_dma_newbuf(dr, desc, meta, 0)) {
    +		ifp->if_ierrors++;
    +		return;
    +	}
    +
    +	rxhdr = mtod(m, struct bwn_rxhdr4 *);
    +	len = le16toh(rxhdr->frame_len);
    +	if (len <= 0) {
    +		ifp->if_ierrors++;
    +		return;
    +	}
    +	if (bwn_dma_check_redzone(dr, m)) {
    +		device_printf(sc->sc_dev, "redzone error.\n");
    +		bwn_dma_set_redzone(dr, m);
    +		bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
    +		    BUS_DMASYNC_PREWRITE);
    +		return;
    +	}
    +	if (len > dr->dr_rx_bufsize) {
    +		tmp = len;
    +		while (1) {
    +			dr->getdesc(dr, *slot, &desc, &meta);
    +			bwn_dma_set_redzone(dr, meta->mt_m);
    +			bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
    +			    BUS_DMASYNC_PREWRITE);
    +			*slot = bwn_dma_nextslot(dr, *slot);
    +			cnt++;
    +			tmp -= dr->dr_rx_bufsize;
    +			if (tmp <= 0)
    +				break;
    +		}
    +		device_printf(sc->sc_dev, "too small buffer "
    +		       "(len %u buffer %u dropped %d)\n",
    +		       len, dr->dr_rx_bufsize, cnt);
    +		return;
    +	}
    +	macstat = le32toh(rxhdr->mac_status);
    +	if (macstat & BWN_RX_MAC_FCSERR) {
    +		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
    +			device_printf(sc->sc_dev, "RX drop\n");
    +			return;
    +		}
    +	}
    +
    +	m->m_pkthdr.rcvif = ifp;
    +	m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
    +	m_adj(m, dr->dr_frameoffset);
    +
    +	bwn_rxeof(dr->dr_mac, m, rxhdr);
    +}
    +
    +static void
    +bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
    +{
    +	struct bwn_dma_ring *dr;
    +	struct bwn_dmadesc_generic *desc;
    +	struct bwn_dmadesc_meta *meta;
    +	struct bwn_node *bn;
    +	struct bwn_pio_txqueue *tq;
    +	struct bwn_pio_txpkt *tp = NULL;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211_node *ni;
    +	int slot;
    +
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
    +
    +	if (status->im)
    +		device_printf(sc->sc_dev, "TODO: STATUS IM\n");
    +	if (status->ampdu)
    +		device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
    +	if (status->rtscnt) {
    +		if (status->rtscnt == 0xf)
    +			device_printf(sc->sc_dev, "TODO: RTS fail\n");
    +		else
    +			device_printf(sc->sc_dev, "TODO: RTS ok\n");
    +	}
    +
    +	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
    +		if (status->ack) {
    +			dr = bwn_dma_parse_cookie(mac, status,
    +			    status->cookie, &slot);
    +			if (dr == NULL) {
    +				device_printf(sc->sc_dev,
    +				    "failed to parse cookie\n");
    +				return;
    +			}
    +			while (1) {
    +				dr->getdesc(dr, slot, &desc, &meta);
    +				if (meta->mt_islast) {
    +					ni = meta->mt_ni;
    +					bn = (struct bwn_node *)ni;
    +					ieee80211_amrr_tx_complete(&bn->bn_amn,
    +					    status->ack, 0);
    +					break;
    +				}
    +				slot = bwn_dma_nextslot(dr, slot);
    +			}
    +		}
    +		bwn_dma_handle_txeof(mac, status);
    +	} else {
    +		if (status->ack) {
    +			tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
    +			if (tq == NULL) {
    +				device_printf(sc->sc_dev,
    +				    "failed to parse cookie\n");
    +				return;
    +			}
    +			ni = tp->tp_ni;
    +			bn = (struct bwn_node *)ni;
    +			ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0);
    +		}
    +		bwn_pio_handle_txeof(mac, status);
    +	}
    +
    +	bwn_phy_txpower_check(mac, 0);
    +}
    +
    +static uint8_t
    +bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
    +{
    +	struct bwn_mac *mac = prq->prq_mac;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_rxhdr4 rxhdr;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct mbuf *m;
    +	uint32_t ctl32, macstat, v32;
    +	unsigned int i, padding;
    +	uint16_t ctl16, len, v16;
    +	unsigned char *mp;
    +	char *data;
    +
    +	memset(&rxhdr, 0, sizeof(rxhdr));
    +
    +	if (prq->prq_rev >= 8) {
    +		ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
    +		if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
    +			return (0);
    +		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
    +		    BWN_PIO8_RXCTL_FRAMEREADY);
    +		for (i = 0; i < 10; i++) {
    +			ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
    +			if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
    +				goto ready;
    +			DELAY(10);
    +		}
    +	} else {
    +		ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
    +		if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
    +			return (0);
    +		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
    +		    BWN_PIO_RXCTL_FRAMEREADY);
    +		for (i = 0; i < 10; i++) {
    +			ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
    +			if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
    +				goto ready;
    +			DELAY(10);
    +		}
    +	}
    +	device_printf(sc->sc_dev, "%s: timed out\n", __func__);
    +	return (1);
    +ready:
    +	if (prq->prq_rev >= 8)
    +		siba_read_multi_4(mac->mac_sd, &rxhdr, sizeof(rxhdr),
    +		    prq->prq_base + BWN_PIO8_RXDATA);
    +	else
    +		siba_read_multi_2(mac->mac_sd, &rxhdr, sizeof(rxhdr),
    +		    prq->prq_base + BWN_PIO_RXDATA);
    +	len = le16toh(rxhdr.frame_len);
    +	if (len > 0x700) {
    +		device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
    +		goto error;
    +	}
    +	if (len == 0) {
    +		device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
    +		goto error;
    +	}
    +
    +	macstat = le32toh(rxhdr.mac_status);
    +	if (macstat & BWN_RX_MAC_FCSERR) {
    +		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
    +			device_printf(sc->sc_dev, "%s: FCS error", __func__);
    +			goto error;
    +		}
    +	}
    +
    +	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
    +	KASSERT(len + padding <= MCLBYTES, ("too big..\n"));
    +	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
    +	if (m == NULL) {
    +		device_printf(sc->sc_dev, "%s: out of memory", __func__);
    +		goto error;
    +	}
    +	mp = mtod(m, unsigned char *);
    +	if (prq->prq_rev >= 8) {
    +		siba_read_multi_4(mac->mac_sd, mp + padding, (len & ~3),
    +		    prq->prq_base + BWN_PIO8_RXDATA);
    +		if (len & 3) {
    +			v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
    +			data = &(mp[len + padding - 1]);
    +			switch (len & 3) {
    +			case 3:
    +				*data = (v32 >> 16);
    +				data--;
    +			case 2:
    +				*data = (v32 >> 8);
    +				data--;
    +			case 1:
    +				*data = v32;
    +			}
    +		}
    +	} else {
    +		siba_read_multi_2(mac->mac_sd, mp + padding, (len & ~1),
    +		    prq->prq_base + BWN_PIO_RXDATA);
    +		if (len & 1) {
    +			v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
    +			mp[len + padding - 1] = v16;
    +		}
    +	}
    +
    +	m->m_pkthdr.rcvif = ifp;
    +	m->m_len = m->m_pkthdr.len = len + padding;
    +
    +	bwn_rxeof(prq->prq_mac, m, &rxhdr);
    +
    +	return (1);
    +error:
    +	if (prq->prq_rev >= 8)
    +		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
    +		    BWN_PIO8_RXCTL_DATAREADY);
    +	else
    +		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
    +	return (1);
    +}
    +
    +static int
    +bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
    +    struct bwn_dmadesc_meta *meta, int init)
    +{
    +	struct bwn_mac *mac = dr->dr_mac;
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +	struct bwn_rxhdr4 *hdr;
    +	bus_dmamap_t map;
    +	bus_addr_t paddr;
    +	struct mbuf *m;
    +	int error;
    +
    +	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
    +	if (m == NULL) {
    +		error = ENOBUFS;
    +
    +		/*
    +		 * If the NIC is up and running, we need to:
    +		 * - Clear RX buffer's header.
    +		 * - Restore RX descriptor settings.
    +		 */
    +		if (init)
    +			return (error);
    +		else
    +			goto back;
    +	}
    +	m->m_len = m->m_pkthdr.len = MCLBYTES;
    +
    +	bwn_dma_set_redzone(dr, m);
    +
    +	/*
    +	 * Try to load RX buf into temporary DMA map
    +	 */
    +	error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
    +	    bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
    +	if (error) {
    +		m_freem(m);
    +
    +		/*
    +		 * See the comment above
    +		 */
    +		if (init)
    +			return (error);
    +		else
    +			goto back;
    +	}
    +
    +	if (!init)
    +		bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
    +	meta->mt_m = m;
    +	meta->mt_paddr = paddr;
    +
    +	/*
    +	 * Swap RX buf's DMA map with the loaded temporary one
    +	 */
    +	map = meta->mt_dmap;
    +	meta->mt_dmap = dr->dr_spare_dmap;
    +	dr->dr_spare_dmap = map;
    +
    +back:
    +	/*
    +	 * Clear RX buf header
    +	 */
    +	hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
    +	bzero(hdr, sizeof(*hdr));
    +	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
    +	    BUS_DMASYNC_PREWRITE);
    +
    +	/*
    +	 * Setup RX buf descriptor
    +	 */
    +	dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
    +	    sizeof(*hdr), 0, 0, 0);
    +	return (error);
    +}
    +
    +static void
    +bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
    +		 bus_size_t mapsz __unused, int error)
    +{
    +
    +	if (!error) {
    +		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
    +		*((bus_addr_t *)arg) = seg->ds_addr;
    +	}
    +}
    +
    +static int
    +bwn_hwrate2ieeerate(int rate)
    +{
    +
    +	switch (rate) {
    +	case BWN_CCK_RATE_1MB:
    +		return (2);
    +	case BWN_CCK_RATE_2MB:
    +		return (4);
    +	case BWN_CCK_RATE_5MB:
    +		return (11);
    +	case BWN_CCK_RATE_11MB:
    +		return (22);
    +	case BWN_OFDM_RATE_6MB:
    +		return (12);
    +	case BWN_OFDM_RATE_9MB:
    +		return (18);
    +	case BWN_OFDM_RATE_12MB:
    +		return (24);
    +	case BWN_OFDM_RATE_18MB:
    +		return (36);
    +	case BWN_OFDM_RATE_24MB:
    +		return (48);
    +	case BWN_OFDM_RATE_36MB:
    +		return (72);
    +	case BWN_OFDM_RATE_48MB:
    +		return (96);
    +	case BWN_OFDM_RATE_54MB:
    +		return (108);
    +	default:
    +		printf("Ooops\n");
    +		return (0);
    +	}
    +}
    +
    +static void
    +bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
    +{
    +	const struct bwn_rxhdr4 *rxhdr = _rxhdr;
    +	struct bwn_plcp6 *plcp;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211_frame_min *wh;
    +	struct ieee80211_node *ni;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	uint32_t macstat;
    +	int padding, rate, rssi, noise, type;
    +	uint16_t phytype, phystat0, phystat3, chanstat;
    +	unsigned char *mp = mtod(m, unsigned char *);
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	phystat0 = le16toh(rxhdr->phy_status0);
    +	phystat3 = le16toh(rxhdr->phy_status3);
    +	macstat = le32toh(rxhdr->mac_status);
    +	chanstat = le16toh(rxhdr->channel);
    +	phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
    +
    +	if (macstat & BWN_RX_MAC_FCSERR)
    +		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
    +	if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
    +		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
    +	if (phystat0 & BWN_RX_PHYST0_SHORTPRMBL)
    +		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_SHORTPRE\n");
    +	if (macstat & BWN_RX_MAC_DECERR)
    +		goto drop;
    +
    +	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
    +	if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
    +		device_printf(sc->sc_dev, "RX: Packet size underrun (1)\n");
    +		goto drop;
    +	}
    +	plcp = (struct bwn_plcp6 *)(mp + padding);
    +	m_adj(m, sizeof(struct bwn_plcp6) + padding);
    +	if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
    +		device_printf(sc->sc_dev, "RX: Packet size underrun (2)\n");
    +		goto drop;
    +	}
    +	wh = mtod(m, struct ieee80211_frame_min *);
    +
    +	if (macstat & BWN_RX_MAC_DEC)
    +		device_printf(sc->sc_dev, "TODO: BWN_RX_MAC_DEC\n");
    +
    +	/* XXX calculating RSSI & noise & antenna */
    +
    +	if (phystat0 & BWN_RX_PHYST0_OFDM)
    +		rate = bwn_plcp_get_ofdmrate(mac, plcp,
    +		    phytype == BWN_PHYTYPE_A);
    +	else
    +		rate = bwn_plcp_get_cckrate(mac, plcp);
    +	if (rate == -1) {
    +		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
    +			goto drop;
    +	}
    +	sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
    +
    +	/* RX radio tap */
    +	if (ieee80211_radiotap_active(ic))
    +		bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
    +	m_adj(m, -IEEE80211_CRC_LEN);
    +
    +	rssi = rxhdr->phy.abg.rssi;	/* XXX incorrect RSSI calculation? */
    +	noise = mac->mac_stats.link_noise;
    +
    +	BWN_UNLOCK(sc);
    +
    +	ni = ieee80211_find_rxnode(ic, wh);
    +	if (ni != NULL) {
    +		type = ieee80211_input(ni, m, rssi, noise);
    +		ieee80211_free_node(ni);
    +	} else
    +		type = ieee80211_input_all(ic, m, rssi, noise);
    +
    +	BWN_LOCK(sc);
    +	return;
    +drop:
    +	device_printf(sc->sc_dev, "%s: dropped\n", __func__);
    +}
    +
    +static void
    +bwn_dma_handle_txeof(struct bwn_mac *mac,
    +    const struct bwn_txstatus *status)
    +{
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +	struct bwn_dma_ring *dr;
    +	struct bwn_dmadesc_generic *desc;
    +	struct bwn_dmadesc_meta *meta;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211_node *ni;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct mbuf *m;
    +	int slot;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
    +	if (dr == NULL) {
    +		device_printf(sc->sc_dev, "failed to parse cookie\n");
    +		return;
    +	}
    +	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
    +
    +	while (1) {
    +		KASSERT(slot >= 0 && slot < dr->dr_numslots,
    +		    ("%s:%d: fail", __func__, __LINE__));
    +		dr->getdesc(dr, slot, &desc, &meta);
    +
    +		if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
    +			bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
    +		else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
    +			bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
    +
    +		if (meta->mt_islast) {
    +			KASSERT(meta->mt_m != NULL,
    +			    ("%s:%d: fail", __func__, __LINE__));
    +
    +			ni = meta->mt_ni;
    +			m = meta->mt_m;
    +			if (ni != NULL) {
    +				/*
    +				 * Do any tx complete callback. Note this must
    +				 * be done before releasing the node reference.
    +				 */
    +				if (m->m_flags & M_TXCB)
    +					ieee80211_process_callback(ni, m, 0);
    +				ieee80211_free_node(ni);
    +				meta->mt_ni = NULL;
    +			}
    +			m_freem(m);
    +			meta->mt_m = NULL;
    +		} else {
    +			KASSERT(meta->mt_m == NULL,
    +			    ("%s:%d: fail", __func__, __LINE__));
    +		}
    +
    +		dr->dr_usedslot--;
    +		if (meta->mt_islast) {
    +			ifp->if_opackets++;
    +			break;
    +		}
    +		slot = bwn_dma_nextslot(dr, slot);
    +	}
    +	sc->sc_watchdog_timer = 0;
    +	if (dr->dr_stop) {
    +		KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
    +		    ("%s:%d: fail", __func__, __LINE__));
    +		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
    +		dr->dr_stop = 0;
    +	}
    +}
    +
    +static void
    +bwn_pio_handle_txeof(struct bwn_mac *mac,
    +    const struct bwn_txstatus *status)
    +{
    +	struct bwn_pio_txqueue *tq;
    +	struct bwn_pio_txpkt *tp = NULL;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +
    +	tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
    +	if (tq == NULL)
    +		return;
    +
    +	tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
    +	tq->tq_free++;
    +
    +	if (tp->tp_ni != NULL) {
    +		/*
    +		 * Do any tx complete callback.  Note this must
    +		 * be done before releasing the node reference.
    +		 */
    +		if (tp->tp_m->m_flags & M_TXCB)
    +			ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
    +		ieee80211_free_node(tp->tp_ni);
    +		tp->tp_ni = NULL;
    +	}
    +	m_freem(tp->tp_m);
    +	tp->tp_m = NULL;
    +	TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
    +
    +	ifp->if_opackets++;
    +
    +	sc->sc_watchdog_timer = 0;
    +	if (tq->tq_stop) {
    +		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
    +		tq->tq_stop = 0;
    +	}
    +}
    +
    +static void
    +bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	struct siba_softc *siba = mac->mac_sd->sd_bus;
    +	unsigned long now;
    +	int result;
    +
    +	BWN_GETTIME(now);
    +
    +	if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
    +		return;
    +	phy->nexttime = now + 2 * 1000;
    +
    +	if (siba->siba_board_vendor == SIBA_BOARDVENDOR_BCM &&
    +	    siba->siba_board_type == SIBA_BOARD_BU4306)
    +		return;
    +
    +	if (phy->recalc_txpwr != NULL) {
    +		result = phy->recalc_txpwr(mac,
    +		    (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
    +		if (result == BWN_TXPWR_RES_DONE)
    +			return;
    +		KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
    +		    ("%s: fail", __func__));
    +		KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
    +
    +		ieee80211_runtask(ic, &mac->mac_txpower);
    +	}
    +}
    +
    +static uint16_t
    +bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
    +{
    +
    +	return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
    +}
    +
    +static uint32_t
    +bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
    +{
    +
    +	return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
    +}
    +
    +static void
    +bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
    +{
    +
    +	BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
    +}
    +
    +static void
    +bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
    +{
    +
    +	BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
    +}
    +
    +static int
    +bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
    +{
    +
    +	switch (rate) {
    +	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
    +	case 12:
    +		return (BWN_OFDM_RATE_6MB);
    +	case 18:
    +		return (BWN_OFDM_RATE_9MB);
    +	case 24:
    +		return (BWN_OFDM_RATE_12MB);
    +	case 36:
    +		return (BWN_OFDM_RATE_18MB);
    +	case 48:
    +		return (BWN_OFDM_RATE_24MB);
    +	case 72:
    +		return (BWN_OFDM_RATE_36MB);
    +	case 96:
    +		return (BWN_OFDM_RATE_48MB);
    +	case 108:
    +		return (BWN_OFDM_RATE_54MB);
    +	/* CCK rates (NB: not IEEE std, device-specific) */
    +	case 2:
    +		return (BWN_CCK_RATE_1MB);
    +	case 4:
    +		return (BWN_CCK_RATE_2MB);
    +	case 11:
    +		return (BWN_CCK_RATE_5MB);
    +	case 22:
    +		return (BWN_CCK_RATE_11MB);
    +	}
    +
    +	device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
    +	return (BWN_CCK_RATE_1MB);
    +}
    +
    +static int
    +bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
    +    struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
    +{
    +	const struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211_frame *wh;
    +	struct ieee80211_frame *protwh;
    +	struct ieee80211_frame_cts *cts;
    +	struct ieee80211_frame_rts *rts;
    +	const struct ieee80211_txparam *tp;
    +	struct ieee80211vap *vap = ni->ni_vap;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	struct mbuf *mprot;
    +	unsigned int len;
    +	uint32_t macctl = 0;
    +	int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
    +	uint16_t phyctl = 0;
    +	uint8_t rate, rate_fb;
    +
    +	wh = mtod(m, struct ieee80211_frame *);
    +	memset(txhdr, 0, sizeof(*txhdr));
    +
    +	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
    +	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
    +	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
    +
    +	/*
    +	 * Find TX rate
    +	 */
    +	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
    +	if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
    +		rate = rate_fb = tp->mgmtrate;
    +	else if (ismcast)
    +		rate = rate_fb = tp->mcastrate;
    +	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
    +		rate = rate_fb = tp->ucastrate;
    +	else {
    +		rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn);
    +		rate = ni->ni_txrate;
    +
    +		if (rix > 0)
    +			rate_fb = ni->ni_rates.rs_rates[rix - 1] &
    +			    IEEE80211_RATE_VAL;
    +		else
    +			rate_fb = rate;
    +	}
    +
    +	sc->sc_tx_rate = rate;
    +
    +	rate = bwn_ieeerate2hwrate(sc, rate);
    +	rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
    +
    +	txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
    +	    bwn_plcp_getcck(rate);
    +	bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
    +	bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
    +
    +	if ((rate_fb == rate) ||
    +	    (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
    +	    (*(u_int16_t *)wh->i_dur == htole16(0)))
    +		txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
    +	else
    +		txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
    +		    m->m_pkthdr.len, rate, isshort);
    +
    +	/* XXX TX encryption */
    +	bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
    +	    (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
    +	    (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
    +	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
    +	bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
    +	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
    +
    +	txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
    +	    BWN_TX_EFT_FB_CCK;
    +	txhdr->chan = phy->chan;
    +	phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
    +	    BWN_TX_PHY_ENC_CCK;
    +	if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
    +	     rate == BWN_CCK_RATE_11MB))
    +		phyctl |= BWN_TX_PHY_SHORTPRMBL;
    +
    +	/* XXX TX antenna selection */
    +
    +	switch (bwn_antenna_sanitize(mac, 0)) {
    +	case 0:
    +		phyctl |= BWN_TX_PHY_ANT01AUTO;
    +		break;
    +	case 1:
    +		phyctl |= BWN_TX_PHY_ANT0;
    +		break;
    +	case 2:
    +		phyctl |= BWN_TX_PHY_ANT1;
    +		break;
    +	case 3:
    +		phyctl |= BWN_TX_PHY_ANT2;
    +		break;
    +	case 4:
    +		phyctl |= BWN_TX_PHY_ANT3;
    +		break;
    +	default:
    +		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	}
    +
    +	if (!ismcast)
    +		macctl |= BWN_TX_MAC_ACK;
    +
    +	macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
    +	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
    +	    m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
    +		macctl |= BWN_TX_MAC_LONGFRAME;
    +
    +	if (ic->ic_flags & IEEE80211_F_USEPROT) {
    +		/* XXX RTS rate is always 1MB??? */
    +		rts_rate = BWN_CCK_RATE_1MB;
    +		rts_rate_fb = bwn_get_fbrate(rts_rate);
    +
    +		protdur = ieee80211_compute_duration(ic->ic_rt,
    +		    m->m_pkthdr.len, rate, isshort) +
    +		    + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
    +
    +		if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
    +			cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
    +			    (txhdr->body.old.rts_frame) :
    +			    (txhdr->body.new.rts_frame));
    +			mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
    +			    protdur);
    +			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
    +			bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
    +			    mprot->m_pkthdr.len);
    +			m_freem(mprot);
    +			macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
    +			len = sizeof(struct ieee80211_frame_cts);
    +		} else {
    +			rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
    +			    (txhdr->body.old.rts_frame) :
    +			    (txhdr->body.new.rts_frame));
    +			protdur += ieee80211_ack_duration(ic->ic_rt, rate,
    +			    isshort);
    +			mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
    +			    wh->i_addr2, protdur);
    +			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
    +			bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
    +			    mprot->m_pkthdr.len);
    +			m_freem(mprot);
    +			macctl |= BWN_TX_MAC_SEND_RTSCTS;
    +			len = sizeof(struct ieee80211_frame_rts);
    +		}
    +		len += IEEE80211_CRC_LEN;
    +		bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
    +		    &txhdr->body.old.rts_plcp :
    +		    &txhdr->body.new.rts_plcp), len, rts_rate);
    +		bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
    +		    rts_rate_fb);
    +
    +		protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
    +		    (&txhdr->body.old.rts_frame) :
    +		    (&txhdr->body.new.rts_frame));
    +		txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
    +
    +		if (BWN_ISOFDMRATE(rts_rate)) {
    +			txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
    +			txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
    +		} else {
    +			txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
    +			txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
    +		}
    +		txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
    +		    BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
    +	}
    +
    +	if (BWN_ISOLDFMT(mac))
    +		txhdr->body.old.cookie = htole16(cookie);
    +	else
    +		txhdr->body.new.cookie = htole16(cookie);
    +
    +	txhdr->macctl = htole32(macctl);
    +	txhdr->phyctl = htole16(phyctl);
    +
    +	/*
    +	 * TX radio tap
    +	 */
    +	if (ieee80211_radiotap_active_vap(vap)) {
    +		sc->sc_tx_th.wt_flags = 0;
    +		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
    +			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
    +		if (isshort &&
    +		    (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
    +		     rate == BWN_CCK_RATE_11MB))
    +			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
    +		sc->sc_tx_th.wt_rate = rate;
    +
    +		ieee80211_radiotap_tx(vap, m);
    +	}
    +
    +	return (0);
    +}
    +
    +static void
    +bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
    +    const uint8_t rate)
    +{
    +	uint32_t d, plen;
    +	uint8_t *raw = plcp->o.raw;
    +
    +	if (BWN_ISOFDMRATE(rate)) {
    +		d = bwn_plcp_getofdm(rate);
    +		KASSERT(!(octets & 0xf000),
    +		    ("%s:%d: fail", __func__, __LINE__));
    +		d |= (octets << 5);
    +		plcp->o.data = htole32(d);
    +	} else {
    +		plen = octets * 16 / rate;
    +		if ((octets * 16 % rate) > 0) {
    +			plen++;
    +			if ((rate == BWN_CCK_RATE_11MB)
    +			    && ((octets * 8 % 11) < 4)) {
    +				raw[1] = 0x84;
    +			} else
    +				raw[1] = 0x04;
    +		} else
    +			raw[1] = 0x04;
    +		plcp->o.data |= htole32(plen << 16);
    +		raw[0] = bwn_plcp_getcck(rate);
    +	}
    +}
    +
    +static uint8_t
    +bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
    +{
    +	uint8_t mask;
    +
    +	if (n == 0)
    +		return (0);
    +	if (mac->mac_phy.gmode)
    +		mask = mac->mac_sd->sd_bus->siba_sprom.ant_bg;
    +	else
    +		mask = mac->mac_sd->sd_bus->siba_sprom.ant_a;
    +	if (!(mask & (1 << (n - 1))))
    +		return (0);
    +	return (n);
    +}
    +
    +static uint8_t
    +bwn_get_fbrate(uint8_t bitrate)
    +{
    +	switch (bitrate) {
    +	case BWN_CCK_RATE_1MB:
    +		return (BWN_CCK_RATE_1MB);
    +	case BWN_CCK_RATE_2MB:
    +		return (BWN_CCK_RATE_1MB);
    +	case BWN_CCK_RATE_5MB:
    +		return (BWN_CCK_RATE_2MB);
    +	case BWN_CCK_RATE_11MB:
    +		return (BWN_CCK_RATE_5MB);
    +	case BWN_OFDM_RATE_6MB:
    +		return (BWN_CCK_RATE_5MB);
    +	case BWN_OFDM_RATE_9MB:
    +		return (BWN_OFDM_RATE_6MB);
    +	case BWN_OFDM_RATE_12MB:
    +		return (BWN_OFDM_RATE_9MB);
    +	case BWN_OFDM_RATE_18MB:
    +		return (BWN_OFDM_RATE_12MB);
    +	case BWN_OFDM_RATE_24MB:
    +		return (BWN_OFDM_RATE_18MB);
    +	case BWN_OFDM_RATE_36MB:
    +		return (BWN_OFDM_RATE_24MB);
    +	case BWN_OFDM_RATE_48MB:
    +		return (BWN_OFDM_RATE_36MB);
    +	case BWN_OFDM_RATE_54MB:
    +		return (BWN_OFDM_RATE_48MB);
    +	}
    +	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	return (0);
    +}
    +
    +static uint32_t
    +bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
    +    uint32_t ctl, const void *_data, int len)
    +{
    +	uint32_t value = 0;
    +	const uint8_t *data = _data;
    +
    +	ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
    +	    BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
    +	bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
    +
    +	siba_write_multi_4(mac->mac_sd, data, (len & ~3),
    +	    tq->tq_base + BWN_PIO8_TXDATA);
    +	if (len & 3) {
    +		ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
    +		    BWN_PIO8_TXCTL_24_31);
    +		data = &(data[len - 1]);
    +		switch (len & 3) {
    +		case 3:
    +			ctl |= BWN_PIO8_TXCTL_16_23;
    +			value |= (uint32_t)(*data) << 16;
    +			data--;
    +		case 2:
    +			ctl |= BWN_PIO8_TXCTL_8_15;
    +			value |= (uint32_t)(*data) << 8;
    +			data--;
    +		case 1:
    +			value |= (uint32_t)(*data);
    +		}
    +		bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
    +		bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
    +	}
    +
    +	return (ctl);
    +}
    +
    +static void
    +bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
    +    uint16_t offset, uint32_t value)
    +{
    +
    +	BWN_WRITE_4(mac, tq->tq_base + offset, value);
    +}
    +
    +static uint16_t
    +bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
    +    uint16_t ctl, const void *_data, int len)
    +{
    +	const uint8_t *data = _data;
    +
    +	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
    +	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
    +
    +	siba_write_multi_2(mac->mac_sd, data, (len & ~1),
    +	    tq->tq_base + BWN_PIO_TXDATA);
    +	if (len & 1) {
    +		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
    +		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
    +		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
    +	}
    +
    +	return (ctl);
    +}
    +
    +static uint16_t
    +bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
    +    uint16_t ctl, struct mbuf *m0)
    +{
    +	int i, j = 0;
    +	uint16_t data = 0;
    +	const uint8_t *buf;
    +	struct mbuf *m = m0;
    +
    +	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
    +	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
    +
    +	for (; m != NULL; m = m->m_next) {
    +		buf = mtod(m, const uint8_t *);
    +		for (i = 0; i < m->m_len; i++) {
    +			if (!((j++) % 2))
    +				data |= buf[i];
    +			else {
    +				data |= (buf[i] << 8);
    +				BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
    +				data = 0;
    +			}
    +		}
    +	}
    +	if (m0->m_pkthdr.len % 2) {
    +		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
    +		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
    +		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
    +	}
    +
    +	return (ctl);
    +}
    +
    +static void
    +bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
    +{
    +
    +	if (mac->mac_phy.type != BWN_PHYTYPE_G)
    +		return;
    +	BWN_WRITE_2(mac, 0x684, 510 + time);
    +	bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
    +}
    +
    +static struct bwn_dma_ring *
    +bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
    +{
    +
    +	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
    +		return (mac->mac_method.dma.wme[WME_AC_BE]);
    +
    +	switch (prio) {
    +	case 3:
    +		return (mac->mac_method.dma.wme[WME_AC_VO]);
    +	case 2:
    +		return (mac->mac_method.dma.wme[WME_AC_VI]);
    +	case 0:
    +		return (mac->mac_method.dma.wme[WME_AC_BE]);
    +	case 1:
    +		return (mac->mac_method.dma.wme[WME_AC_BK]);
    +	}
    +	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +}
    +
    +static int
    +bwn_dma_getslot(struct bwn_dma_ring *dr)
    +{
    +	struct bwn_mac *mac = dr->dr_mac;
    +	int slot;
    +
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
    +
    +	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
    +	KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
    +	KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
    +
    +	slot = bwn_dma_nextslot(dr, dr->dr_curslot);
    +	KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
    +	dr->dr_curslot = slot;
    +	dr->dr_usedslot++;
    +
    +	return (slot);
    +}
    +
    +static int
    +bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
    +{
    +	const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
    +	unsigned int a, b, c, d;
    +	unsigned int avg;
    +	uint32_t tmp;
    +
    +	tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
    +	a = tmp & 0xff;
    +	b = (tmp >> 8) & 0xff;
    +	c = (tmp >> 16) & 0xff;
    +	d = (tmp >> 24) & 0xff;
    +	if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
    +	    c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
    +		return (ENOENT);
    +	bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
    +	    BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
    +	    (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
    +
    +	if (ofdm) {
    +		a = (a + 32) & 0x3f;
    +		b = (b + 32) & 0x3f;
    +		c = (c + 32) & 0x3f;
    +		d = (d + 32) & 0x3f;
    +	}
    +
    +	avg = (a + b + c + d + 2) / 4;
    +	if (ofdm) {
    +		if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
    +		    & BWN_HF_4DB_CCK_POWERBOOST)
    +			avg = (avg >= 13) ? (avg - 13) : 0;
    +	}
    +	return (avg);
    +}
    +
    +static void
    +bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
    +{
    +	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
    +	int rfatt = *rfattp;
    +	int bbatt = *bbattp;
    +
    +	while (1) {
    +		if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
    +			break;
    +		if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
    +			break;
    +		if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
    +			break;
    +		if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
    +			break;
    +		if (bbatt > lo->bbatt.max) {
    +			bbatt -= 4;
    +			rfatt += 1;
    +			continue;
    +		}
    +		if (bbatt < lo->bbatt.min) {
    +			bbatt += 4;
    +			rfatt -= 1;
    +			continue;
    +		}
    +		if (rfatt > lo->rfatt.max) {
    +			rfatt -= 1;
    +			bbatt += 4;
    +			continue;
    +		}
    +		if (rfatt < lo->rfatt.min) {
    +			rfatt += 1;
    +			bbatt -= 4;
    +			continue;
    +		}
    +		break;
    +	}
    +
    +	*rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
    +	*bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
    +}
    +
    +static void
    +bwn_phy_lock(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +
    +	KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
    +	    ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev));
    +
    +	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
    +		bwn_psctl(mac, BWN_PS_AWAKE);
    +}
    +
    +static void
    +bwn_phy_unlock(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
    +
    +	KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
    +	    ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev));
    +
    +	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
    +		bwn_psctl(mac, 0);
    +}
    +
    +static void
    +bwn_rf_lock(struct bwn_mac *mac)
    +{
    +
    +	BWN_WRITE_4(mac, BWN_MACCTL,
    +	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
    +	BWN_READ_4(mac, BWN_MACCTL);
    +	DELAY(10);
    +}
    +
    +static void
    +bwn_rf_unlock(struct bwn_mac *mac)
    +{
    +
    +	BWN_READ_2(mac, BWN_PHYVER);
    +	BWN_WRITE_4(mac, BWN_MACCTL,
    +	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
    +}
    +
    +static struct bwn_pio_txqueue *
    +bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
    +    struct bwn_pio_txpkt **pack)
    +{
    +	struct bwn_pio *pio = &mac->mac_method.pio;
    +	struct bwn_pio_txqueue *tq = NULL;
    +	unsigned int index;
    +
    +	switch (cookie & 0xf000) {
    +	case 0x1000:
    +		tq = &pio->wme[WME_AC_BK];
    +		break;
    +	case 0x2000:
    +		tq = &pio->wme[WME_AC_BE];
    +		break;
    +	case 0x3000:
    +		tq = &pio->wme[WME_AC_VI];
    +		break;
    +	case 0x4000:
    +		tq = &pio->wme[WME_AC_VO];
    +		break;
    +	case 0x5000:
    +		tq = &pio->mcast;
    +		break;
    +	}
    +	KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
    +	if (tq == NULL)
    +		return (NULL);
    +	index = (cookie & 0x0fff);
    +	KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
    +	if (index >= N(tq->tq_pkts))
    +		return (NULL);
    +	*pack = &tq->tq_pkts[index];
    +	KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
    +	return (tq);
    +}
    +
    +static void
    +bwn_txpwr(void *arg, int npending)
    +{
    +	struct bwn_mac *mac = arg;
    +	struct bwn_softc *sc = mac->mac_sc;
    +
    +	BWN_LOCK(sc);
    +	if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
    +	    mac->mac_phy.set_txpwr != NULL)
    +		mac->mac_phy.set_txpwr(mac);
    +	BWN_UNLOCK(sc);
    +}
    +
    +static void
    +bwn_task_15s(struct bwn_mac *mac)
    +{
    +	uint16_t reg;
    +
    +	if (mac->mac_fw.opensource) {
    +		reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
    +		if (reg) {
    +			bwn_restart(mac, "fw watchdog");
    +			return;
    +		}
    +		bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
    +	}
    +	if (mac->mac_phy.task_15s)
    +		mac->mac_phy.task_15s(mac);
    +
    +	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
    +}
    +
    +static void
    +bwn_task_30s(struct bwn_mac *mac)
    +{
    +
    +	if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
    +		return;
    +	mac->mac_noise.noi_running = 1;
    +	mac->mac_noise.noi_nsamples = 0;
    +
    +	bwn_noise_gensample(mac);
    +}
    +
    +static void
    +bwn_task_60s(struct bwn_mac *mac)
    +{
    +
    +	if (mac->mac_phy.task_60s)
    +		mac->mac_phy.task_60s(mac);
    +	bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
    +}
    +
    +static void
    +bwn_tasks(void *arg)
    +{
    +	struct bwn_mac *mac = arg;
    +	struct bwn_softc *sc = mac->mac_sc;
    +
    +	BWN_ASSERT_LOCKED(sc);
    +	if (mac->mac_status != BWN_MAC_STATUS_STARTED)
    +		return;
    +
    +	if (mac->mac_task_state % 4 == 0)
    +		bwn_task_60s(mac);
    +	if (mac->mac_task_state % 2 == 0)
    +		bwn_task_30s(mac);
    +	bwn_task_15s(mac);
    +
    +	mac->mac_task_state++;
    +	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
    +}
    +
    +static int
    +bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +
    +	KASSERT(a == 0, ("not support APHY\n"));
    +
    +	switch (plcp->o.raw[0] & 0xf) {
    +	case 0xb:
    +		return (BWN_OFDM_RATE_6MB);
    +	case 0xf:
    +		return (BWN_OFDM_RATE_9MB);
    +	case 0xa:
    +		return (BWN_OFDM_RATE_12MB);
    +	case 0xe:
    +		return (BWN_OFDM_RATE_18MB);
    +	case 0x9:
    +		return (BWN_OFDM_RATE_24MB);
    +	case 0xd:
    +		return (BWN_OFDM_RATE_36MB);
    +	case 0x8:
    +		return (BWN_OFDM_RATE_48MB);
    +	case 0xc:
    +		return (BWN_OFDM_RATE_54MB);
    +	}
    +	device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
    +	    plcp->o.raw[0] & 0xf);
    +	return (-1);
    +}
    +
    +static int
    +bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +
    +	switch (plcp->o.raw[0]) {
    +	case 0x0a:
    +		return (BWN_CCK_RATE_1MB);
    +	case 0x14:
    +		return (BWN_CCK_RATE_2MB);
    +	case 0x37:
    +		return (BWN_CCK_RATE_5MB);
    +	case 0x6e:
    +		return (BWN_CCK_RATE_11MB);
    +	}
    +	device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
    +	return (-1);
    +}
    +
    +static void
    +bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
    +    const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
    +    int rssi, int noise)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	const struct ieee80211_frame_min *wh;
    +	uint64_t tsf;
    +	uint16_t low_mactime_now;
    +
    +	if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
    +		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
    +
    +	wh = mtod(m, const struct ieee80211_frame_min *);
    +	if (wh->i_fc[1] & IEEE80211_FC1_WEP)
    +		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
    +
    +	bwn_tsf_read(mac, &tsf);
    +	low_mactime_now = tsf;
    +	tsf = tsf & ~0xffffULL;
    +	tsf += le16toh(rxhdr->mac_time);
    +	if (low_mactime_now < le16toh(rxhdr->mac_time))
    +		tsf -= 0x10000;
    +
    +	sc->sc_rx_th.wr_tsf = tsf;
    +	sc->sc_rx_th.wr_rate = rate;
    +	sc->sc_rx_th.wr_antsignal = rssi;
    +	sc->sc_rx_th.wr_antnoise = noise;
    +}
    +
    +static void
    +bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
    +{
    +	uint32_t low, high;
    +
    +	KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +
    +	low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
    +	high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
    +	*tsf = high;
    +	*tsf <<= 32;
    +	*tsf |= low;
    +}
    +
    +static int
    +bwn_dma_attach(struct bwn_mac *mac)
    +{
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	bus_addr_t lowaddr = 0;
    +	int error;
    +
    +	if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
    +		return (0);
    +
    +	KASSERT(mac->mac_sd->sd_id.sd_rev >= 5, ("%s: fail", __func__));
    +
    +	mac->mac_flags |= BWN_MAC_FLAG_DMA;
    +
    +	dma->dmatype = bwn_dma_gettype(mac);
    +	if (dma->dmatype == BWN_DMA_30BIT)
    +		lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
    +	else if (dma->dmatype == BWN_DMA_32BIT)
    +		lowaddr = BUS_SPACE_MAXADDR_32BIT;
    +	else
    +		lowaddr = BUS_SPACE_MAXADDR;
    +
    +	/*
    +	 * Create top level DMA tag
    +	 */
    +	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),	/* parent */
    +			       BWN_ALIGN, 0,		/* alignment, bounds */
    +			       lowaddr,			/* lowaddr */
    +			       BUS_SPACE_MAXADDR,	/* highaddr */
    +			       NULL, NULL,		/* filter, filterarg */
    +			       MAXBSIZE,		/* maxsize */
    +			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
    +			       BUS_SPACE_MAXSIZE,	/* maxsegsize */
    +			       0,			/* flags */
    +			       NULL, NULL,		/* lockfunc, lockarg */
    +			       &dma->parent_dtag);
    +	if (error) {
    +		device_printf(sc->sc_dev, "can't create parent DMA tag\n");
    +		return (error);
    +	}
    +
    +	/*
    +	 * Create TX/RX mbuf DMA tag
    +	 */
    +	error = bus_dma_tag_create(dma->parent_dtag,
    +				1,
    +				0,
    +				BUS_SPACE_MAXADDR,
    +				BUS_SPACE_MAXADDR,
    +				NULL, NULL,
    +				MCLBYTES,
    +				1,
    +				BUS_SPACE_MAXSIZE_32BIT,
    +				0,
    +				NULL, NULL,
    +				&dma->rxbuf_dtag);
    +	if (error) {
    +		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
    +		goto fail0;
    +	}
    +	error = bus_dma_tag_create(dma->parent_dtag,
    +				1,
    +				0,
    +				BUS_SPACE_MAXADDR,
    +				BUS_SPACE_MAXADDR,
    +				NULL, NULL,
    +				MCLBYTES,
    +				1,
    +				BUS_SPACE_MAXSIZE_32BIT,
    +				0,
    +				NULL, NULL,
    +				&dma->txbuf_dtag);
    +	if (error) {
    +		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
    +		goto fail1;
    +	}
    +
    +	dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
    +	if (!dma->wme[WME_AC_BK])
    +		goto fail2;
    +
    +	dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
    +	if (!dma->wme[WME_AC_BE])
    +		goto fail3;
    +
    +	dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
    +	if (!dma->wme[WME_AC_VI])
    +		goto fail4;
    +
    +	dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
    +	if (!dma->wme[WME_AC_VO])
    +		goto fail5;
    +
    +	dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
    +	if (!dma->mcast)
    +		goto fail6;
    +	dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
    +	if (!dma->rx)
    +		goto fail7;
    +
    +	return (error);
    +
    +fail7:	bwn_dma_ringfree(&dma->mcast);
    +fail6:	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
    +fail5:	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
    +fail4:	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
    +fail3:	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
    +fail2:	bus_dma_tag_destroy(dma->txbuf_dtag);
    +fail1:	bus_dma_tag_destroy(dma->rxbuf_dtag);
    +fail0:	bus_dma_tag_destroy(dma->parent_dtag);
    +	return (error);
    +}
    +
    +static struct bwn_dma_ring *
    +bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
    +    uint16_t cookie, int *slot)
    +{
    +	struct bwn_dma *dma = &mac->mac_method.dma;
    +	struct bwn_dma_ring *dr;
    +	struct bwn_softc *sc = mac->mac_sc;
    +
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
    +
    +	switch (cookie & 0xf000) {
    +	case 0x1000:
    +		dr = dma->wme[WME_AC_BK];
    +		break;
    +	case 0x2000:
    +		dr = dma->wme[WME_AC_BE];
    +		break;
    +	case 0x3000:
    +		dr = dma->wme[WME_AC_VI];
    +		break;
    +	case 0x4000:
    +		dr = dma->wme[WME_AC_VO];
    +		break;
    +	case 0x5000:
    +		dr = dma->mcast;
    +		break;
    +	default:
    +		KASSERT(0 == 1,
    +		    ("invalid cookie value %d", cookie & 0xf000));
    +	}
    +	*slot = (cookie & 0x0fff);
    +	if (*slot < 0 || *slot >= dr->dr_numslots) {
    +		/*
    +		 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
    +		 * that it occurs events which have same H/W sequence numbers.
    +		 * When it's occurred just prints a WARNING msgs and ignores.
    +		 */
    +		KASSERT(status->seq == dma->lastseq,
    +		    ("%s:%d: fail", __func__, __LINE__));
    +		device_printf(sc->sc_dev,
    +		    "out of slot ranges (0 < %d < %d)\n", *slot,
    +		    dr->dr_numslots);
    +		return (NULL);
    +	}
    +	dma->lastseq = status->seq;
    +	return (dr);
    +}
    +
    +static void
    +bwn_dma_stop(struct bwn_mac *mac)
    +{
    +	struct bwn_dma *dma;
    +
    +	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
    +		return;
    +	dma = &mac->mac_method.dma;
    +
    +	bwn_dma_ringstop(&dma->rx);
    +	bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
    +	bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
    +	bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
    +	bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
    +	bwn_dma_ringstop(&dma->mcast);
    +}
    +
    +static void
    +bwn_dma_ringstop(struct bwn_dma_ring **dr)
    +{
    +
    +	if (dr == NULL)
    +		return;
    +
    +	bwn_dma_cleanup(*dr);
    +}
    +
    +static void
    +bwn_pio_stop(struct bwn_mac *mac)
    +{
    +	struct bwn_pio *pio;
    +
    +	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
    +		return;
    +	pio = &mac->mac_method.pio;
    +
    +	bwn_destroy_queue_tx(&pio->mcast);
    +	bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
    +	bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
    +	bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
    +	bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
    +}
    +
    +static void
    +bwn_led_attach(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct siba_softc *siba = mac->mac_sd->sd_bus;
    +	const uint8_t *led_act = NULL;
    +	uint16_t val[BWN_LED_MAX];
    +	int i;
    +
    +	sc->sc_led_idle = (2350 * hz) / 1000;
    +	sc->sc_led_blink = 1;
    +
    +	for (i = 0; i < N(bwn_vendor_led_act); ++i) {
    +		if (siba->siba_pci_subvid == bwn_vendor_led_act[i].vid) {
    +			led_act = bwn_vendor_led_act[i].led_act;
    +			break;
    +		}
    +	}
    +	if (led_act == NULL)
    +		led_act = bwn_default_led_act;
    +
    +	val[0] = siba->siba_sprom.gpio0;
    +	val[1] = siba->siba_sprom.gpio1;
    +	val[2] = siba->siba_sprom.gpio2;
    +	val[3] = siba->siba_sprom.gpio3;
    +
    +	for (i = 0; i < BWN_LED_MAX; ++i) {
    +		struct bwn_led *led = &sc->sc_leds[i];
    +
    +		if (val[i] == 0xff) {
    +			led->led_act = led_act[i];
    +		} else {
    +			if (val[i] & BWN_LED_ACT_LOW)
    +				led->led_flags |= BWN_LED_F_ACTLOW;
    +			led->led_act = val[i] & BWN_LED_ACT_MASK;
    +		}
    +		led->led_mask = (1 << i);
    +
    +		if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
    +		    led->led_act == BWN_LED_ACT_BLINK_POLL ||
    +		    led->led_act == BWN_LED_ACT_BLINK) {
    +			led->led_flags |= BWN_LED_F_BLINK;
    +			if (led->led_act == BWN_LED_ACT_BLINK_POLL)
    +				led->led_flags |= BWN_LED_F_POLLABLE;
    +			else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
    +				led->led_flags |= BWN_LED_F_SLOW;
    +
    +			if (sc->sc_blink_led == NULL) {
    +				sc->sc_blink_led = led;
    +				if (led->led_flags & BWN_LED_F_SLOW)
    +					BWN_LED_SLOWDOWN(sc->sc_led_idle);
    +			}
    +		}
    +
    +		DPRINTF(sc, BWN_DEBUG_LED,
    +		    "%dth led, act %d, lowact %d\n", i,
    +		    led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
    +	}
    +	callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
    +}
    +
    +static __inline uint16_t
    +bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
    +{
    +
    +	if (led->led_flags & BWN_LED_F_ACTLOW)
    +		on = !on;
    +	if (on)
    +		val |= led->led_mask;
    +	else
    +		val &= ~led->led_mask;
    +	return val;
    +}
    +
    +static void
    +bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	uint16_t val;
    +	int i;
    +
    +	if (nstate == IEEE80211_S_INIT) {
    +		callout_stop(&sc->sc_led_blink_ch);
    +		sc->sc_led_blinking = 0;
    +	}
    +
    +	if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
    +		return;
    +
    +	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
    +	for (i = 0; i < BWN_LED_MAX; ++i) {
    +		struct bwn_led *led = &sc->sc_leds[i];
    +		int on;
    +
    +		if (led->led_act == BWN_LED_ACT_UNKN ||
    +		    led->led_act == BWN_LED_ACT_NULL)
    +			continue;
    +
    +		if ((led->led_flags & BWN_LED_F_BLINK) &&
    +		    nstate != IEEE80211_S_INIT)
    +			continue;
    +
    +		switch (led->led_act) {
    +		case BWN_LED_ACT_ON:    /* Always on */
    +			on = 1;
    +			break;
    +		case BWN_LED_ACT_OFF:   /* Always off */
    +		case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
    +			on = 0;
    +			break;
    +		default:
    +			on = 1;
    +			switch (nstate) {
    +			case IEEE80211_S_INIT:
    +				on = 0;
    +				break;
    +			case IEEE80211_S_RUN:
    +				if (led->led_act == BWN_LED_ACT_11G &&
    +				    ic->ic_curmode != IEEE80211_MODE_11G)
    +					on = 0;
    +				break;
    +			default:
    +				if (led->led_act == BWN_LED_ACT_ASSOC)
    +					on = 0;
    +				break;
    +			}
    +			break;
    +		}
    +
    +		val = bwn_led_onoff(led, val, on);
    +	}
    +	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
    +}
    +
    +static void
    +bwn_led_event(struct bwn_mac *mac, int event)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +        struct bwn_led *led = sc->sc_blink_led;
    +        int rate;
    +
    +        if (event == BWN_LED_EVENT_POLL) {
    +                if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
    +                        return;
    +                if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
    +                        return;
    +        }
    +
    +        sc->sc_led_ticks = ticks;
    +        if (sc->sc_led_blinking)
    +                return;
    +
    +        switch (event) {
    +        case BWN_LED_EVENT_RX:
    +                rate = sc->sc_rx_rate;
    +                break;
    +        case BWN_LED_EVENT_TX:
    +                rate = sc->sc_tx_rate;
    +                break;
    +        case BWN_LED_EVENT_POLL:
    +                rate = 0;
    +                break;
    +        default:
    +                panic("unknown LED event %d\n", event);
    +                break;
    +        }
    +        bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
    +            bwn_led_duration[rate].off_dur);
    +}
    +
    +static void
    +bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +        struct bwn_led *led = sc->sc_blink_led;
    +        uint16_t val;
    +
    +        val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
    +        val = bwn_led_onoff(led, val, 1);
    +        BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
    +
    +        if (led->led_flags & BWN_LED_F_SLOW) {
    +                BWN_LED_SLOWDOWN(on_dur);
    +                BWN_LED_SLOWDOWN(off_dur);
    +        }
    +
    +        sc->sc_led_blinking = 1;
    +        sc->sc_led_blink_offdur = off_dur;
    +
    +        callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
    +}
    +
    +static void
    +bwn_led_blink_next(void *arg)
    +{
    +	struct bwn_mac *mac = arg;
    +        struct bwn_softc *sc = mac->mac_sc;
    +        uint16_t val;
    +
    +        val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
    +        val = bwn_led_onoff(sc->sc_blink_led, val, 0);
    +        BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
    +
    +        callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
    +            bwn_led_blink_end, mac);
    +}
    +
    +static void
    +bwn_led_blink_end(void *arg)
    +{
    +	struct bwn_mac *mac = arg;
    +        struct bwn_softc *sc = mac->mac_sc;
    +
    +        sc->sc_led_blinking = 0;
    +}
    +
    +static int
    +bwn_suspend(device_t dev)
    +{
    +	struct bwn_softc *sc = device_get_softc(dev);
    +
    +	bwn_stop(sc, 1);
    +	return (0);
    +}
    +
    +static int
    +bwn_resume(device_t dev)
    +{
    +	struct bwn_softc *sc = device_get_softc(dev);
    +	struct ifnet *ifp = sc->sc_ifp;
    +
    +	if (ifp->if_flags & IFF_UP)
    +		bwn_init(sc);
    +	return (0);
    +}
    +
    +static void
    +bwn_rfswitch(void *arg)
    +{
    +	struct bwn_softc *sc = arg;
    +	struct bwn_mac *mac = sc->sc_curmac;
    +	int cur = 0, prev = 0;
    +
    +	KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
    +	    ("%s: invalid MAC status %d", __func__, mac->mac_status));
    +
    +	if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
    +		if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
    +			& BWN_RF_HWENABLED_HI_MASK))
    +			cur = 1;
    +	} else {
    +		if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
    +		    & BWN_RF_HWENABLED_LO_MASK)
    +			cur = 1;
    +	}
    +
    +	if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
    +		prev = 1;
    +
    +	if (cur != prev) {
    +		if (cur)
    +			mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
    +		else
    +			mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
    +
    +		device_printf(sc->sc_dev,
    +		    "status of RF switch is changed to %s\n",
    +		    cur ? "ON" : "OFF");
    +		if (cur != mac->mac_phy.rf_on) {
    +			if (cur)
    +				bwn_rf_turnon(mac);
    +			else
    +				bwn_rf_turnoff(mac);
    +		}
    +	}
    +
    +	callout_schedule(&sc->sc_rfswitch_ch, hz);
    +}
    +
    +static void
    +bwn_phy_lp_init_pre(struct bwn_mac *mac)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_lp *plp = &phy->phy_lp;
    +
    +	plp->plp_antenna = BWN_ANT_DEFAULT;
    +}
    +
    +static int
    +bwn_phy_lp_init(struct bwn_mac *mac)
    +{
    +	static const struct bwn_stxtable tables[] = {
    +		{ 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
    +		{ 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
    +		{ 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
    +		{ 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
    +		{ 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
    +		{ 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
    +		{ 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
    +		{ 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
    +		{ 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
    +		{ 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
    +		{ 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
    +		{ 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
    +		{ 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
    +		{ 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
    +		{ 2, 11, 0x40, 0, 0x0f }
    +	};
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	const struct bwn_stxtable *st;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	int i, error;
    +	uint16_t tmp;
    +
    +	bwn_phy_lp_readsprom(mac);	/* XXX bad place */
    +	bwn_phy_lp_bbinit(mac);
    +
    +	/* initialize RF */
    +	BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
    +	DELAY(1);
    +	BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
    +	DELAY(1);
    +
    +	if (mac->mac_phy.rf_ver == 0x2062)
    +		bwn_phy_lp_b2062_init(mac);
    +	else {
    +		bwn_phy_lp_b2063_init(mac);
    +
    +		/* synchronize stx table. */
    +		for (i = 0; i < N(tables); i++) {
    +			st = &tables[i];
    +			tmp = BWN_RF_READ(mac, st->st_rfaddr);
    +			tmp >>= st->st_rfshift;
    +			tmp <<= st->st_physhift;
    +			BWN_PHY_SETMASK(mac,
    +			    BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
    +			    ~(st->st_mask << st->st_physhift), tmp);
    +		}
    +
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
    +		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
    +	}
    +
    +	/* calibrate RC */
    +	if (mac->mac_phy.rev >= 2)
    +		bwn_phy_lp_rxcal_r2(mac);
    +	else if (!plp->plp_rccap) {
    +		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
    +			bwn_phy_lp_rccal_r12(mac);
    +	} else
    +		bwn_phy_lp_set_rccap(mac);
    +
    +	error = bwn_phy_lp_switch_channel(mac, 7);
    +	if (error)
    +		device_printf(sc->sc_dev,
    +		    "failed to change channel 7 (%d)\n", error);
    +	bwn_phy_lp_txpctl_init(mac);
    +	bwn_phy_lp_calib(mac);
    +	return (0);
    +}
    +
    +static uint16_t
    +bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
    +{
    +
    +	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
    +	return (BWN_READ_2(mac, BWN_PHYDATA));
    +}
    +
    +static void
    +bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
    +{
    +
    +	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
    +	BWN_WRITE_2(mac, BWN_PHYDATA, value);
    +}
    +
    +static void
    +bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
    +    uint16_t set)
    +{
    +
    +	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
    +	BWN_WRITE_2(mac, BWN_PHYDATA,
    +	    (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
    +}
    +
    +static uint16_t
    +bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
    +{
    +
    +	KASSERT(reg != 1, ("unaccessible register %d", reg));
    +	if (mac->mac_phy.rev < 2 && reg != 0x4001)
    +		reg |= 0x100;
    +	if (mac->mac_phy.rev >= 2)
    +		reg |= 0x200;
    +	BWN_WRITE_2(mac, BWN_RFCTL, reg);
    +	return BWN_READ_2(mac, BWN_RFDATALO);
    +}
    +
    +static void
    +bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
    +{
    +
    +	KASSERT(reg != 1, ("unaccessible register %d", reg));
    +	BWN_WRITE_2(mac, BWN_RFCTL, reg);
    +	BWN_WRITE_2(mac, BWN_RFDATALO, value);
    +}
    +
    +static void
    +bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
    +{
    +
    +	if (on) {
    +		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
    +		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
    +		    (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
    +		return;
    +	}
    +
    +	if (mac->mac_phy.rev >= 2) {
    +		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
    +		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
    +		BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
    +		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
    +		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
    +		return;
    +	}
    +
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
    +}
    +
    +static int
    +bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_lp *plp = &phy->phy_lp;
    +	int error;
    +
    +	if (phy->rf_ver == 0x2063) {
    +		error = bwn_phy_lp_b2063_switch_channel(mac, chan);
    +		if (error)
    +			return (error);
    +	} else {
    +		error = bwn_phy_lp_b2062_switch_channel(mac, chan);
    +		if (error)
    +			return (error);
    +		bwn_phy_lp_set_anafilter(mac, chan);
    +		bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
    +	}
    +
    +	plp->plp_chan = chan;
    +	BWN_WRITE_2(mac, BWN_CHANNEL, chan);
    +	return (0);
    +}
    +
    +static uint32_t
    +bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +
    +	device_printf(sc->sc_dev, "correct?\n");
    +
    +	return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
    +}
    +
    +static void
    +bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
    +{
    +	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_phy_lp *plp = &phy->phy_lp;
    +
    +	if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
    +		return;
    +
    +	bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
    +	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
    +	plp->plp_antenna = antenna;
    +}
    +
    +static void
    +bwn_phy_lp_task_60s(struct bwn_mac *mac)
    +{
    +
    +	bwn_phy_lp_calib(mac);
    +}
    +
    +static void
    +bwn_phy_lp_readsprom(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct siba_sprom *sprom = &siba->siba_sprom;
    +
    +	device_printf(sc->sc_dev, "XXX using %dghz\n",
    +	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 2 : 5);
    +
    +	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    +		plp->plp_txisoband_m = sprom->tri2g;
    +		plp->plp_bxarch = sprom->bxa2g;
    +		plp->plp_rxpwroffset = sprom->rxpo2g;
    +		plp->plp_rssivf = sprom->rssismf2g;
    +		plp->plp_rssivc = sprom->rssismc2g;
    +		plp->plp_rssigs = sprom->rssisav2g;
    +		return;
    +	}
    +
    +	plp->plp_txisoband_l = sprom->tri5gl;
    +	plp->plp_txisoband_m = sprom->tri5g;
    +	plp->plp_txisoband_h = sprom->tri5gh;
    +	plp->plp_bxarch = sprom->bxa5g;
    +	plp->plp_rxpwroffset = sprom->rxpo5g;
    +	plp->plp_rssivf = sprom->rssismf5g;
    +	plp->plp_rssivc = sprom->rssismc5g;
    +	plp->plp_rssigs = sprom->rssisav5g;
    +}
    +
    +static void
    +bwn_phy_lp_bbinit(struct bwn_mac *mac)
    +{
    +
    +	bwn_phy_lp_tblinit(mac);
    +	if (mac->mac_phy.rev >= 2)
    +		bwn_phy_lp_bbinit_r2(mac);
    +	else
    +		bwn_phy_lp_bbinit_r01(mac);
    +}
    +
    +static void
    +bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
    +{
    +	struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
    +	struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +
    +	bwn_phy_lp_set_txgain(mac,
    +	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
    +	bwn_phy_lp_set_bbmult(mac, 150);
    +}
    +
    +static void
    +bwn_phy_lp_calib(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	const struct bwn_rxcompco *rc = NULL;
    +	struct bwn_txgain ogain;
    +	int i, omode, oafeovr, orf, obbmult;
    +	uint8_t mode, fc = 0;
    +
    +	if (plp->plp_chanfullcal != plp->plp_chan) {
    +		plp->plp_chanfullcal = plp->plp_chan;
    +		fc = 1;
    +	}
    +
    +	bwn_mac_suspend(mac);
    +
    +	/* BlueTooth Coexistance Override */
    +	BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
    +	BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
    +
    +	if (mac->mac_phy.rev >= 2)
    +		bwn_phy_lp_digflt_save(mac);
    +	bwn_phy_lp_get_txpctlmode(mac);
    +	mode = plp->plp_txpctlmode;
    +	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
    +	if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
    +		bwn_phy_lp_bugfix(mac);
    +	if (mac->mac_phy.rev >= 2 && fc == 1) {
    +		bwn_phy_lp_get_txpctlmode(mac);
    +		omode = plp->plp_txpctlmode;
    +		oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
    +		if (oafeovr)
    +			ogain = bwn_phy_lp_get_txgain(mac);
    +		orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
    +		obbmult = bwn_phy_lp_get_bbmult(mac);
    +		bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
    +		if (oafeovr)
    +			bwn_phy_lp_set_txgain(mac, &ogain);
    +		bwn_phy_lp_set_bbmult(mac, obbmult);
    +		bwn_phy_lp_set_txpctlmode(mac, omode);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
    +	}
    +	bwn_phy_lp_set_txpctlmode(mac, mode);
    +	if (mac->mac_phy.rev >= 2)
    +		bwn_phy_lp_digflt_restore(mac);
    +
    +	/* do RX IQ Calculation; assumes that noise is true. */
    +	if (siba->siba_chipid == 0x5354) {
    +		for (i = 0; i < N(bwn_rxcompco_5354); i++) {
    +			if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
    +				rc = &bwn_rxcompco_5354[i];
    +		}
    +	} else if (mac->mac_phy.rev >= 2)
    +		rc = &bwn_rxcompco_r2;
    +	else {
    +		for (i = 0; i < N(bwn_rxcompco_r12); i++) {
    +			if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
    +				rc = &bwn_rxcompco_r12[i];
    +		}
    +	}
    +	if (rc == NULL)
    +		goto fail;
    +
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
    +
    +	bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
    +
    +	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    +		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
    +	} else {
    +		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
    +	}
    +
    +	bwn_phy_lp_set_rxgain(mac, 0x2d5d);
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
    +	bwn_phy_lp_set_deaf(mac, 0);
    +	/* XXX no checking return value? */
    +	(void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
    +	bwn_phy_lp_clear_deaf(mac, 0);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
    +
    +	/* disable RX GAIN override. */
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
    +	if (mac->mac_phy.rev >= 2) {
    +		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
    +		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    +			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
    +			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
    +		}
    +	} else {
    +		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
    +	}
    +
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
    +fail:
    +	bwn_mac_enable(mac);
    +}
    +
    +static void
    +bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
    +{
    +
    +       if (on) {
    +               BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
    +	       return;
    +       }
    +
    +       BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
    +       BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
    +}
    +
    +static int
    +bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
    +{
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	static const struct bwn_b206x_chan *bc = NULL;
    +	uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
    +	    tmp[6];
    +	uint16_t old, scale, tmp16;
    +	int i, div;
    +
    +	for (i = 0; i < N(bwn_b2063_chantable); i++) {
    +		if (bwn_b2063_chantable[i].bc_chan == chan) {
    +			bc = &bwn_b2063_chantable[i];
    +			break;
    +		}
    +	}
    +	if (bc == NULL)
    +		return (EINVAL);
    +
    +	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
    +	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
    +	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
    +	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
    +	BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
    +	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
    +	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
    +	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
    +	BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
    +	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
    +	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
    +	BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
    +
    +	old = BWN_RF_READ(mac, BWN_B2063_COM15);
    +	BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
    +
    +	freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
    +	freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
    +	freqref = freqxtal * 3;
    +	div = (freqxtal <= 26000000 ? 1 : 2);
    +	timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
    +	timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
    +		999999) / 1000000) + 1;
    +
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
    +	    0xfff8, timeout >> 2);
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
    +	    0xff9f,timeout << 5);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
    +
    +	val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
    +	val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
    +	val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
    +
    +	count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
    +	    (timeoutref + 1)) - 1;
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
    +	    0xf0, count >> 8);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
    +
    +	tmp[0] = ((val[2] * 62500) / freqref) << 4;
    +	tmp[1] = ((val[2] * 62500) % freqref) << 4;
    +	while (tmp[1] >= freqref) {
    +		tmp[0]++;
    +		tmp[1] -= freqref;
    +	}
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
    +
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
    +
    +	tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
    +	tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
    +
    +	if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
    +		scale = 1;
    +		tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
    +	} else {
    +		scale = 0;
    +		tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
    +	}
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
    +
    +	tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
    +	    (scale + 1);
    +	if (tmp[5] > 150)
    +		tmp[5] = 0;
    +
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
    +
    +	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
    +	if (freqxtal > 26000000)
    +		BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
    +	else
    +		BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
    +
    +	if (val[0] == 45)
    +		BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
    +	else
    +		BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
    +
    +	BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
    +	DELAY(1);
    +	BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
    +
    +	/* VCO Calibration */
    +	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
    +	tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
    +	DELAY(1);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
    +	DELAY(1);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
    +	DELAY(1);
    +	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
    +	DELAY(300);
    +	BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
    +
    +	BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
    +	return (0);
    +}
    +
    +static int
    +bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	const struct bwn_b206x_chan *bc = NULL;
    +	uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
    +	uint32_t tmp[9];
    +	int i;
    +
    +	for (i = 0; i < N(bwn_b2062_chantable); i++) {
    +		if (bwn_b2062_chantable[i].bc_chan == chan) {
    +			bc = &bwn_b2062_chantable[i];
    +			break;
    +		}
    +	}
    +
    +	if (bc == NULL)
    +		return (EINVAL);
    +
    +	BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
    +	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
    +	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
    +	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
    +	BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
    +	BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
    +	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
    +	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
    +	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
    +	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
    +
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
    +	bwn_phy_lp_b2062_reset_pllbias(mac);
    +	tmp[0] = freqxtal / 1000;
    +	tmp[1] = plp->plp_div * 1000;
    +	tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
    +	if (ieee80211_ieee2mhz(chan, 0) < 4000)
    +		tmp[2] *= 2;
    +	tmp[3] = 48 * tmp[0];
    +	tmp[5] = tmp[2] / tmp[3];
    +	tmp[6] = tmp[2] % tmp[3];
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
    +	tmp[4] = tmp[6] * 0x100;
    +	tmp[5] = tmp[4] / tmp[3];
    +	tmp[6] = tmp[4] % tmp[3];
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
    +	tmp[4] = tmp[6] * 0x100;
    +	tmp[5] = tmp[4] / tmp[3];
    +	tmp[6] = tmp[4] % tmp[3];
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
    +	tmp[4] = tmp[6] * 0x100;
    +	tmp[5] = tmp[4] / tmp[3];
    +	tmp[6] = tmp[4] % tmp[3];
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
    +	    tmp[5] + ((2 * tmp[6]) / tmp[3]));
    +	tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
    +	tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
    +
    +	bwn_phy_lp_b2062_vco_calib(mac);
    +	if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
    +		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
    +		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
    +		bwn_phy_lp_b2062_reset_pllbias(mac);
    +		bwn_phy_lp_b2062_vco_calib(mac);
    +		if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
    +			BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
    +			return (EIO);
    +		}
    +	}
    +	BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
    +	return (0);
    +}
    +
    +static void
    +bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	uint16_t tmp = (channel == 14);
    +
    +	if (mac->mac_phy.rev < 2) {
    +		BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
    +		if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
    +			bwn_phy_lp_set_rccap(mac);
    +		return;
    +	}
    +
    +	BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
    +}
    +
    +static void
    +bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	uint16_t iso, tmp[3];
    +
    +	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
    +
    +	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
    +		iso = plp->plp_txisoband_m;
    +	else if (freq <= 5320)
    +		iso = plp->plp_txisoband_l;
    +	else if (freq <= 5700)
    +		iso = plp->plp_txisoband_m;
    +	else
    +		iso = plp->plp_txisoband_h;
    +
    +	tmp[0] = ((iso - 26) / 12) << 12;
    +	tmp[1] = tmp[0] + 0x1000;
    +	tmp[2] = tmp[0] + 0x2000;
    +
    +	bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
    +}
    +
    +static void
    +bwn_phy_lp_digflt_save(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	int i;
    +	static const uint16_t addr[] = {
    +		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
    +		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
    +		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
    +		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
    +		BWN_PHY_OFDM(0xcf),
    +	};
    +	static const uint16_t val[] = {
    +		0xde5e, 0xe832, 0xe331, 0x4d26,
    +		0x0026, 0x1420, 0x0020, 0xfe08,
    +		0x0008,
    +	};
    +
    +	for (i = 0; i < N(addr); i++) {
    +		plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
    +		BWN_PHY_WRITE(mac, addr[i], val[i]);
    +	}
    +}
    +
    +static void
    +bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint16_t ctl;
    +
    +	ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
    +	switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
    +	case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
    +		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
    +		break;
    +	case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
    +		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
    +		break;
    +	case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
    +		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
    +		break;
    +	default:
    +		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
    +		device_printf(sc->sc_dev, "unknown command mode\n");
    +		break;
    +	}
    +}
    +
    +static void
    +bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	uint16_t ctl;
    +	uint8_t old;
    +
    +	bwn_phy_lp_get_txpctlmode(mac);
    +	old = plp->plp_txpctlmode;
    +	if (old == mode)
    +		return;
    +	plp->plp_txpctlmode = mode;
    +
    +	if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
    +		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
    +		    plp->plp_tssiidx);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
    +		    0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
    +
    +		/* disable TX GAIN override */
    +		if (mac->mac_phy.rev < 2)
    +			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
    +		else {
    +			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
    +			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
    +		}
    +		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
    +
    +		plp->plp_txpwridx = -1;
    +	}
    +	if (mac->mac_phy.rev >= 2) {
    +		if (mode == BWN_PHYLP_TXPCTL_ON_HW)
    +			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
    +		else
    +			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
    +	}
    +
    +	/* writes TX Power Control mode */
    +	switch (plp->plp_txpctlmode) {
    +	case BWN_PHYLP_TXPCTL_OFF:
    +		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
    +		break;
    +	case BWN_PHYLP_TXPCTL_ON_HW:
    +		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
    +		break;
    +	case BWN_PHYLP_TXPCTL_ON_SW:
    +		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
    +		break;
    +	default:
    +		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	}
    +	BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
    +	    (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
    +}
    +
    +static void
    +bwn_phy_lp_bugfix(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	const unsigned int size = 256;
    +	struct bwn_txgain tg;
    +	uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
    +	uint16_t tssinpt, tssiidx, value[2];
    +	uint8_t mode;
    +	int8_t txpwridx;
    +
    +	tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
    +	    M_NOWAIT | M_ZERO);
    +	if (tabs == NULL) {
    +		device_printf(sc->sc_dev, "failed to allocate buffer.\n");
    +		return;
    +	}
    +
    +	bwn_phy_lp_get_txpctlmode(mac);
    +	mode = plp->plp_txpctlmode;
    +	txpwridx = plp->plp_txpwridx;
    +	tssinpt = plp->plp_tssinpt;
    +	tssiidx = plp->plp_tssiidx;
    +
    +	bwn_tab_read_multi(mac,
    +	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
    +	    BWN_TAB_4(7, 0x140), size, tabs);
    +
    +	bwn_phy_lp_tblinit(mac);
    +	bwn_phy_lp_bbinit(mac);
    +	bwn_phy_lp_txpctl_init(mac);
    +	bwn_phy_lp_rf_onoff(mac, 1);
    +	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
    +
    +	bwn_tab_write_multi(mac,
    +	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
    +	    BWN_TAB_4(7, 0x140), size, tabs);
    +
    +	BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
    +	plp->plp_tssinpt = tssinpt;
    +	plp->plp_tssiidx = tssiidx;
    +	bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
    +	if (txpwridx != -1) {
    +		/* set TX power by index */
    +		plp->plp_txpwridx = txpwridx;
    +		bwn_phy_lp_get_txpctlmode(mac);
    +		if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
    +			bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
    +		if (mac->mac_phy.rev >= 2) {
    +			rxcomp = bwn_tab_read(mac,
    +			    BWN_TAB_4(7, txpwridx + 320));
    +			txgain = bwn_tab_read(mac,
    +			    BWN_TAB_4(7, txpwridx + 192));
    +			tg.tg_pad = (txgain >> 16) & 0xff;
    +			tg.tg_gm = txgain & 0xff;
    +			tg.tg_pga = (txgain >> 8) & 0xff;
    +			tg.tg_dac = (rxcomp >> 28) & 0xff;
    +			bwn_phy_lp_set_txgain(mac, &tg);
    +		} else {
    +			rxcomp = bwn_tab_read(mac,
    +			    BWN_TAB_4(10, txpwridx + 320));
    +			txgain = bwn_tab_read(mac,
    +			    BWN_TAB_4(10, txpwridx + 192));
    +			BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
    +			    0xf800, (txgain >> 4) & 0x7fff);
    +			bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
    +			bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
    +		}
    +		bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
    +
    +		/* set TX IQCC */
    +		value[0] = (rxcomp >> 10) & 0x3ff;
    +		value[1] = rxcomp & 0x3ff;
    +		bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
    +
    +		coeff = bwn_tab_read(mac,
    +		    (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
    +		    BWN_TAB_4(10, txpwridx + 448));
    +		bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
    +		if (mac->mac_phy.rev >= 2) {
    +			rfpwr = bwn_tab_read(mac,
    +			    BWN_TAB_4(7, txpwridx + 576));
    +			BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
    +			    rfpwr & 0xffff);
    +		}
    +		bwn_phy_lp_set_txgain_override(mac);
    +	}
    +	if (plp->plp_rccap)
    +		bwn_phy_lp_set_rccap(mac);
    +	bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
    +	bwn_phy_lp_set_txpctlmode(mac, mode);
    +	free(tabs, M_DEVBUF);
    +}
    +
    +static void
    +bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	int i;
    +	static const uint16_t addr[] = {
    +		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
    +		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
    +		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
    +		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
    +		BWN_PHY_OFDM(0xcf),
    +	};
    +
    +	for (i = 0; i < N(addr); i++)
    +		BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
    +}
    +
    +static void
    +bwn_phy_lp_tblinit(struct bwn_mac *mac)
    +{
    +	uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
    +
    +	if (mac->mac_phy.rev < 2) {
    +		bwn_phy_lp_tblinit_r01(mac);
    +		bwn_phy_lp_tblinit_txgain(mac);
    +		bwn_phy_lp_set_gaintbl(mac, freq);
    +		return;
    +	}
    +
    +	bwn_phy_lp_tblinit_r2(mac);
    +	bwn_phy_lp_tblinit_txgain(mac);
    +}
    +
    +struct bwn_wpair {
    +	uint16_t		reg;
    +	uint16_t		value;
    +};
    +
    +struct bwn_smpair {
    +	uint16_t		offset;
    +	uint16_t		mask;
    +	uint16_t		set;
    +};
    +
    +static void
    +bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	static const struct bwn_wpair v1[] = {
    +		{ BWN_PHY_AFE_DAC_CTL, 0x50 },
    +		{ BWN_PHY_AFE_CTL, 0x8800 },
    +		{ BWN_PHY_AFE_CTL_OVR, 0 },
    +		{ BWN_PHY_AFE_CTL_OVRVAL, 0 },
    +		{ BWN_PHY_RF_OVERRIDE_0, 0 },
    +		{ BWN_PHY_RF_OVERRIDE_2, 0 },
    +		{ BWN_PHY_OFDM(0xf9), 0 },
    +		{ BWN_PHY_TR_LOOKUP_1, 0 }
    +	};
    +	static const struct bwn_smpair v2[] = {
    +		{ BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
    +		{ BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
    +		{ BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
    +		{ BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
    +		{ BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
    +	};
    +	static const struct bwn_smpair v3[] = {
    +		{ BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
    +		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
    +		{ BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
    +		{ BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
    +		{ BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
    +		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
    +		{ BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
    +		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
    +		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
    +		{ BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
    +		
    +	};
    +	int i;
    +
    +	for (i = 0; i < N(v1); i++)
    +		BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
    +	BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
    +	for (i = 0; i < N(v2); i++)
    +		BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
    +
    +	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
    +	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
    +	BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
    +	if (siba->siba_board_rev >= 0x18) {
    +		bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
    +	} else {
    +		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
    +	}
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
    +	BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
    +	BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
    +	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
    +		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
    +	} else {
    +		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
    +	}
    +	for (i = 0; i < N(v3); i++)
    +		BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
    +	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
    +		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
    +		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
    +	}
    +
    +	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    +		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
    +		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
    +	} else
    +		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
    +
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
    +	BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
    +	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
    +	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
    +	    0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
    +	    ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
    +
    +	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
    +		BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
    +	}
    +
    +	bwn_phy_lp_digflt_save(mac);
    +}
    +
    +static void
    +bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	static const struct bwn_smpair v1[] = {
    +		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
    +		{ BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
    +		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
    +		{ BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
    +		{ BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
    +		{ BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
    +		{ BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
    +	};
    +	static const struct bwn_smpair v2[] = {
    +		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
    +		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
    +		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
    +		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
    +		{ BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
    +		{ BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
    +		{ BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
    +		{ BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
    +	};
    +	static const struct bwn_smpair v3[] = {
    +		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
    +		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
    +		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
    +		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
    +		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
    +		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
    +		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
    +		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
    +	};
    +	static const struct bwn_smpair v4[] = {
    +		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
    +		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
    +		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
    +		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
    +		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
    +		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
    +		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
    +		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
    +	};
    +	static const struct bwn_smpair v5[] = {
    +		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
    +		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
    +		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
    +		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
    +		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
    +		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
    +		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
    +	};
    +	int i;
    +	uint16_t tmp, tmp2;
    +
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
    +	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
    +	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
    +	BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
    +	BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
    +	BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
    +	for (i = 0; i < N(v1); i++)
    +		BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
    +	    0xff00, plp->plp_rxpwroffset);
    +	if ((siba->siba_sprom.bf_lo & BWN_BFL_FEM) &&
    +	    ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
    +	   (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF))) {
    +		siba_cc_pmu_set_ldovolt(&siba->siba_cc, SIBA_LDO_PAREF, 0x28);
    +		siba_cc_pmu_set_ldoparef(&siba->siba_cc, 1);
    +		if (mac->mac_phy.rev == 0)
    +			BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
    +			    0xffcf, 0x0010);
    +		bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
    +	} else {
    +		siba_cc_pmu_set_ldoparef(&siba->siba_cc, 0);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
    +		bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
    +	}
    +	tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
    +	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
    +	if (siba->siba_sprom.bf_hi & BWN_BFH_RSSIINV)
    +		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
    +	else
    +		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
    +	bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
    +	    0xfff9, (plp->plp_bxarch << 1));
    +	if (mac->mac_phy.rev == 1 &&
    +	    (siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT)) {
    +		for (i = 0; i < N(v2); i++)
    +			BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
    +			    v2[i].set);
    +	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
    +	    (siba->siba_board_type == 0x048a) || ((mac->mac_phy.rev == 0) &&
    +	    (siba->siba_sprom.bf_lo & BWN_BFL_FEM))) {
    +		for (i = 0; i < N(v3); i++)
    +			BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
    +			    v3[i].set);
    +	} else if (mac->mac_phy.rev == 1 ||
    +		  (siba->siba_sprom.bf_lo & BWN_BFL_FEM)) {
    +		for (i = 0; i < N(v4); i++)
    +			BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
    +			    v4[i].set);
    +	} else {
    +		for (i = 0; i < N(v5); i++)
    +			BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
    +			    v5[i].set);
    +	}
    +	if (mac->mac_phy.rev == 1 &&
    +	    (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF)) {
    +		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
    +		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
    +		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
    +		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
    +	}
    +	if ((siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT) &&
    +	    (siba->siba_chipid == 0x5354) &&
    +	    (siba->siba_chippkg == SIBA_CHIPPACK_BCM4712S)) {
    +		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
    +		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
    +		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
    +		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
    +	}
    +	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    +		BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
    +		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
    +		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
    +	} else {
    +		BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
    +		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
    +	}
    +	if (mac->mac_phy.rev == 1) {
    +		tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
    +		tmp2 = (tmp & 0x03e0) >> 5;
    +		tmp2 |= tmp2 << 5;
    +		BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
    +		tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
    +		tmp2 = (tmp & 0x1f00) >> 8;
    +		tmp2 |= tmp2 << 5;
    +		BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
    +		tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
    +		tmp2 = tmp & 0x00ff;
    +		tmp2 |= tmp << 8;
    +		BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
    +	}
    +}
    +
    +struct bwn_b2062_freq {
    +	uint16_t		freq;
    +	uint8_t			value[6];
    +};
    +
    +static void
    +bwn_phy_lp_b2062_init(struct bwn_mac *mac)
    +{
    +#define	CALC_CTL7(freq, div)						\
    +	(((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
    +#define	CALC_CTL18(freq, div)						\
    +	((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
    +#define	CALC_CTL19(freq, div)						\
    +	((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	static const struct bwn_b2062_freq freqdata_tab[] = {
    +		{ 12000, { 6, 6, 6, 6, 10, 6 } },
    +		{ 13000, { 4, 4, 4, 4, 11, 7 } },
    +		{ 14400, { 3, 3, 3, 3, 12, 7 } },
    +		{ 16200, { 3, 3, 3, 3, 13, 8 } },
    +		{ 18000, { 2, 2, 2, 2, 14, 8 } },
    +		{ 19200, { 1, 1, 1, 1, 14, 9 } }
    +	};
    +	static const struct bwn_wpair v1[] = {
    +		{ BWN_B2062_N_TXCTL3, 0 },
    +		{ BWN_B2062_N_TXCTL4, 0 },
    +		{ BWN_B2062_N_TXCTL5, 0 },
    +		{ BWN_B2062_N_TXCTL6, 0 },
    +		{ BWN_B2062_N_PDNCTL0, 0x40 },
    +		{ BWN_B2062_N_PDNCTL0, 0 },
    +		{ BWN_B2062_N_CALIB_TS, 0x10 },
    +		{ BWN_B2062_N_CALIB_TS, 0 }
    +	};
    +	const struct bwn_b2062_freq *f = NULL;
    +	uint32_t xtalfreq, ref;
    +	unsigned int i;
    +
    +	bwn_phy_lp_b2062_tblinit(mac);
    +
    +	for (i = 0; i < N(v1); i++)
    +		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
    +	if (mac->mac_phy.rev > 0)
    +		BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
    +		    (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
    +	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
    +		BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
    +	else
    +		BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
    +
    +	KASSERT(siba->siba_cc.scc_caps & SIBA_CC_CAPS_PMU,
    +	    ("%s:%d: fail", __func__, __LINE__));
    +	xtalfreq = siba->siba_cc.scc_pmu.freq * 1000;
    +	KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
    +
    +	if (xtalfreq <= 30000000) {
    +		plp->plp_div = 1;
    +		BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
    +	} else {
    +		plp->plp_div = 2;
    +		BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
    +	}
    +
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
    +	    CALC_CTL7(xtalfreq, plp->plp_div));
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
    +	    CALC_CTL18(xtalfreq, plp->plp_div));
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
    +	    CALC_CTL19(xtalfreq, plp->plp_div));
    +
    +	ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
    +	ref &= 0xffff;
    +	for (i = 0; i < N(freqdata_tab); i++) {
    +		if (ref < freqdata_tab[i].freq) {
    +			f = &freqdata_tab[i];
    +			break;
    +		}
    +	}
    +	if (f == NULL)
    +		f = &freqdata_tab[N(freqdata_tab) - 1];
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
    +	    ((uint16_t)(f->value[1]) << 4) | f->value[0]);
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
    +	    ((uint16_t)(f->value[3]) << 4) | f->value[2]);
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
    +#undef CALC_CTL7
    +#undef CALC_CTL18
    +#undef CALC_CTL19
    +}
    +
    +static void
    +bwn_phy_lp_b2063_init(struct bwn_mac *mac)
    +{
    +
    +	bwn_phy_lp_b2063_tblinit(mac);
    +	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
    +	BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
    +	BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
    +	BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
    +	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
    +	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
    +	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
    +	if (mac->mac_phy.rev == 2) {
    +		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
    +		BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
    +		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
    +	} else {
    +		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
    +		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
    +	}
    +}
    +
    +static void
    +bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
    +{
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	static const struct bwn_wpair v1[] = {
    +		{ BWN_B2063_RX_BB_SP8, 0x0 },
    +		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
    +		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
    +		{ BWN_B2063_RC_CALIB_CTL2, 0x15 },
    +		{ BWN_B2063_RC_CALIB_CTL3, 0x70 },
    +		{ BWN_B2063_RC_CALIB_CTL4, 0x52 },
    +		{ BWN_B2063_RC_CALIB_CTL5, 0x1 },
    +		{ BWN_B2063_RC_CALIB_CTL1, 0x7d }
    +	};
    +	static const struct bwn_wpair v2[] = {
    +		{ BWN_B2063_TX_BB_SP3, 0x0 },
    +		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
    +		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
    +		{ BWN_B2063_RC_CALIB_CTL2, 0x55 },
    +		{ BWN_B2063_RC_CALIB_CTL3, 0x76 }
    +	};
    +	uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
    +	int i;
    +	uint8_t tmp;
    +
    +	tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
    +
    +	for (i = 0; i < 2; i++)
    +		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
    +	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
    +	for (i = 2; i < N(v1); i++)
    +		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
    +	for (i = 0; i < 10000; i++) {
    +		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
    +			break;
    +		DELAY(1000);
    +	}
    +
    +	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
    +		BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
    +
    +	tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
    +
    +	for (i = 0; i < N(v2); i++)
    +		BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
    +	if (freqxtal == 24000000) {
    +		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
    +		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
    +	} else {
    +		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
    +		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
    +	}
    +	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
    +	for (i = 0; i < 10000; i++) {
    +		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
    +			break;
    +		DELAY(1000);
    +	}
    +	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
    +		BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
    +	BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
    +}
    +
    +static void
    +bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_phy_lp_iq_est ie;
    +	struct bwn_txgain tx_gains;
    +	static const uint32_t pwrtbl[21] = {
    +		0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
    +		0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
    +		0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
    +		0x0004c, 0x0002c, 0x0001a,
    +	};
    +	uint32_t npwr, ipwr, sqpwr, tmp;
    +	int loopback, i, j, sum, error;
    +	uint16_t save[7];
    +	uint8_t txo, bbmult, txpctlmode;
    +
    +	error = bwn_phy_lp_switch_channel(mac, 7);
    +	if (error)
    +		device_printf(sc->sc_dev,
    +		    "failed to change channel to 7 (%d)\n", error);
    +	txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
    +	bbmult = bwn_phy_lp_get_bbmult(mac);
    +	if (txo)
    +		tx_gains = bwn_phy_lp_get_txgain(mac);
    +
    +	save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
    +	save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
    +	save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
    +	save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
    +	save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
    +	save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
    +	save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
    +
    +	bwn_phy_lp_get_txpctlmode(mac);
    +	txpctlmode = plp->plp_txpctlmode;
    +	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
    +
    +	/* disable CRS */
    +	bwn_phy_lp_set_deaf(mac, 1);
    +	bwn_phy_lp_set_trsw_over(mac, 0, 1);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
    +	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
    +	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
    +	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
    +	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
    +
    +	loopback = bwn_phy_lp_loopback(mac);
    +	if (loopback == -1)
    +		goto done;
    +	bwn_phy_lp_set_rxgain_idx(mac, loopback);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
    +
    +	tmp = 0;
    +	memset(&ie, 0, sizeof(ie));
    +	for (i = 128; i <= 159; i++) {
    +		BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
    +		sum = 0;
    +		for (j = 5; j <= 25; j++) {
    +			bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
    +			if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
    +				goto done;
    +			sqpwr = ie.ie_ipwr + ie.ie_qpwr;
    +			ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
    +			npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
    +			    12);
    +			sum += ((ipwr - npwr) * (ipwr - npwr));
    +			if ((i == 128) || (sum < tmp)) {
    +				plp->plp_rccap = i;
    +				tmp = sum;
    +			}
    +		}
    +	}
    +	bwn_phy_lp_ddfs_turnoff(mac);
    +done:
    +	/* restore CRS */
    +	bwn_phy_lp_clear_deaf(mac, 1);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
    +	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
    +	BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
    +
    +	bwn_phy_lp_set_bbmult(mac, bbmult);
    +	if (txo)
    +		bwn_phy_lp_set_txgain(mac, &tx_gains);
    +	bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
    +	if (plp->plp_rccap)
    +		bwn_phy_lp_set_rccap(mac);
    +}
    +
    +static void
    +bwn_phy_lp_set_rccap(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
    +
    +	if (mac->mac_phy.rev == 1)
    +		rc_cap = MIN(rc_cap + 5, 15);
    +
    +	BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
    +	    MAX(plp->plp_rccap - 4, 0x80));
    +	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
    +	    ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
    +}
    +
    +static uint32_t
    +bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
    +{
    +	uint32_t i, q, r;
    +
    +	if (div == 0)
    +		return (0);
    +
    +	for (i = 0, q = value / div, r = value % div; i < pre; i++) {
    +		q <<= 1;
    +		if (r << 1 >= div) {
    +			q++;
    +			r = (r << 1) - div;
    +		}
    +	}
    +	if (r << 1 >= div)
    +		q++;
    +	return (q);
    +}
    +
    +static void
    +bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
    +{
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
    +	DELAY(20);
    +	if (siba->siba_chipid == 0x5354) {
    +		BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
    +		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
    +	} else {
    +		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
    +	}
    +	DELAY(5);
    +}
    +
    +static void
    +bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
    +{
    +
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
    +	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
    +	DELAY(200);
    +}
    +
    +static void
    +bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
    +{
    +#define	FLAG_A	0x01
    +#define	FLAG_G	0x02
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
    +		{ BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
    +		{ BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
    +		{ BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
    +		{ BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
    +	};
    +	const struct bwn_b206x_rfinit_entry *br;
    +	unsigned int i;
    +
    +	for (i = 0; i < N(bwn_b2062_init_tab); i++) {
    +		br = &bwn_b2062_init_tab[i];
    +		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    +			if (br->br_flags & FLAG_G)
    +				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
    +		} else {
    +			if (br->br_flags & FLAG_A)
    +				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
    +		}
    +	}
    +#undef FLAG_A
    +#undef FLAG_B
    +}
    +
    +static void
    +bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
    +{
    +#define	FLAG_A	0x01
    +#define	FLAG_G	0x02
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
    +		{ BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
    +		{ BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
    +		{ BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
    +		{ BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
    +		{ BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
    +		{ BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
    +		{ BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
    +		{ BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
    +		{ BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
    +		{ BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
    +		{ BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
    +	};
    +	const struct bwn_b206x_rfinit_entry *br;
    +	unsigned int i;
    +
    +	for (i = 0; i < N(bwn_b2063_init_tab); i++) {
    +		br = &bwn_b2063_init_tab[i];
    +		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    +			if (br->br_flags & FLAG_G)
    +				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
    +		} else {
    +			if (br->br_flags & FLAG_A)
    +				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
    +		}
    +	}
    +#undef FLAG_A
    +#undef FLAG_B
    +}
    +
    +static void
    +bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
    +    int count, void *_data)
    +{
    +	unsigned int i;
    +	uint32_t offset, type;
    +	uint8_t *data = _data;
    +
    +	type = BWN_TAB_GETTYPE(typenoffset);
    +	offset = BWN_TAB_GETOFFSET(typenoffset);
    +	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
    +
    +	for (i = 0; i < count; i++) {
    +		switch (type) {
    +		case BWN_TAB_8BIT:
    +			*data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
    +			data++;
    +			break;
    +		case BWN_TAB_16BIT:
    +			*((uint16_t *)data) = BWN_PHY_READ(mac,
    +			    BWN_PHY_TABLEDATALO);
    +			data += 2;
    +			break;
    +		case BWN_TAB_32BIT:
    +			*((uint32_t *)data) = BWN_PHY_READ(mac,
    +			    BWN_PHY_TABLEDATAHI);
    +			*((uint32_t *)data) <<= 16;
    +			*((uint32_t *)data) |= BWN_PHY_READ(mac,
    +			    BWN_PHY_TABLEDATALO);
    +			data += 4;
    +			break;
    +		default:
    +			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +		}
    +	}
    +}
    +
    +static void
    +bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
    +    int count, const void *_data)
    +{
    +	uint32_t offset, type, value;
    +	const uint8_t *data = _data;
    +	unsigned int i;
    +
    +	type = BWN_TAB_GETTYPE(typenoffset);
    +	offset = BWN_TAB_GETOFFSET(typenoffset);
    +	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
    +
    +	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
    +
    +	for (i = 0; i < count; i++) {
    +		switch (type) {
    +		case BWN_TAB_8BIT:
    +			value = *data;
    +			data++;
    +			KASSERT(!(value & ~0xff),
    +			    ("%s:%d: fail", __func__, __LINE__));
    +			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
    +			break;
    +		case BWN_TAB_16BIT:
    +			value = *((const uint16_t *)data);
    +			data += 2;
    +			KASSERT(!(value & ~0xffff),
    +			    ("%s:%d: fail", __func__, __LINE__));
    +			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
    +			break;
    +		case BWN_TAB_32BIT:
    +			value = *((const uint32_t *)data);
    +			data += 4;
    +			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
    +			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
    +			break;
    +		default:
    +			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +		}
    +	}
    +}
    +
    +static struct bwn_txgain
    +bwn_phy_lp_get_txgain(struct bwn_mac *mac)
    +{
    +	struct bwn_txgain tg;
    +	uint16_t tmp;
    +
    +	tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
    +	if (mac->mac_phy.rev < 2) {
    +		tmp = BWN_PHY_READ(mac,
    +		    BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
    +		tg.tg_gm = tmp & 0x0007;
    +		tg.tg_pga = (tmp & 0x0078) >> 3;
    +		tg.tg_pad = (tmp & 0x780) >> 7;
    +		return (tg);
    +	}
    +
    +	tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
    +	tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
    +	tg.tg_gm = tmp & 0xff;
    +	tg.tg_pga = (tmp >> 8) & 0xff;
    +	return (tg);
    +}
    +
    +static uint8_t
    +bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
    +{
    +
    +	return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
    +}
    +
    +static void
    +bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
    +{
    +	uint16_t pa;
    +
    +	if (mac->mac_phy.rev < 2) {
    +		BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
    +		    (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
    +		bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
    +		bwn_phy_lp_set_txgain_override(mac);
    +		return;
    +	}
    +
    +	pa = bwn_phy_lp_get_pa_gain(mac);
    +	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
    +	    (tg->tg_pga << 8) | tg->tg_gm);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
    +	    tg->tg_pad | (pa << 6));
    +	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
    +	    tg->tg_pad | (pa << 8));
    +	bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
    +	bwn_phy_lp_set_txgain_override(mac);
    +}
    +
    +static void
    +bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
    +{
    +
    +	bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
    +}
    +
    +static void
    +bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
    +{
    +	uint16_t trsw = (tx << 1) | rx;
    +
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
    +}
    +
    +static void
    +bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
    +
    +	if (mac->mac_phy.rev < 2) {
    +		trsw = gain & 0x1;
    +		lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
    +		ext_lna = (gain & 2) >> 1;
    +
    +		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
    +		    0xfbff, ext_lna << 10);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
    +		    0xf7ff, ext_lna << 11);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
    +	} else {
    +		low_gain = gain & 0xffff;
    +		high_gain = (gain >> 16) & 0xf;
    +		ext_lna = (gain >> 21) & 0x1;
    +		trsw = ~(gain >> 20) & 0x1;
    +
    +		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
    +		    0xfdff, ext_lna << 9);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
    +		    0xfbff, ext_lna << 10);
    +		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
    +		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
    +		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    +			tmp = (gain >> 2) & 0x3;
    +			BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
    +			    0xe7ff, tmp<<11);
    +			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
    +			    tmp << 3);
    +		}
    +	}
    +
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
    +	if (mac->mac_phy.rev >= 2) {
    +		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
    +		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    +			BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
    +			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
    +		}
    +		return;
    +	}
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
    +}
    +
    +static void
    +bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +
    +	if (user)
    +		plp->plp_crsusr_off = 1;
    +	else
    +		plp->plp_crssys_off = 1;
    +
    +	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
    +}
    +
    +static void
    +bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
    +{
    +	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +
    +	if (user)
    +		plp->plp_crsusr_off = 0;
    +	else
    +		plp->plp_crssys_off = 0;
    +
    +	if (plp->plp_crsusr_off || plp->plp_crssys_off)
    +		return;
    +
    +	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
    +		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
    +	else
    +		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
    +}
    +
    +static unsigned int
    +bwn_sqrt(struct bwn_mac *mac, unsigned int x)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	/* 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
    +	};
    +
    +	if (x == 0)
    +		return (0);
    +	if (x >= 256) {
    +		device_printf(sc->sc_dev,
    +		    "out of bounds of the square-root table (%d)\n", x);
    +		return (16);
    +	}
    +	return (sqrt_table[x - 1] / 10);
    +}
    +
    +static int
    +bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
    +{
    +#define	CALC_COEFF(_v, _x, _y, _z)	do {				\
    +	int _t;								\
    +	_t = _x - 20;							\
    +	if (_t >= 0) {							\
    +		_v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
    +	} else {							\
    +		_v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
    +	}								\
    +} while (0)
    +#define	CALC_COEFF2(_v, _x, _y, _z)	do {				\
    +	int _t;								\
    +	_t = _x - 11;							\
    +	if (_t >= 0)							\
    +		tmp[3] = (_y << (31 - _x)) / (_z >> _t);		\
    +	else								\
    +		tmp[3] = (_y << (31 - _x)) / (_z << -_t);		\
    +} while (0)
    +	struct bwn_phy_lp_iq_est ie;
    +	uint16_t v0, v1;
    +	int tmp[2], ret;
    +
    +	v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
    +	v0 = v1 >> 8;
    +	v1 |= 0xff;
    +
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
    +	BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
    +
    +	ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
    +	if (ret == 0)
    +		goto done;
    +
    +	if (ie.ie_ipwr + ie.ie_qpwr < 2) {
    +		ret = 0;
    +		goto done;
    +	}
    +
    +	CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
    +	CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
    +
    +	tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
    +	v0 = tmp[0] >> 3;
    +	v1 = tmp[1] >> 4;
    +done:
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
    +	return ret;
    +#undef CALC_COEFF
    +#undef CALC_COEFF2
    +}
    +
    +static void
    +bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
    +{
    +	static const uint16_t noisescale[] = {
    +		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
    +		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
    +		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
    +		0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
    +	};
    +	static const uint16_t crsgainnft[] = {
    +		0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
    +		0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
    +		0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
    +		0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
    +		0x013d,
    +	};
    +	static const uint16_t filterctl[] = {
    +		0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
    +		0xff53, 0x0127,
    +	};
    +	static const uint32_t psctl[] = {
    +		0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
    +		0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
    +		0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
    +		0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
    +		0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
    +		0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
    +		0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
    +		0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
    +	};
    +	static const uint16_t ofdmcckgain_r0[] = {
    +		0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
    +		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
    +		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
    +		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
    +		0x755d,
    +	};
    +	static const uint16_t ofdmcckgain_r1[] = {
    +		0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
    +		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
    +		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
    +		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
    +		0x755d,
    +	};
    +	static const uint16_t gaindelta[] = {
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000,
    +	};
    +	static const uint32_t txpwrctl[] = {
    +		0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
    +		0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
    +		0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
    +		0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
    +		0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
    +		0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
    +		0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
    +		0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
    +		0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
    +		0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
    +		0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
    +		0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
    +		0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
    +		0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
    +		0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
    +		0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
    +		0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
    +		0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
    +		0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
    +		0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
    +		0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
    +		0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
    +		0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
    +		0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
    +		0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
    +		0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
    +		0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
    +		0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
    +		0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
    +		0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
    +		0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
    +		0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
    +		0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
    +		0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
    +		0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
    +		0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
    +		0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
    +		0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
    +		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
    +		0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
    +		0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
    +		0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
    +		0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
    +		0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
    +		0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
    +		0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
    +		0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
    +		0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
    +		0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
    +		0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
    +		0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
    +		0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
    +		0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
    +		0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
    +		0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
    +		0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
    +		0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
    +		0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
    +		0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
    +		0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
    +		0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
    +		0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
    +		0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
    +		0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
    +		0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
    +		0x00000702,
    +	};
    +
    +	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
    +
    +	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
    +	    bwn_tab_sigsq_tbl);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
    +	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
    +	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
    +	    bwn_tab_pllfrac_tbl);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
    +	    bwn_tabl_iqlocal_tbl);
    +	if (mac->mac_phy.rev == 0) {
    +		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
    +		    ofdmcckgain_r0);
    +		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
    +		    ofdmcckgain_r0);
    +	} else {
    +		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
    +		    ofdmcckgain_r1);
    +		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
    +		    ofdmcckgain_r1);
    +	}
    +	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
    +	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
    +}
    +
    +static void
    +bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
    +{
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	int i;
    +	static const uint16_t noisescale[] = {
    +		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
    +		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
    +		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
    +		0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
    +		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
    +		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
    +		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
    +	};
    +	static const uint32_t filterctl[] = {
    +		0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
    +		0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
    +	};
    +	static const uint32_t psctl[] = {
    +		0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
    +		0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
    +		0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
    +		0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
    +	};
    +	static const uint32_t gainidx[] = {
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
    +		0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
    +		0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
    +		0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
    +		0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
    +		0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
    +		0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
    +		0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
    +		0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
    +		0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
    +		0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
    +		0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
    +		0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
    +		0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
    +		0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
    +		0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
    +		0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
    +		0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
    +		0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
    +		0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
    +		0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
    +		0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
    +		0x0000001a, 0x64ca55ad, 0x0000001a
    +	};
    +	static const uint16_t auxgainidx[] = {
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
    +		0x0004, 0x0016
    +	};
    +	static const uint16_t swctl[] = {
    +		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
    +		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
    +		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
    +		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
    +		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
    +		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
    +		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
    +		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
    +	};
    +	static const uint8_t hf[] = {
    +		0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
    +		0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
    +	};
    +	static const uint32_t gainval[] = {
    +		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
    +		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
    +		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
    +		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
    +		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
    +		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
    +		0x000000f1, 0x00000000, 0x00000000
    +	};
    +	static const uint16_t gain[] = {
    +		0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
    +		0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
    +		0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
    +		0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
    +		0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
    +		0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
    +	};
    +	static const uint32_t papdeps[] = {
    +		0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
    +		0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
    +		0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
    +		0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
    +		0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
    +		0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
    +		0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
    +		0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
    +		0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
    +		0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
    +		0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
    +		0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
    +		0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
    +	};
    +	static const uint32_t papdmult[] = {
    +		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
    +		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
    +		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
    +		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
    +		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
    +		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
    +		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
    +		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
    +		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
    +		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
    +		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
    +		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
    +		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
    +	};
    +	static const uint32_t gainidx_a0[] = {
    +		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
    +		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
    +		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
    +		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
    +		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
    +		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
    +		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
    +		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
    +		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
    +		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
    +		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
    +		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
    +		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
    +	};
    +	static const uint16_t auxgainidx_a0[] = {
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0002, 0x0014
    +	};
    +	static const uint32_t gainval_a0[] = {
    +		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
    +		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
    +		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
    +		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
    +		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
    +		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
    +		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
    +		0x000000f7, 0x00000000, 0x00000000
    +	};
    +	static const uint16_t gain_a0[] = {
    +		0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
    +		0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
    +		0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
    +		0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
    +		0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
    +		0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    +		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
    +	};
    +
    +	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
    +
    +	for (i = 0; i < 704; i++)
    +		bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
    +
    +	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
    +	    bwn_tab_sigsq_tbl);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
    +	bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
    +	bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
    +	bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
    +	bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
    +	bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
    +	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
    +	    bwn_tab_pllfrac_tbl);
    +	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
    +	    bwn_tabl_iqlocal_tbl);
    +	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
    +	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
    +
    +	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
    +		bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
    +		    gainidx_a0);
    +		bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
    +		    auxgainidx_a0);
    +		bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
    +		    gainval_a0);
    +		bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
    +	}
    +}
    +
    +static void
    +bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
    +{
    +	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	static struct bwn_txgain_entry txgain_r2[] = {
    +		{ 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
    +		{ 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
    +		{ 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
    +		{ 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
    +		{ 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
    +		{ 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
    +		{ 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
    +		{ 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
    +		{ 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
    +		{ 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
    +		{ 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
    +		{ 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
    +		{ 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
    +		{ 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
    +		{ 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
    +		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
    +		{ 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
    +		{ 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
    +		{ 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
    +		{ 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
    +		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
    +		{ 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
    +		{ 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
    +		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
    +		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
    +		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
    +		{ 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
    +		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
    +		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
    +		{ 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
    +		{ 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
    +		{ 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
    +		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
    +		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
    +		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
    +		{ 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
    +		{ 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
    +		{ 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
    +		{ 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
    +		{ 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
    +		{ 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
    +		{ 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
    +		{ 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
    +		{ 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
    +		{ 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
    +		{ 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
    +		{ 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
    +		{ 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
    +		{ 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
    +		{ 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
    +		{ 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
    +		{ 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
    +		{ 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
    +		{ 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
    +		{ 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
    +		{ 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
    +		{ 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
    +		{ 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
    +		{ 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
    +		{ 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
    +		{ 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
    +		{ 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
    +		{ 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
    +		{ 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
    +	};
    +	static struct bwn_txgain_entry txgain_2ghz_r2[] = {
    +		{ 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
    +		{ 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
    +		{ 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
    +		{ 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
    +		{ 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
    +		{ 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
    +		{ 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
    +		{ 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
    +		{ 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
    +		{ 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
    +		{ 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
    +		{ 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
    +		{ 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
    +		{ 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
    +		{ 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
    +		{ 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
    +		{ 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
    +		{ 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
    +		{ 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
    +		{ 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
    +		{ 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
    +		{ 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
    +		{ 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
    +		{ 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
    +		{ 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
    +		{ 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
    +		{ 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
    +		{ 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
    +		{ 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
    +		{ 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
    +		{ 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
    +		{ 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
    +		{ 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
    +		{ 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
    +		{ 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
    +		{ 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
    +		{ 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
    +		{ 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
    +		{ 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
    +		{ 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
    +		{ 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
    +		{ 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
    +		{ 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
    +		{ 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
    +		{ 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
    +		{ 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
    +		{ 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
    +		{ 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
    +		{ 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
    +		{ 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
    +		{ 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
    +		{ 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
    +		{ 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
    +		{ 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
    +		{ 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
    +		{ 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
    +		{ 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
    +		{ 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
    +		{ 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
    +		{ 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
    +		{ 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
    +		{ 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
    +		{ 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
    +		{ 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
    +	};
    +	static struct bwn_txgain_entry txgain_5ghz_r2[] = {
    +		{ 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
    +		{ 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
    +		{ 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
    +		{ 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
    +		{ 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
    +		{ 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
    +		{ 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
    +		{ 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
    +		{ 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
    +		{ 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
    +		{ 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
    +		{ 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
    +		{ 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
    +		{ 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
    +		{ 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
    +		{ 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
    +		{ 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
    +		{ 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
    +		{ 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
    +		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
    +		{ 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
    +		{ 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
    +		{ 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
    +		{ 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
    +		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
    +		{ 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
    +		{ 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
    +		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
    +		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
    +		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
    +		{ 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
    +		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
    +		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
    +		{ 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
    +		{ 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
    +		{ 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
    +		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
    +		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
    +		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
    +		{ 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
    +		{ 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
    +		{ 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
    +		{ 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
    +		{ 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
    +		{ 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
    +		{ 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
    +		{ 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
    +		{ 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
    +		{ 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
    +		{ 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
    +		{ 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
    +		{ 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
    +		{ 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
    +		{ 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
    +		{ 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
    +		{ 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
    +		{ 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
    +		{ 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
    +		{ 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
    +		{ 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
    +		{ 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
    +		{ 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
    +		{ 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
    +		{ 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
    +	};
    +	static struct bwn_txgain_entry txgain_r0[] = {
    +		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
    +		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
    +		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
    +		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
    +		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
    +		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
    +		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
    +		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
    +		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
    +		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
    +		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
    +		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
    +		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
    +		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
    +		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
    +		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
    +		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
    +		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
    +		{ 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
    +		{ 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
    +		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
    +		{ 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
    +		{ 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
    +		{ 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
    +		{ 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
    +		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
    +		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
    +		{ 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
    +		{ 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
    +		{ 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
    +		{ 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
    +		{ 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
    +		{ 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
    +		{ 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
    +		{ 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
    +		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
    +		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
    +		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
    +		{ 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
    +		{ 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
    +		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
    +		{ 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
    +		{ 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
    +		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
    +		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
    +		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
    +		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
    +		{ 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
    +		{ 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
    +		{ 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
    +		{ 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
    +		{ 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
    +		{ 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
    +		{ 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
    +		{ 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
    +		{ 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
    +		{ 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
    +		{ 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
    +		{ 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
    +		{ 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
    +		{ 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
    +		{ 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
    +		{ 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
    +		{ 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
    +	};
    +	static struct bwn_txgain_entry txgain_2ghz_r0[] = {
    +		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
    +		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
    +		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
    +		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
    +		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
    +		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
    +		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
    +		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
    +		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
    +		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
    +		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
    +		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
    +		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
    +		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
    +		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
    +		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
    +		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
    +		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
    +		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
    +		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
    +		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
    +		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
    +		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
    +		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
    +		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
    +		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
    +		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
    +		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
    +		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
    +		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
    +		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
    +		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
    +		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
    +		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
    +		{ 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
    +		{ 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
    +		{ 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
    +		{ 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
    +		{ 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
    +		{ 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
    +		{ 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
    +		{ 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
    +		{ 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
    +		{ 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
    +		{ 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
    +		{ 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
    +		{ 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
    +		{ 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
    +		{ 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
    +		{ 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
    +		{ 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
    +		{ 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
    +		{ 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
    +		{ 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
    +		{ 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
    +		{ 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
    +		{ 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
    +		{ 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
    +		{ 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
    +		{ 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
    +		{ 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
    +		{ 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
    +		{ 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
    +		{ 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
    +	};
    +	static struct bwn_txgain_entry txgain_5ghz_r0[] = {
    +		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
    +		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
    +		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
    +		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
    +		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
    +		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
    +		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
    +		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
    +		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
    +		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
    +		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
    +		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
    +		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
    +		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
    +		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
    +		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
    +		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
    +		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
    +		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
    +		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
    +		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
    +		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
    +		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
    +		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
    +		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
    +		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
    +		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
    +		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
    +		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
    +		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
    +		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
    +		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
    +		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
    +		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
    +		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
    +		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
    +		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
    +		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
    +		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
    +		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
    +		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
    +		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
    +		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
    +		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
    +		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
    +		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
    +		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
    +		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
    +		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
    +		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
    +		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
    +		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
    +		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
    +		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
    +		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
    +		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
    +		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
    +		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
    +		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
    +		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
    +		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
    +		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
    +		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
    +		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
    +	};
    +	static struct bwn_txgain_entry txgain_r1[] = {
    +		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
    +		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
    +		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
    +		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
    +		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
    +		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
    +		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
    +		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
    +		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
    +		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
    +		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
    +		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
    +		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
    +		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
    +		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
    +		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
    +		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
    +		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
    +		{ 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
    +		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
    +		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
    +		{ 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
    +		{ 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
    +		{ 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
    +		{ 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
    +		{ 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
    +		{ 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
    +		{ 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
    +		{ 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
    +		{ 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
    +		{ 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
    +		{ 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
    +		{ 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
    +		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
    +		{ 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
    +		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
    +		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
    +		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
    +		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
    +		{ 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
    +		{ 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
    +		{ 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
    +		{ 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
    +		{ 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
    +		{ 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
    +		{ 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
    +		{ 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
    +		{ 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
    +		{ 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
    +		{ 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
    +		{ 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
    +		{ 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
    +		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
    +		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
    +		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
    +		{ 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
    +		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
    +		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
    +		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
    +		{ 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
    +		{ 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
    +		{ 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
    +		{ 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
    +		{ 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
    +		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
    +		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
    +		{ 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
    +		{ 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
    +		{ 7, 11, 6, 0, 71 }
    +	};
    +	static struct bwn_txgain_entry txgain_2ghz_r1[] = {
    +		{ 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
    +		{ 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
    +		{ 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
    +		{ 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
    +		{ 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
    +		{ 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
    +		{ 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
    +		{ 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
    +		{ 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
    +		{ 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
    +		{ 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
    +		{ 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
    +		{ 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
    +		{ 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
    +		{ 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
    +		{ 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
    +		{ 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
    +		{ 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
    +		{ 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
    +		{ 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
    +		{ 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
    +		{ 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
    +		{ 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
    +		{ 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
    +		{ 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
    +		{ 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
    +		{ 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
    +		{ 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
    +		{ 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
    +		{ 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
    +		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
    +		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
    +		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
    +		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
    +		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
    +		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
    +		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
    +		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
    +		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
    +		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
    +		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
    +		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
    +		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
    +		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
    +		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
    +		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
    +		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
    +		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
    +		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
    +		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
    +		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
    +		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
    +		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
    +		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
    +		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
    +		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
    +		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
    +		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
    +		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
    +		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
    +		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
    +		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
    +		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
    +		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
    +	};
    +	static struct bwn_txgain_entry txgain_5ghz_r1[] = {
    +		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
    +		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
    +		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
    +		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
    +		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
    +		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
    +		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
    +		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
    +		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
    +		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
    +		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
    +		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
    +		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
    +		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
    +		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
    +		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
    +		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
    +		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
    +		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
    +		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
    +		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
    +		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
    +		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
    +		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
    +		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
    +		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
    +		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
    +		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
    +		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
    +		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
    +		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
    +		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
    +		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
    +		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
    +		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
    +		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
    +		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
    +		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
    +		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
    +		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
    +		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
    +		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
    +		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
    +		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
    +		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
    +		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
    +		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
    +		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
    +		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
    +		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
    +		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
    +		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
    +		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
    +		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
    +		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
    +		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
    +		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
    +		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
    +		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
    +		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
    +		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
    +		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
    +		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
    +		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
    +	};
    +
    +	if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
    +		if (siba->siba_sprom.bf_hi & BWN_BFH_NOPA)
    +			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
    +		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
    +			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
    +			    txgain_2ghz_r2);
    +		else
    +			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
    +			    txgain_5ghz_r2);
    +		return;
    +	}
    +
    +	if (mac->mac_phy.rev == 0) {
    +		if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) ||
    +		    (siba->siba_sprom.bf_lo & BWN_BFL_HGPA))
    +			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
    +		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
    +			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
    +			    txgain_2ghz_r0);
    +		else
    +			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
    +			    txgain_5ghz_r0);
    +		return;
    +	}
    +
    +	if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) ||
    +	    (siba->siba_sprom.bf_lo & BWN_BFL_HGPA))
    +		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
    +	else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
    +		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
    +	else
    +		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
    +}
    +
    +static void
    +bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
    +{
    +	uint32_t offset, type;
    +
    +	type = BWN_TAB_GETTYPE(typeoffset);
    +	offset = BWN_TAB_GETOFFSET(typeoffset);
    +	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
    +
    +	switch (type) {
    +	case BWN_TAB_8BIT:
    +		KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
    +		break;
    +	case BWN_TAB_16BIT:
    +		KASSERT(!(value & ~0xffff),
    +		    ("%s:%d: fail", __func__, __LINE__));
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
    +		break;
    +	case BWN_TAB_32BIT:
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
    +		break;
    +	default:
    +		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	}
    +}
    +
    +static int
    +bwn_phy_lp_loopback(struct bwn_mac *mac)
    +{
    +	struct bwn_phy_lp_iq_est ie;
    +	int i, index = -1;
    +	uint32_t tmp;
    +
    +	memset(&ie, 0, sizeof(ie));
    +
    +	bwn_phy_lp_set_trsw_over(mac, 1, 1);
    +	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
    +	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
    +	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
    +	for (i = 0; i < 32; i++) {
    +		bwn_phy_lp_set_rxgain_idx(mac, i);
    +		bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
    +		if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
    +			continue;
    +		tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
    +		if ((tmp > 4000) && (tmp < 10000)) {
    +			index = i;
    +			break;
    +		}
    +	}
    +	bwn_phy_lp_ddfs_turnoff(mac);
    +	return (index);
    +}
    +
    +static void
    +bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
    +{
    +
    +	bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
    +}
    +
    +static void
    +bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
    +    int incr1, int incr2, int scale_idx)
    +{
    +
    +	bwn_phy_lp_ddfs_turnoff(mac);
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
    +	BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
    +	BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
    +}
    +
    +static uint8_t
    +bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
    +    struct bwn_phy_lp_iq_est *ie)
    +{
    +	int i;
    +
    +	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
    +	BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
    +	BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
    +	BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
    +
    +	for (i = 0; i < 500; i++) {
    +		if (!(BWN_PHY_READ(mac,
    +		    BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
    +			break;
    +		DELAY(1000);
    +	}
    +	if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
    +		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
    +		return 0;
    +	}
    +
    +	ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
    +	ie->ie_iqprod <<= 16;
    +	ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
    +	ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
    +	ie->ie_ipwr <<= 16;
    +	ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
    +	ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
    +	ie->ie_qpwr <<= 16;
    +	ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
    +
    +	BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
    +	return 1;
    +}
    +
    +static uint32_t
    +bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
    +{
    +	uint32_t offset, type, value;
    +
    +	type = BWN_TAB_GETTYPE(typeoffset);
    +	offset = BWN_TAB_GETOFFSET(typeoffset);
    +	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
    +
    +	switch (type) {
    +	case BWN_TAB_8BIT:
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
    +		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
    +		break;
    +	case BWN_TAB_16BIT:
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
    +		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
    +		break;
    +	case BWN_TAB_32BIT:
    +		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
    +		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
    +		value <<= 16;
    +		value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
    +		break;
    +	default:
    +		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +		value = 0;
    +	}
    +
    +	return (value);
    +}
    +
    +static void
    +bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
    +{
    +
    +	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
    +	BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
    +}
    +
    +static void
    +bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
    +{
    +	uint16_t ctl;
    +
    +	ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
    +	ctl |= dac << 7;
    +	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
    +}
    +
    +static void
    +bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
    +{
    +
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
    +	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
    +}
    +
    +static void
    +bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
    +{
    +
    +	if (mac->mac_phy.rev < 2)
    +		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
    +	else {
    +		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
    +		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
    +	}
    +	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
    +}
    +
    +static uint16_t
    +bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
    +{
    +
    +	return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
    +}
    +
    +static uint8_t
    +bwn_nbits(int32_t val)
    +{
    +	uint32_t tmp;
    +	uint8_t nbits = 0;
    +
    +	for (tmp = abs(val); tmp != 0; tmp >>= 1)
    +		nbits++;
    +	return (nbits);
    +}
    +
    +static void
    +bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
    +    struct bwn_txgain_entry *table)
    +{
    +	int i;
    +
    +	for (i = offset; i < count; i++)
    +		bwn_phy_lp_gaintbl_write(mac, i, table[i]);
    +}
    +
    +static void
    +bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
    +    struct bwn_txgain_entry data)
    +{
    +
    +	if (mac->mac_phy.rev >= 2)
    +		bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
    +	else
    +		bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
    +}
    +
    +static void
    +bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
    +    struct bwn_txgain_entry te)
    +{
    +	struct bwn_softc *sc = mac->mac_sc;
    +	struct ifnet *ifp = sc->sc_ifp;
    +	struct ieee80211com *ic = ifp->if_l2com;
    +	uint32_t tmp;
    +
    +	KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
    +
    +	tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
    +	if (mac->mac_phy.rev >= 3) {
    +		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
    +		    (0x10 << 24) : (0x70 << 24));
    +	} else {
    +		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
    +		    (0x14 << 24) : (0x7f << 24));
    +	}
    +	bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
    +	bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
    +	    te.te_bbmult << 20 | te.te_dac << 28);
    +}
    +
    +static void
    +bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
    +    struct bwn_txgain_entry te)
    +{
    +
    +	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
    +
    +	bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
    +	    (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
    +	    te.te_dac);
    +	bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
    +}
    +
    +static void
    +bwn_identify(driver_t *driver, device_t parent)
    +{
    +
    +	BUS_ADD_CHILD(parent, 0, "bwn", -1);
    +}
    +
    +static device_method_t bwn_methods[] = {
    +	/* Device interface */
    +	DEVMETHOD(device_identify,	bwn_identify),
    +	DEVMETHOD(device_probe,		bwn_probe),
    +	DEVMETHOD(device_attach,	bwn_attach),
    +	DEVMETHOD(device_detach,	bwn_detach),
    +	DEVMETHOD(device_suspend,	bwn_suspend),
    +	DEVMETHOD(device_resume,	bwn_resume),
    +	{ 0,0 }
    +};
    +static driver_t bwn_driver = {
    +	"bwn",
    +	bwn_methods,
    +	sizeof(struct bwn_softc)
    +};
    +static devclass_t bwn_devclass;
    +DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
    +MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
    +MODULE_DEPEND(bwn, wlan, 1, 1, 1);		/* 802.11 media layer */
    +MODULE_DEPEND(bwn, firmware, 1, 1, 1);		/* firmware support */
    +MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);
    diff --git a/sys/dev/bwn/if_bwnreg.h b/sys/dev/bwn/if_bwnreg.h
    new file mode 100644
    index 00000000000..71f56f4da50
    --- /dev/null
    +++ b/sys/dev/bwn/if_bwnreg.h
    @@ -0,0 +1,998 @@
    +/*-
    + * Copyright (c) 2009-2010 Weongyo Jeong 
    + * 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.
    + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    + *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
    + *    redistribution must be conditioned upon including a substantially
    + *    similar Disclaimer requirement for further binary redistribution.
    + *
    + * NO WARRANTY
    + * 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 NONINFRINGEMENT, MERCHANTIBILITY
    + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
    + *
    + * $FreeBSD$
    + */
    +
    +#ifndef _IF_BWNREG_H
    +#define	_IF_BWNREG_H
    +
    +#define	PCI_VENDOR_COMPAQ		0x0e11
    +#define	PCI_VENDOR_DELL			0x1028
    +#define	PCI_VENDOR_HP			0x103c
    +#define	PCI_VENDOR_ASUSTEK		0x1043
    +#define	PCI_VENDOR_MOTOROLA		0x1057
    +#define	PCI_VENDOR_APPLE		0x106b
    +#define	PCI_VENDOR_BROADCOM		0x14e4
    +#define	PCI_VENDOR_LINKSYS		0x1737
    +
    +#define	BWN_BFL_BTCOEXIST		0x0001
    +#define	BWN_BFL_PACTRL			0x0002
    +#define	BWN_BFL_RSSI			0x0008
    +#define	BWN_BFL_CRYSTAL_NOSLOW		0x0020
    +#define	BWN_BFL_FEM			0x0800
    +#define	BWN_BFL_EXTLNA			0x1000
    +#define	BWN_BFL_HGPA			0x2000	/* had high gain PA */
    +#define	BWN_BFL_BTCMOD			0x4000
    +#define	BWN_BFL_ALTIQ			0x8000
    +
    +#define	BWN_BFH_NOPA			0x0001
    +#define	BWN_BFH_RSSIINV			0x0002
    +#define	BWN_BFH_LDO_PAREF		0x0004
    +#define	BWN_BFH_FEM_BT			0x0040
    +
    +#define	BWN_TGSLOW_SUPPORT_G		0x20000000
    +#define	BWN_TGSLOW_PHYRESET		0x00080000
    +#define	BWN_TGSLOW_PHYCLOCK_ENABLE	0x00040000
    +#define	BWN_TGSHIGH_HAVE_2GHZ		0x00010000
    +#define	BWN_TGSHIGH_HAVE_5GHZ		0x00020000
    +
    +#define	BWN_PHYTYPE_A			0x00
    +#define	BWN_PHYTYPE_B			0x01
    +#define	BWN_PHYTYPE_G			0x02
    +#define	BWN_PHYTYPE_N			0x04
    +#define	BWN_PHYTYPE_LP			0x05
    +
    +#define	BWN_DMA0_REASON			0x20
    +#define	BWN_DMA0_INTR_MASK		0x24
    +#define	BWN_DMA1_REASON			0x28
    +#define	BWN_DMA1_INTR_MASK		0x2c
    +#define	BWN_DMA2_REASON			0x30
    +#define	BWN_DMA2_INTR_MASK		0x34
    +#define	BWN_DMA3_REASON			0x38
    +#define	BWN_DMA3_INTR_MASK		0x3c
    +#define	BWN_DMA4_REASON			0x40
    +#define	BWN_DMA4_INTR_MASK		0x44
    +#define	BWN_DMA5_INTR_MASK		0x4c
    +#define	BWN_MACCTL			0x120
    +#define	BWN_MACCTL_ON			0x00000001
    +#define	BWN_MACCTL_MCODE_RUN		0x00000002
    +#define	BWN_MACCTL_MCODE_JMP0		0x00000004
    +#define	BWN_MACCTL_SHM_ON		0x00000100
    +#define	BWN_MACCTL_IHR_ON		0x00000400
    +#define	BWN_MACCTL_GPOUT_MASK		0x0000c000
    +#define	BWN_MACCTL_BIGENDIAN		0x00010000
    +#define	BWN_MACCTL_STA			0x00020000
    +#define	BWN_MACCTL_HOSTAP		0x00040000
    +#define	BWN_MACCTL_RADIO_LOCK		0x00080000
    +#define	BWN_MACCTL_BEACON_PROMISC	0x00100000
    +#define	BWN_MACCTL_PASS_BADPLCP		0x00200000
    +#define	BWN_MACCTL_PASS_CTL		0x00400000
    +#define	BWN_MACCTL_PASS_BADFCS		0x00800000
    +#define	BWN_MACCTL_PROMISC		0x01000000
    +#define	BWN_MACCTL_HWPS			0x02000000
    +#define	BWN_MACCTL_AWAKE		0x04000000
    +#define	BWN_MACCTL_GMODE		0x80000000
    +#define	BWN_MACCMD			0x124	/* MAC command */
    +#define	BWN_MACCMD_BEACON0_VALID	0x00000001
    +#define	BWN_MACCMD_BEACON1_VALID	0x00000002
    +#define	BWN_MACCMD_DFQ_VALID		0x00000004
    +#define	BWN_MACCMD_BGNOISE		0x00000010
    +#define	BWN_INTR_REASON			0x128
    +#define	BWN_INTR_MASK			0x12c
    +#define	BWN_RAM_CONTROL			0x130
    +#define	BWN_RAM_DATA			0x134
    +#define	BWN_PS_STATUS			0x140
    +#define	BWN_RF_HWENABLED_HI		0x158
    +#define	BWN_RF_HWENABLED_HI_MASK	(1 << 16)
    +#define	BWN_SHM_CONTROL			0x160
    +#define	BWN_SHM_DATA			0x164
    +#define	BWN_SHM_DATA_UNALIGNED		0x166
    +#define	BWN_XMITSTAT_0			0x170
    +#define	BWN_XMITSTAT_1			0x174
    +#define	BWN_REV3PLUS_TSF_LOW		0x180	/* core rev >= 3 only */
    +#define	BWN_REV3PLUS_TSF_HIGH		0x184	/* core rev >= 3 only */
    +#define	BWN_TSF_CFP_START		0x18c
    +
    +/* 32-bit DMA */
    +#define	BWN_DMA32_BASE0			0x200
    +#define	BWN_DMA32_BASE1			0x220
    +#define	BWN_DMA32_BASE2			0x240
    +#define	BWN_DMA32_BASE3			0x260
    +#define	BWN_DMA32_BASE4			0x280
    +#define	BWN_DMA32_BASE5			0x2a0
    +/* 64-bit DMA */
    +#define	BWN_DMA64_BASE0			0x200
    +#define	BWN_DMA64_BASE1			0x240
    +#define	BWN_DMA64_BASE2			0x280
    +#define	BWN_DMA64_BASE3			0x2c0
    +#define	BWN_DMA64_BASE4			0x300
    +#define	BWN_DMA64_BASE5			0x340
    +
    +/* PIO on core rev < 11 */
    +#define	BWN_PIO_BASE0			0x300
    +#define	BWN_PIO_BASE1			0x310
    +#define	BWN_PIO_BASE2			0x320
    +#define	BWN_PIO_BASE3			0x330
    +#define	BWN_PIO_BASE4			0x340
    +#define	BWN_PIO_BASE5			0x350
    +#define	BWN_PIO_BASE6			0x360
    +#define	BWN_PIO_BASE7			0x370
    +/* PIO on core rev >= 11 */
    +#define	BWN_PIO11_BASE0			0x200
    +#define	BWN_PIO11_BASE1			0x240
    +#define	BWN_PIO11_BASE2			0x280
    +#define	BWN_PIO11_BASE3			0x2c0
    +#define	BWN_PIO11_BASE4			0x300
    +#define	BWN_PIO11_BASE5			0x340
    +
    +#define	BWN_GPIOCTL			0x06c
    +#define	BWN_PHYVER			0x3e0
    +#define	BWN_PHYVER_ANALOG		0xf000
    +#define	BWN_PHYVER_TYPE			0x0f00
    +#define	BWN_PHYVER_VERSION		0x00ff
    +#define	BWN_PHY_RADIO			0x3e2
    +#define	BWN_PHY0			0x3e6
    +#define	BWN_CHANNEL			0x3f0
    +#define	BWN_CHANNEL_EXT			0x3f4
    +#define	BWN_RFCTL			0x3f6
    +#define	BWN_RFCTL_ID			0x01
    +#define	BWN_RFDATAHI			0x3f8
    +#define	BWN_RFDATALO			0x3fa
    +#define	BWN_PHYCTL			0x3fc
    +#define	BWN_PHYDATA			0x3fe
    +#define	BWN_MACFILTER_CONTROL		0x420
    +#define	BWN_MACFILTER_DATA		0x422
    +#define	BWN_RCMTA_COUNT			0x43c
    +#define	BWN_RF_HWENABLED_LO		0x49a
    +#define	BWN_RF_HWENABLED_LO_MASK	(1 << 4)
    +#define	BWN_GPIO_CONTROL		0x49c
    +#define	BWN_GPIO_MASK			0x49e
    +#define	BWN_TSF_CFP_START_LOW		0x604
    +#define	BWN_TSF_CFP_START_HIGH		0x606
    +#define	BWN_TSF_CFP_PRETBTT		0x612
    +#define	BWN_RNG				0x65a
    +#define	BWN_IFSCTL			0x688 /* Interframe space control */
    +#define	BWN_IFSCTL_USE_EDCF		0x0004
    +#define	BWN_POWERUP_DELAY		0x6a8
    +#define	BWN_BTCOEX_CTL			0x6b4
    +#define	BWN_BTCOEX_TXCTL		0x6b8
    +
    +#define	BWN_UCODE			0x0
    +#define	BWN_HW				0x3
    +#define	BWN_RCMTA			0x4
    +
    +#define	BWN_TSSI_MAX			0x7f
    +#define	BWN_SHARED			0x1
    +#define	BWN_SHARED_UCODE_REV		0x0000
    +#define	BWN_SHARED_UCODE_PATCH		0x0002
    +#define	BWN_SHARED_UCODE_DATE		0x0004
    +#define	BWN_SHARED_UCODE_TIME		0x0006
    +#define	BWN_SHARED_COREREV		0x0016
    +#define	BWN_SHARED_ACKCTS_PHYCTL	0x0022
    +#define	BWN_SHARED_RX_PADOFFSET		0x0034
    +#define	BWN_SHARED_UCODESTAT		0x0040
    +#define	BWN_SHARED_UCODESTAT_SUSPEND	3
    +#define	BWN_SHARED_UCODESTAT_SLEEP	4
    +#define	BWN_SHARED_FWCAPS		0x0042
    +#define	BWN_SHARED_SHORT_RETRY_FALLBACK	0x0044
    +#define	BWN_SHARED_LONG_RETRY_FALLBACK	0x0046
    +#define	BWN_SHARED_BEACON_PHYCTL	0x0054
    +#define	BWN_SHARED_KEY_TABLEP		0x0056
    +#define	BWN_SHARED_TSSI_CCK		0x0058
    +#define	BWN_SHARED_HFLO			0x005e	/* low hostflag */
    +#define	BWN_SHARED_HFMI			0x0060	/* middle hostflag */
    +#define	BWN_SHARED_HFHI			0x0062	/* high hostflag */
    +#define	BWN_SHARED_RADIO_ATT		0x0064
    +#define	BWN_SHARED_TSSI_OFDM_G		0x0070
    +#define	BWN_SHARED_PROBE_RESP_MAXTIME	0x0074
    +#define	BWN_SHARED_SPU_WAKEUP		0x0094
    +#define	BWN_SHARED_PRETBTT		0x0096
    +#define	BWN_SHARED_CHAN			0x00a0
    +#define	BWN_SHARED_AUTOINC		0x0100
    +#define	BWN_SHARED_PROBE_RESP_PHYCTL	0x0188
    +#define	BWN_SHARED_EDCFQ		0x0240
    +#define	BWN_SHARED_KEYIDX_BLOCK		0x05d4
    +#define	BWN_SHARED_PSM			0x05f4
    +
    +/* SHM_SCRATCH offsets */
    +#define	BWN_SCRATCH			0x2
    +#define	BWN_SCRATCH_CONT_MIN		0x0003
    +#define	BWN_SCRATCH_CONT_MAX		0x0004
    +#define	BWN_SCRATCH_SHORT_RETRY		0x0006
    +#define	BWN_SCRATCH_LONG_RETRY		0x0007
    +
    +/* Generic-Interrupt reasons. */
    +#define	BWN_INTR_MAC_SUSPENDED		0x00000001
    +#define	BWN_INTR_BEACON			0x00000002
    +#define	BWN_INTR_TBTT_INDI		0x00000004
    +#define	BWN_INTR_ATIM_END		0x00000020
    +#define	BWN_INTR_PMQ			0x00000040
    +#define	BWN_INTR_MAC_TXERR		0x00000200
    +#define	BWN_INTR_PHY_TXERR		0x00000800
    +#define	BWN_INTR_DMA			0x00008000
    +#define	BWN_INTR_TXFIFO_FLUSH_OK	0x00010000
    +#define	BWN_INTR_NOISESAMPLE_OK		0x00040000
    +#define	BWN_INTR_UCODE_DEBUG		0x08000000
    +#define	BWN_INTR_RFKILL			0x10000000
    +#define	BWN_INTR_TX_OK			0x20000000
    +#define	BWN_INTR_ALL			0xffffffff
    +#define	BWN_INTR_MASKTEMPLATE	\
    +	(BWN_INTR_TBTT_INDI | BWN_INTR_ATIM_END | BWN_INTR_PMQ |	\
    +	 BWN_INTR_MAC_TXERR | BWN_INTR_PHY_TXERR | BWN_INTR_DMA |	\
    +	 BWN_INTR_TXFIFO_FLUSH_OK | BWN_INTR_NOISESAMPLE_OK |	\
    +	 BWN_INTR_UCODE_DEBUG | BWN_INTR_RFKILL | BWN_INTR_TX_OK)
    +
    +#define	BWN_HF_UCODE_ANTDIV_HELPER	0x000000000001ull
    +#define	BWN_HF_GPHY_SYM_WORKAROUND	0x000000000002ull
    +#define	BWN_HF_4DB_CCK_POWERBOOST	0x000000000008ull
    +#define	BWN_HF_BT_COEXIST		0x000000000010ull
    +#define	BWN_HF_GPHY_DC_CANCELFILTER	0x000000000020ull
    +#define	BWN_HF_PAGAINBOOST_OFDM_ON	0x000000000040ull
    +#define	BWN_HF_JAPAN_CHAN14_OFF		0x000000000080ull
    +#define	BWN_HF_EDCF			0x000000000100ull
    +#define	BWN_HF_TSSI_RESET_PSM_WORKAROUN	0x000000000200ull
    +#define	BWN_HF_SLOWCLOCK_REQ_OFF	0x000000000400ull
    +#define	BWN_HF_ACI_WORKAROUND		0x000000000800ull
    +#define	BWN_HF_2060_RADIO_WORKAROUND	0x000000001000ull
    +#define	BWN_HF_FORCE_VCO_RECALC		0x000000040000ull
    +#define	BWN_HF_PCI_SLOWCLOCK_WORKAROUND	0x000000080000ull
    +#define	BWN_HF_4318_TSSI		0x000000200000ull
    +#define	BWN_HF_HW_POWERCTL		0x000000800000ull
    +#define	BWN_HF_BT_COEXISTALT		0x000001000000ull
    +#define	BWN_HF_SKIP_CFP_UPDATE		0x000004000000ull
    +#define	BWN_HF_PR45960W			0x080000000000ULL
    +
    +#define	BWN_TX_PHY_ENC_CCK		0x0000
    +#define	BWN_TX_PHY_ENC_OFDM		0x0001
    +#define	BWN_TX_PHY_SHORTPRMBL		0x0010
    +#define	BWN_TX_PHY_ANT			0x03c0
    +#define	BWN_TX_PHY_ANT0			0x0000
    +#define	BWN_TX_PHY_ANT1			0x0040
    +#define	BWN_TX_PHY_ANT01AUTO		0x00c0
    +#define	BWN_TX_PHY_ANT2			0x0100
    +#define	BWN_TX_PHY_ANT3			0x0200
    +#define	BWN_TX_PHY_TXPWR		0xfc00
    +#define	BWN_TX_MAC_ACK			0x00000001	/* immediate ACK */
    +#define	BWN_TX_MAC_LONGFRAME		0x00000002
    +#define	BWN_TX_MAC_SEND_RTSCTS		0x00000004
    +#define	BWN_TX_MAC_START_MSDU		0x00000008
    +#define	BWN_TX_MAC_HWSEQ		0x00000010
    +#define	BWN_TX_MAC_5GHZ			0x00000080
    +#define	BWN_TX_MAC_SEND_CTSTOSELF	0x00000800
    +#define	BWN_TX_EFT_FB_CCK		0x00
    +#define	BWN_TX_EFT_FB_OFDM		0x01
    +#define	BWN_TX_EFT_RTS_CCK		0x00
    +#define	BWN_TX_EFT_RTS_OFDM		0x04
    +#define	BWN_TX_EFT_RTS_FBCCK		0x00
    +#define	BWN_TX_EFT_RTS_FBOFDM		0x10
    +
    +#define	BWN_PIO_TXCTL			0x00
    +#define	BWN_PIO_TXCTL_WRITELO		0x0001
    +#define	BWN_PIO_TXCTL_WRITEHI		0x0002
    +#define	BWN_PIO_TXCTL_EOF		0x0004
    +#define	BWN_PIO_TXCTL_FRAMEREADY	0x0008
    +#define	BWN_PIO_TXDATA			0x02
    +#define	BWN_PIO_TXQBUFSIZE		0x04
    +#define	BWN_PIO_RXCTL			0x00
    +#define	BWN_PIO_RXCTL_FRAMEREADY	0x0001
    +#define	BWN_PIO_RXCTL_DATAREADY		0x0002
    +#define	BWN_PIO_RXDATA			0x02
    +#define	BWN_PIO8_TXCTL			0x00
    +#define	BWN_PIO8_TXCTL_0_7		0x00000001
    +#define	BWN_PIO8_TXCTL_8_15		0x00000002
    +#define	BWN_PIO8_TXCTL_16_23		0x00000004
    +#define	BWN_PIO8_TXCTL_24_31		0x00000008
    +#define	BWN_PIO8_TXCTL_EOF		0x00000010
    +#define	BWN_PIO8_TXCTL_FRAMEREADY	0x00000080
    +#define	BWN_PIO8_TXDATA			0x04
    +#define	BWN_PIO8_RXCTL			0x00
    +#define	BWN_PIO8_RXCTL_FRAMEREADY	0x00000001
    +#define	BWN_PIO8_RXCTL_DATAREADY	0x00000002
    +#define	BWN_PIO8_RXDATA			0x04
    +
    +#define	BWN_DMA32_TXCTL			0x00
    +#define	BWN_DMA32_TXENABLE		0x00000001
    +#define	BWN_DMA32_TXSUSPEND		0x00000002
    +#define	BWN_DMA32_TXADDREXT_MASK	0x00030000
    +#define	BWN_DMA32_TXADDREXT_SHIFT	16
    +#define	BWN_DMA32_TXRING		0x04
    +#define	BWN_DMA32_TXINDEX		0x08
    +#define	BWN_DMA32_TXSTATUS		0x0c
    +#define	BWN_DMA32_TXSTATE		0x0000f000
    +#define	BWN_DMA32_TXSTAT_DISABLED	0x00000000
    +#define	BWN_DMA32_TXSTAT_IDLEWAIT	0x00002000
    +#define	BWN_DMA32_TXSTAT_STOPPED	0x00003000
    +#define	BWN_DMA32_RXCTL			0x10
    +#define	BWN_DMA32_RXENABLE		0x00000001
    +#define	BWN_DMA32_RXFROFF_SHIFT		1
    +#define	BWN_DMA32_RXDIRECTFIFO		0x00000100
    +#define	BWN_DMA32_RXADDREXT_MASK	0x00030000
    +#define	BWN_DMA32_RXADDREXT_SHIFT	16
    +#define	BWN_DMA32_RXRING		0x14
    +#define	BWN_DMA32_RXINDEX		0x18
    +#define	BWN_DMA32_RXSTATUS		0x1c
    +#define	BWN_DMA32_RXDPTR		0x00000fff
    +#define	BWN_DMA32_RXSTATE		0x0000f000
    +#define	BWN_DMA32_RXSTAT_DISABLED	0x00000000
    +#define	BWN_DMA64_TXCTL			0x00
    +#define	BWN_DMA64_TXENABLE		0x00000001
    +#define	BWN_DMA64_TXSUSPEND		0x00000002
    +#define	BWN_DMA64_TXADDREXT_MASK	0x00030000
    +#define	BWN_DMA64_TXADDREXT_SHIFT	16
    +#define	BWN_DMA64_TXINDEX		0x04
    +#define	BWN_DMA64_TXRINGLO		0x08
    +#define	BWN_DMA64_TXRINGHI		0x0c
    +#define	BWN_DMA64_TXSTATUS		0x10
    +#define	BWN_DMA64_TXSTAT		0xf0000000
    +#define	BWN_DMA64_TXSTAT_DISABLED	0x00000000
    +#define	BWN_DMA64_TXSTAT_IDLEWAIT	0x20000000
    +#define	BWN_DMA64_TXSTAT_STOPPED	0x30000000
    +#define	BWN_DMA64_RXCTL			0x20
    +#define	BWN_DMA64_RXENABLE		0x00000001
    +#define	BWN_DMA64_RXFROFF_SHIFT		1
    +#define	BWN_DMA64_RXDIRECTFIFO		0x00000100
    +#define	BWN_DMA64_RXADDREXT_MASK	0x00030000
    +#define	BWN_DMA64_RXADDREXT_SHIFT	16
    +#define	BWN_DMA64_RXINDEX		0x24
    +#define	BWN_DMA64_RXRINGLO		0x28
    +#define	BWN_DMA64_RXRINGHI		0x2c
    +#define	BWN_DMA64_RXSTATUS		0x30
    +#define	BWN_DMA64_RXSTATDPTR		0x00001fff
    +#define	BWN_DMA64_RXSTAT		0xf0000000
    +#define	BWN_DMA64_RXSTAT_DISABLED	0x00000000
    +#define	BWN_DMA_RINGMEMSIZE		PAGE_SIZE
    +#define	BWN_DMA0_RX_FRAMEOFFSET		30
    +
    +#define	BWN_TXRING_SLOTS		64
    +#define	BWN_RXRING_SLOTS		64
    +#define	BWN_DMA0_RX_BUFFERSIZE		IEEE80211_MAX_LEN
    +
    +#define	BWN_PHYROUTE_BASE		0x0000
    +#define	BWN_PHYROUTE_OFDM_GPHY		0x0400
    +#define	BWN_PHYROUTE_EXT_GPHY		0x0800
    +#define	BWN_PHY_CCK(reg)		((reg) | BWN_PHYROUTE_BASE)
    +#define	BWN_PHY_N_BMODE(reg)		((reg) | BWN_PHYROUTE_N_BMODE)
    +#define	BWN_PHY_OFDM(reg)		((reg) | BWN_PHYROUTE_OFDM_GPHY)
    +#define	BWN_PHY_EXTG(reg)		((reg) | BWN_PHYROUTE_EXT_GPHY)
    +
    +#define	BWN_PHY_VERSION_OFDM		BWN_PHY_OFDM(0x00)
    +#define	BWN_PHY_BBANDCFG		BWN_PHY_OFDM(0x01)
    +#define	BWN_PHY_BBANDCFG_RXANT		0x180
    +#define	BWN_PHY_BBANDCFG_RXANT_SHIFT	7
    +#define	BWN_PHY_PWRDOWN			BWN_PHY_OFDM(0x03)
    +#define	BWN_PHY_CRSTHRES1_R1		BWN_PHY_OFDM(0x06)
    +#define	BWN_PHY_CRSGAIN_CTL		BWN_PHY_OFDM(0x10)
    +#define	BWN_PHY_MINPWR_LEVEL		BWN_PHY_OFDM(0x16)
    +#define	BWN_PHY_OFDMSYNCTHRESH0		BWN_PHY_OFDM(0x17)
    +#define	BWN_PHY_IDLEAFTERPKTRXTO	BWN_PHY_OFDM(0x1a)
    +#define	BWN_PHY_LNAHPFCTL		BWN_PHY_OFDM(0x1c)
    +#define	BWN_PHY_DCOFFSETTRANSIENT	BWN_PHY_OFDM(0x1c) /* for LP */
    +#define	BWN_PHY_PREAMBLECONFIRMTO	BWN_PHY_OFDM(0x1e)
    +#define	BWN_PHY_CLIPTHRESH		BWN_PHY_OFDM(0x1f)
    +#define	BWN_PHY_LPFGAINCTL		BWN_PHY_OFDM(0x20)
    +#define	BWN_PHY_CLIPCTRTHRESH		BWN_PHY_OFDM(0x20) /* for LP */
    +#define	BWN_PHY_HIGAINDB		BWN_PHY_OFDM(0x23)
    +#define	BWN_PHY_LOWGAINDB		BWN_PHY_OFDM(0x24)
    +#define	BWN_PHY_VERYLOWGAINDB		BWN_PHY_OFDM(0x25)
    +#define	BWN_PHY_GAINMISMATCH		BWN_PHY_OFDM(0x26)
    +#define	BWN_PHY_ADIVRELATED		BWN_PHY_OFDM(0x27)
    +#define	BWN_PHY_GAINDIRECTMISMATCH	BWN_PHY_OFDM(0x27) /* for LP */
    +#define	BWN_PHY_CRS0			BWN_PHY_OFDM(0x29)
    +#define	BWN_PHY_CRS0_EN			0x4000
    +#define	BWN_PHY_PWR_THRESH1		BWN_PHY_OFDM(0x29) /* for LP */
    +#define	BWN_PHY_ANTDWELL		BWN_PHY_OFDM(0x2b)
    +#define	BWN_PHY_ANTDWELL_AUTODIV1	0x0100
    +#define	BWN_PHY_DSSS_CONFIRM_CNT	BWN_PHY_OFDM(0x2f) /* DSSS Confirm Cnt */
    +#define	BWN_PHY_PEAK_COUNT		BWN_PHY_OFDM(0x30)
    +#define	BWN_PHY_GAIN_MISMATCH_LIMIT	BWN_PHY_OFDM(0x31)
    +#define	BWN_PHY_CRS_ED_THRESH		BWN_PHY_OFDM(0x32)
    +#define	BWN_PHY_INPUT_PWRDB		BWN_PHY_OFDM(0x34)
    +#define	BWN_PHY_AFE_ADC_CTL_0		BWN_PHY_OFDM(0x36)
    +#define	BWN_PHY_AFE_ADC_CTL_1		BWN_PHY_OFDM(0x37)
    +#define	BWN_PHY_AFE_DAC_CTL		BWN_PHY_OFDM(0x39)
    +#define	BWN_PHY_AFE_CTL			BWN_PHY_OFDM(0x3a)
    +#define	BWN_PHY_AFE_CTL_OVR		BWN_PHY_OFDM(0x3b)
    +#define	BWN_PHY_AFE_CTL_OVRVAL		BWN_PHY_OFDM(0x3c)
    +#define	BWN_PHY_AFE_RSSI_CTL_0		BWN_PHY_OFDM(0x3d)
    +#define	BWN_PHY_AFE_RSSI_CTL_1		BWN_PHY_OFDM(0x3e)
    +#define	BWN_PHY_LP_PHY_CTL		BWN_PHY_OFDM(0x48)
    +#define	BWN_PHY_ENCORE			BWN_PHY_OFDM(0x49)
    +#define	BWN_PHY_ENCORE_EN		0x0200
    +#define	BWN_PHY_RESET_CTL		BWN_PHY_OFDM(0x4a)
    +#define	BWN_PHY_RF_OVERRIDE_0		BWN_PHY_OFDM(0x4c)
    +#define	BWN_PHY_RF_OVERRIDE_VAL_0	BWN_PHY_OFDM(0x4d)
    +#define	BWN_PHY_TR_LOOKUP_1		BWN_PHY_OFDM(0x4e)
    +#define	BWN_PHY_TR_LOOKUP_2		BWN_PHY_OFDM(0x4F)
    +#define	BWN_PHY_LMS			BWN_PHY_OFDM(0x55)
    +#define	BWN_PHY_TABLE_ADDR		BWN_PHY_OFDM(0x55) /* for LP */
    +#define	BWN_PHY_TABLEDATALO		BWN_PHY_OFDM(0x56)
    +#define	BWN_PHY_TABLEDATAHI		BWN_PHY_OFDM(0x57)
    +#define	BWN_PHY_OFDM61			BWN_PHY_OFDM(0x61)
    +#define	BWN_PHY_OFDM61_10		0x0010
    +#define	BWN_PHY_ADC_COMPENSATION_CTL	BWN_PHY_OFDM(0x70)
    +#define	BWN_PHY_OTABLECTL		BWN_PHY_OFDM(0x72)
    +#define	BWN_PHY_OTABLENR_SHIFT		10
    +#define	BWN_PHY_OTABLEI			BWN_PHY_OFDM(0x73)
    +#define	BWN_PHY_OTABLEQ			BWN_PHY_OFDM(0x74)
    +#define	BWN_PHY_HPWR_TSSICTL		BWN_PHY_OFDM(0x78)
    +#define	BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR	BWN_PHY_OFDM(0x81)
    +#define	BWN_PHY_IQ_NUM_SMPLS_ADDR	BWN_PHY_OFDM(0x82)
    +#define	BWN_PHY_IQ_ACC_HI_ADDR		BWN_PHY_OFDM(0x83)
    +#define	BWN_PHY_IQ_ACC_LO_ADDR		BWN_PHY_OFDM(0x84)
    +#define	BWN_PHY_IQ_I_PWR_ACC_HI_ADDR	BWN_PHY_OFDM(0x85)
    +#define	BWN_PHY_IQ_I_PWR_ACC_LO_ADDR	BWN_PHY_OFDM(0x86)
    +#define	BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR	BWN_PHY_OFDM(0x87)
    +#define	BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR	BWN_PHY_OFDM(0x88)
    +#define	BWN_PHY_ANTWRSETT		BWN_PHY_OFDM(0x8c)
    +#define	BWN_PHY_ANTWRSETT_ARXDIV	0x2000
    +#define	BWN_PHY_OFDM9B			BWN_PHY_OFDM(0x9b)
    +#define	BWN_PHY_A_PHY_CTL_ADDR		BWN_PHY_OFDM(0x9c)
    +#define	BWN_PHY_RX_COMP_COEFF_S		BWN_PHY_OFDM(0x9e)
    +#define	BWN_PHY_N1P1GAIN		BWN_PHY_OFDM(0xa0)
    +#define	BWN_PHY_SMPL_PLAY_COUNT		BWN_PHY_OFDM(0xa0) /* for LP */
    +#define	BWN_PHY_P1P2GAIN		BWN_PHY_OFDM(0xa1)
    +#define	BWN_PHY_SMPL_PLAY_BUFFER_CTL	BWN_PHY_OFDM(0xA1) /* for LP */
    +#define	BWN_PHY_N1N2GAIN		BWN_PHY_OFDM(0xa2)
    +#define	BWN_PHY_4WIRECTL		BWN_PHY_OFDM(0xa2)  /* for LP */
    +#define	BWN_PHY_TX_PWR_CTL_CMD		BWN_PHY_OFDM(0xa4)
    +#define	BWN_PHY_TX_PWR_CTL_CMD_MODE	0xe000
    +#define	BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF	0x0000
    +#define	BWN_PHY_TX_PWR_CTL_CMD_MODE_SW	0x8000
    +#define	BWN_PHY_TX_PWR_CTL_CMD_MODE_HW	0xe000
    +#define	BWN_PHY_CCKSHIFTBITS_WA		BWN_PHY_OFDM(0xa5)
    +#define	BWN_PHY_TX_PWR_CTL_NNUM		BWN_PHY_OFDM(0xa5)	/* for LP */
    +#define	BWN_PHY_CCKSHIFTBITS		BWN_PHY_OFDM(0xa7)
    +#define	BWN_PHY_DIVSRCHIDX		BWN_PHY_OFDM(0xa8)
    +#define	BWN_PHY_DIVP1P2GAIN		BWN_PHY_OFDM(0xab)
    +#define	BWN_PHY_LP_RF_SIGNAL_LUT	BWN_PHY_OFDM(0xac)
    +#define	BWN_PHY_DIVSRCHGAINBACK		BWN_PHY_OFDM(0xad)
    +#define	BWN_PHY_RX_RADIO_CTL		BWN_PHY_OFDM(0xae)
    +#define	BWN_PHY_RF_OVERRIDE_2		BWN_PHY_OFDM(0xb0)
    +#define	BWN_PHY_RF_OVERRIDE_2_VAL	BWN_PHY_OFDM(0xb1)
    +#define	BWN_PHY_PS_CTL_OVERRIDE_VAL0	BWN_PHY_OFDM(0xB2)
    +#define	BWN_PHY_PS_CTL_OVERRIDE_VAL1	BWN_PHY_OFDM(0xB3)
    +#define	BWN_PHY_PS_CTL_OVERRIDE_VAL2	BWN_PHY_OFDM(0xB4)
    +#define	BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL	BWN_PHY_OFDM(0xB5)
    +#define	BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL	BWN_PHY_OFDM(0xB6)
    +#define	BWN_PHY_AFE_DDFS		BWN_PHY_OFDM(0xb7)
    +#define	BWN_PHY_AFE_DDFS_POINTER_INIT	BWN_PHY_OFDM(0xB8)
    +#define	BWN_PHY_AFE_DDFS_INCR_INIT	BWN_PHY_OFDM(0xB9)
    +#define	BWN_PHY_TR_LOOKUP_3		BWN_PHY_OFDM(0xbb)
    +#define	BWN_PHY_TR_LOOKUP_4		BWN_PHY_OFDM(0xbc)
    +#define	BWN_PHY_GPIO_OUTEN		BWN_PHY_OFDM(0xbe)
    +#define	BWN_PHY_GPIO_SELECT		BWN_PHY_OFDM(0xbf)
    +#define	BWN_PHY_CRSTHRES1		BWN_PHY_OFDM(0xc0)
    +#define	BWN_PHY_CRSTHRES2		BWN_PHY_OFDM(0xc1)
    +#define	BWN_PHY_4C3			BWN_PHY_OFDM(0xC3)
    +#define	BWN_PHY_4C4			BWN_PHY_OFDM(0xC4)
    +#define	BWN_PHY_4C5			BWN_PHY_OFDM(0xC5)
    +#define	BWN_PHY_TR_LOOKUP_5		BWN_PHY_OFDM(0xC7)
    +#define	BWN_PHY_TR_LOOKUP_6		BWN_PHY_OFDM(0xC8)
    +#define	BWN_PHY_TR_LOOKUP_7		BWN_PHY_OFDM(0xC9)
    +#define	BWN_PHY_TR_LOOKUP_8		BWN_PHY_OFDM(0xCA)
    +#define	BWN_PHY_RF_PWR_OVERRIDE		BWN_PHY_OFDM(0xd3)
    +
    +#define	BWN_OFDMTAB(number, offset)	\
    +	(((number) << BWN_PHY_OTABLENR_SHIFT) | (offset))
    +#define	BWN_OFDMTAB_AGC1		BWN_OFDMTAB(0x00, 0)
    +#define	BWN_OFDMTAB_GAIN0		BWN_OFDMTAB(0x00, 0)
    +#define	BWN_OFDMTAB_GAINX		BWN_OFDMTAB(0x01, 0)
    +#define	BWN_OFDMTAB_GAIN1		BWN_OFDMTAB(0x01, 4)
    +#define	BWN_OFDMTAB_AGC3		BWN_OFDMTAB(0x02, 0)
    +#define	BWN_OFDMTAB_GAIN2		BWN_OFDMTAB(0x02, 3)
    +#define	BWN_OFDMTAB_LNAHPFGAIN1		BWN_OFDMTAB(0x03, 0)
    +#define	BWN_OFDMTAB_WRSSI		BWN_OFDMTAB(0x04, 0)
    +#define	BWN_OFDMTAB_NOISESCALE		BWN_OFDMTAB(0x05, 0)
    +#define	BWN_OFDMTAB_AGC2		BWN_OFDMTAB(0x06, 0)
    +#define	BWN_OFDMTAB_ROTOR		BWN_OFDMTAB(0x08, 0)
    +#define	BWN_OFDMTAB_ADVRETARD		BWN_OFDMTAB(0x09, 0)
    +#define	BWN_OFDMTAB_DAC			BWN_OFDMTAB(0x0c, 0)
    +#define	BWN_OFDMTAB_DC			BWN_OFDMTAB(0x0e, 7)
    +#define	BWN_OFDMTAB_PWRDYN2		BWN_OFDMTAB(0x0e, 12)
    +#define	BWN_OFDMTAB_UNKNOWN_0F		BWN_OFDMTAB(0x0f, 0)
    +#define	BWN_OFDMTAB_UNKNOWN_APHY	BWN_OFDMTAB(0x0f, 7)
    +#define	BWN_OFDMTAB_LPFGAIN		BWN_OFDMTAB(0x0f, 12)
    +#define	BWN_OFDMTAB_RSSI		BWN_OFDMTAB(0x10, 0)
    +#define	BWN_OFDMTAB_UNKNOWN_11		BWN_OFDMTAB(0x11, 4)
    +#define	BWN_OFDMTAB_AGC1_R1		BWN_OFDMTAB(0x13, 0)
    +#define	BWN_OFDMTAB_GAINX_R1		BWN_OFDMTAB(0x14, 0)
    +#define	BWN_OFDMTAB_MINSIGSQ		BWN_OFDMTAB(0x14, 0)
    +#define	BWN_OFDMTAB_AGC3_R1		BWN_OFDMTAB(0x15, 0)
    +#define	BWN_OFDMTAB_WRSSI_R1		BWN_OFDMTAB(0x15, 4)
    +#define	BWN_OFDMTAB_DACRFPABB		BWN_OFDMTAB(0x16, 0)
    +
    +#define	BWN_PHY_CCKBBANDCFG		BWN_PHY_CCK(0x01)
    +#define	BWN_PHY_PGACTL			BWN_PHY_CCK(0x15)
    +#define	BWN_PHY_PGACTL_LPF		0x1000
    +#define	BWN_PHY_PGACTL_LOWBANDW		0x0040
    +#define	BWN_PHY_PGACTL_UNKNOWN		0xefa0
    +#define	BWN_PHY_TSSI			BWN_PHY_CCK(0x29)
    +#define	BWN_PHY_LO_LEAKAGE		BWN_PHY_CCK(0x2d)
    +#define	BWN_PHY_SYNCPEAKCNT		BWN_PHY_CCK(0x30)
    +#define	BWN_PHY_SYNCCTL			BWN_PHY_CCK(0x35)
    +#define	BWN_PHY_DACCTL			BWN_PHY_CCK(0x60)
    +
    +#define	BWN_PHY_CLASSCTL		BWN_PHY_EXTG(0x02)
    +#define	BWN_PHY_GTABCTL			BWN_PHY_EXTG(0x03)
    +#define	BWN_PHY_GTABNR_SHIFT		10
    +#define	BWN_PHY_GTABDATA		BWN_PHY_EXTG(0x04)
    +#define	BWN_PHY_LO_MASK			BWN_PHY_EXTG(0x0f)
    +#define	BWN_PHY_LO_CTL			BWN_PHY_EXTG(0x10)
    +#define	BWN_PHY_RFOVER			BWN_PHY_EXTG(0x11)
    +#define	BWN_PHY_RFOVERVAL		BWN_PHY_EXTG(0x12)
    +#define	BWN_PHY_RFOVERVAL_EXTLNA	0x8000
    +#define	BWN_PHY_RFOVERVAL_LNA		0x7000
    +#define	BWN_PHY_RFOVERVAL_LNA_SHIFT	12
    +#define	BWN_PHY_RFOVERVAL_PGA		0x0f00
    +#define	BWN_PHY_RFOVERVAL_PGA_SHIFT	8
    +#define	BWN_PHY_RFOVERVAL_UNK		0x0010
    +#define	BWN_PHY_RFOVERVAL_TRSWRX	0x00e0
    +#define	BWN_PHY_RFOVERVAL_BW		0x0003
    +#define	BWN_PHY_RFOVERVAL_BW_LPF	0x0001
    +#define	BWN_PHY_RFOVERVAL_BW_LBW	0x0002
    +#define	BWN_PHY_ANALOGOVER		BWN_PHY_EXTG(0x14)
    +#define	BWN_PHY_ANALOGOVERVAL		BWN_PHY_EXTG(0x15)
    +
    +#define	BWN_GTAB(number, offset)	\
    +	(((number) << BWN_PHY_GTABNR_SHIFT) | (offset))
    +#define	BWN_GTAB_ORIGTR			BWN_GTAB(0x2e, 0x298)
    +
    +#define	BWN_PHY_G_LOCTL			0x0810
    +#define	BWN_PHY_RADIO_BITFIELD		0x0401
    +#define	BWN_PHY_G_CRS			0x0429
    +#define	BWN_PHY_NRSSI_CTRL		0x0803
    +#define	BWN_PHY_NRSSI_DATA		0x0804
    +#define	BWN_FWCAPS_HWCRYPTO		0x0001
    +#define	BWN_FWCAPS_WME			0x0002
    +#define	BWN_MACFILTER_SELF		0x0000
    +#define	BWN_MACFILTER_BSSID		0x0003
    +#define	BWN_SEC_KEYSIZE			16
    +#define	BWN_SEC_ALGO_NONE		0
    +#define	BWN_LED_BEHAVIOUR		0x7f
    +#define	BWN_LED_ACTIVELOW		0x80
    +
    +#define	BWN_DEBUGINTR_REASON_REG	63
    +#define	BWN_DEBUGINTR_PANIC		0
    +#define	BWN_DEBUGINTR_DUMP_SHM		1
    +#define	BWN_DEBUGINTR_DUMP_REGS		2
    +#define	BWN_DEBUGINTR_MARKER		3
    +#define	BWN_DEBUGINTR_ACK		0xffff
    +
    +#define	BWN_FWPANIC_REASON_REG		3
    +#define	BWN_FWPANIC_DIE			0
    +#define	BWN_FWPANIC_RESTART		1
    +#define	BWN_WATCHDOG_REG		1
    +
    +#define	BWN_CCK_RATE_1MB		0x02
    +#define	BWN_CCK_RATE_2MB		0x04
    +#define	BWN_CCK_RATE_5MB		0x0b
    +#define	BWN_CCK_RATE_11MB		0x16
    +#define	BWN_OFDM_RATE_6MB		0x0c
    +#define	BWN_OFDM_RATE_9MB		0x12
    +#define	BWN_OFDM_RATE_12MB		0x18
    +#define	BWN_OFDM_RATE_18MB		0x24
    +#define	BWN_OFDM_RATE_24MB		0x30
    +#define	BWN_OFDM_RATE_36MB		0x48
    +#define	BWN_OFDM_RATE_48MB		0x60
    +#define	BWN_OFDM_RATE_54MB		0x6c
    +
    +#define	BWN_RX_CHAN_PHYTYPE		0x0007
    +#define	BWN_RX_PHYST0_GAINCTL		0x4000
    +#define	BWN_RX_PHYST0_PLCPHCF		0x0200
    +#define	BWN_RX_PHYST0_PLCPFV		0x0100
    +#define	BWN_RX_PHYST0_SHORTPRMBL	0x0080
    +#define	BWN_RX_PHYST0_OFDM		0x0001
    +#define	BWN_RX_PHYST3_TRSTATE		0x0400
    +#define	BWN_RX_MAC_KEYIDX		0x000007e0
    +#define	BWN_RX_MAC_KEYIDX_SHIFT		5
    +#define	BWN_RX_MAC_DECERR		0x00000010
    +#define	BWN_RX_MAC_DEC			0x00000008
    +#define	BWN_RX_MAC_PADDING		0x00000004
    +#define	BWN_RX_MAC_FCSERR		0x00000001
    +
    +#define	BWN_PS_ON			(1 << 0)
    +#define	BWN_PS_OFF			(1 << 1)
    +#define	BWN_PS_AWAKE			(1 << 2)
    +#define	BWN_PS_ASLEEP			(1 << 3)
    +
    +#define	BWN_TAB_NOISESCALE_SIZE		27
    +
    +/*
    + * SPROM GPIO
    + */
    +#define	BWN_LED_ACT_LOW			0x80
    +#define	BWN_LED_ACT_MASK		0x7f
    +#define	BWN_LED_ACT_OFF			0
    +#define	BWN_LED_ACT_ON			1
    +#define	BWN_LED_ACT_BLINK		2
    +#define	BWN_LED_ACT_RF_ENABLED		3
    +#define	BWN_LED_ACT_5GHZ		4
    +#define	BWN_LED_ACT_2GHZ		5
    +#define	BWN_LED_ACT_11G			6
    +#define	BWN_LED_ACT_BLINK_SLOW		7
    +#define	BWN_LED_ACT_BLINK_POLL		8
    +#define	BWN_LED_ACT_UNKN		9
    +#define	BWN_LED_ACT_ASSOC		10
    +#define	BWN_LED_ACT_NULL		11
    +
    +#define	BWN_VENDOR_LED_ACT_COMPAQ	\
    +	BWN_LED_ACT_RF_ENABLED,		\
    +	BWN_LED_ACT_2GHZ,		\
    +	BWN_LED_ACT_5GHZ,		\
    +	BWN_LED_ACT_OFF
    +
    +#define	BWN_VENDOR_LED_ACT_ASUSTEK	\
    +	BWN_LED_ACT_ASSOC,		\
    +	BWN_LED_ACT_2GHZ,	\
    +	BWN_LED_ACT_5GHZ,		\
    +	BWN_LED_ACT_OFF
    +
    +#define	BWN_VENDOR_LED_ACT_DEFAULT	\
    +	BWN_LED_ACT_BLINK,		\
    +	BWN_LED_ACT_2GHZ,	\
    +	BWN_LED_ACT_5GHZ,	\
    +	BWN_LED_ACT_OFF
    +
    +#define	BWN_TAB_ROTOR							\
    +{									\
    +	0xfeb93ffd, 0xfec63ffd, 0xfed23ffd, 0xfedf3ffd, 0xfeec3ffe,	\
    +	0xfef83ffe, 0xff053ffe, 0xff113ffe, 0xff1e3ffe, 0xff2a3fff,	\
    +	0xff373fff, 0xff443fff, 0xff503fff, 0xff5d3fff, 0xff693fff,	\
    +	0xff763fff, 0xff824000, 0xff8f4000, 0xff9b4000, 0xffa84000,	\
    +	0xffb54000, 0xffc14000, 0xffce4000, 0xffda4000, 0xffe74000,	\
    +	0xfff34000, 0x00004000, 0x000d4000, 0x00194000, 0x00264000,	\
    +	0x00324000, 0x003f4000, 0x004b4000, 0x00584000, 0x00654000,	\
    +	0x00714000, 0x007e4000, 0x008a3fff, 0x00973fff, 0x00a33fff,	\
    +	0x00b03fff, 0x00bc3fff, 0x00c93fff, 0x00d63fff, 0x00e23ffe,	\
    +	0x00ef3ffe, 0x00fb3ffe, 0x01083ffe, 0x01143ffe, 0x01213ffd,	\
    +	0x012e3ffd, 0x013a3ffd, 0x01473ffd				\
    +}
    +
    +#define	BWN_TAB_RETARD							\
    +{									\
    +	0xdb93cb87, 0xd666cf64, 0xd1fdd358, 0xcda6d826, 0xca38dd9f,	\
    +	0xc729e2b4, 0xc469e88e, 0xc26aee2b, 0xc0def46c, 0xc073fa62,	\
    +	0xc01d00d5, 0xc0760743, 0xc1560d1e, 0xc2e51369, 0xc4ed18ff,	\
    +	0xc7ac1ed7, 0xcb2823b2, 0xcefa28d9, 0xd2f62d3f, 0xd7bb3197,	\
    +	0xdce53568, 0xe1fe3875, 0xe7d13b35, 0xed663d35, 0xf39b3ec4,	\
    +	0xf98e3fa7, 0x00004000, 0x06723fa7, 0x0c653ec4, 0x129a3d35,	\
    +	0x182f3b35, 0x1e023875, 0x231b3568, 0x28453197, 0x2d0a2d3f,	\
    +	0x310628d9, 0x34d823b2, 0x38541ed7, 0x3b1318ff, 0x3d1b1369,	\
    +	0x3eaa0d1e, 0x3f8a0743, 0x3fe300d5, 0x3f8dfa62, 0x3f22f46c,	\
    +	0x3d96ee2b, 0x3b97e88e, 0x38d7e2b4, 0x35c8dd9f, 0x325ad826,	\
    +	0x2e03d358, 0x299acf64, 0x246dcb87,				\
    +}
    +
    +#define	BWN_TAB_FINEFREQ_G						\
    +{									\
    +	0x0089, 0x02e9, 0x0409, 0x04e9, 0x05a9, 0x0669, 0x0709, 0x0789,	\
    +	0x0829, 0x08a9, 0x0929, 0x0989, 0x0a09, 0x0a69, 0x0ac9, 0x0b29,	\
    +	0x0ba9, 0x0be9, 0x0c49, 0x0ca9, 0x0d09, 0x0d69, 0x0da9, 0x0e09,	\
    +	0x0e69, 0x0ea9, 0x0f09, 0x0f49, 0x0fa9, 0x0fe9, 0x1029, 0x1089,	\
    +	0x10c9, 0x1109, 0x1169, 0x11a9, 0x11e9, 0x1229, 0x1289, 0x12c9,	\
    +	0x1309, 0x1349, 0x1389, 0x13c9, 0x1409, 0x1449, 0x14a9, 0x14e9,	\
    +	0x1529, 0x1569, 0x15a9, 0x15e9, 0x1629, 0x1669, 0x16a9, 0x16e8,	\
    +	0x1728, 0x1768, 0x17a8, 0x17e8, 0x1828, 0x1868, 0x18a8, 0x18e8,	\
    +	0x1928, 0x1968, 0x19a8, 0x19e8, 0x1a28, 0x1a68, 0x1aa8, 0x1ae8,	\
    +	0x1b28, 0x1b68, 0x1ba8, 0x1be8, 0x1c28, 0x1c68, 0x1ca8, 0x1ce8,	\
    +	0x1d28, 0x1d68, 0x1dc8, 0x1e08, 0x1e48, 0x1e88, 0x1ec8, 0x1f08,	\
    +	0x1f48, 0x1f88, 0x1fe8, 0x2028, 0x2068, 0x20a8, 0x2108, 0x2148,	\
    +	0x2188, 0x21c8, 0x2228, 0x2268, 0x22c8, 0x2308, 0x2348, 0x23a8,	\
    +	0x23e8, 0x2448, 0x24a8, 0x24e8, 0x2548, 0x25a8, 0x2608, 0x2668,	\
    +	0x26c8, 0x2728, 0x2787, 0x27e7, 0x2847, 0x28c7, 0x2947, 0x29a7,	\
    +	0x2a27, 0x2ac7, 0x2b47, 0x2be7, 0x2ca7, 0x2d67, 0x2e47, 0x2f67,	\
    +	0x3247, 0x3526, 0x3646, 0x3726, 0x3806, 0x38a6, 0x3946, 0x39e6,	\
    +	0x3a66, 0x3ae6, 0x3b66, 0x3bc6, 0x3c45, 0x3ca5, 0x3d05, 0x3d85,	\
    +	0x3de5, 0x3e45, 0x3ea5, 0x3ee5, 0x3f45, 0x3fa5, 0x4005, 0x4045,	\
    +	0x40a5, 0x40e5, 0x4145, 0x4185, 0x41e5, 0x4225, 0x4265, 0x42c5,	\
    +	0x4305, 0x4345, 0x43a5, 0x43e5, 0x4424, 0x4464, 0x44c4, 0x4504,	\
    +	0x4544, 0x4584, 0x45c4, 0x4604, 0x4644, 0x46a4, 0x46e4, 0x4724,	\
    +	0x4764, 0x47a4, 0x47e4, 0x4824, 0x4864, 0x48a4, 0x48e4, 0x4924,	\
    +	0x4964, 0x49a4, 0x49e4, 0x4a24, 0x4a64, 0x4aa4, 0x4ae4, 0x4b23,	\
    +	0x4b63, 0x4ba3, 0x4be3, 0x4c23, 0x4c63, 0x4ca3, 0x4ce3, 0x4d23,	\
    +	0x4d63, 0x4da3, 0x4de3, 0x4e23, 0x4e63, 0x4ea3, 0x4ee3, 0x4f23,	\
    +	0x4f63, 0x4fc3, 0x5003, 0x5043, 0x5083, 0x50c3, 0x5103, 0x5143,	\
    +	0x5183, 0x51e2, 0x5222, 0x5262, 0x52a2, 0x52e2, 0x5342, 0x5382,	\
    +	0x53c2, 0x5402, 0x5462, 0x54a2, 0x5502, 0x5542, 0x55a2, 0x55e2,	\
    +	0x5642, 0x5682, 0x56e2, 0x5722, 0x5782, 0x57e1, 0x5841, 0x58a1,	\
    +	0x5901, 0x5961, 0x59c1, 0x5a21, 0x5aa1, 0x5b01, 0x5b81, 0x5be1,	\
    +	0x5c61, 0x5d01, 0x5d80, 0x5e20, 0x5ee0, 0x5fa0, 0x6080, 0x61c0,	\
    +}
    +
    +#define	BWN_TAB_NOISE_G1						\
    +{									\
    +	0x013c, 0x01f5, 0x031a, 0x0631, 0x0001, 0x0001, 0x0001, 0x0001,	\
    +}
    +
    +#define	BWN_TAB_NOISE_G2						\
    +{									\
    +	0x5484, 0x3c40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,	\
    +}
    +
    +#define	BWN_TAB_NOISESCALE_G1						\
    +{									\
    +	0x6c77, 0x5162, 0x3b40, 0x3335, 0x2f2d, 0x2a2a, 0x2527, 0x1f21,	\
    +	0x1a1d, 0x1719, 0x1616, 0x1414, 0x1414, 0x1400, 0x1414, 0x1614,	\
    +	0x1716, 0x1a19, 0x1f1d, 0x2521, 0x2a27, 0x2f2a, 0x332d, 0x3b35,	\
    +	0x5140, 0x6c62, 0x0077,						\
    +}
    +
    +#define	BWN_TAB_NOISESCALE_G2						\
    +{									\
    +	0xd8dd, 0xcbd4, 0xbcc0, 0xb6b7, 0xb2b0, 0xadad, 0xa7a9, 0x9fa1,	\
    +	0x969b, 0x9195, 0x8f8f, 0x8a8a, 0x8a8a, 0x8a00, 0x8a8a, 0x8f8a,	\
    +	0x918f, 0x9695, 0x9f9b, 0xa7a1, 0xada9, 0xb2ad, 0xb6b0, 0xbcb7,	\
    +	0xcbc0, 0xd8d4, 0x00dd,						\
    +}
    +
    +#define	BWN_TAB_NOISESCALE_G3						\
    +{									\
    +	0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,	\
    +	0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,	\
    +	0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,	\
    +	0xa4a4, 0xa4a4, 0x00a4,						\
    +}
    +
    +#define	BWN_TAB_SIGMASQR2						\
    +{									\
    +	0x00de, 0x00dc, 0x00da, 0x00d8, 0x00d6, 0x00d4, 0x00d2, 0x00cf,	\
    +	0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, 0x00be, 0x00be, 0x00be,	\
    +	0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be,	\
    +	0x00be, 0x00be, 0x0000, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be,	\
    +	0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be,	\
    +	0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00cf, 0x00d2, 0x00d4,	\
    +	0x00d6, 0x00d8, 0x00da, 0x00dc, 0x00de,				\
    +}
    +
    +#define	BWN_PHY_G_TSSI2DBM_TABLE					\
    +{									\
    +	77, 77, 77, 76, 76, 76, 75, 75, 74, 74, 73, 73, 73, 72, 72, 71,	\
    +	71, 70, 70, 69, 68, 68, 67, 67, 66, 65, 65, 64, 63, 63, 62, 61,	\
    +	60, 59, 58, 57, 56, 55, 54, 53, 52, 50, 49, 47, 45, 43, 40, 37,	\
    +	33, 28, 22, 14, 5, -7, -20, -20, -20, -20, -20, -20, -20, -20,	\
    +	-20, -20							\
    +}
    +
    +#define	BWN_PHY_G_RF_CHANNELS						\
    +{									\
    +	12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 84,		\
    +}
    +
    +#define	BWN_BITREV_TABLE						\
    +{									\
    +	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90,	\
    +	0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8,	\
    +	0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8,	\
    +	0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,	\
    +	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c,	\
    +	0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,	\
    +	0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2,	\
    +	0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,	\
    +	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a,	\
    +	0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6,	\
    +	0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6,	\
    +	0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,	\
    +	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81,	\
    +	0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1,	\
    +	0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9,	\
    +	0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,	\
    +	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95,	\
    +	0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,	\
    +	0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd,	\
    +	0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,	\
    +	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b,	\
    +	0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb,	\
    +	0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7,	\
    +	0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,	\
    +	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f,	\
    +	0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff				\
    +}
    +
    +/*
    + * LP PHY
    + */
    +
    +#define	BWN_TAB_TYPEMASK		0xf0000000
    +#define	BWN_TAB_GETTYPE(v)		((v) & BWN_TAB_TYPEMASK)
    +#define	BWN_TAB_GETOFFSET(v)		((v) & ~BWN_TAB_TYPEMASK)
    +#define	BWN_TAB_8BIT			0x10000000
    +#define	BWN_TAB_16BIT			0x20000000
    +#define	BWN_TAB_32BIT			0x30000000
    +#define	BWN_TAB_1(table, offset)			\
    +	(((table) << 10) | (offset) | BWN_TAB_8BIT)
    +#define	BWN_TAB_2(table, offset)			\
    +	(((table) << 10) | (offset) | BWN_TAB_16BIT)
    +#define	BWN_TAB_4(table, offset)			\
    +	(((table) << 10) | (offset) | BWN_TAB_32BIT)
    +
    +#define	BWN_LP_RADIO(radio_reg)		(radio_reg)
    +#define	BWN_LP_NORTH(radio_reg)		BWN_LP_RADIO(radio_reg)
    +#define	BWN_LP_SOUTH(radio_reg)		BWN_LP_RADIO((radio_reg) | 0x4000)
    +
    +#define	BWN_B2062_N_COM1		BWN_LP_NORTH(0x000)
    +#define	BWN_B2062_N_COM2		BWN_LP_NORTH(0x002)
    +#define	BWN_B2062_N_COM4		BWN_LP_NORTH(0x004)
    +#define	BWN_B2062_N_PDNCTL0		BWN_LP_NORTH(0x010)
    +#define	BWN_B2062_N_PDNCTL1		BWN_LP_NORTH(0x011)
    +#define	BWN_B2062_N_PDNCTL3		BWN_LP_NORTH(0x013)
    +#define	BWN_B2062_N_PDNCTL4		BWN_LP_NORTH(0x014)
    +#define	BWN_B2062_N_LGENC		BWN_LP_NORTH(0x017)
    +#define	BWN_B2062_N_LGENATUNE0		BWN_LP_NORTH(0x01E)
    +#define	BWN_B2062_N_LGENATUNE2		BWN_LP_NORTH(0x020)
    +#define	BWN_B2062_N_LGENATUNE3		BWN_LP_NORTH(0x021)
    +#define	BWN_B2062_N_LGENACTL3		BWN_LP_NORTH(0x022)
    +#define	BWN_B2062_N_LGENACTL5		BWN_LP_NORTH(0x024)
    +#define	BWN_B2062_N_LGENACTL6		BWN_LP_NORTH(0x025)
    +#define	BWN_B2062_N_LGENACTL7		BWN_LP_NORTH(0x026)
    +#define	BWN_B2062_N_RXA_CTL1		BWN_LP_NORTH(0x028)
    +#define	BWN_B2062_N_RXBB_CTL0		BWN_LP_NORTH(0x02F)
    +#define	BWN_B2062_N_RXBB_GAIN1		BWN_LP_NORTH(0x033)
    +#define	BWN_B2062_N_RXBB_GAIN2		BWN_LP_NORTH(0x034)
    +#define	BWN_B2062_N_RXBB_CALIB2		BWN_LP_NORTH(0x03A)
    +#define	BWN_B2062_N_TXCTL3		BWN_LP_NORTH(0x048)
    +#define	BWN_B2062_N_TXCTL4		BWN_LP_NORTH(0x049)
    +#define	BWN_B2062_N_TXCTL5		BWN_LP_NORTH(0x04A)
    +#define	BWN_B2062_N_TXCTL6		BWN_LP_NORTH(0x04B)
    +#define	BWN_B2062_N_TXCTL_A		BWN_LP_NORTH(0x04F)
    +#define	BWN_B2062_N_TX_TUNE		BWN_LP_NORTH(0x052)
    +#define	BWN_B2062_N_TX_PAD		BWN_LP_NORTH(0x053)
    +#define	BWN_B2062_N_TX_PGA		BWN_LP_NORTH(0x054)
    +#define	BWN_B2062_N_TSSI_CTL0		BWN_LP_NORTH(0x057)
    +#define	BWN_B2062_N_CALIB_TS		BWN_LP_NORTH(0x05D)
    +#define	BWN_B2062_S_COM4		BWN_LP_SOUTH(0x004)
    +#define	BWN_B2062_S_PDS_CTL0		BWN_LP_SOUTH(0x010)
    +#define	BWN_B2062_S_BG_CTL1		BWN_LP_SOUTH(0x015)
    +#define	BWN_B2062_S_LGENG_CTL0		BWN_LP_SOUTH(0x017)
    +#define	BWN_B2062_S_LGENG_CTL1		BWN_LP_SOUTH(0x018)
    +#define	BWN_B2062_S_LGENG_CTL8		BWN_LP_SOUTH(0x01F)
    +#define	BWN_B2062_S_LGENG_CTL10		BWN_LP_SOUTH(0x021)
    +#define	BWN_B2062_S_RFPLLCTL0		BWN_LP_SOUTH(0x034)
    +#define	BWN_B2062_S_RFPLLCTL1		BWN_LP_SOUTH(0x035)
    +#define	BWN_B2062_S_RFPLLCTL2		BWN_LP_SOUTH(0x036)
    +#define	BWN_B2062_S_RFPLLCTL3		BWN_LP_SOUTH(0x037)
    +#define	BWN_B2062_S_RFPLLCTL5		BWN_LP_SOUTH(0x039)
    +#define	BWN_B2062_S_RFPLLCTL6		BWN_LP_SOUTH(0x03A)
    +#define	BWN_B2062_S_RFPLLCTL7		BWN_LP_SOUTH(0x03B)
    +#define	BWN_B2062_S_RFPLLCTL8		BWN_LP_SOUTH(0x03C)
    +#define	BWN_B2062_S_RFPLLCTL9		BWN_LP_SOUTH(0x03D)
    +#define	BWN_B2062_S_RFPLLCTL10		BWN_LP_SOUTH(0x03E)
    +#define	BWN_B2062_S_RFPLLCTL11		BWN_LP_SOUTH(0x03F)
    +#define	BWN_B2062_S_RFPLLCTL12		BWN_LP_SOUTH(0x040)
    +#define	BWN_B2062_S_RFPLLCTL13		BWN_LP_SOUTH(0x041)
    +#define	BWN_B2062_S_RFPLLCTL14		BWN_LP_SOUTH(0x042)
    +#define	BWN_B2062_S_RFPLLCTL18		BWN_LP_SOUTH(0x046)
    +#define	BWN_B2062_S_RFPLLCTL19		BWN_LP_SOUTH(0x047)
    +#define	BWN_B2062_S_RFPLLCTL21		BWN_LP_SOUTH(0x049)
    +#define	BWN_B2062_S_RFPLLCTL22		BWN_LP_SOUTH(0x04A)
    +#define	BWN_B2062_S_RFPLLCTL23		BWN_LP_SOUTH(0x04B)
    +#define	BWN_B2062_S_RFPLLCTL24		BWN_LP_SOUTH(0x04C)
    +#define	BWN_B2062_S_RFPLLCTL25		BWN_LP_SOUTH(0x04D)
    +#define	BWN_B2062_S_RFPLLCTL26		BWN_LP_SOUTH(0x04E)
    +#define	BWN_B2062_S_RFPLLCTL27		BWN_LP_SOUTH(0x04F)
    +#define	BWN_B2062_S_RFPLLCTL28		BWN_LP_SOUTH(0x050)
    +#define	BWN_B2062_S_RFPLLCTL29		BWN_LP_SOUTH(0x051)
    +#define	BWN_B2062_S_RFPLLCTL30		BWN_LP_SOUTH(0x052)
    +#define	BWN_B2062_S_RFPLLCTL31		BWN_LP_SOUTH(0x053)
    +#define	BWN_B2062_S_RFPLLCTL33		BWN_LP_SOUTH(0x055)
    +#define	BWN_B2062_S_RFPLLCTL34		BWN_LP_SOUTH(0x056)
    +#define	BWN_B2062_S_RXG_CNT8		BWN_LP_SOUTH(0x05F)
    +#define	BWN_B2062_S_RXG_CNT16		BWN_LP_SOUTH(0x067)
    +#define	BWN_B2063_COM1			BWN_LP_RADIO(0x000)
    +#define	BWN_B2063_COM8			BWN_LP_RADIO(0x008)
    +#define	BWN_B2063_COM10			BWN_LP_RADIO(0x00A)
    +#define	BWN_B2063_COM15			BWN_LP_RADIO(0x00F)
    +#define	BWN_B2063_COM16			BWN_LP_RADIO(0x010)
    +#define	BWN_B2063_COM17			BWN_LP_RADIO(0x011)
    +#define	BWN_B2063_COM18			BWN_LP_RADIO(0x012)
    +#define	BWN_B2063_COM19			BWN_LP_RADIO(0x013)
    +#define	BWN_B2063_COM20			BWN_LP_RADIO(0x014)
    +#define	BWN_B2063_COM21			BWN_LP_RADIO(0x015)
    +#define	BWN_B2063_COM22			BWN_LP_RADIO(0x016)
    +#define	BWN_B2063_COM23			BWN_LP_RADIO(0x017)
    +#define	BWN_B2063_COM24			BWN_LP_RADIO(0x018)
    +#define	BWN_B2063_PLL_SP1		BWN_LP_RADIO(0x01A)
    +#define	BWN_B2063_PLL_SP2		BWN_LP_RADIO(0x01B)
    +#define	BWN_B2063_LOGEN_SP1		BWN_LP_RADIO(0x01C)
    +#define	BWN_B2063_LOGEN_SP2		BWN_LP_RADIO(0x01D)
    +#define	BWN_B2063_LOGEN_SP4		BWN_LP_RADIO(0x01F)
    +#define	BWN_B2063_LOGEN_SP5		BWN_LP_RADIO(0x020)
    +#define	BWN_B2063_G_RX_SP1		BWN_LP_RADIO(0x021)
    +#define	BWN_B2063_G_RX_SP2		BWN_LP_RADIO(0x022)
    +#define	BWN_B2063_G_RX_SP3		BWN_LP_RADIO(0x023)
    +#define	BWN_B2063_G_RX_SP7		BWN_LP_RADIO(0x027)
    +#define	BWN_B2063_G_RX_SP10		BWN_LP_RADIO(0x02A)
    +#define	BWN_B2063_A_RX_SP1		BWN_LP_RADIO(0x02C)
    +#define	BWN_B2063_A_RX_SP2		BWN_LP_RADIO(0x02D)
    +#define	BWN_B2063_A_RX_SP7		BWN_LP_RADIO(0x032)
    +#define	BWN_B2063_RX_BB_SP3		BWN_LP_RADIO(0x035)
    +#define	BWN_B2063_RX_BB_SP4		BWN_LP_RADIO(0x036)
    +#define	BWN_B2063_RX_BB_SP8		BWN_LP_RADIO(0x03A)
    +#define	BWN_B2063_TX_RF_SP3		BWN_LP_RADIO(0x03D)
    +#define	BWN_B2063_TX_RF_SP4		BWN_LP_RADIO(0x03E)
    +#define	BWN_B2063_TX_RF_SP6		BWN_LP_RADIO(0x040)
    +#define	BWN_B2063_TX_RF_SP9		BWN_LP_RADIO(0x043)
    +#define	BWN_B2063_PA_SP1		BWN_LP_RADIO(0x04C)
    +#define	BWN_B2063_PA_SP2		BWN_LP_RADIO(0x04D)
    +#define	BWN_B2063_PA_SP3		BWN_LP_RADIO(0x04E)
    +#define	BWN_B2063_PA_SP4		BWN_LP_RADIO(0x04F)
    +#define	BWN_B2063_PA_SP7		BWN_LP_RADIO(0x052)
    +#define	BWN_B2063_TX_BB_SP1		BWN_LP_RADIO(0x053)
    +#define	BWN_B2063_TX_BB_SP3		BWN_LP_RADIO(0x055)
    +#define	BWN_B2063_REG_SP1		BWN_LP_RADIO(0x056)
    +#define	BWN_B2063_BANDGAP_CTL1		BWN_LP_RADIO(0x057)
    +#define	BWN_B2063_RC_CALIB_CTL1		BWN_LP_RADIO(0x05A)
    +#define	BWN_B2063_RC_CALIB_CTL2		BWN_LP_RADIO(0x05B)
    +#define	BWN_B2063_RC_CALIB_CTL3		BWN_LP_RADIO(0x05C)
    +#define	BWN_B2063_RC_CALIB_CTL4		BWN_LP_RADIO(0x05D)
    +#define	BWN_B2063_RC_CALIB_CTL5		BWN_LP_RADIO(0x05E)
    +#define	BWN_B2063_RC_CALIB_CTL6		BWN_LP_RADIO(0x05F)
    +#define	BWN_B2063_JTAG_CALNRST		BWN_LP_RADIO(0x064)
    +#define	BWN_B2063_JTAG_CP2		BWN_LP_RADIO(0x068)
    +#define	BWN_B2063_JTAG_CP3		BWN_LP_RADIO(0x069)
    +#define	BWN_B2063_JTAG_LF1		BWN_LP_RADIO(0x06C)
    +#define	BWN_B2063_JTAG_LF2		BWN_LP_RADIO(0x06D)
    +#define	BWN_B2063_JTAG_LF3		BWN_LP_RADIO(0x06E)
    +#define	BWN_B2063_JTAG_LF4		BWN_LP_RADIO(0x06F)
    +#define	BWN_B2063_JTAG_SG1		BWN_LP_RADIO(0x070)
    +#define	BWN_B2063_JTAG_SG2		BWN_LP_RADIO(0x071)
    +#define	BWN_B2063_JTAG_SG3		BWN_LP_RADIO(0x072)
    +#define	BWN_B2063_JTAG_SG4		BWN_LP_RADIO(0x073)
    +#define	BWN_B2063_JTAG_VCO1		BWN_LP_RADIO(0x075)
    +#define	BWN_B2063_JTAG_VCO2		BWN_LP_RADIO(0x076)
    +#define	BWN_B2063_JTAG_VCO_CALIB3	BWN_LP_RADIO(0x079)
    +#define	BWN_B2063_JTAG_VCO_CALIB5	BWN_LP_RADIO(0x07B)
    +#define	BWN_B2063_JTAG_VCO_CALIB6	BWN_LP_RADIO(0x07C)
    +#define	BWN_B2063_JTAG_VCO_CALIB7	BWN_LP_RADIO(0x07D)
    +#define	BWN_B2063_JTAG_VCO_CALIB8	BWN_LP_RADIO(0x07E)
    +#define	BWN_B2063_JTAG_XTAL_12		BWN_LP_RADIO(0x081)
    +#define	BWN_B2063_LOGEN_RCCR1		BWN_LP_RADIO(0x0A1)
    +#define	BWN_B2063_LOGEN_VCOBUF1		BWN_LP_RADIO(0x0A2)
    +#define	BWN_B2063_LOGEN_MIXER2		BWN_LP_RADIO(0x0A4)
    +#define	BWN_B2063_LOGEN_BUF2		BWN_LP_RADIO(0x0A6)
    +#define	BWN_B2063_G_RX_MIX3		BWN_LP_RADIO(0x0C4)
    +#define	BWN_B2063_G_RX_MIX4		BWN_LP_RADIO(0x0C5)
    +#define	BWN_B2063_A_RX_1ST2		BWN_LP_RADIO(0x0CF)
    +#define	BWN_B2063_A_RX_1ST3		BWN_LP_RADIO(0x0D0)
    +#define	BWN_B2063_A_RX_2ND1		BWN_LP_RADIO(0x0D3)
    +#define	BWN_B2063_A_RX_2ND4		BWN_LP_RADIO(0x0D6)
    +#define	BWN_B2063_A_RX_2ND7		BWN_LP_RADIO(0x0D9)
    +#define	BWN_B2063_A_RX_PS6		BWN_LP_RADIO(0x0DF)
    +#define	BWN_B2063_A_RX_MIX4		BWN_LP_RADIO(0x0E3)
    +#define	BWN_B2063_A_RX_MIX5		BWN_LP_RADIO(0x0E4)
    +#define	BWN_B2063_A_RX_MIX6		BWN_LP_RADIO(0x0E5)
    +#define	BWN_B2063_RX_TIA_CTL1		BWN_LP_RADIO(0x0EC)
    +#define	BWN_B2063_RX_TIA_CTL3		BWN_LP_RADIO(0x0EE)
    +#define	BWN_B2063_RX_BB_CTL2		BWN_LP_RADIO(0x0F3)
    +#define	BWN_B2063_TX_RF_CTL2		BWN_LP_RADIO(0x100)
    +#define	BWN_B2063_TX_RF_CTL5		BWN_LP_RADIO(0x103)
    +#define	BWN_B2063_PA_CTL1		BWN_LP_RADIO(0x10B)
    +#define	BWN_B2063_PA_CTL11		BWN_LP_RADIO(0x115)
    +#define	BWN_B2063_VREG_CTL1		BWN_LP_RADIO(0x11D)
    +
    +#endif	/* !_IF_BWNREG_H */
    diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h
    new file mode 100644
    index 00000000000..40b759e24b9
    --- /dev/null
    +++ b/sys/dev/bwn/if_bwnvar.h
    @@ -0,0 +1,957 @@
    +/*-
    + * Copyright (c) 2009-2010 Weongyo Jeong 
    + * 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.
    + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    + *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
    + *    redistribution must be conditioned upon including a substantially
    + *    similar Disclaimer requirement for further binary redistribution.
    + *
    + * NO WARRANTY
    + * 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 NONINFRINGEMENT, MERCHANTIBILITY
    + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
    + *
    + * $FreeBSD$
    + */
    +
    +#ifndef _IF_BWNVAR_H
    +#define	_IF_BWNVAR_H
    +
    +struct siba_dev_softc;
    +struct bwn_softc;
    +struct bwn_mac;
    +
    +#define	N(a)			(sizeof(a) / sizeof(a[0]))
    +#define	BWN_ALIGN			0x1000
    +#define	BWN_BUS_SPACE_MAXADDR_30BIT	0x3fffffff
    +#define	BWN_RETRY_SHORT			7
    +#define	BWN_RETRY_LONG			4
    +#define	BWN_STAID_MAX			64
    +#define	BWN_TXPWR_IGNORE_TIME		(1 << 0)
    +#define	BWN_TXPWR_IGNORE_TSSI		(1 << 1)
    +#define	BWN_HAS_TXMAG(phy)						\
    +	(((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) &&		\
    +	 ((phy)->rf_rev == 8))
    +#define	BWN_HAS_LOOPBACK(phy)						\
    +	(((phy)->rev > 1) || ((phy)->gmode))
    +#define	BWN_TXERROR_MAX			1000
    +#define	BWN_GETTIME(v)	do {						\
    +	struct timespec ts;						\
    +	nanouptime(&ts);						\
    +	(v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000;			\
    +} while (0)
    +#define	BWN_ISOLDFMT(mac)		((mac)->mac_fw.rev <= 351)
    +#define	BWN_TSSI2DBM(num, den)						\
    +	((int32_t)((num < 0) ? num / den : (num + den / 2) / den))
    +#define	BWN_HDRSIZE(mac)						\
    +	((BWN_ISOLDFMT(mac)) ? (100 + sizeof(struct bwn_plcp6)) :	\
    +	    (104 + sizeof(struct bwn_plcp6)))
    +#define	BWN_PIO_COOKIE(tq, tp)						\
    +	((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
    +#define	BWN_DMA_COOKIE(dr, slot)					\
    +	((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
    +#define	BWN_READ_2(mac, o)		(siba_read_2(mac->mac_sd, o))
    +#define	BWN_READ_4(mac, o)		(siba_read_4(mac->mac_sd, o))
    +#define	BWN_WRITE_2(mac, o, v)		(siba_write_2(mac->mac_sd, o, v))
    +#define	BWN_WRITE_4(mac, o, v)		(siba_write_4(mac->mac_sd, o, v))
    +#define	BWN_PIO_TXQOFFSET(mac)						\
    +	((mac->mac_sd->sd_id.sd_rev >= 11) ? 0x18 : 0)
    +#define	BWN_PIO_RXQOFFSET(mac)						\
    +	((mac->mac_sd->sd_id.sd_rev >= 11) ? 0x38 : 8)
    +#define	BWN_SEC_NEWAPI(mac)		(mac->mac_fw.rev >= 351)
    +#define	BWN_SEC_KEY2FW(mac, idx)					\
    +	(BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx))
    +#define	BWN_RF_READ(mac, r)		(mac->mac_phy.rf_read(mac, r))
    +#define	BWN_RF_WRITE(mac, r, v)		(mac->mac_phy.rf_write(mac, r, v))
    +#define	BWN_RF_MASK(mac, o, m)						\
    +	BWN_RF_WRITE(mac, o, BWN_RF_READ(mac, o) & m)
    +#define	BWN_RF_SETMASK(mac, offset, mask, set)				\
    +	BWN_RF_WRITE(mac, offset, (BWN_RF_READ(mac, offset) & mask) | set)
    +#define	BWN_RF_SET(mac, offset, set)					\
    +	BWN_RF_WRITE(mac, offset, BWN_RF_READ(mac, offset) | set)
    +#define	BWN_PHY_READ(mac, r)		(mac->mac_phy.phy_read(mac, r))
    +#define	BWN_PHY_WRITE(mac, r, v)					\
    +	(mac->mac_phy.phy_write(mac, r, v))
    +#define	BWN_PHY_SET(mac, offset, set)	do {				\
    +	if (mac->mac_phy.phy_maskset != NULL) {				\
    +		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
    +		    mac->mac_suspended > 0,				\
    +		    ("dont access PHY or RF registers after turning on MAC")); \
    +		mac->mac_phy.phy_maskset(mac, offset, 0xffff, set);	\
    +	} else								\
    +		BWN_PHY_WRITE(mac, offset,				\
    +		    BWN_PHY_READ(mac, offset) | (set));			\
    +} while (0)
    +#define	BWN_PHY_SETMASK(mac, offset, mask, set)	do {			\
    +	if (mac->mac_phy.phy_maskset != NULL) {				\
    +		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
    +		    mac->mac_suspended > 0,				\
    +		    ("dont access PHY or RF registers after turning on MAC")); \
    +		mac->mac_phy.phy_maskset(mac, offset, mask, set);	\
    +	} else								\
    +		BWN_PHY_WRITE(mac, offset,				\
    +		    (BWN_PHY_READ(mac, offset) & (mask)) | (set));	\
    +} while (0)
    +#define	BWN_PHY_MASK(mac, offset, mask)	do {				\
    +	if (mac->mac_phy.phy_maskset != NULL) {				\
    +		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
    +		    mac->mac_suspended > 0,				\
    +		    ("dont access PHY or RF registers after turning on MAC")); \
    +		mac->mac_phy.phy_maskset(mac, offset, mask, 0);		\
    +	} else								\
    +		BWN_PHY_WRITE(mac, offset,				\
    +		    BWN_PHY_READ(mac, offset) & mask);			\
    +} while (0)
    +#define	BWN_PHY_COPY(mac, dst, src)	do {				\
    +	KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||		\
    +	    mac->mac_suspended > 0,					\
    +	    ("dont access PHY or RF registers after turning on MAC"));	\
    +	BWN_PHY_WRITE(mac, dst, BWN_PHY_READ(mac, src));		\
    +} while (0)
    +#define BWN_LO_CALIB_EXPIRE		(1000 * (30 - 2))
    +#define BWN_LO_PWRVEC_EXPIRE		(1000 * (30 - 2))
    +#define BWN_LO_TXCTL_EXPIRE		(1000 * (180 - 4))
    +#define	BWN_DMA_BIT_MASK(n)		(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
    +#define BWN_LPD(L, P, D)		(((L) << 2) | ((P) << 1) | ((D) << 0))
    +#define BWN_BITREV4(tmp)		(BWN_BITREV8(tmp) >> 4)
    +#define	BWN_BITREV8(byte)		(bwn_bitrev_table[byte])
    +#define	BWN_BBATTCMP(a, b)		((a)->att == (b)->att)
    +#define	BWN_RFATTCMP(a, b)						\
    +	(((a)->att == (b)->att) && ((a)->padmix == (b)->padmix))
    +#define	BWN_PIO_WRITE_2(mac, tq, offset, value)				\
    +	BWN_WRITE_2(mac, (tq)->tq_base + offset, value)
    +#define	BWN_PIO_READ_4(mac, tq, offset)					\
    +	BWN_READ_4(mac, tq->tq_base + offset)
    +#define	BWN_ISCCKRATE(rate)						\
    +	(rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB ||	\
    +	 rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
    +#define	BWN_ISOFDMRATE(rate)		(!BWN_ISCCKRATE(rate))
    +#define	BWN_BARRIER(mac, flags)		siba_barrier(mac->mac_sd, flags)
    +#define	BWN_DMA_READ(dr, offset)				\
    +	(BWN_READ_4(dr->dr_mac, dr->dr_base + offset))
    +#define	BWN_DMA_WRITE(dr, offset, value)			\
    +	(BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value))
    +
    +struct bwn_rate {
    +	uint16_t			rateid;
    +	uint32_t			flags;
    +};
    +
    +#define	BWN_ANT0			0
    +#define	BWN_ANT1			1
    +#define	BWN_ANTAUTO0			2
    +#define	BWN_ANTAUTO1			3
    +#define	BWN_ANT2			4
    +#define	BWN_ANT3			8
    +#define	BWN_ANTAUTO			BWN_ANTAUTO0
    +#define	BWN_ANT_DEFAULT			BWN_ANTAUTO
    +#define	BWN_TX_SLOTS_PER_FRAME		2
    +
    +struct bwn_channel {
    +	unsigned			freq;
    +	unsigned			ieee;
    +	unsigned			maxTxPow;
    +};
    +
    +struct bwn_channelinfo {
    +	struct bwn_channel		channels[IEEE80211_CHAN_MAX];
    +	unsigned			nchannels;
    +};
    +
    +struct bwn_bbatt {
    +	uint8_t				att;
    +};
    +
    +struct bwn_bbatt_list {
    +	const struct bwn_bbatt		*array;
    +	uint8_t				len;
    +	uint8_t				min;
    +	uint8_t				max;
    +};
    +
    +struct bwn_rfatt {
    +	uint8_t				att;
    +	int				padmix;
    +};
    +
    +struct bwn_rfatt_list {
    +	const struct bwn_rfatt		*array;
    +	uint8_t				len;
    +	uint8_t				min;
    +	uint8_t				max;
    +};
    +
    +#define	BWN_DC_LT_SIZE			32
    +
    +struct bwn_loctl {
    +	int8_t				i;
    +	int8_t				q;
    +};
    +
    +struct bwn_lo_calib {
    +	struct bwn_bbatt		bbatt;
    +	struct bwn_rfatt		rfatt;
    +	struct bwn_loctl		ctl;
    +	unsigned long			calib_time;
    +	TAILQ_ENTRY(bwn_lo_calib)	list;
    +};
    +
    +struct bwn_rxhdr4 {
    +	uint16_t			frame_len;
    +	uint8_t				pad1[2];
    +	uint16_t			phy_status0;
    +	union {
    +		struct {
    +			uint8_t		rssi;
    +			uint8_t		sig_qual;
    +		} __packed abg;
    +		struct {
    +			int8_t		power0;
    +			int8_t		power1;
    +		} __packed n;
    +	} __packed phy;
    +	uint16_t			phy_status2;
    +	uint16_t			phy_status3;
    +	uint32_t			mac_status;
    +	uint16_t			mac_time;
    +	uint16_t			channel;
    +} __packed;
    +
    +struct bwn_txstatus {
    +	uint16_t			cookie;
    +	uint16_t			seq;
    +	uint8_t				phy_stat;
    +	uint8_t				framecnt;
    +	uint8_t				rtscnt;
    +	uint8_t				sreason;
    +	uint8_t				pm;
    +	uint8_t				im;
    +	uint8_t				ampdu;
    +	uint8_t				ack;
    +};
    +
    +#define	BWN_TXCTL_PA3DB			0x40
    +#define	BWN_TXCTL_PA2DB			0x20
    +#define	BWN_TXCTL_TXMIX			0x10
    +
    +struct bwn_txpwr_loctl {
    +	struct bwn_rfatt_list		rfatt;
    +	struct bwn_bbatt_list		bbatt;
    +	uint16_t			dc_lt[BWN_DC_LT_SIZE];
    +	TAILQ_HEAD(, bwn_lo_calib)	calib_list;
    +	unsigned long			pwr_vec_read_time;
    +	unsigned long			txctl_measured_time;
    +	uint8_t				tx_bias;
    +	uint8_t				tx_magn;
    +	uint64_t			power_vector;
    +};
    +
    +#define	BWN_OFDMTAB_DIR_UNKNOWN		0
    +#define	BWN_OFDMTAB_DIR_READ		1
    +#define	BWN_OFDMTAB_DIR_WRITE		2
    +
    +struct bwn_phy_g {
    +	unsigned			pg_flags;
    +#define	BWN_PHY_G_FLAG_TSSITABLE_ALLOC	(1 << 0)
    +#define	BWN_PHY_G_FLAG_RADIOCTX_VALID	(1 << 1)
    +	int				pg_aci_enable;
    +	int				pg_aci_wlan_automatic;
    +	int				pg_aci_hw_rssi;
    +	int				pg_rf_on;
    +	uint16_t			pg_radioctx_over;
    +	uint16_t			pg_radioctx_overval;
    +	uint16_t			pg_minlowsig[2];
    +	uint16_t			pg_minlowsigpos[2];
    +	int8_t				*pg_tssi2dbm;
    +	int				pg_idletssi;
    +	int				pg_curtssi;
    +	uint8_t				pg_avgtssi;
    +	struct bwn_bbatt		pg_bbatt;
    +	struct bwn_rfatt		pg_rfatt;
    +	uint8_t				pg_txctl;
    +	int				pg_bbatt_delta;
    +	int				pg_rfatt_delta;
    +
    +	struct bwn_txpwr_loctl		pg_loctl;
    +	int16_t				pg_max_lb_gain;
    +	int16_t				pg_trsw_rx_gain;
    +	int16_t				pg_lna_lod_gain;
    +	int16_t				pg_lna_gain;
    +	int16_t				pg_pga_gain;
    +	int				pg_immode;
    +#define	BWN_INTERFSTACK_SIZE	26
    +	uint32_t			pg_interfstack[BWN_INTERFSTACK_SIZE];
    +
    +	int16_t				pg_nrssi[2];
    +	int32_t				pg_nrssi_slope;
    +	int8_t				pg_nrssi_lt[64];
    +
    +	uint16_t			pg_lofcal;
    +
    +	uint16_t			pg_initval;
    +	uint16_t			pg_ofdmtab_addr;
    +	unsigned			pg_ofdmtab_dir;
    +};
    +
    +#define	BWN_IMMODE_NONE			0
    +#define	BWN_IMMODE_NONWLAN		1
    +#define	BWN_IMMODE_MANUAL		2
    +#define	BWN_IMMODE_AUTO			3
    +#define	BWN_TXPWR_RES_NEED_ADJUST	0
    +#define	BWN_TXPWR_RES_DONE		1
    +
    +#define	BWN_PHYLP_TXPCTL_UNKNOWN	0
    +#define	BWN_PHYLP_TXPCTL_OFF		1
    +#define	BWN_PHYLP_TXPCTL_ON_SW		2
    +#define	BWN_PHYLP_TXPCTL_ON_HW		3
    +
    +struct bwn_phy_lp {
    +	uint8_t				plp_chan;
    +	uint8_t				plp_chanfullcal;
    +	int32_t				plp_antenna;
    +	uint8_t				plp_txpctlmode;
    +	uint8_t				plp_txisoband_h;
    +	uint8_t				plp_txisoband_m;
    +	uint8_t				plp_txisoband_l;
    +	uint8_t				plp_rxpwroffset;
    +	int8_t				plp_txpwridx;
    +	uint16_t			plp_tssiidx;
    +	uint16_t			plp_tssinpt;
    +	uint8_t				plp_rssivf;
    +	uint8_t				plp_rssivc;
    +	uint8_t				plp_rssigs;
    +	uint8_t				plp_rccap;
    +	uint8_t				plp_bxarch;
    +	uint8_t				plp_crsusr_off;
    +	uint8_t				plp_crssys_off;
    +	uint32_t			plp_div;
    +	int32_t				plp_tonefreq;
    +	uint16_t			plp_digfilt[9];
    +};
    +
    +/* for LP */
    +struct bwn_txgain {
    +	uint16_t			tg_gm;
    +	uint16_t			tg_pga;
    +	uint16_t			tg_pad;
    +	uint16_t			tg_dac;
    +};
    +
    +struct bwn_rxcompco {
    +	uint8_t				rc_chan;
    +	int8_t				rc_c1;
    +	int8_t				rc_c0;
    +};
    +
    +struct bwn_phy_lp_iq_est {
    +	uint32_t			ie_iqprod;
    +	uint32_t			ie_ipwr;
    +	uint32_t			ie_qpwr;
    +};
    +
    +struct bwn_txgain_entry {
    +	uint8_t				te_gm;
    +	uint8_t				te_pga;
    +	uint8_t				te_pad;
    +	uint8_t				te_dac;
    +	uint8_t				te_bbmult;
    +};
    +
    +/* only for LP PHY */
    +struct bwn_stxtable {
    +	uint16_t			st_phyoffset;
    +	uint16_t			st_physhift;
    +	uint16_t			st_rfaddr;
    +	uint16_t			st_rfshift;
    +	uint16_t			st_mask;
    +};
    +
    +struct bwn_b206x_chan {
    +	uint8_t				bc_chan;
    +	uint16_t			bc_freq;
    +	const uint8_t			*bc_data;
    +};
    +
    +struct bwn_b206x_rfinit_entry {
    +	uint16_t			br_offset;
    +	uint16_t			br_valuea;
    +	uint16_t			br_valueg;
    +	uint8_t				br_flags;
    +};
    +
    +struct bwn_phy {
    +	uint8_t				type;
    +	uint8_t				rev;
    +	uint8_t				analog;
    +
    +	int				supports_2ghz;
    +	int				supports_5ghz;
    +
    +	int				gmode;
    +	struct bwn_phy_g		phy_g;
    +	struct bwn_phy_lp		phy_lp;
    +
    +	uint16_t			rf_manuf;
    +	uint16_t			rf_ver;
    +	uint8_t				rf_rev;
    +	int				rf_on;
    +
    +	int				txpower;
    +	int				hwpctl;
    +	unsigned long			nexttime;
    +	unsigned int			chan;
    +	int				txerrors;
    +
    +	int				(*attach)(struct bwn_mac *);
    +	void				(*detach)(struct bwn_mac *);
    +	int				(*prepare_hw)(struct bwn_mac *);
    +	void				(*init_pre)(struct bwn_mac *);
    +	int				(*init)(struct bwn_mac *);
    +	void				(*exit)(struct bwn_mac *);
    +	uint16_t			(*phy_read)(struct bwn_mac *, uint16_t);
    +	void				(*phy_write)(struct bwn_mac *, uint16_t,
    +					    uint16_t);
    +	void				(*phy_maskset)(struct bwn_mac *,
    +					    uint16_t, uint16_t, uint16_t);
    +	uint16_t			(*rf_read)(struct bwn_mac *, uint16_t);
    +	void				(*rf_write)(struct bwn_mac *, uint16_t,
    +					    uint16_t);
    +	int				(*use_hwpctl)(struct bwn_mac *);
    +	void				(*rf_onoff)(struct bwn_mac *, int);
    +	void				(*switch_analog)(struct bwn_mac *, int);
    +	int				(*switch_channel)(struct bwn_mac *,
    +					    unsigned int);
    +	uint32_t			(*get_default_chan)(struct bwn_mac *);
    +	void				(*set_antenna)(struct bwn_mac *, int);
    +	int				(*set_im)(struct bwn_mac *, int);
    +	int				(*recalc_txpwr)(struct bwn_mac *, int);
    +	void				(*set_txpwr)(struct bwn_mac *);
    +	void				(*task_15s)(struct bwn_mac *);
    +	void				(*task_60s)(struct bwn_mac *);
    +};
    +
    +struct bwn_chan_band {
    +	uint32_t			flags;
    +	uint8_t				nchan;
    +#define	BWN_MAX_CHAN_PER_BAND		14
    +	uint8_t				chan[BWN_MAX_CHAN_PER_BAND];
    +};
    +
    +#define	BWN_NR_WMEPARAMS		16
    +enum {
    +	BWN_WMEPARAM_TXOP = 0,
    +	BWN_WMEPARAM_CWMIN,
    +	BWN_WMEPARAM_CWMAX,
    +	BWN_WMEPARAM_CWCUR,
    +	BWN_WMEPARAM_AIFS,
    +	BWN_WMEPARAM_BSLOTS,
    +	BWN_WMEPARAM_REGGAP,
    +	BWN_WMEPARAM_STATUS,
    +};
    +
    +#define	BWN_WME_PARAMS(queue)	\
    +	(BWN_SHARED_EDCFQ + (BWN_NR_WMEPARAMS * sizeof(uint16_t) * (queue)))
    +#define	BWN_WME_BACKGROUND	BWN_WME_PARAMS(0)
    +#define	BWN_WME_BESTEFFORT	BWN_WME_PARAMS(1)
    +#define	BWN_WME_VIDEO		BWN_WME_PARAMS(2)
    +#define	BWN_WME_VOICE		BWN_WME_PARAMS(3)
    +
    +/*
    + * Radio capture format.
    + */
    +#define	BWN_RX_RADIOTAP_PRESENT (		\
    +	(1 << IEEE80211_RADIOTAP_TSFT)		| \
    +	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
    +	(1 << IEEE80211_RADIOTAP_RATE)		| \
    +	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
    +	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
    +	(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)	| \
    +	(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)	| \
    +	0)
    +
    +struct bwn_rx_radiotap_header {
    +	struct ieee80211_radiotap_header wr_ihdr;
    +	uint64_t			wr_tsf;
    +	u_int8_t			wr_flags;
    +	u_int8_t			wr_rate;
    +	u_int16_t			wr_chan_freq;
    +	u_int16_t			wr_chan_flags;
    +	int8_t				wr_antsignal;
    +	int8_t				wr_antnoise;
    +	u_int8_t			wr_antenna;
    +};
    +
    +#define	BWN_TX_RADIOTAP_PRESENT (		\
    +	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
    +	(1 << IEEE80211_RADIOTAP_RATE)		| \
    +	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
    +	(1 << IEEE80211_RADIOTAP_DBM_TX_POWER)	| \
    +	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
    +	0)
    +
    +struct bwn_tx_radiotap_header {
    +	struct ieee80211_radiotap_header wt_ihdr;
    +	u_int8_t			wt_flags;
    +	u_int8_t			wt_rate;
    +	u_int16_t			wt_chan_freq;
    +	u_int16_t			wt_chan_flags;
    +	u_int8_t			wt_txpower;
    +	u_int8_t			wt_antenna;
    +};
    +
    +struct bwn_stats {
    +	int32_t				link_noise;
    +};
    +
    +/* Noise Calculation (Link Quality) */
    +struct bwn_noise {
    +	uint8_t				noi_running;
    +	uint8_t				noi_nsamples;
    +	int8_t				noi_samples[8][4];
    +};
    +
    +#define	BWN_DMA_30BIT			30
    +#define	BWN_DMA_32BIT			32
    +#define	BWN_DMA_64BIT			64
    +
    +struct bwn_dmadesc_meta {
    +	bus_dmamap_t			mt_dmap;
    +	bus_addr_t			mt_paddr;
    +	struct mbuf			*mt_m;
    +	struct ieee80211_node		*mt_ni;
    +	uint8_t				mt_txtype;
    +#define	BWN_DMADESC_METATYPE_HEADER	0
    +#define	BWN_DMADESC_METATYPE_BODY	1
    +	uint8_t				mt_islast;
    +};
    +
    +#define	BWN_DMAINTR_FATALMASK	\
    +	((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15))
    +#define	BWN_DMAINTR_NONFATALMASK	(1 << 13)
    +#define	BWN_DMAINTR_RX_DONE		(1 << 16)
    +
    +#define	BWN_DMA32_DCTL_BYTECNT		0x00001fff
    +#define	BWN_DMA32_DCTL_ADDREXT_MASK	0x00030000
    +#define	BWN_DMA32_DCTL_ADDREXT_SHIFT	16
    +#define	BWN_DMA32_DCTL_DTABLEEND	0x10000000
    +#define	BWN_DMA32_DCTL_IRQ		0x20000000
    +#define	BWN_DMA32_DCTL_FRAMEEND		0x40000000
    +#define	BWN_DMA32_DCTL_FRAMESTART	0x80000000
    +struct bwn_dmadesc32 {
    +	uint32_t			control;
    +	uint32_t			address;
    +} __packed;
    +
    +#define	BWN_DMA64_DCTL0_DTABLEEND	0x10000000
    +#define	BWN_DMA64_DCTL0_IRQ		0x20000000
    +#define	BWN_DMA64_DCTL0_FRAMEEND	0x40000000
    +#define	BWN_DMA64_DCTL0_FRAMESTART	0x80000000
    +#define	BWN_DMA64_DCTL1_BYTECNT		0x00001fff
    +#define	BWN_DMA64_DCTL1_ADDREXT_MASK	0x00030000
    +#define	BWN_DMA64_DCTL1_ADDREXT_SHIFT	16
    +struct bwn_dmadesc64 {
    +	uint32_t			control0;
    +	uint32_t			control1;
    +	uint32_t			address_low;
    +	uint32_t			address_high;
    +} __packed;
    +
    +struct bwn_dmadesc_generic {
    +	union {
    +		struct bwn_dmadesc32 dma32;
    +		struct bwn_dmadesc64 dma64;
    +	} __packed dma;
    +} __packed;
    +
    +struct bwn_dma_ring;
    +
    +struct bwn_dma_ring {
    +	struct bwn_mac			*dr_mac;
    +	const struct bwn_dma_ops	*dr_ops;
    +	struct bwn_dmadesc_meta		*dr_meta;
    +	void				*dr_txhdr_cache;
    +	bus_dma_tag_t			dr_ring_dtag;
    +	bus_dma_tag_t			dr_txring_dtag;
    +	bus_dmamap_t			dr_spare_dmap; /* only for RX */
    +	bus_dmamap_t			dr_ring_dmap;
    +	bus_addr_t			dr_txring_paddr;
    +	void				*dr_ring_descbase;
    +	bus_addr_t			dr_ring_dmabase;
    +	int				dr_numslots;
    +	int				dr_usedslot;
    +	int				dr_curslot;
    +	uint32_t			dr_frameoffset;
    +	uint16_t			dr_rx_bufsize;
    +	uint16_t			dr_base;
    +	int				dr_index;
    +	uint8_t				dr_tx;
    +	uint8_t				dr_stop;
    +	int				dr_type;
    +
    +	void				(*getdesc)(struct bwn_dma_ring *,
    +					    int, struct bwn_dmadesc_generic **,
    +					    struct bwn_dmadesc_meta **);
    +	void				(*setdesc)(struct bwn_dma_ring *,
    +					    struct bwn_dmadesc_generic *,
    +					    bus_addr_t, uint16_t, int, int,
    +					    int);
    +	void				(*start_transfer)(struct bwn_dma_ring *,
    +					    int);
    +	void				(*suspend)(struct bwn_dma_ring *);
    +	void				(*resume)(struct bwn_dma_ring *);
    +	int				(*get_curslot)(struct bwn_dma_ring *);
    +	void				(*set_curslot)(struct bwn_dma_ring *,
    +					    int);
    +};
    +
    +struct bwn_dma {
    +	int				dmatype;
    +	bus_dma_tag_t			parent_dtag;
    +	bus_dma_tag_t			rxbuf_dtag;
    +	bus_dma_tag_t			txbuf_dtag;
    +
    +	struct bwn_dma_ring		*wme[5];
    +	struct bwn_dma_ring		*mcast;
    +	struct bwn_dma_ring		*rx;
    +	uint64_t			lastseq;	/* XXX FIXME */
    +};
    +
    +struct bwn_pio_rxqueue {
    +	struct bwn_mac			*prq_mac;
    +	uint16_t			prq_base;
    +	uint8_t				prq_rev;
    +};
    +
    +struct bwn_pio_txqueue;
    +struct bwn_pio_txpkt {
    +	struct bwn_pio_txqueue		*tp_queue;
    +	struct ieee80211_node		*tp_ni;
    +	struct mbuf			*tp_m;
    +	uint8_t				tp_index;
    +	TAILQ_ENTRY(bwn_pio_txpkt)	tp_list;
    +};
    +
    +#define	BWN_PIO_MAX_TXPACKETS		32
    +struct bwn_pio_txqueue {
    +	uint16_t			tq_base;
    +	uint16_t			tq_size;
    +	uint16_t			tq_used;
    +	uint16_t			tq_free;
    +	uint8_t				tq_stop;
    +	uint8_t				tq_index;
    +	struct bwn_pio_txpkt		tq_pkts[BWN_PIO_MAX_TXPACKETS];
    +	TAILQ_HEAD(, bwn_pio_txpkt)	tq_pktlist;
    +};
    +
    +struct bwn_pio {
    +	struct bwn_pio_txqueue		wme[5];
    +	struct bwn_pio_txqueue		mcast;
    +	struct bwn_pio_rxqueue		rx;
    +};
    +
    +struct bwn_plcp4 {
    +	union {
    +		uint32_t		data;
    +		uint8_t			raw[4];
    +	} __packed o;
    +} __packed;
    +
    +struct bwn_plcp6 {
    +	union {
    +		uint32_t		data;
    +		uint8_t			raw[6];
    +	} __packed o;
    +} __packed;
    +
    +struct bwn_txhdr {
    +	uint32_t			macctl;
    +	uint8_t				macfc[2];
    +	uint16_t			tx_festime;
    +	uint16_t			phyctl;
    +	uint16_t			phyctl_1;
    +	uint16_t			phyctl_1fb;
    +	uint16_t			phyctl_1rts;
    +	uint16_t			phyctl_1rtsfb;
    +	uint8_t				phyrate;
    +	uint8_t				phyrate_rts;
    +	uint8_t				eftypes;	/* extra frame types */
    +	uint8_t				chan;
    +	uint8_t				iv[16];
    +	uint8_t				addr1[IEEE80211_ADDR_LEN];
    +	uint16_t			tx_festime_fb;
    +	struct bwn_plcp6		rts_plcp_fb;
    +	uint16_t			rts_dur_fb;
    +	struct bwn_plcp6		plcp_fb;
    +	uint16_t			dur_fb;
    +	uint16_t			mimo_modelen;
    +	uint16_t			mimo_ratelen_fb;
    +	uint32_t			timeout;
    +
    +	union {
    +		/* format <= r351 */
    +		struct {
    +			uint8_t		pad0[2];
    +			uint16_t	cookie;
    +			uint16_t	tx_status;
    +			struct bwn_plcp6	rts_plcp;
    +			uint8_t		rts_frame[16];
    +			uint8_t		pad1[2];;
    +			struct bwn_plcp6	plcp;
    +		} __packed old;
    +		/* format > r410 */
    +		struct {
    +			uint16_t	mimo_antenna;
    +			uint16_t	preload_size;
    +			uint8_t		pad0[2];
    +			uint16_t	cookie;
    +			uint16_t	tx_status;
    +			struct bwn_plcp6	rts_plcp;
    +			uint8_t		rts_frame[16];
    +			uint8_t		pad1[2];
    +			struct bwn_plcp6	plcp;
    +		} __packed new;
    +	} __packed body;
    +} __packed;
    +
    +#define	BWN_FWTYPE_UCODE		'u'
    +#define	BWN_FWTYPE_PCM			'p'
    +#define	BWN_FWTYPE_IV			'i'
    +struct bwn_fwhdr {
    +	uint8_t				type;
    +	uint8_t				ver;
    +	uint8_t				pad[2];
    +	uint32_t			size;
    +} __packed;
    +
    +#define	BWN_FWINITVALS_OFFSET_MASK	0x7fff
    +#define	BWN_FWINITVALS_32BIT		0x8000
    +struct bwn_fwinitvals {
    +	uint16_t			offset_size;
    +	union {
    +		uint16_t		d16;
    +		uint32_t		d32;
    +	} __packed data;
    +} __packed;
    +
    +enum bwn_fwtype {
    +	BWN_FWTYPE_DEFAULT,
    +	BWN_FWTYPE_OPENSOURCE,
    +	BWN_NR_FWTYPES,
    +};
    +
    +struct bwn_fwfile {
    +	const char			*filename;
    +	const struct firmware		*fw;
    +	enum bwn_fwtype			type;
    +};
    +
    +struct bwn_key {
    +	void				*keyconf;
    +	uint8_t				algorithm;
    +};
    +
    +struct bwn_fw {
    +	struct bwn_fwfile		ucode;
    +	struct bwn_fwfile		pcm;
    +	struct bwn_fwfile		initvals;
    +	struct bwn_fwfile		initvals_band;
    +
    +	uint16_t			rev;
    +	uint16_t			patch;
    +	uint8_t				opensource;
    +	uint8_t				no_pcmfile;
    +};
    +
    +struct bwn_lo_g_sm {
    +	int				curstate;
    +	int				nmeasure;
    +	int				multipler;
    +	uint16_t			feedth;
    +	struct bwn_loctl		loctl;
    +};
    +
    +struct bwn_lo_g_value {
    +	uint8_t				old_channel;
    +	uint16_t			phy_lomask;
    +	uint16_t			phy_extg;
    +	uint16_t			phy_dacctl_hwpctl;
    +	uint16_t			phy_dacctl;
    +	uint16_t			phy_hpwr_tssictl;
    +	uint16_t			phy_analogover;
    +	uint16_t			phy_analogoverval;
    +	uint16_t			phy_rfover;
    +	uint16_t			phy_rfoverval;
    +	uint16_t			phy_classctl;
    +	uint16_t			phy_crs0;
    +	uint16_t			phy_pgactl;
    +	uint16_t			phy_syncctl;
    +	uint16_t			phy_cck0;
    +	uint16_t			phy_cck1;
    +	uint16_t			phy_cck2;
    +	uint16_t			phy_cck3;
    +	uint16_t			phy_cck4;
    +	uint16_t			reg0;
    +	uint16_t			reg1;
    +	uint16_t			rf0;
    +	uint16_t			rf1;
    +	uint16_t			rf2;
    +};
    +
    +#define	BWN_LED_MAX			4
    +
    +#define	BWN_LED_EVENT_NONE		-1
    +#define	BWN_LED_EVENT_POLL		0
    +#define	BWN_LED_EVENT_TX		1
    +#define	BWN_LED_EVENT_RX		2
    +#define	BWN_LED_SLOWDOWN(dur)		(dur) = (((dur) * 3) / 2)
    +
    +struct bwn_led {
    +	uint8_t				led_flags;	/* BWN_LED_F_ */
    +	uint8_t				led_act;	/* BWN_LED_ACT_ */
    +	uint8_t				led_mask;
    +};
    +
    +#define	BWN_LED_F_ACTLOW		0x1
    +#define	BWN_LED_F_BLINK			0x2
    +#define	BWN_LED_F_POLLABLE		0x4
    +#define	BWN_LED_F_SLOW			0x8
    +
    +struct bwn_mac {
    +	struct bwn_softc		*mac_sc;
    +	struct siba_dev_softc		*mac_sd;
    +	unsigned			mac_status;
    +#define	BWN_MAC_STATUS_UNINIT		0
    +#define	BWN_MAC_STATUS_INITED		1
    +#define	BWN_MAC_STATUS_STARTED		2
    +	unsigned			mac_flags;
    +	/* use "Bad Frames Preemption" */
    +#define	BWN_MAC_FLAG_BADFRAME_PREEMP	(1 << 0)
    +#define	BWN_MAC_FLAG_DFQVALID		(1 << 1)
    +#define	BWN_MAC_FLAG_RADIO_ON		(1 << 2)
    +#define	BWN_MAC_FLAG_DMA		(1 << 3)
    +#define	BWN_MAC_FLAG_WME		(1 << 4)
    +#define	BWN_MAC_FLAG_HWCRYPTO		(1 << 5)
    +
    +	struct resource_spec		*mac_intr_spec;
    +#define	BWN_MSI_MESSAGES		1
    +	struct resource			*mac_res_irq[BWN_MSI_MESSAGES];
    +	void				*mac_intrhand[BWN_MSI_MESSAGES];
    +	int				mac_msi;
    +
    +	struct bwn_noise		mac_noise;
    +	struct bwn_phy			mac_phy;
    +	struct bwn_stats		mac_stats;
    +	uint32_t			mac_reason_intr;
    +	uint32_t			mac_reason[6];
    +	uint32_t			mac_intr_mask;
    +	int				mac_suspended;
    +
    +	struct bwn_fw			mac_fw;
    +
    +	union {
    +		struct bwn_dma		dma;
    +		struct bwn_pio		pio;
    +	} mac_method;
    +
    +	uint16_t			mac_ktp;	/* Key table pointer */
    +	uint8_t				mac_max_nr_keys;
    +	struct bwn_key			mac_key[58];
    +
    +	unsigned int			mac_task_state;
    +	struct task			mac_intrtask;
    +	struct task			mac_hwreset;
    +	struct task			mac_txpower;
    +
    +	TAILQ_ENTRY(bwn_mac)	mac_list;
    +};
    +
    +struct bwn_node {
    +	struct ieee80211_node		bn_node;	/* must be the first */
    +	struct ieee80211_amrr_node	bn_amn;
    +};
    +#define	BWN_NODE(ni)			((struct bwn_node *)(ni))
    +
    +/*
    + * Driver-specific vap state.
    + */
    +struct bwn_vap {
    +	struct ieee80211vap		bv_vap;	/* base class */
    +	struct ieee80211_amrr		bv_amrr;
    +	int				(*bv_newstate)(struct ieee80211vap *,
    +					    enum ieee80211_state, int);
    +};
    +#define	BWN_VAP(vap)			((struct bwn_vap *)(vap))
    +#define	BWN_VAP_CONST(vap)		((const struct mwl_vap *)(vap))
    +
    +struct bwn_softc {
    +	device_t			sc_dev;
    +	struct siba_dev_softc		*sc_sd;
    +	struct mtx			sc_mtx;
    +	struct ifnet			*sc_ifp;
    +	unsigned			sc_flags;
    +#define	BWN_FLAG_ATTACHED		(1 << 0)
    +#define	BWN_FLAG_INVALID		(1 << 1)
    +#define	BWN_FLAG_NEED_BEACON_TP		(1 << 2)
    +	unsigned			sc_debug;
    +
    +	struct bwn_mac		*sc_curmac;
    +	TAILQ_HEAD(, bwn_mac)	sc_maclist;
    +
    +	uint8_t				sc_macaddr[IEEE80211_ADDR_LEN];
    +	uint8_t				sc_bssid[IEEE80211_ADDR_LEN];
    +	unsigned int			sc_filters;
    +	uint8_t				sc_beacons[2];
    +	uint8_t				sc_rf_enabled;
    +
    +	struct wmeParams		sc_wmeParams[4];
    +
    +	struct callout			sc_rfswitch_ch;	/* for laptop */
    +	struct callout			sc_task_ch;
    +	struct callout			sc_watchdog_ch;
    +	int				sc_watchdog_timer;
    +	struct taskqueue		*sc_tq;	/* private task queue */
    +	int				(*sc_newstate)(struct ieee80211com *,
    +					    enum ieee80211_state, int);
    +	void				(*sc_node_cleanup)(
    +					    struct ieee80211_node *);
    +
    +	int				sc_rx_rate;
    +	int				sc_tx_rate;
    +
    +	int				sc_led_blinking;
    +	int				sc_led_ticks;
    +	struct bwn_led			*sc_blink_led;
    +	struct callout			sc_led_blink_ch;
    +	int				sc_led_blink_offdur;
    +	struct bwn_led			sc_leds[BWN_LED_MAX];
    +	int				sc_led_idle;
    +	int				sc_led_blink;
    +
    +	struct bwn_tx_radiotap_header	sc_tx_th;
    +	struct bwn_rx_radiotap_header	sc_rx_th;
    +};
    +
    +#define	BWN_LOCK_INIT(sc) \
    +	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \
    +	    MTX_NETWORK_LOCK, MTX_DEF)
    +#define	BWN_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
    +#define	BWN_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
    +#define	BWN_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
    +#define	BWN_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)
    +
    +#endif	/* !_IF_BWNVAR_H */
    diff --git a/sys/modules/bwn/Makefile b/sys/modules/bwn/Makefile
    new file mode 100644
    index 00000000000..a5b18aa231a
    --- /dev/null
    +++ b/sys/modules/bwn/Makefile
    @@ -0,0 +1,9 @@
    +# $FreeBSD$
    +
    +.PATH: ${.CURDIR}/../../dev/bwn
    +
    +KMOD=	if_bwn
    +SRCS=	if_bwn.c if_bwnreg.h if_bwnvar.h
    +SRCS+=	device_if.h bus_if.h pci_if.h
    +
    +.include 
    
    From 5533a0c47e6f764c0cebb28ba47f1e5ad92dadbe Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:41:43 +0000
    Subject: [PATCH 2052/2592] MFC r204081:   o print msgs with length if the
     frame is too short to pass to     net80211.   o print key index for debugging
     if the frame is attempted to decrypt     for WEP, AES or TKIP though
     currently HW decryption isn't supported.
    
    ---
     sys/dev/bwn/if_bwn.c | 11 ++++++++---
     1 file changed, 8 insertions(+), 3 deletions(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index 6120474f175..26d4724b474 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -9416,19 +9416,24 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
     
     	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
     	if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
    -		device_printf(sc->sc_dev, "RX: Packet size underrun (1)\n");
    +		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
    +		    m->m_pkthdr.len);
     		goto drop;
     	}
     	plcp = (struct bwn_plcp6 *)(mp + padding);
     	m_adj(m, sizeof(struct bwn_plcp6) + padding);
     	if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
    -		device_printf(sc->sc_dev, "RX: Packet size underrun (2)\n");
    +		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
    +		    m->m_pkthdr.len);
     		goto drop;
     	}
     	wh = mtod(m, struct ieee80211_frame_min *);
     
     	if (macstat & BWN_RX_MAC_DEC)
    -		device_printf(sc->sc_dev, "TODO: BWN_RX_MAC_DEC\n");
    +		device_printf(sc->sc_dev,
    +		    "RX decryption attempted (old %d keyidx %#x)\n",
    +		    BWN_ISOLDFMT(mac),
    +		    (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
     
     	/* XXX calculating RSSI & noise & antenna */
     
    
    From 286546e3d5cea0109f37c39cef624edc5155820b Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:48:48 +0000
    Subject: [PATCH 2053/2592] MFC r204242:   Fix compilation problems with
     INVARIANTS.
    
      # also limit RX decryption attempted messages to 50
    
      Reviewed by:  weongyo
    
    Approved by:	imp (implicit)
    ---
     sys/dev/bwn/if_bwn.c | 47 +++++++++++++++++++-------------------------
     1 file changed, 20 insertions(+), 27 deletions(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index 26d4724b474..bb3128a5f35 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -1496,6 +1496,7 @@ bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
     		return (&mac->mac_method.pio.wme[WME_AC_VO]);
     	}
     	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	return (NULL);
     }
     
     static int
    @@ -1905,10 +1906,9 @@ bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
     static uint32_t
     bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
     {
    -	struct bwn_softc *sc = mac->mac_sc;
     	uint32_t ret;
     
    -	BWN_ASSERT_LOCKED(sc);
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
     
     	if (way == BWN_SHARED) {
     		KASSERT((offset & 0x0001) == 0,
    @@ -1932,10 +1932,9 @@ out:
     static uint16_t
     bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
     {
    -	struct bwn_softc *sc = mac->mac_sc;
     	uint16_t ret;
     
    -	BWN_ASSERT_LOCKED(sc);
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
     
     	if (way == BWN_SHARED) {
     		KASSERT((offset & 0x0001) == 0,
    @@ -1970,9 +1969,7 @@ static void
     bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
         uint32_t value)
     {
    -	struct bwn_softc *sc = mac->mac_sc;
    -
    -	BWN_ASSERT_LOCKED(sc);
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
     
     	if (way == BWN_SHARED) {
     		KASSERT((offset & 0x0001) == 0,
    @@ -1995,9 +1992,7 @@ static void
     bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
         uint16_t value)
     {
    -	struct bwn_softc *sc = mac->mac_sc;
    -
    -	BWN_ASSERT_LOCKED(sc);
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
     
     	if (way == BWN_SHARED) {
     		KASSERT((offset & 0x0001) == 0,
    @@ -3335,10 +3330,9 @@ bwn_core_start(struct bwn_mac *mac)
     static void
     bwn_core_exit(struct bwn_mac *mac)
     {
    -	struct bwn_softc *sc = mac->mac_sc;
     	uint32_t macctl;
     
    -	BWN_ASSERT_LOCKED(sc);
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
     
     	KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
     	    ("%s:%d: fail", __func__, __LINE__));
    @@ -5198,6 +5192,8 @@ bwn_rf_init_bcm2050(struct bwn_mac *mac)
     		0x0e, 0x0f, 0x0d, 0x0f,
     	};
     
    +	loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
    +	    rfoverval = rfover = cck3 = 0;
     	radio0 = BWN_RF_READ(mac, 0x43);
     	radio1 = BWN_RF_READ(mac, 0x51);
     	radio2 = BWN_RF_READ(mac, 0x52);
    @@ -5891,7 +5887,6 @@ static void
     bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
    -	struct bwn_softc *sc = mac->mac_sc;
     	unsigned int i, max_loop;
     	uint16_t value;
     	uint32_t buffer[5] = {
    @@ -5906,7 +5901,7 @@ bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
     		buffer[0] = 0x000b846e;
     	}
     
    -	BWN_ASSERT_LOCKED(sc);
    +	BWN_ASSERT_LOCKED(mac->mac_sc);
     
     	for (i = 0; i < 5; i++)
     		bwn_ram_write(mac, i * 4, buffer[i]);
    @@ -5972,10 +5967,9 @@ bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
     static void
     bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
     {
    -	struct bwn_phy *phy = &mac->mac_phy;
     	uint16_t value;
     
    -	KASSERT(phy->type == BWN_PHYTYPE_G,
    +	KASSERT(mac->mac_phy->type == BWN_PHYTYPE_G,
     	    ("%s:%d: fail", __func__, __LINE__));
     
     	value = (uint8_t) (ctl->q);
    @@ -6570,7 +6564,7 @@ bwn_lo_calibset(struct bwn_mac *mac,
     	struct bwn_phy_g *pg = &phy->phy_g;
     	struct bwn_loctl loctl = { 0, 0 };
     	struct bwn_lo_calib *cal;
    -	struct bwn_lo_g_value sval;
    +	struct bwn_lo_g_value sval = { 0 };
     	int rxgain;
     	uint16_t pad, reg, value;
     
    @@ -8984,9 +8978,7 @@ bwn_noise_gensample(struct bwn_mac *mac)
     static int
     bwn_dma_freeslot(struct bwn_dma_ring *dr)
     {
    -	struct bwn_mac *mac = dr->dr_mac;
    -
    -	BWN_ASSERT_LOCKED(mac->mac_sc);
    +	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
     
     	return (dr->dr_numslots - dr->dr_usedslot);
     }
    @@ -8994,9 +8986,7 @@ bwn_dma_freeslot(struct bwn_dma_ring *dr)
     static int
     bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
     {
    -	struct bwn_mac *mac = dr->dr_mac;
    -
    -	BWN_ASSERT_LOCKED(mac->mac_sc);
    +	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
     
     	KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
     	    ("%s:%d: fail", __func__, __LINE__));
    @@ -9393,9 +9383,10 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
     	uint32_t macstat;
    -	int padding, rate, rssi, noise, type;
    +	int padding, rate, rssi = 0, noise = 0, type;
     	uint16_t phytype, phystat0, phystat3, chanstat;
     	unsigned char *mp = mtod(m, unsigned char *);
    +	static int rx_mac_dec_rpt = 0;
     
     	BWN_ASSERT_LOCKED(sc);
     
    @@ -9429,7 +9420,7 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
     	}
     	wh = mtod(m, struct ieee80211_frame_min *);
     
    -	if (macstat & BWN_RX_MAC_DEC)
    +	if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
     		device_printf(sc->sc_dev,
     		    "RX decryption attempted (old %d keyidx %#x)\n",
     		    BWN_ISOLDFMT(mac),
    @@ -10086,15 +10077,15 @@ bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
     		return (mac->mac_method.dma.wme[WME_AC_BK]);
     	}
     	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
    +	return (NULL);
     }
     
     static int
     bwn_dma_getslot(struct bwn_dma_ring *dr)
     {
    -	struct bwn_mac *mac = dr->dr_mac;
     	int slot;
     
    -	BWN_ASSERT_LOCKED(mac->mac_sc);
    +	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
     
     	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
     	KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
    @@ -10579,6 +10570,7 @@ bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
     		dr = dma->mcast;
     		break;
     	default:
    +		dr = NULL;
     		KASSERT(0 == 1,
     		    ("invalid cookie value %d", cookie & 0xf000));
     	}
    @@ -11677,6 +11669,7 @@ bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
     		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
     		break;
     	default:
    +		ctl = 0;
     		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
     	}
     	BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
    
    From f60b07631bf9361a290eb311d4a8a54bc88d6596 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:51:45 +0000
    Subject: [PATCH 2054/2592] MFC r204256:   fixes a compile error; invalid type
     argument of '->'.
    
    ---
     sys/dev/bwn/if_bwn.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index bb3128a5f35..b77f55c1faa 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -5969,7 +5969,7 @@ bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
     {
     	uint16_t value;
     
    -	KASSERT(mac->mac_phy->type == BWN_PHYTYPE_G,
    +	KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
     	    ("%s:%d: fail", __func__, __LINE__));
     
     	value = (uint8_t) (ctl->q);
    
    From 460ea5b2fd9b5acdc504f5347547813950459202 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:52:54 +0000
    Subject: [PATCH 2055/2592] MFC r204257:   o adds sysctl variables to show
     device statistics.   o records RTS success/fail statistics.
    
      Pointed by:   imp
    ---
     sys/dev/bwn/if_bwn.c    | 45 ++++++++++++++++++++++++++++++++---------
     sys/dev/bwn/if_bwnvar.h |  2 ++
     2 files changed, 37 insertions(+), 10 deletions(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index b77f55c1faa..80b567fbe21 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -536,6 +536,7 @@ static void	bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
     		    struct bwn_txgain_entry);
     static void	bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
     		    struct bwn_txgain_entry);
    +static void	bwn_sysctl_node(struct bwn_softc *);
     
     static struct resource_spec bwn_res_spec_legacy[] = {
     	{ SYS_RES_IRQ,		0,		RF_ACTIVE | RF_SHAREABLE },
    @@ -1066,9 +1067,6 @@ bwn_attach_post(struct bwn_softc *sc)
     	struct ifnet *ifp = sc->sc_ifp;
     	struct siba_dev_softc *sd = sc->sc_sd;
     	struct siba_sprom *sprom = &sd->sd_bus->siba_sprom;
    -#ifdef BWN_DEBUG
    -	device_t dev = sc->sc_dev;
    -#endif
     
     	ic = ifp->if_l2com;
     	ic->ic_ifp = ifp;
    @@ -1117,11 +1115,7 @@ bwn_attach_post(struct bwn_softc *sc)
     	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
     	    BWN_RX_RADIOTAP_PRESENT);
     
    -#ifdef BWN_DEBUG
    -	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
    -	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    -	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
    -#endif
    +	bwn_sysctl_node(sc);
     
     	if (bootverbose)
     		ieee80211_announce(ic);
    @@ -9077,6 +9071,7 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
     	struct bwn_pio_txqueue *tq;
     	struct bwn_pio_txpkt *tp = NULL;
     	struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_stats *stats = &mac->mac_stats;
     	struct ieee80211_node *ni;
     	int slot;
     
    @@ -9088,9 +9083,9 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
     		device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
     	if (status->rtscnt) {
     		if (status->rtscnt == 0xf)
    -			device_printf(sc->sc_dev, "TODO: RTS fail\n");
    +			stats->rtsfail++;
     		else
    -			device_printf(sc->sc_dev, "TODO: RTS ok\n");
    +			stats->rts++;
     	}
     
     	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
    @@ -14285,6 +14280,36 @@ bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
     	bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
     }
     
    +static void
    +bwn_sysctl_node(struct bwn_softc *sc)
    +{
    +	device_t dev = sc->sc_dev;
    +	struct bwn_mac *mac;
    +	struct bwn_stats *stats;
    +
    +	/* XXX assume that count of MAC is only 1. */
    +
    +	if ((mac = sc->sc_curmac) == NULL)
    +		return;
    +	stats = &mac->mac_stats;
    +
    +	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    +	    "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
    +	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    +	    "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
    +	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    +	    "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
    +
    +#ifdef BWN_DEBUG
    +	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
    +	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
    +	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
    +#endif
    +}
    +
     static void
     bwn_identify(driver_t *driver, device_t parent)
     {
    diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h
    index 40b759e24b9..61598c2f390 100644
    --- a/sys/dev/bwn/if_bwnvar.h
    +++ b/sys/dev/bwn/if_bwnvar.h
    @@ -515,6 +515,8 @@ struct bwn_tx_radiotap_header {
     };
     
     struct bwn_stats {
    +	int32_t				rtsfail;
    +	int32_t				rts;
     	int32_t				link_noise;
     };
     
    
    From 56ffe5518525ac41e28a2a6e11bf7a5bac549ea7 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 21:55:44 +0000
    Subject: [PATCH 2056/2592] MFC r204326:   Add bwn(4) driver to the build.
    
    ---
     sys/modules/Makefile | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/modules/Makefile b/sys/modules/Makefile
    index dc088d22d27..8ae3b43d9ce 100644
    --- a/sys/modules/Makefile
    +++ b/sys/modules/Makefile
    @@ -41,6 +41,7 @@ SUBDIR=	${_3dfx} \
     	${_bktr} \
     	${_bm} \
     	bridgestp \
    +	bwn \
     	cam \
     	${_canbepm} \
     	${_canbus} \
    
    From 8fefa76ddfd0070e01a81623c15305c7276e159b Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 22:00:56 +0000
    Subject: [PATCH 2057/2592] MFC r203945:   adds bwn(4) driver man page which
     missed to be merged.
    
    MFC r204327:
      Connect bwn.4 to the build.
    ---
     share/man/man4/Makefile |   1 +
     share/man/man4/bwn.4    | 134 ++++++++++++++++++++++++++++++++++++++++
     2 files changed, 135 insertions(+)
     create mode 100644 share/man/man4/bwn.4
    
    diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
    index f8af593a09b..fc9b0fb17d9 100644
    --- a/share/man/man4/Makefile
    +++ b/share/man/man4/Makefile
    @@ -58,6 +58,7 @@ MAN=	aac.4 \
     	bridge.4 \
     	bt.4 \
     	bwi.4 \
    +	bwn.4 \
     	cardbus.4 \
     	carp.4 \
     	cas.4 \
    diff --git a/share/man/man4/bwn.4 b/share/man/man4/bwn.4
    new file mode 100644
    index 00000000000..82371126ee9
    --- /dev/null
    +++ b/share/man/man4/bwn.4
    @@ -0,0 +1,134 @@
    +.\" Copyright (c) 2009 Christian Brueffer
    +.\" 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 February 15, 2010
    +.Dt BWN 4
    +.Os
    +.Sh NAME
    +.Nm bwn
    +.Nd Broadcom BCM43xx IEEE 802.11b/g wireless network driver
    +.Sh SYNOPSIS
    +To compile this driver into the kernel,
    +place the following lines in your
    +kernel configuration file:
    +.Bd -ragged -offset indent
    +.Cd "device siba_bwn"
    +.Cd "device bwn"
    +.Cd "device wlan"
    +.Cd "device wlan_amrr"
    +.Cd "device firmware"
    +.Ed
    +.Pp
    +Alternatively, to load the driver as a
    +module at boot time, place the following line in
    +.Xr loader.conf 5 :
    +.Bd -literal -offset indent
    +if_bwn_load="YES"
    +.Ed
    +.Sh DESCRIPTION
    +The
    +.Nm
    +driver provides support for Broadcom BCM43xx based
    +PCI/CardBus network adapters.
    +.Pp
    +It supports
    +.Cm station
    +and
    +.Cm monitor
    +mode operation.
    +Only one virtual interface may be configured at any time.
    +For more information on configuring this device, see
    +.Xr ifconfig 8 .
    +.Pp
    +This driver requires firmware to be loaded before it will work.
    +The
    +.Pa ports/net/bwn-firmware-kmod
    +port needs to be installed before
    +.Xr ifconfig 8
    +will work.
    +.Sh HARDWARE
    +The
    +.Nm
    +driver supports Broadcom BCM43xx based wireless devices, including:
    +.Pp
    +.Bl -column -compact "Apple Airport Extreme" "BCM4306" "Mini PCI" "a/b/g" -offset 6n
    +.It Em "Card	Chip	Bus	Standard"
    +.It "Apple Airport Extreme	BCM4306	PCI	b/g"
    +.It "Apple Airport Extreme	BCM4318	PCI	b/g"
    +.It "ASUS WL-138g	BCM4318	PCI	b/g"
    +.It "Buffalo WLI-CB-G54S	BCM4318	CardBus	b/g"
    +.It "Buffalo WLI-PCI-G54S	BCM4306	PCI	b/g"
    +.It "Compaq R4035 onboard	BCM4306	PCI	b/g"
    +.It "Dell Wireless 1470	BCM4318	Mini PCI	b/g"
    +.It "Dell Truemobile 1400	BCM4309	Mini PCI	b/g"
    +.It "HP nx6125	BCM4319	PCI	b/g"
    +.It "Linksys WPC54G Ver 3	BCM4318	CardBus	b/g"
    +.It "Linksys WPC54GS Ver 2	BCM4318	CardBus	b/g"
    +.It "TRENDnet TEW-401PCplus	BCM4306	CardBus	b/g"
    +.It "US Robotics 5411	BCM4318	CardBus	b/g"
    +.El
    +.Sh EXAMPLES
    +Join an existing BSS network (i.e., connect to an access point):
    +.Pp
    +.Bd -literal -offset indent
    +ifconfig wlan create wlandev bwn0 inet 192.168.0.20 \e
    +    netmask 0xffffff00
    +.Ed
    +.Pp
    +Join a specific BSS network with network name
    +.Dq Li my_net :
    +.Pp
    +.Dl "ifconfig wlan create wlandev bwn0 ssid my_net up"
    +.Pp
    +Join a specific BSS network with 64-bit WEP encryption:
    +.Bd -literal -offset indent
    +ifconfig wlan create wlandev bwn0 ssid my_net \e
    +        wepmode on wepkey 0x1234567890 weptxkey 1 up
    +.Ed
    +.Sh SEE ALSO
    +.Xr arp 4 ,
    +.Xr cardbus 4 ,
    +.Xr intro 4 ,
    +.Xr pci 4 ,
    +.Xr wlan 4 ,
    +.Xr wlan_amrr 4 ,
    +.Xr ifconfig 8 ,
    +.Xr wpa_supplicant 8
    +.Sh HISTORY
    +The
    +.Nm
    +driver first appeared in
    +.Fx 8.0 .
    +.Sh AUTHORS
    +.An -nosplit
    +The
    +.Nm
    +driver was written by
    +.An Weongyo Jeong
    +.Aq weongyo@FreeBSD.org .
    +.\".Sh BUGS
    +.\"Some card based on the BCM4306 and BCM4309 chips do not work properly
    +.\"on channel 1, 2 and 3.
    
    From 631680bf1cf2c7a84e4954838985de4e705b657f Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Tue, 20 Apr 2010 22:20:31 +0000
    Subject: [PATCH 2058/2592] MFC r199282: sh: Allow a newline before "in" in a
     for command, as required by POSIX.
    
    ---
     bin/sh/parser.c                       |  4 +++-
     tools/regression/bin/sh/parser/for1.0 | 29 +++++++++++++++++++++++++++
     2 files changed, 32 insertions(+), 1 deletion(-)
     create mode 100644 tools/regression/bin/sh/parser/for1.0
    
    diff --git a/bin/sh/parser.c b/bin/sh/parser.c
    index 73d628eb7e6..cbd66bc0bd1 100644
    --- a/bin/sh/parser.c
    +++ b/bin/sh/parser.c
    @@ -365,7 +365,9 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
     		n1 = (union node *)stalloc(sizeof (struct nfor));
     		n1->type = NFOR;
     		n1->nfor.var = wordtext;
    -		if (readtoken() == TWORD && ! quoteflag && equal(wordtext, "in")) {
    +		while (readtoken() == TNL)
    +			;
    +		if (lasttoken == TWORD && ! quoteflag && equal(wordtext, "in")) {
     			app = ≈
     			while (readtoken() == TWORD) {
     				n2 = (union node *)stalloc(sizeof (struct narg));
    diff --git a/tools/regression/bin/sh/parser/for1.0 b/tools/regression/bin/sh/parser/for1.0
    new file mode 100644
    index 00000000000..f4b38d41414
    --- /dev/null
    +++ b/tools/regression/bin/sh/parser/for1.0
    @@ -0,0 +1,29 @@
    +# $FreeBSD$
    +
    +nl='
    +'
    +list=' a b c'
    +for s1 in "$nl" " "; do
    +	for s2 in "$nl" ";"; do
    +		for s3 in "$nl" " "; do
    +			r=''
    +			eval "for i${s1}in ${list}${s2}do${s3}r=\"\$r \$i\"; done"
    +			[ "$r" = "$list" ] || exit 1
    +		done
    +	done
    +done
    +set -- $list
    +for s2 in "$nl" " " ";"; do # s2=";" is an extension to POSIX
    +	for s3 in "$nl" " "; do
    +		r=''
    +		eval "for i${s2}do${s3}r=\"\$r \$i\"; done"
    +		[ "$r" = "$list" ] || exit 1
    +	done
    +done
    +for s1 in "$nl" " "; do
    +	for s2 in "$nl" ";"; do
    +		for s3 in "$nl" " "; do
    +			eval "for i${s1}in${s2}do${s3}exit 1; done"
    +		done
    +	done
    +done
    
    From 7e140e7e32de5cc8a029899e6ff4e94b2b40cbda Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Tue, 20 Apr 2010 22:32:34 +0000
    Subject: [PATCH 2059/2592] MFC r200943: sh: Remove setting variables from
     dotcmd/exportcmd.
    
    It is already done by evalcommand(), unless special-ness has been removed,
    in which case variable assignments should not persist. (These are currently
    always special builtins, but this may change later: command builtin,
    command substitution.)
    
    This also fixes a memory leak when calling . with variable assignments.
    
    Example:
      valgrind --leak-check=full sh -c 'x=1 . /dev/null; x=2'
    ---
     bin/sh/main.c | 4 ----
     bin/sh/var.c  | 1 -
     2 files changed, 5 deletions(-)
    
    diff --git a/bin/sh/main.c b/bin/sh/main.c
    index 85a6d20ee45..6aa588faec8 100644
    --- a/bin/sh/main.c
    +++ b/bin/sh/main.c
    @@ -315,7 +315,6 @@ find_dot_file(char *basename)
     int
     dotcmd(int argc, char **argv)
     {
    -	struct strlist *sp;
     	char *fullname;
     
     	if (argc < 2)
    @@ -323,9 +322,6 @@ dotcmd(int argc, char **argv)
     
     	exitstatus = 0;
     
    -	for (sp = cmdenviron; sp ; sp = sp->next)
    -		setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
    -
     	fullname = find_dot_file(argv[1]);
     	setinputfile(fullname, 1);
     	commandname = fullname;
    diff --git a/bin/sh/var.c b/bin/sh/var.c
    index 2c1caf14800..62382b21c50 100644
    --- a/bin/sh/var.c
    +++ b/bin/sh/var.c
    @@ -604,7 +604,6 @@ exportcmd(int argc, char **argv)
     
     	if (values && argc != 0)
     		error("-p requires no arguments");
    -	listsetvar(cmdenviron);
     	if (argc != 0) {
     		while ((name = *argv++) != NULL) {
     			if ((p = strchr(name, '=')) != NULL) {
    
    From a9de89ae433221c11cbde45ab9c35cb892737f39 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Tue, 20 Apr 2010 22:47:24 +0000
    Subject: [PATCH 2060/2592] MFC r206387:
    
    Diff reduction against NetBSD and add myself to AUTHORS section of the
    manual page as I wrote the unpack functionality.  No actual executable
    code change verified with md5(1).
    ---
     usr.bin/gzip/gzip.1    | 11 +++++++----
     usr.bin/gzip/gzip.c    | 14 ++++++--------
     usr.bin/gzip/unbzip2.c |  2 +-
     3 files changed, 14 insertions(+), 13 deletions(-)
    
    diff --git a/usr.bin/gzip/gzip.1 b/usr.bin/gzip/gzip.1
    index 20d0250380b..bb1faddbabb 100644
    --- a/usr.bin/gzip/gzip.1
    +++ b/usr.bin/gzip/gzip.1
    @@ -25,7 +25,7 @@
     .\" SUCH DAMAGE.
     .\"
     .\" $FreeBSD$
    -.Dd June 24, 2009
    +.Dd April 7, 2010
     .Dt GZIP 1
     .Os
     .Sh NAME
    @@ -205,14 +205,17 @@ This implementation of
     .Nm
     was ported based on the
     .Nx
    -.Nm
    -20090412, and first appeared in
    +.Nm ,
    +and first appeared in
     .Fx 7.0 .
     .Sh AUTHORS
    +.An -nosplit
     This implementation of
     .Nm
     was written by
    -.An Matthew R. Green Aq mrg@eterna.com.au .
    +.An Matthew R. Green Aq mrg@eterna.com.au
    +with unpack support written by
    +.An Xin LI Aq delphij@FreeBSD.org .
     .Sh BUGS
     According to RFC 1952, the recorded file size is stored in a 32-bit
     integer and therefore it can not represent files that is bigger than
    diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c
    index e9371d2c47c..bb2b73545cc 100644
    --- a/usr.bin/gzip/gzip.c
    +++ b/usr.bin/gzip/gzip.c
    @@ -1,4 +1,4 @@
    -/*	$NetBSD: gzip.c,v 1.94 2009/04/12 10:31:14 lukem Exp $	*/
    +/*	$NetBSD: gzip.c,v 1.97 2009/10/11 09:17:21 mrg Exp $	*/
     
     /*-
      * Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green
    @@ -149,10 +149,9 @@ static suffixes_t suffixes[] = {
     #undef SUFFIX
     };
     #define NUM_SUFFIXES (sizeof suffixes / sizeof suffixes[0])
    -
     #define SUFFIX_MAXLEN	30
     
    -static	const char	gzip_version[] = "FreeBSD gzip 20090621";
    +static	const char	gzip_version[] = "FreeBSD gzip 20100407";
     
     #ifndef SMALL
     static	const char	gzip_copyright[] = \
    @@ -206,7 +205,7 @@ static	char	*infile;		/* name of file coming in */
     
     static	void	maybe_err(const char *fmt, ...) __dead2
         __attribute__((__format__(__printf__, 1, 2)));
    -#ifndef NO_BZIP2_SUPPORT
    +#if !defined(NO_BZIP2_SUPPORT) || !defined(NO_PACK_SUPPORT)
     static	void	maybe_errx(const char *fmt, ...) __dead2
         __attribute__((__format__(__printf__, 1, 2)));
     #endif
    @@ -461,7 +460,7 @@ maybe_err(const char *fmt, ...)
     	exit(2);
     }
     
    -#ifndef NO_BZIP2_SUPPORT
    +#if !defined(NO_BZIP2_SUPPORT) || !defined(NO_PACK_SUPPORT)
     /* ... without an errno. */
     void
     maybe_errx(const char *fmt, ...)
    @@ -1319,6 +1318,7 @@ file_uncompress(char *file, char *outfile, size_t outsize)
     	enum filetype method;
     	int fd, ofd, zfd = -1;
     #ifndef SMALL
    +	ssize_t rv;
     	time_t timestamp = 0;
     	unsigned char name[PATH_MAX + 1];
     #endif
    @@ -1364,7 +1364,6 @@ file_uncompress(char *file, char *outfile, size_t outsize)
     #ifndef SMALL
     	if (method == FT_GZIP && Nflag) {
     		unsigned char ts[4];	/* timestamp */
    -		ssize_t rv;
     
     		rv = pread(fd, ts, sizeof ts, GZIP_TIMESTAMP);
     		if (rv >= 0 && rv < (ssize_t)(sizeof ts))
    @@ -2054,7 +2053,7 @@ static void
     display_license(void)
     {
     
    -	fprintf(stderr, "%s (based on NetBSD gzip 20060927)\n", gzip_version);
    +	fprintf(stderr, "%s (based on NetBSD gzip 20091011)\n", gzip_version);
     	fprintf(stderr, "%s\n", gzip_copyright);
     	exit(0);
     }
    @@ -2100,4 +2099,3 @@ read_retry(int fd, void *buf, size_t sz)
     
     	return sz - left;
     }
    -
    diff --git a/usr.bin/gzip/unbzip2.c b/usr.bin/gzip/unbzip2.c
    index c744e564ef1..a5cd1be1be8 100644
    --- a/usr.bin/gzip/unbzip2.c
    +++ b/usr.bin/gzip/unbzip2.c
    @@ -1,4 +1,4 @@
    -/*	$NetBSD: unbzip2.c,v 1.12 2009/10/11 05:17:20 mrg Exp $	*/
    +/*	$NetBSD: unbzip2.c,v 1.13 2009/12/05 03:23:37 mrg Exp $	*/
     
     /*-
      * Copyright (c) 2006 The NetBSD Foundation, Inc.
    
    From a6cd5bcfbf09411e540b34fd0c315612cb7371e1 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Tue, 20 Apr 2010 22:52:13 +0000
    Subject: [PATCH 2061/2592] MFC r205472:
    
    Enable mmap for minigzip(1).
    ---
     usr.bin/minigzip/Makefile | 8 ++++++--
     1 file changed, 6 insertions(+), 2 deletions(-)
    
    diff --git a/usr.bin/minigzip/Makefile b/usr.bin/minigzip/Makefile
    index 226ba761798..8387cf53a67 100644
    --- a/usr.bin/minigzip/Makefile
    +++ b/usr.bin/minigzip/Makefile
    @@ -1,8 +1,12 @@
     # $FreeBSD$
     
    +SRCDIR=	${.CURDIR}/../../lib/libz
    +.PATH:	${SRCDIR}
    +
     PROG=	minigzip
    -LDADD=	-lz
    +
    +CFLAGS+=-DUSE_MMAP
     DPADD=	${LIBZ}
    -.PATH:	${.CURDIR}/../../lib/libz
    +LDADD=	-lz
     
     .include 
    
    From f08f4ed3740e0558812910493fe7b0e611f83ba0 Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Tue, 20 Apr 2010 22:52:28 +0000
    Subject: [PATCH 2062/2592] MFC r203576,r203677: sh: Don't stat()
     $MAIL/$MAILPATH if not interactive.
    
    These may be NFS mounted, and we should not touch them unless we are going
    to do something useful with the information.
    ---
     bin/sh/main.c                              |  2 ++
     bin/sh/var.c                               |  7 ++++++-
     tools/regression/bin/sh/parameters/mail1.0 | 15 +++++++++++++++
     tools/regression/bin/sh/parameters/mail2.0 | 15 +++++++++++++++
     4 files changed, 38 insertions(+), 1 deletion(-)
     create mode 100644 tools/regression/bin/sh/parameters/mail1.0
     create mode 100644 tools/regression/bin/sh/parameters/mail2.0
    
    diff --git a/bin/sh/main.c b/bin/sh/main.c
    index 6aa588faec8..42756e881ba 100644
    --- a/bin/sh/main.c
    +++ b/bin/sh/main.c
    @@ -157,6 +157,8 @@ main(int argc, char *argv[])
     		out2str("sh: cannot determine working directory\n");
     	if (getpwd() != NULL)
     		setvar ("PWD", getpwd(), VEXPORT);
    +	if (iflag)
    +		chkmail(1);
     	if (argv[0] && argv[0][0] == '-') {
     		state = 1;
     		read_profile("/etc/profile");
    diff --git a/bin/sh/var.c b/bin/sh/var.c
    index 62382b21c50..3188b28f615 100644
    --- a/bin/sh/var.c
    +++ b/bin/sh/var.c
    @@ -335,8 +335,13 @@ setvareq(char *s, int flags)
     			/*
     			 * We could roll this to a function, to handle it as
     			 * a regular variable function callback, but why bother?
    +			 *
    +			 * Note: this assumes iflag is not set to 1 initially.
    +			 * As part of init(), this is called before arguments
    +			 * are looked at.
     			 */
    -			if (vp == &vmpath || (vp == &vmail && ! mpathset()))
    +			if ((vp == &vmpath || (vp == &vmail && ! mpathset())) &&
    +			    iflag == 1)
     				chkmail(1);
     			if ((vp->flags & VEXPORT) && localevar(s)) {
     				change_env(s, 1);
    diff --git a/tools/regression/bin/sh/parameters/mail1.0 b/tools/regression/bin/sh/parameters/mail1.0
    new file mode 100644
    index 00000000000..26308eadbdc
    --- /dev/null
    +++ b/tools/regression/bin/sh/parameters/mail1.0
    @@ -0,0 +1,15 @@
    +# $FreeBSD$
    +# Test that a non-interactive shell does not access $MAIL.
    +
    +goodfile=/var/empty/sh-test-goodfile
    +mailfile=/var/empty/sh-test-mailfile
    +T=$(mktemp sh-test.XXXXXX) || exit
    +MAIL=$mailfile ktrace -i -f "$T" sh -c "[ -s $goodfile ]" 2>/dev/null
    +if ! grep -q $goodfile "$T"; then
    +	# ktrace problem
    +	rc=0
    +elif ! grep -q $mailfile "$T"; then
    +	rc=0
    +fi
    +rm "$T"
    +exit ${rc:-3}
    diff --git a/tools/regression/bin/sh/parameters/mail2.0 b/tools/regression/bin/sh/parameters/mail2.0
    new file mode 100644
    index 00000000000..e3b7da34132
    --- /dev/null
    +++ b/tools/regression/bin/sh/parameters/mail2.0
    @@ -0,0 +1,15 @@
    +# $FreeBSD$
    +# Test that an interactive shell accesses $MAIL.
    +
    +goodfile=/var/empty/sh-test-goodfile
    +mailfile=/var/empty/sh-test-mailfile
    +T=$(mktemp sh-test.XXXXXX) || exit
    +ENV=$goodfile MAIL=$mailfile ktrace -i -f "$T" sh +m -i /dev/null 2>&1
    +if ! grep -q $goodfile "$T"; then
    +	# ktrace problem
    +	rc=0
    +elif grep -q $mailfile "$T"; then
    +	rc=0
    +fi
    +rm "$T"
    +exit ${rc:-3}
    
    From 499ba4648dde4b3b3879a95c70695ec6ae36742b Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 22:55:07 +0000
    Subject: [PATCH 2063/2592] MFC r204328:   Add bwn(4) driver.
    
    ---
     sys/boot/forth/loader.conf    | 1 +
     usr.sbin/sysinstall/devices.c | 1 +
     2 files changed, 2 insertions(+)
    
    diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf
    index 523a2f7ce3e..422d5cb436c 100644
    --- a/sys/boot/forth/loader.conf
    +++ b/sys/boot/forth/loader.conf
    @@ -224,6 +224,7 @@ if_axe_load="NO"		# ASIX Electronics AX88172 USB Ethernet
     if_bce_load="NO"		# Broadcom NetXtreme II Gigabit Ethernet
     if_bfe_load="NO"		# Broadcom BCM4401
     if_bge_load="NO"		# Broadcom BCM570x PCI Gigabit Ethernet
    +if_bwn_load="NO"		# Broadcom BCM43xx IEEE 802.11 wireless NICs
     if_cas_load="NO"		# Sun Cassini/Cassini+ and NS DP83065 Saturn
     if_cm_load="NO"			# SMC (90c26, 90c56, 90c66)
     if_cs_load="NO"			# Crystal Semiconductor CS8920
    diff --git a/usr.sbin/sysinstall/devices.c b/usr.sbin/sysinstall/devices.c
    index b95fdc595a5..a2b7939f048 100644
    --- a/usr.sbin/sysinstall/devices.c
    +++ b/usr.sbin/sysinstall/devices.c
    @@ -105,6 +105,7 @@ static struct _devname {
         NETWORK("bfe",	"Broadcom BCM440x PCI Ethernet card"),
         NETWORK("bge",	"Broadcom BCM570x PCI Gigabit Ethernet card"),
         NETWORK("bm",	"Apple BMAC Built-in Ethernet"),
    +    NETWORK("bwn",	"Broadcom BCM43xx IEEE 802.11 wireless adapter"),
         NETWORK("cas",	"Sun Cassini/Cassini+ or NS DP83065 Saturn Ethernet"),
         NETWORK("cue",	"CATC USB Ethernet adapter"),
         NETWORK("cxgb",	"Chelsio T3 10Gb Ethernet card"),
    
    From 2c221f6f88b69a7e7b631a029905065e5bdeb34a Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Tue, 20 Apr 2010 22:57:05 +0000
    Subject: [PATCH 2064/2592] MFC assembler version of match functions for amd64
     and i386(*).
    
    This gives approximately 15% improvement on compression case.
    
    (*) i386 assembler version is enabled ONLY when MACHINE_CPU have
    'i686' which is not default on FreeBSD/i386.  One can specify
    for instance CPUTYPE=pentium4 in /etc/make.conf to get this
    feature.
    ---
     lib/libz/Makefile                      |  12 +
     lib/libz/contrib/README.contrib        |  77 ++++
     lib/libz/contrib/asm686/README.686     |  51 +++
     lib/libz/contrib/asm686/match.S        | 343 +++++++++++++++
     lib/libz/contrib/gcc_gvmat64/gvmat64.S | 574 +++++++++++++++++++++++++
     5 files changed, 1057 insertions(+)
     create mode 100644 lib/libz/contrib/README.contrib
     create mode 100644 lib/libz/contrib/asm686/README.686
     create mode 100644 lib/libz/contrib/asm686/match.S
     create mode 100644 lib/libz/contrib/gcc_gvmat64/gvmat64.S
    
    diff --git a/lib/libz/Makefile b/lib/libz/Makefile
    index 63383b4d97b..1390d081dd0 100644
    --- a/lib/libz/Makefile
    +++ b/lib/libz/Makefile
    @@ -19,6 +19,18 @@ SRCS = adler32.c compress.c crc32.c gzio.c uncompr.c deflate.c trees.c \
            zutil.c inflate.c inftrees.c inffast.c zopen.c infback.c
     INCS=		zconf.h zlib.h
     
    +.if ${MACHINE_ARCH} == "i386" && ${MACHINE_CPU:M*i686*}
    +.PATH:		${.CURDIR}/contrib/asm686
    +SRCS+=		match.S
    +CFLAGS+=	-DASMV -DNO_UNDERLINE
    +.endif
    +
    +.if ${MACHINE_ARCH} == "amd64"
    +.PATH:		${.CURDIR}/contrib/gcc_gvmat64
    +SRCS+=		gvmat64.S
    +CFLAGS+=	-DASMV -DNO_UNDERLINE
    +.endif
    +
     minigzip:	all minigzip.o
     	$(CC) -o minigzip minigzip.o -L. -lz
     
    diff --git a/lib/libz/contrib/README.contrib b/lib/libz/contrib/README.contrib
    new file mode 100644
    index 00000000000..dd2285d960a
    --- /dev/null
    +++ b/lib/libz/contrib/README.contrib
    @@ -0,0 +1,77 @@
    +All files under this contrib directory are UNSUPPORTED. There were
    +provided by users of zlib and were not tested by the authors of zlib.
    +Use at your own risk. Please contact the authors of the contributions
    +for help about these, not the zlib authors. Thanks.
    +
    +
    +ada/        by Dmitriy Anisimkov 
    +        Support for Ada
    +        See http://zlib-ada.sourceforge.net/
    +
    +amd64/      by Mikhail Teterin 
    +        asm code for AMD64
    +        See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393
    +
    +asm686/     by Brian Raiter 
    +        asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
    +        See http://www.muppetlabs.com/~breadbox/software/assembly.html
    +
    +blast/      by Mark Adler 
    +        Decompressor for output of PKWare Data Compression Library (DCL)
    +
    +delphi/     by Cosmin Truta 
    +        Support for Delphi and C++ Builder
    +
    +dotzlib/    by Henrik Ravn 
    +        Support for Microsoft .Net and Visual C++ .Net
    +
    +gcc_gvmat64/by Gilles Vollant 
    +        GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64
    +        assembler to replace longest_match() and inflate_fast()
    +
    +infback9/   by Mark Adler 
    +        Unsupported diffs to infback to decode the deflate64 format
    +
    +inflate86/  by Chris Anderson 
    +        Tuned x86 gcc asm code to replace inflate_fast()
    +
    +iostream/   by Kevin Ruland 
    +        A C++ I/O streams interface to the zlib gz* functions
    +
    +iostream2/  by Tyge Løvset 
    +        Another C++ I/O streams interface
    +
    +iostream3/  by Ludwig Schwardt 
    +            and Kevin Ruland 
    +        Yet another C++ I/O streams interface
    +
    +masmx64/    by Gilles Vollant 
    +        x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to
    +        replace longest_match() and inflate_fast(),  also masm x86
    +        64-bits translation of Chris Anderson inflate_fast()
    +
    +masmx86/    by Gilles Vollant 
    +        x86 asm code to replace longest_match() and inflate_fast(),
    +        for Visual C++ and MASM (32 bits).
    +        Based on Brian Raiter (asm686) and Chris Anderson (inflate86)
    +
    +minizip/    by Gilles Vollant 
    +        Mini zip and unzip based on zlib
    +        Includes Zip64 support by Mathias Svensson 
    +        See http://www.winimage.com/zLibDll/unzip.html
    +
    +pascal/     by Bob Dellaca  et al.
    +        Support for Pascal
    +
    +puff/       by Mark Adler 
    +        Small, low memory usage inflate.  Also serves to provide an
    +        unambiguous description of the deflate format.
    +
    +testzlib/   by Gilles Vollant 
    +        Example of the use of zlib
    +
    +untgz/      by Pedro A. Aranda Gutierrez 
    +        A very simple tar.gz file extractor using zlib
    +
    +vstudio/    by Gilles Vollant 
    +        Building a minizip-enhanced zlib with Microsoft Visual Studio
    diff --git a/lib/libz/contrib/asm686/README.686 b/lib/libz/contrib/asm686/README.686
    new file mode 100644
    index 00000000000..a0bf3bea4af
    --- /dev/null
    +++ b/lib/libz/contrib/asm686/README.686
    @@ -0,0 +1,51 @@
    +This is a patched version of zlib, modified to use
    +Pentium-Pro-optimized assembly code in the deflation algorithm. The
    +files changed/added by this patch are:
    +
    +README.686
    +match.S
    +
    +The speedup that this patch provides varies, depending on whether the
    +compiler used to build the original version of zlib falls afoul of the
    +PPro's speed traps. My own tests show a speedup of around 10-20% at
    +the default compression level, and 20-30% using -9, against a version
    +compiled using gcc 2.7.2.3. Your mileage may vary.
    +
    +Note that this code has been tailored for the PPro/PII in particular,
    +and will not perform particuarly well on a Pentium.
    +
    +If you are using an assembler other than GNU as, you will have to
    +translate match.S to use your assembler's syntax. (Have fun.)
    +
    +Brian Raiter
    +breadbox@muppetlabs.com
    +April, 1998
    +
    +
    +Added for zlib 1.1.3:
    +
    +The patches come from
    +http://www.muppetlabs.com/~breadbox/software/assembly.html
    +
    +To compile zlib with this asm file, copy match.S to the zlib directory
    +then do:
    +
    +CFLAGS="-O3 -DASMV" ./configure
    +make OBJA=match.o
    +
    +
    +Update:
    +
    +I've been ignoring these assembly routines for years, believing that
    +gcc's generated code had caught up with it sometime around gcc 2.95
    +and the major rearchitecting of the Pentium 4. However, I recently
    +learned that, despite what I believed, this code still has some life
    +in it. On the Pentium 4 and AMD64 chips, it continues to run about 8%
    +faster than the code produced by gcc 4.1.
    +
    +In acknowledgement of its continuing usefulness, I've altered the
    +license to match that of the rest of zlib. Share and Enjoy!
    +
    +Brian Raiter
    +breadbox@muppetlabs.com
    +April, 2007
    diff --git a/lib/libz/contrib/asm686/match.S b/lib/libz/contrib/asm686/match.S
    new file mode 100644
    index 00000000000..06817e1dd08
    --- /dev/null
    +++ b/lib/libz/contrib/asm686/match.S
    @@ -0,0 +1,343 @@
    +/* match.S -- x86 assembly version of the zlib longest_match() function.
    + * Optimized for the Intel 686 chips (PPro and later).
    + *
    + * Copyright (C) 1998, 2007 Brian Raiter 
    + *
    + * This software is provided 'as-is', without any express or implied
    + * warranty.  In no event will the author be held liable for any damages
    + * arising from the use of this software.
    + *
    + * Permission is granted to anyone to use this software for any purpose,
    + * including commercial applications, and to alter it and redistribute it
    + * freely, subject to the following restrictions:
    + *
    + * 1. The origin of this software must not be misrepresented; you must not
    + *    claim that you wrote the original software. If you use this software
    + *    in a product, an acknowledgment in the product documentation would be
    + *    appreciated but is not required.
    + * 2. Altered source versions must be plainly marked as such, and must not be
    + *    misrepresented as being the original software.
    + * 3. This notice may not be removed or altered from any source distribution.
    + */
    +
    +#ifndef NO_UNDERLINE
    +#define	match_init	_match_init
    +#define	longest_match	_longest_match
    +#endif
    +
    +#define	MAX_MATCH	(258)
    +#define	MIN_MATCH	(3)
    +#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)
    +#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)
    +
    +/* stack frame offsets */
    +
    +#define	chainlenwmask		0	/* high word: current chain len	*/
    +					/* low word: s->wmask		*/
    +#define	window			4	/* local copy of s->window	*/
    +#define	windowbestlen		8	/* s->window + bestlen		*/
    +#define	scanstart		16	/* first two bytes of string	*/
    +#define	scanend			12	/* last two bytes of string	*/
    +#define	scanalign		20	/* dword-misalignment of string	*/
    +#define	nicematch		24	/* a good enough match size	*/
    +#define	bestlen			28	/* size of best match so far	*/
    +#define	scan			32	/* ptr to string wanting match	*/
    +
    +#define	LocalVarsSize		(36)
    +/*	saved ebx		36 */
    +/*	saved edi		40 */
    +/*	saved esi		44 */
    +/*	saved ebp		48 */
    +/*	return address		52 */
    +#define	deflatestate		56	/* the function arguments	*/
    +#define	curmatch		60
    +
    +/* All the +zlib1222add offsets are due to the addition of fields
    + *  in zlib in the deflate_state structure since the asm code was first written
    + * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
    + * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
    + * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
    + */
    +
    +#define zlib1222add		(8)
    +
    +#define	dsWSize			(36+zlib1222add)
    +#define	dsWMask			(44+zlib1222add)
    +#define	dsWindow		(48+zlib1222add)
    +#define	dsPrev			(56+zlib1222add)
    +#define	dsMatchLen		(88+zlib1222add)
    +#define	dsPrevMatch		(92+zlib1222add)
    +#define	dsStrStart		(100+zlib1222add)
    +#define	dsMatchStart		(104+zlib1222add)
    +#define	dsLookahead		(108+zlib1222add)
    +#define	dsPrevLen		(112+zlib1222add)
    +#define	dsMaxChainLen		(116+zlib1222add)
    +#define	dsGoodMatch		(132+zlib1222add)
    +#define	dsNiceMatch		(136+zlib1222add)
    +
    +
    +.file "match.S"
    +
    +.globl	match_init, longest_match
    +
    +.text
    +
    +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
    +
    +longest_match:
    +
    +/* Save registers that the compiler may be using, and adjust %esp to	*/
    +/* make room for our stack frame.					*/
    +
    +		pushl	%ebp
    +		pushl	%edi
    +		pushl	%esi
    +		pushl	%ebx
    +		subl	$LocalVarsSize, %esp
    +
    +/* Retrieve the function arguments. %ecx will hold cur_match		*/
    +/* throughout the entire function. %edx will hold the pointer to the	*/
    +/* deflate_state structure during the function's setup (before		*/
    +/* entering the main loop).						*/
    +
    +		movl	deflatestate(%esp), %edx
    +		movl	curmatch(%esp), %ecx
    +
    +/* uInt wmask = s->w_mask;						*/
    +/* unsigned chain_length = s->max_chain_length;				*/
    +/* if (s->prev_length >= s->good_match) {				*/
    +/*     chain_length >>= 2;						*/
    +/* }									*/
    +
    +		movl	dsPrevLen(%edx), %eax
    +		movl	dsGoodMatch(%edx), %ebx
    +		cmpl	%ebx, %eax
    +		movl	dsWMask(%edx), %eax
    +		movl	dsMaxChainLen(%edx), %ebx
    +		jl	LastMatchGood
    +		shrl	$2, %ebx
    +LastMatchGood:
    +
    +/* chainlen is decremented once beforehand so that the function can	*/
    +/* use the sign flag instead of the zero flag for the exit test.	*/
    +/* It is then shifted into the high word, to make room for the wmask	*/
    +/* value, which it will always accompany.				*/
    +
    +		decl	%ebx
    +		shll	$16, %ebx
    +		orl	%eax, %ebx
    +		movl	%ebx, chainlenwmask(%esp)
    +
    +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/
    +
    +		movl	dsNiceMatch(%edx), %eax
    +		movl	dsLookahead(%edx), %ebx
    +		cmpl	%eax, %ebx
    +		jl	LookaheadLess
    +		movl	%eax, %ebx
    +LookaheadLess:	movl	%ebx, nicematch(%esp)
    +
    +/* register Bytef *scan = s->window + s->strstart;			*/
    +
    +		movl	dsWindow(%edx), %esi
    +		movl	%esi, window(%esp)
    +		movl	dsStrStart(%edx), %ebp
    +		lea	(%esi,%ebp), %edi
    +		movl	%edi, scan(%esp)
    +
    +/* Determine how many bytes the scan ptr is off from being		*/
    +/* dword-aligned.							*/
    +
    +		movl	%edi, %eax
    +		negl	%eax
    +		andl	$3, %eax
    +		movl	%eax, scanalign(%esp)
    +
    +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/
    +/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/
    +
    +		movl	dsWSize(%edx), %eax
    +		subl	$MIN_LOOKAHEAD, %eax
    +		subl	%eax, %ebp
    +		jg	LimitPositive
    +		xorl	%ebp, %ebp
    +LimitPositive:
    +
    +/* int best_len = s->prev_length;					*/
    +
    +		movl	dsPrevLen(%edx), %eax
    +		movl	%eax, bestlen(%esp)
    +
    +/* Store the sum of s->window + best_len in %esi locally, and in %esi.	*/
    +
    +		addl	%eax, %esi
    +		movl	%esi, windowbestlen(%esp)
    +
    +/* register ush scan_start = *(ushf*)scan;				*/
    +/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/
    +/* Posf *prev = s->prev;						*/
    +
    +		movzwl	(%edi), %ebx
    +		movl	%ebx, scanstart(%esp)
    +		movzwl	-1(%edi,%eax), %ebx
    +		movl	%ebx, scanend(%esp)
    +		movl	dsPrev(%edx), %edi
    +
    +/* Jump into the main loop.						*/
    +
    +		movl	chainlenwmask(%esp), %edx
    +		jmp	LoopEntry
    +
    +.balign 16
    +
    +/* do {
    + *     match = s->window + cur_match;
    + *     if (*(ushf*)(match+best_len-1) != scan_end ||
    + *         *(ushf*)match != scan_start) continue;
    + *     [...]
    + * } while ((cur_match = prev[cur_match & wmask]) > limit
    + *          && --chain_length != 0);
    + *
    + * Here is the inner loop of the function. The function will spend the
    + * majority of its time in this loop, and majority of that time will
    + * be spent in the first ten instructions.
    + *
    + * Within this loop:
    + * %ebx = scanend
    + * %ecx = curmatch
    + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
    + * %esi = windowbestlen - i.e., (window + bestlen)
    + * %edi = prev
    + * %ebp = limit
    + */
    +LookupLoop:
    +		andl	%edx, %ecx
    +		movzwl	(%edi,%ecx,2), %ecx
    +		cmpl	%ebp, %ecx
    +		jbe	LeaveNow
    +		subl	$0x00010000, %edx
    +		js	LeaveNow
    +LoopEntry:	movzwl	-1(%esi,%ecx), %eax
    +		cmpl	%ebx, %eax
    +		jnz	LookupLoop
    +		movl	window(%esp), %eax
    +		movzwl	(%eax,%ecx), %eax
    +		cmpl	scanstart(%esp), %eax
    +		jnz	LookupLoop
    +
    +/* Store the current value of chainlen.					*/
    +
    +		movl	%edx, chainlenwmask(%esp)
    +
    +/* Point %edi to the string under scrutiny, and %esi to the string we	*/
    +/* are hoping to match it up with. In actuality, %esi and %edi are	*/
    +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/
    +/* initialized to -(MAX_MATCH_8 - scanalign).				*/
    +
    +		movl	window(%esp), %esi
    +		movl	scan(%esp), %edi
    +		addl	%ecx, %esi
    +		movl	scanalign(%esp), %eax
    +		movl	$(-MAX_MATCH_8), %edx
    +		lea	MAX_MATCH_8(%edi,%eax), %edi
    +		lea	MAX_MATCH_8(%esi,%eax), %esi
    +
    +/* Test the strings for equality, 8 bytes at a time. At the end,
    + * adjust %edx so that it is offset to the exact byte that mismatched.
    + *
    + * We already know at this point that the first three bytes of the
    + * strings match each other, and they can be safely passed over before
    + * starting the compare loop. So what this code does is skip over 0-3
    + * bytes, as much as necessary in order to dword-align the %edi
    + * pointer. (%esi will still be misaligned three times out of four.)
    + *
    + * It should be confessed that this loop usually does not represent
    + * much of the total running time. Replacing it with a more
    + * straightforward "rep cmpsb" would not drastically degrade
    + * performance.
    + */
    +LoopCmps:
    +		movl	(%esi,%edx), %eax
    +		xorl	(%edi,%edx), %eax
    +		jnz	LeaveLoopCmps
    +		movl	4(%esi,%edx), %eax
    +		xorl	4(%edi,%edx), %eax
    +		jnz	LeaveLoopCmps4
    +		addl	$8, %edx
    +		jnz	LoopCmps
    +		jmp	LenMaximum
    +LeaveLoopCmps4:	addl	$4, %edx
    +LeaveLoopCmps:	testl	$0x0000FFFF, %eax
    +		jnz	LenLower
    +		addl	$2, %edx
    +		shrl	$16, %eax
    +LenLower:	subb	$1, %al
    +		adcl	$0, %edx
    +
    +/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/
    +/* then automatically accept it as the best possible match and leave.	*/
    +
    +		lea	(%edi,%edx), %eax
    +		movl	scan(%esp), %edi
    +		subl	%edi, %eax
    +		cmpl	$MAX_MATCH, %eax
    +		jge	LenMaximum
    +
    +/* If the length of the match is not longer than the best match we	*/
    +/* have so far, then forget it and return to the lookup loop.		*/
    +
    +		movl	deflatestate(%esp), %edx
    +		movl	bestlen(%esp), %ebx
    +		cmpl	%ebx, %eax
    +		jg	LongerMatch
    +		movl	windowbestlen(%esp), %esi
    +		movl	dsPrev(%edx), %edi
    +		movl	scanend(%esp), %ebx
    +		movl	chainlenwmask(%esp), %edx
    +		jmp	LookupLoop
    +
    +/*         s->match_start = cur_match;					*/
    +/*         best_len = len;						*/
    +/*         if (len >= nice_match) break;				*/
    +/*         scan_end = *(ushf*)(scan+best_len-1);			*/
    +
    +LongerMatch:	movl	nicematch(%esp), %ebx
    +		movl	%eax, bestlen(%esp)
    +		movl	%ecx, dsMatchStart(%edx)
    +		cmpl	%ebx, %eax
    +		jge	LeaveNow
    +		movl	window(%esp), %esi
    +		addl	%eax, %esi
    +		movl	%esi, windowbestlen(%esp)
    +		movzwl	-1(%edi,%eax), %ebx
    +		movl	dsPrev(%edx), %edi
    +		movl	%ebx, scanend(%esp)
    +		movl	chainlenwmask(%esp), %edx
    +		jmp	LookupLoop
    +
    +/* Accept the current string, with the maximum possible length.		*/
    +
    +LenMaximum:	movl	deflatestate(%esp), %edx
    +		movl	$MAX_MATCH, bestlen(%esp)
    +		movl	%ecx, dsMatchStart(%edx)
    +
    +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/
    +/* return s->lookahead;							*/
    +
    +LeaveNow:
    +		movl	deflatestate(%esp), %edx
    +		movl	bestlen(%esp), %ebx
    +		movl	dsLookahead(%edx), %eax
    +		cmpl	%eax, %ebx
    +		jg	LookaheadRet
    +		movl	%ebx, %eax
    +LookaheadRet:
    +
    +/* Restore the stack and return from whence we came.			*/
    +
    +		addl	$LocalVarsSize, %esp
    +		popl	%ebx
    +		popl	%esi
    +		popl	%edi
    +		popl	%ebp
    +match_init:	ret
    diff --git a/lib/libz/contrib/gcc_gvmat64/gvmat64.S b/lib/libz/contrib/gcc_gvmat64/gvmat64.S
    new file mode 100644
    index 00000000000..23309fa286e
    --- /dev/null
    +++ b/lib/libz/contrib/gcc_gvmat64/gvmat64.S
    @@ -0,0 +1,574 @@
    +/*
    +;uInt longest_match_x64(
    +;    deflate_state *s,
    +;    IPos cur_match);                             // current match 
    +
    +; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64
    +;  (AMD64 on Athlon 64, Opteron, Phenom
    +;     and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)
    +; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode)
    +; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
    +;
    +; File written by Gilles Vollant, by converting to assembly the longest_match
    +;  from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
    +;  and by taking inspiration on asm686 with masm, optimised assembly code
    +;        from Brian Raiter, written 1998
    +;
    +;  This software is provided 'as-is', without any express or implied
    +;  warranty.  In no event will the authors be held liable for any damages
    +;  arising from the use of this software.
    +;
    +;  Permission is granted to anyone to use this software for any purpose,
    +;  including commercial applications, and to alter it and redistribute it
    +;  freely, subject to the following restrictions:
    +;
    +;  1. The origin of this software must not be misrepresented; you must not
    +;     claim that you wrote the original software. If you use this software
    +;     in a product, an acknowledgment in the product documentation would be
    +;     appreciated but is not required.
    +;  2. Altered source versions must be plainly marked as such, and must not be
    +;     misrepresented as being the original software
    +;  3. This notice may not be removed or altered from any source distribution.
    +;
    +;         http://www.zlib.net
    +;         http://www.winimage.com/zLibDll
    +;         http://www.muppetlabs.com/~breadbox/software/assembly.html
    +;
    +; to compile this file for zLib, I use option:
    +;   gcc -c -arch x86_64 gvmat64.S
    +
    +
    +;uInt longest_match(s, cur_match)
    +;    deflate_state *s;
    +;    IPos cur_match;                             // current match /
    +;
    +; with XCode for Mac, I had strange error with some jump on intel syntax
    +; this is why BEFORE_JMP and AFTER_JMP are used
    + */
    +
    +
    +#define BEFORE_JMP .att_syntax
    +#define AFTER_JMP .intel_syntax noprefix
    +
    +#ifndef NO_UNDERLINE
    +#	define	match_init	_match_init
    +#	define	longest_match	_longest_match
    +#endif
    +
    +.intel_syntax noprefix
    +
    +.globl	match_init, longest_match
    +.text
    +longest_match:
    +
    +
    +
    +#define LocalVarsSize 96
    +/*
    +; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
    +; free register :  r14,r15
    +; register can be saved : rsp
    +*/
    +
    +#define chainlenwmask     (rsp + 8 - LocalVarsSize)
    +#define nicematch         (rsp + 16 - LocalVarsSize)
    +
    +#define save_rdi        (rsp + 24 - LocalVarsSize)
    +#define save_rsi        (rsp + 32 - LocalVarsSize)
    +#define save_rbx        (rsp + 40 - LocalVarsSize)
    +#define save_rbp        (rsp + 48 - LocalVarsSize)
    +#define save_r12        (rsp + 56 - LocalVarsSize)
    +#define save_r13        (rsp + 64 - LocalVarsSize)
    +#define save_r14        (rsp + 72 - LocalVarsSize)
    +#define save_r15        (rsp + 80 - LocalVarsSize)
    +
    +
    +/*
    +;  all the +4 offsets are due to the addition of pending_buf_size (in zlib
    +;  in the deflate_state structure since the asm code was first written
    +;  (if you compile with zlib 1.0.4 or older, remove the +4).
    +;  Note : these value are good with a 8 bytes boundary pack structure
    +*/
    +
    +#define    MAX_MATCH              258
    +#define    MIN_MATCH              3
    +#define    MIN_LOOKAHEAD          (MAX_MATCH+MIN_MATCH+1)
    +
    +/*
    +;;; Offsets for fields in the deflate_state structure. These numbers
    +;;; are calculated from the definition of deflate_state, with the
    +;;; assumption that the compiler will dword-align the fields. (Thus,
    +;;; changing the definition of deflate_state could easily cause this
    +;;; program to crash horribly, without so much as a warning at
    +;;; compile time. Sigh.)
    +
    +;  all the +zlib1222add offsets are due to the addition of fields
    +;  in zlib in the deflate_state structure since the asm code was first written
    +;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
    +;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
    +;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
    +*/
    +
    +
    +
    +/* you can check the structure offset by running
    +
    +#include 
    +#include 
    +#include "deflate.h"
    +
    +void print_depl()
    +{
    +deflate_state ds;
    +deflate_state *s=&ds;
    +printf("size pointer=%u\n",(int)sizeof(void*));
    +
    +printf("#define dsWSize         %u\n",(int)(((char*)&(s->w_size))-((char*)s)));
    +printf("#define dsWMask         %u\n",(int)(((char*)&(s->w_mask))-((char*)s)));
    +printf("#define dsWindow        %u\n",(int)(((char*)&(s->window))-((char*)s)));
    +printf("#define dsPrev          %u\n",(int)(((char*)&(s->prev))-((char*)s)));
    +printf("#define dsMatchLen      %u\n",(int)(((char*)&(s->match_length))-((char*)s)));
    +printf("#define dsPrevMatch     %u\n",(int)(((char*)&(s->prev_match))-((char*)s)));
    +printf("#define dsStrStart      %u\n",(int)(((char*)&(s->strstart))-((char*)s)));
    +printf("#define dsMatchStart    %u\n",(int)(((char*)&(s->match_start))-((char*)s)));
    +printf("#define dsLookahead     %u\n",(int)(((char*)&(s->lookahead))-((char*)s)));
    +printf("#define dsPrevLen       %u\n",(int)(((char*)&(s->prev_length))-((char*)s)));
    +printf("#define dsMaxChainLen   %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));
    +printf("#define dsGoodMatch     %u\n",(int)(((char*)&(s->good_match))-((char*)s)));
    +printf("#define dsNiceMatch     %u\n",(int)(((char*)&(s->nice_match))-((char*)s)));
    +}
    +*/
    +
    +#define dsWSize          68
    +#define dsWMask          76
    +#define dsWindow         80
    +#define dsPrev           96
    +#define dsMatchLen       144
    +#define dsPrevMatch      148
    +#define dsStrStart       156
    +#define dsMatchStart     160
    +#define dsLookahead      164
    +#define dsPrevLen        168
    +#define dsMaxChainLen    172
    +#define dsGoodMatch      188
    +#define dsNiceMatch      192
    +
    +#define window_size      [ rcx + dsWSize]
    +#define WMask            [ rcx + dsWMask]
    +#define window_ad        [ rcx + dsWindow]
    +#define prev_ad          [ rcx + dsPrev]
    +#define strstart         [ rcx + dsStrStart]
    +#define match_start      [ rcx + dsMatchStart]
    +#define Lookahead        [ rcx + dsLookahead] //; 0ffffffffh on infozip
    +#define prev_length      [ rcx + dsPrevLen]
    +#define max_chain_length [ rcx + dsMaxChainLen]
    +#define good_match       [ rcx + dsGoodMatch]
    +#define nice_match       [ rcx + dsNiceMatch]
    +
    +/*
    +; windows:
    +; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match)
    +
    +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
    +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
    +;
    +; All registers must be preserved across the call, except for
    +;   rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
    +
    +;
    +; gcc on macosx-linux:
    +; see http://www.x86-64.org/documentation/abi-0.99.pdf
    +; param 1 in rdi, param 2 in rsi
    +; rbx, rsp, rbp, r12 to r15 must be preserved
    +
    +;;; Save registers that the compiler may be using, and adjust esp to
    +;;; make room for our stack frame.
    +
    +
    +;;; Retrieve the function arguments. r8d will hold cur_match
    +;;; throughout the entire function. edx will hold the pointer to the
    +;;; deflate_state structure during the function's setup (before
    +;;; entering the main loop.
    +
    +; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
    +; mac: param 1 in rdi, param 2 rsi
    +; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
    +*/
    +        mov [save_rbx],rbx
    +        mov [save_rbp],rbp
    +
    +
    +        mov rcx,rdi
    +
    +        mov r8d,esi
    +
    +
    +        mov [save_r12],r12
    +        mov [save_r13],r13
    +        mov [save_r14],r14
    +        mov [save_r15],r15
    +
    +
    +//;;; uInt wmask = s->w_mask;
    +//;;; unsigned chain_length = s->max_chain_length;
    +//;;; if (s->prev_length >= s->good_match) {
    +//;;;     chain_length >>= 2;
    +//;;; }
    +
    +
    +        mov edi, prev_length
    +        mov esi, good_match
    +        mov eax, WMask
    +        mov ebx, max_chain_length
    +        cmp edi, esi
    +        jl  LastMatchGood
    +        shr ebx, 2
    +LastMatchGood:
    +
    +//;;; chainlen is decremented once beforehand so that the function can
    +//;;; use the sign flag instead of the zero flag for the exit test.
    +//;;; It is then shifted into the high word, to make room for the wmask
    +//;;; value, which it will always accompany.
    +
    +        dec ebx
    +        shl ebx, 16
    +        or  ebx, eax
    +
    +//;;; on zlib only
    +//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
    +
    +
    +
    +        mov eax, nice_match
    +        mov [chainlenwmask], ebx
    +        mov r10d, Lookahead
    +        cmp r10d, eax
    +        cmovnl r10d, eax
    +        mov [nicematch],r10d
    +
    +
    +
    +//;;; register Bytef *scan = s->window + s->strstart;
    +        mov r10, window_ad
    +        mov ebp, strstart
    +        lea r13, [r10 + rbp]
    +
    +//;;; Determine how many bytes the scan ptr is off from being
    +//;;; dword-aligned.
    +
    +         mov r9,r13
    +         neg r13
    +         and r13,3
    +
    +//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
    +//;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;
    +
    +
    +        mov eax, window_size
    +        sub eax, MIN_LOOKAHEAD
    +
    +
    +        xor edi,edi
    +        sub ebp, eax
    +
    +        mov r11d, prev_length
    +
    +        cmovng ebp,edi
    +
    +//;;; int best_len = s->prev_length;
    +
    +
    +//;;; Store the sum of s->window + best_len in esi locally, and in esi.
    +
    +       lea  rsi,[r10+r11]
    +
    +//;;; register ush scan_start = *(ushf*)scan;
    +//;;; register ush scan_end   = *(ushf*)(scan+best_len-1);
    +//;;; Posf *prev = s->prev;
    +
    +        movzx r12d,word ptr [r9]
    +        movzx ebx, word ptr [r9 + r11 - 1]
    +
    +        mov rdi, prev_ad
    +
    +//;;; Jump into the main loop.
    +
    +        mov edx, [chainlenwmask]
    +
    +        cmp bx,word ptr [rsi + r8 - 1]
    +        jz  LookupLoopIsZero
    +				
    +						
    +						
    +LookupLoop1:
    +        and r8d, edx
    +
    +        movzx   r8d, word ptr [rdi + r8*2]
    +        cmp r8d, ebp
    +        jbe LeaveNow
    +		
    +		
    +		
    +        sub edx, 0x00010000
    +		BEFORE_JMP
    +        js  LeaveNow
    +		AFTER_JMP
    +
    +LoopEntry1:
    +        cmp bx,word ptr [rsi + r8 - 1]
    +		BEFORE_JMP
    +        jz  LookupLoopIsZero
    +		AFTER_JMP
    +
    +LookupLoop2:
    +        and r8d, edx
    +
    +        movzx   r8d, word ptr [rdi + r8*2]
    +        cmp r8d, ebp
    +		BEFORE_JMP
    +        jbe LeaveNow
    +		AFTER_JMP
    +        sub edx, 0x00010000
    +		BEFORE_JMP
    +        js  LeaveNow
    +		AFTER_JMP
    +
    +LoopEntry2:
    +        cmp bx,word ptr [rsi + r8 - 1]
    +		BEFORE_JMP
    +        jz  LookupLoopIsZero
    +		AFTER_JMP
    +
    +LookupLoop4:
    +        and r8d, edx
    +
    +        movzx   r8d, word ptr [rdi + r8*2]
    +        cmp r8d, ebp
    +		BEFORE_JMP
    +        jbe LeaveNow
    +		AFTER_JMP
    +        sub edx, 0x00010000
    +		BEFORE_JMP
    +        js  LeaveNow
    +		AFTER_JMP
    +
    +LoopEntry4:
    +
    +        cmp bx,word ptr [rsi + r8 - 1]
    +		BEFORE_JMP
    +        jnz LookupLoop1
    +        jmp LookupLoopIsZero
    +		AFTER_JMP
    +/*
    +;;; do {
    +;;;     match = s->window + cur_match;
    +;;;     if (*(ushf*)(match+best_len-1) != scan_end ||
    +;;;         *(ushf*)match != scan_start) continue;
    +;;;     [...]
    +;;; } while ((cur_match = prev[cur_match & wmask]) > limit
    +;;;          && --chain_length != 0);
    +;;;
    +;;; Here is the inner loop of the function. The function will spend the
    +;;; majority of its time in this loop, and majority of that time will
    +;;; be spent in the first ten instructions.
    +;;;
    +;;; Within this loop:
    +;;; ebx = scanend
    +;;; r8d = curmatch
    +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
    +;;; esi = windowbestlen - i.e., (window + bestlen)
    +;;; edi = prev
    +;;; ebp = limit
    +*/
    +.balign 16
    +LookupLoop:
    +        and r8d, edx
    +
    +        movzx   r8d, word ptr [rdi + r8*2]
    +        cmp r8d, ebp
    +		BEFORE_JMP
    +        jbe LeaveNow
    +		AFTER_JMP
    +        sub edx, 0x00010000
    +		BEFORE_JMP
    +        js  LeaveNow
    +		AFTER_JMP
    +
    +LoopEntry:
    +
    +        cmp bx,word ptr [rsi + r8 - 1]
    +		BEFORE_JMP
    +        jnz LookupLoop1
    +		AFTER_JMP
    +LookupLoopIsZero:
    +        cmp     r12w, word ptr [r10 + r8]
    +		BEFORE_JMP
    +        jnz LookupLoop1
    +		AFTER_JMP
    +
    +
    +//;;; Store the current value of chainlen.
    +        mov [chainlenwmask], edx
    +/*
    +;;; Point edi to the string under scrutiny, and esi to the string we
    +;;; are hoping to match it up with. In actuality, esi and edi are
    +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
    +;;; initialized to -(MAX_MATCH_8 - scanalign).
    +*/
    +        lea rsi,[r8+r10]
    +        mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8)
    +        lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8]
    +        lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8]
    +
    +        prefetcht1 [rsi+rdx]
    +        prefetcht1 [rdi+rdx]
    +
    +/*
    +;;; Test the strings for equality, 8 bytes at a time. At the end,
    +;;; adjust rdx so that it is offset to the exact byte that mismatched.
    +;;;
    +;;; We already know at this point that the first three bytes of the
    +;;; strings match each other, and they can be safely passed over before
    +;;; starting the compare loop. So what this code does is skip over 0-3
    +;;; bytes, as much as necessary in order to dword-align the edi
    +;;; pointer. (rsi will still be misaligned three times out of four.)
    +;;;
    +;;; It should be confessed that this loop usually does not represent
    +;;; much of the total running time. Replacing it with a more
    +;;; straightforward "rep cmpsb" would not drastically degrade
    +;;; performance.
    +*/
    +
    +LoopCmps:
    +        mov rax, [rsi + rdx]
    +        xor rax, [rdi + rdx]
    +        jnz LeaveLoopCmps
    +
    +        mov rax, [rsi + rdx + 8]
    +        xor rax, [rdi + rdx + 8]
    +        jnz LeaveLoopCmps8
    +
    +
    +        mov rax, [rsi + rdx + 8+8]
    +        xor rax, [rdi + rdx + 8+8]
    +        jnz LeaveLoopCmps16
    +
    +        add rdx,8+8+8
    +
    +		BEFORE_JMP
    +        jnz  LoopCmps
    +        jmp  LenMaximum
    +		AFTER_JMP
    +		
    +LeaveLoopCmps16: add rdx,8
    +LeaveLoopCmps8: add rdx,8
    +LeaveLoopCmps:
    +
    +        test    eax, 0x0000FFFF
    +        jnz LenLower
    +
    +        test eax,0xffffffff
    +
    +        jnz LenLower32
    +
    +        add rdx,4
    +        shr rax,32
    +        or ax,ax
    +		BEFORE_JMP
    +        jnz LenLower
    +		AFTER_JMP
    +
    +LenLower32:
    +        shr eax,16
    +        add rdx,2
    +		
    +LenLower:		
    +        sub al, 1
    +        adc rdx, 0
    +//;;; Calculate the length of the match. If it is longer than MAX_MATCH,
    +//;;; then automatically accept it as the best possible match and leave.
    +
    +        lea rax, [rdi + rdx]
    +        sub rax, r9
    +        cmp eax, MAX_MATCH
    +		BEFORE_JMP
    +        jge LenMaximum
    +		AFTER_JMP
    +/*
    +;;; If the length of the match is not longer than the best match we
    +;;; have so far, then forget it and return to the lookup loop.
    +;///////////////////////////////////
    +*/
    +        cmp eax, r11d
    +        jg  LongerMatch
    +
    +        lea rsi,[r10+r11]
    +
    +        mov rdi, prev_ad
    +        mov edx, [chainlenwmask]
    +		BEFORE_JMP
    +        jmp LookupLoop
    +		AFTER_JMP
    +/*
    +;;;         s->match_start = cur_match;
    +;;;         best_len = len;
    +;;;         if (len >= nice_match) break;
    +;;;         scan_end = *(ushf*)(scan+best_len-1);
    +*/
    +LongerMatch:
    +        mov r11d, eax
    +        mov match_start, r8d
    +        cmp eax, [nicematch]
    +		BEFORE_JMP
    +        jge LeaveNow
    +		AFTER_JMP
    +
    +        lea rsi,[r10+rax]
    +
    +        movzx   ebx, word ptr [r9 + rax - 1]
    +        mov rdi, prev_ad
    +        mov edx, [chainlenwmask]
    +		BEFORE_JMP
    +        jmp LookupLoop
    +		AFTER_JMP
    +
    +//;;; Accept the current string, with the maximum possible length.
    +
    +LenMaximum:
    +        mov r11d,MAX_MATCH
    +        mov match_start, r8d
    +
    +//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
    +//;;; return s->lookahead;
    +
    +LeaveNow:
    +        mov eax, Lookahead
    +        cmp r11d, eax
    +        cmovng eax, r11d
    +
    +
    +
    +//;;; Restore the stack and return from whence we came.
    +
    +
    +//        mov rsi,[save_rsi]
    +//        mov rdi,[save_rdi]
    +        mov rbx,[save_rbx]
    +        mov rbp,[save_rbp]
    +        mov r12,[save_r12]
    +        mov r13,[save_r13]
    +        mov r14,[save_r14]
    +        mov r15,[save_r15]
    +
    +
    +        ret 0
    +//; please don't remove this string !
    +//; Your can freely use gvmat64 in any free or commercial app
    +//; but it is far better don't remove the string in the binary!
    + //   db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
    +
    +
    +match_init:
    +  ret 0
    +
    +
    
    From 9460e81292a9f7c2c90bb8222067b51a86cd6793 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Tue, 20 Apr 2010 23:59:02 +0000
    Subject: [PATCH 2065/2592] MFC  r204343:   Updates what firmware module should
     be used for LP (low power) PHY   users and bumps date.
    
    ---
     share/man/man4/bwn.4 | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/share/man/man4/bwn.4 b/share/man/man4/bwn.4
    index 82371126ee9..1293c36ca1f 100644
    --- a/share/man/man4/bwn.4
    +++ b/share/man/man4/bwn.4
    @@ -24,7 +24,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd February 15, 2010
    +.Dd February 25, 2010
     .Dt BWN 4
     .Os
     .Sh NAME
    @@ -69,6 +69,8 @@ The
     port needs to be installed before
     .Xr ifconfig 8
     will work.
    +Most cases you need to use bwn_v4_ucode module but if you are a
    +LP (low power) PHY user please uses bwn_v4_lp_ucode module.
     .Sh HARDWARE
     The
     .Nm
    
    From be58dd858494c17a39a4e15b77915a41852660e1 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Wed, 21 Apr 2010 00:01:38 +0000
    Subject: [PATCH 2066/2592] MFC  r204385:   don't need to check
     BWN_RX_PHYST0_SHORTPRMBL flag because it's already   handled in later.
    
      Reported from: imp, nwhitehorn
    ---
     sys/dev/bwn/if_bwn.c | 2 --
     1 file changed, 2 deletions(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index 80b567fbe21..13b35e82e6b 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -9395,8 +9395,6 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
     		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
     	if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
     		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
    -	if (phystat0 & BWN_RX_PHYST0_SHORTPRMBL)
    -		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_SHORTPRE\n");
     	if (macstat & BWN_RX_MAC_DECERR)
     		goto drop;
     
    
    From 95def843ce12b1254bd127689c4697d1b5840c62 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Wed, 21 Apr 2010 00:02:48 +0000
    Subject: [PATCH 2067/2592] MFC r204436:   supports the adhoc demo mode that
     it's tested on modified aircrack-ng   suite and worked.
    
      Submitted by:	Paul B Mahol 
    ---
     sys/dev/bwn/if_bwn.c | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index 13b35e82e6b..c21b4c3e63e 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -1076,6 +1076,7 @@ bwn_attach_post(struct bwn_softc *sc)
     	ic->ic_caps =
     		  IEEE80211_C_STA		/* station mode supported */
     		| IEEE80211_C_MONITOR		/* monitor mode */
    +		| IEEE80211_C_AHDEMO		/* adhoc demo mode */
     		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
     		| IEEE80211_C_SHSLOT		/* short slot time supported */
     		| IEEE80211_C_WME		/* WME/WMM supported */
    @@ -8447,7 +8448,8 @@ bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
     		}
     	}
     
    -	if (vap->iv_opmode == IEEE80211_M_MONITOR) {
    +	if (vap->iv_opmode == IEEE80211_M_MONITOR ||
    +	    vap->iv_opmode == IEEE80211_M_AHDEMO) {
     		/* XXX nothing to do? */
     	} else if (nstate == IEEE80211_S_RUN) {
     		memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
    
    From b0b1f91e3894f75c3f06ef0616299a067062b7b8 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Wed, 21 Apr 2010 00:05:22 +0000
    Subject: [PATCH 2068/2592] MFC r204437:   fixes a bug to load firmware images
     for LP PHY. For LP PHY always,   `lp_' string is contained in its full image
     names.
    
    ---
     sys/dev/bwn/if_bwn.c | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index c21b4c3e63e..482683aef72 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -7789,8 +7789,9 @@ bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
     		bwn_do_release_fw(bfw);
     	}
     
    -	snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s",
    -	    (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", name);
    +	snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
    +	    (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
    +	    (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
     	/* XXX Sleeping on "fwload" with the non-sleepable locks held */
     	fw = firmware_get(namebuf);
     	if (fw == NULL) {
    
    From dcad5dbe15ebc42b56dfc9770183bd735a1ee787 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Wed, 21 Apr 2010 00:06:39 +0000
    Subject: [PATCH 2069/2592] MFC r204542:   calculates the integer square root
     if a positive integer X is larger   than 256 instead of using sqrt_table.
    
      Reported by: Joe Marcus Clarke 
    ---
     sys/dev/bwn/if_bwn.c | 9 +++++----
     1 file changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index 482683aef72..7d1e6634450 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -12846,7 +12846,6 @@ bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
     static unsigned int
     bwn_sqrt(struct bwn_mac *mac, unsigned int x)
     {
    -	struct bwn_softc *sc = mac->mac_sc;
     	/* 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,
    @@ -12886,9 +12885,11 @@ bwn_sqrt(struct bwn_mac *mac, unsigned int x)
     	if (x == 0)
     		return (0);
     	if (x >= 256) {
    -		device_printf(sc->sc_dev,
    -		    "out of bounds of the square-root table (%d)\n", x);
    -		return (16);
    +		unsigned int tmp;
    +
    +		for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
    +			/* do nothing */ ;
    +		return (tmp);
     	}
     	return (sqrt_table[x - 1] / 10);
     }
    
    From 489d21bb61fd449b7f21b7c1e11478c167fa3e9f Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Wed, 21 Apr 2010 00:13:44 +0000
    Subject: [PATCH 2070/2592] MFC r204657:   fixes an attached-at-boot issue that
     bwn(4) using device_identify   interface didn't be attached automatically at
     boot time so changes a   approach to attach children based on leveraging some
     newbus niceties.
    
      Submitted by: nwhitehorn
    ---
     sys/dev/bwn/if_bwn.c     |  8 ------
     sys/dev/siba/siba_bwn.c  | 12 --------
     sys/dev/siba/siba_core.c | 61 ++++++++--------------------------------
     3 files changed, 12 insertions(+), 69 deletions(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index 7d1e6634450..0a86c65fd22 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -14312,16 +14312,8 @@ bwn_sysctl_node(struct bwn_softc *sc)
     #endif
     }
     
    -static void
    -bwn_identify(driver_t *driver, device_t parent)
    -{
    -
    -	BUS_ADD_CHILD(parent, 0, "bwn", -1);
    -}
    -
     static device_method_t bwn_methods[] = {
     	/* Device interface */
    -	DEVMETHOD(device_identify,	bwn_identify),
     	DEVMETHOD(device_probe,		bwn_probe),
     	DEVMETHOD(device_attach,	bwn_attach),
     	DEVMETHOD(device_detach,	bwn_detach),
    diff --git a/sys/dev/siba/siba_bwn.c b/sys/dev/siba/siba_bwn.c
    index a5513bdb4e1..f33f9b3c52c 100644
    --- a/sys/dev/siba/siba_bwn.c
    +++ b/sys/dev/siba/siba_bwn.c
    @@ -97,8 +97,6 @@ static const struct siba_dev {
     	{ PCI_VENDOR_BROADCOM, 0x432b, "Unknown" }
     };
     
    -device_t	siba_add_child(device_t, struct siba_softc *, int, const char *,
    -		    int);
     int		siba_core_attach(struct siba_softc *);
     int		siba_core_detach(struct siba_softc *);
     int		siba_core_suspend(struct siba_softc *);
    @@ -238,15 +236,6 @@ siba_bwn_resume(device_t dev)
     	return (0);
     }
     
    -static device_t
    -siba_bwn_add_child(device_t dev, int order, const char *name, int unit)
    -{
    -	struct siba_bwn_softc *ssc = device_get_softc(dev);
    -	struct siba_softc *siba = &ssc->ssc_siba;
    -
    -	return (siba_add_child(dev, siba, order, name, unit));
    -}
    -
     /* proxying to the parent */
     static struct resource *
     siba_bwn_alloc_resource(device_t dev, device_t child, int type, int *rid,
    @@ -342,7 +331,6 @@ static device_method_t siba_bwn_methods[] = {
     	DEVMETHOD(device_resume,	siba_bwn_resume),
     
     	/* Bus interface */
    -	DEVMETHOD(bus_add_child,	siba_bwn_add_child),
     	DEVMETHOD(bus_alloc_resource,   siba_bwn_alloc_resource),
     	DEVMETHOD(bus_release_resource, siba_bwn_release_resource),
     	DEVMETHOD(bus_setup_intr,       siba_bwn_setup_intr),
    diff --git a/sys/dev/siba/siba_core.c b/sys/dev/siba/siba_core.c
    index d19771dac9d..748b426b7a9 100644
    --- a/sys/dev/siba/siba_core.c
    +++ b/sys/dev/siba/siba_core.c
    @@ -133,8 +133,6 @@ static void	siba_pci_write_multi_4(struct siba_dev_softc *, const void *,
     		    size_t, uint16_t);
     static const char *siba_core_name(uint16_t);
     static void	siba_pcicore_init(struct siba_pci *);
    -device_t	siba_add_child(device_t, struct siba_softc *, int, const char *,
    -		    int);
     int		siba_core_attach(struct siba_softc *);
     int		siba_core_detach(struct siba_softc *);
     int		siba_core_suspend(struct siba_softc *);
    @@ -206,8 +204,10 @@ siba_core_attach(struct siba_softc *siba)
     		return (error);
     	}
     
    +	siba_pcicore_init(&siba->siba_pci);
     	siba_powerdown(siba);
    -	return (0);
    +	
    +	return (bus_generic_attach(siba->siba_dev));
     }
     
     int
    @@ -277,6 +277,7 @@ siba_scan(struct siba_softc *siba)
     {
     	struct siba_dev_softc *sd;
     	uint32_t idhi, tmp;
    +	device_t child;
     	int base, dev_i = 0, error, i, is_pcie, n_80211 = 0, n_cc = 0,
     	    n_pci = 0;
     
    @@ -387,6 +388,14 @@ siba_scan(struct siba_softc *siba)
     			break;
     		}
     		dev_i++;
    +
    +		child = device_add_child(siba->siba_dev, NULL, -1);
    +		if (child == NULL) {
    +			device_printf(siba->siba_dev, "child attach failed\n");
    +			continue;
    +		}
    +
    +		device_set_ivars(child, sd);
     	}
     	siba->siba_ndevs = dev_i;
     }
    @@ -1964,52 +1973,6 @@ siba_barrier(struct siba_dev_softc *sd, int flags)
     	SIBA_BARRIER(siba, flags);
     }
     
    -/*
    - * Attach it as child.
    - */
    -device_t
    -siba_add_child(device_t dev, struct siba_softc *siba, int order,
    -    const char *name, int unit)
    -{
    -	struct siba_dev_softc *sd;
    -	device_t child;
    -	int idx = 0, i;
    -
    -	child = device_add_child(dev, name, unit);
    -	if (child == NULL)
    -		return (NULL);
    -
    -	siba_powerup(siba, 0);
    -	siba_pcicore_init(&siba->siba_pci);
    -	siba_powerdown(siba);
    -
    -	for (i = 0; i < siba->siba_ndevs; i++) {
    -		sd = &(siba->siba_devs[i]);
    -
    -		if (sd->sd_id.sd_device != SIBA_DEVID_80211) {
    -			DPRINTF(siba, SIBA_DEBUG_CORE,
    -			    "skip to register coreid %#x (%s)\n",
    -			    sd->sd_id.sd_device,
    -			    siba_core_name(sd->sd_id.sd_device));
    -			continue;
    -		}
    -
    -		DPRINTF(siba, SIBA_DEBUG_CORE,
    -		    "siba: attaching coreid %#x (%s) idx %d\n",
    -		    sd->sd_id.sd_device,
    -		    siba_core_name(sd->sd_id.sd_device), idx);
    -
    -		KASSERT(sd->sd_id.sd_device == SIBA_DEVID_80211,
    -		    ("%s:%d: SIBA_DEVID_80211 is only supportted currently.",
    -			__func__, __LINE__));
    -
    -		device_set_ivars(child, sd);
    -		device_probe_and_attach(child);
    -		idx++;
    -	}
    -	return (child);
    -}
    -
     static void
     siba_cc_suspend(struct siba_cc *scc)
     {
    
    From 947d8d8758cb37dbb21266e8b24ea9f13c34fd80 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Wed, 21 Apr 2010 00:15:58 +0000
    Subject: [PATCH 2071/2592] MFC r204662:   Hook up the bwn driver.
    
      Pointed by: nwhitehorn
    ---
     sys/conf/files | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/sys/conf/files b/sys/conf/files
    index 72f215a1eb3..e2a7ade57fb 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -771,6 +771,7 @@ dev/bwi/bwiphy.c		optional bwi
     dev/bwi/bwirf.c			optional bwi
     dev/bwi/if_bwi.c		optional bwi
     dev/bwi/if_bwi_pci.c		optional bwi pci
    +dev/bwn/if_bwn.c		optional bwn siba_bwn
     dev/cardbus/cardbus.c		optional cardbus
     dev/cardbus/cardbus_cis.c	optional cardbus
     dev/cardbus/cardbus_device.c	optional cardbus
    @@ -1481,6 +1482,8 @@ dev/si/si3_t225.c		optional si
     dev/si/si_eisa.c		optional si eisa
     dev/si/si_isa.c			optional si isa
     dev/si/si_pci.c			optional si pci
    +dev/siba/siba_bwn.c		optional siba_bwn pci
    +dev/siba/siba_core.c		optional siba_bwn pci
     dev/siis/siis.c			optional siis pci
     dev/sis/if_sis.c		optional sis pci
     dev/sk/if_sk.c			optional sk pci inet
    
    From 87ecd62c3d08daffd7e66c5914263925d0e8acc1 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Wed, 21 Apr 2010 00:22:16 +0000
    Subject: [PATCH 2072/2592] MFC r205003:   Revert r204992 and just wrap it all
     in ifdef INVARIANTS to fix the debug   and non-debug cases
    
    MFC r204992:
      fixes a compile error if INVARIANTS is disabled.
    
      Pointy hat to: me
      Submitted by: Michael Butler 
    
    MFC r204983:
      Fix build breakage introduced in r204922.
    
    MFC r204923:
      uses KOBJMETHOD_END macro to indicate the end of method table.
    
      Submitted by: yongari
    
    MFC r204922:
      o uses bus accessor macros to read values from ivar so no more values
        are referenced directly from ivar pointer.  It's to do like what other
        buses do. [1]
      o changes exported prototypes.  It doesn't use struct siba_* structures
        anymore that instead of it it uses only device_t.
      o removes duplicate code and debug messages.
      o style(9)
    
      Pointed out by:        imp [1]
    ---
     sys/dev/bwn/if_bwn.c     | 724 ++++++++++++++++++---------------------
     sys/dev/bwn/if_bwnvar.h  |  18 +-
     sys/dev/siba/siba.c      |   2 +-
     sys/dev/siba/siba_bwn.c  |  69 +++-
     sys/dev/siba/siba_cc.c   |   2 +-
     sys/dev/siba/siba_core.c | 655 ++++++++++++++++++++++++++++++-----
     sys/dev/siba/siba_pcib.c |   2 +-
     sys/dev/siba/sibavar.h   | 246 ++++++++++---
     8 files changed, 1198 insertions(+), 520 deletions(-)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index 0a86c65fd22..973ba85ba41 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -134,7 +134,7 @@ SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
     
     static int	bwn_attach_pre(struct bwn_softc *);
     static int	bwn_attach_post(struct bwn_softc *);
    -static void	bwn_sprom_bugfixes(struct siba_softc *);
    +static void	bwn_sprom_bugfixes(device_t);
     static void	bwn_init(void *);
     static int	bwn_init_locked(struct bwn_softc *);
     static int	bwn_ioctl(struct ifnet *, u_long, caddr_t);
    @@ -205,7 +205,6 @@ static void	bwn_stop_locked(struct bwn_softc *, int);
     static int	bwn_core_init(struct bwn_mac *);
     static void	bwn_core_start(struct bwn_mac *);
     static void	bwn_core_exit(struct bwn_mac *);
    -static void	bwn_fix_imcfglobug(struct bwn_mac *);
     static void	bwn_bt_disable(struct bwn_mac *);
     static int	bwn_chip_init(struct bwn_mac *);
     static uint64_t	bwn_hf_read(struct bwn_mac *);
    @@ -225,7 +224,6 @@ static int	bwn_fw_loadinitvals(struct bwn_mac *);
     static int	bwn_phy_init(struct bwn_mac *);
     static void	bwn_set_txantenna(struct bwn_mac *, int);
     static void	bwn_set_opmode(struct bwn_mac *);
    -static void	bwn_gpio_cleanup(struct bwn_mac *);
     static void	bwn_rate_write(struct bwn_mac *, uint16_t, int);
     static uint8_t	bwn_plcp_getcck(const uint8_t);
     static uint8_t	bwn_plcp_getofdm(const uint8_t);
    @@ -910,13 +908,12 @@ static const struct siba_devid bwn_devs[] = {
     static int
     bwn_probe(device_t dev)
     {
    -	struct siba_dev_softc *sd = device_get_ivars(dev);
     	int i;
     
     	for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
    -		if (sd->sd_id.sd_vendor == bwn_devs[i].sd_vendor &&
    -		    sd->sd_id.sd_device == bwn_devs[i].sd_device &&
    -		    sd->sd_id.sd_rev == bwn_devs[i].sd_rev)
    +		if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
    +		    siba_get_device(dev) == bwn_devs[i].sd_device &&
    +		    siba_get_revid(dev) == bwn_devs[i].sd_rev)
     			return (BUS_PROBE_DEFAULT);
     	}
     
    @@ -928,12 +925,9 @@ bwn_attach(device_t dev)
     {
     	struct bwn_mac *mac;
     	struct bwn_softc *sc = device_get_softc(dev);
    -	struct siba_dev_softc *sd = device_get_ivars(dev);
    -	struct siba_softc *siba = sd->sd_bus;
     	int error, i, msic, reg;
     
     	sc->sc_dev = dev;
    -	sc->sc_sd = sd;
     #ifdef BWN_DEBUG
     	sc->sc_debug = bwn_debug;
     #endif
    @@ -942,14 +936,14 @@ bwn_attach(device_t dev)
     		error = bwn_attach_pre(sc);
     		if (error != 0)
     			return (error);
    -		bwn_sprom_bugfixes(sd->sd_bus);
    +		bwn_sprom_bugfixes(dev);
     		sc->sc_flags |= BWN_FLAG_ATTACHED;
     	}
     
     	if (!TAILQ_EMPTY(&sc->sc_maclist)) {
    -		if (siba->siba_pci_did != 0x4313 &&
    -		    siba->siba_pci_did != 0x431a &&
    -		    siba->siba_pci_did != 0x4321) {
    +		if (siba_get_pci_device(dev) != 0x4313 &&
    +		    siba_get_pci_device(dev) != 0x431a &&
    +		    siba_get_pci_device(dev) != 0x4321) {
     			device_printf(sc->sc_dev,
     			    "skip 802.11 cores\n");
     			return (ENODEV);
    @@ -961,7 +955,6 @@ bwn_attach(device_t dev)
     	if (mac == NULL)
     		return (ENOMEM);
     	mac->mac_sc = sc;
    -	mac->mac_sd = sd;
     	mac->mac_status = BWN_MAC_STATUS_UNINIT;
     	if (bwn_bfp != 0)
     		mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
    @@ -977,7 +970,7 @@ bwn_attach(device_t dev)
     
     	device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
     	    "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
    -	    sd->sd_bus->siba_chipid, sd->sd_id.sd_rev,
    +	    siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
     	    mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
     	    mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
     	    mac->mac_phy.rf_rev);
    @@ -1065,8 +1058,6 @@ bwn_attach_post(struct bwn_softc *sc)
     {
     	struct ieee80211com *ic;
     	struct ifnet *ifp = sc->sc_ifp;
    -	struct siba_dev_softc *sd = sc->sc_sd;
    -	struct siba_sprom *sprom = &sd->sd_bus->siba_sprom;
     
     	ic = ifp->if_l2com;
     	ic->ic_ifp = ifp;
    @@ -1087,8 +1078,9 @@ bwn_attach_post(struct bwn_softc *sc)
     
     	/* call MI attach routine. */
     	ieee80211_ifattach(ic,
    -	    bwn_is_valid_ether_addr(sprom->mac_80211a) ? sprom->mac_80211a :
    -	    sprom->mac_80211bg);
    +	    bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
    +	    siba_sprom_get_mac_80211a(sc->sc_dev) :
    +	    siba_sprom_get_mac_80211bg(sc->sc_dev));
     
     	ic->ic_headroom = sizeof(struct bwn_txhdr);
     
    @@ -1219,21 +1211,24 @@ fail:	BWN_LOCK_DESTROY(sc);
     }
     
     static void
    -bwn_sprom_bugfixes(struct siba_softc *siba)
    +bwn_sprom_bugfixes(device_t dev)
     {
     #define	BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)		\
    -	((siba->siba_pci_vid == PCI_VENDOR_##_vendor) &&		\
    -	 (siba->siba_pci_did == _device) &&				\
    -	 (siba->siba_pci_subvid == PCI_VENDOR_##_subvendor) &&		\
    -	 (siba->siba_pci_subdid == _subdevice))
    +	((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&		\
    +	 (siba_get_pci_device(dev) == _device) &&			\
    +	 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&	\
    +	 (siba_get_pci_subdevice(dev) == _subdevice))
     
    -	if (siba->siba_board_vendor == PCI_VENDOR_APPLE &&
    -	    siba->siba_board_type == 0x4e && siba->siba_board_rev > 0x40)
    -		siba->siba_sprom.bf_lo |= BWN_BFL_PACTRL;
    -	if (siba->siba_board_vendor == SIBA_BOARDVENDOR_DELL &&
    -	    siba->siba_chipid == 0x4301 && siba->siba_board_rev == 0x74)
    -		siba->siba_sprom.bf_lo |= BWN_BFL_BTCOEXIST;
    -	if (siba->siba_type == SIBA_TYPE_PCI) {
    +	if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
    +	    siba_get_pci_subdevice(dev) == 0x4e &&
    +	    siba_get_pci_revid(dev) > 0x40)
    +		siba_sprom_set_bf_lo(dev,
    +		    siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
    +	if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
    +	    siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
    +		siba_sprom_set_bf_lo(dev,
    +		    siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
    +	if (siba_get_type(dev) == SIBA_TYPE_PCI) {
     		if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
     		    BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
     		    BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
    @@ -1241,7 +1236,8 @@ bwn_sprom_bugfixes(struct siba_softc *siba)
     		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
     		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
     		    BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
    -			siba->siba_sprom.bf_lo &= ~BWN_BFL_BTCOEXIST;
    +			siba_sprom_set_bf_lo(dev,
    +			    siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
     	}
     #undef	BWN_ISDEV
     }
    @@ -1434,7 +1430,7 @@ bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
     	tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
     	tq->tq_free--;
     
    -	if (mac->mac_sd->sd_id.sd_rev >= 8) {
    +	if (siba_get_revid(sc->sc_dev) >= 8) {
     		/*
     		 * XXX please removes m_defrag(9)
     		 */
    @@ -1606,17 +1602,15 @@ static int
     bwn_attach_core(struct bwn_mac *mac)
     {
     	struct bwn_softc *sc = mac->mac_sc;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	int error, have_bg = 0, have_a = 0;
     	uint32_t high;
     
    -	KASSERT(sd->sd_id.sd_rev >= 5,
    -	    ("unsupported revision %d", sd->sd_id.sd_rev));
    +	KASSERT(siba_get_revid(sc->sc_dev) >= 5,
    +	    ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
     
    -	siba_powerup(siba, 0);
    +	siba_powerup(sc->sc_dev, 0);
     
    -	high = siba_read_4(sd, SIBA_TGSHIGH);
    +	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
     	bwn_reset_core(mac,
     	    (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
     	error = bwn_phy_getinfo(mac, high);
    @@ -1625,8 +1619,9 @@ bwn_attach_core(struct bwn_mac *mac)
     
     	have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
     	have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
    -	if (siba->siba_pci_did != 0x4312 && siba->siba_pci_did != 0x4319 &&
    -	    siba->siba_pci_did != 0x4324) {
    +	if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
    +	    siba_get_pci_device(sc->sc_dev) != 0x4319 &&
    +	    siba_get_pci_device(sc->sc_dev) != 0x4324) {
     		have_a = have_bg = 0;
     		if (mac->mac_phy.type == BWN_PHYTYPE_A)
     			have_a = 1;
    @@ -1719,30 +1714,30 @@ bwn_attach_core(struct bwn_mac *mac)
     
     	mac->mac_phy.switch_analog(mac, 0);
     
    -	siba_dev_down(sd, 0);
    +	siba_dev_down(sc->sc_dev, 0);
     fail:
    -	siba_powerdown(siba);
    +	siba_powerdown(sc->sc_dev);
     	return (error);
     }
     
     static void
     bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
     {
    -	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint32_t low, ctl;
     
     	flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
     
    -	siba_dev_up(sd, flags);
    +	siba_dev_up(sc->sc_dev, flags);
     	DELAY(2000);
     
    -	low = (siba_read_4(sd, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
    +	low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
     	    ~BWN_TGSLOW_PHYRESET;
    -	siba_write_4(sd, SIBA_TGSLOW, low);
    -	siba_read_4(sd, SIBA_TGSLOW);
    +	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
    +	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
     	DELAY(1000);
    -	siba_write_4(sd, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
    -	siba_read_4(sd, SIBA_TGSLOW);
    +	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
    +	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
     	DELAY(1000);
     
     	if (mac->mac_phy.switch_analog != NULL)
    @@ -1759,8 +1754,6 @@ bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_softc *sc = mac->mac_sc;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	uint32_t tmp;
     
     	/* PHY */
    @@ -1779,10 +1772,10 @@ bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
     		goto unsupphy;
     
     	/* RADIO */
    -	if (siba->siba_chipid == 0x4317) {
    -		if (siba->siba_chiprev == 0)
    +	if (siba_get_chipid(sc->sc_dev) == 0x4317) {
    +		if (siba_get_chiprev(sc->sc_dev) == 0)
     			tmp = 0x3205017f;
    -		else if (siba->siba_chiprev == 1)
    +		else if (siba_get_chiprev(sc->sc_dev) == 1)
     			tmp = 0x4205017f;
     		else
     			tmp = 0x5205017f;
    @@ -1826,7 +1819,6 @@ bwn_chiptest(struct bwn_mac *mac)
     #define	TESTVAL0	0x55aaaa55
     #define	TESTVAL1	0xaa5555aa
     	struct bwn_softc *sc = mac->mac_sc;
    -	struct siba_dev_softc *sd = mac->mac_sd;
     	uint32_t v, backup;
     
     	BWN_LOCK(sc);
    @@ -1842,7 +1834,8 @@ bwn_chiptest(struct bwn_mac *mac)
     
     	bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
     
    -	if ((sd->sd_id.sd_rev >= 3) && (sd->sd_id.sd_rev <= 10)) {
    +	if ((siba_get_revid(sc->sc_dev) >= 3) &&
    +	    (siba_get_revid(sc->sc_dev) <= 10)) {
     		BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
     		BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
     		if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
    @@ -2070,15 +2063,17 @@ bwn_phy_g_attach(struct bwn_mac *mac)
     	struct bwn_softc *sc = mac->mac_sc;
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_sprom *sprom = &sd->sd_bus->siba_sprom;
     	unsigned int i;
    -	int16_t pab0 = (int16_t)(sprom->pa0b0), pab1 = (int16_t)(sprom->pa0b1),
    -	    pab2 = (int16_t)(sprom->pa0b2);
    +	int16_t pab0, pab1, pab2;
     	static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
    -	int8_t bg = (int8_t)sprom->tssi_bg;
    +	int8_t bg;
     
    -	if ((sd->sd_bus->siba_chipid == 0x4301) && (phy->rf_ver != 0x2050))
    +	bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
    +	pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
    +	pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
    +	pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
    +
    +	if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
     		device_printf(sc->sc_dev, "not supported anymore\n");
     
     	pg->pg_flags = 0;
    @@ -2175,8 +2170,8 @@ bwn_phy_g_prepare_hw(struct bwn_mac *mac)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
     	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
    -	struct siba_softc *bus = mac->mac_sd->sd_bus;
     	static const struct bwn_rfatt rfatt0[] = {
     		{ 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 },	{ 9, 0 }, { 2, 0 },
     		{ 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
    @@ -2204,12 +2199,12 @@ bwn_phy_g_prepare_hw(struct bwn_mac *mac)
     	/* prepare Radio Attenuation */
     	pg->pg_rfatt.padmix = 0;
     
    -	if (bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM &&
    -	    bus->siba_board_type == SIBA_BOARD_BCM4309G) {
    -		if (bus->siba_board_rev < 0x43) {
    +	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
    +	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
    +		if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
     			pg->pg_rfatt.att = 2;
     			goto done;
    -		} else if (bus->siba_board_rev < 0x51) {
    +		} else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
     			pg->pg_rfatt.att = 3;
     			goto done;
     		}
    @@ -2228,24 +2223,25 @@ bwn_phy_g_prepare_hw(struct bwn_mac *mac)
     			goto done;
     		case 1:
     			if (phy->type == BWN_PHYTYPE_G) {
    -				if (bus->siba_board_vendor ==
    +				if (siba_get_pci_subvendor(sc->sc_dev) ==
     				    SIBA_BOARDVENDOR_BCM &&
    -				    bus->siba_board_type ==
    +				    siba_get_pci_subdevice(sc->sc_dev) ==
     				    SIBA_BOARD_BCM4309G &&
    -				    bus->siba_board_rev >= 30)
    +				    siba_get_pci_revid(sc->sc_dev) >= 30)
     					pg->pg_rfatt.att = 3;
    -				else if (bus->siba_board_vendor ==
    +				else if (siba_get_pci_subvendor(sc->sc_dev) ==
     				    SIBA_BOARDVENDOR_BCM &&
    -				    bus->siba_board_type == SIBA_BOARD_BU4306)
    +				    siba_get_pci_subdevice(sc->sc_dev) ==
    +				    SIBA_BOARD_BU4306)
     					pg->pg_rfatt.att = 3;
     				else
     					pg->pg_rfatt.att = 1;
     			} else {
    -				if (bus->siba_board_vendor ==
    +				if (siba_get_pci_subvendor(sc->sc_dev) ==
     				    SIBA_BOARDVENDOR_BCM &&
    -				    bus->siba_board_type ==
    +				    siba_get_pci_subdevice(sc->sc_dev) ==
     				    SIBA_BOARD_BCM4309G &&
    -				    bus->siba_board_rev >= 30)
    +				    siba_get_pci_revid(sc->sc_dev) >= 30)
     					pg->pg_rfatt.att = 7;
     				else
     					pg->pg_rfatt.att = 6;
    @@ -2253,17 +2249,18 @@ bwn_phy_g_prepare_hw(struct bwn_mac *mac)
     			goto done;
     		case 2:
     			if (phy->type == BWN_PHYTYPE_G) {
    -				if (bus->siba_board_vendor ==
    +				if (siba_get_pci_subvendor(sc->sc_dev) ==
     				    SIBA_BOARDVENDOR_BCM &&
    -				    bus->siba_board_type ==
    +				    siba_get_pci_subdevice(sc->sc_dev) ==
     				    SIBA_BOARD_BCM4309G &&
    -				    bus->siba_board_rev >= 30)
    +				    siba_get_pci_revid(sc->sc_dev) >= 30)
     					pg->pg_rfatt.att = 3;
    -				else if (bus->siba_board_vendor ==
    +				else if (siba_get_pci_subvendor(sc->sc_dev) ==
     				    SIBA_BOARDVENDOR_BCM &&
    -				    bus->siba_board_type == SIBA_BOARD_BU4306)
    +				    siba_get_pci_subdevice(sc->sc_dev) ==
    +				    SIBA_BOARD_BU4306)
     					pg->pg_rfatt.att = 5;
    -				else if (bus->siba_chipid == 0x4320)
    +				else if (siba_get_chipid(sc->sc_dev) == 0x4320)
     					pg->pg_rfatt.att = 4;
     				else
     					pg->pg_rfatt.att = 3;
    @@ -2547,7 +2544,6 @@ bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
     	struct bwn_softc *sc = mac->mac_sc;
    -	struct siba_softc *siba = mac->mac_sd->sd_bus;
     	unsigned int tssi;
     	int cck, ofdm;
     	int power;
    @@ -2570,12 +2566,13 @@ bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
     	pg->pg_avgtssi = tssi;
     	KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
     
    -	max = siba->siba_sprom.maxpwr_bg;
    -	if (siba->siba_sprom.bf_lo & BWN_BFL_PACTRL)
    +	max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
    +	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
     		max -= 3;
     	if (max >= 120) {
     		device_printf(sc->sc_dev, "invalid max TX-power value\n");
    -		siba->siba_sprom.maxpwr_bg = max = 80;
    +		max = 80;
    +		siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
     	}
     
     	power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
    @@ -2619,9 +2616,8 @@ bwn_phy_g_set_txpwr(struct bwn_mac *mac)
     				txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
     				rfatt += 2;
     				bbatt += 2;
    -			} else if (mac->mac_sd->sd_bus->siba_sprom.
    -				   bf_lo &
    -				   BWN_BFL_PACTRL) {
    +			} else if (siba_sprom_get_bf_lo(sc->sc_dev) &
    +			    BWN_BFL_PACTRL) {
     				bbatt += 4 * (rfatt - 2);
     				rfatt = 2;
     			}
    @@ -2716,9 +2712,10 @@ static void
     bwn_phy_g_task_60s(struct bwn_mac *mac)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint8_t old = phy->chan;
     
    -	if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI))
    +	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
     		return;
     
     	bwn_mac_suspend(mac);
    @@ -3182,20 +3179,15 @@ bwn_wme_clear(struct bwn_softc *sc)
     static int
     bwn_core_init(struct bwn_mac *mac)
     {
    -#ifdef BWN_DEBUG
     	struct bwn_softc *sc = mac->mac_sc;
    -#endif
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
    -	struct siba_sprom *sprom = &siba->siba_sprom;
     	uint64_t hf;
     	int error;
     
     	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
     	    ("%s:%d: fail", __func__, __LINE__));
     
    -	siba_powerup(siba, 0);
    -	if (!siba_dev_isup(sd))
    +	siba_powerup(sc->sc_dev, 0);
    +	if (!siba_dev_isup(sc->sc_dev))
     		bwn_reset_core(mac,
     		    mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
     
    @@ -3219,9 +3211,9 @@ bwn_core_init(struct bwn_mac *mac)
     
     	mac->mac_phy.init_pre(mac);
     
    -	siba_pcicore_intr(&siba->siba_pci, sd);
    +	siba_pcicore_intr(sc->sc_dev);
     
    -	bwn_fix_imcfglobug(mac);
    +	siba_fix_imcfglobug(sc->sc_dev);
     	bwn_bt_disable(mac);
     	if (mac->mac_phy.prepare_hw) {
     		error = mac->mac_phy.prepare_hw(mac);
    @@ -3232,11 +3224,11 @@ bwn_core_init(struct bwn_mac *mac)
     	if (error)
     		goto fail0;
     	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
    -	    mac->mac_sd->sd_id.sd_rev);
    +	    siba_get_revid(sc->sc_dev));
     	hf = bwn_hf_read(mac);
     	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
     		hf |= BWN_HF_GPHY_SYM_WORKAROUND;
    -		if (sprom->bf_lo & BWN_BFL_PACTRL)
    +		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
     			hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
     		if (mac->mac_phy.rev == 1)
     			hf |= BWN_HF_GPHY_DC_CANCELFILTER;
    @@ -3247,10 +3239,10 @@ bwn_core_init(struct bwn_mac *mac)
     		if (mac->mac_phy.rf_rev == 6)
     			hf |= BWN_HF_4318_TSSI;
     	}
    -	if (sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW)
    +	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
     		hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
    -	if ((siba->siba_type == SIBA_TYPE_PCI) &&
    -	    (siba->siba_pci.spc_dev->sd_id.sd_rev <= 10))
    +	if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
    +	    (siba_get_pcicore_revid(sc->sc_dev) <= 10))
     		hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
     	hf &= ~BWN_HF_SKIP_CFP_UPDATE;
     	bwn_hf_write(mac, hf);
    @@ -3267,7 +3259,7 @@ bwn_core_init(struct bwn_mac *mac)
     	    (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
     	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
     
    -	if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
    +	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
     		bwn_pio_init(mac);
     	else
     		bwn_dma_init(mac);
    @@ -3277,7 +3269,8 @@ bwn_core_init(struct bwn_mac *mac)
     	bwn_spu_setdelay(mac, 1);
     	bwn_bt_enable(mac);
     
    -	siba_powerup(siba, !(sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW));
    +	siba_powerup(sc->sc_dev,
    +	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
     	bwn_set_macaddr(mac);
     	bwn_crypt_init(mac);
     
    @@ -3290,7 +3283,7 @@ bwn_core_init(struct bwn_mac *mac)
     fail1:
     	bwn_chip_exit(mac);
     fail0:
    -	siba_powerdown(siba);
    +	siba_powerdown(sc->sc_dev);
     	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
     	    ("%s:%d: fail", __func__, __LINE__));
     	return (error);
    @@ -3305,7 +3298,7 @@ bwn_core_start(struct bwn_mac *mac)
     	KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
     	    ("%s:%d: fail", __func__, __LINE__));
     
    -	if (mac->mac_sd->sd_id.sd_rev < 5)
    +	if (siba_get_revid(sc->sc_dev) < 5)
     		return;
     
     	while (1) {
    @@ -3325,6 +3318,7 @@ bwn_core_start(struct bwn_mac *mac)
     static void
     bwn_core_exit(struct bwn_mac *mac)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint32_t macctl;
     
     	BWN_ASSERT_LOCKED(mac->mac_sc);
    @@ -3345,35 +3339,8 @@ bwn_core_exit(struct bwn_mac *mac)
     	bwn_pio_stop(mac);
     	bwn_chip_exit(mac);
     	mac->mac_phy.switch_analog(mac, 0);
    -	siba_dev_down(mac->mac_sd, 0);
    -	siba_powerdown(mac->mac_sd->sd_bus);
    -}
    -
    -static void
    -bwn_fix_imcfglobug(struct bwn_mac *mac)
    -{
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
    -	uint32_t tmp;
    -
    -	if (siba->siba_pci.spc_dev == NULL)
    -		return;
    -	if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI ||
    -	    siba->siba_pci.spc_dev->sd_id.sd_rev > 5)
    -		return;
    -
    -	tmp = siba_read_4(sd, SIBA_IMCFGLO) &
    -	    ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO);
    -	switch (siba->siba_type) {
    -	case SIBA_TYPE_PCI:
    -	case SIBA_TYPE_PCMCIA:
    -		tmp |= 0x32;
    -		break;
    -	case SIBA_TYPE_SSB:
    -		tmp |= 0x53;
    -		break;
    -	}
    -	siba_write_4(sd, SIBA_IMCFGLO, tmp);
    +	siba_dev_down(sc->sc_dev, 0);
    +	siba_powerdown(sc->sc_dev);
     }
     
     static void
    @@ -3388,6 +3355,7 @@ bwn_bt_disable(struct bwn_mac *mac)
     static int
     bwn_chip_init(struct bwn_mac *mac)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     	struct bwn_phy *phy = &mac->mac_phy;
     	uint32_t macctl;
     	int error;
    @@ -3410,13 +3378,13 @@ bwn_chip_init(struct bwn_mac *mac)
     
     	error = bwn_fw_loadinitvals(mac);
     	if (error) {
    -		bwn_gpio_cleanup(mac);
    +		siba_gpio_set(sc->sc_dev, 0);
     		return (error);
     	}
     	phy->switch_analog(mac, 1);
     	error = bwn_phy_init(mac);
     	if (error) {
    -		bwn_gpio_cleanup(mac);
    +		siba_gpio_set(sc->sc_dev, 0);
     		return (error);
     	}
     	if (phy->set_im)
    @@ -3428,7 +3396,7 @@ bwn_chip_init(struct bwn_mac *mac)
     	if (phy->type == BWN_PHYTYPE_B)
     		BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
     	BWN_WRITE_4(mac, 0x0100, 0x01000000);
    -	if (mac->mac_sd->sd_id.sd_rev < 5)
    +	if (siba_get_revid(sc->sc_dev) < 5)
     		BWN_WRITE_4(mac, 0x010c, 0x01000000);
     
     	BWN_WRITE_4(mac, BWN_MACCTL,
    @@ -3438,7 +3406,7 @@ bwn_chip_init(struct bwn_mac *mac)
     	bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
     
     	bwn_set_opmode(mac);
    -	if (mac->mac_sd->sd_id.sd_rev < 3) {
    +	if (siba_get_revid(sc->sc_dev) < 3) {
     		BWN_WRITE_2(mac, 0x060e, 0x0000);
     		BWN_WRITE_2(mac, 0x0610, 0x8000);
     		BWN_WRITE_2(mac, 0x0604, 0x0000);
    @@ -3454,10 +3422,9 @@ bwn_chip_init(struct bwn_mac *mac)
     	BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
     	BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
     	BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
    -	siba_write_4(mac->mac_sd, SIBA_TGSLOW,
    -	    siba_read_4(mac->mac_sd, SIBA_TGSLOW) | 0x00100000);
    -	BWN_WRITE_2(mac, BWN_POWERUP_DELAY,
    -	    mac->mac_sd->sd_bus->siba_cc.scc_powerup_delay);
    +	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
    +	    siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
    +	BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
     	return (error);
     }
     
    @@ -3619,13 +3586,14 @@ bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
         int index)
     {
     	struct bwn_pio_txpkt *tp;
    +	struct bwn_softc *sc = mac->mac_sc;
     	unsigned int i;
     
     	tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
     	tq->tq_index = index;
     
     	tq->tq_free = BWN_PIO_MAX_TXPACKETS;
    -	if (mac->mac_sd->sd_id.sd_rev >= 8)
    +	if (siba_get_revid(sc->sc_dev) >= 8)
     		tq->tq_size = 1920;
     	else {
     		tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
    @@ -3664,7 +3632,7 @@ bwn_pio_idx2base(struct bwn_mac *mac, int index)
     		BWN_PIO11_BASE5,
     	};
     
    -	if (mac->mac_sd->sd_id.sd_rev >= 11) {
    +	if (siba_get_revid(sc->sc_dev) >= 11) {
     		if (index >= N(bases_rev11))
     			device_printf(sc->sc_dev, "%s: warning\n", __func__);
     		return (bases_rev11[index]);
    @@ -3678,9 +3646,10 @@ static void
     bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
         int index)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     
     	prq->prq_mac = mac;
    -	prq->prq_rev = mac->mac_sd->sd_id.sd_rev;
    +	prq->prq_rev = siba_get_revid(sc->sc_dev);
     	prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
     	bwn_dma_rxdirectfifo(mac, index, 1);
     }
    @@ -4027,6 +3996,7 @@ bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
         int start, int end, int irq)
     {
     	struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
    +	struct bwn_softc *sc = dr->dr_mac->mac_sc;
     	uint32_t addr, addrext, ctl;
     	int slot;
     
    @@ -4036,7 +4006,7 @@ bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
     
     	addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
     	addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
    -	addr |= siba_dma_translation(dr->dr_mac->mac_sd);
    +	addr |= siba_dma_translation(sc->sc_dev);
     	ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
     	if (slot == dr->dr_numslots - 1)
     		ctl |= BWN_DMA32_DCTL_DTABLEEND;
    @@ -4115,6 +4085,7 @@ bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
         int start, int end, int irq)
     {
     	struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
    +	struct bwn_softc *sc = dr->dr_mac->mac_sc;
     	int slot;
     	uint32_t ctl0 = 0, ctl1 = 0;
     	uint32_t addrlo, addrhi;
    @@ -4128,7 +4099,7 @@ bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
     	addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
     	addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
     	    30;
    -	addrhi |= (siba_dma_translation(dr->dr_mac->mac_sd) << 1);
    +	addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
     	if (slot == dr->dr_numslots - 1)
     		ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
     	if (start)
    @@ -4238,9 +4209,10 @@ bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
     static void
     bwn_dma_setup(struct bwn_dma_ring *dr)
     {
    +	struct bwn_softc *sc = dr->dr_mac->mac_sc;
     	uint64_t ring64;
     	uint32_t addrext, ring32, value;
    -	uint32_t trans = siba_dma_translation(dr->dr_mac->mac_sd);
    +	uint32_t trans = siba_dma_translation(sc->sc_dev);
     
     	if (dr->dr_tx) {
     		dr->dr_curslot = -1;
    @@ -4536,18 +4508,18 @@ bwn_spu_setdelay(struct bwn_mac *mac, int idle)
     static void
     bwn_bt_enable(struct bwn_mac *mac)
     {
    -	struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint64_t hf;
     
     	if (bwn_bluetooth == 0)
     		return;
    -	if ((sprom->bf_lo & BWN_BFL_BTCOEXIST) == 0)
    +	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
     		return;
     	if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
     		return;
     
     	hf = bwn_hf_read(mac);
    -	if (sprom->bf_lo & BWN_BFL_BTCMOD)
    +	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
     		hf |= BWN_HF_BT_COEXISTALT;
     	else
     		hf |= BWN_HF_BT_COEXIST;
    @@ -4584,25 +4556,25 @@ bwn_clear_keys(struct bwn_mac *mac)
     static void
     bwn_crypt_init(struct bwn_mac *mac)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     
    -	mac->mac_max_nr_keys = (mac->mac_sd->sd_id.sd_rev >= 5) ? 58 : 20;
    +	mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
     	KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
     	    ("%s:%d: fail", __func__, __LINE__));
     	mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
     	mac->mac_ktp *= 2;
    -	if (mac->mac_sd->sd_id.sd_rev >= 5) {
    -		BWN_WRITE_2(mac, BWN_RCMTA_COUNT,
    -		    mac->mac_max_nr_keys - 8);
    -	}
    +	if (siba_get_revid(sc->sc_dev) >= 5)
    +		BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
     	bwn_clear_keys(mac);
     }
     
     static void
     bwn_chip_exit(struct bwn_mac *mac)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     
     	bwn_phy_exit(mac);
    -	bwn_gpio_cleanup(mac);
    +	siba_gpio_set(sc->sc_dev, 0);
     }
     
     static int
    @@ -4622,33 +4594,31 @@ bwn_fw_fillinfo(struct bwn_mac *mac)
     static int
     bwn_gpio_init(struct bwn_mac *mac)
     {
    -	struct siba_softc *bus = mac->mac_sd->sd_bus;
    -	struct siba_dev_softc *sd;
    -	uint32_t mask = 0x0000001f, set = 0x0000000f;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint32_t mask = 0x1f, set = 0xf, value;
     
     	BWN_WRITE_4(mac, BWN_MACCTL,
     	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
     	BWN_WRITE_2(mac, BWN_GPIO_MASK,
     	    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
     
    -	if (bus->siba_chipid == 0x4301) {
    +	if (siba_get_chipid(sc->sc_dev) == 0x4301) {
     		mask |= 0x0060;
     		set |= 0x0060;
     	}
    -	if (bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) {
    +	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
     		BWN_WRITE_2(mac, BWN_GPIO_MASK,
     		    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
     		mask |= 0x0200;
     		set |= 0x0200;
     	}
    -	if (mac->mac_sd->sd_id.sd_rev >= 2)
    +	if (siba_get_revid(sc->sc_dev) >= 2)
     		mask |= 0x0010;
    -	sd = (bus->siba_cc.scc_dev != NULL) ? bus->siba_cc.scc_dev :
    -	    bus->siba_pci.spc_dev;
    -	if (sd == NULL)
    +
    +	value = siba_gpio_get(sc->sc_dev);
    +	if (value == -1)
     		return (0);
    -	siba_write_4(sd, BWN_GPIOCTL,
    -	    (siba_read_4(sd, BWN_GPIOCTL) & mask) | set);
    +	siba_gpio_set(sc->sc_dev, (value & mask) | set);
     
     	return (0);
     }
    @@ -4749,15 +4719,15 @@ bwn_set_opmode(struct bwn_mac *mac)
     		ctl &= ~BWN_MACCTL_STA;
     	ctl |= sc->sc_filters;
     
    -	if (mac->mac_sd->sd_id.sd_rev <= 4)
    +	if (siba_get_revid(sc->sc_dev) <= 4)
     		ctl |= BWN_MACCTL_PROMISC;
     
     	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
     
     	cfp_pretbtt = 2;
     	if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
    -		if (mac->mac_sd->sd_bus->siba_chipid == 0x4306 &&
    -		    mac->mac_sd->sd_bus->siba_chiprev == 3)
    +		if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
    +		    siba_get_chiprev(sc->sc_dev) == 3)
     			cfp_pretbtt = 100;
     		else
     			cfp_pretbtt = 50;
    @@ -4765,19 +4735,6 @@ bwn_set_opmode(struct bwn_mac *mac)
     	BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
     }
     
    -static void
    -bwn_gpio_cleanup(struct bwn_mac *mac)
    -{
    -	struct siba_softc *bus = mac->mac_sd->sd_bus;
    -	struct siba_dev_softc *gpiodev, *pcidev = NULL;
    -
    -	pcidev = bus->siba_pci.spc_dev;
    -	gpiodev = bus->siba_cc.scc_dev ? bus->siba_cc.scc_dev : pcidev;
    -	if (!gpiodev)
    -		return;
    -	siba_write_4(gpiodev, BWN_GPIOCTL, 0);
    -}
    -
     static int
     bwn_dma_gettype(struct bwn_mac *mac)
     {
    @@ -4810,6 +4767,7 @@ bwn_phy_g_init_sub(struct bwn_mac *mac)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint16_t i, tmp;
     
     	if (phy->rev == 1)
    @@ -4872,7 +4830,7 @@ bwn_phy_g_init_sub(struct bwn_mac *mac)
     		BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
     		    (pg->pg_loctl.tx_bias << 12));
     	}
    -	if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL)
    +	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
     		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
     	else
     		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
    @@ -4885,7 +4843,7 @@ bwn_phy_g_init_sub(struct bwn_mac *mac)
     		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
     	}
     
    -	if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) {
    +	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
     		for (i = 0; i < 64; i++) {
     			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
     			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
    @@ -4904,8 +4862,8 @@ bwn_phy_g_init_sub(struct bwn_mac *mac)
     	if (phy->rf_rev == 8)
     		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
     	bwn_phy_hwpctl_init(mac);
    -	if ((mac->mac_sd->sd_bus->siba_chipid == 0x4306
    -	     && mac->mac_sd->sd_bus->siba_chippkg == 2) || 0) {
    +	if ((siba_get_chipid(sc->sc_dev) == 0x4306
    +	     && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
     		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
     		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
     	}
    @@ -4923,16 +4881,16 @@ bwn_has_hwpctl(struct bwn_mac *mac)
     static void
     bwn_phy_init_b5(struct bwn_mac *mac)
     {
    -	struct siba_softc *bus = mac->mac_sd->sd_bus;
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint16_t offset, value;
     	uint8_t old_channel;
     
     	if (phy->analog == 1)
     		BWN_RF_SET(mac, 0x007a, 0x0050);
    -	if ((bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM) &&
    -	    (bus->siba_board_type != SIBA_BOARD_BU4306)) {
    +	if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
    +	    (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
     		value = 0x2120;
     		for (offset = 0x00a8; offset < 0x00c7; offset++) {
     			BWN_PHY_WRITE(mac, offset, value);
    @@ -5021,6 +4979,7 @@ bwn_loopback_calcgain(struct bwn_mac *mac)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint16_t backup_phy[16] = { 0 };
     	uint16_t backup_radio[3];
     	uint16_t backup_bband;
    @@ -5099,7 +5058,7 @@ bwn_loopback_calcgain(struct bwn_mac *mac)
     	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
     	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
     
    -	if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) {
    +	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
     		if (phy->rev >= 7) {
     			BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
     			BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
    @@ -5399,6 +5358,7 @@ bwn_phy_init_b6(struct bwn_mac *mac)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint16_t offset, val;
     	uint8_t old_channel;
     
    @@ -5428,7 +5388,7 @@ bwn_phy_init_b6(struct bwn_mac *mac)
     		BWN_RF_WRITE(mac, 0x5a, 0x88);
     		BWN_RF_WRITE(mac, 0x5b, 0x6b);
     		BWN_RF_WRITE(mac, 0x5c, 0x0f);
    -		if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_ALTIQ) {
    +		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
     			BWN_RF_WRITE(mac, 0x5d, 0xfa);
     			BWN_RF_WRITE(mac, 0x5e, 0xd8);
     		} else {
    @@ -5509,6 +5469,7 @@ static void
     bwn_phy_init_a(struct bwn_mac *mac)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_softc *sc = mac->mac_sc;
     
     	KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
     	    ("%s:%d: fail", __func__, __LINE__));
    @@ -5525,7 +5486,7 @@ bwn_phy_init_a(struct bwn_mac *mac)
     	bwn_wa_init(mac);
     
     	if (phy->type == BWN_PHYTYPE_G &&
    -	    (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL))
    +	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
     		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
     }
     
    @@ -5776,7 +5737,7 @@ static void
     bwn_wa_init(struct bwn_mac *mac)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
    -	struct siba_softc *bus = mac->mac_sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
     
     	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
     
    @@ -5795,9 +5756,9 @@ bwn_wa_init(struct bwn_mac *mac)
     		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
     	}
     
    -	if (bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM ||
    -	    bus->siba_board_type != SIBA_BOARD_BU4306 ||
    -	    bus->siba_board_rev != 0x17) {
    +	if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
    +	    siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
    +	    siba_get_pci_revid(sc->sc_dev) != 0x17) {
     		if (phy->rev < 2) {
     			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
     			    0x0002);
    @@ -5806,7 +5767,8 @@ bwn_wa_init(struct bwn_mac *mac)
     		} else {
     			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
     			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
    -			if ((bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) &&
    +			if ((siba_sprom_get_bf_lo(sc->sc_dev) &
    +			     BWN_BFL_EXTLNA) &&
     			    (phy->rev >= 7)) {
     				BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
     				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
    @@ -5824,7 +5786,7 @@ bwn_wa_init(struct bwn_mac *mac)
     			}
     		}
     	}
    -	if (bus->siba_sprom.bf_lo & BWN_BFL_FEM) {
    +	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
     		BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
     		BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
     	}
    @@ -5882,6 +5844,7 @@ static void
     bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_softc *sc = mac->mac_sc;
     	unsigned int i, max_loop;
     	uint16_t value;
     	uint32_t buffer[5] = {
    @@ -5903,7 +5866,7 @@ bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
     
     	BWN_WRITE_2(mac, 0x0568, 0x0000);
     	BWN_WRITE_2(mac, 0x07c0,
    -	    (mac->mac_sd->sd_id.sd_rev < 11) ? 0x0000 : 0x0100);
    +	    (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
     	value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
     	BWN_WRITE_2(mac, 0x050c, value);
     	if (phy->type == BWN_PHYTYPE_LP)
    @@ -5977,6 +5940,7 @@ bwn_lo_calcfeed(struct bwn_mac *mac,
         uint16_t lna, uint16_t pga, uint16_t trsw_rx)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint16_t rfover;
     	uint16_t feedthrough;
     
    @@ -5992,8 +5956,8 @@ bwn_lo_calcfeed(struct bwn_mac *mac,
     		trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
     
     		rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
    -		if ((mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA)
    -		    && phy->rev > 6)
    +		if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
    +		    phy->rev > 6)
     			rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
     
     		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
    @@ -6241,9 +6205,9 @@ bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
     static void
     bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
     {
    -	struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom;
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
    +	struct bwn_softc *sc = mac->mac_sc;
     	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
     	struct timespec ts;
     	uint16_t tmp;
    @@ -6281,7 +6245,8 @@ bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
     		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
     		if (phy->type == BWN_PHYTYPE_G) {
     			if ((phy->rev >= 7) &&
    -			    (sprom->bf_lo & BWN_BFL_EXTLNA)) {
    +			    (siba_sprom_get_bf_lo(sc->sc_dev) &
    +			     BWN_BFL_EXTLNA)) {
     				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
     			} else {
     				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
    @@ -6781,6 +6746,7 @@ bwn_mac_enable(struct bwn_mac *mac)
     static void
     bwn_psctl(struct bwn_mac *mac, uint32_t flags)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     	int i;
     	uint16_t ucstat;
     
    @@ -6795,7 +6761,7 @@ bwn_psctl(struct bwn_mac *mac, uint32_t flags)
     	    (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
     	    ~BWN_MACCTL_HWPS);
     	BWN_READ_4(mac, BWN_MACCTL);
    -	if (mac->mac_sd->sd_id.sd_rev >= 5) {
    +	if (siba_get_revid(sc->sc_dev) >= 5) {
     		for (i = 0; i < 100; i++) {
     			ucstat = bwn_shm_read_2(mac, BWN_SHARED,
     			    BWN_SHARED_UCODESTAT);
    @@ -6819,14 +6785,14 @@ bwn_nrssi_threshold(struct bwn_mac *mac)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
    -	struct siba_softc *siba = mac->mac_sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
     	int32_t a, b;
     	int16_t tmp16;
     	uint16_t tmpu16;
     
     	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
     
    -	if (phy->gmode && (siba->siba_sprom.bf_lo & BWN_BFL_RSSI)) {
    +	if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
     		if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
     			a = 0x13;
     			b = 0x12;
    @@ -7259,18 +7225,18 @@ bwn_set_original_gains(struct bwn_mac *mac)
     static void
     bwn_phy_hwpctl_init(struct bwn_mac *mac)
     {
    -	struct siba_softc *bus = mac->mac_sd->sd_bus;
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
     	struct bwn_rfatt old_rfatt, rfatt;
     	struct bwn_bbatt old_bbatt, bbatt;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint8_t old_txctl = 0;
     
     	KASSERT(phy->type == BWN_PHYTYPE_G,
     	    ("%s:%d: fail", __func__, __LINE__));
     
    -	if ((bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM) &&
    -	    (bus->siba_board_type == SIBA_BOARD_BU4306))
    +	if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
    +	    (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
     		return;
     
     	BWN_PHY_WRITE(mac, 0x0028, 0x8018);
    @@ -7407,7 +7373,7 @@ bwn_hwpctl_init_gphy(struct bwn_mac *mac)
     static void
     bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
     {
    -	struct siba_softc *siba = mac->mac_sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
     
     	if (spu != 0)
     		bwn_spu_workaround(mac, channel);
    @@ -7415,7 +7381,7 @@ bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
     	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
     
     	if (channel == 14) {
    -		if (siba->siba_sprom.ccode == SIBA_CCODE_JAPAN)
    +		if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
     			bwn_hf_write(mac,
     			    bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
     		else
    @@ -7500,7 +7466,7 @@ bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
     {
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct bwn_phy_g *pg = &phy->phy_g;
    -	struct siba_sprom *sprom = &(mac->mac_sd->sd_bus->siba_sprom);
    +	struct bwn_softc *sc = mac->mac_sc;
     	int max_lb_gain;
     	uint16_t extlna;
     	uint16_t i;
    @@ -7531,7 +7497,8 @@ bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
     				break;
     		}
     
    -		if ((phy->rev < 7) || !(sprom->bf_lo & BWN_BFL_EXTLNA)) {
    +		if ((phy->rev < 7) ||
    +		    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
     			if (reg == BWN_PHY_RFOVER) {
     				return (0x1b3);
     			} else if (reg == BWN_PHY_RFOVERVAL) {
    @@ -7575,7 +7542,7 @@ bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
     	}
     
     	if ((phy->rev < 7) ||
    -	    !(sprom->bf_lo & BWN_BFL_EXTLNA)) {
    +	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
     		if (reg == BWN_PHY_RFOVER) {
     			return (0x1b3);
     		} else if (reg == BWN_PHY_RFOVERVAL) {
    @@ -7632,7 +7599,7 @@ bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
     {
     	struct bwn_softc *sc = mac->mac_sc;
     	struct bwn_fw *fw = &mac->mac_fw;
    -	const uint8_t rev = mac->mac_sd->sd_id.sd_rev;
    +	const uint8_t rev = siba_get_revid(sc->sc_dev);
     	const char *filename;
     	uint32_t high;
     	int error;
    @@ -7675,7 +7642,7 @@ bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
     	}
     
     	/* initvals */
    -	high = siba_read_4(mac->mac_sd, SIBA_TGSHIGH);
    +	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
     	switch (mac->mac_phy.type) {
     	case BWN_PHYTYPE_A:
     		if (rev < 5 || rev > 10)
    @@ -8206,6 +8173,7 @@ bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
     static void
     bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint32_t addrtmp[2] = { 0, 0 };
     	uint8_t start = 8;
     
    @@ -8225,7 +8193,7 @@ bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
     		addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
     	}
     
    -	if (mac->mac_sd->sd_id.sd_rev >= 5) {
    +	if (siba_get_revid(sc->sc_dev) >= 5) {
     		bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
     		bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
     	} else {
    @@ -8396,14 +8364,14 @@ bwn_rf_turnoff(struct bwn_mac *mac)
     static void
     bwn_phy_reset(struct bwn_mac *mac)
     {
    -	struct siba_dev_softc *sd = mac->mac_sd;
    +	struct bwn_softc *sc = mac->mac_sc;
     
    -	siba_write_4(sd, SIBA_TGSLOW,
    -	    ((siba_read_4(sd, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
    +	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
    +	    ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
     	     BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
     	DELAY(1000);
    -	siba_write_4(sd, SIBA_TGSLOW,
    -	    (siba_read_4(sd, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
    +	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
    +	    (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
     	    BWN_TGSLOW_PHYRESET);
     	DELAY(1000);
     }
    @@ -8486,10 +8454,10 @@ bwn_intr(void *arg)
     {
     	struct bwn_mac *mac = arg;
     	struct bwn_softc *sc = mac->mac_sc;
    -	struct siba_softc *siba = mac->mac_sd->sd_bus;
     	uint32_t reason;
     
    -	if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid)
    +	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
    +	    (sc->sc_flags & BWN_FLAG_INVALID))
     		return (FILTER_STRAY);
     
     	reason = BWN_READ_4(mac, BWN_INTR_REASON);
    @@ -8529,12 +8497,12 @@ bwn_intrtask(void *arg, int npending)
     	struct bwn_mac *mac = arg;
     	struct bwn_softc *sc = mac->mac_sc;
     	struct ifnet *ifp = sc->sc_ifp;
    -	struct siba_softc *siba = mac->mac_sd->sd_bus;
     	uint32_t merged = 0;
     	int i, tx = 0, rx = 0;
     
     	BWN_LOCK(sc);
    -	if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) {
    +	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
    +	    (sc->sc_flags & BWN_FLAG_INVALID)) {
     		BWN_UNLOCK(sc);
     		return;
     	}
    @@ -9176,10 +9144,10 @@ bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
     	return (1);
     ready:
     	if (prq->prq_rev >= 8)
    -		siba_read_multi_4(mac->mac_sd, &rxhdr, sizeof(rxhdr),
    +		siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
     		    prq->prq_base + BWN_PIO8_RXDATA);
     	else
    -		siba_read_multi_2(mac->mac_sd, &rxhdr, sizeof(rxhdr),
    +		siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
     		    prq->prq_base + BWN_PIO_RXDATA);
     	len = le16toh(rxhdr.frame_len);
     	if (len > 0x700) {
    @@ -9208,7 +9176,7 @@ ready:
     	}
     	mp = mtod(m, unsigned char *);
     	if (prq->prq_rev >= 8) {
    -		siba_read_multi_4(mac->mac_sd, mp + padding, (len & ~3),
    +		siba_read_multi_4(sc->sc_dev, mp + padding, (len & ~3),
     		    prq->prq_base + BWN_PIO8_RXDATA);
     		if (len & 3) {
     			v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
    @@ -9225,7 +9193,7 @@ ready:
     			}
     		}
     	} else {
    -		siba_read_multi_2(mac->mac_sd, mp + padding, (len & ~1),
    +		siba_read_multi_2(sc->sc_dev, mp + padding, (len & ~1),
     		    prq->prq_base + BWN_PIO_RXDATA);
     		if (len & 1) {
     			v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
    @@ -9578,7 +9546,6 @@ bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
     	struct bwn_phy *phy = &mac->mac_phy;
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
    -	struct siba_softc *siba = mac->mac_sd->sd_bus;
     	unsigned long now;
     	int result;
     
    @@ -9588,8 +9555,8 @@ bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
     		return;
     	phy->nexttime = now + 2 * 1000;
     
    -	if (siba->siba_board_vendor == SIBA_BOARDVENDOR_BCM &&
    -	    siba->siba_board_type == SIBA_BOARD_BU4306)
    +	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
    +	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
     		return;
     
     	if (phy->recalc_txpwr != NULL) {
    @@ -9902,14 +9869,15 @@ bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
     static uint8_t
     bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint8_t mask;
     
     	if (n == 0)
     		return (0);
     	if (mac->mac_phy.gmode)
    -		mask = mac->mac_sd->sd_bus->siba_sprom.ant_bg;
    +		mask = siba_sprom_get_ant_bg(sc->sc_dev);
     	else
    -		mask = mac->mac_sd->sd_bus->siba_sprom.ant_a;
    +		mask = siba_sprom_get_ant_a(sc->sc_dev);
     	if (!(mask & (1 << (n - 1))))
     		return (0);
     	return (n);
    @@ -9952,6 +9920,7 @@ static uint32_t
     bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
         uint32_t ctl, const void *_data, int len)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint32_t value = 0;
     	const uint8_t *data = _data;
     
    @@ -9959,7 +9928,7 @@ bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
     	    BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
     	bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
     
    -	siba_write_multi_4(mac->mac_sd, data, (len & ~3),
    +	siba_write_multi_4(sc->sc_dev, data, (len & ~3),
     	    tq->tq_base + BWN_PIO8_TXDATA);
     	if (len & 3) {
     		ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
    @@ -9996,12 +9965,13 @@ static uint16_t
     bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
         uint16_t ctl, const void *_data, int len)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     	const uint8_t *data = _data;
     
     	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
     	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
     
    -	siba_write_multi_2(mac->mac_sd, data, (len & ~1),
    +	siba_write_multi_2(sc->sc_dev, data, (len & ~1),
     	    tq->tq_base + BWN_PIO_TXDATA);
     	if (len & 1) {
     		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
    @@ -10180,8 +10150,8 @@ bwn_phy_lock(struct bwn_mac *mac)
     	struct bwn_softc *sc = mac->mac_sc;
     	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
     
    -	KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
    -	    ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev));
    +	KASSERT(siba_get_revid(sc->sc_dev) >= 3,
    +	    ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
     
     	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
     		bwn_psctl(mac, BWN_PS_AWAKE);
    @@ -10193,8 +10163,8 @@ bwn_phy_unlock(struct bwn_mac *mac)
     	struct bwn_softc *sc = mac->mac_sc;
     	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
     
    -	KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
    -	    ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev));
    +	KASSERT(siba_get_revid(sc->sc_dev) >= 3,
    +	    ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
     
     	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
     		bwn_psctl(mac, 0);
    @@ -10413,7 +10383,7 @@ bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
     {
     	uint32_t low, high;
     
    -	KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
    +	KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
     	    ("%s:%d: fail", __func__, __LINE__));
     
     	low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
    @@ -10428,15 +10398,13 @@ bwn_dma_attach(struct bwn_mac *mac)
     {
     	struct bwn_dma *dma = &mac->mac_method.dma;
     	struct bwn_softc *sc = mac->mac_sc;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	bus_addr_t lowaddr = 0;
     	int error;
     
    -	if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
    +	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
     		return (0);
     
    -	KASSERT(mac->mac_sd->sd_id.sd_rev >= 5, ("%s: fail", __func__));
    +	KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
     
     	mac->mac_flags |= BWN_MAC_FLAG_DMA;
     
    @@ -10635,7 +10603,6 @@ static void
     bwn_led_attach(struct bwn_mac *mac)
     {
     	struct bwn_softc *sc = mac->mac_sc;
    -	struct siba_softc *siba = mac->mac_sd->sd_bus;
     	const uint8_t *led_act = NULL;
     	uint16_t val[BWN_LED_MAX];
     	int i;
    @@ -10644,7 +10611,8 @@ bwn_led_attach(struct bwn_mac *mac)
     	sc->sc_led_blink = 1;
     
     	for (i = 0; i < N(bwn_vendor_led_act); ++i) {
    -		if (siba->siba_pci_subvid == bwn_vendor_led_act[i].vid) {
    +		if (siba_get_pci_subvendor(sc->sc_dev) ==
    +		    bwn_vendor_led_act[i].vid) {
     			led_act = bwn_vendor_led_act[i].led_act;
     			break;
     		}
    @@ -10652,10 +10620,10 @@ bwn_led_attach(struct bwn_mac *mac)
     	if (led_act == NULL)
     		led_act = bwn_default_led_act;
     
    -	val[0] = siba->siba_sprom.gpio0;
    -	val[1] = siba->siba_sprom.gpio1;
    -	val[2] = siba->siba_sprom.gpio2;
    -	val[3] = siba->siba_sprom.gpio3;
    +	val[0] = siba_sprom_get_gpio0(sc->sc_dev);
    +	val[1] = siba_sprom_get_gpio1(sc->sc_dev);
    +	val[2] = siba_sprom_get_gpio2(sc->sc_dev);
    +	val[3] = siba_sprom_get_gpio3(sc->sc_dev);
     
     	for (i = 0; i < BWN_LED_MAX; ++i) {
     		struct bwn_led *led = &sc->sc_leds[i];
    @@ -10771,82 +10739,82 @@ static void
     bwn_led_event(struct bwn_mac *mac, int event)
     {
     	struct bwn_softc *sc = mac->mac_sc;
    -        struct bwn_led *led = sc->sc_blink_led;
    -        int rate;
    +	struct bwn_led *led = sc->sc_blink_led;
    +	int rate;
     
    -        if (event == BWN_LED_EVENT_POLL) {
    -                if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
    -                        return;
    -                if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
    -                        return;
    -        }
    +	if (event == BWN_LED_EVENT_POLL) {
    +		if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
    +			return;
    +		if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
    +			return;
    +	}
     
    -        sc->sc_led_ticks = ticks;
    -        if (sc->sc_led_blinking)
    -                return;
    +	sc->sc_led_ticks = ticks;
    +	if (sc->sc_led_blinking)
    +		return;
     
    -        switch (event) {
    -        case BWN_LED_EVENT_RX:
    -                rate = sc->sc_rx_rate;
    -                break;
    -        case BWN_LED_EVENT_TX:
    -                rate = sc->sc_tx_rate;
    -                break;
    -        case BWN_LED_EVENT_POLL:
    -                rate = 0;
    -                break;
    -        default:
    -                panic("unknown LED event %d\n", event);
    -                break;
    -        }
    -        bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
    -            bwn_led_duration[rate].off_dur);
    +	switch (event) {
    +	case BWN_LED_EVENT_RX:
    +		rate = sc->sc_rx_rate;
    +		break;
    +	case BWN_LED_EVENT_TX:
    +		rate = sc->sc_tx_rate;
    +		break;
    +	case BWN_LED_EVENT_POLL:
    +		rate = 0;
    +		break;
    +	default:
    +		panic("unknown LED event %d\n", event);
    +		break;
    +	}
    +	bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
    +	    bwn_led_duration[rate].off_dur);
     }
     
     static void
     bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
     {
     	struct bwn_softc *sc = mac->mac_sc;
    -        struct bwn_led *led = sc->sc_blink_led;
    -        uint16_t val;
    +	struct bwn_led *led = sc->sc_blink_led;
    +	uint16_t val;
     
    -        val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
    -        val = bwn_led_onoff(led, val, 1);
    -        BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
    +	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
    +	val = bwn_led_onoff(led, val, 1);
    +	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
     
    -        if (led->led_flags & BWN_LED_F_SLOW) {
    -                BWN_LED_SLOWDOWN(on_dur);
    -                BWN_LED_SLOWDOWN(off_dur);
    -        }
    +	if (led->led_flags & BWN_LED_F_SLOW) {
    +		BWN_LED_SLOWDOWN(on_dur);
    +		BWN_LED_SLOWDOWN(off_dur);
    +	}
     
    -        sc->sc_led_blinking = 1;
    -        sc->sc_led_blink_offdur = off_dur;
    +	sc->sc_led_blinking = 1;
    +	sc->sc_led_blink_offdur = off_dur;
     
    -        callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
    +	callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
     }
     
     static void
     bwn_led_blink_next(void *arg)
     {
     	struct bwn_mac *mac = arg;
    -        struct bwn_softc *sc = mac->mac_sc;
    -        uint16_t val;
    +	struct bwn_softc *sc = mac->mac_sc;
    +	uint16_t val;
     
    -        val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
    -        val = bwn_led_onoff(sc->sc_blink_led, val, 0);
    -        BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
    +	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
    +	val = bwn_led_onoff(sc->sc_blink_led, val, 0);
    +	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
     
    -        callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
    -            bwn_led_blink_end, mac);
    +	callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
    +	    bwn_led_blink_end, mac);
     }
     
     static void
     bwn_led_blink_end(void *arg)
     {
     	struct bwn_mac *mac = arg;
    -        struct bwn_softc *sc = mac->mac_sc;
    +	struct bwn_softc *sc = mac->mac_sc;
     
    -        sc->sc_led_blinking = 0;
    +	sc->sc_led_blinking = 0;
     }
     
     static int
    @@ -11101,8 +11069,6 @@ bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
     
    -	device_printf(sc->sc_dev, "correct?\n");
    -
     	return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
     }
     
    @@ -11136,31 +11102,25 @@ bwn_phy_lp_readsprom(struct bwn_mac *mac)
     	struct bwn_softc *sc = mac->mac_sc;
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
    -	struct siba_sprom *sprom = &siba->siba_sprom;
    -
    -	device_printf(sc->sc_dev, "XXX using %dghz\n",
    -	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 2 : 5);
     
     	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
    -		plp->plp_txisoband_m = sprom->tri2g;
    -		plp->plp_bxarch = sprom->bxa2g;
    -		plp->plp_rxpwroffset = sprom->rxpo2g;
    -		plp->plp_rssivf = sprom->rssismf2g;
    -		plp->plp_rssivc = sprom->rssismc2g;
    -		plp->plp_rssigs = sprom->rssisav2g;
    +		plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
    +		plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
    +		plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
    +		plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
    +		plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
    +		plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
     		return;
     	}
     
    -	plp->plp_txisoband_l = sprom->tri5gl;
    -	plp->plp_txisoband_m = sprom->tri5g;
    -	plp->plp_txisoband_h = sprom->tri5gh;
    -	plp->plp_bxarch = sprom->bxa5g;
    -	plp->plp_rxpwroffset = sprom->rxpo5g;
    -	plp->plp_rssivf = sprom->rssismf5g;
    -	plp->plp_rssivc = sprom->rssismc5g;
    -	plp->plp_rssigs = sprom->rssisav5g;
    +	plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
    +	plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
    +	plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
    +	plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
    +	plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
    +	plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
    +	plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
    +	plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
     }
     
     static void
    @@ -11192,8 +11152,6 @@ static void
     bwn_phy_lp_calib(struct bwn_mac *mac)
     {
     	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	struct bwn_softc *sc = mac->mac_sc;
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
    @@ -11240,7 +11198,7 @@ bwn_phy_lp_calib(struct bwn_mac *mac)
     		bwn_phy_lp_digflt_restore(mac);
     
     	/* do RX IQ Calculation; assumes that noise is true. */
    -	if (siba->siba_chipid == 0x5354) {
    +	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
     		for (i = 0; i < N(bwn_rxcompco_5354); i++) {
     			if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
     				rc = &bwn_rxcompco_5354[i];
    @@ -11306,21 +11264,20 @@ static void
     bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
     {
     
    -       if (on) {
    -               BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
    -	       return;
    -       }
    +	if (on) {
    +		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
    +		return;
    +	}
     
    -       BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
    -       BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
    +	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
    +	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
     }
     
     static int
     bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
     {
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	static const struct bwn_b206x_chan *bc = NULL;
    +	struct bwn_softc *sc = mac->mac_sc;
     	uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
     	    tmp[6];
     	uint16_t old, scale, tmp16;
    @@ -11351,7 +11308,7 @@ bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
     	old = BWN_RF_READ(mac, BWN_B2063_COM15);
     	BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
     
    -	freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
    +	freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
     	freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
     	freqref = freqxtal * 3;
     	div = (freqxtal <= 26000000 ? 1 : 2);
    @@ -11449,11 +11406,10 @@ bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
     static int
     bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
     {
    +	struct bwn_softc *sc = mac->mac_sc;
     	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	const struct bwn_b206x_chan *bc = NULL;
    -	uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
    +	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
     	uint32_t tmp[9];
     	int i;
     
    @@ -11815,8 +11771,6 @@ static void
     bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
     {
     	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	struct bwn_softc *sc = mac->mac_sc;
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
    @@ -11848,7 +11802,7 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
     		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
     		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
     		{ BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
    -		
    +
     	};
     	int i;
     
    @@ -11861,7 +11815,7 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
     	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
     	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
     	BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
    -	if (siba->siba_board_rev >= 0x18) {
    +	if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
     		bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
     		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
     	} else {
    @@ -11878,7 +11832,8 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
     	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
     	BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
     	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
    -	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
    +	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
    +	    (siba_get_chiprev(sc->sc_dev) == 0)) {
     		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
     		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
     	} else {
    @@ -11887,7 +11842,8 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
     	}
     	for (i = 0; i < N(v3); i++)
     		BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
    -	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
    +	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
    +	    (siba_get_chiprev(sc->sc_dev) == 0)) {
     		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
     		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
     	}
    @@ -11912,7 +11868,8 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
     	    0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
     	    ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
     
    -	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
    +	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
    +	    (siba_get_chiprev(sc->sc_dev) == 0)) {
     		BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
     		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
     		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
    @@ -11925,8 +11882,6 @@ static void
     bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
     {
     	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	struct bwn_softc *sc = mac->mac_sc;
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
    @@ -12009,23 +11964,23 @@ bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
     		BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
     	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
     	    0xff00, plp->plp_rxpwroffset);
    -	if ((siba->siba_sprom.bf_lo & BWN_BFL_FEM) &&
    +	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
     	    ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
    -	   (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF))) {
    -		siba_cc_pmu_set_ldovolt(&siba->siba_cc, SIBA_LDO_PAREF, 0x28);
    -		siba_cc_pmu_set_ldoparef(&siba->siba_cc, 1);
    +	   (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
    +		siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
    +		siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
     		if (mac->mac_phy.rev == 0)
     			BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
     			    0xffcf, 0x0010);
     		bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
     	} else {
    -		siba_cc_pmu_set_ldoparef(&siba->siba_cc, 0);
    +		siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
     		BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
     		bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
     	}
     	tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
     	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
    -	if (siba->siba_sprom.bf_hi & BWN_BFH_RSSIINV)
    +	if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
     		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
     	else
     		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
    @@ -12033,18 +11988,19 @@ bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
     	BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
     	    0xfff9, (plp->plp_bxarch << 1));
     	if (mac->mac_phy.rev == 1 &&
    -	    (siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT)) {
    +	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
     		for (i = 0; i < N(v2); i++)
     			BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
     			    v2[i].set);
     	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
    -	    (siba->siba_board_type == 0x048a) || ((mac->mac_phy.rev == 0) &&
    -	    (siba->siba_sprom.bf_lo & BWN_BFL_FEM))) {
    +	    (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
    +	    ((mac->mac_phy.rev == 0) &&
    +	     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
     		for (i = 0; i < N(v3); i++)
     			BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
     			    v3[i].set);
     	} else if (mac->mac_phy.rev == 1 ||
    -		  (siba->siba_sprom.bf_lo & BWN_BFL_FEM)) {
    +		  (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
     		for (i = 0; i < N(v4); i++)
     			BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
     			    v4[i].set);
    @@ -12054,15 +12010,15 @@ bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
     			    v5[i].set);
     	}
     	if (mac->mac_phy.rev == 1 &&
    -	    (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF)) {
    +	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
     		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
     		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
     		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
     		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
     	}
    -	if ((siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT) &&
    -	    (siba->siba_chipid == 0x5354) &&
    -	    (siba->siba_chippkg == SIBA_CHIPPACK_BCM4712S)) {
    +	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
    +	    (siba_get_chipid(sc->sc_dev) == 0x5354) &&
    +	    (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
     		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
     		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
     		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
    @@ -12112,8 +12068,6 @@ bwn_phy_lp_b2062_init(struct bwn_mac *mac)
     #define	CALC_CTL19(freq, div)						\
     	((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
     	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	struct bwn_softc *sc = mac->mac_sc;
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
    @@ -12151,9 +12105,9 @@ bwn_phy_lp_b2062_init(struct bwn_mac *mac)
     	else
     		BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
     
    -	KASSERT(siba->siba_cc.scc_caps & SIBA_CC_CAPS_PMU,
    +	KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
     	    ("%s:%d: fail", __func__, __LINE__));
    -	xtalfreq = siba->siba_cc.scc_pmu.freq * 1000;
    +	xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
     	KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
     
     	if (xtalfreq <= 30000000) {
    @@ -12217,8 +12171,7 @@ bwn_phy_lp_b2063_init(struct bwn_mac *mac)
     static void
     bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
     {
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
     	static const struct bwn_wpair v1[] = {
     		{ BWN_B2063_RX_BB_SP8, 0x0 },
     		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
    @@ -12236,7 +12189,7 @@ bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
     		{ BWN_B2063_RC_CALIB_CTL2, 0x55 },
     		{ BWN_B2063_RC_CALIB_CTL3, 0x76 }
     	};
    -	uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
    +	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
     	int i;
     	uint8_t tmp;
     
    @@ -12435,12 +12388,11 @@ bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
     static void
     bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
     {
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
     
     	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
     	DELAY(20);
    -	if (siba->siba_chipid == 0x5354) {
    +	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
     		BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
     		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
     	} else {
    @@ -13146,8 +13098,7 @@ bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
     static void
     bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
     {
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
    +	struct bwn_softc *sc = mac->mac_sc;
     	int i;
     	static const uint16_t noisescale[] = {
     		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
    @@ -13355,7 +13306,8 @@ bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
     	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
     	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
     
    -	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
    +	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
    +	    (siba_get_chiprev(sc->sc_dev) == 0)) {
     		bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
     		    gainidx_a0);
     		bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
    @@ -13369,8 +13321,6 @@ bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
     static void
     bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
     {
    -	struct siba_dev_softc *sd = mac->mac_sd;
    -	struct siba_softc *siba = sd->sd_bus;
     	struct bwn_softc *sc = mac->mac_sc;
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
    @@ -13975,7 +13925,7 @@ bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
     	};
     
     	if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
    -		if (siba->siba_sprom.bf_hi & BWN_BFH_NOPA)
    +		if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
     			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
     		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
     			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
    @@ -13987,8 +13937,8 @@ bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
     	}
     
     	if (mac->mac_phy.rev == 0) {
    -		if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) ||
    -		    (siba->siba_sprom.bf_lo & BWN_BFL_HGPA))
    +		if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
    +		    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
     			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
     		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
     			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
    @@ -13999,8 +13949,8 @@ bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
     		return;
     	}
     
    -	if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) ||
    -	    (siba->siba_sprom.bf_lo & BWN_BFL_HGPA))
    +	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
    +	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
     		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
     	else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
     		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
    @@ -14319,7 +14269,7 @@ static device_method_t bwn_methods[] = {
     	DEVMETHOD(device_detach,	bwn_detach),
     	DEVMETHOD(device_suspend,	bwn_suspend),
     	DEVMETHOD(device_resume,	bwn_resume),
    -	{ 0,0 }
    +	KOBJMETHOD_END
     };
     static driver_t bwn_driver = {
     	"bwn",
    diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h
    index 61598c2f390..16934c3e39e 100644
    --- a/sys/dev/bwn/if_bwnvar.h
    +++ b/sys/dev/bwn/if_bwnvar.h
    @@ -65,14 +65,16 @@ struct bwn_mac;
     	((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
     #define	BWN_DMA_COOKIE(dr, slot)					\
     	((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
    -#define	BWN_READ_2(mac, o)		(siba_read_2(mac->mac_sd, o))
    -#define	BWN_READ_4(mac, o)		(siba_read_4(mac->mac_sd, o))
    -#define	BWN_WRITE_2(mac, o, v)		(siba_write_2(mac->mac_sd, o, v))
    -#define	BWN_WRITE_4(mac, o, v)		(siba_write_4(mac->mac_sd, o, v))
    +#define	BWN_READ_2(mac, o)		(siba_read_2(mac->mac_sc->sc_dev, o))
    +#define	BWN_READ_4(mac, o)		(siba_read_4(mac->mac_sc->sc_dev, o))
    +#define	BWN_WRITE_2(mac, o, v)						\
    +	(siba_write_2(mac->mac_sc->sc_dev, o, v))
    +#define	BWN_WRITE_4(mac, o, v)						\
    +	(siba_write_4(mac->mac_sc->sc_dev, o, v))
     #define	BWN_PIO_TXQOFFSET(mac)						\
    -	((mac->mac_sd->sd_id.sd_rev >= 11) ? 0x18 : 0)
    +	((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0)
     #define	BWN_PIO_RXQOFFSET(mac)						\
    -	((mac->mac_sd->sd_id.sd_rev >= 11) ? 0x38 : 8)
    +	((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x38 : 8)
     #define	BWN_SEC_NEWAPI(mac)		(mac->mac_fw.rev >= 351)
     #define	BWN_SEC_KEY2FW(mac, idx)					\
     	(BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx))
    @@ -141,7 +143,7 @@ struct bwn_mac;
     	(rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB ||	\
     	 rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
     #define	BWN_ISOFDMRATE(rate)		(!BWN_ISCCKRATE(rate))
    -#define	BWN_BARRIER(mac, flags)		siba_barrier(mac->mac_sd, flags)
    +#define	BWN_BARRIER(mac, flags)		siba_barrier(mac->mac_sc->sc_dev, flags)
     #define	BWN_DMA_READ(dr, offset)				\
     	(BWN_READ_4(dr->dr_mac, dr->dr_base + offset))
     #define	BWN_DMA_WRITE(dr, offset, value)			\
    @@ -835,7 +837,6 @@ struct bwn_led {
     
     struct bwn_mac {
     	struct bwn_softc		*mac_sc;
    -	struct siba_dev_softc		*mac_sd;
     	unsigned			mac_status;
     #define	BWN_MAC_STATUS_UNINIT		0
     #define	BWN_MAC_STATUS_INITED		1
    @@ -902,7 +903,6 @@ struct bwn_vap {
     
     struct bwn_softc {
     	device_t			sc_dev;
    -	struct siba_dev_softc		*sc_sd;
     	struct mtx			sc_mtx;
     	struct ifnet			*sc_ifp;
     	unsigned			sc_flags;
    diff --git a/sys/dev/siba/siba.c b/sys/dev/siba/siba.c
    index 541585b47e7..4ee11ca24a4 100644
    --- a/sys/dev/siba/siba.c
    +++ b/sys/dev/siba/siba.c
    @@ -632,7 +632,7 @@ static device_method_t siba_methods[] = {
     	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
     	DEVMETHOD(bus_write_ivar,	siba_write_ivar),
     
    -	{0, 0},
    +	KOBJMETHOD_END
     };
     
     static driver_t siba_driver = {
    diff --git a/sys/dev/siba/siba_bwn.c b/sys/dev/siba/siba_bwn.c
    index f33f9b3c52c..b335484d4d7 100644
    --- a/sys/dev/siba/siba_bwn.c
    +++ b/sys/dev/siba/siba_bwn.c
    @@ -152,6 +152,7 @@ siba_bwn_attach(device_t dev)
     	siba->siba_pci_vid = pci_get_vendor(dev);
     	siba->siba_pci_subvid = pci_get_subvendor(dev);
     	siba->siba_pci_subdid = pci_get_subdevice(dev);
    +	siba->siba_pci_revid = pci_get_revid(dev);
     
     	return (siba_core_attach(siba));
     }
    @@ -321,6 +322,71 @@ siba_bwn_msi_count(device_t dev, device_t child)
     	return (pci_msi_count(dev));
     }
     
    +static int
    +siba_bwn_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
    +{
    +	struct siba_dev_softc *sd;
    +	struct siba_softc *siba;;
    +
    +	sd = device_get_ivars(child);
    +	siba = sd->sd_bus;
    +
    +	switch (which) {
    +	case SIBA_IVAR_VENDOR:
    +		*result = sd->sd_id.sd_vendor;
    +		break;
    +	case SIBA_IVAR_DEVICE:
    +		*result = sd->sd_id.sd_device;
    +		break;
    +	case SIBA_IVAR_REVID:
    +		*result = sd->sd_id.sd_rev;
    +		break;
    +	case SIBA_IVAR_PCI_VENDOR:
    +		*result = siba->siba_pci_vid;
    +		break;
    +	case SIBA_IVAR_PCI_DEVICE:
    +		*result = siba->siba_pci_did;
    +		break;
    +	case SIBA_IVAR_PCI_SUBVENDOR:
    +		*result = siba->siba_pci_subvid;
    +		break;
    +	case SIBA_IVAR_PCI_SUBDEVICE:
    +		*result = siba->siba_pci_subdid;
    +		break;
    +	case SIBA_IVAR_PCI_REVID:
    +		*result = siba->siba_pci_revid;
    +		break;
    +	case SIBA_IVAR_CHIPID:
    +		*result = siba->siba_chipid;
    +		break;
    +	case SIBA_IVAR_CHIPREV:
    +		*result = siba->siba_chiprev;
    +		break;
    +	case SIBA_IVAR_CHIPPKG:
    +		*result = siba->siba_chippkg;
    +		break;
    +	case SIBA_IVAR_TYPE:
    +		*result = siba->siba_type;
    +		break;
    +	case SIBA_IVAR_CC_PMUFREQ:
    +		*result = siba->siba_cc.scc_pmu.freq;
    +		break;
    +	case SIBA_IVAR_CC_CAPS:
    +		*result = siba->siba_cc.scc_caps;
    +		break;
    +	case SIBA_IVAR_CC_POWERDELAY:
    +		*result = siba->siba_cc.scc_powerup_delay;
    +		break;
    +	case SIBA_IVAR_PCICORE_REVID:
    +		*result = siba->siba_pci.spc_dev->sd_id.sd_rev;
    +		break;
    +	default:
    +		return (ENOENT);
    +	}
    +
    +	return (0);
    +}
    +
     static device_method_t siba_bwn_methods[] = {
     	/* Device interface */
     	DEVMETHOD(device_probe,		siba_bwn_probe),
    @@ -333,6 +399,7 @@ static device_method_t siba_bwn_methods[] = {
     	/* Bus interface */
     	DEVMETHOD(bus_alloc_resource,   siba_bwn_alloc_resource),
     	DEVMETHOD(bus_release_resource, siba_bwn_release_resource),
    +	DEVMETHOD(bus_read_ivar,	siba_bwn_read_ivar),
     	DEVMETHOD(bus_setup_intr,       siba_bwn_setup_intr),
     	DEVMETHOD(bus_teardown_intr,    siba_bwn_teardown_intr),
     
    @@ -342,7 +409,7 @@ static device_method_t siba_bwn_methods[] = {
     	DEVMETHOD(pci_release_msi,	siba_bwn_release_msi),
     	DEVMETHOD(pci_msi_count,	siba_bwn_msi_count),
     
    -	{ 0,0 }
    +	KOBJMETHOD_END
     };
     static driver_t siba_bwn_driver = {
     	"siba_bwn",
    diff --git a/sys/dev/siba/siba_cc.c b/sys/dev/siba/siba_cc.c
    index db0aac507be..67af696fba7 100644
    --- a/sys/dev/siba/siba_cc.c
    +++ b/sys/dev/siba/siba_cc.c
    @@ -141,7 +141,7 @@ static device_method_t siba_cc_methods[] = {
     	DEVMETHOD(device_attach,	siba_cc_attach),
     	DEVMETHOD(device_probe,		siba_cc_probe),
     
    -	{0, 0},
    +	KOBJMETHOD_END
     };
     
     static driver_t siba_cc_driver = {
    diff --git a/sys/dev/siba/siba_core.c b/sys/dev/siba/siba_core.c
    index 748b426b7a9..979ac1406a6 100644
    --- a/sys/dev/siba/siba_core.c
    +++ b/sys/dev/siba/siba_core.c
    @@ -133,6 +133,13 @@ static void	siba_pci_write_multi_4(struct siba_dev_softc *, const void *,
     		    size_t, uint16_t);
     static const char *siba_core_name(uint16_t);
     static void	siba_pcicore_init(struct siba_pci *);
    +static uint32_t	siba_read_4_sub(struct siba_dev_softc *, uint16_t);
    +static void	siba_write_4_sub(struct siba_dev_softc *, uint16_t, uint32_t);
    +static void	siba_powerup_sub(struct siba_softc *, int);
    +static int	siba_powerdown_sub(struct siba_softc *);
    +static int	siba_dev_isup_sub(struct siba_dev_softc *);
    +static void	siba_dev_up_sub(struct siba_dev_softc *, uint32_t);
    +static void	siba_dev_down_sub(struct siba_dev_softc *, uint32_t);
     int		siba_core_attach(struct siba_softc *);
     int		siba_core_detach(struct siba_softc *);
     int		siba_core_suspend(struct siba_softc *);
    @@ -181,7 +188,7 @@ siba_core_attach(struct siba_softc *siba)
     
     	/* XXX init PCI or PCMCIA host devices */
     
    -	siba_powerup(siba, 0);
    +	siba_powerup_sub(siba, 0);
     
     	/* init ChipCommon */
     	scc = &siba->siba_cc;
    @@ -192,21 +199,15 @@ siba_core_attach(struct siba_softc *siba)
     		siba_cc_powerup_delay(scc);
     	}
     
    -	/* fetch various internal informations for PCI */
    -	siba->siba_board_vendor = pci_read_config(siba->siba_dev,
    -	    PCIR_SUBVEND_0, 2);
    -	siba->siba_board_type = pci_read_config(siba->siba_dev, PCIR_SUBDEV_0,
    -	    2);
    -	siba->siba_board_rev = pci_read_config(siba->siba_dev, PCIR_REVID, 2);
     	error = siba_pci_sprom(siba, &siba->siba_sprom);
     	if (error) {
    -		siba_powerdown(siba);
    +		siba_powerdown_sub(siba);
     		return (error);
     	}
     
     	siba_pcicore_init(&siba->siba_pci);
    -	siba_powerdown(siba);
    -	
    +	siba_powerdown_sub(siba);
    +
     	return (bus_generic_attach(siba->siba_dev));
     }
     
    @@ -746,7 +747,16 @@ siba_pci_write_multi_4(struct siba_dev_softc *sd, const void *buffer,
     }
     
     void
    -siba_powerup(struct siba_softc *siba, int dynamic)
    +siba_powerup(device_t dev, int dynamic)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	siba_powerup_sub(siba, dynamic);
    +}
    +
    +static void
    +siba_powerup_sub(struct siba_softc *siba, int dynamic)
     {
     
     	siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 1);
    @@ -802,77 +812,101 @@ siba_cc_clock(struct siba_cc *scc, enum siba_clock clock)
     }
     
     uint16_t
    -siba_read_2(struct siba_dev_softc *sd, uint16_t offset)
    +siba_read_2(device_t dev, uint16_t offset)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
     
     	return (sd->sd_ops->read_2(sd, offset));
     }
     
     uint32_t
    -siba_read_4(struct siba_dev_softc *sd, uint16_t offset)
    +siba_read_4(device_t dev, uint16_t offset)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +
    +	return (siba_read_4_sub(sd, offset));
    +}
    +
    +static uint32_t
    +siba_read_4_sub(struct siba_dev_softc *sd, uint16_t offset)
     {
     
     	return (sd->sd_ops->read_4(sd, offset));
     }
     
     void
    -siba_write_2(struct siba_dev_softc *sd, uint16_t offset, uint16_t value)
    +siba_write_2(device_t dev, uint16_t offset, uint16_t value)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
     
     	sd->sd_ops->write_2(sd, offset, value);
     }
     
     void
    -siba_write_4(struct siba_dev_softc *sd, uint16_t offset, uint32_t value)
    +siba_write_4(device_t dev, uint16_t offset, uint32_t value)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +
    +	return (siba_write_4_sub(sd, offset, value));
    +}
    +
    +static void
    +siba_write_4_sub(struct siba_dev_softc *sd, uint16_t offset, uint32_t value)
     {
     
     	sd->sd_ops->write_4(sd, offset, value);
     }
     
     void
    -siba_read_multi_1(struct siba_dev_softc *sd, void *buffer, size_t count,
    +siba_read_multi_1(device_t dev, void *buffer, size_t count,
         uint16_t offset)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
     
     	sd->sd_ops->read_multi_1(sd, buffer, count, offset);
     }
     
     void
    -siba_read_multi_2(struct siba_dev_softc *sd, void *buffer, size_t count,
    +siba_read_multi_2(device_t dev, void *buffer, size_t count,
         uint16_t offset)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
     
     	sd->sd_ops->read_multi_2(sd, buffer, count, offset);
     }
     
     void
    -siba_read_multi_4(struct siba_dev_softc *sd, void *buffer, size_t count,
    +siba_read_multi_4(device_t dev, void *buffer, size_t count,
         uint16_t offset)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
     
     	sd->sd_ops->read_multi_4(sd, buffer, count, offset);
     }
     
     void
    -siba_write_multi_1(struct siba_dev_softc *sd, const void *buffer,
    -    size_t count, uint16_t offset)
    +siba_write_multi_1(device_t dev, const void *buffer, size_t count,
    +    uint16_t offset)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
     
     	sd->sd_ops->write_multi_1(sd, buffer, count, offset);
     }
     
     void
    -siba_write_multi_2(struct siba_dev_softc *sd, const void *buffer,
    -    size_t count, uint16_t offset)
    +siba_write_multi_2(device_t dev, const void *buffer, size_t count,
    +    uint16_t offset)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
     
     	sd->sd_ops->write_multi_2(sd, buffer, count, offset);
     }
     
     void
    -siba_write_multi_4(struct siba_dev_softc *sd, const void *buffer,
    -    size_t count, uint16_t offset)
    +siba_write_multi_4(device_t dev, const void *buffer, size_t count,
    +    uint16_t offset)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
     
     	sd->sd_ops->write_multi_4(sd, buffer, count, offset);
     }
    @@ -1685,7 +1719,16 @@ siba_sprom_r123_antgain(uint8_t sprom_revision, const uint16_t *in,
     #undef SIBA_SHIFTOUT
     
     int
    -siba_powerdown(struct siba_softc *siba)
    +siba_powerdown(device_t dev)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	return (siba_powerdown_sub(siba));
    +}
    +
    +static int
    +siba_powerdown_sub(struct siba_softc *siba)
     {
     	struct siba_cc *scc;
     
    @@ -1710,61 +1753,77 @@ siba_pcicore_init(struct siba_pci *spc)
     		return;
     
     	siba = sd->sd_bus;
    -	if (!siba_dev_isup(sd))
    -		siba_dev_up(sd, 0);
    +	if (!siba_dev_isup_sub(sd))
    +		siba_dev_up_sub(sd, 0);
     
     	KASSERT(spc->spc_hostmode == 0,
     	    ("%s:%d: hostmode", __func__, __LINE__));
     	/* disable PCI interrupt */
    -	siba_write_4(spc->spc_dev, SIBA_INTR_MASK, 0);
    +	siba_write_4_sub(spc->spc_dev, SIBA_INTR_MASK, 0);
     }
     
     int
    -siba_dev_isup(struct siba_dev_softc *sd)
    +siba_dev_isup(device_t dev)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +
    +	return (siba_dev_isup_sub(sd));
    +}
    +
    +static int
    +siba_dev_isup_sub(struct siba_dev_softc *sd)
     {
     	uint32_t reject, val;
     
     	reject = siba_tmslow_reject_bitmask(sd);
    -	val = siba_read_4(sd, SIBA_TGSLOW);
    +	val = siba_read_4_sub(sd, SIBA_TGSLOW);
     	val &= SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_RESET | reject;
     
     	return (val == SIBA_TGSLOW_CLOCK);
     }
     
     void
    -siba_dev_up(struct siba_dev_softc *sd, uint32_t flags)
    +siba_dev_up(device_t dev, uint32_t flags)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +
    +	siba_dev_up_sub(sd, flags);
    +}
    +
    +static void
    +siba_dev_up_sub(struct siba_dev_softc *sd, uint32_t flags)
     {
     	uint32_t val;
     
    -	siba_dev_down(sd, flags);
    -	siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_RESET | SIBA_TGSLOW_CLOCK |
    -	    SIBA_TGSLOW_FGC | flags);
    -	siba_read_4(sd, SIBA_TGSLOW);
    +	siba_dev_down_sub(sd, flags);
    +	siba_write_4_sub(sd, SIBA_TGSLOW,
    +	    SIBA_TGSLOW_RESET | SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_FGC | flags);
    +	siba_read_4_sub(sd, SIBA_TGSLOW);
     	DELAY(1);
     
    -	if (siba_read_4(sd, SIBA_TGSHIGH) & SIBA_TGSHIGH_SERR)
    -		siba_write_4(sd, SIBA_TGSHIGH, 0);
    +	if (siba_read_4_sub(sd, SIBA_TGSHIGH) & SIBA_TGSHIGH_SERR)
    +		siba_write_4_sub(sd, SIBA_TGSHIGH, 0);
     
    -	val = siba_read_4(sd, SIBA_IAS);
    +	val = siba_read_4_sub(sd, SIBA_IAS);
     	if (val & (SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT)) {
     		val &= ~(SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT);
    -		siba_write_4(sd, SIBA_IAS, val);
    +		siba_write_4_sub(sd, SIBA_IAS, val);
     	}
     
    -	siba_write_4(sd, SIBA_TGSLOW,
    +	siba_write_4_sub(sd, SIBA_TGSLOW,
     	    SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_FGC | flags);
    -	siba_read_4(sd, SIBA_TGSLOW);
    +	siba_read_4_sub(sd, SIBA_TGSLOW);
     	DELAY(1);
     
    -	siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_CLOCK | flags);
    -	siba_read_4(sd, SIBA_TGSLOW);
    +	siba_write_4_sub(sd, SIBA_TGSLOW, SIBA_TGSLOW_CLOCK | flags);
    +	siba_read_4_sub(sd, SIBA_TGSLOW);
     	DELAY(1);
     }
     
     static uint32_t
     siba_tmslow_reject_bitmask(struct siba_dev_softc *sd)
     {
    -	uint32_t rev = siba_read_4(sd, SIBA_IDLOW) & SIBA_IDLOW_SSBREV;
    +	uint32_t rev = siba_read_4_sub(sd, SIBA_IDLOW) & SIBA_IDLOW_SSBREV;
     
     	switch (rev) {
     	case SIBA_IDLOW_SSBREV_22:
    @@ -1785,20 +1844,28 @@ siba_tmslow_reject_bitmask(struct siba_dev_softc *sd)
     }
     
     void
    -siba_dev_down(struct siba_dev_softc *sd, uint32_t flags)
    +siba_dev_down(device_t dev, uint32_t flags)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +
    +	siba_dev_down_sub(sd, flags);
    +}
    +
    +static void
    +siba_dev_down_sub(struct siba_dev_softc *sd, uint32_t flags)
     {
     	struct siba_softc *siba = sd->sd_bus;
     	uint32_t reject, val;
     	int i;
     
    -	if (siba_read_4(sd, SIBA_TGSLOW) & SIBA_TGSLOW_RESET)
    +	if (siba_read_4_sub(sd, SIBA_TGSLOW) & SIBA_TGSLOW_RESET)
     		return;
     
     	reject = siba_tmslow_reject_bitmask(sd);
    -	siba_write_4(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_CLOCK);
    +	siba_write_4_sub(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_CLOCK);
     
     	for (i = 0; i < 1000; i++) {
    -		val = siba_read_4(sd, SIBA_TGSLOW);
    +		val = siba_read_4_sub(sd, SIBA_TGSLOW);
     		if (val & reject)
     			break;
     		DELAY(10);
    @@ -1808,7 +1875,7 @@ siba_dev_down(struct siba_dev_softc *sd, uint32_t flags)
     		    reject, SIBA_TGSLOW);
     	}
     	for (i = 0; i < 1000; i++) {
    -		val = siba_read_4(sd, SIBA_TGSHIGH);
    +		val = siba_read_4_sub(sd, SIBA_TGSHIGH);
     		if (!(val & SIBA_TGSHIGH_BUSY))
     			break;
     		DELAY(10);
    @@ -1818,12 +1885,12 @@ siba_dev_down(struct siba_dev_softc *sd, uint32_t flags)
     		    SIBA_TGSHIGH_BUSY, SIBA_TGSHIGH);
     	}
     
    -	siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_FGC | SIBA_TGSLOW_CLOCK |
    +	siba_write_4_sub(sd, SIBA_TGSLOW, SIBA_TGSLOW_FGC | SIBA_TGSLOW_CLOCK |
     	    reject | SIBA_TGSLOW_RESET | flags);
    -	siba_read_4(sd, SIBA_TGSLOW);
    +	siba_read_4_sub(sd, SIBA_TGSLOW);
     	DELAY(1);
    -	siba_write_4(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_RESET | flags);
    -	siba_read_4(sd, SIBA_TGSLOW);
    +	siba_write_4_sub(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_RESET | flags);
    +	siba_read_4_sub(sd, SIBA_TGSLOW);
     	DELAY(1);
     }
     
    @@ -1840,21 +1907,22 @@ siba_pcicore_setup(struct siba_pci *spc, struct siba_dev_softc *sd)
     		    SIBA_PCICORE_SBTOPCI_PREF | SIBA_PCICORE_SBTOPCI_BURST);
     
     		if (psd->sd_id.sd_rev < 5) {
    -			tmp = siba_read_4(psd, SIBA_IMCFGLO);
    +			tmp = siba_read_4_sub(psd, SIBA_IMCFGLO);
     			tmp &= ~SIBA_IMCFGLO_SERTO;
     			tmp = (tmp | 2) & ~SIBA_IMCFGLO_REQTO;
     			tmp |= 3 << 4 /* SIBA_IMCFGLO_REQTO_SHIFT */;
    -			siba_write_4(psd, SIBA_IMCFGLO, tmp);
    +			siba_write_4_sub(psd, SIBA_IMCFGLO, tmp);
     
     			/* broadcast value */
     			sd = (siba->siba_cc.scc_dev != NULL) ?
     			    siba->siba_cc.scc_dev : siba->siba_pci.spc_dev;
     			if (sd != NULL) {
    -				siba_write_4(sd, SIBA_PCICORE_BCAST_ADDR,
    +				siba_write_4_sub(sd, SIBA_PCICORE_BCAST_ADDR,
     				    0xfd8);
    -				siba_read_4(sd, SIBA_PCICORE_BCAST_ADDR);
    -				siba_write_4(sd, SIBA_PCICORE_BCAST_DATA, 0);
    -				siba_read_4(sd, SIBA_PCICORE_BCAST_DATA);
    +				siba_read_4_sub(sd, SIBA_PCICORE_BCAST_ADDR);
    +				siba_write_4_sub(sd,
    +				    SIBA_PCICORE_BCAST_DATA, 0);
    +				siba_read_4_sub(sd, SIBA_PCICORE_BCAST_DATA);
     			}
     		} else if (psd->sd_id.sd_rev >= 11) {
     			tmp = siba_pcicore_read_4(spc, SIBA_PCICORE_SBTOPCI2);
    @@ -1878,27 +1946,31 @@ siba_pcicore_setup(struct siba_pci *spc, struct siba_dev_softc *sd)
     }
     
     void
    -siba_pcicore_intr(struct siba_pci *spc, struct siba_dev_softc *sd)
    +siba_pcicore_intr(device_t dev)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct siba_pci *spc = &siba->siba_pci;
     	struct siba_dev_softc *psd = spc->spc_dev;
    -	struct siba_softc *siba;
     	uint32_t tmp;
     
    -	if (sd->sd_bus->siba_type != SIBA_TYPE_PCI || !psd)
    +	if (siba->siba_type != SIBA_TYPE_PCI || !psd)
     		return;
     
    -	siba = psd->sd_bus;
    +	KASSERT(siba == psd->sd_bus, ("different pointers"));
    +
     	/* enable interrupts */
     	if (siba->siba_dev != NULL &&
    -	    (psd->sd_id.sd_rev >= 6 || psd->sd_id.sd_device == SIBA_DEVID_PCIE)) {
    +	    (psd->sd_id.sd_rev >= 6 ||
    +	     psd->sd_id.sd_device == SIBA_DEVID_PCIE)) {
     		tmp = pci_read_config(siba->siba_dev, SIBA_IRQMASK, 4);
     		tmp |= (1 << sd->sd_coreidx) << 8;
     		pci_write_config(siba->siba_dev, SIBA_IRQMASK, tmp, 4);
     	} else {
    -		tmp = siba_read_4(sd, SIBA_TPS);
    +		tmp = siba_read_4_sub(sd, SIBA_TPS);
     		tmp &= SIBA_TPS_BPFLAG;
    -		siba_write_4(psd, SIBA_INTR_MASK,
    -		    siba_read_4(psd, SIBA_INTR_MASK) | (1 << tmp));
    +		siba_write_4_sub(psd, SIBA_INTR_MASK,
    +		    siba_read_4_sub(psd, SIBA_INTR_MASK) | (1 << tmp));
     	}
     
     	/* setup PCIcore */
    @@ -1910,14 +1982,14 @@ static uint32_t
     siba_pcicore_read_4(struct siba_pci *spc, uint16_t offset)
     {
     
    -	return (siba_read_4(spc->spc_dev, offset));
    +	return (siba_read_4_sub(spc->spc_dev, offset));
     }
     
     static void
     siba_pcicore_write_4(struct siba_pci *spc, uint16_t offset, uint32_t value)
     {
     
    -	siba_write_4(spc->spc_dev, offset, value);
    +	siba_write_4_sub(spc->spc_dev, offset, value);
     }
     
     static uint32_t
    @@ -1957,17 +2029,22 @@ siba_pcie_mdio_write(struct siba_pci *spc, uint8_t device, uint8_t address,
     }
     
     uint32_t
    -siba_dma_translation(struct siba_dev_softc *sd)
    +siba_dma_translation(device_t dev)
     {
    +#ifdef INVARIANTS
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
     
    -	KASSERT(sd->sd_bus->siba_type == SIBA_TYPE_PCI,
    -	    ("unsupported bustype %d\n", sd->sd_bus->siba_type));
    +	KASSERT(siba->siba_type == SIBA_TYPE_PCI,
    +	    ("unsupported bustype %d\n", siba->siba_type));
    +#endif
     	return (SIBA_PCI_DMA);
     }
     
     void
    -siba_barrier(struct siba_dev_softc *sd, int flags)
    +siba_barrier(device_t dev, int flags)
     {
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
     	struct siba_softc *siba = sd->sd_bus;
     
     	SIBA_BARRIER(siba, flags);
    @@ -2004,10 +2081,10 @@ siba_core_resume(struct siba_softc *siba)
     	siba->siba_pci.spc_inited = 0;
     	siba->siba_curdev = NULL;
     
    -	siba_powerup(siba, 0);
    +	siba_powerup_sub(siba, 0);
     	/* XXX setup H/W for PCMCIA??? */
     	siba_cc_resume(&siba->siba_cc);
    -	siba_powerdown(siba);
    +	siba_powerdown_sub(siba);
     
     	return (0);
     }
    @@ -2026,9 +2103,11 @@ siba_cc_regctl_setmask(struct siba_cc *cc, uint32_t offset, uint32_t mask,
     }
     
     void
    -siba_cc_pmu_set_ldovolt(struct siba_cc *scc, int id, uint32_t volt)
    +siba_cc_pmu_set_ldovolt(device_t dev, int id, uint32_t volt)
     {
    -	struct siba_softc *siba = scc->scc_dev->sd_bus;
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct siba_cc *scc = &siba->siba_cc;
     	uint32_t *p = NULL, info[5][3] = {
     		{ 2, 25,  0xf },
     		{ 3,  1,  0xf },
    @@ -2070,9 +2149,11 @@ siba_cc_pmu_set_ldovolt(struct siba_cc *scc, int id, uint32_t volt)
     }
     
     void
    -siba_cc_pmu_set_ldoparef(struct siba_cc *scc, uint8_t on)
    +siba_cc_pmu_set_ldoparef(device_t dev, uint8_t on)
     {
    -	struct siba_softc *siba = scc->scc_dev->sd_bus;
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct siba_cc *scc = &siba->siba_cc;
     	int ldo;
     
     	ldo = ((siba->siba_chipid == 0x4312) ? SIBA_CC_PMU_4312_PA_REF :
    @@ -2087,3 +2168,419 @@ siba_cc_pmu_set_ldoparef(struct siba_cc *scc, uint8_t on)
     		SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, ~(1 << ldo));
     	SIBA_CC_READ32(scc, SIBA_CC_PMU_MINRES);
     }
    +
    +int
    +siba_read_sprom(device_t dev, device_t child, int which, uintptr_t *result)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(child);
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	switch (which) {
    +	case SIBA_SPROMVAR_REV:
    +		*result = siba->siba_sprom.rev;
    +		break;
    +	case SIBA_SPROMVAR_MAC_80211BG:
    +		*((uint8_t **) result) = siba->siba_sprom.mac_80211bg;
    +		break;
    +	case SIBA_SPROMVAR_MAC_ETH:
    +		*((uint8_t **) result) = siba->siba_sprom.mac_eth;
    +		break;
    +	case SIBA_SPROMVAR_MAC_80211A:
    +		*((uint8_t **) result) = siba->siba_sprom.mac_80211a;
    +		break;
    +	case SIBA_SPROMVAR_MII_ETH0:
    +		*result = siba->siba_sprom.mii_eth0;
    +		break;
    +	case SIBA_SPROMVAR_MII_ETH1:
    +		*result = siba->siba_sprom.mii_eth1;
    +		break;
    +	case SIBA_SPROMVAR_MDIO_ETH0:
    +		*result = siba->siba_sprom.mdio_eth0;
    +		break;
    +	case SIBA_SPROMVAR_MDIO_ETH1:
    +		*result = siba->siba_sprom.mdio_eth1;
    +		break;
    +	case SIBA_SPROMVAR_BREV:
    +		*result = siba->siba_sprom.brev;
    +		break;
    +	case SIBA_SPROMVAR_CCODE:
    +		*result = siba->siba_sprom.ccode;
    +		break;
    +	case SIBA_SPROMVAR_ANT_A:
    +		*result = siba->siba_sprom.ant_a;
    +		break;
    +	case SIBA_SPROMVAR_ANT_BG:
    +		*result = siba->siba_sprom.ant_bg;
    +		break;
    +	case SIBA_SPROMVAR_PA0B0:
    +		*result = siba->siba_sprom.pa0b0;
    +		break;
    +	case SIBA_SPROMVAR_PA0B1:
    +		*result = siba->siba_sprom.pa0b1;
    +		break;
    +	case SIBA_SPROMVAR_PA0B2:
    +		*result = siba->siba_sprom.pa0b2;
    +		break;
    +	case SIBA_SPROMVAR_PA1B0:
    +		*result = siba->siba_sprom.pa1b0;
    +		break;
    +	case SIBA_SPROMVAR_PA1B1:
    +		*result = siba->siba_sprom.pa1b1;
    +		break;
    +	case SIBA_SPROMVAR_PA1B2:
    +		*result = siba->siba_sprom.pa1b2;
    +		break;
    +	case SIBA_SPROMVAR_PA1LOB0:
    +		*result = siba->siba_sprom.pa1lob0;
    +		break;
    +	case SIBA_SPROMVAR_PA1LOB1:
    +		*result = siba->siba_sprom.pa1lob1;
    +		break;
    +	case SIBA_SPROMVAR_PA1LOB2:
    +		*result = siba->siba_sprom.pa1lob2;
    +		break;
    +	case SIBA_SPROMVAR_PA1HIB0:
    +		*result = siba->siba_sprom.pa1hib0;
    +		break;
    +	case SIBA_SPROMVAR_PA1HIB1:
    +		*result = siba->siba_sprom.pa1hib1;
    +		break;
    +	case SIBA_SPROMVAR_PA1HIB2:
    +		*result = siba->siba_sprom.pa1hib2;
    +		break;
    +	case SIBA_SPROMVAR_GPIO0:
    +		*result = siba->siba_sprom.gpio0;
    +		break;
    +	case SIBA_SPROMVAR_GPIO1:
    +		*result = siba->siba_sprom.gpio1;
    +		break;
    +	case SIBA_SPROMVAR_GPIO2:
    +		*result = siba->siba_sprom.gpio2;
    +		break;
    +	case SIBA_SPROMVAR_GPIO3:
    +		*result = siba->siba_sprom.gpio3;
    +		break;
    +	case SIBA_SPROMVAR_MAXPWR_AL:
    +		*result = siba->siba_sprom.maxpwr_al;
    +		break;
    +	case SIBA_SPROMVAR_MAXPWR_A:
    +		*result = siba->siba_sprom.maxpwr_a;
    +		break;
    +	case SIBA_SPROMVAR_MAXPWR_AH:
    +		*result = siba->siba_sprom.maxpwr_ah;
    +		break;
    +	case SIBA_SPROMVAR_MAXPWR_BG:
    +		*result = siba->siba_sprom.maxpwr_bg;
    +		break;
    +	case SIBA_SPROMVAR_RXPO2G:
    +		*result = siba->siba_sprom.rxpo2g;
    +		break;
    +	case SIBA_SPROMVAR_RXPO5G:
    +		*result = siba->siba_sprom.rxpo5g;
    +		break;
    +	case SIBA_SPROMVAR_TSSI_A:
    +		*result = siba->siba_sprom.tssi_a;
    +		break;
    +	case SIBA_SPROMVAR_TSSI_BG:
    +		*result = siba->siba_sprom.tssi_bg;
    +		break;
    +	case SIBA_SPROMVAR_TRI2G:
    +		*result = siba->siba_sprom.tri2g;
    +		break;
    +	case SIBA_SPROMVAR_TRI5GL:
    +		*result = siba->siba_sprom.tri5gl;
    +		break;
    +	case SIBA_SPROMVAR_TRI5G:
    +		*result = siba->siba_sprom.tri5g;
    +		break;
    +	case SIBA_SPROMVAR_TRI5GH:
    +		*result = siba->siba_sprom.tri5gh;
    +		break;
    +	case SIBA_SPROMVAR_RSSISAV2G:
    +		*result = siba->siba_sprom.rssisav2g;
    +		break;
    +	case SIBA_SPROMVAR_RSSISMC2G:
    +		*result = siba->siba_sprom.rssismc2g;
    +		break;
    +	case SIBA_SPROMVAR_RSSISMF2G:
    +		*result = siba->siba_sprom.rssismf2g;
    +		break;
    +	case SIBA_SPROMVAR_BXA2G:
    +		*result = siba->siba_sprom.bxa2g;
    +		break;
    +	case SIBA_SPROMVAR_RSSISAV5G:
    +		*result = siba->siba_sprom.rssisav5g;
    +		break;
    +	case SIBA_SPROMVAR_RSSISMC5G:
    +		*result = siba->siba_sprom.rssismc5g;
    +		break;
    +	case SIBA_SPROMVAR_RSSISMF5G:
    +		*result = siba->siba_sprom.rssismf5g;
    +		break;
    +	case SIBA_SPROMVAR_BXA5G:
    +		*result = siba->siba_sprom.bxa5g;
    +		break;
    +	case SIBA_SPROMVAR_CCK2GPO:
    +		*result = siba->siba_sprom.cck2gpo;
    +		break;
    +	case SIBA_SPROMVAR_OFDM2GPO:
    +		*result = siba->siba_sprom.ofdm2gpo;
    +		break;
    +	case SIBA_SPROMVAR_OFDM5GLPO:
    +		*result = siba->siba_sprom.ofdm5glpo;
    +		break;
    +	case SIBA_SPROMVAR_OFDM5GPO:
    +		*result = siba->siba_sprom.ofdm5gpo;
    +		break;
    +	case SIBA_SPROMVAR_OFDM5GHPO:
    +		*result = siba->siba_sprom.ofdm5ghpo;
    +		break;
    +	case SIBA_SPROMVAR_BF_LO:
    +		*result = siba->siba_sprom.bf_lo;
    +		break;
    +	case SIBA_SPROMVAR_BF_HI:
    +		*result = siba->siba_sprom.bf_hi;
    +		break;
    +	case SIBA_SPROMVAR_BF2_LO:
    +		*result = siba->siba_sprom.bf2_lo;
    +		break;
    +	case SIBA_SPROMVAR_BF2_HI:
    +		*result = siba->siba_sprom.bf2_hi;
    +		break;
    +	default:
    +		return (ENOENT);
    +	}
    +	return (0);
    +}
    +
    +int
    +siba_write_sprom(device_t dev, device_t child, int which, uintptr_t value)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(child);
    +	struct siba_softc *siba = sd->sd_bus;
    +
    +	switch (which) {
    +	case SIBA_SPROMVAR_REV:
    +		siba->siba_sprom.rev = value;
    +		break;
    +	case SIBA_SPROMVAR_MII_ETH0:
    +		siba->siba_sprom.mii_eth0 = value;
    +		break;
    +	case SIBA_SPROMVAR_MII_ETH1:
    +		siba->siba_sprom.mii_eth1 = value;
    +		break;
    +	case SIBA_SPROMVAR_MDIO_ETH0:
    +		siba->siba_sprom.mdio_eth0 = value;
    +		break;
    +	case SIBA_SPROMVAR_MDIO_ETH1:
    +		siba->siba_sprom.mdio_eth1 = value;
    +		break;
    +	case SIBA_SPROMVAR_BREV:
    +		siba->siba_sprom.brev = value;
    +		break;
    +	case SIBA_SPROMVAR_CCODE:
    +		siba->siba_sprom.ccode = value;
    +		break;
    +	case SIBA_SPROMVAR_ANT_A:
    +		siba->siba_sprom.ant_a = value;
    +		break;
    +	case SIBA_SPROMVAR_ANT_BG:
    +		siba->siba_sprom.ant_bg = value;
    +		break;
    +	case SIBA_SPROMVAR_PA0B0:
    +		siba->siba_sprom.pa0b0 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA0B1:
    +		siba->siba_sprom.pa0b1 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA0B2:
    +		siba->siba_sprom.pa0b2 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA1B0:
    +		siba->siba_sprom.pa1b0 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA1B1:
    +		siba->siba_sprom.pa1b1 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA1B2:
    +		siba->siba_sprom.pa1b2 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA1LOB0:
    +		siba->siba_sprom.pa1lob0 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA1LOB1:
    +		siba->siba_sprom.pa1lob1 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA1LOB2:
    +		siba->siba_sprom.pa1lob2 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA1HIB0:
    +		siba->siba_sprom.pa1hib0 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA1HIB1:
    +		siba->siba_sprom.pa1hib1 = value;
    +		break;
    +	case SIBA_SPROMVAR_PA1HIB2:
    +		siba->siba_sprom.pa1hib2 = value;
    +		break;
    +	case SIBA_SPROMVAR_GPIO0:
    +		siba->siba_sprom.gpio0 = value;
    +		break;
    +	case SIBA_SPROMVAR_GPIO1:
    +		siba->siba_sprom.gpio1 = value;
    +		break;
    +	case SIBA_SPROMVAR_GPIO2:
    +		siba->siba_sprom.gpio2 = value;
    +		break;
    +	case SIBA_SPROMVAR_GPIO3:
    +		siba->siba_sprom.gpio3 = value;
    +		break;
    +	case SIBA_SPROMVAR_MAXPWR_AL:
    +		siba->siba_sprom.maxpwr_al = value;
    +		break;
    +	case SIBA_SPROMVAR_MAXPWR_A:
    +		siba->siba_sprom.maxpwr_a = value;
    +		break;
    +	case SIBA_SPROMVAR_MAXPWR_AH:
    +		siba->siba_sprom.maxpwr_ah = value;
    +		break;
    +	case SIBA_SPROMVAR_MAXPWR_BG:
    +		siba->siba_sprom.maxpwr_bg = value;
    +		break;
    +	case SIBA_SPROMVAR_RXPO2G:
    +		siba->siba_sprom.rxpo2g = value;
    +		break;
    +	case SIBA_SPROMVAR_RXPO5G:
    +		siba->siba_sprom.rxpo5g = value;
    +		break;
    +	case SIBA_SPROMVAR_TSSI_A:
    +		siba->siba_sprom.tssi_a = value;
    +		break;
    +	case SIBA_SPROMVAR_TSSI_BG:
    +		siba->siba_sprom.tssi_bg = value;
    +		break;
    +	case SIBA_SPROMVAR_TRI2G:
    +		siba->siba_sprom.tri2g = value;
    +		break;
    +	case SIBA_SPROMVAR_TRI5GL:
    +		siba->siba_sprom.tri5gl = value;
    +		break;
    +	case SIBA_SPROMVAR_TRI5G:
    +		siba->siba_sprom.tri5g = value;
    +		break;
    +	case SIBA_SPROMVAR_TRI5GH:
    +		siba->siba_sprom.tri5gh = value;
    +		break;
    +	case SIBA_SPROMVAR_RSSISAV2G:
    +		siba->siba_sprom.rssisav2g = value;
    +		break;
    +	case SIBA_SPROMVAR_RSSISMC2G:
    +		siba->siba_sprom.rssismc2g = value;
    +		break;
    +	case SIBA_SPROMVAR_RSSISMF2G:
    +		siba->siba_sprom.rssismf2g = value;
    +		break;
    +	case SIBA_SPROMVAR_BXA2G:
    +		siba->siba_sprom.bxa2g = value;
    +		break;
    +	case SIBA_SPROMVAR_RSSISAV5G:
    +		siba->siba_sprom.rssisav5g = value;
    +		break;
    +	case SIBA_SPROMVAR_RSSISMC5G:
    +		siba->siba_sprom.rssismc5g = value;
    +		break;
    +	case SIBA_SPROMVAR_RSSISMF5G:
    +		siba->siba_sprom.rssismf5g = value;
    +		break;
    +	case SIBA_SPROMVAR_BXA5G:
    +		siba->siba_sprom.bxa5g = value;
    +		break;
    +	case SIBA_SPROMVAR_CCK2GPO:
    +		siba->siba_sprom.cck2gpo = value;
    +		break;
    +	case SIBA_SPROMVAR_OFDM2GPO:
    +		siba->siba_sprom.ofdm2gpo = value;
    +		break;
    +	case SIBA_SPROMVAR_OFDM5GLPO:
    +		siba->siba_sprom.ofdm5glpo = value;
    +		break;
    +	case SIBA_SPROMVAR_OFDM5GPO:
    +		siba->siba_sprom.ofdm5gpo = value;
    +		break;
    +	case SIBA_SPROMVAR_OFDM5GHPO:
    +		siba->siba_sprom.ofdm5ghpo = value;
    +		break;
    +	case SIBA_SPROMVAR_BF_LO:
    +		siba->siba_sprom.bf_lo = value;
    +		break;
    +	case SIBA_SPROMVAR_BF_HI:
    +		siba->siba_sprom.bf_hi = value;
    +		break;
    +	case SIBA_SPROMVAR_BF2_LO:
    +		siba->siba_sprom.bf2_lo = value;
    +		break;
    +	case SIBA_SPROMVAR_BF2_HI:
    +		siba->siba_sprom.bf2_hi = value;
    +		break;
    +	default:
    +		return (ENOENT);
    +	}
    +	return (0);
    +}
    +
    +#define	SIBA_GPIOCTL			0x06c
    +
    +uint32_t
    +siba_gpio_get(device_t dev)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct siba_dev_softc *gpiodev, *pcidev = NULL;
    +
    +	pcidev = siba->siba_pci.spc_dev;
    +	gpiodev = siba->siba_cc.scc_dev ? siba->siba_cc.scc_dev : pcidev;
    +	if (!gpiodev)
    +		return (-1);
    +	return (siba_read_4_sub(gpiodev, SIBA_GPIOCTL));
    +}
    +
    +void
    +siba_gpio_set(device_t dev, uint32_t value)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
    +	struct siba_dev_softc *gpiodev, *pcidev = NULL;
    +
    +	pcidev = siba->siba_pci.spc_dev;
    +	gpiodev = siba->siba_cc.scc_dev ? siba->siba_cc.scc_dev : pcidev;
    +	if (!gpiodev)
    +		return;
    +	siba_write_4_sub(gpiodev, SIBA_GPIOCTL, value);
    +}
    +
    +void
    +siba_fix_imcfglobug(device_t dev)
    +{
    +	struct siba_dev_softc *sd = device_get_ivars(dev);
    +	struct siba_softc *siba = sd->sd_bus;
    +	uint32_t tmp;
    +
    +	if (siba->siba_pci.spc_dev == NULL)
    +		return;
    +	if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI ||
    +	    siba->siba_pci.spc_dev->sd_id.sd_rev > 5)
    +		return;
    +
    +	tmp = siba_read_4_sub(sd, SIBA_IMCFGLO) &
    +	    ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO);
    +	switch (siba->siba_type) {
    +	case SIBA_TYPE_PCI:
    +	case SIBA_TYPE_PCMCIA:
    +		tmp |= 0x32;
    +		break;
    +	case SIBA_TYPE_SSB:
    +		tmp |= 0x53;
    +		break;
    +	}
    +	siba_write_4_sub(sd, SIBA_IMCFGLO, tmp);
    +}
    diff --git a/sys/dev/siba/siba_pcib.c b/sys/dev/siba/siba_pcib.c
    index 5175aa7ee0b..d6ddeb695ab 100644
    --- a/sys/dev/siba/siba_pcib.c
    +++ b/sys/dev/siba/siba_pcib.c
    @@ -419,7 +419,7 @@ static device_method_t siba_pcib_methods[] = {
     	DEVMETHOD(pcib_write_config,	siba_pcib_write_config),
     	DEVMETHOD(pcib_route_interrupt,	siba_pcib_route_interrupt),
     
    -	{0, 0},
    +	KOBJMETHOD_END
     };
     
     static driver_t siba_pcib_driver = {
    diff --git a/sys/dev/siba/sibavar.h b/sys/dev/siba/sibavar.h
    index 307903b9920..9b82310b338 100644
    --- a/sys/dev/siba/sibavar.h
    +++ b/sys/dev/siba/sibavar.h
    @@ -34,11 +34,30 @@
     struct siba_softc;
     struct siba_dev_softc;
     
    +enum siba_type {
    +	SIBA_TYPE_SSB,
    +	SIBA_TYPE_PCI,
    +	SIBA_TYPE_PCMCIA,
    +};
    +
     enum siba_device_ivars {
     	SIBA_IVAR_VENDOR,
     	SIBA_IVAR_DEVICE,
     	SIBA_IVAR_REVID,
    -	SIBA_IVAR_CORE_INDEX
    +	SIBA_IVAR_CORE_INDEX,
    +	SIBA_IVAR_PCI_VENDOR,
    +	SIBA_IVAR_PCI_DEVICE,
    +	SIBA_IVAR_PCI_SUBVENDOR,
    +	SIBA_IVAR_PCI_SUBDEVICE,
    +	SIBA_IVAR_PCI_REVID,
    +	SIBA_IVAR_CHIPID,
    +	SIBA_IVAR_CHIPREV,
    +	SIBA_IVAR_CHIPPKG,
    +	SIBA_IVAR_TYPE,
    +	SIBA_IVAR_CC_PMUFREQ,
    +	SIBA_IVAR_CC_CAPS,
    +	SIBA_IVAR_CC_POWERDELAY,
    +	SIBA_IVAR_PCICORE_REVID
     };
     
     #define	SIBA_ACCESSOR(var, ivar, type)				\
    @@ -48,6 +67,19 @@ SIBA_ACCESSOR(vendor,		VENDOR,		uint16_t)
     SIBA_ACCESSOR(device,		DEVICE,		uint16_t)
     SIBA_ACCESSOR(revid,		REVID,		uint8_t)
     SIBA_ACCESSOR(core_index,	CORE_INDEX,	uint8_t)
    +SIBA_ACCESSOR(pci_vendor,	PCI_VENDOR,	uint16_t)
    +SIBA_ACCESSOR(pci_device,	PCI_DEVICE,	uint16_t)
    +SIBA_ACCESSOR(pci_subvendor,	PCI_SUBVENDOR,	uint16_t)
    +SIBA_ACCESSOR(pci_subdevice,	PCI_SUBDEVICE,	uint16_t)
    +SIBA_ACCESSOR(pci_revid,	PCI_REVID,	uint8_t)
    +SIBA_ACCESSOR(chipid,		CHIPID,		uint16_t)
    +SIBA_ACCESSOR(chiprev,		CHIPREV,	uint16_t)
    +SIBA_ACCESSOR(chippkg,		CHIPPKG,	uint8_t)
    +SIBA_ACCESSOR(type,		TYPE,		enum siba_type)
    +SIBA_ACCESSOR(cc_pmufreq,	CC_PMUFREQ,	uint32_t)
    +SIBA_ACCESSOR(cc_caps,		CC_CAPS,	uint32_t)
    +SIBA_ACCESSOR(cc_powerdelay,	CC_POWERDELAY,	uint16_t)
    +SIBA_ACCESSOR(pcicore_revid,	PCICORE_REVID,	uint8_t)
     
     #undef SIBA_ACCESSOR
     
    @@ -135,9 +167,9 @@ enum {
     	SIBA_WRITE_2((siba), (reg), SIBA_READ_2((siba), (reg)) & ~(bits))
     
     #define	SIBA_CC_READ32(scc, offset) \
    -	siba_read_4((scc)->scc_dev, offset)
    +	siba_read_4_sub((scc)->scc_dev, offset)
     #define	SIBA_CC_WRITE32(scc, offset, val) \
    -	siba_write_4((scc)->scc_dev, offset, val)
    +	siba_write_4_sub((scc)->scc_dev, offset, val)
     #define	SIBA_CC_MASK32(scc, offset, mask) \
     	SIBA_CC_WRITE32(scc, offset, SIBA_CC_READ32(scc, offset) & (mask))
     #define	SIBA_CC_SET32(scc, offset, set) \
    @@ -146,12 +178,6 @@ enum {
     	SIBA_CC_WRITE32(scc, offset,			\
     	    (SIBA_CC_READ32(scc, offset) & (mask)) | (set))
     
    -enum siba_type {
    -	SIBA_TYPE_SSB,
    -	SIBA_TYPE_PCI,
    -	SIBA_TYPE_PCMCIA,
    -};
    -
     enum siba_clock {
     	SIBA_CLOCK_DYNAMIC,
     	SIBA_CLOCK_SLOW,
    @@ -195,6 +221,152 @@ struct siba_cc_pmu_res_depend {
     	uint32_t		depend;
     };
     
    +enum siba_sprom_vars {
    +	SIBA_SPROMVAR_REV,
    +	SIBA_SPROMVAR_MAC_80211BG,
    +	SIBA_SPROMVAR_MAC_ETH,
    +	SIBA_SPROMVAR_MAC_80211A,
    +	SIBA_SPROMVAR_MII_ETH0,
    +	SIBA_SPROMVAR_MII_ETH1,
    +	SIBA_SPROMVAR_MDIO_ETH0,
    +	SIBA_SPROMVAR_MDIO_ETH1,
    +	SIBA_SPROMVAR_BREV,
    +	SIBA_SPROMVAR_CCODE,
    +	SIBA_SPROMVAR_ANT_A,
    +	SIBA_SPROMVAR_ANT_BG,
    +	SIBA_SPROMVAR_PA0B0,
    +	SIBA_SPROMVAR_PA0B1,
    +	SIBA_SPROMVAR_PA0B2,
    +	SIBA_SPROMVAR_PA1B0,
    +	SIBA_SPROMVAR_PA1B1,
    +	SIBA_SPROMVAR_PA1B2,
    +	SIBA_SPROMVAR_PA1LOB0,
    +	SIBA_SPROMVAR_PA1LOB1,
    +	SIBA_SPROMVAR_PA1LOB2,
    +	SIBA_SPROMVAR_PA1HIB0,
    +	SIBA_SPROMVAR_PA1HIB1,
    +	SIBA_SPROMVAR_PA1HIB2,
    +	SIBA_SPROMVAR_GPIO0,
    +	SIBA_SPROMVAR_GPIO1,
    +	SIBA_SPROMVAR_GPIO2,
    +	SIBA_SPROMVAR_GPIO3,
    +	SIBA_SPROMVAR_MAXPWR_AL,
    +	SIBA_SPROMVAR_MAXPWR_A,
    +	SIBA_SPROMVAR_MAXPWR_AH,
    +	SIBA_SPROMVAR_MAXPWR_BG,
    +	SIBA_SPROMVAR_RXPO2G,
    +	SIBA_SPROMVAR_RXPO5G,
    +	SIBA_SPROMVAR_TSSI_A,
    +	SIBA_SPROMVAR_TSSI_BG,
    +	SIBA_SPROMVAR_TRI2G,
    +	SIBA_SPROMVAR_TRI5GL,
    +	SIBA_SPROMVAR_TRI5G,
    +	SIBA_SPROMVAR_TRI5GH,
    +	SIBA_SPROMVAR_RSSISAV2G,
    +	SIBA_SPROMVAR_RSSISMC2G,
    +	SIBA_SPROMVAR_RSSISMF2G,
    +	SIBA_SPROMVAR_BXA2G,
    +	SIBA_SPROMVAR_RSSISAV5G,
    +	SIBA_SPROMVAR_RSSISMC5G,
    +	SIBA_SPROMVAR_RSSISMF5G,
    +	SIBA_SPROMVAR_BXA5G,
    +	SIBA_SPROMVAR_CCK2GPO,
    +	SIBA_SPROMVAR_OFDM2GPO,
    +	SIBA_SPROMVAR_OFDM5GLPO,
    +	SIBA_SPROMVAR_OFDM5GPO,
    +	SIBA_SPROMVAR_OFDM5GHPO,
    +	SIBA_SPROMVAR_BF_LO,
    +	SIBA_SPROMVAR_BF_HI,
    +	SIBA_SPROMVAR_BF2_LO,
    +	SIBA_SPROMVAR_BF2_HI
    +};
    +
    +int		siba_read_sprom(device_t, device_t, int, uintptr_t *);
    +int		siba_write_sprom(device_t, device_t, int, uintptr_t);
    +
    +/**
    + * Generic sprom accessor generation macros for siba(4) drivers
    + */
    +#define __SPROM_ACCESSOR(varp, var, ivarp, ivar, type)			\
    +									\
    +static __inline type varp ## _get_ ## var(device_t dev)			\
    +{									\
    +	uintptr_t v;							\
    +	siba_read_sprom(device_get_parent(dev), dev,			\
    +	    ivarp ## _SPROMVAR_ ## ivar, &v);				\
    +	return ((type) v);						\
    +}									\
    +									\
    +static __inline void varp ## _set_ ## var(device_t dev, type t)		\
    +{									\
    +	uintptr_t v = (uintptr_t) t;					\
    +	siba_write_sprom(device_get_parent(dev), dev,			\
    +	    ivarp ## _SPROMVAR_ ## ivar, v);				\
    +}
    +
    +#define	SIBA_SPROM_ACCESSOR(var, ivar, type)				\
    +	__SPROM_ACCESSOR(siba_sprom, var, SIBA, ivar, type)
    +
    +SIBA_SPROM_ACCESSOR(rev,	REV,		uint8_t);
    +SIBA_SPROM_ACCESSOR(mac_80211bg,	MAC_80211BG,	uint8_t *);
    +SIBA_SPROM_ACCESSOR(mac_eth,	MAC_ETH,	uint8_t *);
    +SIBA_SPROM_ACCESSOR(mac_80211a,	MAC_80211A,	uint8_t *);
    +SIBA_SPROM_ACCESSOR(mii_eth0,	MII_ETH0,	uint8_t);
    +SIBA_SPROM_ACCESSOR(mii_eth1,	MII_ETH1,	uint8_t);
    +SIBA_SPROM_ACCESSOR(mdio_eth0,	MDIO_ETH0,	uint8_t);
    +SIBA_SPROM_ACCESSOR(mdio_eth1,	MDIO_ETH1,	uint8_t);
    +SIBA_SPROM_ACCESSOR(brev,	BREV,		uint8_t);
    +SIBA_SPROM_ACCESSOR(ccode,	CCODE,		uint8_t);
    +SIBA_SPROM_ACCESSOR(ant_a,	ANT_A,		uint8_t);
    +SIBA_SPROM_ACCESSOR(ant_bg,	ANT_BG,		uint8_t);
    +SIBA_SPROM_ACCESSOR(pa0b0,	PA0B0,		uint16_t);
    +SIBA_SPROM_ACCESSOR(pa0b1,	PA0B1,		uint16_t);
    +SIBA_SPROM_ACCESSOR(pa0b2,	PA0B2,		uint16_t);
    +SIBA_SPROM_ACCESSOR(pa1b0,	PA1B0,		uint16_t);
    +SIBA_SPROM_ACCESSOR(pa1b1,	PA1B1,		uint16_t);
    +SIBA_SPROM_ACCESSOR(pa1b2,	PA1B2,		uint16_t);
    +SIBA_SPROM_ACCESSOR(pa1lob0,	PA1LOB0,	uint16_t);
    +SIBA_SPROM_ACCESSOR(pa1lob1,	PA1LOB1,	uint16_t);
    +SIBA_SPROM_ACCESSOR(pa1lob2,	PA1LOB2,	uint16_t);
    +SIBA_SPROM_ACCESSOR(pa1hib0,	PA1HIB0,	uint16_t);
    +SIBA_SPROM_ACCESSOR(pa1hib1,	PA1HIB1,	uint16_t);
    +SIBA_SPROM_ACCESSOR(pa1hib2,	PA1HIB2,	uint16_t);
    +SIBA_SPROM_ACCESSOR(gpio0,	GPIO0,		uint8_t);
    +SIBA_SPROM_ACCESSOR(gpio1,	GPIO1,		uint8_t);
    +SIBA_SPROM_ACCESSOR(gpio2,	GPIO2,		uint8_t);
    +SIBA_SPROM_ACCESSOR(gpio3,	GPIO3,		uint8_t);
    +SIBA_SPROM_ACCESSOR(maxpwr_al,	MAXPWR_AL,	uint16_t);
    +SIBA_SPROM_ACCESSOR(maxpwr_a,	MAXPWR_A,	uint16_t);
    +SIBA_SPROM_ACCESSOR(maxpwr_ah,	MAXPWR_AH,	uint16_t);
    +SIBA_SPROM_ACCESSOR(maxpwr_bg,	MAXPWR_BG,	uint16_t);
    +SIBA_SPROM_ACCESSOR(rxpo2g,	RXPO2G,		uint8_t);
    +SIBA_SPROM_ACCESSOR(rxpo5g,	RXPO5G,		uint8_t);
    +SIBA_SPROM_ACCESSOR(tssi_a,	TSSI_A,		uint8_t);
    +SIBA_SPROM_ACCESSOR(tssi_bg,	TSSI_BG,	uint8_t);
    +SIBA_SPROM_ACCESSOR(tri2g,	TRI2G,		uint8_t);
    +SIBA_SPROM_ACCESSOR(tri5gl,	TRI5GL,		uint8_t);
    +SIBA_SPROM_ACCESSOR(tri5g,	TRI5G,		uint8_t);
    +SIBA_SPROM_ACCESSOR(tri5gh,	TRI5GH,		uint8_t);
    +SIBA_SPROM_ACCESSOR(rssisav2g,	RSSISAV2G,	uint8_t);
    +SIBA_SPROM_ACCESSOR(rssismc2g,	RSSISMC2G,	uint8_t);
    +SIBA_SPROM_ACCESSOR(rssismf2g,	RSSISMF2G,	uint8_t);
    +SIBA_SPROM_ACCESSOR(bxa2g,	BXA2G,		uint8_t);
    +SIBA_SPROM_ACCESSOR(rssisav5g,	RSSISAV5G,	uint8_t);
    +SIBA_SPROM_ACCESSOR(rssismc5g,	RSSISMC5G,	uint8_t);
    +SIBA_SPROM_ACCESSOR(rssismf5g,	RSSISMF5G,	uint8_t);
    +SIBA_SPROM_ACCESSOR(bxa5g,	BXA5G,		uint8_t);
    +SIBA_SPROM_ACCESSOR(cck2gpo,	CCK2GPO,	uint16_t);
    +SIBA_SPROM_ACCESSOR(ofdm2gpo,	OFDM2GPO,	uint32_t);
    +SIBA_SPROM_ACCESSOR(ofdm5glpo,	OFDM5GLPO,	uint32_t);
    +SIBA_SPROM_ACCESSOR(ofdm5gpo,	OFDM5GPO,	uint32_t);
    +SIBA_SPROM_ACCESSOR(ofdm5ghpo,	OFDM5GHPO,	uint32_t);
    +SIBA_SPROM_ACCESSOR(bf_lo,	BF_LO,		uint16_t);
    +SIBA_SPROM_ACCESSOR(bf_hi,	BF_HI,		uint16_t);
    +SIBA_SPROM_ACCESSOR(bf2_lo,	BF2_LO,		uint16_t);
    +SIBA_SPROM_ACCESSOR(bf2_hi,	BF2_HI,		uint16_t);
    +
    +#undef SIBA_SPROM_ACCESSOR
    +
     struct siba_sprom {
     	uint8_t			rev;		/* revision */
     	uint8_t			mac_80211bg[6];	/* address for 802.11b/g */
    @@ -358,6 +530,7 @@ struct siba_softc {
     	uint16_t			siba_pci_did;
     	uint16_t			siba_pci_subvid;
     	uint16_t			siba_pci_subdid;
    +	uint8_t				siba_pci_revid;
     	int				siba_mem_rid;
     
     	uint16_t			siba_chipid;	/* for CORE 0 */
    @@ -368,41 +541,32 @@ struct siba_softc {
     	struct siba_pci			siba_pci;	/* PCI-core */
     	const struct siba_bus_ops	*siba_ops;
     
    -	/* board informations */
    -	uint16_t			siba_board_vendor;
    -	uint16_t			siba_board_type;
    -	uint16_t			siba_board_rev;
     	struct siba_sprom		siba_sprom;	/* SPROM */
     	uint16_t			siba_spromsize;	/* in word size */
     };
     
    -void		siba_powerup(struct siba_softc *, int);
    -uint16_t	siba_read_2(struct siba_dev_softc *, uint16_t);
    -void		siba_write_2(struct siba_dev_softc *, uint16_t, uint16_t);
    -uint32_t	siba_read_4(struct siba_dev_softc *, uint16_t);
    -void		siba_write_4(struct siba_dev_softc *, uint16_t, uint32_t);
    -void		siba_dev_up(struct siba_dev_softc *, uint32_t);
    -void		siba_dev_down(struct siba_dev_softc *, uint32_t);
    -int		siba_powerdown(struct siba_softc *);
    -int		siba_dev_isup(struct siba_dev_softc *);
    -void		siba_pcicore_intr(struct siba_pci *, struct siba_dev_softc *);
    -uint32_t	siba_dma_translation(struct siba_dev_softc *);
    -void		*siba_dma_alloc_consistent(struct siba_dev_softc *, size_t,
    -		    bus_addr_t *);
    -void		siba_read_multi_1(struct siba_dev_softc *, void *, size_t,
    -		    uint16_t);
    -void		siba_read_multi_2(struct siba_dev_softc *, void *, size_t,
    -		    uint16_t);
    -void		siba_read_multi_4(struct siba_dev_softc *, void *, size_t,
    -		    uint16_t);
    -void		siba_write_multi_1(struct siba_dev_softc *, const void *,
    -		    size_t, uint16_t);
    -void		siba_write_multi_2(struct siba_dev_softc *, const void *,
    -		    size_t, uint16_t);
    -void		siba_write_multi_4(struct siba_dev_softc *, const void *,
    -		    size_t, uint16_t);
    -void		siba_barrier(struct siba_dev_softc *, int);
    -void		siba_cc_pmu_set_ldovolt(struct siba_cc *, int, uint32_t);
    -void		siba_cc_pmu_set_ldoparef(struct siba_cc *, uint8_t);
    +void		siba_powerup(device_t, int);
    +int		siba_powerdown(device_t);
    +uint16_t	siba_read_2(device_t, uint16_t);
    +void		siba_write_2(device_t, uint16_t, uint16_t);
    +uint32_t	siba_read_4(device_t, uint16_t);
    +void		siba_write_4(device_t, uint16_t, uint32_t);
    +void		siba_dev_up(device_t, uint32_t);
    +void		siba_dev_down(device_t, uint32_t);
    +int		siba_dev_isup(device_t);
    +void		siba_pcicore_intr(device_t);
    +uint32_t	siba_dma_translation(device_t);
    +void		siba_read_multi_1(device_t, void *, size_t, uint16_t);
    +void		siba_read_multi_2(device_t, void *, size_t, uint16_t);
    +void		siba_read_multi_4(device_t, void *, size_t, uint16_t);
    +void		siba_write_multi_1(device_t, const void *, size_t, uint16_t);
    +void		siba_write_multi_2(device_t, const void *, size_t, uint16_t);
    +void		siba_write_multi_4(device_t, const void *, size_t, uint16_t);
    +void		siba_barrier(device_t, int);
    +void		siba_cc_pmu_set_ldovolt(device_t, int, uint32_t);
    +void		siba_cc_pmu_set_ldoparef(device_t, uint8_t);
    +void		siba_gpio_set(device_t, uint32_t);
    +uint32_t	siba_gpio_get(device_t);
    +void		siba_fix_imcfglobug(device_t);
     
     #endif /* _SIBA_SIBAVAR_H_ */
    
    From 06c84dc09b5382fdd378f6e368c393d33c2e2c1c Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Wed, 21 Apr 2010 00:23:23 +0000
    Subject: [PATCH 2073/2592] MFC r205141:   enables S/W beacon miss handler.
    
      Reported by:	imp
    ---
     sys/dev/bwn/if_bwn.c | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index 973ba85ba41..a48548b4768 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -1076,6 +1076,8 @@ bwn_attach_post(struct bwn_softc *sc)
     		| IEEE80211_C_TXPMGT		/* capable of txpow mgt */
     		;
     
    +	ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;	/* s/w bmiss */
    +
     	/* call MI attach routine. */
     	ieee80211_ifattach(ic,
     	    bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
    
    From 79d7271eb5b7e82b824745ec62a0afbadd6def0e Mon Sep 17 00:00:00 2001
    From: Maxim Konovalov 
    Date: Wed, 21 Apr 2010 05:35:06 +0000
    Subject: [PATCH 2075/2592] MFC r205671: trim leading w/space.
    
    ---
     usr.sbin/sysinstall/sysinstall.8 | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/usr.sbin/sysinstall/sysinstall.8 b/usr.sbin/sysinstall/sysinstall.8
    index 46a14fc8d9c..66ab552327d 100644
    --- a/usr.sbin/sysinstall/sysinstall.8
    +++ b/usr.sbin/sysinstall/sysinstall.8
    @@ -543,7 +543,7 @@ Commit any rc.conf changes to disk.
     Preserve existing rc.conf parameters.
     This is useful if you have a post-install script which modifies rc.conf.
     .El
    - .It installExpress
    +.It installExpress
     Start an "express" installation, asking few questions of
     the user.
     .Pp
    
    From f81dc89a9d8df5327d12d2e1d73ead5110d02f88 Mon Sep 17 00:00:00 2001
    From: Maxim Konovalov 
    Date: Wed, 21 Apr 2010 05:36:53 +0000
    Subject: [PATCH 2076/2592] MFC r205672: fix typo.
    
    ---
     sbin/setkey/setkey.8 | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sbin/setkey/setkey.8 b/sbin/setkey/setkey.8
    index 12c9cc2dc71..1339c49f4d8 100644
    --- a/sbin/setkey/setkey.8
    +++ b/sbin/setkey/setkey.8
    @@ -674,7 +674,7 @@ add 10.0.11.41 10.0.11.33 esp 0x10001
     	-A hmac-md5 "authentication!!" ;
     
     .Ed
    -Get the SA information assocaited with first example above:
    +Get the SA information associated with first example above:
     .Bd -literal -offset
     get 3ffe:501:4819::1 3ffe:501:481d::1 ah 123456 ;
     
    
    From 9e0142f045bb162889408775b3de8817f7a7b6bf Mon Sep 17 00:00:00 2001
    From: Maxim Konovalov 
    Date: Wed, 21 Apr 2010 05:38:16 +0000
    Subject: [PATCH 2077/2592] MFC r205873: remove duplication, improve wording.
    
    ---
     usr.sbin/mtree/mtree.8 | 5 +----
     1 file changed, 1 insertion(+), 4 deletions(-)
    
    diff --git a/usr.sbin/mtree/mtree.8 b/usr.sbin/mtree/mtree.8
    index f0a93ed8cda..119481b6746 100644
    --- a/usr.sbin/mtree/mtree.8
    +++ b/usr.sbin/mtree/mtree.8
    @@ -41,9 +41,6 @@
     .Op Fl f Ar spec
     .Ek
     .Bk -words
    -.Op Fl f Ar spec
    -.Ek
    -.Bk -words
     .Op Fl K Ar keywords
     .Ek
     .Bk -words
    @@ -119,7 +116,7 @@ Same as
     except a status of 2 is returned if the file hierarchy did not match
     the specification.
     .It Fl w
    -Make some errorconditions non-fatal warnings.
    +Make some errors non-fatal warnings.
     .It Fl x
     Do not descend below mount points in the file hierarchy.
     .It Fl f Ar file
    
    From 6cf6ace6cd75c9a99f4bb0d53556e828f4afb2bf Mon Sep 17 00:00:00 2001
    From: Maxim Konovalov 
    Date: Wed, 21 Apr 2010 05:39:51 +0000
    Subject: [PATCH 2078/2592] MFC r205874: make sockstat -6 output more readable
     for long ipv6 addresses.
    
    ---
     usr.bin/sockstat/sockstat.c | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
    index 1b2f1417b9c..e66dc41337c 100644
    --- a/usr.bin/sockstat/sockstat.c
    +++ b/usr.bin/sockstat/sockstat.c
    @@ -621,6 +621,8 @@ display(void)
     		case AF_INET:
     		case AF_INET6:
     			pos += printaddr(s->family, &s->laddr);
    +			if (s->family == AF_INET6 && pos >= 58)
    +				pos += xprintf(" ");
     			while (pos < 58)
     				pos += xprintf(" ");
     			pos += printaddr(s->family, &s->faddr);
    
    From 124981e16f7eb2b6f4bc10c9e65b66ff8a8b2c17 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= 
    Date: Wed, 21 Apr 2010 06:33:10 +0000
    Subject: [PATCH 2079/2592] MFH OpenSSH 5.4p1
    
    ---
     crypto/openssh/ChangeLog                      | 1258 +++++++++++
     crypto/openssh/INSTALL                        |    6 +-
     crypto/openssh/PROTOCOL                       |   37 +-
     crypto/openssh/PROTOCOL.agent                 |   24 +-
     crypto/openssh/PROTOCOL.certkeys              |  193 ++
     crypto/openssh/PROTOCOL.mux                   |  196 ++
     crypto/openssh/README                         |    4 +-
     crypto/openssh/README.platform                |   14 +-
     crypto/openssh/README.smartcard               |   93 -
     crypto/openssh/addrmatch.c                    |   78 +-
     crypto/openssh/auth-krb5.c                    |   13 +-
     crypto/openssh/auth-options.c                 |  169 +-
     crypto/openssh/auth-options.h                 |    4 +-
     crypto/openssh/auth-pam.c                     |   10 +-
     crypto/openssh/auth-passwd.c                  |    2 +-
     crypto/openssh/auth-rh-rsa.c                  |    5 +-
     crypto/openssh/auth-rhosts.c                  |   10 +-
     crypto/openssh/auth-rsa.c                     |    5 +-
     crypto/openssh/auth-sia.c                     |   53 -
     crypto/openssh/auth.c                         |   96 +-
     crypto/openssh/auth.h                         |    6 +-
     crypto/openssh/auth1.c                        |   10 +-
     crypto/openssh/auth2-hostbased.c              |    5 +-
     crypto/openssh/auth2-jpake.c                  |    7 +-
     crypto/openssh/auth2-kbdint.c                 |    4 -
     crypto/openssh/auth2-none.c                   |    4 -
     crypto/openssh/auth2-passwd.c                 |    4 -
     crypto/openssh/auth2-pubkey.c                 |   92 +-
     crypto/openssh/auth2.c                        |    4 +-
     crypto/openssh/authfd.c                       |   30 +-
     crypto/openssh/authfd.h                       |    3 +-
     crypto/openssh/authfile.c                     |   83 +-
     crypto/openssh/authfile.h                     |    3 +-
     crypto/openssh/bufaux.c                       |   28 +-
     crypto/openssh/buffer.c                       |    8 +-
     crypto/openssh/buffer.h                       |    9 +-
     crypto/openssh/canohost.c                     |   42 +-
     crypto/openssh/canohost.h                     |    4 +-
     crypto/openssh/channels.c                     |  283 ++-
     crypto/openssh/channels.h                     |   23 +-
     crypto/openssh/clientloop.c                   |   98 +-
     crypto/openssh/clientloop.h                   |   12 +-
     crypto/openssh/config.guess                   |  238 +-
     crypto/openssh/config.h                       |   56 +-
     crypto/openssh/config.h.in                    |   50 +-
     crypto/openssh/defines.h                      |   21 +-
     crypto/openssh/dh.c                           |    4 +-
     crypto/openssh/dns.c                          |    8 +-
     crypto/openssh/dns.h                          |    6 +-
     crypto/openssh/gss-genr.c                     |    2 +-
     crypto/openssh/hostfile.c                     |  101 +-
     crypto/openssh/hostfile.h                     |    7 +-
     crypto/openssh/includes.h                     |    3 +-
     crypto/openssh/jpake.c                        |  181 +-
     crypto/openssh/jpake.h                        |   38 +-
     crypto/openssh/kex.c                          |   15 +-
     crypto/openssh/kex.h                          |    9 +-
     crypto/openssh/kexdhs.c                       |   21 +-
     crypto/openssh/kexgexs.c                      |   22 +-
     crypto/openssh/key.c                          |  615 +++++-
     crypto/openssh/key.h                          |   32 +-
     crypto/openssh/loginrec.c                     |    4 +-
     crypto/openssh/match.h                        |    4 +-
     crypto/openssh/misc.c                         |   29 +-
     crypto/openssh/misc.h                         |    3 +-
     crypto/openssh/monitor.c                      |   43 +-
     crypto/openssh/monitor_fdpass.c               |   23 +-
     crypto/openssh/monitor_mm.c                   |    2 +-
     crypto/openssh/monitor_wrap.c                 |   48 +-
     crypto/openssh/monitor_wrap.h                 |   10 +-
     crypto/openssh/mux.c                          | 1923 +++++++++++++----
     crypto/openssh/myproposal.h                   |    6 +-
     crypto/openssh/nchan.c                        |   21 +-
     .../openssh/openbsd-compat/bsd-cygwin_util.c  |  133 --
     .../openssh/openbsd-compat/bsd-cygwin_util.h  |    5 +-
     crypto/openssh/openbsd-compat/daemon.c        |   10 -
     .../openssh/openbsd-compat/getrrsetbyname.c   |    2 +-
     .../openssh/openbsd-compat/openbsd-compat.h   |   10 +-
     .../openssh/openbsd-compat/openssl-compat.c   |   12 +-
     .../openssh/openbsd-compat/openssl-compat.h   |    6 +-
     crypto/openssh/openbsd-compat/port-aix.c      |   44 +-
     crypto/openssh/openbsd-compat/port-aix.h      |   13 +-
     crypto/openssh/openbsd-compat/port-linux.c    |   98 +-
     crypto/openssh/openbsd-compat/port-linux.h    |    8 +-
     crypto/openssh/openbsd-compat/pwcache.c       |  114 +
     .../openssh/openbsd-compat/readpassphrase.c   |   78 +-
     crypto/openssh/packet.c                       |  997 +++++----
     crypto/openssh/packet.h                       |   17 +-
     crypto/openssh/pathnames.h                    |    7 +-
     crypto/openssh/pkcs11.h                       | 1357 ++++++++++++
     crypto/openssh/platform.c                     |   24 +-
     crypto/openssh/platform.h                     |    7 +-
     crypto/openssh/readconf.c                     |   28 +-
     crypto/openssh/readconf.h                     |    6 +-
     crypto/openssh/roaming.h                      |   44 +
     crypto/openssh/roaming_client.c               |  280 +++
     crypto/openssh/roaming_common.c               |  244 +++
     crypto/openssh/roaming_dummy.c                |   61 +
     crypto/openssh/roaming_serv.c                 |   31 +
     crypto/openssh/scard-opensc.c                 |  532 -----
     crypto/openssh/scard.c                        |  571 -----
     crypto/openssh/scard.h                        |   39 -
     crypto/openssh/schnorr.c                      |  378 +++-
     crypto/openssh/schnorr.h                      |   60 +
     crypto/openssh/scp.1                          |    6 +-
     crypto/openssh/scp.c                          |   21 +-
     crypto/openssh/servconf.c                     |   64 +-
     crypto/openssh/servconf.h                     |    8 +-
     crypto/openssh/serverloop.c                   |   15 +-
     crypto/openssh/session.c                      |  126 +-
     crypto/openssh/sftp-client.c                  |  301 ++-
     crypto/openssh/sftp-client.h                  |   21 +-
     crypto/openssh/sftp-common.c                  |   31 +-
     crypto/openssh/sftp-common.h                  |    4 +-
     crypto/openssh/sftp-server.8                  |   28 +-
     crypto/openssh/sftp-server.c                  |  121 +-
     crypto/openssh/sftp.1                         |   93 +-
     crypto/openssh/sftp.c                         |  856 ++++++--
     crypto/openssh/ssh-add.1                      |   32 +-
     crypto/openssh/ssh-add.c                      |   54 +-
     crypto/openssh/ssh-agent.1                    |   25 +-
     crypto/openssh/ssh-agent.c                    |  163 +-
     crypto/openssh/ssh-dss.c                      |   10 +-
     crypto/openssh/ssh-keygen.1                   |  210 +-
     crypto/openssh/ssh-keygen.c                   |  636 +++++-
     crypto/openssh/ssh-keyscan.1                  |    4 +-
     crypto/openssh/ssh-keyscan.c                  |    2 +-
     crypto/openssh/ssh-keysign.c                  |    4 +-
     crypto/openssh/ssh-pkcs11-client.c            |  238 ++
     crypto/openssh/ssh-pkcs11-helper.0            |   25 +
     crypto/openssh/ssh-pkcs11-helper.8            |   43 +
     crypto/openssh/ssh-pkcs11-helper.c            |  372 ++++
     crypto/openssh/ssh-pkcs11.c                   |  564 +++++
     crypto/openssh/ssh-pkcs11.h                   |   20 +
     crypto/openssh/ssh-rand-helper.c              |    9 +-
     crypto/openssh/ssh-rsa.c                      |   10 +-
     crypto/openssh/ssh.1                          |   92 +-
     crypto/openssh/ssh.c                          |  193 +-
     crypto/openssh/ssh2.h                         |   12 +-
     crypto/openssh/ssh_config                     |    5 +-
     crypto/openssh/ssh_config.5                   |   42 +-
     crypto/openssh/ssh_namespace.h                |   61 +-
     crypto/openssh/sshconnect.c                   |  114 +-
     crypto/openssh/sshconnect.h                   |    4 +-
     crypto/openssh/sshconnect2.c                  |   66 +-
     crypto/openssh/sshd.8                         |   79 +-
     crypto/openssh/sshd.c                         |  144 +-
     crypto/openssh/sshd_config                    |   11 +-
     crypto/openssh/sshd_config.5                  |   65 +-
     crypto/openssh/sshlogin.c                     |   10 +-
     crypto/openssh/sshpty.h                       |    6 +-
     crypto/openssh/sshtty.c                       |   23 +-
     crypto/openssh/uuencode.c                     |   13 +-
     crypto/openssh/version.h                      |    6 +-
     lib/libpam/modules/pam_ssh/Makefile           |    3 +
     lib/libpam/modules/pam_ssh/pam_ssh.c          |    3 +
     secure/lib/libssh/Makefile                    |    7 +-
     secure/libexec/Makefile                       |    2 +-
     secure/libexec/sftp-server/Makefile           |    5 +-
     secure/libexec/ssh-keysign/Makefile           |    2 +-
     secure/libexec/ssh-pkcs11-helper/Makefile     |   16 +
     secure/usr.bin/scp/Makefile                   |    4 +
     secure/usr.bin/sftp/Makefile                  |    3 +
     secure/usr.bin/ssh-add/Makefile               |    4 +
     secure/usr.bin/ssh-agent/Makefile             |    4 +
     secure/usr.bin/ssh-keygen/Makefile            |    4 +
     secure/usr.bin/ssh-keyscan/Makefile           |    1 +
     secure/usr.bin/ssh/Makefile                   |    5 +-
     secure/usr.sbin/sshd/Makefile                 |    7 +-
     169 files changed, 12861 insertions(+), 4064 deletions(-)
     create mode 100644 crypto/openssh/PROTOCOL.certkeys
     create mode 100644 crypto/openssh/PROTOCOL.mux
     delete mode 100644 crypto/openssh/README.smartcard
     create mode 100644 crypto/openssh/openbsd-compat/pwcache.c
     create mode 100644 crypto/openssh/pkcs11.h
     create mode 100644 crypto/openssh/roaming.h
     create mode 100644 crypto/openssh/roaming_client.c
     create mode 100644 crypto/openssh/roaming_common.c
     create mode 100644 crypto/openssh/roaming_dummy.c
     create mode 100644 crypto/openssh/roaming_serv.c
     delete mode 100644 crypto/openssh/scard-opensc.c
     delete mode 100644 crypto/openssh/scard.c
     delete mode 100644 crypto/openssh/scard.h
     create mode 100644 crypto/openssh/schnorr.h
     create mode 100644 crypto/openssh/ssh-pkcs11-client.c
     create mode 100644 crypto/openssh/ssh-pkcs11-helper.0
     create mode 100644 crypto/openssh/ssh-pkcs11-helper.8
     create mode 100644 crypto/openssh/ssh-pkcs11-helper.c
     create mode 100644 crypto/openssh/ssh-pkcs11.c
     create mode 100644 crypto/openssh/ssh-pkcs11.h
     create mode 100644 secure/libexec/ssh-pkcs11-helper/Makefile
    
    diff --git a/crypto/openssh/ChangeLog b/crypto/openssh/ChangeLog
    index f802c0d7fc4..d6e4a4a25ae 100644
    --- a/crypto/openssh/ChangeLog
    +++ b/crypto/openssh/ChangeLog
    @@ -1,3 +1,1261 @@
    +20100307
    + - (djm) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2010/03/07 22:16:01
    +     [ssh-keygen.c]
    +     make internal strptime string match strftime format;
    +     suggested by vinschen AT redhat.com and markus@
    +   - djm@cvs.openbsd.org 2010/03/08 00:28:55
    +     [ssh-keygen.1]
    +     document permit-agent-forwarding certificate constraint; patch from
    +     stevesk@
    +   - djm@cvs.openbsd.org 2010/03/07 22:01:32
    +     [version.h]
    +     openssh-5.4
    + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
    +   crank version numbers
    + - (djm) Release OpenSSH-5.4p1
    +
    +20100307
    + - (dtucker) [auth.c] Bug #1710: call setauthdb on AIX before getpwuid so that
    +   it gets the passwd struct from the LAM that knows about the user which is
    +   not necessarily the default.  Patch from Alexandre Letourneau.
    + - (dtucker) [session.c] Bug #1567: move setpcred call to before chroot and
    +   do not set real uid, since that's needed for the chroot, and will be set
    +   by permanently_set_uid.
    + - (dtucker) [session.c] Also initialize creds to NULL for handing to
    +    setpcred.
    + - (dtucker) OpenBSD CVS Sync
    +   - dtucker@cvs.openbsd.org 2010/03/07 11:57:13
    +     [auth-rhosts.c monitor.c monitor_wrap.c session.c auth-options.c sshd.c]
    +     Hold authentication debug messages until after successful authentication.
    +     Fixes an info leak of environment variables specified in authorized_keys,
    +     reported by Jacob Appelbaum.  ok djm@
    +
    +20100305
    + - OpenBSD CVS Sync
    +   - jmc@cvs.openbsd.org 2010/03/04 12:51:25
    +     [ssh.1 sshd_config.5]
    +     tweak previous;
    +   - djm@cvs.openbsd.org 2010/03/04 20:35:08
    +     [ssh-keygen.1 ssh-keygen.c]
    +     Add a -L flag to print the contents of a certificate; ok markus@
    +   - jmc@cvs.openbsd.org 2010/03/04 22:52:40
    +     [ssh-keygen.1]
    +     fix Bk/Ek;
    +   - djm@cvs.openbsd.org 2010/03/04 23:17:25
    +     [sshd_config.5]
    +     missing word; spotted by jmc@
    +   - djm@cvs.openbsd.org 2010/03/04 23:19:29
    +     [ssh.1 sshd.8]
    +     move section on CA and revoked keys from ssh.1 to sshd.8's known hosts
    +     format section and rework it a bit; requested by jmc@
    +   - djm@cvs.openbsd.org 2010/03/04 23:27:25
    +     [auth-options.c ssh-keygen.c]
    +     "force-command" is not spelled "forced-command"; spotted by
    +     imorgan AT nas.nasa.gov
    +   - djm@cvs.openbsd.org 2010/03/05 02:58:11
    +     [auth.c]
    +     make the warning for a revoked key louder and more noticable
    +   - jmc@cvs.openbsd.org 2010/03/05 06:50:35
    +     [ssh.1 sshd.8]
    +     tweak previous;
    +   - jmc@cvs.openbsd.org 2010/03/05 08:31:20
    +     [ssh.1]
    +     document certificate authentication; help/ok djm
    +   - djm@cvs.openbsd.org 2010/03/05 10:28:21
    +     [ssh-add.1 ssh.1 ssh_config.5]
    +     mention loading of certificate files from [private]-cert.pub when
    +     they are present; feedback and ok jmc@
    + - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older
    +   compilers. OK djm@
    + - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure
    +   on some platforms
    + - (djm) [configure.ac] set -fno-strict-aliasing for gcc4; ok dtucker@
    +
    +20100304
    + - (djm) [ssh-keygen.c] Use correct local variable, instead of
    +   maybe-undefined global "optarg"
    + - (djm) [contrib/redhat/openssh.spec] Replace obsolete BuildPreReq
    +   on XFree86-devel with neutral /usr/include/X11/Xlib.h;
    +   imorgan AT nas.nasa.gov in bz#1731
    + - (djm) [.cvsignore] Ignore ssh-pkcs11-helper
    + - (djm) [regress/Makefile] Cleanup sshd_proxy_orig
    + - OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2010/03/03 01:44:36
    +     [auth-options.c key.c]
    +     reject strings with embedded ASCII nul chars in certificate key IDs,
    +     principal names and constraints
    +   - djm@cvs.openbsd.org 2010/03/03 22:49:50
    +     [sshd.8]
    +     the authorized_keys option for CA keys is "cert-authority", not
    +     "from=cert-authority". spotted by imorgan AT nas.nasa.gov
    +   - djm@cvs.openbsd.org 2010/03/03 22:50:40
    +     [PROTOCOL.certkeys]
    +     s/similar same/similar/; from imorgan AT nas.nasa.gov
    +   - djm@cvs.openbsd.org 2010/03/04 01:44:57
    +     [key.c]
    +     use buffer_get_string_ptr_ret() where we are checking the return
    +     value explicitly instead of the fatal()-causing buffer_get_string_ptr()
    +   - djm@cvs.openbsd.org 2010/03/04 10:36:03
    +     [auth-rh-rsa.c auth-rsa.c auth.c auth.h auth2-hostbased.c auth2-pubkey.c]
    +     [authfile.c authfile.h hostfile.c hostfile.h servconf.c servconf.h]
    +     [ssh-keygen.c ssh.1 sshconnect.c sshd_config.5]
    +     Add a TrustedUserCAKeys option to sshd_config to specify CA keys that
    +     are trusted to authenticate users (in addition than doing it per-user
    +     in authorized_keys).
    +     
    +     Add a RevokedKeys option to sshd_config and a @revoked marker to
    +     known_hosts to allow keys to me revoked and banned for user or host
    +     authentication.
    +     
    +     feedback and ok markus@
    +   - djm@cvs.openbsd.org 2010/03/03 00:47:23
    +     [regress/cert-hostkey.sh regress/cert-userkey.sh]
    +     add an extra test to ensure that authentication with the wrong
    +     certificate fails as it should (and it does)
    +   - djm@cvs.openbsd.org 2010/03/04 10:38:23
    +     [regress/cert-hostkey.sh regress/cert-userkey.sh]
    +     additional regression tests for revoked keys and TrustedUserCAKeys
    +
    +20100303
    + - (djm) [PROTOCOL.certkeys] Add RCS Ident
    + - OpenBSD CVS Sync
    +   - jmc@cvs.openbsd.org 2010/02/26 22:09:28
    +     [ssh-keygen.1 ssh.1 sshd.8]
    +     tweak previous;
    +   - otto@cvs.openbsd.org 2010/03/01 11:07:06
    +     [ssh-add.c]
    +     zap what seems to be a left-over debug message; ok markus@
    +   - djm@cvs.openbsd.org 2010/03/02 23:20:57
    +     [ssh-keygen.c]
    +     POSIX strptime is stricter than OpenBSD's so do a little dance to
    +     appease it.
    + - (djm) [regress/cert-userkey.sh] s/echo -n/echon/ here too
    +
    +20100302
    + - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from
    +   http://git.savannah.gnu.org/gitweb/ (2009-12-30 and 2010-01-22
    +   respectively).
    +
    +20100301
    + - (dtucker) [regress/{cert-hostkey,cfgmatch,cipher-speed}.sh} Replace
    +   "echo -n" with "echon" for portability.
    + - (dtucker) [openbsd-compat/port-linux.c] Make failure to write to the OOM
    +   adjust log at verbose only, since according to cjwatson in bug #1470
    +   some virtualization platforms don't allow writes.
    +
    +20100228
    + - (djm) [auth.c] On Cygwin, refuse usernames that have differences in
    +   case from that matched in the system password database. On this
    +   platform, passwords are stored case-insensitively, but sshd requires
    +   exact case matching for Match blocks in sshd_config(5). Based on
    +   a patch from vinschen AT redhat.com.
    + - (tim) [ssh-pkcs11-helper.c] Move declarations before calling functions
    +   to make older compilers (gcc 2.95) happy.
    +
    +20100227
    + - (djm) [ssh-pkcs11-helper.c ] Ensure RNG is initialised and seeded
    + - (djm) [openbsd-compat/bsd-cygwin_util.c] Reduce the set of environment
    +   variables copied into sshd child processes. From vinschen AT redhat.com
    +
    +20100226
    + - OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2010/02/26 20:29:54
    +     [PROTOCOL PROTOCOL.agent PROTOCOL.certkeys addrmatch.c auth-options.c]
    +     [auth-options.h auth.h auth2-pubkey.c authfd.c dns.c dns.h hostfile.c]
    +     [hostfile.h kex.h kexdhs.c kexgexs.c key.c key.h match.h monitor.c]
    +     [myproposal.h servconf.c servconf.h ssh-add.c ssh-agent.c ssh-dss.c]
    +     [ssh-keygen.1 ssh-keygen.c ssh-rsa.c ssh.1 ssh.c ssh2.h sshconnect.c]
    +     [sshconnect2.c sshd.8 sshd.c sshd_config.5]
    +     Add support for certificate key types for users and hosts.
    +     
    +     OpenSSH certificate key types are not X.509 certificates, but a much
    +     simpler format that encodes a public key, identity information and
    +     some validity constraints and signs it with a CA key. CA keys are
    +     regular SSH keys. This certificate style avoids the attack surface
    +     of X.509 certificates and is very easy to deploy.
    +     
    +     Certified host keys allow automatic acceptance of new host keys
    +     when a CA certificate is marked as trusted in ~/.ssh/known_hosts.
    +     see VERIFYING HOST KEYS in ssh(1) for details.
    +     
    +     Certified user keys allow authentication of users when the signing
    +     CA key is marked as trusted in authorized_keys. See "AUTHORIZED_KEYS
    +     FILE FORMAT" in sshd(8) for details.
    +     
    +     Certificates are minted using ssh-keygen(1), documentation is in
    +     the "CERTIFICATES" section of that manpage.
    +     
    +     Documentation on the format of certificates is in the file
    +     PROTOCOL.certkeys
    +     
    +     feedback and ok markus@
    +   - djm@cvs.openbsd.org 2010/02/26 20:33:21
    +     [Makefile regress/cert-hostkey.sh regress/cert-userkey.sh]
    +     regression tests for certified keys
    +
    +20100224
    + - (djm) [pkcs11.h ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c]
    +   [ssh-pkcs11.h] Add $OpenBSD$ RCS idents so we can sync portable
    + - (djm) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2010/02/11 20:37:47
    +     [pathnames.h]
    +     correct comment
    +   - dtucker@cvs.openbsd.org 2009/11/09 04:20:04
    +     [regress/Makefile]
    +     add regression test for ssh-keygen pubkey conversions
    +   - dtucker@cvs.openbsd.org 2010/01/11 02:53:44
    +     [regress/forwarding.sh]
    +     regress test for stdio forwarding
    +   - djm@cvs.openbsd.org 2010/02/09 04:57:36
    +     [regress/addrmatch.sh]
    +     clean up droppings
    +   - djm@cvs.openbsd.org 2010/02/09 06:29:02
    +     [regress/Makefile]
    +     turn on all the malloc(3) checking options when running regression
    +     tests. this has caught a few bugs for me in the past; ok dtucker@
    +   - djm@cvs.openbsd.org 2010/02/24 06:21:56
    +     [regress/test-exec.sh]
    +     wait for sshd to fully stop in cleanup() function; avoids races in tests
    +     that do multiple start_sshd/cleanup cycles; "I hate pidfiles" deraadt@
    +   - markus@cvs.openbsd.org 2010/02/08 10:52:47
    +     [regress/agent-pkcs11.sh]
    +     test for PKCS#11 support (currently disabled)
    + - (djm) [Makefile.in ssh-pkcs11-helper.8] Add manpage for PKCS#11 helper
    + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
    +   [contrib/suse/openssh.spec] Add PKCS#11 helper binary and manpage
    +
    +20100212
    + - (djm) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2010/02/02 22:49:34
    +     [bufaux.c]
    +     make buffer_get_string_ret() really non-fatal in all cases (it was
    +     using buffer_get_int(), which could fatal() on buffer empty);
    +     ok markus dtucker
    +   - markus@cvs.openbsd.org 2010/02/08 10:50:20
    +     [pathnames.h readconf.c readconf.h scp.1 sftp.1 ssh-add.1 ssh-add.c]
    +     [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config.5]
    +     replace our obsolete smartcard code with PKCS#11.
    +        ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf
    +     ssh(1) and ssh-keygen(1) use dlopen(3) directly to talk to a PKCS#11
    +     provider (shared library) while ssh-agent(1) delegates PKCS#11 to
    +     a forked a ssh-pkcs11-helper process.
    +     PKCS#11 is currently a compile time option.
    +     feedback and ok djm@; inspired by patches from Alon Bar-Lev
    +   - jmc@cvs.openbsd.org 2010/02/08 22:03:05
    +     [ssh-add.1 ssh-keygen.1 ssh.1 ssh.c]
    +     tweak previous; ok markus
    +   - djm@cvs.openbsd.org 2010/02/09 00:50:36
    +     [ssh-agent.c]
    +     fallout from PKCS#11: unbreak -D
    +   - djm@cvs.openbsd.org 2010/02/09 00:50:59
    +     [ssh-keygen.c]
    +     fix -Wall
    +   - djm@cvs.openbsd.org 2010/02/09 03:56:28
    +     [buffer.c buffer.h]
    +     constify the arguments to buffer_len, buffer_ptr and buffer_dump
    +   - djm@cvs.openbsd.org 2010/02/09 06:18:46
    +     [auth.c]
    +     unbreak ChrootDirectory+internal-sftp by skipping check for executable
    +     shell when chrooting; reported by danh AT wzrd.com; ok dtucker@
    +   - markus@cvs.openbsd.org 2010/02/10 23:20:38
    +     [ssh-add.1 ssh-keygen.1 ssh.1 ssh_config.5]
    +     pkcs#11 is no longer optional; improve wording; ok jmc@
    +   - jmc@cvs.openbsd.org 2010/02/11 13:23:29
    +     [ssh.1]
    +     libarary -> library;
    + - (djm) [INSTALL Makefile.in README.smartcard configure.ac scard-opensc.c]
    +   [scard.c scard.h pkcs11.h scard/Makefile.in scard/Ssh.bin.uu scard/Ssh.java]
    +   Remove obsolete smartcard support
    + - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c]
    +   Make it compile on OSX
    + - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c]
    +   Use ssh_get_progname to fill __progname
    + - (djm) [configure.ac] Enable PKCS#11 support only when we find a working
    +   dlopen()
    +
    +20100210
    + - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for
    +   getseuserbyname; patch from calebcase AT gmail.com via
    +   cjwatson AT debian.org
    +
    +20100202
    + - (djm) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2010/01/30 21:08:33
    +     [sshd.8]
    +     debug output goes to stderr, not "the system log"; ok markus dtucker
    +   - djm@cvs.openbsd.org 2010/01/30 21:12:08
    +     [channels.c]
    +     fake local addr:port when stdio fowarding as some servers (Tectia at
    +     least) validate that they are well-formed;
    +     reported by imorgan AT nas.nasa.gov
    +     ok dtucker
    +
    +20100130
    + - (djm) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2010/01/28 00:21:18
    +     [clientloop.c]
    +     downgrade an error() to a debug() - this particular case can be hit in
    +     normal operation for certain sequences of mux slave vs session closure
    +     and is harmless
    +   - djm@cvs.openbsd.org 2010/01/29 00:20:41
    +     [sshd.c]
    +     set FD_CLOEXEC on sock_in/sock_out; bz#1706 from jchadima AT redhat.com
    +     ok dtucker@
    +   - djm@cvs.openbsd.org 2010/01/29 20:16:17
    +     [mux.c]
    +     kill correct channel (was killing already-dead mux channel, not
    +     its session channel)
    +   - djm@cvs.openbsd.org 2010/01/30 02:54:53
    +     [mux.c]
    +     don't mark channel as read failed if it is already closing; suppresses
    +     harmless error messages when connecting to SSH.COM Tectia server
    +     report by imorgan AT nas.nasa.gov
    +
    +20100129
    + - (dtucker) [openbsd-compat/openssl-compat.c] Bug #1707: Call OPENSSL_config()
    +   after registering the hardware engines, which causes the openssl.cnf file to
    +   be processed.  See OpenSSL's man page for OPENSSL_config(3) for details.
    +   Patch from Solomon Peachy, ok djm@.
    +
    +20100128
    + - (djm) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2010/01/26 02:15:20
    +     [mux.c]
    +     -Wuninitialized and remove a // comment; from portable
    +     (Id sync only)
    +   - djm@cvs.openbsd.org 2010/01/27 13:26:17
    +     [mux.c]
    +     fix bug introduced in mux rewrite:
    +     
    +     In a mux master, when a socket to a mux slave closes before its server
    +     session (as may occur when the slave has been signalled), gracefully
    +     close the server session rather than deleting its channel immediately.
    +     A server may have more messages on that channel to send (e.g. an exit
    +     message) that will fatal() the client if they are sent to a channel that
    +     has been prematurely deleted.
    +     
    +     spotted by imorgan AT nas.nasa.gov
    +   - djm@cvs.openbsd.org 2010/01/27 19:21:39
    +     [sftp.c]
    +     add missing "p" flag to getopt optstring;
    +     bz#1704 from imorgan AT nas.nasa.gov
    +
    +20100126
    + - (djm) OpenBSD CVS Sync
    +   - tedu@cvs.openbsd.org 2010/01/17 21:49:09
    +     [ssh-agent.1]
    +     Correct and clarify ssh-add's password asking behavior.
    +     Improved text dtucker and ok jmc
    +   - dtucker@cvs.openbsd.org 2010/01/18 01:50:27
    +     [roaming_client.c]
    +     s/long long unsigned/unsigned long long/, from tim via portable
    +     (Id sync only, change already in portable)
    +   - djm@cvs.openbsd.org 2010/01/26 01:28:35
    +     [channels.c channels.h clientloop.c clientloop.h mux.c nchan.c ssh.c]
    +     rewrite ssh(1) multiplexing code to a more sensible protocol.
    +     
    +     The new multiplexing code uses channels for the listener and
    +     accepted control sockets to make the mux master non-blocking, so
    +     no stalls when processing messages from a slave.
    +     
    +     avoid use of fatal() in mux master protocol parsing so an errant slave
    +     process cannot take down a running master.
    +     
    +     implement requesting of port-forwards over multiplexed sessions. Any
    +     port forwards requested by the slave are added to those the master has
    +     established.
    +     
    +     add support for stdio forwarding ("ssh -W host:port ...") in mux slaves.
    +     
    +     document master/slave mux protocol so that other tools can use it to
    +     control a running ssh(1). Note: there are no guarantees that this
    +     protocol won't be incompatibly changed (though it is versioned).
    +     
    +     feedback Salvador Fandino, dtucker@
    +     channel changes ok markus@
    +
    +20100122
    + - (tim) [configure.ac] Due to constraints in Windows Sockets in terms of
    +   socket inheritance, reduce the default SO_RCVBUF/SO_SNDBUF buffer size
    +   in Cygwin to 65535. Patch from Corinna Vinschen.
    +
    +20100117
    + - (tim) [configure.ac] OpenServer 5 needs BROKEN_GETADDRINFO too.
    + - (tim) [configure.ac] On SVR5 systems, use the C99-conforming functions
    +   snprintf() and vsnprintf() named _xsnprintf() and _xvsnprintf().
    +
    +20100116
    + - (dtucker) [openbsd-compat/pwcache.c] Pull in includes.h and thus defines.h
    +   so we correctly detect whether or not we have a native user_from_uid.
    + - (dtucker) [openbsd-compat/openbsd-compat.h] Prototypes for user_from_uid
    +   and group_from_gid.
    + - (dtucker) [openbsd-compat/openbsd-compat.h] Fix prototypes, spotted by
    +   Tim.
    + - (dtucker) OpenBSD CVS Sync
    +   - markus@cvs.openbsd.org 2010/01/15 09:24:23
    +     [sftp-common.c]
    +     unused
    + - (dtucker) [openbsd-compat/pwcache.c] Shrink ifdef area to prevent unused
    +   variable warnings.
    + - (dtucker) [openbsd-compat/openbsd-compat.h] Typo.
    + - (tim) [regress/portnum.sh] Shell portability fix.
    + - (tim) [configure.ac] Define BROKEN_GETADDRINFO on SVR5 systems. The native
    +   getaddrinfo() is too old and limited for addr_pton() in addrmatch.c.
    + - (tim) [roaming_client.c] Use of  is not really portable so we
    +   use "openbsd-compat/sys-queue.h". s/long long unsigned/unsigned long long/
    +   to keep USL compilers happy.
    +
    +20100115
    + - (dtucker) OpenBSD CVS Sync
    +   - jmc@cvs.openbsd.org 2010/01/13 12:48:34
    +     [sftp.1 sftp.c]
    +     sftp.1: put ls -h in the right place
    +     sftp.c: as above, plus add -p to get/put, and shorten their arg names
    +     to keep the help usage nicely aligned
    +     ok djm
    +   - djm@cvs.openbsd.org 2010/01/13 23:47:26
    +     [auth.c]
    +     when using ChrootDirectory, make sure we test for the existence of the
    +     user's shell inside the chroot; bz #1679, patch from alex AT rtfs.hu;
    +     ok dtucker
    +   - dtucker@cvs.openbsd.org 2010/01/14 23:41:49
    +     [sftp-common.c]
    +     use user_from{uid,gid} to lookup up ids since it keeps a small cache.
    +     ok djm
    +   - guenther@cvs.openbsd.org 2010/01/15 00:05:22
    +     [sftp.c]
    +     Reset SIGTERM to SIG_DFL before executing ssh, so that even if sftp
    +     inherited SIGTERM as ignored it will still be able to kill the ssh it
    +     starts.
    +     ok dtucker@
    + - (dtucker) [openbsd-compat/pwcache.c] Pull in pwcache.c from OpenBSD (no
    +   changes yet but there will be some to come).
    + - (dtucker) [configure.ac openbsd-compat/{Makefile.in,pwcache.c} Portability
    +   for pwcache.  Also, added caching of negative hits.
    +
    +20100114
    + - (djm) [platform.h] Add missing prototype for
    +   platform_krb5_get_principal_name
    +
    +20100113
    + - (dtucker) [monitor_fdpass.c] Wrap poll.h include in ifdefs.
    + - (dtucker) [openbsd-compat/readpassphrase.c] Resync against OpenBSD's r1.18:
    +   missing restore of SIGTTOU and some whitespace.
    + - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.21.
    + - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.22.
    +   Fixes bz #1590, where sometimes you could not interrupt a connection while
    +   ssh was prompting for a passphrase or password.
    + - (dtucker) OpenBSD CVS Sync
    +   - dtucker@cvs.openbsd.org 2010/01/13 00:19:04
    +     [sshconnect.c auth.c]
    +     Fix a couple of typos/mispellings in comments
    +   - dtucker@cvs.openbsd.org 2010/01/13 01:10:56
    +     [key.c]
    +     Ignore and log any Protocol 1 keys where the claimed size is not equal to
    +     the actual size.  Noted by Derek Martin, ok djm@
    +   - dtucker@cvs.openbsd.org 2010/01/13 01:20:20
    +     [canohost.c ssh-keysign.c sshconnect2.c]
    +     Make HostBased authentication work with a ProxyCommand.  bz #1569, patch
    +     from imorgan at nas nasa gov, ok djm@
    +   - djm@cvs.openbsd.org 2010/01/13 01:40:16
    +     [sftp.c sftp-server.c sftp.1 sftp-common.c sftp-common.h]
    +     support '-h' (human-readable units) for sftp's ls command, just like
    +     ls(1); ok dtucker@
    +   - djm@cvs.openbsd.org 2010/01/13 03:48:13
    +     [servconf.c servconf.h sshd.c]
    +     avoid run-time failures when specifying hostkeys via a relative
    +     path by prepending the cwd in these cases; bz#1290; ok dtucker@
    +   - djm@cvs.openbsd.org 2010/01/13 04:10:50
    +     [sftp.c]
    +     don't append a space after inserting a completion of a directory (i.e.
    +     a path ending in '/') for a slightly better user experience; ok dtucker@
    + - (dtucker) [sftp-common.c] Wrap include of util.h in an ifdef.
    + - (tim) [defines.h] openbsd-compat/readpassphrase.c now needs _NSIG. 
    +   feedback and ok dtucker@
    +
    +20100112
    + - (dtucker) OpenBSD CVS Sync
    +   - dtucker@cvs.openbsd.org 2010/01/11 01:39:46
    +     [ssh_config channels.c ssh.1 channels.h ssh.c]
    +     Add a 'netcat mode' (ssh -W).  This connects stdio on the client to a
    +     single port forward on the server.  This allows, for example, using ssh as
    +     a ProxyCommand to route connections via intermediate servers.
    +     bz #1618, man page help from jmc@, ok markus@
    +   - dtucker@cvs.openbsd.org 2010/01/11 04:46:45
    +     [authfile.c sshconnect2.c]
    +     Do not prompt for a passphrase if we fail to open a keyfile, and log the
    +     reason the open failed to debug.
    +     bz #1693, found by tj AT castaglia org, ok djm@
    +   - djm@cvs.openbsd.org 2010/01/11 10:51:07
    +     [ssh-keygen.c]
    +     when converting keys, truncate key comments at 72 chars as per RFC4716;
    +     bz#1630 reported by tj AT castaglia.org; ok markus@
    +   - dtucker@cvs.openbsd.org 2010/01/12 00:16:47
    +     [authfile.c]
    +     Fix bug introduced in r1.78 (incorrect brace location) that broke key auth.
    +     Patch from joachim joachimschipper nl.
    +   - djm@cvs.openbsd.org 2010/01/12 00:58:25
    +     [monitor_fdpass.c]
    +     avoid spinning when fd passing on nonblocking sockets by calling poll()
    +     in the EINTR/EAGAIN path, much like we do in atomicio; ok dtucker@
    +   - djm@cvs.openbsd.org 2010/01/12 00:59:29
    +     [roaming_common.c]
    +     delete with extreme prejudice a debug() that fired with every keypress;
    +     ok dtucker deraadt
    +   - dtucker@cvs.openbsd.org 2010/01/12 01:31:05
    +     [session.c]
    +     Do not allow logins if /etc/nologin exists but is not readable by the user
    +     logging in.  Noted by Jan.Pechanec at Sun, ok djm@ deraadt@
    +   - djm@cvs.openbsd.org 2010/01/12 01:36:08
    +     [buffer.h bufaux.c]
    +     add a buffer_get_string_ptr_ret() that does the same as
    +     buffer_get_string_ptr() but does not fatal() on error; ok dtucker@
    +   - dtucker@cvs.openbsd.org 2010/01/12 08:33:17
    +     [session.c]
    +     Add explicit stat so we reliably detect nologin with bad perms.
    +     ok djm markus
    +
    +20100110
    + - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c]
    +   Remove hacks add for RoutingDomain in preparation for its removal.
    + - (dtucker) OpenBSD CVS Sync
    +   - dtucker@cvs.openbsd.org 2010/01/09 23:04:13
    +     [channels.c ssh.1 servconf.c sshd_config.5 sshd.c channels.h servconf.h
    +     ssh-keyscan.1 ssh-keyscan.c readconf.c sshconnect.c misc.c ssh.c
    +     readconf.h scp.1 sftp.1 ssh_config.5 misc.h]
    +     Remove RoutingDomain from ssh since it's now not needed.  It can be
    +     replaced with "route exec" or "nc -V" as a proxycommand.  "route exec"
    +     also ensures that trafic such as DNS lookups stays withing the specified
    +     routingdomain.  For example (from reyk):
    +     # route -T 2 exec /usr/sbin/sshd
    +     or inherited from the parent process
    +     $ route -T 2 exec sh
    +     $ ssh 10.1.2.3
    +     ok deraadt@ markus@ stevesk@ reyk@
    +   - dtucker@cvs.openbsd.org 2010/01/10 03:51:17
    +     [servconf.c]
    +     Add ChrootDirectory to sshd.c test-mode output
    +   - dtucker@cvs.openbsd.org 2010/01/10 07:15:56
    +     [auth.c]
    +     Output a debug if we can't open an existing keyfile.  bz#1694, ok djm@
    +
    +20100109
    + - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't
    +   have it.
    + - (dtucker) [defines.h] define PRIu64 for platforms that don't have it.
    + - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef.
    + - (dtucker) [loginrec.c] Use the SUSv3 specified name for the user name
    +   when using utmpx.  Patch from Ed Schouten.
    + - (dtucker) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2010/01/09 00:20:26
    +     [sftp-server.c sftp-server.8]
    +     add a 'read-only' mode to sftp-server(8) that disables open in write mode
    +     and all other fs-modifying protocol methods. bz#430 ok dtucker@
    +   - djm@cvs.openbsd.org 2010/01/09 00:57:10
    +     [PROTOCOL]
    +     tweak language
    +   - jmc@cvs.openbsd.org 2010/01/09 03:36:00
    +     [sftp-server.8]
    +     bad place to forget a comma...
    +   - djm@cvs.openbsd.org 2010/01/09 05:04:24
    +     [mux.c sshpty.h clientloop.c sshtty.c]
    +     quell tc[gs]etattr warnings when forcing a tty (ssh -tt), since we
    +     usually don't actually have a tty to read/set; bz#1686 ok dtucker@
    +   - dtucker@cvs.openbsd.org 2010/01/09 05:17:00
    +     [roaming_client.c]
    +     Remove a PRIu64 format string that snuck in with roaming.  ok djm@
    +   - dtucker@cvs.openbsd.org 2010/01/09 11:13:02
    +     [sftp.c]
    +     Prevent sftp from derefing a null pointer when given a "-" without a
    +     command.  Also, allow whitespace to follow a "-".  bz#1691, path from
    +     Colin Watson via Debian.  ok djm@ deraadt@
    +   - dtucker@cvs.openbsd.org 2010/01/09 11:17:56
    +     [sshd.c]
    +     Afer sshd receives a SIGHUP, ignore subsequent HUPs while sshd re-execs
    +     itself.  Prevents two HUPs in quick succession from resulting in sshd
    +     dying.  bz#1692, patch from Colin Watson via Ubuntu.
    + - (dtucker) [defines.h] Remove now-undeeded PRIu64 define.
    +
    +20100108
    + - (dtucker) OpenBSD CVS Sync
    +   - andreas@cvs.openbsd.org 2009/10/24 11:11:58
    +     [roaming.h]
    +     Declarations needed for upcoming changes.
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/10/24 11:13:54
    +     [sshconnect2.c kex.h kex.c]
    +     Let the client detect if the server supports roaming by looking
    +     for the resume@appgate.com kex algorithm.
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/10/24 11:15:29
    +     [clientloop.c]
    +     client_loop() must detect if the session has been suspended and resumed,
    +     and take appropriate action in that case.
    +     From Martin Forssen, maf at appgate dot com
    +   - andreas@cvs.openbsd.org 2009/10/24 11:19:17
    +     [ssh2.h]
    +     Define the KEX messages used when resuming a suspended connection.
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/10/24 11:22:37
    +     [roaming_common.c]
    +     Do the actual suspend/resume in the client. This won't be useful until
    +     the server side supports roaming.
    +     Most code from Martin Forssen, maf at appgate dot com. Some changes by
    +     me and markus@
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/10/24 11:23:42
    +     [ssh.c]
    +     Request roaming to be enabled if UseRoaming is true and the server
    +     supports it.
    +     ok markus@
    +   - reyk@cvs.openbsd.org 2009/10/28 16:38:18
    +     [ssh_config.5 sshd.c misc.h ssh-keyscan.1 readconf.h sshconnect.c
    +     channels.c channels.h servconf.h servconf.c ssh.1 ssh-keyscan.c scp.1
    +     sftp.1 sshd_config.5 readconf.c ssh.c misc.c]
    +     Allow to set the rdomain in ssh/sftp/scp/sshd and ssh-keyscan.
    +     ok markus@
    +   - jmc@cvs.openbsd.org 2009/10/28 21:45:08
    +     [sshd_config.5 sftp.1]
    +     tweak previous;
    +   - djm@cvs.openbsd.org 2009/11/10 02:56:22
    +     [ssh_config.5]
    +     explain the constraints on LocalCommand some more so people don't
    +     try to abuse it.
    +   - djm@cvs.openbsd.org 2009/11/10 02:58:56
    +     [sshd_config.5]
    +     clarify that StrictModes does not apply to ChrootDirectory. Permissions
    +     and ownership are always checked when chrooting. bz#1532
    +   - dtucker@cvs.openbsd.org 2009/11/10 04:30:45
    +     [sshconnect2.c channels.c sshconnect.c]
    +     Set close-on-exec on various descriptors so they don't get leaked to
    +     child processes.  bz #1643, patch from jchadima at redhat, ok deraadt.
    +   - markus@cvs.openbsd.org 2009/11/11 21:37:03
    +     [channels.c channels.h]
    +     fix race condition in x11/agent channel allocation: don't read after
    +     the end of the select read/write fdset and make sure a reused FD
    +     is not touched before the pre-handlers are called.
    +     with and ok djm@
    +   - djm@cvs.openbsd.org 2009/11/17 05:31:44
    +     [clientloop.c]
    +     fix incorrect exit status when multiplexing and channel ID 0 is recycled
    +     bz#1570 reported by peter.oliver AT eon-is.co.uk; ok dtucker
    +   - djm@cvs.openbsd.org 2009/11/19 23:39:50
    +     [session.c]
    +     bz#1606: error when an attempt is made to connect to a server
    +     with ForceCommand=internal-sftp with a shell session (i.e. not a
    +     subsystem session). Avoids stuck client when attempting to ssh to such a
    +     service. ok dtucker@
    +   - dtucker@cvs.openbsd.org 2009/11/20 00:15:41
    +     [session.c]
    +     Warn but do not fail if stat()ing the subsystem binary fails.  This helps
    +     with chrootdirectory+forcecommand=sftp-server and restricted shells.
    +     bz #1599, ok djm.
    +   - djm@cvs.openbsd.org 2009/11/20 00:54:01
    +     [sftp.c]
    +     bz#1588 change "Connecting to host..." message to "Connected to host."
    +     and delay it until after the sftp protocol connection has been established.
    +     Avoids confusing sequence of messages when the underlying ssh connection
    +     experiences problems. ok dtucker@
    +   - dtucker@cvs.openbsd.org 2009/11/20 00:59:36
    +     [sshconnect2.c]
    +     Use the HostKeyAlias when prompting for passwords.  bz#1039, ok djm@
    +   - djm@cvs.openbsd.org 2009/11/20 03:24:07
    +     [misc.c]
    +     correct off-by-one in percent_expand(): we would fatal() when trying
    +     to expand EXPAND_MAX_KEYS, allowing only EXPAND_MAX_KEYS-1 to actually
    +     work.  Note that nothing in OpenSSH actually uses close to this limit at
    +     present.  bz#1607 from Jan.Pechanec AT Sun.COM
    +   - halex@cvs.openbsd.org 2009/11/22 13:18:00
    +     [sftp.c]
    +     make passing of zero-length arguments to ssh safe by
    +     passing "-" "" rather than "-"
    +     ok dtucker@, guenther@, djm@
    +   - dtucker@cvs.openbsd.org 2009/12/06 23:41:15
    +     [sshconnect2.c]
    +     zap unused variable and strlen; from Steve McClellan, ok djm
    +   - djm@cvs.openbsd.org 2009/12/06 23:53:45
    +     [roaming_common.c]
    +     use socklen_t for getsockopt optlen parameter; reported by
    +     Steve.McClellan AT radisys.com, ok dtucker@
    +   - dtucker@cvs.openbsd.org 2009/12/06 23:53:54
    +     [sftp.c]
    +     fix potential divide-by-zero in sftp's "df" output when talking to a server
    +     that reports zero files on the filesystem (Unix filesystems always have at
    +     least the root inode).  From Steve McClellan at radisys, ok djm@
    +   - markus@cvs.openbsd.org 2009/12/11 18:16:33
    +     [key.c]
    +     switch from 35 to the more common value of RSA_F4 == (2**16)+1 == 65537
    +     for the RSA public exponent; discussed with provos; ok djm@
    +   - guenther@cvs.openbsd.org 2009/12/20 07:28:36
    +     [ssh.c sftp.c scp.c]
    +     When passing user-controlled options with arguments to other programs,
    +     pass the option and option argument as separate argv entries and
    +     not smashed into one (e.g., as -l foo and not -lfoo).  Also, always
    +     pass a "--" argument to stop option parsing, so that a positional
    +     argument that starts with a '-' isn't treated as an option.  This
    +     fixes some error cases as well as the handling of hostnames and
    +     filenames that start with a '-'.
    +     Based on a diff by halex@
    +     ok halex@ djm@ deraadt@
    +   - djm@cvs.openbsd.org 2009/12/20 23:20:40
    +     [PROTOCOL]
    +     fix an incorrect magic number and typo in PROTOCOL; bz#1688
    +     report and fix from ueno AT unixuser.org
    +   - stevesk@cvs.openbsd.org 2009/12/25 19:40:21
    +     [readconf.c servconf.c misc.h ssh-keyscan.c misc.c]
    +     validate routing domain is in range 0-RT_TABLEID_MAX.
    +     'Looks right' deraadt@
    +   - stevesk@cvs.openbsd.org 2009/12/29 16:38:41
    +     [sshd_config.5 readconf.c ssh_config.5 scp.1 servconf.c sftp.1 ssh.1]
    +     Rename RDomain config option to RoutingDomain to be more clear and
    +     consistent with other options.
    +     NOTE: if you currently use RDomain in the ssh client or server config,
    +     or ssh/sshd -o, you must update to use RoutingDomain.
    +     ok markus@ djm@
    +   - jmc@cvs.openbsd.org 2009/12/29 18:03:32
    +     [sshd_config.5 ssh_config.5]
    +     sort previous;
    +   - dtucker@cvs.openbsd.org 2010/01/04 01:45:30
    +     [sshconnect2.c]
    +     Don't escape backslashes in the SSH2 banner.  bz#1533, patch from
    +     Michal Gorny via Gentoo.
    +   - djm@cvs.openbsd.org 2010/01/04 02:03:57
    +     [sftp.c]
    +     Implement tab-completion of commands, local and remote filenames for sftp.
    +     Hacked on and off for some time by myself, mouring, Carlos Silva (via 2009
    +     Google Summer of Code) and polished to a fine sheen by myself again.
    +     It should deal more-or-less correctly with the ikky corner-cases presented
    +     by quoted filenames, but the UI could still be slightly improved.
    +     In particular, it is quite slow for remote completion on large directories.
    +     bz#200; ok markus@
    +   - djm@cvs.openbsd.org 2010/01/04 02:25:15
    +     [sftp-server.c]
    +     bz#1566 don't unnecessarily dup() in and out fds for sftp-server;
    +     ok markus@
    +   - dtucker@cvs.openbsd.org 2010/01/08 21:50:49
    +     [sftp.c]
    +     Fix two warnings: possibly used unitialized and use a nul byte instead of
    +     NULL pointer.  ok djm@
    + - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new
    +   files for roaming and add to Makefile.
    + - (dtucker) [Makefile.in] .c files do not belong in the OBJ lines.
    + - (dtucker) [sftp.c] ifdef out the sftp completion bits for platforms that
    +   don't have libedit.
    + - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Make
    +   RoutingDomain an unsupported option on platforms that don't have it.
    + - (dtucker) [sftp.c] Expand ifdef for libedit to cover complete_is_remote
    +   too.
    + - (dtucker) [misc.c] Move the routingdomain ifdef to allow the socket to
    +   be created.
    + - (dtucker] [misc.c] Shrink the area covered by USE_ROUTINGDOMAIN more
    +   to eliminate an unused variable warning.
    + - (dtucker) [roaming_serv.c] Include includes.h for u_intXX_t types.
    +
    +20091226
    + - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1
    +   Gzip all man pages. Patch from Corinna Vinschen.
    +
    +20091221
    + - (dtucker) [auth-krb5.c platform.{c,h} openbsd-compat/port-aix.{c,h}]
    +   Bug #1583: Use system's kerberos principal name on AIX if it's available.
    +   Based on a patch from and tested by Miguel Sanders 
    +
    +20091208
    + - (dtucker) Bug #1470: Disable OOM-killing of the listening sshd on Linux,
    +   based on a patch from Vaclav Ovsik and Colin Watson.  ok djm.
    +
    +20091207
    + - (dtucker) Bug #1160: use pkg-config for opensc config if it's available.
    +   Tested by Martin Paljak.
    + - (dtucker) Bug #1677: add conditionals around the source for ssh-askpass.
    +
    +20091121
    + - (tim) [opensshd.init.in] If PidFile is set in sshd_config, use it.
    +   Bug 1628. OK dtucker@
    +
    +20091120
    + - (djm) [ssh-rand-helper.c] Print error and usage() when passed command-
    +   line arguments as none are supported. Exit when passed unrecognised
    +   commandline flags. bz#1568 from gson AT araneus.fi
    +
    +20091118
    + - (djm) [channels.c misc.c misc.h sshd.c] add missing setsockopt() to
    +   set IPV6_V6ONLY for local forwarding with GatwayPorts=yes. Unify
    +   setting IPV6_V6ONLY behind a new function misc.c:sock_set_v6only()
    +   bz#1648, report and fix from jan.kratochvil AT redhat.com
    + - (djm) [contrib/gnome-ssh-askpass2.c] Make askpass dialog desktop-modal.
    +   bz#1645, patch from jchadima AT redhat.com
    +
    +20091107
    + - (dtucker) [authfile.c] Fall back to 3DES for the encryption of private
    +    keys when built with OpenSSL versions that don't do AES.
    +
    +20091105
    + - (dtucker) [authfile.c] Add OpenSSL compat header so this still builds with
    +   older versions of OpenSSL.
    +
    +20091024
    + - (dtucker) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2009/10/11 23:03:15
    +     [hostfile.c]
    +     mention the host name that we are looking for in check_host_in_hostfile()
    +   - sobrado@cvs.openbsd.org 2009/10/17 12:10:39
    +     [sftp-server.c]
    +     sort flags.
    +   - sobrado@cvs.openbsd.org 2009/10/22 12:35:53
    +     [ssh.1 ssh-agent.1 ssh-add.1]
    +     use the UNIX-related macros (.At and .Ux) where appropriate.
    +     ok jmc@
    +   - sobrado@cvs.openbsd.org 2009/10/22 15:02:12
    +     [ssh-agent.1 ssh-add.1 ssh.1]
    +     write UNIX-domain in a more consistent way; while here, replace a
    +     few remaining ".Tn UNIX" macros with ".Ux" ones.
    +     pointed out by ratchov@, thanks!
    +     ok jmc@
    +   - djm@cvs.openbsd.org 2009/10/22 22:26:13
    +     [authfile.c]
    +     switch from 3DES to AES-128 for encryption of passphrase-protected
    +     SSH protocol 2 private keys; ok several
    +   - djm@cvs.openbsd.org 2009/10/23 01:57:11
    +     [sshconnect2.c]
    +     disallow a hostile server from checking jpake auth by sending an
    +     out-of-sequence success message. (doesn't affect code enabled by default)
    +   - dtucker@cvs.openbsd.org 2009/10/24 00:48:34
    +     [ssh-keygen.1]
    +     ssh-keygen now uses AES-128 for private keys
    + - (dtucker) [mdoc2man.awk] Teach it to understand the .Ux macro.
    + - (dtucker) [session.c openbsd-compat/port-linux.{c,h}] Bug #1637: if selinux
    +   is enabled set the security context to "sftpd_t" before running the
    +   internal sftp server   Based on a patch from jchadima at redhat.
    +
    +20091011
    + - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for
    +   dirent d_type and DTTOIF as we've switched OpenBSD to the more portable
    +   lstat.
    + - (dtucker) OpenBSD CVS Sync
    +   - markus@cvs.openbsd.org 2009/10/08 14:03:41
    +     [sshd_config readconf.c ssh_config.5 servconf.c sshd_config.5]
    +     disable protocol 1 by default (after a transition period of about 10 years)
    +     ok deraadt
    +   - jmc@cvs.openbsd.org 2009/10/08 20:42:12
    +     [sshd_config.5 ssh_config.5 sshd.8 ssh.1]
    +     some tweaks now that protocol 1 is not offered by default; ok markus
    +   - dtucker@cvs.openbsd.org 2009/10/11 10:41:26
    +     [sftp-client.c]
    +     d_type isn't portable so use lstat to get dirent modes.  Suggested by and
    +     "looks sane" deraadt@
    +   - markus@cvs.openbsd.org 2009/10/08 18:04:27
    +     [regress/test-exec.sh]
    +     re-enable protocol v1 for the tests.
    +
    +20091007
    + - (dtucker) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2009/08/12 00:13:00
    +     [sftp.c sftp.1]
    +     support most of scp(1)'s commandline arguments in sftp(1), as a first
    +     step towards making sftp(1) a drop-in replacement for scp(1).
    +     One conflicting option (-P) has not been changed, pending further
    +     discussion.
    +     Patch from carlosvsilvapt@gmail.com as part of his work in the
    +     Google Summer of Code
    +  - jmc@cvs.openbsd.org 2009/08/12 06:31:42
    +     [sftp.1]
    +     sort options;
    +   - djm@cvs.openbsd.org 2009/08/13 01:11:19
    +     [sftp.1 sftp.c]
    +     Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path",
    +     add "-P port" to match scp(1). Fortunately, the -P option is only really
    +     used by our regression scripts.
    +     part of larger patch from carlosvsilvapt@gmail.com for his Google Summer
    +     of Code work; ok deraadt markus
    +   - jmc@cvs.openbsd.org 2009/08/13 13:39:54
    +     [sftp.1 sftp.c]
    +     sync synopsis and usage();
    +   - djm@cvs.openbsd.org 2009/08/14 18:17:49
    +     [sftp-client.c]
    +     make the "get_handle: ..." error messages vaguely useful by allowing
    +     callers to specify their own error message strings.
    +   - fgsch@cvs.openbsd.org 2009/08/15 18:56:34
    +     [auth.h]
    +     remove unused define. markus@ ok.
    +     (Id sync only, Portable still uses this.)
    +   - dtucker@cvs.openbsd.org 2009/08/16 23:29:26
    +     [sshd_config.5]
    +     Add PubkeyAuthentication to the list allowed in a Match block (bz #1577)
    +   - djm@cvs.openbsd.org 2009/08/18 18:36:21
    +     [sftp-client.h sftp.1 sftp-client.c sftp.c]
    +     recursive transfer support for get/put and on the commandline
    +     work mostly by carlosvsilvapt@gmail.com for the Google Summer of Code
    +     with some tweaks by me; "go for it" deraadt@
    +  - djm@cvs.openbsd.org 2009/08/18 21:15:59
    +     [sftp.1]
    +     fix "get" command usage, spotted by jmc@
    +   - jmc@cvs.openbsd.org 2009/08/19 04:56:03
    +     [sftp.1]
    +     ether -> either;
    +   - dtucker@cvs.openbsd.org 2009/08/20 23:54:28
    +     [mux.c]
    +     subsystem_flag is defined in ssh.c so it's extern; ok djm
    +   - djm@cvs.openbsd.org 2009/08/27 17:28:52
    +     [sftp-server.c]
    +     allow setting an explicit umask on the commandline to override whatever
    +     default the user has. bz#1229; ok dtucker@ deraadt@ markus@
    +   - djm@cvs.openbsd.org 2009/08/27 17:33:49
    +     [ssh-keygen.c]
    +     force use of correct hash function for random-art signature display
    +     as it was inheriting the wrong one when bubblebabble signatures were
    +     activated; bz#1611 report and patch from fwojcik+openssh AT besh.com;
    +     ok markus@
    +   - djm@cvs.openbsd.org 2009/08/27 17:43:00
    +     [sftp-server.8]
    +     allow setting an explicit umask on the commandline to override whatever
    +     default the user has. bz#1229; ok dtucker@ deraadt@ markus@
    +   - djm@cvs.openbsd.org 2009/08/27 17:44:52
    +     [authfd.c ssh-add.c authfd.h]
    +     Do not fall back to adding keys without contraints (ssh-add -c / -t ...)
    +     when the agent refuses the constrained add request. This was a useful
    +     migration measure back in 2002 when constraints were new, but just
    +     adds risk now.
    +     bz #1612, report and patch from dkg AT fifthhorseman.net; ok markus@
    +   - djm@cvs.openbsd.org 2009/08/31 20:56:02
    +     [sftp-server.c]
    +     check correct variable for error message, spotted by martynas@
    +   - djm@cvs.openbsd.org 2009/08/31 21:01:29
    +     [sftp-server.8]
    +     document -e and -h; prodded by jmc@
    +   - djm@cvs.openbsd.org 2009/09/01 14:43:17
    +     [ssh-agent.c]
    +     fix a race condition in ssh-agent that could result in a wedged or
    +     spinning agent: don't read off the end of the allocated fd_sets, and
    +     don't issue blocking read/write on agent sockets - just fall back to
    +     select() on retriable read/write errors. bz#1633 reported and tested
    +     by "noodle10000 AT googlemail.com"; ok dtucker@ markus@
    +   - grunk@cvs.openbsd.org 2009/10/01 11:37:33
    +     [dh.c]
    +     fix a cast
    +     ok djm@ markus@
    +   - djm@cvs.openbsd.org 2009/10/06 04:46:40
    +     [session.c]
    +     bz#1596: fflush(NULL) before exec() to ensure that everying (motd
    +     in particular) has made it out before the streams go away.
    +   - djm@cvs.openbsd.org 2008/12/07 22:17:48
    +     [regress/addrmatch.sh]
    +     match string "passwordauthentication" only at start of line, not anywhere
    +     in sshd -T output
    +   - dtucker@cvs.openbsd.org 2009/05/05 07:51:36
    +     [regress/multiplex.sh]
    +     Always specify ssh_config for multiplex tests: prevents breakage caused
    +     by options in ~/.ssh/config.  From Dan Peterson.
    +   - djm@cvs.openbsd.org 2009/08/13 00:57:17
    +     [regress/Makefile]
    +     regression test for port number parsing. written as part of the a2port
    +     change that went into 5.2 but I forgot to commit it at the time...
    +   - djm@cvs.openbsd.org 2009/08/13 01:11:55
    +     [regress/sftp-batch.sh regress/sftp-badcmds.sh regress/sftp.sh
    +     regress/sftp-cmds.sh regres/sftp-glob.sh]
    +     date: 2009/08/13 01:11:19;  author: djm;  state: Exp;  lines: +10 -7
    +     Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path",
    +     add "-P port" to match scp(1). Fortunately, the -P option is only really
    +     used by our regression scripts.
    +     part of larger patch from carlosvsilvapt@gmail.com for his Google Summer
    +     of Code work; ok deraadt markus
    +   - djm@cvs.openbsd.org 2009/08/20 18:43:07
    +     [regress/ssh-com-sftp.sh]
    +     fix one sftp -D ... => sftp -P ... conversion that I missed; from Carlos
    +     Silva for Google Summer of Code
    +   - dtucker@cvs.openbsd.org 2009/10/06 23:51:49
    +     [regress/ssh2putty.sh]
    +     Add OpenBSD tag to make syncs easier
    + - (dtucker) [regress/portnum.sh] Import new test.
    + - (dtucker) [configure.ac sftp-client.c] DTOTIF is in fs/ffs/dir.h on at
    +   least dragonflybsd.
    + - (dtucker) d_type is not mandated by POSIX, so add fallback code using
    +    stat(), needed on at least cygwin.
    +
    +20091002
    + - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps.
    +   spotted by des AT des.no
    +
    +20090926
    + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
    +         [contrib/suse/openssh.spec] Update for release
    + - (djm) [README] update relnotes URL
    + - (djm) [packet.c] Restore EWOULDBLOCK handling that got lost somewhere
    + - (djm) Release 5.3p1
    +
    +20090911
    + - (dtucker) [configure.ac] Change the -lresolv check so it works on Mac OS X
    +   10.6 (which doesn't have BIND8_COMPAT and thus uses res_9_query).  Patch
    +   from jbasney at ncsa uiuc edu.
    +
    +20090908
    + - (djm) [serverloop.c] Fix test for server-assigned remote forwarding port
    +   (-R 0:...); bz#1578, spotted and fix by gavin AT emf.net; ok dtucker@
    +
    +20090901
    + - (dtucker) [configure.ac] Bug #1639: use AC_PATH_PROG to search the path for
    +   krb5-config if it's not in the location specified by --with-kerberos5.
    +   Patch from jchadima at redhat.
    +
    +20090829
    + - (dtucker) [README.platform] Add text about development packages, based on
    +   text from Chris Pepper in bug #1631.
    +
    +20090828
    + - dtucker [auth-sia.c] Roll back the change for bug #1241 as it apparently
    +   causes problems in some Tru64 configurations.
    + - (djm) [sshd_config.5] downgrade mention of login.conf to be an example
    +   and mention PAM as another provider for ChallengeResponseAuthentication;
    +   bz#1408; ok dtucker@
    + - (djm) [sftp-server.c] bz#1535: accept ENOSYS as a fallback error when
    +   attempting atomic rename(); ok dtucker@
    + - (djm) [Makefile.in] bz#1505: Solaris make(1) doesn't accept make variables
    +   in argv, so pass them in the environment; ok dtucker@
    + - (dtucker) [channels.c configure.ac] Bug #1528: skip the tcgetattr call on
    +    the pty master on Solaris, since it never succeeds and can hang if large
    +    amounts of data is sent to the slave (eg a copy-paste).  Based on a patch
    +    originally from Doke Scott, ok djm@
    + - (dtucker) [clientloop.c configure.ac defines.h] Make the client's IO buffer
    +   size a compile-time option and set it to 64k on Cygwin, since Corinna
    +   reports that it makes a significant difference to performance.  ok djm@
    + - (dtucker) [configure.ac] Fix the syntax of the Solaris tcgetattr entry.
    +
    +20090820
    + - (dtucker) [includes.h] Bug #1634: do not include system glob.h if we're not
    +   using it since the type conflicts can cause problems on FreeBSD.  Patch
    +   from Jonathan Chen.
    + - (dtucker) [session.c openbsd-compat/port-aix.h] Bugs #1249 and #1567: move
    +   the setpcred call on AIX to immediately before the permanently_set_uid().
    +   Ensures that we still have privileges when we call chroot and
    +   pam_open_sesson.  Based on a patch from David Leonard.
    +
    +20090817
    + - (dtucker) [configure.ac] Check for headers before libraries for openssl an
    +   zlib, which should make the errors slightly more meaningful on platforms
    +   where there's separate "-devel" packages for those.
    + - (dtucker) [sshlogin.c openbsd-compat/port-aix.{c,h}] Bug #1595: make
    +   PrintLastLog work on AIX.  Based in part on a patch from Miguel Sanders.
    +
    +20090729
    + - (tim) [contrib/cygwin/ssh-user-config] Change script to call correct error
    +   function. Patch from Corinna Vinschen.
    +
    +20090713
    + - (dtucker) [openbsd-compat/getrrsetbyname.c] Reduce answer buffer size so it
    +   fits into 16 bits to work around a bug in glibc's resolver where it masks
    +   off the buffer size at 16 bits.  Patch from Hauke Lampe, ok djm jakob.
    +
    +20090712
    + - (dtucker) [configure.ac] Include sys/param.h for the sys/mount.h test,
    +   prevents configure complaining on older BSDs.
    + - (dtucker [contrib/cygwin/ssh-{host,user}-config] Add license text. Patch
    +   from Corinna Vinschen.
    + - (dtucker) [auth-pam.c] Bug #1534: move the deletion of PAM credentials on
    +   logout to after the session close.  Patch from Anicka Bernathova,
    +   originally from Andreas Schwab via Novelll ok djm.
    +
    +20090707
    + - (dtucker) [contrib/cygwin/ssh-host-config] better support for automated
    +   scripts and fix usage of eval.  Patch from Corinna Vinschen.
    +
    +20090705
    + - (dtucker) OpenBSD CVS Sync
    +   - andreas@cvs.openbsd.org 2009/06/27 09:29:06
    +     [packet.h packet.c]
    +     packet_bacup_state() and packet_restore_state() will be used to
    +     temporarily save the current state ren resuming a suspended connection.
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/06/27 09:32:43
    +     [roaming_common.c roaming.h]
    +     It may be necessary to retransmit some data when resuming, so add it
    +     to a buffer when roaming is enabled.
    +     Most of this code was written by Martin Forssen, maf at appgate dot com.
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/06/27 09:35:06
    +     [readconf.h readconf.c]
    +     Add client option UseRoaming. It doesn't do anything yet but will
    +     control whether the client tries to use roaming if enabled on the
    +     server. From Martin Forssen.
    +     ok markus@
    +   - markus@cvs.openbsd.org 2009/06/30 14:54:40
    +     [version.h]
    +     crank version; ok deraadt
    +   - dtucker@cvs.openbsd.org 2009/07/02 02:11:47
    +     [ssh.c]
    +     allow for long home dir paths (bz #1615).  ok deraadt
    +     (based in part on a patch from jchadima at redhat)
    +   - stevesk@cvs.openbsd.org 2009/07/05 19:28:33
    +     [clientloop.c]
    +     only send SSH2_MSG_DISCONNECT if we're in compat20; from dtucker@
    +     ok deraadt@ markus@
    +
    +20090622
    + - (dtucker) OpenBSD CVS Sync
    +   - dtucker@cvs.openbsd.org 2009/06/22 05:39:28
    +     [monitor_wrap.c monitor_mm.c ssh-keygen.c auth2.c gss-genr.c sftp-client.c]
    +     alphabetize includes; reduces diff vs portable and style(9).
    +     ok stevesk djm
    +     (Id sync only; these were already in order in -portable)
    +
    +20090621
    + - (dtucker) OpenBSD CVS Sync
    +   - markus@cvs.openbsd.org 2009/03/17 21:37:00
    +     [ssh.c]
    +     pass correct argv[0] to openlog(); ok djm@
    +  - jmc@cvs.openbsd.org 2009/03/19 15:15:09
    +     [ssh.1]
    +     for "Ciphers", just point the reader to the keyword in ssh_config(5), just
    +     as we do for "MACs": this stops us getting out of sync when the lists
    +     change;
    +     fixes documentation/6102, submitted by Peter J. Philipp
    +     alternative fix proposed by djm
    +     ok markus
    +   - tobias@cvs.openbsd.org 2009/03/23 08:31:19
    +     [ssh-agent.c]
    +     Fixed a possible out-of-bounds memory access if the environment variable
    +     SHELL is shorter than 3 characters.
    +     with input by and ok dtucker
    +   - tobias@cvs.openbsd.org 2009/03/23 19:38:04
    +     [ssh-agent.c]
    +     My previous commit didn't fix the problem at all, so stick at my first
    +     version of the fix presented to dtucker.
    +     Issue notified by Matthias Barkhoff (matthias dot barkhoff at gmx dot de).
    +     ok dtucker
    +   - sobrado@cvs.openbsd.org 2009/03/26 08:38:39
    +     [sftp-server.8 sshd.8 ssh-agent.1]
    +     fix a few typographical errors found by spell(1).
    +     ok dtucker@, jmc@
    +   - stevesk@cvs.openbsd.org 2009/04/13 19:07:44
    +     [sshd_config.5]
    +     fix possessive; ok djm@
    +   - stevesk@cvs.openbsd.org 2009/04/14 16:33:42
    +     [sftp-server.c]
    +     remove unused option character from getopt() optstring; ok markus@
    +   - jj@cvs.openbsd.org 2009/04/14 21:10:54
    +     [servconf.c]
    +     Fixed a few the-the misspellings in comments. Skipped a bunch in
    +     binutils,gcc and so on. ok jmc@
    +   - stevesk@cvs.openbsd.org 2009/04/17 19:23:06
    +     [session.c]
    +     use INTERNAL_SFTP_NAME for setproctitle() of in-process sftp-server;
    +     ok djm@ markus@
    +   - stevesk@cvs.openbsd.org 2009/04/17 19:40:17
    +     [sshd_config.5]
    +     clarify that even internal-sftp needs /dev/log for logging to work; ok
    +     markus@
    +   - jmc@cvs.openbsd.org 2009/04/18 18:39:10
    +     [sshd_config.5]
    +     tweak previous; ok stevesk
    +   - stevesk@cvs.openbsd.org 2009/04/21 15:13:17
    +     [sshd_config.5]
    +     clarify we cd to user's home after chroot; ok markus@ on
    +     earlier version; tweaks and ok jmc@
    +   - andreas@cvs.openbsd.org 2009/05/25 06:48:01
    +     [channels.c packet.c clientloop.c packet.h serverloop.c monitor_wrap.c
    +     monitor.c]
    +     Put the globals in packet.c into a struct and don't access it directly
    +     from other files. No functional changes.
    +     ok markus@ djm@
    +   - andreas@cvs.openbsd.org 2009/05/27 06:31:25
    +     [canohost.h canohost.c]
    +     Add clear_cached_addr(), needed for upcoming changes allowing the peer
    +     address to change.
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/05/27 06:33:39
    +     [clientloop.c]
    +     Send SSH2_MSG_DISCONNECT when the client disconnects. From a larger
    +     change from Martin Forssen, maf at appgate dot com.
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/05/27 06:34:36
    +     [kex.c kex.h]
    +     Move the KEX_COOKIE_LEN define to kex.h
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/05/27 06:36:07
    +     [packet.h packet.c]
    +     Add packet_put_int64() and packet_get_int64(), part of a larger change
    +     from Martin Forssen.
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/05/27 06:38:16
    +     [sshconnect.h sshconnect.c]
    +     Un-static ssh_exchange_identification(), part of a larger change from
    +     Martin Forssen and needed for upcoming changes.
    +     ok markus@
    +   - andreas@cvs.openbsd.org 2009/05/28 16:50:16
    +     [sshd.c packet.c serverloop.c monitor_wrap.c clientloop.c sshconnect.c
    +     monitor.c Added roaming.h roaming_common.c roaming_dummy.c]
    +     Keep track of number of bytes read and written. Needed for upcoming
    +     changes. Most code from Martin Forssen, maf at appgate dot com.
    +     ok markus@
    +     Also, applied appropriate changes to Makefile.in
    +   - andreas@cvs.openbsd.org 2009/06/12 20:43:22
    +     [monitor.c packet.c]
    +     Fix warnings found by chl@ and djm@ and change roaming_atomicio's
    +     return type to match atomicio's
    +     Diff from djm@, ok markus@
    +   - andreas@cvs.openbsd.org 2009/06/12 20:58:32
    +     [packet.c]
    +     Move some more statics into session_state
    +     ok markus@ djm@
    +   - dtucker@cvs.openbsd.org 2009/06/21 07:37:15
    +     [kexdhs.c kexgexs.c]
    +     abort if key_sign fails, preventing possible null deref.  Based on report
    +     from Paolo Ganci, ok markus@ djm@
    +   - dtucker@cvs.openbsd.org 2009/06/21 09:04:03
    +     [roaming.h roaming_common.c roaming_dummy.c]
    +     Add  tags for the benefit of the sync scripts
    +     Also: pull in the changes for 1.1->1.2 missed in the previous sync.
    + - (dtucker) [auth2-jpake.c auth2.c canohost.h session.c] Whitespace and
    +   header-order changes to reduce diff vs OpenBSD.
    + - (dtucker) [servconf.c sshd.c] More whitespace sync.
    + - (dtucker) [roaming_common.c roaming_dummy.c] Wrap #include  in
    +   ifdef.
    +
    +20090616
    + - (dtucker) [configure.ac defines.h] Bug #1607: handle the case where fsid_t
    +   is a struct with a __val member.  Fixes build on, eg, Redhat 6.2.
    +
    +20090504
    + - (dtucker) [sshlogin.c] Move the NO_SSH_LASTLOG #ifndef line to include
    +   variable declarations.  Should prevent unused warnings anywhere it's set
    +   (only Crays as far as I can tell) and be a no-op everywhere else.
    +
    +20090318
    + - (tim) [configure.ac] Remove setting IP_TOS_IS_BROKEN for Cygwin. The problem
    +   that setsockopt(IP_TOS) doesn't work on Cygwin has been fixed since 2005.
    +   Based on patch from vinschen at redhat com.
    +
    +20090308
    + - (dtucker) [auth-passwd.c auth1.c auth2-kbdint.c auth2-none.c auth2-passwd.c
    +   auth2-pubkey.c session.c openbsd-compat/bsd-cygwin_util.{c,h}
    +   openbsd-compat/daemon.c] Remove support for Windows 95/98/ME and very old
    +   version of Cygwin.  Patch from vinschen at redhat com.
    +
    +20090307
    + - (dtucker) [contrib/aix/buildbff.sh] Only try to rename ssh_prng_cmds if it
    +   exists (it's not created if OpenSSL's PRNG is self-seeded, eg if the OS
    +   has a /dev/random).
    + - (dtucker) [schnorr.c openbsd-compat/openssl-compat.{c,h}] Add
    +   EVP_DigestUpdate to the OLD_EVP compatibility functions and tell schnorr.c
    +   to use them.  Allows building with older OpenSSL versions.
    + - (dtucker) [configure.ac defines.h] Check for in_port_t and typedef if needed.
    + - (dtucker) [configure.ac] Missing comma in type list.
    + - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}]
    +   EVP_DigestUpdate does not exactly match the other OLD_EVP functions (eg
    +   in openssl 0.9.6) so add an explicit test for it.
    +
    +20090306
    + - (djm) OpenBSD CVS Sync
    +   - djm@cvs.openbsd.org 2009/03/05 07:18:19
    +     [auth2-jpake.c jpake.c jpake.h monitor_wrap.c monitor_wrap.h schnorr.c]
    +     [sshconnect2.c]
    +     refactor the (disabled) Schnorr proof code to make it a little more
    +     generally useful
    +   - djm@cvs.openbsd.org 2009/03/05 11:30:50
    +     [uuencode.c]
    +     document what these functions do so I don't ever have to recuse into
    +     b64_pton/ntop to remember their return values
    +
     20090223
      - (djm) OpenBSD CVS Sync
        - djm@cvs.openbsd.org 2009/02/22 23:50:57
    diff --git a/crypto/openssh/INSTALL b/crypto/openssh/INSTALL
    index 001ebb66686..09dfd666d99 100644
    --- a/crypto/openssh/INSTALL
    +++ b/crypto/openssh/INSTALL
    @@ -208,10 +208,6 @@ are installed.
     --with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to
     real (AF_INET) IPv4 addresses. Works around some quirks on Linux.
     
    ---with-opensc=DIR
    ---with-sectok=DIR allows for OpenSC or sectok smartcard libraries to
    -be used with OpenSSH.  See 'README.smartcard' for more details.
    -
     If you need to pass special options to the compiler or linker, you
     can specify these as environment variables before running ./configure.
     For example:
    @@ -266,4 +262,4 @@ Please refer to the "reporting bugs" section of the webpage at
     http://www.openssh.com/
     
     
    -$Id: INSTALL,v 1.84 2007/08/17 12:52:05 dtucker Exp $
    +$Id: INSTALL,v 1.85 2010/02/11 22:34:22 djm Exp $
    diff --git a/crypto/openssh/PROTOCOL b/crypto/openssh/PROTOCOL
    index 5aada630ddd..5fc31eade32 100644
    --- a/crypto/openssh/PROTOCOL
    +++ b/crypto/openssh/PROTOCOL
    @@ -6,8 +6,8 @@ filexfer protocol described in:
     
     http://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt
     
    -Features from newer versions of the draft are not supported, unless
    -explicitly implemented as extensions described below.
    +Newer versions of the draft will not be supported, though some features
    +are individually implemented as extensions described below.
     
     The protocol used by OpenSSH's ssh-agent is described in the file
     PROTOCOL.agent
    @@ -31,7 +31,14 @@ The method is documented in:
     
     http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
     
    -3. connection: Channel write close extension "eow@openssh.com"
    +3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com" and
    +   "ssh-dsa-cert-v00@openssh.com"
    +
    +OpenSSH introduces two new public key algorithms to support certificate
    +authentication for users and hostkeys. These methods are documented in
    +the file PROTOCOL.certkeys
    +
    +4. connection: Channel write close extension "eow@openssh.com"
     
     The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
     message to allow an endpoint to signal its peer that it will send no
    @@ -70,7 +77,7 @@ message is only sent to OpenSSH peers (identified by banner).
     Other SSH implementations may be whitelisted to receive this message
     upon request.
     
    -4. connection: disallow additional sessions extension
    +5. connection: disallow additional sessions extension
        "no-more-sessions@openssh.com"
     
     Most SSH connections will only ever request a single session, but a
    @@ -98,7 +105,7 @@ of this message, the no-more-sessions request is only sent to OpenSSH
     servers (identified by banner). Other SSH implementations may be
     whitelisted to receive this message upon request.
     
    -5. connection: Tunnel forward extension "tun@openssh.com"
    +6. connection: Tunnel forward extension "tun@openssh.com"
     
     OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
     channel type. This channel type supports forwarding of network packets
    @@ -121,10 +128,10 @@ layer 2 frames or layer 3 packets. It may take one of the following values:
     	SSH_TUNMODE_ETHERNET     2		/* layer 2 frames */
     
     The "tunnel unit number" specifies the remote interface number, or may
    -be zero to allow the server to automatically chose an interface. A server
    -that is not willing to open a client-specified unit should refuse the
    -request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful open,
    -the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
    +be 0x7fffffff to allow the server to automatically chose an interface. A
    +server that is not willing to open a client-specified unit should refuse
    +the request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful
    +open, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
     
     Once established the client and server may exchange packet or frames
     over the tunnel channel by encapsulating them in SSH protocol strings
    @@ -151,7 +158,7 @@ It may be one of:
     The "packet data" field consists of the IPv4/IPv6 datagram itself
     without any link layer header.
     
    -The contents of the "data" field for layer 3 packets is:
    +The contents of the "data" field for layer 2 packets is:
     
     	uint32			packet length
     	byte[packet length]	frame
    @@ -159,7 +166,7 @@ The contents of the "data" field for layer 3 packets is:
     The "frame" field contains an IEEE 802.3 Ethernet frame, including
     header.
     
    -6. sftp: Reversal of arguments to SSH_FXP_SYMLINK
    +7. sftp: Reversal of arguments to SSH_FXP_SYMLINK
     
     When OpenSSH's sftp-server was implemented, the order of the arguments
     to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
    @@ -172,7 +179,7 @@ SSH_FXP_SYMLINK as follows:
     	string		targetpath
     	string		linkpath
     
    -7. sftp: Server extension announcement in SSH_FXP_VERSION
    +8. sftp: Server extension announcement in SSH_FXP_VERSION
     
     OpenSSH's sftp-server lists the extensions it supports using the
     standard extension announcement mechanism in the SSH_FXP_VERSION server
    @@ -193,7 +200,7 @@ ever changed in an incompatible way. The server MAY advertise the same
     extension with multiple versions (though this is unlikely). Clients MUST
     check the version number before attempting to use the extension.
     
    -8. sftp: Extension request "posix-rename@openssh.com"
    +9. sftp: Extension request "posix-rename@openssh.com"
     
     This operation provides a rename operation with POSIX semantics, which
     are different to those provided by the standard SSH_FXP_RENAME in
    @@ -210,7 +217,7 @@ rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
     This extension is advertised in the SSH_FXP_VERSION hello with version
     "1".
     
    -9. sftp: Extension requests "statvfs@openssh.com" and
    +10. sftp: Extension requests "statvfs@openssh.com" and
              "fstatvfs@openssh.com"
     
     These requests correspond to the statvfs and fstatvfs POSIX system
    @@ -251,4 +258,4 @@ The values of the f_flag bitmask are as follows:
     Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
     advertised in the SSH_FXP_VERSION hello with version "2".
     
    -$OpenBSD: PROTOCOL,v 1.12 2009/02/14 06:35:49 djm Exp $
    +$OpenBSD: PROTOCOL,v 1.15 2010/02/26 20:29:54 djm Exp $
    diff --git a/crypto/openssh/PROTOCOL.agent b/crypto/openssh/PROTOCOL.agent
    index 49adbdd5c7a..b34fcd318e1 100644
    --- a/crypto/openssh/PROTOCOL.agent
    +++ b/crypto/openssh/PROTOCOL.agent
    @@ -173,6 +173,15 @@ be added using the following request
     	string			key_comment
     	constraint[]		key_constraints
     
    +DSA certificates may be added with:
    +	byte			SSH2_AGENTC_ADD_IDENTITY or
    +				SSH2_AGENTC_ADD_ID_CONSTRAINED
    +	string			"ssh-dss-cert-v00@openssh.com"
    +	string			certificate
    +	mpint			dsa_private_key
    +	string			key_comment
    +	constraint[]		key_constraints
    +
     RSA keys may be added with this request:
     
     	byte			SSH2_AGENTC_ADD_IDENTITY or
    @@ -187,6 +196,19 @@ RSA keys may be added with this request:
     	string			key_comment
     	constraint[]		key_constraints
     
    +RSA certificates may be added with this request:
    +
    +	byte			SSH2_AGENTC_ADD_IDENTITY or
    +				SSH2_AGENTC_ADD_ID_CONSTRAINED
    +	string			"ssh-rsa-cert-v00@openssh.com"
    +	string			certificate
    +	mpint			rsa_d
    +	mpint			rsa_iqmp
    +	mpint			rsa_p
    +	mpint			rsa_q
    +	string			key_comment
    +	constraint[]		key_constraints
    +
     Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse
     order to the protocol 1 add keys message. As with the corresponding
     protocol 1 "add key" request, the private key is overspecified to avoid
    @@ -513,4 +535,4 @@ Locking and unlocking affects both protocol 1 and protocol 2 keys.
     	SSH_AGENT_CONSTRAIN_LIFETIME			1
     	SSH_AGENT_CONSTRAIN_CONFIRM			2
     
    -$OpenBSD: PROTOCOL.agent,v 1.4 2008/07/01 23:12:47 stevesk Exp $
    +$OpenBSD: PROTOCOL.agent,v 1.5 2010/02/26 20:29:54 djm Exp $
    diff --git a/crypto/openssh/PROTOCOL.certkeys b/crypto/openssh/PROTOCOL.certkeys
    new file mode 100644
    index 00000000000..1ed9e206410
    --- /dev/null
    +++ b/crypto/openssh/PROTOCOL.certkeys
    @@ -0,0 +1,193 @@
    +This document describes a simple public-key certificate authentication
    +system for use by SSH.
    +
    +Background
    +----------
    +
    +The SSH protocol currently supports a simple public key authentication
    +mechanism. Unlike other public key implementations, SSH eschews the
    +use of X.509 certificates and uses raw keys. This approach has some
    +benefits relating to simplicity of configuration and minimisation
    +of attack surface, but it does not support the important use-cases
    +of centrally managed, passwordless authentication and centrally
    +certified host keys.
    +
    +These protocol extensions build on the simple public key authentication
    +system already in SSH to allow certificate-based authentication.
    +The certificates used are not traditional X.509 certificates, with
    +numerous options and complex encoding rules, but something rather
    +more minimal: a key, some identity information and usage constraints
    +that have been signed with some other trusted key.
    +
    +A sshd server may be configured to allow authentication via certified
    +keys, by extending the existing ~/.ssh/authorized_keys mechanism
    +to allow specification of certification authority keys in addition
    +to raw user keys. The ssh client will support automatic verification
    +of acceptance of certified host keys, by adding a similar ability
    +to specify CA keys in ~/.ssh/known_hosts.
    +
    +Certified keys are represented using two new key types:
    +ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com that
    +include certification information along with the public key that is used
    +to sign challenges. ssh-keygen performs the CA signing operation.
    +
    +Protocol extensions
    +-------------------
    +
    +The SSH wire protocol includes several extensibility mechanisms.
    +These modifications shall take advantage of namespaced public key
    +algorithm names to add support for certificate authentication without
    +breaking the protocol - implementations that do not support the
    +extensions will simply ignore them.
    +
    +Authentication using the new key formats described below proceeds
    +using the existing SSH "publickey" authentication method described
    +in RFC4252 section 7.
    +
    +New public key formats
    +----------------------
    +
    +The ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com key
    +types take a similar high-level format (note: data types and
    +encoding are as per RFC4251 section 5). The serialised wire encoding of
    +these certificates is also used for storing them on disk.
    +
    +#define SSH_CERT_TYPE_USER    1
    +#define SSH_CERT_TYPE_HOST    2
    +
    +RSA certificate
    +
    +    string    "ssh-rsa-cert-v00@openssh.com"
    +    mpint     e
    +    mpint     n
    +    uint32    type
    +    string    key id
    +    string    valid principals
    +    uint64    valid after
    +    uint64    valid before
    +    string    constraints
    +    string    nonce
    +    string    reserved
    +    string    signature key
    +    string    signature
    +
    +DSA certificate
    +
    +    string    "ssh-dss-cert-v00@openssh.com"
    +    mpint     p
    +    mpint     q
    +    mpint     g
    +    mpint     y
    +    uint32    type
    +    string    key id
    +    string    valid principals
    +    uint64    valid after
    +    uint64    valid before
    +    string    constraints
    +    string    nonce
    +    string    reserved
    +    string    signature key
    +    string    signature
    +
    +e and n are the RSA exponent and public modulus respectively.
    +
    +p, q, g, y are the DSA parameters as described in FIPS-186-2.
    +
    +type specifies whether this certificate is for identification of a user
    +or a host using a SSH_CERT_TYPE_... value.
    +
    +key id is a free-form text field that is filled in by the CA at the time
    +of signing; the intention is that the contents of this field are used to
    +identify the identity principal in log messages.
    +
    +"valid principals" is a string containing zero or more principals as
    +strings packed inside it. These principals list the names for which this
    +certificate is valid; hostnames for SSH_CERT_TYPE_HOST certificates and
    +usernames for SSH_CERT_TYPE_USER certificates. As a special case, a
    +zero-length "valid principals" field means the certificate is valid for
    +any principal of the specified type. XXX DNS wildcards?
    +
    +"valid after" and "valid before" specify a validity period for the
    +certificate. Each represents a time in seconds since 1970-01-01
    +00:00:00. A certificate is considered valid if:
    +	 valid after <= current time < valid before
    +
    +constraints is a set of zero or more key constraints encoded as below.
    +
    +The nonce field is a CA-provided random bitstring of arbitrary length
    +(but typically 16 or 32 bytes) included to make attacks that depend on
    +inducing collisions in the signature hash infeasible.
    +
    +The reserved field is current unused and is ignored in this version of
    +the protocol.
    +
    +signature key contains the CA key used to sign the certificate.
    +The valid key types for CA keys are ssh-rsa and ssh-dss. "Chained"
    +certificates, where the signature key type is a certificate type itself
    +are NOT supported. Note that it is possible for a RSA certificate key to
    +be signed by a DSS CA key and vice-versa.
    +
    +signature is computed over all preceding fields from the initial string
    +up to, and including the signature key. Signatures are computed and
    +encoded according to the rules defined for the CA's public key algorithm
    +(RFC4253 section 6.6 for ssh-rsa and ssh-dss).
    +
    +Constraints
    +-----------
    +
    +The constraints section of the certificate specifies zero or more
    +constraints on the certificates validity. The format of this field
    +is a sequence of zero or more tuples:
    +
    +    string       name
    +    string       data
    +
    +The name field identifies the constraint and the data field encodes
    +constraint-specific information (see below). All constraints are
    +"critical", if an implementation does not recognise a constraint
    +then the validating party should refuse to accept the certificate.
    +
    +The supported constraints and the contents and structure of their
    +data fields are:
    +
    +Name                    Format        Description
    +-----------------------------------------------------------------------------
    +force-command           string        Specifies a command that is executed
    +                                      (replacing any the user specified on the
    +                                      ssh command-line) whenever this key is
    +                                      used for authentication.
    +
    +permit-X11-forwarding   empty         Flag indicating that X11 forwarding
    +                                      should be permitted. X11 forwarding will
    +                                      be refused if this constraint is absent.
    +
    +permit-agent-forwarding empty         Flag indicating that agent forwarding
    +                                      should be allowed. Agent forwarding
    +                                      must not be permitted unless this
    +                                      constraint is present.
    +
    +permit-port-forwarding  empty         Flag indicating that port-forwarding
    +                                      should be allowed. If this constraint is
    +                                      not present then no port forwarding will
    +                                      be allowed.
    +
    +permit-pty              empty         Flag indicating that PTY allocation
    +                                      should be permitted. In the absence of
    +                                      this constraint PTY allocation will be
    +                                      disabled.
    +
    +permit-user-rc          empty         Flag indicating that execution of
    +                                      ~/.ssh/rc should be permitted. Execution
    +                                      of this script will not be permitted if
    +                                      this constraint is not present.
    +
    +source-address          string        Comma-separated list of source addresses
    +                                      from which this certificate is accepted
    +                                      for authentication. Addresses are
    +                                      specified in CIDR format (nn.nn.nn.nn/nn
    +                                      or hhhh::hhhh/nn).
    +                                      If this constraint is not present then
    +                                      certificates may be presented from any
    +                                      source address.
    +
    +$OpenBSD: PROTOCOL.certkeys,v 1.3 2010/03/03 22:50:40 djm Exp $
    diff --git a/crypto/openssh/PROTOCOL.mux b/crypto/openssh/PROTOCOL.mux
    new file mode 100644
    index 00000000000..d22f7379c85
    --- /dev/null
    +++ b/crypto/openssh/PROTOCOL.mux
    @@ -0,0 +1,196 @@
    +This document describes the multiplexing protocol used by ssh(1)'s
    +ControlMaster connection-sharing.
    +
    +Most messages from the client to the server contain a "request id" field.
    +This field is returned in replies as "client request id" to facilitate
    +matching of responses to requests.
    +
    +1. Connection setup
    +
    +When a multiplexing connection is made to a ssh(1) operating as a
    +ControlMaster from a ssh(1) in multiplex slave mode, the first
    +action of each is to exchange hello messages:
    +
    +	uint32	MUX_MSG_HELLO
    +	uint32  protocol version
    +	string  extension name [optional]
    +	string  extension value [optional]
    +	...
    +
    +The current version of the mux protocol is 4. A slave should refuse
    +to connect to a master that speaks an unsupported protocol version.
    +Following the version identifier are zero or more extensions
    +represented as a name/value pair. No extensions are currently
    +defined.
    +
    +2. Opening sessions
    +
    +To open a new multiplexed session, a client may send the following
    +request:
    +
    +	uint32	MUX_C_MSG_NEW_SESSION
    +	uint32  request id
    +	string	reserved
    +	bool	want tty flag
    +	bool	want X11 forwarding flag
    +	bool	want agent flag
    +	bool	subsystem flag
    +	uint32	escape char
    +	string	terminal type
    +	string	command
    +	string	environment string 0 [optional]
    +	...
    +
    +To disable the use of an escape character, "escape char" may be set
    +to 0xffffffff. "terminal type" is generally set to the value of
    +$TERM. zero or more environment strings may follow the command.
    +
    +The client then sends its standard input, output and error file
    +descriptors (in that order) using Unix domain socket control messages.
    +
    +The contents of "reserved" are currently ignored.
    +
    +If successful, the server will reply with MUX_S_SESSION_OPENED
    +
    +	uint32	MUX_S_SESSION_OPENED
    +	uint32	client request id
    +	uint32	session id
    +
    +Otherwise it will reply with an error: MUX_S_PERMISSION_DENIED or
    +MUX_S_FAILURE.
    +
    +Once the server has received the fds, it will respond with MUX_S_OK
    +indicating that the session is up. The client now waits for the
    +session to end. When it does, the server will send an exit status
    +message:
    +
    +	uint32	MUX_S_EXIT_MESSAGE
    +	uint32	session id
    +	uint32	exit value
    +
    +The client should exit with this value to mimic the behaviour of a
    +non-multiplexed ssh(1) connection. Two additional cases that the
    +client must cope with are it receiving a signal itself and the
    +server disconnecting without sending an exit message.
    +
    +3. Health checks
    +
    +The client may request a health check/PID report from a server:
    +
    +	uint32	MUX_C_ALIVE_CHECK
    +	uint32	request id
    +
    +The server replies with:
    +
    +	uint32	MUX_S_ALIVE
    +	uint32	client request id
    +	uint32	server pid
    +
    +4. Remotely terminating a master
    +
    +A client may request that a master terminate immediately:
    +
    +	uint32	MUX_C_TERMINATE
    +	uint32	request id
    +
    +The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED.
    +
    +5. Requesting establishment of port forwards
    +
    +A client may request the master to establish a port forward:
    +
    +	uint32	MUX_C_OPEN_FORWARD
    +	uint32	request id
    +	uint32	forwarding type
    +	string	listen host
    +	string	listen port
    +	string	connect host
    +	string	connect port
    +
    +forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC.
    +
    +A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
    +MUX_S_FAILURE.
    +
    +5. Requesting closure of port forwards
    +
    +A client may request the master to establish a port forward:
    +
    +	uint32	MUX_C_OPEN_FORWARD
    +	uint32	request id
    +	uint32	forwarding type
    +	string	listen host
    +	string	listen port
    +	string	connect host
    +	string	connect port
    +
    +forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC.
    +
    +A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
    +MUX_S_FAILURE.
    +
    +6. Requesting stdio forwarding
    +
    +A client may request the master to establish a stdio forwarding:
    +
    +	uint32	MUX_C_NEW_STDIO_FWD
    +	uint32	request id
    +	string	reserved
    +	string	connect host
    +	string	connect port
    +
    +The client then sends its standard input and output file descriptors
    +(in that order) using Unix domain socket control messages.
    +
    +The contents of "reserved" are currently ignored.
    +
    +A server may reply with a MUX_S_SESSION_OPEED, a MUX_S_PERMISSION_DENIED
    +or a MUX_S_FAILURE.
    +
    +7. Status messages
    +
    +The MUX_S_OK message is empty:
    +
    +	uint32	MUX_S_OK
    +	uint32	client request id
    +
    +The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
    +
    +	uint32	MUX_S_PERMISSION_DENIED
    +	uint32	client request id
    +	string	reason
    +
    +	uint32	MUX_S_FAILURE
    +	uint32	client request id
    +	string	reason
    +
    +7. Protocol numbers
    +
    +#define MUX_MSG_HELLO		0x00000001
    +#define MUX_C_NEW_SESSION	0x10000002
    +#define MUX_C_ALIVE_CHECK	0x10000004
    +#define MUX_C_TERMINATE		0x10000005
    +#define MUX_C_OPEN_FORWARD	0x10000006
    +#define MUX_C_CLOSE_FORWARD	0x10000007
    +#define MUX_S_OK		0x80000001
    +#define MUX_S_PERMISSION_DENIED	0x80000002
    +#define MUX_S_FAILURE		0x80000003
    +#define MUX_S_EXIT_MESSAGE	0x80000004
    +#define MUX_S_ALIVE		0x80000005
    +#define MUX_S_SESSION_OPENED	0x80000006
    +
    +#define MUX_FWD_LOCAL	1
    +#define MUX_FWD_REMOTE	2
    +#define MUX_FWD_DYNAMIC	3
    +
    +XXX TODO
    +XXX extended status (e.g. report open channels / forwards)
    +XXX graceful close (delete listening socket, but keep existing sessions active)
    +XXX lock (maybe)
    +XXX watch in/out traffic (pre/post crypto)
    +XXX inject packet (what about replies)
    +XXX server->client error/warning notifications
    +XXX port0 rfwd (need custom response message)
    +XXX send signals via mux
    +
    +$OpenBSD: PROTOCOL.mux,v 1.1 2010/01/26 01:28:35 djm Exp $
    diff --git a/crypto/openssh/README b/crypto/openssh/README
    index 9de00c09335..0ecb670b6d8 100644
    --- a/crypto/openssh/README
    +++ b/crypto/openssh/README
    @@ -1,4 +1,4 @@
    -See http://www.openssh.com/txt/release-5.2 for the release notes.
    +See http://www.openssh.com/txt/release-5.4 for the release notes.
     
     - A Japanese translation of this document and of the OpenSSH FAQ is
     - available at http://www.unixuser.org/~haruyama/security/openssh/index.html
    @@ -62,4 +62,4 @@ References -
     [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
     [7] http://www.openssh.com/faq.html
     
    -$Id: README,v 1.70 2009/02/23 00:11:57 djm Exp $
    +$Id: README,v 1.72 2010/03/07 22:41:02 djm Exp $
    diff --git a/crypto/openssh/README.platform b/crypto/openssh/README.platform
    index 3d7db149477..d1982321e3a 100644
    --- a/crypto/openssh/README.platform
    +++ b/crypto/openssh/README.platform
    @@ -56,6 +56,18 @@ using a third party driver. More information is available at:
     	http://www-user.rhrk.uni-kl.de/~nissler/tuntap/
     
     
    +Linux
    +-----
    +
    +Some Linux distributions (including Red Hat/Fedora/CentOS) include
    +headers and library links in the -devel RPMs rather than the main
    +binary RPMs. If you get an error about headers, or complaining about a
    +missing prerequisite then you may need to install the equivalent
    +development packages.  On Redhat based distros these may be openssl-devel,
    +zlib-devel and pam-devel, on Debian based distros these may be
    +libssl-dev, libz-dev and libpam-dev.
    +
    +
     Solaris
     -------
     If you enable BSM auditing on Solaris, you need to update audit_event(4)
    @@ -81,4 +93,4 @@ account stacks which will prevent authentication entirely, but will still
     return the output from pam_nologin to the client.
     
     
    -$Id: README.platform,v 1.9 2007/08/09 04:31:53 dtucker Exp $
    +$Id: README.platform,v 1.10 2009/08/28 23:14:48 dtucker Exp $
    diff --git a/crypto/openssh/README.smartcard b/crypto/openssh/README.smartcard
    deleted file mode 100644
    index fdf83ecab4c..00000000000
    --- a/crypto/openssh/README.smartcard
    +++ /dev/null
    @@ -1,93 +0,0 @@
    -How to use smartcards with OpenSSH?
    -
    -OpenSSH contains experimental support for authentication using
    -Cyberflex smartcards and TODOS card readers, in addition to the cards
    -with PKCS#15 structure supported by OpenSC. To enable this you
    -need to:
    -
    -Using libsectok:
    -
    -(1) enable sectok support in OpenSSH:
    -
    -	$ ./configure --with-sectok
    -
    -(2) If you have used a previous version of ssh with your card, you
    -    must remove the old applet and keys.
    -
    -	$ sectok
    -	sectok> login -d
    -	sectok> junload Ssh.bin
    -	sectok> delete 0012
    -	sectok> delete sh
    -	sectok> quit
    -
    -(3) load the Java Cardlet to the Cyberflex card and set card passphrase:
    -
    -	$ sectok
    -	sectok> login -d
    -	sectok> jload /usr/libdata/ssh/Ssh.bin
    -	sectok> setpass
    -	Enter new AUT0 passphrase:
    -	Re-enter passphrase:
    -	sectok> quit
    -
    -	Do not forget the passphrase.  There is no way to
    -	recover if you do.
    -
    -	IMPORTANT WARNING: If you attempt to login with the
    -	wrong passphrase three times in a row, you will
    -	destroy your card.
    -
    -(4) load a RSA key to the card:
    -
    -	$ ssh-keygen -f /path/to/rsakey -U 1
    -	(where 1 is the reader number, you can also try 0)
    -
    -	In spite of the name, this does not generate a key.
    -	It just loads an already existing key on to the card.
    -
    -(5) Optional: If you don't want to use a card passphrase, change the
    -    acl on the private key file:
    -
    -	$ sectok
    -	sectok> login -d
    -	sectok> acl 0012 world: w
    -	 world: w
    -	 AUT0: w inval
    -	sectok> quit
    -
    -	If you do this, anyone who has access to your card
    -	can assume your identity.  This is not recommended.
    -
    -
    -Using OpenSC:
    -
    -(1) install OpenSC:
    -
    -	Sources and instructions are available from
    -	http://www.opensc.org/
    -
    -(2) enable OpenSC support in OpenSSH:
    -
    -	$ ./configure --with-opensc[=/path/to/opensc] [options]
    -
    -(3) load a RSA key to the card:
    -
    -	Not supported yet.
    -
    -
    -Common operations:
    -
    -(1) tell the ssh client to use the card reader:
    -
    -	$ ssh -I 1 otherhost
    -
    -(2) or tell the agent (don't forget to restart) to use the smartcard:
    -
    -	$ ssh-add -s 1
    -
    -
    --markus,
    -Tue Jul 17 23:54:51 CEST 2001
    -
    -$OpenBSD: README.smartcard,v 1.9 2003/11/21 11:57:02 djm Exp $
    diff --git a/crypto/openssh/addrmatch.c b/crypto/openssh/addrmatch.c
    index d39885b7bde..5b6773ccef7 100644
    --- a/crypto/openssh/addrmatch.c
    +++ b/crypto/openssh/addrmatch.c
    @@ -1,4 +1,4 @@
    -/*	$OpenBSD: addrmatch.c,v 1.4 2008/12/10 03:55:20 stevesk Exp $ */
    +/*	$OpenBSD: addrmatch.c,v 1.5 2010/02/26 20:29:54 djm Exp $ */
     
     /*
      * Copyright (c) 2004-2008 Damien Miller 
    @@ -126,6 +126,8 @@ addr_netmask(int af, u_int l, struct xaddr *n)
     	switch (af) {
     	case AF_INET:
     		n->af = AF_INET;
    +		if (l == 0)
    +			return 0;
     		n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff);
     		return 0;
     	case AF_INET6:
    @@ -422,3 +424,77 @@ addr_match_list(const char *addr, const char *_list)
     
     	return ret;
     }
    +
    +/*
    + * Match "addr" against list CIDR list "_list". Lexical wildcards and
    + * negation are not supported. If "addr" == NULL, will verify structure
    + * of "_list".
    + *
    + * Returns 1 on match found (never returned when addr == NULL).
    + * Returns 0 on if no match found, or no errors found when addr == NULL.
    + * Returns -1 on error
    + */
    +int
    +addr_match_cidr_list(const char *addr, const char *_list)
    +{
    +	char *list, *cp, *o;
    +	struct xaddr try_addr, match_addr;
    +	u_int masklen;
    +	int ret = 0, r;
    +
    +	if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
    +		debug2("%s: couldn't parse address %.100s", __func__, addr);
    +		return 0;
    +	}
    +	if ((o = list = strdup(_list)) == NULL)
    +		return -1;
    +	while ((cp = strsep(&list, ",")) != NULL) {
    +		if (*cp == '\0') {
    +			error("%s: empty entry in list \"%.100s\"",
    +			    __func__, o);
    +			ret = -1;
    +			break;
    +		}
    +
    +		/*
    +		 * NB. This function is called in pre-auth with untrusted data,
    +		 * so be extra paranoid about junk reaching getaddrino (via
    +		 * addr_pton_cidr).
    +		 */
    +
    +		/* Stop junk from reaching getaddrinfo. +3 is for masklen */
    +		if (strlen(cp) > INET6_ADDRSTRLEN + 3) {
    +			error("%s: list entry \"%.100s\" too long",
    +			    __func__, cp);
    +			ret = -1;
    +			break;
    +		}
    +#define VALID_CIDR_CHARS "0123456789abcdefABCDEF.:/"
    +		if (strspn(cp, VALID_CIDR_CHARS) != strlen(cp)) {
    +			error("%s: list entry \"%.100s\" contains invalid "
    +			    "characters", __func__, cp);
    +			ret = -1;
    +		}
    +
    +		/* Prefer CIDR address matching */
    +		r = addr_pton_cidr(cp, &match_addr, &masklen);
    +		if (r == -1) {
    +			error("Invalid network entry \"%.100s\"", cp);
    +			ret = -1;
    +			break;
    +		} else if (r == -2) {
    +			error("Inconsistent mask length for "
    +			    "network \"%.100s\"", cp);
    +			ret = -1;
    +			break;
    +		} else if (r == 0 && addr != NULL) {
    +			if (addr_netmatch(&try_addr, &match_addr,
    +			    masklen) == 0)
    +				ret = 1;
    +			continue;
    +		}
    +	}
    +	xfree(o);
    +
    +	return ret;
    +}
    diff --git a/crypto/openssh/auth-krb5.c b/crypto/openssh/auth-krb5.c
    index 86828812621..d019fe202c5 100644
    --- a/crypto/openssh/auth-krb5.c
    +++ b/crypto/openssh/auth-krb5.c
    @@ -78,6 +78,11 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
     	krb5_error_code problem;
     	krb5_ccache ccache = NULL;
     	int len;
    +	char *client, *platform_client;
    +
    +	/* get platform-specific kerberos client principal name (if it exists) */
    +	platform_client = platform_krb5_get_principal_name(authctxt->pw->pw_name);
    +	client = platform_client ? platform_client : authctxt->pw->pw_name;
     
     	temporarily_use_uid(authctxt->pw);
     
    @@ -85,7 +90,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
     	if (problem)
     		goto out;
     
    -	problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
    +	problem = krb5_parse_name(authctxt->krb5_ctx, client,
     		    &authctxt->krb5_user);
     	if (problem)
     		goto out;
    @@ -141,8 +146,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
     	if (problem)
     		goto out;
     
    -	if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
    -			  authctxt->pw->pw_name)) {
    +	if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) {
     		problem = -1;
     		goto out;
     	}
    @@ -176,6 +180,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
     
      out:
     	restore_uid();
    +	
    +	if (platform_client != NULL)
    +		xfree(platform_client);
     
     	if (problem) {
     		if (ccache)
    diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c
    index ab085c2339c..129301765b7 100644
    --- a/crypto/openssh/auth-options.c
    +++ b/crypto/openssh/auth-options.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */
    +/* $OpenBSD: auth-options.c,v 1.48 2010/03/07 11:57:13 dtucker Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -44,6 +44,7 @@ int no_agent_forwarding_flag = 0;
     int no_x11_forwarding_flag = 0;
     int no_pty_flag = 0;
     int no_user_rc = 0;
    +int key_is_cert_authority = 0;
     
     /* "command=" option. */
     char *forced_command = NULL;
    @@ -64,6 +65,7 @@ auth_clear_options(void)
     	no_pty_flag = 0;
     	no_x11_forwarding_flag = 0;
     	no_user_rc = 0;
    +	key_is_cert_authority = 0;
     	while (custom_environment) {
     		struct envstring *ce = custom_environment;
     		custom_environment = ce->next;
    @@ -76,7 +78,6 @@ auth_clear_options(void)
     	}
     	forced_tun_device = -1;
     	channel_clear_permitted_opens();
    -	auth_debug_reset();
     }
     
     /*
    @@ -96,6 +97,12 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
     		return 1;
     
     	while (*opts && *opts != ' ' && *opts != '\t') {
    +		cp = "cert-authority";
    +		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
    +			key_is_cert_authority = 1;
    +			opts += strlen(cp);
    +			goto next_option;
    +		}
     		cp = "no-port-forwarding";
     		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
     			auth_debug_add("Port forwarding disabled.");
    @@ -356,9 +363,6 @@ next_option:
     		/* Process the next option. */
     	}
     
    -	if (!use_privsep)
    -		auth_debug_send();
    -
     	/* grant access */
     	return 1;
     
    @@ -368,9 +372,158 @@ bad_option:
     	auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
     	    file, linenum, opts);
     
    -	if (!use_privsep)
    -		auth_debug_send();
    -
     	/* deny access */
     	return 0;
     }
    +
    +/*
    + * Set options from certificate constraints. These supersede user key options
    + * so this must be called after auth_parse_options().
    + */
    +int
    +auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
    +{
    +	u_char *name = NULL, *data_blob = NULL;
    +	u_int nlen, dlen, clen;
    +	Buffer c, data;
    +	int ret = -1;
    +
    +	int cert_no_port_forwarding_flag = 1;
    +	int cert_no_agent_forwarding_flag = 1;
    +	int cert_no_x11_forwarding_flag = 1;
    +	int cert_no_pty_flag = 1;
    +	int cert_no_user_rc = 1;
    +	char *cert_forced_command = NULL;
    +	int cert_source_address_done = 0;
    +
    +	buffer_init(&data);
    +
    +	/* Make copy to avoid altering original */
    +	buffer_init(&c);
    +	buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig));
    +
    +	while (buffer_len(&c) > 0) {
    +		if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
    +		    (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
    +			error("Certificate constraints corrupt");
    +			goto out;
    +		}
    +		buffer_append(&data, data_blob, dlen);
    +		debug3("found certificate constraint \"%.100s\" len %u",
    +		    name, dlen);
    +		if (strlen(name) != nlen) {
    +			error("Certificate constraint name contains \\0");
    +			goto out;
    +		}
    +		if (strcmp(name, "permit-X11-forwarding") == 0)
    +			cert_no_x11_forwarding_flag = 0;
    +		else if (strcmp(name, "permit-agent-forwarding") == 0)
    +			cert_no_agent_forwarding_flag = 0;
    +		else if (strcmp(name, "permit-port-forwarding") == 0)
    +			cert_no_port_forwarding_flag = 0;
    +		else if (strcmp(name, "permit-pty") == 0)
    +			cert_no_pty_flag = 0;
    +		else if (strcmp(name, "permit-user-rc") == 0)
    +			cert_no_user_rc = 0;
    +		else if (strcmp(name, "force-command") == 0) {
    +			char *command = buffer_get_string_ret(&data, &clen);
    +
    +			if (command == NULL) {
    +				error("Certificate constraint \"%s\" corrupt",
    +				    name);
    +				goto out;
    +			}
    +			if (strlen(command) != clen) {
    +				error("force-command constrain contains \\0");
    +				goto out;
    +			}
    +			if (cert_forced_command != NULL) {
    +				error("Certificate has multiple "
    +				    "force-command constraints");
    +				xfree(command);
    +				goto out;
    +			}
    +			cert_forced_command = command;
    +		} else if (strcmp(name, "source-address") == 0) {
    +			char *allowed = buffer_get_string_ret(&data, &clen);
    +			const char *remote_ip = get_remote_ipaddr();
    +			
    +			if (allowed == NULL) {
    +				error("Certificate constraint \"%s\" corrupt",
    +				    name);
    +				goto out;
    +			}
    +			if (strlen(allowed) != clen) {
    +				error("source-address constrain contains \\0");
    +				goto out;
    +			}
    +			if (cert_source_address_done++) {
    +				error("Certificate has multiple "
    +				    "source-address constraints");
    +				xfree(allowed);
    +				goto out;
    +			}
    +			switch (addr_match_cidr_list(remote_ip, allowed)) {
    +			case 1:
    +				/* accepted */
    +				xfree(allowed);
    +				break;
    +			case 0:
    +				/* no match */
    +				logit("Authentication tried for %.100s with "
    +				    "valid certificate but not from a "
    +				    "permitted host (ip=%.200s).",
    +				    pw->pw_name, remote_ip);
    +				auth_debug_add("Your address '%.200s' is not "
    +				    "permitted to use this certificate for "
    +				    "login.", remote_ip);
    +				xfree(allowed);
    +				goto out;
    +			case -1:
    +				error("Certificate source-address contents "
    +				    "invalid");
    +				xfree(allowed);
    +				goto out;
    +			}
    +		} else {
    +			error("Certificate constraint \"%s\" is not supported",
    +			    name);
    +			goto out;
    +		}
    +
    +		if (buffer_len(&data) != 0) {
    +			error("Certificate constraint \"%s\" corrupt "
    +			    "(extra data)", name);
    +			goto out;
    +		}
    +		buffer_clear(&data);
    +		xfree(name);
    +		xfree(data_blob);
    +		name = data_blob = NULL;
    +	}
    +
    +	/* successfully parsed all constraints */
    +	ret = 0;
    +
    +	no_port_forwarding_flag |= cert_no_port_forwarding_flag;
    +	no_agent_forwarding_flag |= cert_no_agent_forwarding_flag;
    +	no_x11_forwarding_flag |= cert_no_x11_forwarding_flag;
    +	no_pty_flag |= cert_no_pty_flag;
    +	no_user_rc |= cert_no_user_rc;
    +	/* CA-specified forced command supersedes key option */
    +	if (cert_forced_command != NULL) {
    +		if (forced_command != NULL)
    +			xfree(forced_command);
    +		forced_command = cert_forced_command;
    +	}
    +	
    + out:
    +	if (name != NULL)
    +		xfree(name);
    +	if (data_blob != NULL)
    +		xfree(data_blob);
    +	buffer_free(&data);
    +	buffer_free(&c);
    +	return ret;
    +}
    +
    diff --git a/crypto/openssh/auth-options.h b/crypto/openssh/auth-options.h
    index 14488f72d8d..694edc842b3 100644
    --- a/crypto/openssh/auth-options.h
    +++ b/crypto/openssh/auth-options.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth-options.h,v 1.17 2008/03/26 21:28:14 djm Exp $ */
    +/* $OpenBSD: auth-options.h,v 1.18 2010/02/26 20:29:54 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -30,8 +30,10 @@ extern int no_user_rc;
     extern char *forced_command;
     extern struct envstring *custom_environment;
     extern int forced_tun_device;
    +extern int key_is_cert_authority;
     
     int	auth_parse_options(struct passwd *, char *, char *, u_long);
     void	auth_clear_options(void);
    +int	auth_cert_constraints(Buffer *, struct passwd *);
     
     #endif
    diff --git a/crypto/openssh/auth-pam.c b/crypto/openssh/auth-pam.c
    index bbfafa67e05..fc79dee80e8 100644
    --- a/crypto/openssh/auth-pam.c
    +++ b/crypto/openssh/auth-pam.c
    @@ -602,16 +602,16 @@ sshpam_cleanup(void)
     		return;
     	debug("PAM: cleanup");
     	pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
    -	if (sshpam_cred_established) {
    -		debug("PAM: deleting credentials");
    -		pam_setcred(sshpam_handle, PAM_DELETE_CRED);
    -		sshpam_cred_established = 0;
    -	}
     	if (sshpam_session_open) {
     		debug("PAM: closing session");
     		pam_close_session(sshpam_handle, PAM_SILENT);
     		sshpam_session_open = 0;
     	}
    +	if (sshpam_cred_established) {
    +		debug("PAM: deleting credentials");
    +		pam_setcred(sshpam_handle, PAM_DELETE_CRED);
    +		sshpam_cred_established = 0;
    +	}
     	sshpam_authenticated = 0;
     	pam_end(sshpam_handle, sshpam_err);
     	sshpam_handle = NULL;
    diff --git a/crypto/openssh/auth-passwd.c b/crypto/openssh/auth-passwd.c
    index bdfced023f2..b1c6ce09289 100644
    --- a/crypto/openssh/auth-passwd.c
    +++ b/crypto/openssh/auth-passwd.c
    @@ -102,7 +102,7 @@ auth_password(Authctxt *authctxt, const char *password)
     	}
     #endif
     #ifdef HAVE_CYGWIN
    -	if (is_winnt) {
    +	{
     		HANDLE hToken = cygwin_logon_user(pw, password);
     
     		if (hToken == INVALID_HANDLE_VALUE)
    diff --git a/crypto/openssh/auth-rh-rsa.c b/crypto/openssh/auth-rh-rsa.c
    index eca75027580..b21a0f4a2f8 100644
    --- a/crypto/openssh/auth-rh-rsa.c
    +++ b/crypto/openssh/auth-rh-rsa.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth-rh-rsa.c,v 1.42 2006/08/03 03:34:41 deraadt Exp $ */
    +/* $OpenBSD: auth-rh-rsa.c,v 1.43 2010/03/04 10:36:03 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -44,6 +44,9 @@ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
     {
     	HostStatus host_status;
     
    +	if (auth_key_is_revoked(client_host_key))
    +		return 0;
    +
     	/* Check if we would accept it using rhosts authentication. */
     	if (!auth_rhosts(pw, cuser))
     		return 0;
    diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c
    index 5c12967016b..06ae7f0b9e7 100644
    --- a/crypto/openssh/auth-rhosts.c
    +++ b/crypto/openssh/auth-rhosts.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth-rhosts.c,v 1.43 2008/06/13 14:18:51 dtucker Exp $ */
    +/* $OpenBSD: auth-rhosts.c,v 1.44 2010/03/07 11:57:13 dtucker Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -317,11 +317,5 @@ int
     auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
         const char *ipaddr)
     {
    -	int ret;
    -
    -	auth_debug_reset();
    -	ret = auth_rhosts2_raw(pw, client_user, hostname, ipaddr);
    -	if (!use_privsep)
    -		auth_debug_send();
    -	return ret;
    +       return auth_rhosts2_raw(pw, client_user, hostname, ipaddr);
     }
    diff --git a/crypto/openssh/auth-rsa.c b/crypto/openssh/auth-rsa.c
    index bf54620760a..65571a890b4 100644
    --- a/crypto/openssh/auth-rsa.c
    +++ b/crypto/openssh/auth-rsa.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth-rsa.c,v 1.73 2008/07/02 12:03:51 dtucker Exp $ */
    +/* $OpenBSD: auth-rsa.c,v 1.74 2010/03/04 10:36:03 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -94,6 +94,9 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
     	MD5_CTX md;
     	int len;
     
    +	if (auth_key_is_revoked(key))
    +		return 0;
    +
     	/* don't allow short keys */
     	if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
     		error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits",
    diff --git a/crypto/openssh/auth-sia.c b/crypto/openssh/auth-sia.c
    index debf30201b7..a9e1c258ca6 100644
    --- a/crypto/openssh/auth-sia.c
    +++ b/crypto/openssh/auth-sia.c
    @@ -34,10 +34,6 @@
     #include 
     #include 
     #include 
    -#include 
    -#include 
    -#include 
    -#include 
     
     #include "ssh.h"
     #include "key.h"
    @@ -53,52 +49,6 @@ extern ServerOptions options;
     extern int saved_argc;
     extern char **saved_argv;
     
    -static int
    -sia_password_change_required(const char *user)
    -{
    -	struct es_passwd *acct;
    -	time_t pw_life;
    -	time_t pw_date;
    -
    -	set_auth_parameters(saved_argc, saved_argv);
    -
    -	if ((acct = getespwnam(user)) == NULL) {
    -		error("Couldn't access protected database entry for %s", user);
    -		endprpwent();
    -		return (0);
    -	}
    -
    -	/* If forced password change flag is set, honor it */
    -	if (acct->uflg->fg_psw_chg_reqd && acct->ufld->fd_psw_chg_reqd) {
    -		endprpwent();
    -		return (1);
    -	}
    -
    -	/* Obtain password lifetime; if none, it can't have expired */
    -	if (acct->uflg->fg_expire)
    -		pw_life = acct->ufld->fd_expire;
    -	else if (acct->sflg->fg_expire)
    -		pw_life = acct->sfld->fd_expire;
    -	else {
    -		endprpwent();
    -		return (0);
    -	}
    -
    -	/* Offset from last change; if none, it must be expired */
    -	if (acct->uflg->fg_schange)
    -		pw_date = acct->ufld->fd_schange + pw_life;
    -	else {
    -		endprpwent();
    -		return (1);
    -	}
    -
    -	endprpwent();
    -
    -	/* If expiration date is prior to now, change password */
    -	
    -	return (pw_date <= time((time_t *) NULL));
    -}
    -
     int
     sys_auth_passwd(Authctxt *authctxt, const char *pass)
     {
    @@ -126,9 +76,6 @@ sys_auth_passwd(Authctxt *authctxt, const char *pass)
     
     	sia_ses_release(&ent);
     
    -	authctxt->force_pwchange = sia_password_change_required(
    -		authctxt->user);
    -
     	return (1);
     }
     
    diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c
    index 02f9175ee48..2917414304d 100644
    --- a/crypto/openssh/auth.c
    +++ b/crypto/openssh/auth.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth.c,v 1.80 2008/11/04 07:58:09 djm Exp $ */
    +/* $OpenBSD: auth.c,v 1.86 2010/03/05 02:58:11 djm Exp $ */
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
      *
    @@ -70,6 +70,7 @@ __RCSID("$FreeBSD$");
     #ifdef GSSAPI
     #include "ssh-gss.h"
     #endif
    +#include "authfile.h"
     #include "monitor_wrap.h"
     
     /* import */
    @@ -96,7 +97,6 @@ allowed_user(struct passwd * pw)
     {
     	struct stat st;
     	const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
    -	char *shell;
     	u_int i;
     #ifdef USE_SHADOW
     	struct spwd *spw = NULL;
    @@ -154,22 +154,28 @@ allowed_user(struct passwd * pw)
     	}
     
     	/*
    -	 * Get the shell from the password data.  An empty shell field is
    -	 * legal, and means /bin/sh.
    +	 * Deny if shell does not exist or is not executable unless we
    +	 * are chrooting.
     	 */
    -	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
    +	if (options.chroot_directory == NULL ||
    +	    strcasecmp(options.chroot_directory, "none") == 0) {
    +		char *shell = xstrdup((pw->pw_shell[0] == '\0') ?
    +		    _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */
     
    -	/* deny if shell does not exists or is not executable */
    -	if (stat(shell, &st) != 0) {
    -		logit("User %.100s not allowed because shell %.100s does not exist",
    -		    pw->pw_name, shell);
    -		return 0;
    -	}
    -	if (S_ISREG(st.st_mode) == 0 ||
    -	    (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
    -		logit("User %.100s not allowed because shell %.100s is not executable",
    -		    pw->pw_name, shell);
    -		return 0;
    +		if (stat(shell, &st) != 0) {
    +			logit("User %.100s not allowed because shell %.100s "
    +			    "does not exist", pw->pw_name, shell);
    +			xfree(shell);
    +			return 0;
    +		}
    +		if (S_ISREG(st.st_mode) == 0 ||
    +		    (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
    +			logit("User %.100s not allowed because shell %.100s "
    +			    "is not executable", pw->pw_name, shell);
    +			xfree(shell);
    +			return 0;
    +		}
    +		xfree(shell);
     	}
     
     	if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
    @@ -456,7 +462,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
     			return -1;
     		}
     
    -		/* If are passed the homedir then we can stop */
    +		/* If are past the homedir then we can stop */
     		if (comparehome && strcmp(homedir, buf) == 0) {
     			debug3("secure_filename: terminating check at '%s'",
     			    buf);
    @@ -484,8 +490,12 @@ auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
     	 * Open the file containing the authorized keys
     	 * Fail quietly if file does not exist
     	 */
    -	if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1)
    +	if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
    +		if (errno != ENOENT)
    +			debug("Could not open keyfile '%s': %s", file,
    +			   strerror(errno));
     		return NULL;
    +	}
     
     	if (fstat(fd, &st) < 0) {
     		close(fd);
    @@ -526,7 +536,28 @@ getpwnamallow(const char *user)
     	parse_server_match_config(&options, user,
     	    get_canonical_hostname(options.use_dns), get_remote_ipaddr());
     
    +#if defined(_AIX) && defined(HAVE_SETAUTHDB)
    +	aix_setauthdb(user);
    +#endif
    +
     	pw = getpwnam(user);
    +
    +#if defined(_AIX) && defined(HAVE_SETAUTHDB)
    +	aix_restoreauthdb();
    +#endif
    +#ifdef HAVE_CYGWIN
    +	/*
    +	 * Windows usernames are case-insensitive.  To avoid later problems
    +	 * when trying to match the username, the user is only allowed to
    +	 * login if the username is given in the same case as stored in the
    +	 * user database.
    +	 */
    +	if (pw != NULL && strcmp(user, pw->pw_name) != 0) {
    +		logit("Login name %.100s does not match stored username %.100s",
    +		    user, pw->pw_name);
    +		pw = NULL;
    +	}
    +#endif
     	if (pw == NULL) {
     		logit("Invalid user %.100s from %.100s",
     		    user, get_remote_ipaddr());
    @@ -561,6 +592,35 @@ getpwnamallow(const char *user)
     	return (NULL);
     }
     
    +/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
    +int
    +auth_key_is_revoked(Key *key)
    +{
    +	char *key_fp;
    +
    +	if (options.revoked_keys_file == NULL)
    +		return 0;
    +
    +	switch (key_in_file(key, options.revoked_keys_file, 0)) {
    +	case 0:
    +		/* key not revoked */
    +		return 0;
    +	case -1:
    +		/* Error opening revoked_keys_file: refuse all keys */
    +		error("Revoked keys file is unreadable: refusing public key "
    +		    "authentication");
    +		return 1;
    +	case 1:
    +		/* Key revoked */
    +		key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
    +		error("WARNING: authentication attempt with a revoked "
    +		    "%s key %s ", key_type(key), key_fp);
    +		xfree(key_fp);
    +		return 1;
    +	}
    +	fatal("key_in_file returned junk");
    +}
    +
     void
     auth_debug_add(const char *fmt,...)
     {
    diff --git a/crypto/openssh/auth.h b/crypto/openssh/auth.h
    index 3a70f442134..a65b87dd126 100644
    --- a/crypto/openssh/auth.h
    +++ b/crypto/openssh/auth.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth.h,v 1.62 2008/11/04 08:22:12 djm Exp $ */
    +/* $OpenBSD: auth.h,v 1.65 2010/03/04 10:36:03 djm Exp $ */
     
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
    @@ -171,6 +171,7 @@ char	*authorized_keys_file(struct passwd *);
     char	*authorized_keys_file2(struct passwd *);
     
     FILE	*auth_openkeyfile(const char *, struct passwd *, int);
    +int	 auth_key_is_revoked(Key *);
     
     HostStatus
     check_key_in_hostfiles(struct passwd *, Key *, const char *,
    @@ -178,7 +179,8 @@ check_key_in_hostfiles(struct passwd *, Key *, const char *,
     
     /* hostkey handling */
     Key	*get_hostkey_by_index(int);
    -Key	*get_hostkey_by_type(int);
    +Key	*get_hostkey_public_by_type(int);
    +Key	*get_hostkey_private_by_type(int);
     int	 get_hostkey_index(Key *);
     int	 ssh1_session_key(BIGNUM *);
     
    diff --git a/crypto/openssh/auth1.c b/crypto/openssh/auth1.c
    index b8a25587232..1801661fdda 100644
    --- a/crypto/openssh/auth1.c
    +++ b/crypto/openssh/auth1.c
    @@ -318,15 +318,7 @@ do_authloop(Authctxt *authctxt)
     		}
     #endif /* _UNICOS */
     
    -#ifdef HAVE_CYGWIN
    -		if (authenticated &&
    -		    !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,
    -		    authctxt->pw)) {
    -			packet_disconnect("Authentication rejected for uid %d.",
    -			    authctxt->pw == NULL ? -1 : authctxt->pw->pw_uid);
    -			authenticated = 0;
    -		}
    -#else
    +#ifndef HAVE_CYGWIN
     		/* Special handling for root */
     		if (authenticated && authctxt->pw->pw_uid == 0 &&
     		    !auth_root_allowed(meth->name)) {
    diff --git a/crypto/openssh/auth2-hostbased.c b/crypto/openssh/auth2-hostbased.c
    index 041051c53c7..721646520fe 100644
    --- a/crypto/openssh/auth2-hostbased.c
    +++ b/crypto/openssh/auth2-hostbased.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth2-hostbased.c,v 1.12 2008/07/17 08:51:07 djm Exp $ */
    +/* $OpenBSD: auth2-hostbased.c,v 1.13 2010/03/04 10:36:03 djm Exp $ */
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
      *
    @@ -145,6 +145,9 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
     	HostStatus host_status;
     	int len;
     
    +	if (auth_key_is_revoked(key))
    +		return 0;
    +
     	resolvedname = get_canonical_hostname(options.use_dns);
     	ipaddr = get_remote_ipaddr();
     
    diff --git a/crypto/openssh/auth2-jpake.c b/crypto/openssh/auth2-jpake.c
    index efe7ff2a396..5de5506a664 100644
    --- a/crypto/openssh/auth2-jpake.c
    +++ b/crypto/openssh/auth2-jpake.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth2-jpake.c,v 1.2 2008/11/07 23:34:48 dtucker Exp $ */
    +/* $OpenBSD: auth2-jpake.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
     /*
      * Copyright (c) 2008 Damien Miller.  All rights reserved.
      *
    @@ -42,8 +42,8 @@
     #include "ssh2.h"
     #include "key.h"
     #include "hostfile.h"
    -#include "buffer.h"
     #include "auth.h"
    +#include "buffer.h"
     #include "packet.h"
     #include "dispatch.h"
     #include "log.h"
    @@ -55,6 +55,7 @@
     #endif
     #include "monitor_wrap.h"
     
    +#include "schnorr.h"
     #include "jpake.h"
     
     /*
    @@ -359,7 +360,7 @@ auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
     }
     
     /*
    - * Being authentication attempt.
    + * Begin authentication attempt.
      * Note, sets authctxt->postponed while in subprotocol
      */
     static int
    diff --git a/crypto/openssh/auth2-kbdint.c b/crypto/openssh/auth2-kbdint.c
    index a4fc9e6f73f..fae67da6e33 100644
    --- a/crypto/openssh/auth2-kbdint.c
    +++ b/crypto/openssh/auth2-kbdint.c
    @@ -58,10 +58,6 @@ userauth_kbdint(Authctxt *authctxt)
     
     	xfree(devs);
     	xfree(lang);
    -#ifdef HAVE_CYGWIN
    -	if (check_nt_auth(0, authctxt->pw) == 0)
    -		authenticated = 0;
    -#endif
     	return authenticated;
     }
     
    diff --git a/crypto/openssh/auth2-none.c b/crypto/openssh/auth2-none.c
    index 10accfe552d..08f2f935fe9 100644
    --- a/crypto/openssh/auth2-none.c
    +++ b/crypto/openssh/auth2-none.c
    @@ -61,10 +61,6 @@ userauth_none(Authctxt *authctxt)
     {
     	none_enabled = 0;
     	packet_check_eom();
    -#ifdef HAVE_CYGWIN
    -	if (check_nt_auth(1, authctxt->pw) == 0)
    -		return (0);
    -#endif
     	if (options.password_authentication)
     		return (PRIVSEP(auth_password(authctxt, "")));
     	return (0);
    diff --git a/crypto/openssh/auth2-passwd.c b/crypto/openssh/auth2-passwd.c
    index 421c5c25d01..5f1f3635f7a 100644
    --- a/crypto/openssh/auth2-passwd.c
    +++ b/crypto/openssh/auth2-passwd.c
    @@ -68,10 +68,6 @@ userauth_passwd(Authctxt *authctxt)
     		logit("password change not supported");
     	else if (PRIVSEP(auth_password(authctxt, password)) == 1)
     		authenticated = 1;
    -#ifdef HAVE_CYGWIN
    -	if (check_nt_auth(1, authctxt->pw) == 0)
    -		authenticated = 0;
    -#endif
     	memset(password, 0, len);
     	xfree(password);
     	return authenticated;
    diff --git a/crypto/openssh/auth2-pubkey.c b/crypto/openssh/auth2-pubkey.c
    index b1e38e5f586..51aa774872b 100644
    --- a/crypto/openssh/auth2-pubkey.c
    +++ b/crypto/openssh/auth2-pubkey.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth2-pubkey.c,v 1.19 2008/07/03 21:46:58 otto Exp $ */
    +/* $OpenBSD: auth2-pubkey.c,v 1.21 2010/03/04 10:36:03 djm Exp $ */
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
      *
    @@ -32,6 +32,8 @@
     #include 
     #include 
     #include 
    +#include 
    +#include 
     #include 
     
     #include "xmalloc.h"
    @@ -54,6 +56,7 @@
     #endif
     #include "monitor_wrap.h"
     #include "misc.h"
    +#include "authfile.h"
     
     /* import */
     extern ServerOptions options;
    @@ -170,10 +173,6 @@ done:
     		key_free(key);
     	xfree(pkalg);
     	xfree(pkblob);
    -#ifdef HAVE_CYGWIN
    -	if (check_nt_auth(0, authctxt->pw) == 0)
    -		authenticated = 0;
    -#endif
     	return authenticated;
     }
     
    @@ -182,6 +181,7 @@ static int
     user_key_allowed2(struct passwd *pw, Key *key, char *file)
     {
     	char line[SSH_MAX_PUBKEY_BYTES];
    +	const char *reason;
     	int found_key = 0;
     	FILE *f;
     	u_long linenum = 0;
    @@ -200,11 +200,13 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
     	}
     
     	found_key = 0;
    -	found = key_new(key->type);
    +	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
     
     	while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
     		char *cp, *key_options = NULL;
     
    +		auth_clear_options();
    +
     		/* Skip leading whitespace, empty and comment lines. */
     		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
     			;
    @@ -231,8 +233,32 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
     				continue;
     			}
     		}
    -		if (key_equal(found, key) &&
    -		    auth_parse_options(pw, key_options, file, linenum) == 1) {
    +		if (auth_parse_options(pw, key_options, file, linenum) != 1)
    +			continue;
    +		if (key->type == KEY_RSA_CERT || key->type == KEY_DSA_CERT) {
    +			if (!key_is_cert_authority)
    +				continue;
    +			if (!key_equal(found, key->cert->signature_key))
    +				continue;
    +			debug("matching CA found: file %s, line %lu",
    +			    file, linenum);
    +			fp = key_fingerprint(found, SSH_FP_MD5,
    +			    SSH_FP_HEX);
    +			verbose("Found matching %s CA: %s",
    +			    key_type(found), fp);
    +			xfree(fp);
    +			if (key_cert_check_authority(key, 0, 0, pw->pw_name,
    +			    &reason) != 0) {
    +				error("%s", reason);
    +				auth_debug_add("%s", reason);
    +				continue;
    +			}
    +			if (auth_cert_constraints(&key->cert->constraints,
    +			    pw) != 0)
    +				continue;
    +			found_key = 1;
    +			break;
    +		} else if (!key_is_cert_authority && key_equal(found, key)) {
     			found_key = 1;
     			debug("matching key found: file %s, line %lu",
     			    file, linenum);
    @@ -251,6 +277,47 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
     	return found_key;
     }
     
    +/* Authenticate a certificate key against TrustedUserCAKeys */
    +static int
    +user_cert_trusted_ca(struct passwd *pw, Key *key)
    +{
    +	char *key_fp, *ca_fp;
    +	const char *reason;
    +	int ret = 0;
    +
    +	if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
    +		return 0;
    +
    +	key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
    +	ca_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
    +
    +	if (key_in_file(key->cert->signature_key,
    +	    options.trusted_user_ca_keys, 1) != 1) {
    +		debug2("%s: CA %s %s is not listed in %s", __func__,
    +		    key_type(key->cert->signature_key), ca_fp,
    +		    options.trusted_user_ca_keys);
    +		goto out;
    +	}
    +	if (key_cert_check_authority(key, 0, 1, pw->pw_name, &reason) != 0) {
    +		error("%s", reason);
    +		auth_debug_add("%s", reason);
    +		goto out;
    +	}
    +	if (auth_cert_constraints(&key->cert->constraints, pw) != 0)
    +		goto out;
    +
    +	verbose("%s certificate %s allowed by trusted %s key %s",
    +	    key_type(key), key_fp, key_type(key->cert->signature_key), ca_fp);
    +	ret = 1;
    +
    + out:
    +	if (key_fp != NULL)
    +		xfree(key_fp);
    +	if (ca_fp != NULL)
    +		xfree(ca_fp);
    +	return ret;
    +}
    +
     /* check whether given key is in .ssh/authorized_keys* */
     int
     user_key_allowed(struct passwd *pw, Key *key)
    @@ -258,6 +325,15 @@ user_key_allowed(struct passwd *pw, Key *key)
     	int success;
     	char *file;
     
    +	if (auth_key_is_revoked(key))
    +		return 0;
    +	if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
    +		return 0;
    +
    +	success = user_cert_trusted_ca(pw, key);
    +	if (success)
    +		return success;
    +
     	file = authorized_keys_file(pw);
     	success = user_key_allowed2(pw, key, file);
     	xfree(file);
    diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c
    index 1c44bb5c937..50fb3396f04 100644
    --- a/crypto/openssh/auth2.c
    +++ b/crypto/openssh/auth2.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: auth2.c,v 1.120 2008/11/04 08:22:12 djm Exp $ */
    +/* $OpenBSD: auth2.c,v 1.121 2009/06/22 05:39:28 dtucker Exp $ */
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
      *
    @@ -36,8 +36,8 @@ __RCSID("$FreeBSD$");
     #include 
     #include 
     
    -#include "xmalloc.h"
     #include "atomicio.h"
    +#include "xmalloc.h"
     #include "ssh2.h"
     #include "packet.h"
     #include "log.h"
    diff --git a/crypto/openssh/authfd.c b/crypto/openssh/authfd.c
    index 61faad12319..28a8cf2d7d8 100644
    --- a/crypto/openssh/authfd.c
    +++ b/crypto/openssh/authfd.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: authfd.c,v 1.80 2006/08/03 03:34:41 deraadt Exp $ */
    +/* $OpenBSD: authfd.c,v 1.82 2010/02/26 20:29:54 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -483,6 +483,16 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
     		buffer_put_bignum2(b, key->rsa->p);
     		buffer_put_bignum2(b, key->rsa->q);
     		break;
    +	case KEY_RSA_CERT:
    +		if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
    +			fatal("%s: no cert/certblob", __func__);
    +		buffer_put_string(b, buffer_ptr(&key->cert->certblob),
    +		    buffer_len(&key->cert->certblob));
    +		buffer_put_bignum2(b, key->rsa->d);
    +		buffer_put_bignum2(b, key->rsa->iqmp);
    +		buffer_put_bignum2(b, key->rsa->p);
    +		buffer_put_bignum2(b, key->rsa->q);
    +		break;
     	case KEY_DSA:
     		buffer_put_bignum2(b, key->dsa->p);
     		buffer_put_bignum2(b, key->dsa->q);
    @@ -490,6 +500,13 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
     		buffer_put_bignum2(b, key->dsa->pub_key);
     		buffer_put_bignum2(b, key->dsa->priv_key);
     		break;
    +	case KEY_DSA_CERT:
    +		if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
    +			fatal("%s: no cert/certblob", __func__);
    +		buffer_put_string(b, buffer_ptr(&key->cert->certblob),
    +		    buffer_len(&key->cert->certblob));
    +		buffer_put_bignum2(b, key->dsa->priv_key);
    +		break;
     	}
     	buffer_put_cstring(b, comment);
     }
    @@ -517,7 +534,9 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
     		ssh_encode_identity_rsa1(&msg, key->rsa, comment);
     		break;
     	case KEY_RSA:
    +	case KEY_RSA_CERT:
     	case KEY_DSA:
    +	case KEY_DSA_CERT:
     		type = constrained ?
     		    SSH2_AGENTC_ADD_ID_CONSTRAINED :
     		    SSH2_AGENTC_ADD_IDENTITY;
    @@ -545,12 +564,6 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
     	return decode_reply(type);
     }
     
    -int
    -ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment)
    -{
    -	return ssh_add_identity_constrained(auth, key, comment, 0, 0);
    -}
    -
     /*
      * Removes an identity from the authentication server.  This call is not
      * meant to be used by normal applications.
    @@ -571,7 +584,8 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
     		buffer_put_int(&msg, BN_num_bits(key->rsa->n));
     		buffer_put_bignum(&msg, key->rsa->e);
     		buffer_put_bignum(&msg, key->rsa->n);
    -	} else if (key->type == KEY_DSA || key->type == KEY_RSA) {
    +	} else if (key_type_plain(key->type) == KEY_DSA ||
    +	    key_type_plain(key->type) == KEY_RSA) {
     		key_to_blob(key, &blob, &blen);
     		buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
     		buffer_put_string(&msg, blob, blen);
    diff --git a/crypto/openssh/authfd.h b/crypto/openssh/authfd.h
    index 3da2561127e..2582a27aa52 100644
    --- a/crypto/openssh/authfd.h
    +++ b/crypto/openssh/authfd.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: authfd.h,v 1.36 2006/08/03 03:34:41 deraadt Exp $ */
    +/* $OpenBSD: authfd.h,v 1.37 2009/08/27 17:44:52 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -75,7 +75,6 @@ void	ssh_close_authentication_connection(AuthenticationConnection *);
     int	 ssh_get_num_identities(AuthenticationConnection *, int);
     Key	*ssh_get_first_identity(AuthenticationConnection *, char **, int);
     Key	*ssh_get_next_identity(AuthenticationConnection *, char **, int);
    -int	 ssh_add_identity(AuthenticationConnection *, Key *, const char *);
     int	 ssh_add_identity_constrained(AuthenticationConnection *, Key *,
         const char *, u_int, u_int);
     int	 ssh_remove_identity(AuthenticationConnection *, Key *);
    diff --git a/crypto/openssh/authfile.c b/crypto/openssh/authfile.c
    index 735c6478096..224c6aa806f 100644
    --- a/crypto/openssh/authfile.c
    +++ b/crypto/openssh/authfile.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: authfile.c,v 1.76 2006/08/03 03:34:41 deraadt Exp $ */
    +/* $OpenBSD: authfile.c,v 1.80 2010/03/04 10:36:03 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -47,6 +47,9 @@
     #include 
     #include 
     
    +/* compatibility with old or broken OpenSSL versions */
    +#include "openbsd-compat/openssl-compat.h"
    +
     #include 
     #include 
     #include 
    @@ -184,7 +187,11 @@ key_save_private_pem(Key *key, const char *filename, const char *_passphrase,
     	int success = 0;
     	int len = strlen(_passphrase);
     	u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
    +#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
     	const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
    +#else
    +	const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
    +#endif
     
     	if (len > 0 && len <= 4) {
     		error("passphrase too short: have %d bytes, need > 4", len);
    @@ -552,8 +559,13 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
     	int fd;
     
     	fd = open(filename, O_RDONLY);
    -	if (fd < 0)
    +	if (fd < 0) {
    +		debug("could not open key file '%s': %s", filename,
    +		    strerror(errno));
    +		if (perm_ok != NULL)
    +			*perm_ok = 0;
     		return NULL;
    +	}
     	if (!key_perm_ok(fd, filename)) {
     		if (perm_ok != NULL)
     			*perm_ok = 0;
    @@ -588,8 +600,11 @@ key_load_private(const char *filename, const char *passphrase,
     	int fd;
     
     	fd = open(filename, O_RDONLY);
    -	if (fd < 0)
    +	if (fd < 0) {
    +		debug("could not open key file '%s': %s", filename,
    +		    strerror(errno));
     		return NULL;
    +	}
     	if (!key_perm_ok(fd, filename)) {
     		error("bad permissions: ignore key: %s", filename);
     		close(fd);
    @@ -677,3 +692,65 @@ key_load_public(const char *filename, char **commentp)
     	key_free(pub);
     	return NULL;
     }
    +
    +/*
    + * Returns 1 if the specified "key" is listed in the file "filename",
    + * 0 if the key is not listed or -1 on error.
    + * If strict_type is set then the key type must match exactly,
    + * otherwise a comparison that ignores certficiate data is performed.
    + */
    +int
    +key_in_file(Key *key, const char *filename, int strict_type)
    +{
    +	FILE *f;
    +	char line[SSH_MAX_PUBKEY_BYTES];
    +	char *cp;
    +	u_long linenum = 0;
    +	int ret = 0;
    +	Key *pub;
    +	int (*key_compare)(const Key *, const Key *) = strict_type ?
    +	    key_equal : key_equal_public;
    +
    +	if ((f = fopen(filename, "r")) == NULL) {
    +		if (errno == ENOENT) {
    +			debug("%s: keyfile \"%s\" missing", __func__, filename);
    +			return 0;
    +		} else {
    +			error("%s: could not open keyfile \"%s\": %s", __func__,
    +			    filename, strerror(errno));
    +			return -1;
    +		}
    +	}
    +
    +	while (read_keyfile_line(f, filename, line, sizeof(line),
    +		    &linenum) != -1) {
    +		cp = line;
    +
    +		/* Skip leading whitespace. */
    +		for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
    +			;
    +
    +		/* Skip comments and empty lines */
    +		switch (*cp) {
    +		case '#':
    +		case '\n':
    +		case '\0':
    +			continue;
    +		}
    +
    +		pub = key_new(KEY_UNSPEC);
    +		if (key_read(pub, &cp) != 1) {
    +			key_free(pub);
    +			continue;
    +		}
    +		if (key_compare(key, pub)) {
    +			ret = 1;
    +			key_free(pub);
    +			break;
    +		}
    +		key_free(pub);
    +	}
    +	fclose(f);
    +	return ret;
    +}
    +
    diff --git a/crypto/openssh/authfile.h b/crypto/openssh/authfile.h
    index a6c74934d69..6dfa478e76e 100644
    --- a/crypto/openssh/authfile.h
    +++ b/crypto/openssh/authfile.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: authfile.h,v 1.13 2006/04/25 08:02:27 dtucker Exp $ */
    +/* $OpenBSD: authfile.h,v 1.14 2010/03/04 10:36:03 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -22,5 +22,6 @@ Key	*key_load_private(const char *, const char *, char **);
     Key	*key_load_private_type(int, const char *, const char *, char **, int *);
     Key	*key_load_private_pem(int, int, const char *, char **);
     int	 key_perm_ok(int, const char *);
    +int	 key_in_file(Key *, const char *, int);
     
     #endif
    diff --git a/crypto/openssh/bufaux.c b/crypto/openssh/bufaux.c
    index cd9a35dedc5..4ef19c454b1 100644
    --- a/crypto/openssh/bufaux.c
    +++ b/crypto/openssh/bufaux.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: bufaux.c,v 1.46 2008/06/10 23:21:34 dtucker Exp $ */
    +/* $OpenBSD: bufaux.c,v 1.48 2010/02/02 22:49:34 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -166,7 +166,10 @@ buffer_get_string_ret(Buffer *buffer, u_int *length_ptr)
     	u_int len;
     
     	/* Get the length. */
    -	len = buffer_get_int(buffer);
    +	if (buffer_get_int_ret(&len, buffer) != 0) {
    +		error("buffer_get_string_ret: cannot extract length");
    +		return (NULL);
    +	}
     	if (len > 256 * 1024) {
     		error("buffer_get_string_ret: bad string length %u", len);
     		return (NULL);
    @@ -198,14 +201,17 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr)
     }
     
     void *
    -buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)
    +buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr)
     {
     	void *ptr;
     	u_int len;
     
    -	len = buffer_get_int(buffer);
    -	if (len > 256 * 1024)
    -		fatal("buffer_get_string_ptr: bad string length %u", len);
    +	if (buffer_get_int_ret(&len, buffer) != 0)
    +		return NULL;
    +	if (len > 256 * 1024) {
    +		error("buffer_get_string_ptr: bad string length %u", len);
    +		return NULL;
    +	}
     	ptr = buffer_ptr(buffer);
     	buffer_consume(buffer, len);
     	if (length_ptr)
    @@ -213,6 +219,16 @@ buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)
     	return (ptr);
     }
     
    +void *
    +buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)
    +{
    +	void *ret;
    +
    +	if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL)
    +		fatal("buffer_get_string_ptr: buffer error");
    +	return (ret);
    +}
    +
     /*
      * Stores and arbitrary binary string in the buffer.
      */
    diff --git a/crypto/openssh/buffer.c b/crypto/openssh/buffer.c
    index e02e1e35c99..ae9700344d2 100644
    --- a/crypto/openssh/buffer.c
    +++ b/crypto/openssh/buffer.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: buffer.c,v 1.31 2006/08/03 03:34:41 deraadt Exp $ */
    +/* $OpenBSD: buffer.c,v 1.32 2010/02/09 03:56:28 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -160,7 +160,7 @@ buffer_check_alloc(Buffer *buffer, u_int len)
     /* Returns the number of bytes of data in the buffer. */
     
     u_int
    -buffer_len(Buffer *buffer)
    +buffer_len(const Buffer *buffer)
     {
     	return buffer->end - buffer->offset;
     }
    @@ -228,7 +228,7 @@ buffer_consume_end(Buffer *buffer, u_int bytes)
     /* Returns a pointer to the first used byte in the buffer. */
     
     void *
    -buffer_ptr(Buffer *buffer)
    +buffer_ptr(const Buffer *buffer)
     {
     	return buffer->buf + buffer->offset;
     }
    @@ -236,7 +236,7 @@ buffer_ptr(Buffer *buffer)
     /* Dumps the contents of the buffer to stderr. */
     
     void
    -buffer_dump(Buffer *buffer)
    +buffer_dump(const Buffer *buffer)
     {
     	u_int i;
     	u_char *ucp = buffer->buf;
    diff --git a/crypto/openssh/buffer.h b/crypto/openssh/buffer.h
    index d0f354ee7bf..4ef4f80b35a 100644
    --- a/crypto/openssh/buffer.h
    +++ b/crypto/openssh/buffer.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: buffer.h,v 1.17 2008/05/08 06:59:01 markus Exp $ */
    +/* $OpenBSD: buffer.h,v 1.19 2010/02/09 03:56:28 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -27,8 +27,8 @@ void	 buffer_init(Buffer *);
     void	 buffer_clear(Buffer *);
     void	 buffer_free(Buffer *);
     
    -u_int	 buffer_len(Buffer *);
    -void	*buffer_ptr(Buffer *);
    +u_int	 buffer_len(const Buffer *);
    +void	*buffer_ptr(const Buffer *);
     
     void	 buffer_append(Buffer *, const void *, u_int);
     void	*buffer_append_space(Buffer *, u_int);
    @@ -40,7 +40,7 @@ void	 buffer_get(Buffer *, void *, u_int);
     void	 buffer_consume(Buffer *, u_int);
     void	 buffer_consume_end(Buffer *, u_int);
     
    -void     buffer_dump(Buffer *);
    +void     buffer_dump(const Buffer *);
     
     int	 buffer_get_ret(Buffer *, void *, u_int);
     int	 buffer_consume_ret(Buffer *, u_int);
    @@ -81,6 +81,7 @@ int	buffer_get_short_ret(u_short *, Buffer *);
     int	buffer_get_int_ret(u_int *, Buffer *);
     int	buffer_get_int64_ret(u_int64_t *, Buffer *);
     void	*buffer_get_string_ret(Buffer *, u_int *);
    +void	*buffer_get_string_ptr_ret(Buffer *, u_int *);
     int	buffer_get_char_ret(char *, Buffer *);
     
     #endif				/* BUFFER_H */
    diff --git a/crypto/openssh/canohost.c b/crypto/openssh/canohost.c
    index 7138f48d0f4..ef94d9155ea 100644
    --- a/crypto/openssh/canohost.c
    +++ b/crypto/openssh/canohost.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: canohost.c,v 1.64 2009/02/12 03:00:56 djm Exp $ */
    +/* $OpenBSD: canohost.c,v 1.66 2010/01/13 01:20:20 dtucker Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -27,6 +27,7 @@
     #include 
     #include 
     #include 
    +#include 
     
     #include "xmalloc.h"
     #include "packet.h"
    @@ -35,6 +36,8 @@
     #include "misc.h"
     
     static void check_ip_options(int, char *);
    +static char *canonical_host_ip = NULL;
    +static int cached_port = -1;
     
     /*
      * Return the canonical name of the host at the other end of the socket. The
    @@ -299,9 +302,32 @@ get_local_ipaddr(int sock)
     }
     
     char *
    -get_local_name(int sock)
    +get_local_name(int fd)
     {
    -	return get_socket_address(sock, 0, NI_NAMEREQD);
    +	char *host, myname[NI_MAXHOST];
    +
    +	/* Assume we were passed a socket */
    +	if ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL)
    +		return host;
    +
    +	/* Handle the case where we were passed a pipe */
    +	if (gethostname(myname, sizeof(myname)) == -1) {
    +		verbose("get_local_name: gethostname: %s", strerror(errno));
    +	} else {
    +		host = xstrdup(myname);
    +	}
    +
    +	return host;
    +}
    +
    +void
    +clear_cached_addr(void)
    +{
    +	if (canonical_host_ip != NULL) {
    +		xfree(canonical_host_ip);
    +		canonical_host_ip = NULL;
    +	}
    +	cached_port = -1;
     }
     
     /*
    @@ -312,8 +338,6 @@ get_local_name(int sock)
     const char *
     get_remote_ipaddr(void)
     {
    -	static char *canonical_host_ip = NULL;
    -
     	/* Check whether we have cached the ipaddr. */
     	if (canonical_host_ip == NULL) {
     		if (packet_connection_is_on_socket()) {
    @@ -402,13 +426,11 @@ get_peer_port(int sock)
     int
     get_remote_port(void)
     {
    -	static int port = -1;
    -
     	/* Cache to avoid getpeername() on a dead connection */
    -	if (port == -1)
    -		port = get_port(0);
    +	if (cached_port == -1)
    +		cached_port = get_port(0);
     
    -	return port;
    +	return cached_port;
     }
     
     int
    diff --git a/crypto/openssh/canohost.h b/crypto/openssh/canohost.h
    index d9b41ffe544..4c8636f42dd 100644
    --- a/crypto/openssh/canohost.h
    +++ b/crypto/openssh/canohost.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: canohost.h,v 1.10 2009/02/12 03:00:56 djm Exp $ */
    +/* $OpenBSD: canohost.h,v 1.11 2009/05/27 06:31:25 andreas Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -24,6 +24,6 @@ char		*get_local_name(int);
     int		 get_remote_port(void);
     int		 get_local_port(void);
     int		 get_sock_port(int, int);
    -
    +void		 clear_cached_addr(void);
     
     void		 ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
    diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c
    index dea60ba24e7..d8c53a4a8f2 100644
    --- a/crypto/openssh/channels.c
    +++ b/crypto/openssh/channels.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: channels.c,v 1.295 2009/02/12 03:00:56 djm Exp $ */
    +/* $OpenBSD: channels.c,v 1.303 2010/01/30 21:12:08 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -53,6 +53,7 @@
     #include 
     
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -228,12 +229,16 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
     	channel_max_fd = MAX(channel_max_fd, wfd);
     	channel_max_fd = MAX(channel_max_fd, efd);
     
    -	/* XXX set close-on-exec -markus */
    +	if (rfd != -1)
    +		fcntl(rfd, F_SETFD, FD_CLOEXEC);
    +	if (wfd != -1 && wfd != rfd)
    +		fcntl(wfd, F_SETFD, FD_CLOEXEC);
    +	if (efd != -1 && efd != rfd && efd != wfd)
    +		fcntl(efd, F_SETFD, FD_CLOEXEC);
     
     	c->rfd = rfd;
     	c->wfd = wfd;
     	c->sock = (rfd == wfd) ? rfd : -1;
    -	c->ctl_fd = -1; /* XXX: set elsewhere */
     	c->efd = efd;
     	c->extended_usage = extusage;
     
    @@ -322,6 +327,10 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
     	c->output_filter = NULL;
     	c->filter_ctx = NULL;
     	c->filter_cleanup = NULL;
    +	c->ctl_chan = -1;
    +	c->mux_rcb = NULL;
    +	c->mux_ctx = NULL;
    +	c->delayed = 1;		/* prevent call to channel_post handler */
     	TAILQ_INIT(&c->status_confirms);
     	debug("channel %d: new [%s]", found, remote_name);
     	return c;
    @@ -363,11 +372,10 @@ channel_close_fd(int *fdp)
     static void
     channel_close_fds(Channel *c)
     {
    -	debug3("channel %d: close_fds r %d w %d e %d c %d",
    -	    c->self, c->rfd, c->wfd, c->efd, c->ctl_fd);
    +	debug3("channel %d: close_fds r %d w %d e %d",
    +	    c->self, c->rfd, c->wfd, c->efd);
     
     	channel_close_fd(&c->sock);
    -	channel_close_fd(&c->ctl_fd);
     	channel_close_fd(&c->rfd);
     	channel_close_fd(&c->wfd);
     	channel_close_fd(&c->efd);
    @@ -393,8 +401,6 @@ channel_free(Channel *c)
     
     	if (c->sock != -1)
     		shutdown(c->sock, SHUT_RDWR);
    -	if (c->ctl_fd != -1)
    -		shutdown(c->ctl_fd, SHUT_RDWR);
     	channel_close_fds(c);
     	buffer_free(&c->input);
     	buffer_free(&c->output);
    @@ -516,6 +522,7 @@ channel_still_open(void)
     		case SSH_CHANNEL_X11_LISTENER:
     		case SSH_CHANNEL_PORT_LISTENER:
     		case SSH_CHANNEL_RPORT_LISTENER:
    +		case SSH_CHANNEL_MUX_LISTENER:
     		case SSH_CHANNEL_CLOSED:
     		case SSH_CHANNEL_AUTH_SOCKET:
     		case SSH_CHANNEL_DYNAMIC:
    @@ -529,6 +536,7 @@ channel_still_open(void)
     		case SSH_CHANNEL_OPENING:
     		case SSH_CHANNEL_OPEN:
     		case SSH_CHANNEL_X11_OPEN:
    +		case SSH_CHANNEL_MUX_CLIENT:
     			return 1;
     		case SSH_CHANNEL_INPUT_DRAINING:
     		case SSH_CHANNEL_OUTPUT_DRAINING:
    @@ -560,6 +568,8 @@ channel_find_open(void)
     		case SSH_CHANNEL_X11_LISTENER:
     		case SSH_CHANNEL_PORT_LISTENER:
     		case SSH_CHANNEL_RPORT_LISTENER:
    +		case SSH_CHANNEL_MUX_LISTENER:
    +		case SSH_CHANNEL_MUX_CLIENT:
     		case SSH_CHANNEL_OPENING:
     		case SSH_CHANNEL_CONNECTING:
     		case SSH_CHANNEL_ZOMBIE:
    @@ -610,6 +620,8 @@ channel_open_message(void)
     		case SSH_CHANNEL_CLOSED:
     		case SSH_CHANNEL_AUTH_SOCKET:
     		case SSH_CHANNEL_ZOMBIE:
    +		case SSH_CHANNEL_MUX_CLIENT:
    +		case SSH_CHANNEL_MUX_LISTENER:
     			continue;
     		case SSH_CHANNEL_LARVAL:
     		case SSH_CHANNEL_OPENING:
    @@ -620,12 +632,12 @@ channel_open_message(void)
     		case SSH_CHANNEL_INPUT_DRAINING:
     		case SSH_CHANNEL_OUTPUT_DRAINING:
     			snprintf(buf, sizeof buf,
    -			    "  #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cfd %d)\r\n",
    +			    "  #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cc %d)\r\n",
     			    c->self, c->remote_name,
     			    c->type, c->remote_id,
     			    c->istate, buffer_len(&c->input),
     			    c->ostate, buffer_len(&c->output),
    -			    c->rfd, c->wfd, c->ctl_fd);
    +			    c->rfd, c->wfd, c->ctl_chan);
     			buffer_append(&buffer, buf, strlen(buf));
     			continue;
     		default:
    @@ -832,9 +844,6 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
     			FD_SET(c->efd, readset);
     	}
     	/* XXX: What about efd? races? */
    -	if (compat20 && c->ctl_fd != -1 &&
    -	    c->istate == CHAN_INPUT_OPEN && c->ostate == CHAN_OUTPUT_OPEN)
    -		FD_SET(c->ctl_fd, readset);
     }
     
     /* ARGSUSED */
    @@ -979,6 +988,28 @@ channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
     	}
     }
     
    +static void
    +channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
    +{
    +	if (c->istate == CHAN_INPUT_OPEN &&
    +	    buffer_check_alloc(&c->input, CHAN_RBUF))
    +		FD_SET(c->rfd, readset);
    +	if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
    +		/* clear buffer immediately (discard any partial packet) */
    +		buffer_clear(&c->input);
    +		chan_ibuf_empty(c);
    +		/* Start output drain. XXX just kill chan? */
    +		chan_rcvd_oclose(c);
    +	}
    +	if (c->ostate == CHAN_OUTPUT_OPEN ||
    +	    c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
    +		if (buffer_len(&c->output) > 0)
    +			FD_SET(c->wfd, writeset);
    +		else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN)
    +			chan_obuf_empty(c);
    +	}
    +}
    +
     /* try to decode a socks4 header */
     /* ARGSUSED */
     static int
    @@ -1210,6 +1241,30 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
     	return 1;
     }
     
    +Channel *
    +channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect,
    +    int in, int out)
    +{
    +	Channel *c;
    +
    +	debug("channel_connect_stdio_fwd %s:%d", host_to_connect,
    +	    port_to_connect);
    +
    +	c = channel_new("stdio-forward", SSH_CHANNEL_OPENING, in, out,
    +	    -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
    +	    0, "stdio-forward", /*nonblock*/0);
    +
    +	c->path = xstrdup(host_to_connect);
    +	c->host_port = port_to_connect;
    +	c->listening_port = 0;
    +	c->force_drain = 1;
    +
    +	channel_register_fds(c, in, out, -1, 0, 1, 0);
    +	port_open_helper(c, "direct-tcpip");
    +
    +	return c;
    +}
    +
     /* dynamic port forwarding */
     static void
     channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
    @@ -1219,7 +1274,6 @@ channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
     	int ret;
     
     	have = buffer_len(&c->input);
    -	c->delayed = 0;
     	debug2("channel %d: pre_dynamic: have %d", c->self, have);
     	/* buffer_dump(&c->input); */
     	/* check if the fixed size part of the packet is in buffer. */
    @@ -1322,6 +1376,13 @@ port_open_helper(Channel *c, char *rtype)
     	char *remote_ipaddr = get_peer_ipaddr(c->sock);
     	int remote_port = get_peer_port(c->sock);
     
    +	if (remote_port == -1) {
    +		/* Fake addr/port to appease peers that validate it (Tectia) */
    +		xfree(remote_ipaddr);
    +		remote_ipaddr = xstrdup("127.0.0.1");
    +		remote_port = 65535;
    +	}
    +
     	direct = (strcmp(rtype, "direct-tcpip") == 0);
     
     	snprintf(buf, sizeof buf,
    @@ -1423,16 +1484,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
     		if (c->path != NULL)
     			nc->path = xstrdup(c->path);
     
    -		if (nextstate == SSH_CHANNEL_DYNAMIC) {
    -			/*
    -			 * do not call the channel_post handler until
    -			 * this flag has been reset by a pre-handler.
    -			 * otherwise the FD_ISSET calls might overflow
    -			 */
    -			nc->delayed = 1;
    -		} else {
    +		if (nextstate != SSH_CHANNEL_DYNAMIC)
     			port_open_helper(nc, rtype);
    -		}
     	}
     }
     
    @@ -1653,6 +1706,7 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
     			}
     			return -1;
     		}
    +#ifndef BROKEN_TCGETATTR_ICANON
     		if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
     			if (tcgetattr(c->wfd, &tio) == 0 &&
     			    !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
    @@ -1666,6 +1720,7 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
     				packet_send();
     			}
     		}
    +#endif
     		buffer_consume(&c->output, len);
     		if (compat20 && len > 0) {
     			c->local_consumed += len;
    @@ -1720,36 +1775,6 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
     	return 1;
     }
     
    -/* ARGSUSED */
    -static int
    -channel_handle_ctl(Channel *c, fd_set *readset, fd_set *writeset)
    -{
    -	char buf[16];
    -	int len;
    -
    -	/* Monitor control fd to detect if the slave client exits */
    -	if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) {
    -		len = read(c->ctl_fd, buf, sizeof(buf));
    -		if (len < 0 &&
    -		    (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
    -			return 1;
    -		if (len <= 0) {
    -			debug2("channel %d: ctl read<=0", c->self);
    -			if (c->type != SSH_CHANNEL_OPEN) {
    -				debug2("channel %d: not open", c->self);
    -				chan_mark_dead(c);
    -				return -1;
    -			} else {
    -				chan_read_failed(c);
    -				chan_write_failed(c);
    -			}
    -			return -1;
    -		} else
    -			fatal("%s: unexpected data on ctl fd", __func__);
    -	}
    -	return 1;
    -}
    -
     static int
     channel_check_window(Channel *c)
     {
    @@ -1775,17 +1800,136 @@ channel_check_window(Channel *c)
     static void
     channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
     {
    -	if (c->delayed)
    -		return;
     	channel_handle_rfd(c, readset, writeset);
     	channel_handle_wfd(c, readset, writeset);
     	if (!compat20)
     		return;
     	channel_handle_efd(c, readset, writeset);
    -	channel_handle_ctl(c, readset, writeset);
     	channel_check_window(c);
     }
     
    +static u_int
    +read_mux(Channel *c, u_int need)
    +{
    +	char buf[CHAN_RBUF];
    +	int len;
    +	u_int rlen;
    +
    +	if (buffer_len(&c->input) < need) {
    +		rlen = need - buffer_len(&c->input);
    +		len = read(c->rfd, buf, MIN(rlen, CHAN_RBUF));
    +		if (len <= 0) {
    +			if (errno != EINTR && errno != EAGAIN) {
    +				debug2("channel %d: ctl read<=0 rfd %d len %d",
    +				    c->self, c->rfd, len);
    +				chan_read_failed(c);
    +				return 0;
    +			}
    +		} else
    +			buffer_append(&c->input, buf, len);
    +	}
    +	return buffer_len(&c->input);
    +}
    +
    +static void
    +channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
    +{
    +	u_int need;
    +	ssize_t len;
    +
    +	if (!compat20)
    +		fatal("%s: entered with !compat20", __func__);
    +
    +	if (c->rfd != -1 && FD_ISSET(c->rfd, readset) &&
    +	    (c->istate == CHAN_INPUT_OPEN ||
    +	    c->istate == CHAN_INPUT_WAIT_DRAIN)) {
    +		/*
    +		 * Don't not read past the precise end of packets to
    +		 * avoid disrupting fd passing.
    +		 */
    +		if (read_mux(c, 4) < 4) /* read header */
    +			return;
    +		need = get_u32(buffer_ptr(&c->input));
    +#define CHANNEL_MUX_MAX_PACKET	(256 * 1024)
    +		if (need > CHANNEL_MUX_MAX_PACKET) {
    +			debug2("channel %d: packet too big %u > %u",
    +			    c->self, CHANNEL_MUX_MAX_PACKET, need);
    +			chan_rcvd_oclose(c);
    +			return;
    +		}
    +		if (read_mux(c, need + 4) < need + 4) /* read body */
    +			return;
    +		if (c->mux_rcb(c) != 0) {
    +			debug("channel %d: mux_rcb failed", c->self);
    +			chan_mark_dead(c);
    +			return;
    +		}
    +	}
    +
    +	if (c->wfd != -1 && FD_ISSET(c->wfd, writeset) &&
    +	    buffer_len(&c->output) > 0) {
    +		len = write(c->wfd, buffer_ptr(&c->output),
    +		    buffer_len(&c->output));
    +		if (len < 0 && (errno == EINTR || errno == EAGAIN))
    +			return;
    +		if (len <= 0) {
    +			chan_mark_dead(c);
    +			return;
    +		}
    +		buffer_consume(&c->output, len);
    +	}
    +}
    +
    +static void
    +channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
    +{
    +	Channel *nc;
    +	struct sockaddr_storage addr;
    +	socklen_t addrlen;
    +	int newsock;
    +	uid_t euid;
    +	gid_t egid;
    +
    +	if (!FD_ISSET(c->sock, readset))
    +		return;
    +
    +	debug("multiplexing control connection");
    +
    +	/*
    +	 * Accept connection on control socket
    +	 */
    +	memset(&addr, 0, sizeof(addr));
    +	addrlen = sizeof(addr);
    +	if ((newsock = accept(c->sock, (struct sockaddr*)&addr,
    +	    &addrlen)) == -1) {
    +		error("%s accept: %s", __func__, strerror(errno));
    +		return;
    +	}
    +
    +	if (getpeereid(newsock, &euid, &egid) < 0) {
    +		error("%s getpeereid failed: %s", __func__,
    +		    strerror(errno));
    +		close(newsock);
    +		return;
    +	}
    +	if ((euid != 0) && (getuid() != euid)) {
    +		error("multiplex uid mismatch: peer euid %u != uid %u",
    +		    (u_int)euid, (u_int)getuid());
    +		close(newsock);
    +		return;
    +	}
    +	nc = channel_new("multiplex client", SSH_CHANNEL_MUX_CLIENT,
    +	    newsock, newsock, -1, c->local_window_max,
    +	    c->local_maxpacket, 0, "mux-control", 1);
    +	nc->mux_rcb = c->mux_rcb;
    +	debug3("%s: new mux channel %d fd %d", __func__,
    +	    nc->self, nc->sock);
    +	/* establish state */
    +	nc->mux_rcb(nc);
    +	/* mux state transitions must not elicit protocol messages */
    +	nc->flags |= CHAN_LOCAL;
    +}
    +
     /* ARGSUSED */
     static void
     channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset)
    @@ -1814,6 +1958,8 @@ channel_handler_init_20(void)
     	channel_pre[SSH_CHANNEL_AUTH_SOCKET] =		&channel_pre_listener;
     	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
     	channel_pre[SSH_CHANNEL_DYNAMIC] =		&channel_pre_dynamic;
    +	channel_pre[SSH_CHANNEL_MUX_LISTENER] =		&channel_pre_listener;
    +	channel_pre[SSH_CHANNEL_MUX_CLIENT] =		&channel_pre_mux_client;
     
     	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open;
     	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
    @@ -1822,6 +1968,8 @@ channel_handler_init_20(void)
     	channel_post[SSH_CHANNEL_AUTH_SOCKET] =		&channel_post_auth_listener;
     	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
     	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
    +	channel_post[SSH_CHANNEL_MUX_LISTENER] =	&channel_post_mux_listener;
    +	channel_post[SSH_CHANNEL_MUX_CLIENT] =		&channel_post_mux_client;
     }
     
     static void
    @@ -1908,17 +2056,23 @@ static void
     channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
     {
     	static int did_init = 0;
    -	u_int i;
    +	u_int i, oalloc;
     	Channel *c;
     
     	if (!did_init) {
     		channel_handler_init();
     		did_init = 1;
     	}
    -	for (i = 0; i < channels_alloc; i++) {
    +	for (i = 0, oalloc = channels_alloc; i < oalloc; i++) {
     		c = channels[i];
     		if (c == NULL)
     			continue;
    +		if (c->delayed) {
    +			if (ftab == channel_pre)
    +				c->delayed = 0;
    +			else
    +				continue;
    +		}
     		if (ftab[c->type] != NULL)
     			(*ftab[c->type])(c, readset, writeset);
     		channel_garbage_collect(c);
    @@ -2431,7 +2585,7 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
     	int id;
     
     	/* Reset keepalive timeout */
    -	keep_alive_timeouts = 0;
    +	packet_set_alive_timeouts(0);
     
     	id = packet_get_int();
     	packet_check_eom();
    @@ -2575,6 +2729,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr,
     		}
     
     		channel_set_reuseaddr(sock);
    +		if (ai->ai_family == AF_INET6)
    +			sock_set_v6only(sock);
     
     		debug("Local forwarding listening on %s port %s.",
     		    ntop, strport);
    @@ -3106,13 +3262,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
     					continue;
     				}
     			}
    -#ifdef IPV6_V6ONLY
    -			if (ai->ai_family == AF_INET6) {
    -				int on = 1;
    -				if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
    -					error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno));
    -			}
    -#endif
    +			if (ai->ai_family == AF_INET6)
    +				sock_set_v6only(sock);
     			if (x11_use_localhost)
     				channel_set_reuseaddr(sock);
     			if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
    diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h
    index 1488ed7e59a..cc71885f494 100644
    --- a/crypto/openssh/channels.h
    +++ b/crypto/openssh/channels.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: channels.h,v 1.98 2009/02/12 03:00:56 djm Exp $ */
    +/* $OpenBSD: channels.h,v 1.103 2010/01/26 01:28:35 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -53,7 +53,9 @@
     #define SSH_CHANNEL_CONNECTING		12
     #define SSH_CHANNEL_DYNAMIC		13
     #define SSH_CHANNEL_ZOMBIE		14	/* Almost dead. */
    -#define SSH_CHANNEL_MAX_TYPE		15
    +#define SSH_CHANNEL_MUX_LISTENER	15	/* Listener for mux conn. */
    +#define SSH_CHANNEL_MUX_CLIENT		16	/* Conn. to mux slave */
    +#define SSH_CHANNEL_MAX_TYPE		17
     
     struct Channel;
     typedef struct Channel Channel;
    @@ -81,6 +83,9 @@ struct channel_connect {
     	struct addrinfo *ai, *aitop;
     };
     
    +/* Callbacks for mux channels back into client-specific code */
    +typedef int mux_callback_fn(struct Channel *);
    +
     struct Channel {
     	int     type;		/* channel type/state */
     	int     self;		/* my own channel identifier */
    @@ -92,12 +97,16 @@ struct Channel {
     	int     wfd;		/* write fd */
     	int     efd;		/* extended fd */
     	int     sock;		/* sock fd */
    -	int     ctl_fd;		/* control fd (client sharing) */
    +	int     ctl_chan;	/* control channel (multiplexed connections) */
     	int     isatty;		/* rfd is a tty */
     	int     wfd_isatty;	/* wfd is a tty */
     	int	client_tty;	/* (client) TTY has been requested */
     	int     force_drain;	/* force close on iEOF */
    -	int     delayed;		/* fdset hack */
    +	int     delayed;	/* post-select handlers for newly created
    +				 * channels are delayed until the first call
    +				 * to a matching pre-select handler. 
    +				 * this way post-select handlers are not
    +				 * accidenly called if a FD gets reused */
     	Buffer  input;		/* data read from socket, to be sent over
     				 * encrypted connection */
     	Buffer  output;		/* data received over encrypted connection for
    @@ -138,6 +147,10 @@ struct Channel {
     
     	/* non-blocking connect */
     	struct channel_connect	connect_ctx;
    +
    +	/* multiplexing protocol hook, called for each packet received */
    +	mux_callback_fn		*mux_rcb;
    +	void			*mux_ctx;
     };
     
     #define CHAN_EXTENDED_IGNORE		0
    @@ -168,6 +181,7 @@ struct Channel {
     #define CHAN_CLOSE_RCVD			0x02
     #define CHAN_EOF_SENT			0x04
     #define CHAN_EOF_RCVD			0x08
    +#define CHAN_LOCAL			0x10
     
     #define CHAN_RBUF	16*1024
     
    @@ -239,6 +253,7 @@ void	 channel_clear_adm_permitted_opens(void);
     void 	 channel_print_adm_permitted_opens(void);
     int      channel_input_port_forward_request(int, int);
     Channel	*channel_connect_to(const char *, u_short, char *, char *);
    +Channel	*channel_connect_stdio_fwd(const char*, u_short, int, int);
     Channel	*channel_connect_by_listen_address(u_short, char *, char *);
     int	 channel_request_remote_forwarding(const char *, u_short,
     	     const char *, u_short);
    diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c
    index a2d2d1d0746..6ffef95a2d7 100644
    --- a/crypto/openssh/clientloop.c
    +++ b/crypto/openssh/clientloop.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: clientloop.c,v 1.209 2009/02/12 03:00:56 djm Exp $ */
    +/* $OpenBSD: clientloop.c,v 1.218 2010/01/28 00:21:18 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -109,6 +109,7 @@
     #include "misc.h"
     #include "match.h"
     #include "msg.h"
    +#include "roaming.h"
     
     /* import options */
     extern Options options;
    @@ -120,7 +121,7 @@ extern int stdin_null_flag;
     extern int no_shell_flag;
     
     /* Control socket */
    -extern int muxserver_sock;
    +extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
     
     /*
      * Name of the host we are connecting to.  This is the name given on the
    @@ -129,6 +130,9 @@ extern int muxserver_sock;
      */
     extern char *host;
     
    +/* Force TTY allocation */
    +extern int force_tty_flag;
    +
     /*
      * Flag to indicate that we have received a window change signal which has
      * not yet been processed.  This will cause a message indicating the new
    @@ -142,7 +146,7 @@ static volatile sig_atomic_t received_signal = 0;
     static int in_non_blocking_mode = 0;
     
     /* Common data for the client loop code. */
    -static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
    +volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
     static int escape_char1;	/* Escape character. (proto1 only) */
     static int escape_pending1;	/* Last character was an escape (proto1 only) */
     static int last_was_cr;		/* Last character was a newline. */
    @@ -160,6 +164,8 @@ static int session_closed = 0;	/* In SSH2: login session closed. */
     static void client_init_dispatch(void);
     int	session_ident = -1;
     
    +int	session_resumed = 0;
    +
     /* Track escape per proto2 channel */
     struct escape_filter_ctx {
     	int escape_pending;
    @@ -491,13 +497,13 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt)
     		xfree(gc);
     	}
     
    -	keep_alive_timeouts = 0;
    +	packet_set_alive_timeouts(0);
     }
     
     static void
     server_alive_check(void)
     {
    -	if (++keep_alive_timeouts > options.server_alive_count_max) {
    +	if (packet_inc_alive_timeouts() > options.server_alive_count_max) {
     		logit("Timeout, server not responding.");
     		cleanup_exit(255);
     	}
    @@ -558,9 +564,6 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
     	if (packet_have_data_to_write())
     		FD_SET(connection_out, *writesetp);
     
    -	if (muxserver_sock != -1)
    -		FD_SET(muxserver_sock, *readsetp);
    -
     	/*
     	 * Wait for something to happen.  This will suspend the process until
     	 * some selected descriptor can be read, written, or has some other
    @@ -607,7 +610,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
     		atomicio(vwrite, fileno(stderr), buffer_ptr(berr),
     		    buffer_len(berr));
     
    -	leave_raw_mode();
    +	leave_raw_mode(force_tty_flag);
     
     	/*
     	 * Free (and clear) the buffer to reduce the amount of data that gets
    @@ -628,14 +631,14 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
     	buffer_init(bout);
     	buffer_init(berr);
     
    -	enter_raw_mode();
    +	enter_raw_mode(force_tty_flag);
     }
     
     static void
     client_process_net_input(fd_set *readset)
     {
    -	int len;
    -	char buf[8192];
    +	int len, cont = 0;
    +	char buf[SSH_IOBUFSZ];
     
     	/*
     	 * Read input from the server, and add any such data to the buffer of
    @@ -643,8 +646,8 @@ client_process_net_input(fd_set *readset)
     	 */
     	if (FD_ISSET(connection_in, readset)) {
     		/* Read as much as possible. */
    -		len = read(connection_in, buf, sizeof(buf));
    -		if (len == 0) {
    +		len = roaming_read(connection_in, buf, sizeof(buf), &cont);
    +		if (len == 0 && cont == 0) {
     			/*
     			 * Received EOF.  The remote host has closed the
     			 * connection.
    @@ -689,7 +692,7 @@ client_status_confirm(int type, Channel *c, void *ctx)
     
     	/* XXX supress on mux _client_ quietmode */
     	tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
    -	    c->ctl_fd != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
    +	    c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
     
     	if (type == SSH2_MSG_CHANNEL_SUCCESS) {
     		debug2("%s request accepted on channel %d",
    @@ -771,7 +774,7 @@ process_cmdline(void)
     	bzero(&fwd, sizeof(fwd));
     	fwd.listen_host = fwd.connect_host = NULL;
     
    -	leave_raw_mode();
    +	leave_raw_mode(force_tty_flag);
     	handler = signal(SIGINT, SIG_IGN);
     	cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
     	if (s == NULL)
    @@ -833,6 +836,7 @@ process_cmdline(void)
     	while (isspace(*++s))
     		;
     
    +	/* XXX update list of forwards in options */
     	if (delete) {
     		cancel_port = 0;
     		cancel_host = hpdelim(&s);	/* may be NULL */
    @@ -874,7 +878,7 @@ process_cmdline(void)
     
     out:
     	signal(SIGINT, handler);
    -	enter_raw_mode();
    +	enter_raw_mode(force_tty_flag);
     	if (cmd)
     		xfree(cmd);
     	if (fwd.listen_host != NULL)
    @@ -930,7 +934,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
     				    escape_char);
     				buffer_append(berr, string, strlen(string));
     
    -				if (c && c->ctl_fd != -1) {
    +				if (c && c->ctl_chan != -1) {
     					chan_read_failed(c);
     					chan_write_failed(c);
     					return 0;
    @@ -940,7 +944,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
     
     			case 'Z' - 64:
     				/* XXX support this for mux clients */
    -				if (c && c->ctl_fd != -1) {
    +				if (c && c->ctl_chan != -1) {
      noescape:
     					snprintf(string, sizeof string,
     					    "%c%c escape not available to "
    @@ -985,7 +989,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
     				continue;
     
     			case '&':
    -				if (c && c->ctl_fd != -1)
    +				if (c && c->ctl_chan != -1)
     					goto noescape;
     				/*
     				 * Detach the program (continue to serve
    @@ -993,7 +997,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
     				 * more new connections).
     				 */
     				/* Restore tty modes. */
    -				leave_raw_mode();
    +				leave_raw_mode(force_tty_flag);
     
     				/* Stop listening for new connections. */
     				channel_stop_listening();
    @@ -1036,7 +1040,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
     				continue;
     
     			case '?':
    -				if (c && c->ctl_fd != -1) {
    +				if (c && c->ctl_chan != -1) {
     					snprintf(string, sizeof string,
     "%c?\r\n\
     Supported escape sequences:\r\n\
    @@ -1085,7 +1089,7 @@ Supported escape sequences:\r\n\
     				continue;
     
     			case 'C':
    -				if (c && c->ctl_fd != -1)
    +				if (c && c->ctl_chan != -1)
     					goto noescape;
     				process_cmdline();
     				continue;
    @@ -1128,7 +1132,7 @@ static void
     client_process_input(fd_set *readset)
     {
     	int len;
    -	char buf[8192];
    +	char buf[SSH_IOBUFSZ];
     
     	/* Read input from stdin. */
     	if (FD_ISSET(fileno(stdin), readset)) {
    @@ -1288,7 +1292,7 @@ client_channel_closed(int id, void *arg)
     {
     	channel_cancel_cleanup(id);
     	session_closed = 1;
    -	leave_raw_mode();
    +	leave_raw_mode(force_tty_flag);
     }
     
     /*
    @@ -1321,8 +1325,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
     	connection_in = packet_get_connection_in();
     	connection_out = packet_get_connection_out();
     	max_fd = MAX(connection_in, connection_out);
    -	if (muxserver_sock != -1)
    -		max_fd = MAX(max_fd, muxserver_sock);
     
     	if (!compat20) {
     		/* enable nonblocking unless tty */
    @@ -1361,7 +1363,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
     	signal(SIGWINCH, window_change_handler);
     
     	if (have_pty)
    -		enter_raw_mode();
    +		enter_raw_mode(force_tty_flag);
     
     	if (compat20) {
     		session_ident = ssh2_chan_id;
    @@ -1440,12 +1442,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
     		/* Buffer input from the connection.  */
     		client_process_net_input(readset);
     
    -		/* Accept control connections.  */
    -		if (muxserver_sock != -1 &&FD_ISSET(muxserver_sock, readset)) {
    -			if (muxserver_accept_control())
    -				quit_pending = 1;
    -		}
    -
     		if (quit_pending)
     			break;
     
    @@ -1459,6 +1455,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
     			client_process_output(writeset);
     		}
     
    +		if (session_resumed) {
    +			connection_in = packet_get_connection_in();
    +			connection_out = packet_get_connection_out();
    +			max_fd = MAX(max_fd, connection_out);
    +			max_fd = MAX(max_fd, connection_in);
    +			session_resumed = 0;
    +		}
    +
     		/*
     		 * Send as much buffered packet data as possible to the
     		 * sender.
    @@ -1476,10 +1480,18 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
     	/* Stop watching for window change. */
     	signal(SIGWINCH, SIG_DFL);
     
    +	if (compat20) {
    +		packet_start(SSH2_MSG_DISCONNECT);
    +		packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
    +		packet_put_cstring("disconnected by user");
    +		packet_send();
    +		packet_write_wait();
    +	}
    +
     	channel_free_all();
     
     	if (have_pty)
    -		leave_raw_mode();
    +		leave_raw_mode(force_tty_flag);
     
     	/* restore blocking io */
     	if (!isatty(fileno(stdin)))
    @@ -1837,15 +1849,17 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
     		chan_rcvd_eow(c);
     	} else if (strcmp(rtype, "exit-status") == 0) {
     		exitval = packet_get_int();
    -		if (id == session_ident) {
    +		if (c->ctl_chan != -1) {
    +			mux_exit_message(c, exitval);
    +			success = 1;
    +		} else if (id == session_ident) {
    +			/* Record exit value of local session */
     			success = 1;
     			exit_status = exitval;
    -		} else if (c->ctl_fd == -1) {
    -			error("client_input_channel_req: unexpected channel %d",
    -			    session_ident);
     		} else {
    -			atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval));
    -			success = 1;
    +			/* Probably for a mux channel that has already closed */
    +			debug("%s: no sink for exit-status on channel %d",
    +			    __func__, id);
     		}
     		packet_check_eom();
     	}
    @@ -2041,7 +2055,7 @@ client_init_dispatch(void)
     void
     cleanup_exit(int i)
     {
    -	leave_raw_mode();
    +	leave_raw_mode(force_tty_flag);
     	leave_non_blocking();
     	if (options.control_path != NULL && muxserver_sock != -1)
     		unlink(options.control_path);
    diff --git a/crypto/openssh/clientloop.h b/crypto/openssh/clientloop.h
    index 8bb874b3882..0b8257b996c 100644
    --- a/crypto/openssh/clientloop.h
    +++ b/crypto/openssh/clientloop.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: clientloop.h,v 1.22 2008/06/12 15:19:17 djm Exp $ */
    +/* $OpenBSD: clientloop.h,v 1.23 2010/01/26 01:28:35 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -56,18 +56,14 @@ typedef void global_confirm_cb(int, u_int32_t seq, void *);
     void	 client_register_global_confirm(global_confirm_cb *, void *);
     
     /* Multiplexing protocol version */
    -#define SSHMUX_VER			2
    +#define SSHMUX_VER			4
     
     /* Multiplexing control protocol flags */
     #define SSHMUX_COMMAND_OPEN		1	/* Open new connection */
     #define SSHMUX_COMMAND_ALIVE_CHECK	2	/* Check master is alive */
     #define SSHMUX_COMMAND_TERMINATE	3	/* Ask master to exit */
    -
    -#define SSHMUX_FLAG_TTY			(1)	/* Request tty on open */
    -#define SSHMUX_FLAG_SUBSYS		(1<<1)	/* Subsystem request on open */
    -#define SSHMUX_FLAG_X11_FWD		(1<<2)	/* Request X11 forwarding */
    -#define SSHMUX_FLAG_AGENT_FWD		(1<<3)	/* Request agent forwarding */
    +#define SSHMUX_COMMAND_STDIO_FWD	4	/* Open stdio fwd (ssh -W) */
     
     void	muxserver_listen(void);
    -int	muxserver_accept_control(void);
     void	muxclient(const char *);
    +void	mux_exit_message(Channel *, int);
    diff --git a/crypto/openssh/config.guess b/crypto/openssh/config.guess
    index c7607c74f1b..c2246a4f7f4 100755
    --- a/crypto/openssh/config.guess
    +++ b/crypto/openssh/config.guess
    @@ -1,10 +1,10 @@
     #! /bin/sh
     # Attempt to guess a canonical system name.
     #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
    -#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    +#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
     #   Free Software Foundation, Inc.
     
    -timestamp='2008-04-14'
    +timestamp='2009-12-30'
     
     # This file is free software; you can redistribute it and/or modify it
     # under the terms of the GNU General Public License as published by
    @@ -27,16 +27,16 @@ timestamp='2008-04-14'
     # the same distribution terms that you use for the rest of that program.
     
     
    -# Originally written by Per Bothner .
    -# Please send patches to .  Submit a context
    -# diff and a properly formatted ChangeLog entry.
    +# Originally written by Per Bothner.  Please send patches (context
    +# diff format) to  and include a ChangeLog
    +# entry.
     #
     # This script attempts to guess a canonical system name similar to
     # config.sub.  If it succeeds, it prints the system name on stdout, and
     # exits with 0.  Otherwise, it exits with 1.
     #
    -# The plan is that this can be called by configure scripts if you
    -# don't specify an explicit build system type.
    +# You can get the latest version of this script from:
    +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
     
     me=`echo "$0" | sed -e 's,.*/,,'`
     
    @@ -56,8 +56,9 @@ version="\
     GNU config.guess ($timestamp)
     
     Originally written by Per Bothner.
    -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
    -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
    +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
    +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
    +Software Foundation, Inc.
     
     This is free software; see the source for copying conditions.  There is NO
     warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
    @@ -170,7 +171,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
     		eval $set_cc_for_build
     		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
    -			| grep __ELF__ >/dev/null
    +			| grep -q __ELF__
     		then
     		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
     		    # Return netbsd for either.  FIX?
    @@ -324,14 +325,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     	case `/usr/bin/uname -p` in
     	    sparc) echo sparc-icl-nx7; exit ;;
     	esac ;;
    +    s390x:SunOS:*:*)
    +	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
    +	exit ;;
         sun4H:SunOS:5.*:*)
     	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
     	exit ;;
         sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
     	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
     	exit ;;
    +    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
    +	echo i386-pc-auroraux${UNAME_RELEASE}
    +	exit ;;
         i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
    -	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
    +	eval $set_cc_for_build
    +	SUN_ARCH="i386"
    +	# If there is a compiler, see if it is configured for 64-bit objects.
    +	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
    +	# This test works for both compilers.
    +	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
    +	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
    +		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
    +		grep IS_64BIT_ARCH >/dev/null
    +	    then
    +		SUN_ARCH="x86_64"
    +	    fi
    +	fi
    +	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
     	exit ;;
         sun4*:SunOS:6*:*)
     	# According to config.sub, this is the proper way to canonicalize
    @@ -640,7 +660,7 @@ EOF
     	    # => hppa64-hp-hpux11.23
     
     	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
    -		grep __LP64__ >/dev/null
    +		grep -q __LP64__
     	    then
     		HP_ARCH="hppa2.0w"
     	    else
    @@ -791,12 +811,12 @@ EOF
         i*:PW*:*)
     	echo ${UNAME_MACHINE}-pc-pw32
     	exit ;;
    -    *:Interix*:[3456]*)
    +    *:Interix*:*)
         	case ${UNAME_MACHINE} in
     	    x86)
     		echo i586-pc-interix${UNAME_RELEASE}
     		exit ;;
    -	    EM64T | authenticamd)
    +	    authenticamd | genuineintel | EM64T)
     		echo x86_64-unknown-interix${UNAME_RELEASE}
     		exit ;;
     	    IA64)
    @@ -806,6 +826,9 @@ EOF
         [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
     	echo i${UNAME_MACHINE}-pc-mks
     	exit ;;
    +    8664:Windows_NT:*)
    +	echo x86_64-pc-mks
    +	exit ;;
         i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
     	# How do we know it's Interix rather than the generic POSIX subsystem?
     	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
    @@ -835,6 +858,20 @@ EOF
         i*86:Minix:*:*)
     	echo ${UNAME_MACHINE}-pc-minix
     	exit ;;
    +    alpha:Linux:*:*)
    +	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
    +	  EV5)   UNAME_MACHINE=alphaev5 ;;
    +	  EV56)  UNAME_MACHINE=alphaev56 ;;
    +	  PCA56) UNAME_MACHINE=alphapca56 ;;
    +	  PCA57) UNAME_MACHINE=alphapca56 ;;
    +	  EV6)   UNAME_MACHINE=alphaev6 ;;
    +	  EV67)  UNAME_MACHINE=alphaev67 ;;
    +	  EV68*) UNAME_MACHINE=alphaev68 ;;
    +        esac
    +	objdump --private-headers /bin/sh | grep -q ld.so.1
    +	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
    +	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
    +	exit ;;
         arm*:Linux:*:*)
     	eval $set_cc_for_build
     	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
    @@ -857,6 +894,17 @@ EOF
         frv:Linux:*:*)
         	echo frv-unknown-linux-gnu
     	exit ;;
    +    i*86:Linux:*:*)
    +	LIBC=gnu
    +	eval $set_cc_for_build
    +	sed 's/^	//' << EOF >$dummy.c
    +	#ifdef __dietlibc__
    +	LIBC=dietlibc
    +	#endif
    +EOF
    +	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
    +	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
    +	exit ;;
         ia64:Linux:*:*)
     	echo ${UNAME_MACHINE}-unknown-linux-gnu
     	exit ;;
    @@ -866,74 +914,33 @@ EOF
         m68*:Linux:*:*)
     	echo ${UNAME_MACHINE}-unknown-linux-gnu
     	exit ;;
    -    mips:Linux:*:*)
    +    mips:Linux:*:* | mips64:Linux:*:*)
     	eval $set_cc_for_build
     	sed 's/^	//' << EOF >$dummy.c
     	#undef CPU
    -	#undef mips
    -	#undef mipsel
    +	#undef ${UNAME_MACHINE}
    +	#undef ${UNAME_MACHINE}el
     	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
    -	CPU=mipsel
    +	CPU=${UNAME_MACHINE}el
     	#else
     	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
    -	CPU=mips
    +	CPU=${UNAME_MACHINE}
     	#else
     	CPU=
     	#endif
     	#endif
     EOF
    -	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
    -	    /^CPU/{
    -		s: ::g
    -		p
    -	    }'`"
    -	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
    -	;;
    -    mips64:Linux:*:*)
    -	eval $set_cc_for_build
    -	sed 's/^	//' << EOF >$dummy.c
    -	#undef CPU
    -	#undef mips64
    -	#undef mips64el
    -	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
    -	CPU=mips64el
    -	#else
    -	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
    -	CPU=mips64
    -	#else
    -	CPU=
    -	#endif
    -	#endif
    -EOF
    -	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
    -	    /^CPU/{
    -		s: ::g
    -		p
    -	    }'`"
    +	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
     	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
     	;;
         or32:Linux:*:*)
     	echo or32-unknown-linux-gnu
     	exit ;;
    -    ppc:Linux:*:*)
    -	echo powerpc-unknown-linux-gnu
    +    padre:Linux:*:*)
    +	echo sparc-unknown-linux-gnu
     	exit ;;
    -    ppc64:Linux:*:*)
    -	echo powerpc64-unknown-linux-gnu
    -	exit ;;
    -    alpha:Linux:*:*)
    -	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
    -	  EV5)   UNAME_MACHINE=alphaev5 ;;
    -	  EV56)  UNAME_MACHINE=alphaev56 ;;
    -	  PCA56) UNAME_MACHINE=alphapca56 ;;
    -	  PCA57) UNAME_MACHINE=alphapca56 ;;
    -	  EV6)   UNAME_MACHINE=alphaev6 ;;
    -	  EV67)  UNAME_MACHINE=alphaev67 ;;
    -	  EV68*) UNAME_MACHINE=alphaev68 ;;
    -        esac
    -	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
    -	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
    -	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
    +    parisc64:Linux:*:* | hppa64:Linux:*:*)
    +	echo hppa64-unknown-linux-gnu
     	exit ;;
         parisc:Linux:*:* | hppa:Linux:*:*)
     	# Look for CPU level
    @@ -943,8 +950,11 @@ EOF
     	  *)    echo hppa-unknown-linux-gnu ;;
     	esac
     	exit ;;
    -    parisc64:Linux:*:* | hppa64:Linux:*:*)
    -	echo hppa64-unknown-linux-gnu
    +    ppc64:Linux:*:*)
    +	echo powerpc64-unknown-linux-gnu
    +	exit ;;
    +    ppc:Linux:*:*)
    +	echo powerpc-unknown-linux-gnu
     	exit ;;
         s390:Linux:*:* | s390x:Linux:*:*)
     	echo ${UNAME_MACHINE}-ibm-linux
    @@ -967,66 +977,6 @@ EOF
         xtensa*:Linux:*:*)
         	echo ${UNAME_MACHINE}-unknown-linux-gnu
     	exit ;;
    -    i*86:Linux:*:*)
    -	# The BFD linker knows what the default object file format is, so
    -	# first see if it will tell us. cd to the root directory to prevent
    -	# problems with other programs or directories called `ld' in the path.
    -	# Set LC_ALL=C to ensure ld outputs messages in English.
    -	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
    -			 | sed -ne '/supported targets:/!d
    -				    s/[ 	][ 	]*/ /g
    -				    s/.*supported targets: *//
    -				    s/ .*//
    -				    p'`
    -        case "$ld_supported_targets" in
    -	  elf32-i386)
    -		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
    -		;;
    -	  a.out-i386-linux)
    -		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
    -		exit ;;
    -	  "")
    -		# Either a pre-BFD a.out linker (linux-gnuoldld) or
    -		# one that does not give us useful --help.
    -		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
    -		exit ;;
    -	esac
    -	# Determine whether the default compiler is a.out or elf
    -	eval $set_cc_for_build
    -	sed 's/^	//' << EOF >$dummy.c
    -	#include 
    -	#ifdef __ELF__
    -	# ifdef __GLIBC__
    -	#  if __GLIBC__ >= 2
    -	LIBC=gnu
    -	#  else
    -	LIBC=gnulibc1
    -	#  endif
    -	# else
    -	LIBC=gnulibc1
    -	# endif
    -	#else
    -	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
    -	LIBC=gnu
    -	#else
    -	LIBC=gnuaout
    -	#endif
    -	#endif
    -	#ifdef __dietlibc__
    -	LIBC=dietlibc
    -	#endif
    -EOF
    -	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
    -	    /^LIBC/{
    -		s: ::g
    -		p
    -	    }'`"
    -	test x"${LIBC}" != x && {
    -		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
    -		exit
    -	}
    -	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
    -	;;
         i*86:DYNIX/ptx:4*:*)
     	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
     	# earlier versions are messed up and put the nodename in both
    @@ -1055,7 +1005,7 @@ EOF
         i*86:syllable:*:*)
     	echo ${UNAME_MACHINE}-pc-syllable
     	exit ;;
    -    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
    +    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
     	echo i386-unknown-lynxos${UNAME_RELEASE}
     	exit ;;
         i*86:*DOS:*:*)
    @@ -1099,8 +1049,11 @@ EOF
         pc:*:*:*)
     	# Left here for compatibility:
             # uname -m prints for DJGPP always 'pc', but it prints nothing about
    -        # the processor, so we play safe by assuming i386.
    -	echo i386-pc-msdosdjgpp
    +        # the processor, so we play safe by assuming i586.
    +	# Note: whatever this is, it MUST be the same as what config.sub
    +	# prints for the "djgpp" host, or else GDB configury will decide that
    +	# this is a cross-build.
    +	echo i586-pc-msdosdjgpp
             exit ;;
         Intel:Mach:3*:*)
     	echo i386-pc-mach3
    @@ -1138,6 +1091,16 @@ EOF
         3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
             /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
               && { echo i486-ncr-sysv4; exit; } ;;
    +    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
    +	OS_REL='.3'
    +	test -r /etc/.relid \
    +	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
    +	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
    +	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
    +	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
    +	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
    +	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
    +	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
         m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
     	echo m68k-unknown-lynxos${UNAME_RELEASE}
     	exit ;;
    @@ -1150,7 +1113,7 @@ EOF
         rs6000:LynxOS:2.*:*)
     	echo rs6000-unknown-lynxos${UNAME_RELEASE}
     	exit ;;
    -    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
    +    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
     	echo powerpc-unknown-lynxos${UNAME_RELEASE}
     	exit ;;
         SM[BE]S:UNIX_SV:*:*)
    @@ -1243,6 +1206,16 @@ EOF
         *:Darwin:*:*)
     	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
     	case $UNAME_PROCESSOR in
    +	    i386)
    +		eval $set_cc_for_build
    +		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
    +		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
    +		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
    +		      grep IS_64BIT_ARCH >/dev/null
    +		  then
    +		      UNAME_PROCESSOR="x86_64"
    +		  fi
    +		fi ;;
     	    unknown) UNAME_PROCESSOR=powerpc ;;
     	esac
     	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
    @@ -1324,6 +1297,9 @@ EOF
         i*86:rdos:*:*)
     	echo ${UNAME_MACHINE}-pc-rdos
     	exit ;;
    +    i*86:AROS:*:*)
    +	echo ${UNAME_MACHINE}-pc-aros
    +	exit ;;
     esac
     
     #echo '(No uname command or uname output not recognized.)' 1>&2
    diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h
    index d07ee699a02..c975e019ec1 100644
    --- a/crypto/openssh/config.h
    +++ b/crypto/openssh/config.h
    @@ -69,6 +69,9 @@
     /* Define if your snprintf is busted */
     /* #undef BROKEN_SNPRINTF */
     
    +/* tcgetattr with ICANON may hang */
    +/* #undef BROKEN_TCGETATTR_ICANON */
    +
     /* updwtmpx is broken (if present) */
     /* #undef BROKEN_UPDWTMPX */
     
    @@ -120,12 +123,18 @@
     /* Define if you don't want to use wtmpx */
     #define DISABLE_WTMPX 1
     
    +/* Enable for PKCS#11 support */
    +#define ENABLE_PKCS11 
    +
     /* Builtin PRNG command timeout */
     #define ENTROPY_TIMEOUT_MSEC 200
     
    -/* f_fsid has members */
    +/* fsid_t has member val */
     /* #undef FSID_HAS_VAL */
     
    +/* fsid_t has member __val */
    +/* #undef FSID_HAS___VAL */
    +
     /* Define to 1 if the `getpgrp' function requires zero arguments. */
     #define GETPGRP_VOID 1
     
    @@ -456,6 +465,9 @@
     /* Define to 1 if you have the  header file. */
     #define HAVE_GLOB_H 1
     
    +/* Define to 1 if you have the `group_from_gid' function. */
    +#define HAVE_GROUP_FROM_GID 1
    +
     /* Define to 1 if you have the  header file. */
     /* #undef HAVE_GSSAPI_GENERIC_H */
     
    @@ -519,6 +531,9 @@
     /* Define to 1 if the system has the type `in_addr_t'. */
     #define HAVE_IN_ADDR_T 1
     
    +/* Define to 1 if the system has the type `in_port_t'. */
    +#define HAVE_IN_PORT_T 1
    +
     /* Define to 1 if you have the  header file. */
     /* #undef HAVE_LASTLOG_H */
     
    @@ -543,9 +558,6 @@
     /* Define to 1 if you have the `pam' library (-lpam). */
     #define HAVE_LIBPAM 1
     
    -/* Define to 1 if you have the `sectok' library (-lsectok). */
    -/* #undef HAVE_LIBSECTOK */
    -
     /* Define to 1 if you have the `socket' library (-lsocket). */
     /* #undef HAVE_LIBSOCKET */
     
    @@ -727,9 +739,6 @@
     /* define if you have sa_family_t data type */
     #define HAVE_SA_FAMILY_T 1
     
    -/* Define to 1 if you have the  header file. */
    -/* #undef HAVE_SECTOK_H */
    -
     /* Define if you have SecureWare-based protected password database */
     /* #undef HAVE_SECUREWARE */
     
    @@ -754,6 +763,9 @@
     /* Define to 1 if you have the `seteuid' function. */
     #define HAVE_SETEUID 1
     
    +/* Define to 1 if you have the `setgroupent' function. */
    +#define HAVE_SETGROUPENT 1
    +
     /* Define to 1 if you have the `setgroups' function. */
     #define HAVE_SETGROUPS 1
     
    @@ -763,6 +775,9 @@
     /* Define to 1 if you have the `setluid' function. */
     /* #undef HAVE_SETLUID */
     
    +/* Define to 1 if you have the `setpassent' function. */
    +#define HAVE_SETPASSENT 1
    +
     /* Define to 1 if you have the `setpcred' function. */
     /* #undef HAVE_SETPCRED */
     
    @@ -1066,6 +1081,9 @@
     /* Define to 1 if you have the  header file. */
     /* #undef HAVE_USERSEC_H */
     
    +/* Define to 1 if you have the `user_from_uid' function. */
    +#define HAVE_USER_FROM_UID 1
    +
     /* Define to 1 if you have the  header file. */
     /* #undef HAVE_UTIL_H */
     
    @@ -1175,6 +1193,9 @@
        EOPNOTSUPP. */
     /* #undef LINK_OPNOTSUPP_ERRNO */
     
    +/* Adjust Linux out-of-memory killer */
    +/* #undef LINUX_OOM_ADJUST */
    +
     /* max value of long long calculated by configure */
     /* #undef LLONG_MAX */
     
    @@ -1227,6 +1248,9 @@
     /* Define if X11 doesn't support AF_UNIX sockets on that system */
     /* #undef NO_X11_UNIX_SOCKETS */
     
    +/* Define if EVP_DigestUpdate returns void */
    +/* #undef OPENSSL_EVP_DIGESTUPDATE_VOID */
    +
     /* libcrypto is missing AES 192 and 256 bit functions */
     /* #undef OPENSSL_LOBOTOMISED_AES */
     
    @@ -1291,9 +1315,6 @@
     /* Define if your skeychallenge() function takes 4 arguments (NetBSD) */
     /* #undef SKEYCHALLENGE_4ARG */
     
    -/* Define if you want smartcard support */
    -/* #undef SMARTCARD */
    -
     /* Define as const if snprintf() can declare const char *fmt */
     #define SNPRINTF_CONST const
     
    @@ -1310,6 +1331,9 @@
     /* Use audit debugging module */
     /* #undef SSH_AUDIT_EVENTS */
     
    +/* Windows is sensitive to read buffer size */
    +/* #undef SSH_IOBUFSZ */
    +
     /* non-privileged user for privilege separation */
     #define SSH_PRIVSEP_USER "sshd"
     
    @@ -1358,9 +1382,6 @@
     /* Use libedit for sftp */
     #define USE_LIBEDIT 1
     
    -/* Define if you want smartcard support using OpenSC */
    -/* #undef USE_OPENSC */
    -
     /* Enable OpenSSL engine support */
     #define USE_OPENSSL_ENGINE 1
     
    @@ -1370,9 +1391,6 @@
     /* Use PIPES instead of a socketpair() */
     /* #undef USE_PIPES */
     
    -/* Define if you want smartcard support using sectok */
    -/* #undef USE_SECTOK */
    -
     /* Define if you have Solaris process contracts */
     /* #undef USE_SOLARIS_PROCESS_CONTRACTS */
     
    @@ -1400,7 +1418,11 @@
     
     /* Define to 1 if your processor stores words with the most significant byte
        first (like Motorola and SPARC, unlike Intel and VAX). */
    -/* #undef WORDS_BIGENDIAN */
    +#if defined __BIG_ENDIAN__
    +# define WORDS_BIGENDIAN 1
    +#elif ! defined __LITTLE_ENDIAN__
    +/* # undef WORDS_BIGENDIAN */
    +#endif
     
     /* Define if xauth is found in your path */
     /* #undef XAUTH_PATH */
    diff --git a/crypto/openssh/config.h.in b/crypto/openssh/config.h.in
    index 84967a46126..a61dec6095d 100644
    --- a/crypto/openssh/config.h.in
    +++ b/crypto/openssh/config.h.in
    @@ -68,6 +68,9 @@
     /* Define if your snprintf is busted */
     #undef BROKEN_SNPRINTF
     
    +/* tcgetattr with ICANON may hang */
    +#undef BROKEN_TCGETATTR_ICANON
    +
     /* updwtmpx is broken (if present) */
     #undef BROKEN_UPDWTMPX
     
    @@ -119,12 +122,18 @@
     /* Define if you don't want to use wtmpx */
     #undef DISABLE_WTMPX
     
    +/* Enable for PKCS#11 support */
    +#undef ENABLE_PKCS11
    +
     /* Builtin PRNG command timeout */
     #undef ENTROPY_TIMEOUT_MSEC
     
    -/* f_fsid has members */
    +/* fsid_t has member val */
     #undef FSID_HAS_VAL
     
    +/* fsid_t has member __val */
    +#undef FSID_HAS___VAL
    +
     /* Define to 1 if the `getpgrp' function requires zero arguments. */
     #undef GETPGRP_VOID
     
    @@ -455,6 +464,9 @@
     /* Define to 1 if you have the  header file. */
     #undef HAVE_GLOB_H
     
    +/* Define to 1 if you have the `group_from_gid' function. */
    +#undef HAVE_GROUP_FROM_GID
    +
     /* Define to 1 if you have the  header file. */
     #undef HAVE_GSSAPI_GENERIC_H
     
    @@ -518,6 +530,9 @@
     /* Define to 1 if the system has the type `in_addr_t'. */
     #undef HAVE_IN_ADDR_T
     
    +/* Define to 1 if the system has the type `in_port_t'. */
    +#undef HAVE_IN_PORT_T
    +
     /* Define to 1 if you have the  header file. */
     #undef HAVE_LASTLOG_H
     
    @@ -542,9 +557,6 @@
     /* Define to 1 if you have the `pam' library (-lpam). */
     #undef HAVE_LIBPAM
     
    -/* Define to 1 if you have the `sectok' library (-lsectok). */
    -#undef HAVE_LIBSECTOK
    -
     /* Define to 1 if you have the `socket' library (-lsocket). */
     #undef HAVE_LIBSOCKET
     
    @@ -726,9 +738,6 @@
     /* define if you have sa_family_t data type */
     #undef HAVE_SA_FAMILY_T
     
    -/* Define to 1 if you have the  header file. */
    -#undef HAVE_SECTOK_H
    -
     /* Define if you have SecureWare-based protected password database */
     #undef HAVE_SECUREWARE
     
    @@ -753,6 +762,9 @@
     /* Define to 1 if you have the `seteuid' function. */
     #undef HAVE_SETEUID
     
    +/* Define to 1 if you have the `setgroupent' function. */
    +#undef HAVE_SETGROUPENT
    +
     /* Define to 1 if you have the `setgroups' function. */
     #undef HAVE_SETGROUPS
     
    @@ -762,6 +774,9 @@
     /* Define to 1 if you have the `setluid' function. */
     #undef HAVE_SETLUID
     
    +/* Define to 1 if you have the `setpassent' function. */
    +#undef HAVE_SETPASSENT
    +
     /* Define to 1 if you have the `setpcred' function. */
     #undef HAVE_SETPCRED
     
    @@ -1065,6 +1080,9 @@
     /* Define to 1 if you have the  header file. */
     #undef HAVE_USERSEC_H
     
    +/* Define to 1 if you have the `user_from_uid' function. */
    +#undef HAVE_USER_FROM_UID
    +
     /* Define to 1 if you have the  header file. */
     #undef HAVE_UTIL_H
     
    @@ -1174,6 +1192,9 @@
        EOPNOTSUPP. */
     #undef LINK_OPNOTSUPP_ERRNO
     
    +/* Adjust Linux out-of-memory killer */
    +#undef LINUX_OOM_ADJUST
    +
     /* max value of long long calculated by configure */
     #undef LLONG_MAX
     
    @@ -1226,6 +1247,9 @@
     /* Define if X11 doesn't support AF_UNIX sockets on that system */
     #undef NO_X11_UNIX_SOCKETS
     
    +/* Define if EVP_DigestUpdate returns void */
    +#undef OPENSSL_EVP_DIGESTUPDATE_VOID
    +
     /* libcrypto is missing AES 192 and 256 bit functions */
     #undef OPENSSL_LOBOTOMISED_AES
     
    @@ -1290,9 +1314,6 @@
     /* Define if your skeychallenge() function takes 4 arguments (NetBSD) */
     #undef SKEYCHALLENGE_4ARG
     
    -/* Define if you want smartcard support */
    -#undef SMARTCARD
    -
     /* Define as const if snprintf() can declare const char *fmt */
     #undef SNPRINTF_CONST
     
    @@ -1309,6 +1330,9 @@
     /* Use audit debugging module */
     #undef SSH_AUDIT_EVENTS
     
    +/* Windows is sensitive to read buffer size */
    +#undef SSH_IOBUFSZ
    +
     /* non-privileged user for privilege separation */
     #undef SSH_PRIVSEP_USER
     
    @@ -1357,9 +1381,6 @@
     /* Use libedit for sftp */
     #undef USE_LIBEDIT
     
    -/* Define if you want smartcard support using OpenSC */
    -#undef USE_OPENSC
    -
     /* Enable OpenSSL engine support */
     #undef USE_OPENSSL_ENGINE
     
    @@ -1369,9 +1390,6 @@
     /* Use PIPES instead of a socketpair() */
     #undef USE_PIPES
     
    -/* Define if you want smartcard support using sectok */
    -#undef USE_SECTOK
    -
     /* Define if you have Solaris process contracts */
     #undef USE_SOLARIS_PROCESS_CONTRACTS
     
    diff --git a/crypto/openssh/defines.h b/crypto/openssh/defines.h
    index 536ec4978be..c9b93bf7139 100644
    --- a/crypto/openssh/defines.h
    +++ b/crypto/openssh/defines.h
    @@ -25,7 +25,7 @@
     #ifndef _DEFINES_H
     #define _DEFINES_H
     
    -/* $Id: defines.h,v 1.153 2009/02/01 11:19:54 dtucker Exp $ */
    +/* $Id: defines.h,v 1.159 2010/01/13 23:44:34 tim Exp $ */
     
     
     /* Constants */
    @@ -300,6 +300,9 @@ struct	sockaddr_un {
     #ifndef HAVE_IN_ADDR_T
     typedef u_int32_t	in_addr_t;
     #endif
    +#ifndef HAVE_IN_PORT_T
    +typedef u_int16_t	in_port_t;
    +#endif
     
     #if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE)
     #define _STRUCT_WINSIZE
    @@ -591,6 +594,10 @@ struct winsize {
     #define FSID_TO_ULONG(f) \
     	((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \
     	    ((f).val[1] & 0xffffffffUL))
    +#elif defined(FSID_HAS___VAL)
    +#define FSID_TO_ULONG(f) \
    +	((((u_int64_t)(f).__val[0] & 0xffffffffUL) << 32) | \
    +	    ((f).__val[1] & 0xffffffffUL))
     #else
     # define FSID_TO_ULONG(f) ((f))
     #endif
    @@ -742,4 +749,16 @@ struct winsize {
     #define INET6_ADDRSTRLEN 46
     #endif
     
    +#ifndef SSH_IOBUFSZ
    +# define SSH_IOBUFSZ 8192
    +#endif
    +
    +#ifndef _NSIG
    +# ifdef NSIG
    +#  define _NSIG NSIG
    +# else
    +#  define _NSIG 128
    +# endif
    +#endif
    +
     #endif /* _DEFINES_H */
    diff --git a/crypto/openssh/dh.c b/crypto/openssh/dh.c
    index b76605325de..b9029d867e1 100644
    --- a/crypto/openssh/dh.c
    +++ b/crypto/openssh/dh.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: dh.c,v 1.47 2008/06/26 09:19:39 djm Exp $ */
    +/* $OpenBSD: dh.c,v 1.48 2009/10/01 11:37:33 grunk Exp $ */
     /*
      * Copyright (c) 2000 Niels Provos.  All rights reserved.
      *
    @@ -83,7 +83,7 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
     		goto fail;
     	strsize = strsep(&cp, " "); /* size */
     	if (cp == NULL || *strsize == '\0' ||
    -	    (dhg->size = (u_int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
    +	    (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
     	    errstr)
     		goto fail;
     	/* The whole group is one bit larger */
    diff --git a/crypto/openssh/dns.c b/crypto/openssh/dns.c
    index a7da03fa3ef..2e7bb5aae9f 100644
    --- a/crypto/openssh/dns.c
    +++ b/crypto/openssh/dns.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: dns.c,v 1.25 2008/06/12 00:03:49 dtucker Exp $ */
    +/* $OpenBSD: dns.c,v 1.26 2010/02/26 20:29:54 djm Exp $ */
     
     /*
      * Copyright (c) 2003 Wesley Griffin. All rights reserved.
    @@ -75,7 +75,7 @@ dns_result_totext(unsigned int res)
      */
     static int
     dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
    -    u_char **digest, u_int *digest_len, const Key *key)
    +    u_char **digest, u_int *digest_len, Key *key)
     {
     	int success = 0;
     
    @@ -172,7 +172,7 @@ is_numeric_hostname(const char *hostname)
      */
     int
     verify_host_key_dns(const char *hostname, struct sockaddr *address,
    -    const Key *hostkey, int *flags)
    +    Key *hostkey, int *flags)
     {
     	u_int counter;
     	int result;
    @@ -271,7 +271,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
      * Export the fingerprint of a key as a DNS resource record
      */
     int
    -export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic)
    +export_dns_rr(const char *hostname, Key *key, FILE *f, int generic)
     {
     	u_int8_t rdata_pubkey_algorithm = 0;
     	u_int8_t rdata_digest_type = SSHFP_HASH_SHA1;
    diff --git a/crypto/openssh/dns.h b/crypto/openssh/dns.h
    index b2633a1fe98..90cfd7b92ce 100644
    --- a/crypto/openssh/dns.h
    +++ b/crypto/openssh/dns.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: dns.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
    +/* $OpenBSD: dns.h,v 1.11 2010/02/26 20:29:54 djm Exp $ */
     
     /*
      * Copyright (c) 2003 Wesley Griffin. All rights reserved.
    @@ -46,7 +46,7 @@ enum sshfp_hashes {
     #define DNS_VERIFY_MATCH	0x00000002
     #define DNS_VERIFY_SECURE	0x00000004
     
    -int	verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *);
    -int	export_dns_rr(const char *, const Key *, FILE *, int);
    +int	verify_host_key_dns(const char *, struct sockaddr *, Key *, int *);
    +int	export_dns_rr(const char *, Key *, FILE *, int);
     
     #endif /* DNS_H */
    diff --git a/crypto/openssh/gss-genr.c b/crypto/openssh/gss-genr.c
    index e9190575d35..842f38582c0 100644
    --- a/crypto/openssh/gss-genr.c
    +++ b/crypto/openssh/gss-genr.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: gss-genr.c,v 1.19 2007/06/12 11:56:15 dtucker Exp $ */
    +/* $OpenBSD: gss-genr.c,v 1.20 2009/06/22 05:39:28 dtucker Exp $ */
     
     /*
      * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
    diff --git a/crypto/openssh/hostfile.c b/crypto/openssh/hostfile.c
    index 2cceb352a1f..afab6dad182 100644
    --- a/crypto/openssh/hostfile.c
    +++ b/crypto/openssh/hostfile.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: hostfile.c,v 1.45 2006/08/03 03:34:42 deraadt Exp $ */
    +/* $OpenBSD: hostfile.c,v 1.48 2010/03/04 10:36:03 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -183,6 +183,41 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen
     	return 1;
     }
     
    +static enum { MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA }
    +check_markers(char **cpp)
    +{
    +	char marker[32], *sp, *cp = *cpp;
    +	int ret = MRK_NONE;
    +
    +	while (*cp == '@') {
    +		/* Only one marker is allowed */
    +		if (ret != MRK_NONE)
    +			return MRK_ERROR;
    +		/* Markers are terminated by whitespace */
    +		if ((sp = strchr(cp, ' ')) == NULL &&
    +		    (sp = strchr(cp, '\t')) == NULL)
    +			return MRK_ERROR;
    +		/* Extract marker for comparison */
    +		if (sp <= cp + 1 || sp >= cp + sizeof(marker))
    +			return MRK_ERROR;
    +		memcpy(marker, cp, sp - cp);
    +		marker[sp - cp] = '\0';
    +		if (strcmp(marker, CA_MARKER) == 0)
    +			ret = MRK_CA;
    +		else if (strcmp(marker, REVOKE_MARKER) == 0)
    +			ret = MRK_REVOKE;
    +		else
    +			return MRK_ERROR;
    +
    +		/* Skip past marker and any whitespace that follows it */
    +		cp = sp;
    +		for (; *cp == ' ' || *cp == '\t'; cp++)
    +			;
    +	}
    +	*cpp = cp;
    +	return ret;
    +}
    +
     /*
      * Checks whether the given host (which must be in all lowercase) is already
      * in the list of our known hosts. Returns HOST_OK if the host is known and
    @@ -195,16 +230,20 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen
     
     static HostStatus
     check_host_in_hostfile_by_key_or_type(const char *filename,
    -    const char *host, const Key *key, int keytype, Key *found, int *numret)
    +    const char *host, const Key *key, int keytype, Key *found,
    +    int want_revocation, int *numret)
     {
     	FILE *f;
     	char line[8192];
    -	int linenum = 0;
    +	int want, have, linenum = 0, want_cert = key_is_cert(key);
     	u_int kbits;
     	char *cp, *cp2, *hashed_host;
     	HostStatus end_return;
     
    -	debug3("check_host_in_hostfile: filename %s", filename);
    +	debug3("check_host_in_hostfile: host %s filename %s", host, filename);
    +
    +	if (want_revocation && (key == NULL || keytype != 0 || found != NULL))
    +		fatal("%s: invalid arguments", __func__);
     
     	/* Open the file containing the list of known hosts. */
     	f = fopen(filename, "r");
    @@ -229,6 +268,20 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
     		if (!*cp || *cp == '#' || *cp == '\n')
     			continue;
     
    +		if (want_revocation)
    +			want = MRK_REVOKE;
    +		else if (want_cert)
    +			want = MRK_CA;
    +		else
    +			want = MRK_NONE;
    +
    +		if ((have = check_markers(&cp)) == MRK_ERROR) {
    +			verbose("%s: invalid marker at %s:%d",
    +			    __func__, filename, linenum);
    +			continue;
    +		} else if (want != have)
    +			continue;
    +
     		/* Find the end of the host name portion. */
     		for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
     			;
    @@ -250,6 +303,9 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
     		/* Got a match.  Skip host name. */
     		cp = cp2;
     
    +		if (want_revocation)
    +			found = key_new(KEY_UNSPEC);
    +
     		/*
     		 * Extract the key from the line.  This will skip any leading
     		 * whitespace.  Ignore badly formatted lines.
    @@ -272,9 +328,33 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
     		if (!hostfile_check_key(kbits, found, host, filename, linenum))
     			continue;
     
    +		if (want_revocation) {
    +			if (key_is_cert(key) &&
    +			    key_equal_public(key->cert->signature_key, found)) {
    +				verbose("check_host_in_hostfile: revoked CA "
    +				    "line %d", linenum);
    +				key_free(found);
    +				return HOST_REVOKED;
    +			}
    +			if (key_equal_public(key, found)) {
    +				verbose("check_host_in_hostfile: revoked key "
    +				    "line %d", linenum);
    +				key_free(found);
    +				return HOST_REVOKED;
    +			}
    +			key_free(found);
    +			continue;
    +		}
    +
     		/* Check if the current key is the same as the given key. */
    -		if (key_equal(key, found)) {
    -			/* Ok, they match. */
    +		if (want_cert && key_equal(key->cert->signature_key, found)) {
    +			/* Found CA cert for key */
    +			debug3("check_host_in_hostfile: CA match line %d",
    +			    linenum);
    +			fclose(f);
    +			return HOST_OK;
    +		} else if (!want_cert && key_equal(key, found)) {
    +			/* Found identical key */
     			debug3("check_host_in_hostfile: match line %d", linenum);
     			fclose(f);
     			return HOST_OK;
    @@ -302,8 +382,11 @@ check_host_in_hostfile(const char *filename, const char *host, const Key *key,
     {
     	if (key == NULL)
     		fatal("no key to look up");
    -	return (check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
    -	    found, numret));
    +	if (check_host_in_hostfile_by_key_or_type(filename, host,
    +	    key, 0, NULL, 1, NULL) == HOST_REVOKED)
    +		return HOST_REVOKED;
    +	return check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
    +	    found, 0, numret);
     }
     
     int
    @@ -311,7 +394,7 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
         int keytype, Key *found, int *numret)
     {
     	return (check_host_in_hostfile_by_key_or_type(filename, host, NULL,
    -	    keytype, found, numret) == HOST_FOUND);
    +	    keytype, found, 0, numret) == HOST_FOUND);
     }
     
     /*
    diff --git a/crypto/openssh/hostfile.h b/crypto/openssh/hostfile.h
    index d1983b3e093..1d460c1a915 100644
    --- a/crypto/openssh/hostfile.h
    +++ b/crypto/openssh/hostfile.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: hostfile.h,v 1.16 2006/03/25 22:22:43 djm Exp $ */
    +/* $OpenBSD: hostfile.h,v 1.18 2010/03/04 10:36:03 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -15,7 +15,7 @@
     #define HOSTFILE_H
     
     typedef enum {
    -	HOST_OK, HOST_NEW, HOST_CHANGED, HOST_FOUND
    +	HOST_OK, HOST_NEW, HOST_CHANGED, HOST_REVOKED, HOST_FOUND
     }       HostStatus;
     
     int	 hostfile_read_key(char **, u_int *, Key *);
    @@ -28,6 +28,9 @@ int	lookup_key_in_hostfile_by_type(const char *, const char *,
     #define HASH_MAGIC	"|1|"
     #define HASH_DELIM	'|'
     
    +#define CA_MARKER	"@cert-authority"
    +#define REVOKE_MARKER	"@revoked"
    +
     char	*host_hash(const char *, const char *, u_int);
     
     #endif
    diff --git a/crypto/openssh/includes.h b/crypto/openssh/includes.h
    index f1b47f666d0..6bb98780729 100644
    --- a/crypto/openssh/includes.h
    +++ b/crypto/openssh/includes.h
    @@ -31,7 +31,8 @@
     #endif
     #if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
         defined(GLOB_HAS_GL_MATCHC) && \
    -    defined(HAVE_DECL_GLOB_NOMATCH) &&  HAVE_DECL_GLOB_NOMATCH != 0
    +    defined(HAVE_DECL_GLOB_NOMATCH) &&  HAVE_DECL_GLOB_NOMATCH != 0 && \
    +    !defined(BROKEN_GLOB)
     # include 
     #endif
     #ifdef HAVE_ENDIAN_H
    diff --git a/crypto/openssh/jpake.c b/crypto/openssh/jpake.c
    index 565f2e25508..130661069fb 100644
    --- a/crypto/openssh/jpake.c
    +++ b/crypto/openssh/jpake.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: jpake.c,v 1.1 2008/11/04 08:22:12 djm Exp $ */
    +/* $OpenBSD: jpake.c,v 1.2 2009/03/05 07:18:19 djm Exp $ */
     /*
      * Copyright (c) 2008 Damien Miller.  All rights reserved.
      *
    @@ -47,6 +47,7 @@
     #include "log.h"
     
     #include "jpake.h"
    +#include "schnorr.h"
     
     #ifdef JPAKE
     
    @@ -60,165 +61,10 @@
     	"98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" \
     	"9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
     
    -struct jpake_group *
    +struct modp_group *
     jpake_default_group(void)
     {
    -	struct jpake_group *ret;
    -
    -	ret = xmalloc(sizeof(*ret));
    -	ret->p = ret->q = ret->g = NULL;
    -	if (BN_hex2bn(&ret->p, JPAKE_GROUP_P) == 0 ||
    -	    BN_hex2bn(&ret->g, JPAKE_GROUP_G) == 0)
    -		fatal("%s: BN_hex2bn", __func__);
    -	/* Subgroup order is p/2 (p is a safe prime) */
    -	if ((ret->q = BN_new()) == NULL)
    -		fatal("%s: BN_new", __func__);
    -	if (BN_rshift1(ret->q, ret->p) != 1)
    -		fatal("%s: BN_rshift1", __func__);
    -
    -	return ret;
    -}
    -
    -/*
    - * Generate uniformly distributed random number in range (1, high).
    - * Return number on success, NULL on failure.
    - */
    -BIGNUM *
    -bn_rand_range_gt_one(const BIGNUM *high)
    -{
    -	BIGNUM *r, *tmp;
    -	int success = -1;
    -
    -	if ((tmp = BN_new()) == NULL) {
    -		error("%s: BN_new", __func__);
    -		return NULL;
    -	}
    -	if ((r = BN_new()) == NULL) {
    -		error("%s: BN_new failed", __func__);
    -		goto out;
    -	}
    -	if (BN_set_word(tmp, 2) != 1) {
    -		error("%s: BN_set_word(tmp, 2)", __func__);
    -		goto out;
    -	}
    -	if (BN_sub(tmp, high, tmp) == -1) {
    -		error("%s: BN_sub failed (tmp = high - 2)", __func__);
    -		goto out;
    -	}
    -	if (BN_rand_range(r, tmp) == -1) {
    -		error("%s: BN_rand_range failed", __func__);
    -		goto out;
    -	}
    -	if (BN_set_word(tmp, 2) != 1) {
    -		error("%s: BN_set_word(tmp, 2)", __func__);
    -		goto out;
    -	}
    -	if (BN_add(r, r, tmp) == -1) {
    -		error("%s: BN_add failed (r = r + 2)", __func__);
    -		goto out;
    -	}
    -	success = 0;
    - out:
    -	BN_clear_free(tmp);
    -	if (success == 0)
    -		return r;
    -	BN_clear_free(r);
    -	return NULL;
    -}
    -
    -/*
    - * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
    - * with digest via 'digestp' (caller to free) and length via 'lenp'.
    - * Returns -1 on failure.
    - */
    -int
    -hash_buffer(const u_char *buf, u_int len, const EVP_MD *md,
    -    u_char **digestp, u_int *lenp)
    -{
    -	u_char digest[EVP_MAX_MD_SIZE];
    -	u_int digest_len;
    -	EVP_MD_CTX evp_md_ctx;
    -	int success = -1;
    -
    -	EVP_MD_CTX_init(&evp_md_ctx);
    -
    -	if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) {
    -		error("%s: EVP_DigestInit_ex", __func__);
    -		goto out;
    -	}
    -	if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
    -		error("%s: EVP_DigestUpdate", __func__);
    -		goto out;
    -	}
    -	if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) {
    -		error("%s: EVP_DigestFinal_ex", __func__);
    -		goto out;
    -	}
    -	*digestp = xmalloc(digest_len);
    -	*lenp = digest_len;
    -	memcpy(*digestp, digest, *lenp);
    -	success = 0;
    - out:
    -	EVP_MD_CTX_cleanup(&evp_md_ctx);
    -	bzero(digest, sizeof(digest));
    -	digest_len = 0;
    -	return success;
    -}
    -
    -/* print formatted string followed by bignum */
    -void
    -jpake_debug3_bn(const BIGNUM *n, const char *fmt, ...)
    -{
    -	char *out, *h;
    -	va_list args;
    -
    -	out = NULL;
    -	va_start(args, fmt);
    -	vasprintf(&out, fmt, args);
    -	va_end(args);
    -	if (out == NULL)
    -		fatal("%s: vasprintf failed", __func__);
    -
    -	if (n == NULL)
    -		debug3("%s(null)", out);
    -	else {
    -		h = BN_bn2hex(n);
    -		debug3("%s0x%s", out, h);
    -		free(h);
    -	}
    -	free(out);
    -}
    -
    -/* print formatted string followed by buffer contents in hex */
    -void
    -jpake_debug3_buf(const u_char *buf, u_int len, const char *fmt, ...)
    -{
    -	char *out, h[65];
    -	u_int i, j;
    -	va_list args;
    -
    -	out = NULL;
    -	va_start(args, fmt);
    -	vasprintf(&out, fmt, args);
    -	va_end(args);
    -	if (out == NULL)
    -		fatal("%s: vasprintf failed", __func__);
    -
    -	debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : "");
    -	free(out);
    -	if (buf == NULL)
    -		return;
    -
    -	*h = '\0';
    -	for (i = j = 0; i < len; i++) {
    -		snprintf(h + j, sizeof(h) - j, "%02x", buf[i]);
    -		j += 2;
    -		if (j >= sizeof(h) - 1 || i == len - 1) {
    -			debug3("    %s", h);
    -			*h = '\0';
    -			j = 0;
    -		}
    -	}
    +	return modp_group_from_g_and_safe_p(JPAKE_GROUP_G, JPAKE_GROUP_P);
     }
     
     struct jpake_ctx *
    @@ -243,7 +89,6 @@ jpake_new(void)
     	return ret;
     }
     
    -
     void
     jpake_free(struct jpake_ctx *pctx)
     {
    @@ -344,7 +189,7 @@ jpake_dump(struct jpake_ctx *pctx, const char *fmt, ...)
     
     /* Shared parts of step 1 exchange calculation */
     void
    -jpake_step1(struct jpake_group *grp,
    +jpake_step1(struct modp_group *grp,
         u_char **id, u_int *id_len,
         BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
         u_char **priv1_proof, u_int *priv1_proof_len,
    @@ -383,11 +228,11 @@ jpake_step1(struct jpake_group *grp,
     		fatal("%s: BN_mod_exp", __func__);
     
     	/* Generate proofs for holding x1/x3 and x2/x4 */
    -	if (schnorr_sign(grp->p, grp->q, grp->g,
    +	if (schnorr_sign_buf(grp->p, grp->q, grp->g,
     	    *priv1, *g_priv1, *id, *id_len,
     	    priv1_proof, priv1_proof_len) != 0)
     		fatal("%s: schnorr_sign", __func__);
    -	if (schnorr_sign(grp->p, grp->q, grp->g,
    +	if (schnorr_sign_buf(grp->p, grp->q, grp->g,
     	    *priv2, *g_priv2, *id, *id_len,
     	    priv2_proof, priv2_proof_len) != 0)
     		fatal("%s: schnorr_sign", __func__);
    @@ -397,7 +242,7 @@ jpake_step1(struct jpake_group *grp,
     
     /* Shared parts of step 2 exchange calculation */
     void
    -jpake_step2(struct jpake_group *grp, BIGNUM *s,
    +jpake_step2(struct modp_group *grp, BIGNUM *s,
         BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
         const u_char *theirid, u_int theirid_len,
         const u_char *myid, u_int myid_len,
    @@ -415,10 +260,10 @@ jpake_step2(struct jpake_group *grp, BIGNUM *s,
     	if (BN_cmp(theirpub2, BN_value_one()) <= 0)
     		fatal("%s: theirpub2 <= 1", __func__);
     
    -	if (schnorr_verify(grp->p, grp->q, grp->g, theirpub1,
    +	if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub1,
     	    theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1)
     		fatal("%s: schnorr_verify theirpub1 failed", __func__);
    -	if (schnorr_verify(grp->p, grp->q, grp->g, theirpub2,
    +	if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub2,
     	    theirid, theirid_len, theirpub2_proof, theirpub2_proof_len) != 1)
     		fatal("%s: schnorr_verify theirpub2 failed", __func__);
     
    @@ -459,7 +304,7 @@ jpake_step2(struct jpake_group *grp, BIGNUM *s,
     	JPAKE_DEBUG_BN((exponent, "%s: exponent = ", __func__));
     
     	/* Note the generator here is 'tmp', not g */
    -	if (schnorr_sign(grp->p, grp->q, tmp, exponent, *newpub,
    +	if (schnorr_sign_buf(grp->p, grp->q, tmp, exponent, *newpub,
     	    myid, myid_len,
     	    newpub_exponent_proof, newpub_exponent_proof_len) != 0)
     		fatal("%s: schnorr_sign newpub", __func__);
    @@ -496,7 +341,7 @@ jpake_confirm_hash(const BIGNUM *k,
     
     /* Shared parts of key derivation and confirmation calculation */
     void
    -jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val,
    +jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
         BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
         BIGNUM *theirpub1, BIGNUM *theirpub2,
         const u_char *my_id, u_int my_id_len,
    @@ -531,7 +376,7 @@ jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val,
     
     	JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__));
     
    -	if (schnorr_verify(grp->p, grp->q, tmp, step2_val, 
    +	if (schnorr_verify_buf(grp->p, grp->q, tmp, step2_val, 
     	    their_id, their_id_len,
     	    theirpriv2_s_proof, theirpriv2_s_proof_len) != 1)
     		fatal("%s: schnorr_verify theirpriv2_s_proof failed", __func__);
    diff --git a/crypto/openssh/jpake.h b/crypto/openssh/jpake.h
    index a3d800cd3c4..a3f2cf0256c 100644
    --- a/crypto/openssh/jpake.h
    +++ b/crypto/openssh/jpake.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: jpake.h,v 1.1 2008/11/04 08:22:13 djm Exp $ */
    +/* $OpenBSD: jpake.h,v 1.2 2009/03/05 07:18:19 djm Exp $ */
     /*
      * Copyright (c) 2008 Damien Miller.  All rights reserved.
      *
    @@ -28,20 +28,16 @@
     # define JPAKE_DEBUG_BUF(a)
     # define JPAKE_DEBUG_CTX(a)
     #else
    -# define JPAKE_DEBUG_BN(a)	jpake_debug3_bn a
    -# define JPAKE_DEBUG_BUF(a)	jpake_debug3_buf a
    +# define JPAKE_DEBUG_BN(a)	debug3_bn a
    +# define JPAKE_DEBUG_BUF(a)	debug3_buf a
     # define JPAKE_DEBUG_CTX(a)	jpake_dump a
    -#endif /* SCHNORR_DEBUG */
    -
    -struct jpake_group {
    -	BIGNUM *p, *q, *g;
    -};
    +#endif /* JPAKE_DEBUG */
     
     #define KZP_ID_LEN	16	/* Length of client and server IDs */
     
     struct jpake_ctx {
     	/* Parameters */
    -	struct jpake_group *grp;
    +	struct modp_group *grp;
     
     	/* Private values shared by client and server */
     	BIGNUM *s;			/* Secret (salted, crypted password) */
    @@ -83,26 +79,18 @@ struct jpake_ctx {
     };
     
     /* jpake.c */
    -struct jpake_group *jpake_default_group(void);
    -BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
    -int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *);
    -void jpake_debug3_bn(const BIGNUM *, const char *, ...)
    -    __attribute__((__nonnull__ (2)))
    -    __attribute__((format(printf, 2, 3)));
    -void jpake_debug3_buf(const u_char *, u_int, const char *, ...)
    -    __attribute__((__nonnull__ (3)))
    -    __attribute__((format(printf, 3, 4)));
    +struct modp_group *jpake_default_group(void);
     void jpake_dump(struct jpake_ctx *, const char *, ...)
         __attribute__((__nonnull__ (2)))
         __attribute__((format(printf, 2, 3)));
     struct jpake_ctx *jpake_new(void);
     void jpake_free(struct jpake_ctx *);
     
    -void jpake_step1(struct jpake_group *, u_char **, u_int *,
    +void jpake_step1(struct modp_group *, u_char **, u_int *,
         BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
         u_char **, u_int *, u_char **, u_int *);
     
    -void jpake_step2(struct jpake_group *, BIGNUM *,
    +void jpake_step2(struct modp_group *, BIGNUM *,
         BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
         const u_char *, u_int, const u_char *, u_int,
         const u_char *, u_int, const u_char *, u_int,
    @@ -113,7 +101,7 @@ void jpake_confirm_hash(const BIGNUM *,
         const u_char *, u_int,
         u_char **, u_int *);
     
    -void jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
    +void jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *,
         BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
         const u_char *, u_int, const u_char *, u_int,
         const u_char *, u_int, const u_char *, u_int,
    @@ -122,13 +110,5 @@ void jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
     int jpake_check_confirm(const BIGNUM *, const u_char *, u_int,
         const u_char *, u_int, const u_char *, u_int);
     
    -/* schnorr.c */
    -int schnorr_sign(const BIGNUM *, const BIGNUM *, const BIGNUM *,
    -    const BIGNUM *, const BIGNUM *, const u_char *, u_int ,
    -    u_char **, u_int *);
    -int schnorr_verify(const BIGNUM *, const BIGNUM *, const BIGNUM *, 
    -    const BIGNUM *, const u_char *, u_int,
    -    const u_char *, u_int);
    -
     #endif /* JPAKE_H */
     
    diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c
    index 48b54f5f734..148cfee8046 100644
    --- a/crypto/openssh/kex.c
    +++ b/crypto/openssh/kex.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: kex.c,v 1.80 2008/09/06 12:24:13 djm Exp $ */
    +/* $OpenBSD: kex.c,v 1.82 2009/10/24 11:13:54 andreas Exp $ */
     /*
      * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
      *
    @@ -48,8 +48,7 @@
     #include "match.h"
     #include "dispatch.h"
     #include "monitor.h"
    -
    -#define KEX_COOKIE_LEN	16
    +#include "roaming.h"
     
     #if OPENSSL_VERSION_NUMBER >= 0x00907000L
     # if defined(HAVE_EVP_SHA256)
    @@ -388,6 +387,16 @@ kex_choose_conf(Kex *kex)
     		sprop=peer;
     	}
     
    +	/* Check whether server offers roaming */
    +	if (!kex->server) {
    +		char *roaming;
    +		roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL);
    +		if (roaming) {
    +			kex->roaming = 1;
    +			xfree(roaming);
    +		}
    +	}
    +
     	/* Algorithm Negotiation */
     	for (mode = 0; mode < MODE_MAX; mode++) {
     		newkeys = xcalloc(1, sizeof(*newkeys));
    diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h
    index 8e29c90e902..62fa2ea50f0 100644
    --- a/crypto/openssh/kex.h
    +++ b/crypto/openssh/kex.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: kex.h,v 1.46 2007/06/07 19:37:34 pvalchev Exp $ */
    +/* $OpenBSD: kex.h,v 1.49 2010/02/26 20:29:54 djm Exp $ */
     
     /*
      * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
    @@ -30,10 +30,13 @@
     #include 
     #include 
     
    +#define KEX_COOKIE_LEN	16
    +
     #define	KEX_DH1			"diffie-hellman-group1-sha1"
     #define	KEX_DH14		"diffie-hellman-group14-sha1"
     #define	KEX_DHGEX_SHA1		"diffie-hellman-group-exchange-sha1"
     #define	KEX_DHGEX_SHA256	"diffie-hellman-group-exchange-sha256"
    +#define	KEX_RESUME		"resume@appgate.com"
     
     #define COMP_NONE	0
     #define COMP_ZLIB	1
    @@ -114,6 +117,7 @@ struct Kex {
     	char	*name;
     	int	hostkey_type;
     	int	kex_type;
    +	int	roaming;
     	Buffer	my;
     	Buffer	peer;
     	sig_atomic_t done;
    @@ -122,7 +126,8 @@ struct Kex {
     	char	*client_version_string;
     	char	*server_version_string;
     	int	(*verify_host_key)(Key *);
    -	Key	*(*load_host_key)(int);
    +	Key	*(*load_host_public_key)(int);
    +	Key	*(*load_host_private_key)(int);
     	int	(*host_key_index)(Key *);
     	void	(*kex[KEX_MAX])(Kex *);
     };
    diff --git a/crypto/openssh/kexdhs.c b/crypto/openssh/kexdhs.c
    index 86170881845..e722877d5f8 100644
    --- a/crypto/openssh/kexdhs.c
    +++ b/crypto/openssh/kexdhs.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: kexdhs.c,v 1.9 2006/11/06 21:25:28 markus Exp $ */
    +/* $OpenBSD: kexdhs.c,v 1.11 2010/02/26 20:29:54 djm Exp $ */
     /*
      * Copyright (c) 2001 Markus Friedl.  All rights reserved.
      *
    @@ -50,7 +50,7 @@ kexdh_server(Kex *kex)
     {
     	BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
     	DH *dh;
    -	Key *server_host_key;
    +	Key *server_host_public, *server_host_private;
     	u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
     	u_int sbloblen, klen, hashlen, slen;
     	int kout;
    @@ -71,11 +71,16 @@ kexdh_server(Kex *kex)
     	debug("expecting SSH2_MSG_KEXDH_INIT");
     	packet_read_expect(SSH2_MSG_KEXDH_INIT);
     
    -	if (kex->load_host_key == NULL)
    +	if (kex->load_host_public_key == NULL ||
    +	    kex->load_host_private_key == NULL)
     		fatal("Cannot load hostkey");
    -	server_host_key = kex->load_host_key(kex->hostkey_type);
    -	if (server_host_key == NULL)
    +	server_host_public = kex->load_host_public_key(kex->hostkey_type);
    +	if (server_host_public == NULL)
     		fatal("Unsupported hostkey type %d", kex->hostkey_type);
    +	server_host_private = kex->load_host_private_key(kex->hostkey_type);
    +	if (server_host_private == NULL)
    +		fatal("Missing private key for hostkey type %d",
    +		    kex->hostkey_type);
     
     	/* key, cert */
     	if ((dh_client_pub = BN_new()) == NULL)
    @@ -113,7 +118,7 @@ kexdh_server(Kex *kex)
     	memset(kbuf, 0, klen);
     	xfree(kbuf);
     
    -	key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
    +	key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
     
     	/* calc H */
     	kex_dh_hash(
    @@ -137,7 +142,9 @@ kexdh_server(Kex *kex)
     	}
     
     	/* sign H */
    -	PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
    +	if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash,
    +	    hashlen)) < 0)
    +		fatal("kexdh_server: key_sign failed");
     
     	/* destroy_sensitive_data(); */
     
    diff --git a/crypto/openssh/kexgexs.c b/crypto/openssh/kexgexs.c
    index 76a0f8ca716..f4156af9636 100644
    --- a/crypto/openssh/kexgexs.c
    +++ b/crypto/openssh/kexgexs.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: kexgexs.c,v 1.11 2009/01/01 21:17:36 djm Exp $ */
    +/* $OpenBSD: kexgexs.c,v 1.13 2010/02/26 20:29:54 djm Exp $ */
     /*
      * Copyright (c) 2000 Niels Provos.  All rights reserved.
      * Copyright (c) 2001 Markus Friedl.  All rights reserved.
    @@ -52,18 +52,24 @@ void
     kexgex_server(Kex *kex)
     {
     	BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
    -	Key *server_host_key;
    +	Key *server_host_public, *server_host_private;
     	DH *dh;
     	u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
     	u_int sbloblen, klen, slen, hashlen;
     	int omin = -1, min = -1, omax = -1, max = -1, onbits = -1, nbits = -1;
     	int type, kout;
     
    -	if (kex->load_host_key == NULL)
    +	if (kex->load_host_public_key == NULL ||
    +	    kex->load_host_private_key == NULL)
     		fatal("Cannot load hostkey");
    -	server_host_key = kex->load_host_key(kex->hostkey_type);
    -	if (server_host_key == NULL)
    +	server_host_public = kex->load_host_public_key(kex->hostkey_type);
    +	if (server_host_public == NULL)
     		fatal("Unsupported hostkey type %d", kex->hostkey_type);
    +	server_host_private = kex->load_host_private_key(kex->hostkey_type);
    +	if (server_host_private == NULL)
    +		fatal("Missing private key for hostkey type %d",
    +		    kex->hostkey_type);
    +
     
     	type = packet_read();
     	switch (type) {
    @@ -149,7 +155,7 @@ kexgex_server(Kex *kex)
     	memset(kbuf, 0, klen);
     	xfree(kbuf);
     
    -	key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
    +	key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
     
     	if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
     		omin = min = omax = max = -1;
    @@ -179,7 +185,9 @@ kexgex_server(Kex *kex)
     	}
     
     	/* sign H */
    -	PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
    +	if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash,
    +	    hashlen)) < 0)
    +		fatal("kexgex_server: key_sign failed");
     
     	/* destroy_sensitive_data(); */
     
    diff --git a/crypto/openssh/key.c b/crypto/openssh/key.c
    index 3e17da60162..0d0c912e64f 100644
    --- a/crypto/openssh/key.c
    +++ b/crypto/openssh/key.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: key.c,v 1.80 2008/10/10 05:00:12 stevesk Exp $ */
    +/* $OpenBSD: key.c,v 1.85 2010/03/04 01:44:57 djm Exp $ */
     /*
      * read_bignum():
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -52,6 +52,21 @@
     #include "uuencode.h"
     #include "buffer.h"
     #include "log.h"
    +#include "ssh2.h"
    +
    +static struct KeyCert *
    +cert_new(void)
    +{
    +	struct KeyCert *cert;
    +
    +	cert = xcalloc(1, sizeof(*cert));
    +	buffer_init(&cert->certblob);
    +	buffer_init(&cert->constraints);
    +	cert->key_id = NULL;
    +	cert->principals = NULL;
    +	cert->signature_key = NULL;
    +	return cert;
    +}
     
     Key *
     key_new(int type)
    @@ -63,9 +78,11 @@ key_new(int type)
     	k->type = type;
     	k->dsa = NULL;
     	k->rsa = NULL;
    +	k->cert = NULL;
     	switch (k->type) {
     	case KEY_RSA1:
     	case KEY_RSA:
    +	case KEY_RSA_CERT:
     		if ((rsa = RSA_new()) == NULL)
     			fatal("key_new: RSA_new failed");
     		if ((rsa->n = BN_new()) == NULL)
    @@ -75,6 +92,7 @@ key_new(int type)
     		k->rsa = rsa;
     		break;
     	case KEY_DSA:
    +	case KEY_DSA_CERT:
     		if ((dsa = DSA_new()) == NULL)
     			fatal("key_new: DSA_new failed");
     		if ((dsa->p = BN_new()) == NULL)
    @@ -93,16 +111,20 @@ key_new(int type)
     		fatal("key_new: bad key type %d", k->type);
     		break;
     	}
    +
    +	if (key_is_cert(k))
    +		k->cert = cert_new();
    +
     	return k;
     }
     
    -Key *
    -key_new_private(int type)
    +void
    +key_add_private(Key *k)
     {
    -	Key *k = key_new(type);
     	switch (k->type) {
     	case KEY_RSA1:
     	case KEY_RSA:
    +	case KEY_RSA_CERT:
     		if ((k->rsa->d = BN_new()) == NULL)
     			fatal("key_new_private: BN_new failed");
     		if ((k->rsa->iqmp = BN_new()) == NULL)
    @@ -117,6 +139,7 @@ key_new_private(int type)
     			fatal("key_new_private: BN_new failed");
     		break;
     	case KEY_DSA:
    +	case KEY_DSA_CERT:
     		if ((k->dsa->priv_key = BN_new()) == NULL)
     			fatal("key_new_private: BN_new failed");
     		break;
    @@ -125,9 +148,34 @@ key_new_private(int type)
     	default:
     		break;
     	}
    +}
    +
    +Key *
    +key_new_private(int type)
    +{
    +	Key *k = key_new(type);
    +
    +	key_add_private(k);
     	return k;
     }
     
    +static void
    +cert_free(struct KeyCert *cert)
    +{
    +	u_int i;
    +
    +	buffer_free(&cert->certblob);
    +	buffer_free(&cert->constraints);
    +	if (cert->key_id != NULL)
    +		xfree(cert->key_id);
    +	for (i = 0; i < cert->nprincipals; i++)
    +		xfree(cert->principals[i]);
    +	if (cert->principals != NULL)
    +		xfree(cert->principals);
    +	if (cert->signature_key != NULL)
    +		key_free(cert->signature_key);
    +}
    +
     void
     key_free(Key *k)
     {
    @@ -136,11 +184,13 @@ key_free(Key *k)
     	switch (k->type) {
     	case KEY_RSA1:
     	case KEY_RSA:
    +	case KEY_RSA_CERT:
     		if (k->rsa != NULL)
     			RSA_free(k->rsa);
     		k->rsa = NULL;
     		break;
     	case KEY_DSA:
    +	case KEY_DSA_CERT:
     		if (k->dsa != NULL)
     			DSA_free(k->dsa);
     		k->dsa = NULL;
    @@ -151,20 +201,49 @@ key_free(Key *k)
     		fatal("key_free: bad key type %d", k->type);
     		break;
     	}
    +	if (key_is_cert(k)) {
    +		if (k->cert != NULL)
    +			cert_free(k->cert);
    +		k->cert = NULL;
    +	}
    +
     	xfree(k);
     }
     
    -int
    -key_equal(const Key *a, const Key *b)
    +static int
    +cert_compare(struct KeyCert *a, struct KeyCert *b)
     {
    -	if (a == NULL || b == NULL || a->type != b->type)
    +	if (a == NULL && b == NULL)
    +		return 1;
    +	if (a == NULL || b == NULL)
     		return 0;
    +	if (buffer_len(&a->certblob) != buffer_len(&b->certblob))
    +		return 0;
    +	if (memcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob),
    +	    buffer_len(&a->certblob)) != 0)
    +		return 0;
    +	return 1;
    +}
    +
    +/*
    + * Compare public portions of key only, allowing comparisons between
    + * certificates and plain keys too.
    + */
    +int
    +key_equal_public(const Key *a, const Key *b)
    +{
    +	if (a == NULL || b == NULL ||
    +	    key_type_plain(a->type) != key_type_plain(b->type))
    +		return 0;
    +
     	switch (a->type) {
     	case KEY_RSA1:
    +	case KEY_RSA_CERT:
     	case KEY_RSA:
     		return a->rsa != NULL && b->rsa != NULL &&
     		    BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
     		    BN_cmp(a->rsa->n, b->rsa->n) == 0;
    +	case KEY_DSA_CERT:
     	case KEY_DSA:
     		return a->dsa != NULL && b->dsa != NULL &&
     		    BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
    @@ -177,16 +256,27 @@ key_equal(const Key *a, const Key *b)
     	/* NOTREACHED */
     }
     
    +int
    +key_equal(const Key *a, const Key *b)
    +{
    +	if (a == NULL || b == NULL || a->type != b->type)
    +		return 0;
    +	if (key_is_cert(a)) {
    +		if (!cert_compare(a->cert, b->cert))
    +			return 0;
    +	}
    +	return key_equal_public(a, b);
    +}
    +
     u_char*
    -key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
    -    u_int *dgst_raw_length)
    +key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
     {
     	const EVP_MD *md = NULL;
     	EVP_MD_CTX ctx;
     	u_char *blob = NULL;
     	u_char *retval = NULL;
     	u_int len = 0;
    -	int nlen, elen;
    +	int nlen, elen, otype;
     
     	*dgst_raw_length = 0;
     
    @@ -214,6 +304,14 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
     	case KEY_RSA:
     		key_to_blob(k, &blob, &len);
     		break;
    +	case KEY_DSA_CERT:
    +	case KEY_RSA_CERT:
    +		/* We want a fingerprint of the _key_ not of the cert */
    +		otype = k->type;
    +		k->type = key_type_plain(k->type);
    +		key_to_blob(k, &blob, &len);
    +		k->type = otype;
    +		break;
     	case KEY_UNSPEC:
     		return retval;
     	default:
    @@ -408,7 +506,7 @@ key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
     }
     
     char *
    -key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
    +key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
     {
     	char *retval = NULL;
     	u_char *dgst_raw;
    @@ -522,11 +620,19 @@ key_read(Key *ret, char **cpp)
     			return -1;
     		if (!read_bignum(cpp, ret->rsa->n))
     			return -1;
    +		/* validate the claimed number of bits */
    +		if ((u_int)BN_num_bits(ret->rsa->n) != bits) {
    +			verbose("key_read: claimed key size %d does not match "
    +			   "actual %d", bits, BN_num_bits(ret->rsa->n));
    +			return -1;
    +		}
     		success = 1;
     		break;
     	case KEY_UNSPEC:
     	case KEY_RSA:
     	case KEY_DSA:
    +	case KEY_DSA_CERT:
    +	case KEY_RSA_CERT:
     		space = strchr(cp, ' ');
     		if (space == NULL) {
     			debug3("key_read: missing whitespace");
    @@ -571,25 +677,36 @@ key_read(Key *ret, char **cpp)
     			return -1;
     		}
     /*XXXX*/
    -		if (ret->type == KEY_RSA) {
    +		if (key_is_cert(ret)) {
    +			if (!key_is_cert(k)) {
    +				error("key_read: loaded key is not a cert");
    +				key_free(k);
    +				return -1;
    +			}
    +			if (ret->cert != NULL)
    +				cert_free(ret->cert);
    +			ret->cert = k->cert;
    +			k->cert = NULL;
    +		}
    +		if (key_type_plain(ret->type) == KEY_RSA) {
     			if (ret->rsa != NULL)
     				RSA_free(ret->rsa);
     			ret->rsa = k->rsa;
     			k->rsa = NULL;
    -			success = 1;
     #ifdef DEBUG_PK
     			RSA_print_fp(stderr, ret->rsa, 8);
     #endif
    -		} else {
    +		}
    +		if (key_type_plain(ret->type) == KEY_DSA) {
     			if (ret->dsa != NULL)
     				DSA_free(ret->dsa);
     			ret->dsa = k->dsa;
     			k->dsa = NULL;
    -			success = 1;
     #ifdef DEBUG_PK
     			DSA_print_fp(stderr, ret->dsa, 8);
     #endif
     		}
    +		success = 1;
     /*XXXX*/
     		key_free(k);
     		if (success != 1)
    @@ -616,28 +733,53 @@ key_write(const Key *key, FILE *f)
     	u_char *blob;
     	char *uu;
     
    -	if (key->type == KEY_RSA1 && key->rsa != NULL) {
    +	if (key_is_cert(key)) {
    +		if (key->cert == NULL) {
    +			error("%s: no cert data", __func__);
    +			return 0;
    +		}
    +		if (buffer_len(&key->cert->certblob) == 0) {
    +			error("%s: no signed certificate blob", __func__);
    +			return 0;
    +		}
    +	}
    +
    +	switch (key->type) {
    +	case KEY_RSA1:
    +		if (key->rsa == NULL)
    +			return 0;
     		/* size of modulus 'n' */
     		bits = BN_num_bits(key->rsa->n);
     		fprintf(f, "%u", bits);
     		if (write_bignum(f, key->rsa->e) &&
    -		    write_bignum(f, key->rsa->n)) {
    -			success = 1;
    -		} else {
    -			error("key_write: failed for RSA key");
    -		}
    -	} else if ((key->type == KEY_DSA && key->dsa != NULL) ||
    -	    (key->type == KEY_RSA && key->rsa != NULL)) {
    -		key_to_blob(key, &blob, &len);
    -		uu = xmalloc(2*len);
    -		n = uuencode(blob, len, uu, 2*len);
    -		if (n > 0) {
    -			fprintf(f, "%s %s", key_ssh_name(key), uu);
    -			success = 1;
    -		}
    -		xfree(blob);
    -		xfree(uu);
    +		    write_bignum(f, key->rsa->n))
    +			return 1;
    +		error("key_write: failed for RSA key");
    +		return 0;
    +	case KEY_DSA:
    +	case KEY_DSA_CERT:
    +		if (key->dsa == NULL)
    +			return 0;
    +		break;
    +	case KEY_RSA:
    +	case KEY_RSA_CERT:
    +		if (key->rsa == NULL)
    +			return 0;
    +		break;
    +	default:
    +		return 0;
     	}
    +
    +	key_to_blob(key, &blob, &len);
    +	uu = xmalloc(2*len);
    +	n = uuencode(blob, len, uu, 2*len);
    +	if (n > 0) {
    +		fprintf(f, "%s %s", key_ssh_name(key), uu);
    +		success = 1;
    +	}
    +	xfree(blob);
    +	xfree(uu);
    +
     	return success;
     }
     
    @@ -651,6 +793,10 @@ key_type(const Key *k)
     		return "RSA";
     	case KEY_DSA:
     		return "DSA";
    +	case KEY_RSA_CERT:
    +		return "RSA-CERT";
    +	case KEY_DSA_CERT:
    +		return "DSA-CERT";
     	}
     	return "unknown";
     }
    @@ -663,6 +809,10 @@ key_ssh_name(const Key *k)
     		return "ssh-rsa";
     	case KEY_DSA:
     		return "ssh-dss";
    +	case KEY_RSA_CERT:
    +		return "ssh-rsa-cert-v00@openssh.com";
    +	case KEY_DSA_CERT:
    +		return "ssh-dss-cert-v00@openssh.com";
     	}
     	return "ssh-unknown";
     }
    @@ -673,8 +823,10 @@ key_size(const Key *k)
     	switch (k->type) {
     	case KEY_RSA1:
     	case KEY_RSA:
    +	case KEY_RSA_CERT:
     		return BN_num_bits(k->rsa->n);
     	case KEY_DSA:
    +	case KEY_DSA_CERT:
     		return BN_num_bits(k->dsa->p);
     	}
     	return 0;
    @@ -685,7 +837,7 @@ rsa_generate_private_key(u_int bits)
     {
     	RSA *private;
     
    -	private = RSA_generate_key(bits, 35, NULL, NULL);
    +	private = RSA_generate_key(bits, RSA_F4, NULL, NULL);
     	if (private == NULL)
     		fatal("rsa_generate_private_key: key generation failed.");
     	return private;
    @@ -717,6 +869,9 @@ key_generate(int type, u_int bits)
     	case KEY_RSA1:
     		k->rsa = rsa_generate_private_key(bits);
     		break;
    +	case KEY_RSA_CERT:
    +	case KEY_DSA_CERT:
    +		fatal("key_generate: cert keys cannot be generated directly");
     	default:
     		fatal("key_generate: unknown type %d", type);
     	}
    @@ -724,12 +879,55 @@ key_generate(int type, u_int bits)
     	return k;
     }
     
    +void
    +key_cert_copy(const Key *from_key, struct Key *to_key)
    +{
    +	u_int i;
    +	const struct KeyCert *from;
    +	struct KeyCert *to;
    +
    +	if (to_key->cert != NULL) {
    +		cert_free(to_key->cert);
    +		to_key->cert = NULL;
    +	}
    +
    +	if ((from = from_key->cert) == NULL)
    +		return;
    +
    +	to = to_key->cert = cert_new();
    +
    +	buffer_append(&to->certblob, buffer_ptr(&from->certblob),
    +	    buffer_len(&from->certblob));
    +
    +	buffer_append(&to->constraints, buffer_ptr(&from->constraints),
    +	    buffer_len(&from->constraints));
    +
    +	to->type = from->type;
    +	to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id);
    +	to->valid_after = from->valid_after;
    +	to->valid_before = from->valid_before;
    +	to->signature_key = from->signature_key == NULL ?
    +	    NULL : key_from_private(from->signature_key);
    +
    +	to->nprincipals = from->nprincipals;
    +	if (to->nprincipals > CERT_MAX_PRINCIPALS)
    +		fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)",
    +		    __func__, to->nprincipals, CERT_MAX_PRINCIPALS);
    +	if (to->nprincipals > 0) {
    +		to->principals = xcalloc(from->nprincipals,
    +		    sizeof(*to->principals));
    +		for (i = 0; i < to->nprincipals; i++)
    +			to->principals[i] = xstrdup(from->principals[i]);
    +	}
    +}
    +
     Key *
     key_from_private(const Key *k)
     {
     	Key *n = NULL;
     	switch (k->type) {
     	case KEY_DSA:
    +	case KEY_DSA_CERT:
     		n = key_new(k->type);
     		if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
     		    (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
    @@ -739,6 +937,7 @@ key_from_private(const Key *k)
     		break;
     	case KEY_RSA:
     	case KEY_RSA1:
    +	case KEY_RSA_CERT:
     		n = key_new(k->type);
     		if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
     		    (BN_copy(n->rsa->e, k->rsa->e) == NULL))
    @@ -748,6 +947,8 @@ key_from_private(const Key *k)
     		fatal("key_from_private: unknown type %d", k->type);
     		break;
     	}
    +	if (key_is_cert(k))
    +		key_cert_copy(k, n);
     	return n;
     }
     
    @@ -764,6 +965,10 @@ key_type_from_name(char *name)
     		return KEY_RSA;
     	} else if (strcmp(name, "ssh-dss") == 0) {
     		return KEY_DSA;
    +	} else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) {
    +		return KEY_RSA_CERT;
    +	} else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) {
    +		return KEY_DSA_CERT;
     	}
     	debug2("key_type_from_name: unknown key type '%s'", name);
     	return KEY_UNSPEC;
    @@ -791,6 +996,127 @@ key_names_valid2(const char *names)
     	return 1;
     }
     
    +static int
    +cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
    +{
    +	u_char *principals, *constraints, *sig_key, *sig;
    +	u_int signed_len, plen, clen, sklen, slen, kidlen;
    +	Buffer tmp;
    +	char *principal;
    +	int ret = -1;
    +
    +	buffer_init(&tmp);
    +
    +	/* Copy the entire key blob for verification and later serialisation */
    +	buffer_append(&key->cert->certblob, blob, blen);
    +
    +	principals = constraints = sig_key = sig = NULL;
    +	if (buffer_get_int_ret(&key->cert->type, b) != 0 ||
    +	    (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL ||
    +	    (principals = buffer_get_string_ret(b, &plen)) == NULL ||
    +	    buffer_get_int64_ret(&key->cert->valid_after, b) != 0 ||
    +	    buffer_get_int64_ret(&key->cert->valid_before, b) != 0 ||
    +	    (constraints = buffer_get_string_ret(b, &clen)) == NULL ||
    +	    /* skip nonce */ buffer_get_string_ptr_ret(b, NULL) == NULL ||
    +	    /* skip reserved */ buffer_get_string_ptr_ret(b, NULL) == NULL ||
    +	    (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) {
    +		error("%s: parse error", __func__);
    +		goto out;
    +	}
    +
    +	if (kidlen != strlen(key->cert->key_id)) {
    +		error("%s: key ID contains \\0 character", __func__);
    +		goto out;
    +	}
    +
    +	/* Signature is left in the buffer so we can calculate this length */
    +	signed_len = buffer_len(&key->cert->certblob) - buffer_len(b);
    +
    +	if ((sig = buffer_get_string_ret(b, &slen)) == NULL) {
    +		error("%s: parse error", __func__);
    +		goto out;
    +	}
    +
    +	if (key->cert->type != SSH2_CERT_TYPE_USER &&
    +	    key->cert->type != SSH2_CERT_TYPE_HOST) {
    +		error("Unknown certificate type %u", key->cert->type);
    +		goto out;
    +	}
    +
    +	buffer_append(&tmp, principals, plen);
    +	while (buffer_len(&tmp) > 0) {
    +		if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) {
    +			error("%s: Too many principals", __func__);
    +			goto out;
    +		}
    +		if ((principal = buffer_get_string_ret(&tmp, &plen)) == NULL) {
    +			error("%s: Principals data invalid", __func__);
    +			goto out;
    +		}
    +		if (strlen(principal) != plen) {
    +			error("%s: Principal contains \\0 character",
    +			    __func__);
    +			goto out;
    +		}
    +		key->cert->principals = xrealloc(key->cert->principals,
    +		    key->cert->nprincipals + 1, sizeof(*key->cert->principals));
    +		key->cert->principals[key->cert->nprincipals++] = principal;
    +	}
    +
    +	buffer_clear(&tmp);
    +
    +	buffer_append(&key->cert->constraints, constraints, clen);
    +	buffer_append(&tmp, constraints, clen);
    +	/* validate structure */
    +	while (buffer_len(&tmp) != 0) {
    +		if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
    +		    buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
    +			error("%s: Constraints data invalid", __func__);
    +			goto out;
    +		}
    +	}
    +	buffer_clear(&tmp);
    +
    +	if ((key->cert->signature_key = key_from_blob(sig_key,
    +	    sklen)) == NULL) {
    +		error("%s: Signature key invalid", __func__);
    +		goto out;
    +	}
    +	if (key->cert->signature_key->type != KEY_RSA &&
    +	    key->cert->signature_key->type != KEY_DSA) {
    +		error("%s: Invalid signature key type %s (%d)", __func__,
    +		    key_type(key->cert->signature_key),
    +		    key->cert->signature_key->type);
    +		goto out;
    +	}
    +
    +	switch (key_verify(key->cert->signature_key, sig, slen, 
    +	    buffer_ptr(&key->cert->certblob), signed_len)) {
    +	case 1:
    +		ret = 0;
    +		break; /* Good signature */
    +	case 0:
    +		error("%s: Invalid signature on certificate", __func__);
    +		goto out;
    +	case -1:
    +		error("%s: Certificate signature verification failed",
    +		    __func__);
    +		goto out;
    +	}
    +
    + out:
    +	buffer_free(&tmp);
    +	if (principals != NULL)
    +		xfree(principals);
    +	if (constraints != NULL)
    +		xfree(constraints);
    +	if (sig_key != NULL)
    +		xfree(sig_key);
    +	if (sig != NULL)
    +		xfree(sig);
    +	return ret;
    +}
    +
     Key *
     key_from_blob(const u_char *blob, u_int blen)
     {
    @@ -813,10 +1139,12 @@ key_from_blob(const u_char *blob, u_int blen)
     
     	switch (type) {
     	case KEY_RSA:
    +	case KEY_RSA_CERT:
     		key = key_new(type);
     		if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
     		    buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
     			error("key_from_blob: can't read rsa key");
    + badkey:
     			key_free(key);
     			key = NULL;
     			goto out;
    @@ -826,15 +1154,14 @@ key_from_blob(const u_char *blob, u_int blen)
     #endif
     		break;
     	case KEY_DSA:
    +	case KEY_DSA_CERT:
     		key = key_new(type);
     		if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
     		    buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
     		    buffer_get_bignum2_ret(&b, key->dsa->g) == -1 ||
     		    buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) {
     			error("key_from_blob: can't read dsa key");
    -			key_free(key);
    -			key = NULL;
    -			goto out;
    +			goto badkey;
     		}
     #ifdef DEBUG_PK
     		DSA_print_fp(stderr, key->dsa, 8);
    @@ -847,6 +1174,10 @@ key_from_blob(const u_char *blob, u_int blen)
     		error("key_from_blob: cannot handle type %s", ktype);
     		goto out;
     	}
    +	if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) {
    +		error("key_from_blob: can't parse cert data");
    +		goto badkey;
    +	}
     	rlen = buffer_len(&b);
     	if (key != NULL && rlen != 0)
     		error("key_from_blob: remaining bytes in key blob %d", rlen);
    @@ -869,6 +1200,12 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
     	}
     	buffer_init(&b);
     	switch (key->type) {
    +	case KEY_DSA_CERT:
    +	case KEY_RSA_CERT:
    +		/* Use the existing blob */
    +		buffer_append(&b, buffer_ptr(&key->cert->certblob),
    +		    buffer_len(&key->cert->certblob));
    +		break;
     	case KEY_DSA:
     		buffer_put_cstring(&b, key_ssh_name(key));
     		buffer_put_bignum2(&b, key->dsa->p);
    @@ -905,8 +1242,10 @@ key_sign(
         const u_char *data, u_int datalen)
     {
     	switch (key->type) {
    +	case KEY_DSA_CERT:
     	case KEY_DSA:
     		return ssh_dss_sign(key, sigp, lenp, data, datalen);
    +	case KEY_RSA_CERT:
     	case KEY_RSA:
     		return ssh_rsa_sign(key, sigp, lenp, data, datalen);
     	default:
    @@ -929,8 +1268,10 @@ key_verify(
     		return -1;
     
     	switch (key->type) {
    +	case KEY_DSA_CERT:
     	case KEY_DSA:
     		return ssh_dss_verify(key, signature, signaturelen, data, datalen);
    +	case KEY_RSA_CERT:
     	case KEY_RSA:
     		return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
     	default:
    @@ -952,6 +1293,9 @@ key_demote(const Key *k)
     	pk->rsa = NULL;
     
     	switch (k->type) {
    +	case KEY_RSA_CERT:
    +		key_cert_copy(k, pk);
    +		/* FALLTHROUGH */
     	case KEY_RSA1:
     	case KEY_RSA:
     		if ((pk->rsa = RSA_new()) == NULL)
    @@ -961,6 +1305,9 @@ key_demote(const Key *k)
     		if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
     			fatal("key_demote: BN_dup failed");
     		break;
    +	case KEY_DSA_CERT:
    +		key_cert_copy(k, pk);
    +		/* FALLTHROUGH */
     	case KEY_DSA:
     		if ((pk->dsa = DSA_new()) == NULL)
     			fatal("key_demote: DSA_new failed");
    @@ -980,3 +1327,199 @@ key_demote(const Key *k)
     
     	return (pk);
     }
    +
    +int
    +key_is_cert(const Key *k)
    +{
    +	return k != NULL &&
    +	    (k->type == KEY_RSA_CERT || k->type == KEY_DSA_CERT);
    +}
    +
    +/* Return the cert-less equivalent to a certified key type */
    +int
    +key_type_plain(int type)
    +{
    +	switch (type) {
    +	case KEY_RSA_CERT:
    +		return KEY_RSA;
    +	case KEY_DSA_CERT:
    +		return KEY_DSA;
    +	default:
    +		return type;
    +	}
    +}
    +
    +/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */
    +int
    +key_to_certified(Key *k)
    +{
    +	switch (k->type) {
    +	case KEY_RSA:
    +		k->cert = cert_new();
    +		k->type = KEY_RSA_CERT;
    +		return 0;
    +	case KEY_DSA:
    +		k->cert = cert_new();
    +		k->type = KEY_DSA_CERT;
    +		return 0;
    +	default:
    +		error("%s: key has incorrect type %s", __func__, key_type(k));
    +		return -1;
    +	}
    +}
    +
    +/* Convert a KEY_RSA_CERT or KEY_DSA_CERT to their raw key equivalent */
    +int
    +key_drop_cert(Key *k)
    +{
    +	switch (k->type) {
    +	case KEY_RSA_CERT:
    +		cert_free(k->cert);
    +		k->type = KEY_RSA;
    +		return 0;
    +	case KEY_DSA_CERT:
    +		cert_free(k->cert);
    +		k->type = KEY_DSA;
    +		return 0;
    +	default:
    +		error("%s: key has incorrect type %s", __func__, key_type(k));
    +		return -1;
    +	}
    +}
    +
    +/* Sign a KEY_RSA_CERT or KEY_DSA_CERT, (re-)generating the signed certblob */
    +int
    +key_certify(Key *k, Key *ca)
    +{
    +	Buffer principals;
    +	u_char *ca_blob, *sig_blob, nonce[32];
    +	u_int i, ca_len, sig_len;
    +
    +	if (k->cert == NULL) {
    +		error("%s: key lacks cert info", __func__);
    +		return -1;
    +	}
    +
    +	if (!key_is_cert(k)) {
    +		error("%s: certificate has unknown type %d", __func__,
    +		    k->cert->type);
    +		return -1;
    +	}
    +
    +	if (ca->type != KEY_RSA && ca->type != KEY_DSA) {
    +		error("%s: CA key has unsupported type %s", __func__,
    +		    key_type(ca));
    +		return -1;
    +	}
    +
    +	key_to_blob(ca, &ca_blob, &ca_len);
    +
    +	buffer_clear(&k->cert->certblob);
    +	buffer_put_cstring(&k->cert->certblob, key_ssh_name(k));
    +
    +	switch (k->type) {
    +	case KEY_DSA_CERT:
    +		buffer_put_bignum2(&k->cert->certblob, k->dsa->p);
    +		buffer_put_bignum2(&k->cert->certblob, k->dsa->q);
    +		buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
    +		buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
    +		break;
    +	case KEY_RSA_CERT:
    +		buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
    +		buffer_put_bignum2(&k->cert->certblob, k->rsa->n);
    +		break;
    +	default:
    +		error("%s: key has incorrect type %s", __func__, key_type(k));
    +		buffer_clear(&k->cert->certblob);
    +		xfree(ca_blob);
    +		return -1;
    +	}
    +
    +	buffer_put_int(&k->cert->certblob, k->cert->type);
    +	buffer_put_cstring(&k->cert->certblob, k->cert->key_id);
    +
    +	buffer_init(&principals);
    +	for (i = 0; i < k->cert->nprincipals; i++)
    +		buffer_put_cstring(&principals, k->cert->principals[i]);
    +	buffer_put_string(&k->cert->certblob, buffer_ptr(&principals),
    +	    buffer_len(&principals));
    +	buffer_free(&principals);
    +
    +	buffer_put_int64(&k->cert->certblob, k->cert->valid_after);
    +	buffer_put_int64(&k->cert->certblob, k->cert->valid_before);
    +	buffer_put_string(&k->cert->certblob,
    +	    buffer_ptr(&k->cert->constraints),
    +	    buffer_len(&k->cert->constraints));
    +
    +	arc4random_buf(&nonce, sizeof(nonce));
    +	buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
    +	buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */
    +	buffer_put_string(&k->cert->certblob, ca_blob, ca_len);
    +	xfree(ca_blob);
    +
    +	/* Sign the whole mess */
    +	if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob),
    +	    buffer_len(&k->cert->certblob)) != 0) {
    +		error("%s: signature operation failed", __func__);
    +		buffer_clear(&k->cert->certblob);
    +		return -1;
    +	}
    +	/* Append signature and we are done */
    +	buffer_put_string(&k->cert->certblob, sig_blob, sig_len);
    +	xfree(sig_blob);
    +
    +	return 0;
    +}
    +
    +int
    +key_cert_check_authority(const Key *k, int want_host, int require_principal,
    +    const char *name, const char **reason)
    +{
    +	u_int i, principal_matches;
    +	time_t now = time(NULL);
    +
    +	if (want_host) {
    +		if (k->cert->type != SSH2_CERT_TYPE_HOST) {
    +			*reason = "Certificate invalid: not a host certificate";
    +			return -1;
    +		}
    +	} else {
    +		if (k->cert->type != SSH2_CERT_TYPE_USER) {
    +			*reason = "Certificate invalid: not a user certificate";
    +			return -1;
    +		}
    +	}
    +	if (now < 0) {
    +		error("%s: system clock lies before epoch", __func__);
    +		*reason = "Certificate invalid: not yet valid";
    +		return -1;
    +	}
    +	if ((u_int64_t)now < k->cert->valid_after) {
    +		*reason = "Certificate invalid: not yet valid";
    +		return -1;
    +	}
    +	if ((u_int64_t)now >= k->cert->valid_before) {
    +		*reason = "Certificate invalid: expired";
    +		return -1;
    +	}
    +	if (k->cert->nprincipals == 0) {
    +		if (require_principal) {
    +			*reason = "Certificate lacks principal list";
    +			return -1;
    +		}
    +	} else {
    +		principal_matches = 0;
    +		for (i = 0; i < k->cert->nprincipals; i++) {
    +			if (strcmp(name, k->cert->principals[i]) == 0) {
    +				principal_matches = 1;
    +				break;
    +			}
    +		}
    +		if (!principal_matches) {
    +			*reason = "Certificate invalid: name is not a listed "
    +			    "principal";
    +			return -1;
    +		}
    +	}
    +	return 0;
    +}
    diff --git a/crypto/openssh/key.h b/crypto/openssh/key.h
    index 14aac79c2de..6a2e049af11 100644
    --- a/crypto/openssh/key.h
    +++ b/crypto/openssh/key.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: key.h,v 1.27 2008/06/11 21:01:35 grunk Exp $ */
    +/* $OpenBSD: key.h,v 1.28 2010/02/26 20:29:54 djm Exp $ */
     
     /*
      * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
    @@ -26,6 +26,7 @@
     #ifndef KEY_H
     #define KEY_H
     
    +#include "buffer.h"
     #include 
     #include 
     
    @@ -34,6 +35,8 @@ enum types {
     	KEY_RSA1,
     	KEY_RSA,
     	KEY_DSA,
    +	KEY_RSA_CERT,
    +	KEY_DSA_CERT,
     	KEY_UNSPEC
     };
     enum fp_type {
    @@ -49,20 +52,35 @@ enum fp_rep {
     /* key is stored in external hardware */
     #define KEY_FLAG_EXT		0x0001
     
    +#define CERT_MAX_PRINCIPALS	256
    +struct KeyCert {
    +	Buffer		 certblob; /* Kept around for use on wire */
    +	u_int		 type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
    +	char		*key_id;
    +	u_int		 nprincipals;
    +	char		**principals;
    +	u_int64_t	 valid_after, valid_before;
    +	Buffer		 constraints;
    +	Key		*signature_key;
    +};
    +
     struct Key {
     	int	 type;
     	int	 flags;
     	RSA	*rsa;
     	DSA	*dsa;
    +	struct KeyCert *cert;
     };
     
     Key		*key_new(int);
    +void		 key_add_private(Key *);
     Key		*key_new_private(int);
     void		 key_free(Key *);
     Key		*key_demote(const Key *);
    +int		 key_equal_public(const Key *, const Key *);
     int		 key_equal(const Key *, const Key *);
    -char		*key_fingerprint(const Key *, enum fp_type, enum fp_rep);
    -u_char		*key_fingerprint_raw(const Key *, enum fp_type, u_int *);
    +char		*key_fingerprint(Key *, enum fp_type, enum fp_rep);
    +u_char		*key_fingerprint_raw(Key *, enum fp_type, u_int *);
     const char	*key_type(const Key *);
     int		 key_write(const Key *, FILE *);
     int		 key_read(Key *, char **);
    @@ -71,6 +89,14 @@ u_int		 key_size(const Key *);
     Key	*key_generate(int, u_int);
     Key	*key_from_private(const Key *);
     int	 key_type_from_name(char *);
    +int	 key_is_cert(const Key *);
    +int	 key_type_plain(int);
    +int	 key_to_certified(Key *);
    +int	 key_drop_cert(Key *);
    +int	 key_certify(Key *, Key *);
    +void	 key_cert_copy(const Key *, struct Key *);
    +int	 key_cert_check_authority(const Key *, int, int, const char *,
    +	    const char **);
     
     Key		*key_from_blob(const u_char *, u_int);
     int		 key_to_blob(const Key *, u_char **, u_int *);
    diff --git a/crypto/openssh/loginrec.c b/crypto/openssh/loginrec.c
    index f4af0673601..57413db078c 100644
    --- a/crypto/openssh/loginrec.c
    +++ b/crypto/openssh/loginrec.c
    @@ -1316,8 +1316,8 @@ wtmpx_write_entry(struct logininfo *li)
     static int
     wtmpx_islogin(struct logininfo *li, struct utmpx *utx)
     {
    -	if (strncmp(li->username, utx->ut_name,
    -	    MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) {
    +	if (strncmp(li->username, utx->ut_user,
    +	    MIN_SIZEOF(li->username, utx->ut_user)) == 0 ) {
     # ifdef HAVE_TYPE_IN_UTMPX
     		if (utx->ut_type == USER_PROCESS)
     			return (1);
    diff --git a/crypto/openssh/match.h b/crypto/openssh/match.h
    index 18f6830703b..3d7f70fc01b 100644
    --- a/crypto/openssh/match.h
    +++ b/crypto/openssh/match.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: match.h,v 1.14 2008/06/10 03:57:27 djm Exp $ */
    +/* $OpenBSD: match.h,v 1.15 2010/02/26 20:29:54 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -23,5 +23,5 @@ char	*match_list(const char *, const char *, u_int *);
     
     /* addrmatch.c */
     int	 addr_match_list(const char *, const char *);
    -
    +int	 addr_match_cidr_list(const char *, const char *);
     #endif
    diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c
    index 143dbf0e2d0..e1f723123eb 100644
    --- a/crypto/openssh/misc.c
    +++ b/crypto/openssh/misc.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: misc.c,v 1.71 2009/02/21 19:32:04 tobias Exp $ */
    +/* $OpenBSD: misc.c,v 1.75 2010/01/09 23:04:13 dtucker Exp $ */
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
      * Copyright (c) 2005,2006 Damien Miller.  All rights reserved.
    @@ -560,11 +560,11 @@ char *
     percent_expand(const char *string, ...)
     {
     #define EXPAND_MAX_KEYS	16
    +	u_int num_keys, i, j;
     	struct {
     		const char *key;
     		const char *repl;
     	} keys[EXPAND_MAX_KEYS];
    -	u_int num_keys, i, j;
     	char buf[4096];
     	va_list ap;
     
    @@ -576,13 +576,12 @@ percent_expand(const char *string, ...)
     			break;
     		keys[num_keys].repl = va_arg(ap, char *);
     		if (keys[num_keys].repl == NULL)
    -			fatal("percent_expand: NULL replacement");
    +			fatal("%s: NULL replacement", __func__);
     	}
    +	if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)
    +		fatal("%s: too many keys", __func__);
     	va_end(ap);
     
    -	if (num_keys >= EXPAND_MAX_KEYS)
    -		fatal("percent_expand: too many keys");
    -
     	/* Expand string */
     	*buf = '\0';
     	for (i = 0; *string != '\0'; string++) {
    @@ -590,23 +589,24 @@ percent_expand(const char *string, ...)
      append:
     			buf[i++] = *string;
     			if (i >= sizeof(buf))
    -				fatal("percent_expand: string too long");
    +				fatal("%s: string too long", __func__);
     			buf[i] = '\0';
     			continue;
     		}
     		string++;
    +		/* %% case */
     		if (*string == '%')
     			goto append;
     		for (j = 0; j < num_keys; j++) {
     			if (strchr(keys[j].key, *string) != NULL) {
     				i = strlcat(buf, keys[j].repl, sizeof(buf));
     				if (i >= sizeof(buf))
    -					fatal("percent_expand: string too long");
    +					fatal("%s: string too long", __func__);
     				break;
     			}
     		}
     		if (j >= num_keys)
    -			fatal("percent_expand: unknown key %%%c", *string);
    +			fatal("%s: unknown key %%%c", __func__, *string);
     	}
     	return (xstrdup(buf));
     #undef EXPAND_MAX_KEYS
    @@ -849,3 +849,14 @@ ms_to_timeval(struct timeval *tv, int ms)
     	tv->tv_usec = (ms % 1000) * 1000;
     }
     
    +void
    +sock_set_v6only(int s)
    +{
    +#ifdef IPV6_V6ONLY
    +	int on = 1;
    +
    +	debug3("%s: set socket %d IPV6_V6ONLY", __func__, s);
    +	if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1)
    +		error("setsockopt IPV6_V6ONLY: %s", strerror(errno));
    +#endif
    +}
    diff --git a/crypto/openssh/misc.h b/crypto/openssh/misc.h
    index 5da170d2fd8..32073acd417 100644
    --- a/crypto/openssh/misc.h
    +++ b/crypto/openssh/misc.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: misc.h,v 1.38 2008/06/12 20:38:28 dtucker Exp $ */
    +/* $OpenBSD: misc.h,v 1.41 2010/01/09 23:04:13 dtucker Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -35,6 +35,7 @@ char	*tohex(const void *, size_t);
     void	 sanitise_stdfd(void);
     void	 ms_subtract_diff(struct timeval *, int *);
     void	 ms_to_timeval(struct timeval *, int);
    +void	 sock_set_v6only(int);
     
     struct passwd *pwcopy(struct passwd *);
     const char *ssh_gai_strerror(int);
    diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c
    index f57e74ba5ce..334aedde591 100644
    --- a/crypto/openssh/monitor.c
    +++ b/crypto/openssh/monitor.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: monitor.c,v 1.101 2009/02/12 03:26:22 djm Exp $ */
    +/* $OpenBSD: monitor.c,v 1.106 2010/03/07 11:57:13 dtucker Exp $ */
     /*
      * Copyright 2002 Niels Provos 
      * Copyright 2002 Markus Friedl 
    @@ -88,6 +88,7 @@
     #include "compat.h"
     #include "ssh2.h"
     #include "jpake.h"
    +#include "roaming.h"
     
     #ifdef GSSAPI
     static Gssctxt *gsscontext = NULL;
    @@ -100,7 +101,6 @@ extern Newkeys *current_keys[];
     extern z_stream incoming_stream;
     extern z_stream outgoing_stream;
     extern u_char session_id[];
    -extern Buffer input, output;
     extern Buffer auth_debug;
     extern int auth_debug_init;
     extern Buffer loginmsg;
    @@ -126,6 +126,8 @@ struct {
     	u_int ilen;
     	u_char *output;
     	u_int olen;
    +	u_int64_t sent_bytes;
    +	u_int64_t recv_bytes;
     } child_state;
     
     /* Functions on the monitor that answer unprivileged requests */
    @@ -995,17 +997,6 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
     }
     #endif
     
    -static void
    -mm_append_debug(Buffer *m)
    -{
    -	if (auth_debug_init && buffer_len(&auth_debug)) {
    -		debug3("%s: Appending debug messages for child", __func__);
    -		buffer_append(m, buffer_ptr(&auth_debug),
    -		    buffer_len(&auth_debug));
    -		buffer_clear(&auth_debug);
    -	}
    -}
    -
     int
     mm_answer_keyallowed(int sock, Buffer *m)
     {
    @@ -1088,8 +1079,6 @@ mm_answer_keyallowed(int sock, Buffer *m)
     	buffer_put_int(m, allowed);
     	buffer_put_int(m, forced_command != NULL);
     
    -	mm_append_debug(m);
    -
     	mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m);
     
     	if (type == MM_RSAHOSTKEY)
    @@ -1473,8 +1462,6 @@ mm_answer_rsa_keyallowed(int sock, Buffer *m)
     	if (key != NULL)
     		key_free(key);
     
    -	mm_append_debug(m);
    -
     	mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m);
     
     	monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
    @@ -1670,15 +1657,20 @@ monitor_apply_keystate(struct monitor *pmonitor)
     
     	/* Network I/O buffers */
     	/* XXX inefficient for large buffers, need: buffer_init_from_string */
    -	buffer_clear(&input);
    -	buffer_append(&input, child_state.input, child_state.ilen);
    +	buffer_clear(packet_get_input());
    +	buffer_append(packet_get_input(), child_state.input, child_state.ilen);
     	memset(child_state.input, 0, child_state.ilen);
     	xfree(child_state.input);
     
    -	buffer_clear(&output);
    -	buffer_append(&output, child_state.output, child_state.olen);
    +	buffer_clear(packet_get_output());
    +	buffer_append(packet_get_output(), child_state.output,
    +		      child_state.olen);
     	memset(child_state.output, 0, child_state.olen);
     	xfree(child_state.output);
    +
    +	/* Roaming */
    +	if (compat20)
    +		roam_set_bytes(child_state.sent_bytes, child_state.recv_bytes);
     }
     
     static Kex *
    @@ -1714,7 +1706,8 @@ mm_get_kex(Buffer *m)
     	kex->flags = buffer_get_int(m);
     	kex->client_version_string = buffer_get_string(m, NULL);
     	kex->server_version_string = buffer_get_string(m, NULL);
    -	kex->load_host_key=&get_hostkey_by_type;
    +	kex->load_host_public_key=&get_hostkey_public_by_type;
    +	kex->load_host_private_key=&get_hostkey_private_by_type;
     	kex->host_key_index=&get_hostkey_index;
     
     	return (kex);
    @@ -1794,6 +1787,12 @@ mm_get_keystate(struct monitor *pmonitor)
     	child_state.input = buffer_get_string(&m, &child_state.ilen);
     	child_state.output = buffer_get_string(&m, &child_state.olen);
     
    +	/* Roaming */
    +	if (compat20) {
    +		child_state.sent_bytes = buffer_get_int64(&m);
    +		child_state.recv_bytes = buffer_get_int64(&m);
    +	}
    +
     	buffer_free(&m);
     }
     
    diff --git a/crypto/openssh/monitor_fdpass.c b/crypto/openssh/monitor_fdpass.c
    index 4b9a066bcf0..7eb6f5c6e1f 100644
    --- a/crypto/openssh/monitor_fdpass.c
    +++ b/crypto/openssh/monitor_fdpass.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: monitor_fdpass.c,v 1.18 2008/11/30 11:59:26 dtucker Exp $ */
    +/* $OpenBSD: monitor_fdpass.c,v 1.19 2010/01/12 00:58:25 djm Exp $ */
     /*
      * Copyright 2001 Niels Provos 
      * All rights reserved.
    @@ -34,6 +34,9 @@
     #endif
     
     #include 
    +#ifdef HAVE_POLL_H
    +#include 
    +#endif
     #include 
     #include 
     
    @@ -55,6 +58,7 @@ mm_send_fd(int sock, int fd)
     	struct iovec vec;
     	char ch = '\0';
     	ssize_t n;
    +	struct pollfd pfd;
     
     	memset(&msg, 0, sizeof(msg));
     #ifdef HAVE_ACCRIGHTS_IN_MSGHDR
    @@ -75,9 +79,13 @@ mm_send_fd(int sock, int fd)
     	msg.msg_iov = &vec;
     	msg.msg_iovlen = 1;
     
    -	while ((n = sendmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN ||
    -	    errno == EINTR))
    +	pfd.fd = sock;
    +	pfd.events = POLLOUT;
    +	while ((n = sendmsg(sock, &msg, 0)) == -1 &&
    +	    (errno == EAGAIN || errno == EINTR)) {
     		debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno));
    +		(void)poll(&pfd, 1, -1);
    +	}
     	if (n == -1) {
     		error("%s: sendmsg(%d): %s", __func__, fd,
     		    strerror(errno));
    @@ -112,6 +120,7 @@ mm_receive_fd(int sock)
     	ssize_t n;
     	char ch;
     	int fd;
    +	struct pollfd pfd;
     
     	memset(&msg, 0, sizeof(msg));
     	vec.iov_base = &ch;
    @@ -126,9 +135,13 @@ mm_receive_fd(int sock)
     	msg.msg_controllen = sizeof(cmsgbuf.buf);
     #endif
     
    -	while ((n = recvmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN ||
    -	    errno == EINTR))
    +	pfd.fd = sock;
    +	pfd.events = POLLIN;
    +	while ((n = recvmsg(sock, &msg, 0)) == -1 &&
    +	    (errno == EAGAIN || errno == EINTR)) {
     		debug3("%s: recvmsg: %s", __func__, strerror(errno));
    +		(void)poll(&pfd, 1, -1);
    +	}
     	if (n == -1) {
     		error("%s: recvmsg: %s", __func__, strerror(errno));
     		return -1;
    diff --git a/crypto/openssh/monitor_mm.c b/crypto/openssh/monitor_mm.c
    index dab747532a0..faf9f3dcb4f 100644
    --- a/crypto/openssh/monitor_mm.c
    +++ b/crypto/openssh/monitor_mm.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: monitor_mm.c,v 1.15 2006/08/03 03:34:42 deraadt Exp $ */
    +/* $OpenBSD: monitor_mm.c,v 1.16 2009/06/22 05:39:28 dtucker Exp $ */
     /*
      * Copyright 2002 Niels Provos 
      * All rights reserved.
    diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c
    index 0986fc51827..faeb02cfa35 100644
    --- a/crypto/openssh/monitor_wrap.c
    +++ b/crypto/openssh/monitor_wrap.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: monitor_wrap.c,v 1.64 2008/11/04 08:22:13 djm Exp $ */
    +/* $OpenBSD: monitor_wrap.c,v 1.69 2010/03/07 11:57:13 dtucker Exp $ */
     /*
      * Copyright 2002 Niels Provos 
      * Copyright 2002 Markus Friedl 
    @@ -71,19 +71,19 @@
     #include "atomicio.h"
     #include "monitor_fdpass.h"
     #include "misc.h"
    +#include "schnorr.h"
     #include "jpake.h"
     
     #include "channels.h"
     #include "session.h"
     #include "servconf.h"
    +#include "roaming.h"
     
     /* Imports */
     extern int compat20;
    -extern Newkeys *newkeys[];
     extern z_stream incoming_stream;
     extern z_stream outgoing_stream;
     extern struct monitor *pmonitor;
    -extern Buffer input, output;
     extern Buffer loginmsg;
     extern ServerOptions options;
     
    @@ -347,19 +347,6 @@ mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
     	return (ret);
     }
     
    -static void
    -mm_send_debug(Buffer *m)
    -{
    -	char *msg;
    -
    -	while (buffer_len(m)) {
    -		msg = buffer_get_string(m, NULL);
    -		debug3("%s: Sending debug: %s", __func__, msg);
    -		packet_send_debug("%s", msg);
    -		xfree(msg);
    -	}
    -}
    -
     int
     mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
     {
    @@ -393,9 +380,6 @@ mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
     	have_forced = buffer_get_int(&m);
     	forced_command = have_forced ? xstrdup("true") : NULL;
     
    -	/* Send potential debug messages */
    -	mm_send_debug(&m);
    -
     	buffer_free(&m);
     
     	return (allowed);
    @@ -508,7 +492,7 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
     	Enc *enc;
     	Mac *mac;
     	Comp *comp;
    -	Newkeys *newkey = newkeys[mode];
    +	Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode);
     
     	debug3("%s: converting %p", __func__, newkey);
     
    @@ -570,7 +554,7 @@ mm_send_kex(Buffer *m, Kex *kex)
     void
     mm_send_keystate(struct monitor *monitor)
     {
    -	Buffer m;
    +	Buffer m, *input, *output;
     	u_char *blob, *p;
     	u_int bloblen, plen;
     	u_int32_t seqnr, packets;
    @@ -608,7 +592,8 @@ mm_send_keystate(struct monitor *monitor)
     	}
     
     	debug3("%s: Sending new keys: %p %p",
    -	    __func__, newkeys[MODE_OUT], newkeys[MODE_IN]);
    +	    __func__, packet_get_newkeys(MODE_OUT),
    +	    packet_get_newkeys(MODE_IN));
     
     	/* Keys from Kex */
     	if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
    @@ -655,8 +640,16 @@ mm_send_keystate(struct monitor *monitor)
     	buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
     
     	/* Network I/O buffers */
    -	buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
    -	buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
    +	input = (Buffer *)packet_get_input();
    +	output = (Buffer *)packet_get_output();
    +	buffer_put_string(&m, buffer_ptr(input), buffer_len(input));
    +	buffer_put_string(&m, buffer_ptr(output), buffer_len(output));
    +
    +	/* Roaming */
    +	if (compat20) {
    +		buffer_put_int64(&m, get_sent_bytes());
    +		buffer_put_int64(&m, get_recv_bytes());
    +	}
     
     	mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
     	debug3("%s: Finished sending state", __func__);
    @@ -1076,7 +1069,6 @@ mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
     		*rkey = key;
     		xfree(blob);
     	}
    -	mm_send_debug(&m);
     	buffer_free(&m);
     
     	return (allowed);
    @@ -1282,7 +1274,7 @@ mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
     }
     
     void
    -mm_jpake_step1(struct jpake_group *grp,
    +mm_jpake_step1(struct modp_group *grp,
         u_char **id, u_int *id_len,
         BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
         u_char **priv1_proof, u_int *priv1_proof_len,
    @@ -1317,7 +1309,7 @@ mm_jpake_step1(struct jpake_group *grp,
     }
     
     void
    -mm_jpake_step2(struct jpake_group *grp, BIGNUM *s,
    +mm_jpake_step2(struct modp_group *grp, BIGNUM *s,
         BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
         const u_char *theirid, u_int theirid_len,
         const u_char *myid, u_int myid_len,
    @@ -1357,7 +1349,7 @@ mm_jpake_step2(struct jpake_group *grp, BIGNUM *s,
     }
     
     void
    -mm_jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val,
    +mm_jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
         BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
         BIGNUM *theirpub1, BIGNUM *theirpub2,
         const u_char *my_id, u_int my_id_len,
    diff --git a/crypto/openssh/monitor_wrap.h b/crypto/openssh/monitor_wrap.h
    index 55c4b99f354..de2d16f6627 100644
    --- a/crypto/openssh/monitor_wrap.h
    +++ b/crypto/openssh/monitor_wrap.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: monitor_wrap.h,v 1.21 2008/11/04 08:22:13 djm Exp $ */
    +/* $OpenBSD: monitor_wrap.h,v 1.22 2009/03/05 07:18:19 djm Exp $ */
     
     /*
      * Copyright 2002 Niels Provos 
    @@ -102,17 +102,17 @@ int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
     int mm_skey_respond(void *, u_int, char **);
     
     /* jpake */
    -struct jpake_group;
    +struct modp_group;
     void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **);
    -void mm_jpake_step1(struct jpake_group *, u_char **, u_int *,
    +void mm_jpake_step1(struct modp_group *, u_char **, u_int *,
         BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
         u_char **, u_int *, u_char **, u_int *);
    -void mm_jpake_step2(struct jpake_group *, BIGNUM *,
    +void mm_jpake_step2(struct modp_group *, BIGNUM *,
         BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
         const u_char *, u_int, const u_char *, u_int,
         const u_char *, u_int, const u_char *, u_int,
         BIGNUM **, u_char **, u_int *);
    -void mm_jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
    +void mm_jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *,
         BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
         const u_char *, u_int, const u_char *, u_int,
         const u_char *, u_int, const u_char *, u_int,
    diff --git a/crypto/openssh/mux.c b/crypto/openssh/mux.c
    index 79f83768b33..825fb7a9a70 100644
    --- a/crypto/openssh/mux.c
    +++ b/crypto/openssh/mux.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: mux.c,v 1.7 2008/06/13 17:21:20 dtucker Exp $ */
    +/* $OpenBSD: mux.c,v 1.14 2010/01/30 02:54:53 djm Exp $ */
     /*
      * Copyright (c) 2002-2008 Damien Miller 
      *
    @@ -17,25 +17,21 @@
     
     /* ssh session multiplexing support */
     
    -#include "includes.h"
    -
     /*
      * TODO:
    - *   1. partial reads in muxserver_accept_control (maybe make channels
    - *      from accepted connections)
    - *   2. Better signalling from master to slave, especially passing of
    + *   - Better signalling from master to slave, especially passing of
      *      error messages
    - *   3. Better fall-back from mux slave error to new connection.
    - *   3. Add/delete forwardings via slave
    - *   4. ExitOnForwardingFailure (after #3 obviously)
    - *   5. Maybe extension mechanisms for multi-X11/multi-agent forwarding
    - *   6. Document the mux mini-protocol somewhere.
    - *   7. Support ~^Z in mux slaves.
    - *   8. Inspect or control sessions in master.
    - *   9. If we ever support the "signal" channel request, send signals on
    - *      sessions in master.
    + *   - Better fall-back from mux slave error to new connection.
    + *   - ExitOnForwardingFailure
    + *   - Maybe extension mechanisms for multi-X11/multi-agent forwarding
    + *   - Support ~^Z in mux slaves.
    + *   - Inspect or control sessions in master.
    + *   - If we ever support the "signal" channel request, send signals on
    + *     sessions in master.
      */
     
    +#include "includes.h"
    +
     #include 
     #include 
     #include 
    @@ -55,6 +51,14 @@
     #include 
     #endif
     
    +#ifdef HAVE_POLL_H
    +#include 
    +#else
    +# ifdef HAVE_SYS_POLL_H
    +#  include 
    +# endif
    +#endif
    +
     #ifdef HAVE_UTIL_H
     # include 
     #endif
    @@ -82,18 +86,22 @@
     
     /* from ssh.c */
     extern int tty_flag;
    +extern int force_tty_flag;
     extern Options options;
     extern int stdin_null_flag;
     extern char *host;
    -int subsystem_flag;
    +extern int subsystem_flag;
     extern Buffer command;
    +extern volatile sig_atomic_t quit_pending;
    +extern char *stdio_forward_host;
    +extern int stdio_forward_port;
     
     /* Context for session open confirmation callback */
     struct mux_session_confirm_ctx {
    -	int want_tty;
    -	int want_subsys;
    -	int want_x_fwd;
    -	int want_agent_fwd;
    +	u_int want_tty;
    +	u_int want_subsys;
    +	u_int want_x_fwd;
    +	u_int want_agent_fwd;
     	Buffer cmd;
     	char *term;
     	struct termios tio;
    @@ -103,6 +111,9 @@ struct mux_session_confirm_ctx {
     /* fd to control socket */
     int muxserver_sock = -1;
     
    +/* client request id */
    +u_int muxclient_request_id = 0;
    +
     /* Multiplexing control command */
     u_int muxclient_command = 0;
     
    @@ -112,16 +123,831 @@ static volatile sig_atomic_t muxclient_terminate = 0;
     /* PID of multiplex server */
     static u_int muxserver_pid = 0;
     
    +static Channel *mux_listener_channel = NULL;
     
    -/* ** Multiplexing master support */
    +struct mux_master_state {
    +	int hello_rcvd;
    +};
    +
    +/* mux protocol messages */
    +#define MUX_MSG_HELLO		0x00000001
    +#define MUX_C_NEW_SESSION	0x10000002
    +#define MUX_C_ALIVE_CHECK	0x10000004
    +#define MUX_C_TERMINATE		0x10000005
    +#define MUX_C_OPEN_FWD		0x10000006
    +#define MUX_C_CLOSE_FWD		0x10000007
    +#define MUX_C_NEW_STDIO_FWD	0x10000008
    +#define MUX_S_OK		0x80000001
    +#define MUX_S_PERMISSION_DENIED	0x80000002
    +#define MUX_S_FAILURE		0x80000003
    +#define MUX_S_EXIT_MESSAGE	0x80000004
    +#define MUX_S_ALIVE		0x80000005
    +#define MUX_S_SESSION_OPENED	0x80000006
    +
    +/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
    +#define MUX_FWD_LOCAL   1
    +#define MUX_FWD_REMOTE  2
    +#define MUX_FWD_DYNAMIC 3
    +
    +static void mux_session_confirm(int, void *);
    +
    +static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *);
    +static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *);
    +static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *);
    +static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *);
    +static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);
    +static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);
    +static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);
    +
    +static const struct {
    +	u_int type;
    +	int (*handler)(u_int, Channel *, Buffer *, Buffer *);
    +} mux_master_handlers[] = {
    +	{ MUX_MSG_HELLO, process_mux_master_hello },
    +	{ MUX_C_NEW_SESSION, process_mux_new_session },
    +	{ MUX_C_ALIVE_CHECK, process_mux_alive_check },
    +	{ MUX_C_TERMINATE, process_mux_terminate },
    +	{ MUX_C_OPEN_FWD, process_mux_open_fwd },
    +	{ MUX_C_CLOSE_FWD, process_mux_close_fwd },
    +	{ MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd },
    +	{ 0, NULL }
    +};
    +
    +/* Cleanup callback fired on closure of mux slave _session_ channel */
    +/* ARGSUSED */
    +static void
    +mux_master_session_cleanup_cb(int cid, void *unused)
    +{
    +	Channel *cc, *c = channel_by_id(cid);
    +
    +	debug3("%s: entering for channel %d", __func__, cid);
    +	if (c == NULL)
    +		fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
    +	if (c->ctl_chan != -1) {
    +		if ((cc = channel_by_id(c->ctl_chan)) == NULL)
    +			fatal("%s: channel %d missing control channel %d",
    +			    __func__, c->self, c->ctl_chan);
    +		c->ctl_chan = -1;
    +		cc->remote_id = -1;
    +		chan_rcvd_oclose(cc);
    +	}
    +	channel_cancel_cleanup(c->self);
    +}
    +
    +/* Cleanup callback fired on closure of mux slave _control_ channel */
    +/* ARGSUSED */
    +static void
    +mux_master_control_cleanup_cb(int cid, void *unused)
    +{
    +	Channel *sc, *c = channel_by_id(cid);
    +
    +	debug3("%s: entering for channel %d", __func__, cid);
    +	if (c == NULL)
    +		fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
    +	if (c->remote_id != -1) {
    +		if ((sc = channel_by_id(c->remote_id)) == NULL)
    +			debug2("%s: channel %d n session channel %d",
    +			    __func__, c->self, c->remote_id);
    +		c->remote_id = -1;
    +		sc->ctl_chan = -1;
    +		if (sc->type != SSH_CHANNEL_OPEN) {
    +			debug2("%s: channel %d: not open", __func__, sc->self);
    +			chan_mark_dead(sc);
    +		} else {
    +			if (sc->istate == CHAN_INPUT_OPEN)
    +				chan_read_failed(sc);
    +			if (sc->ostate == CHAN_OUTPUT_OPEN)
    +				chan_write_failed(sc);
    +		}
    +	}
    +	channel_cancel_cleanup(c->self);
    +}
    +
    +/* Check mux client environment variables before passing them to mux master. */
    +static int
    +env_permitted(char *env)
    +{
    +	int i, ret;
    +	char name[1024], *cp;
    +
    +	if ((cp = strchr(env, '=')) == NULL || cp == env)
    +		return 0;
    +	ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
    +	if (ret <= 0 || (size_t)ret >= sizeof(name)) {
    +		error("env_permitted: name '%.100s...' too long", env);
    +		return 0;
    +	}
    +
    +	for (i = 0; i < options.num_send_env; i++)
    +		if (match_pattern(name, options.send_env[i]))
    +			return 1;
    +
    +	return 0;
    +}
    +
    +/* Mux master protocol message handlers */
    +
    +static int
    +process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r)
    +{
    +	u_int ver;
    +	struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
    +
    +	if (state == NULL)
    +		fatal("%s: channel %d: c->mux_ctx == NULL", __func__, c->self);
    +	if (state->hello_rcvd) {
    +		error("%s: HELLO received twice", __func__);
    +		return -1;
    +	}
    +	if (buffer_get_int_ret(&ver, m) != 0) {
    + malf:
    +		error("%s: malformed message", __func__);
    +		return -1;
    +	}
    +	if (ver != SSHMUX_VER) {
    +		error("Unsupported multiplexing protocol version %d "
    +		    "(expected %d)", ver, SSHMUX_VER);
    +		return -1;
    +	}
    +	debug2("%s: channel %d slave version %u", __func__, c->self, ver);
    +
    +	/* No extensions are presently defined */
    +	while (buffer_len(m) > 0) {
    +		char *name = buffer_get_string_ret(m, NULL);
    +		char *value = buffer_get_string_ret(m, NULL);
    +
    +		if (name == NULL || value == NULL) {
    +			if (name != NULL)
    +				xfree(name);
    +			goto malf;
    +		}
    +		debug2("Unrecognised slave extension \"%s\"", name);
    +		xfree(name);
    +		xfree(value);
    +	}
    +	state->hello_rcvd = 1;
    +	return 0;
    +}
    +
    +static int
    +process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
    +{
    +	Channel *nc;
    +	struct mux_session_confirm_ctx *cctx;
    +	char *reserved, *cmd, *cp;
    +	u_int i, j, len, env_len, escape_char, window, packetmax;
    +	int new_fd[3];
    +
    +	/* Reply for SSHMUX_COMMAND_OPEN */
    +	cctx = xcalloc(1, sizeof(*cctx));
    +	cctx->term = NULL;
    +	cmd = reserved = NULL;
    +	if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
    +	    buffer_get_int_ret(&cctx->want_tty, m) != 0 ||
    +	    buffer_get_int_ret(&cctx->want_x_fwd, m) != 0 ||
    +	    buffer_get_int_ret(&cctx->want_agent_fwd, m) != 0 ||
    +	    buffer_get_int_ret(&cctx->want_subsys, m) != 0 ||
    +	    buffer_get_int_ret(&escape_char, m) != 0 ||
    +	    (cctx->term = buffer_get_string_ret(m, &len)) == NULL ||
    +	    (cmd = buffer_get_string_ret(m, &len)) == NULL) {
    + malf:
    +		if (cmd != NULL)
    +			xfree(cmd);
    +		if (reserved != NULL)
    +			xfree(reserved);
    +		if (cctx->term != NULL)
    +			xfree(cctx->term);
    +		error("%s: malformed message", __func__);
    +		return -1;
    +	}
    +	xfree(reserved);
    +	reserved = NULL;
    +
    +	cctx->env = NULL;
    +	env_len = 0;
    +	while (buffer_len(m) > 0) {
    +#define MUX_MAX_ENV_VARS	4096
    +		if ((cp = buffer_get_string_ret(m, &len)) == NULL) {
    +			xfree(cmd);
    +			goto malf;
    +		}
    +		if (!env_permitted(cp)) {
    +			xfree(cp);
    +			continue;
    +		}
    +		cctx->env = xrealloc(cctx->env, env_len + 2,
    +		    sizeof(*cctx->env));
    +		cctx->env[env_len++] = cp;
    +		cctx->env[env_len] = NULL;
    +		if (env_len > MUX_MAX_ENV_VARS) {
    +			error(">%d environment variables received, ignoring "
    +			    "additional", MUX_MAX_ENV_VARS);
    +			break;
    +		}
    +	}
    +
    +	debug2("%s: channel %d: request tty %d, X %d, agent %d, subsys %d, "
    +	    "term \"%s\", cmd \"%s\", env %u", __func__, c->self,
    +	    cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd,
    +	    cctx->want_subsys, cctx->term, cmd, env_len);
    +
    +	buffer_init(&cctx->cmd);
    +	buffer_append(&cctx->cmd, cmd, strlen(cmd));
    +	xfree(cmd);
    +	cmd = NULL;
    +
    +	/* Gather fds from client */
    +	for(i = 0; i < 3; i++) {
    +		if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
    +			error("%s: failed to receive fd %d from slave",
    +			    __func__, i);
    +			for (j = 0; j < i; j++)
    +				close(new_fd[j]);
    +			for (j = 0; j < env_len; j++)
    +				xfree(cctx->env[j]);
    +			if (env_len > 0)
    +				xfree(cctx->env);
    +			xfree(cctx->term);
    +			buffer_free(&cctx->cmd);
    +			xfree(cctx);
    +
    +			/* prepare reply */
    +			buffer_put_int(r, MUX_S_FAILURE);
    +			buffer_put_int(r, rid);
    +			buffer_put_cstring(r,
    +			    "did not receive file descriptors");
    +			return -1;
    +		}
    +	}
    +
    +	debug3("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
    +	    new_fd[0], new_fd[1], new_fd[2]);
    +
    +	/* XXX support multiple child sessions in future */
    +	if (c->remote_id != -1) {
    +		debug2("%s: session already open", __func__);
    +		/* prepare reply */
    +		buffer_put_int(r, MUX_S_FAILURE);
    +		buffer_put_int(r, rid);
    +		buffer_put_cstring(r, "Multiple sessions not supported");
    + cleanup:
    +		close(new_fd[0]);
    +		close(new_fd[1]);
    +		close(new_fd[2]);
    +		xfree(cctx->term);
    +		if (env_len != 0) {
    +			for (i = 0; i < env_len; i++)
    +				xfree(cctx->env[i]);
    +			xfree(cctx->env);
    +		}
    +		buffer_free(&cctx->cmd);
    +		return 0;
    +	}
    +
    +	if (options.control_master == SSHCTL_MASTER_ASK ||
    +	    options.control_master == SSHCTL_MASTER_AUTO_ASK) {
    +		if (!ask_permission("Allow shared connection to %s? ", host)) {
    +			debug2("%s: session refused by user", __func__);
    +			/* prepare reply */
    +			buffer_put_int(r, MUX_S_PERMISSION_DENIED);
    +			buffer_put_int(r, rid);
    +			buffer_put_cstring(r, "Permission denied");
    +			goto cleanup;
    +		}
    +	}
    +
    +	/* Try to pick up ttymodes from client before it goes raw */
    +	if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
    +		error("%s: tcgetattr: %s", __func__, strerror(errno));
    +
    +	/* enable nonblocking unless tty */
    +	if (!isatty(new_fd[0]))
    +		set_nonblock(new_fd[0]);
    +	if (!isatty(new_fd[1]))
    +		set_nonblock(new_fd[1]);
    +	if (!isatty(new_fd[2]))
    +		set_nonblock(new_fd[2]);
    +
    +	window = CHAN_SES_WINDOW_DEFAULT;
    +	packetmax = CHAN_SES_PACKET_DEFAULT;
    +	if (cctx->want_tty) {
    +		window >>= 1;
    +		packetmax >>= 1;
    +	}
    +
    +	nc = channel_new("session", SSH_CHANNEL_OPENING,
    +	    new_fd[0], new_fd[1], new_fd[2], window, packetmax,
    +	    CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
    +
    +	nc->ctl_chan = c->self;		/* link session -> control channel */
    +	c->remote_id = nc->self; 	/* link control -> session channel */
    +
    +	if (cctx->want_tty && escape_char != 0xffffffff) {
    +		channel_register_filter(nc->self,
    +		    client_simple_escape_filter, NULL,
    +		    client_filter_cleanup,
    +		    client_new_escape_filter_ctx((int)escape_char));
    +	}
    +
    +	debug2("%s: channel_new: %d linked to control channel %d",
    +	    __func__, nc->self, nc->ctl_chan);
    +
    +	channel_send_open(nc->self);
    +	channel_register_open_confirm(nc->self, mux_session_confirm, cctx);
    +	channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 0);
    +
    +	/* prepare reply */
    +	/* XXX defer until mux_session_confirm() fires */
    +	buffer_put_int(r, MUX_S_SESSION_OPENED);
    +	buffer_put_int(r, rid);
    +	buffer_put_int(r, nc->self);
    +
    +	return 0;
    +}
    +
    +static int
    +process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r)
    +{
    +	debug2("%s: channel %d: alive check", __func__, c->self);
    +
    +	/* prepare reply */
    +	buffer_put_int(r, MUX_S_ALIVE);
    +	buffer_put_int(r, rid);
    +	buffer_put_int(r, (u_int)getpid());
    +
    +	return 0;
    +}
    +
    +static int
    +process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r)
    +{
    +	debug2("%s: channel %d: terminate request", __func__, c->self);
    +
    +	if (options.control_master == SSHCTL_MASTER_ASK ||
    +	    options.control_master == SSHCTL_MASTER_AUTO_ASK) {
    +		if (!ask_permission("Terminate shared connection to %s? ",
    +		    host)) {
    +			debug2("%s: termination refused by user", __func__);
    +			buffer_put_int(r, MUX_S_PERMISSION_DENIED);
    +			buffer_put_int(r, rid);
    +			buffer_put_cstring(r, "Permission denied");
    +			return 0;
    +		}
    +	}
    +
    +	quit_pending = 1;
    +	buffer_put_int(r, MUX_S_OK);
    +	buffer_put_int(r, rid);
    +	/* XXX exit happens too soon - message never makes it to client */
    +	return 0;
    +}
    +
    +static char *
    +format_forward(u_int ftype, Forward *fwd)
    +{
    +	char *ret;
    +
    +	switch (ftype) {
    +	case MUX_FWD_LOCAL:
    +		xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d",
    +		    (fwd->listen_host == NULL) ?
    +		    (options.gateway_ports ? "*" : "LOCALHOST") :
    +		    fwd->listen_host, fwd->listen_port,
    +		    fwd->connect_host, fwd->connect_port);
    +		break;
    +	case MUX_FWD_DYNAMIC:
    +		xasprintf(&ret, "dynamic forward %.200s:%d -> *",
    +		    (fwd->listen_host == NULL) ?
    +		    (options.gateway_ports ? "*" : "LOCALHOST") :
    +		     fwd->listen_host, fwd->listen_port);
    +		break;
    +	case MUX_FWD_REMOTE:
    +		xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d",
    +		    (fwd->listen_host == NULL) ?
    +		    "LOCALHOST" : fwd->listen_host,
    +		    fwd->listen_port,
    +		    fwd->connect_host, fwd->connect_port);
    +		break;
    +	default:
    +		fatal("%s: unknown forward type %u", __func__, ftype);
    +	}
    +	return ret;
    +}
    +
    +static int
    +compare_host(const char *a, const char *b)
    +{
    +	if (a == NULL && b == NULL)
    +		return 1;
    +	if (a == NULL || b == NULL)
    +		return 0;
    +	return strcmp(a, b) == 0;
    +}
    +
    +static int
    +compare_forward(Forward *a, Forward *b)
    +{
    +	if (!compare_host(a->listen_host, b->listen_host))
    +		return 0;
    +	if (a->listen_port != b->listen_port)
    +		return 0;
    +	if (!compare_host(a->connect_host, b->connect_host))
    +		return 0;
    +	if (a->connect_port != b->connect_port)
    +		return 0;
    +
    +	return 1;
    +}
    +
    +static int
    +process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
    +{
    +	Forward fwd;
    +	char *fwd_desc = NULL;
    +	u_int ftype;
    +	int i, ret = 0, freefwd = 1;
    +
    +	fwd.listen_host = fwd.connect_host = NULL;
    +	if (buffer_get_int_ret(&ftype, m) != 0 ||
    +	    (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
    +	    buffer_get_int_ret(&fwd.listen_port, m) != 0 ||
    +	    (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
    +	    buffer_get_int_ret(&fwd.connect_port, m) != 0) {
    +		error("%s: malformed message", __func__);
    +		ret = -1;
    +		goto out;
    +	}
    +
    +	if (*fwd.listen_host == '\0') {
    +		xfree(fwd.listen_host);
    +		fwd.listen_host = NULL;
    +	}
    +	if (*fwd.connect_host == '\0') {
    +		xfree(fwd.connect_host);
    +		fwd.connect_host = NULL;
    +	}
    +
    +	debug2("%s: channel %d: request %s", __func__, c->self,
    +	    (fwd_desc = format_forward(ftype, &fwd)));
    +
    +	if (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE &&
    +	    ftype != MUX_FWD_DYNAMIC) {
    +		logit("%s: invalid forwarding type %u", __func__, ftype);
    + invalid:
    +		xfree(fwd.listen_host);
    +		xfree(fwd.connect_host);
    +		buffer_put_int(r, MUX_S_FAILURE);
    +		buffer_put_int(r, rid);
    +		buffer_put_cstring(r, "Invalid forwarding request");
    +		return 0;
    +	}
    +	/* XXX support rport0 forwarding with reply of port assigned */
    +	if (fwd.listen_port == 0 || fwd.listen_port >= 65536) {
    +		logit("%s: invalid listen port %u", __func__,
    +		    fwd.listen_port);
    +		goto invalid;
    +	}
    +	if (fwd.connect_port >= 65536 || (ftype != MUX_FWD_DYNAMIC &&
    +	    ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {
    +		logit("%s: invalid connect port %u", __func__,
    +		    fwd.connect_port);
    +		goto invalid;
    +	}
    +	if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL) {
    +		logit("%s: missing connect host", __func__);
    +		goto invalid;
    +	}
    +
    +	/* Skip forwards that have already been requested */
    +	switch (ftype) {
    +	case MUX_FWD_LOCAL:
    +	case MUX_FWD_DYNAMIC:
    +		for (i = 0; i < options.num_local_forwards; i++) {
    +			if (compare_forward(&fwd,
    +			    options.local_forwards + i)) {
    + exists:
    +				debug2("%s: found existing forwarding",
    +				    __func__);
    +				buffer_put_int(r, MUX_S_OK);
    +				buffer_put_int(r, rid);
    +				goto out;
    +			}
    +		}
    +		break;
    +	case MUX_FWD_REMOTE:
    +		for (i = 0; i < options.num_remote_forwards; i++) {
    +			if (compare_forward(&fwd,
    +			    options.remote_forwards + i))
    +				goto exists;
    +		}
    +		break;
    +	}
    +
    +	if (options.control_master == SSHCTL_MASTER_ASK ||
    +	    options.control_master == SSHCTL_MASTER_AUTO_ASK) {
    +		if (!ask_permission("Open %s on %s?", fwd_desc, host)) {
    +			debug2("%s: forwarding refused by user", __func__);
    +			buffer_put_int(r, MUX_S_PERMISSION_DENIED);
    +			buffer_put_int(r, rid);
    +			buffer_put_cstring(r, "Permission denied");
    +			goto out;
    +		}
    +	}
    +
    +	if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
    +		if (options.num_local_forwards + 1 >=
    +		    SSH_MAX_FORWARDS_PER_DIRECTION ||
    +		    channel_setup_local_fwd_listener(fwd.listen_host,
    +		    fwd.listen_port, fwd.connect_host, fwd.connect_port,
    +		    options.gateway_ports) < 0) {
    + fail:
    +			logit("slave-requested %s failed", fwd_desc);
    +			buffer_put_int(r, MUX_S_FAILURE);
    +			buffer_put_int(r, rid);
    +			buffer_put_cstring(r, "Port forwarding failed");
    +			goto out;
    +		}
    +		add_local_forward(&options, &fwd);
    +		freefwd = 0;
    +	} else {
    +		/* XXX wait for remote to confirm */
    +		if (options.num_remote_forwards + 1 >=
    +		    SSH_MAX_FORWARDS_PER_DIRECTION ||
    +		    channel_request_remote_forwarding(fwd.listen_host,
    +		    fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0)
    +			goto fail;
    +		add_remote_forward(&options, &fwd);
    +		freefwd = 0;
    +	}
    +	buffer_put_int(r, MUX_S_OK);
    +	buffer_put_int(r, rid);
    + out:
    +	if (fwd_desc != NULL)
    +		xfree(fwd_desc);
    +	if (freefwd) {
    +		if (fwd.listen_host != NULL)
    +			xfree(fwd.listen_host);
    +		if (fwd.connect_host != NULL)
    +			xfree(fwd.connect_host);
    +	}
    +	return ret;
    +}
    +
    +static int
    +process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
    +{
    +	Forward fwd;
    +	char *fwd_desc = NULL;
    +	u_int ftype;
    +	int ret = 0;
    +
    +	fwd.listen_host = fwd.connect_host = NULL;
    +	if (buffer_get_int_ret(&ftype, m) != 0 ||
    +	    (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
    +	    buffer_get_int_ret(&fwd.listen_port, m) != 0 ||
    +	    (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
    +	    buffer_get_int_ret(&fwd.connect_port, m) != 0) {
    +		error("%s: malformed message", __func__);
    +		ret = -1;
    +		goto out;
    +	}
    +
    +	if (*fwd.listen_host == '\0') {
    +		xfree(fwd.listen_host);
    +		fwd.listen_host = NULL;
    +	}
    +	if (*fwd.connect_host == '\0') {
    +		xfree(fwd.connect_host);
    +		fwd.connect_host = NULL;
    +	}
    +
    +	debug2("%s: channel %d: request %s", __func__, c->self,
    +	    (fwd_desc = format_forward(ftype, &fwd)));
    +
    +	/* XXX implement this */
    +	buffer_put_int(r, MUX_S_FAILURE);
    +	buffer_put_int(r, rid);
    +	buffer_put_cstring(r, "unimplemented");
    +
    + out:
    +	if (fwd_desc != NULL)
    +		xfree(fwd_desc);
    +	if (fwd.listen_host != NULL)
    +		xfree(fwd.listen_host);
    +	if (fwd.connect_host != NULL)
    +		xfree(fwd.connect_host);
    +
    +	return ret;
    +}
    +
    +static int
    +process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
    +{
    +	Channel *nc;
    +	char *reserved, *chost;
    +	u_int cport, i, j;
    +	int new_fd[2];
    +
    +	chost = reserved = NULL;
    +	if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
    +	   (chost = buffer_get_string_ret(m, NULL)) == NULL ||
    +	    buffer_get_int_ret(&cport, m) != 0) {
    +		if (reserved != NULL)
    +			xfree(reserved);
    +		if (chost != NULL)
    +			xfree(chost);
    +		error("%s: malformed message", __func__);
    +		return -1;
    +	}
    +	xfree(reserved);
    +
    +	debug2("%s: channel %d: request stdio fwd to %s:%u",
    +	    __func__, c->self, chost, cport);
    +
    +	/* Gather fds from client */
    +	for(i = 0; i < 2; i++) {
    +		if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
    +			error("%s: failed to receive fd %d from slave",
    +			    __func__, i);
    +			for (j = 0; j < i; j++)
    +				close(new_fd[j]);
    +			xfree(chost);
    +
    +			/* prepare reply */
    +			buffer_put_int(r, MUX_S_FAILURE);
    +			buffer_put_int(r, rid);
    +			buffer_put_cstring(r,
    +			    "did not receive file descriptors");
    +			return -1;
    +		}
    +	}
    +
    +	debug3("%s: got fds stdin %d, stdout %d", __func__,
    +	    new_fd[0], new_fd[1]);
    +
    +	/* XXX support multiple child sessions in future */
    +	if (c->remote_id != -1) {
    +		debug2("%s: session already open", __func__);
    +		/* prepare reply */
    +		buffer_put_int(r, MUX_S_FAILURE);
    +		buffer_put_int(r, rid);
    +		buffer_put_cstring(r, "Multiple sessions not supported");
    + cleanup:
    +		close(new_fd[0]);
    +		close(new_fd[1]);
    +		xfree(chost);
    +		return 0;
    +	}
    +
    +	if (options.control_master == SSHCTL_MASTER_ASK ||
    +	    options.control_master == SSHCTL_MASTER_AUTO_ASK) {
    +		if (!ask_permission("Allow forward to to %s:%u? ",
    +		    chost, cport)) {
    +			debug2("%s: stdio fwd refused by user", __func__);
    +			/* prepare reply */
    +			buffer_put_int(r, MUX_S_PERMISSION_DENIED);
    +			buffer_put_int(r, rid);
    +			buffer_put_cstring(r, "Permission denied");
    +			goto cleanup;
    +		}
    +	}
    +
    +	/* enable nonblocking unless tty */
    +	if (!isatty(new_fd[0]))
    +		set_nonblock(new_fd[0]);
    +	if (!isatty(new_fd[1]))
    +		set_nonblock(new_fd[1]);
    +
    +	nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]);
    +
    +	nc->ctl_chan = c->self;		/* link session -> control channel */
    +	c->remote_id = nc->self; 	/* link control -> session channel */
    +
    +	debug2("%s: channel_new: %d linked to control channel %d",
    +	    __func__, nc->self, nc->ctl_chan);
    +
    +	channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 0);
    +
    +	/* prepare reply */
    +	/* XXX defer until channel confirmed */
    +	buffer_put_int(r, MUX_S_SESSION_OPENED);
    +	buffer_put_int(r, rid);
    +	buffer_put_int(r, nc->self);
    +
    +	return 0;
    +}
    +
    +/* Channel callbacks fired on read/write from mux slave fd */
    +static int
    +mux_master_read_cb(Channel *c)
    +{
    +	struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
    +	Buffer in, out;
    +	void *ptr;
    +	u_int type, rid, have, i;
    +	int ret = -1;
    +
    +	/* Setup ctx and  */
    +	if (c->mux_ctx == NULL) {
    +		state = xcalloc(1, sizeof(state));
    +		c->mux_ctx = state;
    +		channel_register_cleanup(c->self,
    +		    mux_master_control_cleanup_cb, 0);
    +
    +		/* Send hello */
    +		buffer_init(&out);
    +		buffer_put_int(&out, MUX_MSG_HELLO);
    +		buffer_put_int(&out, SSHMUX_VER);
    +		/* no extensions */
    +		buffer_put_string(&c->output, buffer_ptr(&out),
    +		    buffer_len(&out));
    +		buffer_free(&out);
    +		debug3("%s: channel %d: hello sent", __func__, c->self);
    +		return 0;
    +	}
    +
    +	buffer_init(&in);
    +	buffer_init(&out);
    +
    +	/* Channel code ensures that we receive whole packets */
    +	if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) {
    + malf:
    +		error("%s: malformed message", __func__);
    +		goto out;
    +	}
    +	buffer_append(&in, ptr, have);
    +
    +	if (buffer_get_int_ret(&type, &in) != 0)
    +		goto malf;
    +	debug3("%s: channel %d packet type 0x%08x len %u",
    +	    __func__, c->self, type, buffer_len(&in));
    +
    +	if (type == MUX_MSG_HELLO)
    +		rid = 0;
    +	else {
    +		if (!state->hello_rcvd) {
    +			error("%s: expected MUX_MSG_HELLO(0x%08x), "
    +			    "received 0x%08x", __func__, MUX_MSG_HELLO, type);
    +			goto out;
    +		}
    +		if (buffer_get_int_ret(&rid, &in) != 0)
    +			goto malf;
    +	}
    +
    +	for (i = 0; mux_master_handlers[i].handler != NULL; i++) {
    +		if (type == mux_master_handlers[i].type) {
    +			ret = mux_master_handlers[i].handler(rid, c, &in, &out);
    +			break;
    +		}
    +	}
    +	if (mux_master_handlers[i].handler == NULL) {
    +		error("%s: unsupported mux message 0x%08x", __func__, type);
    +		buffer_put_int(&out, MUX_S_FAILURE);
    +		buffer_put_int(&out, rid);
    +		buffer_put_cstring(&out, "unsupported request");
    +		ret = 0;
    +	}
    +	/* Enqueue reply packet */
    +	if (buffer_len(&out) != 0) {
    +		buffer_put_string(&c->output, buffer_ptr(&out),
    +		    buffer_len(&out));
    +	}
    + out:
    +	buffer_free(&in);
    +	buffer_free(&out);
    +	return ret;
    +}
    +
    +void
    +mux_exit_message(Channel *c, int exitval)
    +{
    +	Buffer m;
    +	Channel *mux_chan;
    +
    +	debug3("%s: channel %d: exit message, evitval %d", __func__, c->self,
    +	    exitval);
    +
    +	if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)
    +		fatal("%s: channel %d missing mux channel %d",
    +		    __func__, c->self, c->ctl_chan);
    +
    +	/* Append exit message packet to control socket output queue */
    +	buffer_init(&m);
    +	buffer_put_int(&m, MUX_S_EXIT_MESSAGE);
    +	buffer_put_int(&m, c->self);
    +	buffer_put_int(&m, exitval);
    +
    +	buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m));
    +	buffer_free(&m);
    +}
     
     /* Prepare a mux master to listen on a Unix domain socket. */
     void
     muxserver_listen(void)
     {
     	struct sockaddr_un addr;
    +	socklen_t sun_len;
     	mode_t old_umask;
    -	int addr_len;
     
     	if (options.control_path == NULL ||
     	    options.control_master == SSHCTL_MASTER_NO)
    @@ -131,7 +957,7 @@ muxserver_listen(void)
     
     	memset(&addr, '\0', sizeof(addr));
     	addr.sun_family = AF_UNIX;
    -	addr_len = offsetof(struct sockaddr_un, sun_path) +
    +	sun_len = offsetof(struct sockaddr_un, sun_path) +
     	    strlen(options.control_path) + 1;
     
     	if (strlcpy(addr.sun_path, options.control_path,
    @@ -142,7 +968,7 @@ muxserver_listen(void)
     		fatal("%s socket(): %s", __func__, strerror(errno));
     
     	old_umask = umask(0177);
    -	if (bind(muxserver_sock, (struct sockaddr *)&addr, addr_len) == -1) {
    +	if (bind(muxserver_sock, (struct sockaddr *)&addr, sun_len) == -1) {
     		muxserver_sock = -1;
     		if (errno == EINVAL || errno == EADDRINUSE) {
     			error("ControlSocket %s already exists, "
    @@ -162,6 +988,14 @@ muxserver_listen(void)
     		fatal("%s listen(): %s", __func__, strerror(errno));
     
     	set_nonblock(muxserver_sock);
    +
    +	mux_listener_channel = channel_new("mux listener",
    +	    SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
    +	    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
    +	    0, addr.sun_path, 1);
    +	mux_listener_channel->mux_rcb = mux_master_read_cb;
    +	debug3("%s: mux listener channel %d fd %d", __func__,
    +	    mux_listener_channel->self, mux_listener_channel->sock);
     }
     
     /* Callback on open confirmation in mux master for a mux client session. */
    @@ -175,7 +1009,7 @@ mux_session_confirm(int id, void *arg)
     
     	if (cctx == NULL)
     		fatal("%s: cctx == NULL", __func__);
    -	if ((c = channel_lookup(id)) == NULL)
    +	if ((c = channel_by_id(id)) == NULL)
     		fatal("%s: no channel for id %d", __func__, id);
     
     	display = getenv("DISPLAY");
    @@ -210,249 +1044,6 @@ mux_session_confirm(int id, void *arg)
     	xfree(cctx);
     }
     
    -/*
    - * Accept a connection on the mux master socket and process the
    - * client's request. Returns flag indicating whether mux master should
    - * begin graceful close.
    - */
    -int
    -muxserver_accept_control(void)
    -{
    -	Buffer m;
    -	Channel *c;
    -	int client_fd, new_fd[3], ver, allowed, window, packetmax;
    -	socklen_t addrlen;
    -	struct sockaddr_storage addr;
    -	struct mux_session_confirm_ctx *cctx;
    -	char *cmd;
    -	u_int i, j, len, env_len, mux_command, flags, escape_char;
    -	uid_t euid;
    -	gid_t egid;
    -	int start_close = 0;
    -
    -	/*
    -	 * Accept connection on control socket
    -	 */
    -	memset(&addr, 0, sizeof(addr));
    -	addrlen = sizeof(addr);
    -	if ((client_fd = accept(muxserver_sock,
    -	    (struct sockaddr*)&addr, &addrlen)) == -1) {
    -		error("%s accept: %s", __func__, strerror(errno));
    -		return 0;
    -	}
    -
    -	if (getpeereid(client_fd, &euid, &egid) < 0) {
    -		error("%s getpeereid failed: %s", __func__, strerror(errno));
    -		close(client_fd);
    -		return 0;
    -	}
    -	if ((euid != 0) && (getuid() != euid)) {
    -		error("control mode uid mismatch: peer euid %u != uid %u",
    -		    (u_int) euid, (u_int) getuid());
    -		close(client_fd);
    -		return 0;
    -	}
    -
    -	/* XXX handle asynchronously */
    -	unset_nonblock(client_fd);
    -
    -	/* Read command */
    -	buffer_init(&m);
    -	if (ssh_msg_recv(client_fd, &m) == -1) {
    -		error("%s: client msg_recv failed", __func__);
    -		close(client_fd);
    -		buffer_free(&m);
    -		return 0;
    -	}
    -	if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
    -		error("%s: wrong client version %d", __func__, ver);
    -		buffer_free(&m);
    -		close(client_fd);
    -		return 0;
    -	}
    -
    -	allowed = 1;
    -	mux_command = buffer_get_int(&m);
    -	flags = buffer_get_int(&m);
    -
    -	buffer_clear(&m);
    -
    -	switch (mux_command) {
    -	case SSHMUX_COMMAND_OPEN:
    -		if (options.control_master == SSHCTL_MASTER_ASK ||
    -		    options.control_master == SSHCTL_MASTER_AUTO_ASK)
    -			allowed = ask_permission("Allow shared connection "
    -			    "to %s? ", host);
    -		/* continue below */
    -		break;
    -	case SSHMUX_COMMAND_TERMINATE:
    -		if (options.control_master == SSHCTL_MASTER_ASK ||
    -		    options.control_master == SSHCTL_MASTER_AUTO_ASK)
    -			allowed = ask_permission("Terminate shared connection "
    -			    "to %s? ", host);
    -		if (allowed)
    -			start_close = 1;
    -		/* FALLTHROUGH */
    -	case SSHMUX_COMMAND_ALIVE_CHECK:
    -		/* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */
    -		buffer_clear(&m);
    -		buffer_put_int(&m, allowed);
    -		buffer_put_int(&m, getpid());
    -		if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
    -			error("%s: client msg_send failed", __func__);
    -			close(client_fd);
    -			buffer_free(&m);
    -			return start_close;
    -		}
    -		buffer_free(&m);
    -		close(client_fd);
    -		return start_close;
    -	default:
    -		error("Unsupported command %d", mux_command);
    -		buffer_free(&m);
    -		close(client_fd);
    -		return 0;
    -	}
    -
    -	/* Reply for SSHMUX_COMMAND_OPEN */
    -	buffer_clear(&m);
    -	buffer_put_int(&m, allowed);
    -	buffer_put_int(&m, getpid());
    -	if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
    -		error("%s: client msg_send failed", __func__);
    -		close(client_fd);
    -		buffer_free(&m);
    -		return 0;
    -	}
    -
    -	if (!allowed) {
    -		error("Refused control connection");
    -		close(client_fd);
    -		buffer_free(&m);
    -		return 0;
    -	}
    -
    -	buffer_clear(&m);
    -	if (ssh_msg_recv(client_fd, &m) == -1) {
    -		error("%s: client msg_recv failed", __func__);
    -		close(client_fd);
    -		buffer_free(&m);
    -		return 0;
    -	}
    -	if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
    -		error("%s: wrong client version %d", __func__, ver);
    -		buffer_free(&m);
    -		close(client_fd);
    -		return 0;
    -	}
    -
    -	cctx = xcalloc(1, sizeof(*cctx));
    -	cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0;
    -	cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0;
    -	cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
    -	cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
    -	cctx->term = buffer_get_string(&m, &len);
    -	escape_char = buffer_get_int(&m);
    -
    -	cmd = buffer_get_string(&m, &len);
    -	buffer_init(&cctx->cmd);
    -	buffer_append(&cctx->cmd, cmd, strlen(cmd));
    -
    -	env_len = buffer_get_int(&m);
    -	env_len = MIN(env_len, 4096);
    -	debug3("%s: receiving %d env vars", __func__, env_len);
    -	if (env_len != 0) {
    -		cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env));
    -		for (i = 0; i < env_len; i++)
    -			cctx->env[i] = buffer_get_string(&m, &len);
    -		cctx->env[i] = NULL;
    -	}
    -
    -	debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__,
    -	    cctx->want_tty, cctx->want_subsys, cmd);
    -	xfree(cmd);
    -
    -	/* Gather fds from client */
    -	for(i = 0; i < 3; i++) {
    -		if ((new_fd[i] = mm_receive_fd(client_fd)) == -1) {
    -			error("%s: failed to receive fd %d from slave",
    -			    __func__, i);
    -			for (j = 0; j < i; j++)
    -				close(new_fd[j]);
    -			for (j = 0; j < env_len; j++)
    -				xfree(cctx->env[j]);
    -			if (env_len > 0)
    -				xfree(cctx->env);
    -			xfree(cctx->term);
    -			buffer_free(&cctx->cmd);
    -			close(client_fd);
    -			xfree(cctx);
    -			return 0;
    -		}
    -	}
    -
    -	debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
    -	    new_fd[0], new_fd[1], new_fd[2]);
    -
    -	/* Try to pick up ttymodes from client before it goes raw */
    -	if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
    -		error("%s: tcgetattr: %s", __func__, strerror(errno));
    -
    -	/* This roundtrip is just for synchronisation of ttymodes */
    -	buffer_clear(&m);
    -	if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
    -		error("%s: client msg_send failed", __func__);
    -		close(client_fd);
    -		close(new_fd[0]);
    -		close(new_fd[1]);
    -		close(new_fd[2]);
    -		buffer_free(&m);
    -		xfree(cctx->term);
    -		if (env_len != 0) {
    -			for (i = 0; i < env_len; i++)
    -				xfree(cctx->env[i]);
    -			xfree(cctx->env);
    -		}
    -		return 0;
    -	}
    -	buffer_free(&m);
    -
    -	/* enable nonblocking unless tty */
    -	if (!isatty(new_fd[0]))
    -		set_nonblock(new_fd[0]);
    -	if (!isatty(new_fd[1]))
    -		set_nonblock(new_fd[1]);
    -	if (!isatty(new_fd[2]))
    -		set_nonblock(new_fd[2]);
    -
    -	set_nonblock(client_fd);
    -
    -	window = CHAN_SES_WINDOW_DEFAULT;
    -	packetmax = CHAN_SES_PACKET_DEFAULT;
    -	if (cctx->want_tty) {
    -		window >>= 1;
    -		packetmax >>= 1;
    -	}
    -	
    -	c = channel_new("session", SSH_CHANNEL_OPENING,
    -	    new_fd[0], new_fd[1], new_fd[2], window, packetmax,
    -	    CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
    -
    -	c->ctl_fd = client_fd;
    -	if (cctx->want_tty && escape_char != 0xffffffff) {
    -		channel_register_filter(c->self,
    -		    client_simple_escape_filter, NULL,
    -		    client_filter_cleanup,
    -		    client_new_escape_filter_ctx((int)escape_char));
    -	}
    -
    -	debug3("%s: channel_new: %d", __func__, c->self);
    -
    -	channel_send_open(c->self);
    -	channel_register_open_confirm(c->self, mux_session_confirm, cctx);
    -	return 0;
    -}
    -
     /* ** Multiplexing client support */
     
     /* Exit signal handler */
    @@ -477,24 +1068,592 @@ control_client_sigrelay(int signo)
     	errno = save_errno;
     }
     
    -/* Check mux client environment variables before passing them to mux master. */
     static int
    -env_permitted(char *env)
    +mux_client_read(int fd, Buffer *b, u_int need)
     {
    -	int i, ret;
    -	char name[1024], *cp;
    +	u_int have;
    +	ssize_t len;
    +	u_char *p;
    +	struct pollfd pfd;
     
    -	if ((cp = strchr(env, '=')) == NULL || cp == env)
    -		return (0);
    -	ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
    -	if (ret <= 0 || (size_t)ret >= sizeof(name))
    -		fatal("env_permitted: name '%.100s...' too long", env);
    +	pfd.fd = fd;
    +	pfd.events = POLLIN;
    +	p = buffer_append_space(b, need);
    +	for (have = 0; have < need; ) {
    +		if (muxclient_terminate) {
    +			errno = EINTR;
    +			return -1;
    +		}
    +		len = read(fd, p + have, need - have);
    +		if (len < 0) {
    +			switch (errno) {
    +#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
    +			case EWOULDBLOCK:
    +#endif
    +			case EAGAIN:
    +				(void)poll(&pfd, 1, -1);
    +				/* FALLTHROUGH */
    +			case EINTR:
    +				continue;
    +			default:
    +				return -1;
    +			}
    +		}
    +		if (len == 0) {
    +			errno = EPIPE;
    +			return -1;
    +		}
    +		have += (u_int)len;
    +	}
    +	return 0;
    +}
     
    -	for (i = 0; i < options.num_send_env; i++)
    -		if (match_pattern(name, options.send_env[i]))
    -			return (1);
    +static int
    +mux_client_write_packet(int fd, Buffer *m)
    +{
    +	Buffer queue;
    +	u_int have, need;
    +	int oerrno, len;
    +	u_char *ptr;
    +	struct pollfd pfd;
     
    -	return (0);
    +	pfd.fd = fd;
    +	pfd.events = POLLOUT;
    +	buffer_init(&queue);
    +	buffer_put_string(&queue, buffer_ptr(m), buffer_len(m));
    +
    +	need = buffer_len(&queue);
    +	ptr = buffer_ptr(&queue);
    +
    +	for (have = 0; have < need; ) {
    +		if (muxclient_terminate) {
    +			buffer_free(&queue);
    +			errno = EINTR;
    +			return -1;
    +		}
    +		len = write(fd, ptr + have, need - have);
    +		if (len < 0) {
    +			switch (errno) {
    +#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
    +			case EWOULDBLOCK:
    +#endif
    +			case EAGAIN:
    +				(void)poll(&pfd, 1, -1);
    +				/* FALLTHROUGH */
    +			case EINTR:
    +				continue;
    +			default:
    +				oerrno = errno;
    +				buffer_free(&queue);
    +				errno = oerrno;
    +				return -1;
    +			}
    +		}
    +		if (len == 0) {
    +			buffer_free(&queue);
    +			errno = EPIPE;
    +			return -1;
    +		}
    +		have += (u_int)len;
    +	}
    +	buffer_free(&queue);
    +	return 0;
    +}
    +
    +static int
    +mux_client_read_packet(int fd, Buffer *m)
    +{
    +	Buffer queue;
    +	u_int need, have;
    +	void *ptr;
    +	int oerrno;
    +
    +	buffer_init(&queue);
    +	if (mux_client_read(fd, &queue, 4) != 0) {
    +		if ((oerrno = errno) == EPIPE)
    +		debug3("%s: read header failed: %s", __func__, strerror(errno));
    +		errno = oerrno;
    +		return -1;
    +	}
    +	need = get_u32(buffer_ptr(&queue));
    +	if (mux_client_read(fd, &queue, need) != 0) {
    +		oerrno = errno;
    +		debug3("%s: read body failed: %s", __func__, strerror(errno));
    +		errno = oerrno;
    +		return -1;
    +	}
    +	ptr = buffer_get_string_ptr(&queue, &have);
    +	buffer_append(m, ptr, have);
    +	buffer_free(&queue);
    +	return 0;
    +}
    +
    +static int
    +mux_client_hello_exchange(int fd)
    +{
    +	Buffer m;
    +	u_int type, ver;
    +
    +	buffer_init(&m);
    +	buffer_put_int(&m, MUX_MSG_HELLO);
    +	buffer_put_int(&m, SSHMUX_VER);
    +	/* no extensions */
    +
    +	if (mux_client_write_packet(fd, &m) != 0)
    +		fatal("%s: write packet: %s", __func__, strerror(errno));
    +
    +	buffer_clear(&m);
    +
    +	/* Read their HELLO */
    +	if (mux_client_read_packet(fd, &m) != 0) {
    +		buffer_free(&m);
    +		return -1;
    +	}
    +
    +	type = buffer_get_int(&m);
    +	if (type != MUX_MSG_HELLO)
    +		fatal("%s: expected HELLO (%u) received %u",
    +		    __func__, MUX_MSG_HELLO, type);
    +	ver = buffer_get_int(&m);
    +	if (ver != SSHMUX_VER)
    +		fatal("Unsupported multiplexing protocol version %d "
    +		    "(expected %d)", ver, SSHMUX_VER);
    +	debug2("%s: master version %u", __func__, ver);
    +	/* No extensions are presently defined */
    +	while (buffer_len(&m) > 0) {
    +		char *name = buffer_get_string(&m, NULL);
    +		char *value = buffer_get_string(&m, NULL);
    +
    +		debug2("Unrecognised master extension \"%s\"", name);
    +		xfree(name);
    +		xfree(value);
    +	}
    +	buffer_free(&m);
    +	return 0;
    +}
    +
    +static u_int
    +mux_client_request_alive(int fd)
    +{
    +	Buffer m;
    +	char *e;
    +	u_int pid, type, rid;
    +
    +	debug3("%s: entering", __func__);
    +
    +	buffer_init(&m);
    +	buffer_put_int(&m, MUX_C_ALIVE_CHECK);
    +	buffer_put_int(&m, muxclient_request_id);
    +
    +	if (mux_client_write_packet(fd, &m) != 0)
    +		fatal("%s: write packet: %s", __func__, strerror(errno));
    +
    +	buffer_clear(&m);
    +
    +	/* Read their reply */
    +	if (mux_client_read_packet(fd, &m) != 0) {
    +		buffer_free(&m);
    +		return 0;
    +	}
    +
    +	type = buffer_get_int(&m);
    +	if (type != MUX_S_ALIVE) {
    +		e = buffer_get_string(&m, NULL);
    +		fatal("%s: master returned error: %s", __func__, e);
    +	}
    +
    +	if ((rid = buffer_get_int(&m)) != muxclient_request_id)
    +		fatal("%s: out of sequence reply: my id %u theirs %u",
    +		    __func__, muxclient_request_id, rid);
    +	pid = buffer_get_int(&m);
    +	buffer_free(&m);
    +
    +	debug3("%s: done pid = %u", __func__, pid);
    +
    +	muxclient_request_id++;
    +
    +	return pid;
    +}
    +
    +static void
    +mux_client_request_terminate(int fd)
    +{
    +	Buffer m;
    +	char *e;
    +	u_int type, rid;
    +
    +	debug3("%s: entering", __func__);
    +
    +	buffer_init(&m);
    +	buffer_put_int(&m, MUX_C_TERMINATE);
    +	buffer_put_int(&m, muxclient_request_id);
    +
    +	if (mux_client_write_packet(fd, &m) != 0)
    +		fatal("%s: write packet: %s", __func__, strerror(errno));
    +
    +	buffer_clear(&m);
    +
    +	/* Read their reply */
    +	if (mux_client_read_packet(fd, &m) != 0) {
    +		/* Remote end exited already */
    +		if (errno == EPIPE) {
    +			buffer_free(&m);
    +			return;
    +		}
    +		fatal("%s: read from master failed: %s",
    +		    __func__, strerror(errno));
    +	}
    +
    +	type = buffer_get_int(&m);
    +	if ((rid = buffer_get_int(&m)) != muxclient_request_id)
    +		fatal("%s: out of sequence reply: my id %u theirs %u",
    +		    __func__, muxclient_request_id, rid);
    +	switch (type) {
    +	case MUX_S_OK:
    +		break;
    +	case MUX_S_PERMISSION_DENIED:
    +		e = buffer_get_string(&m, NULL);
    +		fatal("Master refused termination request: %s", e);
    +	case MUX_S_FAILURE:
    +		e = buffer_get_string(&m, NULL);
    +		fatal("%s: termination request failed: %s", __func__, e);
    +	default:
    +		fatal("%s: unexpected response from master 0x%08x",
    +		    __func__, type);
    +	}
    +	buffer_free(&m);
    +	muxclient_request_id++;
    +}
    +
    +static int
    +mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
    +{
    +	Buffer m;
    +	char *e, *fwd_desc;
    +	u_int type, rid;
    +
    +	fwd_desc = format_forward(ftype, fwd);
    +	debug("Requesting %s", fwd_desc);
    +	xfree(fwd_desc);
    +
    +	buffer_init(&m);
    +	buffer_put_int(&m, MUX_C_OPEN_FWD);
    +	buffer_put_int(&m, muxclient_request_id);
    +	buffer_put_int(&m, ftype);
    +	buffer_put_cstring(&m,
    +	    fwd->listen_host == NULL ? "" : fwd->listen_host);
    +	buffer_put_int(&m, fwd->listen_port);
    +	buffer_put_cstring(&m,
    +	    fwd->connect_host == NULL ? "" : fwd->connect_host);
    +	buffer_put_int(&m, fwd->connect_port);
    +
    +	if (mux_client_write_packet(fd, &m) != 0)
    +		fatal("%s: write packet: %s", __func__, strerror(errno));
    +
    +	buffer_clear(&m);
    +
    +	/* Read their reply */
    +	if (mux_client_read_packet(fd, &m) != 0) {
    +		buffer_free(&m);
    +		return -1;
    +	}
    +
    +	type = buffer_get_int(&m);
    +	if ((rid = buffer_get_int(&m)) != muxclient_request_id)
    +		fatal("%s: out of sequence reply: my id %u theirs %u",
    +		    __func__, muxclient_request_id, rid);
    +	switch (type) {
    +	case MUX_S_OK:
    +		break;
    +	case MUX_S_PERMISSION_DENIED:
    +		e = buffer_get_string(&m, NULL);
    +		buffer_free(&m);
    +		error("Master refused forwarding request: %s", e);
    +		return -1;
    +	case MUX_S_FAILURE:
    +		e = buffer_get_string(&m, NULL);
    +		buffer_free(&m);
    +		error("%s: session request failed: %s", __func__, e);
    +		return -1;
    +	default:
    +		fatal("%s: unexpected response from master 0x%08x",
    +		    __func__, type);
    +	}
    +	buffer_free(&m);
    +
    +	muxclient_request_id++;
    +	return 0;
    +}
    +
    +static int
    +mux_client_request_forwards(int fd)
    +{
    +	int i;
    +
    +	debug3("%s: requesting forwardings: %d local, %d remote", __func__,
    +	    options.num_local_forwards, options.num_remote_forwards);
    +
    +	/* XXX ExitOnForwardingFailure */
    +	for (i = 0; i < options.num_local_forwards; i++) {
    +		if (mux_client_request_forward(fd,
    +		    options.local_forwards[i].connect_port == 0 ?
    +		    MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,
    +		    options.local_forwards + i) != 0)
    +			return -1;
    +	}
    +	for (i = 0; i < options.num_remote_forwards; i++) {
    +		if (mux_client_request_forward(fd, MUX_FWD_REMOTE,
    +		    options.remote_forwards + i) != 0)
    +			return -1;
    +	}
    +	return 0;
    +}
    +
    +static int
    +mux_client_request_session(int fd)
    +{
    +	Buffer m;
    +	char *e, *term;
    +	u_int i, rid, sid, esid, exitval, type, exitval_seen;
    +	extern char **environ;
    +	int devnull;
    +
    +	debug3("%s: entering", __func__);
    +
    +	if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
    +		error("%s: master alive request failed", __func__);
    +		return -1;
    +	}
    +
    +	signal(SIGPIPE, SIG_IGN);
    +
    +	if (stdin_null_flag) {
    +		if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)
    +			fatal("open(/dev/null): %s", strerror(errno));
    +		if (dup2(devnull, STDIN_FILENO) == -1)
    +			fatal("dup2: %s", strerror(errno));
    +		if (devnull > STDERR_FILENO)
    +			close(devnull);
    +	}
    +
    +	term = getenv("TERM");
    +
    +	buffer_init(&m);
    +	buffer_put_int(&m, MUX_C_NEW_SESSION);
    +	buffer_put_int(&m, muxclient_request_id);
    +	buffer_put_cstring(&m, ""); /* reserved */
    +	buffer_put_int(&m, tty_flag);
    +	buffer_put_int(&m, options.forward_x11);
    +	buffer_put_int(&m, options.forward_agent);
    +	buffer_put_int(&m, subsystem_flag);
    +	buffer_put_int(&m, options.escape_char == SSH_ESCAPECHAR_NONE ?
    +	    0xffffffff : (u_int)options.escape_char);
    +	buffer_put_cstring(&m, term == NULL ? "" : term);
    +	buffer_put_string(&m, buffer_ptr(&command), buffer_len(&command));
    +
    +	if (options.num_send_env > 0 && environ != NULL) {
    +		/* Pass environment */
    +		for (i = 0; environ[i] != NULL; i++) {
    +			if (env_permitted(environ[i])) {
    +				buffer_put_cstring(&m, environ[i]);
    +			}
    +		}
    +	}
    +
    +	if (mux_client_write_packet(fd, &m) != 0)
    +		fatal("%s: write packet: %s", __func__, strerror(errno));
    +
    +	/* Send the stdio file descriptors */
    +	if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
    +	    mm_send_fd(fd, STDOUT_FILENO) == -1 ||
    +	    mm_send_fd(fd, STDERR_FILENO) == -1)
    +		fatal("%s: send fds failed", __func__);
    +
    +	debug3("%s: session request sent", __func__);
    +
    +	/* Read their reply */
    +	buffer_clear(&m);
    +	if (mux_client_read_packet(fd, &m) != 0) {
    +		error("%s: read from master failed: %s",
    +		    __func__, strerror(errno));
    +		buffer_free(&m);
    +		return -1;
    +	}
    +
    +	type = buffer_get_int(&m);
    +	if ((rid = buffer_get_int(&m)) != muxclient_request_id)
    +		fatal("%s: out of sequence reply: my id %u theirs %u",
    +		    __func__, muxclient_request_id, rid);
    +	switch (type) {
    +	case MUX_S_SESSION_OPENED:
    +		sid = buffer_get_int(&m);
    +		debug("%s: master session id: %u", __func__, sid);
    +		break;
    +	case MUX_S_PERMISSION_DENIED:
    +		e = buffer_get_string(&m, NULL);
    +		buffer_free(&m);
    +		error("Master refused forwarding request: %s", e);
    +		return -1;
    +	case MUX_S_FAILURE:
    +		e = buffer_get_string(&m, NULL);
    +		buffer_free(&m);
    +		error("%s: forwarding request failed: %s", __func__, e);
    +		return -1;
    +	default:
    +		buffer_free(&m);
    +		error("%s: unexpected response from master 0x%08x",
    +		    __func__, type);
    +		return -1;
    +	}
    +	muxclient_request_id++;
    +
    +	signal(SIGHUP, control_client_sighandler);
    +	signal(SIGINT, control_client_sighandler);
    +	signal(SIGTERM, control_client_sighandler);
    +	signal(SIGWINCH, control_client_sigrelay);
    +
    +	if (tty_flag)
    +		enter_raw_mode(force_tty_flag);
    +
    +	/*
    +	 * Stick around until the controlee closes the client_fd.
    +	 * Before it does, it is expected to write an exit message.
    +	 * This process must read the value and wait for the closure of
    +	 * the client_fd; if this one closes early, the multiplex master will
    +	 * terminate early too (possibly losing data).
    +	 */
    +	for (exitval = 255, exitval_seen = 0;;) {
    +		buffer_clear(&m);
    +		if (mux_client_read_packet(fd, &m) != 0)
    +			break;
    +		type = buffer_get_int(&m);
    +		if (type != MUX_S_EXIT_MESSAGE) {
    +			e = buffer_get_string(&m, NULL);
    +			fatal("%s: master returned error: %s", __func__, e);
    +		}
    +		if ((esid = buffer_get_int(&m)) != sid)
    +			fatal("%s: exit on unknown session: my id %u theirs %u",
    +			    __func__, sid, esid);
    +		debug("%s: master session id: %u", __func__, sid);
    +		if (exitval_seen)
    +			fatal("%s: exitval sent twice", __func__);
    +		exitval = buffer_get_int(&m);
    +		exitval_seen = 1;
    +	}
    +
    +	close(fd);
    +	leave_raw_mode(force_tty_flag);
    +
    +	if (muxclient_terminate) {
    +		debug2("Exiting on signal %d", muxclient_terminate);
    +		exitval = 255;
    +	} else if (!exitval_seen) {
    +		debug2("Control master terminated unexpectedly");
    +		exitval = 255;
    +	} else
    +		debug2("Received exit status from master %d", exitval);
    +
    +	if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
    +		fprintf(stderr, "Shared connection to %s closed.\r\n", host);
    +
    +	exit(exitval);
    +}
    +
    +static int
    +mux_client_request_stdio_fwd(int fd)
    +{
    +	Buffer m;
    +	char *e;
    +	u_int type, rid, sid;
    +	int devnull;
    +
    +	debug3("%s: entering", __func__);
    +
    +	if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
    +		error("%s: master alive request failed", __func__);
    +		return -1;
    +	}
    +
    +	signal(SIGPIPE, SIG_IGN);
    +
    +	if (stdin_null_flag) {
    +		if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)
    +			fatal("open(/dev/null): %s", strerror(errno));
    +		if (dup2(devnull, STDIN_FILENO) == -1)
    +			fatal("dup2: %s", strerror(errno));
    +		if (devnull > STDERR_FILENO)
    +			close(devnull);
    +	}
    +
    +	buffer_init(&m);
    +	buffer_put_int(&m, MUX_C_NEW_STDIO_FWD);
    +	buffer_put_int(&m, muxclient_request_id);
    +	buffer_put_cstring(&m, ""); /* reserved */
    +	buffer_put_cstring(&m, stdio_forward_host);
    +	buffer_put_int(&m, stdio_forward_port);
    +
    +	if (mux_client_write_packet(fd, &m) != 0)
    +		fatal("%s: write packet: %s", __func__, strerror(errno));
    +
    +	/* Send the stdio file descriptors */
    +	if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
    +	    mm_send_fd(fd, STDOUT_FILENO) == -1)
    +		fatal("%s: send fds failed", __func__);
    +
    +	debug3("%s: stdio forward request sent", __func__);
    +
    +	/* Read their reply */
    +	buffer_clear(&m);
    +
    +	if (mux_client_read_packet(fd, &m) != 0) {
    +		error("%s: read from master failed: %s",
    +		    __func__, strerror(errno));
    +		buffer_free(&m);
    +		return -1;
    +	}
    +
    +	type = buffer_get_int(&m);
    +	if ((rid = buffer_get_int(&m)) != muxclient_request_id)
    +		fatal("%s: out of sequence reply: my id %u theirs %u",
    +		    __func__, muxclient_request_id, rid);
    +	switch (type) {
    +	case MUX_S_SESSION_OPENED:
    +		sid = buffer_get_int(&m);
    +		debug("%s: master session id: %u", __func__, sid);
    +		break;
    +	case MUX_S_PERMISSION_DENIED:
    +		e = buffer_get_string(&m, NULL);
    +		buffer_free(&m);
    +		fatal("Master refused forwarding request: %s", e);
    +	case MUX_S_FAILURE:
    +		e = buffer_get_string(&m, NULL);
    +		buffer_free(&m);
    +		fatal("%s: stdio forwarding request failed: %s", __func__, e);
    +	default:
    +		buffer_free(&m);
    +		error("%s: unexpected response from master 0x%08x",
    +		    __func__, type);
    +		return -1;
    +	}
    +	muxclient_request_id++;
    +
    +	signal(SIGHUP, control_client_sighandler);
    +	signal(SIGINT, control_client_sighandler);
    +	signal(SIGTERM, control_client_sighandler);
    +	signal(SIGWINCH, control_client_sigrelay);
    +
    +	/*
    +	 * Stick around until the controlee closes the client_fd.
    +	 */
    +	buffer_clear(&m);
    +	if (mux_client_read_packet(fd, &m) != 0) {
    +		if (errno == EPIPE ||
    +		    (errno == EINTR && muxclient_terminate != 0))
    +			return 0;
    +		fatal("%s: mux_client_read_packet: %s",
    +		    __func__, strerror(errno));
    +	}
    +	fatal("%s: master returned unexpected message %u", __func__, type);
     }
     
     /* Multiplex client main loop. */
    @@ -502,14 +1661,16 @@ void
     muxclient(const char *path)
     {
     	struct sockaddr_un addr;
    -	int i, r, fd, sock, exitval[2], num_env, addr_len;
    -	Buffer m;
    -	char *term;
    -	extern char **environ;
    -	u_int allowed, flags;
    +	socklen_t sun_len;
    +	int sock;
    +	u_int pid;
     
    -	if (muxclient_command == 0)
    -		muxclient_command = SSHMUX_COMMAND_OPEN;
    +	if (muxclient_command == 0) {
    +		if (stdio_forward_host != NULL)
    +			muxclient_command = SSHMUX_COMMAND_STDIO_FWD;
    +		else
    +			muxclient_command = SSHMUX_COMMAND_OPEN;
    +	}
     
     	switch (options.control_master) {
     	case SSHCTL_MASTER_AUTO:
    @@ -524,7 +1685,7 @@ muxclient(const char *path)
     
     	memset(&addr, '\0', sizeof(addr));
     	addr.sun_family = AF_UNIX;
    -	addr_len = offsetof(struct sockaddr_un, sun_path) +
    +	sun_len = offsetof(struct sockaddr_un, sun_path) +
     	    strlen(path) + 1;
     
     	if (strlcpy(addr.sun_path, path,
    @@ -534,8 +1695,12 @@ muxclient(const char *path)
     	if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
     		fatal("%s socket(): %s", __func__, strerror(errno));
     
    -	if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) {
    -		if (muxclient_command != SSHMUX_COMMAND_OPEN) {
    +	if (connect(sock, (struct sockaddr *)&addr, sun_len) == -1) {
    +		switch (muxclient_command) {
    +		case SSHMUX_COMMAND_OPEN:
    +		case SSHMUX_COMMAND_STDIO_FWD:
    +			break;
    +		default:
     			fatal("Control socket connect(%.100s): %s", path,
     			    strerror(errno));
     		}
    @@ -548,181 +1713,35 @@ muxclient(const char *path)
     		close(sock);
     		return;
     	}
    +	set_nonblock(sock);
     
    -	if (stdin_null_flag) {
    -		if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
    -			fatal("open(/dev/null): %s", strerror(errno));
    -		if (dup2(fd, STDIN_FILENO) == -1)
    -			fatal("dup2: %s", strerror(errno));
    -		if (fd > STDERR_FILENO)
    -			close(fd);
    -	}
    -
    -	term = getenv("TERM");
    -
    -	flags = 0;
    -	if (tty_flag)
    -		flags |= SSHMUX_FLAG_TTY;
    -	if (subsystem_flag)
    -		flags |= SSHMUX_FLAG_SUBSYS;
    -	if (options.forward_x11)
    -		flags |= SSHMUX_FLAG_X11_FWD;
    -	if (options.forward_agent)
    -		flags |= SSHMUX_FLAG_AGENT_FWD;
    -
    -	signal(SIGPIPE, SIG_IGN);
    -
    -	buffer_init(&m);
    -
    -	/* Send our command to server */
    -	buffer_put_int(&m, muxclient_command);
    -	buffer_put_int(&m, flags);
    -	if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
    -		error("%s: msg_send", __func__);
    - muxerr:
    +	if (mux_client_hello_exchange(sock) != 0) {
    +		error("%s: master hello exchange failed", __func__);
     		close(sock);
    -		buffer_free(&m);
    -		if (muxclient_command != SSHMUX_COMMAND_OPEN)
    -			cleanup_exit(255);
    -		logit("Falling back to non-multiplexed connection");
    -		xfree(options.control_path);
    -		options.control_path = NULL;
    -		options.control_master = SSHCTL_MASTER_NO;
     		return;
     	}
    -	buffer_clear(&m);
    -
    -	/* Get authorisation status and PID of controlee */
    -	if (ssh_msg_recv(sock, &m) == -1) {
    -		error("%s: Did not receive reply from master", __func__);
    -		goto muxerr;
    -	}
    -	if (buffer_get_char(&m) != SSHMUX_VER) {
    -		error("%s: Master replied with wrong version", __func__);
    -		goto muxerr;
    -	}
    -	if (buffer_get_int_ret(&allowed, &m) != 0) {
    -		error("%s: bad server reply", __func__);
    -		goto muxerr;
    -	}
    -	if (allowed != 1) {
    -		error("Connection to master denied");
    -		goto muxerr;
    -	}
    -	muxserver_pid = buffer_get_int(&m);
    -
    -	buffer_clear(&m);
     
     	switch (muxclient_command) {
     	case SSHMUX_COMMAND_ALIVE_CHECK:
    -		fprintf(stderr, "Master running (pid=%d)\r\n",
    -		    muxserver_pid);
    +		if ((pid = mux_client_request_alive(sock)) == 0)
    +			fatal("%s: master alive check failed", __func__);
    +		fprintf(stderr, "Master running (pid=%d)\r\n", pid);
     		exit(0);
     	case SSHMUX_COMMAND_TERMINATE:
    +		mux_client_request_terminate(sock);
     		fprintf(stderr, "Exit request sent.\r\n");
     		exit(0);
     	case SSHMUX_COMMAND_OPEN:
    -		buffer_put_cstring(&m, term ? term : "");
    -		if (options.escape_char == SSH_ESCAPECHAR_NONE)
    -			buffer_put_int(&m, 0xffffffff);
    -		else
    -			buffer_put_int(&m, options.escape_char);
    -		buffer_append(&command, "\0", 1);
    -		buffer_put_cstring(&m, buffer_ptr(&command));
    -
    -		if (options.num_send_env == 0 || environ == NULL) {
    -			buffer_put_int(&m, 0);
    -		} else {
    -			/* Pass environment */
    -			num_env = 0;
    -			for (i = 0; environ[i] != NULL; i++) {
    -				if (env_permitted(environ[i]))
    -					num_env++; /* Count */
    -			}
    -			buffer_put_int(&m, num_env);
    -		for (i = 0; environ[i] != NULL && num_env >= 0; i++) {
    -				if (env_permitted(environ[i])) {
    -					num_env--;
    -					buffer_put_cstring(&m, environ[i]);
    -				}
    -			}
    +		if (mux_client_request_forwards(sock) != 0) {
    +			error("%s: master forward request failed", __func__);
    +			return;
     		}
    -		break;
    +		mux_client_request_session(sock);
    +		return;
    +	case SSHMUX_COMMAND_STDIO_FWD:
    +		mux_client_request_stdio_fwd(sock);
    +		exit(0);
     	default:
     		fatal("unrecognised muxclient_command %d", muxclient_command);
     	}
    -
    -	if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
    -		error("%s: msg_send", __func__);
    -		goto muxerr;
    -	}
    -
    -	if (mm_send_fd(sock, STDIN_FILENO) == -1 ||
    -	    mm_send_fd(sock, STDOUT_FILENO) == -1 ||
    -	    mm_send_fd(sock, STDERR_FILENO) == -1) {
    -		error("%s: send fds failed", __func__);
    -		goto muxerr;
    -	}
    -
    -	/*
    -	 * Mux errors are non-recoverable from this point as the master
    -	 * has ownership of the session now.
    -	 */
    -
    -	/* Wait for reply, so master has a chance to gather ttymodes */
    -	buffer_clear(&m);
    -	if (ssh_msg_recv(sock, &m) == -1)
    -		fatal("%s: msg_recv", __func__);
    -	if (buffer_get_char(&m) != SSHMUX_VER)
    -		fatal("%s: wrong version", __func__);
    -	buffer_free(&m);
    -
    -	signal(SIGHUP, control_client_sighandler);
    -	signal(SIGINT, control_client_sighandler);
    -	signal(SIGTERM, control_client_sighandler);
    -	signal(SIGWINCH, control_client_sigrelay);
    -
    -	if (tty_flag)
    -		enter_raw_mode();
    -
    -	/*
    -	 * Stick around until the controlee closes the client_fd.
    -	 * Before it does, it is expected to write this process' exit
    -	 * value (one int). This process must read the value and wait for
    -	 * the closure of the client_fd; if this one closes early, the 
    -	 * multiplex master will terminate early too (possibly losing data).
    -	 */
    -	exitval[0] = 0;
    -	for (i = 0; !muxclient_terminate && i < (int)sizeof(exitval);) {
    -		r = read(sock, (char *)exitval + i, sizeof(exitval) - i);
    -		if (r == 0) {
    -			debug2("Received EOF from master");
    -			break;
    -		}
    -		if (r == -1) {
    -			if (errno == EINTR)
    -				continue;
    -			fatal("%s: read %s", __func__, strerror(errno));
    -		}
    -		i += r;
    -	}
    -
    -	close(sock);
    -	leave_raw_mode();
    -	if (i > (int)sizeof(int))
    -		fatal("%s: master returned too much data (%d > %lu)",
    -		    __func__, i, (u_long)sizeof(int));
    -	if (muxclient_terminate) {
    -		debug2("Exiting on signal %d", muxclient_terminate);
    -		exitval[0] = 255;
    -	} else if (i < (int)sizeof(int)) {
    -		debug2("Control master terminated unexpectedly");
    -		exitval[0] = 255;
    -	} else
    -		debug2("Received exit status from master %d", exitval[0]);
    -
    -	if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
    -		fprintf(stderr, "Shared connection to %s closed.\r\n", host);
    -
    -	exit(exitval[0]);
     }
    diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h
    index 7bca3bcae44..98f27fd1593 100644
    --- a/crypto/openssh/myproposal.h
    +++ b/crypto/openssh/myproposal.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: myproposal.h,v 1.23 2009/01/23 07:58:11 djm Exp $ */
    +/* $OpenBSD: myproposal.h,v 1.24 2010/02/26 20:29:54 djm Exp $ */
     
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
    @@ -40,7 +40,9 @@
     	"diffie-hellman-group1-sha1"
     #endif
     
    -#define	KEX_DEFAULT_PK_ALG	"ssh-rsa,ssh-dss"
    +#define	KEX_DEFAULT_PK_ALG	"ssh-rsa-cert-v00@openssh.com," \
    +				"ssh-dss-cert-v00@openssh.com," \
    +				"ssh-rsa,ssh-dss"
     
     #define	KEX_DEFAULT_ENCRYPT \
     	"aes128-ctr,aes192-ctr,aes256-ctr," \
    diff --git a/crypto/openssh/nchan.c b/crypto/openssh/nchan.c
    index 160445e5a26..20f6a2f4990 100644
    --- a/crypto/openssh/nchan.c
    +++ b/crypto/openssh/nchan.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: nchan.c,v 1.62 2008/11/07 18:50:18 stevesk Exp $ */
    +/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */
     /*
      * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
      *
    @@ -161,7 +161,7 @@ chan_ibuf_empty(Channel *c)
     	switch (c->istate) {
     	case CHAN_INPUT_WAIT_DRAIN:
     		if (compat20) {
    -			if (!(c->flags & CHAN_CLOSE_SENT))
    +			if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
     				chan_send_eof2(c);
     			chan_set_istate(c, CHAN_INPUT_CLOSED);
     		} else {
    @@ -278,9 +278,12 @@ static void
     chan_rcvd_close2(Channel *c)
     {
     	debug2("channel %d: rcvd close", c->self);
    -	if (c->flags & CHAN_CLOSE_RCVD)
    -		error("channel %d: protocol error: close rcvd twice", c->self);
    -	c->flags |= CHAN_CLOSE_RCVD;
    +	if (!(c->flags & CHAN_LOCAL)) {
    +		if (c->flags & CHAN_CLOSE_RCVD)
    +			error("channel %d: protocol error: close rcvd twice",
    +			    c->self);
    +		c->flags |= CHAN_CLOSE_RCVD;
    +	}
     	if (c->type == SSH_CHANNEL_LARVAL) {
     		/* tear down larval channels immediately */
     		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
    @@ -302,11 +305,13 @@ chan_rcvd_close2(Channel *c)
     		chan_set_istate(c, CHAN_INPUT_CLOSED);
     		break;
     	case CHAN_INPUT_WAIT_DRAIN:
    -		chan_send_eof2(c);
    +		if (!(c->flags & CHAN_LOCAL))
    +			chan_send_eof2(c);
     		chan_set_istate(c, CHAN_INPUT_CLOSED);
     		break;
     	}
     }
    +
     void
     chan_rcvd_eow(Channel *c)
     {
    @@ -454,6 +459,10 @@ chan_is_dead(Channel *c, int do_send)
     		    c->self, c->efd, buffer_len(&c->extended));
     		return 0;
     	}
    +	if (c->flags & CHAN_LOCAL) {
    +		debug2("channel %d: is dead (local)", c->self);
    +		return 1;
    +	}		
     	if (!(c->flags & CHAN_CLOSE_SENT)) {
     		if (do_send) {
     			chan_send_close2(c);
    diff --git a/crypto/openssh/openbsd-compat/bsd-cygwin_util.c b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c
    index 38be7e350ae..e9fa3a0e244 100644
    --- a/crypto/openssh/openbsd-compat/bsd-cygwin_util.c
    +++ b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c
    @@ -39,9 +39,6 @@
     #endif
     
     #include 
    -#include 
    -#include 
    -#include 
     
     #include 
     #include 
    @@ -49,11 +46,6 @@
     #include 
     
     #include "xmalloc.h"
    -#define is_winnt       (GetVersion() < 0x80000000)
    -
    -#define ntsec_on(c)	((c) && strstr((c),"ntsec") && !strstr((c),"nontsec"))
    -#define ntsec_off(c)	((c) && strstr((c),"nontsec"))
    -#define ntea_on(c)	((c) && strstr((c),"ntea") && !strstr((c),"nontea"))
     
     int 
     binary_open(const char *filename, int flags, ...)
    @@ -79,128 +71,12 @@ binary_pipe(int fd[2])
     	return (ret);
     }
     
    -#define HAS_CREATE_TOKEN 1
    -#define HAS_NTSEC_BY_DEFAULT 2
    -#define HAS_CREATE_TOKEN_WO_NTSEC 3
    -
    -static int 
    -has_capability(int what)
    -{
    -	static int inited;
    -	static int has_create_token;
    -	static int has_ntsec_by_default;
    -	static int has_create_token_wo_ntsec;
    -
    -	/* 
    -	 * has_capability() basically calls uname() and checks if
    -	 * specific capabilities of Cygwin can be evaluated from that.
    -	 * This simplifies the calling functions which only have to ask
    -	 * for a capability using has_capability() instead of having
    -	 * to figure that out by themselves.
    -	 */
    -	if (!inited) {
    -		struct utsname uts;
    -		
    -		if (!uname(&uts)) {
    -			int major_high = 0, major_low = 0, minor = 0;
    -			int api_major_version = 0, api_minor_version = 0;
    -			char *c;
    -
    -			sscanf(uts.release, "%d.%d.%d", &major_high,
    -			    &major_low, &minor);
    -			if ((c = strchr(uts.release, '(')) != NULL) {
    -				sscanf(c + 1, "%d.%d", &api_major_version,
    -				    &api_minor_version);
    -			}
    -			if (major_high > 1 ||
    -			    (major_high == 1 && (major_low > 3 ||
    -			    (major_low == 3 && minor >= 2))))
    -				has_create_token = 1;
    -			if (api_major_version > 0 || api_minor_version >= 56)
    -				has_ntsec_by_default = 1;
    -			if (major_high > 1 ||
    -			    (major_high == 1 && major_low >= 5))
    -				has_create_token_wo_ntsec = 1;
    -			inited = 1;
    -		}
    -	}
    -	switch (what) {
    -	case HAS_CREATE_TOKEN:
    -		return (has_create_token);
    -	case HAS_NTSEC_BY_DEFAULT:
    -		return (has_ntsec_by_default);
    -	case HAS_CREATE_TOKEN_WO_NTSEC:
    -		return (has_create_token_wo_ntsec);
    -	}
    -	return (0);
    -}
    -
    -int
    -check_nt_auth(int pwd_authenticated, struct passwd *pw)
    -{
    -	/*
    -	* The only authentication which is able to change the user
    -	* context on NT systems is the password authentication. So
    -	* we deny all requsts for changing the user context if another
    -	* authentication method is used.
    -	*
    -	* This doesn't apply to Cygwin versions >= 1.3.2 anymore which
    -	* uses the undocumented NtCreateToken() call to create a user
    -	* token if the process has the appropriate privileges and if
    -	* CYGWIN ntsec setting is on.
    -	*/
    -	static int has_create_token = -1;
    -
    -	if (pw == NULL)
    -		return 0;
    -	if (is_winnt) {
    -		if (has_create_token < 0) {
    -			char *cygwin = getenv("CYGWIN");
    -
    -			has_create_token = 0;
    -			if (has_capability(HAS_CREATE_TOKEN) &&
    -			    (ntsec_on(cygwin) ||
    -			    (has_capability(HAS_NTSEC_BY_DEFAULT) &&
    -			     !ntsec_off(cygwin)) ||
    -			     has_capability(HAS_CREATE_TOKEN_WO_NTSEC)))
    -				has_create_token = 1;
    -		}
    -		if (has_create_token < 1 &&
    -		    !pwd_authenticated && geteuid() != pw->pw_uid)
    -			return (0);
    -	}
    -	return (1);
    -}
    -
     int
     check_ntsec(const char *filename)
     {
     	return (pathconf(filename, _PC_POSIX_PERMISSIONS));
     }
     
    -void
    -register_9x_service(void)
    -{
    -        HINSTANCE kerneldll;
    -        DWORD (*RegisterServiceProcess)(DWORD, DWORD);
    -
    -	/* The service register mechanism in 9x/Me is pretty different from
    -	 * NT/2K/XP.  In NT/2K/XP we're using a special service starter
    -	 * application to register and control sshd as service.  This method
    -	 * doesn't play nicely with 9x/Me.  For that reason we register here
    -	 * as service when running under 9x/Me.  This function is only called
    -	 * by the child sshd when it's going to daemonize.
    -	 */
    -	if (is_winnt)
    -		return;
    -	if (!(kerneldll = LoadLibrary("KERNEL32.DLL")))
    -		return;
    -	if (!(RegisterServiceProcess = (DWORD (*)(DWORD, DWORD))
    -		GetProcAddress(kerneldll, "RegisterServiceProcess")))
    -		return;
    -	RegisterServiceProcess(0, 1);
    -}
    -
     #define NL(x) x, (sizeof (x) - 1)
     #define WENV_SIZ (sizeof (wenv_arr) / sizeof (wenv_arr[0]))
     
    @@ -209,23 +85,14 @@ static struct wenv {
     	size_t namelen;
     } wenv_arr[] = {
     	{ NL("ALLUSERSPROFILE=") },
    -	{ NL("COMMONPROGRAMFILES=") },
     	{ NL("COMPUTERNAME=") },
     	{ NL("COMSPEC=") },
     	{ NL("CYGWIN=") },
    -	{ NL("NUMBER_OF_PROCESSORS=") },
     	{ NL("OS=") },
     	{ NL("PATH=") },
     	{ NL("PATHEXT=") },
    -	{ NL("PROCESSOR_ARCHITECTURE=") },
    -	{ NL("PROCESSOR_IDENTIFIER=") },
    -	{ NL("PROCESSOR_LEVEL=") },
    -	{ NL("PROCESSOR_REVISION=") },
    -	{ NL("PROGRAMFILES=") },
     	{ NL("SYSTEMDRIVE=") },
     	{ NL("SYSTEMROOT=") },
    -	{ NL("TMP=") },
    -	{ NL("TEMP=") },
     	{ NL("WINDIR=") }
     };
     
    diff --git a/crypto/openssh/openbsd-compat/bsd-cygwin_util.h b/crypto/openssh/openbsd-compat/bsd-cygwin_util.h
    index 6719b8a49c2..39b8eb788df 100644
    --- a/crypto/openssh/openbsd-compat/bsd-cygwin_util.h
    +++ b/crypto/openssh/openbsd-compat/bsd-cygwin_util.h
    @@ -1,4 +1,4 @@
    -/* $Id: bsd-cygwin_util.h,v 1.11 2004/08/30 10:42:08 dtucker Exp $ */
    +/* $Id: bsd-cygwin_util.h,v 1.12 2009/03/08 00:40:28 dtucker Exp $ */
     
     /*
      * Copyright (c) 2000, 2001, Corinna Vinschen 
    @@ -35,7 +35,6 @@
     #ifdef HAVE_CYGWIN
     
     #undef ERROR
    -#define is_winnt       (GetVersion() < 0x80000000)
     
     #include 
     #include 
    @@ -43,9 +42,7 @@
     
     int binary_open(const char *, int , ...);
     int binary_pipe(int fd[2]);
    -int check_nt_auth(int, struct passwd *);
     int check_ntsec(const char *);
    -void register_9x_service(void);
     char **fetch_windows_environment(void);
     void free_windows_environment(char **);
     
    diff --git a/crypto/openssh/openbsd-compat/daemon.c b/crypto/openssh/openbsd-compat/daemon.c
    index e3a6886bd1c..3efe14c68c4 100644
    --- a/crypto/openssh/openbsd-compat/daemon.c
    +++ b/crypto/openssh/openbsd-compat/daemon.c
    @@ -57,18 +57,8 @@ daemon(int nochdir, int noclose)
     	case -1:
     		return (-1);
     	case 0:
    -#ifdef HAVE_CYGWIN
    -		register_9x_service();
    -#endif
     		break;
     	default:
    -#ifdef HAVE_CYGWIN
    -		/*
    -		 * This sleep avoids a race condition which kills the
    -		 * child process if parent is started by a NT/W2K service.
    -		 */
    -		sleep(1);
    -#endif
     		_exit(0);
     	}
     
    diff --git a/crypto/openssh/openbsd-compat/getrrsetbyname.c b/crypto/openssh/openbsd-compat/getrrsetbyname.c
    index 785b2256911..98876673d00 100644
    --- a/crypto/openssh/openbsd-compat/getrrsetbyname.c
    +++ b/crypto/openssh/openbsd-compat/getrrsetbyname.c
    @@ -143,7 +143,7 @@ u_int32_t _getlong(register const u_char *);
     
     /* ************** */
     
    -#define ANSWER_BUFFER_SIZE 1024*64
    +#define ANSWER_BUFFER_SIZE 0xffff
     
     struct dns_query {
     	char			*name;
    diff --git a/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h
    index 50c6d990bf1..cad2408d6a0 100644
    --- a/crypto/openssh/openbsd-compat/openbsd-compat.h
    +++ b/crypto/openssh/openbsd-compat/openbsd-compat.h
    @@ -1,4 +1,4 @@
    -/* $Id: openbsd-compat.h,v 1.46 2008/06/08 17:32:29 dtucker Exp $ */
    +/* $Id: openbsd-compat.h,v 1.49 2010/01/16 12:58:37 dtucker Exp $ */
     
     /*
      * Copyright (c) 1999-2003 Damien Miller.  All rights reserved.
    @@ -200,6 +200,14 @@ int vasprintf(char **, const char *, va_list);
     int vsnprintf(char *, size_t, const char *, va_list);
     #endif
     
    +#ifndef HAVE_USER_FROM_UID
    +char *user_from_uid(uid_t, int);
    +#endif
    +
    +#ifndef HAVE_GROUP_FROM_GID
    +char *group_from_gid(gid_t, int);
    +#endif
    +
     void *xmmap(size_t size);
     char *xcrypt(const char *password, const char *salt);
     char *shadow_pw(struct passwd *pw);
    diff --git a/crypto/openssh/openbsd-compat/openssl-compat.c b/crypto/openssh/openbsd-compat/openssl-compat.c
    index 49238ba804b..420496caa5a 100644
    --- a/crypto/openssh/openbsd-compat/openssl-compat.c
    +++ b/crypto/openssh/openbsd-compat/openssl-compat.c
    @@ -1,4 +1,4 @@
    -/* $Id: openssl-compat.c,v 1.6 2008/02/28 08:13:52 dtucker Exp $ */
    +/* $Id: openssl-compat.c,v 1.9 2010/01/28 23:54:11 dtucker Exp $ */
     
     /*
      * Copyright (c) 2005 Darren Tucker 
    @@ -49,6 +49,15 @@ ssh_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *evp)
     }
     #endif
     
    +#ifdef OPENSSL_EVP_DIGESTUPDATE_VOID
    +int
    +ssh_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt)
    +{
    +	EVP_DigestUpdate(ctx, d, cnt);
    +	return 1;
    +}
    +#endif
    +
     #ifdef	USE_OPENSSL_ENGINE
     void
     ssh_SSLeay_add_all_algorithms(void)
    @@ -58,5 +67,6 @@ ssh_SSLeay_add_all_algorithms(void)
     	/* Enable use of crypto hardware */
     	ENGINE_load_builtin_engines();
     	ENGINE_register_all_complete();
    +	OPENSSL_config(NULL);
     }
     #endif
    diff --git a/crypto/openssh/openbsd-compat/openssl-compat.h b/crypto/openssh/openbsd-compat/openssl-compat.h
    index 6a1bed5b2b4..fcc762867d5 100644
    --- a/crypto/openssh/openbsd-compat/openssl-compat.h
    +++ b/crypto/openssh/openbsd-compat/openssl-compat.h
    @@ -1,4 +1,4 @@
    -/* $Id: openssl-compat.h,v 1.12 2008/02/28 08:22:04 dtucker Exp $ */
    +/* $Id: openssl-compat.h,v 1.14 2009/03/07 11:22:35 dtucker Exp $ */
     
     /*
      * Copyright (c) 2005 Darren Tucker 
    @@ -80,6 +80,10 @@ extern const EVP_CIPHER *evp_acss(void);
     #  define EVP_CIPHER_CTX_cleanup(a)	ssh_EVP_CIPHER_CTX_cleanup((a))
     # endif /* SSH_OLD_EVP */
     
    +# ifdef OPENSSL_EVP_DIGESTUPDATE_VOID
    +#  define EVP_DigestUpdate(a,b,c)	ssh_EVP_DigestUpdate((a),(b),(c))
    +#  endif
    +
     # ifdef USE_OPENSSL_ENGINE
     #  ifdef SSLeay_add_all_algorithms
     #   undef SSLeay_add_all_algorithms
    diff --git a/crypto/openssh/openbsd-compat/port-aix.c b/crypto/openssh/openbsd-compat/port-aix.c
    index 5b1cb73874d..0bdefbf6da0 100644
    --- a/crypto/openssh/openbsd-compat/port-aix.c
    +++ b/crypto/openssh/openbsd-compat/port-aix.c
    @@ -57,6 +57,8 @@
     
     #include "port-aix.h"
     
    +static char *lastlogin_msg = NULL;
    +
     # ifdef HAVE_SETAUTHDB
     static char old_registry[REGISTRY_SIZE] = "";
     # endif
    @@ -276,23 +278,30 @@ sys_auth_record_login(const char *user, const char *host, const char *ttynm,
         Buffer *loginmsg)
     {
     	char *msg = NULL;
    -	static int msg_done = 0;
     	int success = 0;
     
     	aix_setauthdb(user);
     	if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) {
     		success = 1;
    -		if (msg != NULL && loginmsg != NULL && !msg_done) {
    +		if (msg != NULL) {
     			debug("AIX/loginsuccess: msg %s", msg);
    -			buffer_append(loginmsg, msg, strlen(msg));
    -			xfree(msg);
    -			msg_done = 1;
    +			if (lastlogin_msg == NULL)
    +				lastlogin_msg = msg;
     		}
     	}
     	aix_restoreauthdb();
     	return (success);
     }
     
    +char *
    +sys_auth_get_lastlogin_msg(const char *user, uid_t uid)
    +{
    +	char *msg = lastlogin_msg;
    +
    +	lastlogin_msg = NULL;
    +	return msg;
    +}
    +
     #  ifdef CUSTOM_FAILED_LOGIN
     /*
      * record_failed_login: generic "login failed" interface function
    @@ -365,6 +374,31 @@ aix_restoreauthdb(void)
     
     # endif /* WITH_AIXAUTHENTICATE */
     
    +# ifdef USE_AIX_KRB_NAME
    +/*
    + * aix_krb5_get_principal_name: returns the user's kerberos client principal name if
    + * configured, otherwise NULL.  Caller must free returned string.
    + */
    +char *
    +aix_krb5_get_principal_name(char *pw_name)
    +{
    +	char *authname = NULL, *authdomain = NULL, *principal = NULL;
    +
    +	setuserdb(S_READ);
    +	if (getuserattr(pw_name, S_AUTHDOMAIN, &authdomain, SEC_CHAR) != 0)
    +		debug("AIX getuserattr S_AUTHDOMAIN: %s", strerror(errno));
    +	if (getuserattr(pw_name, S_AUTHNAME, &authname, SEC_CHAR) != 0)
    +		debug("AIX getuserattr S_AUTHNAME: %s", strerror(errno));
    +
    +	if (authdomain != NULL)
    +		xasprintf(&principal, "%s@%s", authname ? authname : pw_name, authdomain);
    +	else if (authname != NULL)
    +		principal = xstrdup(authname);
    +	enduserdb();
    +	return principal;
    +}
    +# endif /* USE_AIX_KRB_NAME */
    +
     # if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO)
     # undef getnameinfo
     /*
    diff --git a/crypto/openssh/openbsd-compat/port-aix.h b/crypto/openssh/openbsd-compat/port-aix.h
    index ecb9feae8bb..53e4e88a0c3 100644
    --- a/crypto/openssh/openbsd-compat/port-aix.h
    +++ b/crypto/openssh/openbsd-compat/port-aix.h
    @@ -1,4 +1,4 @@
    -/* $Id: port-aix.h,v 1.29 2008/03/09 05:36:55 dtucker Exp $ */
    +/* $Id: port-aix.h,v 1.32 2009/12/20 23:49:22 dtucker Exp $ */
     
     /*
      *
    @@ -71,6 +71,11 @@ int passwdexpired(char *, char **);
     # include 
     #endif
     
    +/* for setpcred and friends */
    +#ifdef HAVE_USERSEC_H
    +# include 
    +#endif
    +
     /*
      * According to the setauthdb man page, AIX password registries must be 15
      * chars or less plus terminating NUL.
    @@ -87,7 +92,13 @@ void aix_usrinfo(struct passwd *);
     int sys_auth_allowed_user(struct passwd *, Buffer *);
     # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1
     int sys_auth_record_login(const char *, const char *, const char *, Buffer *);
    +# define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
    +char *sys_auth_get_lastlogin_msg(const char *, uid_t);
     # define CUSTOM_FAILED_LOGIN 1
    +# if defined(S_AUTHDOMAIN)  && defined (S_AUTHNAME)
    +# define USE_AIX_KRB_NAME
    +char *aix_krb5_get_principal_name(char *);
    +# endif
     #endif
     
     void aix_setauthdb(const char *);
    diff --git a/crypto/openssh/openbsd-compat/port-linux.c b/crypto/openssh/openbsd-compat/port-linux.c
    index ad262758e33..89b9a734041 100644
    --- a/crypto/openssh/openbsd-compat/port-linux.c
    +++ b/crypto/openssh/openbsd-compat/port-linux.c
    @@ -1,4 +1,4 @@
    -/* $Id: port-linux.c,v 1.5 2008/03/26 20:27:21 dtucker Exp $ */
    +/* $Id: port-linux.c,v 1.8 2010/03/01 04:52:50 dtucker Exp $ */
     
     /*
      * Copyright (c) 2005 Daniel Walsh 
    @@ -23,14 +23,17 @@
     
     #include "includes.h"
     
    +#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
     #include 
     #include 
     #include 
    +#include 
     
    -#ifdef WITH_SELINUX
     #include "log.h"
    +#include "xmalloc.h"
     #include "port-linux.h"
     
    +#ifdef WITH_SELINUX
     #include 
     #include 
     #include 
    @@ -168,4 +171,95 @@ ssh_selinux_setup_pty(char *pwname, const char *tty)
     		freecon(user_ctx);
     	debug3("%s: done", __func__);
     }
    +
    +void
    +ssh_selinux_change_context(const char *newname)
    +{
    +	int len, newlen;
    +	char *oldctx, *newctx, *cx;
    +
    +	if (!ssh_selinux_enabled())
    +		return;
    +
    +	if (getcon((security_context_t *)&oldctx) < 0) {
    +		logit("%s: getcon failed with %s", __func__, strerror (errno));
    +		return;
    +	}
    +	if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) ==
    +	    NULL) {
    +		logit ("%s: unparseable context %s", __func__, oldctx);
    +		return;
    +	}
    +
    +	newlen = strlen(oldctx) + strlen(newname) + 1;
    +	newctx = xmalloc(newlen);
    +	len = cx - oldctx + 1;
    +	memcpy(newctx, oldctx, len);
    +	strlcpy(newctx + len, newname, newlen - len);
    +	if ((cx = index(cx + 1, ':')))
    +		strlcat(newctx, cx, newlen);
    +	debug3("%s: setting context from '%s' to '%s'", __func__, oldctx,
    +	    newctx);
    +	if (setcon(newctx) < 0)
    +		logit("%s: setcon failed with %s", __func__, strerror (errno));
    +	xfree(oldctx);
    +	xfree(newctx);
    +}
     #endif /* WITH_SELINUX */
    +
    +#ifdef LINUX_OOM_ADJUST
    +#define OOM_ADJ_PATH	"/proc/self/oom_adj"
    +/*
    + * The magic "don't kill me", as documented in eg:
    + * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt
    + */
    +#define OOM_ADJ_NOKILL	-17
    +
    +static int oom_adj_save = INT_MIN;
    +
    +/*
    + * Tell the kernel's out-of-memory killer to avoid sshd.
    + * Returns the previous oom_adj value or zero.
    + */
    +void
    +oom_adjust_setup(void)
    +{
    +	FILE *fp;
    +
    +	debug3("%s", __func__);
    +	if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) {
    +		if (fscanf(fp, "%d", &oom_adj_save) != 1)
    +			verbose("error reading %s: %s", OOM_ADJ_PATH, strerror(errno));
    +		else {
    +			rewind(fp);
    +			if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0)
    +				verbose("error writing %s: %s",
    +				    OOM_ADJ_PATH, strerror(errno));
    +			else
    +				verbose("Set %s from %d to %d",
    +				    OOM_ADJ_PATH, oom_adj_save, OOM_ADJ_NOKILL);
    +		}
    +		fclose(fp);
    +	}
    +}
    +
    +/* Restore the saved OOM adjustment */
    +void
    +oom_adjust_restore(void)
    +{
    +	FILE *fp;
    +
    +	debug3("%s", __func__);
    +	if (oom_adj_save == INT_MIN || (fp = fopen(OOM_ADJ_PATH, "w")) == NULL)
    +		return;
    +
    +	if (fprintf(fp, "%d\n", oom_adj_save) <= 0)
    +		verbose("error writing %s: %s", OOM_ADJ_PATH, strerror(errno));
    +	else
    +		verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save);
    +
    +	fclose(fp);
    +	return;
    +}
    +#endif /* LINUX_OOM_ADJUST */
    +#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */
    diff --git a/crypto/openssh/openbsd-compat/port-linux.h b/crypto/openssh/openbsd-compat/port-linux.h
    index 5cd39bf83c2..209d9a7a249 100644
    --- a/crypto/openssh/openbsd-compat/port-linux.h
    +++ b/crypto/openssh/openbsd-compat/port-linux.h
    @@ -1,4 +1,4 @@
    -/* $Id: port-linux.h,v 1.2 2008/03/26 20:27:21 dtucker Exp $ */
    +/* $Id: port-linux.h,v 1.4 2009/12/08 02:39:48 dtucker Exp $ */
     
     /*
      * Copyright (c) 2006 Damien Miller 
    @@ -23,6 +23,12 @@
     int ssh_selinux_enabled(void);
     void ssh_selinux_setup_pty(char *, const char *);
     void ssh_selinux_setup_exec_context(char *);
    +void ssh_selinux_change_context(const char *);
    +#endif
    +
    +#ifdef LINUX_OOM_ADJUST
    +void oom_adjust_restore(void);
    +void oom_adjust_setup(void);
     #endif
     
     #endif /* ! _PORT_LINUX_H */
    diff --git a/crypto/openssh/openbsd-compat/pwcache.c b/crypto/openssh/openbsd-compat/pwcache.c
    new file mode 100644
    index 00000000000..5a8b78801b9
    --- /dev/null
    +++ b/crypto/openssh/openbsd-compat/pwcache.c
    @@ -0,0 +1,114 @@
    +/*	$OpenBSD: pwcache.c,v 1.9 2005/08/08 08:05:34 espie Exp $ */
    +/*
    + * Copyright (c) 1989, 1993
    + *	The Regents of the University of California.  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.
    + * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
    + */
    +
    +/* OPENBSD ORIGINAL: lib/libc/gen/pwcache.c */
    +
    +#include "includes.h"
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#define	NCACHE	64			/* power of 2 */
    +#define	MASK	(NCACHE - 1)		/* bits to store with */
    +
    +#ifndef HAVE_USER_FROM_UID
    +char *
    +user_from_uid(uid_t uid, int nouser)
    +{
    +	static struct ncache {
    +		uid_t	uid;
    +		char	*name;
    +	} c_uid[NCACHE];
    +	static int pwopen;
    +	static char nbuf[15];		/* 32 bits == 10 digits */
    +	struct passwd *pw;
    +	struct ncache *cp;
    +
    +	cp = c_uid + (uid & MASK);
    +	if (cp->uid != uid || cp->name == NULL) {
    +		if (pwopen == 0) {
    +#ifdef HAVE_SETPASSENT
    +			setpassent(1);
    +#endif
    +			pwopen = 1;
    +		}
    +		if ((pw = getpwuid(uid)) == NULL) {
    +			if (nouser)
    +				return (NULL);
    +			(void)snprintf(nbuf, sizeof(nbuf), "%u", uid);
    +		}
    +		cp->uid = uid;
    +		if (cp->name != NULL)
    +			free(cp->name);
    +		cp->name = strdup(pw ? pw->pw_name : nbuf);
    +	}
    +	return (cp->name);
    +}
    +#endif
    +
    +#ifndef HAVE_GROUP_FROM_GID
    +char *
    +group_from_gid(gid_t gid, int nogroup)
    +{
    +	static struct ncache {
    +		gid_t	gid;
    +		char	*name;
    +	} c_gid[NCACHE];
    +	static int gropen;
    +	static char nbuf[15];		/* 32 bits == 10 digits */
    +	struct group *gr;
    +	struct ncache *cp;
    +
    +	cp = c_gid + (gid & MASK);
    +	if (cp->gid != gid || cp->name == NULL) {
    +		if (gropen == 0) {
    +#ifdef HAVE_SETGROUPENT
    +			setgroupent(1);
    +#endif
    +			gropen = 1;
    +		}
    +		if ((gr = getgrgid(gid)) == NULL) {
    +			if (nogroup)
    +				return (NULL);
    +			(void)snprintf(nbuf, sizeof(nbuf), "%u", gid);
    +		}
    +		cp->gid = gid;
    +		if (cp->name != NULL)
    +			free(cp->name);
    +		cp->name = strdup(gr ? gr->gr_name : nbuf);
    +	}
    +	return (cp->name);
    +}
    +#endif
    diff --git a/crypto/openssh/openbsd-compat/readpassphrase.c b/crypto/openssh/openbsd-compat/readpassphrase.c
    index 11bd8f646e1..62b6d0d8438 100644
    --- a/crypto/openssh/openbsd-compat/readpassphrase.c
    +++ b/crypto/openssh/openbsd-compat/readpassphrase.c
    @@ -1,7 +1,7 @@
    -/*	$OpenBSD: readpassphrase.c,v 1.18 2005/08/08 08:05:34 espie Exp $	*/
    +/*	$OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $	*/
     
     /*
    - * Copyright (c) 2000-2002 Todd C. Miller 
    + * Copyright (c) 2000-2002, 2007 Todd C. Miller 
      *
      * Permission to use, copy, modify, and distribute this software for any
      * purpose with or without fee is hereby granted, provided that the above
    @@ -46,7 +46,7 @@
     #  define _POSIX_VDISABLE       VDISABLE
     #endif
     
    -static volatile sig_atomic_t signo;
    +static volatile sig_atomic_t signo[_NSIG];
     
     static void handler(int);
     
    @@ -54,7 +54,7 @@ char *
     readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
     {
     	ssize_t nr;
    -	int input, output, save_errno;
    +	int input, output, save_errno, i, need_restart;
     	char ch, *p, *end;
     	struct termios term, oterm;
     	struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
    @@ -67,7 +67,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
     	}
     
     restart:
    -	signo = 0;
    +	for (i = 0; i < _NSIG; i++)
    +		signo[i] = 0;
    +	nr = -1;
    +	save_errno = 0;
    +	need_restart = 0;
     	/*
     	 * Read and write to /dev/tty if available.  If not, read from
     	 * stdin and write to stderr unless a tty is required.
    @@ -117,26 +121,30 @@ restart:
     		oterm.c_lflag |= ECHO;
     	}
     
    -	if (!(flags & RPP_STDIN))
    -		(void)write(output, prompt, strlen(prompt));
    -	end = buf + bufsiz - 1;
    -	for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) {
    -		if (p < end) {
    -			if ((flags & RPP_SEVENBIT))
    -				ch &= 0x7f;
    -			if (isalpha(ch)) {
    -				if ((flags & RPP_FORCELOWER))
    -					ch = tolower(ch);
    -				if ((flags & RPP_FORCEUPPER))
    -					ch = toupper(ch);
    +	/* No I/O if we are already backgrounded. */
    +	if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) {
    +		if (!(flags & RPP_STDIN))
    +			(void)write(output, prompt, strlen(prompt));
    +		end = buf + bufsiz - 1;
    +		p = buf;
    +		while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
    +			if (p < end) {
    +				if ((flags & RPP_SEVENBIT))
    +					ch &= 0x7f;
    +				if (isalpha(ch)) {
    +					if ((flags & RPP_FORCELOWER))
    +						ch = (char)tolower(ch);
    +					if ((flags & RPP_FORCEUPPER))
    +						ch = (char)toupper(ch);
    +				}
    +				*p++ = ch;
     			}
    -			*p++ = ch;
     		}
    +		*p = '\0';
    +		save_errno = errno;
    +		if (!(term.c_lflag & ECHO))
    +			(void)write(output, "\n", 1);
     	}
    -	*p = '\0';
    -	save_errno = errno;
    -	if (!(term.c_lflag & ECHO))
    -		(void)write(output, "\n", 1);
     
     	/* Restore old terminal settings and signals. */
     	if (memcmp(&term, &oterm, sizeof(term)) != 0) {
    @@ -152,6 +160,7 @@ restart:
     	(void)sigaction(SIGTERM, &saveterm, NULL);
     	(void)sigaction(SIGTSTP, &savetstp, NULL);
     	(void)sigaction(SIGTTIN, &savettin, NULL);
    +	(void)sigaction(SIGTTOU, &savettou, NULL);
     	if (input != STDIN_FILENO)
     		(void)close(input);
     
    @@ -159,20 +168,25 @@ restart:
     	 * If we were interrupted by a signal, resend it to ourselves
     	 * now that we have restored the signal handlers.
     	 */
    -	if (signo) {
    -		kill(getpid(), signo);
    -		switch (signo) {
    -		case SIGTSTP:
    -		case SIGTTIN:
    -		case SIGTTOU:
    -			goto restart;
    +	for (i = 0; i < _NSIG; i++) {
    +		if (signo[i]) {
    +			kill(getpid(), i);
    +			switch (i) {
    +			case SIGTSTP:
    +			case SIGTTIN:
    +			case SIGTTOU:
    +				need_restart = 1;
    +			}
     		}
     	}
    +	if (need_restart)
    +		goto restart;
     
    -	errno = save_errno;
    +	if (save_errno)
    +		errno = save_errno;
     	return(nr == -1 ? NULL : buf);
     }
    -  
    +
     #if 0
     char *
     getpass(const char *prompt)
    @@ -186,6 +200,6 @@ getpass(const char *prompt)
     static void handler(int s)
     {
     
    -	signo = s;
    +	signo[s] = 1;
     }
     #endif /* HAVE_READPASSPHRASE */
    diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c
    index 5afc84ce0bc..994e35b6df5 100644
    --- a/crypto/openssh/packet.c
    +++ b/crypto/openssh/packet.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: packet.c,v 1.160 2009/02/13 11:50:21 markus Exp $ */
    +/* $OpenBSD: packet.c,v 1.166 2009/06/27 09:29:06 andreas Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -77,6 +77,7 @@
     #include "canohost.h"
     #include "misc.h"
     #include "ssh.h"
    +#include "roaming.h"
     
     #ifdef PACKET_DEBUG
     #define DBG(x) x
    @@ -86,92 +87,126 @@
     
     #define PACKET_MAX_SIZE (256 * 1024)
     
    -/*
    - * This variable contains the file descriptors used for communicating with
    - * the other side.  connection_in is used for reading; connection_out for
    - * writing.  These can be the same descriptor, in which case it is assumed to
    - * be a socket.
    - */
    -static int connection_in = -1;
    -static int connection_out = -1;
    -
    -/* Protocol flags for the remote side. */
    -static u_int remote_protocol_flags = 0;
    -
    -/* Encryption context for receiving data.  This is only used for decryption. */
    -static CipherContext receive_context;
    -
    -/* Encryption context for sending data.  This is only used for encryption. */
    -static CipherContext send_context;
    -
    -/* Buffer for raw input data from the socket. */
    -Buffer input;
    -
    -/* Buffer for raw output data going to the socket. */
    -Buffer output;
    -
    -/* Buffer for the partial outgoing packet being constructed. */
    -static Buffer outgoing_packet;
    -
    -/* Buffer for the incoming packet currently being processed. */
    -static Buffer incoming_packet;
    -
    -/* Scratch buffer for packet compression/decompression. */
    -static Buffer compression_buffer;
    -static int compression_buffer_ready = 0;
    -
    -/* Flag indicating whether packet compression/decompression is enabled. */
    -static int packet_compression = 0;
    -
    -/* default maximum packet size */
    -u_int max_packet_size = 32768;
    -
    -/* Flag indicating whether this module has been initialized. */
    -static int initialized = 0;
    -
    -/* Set to true if the connection is interactive. */
    -static int interactive_mode = 0;
    -
    -/* Set to true if we are the server side. */
    -static int server_side = 0;
    -
    -/* Set to true if we are authenticated. */
    -static int after_authentication = 0;
    -
    -int keep_alive_timeouts = 0;
    -
    -/* Set to the maximum time that we will wait to send or receive a packet */
    -static int packet_timeout_ms = -1;
    -
    -/* Session key information for Encryption and MAC */
    -Newkeys *newkeys[MODE_MAX];
    -static struct packet_state {
    +struct packet_state {
     	u_int32_t seqnr;
     	u_int32_t packets;
     	u_int64_t blocks;
     	u_int64_t bytes;
    -} p_read, p_send;
    -
    -static u_int64_t max_blocks_in, max_blocks_out;
    -static u_int32_t rekey_limit;
    -
    -/* Session key for protocol v1 */
    -static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
    -static u_int ssh1_keylen;
    -
    -/* roundup current message to extra_pad bytes */
    -static u_char extra_pad = 0;
    -
    -/* XXX discard incoming data after MAC error */
    -static u_int packet_discard = 0;
    -static Mac *packet_discard_mac = NULL;
    +};
     
     struct packet {
     	TAILQ_ENTRY(packet) next;
     	u_char type;
     	Buffer payload;
     };
    -TAILQ_HEAD(, packet) outgoing;
    +
    +struct session_state {
    +	/*
    +	 * This variable contains the file descriptors used for
    +	 * communicating with the other side.  connection_in is used for
    +	 * reading; connection_out for writing.  These can be the same
    +	 * descriptor, in which case it is assumed to be a socket.
    +	 */
    +	int connection_in;
    +	int connection_out;
    +
    +	/* Protocol flags for the remote side. */
    +	u_int remote_protocol_flags;
    +
    +	/* Encryption context for receiving data.  Only used for decryption. */
    +	CipherContext receive_context;
    +
    +	/* Encryption context for sending data.  Only used for encryption. */
    +	CipherContext send_context;
    +
    +	/* Buffer for raw input data from the socket. */
    +	Buffer input;
    +
    +	/* Buffer for raw output data going to the socket. */
    +	Buffer output;
    +
    +	/* Buffer for the partial outgoing packet being constructed. */
    +	Buffer outgoing_packet;
    +
    +	/* Buffer for the incoming packet currently being processed. */
    +	Buffer incoming_packet;
    +
    +	/* Scratch buffer for packet compression/decompression. */
    +	Buffer compression_buffer;
    +	int compression_buffer_ready;
    +
    +	/*
    +	 * Flag indicating whether packet compression/decompression is
    +	 * enabled.
    +	 */
    +	int packet_compression;
    +
    +	/* default maximum packet size */
    +	u_int max_packet_size;
    +
    +	/* Flag indicating whether this module has been initialized. */
    +	int initialized;
    +
    +	/* Set to true if the connection is interactive. */
    +	int interactive_mode;
    +
    +	/* Set to true if we are the server side. */
    +	int server_side;
    +
    +	/* Set to true if we are authenticated. */
    +	int after_authentication;
    +
    +	int keep_alive_timeouts;
    +
    +	/* The maximum time that we will wait to send or receive a packet */
    +	int packet_timeout_ms;
    +
    +	/* Session key information for Encryption and MAC */
    +	Newkeys *newkeys[MODE_MAX];
    +	struct packet_state p_read, p_send;
    +
    +	u_int64_t max_blocks_in, max_blocks_out;
    +	u_int32_t rekey_limit;
    +
    +	/* Session key for protocol v1 */
    +	u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
    +	u_int ssh1_keylen;
    +
    +	/* roundup current message to extra_pad bytes */
    +	u_char extra_pad;
    +
    +	/* XXX discard incoming data after MAC error */
    +	u_int packet_discard;
    +	Mac *packet_discard_mac;
    +
    +	/* Used in packet_read_poll2() */
    +	u_int packlen;
    +
    +	/* Used in packet_send2 */
    +	int rekeying;
    +
    +	/* Used in packet_set_interactive */
    +	int set_interactive_called;
    +
    +	/* Used in packet_set_maxsize */
    +	int set_maxsize_called;
    +
    +	TAILQ_HEAD(, packet) outgoing;
    +};
    +
    +static struct session_state *active_state, *backup_state;
    +
    +static struct session_state *
    +alloc_session_state(void)
    +{
    +    struct session_state *s = xcalloc(1, sizeof(*s));
    +
    +    s->connection_in = -1;
    +    s->connection_out = -1;
    +    s->max_packet_size = 32768;
    +    s->packet_timeout_ms = -1;
    +    return s;
    +}
     
     /*
      * Sets the descriptors used for communication.  Disables encryption until
    @@ -184,21 +219,23 @@ packet_set_connection(int fd_in, int fd_out)
     
     	if (none == NULL)
     		fatal("packet_set_connection: cannot load cipher 'none'");
    -	connection_in = fd_in;
    -	connection_out = fd_out;
    -	cipher_init(&send_context, none, (const u_char *)"",
    +	if (active_state == NULL)
    +		active_state = alloc_session_state();
    +	active_state->connection_in = fd_in;
    +	active_state->connection_out = fd_out;
    +	cipher_init(&active_state->send_context, none, (const u_char *)"",
     	    0, NULL, 0, CIPHER_ENCRYPT);
    -	cipher_init(&receive_context, none, (const u_char *)"",
    +	cipher_init(&active_state->receive_context, none, (const u_char *)"",
     	    0, NULL, 0, CIPHER_DECRYPT);
    -	newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
    -	if (!initialized) {
    -		initialized = 1;
    -		buffer_init(&input);
    -		buffer_init(&output);
    -		buffer_init(&outgoing_packet);
    -		buffer_init(&incoming_packet);
    -		TAILQ_INIT(&outgoing);
    -		p_send.packets = p_read.packets = 0;
    +	active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL;
    +	if (!active_state->initialized) {
    +		active_state->initialized = 1;
    +		buffer_init(&active_state->input);
    +		buffer_init(&active_state->output);
    +		buffer_init(&active_state->outgoing_packet);
    +		buffer_init(&active_state->incoming_packet);
    +		TAILQ_INIT(&active_state->outgoing);
    +		active_state->p_send.packets = active_state->p_read.packets = 0;
     	}
     }
     
    @@ -206,27 +243,29 @@ void
     packet_set_timeout(int timeout, int count)
     {
     	if (timeout == 0 || count == 0) {
    -		packet_timeout_ms = -1;
    +		active_state->packet_timeout_ms = -1;
     		return;
     	}
     	if ((INT_MAX / 1000) / count < timeout)
    -		packet_timeout_ms = INT_MAX;
    +		active_state->packet_timeout_ms = INT_MAX;
     	else
    -		packet_timeout_ms = timeout * count * 1000;
    +		active_state->packet_timeout_ms = timeout * count * 1000;
     }
     
     static void
     packet_stop_discard(void)
     {
    -	if (packet_discard_mac) {
    +	if (active_state->packet_discard_mac) {
     		char buf[1024];
     		
     		memset(buf, 'a', sizeof(buf));
    -		while (buffer_len(&incoming_packet) < PACKET_MAX_SIZE)
    -			buffer_append(&incoming_packet, buf, sizeof(buf));
    -		(void) mac_compute(packet_discard_mac,
    -		    p_read.seqnr,
    -		    buffer_ptr(&incoming_packet),
    +		while (buffer_len(&active_state->incoming_packet) <
    +		    PACKET_MAX_SIZE)
    +			buffer_append(&active_state->incoming_packet, buf,
    +			    sizeof(buf));
    +		(void) mac_compute(active_state->packet_discard_mac,
    +		    active_state->p_read.seqnr,
    +		    buffer_ptr(&active_state->incoming_packet),
     		    PACKET_MAX_SIZE);
     	}
     	logit("Finished discarding for %.200s", get_remote_ipaddr());
    @@ -239,10 +278,11 @@ packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard)
     	if (enc == NULL || !cipher_is_cbc(enc->cipher))
     		packet_disconnect("Packet corrupt");
     	if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
    -		packet_discard_mac = mac;
    -	if (buffer_len(&input) >= discard)
    +		active_state->packet_discard_mac = mac;
    +	if (buffer_len(&active_state->input) >= discard)
     		packet_stop_discard();
    -	packet_discard = discard - buffer_len(&input);
    +	active_state->packet_discard = discard -
    +	    buffer_len(&active_state->input);
     }
     
     /* Returns 1 if remote host is connected via socket, 0 if not. */
    @@ -254,15 +294,17 @@ packet_connection_is_on_socket(void)
     	socklen_t fromlen, tolen;
     
     	/* filedescriptors in and out are the same, so it's a socket */
    -	if (connection_in == connection_out)
    +	if (active_state->connection_in == active_state->connection_out)
     		return 1;
     	fromlen = sizeof(from);
     	memset(&from, 0, sizeof(from));
    -	if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0)
    +	if (getpeername(active_state->connection_in, (struct sockaddr *)&from,
    +	    &fromlen) < 0)
     		return 0;
     	tolen = sizeof(to);
     	memset(&to, 0, sizeof(to));
    -	if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0)
    +	if (getpeername(active_state->connection_out, (struct sockaddr *)&to,
    +	    &tolen) < 0)
     		return 0;
     	if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
     		return 0;
    @@ -283,9 +325,9 @@ packet_get_keyiv(int mode, u_char *iv, u_int len)
     	CipherContext *cc;
     
     	if (mode == MODE_OUT)
    -		cc = &send_context;
    +		cc = &active_state->send_context;
     	else
    -		cc = &receive_context;
    +		cc = &active_state->receive_context;
     
     	cipher_get_keyiv(cc, iv, len);
     }
    @@ -296,9 +338,9 @@ packet_get_keycontext(int mode, u_char *dat)
     	CipherContext *cc;
     
     	if (mode == MODE_OUT)
    -		cc = &send_context;
    +		cc = &active_state->send_context;
     	else
    -		cc = &receive_context;
    +		cc = &active_state->receive_context;
     
     	return (cipher_get_keycontext(cc, dat));
     }
    @@ -309,9 +351,9 @@ packet_set_keycontext(int mode, u_char *dat)
     	CipherContext *cc;
     
     	if (mode == MODE_OUT)
    -		cc = &send_context;
    +		cc = &active_state->send_context;
     	else
    -		cc = &receive_context;
    +		cc = &active_state->receive_context;
     
     	cipher_set_keycontext(cc, dat);
     }
    @@ -322,9 +364,9 @@ packet_get_keyiv_len(int mode)
     	CipherContext *cc;
     
     	if (mode == MODE_OUT)
    -		cc = &send_context;
    +		cc = &active_state->send_context;
     	else
    -		cc = &receive_context;
    +		cc = &active_state->receive_context;
     
     	return (cipher_get_keyiv_len(cc));
     }
    @@ -335,9 +377,9 @@ packet_set_iv(int mode, u_char *dat)
     	CipherContext *cc;
     
     	if (mode == MODE_OUT)
    -		cc = &send_context;
    +		cc = &active_state->send_context;
     	else
    -		cc = &receive_context;
    +		cc = &active_state->receive_context;
     
     	cipher_set_keyiv(cc, dat);
     }
    @@ -345,7 +387,7 @@ packet_set_iv(int mode, u_char *dat)
     int
     packet_get_ssh1_cipher(void)
     {
    -	return (cipher_get_number(receive_context.cipher));
    +	return (cipher_get_number(active_state->receive_context.cipher));
     }
     
     void
    @@ -354,7 +396,8 @@ packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packe
     {
     	struct packet_state *state;
     
    -	state = (mode == MODE_IN) ? &p_read : &p_send;
    +	state = (mode == MODE_IN) ?
    +	    &active_state->p_read : &active_state->p_send;
     	if (seqnr)
     		*seqnr = state->seqnr;
     	if (blocks)
    @@ -371,7 +414,8 @@ packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets,
     {
     	struct packet_state *state;
     
    -	state = (mode == MODE_IN) ? &p_read : &p_send;
    +	state = (mode == MODE_IN) ?
    +	    &active_state->p_read : &active_state->p_send;
     	state->seqnr = seqnr;
     	state->blocks = blocks;
     	state->packets = packets;
    @@ -387,7 +431,8 @@ packet_connection_is_ipv4(void)
     	socklen_t tolen = sizeof(to);
     
     	memset(&to, 0, sizeof(to));
    -	if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0)
    +	if (getsockname(active_state->connection_out, (struct sockaddr *)&to,
    +	    &tolen) < 0)
     		return 0;
     	if (to.ss_family == AF_INET)
     		return 1;
    @@ -405,10 +450,10 @@ void
     packet_set_nonblocking(void)
     {
     	/* Set the socket into non-blocking mode. */
    -	set_nonblock(connection_in);
    +	set_nonblock(active_state->connection_in);
     
    -	if (connection_out != connection_in)
    -		set_nonblock(connection_out);
    +	if (active_state->connection_out != active_state->connection_in)
    +		set_nonblock(active_state->connection_out);
     }
     
     /* Returns the socket used for reading. */
    @@ -416,7 +461,7 @@ packet_set_nonblocking(void)
     int
     packet_get_connection_in(void)
     {
    -	return connection_in;
    +	return active_state->connection_in;
     }
     
     /* Returns the descriptor used for writing. */
    @@ -424,7 +469,7 @@ packet_get_connection_in(void)
     int
     packet_get_connection_out(void)
     {
    -	return connection_out;
    +	return active_state->connection_out;
     }
     
     /* Closes the connection and clears and frees internal data structures. */
    @@ -432,26 +477,26 @@ packet_get_connection_out(void)
     void
     packet_close(void)
     {
    -	if (!initialized)
    +	if (!active_state->initialized)
     		return;
    -	initialized = 0;
    -	if (connection_in == connection_out) {
    -		shutdown(connection_out, SHUT_RDWR);
    -		close(connection_out);
    +	active_state->initialized = 0;
    +	if (active_state->connection_in == active_state->connection_out) {
    +		shutdown(active_state->connection_out, SHUT_RDWR);
    +		close(active_state->connection_out);
     	} else {
    -		close(connection_in);
    -		close(connection_out);
    +		close(active_state->connection_in);
    +		close(active_state->connection_out);
     	}
    -	buffer_free(&input);
    -	buffer_free(&output);
    -	buffer_free(&outgoing_packet);
    -	buffer_free(&incoming_packet);
    -	if (compression_buffer_ready) {
    -		buffer_free(&compression_buffer);
    +	buffer_free(&active_state->input);
    +	buffer_free(&active_state->output);
    +	buffer_free(&active_state->outgoing_packet);
    +	buffer_free(&active_state->incoming_packet);
    +	if (active_state->compression_buffer_ready) {
    +		buffer_free(&active_state->compression_buffer);
     		buffer_compress_uninit();
     	}
    -	cipher_cleanup(&send_context);
    -	cipher_cleanup(&receive_context);
    +	cipher_cleanup(&active_state->send_context);
    +	cipher_cleanup(&active_state->receive_context);
     }
     
     /* Sets remote side protocol flags. */
    @@ -459,7 +504,7 @@ packet_close(void)
     void
     packet_set_protocol_flags(u_int protocol_flags)
     {
    -	remote_protocol_flags = protocol_flags;
    +	active_state->remote_protocol_flags = protocol_flags;
     }
     
     /* Returns the remote protocol flags set earlier by the above function. */
    @@ -467,7 +512,7 @@ packet_set_protocol_flags(u_int protocol_flags)
     u_int
     packet_get_protocol_flags(void)
     {
    -	return remote_protocol_flags;
    +	return active_state->remote_protocol_flags;
     }
     
     /*
    @@ -478,18 +523,18 @@ packet_get_protocol_flags(void)
     static void
     packet_init_compression(void)
     {
    -	if (compression_buffer_ready == 1)
    +	if (active_state->compression_buffer_ready == 1)
     		return;
    -	compression_buffer_ready = 1;
    -	buffer_init(&compression_buffer);
    +	active_state->compression_buffer_ready = 1;
    +	buffer_init(&active_state->compression_buffer);
     }
     
     void
     packet_start_compression(int level)
     {
    -	if (packet_compression && !compat20)
    +	if (active_state->packet_compression && !compat20)
     		fatal("Compression already enabled.");
    -	packet_compression = 1;
    +	active_state->packet_compression = 1;
     	packet_init_compression();
     	buffer_compress_init_send(level);
     	buffer_compress_init_recv();
    @@ -513,19 +558,21 @@ packet_set_encryption_key(const u_char *key, u_int keylen,
     		fatal("packet_set_encryption_key: keylen too small: %d", keylen);
     	if (keylen > SSH_SESSION_KEY_LENGTH)
     		fatal("packet_set_encryption_key: keylen too big: %d", keylen);
    -	memcpy(ssh1_key, key, keylen);
    -	ssh1_keylen = keylen;
    -	cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);
    -	cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);
    +	memcpy(active_state->ssh1_key, key, keylen);
    +	active_state->ssh1_keylen = keylen;
    +	cipher_init(&active_state->send_context, cipher, key, keylen, NULL,
    +	    0, CIPHER_ENCRYPT);
    +	cipher_init(&active_state->receive_context, cipher, key, keylen, NULL,
    +	    0, CIPHER_DECRYPT);
     }
     
     u_int
     packet_get_encryption_key(u_char *key)
     {
     	if (key == NULL)
    -		return (ssh1_keylen);
    -	memcpy(key, ssh1_key, ssh1_keylen);
    -	return (ssh1_keylen);
    +		return (active_state->ssh1_keylen);
    +	memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen);
    +	return (active_state->ssh1_keylen);
     }
     
     /* Start constructing a packet to send. */
    @@ -539,8 +586,8 @@ packet_start(u_char type)
     	len = compat20 ? 6 : 9;
     	memset(buf, 0, len - 1);
     	buf[len - 1] = type;
    -	buffer_clear(&outgoing_packet);
    -	buffer_append(&outgoing_packet, buf, len);
    +	buffer_clear(&active_state->outgoing_packet);
    +	buffer_append(&active_state->outgoing_packet, buf, len);
     }
     
     /* Append payload. */
    @@ -549,43 +596,49 @@ packet_put_char(int value)
     {
     	char ch = value;
     
    -	buffer_append(&outgoing_packet, &ch, 1);
    +	buffer_append(&active_state->outgoing_packet, &ch, 1);
     }
     
     void
     packet_put_int(u_int value)
     {
    -	buffer_put_int(&outgoing_packet, value);
    +	buffer_put_int(&active_state->outgoing_packet, value);
    +}
    +
    +void
    +packet_put_int64(u_int64_t value)
    +{
    +	buffer_put_int64(&active_state->outgoing_packet, value);
     }
     
     void
     packet_put_string(const void *buf, u_int len)
     {
    -	buffer_put_string(&outgoing_packet, buf, len);
    +	buffer_put_string(&active_state->outgoing_packet, buf, len);
     }
     
     void
     packet_put_cstring(const char *str)
     {
    -	buffer_put_cstring(&outgoing_packet, str);
    +	buffer_put_cstring(&active_state->outgoing_packet, str);
     }
     
     void
     packet_put_raw(const void *buf, u_int len)
     {
    -	buffer_append(&outgoing_packet, buf, len);
    +	buffer_append(&active_state->outgoing_packet, buf, len);
     }
     
     void
     packet_put_bignum(BIGNUM * value)
     {
    -	buffer_put_bignum(&outgoing_packet, value);
    +	buffer_put_bignum(&active_state->outgoing_packet, value);
     }
     
     void
     packet_put_bignum2(BIGNUM * value)
     {
    -	buffer_put_bignum2(&outgoing_packet, value);
    +	buffer_put_bignum2(&active_state->outgoing_packet, value);
     }
     
     /*
    @@ -605,24 +658,27 @@ packet_send1(void)
     	 * If using packet compression, compress the payload of the outgoing
     	 * packet.
     	 */
    -	if (packet_compression) {
    -		buffer_clear(&compression_buffer);
    +	if (active_state->packet_compression) {
    +		buffer_clear(&active_state->compression_buffer);
     		/* Skip padding. */
    -		buffer_consume(&outgoing_packet, 8);
    +		buffer_consume(&active_state->outgoing_packet, 8);
     		/* padding */
    -		buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8);
    -		buffer_compress(&outgoing_packet, &compression_buffer);
    -		buffer_clear(&outgoing_packet);
    -		buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
    -		    buffer_len(&compression_buffer));
    +		buffer_append(&active_state->compression_buffer,
    +		    "\0\0\0\0\0\0\0\0", 8);
    +		buffer_compress(&active_state->outgoing_packet,
    +		    &active_state->compression_buffer);
    +		buffer_clear(&active_state->outgoing_packet);
    +		buffer_append(&active_state->outgoing_packet,
    +		    buffer_ptr(&active_state->compression_buffer),
    +		    buffer_len(&active_state->compression_buffer));
     	}
     	/* Compute packet length without padding (add checksum, remove padding). */
    -	len = buffer_len(&outgoing_packet) + 4 - 8;
    +	len = buffer_len(&active_state->outgoing_packet) + 4 - 8;
     
     	/* Insert padding. Initialized to zero in packet_start1() */
     	padding = 8 - len % 8;
    -	if (!send_context.plaintext) {
    -		cp = buffer_ptr(&outgoing_packet);
    +	if (!active_state->send_context.plaintext) {
    +		cp = buffer_ptr(&active_state->outgoing_packet);
     		for (i = 0; i < padding; i++) {
     			if (i % 4 == 0)
     				rnd = arc4random();
    @@ -630,33 +686,36 @@ packet_send1(void)
     			rnd >>= 8;
     		}
     	}
    -	buffer_consume(&outgoing_packet, 8 - padding);
    +	buffer_consume(&active_state->outgoing_packet, 8 - padding);
     
     	/* Add check bytes. */
    -	checksum = ssh_crc32(buffer_ptr(&outgoing_packet),
    -	    buffer_len(&outgoing_packet));
    +	checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet),
    +	    buffer_len(&active_state->outgoing_packet));
     	put_u32(buf, checksum);
    -	buffer_append(&outgoing_packet, buf, 4);
    +	buffer_append(&active_state->outgoing_packet, buf, 4);
     
     #ifdef PACKET_DEBUG
     	fprintf(stderr, "packet_send plain: ");
    -	buffer_dump(&outgoing_packet);
    +	buffer_dump(&active_state->outgoing_packet);
     #endif
     
     	/* Append to output. */
     	put_u32(buf, len);
    -	buffer_append(&output, buf, 4);
    -	cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
    -	cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
    -	    buffer_len(&outgoing_packet));
    +	buffer_append(&active_state->output, buf, 4);
    +	cp = buffer_append_space(&active_state->output,
    +	    buffer_len(&active_state->outgoing_packet));
    +	cipher_crypt(&active_state->send_context, cp,
    +	    buffer_ptr(&active_state->outgoing_packet),
    +	    buffer_len(&active_state->outgoing_packet));
     
     #ifdef PACKET_DEBUG
     	fprintf(stderr, "encrypted: ");
    -	buffer_dump(&output);
    +	buffer_dump(&active_state->output);
     #endif
    -	p_send.packets++;
    -	p_send.bytes += len + buffer_len(&outgoing_packet);
    -	buffer_clear(&outgoing_packet);
    +	active_state->p_send.packets++;
    +	active_state->p_send.bytes += len +
    +	    buffer_len(&active_state->outgoing_packet);
    +	buffer_clear(&active_state->outgoing_packet);
     
     	/*
     	 * Note that the packet is now only buffered in output.  It won't be
    @@ -678,22 +737,22 @@ set_newkeys(int mode)
     	debug2("set_newkeys: mode %d", mode);
     
     	if (mode == MODE_OUT) {
    -		cc = &send_context;
    +		cc = &active_state->send_context;
     		crypt_type = CIPHER_ENCRYPT;
    -		p_send.packets = p_send.blocks = 0;
    -		max_blocks = &max_blocks_out;
    +		active_state->p_send.packets = active_state->p_send.blocks = 0;
    +		max_blocks = &active_state->max_blocks_out;
     	} else {
    -		cc = &receive_context;
    +		cc = &active_state->receive_context;
     		crypt_type = CIPHER_DECRYPT;
    -		p_read.packets = p_read.blocks = 0;
    -		max_blocks = &max_blocks_in;
    +		active_state->p_read.packets = active_state->p_read.blocks = 0;
    +		max_blocks = &active_state->max_blocks_in;
     	}
    -	if (newkeys[mode] != NULL) {
    +	if (active_state->newkeys[mode] != NULL) {
     		debug("set_newkeys: rekeying");
     		cipher_cleanup(cc);
    -		enc  = &newkeys[mode]->enc;
    -		mac  = &newkeys[mode]->mac;
    -		comp = &newkeys[mode]->comp;
    +		enc  = &active_state->newkeys[mode]->enc;
    +		mac  = &active_state->newkeys[mode]->mac;
    +		comp = &active_state->newkeys[mode]->comp;
     		mac_clear(mac);
     		xfree(enc->name);
     		xfree(enc->iv);
    @@ -701,14 +760,14 @@ set_newkeys(int mode)
     		xfree(mac->name);
     		xfree(mac->key);
     		xfree(comp->name);
    -		xfree(newkeys[mode]);
    +		xfree(active_state->newkeys[mode]);
     	}
    -	newkeys[mode] = kex_get_newkeys(mode);
    -	if (newkeys[mode] == NULL)
    +	active_state->newkeys[mode] = kex_get_newkeys(mode);
    +	if (active_state->newkeys[mode] == NULL)
     		fatal("newkeys: no keys for mode %d", mode);
    -	enc  = &newkeys[mode]->enc;
    -	mac  = &newkeys[mode]->mac;
    -	comp = &newkeys[mode]->comp;
    +	enc  = &active_state->newkeys[mode]->enc;
    +	mac  = &active_state->newkeys[mode]->mac;
    +	comp = &active_state->newkeys[mode]->comp;
     	if (mac_init(mac) == 0)
     		mac->enabled = 1;
     	DBG(debug("cipher_init_context: %d", mode));
    @@ -719,8 +778,8 @@ set_newkeys(int mode)
     	   memset(enc->key, 0, enc->key_len);
     	   memset(mac->key, 0, mac->key_len); */
     	if ((comp->type == COMP_ZLIB ||
    -	    (comp->type == COMP_DELAYED && after_authentication)) &&
    -	    comp->enabled == 0) {
    +	    (comp->type == COMP_DELAYED &&
    +	     active_state->after_authentication)) && comp->enabled == 0) {
     		packet_init_compression();
     		if (mode == MODE_OUT)
     			buffer_compress_init_send(6);
    @@ -736,8 +795,9 @@ set_newkeys(int mode)
     		*max_blocks = (u_int64_t)1 << (enc->block_size*2);
     	else
     		*max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
    -	if (rekey_limit)
    -		*max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
    +	if (active_state->rekey_limit)
    +		*max_blocks = MIN(*max_blocks,
    +		    active_state->rekey_limit / enc->block_size);
     }
     
     /*
    @@ -755,12 +815,12 @@ packet_enable_delayed_compress(void)
     	 * Remember that we are past the authentication step, so rekeying
     	 * with COMP_DELAYED will turn on compression immediately.
     	 */
    -	after_authentication = 1;
    +	active_state->after_authentication = 1;
     	for (mode = 0; mode < MODE_MAX; mode++) {
     		/* protocol error: USERAUTH_SUCCESS received before NEWKEYS */
    -		if (newkeys[mode] == NULL)
    +		if (active_state->newkeys[mode] == NULL)
     			continue;
    -		comp = &newkeys[mode]->comp;
    +		comp = &active_state->newkeys[mode]->comp;
     		if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
     			packet_init_compression();
     			if (mode == MODE_OUT)
    @@ -788,37 +848,39 @@ packet_send2_wrapped(void)
     	Comp *comp = NULL;
     	int block_size;
     
    -	if (newkeys[MODE_OUT] != NULL) {
    -		enc  = &newkeys[MODE_OUT]->enc;
    -		mac  = &newkeys[MODE_OUT]->mac;
    -		comp = &newkeys[MODE_OUT]->comp;
    +	if (active_state->newkeys[MODE_OUT] != NULL) {
    +		enc  = &active_state->newkeys[MODE_OUT]->enc;
    +		mac  = &active_state->newkeys[MODE_OUT]->mac;
    +		comp = &active_state->newkeys[MODE_OUT]->comp;
     	}
     	block_size = enc ? enc->block_size : 8;
     
    -	cp = buffer_ptr(&outgoing_packet);
    +	cp = buffer_ptr(&active_state->outgoing_packet);
     	type = cp[5];
     
     #ifdef PACKET_DEBUG
     	fprintf(stderr, "plain:     ");
    -	buffer_dump(&outgoing_packet);
    +	buffer_dump(&active_state->outgoing_packet);
     #endif
     
     	if (comp && comp->enabled) {
    -		len = buffer_len(&outgoing_packet);
    +		len = buffer_len(&active_state->outgoing_packet);
     		/* skip header, compress only payload */
    -		buffer_consume(&outgoing_packet, 5);
    -		buffer_clear(&compression_buffer);
    -		buffer_compress(&outgoing_packet, &compression_buffer);
    -		buffer_clear(&outgoing_packet);
    -		buffer_append(&outgoing_packet, "\0\0\0\0\0", 5);
    -		buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
    -		    buffer_len(&compression_buffer));
    +		buffer_consume(&active_state->outgoing_packet, 5);
    +		buffer_clear(&active_state->compression_buffer);
    +		buffer_compress(&active_state->outgoing_packet,
    +		    &active_state->compression_buffer);
    +		buffer_clear(&active_state->outgoing_packet);
    +		buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5);
    +		buffer_append(&active_state->outgoing_packet,
    +		    buffer_ptr(&active_state->compression_buffer),
    +		    buffer_len(&active_state->compression_buffer));
     		DBG(debug("compression: raw %d compressed %d", len,
    -		    buffer_len(&outgoing_packet)));
    +		    buffer_len(&active_state->outgoing_packet)));
     	}
     
     	/* sizeof (packet_len + pad_len + payload) */
    -	len = buffer_len(&outgoing_packet);
    +	len = buffer_len(&active_state->outgoing_packet);
     
     	/*
     	 * calc size of padding, alloc space, get random data,
    @@ -827,17 +889,19 @@ packet_send2_wrapped(void)
     	padlen = block_size - (len % block_size);
     	if (padlen < 4)
     		padlen += block_size;
    -	if (extra_pad) {
    +	if (active_state->extra_pad) {
     		/* will wrap if extra_pad+padlen > 255 */
    -		extra_pad  = roundup(extra_pad, block_size);
    -		pad = extra_pad - ((len + padlen) % extra_pad);
    +		active_state->extra_pad =
    +		    roundup(active_state->extra_pad, block_size);
    +		pad = active_state->extra_pad -
    +		    ((len + padlen) % active_state->extra_pad);
     		debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
    -		    pad, len, padlen, extra_pad);
    +		    pad, len, padlen, active_state->extra_pad);
     		padlen += pad;
    -		extra_pad = 0;
    +		active_state->extra_pad = 0;
     	}
    -	cp = buffer_append_space(&outgoing_packet, padlen);
    -	if (enc && !send_context.plaintext) {
    +	cp = buffer_append_space(&active_state->outgoing_packet, padlen);
    +	if (enc && !active_state->send_context.plaintext) {
     		/* random padding */
     		for (i = 0; i < padlen; i++) {
     			if (i % 4 == 0)
    @@ -850,86 +914,88 @@ packet_send2_wrapped(void)
     		memset(cp, 0, padlen);
     	}
     	/* packet_length includes payload, padding and padding length field */
    -	packet_length = buffer_len(&outgoing_packet) - 4;
    -	cp = buffer_ptr(&outgoing_packet);
    +	packet_length = buffer_len(&active_state->outgoing_packet) - 4;
    +	cp = buffer_ptr(&active_state->outgoing_packet);
     	put_u32(cp, packet_length);
     	cp[4] = padlen;
     	DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
     
     	/* compute MAC over seqnr and packet(length fields, payload, padding) */
     	if (mac && mac->enabled) {
    -		macbuf = mac_compute(mac, p_send.seqnr,
    -		    buffer_ptr(&outgoing_packet),
    -		    buffer_len(&outgoing_packet));
    -		DBG(debug("done calc MAC out #%d", p_send.seqnr));
    +		macbuf = mac_compute(mac, active_state->p_send.seqnr,
    +		    buffer_ptr(&active_state->outgoing_packet),
    +		    buffer_len(&active_state->outgoing_packet));
    +		DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
     	}
     	/* encrypt packet and append to output buffer. */
    -	cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
    -	cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
    -	    buffer_len(&outgoing_packet));
    +	cp = buffer_append_space(&active_state->output,
    +	    buffer_len(&active_state->outgoing_packet));
    +	cipher_crypt(&active_state->send_context, cp,
    +	    buffer_ptr(&active_state->outgoing_packet),
    +	    buffer_len(&active_state->outgoing_packet));
     	/* append unencrypted MAC */
     	if (mac && mac->enabled)
    -		buffer_append(&output, macbuf, mac->mac_len);
    +		buffer_append(&active_state->output, macbuf, mac->mac_len);
     #ifdef PACKET_DEBUG
     	fprintf(stderr, "encrypted: ");
    -	buffer_dump(&output);
    +	buffer_dump(&active_state->output);
     #endif
     	/* increment sequence number for outgoing packets */
    -	if (++p_send.seqnr == 0)
    +	if (++active_state->p_send.seqnr == 0)
     		logit("outgoing seqnr wraps around");
    -	if (++p_send.packets == 0)
    +	if (++active_state->p_send.packets == 0)
     		if (!(datafellows & SSH_BUG_NOREKEY))
     			fatal("XXX too many packets with same key");
    -	p_send.blocks += (packet_length + 4) / block_size;
    -	p_send.bytes += packet_length + 4;
    -	buffer_clear(&outgoing_packet);
    +	active_state->p_send.blocks += (packet_length + 4) / block_size;
    +	active_state->p_send.bytes += packet_length + 4;
    +	buffer_clear(&active_state->outgoing_packet);
     
     	if (type == SSH2_MSG_NEWKEYS)
     		set_newkeys(MODE_OUT);
    -	else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
    +	else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side)
     		packet_enable_delayed_compress();
     }
     
     static void
     packet_send2(void)
     {
    -	static int rekeying = 0;
     	struct packet *p;
     	u_char type, *cp;
     
    -	cp = buffer_ptr(&outgoing_packet);
    +	cp = buffer_ptr(&active_state->outgoing_packet);
     	type = cp[5];
     
     	/* during rekeying we can only send key exchange messages */
    -	if (rekeying) {
    +	if (active_state->rekeying) {
     		if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
     		    (type <= SSH2_MSG_TRANSPORT_MAX))) {
     			debug("enqueue packet: %u", type);
     			p = xmalloc(sizeof(*p));
     			p->type = type;
    -			memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
    -			buffer_init(&outgoing_packet);
    -			TAILQ_INSERT_TAIL(&outgoing, p, next);
    +			memcpy(&p->payload, &active_state->outgoing_packet,
    +			    sizeof(Buffer));
    +			buffer_init(&active_state->outgoing_packet);
    +			TAILQ_INSERT_TAIL(&active_state->outgoing, p, next);
     			return;
     		}
     	}
     
     	/* rekeying starts with sending KEXINIT */
     	if (type == SSH2_MSG_KEXINIT)
    -		rekeying = 1;
    +		active_state->rekeying = 1;
     
     	packet_send2_wrapped();
     
     	/* after a NEWKEYS message we can send the complete queue */
     	if (type == SSH2_MSG_NEWKEYS) {
    -		rekeying = 0;
    -		while ((p = TAILQ_FIRST(&outgoing))) {
    +		active_state->rekeying = 0;
    +		while ((p = TAILQ_FIRST(&active_state->outgoing))) {
     			type = p->type;
     			debug("dequeue packet: %u", type);
    -			buffer_free(&outgoing_packet);
    -			memcpy(&outgoing_packet, &p->payload,
    +			buffer_free(&active_state->outgoing_packet);
    +			memcpy(&active_state->outgoing_packet, &p->payload,
     			    sizeof(Buffer));
    -			TAILQ_REMOVE(&outgoing, p, next);
    +			TAILQ_REMOVE(&active_state->outgoing, p, next);
     			xfree(p);
     			packet_send2_wrapped();
     		}
    @@ -955,15 +1021,15 @@ packet_send(void)
     int
     packet_read_seqnr(u_int32_t *seqnr_p)
     {
    -	int type, len, ret, ms_remain;
    +	int type, len, ret, ms_remain, cont;
     	fd_set *setp;
     	char buf[8192];
     	struct timeval timeout, start, *timeoutp = NULL;
     
     	DBG(debug("packet_read()"));
     
    -	setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS),
    -	    sizeof(fd_mask));
    +	setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1,
    +	    NFDBITS), sizeof(fd_mask));
     
     	/* Since we are blocking, ensure that all written packets have been sent. */
     	packet_write_wait();
    @@ -987,27 +1053,27 @@ packet_read_seqnr(u_int32_t *seqnr_p)
     		 * Otherwise, wait for some data to arrive, add it to the
     		 * buffer, and try again.
     		 */
    -		memset(setp, 0, howmany(connection_in + 1, NFDBITS) *
    -		    sizeof(fd_mask));
    -		FD_SET(connection_in, setp);
    +		memset(setp, 0, howmany(active_state->connection_in + 1,
    +		    NFDBITS) * sizeof(fd_mask));
    +		FD_SET(active_state->connection_in, setp);
     
    -		if (packet_timeout_ms > 0) {
    -			ms_remain = packet_timeout_ms;
    +		if (active_state->packet_timeout_ms > 0) {
    +			ms_remain = active_state->packet_timeout_ms;
     			timeoutp = &timeout;
     		}
     		/* Wait for some data to arrive. */
     		for (;;) {
    -			if (packet_timeout_ms != -1) {
    +			if (active_state->packet_timeout_ms != -1) {
     				ms_to_timeval(&timeout, ms_remain);
     				gettimeofday(&start, NULL);
     			}
    -			if ((ret = select(connection_in + 1, setp, NULL,
    -			    NULL, timeoutp)) >= 0)
    +			if ((ret = select(active_state->connection_in + 1, setp,
    +			    NULL, NULL, timeoutp)) >= 0)
     				break;
    -		   	if (errno != EAGAIN && errno != EINTR &&
    +			if (errno != EAGAIN && errno != EINTR &&
     			    errno != EWOULDBLOCK)
     				break;
    -			if (packet_timeout_ms == -1)
    +			if (active_state->packet_timeout_ms == -1)
     				continue;
     			ms_subtract_diff(&start, &ms_remain);
     			if (ms_remain <= 0) {
    @@ -1021,7 +1087,11 @@ packet_read_seqnr(u_int32_t *seqnr_p)
     			cleanup_exit(255);
     		}
     		/* Read data from the socket. */
    -		len = read(connection_in, buf, sizeof(buf));
    +		do {
    +			cont = 0;
    +			len = roaming_read(active_state->connection_in, buf,
    +			    sizeof(buf), &cont);
    +		} while (len == 0 && cont);
     		if (len == 0) {
     			logit("Connection closed by %.200s", get_remote_ipaddr());
     			cleanup_exit(255);
    @@ -1073,31 +1143,32 @@ packet_read_poll1(void)
     	u_int checksum, stored_checksum;
     
     	/* Check if input size is less than minimum packet size. */
    -	if (buffer_len(&input) < 4 + 8)
    +	if (buffer_len(&active_state->input) < 4 + 8)
     		return SSH_MSG_NONE;
     	/* Get length of incoming packet. */
    -	cp = buffer_ptr(&input);
    +	cp = buffer_ptr(&active_state->input);
     	len = get_u32(cp);
     	if (len < 1 + 2 + 2 || len > 256 * 1024)
     		packet_disconnect("Bad packet length %u.", len);
     	padded_len = (len + 8) & ~7;
     
     	/* Check if the packet has been entirely received. */
    -	if (buffer_len(&input) < 4 + padded_len)
    +	if (buffer_len(&active_state->input) < 4 + padded_len)
     		return SSH_MSG_NONE;
     
     	/* The entire packet is in buffer. */
     
     	/* Consume packet length. */
    -	buffer_consume(&input, 4);
    +	buffer_consume(&active_state->input, 4);
     
     	/*
     	 * Cryptographic attack detector for ssh
     	 * (C)1998 CORE-SDI, Buenos Aires Argentina
     	 * Ariel Futoransky(futo@core-sdi.com)
     	 */
    -	if (!receive_context.plaintext) {
    -		switch (detect_attack(buffer_ptr(&input), padded_len)) {
    +	if (!active_state->receive_context.plaintext) {
    +		switch (detect_attack(buffer_ptr(&active_state->input),
    +		    padded_len)) {
     		case DEATTACK_DETECTED:
     			packet_disconnect("crc32 compensation attack: "
     			    "network attack detected");
    @@ -1108,45 +1179,48 @@ packet_read_poll1(void)
     	}
     
     	/* Decrypt data to incoming_packet. */
    -	buffer_clear(&incoming_packet);
    -	cp = buffer_append_space(&incoming_packet, padded_len);
    -	cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len);
    +	buffer_clear(&active_state->incoming_packet);
    +	cp = buffer_append_space(&active_state->incoming_packet, padded_len);
    +	cipher_crypt(&active_state->receive_context, cp,
    +	    buffer_ptr(&active_state->input), padded_len);
     
    -	buffer_consume(&input, padded_len);
    +	buffer_consume(&active_state->input, padded_len);
     
     #ifdef PACKET_DEBUG
     	fprintf(stderr, "read_poll plain: ");
    -	buffer_dump(&incoming_packet);
    +	buffer_dump(&active_state->incoming_packet);
     #endif
     
     	/* Compute packet checksum. */
    -	checksum = ssh_crc32(buffer_ptr(&incoming_packet),
    -	    buffer_len(&incoming_packet) - 4);
    +	checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet),
    +	    buffer_len(&active_state->incoming_packet) - 4);
     
     	/* Skip padding. */
    -	buffer_consume(&incoming_packet, 8 - len % 8);
    +	buffer_consume(&active_state->incoming_packet, 8 - len % 8);
     
     	/* Test check bytes. */
    -	if (len != buffer_len(&incoming_packet))
    +	if (len != buffer_len(&active_state->incoming_packet))
     		packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
    -		    len, buffer_len(&incoming_packet));
    +		    len, buffer_len(&active_state->incoming_packet));
     
    -	cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4;
    +	cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4;
     	stored_checksum = get_u32(cp);
     	if (checksum != stored_checksum)
     		packet_disconnect("Corrupted check bytes on input.");
    -	buffer_consume_end(&incoming_packet, 4);
    +	buffer_consume_end(&active_state->incoming_packet, 4);
     
    -	if (packet_compression) {
    -		buffer_clear(&compression_buffer);
    -		buffer_uncompress(&incoming_packet, &compression_buffer);
    -		buffer_clear(&incoming_packet);
    -		buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
    -		    buffer_len(&compression_buffer));
    +	if (active_state->packet_compression) {
    +		buffer_clear(&active_state->compression_buffer);
    +		buffer_uncompress(&active_state->incoming_packet,
    +		    &active_state->compression_buffer);
    +		buffer_clear(&active_state->incoming_packet);
    +		buffer_append(&active_state->incoming_packet,
    +		    buffer_ptr(&active_state->compression_buffer),
    +		    buffer_len(&active_state->compression_buffer));
     	}
    -	p_read.packets++;
    -	p_read.bytes += padded_len + 4;
    -	type = buffer_get_char(&incoming_packet);
    +	active_state->p_read.packets++;
    +	active_state->p_read.bytes += padded_len + 4;
    +	type = buffer_get_char(&active_state->incoming_packet);
     	if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
     		packet_disconnect("Invalid ssh1 packet type: %d", type);
     	return type;
    @@ -1155,7 +1229,6 @@ packet_read_poll1(void)
     static int
     packet_read_poll2(u_int32_t *seqnr_p)
     {
    -	static u_int packet_length = 0;
     	u_int padlen, need;
     	u_char *macbuf, *cp, type;
     	u_int maclen, block_size;
    @@ -1163,50 +1236,52 @@ packet_read_poll2(u_int32_t *seqnr_p)
     	Mac *mac   = NULL;
     	Comp *comp = NULL;
     
    -	if (packet_discard)
    +	if (active_state->packet_discard)
     		return SSH_MSG_NONE;
     
    -	if (newkeys[MODE_IN] != NULL) {
    -		enc  = &newkeys[MODE_IN]->enc;
    -		mac  = &newkeys[MODE_IN]->mac;
    -		comp = &newkeys[MODE_IN]->comp;
    +	if (active_state->newkeys[MODE_IN] != NULL) {
    +		enc  = &active_state->newkeys[MODE_IN]->enc;
    +		mac  = &active_state->newkeys[MODE_IN]->mac;
    +		comp = &active_state->newkeys[MODE_IN]->comp;
     	}
     	maclen = mac && mac->enabled ? mac->mac_len : 0;
     	block_size = enc ? enc->block_size : 8;
     
    -	if (packet_length == 0) {
    +	if (active_state->packlen == 0) {
     		/*
     		 * check if input size is less than the cipher block size,
     		 * decrypt first block and extract length of incoming packet
     		 */
    -		if (buffer_len(&input) < block_size)
    +		if (buffer_len(&active_state->input) < block_size)
     			return SSH_MSG_NONE;
    -		buffer_clear(&incoming_packet);
    -		cp = buffer_append_space(&incoming_packet, block_size);
    -		cipher_crypt(&receive_context, cp, buffer_ptr(&input),
    +		buffer_clear(&active_state->incoming_packet);
    +		cp = buffer_append_space(&active_state->incoming_packet,
     		    block_size);
    -		cp = buffer_ptr(&incoming_packet);
    -		packet_length = get_u32(cp);
    -		if (packet_length < 1 + 4 || packet_length > PACKET_MAX_SIZE) {
    +		cipher_crypt(&active_state->receive_context, cp,
    +		    buffer_ptr(&active_state->input), block_size);
    +		cp = buffer_ptr(&active_state->incoming_packet);
    +		active_state->packlen = get_u32(cp);
    +		if (active_state->packlen < 1 + 4 ||
    +		    active_state->packlen > PACKET_MAX_SIZE) {
     #ifdef PACKET_DEBUG
    -			buffer_dump(&incoming_packet);
    +			buffer_dump(&active_state->incoming_packet);
     #endif
    -			logit("Bad packet length %u.", packet_length);
    -			packet_start_discard(enc, mac, packet_length,
    +			logit("Bad packet length %u.", active_state->packlen);
    +			packet_start_discard(enc, mac, active_state->packlen,
     			    PACKET_MAX_SIZE);
     			return SSH_MSG_NONE;
     		}
    -		DBG(debug("input: packet len %u", packet_length+4));
    -		buffer_consume(&input, block_size);
    +		DBG(debug("input: packet len %u", active_state->packlen+4));
    +		buffer_consume(&active_state->input, block_size);
     	}
     	/* we have a partial packet of block_size bytes */
    -	need = 4 + packet_length - block_size;
    +	need = 4 + active_state->packlen - block_size;
     	DBG(debug("partial packet %d, need %d, maclen %d", block_size,
     	    need, maclen));
     	if (need % block_size != 0) {
     		logit("padding error: need %d block %d mod %d",
     		    need, block_size, need % block_size);
    -		packet_start_discard(enc, mac, packet_length,
    +		packet_start_discard(enc, mac, active_state->packlen,
     		    PACKET_MAX_SIZE - block_size);
     		return SSH_MSG_NONE;
     	}
    @@ -1214,84 +1289,90 @@ packet_read_poll2(u_int32_t *seqnr_p)
     	 * check if the entire packet has been received and
     	 * decrypt into incoming_packet
     	 */
    -	if (buffer_len(&input) < need + maclen)
    +	if (buffer_len(&active_state->input) < need + maclen)
     		return SSH_MSG_NONE;
     #ifdef PACKET_DEBUG
     	fprintf(stderr, "read_poll enc/full: ");
    -	buffer_dump(&input);
    +	buffer_dump(&active_state->input);
     #endif
    -	cp = buffer_append_space(&incoming_packet, need);
    -	cipher_crypt(&receive_context, cp, buffer_ptr(&input), need);
    -	buffer_consume(&input, need);
    +	cp = buffer_append_space(&active_state->incoming_packet, need);
    +	cipher_crypt(&active_state->receive_context, cp,
    +	    buffer_ptr(&active_state->input), need);
    +	buffer_consume(&active_state->input, need);
     	/*
     	 * compute MAC over seqnr and packet,
     	 * increment sequence number for incoming packet
     	 */
     	if (mac && mac->enabled) {
    -		macbuf = mac_compute(mac, p_read.seqnr,
    -		    buffer_ptr(&incoming_packet),
    -		    buffer_len(&incoming_packet));
    -		if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) {
    +		macbuf = mac_compute(mac, active_state->p_read.seqnr,
    +		    buffer_ptr(&active_state->incoming_packet),
    +		    buffer_len(&active_state->incoming_packet));
    +		if (memcmp(macbuf, buffer_ptr(&active_state->input),
    +		    mac->mac_len) != 0) {
     			logit("Corrupted MAC on input.");
     			if (need > PACKET_MAX_SIZE)
     				fatal("internal error need %d", need);
    -			packet_start_discard(enc, mac, packet_length,
    +			packet_start_discard(enc, mac, active_state->packlen,
     			    PACKET_MAX_SIZE - need);
     			return SSH_MSG_NONE;
     		}
     				
    -		DBG(debug("MAC #%d ok", p_read.seqnr));
    -		buffer_consume(&input, mac->mac_len);
    +		DBG(debug("MAC #%d ok", active_state->p_read.seqnr));
    +		buffer_consume(&active_state->input, mac->mac_len);
     	}
     	/* XXX now it's safe to use fatal/packet_disconnect */
     	if (seqnr_p != NULL)
    -		*seqnr_p = p_read.seqnr;
    -	if (++p_read.seqnr == 0)
    +		*seqnr_p = active_state->p_read.seqnr;
    +	if (++active_state->p_read.seqnr == 0)
     		logit("incoming seqnr wraps around");
    -	if (++p_read.packets == 0)
    +	if (++active_state->p_read.packets == 0)
     		if (!(datafellows & SSH_BUG_NOREKEY))
     			fatal("XXX too many packets with same key");
    -	p_read.blocks += (packet_length + 4) / block_size;
    -	p_read.bytes += packet_length + 4;
    +	active_state->p_read.blocks += (active_state->packlen + 4) / block_size;
    +	active_state->p_read.bytes += active_state->packlen + 4;
     
     	/* get padlen */
    -	cp = buffer_ptr(&incoming_packet);
    +	cp = buffer_ptr(&active_state->incoming_packet);
     	padlen = cp[4];
     	DBG(debug("input: padlen %d", padlen));
     	if (padlen < 4)
     		packet_disconnect("Corrupted padlen %d on input.", padlen);
     
     	/* skip packet size + padlen, discard padding */
    -	buffer_consume(&incoming_packet, 4 + 1);
    -	buffer_consume_end(&incoming_packet, padlen);
    +	buffer_consume(&active_state->incoming_packet, 4 + 1);
    +	buffer_consume_end(&active_state->incoming_packet, padlen);
     
    -	DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet)));
    +	DBG(debug("input: len before de-compress %d",
    +	    buffer_len(&active_state->incoming_packet)));
     	if (comp && comp->enabled) {
    -		buffer_clear(&compression_buffer);
    -		buffer_uncompress(&incoming_packet, &compression_buffer);
    -		buffer_clear(&incoming_packet);
    -		buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
    -		    buffer_len(&compression_buffer));
    +		buffer_clear(&active_state->compression_buffer);
    +		buffer_uncompress(&active_state->incoming_packet,
    +		    &active_state->compression_buffer);
    +		buffer_clear(&active_state->incoming_packet);
    +		buffer_append(&active_state->incoming_packet,
    +		    buffer_ptr(&active_state->compression_buffer),
    +		    buffer_len(&active_state->compression_buffer));
     		DBG(debug("input: len after de-compress %d",
    -		    buffer_len(&incoming_packet)));
    +		    buffer_len(&active_state->incoming_packet)));
     	}
     	/*
     	 * get packet type, implies consume.
     	 * return length of payload (without type field)
     	 */
    -	type = buffer_get_char(&incoming_packet);
    +	type = buffer_get_char(&active_state->incoming_packet);
     	if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)
     		packet_disconnect("Invalid ssh2 packet type: %d", type);
     	if (type == SSH2_MSG_NEWKEYS)
     		set_newkeys(MODE_IN);
    -	else if (type == SSH2_MSG_USERAUTH_SUCCESS && !server_side)
    +	else if (type == SSH2_MSG_USERAUTH_SUCCESS &&
    +	    !active_state->server_side)
     		packet_enable_delayed_compress();
     #ifdef PACKET_DEBUG
     	fprintf(stderr, "read/plain[%d]:\r\n", type);
    -	buffer_dump(&incoming_packet);
    +	buffer_dump(&active_state->incoming_packet);
     #endif
     	/* reset for next packet */
    -	packet_length = 0;
    +	active_state->packlen = 0;
     	return type;
     }
     
    @@ -1306,7 +1387,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
     		if (compat20) {
     			type = packet_read_poll2(seqnr_p);
     			if (type) {
    -				keep_alive_timeouts = 0;
    +				active_state->keep_alive_timeouts = 0;
     				DBG(debug("received packet type %d", type));
     			}
     			switch (type) {
    @@ -1376,14 +1457,14 @@ packet_read_poll(void)
     void
     packet_process_incoming(const char *buf, u_int len)
     {
    -	if (packet_discard) {
    -		keep_alive_timeouts = 0; /* ?? */
    -		if (len >= packet_discard)
    +	if (active_state->packet_discard) {
    +		active_state->keep_alive_timeouts = 0; /* ?? */
    +		if (len >= active_state->packet_discard)
     			packet_stop_discard();
    -		packet_discard -= len;
    +		active_state->packet_discard -= len;
     		return;
     	}
    -	buffer_append(&input, buf, len);
    +	buffer_append(&active_state->input, buf, len);
     }
     
     /* Returns a character from the packet. */
    @@ -1393,7 +1474,7 @@ packet_get_char(void)
     {
     	char ch;
     
    -	buffer_get(&incoming_packet, &ch, 1);
    +	buffer_get(&active_state->incoming_packet, &ch, 1);
     	return (u_char) ch;
     }
     
    @@ -1402,7 +1483,15 @@ packet_get_char(void)
     u_int
     packet_get_int(void)
     {
    -	return buffer_get_int(&incoming_packet);
    +	return buffer_get_int(&active_state->incoming_packet);
    +}
    +
    +/* Returns an 64 bit integer from the packet data. */
    +
    +u_int64_t
    +packet_get_int64(void)
    +{
    +	return buffer_get_int64(&active_state->incoming_packet);
     }
     
     /*
    @@ -1413,29 +1502,29 @@ packet_get_int(void)
     void
     packet_get_bignum(BIGNUM * value)
     {
    -	buffer_get_bignum(&incoming_packet, value);
    +	buffer_get_bignum(&active_state->incoming_packet, value);
     }
     
     void
     packet_get_bignum2(BIGNUM * value)
     {
    -	buffer_get_bignum2(&incoming_packet, value);
    +	buffer_get_bignum2(&active_state->incoming_packet, value);
     }
     
     void *
     packet_get_raw(u_int *length_ptr)
     {
    -	u_int bytes = buffer_len(&incoming_packet);
    +	u_int bytes = buffer_len(&active_state->incoming_packet);
     
     	if (length_ptr != NULL)
     		*length_ptr = bytes;
    -	return buffer_ptr(&incoming_packet);
    +	return buffer_ptr(&active_state->incoming_packet);
     }
     
     int
     packet_remaining(void)
     {
    -	return buffer_len(&incoming_packet);
    +	return buffer_len(&active_state->incoming_packet);
     }
     
     /*
    @@ -1448,13 +1537,13 @@ packet_remaining(void)
     void *
     packet_get_string(u_int *length_ptr)
     {
    -	return buffer_get_string(&incoming_packet, length_ptr);
    +	return buffer_get_string(&active_state->incoming_packet, length_ptr);
     }
     
     void *
     packet_get_string_ptr(u_int *length_ptr)
     {
    -	return buffer_get_string_ptr(&incoming_packet, length_ptr);
    +	return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
     }
     
     /*
    @@ -1547,23 +1636,25 @@ packet_disconnect(const char *fmt,...)
     void
     packet_write_poll(void)
     {
    -	int len = buffer_len(&output);
    +	int len = buffer_len(&active_state->output);
    +	int cont;
     
     	if (len > 0) {
    -		len = write(connection_out, buffer_ptr(&output), len);
    +		cont = 0;
    +		len = roaming_write(active_state->connection_out,
    +		    buffer_ptr(&active_state->output), len, &cont);
     		if (len == -1) {
     			if (errno == EINTR || errno == EAGAIN ||
     			    errno == EWOULDBLOCK)
     				return;
     			fatal("Write failed: %.100s", strerror(errno));
     		}
    -		if (len == 0)
    +		if (len == 0 && !cont)
     			fatal("Write connection closed");
    -		buffer_consume(&output, len);
    +		buffer_consume(&active_state->output, len);
     	}
     }
     
    -
     /*
      * Calls packet_write_poll repeatedly until all pending output data has been
      * written.
    @@ -1576,30 +1667,30 @@ packet_write_wait(void)
     	int ret, ms_remain;
     	struct timeval start, timeout, *timeoutp = NULL;
     
    -	setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
    -	    sizeof(fd_mask));
    +	setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1,
    +	    NFDBITS), sizeof(fd_mask));
     	packet_write_poll();
     	while (packet_have_data_to_write()) {
    -		memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
    -		    sizeof(fd_mask));
    -		FD_SET(connection_out, setp);
    +		memset(setp, 0, howmany(active_state->connection_out + 1,
    +		    NFDBITS) * sizeof(fd_mask));
    +		FD_SET(active_state->connection_out, setp);
     
    -		if (packet_timeout_ms > 0) {
    -			ms_remain = packet_timeout_ms;
    +		if (active_state->packet_timeout_ms > 0) {
    +			ms_remain = active_state->packet_timeout_ms;
     			timeoutp = &timeout;
     		}
     		for (;;) {
    -			if (packet_timeout_ms != -1) {
    +			if (active_state->packet_timeout_ms != -1) {
     				ms_to_timeval(&timeout, ms_remain);
     				gettimeofday(&start, NULL);
     			}
    -			if ((ret = select(connection_out + 1, NULL, setp,
    -			    NULL, timeoutp)) >= 0)
    +			if ((ret = select(active_state->connection_out + 1,
    +			    NULL, setp, NULL, timeoutp)) >= 0)
     				break;
    -		   	if (errno != EAGAIN && errno != EINTR &&
    +			if (errno != EAGAIN && errno != EINTR &&
     			    errno != EWOULDBLOCK)
     				break;
    -			if (packet_timeout_ms == -1)
    +			if (active_state->packet_timeout_ms == -1)
     				continue;
     			ms_subtract_diff(&start, &ms_remain);
     			if (ms_remain <= 0) {
    @@ -1622,7 +1713,7 @@ packet_write_wait(void)
     int
     packet_have_data_to_write(void)
     {
    -	return buffer_len(&output) != 0;
    +	return buffer_len(&active_state->output) != 0;
     }
     
     /* Returns true if there is not too much data to write to the connection. */
    @@ -1630,13 +1721,12 @@ packet_have_data_to_write(void)
     int
     packet_not_very_much_data_to_write(void)
     {
    -	if (interactive_mode)
    -		return buffer_len(&output) < 16384;
    +	if (active_state->interactive_mode)
    +		return buffer_len(&active_state->output) < 16384;
     	else
    -		return buffer_len(&output) < 128 * 1024;
    +		return buffer_len(&active_state->output) < 128 * 1024;
     }
     
    -
     static void
     packet_set_tos(int interactive)
     {
    @@ -1646,7 +1736,7 @@ packet_set_tos(int interactive)
     	if (!packet_connection_is_on_socket() ||
     	    !packet_connection_is_ipv4())
     		return;
    -	if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &tos,
    +	if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos,
     	    sizeof(tos)) < 0)
     		error("setsockopt IP_TOS %d: %.100s:",
     		    tos, strerror(errno));
    @@ -1658,19 +1748,17 @@ packet_set_tos(int interactive)
     void
     packet_set_interactive(int interactive)
     {
    -	static int called = 0;
    -
    -	if (called)
    +	if (active_state->set_interactive_called)
     		return;
    -	called = 1;
    +	active_state->set_interactive_called = 1;
     
     	/* Record that we are in interactive mode. */
    -	interactive_mode = interactive;
    +	active_state->interactive_mode = interactive;
     
     	/* Only set socket options if using a socket.  */
     	if (!packet_connection_is_on_socket())
     		return;
    -	set_nodelay(connection_in);
    +	set_nodelay(active_state->connection_in);
     	packet_set_tos(interactive);
     }
     
    @@ -1679,34 +1767,50 @@ packet_set_interactive(int interactive)
     int
     packet_is_interactive(void)
     {
    -	return interactive_mode;
    +	return active_state->interactive_mode;
     }
     
     int
     packet_set_maxsize(u_int s)
     {
    -	static int called = 0;
    -
    -	if (called) {
    +	if (active_state->set_maxsize_called) {
     		logit("packet_set_maxsize: called twice: old %d new %d",
    -		    max_packet_size, s);
    +		    active_state->max_packet_size, s);
     		return -1;
     	}
     	if (s < 4 * 1024 || s > 1024 * 1024) {
     		logit("packet_set_maxsize: bad size %d", s);
     		return -1;
     	}
    -	called = 1;
    +	active_state->set_maxsize_called = 1;
     	debug("packet_set_maxsize: setting to %d", s);
    -	max_packet_size = s;
    +	active_state->max_packet_size = s;
     	return s;
     }
     
    +int
    +packet_inc_alive_timeouts(void)
    +{
    +	return ++active_state->keep_alive_timeouts;
    +}
    +
    +void
    +packet_set_alive_timeouts(int ka)
    +{
    +	active_state->keep_alive_timeouts = ka;
    +}
    +
    +u_int
    +packet_get_maxsize(void)
    +{
    +	return active_state->max_packet_size;
    +}
    +
     /* roundup current message to pad bytes */
     void
     packet_add_padding(u_char pad)
     {
    -	extra_pad = pad;
    +	active_state->extra_pad = pad;
     }
     
     /*
    @@ -1743,26 +1847,93 @@ packet_need_rekeying(void)
     	if (datafellows & SSH_BUG_NOREKEY)
     		return 0;
     	return
    -	    (p_send.packets > MAX_PACKETS) ||
    -	    (p_read.packets > MAX_PACKETS) ||
    -	    (max_blocks_out && (p_send.blocks > max_blocks_out)) ||
    -	    (max_blocks_in  && (p_read.blocks > max_blocks_in));
    +	    (active_state->p_send.packets > MAX_PACKETS) ||
    +	    (active_state->p_read.packets > MAX_PACKETS) ||
    +	    (active_state->max_blocks_out &&
    +	        (active_state->p_send.blocks > active_state->max_blocks_out)) ||
    +	    (active_state->max_blocks_in &&
    +	        (active_state->p_read.blocks > active_state->max_blocks_in));
     }
     
     void
     packet_set_rekey_limit(u_int32_t bytes)
     {
    -	rekey_limit = bytes;
    +	active_state->rekey_limit = bytes;
     }
     
     void
     packet_set_server(void)
     {
    -	server_side = 1;
    +	active_state->server_side = 1;
     }
     
     void
     packet_set_authenticated(void)
     {
    -	after_authentication = 1;
    +	active_state->after_authentication = 1;
    +}
    +
    +void *
    +packet_get_input(void)
    +{
    +	return (void *)&active_state->input;
    +}
    +
    +void *
    +packet_get_output(void)
    +{
    +	return (void *)&active_state->output;
    +}
    +
    +void *
    +packet_get_newkeys(int mode)
    +{
    +	return (void *)active_state->newkeys[mode];
    +}
    +
    +/*
    + * Save the state for the real connection, and use a separate state when
    + * resuming a suspended connection.
    + */
    +void
    +packet_backup_state(void)
    +{
    +	struct session_state *tmp;
    +
    +	close(active_state->connection_in);
    +	active_state->connection_in = -1;
    +	close(active_state->connection_out);
    +	active_state->connection_out = -1;
    +	if (backup_state)
    +		tmp = backup_state;
    +	else
    +		tmp = alloc_session_state();
    +	backup_state = active_state;
    +	active_state = tmp;
    +}
    +
    +/*
    + * Swap in the old state when resuming a connecion.
    + */
    +void
    +packet_restore_state(void)
    +{
    +	struct session_state *tmp;
    +	void *buf;
    +	u_int len;
    +
    +	tmp = backup_state;
    +	backup_state = active_state;
    +	active_state = tmp;
    +	active_state->connection_in = backup_state->connection_in;
    +	backup_state->connection_in = -1;
    +	active_state->connection_out = backup_state->connection_out;
    +	backup_state->connection_out = -1;
    +	len = buffer_len(&backup_state->input);
    +	if (len > 0) {
    +		buf = buffer_ptr(&backup_state->input);
    +		buffer_append(&active_state->input, buf, len);
    +		buffer_clear(&backup_state->input);
    +		add_recv_bytes(len);
    +	}
     }
    diff --git a/crypto/openssh/packet.h b/crypto/openssh/packet.h
    index 03bb87c9bee..33523d7503c 100644
    --- a/crypto/openssh/packet.h
    +++ b/crypto/openssh/packet.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: packet.h,v 1.49 2008/07/10 18:08:11 markus Exp $ */
    +/* $OpenBSD: packet.h,v 1.52 2009/06/27 09:29:06 andreas Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -39,6 +39,7 @@ void     packet_set_authenticated(void);
     void     packet_start(u_char);
     void     packet_put_char(int ch);
     void     packet_put_int(u_int value);
    +void     packet_put_int64(u_int64_t value);
     void     packet_put_bignum(BIGNUM * value);
     void     packet_put_bignum2(BIGNUM * value);
     void     packet_put_string(const void *buf, u_int len);
    @@ -55,6 +56,7 @@ int      packet_read_poll_seqnr(u_int32_t *seqnr_p);
     
     u_int	 packet_get_char(void);
     u_int	 packet_get_int(void);
    +u_int64_t packet_get_int64(void);
     void     packet_get_bignum(BIGNUM * value);
     void     packet_get_bignum2(BIGNUM * value);
     void	*packet_get_raw(u_int *length_ptr);
    @@ -72,6 +74,7 @@ void	 packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *, u_int64_t *);
     void	 packet_set_state(int, u_int32_t, u_int64_t, u_int32_t, u_int64_t);
     int	 packet_get_ssh1_cipher(void);
     void	 packet_set_iv(int, u_char *);
    +void	*packet_get_newkeys(int);
     
     void     packet_write_poll(void);
     void     packet_write_wait(void);
    @@ -87,10 +90,10 @@ void	 packet_add_padding(u_char);
     void	 tty_make_modes(int, struct termios *);
     void	 tty_parse_modes(int, int *);
     
    -extern u_int max_packet_size;
    -extern int keep_alive_timeouts;
    +void	 packet_set_alive_timeouts(int);
    +int	 packet_inc_alive_timeouts(void);
     int	 packet_set_maxsize(u_int);
    -#define  packet_get_maxsize() max_packet_size
    +u_int	 packet_get_maxsize(void);
     
     /* don't allow remaining bytes after the end of the message */
     #define packet_check_eom() \
    @@ -106,4 +109,10 @@ do { \
     int	 packet_need_rekeying(void);
     void	 packet_set_rekey_limit(u_int32_t);
     
    +void	 packet_backup_state(void);
    +void	 packet_restore_state(void);
    +
    +void	*packet_get_input(void);
    +void	*packet_get_output(void);
    +
     #endif				/* PACKET_H */
    diff --git a/crypto/openssh/pathnames.h b/crypto/openssh/pathnames.h
    index bc4f66a6638..0bb0c0626c6 100644
    --- a/crypto/openssh/pathnames.h
    +++ b/crypto/openssh/pathnames.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: pathnames.h,v 1.17 2008/12/29 02:23:26 stevesk Exp $ */
    +/* $OpenBSD: pathnames.h,v 1.19 2010/02/11 20:37:47 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -125,6 +125,11 @@
     #define _PATH_SSH_KEY_SIGN		"/usr/libexec/ssh-keysign"
     #endif
     
    +/* Location of ssh-pkcs11-helper to support keys in tokens */
    +#ifndef _PATH_SSH_PKCS11_HELPER
    +#define _PATH_SSH_PKCS11_HELPER		"/usr/libexec/ssh-pkcs11-helper"
    +#endif
    +
     /* xauth for X11 forwarding */
     #ifndef _PATH_XAUTH
     #define _PATH_XAUTH			"/usr/local/bin/xauth"
    diff --git a/crypto/openssh/pkcs11.h b/crypto/openssh/pkcs11.h
    new file mode 100644
    index 00000000000..2cde5b3f4fa
    --- /dev/null
    +++ b/crypto/openssh/pkcs11.h
    @@ -0,0 +1,1357 @@
    +/* $OpenBSD: pkcs11.h,v 1.2 2010/02/24 06:12:53 djm Exp $ */
    +/* pkcs11.h
    +   Copyright 2006, 2007 g10 Code GmbH
    +   Copyright 2006 Andreas Jellinghaus
    +
    +   This file is free software; as a special exception the author gives
    +   unlimited permission to copy and/or distribute it, with or without
    +   modifications, as long as this notice is preserved.
    +
    +   This file is distributed in the hope that it will be useful, but
    +   WITHOUT ANY WARRANTY, to the extent permitted by law; without even
    +   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
    +   PURPOSE.  */
    +
    +/* Please submit changes back to the Scute project at
    +   http://www.scute.org/ (or send them to marcus@g10code.com), so that
    +   they can be picked up by other projects from there as well.  */
    +
    +/* This file is a modified implementation of the PKCS #11 standard by
    +   RSA Security Inc.  It is mostly a drop-in replacement, with the
    +   following change:
    +
    +   This header file does not require any macro definitions by the user
    +   (like CK_DEFINE_FUNCTION etc).  In fact, it defines those macros
    +   for you (if useful, some are missing, let me know if you need
    +   more).
    +
    +   There is an additional API available that does comply better to the
    +   GNU coding standard.  It can be switched on by defining
    +   CRYPTOKI_GNU before including this header file.  For this, the
    +   following changes are made to the specification:
    +
    +   All structure types are changed to a "struct ck_foo" where CK_FOO
    +   is the type name in PKCS #11.
    +
    +   All non-structure types are changed to ck_foo_t where CK_FOO is the
    +   lowercase version of the type name in PKCS #11.  The basic types
    +   (CK_ULONG et al.) are removed without substitute.
    +
    +   All members of structures are modified in the following way: Type
    +   indication prefixes are removed, and underscore characters are
    +   inserted before words.  Then the result is lowercased.
    +
    +   Note that function names are still in the original case, as they
    +   need for ABI compatibility.
    +
    +   CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute.  Use
    +   .
    +
    +   If CRYPTOKI_COMPAT is defined before including this header file,
    +   then none of the API changes above take place, and the API is the
    +   one defined by the PKCS #11 standard.  */
    +
    +#ifndef PKCS11_H
    +#define PKCS11_H 1
    +
    +#if defined(__cplusplus)
    +extern "C" {
    +#endif
    +
    +
    +/* The version of cryptoki we implement.  The revision is changed with
    +   each modification of this file.  If you do not use the "official"
    +   version of this file, please consider deleting the revision macro
    +   (you may use a macro with a different name to keep track of your
    +   versions).  */
    +#define CRYPTOKI_VERSION_MAJOR		2
    +#define CRYPTOKI_VERSION_MINOR		20
    +#define CRYPTOKI_VERSION_REVISION	6
    +
    +
    +/* Compatibility interface is default, unless CRYPTOKI_GNU is
    +   given.  */
    +#ifndef CRYPTOKI_GNU
    +#ifndef CRYPTOKI_COMPAT
    +#define CRYPTOKI_COMPAT 1
    +#endif
    +#endif
    +
    +/* System dependencies.  */
    +
    +#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32)
    +
    +/* There is a matching pop below.  */
    +#pragma pack(push, cryptoki, 1)
    +
    +#ifdef CRYPTOKI_EXPORTS
    +#define CK_SPEC __declspec(dllexport)
    +#else
    +#define CK_SPEC __declspec(dllimport)
    +#endif
    +
    +#else
    +
    +#define CK_SPEC
    +
    +#endif
    +
    +
    +#ifdef CRYPTOKI_COMPAT
    +  /* If we are in compatibility mode, switch all exposed names to the
    +     PKCS #11 variant.  There are corresponding #undefs below.  */
    +
    +#define ck_flags_t CK_FLAGS
    +#define ck_version _CK_VERSION
    +
    +#define ck_info _CK_INFO
    +#define cryptoki_version cryptokiVersion
    +#define manufacturer_id manufacturerID
    +#define library_description libraryDescription
    +#define library_version libraryVersion
    +
    +#define ck_notification_t CK_NOTIFICATION
    +#define ck_slot_id_t CK_SLOT_ID
    +
    +#define ck_slot_info _CK_SLOT_INFO
    +#define slot_description slotDescription
    +#define hardware_version hardwareVersion
    +#define firmware_version firmwareVersion
    +
    +#define ck_token_info _CK_TOKEN_INFO
    +#define serial_number serialNumber
    +#define max_session_count ulMaxSessionCount
    +#define session_count ulSessionCount
    +#define max_rw_session_count ulMaxRwSessionCount
    +#define rw_session_count ulRwSessionCount
    +#define max_pin_len ulMaxPinLen
    +#define min_pin_len ulMinPinLen
    +#define total_public_memory ulTotalPublicMemory
    +#define free_public_memory ulFreePublicMemory
    +#define total_private_memory ulTotalPrivateMemory
    +#define free_private_memory ulFreePrivateMemory
    +#define utc_time utcTime
    +
    +#define ck_session_handle_t CK_SESSION_HANDLE
    +#define ck_user_type_t CK_USER_TYPE
    +#define ck_state_t CK_STATE
    +
    +#define ck_session_info _CK_SESSION_INFO
    +#define slot_id slotID
    +#define device_error ulDeviceError
    +
    +#define ck_object_handle_t CK_OBJECT_HANDLE
    +#define ck_object_class_t CK_OBJECT_CLASS
    +#define ck_hw_feature_type_t CK_HW_FEATURE_TYPE
    +#define ck_key_type_t CK_KEY_TYPE
    +#define ck_certificate_type_t CK_CERTIFICATE_TYPE
    +#define ck_attribute_type_t CK_ATTRIBUTE_TYPE
    +
    +#define ck_attribute _CK_ATTRIBUTE
    +#define value pValue
    +#define value_len ulValueLen
    +
    +#define ck_date _CK_DATE
    +
    +#define ck_mechanism_type_t CK_MECHANISM_TYPE
    +
    +#define ck_mechanism _CK_MECHANISM
    +#define parameter pParameter
    +#define parameter_len ulParameterLen
    +
    +#define ck_mechanism_info _CK_MECHANISM_INFO
    +#define min_key_size ulMinKeySize
    +#define max_key_size ulMaxKeySize
    +
    +#define ck_rv_t CK_RV
    +#define ck_notify_t CK_NOTIFY
    +
    +#define ck_function_list _CK_FUNCTION_LIST
    +
    +#define ck_createmutex_t CK_CREATEMUTEX
    +#define ck_destroymutex_t CK_DESTROYMUTEX
    +#define ck_lockmutex_t CK_LOCKMUTEX
    +#define ck_unlockmutex_t CK_UNLOCKMUTEX
    +
    +#define ck_c_initialize_args _CK_C_INITIALIZE_ARGS
    +#define create_mutex CreateMutex
    +#define destroy_mutex DestroyMutex
    +#define lock_mutex LockMutex
    +#define unlock_mutex UnlockMutex
    +#define reserved pReserved
    +
    +#endif	/* CRYPTOKI_COMPAT */
    +
    +
    +
    +typedef unsigned long ck_flags_t;
    +
    +struct ck_version
    +{
    +  unsigned char major;
    +  unsigned char minor;
    +};
    +
    +
    +struct ck_info
    +{
    +  struct ck_version cryptoki_version;
    +  unsigned char manufacturer_id[32];
    +  ck_flags_t flags;
    +  unsigned char library_description[32];
    +  struct ck_version library_version;
    +};
    +
    +
    +typedef unsigned long ck_notification_t;
    +
    +#define CKN_SURRENDER	(0)
    +
    +
    +typedef unsigned long ck_slot_id_t;
    +
    +
    +struct ck_slot_info
    +{
    +  unsigned char slot_description[64];
    +  unsigned char manufacturer_id[32];
    +  ck_flags_t flags;
    +  struct ck_version hardware_version;
    +  struct ck_version firmware_version;
    +};
    +
    +
    +#define CKF_TOKEN_PRESENT	(1 << 0)
    +#define CKF_REMOVABLE_DEVICE	(1 << 1)
    +#define CKF_HW_SLOT		(1 << 2)
    +#define CKF_ARRAY_ATTRIBUTE	(1 << 30)
    +
    +
    +struct ck_token_info
    +{
    +  unsigned char label[32];
    +  unsigned char manufacturer_id[32];
    +  unsigned char model[16];
    +  unsigned char serial_number[16];
    +  ck_flags_t flags;
    +  unsigned long max_session_count;
    +  unsigned long session_count;
    +  unsigned long max_rw_session_count;
    +  unsigned long rw_session_count;
    +  unsigned long max_pin_len;
    +  unsigned long min_pin_len;
    +  unsigned long total_public_memory;
    +  unsigned long free_public_memory;
    +  unsigned long total_private_memory;
    +  unsigned long free_private_memory;
    +  struct ck_version hardware_version;
    +  struct ck_version firmware_version;
    +  unsigned char utc_time[16];
    +};
    +
    +
    +#define CKF_RNG					(1 << 0)
    +#define CKF_WRITE_PROTECTED			(1 << 1)
    +#define CKF_LOGIN_REQUIRED			(1 << 2)
    +#define CKF_USER_PIN_INITIALIZED		(1 << 3)
    +#define CKF_RESTORE_KEY_NOT_NEEDED		(1 << 5)
    +#define CKF_CLOCK_ON_TOKEN			(1 << 6)
    +#define CKF_PROTECTED_AUTHENTICATION_PATH	(1 << 8)
    +#define CKF_DUAL_CRYPTO_OPERATIONS		(1 << 9)
    +#define CKF_TOKEN_INITIALIZED			(1 << 10)
    +#define CKF_SECONDARY_AUTHENTICATION		(1 << 11)
    +#define CKF_USER_PIN_COUNT_LOW			(1 << 16)
    +#define CKF_USER_PIN_FINAL_TRY			(1 << 17)
    +#define CKF_USER_PIN_LOCKED			(1 << 18)
    +#define CKF_USER_PIN_TO_BE_CHANGED		(1 << 19)
    +#define CKF_SO_PIN_COUNT_LOW			(1 << 20)
    +#define CKF_SO_PIN_FINAL_TRY			(1 << 21)
    +#define CKF_SO_PIN_LOCKED			(1 << 22)
    +#define CKF_SO_PIN_TO_BE_CHANGED		(1 << 23)
    +
    +#define CK_UNAVAILABLE_INFORMATION	((unsigned long) -1)
    +#define CK_EFFECTIVELY_INFINITE		(0)
    +
    +
    +typedef unsigned long ck_session_handle_t;
    +
    +#define CK_INVALID_HANDLE	(0)
    +
    +
    +typedef unsigned long ck_user_type_t;
    +
    +#define CKU_SO			(0)
    +#define CKU_USER		(1)
    +#define CKU_CONTEXT_SPECIFIC	(2)
    +
    +
    +typedef unsigned long ck_state_t;
    +
    +#define CKS_RO_PUBLIC_SESSION	(0)
    +#define CKS_RO_USER_FUNCTIONS	(1)
    +#define CKS_RW_PUBLIC_SESSION	(2)
    +#define CKS_RW_USER_FUNCTIONS	(3)
    +#define CKS_RW_SO_FUNCTIONS	(4)
    +
    +
    +struct ck_session_info
    +{
    +  ck_slot_id_t slot_id;
    +  ck_state_t state;
    +  ck_flags_t flags;
    +  unsigned long device_error;
    +};
    +
    +#define CKF_RW_SESSION		(1 << 1)
    +#define CKF_SERIAL_SESSION	(1 << 2)
    +
    +
    +typedef unsigned long ck_object_handle_t;
    +
    +
    +typedef unsigned long ck_object_class_t;
    +
    +#define CKO_DATA		(0)
    +#define CKO_CERTIFICATE		(1)
    +#define CKO_PUBLIC_KEY		(2)
    +#define CKO_PRIVATE_KEY		(3)
    +#define CKO_SECRET_KEY		(4)
    +#define CKO_HW_FEATURE		(5)
    +#define CKO_DOMAIN_PARAMETERS	(6)
    +#define CKO_MECHANISM		(7)
    +#define CKO_VENDOR_DEFINED	((unsigned long) (1 << 31))
    +
    +
    +typedef unsigned long ck_hw_feature_type_t;
    +
    +#define CKH_MONOTONIC_COUNTER	(1)
    +#define CKH_CLOCK		(2)
    +#define CKH_USER_INTERFACE	(3)
    +#define CKH_VENDOR_DEFINED	((unsigned long) (1 << 31))
    +
    +
    +typedef unsigned long ck_key_type_t;
    +
    +#define CKK_RSA			(0)
    +#define CKK_DSA			(1)
    +#define CKK_DH			(2)
    +#define CKK_ECDSA		(3)
    +#define CKK_EC			(3)
    +#define CKK_X9_42_DH		(4)
    +#define CKK_KEA			(5)
    +#define CKK_GENERIC_SECRET	(0x10)
    +#define CKK_RC2			(0x11)
    +#define CKK_RC4			(0x12)
    +#define CKK_DES			(0x13)
    +#define CKK_DES2		(0x14)
    +#define CKK_DES3		(0x15)
    +#define CKK_CAST		(0x16)
    +#define CKK_CAST3		(0x17)
    +#define CKK_CAST128		(0x18)
    +#define CKK_RC5			(0x19)
    +#define CKK_IDEA		(0x1a)
    +#define CKK_SKIPJACK		(0x1b)
    +#define CKK_BATON		(0x1c)
    +#define CKK_JUNIPER		(0x1d)
    +#define CKK_CDMF		(0x1e)
    +#define CKK_AES			(0x1f)
    +#define CKK_BLOWFISH		(0x20)
    +#define CKK_TWOFISH		(0x21)
    +#define CKK_VENDOR_DEFINED	((unsigned long) (1 << 31))
    +
    +typedef unsigned long ck_certificate_type_t;
    +
    +#define CKC_X_509		(0)
    +#define CKC_X_509_ATTR_CERT	(1)
    +#define CKC_WTLS		(2)
    +#define CKC_VENDOR_DEFINED	((unsigned long) (1 << 31))
    +
    +
    +typedef unsigned long ck_attribute_type_t;
    +
    +#define CKA_CLASS			(0)
    +#define CKA_TOKEN			(1)
    +#define CKA_PRIVATE			(2)
    +#define CKA_LABEL			(3)
    +#define CKA_APPLICATION			(0x10)
    +#define CKA_VALUE			(0x11)
    +#define CKA_OBJECT_ID			(0x12)
    +#define CKA_CERTIFICATE_TYPE		(0x80)
    +#define CKA_ISSUER			(0x81)
    +#define CKA_SERIAL_NUMBER		(0x82)
    +#define CKA_AC_ISSUER			(0x83)
    +#define CKA_OWNER			(0x84)
    +#define CKA_ATTR_TYPES			(0x85)
    +#define CKA_TRUSTED			(0x86)
    +#define CKA_CERTIFICATE_CATEGORY	(0x87)
    +#define CKA_JAVA_MIDP_SECURITY_DOMAIN	(0x88)
    +#define CKA_URL				(0x89)
    +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY	(0x8a)
    +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY	(0x8b)
    +#define CKA_CHECK_VALUE			(0x90)
    +#define CKA_KEY_TYPE			(0x100)
    +#define CKA_SUBJECT			(0x101)
    +#define CKA_ID				(0x102)
    +#define CKA_SENSITIVE			(0x103)
    +#define CKA_ENCRYPT			(0x104)
    +#define CKA_DECRYPT			(0x105)
    +#define CKA_WRAP			(0x106)
    +#define CKA_UNWRAP			(0x107)
    +#define CKA_SIGN			(0x108)
    +#define CKA_SIGN_RECOVER		(0x109)
    +#define CKA_VERIFY			(0x10a)
    +#define CKA_VERIFY_RECOVER		(0x10b)
    +#define CKA_DERIVE			(0x10c)
    +#define CKA_START_DATE			(0x110)
    +#define CKA_END_DATE			(0x111)
    +#define CKA_MODULUS			(0x120)
    +#define CKA_MODULUS_BITS		(0x121)
    +#define CKA_PUBLIC_EXPONENT		(0x122)
    +#define CKA_PRIVATE_EXPONENT		(0x123)
    +#define CKA_PRIME_1			(0x124)
    +#define CKA_PRIME_2			(0x125)
    +#define CKA_EXPONENT_1			(0x126)
    +#define CKA_EXPONENT_2			(0x127)
    +#define CKA_COEFFICIENT			(0x128)
    +#define CKA_PRIME			(0x130)
    +#define CKA_SUBPRIME			(0x131)
    +#define CKA_BASE			(0x132)
    +#define CKA_PRIME_BITS			(0x133)
    +#define CKA_SUB_PRIME_BITS		(0x134)
    +#define CKA_VALUE_BITS			(0x160)
    +#define CKA_VALUE_LEN			(0x161)
    +#define CKA_EXTRACTABLE			(0x162)
    +#define CKA_LOCAL			(0x163)
    +#define CKA_NEVER_EXTRACTABLE		(0x164)
    +#define CKA_ALWAYS_SENSITIVE		(0x165)
    +#define CKA_KEY_GEN_MECHANISM		(0x166)
    +#define CKA_MODIFIABLE			(0x170)
    +#define CKA_ECDSA_PARAMS		(0x180)
    +#define CKA_EC_PARAMS			(0x180)
    +#define CKA_EC_POINT			(0x181)
    +#define CKA_SECONDARY_AUTH		(0x200)
    +#define CKA_AUTH_PIN_FLAGS		(0x201)
    +#define CKA_ALWAYS_AUTHENTICATE		(0x202)
    +#define CKA_WRAP_WITH_TRUSTED		(0x210)
    +#define CKA_HW_FEATURE_TYPE		(0x300)
    +#define CKA_RESET_ON_INIT		(0x301)
    +#define CKA_HAS_RESET			(0x302)
    +#define CKA_PIXEL_X			(0x400)
    +#define CKA_PIXEL_Y			(0x401)
    +#define CKA_RESOLUTION			(0x402)
    +#define CKA_CHAR_ROWS			(0x403)
    +#define CKA_CHAR_COLUMNS		(0x404)
    +#define CKA_COLOR			(0x405)
    +#define CKA_BITS_PER_PIXEL		(0x406)
    +#define CKA_CHAR_SETS			(0x480)
    +#define CKA_ENCODING_METHODS		(0x481)
    +#define CKA_MIME_TYPES			(0x482)
    +#define CKA_MECHANISM_TYPE		(0x500)
    +#define CKA_REQUIRED_CMS_ATTRIBUTES	(0x501)
    +#define CKA_DEFAULT_CMS_ATTRIBUTES	(0x502)
    +#define CKA_SUPPORTED_CMS_ATTRIBUTES	(0x503)
    +#define CKA_WRAP_TEMPLATE		(CKF_ARRAY_ATTRIBUTE | 0x211)
    +#define CKA_UNWRAP_TEMPLATE		(CKF_ARRAY_ATTRIBUTE | 0x212)
    +#define CKA_ALLOWED_MECHANISMS		(CKF_ARRAY_ATTRIBUTE | 0x600)
    +#define CKA_VENDOR_DEFINED		((unsigned long) (1 << 31))
    +
    +
    +struct ck_attribute
    +{
    +  ck_attribute_type_t type;
    +  void *value;
    +  unsigned long value_len;
    +};
    +
    +
    +struct ck_date
    +{
    +  unsigned char year[4];
    +  unsigned char month[2];
    +  unsigned char day[2];
    +};
    +
    +
    +typedef unsigned long ck_mechanism_type_t;
    +
    +#define CKM_RSA_PKCS_KEY_PAIR_GEN	(0)
    +#define CKM_RSA_PKCS			(1)
    +#define CKM_RSA_9796			(2)
    +#define CKM_RSA_X_509			(3)
    +#define CKM_MD2_RSA_PKCS		(4)
    +#define CKM_MD5_RSA_PKCS		(5)
    +#define CKM_SHA1_RSA_PKCS		(6)
    +#define CKM_RIPEMD128_RSA_PKCS		(7)
    +#define CKM_RIPEMD160_RSA_PKCS		(8)
    +#define CKM_RSA_PKCS_OAEP		(9)
    +#define CKM_RSA_X9_31_KEY_PAIR_GEN	(0xa)
    +#define CKM_RSA_X9_31			(0xb)
    +#define CKM_SHA1_RSA_X9_31		(0xc)
    +#define CKM_RSA_PKCS_PSS		(0xd)
    +#define CKM_SHA1_RSA_PKCS_PSS		(0xe)
    +#define CKM_DSA_KEY_PAIR_GEN		(0x10)
    +#define	CKM_DSA				(0x11)
    +#define CKM_DSA_SHA1			(0x12)
    +#define CKM_DH_PKCS_KEY_PAIR_GEN	(0x20)
    +#define CKM_DH_PKCS_DERIVE		(0x21)
    +#define	CKM_X9_42_DH_KEY_PAIR_GEN	(0x30)
    +#define CKM_X9_42_DH_DERIVE		(0x31)
    +#define CKM_X9_42_DH_HYBRID_DERIVE	(0x32)
    +#define CKM_X9_42_MQV_DERIVE		(0x33)
    +#define CKM_SHA256_RSA_PKCS		(0x40)
    +#define CKM_SHA384_RSA_PKCS		(0x41)
    +#define CKM_SHA512_RSA_PKCS		(0x42)
    +#define CKM_SHA256_RSA_PKCS_PSS		(0x43)
    +#define CKM_SHA384_RSA_PKCS_PSS		(0x44)
    +#define CKM_SHA512_RSA_PKCS_PSS		(0x45)
    +#define CKM_RC2_KEY_GEN			(0x100)
    +#define CKM_RC2_ECB			(0x101)
    +#define	CKM_RC2_CBC			(0x102)
    +#define	CKM_RC2_MAC			(0x103)
    +#define CKM_RC2_MAC_GENERAL		(0x104)
    +#define CKM_RC2_CBC_PAD			(0x105)
    +#define CKM_RC4_KEY_GEN			(0x110)
    +#define CKM_RC4				(0x111)
    +#define CKM_DES_KEY_GEN			(0x120)
    +#define CKM_DES_ECB			(0x121)
    +#define CKM_DES_CBC			(0x122)
    +#define CKM_DES_MAC			(0x123)
    +#define CKM_DES_MAC_GENERAL		(0x124)
    +#define CKM_DES_CBC_PAD			(0x125)
    +#define CKM_DES2_KEY_GEN		(0x130)
    +#define CKM_DES3_KEY_GEN		(0x131)
    +#define CKM_DES3_ECB			(0x132)
    +#define CKM_DES3_CBC			(0x133)
    +#define CKM_DES3_MAC			(0x134)
    +#define CKM_DES3_MAC_GENERAL		(0x135)
    +#define CKM_DES3_CBC_PAD		(0x136)
    +#define CKM_CDMF_KEY_GEN		(0x140)
    +#define CKM_CDMF_ECB			(0x141)
    +#define CKM_CDMF_CBC			(0x142)
    +#define CKM_CDMF_MAC			(0x143)
    +#define CKM_CDMF_MAC_GENERAL		(0x144)
    +#define CKM_CDMF_CBC_PAD		(0x145)
    +#define CKM_MD2				(0x200)
    +#define CKM_MD2_HMAC			(0x201)
    +#define CKM_MD2_HMAC_GENERAL		(0x202)
    +#define CKM_MD5				(0x210)
    +#define CKM_MD5_HMAC			(0x211)
    +#define CKM_MD5_HMAC_GENERAL		(0x212)
    +#define CKM_SHA_1			(0x220)
    +#define CKM_SHA_1_HMAC			(0x221)
    +#define CKM_SHA_1_HMAC_GENERAL		(0x222)
    +#define CKM_RIPEMD128			(0x230)
    +#define CKM_RIPEMD128_HMAC		(0x231)
    +#define CKM_RIPEMD128_HMAC_GENERAL	(0x232)
    +#define CKM_RIPEMD160			(0x240)
    +#define CKM_RIPEMD160_HMAC		(0x241)
    +#define CKM_RIPEMD160_HMAC_GENERAL	(0x242)
    +#define CKM_SHA256			(0x250)
    +#define CKM_SHA256_HMAC			(0x251)
    +#define CKM_SHA256_HMAC_GENERAL		(0x252)
    +#define CKM_SHA384			(0x260)
    +#define CKM_SHA384_HMAC			(0x261)
    +#define CKM_SHA384_HMAC_GENERAL		(0x262)
    +#define CKM_SHA512			(0x270)
    +#define CKM_SHA512_HMAC			(0x271)
    +#define CKM_SHA512_HMAC_GENERAL		(0x272)
    +#define CKM_CAST_KEY_GEN		(0x300)
    +#define CKM_CAST_ECB			(0x301)
    +#define CKM_CAST_CBC			(0x302)
    +#define CKM_CAST_MAC			(0x303)
    +#define CKM_CAST_MAC_GENERAL		(0x304)
    +#define CKM_CAST_CBC_PAD		(0x305)
    +#define CKM_CAST3_KEY_GEN		(0x310)
    +#define CKM_CAST3_ECB			(0x311)
    +#define CKM_CAST3_CBC			(0x312)
    +#define CKM_CAST3_MAC			(0x313)
    +#define CKM_CAST3_MAC_GENERAL		(0x314)
    +#define CKM_CAST3_CBC_PAD		(0x315)
    +#define CKM_CAST5_KEY_GEN		(0x320)
    +#define CKM_CAST128_KEY_GEN		(0x320)
    +#define CKM_CAST5_ECB			(0x321)
    +#define CKM_CAST128_ECB			(0x321)
    +#define CKM_CAST5_CBC			(0x322)
    +#define CKM_CAST128_CBC			(0x322)
    +#define CKM_CAST5_MAC			(0x323)
    +#define	CKM_CAST128_MAC			(0x323)
    +#define CKM_CAST5_MAC_GENERAL		(0x324)
    +#define CKM_CAST128_MAC_GENERAL		(0x324)
    +#define CKM_CAST5_CBC_PAD		(0x325)
    +#define CKM_CAST128_CBC_PAD		(0x325)
    +#define CKM_RC5_KEY_GEN			(0x330)
    +#define CKM_RC5_ECB			(0x331)
    +#define CKM_RC5_CBC			(0x332)
    +#define CKM_RC5_MAC			(0x333)
    +#define CKM_RC5_MAC_GENERAL		(0x334)
    +#define CKM_RC5_CBC_PAD			(0x335)
    +#define CKM_IDEA_KEY_GEN		(0x340)
    +#define CKM_IDEA_ECB			(0x341)
    +#define	CKM_IDEA_CBC			(0x342)
    +#define CKM_IDEA_MAC			(0x343)
    +#define CKM_IDEA_MAC_GENERAL		(0x344)
    +#define CKM_IDEA_CBC_PAD		(0x345)
    +#define CKM_GENERIC_SECRET_KEY_GEN	(0x350)
    +#define CKM_CONCATENATE_BASE_AND_KEY	(0x360)
    +#define CKM_CONCATENATE_BASE_AND_DATA	(0x362)
    +#define CKM_CONCATENATE_DATA_AND_BASE	(0x363)
    +#define CKM_XOR_BASE_AND_DATA		(0x364)
    +#define CKM_EXTRACT_KEY_FROM_KEY	(0x365)
    +#define CKM_SSL3_PRE_MASTER_KEY_GEN	(0x370)
    +#define CKM_SSL3_MASTER_KEY_DERIVE	(0x371)
    +#define CKM_SSL3_KEY_AND_MAC_DERIVE	(0x372)
    +#define CKM_SSL3_MASTER_KEY_DERIVE_DH	(0x373)
    +#define CKM_TLS_PRE_MASTER_KEY_GEN	(0x374)
    +#define CKM_TLS_MASTER_KEY_DERIVE	(0x375)
    +#define CKM_TLS_KEY_AND_MAC_DERIVE	(0x376)
    +#define CKM_TLS_MASTER_KEY_DERIVE_DH	(0x377)
    +#define CKM_SSL3_MD5_MAC		(0x380)
    +#define CKM_SSL3_SHA1_MAC		(0x381)
    +#define CKM_MD5_KEY_DERIVATION		(0x390)
    +#define CKM_MD2_KEY_DERIVATION		(0x391)
    +#define CKM_SHA1_KEY_DERIVATION		(0x392)
    +#define CKM_PBE_MD2_DES_CBC		(0x3a0)
    +#define CKM_PBE_MD5_DES_CBC		(0x3a1)
    +#define CKM_PBE_MD5_CAST_CBC		(0x3a2)
    +#define CKM_PBE_MD5_CAST3_CBC		(0x3a3)
    +#define CKM_PBE_MD5_CAST5_CBC		(0x3a4)
    +#define CKM_PBE_MD5_CAST128_CBC		(0x3a4)
    +#define CKM_PBE_SHA1_CAST5_CBC		(0x3a5)
    +#define CKM_PBE_SHA1_CAST128_CBC	(0x3a5)
    +#define CKM_PBE_SHA1_RC4_128		(0x3a6)
    +#define CKM_PBE_SHA1_RC4_40		(0x3a7)
    +#define CKM_PBE_SHA1_DES3_EDE_CBC	(0x3a8)
    +#define CKM_PBE_SHA1_DES2_EDE_CBC	(0x3a9)
    +#define CKM_PBE_SHA1_RC2_128_CBC	(0x3aa)
    +#define CKM_PBE_SHA1_RC2_40_CBC		(0x3ab)
    +#define CKM_PKCS5_PBKD2			(0x3b0)
    +#define CKM_PBA_SHA1_WITH_SHA1_HMAC	(0x3c0)
    +#define CKM_KEY_WRAP_LYNKS		(0x400)
    +#define CKM_KEY_WRAP_SET_OAEP		(0x401)
    +#define CKM_SKIPJACK_KEY_GEN		(0x1000)
    +#define CKM_SKIPJACK_ECB64		(0x1001)
    +#define CKM_SKIPJACK_CBC64		(0x1002)
    +#define CKM_SKIPJACK_OFB64		(0x1003)
    +#define CKM_SKIPJACK_CFB64		(0x1004)
    +#define CKM_SKIPJACK_CFB32		(0x1005)
    +#define CKM_SKIPJACK_CFB16		(0x1006)
    +#define CKM_SKIPJACK_CFB8		(0x1007)
    +#define CKM_SKIPJACK_WRAP		(0x1008)
    +#define CKM_SKIPJACK_PRIVATE_WRAP	(0x1009)
    +#define CKM_SKIPJACK_RELAYX		(0x100a)
    +#define CKM_KEA_KEY_PAIR_GEN		(0x1010)
    +#define CKM_KEA_KEY_DERIVE		(0x1011)
    +#define CKM_FORTEZZA_TIMESTAMP		(0x1020)
    +#define CKM_BATON_KEY_GEN		(0x1030)
    +#define CKM_BATON_ECB128		(0x1031)
    +#define CKM_BATON_ECB96			(0x1032)
    +#define CKM_BATON_CBC128		(0x1033)
    +#define CKM_BATON_COUNTER		(0x1034)
    +#define CKM_BATON_SHUFFLE		(0x1035)
    +#define CKM_BATON_WRAP			(0x1036)
    +#define CKM_ECDSA_KEY_PAIR_GEN		(0x1040)
    +#define CKM_EC_KEY_PAIR_GEN		(0x1040)
    +#define CKM_ECDSA			(0x1041)
    +#define CKM_ECDSA_SHA1			(0x1042)
    +#define CKM_ECDH1_DERIVE		(0x1050)
    +#define CKM_ECDH1_COFACTOR_DERIVE	(0x1051)
    +#define CKM_ECMQV_DERIVE		(0x1052)
    +#define CKM_JUNIPER_KEY_GEN		(0x1060)
    +#define CKM_JUNIPER_ECB128		(0x1061)
    +#define CKM_JUNIPER_CBC128		(0x1062)
    +#define CKM_JUNIPER_COUNTER		(0x1063)
    +#define CKM_JUNIPER_SHUFFLE		(0x1064)
    +#define CKM_JUNIPER_WRAP		(0x1065)
    +#define CKM_FASTHASH			(0x1070)
    +#define CKM_AES_KEY_GEN			(0x1080)
    +#define CKM_AES_ECB			(0x1081)
    +#define CKM_AES_CBC			(0x1082)
    +#define CKM_AES_MAC			(0x1083)
    +#define CKM_AES_MAC_GENERAL		(0x1084)
    +#define CKM_AES_CBC_PAD			(0x1085)
    +#define CKM_DSA_PARAMETER_GEN		(0x2000)
    +#define CKM_DH_PKCS_PARAMETER_GEN	(0x2001)
    +#define CKM_X9_42_DH_PARAMETER_GEN	(0x2002)
    +#define CKM_VENDOR_DEFINED		((unsigned long) (1 << 31))
    +
    +
    +struct ck_mechanism
    +{
    +  ck_mechanism_type_t mechanism;
    +  void *parameter;
    +  unsigned long parameter_len;
    +};
    +
    +
    +struct ck_mechanism_info
    +{
    +  unsigned long min_key_size;
    +  unsigned long max_key_size;
    +  ck_flags_t flags;
    +};
    +
    +#define CKF_HW			(1 << 0)
    +#define CKF_ENCRYPT		(1 << 8)
    +#define CKF_DECRYPT		(1 << 9)
    +#define CKF_DIGEST		(1 << 10)
    +#define CKF_SIGN		(1 << 11)
    +#define CKF_SIGN_RECOVER	(1 << 12)
    +#define CKF_VERIFY		(1 << 13)
    +#define CKF_VERIFY_RECOVER	(1 << 14)
    +#define CKF_GENERATE		(1 << 15)
    +#define CKF_GENERATE_KEY_PAIR	(1 << 16)
    +#define CKF_WRAP		(1 << 17)
    +#define CKF_UNWRAP		(1 << 18)
    +#define CKF_DERIVE		(1 << 19)
    +#define CKF_EXTENSION		((unsigned long) (1 << 31))
    +
    +
    +/* Flags for C_WaitForSlotEvent.  */
    +#define CKF_DONT_BLOCK				(1)
    +
    +
    +typedef unsigned long ck_rv_t;
    +
    +
    +typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session,
    +				ck_notification_t event, void *application);
    +
    +/* Forward reference.  */
    +struct ck_function_list;
    +
    +#define _CK_DECLARE_FUNCTION(name, args)	\
    +typedef ck_rv_t (*CK_ ## name) args;		\
    +ck_rv_t CK_SPEC name args
    +
    +_CK_DECLARE_FUNCTION (C_Initialize, (void *init_args));
    +_CK_DECLARE_FUNCTION (C_Finalize, (void *reserved));
    +_CK_DECLARE_FUNCTION (C_GetInfo, (struct ck_info *info));
    +_CK_DECLARE_FUNCTION (C_GetFunctionList,
    +		      (struct ck_function_list **function_list));
    +
    +_CK_DECLARE_FUNCTION (C_GetSlotList,
    +		      (unsigned char token_present, ck_slot_id_t *slot_list,
    +		       unsigned long *count));
    +_CK_DECLARE_FUNCTION (C_GetSlotInfo,
    +		      (ck_slot_id_t slot_id, struct ck_slot_info *info));
    +_CK_DECLARE_FUNCTION (C_GetTokenInfo,
    +		      (ck_slot_id_t slot_id, struct ck_token_info *info));
    +_CK_DECLARE_FUNCTION (C_WaitForSlotEvent,
    +		      (ck_flags_t flags, ck_slot_id_t *slot, void *reserved));
    +_CK_DECLARE_FUNCTION (C_GetMechanismList,
    +		      (ck_slot_id_t slot_id,
    +		       ck_mechanism_type_t *mechanism_list,
    +		       unsigned long *count));
    +_CK_DECLARE_FUNCTION (C_GetMechanismInfo,
    +		      (ck_slot_id_t slot_id, ck_mechanism_type_t type,
    +		       struct ck_mechanism_info *info));
    +_CK_DECLARE_FUNCTION (C_InitToken,
    +		      (ck_slot_id_t slot_id, unsigned char *pin,
    +		       unsigned long pin_len, unsigned char *label));
    +_CK_DECLARE_FUNCTION (C_InitPIN,
    +		      (ck_session_handle_t session, unsigned char *pin,
    +		       unsigned long pin_len));
    +_CK_DECLARE_FUNCTION (C_SetPIN,
    +		      (ck_session_handle_t session, unsigned char *old_pin,
    +		       unsigned long old_len, unsigned char *new_pin,
    +		       unsigned long new_len));
    +
    +_CK_DECLARE_FUNCTION (C_OpenSession,
    +		      (ck_slot_id_t slot_id, ck_flags_t flags,
    +		       void *application, ck_notify_t notify,
    +		       ck_session_handle_t *session));
    +_CK_DECLARE_FUNCTION (C_CloseSession, (ck_session_handle_t session));
    +_CK_DECLARE_FUNCTION (C_CloseAllSessions, (ck_slot_id_t slot_id));
    +_CK_DECLARE_FUNCTION (C_GetSessionInfo,
    +		      (ck_session_handle_t session,
    +		       struct ck_session_info *info));
    +_CK_DECLARE_FUNCTION (C_GetOperationState,
    +		      (ck_session_handle_t session,
    +		       unsigned char *operation_state,
    +		       unsigned long *operation_state_len));
    +_CK_DECLARE_FUNCTION (C_SetOperationState,
    +		      (ck_session_handle_t session,
    +		       unsigned char *operation_state,
    +		       unsigned long operation_state_len,
    +		       ck_object_handle_t encryption_key,
    +		       ck_object_handle_t authentiation_key));
    +_CK_DECLARE_FUNCTION (C_Login,
    +		      (ck_session_handle_t session, ck_user_type_t user_type,
    +		       unsigned char *pin, unsigned long pin_len));
    +_CK_DECLARE_FUNCTION (C_Logout, (ck_session_handle_t session));
    +
    +_CK_DECLARE_FUNCTION (C_CreateObject,
    +		      (ck_session_handle_t session,
    +		       struct ck_attribute *templ,
    +		       unsigned long count, ck_object_handle_t *object));
    +_CK_DECLARE_FUNCTION (C_CopyObject,
    +		      (ck_session_handle_t session, ck_object_handle_t object,
    +		       struct ck_attribute *templ, unsigned long count,
    +		       ck_object_handle_t *new_object));
    +_CK_DECLARE_FUNCTION (C_DestroyObject,
    +		      (ck_session_handle_t session,
    +		       ck_object_handle_t object));
    +_CK_DECLARE_FUNCTION (C_GetObjectSize,
    +		      (ck_session_handle_t session,
    +		       ck_object_handle_t object,
    +		       unsigned long *size));
    +_CK_DECLARE_FUNCTION (C_GetAttributeValue,
    +		      (ck_session_handle_t session,
    +		       ck_object_handle_t object,
    +		       struct ck_attribute *templ,
    +		       unsigned long count));
    +_CK_DECLARE_FUNCTION (C_SetAttributeValue,
    +		      (ck_session_handle_t session,
    +		       ck_object_handle_t object,
    +		       struct ck_attribute *templ,
    +		       unsigned long count));
    +_CK_DECLARE_FUNCTION (C_FindObjectsInit,
    +		      (ck_session_handle_t session,
    +		       struct ck_attribute *templ,
    +		       unsigned long count));
    +_CK_DECLARE_FUNCTION (C_FindObjects,
    +		      (ck_session_handle_t session,
    +		       ck_object_handle_t *object,
    +		       unsigned long max_object_count,
    +		       unsigned long *object_count));
    +_CK_DECLARE_FUNCTION (C_FindObjectsFinal,
    +		      (ck_session_handle_t session));
    +
    +_CK_DECLARE_FUNCTION (C_EncryptInit,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       ck_object_handle_t key));
    +_CK_DECLARE_FUNCTION (C_Encrypt,
    +		      (ck_session_handle_t session,
    +		       unsigned char *data, unsigned long data_len,
    +		       unsigned char *encrypted_data,
    +		       unsigned long *encrypted_data_len));
    +_CK_DECLARE_FUNCTION (C_EncryptUpdate,
    +		      (ck_session_handle_t session,
    +		       unsigned char *part, unsigned long part_len,
    +		       unsigned char *encrypted_part,
    +		       unsigned long *encrypted_part_len));
    +_CK_DECLARE_FUNCTION (C_EncryptFinal,
    +		      (ck_session_handle_t session,
    +		       unsigned char *last_encrypted_part,
    +		       unsigned long *last_encrypted_part_len));
    +
    +_CK_DECLARE_FUNCTION (C_DecryptInit,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       ck_object_handle_t key));
    +_CK_DECLARE_FUNCTION (C_Decrypt,
    +		      (ck_session_handle_t session,
    +		       unsigned char *encrypted_data,
    +		       unsigned long encrypted_data_len,
    +		       unsigned char *data, unsigned long *data_len));
    +_CK_DECLARE_FUNCTION (C_DecryptUpdate,
    +		      (ck_session_handle_t session,
    +		       unsigned char *encrypted_part,
    +		       unsigned long encrypted_part_len,
    +		       unsigned char *part, unsigned long *part_len));
    +_CK_DECLARE_FUNCTION (C_DecryptFinal,
    +		      (ck_session_handle_t session,
    +		       unsigned char *last_part,
    +		       unsigned long *last_part_len));
    +
    +_CK_DECLARE_FUNCTION (C_DigestInit,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism));
    +_CK_DECLARE_FUNCTION (C_Digest,
    +		      (ck_session_handle_t session,
    +		       unsigned char *data, unsigned long data_len,
    +		       unsigned char *digest,
    +		       unsigned long *digest_len));
    +_CK_DECLARE_FUNCTION (C_DigestUpdate,
    +		      (ck_session_handle_t session,
    +		       unsigned char *part, unsigned long part_len));
    +_CK_DECLARE_FUNCTION (C_DigestKey,
    +		      (ck_session_handle_t session, ck_object_handle_t key));
    +_CK_DECLARE_FUNCTION (C_DigestFinal,
    +		      (ck_session_handle_t session,
    +		       unsigned char *digest,
    +		       unsigned long *digest_len));
    +
    +_CK_DECLARE_FUNCTION (C_SignInit,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       ck_object_handle_t key));
    +_CK_DECLARE_FUNCTION (C_Sign,
    +		      (ck_session_handle_t session,
    +		       unsigned char *data, unsigned long data_len,
    +		       unsigned char *signature,
    +		       unsigned long *signature_len));
    +_CK_DECLARE_FUNCTION (C_SignUpdate,
    +		      (ck_session_handle_t session,
    +		       unsigned char *part, unsigned long part_len));
    +_CK_DECLARE_FUNCTION (C_SignFinal,
    +		      (ck_session_handle_t session,
    +		       unsigned char *signature,
    +		       unsigned long *signature_len));
    +_CK_DECLARE_FUNCTION (C_SignRecoverInit,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       ck_object_handle_t key));
    +_CK_DECLARE_FUNCTION (C_SignRecover,
    +		      (ck_session_handle_t session,
    +		       unsigned char *data, unsigned long data_len,
    +		       unsigned char *signature,
    +		       unsigned long *signature_len));
    +
    +_CK_DECLARE_FUNCTION (C_VerifyInit,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       ck_object_handle_t key));
    +_CK_DECLARE_FUNCTION (C_Verify,
    +		      (ck_session_handle_t session,
    +		       unsigned char *data, unsigned long data_len,
    +		       unsigned char *signature,
    +		       unsigned long signature_len));
    +_CK_DECLARE_FUNCTION (C_VerifyUpdate,
    +		      (ck_session_handle_t session,
    +		       unsigned char *part, unsigned long part_len));
    +_CK_DECLARE_FUNCTION (C_VerifyFinal,
    +		      (ck_session_handle_t session,
    +		       unsigned char *signature,
    +		       unsigned long signature_len));
    +_CK_DECLARE_FUNCTION (C_VerifyRecoverInit,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       ck_object_handle_t key));
    +_CK_DECLARE_FUNCTION (C_VerifyRecover,
    +		      (ck_session_handle_t session,
    +		       unsigned char *signature,
    +		       unsigned long signature_len,
    +		       unsigned char *data,
    +		       unsigned long *data_len));
    +
    +_CK_DECLARE_FUNCTION (C_DigestEncryptUpdate,
    +		      (ck_session_handle_t session,
    +		       unsigned char *part, unsigned long part_len,
    +		       unsigned char *encrypted_part,
    +		       unsigned long *encrypted_part_len));
    +_CK_DECLARE_FUNCTION (C_DecryptDigestUpdate,
    +		      (ck_session_handle_t session,
    +		       unsigned char *encrypted_part,
    +		       unsigned long encrypted_part_len,
    +		       unsigned char *part,
    +		       unsigned long *part_len));
    +_CK_DECLARE_FUNCTION (C_SignEncryptUpdate,
    +		      (ck_session_handle_t session,
    +		       unsigned char *part, unsigned long part_len,
    +		       unsigned char *encrypted_part,
    +		       unsigned long *encrypted_part_len));
    +_CK_DECLARE_FUNCTION (C_DecryptVerifyUpdate,
    +		      (ck_session_handle_t session,
    +		       unsigned char *encrypted_part,
    +		       unsigned long encrypted_part_len,
    +		       unsigned char *part,
    +		       unsigned long *part_len));
    +
    +_CK_DECLARE_FUNCTION (C_GenerateKey,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       struct ck_attribute *templ,
    +		       unsigned long count,
    +		       ck_object_handle_t *key));
    +_CK_DECLARE_FUNCTION (C_GenerateKeyPair,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       struct ck_attribute *public_key_template,
    +		       unsigned long public_key_attribute_count,
    +		       struct ck_attribute *private_key_template,
    +		       unsigned long private_key_attribute_count,
    +		       ck_object_handle_t *public_key,
    +		       ck_object_handle_t *private_key));
    +_CK_DECLARE_FUNCTION (C_WrapKey,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       ck_object_handle_t wrapping_key,
    +		       ck_object_handle_t key,
    +		       unsigned char *wrapped_key,
    +		       unsigned long *wrapped_key_len));
    +_CK_DECLARE_FUNCTION (C_UnwrapKey,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       ck_object_handle_t unwrapping_key,
    +		       unsigned char *wrapped_key,
    +		       unsigned long wrapped_key_len,
    +		       struct ck_attribute *templ,
    +		       unsigned long attribute_count,
    +		       ck_object_handle_t *key));
    +_CK_DECLARE_FUNCTION (C_DeriveKey,
    +		      (ck_session_handle_t session,
    +		       struct ck_mechanism *mechanism,
    +		       ck_object_handle_t base_key,
    +		       struct ck_attribute *templ,
    +		       unsigned long attribute_count,
    +		       ck_object_handle_t *key));
    +
    +_CK_DECLARE_FUNCTION (C_SeedRandom,
    +		      (ck_session_handle_t session, unsigned char *seed,
    +		       unsigned long seed_len));
    +_CK_DECLARE_FUNCTION (C_GenerateRandom,
    +		      (ck_session_handle_t session,
    +		       unsigned char *random_data,
    +		       unsigned long random_len));
    +
    +_CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session));
    +_CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session));
    +
    +
    +struct ck_function_list
    +{
    +  struct ck_version version;
    +  CK_C_Initialize C_Initialize;
    +  CK_C_Finalize C_Finalize;
    +  CK_C_GetInfo C_GetInfo;
    +  CK_C_GetFunctionList C_GetFunctionList;
    +  CK_C_GetSlotList C_GetSlotList;
    +  CK_C_GetSlotInfo C_GetSlotInfo;
    +  CK_C_GetTokenInfo C_GetTokenInfo;
    +  CK_C_GetMechanismList C_GetMechanismList;
    +  CK_C_GetMechanismInfo C_GetMechanismInfo;
    +  CK_C_InitToken C_InitToken;
    +  CK_C_InitPIN C_InitPIN;
    +  CK_C_SetPIN C_SetPIN;
    +  CK_C_OpenSession C_OpenSession;
    +  CK_C_CloseSession C_CloseSession;
    +  CK_C_CloseAllSessions C_CloseAllSessions;
    +  CK_C_GetSessionInfo C_GetSessionInfo;
    +  CK_C_GetOperationState C_GetOperationState;
    +  CK_C_SetOperationState C_SetOperationState;
    +  CK_C_Login C_Login;
    +  CK_C_Logout C_Logout;
    +  CK_C_CreateObject C_CreateObject;
    +  CK_C_CopyObject C_CopyObject;
    +  CK_C_DestroyObject C_DestroyObject;
    +  CK_C_GetObjectSize C_GetObjectSize;
    +  CK_C_GetAttributeValue C_GetAttributeValue;
    +  CK_C_SetAttributeValue C_SetAttributeValue;
    +  CK_C_FindObjectsInit C_FindObjectsInit;
    +  CK_C_FindObjects C_FindObjects;
    +  CK_C_FindObjectsFinal C_FindObjectsFinal;
    +  CK_C_EncryptInit C_EncryptInit;
    +  CK_C_Encrypt C_Encrypt;
    +  CK_C_EncryptUpdate C_EncryptUpdate;
    +  CK_C_EncryptFinal C_EncryptFinal;
    +  CK_C_DecryptInit C_DecryptInit;
    +  CK_C_Decrypt C_Decrypt;
    +  CK_C_DecryptUpdate C_DecryptUpdate;
    +  CK_C_DecryptFinal C_DecryptFinal;
    +  CK_C_DigestInit C_DigestInit;
    +  CK_C_Digest C_Digest;
    +  CK_C_DigestUpdate C_DigestUpdate;
    +  CK_C_DigestKey C_DigestKey;
    +  CK_C_DigestFinal C_DigestFinal;
    +  CK_C_SignInit C_SignInit;
    +  CK_C_Sign C_Sign;
    +  CK_C_SignUpdate C_SignUpdate;
    +  CK_C_SignFinal C_SignFinal;
    +  CK_C_SignRecoverInit C_SignRecoverInit;
    +  CK_C_SignRecover C_SignRecover;
    +  CK_C_VerifyInit C_VerifyInit;
    +  CK_C_Verify C_Verify;
    +  CK_C_VerifyUpdate C_VerifyUpdate;
    +  CK_C_VerifyFinal C_VerifyFinal;
    +  CK_C_VerifyRecoverInit C_VerifyRecoverInit;
    +  CK_C_VerifyRecover C_VerifyRecover;
    +  CK_C_DigestEncryptUpdate C_DigestEncryptUpdate;
    +  CK_C_DecryptDigestUpdate C_DecryptDigestUpdate;
    +  CK_C_SignEncryptUpdate C_SignEncryptUpdate;
    +  CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate;
    +  CK_C_GenerateKey C_GenerateKey;
    +  CK_C_GenerateKeyPair C_GenerateKeyPair;
    +  CK_C_WrapKey C_WrapKey;
    +  CK_C_UnwrapKey C_UnwrapKey;
    +  CK_C_DeriveKey C_DeriveKey;
    +  CK_C_SeedRandom C_SeedRandom;
    +  CK_C_GenerateRandom C_GenerateRandom;
    +  CK_C_GetFunctionStatus C_GetFunctionStatus;
    +  CK_C_CancelFunction C_CancelFunction;
    +  CK_C_WaitForSlotEvent C_WaitForSlotEvent;
    +};
    +
    +
    +typedef ck_rv_t (*ck_createmutex_t) (void **mutex);
    +typedef ck_rv_t (*ck_destroymutex_t) (void *mutex);
    +typedef ck_rv_t (*ck_lockmutex_t) (void *mutex);
    +typedef ck_rv_t (*ck_unlockmutex_t) (void *mutex);
    +
    +
    +struct ck_c_initialize_args
    +{
    +  ck_createmutex_t create_mutex;
    +  ck_destroymutex_t destroy_mutex;
    +  ck_lockmutex_t lock_mutex;
    +  ck_unlockmutex_t unlock_mutex;
    +  ck_flags_t flags;
    +  void *reserved;
    +};
    +
    +
    +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS	(1 << 0)
    +#define CKF_OS_LOCKING_OK			(1 << 1)
    +
    +#define CKR_OK					(0)
    +#define CKR_CANCEL				(1)
    +#define CKR_HOST_MEMORY				(2)
    +#define CKR_SLOT_ID_INVALID			(3)
    +#define CKR_GENERAL_ERROR			(5)
    +#define CKR_FUNCTION_FAILED			(6)
    +#define CKR_ARGUMENTS_BAD			(7)
    +#define CKR_NO_EVENT				(8)
    +#define CKR_NEED_TO_CREATE_THREADS		(9)
    +#define CKR_CANT_LOCK				(0xa)
    +#define CKR_ATTRIBUTE_READ_ONLY			(0x10)
    +#define CKR_ATTRIBUTE_SENSITIVE			(0x11)
    +#define CKR_ATTRIBUTE_TYPE_INVALID		(0x12)
    +#define CKR_ATTRIBUTE_VALUE_INVALID		(0x13)
    +#define CKR_DATA_INVALID			(0x20)
    +#define CKR_DATA_LEN_RANGE			(0x21)
    +#define CKR_DEVICE_ERROR			(0x30)
    +#define CKR_DEVICE_MEMORY			(0x31)
    +#define CKR_DEVICE_REMOVED			(0x32)
    +#define CKR_ENCRYPTED_DATA_INVALID		(0x40)
    +#define CKR_ENCRYPTED_DATA_LEN_RANGE		(0x41)
    +#define CKR_FUNCTION_CANCELED			(0x50)
    +#define CKR_FUNCTION_NOT_PARALLEL		(0x51)
    +#define CKR_FUNCTION_NOT_SUPPORTED		(0x54)
    +#define CKR_KEY_HANDLE_INVALID			(0x60)
    +#define CKR_KEY_SIZE_RANGE			(0x62)
    +#define CKR_KEY_TYPE_INCONSISTENT		(0x63)
    +#define CKR_KEY_NOT_NEEDED			(0x64)
    +#define CKR_KEY_CHANGED				(0x65)
    +#define CKR_KEY_NEEDED				(0x66)
    +#define CKR_KEY_INDIGESTIBLE			(0x67)
    +#define CKR_KEY_FUNCTION_NOT_PERMITTED		(0x68)
    +#define CKR_KEY_NOT_WRAPPABLE			(0x69)
    +#define CKR_KEY_UNEXTRACTABLE			(0x6a)
    +#define CKR_MECHANISM_INVALID			(0x70)
    +#define CKR_MECHANISM_PARAM_INVALID		(0x71)
    +#define CKR_OBJECT_HANDLE_INVALID		(0x82)
    +#define CKR_OPERATION_ACTIVE			(0x90)
    +#define CKR_OPERATION_NOT_INITIALIZED		(0x91)
    +#define CKR_PIN_INCORRECT			(0xa0)
    +#define CKR_PIN_INVALID				(0xa1)
    +#define CKR_PIN_LEN_RANGE			(0xa2)
    +#define CKR_PIN_EXPIRED				(0xa3)
    +#define CKR_PIN_LOCKED				(0xa4)
    +#define CKR_SESSION_CLOSED			(0xb0)
    +#define CKR_SESSION_COUNT			(0xb1)
    +#define CKR_SESSION_HANDLE_INVALID		(0xb3)
    +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED	(0xb4)
    +#define CKR_SESSION_READ_ONLY			(0xb5)
    +#define CKR_SESSION_EXISTS			(0xb6)
    +#define CKR_SESSION_READ_ONLY_EXISTS		(0xb7)
    +#define CKR_SESSION_READ_WRITE_SO_EXISTS	(0xb8)
    +#define CKR_SIGNATURE_INVALID			(0xc0)
    +#define CKR_SIGNATURE_LEN_RANGE			(0xc1)
    +#define CKR_TEMPLATE_INCOMPLETE			(0xd0)
    +#define CKR_TEMPLATE_INCONSISTENT		(0xd1)
    +#define CKR_TOKEN_NOT_PRESENT			(0xe0)
    +#define CKR_TOKEN_NOT_RECOGNIZED		(0xe1)
    +#define CKR_TOKEN_WRITE_PROTECTED		(0xe2)
    +#define	CKR_UNWRAPPING_KEY_HANDLE_INVALID	(0xf0)
    +#define CKR_UNWRAPPING_KEY_SIZE_RANGE		(0xf1)
    +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT	(0xf2)
    +#define CKR_USER_ALREADY_LOGGED_IN		(0x100)
    +#define CKR_USER_NOT_LOGGED_IN			(0x101)
    +#define CKR_USER_PIN_NOT_INITIALIZED		(0x102)
    +#define CKR_USER_TYPE_INVALID			(0x103)
    +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN	(0x104)
    +#define CKR_USER_TOO_MANY_TYPES			(0x105)
    +#define CKR_WRAPPED_KEY_INVALID			(0x110)
    +#define CKR_WRAPPED_KEY_LEN_RANGE		(0x112)
    +#define CKR_WRAPPING_KEY_HANDLE_INVALID		(0x113)
    +#define CKR_WRAPPING_KEY_SIZE_RANGE		(0x114)
    +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT	(0x115)
    +#define CKR_RANDOM_SEED_NOT_SUPPORTED		(0x120)
    +#define CKR_RANDOM_NO_RNG			(0x121)
    +#define CKR_DOMAIN_PARAMS_INVALID		(0x130)
    +#define CKR_BUFFER_TOO_SMALL			(0x150)
    +#define CKR_SAVED_STATE_INVALID			(0x160)
    +#define CKR_INFORMATION_SENSITIVE		(0x170)
    +#define CKR_STATE_UNSAVEABLE			(0x180)
    +#define CKR_CRYPTOKI_NOT_INITIALIZED		(0x190)
    +#define CKR_CRYPTOKI_ALREADY_INITIALIZED	(0x191)
    +#define CKR_MUTEX_BAD				(0x1a0)
    +#define CKR_MUTEX_NOT_LOCKED			(0x1a1)
    +#define CKR_FUNCTION_REJECTED			(0x200)
    +#define CKR_VENDOR_DEFINED			((unsigned long) (1 << 31))
    +
    +
    +
    +/* Compatibility layer.  */
    +
    +#ifdef CRYPTOKI_COMPAT
    +
    +#undef CK_DEFINE_FUNCTION
    +#define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name
    +
    +/* For NULL.  */
    +#include 
    +
    +typedef unsigned char CK_BYTE;
    +typedef unsigned char CK_CHAR;
    +typedef unsigned char CK_UTF8CHAR;
    +typedef unsigned char CK_BBOOL;
    +typedef unsigned long int CK_ULONG;
    +typedef long int CK_LONG;
    +typedef CK_BYTE *CK_BYTE_PTR;
    +typedef CK_CHAR *CK_CHAR_PTR;
    +typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR;
    +typedef CK_ULONG *CK_ULONG_PTR;
    +typedef void *CK_VOID_PTR;
    +typedef void **CK_VOID_PTR_PTR;
    +#define CK_FALSE 0
    +#define CK_TRUE 1
    +#ifndef CK_DISABLE_TRUE_FALSE
    +#ifndef FALSE
    +#define FALSE 0
    +#endif
    +#ifndef TRUE
    +#define TRUE 1
    +#endif
    +#endif
    +
    +typedef struct ck_version CK_VERSION;
    +typedef struct ck_version *CK_VERSION_PTR;
    +
    +typedef struct ck_info CK_INFO;
    +typedef struct ck_info *CK_INFO_PTR;
    +
    +typedef ck_slot_id_t *CK_SLOT_ID_PTR;
    +
    +typedef struct ck_slot_info CK_SLOT_INFO;
    +typedef struct ck_slot_info *CK_SLOT_INFO_PTR;
    +
    +typedef struct ck_token_info CK_TOKEN_INFO;
    +typedef struct ck_token_info *CK_TOKEN_INFO_PTR;
    +
    +typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR;
    +
    +typedef struct ck_session_info CK_SESSION_INFO;
    +typedef struct ck_session_info *CK_SESSION_INFO_PTR;
    +
    +typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR;
    +
    +typedef ck_object_class_t *CK_OBJECT_CLASS_PTR;
    +
    +typedef struct ck_attribute CK_ATTRIBUTE;
    +typedef struct ck_attribute *CK_ATTRIBUTE_PTR;
    +
    +typedef struct ck_date CK_DATE;
    +typedef struct ck_date *CK_DATE_PTR;
    +
    +typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR;
    +
    +typedef struct ck_mechanism CK_MECHANISM;
    +typedef struct ck_mechanism *CK_MECHANISM_PTR;
    +
    +typedef struct ck_mechanism_info CK_MECHANISM_INFO;
    +typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR;
    +
    +typedef struct ck_function_list CK_FUNCTION_LIST;
    +typedef struct ck_function_list *CK_FUNCTION_LIST_PTR;
    +typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR;
    +
    +typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS;
    +typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
    +
    +#define NULL_PTR NULL
    +
    +/* Delete the helper macros defined at the top of the file.  */
    +#undef ck_flags_t
    +#undef ck_version
    +
    +#undef ck_info
    +#undef cryptoki_version
    +#undef manufacturer_id
    +#undef library_description
    +#undef library_version
    +
    +#undef ck_notification_t
    +#undef ck_slot_id_t
    +
    +#undef ck_slot_info
    +#undef slot_description
    +#undef hardware_version
    +#undef firmware_version
    +
    +#undef ck_token_info
    +#undef serial_number
    +#undef max_session_count
    +#undef session_count
    +#undef max_rw_session_count
    +#undef rw_session_count
    +#undef max_pin_len
    +#undef min_pin_len
    +#undef total_public_memory
    +#undef free_public_memory
    +#undef total_private_memory
    +#undef free_private_memory
    +#undef utc_time
    +
    +#undef ck_session_handle_t
    +#undef ck_user_type_t
    +#undef ck_state_t
    +
    +#undef ck_session_info
    +#undef slot_id
    +#undef device_error
    +
    +#undef ck_object_handle_t
    +#undef ck_object_class_t
    +#undef ck_hw_feature_type_t
    +#undef ck_key_type_t
    +#undef ck_certificate_type_t
    +#undef ck_attribute_type_t
    +
    +#undef ck_attribute
    +#undef value
    +#undef value_len
    +
    +#undef ck_date
    +
    +#undef ck_mechanism_type_t
    +
    +#undef ck_mechanism
    +#undef parameter
    +#undef parameter_len
    +
    +#undef ck_mechanism_info
    +#undef min_key_size
    +#undef max_key_size
    +
    +#undef ck_rv_t
    +#undef ck_notify_t
    +
    +#undef ck_function_list
    +
    +#undef ck_createmutex_t
    +#undef ck_destroymutex_t
    +#undef ck_lockmutex_t
    +#undef ck_unlockmutex_t
    +
    +#undef ck_c_initialize_args
    +#undef create_mutex
    +#undef destroy_mutex
    +#undef lock_mutex
    +#undef unlock_mutex
    +#undef reserved
    +
    +#endif	/* CRYPTOKI_COMPAT */
    +
    +
    +/* System dependencies.  */
    +#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32)
    +#pragma pack(pop, cryptoki)
    +#endif
    +
    +#if defined(__cplusplus)
    +}
    +#endif
    +
    +#endif	/* PKCS11_H */
    diff --git a/crypto/openssh/platform.c b/crypto/openssh/platform.c
    index aee4b01e7c6..e3a428aaa08 100644
    --- a/crypto/openssh/platform.c
    +++ b/crypto/openssh/platform.c
    @@ -1,4 +1,4 @@
    -/* $Id: platform.c,v 1.1 2006/08/30 17:24:41 djm Exp $ */
    +/* $Id: platform.c,v 1.3 2009/12/20 23:49:22 dtucker Exp $ */
     
     /*
      * Copyright (c) 2006 Darren Tucker.  All rights reserved.
    @@ -21,6 +21,15 @@
     
     #include "openbsd-compat/openbsd-compat.h"
     
    +void
    +platform_pre_listen(void)
    +{
    +#ifdef LINUX_OOM_ADJUST
    +	/* Adjust out-of-memory killer so listening process is not killed */
    +	oom_adjust_setup();
    +#endif
    +}
    +
     void
     platform_pre_fork(void)
     {
    @@ -43,4 +52,17 @@ platform_post_fork_child(void)
     #ifdef USE_SOLARIS_PROCESS_CONTRACTS
     	solaris_contract_post_fork_child();
     #endif
    +#ifdef LINUX_OOM_ADJUST
    +	oom_adjust_restore();
    +#endif
    +}
    +
    +char *
    +platform_krb5_get_principal_name(const char *pw_name)
    +{
    +#ifdef USE_AIX_KRB_NAME
    +	return aix_krb5_get_principal_name(pw_name);
    +#else
    +	return NULL;
    +#endif
     }
    diff --git a/crypto/openssh/platform.h b/crypto/openssh/platform.h
    index cf93bc57c0e..30a1d2259d3 100644
    --- a/crypto/openssh/platform.h
    +++ b/crypto/openssh/platform.h
    @@ -1,4 +1,4 @@
    -/* $Id: platform.h,v 1.1 2006/08/30 17:24:41 djm Exp $ */
    +/* $Id: platform.h,v 1.4 2010/01/14 01:44:16 djm Exp $ */
     
     /*
      * Copyright (c) 2006 Darren Tucker.  All rights reserved.
    @@ -18,6 +18,11 @@
     
     #include 
     
    +void platform_pre_listen(void);
     void platform_pre_fork(void);
     void platform_post_fork_parent(pid_t child_pid);
     void platform_post_fork_child(void);
    +char *platform_get_krb5_client(const char *);
    +char *platform_krb5_get_principal_name(const char *);
    +
    +
    diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c
    index 8b810a1fc78..6c4bb34537a 100644
    --- a/crypto/openssh/readconf.c
    +++ b/crypto/openssh/readconf.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */
    +/* $OpenBSD: readconf.c,v 1.183 2010/02/08 10:50:20 markus Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -126,14 +126,14 @@ typedef enum {
     	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
     	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
     	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
    -	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
    +	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
     	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
     	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
     	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
     	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
     	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
     	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
    -	oVisualHostKey, oZeroKnowledgePasswordAuthentication,
    +	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
     	oVersionAddendum,
     	oDeprecated, oUnsupported
     } OpCodes;
    @@ -209,10 +209,12 @@ static struct {
     	{ "preferredauthentications", oPreferredAuthentications },
     	{ "hostkeyalgorithms", oHostKeyAlgorithms },
     	{ "bindaddress", oBindAddress },
    -#ifdef SMARTCARD
    -	{ "smartcarddevice", oSmartcardDevice },
    +#ifdef ENABLE_PKCS11
    +	{ "smartcarddevice", oPKCS11Provider },
    +	{ "pkcs11provider", oPKCS11Provider },
     #else
     	{ "smartcarddevice", oUnsupported },
    +	{ "pkcs11provider", oUnsupported },
     #endif
     	{ "clearallforwardings", oClearAllForwardings },
     	{ "enablesshkeysign", oEnableSSHKeysign },
    @@ -232,6 +234,7 @@ static struct {
     	{ "localcommand", oLocalCommand },
     	{ "permitlocalcommand", oPermitLocalCommand },
     	{ "visualhostkey", oVisualHostKey },
    +	{ "useroaming", oUseRoaming },
     #ifdef JPAKE
     	{ "zeroknowledgepasswordauthentication",
     	    oZeroKnowledgePasswordAuthentication },
    @@ -625,8 +628,8 @@ parse_string:
     		charptr = &options->bind_address;
     		goto parse_string;
     
    -	case oSmartcardDevice:
    -		charptr = &options->smartcard_device;
    +	case oPKCS11Provider:
    +		charptr = &options->pkcs11_provider;
     		goto parse_string;
     
     	case oProxyCommand:
    @@ -931,6 +934,10 @@ parse_int:
     		intptr = &options->visual_host_key;
     		goto parse_flag;
     
    +	case oUseRoaming:
    +		intptr = &options->use_roaming;
    +		goto parse_flag;
    +
     	case oVersionAddendum:
     		ssh_version_set_addendum(strtok(s, "\n"));
     		do {
    @@ -1070,7 +1077,7 @@ initialize_options(Options * options)
     	options->log_level = SYSLOG_LEVEL_NOT_SET;
     	options->preferred_authentications = NULL;
     	options->bind_address = NULL;
    -	options->smartcard_device = NULL;
    +	options->pkcs11_provider = NULL;
     	options->enable_ssh_keysign = - 1;
     	options->no_host_authentication_for_localhost = - 1;
     	options->identities_only = - 1;
    @@ -1087,6 +1094,7 @@ initialize_options(Options * options)
     	options->tun_remote = -1;
     	options->local_command = NULL;
     	options->permit_local_command = -1;
    +	options->use_roaming = -1;
     	options->visual_host_key = -1;
     	options->zero_knowledge_password_authentication = -1;
     }
    @@ -1160,7 +1168,7 @@ fill_default_options(Options * options)
     	/* options->macs, default set in myproposals.h */
     	/* options->hostkeyalgorithms, default set in myproposals.h */
     	if (options->protocol == SSH_PROTO_UNKNOWN)
    -		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
    +		options->protocol = SSH_PROTO_2;
     	if (options->num_identity_files == 0) {
     		if (options->protocol & SSH_PROTO_1) {
     			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
    @@ -1223,6 +1231,8 @@ fill_default_options(Options * options)
     		options->tun_remote = SSH_TUNID_ANY;
     	if (options->permit_local_command == -1)
     		options->permit_local_command = 0;
    +	if (options->use_roaming == -1)
    +		options->use_roaming = 1;
     	if (options->visual_host_key == -1)
     		options->visual_host_key = 0;
     	if (options->zero_knowledge_password_authentication == -1)
    diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h
    index 8fb3a852816..4264751c516 100644
    --- a/crypto/openssh/readconf.h
    +++ b/crypto/openssh/readconf.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: readconf.h,v 1.78 2009/02/12 03:00:56 djm Exp $ */
    +/* $OpenBSD: readconf.h,v 1.82 2010/02/08 10:50:20 markus Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -84,7 +84,7 @@ typedef struct {
     	char   *user_hostfile2;
     	char   *preferred_authentications;
     	char   *bind_address;	/* local socket address for connection to sshd */
    -	char   *smartcard_device; /* Smartcard reader device */
    +	char   *pkcs11_provider; /* PKCS#11 provider */
     	int	verify_host_key_dns;	/* Verify host key using DNS */
     
     	int     num_identity_files;	/* Number of files for RSA/DSA identities. */
    @@ -123,6 +123,8 @@ typedef struct {
     	int	permit_local_command;
     	int	visual_host_key;
     
    +	int	use_roaming;
    +
     }       Options;
     
     #define SSHCTL_MASTER_NO	0
    diff --git a/crypto/openssh/roaming.h b/crypto/openssh/roaming.h
    new file mode 100644
    index 00000000000..6bb94cc391d
    --- /dev/null
    +++ b/crypto/openssh/roaming.h
    @@ -0,0 +1,44 @@
    +/* $OpenBSD: roaming.h,v 1.5 2009/10/24 11:11:58 andreas Exp $ */
    +/*
    + * Copyright (c) 2004-2009 AppGate Network Security AB
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +#ifndef ROAMING_H
    +#define ROAMING_H
    +
    +#define DEFAULT_ROAMBUF 65536
    +#define ROAMING_REQUEST "roaming@appgate.com"
    +
    +extern int roaming_enabled;
    +extern int resume_in_progress;
    +
    +void	request_roaming(void);
    +int	get_snd_buf_size(void);
    +int	get_recv_buf_size(void);
    +void	add_recv_bytes(u_int64_t);
    +int	wait_for_roaming_reconnect(void);
    +void	roaming_reply(int, u_int32_t, void *);
    +void	set_out_buffer_size(size_t);
    +ssize_t	roaming_write(int, const void *, size_t, int *);
    +ssize_t	roaming_read(int, void *, size_t, int *);
    +size_t	roaming_atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
    +u_int64_t	get_recv_bytes(void);
    +u_int64_t	get_sent_bytes(void);
    +void	roam_set_bytes(u_int64_t, u_int64_t);
    +void	resend_bytes(int, u_int64_t *);
    +void	calculate_new_key(u_int64_t *, u_int64_t, u_int64_t);
    +int	resume_kex(void);
    +
    +#endif /* ROAMING */
    diff --git a/crypto/openssh/roaming_client.c b/crypto/openssh/roaming_client.c
    new file mode 100644
    index 00000000000..cea8e7360ad
    --- /dev/null
    +++ b/crypto/openssh/roaming_client.c
    @@ -0,0 +1,280 @@
    +/* $OpenBSD: roaming_client.c,v 1.3 2010/01/18 01:50:27 dtucker Exp $ */
    +/*
    + * Copyright (c) 2004-2009 AppGate Network Security AB
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +#include "includes.h"
    +
    +#include "openbsd-compat/sys-queue.h"
    +#include 
    +#include 
    +
    +#ifdef HAVE_INTTYPES_H
    +#include 
    +#endif
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +
    +#include "xmalloc.h"
    +#include "buffer.h"
    +#include "channels.h"
    +#include "cipher.h"
    +#include "dispatch.h"
    +#include "clientloop.h"
    +#include "log.h"
    +#include "match.h"
    +#include "misc.h"
    +#include "packet.h"
    +#include "ssh.h"
    +#include "key.h"
    +#include "kex.h"
    +#include "readconf.h"
    +#include "roaming.h"
    +#include "ssh2.h"
    +#include "sshconnect.h"
    +
    +/* import */
    +extern Options options;
    +extern char *host;
    +extern struct sockaddr_storage hostaddr;
    +extern int session_resumed;
    +
    +static u_int32_t roaming_id;
    +static u_int64_t cookie;
    +static u_int64_t lastseenchall;
    +static u_int64_t key1, key2, oldkey1, oldkey2;
    +
    +void
    +roaming_reply(int type, u_int32_t seq, void *ctxt)
    +{
    +	if (type == SSH2_MSG_REQUEST_FAILURE) {
    +		logit("Server denied roaming");
    +		return;
    +	}
    +	verbose("Roaming enabled");
    +	roaming_id = packet_get_int();
    +	cookie = packet_get_int64();
    +	key1 = oldkey1 = packet_get_int64();
    +	key2 = oldkey2 = packet_get_int64();
    +	set_out_buffer_size(packet_get_int() +  get_snd_buf_size());
    +	roaming_enabled = 1;
    +}
    +
    +void
    +request_roaming(void)
    +{
    +	packet_start(SSH2_MSG_GLOBAL_REQUEST);
    +	packet_put_cstring(ROAMING_REQUEST);
    +	packet_put_char(1);
    +	packet_put_int(get_recv_buf_size());
    +	packet_send();
    +	client_register_global_confirm(roaming_reply, NULL);
    +}
    +
    +static void
    +roaming_auth_required(void)
    +{
    +	u_char digest[SHA_DIGEST_LENGTH];
    +	EVP_MD_CTX md;
    +	Buffer b;
    +	const EVP_MD *evp_md = EVP_sha1();
    +	u_int64_t chall, oldchall;
    +
    +	chall = packet_get_int64();
    +	oldchall = packet_get_int64();
    +	if (oldchall != lastseenchall) {
    +		key1 = oldkey1;
    +		key2 = oldkey2;
    +	}
    +	lastseenchall = chall;
    +
    +	buffer_init(&b);
    +	buffer_put_int64(&b, cookie);
    +	buffer_put_int64(&b, chall);
    +	EVP_DigestInit(&md, evp_md);
    +	EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
    +	EVP_DigestFinal(&md, digest, NULL);
    +	buffer_free(&b);
    +
    +	packet_start(SSH2_MSG_KEX_ROAMING_AUTH);
    +	packet_put_int64(key1 ^ get_recv_bytes());
    +	packet_put_raw(digest, sizeof(digest));
    +	packet_send();
    +
    +	oldkey1 = key1;
    +	oldkey2 = key2;
    +	calculate_new_key(&key1, cookie, chall);
    +	calculate_new_key(&key2, cookie, chall);
    +
    +	debug("Received %llu bytes", (unsigned long long)get_recv_bytes());
    +	debug("Sent roaming_auth packet");
    +}
    +
    +int
    +resume_kex(void)
    +{
    +	/*
    +	 * This should not happen - if the client sends the kex method
    +	 * resume@appgate.com then the kex is done in roaming_resume().
    +	 */
    +	return 1;
    +}
    +
    +static int
    +roaming_resume(void)
    +{
    +	u_int64_t recv_bytes;
    +	char *str = NULL, *kexlist = NULL, *c;
    +	int i, type;
    +	int timeout_ms = options.connection_timeout * 1000;
    +	u_int len;
    +	u_int32_t rnd = 0;
    +
    +	resume_in_progress = 1;
    +
    +	/* Exchange banners */
    +	ssh_exchange_identification(timeout_ms);
    +	packet_set_nonblocking();
    +
    +	/* Send a kexinit message with resume@appgate.com as only kex algo */
    +	packet_start(SSH2_MSG_KEXINIT);
    +	for (i = 0; i < KEX_COOKIE_LEN; i++) {
    +		if (i % 4 == 0)
    +			rnd = arc4random();
    +		packet_put_char(rnd & 0xff);
    +		rnd >>= 8;
    +	}
    +	packet_put_cstring(KEX_RESUME);
    +	for (i = 1; i < PROPOSAL_MAX; i++) {
    +		/* kex algorithm added so start with i=1 and not 0 */
    +		packet_put_cstring(""); /* Not used when we resume */
    +	}
    +	packet_put_char(1); /* first kex_packet follows */
    +	packet_put_int(0); /* reserved */
    +	packet_send();
    +
    +	/* Assume that resume@appgate.com will be accepted */
    +	packet_start(SSH2_MSG_KEX_ROAMING_RESUME);
    +	packet_put_int(roaming_id);
    +	packet_send();
    +
    +	/* Read the server's kexinit and check for resume@appgate.com */
    +	if ((type = packet_read()) != SSH2_MSG_KEXINIT) {
    +		debug("expected kexinit on resume, got %d", type);
    +		goto fail;
    +	}
    +	for (i = 0; i < KEX_COOKIE_LEN; i++)
    +		(void)packet_get_char();
    +	kexlist = packet_get_string(&len);
    +	if (!kexlist
    +	    || (str = match_list(KEX_RESUME, kexlist, NULL)) == NULL) {
    +		debug("server doesn't allow resume");
    +		goto fail;
    +	}
    +	xfree(str);
    +	for (i = 1; i < PROPOSAL_MAX; i++) {
    +		/* kex algorithm taken care of so start with i=1 and not 0 */
    +		xfree(packet_get_string(&len));
    +	}
    +	i = packet_get_char(); /* first_kex_packet_follows */
    +	if (i && (c = strchr(kexlist, ',')))
    +		*c = 0;
    +	if (i && strcmp(kexlist, KEX_RESUME)) {
    +		debug("server's kex guess (%s) was wrong, skipping", kexlist);
    +		(void)packet_read(); /* Wrong guess - discard packet */
    +	}
    +
    +	/*
    +	 * Read the ROAMING_AUTH_REQUIRED challenge from the server and
    +	 * send ROAMING_AUTH
    +	 */
    +	if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED) {
    +		debug("expected roaming_auth_required, got %d", type);
    +		goto fail;
    +	}
    +	roaming_auth_required();
    +
    +	/* Read ROAMING_AUTH_OK from the server */
    +	if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_OK) {
    +		debug("expected roaming_auth_ok, got %d", type);
    +		goto fail;
    +	}
    +	recv_bytes = packet_get_int64() ^ oldkey2;
    +	debug("Peer received %llu bytes", (unsigned long long)recv_bytes);
    +	resend_bytes(packet_get_connection_out(), &recv_bytes);
    +
    +	resume_in_progress = 0;
    +
    +	session_resumed = 1; /* Tell clientloop */
    +
    +	return 0;
    +
    +fail:
    +	if (kexlist)
    +		xfree(kexlist);
    +	if (packet_get_connection_in() == packet_get_connection_out())
    +		close(packet_get_connection_in());
    +	else {
    +		close(packet_get_connection_in());
    +		close(packet_get_connection_out());
    +	}
    +	return 1;
    +}
    +
    +int
    +wait_for_roaming_reconnect(void)
    +{
    +	static int reenter_guard = 0;
    +	int timeout_ms = options.connection_timeout * 1000;
    +	int c;
    +
    +	if (reenter_guard != 0)
    +		fatal("Server refused resume, roaming timeout may be exceeded");
    +	reenter_guard = 1;
    +
    +	fprintf(stderr, "[connection suspended, press return to resume]");
    +	fflush(stderr);
    +	packet_backup_state();
    +	/* TODO Perhaps we should read from tty here */
    +	while ((c = fgetc(stdin)) != EOF) {
    +		if (c == 'Z' - 64) {
    +			kill(getpid(), SIGTSTP);
    +			continue;
    +		}
    +		if (c != '\n' && c != '\r')
    +			continue;
    +
    +		if (ssh_connect(host, &hostaddr, options.port,
    +		    options.address_family, 1, &timeout_ms,
    +		    options.tcp_keep_alive, options.use_privileged_port,
    +		    options.proxy_command) == 0 && roaming_resume() == 0) {
    +			packet_restore_state();
    +			reenter_guard = 0;
    +			fprintf(stderr, "[connection resumed]\n");
    +			fflush(stderr);
    +			return 0;
    +		}
    +
    +		fprintf(stderr, "[reconnect failed, press return to retry]");
    +		fflush(stderr);
    +	}
    +	fprintf(stderr, "[exiting]\n");
    +	fflush(stderr);
    +	exit(0);
    +}
    diff --git a/crypto/openssh/roaming_common.c b/crypto/openssh/roaming_common.c
    new file mode 100644
    index 00000000000..9adbe56fcbb
    --- /dev/null
    +++ b/crypto/openssh/roaming_common.c
    @@ -0,0 +1,244 @@
    +/* $OpenBSD: roaming_common.c,v 1.8 2010/01/12 00:59:29 djm Exp $ */
    +/*
    + * Copyright (c) 2004-2009 AppGate Network Security AB
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +#include "includes.h"
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#ifdef HAVE_INTTYPES_H
    +#include 
    +#endif
    +#include 
    +#include 
    +#include 
    +
    +#include "atomicio.h"
    +#include "log.h"
    +#include "packet.h"
    +#include "xmalloc.h"
    +#include "cipher.h"
    +#include "buffer.h"
    +#include "roaming.h"
    +
    +static size_t out_buf_size = 0;
    +static char *out_buf = NULL;
    +static size_t out_start;
    +static size_t out_last;
    +
    +static u_int64_t write_bytes = 0;
    +static u_int64_t read_bytes = 0;
    +
    +int roaming_enabled = 0;
    +int resume_in_progress = 0;
    +
    +int
    +get_snd_buf_size()
    +{
    +	int fd = packet_get_connection_out();
    +	int optval;
    +	socklen_t optvallen = sizeof(optval);
    +
    +	if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optvallen) != 0)
    +		optval = DEFAULT_ROAMBUF;
    +	return optval;
    +}
    +
    +int
    +get_recv_buf_size()
    +{
    +	int fd = packet_get_connection_in();
    +	int optval;
    +	socklen_t optvallen = sizeof(optval);
    +
    +	if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, &optvallen) != 0)
    +		optval = DEFAULT_ROAMBUF;
    +	return optval;
    +}
    +
    +void
    +set_out_buffer_size(size_t size)
    +{
    +	/*
    +	 * The buffer size can only be set once and the buffer will live
    +	 * as long as the session lives.
    +	 */
    +	if (out_buf == NULL) {
    +		out_buf_size = size;
    +		out_buf = xmalloc(size);
    +		out_start = 0;
    +		out_last = 0;
    +	}
    +}
    +
    +u_int64_t
    +get_recv_bytes(void)
    +{
    +	return read_bytes;
    +}
    +
    +void
    +add_recv_bytes(u_int64_t num)
    +{
    +	read_bytes += num;
    +}
    +
    +u_int64_t
    +get_sent_bytes(void)
    +{
    +	return write_bytes;
    +}
    +
    +void
    +roam_set_bytes(u_int64_t sent, u_int64_t recvd)
    +{
    +	read_bytes = recvd;
    +	write_bytes = sent;
    +}
    +
    +static void
    +buf_append(const char *buf, size_t count)
    +{
    +	if (count > out_buf_size) {
    +		buf += count - out_buf_size;
    +		count = out_buf_size;
    +	}
    +	if (count < out_buf_size - out_last) {
    +		memcpy(out_buf + out_last, buf, count);
    +		if (out_start > out_last)
    +			out_start += count;
    +		out_last += count;
    +	} else {
    +		/* data will wrap */
    +		size_t chunk = out_buf_size - out_last;
    +		memcpy(out_buf + out_last, buf, chunk);
    +		memcpy(out_buf, buf + chunk, count - chunk);
    +		out_last = count - chunk;
    +		out_start = out_last + 1;
    +	}
    +}
    +
    +ssize_t
    +roaming_write(int fd, const void *buf, size_t count, int *cont)
    +{
    +	ssize_t ret;
    +
    +	ret = write(fd, buf, count);
    +	if (ret > 0 && !resume_in_progress) {
    +		write_bytes += ret;
    +		if (out_buf_size > 0)
    +			buf_append(buf, ret);
    +	}
    +	if (out_buf_size > 0 &&
    +	    (ret == 0 || (ret == -1 && errno == EPIPE))) {
    +		if (wait_for_roaming_reconnect() != 0) {
    +			ret = 0;
    +			*cont = 1;
    +		} else {
    +			ret = -1;
    +			errno = EAGAIN;
    +		}
    +	}
    +	return ret;
    +}
    +
    +ssize_t
    +roaming_read(int fd, void *buf, size_t count, int *cont)
    +{
    +	ssize_t ret = read(fd, buf, count);
    +	if (ret > 0) {
    +		if (!resume_in_progress) {
    +			read_bytes += ret;
    +		}
    +	} else if (out_buf_size > 0 &&
    +	    (ret == 0 || (ret == -1 && (errno == ECONNRESET
    +	    || errno == ECONNABORTED || errno == ETIMEDOUT
    +	    || errno == EHOSTUNREACH)))) {
    +		debug("roaming_read failed for %d  ret=%ld  errno=%d",
    +		    fd, (long)ret, errno);
    +		ret = 0;
    +		if (wait_for_roaming_reconnect() == 0)
    +			*cont = 1;
    +	}
    +	return ret;
    +}
    +
    +size_t
    +roaming_atomicio(ssize_t(*f)(int, void*, size_t), int fd, void *buf,
    +    size_t count)
    +{
    +	size_t ret = atomicio(f, fd, buf, count);
    +
    +	if (f == vwrite && ret > 0 && !resume_in_progress) {
    +		write_bytes += ret;
    +	} else if (f == read && ret > 0 && !resume_in_progress) {
    +		read_bytes += ret;
    +	}
    +	return ret;
    +}
    +
    +void
    +resend_bytes(int fd, u_int64_t *offset)
    +{
    +	size_t available, needed;
    +
    +	if (out_start < out_last)
    +		available = out_last - out_start;
    +	else
    +		available = out_buf_size;
    +	needed = write_bytes - *offset;
    +	debug3("resend_bytes: resend %lu bytes from %llu",
    +	    (unsigned long)needed, (unsigned long long)*offset);
    +	if (needed > available)
    +		fatal("Needed to resend more data than in the cache");
    +	if (out_last < needed) {
    +		int chunkend = needed - out_last;
    +		atomicio(vwrite, fd, out_buf + out_buf_size - chunkend,
    +		    chunkend);
    +		atomicio(vwrite, fd, out_buf, out_last);
    +	} else {
    +		atomicio(vwrite, fd, out_buf + (out_last - needed), needed);
    +	}
    +}
    +
    +/*
    + * Caclulate a new key after a reconnect
    + */
    +void
    +calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
    +{
    +	const EVP_MD *md = EVP_sha1();
    +	EVP_MD_CTX ctx;
    +	char hash[EVP_MAX_MD_SIZE];
    +	Buffer b;
    +
    +	buffer_init(&b);
    +	buffer_put_int64(&b, *key);
    +	buffer_put_int64(&b, cookie);
    +	buffer_put_int64(&b, challenge);
    +
    +	EVP_DigestInit(&ctx, md);
    +	EVP_DigestUpdate(&ctx, buffer_ptr(&b), buffer_len(&b));
    +	EVP_DigestFinal(&ctx, hash, NULL);
    +
    +	buffer_clear(&b);
    +	buffer_append(&b, hash, EVP_MD_size(md));
    +	*key = buffer_get_int64(&b);
    +	buffer_free(&b);
    +}
    diff --git a/crypto/openssh/roaming_dummy.c b/crypto/openssh/roaming_dummy.c
    new file mode 100644
    index 00000000000..45c4008e7f9
    --- /dev/null
    +++ b/crypto/openssh/roaming_dummy.c
    @@ -0,0 +1,61 @@
    +/* $OpenBSD: roaming_dummy.c,v 1.3 2009/06/21 09:04:03 dtucker Exp $ */
    +/*
    + * Copyright (c) 2004-2009 AppGate Network Security AB
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +/*
    + * This file is included in the client programs which should not
    + * support roaming.
    + */
    +
    +#include "includes.h"
    +
    +#include 
    +#include 
    +
    +#include "roaming.h"
    +
    +int resume_in_progress = 0;
    +
    +u_int64_t
    +get_recv_bytes(void)
    +{
    +	return 0;
    +}
    +
    +ssize_t
    +roaming_write(int fd, const void *buf, size_t count, int *cont)
    +{
    +	return write(fd, buf, count);
    +}
    +
    +ssize_t
    +roaming_read(int fd, void *buf, size_t count, int *cont)
    +{
    +	if (cont)
    +		*cont = 0;
    +	return read(fd, buf, count);
    +}
    +
    +void
    +add_recv_bytes(u_int64_t num)
    +{
    +}
    +
    +int
    +resume_kex(void)
    +{
    +	return 1;
    +}
    diff --git a/crypto/openssh/roaming_serv.c b/crypto/openssh/roaming_serv.c
    new file mode 100644
    index 00000000000..511ca846101
    --- /dev/null
    +++ b/crypto/openssh/roaming_serv.c
    @@ -0,0 +1,31 @@
    +/* $OpenBSD: roaming_serv.c,v 1.1 2009/10/24 11:18:23 andreas Exp $ */
    +/*
    + * Copyright (c) 2004-2009 AppGate Network Security AB
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +#include "includes.h"
    +
    +#include 
    +
    +#include "roaming.h"
    +
    +/*
    + * Wait for the roaming client to reconnect. Returns 0 if a connect ocurred.
    + */
    +int
    +wait_for_roaming_reconnect(void)
    +{
    +	return 1;
    +}
    diff --git a/crypto/openssh/scard-opensc.c b/crypto/openssh/scard-opensc.c
    deleted file mode 100644
    index 36dae05fd5a..00000000000
    --- a/crypto/openssh/scard-opensc.c
    +++ /dev/null
    @@ -1,532 +0,0 @@
    -/*
    - * Copyright (c) 2002 Juha Yrjölä.  All rights reserved.
    - * Copyright (c) 2001 Markus Friedl.
    - *
    - * Redistribution and use in source and binary forms, with or without
    - * modification, are permitted provided that the following conditions
    - * are met:
    - * 1. Redistributions of source code must retain the above copyright
    - *    notice, this list of conditions and the following disclaimer.
    - * 2. Redistributions in binary form must reproduce the above copyright
    - *    notice, this list of conditions and the following disclaimer in the
    - *    documentation and/or other materials provided with the distribution.
    - *
    - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    - */
    -
    -#include "includes.h"
    -#if defined(SMARTCARD) && defined(USE_OPENSC)
    -
    -#include 
    -
    -#include 
    -#include 
    -
    -#include 
    -#include 
    -
    -#include 
    -#include 
    -
    -#include "key.h"
    -#include "log.h"
    -#include "xmalloc.h"
    -#include "misc.h"
    -#include "scard.h"
    -
    -#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
    -#define USE_ENGINE
    -#define RSA_get_default_method RSA_get_default_openssl_method
    -#else
    -#endif
    -
    -#ifdef USE_ENGINE
    -#include 
    -#define sc_get_rsa sc_get_engine
    -#else
    -#define sc_get_rsa sc_get_rsa_method
    -#endif
    -
    -static int sc_reader_id;
    -static sc_context_t *ctx = NULL;
    -static sc_card_t *card = NULL;
    -static sc_pkcs15_card_t *p15card = NULL;
    -
    -static char *sc_pin = NULL;
    -
    -struct sc_priv_data
    -{
    -	struct sc_pkcs15_id cert_id;
    -	int ref_count;
    -};
    -
    -void
    -sc_close(void)
    -{
    -	if (p15card) {
    -		sc_pkcs15_unbind(p15card);
    -		p15card = NULL;
    -	}
    -	if (card) {
    -		sc_disconnect_card(card, 0);
    -		card = NULL;
    -	}
    -	if (ctx) {
    -		sc_release_context(ctx);
    -		ctx = NULL;
    -	}
    -}
    -
    -static int
    -sc_init(void)
    -{
    -	int r;
    -
    -	r = sc_establish_context(&ctx, "openssh");
    -	if (r)
    -		goto err;
    -	if (sc_reader_id >= ctx->reader_count) {
    -		r = SC_ERROR_NO_READERS_FOUND;
    -		error("Illegal reader number %d (max %d)", sc_reader_id,
    -		    ctx->reader_count -1);
    -		goto err;
    -	}
    -	r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card);
    -	if (r)
    -		goto err;
    -	r = sc_pkcs15_bind(card, &p15card);
    -	if (r)
    -		goto err;
    -	return 0;
    -err:
    -	sc_close();
    -	return r;
    -}
    -
    -/* private key operations */
    -
    -static int
    -sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out,
    -	unsigned int usage)
    -{
    -	int r;
    -	struct sc_priv_data *priv;
    -	struct sc_pkcs15_object *key_obj;
    -	struct sc_pkcs15_prkey_info *key;
    -	struct sc_pkcs15_object *pin_obj;
    -	struct sc_pkcs15_pin_info *pin;
    -
    -	priv = (struct sc_priv_data *) RSA_get_app_data(rsa);
    -	if (priv == NULL)
    -		return -1;
    -	if (p15card == NULL) {
    -		sc_close();
    -		r = sc_init();
    -		if (r) {
    -			error("SmartCard init failed: %s", sc_strerror(r));
    -			goto err;
    -		}
    -	}
    -	r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id,
    -		usage, &key_obj);
    -	if (r) {
    -		error("Unable to find private key from SmartCard: %s",
    -		      sc_strerror(r));
    -		goto err;
    -	}
    -	key = key_obj->data;
    -	r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id,
    -					  &pin_obj);
    -	if (r == SC_ERROR_OBJECT_NOT_FOUND) {
    -		/* no pin required */
    -		r = sc_lock(card);
    -		if (r) {
    -			error("Unable to lock smartcard: %s", sc_strerror(r));
    -			goto err;
    -		}
    -		*key_obj_out = key_obj;
    -		return 0;
    -	} else if (r) {
    -		error("Unable to find PIN object from SmartCard: %s",
    -		      sc_strerror(r));
    -		goto err;
    -	}
    -	pin = pin_obj->data;
    -	r = sc_lock(card);
    -	if (r) {
    -		error("Unable to lock smartcard: %s", sc_strerror(r));
    -		goto err;
    -	}
    -	if (sc_pin != NULL) {
    -		r = sc_pkcs15_verify_pin(p15card, pin, sc_pin,
    -					 strlen(sc_pin));
    -		if (r) {
    -			sc_unlock(card);
    -			error("PIN code verification failed: %s",
    -			      sc_strerror(r));
    -			goto err;
    -		}
    -	}
    -	*key_obj_out = key_obj;
    -	return 0;
    -err:
    -	sc_close();
    -	return -1;
    -}
    -
    -#define SC_USAGE_DECRYPT	SC_PKCS15_PRKEY_USAGE_DECRYPT | \
    -				SC_PKCS15_PRKEY_USAGE_UNWRAP
    -
    -static int
    -sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
    -    int padding)
    -{
    -	struct sc_pkcs15_object *key_obj;
    -	int r;
    -
    -	if (padding != RSA_PKCS1_PADDING)
    -		return -1;
    -	r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT);
    -	if (r)
    -		return -1;
    -	r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1,
    -	    from, flen, to, flen);
    -	sc_unlock(card);
    -	if (r < 0) {
    -		error("sc_pkcs15_decipher() failed: %s", sc_strerror(r));
    -		goto err;
    -	}
    -	return r;
    -err:
    -	sc_close();
    -	return -1;
    -}
    -
    -#define SC_USAGE_SIGN 		SC_PKCS15_PRKEY_USAGE_SIGN | \
    -				SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
    -
    -static int
    -sc_sign(int type, u_char *m, unsigned int m_len,
    -	unsigned char *sigret, unsigned int *siglen, RSA *rsa)
    -{
    -	struct sc_pkcs15_object *key_obj;
    -	int r;
    -	unsigned long flags = 0;
    -
    -	/* XXX: sc_prkey_op_init will search for a pkcs15 private
    -	 * key object with the sign or signrecover usage flag set.
    -	 * If the signing key has only the non-repudiation flag set
    -	 * the key will be rejected as using a non-repudiation key
    -	 * for authentication is not recommended. Note: This does not
    -	 * prevent the use of a non-repudiation key for authentication
    -	 * if the sign or signrecover flag is set as well.
    -	 */
    -	r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN);
    -	if (r)
    -		return -1;
    -	/* FIXME: length of sigret correct? */
    -	/* FIXME: check 'type' and modify flags accordingly */
    -	flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1;
    -	r = sc_pkcs15_compute_signature(p15card, key_obj, flags,
    -					m, m_len, sigret, RSA_size(rsa));
    -	sc_unlock(card);
    -	if (r < 0) {
    -		error("sc_pkcs15_compute_signature() failed: %s",
    -		      sc_strerror(r));
    -		goto err;
    -	}
    -	*siglen = r;
    -	return 1;
    -err:
    -	sc_close();
    -	return 0;
    -}
    -
    -static int
    -sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
    -    int padding)
    -{
    -	error("Private key encryption not supported");
    -	return -1;
    -}
    -
    -/* called on free */
    -
    -static int (*orig_finish)(RSA *rsa) = NULL;
    -
    -static int
    -sc_finish(RSA *rsa)
    -{
    -	struct sc_priv_data *priv;
    -
    -	priv = RSA_get_app_data(rsa);
    -	priv->ref_count--;
    -	if (priv->ref_count == 0) {
    -		free(priv);
    -		sc_close();
    -	}
    -	if (orig_finish)
    -		orig_finish(rsa);
    -	return 1;
    -}
    -
    -/* engine for overloading private key operations */
    -
    -static RSA_METHOD *
    -sc_get_rsa_method(void)
    -{
    -	static RSA_METHOD smart_rsa;
    -	const RSA_METHOD *def = RSA_get_default_method();
    -
    -	/* use the OpenSSL version */
    -	memcpy(&smart_rsa, def, sizeof(smart_rsa));
    -
    -	smart_rsa.name		= "opensc";
    -
    -	/* overload */
    -	smart_rsa.rsa_priv_enc	= sc_private_encrypt;
    -	smart_rsa.rsa_priv_dec	= sc_private_decrypt;
    -	smart_rsa.rsa_sign	= sc_sign;
    -
    -	/* save original */
    -	orig_finish		= def->finish;
    -	smart_rsa.finish	= sc_finish;
    -
    -	return &smart_rsa;
    -}
    -
    -#ifdef USE_ENGINE
    -static ENGINE *
    -sc_get_engine(void)
    -{
    -	static ENGINE *smart_engine = NULL;
    -
    -	if ((smart_engine = ENGINE_new()) == NULL)
    -		fatal("ENGINE_new failed");
    -
    -	ENGINE_set_id(smart_engine, "opensc");
    -	ENGINE_set_name(smart_engine, "OpenSC");
    -
    -	ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
    -	ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
    -	ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
    -	ENGINE_set_RAND(smart_engine, RAND_SSLeay());
    -	ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
    -
    -	return smart_engine;
    -}
    -#endif
    -
    -static void
    -convert_rsa_to_rsa1(Key * in, Key * out)
    -{
    -	struct sc_priv_data *priv;
    -
    -	out->rsa->flags = in->rsa->flags;
    -	out->flags = in->flags;
    -	RSA_set_method(out->rsa, RSA_get_method(in->rsa));
    -	BN_copy(out->rsa->n, in->rsa->n);
    -	BN_copy(out->rsa->e, in->rsa->e);
    -	priv = RSA_get_app_data(in->rsa);
    -	priv->ref_count++;
    -	RSA_set_app_data(out->rsa, priv);
    -	return;
    -}
    -
    -static int
    -sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
    -{
    -	int r;
    -	sc_pkcs15_cert_t *cert = NULL;
    -	struct sc_priv_data *priv = NULL;
    -	sc_pkcs15_cert_info_t *cinfo = cert_obj->data;
    -
    -	X509 *x509 = NULL;
    -	EVP_PKEY *pubkey = NULL;
    -	u8 *p;
    -	char *tmp;
    -
    -	debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]);
    -	r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
    -	if (r) {
    -		logit("Certificate read failed: %s", sc_strerror(r));
    -		goto err;
    -	}
    -	x509 = X509_new();
    -	if (x509 == NULL) {
    -		r = -1;
    -		goto err;
    -	}
    -	p = cert->data;
    -	if (!d2i_X509(&x509, &p, cert->data_len)) {
    -		logit("Unable to parse X.509 certificate");
    -		r = -1;
    -		goto err;
    -	}
    -	sc_pkcs15_free_certificate(cert);
    -	cert = NULL;
    -	pubkey = X509_get_pubkey(x509);
    -	X509_free(x509);
    -	x509 = NULL;
    -	if (pubkey->type != EVP_PKEY_RSA) {
    -		logit("Public key is of unknown type");
    -		r = -1;
    -		goto err;
    -	}
    -	k->rsa = EVP_PKEY_get1_RSA(pubkey);
    -	EVP_PKEY_free(pubkey);
    -
    -	k->rsa->flags |= RSA_FLAG_SIGN_VER;
    -	RSA_set_method(k->rsa, sc_get_rsa_method());
    -	priv = xmalloc(sizeof(struct sc_priv_data));
    -	priv->cert_id = cinfo->id;
    -	priv->ref_count = 1;
    -	RSA_set_app_data(k->rsa, priv);
    -
    -	k->flags = KEY_FLAG_EXT;
    -	tmp = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
    -	debug("fingerprint %d %s", key_size(k), tmp);
    -	xfree(tmp);
    -
    -	return 0;
    -err:
    -	if (cert)
    -		sc_pkcs15_free_certificate(cert);
    -	if (pubkey)
    -		EVP_PKEY_free(pubkey);
    -	if (x509)
    -		X509_free(x509);
    -	return r;
    -}
    -
    -Key **
    -sc_get_keys(const char *id, const char *pin)
    -{
    -	Key *k, **keys;
    -	int i, r, real_count = 0, key_count;
    -	sc_pkcs15_id_t cert_id;
    -	sc_pkcs15_object_t *certs[32];
    -	char *buf = xstrdup(id), *p;
    -
    -	debug("sc_get_keys called: id = %s", id);
    -
    -	if (sc_pin != NULL)
    -		xfree(sc_pin);
    -	sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
    -
    -	cert_id.len = 0;
    -	if ((p = strchr(buf, ':')) != NULL) {
    -		*p = 0;
    -		p++;
    -		sc_pkcs15_hex_string_to_id(p, &cert_id);
    -	}
    -	r = sscanf(buf, "%d", &sc_reader_id);
    -	xfree(buf);
    -	if (r != 1)
    -		goto err;
    -	if (p15card == NULL) {
    -		sc_close();
    -		r = sc_init();
    -		if (r) {
    -			error("Smartcard init failed: %s", sc_strerror(r));
    -			goto err;
    -		}
    -	}
    -	if (cert_id.len) {
    -		r = sc_pkcs15_find_cert_by_id(p15card, &cert_id, &certs[0]);
    -		if (r < 0)
    -			goto err;
    -		key_count = 1;
    -	} else {
    -		r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509,
    -					  certs, 32);
    -		if (r == 0) {
    -			logit("No certificates found on smartcard");
    -			r = -1;
    -			goto err;
    -		} else if (r < 0) {
    -			error("Certificate enumeration failed: %s",
    -			      sc_strerror(r));
    -			goto err;
    -		}
    -		key_count = r;
    -	}
    -	if (key_count > 1024)
    -		fatal("Too many keys (%u), expected <= 1024", key_count);
    -	keys = xcalloc(key_count * 2 + 1, sizeof(Key *));
    -	for (i = 0; i < key_count; i++) {
    -		sc_pkcs15_object_t *tmp_obj = NULL;
    -		cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id;
    -		if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj))
    -			/* skip the public key (certificate) if no
    -			 * corresponding private key is present */
    -			continue;
    -		k = key_new(KEY_RSA);
    -		if (k == NULL)
    -			break;
    -		r = sc_read_pubkey(k, certs[i]);
    -		if (r) {
    -			error("sc_read_pubkey failed: %s", sc_strerror(r));
    -			key_free(k);
    -			continue;
    -		}
    -		keys[real_count] = k;
    -		real_count++;
    -		k = key_new(KEY_RSA1);
    -		if (k == NULL)
    -			break;
    -		convert_rsa_to_rsa1(keys[real_count-1], k);
    -		keys[real_count] = k;
    -		real_count++;
    -	}
    -	keys[real_count] = NULL;
    -
    -	return keys;
    -err:
    -	sc_close();
    -	return NULL;
    -}
    -
    -int
    -sc_put_key(Key *prv, const char *id)
    -{
    -	error("key uploading not yet supported");
    -	return -1;
    -}
    -
    -char *
    -sc_get_key_label(Key *key)
    -{
    -	int r;
    -	const struct sc_priv_data *priv;
    -	struct sc_pkcs15_object *key_obj;
    -
    -	priv = (const struct sc_priv_data *) RSA_get_app_data(key->rsa);
    -	if (priv == NULL || p15card == NULL) {
    -		logit("SmartCard key not loaded");
    -		/* internal error => return default label */
    -		return xstrdup("smartcard key");
    -	}
    -	r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj);
    -	if (r) {
    -		logit("Unable to find private key from SmartCard: %s",
    -		      sc_strerror(r));
    -		return xstrdup("smartcard key");
    -	}
    -	if (key_obj == NULL || key_obj->label == NULL)
    -		/* the optional PKCS#15 label does not exists
    -		 * => return the default label */
    -		return xstrdup("smartcard key");
    -	return xstrdup(key_obj->label);
    -}
    -
    -#endif /* SMARTCARD */
    diff --git a/crypto/openssh/scard.c b/crypto/openssh/scard.c
    deleted file mode 100644
    index 9fd3ca1b4ee..00000000000
    --- a/crypto/openssh/scard.c
    +++ /dev/null
    @@ -1,571 +0,0 @@
    -/* $OpenBSD: scard.c,v 1.36 2006/11/06 21:25:28 markus Exp $ */
    -/*
    - * Copyright (c) 2001 Markus Friedl.  All rights reserved.
    - *
    - * Redistribution and use in source and binary forms, with or without
    - * modification, are permitted provided that the following conditions
    - * are met:
    - * 1. Redistributions of source code must retain the above copyright
    - *    notice, this list of conditions and the following disclaimer.
    - * 2. Redistributions in binary form must reproduce the above copyright
    - *    notice, this list of conditions and the following disclaimer in the
    - *    documentation and/or other materials provided with the distribution.
    - *
    - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    - */
    -
    -#include "includes.h"
    -#if defined(SMARTCARD) && defined(USE_SECTOK)
    -
    -#include 
    -
    -#include 
    -#include 
    -#include 
    -
    -#include 
    -
    -#include "xmalloc.h"
    -#include "key.h"
    -#include "log.h"
    -#include "misc.h"
    -#include "scard.h"
    -
    -#if OPENSSL_VERSION_NUMBER < 0x00907000L
    -#define USE_ENGINE
    -#define RSA_get_default_method RSA_get_default_openssl_method
    -#else
    -#endif
    -
    -#ifdef USE_ENGINE
    -#include 
    -#define sc_get_rsa sc_get_engine
    -#else
    -#define sc_get_rsa sc_get_rsa_method
    -#endif
    -
    -#define CLA_SSH 0x05
    -#define INS_DECRYPT 0x10
    -#define INS_GET_KEYLENGTH 0x20
    -#define INS_GET_PUBKEY 0x30
    -#define INS_GET_RESPONSE 0xc0
    -
    -#define MAX_BUF_SIZE 256
    -
    -u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
    -
    -static int sc_fd = -1;
    -static char *sc_reader_id = NULL;
    -static char *sc_pin = NULL;
    -static int cla = 0x00;	/* class */
    -
    -static void sc_mk_digest(const char *pin, u_char *digest);
    -static int get_AUT0(u_char *aut0);
    -static int try_AUT0(void);
    -
    -/* interface to libsectok */
    -
    -static int
    -sc_open(void)
    -{
    -	int sw;
    -
    -	if (sc_fd >= 0)
    -		return sc_fd;
    -
    -	sc_fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
    -	if (sc_fd < 0) {
    -		error("sectok_open failed: %s", sectok_get_sw(sw));
    -		return SCARD_ERROR_FAIL;
    -	}
    -	if (! sectok_cardpresent(sc_fd)) {
    -		debug("smartcard in reader %s not present, skipping",
    -		    sc_reader_id);
    -		sc_close();
    -		return SCARD_ERROR_NOCARD;
    -	}
    -	if (sectok_reset(sc_fd, 0, NULL, &sw) <= 0) {
    -		error("sectok_reset failed: %s", sectok_get_sw(sw));
    -		sc_fd = -1;
    -		return SCARD_ERROR_FAIL;
    -	}
    -	if ((cla = cyberflex_inq_class(sc_fd)) < 0)
    -		cla = 0;
    -
    -	debug("sc_open ok %d", sc_fd);
    -	return sc_fd;
    -}
    -
    -static int
    -sc_enable_applet(void)
    -{
    -	static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e};
    -	int sw = 0;
    -
    -	/* select applet id */
    -	sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, sizeof aid, aid, 0, NULL, &sw);
    -	if (!sectok_swOK(sw)) {
    -		error("sectok_apdu failed: %s", sectok_get_sw(sw));
    -		sc_close();
    -		return -1;
    -	}
    -	return 0;
    -}
    -
    -static int
    -sc_init(void)
    -{
    -	int status;
    -
    -	status = sc_open();
    -	if (status == SCARD_ERROR_NOCARD) {
    -		return SCARD_ERROR_NOCARD;
    -	}
    -	if (status < 0) {
    -		error("sc_open failed");
    -		return status;
    -	}
    -	if (sc_enable_applet() < 0) {
    -		error("sc_enable_applet failed");
    -		return SCARD_ERROR_APPLET;
    -	}
    -	return 0;
    -}
    -
    -static int
    -sc_read_pubkey(Key * k)
    -{
    -	u_char buf[2], *n;
    -	char *p;
    -	int len, sw, status = -1;
    -
    -	len = sw = 0;
    -	n = NULL;
    -
    -	if (sc_fd < 0) {
    -		if (sc_init() < 0)
    -			goto err;
    -	}
    -
    -	/* get key size */
    -	sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
    -	    sizeof(buf), buf, &sw);
    -	if (!sectok_swOK(sw)) {
    -		error("could not obtain key length: %s", sectok_get_sw(sw));
    -		goto err;
    -	}
    -	len = (buf[0] << 8) | buf[1];
    -	len /= 8;
    -	debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw));
    -
    -	n = xmalloc(len);
    -	/* get n */
    -	sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
    -
    -	if (sw == 0x6982) {
    -		if (try_AUT0() < 0)
    -			goto err;
    -		sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
    -	}
    -	if (!sectok_swOK(sw)) {
    -		error("could not obtain public key: %s", sectok_get_sw(sw));
    -		goto err;
    -	}
    -
    -	debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw));
    -
    -	if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
    -		error("c_read_pubkey: BN_bin2bn failed");
    -		goto err;
    -	}
    -
    -	/* currently the java applet just stores 'n' */
    -	if (!BN_set_word(k->rsa->e, 35)) {
    -		error("c_read_pubkey: BN_set_word(e, 35) failed");
    -		goto err;
    -	}
    -
    -	status = 0;
    -	p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
    -	debug("fingerprint %u %s", key_size(k), p);
    -	xfree(p);
    -
    -err:
    -	if (n != NULL)
    -		xfree(n);
    -	sc_close();
    -	return status;
    -}
    -
    -/* private key operations */
    -
    -static int
    -sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
    -    int padding)
    -{
    -	u_char *padded = NULL;
    -	int sw, len, olen, status = -1;
    -
    -	debug("sc_private_decrypt called");
    -
    -	olen = len = sw = 0;
    -	if (sc_fd < 0) {
    -		status = sc_init();
    -		if (status < 0)
    -			goto err;
    -	}
    -	if (padding != RSA_PKCS1_PADDING)
    -		goto err;
    -
    -	len = BN_num_bytes(rsa->n);
    -	padded = xmalloc(len);
    -
    -	sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
    -
    -	if (sw == 0x6982) {
    -		if (try_AUT0() < 0)
    -			goto err;
    -		sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
    -	}
    -	if (!sectok_swOK(sw)) {
    -		error("sc_private_decrypt: INS_DECRYPT failed: %s",
    -		    sectok_get_sw(sw));
    -		goto err;
    -	}
    -	olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
    -	    len);
    -err:
    -	if (padded)
    -		xfree(padded);
    -	sc_close();
    -	return (olen >= 0 ? olen : status);
    -}
    -
    -static int
    -sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
    -    int padding)
    -{
    -	u_char *padded = NULL;
    -	int sw, len, status = -1;
    -
    -	len = sw = 0;
    -	if (sc_fd < 0) {
    -		status = sc_init();
    -		if (status < 0)
    -			goto err;
    -	}
    -	if (padding != RSA_PKCS1_PADDING)
    -		goto err;
    -
    -	debug("sc_private_encrypt called");
    -	len = BN_num_bytes(rsa->n);
    -	padded = xmalloc(len);
    -
    -	if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) {
    -		error("RSA_padding_add_PKCS1_type_1 failed");
    -		goto err;
    -	}
    -	sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
    -	if (sw == 0x6982) {
    -		if (try_AUT0() < 0)
    -			goto err;
    -		sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
    -	}
    -	if (!sectok_swOK(sw)) {
    -		error("sc_private_encrypt: INS_DECRYPT failed: %s",
    -		    sectok_get_sw(sw));
    -		goto err;
    -	}
    -err:
    -	if (padded)
    -		xfree(padded);
    -	sc_close();
    -	return (len >= 0 ? len : status);
    -}
    -
    -/* called on free */
    -
    -static int (*orig_finish)(RSA *rsa) = NULL;
    -
    -static int
    -sc_finish(RSA *rsa)
    -{
    -	if (orig_finish)
    -		orig_finish(rsa);
    -	sc_close();
    -	return 1;
    -}
    -
    -/* engine for overloading private key operations */
    -
    -static RSA_METHOD *
    -sc_get_rsa_method(void)
    -{
    -	static RSA_METHOD smart_rsa;
    -	const RSA_METHOD *def = RSA_get_default_method();
    -
    -	/* use the OpenSSL version */
    -	memcpy(&smart_rsa, def, sizeof(smart_rsa));
    -
    -	smart_rsa.name		= "sectok";
    -
    -	/* overload */
    -	smart_rsa.rsa_priv_enc	= sc_private_encrypt;
    -	smart_rsa.rsa_priv_dec	= sc_private_decrypt;
    -
    -	/* save original */
    -	orig_finish		= def->finish;
    -	smart_rsa.finish	= sc_finish;
    -
    -	return &smart_rsa;
    -}
    -
    -#ifdef USE_ENGINE
    -static ENGINE *
    -sc_get_engine(void)
    -{
    -	static ENGINE *smart_engine = NULL;
    -
    -	if ((smart_engine = ENGINE_new()) == NULL)
    -		fatal("ENGINE_new failed");
    -
    -	ENGINE_set_id(smart_engine, "sectok");
    -	ENGINE_set_name(smart_engine, "libsectok");
    -
    -	ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
    -	ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
    -	ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
    -	ENGINE_set_RAND(smart_engine, RAND_SSLeay());
    -	ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
    -
    -	return smart_engine;
    -}
    -#endif
    -
    -void
    -sc_close(void)
    -{
    -	if (sc_fd >= 0) {
    -		sectok_close(sc_fd);
    -		sc_fd = -1;
    -	}
    -}
    -
    -Key **
    -sc_get_keys(const char *id, const char *pin)
    -{
    -	Key *k, *n, **keys;
    -	int status, nkeys = 2;
    -
    -	if (sc_reader_id != NULL)
    -		xfree(sc_reader_id);
    -	sc_reader_id = xstrdup(id);
    -
    -	if (sc_pin != NULL)
    -		xfree(sc_pin);
    -	sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
    -
    -	k = key_new(KEY_RSA);
    -	if (k == NULL) {
    -		return NULL;
    -	}
    -	status = sc_read_pubkey(k);
    -	if (status == SCARD_ERROR_NOCARD) {
    -		key_free(k);
    -		return NULL;
    -	}
    -	if (status < 0) {
    -		error("sc_read_pubkey failed");
    -		key_free(k);
    -		return NULL;
    -	}
    -	keys = xcalloc((nkeys+1), sizeof(Key *));
    -
    -	n = key_new(KEY_RSA1);
    -	if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
    -	    (BN_copy(n->rsa->e, k->rsa->e) == NULL))
    -		fatal("sc_get_keys: BN_copy failed");
    -	RSA_set_method(n->rsa, sc_get_rsa());
    -	n->flags |= KEY_FLAG_EXT;
    -	keys[0] = n;
    -
    -	n = key_new(KEY_RSA);
    -	if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
    -	    (BN_copy(n->rsa->e, k->rsa->e) == NULL))
    -		fatal("sc_get_keys: BN_copy failed");
    -	RSA_set_method(n->rsa, sc_get_rsa());
    -	n->flags |= KEY_FLAG_EXT;
    -	keys[1] = n;
    -
    -	keys[2] = NULL;
    -
    -	key_free(k);
    -	return keys;
    -}
    -
    -#define NUM_RSA_KEY_ELEMENTS 5+1
    -#define COPY_RSA_KEY(x, i) \
    -	do { \
    -		len = BN_num_bytes(prv->rsa->x); \
    -		elements[i] = xmalloc(len); \
    -		debug("#bytes %d", len); \
    -		if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
    -			goto done; \
    -	} while (0)
    -
    -static void
    -sc_mk_digest(const char *pin, u_char *digest)
    -{
    -	const EVP_MD *evp_md = EVP_sha1();
    -	EVP_MD_CTX md;
    -
    -	EVP_DigestInit(&md, evp_md);
    -	EVP_DigestUpdate(&md, pin, strlen(pin));
    -	EVP_DigestFinal(&md, digest, NULL);
    -}
    -
    -static int
    -get_AUT0(u_char *aut0)
    -{
    -	char *pass;
    -
    -	pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
    -	if (pass == NULL)
    -		return -1;
    -	if (!strcmp(pass, "-")) {
    -		memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
    -		return 0;
    -	}
    -	sc_mk_digest(pass, aut0);
    -	memset(pass, 0, strlen(pass));
    -	xfree(pass);
    -	return 0;
    -}
    -
    -static int
    -try_AUT0(void)
    -{
    -	u_char aut0[EVP_MAX_MD_SIZE];
    -
    -	/* permission denied; try PIN if provided */
    -	if (sc_pin && strlen(sc_pin) > 0) {
    -		sc_mk_digest(sc_pin, aut0);
    -		if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
    -			error("smartcard passphrase incorrect");
    -			return (-1);
    -		}
    -	} else {
    -		/* try default AUT0 key */
    -		if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
    -			/* default AUT0 key failed; prompt for passphrase */
    -			if (get_AUT0(aut0) < 0 ||
    -			    cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
    -				error("smartcard passphrase incorrect");
    -				return (-1);
    -			}
    -		}
    -	}
    -	return (0);
    -}
    -
    -int
    -sc_put_key(Key *prv, const char *id)
    -{
    -	u_char *elements[NUM_RSA_KEY_ELEMENTS];
    -	u_char key_fid[2];
    -	u_char AUT0[EVP_MAX_MD_SIZE];
    -	int len, status = -1, i, fd = -1, ret;
    -	int sw = 0, cla = 0x00;
    -
    -	for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
    -		elements[i] = NULL;
    -
    -	COPY_RSA_KEY(q, 0);
    -	COPY_RSA_KEY(p, 1);
    -	COPY_RSA_KEY(iqmp, 2);
    -	COPY_RSA_KEY(dmq1, 3);
    -	COPY_RSA_KEY(dmp1, 4);
    -	COPY_RSA_KEY(n, 5);
    -	len = BN_num_bytes(prv->rsa->n);
    -	fd = sectok_friendly_open(id, STONOWAIT, &sw);
    -	if (fd < 0) {
    -		error("sectok_open failed: %s", sectok_get_sw(sw));
    -		goto done;
    -	}
    -	if (! sectok_cardpresent(fd)) {
    -		error("smartcard in reader %s not present", id);
    -		goto done;
    -	}
    -	ret = sectok_reset(fd, 0, NULL, &sw);
    -	if (ret <= 0) {
    -		error("sectok_reset failed: %s", sectok_get_sw(sw));
    -		goto done;
    -	}
    -	if ((cla = cyberflex_inq_class(fd)) < 0) {
    -		error("cyberflex_inq_class failed");
    -		goto done;
    -	}
    -	memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
    -	if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
    -		if (get_AUT0(AUT0) < 0 ||
    -		    cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
    -			memset(AUT0, 0, sizeof(DEFAUT0));
    -			error("smartcard passphrase incorrect");
    -			goto done;
    -		}
    -	}
    -	memset(AUT0, 0, sizeof(DEFAUT0));
    -	key_fid[0] = 0x00;
    -	key_fid[1] = 0x12;
    -	if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
    -	    &sw) < 0) {
    -		error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
    -		goto done;
    -	}
    -	if (!sectok_swOK(sw))
    -		goto done;
    -	logit("cyberflex_load_rsa_priv done");
    -	key_fid[0] = 0x73;
    -	key_fid[1] = 0x68;
    -	if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
    -	    &sw) < 0) {
    -		error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
    -		goto done;
    -	}
    -	if (!sectok_swOK(sw))
    -		goto done;
    -	logit("cyberflex_load_rsa_pub done");
    -	status = 0;
    -
    -done:
    -	memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
    -	memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
    -	memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
    -	memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
    -	memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
    -	memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
    -
    -	for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
    -		if (elements[i])
    -			xfree(elements[i]);
    -	if (fd != -1)
    -		sectok_close(fd);
    -	return (status);
    -}
    -
    -char *
    -sc_get_key_label(Key *key)
    -{
    -	return xstrdup("smartcard key");
    -}
    -
    -#endif /* SMARTCARD && USE_SECTOK */
    diff --git a/crypto/openssh/scard.h b/crypto/openssh/scard.h
    deleted file mode 100644
    index 82efe483922..00000000000
    --- a/crypto/openssh/scard.h
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -/* $OpenBSD: scard.h,v 1.14 2006/08/03 03:34:42 deraadt Exp $ */
    -
    -/*
    - * Copyright (c) 2001 Markus Friedl.  All rights reserved.
    - *
    - * Redistribution and use in source and binary forms, with or without
    - * modification, are permitted provided that the following conditions
    - * are met:
    - * 1. Redistributions of source code must retain the above copyright
    - *    notice, this list of conditions and the following disclaimer.
    - * 2. Redistributions in binary form must reproduce the above copyright
    - *    notice, this list of conditions and the following disclaimer in the
    - *    documentation and/or other materials provided with the distribution.
    - *
    - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    - */
    -
    -#ifndef SCARD_H
    -#define SCARD_H
    -
    -#define SCARD_ERROR_FAIL	-1
    -#define SCARD_ERROR_NOCARD	-2
    -#define SCARD_ERROR_APPLET	-3
    -
    -Key	**sc_get_keys(const char *, const char *);
    -void	 sc_close(void);
    -int	 sc_put_key(Key *, const char *);
    -char	*sc_get_key_label(Key *);
    -
    -#endif
    diff --git a/crypto/openssh/schnorr.c b/crypto/openssh/schnorr.c
    index 61ba68a73b7..daeec0627a3 100644
    --- a/crypto/openssh/schnorr.c
    +++ b/crypto/openssh/schnorr.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: schnorr.c,v 1.2 2009/02/18 04:31:21 djm Exp $ */
    +/* $OpenBSD: schnorr.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
     /* $FreeBSD$ */
     /*
      * Copyright (c) 2008 Damien Miller.  All rights reserved.
    @@ -41,38 +41,36 @@
     #include "buffer.h"
     #include "log.h"
     
    -#include "jpake.h"
    +#include "schnorr.h"
     
     #ifdef JPAKE
     
    +#include "openbsd-compat/openssl-compat.h"
    +
     /* #define SCHNORR_DEBUG */		/* Privacy-violating debugging */
     /* #define SCHNORR_MAIN */		/* Include main() selftest */
     
    -/* XXX */
    -/* Parametise signature hash? (sha256, sha1, etc.) */
    -/* Signature format - include type name, hash type, group params? */
    -
     #ifndef SCHNORR_DEBUG
     # define SCHNORR_DEBUG_BN(a)
     # define SCHNORR_DEBUG_BUF(a)
     #else
    -# define SCHNORR_DEBUG_BN(a)	jpake_debug3_bn a
    -# define SCHNORR_DEBUG_BUF(a)	jpake_debug3_buf a
    +# define SCHNORR_DEBUG_BN(a)	debug3_bn a
    +# define SCHNORR_DEBUG_BUF(a)	debug3_buf a
     #endif /* SCHNORR_DEBUG */
     
     /*
      * Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
    - * using SHA1. Returns signature as bignum or NULL on error.
    + * using the hash function defined by "evp_md". Returns signature as
    + * bignum or NULL on error.
      */
     static BIGNUM *
     schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
    -    const BIGNUM *g_v, const BIGNUM *g_x,
    +    const EVP_MD *evp_md, const BIGNUM *g_v, const BIGNUM *g_x,
         const u_char *id, u_int idlen)
     {
     	u_char *digest;
     	u_int digest_len;
     	BIGNUM *h;
    -	EVP_MD_CTX evp_md_ctx;
     	Buffer b;
     	int success = -1;
     
    @@ -82,7 +80,6 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
     	}
     
     	buffer_init(&b);
    -	EVP_MD_CTX_init(&evp_md_ctx);
     
     	/* h = H(g || p || q || g^v || g^x || id) */
     	buffer_put_bignum2(&b, g);
    @@ -94,7 +91,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
     
     	SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
     	    "%s: hashblob", __func__));
    -	if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
    +	if (hash_buffer(buffer_ptr(&b), buffer_len(&b), evp_md,
     	    &digest, &digest_len) != 0) {
     		error("%s: hash_buffer", __func__);
     		goto out;
    @@ -107,7 +104,6 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
     	SCHNORR_DEBUG_BN((h, "%s: h = ", __func__));
      out:
     	buffer_free(&b);
    -	EVP_MD_CTX_cleanup(&evp_md_ctx);
     	bzero(digest, digest_len);
     	xfree(digest);
     	digest_len = 0;
    @@ -120,18 +116,20 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
     /*
      * Generate Schnorr signature to prove knowledge of private value 'x' used
      * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
    + * using the hash function "evp_md".
      * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
      * replay salt.
    - * On success, 0 is returned and *siglen bytes of signature are returned in
    - * *sig (caller to free). Returns -1 on failure.
    + * 
    + * On success, 0 is returned. The signature values are returned as *e_p
    + * (g^v mod p) and *r_p (v - xh mod q). The caller must free these values.
    + * On failure, -1 is returned.
      */
     int
     schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
    -    const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
    -    u_char **sig, u_int *siglen)
    +    const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x,
    +    const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p)
     {
     	int success = -1;
    -	Buffer b;
     	BIGNUM *h, *tmp, *v, *g_v, *r;
     	BN_CTX *bn_ctx;
     
    @@ -174,7 +172,7 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
     	SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
     
     	/* h = H(g || g^v || g^x || id) */
    -	if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
    +	if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, g_v, g_x,
     	    id, idlen)) == NULL) {
     		error("%s: schnorr_hash failed", __func__);
     		goto out;
    @@ -189,19 +187,12 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
     		error("%s: BN_mod_mul (r = v - tmp)", __func__);
     		goto out;
     	}
    +	SCHNORR_DEBUG_BN((g_v, "%s: e = ", __func__));
     	SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
     
    -	/* Signature is (g_v, r) */
    -	buffer_init(&b);
    -	/* XXX sigtype-hash as string? */
    -	buffer_put_bignum2(&b, g_v);
    -	buffer_put_bignum2(&b, r);
    -	*siglen = buffer_len(&b);
    -	*sig = xmalloc(*siglen);
    -	memcpy(*sig, buffer_ptr(&b), *siglen);
    -	SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
    -	    "%s: sigblob", __func__));
    -	buffer_free(&b);
    +	*e_p = g_v;
    +	*r_p = r;
    +
     	success = 0;
      out:
     	BN_CTX_free(bn_ctx);
    @@ -209,29 +200,65 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
     		BN_clear_free(h);
     	if (v != NULL)
     		BN_clear_free(v);
    -	BN_clear_free(r);
    -	BN_clear_free(g_v);
     	BN_clear_free(tmp);
     
     	return success;
     }
     
     /*
    - * Verify Schnorr signature 'sig' of length 'siglen' against public exponent
    - * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g'.
    + * Generate Schnorr signature to prove knowledge of private value 'x' used
    + * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
    + * using a SHA256 hash.
    + * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
    + * replay salt.
    + * On success, 0 is returned and *siglen bytes of signature are returned in
    + * *sig (caller to free). Returns -1 on failure.
    + */
    +int
    +schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
    +    const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
    +    u_char **sig, u_int *siglen)
    +{
    +	Buffer b;
    +	BIGNUM *r, *e;
    +
    +	if (schnorr_sign(grp_p, grp_q, grp_g, EVP_sha256(),
    +	    x, g_x, id, idlen, &r, &e) != 0)
    +		return -1;
    +
    +	/* Signature is (e, r) */
    +	buffer_init(&b);
    +	/* XXX sigtype-hash as string? */
    +	buffer_put_bignum2(&b, e);
    +	buffer_put_bignum2(&b, r);
    +	*siglen = buffer_len(&b);
    +	*sig = xmalloc(*siglen);
    +	memcpy(*sig, buffer_ptr(&b), *siglen);
    +	SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
    +	    "%s: sigblob", __func__));
    +	buffer_free(&b);
    +
    +	BN_clear_free(r);
    +	BN_clear_free(e);
    +
    +	return 0;
    +}
    +
    +/*
    + * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against
    + * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and
    + * 'grp_g' using hash "evp_md".
      * Signature hash will be salted with 'idlen' bytes from 'id'.
      * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
      */
     int
     schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
    -    const BIGNUM *g_x, const u_char *id, u_int idlen,
    -    const u_char *sig, u_int siglen)
    +    const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen,
    +    const BIGNUM *r, const BIGNUM *e)
     {
     	int success = -1;
    -	Buffer b;
    -	BIGNUM *g_v, *h, *r, *g_xh, *g_r, *expected;
    +	BIGNUM *h, *g_xh, *g_r, *expected;
     	BN_CTX *bn_ctx;
    -	u_int rlen;
     
     	SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
     
    @@ -241,39 +268,23 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
     		return -1;
     	}
     
    -	g_v = h = r = g_xh = g_r = expected = NULL;
    +	h = g_xh = g_r = expected = NULL;
     	if ((bn_ctx = BN_CTX_new()) == NULL) {
     		error("%s: BN_CTX_new", __func__);
     		goto out;
     	}
    -	if ((g_v = BN_new()) == NULL ||
    -	    (r = BN_new()) == NULL ||
    -	    (g_xh = BN_new()) == NULL ||
    +	if ((g_xh = BN_new()) == NULL ||
     	    (g_r = BN_new()) == NULL ||
     	    (expected = BN_new()) == NULL) {
     		error("%s: BN_new", __func__);
     		goto out;
     	}
     
    -	/* Extract g^v and r from signature blob */
    -	buffer_init(&b);
    -	buffer_append(&b, sig, siglen);
    -	SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
    -	    "%s: sigblob", __func__));
    -	buffer_get_bignum2(&b, g_v);
    -	buffer_get_bignum2(&b, r);
    -	rlen = buffer_len(&b);
    -	buffer_free(&b);
    -	if (rlen != 0) {
    -		error("%s: remaining bytes in signature %d", __func__, rlen);
    -		goto out;
    -	}
    -	buffer_free(&b);
    -	SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
    +	SCHNORR_DEBUG_BN((e, "%s: e = ", __func__));
     	SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
     
     	/* h = H(g || g^v || g^x || id) */
    -	if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
    +	if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x,
     	    id, idlen)) == NULL) {
     		error("%s: schnorr_hash failed", __func__);
     		goto out;
    @@ -300,20 +311,248 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
     	}
     	SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__));
     
    -	/* Check g_v == expected */
    -	success = BN_cmp(expected, g_v) == 0;
    +	/* Check e == expected */
    +	success = BN_cmp(expected, e) == 0;
      out:
     	BN_CTX_free(bn_ctx);
     	if (h != NULL)
     		BN_clear_free(h);
    -	BN_clear_free(g_v);
    -	BN_clear_free(r);
     	BN_clear_free(g_xh);
     	BN_clear_free(g_r);
     	BN_clear_free(expected);
     	return success;
     }
     
    +/*
    + * Verify Schnorr signature 'sig' of length 'siglen' against public exponent
    + * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g' using a
    + * SHA256 hash.
    + * Signature hash will be salted with 'idlen' bytes from 'id'.
    + * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
    + */
    +int
    +schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
    +    const BIGNUM *grp_g,
    +    const BIGNUM *g_x, const u_char *id, u_int idlen,
    +    const u_char *sig, u_int siglen)
    +{
    +	Buffer b;
    +	int ret = -1;
    +	u_int rlen;
    +	BIGNUM *r, *e;
    +
    +	e = r = NULL;
    +	if ((e = BN_new()) == NULL ||
    +	    (r = BN_new()) == NULL) {
    +		error("%s: BN_new", __func__);
    +		goto out;
    +	}
    +
    +	/* Extract g^v and r from signature blob */
    +	buffer_init(&b);
    +	buffer_append(&b, sig, siglen);
    +	SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
    +	    "%s: sigblob", __func__));
    +	buffer_get_bignum2(&b, e);
    +	buffer_get_bignum2(&b, r);
    +	rlen = buffer_len(&b);
    +	buffer_free(&b);
    +	if (rlen != 0) {
    +		error("%s: remaining bytes in signature %d", __func__, rlen);
    +		goto out;
    +	}
    +
    +	ret = schnorr_verify(grp_p, grp_q, grp_g, EVP_sha256(),
    +	    g_x, id, idlen, r, e);
    + out:
    +	BN_clear_free(e);
    +	BN_clear_free(r);
    +
    +	return ret;
    +}
    +
    +/* Helper functions */
    +
    +/*
    + * Generate uniformly distributed random number in range (1, high).
    + * Return number on success, NULL on failure.
    + */
    +BIGNUM *
    +bn_rand_range_gt_one(const BIGNUM *high)
    +{
    +	BIGNUM *r, *tmp;
    +	int success = -1;
    +
    +	if ((tmp = BN_new()) == NULL) {
    +		error("%s: BN_new", __func__);
    +		return NULL;
    +	}
    +	if ((r = BN_new()) == NULL) {
    +		error("%s: BN_new failed", __func__);
    +		goto out;
    +	}
    +	if (BN_set_word(tmp, 2) != 1) {
    +		error("%s: BN_set_word(tmp, 2)", __func__);
    +		goto out;
    +	}
    +	if (BN_sub(tmp, high, tmp) == -1) {
    +		error("%s: BN_sub failed (tmp = high - 2)", __func__);
    +		goto out;
    +	}
    +	if (BN_rand_range(r, tmp) == -1) {
    +		error("%s: BN_rand_range failed", __func__);
    +		goto out;
    +	}
    +	if (BN_set_word(tmp, 2) != 1) {
    +		error("%s: BN_set_word(tmp, 2)", __func__);
    +		goto out;
    +	}
    +	if (BN_add(r, r, tmp) == -1) {
    +		error("%s: BN_add failed (r = r + 2)", __func__);
    +		goto out;
    +	}
    +	success = 0;
    + out:
    +	BN_clear_free(tmp);
    +	if (success == 0)
    +		return r;
    +	BN_clear_free(r);
    +	return NULL;
    +}
    +
    +/*
    + * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
    + * with digest via 'digestp' (caller to free) and length via 'lenp'.
    + * Returns -1 on failure.
    + */
    +int
    +hash_buffer(const u_char *buf, u_int len, const EVP_MD *md,
    +    u_char **digestp, u_int *lenp)
    +{
    +	u_char digest[EVP_MAX_MD_SIZE];
    +	u_int digest_len;
    +	EVP_MD_CTX evp_md_ctx;
    +	int success = -1;
    +
    +	EVP_MD_CTX_init(&evp_md_ctx);
    +
    +	if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) {
    +		error("%s: EVP_DigestInit_ex", __func__);
    +		goto out;
    +	}
    +	if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
    +		error("%s: EVP_DigestUpdate", __func__);
    +		goto out;
    +	}
    +	if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) {
    +		error("%s: EVP_DigestFinal_ex", __func__);
    +		goto out;
    +	}
    +	*digestp = xmalloc(digest_len);
    +	*lenp = digest_len;
    +	memcpy(*digestp, digest, *lenp);
    +	success = 0;
    + out:
    +	EVP_MD_CTX_cleanup(&evp_md_ctx);
    +	bzero(digest, sizeof(digest));
    +	digest_len = 0;
    +	return success;
    +}
    +
    +/* print formatted string followed by bignum */
    +void
    +debug3_bn(const BIGNUM *n, const char *fmt, ...)
    +{
    +	char *out, *h;
    +	va_list args;
    +
    +	out = NULL;
    +	va_start(args, fmt);
    +	vasprintf(&out, fmt, args);
    +	va_end(args);
    +	if (out == NULL)
    +		fatal("%s: vasprintf failed", __func__);
    +
    +	if (n == NULL)
    +		debug3("%s(null)", out);
    +	else {
    +		h = BN_bn2hex(n);
    +		debug3("%s0x%s", out, h);
    +		free(h);
    +	}
    +	free(out);
    +}
    +
    +/* print formatted string followed by buffer contents in hex */
    +void
    +debug3_buf(const u_char *buf, u_int len, const char *fmt, ...)
    +{
    +	char *out, h[65];
    +	u_int i, j;
    +	va_list args;
    +
    +	out = NULL;
    +	va_start(args, fmt);
    +	vasprintf(&out, fmt, args);
    +	va_end(args);
    +	if (out == NULL)
    +		fatal("%s: vasprintf failed", __func__);
    +
    +	debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : "");
    +	free(out);
    +	if (buf == NULL)
    +		return;
    +
    +	*h = '\0';
    +	for (i = j = 0; i < len; i++) {
    +		snprintf(h + j, sizeof(h) - j, "%02x", buf[i]);
    +		j += 2;
    +		if (j >= sizeof(h) - 1 || i == len - 1) {
    +			debug3("    %s", h);
    +			*h = '\0';
    +			j = 0;
    +		}
    +	}
    +}
    +
    +/*
    + * Construct a MODP group from hex strings p (which must be a safe
    + * prime) and g, automatically calculating subgroup q as (p / 2)
    + */
    +struct modp_group *
    +modp_group_from_g_and_safe_p(const char *grp_g, const char *grp_p)
    +{
    +	struct modp_group *ret;
    +
    +	ret = xmalloc(sizeof(*ret));
    +	ret->p = ret->q = ret->g = NULL;
    +	if (BN_hex2bn(&ret->p, grp_p) == 0 ||
    +	    BN_hex2bn(&ret->g, grp_g) == 0)
    +		fatal("%s: BN_hex2bn", __func__);
    +	/* Subgroup order is p/2 (p is a safe prime) */
    +	if ((ret->q = BN_new()) == NULL)
    +		fatal("%s: BN_new", __func__);
    +	if (BN_rshift1(ret->q, ret->p) != 1)
    +		fatal("%s: BN_rshift1", __func__);
    +
    +	return ret;
    +}
    +
    +void
    +modp_group_free(struct modp_group *grp)
    +{
    +	if (grp->g != NULL)
    +		BN_clear_free(grp->g);
    +	if (grp->p != NULL)
    +		BN_clear_free(grp->p);
    +	if (grp->q != NULL)
    +		BN_clear_free(grp->q);
    +	bzero(grp, sizeof(*grp));
    +	xfree(grp);
    +}
    +
    +/* main() function for self-test */
    +
     #ifdef SCHNORR_MAIN
     static void
     schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
    @@ -331,16 +570,17 @@ schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
     
     	if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1)
     		fatal("%s: g_x", __func__);
    -	if (schnorr_sign(grp_p, grp_q, grp_g, x, g_x, "junk", 4, &sig, &siglen))
    +	if (schnorr_sign_buf(grp_p, grp_q, grp_g, x, g_x, "junk", 4,
    +	    &sig, &siglen))
     		fatal("%s: schnorr_sign", __func__);
    -	if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
    +	if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
     	    sig, siglen) != 1)
     		fatal("%s: verify fail", __func__);
    -	if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
    +	if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
     	    sig, siglen) != 0)
     		fatal("%s: verify should have failed (bad ID)", __func__);
     	sig[4] ^= 1;
    -	if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
    +	if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
     	    sig, siglen) != 0)
     		fatal("%s: verify should have failed (bit error)", __func__);
     	xfree(sig);
    @@ -352,7 +592,7 @@ static void
     schnorr_selftest(void)
     {
     	BIGNUM *x;
    -	struct jpake_group *grp;
    +	struct modp_group *grp;
     	u_int i;
     	char *hh;
     
    diff --git a/crypto/openssh/schnorr.h b/crypto/openssh/schnorr.h
    new file mode 100644
    index 00000000000..9730b47cef3
    --- /dev/null
    +++ b/crypto/openssh/schnorr.h
    @@ -0,0 +1,60 @@
    +/* $OpenBSD: schnorr.h,v 1.1 2009/03/05 07:18:19 djm Exp $ */
    +/*
    + * Copyright (c) 2009 Damien Miller.  All rights reserved.
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +#ifndef SCHNORR_H
    +#define SCHNORR_H
    +
    +#include 
    +
    +#include 
    +
    +struct modp_group {
    +	BIGNUM *p, *q, *g;
    +};
    +
    +BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
    +int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *);
    +void debug3_bn(const BIGNUM *, const char *, ...)
    +    __attribute__((__nonnull__ (2)))
    +    __attribute__((format(printf, 2, 3)));
    +void debug3_buf(const u_char *, u_int, const char *, ...)
    +    __attribute__((__nonnull__ (3)))
    +    __attribute__((format(printf, 3, 4)));
    +struct modp_group *modp_group_from_g_and_safe_p(const char *, const char *);
    +void modp_group_free(struct modp_group *);
    +
    +/* Signature and verification functions */
    +int
    +schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
    +    const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x,
    +    const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p);
    +int
    +schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
    +    const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
    +    u_char **sig, u_int *siglen);
    +int
    +schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
    +    const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen,
    +    const BIGNUM *r, const BIGNUM *e);
    +int
    +schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
    +    const BIGNUM *grp_g,
    +    const BIGNUM *g_x, const u_char *id, u_int idlen,
    +    const u_char *sig, u_int siglen);
    +
    +#endif /* JPAKE_H */
    +
    diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1
    index 611beeaef2a..615520bb359 100644
    --- a/crypto/openssh/scp.1
    +++ b/crypto/openssh/scp.1
    @@ -9,9 +9,9 @@
     .\"
     .\" Created: Sun May  7 00:14:37 1995 ylo
     .\"
    -.\" $OpenBSD: scp.1,v 1.46 2008/07/12 05:33:41 djm Exp $
    +.\" $OpenBSD: scp.1,v 1.50 2010/02/08 10:50:20 markus Exp $
     .\"
    -.Dd July 12 2008
    +.Dd February 8 2010
     .Dt SCP 1
     .Os
     .Sh NAME
    @@ -153,6 +153,7 @@ For full details of the options listed below, and their possible values, see
     .It NoHostAuthenticationForLocalhost
     .It NumberOfPasswordPrompts
     .It PasswordAuthentication
    +.It PKCS11Provider
     .It Port
     .It PreferredAuthentications
     .It Protocol
    @@ -164,7 +165,6 @@ For full details of the options listed below, and their possible values, see
     .It SendEnv
     .It ServerAliveInterval
     .It ServerAliveCountMax
    -.It SmartcardDevice
     .It StrictHostKeyChecking
     .It TCPKeepAlive
     .It UsePrivilegedPort
    diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c
    index 32374780687..09efb82acb3 100644
    --- a/crypto/openssh/scp.c
    +++ b/crypto/openssh/scp.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: scp.c,v 1.164 2008/10/10 04:55:16 stevesk Exp $ */
    +/* $OpenBSD: scp.c,v 1.165 2009/12/20 07:28:36 guenther Exp $ */
     /*
      * scp - secure remote copy.  This is basically patched BSD rcp which
      * uses ssh to do the data transfer (instead of using rcmd).
    @@ -244,8 +244,11 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
     		close(pout[1]);
     
     		replacearg(&args, 0, "%s", ssh_program);
    -		if (remuser != NULL)
    -			addargs(&args, "-l%s", remuser);
    +		if (remuser != NULL) {
    +			addargs(&args, "-l");
    +			addargs(&args, "%s", remuser);
    +		}
    +		addargs(&args, "--");
     		addargs(&args, "%s", host);
     		addargs(&args, "%s", cmd);
     
    @@ -337,10 +340,12 @@ main(int argc, char **argv)
     		case 'c':
     		case 'i':
     		case 'F':
    -			addargs(&args, "-%c%s", ch, optarg);
    +			addargs(&args, "-%c", ch);
    +			addargs(&args, "%s", optarg);
     			break;
     		case 'P':
    -			addargs(&args, "-p%s", optarg);
    +			addargs(&args, "-p");
    +			addargs(&args, "%s", optarg);
     			break;
     		case 'B':
     			addargs(&args, "-oBatchmode yes");
    @@ -548,6 +553,7 @@ toremote(char *targ, int argc, char **argv)
     			} else {
     				host = cleanhostname(argv[i]);
     			}
    +			addargs(&alist, "--");
     			addargs(&alist, "%s", host);
     			addargs(&alist, "%s", cmd);
     			addargs(&alist, "%s", src);
    @@ -558,7 +564,7 @@ toremote(char *targ, int argc, char **argv)
     				errs = 1;
     		} else {	/* local to remote */
     			if (remin == -1) {
    -				xasprintf(&bp, "%s -t %s", cmd, targ);
    +				xasprintf(&bp, "%s -t -- %s", cmd, targ);
     				host = cleanhostname(thost);
     				if (do_cmd(host, tuser, bp, &remin,
     				    &remout) < 0)
    @@ -591,6 +597,7 @@ tolocal(int argc, char **argv)
     				addargs(&alist, "-r");
     			if (pflag)
     				addargs(&alist, "-p");
    +			addargs(&alist, "--");
     			addargs(&alist, "%s", argv[i]);
     			addargs(&alist, "%s", argv[argc-1]);
     			if (do_local_cmd(&alist))
    @@ -610,7 +617,7 @@ tolocal(int argc, char **argv)
     				suser = pwd->pw_name;
     		}
     		host = cleanhostname(host);
    -		xasprintf(&bp, "%s -f %s", cmd, src);
    +		xasprintf(&bp, "%s -f -- %s", cmd, src);
     		if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
     			(void) xfree(bp);
     			++errs;
    diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c
    index 4744688c49b..603c5865f9c 100644
    --- a/crypto/openssh/servconf.c
    +++ b/crypto/openssh/servconf.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: servconf.c,v 1.194 2009/01/22 10:02:34 djm Exp $ */
    +/* $OpenBSD: servconf.c,v 1.204 2010/03/04 10:36:03 djm Exp $ */
     /*
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
      *                    All rights reserved
    @@ -42,6 +42,7 @@ __RCSID("$FreeBSD$");
     #include "match.h"
     #include "channels.h"
     #include "groupaccess.h"
    +#include "version.h"
     
     static void add_listen_addr(ServerOptions *, char *, int);
     static void add_one_listen_addr(ServerOptions *, char *, int);
    @@ -66,6 +67,7 @@ initialize_server_options(ServerOptions *options)
     	options->listen_addrs = NULL;
     	options->address_family = -1;
     	options->num_host_key_files = 0;
    +	options->num_host_cert_files = 0;
     	options->pid_file = NULL;
     	options->server_key_bits = -1;
     	options->login_grace_time = -1;
    @@ -129,6 +131,8 @@ initialize_server_options(ServerOptions *options)
     	options->adm_forced_command = NULL;
     	options->chroot_directory = NULL;
     	options->zero_knowledge_password_authentication = -1;
    +	options->revoked_keys_file = NULL;
    +	options->trusted_user_ca_keys = NULL;
     }
     
     void
    @@ -153,6 +157,7 @@ fill_default_server_options(ServerOptions *options)
     			    _PATH_HOST_DSA_KEY_FILE;
     		}
     	}
    +	/* No certificates by default */
     	if (options->num_ports == 0)
     		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
     	if (options->listen_addrs == NULL)
    @@ -306,7 +311,8 @@ typedef enum {
     	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
     	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
     	sUsePrivilegeSeparation, sAllowAgentForwarding,
    -	sZeroKnowledgePasswordAuthentication,
    +	sZeroKnowledgePasswordAuthentication, sHostCertificate,
    +	sRevokedKeys, sTrustedUserCAKeys,
     	sVersionAddendum,
     	sDeprecated, sUnsupported
     } ServerOpCodes;
    @@ -345,7 +351,7 @@ static struct {
     	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
     	{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
     	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
    -	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },	/* alias */
    +	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
     #ifdef KRB5
     	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
     	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
    @@ -419,13 +425,16 @@ static struct {
     	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
     	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
     	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
    -	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
    +	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
     	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
     	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
    - 	{ "match", sMatch, SSHCFG_ALL },
    +	{ "match", sMatch, SSHCFG_ALL },
     	{ "permitopen", sPermitOpen, SSHCFG_ALL },
     	{ "forcecommand", sForceCommand, SSHCFG_ALL },
     	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
    +	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
    +	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
    +	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
     	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
     	{ NULL, sBadOption, 0 }
     };
    @@ -462,6 +471,22 @@ parse_token(const char *cp, const char *filename,
     	return sBadOption;
     }
     
    +char *
    +derelativise_path(const char *path)
    +{
    +	char *expanded, *ret, *cwd;
    +
    +	expanded = tilde_expand_filename(path, getuid());
    +	if (*expanded == '/')
    +		return expanded;
    +	if ((cwd = getcwd(NULL, 0)) == NULL)
    +		fatal("%s: getcwd: %s", __func__, strerror(errno));
    +	xasprintf(&ret, "%s/%s", cwd, expanded);
    +	xfree(cwd);
    +	xfree(expanded);
    +	return ret;
    +}
    +
     static void
     add_listen_addr(ServerOptions *options, char *addr, int port)
     {
    @@ -796,13 +821,23 @@ process_server_config_line(ServerOptions *options, char *line,
     			fatal("%s line %d: missing file name.",
     			    filename, linenum);
     		if (*activep && *charptr == NULL) {
    -			*charptr = tilde_expand_filename(arg, getuid());
    +			*charptr = derelativise_path(arg);
     			/* increase optional counter */
     			if (intptr != NULL)
     				*intptr = *intptr + 1;
     		}
     		break;
     
    +	case sHostCertificate:
    +		intptr = &options->num_host_cert_files;
    +		if (*intptr >= MAX_HOSTKEYS)
    +			fatal("%s line %d: too many host certificates "
    +			    "specified (max %d).", filename, linenum,
    +			    MAX_HOSTCERTS);
    +		charptr = &options->host_cert_files[*intptr];
    +		goto parse_filename;
    +		break;
    +
     	case sPidFile:
     		charptr = &options->pid_file;
     		goto parse_filename;
    @@ -1297,6 +1332,14 @@ process_server_config_line(ServerOptions *options, char *line,
     			*charptr = xstrdup(arg);
     		break;
     
    +	case sTrustedUserCAKeys:
    +		charptr = &options->trusted_user_ca_keys;
    +		goto parse_filename;
    +
    +	case sRevokedKeys:
    +		charptr = &options->revoked_keys_file;
    +		goto parse_filename;
    +
     	case sVersionAddendum:
                     ssh_version_set_addendum(strtok(cp, "\n"));
                     do {
    @@ -1386,7 +1429,7 @@ parse_server_match_config(ServerOptions *options, const char *user,
     /*
      * Copy any supported values that are set.
      *
    - * If the preauth flag is set, we do not bother copying the the string or
    + * If the preauth flag is set, we do not bother copying the string or
      * array values that are not used pre-authentication, because any that we
      * do use must be explictly sent in mm_getpwnamallow().
      */
    @@ -1418,6 +1461,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
     		return;
     	M_CP_STROPT(adm_forced_command);
     	M_CP_STROPT(chroot_directory);
    +	M_CP_STROPT(trusted_user_ca_keys);
    +	M_CP_STROPT(revoked_keys_file);
     }
     
     #undef M_CP_INTOPT
    @@ -1636,6 +1681,9 @@ dump_config(ServerOptions *o)
     	dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
     	dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
     	dump_cfg_string(sForceCommand, o->adm_forced_command);
    +	dump_cfg_string(sChrootDirectory, o->chroot_directory);
    +	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
    +	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
     
     	/* string arguments requiring a lookup */
     	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
    @@ -1644,6 +1692,8 @@ dump_config(ServerOptions *o)
     	/* string array arguments */
     	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
     	     o->host_key_files);
    +	dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files,
    +	     o->host_cert_files);
     	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
     	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
     	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
    diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h
    index b3ac7da4b65..860009f9c73 100644
    --- a/crypto/openssh/servconf.h
    +++ b/crypto/openssh/servconf.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: servconf.h,v 1.87 2009/01/22 10:02:34 djm Exp $ */
    +/* $OpenBSD: servconf.h,v 1.92 2010/03/04 10:36:03 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -24,6 +24,7 @@
     #define MAX_DENY_GROUPS		256	/* Max # groups on deny list. */
     #define MAX_SUBSYSTEMS		256	/* Max # subsystems. */
     #define MAX_HOSTKEYS		256	/* Max # hostkeys. */
    +#define MAX_HOSTCERTS		256	/* Max # host certificates. */
     #define MAX_ACCEPT_ENV		256	/* Max # of env vars. */
     #define MAX_MATCH_GROUPS	256	/* Max # of groups for Match. */
     
    @@ -49,6 +50,8 @@ typedef struct {
     	int     address_family;		/* Address family used by the server. */
     	char   *host_key_files[MAX_HOSTKEYS];	/* Files containing host keys. */
     	int     num_host_key_files;     /* Number of files for host keys. */
    +	char   *host_cert_files[MAX_HOSTCERTS];	/* Files containing host certs. */
    +	int     num_host_cert_files;     /* Number of files for host certs. */
     	char   *pid_file;	/* Where to put our pid */
     	int     server_key_bits;/* Size of the server key. */
     	int     login_grace_time;	/* Disconnect if no auth in this time
    @@ -151,6 +154,8 @@ typedef struct {
     	int	num_permitted_opens;
     
     	char   *chroot_directory;
    +	char   *revoked_keys_file;
    +	char   *trusted_user_ca_keys;
     }       ServerOptions;
     
     void	 initialize_server_options(ServerOptions *);
    @@ -164,5 +169,6 @@ void	 parse_server_match_config(ServerOptions *, const char *, const char *,
     	     const char *);
     void	 copy_set_server_options(ServerOptions *, ServerOptions *, int);
     void	 dump_config(ServerOptions *);
    +char	*derelativise_path(const char *);
     
     #endif				/* SERVCONF_H */
    diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c
    index 81cafe6ad55..8be01c5c37c 100644
    --- a/crypto/openssh/serverloop.c
    +++ b/crypto/openssh/serverloop.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: serverloop.c,v 1.157 2009/02/12 03:16:01 djm Exp $ */
    +/* $OpenBSD: serverloop.c,v 1.159 2009/05/28 16:50:16 andreas Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -78,6 +78,7 @@
     #include "auth-options.h"
     #include "serverloop.h"
     #include "misc.h"
    +#include "roaming.h"
     
     extern ServerOptions options;
     
    @@ -249,7 +250,7 @@ client_alive_check(void)
     	int channel_id;
     
     	/* timeout, check to see how many we have had */
    -	if (++keep_alive_timeouts > options.client_alive_count_max) {
    +	if (packet_inc_alive_timeouts() > options.client_alive_count_max) {
     		logit("Timeout, client not responding.");
     		cleanup_exit(255);
     	}
    @@ -391,8 +392,11 @@ process_input(fd_set *readset)
     
     	/* Read and buffer any input data from the client. */
     	if (FD_ISSET(connection_in, readset)) {
    -		len = read(connection_in, buf, sizeof(buf));
    +		int cont = 0;
    +		len = roaming_read(connection_in, buf, sizeof(buf), &cont);
     		if (len == 0) {
    +			if (cont)
    +				return;
     			verbose("Connection closed by %.100s",
     			    get_remote_ipaddr());
     			connection_closed = 1;
    @@ -890,7 +894,7 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
     	 * even if this was generated by something other than
     	 * the bogus CHANNEL_REQUEST we send for keepalives.
     	 */
    -	keep_alive_timeouts = 0;
    +	packet_set_alive_timeouts(0);
     }
     
     static void
    @@ -1120,7 +1124,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
     		    no_port_forwarding_flag ||
     		    (!want_reply && listen_port == 0)
     #ifndef NO_IPPORT_RESERVED_CONCEPT
    -		    || (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)
    +		    || (listen_port != 0 && listen_port < IPPORT_RESERVED &&
    +                    pw->pw_uid != 0)
     #endif
     		    ) {
     			success = 0;
    diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c
    index 16cc4aef308..aad0979e7fd 100644
    --- a/crypto/openssh/session.c
    +++ b/crypto/openssh/session.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: session.c,v 1.245 2009/01/22 09:46:01 djm Exp $ */
    +/* $OpenBSD: session.c,v 1.252 2010/03/07 11:57:13 dtucker Exp $ */
     /*
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
      *                    All rights reserved
    @@ -143,9 +143,10 @@ static int sessions_first_unused = -1;
     static int sessions_nalloc = 0;
     static Session *sessions = NULL;
     
    -#define SUBSYSTEM_NONE		0
    -#define SUBSYSTEM_EXT		1
    -#define SUBSYSTEM_INT_SFTP	2
    +#define SUBSYSTEM_NONE			0
    +#define SUBSYSTEM_EXT			1
    +#define SUBSYSTEM_INT_SFTP		2
    +#define SUBSYSTEM_INT_SFTP_ERROR	3
     
     #ifdef HAVE_LOGIN_CAP
     login_cap_t *lc;
    @@ -271,6 +272,8 @@ do_authenticated(Authctxt *authctxt)
     	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
     		channel_permit_all_opens();
     
    +	auth_debug_send();
    +
     	if (compat20)
     		do_authenticated2(authctxt);
     	else
    @@ -572,8 +575,7 @@ do_exec_no_pty(Session *s, const char *command)
     	signal(WJSIGNAL, cray_job_termination_handler);
     #endif /* _UNICOS */
     #ifdef HAVE_CYGWIN
    -	if (is_winnt)
    -		cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
    +	cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
     #endif
     
     	s->pid = pid;
    @@ -717,8 +719,8 @@ do_exec_pty(Session *s, const char *command)
     		 * Do common processing for the child, such as execing
     		 * the command.
     		 */
    - 		do_child(s, command);
    - 		/* NOTREACHED */
    +		do_child(s, command);
    +		/* NOTREACHED */
     	default:
     		break;
     	}
    @@ -727,8 +729,7 @@ do_exec_pty(Session *s, const char *command)
     	signal(WJSIGNAL, cray_job_termination_handler);
     #endif /* _UNICOS */
     #ifdef HAVE_CYGWIN
    -	if (is_winnt)
    -		cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
    +	cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
     #endif
     
     	s->pid = pid;
    @@ -788,17 +789,19 @@ do_exec(Session *s, const char *command)
     	if (options.adm_forced_command) {
     		original_command = command;
     		command = options.adm_forced_command;
    -		if (IS_INTERNAL_SFTP(command))
    -			s->is_subsystem = SUBSYSTEM_INT_SFTP;
    -		else if (s->is_subsystem)
    +		if (IS_INTERNAL_SFTP(command)) {
    +			s->is_subsystem = s->is_subsystem ?
    +			    SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
    +		} else if (s->is_subsystem)
     			s->is_subsystem = SUBSYSTEM_EXT;
     		debug("Forced command (config) '%.900s'", command);
     	} else if (forced_command) {
     		original_command = command;
     		command = forced_command;
    -		if (IS_INTERNAL_SFTP(command))
    -			s->is_subsystem = SUBSYSTEM_INT_SFTP;
    -		else if (s->is_subsystem)
    +		if (IS_INTERNAL_SFTP(command)) {
    +			s->is_subsystem = s->is_subsystem ?
    +			    SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
    +		} else if (s->is_subsystem)
     			s->is_subsystem = SUBSYSTEM_EXT;
     		debug("Forced command (key option) '%.900s'", command);
     	}
    @@ -848,7 +851,7 @@ do_login(Session *s, const char *command)
     	fromlen = sizeof(from);
     	if (packet_connection_is_on_socket()) {
     		if (getpeername(packet_get_connection_in(),
    -		    (struct sockaddr *) & from, &fromlen) < 0) {
    +		    (struct sockaddr *)&from, &fromlen) < 0) {
     			debug("getpeername: %.100s", strerror(errno));
     			cleanup_exit(255);
     		}
    @@ -1135,7 +1138,7 @@ do_setup_env(Session *s, const char *shell)
     	u_int i, envsize;
     	char **env, *laddr;
     	struct passwd *pw = s->pw;
    -#ifndef HAVE_LOGIN_CAP
    +#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN)
     	char *path = NULL;
     #else
     	extern char **environ;
    @@ -1406,26 +1409,32 @@ static void
     do_nologin(struct passwd *pw)
     {
     	FILE *f = NULL;
    -	char buf[1024];
    +	char buf[1024], *nl, *def_nl = _PATH_NOLOGIN;
    +	struct stat sb;
     
     #ifdef HAVE_LOGIN_CAP
    -	if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
    -		f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
    -		    _PATH_NOLOGIN), "r");
    +	if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
    +		return;
    +	nl = login_getcapstr(lc, "nologin", def_nl, def_nl);
     #else
    -	if (pw->pw_uid)
    -		f = fopen(_PATH_NOLOGIN, "r");
    +	if (pw->pw_uid == 0)
    +		return;
    +	nl = def_nl;
     #endif
    -	if (f) {
    -		/* /etc/nologin exists.  Print its contents and exit. */
    -		logit("User %.100s not allowed because %s exists",
    -		    pw->pw_name, _PATH_NOLOGIN);
    -		while (fgets(buf, sizeof(buf), f))
    -			fputs(buf, stderr);
    -		fclose(f);
    -		fflush(NULL);
    -		exit(254);
    +	if (stat(nl, &sb) == -1) {
    +		if (nl != def_nl)
    +			xfree(nl);
    +		return;
     	}
    +
    +	/* /etc/nologin exists.  Print its contents if we can and exit. */
    +	logit("User %.100s not allowed because %s exists", pw->pw_name, nl);
    +	if ((f = fopen(nl, "r")) != NULL) {
    + 		while (fgets(buf, sizeof(buf), f))
    + 			fputs(buf, stderr);
    + 		fclose(f);
    + 	}
    +	exit(254);
     }
     
     /*
    @@ -1498,11 +1507,6 @@ do_setusercontext(struct passwd *pw)
     	if (getuid() == 0 || geteuid() == 0)
     #endif /* HAVE_CYGWIN */
     	{
    -
    -#ifdef HAVE_SETPCRED
    -		if (setpcred(pw->pw_name, (char **)NULL) == -1)
    -			fatal("Failed to set process credentials");
    -#endif /* HAVE_SETPCRED */
     #ifdef HAVE_LOGIN_CAP
     # ifdef __bsdi__
     		setpgid(0, 0);
    @@ -1558,6 +1562,24 @@ do_setusercontext(struct passwd *pw)
     		}
     # endif /* USE_LIBIAF */
     #endif
    +#ifdef HAVE_SETPCRED
    +		/*
    +		 * If we have a chroot directory, we set all creds except real
    +		 * uid which we will need for chroot.  If we don't have a
    +		 * chroot directory, we don't override anything.
    +		 */
    +		{
    +			char **creds = NULL, *chroot_creds[] =
    +			    { "REAL_USER=root", NULL };
    +
    +			if (options.chroot_directory != NULL &&
    +			    strcasecmp(options.chroot_directory, "none") != 0)
    +				creds = chroot_creds;
    +
    +			if (setpcred(pw->pw_name, creds) == -1)
    +				fatal("Failed to set process credentials");
    +		}
    +#endif /* HAVE_SETPCRED */
     
     		if (options.chroot_directory != NULL &&
     		    strcasecmp(options.chroot_directory, "none") != 0) {
    @@ -1581,9 +1603,6 @@ do_setusercontext(struct passwd *pw)
     #endif
     	}
     
    -#ifdef HAVE_CYGWIN
    -	if (is_winnt)
    -#endif
     	if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
     		fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
     
    @@ -1819,12 +1838,16 @@ do_child(Session *s, const char *command)
     	/* restore SIGPIPE for child */
     	signal(SIGPIPE, SIG_DFL);
     
    -	if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
    +	if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) {
    +		printf("This service allows sftp connections only.\n");
    +		fflush(NULL);
    +		exit(1);
    +	} else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
     		extern int optind, optreset;
     		int i;
     		char *p, *args;
     
    -		setproctitle("%s@internal-sftp-server", s->pw->pw_name);
    +		setproctitle("%s@%s", s->pw->pw_name, INTERNAL_SFTP_NAME);
     		args = xstrdup(command ? command : "sftp-server");
     		for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " ")))
     			if (i < ARGV_MAX - 1)
    @@ -1832,9 +1855,14 @@ do_child(Session *s, const char *command)
     		argv[i] = NULL;
     		optind = optreset = 1;
     		__progname = argv[0];
    +#ifdef WITH_SELINUX
    +		ssh_selinux_change_context("sftpd_t");
    +#endif
     		exit(sftp_server_main(i, argv, s->pw));
     	}
     
    +	fflush(NULL);
    +
     	if (options.use_login) {
     		launch_login(pw, hostname);
     		/* NEVERREACHED */
    @@ -2145,16 +2173,16 @@ session_subsystem_req(Session *s)
     		if (strcmp(subsys, options.subsystem_name[i]) == 0) {
     			prog = options.subsystem_command[i];
     			cmd = options.subsystem_args[i];
    -			if (!strcmp(INTERNAL_SFTP_NAME, prog)) {
    +			if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) {
     				s->is_subsystem = SUBSYSTEM_INT_SFTP;
    -			} else if (stat(prog, &st) < 0) {
    -				error("subsystem: cannot stat %s: %s", prog,
    -				    strerror(errno));
    -				break;
    +				debug("subsystem: %s", prog);
     			} else {
    +				if (stat(prog, &st) < 0)
    +					debug("subsystem: cannot stat %s: %s",
    +					    prog, strerror(errno));
     				s->is_subsystem = SUBSYSTEM_EXT;
    +				debug("subsystem: exec() %s", cmd);
     			}
    -			debug("subsystem: exec() %s", cmd);
     			success = do_exec(s, cmd) == 0;
     			break;
     		}
    diff --git a/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c
    index 5e39aa7d21b..6124c0f408c 100644
    --- a/crypto/openssh/sftp-client.c
    +++ b/crypto/openssh/sftp-client.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sftp-client.c,v 1.86 2008/06/26 06:10:09 djm Exp $ */
    +/* $OpenBSD: sftp-client.c,v 1.90 2009/10/11 10:41:26 dtucker Exp $ */
     /*
      * Copyright (c) 2001-2004 Damien Miller 
      *
    @@ -36,6 +36,7 @@
     #endif
     #include 
     
    +#include 
     #include 
     #include 
     #include 
    @@ -61,6 +62,9 @@ extern int showprogress;
     /* Minimum amount of data to read at a time */
     #define MIN_READ_SIZE	512
     
    +/* Maximum depth to descend in directory trees */
    +#define MAX_DIR_DEPTH 64
    +
     struct sftp_conn {
     	int fd_in;
     	int fd_out;
    @@ -74,6 +78,10 @@ struct sftp_conn {
     	u_int exts;
     };
     
    +static char *
    +get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
    +    __attribute__((format(printf, 4, 5)));
    +
     static void
     send_msg(int fd, Buffer *m)
     {
    @@ -179,11 +187,18 @@ get_status(int fd, u_int expected_id)
     }
     
     static char *
    -get_handle(int fd, u_int expected_id, u_int *len)
    +get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
     {
     	Buffer msg;
     	u_int type, id;
    -	char *handle;
    +	char *handle, errmsg[256];
    +	va_list args;
    +	int status;
    +
    +	va_start(args, errfmt);
    +	if (errfmt != NULL)
    +		vsnprintf(errmsg, sizeof(errmsg), errfmt, args);
    +	va_end(args);
     
     	buffer_init(&msg);
     	get_msg(fd, &msg);
    @@ -191,16 +206,17 @@ get_handle(int fd, u_int expected_id, u_int *len)
     	id = buffer_get_int(&msg);
     
     	if (id != expected_id)
    -		fatal("ID mismatch (%u != %u)", id, expected_id);
    +		fatal("%s: ID mismatch (%u != %u)",
    +		    errfmt == NULL ? __func__ : errmsg, id, expected_id);
     	if (type == SSH2_FXP_STATUS) {
    -		int status = buffer_get_int(&msg);
    -
    -		error("Couldn't get handle: %s", fx2txt(status));
    +		status = buffer_get_int(&msg);
    +		if (errfmt != NULL)
    +			error("%s: %s", errmsg, fx2txt(status));
     		buffer_free(&msg);
     		return(NULL);
     	} else if (type != SSH2_FXP_HANDLE)
    -		fatal("Expected SSH2_FXP_HANDLE(%u) packet, got %u",
    -		    SSH2_FXP_HANDLE, type);
    +		fatal("%s: Expected SSH2_FXP_HANDLE(%u) packet, got %u",
    +		    errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type);
     
     	handle = buffer_get_string(&msg, len);
     	buffer_free(&msg);
    @@ -418,7 +434,8 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
     
     	buffer_clear(&msg);
     
    -	handle = get_handle(conn->fd_in, id, &handle_len);
    +	handle = get_handle(conn->fd_in, id, &handle_len,
    +	    "remote readdir(\"%s\")", path);
     	if (handle == NULL)
     		return(-1);
     
    @@ -484,6 +501,17 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
     			if (printflag)
     				printf("%s\n", longname);
     
    +			/*
    +			 * Directory entries should never contain '/'
    +			 * These can be used to attack recursive ops
    +			 * (e.g. send '../../../../etc/passwd')
    +			 */
    +			if (strchr(filename, '/') != NULL) {
    +				error("Server sent suspect path \"%s\" "
    +				    "during readdir of \"%s\"", filename, path);
    +				goto next;
    +			}
    +
     			if (dir) {
     				*dir = xrealloc(*dir, ents + 2, sizeof(**dir));
     				(*dir)[ents] = xmalloc(sizeof(***dir));
    @@ -492,7 +520,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
     				memcpy(&(*dir)[ents]->a, a, sizeof(*a));
     				(*dir)[++ents] = NULL;
     			}
    -
    + next:
     			xfree(filename);
     			xfree(longname);
     		}
    @@ -547,7 +575,7 @@ do_rm(struct sftp_conn *conn, char *path)
     }
     
     int
    -do_mkdir(struct sftp_conn *conn, char *path, Attrib *a)
    +do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag)
     {
     	u_int status, id;
     
    @@ -556,7 +584,7 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a)
     	    strlen(path), a);
     
     	status = get_status(conn->fd_in, id);
    -	if (status != SSH2_FX_OK)
    +	if (status != SSH2_FX_OK && printflag)
     		error("Couldn't create directory: %s", fx2txt(status));
     
     	return(status);
    @@ -895,9 +923,9 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
     
     int
     do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
    -    int pflag)
    +    Attrib *a, int pflag)
     {
    -	Attrib junk, *a;
    +	Attrib junk;
     	Buffer msg;
     	char *handle;
     	int local_fd, status = 0, write_error;
    @@ -916,9 +944,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
     
     	TAILQ_INIT(&requests);
     
    -	a = do_stat(conn, remote_path, 0);
    -	if (a == NULL)
    -		return(-1);
    +	if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL)
    +		return -1;
     
     	/* Do not preserve set[ug]id here, as we do not preserve ownership */
     	if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
    @@ -951,7 +978,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
     	send_msg(conn->fd_out, &msg);
     	debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
     
    -	handle = get_handle(conn->fd_in, id, &handle_len);
    +	handle = get_handle(conn->fd_in, id, &handle_len,
    +	    "remote open(\"%s\")", remote_path);
     	if (handle == NULL) {
     		buffer_free(&msg);
     		return(-1);
    @@ -1132,6 +1160,114 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
     	return(status);
     }
     
    +static int
    +download_dir_internal(struct sftp_conn *conn, char *src, char *dst,
    +    Attrib *dirattrib, int pflag, int printflag, int depth)
    +{
    +	int i, ret = 0;
    +	SFTP_DIRENT **dir_entries;
    +	char *filename, *new_src, *new_dst;
    +	mode_t mode = 0777;
    +
    +	if (depth >= MAX_DIR_DEPTH) {
    +		error("Maximum directory depth exceeded: %d levels", depth);
    +		return -1;
    +	}
    +
    +	if (dirattrib == NULL &&
    +	    (dirattrib = do_stat(conn, src, 1)) == NULL) {
    +		error("Unable to stat remote directory \"%s\"", src);
    +		return -1;
    +	}
    +	if (!S_ISDIR(dirattrib->perm)) {
    +		error("\"%s\" is not a directory", src);
    +		return -1;
    +	}
    +	if (printflag)
    +		printf("Retrieving %s\n", src);
    +
    +	if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
    +		mode = dirattrib->perm & 01777;
    +	else {
    +		debug("Server did not send permissions for "
    +		    "directory \"%s\"", dst);
    +	}
    +
    +	if (mkdir(dst, mode) == -1 && errno != EEXIST) {
    +		error("mkdir %s: %s", dst, strerror(errno));
    +		return -1;
    +	}
    +
    +	if (do_readdir(conn, src, &dir_entries) == -1) {
    +		error("%s: Failed to get directory contents", src);
    +		return -1;
    +	}
    +
    +	for (i = 0; dir_entries[i] != NULL && !interrupted; i++) {
    +		filename = dir_entries[i]->filename;
    +
    +		new_dst = path_append(dst, filename);
    +		new_src = path_append(src, filename);
    +
    +		if (S_ISDIR(dir_entries[i]->a.perm)) {
    +			if (strcmp(filename, ".") == 0 ||
    +			    strcmp(filename, "..") == 0)
    +				continue;
    +			if (download_dir_internal(conn, new_src, new_dst,
    +			    &(dir_entries[i]->a), pflag, printflag,
    +			    depth + 1) == -1)
    +				ret = -1;
    +		} else if (S_ISREG(dir_entries[i]->a.perm) ) {
    +			if (do_download(conn, new_src, new_dst,
    +			    &(dir_entries[i]->a), pflag) == -1) {
    +				error("Download of file %s to %s failed",
    +				    new_src, new_dst);
    +				ret = -1;
    +			}
    +		} else
    +			logit("%s: not a regular file\n", new_src);
    +
    +		xfree(new_dst);
    +		xfree(new_src);
    +	}
    +
    +	if (pflag) {
    +		if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
    +			struct timeval tv[2];
    +			tv[0].tv_sec = dirattrib->atime;
    +			tv[1].tv_sec = dirattrib->mtime;
    +			tv[0].tv_usec = tv[1].tv_usec = 0;
    +			if (utimes(dst, tv) == -1)
    +				error("Can't set times on \"%s\": %s",
    +				    dst, strerror(errno));
    +		} else
    +			debug("Server did not send times for directory "
    +			    "\"%s\"", dst);
    +	}
    +
    +	free_sftp_dirents(dir_entries);
    +
    +	return ret;
    +}
    +
    +int
    +download_dir(struct sftp_conn *conn, char *src, char *dst,
    +    Attrib *dirattrib, int pflag, int printflag)
    +{
    +	char *src_canon;
    +	int ret;
    +
    +	if ((src_canon = do_realpath(conn, src)) == NULL) {
    +		error("Unable to canonicalise path \"%s\"", src);
    +		return -1;
    +	}
    +
    +	ret = download_dir_internal(conn, src_canon, dst,
    +	    dirattrib, pflag, printflag, 0);
    +	xfree(src_canon);
    +	return ret;
    +}
    +
     int
     do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
         int pflag)
    @@ -1195,7 +1331,8 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
     
     	buffer_clear(&msg);
     
    -	handle = get_handle(conn->fd_in, id, &handle_len);
    +	handle = get_handle(conn->fd_in, id, &handle_len,
    +	    "remote open(\"%s\")", remote_path);
     	if (handle == NULL) {
     		close(local_fd);
     		buffer_free(&msg);
    @@ -1313,3 +1450,127 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
     
     	return status;
     }
    +
    +static int
    +upload_dir_internal(struct sftp_conn *conn, char *src, char *dst,
    +    int pflag, int printflag, int depth)
    +{
    +	int ret = 0, status;
    +	DIR *dirp;
    +	struct dirent *dp;
    +	char *filename, *new_src, *new_dst;
    +	struct stat sb;
    +	Attrib a;
    +
    +	if (depth >= MAX_DIR_DEPTH) {
    +		error("Maximum directory depth exceeded: %d levels", depth);
    +		return -1;
    +	}
    +
    +	if (stat(src, &sb) == -1) {
    +		error("Couldn't stat directory \"%s\": %s",
    +		    src, strerror(errno));
    +		return -1;
    +	}
    +	if (!S_ISDIR(sb.st_mode)) {
    +		error("\"%s\" is not a directory", src);
    +		return -1;
    +	}
    +	if (printflag)
    +		printf("Entering %s\n", src);
    +
    +	attrib_clear(&a);
    +	stat_to_attrib(&sb, &a);
    +	a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
    +	a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
    +	a.perm &= 01777;
    +	if (!pflag)
    +		a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
    +	
    +	status = do_mkdir(conn, dst, &a, 0);
    +	/*
    +	 * we lack a portable status for errno EEXIST,
    +	 * so if we get a SSH2_FX_FAILURE back we must check
    +	 * if it was created successfully.
    +	 */
    +	if (status != SSH2_FX_OK) {
    +		if (status != SSH2_FX_FAILURE)
    +			return -1;
    +		if (do_stat(conn, dst, 0) == NULL) 
    +			return -1;
    +	}
    +
    +	if ((dirp = opendir(src)) == NULL) {
    +		error("Failed to open dir \"%s\": %s", src, strerror(errno));
    +		return -1;
    +	}
    +	
    +	while (((dp = readdir(dirp)) != NULL) && !interrupted) {
    +		if (dp->d_ino == 0)
    +			continue;
    +		filename = dp->d_name;
    +		new_dst = path_append(dst, filename);
    +		new_src = path_append(src, filename);
    +
    +		if (lstat(new_src, &sb) == -1) {
    +			logit("%s: lstat failed: %s", filename,
    +			    strerror(errno));
    +			ret = -1;
    +		} else if (S_ISDIR(sb.st_mode)) {
    +			if (strcmp(filename, ".") == 0 ||
    +			    strcmp(filename, "..") == 0)
    +				continue;
    +
    +			if (upload_dir_internal(conn, new_src, new_dst,
    +			    pflag, depth + 1, printflag) == -1)
    +				ret = -1;
    +		} else if (S_ISREG(sb.st_mode)) {
    +			if (do_upload(conn, new_src, new_dst, pflag) == -1) {
    +				error("Uploading of file %s to %s failed!",
    +				    new_src, new_dst);
    +				ret = -1;
    +			}
    +		} else
    +			logit("%s: not a regular file\n", filename);
    +		xfree(new_dst);
    +		xfree(new_src);
    +	}
    +
    +	do_setstat(conn, dst, &a);
    +
    +	(void) closedir(dirp);
    +	return ret;
    +}
    +
    +int
    +upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag,
    +    int pflag)
    +{
    +	char *dst_canon;
    +	int ret;
    +
    +	if ((dst_canon = do_realpath(conn, dst)) == NULL) {
    +		error("Unable to canonicalise path \"%s\"", dst);
    +		return -1;
    +	}
    +
    +	ret = upload_dir_internal(conn, src, dst_canon, pflag, printflag, 0);
    +	xfree(dst_canon);
    +	return ret;
    +}
    +
    +char *
    +path_append(char *p1, char *p2)
    +{
    +	char *ret;
    +	size_t len = strlen(p1) + strlen(p2) + 2;
    +
    +	ret = xmalloc(len);
    +	strlcpy(ret, p1, len);
    +	if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/')
    +		strlcat(ret, "/", len);
    +	strlcat(ret, p2, len);
    +
    +	return(ret);
    +}
    +
    diff --git a/crypto/openssh/sftp-client.h b/crypto/openssh/sftp-client.h
    index edb46790f3e..1d08c40493b 100644
    --- a/crypto/openssh/sftp-client.h
    +++ b/crypto/openssh/sftp-client.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sftp-client.h,v 1.17 2008/06/08 20:15:29 dtucker Exp $ */
    +/* $OpenBSD: sftp-client.h,v 1.18 2009/08/18 18:36:20 djm Exp $ */
     
     /*
      * Copyright (c) 2001-2004 Damien Miller 
    @@ -68,7 +68,7 @@ void free_sftp_dirents(SFTP_DIRENT **);
     int do_rm(struct sftp_conn *, char *);
     
     /* Create directory 'path' */
    -int do_mkdir(struct sftp_conn *, char *, Attrib *);
    +int do_mkdir(struct sftp_conn *, char *, Attrib *, int);
     
     /* Remove directory 'path' */
     int do_rmdir(struct sftp_conn *, char *);
    @@ -103,7 +103,13 @@ int do_symlink(struct sftp_conn *, char *, char *);
      * Download 'remote_path' to 'local_path'. Preserve permissions and times
      * if 'pflag' is set
      */
    -int do_download(struct sftp_conn *, char *, char *, int);
    +int do_download(struct sftp_conn *, char *, char *, Attrib *, int);
    +
    +/*
    + * Recursively download 'remote_directory' to 'local_directory'. Preserve 
    + * times if 'pflag' is set
    + */
    +int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int);
     
     /*
      * Upload 'local_path' to 'remote_path'. Preserve permissions and times
    @@ -111,4 +117,13 @@ int do_download(struct sftp_conn *, char *, char *, int);
      */
     int do_upload(struct sftp_conn *, char *, char *, int);
     
    +/*
    + * Recursively upload 'local_directory' to 'remote_directory'. Preserve 
    + * times if 'pflag' is set
    + */
    +int upload_dir(struct sftp_conn *, char *, char *, int, int);
    +
    +/* Concatenate paths, taking care of slashes. Caller must free result. */
    +char *path_append(char *, char *);
    +
     #endif
    diff --git a/crypto/openssh/sftp-common.c b/crypto/openssh/sftp-common.c
    index 7ebadcc53b0..a042875c69d 100644
    --- a/crypto/openssh/sftp-common.c
    +++ b/crypto/openssh/sftp-common.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sftp-common.c,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */
    +/* $OpenBSD: sftp-common.c,v 1.23 2010/01/15 09:24:23 markus Exp $ */
     /*
      * Copyright (c) 2001 Markus Friedl.  All rights reserved.
      * Copyright (c) 2001 Damien Miller.  All rights reserved.
    @@ -36,6 +36,9 @@
     #include 
     #include 
     #include 
    +#ifdef HAVE_UTIL_H
    +#include 
    +#endif
     
     #include "xmalloc.h"
     #include "buffer.h"
    @@ -184,24 +187,23 @@ fx2txt(int status)
      * drwxr-xr-x    5 markus   markus       1024 Jan 13 18:39 .ssh
      */
     char *
    -ls_file(const char *name, const struct stat *st, int remote)
    +ls_file(const char *name, const struct stat *st, int remote, int si_units)
     {
     	int ulen, glen, sz = 0;
    -	struct passwd *pw;
    -	struct group *gr;
     	struct tm *ltime = localtime(&st->st_mtime);
     	char *user, *group;
     	char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1];
    +	char sbuf[FMT_SCALED_STRSIZE];
     
     	strmode(st->st_mode, mode);
    -	if (!remote && (pw = getpwuid(st->st_uid)) != NULL) {
    -		user = pw->pw_name;
    +	if (!remote) {
    +		user = user_from_uid(st->st_uid, 0);
     	} else {
     		snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
     		user = ubuf;
     	}
    -	if (!remote && (gr = getgrgid(st->st_gid)) != NULL) {
    -		group = gr->gr_name;
    +	if (!remote) {
    +		group = group_from_gid(st->st_gid, 0);
     	} else {
     		snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
     		group = gbuf;
    @@ -216,8 +218,15 @@ ls_file(const char *name, const struct stat *st, int remote)
     		tbuf[0] = '\0';
     	ulen = MAX(strlen(user), 8);
     	glen = MAX(strlen(group), 8);
    -	snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode,
    -	    (u_int)st->st_nlink, ulen, user, glen, group,
    -	    (unsigned long long)st->st_size, tbuf, name);
    +	if (si_units) {
    +		fmt_scaled((long long)st->st_size, sbuf);
    +		snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8s %s %s", mode,
    +		    (u_int)st->st_nlink, ulen, user, glen, group,
    +		    sbuf, tbuf, name);
    +	} else {
    +		snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode,
    +		    (u_int)st->st_nlink, ulen, user, glen, group,
    +		    (unsigned long long)st->st_size, tbuf, name);
    +	}
     	return xstrdup(buf);
     }
    diff --git a/crypto/openssh/sftp-common.h b/crypto/openssh/sftp-common.h
    index 9b5848462a2..9ed86c070dd 100644
    --- a/crypto/openssh/sftp-common.h
    +++ b/crypto/openssh/sftp-common.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sftp-common.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
    +/* $OpenBSD: sftp-common.h,v 1.11 2010/01/13 01:40:16 djm Exp $ */
     
     /*
      * Copyright (c) 2001 Markus Friedl.  All rights reserved.
    @@ -46,6 +46,6 @@ void	 stat_to_attrib(const struct stat *, Attrib *);
     void	 attrib_to_stat(const Attrib *, struct stat *);
     Attrib	*decode_attrib(Buffer *);
     void	 encode_attrib(Buffer *, const Attrib *);
    -char	*ls_file(const char *, const struct stat *, int);
    +char	*ls_file(const char *, const struct stat *, int, int);
     
     const char *fx2txt(int);
    diff --git a/crypto/openssh/sftp-server.8 b/crypto/openssh/sftp-server.8
    index 03e58cb893a..fb0cc6e07d8 100644
    --- a/crypto/openssh/sftp-server.8
    +++ b/crypto/openssh/sftp-server.8
    @@ -1,4 +1,5 @@
    -.\" $OpenBSD: sftp-server.8,v 1.14 2008/07/18 22:51:01 jmc Exp $
    +.\" $OpenBSD: sftp-server.8,v 1.19 2010/01/09 03:36:00 jmc Exp $
    +.\" $FreeBSD$
     .\"
     .\" Copyright (c) 2000 Markus Friedl.  All rights reserved.
     .\"
    @@ -22,7 +23,7 @@
     .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     .\"
    -.Dd July 18 2008
    +.Dd January 9 2010
     .Dt SFTP-SERVER 8
     .Os
     .Sh NAME
    @@ -30,8 +31,10 @@
     .Nd SFTP server subsystem
     .Sh SYNOPSIS
     .Nm sftp-server
    +.Op Fl ehR
     .Op Fl f Ar log_facility
     .Op Fl l Ar log_level
    +.Op Fl u Ar umask
     .Sh DESCRIPTION
     .Nm
     is a program that speaks the server side of SFTP protocol
    @@ -54,12 +57,20 @@ for more information.
     .Pp
     Valid options are:
     .Bl -tag -width Ds
    +.It Fl e
    +Causes
    +.Nm
    +to print logging information to stderr instead of syslog for debugging.
     .It Fl f Ar log_facility
     Specifies the facility code that is used when logging messages from
     .Nm .
     The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
     LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
     The default is AUTH.
    +.It Fl h
    +Displays
    +.Nm
    +usage information.
     .It Fl l Ar log_level
     Specifies which messages will be logged by
     .Nm .
    @@ -71,6 +82,17 @@ performs on behalf of the client.
     DEBUG and DEBUG1 are equivalent.
     DEBUG2 and DEBUG3 each specify higher levels of debugging output.
     The default is ERROR.
    +.It Fl R
    +Places this instance of
    +.Nm
    +into a read-only mode.
    +Attempts to open files for writing, as well as other operations that change
    +the state of the filesystem, will be denied.
    +.It Fl u Ar umask
    +Sets an explicit
    +.Xr umask 2
    +to be applied to newly-created files and directories, instead of the
    +user's default mask.
     .El
     .Pp
     For logging to work,
    @@ -79,7 +101,7 @@ must be able to access
     .Pa /dev/log .
     Use of
     .Nm
    -in a chroot configuation therefore requires that
    +in a chroot configuration therefore requires that
     .Xr syslogd 8
     establish a logging socket inside the chroot directory.
     .Sh SEE ALSO
    diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c
    index 24c4ff71722..a98ac2b6dd2 100644
    --- a/crypto/openssh/sftp-server.c
    +++ b/crypto/openssh/sftp-server.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sftp-server.c,v 1.84 2008/06/26 06:10:09 djm Exp $ */
    +/* $OpenBSD: sftp-server.c,v 1.91 2010/01/13 01:40:16 djm Exp $ */
     /*
      * Copyright (c) 2000-2004 Markus Friedl.  All rights reserved.
      *
    @@ -70,6 +70,9 @@ Buffer oqueue;
     /* Version of client */
     int version;
     
    +/* Disable writes */
    +int readonly;
    +
     /* portable attributes, etc. */
     
     typedef struct Stat Stat;
    @@ -553,16 +556,21 @@ process_open(void)
     	mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
     	logit("open \"%s\" flags %s mode 0%o",
     	    name, string_from_portable(pflags), mode);
    -	fd = open(name, flags, mode);
    -	if (fd < 0) {
    -		status = errno_to_portable(errno);
    -	} else {
    -		handle = handle_new(HANDLE_FILE, name, fd, NULL);
    -		if (handle < 0) {
    -			close(fd);
    +	if (readonly &&
    +	    ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR))
    +		status = SSH2_FX_PERMISSION_DENIED;
    +	else {
    +		fd = open(name, flags, mode);
    +		if (fd < 0) {
    +			status = errno_to_portable(errno);
     		} else {
    -			send_handle(id, handle);
    -			status = SSH2_FX_OK;
    +			handle = handle_new(HANDLE_FILE, name, fd, NULL);
    +			if (handle < 0) {
    +				close(fd);
    +			} else {
    +				send_handle(id, handle);
    +				status = SSH2_FX_OK;
    +			}
     		}
     	}
     	if (status != SSH2_FX_OK)
    @@ -632,7 +640,7 @@ process_write(void)
     	u_int32_t id;
     	u_int64_t off;
     	u_int len;
    -	int handle, fd, ret, status = SSH2_FX_FAILURE;
    +	int handle, fd, ret, status;
     	char *data;
     
     	id = get_int();
    @@ -643,7 +651,12 @@ process_write(void)
     	debug("request %u: write \"%s\" (handle %d) off %llu len %d",
     	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
     	fd = handle_to_fd(handle);
    -	if (fd >= 0) {
    +	
    +	if (fd < 0)
    +		status = SSH2_FX_FAILURE;
    +	else if (readonly)
    +		status = SSH2_FX_PERMISSION_DENIED;
    +	else {
     		if (lseek(fd, off, SEEK_SET) < 0) {
     			status = errno_to_portable(errno);
     			error("process_write: seek failed");
    @@ -658,6 +671,7 @@ process_write(void)
     				handle_update_write(handle, ret);
     			} else {
     				debug2("nothing at all written");
    +				status = SSH2_FX_FAILURE;
     			}
     		}
     	}
    @@ -754,6 +768,10 @@ process_setstat(void)
     	name = get_string(NULL);
     	a = get_attrib();
     	debug("request %u: setstat name \"%s\"", id, name);
    +	if (readonly) {
    +		status = SSH2_FX_PERMISSION_DENIED;
    +		a->flags = 0;
    +	}
     	if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
     		logit("set \"%s\" size %llu",
     		    name, (unsigned long long)a->size);
    @@ -802,9 +820,11 @@ process_fsetstat(void)
     	a = get_attrib();
     	debug("request %u: fsetstat handle %d", id, handle);
     	fd = handle_to_fd(handle);
    -	if (fd < 0) {
    +	if (fd < 0)
     		status = SSH2_FX_FAILURE;
    -	} else {
    +	else if (readonly)
    +		status = SSH2_FX_PERMISSION_DENIED;
    +	else {
     		char *name = handle_to_name(handle);
     
     		if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
    @@ -920,7 +940,7 @@ process_readdir(void)
     				continue;
     			stat_to_attrib(&st, &(stats[count].attrib));
     			stats[count].name = xstrdup(dp->d_name);
    -			stats[count].long_name = ls_file(dp->d_name, &st, 0);
    +			stats[count].long_name = ls_file(dp->d_name, &st, 0, 0);
     			count++;
     			/* send up to 100 entries in one message */
     			/* XXX check packet size instead */
    @@ -952,8 +972,12 @@ process_remove(void)
     	name = get_string(NULL);
     	debug3("request %u: remove", id);
     	logit("remove name \"%s\"", name);
    -	ret = unlink(name);
    -	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
    +	if (readonly)
    +		status = SSH2_FX_PERMISSION_DENIED;
    +	else {
    +		ret = unlink(name);
    +		status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
    +	}
     	send_status(id, status);
     	xfree(name);
     }
    @@ -973,8 +997,12 @@ process_mkdir(void)
     	    a->perm & 07777 : 0777;
     	debug3("request %u: mkdir", id);
     	logit("mkdir name \"%s\" mode 0%o", name, mode);
    -	ret = mkdir(name, mode);
    -	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
    +	if (readonly)
    +		status = SSH2_FX_PERMISSION_DENIED;
    +	else {
    +		ret = mkdir(name, mode);
    +		status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
    +	}
     	send_status(id, status);
     	xfree(name);
     }
    @@ -990,8 +1018,12 @@ process_rmdir(void)
     	name = get_string(NULL);
     	debug3("request %u: rmdir", id);
     	logit("rmdir name \"%s\"", name);
    -	ret = rmdir(name);
    -	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
    +	if (readonly)
    +		status = SSH2_FX_PERMISSION_DENIED;
    +	else {
    +		ret = rmdir(name);
    +		status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
    +	}
     	send_status(id, status);
     	xfree(name);
     }
    @@ -1036,12 +1068,14 @@ process_rename(void)
     	debug3("request %u: rename", id);
     	logit("rename old \"%s\" new \"%s\"", oldpath, newpath);
     	status = SSH2_FX_FAILURE;
    -	if (lstat(oldpath, &sb) == -1)
    +	if (readonly)
    +		status = SSH2_FX_PERMISSION_DENIED;
    +	else if (lstat(oldpath, &sb) == -1)
     		status = errno_to_portable(errno);
     	else if (S_ISREG(sb.st_mode)) {
     		/* Race-free rename of regular files */
     		if (link(oldpath, newpath) == -1) {
    -			if (errno == EOPNOTSUPP
    +			if (errno == EOPNOTSUPP || errno == ENOSYS
     #ifdef EXDEV
     			    || errno == EXDEV
     #endif
    @@ -1120,8 +1154,12 @@ process_symlink(void)
     	debug3("request %u: symlink", id);
     	logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
     	/* this will fail if 'newpath' exists */
    -	ret = symlink(oldpath, newpath);
    -	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
    +	if (readonly)
    +		status = SSH2_FX_PERMISSION_DENIED;
    +	else {
    +		ret = symlink(oldpath, newpath);
    +		status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
    +	}
     	send_status(id, status);
     	xfree(oldpath);
     	xfree(newpath);
    @@ -1131,15 +1169,19 @@ static void
     process_extended_posix_rename(u_int32_t id)
     {
     	char *oldpath, *newpath;
    +	int ret, status;
     
     	oldpath = get_string(NULL);
     	newpath = get_string(NULL);
     	debug3("request %u: posix-rename", id);
     	logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath);
    -	if (rename(oldpath, newpath) == -1)
    -		send_status(id, errno_to_portable(errno));
    -	else
    -		send_status(id, SSH2_FX_OK);
    +	if (readonly)
    +		status = SSH2_FX_PERMISSION_DENIED;
    +	else {
    +		ret = rename(oldpath, newpath);
    +		status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
    +	}
    +	send_status(id, status);
     	xfree(oldpath);
     	xfree(newpath);
     }
    @@ -1322,7 +1364,8 @@ sftp_server_usage(void)
     	extern char *__progname;
     
     	fprintf(stderr,
    -	    "usage: %s [-he] [-l log_level] [-f log_facility]\n", __progname);
    +	    "usage: %s [-ehR] [-f log_facility] [-l log_level] [-u umask]\n",
    +	    __progname);
     	exit(1);
     }
     
    @@ -1334,6 +1377,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
     	ssize_t len, olen, set_size;
     	SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
     	char *cp, buf[4*4096];
    +	const char *errmsg;
    +	mode_t mask;
     
     	extern char *optarg;
     	extern char *__progname;
    @@ -1341,8 +1386,11 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
     	__progname = ssh_get_progname(argv[0]);
     	log_init(__progname, log_level, log_facility, log_stderr);
     
    -	while (!skipargs && (ch = getopt(argc, argv, "C:f:l:che")) != -1) {
    +	while (!skipargs && (ch = getopt(argc, argv, "f:l:u:cehR")) != -1) {
     		switch (ch) {
    +		case 'R':
    +			readonly = 1;
    +			break;
     		case 'c':
     			/*
     			 * Ignore all arguments if we are invoked as a
    @@ -1363,6 +1411,13 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
     			if (log_facility == SYSLOG_FACILITY_NOT_SET)
     				error("Invalid log facility \"%s\"", optarg);
     			break;
    +		case 'u':
    +			mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg);
    +			if (errmsg != NULL)
    +				fatal("Invalid umask \"%s\": %s",
    +				    optarg, errmsg);
    +			(void)umask(mask);
    +			break;
     		case 'h':
     		default:
     			sftp_server_usage();
    @@ -1387,8 +1442,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
     	logit("session opened for local user %s from [%s]",
     	    pw->pw_name, client_addr);
     
    -	in = dup(STDIN_FILENO);
    -	out = dup(STDOUT_FILENO);
    +	in = STDIN_FILENO;
    +	out = STDOUT_FILENO;
     
     #ifdef HAVE_CYGWIN
     	setmode(in, O_BINARY);
    diff --git a/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1
    index ea56e5038e1..9655cb8475a 100644
    --- a/crypto/openssh/sftp.1
    +++ b/crypto/openssh/sftp.1
    @@ -1,4 +1,4 @@
    -.\" $OpenBSD: sftp.1,v 1.69 2008/12/09 15:35:00 sobrado Exp $
    +.\" $OpenBSD: sftp.1,v 1.83 2010/02/08 10:50:20 markus Exp $
     .\" $FreeBSD$
     .\"
     .\" Copyright (c) 2001 Damien Miller.  All rights reserved.
    @@ -23,7 +23,7 @@
     .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     .\"
    -.Dd December 9 2008
    +.Dd February 8 2010
     .Dt SFTP 1
     .Os
     .Sh NAME
    @@ -32,12 +32,15 @@
     .Sh SYNOPSIS
     .Nm sftp
     .Bk -words
    -.Op Fl 1Cv
    +.Op Fl 1246Cpqrv
     .Op Fl B Ar buffer_size
     .Op Fl b Ar batchfile
    +.Op Fl c Ar cipher
    +.Op Fl D Ar sftp_server_path
     .Op Fl F Ar ssh_config
    +.Op Fl i Ar identity_file
     .Op Fl o Ar ssh_option
    -.Op Fl P Ar sftp_server_path
    +.Op Fl P Ar port
     .Op Fl R Ar num_requests
     .Op Fl S Ar program
     .Op Fl s Ar subsystem | sftp_server
    @@ -88,6 +91,16 @@ The options are as follows:
     .Bl -tag -width Ds
     .It Fl 1
     Specify the use of protocol version 1.
    +.It Fl 2
    +Specify the use of protocol version 2.
    +.It Fl 4
    +Forces
    +.Nm
    +to use IPv4 addresses only.
    +.It Fl 6
    +Forces
    +.Nm
    +to use IPv6 addresses only.
     .It Fl B Ar buffer_size
     Specify the size of the buffer that
     .Nm
    @@ -125,12 +138,26 @@ character (for example,
     Enables compression (via ssh's
     .Fl C
     flag).
    +.It Fl c Ar cipher
    +Selects the cipher to use for encrypting the data transfers.
    +This option is directly passed to
    +.Xr ssh 1 .
    +.It Fl D Ar sftp_server_path
    +Connect directly to a local sftp server
    +(rather than via
    +.Xr ssh 1 ) .
    +This option may be useful in debugging the client and server.
     .It Fl F Ar ssh_config
     Specifies an alternative
     per-user configuration file for
     .Xr ssh 1 .
     This option is directly passed to
     .Xr ssh 1 .
    +.It Fl i Ar identity_file
    +Selects the file from which the identity (private key) for public key
    +authentication is read.
    +This option is directly passed to
    +.Xr ssh 1 .
     .It Fl o Ar ssh_option
     Can be used to pass options to
     .Nm ssh
    @@ -176,6 +203,7 @@ For full details of the options listed below, and their possible values, see
     .It NoHostAuthenticationForLocalhost
     .It NumberOfPasswordPrompts
     .It PasswordAuthentication
    +.It PKCS11Provider
     .It Port
     .It PreferredAuthentications
     .It Protocol
    @@ -187,7 +215,6 @@ For full details of the options listed below, and their possible values, see
     .It SendEnv
     .It ServerAliveInterval
     .It ServerAliveCountMax
    -.It SmartcardDevice
     .It StrictHostKeyChecking
     .It TCPKeepAlive
     .It UsePrivilegedPort
    @@ -195,16 +222,25 @@ For full details of the options listed below, and their possible values, see
     .It UserKnownHostsFile
     .It VerifyHostKeyDNS
     .El
    -.It Fl P Ar sftp_server_path
    -Connect directly to a local sftp server
    -(rather than via
    -.Xr ssh 1 ) .
    -This option may be useful in debugging the client and server.
    +.It Fl P Ar port
    +Specifies the port to connect to on the remote host.
    +.It Fl p
    +Preserves modification times, access times, and modes from the
    +original files transferred.
    +.It Fl q
    +Quiet mode: disables the progress meter as well as warning and
    +diagnostic messages from
    +.Xr ssh 1 .
     .It Fl R Ar num_requests
     Specify how many requests may be outstanding at any one time.
     Increasing this may slightly improve file transfer speed
     but will increase memory usage.
     The default is 64 outstanding requests.
    +.It Fl r
    +Recursively copy entire directories when uploading and downloading.
    +Note that
    +.Nm
    +does not follow symbolic links encountered in the tree traversal.
     .It Fl S Ar program
     Name of the
     .Ar program
    @@ -295,7 +331,7 @@ extension.
     Quit
     .Nm sftp .
     .It Xo Ic get
    -.Op Fl P
    +.Op Fl Ppr
     .Ar remote-path
     .Op Ar local-path
     .Xc
    @@ -314,10 +350,20 @@ If it does and
     is specified, then
     .Ar local-path
     must specify a directory.
    -If the
    +.Pp
    +If either the
     .Fl P
    +or
    +.Fl p
     flag is specified, then full file permissions and access times are
     copied too.
    +.Pp
    +If the
    +.Fl r
    +flag is specified then directories will be copied recursively.
    +Note that
    +.Nm
    +does not follow symbolic links when performing recursive transfers.
     .It Ic help
     Display help text.
     .It Ic lcd Ar path
    @@ -348,7 +394,7 @@ to
     .It Ic lpwd
     Print local working directory.
     .It Xo Ic ls
    -.Op Fl 1aflnrSt
    +.Op Fl 1afhlnrSt
     .Op Ar path
     .Xc
     Display a remote directory listing of either
    @@ -373,6 +419,11 @@ List files beginning with a dot
     .It Fl f
     Do not sort the listing.
     The default sort order is lexicographical.
    +.It Fl h
    +When used with a long format option, use unit suffixes: Byte, Kilobyte,
    +Megabyte, Gigabyte, Terabyte, Petabyte, and Exabyte in order to reduce
    +the number of digits to four or fewer using powers of 2 for sizes (K=1024,
    +M=1048576, etc.).
     .It Fl l
     Display additional details including permissions
     and ownership information.
    @@ -395,7 +446,7 @@ Create remote directory specified by
     .It Ic progress
     Toggle display of progress meter.
     .It Xo Ic put
    -.Op Fl P
    +.Op Fl Ppr
     .Ar local-path
     .Op Ar remote-path
     .Xc
    @@ -413,10 +464,20 @@ If it does and
     is specified, then
     .Ar remote-path
     must specify a directory.
    -If the
    +.Pp
    +If ether the
     .Fl P
    -flag is specified, then the file's full permission and access time are
    +or
    +.Fl p
    +flag is specified, then full file permissions and access times are
     copied too.
    +.Pp
    +If the
    +.Fl r
    +flag is specified then directories will be copied recursively.
    +Note that
    +.Nm
    +does not follow symbolic links when performing recursive transfers.
     .It Ic pwd
     Display remote working directory.
     .It Ic quit
    diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c
    index 66bd111b122..d65d4ec62ea 100644
    --- a/crypto/openssh/sftp.c
    +++ b/crypto/openssh/sftp.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sftp.c,v 1.107 2009/02/02 11:15:14 dtucker Exp $ */
    +/* $OpenBSD: sftp.c,v 1.123 2010/01/27 19:21:39 djm Exp $ */
     /*
      * Copyright (c) 2001-2004 Damien Miller 
      *
    @@ -35,6 +35,9 @@
     #ifdef HAVE_PATHS_H
     # include 
     #endif
    +#ifdef HAVE_LIBGEN_H
    +#include 
    +#endif
     #ifdef USE_LIBEDIT
     #include 
     #else
    @@ -65,30 +68,39 @@ typedef void EditLine;
     #include "sftp-common.h"
     #include "sftp-client.h"
     
    +#define DEFAULT_COPY_BUFLEN	32768	/* Size of buffer for up/download */
    +#define DEFAULT_NUM_REQUESTS	64	/* # concurrent outstanding requests */
    +
     /* File to read commands from */
     FILE* infile;
     
     /* Are we in batchfile mode? */
     int batchmode = 0;
     
    -/* Size of buffer used when copying files */
    -size_t copy_buffer_len = 32768;
    -
    -/* Number of concurrent outstanding requests */
    -size_t num_requests = 64;
    -
     /* PID of ssh transport process */
     static pid_t sshpid = -1;
     
     /* This is set to 0 if the progressmeter is not desired. */
     int showprogress = 1;
     
    +/* When this option is set, we always recursively download/upload directories */
    +int global_rflag = 0;
    +
    +/* When this option is set, the file transfers will always preserve times */
    +int global_pflag = 0;
    +
     /* SIGINT received during command processing */
     volatile sig_atomic_t interrupted = 0;
     
     /* I wish qsort() took a separate ctx for the comparison function...*/
     int sort_flag;
     
    +/* Context used for commandline completion */
    +struct complete_ctx {
    +	struct sftp_conn *conn;
    +	char **remote_pathp;
    +};
    +
     int remote_glob(struct sftp_conn *, const char *, int,
         int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */
     
    @@ -98,16 +110,17 @@ extern char *__progname;
     #define WHITESPACE " \t\r\n"
     
     /* ls flags */
    -#define LS_LONG_VIEW	0x01	/* Full view ala ls -l */
    -#define LS_SHORT_VIEW	0x02	/* Single row view ala ls -1 */
    -#define LS_NUMERIC_VIEW	0x04	/* Long view with numeric uid/gid */
    -#define LS_NAME_SORT	0x08	/* Sort by name (default) */
    -#define LS_TIME_SORT	0x10	/* Sort by mtime */
    -#define LS_SIZE_SORT	0x20	/* Sort by file size */
    -#define LS_REVERSE_SORT	0x40	/* Reverse sort order */
    -#define LS_SHOW_ALL	0x80	/* Don't skip filenames starting with '.' */
    +#define LS_LONG_VIEW	0x0001	/* Full view ala ls -l */
    +#define LS_SHORT_VIEW	0x0002	/* Single row view ala ls -1 */
    +#define LS_NUMERIC_VIEW	0x0004	/* Long view with numeric uid/gid */
    +#define LS_NAME_SORT	0x0008	/* Sort by name (default) */
    +#define LS_TIME_SORT	0x0010	/* Sort by mtime */
    +#define LS_SIZE_SORT	0x0020	/* Sort by file size */
    +#define LS_REVERSE_SORT	0x0040	/* Reverse sort order */
    +#define LS_SHOW_ALL	0x0080	/* Don't skip filenames starting with '.' */
    +#define LS_SI_UNITS	0x0100	/* Display sizes as K, M, G, etc. */
     
    -#define VIEW_FLAGS	(LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW)
    +#define VIEW_FLAGS	(LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW|LS_SI_UNITS)
     #define SORT_FLAGS	(LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT)
     
     /* Commands for interactive mode */
    @@ -139,46 +152,50 @@ extern char *__progname;
     struct CMD {
     	const char *c;
     	const int n;
    +	const int t;
     };
     
    +/* Type of completion */
    +#define NOARGS	0
    +#define REMOTE	1
    +#define LOCAL	2
    +
     static const struct CMD cmds[] = {
    -	{ "bye",	I_QUIT },
    -	{ "cd",		I_CHDIR },
    -	{ "chdir",	I_CHDIR },
    -	{ "chgrp",	I_CHGRP },
    -	{ "chmod",	I_CHMOD },
    -	{ "chown",	I_CHOWN },
    -	{ "df",		I_DF },
    -	{ "dir",	I_LS },
    -	{ "exit",	I_QUIT },
    -	{ "get",	I_GET },
    -	{ "mget",	I_GET },
    -	{ "help",	I_HELP },
    -	{ "lcd",	I_LCHDIR },
    -	{ "lchdir",	I_LCHDIR },
    -	{ "lls",	I_LLS },
    -	{ "lmkdir",	I_LMKDIR },
    -	{ "ln",		I_SYMLINK },
    -	{ "lpwd",	I_LPWD },
    -	{ "ls",		I_LS },
    -	{ "lumask",	I_LUMASK },
    -	{ "mkdir",	I_MKDIR },
    -	{ "progress",	I_PROGRESS },
    -	{ "put",	I_PUT },
    -	{ "mput",	I_PUT },
    -	{ "pwd",	I_PWD },
    -	{ "quit",	I_QUIT },
    -	{ "rename",	I_RENAME },
    -	{ "rm",		I_RM },
    -	{ "rmdir",	I_RMDIR },
    -	{ "symlink",	I_SYMLINK },
    -	{ "version",	I_VERSION },
    -	{ "!",		I_SHELL },
    -	{ "?",		I_HELP },
    -	{ NULL,			-1}
    +	{ "bye",	I_QUIT,		NOARGS	},
    +	{ "cd",		I_CHDIR,	REMOTE	},
    +	{ "chdir",	I_CHDIR,	REMOTE	},
    +	{ "chgrp",	I_CHGRP,	REMOTE	},
    +	{ "chmod",	I_CHMOD,	REMOTE	},
    +	{ "chown",	I_CHOWN,	REMOTE	},
    +	{ "df",		I_DF,		REMOTE	},
    +	{ "dir",	I_LS,		REMOTE	},
    +	{ "exit",	I_QUIT,		NOARGS	},
    +	{ "get",	I_GET,		REMOTE	},
    +	{ "help",	I_HELP,		NOARGS	},
    +	{ "lcd",	I_LCHDIR,	LOCAL	},
    +	{ "lchdir",	I_LCHDIR,	LOCAL	},
    +	{ "lls",	I_LLS,		LOCAL	},
    +	{ "lmkdir",	I_LMKDIR,	LOCAL	},
    +	{ "ln",		I_SYMLINK,	REMOTE	},
    +	{ "lpwd",	I_LPWD,		LOCAL	},
    +	{ "ls",		I_LS,		REMOTE	},
    +	{ "lumask",	I_LUMASK,	NOARGS	},
    +	{ "mkdir",	I_MKDIR,	REMOTE	},
    +	{ "progress",	I_PROGRESS,	NOARGS	},
    +	{ "put",	I_PUT,		LOCAL	},
    +	{ "pwd",	I_PWD,		REMOTE	},
    +	{ "quit",	I_QUIT,		NOARGS	},
    +	{ "rename",	I_RENAME,	REMOTE	},
    +	{ "rm",		I_RM,		REMOTE	},
    +	{ "rmdir",	I_RMDIR,	REMOTE	},
    +	{ "symlink",	I_SYMLINK,	REMOTE	},
    +	{ "version",	I_VERSION,	NOARGS	},
    +	{ "!",		I_SHELL,	NOARGS	},
    +	{ "?",		I_HELP,		NOARGS	},
    +	{ NULL,		-1,		-1	}
     };
     
    -int interactive_loop(int fd_in, int fd_out, char *file1, char *file2);
    +int interactive_loop(struct sftp_conn *, char *file1, char *file2);
     
     /* ARGSUSED */
     static void
    @@ -216,18 +233,18 @@ help(void)
     	    "df [-hi] [path]                    Display statistics for current directory or\n"
     	    "                                   filesystem containing 'path'\n"
     	    "exit                               Quit sftp\n"
    -	    "get [-P] remote-path [local-path]  Download file\n"
    +	    "get [-Ppr] remote [local]          Download file\n"
     	    "help                               Display this help text\n"
     	    "lcd path                           Change local directory to 'path'\n"
     	    "lls [ls-options [path]]            Display local directory listing\n"
     	    "lmkdir path                        Create local directory\n"
     	    "ln oldpath newpath                 Symlink remote file\n"
     	    "lpwd                               Print local working directory\n"
    -	    "ls [-1aflnrSt] [path]              Display remote directory listing\n"
    +	    "ls [-1afhlnrSt] [path]             Display remote directory listing\n"
     	    "lumask umask                       Set local umask to 'umask'\n"
     	    "mkdir path                         Create remote directory\n"
     	    "progress                           Toggle display of progress meter\n"
    -	    "put [-P] local-path [remote-path]  Upload file\n"
    +	    "put [-Ppr] local [remote]          Upload file\n"
     	    "pwd                                Display remote working directory\n"
     	    "quit                               Quit sftp\n"
     	    "rename oldpath newpath             Rename remote file\n"
    @@ -313,21 +330,6 @@ path_strip(char *path, char *strip)
     	return (xstrdup(path));
     }
     
    -static char *
    -path_append(char *p1, char *p2)
    -{
    -	char *ret;
    -	size_t len = strlen(p1) + strlen(p2) + 2;
    -
    -	ret = xmalloc(len);
    -	strlcpy(ret, p1, len);
    -	if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/')
    -		strlcat(ret, "/", len);
    -	strlcat(ret, p2, len);
    -
    -	return(ret);
    -}
    -
     static char *
     make_absolute(char *p, char *pwd)
     {
    @@ -343,27 +345,8 @@ make_absolute(char *p, char *pwd)
     }
     
     static int
    -infer_path(const char *p, char **ifp)
    -{
    -	char *cp;
    -
    -	cp = strrchr(p, '/');
    -	if (cp == NULL) {
    -		*ifp = xstrdup(p);
    -		return(0);
    -	}
    -
    -	if (!cp[1]) {
    -		error("Invalid path");
    -		return(-1);
    -	}
    -
    -	*ifp = xstrdup(cp + 1);
    -	return(0);
    -}
    -
    -static int
    -parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag)
    +parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag,
    +    int *rflag)
     {
     	extern int opterr, optind, optopt, optreset;
     	int ch;
    @@ -371,13 +354,17 @@ parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag)
     	optind = optreset = 1;
     	opterr = 0;
     
    -	*pflag = 0;
    -	while ((ch = getopt(argc, argv, "Pp")) != -1) {
    +	*rflag = *pflag = 0;
    +	while ((ch = getopt(argc, argv, "PpRr")) != -1) {
     		switch (ch) {
     		case 'p':
     		case 'P':
     			*pflag = 1;
     			break;
    +		case 'r':
    +		case 'R':
    +			*rflag = 1;
    +			break;
     		default:
     			error("%s: Invalid flag -%c", cmd, optopt);
     			return -1;
    @@ -397,7 +384,7 @@ parse_ls_flags(char **argv, int argc, int *lflag)
     	opterr = 0;
     
     	*lflag = LS_NAME_SORT;
    -	while ((ch = getopt(argc, argv, "1Saflnrt")) != -1) {
    +	while ((ch = getopt(argc, argv, "1Safhlnrt")) != -1) {
     		switch (ch) {
     		case '1':
     			*lflag &= ~VIEW_FLAGS;
    @@ -413,12 +400,15 @@ parse_ls_flags(char **argv, int argc, int *lflag)
     		case 'f':
     			*lflag &= ~SORT_FLAGS;
     			break;
    +		case 'h':
    +			*lflag |= LS_SI_UNITS;
    +			break;
     		case 'l':
    -			*lflag &= ~VIEW_FLAGS;
    +			*lflag &= ~LS_SHORT_VIEW;
     			*lflag |= LS_LONG_VIEW;
     			break;
     		case 'n':
    -			*lflag &= ~VIEW_FLAGS;
    +			*lflag &= ~LS_SHORT_VIEW;
     			*lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;
     			break;
     		case 'r':
    @@ -489,62 +479,79 @@ remote_is_dir(struct sftp_conn *conn, char *path)
     	return(S_ISDIR(a->perm));
     }
     
    +/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
     static int
    -process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
    +pathname_is_dir(char *pathname)
    +{
    +	size_t l = strlen(pathname);
    +
    +	return l > 0 && pathname[l - 1] == '/';
    +}
    +
    +static int
    +process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
    +    int pflag, int rflag)
     {
     	char *abs_src = NULL;
     	char *abs_dst = NULL;
    -	char *tmp;
     	glob_t g;
    -	int err = 0;
    -	int i;
    +	char *filename, *tmp=NULL;
    +	int i, err = 0;
     
     	abs_src = xstrdup(src);
     	abs_src = make_absolute(abs_src, pwd);
    -
     	memset(&g, 0, sizeof(g));
    +
     	debug3("Looking up %s", abs_src);
    -	if (remote_glob(conn, abs_src, 0, NULL, &g)) {
    +	if (remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) {
     		error("File \"%s\" not found.", abs_src);
     		err = -1;
     		goto out;
     	}
     
    -	/* If multiple matches, dst must be a directory or unspecified */
    -	if (g.gl_matchc > 1 && dst && !is_dir(dst)) {
    -		error("Multiple files match, but \"%s\" is not a directory",
    -		    dst);
    +	/*
    +	 * If multiple matches then dst must be a directory or
    +	 * unspecified.
    +	 */
    +	if (g.gl_matchc > 1 && dst != NULL && !is_dir(dst)) {
    +		error("Multiple source paths, but destination "
    +		    "\"%s\" is not a directory", dst);
     		err = -1;
     		goto out;
     	}
     
     	for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
    -		if (infer_path(g.gl_pathv[i], &tmp)) {
    +		tmp = xstrdup(g.gl_pathv[i]);
    +		if ((filename = basename(tmp)) == NULL) {
    +			error("basename %s: %s", tmp, strerror(errno));
    +			xfree(tmp);
     			err = -1;
     			goto out;
     		}
     
     		if (g.gl_matchc == 1 && dst) {
    -			/* If directory specified, append filename */
    -			xfree(tmp);
     			if (is_dir(dst)) {
    -				if (infer_path(g.gl_pathv[0], &tmp)) {
    -					err = 1;
    -					goto out;
    -				}
    -				abs_dst = path_append(dst, tmp);
    -				xfree(tmp);
    -			} else
    +				abs_dst = path_append(dst, filename);
    +			} else {
     				abs_dst = xstrdup(dst);
    +			}
     		} else if (dst) {
    -			abs_dst = path_append(dst, tmp);
    -			xfree(tmp);
    -		} else
    -			abs_dst = tmp;
    +			abs_dst = path_append(dst, filename);
    +		} else {
    +			abs_dst = xstrdup(filename);
    +		}
    +		xfree(tmp);
     
     		printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
    -		if (do_download(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
    -			err = -1;
    +		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
    +			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, 
    +			    pflag || global_pflag, 1) == -1)
    +				err = -1;
    +		} else {
    +			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
    +			    pflag || global_pflag) == -1)
    +				err = -1;
    +		}
     		xfree(abs_dst);
     		abs_dst = NULL;
     	}
    @@ -556,14 +563,15 @@ out:
     }
     
     static int
    -process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
    +process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
    +    int pflag, int rflag)
     {
     	char *tmp_dst = NULL;
     	char *abs_dst = NULL;
    -	char *tmp;
    +	char *tmp = NULL, *filename = NULL;
     	glob_t g;
     	int err = 0;
    -	int i;
    +	int i, dst_is_dir = 1;
     	struct stat sb;
     
     	if (dst) {
    @@ -573,16 +581,20 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
     
     	memset(&g, 0, sizeof(g));
     	debug3("Looking up %s", src);
    -	if (glob(src, GLOB_NOCHECK, NULL, &g)) {
    +	if (glob(src, GLOB_NOCHECK | GLOB_MARK, NULL, &g)) {
     		error("File \"%s\" not found.", src);
     		err = -1;
     		goto out;
     	}
     
    +	/* If we aren't fetching to pwd then stash this status for later */
    +	if (tmp_dst != NULL)
    +		dst_is_dir = remote_is_dir(conn, tmp_dst);
    +
     	/* If multiple matches, dst may be directory or unspecified */
    -	if (g.gl_matchc > 1 && tmp_dst && !remote_is_dir(conn, tmp_dst)) {
    -		error("Multiple files match, but \"%s\" is not a directory",
    -		    tmp_dst);
    +	if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
    +		error("Multiple paths match, but destination "
    +		    "\"%s\" is not a directory", tmp_dst);
     		err = -1;
     		goto out;
     	}
    @@ -593,38 +605,38 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
     			error("stat %s: %s", g.gl_pathv[i], strerror(errno));
     			continue;
     		}
    -
    -		if (!S_ISREG(sb.st_mode)) {
    -			error("skipping non-regular file %s",
    -			    g.gl_pathv[i]);
    -			continue;
    -		}
    -		if (infer_path(g.gl_pathv[i], &tmp)) {
    +		
    +		tmp = xstrdup(g.gl_pathv[i]);
    +		if ((filename = basename(tmp)) == NULL) {
    +			error("basename %s: %s", tmp, strerror(errno));
    +			xfree(tmp);
     			err = -1;
     			goto out;
     		}
     
     		if (g.gl_matchc == 1 && tmp_dst) {
     			/* If directory specified, append filename */
    -			if (remote_is_dir(conn, tmp_dst)) {
    -				if (infer_path(g.gl_pathv[0], &tmp)) {
    -					err = 1;
    -					goto out;
    -				}
    -				abs_dst = path_append(tmp_dst, tmp);
    -				xfree(tmp);
    -			} else
    +			if (dst_is_dir)
    +				abs_dst = path_append(tmp_dst, filename);
    +			else
     				abs_dst = xstrdup(tmp_dst);
    -
     		} else if (tmp_dst) {
    -			abs_dst = path_append(tmp_dst, tmp);
    -			xfree(tmp);
    -		} else
    -			abs_dst = make_absolute(tmp, pwd);
    +			abs_dst = path_append(tmp_dst, filename);
    +		} else {
    +			abs_dst = make_absolute(xstrdup(filename), pwd);
    +		}
    +		xfree(tmp);
     
     		printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
    -		if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
    -			err = -1;
    +		if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
    +			if (upload_dir(conn, g.gl_pathv[i], abs_dst,
    +			    pflag || global_pflag, 1) == -1)
    +				err = -1;
    +		} else {
    +			if (do_upload(conn, g.gl_pathv[i], abs_dst,
    +			    pflag || global_pflag) == -1)
    +				err = -1;
    +		}
     	}
     
     out:
    @@ -708,13 +720,14 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
     		xfree(tmp);
     
     		if (lflag & LS_LONG_VIEW) {
    -			if (lflag & LS_NUMERIC_VIEW) {
    +			if (lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) {
     				char *lname;
     				struct stat sb;
     
     				memset(&sb, 0, sizeof(sb));
     				attrib_to_stat(&d[n]->a, &sb);
    -				lname = ls_file(fname, &sb, 1);
    +				lname = ls_file(fname, &sb, 1,
    +				    (lflag & LS_SI_UNITS));
     				printf("%s\n", lname);
     				xfree(lname);
     			} else
    @@ -816,7 +829,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
     				a = do_lstat(conn, g.gl_pathv[i], 1);
     			if (a != NULL)
     				attrib_to_stat(a, &sb);
    -			lname = ls_file(fname, &sb, 1);
    +			lname = ls_file(fname, &sb, 1, (lflag & LS_SI_UNITS));
     			printf("%s\n", lname);
     			xfree(lname);
     		} else {
    @@ -848,19 +861,19 @@ do_df(struct sftp_conn *conn, char *path, int hflag, int iflag)
     	char s_avail[FMT_SCALED_STRSIZE];
     	char s_root[FMT_SCALED_STRSIZE];
     	char s_total[FMT_SCALED_STRSIZE];
    +	unsigned long long ffree;
     
     	if (do_statvfs(conn, path, &st, 1) == -1)
     		return -1;
     	if (iflag) {
    +		ffree = st.f_files ? (100 * (st.f_files - st.f_ffree) / st.f_files) : 0;
     		printf("     Inodes        Used       Avail      "
     		    "(root)    %%Capacity\n");
     		printf("%11llu %11llu %11llu %11llu         %3llu%%\n",
     		    (unsigned long long)st.f_files,
     		    (unsigned long long)(st.f_files - st.f_ffree),
     		    (unsigned long long)st.f_favail,
    -		    (unsigned long long)st.f_ffree,
    -		    (unsigned long long)(100 * (st.f_files - st.f_ffree) /
    -		    st.f_files));
    +		    (unsigned long long)st.f_ffree, ffree);
     	} else if (hflag) {
     		strlcpy(s_used, "error", sizeof(s_used));
     		strlcpy(s_avail, "error", sizeof(s_avail));
    @@ -934,12 +947,23 @@ undo_glob_escape(char *s)
      * Split a string into an argument vector using sh(1)-style quoting,
      * comment and escaping rules, but with some tweaks to handle glob(3)
      * wildcards.
    + * The "sloppy" flag allows for recovery from missing terminating quote, for
    + * use in parsing incomplete commandlines during tab autocompletion.
    + *
      * Returns NULL on error or a NULL-terminated array of arguments.
    + *
    + * If "lastquote" is not NULL, the quoting character used for the last
    + * argument is placed in *lastquote ("\0", "'" or "\"").
    + * 
    + * If "terminated" is not NULL, *terminated will be set to 1 when the
    + * last argument's quote has been properly terminated or 0 otherwise.
    + * This parameter is only of use if "sloppy" is set.
      */
     #define MAXARGS 	128
     #define MAXARGLEN	8192
     static char **
    -makeargv(const char *arg, int *argcp)
    +makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
    +    u_int *terminated)
     {
     	int argc, quot;
     	size_t i, j;
    @@ -953,6 +977,10 @@ makeargv(const char *arg, int *argcp)
     		error("string too long");
     		return NULL;
     	}
    +	if (terminated != NULL)
    +		*terminated = 1;
    +	if (lastquote != NULL)
    +		*lastquote = '\0';
     	state = MA_START;
     	i = j = 0;
     	for (;;) {
    @@ -969,6 +997,8 @@ makeargv(const char *arg, int *argcp)
     			if (state == MA_START) {
     				argv[argc] = argvs + j;
     				state = q;
    +				if (lastquote != NULL)
    +					*lastquote = arg[i];
     			} else if (state == MA_UNQUOTED) 
     				state = q;
     			else if (state == q)
    @@ -1005,6 +1035,8 @@ makeargv(const char *arg, int *argcp)
     				if (state == MA_START) {
     					argv[argc] = argvs + j;
     					state = MA_UNQUOTED;
    +					if (lastquote != NULL)
    +						*lastquote = '\0';
     				}
     				if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
     				    arg[i + 1] == '*' || arg[i + 1] == '\\') {
    @@ -1030,6 +1062,12 @@ makeargv(const char *arg, int *argcp)
     				goto string_done;
     		} else if (arg[i] == '\0') {
     			if (state == MA_SQUOTE || state == MA_DQUOTE) {
    +				if (sloppy) {
    +					state = MA_UNQUOTED;
    +					if (terminated != NULL)
    +						*terminated = 0;
    +					goto string_done;
    +				}
     				error("Unterminated quoted argument");
     				return NULL;
     			}
    @@ -1043,6 +1081,8 @@ makeargv(const char *arg, int *argcp)
     			if (state == MA_START) {
     				argv[argc] = argvs + j;
     				state = MA_UNQUOTED;
    +				if (lastquote != NULL)
    +					*lastquote = '\0';
     			}
     			if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
     			    (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
    @@ -1065,8 +1105,8 @@ makeargv(const char *arg, int *argcp)
     }
     
     static int
    -parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag,
    -    unsigned long *n_arg, char **path1, char **path2)
    +parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
    +    int *hflag, unsigned long *n_arg, char **path1, char **path2)
     {
     	const char *cmd, *cp = *cpp;
     	char *cp2, **argv;
    @@ -1077,18 +1117,19 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag,
     	/* Skip leading whitespace */
     	cp = cp + strspn(cp, WHITESPACE);
     
    -	/* Ignore blank lines and lines which begin with comment '#' char */
    -	if (*cp == '\0' || *cp == '#')
    -		return (0);
    -
     	/* Check for leading '-' (disable error processing) */
     	*iflag = 0;
     	if (*cp == '-') {
     		*iflag = 1;
     		cp++;
    +		cp = cp + strspn(cp, WHITESPACE);
     	}
     
    -	if ((argv = makeargv(cp, &argc)) == NULL)
    +	/* Ignore blank lines and lines which begin with comment '#' char */
    +	if (*cp == '\0' || *cp == '#')
    +		return (0);
    +
    +	if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL)
     		return -1;
     
     	/* Figure out which command we have */
    @@ -1109,13 +1150,13 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag,
     	}
     
     	/* Get arguments and parse flags */
    -	*lflag = *pflag = *hflag = *n_arg = 0;
    +	*lflag = *pflag = *rflag = *hflag = *n_arg = 0;
     	*path1 = *path2 = NULL;
     	optidx = 1;
     	switch (cmdnum) {
     	case I_GET:
     	case I_PUT:
    -		if ((optidx = parse_getput_flags(cmd, argv, argc, pflag)) == -1)
    +		if ((optidx = parse_getput_flags(cmd, argv, argc, pflag, rflag)) == -1)
     			return -1;
     		/* Get first pathname (mandatory) */
     		if (argc - optidx < 1) {
    @@ -1235,7 +1276,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
         int err_abort)
     {
     	char *path1, *path2, *tmp;
    -	int pflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i;
    +	int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i;
     	unsigned long n_arg = 0;
     	Attrib a, *aa;
     	char path_buf[MAXPATHLEN];
    @@ -1243,7 +1284,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
     	glob_t g;
     
     	path1 = path2 = NULL;
    -	cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &hflag, &n_arg,
    +	cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, &n_arg,
     	    &path1, &path2);
     
     	if (iflag != 0)
    @@ -1261,10 +1302,10 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
     		err = -1;
     		break;
     	case I_GET:
    -		err = process_get(conn, path1, path2, *pwd, pflag);
    +		err = process_get(conn, path1, path2, *pwd, pflag, rflag);
     		break;
     	case I_PUT:
    -		err = process_put(conn, path1, path2, *pwd, pflag);
    +		err = process_put(conn, path1, path2, *pwd, pflag, rflag);
     		break;
     	case I_RENAME:
     		path1 = make_absolute(path1, *pwd);
    @@ -1290,7 +1331,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
     		attrib_clear(&a);
     		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
     		a.perm = 0777;
    -		err = do_mkdir(conn, path1, &a);
    +		err = do_mkdir(conn, path1, &a, 1);
     		break;
     	case I_RMDIR:
     		path1 = make_absolute(path1, *pwd);
    @@ -1468,21 +1509,352 @@ prompt(EditLine *el)
     {
     	return ("sftp> ");
     }
    -#endif
    +
    +/* Display entries in 'list' after skipping the first 'len' chars */
    +static void
    +complete_display(char **list, u_int len)
    +{
    +	u_int y, m = 0, width = 80, columns = 1, colspace = 0, llen;
    +	struct winsize ws;
    +	char *tmp;
    +
    +	/* Count entries for sort and find longest */
    +	for (y = 0; list[y]; y++) 
    +		m = MAX(m, strlen(list[y]));
    +
    +	if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
    +		width = ws.ws_col;
    +
    +	m = m > len ? m - len : 0;
    +	columns = width / (m + 2);
    +	columns = MAX(columns, 1);
    +	colspace = width / columns;
    +	colspace = MIN(colspace, width);
    +
    +	printf("\n");
    +	m = 1;
    +	for (y = 0; list[y]; y++) {
    +		llen = strlen(list[y]);
    +		tmp = llen > len ? list[y] + len : "";
    +		printf("%-*s", colspace, tmp);
    +		if (m >= columns) {
    +			printf("\n");
    +			m = 1;
    +		} else
    +			m++;
    +	}
    +	printf("\n");
    +}
    +
    +/*
    + * Given a "list" of words that begin with a common prefix of "word",
    + * attempt to find an autocompletion to extends "word" by the next
    + * characters common to all entries in "list".
    + */
    +static char *
    +complete_ambiguous(const char *word, char **list, size_t count)
    +{
    +	if (word == NULL)
    +		return NULL;
    +
    +	if (count > 0) {
    +		u_int y, matchlen = strlen(list[0]);
    +
    +		/* Find length of common stem */
    +		for (y = 1; list[y]; y++) {
    +			u_int x;
    +
    +			for (x = 0; x < matchlen; x++) 
    +				if (list[0][x] != list[y][x]) 
    +					break;
    +
    +			matchlen = x;
    +		}
    +
    +		if (matchlen > strlen(word)) {
    +			char *tmp = xstrdup(list[0]);
    +
    +			tmp[matchlen] = '\0';
    +			return tmp;
    +		}
    +	} 
    +
    +	return xstrdup(word);
    +}
    +
    +/* Autocomplete a sftp command */
    +static int
    +complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote,
    +    int terminated)
    +{
    +	u_int y, count = 0, cmdlen, tmplen;
    +	char *tmp, **list, argterm[3];
    +	const LineInfo *lf;
    +
    +	list = xcalloc((sizeof(cmds) / sizeof(*cmds)) + 1, sizeof(char *));
    +
    +	/* No command specified: display all available commands */
    +	if (cmd == NULL) {
    +		for (y = 0; cmds[y].c; y++)
    +			list[count++] = xstrdup(cmds[y].c);
    +		
    +		list[count] = NULL;
    +		complete_display(list, 0);
    +
    +		for (y = 0; list[y] != NULL; y++)  
    +			xfree(list[y]);	
    +		xfree(list);
    +		return count;
    +	}
    +
    +	/* Prepare subset of commands that start with "cmd" */
    +	cmdlen = strlen(cmd);
    +	for (y = 0; cmds[y].c; y++)  {
    +		if (!strncasecmp(cmd, cmds[y].c, cmdlen)) 
    +			list[count++] = xstrdup(cmds[y].c);
    +	}
    +	list[count] = NULL;
    +
    +	if (count == 0)
    +		return 0;
    +
    +	/* Complete ambigious command */
    +	tmp = complete_ambiguous(cmd, list, count);
    +	if (count > 1)
    +		complete_display(list, 0);
    +
    +	for (y = 0; list[y]; y++)  
    +		xfree(list[y]);	
    +	xfree(list);
    +
    +	if (tmp != NULL) {
    +		tmplen = strlen(tmp);
    +		cmdlen = strlen(cmd);
    +		/* If cmd may be extended then do so */
    +		if (tmplen > cmdlen)
    +			if (el_insertstr(el, tmp + cmdlen) == -1)
    +				fatal("el_insertstr failed.");
    +		lf = el_line(el);
    +		/* Terminate argument cleanly */
    +		if (count == 1) {
    +			y = 0;
    +			if (!terminated)
    +				argterm[y++] = quote;
    +			if (lastarg || *(lf->cursor) != ' ')
    +				argterm[y++] = ' ';
    +			argterm[y] = '\0';
    +			if (y > 0 && el_insertstr(el, argterm) == -1)
    +				fatal("el_insertstr failed.");
    +		}
    +		xfree(tmp);
    +	}
    +
    +	return count;
    +}
    +
    +/*
    + * Determine whether a particular sftp command's arguments (if any)
    + * represent local or remote files.
    + */
    +static int
    +complete_is_remote(char *cmd) {
    +	int i;
    +
    +	if (cmd == NULL)
    +		return -1;
    +
    +	for (i = 0; cmds[i].c; i++) {
    +		if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) 
    +			return cmds[i].t;
    +	}
    +
    +	return -1;
    +}
    +
    +/* Autocomplete a filename "file" */
    +static int
    +complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
    +    char *file, int remote, int lastarg, char quote, int terminated)
    +{
    +	glob_t g;
    +	char *tmp, *tmp2, ins[3];
    +	u_int i, hadglob, pwdlen, len, tmplen, filelen;
    +	const LineInfo *lf;
    +	
    +	/* Glob from "file" location */
    +	if (file == NULL)
    +		tmp = xstrdup("*");
    +	else
    +		xasprintf(&tmp, "%s*", file);
    +
    +	memset(&g, 0, sizeof(g));
    +	if (remote != LOCAL) {
    +		tmp = make_absolute(tmp, remote_path);
    +		remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
    +	} else 
    +		glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
    +	
    +	/* Determine length of pwd so we can trim completion display */
    +	for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) {
    +		/* Terminate counting on first unescaped glob metacharacter */
    +		if (tmp[tmplen] == '*' || tmp[tmplen] == '?') {
    +			if (tmp[tmplen] != '*' || tmp[tmplen + 1] != '\0')
    +				hadglob = 1;
    +			break;
    +		}
    +		if (tmp[tmplen] == '\\' && tmp[tmplen + 1] != '\0')
    +			tmplen++;
    +		if (tmp[tmplen] == '/')
    +			pwdlen = tmplen + 1;	/* track last seen '/' */
    +	}
    +	xfree(tmp);
    +
    +	if (g.gl_matchc == 0) 
    +		goto out;
    +
    +	if (g.gl_matchc > 1)
    +		complete_display(g.gl_pathv, pwdlen);
    +
    +	tmp = NULL;
    +	/* Don't try to extend globs */
    +	if (file == NULL || hadglob)
    +		goto out;
    +
    +	tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc);
    +	tmp = path_strip(tmp2, remote_path);
    +	xfree(tmp2);
    +
    +	if (tmp == NULL)
    +		goto out;
    +
    +	tmplen = strlen(tmp);
    +	filelen = strlen(file);
    +
    +	if (tmplen > filelen)  {
    +		tmp2 = tmp + filelen;
    +		len = strlen(tmp2); 
    +		/* quote argument on way out */
    +		for (i = 0; i < len; i++) {
    +			ins[0] = '\\';
    +			ins[1] = tmp2[i];
    +			ins[2] = '\0';
    +			switch (tmp2[i]) {
    +			case '\'':
    +			case '"':
    +			case '\\':
    +			case '\t':
    +			case ' ':
    +				if (quote == '\0' || tmp2[i] == quote) {
    +					if (el_insertstr(el, ins) == -1)
    +						fatal("el_insertstr "
    +						    "failed.");
    +					break;
    +				}
    +				/* FALLTHROUGH */
    +			default:
    +				if (el_insertstr(el, ins + 1) == -1)
    +					fatal("el_insertstr failed.");
    +				break;
    +			}
    +		}
    +	}
    +
    +	lf = el_line(el);
    +	if (g.gl_matchc == 1) {
    +		i = 0;
    +		if (!terminated)
    +			ins[i++] = quote;
    +		if (*(lf->cursor - 1) != '/' &&
    +		    (lastarg || *(lf->cursor) != ' '))
    +			ins[i++] = ' ';
    +		ins[i] = '\0';
    +		if (i > 0 && el_insertstr(el, ins) == -1)
    +			fatal("el_insertstr failed.");
    +	}
    +	xfree(tmp);
    +
    + out:
    +	globfree(&g);
    +	return g.gl_matchc;
    +}
    +
    +/* tab-completion hook function, called via libedit */
    +static unsigned char
    +complete(EditLine *el, int ch)
    +{
    +	char **argv, *line, quote; 
    +	u_int argc, carg, cursor, len, terminated, ret = CC_ERROR;
    +	const LineInfo *lf;
    +	struct complete_ctx *complete_ctx;
    +
    +	lf = el_line(el);
    +	if (el_get(el, EL_CLIENTDATA, (void**)&complete_ctx) != 0)
    +		fatal("%s: el_get failed", __func__);
    +
    +	/* Figure out which argument the cursor points to */
    +	cursor = lf->cursor - lf->buffer;
    +	line = (char *)xmalloc(cursor + 1);
    +	memcpy(line, lf->buffer, cursor);
    +	line[cursor] = '\0';
    +	argv = makeargv(line, &carg, 1, "e, &terminated);
    +	xfree(line);
    +
    +	/* Get all the arguments on the line */
    +	len = lf->lastchar - lf->buffer;
    +	line = (char *)xmalloc(len + 1);
    +	memcpy(line, lf->buffer, len);
    +	line[len] = '\0';
    +	argv = makeargv(line, &argc, 1, NULL, NULL);
    +
    +	/* Ensure cursor is at EOL or a argument boundary */
    +	if (line[cursor] != ' ' && line[cursor] != '\0' &&
    +	    line[cursor] != '\n') {
    +		xfree(line);
    +		return ret;
    +	}
    +
    +	if (carg == 0) {
    +		/* Show all available commands */
    +		complete_cmd_parse(el, NULL, argc == carg, '\0', 1);
    +		ret = CC_REDISPLAY;
    +	} else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ')  {
    +		/* Handle the command parsing */
    +		if (complete_cmd_parse(el, argv[0], argc == carg,
    +		    quote, terminated) != 0) 
    +			ret = CC_REDISPLAY;
    +	} else if (carg >= 1) {
    +		/* Handle file parsing */
    +		int remote = complete_is_remote(argv[0]);
    +		char *filematch = NULL;
    +
    +		if (carg > 1 && line[cursor-1] != ' ')
    +			filematch = argv[carg - 1];
    +
    +		if (remote != 0 &&
    +		    complete_match(el, complete_ctx->conn,
    +		    *complete_ctx->remote_pathp, filematch,
    +		    remote, carg == argc, quote, terminated) != 0) 
    +			ret = CC_REDISPLAY;
    +	}
    +
    +	xfree(line);	
    +	return ret;
    +}
    +#endif /* USE_LIBEDIT */
     
     int
    -interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
    +interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
     {
    -	char *pwd;
    +	char *remote_path;
     	char *dir = NULL;
     	char cmd[2048];
    -	struct sftp_conn *conn;
     	int err, interactive;
     	EditLine *el = NULL;
     #ifdef USE_LIBEDIT
     	History *hl = NULL;
     	HistEvent hev;
     	extern char *__progname;
    +	struct complete_ctx complete_ctx;
     
     	if (!batchmode && isatty(STDIN_FILENO)) {
     		if ((el = el_init(__progname, stdin, stdout, stderr)) == NULL)
    @@ -1497,27 +1869,32 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
     		el_set(el, EL_TERMINAL, NULL);
     		el_set(el, EL_SIGNAL, 1);
     		el_source(el, NULL);
    +
    +		/* Tab Completion */
    +		el_set(el, EL_ADDFN, "ftp-complete", 
    +		    "Context senstive argument completion", complete);
    +		complete_ctx.conn = conn;
    +		complete_ctx.remote_pathp = &remote_path;
    +		el_set(el, EL_CLIENTDATA, (void*)&complete_ctx);
    +		el_set(el, EL_BIND, "^I", "ftp-complete", NULL);
     	}
     #endif /* USE_LIBEDIT */
     
    -	conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
    -	if (conn == NULL)
    -		fatal("Couldn't initialise connection to server");
    -
    -	pwd = do_realpath(conn, ".");
    -	if (pwd == NULL)
    +	remote_path = do_realpath(conn, ".");
    +	if (remote_path == NULL)
     		fatal("Need cwd");
     
     	if (file1 != NULL) {
     		dir = xstrdup(file1);
    -		dir = make_absolute(dir, pwd);
    +		dir = make_absolute(dir, remote_path);
     
     		if (remote_is_dir(conn, dir) && file2 == NULL) {
     			printf("Changing to: %s\n", dir);
     			snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
    -			if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0) {
    +			if (parse_dispatch_command(conn, cmd,
    +			    &remote_path, 1) != 0) {
     				xfree(dir);
    -				xfree(pwd);
    +				xfree(remote_path);
     				xfree(conn);
     				return (-1);
     			}
    @@ -1528,9 +1905,10 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
     				snprintf(cmd, sizeof cmd, "get %s %s", dir,
     				    file2);
     
    -			err = parse_dispatch_command(conn, cmd, &pwd, 1);
    +			err = parse_dispatch_command(conn, cmd,
    +			    &remote_path, 1);
     			xfree(dir);
    -			xfree(pwd);
    +			xfree(remote_path);
     			xfree(conn);
     			return (err);
     		}
    @@ -1571,7 +1949,8 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
     			const char *line;
     			int count = 0;
     
    -			if ((line = el_gets(el, &count)) == NULL || count <= 0) {
    +			if ((line = el_gets(el, &count)) == NULL ||
    +			    count <= 0) {
     				printf("\n");
      				break;
     			}
    @@ -1591,11 +1970,12 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
     		interrupted = 0;
     		signal(SIGINT, cmd_interrupt);
     
    -		err = parse_dispatch_command(conn, cmd, &pwd, batchmode);
    +		err = parse_dispatch_command(conn, cmd, &remote_path,
    +		    batchmode);
     		if (err != 0)
     			break;
     	}
    -	xfree(pwd);
    +	xfree(remote_path);
     	xfree(conn);
     
     #ifdef USE_LIBEDIT
    @@ -1647,9 +2027,11 @@ connect_to_server(char *path, char **args, int *in, int *out)
     		 * The underlying ssh is in the same process group, so we must
     		 * ignore SIGINT if we want to gracefully abort commands,
     		 * otherwise the signal will make it to the ssh process and
    -		 * kill it too
    +		 * kill it too.  Contrawise, since sftp sends SIGTERMs to the
    +		 * underlying ssh, it must *not* ignore that signal.
     		 */
     		signal(SIGINT, SIG_IGN);
    +		signal(SIGTERM, SIG_DFL);
     		execvp(path, args);
     		fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
     		_exit(1);
    @@ -1668,12 +2050,16 @@ usage(void)
     	extern char *__progname;
     
     	fprintf(stderr,
    -	    "usage: %s [-1Cv] [-B buffer_size] [-b batchfile] [-F ssh_config]\n"
    -	    "            [-o ssh_option] [-P sftp_server_path] [-R num_requests]\n"
    -	    "            [-S program] [-s subsystem | sftp_server] host\n"
    +	    "usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
    +	    "          [-D sftp_server_path] [-F ssh_config] "
    +	    "[-i identity_file]\n"
    +	    "          [-o ssh_option] [-P port] [-R num_requests] "
    +	    "[-S program]\n"
    +	    "          [-s subsystem | sftp_server] host\n"
     	    "       %s [user@]host[:file ...]\n"
     	    "       %s [user@]host[:dir[/]]\n"
    -	    "       %s -b batchfile [user@]host\n", __progname, __progname, __progname, __progname);
    +	    "       %s -b batchfile [user@]host\n",
    +	    __progname, __progname, __progname, __progname);
     	exit(1);
     }
     
    @@ -1681,7 +2067,7 @@ int
     main(int argc, char **argv)
     {
     	int in, out, ch, err;
    -	char *host, *userhost, *cp, *file2 = NULL;
    +	char *host = NULL, *userhost, *cp, *file2 = NULL;
     	int debug_level = 0, sshver = 2;
     	char *file1 = NULL, *sftp_server = NULL;
     	char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
    @@ -1689,6 +2075,9 @@ main(int argc, char **argv)
     	arglist args;
     	extern int optind;
     	extern char *optarg;
    +	struct sftp_conn *conn;
    +	size_t copy_buffer_len = DEFAULT_COPY_BUFLEN;
    +	size_t num_requests = DEFAULT_NUM_REQUESTS;
     
     	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
     	sanitise_stdfd();
    @@ -1705,10 +2094,29 @@ main(int argc, char **argv)
     	ll = SYSLOG_LEVEL_INFO;
     	infile = stdin;
     
    -	while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:")) != -1) {
    +	while ((ch = getopt(argc, argv,
    +	    "1246hpqrvCc:D:i:o:s:S:b:B:F:P:R:")) != -1) {
     		switch (ch) {
    +		/* Passed through to ssh(1) */
    +		case '4':
    +		case '6':
     		case 'C':
    -			addargs(&args, "-C");
    +			addargs(&args, "-%c", ch);
    +			break;
    +		/* Passed through to ssh(1) with argument */
    +		case 'F':
    +		case 'c':
    +		case 'i':
    +		case 'o':
    +			addargs(&args, "-%c", ch);
    +			addargs(&args, "%s", optarg);
    +			break;
    +		case 'q':
    +			showprogress = 0;
    +			addargs(&args, "-%c", ch);
    +			break;
    +		case 'P':
    +			addargs(&args, "-oPort %s", optarg);
     			break;
     		case 'v':
     			if (debug_level < 3) {
    @@ -1717,21 +2125,18 @@ main(int argc, char **argv)
     			}
     			debug_level++;
     			break;
    -		case 'F':
    -		case 'o':
    -			addargs(&args, "-%c%s", ch, optarg);
    -			break;
     		case '1':
     			sshver = 1;
     			if (sftp_server == NULL)
     				sftp_server = _PATH_SFTP_SERVER;
     			break;
    -		case 's':
    -			sftp_server = optarg;
    +		case '2':
    +			sshver = 2;
     			break;
    -		case 'S':
    -			ssh_program = optarg;
    -			replacearg(&args, 0, "%s", ssh_program);
    +		case 'B':
    +			copy_buffer_len = strtol(optarg, &cp, 10);
    +			if (copy_buffer_len == 0 || *cp != '\0')
    +				fatal("Invalid buffer size \"%s\"", optarg);
     			break;
     		case 'b':
     			if (batchmode)
    @@ -1745,13 +2150,14 @@ main(int argc, char **argv)
     			batchmode = 1;
     			addargs(&args, "-obatchmode yes");
     			break;
    -		case 'P':
    +		case 'p':
    +			global_pflag = 1;
    +			break;
    +		case 'D':
     			sftp_direct = optarg;
     			break;
    -		case 'B':
    -			copy_buffer_len = strtol(optarg, &cp, 10);
    -			if (copy_buffer_len == 0 || *cp != '\0')
    -				fatal("Invalid buffer size \"%s\"", optarg);
    +		case 'r':
    +			global_rflag = 1;
     			break;
     		case 'R':
     			num_requests = strtol(optarg, &cp, 10);
    @@ -1759,6 +2165,13 @@ main(int argc, char **argv)
     				fatal("Invalid number of requests \"%s\"",
     				    optarg);
     			break;
    +		case 's':
    +			sftp_server = optarg;
    +			break;
    +		case 'S':
    +			ssh_program = optarg;
    +			replacearg(&args, 0, "%s", ssh_program);
    +			break;
     		case 'h':
     		default:
     			usage();
    @@ -1785,7 +2198,8 @@ main(int argc, char **argv)
     				fprintf(stderr, "Missing username\n");
     				usage();
     			}
    -			addargs(&args, "-l%s", userhost);
    +			addargs(&args, "-l");
    +			addargs(&args, "%s", userhost);
     		}
     
     		if ((cp = colon(host)) != NULL) {
    @@ -1805,24 +2219,32 @@ main(int argc, char **argv)
     		if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
     			addargs(&args, "-s");
     
    +		addargs(&args, "--");
     		addargs(&args, "%s", host);
     		addargs(&args, "%s", (sftp_server != NULL ?
     		    sftp_server : "sftp"));
     
    -		if (!batchmode)
    -			fprintf(stderr, "Connecting to %s...\n", host);
     		connect_to_server(ssh_program, args.list, &in, &out);
     	} else {
     		args.list = NULL;
     		addargs(&args, "sftp-server");
     
    -		if (!batchmode)
    -			fprintf(stderr, "Attaching to %s...\n", sftp_direct);
     		connect_to_server(sftp_direct, args.list, &in, &out);
     	}
     	freeargs(&args);
     
    -	err = interactive_loop(in, out, file1, file2);
    +	conn = do_init(in, out, copy_buffer_len, num_requests);
    +	if (conn == NULL)
    +		fatal("Couldn't initialise connection to server");
    +
    +	if (!batchmode) {
    +		if (sftp_direct == NULL)
    +			fprintf(stderr, "Connected to %s.\n", host);
    +		else
    +			fprintf(stderr, "Attached to %s.\n", sftp_direct);
    +	}
    +
    +	err = interactive_loop(conn, file1, file2);
     
     #if !defined(USE_PIPES)
     	shutdown(in, SHUT_RDWR);
    diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1
    index 464070ec552..1eb34f33de9 100644
    --- a/crypto/openssh/ssh-add.1
    +++ b/crypto/openssh/ssh-add.1
    @@ -1,4 +1,4 @@
    -.\"	$OpenBSD: ssh-add.1,v 1.46 2007/06/12 13:41:03 jmc Exp $
    +.\"	$OpenBSD: ssh-add.1,v 1.52 2010/03/05 10:28:21 djm Exp $
     .\"
     .\"  -*- nroff -*-
     .\"
    @@ -37,7 +37,7 @@
     .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     .\"
    -.Dd June 12 2007
    +.Dd March 5 2010
     .Dt SSH-ADD 1
     .Os
     .Sh NAME
    @@ -49,9 +49,9 @@
     .Op Fl t Ar life
     .Op Ar
     .Nm ssh-add
    -.Fl s Ar reader
    +.Fl s Ar pkcs11
     .Nm ssh-add
    -.Fl e Ar reader
    +.Fl e Ar pkcs11
     .Sh DESCRIPTION
     .Nm
     adds RSA or DSA identities to the authentication agent,
    @@ -61,7 +61,14 @@ When run without arguments, it adds the files
     .Pa ~/.ssh/id_dsa
     and
     .Pa ~/.ssh/identity .
    +After loading a private key,
    +.Nm
    +will try to load corresponding certificate information from the
    +filename obtained by appending
    +.Pa -cert.pub
    +to the name of the private key file.
     Alternative file names can be given on the command line.
    +.Pp
     If any file requires a passphrase,
     .Nm
     asks for the passphrase from the user.
    @@ -101,17 +108,17 @@ If no public key is found at a given path,
     will append
     .Pa .pub
     and retry.
    -.It Fl e Ar reader
    -Remove key in smartcard
    -.Ar reader .
    +.It Fl e Ar pkcs11
    +Remove keys provided by the PKCS#11 shared library
    +.Ar pkcs11 .
     .It Fl L
     Lists public key parameters of all identities currently represented
     by the agent.
     .It Fl l
     Lists fingerprints of all identities currently represented by the agent.
    -.It Fl s Ar reader
    -Add key in smartcard
    -.Ar reader .
    +.It Fl s Ar pkcs11
    +Add keys provided by the PKCS#11 shared library
    +.Ar pkcs11 .
     .It Fl t Ar life
     Set a maximum lifetime when adding identities to an agent.
     The lifetime may be specified in seconds or in a time format
    @@ -148,8 +155,9 @@ may be necessary to redirect the input from
     .Pa /dev/null
     to make this work.)
     .It Ev SSH_AUTH_SOCK
    -Identifies the path of a unix-domain socket used to communicate with the
    -agent.
    +Identifies the path of a
    +.Ux Ns -domain
    +socket used to communicate with the agent.
     .El
     .Sh FILES
     .Bl -tag -width Ds
    diff --git a/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c
    index 7a43282f2d9..ad9f7a83e40 100644
    --- a/crypto/openssh/ssh-add.c
    +++ b/crypto/openssh/ssh-add.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: ssh-add.c,v 1.90 2007/09/09 11:38:01 sobrado Exp $ */
    +/* $OpenBSD: ssh-add.c,v 1.94 2010/03/01 11:07:06 otto Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -138,9 +138,9 @@ delete_all(AuthenticationConnection *ac)
     static int
     add_file(AuthenticationConnection *ac, const char *filename)
     {
    -	Key *private;
    +	Key *private, *cert;
     	char *comment = NULL;
    -	char msg[1024];
    +	char msg[1024], *certpath;
     	int fd, perms_ok, ret = -1;
     
     	if ((fd = open(filename, O_RDONLY)) < 0) {
    @@ -195,13 +195,37 @@ add_file(AuthenticationConnection *ac, const char *filename)
     		if (confirm != 0)
     			fprintf(stderr,
     			    "The user has to confirm each use of the key\n");
    -	} else if (ssh_add_identity(ac, private, comment)) {
    -		fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
    -		ret = 0;
     	} else {
     		fprintf(stderr, "Could not add identity: %s\n", filename);
     	}
     
    +
    +	/* Now try to add the certificate flavour too */
    +	xasprintf(&certpath, "%s-cert.pub", filename);
    +	if ((cert = key_load_public(certpath, NULL)) != NULL) {
    +		/* Graft with private bits */
    +		if (key_to_certified(private) != 0)
    +			fatal("%s: key_to_certified failed", __func__);
    +		key_cert_copy(cert, private);
    +		key_free(cert);
    +
    +		if (ssh_add_identity_constrained(ac, private, comment,
    +		    lifetime, confirm)) {
    +			fprintf(stderr, "Certificate added: %s (%s)\n",
    +			    certpath, private->cert->key_id);
    +			if (lifetime != 0)
    +				fprintf(stderr, "Lifetime set to %d seconds\n",
    +				    lifetime);
    +			if (confirm != 0)
    +				fprintf(stderr, "The user has to confirm each "
    +				    "use of the key\n");
    +		} else {
    +			error("Certificate %s (%s) add failed", certpath,
    +			    private->cert->key_id);
    +		}
    +	}
    +
    +	xfree(certpath);
     	xfree(comment);
     	key_free(private);
     
    @@ -214,7 +238,7 @@ update_card(AuthenticationConnection *ac, int add, const char *id)
     	char *pin;
     	int ret = -1;
     
    -	pin = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
    +	pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN);
     	if (pin == NULL)
     		return -1;
     
    @@ -320,10 +344,8 @@ usage(void)
     	fprintf(stderr, "  -X          Unlock agent.\n");
     	fprintf(stderr, "  -t life     Set lifetime (in seconds) when adding identities.\n");
     	fprintf(stderr, "  -c          Require confirmation to sign using identities\n");
    -#ifdef SMARTCARD
    -	fprintf(stderr, "  -s reader   Add key in smartcard reader.\n");
    -	fprintf(stderr, "  -e reader   Remove key in smartcard reader.\n");
    -#endif
    +	fprintf(stderr, "  -s pkcs11   Add keys from PKCS#11 provider.\n");
    +	fprintf(stderr, "  -e pkcs11   Remove keys provided by PKCS#11 provider.\n");
     }
     
     int
    @@ -332,7 +354,7 @@ main(int argc, char **argv)
     	extern char *optarg;
     	extern int optind;
     	AuthenticationConnection *ac = NULL;
    -	char *sc_reader_id = NULL;
    +	char *pkcs11provider = NULL;
     	int i, ch, deleting = 0, ret = 0;
     
     	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
    @@ -374,11 +396,11 @@ main(int argc, char **argv)
     				ret = 1;
     			goto done;
     		case 's':
    -			sc_reader_id = optarg;
    +			pkcs11provider = optarg;
     			break;
     		case 'e':
     			deleting = 1;
    -			sc_reader_id = optarg;
    +			pkcs11provider = optarg;
     			break;
     		case 't':
     			if ((lifetime = convtime(optarg)) == -1) {
    @@ -395,8 +417,8 @@ main(int argc, char **argv)
     	}
     	argc -= optind;
     	argv += optind;
    -	if (sc_reader_id != NULL) {
    -		if (update_card(ac, !deleting, sc_reader_id) == -1)
    +	if (pkcs11provider != NULL) {
    +		if (update_card(ac, !deleting, pkcs11provider) == -1)
     			ret = 1;
     		goto done;
     	}
    diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1
    index 7ce9dc2ba70..5bcfd8f615f 100644
    --- a/crypto/openssh/ssh-agent.1
    +++ b/crypto/openssh/ssh-agent.1
    @@ -1,4 +1,5 @@
    -.\" $OpenBSD: ssh-agent.1,v 1.46 2007/09/09 11:38:01 sobrado Exp $
    +.\" $OpenBSD: ssh-agent.1,v 1.50 2010/01/17 21:49:09 tedu Exp $
    +.\" $FreeBSD$
     .\"
     .\" Author: Tatu Ylonen 
     .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -34,7 +35,7 @@
     .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     .\"
    -.Dd June 5 2007
    +.Dd January 17 2010
     .Dt SSH-AGENT 1
     .Os
     .Sh NAME
    @@ -67,7 +68,9 @@ machines using
     The options are as follows:
     .Bl -tag -width Ds
     .It Fl a Ar bind_address
    -Bind the agent to the unix-domain socket
    +Bind the agent to the
    +.Ux Ns -domain
    +socket
     .Ar bind_address .
     The default is
     .Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt .
    @@ -117,8 +120,9 @@ and
     .Pa ~/.ssh/identity .
     If the identity has a passphrase,
     .Xr ssh-add 1
    -asks for the passphrase (using a small X11 application if running
    -under X11, or from the terminal if running without X).
    +asks for the passphrase on the terminal if it has one or from a small X11
    +program if running under X11.
    +If neither of these is the case then the authentication will fail.
     It then sends the identity to the agent.
     Several identities can be stored in the
     agent; the agent can automatically use any of these identities.
    @@ -141,7 +145,7 @@ The second is that the agent prints the needed shell commands (either
     .Xr sh 1
     or
     .Xr csh 1
    -syntax can be generated) which can be evalled in the calling shell, eg
    +syntax can be generated) which can be evaluated in the calling shell, eg
     .Cm eval `ssh-agent -s`
     for Bourne-type shells such as
     .Xr sh 1
    @@ -162,8 +166,9 @@ Instead, operations that require a private key will be performed
     by the agent, and the result will be returned to the requester.
     This way, private keys are not exposed to clients using the agent.
     .Pp
    -A unix-domain socket is created
    -and the name of this socket is stored in the
    +A
    +.Ux Ns -domain
    +socket is created and the name of this socket is stored in the
     .Ev SSH_AUTH_SOCK
     environment
     variable.
    @@ -186,8 +191,8 @@ Contains the protocol version 2 DSA authentication identity of the user.
     .It Pa ~/.ssh/id_rsa
     Contains the protocol version 2 RSA authentication identity of the user.
     .It Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt
    -Unix-domain sockets used to contain the connection to the
    -authentication agent.
    +.Ux Ns -domain
    +sockets used to contain the connection to the authentication agent.
     These sockets should only be readable by the owner.
     The sockets should get automatically removed when the agent exits.
     .El
    diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c
    index ef62f196b48..320591bf91e 100644
    --- a/crypto/openssh/ssh-agent.c
    +++ b/crypto/openssh/ssh-agent.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: ssh-agent.c,v 1.159 2008/06/28 14:05:15 djm Exp $ */
    +/* $OpenBSD: ssh-agent.c,v 1.165 2010/02/26 20:29:54 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -77,8 +77,8 @@ __RCSID("$FreeBSD$");
     #include "log.h"
     #include "misc.h"
     
    -#ifdef SMARTCARD
    -#include "scard.h"
    +#ifdef ENABLE_PKCS11
    +#include "ssh-pkcs11.h"
     #endif
     
     #if defined(HAVE_SYS_PRCTL_H)
    @@ -106,6 +106,7 @@ typedef struct identity {
     	TAILQ_ENTRY(identity) next;
     	Key *key;
     	char *comment;
    +	char *provider;
     	u_int death;
     	u_int confirm;
     } Identity;
    @@ -172,6 +173,8 @@ static void
     free_identity(Identity *id)
     {
     	key_free(id->key);
    +	if (id->provider != NULL)
    +		xfree(id->provider);
     	xfree(id->comment);
     	xfree(id);
     }
    @@ -466,6 +469,8 @@ process_add_identity(SocketEntry *e, int version)
     	int type, success = 0, death = 0, confirm = 0;
     	char *type_name, *comment;
     	Key *k = NULL;
    +	u_char *cert;
    +	u_int len;
     
     	switch (version) {
     	case 1:
    @@ -496,6 +501,14 @@ process_add_identity(SocketEntry *e, int version)
     			buffer_get_bignum2(&e->request, k->dsa->pub_key);
     			buffer_get_bignum2(&e->request, k->dsa->priv_key);
     			break;
    +		case KEY_DSA_CERT:
    +			cert = buffer_get_string(&e->request, &len);
    +			if ((k = key_from_blob(cert, len)) == NULL)
    +				fatal("Certificate parse failed");
    +			xfree(cert);
    +			key_add_private(k);
    +			buffer_get_bignum2(&e->request, k->dsa->priv_key);
    +			break;
     		case KEY_RSA:
     			k = key_new_private(type);
     			buffer_get_bignum2(&e->request, k->rsa->n);
    @@ -508,6 +521,17 @@ process_add_identity(SocketEntry *e, int version)
     			/* Generate additional parameters */
     			rsa_generate_additional_parameters(k->rsa);
     			break;
    +		case KEY_RSA_CERT:
    +			cert = buffer_get_string(&e->request, &len);
    +			if ((k = key_from_blob(cert, len)) == NULL)
    +				fatal("Certificate parse failed");
    +			xfree(cert);
    +			key_add_private(k);
    +			buffer_get_bignum2(&e->request, k->rsa->d);
    +			buffer_get_bignum2(&e->request, k->rsa->iqmp);
    +			buffer_get_bignum2(&e->request, k->rsa->p);
    +			buffer_get_bignum2(&e->request, k->rsa->q);
    +			break;
     		default:
     			buffer_clear(&e->request);
     			goto send;
    @@ -517,6 +541,7 @@ process_add_identity(SocketEntry *e, int version)
     	/* enable blinding */
     	switch (k->type) {
     	case KEY_RSA:
    +	case KEY_RSA_CERT:
     	case KEY_RSA1:
     		if (RSA_blinding_on(k->rsa, NULL) != 1) {
     			error("process_add_identity: RSA_blinding_on failed");
    @@ -550,7 +575,7 @@ process_add_identity(SocketEntry *e, int version)
     	if (lifetime && !death)
     		death = time(NULL) + lifetime;
     	if ((id = lookup_identity(k, version)) == NULL) {
    -		id = xmalloc(sizeof(Identity));
    +		id = xcalloc(1, sizeof(Identity));
     		id->key = k;
     		TAILQ_INSERT_TAIL(&tab->idlist, id, next);
     		/* Increment the number of identities. */
    @@ -610,17 +635,17 @@ no_identities(SocketEntry *e, u_int type)
     	buffer_free(&msg);
     }
     
    -#ifdef SMARTCARD
    +#ifdef ENABLE_PKCS11
     static void
     process_add_smartcard_key(SocketEntry *e)
     {
    -	char *sc_reader_id = NULL, *pin;
    -	int i, type, version, success = 0, death = 0, confirm = 0;
    -	Key **keys, *k;
    +	char *provider = NULL, *pin;
    +	int i, type, version, count = 0, success = 0, death = 0, confirm = 0;
    +	Key **keys = NULL, *k;
     	Identity *id;
     	Idtab *tab;
     
    -	sc_reader_id = buffer_get_string(&e->request, NULL);
    +	provider = buffer_get_string(&e->request, NULL);
     	pin = buffer_get_string(&e->request, NULL);
     
     	while (buffer_len(&e->request)) {
    @@ -634,30 +659,22 @@ process_add_smartcard_key(SocketEntry *e)
     		default:
     			error("process_add_smartcard_key: "
     			    "Unknown constraint type %d", type);
    -			xfree(sc_reader_id);
    -			xfree(pin);
     			goto send;
     		}
     	}
     	if (lifetime && !death)
     		death = time(NULL) + lifetime;
     
    -	keys = sc_get_keys(sc_reader_id, pin);
    -	xfree(sc_reader_id);
    -	xfree(pin);
    -
    -	if (keys == NULL || keys[0] == NULL) {
    -		error("sc_get_keys failed");
    -		goto send;
    -	}
    -	for (i = 0; keys[i] != NULL; i++) {
    +	count = pkcs11_add_provider(provider, pin, &keys);
    +	for (i = 0; i < count; i++) {
     		k = keys[i];
     		version = k->type == KEY_RSA1 ? 1 : 2;
     		tab = idtab_lookup(version);
     		if (lookup_identity(k, version) == NULL) {
    -			id = xmalloc(sizeof(Identity));
    +			id = xcalloc(1, sizeof(Identity));
     			id->key = k;
    -			id->comment = sc_get_key_label(k);
    +			id->provider = xstrdup(provider);
    +			id->comment = xstrdup(provider); /* XXX */
     			id->death = death;
     			id->confirm = confirm;
     			TAILQ_INSERT_TAIL(&tab->idlist, id, next);
    @@ -668,8 +685,13 @@ process_add_smartcard_key(SocketEntry *e)
     		}
     		keys[i] = NULL;
     	}
    -	xfree(keys);
     send:
    +	if (pin)
    +		xfree(pin);
    +	if (provider)
    +		xfree(provider);
    +	if (keys)
    +		xfree(keys);
     	buffer_put_int(&e->output, 1);
     	buffer_put_char(&e->output,
     	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
    @@ -678,42 +700,37 @@ send:
     static void
     process_remove_smartcard_key(SocketEntry *e)
     {
    -	char *sc_reader_id = NULL, *pin;
    -	int i, version, success = 0;
    -	Key **keys, *k = NULL;
    -	Identity *id;
    +	char *provider = NULL, *pin = NULL;
    +	int version, success = 0;
    +	Identity *id, *nxt;
     	Idtab *tab;
     
    -	sc_reader_id = buffer_get_string(&e->request, NULL);
    +	provider = buffer_get_string(&e->request, NULL);
     	pin = buffer_get_string(&e->request, NULL);
    -	keys = sc_get_keys(sc_reader_id, pin);
    -	xfree(sc_reader_id);
     	xfree(pin);
     
    -	if (keys == NULL || keys[0] == NULL) {
    -		error("sc_get_keys failed");
    -		goto send;
    -	}
    -	for (i = 0; keys[i] != NULL; i++) {
    -		k = keys[i];
    -		version = k->type == KEY_RSA1 ? 1 : 2;
    -		if ((id = lookup_identity(k, version)) != NULL) {
    -			tab = idtab_lookup(version);
    -			TAILQ_REMOVE(&tab->idlist, id, next);
    -			tab->nentries--;
    -			free_identity(id);
    -			success = 1;
    +	for (version = 1; version < 3; version++) {
    +		tab = idtab_lookup(version);
    +		for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
    +			nxt = TAILQ_NEXT(id, next);
    +			if (!strcmp(provider, id->provider)) {
    +				TAILQ_REMOVE(&tab->idlist, id, next);
    +				free_identity(id);
    +				tab->nentries--;
    +			}
     		}
    -		key_free(k);
    -		keys[i] = NULL;
     	}
    -	xfree(keys);
    -send:
    +	if (pkcs11_del_provider(provider) == 0)
    +		success = 1;
    +	else
    +		error("process_remove_smartcard_key:"
    +		    " pkcs11_del_provider failed");
    +	xfree(provider);
     	buffer_put_int(&e->output, 1);
     	buffer_put_char(&e->output,
     	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
     }
    -#endif /* SMARTCARD */
    +#endif /* ENABLE_PKCS11 */
     
     /* dispatch incoming messages */
     
    @@ -798,7 +815,7 @@ process_message(SocketEntry *e)
     	case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
     		process_remove_all_identities(e, 2);
     		break;
    -#ifdef SMARTCARD
    +#ifdef ENABLE_PKCS11
     	case SSH_AGENTC_ADD_SMARTCARD_KEY:
     	case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
     		process_add_smartcard_key(e);
    @@ -806,7 +823,7 @@ process_message(SocketEntry *e)
     	case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
     		process_remove_smartcard_key(e);
     		break;
    -#endif /* SMARTCARD */
    +#endif /* ENABLE_PKCS11 */
     	default:
     		/* Unknown message.  Respond with failure. */
     		error("Unknown message %d", type);
    @@ -920,11 +937,11 @@ after_select(fd_set *readset, fd_set *writeset)
     	socklen_t slen;
     	char buf[1024];
     	int len, sock;
    -	u_int i;
    +	u_int i, orig_alloc;
     	uid_t euid;
     	gid_t egid;
     
    -	for (i = 0; i < sockets_alloc; i++)
    +	for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++)
     		switch (sockets[i].type) {
     		case AUTH_UNUSED:
     			break;
    @@ -957,16 +974,13 @@ after_select(fd_set *readset, fd_set *writeset)
     		case AUTH_CONNECTION:
     			if (buffer_len(&sockets[i].output) > 0 &&
     			    FD_ISSET(sockets[i].fd, writeset)) {
    -				do {
    -					len = write(sockets[i].fd,
    -					    buffer_ptr(&sockets[i].output),
    -					    buffer_len(&sockets[i].output));
    -					if (len == -1 && (errno == EAGAIN ||
    -					    errno == EINTR ||
    -					    errno == EWOULDBLOCK))
    -						continue;
    -					break;
    -				} while (1);
    +				len = write(sockets[i].fd,
    +				    buffer_ptr(&sockets[i].output),
    +				    buffer_len(&sockets[i].output));
    +				if (len == -1 && (errno == EAGAIN ||
    +				    errno == EWOULDBLOCK ||
    +				    errno == EINTR))
    +					continue;
     				if (len <= 0) {
     					close_socket(&sockets[i]);
     					break;
    @@ -974,14 +988,11 @@ after_select(fd_set *readset, fd_set *writeset)
     				buffer_consume(&sockets[i].output, len);
     			}
     			if (FD_ISSET(sockets[i].fd, readset)) {
    -				do {
    -					len = read(sockets[i].fd, buf, sizeof(buf));
    -					if (len == -1 && (errno == EAGAIN ||
    -					    errno == EINTR ||
    -					    errno == EWOULDBLOCK))
    -						continue;
    -					break;
    -				} while (1);
    +				len = read(sockets[i].fd, buf, sizeof(buf));
    +				if (len == -1 && (errno == EAGAIN ||
    +				    errno == EWOULDBLOCK ||
    +				    errno == EINTR))
    +					continue;
     				if (len <= 0) {
     					close_socket(&sockets[i]);
     					break;
    @@ -1016,6 +1027,9 @@ static void
     cleanup_handler(int sig)
     {
     	cleanup_socket();
    +#ifdef ENABLE_PKCS11
    +	pkcs11_terminate();
    +#endif
     	_exit(2);
     }
     
    @@ -1062,6 +1076,7 @@ main(int ac, char **av)
     	pid_t pid;
     	char pidstrbuf[1 + 3 * sizeof pid];
     	struct timeval *tvp = NULL;
    +	size_t len;
     
     	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
     	sanitise_stdfd();
    @@ -1123,8 +1138,8 @@ main(int ac, char **av)
     
     	if (ac == 0 && !c_flag && !s_flag) {
     		shell = getenv("SHELL");
    -		if (shell != NULL &&
    -		    strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
    +		if (shell != NULL && (len = strlen(shell)) > 2 &&
    +		    strncmp(shell + len - 3, "csh", 3) == 0)
     			c_flag = 1;
     	}
     	if (k_flag) {
    @@ -1262,6 +1277,10 @@ main(int ac, char **av)
     #endif
     
     skip:
    +
    +#ifdef ENABLE_PKCS11
    +	pkcs11_init(0);
    +#endif
     	new_socket(AUTH_SOCKET, sock);
     	if (ac > 0)
     		parent_alive_interval = 10;
    diff --git a/crypto/openssh/ssh-dss.c b/crypto/openssh/ssh-dss.c
    index 51a06e98fe2..449f493b405 100644
    --- a/crypto/openssh/ssh-dss.c
    +++ b/crypto/openssh/ssh-dss.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: ssh-dss.c,v 1.24 2006/11/06 21:25:28 markus Exp $ */
    +/* $OpenBSD: ssh-dss.c,v 1.25 2010/02/26 20:29:54 djm Exp $ */
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
      *
    @@ -53,7 +53,9 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
     	u_int rlen, slen, len, dlen;
     	Buffer b;
     
    -	if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
    +	if (key == NULL ||
    +	    (key->type != KEY_DSA && key->type != KEY_DSA_CERT) ||
    +	    key->dsa == NULL) {
     		error("ssh_dss_sign: no DSA key");
     		return -1;
     	}
    @@ -116,7 +118,9 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
     	int rlen, ret;
     	Buffer b;
     
    -	if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
    +	if (key == NULL ||
    +	    (key->type != KEY_DSA && key->type != KEY_DSA_CERT) ||
    +	    key->dsa == NULL) {
     		error("ssh_dss_verify: no DSA key");
     		return -1;
     	}
    diff --git a/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1
    index 4247ea13e9b..0da6354d379 100644
    --- a/crypto/openssh/ssh-keygen.1
    +++ b/crypto/openssh/ssh-keygen.1
    @@ -1,4 +1,4 @@
    -.\"	$OpenBSD: ssh-keygen.1,v 1.79 2008/07/24 23:55:30 sthen Exp $
    +.\"	$OpenBSD: ssh-keygen.1,v 1.88 2010/03/08 00:28:55 djm Exp $
     .\"	$FreeBSD$
     .\"
     .\"  -*- nroff -*-
    @@ -38,7 +38,7 @@
     .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     .\"
    -.Dd July 24 2008
    +.Dd March 8 2010
     .Dt SSH-KEYGEN 1
     .Os
     .Sh NAME
    @@ -53,7 +53,6 @@
     .Op Fl N Ar new_passphrase
     .Op Fl C Ar comment
     .Op Fl f Ar output_keyfile
    -.Ek
     .Nm ssh-keygen
     .Fl p
     .Op Fl P Ar old_passphrase
    @@ -80,7 +79,7 @@
     .Fl B
     .Op Fl f Ar input_keyfile
     .Nm ssh-keygen
    -.Fl D Ar reader
    +.Fl D Ar pkcs11
     .Nm ssh-keygen
     .Fl F Ar hostname
     .Op Fl f Ar known_hosts_file
    @@ -92,9 +91,6 @@
     .Fl R Ar hostname
     .Op Fl f Ar known_hosts_file
     .Nm ssh-keygen
    -.Fl U Ar reader
    -.Op Fl f Ar input_keyfile
    -.Nm ssh-keygen
     .Fl r Ar hostname
     .Op Fl f Ar input_keyfile
     .Op Fl g
    @@ -110,6 +106,18 @@
     .Op Fl v
     .Op Fl a Ar num_trials
     .Op Fl W Ar generator
    +.Nm ssh-keygen
    +.Fl s Ar ca_key
    +.Fl I Ar certificate_identity
    +.Op Fl h
    +.Op Fl n Ar principals
    +.Op Fl O Ar constraint
    +.Op Fl V Ar validity_interval
    +.Ar
    +.Nm ssh-keygen
    +.Fl L
    +.Op Fl f Ar input_keyfile
    +.Ek
     .Sh DESCRIPTION
     .Nm
     generates, manages and converts authentication keys for
    @@ -202,9 +210,9 @@ Requests changing the comment in the private and public key files.
     This operation is only supported for RSA1 keys.
     The program will prompt for the file containing the private keys, for
     the passphrase if the key has one, and for the new comment.
    -.It Fl D Ar reader
    -Download the RSA public key stored in the smartcard in
    -.Ar reader .
    +.It Fl D Ar pkcs11
    +Download the RSA public keys provided by the PKCS#11 shared library
    +.Ar pkcs11 .
     .It Fl e
     This option will read a private or public OpenSSH key file and
     print the key in
    @@ -249,6 +257,17 @@ but they do not reveal identifying information should the file's contents
     be disclosed.
     This option will not modify existing hashed hostnames and is therefore safe
     to use on files that mix hashed and non-hashed names.
    +.It Fl h
    +When signing a key, create a host certificate instead of a user
    +certificate.
    +Please see the
    +.Sx CERTIFICATES
    +section for details.
    +.It Fl I Ar certificate_identity
    +Specify the key identity when signing a public key.
    +Please see the
    +.Sx CERTIFICATES
    +section for details.
     .It Fl i
     This option will read an unencrypted private (or public) key file
     in SSH2-compatible format and print an OpenSSH compatible private
    @@ -258,6 +277,8 @@ also reads the
     RFC 4716 SSH Public Key File Format.
     This option allows importing keys from several commercial
     SSH implementations.
    +.It Fl L
    +Prints the contents of a certificate.
     .It Fl l
     Show fingerprint of specified public key file.
     Private RSA1 keys are also supported.
    @@ -272,6 +293,71 @@ Specify the amount of memory to use (in megabytes) when generating
     candidate moduli for DH-GEX.
     .It Fl N Ar new_passphrase
     Provides the new passphrase.
    +.It Fl n Ar principals
    +Specify one or more principals (user or host names) to be included in
    +a certificate when signing a key.
    +Multiple principals may be specified, separated by commas.
    +Please see the
    +.Sx CERTIFICATES
    +section for details.
    +.It Fl O Ar constraint
    +Specify a certificate constraint when signing a key.
    +This option may be specified multiple times.
    +Please see the
    +.Sx CERTIFICATES
    +section for details.
    +The constraints that are valid for user certificates are:
    +.Bl -tag -width Ds
    +.It Ic no-x11-forwarding
    +Disable X11 forwarding (permitted by default).
    +.It Ic no-agent-forwarding
    +Disable
    +.Xr ssh-agent 1
    +forwarding (permitted by default).
    +.It Ic no-port-forwarding
    +Disable port forwarding (permitted by default).
    +.It Ic no-pty
    +Disable PTY allocation (permitted by default).
    +.It Ic no-user-rc
    +Disable execution of
    +.Pa ~/.ssh/rc
    +by
    +.Xr sshd 8
    +(permitted by default).
    +.It Ic clear
    +Clear all enabled permissions.
    +This is useful for clearing the default set of permissions so permissions may
    +be added individually.
    +.It Ic permit-x11-forwarding
    +Allows X11 forwarding.
    +.It Ic permit-agent-forwarding
    +Allows
    +.Xr ssh-agent 1
    +forwarding.
    +.It Ic permit-port-forwarding
    +Allows port forwarding.
    +.It Ic permit-pty
    +Allows PTY allocation.
    +.It Ic permit-user-rc
    +Allows execution of
    +.Pa ~/.ssh/rc
    +by
    +.Xr sshd 8 .
    +.It Ic force-command=command
    +Forces the execution of
    +.Ar command
    +instead of any shell or command specified by the user when
    +the certificate is used for authentication.
    +.It Ic source-address=address_list
    +Restrict the source addresses from which the certificate is considered valid
    +from.
    +The
    +.Ar address_list
    +is a comma-separated list of one or more address/netmask pairs in CIDR
    +format.
    +.El
    +.Pp
    +At present, no constraints are valid for host keys.
     .It Fl P Ar passphrase
     Provides the (old) passphrase.
     .It Fl p
    @@ -301,6 +387,11 @@ Print the SSHFP fingerprint resource record named
     for the specified public key file.
     .It Fl S Ar start
     Specify start point (in hex) when generating candidate moduli for DH-GEX.
    +.It Fl s Ar ca_key
    +Certify (sign) a public key using the specified CA key.
    +Please see the
    +.Sx CERTIFICATES
    +section for details.
     .It Fl T Ar output_file
     Test DH group exchange candidate primes (generated using the
     .Fl G
    @@ -314,9 +405,29 @@ for protocol version 1 and
     or
     .Dq dsa
     for protocol version 2.
    -.It Fl U Ar reader
    -Upload an existing RSA private key into the smartcard in
    -.Ar reader .
    +.It Fl V Ar validity_interval
    +Specify a validity interval when signing a certificate.
    +A validity interval may consist of a single time, indicating that the
    +certificate is valid beginning now and expiring at that time, or may consist
    +of two times separated by a colon to indicate an explicit time interval.
    +The start time may be specified as a date in YYYYMMDD format, a time
    +in YYYYMMDDHHMMSS format or a relative time (to the current time) consisting
    +of a minus sign followed by a relative time in the format described in the
    +.Sx TIME FORMATS
    +section of
    +.Xr ssh_config 5 .
    +The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or
    +a relative time starting with a plus character.
    +.Pp
    +For example:
    +.Dq +52w1d
    +(valid from now to 52 weeks and one day from now),
    +.Dq -4w:+4w
    +(valid from four weeks ago to four weeks from now),
    +.Dq 20100101123000:20110101123000
    +(valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011),
    +.Dq -1d:20110101
    +(valid from yesterday to midnight, January 1st, 2011).
     .It Fl v
     Verbose mode.
     Causes
    @@ -387,6 +498,73 @@ Screened DH groups may be installed in
     .Pa /etc/moduli .
     It is important that this file contains moduli of a range of bit lengths and
     that both ends of a connection share common moduli.
    +.Sh CERTIFICATES
    +.Nm
    +supports signing of keys to produce certificates that may be used for
    +user or host authentication.
    +Certificates consist of a public key, some identity information, zero or
    +more principal (user or host) names and an optional set of constraints that
    +are signed by a Certification Authority (CA) key.
    +Clients or servers may then trust only the CA key and verify its signature
    +on a certificate rather than trusting many user/host keys.
    +Note that OpenSSH certificates are a different, and much simpler, format to
    +the X.509 certificates used in
    +.Xr ssl 8 .
    +.Pp
    +.Nm
    +supports two types of certificates: user and host.
    +User certificates authenticate users to servers, whereas host certificates
    +authenticate server hosts to users.
    +To generate a user certificate:
    +.Pp
    +.Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub
    +.Pp
    +The resultant certificate will be placed in
    +.Pa /path/to/user_key_cert.pub .
    +A host certificate requires the
    +.Fl h
    +option:
    +.Pp
    +.Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub
    +.Pp
    +The host certificate will be output to
    +.Pa /path/to/host_key_cert.pub .
    +In both cases,
    +.Ar key_id
    +is a "key identifier" that is logged by the server when the certificate
    +is used for authentication.
    +.Pp
    +Certificates may be limited to be valid for a set of principal (user/host)
    +names.
    +By default, generated certificates are valid for all users or hosts.
    +To generate a certificate for a specified set of principals:
    +.Pp
    +.Dl $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub
    +.Dl $ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub
    +.Pp
    +Additional limitations on the validity and use of user certificates may
    +be specified through certificate constraints.
    +A constrained certificate may disable features of the SSH session, may be
    +valid only when presented from particular source addresses or may
    +force the use of a specific command.
    +For a list of valid certificate constraints, see the documentation for the
    +.Fl O
    +option above.
    +.Pp
    +Finally, certificates may be defined with a validity lifetime.
    +The
    +.Fl V
    +option allows specification of certificate start and end times.
    +A certificate that is presented at a time outside this range will not be
    +considered valid.
    +By default, certificates have a maximum validity interval.
    +.Pp
    +For certificates to be used for user or host authentication, the CA
    +public key must be trusted by
    +.Xr sshd 8
    +or
    +.Xr ssh 1 .
    +Please refer to those manual pages for details.
     .Sh FILES
     .Bl -tag -width Ds
     .It Pa ~/.ssh/identity
    @@ -394,7 +572,7 @@ Contains the protocol version 1 RSA authentication identity of the user.
     This file should not be readable by anyone but the user.
     It is possible to
     specify a passphrase when generating the key; that passphrase will be
    -used to encrypt the private part of this file using 3DES.
    +used to encrypt the private part of this file using 128-bit AES.
     This file is not automatically accessed by
     .Nm
     but it is offered as the default file for the private key.
    @@ -412,7 +590,7 @@ Contains the protocol version 2 DSA authentication identity of the user.
     This file should not be readable by anyone but the user.
     It is possible to
     specify a passphrase when generating the key; that passphrase will be
    -used to encrypt the private part of this file using 3DES.
    +used to encrypt the private part of this file using 128-bit AES.
     This file is not automatically accessed by
     .Nm
     but it is offered as the default file for the private key.
    @@ -430,7 +608,7 @@ Contains the protocol version 2 RSA authentication identity of the user.
     This file should not be readable by anyone but the user.
     It is possible to
     specify a passphrase when generating the key; that passphrase will be
    -used to encrypt the private part of this file using 3DES.
    +used to encrypt the private part of this file using 128-bit AES.
     This file is not automatically accessed by
     .Nm
     but it is offered as the default file for the private key.
    diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c
    index 5765cff0884..dd662c90760 100644
    --- a/crypto/openssh/ssh-keygen.c
    +++ b/crypto/openssh/ssh-keygen.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: ssh-keygen.c,v 1.173 2009/02/21 19:32:04 tobias Exp $ */
    +/* $OpenBSD: ssh-keygen.c,v 1.184 2010/03/07 22:16:01 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland
    @@ -48,9 +48,10 @@
     #include "match.h"
     #include "hostfile.h"
     #include "dns.h"
    +#include "ssh2.h"
     
    -#ifdef SMARTCARD
    -#include "scard.h"
    +#ifdef ENABLE_PKCS11
    +#include "ssh-pkcs11.h"
     #endif
     
     /* Number of bits in the RSA/DSA key.  This value can be set on the command line. */
    @@ -81,6 +82,9 @@ int find_host = 0;
     /* Flag indicating that we want to delete a host from a known_hosts file */
     int delete_host = 0;
     
    +/* Flag indicating that we want to show the contents of a certificate */
    +int show_cert = 0;
    +
     /* Flag indicating that we just want to see the key fingerprint */
     int print_fingerprint = 0;
     int print_bubblebabble = 0;
    @@ -98,6 +102,35 @@ char *identity_new_passphrase = NULL;
     /* This is set to the new comment if given on the command line. */
     char *identity_comment = NULL;
     
    +/* Path to CA key when certifying keys. */
    +char *ca_key_path = NULL;
    +
    +/* Key type when certifying */
    +u_int cert_key_type = SSH2_CERT_TYPE_USER;
    +
    +/* "key ID" of signed key */
    +char *cert_key_id = NULL;
    +
    +/* Comma-separated list of principal names for certifying keys */
    +char *cert_principals = NULL;
    +
    +/* Validity period for certificates */
    +u_int64_t cert_valid_from = 0;
    +u_int64_t cert_valid_to = ~0ULL;
    +
    +/* Certificate constraints */
    +#define CONSTRAINT_X_FWD	(1)
    +#define CONSTRAINT_AGENT_FWD	(1<<1)
    +#define CONSTRAINT_PORT_FWD	(1<<2)
    +#define CONSTRAINT_PTY		(1<<3)
    +#define CONSTRAINT_USER_RC	(1<<4)
    +#define CONSTRAINT_DEFAULT	(CONSTRAINT_X_FWD|CONSTRAINT_AGENT_FWD| \
    +				CONSTRAINT_PORT_FWD|CONSTRAINT_PTY| \
    +				CONSTRAINT_USER_RC)
    +u_int32_t constraint_flags = CONSTRAINT_DEFAULT;
    +char *constraint_command = NULL;
    +char *constraint_src_addr = NULL;
    +
     /* Dump public key file in format used by real and the original SSH 2 */
     int convert_to_ssh2 = 0;
     int convert_from_ssh2 = 0;
    @@ -181,6 +214,7 @@ do_convert_to_ssh2(struct passwd *pw)
     	Key *k;
     	u_int len;
     	u_char *blob;
    +	char comment[61];
     	struct stat st;
     
     	if (!have_identity)
    @@ -203,11 +237,14 @@ do_convert_to_ssh2(struct passwd *pw)
     		fprintf(stderr, "key_to_blob failed\n");
     		exit(1);
     	}
    -	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
    -	fprintf(stdout,
    -	    "Comment: \"%u-bit %s, converted from OpenSSH by %s@%s\"\n",
    +	/* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
    +	snprintf(comment, sizeof(comment),
    +	    "%u-bit %s, converted by %s@%s from OpenSSH",
     	    key_size(k), key_type(k),
     	    pw->pw_name, hostname);
    +
    +	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
    +	fprintf(stdout, "Comment: \"%s\"\n", comment);
     	dump_base64(stdout, blob, len);
     	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
     	key_free(k);
    @@ -455,51 +492,29 @@ do_print_public(struct passwd *pw)
     	exit(0);
     }
     
    -#ifdef SMARTCARD
     static void
    -do_upload(struct passwd *pw, const char *sc_reader_id)
    -{
    -	Key *prv = NULL;
    -	struct stat st;
    -	int ret;
    -
    -	if (!have_identity)
    -		ask_filename(pw, "Enter file in which the key is");
    -	if (stat(identity_file, &st) < 0) {
    -		perror(identity_file);
    -		exit(1);
    -	}
    -	prv = load_identity(identity_file);
    -	if (prv == NULL) {
    -		error("load failed");
    -		exit(1);
    -	}
    -	ret = sc_put_key(prv, sc_reader_id);
    -	key_free(prv);
    -	if (ret < 0)
    -		exit(1);
    -	logit("loading key done");
    -	exit(0);
    -}
    -
    -static void
    -do_download(struct passwd *pw, const char *sc_reader_id)
    +do_download(struct passwd *pw, char *pkcs11provider)
     {
    +#ifdef ENABLE_PKCS11
     	Key **keys = NULL;
    -	int i;
    +	int i, nkeys;
     
    -	keys = sc_get_keys(sc_reader_id, NULL);
    -	if (keys == NULL)
    -		fatal("cannot read public key from smartcard");
    -	for (i = 0; keys[i]; i++) {
    +	pkcs11_init(0);
    +	nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
    +	if (nkeys <= 0)
    +		fatal("cannot read public key from pkcs11");
    +	for (i = 0; i < nkeys; i++) {
     		key_write(keys[i], stdout);
     		key_free(keys[i]);
     		fprintf(stdout, "\n");
     	}
     	xfree(keys);
    +	pkcs11_terminate();
     	exit(0);
    +#else
    +	fatal("no pkcs11 support");
    +#endif /* ENABLE_PKCS11 */
     }
    -#endif /* SMARTCARD */
     
     static void
     do_fingerprint(struct passwd *pw)
    @@ -524,7 +539,7 @@ do_fingerprint(struct passwd *pw)
     	public = key_load_public(identity_file, &comment);
     	if (public != NULL) {
     		fp = key_fingerprint(public, fptype, rep);
    -		ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
    +		ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
     		printf("%u %s %s (%s)\n", key_size(public), fp, comment,
     		    key_type(public));
     		if (log_level >= SYSLOG_LEVEL_VERBOSE)
    @@ -589,7 +604,7 @@ do_fingerprint(struct passwd *pw)
     			}
     			comment = *cp ? cp : comment;
     			fp = key_fingerprint(public, fptype, rep);
    -			ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
    +			ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
     			printf("%u %s %s (%s)\n", key_size(public), fp,
     			    comment ? comment : "no comment", key_type(public));
     			if (log_level >= SYSLOG_LEVEL_VERBOSE)
    @@ -609,7 +624,7 @@ do_fingerprint(struct passwd *pw)
     }
     
     static void
    -print_host(FILE *f, const char *name, Key *public, int hash)
    +printhost(FILE *f, const char *name, Key *public, int ca, int hash)
     {
     	if (print_fingerprint) {
     		enum fp_rep rep;
    @@ -619,7 +634,7 @@ print_host(FILE *f, const char *name, Key *public, int hash)
     		fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
     		rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
     		fp = key_fingerprint(public, fptype, rep);
    -		ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
    +		ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
     		printf("%u %s %s (%s)\n", key_size(public), fp, name,
     		    key_type(public));
     		if (log_level >= SYSLOG_LEVEL_VERBOSE)
    @@ -629,7 +644,7 @@ print_host(FILE *f, const char *name, Key *public, int hash)
     	} else {
     		if (hash && (name = host_hash(name, NULL, 0)) == NULL)
     			fatal("hash_host failed");
    -		fprintf(f, "%s ", name);
    +		fprintf(f, "%s%s%s ", ca ? CA_MARKER : "", ca ? " " : "", name);
     		if (!key_write(public, f))
     			fatal("key_write failed");
     		fprintf(f, "\n");
    @@ -640,10 +655,11 @@ static void
     do_known_hosts(struct passwd *pw, const char *name)
     {
     	FILE *in, *out = stdout;
    -	Key *public;
    +	Key *pub;
     	char *cp, *cp2, *kp, *kp2;
     	char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
     	int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
    +	int ca;
     
     	if (!have_identity) {
     		cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
    @@ -699,9 +715,19 @@ do_known_hosts(struct passwd *pw, const char *name)
     				fprintf(out, "%s\n", cp);
     			continue;
     		}
    +		/* Check whether this is a CA key */
    +		if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 &&
    +		    (cp[sizeof(CA_MARKER) - 1] == ' ' ||
    +		    cp[sizeof(CA_MARKER) - 1] == '\t')) {
    +			ca = 1;
    +			cp += sizeof(CA_MARKER);
    +		} else
    +			ca = 0;
    +
     		/* Find the end of the host name portion. */
     		for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++)
     			;
    +
     		if (*kp == '\0' || *(kp + 1) == '\0') {
     			error("line %d missing key: %.40s...",
     			    num, line);
    @@ -711,15 +737,15 @@ do_known_hosts(struct passwd *pw, const char *name)
     		*kp++ = '\0';
     		kp2 = kp;
     
    -		public = key_new(KEY_RSA1);
    -		if (key_read(public, &kp) != 1) {
    +		pub = key_new(KEY_RSA1);
    +		if (key_read(pub, &kp) != 1) {
     			kp = kp2;
    -			key_free(public);
    -			public = key_new(KEY_UNSPEC);
    -			if (key_read(public, &kp) != 1) {
    +			key_free(pub);
    +			pub = key_new(KEY_UNSPEC);
    +			if (key_read(pub, &kp) != 1) {
     				error("line %d invalid key: %.40s...",
     				    num, line);
    -				key_free(public);
    +				key_free(pub);
     				invalid = 1;
     				continue;
     			}
    @@ -737,43 +763,52 @@ do_known_hosts(struct passwd *pw, const char *name)
     				c = (strcmp(cp2, cp) == 0);
     				if (find_host && c) {
     					printf("# Host %s found: "
    -					    "line %d type %s\n", name,
    -					    num, key_type(public));
    -					print_host(out, cp, public, 0);
    +					    "line %d type %s%s\n", name,
    +					    num, key_type(pub),
    +					    ca ? " (CA key)" : "");
    +					printhost(out, cp, pub, ca, 0);
     				}
    -				if (delete_host && !c)
    -					print_host(out, cp, public, 0);
    +				if (delete_host && !c && !ca)
    +					printhost(out, cp, pub, ca, 0);
     			} else if (hash_hosts)
    -				print_host(out, cp, public, 0);
    +				printhost(out, cp, pub, ca, 0);
     		} else {
     			if (find_host || delete_host) {
     				c = (match_hostname(name, cp,
     				    strlen(cp)) == 1);
     				if (find_host && c) {
     					printf("# Host %s found: "
    -					    "line %d type %s\n", name,
    -					    num, key_type(public));
    -					print_host(out, name, public,
    -					    hash_hosts);
    +					    "line %d type %s%s\n", name,
    +					    num, key_type(pub),
    +					    ca ? " (CA key)" : "");
    +					printhost(out, name, pub,
    +					    ca, hash_hosts && !ca);
     				}
    -				if (delete_host && !c)
    -					print_host(out, cp, public, 0);
    +				if (delete_host && !c && !ca)
    +					printhost(out, cp, pub, ca, 0);
     			} else if (hash_hosts) {
     				for (cp2 = strsep(&cp, ",");
     				    cp2 != NULL && *cp2 != '\0';
     				    cp2 = strsep(&cp, ",")) {
    -					if (strcspn(cp2, "*?!") != strlen(cp2))
    +					if (ca) {
    +						fprintf(stderr, "Warning: "
    +						    "ignoring CA key for host: "
    +						    "%.64s\n", cp2);
    +						printhost(out, cp2, pub, ca, 0);
    +					} else if (strcspn(cp2, "*?!") !=
    +					    strlen(cp2)) {
     						fprintf(stderr, "Warning: "
     						    "ignoring host name with "
     						    "metacharacters: %.64s\n",
     						    cp2);
    -					else
    -						print_host(out, cp2, public, 1);
    +						printhost(out, cp2, pub, ca, 0);
    +					} else
    +						printhost(out, cp2, pub, ca, 1);
     				}
     				has_unhashed = 1;
     			}
     		}
    -		key_free(public);
    +		key_free(pub);
     	}
     	fclose(in);
     
    @@ -1030,6 +1065,391 @@ do_change_comment(struct passwd *pw)
     	exit(0);
     }
     
    +static const char *
    +fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
    +{
    +	char from[32], to[32];
    +	static char ret[64];
    +	time_t tt;
    +	struct tm *tm;
    +
    +	*from = *to = '\0';
    +	if (valid_from == 0 && valid_to == 0xffffffffffffffffULL)
    +		return "forever";
    +
    +	if (valid_from != 0) {
    +		/* XXX revisit INT_MAX in 2038 :) */
    +		tt = valid_from > INT_MAX ? INT_MAX : valid_from;
    +		tm = localtime(&tt);
    +		strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
    +	}
    +	if (valid_to != 0xffffffffffffffffULL) {
    +		/* XXX revisit INT_MAX in 2038 :) */
    +		tt = valid_to > INT_MAX ? INT_MAX : valid_to;
    +		tm = localtime(&tt);
    +		strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
    +	}
    +
    +	if (valid_from == 0) {
    +		snprintf(ret, sizeof(ret), "before %s", to);
    +		return ret;
    +	}
    +	if (valid_to == 0xffffffffffffffffULL) {
    +		snprintf(ret, sizeof(ret), "after %s", from);
    +		return ret;
    +	}
    +
    +	snprintf(ret, sizeof(ret), "from %s to %s", from, to);
    +	return ret;
    +}
    +
    +static void
    +add_flag_constraint(Buffer *c, const char *name)
    +{
    +	debug3("%s: %s", __func__, name);
    +	buffer_put_cstring(c, name);
    +	buffer_put_string(c, NULL, 0);
    +}
    +
    +static void
    +add_string_constraint(Buffer *c, const char *name, const char *value)
    +{
    +	Buffer b;
    +
    +	debug3("%s: %s=%s", __func__, name, value);
    +	buffer_init(&b);
    +	buffer_put_cstring(&b, value);
    +
    +	buffer_put_cstring(c, name);
    +	buffer_put_string(c, buffer_ptr(&b), buffer_len(&b));
    +
    +	buffer_free(&b);
    +}
    +
    +static void
    +prepare_constraint_buf(Buffer *c)
    +{
    +
    +	buffer_clear(c);
    +	if ((constraint_flags & CONSTRAINT_X_FWD) != 0)
    +		add_flag_constraint(c, "permit-X11-forwarding");
    +	if ((constraint_flags & CONSTRAINT_AGENT_FWD) != 0)
    +		add_flag_constraint(c, "permit-agent-forwarding");
    +	if ((constraint_flags & CONSTRAINT_PORT_FWD) != 0)
    +		add_flag_constraint(c, "permit-port-forwarding");
    +	if ((constraint_flags & CONSTRAINT_PTY) != 0)
    +		add_flag_constraint(c, "permit-pty");
    +	if ((constraint_flags & CONSTRAINT_USER_RC) != 0)
    +		add_flag_constraint(c, "permit-user-rc");
    +	if (constraint_command != NULL)
    +		add_string_constraint(c, "force-command", constraint_command);
    +	if (constraint_src_addr != NULL)
    +		add_string_constraint(c, "source-address", constraint_src_addr);
    +}
    +
    +static void
    +do_ca_sign(struct passwd *pw, int argc, char **argv)
    +{
    +	int i, fd;
    +	u_int n;
    +	Key *ca, *public;
    +	char *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
    +	FILE *f;
    +
    +	tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
    +	if ((ca = load_identity(tmp)) == NULL)
    +		fatal("Couldn't load CA key \"%s\"", tmp);
    +	xfree(tmp);
    +
    +	for (i = 0; i < argc; i++) {
    +		/* Split list of principals */
    +		n = 0;
    +		if (cert_principals != NULL) {
    +			otmp = tmp = xstrdup(cert_principals);
    +			plist = NULL;
    +			for (; (cp = strsep(&tmp, ",")) != NULL; n++) {
    +				plist = xrealloc(plist, n + 1, sizeof(*plist));
    +				if (*(plist[n] = xstrdup(cp)) == '\0')
    +					fatal("Empty principal name");
    +			}
    +			xfree(otmp);
    +		}
    +	
    +		tmp = tilde_expand_filename(argv[i], pw->pw_uid);
    +		if ((public = key_load_public(tmp, &comment)) == NULL)
    +			fatal("%s: unable to open \"%s\"", __func__, tmp);
    +		if (public->type != KEY_RSA && public->type != KEY_DSA)
    +			fatal("%s: key \"%s\" type %s cannot be certified",
    +			    __func__, tmp, key_type(public));
    +
    +		/* Prepare certificate to sign */
    +		if (key_to_certified(public) != 0)
    +			fatal("Could not upgrade key %s to certificate", tmp);
    +		public->cert->type = cert_key_type;
    +		public->cert->key_id = xstrdup(cert_key_id);
    +		public->cert->nprincipals = n;
    +		public->cert->principals = plist;
    +		public->cert->valid_after = cert_valid_from;
    +		public->cert->valid_before = cert_valid_to;
    +		prepare_constraint_buf(&public->cert->constraints);
    +		public->cert->signature_key = key_from_private(ca);
    +
    +		if (key_certify(public, ca) != 0)
    +			fatal("Couldn't not certify key %s", tmp);
    +
    +		if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
    +			*cp = '\0';
    +		xasprintf(&out, "%s-cert.pub", tmp);
    +		xfree(tmp);
    +
    +		if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
    +			fatal("Could not open \"%s\" for writing: %s", out,
    +			    strerror(errno));
    +		if ((f = fdopen(fd, "w")) == NULL)
    +			fatal("%s: fdopen: %s", __func__, strerror(errno));
    +		if (!key_write(public, f))
    +			fatal("Could not write certified key to %s", out);
    +		fprintf(f, " %s\n", comment);
    +		fclose(f);
    +
    +		if (!quiet)
    +			logit("Signed %s key %s: id \"%s\"%s%s valid %s",
    +			    cert_key_type == SSH2_CERT_TYPE_USER?"user":"host",
    +			    out, cert_key_id,
    +			    cert_principals != NULL ? " for " : "",
    +			    cert_principals != NULL ? cert_principals : "",
    +			    fmt_validity(cert_valid_from, cert_valid_to));
    +
    +		key_free(public);
    +		xfree(out);
    +	}
    +	exit(0);
    +}
    +
    +static u_int64_t
    +parse_relative_time(const char *s, time_t now)
    +{
    +	int64_t mul, secs;
    +
    +	mul = *s == '-' ? -1 : 1;
    +
    +	if ((secs = convtime(s + 1)) == -1)
    +		fatal("Invalid relative certificate time %s", s);
    +	if (mul == -1 && secs > now)
    +		fatal("Certificate time %s cannot be represented", s);
    +	return now + (u_int64_t)(secs * mul);
    +}
    +
    +static u_int64_t
    +parse_absolute_time(const char *s)
    +{
    +	struct tm tm;
    +	time_t tt;
    +	char buf[32], *fmt;
    +
    +	/*
    +	 * POSIX strptime says "The application shall ensure that there 
    +	 * is white-space or other non-alphanumeric characters between
    +	 * any two conversion specifications" so arrange things this way.
    +	 */
    +	switch (strlen(s)) {
    +	case 8:
    +		fmt = "%Y-%m-%d";
    +		snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6);
    +		break;
    +	case 14:
    +		fmt = "%Y-%m-%dT%H:%M:%S";
    +		snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s",
    +		    s, s + 4, s + 6, s + 8, s + 10, s + 12);
    +		break;
    +	default:
    +		fatal("Invalid certificate time format %s", s);
    +	}
    +
    +	bzero(&tm, sizeof(tm));
    +	if (strptime(buf, fmt, &tm) == NULL)
    +		fatal("Invalid certificate time %s", s);
    +	if ((tt = mktime(&tm)) < 0)
    +		fatal("Certificate time %s cannot be represented", s);
    +	return (u_int64_t)tt;
    +}
    +
    +static void
    +parse_cert_times(char *timespec)
    +{
    +	char *from, *to;
    +	time_t now = time(NULL);
    +	int64_t secs;
    +
    +	/* +timespec relative to now */
    +	if (*timespec == '+' && strchr(timespec, ':') == NULL) {
    +		if ((secs = convtime(timespec + 1)) == -1)
    +			fatal("Invalid relative certificate life %s", timespec);
    +		cert_valid_to = now + secs;
    +		/*
    +		 * Backdate certificate one minute to avoid problems on hosts
    +		 * with poorly-synchronised clocks.
    +		 */
    +		cert_valid_from = ((now - 59)/ 60) * 60;
    +		return;
    +	}
    +
    +	/*
    +	 * from:to, where
    +	 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
    +	 *   to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
    +	 */
    +	from = xstrdup(timespec);
    +	to = strchr(from, ':');
    +	if (to == NULL || from == to || *(to + 1) == '\0')
    +		fatal("Invalid certificate life specification %s", timespec);
    +	*to++ = '\0';
    +
    +	if (*from == '-' || *from == '+')
    +		cert_valid_from = parse_relative_time(from, now);
    +	else
    +		cert_valid_from = parse_absolute_time(from);
    +
    +	if (*to == '-' || *to == '+')
    +		cert_valid_to = parse_relative_time(to, cert_valid_from);
    +	else
    +		cert_valid_to = parse_absolute_time(to);
    +
    +	if (cert_valid_to <= cert_valid_from)
    +		fatal("Empty certificate validity interval");
    +	xfree(from);
    +}
    +
    +static void
    +add_cert_constraint(char *opt)
    +{
    +	char *val;
    +
    +	if (strcmp(opt, "clear") == 0)
    +		constraint_flags = 0;
    +	else if (strcasecmp(opt, "no-x11-forwarding") == 0)
    +		constraint_flags &= ~CONSTRAINT_X_FWD;
    +	else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
    +		constraint_flags |= CONSTRAINT_X_FWD;
    +	else if (strcasecmp(opt, "no-agent-forwarding") == 0)
    +		constraint_flags &= ~CONSTRAINT_AGENT_FWD;
    +	else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
    +		constraint_flags |= CONSTRAINT_AGENT_FWD;
    +	else if (strcasecmp(opt, "no-port-forwarding") == 0)
    +		constraint_flags &= ~CONSTRAINT_PORT_FWD;
    +	else if (strcasecmp(opt, "permit-port-forwarding") == 0)
    +		constraint_flags |= CONSTRAINT_PORT_FWD;
    +	else if (strcasecmp(opt, "no-pty") == 0)
    +		constraint_flags &= ~CONSTRAINT_PTY;
    +	else if (strcasecmp(opt, "permit-pty") == 0)
    +		constraint_flags |= CONSTRAINT_PTY;
    +	else if (strcasecmp(opt, "no-user-rc") == 0)
    +		constraint_flags &= ~CONSTRAINT_USER_RC;
    +	else if (strcasecmp(opt, "permit-user-rc") == 0)
    +		constraint_flags |= CONSTRAINT_USER_RC;
    +	else if (strncasecmp(opt, "force-command=", 14) == 0) {
    +		val = opt + 14;
    +		if (*val == '\0')
    +			fatal("Empty force-command constraint");
    +		if (constraint_command != NULL)
    +			fatal("force-command already specified");
    +		constraint_command = xstrdup(val);
    +	} else if (strncasecmp(opt, "source-address=", 15) == 0) {
    +		val = opt + 15;
    +		if (*val == '\0')
    +			fatal("Empty source-address constraint");
    +		if (constraint_src_addr != NULL)
    +			fatal("source-address already specified");
    +		if (addr_match_cidr_list(NULL, val) != 0)
    +			fatal("Invalid source-address list");
    +		constraint_src_addr = xstrdup(val);
    +	} else
    +		fatal("Unsupported certificate constraint \"%s\"", opt);
    +}
    +
    +static void
    +do_show_cert(struct passwd *pw)
    +{
    +	Key *key;
    +	struct stat st;
    +	char *key_fp, *ca_fp;
    +	Buffer constraints, constraint;
    +	u_char *name, *data;
    +	u_int i, dlen;
    +
    +	if (!have_identity)
    +		ask_filename(pw, "Enter file in which the key is");
    +	if (stat(identity_file, &st) < 0) {
    +		perror(identity_file);
    +		exit(1);
    +	}
    +	if ((key = key_load_public(identity_file, NULL)) == NULL)
    +		fatal("%s is not a public key", identity_file);
    +	if (!key_is_cert(key))
    +		fatal("%s is not a certificate", identity_file);
    +	
    +	key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
    +	ca_fp = key_fingerprint(key->cert->signature_key,
    +	    SSH_FP_MD5, SSH_FP_HEX);
    +
    +	printf("%s:\n", identity_file);
    +	printf("        %s certificate %s\n", key_type(key), key_fp);
    +	printf("        Signed by %s CA %s\n",
    +	    key_type(key->cert->signature_key), ca_fp);
    +	printf("        Key ID \"%s\"\n", key->cert->key_id);
    +	printf("        Valid: %s\n",
    +	    fmt_validity(key->cert->valid_after, key->cert->valid_before));
    +	printf("        Principals: ");
    +	if (key->cert->nprincipals == 0)
    +		printf("(none)\n");
    +	else {
    +		for (i = 0; i < key->cert->nprincipals; i++)
    +			printf("\n                %s",
    +			    key->cert->principals[i]);
    +		printf("\n");
    +	}
    +	printf("        Constraints: ");
    +	if (buffer_len(&key->cert->constraints) == 0)
    +		printf("(none)\n");
    +	else {
    +		printf("\n");
    +		buffer_init(&constraints);
    +		buffer_append(&constraints,
    +		    buffer_ptr(&key->cert->constraints),
    +		    buffer_len(&key->cert->constraints));
    +		buffer_init(&constraint);
    +		while (buffer_len(&constraints) != 0) {
    +			name = buffer_get_string(&constraints, NULL);
    +			data = buffer_get_string_ptr(&constraints, &dlen);
    +			buffer_append(&constraint, data, dlen);
    +			printf("                %s", name);
    +			if (strcmp(name, "permit-X11-forwarding") == 0 ||
    +			    strcmp(name, "permit-agent-forwarding") == 0 ||
    +			    strcmp(name, "permit-port-forwarding") == 0 ||
    +			    strcmp(name, "permit-pty") == 0 ||
    +			    strcmp(name, "permit-user-rc") == 0)
    +				printf("\n");
    +			else if (strcmp(name, "force-command") == 0 ||
    +			    strcmp(name, "source-address") == 0) {
    +				data = buffer_get_string(&constraint, NULL);
    +				printf(" %s\n", data);
    +				xfree(data);
    +			} else {
    +				printf(" UNKNOWN CONSTRAINT (len %u)\n",
    +				    buffer_len(&constraint));
    +				buffer_clear(&constraint);
    +			}
    +			xfree(name);
    +			if (buffer_len(&constraint) != 0)
    +				fatal("Constraint corrupt: extra data at end");
    +		}
    +		buffer_free(&constraint);
    +		buffer_free(&constraints);
    +	}
    +
    +	exit(0);
    +}
    +
     static void
     usage(void)
     {
    @@ -1040,30 +1460,34 @@ usage(void)
     	fprintf(stderr, "  -b bits     Number of bits in the key to create.\n");
     	fprintf(stderr, "  -C comment  Provide new comment.\n");
     	fprintf(stderr, "  -c          Change comment in private and public key files.\n");
    -#ifdef SMARTCARD
    -	fprintf(stderr, "  -D reader   Download public key from smartcard.\n");
    -#endif /* SMARTCARD */
    +#ifdef ENABLE_PKCS11
    +	fprintf(stderr, "  -D pkcs11   Download public key from pkcs11 token.\n");
    +#endif
     	fprintf(stderr, "  -e          Convert OpenSSH to RFC 4716 key file.\n");
     	fprintf(stderr, "  -F hostname Find hostname in known hosts file.\n");
     	fprintf(stderr, "  -f filename Filename of the key file.\n");
     	fprintf(stderr, "  -G file     Generate candidates for DH-GEX moduli.\n");
     	fprintf(stderr, "  -g          Use generic DNS resource record format.\n");
     	fprintf(stderr, "  -H          Hash names in known_hosts file.\n");
    +	fprintf(stderr, "  -h          Generate host certificate instead of a user certificate.\n");
    +	fprintf(stderr, "  -I key_id   Key identifier to include in certificate.\n");
     	fprintf(stderr, "  -i          Convert RFC 4716 to OpenSSH key file.\n");
    +	fprintf(stderr, "  -L          Print the contents of a certificate.\n");
     	fprintf(stderr, "  -l          Show fingerprint of key file.\n");
     	fprintf(stderr, "  -M memory   Amount of memory (MB) to use for generating DH-GEX moduli.\n");
    +	fprintf(stderr, "  -n name,... User/host principal names to include in certificate\n");
     	fprintf(stderr, "  -N phrase   Provide new passphrase.\n");
    +	fprintf(stderr, "  -O cnstr    Specify a certificate constraint.\n");
     	fprintf(stderr, "  -P phrase   Provide old passphrase.\n");
     	fprintf(stderr, "  -p          Change passphrase of private key file.\n");
     	fprintf(stderr, "  -q          Quiet.\n");
     	fprintf(stderr, "  -R hostname Remove host from known_hosts file.\n");
     	fprintf(stderr, "  -r hostname Print DNS resource record.\n");
    +	fprintf(stderr, "  -s ca_key   Certify keys with CA key.\n");
     	fprintf(stderr, "  -S start    Start point (hex) for generating DH-GEX moduli.\n");
     	fprintf(stderr, "  -T file     Screen candidates for DH-GEX moduli.\n");
     	fprintf(stderr, "  -t type     Specify type of key to create.\n");
    -#ifdef SMARTCARD
    -	fprintf(stderr, "  -U reader   Upload private key to smartcard.\n");
    -#endif /* SMARTCARD */
    +	fprintf(stderr, "  -V from:to  Specify certificate validity interval.\n");
     	fprintf(stderr, "  -v          Verbose.\n");
     	fprintf(stderr, "  -W gen      Generator to use for generating DH-GEX moduli.\n");
     	fprintf(stderr, "  -y          Read private key file and print public key.\n");
    @@ -1078,12 +1502,12 @@ int
     main(int argc, char **argv)
     {
     	char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
    -	char out_file[MAXPATHLEN], *reader_id = NULL;
    +	char out_file[MAXPATHLEN], *pkcs11provider = NULL;
     	char *rr_hostname = NULL;
     	Key *private, *public;
     	struct passwd *pw;
     	struct stat st;
    -	int opt, type, fd, download = 0;
    +	int opt, type, fd;
     	u_int32_t memory = 0, generator_wanted = 0, trials = 100;
     	int do_gen_candidates = 0, do_screen_candidates = 0;
     	BIGNUM *start = NULL;
    @@ -1115,8 +1539,8 @@ main(int argc, char **argv)
     		exit(1);
     	}
     
    -	while ((opt = getopt(argc, argv,
    -	    "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
    +	while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:N:n:"
    +	    "O:C:r:g:R:T:G:M:S:s:a:V:W:")) != -1) {
     		switch (opt) {
     		case 'b':
     			bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
    @@ -1131,16 +1555,25 @@ main(int argc, char **argv)
     		case 'H':
     			hash_hosts = 1;
     			break;
    +		case 'I':
    +			cert_key_id = optarg;
    +			break;
     		case 'R':
     			delete_host = 1;
     			rr_hostname = optarg;
     			break;
    +		case 'L':
    +			show_cert = 1;
    +			break;
     		case 'l':
     			print_fingerprint = 1;
     			break;
     		case 'B':
     			print_bubblebabble = 1;
     			break;
    +		case 'n':
    +			cert_principals = optarg;
    +			break;
     		case 'p':
     			change_passphrase = 1;
     			break;
    @@ -1162,6 +1595,9 @@ main(int argc, char **argv)
     		case 'N':
     			identity_new_passphrase = optarg;
     			break;
    +		case 'O':
    +			add_cert_constraint(optarg);
    +			break;
     		case 'C':
     			identity_comment = optarg;
     			break;
    @@ -1173,6 +1609,10 @@ main(int argc, char **argv)
     			/* export key */
     			convert_to_ssh2 = 1;
     			break;
    +		case 'h':
    +			cert_key_type = SSH2_CERT_TYPE_HOST;
    +			constraint_flags = 0;
    +			break;
     		case 'i':
     		case 'X':
     			/* import key */
    @@ -1184,14 +1624,14 @@ main(int argc, char **argv)
     		case 'd':
     			key_type_name = "dsa";
     			break;
    +		case 's':
    +			ca_key_path = optarg;
    +			break;
     		case 't':
     			key_type_name = optarg;
     			break;
     		case 'D':
    -			download = 1;
    -			/*FALLTHROUGH*/
    -		case 'U':
    -			reader_id = optarg;
    +			pkcs11provider = optarg;
     			break;
     		case 'v':
     			if (log_level == SYSLOG_LEVEL_INFO)
    @@ -1241,6 +1681,9 @@ main(int argc, char **argv)
     			if (BN_hex2bn(&start, optarg) == 0)
     				fatal("Invalid start point.");
     			break;
    +		case 'V':
    +			parse_cert_times(optarg);
    +			break;
     		case '?':
     		default:
     			usage();
    @@ -1250,7 +1693,15 @@ main(int argc, char **argv)
     	/* reinit */
     	log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
     
    -	if (optind < argc) {
    +	argv += optind;
    +	argc -= optind;
    +
    +	if (ca_key_path != NULL) {
    +		if (argc < 1) {
    +			printf("Too few arguments.\n");
    +			usage();
    +		}
    +	} else if (argc > 0) {
     		printf("Too many arguments.\n");
     		usage();
     	}
    @@ -1262,6 +1713,13 @@ main(int argc, char **argv)
     		printf("Cannot use -l with -D or -R.\n");
     		usage();
     	}
    +	if (ca_key_path != NULL) {
    +		if (cert_key_id == NULL)
    +			fatal("Must specify key id (-I) when certifying");
    +		do_ca_sign(pw, argc, argv);
    +	}
    +	if (show_cert)
    +		do_show_cert(pw);
     	if (delete_host || hash_hosts || find_host)
     		do_known_hosts(pw, rr_hostname);
     	if (print_fingerprint || print_bubblebabble)
    @@ -1299,16 +1757,8 @@ main(int argc, char **argv)
     			exit(0);
     		}
     	}
    -	if (reader_id != NULL) {
    -#ifdef SMARTCARD
    -		if (download)
    -			do_download(pw, reader_id);
    -		else
    -			do_upload(pw, reader_id);
    -#else /* SMARTCARD */
    -		fatal("no support for smartcards.");
    -#endif /* SMARTCARD */
    -	}
    +	if (pkcs11provider != NULL)
    +		do_download(pw, pkcs11provider);
     
     	if (do_gen_candidates) {
     		FILE *out = fopen(out_file, "w");
    diff --git a/crypto/openssh/ssh-keyscan.1 b/crypto/openssh/ssh-keyscan.1
    index 2c7ac1084cb..fd6b94a5917 100644
    --- a/crypto/openssh/ssh-keyscan.1
    +++ b/crypto/openssh/ssh-keyscan.1
    @@ -1,4 +1,4 @@
    -.\"	$OpenBSD: ssh-keyscan.1,v 1.26 2008/12/29 01:12:36 stevesk Exp $
    +.\"	$OpenBSD: ssh-keyscan.1,v 1.28 2010/01/09 23:04:13 dtucker Exp $
     .\"	$FreeBSD$
     .\"
     .\" Copyright 1995, 1996 by David Mazieres .
    @@ -7,7 +7,7 @@
     .\" permitted provided that due credit is given to the author and the
     .\" OpenBSD project by leaving this copyright notice intact.
     .\"
    -.Dd December 29 2008
    +.Dd January 9 2010
     .Dt SSH-KEYSCAN 1
     .Os
     .Sh NAME
    diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c
    index 9a91be499ec..7afe446ae28 100644
    --- a/crypto/openssh/ssh-keyscan.c
    +++ b/crypto/openssh/ssh-keyscan.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: ssh-keyscan.c,v 1.78 2009/01/22 10:02:34 djm Exp $ */
    +/* $OpenBSD: ssh-keyscan.c,v 1.81 2010/01/09 23:04:13 dtucker Exp $ */
     /*
      * Copyright 1995, 1996 by David Mazieres .
      *
    diff --git a/crypto/openssh/ssh-keysign.c b/crypto/openssh/ssh-keysign.c
    index c4bc7e56e56..0fdcebbd22c 100644
    --- a/crypto/openssh/ssh-keysign.c
    +++ b/crypto/openssh/ssh-keysign.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: ssh-keysign.c,v 1.29 2006/08/03 03:34:42 deraadt Exp $ */
    +/* $OpenBSD: ssh-keysign.c,v 1.30 2010/01/13 01:20:20 dtucker Exp $ */
     /*
      * Copyright (c) 2002 Markus Friedl.  All rights reserved.
      *
    @@ -222,7 +222,7 @@ main(int argc, char **argv)
     	if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO))
     		fatal("bad fd");
     	if ((host = get_local_name(fd)) == NULL)
    -		fatal("cannot get sockname for fd");
    +		fatal("cannot get local name for fd");
     
     	data = buffer_get_string(&b, &dlen);
     	if (valid_request(pw, host, &key, data, dlen) < 0)
    diff --git a/crypto/openssh/ssh-pkcs11-client.c b/crypto/openssh/ssh-pkcs11-client.c
    new file mode 100644
    index 00000000000..650c3734279
    --- /dev/null
    +++ b/crypto/openssh/ssh-pkcs11-client.c
    @@ -0,0 +1,238 @@
    +/* $OpenBSD: ssh-pkcs11-client.c,v 1.2 2010/02/24 06:12:53 djm Exp $ */
    +/*
    + * Copyright (c) 2010 Markus Friedl.  All rights reserved.
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +#include "includes.h"
    +
    +#ifdef ENABLE_PKCS11
    +
    +#include 
    +#ifdef HAVE_SYS_TIME_H
    +# include 
    +#endif
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include "pathnames.h"
    +#include "xmalloc.h"
    +#include "buffer.h"
    +#include "log.h"
    +#include "misc.h"
    +#include "key.h"
    +#include "authfd.h"
    +#include "atomicio.h"
    +#include "ssh-pkcs11.h"
    +
    +/* borrows code from sftp-server and ssh-agent */
    +
    +int fd = -1;
    +pid_t pid = -1;
    +
    +static void
    +send_msg(Buffer *m)
    +{
    +	u_char buf[4];
    +	int mlen = buffer_len(m);
    +
    +	put_u32(buf, mlen);
    +	if (atomicio(vwrite, fd, buf, 4) != 4 ||
    +	    atomicio(vwrite, fd, buffer_ptr(m),
    +	    buffer_len(m)) != buffer_len(m))
    +		error("write to helper failed");
    +	buffer_consume(m, mlen);
    +}
    +
    +static int
    +recv_msg(Buffer *m)
    +{
    +	u_int l, len;
    +	u_char buf[1024];
    +
    +	if ((len = atomicio(read, fd, buf, 4)) != 4) {
    +		error("read from helper failed: %u", len);
    +		return (0); /* XXX */
    +	}
    +	len = get_u32(buf);
    +	if (len > 256 * 1024)
    +		fatal("response too long: %u", len);
    +	/* read len bytes into m */
    +	buffer_clear(m);
    +	while (len > 0) {
    +		l = len;
    +		if (l > sizeof(buf))
    +			l = sizeof(buf);
    +		if (atomicio(read, fd, buf, l) != l) {
    +			error("response from helper failed.");
    +			return (0); /* XXX */
    +		}
    +		buffer_append(m, buf, l);
    +		len -= l;
    +	}
    +	return (buffer_get_char(m));
    +}
    +
    +int
    +pkcs11_init(int interactive)
    +{
    +	return (0);
    +}
    +
    +void
    +pkcs11_terminate(void)
    +{
    +	close(fd);
    +}
    +
    +static int
    +pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
    +    int padding)
    +{
    +	Key key;
    +	u_char *blob, *signature = NULL;
    +	u_int blen, slen = 0;
    +	int ret = -1;
    +	Buffer msg;
    +
    +	if (padding != RSA_PKCS1_PADDING)
    +		return (-1);
    +	key.type = KEY_RSA;
    +	key.rsa = rsa;
    +	if (key_to_blob(&key, &blob, &blen) == 0)
    +		return -1;
    +	buffer_init(&msg);
    +	buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
    +	buffer_put_string(&msg, blob, blen);
    +	buffer_put_string(&msg, from, flen);
    +	buffer_put_int(&msg, 0);
    +	xfree(blob);
    +	send_msg(&msg);
    +
    +	if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) {
    +		signature = buffer_get_string(&msg, &slen);
    +		if (slen <= (u_int)RSA_size(rsa)) {
    +			memcpy(to, signature, slen);
    +			ret = slen;
    +		}
    +		xfree(signature);
    +	}
    +	return (ret);
    +}
    +
    +/* redirect the private key encrypt operation to the ssh-pkcs11-helper */
    +static int
    +wrap_key(RSA *rsa)
    +{
    +	static RSA_METHOD helper_rsa;
    +
    +	memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa));
    +	helper_rsa.name = "ssh-pkcs11-helper";
    +	helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt;
    +	RSA_set_method(rsa, &helper_rsa);
    +	return (0);
    +}
    +
    +static int
    +pkcs11_start_helper(void)
    +{
    +	int pair[2];
    +
    +	if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
    +		error("socketpair: %s", strerror(errno));
    +		return (-1);
    +	}
    +	if ((pid = fork()) == -1) {
    +		error("fork: %s", strerror(errno));
    +		return (-1);
    +	} else if (pid == 0) {
    +		if ((dup2(pair[1], STDIN_FILENO) == -1) ||
    +		    (dup2(pair[1], STDOUT_FILENO) == -1)) {
    +			fprintf(stderr, "dup2: %s\n", strerror(errno));
    +			_exit(1);
    +		}
    +		close(pair[0]);
    +		close(pair[1]);
    +		execlp(_PATH_SSH_PKCS11_HELPER, _PATH_SSH_PKCS11_HELPER,
    +		    (char *) 0);
    +		fprintf(stderr, "exec: %s: %s\n", _PATH_SSH_PKCS11_HELPER,
    +		    strerror(errno));
    +		_exit(1);
    +	}
    +	close(pair[1]);
    +	fd = pair[0];
    +	return (0);
    +}
    +
    +int
    +pkcs11_add_provider(char *name, char *pin, Key ***keysp)
    +{
    +	Key *k;
    +	int i, nkeys;
    +	u_char *blob;
    +	u_int blen;
    +	Buffer msg;
    +
    +	if (fd < 0 && pkcs11_start_helper() < 0)
    +		return (-1);
    +
    +	buffer_init(&msg);
    +	buffer_put_char(&msg, SSH_AGENTC_ADD_SMARTCARD_KEY);
    +	buffer_put_cstring(&msg, name);
    +	buffer_put_cstring(&msg, pin);
    +	send_msg(&msg);
    +	buffer_clear(&msg);
    +
    +	if (recv_msg(&msg) == SSH2_AGENT_IDENTITIES_ANSWER) {
    +		nkeys = buffer_get_int(&msg);
    +		*keysp = xcalloc(nkeys, sizeof(Key *));
    +		for (i = 0; i < nkeys; i++) {
    +			blob = buffer_get_string(&msg, &blen);
    +			xfree(buffer_get_string(&msg, NULL));
    +			k = key_from_blob(blob, blen);
    +			wrap_key(k->rsa);
    +			(*keysp)[i] = k;
    +			xfree(blob);
    +		}
    +	} else {
    +		nkeys = -1;
    +	}
    +	buffer_free(&msg);
    +	return (nkeys);
    +}
    +
    +int
    +pkcs11_del_provider(char *name)
    +{
    +	int ret = -1;
    +	Buffer msg;
    +
    +	buffer_init(&msg);
    +	buffer_put_char(&msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY);
    +	buffer_put_cstring(&msg, name);
    +	buffer_put_cstring(&msg, "");
    +	send_msg(&msg);
    +	buffer_clear(&msg);
    +
    +	if (recv_msg(&msg) == SSH_AGENT_SUCCESS)
    +		ret = 0;
    +	buffer_free(&msg);
    +	return (ret);
    +}
    +
    +#endif /* ENABLE_PKCS11 */
    diff --git a/crypto/openssh/ssh-pkcs11-helper.0 b/crypto/openssh/ssh-pkcs11-helper.0
    new file mode 100644
    index 00000000000..2760cad94d4
    --- /dev/null
    +++ b/crypto/openssh/ssh-pkcs11-helper.0
    @@ -0,0 +1,25 @@
    +SSH-PKCS11-HELPER(8)    OpenBSD System Manager's Manual   SSH-PKCS11-HELPER(8)
    +
    +NAME
    +     ssh-pkcs11-helper - ssh-agent helper program for PKCS#11 support
    +
    +SYNOPSIS
    +     ssh-pkcs11-helper
    +
    +DESCRIPTION
    +     ssh-pkcs11-helper is used by ssh-agent(1) to access keys provided by a
    +     PKCS#11 token.
    +
    +     ssh-pkcs11-helper is not intended to be invoked by the user, but from
    +     ssh-agent(1).
    +
    +SEE ALSO
    +     ssh(1), ssh-add(1), ssh-agent(1)
    +
    +HISTORY
    +     ssh-pkcs11-helper first appeared in OpenBSD 4.7.
    +
    +AUTHORS
    +     Markus Friedl 
    +
    +OpenBSD 4.6                    February 10, 2010                             1
    diff --git a/crypto/openssh/ssh-pkcs11-helper.8 b/crypto/openssh/ssh-pkcs11-helper.8
    new file mode 100644
    index 00000000000..9bdaadc0151
    --- /dev/null
    +++ b/crypto/openssh/ssh-pkcs11-helper.8
    @@ -0,0 +1,43 @@
    +.\" $OpenBSD: ssh-pkcs11-helper.8,v 1.3 2010/02/10 23:20:38 markus Exp $
    +.\"
    +.\" Copyright (c) 2010 Markus Friedl.  All rights reserved.
    +.\"
    +.\" Permission to use, copy, modify, and 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.
    +.\"
    +.Dd $Mdocdate: February 10 2010 $
    +.Dt SSH-PKCS11-HELPER 8
    +.Os
    +.Sh NAME
    +.Nm ssh-pkcs11-helper
    +.Nd ssh-agent helper program for PKCS#11 support
    +.Sh SYNOPSIS
    +.Nm
    +.Sh DESCRIPTION
    +.Nm
    +is used by
    +.Xr ssh-agent 1
    +to access keys provided by a PKCS#11 token.
    +.Pp
    +.Nm
    +is not intended to be invoked by the user, but from
    +.Xr ssh-agent 1 .
    +.Sh SEE ALSO
    +.Xr ssh 1 ,
    +.Xr ssh-add 1 ,
    +.Xr ssh-agent 1
    +.Sh HISTORY
    +.Nm
    +first appeared in
    +.Ox 4.7 .
    +.Sh AUTHORS
    +.An Markus Friedl Aq markus@openbsd.org
    diff --git a/crypto/openssh/ssh-pkcs11-helper.c b/crypto/openssh/ssh-pkcs11-helper.c
    new file mode 100644
    index 00000000000..d3bfb98384e
    --- /dev/null
    +++ b/crypto/openssh/ssh-pkcs11-helper.c
    @@ -0,0 +1,372 @@
    +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.3 2010/02/24 06:12:53 djm Exp $ */
    +/*
    + * Copyright (c) 2010 Markus Friedl.  All rights reserved.
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +#include "includes.h"
    +
    +#ifdef ENABLE_PKCS11
    +
    +#include 
    +#ifdef HAVE_SYS_TIME_H
    +# include 
    +#endif
    +
    +#include "openbsd-compat/sys-queue.h"
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include "xmalloc.h"
    +#include "buffer.h"
    +#include "log.h"
    +#include "misc.h"
    +#include "key.h"
    +#include "authfd.h"
    +#include "ssh-pkcs11.h"
    +
    +/* borrows code from sftp-server and ssh-agent */
    +
    +struct pkcs11_keyinfo {
    +	Key		*key;
    +	char		*providername;
    +	TAILQ_ENTRY(pkcs11_keyinfo) next;
    +};
    +
    +TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist;
    +
    +#define MAX_MSG_LENGTH		10240 /*XXX*/
    +
    +/* helper */
    +#define get_int()			buffer_get_int(&iqueue);
    +#define get_string(lenp)		buffer_get_string(&iqueue, lenp);
    +
    +/* input and output queue */
    +Buffer iqueue;
    +Buffer oqueue;
    +
    +static void
    +add_key(Key *k, char *name)
    +{
    +	struct pkcs11_keyinfo *ki;
    +
    +	ki = xcalloc(1, sizeof(*ki));
    +	ki->providername = xstrdup(name);
    +	ki->key = k;
    +	TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next);
    +}
    +
    +static void
    +del_keys_by_name(char *name)
    +{
    +	struct pkcs11_keyinfo *ki, *nxt;
    +
    +	for (ki = TAILQ_FIRST(&pkcs11_keylist); ki; ki = nxt) {
    +		nxt = TAILQ_NEXT(ki, next);
    +		if (!strcmp(ki->providername, name)) {
    +			TAILQ_REMOVE(&pkcs11_keylist, ki, next);
    +			xfree(ki->providername);
    +			key_free(ki->key);
    +			free(ki);
    +		}
    +	}
    +}
    +
    +/* lookup matching 'private' key */
    +static Key *
    +lookup_key(Key *k)
    +{
    +	struct pkcs11_keyinfo *ki;
    +
    +	TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
    +		debug("check %p %s", ki, ki->providername);
    +		if (key_equal(k, ki->key))
    +			return (ki->key);
    +	}
    +	return (NULL);
    +}
    +
    +static void
    +send_msg(Buffer *m)
    +{
    +	int mlen = buffer_len(m);
    +
    +	buffer_put_int(&oqueue, mlen);
    +	buffer_append(&oqueue, buffer_ptr(m), mlen);
    +	buffer_consume(m, mlen);
    +}
    +
    +static void
    +process_add(void)
    +{
    +	char *name, *pin;
    +	Key **keys;
    +	int i, nkeys;
    +	u_char *blob;
    +	u_int blen;
    +	Buffer msg;
    +
    +	buffer_init(&msg);
    +	name = get_string(NULL);
    +	pin = get_string(NULL);
    +	if ((nkeys = pkcs11_add_provider(name, pin, &keys)) > 0) {
    +		buffer_put_char(&msg, SSH2_AGENT_IDENTITIES_ANSWER);
    +		buffer_put_int(&msg, nkeys);
    +		for (i = 0; i < nkeys; i++) {
    +			key_to_blob(keys[i], &blob, &blen);
    +			buffer_put_string(&msg, blob, blen);
    +			buffer_put_cstring(&msg, name);
    +			xfree(blob);
    +			add_key(keys[i], name);
    +		}
    +		xfree(keys);
    +	} else {
    +		buffer_put_char(&msg, SSH_AGENT_FAILURE);
    +	}
    +	xfree(pin);
    +	xfree(name);
    +	send_msg(&msg);
    +	buffer_free(&msg);
    +}
    +
    +static void
    +process_del(void)
    +{
    +	char *name, *pin;
    +	Buffer msg;
    +
    +	buffer_init(&msg);
    +	name = get_string(NULL);
    +	pin = get_string(NULL);
    +	del_keys_by_name(name);
    +	if (pkcs11_del_provider(name) == 0)
    +		 buffer_put_char(&msg, SSH_AGENT_SUCCESS);
    +	else
    +		 buffer_put_char(&msg, SSH_AGENT_FAILURE);
    +	xfree(pin);
    +	xfree(name);
    +	send_msg(&msg);
    +	buffer_free(&msg);
    +}
    +
    +static void
    +process_sign(void)
    +{
    +	u_char *blob, *data, *signature = NULL;
    +	u_int blen, dlen, slen = 0;
    +	int ok = -1, flags, ret;
    +	Key *key, *found;
    +	Buffer msg;
    +
    +	blob = get_string(&blen);
    +	data = get_string(&dlen);
    +	flags = get_int(); /* XXX ignore */
    +
    +	if ((key = key_from_blob(blob, blen)) != NULL) {
    +		if ((found = lookup_key(key)) != NULL) {
    +			slen = RSA_size(key->rsa);
    +			signature = xmalloc(slen);
    +			if ((ret = RSA_private_encrypt(dlen, data, signature,
    +			    found->rsa, RSA_PKCS1_PADDING)) != -1) {
    +				slen = ret;
    +				ok = 0;
    +			}
    +		}
    +		key_free(key);
    +	}
    +	buffer_init(&msg);
    +	if (ok == 0) {
    +		buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE);
    +		buffer_put_string(&msg, signature, slen);
    +	} else {
    +		buffer_put_char(&msg, SSH_AGENT_FAILURE);
    +	}
    +	xfree(data);
    +	xfree(blob);
    +	if (signature != NULL)
    +		xfree(signature);
    +	send_msg(&msg);
    +	buffer_free(&msg);
    +}
    +
    +static void
    +process(void)
    +{
    +	u_int msg_len;
    +	u_int buf_len;
    +	u_int consumed;
    +	u_int type;
    +	u_char *cp;
    +
    +	buf_len = buffer_len(&iqueue);
    +	if (buf_len < 5)
    +		return;		/* Incomplete message. */
    +	cp = buffer_ptr(&iqueue);
    +	msg_len = get_u32(cp);
    +	if (msg_len > MAX_MSG_LENGTH) {
    +		error("bad message len %d", msg_len);
    +		cleanup_exit(11);
    +	}
    +	if (buf_len < msg_len + 4)
    +		return;
    +	buffer_consume(&iqueue, 4);
    +	buf_len -= 4;
    +	type = buffer_get_char(&iqueue);
    +	switch (type) {
    +	case SSH_AGENTC_ADD_SMARTCARD_KEY:
    +		debug("process_add");
    +		process_add();
    +		break;
    +	case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
    +		debug("process_del");
    +		process_del();
    +		break;
    +	case SSH2_AGENTC_SIGN_REQUEST:
    +		debug("process_sign");
    +		process_sign();
    +		break;
    +	default:
    +		error("Unknown message %d", type);
    +		break;
    +	}
    +	/* discard the remaining bytes from the current packet */
    +	if (buf_len < buffer_len(&iqueue)) {
    +		error("iqueue grew unexpectedly");
    +		cleanup_exit(255);
    +	}
    +	consumed = buf_len - buffer_len(&iqueue);
    +	if (msg_len < consumed) {
    +		error("msg_len %d < consumed %d", msg_len, consumed);
    +		cleanup_exit(255);
    +	}
    +	if (msg_len > consumed)
    +		buffer_consume(&iqueue, msg_len - consumed);
    +}
    +
    +void
    +cleanup_exit(int i)
    +{
    +	/* XXX */
    +	_exit(i);
    +}
    +
    +int
    +main(int argc, char **argv)
    +{
    +	fd_set *rset, *wset;
    +	int in, out, max, log_stderr = 0;
    +	ssize_t len, olen, set_size;
    +	SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
    +	LogLevel log_level = SYSLOG_LEVEL_ERROR;
    +	char buf[4*4096];
    +
    +	extern char *optarg;
    +	extern char *__progname;
    +
    +	TAILQ_INIT(&pkcs11_keylist);
    +	pkcs11_init(0);
    +
    +	init_rng();
    +	seed_rng();
    +	__progname = ssh_get_progname(argv[0]);
    +
    +	log_init(__progname, log_level, log_facility, log_stderr);
    +
    +	in = STDIN_FILENO;
    +	out = STDOUT_FILENO;
    +
    +	max = 0;
    +	if (in > max)
    +		max = in;
    +	if (out > max)
    +		max = out;
    +
    +	buffer_init(&iqueue);
    +	buffer_init(&oqueue);
    +
    +	set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
    +	rset = (fd_set *)xmalloc(set_size);
    +	wset = (fd_set *)xmalloc(set_size);
    +
    +	for (;;) {
    +		memset(rset, 0, set_size);
    +		memset(wset, 0, set_size);
    +
    +		/*
    +		 * Ensure that we can read a full buffer and handle
    +		 * the worst-case length packet it can generate,
    +		 * otherwise apply backpressure by stopping reads.
    +		 */
    +		if (buffer_check_alloc(&iqueue, sizeof(buf)) &&
    +		    buffer_check_alloc(&oqueue, MAX_MSG_LENGTH))
    +			FD_SET(in, rset);
    +
    +		olen = buffer_len(&oqueue);
    +		if (olen > 0)
    +			FD_SET(out, wset);
    +
    +		if (select(max+1, rset, wset, NULL, NULL) < 0) {
    +			if (errno == EINTR)
    +				continue;
    +			error("select: %s", strerror(errno));
    +			cleanup_exit(2);
    +		}
    +
    +		/* copy stdin to iqueue */
    +		if (FD_ISSET(in, rset)) {
    +			len = read(in, buf, sizeof buf);
    +			if (len == 0) {
    +				debug("read eof");
    +				cleanup_exit(0);
    +			} else if (len < 0) {
    +				error("read: %s", strerror(errno));
    +				cleanup_exit(1);
    +			} else {
    +				buffer_append(&iqueue, buf, len);
    +			}
    +		}
    +		/* send oqueue to stdout */
    +		if (FD_ISSET(out, wset)) {
    +			len = write(out, buffer_ptr(&oqueue), olen);
    +			if (len < 0) {
    +				error("write: %s", strerror(errno));
    +				cleanup_exit(1);
    +			} else {
    +				buffer_consume(&oqueue, len);
    +			}
    +		}
    +
    +		/*
    +		 * Process requests from client if we can fit the results
    +		 * into the output buffer, otherwise stop processing input
    +		 * and let the output queue drain.
    +		 */
    +		if (buffer_check_alloc(&oqueue, MAX_MSG_LENGTH))
    +			process();
    +	}
    +}
    +#else /* ENABLE_PKCS11 */
    +int
    +main(int argc, char **argv)
    +{
    +	extern char *__progname;
    +
    +	__progname = ssh_get_progname(argv[0]);
    +	log_init(__progname, SYSLOG_LEVEL_ERROR, SYSLOG_FACILITY_AUTH, 0);
    +	fatal("PKCS#11 support disabled at compile time");
    +}
    +#endif /* ENABLE_PKCS11 */
    diff --git a/crypto/openssh/ssh-pkcs11.c b/crypto/openssh/ssh-pkcs11.c
    new file mode 100644
    index 00000000000..f0192dcf1c7
    --- /dev/null
    +++ b/crypto/openssh/ssh-pkcs11.c
    @@ -0,0 +1,564 @@
    +/* $OpenBSD: ssh-pkcs11.c,v 1.4 2010/02/24 06:12:53 djm Exp $ */
    +/*
    + * Copyright (c) 2010 Markus Friedl.  All rights reserved.
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +
    +#include "includes.h"
    +
    +#ifdef ENABLE_PKCS11
    +
    +#include 
    +#ifdef HAVE_SYS_TIME_H
    +# include 
    +#endif
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +
    +#include "openbsd-compat/sys-queue.h"
    +
    +#define CRYPTOKI_COMPAT
    +#include "pkcs11.h"
    +
    +#include "log.h"
    +#include "misc.h"
    +#include "key.h"
    +#include "ssh-pkcs11.h"
    +#include "xmalloc.h"
    +
    +struct pkcs11_slotinfo {
    +	CK_TOKEN_INFO		token;
    +	CK_SESSION_HANDLE	session;
    +	int			logged_in;
    +};
    +
    +struct pkcs11_provider {
    +	char			*name;
    +	void			*handle;
    +	CK_FUNCTION_LIST	*function_list;
    +	CK_INFO			info;
    +	CK_ULONG		nslots;
    +	CK_SLOT_ID		*slotlist;
    +	struct pkcs11_slotinfo	*slotinfo;
    +	int			valid;
    +	int			refcount;
    +	TAILQ_ENTRY(pkcs11_provider) next;
    +};
    +
    +TAILQ_HEAD(, pkcs11_provider) pkcs11_providers;
    +
    +struct pkcs11_key {
    +	struct pkcs11_provider	*provider;
    +	CK_ULONG		slotidx;
    +	int			(*orig_finish)(RSA *rsa);
    +	RSA_METHOD		rsa_method;
    +	char			*keyid;
    +	int			keyid_len;
    +};
    +
    +int pkcs11_interactive = 0;
    +
    +int
    +pkcs11_init(int interactive)
    +{
    +	pkcs11_interactive = interactive;
    +	TAILQ_INIT(&pkcs11_providers);
    +	return (0);
    +}
    +
    +/*
    + * finalize a provider shared libarary, it's no longer usable.
    + * however, there might still be keys referencing this provider,
    + * so the actuall freeing of memory is handled by pkcs11_provider_unref().
    + * this is called when a provider gets unregistered.
    + */
    +static void
    +pkcs11_provider_finalize(struct pkcs11_provider *p)
    +{
    +	CK_RV rv;
    +	CK_ULONG i;
    +
    +	debug("pkcs11_provider_finalize: %p refcount %d valid %d",
    +	    p, p->refcount, p->valid);
    +	if (!p->valid)
    +		return;
    +	for (i = 0; i < p->nslots; i++) {
    +		if (p->slotinfo[i].session &&
    +		    (rv = p->function_list->C_CloseSession(
    +		    p->slotinfo[i].session)) != CKR_OK)
    +			error("C_CloseSession failed: %lu", rv);
    +	}
    +	if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK)
    +		error("C_Finalize failed: %lu", rv);
    +	p->valid = 0;
    +	p->function_list = NULL;
    +	dlclose(p->handle);
    +}
    +
    +/*
    + * remove a reference to the provider.
    + * called when a key gets destroyed or when the provider is unregistered.
    + */
    +static void
    +pkcs11_provider_unref(struct pkcs11_provider *p)
    +{
    +	debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount);
    +	if (--p->refcount <= 0) {
    +		if (p->valid)
    +			error("pkcs11_provider_unref: %p still valid", p);
    +		xfree(p->slotlist);
    +		xfree(p->slotinfo);
    +		xfree(p);
    +	}
    +}
    +
    +/* unregister all providers, keys might still point to the providers */
    +void
    +pkcs11_terminate(void)
    +{
    +	struct pkcs11_provider *p;
    +
    +	while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) {
    +		TAILQ_REMOVE(&pkcs11_providers, p, next);
    +		pkcs11_provider_finalize(p);
    +		pkcs11_provider_unref(p);
    +	}
    +}
    +
    +/* lookup provider by name */
    +static struct pkcs11_provider *
    +pkcs11_provider_lookup(char *provider_id)
    +{
    +	struct pkcs11_provider *p;
    +
    +	TAILQ_FOREACH(p, &pkcs11_providers, next) {
    +		debug("check %p %s", p, p->name);
    +		if (!strcmp(provider_id, p->name))
    +			return (p);
    +	}
    +	return (NULL);
    +}
    +
    +/* unregister provider by name */
    +int
    +pkcs11_del_provider(char *provider_id)
    +{
    +	struct pkcs11_provider *p;
    +
    +	if ((p = pkcs11_provider_lookup(provider_id)) != NULL) {
    +		TAILQ_REMOVE(&pkcs11_providers, p, next);
    +		pkcs11_provider_finalize(p);
    +		pkcs11_provider_unref(p);
    +		return (0);
    +	}
    +	return (-1);
    +}
    +
    +/* openssl callback for freeing an RSA key */
    +static int
    +pkcs11_rsa_finish(RSA *rsa)
    +{
    +	struct pkcs11_key	*k11;
    +	int rv = -1;
    +
    +	if ((k11 = RSA_get_app_data(rsa)) != NULL) {
    +		if (k11->orig_finish)
    +			rv = k11->orig_finish(rsa);
    +		if (k11->provider)
    +			pkcs11_provider_unref(k11->provider);
    +		if (k11->keyid)
    +			xfree(k11->keyid);
    +		xfree(k11);
    +	}
    +	return (rv);
    +}
    +
    +/* openssl callback doing the actual signing operation */
    +static int
    +pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
    +    int padding)
    +{
    +	struct pkcs11_key	*k11;
    +	struct pkcs11_slotinfo	*si;
    +	CK_FUNCTION_LIST	*f;
    +	CK_OBJECT_HANDLE	obj;
    +	CK_ULONG		tlen = 0, nfound = 0;
    +	CK_RV			rv;
    +	CK_OBJECT_CLASS		private_key_class = CKO_PRIVATE_KEY;
    +	CK_BBOOL		true_val = CK_TRUE;
    +	CK_MECHANISM		mech = {
    +		CKM_RSA_PKCS, NULL_PTR, 0
    +	};
    +	CK_ATTRIBUTE		key_filter[] = {
    +		{CKA_CLASS, NULL, sizeof(private_key_class) },
    +		{CKA_ID, NULL, 0},
    +		{CKA_SIGN, NULL, sizeof(true_val) }
    +	};
    +	char			*pin, prompt[1024];
    +	int			rval = -1;
    +
    +	/* some compilers complain about non-constant initializer so we
    +	   use NULL in CK_ATTRIBUTE above and set the values here */
    +	key_filter[0].pValue = &private_key_class;
    +	key_filter[2].pValue = &true_val;
    +
    +	if ((k11 = RSA_get_app_data(rsa)) == NULL) {
    +		error("RSA_get_app_data failed for rsa %p", rsa);
    +		return (-1);
    +	}
    +	if (!k11->provider || !k11->provider->valid) {
    +		error("no pkcs11 (valid) provider for rsa %p", rsa);
    +		return (-1);
    +	}
    +	f = k11->provider->function_list;
    +	si = &k11->provider->slotinfo[k11->slotidx];
    +	if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
    +		if (!pkcs11_interactive) {
    +			error("need pin");
    +			return (-1);
    +		}
    +		snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ",
    +		    si->token.label);
    +		pin = read_passphrase(prompt, RP_ALLOW_EOF);
    +		if (pin == NULL)
    +			return (-1);	/* bail out */
    +		if ((rv = f->C_Login(si->session, CKU_USER, pin, strlen(pin)))
    +		    != CKR_OK) {
    +			xfree(pin);
    +			error("C_Login failed: %lu", rv);
    +			return (-1);
    +		}
    +		xfree(pin);
    +		si->logged_in = 1;
    +	}
    +	key_filter[1].pValue = k11->keyid;
    +	key_filter[1].ulValueLen = k11->keyid_len;
    +	if ((rv = f->C_FindObjectsInit(si->session, key_filter, 3)) != CKR_OK) {
    +		error("C_FindObjectsInit failed: %lu", rv);
    +		return (-1);
    +	}
    +	if ((rv = f->C_FindObjects(si->session, &obj, 1, &nfound)) != CKR_OK ||
    +	    nfound != 1) {
    +		error("C_FindObjects failed (%lu nfound): %lu", nfound, rv);
    +	} else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
    +		error("C_SignInit failed: %lu", rv);
    +	} else {
    +		/* XXX handle CKR_BUFFER_TOO_SMALL */
    +		tlen = RSA_size(rsa);
    +		rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen);
    +		if (rv == CKR_OK) 
    +			rval = tlen;
    +		else 
    +			error("C_Sign failed: %lu", rv);
    +	}
    +	if ((rv = f->C_FindObjectsFinal(si->session)) != CKR_OK)
    +		error("C_FindObjectsFinal failed: %lu", rv);
    +	return (rval);
    +}
    +
    +static int
    +pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
    +    int padding)
    +{
    +	return (-1);
    +}
    +
    +/* redirect private key operations for rsa key to pkcs11 token */
    +static int
    +pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
    +    CK_ATTRIBUTE *keyid_attrib, RSA *rsa)
    +{
    +	struct pkcs11_key	*k11;
    +	const RSA_METHOD	*def = RSA_get_default_method();
    +
    +	k11 = xcalloc(1, sizeof(*k11));
    +	k11->provider = provider;
    +	provider->refcount++;	/* provider referenced by RSA key */
    +	k11->slotidx = slotidx;
    +	/* identify key object on smartcard */
    +	k11->keyid_len = keyid_attrib->ulValueLen;
    +	k11->keyid = xmalloc(k11->keyid_len);
    +	memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
    +	k11->orig_finish = def->finish;
    +	memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method));
    +	k11->rsa_method.name = "pkcs11";
    +	k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt;
    +	k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt;
    +	k11->rsa_method.finish = pkcs11_rsa_finish;
    +	RSA_set_method(rsa, &k11->rsa_method);
    +	RSA_set_app_data(rsa, k11);
    +	return (0);
    +}
    +
    +/* remove trailing spaces */
    +static void
    +rmspace(char *buf, size_t len)
    +{
    +	size_t i;
    +
    +	if (!len)
    +		return;
    +	for (i = len - 1;  i > 0; i--)
    +		if (i == len - 1 || buf[i] == ' ')
    +			buf[i] = '\0';
    +		else
    +			break;
    +}
    +
    +/*
    + * open a pkcs11 session and login if required.
    + * if pin == NULL we delay login until key use
    + */
    +static int
    +pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin)
    +{
    +	CK_RV			rv;
    +	CK_FUNCTION_LIST	*f;
    +	CK_SESSION_HANDLE	session;
    +	int			login_required;
    +
    +	f = p->function_list;
    +	login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED;
    +	if (pin && login_required && !strlen(pin)) {
    +		error("pin required");
    +		return (-1);
    +	}
    +	if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION|
    +	    CKF_SERIAL_SESSION, NULL, NULL, &session))
    +	    != CKR_OK) {
    +		error("C_OpenSession failed: %lu", rv);
    +		return (-1);
    +	}
    +	if (login_required && pin) {
    +		if ((rv = f->C_Login(session, CKU_USER, pin, strlen(pin)))
    +		    != CKR_OK) {
    +			error("C_Login failed: %lu", rv);
    +			if ((rv = f->C_CloseSession(session)) != CKR_OK)
    +				error("C_CloseSession failed: %lu", rv);
    +			return (-1);
    +		}
    +		p->slotinfo[slotidx].logged_in = 1;
    +	}
    +	p->slotinfo[slotidx].session = session;
    +	return (0);
    +}
    +
    +/*
    + * lookup public keys for token in slot identified by slotidx,
    + * add 'wrapped' public keys to the 'keysp' array and increment nkeys.
    + * keysp points to an (possibly empty) array with *nkeys keys.
    + */
    +static int
    +pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp,
    +    int *nkeys)
    +{
    +	Key			*key;
    +	RSA			*rsa;
    +	int			i;
    +	CK_RV			rv;
    +	CK_OBJECT_HANDLE	obj;
    +	CK_ULONG		nfound;
    +	CK_SESSION_HANDLE	session;
    +	CK_FUNCTION_LIST	*f;
    +	CK_OBJECT_CLASS		pubkey_class = CKO_PUBLIC_KEY;
    +	CK_ATTRIBUTE		pubkey_filter[] = {
    +		{ CKA_CLASS, NULL, sizeof(pubkey_class) }
    +	};
    +	CK_ATTRIBUTE		attribs[] = {
    +		{ CKA_ID, NULL, 0 },
    +		{ CKA_MODULUS, NULL, 0 },
    +		{ CKA_PUBLIC_EXPONENT, NULL, 0 }
    +	};
    +
    +	/* some compilers complain about non-constant initializer so we
    +	   use NULL in CK_ATTRIBUTE above and set the value here */
    +	pubkey_filter[0].pValue = &pubkey_class;
    +
    +	f = p->function_list;
    +	session = p->slotinfo[slotidx].session;
    +	/* setup a filter the looks for public keys */
    +	if ((rv = f->C_FindObjectsInit(session, pubkey_filter, 1)) != CKR_OK) {
    +		error("C_FindObjectsInit failed: %lu", rv);
    +		return (-1);
    +	}
    +	while (1) {
    +		/* XXX 3 attributes in attribs[] */
    +		for (i = 0; i < 3; i++) {
    +			attribs[i].pValue = NULL;
    +			attribs[i].ulValueLen = 0;
    +		}
    +		if ((rv = f->C_FindObjects(session, &obj, 1, &nfound)) != CKR_OK
    +		    || nfound == 0)
    +			break;
    +		/* found a key, so figure out size of the attributes */
    +		if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
    +		    != CKR_OK) {
    +			error("C_GetAttributeValue failed: %lu", rv);
    +			continue;
    +		}
    +		/* allocate buffers for attributes, XXX check ulValueLen? */
    +		for (i = 0; i < 3; i++)
    +			attribs[i].pValue = xmalloc(attribs[i].ulValueLen);
    +		/* retrieve ID, modulus and public exponent of RSA key */
    +		if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
    +		    != CKR_OK) {
    +			error("C_GetAttributeValue failed: %lu", rv);
    +		} else if ((rsa = RSA_new()) == NULL) {
    +			error("RSA_new failed");
    +		} else {
    +			rsa->n = BN_bin2bn(attribs[1].pValue,
    +			    attribs[1].ulValueLen, NULL);
    +			rsa->e = BN_bin2bn(attribs[2].pValue,
    +			    attribs[2].ulValueLen, NULL);
    +			if (rsa->n && rsa->e &&
    +			    pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
    +				key = key_new(KEY_UNSPEC);
    +				key->rsa = rsa;
    +				key->type = KEY_RSA;
    +				key->flags |= KEY_FLAG_EXT;
    +				/* expand key array and add key */
    +				*keysp = xrealloc(*keysp, *nkeys + 1,
    +				    sizeof(Key *));
    +				(*keysp)[*nkeys] = key;
    +				*nkeys = *nkeys + 1;
    +				debug("have %d keys", *nkeys);
    +			} else {
    +				RSA_free(rsa);
    +			}
    +		}
    +		for (i = 0; i < 3; i++)
    +			xfree(attribs[i].pValue);
    +	}
    +	if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK)
    +		error("C_FindObjectsFinal failed: %lu", rv);
    +	return (0);
    +}
    +
    +/* register a new provider, fails if provider already exists */
    +int
    +pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp)
    +{
    +	int nkeys, need_finalize = 0;
    +	struct pkcs11_provider *p = NULL;
    +	void *handle = NULL;
    +	CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **);
    +	CK_RV rv;
    +	CK_FUNCTION_LIST *f = NULL;
    +	CK_TOKEN_INFO *token;
    +	CK_ULONG i;
    +
    +	*keyp = NULL;
    +	if (pkcs11_provider_lookup(provider_id) != NULL) {
    +		error("provider already registered: %s", provider_id);
    +		goto fail;
    +	}
    +	/* open shared pkcs11-libarary */
    +	if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) {
    +		error("dlopen %s failed: %s", provider_id, dlerror());
    +		goto fail;
    +	}
    +	if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) {
    +		error("dlsym(C_GetFunctionList) failed: %s", dlerror());
    +		goto fail;
    +	}
    +	p = xcalloc(1, sizeof(*p));
    +	p->name = xstrdup(provider_id);
    +	p->handle = handle;
    +	/* setup the pkcs11 callbacks */
    +	if ((rv = (*getfunctionlist)(&f)) != CKR_OK) {
    +		error("C_GetFunctionList failed: %lu", rv);
    +		goto fail;
    +	}
    +	p->function_list = f;
    +	if ((rv = f->C_Initialize(NULL)) != CKR_OK) {
    +		error("C_Initialize failed: %lu", rv);
    +		goto fail;
    +	}
    +	need_finalize = 1;
    +	if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) {
    +		error("C_GetInfo failed: %lu", rv);
    +		goto fail;
    +	}
    +	rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID));
    +	rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription));
    +	debug("manufacturerID <%s> cryptokiVersion %d.%d"
    +	    " libraryDescription <%s> libraryVersion %d.%d",
    +	    p->info.manufacturerID,
    +	    p->info.cryptokiVersion.major,
    +	    p->info.cryptokiVersion.minor,
    +	    p->info.libraryDescription,
    +	    p->info.libraryVersion.major,
    +	    p->info.libraryVersion.minor);
    +	if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) {
    +		error("C_GetSlotList failed: %lu", rv);
    +		goto fail;
    +	}
    +	if (p->nslots == 0) {
    +		error("no slots");
    +		goto fail;
    +	}
    +	p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID));
    +	if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots))
    +	    != CKR_OK) {
    +		error("C_GetSlotList failed: %lu", rv);
    +		goto fail;
    +	}
    +	p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo));
    +	p->valid = 1;
    +	nkeys = 0;
    +	for (i = 0; i < p->nslots; i++) {
    +		token = &p->slotinfo[i].token;
    +		if ((rv = f->C_GetTokenInfo(p->slotlist[i], token))
    +		    != CKR_OK) {
    +			error("C_GetTokenInfo failed: %lu", rv);
    +			continue;
    +		}
    +		rmspace(token->label, sizeof(token->label));
    +		rmspace(token->manufacturerID, sizeof(token->manufacturerID));
    +		rmspace(token->model, sizeof(token->model));
    +		rmspace(token->serialNumber, sizeof(token->serialNumber));
    +		debug("label <%s> manufacturerID <%s> model <%s> serial <%s>"
    +		    " flags 0x%lx",
    +		    token->label, token->manufacturerID, token->model,
    +		    token->serialNumber, token->flags);
    +		/* open session, login with pin and retrieve public keys */
    +		if (pkcs11_open_session(p, i, pin) == 0)
    +			pkcs11_fetch_keys(p, i, keyp, &nkeys);
    +	}
    +	if (nkeys > 0) {
    +		TAILQ_INSERT_TAIL(&pkcs11_providers, p, next);
    +		p->refcount++;	/* add to provider list */
    +		return (nkeys);
    +	}
    +	error("no keys");
    +	/* don't add the provider, since it does not have any keys */
    +fail:
    +	if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK)
    +		error("C_Finalize failed: %lu", rv);
    +	if (p) {
    +		if (p->slotlist)
    +			xfree(p->slotlist);
    +		if (p->slotinfo)
    +			xfree(p->slotinfo);
    +		xfree(p);
    +	}
    +	if (handle)
    +		dlclose(handle);
    +	return (-1);
    +}
    +
    +#endif /* ENABLE_PKCS11 */
    diff --git a/crypto/openssh/ssh-pkcs11.h b/crypto/openssh/ssh-pkcs11.h
    new file mode 100644
    index 00000000000..59f456adf09
    --- /dev/null
    +++ b/crypto/openssh/ssh-pkcs11.h
    @@ -0,0 +1,20 @@
    +/* $OpenBSD: ssh-pkcs11.h,v 1.2 2010/02/24 06:12:53 djm Exp $ */
    +/*
    + * Copyright (c) 2010 Markus Friedl.  All rights reserved.
    + *
    + * Permission to use, copy, modify, and 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.
    + */
    +int	pkcs11_init(int);
    +void	pkcs11_terminate(void);
    +int	pkcs11_add_provider(char *, char *, Key ***);
    +int	pkcs11_del_provider(char *);
    diff --git a/crypto/openssh/ssh-rand-helper.c b/crypto/openssh/ssh-rand-helper.c
    index 8b1c4b4f47b..fa5070499e5 100644
    --- a/crypto/openssh/ssh-rand-helper.c
    +++ b/crypto/openssh/ssh-rand-helper.c
    @@ -818,6 +818,7 @@ main(int argc, char **argv)
     	unsigned char *buf;
     	int ret, ch, debug_level, output_hex, bytes;
     	extern char *optarg;
    +	extern int optind;
     	LogLevel ll;
     
     	__progname = ssh_get_progname(argv[0]);
    @@ -853,11 +854,17 @@ main(int argc, char **argv)
     		default:
     			error("Invalid commandline option");
     			usage();
    +			exit(1);
     		}
     	}
    -
     	log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
     
    +	if (argc != optind) {
    +		error("Unexpected commandline arguments.");
    +		usage();
    +		exit(1);
    +	}
    +
     #ifdef USE_SEED_FILES
     	prng_read_seedfile();
     #endif
    diff --git a/crypto/openssh/ssh-rsa.c b/crypto/openssh/ssh-rsa.c
    index 0e16ff85f1d..842857fee4f 100644
    --- a/crypto/openssh/ssh-rsa.c
    +++ b/crypto/openssh/ssh-rsa.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: ssh-rsa.c,v 1.39 2006/08/03 03:34:42 deraadt Exp $ */
    +/* $OpenBSD: ssh-rsa.c,v 1.40 2010/02/26 20:29:54 djm Exp $ */
     /*
      * Copyright (c) 2000, 2003 Markus Friedl 
      *
    @@ -46,7 +46,9 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
     	int ok, nid;
     	Buffer b;
     
    -	if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
    +	if (key == NULL ||
    +	    (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
    +	    key->rsa == NULL) {
     		error("ssh_rsa_sign: no RSA key");
     		return -1;
     	}
    @@ -113,7 +115,9 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
     	u_int len, dlen, modlen;
     	int rlen, ret, nid;
     
    -	if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
    +	if (key == NULL ||
    +	    (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
    +	    key->rsa == NULL) {
     		error("ssh_rsa_verify: no RSA key");
     		return -1;
     	}
    diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1
    index 0ea4c490f62..e3a826ef4d8 100644
    --- a/crypto/openssh/ssh.1
    +++ b/crypto/openssh/ssh.1
    @@ -34,9 +34,9 @@
     .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     .\"
    -.\" $OpenBSD: ssh.1,v 1.282 2009/02/12 03:44:25 djm Exp $
    +.\" $OpenBSD: ssh.1,v 1.302 2010/03/05 10:28:21 djm Exp $
     .\" $FreeBSD$
    -.Dd February 12 2009
    +.Dd March 5 2010
     .Dt SSH 1
     .Os
     .Sh NAME
    @@ -55,6 +55,7 @@
     .Oc
     .Op Fl e Ar escape_char
     .Op Fl F Ar configfile
    +.Op Fl I Ar pkcs11
     .Bk -words
     .Op Fl i Ar identity_file
     .Ek
    @@ -78,12 +79,11 @@
     .Sm on
     .Oc
     .Op Fl S Ar ctl_path
    -.Bk -words
    +.Op Fl W Ar host : Ns Ar port
     .Oo Fl w Ar local_tun Ns
     .Op : Ns Ar remote_tun Oc
     .Oo Ar user Ns @ Oc Ns Ar hostname
     .Op Ar command
    -.Ek
     .Sh DESCRIPTION
     .Nm
     (SSH client) is a program for logging into a remote machine and for
    @@ -133,8 +133,9 @@ This can also be specified on a per-host basis in a configuration file.
     .Pp
     Agent forwarding should be enabled with caution.
     Users with the ability to bypass file permissions on the remote host
    -(for the agent's Unix-domain socket)
    -can access the local agent through the forwarded connection.
    +(for the agent's
    +.Ux Ns -domain
    +socket) can access the local agent through the forwarded connection.
     An attacker cannot obtain key material from the agent,
     however they can perform operations on the keys that enable them to
     authenticate using the identities loaded into the agent.
    @@ -192,26 +193,9 @@ For protocol version 2,
     .Ar cipher_spec
     is a comma-separated list of ciphers
     listed in order of preference.
    -The supported ciphers are:
    -3des-cbc,
    -aes128-cbc,
    -aes192-cbc,
    -aes256-cbc,
    -aes128-ctr,
    -aes192-ctr,
    -aes256-ctr,
    -arcfour128,
    -arcfour256,
    -arcfour,
    -blowfish-cbc,
    -and
    -cast128-cbc.
    -The default is:
    -.Bd -literal -offset indent
    -aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
    -arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
    -aes192-ctr,aes256-ctr
    -.Ed
    +See the
    +.Cm Ciphers
    +keyword for more information.
     .It Fl D Xo
     .Sm off
     .Oo Ar bind_address : Oc
    @@ -302,13 +286,11 @@ will wait for all remote port forwards to be successfully established
     before placing itself in the background.
     .It Fl g
     Allows remote hosts to connect to local forwarded ports.
    -.It Fl I Ar smartcard_device
    -Specify the device
    +.It Fl I Ar pkcs11
    +Specify the PKCS#11 shared library
     .Nm
    -should use to communicate with a smartcard used for storing the user's
    +should use to communicate with a PKCS#11 token providing the user's
     private RSA key.
    -This option is only available if support for smartcard devices
    -is compiled in (default is no support).
     .It Fl i Ar identity_file
     Selects a file from which the identity (private key) for
     RSA or DSA authentication is read.
    @@ -325,6 +307,11 @@ It is possible to have multiple
     .Fl i
     options (and multiple identities specified in
     configuration files).
    +.Nm
    +will also try to load certificate information from the filename obtained
    +by appending
    +.Pa -cert.pub
    +to identity filenames.
     .It Fl K
     Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI
     credentials to the server.
    @@ -487,6 +474,7 @@ For full details of the options listed below, and their possible values, see
     .It NumberOfPasswordPrompts
     .It PasswordAuthentication
     .It PermitLocalCommand
    +.It PKCS11Provider
     .It Port
     .It PreferredAuthentications
     .It Protocol
    @@ -499,7 +487,6 @@ For full details of the options listed below, and their possible values, see
     .It SendEnv
     .It ServerAliveInterval
     .It ServerAliveCountMax
    -.It SmartcardDevice
     .It StrictHostKeyChecking
     .It TCPKeepAlive
     .It Tunnel
    @@ -612,6 +599,19 @@ Multiple
     .Fl v
     options increase the verbosity.
     The maximum is 3.
    +.It Fl W Ar host : Ns Ar port
    +Requests that standard input and output on the client be forwarded to
    +.Ar host
    +on
    +.Ar port
    +over the secure channel.
    +Implies
    +.Fl N ,
    +.Fl T ,
    +.Cm ExitOnForwardFailure
    +and
    +.Cm ClearAllForwardings
    +and works with Protocol version 2 only.
     .It Fl w Xo
     .Ar local_tun Ns Op : Ns Ar remote_tun
     .Xc
    @@ -685,20 +685,18 @@ exits with the exit status of the remote command or with 255
     if an error occurred.
     .Sh AUTHENTICATION
     The OpenSSH SSH client supports SSH protocols 1 and 2.
    -Protocol 2 is the default, with
    -.Nm
    -falling back to protocol 1 if it detects protocol 2 is unsupported.
    -These settings may be altered using the
    +The default is to use protocol 2 only,
    +though this can be changed via the
     .Cm Protocol
     option in
    -.Xr ssh_config 5 ,
    -or enforced using the
    +.Xr ssh_config 5
    +or the
     .Fl 1
     and
     .Fl 2
     options (see above).
     Both protocols support similar authentication methods,
    -but protocol 2 is preferred since
    +but protocol 2 is the default since
     it provides additional mechanisms for confidentiality
     (the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour)
     and integrity (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160).
    @@ -807,8 +805,20 @@ file, and has one key
     per line, though the lines can be very long.
     After this, the user can log in without giving the password.
     .Pp
    -The most convenient way to use public key authentication may be with an
    -authentication agent.
    +A variation on public key authentication
    +is available in the form of certificate authentication:
    +instead of a set of public/private keys,
    +signed certificates are used.
    +This has the advantage that a single trusted certification authority
    +can be used in place of many public/private keys.
    +See the
    +.Sx CERTIFICATES
    +section of
    +.Xr ssh-keygen 1
    +for more information.
    +.Pp
    +The most convenient way to use public key or certificate authentication
    +may be with an authentication agent.
     See
     .Xr ssh-agent 1
     for more information.
    diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
    index cd3449a1173..884d7e97821 100644
    --- a/crypto/openssh/ssh.c
    +++ b/crypto/openssh/ssh.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: ssh.c,v 1.324 2009/02/12 03:00:56 djm Exp $ */
    +/* $OpenBSD: ssh.c,v 1.335 2010/02/26 20:29:54 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -49,6 +49,7 @@ __RCSID("$FreeBSD$");
     #endif
     #include 
     #include 
    +#include 
     #include 
     
     #include 
    @@ -100,10 +101,11 @@ __RCSID("$FreeBSD$");
     #include "match.h"
     #include "msg.h"
     #include "uidswap.h"
    +#include "roaming.h"
     #include "version.h"
     
    -#ifdef SMARTCARD
    -#include "scard.h"
    +#ifdef ENABLE_PKCS11
    +#include "ssh-pkcs11.h"
     #endif
     
     extern char *__progname;
    @@ -132,6 +134,10 @@ int stdin_null_flag = 0;
      */
     int fork_after_authentication_flag = 0;
     
    +/* forward stdio to remote host and port */
    +char *stdio_forward_host = NULL;
    +int stdio_forward_port = 0;
    +
     /*
      * General data structure for command line options and options configurable
      * in configuration files.  See readconf.h.
    @@ -182,10 +188,12 @@ usage(void)
     	fprintf(stderr,
     "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
     "           [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
    -"           [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
    +"           [-I pkcs11] [-i identity_file]\n"
    +"           [-L [bind_address:]port:host:hostport]\n"
     "           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
     "           [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
    -"           [-w local_tun[:remote_tun]] [user@]hostname [command]\n"
    +"           [-W host:port] [-w local_tun[:remote_tun]]\n"
    +"           [user@]hostname [command]\n"
     	);
     	exit(255);
     }
    @@ -204,8 +212,8 @@ void muxserver_listen(void);
     int
     main(int ac, char **av)
     {
    -	int i, opt, exit_status, use_syslog;
    -	char *p, *cp, *line, buf[256];
    +	int i, r, opt, exit_status, use_syslog;
    +	char *p, *cp, *line, *argv0, buf[MAXPATHLEN];
     	struct stat st;
     	struct passwd *pw;
     	int dummy, timeout_ms;
    @@ -271,10 +279,11 @@ main(int ac, char **av)
     	/* Parse command-line arguments. */
     	host = NULL;
     	use_syslog = 0;
    +	argv0 = av[0];
     
      again:
     	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
    -	    "ACD:F:I:KL:MNO:PR:S:TVw:XYy")) != -1) {
    +	    "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) {
     		switch (opt) {
     		case '1':
     			options.protocol = SSH_PROTO_1;
    @@ -312,6 +321,11 @@ main(int ac, char **av)
     			options.gateway_ports = 1;
     			break;
     		case 'O':
    +			if (stdio_forward_host != NULL)
    +				fatal("Cannot specify multiplexing "
    +				    "command with -W");
    +			else if (muxclient_command != 0)
    +				fatal("Multiplexing command already specified");
     			if (strcmp(optarg, "check") == 0)
     				muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
     			else if (strcmp(optarg, "exit") == 0)
    @@ -350,10 +364,10 @@ main(int ac, char **av)
     			    xstrdup(optarg);
     			break;
     		case 'I':
    -#ifdef SMARTCARD
    -			options.smartcard_device = xstrdup(optarg);
    +#ifdef ENABLE_PKCS11
    +			options.pkcs11_provider = xstrdup(optarg);
     #else
    -			fprintf(stderr, "no support for smartcards.\n");
    +			fprintf(stderr, "no support for PKCS#11.\n");
     #endif
     			break;
     		case 't':
    @@ -387,6 +401,26 @@ main(int ac, char **av)
     				exit(255);
     			}
     			break;
    +		case 'W':
    +			if (stdio_forward_host != NULL)
    +				fatal("stdio forward already specified");
    +			if (muxclient_command != 0)
    +				fatal("Cannot specify stdio forward with -O");
    +			if (parse_forward(&fwd, optarg, 1, 0)) {
    +				stdio_forward_host = fwd.listen_host;
    +				stdio_forward_port = fwd.listen_port;
    +				xfree(fwd.connect_host);
    +			} else {
    +				fprintf(stderr,
    +				    "Bad stdio forwarding specification '%s'\n",
    +				    optarg);
    +				exit(255);
    +			}
    +			no_tty_flag = 1;
    +			no_shell_flag = 1;
    +			options.clear_forwardings = 1;
    +			options.exit_on_forward_failure = 1;
    +			break;
     		case 'q':
     			options.log_level = SYSLOG_LEVEL_QUIET;
     			break;
    @@ -526,7 +560,7 @@ main(int ac, char **av)
     	ac -= optind;
     	av += optind;
     
    -	if (ac > 0 && !host && **av != '-') {
    +	if (ac > 0 && !host) {
     		if (strrchr(*av, '@')) {
     			p = xstrdup(*av);
     			cp = strrchr(p, '@');
    @@ -601,7 +635,7 @@ main(int ac, char **av)
     	 * Initialize "log" output.  Since we are the client all output
     	 * actually goes to stderr.
     	 */
    -	log_init(av[0],
    +	log_init(argv0,
     	    options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
     	    SYSLOG_FACILITY_USER, !use_syslog);
     
    @@ -614,9 +648,10 @@ main(int ac, char **av)
     			fatal("Can't open user config file %.100s: "
     			    "%.100s", config, strerror(errno));
     	} else {
    -		snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir,
    +		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
     		    _PATH_SSH_USER_CONFFILE);
    -		(void)read_config_file(buf, host, &options, 1);
    +		if (r > 0 && (size_t)r < sizeof(buf))
    +			(void)read_config_file(buf, host, &options, 1);
     
     		/* Read systemwide configuration file after use config. */
     		(void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
    @@ -629,7 +664,7 @@ main(int ac, char **av)
     	channel_set_af(options.address_family);
     
     	/* reinit */
    -	log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
    +	log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
     
     	seed_rng();
     
    @@ -784,9 +819,9 @@ main(int ac, char **av)
     	 * Now that we are back to our own permissions, create ~/.ssh
     	 * directory if it doesn't already exist.
     	 */
    -	snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir,
    +	r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
     	    strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
    -	if (stat(buf, &st) < 0)
    +	if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0)
     		if (mkdir(buf, 0700) < 0)
     			error("Could not create directory '%.200s'.", buf);
     
    @@ -884,12 +919,49 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
     	}
     }
     
    +static void
    +client_cleanup_stdio_fwd(int id, void *arg)
    +{
    +	debug("stdio forwarding: done");
    +	cleanup_exit(0);
    +}
    +
    +static int
    +client_setup_stdio_fwd(const char *host_to_connect, u_short port_to_connect)
    +{
    +	Channel *c;
    +	int in, out;
    +
    +	debug3("client_setup_stdio_fwd %s:%d", host_to_connect,
    +	    port_to_connect);
    +
    +	in = dup(STDIN_FILENO);
    +	out = dup(STDOUT_FILENO);
    +	if (in < 0 || out < 0)
    +		fatal("channel_connect_stdio_fwd: dup() in/out failed");
    +
    +	if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect,
    +	    in, out)) == NULL)
    +		return 0;
    +	channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0);
    +	return 1;
    +}
    +
     static void
     ssh_init_forwarding(void)
     {
     	int success = 0;
     	int i;
     
    +	if (stdio_forward_host != NULL) {
    +		if (!compat20) {
    +			fatal("stdio forwarding require Protocol 2");
    +		}
    +		if (!client_setup_stdio_fwd(stdio_forward_host,
    +		    stdio_forward_port))
    +			fatal("Failed to connect in stdio forward mode.");
    +	}
    +
     	/* Initiate local TCP/IP port forwardings. */
     	for (i = 0; i < options.num_local_forwards; i++) {
     		debug("Local connections to %.200s:%d forwarded to remote "
    @@ -1237,6 +1309,9 @@ ssh_session2(void)
     			fatal("daemon() failed: %.200s", strerror(errno));
     	}
     
    +	if (options.use_roaming)
    +		request_roaming();
    +
     	return client_loop(tty_flag, tty_flag ?
     	    options.escape_char : SSH_ESCAPECHAR_NONE, id);
     }
    @@ -1249,31 +1324,37 @@ load_public_identity_files(void)
     	int i = 0;
     	Key *public;
     	struct passwd *pw;
    -#ifdef SMARTCARD
    +	u_int n_ids;
    +	char *identity_files[SSH_MAX_IDENTITY_FILES];
    +	Key *identity_keys[SSH_MAX_IDENTITY_FILES];
    +#ifdef ENABLE_PKCS11
     	Key **keys;
    +	int nkeys;
    +#endif /* PKCS11 */
     
    -	if (options.smartcard_device != NULL &&
    +	n_ids = 0;
    +	bzero(identity_files, sizeof(identity_files));
    +	bzero(identity_keys, sizeof(identity_keys));
    +
    +#ifdef ENABLE_PKCS11
    +	if (options.pkcs11_provider != NULL &&
     	    options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
    -	    (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL) {
    -		int count = 0;
    -		for (i = 0; keys[i] != NULL; i++) {
    -			count++;
    -			memmove(&options.identity_files[1],
    -			    &options.identity_files[0],
    -			    sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
    -			memmove(&options.identity_keys[1],
    -			    &options.identity_keys[0],
    -			    sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
    -			options.num_identity_files++;
    -			options.identity_keys[0] = keys[i];
    -			options.identity_files[0] = sc_get_key_label(keys[i]);
    +	    (pkcs11_init(!options.batch_mode) == 0) &&
    +	    (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL,
    +	    &keys)) > 0) {
    +		for (i = 0; i < nkeys; i++) {
    +			if (n_ids >= SSH_MAX_IDENTITY_FILES) {
    +				key_free(keys[i]);
    +				continue;
    +			}
    +			identity_keys[n_ids] = keys[i];
    +			identity_files[n_ids] =
    +			    xstrdup(options.pkcs11_provider); /* XXX */
    +			n_ids++;
     		}
    -		if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
    -			options.num_identity_files = SSH_MAX_IDENTITY_FILES;
    -		i = count;
     		xfree(keys);
     	}
    -#endif /* SMARTCARD */
    +#endif /* ENABLE_PKCS11 */
     	if ((pw = getpwuid(original_real_uid)) == NULL)
     		fatal("load_public_identity_files: getpwuid failed");
     	pwname = xstrdup(pw->pw_name);
    @@ -1281,7 +1362,11 @@ load_public_identity_files(void)
     	if (gethostname(thishost, sizeof(thishost)) == -1)
     		fatal("load_public_identity_files: gethostname: %s",
     		    strerror(errno));
    -	for (; i < options.num_identity_files; i++) {
    +	for (i = 0; i < options.num_identity_files; i++) {
    +		if (n_ids >= SSH_MAX_IDENTITY_FILES) {
    +			xfree(options.identity_files[i]);
    +			continue;
    +		}
     		cp = tilde_expand_filename(options.identity_files[i],
     		    original_real_uid);
     		filename = percent_expand(cp, "d", pwdir,
    @@ -1292,9 +1377,37 @@ load_public_identity_files(void)
     		debug("identity file %s type %d", filename,
     		    public ? public->type : -1);
     		xfree(options.identity_files[i]);
    -		options.identity_files[i] = filename;
    -		options.identity_keys[i] = public;
    +		identity_files[n_ids] = filename;
    +		identity_keys[n_ids] = public;
    +
    +		if (++n_ids >= SSH_MAX_IDENTITY_FILES)
    +			continue;
    +
    +		/* Try to add the certificate variant too */
    +		xasprintf(&cp, "%s-cert", filename);
    +		public = key_load_public(cp, NULL);
    +		debug("identity file %s type %d", cp,
    +		    public ? public->type : -1);
    +		if (public == NULL) {
    +			xfree(cp);
    +			continue;
    +		}
    +		if (!key_is_cert(public)) {
    +			debug("%s: key %s type %s is not a certificate",
    +			    __func__, cp, key_type(public));
    +			key_free(public);
    +			xfree(cp);
    +			continue;
    +		}
    +		identity_keys[n_ids] = public;
    +		/* point to the original path, most likely the private key */
    +		identity_files[n_ids] = xstrdup(filename);
    +		n_ids++;
     	}
    +	options.num_identity_files = n_ids;
    +	memcpy(options.identity_files, identity_files, sizeof(identity_files));
    +	memcpy(options.identity_keys, identity_keys, sizeof(identity_keys));
    +
     	bzero(pwname, strlen(pwname));
     	xfree(pwname);
     	bzero(pwdir, strlen(pwdir));
    diff --git a/crypto/openssh/ssh2.h b/crypto/openssh/ssh2.h
    index 1c33dc268b3..3ffaf686b86 100644
    --- a/crypto/openssh/ssh2.h
    +++ b/crypto/openssh/ssh2.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: ssh2.h,v 1.11 2008/11/04 08:22:13 djm Exp $ */
    +/* $OpenBSD: ssh2.h,v 1.13 2010/02/26 20:29:54 djm Exp $ */
     
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
    @@ -166,3 +166,13 @@
     
     #define SSH2_EXTENDED_DATA_STDERR			1
     
    +/* kex messages for resume@appgate.com */
    +#define SSH2_MSG_KEX_ROAMING_RESUME			30
    +#define SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED		31
    +#define SSH2_MSG_KEX_ROAMING_AUTH			32
    +#define SSH2_MSG_KEX_ROAMING_AUTH_OK			33
    +#define SSH2_MSG_KEX_ROAMING_AUTH_FAIL			34
    +
    +/* Certificate types for OpenSSH certificate keys extension */
    +#define SSH2_CERT_TYPE_USER				1
    +#define SSH2_CERT_TYPE_HOST				2
    diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config
    index 1549e06a6ef..1edf1648c70 100644
    --- a/crypto/openssh/ssh_config
    +++ b/crypto/openssh/ssh_config
    @@ -1,4 +1,4 @@
    -#	$OpenBSD: ssh_config,v 1.25 2009/02/17 01:28:32 djm Exp $
    +#	$OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $
     #	$FreeBSD$
     
     # This is the ssh client system-wide configuration file.  See
    @@ -45,4 +45,5 @@
     #   TunnelDevice any:any
     #   PermitLocalCommand no
     #   VisualHostKey no
    -#   VersionAddendum FreeBSD-20090522
    +#   ProxyCommand ssh -q -W %h:%p gateway.example.com
    +#   VersionAddendum FreeBSD-20100308
    diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5
    index e5e020e5415..0f67fdc6c8a 100644
    --- a/crypto/openssh/ssh_config.5
    +++ b/crypto/openssh/ssh_config.5
    @@ -34,9 +34,9 @@
     .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     .\"
    -.\" $OpenBSD: ssh_config.5,v 1.119 2009/02/22 23:50:57 djm Exp $
    +.\" $OpenBSD: ssh_config.5,v 1.129 2010/03/05 10:28:21 djm Exp $
     .\" $FreeBSD$
    -.Dd February 22 2009
    +.Dd March 5 2010
     .Dt SSH_CONFIG 5
     .Os
     .Sh NAME
    @@ -560,6 +560,12 @@ and
     for protocol version 2.
     Additionally, any identities represented by the authentication agent
     will be used for authentication.
    +.Xr ssh 1
    +will try to load certificate information from the filename obtained by
    +appending
    +.Pa -cert.pub
    +to the path of a specified
    +.Cm IdentityFile .
     .Pp
     The file name may use the tilde
     syntax to refer to a user's home directory or one of the following
    @@ -617,6 +623,13 @@ The following escape character substitutions will be performed:
     (remote user name) or
     .Ql %u
     (local user name).
    +.Pp
    +The command is run synchronously and does not have access to the
    +session of the
    +.Xr ssh 1
    +that spawned it.
    +It should not be used for interactive commands.
    +.Pp
     This directive is ignored unless
     .Cm PermitLocalCommand
     has been enabled.
    @@ -705,6 +718,12 @@ or
     .Dq no .
     The default is
     .Dq no .
    +.It Cm PKCS11Provider
    +Specifies which PKCS#11 provider to use.
    +The argument to this keyword is the PKCS#11 shared libary
    +.Xr ssh 1
    +should use to communicate with a PKCS#11 token providing the user's
    +private RSA key.
     .It Cm Port
     Specifies the port number to connect on the remote host.
     The default is 22.
    @@ -731,11 +750,13 @@ The possible values are
     and
     .Sq 2 .
     Multiple versions must be comma-separated.
    -The default is
    -.Dq 2,1 .
    -This means that ssh
    -tries version 2 and falls back to version 1
    +When this option is set to
    +.Dq 2,1
    +.Nm ssh
    +will try version 2 and fall back to version 1
     if version 2 is not available.
    +The default is
    +.Sq 2 .
     .It Cm ProxyCommand
     Specifies the command to use to connect to the server.
     The command
    @@ -919,13 +940,6 @@ channel to request a response from the server.
     The default
     is 0, indicating that these messages will not be sent to the server.
     This option applies to protocol version 2 only.
    -.It Cm SmartcardDevice
    -Specifies which smartcard device to use.
    -The argument to this keyword is the device
    -.Xr ssh 1
    -should use to communicate with a smartcard used for storing the user's
    -private RSA key.
    -By default, no device is specified and smartcard support is not activated.
     .It Cm StrictHostKeyChecking
     If this flag is set to
     .Dq yes ,
    @@ -1073,7 +1087,7 @@ in
     Specifies a string to append to the regular version string to identify
     OS- or site-specific modifications.
     The default is
    -.Dq FreeBSD-20090522 .
    +.Dq FreeBSD-20100308 .
     .It Cm VisualHostKey
     If this flag is set to
     .Dq yes ,
    diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h
    index 8fdf708a6a5..caa14c8ca04 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,7 +18,9 @@
     #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_cidr_list			ssh_addr_match_cidr_list
     #define addr_match_list				ssh_addr_match_list
     #define ask_permission				ssh_ask_permission
     #define atomicio				ssh_atomicio
    @@ -54,6 +56,7 @@
     #define buffer_get_short_ret			ssh_buffer_get_short_ret
     #define buffer_get_string			ssh_buffer_get_string
     #define buffer_get_string_ptr			ssh_buffer_get_string_ptr
    +#define buffer_get_string_ptr_ret		ssh_buffer_get_string_ptr_ret
     #define buffer_get_string_ret			ssh_buffer_get_string_ret
     #define buffer_init				ssh_buffer_init
     #define buffer_len				ssh_buffer_len
    @@ -89,6 +92,7 @@
     #define channel_close_all			ssh_channel_close_all
     #define channel_close_fd			ssh_channel_close_fd
     #define channel_connect_by_listen_address	ssh_channel_connect_by_listen_address
    +#define channel_connect_stdio_fwd		ssh_channel_connect_stdio_fwd
     #define channel_connect_to			ssh_channel_connect_to
     #define channel_find_open			ssh_channel_find_open
     #define channel_free				ssh_channel_free
    @@ -111,10 +115,11 @@
     #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
    -#define channel_register_confirm		ssh_channel_register_confirm
     #define channel_register_filter			ssh_channel_register_filter
     #define channel_register_open_confirm		ssh_channel_register_open_confirm
     #define channel_register_status_confirm		ssh_channel_register_status_confirm
    @@ -150,18 +155,21 @@
     #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 debug					ssh_debug
    +#define current_keys				ssh_current_keys
    +#define datafellows				ssh_datafellows
     #define debug					ssh_debug
     #define debug2					ssh_debug2
    -#define debug2					ssh_debug2
    -#define debug3					ssh_debug3
     #define debug3					ssh_debug3
     #define decode_reply				ssh_decode_reply
     #define deny_input_open				ssh_deny_input_open
    @@ -174,6 +182,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
    @@ -185,7 +194,6 @@
     #define enable_compat13				ssh_enable_compat13
     #define enable_compat20				ssh_enable_compat20
     #define error					ssh_error
    -#define error					ssh_error
     #define evp_acss				ssh_evp_acss
     #define evp_aes_128_ctr				ssh_evp_aes_128_ctr
     #define evp_rijndael				ssh_evp_rijndael
    @@ -193,7 +201,6 @@
     #define evp_ssh1_bf				ssh_evp_ssh1_bf
     #define export_dns_rr				ssh_export_dns_rr
     #define fatal					ssh_fatal
    -#define fatal					ssh_fatal
     #define fmt_scaled				ssh_fmt_scaled
     #define freeargs				ssh_freeargs
     #define freerrset				ssh_freerrset
    @@ -204,6 +211,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
    @@ -212,9 +220,12 @@
     #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
    +#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
    @@ -227,14 +238,22 @@
     #define kexdh_client				ssh_kexdh_client
     #define kexgex_client				ssh_kexgex_client
     #define kexgex_hash				ssh_kexgex_hash
    +#define key_add_private				ssh_key_add_private
    +#define key_cert_check_authority		ssh_key_cert_check_authority
    +#define key_cert_copy				ssh_key_cert_copy
    +#define key_certify				ssh_key_certify
     #define key_demote				ssh_key_demote
    +#define key_drop_cert				ssh_key_drop_cert
     #define key_equal				ssh_key_equal
    +#define key_equal_public			ssh_key_equal_public
     #define key_fingerprint				ssh_key_fingerprint
     #define key_fingerprint_raw			ssh_key_fingerprint_raw
     #define key_free				ssh_key_free
     #define key_from_blob				ssh_key_from_blob
     #define key_from_private			ssh_key_from_private
     #define key_generate				ssh_key_generate
    +#define key_in_file				ssh_key_in_file
    +#define key_is_cert				ssh_key_is_cert
     #define key_load_private			ssh_key_load_private
     #define key_load_private_pem			ssh_key_load_private_pem
     #define key_load_private_type			ssh_key_load_private_type
    @@ -250,8 +269,10 @@
     #define key_size				ssh_key_size
     #define key_ssh_name				ssh_key_ssh_name
     #define key_to_blob				ssh_key_to_blob
    +#define key_to_certified			ssh_key_to_certified
     #define key_type				ssh_key_type
     #define key_type_from_name			ssh_key_type_from_name
    +#define key_type_plain				ssh_key_type_plain
     #define key_verify				ssh_key_verify
     #define key_write				ssh_key_write
     #define log_facility_name			ssh_log_facility_name
    @@ -260,13 +281,13 @@
     #define log_level_name				ssh_log_level_name
     #define log_level_number			ssh_log_level_number
     #define logit					ssh_logit
    -#define logit					ssh_logit
     #define lookup_key_in_hostfile_by_type		ssh_lookup_key_in_hostfile_by_type
     #define mac_clear				ssh_mac_clear
     #define mac_compute				ssh_mac_compute
     #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
    @@ -278,7 +299,9 @@
     #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
     #define packet_connection_is_ipv4		ssh_packet_connection_is_ipv4
     #define packet_connection_is_on_socket		ssh_packet_connection_is_on_socket
    @@ -289,10 +312,15 @@
     #define packet_get_connection_in		ssh_packet_get_connection_in
     #define packet_get_connection_out		ssh_packet_get_connection_out
     #define packet_get_encryption_key		ssh_packet_get_encryption_key
    +#define packet_get_input			ssh_packet_get_input
     #define packet_get_int				ssh_packet_get_int
    +#define packet_get_int64			ssh_packet_get_int64
     #define packet_get_keycontext			ssh_packet_get_keycontext
     #define packet_get_keyiv			ssh_packet_get_keyiv
     #define packet_get_keyiv_len			ssh_packet_get_keyiv_len
    +#define packet_get_maxsize			ssh_packet_get_maxsize
    +#define packet_get_newkeys			ssh_packet_get_newkeys
    +#define packet_get_output			ssh_packet_get_output
     #define packet_get_protocol_flags		ssh_packet_get_protocol_flags
     #define packet_get_raw				ssh_packet_get_raw
     #define packet_get_ssh1_cipher			ssh_packet_get_ssh1_cipher
    @@ -300,6 +328,7 @@
     #define packet_get_string			ssh_packet_get_string
     #define packet_get_string_ptr			ssh_packet_get_string_ptr
     #define packet_have_data_to_write		ssh_packet_have_data_to_write
    +#define packet_inc_alive_timeouts		ssh_packet_inc_alive_timeouts
     #define packet_is_interactive			ssh_packet_is_interactive
     #define packet_need_rekeying			ssh_packet_need_rekeying
     #define packet_not_very_much_data_to_write	ssh_packet_not_very_much_data_to_write
    @@ -309,6 +338,7 @@
     #define packet_put_char				ssh_packet_put_char
     #define packet_put_cstring			ssh_packet_put_cstring
     #define packet_put_int				ssh_packet_put_int
    +#define packet_put_int64			ssh_packet_put_int64
     #define packet_put_raw				ssh_packet_put_raw
     #define packet_put_string			ssh_packet_put_string
     #define packet_read				ssh_packet_read
    @@ -317,9 +347,11 @@
     #define packet_read_poll_seqnr			ssh_packet_read_poll_seqnr
     #define packet_read_seqnr			ssh_packet_read_seqnr
     #define packet_remaining			ssh_packet_remaining
    +#define packet_restore_state			ssh_packet_restore_state
     #define packet_send				ssh_packet_send
     #define packet_send_debug			ssh_packet_send_debug
     #define packet_send_ignore			ssh_packet_send_ignore
    +#define packet_set_alive_timeouts		ssh_packet_set_alive_timeouts
     #define packet_set_authenticated		ssh_packet_set_authenticated
     #define packet_set_connection			ssh_packet_set_connection
     #define packet_set_encryption_key		ssh_packet_set_encryption_key
    @@ -340,6 +372,12 @@
     #define percent_expand				ssh_percent_expand
     #define permanently_drop_suid			ssh_permanently_drop_suid
     #define permanently_set_uid			ssh_permanently_set_uid
    +#define pkcs11_add_provider			ssh_pkcs11_add_provider
    +#define pkcs11_del_provider			ssh_pkcs11_del_provider
    +#define pkcs11_init				ssh_pkcs11_init
    +#define pkcs11_interactive			ssh_pkcs11_interactive
    +#define pkcs11_providers			ssh_pkcs11_providers
    +#define pkcs11_terminate			ssh_pkcs11_terminate
     #define prime_test				ssh_prime_test
     #define proto_spec				ssh_proto_spec
     #define put_host_port				ssh_put_host_port
    @@ -352,9 +390,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
    @@ -368,6 +410,7 @@
     #define set_nonblock				ssh_set_nonblock
     #define shadow_pw				ssh_shadow_pw
     #define sigdie					ssh_sigdie
    +#define sock_set_v6only				ssh_sock_set_v6only
     #define ssh1_3des_iv				ssh_ssh1_3des_iv
     #define start_progress_meter			ssh_start_progress_meter
     #define stop_progress_meter			ssh_stop_progress_meter
    @@ -382,6 +425,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
    @@ -390,7 +434,6 @@
     #define uudecode				ssh_uudecode
     #define uuencode				ssh_uuencode
     #define verbose					ssh_verbose
    -#define verbose					ssh_verbose
     #define verify_host_key_dns			ssh_verify_host_key_dns
     #define vis					ssh_vis
     #define x11_connect_display			ssh_x11_connect_display
    diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c
    index cc214714c3c..a54d94270b9 100644
    --- a/crypto/openssh/sshconnect.c
    +++ b/crypto/openssh/sshconnect.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sshconnect.c,v 1.212 2008/10/14 18:11:33 stevesk Exp $ */
    +/* $OpenBSD: sshconnect.c,v 1.220 2010/03/04 10:36:03 djm Exp $ */
     /* $FreeBSD$ */
     /*
      * Author: Tatu Ylonen 
    @@ -29,6 +29,7 @@
     
     #include 
     #include 
    +#include 
     #include 
     #ifdef HAVE_PATHS_H
     #include 
    @@ -57,6 +58,8 @@
     #include "atomicio.h"
     #include "misc.h"
     #include "dns.h"
    +#include "roaming.h"
    +#include "ssh2.h"
     #include "version.h"
     
     char *client_version_string = NULL;
    @@ -191,8 +194,11 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
     		return sock;
     	}
     	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    -	if (sock < 0)
    +	if (sock < 0) {
     		error("socket: %.100s", strerror(errno));
    +		return -1;
    +	}
    +	fcntl(sock, F_SETFD, FD_CLOEXEC);
     
     	/* Bind the socket to an alternative local IP address */
     	if (options.bind_address == NULL)
    @@ -414,7 +420,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
      * Waits for the server identification string, and sends our own
      * identification string.
      */
    -static void
    +void
     ssh_exchange_identification(int timeout_ms)
     {
     	char buf[256], remote_version[256];	/* must be same size! */
    @@ -453,7 +459,7 @@ ssh_exchange_identification(int timeout_ms)
     				}
     			}
     
    -			len = atomicio(read, connection_in, &buf[i], 1);
    +			len = roaming_atomicio(read, connection_in, &buf[i], 1);
     
     			if (len != 1 && errno == EPIPE)
     				fatal("ssh_exchange_identification: "
    @@ -538,7 +544,8 @@ ssh_exchange_identification(int timeout_ms)
     	    compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
     	    compat20 ? PROTOCOL_MINOR_2 : minor1,
     	    SSH_VERSION, compat20 ? "\r\n" : "\n");
    -	if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
    +	if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf))
    +	    != strlen(buf))
     		fatal("write: %.100s", strerror(errno));
     	client_version_string = xstrdup(buf);
     	chop(client_version_string);
    @@ -571,6 +578,23 @@ confirm(const char *prompt)
     	}
     }
     
    +static int
    +check_host_cert(const char *host, const Key *host_key)
    +{
    +	const char *reason;
    +
    +	if (key_cert_check_authority(host_key, 1, 0, host, &reason) != 0) {
    +		error("%s", reason);
    +		return 0;
    +	}
    +	if (buffer_len(&host_key->cert->constraints) != 0) {
    +		error("Certificate for %s contains unsupported constraint(s)",
    +		    host);
    +		return 0;
    +	}
    +	return 1;
    +}
    +
     /*
      * check whether the supplied host key is valid, return -1 if the key
      * is not valid. the user_hostfile will not be updated if 'readonly' is true.
    @@ -583,13 +607,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
         Key *host_key, int readonly, const char *user_hostfile,
         const char *system_hostfile)
     {
    -	Key *file_key;
    -	const char *type = key_type(host_key);
    +	Key *file_key, *raw_key = NULL;
    +	const char *type;
     	char *ip = NULL, *host = NULL;
     	char hostline[1000], *hostp, *fp, *ra;
     	HostStatus host_status;
     	HostStatus ip_status;
    -	int r, local = 0, host_ip_differ = 0;
    +	int r, want_cert, local = 0, host_ip_differ = 0;
     	int salen;
     	char ntop[NI_MAXHOST];
     	char msg[1024];
    @@ -662,11 +686,15 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
     		host = put_host_port(hostname, port);
     	}
     
    + retry:
    +	want_cert = key_is_cert(host_key);
    +	type = key_type(host_key);
    +
     	/*
     	 * Store the host key from the known host file in here so that we can
     	 * compare it with the key for the IP address.
     	 */
    -	file_key = key_new(host_key->type);
    +	file_key = key_new(key_is_cert(host_key) ? KEY_UNSPEC : host_key->type);
     
     	/*
     	 * Check if the host key is present in the user's list of known
    @@ -682,9 +710,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
     	}
     	/*
     	 * Also perform check for the ip address, skip the check if we are
    -	 * localhost or the hostname was an ip address to begin with
    +	 * localhost, looking for a certificate, or the hostname was an ip
    +	 * address to begin with.
     	 */
    -	if (options.check_host_ip) {
    +	if (!want_cert && options.check_host_ip) {
     		Key *ip_key = key_new(host_key->type);
     
     		ip_file = user_hostfile;
    @@ -708,11 +737,14 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
     	switch (host_status) {
     	case HOST_OK:
     		/* The host is known and the key matches. */
    -		debug("Host '%.200s' is known and matches the %s host key.",
    -		    host, type);
    -		debug("Found key in %s:%d", host_file, host_line);
    +		debug("Host '%.200s' is known and matches the %s host %s.",
    +		    host, type, want_cert ? "certificate" : "key");
    +		debug("Found %s in %s:%d",
    +		    want_cert ? "certificate" : "key", host_file, host_line);
    +		if (want_cert && !check_host_cert(hostname, host_key))
    +			goto fail;
     		if (options.check_host_ip && ip_status == HOST_NEW) {
    -			if (readonly)
    +			if (readonly || want_cert)
     				logit("%s host key for IP address "
     				    "'%.128s' not in list of known hosts.",
     				    type, ip);
    @@ -744,7 +776,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
     				break;
     			}
     		}
    -		if (readonly)
    +		if (readonly || want_cert)
     			goto fail;
     		/* The host is new. */
     		if (options.strict_host_key_checking == 1) {
    @@ -828,7 +860,37 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
     			logit("Warning: Permanently added '%.200s' (%s) to the "
     			    "list of known hosts.", hostp, type);
     		break;
    +	case HOST_REVOKED:
    +		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
    +		error("@       WARNING: REVOKED HOST KEY DETECTED!               @");
    +		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
    +		error("The %s host key for %s is marked as revoked.", type, host);
    +		error("This could mean that a stolen key is being used to");
    +		error("impersonate this host.");
    +
    +		/*
    +		 * If strict host key checking is in use, the user will have
    +		 * to edit the key manually and we can only abort.
    +		 */
    +		if (options.strict_host_key_checking) {
    +			error("%s host key for %.200s was revoked and you have "
    +			    "requested strict checking.", type, host);
    +			goto fail;
    +		}
    +		goto continue_unsafe;
    +
     	case HOST_CHANGED:
    +		if (want_cert) {
    +			/*
    +			 * This is only a debug() since it is valid to have
    +			 * CAs with wildcard DNS matches that don't match
    +			 * all hosts that one might visit.
    +			 */
    +			debug("Host certificate authority does not "
    +			    "match %s in %s:%d", CA_MARKER,
    +			    host_file, host_line);
    +			goto fail;
    +		}
     		if (readonly == ROQUIET)
     			goto fail;
     		if (options.check_host_ip && host_ip_differ) {
    @@ -866,6 +928,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
     			goto fail;
     		}
     
    + continue_unsafe:
     		/*
     		 * If strict host key checking has not been requested, allow
     		 * the connection but without MITM-able authentication or
    @@ -924,7 +987,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
     		 * XXX Should permit the user to change to use the new id.
     		 * This could be done by converting the host key to an
     		 * identifying sentence, tell that the host identifies itself
    -		 * by that sentence, and ask the user if he/she whishes to
    +		 * by that sentence, and ask the user if he/she wishes to
     		 * accept the authentication.
     		 */
     		break;
    @@ -965,6 +1028,20 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
     	return 0;
     
     fail:
    +	if (want_cert && host_status != HOST_REVOKED) {
    +		/*
    +		 * No matching certificate. Downgrade cert to raw key and
    +		 * search normally.
    +		 */
    +		debug("No matching CA found. Retry with plain key");
    +		raw_key = key_from_private(host_key);
    +		if (key_drop_cert(raw_key) != 0)
    +			fatal("Couldn't drop certificate");
    +		host_key = raw_key;
    +		goto retry;
    +	}
    +	if (raw_key != NULL)
    +		key_free(raw_key);
     	xfree(ip);
     	xfree(host);
     	return -1;
    @@ -977,7 +1054,8 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
     	struct stat st;
     	int flags = 0;
     
    -	if (options.verify_host_key_dns &&
    +	/* XXX certs are not yet supported for DNS */
    +	if (!key_is_cert(host_key) && options.verify_host_key_dns &&
     	    verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
     
     		if (flags & DNS_VERIFY_FOUND) {
    diff --git a/crypto/openssh/sshconnect.h b/crypto/openssh/sshconnect.h
    index 75bde1a4db1..c59a097f4eb 100644
    --- a/crypto/openssh/sshconnect.h
    +++ b/crypto/openssh/sshconnect.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sshconnect.h,v 1.24 2007/09/04 11:15:56 djm Exp $ */
    +/* $OpenBSD: sshconnect.h,v 1.25 2009/05/27 06:38:16 andreas Exp $ */
     
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
    @@ -38,6 +38,8 @@ ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int,
     void
     ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int);
     
    +void	 ssh_exchange_identification(int);
    +
     int	 verify_host_key(char *, struct sockaddr *, Key *);
     
     void	 ssh_kex(char *, struct sockaddr *);
    diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c
    index a762eec3bdb..2a5943e7e26 100644
    --- a/crypto/openssh/sshconnect2.c
    +++ b/crypto/openssh/sshconnect2.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sshconnect2.c,v 1.170 2008/11/04 08:22:13 djm Exp $ */
    +/* $OpenBSD: sshconnect2.c,v 1.180 2010/02/26 20:29:54 djm Exp $ */
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
      * Copyright (c) 2008 Damien Miller.  All rights reserved.
    @@ -32,6 +32,7 @@
     #include 
     
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -68,6 +69,7 @@
     #include "msg.h"
     #include "pathnames.h"
     #include "uidswap.h"
    +#include "schnorr.h"
     #include "jpake.h"
     
     #ifdef GSSAPI
    @@ -151,6 +153,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
     
     	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
     
    +	if (options.use_roaming && !kex->roaming) {
    +		debug("Roaming not allowed by server");
    +		options.use_roaming = 0;
    +	}
    +
     	session_id2 = kex->session_id;
     	session_id2_len = kex->session_id_len;
     
    @@ -209,6 +216,7 @@ struct Authmethod {
     };
     
     void	input_userauth_success(int, u_int32_t, void *);
    +void	input_userauth_success_unexpected(int, u_int32_t, void *);
     void	input_userauth_failure(int, u_int32_t, void *);
     void	input_userauth_banner(int, u_int32_t, void *);
     void	input_userauth_error(int, u_int32_t, void *);
    @@ -413,7 +421,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
     		if (len > 65536)
     			len = 65536;
     		msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
    -		strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL);
    +		strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
     		fprintf(stderr, "%s", msg);
     		xfree(msg);
     	}
    @@ -426,12 +434,15 @@ void
     input_userauth_success(int type, u_int32_t seq, void *ctxt)
     {
     	Authctxt *authctxt = ctxt;
    +
     	if (authctxt == NULL)
     		fatal("input_userauth_success: no authentication context");
     	if (authctxt->authlist) {
     		xfree(authctxt->authlist);
     		authctxt->authlist = NULL;
     	}
    +	if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
    +		authctxt->method->cleanup(authctxt);
     	if (authctxt->methoddata) {
     		xfree(authctxt->methoddata);
     		authctxt->methoddata = NULL;
    @@ -439,6 +450,18 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
     	authctxt->success = 1;			/* break out */
     }
     
    +void
    +input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
    +{
    +	Authctxt *authctxt = ctxt;
    +
    +	if (authctxt == NULL)
    +		fatal("%s: no authentication context", __func__);
    +
    +	fatal("Unexpected authentication success during %s.",
    +	    authctxt->method->name);
    +}
    +
     /* ARGSUSED */
     void
     input_userauth_failure(int type, u_int32_t seq, void *ctxt)
    @@ -781,6 +804,8 @@ userauth_passwd(Authctxt *authctxt)
     	static int attempt = 0;
     	char prompt[150];
     	char *password;
    +	const char *host = options.host_key_alias ?  options.host_key_alias :
    +	    authctxt->host;
     
     	if (attempt++ >= options.number_of_password_prompts)
     		return 0;
    @@ -789,7 +814,7 @@ userauth_passwd(Authctxt *authctxt)
     		error("Permission denied, please try again.");
     
     	snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
    -	    authctxt->server_user, authctxt->host);
    +	    authctxt->server_user, host);
     	password = read_passphrase(prompt, 0);
     	packet_start(SSH2_MSG_USERAUTH_REQUEST);
     	packet_put_cstring(authctxt->server_user);
    @@ -818,6 +843,8 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
     	Authctxt *authctxt = ctxt;
     	char *info, *lang, *password = NULL, *retype = NULL;
     	char prompt[150];
    +	const char *host = options.host_key_alias ? options.host_key_alias :
    +	    authctxt->host;
     
     	debug2("input_userauth_passwd_changereq");
     
    @@ -838,7 +865,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
     	packet_put_char(1);			/* additional info */
     	snprintf(prompt, sizeof(prompt),
     	    "Enter %.30s@%.128s's old password: ",
    -	    authctxt->server_user, authctxt->host);
    +	    authctxt->server_user, host);
     	password = read_passphrase(prompt, 0);
     	packet_put_cstring(password);
     	memset(password, 0, strlen(password));
    @@ -847,7 +874,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
     	while (password == NULL) {
     		snprintf(prompt, sizeof(prompt),
     		    "Enter %.30s@%.128s's new password: ",
    -		    authctxt->server_user, authctxt->host);
    +		    authctxt->server_user, host);
     		password = read_passphrase(prompt, RP_ALLOW_EOF);
     		if (password == NULL) {
     			/* bail out */
    @@ -855,7 +882,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
     		}
     		snprintf(prompt, sizeof(prompt),
     		    "Retype %.30s@%.128s's new password: ",
    -		    authctxt->server_user, authctxt->host);
    +		    authctxt->server_user, host);
     		retype = read_passphrase(prompt, 0);
     		if (strcmp(password, retype) != 0) {
     			memset(password, 0, strlen(password));
    @@ -1223,7 +1250,7 @@ load_identity_file(char *filename)
     {
     	Key *private;
     	char prompt[300], *passphrase;
    -	int perm_ok, quit, i;
    +	int perm_ok = 0, quit, i;
     	struct stat st;
     
     	if (stat(filename, &st) < 0) {
    @@ -1284,6 +1311,8 @@ pubkey_prepare(Authctxt *authctxt)
     		key = options.identity_keys[i];
     		if (key && key->type == KEY_RSA1)
     			continue;
    +		if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER)
    +			continue;
     		options.identity_keys[i] = NULL;
     		id = xcalloc(1, sizeof(*id));
     		id->key = key;
    @@ -1487,7 +1516,7 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
     	debug2("ssh_keysign called");
     
     	if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
    -		error("ssh_keysign: no installed: %s", strerror(errno));
    +		error("ssh_keysign: not installed: %s", strerror(errno));
     		return -1;
     	}
     	if (fflush(stdout) != 0)
    @@ -1505,6 +1534,8 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
     		return -1;
     	}
     	if (pid == 0) {
    +		/* keep the socket on exec */
    +		fcntl(packet_get_connection_in(), F_SETFD, 0);
     		permanently_drop_suid(getuid());
     		close(from[0]);
     		if (dup2(from[1], STDOUT_FILENO) < 0)
    @@ -1557,10 +1588,10 @@ userauth_hostbased(Authctxt *authctxt)
     	Sensitive *sensitive = authctxt->sensitive;
     	Buffer b;
     	u_char *signature, *blob;
    -	char *chost, *pkalg, *p, myname[NI_MAXHOST];
    +	char *chost, *pkalg, *p;
     	const char *service;
     	u_int blen, slen;
    -	int ok, i, len, found = 0;
    +	int ok, i, found = 0;
     
     	/* check for a useful key */
     	for (i = 0; i < sensitive->nkeys; i++) {
    @@ -1581,23 +1612,13 @@ userauth_hostbased(Authctxt *authctxt)
     		return 0;
     	}
     	/* figure out a name for the client host */
    -	p = NULL;
    -	if (packet_connection_is_on_socket())
    -		p = get_local_name(packet_get_connection_in());
    -	if (p == NULL) {
    -		if (gethostname(myname, sizeof(myname)) == -1) {
    -			verbose("userauth_hostbased: gethostname: %s", 
    -			    strerror(errno));
    -		} else
    -			p = xstrdup(myname);
    -	}
    +	p = get_local_name(packet_get_connection_in());
     	if (p == NULL) {
     		error("userauth_hostbased: cannot get local ipaddr/name");
     		key_free(private);
     		xfree(blob);
     		return 0;
     	}
    -	len = strlen(p) + 2;
     	xasprintf(&chost, "%s.", p);
     	debug2("userauth_hostbased: chost %s", chost);
     	xfree(p);
    @@ -1708,6 +1729,8 @@ userauth_jpake(Authctxt *authctxt)
     	/* Expect step 1 packet from peer */
     	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1,
     	    input_userauth_jpake_server_step1);
    +	dispatch_set(SSH2_MSG_USERAUTH_SUCCESS,
    +	    &input_userauth_success_unexpected);
     
     	return 1;
     }
    @@ -1720,6 +1743,7 @@ userauth_jpake_cleanup(Authctxt *authctxt)
     		jpake_free(authctxt->methoddata);
     		authctxt->methoddata = NULL;
     	}
    +	dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
     }
     #endif /* JPAKE */
     
    diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8
    index f74decf3904..b4a88f823b9 100644
    --- a/crypto/openssh/sshd.8
    +++ b/crypto/openssh/sshd.8
    @@ -34,9 +34,9 @@
     .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     .\"
    -.\" $OpenBSD: sshd.8,v 1.247 2008/10/03 13:08:12 jmc Exp $
    +.\" $OpenBSD: sshd.8,v 1.255 2010/03/05 06:50:35 jmc Exp $
     .\" $FreeBSD$
    -.Dd October 3 2008
    +.Dd March 5 2010
     .Dt SSHD 8
     .Os
     .Sh NAME
    @@ -48,6 +48,7 @@
     .Op Fl 46DdeiqTt
     .Op Fl b Ar bits
     .Op Fl C Ar connection_spec
    +.Op Fl c Ar host_certificate_file
     .Op Fl f Ar config_file
     .Op Fl g Ar login_grace_time
     .Op Fl h Ar host_key_file
    @@ -120,6 +121,15 @@ and
     All are required and may be supplied in any order, either with multiple
     .Fl C
     options or as a comma-separated list.
    +.It Fl c Ar host_certificate_file
    +Specifies a path to a certificate file to identify
    +.Nm
    +during key exchange.
    +The certificate file must match a host key file specified using the
    +.Fl h
    +option or the
    +.Cm HostKey
    +configuration directive.
     .It Fl D
     When this option is specified,
     .Nm
    @@ -128,8 +138,8 @@ This allows easy monitoring of
     .Nm sshd .
     .It Fl d
     Debug mode.
    -The server sends verbose debug output to the system
    -log, and does not put itself in the background.
    +The server sends verbose debug output to standard error,
    +and does not put itself in the background.
     The server also will not fork and will only process one connection.
     This option is only intended for debugging for the server.
     Multiple
    @@ -261,7 +271,7 @@ or
     .El
     .Sh AUTHENTICATION
     The OpenSSH SSH daemon supports SSH protocols 1 and 2.
    -Both protocols are supported by default,
    +The default is to use protocol 2 only,
     though this can be changed via the
     .Cm Protocol
     option in
    @@ -501,6 +511,13 @@ No spaces are permitted, except within double quotes.
     The following option specifications are supported (note
     that option keywords are case-insensitive):
     .Bl -tag -width Ds
    +.It Cm cert-authority
    +Specifies that the listed key is a certification authority (CA) that is
    +trusted to validate signed certificates for user authentication.
    +.Pp
    +Certificates may encode access restrictions similar to these key options.
    +If both certificate restrictions and key options are present, the most
    +restrictive union of the two is applied.
     .It Cm command="command"
     Specifies that the command is executed whenever this key is used for
     authentication.
    @@ -520,6 +537,10 @@ The command originally supplied by the client is available in the
     .Ev SSH_ORIGINAL_COMMAND
     environment variable.
     Note that this option applies to shell, command or subsystem execution.
    +Also note that this command may be superseded by either a
    +.Xr sshd_config 5
    +.Cm ForceCommand
    +directive or a command embedded in a certificate.
     .It Cm environment="NAME=value"
     Specifies that the string is to be added to the environment when
     logging in using this key.
    @@ -546,7 +567,7 @@ for more information on patterns.
     In addition to the wildcard matching that may be applied to hostnames or
     addresses, a
     .Cm from
    -stanza may match IP addressess using CIDR address/masklen notation.
    +stanza may match IP addresses using CIDR address/masklen notation.
     .Pp
     The purpose of this option is to optionally increase security: public key
     authentication by itself does not trust the network or name servers or
    @@ -616,10 +637,19 @@ be prepared by the administrator (optional), and the per-user file is
     maintained automatically: whenever the user connects from an unknown host,
     its key is added to the per-user file.
     .Pp
    -Each line in these files contains the following fields: hostnames,
    -bits, exponent, modulus, comment.
    +Each line in these files contains the following fields: markers (optional),
    +hostnames, bits, exponent, modulus, comment.
     The fields are separated by spaces.
     .Pp
    +The marker is optional, but if it is present then it must be one of
    +.Dq @cert-authority ,
    +to indicate that the line contains a certification authority (CA) key,
    +or
    +.Dq @revoked ,
    +to indicate that the key contained on the line is revoked and must not ever
    +be accepted.
    +Only one marker should be used on a key line.
    +.Pp
     Hostnames is a comma-separated list of patterns
     .Pf ( Ql *
     and
    @@ -659,8 +689,25 @@ Lines starting with
     and empty lines are ignored as comments.
     .Pp
     When performing host authentication, authentication is accepted if any
    -matching line has the proper key.
    -It is thus permissible (but not
    +matching line has the proper key; either one that matches exactly or,
    +if the server has presented a certificate for authentication, the key
    +of the certification authority that signed the certificate.
    +For a key to be trusted as a certification authority, it must use the
    +.Dq @cert-authority
    +marker described above.
    +.Pp
    +The known hosts file also provides a facility to mark keys as revoked,
    +for example when it is known that the associated private key has been
    +stolen.
    +Revoked keys are specified by including the
    +.Dq @revoked
    +marker at the beginning of the key line, and are never accepted for
    +authentication or as certification authorities, but instead will
    +produce a warning from
    +.Xr ssh 1
    +when they are encountered.
    +.Pp
    +It is permissible (but not
     recommended) to have several lines or different host keys for the same
     names.
     This will inevitably happen when short forms of host names
    @@ -671,10 +718,16 @@ accepted if valid information can be found from either file.
     .Pp
     Note that the lines in these files are typically hundreds of characters
     long, and you definitely don't want to type in the host keys by hand.
    -Rather, generate them by a script
    +Rather, generate them by a script,
    +.Xr ssh-keyscan 1
     or by taking
     .Pa /etc/ssh/ssh_host_key.pub
     and adding the host names at the front.
    +.Xr ssh-keygen 1
    +also offers some basic automated editing for
    +.Pa ~/.ssh/known_hosts
    +including removing hosts matching a host name and converting all host
    +names to their hashed representations.
     .Pp
     An example ssh_known_hosts file:
     .Bd -literal -offset 3n
    @@ -684,6 +737,10 @@ cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=
     # A hashed hostname
     |1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
     AAAA1234.....=
    +# A revoked key
    +@revoked * ssh-rsa AAAAB5W...
    +# A CA key, accepted for any host in *.mydomain.com or *.mydomain.org
    +@cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W...
     .Ed
     .Sh FILES
     .Bl -tag -width Ds -compact
    diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
    index 3b955d944b7..9cc12a3de49 100644
    --- a/crypto/openssh/sshd.c
    +++ b/crypto/openssh/sshd.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sshd.c,v 1.366 2009/01/22 10:02:34 djm Exp $ */
    +/* $OpenBSD: sshd.c,v 1.374 2010/03/07 11:57:13 dtucker Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -129,6 +129,7 @@ __RCSID("$FreeBSD$");
     #include "ssh-gss.h"
     #endif
     #include "monitor_wrap.h"
    +#include "roaming.h"
     #include "version.h"
     
     #ifdef LIBWRAP
    @@ -216,6 +217,7 @@ struct {
     	Key	*server_key;		/* ephemeral server key */
     	Key	*ssh1_host_key;		/* ssh1 host key */
     	Key	**host_keys;		/* all private host keys */
    +	Key	**host_certificates;	/* all public host certificates */
     	int	have_ssh1_key;
     	int	have_ssh2_key;
     	u_char	ssh1_cookie[SSH_SESSION_KEY_LENGTH];
    @@ -320,6 +322,7 @@ sighup_restart(void)
     	close_listen_socks();
     	close_startup_pipes();
     	alarm(0);  /* alarm timer persists across exec */
    +	signal(SIGHUP, SIG_IGN); /* will be restored after exec */
     	execv(saved_argv[0], saved_argv);
     	logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
     	    strerror(errno));
    @@ -431,7 +434,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
     	server_version_string = xstrdup(buf);
     
     	/* Send our protocol version identification. */
    -	if (atomicio(vwrite, sock_out, server_version_string,
    +	if (roaming_atomicio(vwrite, sock_out, server_version_string,
     	    strlen(server_version_string))
     	    != strlen(server_version_string)) {
     		logit("Could not write ident string to %s", get_remote_ipaddr());
    @@ -441,7 +444,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
     	/* Read other sides version identification. */
     	memset(buf, 0, sizeof(buf));
     	for (i = 0; i < sizeof(buf) - 1; i++) {
    -		if (atomicio(read, sock_in, &buf[i], 1) != 1) {
    +		if (roaming_atomicio(read, sock_in, &buf[i], 1) != 1) {
     			logit("Did not receive identification string from %s",
     			    get_remote_ipaddr());
     			cleanup_exit(255);
    @@ -555,6 +558,10 @@ destroy_sensitive_data(void)
     			key_free(sensitive_data.host_keys[i]);
     			sensitive_data.host_keys[i] = NULL;
     		}
    +		if (sensitive_data.host_certificates[i]) {
    +			key_free(sensitive_data.host_certificates[i]);
    +			sensitive_data.host_certificates[i] = NULL;
    +		}
     	}
     	sensitive_data.ssh1_host_key = NULL;
     	memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH);
    @@ -581,6 +588,7 @@ demote_sensitive_data(void)
     			if (tmp->type == KEY_RSA1)
     				sensitive_data.ssh1_host_key = tmp;
     		}
    +		/* Certs do not need demotion */
     	}
     
     	/* We do not clear ssh1_host key and cookie.  XXX - Okay Niels? */
    @@ -589,7 +597,7 @@ demote_sensitive_data(void)
     static void
     privsep_preauth_child(void)
     {
    - 	u_int32_t rnd[256];
    +	u_int32_t rnd[256];
     	gid_t gidset[1];
     
     	/* Enable challenge-response authentication for privilege separation */
    @@ -727,10 +735,11 @@ list_hostkey_types(void)
     	const char *p;
     	char *ret;
     	int i;
    +	Key *key;
     
     	buffer_init(&b);
     	for (i = 0; i < options.num_host_key_files; i++) {
    -		Key *key = sensitive_data.host_keys[i];
    +		key = sensitive_data.host_keys[i];
     		if (key == NULL)
     			continue;
     		switch (key->type) {
    @@ -742,6 +751,19 @@ list_hostkey_types(void)
     			buffer_append(&b, p, strlen(p));
     			break;
     		}
    +		/* If the private key has a cert peer, then list that too */
    +		key = sensitive_data.host_certificates[i];
    +		if (key == NULL)
    +			continue;
    +		switch (key->type) {
    +		case KEY_RSA_CERT:
    +		case KEY_DSA_CERT:
    +			if (buffer_len(&b) > 0)
    +				buffer_append(&b, ",", 1);
    +			p = key_ssh_name(key);
    +			buffer_append(&b, p, strlen(p));
    +			break;
    +		}
     	}
     	buffer_append(&b, "\0", 1);
     	ret = xstrdup(buffer_ptr(&b));
    @@ -750,19 +772,36 @@ list_hostkey_types(void)
     	return ret;
     }
     
    -Key *
    -get_hostkey_by_type(int type)
    +static Key *
    +get_hostkey_by_type(int type, int need_private)
     {
     	int i;
    +	Key *key;
     
     	for (i = 0; i < options.num_host_key_files; i++) {
    -		Key *key = sensitive_data.host_keys[i];
    +		if (type == KEY_RSA_CERT || type == KEY_DSA_CERT)
    +			key = sensitive_data.host_certificates[i];
    +		else
    +			key = sensitive_data.host_keys[i];
     		if (key != NULL && key->type == type)
    -			return key;
    +			return need_private ?
    +			    sensitive_data.host_keys[i] : key;
     	}
     	return NULL;
     }
     
    +Key *
    +get_hostkey_public_by_type(int type)
    +{
    +	return get_hostkey_by_type(type, 0);
    +}
    +
    +Key *
    +get_hostkey_private_by_type(int type)
    +{
    +	return get_hostkey_by_type(type, 1);
    +}
    +
     Key *
     get_hostkey_by_index(int ind)
     {
    @@ -777,8 +816,13 @@ get_hostkey_index(Key *key)
     	int i;
     
     	for (i = 0; i < options.num_host_key_files; i++) {
    -		if (key == sensitive_data.host_keys[i])
    -			return (i);
    +		if (key_is_cert(key)) {
    +			if (key == sensitive_data.host_certificates[i])
    +				return (i);
    +		} else {
    +			if (key == sensitive_data.host_keys[i])
    +				return (i);
    +		}
     	}
     	return (-1);
     }
    @@ -817,9 +861,9 @@ usage(void)
     	fprintf(stderr, "%s, %s\n",
     	    SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
     	fprintf(stderr,
    -"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]\n"
    -"            [-g login_grace_time] [-h host_key_file] [-k key_gen_time]\n"
    -"            [-o option] [-p port] [-u len]\n"
    +"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n"
    +"            [-f config_file] [-g login_grace_time] [-h host_key_file]\n"
    +"            [-k key_gen_time] [-o option] [-p port] [-u len]\n"
     	);
     	exit(1);
     }
    @@ -990,15 +1034,9 @@ server_listen(void)
     		    &on, sizeof(on)) == -1)
     			error("setsockopt SO_REUSEADDR: %s", strerror(errno));
     
    -#ifdef IPV6_V6ONLY
     		/* Only communicate in IPv6 over AF_INET6 sockets. */
    -		if (ai->ai_family == AF_INET6) {
    -			if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
    -			    &on, sizeof(on)) == -1)
    -				error("setsockopt IPV6_V6ONLY: %s",
    -				    strerror(errno));
    -		}
    -#endif
    +		if (ai->ai_family == AF_INET6)
    +			sock_set_v6only(listen_sock);
     
     		debug("Bind to port %s on %s.", strport, ntop);
     
    @@ -1252,7 +1290,7 @@ main(int ac, char **av)
     {
     	extern char *optarg;
     	extern int optind;
    -	int opt, i, on = 1;
    +	int opt, i, j, on = 1;
     	int sock_in = -1, sock_out = -1, newsock = -1;
     	const char *remote_ip;
     	char *test_user = NULL, *test_host = NULL, *test_addr = NULL;
    @@ -1305,6 +1343,14 @@ main(int ac, char **av)
     		case 'f':
     			config_file_name = optarg;
     			break;
    +		case 'c':
    +			if (options.num_host_cert_files >= MAX_HOSTCERTS) {
    +				fprintf(stderr, "too many host certificates.\n");
    +				exit(1);
    +			}
    +			options.host_cert_files[options.num_host_cert_files++] =
    +			   derelativise_path(optarg);
    +			break;
     		case 'd':
     			if (debug_flag == 0) {
     				debug_flag = 1;
    @@ -1367,7 +1413,8 @@ main(int ac, char **av)
     				fprintf(stderr, "too many host keys.\n");
     				exit(1);
     			}
    -			options.host_key_files[options.num_host_key_files++] = optarg;
    +			options.host_key_files[options.num_host_key_files++] = 
    +			   derelativise_path(optarg);
     			break;
     		case 't':
     			test_flag = 1;
    @@ -1551,6 +1598,46 @@ main(int ac, char **av)
     		exit(1);
     	}
     
    +	/*
    +	 * Load certificates. They are stored in an array at identical
    +	 * indices to the public keys that they relate to.
    +	 */
    +	sensitive_data.host_certificates = xcalloc(options.num_host_key_files,
    +	    sizeof(Key *));
    +	for (i = 0; i < options.num_host_key_files; i++)
    +		sensitive_data.host_certificates[i] = NULL;
    +
    +	for (i = 0; i < options.num_host_cert_files; i++) {
    +		key = key_load_public(options.host_cert_files[i], NULL);
    +		if (key == NULL) {
    +			error("Could not load host certificate: %s",
    +			    options.host_cert_files[i]);
    +			continue;
    +		}
    +		if (!key_is_cert(key)) {
    +			error("Certificate file is not a certificate: %s",
    +			    options.host_cert_files[i]);
    +			key_free(key);
    +			continue;
    +		}
    +		/* Find matching private key */
    +		for (j = 0; j < options.num_host_key_files; j++) {
    +			if (key_equal_public(key,
    +			    sensitive_data.host_keys[j])) {
    +				sensitive_data.host_certificates[j] = key;
    +				break;
    +			}
    +		}
    +		if (j >= options.num_host_key_files) {
    +			error("No matching private key for certificate: %s",
    +			    options.host_cert_files[i]);
    +			key_free(key);
    +			continue;
    +		}
    +		sensitive_data.host_certificates[j] = key;
    +		debug("host certificate: #%d type %d %s", j, key->type,
    +		    key_type(key));
    +	}
     	/* Check certain values for sanity. */
     	if (options.protocol & SSH_PROTO_1) {
     		if (options.server_key_bits < 512 ||
    @@ -1677,6 +1764,7 @@ main(int ac, char **av)
     	if (inetd_flag) {
     		server_accept_inetd(&sock_in, &sock_out);
     	} else {
    +		platform_pre_listen();
     		server_listen();
     
     		if (options.protocol & SSH_PROTO_1)
    @@ -1766,6 +1854,10 @@ main(int ac, char **av)
     		    sock_in, sock_out, newsock, startup_pipe, config_s[0]);
     	}
     
    +	/* Executed child processes don't need these. */
    +	fcntl(sock_out, F_SETFD, FD_CLOEXEC);
    +	fcntl(sock_in, F_SETFD, FD_CLOEXEC);
    +
     	/*
     	 * Disable the key regeneration alarm.  We will not regenerate the
     	 * key since we are no longer in a position to give it to anyone. We
    @@ -1886,6 +1978,7 @@ main(int ac, char **av)
     
     	/* prepare buffer to collect messages to display to user after login */
     	buffer_init(&loginmsg);
    +	auth_debug_reset();
     
     	if (use_privsep)
     		if (privsep_preauth(authctxt) == 1)
    @@ -2242,7 +2335,8 @@ do_ssh2_kex(void)
     	kex->server = 1;
     	kex->client_version_string=client_version_string;
     	kex->server_version_string=server_version_string;
    -	kex->load_host_key=&get_hostkey_by_type;
    +	kex->load_host_public_key=&get_hostkey_public_by_type;
    +	kex->load_host_private_key=&get_hostkey_private_by_type;
     	kex->host_key_index=&get_hostkey_index;
     
     	xxx_kex = kex;
    diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config
    index c2c08843df2..44b75821e83 100644
    --- a/crypto/openssh/sshd_config
    +++ b/crypto/openssh/sshd_config
    @@ -1,4 +1,4 @@
    -#	$OpenBSD: sshd_config,v 1.80 2008/07/02 02:24:18 djm Exp $
    +#	$OpenBSD: sshd_config,v 1.81 2009/10/08 14:03:41 markus Exp $
     #	$FreeBSD$
     
     # This is the sshd server system-wide configuration file.  See
    @@ -14,18 +14,15 @@
     # Note that some of FreeBSD's defaults differ from OpenBSD's, and
     # FreeBSD has a few additional options.
     
    -#VersionAddendum FreeBSD-20090522
    +#VersionAddendum FreeBSD-20100308
     
     #Port 22
    -#Protocol 2
     #AddressFamily any
     #ListenAddress 0.0.0.0
     #ListenAddress ::
     
    -# Disable legacy (protocol version 1) support in the server for new
    -# installations. In future the default will change to require explicit
    -# activation of protocol 1
    -Protocol 2
    +# The default requires explicit activation of protocol 1
    +#Protocol 2
     
     # HostKey for protocol version 1
     #HostKey /etc/ssh/ssh_host_key
    diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5
    index 6779f0a5e57..d0d3053b7a8 100644
    --- a/crypto/openssh/sshd_config.5
    +++ b/crypto/openssh/sshd_config.5
    @@ -34,9 +34,9 @@
     .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     .\"
    -.\" $OpenBSD: sshd_config.5,v 1.102 2009/02/22 23:59:25 djm Exp $
    +.\" $OpenBSD: sshd_config.5,v 1.120 2010/03/04 23:17:25 djm Exp $
     .\" $FreeBSD$
    -.Dd February 22 2009
    +.Dd March 4 2010
     .Dt SSHD_CONFIG 5
     .Os
     .Sh NAME
    @@ -177,19 +177,22 @@ then no banner is displayed.
     This option is only available for protocol version 2.
     By default, no banner is displayed.
     .It Cm ChallengeResponseAuthentication
    -Specifies whether challenge-response authentication is allowed.
    -See also
    -.Cm UsePAM .
    +Specifies whether challenge-response authentication is allowed (e.g. via
    +PAM or though authentication styles supported in
    +.Xr login.conf 5 )
     The default is
     .Dq yes .
     .It Cm ChrootDirectory
    -Specifies a path to
    +Specifies the pathname of a directory to
     .Xr chroot 2
     to after authentication.
    -This path, and all its components, must be root-owned directories that are
    +All components of the pathname must be root-owned directories that are
     not writable by any other user or group.
    +After the chroot,
    +.Xr sshd 8
    +changes the working directory to the user's home directory.
     .Pp
    -The path may contain the following tokens that are expanded at runtime once
    +The pathname may contain the following tokens that are expanded at runtime once
     the connecting user has been authenticated: %% is replaced by a literal '%',
     %h is replaced by the home directory of the user being authenticated, and
     %u is replaced by the username of that user.
    @@ -197,7 +200,7 @@ the connecting user has been authenticated: %% is replaced by a literal '%',
     The
     .Cm ChrootDirectory
     must contain the necessary files and directories to support the
    -users' session.
    +user's session.
     For an interactive session this requires at least a shell, typically
     .Xr sh 1 ,
     and basic
    @@ -215,8 +218,11 @@ devices.
     For file transfer sessions using
     .Dq sftp ,
     no additional configuration of the environment is necessary if the
    -in-process sftp server is used (see
    -.Cm Subsystem
    +in-process sftp server is used,
    +though sessions which use logging do require
    +.Pa /dev/log
    +inside the chroot directory (see
    +.Xr sftp-server 8
     for details).
     .Pp
     The default is not to
    @@ -406,6 +412,14 @@ uses the name supplied by the client rather than
     attempting to resolve the name from the TCP connection itself.
     The default is
     .Dq no .
    +.It Cm HostCertificate
    +Specifies a file containing a public host certificate.
    +The certificate's public key must match a private host key already specified
    +by
    +.Cm HostKey .
    +The default behaviour of
    +.Xr sshd 8
    +is not to load any certificates.
     .It Cm HostKey
     Specifies a file containing a private host key
     used by SSH.
    @@ -609,6 +623,7 @@ Available keywords are
     .Cm PermitEmptyPasswords ,
     .Cm PermitOpen ,
     .Cm PermitRootLogin ,
    +.Cm PubkeyAuthentication ,
     .Cm RhostsRSAAuthentication ,
     .Cm RSAAuthentication ,
     .Cm X11DisplayOffset ,
    @@ -796,7 +811,7 @@ and
     .Sq 2 .
     Multiple versions must be comma-separated.
     The default is
    -.Dq 2 .
    +.Sq 2 .
     Note that the order of the protocol list does not indicate preference,
     because the client selects among multiple protocol versions offered
     by the server.
    @@ -809,6 +824,11 @@ Specifies whether public key authentication is allowed.
     The default is
     .Dq yes .
     Note that this option applies to protocol version 2 only.
    +.It Cm RevokedKeys
    +Specifies a list of revoked public keys.
    +Keys listed in this file will be refused for public key authentication.
    +Note that if this file is not readable, then public key authentication will
    +be refused for all users.
     .It Cm RhostsRSAAuthentication
     Specifies whether rhosts or
     .Pa /etc/hosts.equiv
    @@ -834,6 +854,9 @@ This is normally desirable because novices sometimes accidentally leave their
     directory or files world-writable.
     The default is
     .Dq yes .
    +Note that this does not apply to
    +.Cm ChrootDirectory ,
    +whose permissions and ownership are checked unconditionally.
     .It Cm Subsystem
     Configures an external subsystem (e.g. file transfer daemon).
     Arguments should be a subsystem name and a command (with optional arguments)
    @@ -883,6 +906,22 @@ This avoids infinitely hanging sessions.
     .Pp
     To disable TCP keepalive messages, the value should be set to
     .Dq no .
    +.It Cm TrustedUserCAKeys
    +Specifies a file containing public keys of certificate authorities that are
    +trusted to sign user certificates for authentication.
    +Keys are listed one per line; empty lines and comments starting with
    +.Ql #
    +are allowed.
    +If a certificate is presented for authentication and has its signing CA key
    +listed in this file, then it may be used for authentication for any user
    +listed in the certificate's principals list.
    +Note that certificates that lack a list of principals will not be permitted
    +for authentication using
    +.Cm TrustedUserCAKeys .
    +For more details on certificates, see the
    +.Sx CERTIFICATES
    +section in
    +.Xr ssh-keygen 1 .
     .It Cm UseDNS
     Specifies whether
     .Xr sshd 8
    @@ -949,7 +988,7 @@ The default is
     Specifies a string to append to the regular version string to identify
     OS- or site-specific modifications.
     The default is
    -.Dq FreeBSD-20090522 .
    +.Dq FreeBSD-20100308 .
     .It Cm X11DisplayOffset
     Specifies the first display number available for
     .Xr sshd 8 Ns 's
    diff --git a/crypto/openssh/sshlogin.c b/crypto/openssh/sshlogin.c
    index cc35d6024b4..33bd652fb0b 100644
    --- a/crypto/openssh/sshlogin.c
    +++ b/crypto/openssh/sshlogin.c
    @@ -86,13 +86,20 @@ get_last_login_time(uid_t uid, const char *logname,
     static void
     store_lastlog_message(const char *user, uid_t uid)
     {
    +#ifndef NO_SSH_LASTLOG
     	char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512];
     	time_t last_login_time;
     
    -#ifndef NO_SSH_LASTLOG
     	if (!options.print_lastlog)
     		return;
     
    +# ifdef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
    +	time_string = sys_auth_get_lastlogin_msg(user, uid);
    +	if (time_string != NULL) {
    +		buffer_append(&loginmsg, time_string, strlen(time_string));
    +		xfree(time_string);
    +	}
    +# else
     	last_login_time = get_last_login_time(uid, user, hostname,
     	    sizeof(hostname));
     
    @@ -107,6 +114,7 @@ store_lastlog_message(const char *user, uid_t uid)
     			    time_string, hostname);
     		buffer_append(&loginmsg, buf, strlen(buf));
     	}
    +# endif /* CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG */
     #endif /* NO_SSH_LASTLOG */
     }
     
    diff --git a/crypto/openssh/sshpty.h b/crypto/openssh/sshpty.h
    index ac900358462..cfa322480f5 100644
    --- a/crypto/openssh/sshpty.h
    +++ b/crypto/openssh/sshpty.h
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sshpty.h,v 1.11 2008/05/19 15:45:07 djm Exp $ */
    +/* $OpenBSD: sshpty.h,v 1.12 2010/01/09 05:04:24 djm Exp $ */
     
     /*
      * Author: Tatu Ylonen 
    @@ -17,8 +17,8 @@
     #include 
     
     struct termios *get_saved_tio(void);
    -void	 leave_raw_mode(void);
    -void	 enter_raw_mode(void);
    +void	 leave_raw_mode(int);
    +void	 enter_raw_mode(int);
     
     int	 pty_allocate(int *, int *, char *, size_t);
     void	 pty_release(const char *);
    diff --git a/crypto/openssh/sshtty.c b/crypto/openssh/sshtty.c
    index 21ade4e5153..d214ce3bb1a 100644
    --- a/crypto/openssh/sshtty.c
    +++ b/crypto/openssh/sshtty.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: sshtty.c,v 1.13 2008/05/19 15:45:07 djm Exp $ */
    +/* $OpenBSD: sshtty.c,v 1.14 2010/01/09 05:04:24 djm Exp $ */
     /*
      * Author: Tatu Ylonen 
      * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland
    @@ -54,23 +54,25 @@ get_saved_tio(void)
     }
     
     void
    -leave_raw_mode(void)
    +leave_raw_mode(int quiet)
     {
     	if (!_in_raw_mode)
     		return;
    -	if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1)
    -		perror("tcsetattr");
    -	else
    +	if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) {
    +		if (!quiet)
    +			perror("tcsetattr");
    +	} else
     		_in_raw_mode = 0;
     }
     
     void
    -enter_raw_mode(void)
    +enter_raw_mode(int quiet)
     {
     	struct termios tio;
     
     	if (tcgetattr(fileno(stdin), &tio) == -1) {
    -		perror("tcgetattr");
    +		if (!quiet)
    +			perror("tcgetattr");
     		return;
     	}
     	_saved_tio = tio;
    @@ -86,8 +88,9 @@ enter_raw_mode(void)
     	tio.c_oflag &= ~OPOST;
     	tio.c_cc[VMIN] = 1;
     	tio.c_cc[VTIME] = 0;
    -	if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1)
    -		perror("tcsetattr");
    -	else
    +	if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) {
    +		if (!quiet)
    +			perror("tcsetattr");
    +	} else
     		_in_raw_mode = 1;
     }
    diff --git a/crypto/openssh/uuencode.c b/crypto/openssh/uuencode.c
    index a13949585f8..b9e57e9934b 100644
    --- a/crypto/openssh/uuencode.c
    +++ b/crypto/openssh/uuencode.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: uuencode.c,v 1.24 2006/08/03 03:34:42 deraadt Exp $ */
    +/* $OpenBSD: uuencode.c,v 1.25 2009/03/05 11:30:50 djm Exp $ */
     /*
      * Copyright (c) 2000 Markus Friedl.  All rights reserved.
      *
    @@ -33,6 +33,12 @@
     #include "xmalloc.h"
     #include "uuencode.h"
     
    +/*
    + * Encode binary 'src' of length 'srclength', writing base64-encoded text
    + * to 'target' of size 'targsize'. Will always nul-terminate 'target'.
    + * Returns the number of bytes stored in 'target' or -1 on error (inc.
    + * 'targsize' too small).
    + */
     int
     uuencode(const u_char *src, u_int srclength,
         char *target, size_t targsize)
    @@ -40,6 +46,11 @@ uuencode(const u_char *src, u_int srclength,
     	return __b64_ntop(src, srclength, target, targsize);
     }
     
    +/*
    + * Decode base64-encoded 'src' into buffer 'target' of 'targsize' bytes.
    + * Will skip leading and trailing whitespace. Returns the number of bytes
    + * stored in 'target' or -1 on error (inc. targsize too small).
    + */
     int
     uudecode(const char *src, u_char *target, size_t targsize)
     {
    diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h
    index ff87b920e9f..d1d1452e99d 100644
    --- a/crypto/openssh/version.h
    +++ b/crypto/openssh/version.h
    @@ -1,12 +1,12 @@
    -/* $OpenBSD: version.h,v 1.55 2009/02/23 00:06:15 djm Exp $ */
    +/* $OpenBSD: version.h,v 1.57 2010/03/07 22:01:32 djm Exp $ */
     /* $FreeBSD$ */
     
     #ifndef SSH_VERSION
     
     #define SSH_VERSION             (ssh_version_get())
     #define SSH_RELEASE             (ssh_version_get())
    -#define SSH_VERSION_BASE        "OpenSSH_5.2p1"
    -#define SSH_VERSION_ADDENDUM    "FreeBSD-20090522"
    +#define SSH_VERSION_BASE        "OpenSSH_5.4p1"
    +#define SSH_VERSION_ADDENDUM    "FreeBSD-20100308"
     
     const char *ssh_version_get(void);
     void ssh_version_set_addendum(const char *);
    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
     
    diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.c b/lib/libpam/modules/pam_ssh/pam_ssh.c
    index 25c63ca7585..9d89045ac22 100644
    --- a/lib/libpam/modules/pam_ssh/pam_ssh.c
    +++ b/lib/libpam/modules/pam_ssh/pam_ssh.c
    @@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$");
     #include "authfd.h"
     #include "authfile.h"
     
    +#define ssh_add_identity(auth, key, comment) \
    +	ssh_add_identity_constrained(auth, key, comment, 0, 0)
    +
     extern char **environ;
     
     struct pam_ssh_key {
    diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile
    index ecc1a928165..d50b8d138ab 100644
    --- a/secure/lib/libssh/Makefile
    +++ b/secure/lib/libssh/Makefile
    @@ -12,14 +12,15 @@ SRCS=	acss.c authfd.c authfile.c bufaux.c bufbn.c buffer.c \
     	readpass.c rsa.c ttymodes.c xmalloc.c addrmatch.c \
     	atomicio.c key.c dispatch.c kex.c mac.c uidswap.c uuencode.c misc.c \
     	monitor_fdpass.c rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c \
    -	kexgex.c kexdhc.c kexgexc.c scard.c msg.c progressmeter.c dns.c \
    -	entropy.c scard-opensc.c umac.c jpake.c schnorr.c
    +	kexgex.c kexdhc.c kexgexc.c msg.c progressmeter.c dns.c \
    +	entropy.c umac.c jpake.c schnorr.c \
    +	ssh-pkcs11.c
     
     # gss-genr.c should be in $SRCS but causes linking problems, so it is
     # 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
    diff --git a/secure/libexec/Makefile b/secure/libexec/Makefile
    index 1c3ee015a5e..0c680e4d7b9 100644
    --- a/secure/libexec/Makefile
    +++ b/secure/libexec/Makefile
    @@ -4,7 +4,7 @@
     
     SUBDIR=
     .if ${MK_OPENSSH} != "no"
    -SUBDIR+=sftp-server ssh-keysign
    +SUBDIR+=sftp-server ssh-keysign ssh-pkcs11-helper
     .endif
     
     .include 
    diff --git a/secure/libexec/sftp-server/Makefile b/secure/libexec/sftp-server/Makefile
    index 22ce649452f..7069cff9015 100644
    --- a/secure/libexec/sftp-server/Makefile
    +++ b/secure/libexec/sftp-server/Makefile
    @@ -5,8 +5,11 @@ SRCS=   sftp-server.c sftp-common.c sftp-server-main.c
     MAN=	sftp-server.8
     CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
     
    +# required when linking with a dynamic libssh 
    +SRCS+=	roaming_dummy.c
    +
     DPADD=	${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ}
    -LDADD=	-lssh -lcrypt -lcrypto -lz
    +LDADD=  -lssh -lcrypt -lcrypto -lz
     
     .include 
     
    diff --git a/secure/libexec/ssh-keysign/Makefile b/secure/libexec/ssh-keysign/Makefile
    index 6018b948265..75f1b6c4c28 100644
    --- a/secure/libexec/ssh-keysign/Makefile
    +++ b/secure/libexec/ssh-keysign/Makefile
    @@ -1,7 +1,7 @@
     # $FreeBSD$
     
     PROG=	ssh-keysign
    -SRCS=	ssh-keysign.c readconf.c
    +SRCS=	ssh-keysign.c readconf.c roaming_dummy.c
     MAN=	ssh-keysign.8
     CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
     .if defined(ENABLE_SUID_SSH)
    diff --git a/secure/libexec/ssh-pkcs11-helper/Makefile b/secure/libexec/ssh-pkcs11-helper/Makefile
    new file mode 100644
    index 00000000000..f575a08afea
    --- /dev/null
    +++ b/secure/libexec/ssh-pkcs11-helper/Makefile
    @@ -0,0 +1,16 @@
    +# $FreeBSD$
    +
    +PROG=	ssh-pkcs11-helper
    +SRCS=	ssh-pkcs11.c ssh-pkcs11-helper.c
    +SRCS+=	roaming_dummy.c
    +MAN=	ssh-pkcs11-helper.8
    +CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
    +
    +DPADD=	${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ}
    +LDADD=	-lssh -lcrypt -lcrypto -lz
    +
    +.include 
    +
    +.PATH:	${SSHDIR}
    +
    +${OBJS} ${POBJS} ${SOBJS}: ssh_namespace.h
    diff --git a/secure/usr.bin/scp/Makefile b/secure/usr.bin/scp/Makefile
    index ddb2b093015..8a558c77b95 100644
    --- a/secure/usr.bin/scp/Makefile
    +++ b/secure/usr.bin/scp/Makefile
    @@ -1,8 +1,12 @@
     # $FreeBSD$
     
     PROG=	scp
    +SRCS=	scp.c
     CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
     
    +# required when linking with a dynamic libssh
    +SRCS+=	roaming_dummy.c
    +
     DPADD=	${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ}
     LDADD=	-lssh -lcrypt -lcrypto -lz
     
    diff --git a/secure/usr.bin/sftp/Makefile b/secure/usr.bin/sftp/Makefile
    index 29c43527209..dce01048429 100644
    --- a/secure/usr.bin/sftp/Makefile
    +++ b/secure/usr.bin/sftp/Makefile
    @@ -4,6 +4,9 @@ PROG=	sftp
     SRCS=   sftp.c sftp-client.c sftp-common.c sftp-glob.c progressmeter.c
     CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
     
    +# required when linking with a dynamic libssh 
    +SRCS+=	roaming_dummy.c
    +
     DPADD=	${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} ${LIBEDIT} ${LIBNCURSES}
     LDADD=	-lssh -lcrypt -lcrypto -lz -ledit -lncurses
     
    diff --git a/secure/usr.bin/ssh-add/Makefile b/secure/usr.bin/ssh-add/Makefile
    index 34d66a6a771..0cbcbcb1a9b 100644
    --- a/secure/usr.bin/ssh-add/Makefile
    +++ b/secure/usr.bin/ssh-add/Makefile
    @@ -1,8 +1,12 @@
     # $FreeBSD$
     
     PROG=	ssh-add
    +SRCS+=	ssh-add.c
     CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
     
    +# required when linking with a dynamic libssh 
    +SRCS+=	roaming_dummy.c
    +
     DPADD=	${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ}
     LDADD=	-lssh -lcrypt -lcrypto -lz
     
    diff --git a/secure/usr.bin/ssh-agent/Makefile b/secure/usr.bin/ssh-agent/Makefile
    index ed99a01ced3..a93a1c64776 100644
    --- a/secure/usr.bin/ssh-agent/Makefile
    +++ b/secure/usr.bin/ssh-agent/Makefile
    @@ -1,8 +1,12 @@
     # $FreeBSD$
     
     PROG=	ssh-agent
    +SRCS=	ssh-agent.c
     CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
     
    +# required when linking with a dynamic libssh 
    +SRCS+=	roaming_dummy.c
    +
     DPADD=	${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ}
     LDADD=	-lssh -lcrypt -lcrypto -lz
     
    diff --git a/secure/usr.bin/ssh-keygen/Makefile b/secure/usr.bin/ssh-keygen/Makefile
    index 30adcf21479..0c250331023 100644
    --- a/secure/usr.bin/ssh-keygen/Makefile
    +++ b/secure/usr.bin/ssh-keygen/Makefile
    @@ -1,8 +1,12 @@
     # $FreeBSD$
     
     PROG=	ssh-keygen
    +SRCS=	ssh-keygen.c
     CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
     
    +# required when linking with a dynamic libssh 
    +SRCS+=  roaming_dummy.c
    +
     DPADD=	${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ}
     LDADD=	-lssh -lcrypt -lcrypto -lz
     
    diff --git a/secure/usr.bin/ssh-keyscan/Makefile b/secure/usr.bin/ssh-keyscan/Makefile
    index f59542e55fb..8d3f6c6b4e8 100644
    --- a/secure/usr.bin/ssh-keyscan/Makefile
    +++ b/secure/usr.bin/ssh-keyscan/Makefile
    @@ -1,6 +1,7 @@
     # $FreeBSD$
     
     PROG=	ssh-keyscan
    +SRCS=	ssh-keyscan.c roaming_dummy.c
     CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
     
     DPADD=	${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ}
    diff --git a/secure/usr.bin/ssh/Makefile b/secure/usr.bin/ssh/Makefile
    index 11ab8633f64..f85784ee0d2 100644
    --- a/secure/usr.bin/ssh/Makefile
    +++ b/secure/usr.bin/ssh/Makefile
    @@ -11,7 +11,10 @@ MLINKS=	ssh.1 slogin.1
     
     SRCS=	ssh.c readconf.c clientloop.c sshtty.c \
     	sshconnect.c sshconnect1.c sshconnect2.c mux.c \
    -	gss-genr.c
    +	roaming_common.c roaming_client.c
    +
    +# gss-genr.c really belongs in libssh; see src/secure/lib/libssh/Makefile
    +SRCS+=	gss-genr.c
     
     DPADD=	${LIBSSH} ${LIBUTIL} ${LIBZ}
     LDADD=	-lssh -lutil -lz
    diff --git a/secure/usr.sbin/sshd/Makefile b/secure/usr.sbin/sshd/Makefile
    index 282a40239b0..b0b8bb778f5 100644
    --- a/secure/usr.sbin/sshd/Makefile
    +++ b/secure/usr.sbin/sshd/Makefile
    @@ -15,9 +15,10 @@ SRCS=	sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
     	auth2-gss.c gss-serv.c gss-serv-krb5.c \
     	loginrec.c auth-pam.c auth-shadow.c auth-sia.c md5crypt.c \
     	audit.c audit-bsm.c platform.c sftp-server.c sftp-common.c \
    -	gss-genr.c
    +	roaming_common.c roaming_serv.c
     
     # gss-genr.c really belongs in libssh; see src/secure/lib/libssh/Makefile
    +SRCS+=	gss-genr.c
     
     MAN=	sshd.8 sshd_config.5
     CFLAGS+=-I${SSHDIR} -include ssh_namespace.h
    @@ -33,8 +34,8 @@ LDADD+=  -lbsm
     
     .if ${MK_KERBEROS_SUPPORT} != "no"
     CFLAGS+= -DGSSAPI -DHAVE_GSSAPI_GSSAPI_H=1 -DHAVE_GSSAPI_GSSAPI_KRB5_H=1 -DKRB5 -DHEIMDAL
    -DPADD+=	 ${LIBGSSAPI} ${LIBGSSAPI_KRB5}
    -LDADD+=	 -lgssapi -lgssapi_krb5
    +DPADD+=	 ${LIBGSSAPI_KRB5} ${LIBGSSAPI} ${LIBKRB5} ${LIBASN1}
    +LDADD+=	 -lgssapi_krb5 -lgssapi -lkrb5 -lasn1
     .endif
     
     .if defined(X11BASE)
    
    From c36c99a99d1c0dfe70590d444153dcc98dd8cbd8 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 21 Apr 2010 11:09:13 +0000
    Subject: [PATCH 2080/2592] MFC r206549: Align the declaration for sa_sigaction
     with POSIX.
    
    MFC r206649:
    Still reference struct __sigaction with clarification when this form
    of argument declaration is needed.
    
    MFC r206802:
    Revert r206649. Simplify the presented declaration of struct sigaction.
    ---
     lib/libc/sys/sigaction.2 | 21 +++++++++++++--------
     1 file changed, 13 insertions(+), 8 deletions(-)
    
    diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2
    index 4c4f18f2a68..3b4f2f0196d 100644
    --- a/lib/libc/sys/sigaction.2
    +++ b/lib/libc/sys/sigaction.2
    @@ -28,7 +28,7 @@
     .\"	From: @(#)sigaction.2	8.2 (Berkeley) 4/3/94
     .\" $FreeBSD$
     .\"
    -.Dd June 7, 2004
    +.Dd April 18, 2010
     .Dt SIGACTION 2
     .Os
     .Sh NAME
    @@ -40,16 +40,11 @@
     .In signal.h
     .Bd -literal
     struct  sigaction {
    -        union {
    -                void    (*__sa_handler)(int);
    -                void    (*__sa_sigaction)(int, struct __siginfo *, void *);
    -        } __sigaction_u;                /* signal handler */
    +        void    (*sa_handler)(int);
    +        void    (*sa_sigaction)(int, siginfo_t *, void *);
             int     sa_flags;               /* see signal options below */
             sigset_t sa_mask;               /* signal mask to apply */
     };
    -
    -#define	sa_handler	__sigaction_u.__sa_handler
    -#define	sa_sigaction	__sigaction_u.__sa_sigaction
     .Ed
     .Ft int
     .Fo sigaction
    @@ -148,6 +143,16 @@ If
     is non-zero, the previous handling information for the signal
     is returned to the user.
     .Pp
    +The above declaration of
    +.Vt "struct sigaction"
    +is not literal.
    +It is provided only to list the accessible members.
    +See
    +.In sys/signal.h
    +for the actual definition.
    +In particular, the storage occupied by sa_handler and sa_sigaction overlaps,
    +and an application can not use both simultaneously.
    +.Pp
     Once a signal handler is installed, it normally remains installed
     until another
     .Fn sigaction
    
    From 407b19379cefd6e6658e043b4619ec7e02b2189a Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Wed, 21 Apr 2010 19:45:41 +0000
    Subject: [PATCH 2081/2592] MFC r205345:
    
      Split eventhandler_register() into an internal part and a wrapper function
      that provides the allocated and setup eventhandler entry.
    
      Add a new wrapper for VIMAGE that allocates extra space to hold the
      callback function and argument in addition to an extra wrapper function.
      While the wrapper function goes as normal callback function the
      argument points to the extra space allocated holding the original func
      and arg that the wrapper function can then call.
    
      Provide an iterator function for the virtual network stack (vnet) that
      will call the callback function for each network stack.
    
      Provide a new set of macros for VNET that in the non-VIMAGE case will
      just call eventhandler_register() while in the VIMAGE case it will use
      vimage_eventhandler_register() passing in the extra iterator function
      but will only register once rather than per-vnet.
      We need a special macro in case we are interested in the tag returned
      as we must check for curvnet and can neither simply assign the
      return value, nor not change it in the non-vnet0 case without that.
    
      Discussed with:       jhb
      Reviewed by:  zec (earlier version), jhb
    ---
     sys/kern/subr_eventhandler.c | 79 ++++++++++++++++++++++++++----------
     sys/net/vnet.c               | 39 ++++++++++++++++++
     sys/net/vnet.h               | 30 ++++++++++++++
     sys/sys/eventhandler.h       | 16 ++++++++
     4 files changed, 143 insertions(+), 21 deletions(-)
    
    diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c
    index 37c482cbd7f..5894099abd2 100644
    --- a/sys/kern/subr_eventhandler.c
    +++ b/sys/kern/subr_eventhandler.c
    @@ -68,15 +68,15 @@ SYSINIT(eventhandlers, SI_SUB_EVENTHANDLER, SI_ORDER_FIRST, eventhandler_init,
      * Insertion is O(n) due to the priority scan, but optimises to O(1)
      * if all priorities are identical.
      */
    -eventhandler_tag
    -eventhandler_register(struct eventhandler_list *list, const char *name, 
    -		      void *func, void *arg, int priority)
    +static eventhandler_tag
    +eventhandler_register_internal(struct eventhandler_list *list,
    +    const char *name, eventhandler_tag epn)
     {
         struct eventhandler_list		*new_list;
    -    struct eventhandler_entry_generic	*eg;
         struct eventhandler_entry		*ep;
         
         KASSERT(eventhandler_lists_initted, ("eventhandler registered too early"));
    +    KASSERT(epn != NULL, ("%s: cannot register NULL event", __func__));
     
         /* lock the eventhandler lists */
         mtx_lock(&eventhandler_mutex);
    @@ -117,32 +117,69 @@ eventhandler_register(struct eventhandler_list *list, const char *name,
         }
         mtx_unlock(&eventhandler_mutex);
     
    +    KASSERT(epn->ee_priority != EHE_DEAD_PRIORITY,
    +	("%s: handler for %s registered with dead priority", __func__, name));
    +
    +    /* sort it into the list */
    +    CTR4(KTR_EVH, "%s: adding item %p (function %p) to \"%s\"", __func__, epn,
    +	((struct eventhandler_entry_generic *)epn)->func, name);
    +    EHL_LOCK(list);
    +    TAILQ_FOREACH(ep, &list->el_entries, ee_link) {
    +	if (ep->ee_priority != EHE_DEAD_PRIORITY &&
    +	    epn->ee_priority < ep->ee_priority) {
    +	    TAILQ_INSERT_BEFORE(ep, epn, ee_link);
    +	    break;
    +	}
    +    }
    +    if (ep == NULL)
    +	TAILQ_INSERT_TAIL(&list->el_entries, epn, ee_link);
    +    EHL_UNLOCK(list);
    +    return(epn);
    +}
    +
    +eventhandler_tag
    +eventhandler_register(struct eventhandler_list *list, const char *name, 
    +		      void *func, void *arg, int priority)
    +{
    +    struct eventhandler_entry_generic	*eg;
    +    
         /* allocate an entry for this handler, populate it */
         eg = malloc(sizeof(struct eventhandler_entry_generic), M_EVENTHANDLER,
     	M_WAITOK | M_ZERO);
         eg->func = func;
         eg->ee.ee_arg = arg;
         eg->ee.ee_priority = priority;
    -    KASSERT(priority != EHE_DEAD_PRIORITY,
    -	("%s: handler for %s registered with dead priority", __func__, name));
     
    -    /* sort it into the list */
    -    CTR4(KTR_EVH, "%s: adding item %p (function %p) to \"%s\"", __func__, eg,
    -	func, name);
    -    EHL_LOCK(list);
    -    TAILQ_FOREACH(ep, &list->el_entries, ee_link) {
    -	if (ep->ee_priority != EHE_DEAD_PRIORITY &&
    -	    eg->ee.ee_priority < ep->ee_priority) {
    -	    TAILQ_INSERT_BEFORE(ep, &eg->ee, ee_link);
    -	    break;
    -	}
    -    }
    -    if (ep == NULL)
    -	TAILQ_INSERT_TAIL(&list->el_entries, &eg->ee, ee_link);
    -    EHL_UNLOCK(list);
    -    return(&eg->ee);
    +    return (eventhandler_register_internal(list, name, &eg->ee));
     }
     
    +#ifdef VIMAGE
    +struct eventhandler_entry_generic_vimage
    +{
    +    struct eventhandler_entry		ee;
    +    vimage_iterator_func_t		func;		/* Vimage iterator function. */
    +    struct eventhandler_entry_vimage	v_ee;		/* Original func, arg. */
    +};
    +
    +eventhandler_tag
    +vimage_eventhandler_register(struct eventhandler_list *list, const char *name, 
    +    void *func, void *arg, int priority, vimage_iterator_func_t iterfunc)
    +{
    +    struct eventhandler_entry_generic_vimage	*eg;
    +    
    +    /* allocate an entry for this handler, populate it */
    +    eg = malloc(sizeof(struct eventhandler_entry_generic_vimage),
    +	M_EVENTHANDLER, M_WAITOK | M_ZERO);
    +    eg->func = iterfunc;
    +    eg->v_ee.func = func;
    +    eg->v_ee.ee_arg = arg;
    +    eg->ee.ee_arg = &eg->v_ee;
    +    eg->ee.ee_priority = priority;
    +
    +    return (eventhandler_register_internal(list, name, &eg->ee));
    +}
    +#endif
    +
     void
     eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
     {
    diff --git a/sys/net/vnet.c b/sys/net/vnet.c
    index 323ed085563..1dac03abf1d 100644
    --- a/sys/net/vnet.c
    +++ b/sys/net/vnet.c
    @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -55,6 +56,8 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    +#include 
    +
     #ifdef DDB
     #include 
     #include 
    @@ -637,6 +640,39 @@ vnet_sysuninit(void)
     	VNET_SYSINIT_RUNLOCK();
     }
     
    +/*
    + * EVENTHANDLER(9) extensions.
    + */
    +/*
    + * Invoke the eventhandler function originally registered with the possibly
    + * registered argument for all virtual network stack instances.
    + *
    + * This iterator can only be used for eventhandlers that do not take any
    + * additional arguments, as we do ignore the variadic arguments from the
    + * EVENTHANDLER_INVOKE() call.
    + */
    +void
    +vnet_global_eventhandler_iterator_func(void *arg, ...)
    +{
    +	VNET_ITERATOR_DECL(vnet_iter);
    +	struct eventhandler_entry_vimage *v_ee;
    +
    +	/*
    +	 * There is a bug here in that we should actually cast things to
    +	 * (struct eventhandler_entry_ ## name *)  but that's not easily
    +	 * possible in here so just re-using the variadic version we
    +	 * defined for the generic vimage case.
    +	 */
    +	v_ee = arg;
    +	VNET_LIST_RLOCK();
    +	VNET_FOREACH(vnet_iter) {
    +		CURVNET_SET(vnet_iter);
    +		((vimage_iterator_func_t)v_ee->func)(v_ee->ee_arg);
    +		CURVNET_RESTORE();
    +	}
    +	VNET_LIST_RUNLOCK();
    +}
    +
     #ifdef VNET_DEBUG
     struct vnet_recursion {
     	SLIST_ENTRY(vnet_recursion)	 vnr_le;
    @@ -696,6 +732,9 @@ vnet_log_recursion(struct vnet *old_vnet, const char *old_fn, int line)
     }
     #endif /* VNET_DEBUG */
     
    +/*
    + * DDB(4).
    + */
     #ifdef DDB
     DB_SHOW_COMMAND(vnets, db_show_vnets)
     {
    diff --git a/sys/net/vnet.h b/sys/net/vnet.h
    index d9a1ee0b679..fb2cc393cb7 100644
    --- a/sys/net/vnet.h
    +++ b/sys/net/vnet.h
    @@ -313,6 +313,29 @@ void	vnet_register_sysuninit(void *arg);
     void	vnet_deregister_sysinit(void *arg);
     void	vnet_deregister_sysuninit(void *arg);
     
    +/*
    + * EVENTHANDLER(9) extensions.
    + */
    +#include 
    +
    +void	vnet_global_eventhandler_iterator_func(void *, ...);
    +#define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
    +do {									\
    +	if (IS_DEFAULT_VNET(curvnet)) {					\
    +		(tag) = vimage_eventhandler_register(NULL, #name, func,	\
    +		    arg, priority,					\
    +		    vnet_global_eventhandler_iterator_func);		\
    +	}								\
    +} while(0)
    +#define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority)	\
    +do {									\
    +	if (IS_DEFAULT_VNET(curvnet)) {					\
    +		vimage_eventhandler_register(NULL, #name, func,		\
    +		    arg, priority,					\
    +		    vnet_global_eventhandler_iterator_func);		\
    +	}								\
    +} while(0)
    +
     #else /* !VIMAGE */
     
     /*
    @@ -384,6 +407,13 @@ void	vnet_deregister_sysuninit(void *arg);
     #define	VNET_SYSUNINIT(ident, subsystem, order, func, arg)		\
     	SYSUNINIT(ident, subsystem, order, func, arg)
     
    +/*
    + * Without VIMAGE revert to the default implementation.
    + */
    +#define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
    +	(tag) = eventhandler_register(NULL, #name, func, arg, priority)
    +#define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority)	\
    +	eventhandler_register(NULL, #name, func, arg, priority)
     #endif /* VIMAGE */
     #endif /* _KERNEL */
     
    diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h
    index 1f26d48f658..3f8846faab9 100644
    --- a/sys/sys/eventhandler.h
    +++ b/sys/sys/eventhandler.h
    @@ -41,6 +41,14 @@ struct eventhandler_entry {
     	void				*ee_arg;
     };
     
    +#ifdef VIMAGE
    +struct eventhandler_entry_vimage {
    +	void	(* func)(void);		/* Original function registered. */
    +	void	*ee_arg;		/* Original argument registered. */
    +	void	*sparep[2];
    +};
    +#endif
    +
     struct eventhandler_list {
     	char				*el_name;
     	int				el_flags;
    @@ -142,6 +150,14 @@ void	eventhandler_deregister(struct eventhandler_list *list,
     struct eventhandler_list *eventhandler_find_list(const char *name);
     void	eventhandler_prune_list(struct eventhandler_list *list);
     
    +#ifdef VIMAGE
    +typedef	void (*vimage_iterator_func_t)(void *, ...);
    +
    +eventhandler_tag vimage_eventhandler_register(struct eventhandler_list *list,
    +	    const char *name, void *func, void *arg, int priority,
    +	    vimage_iterator_func_t);
    +#endif
    +
     /*
      * Standard system event queues.
      */
    
    From b0cf9f5f207c99328556a7a18a7bc9d65df7f33f Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Wed, 21 Apr 2010 19:47:19 +0000
    Subject: [PATCH 2082/2592] MFC r206469:
    
      In if_detach_internal() only try to do the detach run if if_attachdomain1()
      has actually succeeded to initialize and attach.  There is a theoretical
      possibility to drop out early in if_attachdomain1() leaving the array
      uninitialized if we cannot get the lock.
    
      Discussed with:       rwatson
    ---
     sys/net/if.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/net/if.c b/sys/net/if.c
    index 8eff017e29d..fab354fce99 100644
    --- a/sys/net/if.c
    +++ b/sys/net/if.c
    @@ -931,7 +931,7 @@ if_detach_internal(struct ifnet *ifp, int vmove)
     	if_delgroups(ifp);
     
     	IF_AFDATA_LOCK(ifp);
    -	for (dp = domains; dp; dp = dp->dom_next) {
    +	for (dp = domains; ifp->if_afdata_initialized > 0 && dp; dp = dp->dom_next) {
     		if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
     			(*dp->dom_ifdetach)(ifp,
     			    ifp->if_afdata[dp->dom_family]);
    
    From 1ed532bb3dc089280498d08d29b508626c3c1c14 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Wed, 21 Apr 2010 19:48:40 +0000
    Subject: [PATCH 2083/2592] MFC r206470:
    
      In if_detach_internal() we cannot hold the af_data lock over the
      dom_ifdetach() calls as they might sleep for callout_drain().
      Do as we do in if_attachdomain1() [r121470] and handle
      if_afdata_initialized earlier and call dom_ifdetach() unlocked.
    
      Discussed with:       rwatson
    ---
     sys/net/if.c | 12 +++++++++---
     1 file changed, 9 insertions(+), 3 deletions(-)
    
    diff --git a/sys/net/if.c b/sys/net/if.c
    index fab354fce99..0773c2b6597 100644
    --- a/sys/net/if.c
    +++ b/sys/net/if.c
    @@ -930,14 +930,20 @@ if_detach_internal(struct ifnet *ifp, int vmove)
     		devctl_notify("IFNET", ifp->if_xname, "DETACH", NULL);
     	if_delgroups(ifp);
     
    +	/*
    +	 * We cannot hold the lock over dom_ifdetach calls as they might
    +	 * sleep, for example trying to drain a callout, thus open up the
    +	 * theoretical race with re-attaching.
    +	 */
     	IF_AFDATA_LOCK(ifp);
    -	for (dp = domains; ifp->if_afdata_initialized > 0 && dp; dp = dp->dom_next) {
    +	i = ifp->if_afdata_initialized;
    +	ifp->if_afdata_initialized = 0;
    +	IF_AFDATA_UNLOCK(ifp);
    +	for (dp = domains; i > 0 && dp; dp = dp->dom_next) {
     		if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
     			(*dp->dom_ifdetach)(ifp,
     			    ifp->if_afdata[dp->dom_family]);
     	}
    -	ifp->if_afdata_initialized = 0;
    -	IF_AFDATA_UNLOCK(ifp);
     }
     
     #ifdef VIMAGE
    
    From feb3a5f7df039ce84e55be3e239eda3c12f3f4ab Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Wed, 21 Apr 2010 19:51:22 +0000
    Subject: [PATCH 2084/2592] MFC r206481:
    
      Plug reference leaks in the link-layer code ("new-arp") that previously
      prevented the link-layer entry from being freed.
    
      In both in.c and in6.c (though that code path seems to be basically dead)
      plug a reference leak in case of a pending callout being drained.
    
      In if_ether.c consistently add a reference before resetting the callout
      and in case we canceled a pending one remove the reference for that.
      In the final case in arptimer, before freeing the expired entry, remove
      the reference again and explicitly call callout_stop() to clear the active
      flag.
    
      In nd6.c:nd6_free() we are only ever called from the callout function and
      thus need to remove the reference there as well before calling into
      llentry_free().
    
      In if_llatbl.c when freeing the entire tables make sure that in case we
      cancel a pending callout to remove the reference as well.
    
      Reviewed by:          qingli (earlier version)
      MFC after:            10 days
      Problem observed, patch tested by: simon on ipv6gw.f.o,
                            Christian Kratzer (ck cksoft.de),
                            Evgenii Davidov (dado korolev-net.ru)
    PR:			kern/144564
    Configurations still affected:	with options FLOWTABLE
    ---
     sys/net/if_llatbl.c    |  5 ++++-
     sys/netinet/if_ether.c | 18 +++++++++++++++---
     sys/netinet/in.c       |  6 +++++-
     sys/netinet6/in6.c     |  6 +++++-
     sys/netinet6/nd6.c     |  1 +
     5 files changed, 30 insertions(+), 6 deletions(-)
    
    diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
    index f934af5d675..c9b41f9bd37 100644
    --- a/sys/net/if_llatbl.c
    +++ b/sys/net/if_llatbl.c
    @@ -170,9 +170,12 @@ lltable_free(struct lltable *llt)
     
     	for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
     		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
    +			int canceled;
     
    -			callout_drain(&lle->la_timer);
    +			canceled = callout_drain(&lle->la_timer);
     			LLE_WLOCK(lle);
    +			if (canceled)
    +				LLE_REMREF(lle);
     			llentry_free(lle);
     		}
     	}
    diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
    index 4319035d72a..3e2504525f7 100644
    --- a/sys/netinet/if_ether.c
    +++ b/sys/netinet/if_ether.c
    @@ -180,6 +180,8 @@ arptimer(void *arg)
     	else {
     		if (!callout_pending(&lle->la_timer) &&
     		    callout_active(&lle->la_timer)) {
    +			callout_stop(&lle->la_timer);
    +			LLE_REMREF(lle);
     			(void) llentry_free(lle);
     			ARPSTAT_INC(timeouts);
     		} 
    @@ -382,9 +384,14 @@ retry:
     		    EHOSTUNREACH : EHOSTDOWN;
     
     	if (renew) {
    +		int canceled;
    +
     		LLE_ADDREF(la);
     		la->la_expire = time_second + V_arpt_down;
    -		callout_reset(&la->la_timer, hz * V_arpt_down, arptimer, la);
    +		canceled = callout_reset(&la->la_timer, hz * V_arpt_down,
    +		    arptimer, la);
    +		if (canceled)
    +			LLE_REMREF(la);
     		la->la_asked++;
     		LLE_WUNLOCK(la);
     		arprequest(ifp, NULL, &SIN(dst)->sin_addr,
    @@ -694,9 +701,14 @@ match:
     		la->la_flags |= LLE_VALID;
     
     		if (!(la->la_flags & LLE_STATIC)) {
    +			int canceled;
    +
    +			LLE_ADDREF(la);
     			la->la_expire = time_second + V_arpt_keep;
    -			callout_reset(&la->la_timer, hz * V_arpt_keep,
    -			    arptimer, la);
    +			canceled = callout_reset(&la->la_timer,
    +			    hz * V_arpt_keep, arptimer, la);
    +			if (canceled)
    +				LLE_REMREF(la);
     		}
     		la->la_asked = 0;
     		la->la_preempt = V_arp_maxtries;
    diff --git a/sys/netinet/in.c b/sys/netinet/in.c
    index c50a13fb2b4..21207916093 100644
    --- a/sys/netinet/in.c
    +++ b/sys/netinet/in.c
    @@ -1357,8 +1357,12 @@ in_lltable_prefix_free(struct lltable *llt,
     
     			if (IN_ARE_MASKED_ADDR_EQUAL((struct sockaddr_in *)L3_ADDR(lle), 
     						     pfx, msk)) {
    -				callout_drain(&lle->la_timer);
    +				int canceled;
    +
    +				canceled = callout_drain(&lle->la_timer);
     				LLE_WLOCK(lle);
    +				if (canceled)
    +					LLE_REMREF(lle);
     				llentry_free(lle);
     			}
     		}
    diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
    index 7e5d6d4eee0..1cceb9fcf9e 100644
    --- a/sys/netinet6/in6.c
    +++ b/sys/netinet6/in6.c
    @@ -2337,8 +2337,12 @@ in6_lltable_prefix_free(struct lltable *llt,
     				    &((struct sockaddr_in6 *)L3_ADDR(lle))->sin6_addr, 
     				    &pfx->sin6_addr, 
     				    &msk->sin6_addr)) {
    -				callout_drain(&lle->la_timer);
    +				int canceled;
    +
    +				canceled = callout_drain(&lle->la_timer);
     				LLE_WLOCK(lle);
    +				if (canceled)
    +					LLE_REMREF(lle);
     				llentry_free(lle);
     			}
     		}
    diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
    index 488a60abbc8..8e7d10e1126 100644
    --- a/sys/netinet6/nd6.c
    +++ b/sys/netinet6/nd6.c
    @@ -1124,6 +1124,7 @@ nd6_free(struct llentry *ln, int gc)
     	ifp = ln->lle_tbl->llt_ifp;
     	IF_AFDATA_LOCK(ifp);
     	LLE_WLOCK(ln);
    +	LLE_REMREF(ln);
     	llentry_free(ln);
     	IF_AFDATA_UNLOCK(ifp);
     
    
    From 984c5c6804797f4430e55a0b4de28b6eaedd4f66 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Wed, 21 Apr 2010 19:55:43 +0000
    Subject: [PATCH 2085/2592] MFC r206486:
    
      Check that the interface is on the list of cloned interfaces before trying
      to remove it to avoid panics in case of two threads trying to remove it in
      parallel.
    
    PR:	      kern/116837
    Submitted by: Takahiro Kurosawa (takahiro.kurosawa gmail.com) (orig version)
    ---
     sys/net/if_clone.c | 12 +++++++++++-
     1 file changed, 11 insertions(+), 1 deletion(-)
    
    diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c
    index 0dd20fb3610..81ac7ffbdba 100644
    --- a/sys/net/if_clone.c
    +++ b/sys/net/if_clone.c
    @@ -234,6 +234,7 @@ int
     if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
     {
     	int err;
    +	struct ifnet *ifcifp;
     
     	if (ifc->ifc_destroy == NULL)
     		return(EOPNOTSUPP);
    @@ -246,8 +247,17 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
     	CURVNET_SET_QUIET(ifp->if_vnet);
     
     	IF_CLONE_LOCK(ifc);
    -	IFC_IFLIST_REMOVE(ifc, ifp);
    +	LIST_FOREACH(ifcifp, &ifc->ifc_iflist, if_clones) {
    +		if (ifcifp == ifp) {
    +			IFC_IFLIST_REMOVE(ifc, ifp);
    +			break;
    +		}
    +	}
     	IF_CLONE_UNLOCK(ifc);
    +	if (ifcifp == NULL) {
    +		CURVNET_RESTORE();
    +		return (ENXIO);		/* ifp is not on the list. */
    +	}
     
     	if_delgroup(ifp, ifc->ifc_name);
     
    
    From b6a02e249ff9d5b8cb78f0e389baccfaa8779c9d Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Wed, 21 Apr 2010 20:00:13 +0000
    Subject: [PATCH 2086/2592] MFC r206488:
    
      Take a reference to make sure that the interface cannot go away during
      if_clone_destroy() in case parallel threads try to.
    
    PR:		kern/116837
    Submitted by:	Mikolaj Golub (to.my.trociny gmail.com)
    ---
     sys/net/if_clone.c | 11 ++++++++---
     1 file changed, 8 insertions(+), 3 deletions(-)
    
    diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c
    index 81ac7ffbdba..c02737bd463 100644
    --- a/sys/net/if_clone.c
    +++ b/sys/net/if_clone.c
    @@ -196,10 +196,11 @@ if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params)
     int
     if_clone_destroy(const char *name)
     {
    +	int err;
     	struct if_clone *ifc;
     	struct ifnet *ifp;
     
    -	ifp = ifunit(name);
    +	ifp = ifunit_ref(name);
     	if (ifp == NULL)
     		return (ENXIO);
     
    @@ -221,10 +222,14 @@ if_clone_destroy(const char *name)
     	}
     #endif
     	IF_CLONERS_UNLOCK();
    -	if (ifc == NULL)
    +	if (ifc == NULL) {
    +		if_rele(ifp);
     		return (EINVAL);
    +	}
     
    -	return (if_clone_destroyif(ifc, ifp));
    +	err = if_clone_destroyif(ifc, ifp);
    +	if_rele(ifp);
    +	return err;
     }
     
     /*
    
    From b36b15fd885ce3327dd9dd33e5c80ffc5e81b6aa Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Thu, 22 Apr 2010 00:28:49 +0000
    Subject: [PATCH 2087/2592] MFC: netcat 4.7.
    
    ---
     contrib/netcat/FREEBSD-upgrade | 19 ------------
     contrib/netcat/FREEBSD-vendor  |  5 ---
     contrib/netcat/nc.1            | 27 +++++++---------
     contrib/netcat/netcat.c        | 56 +++++++++++++++-------------------
     4 files changed, 36 insertions(+), 71 deletions(-)
     delete mode 100644 contrib/netcat/FREEBSD-upgrade
     delete mode 100644 contrib/netcat/FREEBSD-vendor
    
    diff --git a/contrib/netcat/FREEBSD-upgrade b/contrib/netcat/FREEBSD-upgrade
    deleted file mode 100644
    index 5a52ebc6481..00000000000
    --- a/contrib/netcat/FREEBSD-upgrade
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -$FreeBSD$
    -
    -1. Export from OpenBSD's nc(1) into an empty directory (say "v-nc").
    -2. while read pattern; do rm ${pattern} ; done < FREEBSD-Xlist
    -3. Checkout our contrib/netcat to another directory (say "f-nc"),
    -   with -rOPENBSD, and usr.bin/nc to its ../../
    -4. copy the files from v-nc to f-nc
    -5. do cvs up -A in f-nc
    -6. If there is conflicits, try to resolve them.
    -7. do build in f-nc/../../usr.bin/nc
    -8. If everything seems ok, do the actual import in v-nc:
    -	cvs -n import src/contrib/netcat OPENBSD OPENBSD_
    -   Everything appears be Ok? Do:
    -	cvs import src/contrib/netcat OPENBSD OPENBSD_
    -   (note: recently we import from OpenBSD's release branches
    -    rather than importing -HEAD snapshots)
    -9. Resolve the conflicits with the patchset obtained in step 6.
    -
    -delphij@FreeBSD.org - 21 Apr 2008
    diff --git a/contrib/netcat/FREEBSD-vendor b/contrib/netcat/FREEBSD-vendor
    deleted file mode 100644
    index c808f5bbc5a..00000000000
    --- a/contrib/netcat/FREEBSD-vendor
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -# $FreeBSD$
    -Project:	netcat (aka src/usr.bin/nc in OpenBSD)
    -ProjectURL:	http://www.openbsd.org/
    -Version:	4.6
    -License:	BSD
    diff --git a/contrib/netcat/nc.1 b/contrib/netcat/nc.1
    index 4375ae84cea..ac6aa475fbd 100644
    --- a/contrib/netcat/nc.1
    +++ b/contrib/netcat/nc.1
    @@ -1,4 +1,4 @@
    -.\"     $OpenBSD: nc.1,v 1.50 2009/06/05 06:47:12 jmc Exp $
    +.\"     $OpenBSD: nc.1,v 1.53 2010/02/23 23:00:52 schwarze Exp $
     .\"
     .\" Copyright (c) 1996 David Sacerdote
     .\" All rights reserved.
    @@ -27,7 +27,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd June 5 2009
    +.Dd April 15, 2010
     .Dt NC 1
     .Os
     .Sh NAME
    @@ -36,7 +36,7 @@
     .Sh SYNOPSIS
     .Nm nc
     .Bk -words
    -.Op Fl 46DdEhklnorStUuvz
    +.Op Fl 46DdEhklnrStUuvz
     .Op Fl e Ar IPsec_policy
     .Op Fl I Ar length
     .Op Fl i Ar interval
    @@ -51,8 +51,8 @@
     .Op Fl X Ar proxy_protocol
     .Oo Xo
     .Fl x Ar proxy_address Ns Oo : Ns
    -.Ar port Oc Oc
    -.Xc
    +.Ar port Oc
    +.Xc Oc
     .Op Ar hostname
     .Op Ar port
     .Ek
    @@ -159,15 +159,6 @@ socket option.
     .It Fl O Ar length
     Specifies the size of the TCP send buffer.
     When
    -.It Fl o
    -.Dq Once-only mode .
    -By default,
    -.Nm
    -does not terminate on EOF condition on input,
    -but continues until the network side has been closed down.
    -Specifying
    -.Fl o
    -will make it terminate on EOF as well.
     .It Fl P Ar proxy_username
     Specifies a username to present to a proxy server that requires authentication.
     If no username is specified then authentication will not be attempted.
    @@ -206,7 +197,9 @@ This makes it possible to use
     .Nm
     to script telnet sessions.
     .It Fl U
    -Specifies to use Unix Domain Sockets.
    +Specifies to use
    +.Ux Ns -domain
    +sockets.
     .It Fl u
     Use UDP instead of the default option of TCP.
     .It Fl V Ar fib
    @@ -428,7 +421,9 @@ outgoing traffic only.
     .Pp
     .Dl $ nc -e 'out ipsec esp/transport//require' host.example.com 42
     .Pp
    -Create and listen on a Unix Domain Socket:
    +Create and listen on a
    +.Ux Ns -domain
    +socket:
     .Pp
     .Dl $ nc -lU /var/tmp/dsocket
     .Pp
    diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c
    index a9ce18bb9b5..28a98238676 100644
    --- a/contrib/netcat/netcat.c
    +++ b/contrib/netcat/netcat.c
    @@ -1,4 +1,4 @@
    -/* $OpenBSD: netcat.c,v 1.93 2009/06/05 00:18:10 claudio Exp $ */
    +/* $OpenBSD: netcat.c,v 1.95 2010/02/27 00:58:56 nicm Exp $ */
     /*
      * Copyright (c) 2001 Eric Jackson 
      *
    @@ -72,14 +72,12 @@
     #define PORT_MAX_LEN	6
     
     /* Command Line Options */
    -int	Eflag;					/* Use IPsec ESP */
     int	dflag;					/* detached, no stdin */
     unsigned int iflag;				/* Interval Flag */
     int	jflag;					/* use jumbo frames if we can */
     int	kflag;					/* More than one connect */
     int	lflag;					/* Bind to local port */
     int	nflag;					/* Don't do name look up */
    -int	oflag;					/* Once only: stop on EOF */
     int	FreeBSD_Oflag;				/* Do not use TCP options */
     char   *Pflag;					/* Proxy username */
     char   *pflag;					/* Localport flag */
    @@ -151,7 +149,7 @@ main(int argc, char *argv[])
     	sv = NULL;
     
     	while ((ch = getopt_long(argc, argv,
    -	    "46DdEe:hI:i:jklnO:oP:p:rSs:tT:UuV:vw:X:x:z",
    +	    "46DdEe:hI:i:jklnoO:P:p:rSs:tT:UuV:vw:X:x:z",
     	    longopts, NULL)) != -1) {
     		switch (ch) {
     		case '4':
    @@ -214,7 +212,7 @@ main(int argc, char *argv[])
     			nflag = 1;
     			break;
     		case 'o':
    -			oflag = 1;
    +			fprintf(stderr, "option -o is deprecated.\n");
     			break;
     		case 'P':
     			Pflag = optarg;
    @@ -282,8 +280,6 @@ main(int argc, char *argv[])
     		case 'T':
     			Tflag = parse_iptos(optarg);
     			break;
    -		case 0:
    -			break;
     		default:
     			usage(1);
     		}
    @@ -455,8 +451,10 @@ main(int argc, char *argv[])
     					    uflag ? "udp" : "tcp");
     				}
     
    -				printf("Connection to %s %s port [%s/%s] succeeded!\n",
    -				    host, portlist[i], uflag ? "udp" : "tcp",
    +				fprintf(stderr,
    +				    "Connection to %s %s port [%s/%s] "
    +				    "succeeded!\n", host, portlist[i],
    +				    uflag ? "udp" : "tcp",
     				    sv ? sv->s_name : "*");
     			}
     			if (!zflag)
    @@ -572,10 +570,8 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
     		if (sflag || pflag) {
     			struct addrinfo ahints, *ares;
     
    -#ifdef SO_BINDANY
    -			/* try SO_BINDANY, but don't insist */
    -			setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on));
    -#endif
    +			/* try IP_BINDANY, but don't insist */
    +			setsockopt(s, IPPROTO_IP, IP_BINDANY, &on, sizeof(on));
     			memset(&ahints, 0, sizeof(struct addrinfo));
     			ahints.ai_family = res0->ai_family;
     			ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
    @@ -727,10 +723,9 @@ readwrite(int nfd)
     		}
     
     		if (!dflag && pfd[1].revents & POLLIN) {
    -			if ((n = read(wfd, buf, plen)) < 0 ||
    -			    (oflag && n == 0)) {
    +			if ((n = read(wfd, buf, plen)) < 0)
     				return;
    -			} else if (n == 0) {
    +			else if (n == 0) {
     				shutdown(nfd, SHUT_WR);
     				pfd[1].fd = -1;
     				pfd[1].events = 0;
    @@ -749,27 +744,27 @@ atelnet(int nfd, unsigned char *buf, unsigned int size)
     	unsigned char *p, *end;
     	unsigned char obuf[4];
     
    -	end = buf + size;
    -	obuf[0] = '\0';
    +	if (size < 3)
    +		return;
    +	end = buf + size - 2;
     
     	for (p = buf; p < end; p++) {
     		if (*p != IAC)
    -			break;
    +			continue;
     
     		obuf[0] = IAC;
     		p++;
     		if ((*p == WILL) || (*p == WONT))
     			obuf[1] = DONT;
    -		if ((*p == DO) || (*p == DONT))
    +		else if ((*p == DO) || (*p == DONT))
     			obuf[1] = WONT;
    -		if (obuf) {
    -			p++;
    -			obuf[2] = *p;
    -			obuf[3] = '\0';
    -			if (atomicio(vwrite, nfd, obuf, 3) != 3)
    -				warn("Write Error!");
    -			obuf[0] = '\0';
    -		}
    +		else
    +			continue;
    +
    +		p++;
    +		obuf[2] = *p;
    +		if (atomicio(vwrite, nfd, obuf, 3) != 3)
    +			warn("Write Error!");
     	}
     }
     
    @@ -943,7 +938,6 @@ help(void)
     	\t-n		Suppress name/port resolutions\n\
     	\t--no-tcpopt	Disable TCP options\n\
     	\t-O length	TCP send buffer length\n\
    -	\t-o		Terminate on EOF on input\n\
     	\t-P proxyuser\tUsername for proxy authentication\n\
     	\t-p port\t	Specify local port for remote connects\n\
     	\t-r		Randomize remote ports\n\
    @@ -993,9 +987,9 @@ usage(int ret)
     {
     	fprintf(stderr,
     #ifdef IPSEC
    -	    "usage: nc [-46DdEhklnorStUuvz] [-e policy] [-I length] [-i interval] [-O length]\n"
    +	    "usage: nc [-46DdEhklnrStUuvz] [-e policy] [-I length] [-i interval] [-O length]\n"
     #else
    -	    "usage: nc [-46DdhklnorStUuvz] [-I length] [-i interval] [-O length]\n"
    +	    "usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n"
     #endif
     	    "\t  [-P proxy_username] [-p source_port] [-s source_ip_address] [-T ToS]\n"
     	    "\t  [-V fib] [-w timeout] [-X proxy_protocol]\n"
    
    From 36f19e924780d18905da0c5bc5d41541eabeaae7 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Thu, 22 Apr 2010 00:29:36 +0000
    Subject: [PATCH 2088/2592] Remove a file that is not supposed to be part of
     -STABLE branch.
    
    ---
     contrib/netcat/FREEBSD-Xlist | 3 ---
     1 file changed, 3 deletions(-)
     delete mode 100644 contrib/netcat/FREEBSD-Xlist
    
    diff --git a/contrib/netcat/FREEBSD-Xlist b/contrib/netcat/FREEBSD-Xlist
    deleted file mode 100644
    index b69f5e4de37..00000000000
    --- a/contrib/netcat/FREEBSD-Xlist
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -$FreeBSD$
    -
    -Makefile
    
    From 93a395255310fa5ef339c06f7c8bfbac34d452f3 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Thu, 22 Apr 2010 01:39:45 +0000
    Subject: [PATCH 2089/2592] MFC r206563:   Add Agere ET1011 PHY which is found
     on Belkin F5D5055 USB   controller. Unlike Agere ET1011C, Agere ET1011 does
     not seem to   need special DSP programming to workaround silicon bug.
    
    ---
     sys/dev/mii/miidevs   | 1 +
     sys/dev/mii/truephy.c | 6 +++++-
     2 files changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
    index f3ef20dae35..85eac6878f2 100644
    --- a/sys/dev/mii/miidevs
    +++ b/sys/dev/mii/miidevs
    @@ -109,6 +109,7 @@ oui xxREALTEK			0x000732
      */
     
     /* Agere Systems PHYs */
    +model AGERE ET1011		0x0001 ET1011 10/100/1000baseT PHY
     model AGERE ET1011C		0x0004 ET1011C 10/100/1000baseT PHY
     
     /* Altima Communications PHYs */
    diff --git a/sys/dev/mii/truephy.c b/sys/dev/mii/truephy.c
    index 4eba9d98aae..069b2a0638b 100644
    --- a/sys/dev/mii/truephy.c
    +++ b/sys/dev/mii/truephy.c
    @@ -76,6 +76,7 @@ static device_method_t truephy_methods[] = {
     };
     
     static const struct mii_phydesc truephys[] = {
    +	MII_PHY_DESC(AGERE,	ET1011),
     	MII_PHY_DESC(AGERE,	ET1011C),
     	MII_PHY_END
     };
    @@ -161,7 +162,10 @@ truephy_attach(device_t dev)
     
     	mii->mii_instance++;
     
    -	truephy_reset(sc);
    +	if (MII_MODEL(ma->mii_id2) == MII_MODEL_AGERE_ET1011)
    +		mii_phy_reset(sc);
    +	else
    +		truephy_reset(sc);
     
     	sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
     	if (sc->mii_capabilities & BMSR_EXTSTAT) {
    
    From e5465d9c0cdd44d23efe2edf97380504a0fd1244 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Thu, 22 Apr 2010 11:46:42 +0000
    Subject: [PATCH 2090/2592] MFC r206648,206651: scsi_cd: CD_FLAG_VALID_MEDIA is
     sufficient to set d_sectorsize and d_mediasize
    
    PR:		kern/138789
    ---
     sys/cam/scsi/scsi_cd.c | 9 +++++----
     1 file changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
    index db916fd70f5..5430d2c00ee 100644
    --- a/sys/cam/scsi/scsi_cd.c
    +++ b/sys/cam/scsi/scsi_cd.c
    @@ -2777,8 +2777,12 @@ cdcheckmedia(struct cam_periph *periph)
     		softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC);
     		cdprevent(periph, PR_ALLOW);
     		return (error);
    -	} else
    +	} else {
     		softc->flags |= CD_FLAG_VALID_MEDIA;
    +		softc->disk->d_sectorsize = softc->params.blksize;
    +		softc->disk->d_mediasize =
    +		    (off_t)softc->params.blksize * softc->params.disksize;
    +	}
     
     	/*
     	 * Now we check the table of contents.  This (currently) is only
    @@ -2867,9 +2871,6 @@ cdcheckmedia(struct cam_periph *periph)
     	}
     
     	softc->flags |= CD_FLAG_VALID_TOC;
    -	softc->disk->d_sectorsize = softc->params.blksize;
    -	softc->disk->d_mediasize =
    -	    (off_t)softc->params.blksize * softc->params.disksize;
     
     bailout:
     
    
    From a53cbf9286bd1d3b571314fde20d2eeb54fdd24b Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Thu, 22 Apr 2010 12:24:59 +0000
    Subject: [PATCH 2091/2592] MFC r206650: g_io_check: respond to zero
     pp->mediasize with ENXIO
    
    ---
     sys/geom/geom_io.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c
    index 0b6525e79e8..321e10eded5 100644
    --- a/sys/geom/geom_io.c
    +++ b/sys/geom/geom_io.c
    @@ -309,8 +309,8 @@ g_io_check(struct bio *bp)
     	case BIO_READ:
     	case BIO_WRITE:
     	case BIO_DELETE:
    -		/* Zero sectorsize is a probably lack of media */
    -		if (pp->sectorsize == 0)
    +		/* Zero sectorsize or mediasize is probably a lack of media. */
    +		if (pp->sectorsize == 0 || pp->mediasize == 0)
     			return (ENXIO);
     		/* Reject I/O not on sector boundary */
     		if (bp->bio_offset % pp->sectorsize)
    
    From 45ebe396a89c4fd4259786ba4af7702067f21209 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Thu, 22 Apr 2010 13:16:18 +0000
    Subject: [PATCH 2092/2592] MFC r206687: indent(1): don't treat bare '_t' as a
     type name with -ta
    
    ---
     usr.bin/indent/lexi.c | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/usr.bin/indent/lexi.c b/usr.bin/indent/lexi.c
    index 3d415d074dc..b3604c64205 100644
    --- a/usr.bin/indent/lexi.c
    +++ b/usr.bin/indent/lexi.c
    @@ -251,9 +251,10 @@ lexi(void)
     
     	if (auto_typedefs) {
     	    const char *q = s_token;
    +	    size_t q_len = strlen(q);
     	    /* Check if we have an "_t" in the end */
    -	    if (q[0] && q[1] &&
    -	        (strcmp(q + strlen(q) - 2, "_t") == 0)) {
    +	    if (q_len > 2 &&
    +	        (strcmp(q + q_len - 2, "_t") == 0)) {
     	        ps.its_a_keyword = true;
     		ps.last_u_d = true;
     	        goto found_auto_typedef;
    
    From 12545f55c356805b252fdf7e1aa1967cad06c8e9 Mon Sep 17 00:00:00 2001
    From: Nathan Whitehorn 
    Date: Thu, 22 Apr 2010 14:11:59 +0000
    Subject: [PATCH 2093/2592] MFC r206842:
    
    Fix brokenness in top on big-endian 32-bit systems introduced when
    changing format_k2 to take a long long. Because itoa is defined as a K&R
    C function, without prototyping its arguments, format_k2 passed a 64-bit
    value, but itoa() received only the first word, showing '0' in all memory
    fields.
    ---
     contrib/top/utils.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/contrib/top/utils.c b/contrib/top/utils.c
    index a38b2178fcc..43072b1eccb 100644
    --- a/contrib/top/utils.c
    +++ b/contrib/top/utils.c
    @@ -499,7 +499,7 @@ unsigned long long amt;
     	}
         }
     
    -    p = strecpy(p, itoa(amt));
    +    p = strecpy(p, itoa((int)amt));
         *p++ = tag;
         *p = '\0';
     
    
    From 4a9c979c0f41d9e7e8cd7b33a3c706a672b5a8f7 Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Fri, 23 Apr 2010 00:12:23 +0000
    Subject: [PATCH 2094/2592] MFC: r206688 The experimental NFS client was not
     filling in recovery credentials for opens done locally in the client when a
     delegation for the file was held. This could cause the client to crash in
     crsetgroups() when recovering from a server crash/reboot. This patch fills in
     the recovery credentials for this case, in order to avoid the client crash.
     Also, add KASSERT()s to the credential copy functions, to catch any other
     cases where the credentials aren't filled in correctly.
    
    ---
     sys/fs/nfs/nfs_commonport.c     | 2 ++
     sys/fs/nfs/nfsclstate.h         | 1 +
     sys/fs/nfsclient/nfs_clport.c   | 2 ++
     sys/fs/nfsclient/nfs_clrpcops.c | 8 +++++++-
     sys/fs/nfsclient/nfs_clstate.c  | 9 +++++++--
     5 files changed, 19 insertions(+), 3 deletions(-)
    
    diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
    index 56ccf1b85ee..7bc204e080c 100644
    --- a/sys/fs/nfs/nfs_commonport.c
    +++ b/sys/fs/nfs/nfs_commonport.c
    @@ -225,6 +225,8 @@ void
     newnfs_copycred(struct nfscred *nfscr, struct ucred *cr)
     {
     
    +	KASSERT(nfscr->nfsc_ngroups >= 0,
    +	    ("newnfs_copycred: negative nfsc_ngroups"));
     	cr->cr_uid = nfscr->nfsc_uid;
     	crsetgroups(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups);
     }
    diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h
    index 10747af5a64..edd479cf2ce 100644
    --- a/sys/fs/nfs/nfsclstate.h
    +++ b/sys/fs/nfs/nfsclstate.h
    @@ -140,6 +140,7 @@ struct nfsclopen {
     #define	NFSCLOPEN_OK		0
     #define	NFSCLOPEN_DOOPEN	1
     #define	NFSCLOPEN_DOOPENDOWNGRADE 2
    +#define	NFSCLOPEN_SETCRED	3
     
     struct nfscllockowner {
     	LIST_ENTRY(nfscllockowner) nfsl_list;
    diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
    index e81c3bf805b..f39666db68e 100644
    --- a/sys/fs/nfsclient/nfs_clport.c
    +++ b/sys/fs/nfsclient/nfs_clport.c
    @@ -978,6 +978,8 @@ newnfs_copyincred(struct ucred *cr, struct nfscred *nfscr)
     {
     	int i;
     
    +	KASSERT(cr->cr_ngroups >= 0,
    +	    ("newnfs_copyincred: negative cr_ngroups"));
     	nfscr->nfsc_uid = cr->cr_uid;
     	nfscr->nfsc_ngroups = MIN(cr->cr_ngroups, NFS_MAXGRPS + 1);
     	for (i = 0; i < nfscr->nfsc_ngroups; i++)
    diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
    index 88e17791284..9b7b8dfa67e 100644
    --- a/sys/fs/nfsclient/nfs_clrpcops.c
    +++ b/sys/fs/nfsclient/nfs_clrpcops.c
    @@ -280,7 +280,13 @@ else printf(" fhl=0\n");
     			error = EIO;
     		}
     		newnfs_copyincred(cred, &op->nfso_cred);
    -	    }
    +	    } else if (ret == NFSCLOPEN_SETCRED)
    +		/*
    +		 * This is a new local open on a delegation. It needs
    +		 * to have credentials so that an open can be done
    +		 * against the server during recovery.
    +		 */
    +		newnfs_copyincred(cred, &op->nfso_cred);
     
     	    /*
     	     * nfso_opencnt is the count of how many VOP_OPEN()s have
    diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
    index 568c5de640a..08150a7228e 100644
    --- a/sys/fs/nfsclient/nfs_clstate.c
    +++ b/sys/fs/nfsclient/nfs_clstate.c
    @@ -274,8 +274,13 @@ nfscl_open(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t amode, int usedeleg,
     		*owpp = owp;
     	if (opp != NULL)
     		*opp = op;
    -	if (retp != NULL)
    -		*retp = NFSCLOPEN_OK;
    +	if (retp != NULL) {
    +		if (nfhp != NULL && dp != NULL && nop == NULL)
    +			/* new local open on delegation */
    +			*retp = NFSCLOPEN_SETCRED;
    +		else
    +			*retp = NFSCLOPEN_OK;
    +	}
     
     	/*
     	 * Now, check the mode on the open and return the appropriate
    
    From bf129106d7a94f187c5128321d319e8ec7757011 Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Fri, 23 Apr 2010 00:34:59 +0000
    Subject: [PATCH 2095/2592] MFC: r206690 Add mutex lock calls to 2 cases in the
     experimental NFS client's renew thread where they were missing.
    
    ---
     sys/fs/nfsclient/nfs_clstate.c | 8 ++++++--
     1 file changed, 6 insertions(+), 2 deletions(-)
    
    diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
    index 08150a7228e..7bccbfcc5d7 100644
    --- a/sys/fs/nfsclient/nfs_clstate.c
    +++ b/sys/fs/nfsclient/nfs_clstate.c
    @@ -2318,7 +2318,9 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p)
     	int error, cbpathdown, islept, igotlock, ret, clearok;
     
     	cred = newnfs_getcred();
    +	NFSLOCKCLSTATE();
     	clp->nfsc_flags |= NFSCLFLAGS_HASTHREAD;
    +	NFSUNLOCKCLSTATE();
     	for(;;) {
     		newnfs_setroot(cred);
     		cbpathdown = 0;
    @@ -2331,9 +2333,11 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p)
     			error = nfsrpc_renew(clp, cred, p);
     			if (error == NFSERR_CBPATHDOWN)
     			    cbpathdown = 1;
    -			else if (error == NFSERR_STALECLIENTID)
    +			else if (error == NFSERR_STALECLIENTID) {
    +			    NFSLOCKCLSTATE();
     			    clp->nfsc_flags |= NFSCLFLAGS_RECOVER;
    -			else if (error == NFSERR_EXPIRED)
    +			    NFSUNLOCKCLSTATE();
    +			} else if (error == NFSERR_EXPIRED)
     			    (void) nfscl_hasexpired(clp, clidrev, p);
     		}
     
    
    From dec20309828da6cba74e291be1ae2bd085452502 Mon Sep 17 00:00:00 2001
    From: Andriy Gapon 
    Date: Fri, 23 Apr 2010 15:24:56 +0000
    Subject: [PATCH 2096/2592] MFC r206996: indent.pro example: actually install
     the sample file
    
    ---
     etc/mtree/BSD.usr.dist  | 2 ++
     share/examples/Makefile | 2 ++
     2 files changed, 4 insertions(+)
    
    diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist
    index bc440c8b2ca..008ffb03930 100644
    --- a/etc/mtree/BSD.usr.dist
    +++ b/etc/mtree/BSD.usr.dist
    @@ -217,6 +217,8 @@
                 ..
                 ibcs2
                 ..
    +            indent
    +            ..
                 ipfilter
                 ..
                 ipfw
    diff --git a/share/examples/Makefile b/share/examples/Makefile
    index 99d92c0d99a..7d011e3a9cd 100644
    --- a/share/examples/Makefile
    +++ b/share/examples/Makefile
    @@ -15,6 +15,7 @@ LDIRS=	BSD_daemon \
     	find_interface \
     	hast \
     	ibcs2 \
    +	indent \
     	ipfw \
     	kld \
     	libvgl \
    @@ -77,6 +78,7 @@ XFILES=	BSD_daemon/FreeBSD.pfa \
     	hast/vip-up.sh \
     	ibcs2/README \
     	ibcs2/hello.uu \
    +	indent/indent.pro \
     	ipfw/change_rules.sh \
     	kld/Makefile \
     	kld/cdev/Makefile \
    
    From c18d4b44cc476419bc97be0685064ec53f1b426b Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Fri, 23 Apr 2010 16:20:45 +0000
    Subject: [PATCH 2097/2592] This is an MFS of 205412.
    
    Add 'rotate' and 'getactive' verbs to provide some control and information
    about what the currently active path is.
    ---
     sbin/geom/class/multipath/geom_multipath.c | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/sbin/geom/class/multipath/geom_multipath.c b/sbin/geom/class/multipath/geom_multipath.c
    index 4319d0421c2..ab91e2d884c 100644
    --- a/sbin/geom/class/multipath/geom_multipath.c
    +++ b/sbin/geom/class/multipath/geom_multipath.c
    @@ -62,6 +62,14 @@ struct g_command class_commands[] = {
     		"clear", G_FLAG_VERBOSE, mp_main, G_NULL_OPTS,
     		NULL, "[-v] prov ..."
     	},
    +	{
    +		"rotate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
    +		NULL, "[-v] prov ..."
    +	},
    +	{
    +		"getactive", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
    +		NULL, "[-v] prov ..."
    +	},
     	G_CMD_SENTINEL
     };
     
    
    From 2ef84ecad4526d337001be287dd8546fb844ae92 Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Fri, 23 Apr 2010 16:26:10 +0000
    Subject: [PATCH 2098/2592] This is an MFC of 205412.
    
    Add 'rotate' and 'getactive' verbs to provide some control and information
    about what the currently active path is.
    ---
     sys/geom/multipath/g_multipath.c | 87 ++++++++++++++++++++++++++++++++
     1 file changed, 87 insertions(+)
    
    diff --git a/sys/geom/multipath/g_multipath.c b/sys/geom/multipath/g_multipath.c
    index ed7e71e09a2..f3ed83ff566 100644
    --- a/sys/geom/multipath/g_multipath.c
    +++ b/sys/geom/multipath/g_multipath.c
    @@ -70,6 +70,8 @@ static int g_multipath_destroy(struct g_geom *);
     static int
     g_multipath_destroy_geom(struct gctl_req *, struct g_class *, struct g_geom *);
     
    +static int g_multipath_rotate(struct g_geom *);
    +
     static g_taste_t g_multipath_taste;
     static g_ctl_req_t g_multipath_config;
     static g_init_t g_multipath_init;
    @@ -417,6 +419,30 @@ g_multipath_destroy_geom(struct gctl_req *req, struct g_class *mp,
     	return (g_multipath_destroy(gp));
     }
     
    +static int
    +g_multipath_rotate(struct g_geom *gp)
    +{
    +	struct g_consumer *lcp;
    +	struct g_multipath_softc *sc = gp->softc;
    +
    +	g_topology_assert();
    +	if (sc == NULL)
    +		return (ENXIO);
    +	LIST_FOREACH(lcp, &gp->consumer, consumer) {
    +		if ((lcp->index & MP_BAD) == 0) {
    +			if (sc->cp_active != lcp) {
    +				break;
    +			}
    +		}
    +	}
    +	if (lcp) {
    +		sc->cp_active = lcp;
    +		printf("GEOM_MULTIPATH: %s now active path in %s\n",
    +		    lcp->provider->name, sc->sc_name);
    +	}
    +	return (0);
    +}
    +
     static void
     g_multipath_init(struct g_class *mp)
     {
    @@ -748,6 +774,63 @@ g_multipath_ctl_destroy(struct gctl_req *req, struct g_class *mp)
     	}
     }
     
    +static void
    +g_multipath_ctl_rotate(struct gctl_req *req, struct g_class *mp)
    +{
    +	struct g_geom *gp;
    +	const char *name;
    +	int error;
    +
    +	g_topology_assert();
    +
    +	name = gctl_get_asciiparam(req, "arg0");
    +        if (name == NULL) {
    +                gctl_error(req, "No 'arg0' argument");
    +                return;
    +        }
    +	gp = g_multipath_find_geom(mp, name);
    +	if (gp == NULL) {
    +		gctl_error(req, "Device %s is invalid", name);
    +		return;
    +	}
    +	error = g_multipath_rotate(gp);
    +	if (error != 0) {
    +		gctl_error(req, "failed to rotate %s (err=%d)", name, error);
    +	}
    +}
    +
    +static void
    +g_multipath_ctl_getactive(struct gctl_req *req, struct g_class *mp)
    +{
    +	struct sbuf *sb;
    +	struct g_geom *gp;
    +	struct g_multipath_softc *sc;
    +	const char *name;
    +
    +	sb = sbuf_new_auto();
    +
    +	g_topology_assert();
    +	name = gctl_get_asciiparam(req, "arg0");
    +        if (name == NULL) {
    +                gctl_error(req, "No 'arg0' argument");
    +                return;
    +        }
    +	gp = g_multipath_find_geom(mp, name);
    +	if (gp == NULL) {
    +		gctl_error(req, "Device %s is invalid", name);
    +		return;
    +	}
    +	sc = gp->softc;
    +	if (sc->cp_active) {
    +		sbuf_printf(sb, "%s\n", sc->cp_active->provider->name);
    +	} else {
    +		sbuf_printf(sb, "none\n");
    +	}
    +	sbuf_finish(sb);
    +	gctl_set_param_err(req, "output", sbuf_data(sb), sbuf_len(sb) + 1);
    +	sbuf_delete(sb);
    +}
    +
     static void
     g_multipath_config(struct gctl_req *req, struct g_class *mp, const char *verb)
     {
    @@ -762,6 +845,10 @@ g_multipath_config(struct gctl_req *req, struct g_class *mp, const char *verb)
     		g_multipath_ctl_create(req, mp);
     	} else if (strcmp(verb, "destroy") == 0) {
     		g_multipath_ctl_destroy(req, mp);
    +	} else if (strcmp(verb, "rotate") == 0) {
    +		g_multipath_ctl_rotate(req, mp);
    +	} else if (strcmp(verb, "getactive") == 0) {
    +		g_multipath_ctl_getactive(req, mp);
     	} else {
     		gctl_error(req, "Unknown verb %s", verb);
     	}
    
    From a956023126e6eef7e1e50abe8e04e83624ff6064 Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Fri, 23 Apr 2010 16:49:18 +0000
    Subject: [PATCH 2099/2592] This is an MFC of 205847, 204071 and 196580
    
    ------
    Change how multipath labels are created and managed. This makes it easier
    to support various storage boxes which really aren't active-active.
    
    We only write the label on the *first* provider. For all other providers
    we just "add" the disk. This also allows for an "add" verb.
    
    A usage implication is that you should specificy the currently active
    storage path as the first provider.
    
    Note that this does not add RDAC-like functionality, but better allows for
    autovolumefailover configurations (additional checkins elsewhere will support
    this).
    
    ------------------------------------------------------------------------
    
    - Style fixes.
    - Prefer strlcpy() over strncpy().
    
    ------------------------------------------------------------------------
    
    There's no need for checking result of M_WAITOK allocation.
    ---
     sys/geom/multipath/g_multipath.c | 90 ++++++++++++--------------------
     1 file changed, 32 insertions(+), 58 deletions(-)
    
    diff --git a/sys/geom/multipath/g_multipath.c b/sys/geom/multipath/g_multipath.c
    index f3ed83ff566..1888d7069c9 100644
    --- a/sys/geom/multipath/g_multipath.c
    +++ b/sys/geom/multipath/g_multipath.c
    @@ -97,9 +97,8 @@ g_mpd(void *arg, int flags __unused)
     
     	g_topology_assert();
     	cp = arg;
    -	if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) {
    +	if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0)
     		g_access(cp, -cp->acr, -cp->acw, -cp->ace);
    -	}
     	if (cp->provider) {
     		printf("GEOM_MULTIPATH: %s removed from %s\n",
     		    cp->provider->name, cp->geom->name);
    @@ -224,15 +223,16 @@ g_multipath_done_error(struct bio *bp)
     static void
     g_multipath_kt(void *arg)
     {
    +
     	g_multipath_kt_state = GKT_RUN;
     	mtx_lock(&gmtbq_mtx);
     	while (g_multipath_kt_state == GKT_RUN) {
     		for (;;) {
     			struct bio *bp;
    +
     			bp = bioq_takefirst(&gmtbq);
    -			if (bp == NULL) {
    +			if (bp == NULL)
     				break;
    -			}
     			mtx_unlock(&gmtbq_mtx);
     			g_multipath_done_error(bp);
     			mtx_lock(&gmtbq_mtx);
    @@ -266,9 +266,8 @@ g_multipath_access(struct g_provider *pp, int dr, int dw, int de)
     
     fail:
     	LIST_FOREACH(cp, &gp->consumer, consumer) {
    -		if (cp == badcp) {
    +		if (cp == badcp)
     			break;
    -		}
     		(void) g_access(cp, -dr, -dw, -de);
     	}
     	return (error);
    @@ -292,15 +291,10 @@ g_multipath_create(struct g_class *mp, struct g_multipath_metadata *md)
     	}
     
     	gp = g_new_geomf(mp, md->md_name);
    -	if (gp == NULL) {
    +	if (gp == NULL)
     		goto fail;
    -	}
     
     	sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO);
    -	if (sc == NULL) {
    -		goto fail;
    -	}
    -
     	gp->softc = sc;
     	gp->start = g_multipath_start;
     	gp->orphan = g_multipath_orphan;
    @@ -309,9 +303,8 @@ g_multipath_create(struct g_class *mp, struct g_multipath_metadata *md)
     	memcpy(sc->sc_name, md->md_name, sizeof (sc->sc_name));
     
     	pp = g_new_providerf(gp, "multipath/%s", md->md_name);
    -	if (pp == NULL) {
    +	if (pp == NULL)
     		goto fail;
    -	}
     	/* limit the provider to not have it stomp on metadata */
     	pp->mediasize = md->md_size - md->md_sectorsize;
     	pp->sectorsize = md->md_sectorsize;
    @@ -320,9 +313,8 @@ g_multipath_create(struct g_class *mp, struct g_multipath_metadata *md)
     	return (gp);
     fail:
     	if (gp != NULL) {
    -		if (gp->softc != NULL) {
    +		if (gp->softc != NULL)
     			g_free(gp->softc);
    -		}
     		g_destroy_geom(gp);
     	}
     	return (NULL);
    @@ -344,9 +336,8 @@ g_multipath_add_disk(struct g_geom *gp, struct g_provider *pp)
     	 * Make sure that the passed provider isn't already attached
     	 */
     	LIST_FOREACH(cp, &gp->consumer, consumer) {
    -		if (cp->provider == pp) {
    +		if (cp->provider == pp)
     			break;
    -		}
     	}
     	if (cp) {
     		printf("GEOM_MULTIPATH: provider %s already attached to %s\n",
    @@ -355,9 +346,8 @@ g_multipath_add_disk(struct g_geom *gp, struct g_provider *pp)
     	}
     	nxtcp = LIST_FIRST(&gp->consumer);
     	cp = g_new_consumer(gp);
    -	if (cp == NULL) {
    +	if (cp == NULL)
     		return (ENOMEM);
    -	}
     	error = g_attach(cp, pp);
     	if (error != 0) {
     		printf("GEOM_MULTIPATH: cannot attach %s to %s",
    @@ -398,13 +388,11 @@ g_multipath_destroy(struct g_geom *gp)
     	struct g_provider *pp;
     
     	g_topology_assert();
    -	if (gp->softc == NULL) {
    +	if (gp->softc == NULL)
     		return (ENXIO);
    -	}
     	pp = LIST_FIRST(&gp->provider);
    -	if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
    +	if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0))
     		return (EBUSY);
    -	}
     	printf("GEOM_MULTIPATH: destroying %s\n", gp->name);
     	g_free(gp->softc);
     	gp->softc = NULL;
    @@ -416,6 +404,7 @@ static int
     g_multipath_destroy_geom(struct gctl_req *req, struct g_class *mp,
         struct g_geom *gp)
     {
    +
     	return (g_multipath_destroy(gp));
     }
     
    @@ -448,9 +437,8 @@ g_multipath_init(struct g_class *mp)
     {
     	bioq_init(&gmtbq);
     	mtx_init(&gmtbq_mtx, "gmtbq", NULL, MTX_DEF);
    -	if (kproc_create(g_multipath_kt, mp, NULL, 0, 0, "g_mp_kt") == 0) {
    +	if (kproc_create(g_multipath_kt, mp, NULL, 0, 0, "g_mp_kt") == 0)
     		g_multipath_kt_state = GKT_RUN;
    -	}
     }
     
     static void
    @@ -476,18 +464,16 @@ g_multipath_read_metadata(struct g_consumer *cp,
     
     	g_topology_assert();
     	error = g_access(cp, 1, 0, 0);
    -	if (error != 0) {
    +	if (error != 0)
     		return (error);
    -	}
     	pp = cp->provider;
     	g_topology_unlock();
     	buf = g_read_data(cp, pp->mediasize - pp->sectorsize,
     	    pp->sectorsize, &error);
     	g_topology_lock();
     	g_access(cp, -1, 0, 0);
    -	if (buf == NULL) {
    +	if (buf == NULL)
     		return (error);
    -	}
     	multipath_metadata_decode(buf, md);
     	g_free(buf);
     	return (0);
    @@ -514,15 +500,13 @@ g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
     	g_detach(cp);
     	g_destroy_consumer(cp);
     	g_destroy_geom(gp);
    -	if (error != 0) {
    +	if (error != 0)
     		return (NULL);
    -	}
     	gp = NULL;
     
     	if (strcmp(md.md_magic, G_MULTIPATH_MAGIC) != 0) {
    -		if (g_multipath_debug) {
    +		if (g_multipath_debug)
     			printf("%s is not MULTIPATH\n", pp->name);
    -		}
     		return (NULL);
     	}
     	if (md.md_version != G_MULTIPATH_VERSION) {
    @@ -531,9 +515,8 @@ g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
     		    G_MULTIPATH_VERSION);
     		return (NULL);
     	}
    -	if (g_multipath_debug) {
    +	if (g_multipath_debug)
     		printf("MULTIPATH: %s/%s\n", md.md_name, md.md_uuid);
    -	}
     
     	/*
     	 * Let's check if such a device already is present. We check against
    @@ -549,25 +532,20 @@ g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
     	sc = NULL;
     	LIST_FOREACH(gp, &mp->geom, geom) {
     		sc = gp->softc;
    -		if (sc == NULL) {
    +		if (sc == NULL)
     			continue;
    -		}
    -		if (strncmp(md.md_uuid, sc->sc_uuid, sizeof(md.md_uuid)) == 0) {
    +		if (strncmp(md.md_uuid, sc->sc_uuid, sizeof(md.md_uuid)) == 0)
     			break;
    -		}
     	}
     
     	LIST_FOREACH(gp1, &mp->geom, geom) {
    -		if (gp1 == gp) {
    +		if (gp1 == gp)
     			continue;
    -		}
     		sc = gp1->softc;
    -		if (sc == NULL) {
    +		if (sc == NULL)
     			continue;
    -		}
    -		if (strncmp(md.md_name, sc->sc_name, sizeof(md.md_name)) == 0) {
    +		if (strncmp(md.md_name, sc->sc_name, sizeof(md.md_name)) == 0)
     			break;
    -		}
     	}
     
     	/*
    @@ -594,9 +572,9 @@ g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
     			    sc->sc_name, sc->sc_uuid);
     			printf("GEOM_MULTIPATH: %s will be (temporarily) %s\n",
     			    md.md_uuid, buf);
    -			strlcpy(md.md_name, buf, sizeof (md.md_name));
    +			strlcpy(md.md_name, buf, sizeof(md.md_name));
     		} else {
    -			strlcpy(md.md_name, sc->sc_name, sizeof (md.md_name));
    +			strlcpy(md.md_name, sc->sc_name, sizeof(md.md_name));
     		}
     	}
     
    @@ -616,9 +594,8 @@ g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
     	KASSERT(sc != NULL, ("sc is NULL"));
     	error = g_multipath_add_disk(gp, pp);
     	if (error != 0) {
    -		if (isnew) {
    +		if (isnew)
     			g_multipath_destroy(gp);
    -		}
     		return (NULL);
     	}
     	return (gp);
    @@ -657,9 +634,8 @@ g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp)
     		gctl_error(req, "No 'arg1' argument");
     		return;
     	}
    -	if (strncmp(name, devpf, 5) == 0) {
    +	if (strncmp(name, devpf, 5) == 0)
     		name += 5;
    -	}
     	pp0 = g_provider_by_name(name);
     	if (pp0 == NULL) {
     		gctl_error(req, "Provider %s is invalid", name);
    @@ -671,9 +647,8 @@ g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp)
     		gctl_error(req, "No 'arg2' argument");
     		return;
     	}
    -	if (strncmp(name, devpf, 5) == 0) {
    +	if (strncmp(name, devpf, 5) == 0)
     		name += 5;
    -	}
     	pp1 = g_provider_by_name(name);
     	if (pp1 == NULL) {
     		gctl_error(req, "Provider %s is invalid", name);
    @@ -717,13 +692,12 @@ g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp)
     	memset(&md, 0, sizeof(md));
     	md.md_size = pp0->mediasize;
     	md.md_sectorsize = pp0->sectorsize;
    -	strncpy(md.md_name, mpname, sizeof (md.md_name));
    -	strncpy(md.md_uuid, uuid, sizeof (md.md_uuid));
    +	strlcpy(md.md_name, mpname, sizeof(md.md_name));
    +	strlcpy(md.md_uuid, uuid, sizeof(md.md_uuid));
     
     	gp = g_multipath_create(mp, &md);
    -	if (gp == NULL) {
    +	if (gp == NULL)
     		return;
    -	}
     	error = g_multipath_add_disk(gp, pp0);
     	if (error) {
     		g_multipath_destroy(gp);
    
    From 0dcf6cffeb44f29a2f938240794da889bfefdb36 Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Fri, 23 Apr 2010 17:52:36 +0000
    Subject: [PATCH 2100/2592] MFC r206710: Add some tests for fnmatch(3).
    
    ---
     tools/regression/lib/libc/gen/Makefile       |   2 +-
     tools/regression/lib/libc/gen/test-fnmatch.c | 335 +++++++++++++++++++
     2 files changed, 336 insertions(+), 1 deletion(-)
     create mode 100644 tools/regression/lib/libc/gen/test-fnmatch.c
    
    diff --git a/tools/regression/lib/libc/gen/Makefile b/tools/regression/lib/libc/gen/Makefile
    index 3dbe803a7be..3e911e4fc42 100644
    --- a/tools/regression/lib/libc/gen/Makefile
    +++ b/tools/regression/lib/libc/gen/Makefile
    @@ -1,6 +1,6 @@
     # $FreeBSD$
     
    -TESTS=	test-fmtcheck test-fpclassify test-wordexp
    +TESTS=	test-fmtcheck test-fnmatch test-fpclassify test-wordexp
     
     .PHONY: tests
     tests: ${TESTS}
    diff --git a/tools/regression/lib/libc/gen/test-fnmatch.c b/tools/regression/lib/libc/gen/test-fnmatch.c
    new file mode 100644
    index 00000000000..ffb8c6c7800
    --- /dev/null
    +++ b/tools/regression/lib/libc/gen/test-fnmatch.c
    @@ -0,0 +1,335 @@
    +/*-
    + * Copyright (c) 2010 Jilles Tjoelker
    + * 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 
    +
    +struct testcase {
    +	const char *pattern;
    +	const char *string;
    +	int flags;
    +	int result;
    +} testcases[] = {
    +	"", "", 0, 0,
    +	"a", "a", 0, 0,
    +	"a", "b", 0, FNM_NOMATCH,
    +	"a", "A", 0, FNM_NOMATCH,
    +	"*", "a", 0, 0,
    +	"*", "aa", 0, 0,
    +	"*a", "a", 0, 0,
    +	"*a", "b", 0, FNM_NOMATCH,
    +	"*a*", "b", 0, FNM_NOMATCH,
    +	"*a*b*", "ab", 0, 0,
    +	"*a*b*", "qaqbq", 0, 0,
    +	"*a*bb*", "qaqbqbbq", 0, 0,
    +	"*a*bc*", "qaqbqbcq", 0, 0,
    +	"*a*bb*", "qaqbqbb", 0, 0,
    +	"*a*bc*", "qaqbqbc", 0, 0,
    +	"*a*bb", "qaqbqbb", 0, 0,
    +	"*a*bc", "qaqbqbc", 0, 0,
    +	"*a*bb", "qaqbqbbq", 0, FNM_NOMATCH,
    +	"*a*bc", "qaqbqbcq", 0, FNM_NOMATCH,
    +	"*a*a*a*a*a*a*a*a*a*a*", "aaaaaaaaa", 0, FNM_NOMATCH,
    +	"*a*a*a*a*a*a*a*a*a*a*", "aaaaaaaaaa", 0, 0,
    +	"*a*a*a*a*a*a*a*a*a*a*", "aaaaaaaaaaa", 0, 0,
    +	".*.*.*.*.*.*.*.*.*.*", ".........", 0, FNM_NOMATCH,
    +	".*.*.*.*.*.*.*.*.*.*", "..........", 0, 0,
    +	".*.*.*.*.*.*.*.*.*.*", "...........", 0, 0,
    +	"*?*?*?*?*?*?*?*?*?*?*", "123456789", 0, FNM_NOMATCH,
    +	"??????????*", "123456789", 0, FNM_NOMATCH,
    +	"*??????????", "123456789", 0, FNM_NOMATCH,
    +	"*?*?*?*?*?*?*?*?*?*?*", "1234567890", 0, 0,
    +	"??????????*", "1234567890", 0, 0,
    +	"*??????????", "1234567890", 0, 0,
    +	"*?*?*?*?*?*?*?*?*?*?*", "12345678901", 0, 0,
    +	"??????????*", "12345678901", 0, 0,
    +	"*??????????", "12345678901", 0, 0,
    +	"[x]", "x", 0, 0,
    +	"[*]", "*", 0, 0,
    +	"[?]", "?", 0, 0,
    +	"[", "[", 0, 0,
    +	"[[]", "[", 0, 0,
    +	"[[]", "x", 0, FNM_NOMATCH,
    +	"[*]", "", 0, FNM_NOMATCH,
    +	"[*]", "x", 0, FNM_NOMATCH,
    +	"[?]", "x", 0, FNM_NOMATCH,
    +	"*[*]*", "foo*foo", 0, 0,
    +	"*[*]*", "foo", 0, FNM_NOMATCH,
    +	"[0-9]", "0", 0, 0,
    +	"[0-9]", "5", 0, 0,
    +	"[0-9]", "9", 0, 0,
    +	"[0-9]", "/", 0, FNM_NOMATCH,
    +	"[0-9]", ":", 0, FNM_NOMATCH,
    +	"[0-9]", "*", 0, FNM_NOMATCH,
    +	"[!0-9]", "0", 0, FNM_NOMATCH,
    +	"[!0-9]", "5", 0, FNM_NOMATCH,
    +	"[!0-9]", "9", 0, FNM_NOMATCH,
    +	"[!0-9]", "/", 0, 0,
    +	"[!0-9]", ":", 0, 0,
    +	"[!0-9]", "*", 0, 0,
    +	"*[0-9]", "a0", 0, 0,
    +	"*[0-9]", "a5", 0, 0,
    +	"*[0-9]", "a9", 0, 0,
    +	"*[0-9]", "a/", 0, FNM_NOMATCH,
    +	"*[0-9]", "a:", 0, FNM_NOMATCH,
    +	"*[0-9]", "a*", 0, FNM_NOMATCH,
    +	"*[!0-9]", "a0", 0, FNM_NOMATCH,
    +	"*[!0-9]", "a5", 0, FNM_NOMATCH,
    +	"*[!0-9]", "a9", 0, FNM_NOMATCH,
    +	"*[!0-9]", "a/", 0, 0,
    +	"*[!0-9]", "a:", 0, 0,
    +	"*[!0-9]", "a*", 0, 0,
    +	"*[0-9]", "a00", 0, 0,
    +	"*[0-9]", "a55", 0, 0,
    +	"*[0-9]", "a99", 0, 0,
    +	"*[0-9]", "a0a0", 0, 0,
    +	"*[0-9]", "a5a5", 0, 0,
    +	"*[0-9]", "a9a9", 0, 0,
    +	"\\*", "*", 0, 0,
    +	"\\?", "?", 0, 0,
    +	"\\[x]", "[x]", 0, 0,
    +	"\\[", "[", 0, 0,
    +	"\\\\", "\\", 0, 0,
    +	"*\\**", "foo*foo", 0, 0,
    +	"*\\**", "foo", 0, FNM_NOMATCH,
    +	"*\\\\*", "foo\\foo", 0, 0,
    +	"*\\\\*", "foo", 0, FNM_NOMATCH,
    +	"\\(", "(", 0, 0,
    +	"\\a", "a", 0, 0,
    +	"\\*", "a", 0, FNM_NOMATCH,
    +	"\\?", "a", 0, FNM_NOMATCH,
    +	"\\*", "\\*", 0, FNM_NOMATCH,
    +	"\\?", "\\?", 0, FNM_NOMATCH,
    +	"\\[x]", "\\[x]", 0, FNM_NOMATCH,
    +	"\\[x]", "\\x", 0, FNM_NOMATCH,
    +	"\\[", "\\[", 0, FNM_NOMATCH,
    +	"\\(", "\\(", 0, FNM_NOMATCH,
    +	"\\a", "\\a", 0, FNM_NOMATCH,
    +	"\\*", "\\*", FNM_NOESCAPE, 0,
    +	"\\?", "\\?", FNM_NOESCAPE, 0,
    +	"\\", "\\", FNM_NOESCAPE, 0,
    +	"\\\\", "\\", FNM_NOESCAPE, FNM_NOMATCH,
    +	"\\\\", "\\\\", FNM_NOESCAPE, 0,
    +	"*\\*", "foo\\foo", FNM_NOESCAPE, 0,
    +	"*\\*", "foo", FNM_NOESCAPE, FNM_NOMATCH,
    +	"*", ".", FNM_PERIOD, FNM_NOMATCH,
    +	"?", ".", FNM_PERIOD, FNM_NOMATCH,
    +	".*", ".", 0, 0,
    +	".*", "..", 0, 0,
    +	".*", ".a", 0, 0,
    +	"[0-9]", ".", FNM_PERIOD, FNM_NOMATCH,
    +	"a*", "a.", 0, 0,
    +	"a/a", "a/a", FNM_PATHNAME, 0,
    +	"a/*", "a/a", FNM_PATHNAME, 0,
    +	"*/a", "a/a", FNM_PATHNAME, 0,
    +	"*/*", "a/a", FNM_PATHNAME, 0,
    +	"a*b/*", "abbb/x", FNM_PATHNAME, 0,
    +	"a*b/*", "abbb/.x", FNM_PATHNAME, 0,
    +	"*", "a/a", FNM_PATHNAME, FNM_NOMATCH,
    +	"*/*", "a/a/a", FNM_PATHNAME, FNM_NOMATCH,
    +	"b/*", "b/.x", FNM_PATHNAME | FNM_PERIOD, FNM_NOMATCH,
    +	"b*/*", "a/.x", FNM_PATHNAME | FNM_PERIOD, FNM_NOMATCH,
    +	"b/.*", "b/.x", FNM_PATHNAME | FNM_PERIOD, 0,
    +	"b*/.*", "b/.x", FNM_PATHNAME | FNM_PERIOD, 0,
    +	"a", "A", FNM_CASEFOLD, 0,
    +	"A", "a", FNM_CASEFOLD, 0,
    +	"[a]", "A", FNM_CASEFOLD, 0,
    +	"[A]", "a", FNM_CASEFOLD, 0,
    +	"a", "b", FNM_CASEFOLD, FNM_NOMATCH,
    +	"a", "a/b", FNM_PATHNAME, FNM_NOMATCH,
    +	"*", "a/b", FNM_PATHNAME, FNM_NOMATCH,
    +	"*b", "a/b", FNM_PATHNAME, FNM_NOMATCH,
    +	"a", "a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0,
    +	"*", "a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0,
    +	"*", ".a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0,
    +	"*a", ".a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0,
    +	"*", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH,
    +	"*a", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH,
    +};
    +
    +static const char *
    +flags_to_string(int flags)
    +{
    +	static const int flagvalues[] = { FNM_NOESCAPE, FNM_PATHNAME,
    +		FNM_PERIOD, FNM_LEADING_DIR, FNM_CASEFOLD, 0 };
    +	static const char flagnames[] = "FNM_NOESCAPE\0FNM_PATHNAME\0FNM_PERIOD\0FNM_LEADING_DIR\0FNM_CASEFOLD\0";
    +	static char result[sizeof(flagnames) + 3 * sizeof(int) + 2];
    +	char *p;
    +	size_t i, len;
    +	const char *fp;
    +
    +	p = result;
    +	fp = flagnames;
    +	for (i = 0; flagvalues[i] != 0; i++) {
    +		len = strlen(fp);
    +		if (flags & flagvalues[i]) {
    +			if (p != result)
    +				*p++ = '|';
    +			memcpy(p, fp, len);
    +			p += len;
    +			flags &= ~flagvalues[i];
    +		}
    +		fp += len + 1;
    +	}
    +	if (p == result)
    +		memcpy(p, "0", 2);
    +	else if (flags != 0)
    +		sprintf(p, "%d", flags);
    +	else
    +		*p = '\0';
    +	return result;
    +}
    +
    +int
    +main(int argc, char *argv[])
    +{
    +	size_t i, n;
    +	int flags, result, extra, errors;
    +	struct testcase *t;
    +
    +	n = sizeof(testcases) / sizeof(testcases[0]);
    +	errors = 0;
    +	printf("1..%zu\n", n);
    +	for (i = 0; i < n; i++) {
    +		t = &testcases[i];
    +		flags = t->flags;
    +		extra = 0;
    +		do {
    +			result = fnmatch(t->pattern, t->string, flags);
    +			if (result != t->result)
    +				break;
    +			if (strchr(t->pattern, '\\') == NULL &&
    +			    !(flags & FNM_NOESCAPE)) {
    +				flags |= FNM_NOESCAPE;
    +				result = fnmatch(t->pattern, t->string, flags);
    +				if (result != t->result)
    +					break;
    +				flags = t->flags;
    +				extra++;
    +			}
    +			if (strchr(t->pattern, '\\') != NULL &&
    +			    strchr(t->string, '\\') == NULL &&
    +			    t->result == FNM_NOMATCH &&
    +			    !(flags & (FNM_NOESCAPE | FNM_LEADING_DIR))) {
    +				flags |= FNM_NOESCAPE;
    +				result = fnmatch(t->pattern, t->string, flags);
    +				if (result != t->result)
    +					break;
    +				flags = t->flags;
    +				extra++;
    +			}
    +			if ((t->string[0] != '.' || t->pattern[0] == '.' ||
    +			    t->result == FNM_NOMATCH) &&
    +			    !(flags & (FNM_PATHNAME | FNM_PERIOD))) {
    +				flags |= FNM_PERIOD;
    +				result = fnmatch(t->pattern, t->string, flags);
    +				if (result != t->result)
    +					break;
    +				flags = t->flags;
    +				extra++;
    +			}
    +			if ((strchr(t->string, '/') == NULL ||
    +			    t->result == FNM_NOMATCH) &&
    +			    !(flags & FNM_PATHNAME)) {
    +				flags |= FNM_PATHNAME;
    +				result = fnmatch(t->pattern, t->string, flags);
    +				if (result != t->result)
    +					break;
    +				flags = t->flags;
    +				extra++;
    +			}
    +			if ((((t->string[0] != '.' || t->pattern[0] == '.') &&
    +			    strstr(t->string, "/.") == NULL) ||
    +			    t->result == FNM_NOMATCH) &&
    +			    flags & FNM_PATHNAME && !(flags & FNM_PERIOD)) {
    +				flags |= FNM_PERIOD;
    +				result = fnmatch(t->pattern, t->string, flags);
    +				if (result != t->result)
    +					break;
    +				flags = t->flags;
    +				extra++;
    +			}
    +			if ((((t->string[0] != '.' || t->pattern[0] == '.') &&
    +			    strchr(t->string, '/') == NULL) ||
    +			    t->result == FNM_NOMATCH) &&
    +			    !(flags & (FNM_PATHNAME | FNM_PERIOD))) {
    +				flags |= FNM_PATHNAME | FNM_PERIOD;
    +				result = fnmatch(t->pattern, t->string, flags);
    +				if (result != t->result)
    +					break;
    +				flags = t->flags;
    +				extra++;
    +			}
    +			if ((strchr(t->string, '/') == NULL || t->result == 0)
    +			    && !(flags & FNM_LEADING_DIR)) {
    +				flags |= FNM_LEADING_DIR;
    +				result = fnmatch(t->pattern, t->string, flags);
    +				if (result != t->result)
    +					break;
    +				flags = t->flags;
    +				extra++;
    +			}
    +			if (t->result == 0 && !(flags & FNM_CASEFOLD)) {
    +				flags |= FNM_CASEFOLD;
    +				result = fnmatch(t->pattern, t->string, flags);
    +				if (result != t->result)
    +					break;
    +				flags = t->flags;
    +				extra++;
    +			}
    +			if (strchr(t->pattern, '\\') == NULL &&
    +			    t->result == 0 &&
    +			    !(flags & (FNM_NOESCAPE | FNM_CASEFOLD))) {
    +				flags |= FNM_NOESCAPE | FNM_CASEFOLD;
    +				result = fnmatch(t->pattern, t->string, flags);
    +				if (result != t->result)
    +					break;
    +				flags = t->flags;
    +				extra++;
    +			}
    +		} while (0);
    +		if (result == t->result)
    +			printf("ok %zu - fnmatch(\"%s\", \"%s\", %s) = %d (+%d)\n",
    +			    i + 1, t->pattern, t->string,
    +			    flags_to_string(flags),
    +			    result, extra);
    +		else {
    +			printf("not ok %zu - fnmatch(\"%s\", \"%s\", %s) = %d != %d\n",
    +			    i + 1, t->pattern, t->string,
    +			    flags_to_string(flags),
    +			    result, t->result);
    +			errors = 1;
    +		}
    +	}
    +
    +	return (errors);
    +}
    
    From 8b0241c2d43698aa3a24f09b465b9010f1c88f69 Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Fri, 23 Apr 2010 18:01:19 +0000
    Subject: [PATCH 2101/2592] MFC r206711: fnmatch: Fix bad FNM_PERIOD disabling
     if an asterisk has been seen.
    
    Example: fnmatch("a*b/*", "abbb/.x", FNM_PATHNAME | FNM_PERIOD)
    
    PR:		116074
    ---
     lib/libc/gen/fnmatch.c                       | 16 ++++++++--------
     tools/regression/lib/libc/gen/test-fnmatch.c |  1 +
     2 files changed, 9 insertions(+), 8 deletions(-)
    
    diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c
    index e697bdcedf2..3acbc3b1647 100644
    --- a/lib/libc/gen/fnmatch.c
    +++ b/lib/libc/gen/fnmatch.c
    @@ -67,7 +67,8 @@ __FBSDID("$FreeBSD$");
     #define RANGE_ERROR     (-1)
     
     static int rangematch(const char *, wchar_t, int, char **, mbstate_t *);
    -static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t);
    +static int fnmatch1(const char *, const char *, const char *, int, mbstate_t,
    +		mbstate_t);
     
     int
     fnmatch(pattern, string, flags)
    @@ -76,22 +77,21 @@ fnmatch(pattern, string, flags)
     {
     	static const mbstate_t initial;
     
    -	return (fnmatch1(pattern, string, flags, initial, initial));
    +	return (fnmatch1(pattern, string, string, flags, initial, initial));
     }
     
     static int
    -fnmatch1(pattern, string, flags, patmbs, strmbs)
    -	const char *pattern, *string;
    +fnmatch1(pattern, string, stringstart, flags, patmbs, strmbs)
    +	const char *pattern, *string, *stringstart;
     	int flags;
     	mbstate_t patmbs, strmbs;
     {
    -	const char *stringstart;
     	char *newp;
     	char c;
     	wchar_t pc, sc;
     	size_t pclen, sclen;
     
    -	for (stringstart = string;;) {
    +	for (;;) {
     		pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs);
     		if (pclen == (size_t)-1 || pclen == (size_t)-2)
     			return (FNM_NOMATCH);
    @@ -145,8 +145,8 @@ fnmatch1(pattern, string, flags, patmbs, strmbs)
     
     			/* General case, use recursion. */
     			while (sc != EOS) {
    -				if (!fnmatch1(pattern, string,
    -				    flags & ~FNM_PERIOD, patmbs, strmbs))
    +				if (!fnmatch1(pattern, string, stringstart,
    +				    flags, patmbs, strmbs))
     					return (0);
     				sclen = mbrtowc(&sc, string, MB_LEN_MAX,
     				    &strmbs);
    diff --git a/tools/regression/lib/libc/gen/test-fnmatch.c b/tools/regression/lib/libc/gen/test-fnmatch.c
    index ffb8c6c7800..6cbf8eeef70 100644
    --- a/tools/regression/lib/libc/gen/test-fnmatch.c
    +++ b/tools/regression/lib/libc/gen/test-fnmatch.c
    @@ -174,6 +174,7 @@ struct testcase {
     	"*a", ".a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0,
     	"*", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH,
     	"*a", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH,
    +	"a*b/*", "abbb/.x", FNM_PATHNAME | FNM_PERIOD, FNM_NOMATCH,
     };
     
     static const char *
    
    From 1f7026c7633825ead1919822526044139bf88732 Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Fri, 23 Apr 2010 19:26:03 +0000
    Subject: [PATCH 2102/2592] MFC r197848: 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 e2da58f8958..4f89d2f6a72 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 a2bef3670a7800e141ad996f2db46a273d453dc7 Mon Sep 17 00:00:00 2001
    From: Attilio Rao 
    Date: Sat, 24 Apr 2010 00:49:19 +0000
    Subject: [PATCH 2103/2592] MFC r206421: Default the machdep.lapic_allclocks to
     be enabled in order to cope with broken atrtc. Now if you want more correct
     stats on profhz and stathz it may be disabled by setting to 0.
    
    Sponsored by:	Sandvine Incorporated
    ---
     sys/amd64/isa/clock.c | 2 +-
     sys/i386/isa/clock.c  | 2 +-
     sys/pc98/cbus/clock.c | 2 +-
     3 files changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c
    index e5c27d1bbaf..6e5da8ffaa6 100644
    --- a/sys/amd64/isa/clock.c
    +++ b/sys/amd64/isa/clock.c
    @@ -84,7 +84,7 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq);
     int	i8254_max_count;
     static int i8254_real_max_count;
     
    -static int lapic_allclocks;
    +static int lapic_allclocks = 1;
     TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
     
     struct mtx clock_lock;
    diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
    index 04f74418504..5b0bf05e482 100644
    --- a/sys/i386/isa/clock.c
    +++ b/sys/i386/isa/clock.c
    @@ -97,7 +97,7 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq);
     int	i8254_max_count;
     static int i8254_real_max_count;
     
    -static int lapic_allclocks;
    +static int lapic_allclocks = 1;
     TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
     
     struct mtx clock_lock;
    diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c
    index 22ed8a5f5c9..3028c074d15 100644
    --- a/sys/pc98/cbus/clock.c
    +++ b/sys/pc98/cbus/clock.c
    @@ -93,7 +93,7 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq);
     int	i8254_max_count;
     static int i8254_real_max_count;
     
    -static int lapic_allclocks;
    +static int lapic_allclocks = 1;
     TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
     
     static	struct mtx clock_lock;
    
    From 47fd5bf73a0fd9cfb6db122e2e53e44e6397770c Mon Sep 17 00:00:00 2001
    From: Attilio Rao 
    Date: Sat, 24 Apr 2010 00:53:41 +0000
    Subject: [PATCH 2104/2592] MFC r206482, r206879: - Introduce a blessed list
     for sxlocks that prevents the deadlkres to   panic on those ones. Populate
     this list with getblk and so_snd_sx and   so_rcv_sx. - Fix ticks counter
     wrap-up
    
    Sponsored by:	Sandvine Incorporated
    ---
     sys/kern/kern_clock.c | 33 ++++++++++++++++++++++++++++++++-
     1 file changed, 32 insertions(+), 1 deletion(-)
    
    diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
    index 2844103fa40..da05cc16356 100644
    --- a/sys/kern/kern_clock.c
    +++ b/sys/kern/kern_clock.c
    @@ -162,6 +162,12 @@ SYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE,
         0,0, sysctl_kern_cp_times, "LU", "per-CPU time statistics");
     
     #ifdef DEADLKRES
    +static const char *blessed[] = {
    +	"getblk",
    +	"so_snd_sx",
    +	"so_rcv_sx",
    +	NULL
    +};
     static int slptime_threshold = 1800;
     static int blktime_threshold = 900;
     static int sleepfreq = 3;
    @@ -172,7 +178,7 @@ deadlkres(void)
     	struct proc *p;
     	struct thread *td;
     	void *wchan;
    -	int blkticks, slpticks, slptype, tryl, tticks;
    +	int blkticks, i, slpticks, slptype, tryl, tticks;
     
     	tryl = 0;
     	for (;;) {
    @@ -205,6 +211,10 @@ deadlkres(void)
     					 * turnstile channel is in good state.
     					 */
     					MPASS(td->td_blocked != NULL);
    +
    +					/* Handle ticks wrap-up. */
    +					if (ticks < td->td_blktick)
    +						continue;
     					tticks = ticks - td->td_blktick;
     					thread_unlock(td);
     					if (tticks > blkticks) {
    @@ -222,6 +232,10 @@ deadlkres(void)
     					}
     				} else if (TD_IS_SLEEPING(td)) {
     
    +					/* Handle ticks wrap-up. */
    +					if (ticks < td->td_blktick)
    +						continue;
    +
     					/*
     					 * Check if the thread is sleeping on a
     					 * lock, otherwise skip the check.
    @@ -242,7 +256,24 @@ deadlkres(void)
     						 * thresholds, this thread is
     						 * stuck for too long on a
     						 * sleepqueue.
    +						 * However, being on a
    +						 * sleepqueue, we might still
    +						 * check for the blessed
    +						 * list.
     						 */
    +						tryl = 0;
    +						for (i = 0; blessed[i] != NULL;
    +						    i++) {
    +							if (!strcmp(blessed[i],
    +							    td->td_wmesg)) {
    +								tryl = 1;
    +								break;
    +							}
    +						}
    +						if (tryl != 0) {
    +							tryl = 0;
    +							continue;
    +						}
     						PROC_UNLOCK(p);
     						sx_sunlock(&allproc_lock);
     	panic("%s: possible deadlock detected for %p, blocked for %d ticks\n",
    
    From fbcd5da22bdb2abac2fd2ef6b909de635ead9638 Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Sat, 24 Apr 2010 23:05:56 +0000
    Subject: [PATCH 2105/2592] This is an MFC of 205236
    
    Put gone device timer into a structure tag that can hold more than 32 seconds. Oops.
    
    Untangle some of the confusion about what role means when it's in the FCPARAM/SDPARAM
    or isp_fc/isp_spi structures. This fixed a problem about seeing targets appear if you've
    turned off autologin and find them, or rather don't, via camcontrol rescan.
    ---
     sys/dev/isp/isp_freebsd.c | 23 +++++++++++++++--------
     sys/dev/isp/isp_freebsd.h | 10 +++++-----
     sys/dev/isp/isp_pci.c     |  6 +++---
     sys/dev/isp/isp_sbus.c    |  2 +-
     4 files changed, 24 insertions(+), 17 deletions(-)
    
    diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
    index 8e1d07b6f38..0ceced2d045 100644
    --- a/sys/dev/isp/isp_freebsd.c
    +++ b/sys/dev/isp/isp_freebsd.c
    @@ -3945,11 +3945,15 @@ isp_gdt(void *arg)
     		if (lp->dev_map_idx == 0 || lp->target_mode) {
     			continue;
     		}
    -		if (lp->new_reserved == 0) {
    +		/*
    +		 * We can use new_portid here because it is untouched
    +		 * while the state is ZOMBIE
    +		 */
    +		if (lp->new_portid == 0) {
     			continue;
     		}
    -		lp->new_reserved -= 1;
    -		if (lp->new_reserved != 0) {
    +		lp->new_portid -= 1;
    +		if (lp->new_portid != 0) {
     			more_to_do++;
     			continue;
     		}
    @@ -4059,7 +4063,7 @@ isp_kthread(void *arg)
     		 *
     		 * If not, we simply just wait for loop to come up.
     		 */
    -		if (lb && (fc->role & ISP_ROLE_INITIATOR)) {
    +		if (lb && (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR)) {
     			/*
     			 * Increment loop down time by the last sleep interval
     			 */
    @@ -4927,7 +4931,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
     			/*
     			 * We don't do any simq freezing if we are only in target mode
     			 */
    -			if (fc->role & ISP_ROLE_INITIATOR) {
    +			if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
     				if (fc->path) {
     					isp_freeze_loopdown(isp, bus, msg);
     				}
    @@ -4963,7 +4967,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
     		va_end(ap);
     		fc = ISP_FC_PC(isp, bus);
     		lp->reserved = 0;
    -		if ((fc->role & ISP_ROLE_INITIATOR) && (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
    +		if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) && (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
     			int dbidx = lp - FCPARAM(isp, bus)->portdb;
     			int i;
     
    @@ -5051,10 +5055,13 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
     		 *
     		 * If it isn't marked that isp_gdt is going to get rid of it,
     		 * announce that it's gone.
    +		 *
    +		 * We can use new_portid for the gone timer because it's
    +		 * undefined while the state is ZOMBIE.
     		 */
     		if (lp->dev_map_idx && lp->reserved == 0) {
     			lp->reserved = 1;
    -			lp->new_reserved = ISP_FC_PC(isp, bus)->gone_device_time;
    +			lp->new_portid = ISP_FC_PC(isp, bus)->gone_device_time;
     			lp->state = FC_PORTDB_STATE_ZOMBIE;
     			if (fc->ready && !callout_active(&fc->gdt)) {
     				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d starting Gone Device Timer", bus);
    @@ -5101,7 +5108,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
     			callout_stop(&fc->ldt);
     		}
     		isp_prt(isp, ISP_LOGINFO, msg, bus);
    -		if (fc->role & ISP_ROLE_INITIATOR) {
    +		if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
     			isp_freeze_loopdown(isp, bus, msg);
     		}
     		wakeup(fc);
    diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
    index e1d7a87cadf..44c8bdf1ca5 100644
    --- a/sys/dev/isp/isp_freebsd.h
    +++ b/sys/dev/isp/isp_freebsd.h
    @@ -175,7 +175,7 @@ struct isp_fc {
     		simqfrozen	: 3,
     		default_id	: 8,
     		hysteresis	: 8,
    -		role		: 2,
    +		def_role	: 2,	/* default role */
     		gdt_running	: 1,
     		loop_dead	: 1,
     		fcbsy		: 1,
    @@ -203,7 +203,7 @@ struct isp_spi {
     		tm_enabled	: 1,
     #endif
     		simqfrozen	: 3,
    -		role		: 3,
    +		def_role	: 2,
     		iid		: 4;
     #ifdef	ISP_TARGET_MODE
     	struct tslist lun_hash[LUN_HASH_SIZE];
    @@ -469,12 +469,12 @@ default:							\
     #define	DEFAULT_EXEC_THROTTLE(isp)	isp->isp_osinfo.exec_throttle
     
     #define	GET_DEFAULT_ROLE(isp, chan)	\
    -	(IS_FC(isp)? ISP_FC_PC(isp, chan)->role : ISP_SPI_PC(isp, chan)->role)
    +	(IS_FC(isp)? ISP_FC_PC(isp, chan)->def_role : ISP_SPI_PC(isp, chan)->def_role)
     #define	SET_DEFAULT_ROLE(isp, chan, val)		\
     	if (IS_FC(isp)) { 				\
    -		ISP_FC_PC(isp, chan)->role = val;	\
    +		ISP_FC_PC(isp, chan)->def_role = val;	\
     	} else {					\
    -		ISP_SPI_PC(isp, chan)->role = val;	\
    +		ISP_SPI_PC(isp, chan)->def_role = val;	\
     	}
     
     #define	DEFAULT_IID(isp, chan)		isp->isp_osinfo.pc.spi[chan].iid
    diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
    index 547f48ef2ff..8410ea64d72 100644
    --- a/sys/dev/isp/isp_pci.c
    +++ b/sys/dev/isp/isp_pci.c
    @@ -547,10 +547,10 @@ isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp)
     	}
     
     	if (IS_SCSI(isp)) {
    -		ISP_SPI_PC(isp, chan)->role = tval;
    +		ISP_SPI_PC(isp, chan)->def_role = tval;
     		return;
     	}
    -	ISP_FC_PC(isp, chan)->role = tval;
    +	ISP_FC_PC(isp, chan)->def_role = tval;
     
     	tval = 0;
     	if (resource_int_value(device_get_name(dev), device_get_unit(dev), "fullduplex", &tval) == 0 && tval != 0) {
    @@ -833,7 +833,7 @@ isp_pci_attach(device_t dev)
     	 * The 'it' suffix really only matters for SCSI cards in target mode.
     	 */
     	isp->isp_osinfo.fw = NULL;
    -	if (IS_SCSI(isp) && (ISP_SPI_PC(isp, 0)->role & ISP_ROLE_TARGET)) {
    +	if (IS_SCSI(isp) && (ISP_SPI_PC(isp, 0)->def_role & ISP_ROLE_TARGET)) {
     		snprintf(fwname, sizeof (fwname), "isp_%04x_it", did);
     		isp->isp_osinfo.fw = firmware_get(fwname);
     	} else if (IS_24XX(isp) && (isp->isp_nchan > 1 || isp->isp_osinfo.forcemulti)) {
    diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
    index e2dd78fed96..895645a673a 100644
    --- a/sys/dev/isp/isp_sbus.c
    +++ b/sys/dev/isp/isp_sbus.c
    @@ -195,7 +195,7 @@ isp_sbus_attach(device_t dev)
     	isp->isp_revision = 0;	/* XXX */
     	isp->isp_dev = dev;
     	isp->isp_nchan = 1;
    -	ISP_SET_PC(isp, 0, role, role);
    +	ISP_SET_PC(isp, 0, def_role, role);
     
     	/*
     	 * Get the clock frequency and convert it from HZ to MHz,
    
    From 4c35d8e0923163fbc49e986dd0f924e446a506da Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Sat, 24 Apr 2010 23:10:13 +0000
    Subject: [PATCH 2106/2592] This is an MFC of 205252.
    
    We actually can generate a host number.
    ---
     sys/cam/scsi/scsi_sg.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/cam/scsi/scsi_sg.c b/sys/cam/scsi/scsi_sg.c
    index d47e6e9adb3..8ec01895dfa 100644
    --- a/sys/cam/scsi/scsi_sg.c
    +++ b/sys/cam/scsi/scsi_sg.c
    @@ -586,7 +586,7 @@ sgioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
     	{
     		struct sg_scsi_id id;
     
    -		id.host_no = 0; /* XXX */
    +		id.host_no = cam_sim_path(xpt_path_sim(periph->path));
     		id.channel = xpt_path_path_id(periph->path);
     		id.scsi_id = xpt_path_target_id(periph->path);
     		id.lun = xpt_path_lun_id(periph->path);
    
    From 417e0e58bf8dcc90147c975dd53ba6507eb81942 Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Sat, 24 Apr 2010 23:20:51 +0000
    Subject: [PATCH 2107/2592] This is an MFC of 204050.
    
    Don't try and re-use a handle, even if the firmware tells you that's what is logged in.
    
    PR:             kern/144026
    ---
     sys/dev/isp/isp.c | 63 +++++++++++++++++++++++++----------------------
     1 file changed, 33 insertions(+), 30 deletions(-)
    
    diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
    index 0d00bb4a31e..a03573a6587 100644
    --- a/sys/dev/isp/isp.c
    +++ b/sys/dev/isp/isp.c
    @@ -2167,9 +2167,7 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags
     		msg = "no Exchange Control Block";
     		break;
     	case PLOGX_IOCBERR_FAILED:
    -		ISP_SNPRINTF(buf, sizeof (buf),
    -		    "reason 0x%x (last LOGIN state 0x%x)",
    -		    parm1 & 0xff, (parm1 >> 8) & 0xff);
    +		ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
     		msg = buf;
     		break;
     	case PLOGX_IOCBERR_NOFABRIC:
    @@ -2179,8 +2177,7 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags
     		msg = "firmware not ready";
     		break;
     	case PLOGX_IOCBERR_NOLOGIN:
    -		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)",
    -		    parm1);
    +		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
     		msg = buf;
     		rval = MBOX_NOT_LOGGED_IN;
     		break;
    @@ -2192,21 +2189,18 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags
     		msg = "no PCB allocated";
     		break;
     	case PLOGX_IOCBERR_EINVAL:
    -		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x",
    -		    parm1);
    +		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
     		msg = buf;
     		break;
     	case PLOGX_IOCBERR_PORTUSED:
     		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
    -		ISP_SNPRINTF(buf, sizeof (buf),
    -		    "already logged in with N-Port handle 0x%x", parm1);
    +		ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
     		msg = buf;
     		rval = MBOX_PORT_ID_USED | (parm1 << 16);
     		break;
     	case PLOGX_IOCBERR_HNDLUSED:
     		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
    -		ISP_SNPRINTF(buf, sizeof (buf),
    -		    "handle already used for PortID 0x%06x", parm1);
    +		ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
     		msg = buf;
     		rval = MBOX_LOOP_ID_USED;
     		break;
    @@ -2217,15 +2211,12 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags
     		msg = "no FLOGI_ACC";
     		break;
     	default:
    -		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x",
    -		    plp->plogx_status, flags);
    +		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags);
     		msg = buf;
     		break;
     	}
     	if (msg) {
    -		isp_prt(isp, ISP_LOGERR,
    -		    "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
    -		    chan, portid, handle, msg);
    +		isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", chan, portid, handle, msg);
     	}
     out:
     	if (gs == 0) {
    @@ -3886,8 +3877,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
      * Find an unused handle and try and use to login to a port.
      */
     static int
    -isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
    -    uint16_t *ohp)
    +isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
     {
     	int lim, i, r;
     	uint16_t handle;
    @@ -3907,8 +3897,7 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
     		 */
     		r = isp_getpdb(isp, chan, handle, p, 0);
     		if (r == 0 && p->portid != portid) {
    -			(void) isp_plogx(isp, chan, handle, portid,
    -			    PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1);
    +			(void) isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1);
     		} else if (r == 0) {
     			break;
     		}
    @@ -3918,8 +3907,7 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
     		/*
     		 * Now try and log into the device
     		 */
    -		r = isp_plogx(isp, chan, handle, portid,
    -		    PLOGX_FLG_CMD_PLOGI, 1);
    +		r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
     		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
     			return (-1);
     		}
    @@ -3927,7 +3915,26 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
     			*ohp = handle;
     			break;
     		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
    -			handle = r >> 16;
    +			/*
    +			 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
    +			 * handle. We need to break that association. We used to try and just substitute the handle, but then
    +			 * failed to get any data via isp_getpdb (below).
    +			 */
    +			if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1)) {
    +				isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
    +			}
    +			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
    +				return (-1);
    +			}
    +			r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
    +			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
    +				return (-1);
    +			}
    +			if (r == 0) {
    +				*ohp = handle;
    +			} else {
    +				i = lim;
    +			}
     			break;
     		} else if (r != MBOX_LOOP_ID_USED) {
     			i = lim;
    @@ -3941,8 +3948,7 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
     	}
     
     	if (i == lim) {
    -		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed",
    -		    chan, portid);
    +		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
     		return (-1);
     	}
     
    @@ -3956,15 +3962,12 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
     		return (-1);
     	}
     	if (r != 0) {
    -		isp_prt(isp, ISP_LOGERR,
    -		    "Chan %d new device 0x%06x@0x%x disappeared",
    -		    chan, portid, handle);
    +		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
     		return (-1);
     	}
     
     	if (p->handle != handle || p->portid != portid) {
    -		isp_prt(isp, ISP_LOGERR,
    -		    "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
    +		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
     		    chan, portid, handle, p->portid, p->handle);
     		return (-1);
     	}
    
    From a862e504dab98450dd632d60f582fc357674210c Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Sun, 25 Apr 2010 01:56:31 +0000
    Subject: [PATCH 2108/2592] MFC: r206818 Avoid extraneous recovery cycles in
     the experimental NFS client when an NFSv4 server reboots, by doing two
     things. 1 - Make the function that acquires a stateid for I/O operations    
     block until recovery is complete, so that it doesn't acquire     out of date
     stateids. 2 - Only allow a recovery once every 1/2 of a lease duration, since
         the NFSv4 server must provide a recovery grace period of at     least a
     lease duration. This should avoid recoveries caused     by an out of date
     stateid that was acquired for an I/O op.     just before a recovery cycle
     started.
    
    ---
     sys/fs/nfs/nfsclstate.h        |  1 +
     sys/fs/nfsclient/nfs_clstate.c | 33 +++++++++++++++++++++++++++++----
     2 files changed, 30 insertions(+), 4 deletions(-)
    
    diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h
    index edd479cf2ce..72d8eebfc39 100644
    --- a/sys/fs/nfs/nfsclstate.h
    +++ b/sys/fs/nfs/nfsclstate.h
    @@ -74,6 +74,7 @@ struct nfsclclient {
     #define	NFSCLFLAGS_EXPIREIT	0x0040
     #define	NFSCLFLAGS_FIRSTDELEG	0x0080
     #define	NFSCLFLAGS_GOTDELEG	0x0100
    +#define	NFSCLFLAGS_RECVRINPROG	0x0200
     
     struct nfsclowner {
     	LIST_ENTRY(nfsclowner)	nfsow_list;
    diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
    index 7bccbfcc5d7..6a189635ff7 100644
    --- a/sys/fs/nfsclient/nfs_clstate.c
    +++ b/sys/fs/nfsclient/nfs_clstate.c
    @@ -480,6 +480,13 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode,
     		return (EACCES);
     	}
     
    +	/*
    +	 * Wait for recovery to complete.
    +	 */
    +	while ((clp->nfsc_flags & NFSCLFLAGS_RECVRINPROG))
    +		(void) nfsmsleep(&clp->nfsc_flags, NFSCLSTATEMUTEXPTR,
    +		    PZERO, "nfsrecvr", NULL);
    +
     	/*
     	 * First, look for a delegation.
     	 */
    @@ -1778,6 +1785,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
     	 * block when trying to use state.
     	 */
     	NFSLOCKCLSTATE();
    +	clp->nfsc_flags |= NFSCLFLAGS_RECVRINPROG;
     	do {
     		igotlock = nfsv4_lock(&clp->nfsc_lock, 1, NULL,
     		    NFSCLSTATEMUTEXPTR);
    @@ -1794,9 +1802,10 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
     	     error == NFSERR_STALEDONTRECOVER) && --trycnt > 0);
     	if (error) {
     		nfscl_cleanclient(clp);
    -		clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID |
    -		    NFSCLFLAGS_RECOVER);
     		NFSLOCKCLSTATE();
    +		clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID |
    +		    NFSCLFLAGS_RECOVER | NFSCLFLAGS_RECVRINPROG);
    +		wakeup(&clp->nfsc_flags);
     		nfsv4_unlock(&clp->nfsc_lock, 0);
     		NFSUNLOCKCLSTATE();
     		return;
    @@ -2057,6 +2066,8 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
     	}
     
     	NFSLOCKCLSTATE();
    +	clp->nfsc_flags &= ~NFSCLFLAGS_RECVRINPROG;
    +	wakeup(&clp->nfsc_flags);
     	nfsv4_unlock(&clp->nfsc_lock, 0);
     	NFSUNLOCKCLSTATE();
     	NFSFREECRED(tcred);
    @@ -2316,6 +2327,7 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p)
     	struct ucred *cred;
     	u_int32_t clidrev;
     	int error, cbpathdown, islept, igotlock, ret, clearok;
    +	uint32_t recover_done_time = 0;
     
     	cred = newnfs_getcred();
     	NFSLOCKCLSTATE();
    @@ -2324,8 +2336,21 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p)
     	for(;;) {
     		newnfs_setroot(cred);
     		cbpathdown = 0;
    -		if (clp->nfsc_flags & NFSCLFLAGS_RECOVER)
    -			nfscl_recover(clp, cred, p);
    +		if (clp->nfsc_flags & NFSCLFLAGS_RECOVER) {
    +			/*
    +			 * Only allow one recover within 1/2 of the lease
    +			 * duration (nfsc_renew).
    +			 */
    +			if (recover_done_time < NFSD_MONOSEC) {
    +				recover_done_time = NFSD_MONOSEC +
    +				    clp->nfsc_renew;
    +				nfscl_recover(clp, cred, p);
    +			} else {
    +				NFSLOCKCLSTATE();
    +				clp->nfsc_flags &= ~NFSCLFLAGS_RECOVER;
    +				NFSUNLOCKCLSTATE();
    +			}
    +		}
     		if (clp->nfsc_expire <= NFSD_MONOSEC &&
     		    (clp->nfsc_flags & NFSCLFLAGS_HASCLIENTID)) {
     			clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew;
    
    From 873ff8abccfd745514d8fc50ec5a85d3f6c9a81d Mon Sep 17 00:00:00 2001
    From: Fabien Thomas 
    Date: Sun, 25 Apr 2010 16:16:43 +0000
    Subject: [PATCH 2109/2592] MFC r206994: Apply threshold filter to root node in
     calltree view.
    
    ---
     usr.sbin/pmcstat/pmcpl_calltree.c | 15 ++++++++++-----
     1 file changed, 10 insertions(+), 5 deletions(-)
    
    diff --git a/usr.sbin/pmcstat/pmcpl_calltree.c b/usr.sbin/pmcstat/pmcpl_calltree.c
    index 4f62c62158b..f8ceece158b 100644
    --- a/usr.sbin/pmcstat/pmcpl_calltree.c
    +++ b/usr.sbin/pmcstat/pmcpl_calltree.c
    @@ -499,9 +499,10 @@ void
     pmcpl_ct_topdisplay(void)
     {
     	int i, x, y, pmcin;
    -	struct pmcpl_ct_sample rsamples;
    +	struct pmcpl_ct_sample r, *rsamples;
     
    -	pmcpl_ct_samples_root(&rsamples);
    +	rsamples = &r;
    +	pmcpl_ct_samples_root(rsamples);
     
     	PMCSTAT_PRINTW("%-10.10s %s\n", "IMAGE", "CALLTREE");
     
    @@ -524,16 +525,20 @@ pmcpl_ct_topdisplay(void)
     			if (PMCPL_CT_SAMPLE(pmcin,
     			    &pmcpl_ct_root->pct_arc[i].pcta_samples) == 0)
     				continue;
    +			if (PMCPL_CT_SAMPLEP(pmcin,
    +			    &pmcpl_ct_root->pct_arc[i].pcta_samples) <=
    +			    pmcstat_threshold)
    +				continue;
     			if (pmcpl_ct_node_dumptop(pmcin,
     			        pmcpl_ct_root->pct_arc[i].pcta_child,
    -			        &rsamples, x, &y, pmcstat_displayheight - 2)) {
    +			        rsamples, x, &y, pmcstat_displayheight - 2)) {
     				break;
     			}
     		}
     
    -		pmcpl_ct_node_printtop(&rsamples, pmcin, y);
    +		pmcpl_ct_node_printtop(rsamples, pmcin, y);
     	}
    -	pmcpl_ct_samples_free(&rsamples);
    +	pmcpl_ct_samples_free(rsamples);
     }
     
     /*
    
    From 39fc973d8958d3f35e2d15c206d941c141c9c41b Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Sun, 25 Apr 2010 19:13:08 +0000
    Subject: [PATCH 2110/2592] MFC r206916
    
      Make sure that we free the passed in data message if we don't actually
      insert it onto the queue.  Also, fix a mtx leak if someone turns off
      devctl while we're processing a messages.
    
      MFC after:	5 days
    ---
     sys/kern/subr_bus.c | 15 ++++++++++++---
     1 file changed, 12 insertions(+), 3 deletions(-)
    
    diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
    index eaec75b83de..cd170a94210 100644
    --- a/sys/kern/subr_bus.c
    +++ b/sys/kern/subr_bus.c
    @@ -545,15 +545,16 @@ devctl_queue_data(char *data)
     	struct proc *p;
     
     	if (strlen(data) == 0)
    -		return;
    +		goto out;
     	if (devctl_queue_length == 0)
    -		return;
    +		goto out;
     	n1 = malloc(sizeof(*n1), M_BUS, M_NOWAIT);
     	if (n1 == NULL)
    -		return;
    +		goto out;
     	n1->dei_data = data;
     	mtx_lock(&devsoftc.mtx);
     	if (devctl_queue_length == 0) {
    +		mtx_unlock(&devsoftc.mtx);
     		free(n1->dei_data, M_BUS);
     		free(n1, M_BUS);
     		return;
    @@ -577,6 +578,14 @@ devctl_queue_data(char *data)
     		psignal(p, SIGIO);
     		PROC_UNLOCK(p);
     	}
    +	return;
    +out:
    +	/*
    +	 * We have to free data on all error paths since the caller
    +	 * assumes it will be free'd when this item is dequeued.
    +	 */
    +	free(data, M_BUS);
    +	return;
     }
     
     /**
    
    From e5b0d015b5c11d60f0911cf72e591db7354d5e97 Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Sun, 25 Apr 2010 19:21:19 +0000
    Subject: [PATCH 2111/2592] MFC r206915
    
      Bump minor version of config to reflect the new option remapping
      feature.  The kernel makefiles have specifically not been bumped
      because nothing uses this new feature and doing so forces everybody to
      recompile for no good reason.  This chnage will be MFC'd where the
      kernel version numbers for amd64 and ia64 will be bumped, since those
      are the only two that have use the option remapping feature.  Once
      merged, this will give a better error message to folks that are using
      buildkernel without buildworld or kernel-toolchain to update their
      kernels.
    
      MFC after:	3 days
    ---
     usr.sbin/config/configvers.h | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/usr.sbin/config/configvers.h b/usr.sbin/config/configvers.h
    index 28451585ec2..73310bd6f41 100644
    --- a/usr.sbin/config/configvers.h
    +++ b/usr.sbin/config/configvers.h
    @@ -49,5 +49,5 @@
      *
      * $FreeBSD$
      */
    -#define	CONFIGVERS	600007
    +#define	CONFIGVERS	600008
     #define	MAJOR_VERS(x)	((x) / 100000)
    
    From a057a7f941f636292d28a6d3aeb89eaeb9906d17 Mon Sep 17 00:00:00 2001
    From: Hajimu UMEMOTO 
    Date: Mon, 26 Apr 2010 15:01:14 +0000
    Subject: [PATCH 2112/2592] MFC r200130 (partly):
     /usr/share/examples/etc/rc.firewall6 was also obsoleted.
    
    ---
     ObsoleteFiles.inc | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
    index 9edd071e9e3..6dd8e2e6803 100644
    --- a/ObsoleteFiles.inc
    +++ b/ObsoleteFiles.inc
    @@ -17,6 +17,7 @@
     # 20100408: unify rc.firewall and rc.firewall6.
     OLD_FILES+=etc/rc.d/ip6fw
     OLD_FILES+=etc/rc.firewall6
    +OLD_FILES+=usr/share/examples/etc/rc.firewall6
     # 20100330: [ia64] Sync with 9-current
     .if ${TARGET_ARCH} == "ia64"
     OLD_FILES+=usr/include/machine/nexusvar.h
    
    From ab28e40a317bdfe7ad8db45e1a1161e3eaf89e9a Mon Sep 17 00:00:00 2001
    From: Jaakko Heinonen 
    Date: Mon, 26 Apr 2010 16:20:18 +0000
    Subject: [PATCH 2113/2592] MFC r206859:
    
    Fix ddb(4) "show geom addr" command when INVARIANTS is enabled. Don't
    assert that the topology lock is held when g_valid_obj() is called from
    debugger.
    ---
     sys/geom/geom_subr.c | 20 +++++++++++++-------
     1 file changed, 13 insertions(+), 7 deletions(-)
    
    diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c
    index ae7ee30745a..34e81c4bcd6 100644
    --- a/sys/geom/geom_subr.c
    +++ b/sys/geom/geom_subr.c
    @@ -59,6 +59,10 @@ __FBSDID("$FreeBSD$");
     #include 
     #endif
     
    +#ifdef KDB
    +#include 
    +#endif
    +
     struct class_list_head g_classes = LIST_HEAD_INITIALIZER(g_classes);
     static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms);
     char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
    @@ -1010,12 +1014,11 @@ g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len)
     
     #if defined(DIAGNOSTIC) || defined(DDB)
     /*
    - * This function walks (topologically unsafely) the mesh and return a
    - * non-zero integer if it finds the argument pointer is an object.
    - * The return value indicates which type of object it is belived to be.
    - * If topology is not locked, this function is potentially dangerous,
    - * but since it is for debugging purposes and can be useful for instance
    - * from DDB, we do not assert topology lock is held.
    + * This function walks the mesh and returns a non-zero integer if it
    + * finds the argument pointer is an object. The return value indicates
    + * which type of object it is believed to be. If topology is not locked,
    + * this function is potentially dangerous, but we don't assert that the
    + * topology lock is held when called from debugger.
      */
     int
     g_valid_obj(void const *ptr)
    @@ -1025,7 +1028,10 @@ g_valid_obj(void const *ptr)
     	struct g_consumer *cp;
     	struct g_provider *pp;
     
    -	g_topology_assert();
    +#ifdef KDB
    +	if (kdb_active == 0)
    +#endif
    +		g_topology_assert();
     
     	LIST_FOREACH(mp, &g_classes, class) {
     		if (ptr == mp)
    
    From ffb1296f2c1bd72d9011d2bb33697ac38baf2f7d Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Mon, 26 Apr 2010 17:03:56 +0000
    Subject: [PATCH 2114/2592] MFC r206625:   Add driver for Silicon Integrated
     Systems SiS190/191 Fast/Gigabit Ethernet.   This driver was written by
     Alexander Pohoyda and greatly enhanced   by Nikolay Denev. I don't have these
     hardwares but this driver was   tested by Nikolay Denev and xclin.
    
      Because SiS didn't release data sheet for this controller, programming
      information came from Linux driver and OpenSolaris. Unlike other open
      source driver for SiS190/191, sge(4) takes full advantage of TX/RX
      checksum offloading and does not require additional copy operation in
      RX handler.
      The controller seems to have advanced offloading features like VLAN
      hardware tag insertion/stripping, TCP segmentation offload(TSO) as
      well as jumbo frame support but these features are not available
      yet. Special thanks to xclin  cs dot nctu dot edu dot tw>
      who sent fix for receiving VLAN oversized frames.
    ---
     sys/amd64/conf/GENERIC     |    1 +
     sys/boot/forth/loader.conf |    1 +
     sys/conf/NOTES             |    2 +
     sys/conf/files             |    1 +
     sys/dev/sge/if_sge.c       | 1745 ++++++++++++++++++++++++++++++++++++
     sys/dev/sge/if_sgereg.h    |  350 ++++++++
     sys/i386/conf/GENERIC      |    1 +
     sys/modules/Makefile       |    1 +
     sys/modules/sge/Makefile   |    8 +
     9 files changed, 2110 insertions(+)
     create mode 100644 sys/dev/sge/if_sge.c
     create mode 100644 sys/dev/sge/if_sgereg.h
     create mode 100644 sys/modules/sge/Makefile
    
    diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
    index e9f3c170789..a0edfca7e95 100644
    --- a/sys/amd64/conf/GENERIC
    +++ b/sys/amd64/conf/GENERIC
    @@ -224,6 +224,7 @@ device		pcn		# AMD Am79C97x PCI 10/100 (precedence over 'le')
     device		re		# RealTek 8139C+/8169/8169S/8110S
     device		rl		# RealTek 8129/8139
     device		sf		# Adaptec AIC-6915 (``Starfire'')
    +device		sge		# Silicon Integrated Systems SiS190/191
     device		sis		# Silicon Integrated Systems SiS 900/SiS 7016
     device		sk		# SysKonnect SK-984x & SK-982x gigabit Ethernet
     device		ste		# Sundance ST201 (D-Link DFE-550TX)
    diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf
    index 422d5cb436c..f960f516cc8 100644
    --- a/sys/boot/forth/loader.conf
    +++ b/sys/boot/forth/loader.conf
    @@ -270,6 +270,7 @@ if_rl_load="NO"			# RealTek 8129/8139
     if_rue_load="NO"		# RealTek RTL8150 USB to Fast Ethernet
     if_sbni_load="NO"		# Granch SBNI12 leased line adapters
     if_sf_load="NO"			# Adaptec Duralink PCI (AIC-6915 "starfire")
    +if_sge_load="NO"		# Silicon Integrated Systems SiS190/191
     if_sis_load="NO"		# Silicon Integrated Systems SiS 900/7016
     if_sk_load="NO"			# SysKonnect SK-984x series PCI Gigabit Ethernet
     if_sn_load="NO"			# SMC 91Cxx
    diff --git a/sys/conf/NOTES b/sys/conf/NOTES
    index 107f581f4d2..09e20878026 100644
    --- a/sys/conf/NOTES
    +++ b/sys/conf/NOTES
    @@ -1906,6 +1906,7 @@ device		miibus
     #       This includes dual and quad port cards, as well as one 100baseFX card.
     #       Most of these are 64-bit PCI devices, except for one single port
     #       card which is 32-bit.
    +# sge:  Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet adapter
     # sis:  Support for NICs based on the Silicon Integrated Systems SiS 900,
     #       SiS 7016 and NS DP83815 PCI fast ethernet controller chips.
     # sk:   Support for the SysKonnect SK-984x series PCI gigabit ethernet NICs.
    @@ -2000,6 +2001,7 @@ device		re		# RealTek 8139C+/8169/8169S/8110S
     device		rl		# RealTek 8129/8139
     device		pcn		# AMD Am79C97x PCI 10/100 NICs
     device		sf		# Adaptec AIC-6915 (``Starfire'')
    +device		sge		# Silicon Integrated Systems SiS190/191
     device		sis		# Silicon Integrated Systems SiS 900/SiS 7016
     device		sk		# SysKonnect SK-984x & SK-982x gigabit Ethernet
     device		ste		# Sundance ST201 (D-Link DFE-550TX)
    diff --git a/sys/conf/files b/sys/conf/files
    index e2a7ade57fb..0b231be5d26 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -1476,6 +1476,7 @@ dev/scd/scd.c			optional scd isa
     dev/scd/scd_isa.c		optional scd isa
     dev/sdhci/sdhci.c		optional sdhci pci
     dev/sf/if_sf.c			optional sf pci
    +dev/sge/if_sge.c		optional sge pci
     dev/si/si.c			optional si
     dev/si/si2_z280.c		optional si
     dev/si/si3_t225.c		optional si
    diff --git a/sys/dev/sge/if_sge.c b/sys/dev/sge/if_sge.c
    new file mode 100644
    index 00000000000..a26a6a46359
    --- /dev/null
    +++ b/sys/dev/sge/if_sge.c
    @@ -0,0 +1,1745 @@
    +/*-
    + * Copyright (c) 2008-2010 Nikolay Denev 
    + * Copyright (c) 2007-2008 Alexander Pohoyda 
    + * Copyright (c) 1997, 1998, 1999
    + *	Bill Paul .  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.
    + * 3. All advertising materials mentioning features or use of this software
    + *    must display the following acknowledgement:
    + *	This product includes software developed by Bill Paul.
    + * 4. Neither the name of the author nor the names of any co-contributors
    + *    may be used to endorse or promote products derived from this software
    + *    without specific prior written permission.
    + *
    + * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 AUTHORS OR
    + * THE VOICES IN THEIR HEADS 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$");
    +
    +/*
    + * SiS 190/191 PCI Ethernet NIC driver.
    + *
    + * Adapted to SiS 190 NIC by Alexander Pohoyda based on the original
    + * SiS 900 driver by Bill Paul, using SiS 190/191 Solaris driver by
    + * Masayuki Murayama and SiS 190/191 GNU/Linux driver by K.M. Liu
    + * .  Thanks to Pyun YongHyeon  for
    + * review and very useful comments.
    + *
    + * Adapted to SiS 191 NIC by Nikolay Denev with further ideas from the
    + * Linux and Solaris drivers.
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +
    +#include "if_sgereg.h"
    +
    +MODULE_DEPEND(sge, pci, 1, 1, 1);
    +MODULE_DEPEND(sge, ether, 1, 1, 1);
    +MODULE_DEPEND(sge, miibus, 1, 1, 1);
    +
    +/* "device miibus0" required.  See GENERIC if you get errors here. */
    +#include "miibus_if.h"
    +
    +/*
    + * Various supported device vendors/types and their names.
    + */
    +static struct sge_type sge_devs[] = {
    +	{ SIS_VENDORID, SIS_DEVICEID_190, "SiS190 Fast Ethernet" },
    +	{ SIS_VENDORID, SIS_DEVICEID_191, "SiS191 Fast/Gigabit Ethernet" },
    +	{ 0, 0, NULL }
    +};
    +
    +static int	sge_probe(device_t);
    +static int	sge_attach(device_t);
    +static int	sge_detach(device_t);
    +static int	sge_shutdown(device_t);
    +static int	sge_suspend(device_t);
    +static int	sge_resume(device_t);
    +
    +static int	sge_miibus_readreg(device_t, int, int);
    +static int	sge_miibus_writereg(device_t, int, int, int);
    +static void	sge_miibus_statchg(device_t);
    +
    +static int	sge_newbuf(struct sge_softc *, int);
    +static int	sge_encap(struct sge_softc *, struct mbuf **);
    +#ifndef __NO_STRICT_ALIGNMENT
    +static __inline void
    +		sge_fixup_rx(struct mbuf *);
    +#endif
    +static __inline void
    +		sge_discard_rxbuf(struct sge_softc *, int);
    +static void	sge_rxeof(struct sge_softc *);
    +static void	sge_txeof(struct sge_softc *);
    +static void	sge_intr(void *);
    +static void	sge_tick(void *);
    +static void	sge_start(struct ifnet *);
    +static void	sge_start_locked(struct ifnet *);
    +static int	sge_ioctl(struct ifnet *, u_long, caddr_t);
    +static void	sge_init(void *);
    +static void	sge_init_locked(struct sge_softc *);
    +static void	sge_stop(struct sge_softc *);
    +static void	sge_watchdog(struct sge_softc *);
    +static int	sge_ifmedia_upd(struct ifnet *);
    +static void	sge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
    +
    +static int	sge_get_mac_addr_apc(struct sge_softc *, uint8_t *);
    +static int	sge_get_mac_addr_eeprom(struct sge_softc *, uint8_t *);
    +static uint16_t	sge_read_eeprom(struct sge_softc *, int);
    +
    +static void	sge_rxfilter(struct sge_softc *);
    +static void	sge_reset(struct sge_softc *);
    +static int	sge_list_rx_init(struct sge_softc *);
    +static int	sge_list_rx_free(struct sge_softc *);
    +static int	sge_list_tx_init(struct sge_softc *);
    +static int	sge_list_tx_free(struct sge_softc *);
    +
    +static int	sge_dma_alloc(struct sge_softc *);
    +static void	sge_dma_free(struct sge_softc *);
    +static void	sge_dma_map_addr(void *, bus_dma_segment_t *, int, int);
    +
    +static device_method_t sge_methods[] = {
    +	/* Device interface */
    +	DEVMETHOD(device_probe,		sge_probe),
    +	DEVMETHOD(device_attach,	sge_attach),
    +	DEVMETHOD(device_detach,	sge_detach),
    +	DEVMETHOD(device_suspend,	sge_suspend),
    +	DEVMETHOD(device_resume,	sge_resume),
    +	DEVMETHOD(device_shutdown,	sge_shutdown),
    +
    +	/* Bus interface */
    +	DEVMETHOD(bus_print_child,	bus_generic_print_child),
    +	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
    +
    +	/* MII interface */
    +	DEVMETHOD(miibus_readreg,	sge_miibus_readreg),
    +	DEVMETHOD(miibus_writereg,	sge_miibus_writereg),
    +	DEVMETHOD(miibus_statchg,	sge_miibus_statchg),
    +
    +	KOBJMETHOD_END
    +};
    +
    +static driver_t sge_driver = {
    +	"sge", sge_methods, sizeof(struct sge_softc)
    +};
    +
    +static devclass_t sge_devclass;
    +
    +DRIVER_MODULE(sge, pci, sge_driver, sge_devclass, 0, 0);
    +DRIVER_MODULE(miibus, sge, miibus_driver, miibus_devclass, 0, 0);
    +
    +/*
    + * Register space access macros.
    + */
    +#define	CSR_WRITE_4(sc, reg, val)	bus_write_4(sc->sge_res, reg, val)
    +#define	CSR_WRITE_2(sc, reg, val)	bus_write_2(sc->sge_res, reg, val)
    +#define	CSR_WRITE_1(cs, reg, val)	bus_write_1(sc->sge_res, reg, val)
    +
    +#define	CSR_READ_4(sc, reg)		bus_read_4(sc->sge_res, reg)
    +#define	CSR_READ_2(sc, reg)		bus_read_2(sc->sge_res, reg)
    +#define	CSR_READ_1(sc, reg)		bus_read_1(sc->sge_res, reg)
    +
    +/* Define to show Tx/Rx error status. */
    +#undef SGE_SHOW_ERRORS
    +
    +#define	SGE_CSUM_FEATURES	(CSUM_IP | CSUM_TCP | CSUM_UDP)
    +
    +static void
    +sge_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
    +{
    +	bus_addr_t *p;
    +
    +	if (error != 0)
    +		return;
    +	KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg));
    +	p  = arg;
    +	*p = segs->ds_addr;
    +}
    +
    +/*
    + * Read a sequence of words from the EEPROM.
    + */
    +static uint16_t
    +sge_read_eeprom(struct sge_softc *sc, int offset)
    +{
    +	uint32_t val;
    +	int i;
    +
    +	KASSERT(offset <= EI_OFFSET, ("EEPROM offset too big"));
    +	CSR_WRITE_4(sc, ROMInterface,
    +	    EI_REQ | EI_OP_RD | (offset << EI_OFFSET_SHIFT));
    +	DELAY(500);
    +	for (i = 0; i < SGE_TIMEOUT; i++) {
    +		val = CSR_READ_4(sc, ROMInterface);
    +		if ((val & EI_REQ) == 0)
    +			break;
    +		DELAY(100);
    +	}
    +	if (i == SGE_TIMEOUT) {
    +		device_printf(sc->sge_dev,
    +		    "EEPROM read timeout : 0x%08x\n", val);
    +		return (0xffff);
    +	}
    +
    +	return ((val & EI_DATA) >> EI_DATA_SHIFT);
    +}
    +
    +static int
    +sge_get_mac_addr_eeprom(struct sge_softc *sc, uint8_t *dest)
    +{
    +	uint16_t val;
    +	int i;
    +
    +	val = sge_read_eeprom(sc, EEPROMSignature);
    +	if (val == 0xffff || val == 0) {
    +		device_printf(sc->sge_dev,
    +		    "invalid EEPROM signature : 0x%04x\n", val);
    +		return (EINVAL);
    +	}
    +
    +	for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
    +		val = sge_read_eeprom(sc, EEPROMMACAddr + i / 2);
    +		dest[i + 0] = (uint8_t)val;
    +		dest[i + 1] = (uint8_t)(val >> 8);
    +	}
    +
    +	if ((sge_read_eeprom(sc, EEPROMInfo) & 0x80) != 0)
    +		sc->sge_flags |= SGE_FLAG_RGMII;
    +	return (0);
    +}
    +
    +/*
    + * For SiS96x, APC CMOS RAM is used to store ethernet address.
    + * APC CMOS RAM is accessed through ISA bridge.
    + */
    +static int
    +sge_get_mac_addr_apc(struct sge_softc *sc, uint8_t *dest)
    +{
    +#if defined(__amd64__) || defined(__i386__)
    +	devclass_t pci;
    +	device_t bus, dev = NULL;
    +	device_t *kids;
    +	struct apc_tbl {
    +		uint16_t vid;
    +		uint16_t did;
    +	} *tp, apc_tbls[] = {
    +		{ SIS_VENDORID, 0x0965 },
    +		{ SIS_VENDORID, 0x0966 },
    +		{ SIS_VENDORID, 0x0968 }
    +	};
    +	uint8_t reg;
    +	int busnum, cnt, i, j, numkids;
    +
    +	cnt = sizeof(apc_tbls) / sizeof(apc_tbls[0]);
    +	pci = devclass_find("pci");
    +	for (busnum = 0; busnum < devclass_get_maxunit(pci); busnum++) {
    +		bus = devclass_get_device(pci, busnum);
    +		if (!bus)
    +			continue;
    +		if (device_get_children(bus, &kids, &numkids) != 0)
    +			continue;
    +		for (i = 0; i < numkids; i++) {
    +			dev = kids[i];
    +			if (pci_get_class(dev) == PCIC_BRIDGE &&
    +			    pci_get_subclass(dev) == PCIS_BRIDGE_ISA) {
    +				tp = apc_tbls;
    +				for (j = 0; j < cnt; j++) {
    +					if (pci_get_vendor(dev) == tp->vid &&
    +					    pci_get_device(dev) == tp->did) {
    +						free(kids, M_TEMP);
    +						goto apc_found;
    +					}
    +					tp++;
    +				}
    +			}
    +                }
    +		free(kids, M_TEMP);
    +	}
    +	device_printf(sc->sge_dev, "couldn't find PCI-ISA bridge\n");
    +	return (EINVAL);
    +apc_found:
    +	/* Enable port 0x78 and 0x79 to access APC registers. */
    +	reg = pci_read_config(dev, 0x48, 1);
    +	pci_write_config(dev, 0x48, reg & ~0x02, 1);
    +	DELAY(50);
    +	pci_read_config(dev, 0x48, 1);
    +	/* Read stored ethernet address. */
    +	for (i = 0; i < ETHER_ADDR_LEN; i++) {
    +		outb(0x78, 0x09 + i);
    +		dest[i] = inb(0x79);
    +	}
    +	outb(0x78, 0x12);
    +	if ((inb(0x79) & 0x80) != 0)
    +		sc->sge_flags |= SGE_FLAG_RGMII;
    +	/* Restore access to APC registers. */
    +	pci_write_config(dev, 0x48, reg, 1);
    +
    +	return (0);
    +#else
    +	return (EINVAL);
    +#endif
    +}
    +
    +static int
    +sge_miibus_readreg(device_t dev, int phy, int reg)
    +{
    +	struct sge_softc *sc;
    +	uint32_t val;
    +	int i;
    +
    +	sc = device_get_softc(dev);
    +	CSR_WRITE_4(sc, GMIIControl, (phy << GMI_PHY_SHIFT) |
    +	    (reg << GMI_REG_SHIFT) | GMI_OP_RD | GMI_REQ);
    +	DELAY(10);
    +	for (i = 0; i < SGE_TIMEOUT; i++) {
    +		val = CSR_READ_4(sc, GMIIControl);
    +		if ((val & GMI_REQ) == 0)
    +			break;
    +		DELAY(10);
    +	}
    +	if (i == SGE_TIMEOUT) {
    +		device_printf(sc->sge_dev, "PHY read timeout : %d\n", reg);
    +		return (0);
    +	}
    +	return ((val & GMI_DATA) >> GMI_DATA_SHIFT);
    +}
    +
    +static int
    +sge_miibus_writereg(device_t dev, int phy, int reg, int data)
    +{
    +	struct sge_softc *sc;
    +	uint32_t val;
    +	int i;
    +
    +	sc = device_get_softc(dev);
    +	CSR_WRITE_4(sc, GMIIControl, (phy << GMI_PHY_SHIFT) |
    +	    (reg << GMI_REG_SHIFT) | (data << GMI_DATA_SHIFT) |
    +	    GMI_OP_WR | GMI_REQ);
    +	DELAY(10);
    +	for (i = 0; i < SGE_TIMEOUT; i++) {
    +		val = CSR_READ_4(sc, GMIIControl);
    +		if ((val & GMI_REQ) == 0)
    +			break;
    +		DELAY(10);
    +	}
    +	if (i == SGE_TIMEOUT)
    +		device_printf(sc->sge_dev, "PHY write timeout : %d\n", reg);
    +	return (0);
    +}
    +
    +static void
    +sge_miibus_statchg(device_t dev)
    +{
    +	struct sge_softc *sc;
    +	struct mii_data *mii;
    +	struct ifnet *ifp;
    +	uint32_t ctl, speed;
    +
    +	sc = device_get_softc(dev);
    +	mii = device_get_softc(sc->sge_miibus);
    +	ifp = sc->sge_ifp;
    +	if (mii == NULL || ifp == NULL ||
    +	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
    +		return;
    +	speed = 0;
    +	sc->sge_flags &= ~SGE_FLAG_LINK;
    +	if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
    +	    (IFM_ACTIVE | IFM_AVALID)) {
    +		switch (IFM_SUBTYPE(mii->mii_media_active)) {
    +		case IFM_10_T:
    +			sc->sge_flags |= SGE_FLAG_LINK;
    +			speed = SC_SPEED_10;
    +			break;
    +		case IFM_100_TX:
    +			sc->sge_flags |= SGE_FLAG_LINK;
    +			speed = SC_SPEED_100;
    +			break;
    +		case IFM_1000_T:
    +			if ((sc->sge_flags & SGE_FLAG_FASTETHER) == 0) {
    +				sc->sge_flags |= SGE_FLAG_LINK;
    +				speed = SC_SPEED_1000;
    +			}
    +			break;
    +		default:
    +			break;
    +                }
    +        }
    +	if ((sc->sge_flags & SGE_FLAG_LINK) == 0)
    +		return;
    +	/* Reprogram MAC to resolved speed/duplex/flow-control parameters. */
    +	ctl = CSR_READ_4(sc, StationControl);
    +	ctl &= ~(0x0f000000 | SC_FDX | SC_SPEED_MASK);
    +	if (speed == SC_SPEED_1000) {
    +		ctl |= 0x07000000;
    +		sc->sge_flags |= SGE_FLAG_SPEED_1000;
    +	} else {
    +		ctl |= 0x04000000;
    +		sc->sge_flags &= ~SGE_FLAG_SPEED_1000;
    +	}
    +#ifdef notyet
    +	if ((sc->sge_flags & SGE_FLAG_GMII) != 0)
    +		ctl |= 0x03000000;
    +#endif
    +	ctl |= speed;
    +	if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
    +		ctl |= SC_FDX;
    +		sc->sge_flags |= SGE_FLAG_FDX;
    +	} else
    +		sc->sge_flags &= ~SGE_FLAG_FDX;
    +	CSR_WRITE_4(sc, StationControl, ctl);
    +	if ((sc->sge_flags & SGE_FLAG_RGMII) != 0) {
    +		CSR_WRITE_4(sc, RGMIIDelay, 0x0441);
    +		CSR_WRITE_4(sc, RGMIIDelay, 0x0440);
    +	}
    +}
    +
    +static void
    +sge_rxfilter(struct sge_softc *sc)
    +{
    +	struct ifnet *ifp;
    +	struct ifmultiaddr *ifma;
    +	uint32_t crc, hashes[2];
    +	uint16_t rxfilt;
    +
    +	SGE_LOCK_ASSERT(sc);
    +
    +	ifp = sc->sge_ifp;
    +	hashes[0] = hashes[1] = 0;
    +	rxfilt = AcceptMyPhys;
    +	if ((ifp->if_flags & IFF_BROADCAST) != 0)
    +		rxfilt |= AcceptBroadcast;
    +	if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
    +		if ((ifp->if_flags & IFF_PROMISC) != 0)
    +			rxfilt |= AcceptAllPhys;
    +		rxfilt |= AcceptMulticast;
    +		hashes[0] = 0xFFFFFFFF;
    +		hashes[1] = 0xFFFFFFFF;
    +		goto done;
    +	}
    +	rxfilt |= AcceptMulticast;
    +	/* Now program new ones. */
    +	if_maddr_rlock(ifp);
    +	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
    +		if (ifma->ifma_addr->sa_family != AF_LINK)
    +			continue;
    +		crc = ether_crc32_be(LLADDR((struct sockaddr_dl *)
    +		    ifma->ifma_addr), ETHER_ADDR_LEN);
    +		hashes[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
    +	}
    +	if_maddr_runlock(ifp);
    +done:
    +	CSR_WRITE_2(sc, RxMacControl, rxfilt | 0x02);
    +	CSR_WRITE_4(sc, RxHashTable, hashes[0]);
    +	CSR_WRITE_4(sc, RxHashTable2, hashes[1]);
    +}
    +
    +static void
    +sge_reset(struct sge_softc *sc)
    +{
    +
    +	CSR_WRITE_4(sc, IntrMask, 0);
    +	CSR_WRITE_4(sc, IntrStatus, 0xffffffff);
    +
    +	/* Soft reset. */
    +	CSR_WRITE_4(sc, IntrControl, 0x8000);
    +	CSR_READ_4(sc, IntrControl);
    +	DELAY(100);
    +	CSR_WRITE_4(sc, IntrControl, 0);
    +	/* Stop MAC. */
    +	CSR_WRITE_4(sc, TX_CTL, 0x1a00);
    +	CSR_WRITE_4(sc, RX_CTL, 0x1a00);
    +
    +	CSR_WRITE_4(sc, IntrMask, 0);
    +	CSR_WRITE_4(sc, IntrStatus, 0xffffffff);
    +
    +	CSR_WRITE_4(sc, GMIIControl, 0);
    +}
    +
    +/*
    + * Probe for an SiS chip. Check the PCI vendor and device
    + * IDs against our list and return a device name if we find a match.
    + */
    +static int
    +sge_probe(device_t dev)
    +{
    +	struct sge_type *t;
    +
    +	t = sge_devs;
    +	while (t->sge_name != NULL) {
    +		if ((pci_get_vendor(dev) == t->sge_vid) &&
    +		    (pci_get_device(dev) == t->sge_did)) {
    +			device_set_desc(dev, t->sge_name);
    +			return (BUS_PROBE_DEFAULT);
    +		}
    +		t++;
    +	}
    +
    +	return (ENXIO);
    +}
    +
    +/*
    + * Attach the interface.  Allocate softc structures, do ifmedia
    + * setup and ethernet/BPF attach.
    + */
    +static int
    +sge_attach(device_t dev)
    +{
    +	struct sge_softc *sc;
    +	struct ifnet *ifp;
    +	uint8_t eaddr[ETHER_ADDR_LEN];
    +	int error = 0, rid;
    +
    +	sc = device_get_softc(dev);
    +	sc->sge_dev = dev;
    +
    +	mtx_init(&sc->sge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
    +	    MTX_DEF);
    +        callout_init_mtx(&sc->sge_stat_ch, &sc->sge_mtx, 0);
    +
    +	/*
    +	 * Map control/status registers.
    +	 */
    +	pci_enable_busmaster(dev);
    +
    +	/* Allocate resources. */
    +	sc->sge_res_id = PCIR_BAR(0);
    +	sc->sge_res_type = SYS_RES_MEMORY;
    +	sc->sge_res = bus_alloc_resource_any(dev, sc->sge_res_type,
    +	    &sc->sge_res_id, RF_ACTIVE);
    +	if (sc->sge_res == NULL) {
    +		device_printf(dev, "couldn't allocate resource\n");
    +		error = ENXIO;
    +		goto fail;
    +	}
    +
    +	rid = 0;
    +	sc->sge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
    +	    RF_SHAREABLE | RF_ACTIVE);
    +	if (sc->sge_irq == NULL) {
    +		device_printf(dev, "couldn't allocate IRQ resources\n");
    +		error = ENXIO;
    +		goto fail;
    +	}
    +	sc->sge_rev = pci_get_revid(dev);
    +	if (pci_get_device(dev) == SIS_DEVICEID_190)
    +		sc->sge_flags |= SGE_FLAG_FASTETHER;
    +	/* Reset the adapter. */
    +	sge_reset(sc);
    +
    +	/* Get MAC address from the EEPROM. */
    +	if ((pci_read_config(dev, 0x73, 1) & 0x01) != 0)
    +		sge_get_mac_addr_apc(sc, eaddr);
    +	else
    +		sge_get_mac_addr_eeprom(sc, eaddr);
    +
    +	if ((error = sge_dma_alloc(sc)) != 0)
    +		goto fail;
    +
    +	ifp = sc->sge_ifp = if_alloc(IFT_ETHER);
    +	if (ifp == NULL) {
    +		device_printf(dev, "cannot allocate ifnet structure.\n");
    +		error = ENOSPC;
    +		goto fail;
    +	}
    +	ifp->if_softc = sc;
    +	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
    +	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    +	ifp->if_ioctl = sge_ioctl;
    +	ifp->if_start = sge_start;
    +	ifp->if_init = sge_init;
    +	ifp->if_snd.ifq_drv_maxlen = SGE_TX_RING_CNT - 1;
    +	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
    +	IFQ_SET_READY(&ifp->if_snd);
    +	ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_RXCSUM;
    +	ifp->if_hwassist = SGE_CSUM_FEATURES;
    +	ifp->if_capenable = ifp->if_capabilities;
    +	/*
    +	 * Do MII setup.
    +	 */
    +	if (mii_phy_probe(dev, &sc->sge_miibus, sge_ifmedia_upd,
    +	    sge_ifmedia_sts)) {
    +		device_printf(dev, "no PHY found!\n");
    +		error = ENXIO;
    +		goto fail;
    +	}
    +
    +	/*
    +	 * Call MI attach routine.
    +	 */
    +	ether_ifattach(ifp, eaddr);
    +
    +	/* VLAN setup. */
    +	ifp->if_capabilities |= IFCAP_VLAN_MTU;
    +	ifp->if_capenable = ifp->if_capabilities;
    +	/* Tell the upper layer(s) we support long frames. */
    +	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
    +
    +	/* Hook interrupt last to avoid having to lock softc */
    +	error = bus_setup_intr(dev, sc->sge_irq, INTR_TYPE_NET | INTR_MPSAFE,
    +	    NULL, sge_intr, sc, &sc->sge_intrhand);
    +	if (error) {
    +		device_printf(dev, "couldn't set up irq\n");
    +		ether_ifdetach(ifp);
    +		goto fail;
    +	}
    +
    +fail:
    +	if (error)
    +		sge_detach(dev);
    +
    +	return (error);
    +}
    +
    +/*
    + * Shutdown hardware and free up resources.  This can be called any
    + * time after the mutex has been initialized.  It is called in both
    + * the error case in attach and the normal detach case so it needs
    + * to be careful about only freeing resources that have actually been
    + * allocated.
    + */
    +static int
    +sge_detach(device_t dev)
    +{
    +	struct sge_softc *sc;
    +	struct ifnet *ifp;
    +
    +	sc = device_get_softc(dev);
    +	ifp = sc->sge_ifp;
    +	/* These should only be active if attach succeeded. */
    +	if (device_is_attached(dev)) {
    +		ether_ifdetach(ifp);
    +		SGE_LOCK(sc);
    +		sge_stop(sc);
    +		SGE_UNLOCK(sc);
    +		callout_drain(&sc->sge_stat_ch);
    +	}
    +	if (sc->sge_miibus)
    +		device_delete_child(dev, sc->sge_miibus);
    +	bus_generic_detach(dev);
    +
    +	if (sc->sge_intrhand)
    +		bus_teardown_intr(dev, sc->sge_irq, sc->sge_intrhand);
    +	if (sc->sge_irq)
    +		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sge_irq);
    +	if (sc->sge_res)
    +		bus_release_resource(dev, sc->sge_res_type, sc->sge_res_id,
    +		    sc->sge_res);
    +	if (ifp)
    +		if_free(ifp);
    +	sge_dma_free(sc);
    +	mtx_destroy(&sc->sge_mtx);
    +
    +	return (0);
    +}
    +
    +/*
    + * Stop all chip I/O so that the kernel's probe routines don't
    + * get confused by errant DMAs when rebooting.
    + */
    +static int
    +sge_shutdown(device_t dev)
    +{
    +	struct sge_softc *sc;
    +
    +	sc = device_get_softc(dev);
    +	SGE_LOCK(sc);
    +	sge_stop(sc);
    +	SGE_UNLOCK(sc);
    +	return (0);
    +}
    +
    +static int
    +sge_suspend(device_t dev)
    +{
    +	struct sge_softc *sc;
    +	struct ifnet *ifp;
    +
    +	sc = device_get_softc(dev);
    +	SGE_LOCK(sc);
    +	ifp = sc->sge_ifp;
    +	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
    +		sge_stop(sc);
    +	SGE_UNLOCK(sc);
    +	return (0);
    +}
    +
    +static int
    +sge_resume(device_t dev)
    +{
    +	struct sge_softc *sc;
    +	struct ifnet *ifp;
    +
    +	sc = device_get_softc(dev);
    +	SGE_LOCK(sc);
    +	ifp = sc->sge_ifp;
    +	if ((ifp->if_flags & IFF_UP) != 0)
    +		sge_init_locked(sc);
    +	SGE_UNLOCK(sc);
    +	return (0);
    +}
    +
    +static int
    +sge_dma_alloc(struct sge_softc *sc)
    +{
    +	struct sge_chain_data *cd;
    +	struct sge_list_data *ld;
    +	int error, i;
    +
    +	cd = &sc->sge_cdata;
    +	ld = &sc->sge_ldata;
    +	error = bus_dma_tag_create(bus_get_dma_tag(sc->sge_dev),
    +	    1, 0,			/* alignment, boundary */
    +	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
    +	    BUS_SPACE_MAXADDR,		/* highaddr */
    +	    NULL, NULL,			/* filter, filterarg */
    +	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
    +	    1,				/* nsegments */
    +	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
    +	    0,				/* flags */
    +	    NULL,			/* lockfunc */
    +	    NULL,			/* lockarg */
    +	    &cd->sge_tag);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not create parent DMA tag.\n");
    +		goto fail;
    +	}
    +
    +	/* RX descriptor ring */
    +	error = bus_dma_tag_create(cd->sge_tag,
    +	    SGE_DESC_ALIGN, 0,		/* alignment, boundary */
    +	    BUS_SPACE_MAXADDR,		/* lowaddr */
    +	    BUS_SPACE_MAXADDR,		/* highaddr */
    +	    NULL, NULL,			/* filter, filterarg */
    +	    SGE_RX_RING_SZ, 1,		/* maxsize,nsegments */
    +	    SGE_RX_RING_SZ,		/* maxsegsize */
    +	    0,				/* flags */
    +	    NULL,			/* lockfunc */
    +	    NULL,			/* lockarg */
    +	    &cd->sge_rx_tag);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not create Rx ring DMA tag.\n");
    +		goto fail;
    +	}
    +	/* Allocate DMA'able memory and load DMA map for RX ring. */
    +	error = bus_dmamem_alloc(cd->sge_rx_tag, (void **)&ld->sge_rx_ring,
    +	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
    +	    &cd->sge_rx_dmamap);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not allocate DMA'able memory for Rx ring.\n");
    +		goto fail;
    +	}
    +	error = bus_dmamap_load(cd->sge_rx_tag, cd->sge_rx_dmamap,
    +	    ld->sge_rx_ring, SGE_RX_RING_SZ, sge_dma_map_addr,
    +	    &ld->sge_rx_paddr, BUS_DMA_NOWAIT);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not load DMA'able memory for Rx ring.\n");
    +	}
    +
    +	/* TX descriptor ring */
    +	error = bus_dma_tag_create(cd->sge_tag,
    +	    SGE_DESC_ALIGN, 0,		/* alignment, boundary */
    +	    BUS_SPACE_MAXADDR,		/* lowaddr */
    +	    BUS_SPACE_MAXADDR,		/* highaddr */
    +	    NULL, NULL,			/* filter, filterarg */
    +	    SGE_TX_RING_SZ, 1,		/* maxsize,nsegments */
    +	    SGE_TX_RING_SZ,		/* maxsegsize */
    +	    0,				/* flags */
    +	    NULL,			/* lockfunc */
    +	    NULL,			/* lockarg */
    +	    &cd->sge_tx_tag);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not create Rx ring DMA tag.\n");
    +		goto fail;
    +	}
    +	/* Allocate DMA'able memory and load DMA map for TX ring. */
    +	error = bus_dmamem_alloc(cd->sge_tx_tag, (void **)&ld->sge_tx_ring,
    +	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
    +	    &cd->sge_tx_dmamap);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not allocate DMA'able memory for Tx ring.\n");
    +		goto fail;
    +	}
    +	error = bus_dmamap_load(cd->sge_tx_tag, cd->sge_tx_dmamap,
    +	    ld->sge_tx_ring, SGE_TX_RING_SZ, sge_dma_map_addr,
    +	    &ld->sge_tx_paddr, BUS_DMA_NOWAIT);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not load DMA'able memory for Rx ring.\n");
    +		goto fail;
    +	}
    +
    +	/* Create DMA tag for Tx buffers. */
    +	error = bus_dma_tag_create(cd->sge_tag, 1, 0, BUS_SPACE_MAXADDR,
    +	    BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES * SGE_MAXTXSEGS,
    +	    SGE_MAXTXSEGS, MCLBYTES, 0, NULL, NULL, &cd->sge_txmbuf_tag);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not create Tx mbuf DMA tag.\n");
    +		goto fail;
    +	}
    +
    +	/* Create DMA tag for Rx buffers. */
    +	error = bus_dma_tag_create(cd->sge_tag, SGE_RX_BUF_ALIGN, 0,
    +	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1,
    +	    MCLBYTES, 0, NULL, NULL, &cd->sge_rxmbuf_tag);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not create Rx mbuf DMA tag.\n");
    +		goto fail;
    +	}
    +
    +	/* Create DMA maps for Tx buffers. */
    +	for (i = 0; i < SGE_TX_RING_CNT; i++) {
    +		error = bus_dmamap_create(cd->sge_txmbuf_tag, 0,
    +		    &cd->sge_tx_map[i]);
    +		if (error != 0) {
    +			device_printf(sc->sge_dev,
    +			    "could not create Tx DMA map.\n");
    +			goto fail;
    +		}
    +	}
    +	/* Create spare DMA map for Rx buffer. */
    +	error = bus_dmamap_create(cd->sge_rxmbuf_tag, 0, &cd->sge_rx_spare_map);
    +	if (error != 0) {
    +		device_printf(sc->sge_dev,
    +		    "could not create spare Rx DMA map.\n");
    +		goto fail;
    +	}
    +	/* Create DMA maps for Rx buffers. */
    +	for (i = 0; i < SGE_RX_RING_CNT; i++) {
    +		error = bus_dmamap_create(cd->sge_rxmbuf_tag, 0,
    +		    &cd->sge_rx_map[i]);
    +		if (error) {
    +			device_printf(sc->sge_dev,
    +			    "could not create Rx DMA map.\n");
    +			goto fail;
    +		}
    +	}
    +fail:
    +	return (error);
    +}
    +
    +static void
    +sge_dma_free(struct sge_softc *sc)
    +{
    +	struct sge_chain_data *cd;
    +	struct sge_list_data *ld;
    +	int i;
    +
    +	cd = &sc->sge_cdata;
    +	ld = &sc->sge_ldata;
    +	/* Rx ring. */
    +	if (cd->sge_rx_tag != NULL) {
    +		if (cd->sge_rx_dmamap != NULL)
    +			bus_dmamap_unload(cd->sge_rx_tag, cd->sge_rx_dmamap);
    +		if (cd->sge_rx_dmamap != NULL && ld->sge_rx_ring != NULL)
    +			bus_dmamem_free(cd->sge_rx_tag, ld->sge_rx_ring,
    +			    cd->sge_rx_dmamap);
    +		ld->sge_rx_ring = NULL;
    +		cd->sge_rx_dmamap = NULL;
    +		bus_dma_tag_destroy(cd->sge_rx_tag);
    +		cd->sge_rx_tag = NULL;
    +	}
    +	/* Tx ring. */
    +	if (cd->sge_tx_tag != NULL) {
    +		if (cd->sge_tx_dmamap != NULL)
    +			bus_dmamap_unload(cd->sge_tx_tag, cd->sge_tx_dmamap);
    +		if (cd->sge_tx_dmamap != NULL && ld->sge_tx_ring != NULL)
    +			bus_dmamem_free(cd->sge_tx_tag, ld->sge_tx_ring,
    +			    cd->sge_tx_dmamap);
    +		ld->sge_tx_ring = NULL;
    +		cd->sge_tx_dmamap = NULL;
    +		bus_dma_tag_destroy(cd->sge_tx_tag);
    +		cd->sge_tx_tag = NULL;
    +	}
    +	/* Rx buffers. */
    +	if (cd->sge_rxmbuf_tag != NULL) {
    +		for (i = 0; i < SGE_RX_RING_CNT; i++) {
    +			if (cd->sge_rx_map[i] != NULL) {
    +				bus_dmamap_destroy(cd->sge_rxmbuf_tag,
    +				    cd->sge_rx_map[i]);
    +				cd->sge_rx_map[i] = NULL;
    +			}
    +		}
    +		if (cd->sge_rx_spare_map != NULL) {
    +			bus_dmamap_destroy(cd->sge_rxmbuf_tag,
    +			    cd->sge_rx_spare_map);
    +			cd->sge_rx_spare_map = NULL;
    +		}
    +		bus_dma_tag_destroy(cd->sge_rxmbuf_tag);
    +		cd->sge_rxmbuf_tag = NULL;
    +	}
    +	/* Tx buffers. */
    +	if (cd->sge_txmbuf_tag != NULL) {
    +		for (i = 0; i < SGE_TX_RING_CNT; i++) {
    +			if (cd->sge_tx_map[i] != NULL) {
    +				bus_dmamap_destroy(cd->sge_txmbuf_tag,
    +				    cd->sge_tx_map[i]);
    +				cd->sge_tx_map[i] = NULL;
    +			}
    +		}
    +		bus_dma_tag_destroy(cd->sge_txmbuf_tag);
    +		cd->sge_txmbuf_tag = NULL;
    +	}
    +	if (cd->sge_tag != NULL)
    +		bus_dma_tag_destroy(cd->sge_tag);
    +	cd->sge_tag = NULL;
    +}
    +
    +/*
    + * Initialize the TX descriptors.
    + */
    +static int
    +sge_list_tx_init(struct sge_softc *sc)
    +{
    +	struct sge_list_data *ld;
    +	struct sge_chain_data *cd;
    +
    +	SGE_LOCK_ASSERT(sc);
    +	ld = &sc->sge_ldata;
    +	cd = &sc->sge_cdata;
    +	bzero(ld->sge_tx_ring, SGE_TX_RING_SZ);
    +	ld->sge_tx_ring[SGE_TX_RING_CNT - 1].sge_flags = htole32(RING_END);
    +	bus_dmamap_sync(cd->sge_tx_tag, cd->sge_tx_dmamap,
    +	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    +	cd->sge_tx_prod = 0;
    +	cd->sge_tx_cons = 0;
    +	cd->sge_tx_cnt = 0;
    +	return (0);
    +}
    +
    +static int
    +sge_list_tx_free(struct sge_softc *sc)
    +{
    +	struct sge_chain_data *cd;
    +	int i;
    +
    +	SGE_LOCK_ASSERT(sc);
    +	cd = &sc->sge_cdata;
    +	for (i = 0; i < SGE_TX_RING_CNT; i++) {
    +		if (cd->sge_tx_mbuf[i] != NULL) {
    +			bus_dmamap_sync(cd->sge_txmbuf_tag,
    +			    cd->sge_tx_map[i], BUS_DMASYNC_POSTWRITE);
    +			bus_dmamap_unload(cd->sge_txmbuf_tag,
    +			    cd->sge_tx_map[i]);
    +			m_free(cd->sge_tx_mbuf[i]);
    +			cd->sge_tx_mbuf[i] = NULL;
    +		}
    +	}
    +
    +	return (0);
    +}
    +
    +/*
    + * Initialize the RX descriptors and allocate mbufs for them.  Note that
    + * we arrange the descriptors in a closed ring, so that the last descriptor
    + * has RING_END flag set.
    + */
    +static int
    +sge_list_rx_init(struct sge_softc *sc)
    +{
    +	struct sge_chain_data *cd;
    +	int i;
    +
    +	SGE_LOCK_ASSERT(sc);
    +	cd = &sc->sge_cdata;
    +	cd->sge_rx_cons = 0;
    +	bzero(sc->sge_ldata.sge_rx_ring, SGE_RX_RING_SZ);
    +	for (i = 0; i < SGE_RX_RING_CNT; i++) {
    +		if (sge_newbuf(sc, i) != 0)
    +			return (ENOBUFS);
    +	}
    +	bus_dmamap_sync(cd->sge_rx_tag, cd->sge_rx_dmamap,
    +	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    +	return (0);
    +}
    +
    +static int
    +sge_list_rx_free(struct sge_softc *sc)
    +{
    +	struct sge_chain_data *cd;
    +	int i;
    +
    +	SGE_LOCK_ASSERT(sc);
    +	cd = &sc->sge_cdata;
    +	for (i = 0; i < SGE_RX_RING_CNT; i++) {
    +		if (cd->sge_rx_mbuf[i] != NULL) {
    +			bus_dmamap_sync(cd->sge_rxmbuf_tag, cd->sge_rx_map[i],
    +			    BUS_DMASYNC_POSTREAD);
    +			bus_dmamap_unload(cd->sge_rxmbuf_tag,
    +			    cd->sge_rx_map[i]);
    +			m_free(cd->sge_rx_mbuf[i]);
    +			cd->sge_rx_mbuf[i] = NULL;
    +		}
    +	}
    +	return (0);
    +}
    +
    +/*
    + * Initialize an RX descriptor and attach an MBUF cluster.
    + */
    +static int
    +sge_newbuf(struct sge_softc *sc, int prod)
    +{
    +	struct mbuf *m;
    +	struct sge_desc *desc;
    +	struct sge_chain_data *cd;
    +	bus_dma_segment_t segs[1];
    +	bus_dmamap_t map;
    +	int error, nsegs;
    +
    +	SGE_LOCK_ASSERT(sc);
    +
    +	cd = &sc->sge_cdata;
    +	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
    +	if (m == NULL)
    +		return (ENOBUFS);
    +	m->m_len = m->m_pkthdr.len = MCLBYTES;
    +	m_adj(m, SGE_RX_BUF_ALIGN);
    +	error = bus_dmamap_load_mbuf_sg(cd->sge_rxmbuf_tag,
    +	    cd->sge_rx_spare_map, m, segs, &nsegs, 0);
    +	if (error != 0) {
    +		m_freem(m);
    +		return (error);
    +	}
    +	KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
    +	if (cd->sge_rx_mbuf[prod] != NULL) {
    +		bus_dmamap_sync(cd->sge_rxmbuf_tag, cd->sge_rx_map[prod],
    +		    BUS_DMASYNC_POSTREAD);
    +		bus_dmamap_unload(cd->sge_rxmbuf_tag, cd->sge_rx_map[prod]);
    +	}
    +	map = cd->sge_rx_map[prod];
    +	cd->sge_rx_map[prod] =  cd->sge_rx_spare_map;
    +	cd->sge_rx_spare_map = map;
    +	bus_dmamap_sync(cd->sge_rxmbuf_tag, cd->sge_rx_map[prod],
    +	    BUS_DMASYNC_PREREAD);
    +	cd->sge_rx_mbuf[prod] = m;
    +
    +	desc = &sc->sge_ldata.sge_rx_ring[prod];
    +	desc->sge_sts_size = 0;
    +	desc->sge_ptr = htole32(SGE_ADDR_LO(segs[0].ds_addr));
    +	desc->sge_flags = htole32(segs[0].ds_len);
    +	if (prod == SGE_RX_RING_CNT - 1)
    +		desc->sge_flags |= htole32(RING_END);
    +	desc->sge_cmdsts = htole32(RDC_OWN | RDC_INTR | RDC_IP_CSUM |
    +	    RDC_TCP_CSUM | RDC_UDP_CSUM);
    +	return (0);
    +}
    +
    +#ifndef __NO_STRICT_ALIGNMENT
    +static __inline void
    +sge_fixup_rx(struct mbuf *m)
    +{
    +        int i;
    +        uint16_t *src, *dst;
    +
    +	src = mtod(m, uint16_t *);
    +	dst = src - 3;
    +
    +	for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++)
    +		*dst++ = *src++;
    +
    +	m->m_data -= (SGE_RX_BUF_ALIGN - ETHER_ALIGN);
    +}
    +#endif
    +
    +static __inline void
    +sge_discard_rxbuf(struct sge_softc *sc, int index)
    +{
    +	struct sge_desc *desc;
    +
    +	desc = &sc->sge_ldata.sge_rx_ring[index];
    +	desc->sge_sts_size = 0;
    +	desc->sge_flags = htole32(MCLBYTES - SGE_RX_BUF_ALIGN);
    +	if (index == SGE_RX_RING_CNT - 1)
    +		desc->sge_flags |= htole32(RING_END);
    +	desc->sge_cmdsts = htole32(RDC_OWN | RDC_INTR | RDC_IP_CSUM |
    +	    RDC_TCP_CSUM | RDC_UDP_CSUM);
    +}
    +
    +/*
    + * A frame has been uploaded: pass the resulting mbuf chain up to
    + * the higher level protocols.
    + */
    +static void
    +sge_rxeof(struct sge_softc *sc)
    +{
    +        struct ifnet *ifp;
    +        struct mbuf *m;
    +	struct sge_chain_data *cd;
    +	struct sge_desc	*cur_rx;
    +	uint32_t rxinfo, rxstat;
    +	int cons, prog;
    +
    +	SGE_LOCK_ASSERT(sc);
    +
    +	ifp = sc->sge_ifp;
    +	cd = &sc->sge_cdata;
    +
    +	bus_dmamap_sync(cd->sge_rx_tag, cd->sge_rx_dmamap,
    +	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
    +	cons = cd->sge_rx_cons;
    +	for (prog = 0; prog < SGE_RX_RING_CNT; prog++,
    +	    SGE_INC(cons, SGE_RX_RING_CNT)) {
    +		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
    +			break;
    +		cur_rx = &sc->sge_ldata.sge_rx_ring[cons];
    +		rxinfo = le32toh(cur_rx->sge_cmdsts);
    +		if ((rxinfo & RDC_OWN) != 0)
    +			break;
    +		rxstat = le32toh(cur_rx->sge_sts_size);
    +		if (SGE_RX_ERROR(rxstat) != 0 || SGE_RX_NSEGS(rxstat) != 1) {
    +			/* XXX We don't support multi-segment frames yet. */
    +#ifdef SGE_SHOW_ERRORS
    +			device_printf(sc->sge_dev, "Rx error : 0x%b\n", rxstat,
    +			    RX_ERR_BITS);
    +#endif
    +			sge_discard_rxbuf(sc, cons);
    +			ifp->if_ierrors++;
    +			continue;
    +		}
    +		m = cd->sge_rx_mbuf[cons];
    +		if (sge_newbuf(sc, cons) != 0) {
    +			sge_discard_rxbuf(sc, cons);
    +			ifp->if_iqdrops++;
    +			continue;
    +		}
    +		if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) {
    +			if ((rxinfo & RDC_IP_CSUM) != 0 &&
    +			    (rxinfo & RDC_IP_CSUM_OK) != 0)
    +				m->m_pkthdr.csum_flags |=
    +				    CSUM_IP_CHECKED | CSUM_IP_VALID;
    +			if (((rxinfo & RDC_TCP_CSUM) != 0 &&
    +			    (rxinfo & RDC_TCP_CSUM_OK) != 0) ||
    +			    ((rxinfo & RDC_UDP_CSUM) != 0 &&
    +			    (rxinfo & RDC_UDP_CSUM_OK) != 0)) {
    +				m->m_pkthdr.csum_flags |=
    +				    CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
    +				m->m_pkthdr.csum_data = 0xffff;
    +			}
    +		}
    +		/*
    +		 * TODO : VLAN hardware tag stripping.
    +		 */
    +		m->m_pkthdr.len = m->m_len =
    +		    SGE_RX_BYTES(rxstat) - ETHER_CRC_LEN;
    +#ifndef __NO_STRICT_ALIGNMENT
    +		sge_fixup_rx(m);
    +#endif
    +		m->m_pkthdr.rcvif = ifp;
    +		ifp->if_ipackets++;
    +		SGE_UNLOCK(sc);
    +		(*ifp->if_input)(ifp, m);
    +		SGE_LOCK(sc);
    +	}
    +
    +	if (prog > 0) {
    +		bus_dmamap_sync(cd->sge_rx_tag, cd->sge_rx_dmamap,
    +		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    +		cd->sge_rx_cons = cons;
    +	}
    +}
    +
    +/*
    + * A frame was downloaded to the chip.  It's safe for us to clean up
    + * the list buffers.
    + */
    +static void
    +sge_txeof(struct sge_softc *sc)
    +{
    +	struct ifnet *ifp;
    +	struct sge_list_data *ld;
    +	struct sge_chain_data *cd;
    +	uint32_t txstat;
    +	int cons, prod;
    +
    +	SGE_LOCK_ASSERT(sc);
    +
    +	ifp = sc->sge_ifp;
    +	ld = &sc->sge_ldata;
    +	cd = &sc->sge_cdata;
    +
    +	if (cd->sge_tx_cnt == 0)
    +		return;
    +	bus_dmamap_sync(cd->sge_tx_tag, cd->sge_tx_dmamap,
    +	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
    +	cons = cd->sge_tx_cons;
    +	prod = cd->sge_tx_prod;
    +	for (; cons != prod; SGE_INC(cons, SGE_TX_RING_CNT)) {
    +		txstat = le32toh(ld->sge_tx_ring[cons].sge_cmdsts);
    +		if ((txstat & TDC_OWN) != 0)
    +			break;
    +		cd->sge_tx_cnt--;
    +		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
    +		if (cd->sge_tx_mbuf[cons] != NULL) {
    +			bus_dmamap_sync(cd->sge_txmbuf_tag,
    +			    cd->sge_tx_map[cons], BUS_DMASYNC_POSTWRITE);
    +			bus_dmamap_unload(cd->sge_txmbuf_tag,
    +			    cd->sge_tx_map[cons]);
    +			m_freem(cd->sge_tx_mbuf[cons]);
    +			cd->sge_tx_mbuf[cons] = NULL;
    +			if (SGE_TX_ERROR(txstat) != 0) {
    +#ifdef SGE_SHOW_ERRORS
    +				device_printf(sc->sge_dev, "Tx error : 0x%b\n",
    +				    txstat, TX_ERR_BITS);
    +#endif
    +				ifp->if_oerrors++;
    +			} else {
    +#ifdef notyet
    +				ifp->if_collisions += (txstat & 0xFFFF) - 1;
    +#endif
    +				ifp->if_opackets++;
    +			}
    +		}
    +
    +	}
    +	cd->sge_tx_cons = cons;
    +	if (cd->sge_tx_cnt == 0)
    +		sc->sge_timer = 0;
    +}
    +
    +static void
    +sge_tick(void *arg)
    +{
    +	struct sge_softc *sc;
    +	struct mii_data *mii;
    +	struct ifnet *ifp;
    +
    +	sc = arg;
    +	SGE_LOCK_ASSERT(sc);
    +
    +	ifp = sc->sge_ifp;
    +	mii = device_get_softc(sc->sge_miibus);
    +	mii_tick(mii);
    +	if ((sc->sge_flags & SGE_FLAG_LINK) == 0) {
    +		sge_miibus_statchg(sc->sge_dev);
    +		if ((sc->sge_flags & SGE_FLAG_LINK) != 0 &&
    +		    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
    +			sge_start_locked(ifp);
    +	}
    +	/*
    +	 * Reclaim transmitted frames here as we do not request
    +	 * Tx completion interrupt for every queued frames to
    +	 * reduce excessive interrupts.
    +	 */
    +	sge_txeof(sc);
    +	sge_watchdog(sc);
    +	callout_reset(&sc->sge_stat_ch, hz, sge_tick, sc);
    +}
    +
    +static void
    +sge_intr(void *arg)
    +{
    +	struct sge_softc *sc;
    +	struct ifnet *ifp;
    +	uint32_t status;
    +
    +	sc = arg;
    +	SGE_LOCK(sc);
    +	ifp = sc->sge_ifp;
    +
    +	status = CSR_READ_4(sc, IntrStatus);
    +	if (status == 0xFFFFFFFF || (status & SGE_INTRS) == 0) {
    +		/* Not ours. */
    +		SGE_UNLOCK(sc);
    +		return;
    +	}
    +	/* Acknowledge interrupts. */
    +	CSR_WRITE_4(sc, IntrStatus, status);
    +	/* Disable further interrupts. */
    +	CSR_WRITE_4(sc, IntrMask, 0);
    +	/*
    +	 * It seems the controller supports some kind of interrupt
    +	 * moderation mechanism but we still don't know how to
    +	 * enable that.  To reduce number of generated interrupts
    +	 * under load we check pending interrupts in a loop.  This
    +	 * will increase number of register access and is not correct
    +	 * way to handle interrupt moderation but there seems to be
    +	 * no other way at this time.
    +	 */
    +	for (;;) {
    +		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
    +			break;
    +		if ((status & (INTR_RX_DONE | INTR_RX_IDLE)) != 0) {
    +			sge_rxeof(sc);
    +			/* Wakeup Rx MAC. */
    +			if ((status & INTR_RX_IDLE) != 0)
    +				CSR_WRITE_4(sc, RX_CTL,
    +				    0x1a00 | 0x000c | RX_CTL_POLL | RX_CTL_ENB);
    +		}
    +		if ((status & (INTR_TX_DONE | INTR_TX_IDLE)) != 0)
    +			sge_txeof(sc);
    +		status = CSR_READ_4(sc, IntrStatus);
    +		if ((status & SGE_INTRS) == 0)
    +			break;
    +		/* Acknowledge interrupts. */
    +		CSR_WRITE_4(sc, IntrStatus, status);
    +	}
    +	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
    +		/* Re-enable interrupts */
    +		CSR_WRITE_4(sc, IntrMask, SGE_INTRS);
    +		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
    +			sge_start_locked(ifp);
    +	}
    +	SGE_UNLOCK(sc);
    +}
    +
    +/*
    + * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
    + * pointers to the fragment pointers.
    + */
    +static int
    +sge_encap(struct sge_softc *sc, struct mbuf **m_head)
    +{
    +	struct mbuf *m;
    +	struct sge_desc *desc;
    +	bus_dma_segment_t txsegs[SGE_MAXTXSEGS];
    +	bus_dmamap_t map;
    +	uint32_t cflags;
    +	int error, nsegs, prod;
    +
    +	SGE_LOCK_ASSERT(sc);
    +
    +	prod = sc->sge_cdata.sge_tx_prod;
    +	map = sc->sge_cdata.sge_tx_map[prod];
    +	/*
    +	 * Reading Windows inf file indicates SiS controller supports
    +	 * TSO, VLAN hardware tag insertion/stripping, interrupt
    +	 * moderation and Tx/Rx checksum offloading.  Unfortunately
    +	 * vendor didn't release these information so we're guessing
    +	 * descriptor usage with trial and errors.
    +	 *
    +	 * Controller seems to support multi-fragmented buffers but
    +	 * don't know how to enable that feature so limit number of
    +	 * fragmented Tx buffers to single buffer until we understand
    +	 * the controller internals.
    +	 * I assume the controller can pad zero bytes if frame length
    +	 * is less than 60 bytes and I also think the controller has
    +	 * no Tx buffer alignment limitation. - Need testing!
    +	 */
    +	if ((*m_head)->m_next != NULL) {
    +		m = m_defrag(*m_head, M_DONTWAIT);
    +		if (m == NULL) {
    +			m_freem(*m_head);
    +			*m_head = NULL;
    +			return (ENOBUFS);
    +		}
    +		*m_head = m;
    +	}
    +	error = bus_dmamap_load_mbuf_sg(sc->sge_cdata.sge_tx_tag, map,
    +	    *m_head, txsegs, &nsegs, 0);
    +	if (error != 0) {
    +		m_freem(*m_head);
    +		*m_head = NULL;
    +		return (error);
    +	}
    +	/* Check descriptor overrun. */
    +	if (sc->sge_cdata.sge_tx_cnt + nsegs >= SGE_TX_RING_CNT) {
    +		bus_dmamap_unload(sc->sge_cdata.sge_tx_tag, map);
    +		return (ENOBUFS);
    +	}
    +	bus_dmamap_sync(sc->sge_cdata.sge_tx_tag, map, BUS_DMASYNC_PREWRITE);
    +
    +	cflags = 0;
    +	if ((*m_head)->m_pkthdr.csum_flags & CSUM_IP)
    +		cflags |= TDC_IP_CSUM;
    +	if ((*m_head)->m_pkthdr.csum_flags & CSUM_TCP)
    +		cflags |= TDC_TCP_CSUM;
    +	if ((*m_head)->m_pkthdr.csum_flags & CSUM_UDP)
    +		cflags |= TDC_UDP_CSUM;
    +	desc = &sc->sge_ldata.sge_tx_ring[prod];
    +	desc->sge_sts_size = htole32((*m_head)->m_pkthdr.len);
    +	desc->sge_ptr = htole32(SGE_ADDR_LO(txsegs[0].ds_addr));
    +	desc->sge_flags = htole32(txsegs[0].ds_len);
    +	if (prod == SGE_TX_RING_CNT - 1)
    +		desc->sge_flags |= htole32(RING_END);
    +	desc->sge_cmdsts = htole32(TDC_DEF | TDC_CRC | TDC_PAD | cflags);
    +#if 1
    +	if ((sc->sge_flags & SGE_FLAG_SPEED_1000) != 0)
    +		desc->sge_cmdsts |= htole32(TDC_BST);
    +#else
    +	if ((sc->sge_flags & SGE_FLAG_FDX) == 0) {
    +		desc->sge_cmdsts |= htole32(TDC_COL | TDC_CRS | TDC_BKF);
    +		if ((sc->sge_flags & SGE_FLAG_SPEED_1000) != 0)
    +			desc->sge_cmdsts |= htole32(TDC_EXT | TDC_BST);
    +	}
    +#endif
    +	/* Request interrupt and give ownership to controller. */
    +	if ((prod % SGE_TX_INTR_FRAMES) == 0)
    +		desc->sge_cmdsts |= htole32(TDC_OWN | TDC_INTR);
    +	else
    +		desc->sge_cmdsts |= htole32(TDC_OWN);
    +	sc->sge_cdata.sge_tx_mbuf[prod] = *m_head;
    +	sc->sge_cdata.sge_tx_cnt++;
    +	SGE_INC(sc->sge_cdata.sge_tx_prod, SGE_TX_RING_CNT);
    +	return (0);
    +}
    +
    +static void
    +sge_start(struct ifnet *ifp)
    +{
    +	struct sge_softc *sc;
    +
    +	sc = ifp->if_softc;
    +	SGE_LOCK(sc);
    +	sge_start_locked(ifp);
    +	SGE_UNLOCK(sc);
    +}
    +
    +static void
    +sge_start_locked(struct ifnet *ifp)
    +{
    +	struct sge_softc *sc;
    +	struct mbuf *m_head;
    +	int queued = 0;
    +
    +	sc = ifp->if_softc;
    +	SGE_LOCK_ASSERT(sc);
    +
    +	if ((sc->sge_flags & SGE_FLAG_LINK) == 0 ||
    +	    (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
    +	    IFF_DRV_RUNNING)
    +		return;
    +
    +	for (queued = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
    +		if (sc->sge_cdata.sge_tx_cnt == SGE_TX_RING_CNT - 1) {
    +			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +			break;
    +		}
    +		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
    +		if (m_head == NULL)
    +			break;
    +		if (sge_encap(sc, &m_head)) {
    +			IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
    +			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    +			break;
    +		}
    +		queued++;
    +		/*
    +		 * If there's a BPF listener, bounce a copy of this frame
    +		 * to him.
    +		 */
    +		BPF_MTAP(ifp, m_head);
    +	}
    +
    +	if (queued > 0) {
    +		bus_dmamap_sync(sc->sge_cdata.sge_tx_tag,
    +		    sc->sge_cdata.sge_tx_dmamap,
    +		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    +		CSR_WRITE_4(sc, TX_CTL, 0x1a00 | TX_CTL_ENB | TX_CTL_POLL);
    +		sc->sge_timer = 5;
    +	}
    +}
    +
    +static void
    +sge_init(void *arg)
    +{
    +	struct sge_softc *sc;
    +
    +	sc = arg;
    +	SGE_LOCK(sc);
    +	sge_init_locked(sc);
    +	SGE_UNLOCK(sc);
    +}
    +
    +static void
    +sge_init_locked(struct sge_softc *sc)
    +{
    +	struct ifnet *ifp;
    +	struct mii_data *mii;
    +	int i;
    +
    +	SGE_LOCK_ASSERT(sc);
    +	ifp = sc->sge_ifp;
    +	mii = device_get_softc(sc->sge_miibus);
    +	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
    +		return;
    +	/*
    +	 * Cancel pending I/O and free all RX/TX buffers.
    +	 */
    +	sge_stop(sc);
    +	sge_reset(sc);
    +
    +	/* Init circular RX list. */
    +	if (sge_list_rx_init(sc) == ENOBUFS) {
    +		device_printf(sc->sge_dev, "no memory for Rx buffers\n");
    +		sge_stop(sc);
    +		return;
    +	}
    +	/* Init TX descriptors. */
    +	sge_list_tx_init(sc);
    +	/*
    +	 * Load the address of the RX and TX lists.
    +	 */
    +	CSR_WRITE_4(sc, TX_DESC, SGE_ADDR_LO(sc->sge_ldata.sge_tx_paddr));
    +	CSR_WRITE_4(sc, RX_DESC, SGE_ADDR_LO(sc->sge_ldata.sge_rx_paddr));
    +
    +	CSR_WRITE_4(sc, TxMacControl, 0x60);
    +	CSR_WRITE_4(sc, 0x6c, 0);
    +	CSR_WRITE_4(sc, RxWakeOnLan, 0);
    +	CSR_WRITE_4(sc, RxWakeOnLanData, 0);
    +	/* Allow receiving VLAN frames. */
    +	CSR_WRITE_2(sc, RxMPSControl, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
    +
    +	for (i = 0; i < ETHER_ADDR_LEN; i++)
    +		CSR_WRITE_1(sc, RxMacAddr + i, IF_LLADDR(ifp)[i]);
    +	sge_rxfilter(sc);
    +
    +	/* Initialize default speed/duplex information. */
    +	if ((sc->sge_flags & SGE_FLAG_FASTETHER) == 0)
    +		sc->sge_flags |= SGE_FLAG_SPEED_1000;
    +	sc->sge_flags |= SGE_FLAG_FDX;
    +	if ((sc->sge_flags & SGE_FLAG_RGMII) != 0)
    +		CSR_WRITE_4(sc, StationControl, 0x04008001);
    +	else
    +		CSR_WRITE_4(sc, StationControl, 0x04000001);
    +	/*
    +	 * XXX Try to mitigate interrupts.
    +	 */
    +	if (sc->sge_intrcontrol != 0)
    +		CSR_WRITE_4(sc, IntrControl, sc->sge_intrcontrol);
    +	if (sc->sge_intrtimer != 0)
    +		CSR_WRITE_4(sc, IntrTimer, sc->sge_intrtimer);
    +
    +	/*
    +	 * Clear and enable interrupts.
    +	 */
    +	CSR_WRITE_4(sc, IntrStatus, 0xFFFFFFFF);
    +	CSR_WRITE_4(sc, IntrMask, SGE_INTRS);
    +
    +	/* Enable receiver and transmitter. */
    +	CSR_WRITE_4(sc, TX_CTL, 0x1a00 | TX_CTL_ENB);
    +	CSR_WRITE_4(sc, RX_CTL, 0x1a00 | 0x000c | RX_CTL_POLL | RX_CTL_ENB);
    +
    +	ifp->if_drv_flags |= IFF_DRV_RUNNING;
    +	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
    +
    +	sc->sge_flags &= ~SGE_FLAG_LINK;
    +	mii_mediachg(mii);
    +	callout_reset(&sc->sge_stat_ch, hz, sge_tick, sc);
    +}
    +
    +/*
    + * Set media options.
    + */
    +static int
    +sge_ifmedia_upd(struct ifnet *ifp)
    +{
    +	struct sge_softc *sc;
    +	struct mii_data *mii;
    +	int error;
    +
    +	sc = ifp->if_softc;
    +	SGE_LOCK(sc);
    +	mii = device_get_softc(sc->sge_miibus);
    +	sc->sge_flags &= ~SGE_FLAG_LINK;
    +	if (mii->mii_instance) {
    +		struct mii_softc *miisc;
    +		LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
    +			mii_phy_reset(miisc);
    +	}
    +	error = mii_mediachg(mii);
    +	SGE_UNLOCK(sc);
    +
    +	return (error);
    +}
    +
    +/*
    + * Report current media status.
    + */
    +static void
    +sge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
    +{
    +	struct sge_softc *sc;
    +	struct mii_data *mii;
    +
    +	sc = ifp->if_softc;
    +	SGE_LOCK(sc);
    +	mii = device_get_softc(sc->sge_miibus);
    +	if ((ifp->if_flags & IFF_UP) == 0) {
    +		SGE_UNLOCK(sc);
    +		return;
    +	}
    +	mii_pollstat(mii);
    +	SGE_UNLOCK(sc);
    +	ifmr->ifm_active = mii->mii_media_active;
    +	ifmr->ifm_status = mii->mii_media_status;
    +}
    +
    +static int
    +sge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
    +{
    +	struct sge_softc *sc;
    +	struct ifreq *ifr;
    +	struct mii_data *mii;
    +	int error = 0, mask;
    +
    +	sc = ifp->if_softc;
    +	ifr = (struct ifreq *)data;
    +
    +	switch(command) {
    +	case SIOCSIFFLAGS:
    +		SGE_LOCK(sc);
    +		if ((ifp->if_flags & IFF_UP) != 0) {
    +			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
    +			    ((ifp->if_flags ^ sc->sge_if_flags) &
    +			    (IFF_PROMISC | IFF_ALLMULTI)) != 0)
    +				sge_rxfilter(sc);
    +			else
    +				sge_init_locked(sc);
    +		} else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
    +			sge_stop(sc);
    +		sc->sge_if_flags = ifp->if_flags;
    +		SGE_UNLOCK(sc);
    +		break;
    +	case SIOCSIFCAP:
    +		SGE_LOCK(sc);
    +		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
    +		if ((mask & IFCAP_TXCSUM) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_TXCSUM) != 0) {
    +			ifp->if_capenable ^= IFCAP_TXCSUM;
    +			if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
    +				ifp->if_hwassist |= SGE_CSUM_FEATURES;
    +			else
    +				ifp->if_hwassist &= ~SGE_CSUM_FEATURES;
    +		}
    +		if ((mask & IFCAP_RXCSUM) != 0 &&
    +		    (ifp->if_capabilities & IFCAP_RXCSUM) != 0)
    +			ifp->if_capenable ^= IFCAP_RXCSUM;
    +		SGE_UNLOCK(sc);
    +		break;
    +	case SIOCADDMULTI:
    +	case SIOCDELMULTI:
    +		SGE_LOCK(sc);
    +		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
    +			sge_rxfilter(sc);
    +		SGE_UNLOCK(sc);
    +		break;
    +	case SIOCGIFMEDIA:
    +	case SIOCSIFMEDIA:
    +		mii = device_get_softc(sc->sge_miibus);
    +		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
    +		break;
    +	default:
    +		error = ether_ioctl(ifp, command, data);
    +		break;
    +	}
    +
    +	return (error);
    +}
    +
    +static void
    +sge_watchdog(struct sge_softc *sc)
    +{
    +	struct ifnet *ifp;
    +
    +	SGE_LOCK_ASSERT(sc);
    +	if (sc->sge_timer == 0 || --sc->sge_timer > 0)
    +		return;
    +
    +	ifp = sc->sge_ifp;
    +	if ((sc->sge_flags & SGE_FLAG_LINK) == 0) {
    +		if (1 || bootverbose)
    +			device_printf(sc->sge_dev,
    +			    "watchdog timeout (lost link)\n");
    +		ifp->if_oerrors++;
    +		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
    +		sge_init_locked(sc);
    +		return;
    +	}
    +	device_printf(sc->sge_dev, "watchdog timeout\n");
    +	ifp->if_oerrors++;
    +
    +	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
    +	sge_init_locked(sc);
    +	if (!IFQ_DRV_IS_EMPTY(&sc->sge_ifp->if_snd))
    +		sge_start_locked(ifp);
    +}
    +
    +/*
    + * Stop the adapter and free any mbufs allocated to the
    + * RX and TX lists.
    + */
    +static void
    +sge_stop(struct sge_softc *sc)
    +{
    +	struct ifnet *ifp;
    +
    +	ifp = sc->sge_ifp;
    +
    +	SGE_LOCK_ASSERT(sc);
    +
    +	sc->sge_timer = 0;
    +	callout_stop(&sc->sge_stat_ch);
    +	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
    +
    +	CSR_WRITE_4(sc, IntrMask, 0);
    +	CSR_READ_4(sc, IntrMask);
    +	CSR_WRITE_4(sc, IntrStatus, 0xffffffff);
    +	/* Stop TX/RX MAC. */
    +	CSR_WRITE_4(sc, TX_CTL, 0x1a00);
    +	CSR_WRITE_4(sc, RX_CTL, 0x1a00);
    +	/* XXX Can we assume active DMA cycles gone? */
    +	DELAY(2000);
    +	CSR_WRITE_4(sc, IntrMask, 0);
    +	CSR_WRITE_4(sc, IntrStatus, 0xffffffff);
    +
    +	sc->sge_flags &= ~SGE_FLAG_LINK;
    +	sge_list_rx_free(sc);
    +	sge_list_tx_free(sc);
    +}
    diff --git a/sys/dev/sge/if_sgereg.h b/sys/dev/sge/if_sgereg.h
    new file mode 100644
    index 00000000000..29253e0f892
    --- /dev/null
    +++ b/sys/dev/sge/if_sgereg.h
    @@ -0,0 +1,350 @@
    +/*-
    + * Copyright (c) 2008, 2009, 2010 Nikolay Denev 
    + * Copyright (c) 2007, 2008 Alexander Pohoyda 
    + * Copyright (c) 1997, 1998, 1999
    + *      Bill Paul .  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.
    + * 3. All advertising materials mentioning features or use of this software
    + *    must display the following acknowledgement:
    + *      This product includes software developed by Bill Paul.
    + * 4. Neither the name of the author nor the names of any co-contributors
    + *    may be used to endorse or promote products derived from this software
    + *    without specific prior written permission.
    + *
    + * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 AUTHORS OR
    + * THE VOICES IN THEIR HEADS 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 _IF_SGEREG_H
    +#define	_IF_SGEREG_H
    +
    +/*
    + * SiS PCI vendor ID.
    + */
    +#define	SIS_VENDORID		0x1039
    +
    +/*
    + * SiS PCI device IDs
    + */
    +#define	SIS_DEVICEID_190	0x0190
    +#define	SIS_DEVICEID_191	0x0191
    +
    +#define	TX_CTL			0x00
    +#define	TX_DESC			0x04
    +#define	Reserved0		0x08
    +#define	TX_NEXT			0x0c
    +
    +#define	RX_CTL			0x10
    +#define	RX_DESC			0x14
    +#define	Reserved1		0x18
    +#define	RX_NEXT			0x1c
    +
    +#define	IntrStatus		0x20
    +#define	IntrMask		0x24
    +#define	IntrControl		0x28
    +#define	IntrTimer		0x2c
    +
    +#define	PMControl		0x30
    +#define	Reserved2		0x34
    +#define	ROMControl		0x38
    +#define	ROMInterface		0x3c
    +#define	StationControl		0x40
    +#define	GMIIControl		0x44
    +#define	GMacIOCR		0x48
    +#define	GMacIOCTL		0x4c
    +#define	TxMacControl		0x50
    +#define	TxMacTimeLimit		0x54
    +#define	RGMIIDelay		0x58
    +#define	Reserved3		0x5c
    +#define	RxMacControl		0x60	/* 1  WORD */
    +#define	RxMacAddr		0x62	/* 6x BYTE */
    +#define	RxHashTable		0x68	/* 1 LONG */
    +#define	RxHashTable2		0x6c	/* 1 LONG */
    +#define	RxWakeOnLan		0x70
    +#define	RxWakeOnLanData		0x74
    +#define	RxMPSControl		0x78
    +#define	Reserved4		0x7c
    +
    +/*
    + * IntrStatus Register Content
    + */
    +#define	INTR_SOFT		0x40000000
    +#define	INTR_TIMER		0x20000000
    +#define	INTR_PAUSE_FRAME	0x00080000
    +#define	INTR_MAGIC_FRAME	0x00040000
    +#define	INTR_WAKE_FRAME		0x00020000
    +#define	INTR_LINK		0x00010000
    +#define	INTR_RX_IDLE		0x00000080	
    +#define	INTR_RX_DONE		0x00000040
    +#define	INTR_TXQ1_IDLE		0x00000020
    +#define	INTR_TXQ1_DONE		0x00000010
    +#define	INTR_TX_IDLE		0x00000008
    +#define	INTR_TX_DONE		0x00000004
    +#define	INTR_RX_HALT		0x00000002
    +#define	INTR_TX_HALT		0x00000001
    +
    +#define	SGE_INTRS							\
    +	(INTR_RX_IDLE | INTR_RX_DONE | INTR_TXQ1_IDLE |			\
    +	 INTR_TXQ1_DONE |INTR_TX_IDLE | INTR_TX_DONE |			\
    +	 INTR_TX_HALT | INTR_RX_HALT)
    +
    +/*
    + * RxStatusDesc Register Content
    + */
    +#define	RxRES			0x00200000
    +#define	RxCRC			0x00080000
    +#define	RxRUNT			0x00100000
    +#define	RxRWT			0x00400000
    +
    +/*
    + * RX_CTL Register Content
    + */
    +#define	RX_CTL_POLL		0x00000010
    +#define	RX_CTL_ENB		0x00000001
    +
    +/*
    + * TX_CTL Register Content
    + */
    +#define	TX_CTL_POLL		0x00000010
    +#define	TX_CTL_ENB		0x00000001
    +
    +/*
    + * RxMacControl Register Content
    + */
    +#define	AcceptBroadcast		0x0800
    +#define	AcceptMulticast		0x0400
    +#define	AcceptMyPhys		0x0200
    +#define	AcceptAllPhys		0x0100
    +#define	AcceptErr		0x0020
    +#define	AcceptRunt		0x0010
    +
    +/* Station control register. */
    +#define	SC_LOOPBACK		0x80000000
    +#define	SC_RGMII		0x00008000
    +#define	SC_FDX			0x00001000
    +#define	SC_SPEED_MASK		0x00000c00
    +#define	SC_SPEED_10		0x00000400
    +#define	SC_SPEED_100		0x00000800
    +#define	SC_SPEED_1000		0x00000c00
    +
    +/*
    + * Gigabit Media Independent Interface CTL register
    + */
    +#define	GMI_DATA		0xffff0000
    +#define	GMI_DATA_SHIFT		16
    +#define	GMI_REG			0x0000f800
    +#define	GMI_REG_SHIFT		11
    +#define	GMI_PHY			0x000007c0
    +#define	GMI_PHY_SHIFT		6
    +#define	GMI_OP_WR		0x00000020
    +#define	GMI_OP_RD		0x00000000
    +#define	GMI_REQ			0x00000010
    +#define	GMI_MDIO		0x00000008
    +#define	GMI_MDDIR		0x00000004
    +#define	GMI_MDC			0x00000002
    +#define	GMI_MDEN		0x00000001
    +
    +/* Tx descriptor command bits. */
    +#define	TDC_OWN			0x80000000
    +#define	TDC_INTR		0x40000000
    +#define	TDC_THOL3		0x30000000
    +#define	TDC_THOL2		0x20000000
    +#define	TDC_THOL1		0x10000000
    +#define	TDC_THOL0		0x00000000
    +#define	TDC_LS			0x08000000
    +#define	TDC_IP_CSUM		0x04000000
    +#define	TDC_TCP_CSUM		0x02000000
    +#define	TDC_UDP_CSUM		0x01000000
    +#define	TDC_BST			0x00800000
    +#define	TDC_EXT			0x00400000
    +#define	TDC_DEF			0x00200000
    +#define	TDC_BKF			0x00100000
    +#define	TDC_CRS			0x00080000
    +#define	TDC_COL			0x00040000
    +#define	TDC_CRC			0x00020000
    +#define	TDC_PAD			0x00010000
    +
    +#define	SGE_TX_INTR_FRAMES	32
    +
    +/*
    + * TX descriptor status bits.
    + */
    +#define	TDS_OWC			0x00080000
    +#define	TDS_ABT			0x00040000
    +#define	TDS_FIFO		0x00020000
    +#define	TDS_CRS			0x00010000
    +#define	TDS_COLLS		0x0000ffff
    +#define	SGE_TX_ERROR(x)		((x) & (TDS_OWC | TDS_ABT | TDS_FIFO | TDS_CRS))
    +#define	TX_ERR_BITS		"\20"				\
    +				"\21CRS\22FIFO\23ABT\24OWC"
    +
    +/* Rx descriptor command bits. */
    +#define	RDC_OWN			0x80000000
    +#define	RDC_INTR		0x40000000
    +#define	RDC_IP_CSUM		0x20000000
    +#define	RDC_TCP_CSUM		0x10000000
    +#define	RDC_UDP_CSUM		0x08000000
    +#define	RDC_IP_CSUM_OK		0x04000000
    +#define	RDC_TCP_CSUM_OK		0x02000000
    +#define	RDC_UDP_CSUM_OK		0x01000000
    +#define	RDC_WAKEUP		0x00400000
    +#define	RDC_MAGIC		0x00200000
    +#define	RDC_PAUSE		0x00100000
    +#define	RDC_BCAST		0x000c0000
    +#define	RDC_MCAST		0x00080000
    +#define	RDC_UCAST		0x00040000
    +#define	RDC_CRCOFF		0x00020000
    +#define	RDC_PREADD		0x00010000
    +
    +/*
    + * RX descriptor status bits
    + */
    +#define	RDS_TAGON		0x80000000
    +#define	RDS_DESCS		0x3f000000
    +#define	RDS_ABORT		0x00800000
    +#define	RDS_SHORT		0x00400000
    +#define	RDS_LIMIT		0x00200000
    +#define	RDS_MIIER		0x00100000
    +#define	RDS_OVRUN		0x00080000
    +#define	RDS_NIBON		0x00040000
    +#define	RDS_COLON		0x00020000
    +#define	RDS_CRCOK		0x00010000
    +#define	SGE_RX_ERROR(x)							\
    +        ((x) & (RDS_COLON | RDS_NIBON | RDS_OVRUN | RDS_MIIER |		\
    +	RDS_LIMIT | RDS_SHORT | RDS_ABORT))
    +#define	SGE_RX_NSEGS(x)		(((x) & RDS_DESCS) >> 24)
    +#define	RX_ERR_BITS 		"\20"					\
    +				"\21CRCOK\22COLON\23NIBON\24OVRUN"	\
    +				"\25MIIER\26LIMIT\27SHORT\30ABORT"	\
    +				"\40TAGON"
    +
    +#define	RING_END		0x80000000
    +#define	SGE_RX_BYTES(x)		((x) & 0xFFFF)
    +#define	SGE_INC(x, y)		(x) = (((x) + 1) % y)
    +
    +/* Taken from Solaris driver */
    +#define	EI_DATA			0xffff0000
    +#define	EI_DATA_SHIFT		16
    +#define	EI_OFFSET		0x0000fc00
    +#define	EI_OFFSET_SHIFT		10
    +#define	EI_OP			0x00000300
    +#define	EI_OP_SHIFT		8
    +#define	EI_OP_RD		(2 << EI_OP_SHIFT)
    +#define	EI_OP_WR		(1 << EI_OP_SHIFT)
    +#define	EI_REQ			0x00000080
    +#define	EI_DO			0x00000008
    +#define	EI_DI			0x00000004
    +#define	EI_CLK			0x00000002
    +#define	EI_CS			0x00000001
    +
    +/*
    + * EEPROM Addresses
    + */
    +#define	EEPROMSignature		0x00
    +#define	EEPROMCLK		0x01
    +#define	EEPROMInfo		0x02
    +#define	EEPROMMACAddr		0x03
    +
    +struct sge_desc {
    +	uint32_t	sge_sts_size;
    +	uint32_t	sge_cmdsts;
    +	uint32_t	sge_ptr;
    +	uint32_t	sge_flags;
    +};
    +
    +#define	SGE_RX_RING_CNT		256 /* [8, 1024] */
    +#define	SGE_TX_RING_CNT		256 /* [8, 8192] */
    +#define	SGE_DESC_ALIGN		16
    +#define	SGE_MAXTXSEGS		1
    +#define	SGE_RX_BUF_ALIGN	sizeof(uint64_t)
    +
    +#define	SGE_RX_RING_SZ		(SGE_RX_RING_CNT * sizeof(struct sge_desc))
    +#define	SGE_TX_RING_SZ		(SGE_TX_RING_CNT * sizeof(struct sge_desc))
    +#define	SGE_ADDR_LO(x)		((uint64_t) (x) & 0xFFFFFFFF)
    +
    +struct sge_list_data {
    +	struct sge_desc		*sge_rx_ring;
    +	struct sge_desc		*sge_tx_ring;
    +	/* physical bus addresses of sge_rx_ring/sge_tx_ring */
    +	bus_addr_t		sge_rx_paddr;
    +	bus_addr_t		sge_tx_paddr;
    +};
    +
    +struct sge_chain_data {
    +	bus_dma_tag_t		sge_tag;
    +	bus_dma_tag_t		sge_rx_tag;
    +	bus_dma_tag_t		sge_tx_tag;
    +	bus_dmamap_t		sge_rx_dmamap;
    +	bus_dmamap_t		sge_tx_dmamap;
    +	bus_dma_tag_t		sge_txmbuf_tag;
    +	bus_dma_tag_t		sge_rxmbuf_tag;
    +	struct mbuf		*sge_rx_mbuf[SGE_RX_RING_CNT];
    +	struct mbuf		*sge_tx_mbuf[SGE_TX_RING_CNT];
    +	bus_dmamap_t		sge_rx_map[SGE_RX_RING_CNT];
    +	bus_dmamap_t		sge_rx_spare_map;
    +	bus_dmamap_t		sge_tx_map[SGE_TX_RING_CNT];
    +	int			sge_rx_cons;
    +	int			sge_tx_prod;
    +	int			sge_tx_cons;
    +	int			sge_tx_cnt;
    +};
    +
    +struct sge_type {
    +	uint16_t		sge_vid;
    +	uint16_t		sge_did;
    +	char			*sge_name;
    +};
    +
    +struct sge_softc {
    +	struct ifnet		*sge_ifp;	/* interface info */
    +	struct resource		*sge_res;
    +	int			sge_res_id;
    +	int			sge_res_type;
    +	struct resource		*sge_irq;
    +	void			*sge_intrhand;
    +	device_t		sge_dev;
    +	device_t		sge_miibus;
    +	uint8_t			sge_rev;
    +	struct sge_list_data	sge_ldata;
    +	struct sge_chain_data	sge_cdata;
    +	struct callout		sge_stat_ch;
    +	int			sge_timer;
    +	int			sge_flags;
    +#define	SGE_FLAG_FASTETHER	0x0001
    +#define	SGE_FLAG_RGMII		0x0010
    +#define	SGE_FLAG_SPEED_1000	0x2000
    +#define	SGE_FLAG_FDX		0x4000
    +#define	SGE_FLAG_LINK		0x8000
    +	int			sge_if_flags;
    +	int			sge_intrcontrol;
    +	int			sge_intrtimer;
    +	struct mtx		sge_mtx;
    +};
    +
    +#define	SGE_LOCK(_sc)		mtx_lock(&(_sc)->sge_mtx)
    +#define	SGE_UNLOCK(_sc)		mtx_unlock(&(_sc)->sge_mtx)
    +#define	SGE_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->sge_mtx, MA_OWNED)
    +
    +#define	SGE_TIMEOUT		1000
    +
    +#endif /* _IF_SGEREG_H */
    diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
    index f066958fa61..d9d36a84f5b 100644
    --- a/sys/i386/conf/GENERIC
    +++ b/sys/i386/conf/GENERIC
    @@ -235,6 +235,7 @@ device		pcn		# AMD Am79C97x PCI 10/100 (precedence over 'le')
     device		re		# RealTek 8139C+/8169/8169S/8110S
     device		rl		# RealTek 8129/8139
     device		sf		# Adaptec AIC-6915 (``Starfire'')
    +device		sge		# Silicon Integrated Systems SiS190/191
     device		sis		# Silicon Integrated Systems SiS 900/SiS 7016
     device		sk		# SysKonnect SK-984x & SK-982x gigabit Ethernet
     device		ste		# Sundance ST201 (D-Link DFE-550TX)
    diff --git a/sys/modules/Makefile b/sys/modules/Makefile
    index 8ae3b43d9ce..5c1ebb2819a 100644
    --- a/sys/modules/Makefile
    +++ b/sys/modules/Makefile
    @@ -249,6 +249,7 @@ SUBDIR=	${_3dfx} \
     	sdhci \
     	sem \
     	sf \
    +	sge \
     	siba_bwn \
     	siis \
     	sis \
    diff --git a/sys/modules/sge/Makefile b/sys/modules/sge/Makefile
    new file mode 100644
    index 00000000000..5f8c5879554
    --- /dev/null
    +++ b/sys/modules/sge/Makefile
    @@ -0,0 +1,8 @@
    +# $FreeBSD$
    +
    +.PATH: ${.CURDIR}/../../dev/sge
    +
    +KMOD=	if_sge
    +SRCS=	if_sge.c device_if.h bus_if.h pci_if.h miibus_if.h
    +
    +.include 
    
    From 435d7f8d85a05ea5a9ae7017e600ffe1c2200858 Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Mon, 26 Apr 2010 17:24:10 +0000
    Subject: [PATCH 2115/2592] MFC r198443 (by antoine):
    
    Add more obsolete man pages.
    
    Requested by:	Alex Kozlov
    Ok'ed by:	antoine
    ---
     ObsoleteFiles.inc | 46 ++++++++++++++++++++++++++++++++++++++++++++++
     1 file changed, 46 insertions(+)
    
    diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
    index 6dd8e2e6803..779b00eed48 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.
     #
     
    +# 20100327: fusword.9 and susword.9 removed
    +OLD_FILES+=usr/share/man/man9/fusword.9.gz
    +OLD_FILES+=usr/share/man/man9/susword.9.gz
     # 20100408: unify rc.firewall and rc.firewall6.
     OLD_FILES+=etc/rc.d/ip6fw
     OLD_FILES+=etc/rc.firewall6
    @@ -63,6 +66,49 @@ OLD_FILES+=usr/libexec/lukemftpd
     OLD_FILES+=usr/share/man/man5/ftpd.conf.5.gz
     OLD_FILES+=usr/share/man/man5/ftpusers.5.gz
     OLD_FILES+=usr/share/man/man8/lukemftpd.8.gz
    +# 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 539c23b3a912b17da5be297ffb58dfea5b0eb03e Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Mon, 26 Apr 2010 17:27:08 +0000
    Subject: [PATCH 2116/2592] MFC r206628:   Add sge(4) to the list of supported
     network interface.
    
    ---
     usr.sbin/sysinstall/devices.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/usr.sbin/sysinstall/devices.c b/usr.sbin/sysinstall/devices.c
    index a2b7939f048..8cf1fb30c49 100644
    --- a/usr.sbin/sysinstall/devices.c
    +++ b/usr.sbin/sysinstall/devices.c
    @@ -150,6 +150,7 @@ static struct _devname {
         NETWORK("rue",	"RealTek USB Ethernet card"),
         NETWORK("rum",	"Ralink Technology USB IEEE 802.11 wireless adapter"),
         NETWORK("sf",	"Adaptec AIC-6915 PCI Ethernet card"),
    +    NETWORK("sge",	"Silicon Integrated Systems SiS190/191 Ethernet"),
         NETWORK("sis",	"SiS 900/SiS 7016 PCI Ethernet card"),
     #ifdef PC98
         NETWORK("snc",	"SONIC Ethernet card"),
    
    From b3fd506729f547f2afca646decc5294614609ae8 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Mon, 26 Apr 2010 17:30:41 +0000
    Subject: [PATCH 2117/2592] MFC r206631:   Add sge(4) man page and hook up
     sge(4) to the build.   Also add Xr to appropriate man pages.
    
    ---
     share/man/man4/Makefile |   1 +
     share/man/man4/altq.4   |   3 +-
     share/man/man4/miibus.4 |   5 +-
     share/man/man4/sge.4    | 120 ++++++++++++++++++++++++++++++++++++++++
     share/man/man4/vlan.4   |   3 +-
     5 files changed, 129 insertions(+), 3 deletions(-)
     create mode 100644 share/man/man4/sge.4
    
    diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
    index fc9b0fb17d9..de2d7c65d16 100644
    --- a/share/man/man4/Makefile
    +++ b/share/man/man4/Makefile
    @@ -342,6 +342,7 @@ MAN=	aac.4 \
     	sem.4 \
     	ses.4 \
     	sf.4 \
    +	sge.4 \
     	si.4 \
     	sio.4 \
     	siis.4 \
    diff --git a/share/man/man4/altq.4 b/share/man/man4/altq.4
    index 55fb8c1b0c9..ba3dafc84b4 100644
    --- a/share/man/man4/altq.4
    +++ b/share/man/man4/altq.4
    @@ -25,7 +25,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd July 26, 2009
    +.Dd April 14, 2010
     .Dt ALTQ 4
     .Os
     .Sh NAME
    @@ -151,6 +151,7 @@ They have been applied to the following hardware drivers:
     .Xr rl 4 ,
     .Xr rum 4 ,
     .Xr sf 4 ,
    +.Xr sge 4 ,
     .Xr sis 4 ,
     .Xr sk 4 ,
     .Xr ste 4 ,
    diff --git a/share/man/man4/miibus.4 b/share/man/man4/miibus.4
    index ec939671677..5a385957231 100644
    --- a/share/man/man4/miibus.4
    +++ b/share/man/man4/miibus.4
    @@ -8,7 +8,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd June 14, 2009
    +.Dd April 14, 2010
     .Dt MIIBUS 4
     .Os
     .Sh NAME
    @@ -97,6 +97,8 @@ RealTek 8129/8139
     RealTek RTL8150 USB To Fast Ethernet
     .It Xr sf 4
     Adaptec AIC-6915
    +.It Xr sge 4
    +Silicon Integrated Systems SiS190/191 Ethernet
     .It Xr sis 4
     Silicon Integrated Systems SiS 900/SiS 7016
     .It Xr sk 4
    @@ -158,6 +160,7 @@ but as a result are not well behaved newbus device drivers.
     .Xr rl 4 ,
     .Xr rue 4 ,
     .Xr sf 4 ,
    +.Xr sge 4 ,
     .Xr sis 4 ,
     .Xr sk 4 ,
     .Xr ste 4 ,
    diff --git a/share/man/man4/sge.4 b/share/man/man4/sge.4
    new file mode 100644
    index 00000000000..a3d057d386c
    --- /dev/null
    +++ b/share/man/man4/sge.4
    @@ -0,0 +1,120 @@
    +.\" Copyright (c) 2010 Pyun YongHyeon
    +.\" 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 April 14, 2010
    +.Dt SGE 4
    +.Os
    +.Sh NAME
    +.Nm sge
    +.Nd Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet driver
    +.Sh SYNOPSIS
    +To compile this driver into the kernel,
    +place the following lines in your
    +kernel configuration file:
    +.Bd -ragged -offset indent
    +.Cd "device miibus"
    +.Cd "device sge"
    +.Ed
    +.Pp
    +Alternatively, to load the driver as a
    +module at boot time, place the following line in
    +.Xr loader.conf 5 :
    +.Bd -literal -offset indent
    +if_sge="YES"
    +.Ed
    +.Sh DESCRIPTION
    +The
    +.Nm
    +device driver provides support for SiS190 Fast Ethernet
    +controllers and SiS191 Fast/Gigabit Ethernet controllers.
    +.Pp
    +All LOMs supported by the
    +.Nm
    +driver have TCP/UDP/IP checksum offload for transmit and receive.
    +Due to lack of documentation more offloading features like TCP
    +segmentation offload (TSO), hardware VLAN tag stripping/insertion
    +features, Wake On Lan (WOL), Jumbo frame and an interrupt moderation
    +mechanism are not supported yet.
    +.Pp
    +The
    +.Nm
    +driver supports the following media types:
    +.Bl -tag -width ".Cm 10baseT/UTP"
    +.It Cm autoselect
    +Enable autoselection of the media type and options.
    +The user can manually override
    +the autoselected mode by adding media options to
    +.Xr rc.conf 5 .
    +.It Cm 10baseT/UTP
    +Set 10Mbps operation.
    +.It Cm 100baseTX
    +Set 100Mbps (Fast Ethernet) operation.
    +.It Cm 1000baseTX
    +Set 1000baseTX operation over twisted pair.
    +.El
    +.Pp
    +The
    +.Nm
    +driver supports the following media options:
    +.Bl -tag -width ".Cm full-duplex"
    +.It Cm full-duplex
    +Force full duplex operation.
    +.It Cm half-duplex
    +Force half duplex operation.
    +.El
    +.Pp
    +For more information on configuring this device, see
    +.Xr ifconfig 8 .
    +.Sh HARDWARE
    +The
    +.Nm
    +device driver provides support for the following Ethernet controllers:
    +.Pp
    +.Bl -bullet -compact
    +.It
    +SiS190 Fast Ethernet controller
    +.It
    +SiS191 Fast/Gigabit Ethernet controller
    +.El
    +.Sh SEE ALSO
    +.Xr altq 4 ,
    +.Xr arp 4 ,
    +.Xr miibus 4 ,
    +.Xr netintro 4 ,
    +.Xr ng_ether 4 ,
    +.Xr vlan 4 ,
    +.Xr ifconfig 8
    +.Sh HISTORY
    +The
    +.Nm
    +driver was written by
    +.An Alexander Pohoyda
    +.Aq alexander.pohoyda@gmx.net .
    +And enhanced by
    +.An Nikolay Denev
    +.Aq ndenev@gmail.com .
    +It first appeared in
    +.Fx 8.1 .
    diff --git a/share/man/man4/vlan.4 b/share/man/man4/vlan.4
    index 149d4bc5fcd..f7f7807a86d 100644
    --- a/share/man/man4/vlan.4
    +++ b/share/man/man4/vlan.4
    @@ -25,7 +25,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd June 14, 2009
    +.Dd April 14, 2010
     .Dt VLAN 4
     .Os
     .Sh NAME
    @@ -172,6 +172,7 @@ natively:
     .Xr nve 4 ,
     .Xr rl 4 ,
     .Xr sf 4 ,
    +.Xr sge 4 ,
     .Xr sis 4 ,
     .Xr sk 4 ,
     .Xr ste 4 ,
    
    From ddf5d37989c147529743791e3d78daeca70444af Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Mon, 26 Apr 2010 17:54:49 +0000
    Subject: [PATCH 2118/2592] MFC r206672:   Fix include path.
    
    ---
     sys/dev/sge/if_sge.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/dev/sge/if_sge.c b/sys/dev/sge/if_sge.c
    index a26a6a46359..c4fb5c9bc8b 100644
    --- a/sys/dev/sge/if_sge.c
    +++ b/sys/dev/sge/if_sge.c
    @@ -81,7 +81,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#include "if_sgereg.h"
    +#include 
     
     MODULE_DEPEND(sge, pci, 1, 1, 1);
     MODULE_DEPEND(sge, ether, 1, 1, 1);
    
    From ed0af45af3e0c82120c0d0054e93cb61849a6074 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Mon, 26 Apr 2010 18:02:12 +0000
    Subject: [PATCH 2119/2592] MFC r206876:   With r206844, CSUM_TCP is also set
     for CSUM_TSO case. Modify   drivers to take into account for the change.
     Basically CSUM_TSO   should be checked before checking CSUM_TCP.
    
    ---
     sys/dev/age/if_age.c |  28 ++++++------
     sys/dev/alc/if_alc.c |  44 +++++++++---------
     sys/dev/ale/if_ale.c |  19 ++++----
     sys/dev/fxp/if_fxp.c | 106 +++++++++++++++++++++----------------------
     sys/dev/msk/if_msk.c |  48 ++++++++++----------
     sys/dev/nfe/if_nfe.c |  13 +++---
     6 files changed, 125 insertions(+), 133 deletions(-)
    
    diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c
    index 3c5a1079774..15ce0eff851 100644
    --- a/sys/dev/age/if_age.c
    +++ b/sys/dev/age/if_age.c
    @@ -1629,22 +1629,8 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
     	}
     
     	m = *m_head;
    -	/* Configure Tx IP/TCP/UDP checksum offload. */
    -	if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) {
    -		cflags |= AGE_TD_CSUM;
    -		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
    -			cflags |= AGE_TD_TCPCSUM;
    -		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
    -			cflags |= AGE_TD_UDPCSUM;
    -		/* Set checksum start offset. */
    -		cflags |= (poff << AGE_TD_CSUM_PLOADOFFSET_SHIFT);
    -		/* Set checksum insertion position of TCP/UDP. */
    -		cflags |= ((poff + m->m_pkthdr.csum_data) <<
    -		    AGE_TD_CSUM_XSUMOFFSET_SHIFT);
    -	}
    -
    -	/* Configure TSO. */
     	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
    +		/* Configure TSO. */
     		if (poff + (tcp->th_off << 2) == m->m_pkthdr.len) {
     			/* Not TSO but IP/TCP checksum offload. */
     			cflags |= AGE_TD_IPCSUM | AGE_TD_TCPCSUM;
    @@ -1660,6 +1646,18 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
     		/* Set IP/TCP header size. */
     		cflags |= ip->ip_hl << AGE_TD_IPHDR_LEN_SHIFT;
     		cflags |= tcp->th_off << AGE_TD_TSO_TCPHDR_LEN_SHIFT;
    +	} else if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) {
    +		/* Configure Tx IP/TCP/UDP checksum offload. */
    +		cflags |= AGE_TD_CSUM;
    +		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
    +			cflags |= AGE_TD_TCPCSUM;
    +		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
    +			cflags |= AGE_TD_UDPCSUM;
    +		/* Set checksum start offset. */
    +		cflags |= (poff << AGE_TD_CSUM_PLOADOFFSET_SHIFT);
    +		/* Set checksum insertion position of TCP/UDP. */
    +		cflags |= ((poff + m->m_pkthdr.csum_data) <<
    +		    AGE_TD_CSUM_XSUMOFFSET_SHIFT);
     	}
     
     	/* Configure VLAN hardware tag insertion. */
    diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
    index e95b04453cd..c685b84e863 100644
    --- a/sys/dev/alc/if_alc.c
    +++ b/sys/dev/alc/if_alc.c
    @@ -1908,28 +1908,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
     		vtag = (vtag << TD_VLAN_SHIFT) & TD_VLAN_MASK;
     		cflags |= TD_INS_VLAN_TAG;
     	}
    -	/* Configure Tx checksum offload. */
    -	if ((m->m_pkthdr.csum_flags & ALC_CSUM_FEATURES) != 0) {
    -#ifdef ALC_USE_CUSTOM_CSUM
    -		cflags |= TD_CUSTOM_CSUM;
    -		/* Set checksum start offset. */
    -		cflags |= ((poff >> 1) << TD_PLOAD_OFFSET_SHIFT) &
    -		    TD_PLOAD_OFFSET_MASK;
    -		/* Set checksum insertion position of TCP/UDP. */
    -		cflags |= (((poff + m->m_pkthdr.csum_data) >> 1) <<
    -		    TD_CUSTOM_CSUM_OFFSET_SHIFT) & TD_CUSTOM_CSUM_OFFSET_MASK;
    -#else
    -		if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
    -			cflags |= TD_IPCSUM;
    -		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
    -			cflags |= TD_TCPCSUM;
    -		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
    -			cflags |= TD_UDPCSUM;
    -		/* Set TCP/UDP header offset. */
    -		cflags |= (poff << TD_L4HDR_OFFSET_SHIFT) &
    -		    TD_L4HDR_OFFSET_MASK;
    -#endif
    -	} else if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
    +	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
     		/* Request TSO and set MSS. */
     		cflags |= TD_TSO | TD_TSO_DESCV1;
     		cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << TD_MSS_SHIFT) &
    @@ -1961,6 +1940,27 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
     		}
     		/* Handle remaining fragments. */
     		idx = 1;
    +	} else if ((m->m_pkthdr.csum_flags & ALC_CSUM_FEATURES) != 0) {
    +		/* Configure Tx checksum offload. */
    +#ifdef ALC_USE_CUSTOM_CSUM
    +		cflags |= TD_CUSTOM_CSUM;
    +		/* Set checksum start offset. */
    +		cflags |= ((poff >> 1) << TD_PLOAD_OFFSET_SHIFT) &
    +		    TD_PLOAD_OFFSET_MASK;
    +		/* Set checksum insertion position of TCP/UDP. */
    +		cflags |= (((poff + m->m_pkthdr.csum_data) >> 1) <<
    +		    TD_CUSTOM_CSUM_OFFSET_SHIFT) & TD_CUSTOM_CSUM_OFFSET_MASK;
    +#else
    +		if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
    +			cflags |= TD_IPCSUM;
    +		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
    +			cflags |= TD_TCPCSUM;
    +		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
    +			cflags |= TD_UDPCSUM;
    +		/* Set TCP/UDP header offset. */
    +		cflags |= (poff << TD_L4HDR_OFFSET_SHIFT) &
    +		    TD_L4HDR_OFFSET_MASK;
    +#endif
     	}
     	for (; idx < nsegs; idx++) {
     		desc = &sc->alc_rdata.alc_tx_ring[prod];
    diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c
    index 76f1b74f2af..b3e71872d5b 100644
    --- a/sys/dev/ale/if_ale.c
    +++ b/sys/dev/ale/if_ale.c
    @@ -1737,8 +1737,14 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
     	bus_dmamap_sync(sc->ale_cdata.ale_tx_tag, map, BUS_DMASYNC_PREWRITE);
     
     	m = *m_head;
    -	/* Configure Tx checksum offload. */
    -	if ((m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0) {
    +	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
    +		/* Request TSO and set MSS. */
    +		cflags |= ALE_TD_TSO;
    +		cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << ALE_TD_MSS_SHIFT);
    +		/* Set IP/TCP header size. */
    +		cflags |= ip->ip_hl << ALE_TD_IPHDR_LEN_SHIFT;
    +		cflags |= tcp->th_off << ALE_TD_TCPHDR_LEN_SHIFT;
    +	} else if ((m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0) {
     		/*
     		 * AR81xx supports Tx custom checksum offload feature
     		 * that offloads single 16bit checksum computation.
    @@ -1769,15 +1775,6 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
     		    ALE_TD_CSUM_XSUMOFFSET_SHIFT);
     	}
     
    -	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
    -		/* Request TSO and set MSS. */
    -		cflags |= ALE_TD_TSO;
    -		cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << ALE_TD_MSS_SHIFT);
    -		/* Set IP/TCP header size. */
    -		cflags |= ip->ip_hl << ALE_TD_IPHDR_LEN_SHIFT;
    -		cflags |= tcp->th_off << ALE_TD_TCPHDR_LEN_SHIFT;
    -	}
    -
     	/* Configure VLAN hardware tag insertion. */
     	if ((m->m_flags & M_VLANTAG) != 0) {
     		vtag = ALE_TX_VLAN_TAG(m->m_pkthdr.ether_vtag);
    diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
    index a8d961eb0fb..a480e7cc6a4 100644
    --- a/sys/dev/fxp/if_fxp.c
    +++ b/sys/dev/fxp/if_fxp.c
    @@ -1417,60 +1417,6 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
     		    FXP_IPCB_HARDWAREPARSING_ENABLE;
     
     	m = *m_head;
    -	/*
    -	 * Deal with TCP/IP checksum offload. Note that
    -	 * in order for TCP checksum offload to work,
    -	 * the pseudo header checksum must have already
    -	 * been computed and stored in the checksum field
    -	 * in the TCP header. The stack should have
    -	 * already done this for us.
    -	 */
    -	if (m->m_pkthdr.csum_flags & FXP_CSUM_FEATURES) {
    -		txp->tx_cb->ipcb_ip_schedule = FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
    -		if (m->m_pkthdr.csum_flags & CSUM_TCP)
    -			txp->tx_cb->ipcb_ip_schedule |= FXP_IPCB_TCP_PACKET;
    -
    -#ifdef FXP_IP_CSUM_WAR
    -		/*
    -		 * XXX The 82550 chip appears to have trouble
    -		 * dealing with IP header checksums in very small
    -		 * datagrams, namely fragments from 1 to 3 bytes
    -		 * in size. For example, say you want to transmit
    -		 * a UDP packet of 1473 bytes. The packet will be
    -		 * fragmented over two IP datagrams, the latter
    -		 * containing only one byte of data. The 82550 will
    -		 * botch the header checksum on the 1-byte fragment.
    -		 * As long as the datagram contains 4 or more bytes
    -		 * of data, you're ok.
    -		 *
    -                 * The following code attempts to work around this
    -		 * problem: if the datagram is less than 38 bytes
    -		 * in size (14 bytes ether header, 20 bytes IP header,
    -		 * plus 4 bytes of data), we punt and compute the IP
    -		 * header checksum by hand. This workaround doesn't
    -		 * work very well, however, since it can be fooled
    -		 * by things like VLAN tags and IP options that make
    -		 * the header sizes/offsets vary.
    -		 */
    -
    -		if (m->m_pkthdr.csum_flags & CSUM_IP) {
    -			if (m->m_pkthdr.len < 38) {
    -				struct ip *ip;
    -				m->m_data += ETHER_HDR_LEN;
    -				ip = mtod(m, struct ip *);
    -				ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
    -				m->m_data -= ETHER_HDR_LEN;
    -				m->m_pkthdr.csum_flags &= ~CSUM_IP;
    -			} else {
    -				txp->tx_cb->ipcb_ip_activation_high =
    -				    FXP_IPCB_HARDWAREPARSING_ENABLE;
    -				txp->tx_cb->ipcb_ip_schedule |=
    -				    FXP_IPCB_IP_CHECKSUM_ENABLE;
    -			}
    -		}
    -#endif
    -	}
    -
     	if (m->m_pkthdr.csum_flags & CSUM_TSO) {
     		/*
     		 * 82550/82551 requires ethernet/IP/TCP headers must be
    @@ -1539,6 +1485,58 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
     		tcp_payload = m->m_pkthdr.len - ip_off - (ip->ip_hl << 2);
     		tcp_payload -= tcp->th_off << 2;
     		*m_head = m;
    +	} else if (m->m_pkthdr.csum_flags & FXP_CSUM_FEATURES) {
    +		/*
    +		 * Deal with TCP/IP checksum offload. Note that
    +		 * in order for TCP checksum offload to work,
    +		 * the pseudo header checksum must have already
    +		 * been computed and stored in the checksum field
    +		 * in the TCP header. The stack should have
    +		 * already done this for us.
    +		 */
    +		txp->tx_cb->ipcb_ip_schedule = FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
    +		if (m->m_pkthdr.csum_flags & CSUM_TCP)
    +			txp->tx_cb->ipcb_ip_schedule |= FXP_IPCB_TCP_PACKET;
    +
    +#ifdef FXP_IP_CSUM_WAR
    +		/*
    +		 * XXX The 82550 chip appears to have trouble
    +		 * dealing with IP header checksums in very small
    +		 * datagrams, namely fragments from 1 to 3 bytes
    +		 * in size. For example, say you want to transmit
    +		 * a UDP packet of 1473 bytes. The packet will be
    +		 * fragmented over two IP datagrams, the latter
    +		 * containing only one byte of data. The 82550 will
    +		 * botch the header checksum on the 1-byte fragment.
    +		 * As long as the datagram contains 4 or more bytes
    +		 * of data, you're ok.
    +		 *
    +                 * The following code attempts to work around this
    +		 * problem: if the datagram is less than 38 bytes
    +		 * in size (14 bytes ether header, 20 bytes IP header,
    +		 * plus 4 bytes of data), we punt and compute the IP
    +		 * header checksum by hand. This workaround doesn't
    +		 * work very well, however, since it can be fooled
    +		 * by things like VLAN tags and IP options that make
    +		 * the header sizes/offsets vary.
    +		 */
    +
    +		if (m->m_pkthdr.csum_flags & CSUM_IP) {
    +			if (m->m_pkthdr.len < 38) {
    +				struct ip *ip;
    +				m->m_data += ETHER_HDR_LEN;
    +				ip = mtod(m, struct ip *);
    +				ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
    +				m->m_data -= ETHER_HDR_LEN;
    +				m->m_pkthdr.csum_flags &= ~CSUM_IP;
    +			} else {
    +				txp->tx_cb->ipcb_ip_activation_high =
    +				    FXP_IPCB_HARDWAREPARSING_ENABLE;
    +				txp->tx_cb->ipcb_ip_schedule |=
    +				    FXP_IPCB_IP_CHECKSUM_ENABLE;
    +			}
    +		}
    +#endif
     	}
     
     	error = bus_dmamap_load_mbuf_sg(sc->fxp_txmtag, txp->tx_map, *m_head,
    diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
    index 90b794c6a6d..b6276a0d99a 100644
    --- a/sys/dev/msk/if_msk.c
    +++ b/sys/dev/msk/if_msk.c
    @@ -2529,23 +2529,32 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
     		ip = (struct ip *)(mtod(m, char *) + offset);
     		offset += (ip->ip_hl << 2);
     		tcp_offset = offset;
    -		/*
    -		 * It seems that Yukon II has Tx checksum offload bug for
    -		 * small TCP packets that's less than 60 bytes in size
    -		 * (e.g. TCP window probe packet, pure ACK packet).
    -		 * Common work around like padding with zeros to make the
    -		 * frame minimum ethernet frame size didn't work at all.
    -		 * Instead of disabling checksum offload completely we
    -		 * resort to S/W checksum routine when we encounter short
    -		 * TCP frames.
    -		 * Short UDP packets appear to be handled correctly by
    -		 * Yukon II. Also I assume this bug does not happen on
    -		 * controllers that use newer descriptor format or
    -		 * automatic Tx checksum calaulcation.
    -		 */
    -		if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
    +		if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
    +			m = m_pullup(m, offset + sizeof(struct tcphdr));
    +			if (m == NULL) {
    +				*m_head = NULL;
    +				return (ENOBUFS);
    +			}
    +			tcp = (struct tcphdr *)(mtod(m, char *) + offset);
    +			offset += (tcp->th_off << 2);
    +		} else if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
     		    (m->m_pkthdr.len < MSK_MIN_FRAMELEN) &&
     		    (m->m_pkthdr.csum_flags & CSUM_TCP) != 0) {
    +			/*
    +			 * It seems that Yukon II has Tx checksum offload bug
    +			 * for small TCP packets that's less than 60 bytes in
    +			 * size (e.g. TCP window probe packet, pure ACK packet).
    +			 * Common work around like padding with zeros to make
    +			 * the frame minimum ethernet frame size didn't work at
    +			 * all.
    +			 * Instead of disabling checksum offload completely we
    +			 * resort to S/W checksum routine when we encounter
    +			 * short TCP frames.
    +			 * Short UDP packets appear to be handled correctly by
    +			 * Yukon II. Also I assume this bug does not happen on
    +			 * controllers that use newer descriptor format or
    +			 * automatic Tx checksum calaulcation.
    +			 */
     			m = m_pullup(m, offset + sizeof(struct tcphdr));
     			if (m == NULL) {
     				*m_head = NULL;
    @@ -2556,15 +2565,6 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
     			    m->m_pkthdr.len, offset);
     			m->m_pkthdr.csum_flags &= ~CSUM_TCP;
     		}
    -		if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
    -			m = m_pullup(m, offset + sizeof(struct tcphdr));
    -			if (m == NULL) {
    -				*m_head = NULL;
    -				return (ENOBUFS);
    -			}
    -			tcp = (struct tcphdr *)(mtod(m, char *) + offset);
    -			offset += (tcp->th_off << 2);
    -		}
     		*m_head = m;
     	}
     
    diff --git a/sys/dev/nfe/if_nfe.c b/sys/dev/nfe/if_nfe.c
    index 67d48710f5f..29c835c9c62 100644
    --- a/sys/dev/nfe/if_nfe.c
    +++ b/sys/dev/nfe/if_nfe.c
    @@ -2367,7 +2367,12 @@ nfe_encap(struct nfe_softc *sc, struct mbuf **m_head)
     	m = *m_head;
     	cflags = flags = 0;
     	tso_segsz = 0;
    -	if ((m->m_pkthdr.csum_flags & NFE_CSUM_FEATURES) != 0) {
    +	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
    +		tso_segsz = (uint32_t)m->m_pkthdr.tso_segsz <<
    +		    NFE_TX_TSO_SHIFT;
    +		cflags &= ~(NFE_TX_IP_CSUM | NFE_TX_TCP_UDP_CSUM);
    +		cflags |= NFE_TX_TSO;
    +	} else if ((m->m_pkthdr.csum_flags & NFE_CSUM_FEATURES) != 0) {
     		if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
     			cflags |= NFE_TX_IP_CSUM;
     		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
    @@ -2375,12 +2380,6 @@ nfe_encap(struct nfe_softc *sc, struct mbuf **m_head)
     		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
     			cflags |= NFE_TX_TCP_UDP_CSUM;
     	}
    -	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
    -		tso_segsz = (uint32_t)m->m_pkthdr.tso_segsz <<
    -		    NFE_TX_TSO_SHIFT;
    -		cflags &= ~(NFE_TX_IP_CSUM | NFE_TX_TCP_UDP_CSUM);
    -		cflags |= NFE_TX_TSO;
    -	}
     
     	for (i = 0; i < nsegs; i++) {
     		if (sc->nfe_flags & NFE_40BIT_ADDR) {
    
    From 3e1961268ecf12ff4ba5f522b3d6a8e185bdc1c0 Mon Sep 17 00:00:00 2001
    From: Pyun YongHyeon 
    Date: Mon, 26 Apr 2010 18:07:55 +0000
    Subject: [PATCH 2120/2592] MFC r207071:   Intialize interrupt moderation
     control register. The magic value   was chosen by lots of trial and errors.
     The chosen value shows   good interrupt moderation without additional
     latency.   Without this change, controller can generate more than 140k  
     interrupts per second under high network load.
    
      Submitted by:	xclin  cs dot nctu dot edu dot tw >
    ---
     sys/dev/sge/if_sge.c | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/sys/dev/sge/if_sge.c b/sys/dev/sge/if_sge.c
    index c4fb5c9bc8b..6c737bd3f42 100644
    --- a/sys/dev/sge/if_sge.c
    +++ b/sys/dev/sge/if_sge.c
    @@ -1551,10 +1551,13 @@ sge_init_locked(struct sge_softc *sc)
     	/*
     	 * XXX Try to mitigate interrupts.
     	 */
    +	CSR_WRITE_4(sc, IntrControl, 0x08880000);
    +#ifdef notyet
     	if (sc->sge_intrcontrol != 0)
     		CSR_WRITE_4(sc, IntrControl, sc->sge_intrcontrol);
     	if (sc->sge_intrtimer != 0)
     		CSR_WRITE_4(sc, IntrTimer, sc->sge_intrtimer);
    +#endif
     
     	/*
     	 * Clear and enable interrupts.
    
    From 9a4f7ef7138a2feee9a5db529c4425249b1702ce Mon Sep 17 00:00:00 2001
    From: Jung-uk Kim 
    Date: Mon, 26 Apr 2010 19:19:29 +0000
    Subject: [PATCH 2121/2592] MFC:	r206384
    
    Allocate memory for VBE info block with malloc(9), not as static local.
    ---
     sys/dev/fb/vesa.c | 50 ++++++++++++++++++++++++++---------------------
     1 file changed, 28 insertions(+), 22 deletions(-)
    
    diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c
    index 911f3a39c7f..c625b956b9f 100644
    --- a/sys/dev/fb/vesa.c
    +++ b/sys/dev/fb/vesa.c
    @@ -763,8 +763,8 @@ vesa_get_bpscanline(struct vesa_mode *vmode)
     static int
     vesa_bios_init(void)
     {
    -	static struct vesa_info buf;
     	struct vesa_mode vmode;
    +	struct vesa_info *buf;
     	video_info_t *p;
     	x86regs_t regs;
     	size_t bsize;
    @@ -800,7 +800,7 @@ vesa_bios_init(void)
     	x86bios_init_regs(®s);
     	regs.R_AX = 0x4f00;
     
    -	vmbuf = x86bios_alloc(&offs, sizeof(buf));
    +	vmbuf = x86bios_alloc(&offs, sizeof(*buf));
     	if (vmbuf == NULL)
     		return (1);
     
    @@ -813,23 +813,23 @@ vesa_bios_init(void)
     	if (regs.R_AX != 0x004f || bcmp("VESA", vmbuf, 4) != 0)
     		goto fail;
     
    -	bcopy(vmbuf, &buf, sizeof(buf));
    +	vesa_adp_info = buf = malloc(sizeof(*buf), M_DEVBUF, M_WAITOK);
    +	bcopy(vmbuf, buf, sizeof(*buf));
     
    -	vesa_adp_info = &buf;
     	if (bootverbose) {
     		printf("VESA: information block\n");
    -		hexdump(&buf, sizeof(buf), NULL, HD_OMIT_CHARS);
    +		hexdump(buf, sizeof(*buf), NULL, HD_OMIT_CHARS);
     	}
     
    -	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);
    +	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; "
    @@ -839,21 +839,21 @@ vesa_bios_init(void)
     		return (1);
     	}
     
    -	VESA_STRCPY(vesa_oemstr, buf.v_oemstr);
    +	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);
    +		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;
     
    -	if (buf.v_modetable == 0)
    +	if (buf->v_modetable == 0)
     		goto fail;
     
    -	msize = (size_t)buf.v_memsize * 64 * 1024;
    +	msize = (size_t)buf->v_memsize * 64 * 1024;
     
    -	vesa_vmodetab = x86bios_offset(BIOS_SADDRTOLADDR(buf.v_modetable));
    +	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) {
    @@ -1016,12 +1016,16 @@ vesa_bios_init(void)
     	if (!has_vesa_bios)
     		goto fail;
     
    -	x86bios_free(vmbuf, sizeof(buf));
    +	x86bios_free(vmbuf, sizeof(*buf));
     	return (0);
     
     fail:
     	if (vmbuf != NULL)
     		x86bios_free(vmbuf, sizeof(buf));
    +	if (vesa_adp_info != NULL) {
    +		free(vesa_adp_info, M_DEVBUF);
    +		vesa_adp_info = NULL;
    +	}
     	if (vesa_oemstr != NULL) {
     		free(vesa_oemstr, M_DEVBUF);
     		vesa_oemstr = NULL;
    @@ -1875,6 +1879,8 @@ vesa_unload(void)
     	}
     	splx(s);
     
    +	if (vesa_adp_info != NULL)
    +		free(vesa_adp_info, M_DEVBUF);
     	if (vesa_oemstr != NULL)
     		free(vesa_oemstr, M_DEVBUF);
     	if (vesa_venderstr != NULL)
    
    From 44dd6ac24585ec29b69cfb03181bd3f5c2ffde91 Mon Sep 17 00:00:00 2001
    From: Jung-uk Kim 
    Date: Mon, 26 Apr 2010 20:55:03 +0000
    Subject: [PATCH 2122/2592] MFC:	r204773 Merge ACPICA 20100304.
    
    MFC:	r204874
    Update module Makefile for ACPICA 20100304.
    
    MFC:	r204877
    Allow ACPI module build on amd64.  Although we strongly recommend building
    it into kernel, there is no need to prevent it from building at all.
    
    MFC:	r204916
    - Allow users to enable dumping Debug objects without ACPI debugger.
    Setting the new sysctl MIB "debug.acpi.enable_debug_objects" to a non-zero
    value enables us to print Debug object when something is written to it.
    - Allow users to disable interpreter slack mode.  Setting the new tunable
    "debug.acpi.interpreter_slack" to zero disables some workarounds for common
    BIOS mistakes and enables strict ACPI implementations by the specification.
    
    MFC:	r204920
    Since the interpreter slack mode is a tunable now, enable a local hack only
    when it is set.  Note the default behaviour does not change by this change.
    
    MFC:	r204965
    Fix white spaces.
    
    MFC:	r206117
    Merge ACPICA 20100331 (and four additional upstream patches).
    ---
     sys/conf/files                                |   1 +
     sys/contrib/dev/acpica/changes.txt            | 128 +++
     sys/contrib/dev/acpica/common/dmextern.c      |  11 +-
     sys/contrib/dev/acpica/common/dmtable.c       |   3 +-
     sys/contrib/dev/acpica/common/dmtbdump.c      |  14 +-
     sys/contrib/dev/acpica/common/dmtbinfo.c      |  25 +
     sys/contrib/dev/acpica/compiler/aslanalyze.c  | 289 +------
     sys/contrib/dev/acpica/compiler/aslcompiler.h |  26 +-
     sys/contrib/dev/acpica/compiler/aslglobal.h   |   1 -
     sys/contrib/dev/acpica/compiler/aslmain.c     |   2 +-
     sys/contrib/dev/acpica/compiler/aslmap.c      | 317 -------
     sys/contrib/dev/acpica/compiler/aslpredef.c   | 799 ++++++++++++++++++
     sys/contrib/dev/acpica/compiler/aslstubs.c    |  11 +-
     sys/contrib/dev/acpica/compiler/asltypes.h    |  17 +-
     sys/contrib/dev/acpica/debugger/dbdisply.c    |  59 +-
     sys/contrib/dev/acpica/dispatcher/dsfield.c   |   2 +-
     sys/contrib/dev/acpica/dispatcher/dsmethod.c  |   2 +-
     sys/contrib/dev/acpica/dispatcher/dsmthdat.c  |  10 +-
     sys/contrib/dev/acpica/dispatcher/dsobject.c  |  14 +-
     sys/contrib/dev/acpica/dispatcher/dsopcode.c  |  12 +-
     sys/contrib/dev/acpica/dispatcher/dswexec.c   |   6 +-
     sys/contrib/dev/acpica/dispatcher/dswstate.c  |  10 +-
     sys/contrib/dev/acpica/events/evevent.c       |   2 +-
     sys/contrib/dev/acpica/events/evgpe.c         | 291 +++----
     sys/contrib/dev/acpica/events/evgpeblk.c      | 202 ++---
     sys/contrib/dev/acpica/events/evmisc.c        |   2 +-
     sys/contrib/dev/acpica/events/evxface.c       |   6 +-
     sys/contrib/dev/acpica/events/evxfevnt.c      | 342 +++++---
     sys/contrib/dev/acpica/executer/exconvrt.c    |   4 +-
     sys/contrib/dev/acpica/executer/excreate.c    |   4 +-
     sys/contrib/dev/acpica/executer/exdebug.c     | 350 ++++++++
     sys/contrib/dev/acpica/executer/exfield.c     |   2 +-
     sys/contrib/dev/acpica/executer/exfldio.c     |  16 +-
     sys/contrib/dev/acpica/executer/exmisc.c      |   8 +-
     sys/contrib/dev/acpica/executer/exmutex.c     |  51 +-
     sys/contrib/dev/acpica/executer/exnames.c     |   4 +-
     sys/contrib/dev/acpica/executer/exoparg1.c    |  16 +-
     sys/contrib/dev/acpica/executer/exoparg2.c    |  37 +-
     sys/contrib/dev/acpica/executer/exoparg3.c    |   4 +-
     sys/contrib/dev/acpica/executer/exoparg6.c    |   4 +-
     sys/contrib/dev/acpica/executer/exprep.c      |   4 +-
     sys/contrib/dev/acpica/executer/exregion.c    |  17 +-
     sys/contrib/dev/acpica/executer/exresnte.c    |   4 +-
     sys/contrib/dev/acpica/executer/exresolv.c    |   8 +-
     sys/contrib/dev/acpica/executer/exresop.c     |   8 +-
     sys/contrib/dev/acpica/executer/exstore.c     | 223 +----
     sys/contrib/dev/acpica/executer/exsystem.c    |   2 +-
     sys/contrib/dev/acpica/hardware/hwregs.c      |   6 +-
     sys/contrib/dev/acpica/hardware/hwsleep.c     |  17 +-
     sys/contrib/dev/acpica/hardware/hwvalid.c     |   2 +-
     sys/contrib/dev/acpica/include/acdisasm.h     |   1 +
     sys/contrib/dev/acpica/include/acevents.h     |  20 +-
     sys/contrib/dev/acpica/include/acexcep.h      |   2 +-
     sys/contrib/dev/acpica/include/acglobal.h     |  18 +
     sys/contrib/dev/acpica/include/acinterp.h     |  10 +
     sys/contrib/dev/acpica/include/aclocal.h      |   3 +
     sys/contrib/dev/acpica/include/acoutput.h     |   2 +
     sys/contrib/dev/acpica/include/acpixf.h       |  16 +-
     sys/contrib/dev/acpica/include/actables.h     |   8 +
     sys/contrib/dev/acpica/include/actbl2.h       |  30 +
     sys/contrib/dev/acpica/include/actypes.h      |  51 +-
     .../dev/acpica/include/platform/acfreebsd.h   |  30 +-
     sys/contrib/dev/acpica/namespace/nsaccess.c   |   2 +-
     sys/contrib/dev/acpica/namespace/nsdump.c     |   2 +-
     sys/contrib/dev/acpica/namespace/nsnames.c    |   2 +-
     sys/contrib/dev/acpica/namespace/nssearch.c   |   2 +-
     sys/contrib/dev/acpica/namespace/nsutils.c    |   4 +-
     sys/contrib/dev/acpica/parser/psargs.c        |   4 +-
     sys/contrib/dev/acpica/parser/psloop.c        |   3 +-
     sys/contrib/dev/acpica/parser/psxface.c       |   5 +
     sys/contrib/dev/acpica/resources/rscreate.c   |  14 +-
     sys/contrib/dev/acpica/resources/rslist.c     |   6 +-
     sys/contrib/dev/acpica/resources/rsmisc.c     |   4 +-
     sys/contrib/dev/acpica/tables/tbfadt.c        |  16 +-
     sys/contrib/dev/acpica/tables/tbutils.c       |  86 +-
     sys/contrib/dev/acpica/tables/tbxface.c       |  62 +-
     sys/contrib/dev/acpica/tables/tbxfroot.c      |   6 +-
     sys/contrib/dev/acpica/utilities/utalloc.c    |   2 +-
     sys/contrib/dev/acpica/utilities/utdelete.c   |   4 +-
     sys/contrib/dev/acpica/utilities/uteval.c     |   2 +-
     sys/contrib/dev/acpica/utilities/utglobal.c   |   1 +
     sys/contrib/dev/acpica/utilities/utmisc.c     |   6 +-
     sys/contrib/dev/acpica/utilities/utmutex.c    |   4 +-
     sys/contrib/dev/acpica/utilities/utobject.c   |   8 +-
     sys/contrib/dev/acpica/utilities/uttrack.c    |   4 +-
     sys/dev/acpica/acpi.c                         |  76 +-
     sys/dev/acpica/acpi_button.c                  |   1 -
     sys/dev/acpica/acpi_ec.c                      |  12 +-
     sys/dev/acpica/acpi_lid.c                     |   1 -
     sys/dev/acpica/acpi_video.c                   |   4 +-
     sys/dev/acpica/acpivar.h                      |   1 -
     sys/modules/acpi/acpi/Makefile                |  22 +-
     usr.sbin/acpi/acpidb/Makefile                 |  10 +-
     usr.sbin/acpi/iasl/Makefile                   |   6 +-
     94 files changed, 2337 insertions(+), 1631 deletions(-)
     create mode 100644 sys/contrib/dev/acpica/compiler/aslpredef.c
     create mode 100644 sys/contrib/dev/acpica/executer/exdebug.c
    
    diff --git a/sys/conf/files b/sys/conf/files
    index 0b231be5d26..b08549b9bb3 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -184,6 +184,7 @@ contrib/dev/acpica/events/evxfregn.c		optional acpi
     contrib/dev/acpica/executer/exconfig.c		optional acpi
     contrib/dev/acpica/executer/exconvrt.c		optional acpi
     contrib/dev/acpica/executer/excreate.c		optional acpi
    +contrib/dev/acpica/executer/exdebug.c		optional acpi
     contrib/dev/acpica/executer/exdump.c		optional acpi
     contrib/dev/acpica/executer/exfield.c		optional acpi
     contrib/dev/acpica/executer/exfldio.c		optional acpi
    diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt
    index 60620ce4f76..d2c8c0e41ed 100644
    --- a/sys/contrib/dev/acpica/changes.txt
    +++ b/sys/contrib/dev/acpica/changes.txt
    @@ -1,3 +1,131 @@
    +----------------------------------------
    +31 March 2010. Summary of changes for version 20100331:
    +
    +1) ACPI CA Core Subsystem:
    +
    +Completed a major update for the GPE support in order to improve support for 
    +shared GPEs and to simplify both host OS and ACPICA code. Added a reference 
    +count mechanism to support shared GPEs that require multiple device drivers. 
    +Several external interfaces have changed. One external interface has been 
    +removed. One new external interface was added. Most of the GPE external 
    +interfaces now use the GPE spinlock instead of the events mutex (and the 
    +Flags parameter for many GPE interfaces has been removed.) See the updated 
    +ACPICA Programmer Reference for details. Matthew Garrett, Bob Moore, Rafael 
    +Wysocki. ACPICA BZ 831.
    +
    +Changed:
    +    AcpiEnableGpe, AcpiDisableGpe, AcpiClearGpe, AcpiGetGpeStatus
    +Removed:
    +    AcpiSetGpeType
    +New:
    +    AcpiSetGpe
    +
    +Implemented write support for DataTable operation regions. These regions are 
    +defined via the DataTableRegion() operator. Previously, only read support was 
    +implemented. The ACPI specification allows DataTableRegions to be read/write, 
    +however.
    +
    +Implemented a new subsystem option to force a copy of the DSDT to local 
    +memory. Optionally copy the entire DSDT to local memory (instead of simply 
    +mapping it.) There are some (albeit very rare) BIOSs that corrupt or replace 
    +the original DSDT, creating the need for this option. Default is FALSE, do 
    +not copy the DSDT.
    +
    +Implemented detection of a corrupted or replaced DSDT. This change adds 
    +support to detect a DSDT that has been corrupted and/or replaced from outside 
    +the OS (by firmware). This is typically catastrophic for the system, but has 
    +been seen on some machines. Once this problem has been detected, the DSDT 
    +copy option can be enabled via system configuration. Lin Ming, Bob Moore.
    +
    +Fixed two problems with AcpiReallocateRootTable during the root table copy. 
    +When copying the root table to the new allocation, the length used was 
    +incorrect. The new size was used instead of the current table size, meaning 
    +too much data was copied. Also, the count of available slots for ACPI tables 
    +was not set correctly. Alexey Starikovskiy, Bob Moore.
    +
    +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:  87.5K Code, 18.4K Data, 105.9K Total
    +    Debug Version:     163.4K Code, 51.1K Data, 214.5K Total
    +  Current Release:
    +    Non-Debug Version:  87.9K Code, 18.6K Data, 106.5K Total
    +    Debug Version:     163.5K Code, 51.3K Data, 214.8K Total
    +
    +2) iASL Compiler/Disassembler and Tools:
    +
    +iASL: Implement limited typechecking for values returned from predefined 
    +control methods. The type of any returned static (unnamed) object is now 
    +validated. For example, Return(1). ACPICA BZ 786.
    +
    +iASL: Fixed a predefined name object verification regression. Fixes a problem 
    +introduced in version 20100304. An error is incorrectly generated if a 
    +predefined name is declared as a static named object with a value defined 
    +using the keywords "Zero", "One", or "Ones". Lin Ming.
    +
    +iASL: Added Windows 7 support for the -g option (get local ACPI tables) by 
    +reducing the requested registry access rights. ACPICA BZ 842.
    +
    +Disassembler: fixed a possible fault when generating External() statements. 
    +Introduced in commit ae7d6fd: Properly handle externals with parent-prefix 
    +(carat). Fixes a string length allocation calculation. Lin Ming.
    +
    +----------------------------------------
    +04 March 2010. Summary of changes for version 20100304:
    +
    +1) ACPI CA Core Subsystem:
    +
    +Fixed a possible problem with the AML Mutex handling function 
    +AcpiExReleaseMutex where the function could fault under the very rare 
    +condition when the interpreter has blocked, the interpreter lock is released, 
    +the interpreter is then reentered via the same thread, and attempts to 
    +acquire an AML mutex that was previously acquired. FreeBSD report 140979. Lin 
    +Ming.
    +
    +Implemented additional configuration support for the AML "Debug Object". 
    +Output from the debug object can now be enabled via a global variable, 
    +AcpiGbl_EnableAmlDebugObject. This will assist with remote machine debugging. 
    +This debug output is now available in the release version of ACPICA instead 
    +of just the debug version. Also, the entire debug output module can now be 
    +configured out of the ACPICA build if desired. One new file added, 
    +executer/exdebug.c. Lin Ming, Bob Moore.
    +
    +Added header support for the ACPI MCHI table (Management Controller Host 
    +Interface Table). This table was added in ACPI 4.0, but the defining document 
    +has only recently become available.
    +
    +Standardized output of integer values for ACPICA warnings/errors. Always use 
    +0x prefix for hex output, always use %u for unsigned integer decimal output. 
    +Affects ACPI_INFO, ACPI_ERROR, ACPI_EXCEPTION, and ACPI_WARNING (about 400 
    +invocations.) These invocations were converted from the original 
    +ACPI_DEBUG_PRINT invocations and were not consistent. ACPICA BZ 835.
    +
    +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:  87.1K Code, 18.0K Data, 105.1K Total
    +    Debug Version:     163.5K Code, 50.9K Data, 214.4K Total
    +  Current Release:
    +    Non-Debug Version:  87.5K Code, 18.4K Data, 105.9K Total
    +    Debug Version:     163.4K Code, 51.1K Data, 214.5K Total
    +
    +2) iASL Compiler/Disassembler and Tools:
    +
    +iASL: Implemented typechecking support for static (non-control method) 
    +predefined named objects that are declared with the Name() operator. For 
    +example, the type of this object is now validated to be of type Integer: 
    +Name(_BBN, 1). This change migrates the compiler to using the core predefined 
    +name table instead of maintaining a local version. Added a new file, 
    +aslpredef.c. ACPICA BZ 832.
    +
    +Disassembler: Added support for the ACPI 4.0 MCHI table.
    +
     ----------------------------------------
     21 January 2010. Summary of changes for version 20100121:
     
    diff --git a/sys/contrib/dev/acpica/common/dmextern.c b/sys/contrib/dev/acpica/common/dmextern.c
    index 943a3c2f1e6..8d95571b04e 100644
    --- a/sys/contrib/dev/acpica/common/dmextern.c
    +++ b/sys/contrib/dev/acpica/common/dmextern.c
    @@ -270,6 +270,15 @@ AcpiDmNormalizeParentPrefix (
         }
     
         Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1);
    +    if (ParentPath[1])
    +    {
    +        /*
    +         * If ParentPath is not just a simple '\', increment the length
    +         * for the required dot separator (ParentPath.Path)
    +         */
    +        Length++;
    +    }
    +
         Fullpath = ACPI_ALLOCATE_ZEROED (Length);
         if (!Fullpath)
         {
    @@ -374,7 +383,7 @@ AcpiDmAddToExternalList (
                     (NextExternal->Value != Value))
                 {
                     ACPI_ERROR ((AE_INFO,
    -                    "Argument count mismatch for method %s %d %d",
    +                    "Argument count mismatch for method %s %u %u",
                         NextExternal->Path, NextExternal->Value, Value));
                 }
     
    diff --git a/sys/contrib/dev/acpica/common/dmtable.c b/sys/contrib/dev/acpica/common/dmtable.c
    index 70858911150..4b965756741 100644
    --- a/sys/contrib/dev/acpica/common/dmtable.c
    +++ b/sys/contrib/dev/acpica/common/dmtable.c
    @@ -262,6 +262,7 @@ static ACPI_DMTABLE_DATA    AcpiDmTableData[] =
         {ACPI_SIG_IVRS, NULL,                   AcpiDmDumpIvrs, "I/O Virtualization Reporting Structure"},
         {ACPI_SIG_MADT, NULL,                   AcpiDmDumpMadt, "Multiple APIC Description Table"},
         {ACPI_SIG_MCFG, NULL,                   AcpiDmDumpMcfg, "Memory Mapped Configuration table"},
    +    {ACPI_SIG_MCHI, AcpiDmTableInfoMchi,    NULL,           "Management Controller Host Interface table"},
         {ACPI_SIG_MSCT, NULL,                   AcpiDmDumpMsct, "Maximum System Characteristics Table"},
         {ACPI_SIG_RSDT, NULL,                   AcpiDmDumpRsdt, "Root System Description Table"},
         {ACPI_SIG_SBST, AcpiDmTableInfoSbst,    NULL,           "Smart Battery Specification Table"},
    @@ -911,7 +912,7 @@ AcpiDmDumpTable (
     
             default:
                 ACPI_ERROR ((AE_INFO,
    -                "**** Invalid table opcode [%X] ****\n", Info->Opcode));
    +                "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
                 return (AE_SUPPORT);
             }
         }
    diff --git a/sys/contrib/dev/acpica/common/dmtbdump.c b/sys/contrib/dev/acpica/common/dmtbdump.c
    index 2c9725d8206..143cf5b27ba 100644
    --- a/sys/contrib/dev/acpica/common/dmtbdump.c
    +++ b/sys/contrib/dev/acpica/common/dmtbdump.c
    @@ -363,7 +363,7 @@ AcpiDmDumpAsf (
                 break;
     
             default:
    -            AcpiOsPrintf ("\n**** Unknown ASF sub-table type %X\n", SubTable->Header.Type);
    +            AcpiOsPrintf ("\n**** Unknown ASF sub-table type 0x%X\n", SubTable->Header.Type);
                 return;
             }
     
    @@ -561,7 +561,7 @@ AcpiDmDumpDmar (
                 ScopeOffset = sizeof (ACPI_DMAR_RHSA);
                 break;
             default:
    -            AcpiOsPrintf ("\n**** Unknown DMAR sub-table type %X\n\n", SubTable->Type);
    +            AcpiOsPrintf ("\n**** Unknown DMAR sub-table type 0x%X\n\n", SubTable->Type);
                 return;
             }
     
    @@ -809,7 +809,7 @@ AcpiDmDumpHest (
             default:
                 /* Cannot continue on unknown type - no length */
     
    -            AcpiOsPrintf ("\n**** Unknown HEST sub-table type %X\n", SubTable->Type);
    +            AcpiOsPrintf ("\n**** Unknown HEST sub-table type 0x%X\n", SubTable->Type);
                 return;
             }
     
    @@ -916,7 +916,7 @@ AcpiDmDumpIvrs (
                 InfoTable = AcpiDmTableInfoIvrs1;
                 break;
             default:
    -            AcpiOsPrintf ("\n**** Unknown IVRS sub-table type %X\n",
    +            AcpiOsPrintf ("\n**** Unknown IVRS sub-table type 0x%X\n",
                     SubTable->Type);
     
                 /* Attempt to continue */
    @@ -1002,7 +1002,7 @@ AcpiDmDumpIvrs (
                         InfoTable = AcpiDmTableInfoIvrs4;
                         AcpiOsPrintf (
                             "\n**** Unknown IVRS device entry type/length: "
    -                        "%.2X/%X at offset %.4X: (header below)\n",
    +                        "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
                             EntryType, EntryLength, EntryOffset);
                         break;
                     }
    @@ -1110,7 +1110,7 @@ AcpiDmDumpMadt (
                 InfoTable = AcpiDmTableInfoMadt10;
                 break;
             default:
    -            AcpiOsPrintf ("\n**** Unknown MADT sub-table type %X\n\n", SubTable->Type);
    +            AcpiOsPrintf ("\n**** Unknown MADT sub-table type 0x%X\n\n", SubTable->Type);
     
                 /* Attempt to continue */
     
    @@ -1378,7 +1378,7 @@ AcpiDmDumpSrat (
                 InfoTable = AcpiDmTableInfoSrat2;
                 break;
             default:
    -            AcpiOsPrintf ("\n**** Unknown SRAT sub-table type %X\n", SubTable->Type);
    +            AcpiOsPrintf ("\n**** Unknown SRAT sub-table type 0x%X\n", SubTable->Type);
     
                 /* Attempt to continue */
     
    diff --git a/sys/contrib/dev/acpica/common/dmtbinfo.c b/sys/contrib/dev/acpica/common/dmtbinfo.c
    index 6d3b500e0c0..e3f91d94e3b 100644
    --- a/sys/contrib/dev/acpica/common/dmtbinfo.c
    +++ b/sys/contrib/dev/acpica/common/dmtbinfo.c
    @@ -142,6 +142,7 @@
     #define ACPI_IVRS_OFFSET(f)             (UINT8) ACPI_OFFSET (ACPI_TABLE_IVRS,f)
     #define ACPI_MADT_OFFSET(f)             (UINT8) ACPI_OFFSET (ACPI_TABLE_MADT,f)
     #define ACPI_MCFG_OFFSET(f)             (UINT8) ACPI_OFFSET (ACPI_TABLE_MCFG,f)
    +#define ACPI_MCHI_OFFSET(f)             (UINT8) ACPI_OFFSET (ACPI_TABLE_MCHI,f)
     #define ACPI_MSCT_OFFSET(f)             (UINT8) ACPI_OFFSET (ACPI_TABLE_MSCT,f)
     #define ACPI_SBST_OFFSET(f)             (UINT8) ACPI_OFFSET (ACPI_TABLE_SBST,f)
     #define ACPI_SLIT_OFFSET(f)             (UINT8) ACPI_OFFSET (ACPI_TABLE_SLIT,f)
    @@ -1224,6 +1225,30 @@ ACPI_DMTABLE_INFO           AcpiDmTableInfoMcfg0[] =
     };
     
     
    +/*******************************************************************************
    + *
    + * MCHI - Management Controller Host Interface table
    + *
    + ******************************************************************************/
    +
    +ACPI_DMTABLE_INFO           AcpiDmTableInfoMchi[] =
    +{
    +    {ACPI_DMT_UINT8,    ACPI_MCHI_OFFSET (InterfaceType),           "Interface Type"},
    +    {ACPI_DMT_UINT8,    ACPI_MCHI_OFFSET (Protocol),                "Protocol"},
    +    {ACPI_DMT_UINT64,   ACPI_MCHI_OFFSET (ProtocolData),            "Protocol Data"},
    +    {ACPI_DMT_UINT8,    ACPI_MCHI_OFFSET (InterruptType),           "Interrupt Type"},
    +    {ACPI_DMT_UINT8,    ACPI_MCHI_OFFSET (Gpe),                     "Gpe"},
    +    {ACPI_DMT_UINT8,    ACPI_MCHI_OFFSET (PciDeviceFlag),           "Pci Device Flag"},
    +    {ACPI_DMT_UINT32,   ACPI_MCHI_OFFSET (GlobalInterrupt),         "Global Interrupt"},
    +    {ACPI_DMT_GAS,      ACPI_MCHI_OFFSET (ControlRegister),         "Control Register"},
    +    {ACPI_DMT_UINT8,    ACPI_MCHI_OFFSET (PciSegment),              "Pci Segment"},
    +    {ACPI_DMT_UINT8,    ACPI_MCHI_OFFSET (PciBus),                  "Pci Bus"},
    +    {ACPI_DMT_UINT8,    ACPI_MCHI_OFFSET (PciDevice),               "Pci Device"},
    +    {ACPI_DMT_UINT8,    ACPI_MCHI_OFFSET (PciFunction),             "Pci Function"},
    +    {ACPI_DMT_EXIT,     0,                                          NULL}
    +};
    +
    +
     /*******************************************************************************
      *
      * MSCT - Maximum System Characteristics Table (ACPI 4.0)
    diff --git a/sys/contrib/dev/acpica/compiler/aslanalyze.c b/sys/contrib/dev/acpica/compiler/aslanalyze.c
    index 46a6db00723..608f6e51215 100644
    --- a/sys/contrib/dev/acpica/compiler/aslanalyze.c
    +++ b/sys/contrib/dev/acpica/compiler/aslanalyze.c
    @@ -142,16 +142,6 @@ static UINT32
     AnGetBtype (
         ACPI_PARSE_OBJECT       *Op);
     
    -static UINT32
    -AnCheckForReservedName (
    -    ACPI_PARSE_OBJECT       *Op,
    -    char                    *Name);
    -
    -static void
    -AnCheckForReservedMethod (
    -    ACPI_PARSE_OBJECT       *Op,
    -    ASL_METHOD_INFO         *MethodInfo);
    -
     static UINT32
     AnMapObjTypeToBtype (
         ACPI_PARSE_OBJECT       *Op);
    @@ -596,219 +586,6 @@ AnGetBtype (
     }
     
     
    -/*******************************************************************************
    - *
    - * FUNCTION:    AnCheckForReservedName
    - *
    - * PARAMETERS:  Op              - A parse node
    - *              Name            - NameSeg to check
    - *
    - * RETURN:      None
    - *
    - * DESCRIPTION: Check a NameSeg against the reserved list.
    - *
    - ******************************************************************************/
    -
    -static UINT32
    -AnCheckForReservedName (
    -    ACPI_PARSE_OBJECT       *Op,
    -    char                    *Name)
    -{
    -    UINT32                  i;
    -
    -
    -    if (Name[0] == 0)
    -    {
    -        AcpiOsPrintf ("Found a null name, external = %s\n",
    -            Op->Asl.ExternalName);
    -    }
    -
    -    /* All reserved names are prefixed with a single underscore */
    -
    -    if (Name[0] != '_')
    -    {
    -        return (ACPI_NOT_RESERVED_NAME);
    -    }
    -
    -    /* Check for a standard reserved method name */
    -
    -    for (i = 0; ReservedMethods[i].Name; i++)
    -    {
    -        if (ACPI_COMPARE_NAME (Name, ReservedMethods[i].Name))
    -        {
    -            if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
    -            {
    -                AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
    -                    Op->Asl.ExternalName);
    -                return (ACPI_PREDEFINED_NAME);
    -            }
    -            else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
    -            {
    -                AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
    -                    Op->Asl.ExternalName);
    -                return (ACPI_PREDEFINED_NAME);
    -            }
    -
    -            /* Return index into reserved array */
    -
    -            return i;
    -        }
    -    }
    -
    -    /*
    -     * Now check for the "special" reserved names --
    -     * GPE:  _Lxx
    -     * GPE:  _Exx
    -     * EC:   _Qxx
    -     */
    -    if ((Name[1] == 'L') ||
    -        (Name[1] == 'E') ||
    -        (Name[1] == 'Q'))
    -    {
    -        /* The next two characters must be hex digits */
    -
    -        if ((isxdigit ((int) Name[2])) &&
    -            (isxdigit ((int) Name[3])))
    -        {
    -            return (ACPI_EVENT_RESERVED_NAME);
    -        }
    -    }
    -
    -
    -    /* Check for the names reserved for the compiler itself: _T_x */
    -
    -    else if ((Op->Asl.ExternalName[1] == 'T') &&
    -             (Op->Asl.ExternalName[2] == '_'))
    -    {
    -        /* Ignore if actually emitted by the compiler */
    -
    -        if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
    -        {
    -            return (ACPI_NOT_RESERVED_NAME);
    -        }
    -
    -        /*
    -         * Was not actually emitted by the compiler. This is a special case,
    -         * however. If the ASL code being compiled was the result of a
    -         * dissasembly, it may possibly contain valid compiler-emitted names
    -         * of the form "_T_x". We don't want to issue an error or even a
    -         * warning and force the user to manually change the names. So, we
    -         * will issue a remark instead.
    -         */
    -        AslError (ASL_REMARK, ASL_MSG_COMPILER_RESERVED, Op, Op->Asl.ExternalName);
    -        return (ACPI_COMPILER_RESERVED_NAME);
    -    }
    -
    -    /*
    -     * The name didn't match any of the known reserved names. Flag it as a
    -     * warning, since the entire namespace starting with an underscore is
    -     * reserved by the ACPI spec.
    -     */
    -    AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
    -        Op->Asl.ExternalName);
    -
    -    return (ACPI_NOT_RESERVED_NAME);
    -}
    -
    -
    -/*******************************************************************************
    - *
    - * FUNCTION:    AnCheckForReservedMethod
    - *
    - * PARAMETERS:  Op              - A parse node of type "METHOD".
    - *              MethodInfo      - Saved info about this method
    - *
    - * RETURN:      None
    - *
    - * DESCRIPTION: If method is a reserved name, check that the number of arguments
    - *              and the return type (returns a value or not) is correct.
    - *
    - ******************************************************************************/
    -
    -static void
    -AnCheckForReservedMethod (
    -    ACPI_PARSE_OBJECT       *Op,
    -    ASL_METHOD_INFO         *MethodInfo)
    -{
    -    UINT32                  Index;
    -    UINT32                  RequiredArgsCurrent;
    -    UINT32                  RequiredArgsOld;
    -
    -
    -    /* Check for a match against the reserved name list */
    -
    -    Index = AnCheckForReservedName (Op, Op->Asl.NameSeg);
    -
    -    switch (Index)
    -    {
    -    case ACPI_NOT_RESERVED_NAME:
    -    case ACPI_PREDEFINED_NAME:
    -    case ACPI_COMPILER_RESERVED_NAME:
    -
    -        /* Just return, nothing to do */
    -        break;
    -
    -
    -    case ACPI_EVENT_RESERVED_NAME:
    -
    -        Gbl_ReservedMethods++;
    -
    -        /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
    -
    -        if (MethodInfo->NumArguments != 0)
    -        {
    -            sprintf (MsgBuffer, "%s requires %d",
    -                        Op->Asl.ExternalName, 0);
    -
    -            AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
    -        }
    -        break;
    -
    -
    -    default:
    -
    -        Gbl_ReservedMethods++;
    -
    -        /*
    -         * Matched a reserved method name
    -         *
    -         * Validate the ASL-defined argument count. Allow two different legal
    -         * arg counts.
    -         */
    -        RequiredArgsCurrent = ReservedMethods[Index].NumArguments & 0x0F;
    -        RequiredArgsOld = ReservedMethods[Index].NumArguments >> 4;
    -
    -        if ((MethodInfo->NumArguments != RequiredArgsCurrent) &&
    -            (MethodInfo->NumArguments != RequiredArgsOld))
    -        {
    -            sprintf (MsgBuffer, "%s requires %d",
    -                        ReservedMethods[Index].Name,
    -                        RequiredArgsCurrent);
    -
    -            if (MethodInfo->NumArguments > RequiredArgsCurrent)
    -            {
    -                AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
    -                    MsgBuffer);
    -            }
    -            else
    -            {
    -                AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
    -                    MsgBuffer);
    -            }
    -        }
    -
    -        if (MethodInfo->NumReturnNoValue &&
    -            ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE)
    -        {
    -            sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name);
    -
    -            AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer);
    -        }
    -        break;
    -    }
    -}
    -
    -
     /*******************************************************************************
      *
      * FUNCTION:    AnMapObjTypeToBtype
    @@ -1187,7 +964,7 @@ AnMethodAnalysisWalkBegin (
              * The first operand is a name to be created in the namespace.
              * Check against the reserved list.
              */
    -        i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
    +        i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
             if (i < ACPI_VALID_RESERVED_NAME_MAX)
             {
                 AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
    @@ -1197,51 +974,29 @@ AnMethodAnalysisWalkBegin (
     
         case PARSEOP_NAME:
     
    -        i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
    -        if (i < ACPI_VALID_RESERVED_NAME_MAX)
    +        /* Typecheck any predefined names statically defined with Name() */
    +
    +        ApCheckForPredefinedObject (Op, Op->Asl.NameSeg);
    +
    +        /* Special typechecking for _HID */
    +
    +        if (!ACPI_STRCMP (METHOD_NAME__HID, Op->Asl.NameSeg))
             {
    -            if (ReservedMethods[i].NumArguments > 0)
    +            Next = Op->Asl.Child->Asl.Next;
    +            if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
                 {
                     /*
    -                 * This reserved name must be a control method because
    -                 * it must have arguments
    +                 * _HID is a string, all characters must be alphanumeric.
    +                 * One of the things we want to catch here is the use of
    +                 * a leading asterisk in the string.
                      */
    -                AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
    -                    "with arguments");
    -            }
    -
    -            /* Typechecking for _HID */
    -
    -            else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name))
    -            {
    -                /* Examine the second operand to typecheck it */
    -
    -                Next = Op->Asl.Child->Asl.Next;
    -
    -                if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) &&
    -                    (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL))
    +                for (i = 0; Next->Asl.Value.String[i]; i++)
                     {
    -                    /* _HID must be a string or an integer */
    -
    -                    AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next,
    -                        "String or Integer");
    -                }
    -
    -                if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
    -                {
    -                    /*
    -                     * _HID is a string, all characters must be alphanumeric.
    -                     * One of the things we want to catch here is the use of
    -                     * a leading asterisk in the string.
    -                     */
    -                    for (i = 0; Next->Asl.Value.String[i]; i++)
    +                    if (!isalnum ((int) Next->Asl.Value.String[i]))
                         {
    -                        if (!isalnum ((int) Next->Asl.Value.String[i]))
    -                        {
    -                            AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
    -                                Next, Next->Asl.Value.String);
    -                            break;
    -                        }
    +                        AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
    +                            Next, Next->Asl.Value.String);
    +                        break;
                         }
                     }
                 }
    @@ -1394,13 +1149,19 @@ AnMethodAnalysisWalkEnd (
              * Check predefined method names for correct return behavior
              * and correct number of arguments
              */
    -        AnCheckForReservedMethod (Op, MethodInfo);
    +        ApCheckForPredefinedMethod (Op, MethodInfo);
             ACPI_FREE (MethodInfo);
             break;
     
     
         case PARSEOP_RETURN:
     
    +        /*
    +         * If the parent is a predefined method name, attempt to typecheck
    +         * the return value. Only static types can be validated.
    +         */
    +        ApCheckPredefinedReturnValue (Op, MethodInfo);
    +
             /*
              * The parent block does not "exit" and continue execution -- the
              * method is terminated here with the Return() statement.
    diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.h b/sys/contrib/dev/acpica/compiler/aslcompiler.h
    index 16b5f723d45..dbc2709725b 100644
    --- a/sys/contrib/dev/acpica/compiler/aslcompiler.h
    +++ b/sys/contrib/dev/acpica/compiler/aslcompiler.h
    @@ -452,8 +452,32 @@ ACPI_OBJECT_TYPE
     AslMapNamedOpcodeToDataType (
         UINT16                  Opcode);
     
    +
    +/*
    + * aslpredef - ACPI predefined names support
    + */
     void
    -MpDisplayReservedNames (
    +ApCheckForPredefinedMethod (
    +    ACPI_PARSE_OBJECT       *Op,
    +    ASL_METHOD_INFO         *MethodInfo);
    +
    +void
    +ApCheckPredefinedReturnValue (
    +    ACPI_PARSE_OBJECT       *Op,
    +    ASL_METHOD_INFO         *MethodInfo);
    +
    +UINT32
    +ApCheckForPredefinedName (
    +    ACPI_PARSE_OBJECT       *Op,
    +    char                    *Name);
    +
    +void
    +ApCheckForPredefinedObject (
    +    ACPI_PARSE_OBJECT       *Op,
    +    char                    *Name);
    +
    +void
    +ApDisplayReservedNames (
         void);
     
     
    diff --git a/sys/contrib/dev/acpica/compiler/aslglobal.h b/sys/contrib/dev/acpica/compiler/aslglobal.h
    index 69fcf8438a1..01ab931e0d0 100644
    --- a/sys/contrib/dev/acpica/compiler/aslglobal.h
    +++ b/sys/contrib/dev/acpica/compiler/aslglobal.h
    @@ -261,7 +261,6 @@ ASL_EXTERN FILE                     *AcpiGbl_DebugFile; /* Placeholder for oswin
     
     ASL_EXTERN ASL_ANALYSIS_WALK_INFO   AnalysisWalkInfo;
     ASL_EXTERN ACPI_TABLE_HEADER        TableHeader;
    -extern const ASL_RESERVED_INFO      ReservedMethods[];
     
     /* Event timing */
     
    diff --git a/sys/contrib/dev/acpica/compiler/aslmain.c b/sys/contrib/dev/acpica/compiler/aslmain.c
    index 9b9e9568543..e8b0c457ce5 100644
    --- a/sys/contrib/dev/acpica/compiler/aslmain.c
    +++ b/sys/contrib/dev/acpica/compiler/aslmain.c
    @@ -570,7 +570,7 @@ AslDoOptions (
             case 'r':
                 /* reserved names */
     
    -            MpDisplayReservedNames ();
    +            ApDisplayReservedNames ();
                 exit (0);
     
             default:
    diff --git a/sys/contrib/dev/acpica/compiler/aslmap.c b/sys/contrib/dev/acpica/compiler/aslmap.c
    index be43b229ce5..4027a622067 100644
    --- a/sys/contrib/dev/acpica/compiler/aslmap.c
    +++ b/sys/contrib/dev/acpica/compiler/aslmap.c
    @@ -114,7 +114,6 @@
      *
      *****************************************************************************/
     
    -
     #include 
     #include 
     #include 
    @@ -169,322 +168,6 @@ AslMapNamedOpcodeToDataType (
     }
     
     
    -/*******************************************************************************
    - *
    - * FUNCTION:    MpDisplayReservedNames
    - *
    - * PARAMETERS:  None
    - *
    - * RETURN:      None
    - *
    - * DESCRIPTION: Print the table above
    - *
    - ******************************************************************************/
    -
    -void
    -MpDisplayReservedNames (
    -    void)
    -{
    -    UINT32              i;
    -
    -    printf ("Reserved name information\n\n");
    -
    -    for (i = 0; ReservedMethods[i].Name; i++)
    -    {
    -        printf ("%s    ", ReservedMethods[i].Name);
    -
    -        if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
    -        {
    -            printf ("Reserved scope name\n");
    -        }
    -        else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
    -        {
    -            printf ("Resource data type reserved field name\n");
    -        }
    -        else
    -        {
    -            printf ("Method with %d arguments, ",
    -                ReservedMethods[i].NumArguments & 0x0F);
    -
    -            if (ReservedMethods[i].Flags & ASL_RSVD_RETURN_VALUE)
    -            {
    -                printf ("must return a value\n");
    -            }
    -            else
    -            {
    -                printf ("no return value\n");
    -            }
    -        }
    -    }
    -}
    -
    -
    -/*******************************************************************************
    - *
    - * DATA STRUCTURE:  ReservedMethods
    - *
    - * DESCRIPTION:     Contains all reserved methods and names as defined in the
    - *                  ACPI specification.  Used during the analysis phase to
    - *                  ensure that reserved methods have the required number of
    - *                  arguments and the proper return type.
    - *
    - * Each entry in the table contains the following items:
    - *
    - * Name         - The ACPI reserved name
    - * Args         - Number of arguments to the method
    - * Flags        - Whether this method must return a value or not. Or if the
    - *                name is a resource descriptor label.
    - *
    - ******************************************************************************/
    -
    -const ASL_RESERVED_INFO         ReservedMethods[] = {
    -    {"_AC0",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AC1",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AC2",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AC3",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AC4",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AC5",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AC6",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AC7",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AC8",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AC9",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_ADR",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL0",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL1",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL2",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL3",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL4",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL5",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL6",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL7",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL8",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_AL9",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_ALC",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_ALI",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_ALN",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_ALP",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_ALR",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_ALT",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_ART",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_ASI",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_ASZ",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_BAS",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_BBN",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_BCL",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_BCM",     1,      0},
    -    {"_BCT",     1,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_BDN",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_BFS",     1,      0},
    -    {"_BIF",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_BIX",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_BLT",     3,      0},                        /* Acpi 3.0 */
    -    {"_BM_",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_BMA",     1,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_BMC",     1,      0},                        /* Acpi 3.0 */
    -    {"_BMD",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_BMS",     1,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_BQC",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_BST",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_BTM",     1,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_BTP",     1,      0},
    -    {"_CBA",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_CDM",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_CID",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_CRS",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_CRT",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_CSD",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_CST",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_DCK",     1,      ASL_RSVD_RETURN_VALUE},
    -    {"_DCS",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_DDC",     1,      ASL_RSVD_RETURN_VALUE},
    -    {"_DDN",     0,      0},
    -    {"_DEC",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_DGS",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_DIS",     0,      0},
    -    {"_DMA",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_DOD",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_DOS",     1,      0},
    -    {"_DSM",     4,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_DSS",     1,      0},
    -    {"_DSW",     3,      0},                        /* Acpi 3.0 */
    -    {"_DTI",     1,      0},                        /* Acpi 4.0 */
    -    {"_EC_",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_EDL",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_EJ0",     1,      0},
    -    {"_EJ1",     1,      0},
    -    {"_EJ2",     1,      0},
    -    {"_EJ3",     1,      0},
    -    {"_EJ4",     1,      0},
    -    {"_EJD",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_ERR",     3,      ASL_RSVD_RETURN_VALUE},
    -    {"_FDE",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_FDI",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_FDM",     1,      0},
    -    {"_FIF",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_FIX",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_FPS",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_FSL",     1,      0},                        /* Acpi 4.0 */
    -    {"_FST",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_GAI",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_GHL",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_GL_",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_GLK",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_GPD",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_GPE",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_GRA",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_GSB",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_GTF",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_GTM",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_GTS",     1,      0},
    -    {"_HE_",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_HID",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_HOT",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_HPP",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_HPX",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_IFT",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_INI",     0,      0},
    -    {"_INT",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_IRC",     0,      0},
    -    {"_LCK",     1,      0},
    -    {"_LEN",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_LID",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_LL_",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_MAF",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_MAT",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_MAX",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_MBM",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_MEM",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_MIF",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_MIN",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_MLS",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_MSG",     1,      0},
    -    {"_MSM",     4,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_MTP",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_NTT",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_OFF",     0,      0},
    -    {"_ON_",     0,      0},
    -    {"_OS_",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_OSC",     4,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_OSI",     1,      ASL_RSVD_RETURN_VALUE},
    -    {"_OST",     3,      0},                        /* Acpi 3.0 */
    -    {"_PAI",     1,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PCL",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PCT",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PDC",     1,      0},
    -    {"_PDL",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PIC",     1,      0},
    -    {"_PIF",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PLD",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_PMC",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PMD",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PMM",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PPC",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PPE",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_PR0",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PR1",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PR2",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PR3",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PRL",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PRS",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PRT",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PRW",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PS0",     0,      0},
    -    {"_PS1",     0,      0},
    -    {"_PS2",     0,      0},
    -    {"_PS3",     0,      0},
    -    {"_PSC",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PSD",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_PSL",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PSR",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PSS",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PSV",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PSW",     1,      0},
    -    {"_PTC",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_PTP",     2,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PTS",     1,      0},
    -    {"_PUR",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_PXM",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_RBO",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_RBW",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_REG",     2,      0},
    -    {"_REV",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_RMV",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_RNG",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_ROM",     2,      ASL_RSVD_RETURN_VALUE},
    -    {"_RT_",     0,      ASL_RSVD_RESOURCE_NAME},   /* Acpi 3.0 */
    -    {"_RTV",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_RW_",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_S0_",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S1_",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S2_",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S3_",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S4_",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S5_",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S1D",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S2D",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S3D",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S4D",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_S0W",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_S1W",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_S2W",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_S3W",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_S4W",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_SB_",     0,      ASL_RSVD_SCOPE},
    -    {"_SBS",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_SCP",     0x13,   0},                        /* Acpi 1.0 - one arg; Acpi 3.0 - three args */
    -    {"_SDD",     1,      0},                        /* Acpi 3.0 */
    -    {"_SEG",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_SHL",     1,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_SHR",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_SI_",     0,      ASL_RSVD_SCOPE},
    -    {"_SIZ",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_SLI",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_SPD",     1,      ASL_RSVD_RETURN_VALUE},
    -    {"_SRS",     1,      0},
    -    {"_SRV",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_SST",     1,      0},
    -    {"_STA",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_STM",     3,      0},
    -    {"_STP",     2,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_STR",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_STV",     2,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_SUN",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_SWS",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_TC1",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_TC2",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_TDL",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0b */
    -    {"_TIP",     1,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_TIV",     1,      ASL_RSVD_RETURN_VALUE},    /* Acpi 4.0 */
    -    {"_TMP",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_TPC",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_TPT",     1,      0},                        /* Acpi 3.0 */
    -    {"_TRA",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_TRS",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_TRT",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_TSD",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_TSF",     0,      ASL_RSVD_RESOURCE_NAME},   /* Acpi 3.0 */
    -    {"_TSP",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_TSS",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_TST",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_TTP",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_TTS",     1,      0},                        /* Acpi 3.0 */
    -    {"_TYP",     0,      ASL_RSVD_RESOURCE_NAME},
    -    {"_TZ_",     0,      ASL_RSVD_SCOPE},
    -    {"_TZD",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_TZM",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_TZP",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_UID",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_UPC",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_UPD",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_UPP",     0,      ASL_RSVD_RETURN_VALUE},    /* Acpi 3.0 */
    -    {"_VPO",     0,      ASL_RSVD_RETURN_VALUE},
    -    {"_WAK",     1,      ASL_RSVD_RETURN_VALUE},
    -    {"_WDG",     0,      ASL_RSVD_RETURN_VALUE},    /* MS Extension */
    -    {"_WED",     1,      ASL_RSVD_RETURN_VALUE},    /* MS Extension */
    -    {NULL,       0,      0},
    -};
    -
    -
     /*******************************************************************************
      *
      * DATA STRUCTURE:  AslKeywordMapping
    diff --git a/sys/contrib/dev/acpica/compiler/aslpredef.c b/sys/contrib/dev/acpica/compiler/aslpredef.c
    new file mode 100644
    index 00000000000..b9632f9c6e1
    --- /dev/null
    +++ b/sys/contrib/dev/acpica/compiler/aslpredef.c
    @@ -0,0 +1,799 @@
    +/******************************************************************************
    + *
    + * Module Name: aslpredef - support for ACPI predefined names
    + *
    + *****************************************************************************/
    +
    +/******************************************************************************
    + *
    + * 1. Copyright Notice
    + *
    + * Some or all of this work - Copyright (c) 1999 - 2010, 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.
    + *
    + *****************************************************************************/
    +
    +#define ACPI_CREATE_PREDEFINED_TABLE
    +
    +#include 
    +#include "aslcompiler.y.h"
    +#include 
    +#include 
    +#include 
    +
    +
    +#define _COMPONENT          ACPI_COMPILER
    +        ACPI_MODULE_NAME    ("aslpredef")
    +
    +
    +/* Local prototypes */
    +
    +static UINT32
    +ApCheckForSpecialName (
    +    ACPI_PARSE_OBJECT       *Op,
    +    char                    *Name);
    +
    +static void
    +ApCheckObjectType (
    +    ACPI_PARSE_OBJECT       *Op,
    +    UINT32                  ExpectedBtypes);
    +
    +static void
    +ApGetExpectedTypes (
    +    char                    *Buffer,
    +    UINT32                  ExpectedBtypes);
    +
    +
    +/*
    + * Names for the types that can be returned by the predefined objects.
    + * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
    + */
    +static const char   *AcpiRtypeNames[] =
    +{
    +    "/Integer",
    +    "/String",
    +    "/Buffer",
    +    "/Package",
    +    "/Reference",
    +};
    +
    +/*
    + * Predefined names for use in Resource Descriptors. These names do not
    + * appear in the global Predefined Name table (since these names never
    + * appear in actual AML byte code, only in the original ASL)
    + */
    +static const ACPI_PREDEFINED_INFO      ResourceNames[] = {
    +    {{"_ALN",     0,      0}},
    +    {{"_ASI",     0,      0}},
    +    {{"_ASZ",     0,      0}},
    +    {{"_ATT",     0,      0}},
    +    {{"_BAS",     0,      0}},
    +    {{"_BM_",     0,      0}},
    +    {{"_DEC",     0,      0}},
    +    {{"_GRA",     0,      0}},
    +    {{"_HE_",     0,      0}},
    +    {{"_INT",     0,      0}},
    +    {{"_LEN",     0,      0}},
    +    {{"_LL_",     0,      0}},
    +    {{"_MAF",     0,      0}},
    +    {{"_MAX",     0,      0}},
    +    {{"_MEM",     0,      0}},
    +    {{"_MIF",     0,      0}},
    +    {{"_MIN",     0,      0}},
    +    {{"_MTP",     0,      0}},
    +    {{"_RBO",     0,      0}},
    +    {{"_RBW",     0,      0}},
    +    {{"_RNG",     0,      0}},
    +    {{"_RT_",     0,      0}},  /* Acpi 3.0 */
    +    {{"_RW_",     0,      0}},
    +    {{"_SHR",     0,      0}},
    +    {{"_SIZ",     0,      0}},
    +    {{"_TRA",     0,      0}},
    +    {{"_TRS",     0,      0}},
    +    {{"_TSF",     0,      0}},  /* Acpi 3.0 */
    +    {{"_TTP",     0,      0}},
    +    {{"_TYP",     0,      0}},
    +    {{{0,0,0,0},  0,      0}}   /* Table terminator */
    +};
    +
    +static const ACPI_PREDEFINED_INFO      ScopeNames[] = {
    +    {{"_SB_",     0,      0}},
    +    {{"_SI_",     0,      0}},
    +    {{"_TZ_",     0,      0}},
    +    {{{0,0,0,0},  0,      0}}   /* Table terminator */
    +};
    +
    +
    +/*******************************************************************************
    + *
    + * FUNCTION:    ApCheckForPredefinedMethod
    + *
    + * PARAMETERS:  Op              - A parse node of type "METHOD".
    + *              MethodInfo      - Saved info about this method
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: If method is a predefined name, check that the number of
    + *              arguments and the return type (returns a value or not)
    + *              is correct.
    + *
    + ******************************************************************************/
    +
    +void
    +ApCheckForPredefinedMethod (
    +    ACPI_PARSE_OBJECT       *Op,
    +    ASL_METHOD_INFO         *MethodInfo)
    +{
    +    UINT32                  Index;
    +    UINT32                  RequiredArgsCurrent;
    +    UINT32                  RequiredArgsOld;
    +
    +
    +    /* Check for a match against the predefined name list */
    +
    +    Index = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
    +
    +    switch (Index)
    +    {
    +    case ACPI_NOT_RESERVED_NAME:        /* No underscore or _Txx or _xxx name not matched */
    +    case ACPI_PREDEFINED_NAME:          /* Resource Name or reserved scope name */
    +    case ACPI_COMPILER_RESERVED_NAME:   /* A _Txx that was not emitted by compiler */
    +
    +        /* Just return, nothing to do */
    +        break;
    +
    +
    +    case ACPI_EVENT_RESERVED_NAME:      /* _Lxx, _Exx, and _Qxx methods */
    +
    +        Gbl_ReservedMethods++;
    +
    +        /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
    +
    +        if (MethodInfo->NumArguments != 0)
    +        {
    +            sprintf (MsgBuffer, "%s requires %d", Op->Asl.ExternalName, 0);
    +
    +            AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
    +                MsgBuffer);
    +        }
    +        break;
    +
    +
    +    default:
    +        /*
    +         * Matched a predefined method name
    +         *
    +         * Validate the ASL-defined argument count. Allow two different legal
    +         * arg counts.
    +         */
    +        Gbl_ReservedMethods++;
    +
    +        RequiredArgsCurrent = PredefinedNames[Index].Info.ParamCount & 0x0F;
    +        RequiredArgsOld = PredefinedNames[Index].Info.ParamCount >> 4;
    +
    +        if ((MethodInfo->NumArguments != RequiredArgsCurrent) &&
    +            (MethodInfo->NumArguments != RequiredArgsOld))
    +        {
    +            sprintf (MsgBuffer, "%4.4s requires %d",
    +                PredefinedNames[Index].Info.Name, RequiredArgsCurrent);
    +
    +            if (MethodInfo->NumArguments > RequiredArgsCurrent)
    +            {
    +                AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
    +                    MsgBuffer);
    +            }
    +            else
    +            {
    +                AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
    +                    MsgBuffer);
    +            }
    +        }
    +
    +        /*
    +         * Check if method returns no value, but the predefined name is
    +         * required to return a value
    +         */
    +        if (MethodInfo->NumReturnNoValue &&
    +            PredefinedNames[Index].Info.ExpectedBtypes)
    +        {
    +            ApGetExpectedTypes (StringBuffer,
    +                PredefinedNames[Index].Info.ExpectedBtypes);
    +
    +            sprintf (MsgBuffer, "%s required for %4.4s",
    +                StringBuffer, PredefinedNames[Index].Info.Name);
    +
    +            AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op,
    +                MsgBuffer);
    +        }
    +        break;
    +    }
    +}
    +
    +
    +/*******************************************************************************
    + *
    + * FUNCTION:    ApCheckPredefinedReturnValue
    + *
    + * PARAMETERS:  Op              - A parse node of type "RETURN".
    + *              MethodInfo      - Saved info about this method
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: If method is a predefined name, attempt to validate the return
    + *              value. Only "static" types can be validated - a simple return
    + *              of an integer/string/buffer/package or a named reference to
    + *              a static object. Values such as a Localx or Argx or a control
    + *              method invocation are not checked.
    + *
    + ******************************************************************************/
    +
    +void
    +ApCheckPredefinedReturnValue (
    +    ACPI_PARSE_OBJECT       *Op,
    +    ASL_METHOD_INFO         *MethodInfo)
    +{
    +    UINT32                  Index;
    +    ACPI_PARSE_OBJECT       *ReturnValueOp;
    +
    +
    +    /* Check parent method for a match against the predefined name list */
    +
    +    Index = ApCheckForPredefinedName (MethodInfo->Op,
    +                MethodInfo->Op->Asl.NameSeg);
    +
    +    switch (Index)
    +    {
    +    case ACPI_NOT_RESERVED_NAME:        /* No underscore or _Txx or _xxx name not matched */
    +    case ACPI_PREDEFINED_NAME:          /* Resource Name or reserved scope name */
    +    case ACPI_COMPILER_RESERVED_NAME:   /* A _Txx that was not emitted by compiler */
    +    case ACPI_EVENT_RESERVED_NAME:      /* _Lxx, _Exx, and _Qxx methods */
    +
    +        /* Just return, nothing to do */
    +        return;
    +
    +    default: /* a real predefined ACPI name */
    +
    +        /* Exit if no return value expected */
    +
    +        if (!PredefinedNames[Index].Info.ExpectedBtypes)
    +        {
    +            return;
    +        }
    +
    +        /* Get the object returned, it is the next argument */
    +
    +        ReturnValueOp = Op->Asl.Child;
    +        switch (ReturnValueOp->Asl.ParseOpcode)
    +        {
    +        case PARSEOP_ZERO:
    +        case PARSEOP_ONE:
    +        case PARSEOP_ONES:
    +        case PARSEOP_INTEGER:
    +        case PARSEOP_STRING_LITERAL:
    +        case PARSEOP_BUFFER:
    +        case PARSEOP_PACKAGE:
    +
    +            /* Static data return object - check against expected type */
    +
    +            ApCheckObjectType (ReturnValueOp,
    +                PredefinedNames[Index].Info.ExpectedBtypes);
    +            break;
    +
    +        default:
    +
    +            /*
    +             * All other ops are very difficult or impossible to typecheck at
    +             * compile time. These include all Localx, Argx, and method
    +             * invocations. Also, NAMESEG and NAMESTRING because the type of
    +             * any named object can be changed at runtime (for example,
    +             * CopyObject will change the type of the target object.)
    +             */
    +            break;
    +        }
    +    }
    +}
    +
    +
    +/*******************************************************************************
    + *
    + * FUNCTION:    ApCheckForPredefinedObject
    + *
    + * PARAMETERS:  Op              - A parse node
    + *              Name            - The ACPI name to be checked
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: Check for a predefined name for a static object (created via
    + *              the ASL Name operator). If it is a predefined ACPI name, ensure
    + *              that the name does not require any arguments (which would
    + *              require a control method implemenation of the name), and that
    + *              the type of the object is one of the expected types for the
    + *              predefined name.
    + *
    + ******************************************************************************/
    +
    +void
    +ApCheckForPredefinedObject (
    +    ACPI_PARSE_OBJECT       *Op,
    +    char                    *Name)
    +{
    +    UINT32                  Index;
    +
    +
    +    /*
    +     * Check for a real predefined name -- not a resource descriptor name
    +     * or a predefined scope name
    +     */
    +    Index = ApCheckForPredefinedName (Op, Name);
    +    if (Index > ACPI_VALID_RESERVED_NAME_MAX)
    +    {
    +        return;
    +    }
    +
    +    /*
    +     * We found a matching predefind name.
    +     * Check if this predefined name requires input arguments
    +     */
    +    if (PredefinedNames[Index].Info.ParamCount > 0)
    +    {
    +        /*
    +         * This predefined name must always be defined as a control
    +         * method because it is required to have input arguments.
    +         */
    +        AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
    +            "with arguments");
    +    }
    +
    +    /* Typecheck the actual object, it is the next argument */
    +
    +    ApCheckObjectType (Op->Asl.Child->Asl.Next,
    +        PredefinedNames[Index].Info.ExpectedBtypes);
    +}
    +
    +
    +/*******************************************************************************
    + *
    + * FUNCTION:    ApCheckForPredefinedName
    + *
    + * PARAMETERS:  Op              - A parse node
    + *              Name            - NameSeg to check
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: Check a NameSeg against the reserved list.
    + *
    + ******************************************************************************/
    +
    +UINT32
    +ApCheckForPredefinedName (
    +    ACPI_PARSE_OBJECT       *Op,
    +    char                    *Name)
    +{
    +    UINT32                  i;
    +
    +
    +    if (Name[0] == 0)
    +    {
    +        AcpiOsPrintf ("Found a null name, external = %s\n",
    +            Op->Asl.ExternalName);
    +    }
    +
    +    /* All reserved names are prefixed with a single underscore */
    +
    +    if (Name[0] != '_')
    +    {
    +        return (ACPI_NOT_RESERVED_NAME);
    +    }
    +
    +    /* Check for a standard predefined method name */
    +
    +    for (i = 0; PredefinedNames[i].Info.Name[0]; i++)
    +    {
    +        if (ACPI_COMPARE_NAME (Name, PredefinedNames[i].Info.Name))
    +        {
    +            /* Return index into predefined array */
    +            return (i);
    +        }
    +    }
    +
    +    /* Check for resource names and predefined scope names */
    +
    +    for (i = 0; ResourceNames[i].Info.Name[0]; i++)
    +    {
    +        if (ACPI_COMPARE_NAME (Name, ResourceNames[i].Info.Name))
    +        {
    +            return (ACPI_PREDEFINED_NAME);
    +        }
    +    }
    +
    +    for (i = 0; ScopeNames[i].Info.Name[0]; i++)
    +    {
    +        if (ACPI_COMPARE_NAME (Name, ScopeNames[i].Info.Name))
    +        {
    +            return (ACPI_PREDEFINED_NAME);
    +        }
    +    }
    +
    +    /* Check for _Lxx, _Exx, _Qxx, _T_x. Warning if unknown predefined name */
    +
    +    return (ApCheckForSpecialName (Op, Name));
    +}
    +
    +
    +/*******************************************************************************
    + *
    + * FUNCTION:    ApCheckForSpecialName
    + *
    + * PARAMETERS:  Op              - A parse node
    + *              Name            - NameSeg to check
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: Check for the "special" predefined names -
    + *              _Lxx, _Exx, _Qxx, and _T_x
    + *
    + ******************************************************************************/
    +
    +static UINT32
    +ApCheckForSpecialName (
    +    ACPI_PARSE_OBJECT       *Op,
    +    char                    *Name)
    +{
    +
    +    /*
    +     * Check for the "special" predefined names. We know the first char is an
    +     * underscore already.
    +     *   GPE:  _Lxx
    +     *   GPE:  _Exx
    +     *   EC:   _Qxx
    +     */
    +    if ((Name[1] == 'L') ||
    +        (Name[1] == 'E') ||
    +        (Name[1] == 'Q'))
    +    {
    +        /* The next two characters must be hex digits */
    +
    +        if ((isxdigit ((int) Name[2])) &&
    +            (isxdigit ((int) Name[3])))
    +        {
    +            return (ACPI_EVENT_RESERVED_NAME);
    +        }
    +    }
    +
    +    /* Check for the names reserved for the compiler itself: _T_x */
    +
    +    else if ((Op->Asl.ExternalName[1] == 'T') &&
    +             (Op->Asl.ExternalName[2] == '_'))
    +    {
    +        /* Ignore if actually emitted by the compiler */
    +
    +        if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
    +        {
    +            return (ACPI_NOT_RESERVED_NAME);
    +        }
    +
    +        /*
    +         * Was not actually emitted by the compiler. This is a special case,
    +         * however. If the ASL code being compiled was the result of a
    +         * dissasembly, it may possibly contain valid compiler-emitted names
    +         * of the form "_T_x". We don't want to issue an error or even a
    +         * warning and force the user to manually change the names. So, we
    +         * will issue a remark instead.
    +         */
    +        AslError (ASL_REMARK, ASL_MSG_COMPILER_RESERVED, Op, Op->Asl.ExternalName);
    +        return (ACPI_COMPILER_RESERVED_NAME);
    +    }
    +
    +    /*
    +     * The name didn't match any of the known predefined names. Flag it as a
    +     * warning, since the entire namespace starting with an underscore is
    +     * reserved by the ACPI spec.
    +     */
    +    AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
    +        Op->Asl.ExternalName);
    +
    +    return (ACPI_NOT_RESERVED_NAME);
    +}
    +
    +
    +/*******************************************************************************
    + *
    + * FUNCTION:    ApCheckObjectType
    + *
    + * PARAMETERS:  Op              - Current parse node
    + *              ExpectedBtypes  - Bitmap of expected return type(s)
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: Check if the object type is one of the types that is expected
    + *              by the predefined name. Only a limited number of object types
    + *              can be returned by the predefined names.
    + *
    + ******************************************************************************/
    +
    +static void
    +ApCheckObjectType (
    +    ACPI_PARSE_OBJECT       *Op,
    +    UINT32                  ExpectedBtypes)
    +{
    +    UINT32                  ReturnBtype;
    +
    +
    +    switch (Op->Asl.ParseOpcode)
    +    {
    +    case PARSEOP_ZERO:
    +    case PARSEOP_ONE:
    +    case PARSEOP_ONES:
    +    case PARSEOP_INTEGER:
    +        ReturnBtype = ACPI_RTYPE_INTEGER;
    +        break;
    +
    +    case PARSEOP_BUFFER:
    +        ReturnBtype = ACPI_RTYPE_BUFFER;
    +        break;
    +
    +    case PARSEOP_STRING_LITERAL:
    +        ReturnBtype = ACPI_RTYPE_STRING;
    +        break;
    +
    +    case PARSEOP_PACKAGE:
    +        ReturnBtype = ACPI_RTYPE_PACKAGE;
    +        break;
    +
    +    default:
    +        /* Not one of the supported object types */
    +
    +        goto TypeErrorExit;
    +    }
    +
    +    /* Exit if the object is one of the expected types */
    +
    +    if (ReturnBtype & ExpectedBtypes)
    +    {
    +        return;
    +    }
    +
    +
    +TypeErrorExit:
    +
    +    /* Format the expected types and emit an error message */
    +
    +    ApGetExpectedTypes (StringBuffer, ExpectedBtypes);
    +
    +    sprintf (MsgBuffer, "found %s, requires %s",
    +        UtGetOpName (Op->Asl.ParseOpcode), StringBuffer);
    +
    +    AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op,
    +        MsgBuffer);
    +}
    +
    +
    +/*******************************************************************************
    + *
    + * FUNCTION:    ApDisplayReservedNames
    + *
    + * PARAMETERS:  None
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: Dump information about the ACPI predefined names and predefined
    + *              resource descriptor names.
    + *
    + ******************************************************************************/
    +
    +void
    +ApDisplayReservedNames (
    +    void)
    +{
    +    const ACPI_PREDEFINED_INFO  *ThisName;
    +    char                        TypeBuffer[48]; /* Room for 5 types */
    +    UINT32                      Count;
    +
    +
    +    /*
    +     * Predefined names/methods
    +     */
    +    printf ("\nPredefined Name Information\n\n");
    +
    +    Count = 0;
    +    ThisName = PredefinedNames;
    +    while (ThisName->Info.Name[0])
    +    {
    +        printf ("%4.4s    Requires %d arguments, ",
    +            ThisName->Info.Name, ThisName->Info.ParamCount & 0x0F);
    +
    +        if (ThisName->Info.ExpectedBtypes)
    +        {
    +            ApGetExpectedTypes (TypeBuffer, ThisName->Info.ExpectedBtypes);
    +            printf ("Must return: %s\n", TypeBuffer);
    +        }
    +        else
    +        {
    +            printf ("No return value\n");
    +        }
    +
    +        /*
    +         * Skip next entry in the table if this name returns a Package
    +         * (next entry contains the package info)
    +         */
    +        if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
    +        {
    +            ThisName++;
    +        }
    +
    +        Count++;
    +        ThisName++;
    +    }
    +
    +    printf ("%u Predefined Names are recognized\n", Count);
    +
    +    /*
    +     * Resource Descriptor names
    +     */
    +    printf ("\nResource Descriptor Predefined Names\n\n");
    +
    +    Count = 0;
    +    ThisName = ResourceNames;
    +    while (ThisName->Info.Name[0])
    +    {
    +        printf ("%4.4s    Resource Descriptor\n", ThisName->Info.Name);
    +        Count++;
    +        ThisName++;
    +    }
    +
    +    printf ("%u Resource Descriptor Names are recognized\n", Count);
    +
    +    /*
    +     * Predefined scope names
    +     */
    +    printf ("\nPredefined Scope Names\n\n");
    +
    +    ThisName = ScopeNames;
    +    while (ThisName->Info.Name[0])
    +    {
    +        printf ("%4.4s    Scope\n", ThisName->Info.Name);
    +        ThisName++;
    +    }
    +}
    +
    +
    +/*******************************************************************************
    + *
    + * FUNCTION:    ApGetExpectedTypes
    + *
    + * PARAMETERS:  Buffer              - Where the formatted string is returned
    + *              ExpectedBTypes      - Bitfield of expected data types
    + *
    + * RETURN:      None, formatted string
    + *
    + * DESCRIPTION: Format the expected object types into a printable string.
    + *
    + ******************************************************************************/
    +
    +static void
    +ApGetExpectedTypes (
    +    char                        *Buffer,
    +    UINT32                      ExpectedBtypes)
    +{
    +    UINT32                      ThisRtype;
    +    UINT32                      i;
    +    UINT32                      j;
    +
    +
    +    j = 1;
    +    Buffer[0] = 0;
    +    ThisRtype = ACPI_RTYPE_INTEGER;
    +
    +    for (i = 0; i < ACPI_NUM_RTYPES; i++)
    +    {
    +        /* If one of the expected types, concatenate the name of this type */
    +
    +        if (ExpectedBtypes & ThisRtype)
    +        {
    +            ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
    +            j = 0;              /* Use name separator from now on */
    +        }
    +        ThisRtype <<= 1;    /* Next Rtype */
    +    }
    +}
    +
    diff --git a/sys/contrib/dev/acpica/compiler/aslstubs.c b/sys/contrib/dev/acpica/compiler/aslstubs.c
    index ebc0a7d321a..b2fb69a96fb 100644
    --- a/sys/contrib/dev/acpica/compiler/aslstubs.c
    +++ b/sys/contrib/dev/acpica/compiler/aslstubs.c
    @@ -243,11 +243,13 @@ AcpiEvInitializeRegion (
         return (AE_OK);
     }
     
    -ACPI_STATUS
    -AcpiEvCheckForWakeOnlyGpe (
    -    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
    +void
    +AcpiExDoDebugObject (
    +    ACPI_OPERAND_OBJECT     *SourceDesc,
    +    UINT32                  Level,
    +    UINT32                  Index)
     {
    -    return (AE_OK);
    +    return;
     }
     
     ACPI_STATUS
    @@ -276,7 +278,6 @@ AcpiExLoadTableOp (
         return (AE_SUPPORT);
     }
     
    -
     ACPI_STATUS
     AcpiExUnloadTable (
         ACPI_OPERAND_OBJECT     *DdbHandle)
    diff --git a/sys/contrib/dev/acpica/compiler/asltypes.h b/sys/contrib/dev/acpica/compiler/asltypes.h
    index 9e1d426d2b7..30b8fdfe7d0 100644
    --- a/sys/contrib/dev/acpica/compiler/asltypes.h
    +++ b/sys/contrib/dev/acpica/compiler/asltypes.h
    @@ -188,21 +188,6 @@ typedef struct asl_mapping_entry
     } ASL_MAPPING_ENTRY;
     
     
    -/* An entry in the Reserved Name information table */
    -
    -#define ASL_RSVD_RETURN_VALUE   0x01
    -#define ASL_RSVD_RESOURCE_NAME  0x02
    -#define ASL_RSVD_SCOPE          0x04
    -
    -typedef struct asl_reserved_info
    -{
    -    char                        *Name;
    -    UINT8                       NumArguments;
    -    UINT8                       Flags;
    -
    -} ASL_RESERVED_INFO;
    -
    -
     /* Parse tree walk info structure */
     
     typedef struct asl_walk_info
    @@ -522,7 +507,7 @@ char                        *AslMessages [] = {
     /*    ASL_MSG_RESERVED_ARG_COUNT_HI */      "Reserved method has too many arguments",
     /*    ASL_MSG_RESERVED_ARG_COUNT_LO */      "Reserved method has too few arguments",
     /*    ASL_MSG_RESERVED_METHOD */            "Reserved name must be a control method",
    -/*    ASL_MSG_RESERVED_OPERAND_TYPE */      "Invalid operand type for reserved name, must be",
    +/*    ASL_MSG_RESERVED_OPERAND_TYPE */      "Invalid object type for reserved name",
     /*    ASL_MSG_RESERVED_RETURN_VALUE */      "Reserved method must return a value",
     /*    ASL_MSG_RESERVED_USE */               "Invalid use of reserved name",
     /*    ASL_MSG_RESERVED_WORD */              "Use of reserved name",
    diff --git a/sys/contrib/dev/acpica/debugger/dbdisply.c b/sys/contrib/dev/acpica/debugger/dbdisply.c
    index 179f6f66de9..41094891ad7 100644
    --- a/sys/contrib/dev/acpica/debugger/dbdisply.c
    +++ b/sys/contrib/dev/acpica/debugger/dbdisply.c
    @@ -848,13 +848,12 @@ AcpiDbDisplayGpes (
                     Block, GpeBlock, GpeBlock->Node, Buffer);
     
                 AcpiOsPrintf ("    Registers:    %u (%u GPEs)\n",
    -                GpeBlock->RegisterCount,
    -                ACPI_MUL_8 (GpeBlock->RegisterCount));
    +                GpeBlock->RegisterCount, GpeBlock->GpeCount);
     
    -            AcpiOsPrintf ("    GPE range:    0x%X to 0x%X\n",
    +            AcpiOsPrintf ("    GPE range:    0x%X to 0x%X on interrupt %u\n",
                     GpeBlock->BlockBaseNumber,
    -                GpeBlock->BlockBaseNumber +
    -                    (GpeBlock->RegisterCount * 8) -1);
    +                GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1),
    +                GpeXruptInfo->InterruptNumber);
     
                 AcpiOsPrintf (
                     "    RegisterInfo: %p  Status %8.8X%8.8X Enable %8.8X%8.8X\n",
    @@ -871,9 +870,12 @@ AcpiDbDisplayGpes (
                     GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
     
                     AcpiOsPrintf (
    -                    "    Reg %u:  WakeEnable %2.2X, RunEnable %2.2X  Status %8.8X%8.8X Enable %8.8X%8.8X\n",
    -                    i, GpeRegisterInfo->EnableForWake,
    +                    "    Reg %u: (GPE %.2X-%.2X)  RunEnable %2.2X WakeEnable %2.2X"
    +                    " Status %8.8X%8.8X Enable %8.8X%8.8X\n",
    +                    i, GpeRegisterInfo->BaseGpeNumber,
    +                    GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
                         GpeRegisterInfo->EnableForRun,
    +                    GpeRegisterInfo->EnableForWake,
                         ACPI_FORMAT_UINT64 (GpeRegisterInfo->StatusAddress.Address),
                         ACPI_FORMAT_UINT64 (GpeRegisterInfo->EnableAddress.Address));
     
    @@ -886,17 +888,19 @@ AcpiDbDisplayGpes (
     
                         if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
                         {
    -                        /* This GPE is not used (no method or handler) */
    +                        /* This GPE is not used (no method or handler), ignore it */
     
                             continue;
                         }
     
                         AcpiOsPrintf (
    -                        "        GPE %.3X: %p Flags %2.2X: ",
    -                        GpeBlock->BlockBaseNumber + GpeIndex,
    -                        GpeEventInfo,
    +                        "        GPE %.2X: %p  RunRefs %2.2X   WakeRefs %2.2X Flags %2.2X (",
    +                        GpeBlock->BlockBaseNumber + GpeIndex, GpeEventInfo,
    +                        GpeEventInfo->RuntimeCount, GpeEventInfo->WakeupCount,
                             GpeEventInfo->Flags);
     
    +                    /* Decode the flags byte */
    +
                         if (GpeEventInfo->Flags & ACPI_GPE_LEVEL_TRIGGERED)
                         {
                             AcpiOsPrintf ("Level, ");
    @@ -906,38 +910,13 @@ AcpiDbDisplayGpes (
                             AcpiOsPrintf ("Edge,  ");
                         }
     
    -                    switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
    +                    if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
                         {
    -                    case ACPI_GPE_TYPE_WAKE:
    -                        AcpiOsPrintf ("WakeOnly: ");
    -                        break;
    -                    case ACPI_GPE_TYPE_RUNTIME:
    -                        AcpiOsPrintf (" RunOnly: ");
    -                        break;
    -                    case ACPI_GPE_TYPE_WAKE_RUN:
    -                        AcpiOsPrintf (" WakeRun: ");
    -                        break;
    -                    default:
    -                        AcpiOsPrintf (" NotUsed: ");
    -                        break;
    -                    }
    -
    -                    if (GpeEventInfo->Flags & ACPI_GPE_WAKE_ENABLED)
    -                    {
    -                        AcpiOsPrintf ("[Wake 1 ");
    +                        AcpiOsPrintf ("CanWake, ");
                         }
                         else
                         {
    -                        AcpiOsPrintf ("[Wake 0 ");
    -                    }
    -
    -                    if (GpeEventInfo->Flags & ACPI_GPE_RUN_ENABLED)
    -                    {
    -                        AcpiOsPrintf ("Run 1], ");
    -                    }
    -                    else
    -                    {
    -                        AcpiOsPrintf ("Run 0], ");
    +                        AcpiOsPrintf ("RunOnly, ");
                         }
     
                         switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
    @@ -957,7 +936,7 @@ AcpiDbDisplayGpes (
                             break;
                         }
     
    -                    AcpiOsPrintf ("\n");
    +                    AcpiOsPrintf (")\n");
                     }
                 }
                 Block++;
    diff --git a/sys/contrib/dev/acpica/dispatcher/dsfield.c b/sys/contrib/dev/acpica/dispatcher/dsfield.c
    index e33d6a865be..d0240b06d65 100644
    --- a/sys/contrib/dev/acpica/dispatcher/dsfield.c
    +++ b/sys/contrib/dev/acpica/dispatcher/dsfield.c
    @@ -424,7 +424,7 @@ AcpiDsGetFieldNames (
             default:
     
                 ACPI_ERROR ((AE_INFO,
    -                "Invalid opcode in field list: %X", Arg->Common.AmlOpcode));
    +                "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode));
                 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
             }
     
    diff --git a/sys/contrib/dev/acpica/dispatcher/dsmethod.c b/sys/contrib/dev/acpica/dispatcher/dsmethod.c
    index e54bb608c80..37cb867708b 100644
    --- a/sys/contrib/dev/acpica/dispatcher/dsmethod.c
    +++ b/sys/contrib/dev/acpica/dispatcher/dsmethod.c
    @@ -318,7 +318,7 @@ AcpiDsBeginMethodExecution (
                 (WalkState->Thread->CurrentSyncLevel > ObjDesc->Method.Mutex->Mutex.SyncLevel))
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%d)",
    +                "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)",
                     AcpiUtGetNodeName (MethodNode),
                     WalkState->Thread->CurrentSyncLevel));
     
    diff --git a/sys/contrib/dev/acpica/dispatcher/dsmthdat.c b/sys/contrib/dev/acpica/dispatcher/dsmthdat.c
    index 8d2342f5f7d..593695e5cdf 100644
    --- a/sys/contrib/dev/acpica/dispatcher/dsmthdat.c
    +++ b/sys/contrib/dev/acpica/dispatcher/dsmthdat.c
    @@ -363,7 +363,7 @@ AcpiDsMethodDataGetNode (
             if (Index > ACPI_METHOD_MAX_LOCAL)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Local index %d is invalid (max %d)",
    +                "Local index %u is invalid (max %u)",
                     Index, ACPI_METHOD_MAX_LOCAL));
                 return_ACPI_STATUS (AE_AML_INVALID_INDEX);
             }
    @@ -378,7 +378,7 @@ AcpiDsMethodDataGetNode (
             if (Index > ACPI_METHOD_MAX_ARG)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Arg index %d is invalid (max %d)",
    +                "Arg index %u is invalid (max %u)",
                     Index, ACPI_METHOD_MAX_ARG));
                 return_ACPI_STATUS (AE_AML_INVALID_INDEX);
             }
    @@ -389,7 +389,7 @@ AcpiDsMethodDataGetNode (
             break;
     
         default:
    -        ACPI_ERROR ((AE_INFO, "Type %d is invalid", Type));
    +        ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
             return_ACPI_STATUS (AE_TYPE);
         }
     
    @@ -540,7 +540,7 @@ AcpiDsMethodDataGetValue (
             case ACPI_REFCLASS_ARG:
     
                 ACPI_ERROR ((AE_INFO,
    -                "Uninitialized Arg[%d] at node %p",
    +                "Uninitialized Arg[%u] at node %p",
                     Index, Node));
     
                 return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
    @@ -555,7 +555,7 @@ AcpiDsMethodDataGetValue (
     
             default:
     
    -            ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: %X", Type));
    +            ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
                 return_ACPI_STATUS (AE_AML_INTERNAL);
             }
         }
    diff --git a/sys/contrib/dev/acpica/dispatcher/dsobject.c b/sys/contrib/dev/acpica/dispatcher/dsobject.c
    index 3e1c45e7037..9669ca98e9c 100644
    --- a/sys/contrib/dev/acpica/dispatcher/dsobject.c
    +++ b/sys/contrib/dev/acpica/dispatcher/dsobject.c
    @@ -365,7 +365,7 @@ AcpiDsBuildInternalBufferObj (
             if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Expecting bytelist, got AML opcode %X in op %p",
    +                "Expecting bytelist, found AML opcode 0x%X in op %p",
                     ByteList->Common.AmlOpcode, ByteList));
     
                 AcpiUtRemoveReference (ObjDesc);
    @@ -599,7 +599,7 @@ AcpiDsBuildInternalPackageObj (
             }
     
             ACPI_INFO ((AE_INFO,
    -            "Actual Package length (0x%X) is larger than NumElements field (0x%X), truncated\n",
    +            "Actual Package length (%u) is larger than NumElements field (%u), truncated\n",
                 i, ElementCount));
         }
         else if (i < ElementCount)
    @@ -609,7 +609,7 @@ AcpiDsBuildInternalPackageObj (
              * Note: this is not an error, the package is padded out with NULLs.
              */
             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    -            "Package List length (0x%X) smaller than NumElements count (0x%X), padded with null elements\n",
    +            "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n",
                 i, ElementCount));
         }
     
    @@ -804,7 +804,7 @@ AcpiDsInitObjectFromOp (
                 default:
     
                     ACPI_ERROR ((AE_INFO,
    -                    "Unknown constant opcode %X", Opcode));
    +                    "Unknown constant opcode 0x%X", Opcode));
                     Status = AE_AML_OPERAND_TYPE;
                     break;
                 }
    @@ -821,7 +821,7 @@ AcpiDsInitObjectFromOp (
     
     
             default:
    -            ACPI_ERROR ((AE_INFO, "Unknown Integer type %X",
    +            ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
                     OpInfo->Type));
                 Status = AE_AML_OPERAND_TYPE;
                 break;
    @@ -902,7 +902,7 @@ AcpiDsInitObjectFromOp (
                 default:
     
                     ACPI_ERROR ((AE_INFO,
    -                    "Unimplemented reference type for AML opcode: %4.4X", Opcode));
    +                    "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));
                     return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
                 }
                 break;
    @@ -912,7 +912,7 @@ AcpiDsInitObjectFromOp (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unimplemented data type: %X",
    +        ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
                 ObjDesc->Common.Type));
     
             Status = AE_AML_OPERAND_TYPE;
    diff --git a/sys/contrib/dev/acpica/dispatcher/dsopcode.c b/sys/contrib/dev/acpica/dispatcher/dsopcode.c
    index b1c6dc36d98..5c6004fbdfe 100644
    --- a/sys/contrib/dev/acpica/dispatcher/dsopcode.c
    +++ b/sys/contrib/dev/acpica/dispatcher/dsopcode.c
    @@ -395,7 +395,7 @@ AcpiDsGetBufferArguments (
         if (!Node)
         {
             ACPI_ERROR ((AE_INFO,
    -            "No pointer back to NS node in buffer obj %p", ObjDesc));
    +            "No pointer back to namespace node in buffer object %p", ObjDesc));
             return_ACPI_STATUS (AE_AML_INTERNAL);
         }
     
    @@ -444,7 +444,7 @@ AcpiDsGetPackageArguments (
         if (!Node)
         {
             ACPI_ERROR ((AE_INFO,
    -            "No pointer back to NS node in package %p", ObjDesc));
    +            "No pointer back to namespace node in package %p", ObjDesc));
             return_ACPI_STATUS (AE_AML_INTERNAL);
         }
     
    @@ -678,7 +678,7 @@ AcpiDsInitBufferField (
         default:
     
             ACPI_ERROR ((AE_INFO,
    -            "Unknown field creation opcode %02x",
    +            "Unknown field creation opcode 0x%02X",
                 AmlOpcode));
             Status = AE_AML_BAD_OPCODE;
             goto Cleanup;
    @@ -690,7 +690,7 @@ AcpiDsInitBufferField (
             (8 * (UINT32) BufferDesc->Buffer.Length))
         {
             ACPI_ERROR ((AE_INFO,
    -            "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)",
    +            "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
                 AcpiUtGetNodeName (ResultDesc),
                 BitOffset + BitCount,
                 AcpiUtGetNodeName (BufferDesc->Buffer.Node),
    @@ -806,7 +806,7 @@ AcpiDsEvalBufferFieldOperands (
                         ACPI_WALK_OPERANDS, WalkState);
         if (ACPI_FAILURE (Status))
         {
    -        ACPI_ERROR ((AE_INFO, "(%s) bad operand(s) (%X)",
    +        ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
                 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
     
             return_ACPI_STATUS (Status);
    @@ -1607,7 +1607,7 @@ AcpiDsExecEndControlOp (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown control opcode=%X Op=%p",
    +        ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
                 Op->Common.AmlOpcode, Op));
     
             Status = AE_AML_BAD_OPCODE;
    diff --git a/sys/contrib/dev/acpica/dispatcher/dswexec.c b/sys/contrib/dev/acpica/dispatcher/dswexec.c
    index cad6f5101f9..61a7e1c0d23 100644
    --- a/sys/contrib/dev/acpica/dispatcher/dswexec.c
    +++ b/sys/contrib/dev/acpica/dispatcher/dswexec.c
    @@ -227,7 +227,7 @@ AcpiDsGetPredicateValue (
         if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
    +            "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
                 ObjDesc, WalkState, ObjDesc->Common.Type));
     
             Status = AE_AML_OPERAND_TYPE;
    @@ -463,7 +463,7 @@ AcpiDsExecEndOp (
     
         if (OpClass == AML_CLASS_UNKNOWN)
         {
    -        ACPI_ERROR ((AE_INFO, "Unknown opcode %X", Op->Common.AmlOpcode));
    +        ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode));
             return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
         }
     
    @@ -783,7 +783,7 @@ AcpiDsExecEndOp (
             default:
     
                 ACPI_ERROR ((AE_INFO,
    -                "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p",
    +                "Unimplemented opcode, class=0x%X type=0x%X Opcode=-0x%X Op=%p",
                     OpClass, OpType, Op->Common.AmlOpcode, Op));
     
                 Status = AE_NOT_IMPLEMENTED;
    diff --git a/sys/contrib/dev/acpica/dispatcher/dswstate.c b/sys/contrib/dev/acpica/dispatcher/dswstate.c
    index 19bb45b3f39..622aef286f6 100644
    --- a/sys/contrib/dev/acpica/dispatcher/dswstate.c
    +++ b/sys/contrib/dev/acpica/dispatcher/dswstate.c
    @@ -277,7 +277,7 @@ AcpiDsResultPush (
         if (!Object)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Null Object! Obj=%p State=%p Num=%X",
    +            "Null Object! Obj=%p State=%p Num=%u",
                 Object, WalkState, WalkState->ResultCount));
             return (AE_BAD_PARAMETER);
         }
    @@ -323,7 +323,7 @@ AcpiDsResultStackPush (
         if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
             ACPI_RESULTS_OBJ_NUM_MAX)
         {
    -        ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%X",
    +        ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u",
                 WalkState, WalkState->ResultSize));
             return (AE_STACK_OVERFLOW);
         }
    @@ -426,7 +426,7 @@ AcpiDsObjStackPush (
         if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Object stack overflow! Obj=%p State=%p #Ops=%X",
    +            "Object stack overflow! Obj=%p State=%p #Ops=%u",
                 Object, WalkState, WalkState->NumOperands));
             return (AE_STACK_OVERFLOW);
         }
    @@ -480,7 +480,7 @@ AcpiDsObjStackPop (
             if (WalkState->NumOperands == 0)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Object stack underflow! Count=%X State=%p #Ops=%X",
    +                "Object stack underflow! Count=%X State=%p #Ops=%u",
                     PopCount, WalkState, WalkState->NumOperands));
                 return (AE_STACK_UNDERFLOW);
             }
    @@ -491,7 +491,7 @@ AcpiDsObjStackPop (
             WalkState->Operands [WalkState->NumOperands] = NULL;
         }
     
    -    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
    +    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
             PopCount, WalkState, WalkState->NumOperands));
     
         return (AE_OK);
    diff --git a/sys/contrib/dev/acpica/events/evevent.c b/sys/contrib/dev/acpica/events/evevent.c
    index 2c41639433c..d743051fcb1 100644
    --- a/sys/contrib/dev/acpica/events/evevent.c
    +++ b/sys/contrib/dev/acpica/events/evevent.c
    @@ -415,7 +415,7 @@ AcpiEvFixedEventDispatch (
                     ACPI_DISABLE_EVENT);
     
             ACPI_ERROR ((AE_INFO,
    -            "No installed handler for fixed event [%08X]",
    +            "No installed handler for fixed event [0x%08X]",
                 Event));
     
             return (ACPI_INTERRUPT_NOT_HANDLED);
    diff --git a/sys/contrib/dev/acpica/events/evgpe.c b/sys/contrib/dev/acpica/events/evgpe.c
    index 48355689fdc..0ece12ca78c 100644
    --- a/sys/contrib/dev/acpica/events/evgpe.c
    +++ b/sys/contrib/dev/acpica/events/evgpe.c
    @@ -132,73 +132,22 @@ AcpiEvAsynchEnableGpe (
         void                    *Context);
     
     
    -/*******************************************************************************
    - *
    - * FUNCTION:    AcpiEvSetGpeType
    - *
    - * PARAMETERS:  GpeEventInfo            - GPE to set
    - *              Type                    - New type
    - *
    - * RETURN:      Status
    - *
    - * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
    - *
    - ******************************************************************************/
    -
    -ACPI_STATUS
    -AcpiEvSetGpeType (
    -    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
    -    UINT8                   Type)
    -{
    -    ACPI_STATUS             Status;
    -
    -
    -    ACPI_FUNCTION_TRACE (EvSetGpeType);
    -
    -
    -    /* Validate type and update register enable masks */
    -
    -    switch (Type)
    -    {
    -    case ACPI_GPE_TYPE_WAKE:
    -    case ACPI_GPE_TYPE_RUNTIME:
    -    case ACPI_GPE_TYPE_WAKE_RUN:
    -        break;
    -
    -    default:
    -        return_ACPI_STATUS (AE_BAD_PARAMETER);
    -    }
    -
    -    /* Disable the GPE if currently enabled */
    -
    -    Status = AcpiEvDisableGpe (GpeEventInfo);
    -
    -    /* Clear the type bits and insert the new Type */
    -
    -    GpeEventInfo->Flags &= ~ACPI_GPE_TYPE_MASK;
    -    GpeEventInfo->Flags |= Type;
    -    return_ACPI_STATUS (Status);
    -}
    -
    -
     /*******************************************************************************
      *
      * FUNCTION:    AcpiEvUpdateGpeEnableMasks
      *
      * PARAMETERS:  GpeEventInfo            - GPE to update
    - *              Type                    - What to do: ACPI_GPE_DISABLE or
    - *                                        ACPI_GPE_ENABLE
      *
      * RETURN:      Status
      *
    - * DESCRIPTION: Updates GPE register enable masks based on the GPE type
    + * DESCRIPTION: Updates GPE register enable masks based upon whether there are
    + *              references (either wake or run) to this GPE
      *
      ******************************************************************************/
     
     ACPI_STATUS
     AcpiEvUpdateGpeEnableMasks (
    -    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
    -    UINT8                   Type)
    +    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
     {
         ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
         UINT8                   RegisterBit;
    @@ -216,36 +165,21 @@ AcpiEvUpdateGpeEnableMasks (
         RegisterBit = (UINT8)
             (1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber));
     
    -    /* 1) Disable case. Simply clear all enable bits */
    +    /* Clear the wake/run bits up front */
     
    -    if (Type == ACPI_GPE_DISABLE)
    +    ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
    +    ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
    +
    +    /* Set the mask bits only if there are references to this GPE */
    +
    +    if (GpeEventInfo->RuntimeCount)
         {
    -        ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
    -        ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
    -        return_ACPI_STATUS (AE_OK);
    +        ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
         }
     
    -    /* 2) Enable case. Set/Clear the appropriate enable bits */
    -
    -    switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
    +    if (GpeEventInfo->WakeupCount)
         {
    -    case ACPI_GPE_TYPE_WAKE:
    -        ACPI_SET_BIT   (GpeRegisterInfo->EnableForWake, RegisterBit);
    -        ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
    -        break;
    -
    -    case ACPI_GPE_TYPE_RUNTIME:
    -        ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
    -        ACPI_SET_BIT   (GpeRegisterInfo->EnableForRun, RegisterBit);
    -        break;
    -
    -    case ACPI_GPE_TYPE_WAKE_RUN:
    -        ACPI_SET_BIT   (GpeRegisterInfo->EnableForWake, RegisterBit);
    -        ACPI_SET_BIT   (GpeRegisterInfo->EnableForRun, RegisterBit);
    -        break;
    -
    -    default:
    -        return_ACPI_STATUS (AE_BAD_PARAMETER);
    +        ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
         }
     
         return_ACPI_STATUS (AE_OK);
    @@ -257,19 +191,19 @@ AcpiEvUpdateGpeEnableMasks (
      * FUNCTION:    AcpiEvEnableGpe
      *
      * PARAMETERS:  GpeEventInfo            - GPE to enable
    - *              WriteToHardware         - Enable now, or just mark data structs
    - *                                        (WAKE GPEs should be deferred)
      *
      * RETURN:      Status
      *
    - * DESCRIPTION: Enable a GPE based on the GPE type
    + * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless
    + *              of type or number of references.
    + *
    + * Note: The GPE lock should be already acquired when this function is called.
      *
      ******************************************************************************/
     
     ACPI_STATUS
     AcpiEvEnableGpe (
    -    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
    -    BOOLEAN                 WriteToHardware)
    +    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
     {
         ACPI_STATUS             Status;
     
    @@ -277,54 +211,37 @@ AcpiEvEnableGpe (
         ACPI_FUNCTION_TRACE (EvEnableGpe);
     
     
    -    /* Make sure HW enable masks are updated */
    +    /*
    +     * We will only allow a GPE to be enabled if it has either an
    +     * associated method (_Lxx/_Exx) or a handler. Otherwise, the
    +     * GPE will be immediately disabled by AcpiEvGpeDispatch the
    +     * first time it fires.
    +     */
    +    if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
    +    {
    +        return_ACPI_STATUS (AE_NO_HANDLER);
    +    }
     
    -    Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_ENABLE);
    +    /* Ensure the HW enable masks are current */
    +
    +    Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
         if (ACPI_FAILURE (Status))
         {
             return_ACPI_STATUS (Status);
         }
     
    -    /* Mark wake-enabled or HW enable, or both */
    +    /* Clear the GPE (of stale events) */
     
    -    switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
    +    Status = AcpiHwClearGpe (GpeEventInfo);
    +    if (ACPI_FAILURE (Status))
         {
    -    case ACPI_GPE_TYPE_WAKE:
    -
    -        ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
    -        break;
    -
    -    case ACPI_GPE_TYPE_WAKE_RUN:
    -
    -        ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
    -
    -        /*lint -fallthrough */
    -
    -    case ACPI_GPE_TYPE_RUNTIME:
    -
    -        ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
    -
    -        if (WriteToHardware)
    -        {
    -            /* Clear the GPE (of stale events), then enable it */
    -
    -            Status = AcpiHwClearGpe (GpeEventInfo);
    -            if (ACPI_FAILURE (Status))
    -            {
    -                return_ACPI_STATUS (Status);
    -            }
    -
    -            /* Enable the requested runtime GPE */
    -
    -            Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
    -        }
    -        break;
    -
    -    default:
    -        return_ACPI_STATUS (AE_BAD_PARAMETER);
    +        return_ACPI_STATUS (Status);
         }
     
    -    return_ACPI_STATUS (AE_OK);
    +    /* Enable the requested GPE */
    +
    +    Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
    +    return_ACPI_STATUS (Status);
     }
     
     
    @@ -336,7 +253,10 @@ AcpiEvEnableGpe (
      *
      * RETURN:      Status
      *
    - * DESCRIPTION: Disable a GPE based on the GPE type
    + * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE,
    + *              regardless of the type or number of references.
    + *
    + * Note: The GPE lock should be already acquired when this function is called.
      *
      ******************************************************************************/
     
    @@ -356,40 +276,14 @@ AcpiEvDisableGpe (
          * the GPE behind our back.
          */
     
    -    /* Make sure HW enable masks are updated */
    +    /* Ensure the HW enable masks are current */
     
    -    Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
    +    Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
         if (ACPI_FAILURE (Status))
         {
             return_ACPI_STATUS (Status);
         }
     
    -    /* Clear the appropriate enabled flags for this GPE */
    -
    -    switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
    -    {
    -    case ACPI_GPE_TYPE_WAKE:
    -
    -        ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
    -        break;
    -
    -    case ACPI_GPE_TYPE_WAKE_RUN:
    -
    -        ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
    -
    -        /*lint -fallthrough */
    -
    -    case ACPI_GPE_TYPE_RUNTIME:
    -
    -        /* Disable the requested runtime GPE */
    -
    -        ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
    -        break;
    -
    -    default:
    -        break;
    -    }
    -
         /*
          * Always H/W disable this GPE, even if we don't know the GPE type.
          * Simply clear the enable bit for this particular GPE, but do not
    @@ -403,6 +297,49 @@ AcpiEvDisableGpe (
     }
     
     
    +/*******************************************************************************
    + *
    + * FUNCTION:    AcpiEvLowGetGpeInfo
    + *
    + * PARAMETERS:  GpeNumber           - Raw GPE number
    + *              GpeBlock            - A GPE info block
    + *
    + * RETURN:      A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber
    + *              is not within the specified GPE block)
    + *
    + * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is
    + *              the low-level implementation of EvGetGpeEventInfo.
    + *
    + ******************************************************************************/
    +
    +ACPI_GPE_EVENT_INFO *
    +AcpiEvLowGetGpeInfo (
    +    UINT32                  GpeNumber,
    +    ACPI_GPE_BLOCK_INFO     *GpeBlock)
    +{
    +    UINT32                  GpeIndex;
    +
    +
    +    /*
    +     * Validate that the GpeNumber is within the specified GpeBlock.
    +     * (Two steps)
    +     */
    +    if (!GpeBlock ||
    +        (GpeNumber < GpeBlock->BlockBaseNumber))
    +    {
    +        return (NULL);
    +    }
    +
    +    GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber;
    +    if (GpeIndex >= GpeBlock->GpeCount)
    +    {
    +        return (NULL);
    +    }
    +
    +    return (&GpeBlock->EventInfo[GpeIndex]);
    +}
    +
    +
     /*******************************************************************************
      *
      * FUNCTION:    AcpiEvGetGpeEventInfo
    @@ -426,7 +363,7 @@ AcpiEvGetGpeEventInfo (
         UINT32                  GpeNumber)
     {
         ACPI_OPERAND_OBJECT     *ObjDesc;
    -    ACPI_GPE_BLOCK_INFO     *GpeBlock;
    +    ACPI_GPE_EVENT_INFO     *GpeInfo;
         UINT32                  i;
     
     
    @@ -441,16 +378,11 @@ AcpiEvGetGpeEventInfo (
     
             for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++)
             {
    -            GpeBlock = AcpiGbl_GpeFadtBlocks[i];
    -            if (GpeBlock)
    +            GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber,
    +                        AcpiGbl_GpeFadtBlocks[i]);
    +            if (GpeInfo)
                 {
    -                if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
    -                    (GpeNumber < GpeBlock->BlockBaseNumber +
    -                        (GpeBlock->RegisterCount * 8)))
    -                {
    -                    return (&GpeBlock->EventInfo[GpeNumber -
    -                        GpeBlock->BlockBaseNumber]);
    -                }
    +                return (GpeInfo);
                 }
             }
     
    @@ -468,15 +400,7 @@ AcpiEvGetGpeEventInfo (
             return (NULL);
         }
     
    -    GpeBlock = ObjDesc->Device.GpeBlock;
    -
    -    if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
    -        (GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8)))
    -    {
    -        return (&GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]);
    -    }
    -
    -    return (NULL);
    +    return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock));
     }
     
     
    @@ -654,9 +578,9 @@ AcpiEvAsynchExecuteGpeMethod (
             return_VOID;
         }
     
    -    /* Set the GPE flags for return to enabled state */
    +    /* Update the GPE register masks for return to enabled state */
     
    -    (void) AcpiEvEnableGpe (GpeEventInfo, FALSE);
    +    (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
     
         /*
          * Take a snapshot of the GPE info for this level - we copy the info to
    @@ -803,7 +727,7 @@ AcpiEvGpeDispatch (
             if (ACPI_FAILURE (Status))
             {
                 ACPI_EXCEPTION ((AE_INFO, Status,
    -                "Unable to clear GPE[%2X]", GpeNumber));
    +                "Unable to clear GPE[0x%2X]", GpeNumber));
                 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
             }
         }
    @@ -836,7 +760,7 @@ AcpiEvGpeDispatch (
                 if (ACPI_FAILURE (Status))
                 {
                     ACPI_EXCEPTION ((AE_INFO, Status,
    -                    "Unable to clear GPE[%2X]", GpeNumber));
    +                    "Unable to clear GPE[0x%2X]", GpeNumber));
                     return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
                 }
             }
    @@ -852,7 +776,7 @@ AcpiEvGpeDispatch (
             if (ACPI_FAILURE (Status))
             {
                 ACPI_EXCEPTION ((AE_INFO, Status,
    -                "Unable to disable GPE[%2X]", GpeNumber));
    +                "Unable to disable GPE[0x%2X]", GpeNumber));
                 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
             }
     
    @@ -865,28 +789,31 @@ AcpiEvGpeDispatch (
             if (ACPI_FAILURE (Status))
             {
                 ACPI_EXCEPTION ((AE_INFO, Status,
    -                "Unable to queue handler for GPE[%2X] - event disabled",
    +                "Unable to queue handler for GPE[0x%2X] - event disabled",
                     GpeNumber));
             }
             break;
     
         default:
     
    -        /* No handler or method to run! */
    -
    +        /*
    +         * No handler or method to run!
    +         * 03/2010: This case should no longer be possible. We will not allow
    +         * a GPE to be enabled if it has no handler or method.
    +         */
             ACPI_ERROR ((AE_INFO,
    -            "No handler or method for GPE[%2X], disabling event",
    +            "No handler or method for GPE[0x%2X], disabling event",
                 GpeNumber));
     
             /*
    -         * Disable the GPE. The GPE will remain disabled until the ACPICA
    -         * Core Subsystem is restarted, or a handler is installed.
    +         * Disable the GPE. The GPE will remain disabled a handler
    +         * is installed or ACPICA is restarted.
              */
             Status = AcpiEvDisableGpe (GpeEventInfo);
             if (ACPI_FAILURE (Status))
             {
                 ACPI_EXCEPTION ((AE_INFO, Status,
    -                "Unable to disable GPE[%2X]", GpeNumber));
    +                "Unable to disable GPE[0x%2X]", GpeNumber));
                 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
             }
             break;
    diff --git a/sys/contrib/dev/acpica/events/evgpeblk.c b/sys/contrib/dev/acpica/events/evgpeblk.c
    index fe55162cae1..29b0e711e5f 100644
    --- a/sys/contrib/dev/acpica/events/evgpeblk.c
    +++ b/sys/contrib/dev/acpica/events/evgpeblk.c
    @@ -124,7 +124,7 @@
     /* Local prototypes */
     
     static ACPI_STATUS
    -AcpiEvSaveMethodInfo (
    +AcpiEvMatchGpeMethod (
         ACPI_HANDLE             ObjHandle,
         UINT32                  Level,
         void                    *ObjDesc,
    @@ -194,8 +194,7 @@ AcpiEvValidGpeEvent (
             while (GpeBlock)
             {
                 if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) &&
    -                (&GpeBlock->EventInfo[((ACPI_SIZE)
    -                    GpeBlock->RegisterCount) * 8] > GpeEventInfo))
    +                (&GpeBlock->EventInfo[GpeBlock->GpeCount] > GpeEventInfo))
                 {
                     return (TRUE);
                 }
    @@ -328,7 +327,7 @@ AcpiEvDeleteGpeHandlers (
     
     /*******************************************************************************
      *
    - * FUNCTION:    AcpiEvSaveMethodInfo
    + * FUNCTION:    AcpiEvMatchGpeMethod
      *
      * PARAMETERS:  Callback from WalkNamespace
      *
    @@ -340,8 +339,7 @@ AcpiEvDeleteGpeHandlers (
      *              information for quick lookup during GPE dispatch
      *
      *              The name of each GPE control method is of the form:
    - *              "_Lxx" or "_Exx"
    - *              Where:
    + *              "_Lxx" or "_Exx", where:
      *                  L      - means that the GPE is level triggered
      *                  E      - means that the GPE is edge triggered
      *                  xx     - is the GPE number [in HEX]
    @@ -349,38 +347,44 @@ AcpiEvDeleteGpeHandlers (
      ******************************************************************************/
     
     static ACPI_STATUS
    -AcpiEvSaveMethodInfo (
    +AcpiEvMatchGpeMethod (
         ACPI_HANDLE             ObjHandle,
         UINT32                  Level,
         void                    *ObjDesc,
         void                    **ReturnValue)
     {
    +    ACPI_NAMESPACE_NODE     *MethodNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
         ACPI_GPE_BLOCK_INFO     *GpeBlock = (void *) ObjDesc;
         ACPI_GPE_EVENT_INFO     *GpeEventInfo;
         UINT32                  GpeNumber;
         char                    Name[ACPI_NAME_SIZE + 1];
         UINT8                   Type;
    -    ACPI_STATUS             Status;
     
     
    -    ACPI_FUNCTION_TRACE (EvSaveMethodInfo);
    +    ACPI_FUNCTION_TRACE (EvMatchGpeMethod);
     
     
         /*
    -     * _Lxx and _Exx GPE method support
    +     * Match and decode the _Lxx and _Exx GPE method names
          *
    -     * 1) Extract the name from the object and convert to a string
    +     * 1) Extract the method name and null terminate it
          */
    -    ACPI_MOVE_32_TO_32 (
    -        Name, &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer);
    +    ACPI_MOVE_32_TO_32 (Name, &MethodNode->Name.Integer);
         Name[ACPI_NAME_SIZE] = 0;
     
    +    /* 2) Name must begin with an underscore */
    +
    +    if (Name[0] != '_')
    +    {
    +        return_ACPI_STATUS (AE_OK); /* Ignore this method */
    +    }
    +
         /*
    -     * 2) Edge/Level determination is based on the 2nd character
    +     * 3) Edge/Level determination is based on the 2nd character
          *    of the method name
          *
    -     * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
    -     * if a _PRW object is found that points to this GPE.
    +     * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is
    +     * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set.
          */
         switch (Name[1])
         {
    @@ -393,16 +397,15 @@ AcpiEvSaveMethodInfo (
             break;
     
         default:
    -        /* Unknown method type, just ignore it! */
    +        /* Unknown method type, just ignore it */
     
             ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
                 "Ignoring unknown GPE method type: %s "
    -            "(name not of form _Lxx or _Exx)",
    -            Name));
    +            "(name not of form _Lxx or _Exx)", Name));
             return_ACPI_STATUS (AE_OK);
         }
     
    -    /* Convert the last two characters of the name to the GPE Number */
    +    /* 4) The last two characters of the name are the hex GPE Number */
     
         GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
         if (GpeNumber == ACPI_UINT32_MAX)
    @@ -411,45 +414,34 @@ AcpiEvSaveMethodInfo (
     
             ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
                 "Could not extract GPE number from name: %s "
    -            "(name is not of form _Lxx or _Exx)",
    -            Name));
    +            "(name is not of form _Lxx or _Exx)", Name));
             return_ACPI_STATUS (AE_OK);
         }
     
         /* Ensure that we have a valid GPE number for this GPE block */
     
    -    if ((GpeNumber < GpeBlock->BlockBaseNumber) ||
    -        (GpeNumber >= (GpeBlock->BlockBaseNumber +
    -            (GpeBlock->RegisterCount * 8))))
    +    GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
    +    if (!GpeEventInfo)
         {
             /*
    -         * Not valid for this GPE block, just ignore it. However, it may be
    -         * valid for a different GPE block, since GPE0 and GPE1 methods both
    -         * appear under \_GPE.
    +         * This GpeNumber is not valid for this GPE block, just ignore it.
    +         * However, it may be valid for a different GPE block, since GPE0
    +         * and GPE1 methods both appear under \_GPE.
              */
             return_ACPI_STATUS (AE_OK);
         }
     
         /*
    -     * Now we can add this information to the GpeEventInfo block for use
    -     * during dispatch of this GPE. Default type is RUNTIME, although this may
    -     * change when the _PRW methods are executed later.
    +     * Add the GPE information from above to the GpeEventInfo block for
    +     * use during dispatch of this GPE.
          */
    -    GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];
    -
    -    GpeEventInfo->Flags = (UINT8)
    -        (Type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);
    -
    -    GpeEventInfo->Dispatch.MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle;
    -
    -    /* Update enable mask, but don't enable the HW GPE as of yet */
    -
    -    Status = AcpiEvEnableGpe (GpeEventInfo, FALSE);
    +    GpeEventInfo->Flags = (UINT8) (Type | ACPI_GPE_DISPATCH_METHOD);
    +    GpeEventInfo->Dispatch.MethodNode = MethodNode;
     
         ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
             "Registered GPE method %s as GPE number 0x%.2X\n",
             Name, GpeNumber));
    -    return_ACPI_STATUS (Status);
    +    return_ACPI_STATUS (AE_OK);
     }
     
     
    @@ -464,7 +456,7 @@ AcpiEvSaveMethodInfo (
      *
      * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a
      *              Device. Run the _PRW method. If present, extract the GPE
    - *              number and mark the GPE as a WAKE GPE.
    + *              number and mark the GPE as a CAN_WAKE GPE.
      *
      ******************************************************************************/
     
    @@ -495,7 +487,7 @@ AcpiEvMatchPrwAndGpe (
                     ACPI_BTYPE_PACKAGE, &PkgDesc);
         if (ACPI_FAILURE (Status))
         {
    -        /* Ignore all errors from _PRW, we don't want to abort the subsystem */
    +        /* Ignore all errors from _PRW, we don't want to abort the walk */
     
             return_ACPI_STATUS (AE_OK);
         }
    @@ -561,25 +553,17 @@ AcpiEvMatchPrwAndGpe (
          *     2) The GPE index(number) is within the range of the Gpe Block
          *          associated with the GPE device.
          */
    -    if ((GpeDevice == TargetGpeDevice) &&
    -        (GpeNumber >= GpeBlock->BlockBaseNumber) &&
    -        (GpeNumber < GpeBlock->BlockBaseNumber +
    -            (GpeBlock->RegisterCount * 8)))
    +    if (GpeDevice != TargetGpeDevice)
         {
    -        GpeEventInfo = &GpeBlock->EventInfo[GpeNumber -
    -            GpeBlock->BlockBaseNumber];
    +        goto Cleanup;
    +    }
     
    -        /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
    +    GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
    +    if (GpeEventInfo)
    +    {
    +        /* This GPE can wake the system */
     
    -        GpeEventInfo->Flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
    -
    -        Status = AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE);
    -        if (ACPI_FAILURE (Status))
    -        {
    -            goto Cleanup;
    -        }
    -
    -        Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
    +        GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
         }
     
     Cleanup:
    @@ -880,7 +864,7 @@ AcpiEvDeleteGpeBlock (
             AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
         }
     
    -    AcpiCurrentGpeCount -= GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH;
    +    AcpiCurrentGpeCount -= GpeBlock->GpeCount;
     
         /* Free the GpeBlock */
     
    @@ -925,8 +909,8 @@ AcpiEvCreateGpeInfoBlocks (
         /* Allocate the GPE register information block */
     
         GpeRegisterInfo = ACPI_ALLOCATE_ZEROED (
    -                            (ACPI_SIZE) GpeBlock->RegisterCount *
    -                            sizeof (ACPI_GPE_REGISTER_INFO));
    +                        (ACPI_SIZE) GpeBlock->RegisterCount *
    +                        sizeof (ACPI_GPE_REGISTER_INFO));
         if (!GpeRegisterInfo)
         {
             ACPI_ERROR ((AE_INFO,
    @@ -938,10 +922,8 @@ AcpiEvCreateGpeInfoBlocks (
          * Allocate the GPE EventInfo block. There are eight distinct GPEs
          * per register. Initialization to zeros is sufficient.
          */
    -    GpeEventInfo = ACPI_ALLOCATE_ZEROED (
    -                        ((ACPI_SIZE) GpeBlock->RegisterCount *
    -                        ACPI_GPE_REGISTER_WIDTH) *
    -                        sizeof (ACPI_GPE_EVENT_INFO));
    +    GpeEventInfo = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) GpeBlock->GpeCount *
    +                    sizeof (ACPI_GPE_EVENT_INFO));
         if (!GpeEventInfo)
         {
             ACPI_ERROR ((AE_INFO,
    @@ -1080,6 +1062,7 @@ AcpiEvCreateGpeBlock (
         /* Initialize the new GPE block */
     
         GpeBlock->Node = GpeDevice;
    +    GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
         GpeBlock->RegisterCount = RegisterCount;
         GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
     
    @@ -1110,7 +1093,7 @@ AcpiEvCreateGpeBlock (
     
         Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
                     ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
    -                AcpiEvSaveMethodInfo, NULL, GpeBlock, NULL);
    +                AcpiEvMatchGpeMethod, NULL, GpeBlock, NULL);
     
         /* Return the new block */
     
    @@ -1122,15 +1105,13 @@ AcpiEvCreateGpeBlock (
         ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
             "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
             (UINT32) GpeBlock->BlockBaseNumber,
    -        (UINT32) (GpeBlock->BlockBaseNumber +
    -                ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)),
    -        GpeDevice->Name.Ascii,
    -        GpeBlock->RegisterCount,
    +        (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
    +        GpeDevice->Name.Ascii, GpeBlock->RegisterCount,
             InterruptNumber));
     
         /* Update global count of currently available GPEs */
     
    -    AcpiCurrentGpeCount += RegisterCount * ACPI_GPE_REGISTER_WIDTH;
    +    AcpiCurrentGpeCount += GpeBlock->GpeCount;
         return_ACPI_STATUS (AE_OK);
     }
     
    @@ -1161,6 +1142,8 @@ AcpiEvInitializeGpeBlock (
         ACPI_GPE_WALK_INFO      GpeInfo;
         UINT32                  WakeGpeCount;
         UINT32                  GpeEnabledCount;
    +    UINT32                  GpeIndex;
    +    UINT32                  GpeNumber;
         UINT32                  i;
         UINT32                  j;
     
    @@ -1193,39 +1176,65 @@ AcpiEvInitializeGpeBlock (
             Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
                         ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
                         AcpiEvMatchPrwAndGpe, NULL, &GpeInfo, NULL);
    +        if (ACPI_FAILURE (Status))
    +        {
    +            ACPI_EXCEPTION ((AE_INFO, Status, "While executing _PRW methods"));
    +        }
         }
     
         /*
    -     * Enable all GPEs in this block that have these attributes:
    -     * 1) are "runtime" or "run/wake" GPEs, and
    -     * 2) have a corresponding _Lxx or _Exx method
    -     *
    -     * Any other GPEs within this block must be enabled via the
    -     * AcpiEnableGpe() external interface.
    +     * Enable all GPEs that have a corresponding method and are not
    +     * capable of generating wakeups. Any other GPEs within this block
    +     * must be enabled via the AcpiEnableGpe interface.
          */
         WakeGpeCount = 0;
         GpeEnabledCount = 0;
     
    +    if (GpeDevice == AcpiGbl_FadtGpeDevice)
    +    {
    +        GpeDevice = NULL;
    +    }
    +
         for (i = 0; i < GpeBlock->RegisterCount; i++)
         {
    -        for (j = 0; j < 8; j++)
    +        for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
             {
                 /* Get the info block for this particular GPE */
     
    -            GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
    -                ACPI_GPE_REGISTER_WIDTH) + j];
    +            GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
    +            GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
     
    -            if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
    -                    ACPI_GPE_DISPATCH_METHOD) &&
    -                 (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME))
    -            {
    -                GpeEnabledCount++;
    -            }
    +            /* Ignore GPEs that can wake the system */
     
    -            if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE)
    +            if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
                 {
                     WakeGpeCount++;
    +                if (AcpiGbl_LeaveWakeGpesDisabled)
    +                {
    +                    continue;
    +                }
                 }
    +
    +            /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
    +
    +            if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_METHOD))
    +            {
    +                continue;
    +            }
    +
    +            /* Enable this GPE */
    +
    +            GpeNumber = GpeIndex + GpeBlock->BlockBaseNumber;
    +            Status = AcpiEnableGpe (GpeDevice, GpeNumber,
    +                        ACPI_GPE_TYPE_RUNTIME);
    +            if (ACPI_FAILURE (Status))
    +            {
    +                ACPI_EXCEPTION ((AE_INFO, Status,
    +                    "Could not enable GPE 0x%02X", GpeNumber));
    +                continue;
    +            }
    +
    +            GpeEnabledCount++;
             }
         }
     
    @@ -1233,16 +1242,7 @@ AcpiEvInitializeGpeBlock (
             "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
             WakeGpeCount, GpeEnabledCount));
     
    -    /* Enable all valid runtime GPEs found above */
    -
    -    Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock, NULL);
    -    if (ACPI_FAILURE (Status))
    -    {
    -        ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p",
    -            GpeBlock));
    -    }
    -
    -    return_ACPI_STATUS (Status);
    +    return_ACPI_STATUS (AE_OK);
     }
     
     
    @@ -1337,8 +1337,8 @@ AcpiEvGpeInitialize (
                 (GpeNumberMax >= AcpiGbl_FADT.Gpe1Base))
             {
                 ACPI_ERROR ((AE_INFO,
    -                "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
    -                "(GPE %d to %d) - Ignoring GPE1",
    +                "GPE0 block (GPE 0 to %u) overlaps the GPE1 block "
    +                "(GPE %u to %u) - Ignoring GPE1",
                     GpeNumberMax, AcpiGbl_FADT.Gpe1Base,
                     AcpiGbl_FADT.Gpe1Base +
                     ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
    diff --git a/sys/contrib/dev/acpica/events/evmisc.c b/sys/contrib/dev/acpica/events/evmisc.c
    index 1ee7f9d4a78..eff26cbb6eb 100644
    --- a/sys/contrib/dev/acpica/events/evmisc.c
    +++ b/sys/contrib/dev/acpica/events/evmisc.c
    @@ -696,7 +696,7 @@ AcpiEvTerminate (
                 if (ACPI_FAILURE (Status))
                 {
                     ACPI_ERROR ((AE_INFO,
    -                    "Could not disable fixed event %d", (UINT32) i));
    +                    "Could not disable fixed event %u", (UINT32) i));
                 }
             }
     
    diff --git a/sys/contrib/dev/acpica/events/evxface.c b/sys/contrib/dev/acpica/events/evxface.c
    index abffad6536e..3067fa8748d 100644
    --- a/sys/contrib/dev/acpica/events/evxface.c
    +++ b/sys/contrib/dev/acpica/events/evxface.c
    @@ -232,7 +232,7 @@ AcpiInstallFixedEventHandler (
         Status = AcpiEnableEvent (Event, 0);
         if (ACPI_FAILURE (Status))
         {
    -        ACPI_WARNING ((AE_INFO, "Could not enable fixed event %X", Event));
    +        ACPI_WARNING ((AE_INFO, "Could not enable fixed event 0x%X", Event));
     
             /* Remove the handler */
     
    @@ -303,7 +303,7 @@ AcpiRemoveFixedEventHandler (
         if (ACPI_FAILURE (Status))
         {
             ACPI_WARNING ((AE_INFO,
    -            "Could not write to fixed event enable register %X", Event));
    +            "Could not write to fixed event enable register 0x%X", Event));
         }
         else
         {
    @@ -705,7 +705,7 @@ AcpiInstallGpeHandler (
     
         /* Parameter validation */
     
    -    if ((!Address) || (Type > ACPI_GPE_XRUPT_TYPE_MASK))
    +    if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
         {
             return_ACPI_STATUS (AE_BAD_PARAMETER);
         }
    diff --git a/sys/contrib/dev/acpica/events/evxfevnt.c b/sys/contrib/dev/acpica/events/evxfevnt.c
    index 92b6d4d69db..333e0e58691 100644
    --- a/sys/contrib/dev/acpica/events/evxfevnt.c
    +++ b/sys/contrib/dev/acpica/events/evxfevnt.c
    @@ -305,70 +305,20 @@ AcpiEnableEvent (
     ACPI_EXPORT_SYMBOL (AcpiEnableEvent)
     
     
    -/*******************************************************************************
    - *
    - * FUNCTION:    AcpiSetGpeType
    - *
    - * PARAMETERS:  GpeDevice       - Parent GPE Device
    - *              GpeNumber       - GPE level within the GPE block
    - *              Type            - New GPE type
    - *
    - * RETURN:      Status
    - *
    - * DESCRIPTION: Set the type of an individual GPE
    - *
    - ******************************************************************************/
    -
    -ACPI_STATUS
    -AcpiSetGpeType (
    -    ACPI_HANDLE             GpeDevice,
    -    UINT32                  GpeNumber,
    -    UINT8                   Type)
    -{
    -    ACPI_STATUS             Status = AE_OK;
    -    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    -
    -
    -    ACPI_FUNCTION_TRACE (AcpiSetGpeType);
    -
    -
    -    /* Ensure that we have a valid GPE number */
    -
    -    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    -    if (!GpeEventInfo)
    -    {
    -        Status = AE_BAD_PARAMETER;
    -        goto UnlockAndExit;
    -    }
    -
    -    if ((GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) == Type)
    -    {
    -        return_ACPI_STATUS (AE_OK);
    -    }
    -
    -    /* Set the new type (will disable GPE if currently enabled) */
    -
    -    Status = AcpiEvSetGpeType (GpeEventInfo, Type);
    -
    -UnlockAndExit:
    -    return_ACPI_STATUS (Status);
    -}
    -
    -ACPI_EXPORT_SYMBOL (AcpiSetGpeType)
    -
    -
     /*******************************************************************************
      *
      * FUNCTION:    AcpiEnableGpe
      *
    - * PARAMETERS:  GpeDevice       - Parent GPE Device
    + * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
      *              GpeNumber       - GPE level within the GPE block
    - *              Flags           - Just enable, or also wake enable?
    - *                                Called from ISR or not
    + *              GpeType         - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
    + *                                or both
      *
      * RETURN:      Status
      *
    - * DESCRIPTION: Enable an ACPI event (general purpose)
    + * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
    + *              hardware-enabled (for runtime GPEs), or the GPE register mask
    + *              is updated (for wake GPEs).
      *
      ******************************************************************************/
     
    @@ -376,26 +326,25 @@ ACPI_STATUS
     AcpiEnableGpe (
         ACPI_HANDLE             GpeDevice,
         UINT32                  GpeNumber,
    -    UINT32                  Flags)
    +    UINT8                   GpeType)
     {
         ACPI_STATUS             Status = AE_OK;
         ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    +    ACPI_CPU_FLAGS          Flags;
     
     
         ACPI_FUNCTION_TRACE (AcpiEnableGpe);
     
     
    -    /* Use semaphore lock if not executing at interrupt level */
    +    /* Parameter validation */
     
    -    if (Flags & ACPI_NOT_ISR)
    +    if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
         {
    -        Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    -        if (ACPI_FAILURE (Status))
    -        {
    -            return_ACPI_STATUS (Status);
    -        }
    +        return_ACPI_STATUS (AE_BAD_PARAMETER);
         }
     
    +    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    +
         /* Ensure that we have a valid GPE number */
     
         GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    @@ -405,15 +354,55 @@ AcpiEnableGpe (
             goto UnlockAndExit;
         }
     
    -    /* Perform the enable */
    +    if (GpeType & ACPI_GPE_TYPE_RUNTIME)
    +    {
    +        if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
    +        {
    +            Status = AE_LIMIT; /* Too many references */
    +            goto UnlockAndExit;
    +        }
     
    -    Status = AcpiEvEnableGpe (GpeEventInfo, TRUE);
    +        GpeEventInfo->RuntimeCount++;
    +        if (GpeEventInfo->RuntimeCount == 1)
    +        {
    +            Status = AcpiEvEnableGpe (GpeEventInfo);
    +            if (ACPI_FAILURE (Status))
    +            {
    +                GpeEventInfo->RuntimeCount--;
    +                goto UnlockAndExit;
    +            }
    +        }
    +    }
    +
    +    if (GpeType & ACPI_GPE_TYPE_WAKE)
    +    {
    +        /* The GPE must have the ability to wake the system */
    +
    +        if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
    +        {
    +            Status = AE_TYPE;
    +            goto UnlockAndExit;
    +        }
    +
    +        if (GpeEventInfo->WakeupCount == ACPI_UINT8_MAX)
    +        {
    +            Status = AE_LIMIT; /* Too many references */
    +            goto UnlockAndExit;
    +        }
    +
    +        /*
    +         * Update the enable mask on the first wakeup reference. Wake GPEs
    +         * are only hardware-enabled just before sleeping.
    +         */
    +        GpeEventInfo->WakeupCount++;
    +        if (GpeEventInfo->WakeupCount == 1)
    +        {
    +            (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
    +        }
    +    }
     
     UnlockAndExit:
    -    if (Flags & ACPI_NOT_ISR)
    -    {
    -        (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    -    }
    +    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
         return_ACPI_STATUS (Status);
     }
     
    @@ -424,14 +413,16 @@ ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
      *
      * FUNCTION:    AcpiDisableGpe
      *
    - * PARAMETERS:  GpeDevice       - Parent GPE Device
    + * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
      *              GpeNumber       - GPE level within the GPE block
    - *              Flags           - Just disable, or also wake disable?
    - *                                Called from ISR or not
    + *              GpeType         - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
    + *                                or both
      *
      * RETURN:      Status
      *
    - * DESCRIPTION: Disable an ACPI event (general purpose)
    + * DESCRIPTION: Remove a reference to a GPE. When the last reference is
    + *              removed, only then is the GPE disabled (for runtime GPEs), or
    + *              the GPE mask bit disabled (for wake GPEs)
      *
      ******************************************************************************/
     
    @@ -439,26 +430,25 @@ ACPI_STATUS
     AcpiDisableGpe (
         ACPI_HANDLE             GpeDevice,
         UINT32                  GpeNumber,
    -    UINT32                  Flags)
    +    UINT8                   GpeType)
     {
         ACPI_STATUS             Status = AE_OK;
         ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    +    ACPI_CPU_FLAGS          Flags;
     
     
         ACPI_FUNCTION_TRACE (AcpiDisableGpe);
     
     
    -    /* Use semaphore lock if not executing at interrupt level */
    +    /* Parameter validation */
     
    -    if (Flags & ACPI_NOT_ISR)
    +    if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
         {
    -        Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    -        if (ACPI_FAILURE (Status))
    -        {
    -            return_ACPI_STATUS (Status);
    -        }
    +        return_ACPI_STATUS (AE_BAD_PARAMETER);
         }
     
    +    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    +
         /* Ensure that we have a valid GPE number */
     
         GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    @@ -468,19 +458,127 @@ AcpiDisableGpe (
             goto UnlockAndExit;
         }
     
    -    Status = AcpiEvDisableGpe (GpeEventInfo);
    +    /* Hardware-disable a runtime GPE on removal of the last reference */
    +
    +    if (GpeType & ACPI_GPE_TYPE_RUNTIME)
    +    {
    +        if (!GpeEventInfo->RuntimeCount)
    +        {
    +            Status = AE_LIMIT; /* There are no references to remove */
    +            goto UnlockAndExit;
    +        }
    +
    +        GpeEventInfo->RuntimeCount--;
    +        if (!GpeEventInfo->RuntimeCount)
    +        {
    +            Status = AcpiEvDisableGpe (GpeEventInfo);
    +            if (ACPI_FAILURE (Status))
    +            {
    +                GpeEventInfo->RuntimeCount++;
    +                goto UnlockAndExit;
    +            }
    +        }
    +    }
    +
    +    /*
    +     * Update masks for wake GPE on removal of the last reference.
    +     * No need to hardware-disable wake GPEs here, they are not currently
    +     * enabled.
    +     */
    +    if (GpeType & ACPI_GPE_TYPE_WAKE)
    +    {
    +        if (!GpeEventInfo->WakeupCount)
    +        {
    +            Status = AE_LIMIT; /* There are no references to remove */
    +            goto UnlockAndExit;
    +        }
    +
    +        GpeEventInfo->WakeupCount--;
    +        if (!GpeEventInfo->WakeupCount)
    +        {
    +            (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
    +        }
    +    }
    +
     
     UnlockAndExit:
    -    if (Flags & ACPI_NOT_ISR)
    -    {
    -        (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    -    }
    +    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
         return_ACPI_STATUS (Status);
     }
     
     ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
     
     
    +/*******************************************************************************
    + *
    + * FUNCTION:    AcpiSetGpe
    + *
    + * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
    + *              GpeNumber       - GPE level within the GPE block
    + *              Action          - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
    + *
    + * RETURN:      Status
    + *
    + * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
    + *              the reference count mechanism used in the AcpiEnableGpe and
    + *              AcpiDisableGpe interfaces -- and should be used with care.
    + *
    + * Note: Typically used to disable a runtime GPE for short period of time,
    + * then re-enable it, without disturbing the existing reference counts. This
    + * is useful, for example, in the Embedded Controller (EC) driver.
    + *
    + ******************************************************************************/
    +
    +ACPI_STATUS
    +AcpiSetGpe (
    +    ACPI_HANDLE             GpeDevice,
    +    UINT32                  GpeNumber,
    +    UINT8                   Action)
    +{
    +    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    +    ACPI_STATUS             Status;
    +    ACPI_CPU_FLAGS          Flags;
    +
    +
    +    ACPI_FUNCTION_TRACE (AcpiSetGpe);
    +
    +
    +    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    +
    +    /* Ensure that we have a valid GPE number */
    +
    +    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    +    if (!GpeEventInfo)
    +    {
    +        Status = AE_BAD_PARAMETER;
    +        goto UnlockAndExit;
    +    }
    +
    +    /* Perform the action */
    +
    +    switch (Action)
    +    {
    +    case ACPI_GPE_ENABLE:
    +        Status = AcpiEvEnableGpe (GpeEventInfo);
    +        break;
    +
    +    case ACPI_GPE_DISABLE:
    +        Status = AcpiEvDisableGpe (GpeEventInfo);
    +        break;
    +
    +    default:
    +        Status = AE_BAD_PARAMETER;
    +        break;
    +    }
    +
    +UnlockAndExit:
    +    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    +    return_ACPI_STATUS (Status);
    +}
    +
    +ACPI_EXPORT_SYMBOL (AcpiSetGpe)
    +
    +
     /*******************************************************************************
      *
      * FUNCTION:    AcpiDisableEvent
    @@ -592,9 +690,8 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent)
      *
      * FUNCTION:    AcpiClearGpe
      *
    - * PARAMETERS:  GpeDevice       - Parent GPE Device
    + * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
      *              GpeNumber       - GPE level within the GPE block
    - *              Flags           - Called from an ISR or not
      *
      * RETURN:      Status
      *
    @@ -605,26 +702,17 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent)
     ACPI_STATUS
     AcpiClearGpe (
         ACPI_HANDLE             GpeDevice,
    -    UINT32                  GpeNumber,
    -    UINT32                  Flags)
    +    UINT32                  GpeNumber)
     {
         ACPI_STATUS             Status = AE_OK;
         ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    +    ACPI_CPU_FLAGS          Flags;
     
     
         ACPI_FUNCTION_TRACE (AcpiClearGpe);
     
     
    -    /* Use semaphore lock if not executing at interrupt level */
    -
    -    if (Flags & ACPI_NOT_ISR)
    -    {
    -        Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    -        if (ACPI_FAILURE (Status))
    -        {
    -            return_ACPI_STATUS (Status);
    -        }
    -    }
    +    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
     
         /* Ensure that we have a valid GPE number */
     
    @@ -638,10 +726,7 @@ AcpiClearGpe (
         Status = AcpiHwClearGpe (GpeEventInfo);
     
     UnlockAndExit:
    -    if (Flags & ACPI_NOT_ISR)
    -    {
    -        (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    -    }
    +    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
         return_ACPI_STATUS (Status);
     }
     
    @@ -700,9 +785,8 @@ ACPI_EXPORT_SYMBOL (AcpiGetEventStatus)
      *
      * FUNCTION:    AcpiGetGpeStatus
      *
    - * PARAMETERS:  GpeDevice       - Parent GPE Device
    + * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
      *              GpeNumber       - GPE level within the GPE block
    - *              Flags           - Called from an ISR or not
      *              EventStatus     - Where the current status of the event will
      *                                be returned
      *
    @@ -716,26 +800,17 @@ ACPI_STATUS
     AcpiGetGpeStatus (
         ACPI_HANDLE             GpeDevice,
         UINT32                  GpeNumber,
    -    UINT32                  Flags,
         ACPI_EVENT_STATUS       *EventStatus)
     {
         ACPI_STATUS             Status = AE_OK;
         ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    +    ACPI_CPU_FLAGS          Flags;
     
     
         ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
     
     
    -    /* Use semaphore lock if not executing at interrupt level */
    -
    -    if (Flags & ACPI_NOT_ISR)
    -    {
    -        Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    -        if (ACPI_FAILURE (Status))
    -        {
    -            return_ACPI_STATUS (Status);
    -        }
    -    }
    +    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
     
         /* Ensure that we have a valid GPE number */
     
    @@ -751,10 +826,7 @@ AcpiGetGpeStatus (
         Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
     
     UnlockAndExit:
    -    if (Flags & ACPI_NOT_ISR)
    -    {
    -        (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    -    }
    +    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
         return_ACPI_STATUS (Status);
     }
     
    @@ -823,21 +895,15 @@ AcpiInstallGpeBlock (
             goto UnlockAndExit;
         }
     
    -    /* Run the _PRW methods and enable the GPEs */
    -
    -    Status = AcpiEvInitializeGpeBlock (Node, GpeBlock);
    -    if (ACPI_FAILURE (Status))
    -    {
    -        goto UnlockAndExit;
    -    }
    -
    -    /* Get the DeviceObject attached to the node */
    +    /* Install block in the DeviceObject attached to the node */
     
         ObjDesc = AcpiNsGetAttachedObject (Node);
         if (!ObjDesc)
         {
    -        /* No object, create a new one */
    -
    +        /*
    +         * No object, create a new one (Device nodes do not always have
    +         * an attached object)
    +         */
             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
             if (!ObjDesc)
             {
    @@ -850,17 +916,20 @@ AcpiInstallGpeBlock (
             /* Remove local reference to the object */
     
             AcpiUtRemoveReference (ObjDesc);
    -
             if (ACPI_FAILURE (Status))
             {
                 goto UnlockAndExit;
             }
         }
     
    -    /* Install the GPE block in the DeviceObject */
    +    /* Now install the GPE block in the DeviceObject */
     
         ObjDesc->Device.GpeBlock = GpeBlock;
     
    +    /* Run the _PRW methods and enable the runtime GPEs in the new block */
    +
    +    Status = AcpiEvInitializeGpeBlock (Node, GpeBlock);
    +
     
     UnlockAndExit:
         (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    @@ -1018,8 +1087,7 @@ AcpiEvGetGpeDevice (
     
         /* Increment Index by the number of GPEs in this block */
     
    -    Info->NextBlockBaseIndex +=
    -        (GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH);
    +    Info->NextBlockBaseIndex += GpeBlock->GpeCount;
     
         if (Info->Index < Info->NextBlockBaseIndex)
         {
    diff --git a/sys/contrib/dev/acpica/executer/exconvrt.c b/sys/contrib/dev/acpica/executer/exconvrt.c
    index a67122c12d4..c8e66a68ba0 100644
    --- a/sys/contrib/dev/acpica/executer/exconvrt.c
    +++ b/sys/contrib/dev/acpica/executer/exconvrt.c
    @@ -786,7 +786,7 @@ AcpiExConvertToTargetType (
     
     
             default:
    -            ACPI_ERROR ((AE_INFO, "Bad destination type during conversion: %X",
    +            ACPI_ERROR ((AE_INFO, "Bad destination type during conversion: 0x%X",
                     DestinationType));
                 Status = AE_AML_INTERNAL;
                 break;
    @@ -803,7 +803,7 @@ AcpiExConvertToTargetType (
     
         default:
             ACPI_ERROR ((AE_INFO,
    -            "Unknown Target type ID 0x%X AmlOpcode %X DestType %s",
    +            "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
                 GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs),
                 WalkState->Opcode, AcpiUtGetTypeName (DestinationType)));
             Status = AE_AML_INTERNAL;
    diff --git a/sys/contrib/dev/acpica/executer/excreate.c b/sys/contrib/dev/acpica/executer/excreate.c
    index f6c2700e0d0..a2f3ed06b74 100644
    --- a/sys/contrib/dev/acpica/executer/excreate.c
    +++ b/sys/contrib/dev/acpica/executer/excreate.c
    @@ -402,11 +402,11 @@ AcpiExCreateRegion (
         if ((RegionSpace >= ACPI_NUM_PREDEFINED_REGIONS) &&
             (RegionSpace < ACPI_USER_REGION_BEGIN))
         {
    -        ACPI_ERROR ((AE_INFO, "Invalid AddressSpace type %X", RegionSpace));
    +        ACPI_ERROR ((AE_INFO, "Invalid AddressSpace type 0x%X", RegionSpace));
             return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
         }
     
    -    ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
    +    ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (0x%X)\n",
             AcpiUtGetRegionName (RegionSpace), RegionSpace));
     
         /* Create the region descriptor */
    diff --git a/sys/contrib/dev/acpica/executer/exdebug.c b/sys/contrib/dev/acpica/executer/exdebug.c
    new file mode 100644
    index 00000000000..084c6cb2cc5
    --- /dev/null
    +++ b/sys/contrib/dev/acpica/executer/exdebug.c
    @@ -0,0 +1,350 @@
    +/******************************************************************************
    + *
    + * Module Name: exdebug - Support for stores to the AML Debug Object
    + *
    + *****************************************************************************/
    +
    +/******************************************************************************
    + *
    + * 1. Copyright Notice
    + *
    + * Some or all of this work - Copyright (c) 1999 - 2010, 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.
    + *
    + *****************************************************************************/
    +
    +#define __EXDEBUG_C__
    +
    +#include 
    +#include 
    +#include 
    +
    +
    +#define _COMPONENT          ACPI_EXECUTER
    +        ACPI_MODULE_NAME    ("exdebug")
    +
    +
    +#ifndef ACPI_NO_ERROR_MESSAGES
    +/*******************************************************************************
    + *
    + * FUNCTION:    AcpiExDoDebugObject
    + *
    + * PARAMETERS:  SourceDesc          - Object to be output to "Debug Object"
    + *              Level               - Indentation level (used for packages)
    + *              Index               - Current package element, zero if not pkg
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: Handles stores to the AML Debug Object. For example:
    + *              Store(INT1, Debug)
    + *
    + * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set.
    + *
    + * This function is only enabled if AcpiGbl_EnableAmlDebugObject is set, or
    + * if ACPI_LV_DEBUG_OBJECT is set in the AcpiDbgLevel. Thus, in the normal
    + * operational case, stores to the debug object are ignored but can be easily
    + * enabled if necessary.
    + *
    + ******************************************************************************/
    +
    +void
    +AcpiExDoDebugObject (
    +    ACPI_OPERAND_OBJECT     *SourceDesc,
    +    UINT32                  Level,
    +    UINT32                  Index)
    +{
    +    UINT32                  i;
    +
    +
    +    ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
    +
    +
    +    /* Output must be enabled via the DebugObject global or the DbgLevel */
    +
    +    if (!AcpiGbl_EnableAmlDebugObject &&
    +        !(AcpiDbgLevel & ACPI_LV_DEBUG_OBJECT))
    +    {
    +        return_VOID;
    +    }
    +
    +    /*
    +     * Print line header as long as we are not in the middle of an
    +     * object display
    +     */
    +    if (!((Level > 0) && Index == 0))
    +    {
    +        AcpiOsPrintf ("[ACPI Debug] %*s", Level, " ");
    +    }
    +
    +    /* Display the index for package output only */
    +
    +    if (Index > 0)
    +    {
    +       AcpiOsPrintf ("(%.2u) ", Index-1);
    +    }
    +
    +    if (!SourceDesc)
    +    {
    +        AcpiOsPrintf ("[Null Object]\n");
    +        return_VOID;
    +    }
    +
    +    if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
    +    {
    +        AcpiOsPrintf ("%s ", AcpiUtGetObjectTypeName (SourceDesc));
    +
    +        if (!AcpiUtValidInternalObject (SourceDesc))
    +        {
    +           AcpiOsPrintf ("%p, Invalid Internal Object!\n", SourceDesc);
    +           return_VOID;
    +        }
    +    }
    +    else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
    +    {
    +        AcpiOsPrintf ("%s: %p\n",
    +            AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
    +            SourceDesc);
    +        return_VOID;
    +    }
    +    else
    +    {
    +        return_VOID;
    +    }
    +
    +    /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
    +
    +    switch (SourceDesc->Common.Type)
    +    {
    +    case ACPI_TYPE_INTEGER:
    +
    +        /* Output correct integer width */
    +
    +        if (AcpiGbl_IntegerByteWidth == 4)
    +        {
    +            AcpiOsPrintf ("0x%8.8X\n",
    +                (UINT32) SourceDesc->Integer.Value);
    +        }
    +        else
    +        {
    +            AcpiOsPrintf ("0x%8.8X%8.8X\n",
    +                ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value));
    +        }
    +        break;
    +
    +    case ACPI_TYPE_BUFFER:
    +
    +        AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length);
    +        AcpiUtDumpBuffer2 (SourceDesc->Buffer.Pointer,
    +            (SourceDesc->Buffer.Length < 256) ?
    +                SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY);
    +        break;
    +
    +    case ACPI_TYPE_STRING:
    +
    +        AcpiOsPrintf ("[0x%.2X] \"%s\"\n",
    +            SourceDesc->String.Length, SourceDesc->String.Pointer);
    +        break;
    +
    +    case ACPI_TYPE_PACKAGE:
    +
    +        AcpiOsPrintf ("[Contains 0x%.2X Elements]\n",
    +            SourceDesc->Package.Count);
    +
    +        /* Output the entire contents of the package */
    +
    +        for (i = 0; i < SourceDesc->Package.Count; i++)
    +        {
    +            AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
    +                Level+4, i+1);
    +        }
    +        break;
    +
    +    case ACPI_TYPE_LOCAL_REFERENCE:
    +
    +        AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (SourceDesc));
    +
    +        /* Decode the reference */
    +
    +        switch (SourceDesc->Reference.Class)
    +        {
    +        case ACPI_REFCLASS_INDEX:
    +
    +            AcpiOsPrintf ("0x%X\n", SourceDesc->Reference.Value);
    +            break;
    +
    +        case ACPI_REFCLASS_TABLE:
    +
    +            /* Case for DdbHandle */
    +
    +            AcpiOsPrintf ("Table Index 0x%X\n", SourceDesc->Reference.Value);
    +            return;
    +
    +        default:
    +            break;
    +        }
    +
    +        AcpiOsPrintf ("  ");
    +
    +        /* Check for valid node first, then valid object */
    +
    +        if (SourceDesc->Reference.Node)
    +        {
    +            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
    +                    ACPI_DESC_TYPE_NAMED)
    +            {
    +                AcpiOsPrintf (" %p - Not a valid namespace node\n",
    +                    SourceDesc->Reference.Node);
    +            }
    +            else
    +            {
    +                AcpiOsPrintf ("Node %p [%4.4s] ", SourceDesc->Reference.Node,
    +                    (SourceDesc->Reference.Node)->Name.Ascii);
    +
    +                switch ((SourceDesc->Reference.Node)->Type)
    +                {
    +                /* These types have no attached object */
    +
    +                case ACPI_TYPE_DEVICE:
    +                    AcpiOsPrintf ("Device\n");
    +                    break;
    +
    +                case ACPI_TYPE_THERMAL:
    +                    AcpiOsPrintf ("Thermal Zone\n");
    +                    break;
    +
    +                default:
    +                    AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
    +                        Level+4, 0);
    +                    break;
    +                }
    +            }
    +        }
    +        else if (SourceDesc->Reference.Object)
    +        {
    +            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
    +                    ACPI_DESC_TYPE_NAMED)
    +            {
    +                AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *)
    +                    SourceDesc->Reference.Object)->Object,
    +                    Level+4, 0);
    +            }
    +            else
    +            {
    +                AcpiExDoDebugObject (SourceDesc->Reference.Object,
    +                    Level+4, 0);
    +            }
    +        }
    +        break;
    +
    +    default:
    +
    +        AcpiOsPrintf ("%p\n", SourceDesc);
    +        break;
    +    }
    +
    +    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
    +    return_VOID;
    +}
    +#endif
    +
    +
    diff --git a/sys/contrib/dev/acpica/executer/exfield.c b/sys/contrib/dev/acpica/executer/exfield.c
    index 0e06eefa74d..c0160146816 100644
    --- a/sys/contrib/dev/acpica/executer/exfield.c
    +++ b/sys/contrib/dev/acpica/executer/exfield.c
    @@ -382,7 +382,7 @@ AcpiExWriteDataToField (
             if (SourceDesc->Buffer.Length < Length)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "SMBus or IPMI write requires Buffer of length %X, found length %X",
    +                "SMBus or IPMI write requires Buffer of length %u, found length %u",
                     Length, SourceDesc->Buffer.Length));
     
                 return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
    diff --git a/sys/contrib/dev/acpica/executer/exfldio.c b/sys/contrib/dev/acpica/executer/exfldio.c
    index 8fbc9920adb..b23b643de5b 100644
    --- a/sys/contrib/dev/acpica/executer/exfldio.c
    +++ b/sys/contrib/dev/acpica/executer/exfldio.c
    @@ -181,7 +181,7 @@ AcpiExSetupRegion (
     
         if (RgnDesc->Common.Type != ACPI_TYPE_REGION)
         {
    -        ACPI_ERROR ((AE_INFO, "Needed Region, found type %X (%s)",
    +        ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
                 RgnDesc->Common.Type,
                 AcpiUtGetObjectTypeName (RgnDesc)));
     
    @@ -262,7 +262,7 @@ AcpiExSetupRegion (
                  * byte, and a field with Dword access specified.
                  */
                 ACPI_ERROR ((AE_INFO,
    -                "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)",
    +                "Field [%4.4s] access width (%u bytes) too large for region [%4.4s] (length %u)",
                     AcpiUtGetNodeName (ObjDesc->CommonField.Node),
                     ObjDesc->CommonField.AccessByteWidth,
                     AcpiUtGetNodeName (RgnDesc->Region.Node),
    @@ -274,7 +274,7 @@ AcpiExSetupRegion (
              * exceeds region length, indicate an error
              */
             ACPI_ERROR ((AE_INFO,
    -            "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)",
    +            "Field [%4.4s] Base+Offset+Width %u+%u+%u is beyond end of region [%4.4s] (length %u)",
                 AcpiUtGetNodeName (ObjDesc->CommonField.Node),
                 ObjDesc->CommonField.BaseByteOffset,
                 FieldDatumByteOffset, ObjDesc->CommonField.AccessByteWidth,
    @@ -371,14 +371,14 @@ AcpiExAccessRegion (
             if (Status == AE_NOT_IMPLEMENTED)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Region %s(%X) not implemented",
    +                "Region %s(0x%X) not implemented",
                     AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
                     RgnDesc->Region.SpaceId));
             }
             else if (Status == AE_NOT_EXIST)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Region %s(%X) has no handler",
    +                "Region %s(0x%X) has no handler",
                     AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
                     RgnDesc->Region.SpaceId));
             }
    @@ -633,7 +633,7 @@ AcpiExFieldDatumIo (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %X",
    +        ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %u",
                 ObjDesc->Common.Type));
             Status = AE_AML_INTERNAL;
             break;
    @@ -743,7 +743,7 @@ AcpiExWriteWithUpdateRule (
             default:
     
                 ACPI_ERROR ((AE_INFO,
    -                "Unknown UpdateRule value: %X",
    +                "Unknown UpdateRule value: 0x%X",
                     (ObjDesc->CommonField.FieldFlags & AML_FIELD_UPDATE_RULE_MASK)));
                 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
             }
    @@ -806,7 +806,7 @@ AcpiExExtractFromField (
                 ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength))
         {
             ACPI_ERROR ((AE_INFO,
    -            "Field size %X (bits) is too large for buffer (%X)",
    +            "Field size %u (bits) is too large for buffer (%u)",
                 ObjDesc->CommonField.BitLength, BufferLength));
     
             return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
    diff --git a/sys/contrib/dev/acpica/executer/exmisc.c b/sys/contrib/dev/acpica/executer/exmisc.c
    index a639afb285c..9d01e033778 100644
    --- a/sys/contrib/dev/acpica/executer/exmisc.c
    +++ b/sys/contrib/dev/acpica/executer/exmisc.c
    @@ -183,7 +183,7 @@ AcpiExGetObjectReference (
     
             default:
     
    -            ACPI_ERROR ((AE_INFO, "Unknown Reference Class %2.2X",
    +            ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
                     ObjDesc->Reference.Class));
                 return_ACPI_STATUS (AE_AML_INTERNAL);
             }
    @@ -201,7 +201,7 @@ AcpiExGetObjectReference (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Invalid descriptor type %X",
    +        ACPI_ERROR ((AE_INFO, "Invalid descriptor type 0x%X",
                 ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)));
             return_ACPI_STATUS (AE_TYPE);
         }
    @@ -373,7 +373,7 @@ AcpiExDoConcatenate (
             break;
     
         default:
    -        ACPI_ERROR ((AE_INFO, "Invalid object type: %X",
    +        ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
                 Operand0->Common.Type));
             Status = AE_AML_INTERNAL;
         }
    @@ -475,7 +475,7 @@ AcpiExDoConcatenate (
     
             /* Invalid object type, should not happen here */
     
    -        ACPI_ERROR ((AE_INFO, "Invalid object type: %X",
    +        ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
                 Operand0->Common.Type));
             Status =AE_AML_INTERNAL;
             goto Cleanup;
    diff --git a/sys/contrib/dev/acpica/executer/exmutex.c b/sys/contrib/dev/acpica/executer/exmutex.c
    index 0bd66b35623..315ad100e83 100644
    --- a/sys/contrib/dev/acpica/executer/exmutex.c
    +++ b/sys/contrib/dev/acpica/executer/exmutex.c
    @@ -168,10 +168,10 @@ AcpiExUnlinkMutex (
             (ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
     
             /*
    -         * Migrate the previous sync level associated with this mutex to the
    -         * previous mutex on the list so that it may be preserved. This handles
    -         * the case where several mutexes have been acquired at the same level,
    -         * but are not released in opposite order.
    +         * Migrate the previous sync level associated with this mutex to
    +         * the previous mutex on the list so that it may be preserved.
    +         * This handles the case where several mutexes have been acquired
    +         * at the same level, but are not released in opposite order.
              */
             (ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
                 ObjDesc->Mutex.OriginalSyncLevel;
    @@ -187,8 +187,8 @@ AcpiExUnlinkMutex (
      *
      * FUNCTION:    AcpiExLinkMutex
      *
    - * PARAMETERS:  ObjDesc         - The mutex to be linked
    - *              Thread          - Current executing thread object
    + * PARAMETERS:  ObjDesc             - The mutex to be linked
    + *              Thread              - Current executing thread object
      *
      * RETURN:      None
      *
    @@ -228,9 +228,9 @@ AcpiExLinkMutex (
      *
      * FUNCTION:    AcpiExAcquireMutexObject
      *
    - * PARAMETERS:  TimeDesc            - Timeout in milliseconds
    + * PARAMETERS:  Timeout             - Timeout in milliseconds
      *              ObjDesc             - Mutex object
    - *              Thread              - Current thread state
    + *              ThreadId            - Current thread state
      *
      * RETURN:      Status
      *
    @@ -337,11 +337,12 @@ AcpiExAcquireMutex (
             return_ACPI_STATUS (AE_BAD_PARAMETER);
         }
     
    -    /* Must have a valid thread ID */
    +    /* Must have a valid thread state struct */
     
         if (!WalkState->Thread)
         {
    -        ACPI_ERROR ((AE_INFO, "Cannot acquire Mutex [%4.4s], null thread info",
    +        ACPI_ERROR ((AE_INFO,
    +            "Cannot acquire Mutex [%4.4s], null thread info",
                 AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
             return_ACPI_STATUS (AE_AML_INTERNAL);
         }
    @@ -353,7 +354,7 @@ AcpiExAcquireMutex (
         if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%d)",
    +            "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%u)",
                 AcpiUtGetNodeName (ObjDesc->Mutex.Node),
                 WalkState->Thread->CurrentSyncLevel));
             return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
    @@ -471,6 +472,7 @@ AcpiExReleaseMutex (
     {
         ACPI_STATUS             Status = AE_OK;
         UINT8                   PreviousSyncLevel;
    +    ACPI_THREAD_STATE       *OwnerThread;
     
     
         ACPI_FUNCTION_TRACE (ExReleaseMutex);
    @@ -481,11 +483,14 @@ AcpiExReleaseMutex (
             return_ACPI_STATUS (AE_BAD_PARAMETER);
         }
     
    +    OwnerThread = ObjDesc->Mutex.OwnerThread;
    +
         /* The mutex must have been previously acquired in order to release it */
     
    -    if (!ObjDesc->Mutex.OwnerThread)
    +    if (!OwnerThread)
         {
    -        ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], not acquired",
    +        ACPI_ERROR ((AE_INFO,
    +            "Cannot release Mutex [%4.4s], not acquired",
                 AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
             return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
         }
    @@ -494,7 +499,8 @@ AcpiExReleaseMutex (
     
         if (!WalkState->Thread)
         {
    -        ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
    +        ACPI_ERROR ((AE_INFO,
    +            "Cannot release Mutex [%4.4s], null thread info",
                 AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
             return_ACPI_STATUS (AE_AML_INTERNAL);
         }
    @@ -503,14 +509,14 @@ AcpiExReleaseMutex (
          * The Mutex is owned, but this thread must be the owner.
          * Special case for Global Lock, any thread can release
          */
    -    if ((ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
    +    if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
             (ObjDesc != AcpiGbl_GlobalLockMutex))
         {
             ACPI_ERROR ((AE_INFO,
                 "Thread %p cannot release Mutex [%4.4s] acquired by thread %p",
                 ACPI_CAST_PTR (void, WalkState->Thread->ThreadId),
                 AcpiUtGetNodeName (ObjDesc->Mutex.Node),
    -            ACPI_CAST_PTR (void, ObjDesc->Mutex.OwnerThread->ThreadId)));
    +            ACPI_CAST_PTR (void, OwnerThread->ThreadId)));
             return_ACPI_STATUS (AE_AML_NOT_OWNER);
         }
     
    @@ -521,10 +527,10 @@ AcpiExReleaseMutex (
          * different level can only mean that the mutex ordering rule is being
          * violated. This behavior is clarified in ACPI 4.0 specification.
          */
    -    if (ObjDesc->Mutex.SyncLevel != WalkState->Thread->CurrentSyncLevel)
    +    if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",
    +            "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %u current %u",
                 AcpiUtGetNodeName (ObjDesc->Mutex.Node),
                 ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));
             return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
    @@ -536,7 +542,7 @@ AcpiExReleaseMutex (
          * acquired, but are not released in reverse order.
          */
         PreviousSyncLevel =
    -        WalkState->Thread->AcquiredMutexList->Mutex.OriginalSyncLevel;
    +        OwnerThread->AcquiredMutexList->Mutex.OriginalSyncLevel;
     
         Status = AcpiExReleaseMutexObject (ObjDesc);
         if (ACPI_FAILURE (Status))
    @@ -548,8 +554,9 @@ AcpiExReleaseMutex (
         {
             /* Restore the previous SyncLevel */
     
    -        WalkState->Thread->CurrentSyncLevel = PreviousSyncLevel;
    +        OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
         }
    +
         return_ACPI_STATUS (Status);
     }
     
    @@ -558,7 +565,7 @@ AcpiExReleaseMutex (
      *
      * FUNCTION:    AcpiExReleaseAllMutexes
      *
    - * PARAMETERS:  Thread          - Current executing thread object
    + * PARAMETERS:  Thread              - Current executing thread object
      *
      * RETURN:      Status
      *
    @@ -617,5 +624,3 @@ AcpiExReleaseAllMutexes (
             Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
         }
     }
    -
    -
    diff --git a/sys/contrib/dev/acpica/executer/exnames.c b/sys/contrib/dev/acpica/executer/exnames.c
    index 7134c62d6a4..bd884cb81aa 100644
    --- a/sys/contrib/dev/acpica/executer/exnames.c
    +++ b/sys/contrib/dev/acpica/executer/exnames.c
    @@ -189,7 +189,7 @@ AcpiExAllocateNameString (
         if (!NameString)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Could not allocate size %d", SizeNeeded));
    +            "Could not allocate size %u", SizeNeeded));
             return_PTR (NULL);
         }
     
    @@ -325,7 +325,7 @@ AcpiExNameSegment (
              */
             Status = AE_AML_BAD_NAME;
             ACPI_ERROR ((AE_INFO,
    -            "Bad character %02x in name, at %p",
    +            "Bad character 0x%02x in name, at %p",
                 *AmlAddress, AmlAddress));
         }
     
    diff --git a/sys/contrib/dev/acpica/executer/exoparg1.c b/sys/contrib/dev/acpica/executer/exoparg1.c
    index dff76c61b52..550980f9f3b 100644
    --- a/sys/contrib/dev/acpica/executer/exoparg1.c
    +++ b/sys/contrib/dev/acpica/executer/exoparg1.c
    @@ -193,7 +193,7 @@ AcpiExOpcode_0A_0T_1R (
     
         default:                /*  Unknown opcode  */
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             break;
    @@ -286,7 +286,7 @@ AcpiExOpcode_1A_0T_0R (
     
         default:                /*  Unknown opcode  */
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             break;
    @@ -332,7 +332,7 @@ AcpiExOpcode_1A_1T_0R (
     
         default:                        /* Unknown opcode */
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             goto Cleanup;
    @@ -514,7 +514,7 @@ AcpiExOpcode_1A_1T_1R (
                 if (Digit > 0)
                 {
                     ACPI_ERROR ((AE_INFO,
    -                    "Integer too large to convert to BCD: %8.8X%8.8X",
    +                    "Integer too large to convert to BCD: 0x%8.8X%8.8X",
                         ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
                     Status = AE_AML_NUMERIC_OVERFLOW;
                     goto Cleanup;
    @@ -664,7 +664,7 @@ AcpiExOpcode_1A_1T_1R (
     
         default:                        /* Unknown opcode */
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             goto Cleanup;
    @@ -1116,7 +1116,7 @@ AcpiExOpcode_1A_0T_1R (
                     default:
     
                         ACPI_ERROR ((AE_INFO,
    -                        "Unknown Index TargetType %X in reference object %p",
    +                        "Unknown Index TargetType 0x%X in reference object %p",
                             Operand[0]->Reference.TargetType, Operand[0]));
                         Status = AE_AML_OPERAND_TYPE;
                         goto Cleanup;
    @@ -1143,7 +1143,7 @@ AcpiExOpcode_1A_0T_1R (
     
                 default:
                     ACPI_ERROR ((AE_INFO,
    -                    "Unknown class in reference(%p) - %2.2X",
    +                    "Unknown class in reference(%p) - 0x%2.2X",
                         Operand[0], Operand[0]->Reference.Class));
     
                     Status = AE_TYPE;
    @@ -1155,7 +1155,7 @@ AcpiExOpcode_1A_0T_1R (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             goto Cleanup;
    diff --git a/sys/contrib/dev/acpica/executer/exoparg2.c b/sys/contrib/dev/acpica/executer/exoparg2.c
    index b6e8478f22f..2bedf5a1c9d 100644
    --- a/sys/contrib/dev/acpica/executer/exoparg2.c
    +++ b/sys/contrib/dev/acpica/executer/exoparg2.c
    @@ -206,33 +206,6 @@ AcpiExOpcode_2A_0T_0R (
                 break;
             }
     
    -#ifdef ACPI_GPE_NOTIFY_CHECK
    -        /*
    -         * GPE method wake/notify check.  Here, we want to ensure that we
    -         * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
    -         * GPE method during system runtime.  If we do, the GPE is marked
    -         * as "wake-only" and disabled.
    -         *
    -         * 1) Is the Notify() value == DeviceWake?
    -         * 2) Is this a GPE deferred method?  (An _Lxx or _Exx method)
    -         * 3) Did the original GPE happen at system runtime?
    -         *    (versus during wake)
    -         *
    -         * If all three cases are true, this is a wake-only GPE that should
    -         * be disabled at runtime.
    -         */
    -        if (Value == 2)     /* DeviceWake */
    -        {
    -            Status = AcpiEvCheckForWakeOnlyGpe (WalkState->GpeEventInfo);
    -            if (ACPI_FAILURE (Status))
    -            {
    -                /* AE_WAKE_ONLY_GPE only error, means ignore this notify */
    -
    -                return_ACPI_STATUS (AE_OK)
    -            }
    -        }
    -#endif
    -
             /*
              * Dispatch the notify to the appropriate handler
              * NOTE: the request is queued for execution after this method
    @@ -246,7 +219,7 @@ AcpiExOpcode_2A_0T_0R (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
         }
    @@ -319,7 +292,7 @@ AcpiExOpcode_2A_2T_1R (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             goto Cleanup;
    @@ -555,7 +528,7 @@ AcpiExOpcode_2A_1T_1R (
             if (ACPI_FAILURE (Status))
             {
                 ACPI_EXCEPTION ((AE_INFO, Status,
    -                "Index (%X%8.8X) is beyond end of object",
    +                "Index (0x%8.8X%8.8X) is beyond end of object",
                     ACPI_FORMAT_UINT64 (Index)));
                 goto Cleanup;
             }
    @@ -579,7 +552,7 @@ AcpiExOpcode_2A_1T_1R (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             break;
    @@ -702,7 +675,7 @@ AcpiExOpcode_2A_0T_1R (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             goto Cleanup;
    diff --git a/sys/contrib/dev/acpica/executer/exoparg3.c b/sys/contrib/dev/acpica/executer/exoparg3.c
    index c94a26d272f..9c640c56d6b 100644
    --- a/sys/contrib/dev/acpica/executer/exoparg3.c
    +++ b/sys/contrib/dev/acpica/executer/exoparg3.c
    @@ -206,7 +206,7 @@ AcpiExOpcode_3A_0T_0R (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             goto Cleanup;
    @@ -345,7 +345,7 @@ AcpiExOpcode_3A_1T_1R (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             goto Cleanup;
    diff --git a/sys/contrib/dev/acpica/executer/exoparg6.c b/sys/contrib/dev/acpica/executer/exoparg6.c
    index d13e9f6117a..3d06fa169c5 100644
    --- a/sys/contrib/dev/acpica/executer/exoparg6.c
    +++ b/sys/contrib/dev/acpica/executer/exoparg6.c
    @@ -337,7 +337,7 @@ AcpiExOpcode_6A_0T_1R (
             if (Index >= Operand[0]->Package.Count)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Index (%X%8.8X) beyond package end (%X)",
    +                "Index (0x%8.8X%8.8X) beyond package end (0x%X)",
                     ACPI_FORMAT_UINT64 (Index), Operand[0]->Package.Count));
                 Status = AE_AML_PACKAGE_LIMIT;
                 goto Cleanup;
    @@ -411,7 +411,7 @@ AcpiExOpcode_6A_0T_1R (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 WalkState->Opcode));
             Status = AE_AML_BAD_OPCODE;
             goto Cleanup;
    diff --git a/sys/contrib/dev/acpica/executer/exprep.c b/sys/contrib/dev/acpica/executer/exprep.c
    index b60e09cc15b..3eb5a65255d 100644
    --- a/sys/contrib/dev/acpica/executer/exprep.c
    +++ b/sys/contrib/dev/acpica/executer/exprep.c
    @@ -362,7 +362,7 @@ AcpiExDecodeFieldAccess (
             /* Invalid field access type */
     
             ACPI_ERROR ((AE_INFO,
    -            "Unknown field access type %X",
    +            "Unknown field access type 0x%X",
                 Access));
             return_UINT32 (0);
         }
    @@ -533,7 +533,7 @@ AcpiExPrepFieldValue (
             if (Type != ACPI_TYPE_REGION)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Needed Region, found type %X (%s)",
    +                "Needed Region, found type 0x%X (%s)",
                     Type, AcpiUtGetTypeName (Type)));
     
                 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    diff --git a/sys/contrib/dev/acpica/executer/exregion.c b/sys/contrib/dev/acpica/executer/exregion.c
    index 3969c584bb0..77a500c722e 100644
    --- a/sys/contrib/dev/acpica/executer/exregion.c
    +++ b/sys/contrib/dev/acpica/executer/exregion.c
    @@ -188,7 +188,7 @@ AcpiExSystemMemorySpaceHandler (
             break;
     
         default:
    -        ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %d",
    +        ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u",
                 BitWidth));
             return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
         }
    @@ -265,7 +265,7 @@ AcpiExSystemMemorySpaceHandler (
             if (!MemInfo->MappedLogicalAddress)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Could not map memory at %8.8X%8.8X, size %X",
    +                "Could not map memory at 0x%8.8X%8.8X, size %u",
                     ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) MapLength));
                 MemInfo->MappedLength = 0;
                 return_ACPI_STATUS (AE_NO_MEMORY);
    @@ -608,8 +608,10 @@ AcpiExDataTableSpaceHandler (
         ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
     
     
    -    /* Perform the memory read or write */
    -
    +    /*
    +     * Perform the memory read or write. The BitWidth was already
    +     * validated.
    +     */
         switch (Function)
         {
         case ACPI_READ:
    @@ -619,9 +621,14 @@ AcpiExDataTableSpaceHandler (
             break;
     
         case ACPI_WRITE:
    +
    +        ACPI_MEMCPY (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value),
    +            ACPI_DIV_8 (BitWidth));
    +        break;
    +
         default:
     
    -        return_ACPI_STATUS (AE_SUPPORT);
    +        return_ACPI_STATUS (AE_BAD_PARAMETER);
         }
     
         return_ACPI_STATUS (AE_OK);
    diff --git a/sys/contrib/dev/acpica/executer/exresnte.c b/sys/contrib/dev/acpica/executer/exresnte.c
    index 9a45afde900..7b28f851f9e 100644
    --- a/sys/contrib/dev/acpica/executer/exresnte.c
    +++ b/sys/contrib/dev/acpica/executer/exresnte.c
    @@ -344,7 +344,7 @@ AcpiExResolveNodeToValue (
                 /* No named references are allowed here */
     
                 ACPI_ERROR ((AE_INFO,
    -                "Unsupported Reference type %X",
    +                "Unsupported Reference type 0x%X",
                     SourceDesc->Reference.Class));
     
                 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    @@ -357,7 +357,7 @@ AcpiExResolveNodeToValue (
             /* Default case is for unknown types */
     
             ACPI_ERROR ((AE_INFO,
    -            "Node %p - Unknown object type %X",
    +            "Node %p - Unknown object type 0x%X",
                 Node, EntryType));
     
             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    diff --git a/sys/contrib/dev/acpica/executer/exresolv.c b/sys/contrib/dev/acpica/executer/exresolv.c
    index e587bd1d493..8b19b54f0ee 100644
    --- a/sys/contrib/dev/acpica/executer/exresolv.c
    +++ b/sys/contrib/dev/acpica/executer/exresolv.c
    @@ -326,7 +326,7 @@ AcpiExResolveObjectToValue (
                     /* Invalid reference object */
     
                     ACPI_ERROR ((AE_INFO,
    -                    "Unknown TargetType %X in Index/Reference object %p",
    +                    "Unknown TargetType 0x%X in Index/Reference object %p",
                         StackDesc->Reference.TargetType, StackDesc));
                     Status = AE_AML_INTERNAL;
                     break;
    @@ -367,7 +367,7 @@ AcpiExResolveObjectToValue (
             default:
     
                 ACPI_ERROR ((AE_INFO,
    -                "Unknown Reference type %X in %p", RefType, StackDesc));
    +                "Unknown Reference type 0x%X in %p", RefType, StackDesc));
                 Status = AE_AML_INTERNAL;
                 break;
             }
    @@ -503,7 +503,7 @@ AcpiExResolveMultiple (
                 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
                 {
                     ACPI_ERROR ((AE_INFO,
    -                    "Not a NS node %p [%s]",
    +                    "Not a namespace node %p [%s]",
                         Node, AcpiUtGetDescriptorName (Node)));
                     return_ACPI_STATUS (AE_AML_INTERNAL);
                 }
    @@ -605,7 +605,7 @@ AcpiExResolveMultiple (
             default:
     
                 ACPI_ERROR ((AE_INFO,
    -                "Unknown Reference Class %2.2X", ObjDesc->Reference.Class));
    +                "Unknown Reference Class 0x%2.2X", ObjDesc->Reference.Class));
                 return_ACPI_STATUS (AE_AML_INTERNAL);
             }
         }
    diff --git a/sys/contrib/dev/acpica/executer/exresop.c b/sys/contrib/dev/acpica/executer/exresop.c
    index 22dd558b7d1..211e1d983a4 100644
    --- a/sys/contrib/dev/acpica/executer/exresop.c
    +++ b/sys/contrib/dev/acpica/executer/exresop.c
    @@ -243,7 +243,7 @@ AcpiExResolveOperands (
         ArgTypes = OpInfo->RuntimeArgs;
         if (ArgTypes == ARGI_INVALID_OPCODE)
         {
    -        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
                 Opcode));
     
             return_ACPI_STATUS (AE_AML_INTERNAL);
    @@ -309,7 +309,7 @@ AcpiExResolveOperands (
                 if (!AcpiUtValidObjectType (ObjectType))
                 {
                     ACPI_ERROR ((AE_INFO,
    -                    "Bad operand object type [%X]", ObjectType));
    +                    "Bad operand object type [0x%X]", ObjectType));
     
                     return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
                 }
    @@ -342,7 +342,7 @@ AcpiExResolveOperands (
                     default:
     
                         ACPI_ERROR ((AE_INFO,
    -                        "Unknown Reference Class %2.2X in %p",
    +                        "Unknown Reference Class 0x%2.2X in %p",
                             ObjDesc->Reference.Class, ObjDesc));
     
                         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    @@ -773,7 +773,7 @@ AcpiExResolveOperands (
                 /* Unknown type */
     
                 ACPI_ERROR ((AE_INFO,
    -                "Internal - Unknown ARGI (required operand) type %X",
    +                "Internal - Unknown ARGI (required operand) type 0x%X",
                     ThisArgType));
     
                 return_ACPI_STATUS (AE_BAD_PARAMETER);
    diff --git a/sys/contrib/dev/acpica/executer/exstore.c b/sys/contrib/dev/acpica/executer/exstore.c
    index ff9b940e5bc..c78e106c52b 100644
    --- a/sys/contrib/dev/acpica/executer/exstore.c
    +++ b/sys/contrib/dev/acpica/executer/exstore.c
    @@ -1,4 +1,3 @@
    -
     /******************************************************************************
      *
      * Module Name: exstore - AML Interpreter object store support
    @@ -129,12 +128,6 @@
     
     /* Local prototypes */
     
    -static void
    -AcpiExDoDebugObject (
    -    ACPI_OPERAND_OBJECT     *SourceDesc,
    -    UINT32                  Level,
    -    UINT32                  Index);
    -
     static ACPI_STATUS
     AcpiExStoreObjectToIndex (
         ACPI_OPERAND_OBJECT     *ValDesc,
    @@ -142,218 +135,6 @@ AcpiExStoreObjectToIndex (
         ACPI_WALK_STATE         *WalkState);
     
     
    -/*******************************************************************************
    - *
    - * FUNCTION:    AcpiExDoDebugObject
    - *
    - * PARAMETERS:  SourceDesc          - Value to be stored
    - *              Level               - Indentation level (used for packages)
    - *              Index               - Current package element, zero if not pkg
    - *
    - * RETURN:      None
    - *
    - * DESCRIPTION: Handles stores to the Debug Object.
    - *
    - ******************************************************************************/
    -
    -static void
    -AcpiExDoDebugObject (
    -    ACPI_OPERAND_OBJECT     *SourceDesc,
    -    UINT32                  Level,
    -    UINT32                  Index)
    -{
    -    UINT32                  i;
    -
    -
    -    ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
    -
    -
    -    /* Print line header as long as we are not in the middle of an object display */
    -
    -    if (!((Level > 0) && Index == 0))
    -    {
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
    -            Level, " "));
    -    }
    -
    -    /* Display index for package output only */
    -
    -    if (Index > 0)
    -    {
    -       ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
    -           "(%.2u) ", Index -1));
    -    }
    -
    -    if (!SourceDesc)
    -    {
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[Null Object]\n"));
    -        return_VOID;
    -    }
    -
    -    if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
    -    {
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s ",
    -            AcpiUtGetObjectTypeName (SourceDesc)));
    -
    -        if (!AcpiUtValidInternalObject (SourceDesc))
    -        {
    -           ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
    -               "%p, Invalid Internal Object!\n", SourceDesc));
    -           return_VOID;
    -        }
    -    }
    -    else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
    -    {
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
    -            AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
    -            SourceDesc));
    -        return_VOID;
    -    }
    -    else
    -    {
    -        return_VOID;
    -    }
    -
    -    /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
    -
    -    switch (SourceDesc->Common.Type)
    -    {
    -    case ACPI_TYPE_INTEGER:
    -
    -        /* Output correct integer width */
    -
    -        if (AcpiGbl_IntegerByteWidth == 4)
    -        {
    -            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
    -                (UINT32) SourceDesc->Integer.Value));
    -        }
    -        else
    -        {
    -            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
    -                ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value)));
    -        }
    -        break;
    -
    -    case ACPI_TYPE_BUFFER:
    -
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]\n",
    -            (UINT32) SourceDesc->Buffer.Length));
    -        ACPI_DUMP_BUFFER (SourceDesc->Buffer.Pointer,
    -            (SourceDesc->Buffer.Length < 256) ? SourceDesc->Buffer.Length : 256);
    -        break;
    -
    -    case ACPI_TYPE_STRING:
    -
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
    -            SourceDesc->String.Length, SourceDesc->String.Pointer));
    -        break;
    -
    -    case ACPI_TYPE_PACKAGE:
    -
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[Contains 0x%.2X Elements]\n",
    -            SourceDesc->Package.Count));
    -
    -        /* Output the entire contents of the package */
    -
    -        for (i = 0; i < SourceDesc->Package.Count; i++)
    -        {
    -            AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
    -                Level+4, i+1);
    -        }
    -        break;
    -
    -    case ACPI_TYPE_LOCAL_REFERENCE:
    -
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s] ",
    -            AcpiUtGetReferenceName (SourceDesc)));
    -
    -        /* Decode the reference */
    -
    -        switch (SourceDesc->Reference.Class)
    -        {
    -        case ACPI_REFCLASS_INDEX:
    -
    -            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%X\n",
    -                SourceDesc->Reference.Value));
    -            break;
    -
    -        case ACPI_REFCLASS_TABLE:
    -
    -            /* Case for DdbHandle */
    -
    -            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Table Index 0x%X\n",
    -                SourceDesc->Reference.Value));
    -            return;
    -
    -        default:
    -            break;
    -        }
    -
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "  "));
    -
    -        /* Check for valid node first, then valid object */
    -
    -        if (SourceDesc->Reference.Node)
    -        {
    -            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
    -                    ACPI_DESC_TYPE_NAMED)
    -            {
    -                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
    -                    " %p - Not a valid namespace node\n",
    -                    SourceDesc->Reference.Node));
    -            }
    -            else
    -            {
    -                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Node %p [%4.4s] ",
    -                    SourceDesc->Reference.Node, (SourceDesc->Reference.Node)->Name.Ascii));
    -
    -                switch ((SourceDesc->Reference.Node)->Type)
    -                {
    -                /* These types have no attached object */
    -
    -                case ACPI_TYPE_DEVICE:
    -                    AcpiOsPrintf ("Device\n");
    -                    break;
    -
    -                case ACPI_TYPE_THERMAL:
    -                    AcpiOsPrintf ("Thermal Zone\n");
    -                    break;
    -
    -                default:
    -                    AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
    -                        Level+4, 0);
    -                    break;
    -                }
    -            }
    -        }
    -        else if (SourceDesc->Reference.Object)
    -        {
    -            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
    -                    ACPI_DESC_TYPE_NAMED)
    -            {
    -                AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *)
    -                    SourceDesc->Reference.Object)->Object,
    -                    Level+4, 0);
    -            }
    -            else
    -            {
    -                AcpiExDoDebugObject (SourceDesc->Reference.Object, Level+4, 0);
    -            }
    -        }
    -        break;
    -
    -    default:
    -
    -        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n",
    -            SourceDesc));
    -        break;
    -    }
    -
    -    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
    -    return_VOID;
    -}
    -
    -
     /*******************************************************************************
      *
      * FUNCTION:    AcpiExStore
    @@ -487,13 +268,13 @@ AcpiExStore (
                 "**** Write to Debug Object: Object %p %s ****:\n\n",
                 SourceDesc, AcpiUtGetObjectTypeName (SourceDesc)));
     
    -        AcpiExDoDebugObject (SourceDesc, 0, 0);
    +        ACPI_DEBUG_OBJECT (SourceDesc, 0, 0);
             break;
     
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown Reference Class %2.2X",
    +        ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
                 RefDesc->Reference.Class));
             ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_INFO);
     
    diff --git a/sys/contrib/dev/acpica/executer/exsystem.c b/sys/contrib/dev/acpica/executer/exsystem.c
    index c9f746acb36..96e3063903e 100644
    --- a/sys/contrib/dev/acpica/executer/exsystem.c
    +++ b/sys/contrib/dev/acpica/executer/exsystem.c
    @@ -265,7 +265,7 @@ AcpiExSystemDoStall (
              * (ACPI specifies 100 usec as max, but this gives some slack in
              * order to support existing BIOSs)
              */
    -        ACPI_ERROR ((AE_INFO, "Time parameter is too large (%d)",
    +        ACPI_ERROR ((AE_INFO, "Time parameter is too large (%u)",
                 HowLong));
             Status = AE_AML_OPERAND_VALUE;
         }
    diff --git a/sys/contrib/dev/acpica/hardware/hwregs.c b/sys/contrib/dev/acpica/hardware/hwregs.c
    index 26ee46299f4..050f5b3c632 100644
    --- a/sys/contrib/dev/acpica/hardware/hwregs.c
    +++ b/sys/contrib/dev/acpica/hardware/hwregs.c
    @@ -412,7 +412,7 @@ AcpiHwGetBitRegisterInfo (
     
         if (RegisterId > ACPI_BITREG_MAX)
         {
    -        ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: %X", RegisterId));
    +        ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: 0x%X", RegisterId));
             return (NULL);
         }
     
    @@ -539,7 +539,7 @@ AcpiHwRegisterRead (
     
     
         default:
    -        ACPI_ERROR ((AE_INFO, "Unknown Register ID: %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
                 RegisterId));
             Status = AE_BAD_PARAMETER;
             break;
    @@ -682,7 +682,7 @@ AcpiHwRegisterWrite (
     
     
         default:
    -        ACPI_ERROR ((AE_INFO, "Unknown Register ID: %X",
    +        ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
                 RegisterId));
             Status = AE_BAD_PARAMETER;
             break;
    diff --git a/sys/contrib/dev/acpica/hardware/hwsleep.c b/sys/contrib/dev/acpica/hardware/hwsleep.c
    index 7026c69a025..913deb3de79 100644
    --- a/sys/contrib/dev/acpica/hardware/hwsleep.c
    +++ b/sys/contrib/dev/acpica/hardware/hwsleep.c
    @@ -320,7 +320,7 @@ AcpiEnterSleepState (
         if ((AcpiGbl_SleepTypeA > ACPI_SLEEP_TYPE_MAX) ||
             (AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX))
         {
    -        ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=%X B=%X",
    +        ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
                 AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB));
             return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
         }
    @@ -474,13 +474,16 @@ AcpiEnterSleepState (
                 return_ACPI_STATUS (Status);
             }
     
    -        /*
    -         * Some BIOSs don't set WAK_STS at all.  Give up waiting after
    -         * 1000 retries if it still isn't set.
    -         */
    -        if (Retry-- == 0)
    +        if (AcpiGbl_EnableInterpreterSlack)
             {
    -            break;
    +            /*
    +             * Some BIOSs don't set WAK_STS at all.  Give up waiting after
    +             * 1000 retries if it still isn't set.
    +             */
    +            if (Retry-- == 0)
    +            {
    +                break;
    +            }
             }
     
             /* Spin until we wake */
    diff --git a/sys/contrib/dev/acpica/hardware/hwvalid.c b/sys/contrib/dev/acpica/hardware/hwvalid.c
    index 8c369b18bc2..a7150537268 100644
    --- a/sys/contrib/dev/acpica/hardware/hwvalid.c
    +++ b/sys/contrib/dev/acpica/hardware/hwvalid.c
    @@ -237,7 +237,7 @@ AcpiHwValidateIoRequest (
         if (LastAddress > ACPI_UINT16_MAX)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Illegal I/O port address/length above 64K: 0x%p/%X",
    +            "Illegal I/O port address/length above 64K: %p/0x%X",
                 ACPI_CAST_PTR (void, Address), ByteWidth));
             return_ACPI_STATUS (AE_LIMIT);
         }
    diff --git a/sys/contrib/dev/acpica/include/acdisasm.h b/sys/contrib/dev/acpica/include/acdisasm.h
    index 6c61f84f38b..6d119aa475e 100644
    --- a/sys/contrib/dev/acpica/include/acdisasm.h
    +++ b/sys/contrib/dev/acpica/include/acdisasm.h
    @@ -286,6 +286,7 @@ extern ACPI_DMTABLE_INFO        AcpiDmTableInfoMadt10[];
     extern ACPI_DMTABLE_INFO        AcpiDmTableInfoMadtHdr[];
     extern ACPI_DMTABLE_INFO        AcpiDmTableInfoMcfg[];
     extern ACPI_DMTABLE_INFO        AcpiDmTableInfoMcfg0[];
    +extern ACPI_DMTABLE_INFO        AcpiDmTableInfoMchi[];
     extern ACPI_DMTABLE_INFO        AcpiDmTableInfoMsct[];
     extern ACPI_DMTABLE_INFO        AcpiDmTableInfoMsct0[];
     extern ACPI_DMTABLE_INFO        AcpiDmTableInfoRsdp1[];
    diff --git a/sys/contrib/dev/acpica/include/acevents.h b/sys/contrib/dev/acpica/include/acevents.h
    index 567ac1ec0e1..4d945eff8aa 100644
    --- a/sys/contrib/dev/acpica/include/acevents.h
    +++ b/sys/contrib/dev/acpica/include/acevents.h
    @@ -171,13 +171,11 @@ AcpiEvQueueNotifyRequest (
      */
     ACPI_STATUS
     AcpiEvUpdateGpeEnableMasks (
    -    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
    -    UINT8                   Type);
    +    ACPI_GPE_EVENT_INFO     *GpeEventInfo);
     
     ACPI_STATUS
     AcpiEvEnableGpe (
    -    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
    -    BOOLEAN                 WriteToHardware);
    +    ACPI_GPE_EVENT_INFO     *GpeEventInfo);
     
     ACPI_STATUS
     AcpiEvDisableGpe (
    @@ -188,6 +186,11 @@ AcpiEvGetGpeEventInfo (
         ACPI_HANDLE             GpeDevice,
         UINT32                  GpeNumber);
     
    +ACPI_GPE_EVENT_INFO *
    +AcpiEvLowGetGpeInfo (
    +    UINT32                  GpeNumber,
    +    ACPI_GPE_BLOCK_INFO     *GpeBlock);
    +
     
     /*
      * evgpeblk
    @@ -234,15 +237,6 @@ UINT32
     AcpiEvGpeDetect (
         ACPI_GPE_XRUPT_INFO     *GpeXruptList);
     
    -ACPI_STATUS
    -AcpiEvSetGpeType (
    -    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
    -    UINT8                   Type);
    -
    -ACPI_STATUS
    -AcpiEvCheckForWakeOnlyGpe (
    -    ACPI_GPE_EVENT_INFO     *GpeEventInfo);
    -
     ACPI_STATUS
     AcpiEvGpeInitialize (
         void);
    diff --git a/sys/contrib/dev/acpica/include/acexcep.h b/sys/contrib/dev/acpica/include/acexcep.h
    index 89fe5c66898..a46de7d82f5 100644
    --- a/sys/contrib/dev/acpica/include/acexcep.h
    +++ b/sys/contrib/dev/acpica/include/acexcep.h
    @@ -162,7 +162,7 @@
     #define AE_NO_GLOBAL_LOCK               (ACPI_STATUS) (0x0017 | AE_CODE_ENVIRONMENTAL)
     #define AE_ABORT_METHOD                 (ACPI_STATUS) (0x0018 | AE_CODE_ENVIRONMENTAL)
     #define AE_SAME_HANDLER                 (ACPI_STATUS) (0x0019 | AE_CODE_ENVIRONMENTAL)
    -#define AE_WAKE_ONLY_GPE                (ACPI_STATUS) (0x001A | AE_CODE_ENVIRONMENTAL)
    +#define AE_NO_HANDLER                   (ACPI_STATUS) (0x001A | AE_CODE_ENVIRONMENTAL)
     #define AE_OWNER_ID_LIMIT               (ACPI_STATUS) (0x001B | AE_CODE_ENVIRONMENTAL)
     
     #define AE_CODE_ENV_MAX                 0x001B
    diff --git a/sys/contrib/dev/acpica/include/acglobal.h b/sys/contrib/dev/acpica/include/acglobal.h
    index 4469ee334e3..4f0769e6f67 100644
    --- a/sys/contrib/dev/acpica/include/acglobal.h
    +++ b/sys/contrib/dev/acpica/include/acglobal.h
    @@ -186,6 +186,19 @@ UINT8       ACPI_INIT_GLOBAL (AcpiGbl_LeaveWakeGpesDisabled, TRUE);
      */
     UINT8       ACPI_INIT_GLOBAL (AcpiGbl_UseDefaultRegisterWidths, TRUE);
     
    +/*
    + * Optionally enable output from the AML Debug Object.
    + */
    +UINT8       ACPI_INIT_GLOBAL (AcpiGbl_EnableAmlDebugObject, FALSE);
    +
    +/*
    + * Optionally copy the entire DSDT to local memory (instead of simply
    + * mapping it.) There are some BIOSs that corrupt or replace the original
    + * DSDT, creating the need for this option. Default is FALSE, do not copy
    + * the DSDT.
    + */
    +UINT8       ACPI_INIT_GLOBAL (AcpiGbl_CopyDsdtLocally, FALSE);
    +
     
     /* AcpiGbl_FADT is a local copy of the FADT, converted to a common format. */
     
    @@ -218,6 +231,11 @@ ACPI_EXTERN ACPI_GENERIC_ADDRESS        AcpiGbl_XPm1aEnable;
     ACPI_EXTERN ACPI_GENERIC_ADDRESS        AcpiGbl_XPm1bStatus;
     ACPI_EXTERN ACPI_GENERIC_ADDRESS        AcpiGbl_XPm1bEnable;
     
    +/* DSDT information. Used to check for DSDT corruption */
    +
    +ACPI_EXTERN ACPI_TABLE_HEADER          *AcpiGbl_DSDT;
    +ACPI_EXTERN ACPI_TABLE_HEADER           AcpiGbl_OriginalDsdtHeader;
    +
     /*
      * Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is
      * determined by the revision of the DSDT: If the DSDT revision is less than
    diff --git a/sys/contrib/dev/acpica/include/acinterp.h b/sys/contrib/dev/acpica/include/acinterp.h
    index de7dbf8030e..67142c8911b 100644
    --- a/sys/contrib/dev/acpica/include/acinterp.h
    +++ b/sys/contrib/dev/acpica/include/acinterp.h
    @@ -202,6 +202,16 @@ AcpiExConvertToTargetType (
         ACPI_WALK_STATE         *WalkState);
     
     
    +/*
    + * exdebug - AML debug object
    + */
    +void
    +AcpiExDoDebugObject (
    +    ACPI_OPERAND_OBJECT     *SourceDesc,
    +    UINT32                  Level,
    +    UINT32                  Index);
    +
    +
     /*
      * exfield - ACPI AML (p-code) execution - field manipulation
      */
    diff --git a/sys/contrib/dev/acpica/include/aclocal.h b/sys/contrib/dev/acpica/include/aclocal.h
    index 0aeacff6c52..8818a6ea9b5 100644
    --- a/sys/contrib/dev/acpica/include/aclocal.h
    +++ b/sys/contrib/dev/acpica/include/aclocal.h
    @@ -561,6 +561,8 @@ typedef struct acpi_gpe_event_info
         struct acpi_gpe_register_info   *RegisterInfo;  /* Backpointer to register info */
         UINT8                           Flags;          /* Misc info about this GPE */
         UINT8                           GpeNumber;      /* This GPE */
    +    UINT8                           RuntimeCount;   /* References to a run GPE */
    +    UINT8                           WakeupCount;    /* References to a wake GPE */
     
     } ACPI_GPE_EVENT_INFO;
     
    @@ -590,6 +592,7 @@ typedef struct acpi_gpe_block_info
         ACPI_GPE_EVENT_INFO             *EventInfo;     /* One for each GPE */
         ACPI_GENERIC_ADDRESS            BlockAddress;   /* Base address of the block */
         UINT32                          RegisterCount;  /* Number of register pairs in block */
    +    UINT16                          GpeCount;       /* Number of individual GPEs in block */
         UINT8                           BlockBaseNumber;/* Base GPE number for this block */
     
     } ACPI_GPE_BLOCK_INFO;
    diff --git a/sys/contrib/dev/acpica/include/acoutput.h b/sys/contrib/dev/acpica/include/acoutput.h
    index 8018fed5384..8fca0de3395 100644
    --- a/sys/contrib/dev/acpica/include/acoutput.h
    +++ b/sys/contrib/dev/acpica/include/acoutput.h
    @@ -281,6 +281,7 @@
     #define ACPI_WARNING(plist)             AcpiWarning plist
     #define ACPI_EXCEPTION(plist)           AcpiException plist
     #define ACPI_ERROR(plist)               AcpiError plist
    +#define ACPI_DEBUG_OBJECT(obj,l,i)      AcpiExDoDebugObject(obj,l,i)
     
     #else
     
    @@ -290,6 +291,7 @@
     #define ACPI_WARNING(plist)
     #define ACPI_EXCEPTION(plist)
     #define ACPI_ERROR(plist)
    +#define ACPI_DEBUG_OBJECT(obj,l,i)
     
     #endif /* ACPI_NO_ERROR_MESSAGES */
     
    diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h
    index 7111984df6a..5562fa0215d 100644
    --- a/sys/contrib/dev/acpica/include/acpixf.h
    +++ b/sys/contrib/dev/acpica/include/acpixf.h
    @@ -120,7 +120,7 @@
     
     /* Current ACPICA subsystem version in YYYYMMDD format */
     
    -#define ACPI_CA_VERSION                 0x20100121
    +#define ACPI_CA_VERSION                 0x20100331
     
     #include 
     #include 
    @@ -145,6 +145,8 @@ extern UINT8                AcpiGbl_LeaveWakeGpesDisabled;
     extern UINT8                AcpiGbl_UseDefaultRegisterWidths;
     extern ACPI_NAME            AcpiGbl_TraceMethodName;
     extern UINT32               AcpiGbl_TraceFlags;
    +extern UINT8                AcpiGbl_EnableAmlDebugObject;
    +extern UINT8                AcpiGbl_CopyDsdtLocally;
     
     
     /*
    @@ -462,34 +464,32 @@ AcpiGetEventStatus (
      * GPE Interfaces
      */
     ACPI_STATUS
    -AcpiSetGpeType (
    +AcpiSetGpe (
         ACPI_HANDLE             GpeDevice,
         UINT32                  GpeNumber,
    -    UINT8                   Type);
    +    UINT8                   Action);
     
     ACPI_STATUS
     AcpiEnableGpe (
         ACPI_HANDLE             GpeDevice,
         UINT32                  GpeNumber,
    -    UINT32                  Flags);
    +    UINT8                   GpeType);
     
     ACPI_STATUS
     AcpiDisableGpe (
         ACPI_HANDLE             GpeDevice,
         UINT32                  GpeNumber,
    -    UINT32                  Flags);
    +    UINT8                   GpeType);
     
     ACPI_STATUS
     AcpiClearGpe (
         ACPI_HANDLE             GpeDevice,
    -    UINT32                  GpeNumber,
    -    UINT32                  Flags);
    +    UINT32                  GpeNumber);
     
     ACPI_STATUS
     AcpiGetGpeStatus (
         ACPI_HANDLE             GpeDevice,
         UINT32                  GpeNumber,
    -    UINT32                  Flags,
         ACPI_EVENT_STATUS       *EventStatus);
     
     ACPI_STATUS
    diff --git a/sys/contrib/dev/acpica/include/actables.h b/sys/contrib/dev/acpica/include/actables.h
    index 54fdaae9b1a..9f1c4f00e5a 100644
    --- a/sys/contrib/dev/acpica/include/actables.h
    +++ b/sys/contrib/dev/acpica/include/actables.h
    @@ -230,6 +230,14 @@ AcpiTbVerifyChecksum (
         ACPI_TABLE_HEADER       *Table,
         UINT32                  Length);
     
    +void
    +AcpiTbCheckDsdtHeader (
    +    void);
    +
    +ACPI_TABLE_HEADER *
    +AcpiTbCopyDsdt (
    +    UINT32                  TableIndex);
    +
     void
     AcpiTbInstallTable (
         ACPI_PHYSICAL_ADDRESS   Address,
    diff --git a/sys/contrib/dev/acpica/include/actbl2.h b/sys/contrib/dev/acpica/include/actbl2.h
    index c96715d3c05..7f6ecf84a93 100644
    --- a/sys/contrib/dev/acpica/include/actbl2.h
    +++ b/sys/contrib/dev/acpica/include/actbl2.h
    @@ -143,6 +143,7 @@
     #define ACPI_SIG_IBFT           "IBFT"      /* iSCSI Boot Firmware Table */
     #define ACPI_SIG_IVRS           "IVRS"      /* I/O Virtualization Reporting Structure */
     #define ACPI_SIG_MCFG           "MCFG"      /* PCI Memory Mapped Configuration table */
    +#define ACPI_SIG_MCHI           "MCHI"      /* Management Controller Host Interface table */
     #define ACPI_SIG_SLIC           "SLIC"      /* Software Licensing Description Table */
     #define ACPI_SIG_SPCR           "SPCR"      /* Serial Port Console Redirection table */
     #define ACPI_SIG_SPMI           "SPMI"      /* Server Platform Management Interface table */
    @@ -862,6 +863,35 @@ typedef struct acpi_mcfg_allocation
     } ACPI_MCFG_ALLOCATION;
     
     
    +/*******************************************************************************
    + *
    + * MCHI - Management Controller Host Interface Table
    + *        Version 1
    + *
    + * Conforms to "Management Component Transport Protocol (MCTP) Host
    + * Interface Specification", Revision 1.0.0a, October 13, 2009
    + *
    + ******************************************************************************/
    +
    +typedef struct acpi_table_mchi
    +{
    +    ACPI_TABLE_HEADER       Header;             /* Common ACPI table header */
    +    UINT8                   InterfaceType;
    +    UINT8                   Protocol;
    +    UINT64                  ProtocolData;
    +    UINT8                   InterruptType;
    +    UINT8                   Gpe;
    +    UINT8                   PciDeviceFlag;
    +    UINT32                  GlobalInterrupt;
    +    ACPI_GENERIC_ADDRESS    ControlRegister;
    +    UINT8                   PciSegment;
    +    UINT8                   PciBus;
    +    UINT8                   PciDevice;
    +    UINT8                   PciFunction;
    +
    +} ACPI_TABLE_MCHI;
    +
    +
     /*******************************************************************************
      *
      * SPCR - Serial Port Console Redirection table
    diff --git a/sys/contrib/dev/acpica/include/actypes.h b/sys/contrib/dev/acpica/include/actypes.h
    index 8d0d06ad62c..3c0626ab1e3 100644
    --- a/sys/contrib/dev/acpica/include/actypes.h
    +++ b/sys/contrib/dev/acpica/include/actypes.h
    @@ -742,53 +742,42 @@ typedef UINT32                          ACPI_EVENT_STATUS;
     #define ACPI_GPE_MAX                    0xFF
     #define ACPI_NUM_GPE                    256
     
    +/* Actions for AcpiSetGpe */
    +
     #define ACPI_GPE_ENABLE                 0
     #define ACPI_GPE_DISABLE                1
     
    +/* GpeTypes for AcpiEnableGpe and AcpiDisableGpe */
    +
    +#define ACPI_GPE_TYPE_WAKE              (UINT8) 0x01
    +#define ACPI_GPE_TYPE_RUNTIME           (UINT8) 0x02
    +#define ACPI_GPE_TYPE_WAKE_RUN          (UINT8) 0x03
     
     /*
      * GPE info flags - Per GPE
    - * +-+-+-+---+---+-+
    - * |7|6|5|4:3|2:1|0|
    - * +-+-+-+---+---+-+
    - *  | | |  |   |  |
    - *  | | |  |   |  +--- Interrupt type: Edge or Level Triggered
    - *  | | |  |   +--- Type: Wake-only, Runtime-only, or wake/runtime
    - *  | | |  +--- Type of dispatch -- to method, handler, or none
    - *  | | +--- Enabled for runtime?
    - *  | +--- Enabled for wake?
    - *  +--- Unused
    + * +-------+---+-+-+
    + * |  7:4  |3:2|1|0|
    + * +-------+---+-+-+
    + *     |     |  | |
    + *     |     |  | +--- Interrupt type: edge or level triggered
    + *     |     |  +----- GPE can wake the system
    + *     |     +-------- Type of dispatch:to method, handler, or none
    + *     +-------------- 
      */
     #define ACPI_GPE_XRUPT_TYPE_MASK        (UINT8) 0x01
     #define ACPI_GPE_LEVEL_TRIGGERED        (UINT8) 0x01
     #define ACPI_GPE_EDGE_TRIGGERED         (UINT8) 0x00
     
    -#define ACPI_GPE_TYPE_MASK              (UINT8) 0x06
    -#define ACPI_GPE_TYPE_WAKE_RUN          (UINT8) 0x06
    -#define ACPI_GPE_TYPE_WAKE              (UINT8) 0x02
    -#define ACPI_GPE_TYPE_RUNTIME           (UINT8) 0x04    /* Default */
    +#define ACPI_GPE_CAN_WAKE               (UINT8) 0x02
     
    -#define ACPI_GPE_DISPATCH_MASK          (UINT8) 0x18
    -#define ACPI_GPE_DISPATCH_HANDLER       (UINT8) 0x08
    -#define ACPI_GPE_DISPATCH_METHOD        (UINT8) 0x10
    -#define ACPI_GPE_DISPATCH_NOT_USED      (UINT8) 0x00    /* Default */
    -
    -#define ACPI_GPE_RUN_ENABLE_MASK        (UINT8) 0x20
    -#define ACPI_GPE_RUN_ENABLED            (UINT8) 0x20
    -#define ACPI_GPE_RUN_DISABLED           (UINT8) 0x00    /* Default */
    -
    -#define ACPI_GPE_WAKE_ENABLE_MASK       (UINT8) 0x40
    -#define ACPI_GPE_WAKE_ENABLED           (UINT8) 0x40
    -#define ACPI_GPE_WAKE_DISABLED          (UINT8) 0x00    /* Default */
    -
    -#define ACPI_GPE_ENABLE_MASK            (UINT8) 0x60    /* Both run/wake */
    +#define ACPI_GPE_DISPATCH_MASK          (UINT8) 0x0C
    +#define ACPI_GPE_DISPATCH_HANDLER       (UINT8) 0x04
    +#define ACPI_GPE_DISPATCH_METHOD        (UINT8) 0x08
    +#define ACPI_GPE_DISPATCH_NOT_USED      (UINT8) 0x00
     
     /*
      * Flags for GPE and Lock interfaces
      */
    -#define ACPI_EVENT_WAKE_ENABLE          0x2             /* AcpiGpeEnable */
    -#define ACPI_EVENT_WAKE_DISABLE         0x2             /* AcpiGpeDisable */
    -
     #define ACPI_NOT_ISR                    0x1
     #define ACPI_ISR                        0x0
     
    diff --git a/sys/contrib/dev/acpica/include/platform/acfreebsd.h b/sys/contrib/dev/acpica/include/platform/acfreebsd.h
    index 20ec3a20bf9..c835aaf665d 100644
    --- a/sys/contrib/dev/acpica/include/platform/acfreebsd.h
    +++ b/sys/contrib/dev/acpica/include/platform/acfreebsd.h
    @@ -114,7 +114,7 @@
      *****************************************************************************/
     
     #ifndef __ACFREEBSD_H__
    -#define	__ACFREEBSD_H__
    +#define __ACFREEBSD_H__
     
     
     /* FreeBSD uses GCC */
    @@ -123,11 +123,11 @@
     #include 
     #include 
     
    -#define	ACPI_UINTPTR_T		uintptr_t
    +#define ACPI_UINTPTR_T      uintptr_t
     
    -#define	ACPI_USE_DO_WHILE_0
    -#define	ACPI_USE_LOCAL_CACHE
    -#define	ACPI_USE_SYSTEM_CLIBRARY
    +#define ACPI_USE_DO_WHILE_0
    +#define ACPI_USE_LOCAL_CACHE
    +#define ACPI_USE_SYSTEM_CLIBRARY
     
     #ifdef _KERNEL
     
    @@ -139,18 +139,18 @@
     
     #include "opt_acpi.h"
     
    -#define	ACPI_THREAD_ID		lwpid_t
    -#define	ACPI_MUTEX_TYPE		ACPI_OSL_MUTEX
    +#define ACPI_THREAD_ID      lwpid_t
    +#define ACPI_MUTEX_TYPE     ACPI_OSL_MUTEX
     
     #ifdef ACPI_DEBUG
    -#define	ACPI_DEBUG_OUTPUT	/* for backward compatibility */
    -#define	ACPI_DISASSEMBLER
    +#define ACPI_DEBUG_OUTPUT   /* for backward compatibility */
    +#define ACPI_DISASSEMBLER
     #endif
     
     #ifdef ACPI_DEBUG_OUTPUT
     #include "opt_ddb.h"
     #ifdef DDB
    -#define	ACPI_DEBUGGER
    +#define ACPI_DEBUGGER
     #endif /* DDB */
     #endif /* ACPI_DEBUG_OUTPUT */
     
    @@ -158,7 +158,7 @@
     #undef DEBUGGER_THREADING
     #endif /* DEBUGGER_THREADING */
     
    -#define	DEBUGGER_THREADING	0	/* integrated with DDB */
    +#define DEBUGGER_THREADING  0   /* integrated with DDB */
     
     #else /* _KERNEL */
     
    @@ -166,12 +166,12 @@
     #include 
     #endif
     
    -#define	ACPI_THREAD_ID		pthread_t
    +#define ACPI_THREAD_ID      pthread_t
     
    -#define	ACPI_USE_STANDARD_HEADERS
    +#define ACPI_USE_STANDARD_HEADERS
     
    -#define	ACPI_FLUSH_CPU_CACHE()
    -#define	__cdecl
    +#define ACPI_FLUSH_CPU_CACHE()
    +#define __cdecl
     
     #endif /* _KERNEL */
     
    diff --git a/sys/contrib/dev/acpica/namespace/nsaccess.c b/sys/contrib/dev/acpica/namespace/nsaccess.c
    index e360e28370a..0ee1fae4542 100644
    --- a/sys/contrib/dev/acpica/namespace/nsaccess.c
    +++ b/sys/contrib/dev/acpica/namespace/nsaccess.c
    @@ -306,7 +306,7 @@ AcpiNsRootInitialize (
     
                 default:
     
    -                ACPI_ERROR ((AE_INFO, "Unsupported initial type value %X",
    +                ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X",
                         InitVal->Type));
                     AcpiUtRemoveReference (ObjDesc);
                     ObjDesc = NULL;
    diff --git a/sys/contrib/dev/acpica/namespace/nsdump.c b/sys/contrib/dev/acpica/namespace/nsdump.c
    index a1ae96e5919..2d37135dc21 100644
    --- a/sys/contrib/dev/acpica/namespace/nsdump.c
    +++ b/sys/contrib/dev/acpica/namespace/nsdump.c
    @@ -314,7 +314,7 @@ AcpiNsDumpOneObject (
     
             if (Type > ACPI_TYPE_LOCAL_MAX)
             {
    -            ACPI_WARNING ((AE_INFO, "Invalid ACPI Object Type %08X", Type));
    +            ACPI_WARNING ((AE_INFO, "Invalid ACPI Object Type 0x%08X", Type));
             }
     
             AcpiOsPrintf ("%4.4s", AcpiUtGetNodeName (ThisNode));
    diff --git a/sys/contrib/dev/acpica/namespace/nsnames.c b/sys/contrib/dev/acpica/namespace/nsnames.c
    index c23e6de4f7f..6f26f018a93 100644
    --- a/sys/contrib/dev/acpica/namespace/nsnames.c
    +++ b/sys/contrib/dev/acpica/namespace/nsnames.c
    @@ -191,7 +191,7 @@ AcpiNsBuildExternalPath (
         if (Index != 0)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Could not construct external pathname; index=%X, size=%X, Path=%s",
    +            "Could not construct external pathname; index=%u, size=%u, Path=%s",
                 (UINT32) Index, (UINT32) Size, &NameBuffer[Size]));
     
             return (AE_BAD_PARAMETER);
    diff --git a/sys/contrib/dev/acpica/namespace/nssearch.c b/sys/contrib/dev/acpica/namespace/nssearch.c
    index b583fab1287..24673009aff 100644
    --- a/sys/contrib/dev/acpica/namespace/nssearch.c
    +++ b/sys/contrib/dev/acpica/namespace/nssearch.c
    @@ -397,7 +397,7 @@ AcpiNsSearchAndEnter (
         if (!Node || !TargetName || !ReturnNode)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Null parameter: Node %p Name %X ReturnNode %p",
    +            "Null parameter: Node %p Name 0x%X ReturnNode %p",
                 Node, TargetName, ReturnNode));
             return_ACPI_STATUS (AE_BAD_PARAMETER);
         }
    diff --git a/sys/contrib/dev/acpica/namespace/nsutils.c b/sys/contrib/dev/acpica/namespace/nsutils.c
    index cc42f68b592..7a464c17358 100644
    --- a/sys/contrib/dev/acpica/namespace/nsutils.c
    +++ b/sys/contrib/dev/acpica/namespace/nsutils.c
    @@ -389,7 +389,7 @@ AcpiNsLocal (
         {
             /* Type code out of range  */
     
    -        ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type));
    +        ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
             return_UINT32 (ACPI_NS_NORMAL);
         }
     
    @@ -965,7 +965,7 @@ AcpiNsOpensScope (
         {
             /* type code out of range  */
     
    -        ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type));
    +        ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
             return_UINT32 (ACPI_NS_NORMAL);
         }
     
    diff --git a/sys/contrib/dev/acpica/parser/psargs.c b/sys/contrib/dev/acpica/parser/psargs.c
    index 275993d99a9..609e642a343 100644
    --- a/sys/contrib/dev/acpica/parser/psargs.c
    +++ b/sys/contrib/dev/acpica/parser/psargs.c
    @@ -577,7 +577,7 @@ AcpiPsGetNextSimpleArg (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Invalid ArgType %X", ArgType));
    +        ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
             return_VOID;
         }
     
    @@ -883,7 +883,7 @@ AcpiPsGetNextArg (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Invalid ArgType: %X", ArgType));
    +        ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
             Status = AE_AML_OPERAND_TYPE;
             break;
         }
    diff --git a/sys/contrib/dev/acpica/parser/psloop.c b/sys/contrib/dev/acpica/parser/psloop.c
    index 73bfdf82656..36b4c9abcfb 100644
    --- a/sys/contrib/dev/acpica/parser/psloop.c
    +++ b/sys/contrib/dev/acpica/parser/psloop.c
    @@ -228,7 +228,7 @@ AcpiPsGetAmlOpcode (
             /* The opcode is unrecognized. Just skip unknown opcodes */
     
             ACPI_ERROR ((AE_INFO,
    -             "Found unknown opcode %X at AML address %p offset %X, ignoring",
    +             "Found unknown opcode 0x%X at AML address %p offset 0x%X, ignoring",
                   WalkState->Opcode, WalkState->ParserState.Aml, WalkState->AmlOffset));
     
             ACPI_DUMP_BUFFER (WalkState->ParserState.Aml, 128);
    @@ -1149,7 +1149,6 @@ AcpiPsParseLoop (
                         {
                             ACPI_EXCEPTION ((AE_INFO, Status,
                                 "Invoked method did not return a value"));
    -
                         }
     
                         ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed"));
    diff --git a/sys/contrib/dev/acpica/parser/psxface.c b/sys/contrib/dev/acpica/parser/psxface.c
    index e9fc45de689..52a53c94d9a 100644
    --- a/sys/contrib/dev/acpica/parser/psxface.c
    +++ b/sys/contrib/dev/acpica/parser/psxface.c
    @@ -120,6 +120,7 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
     
     
    @@ -334,6 +335,10 @@ AcpiPsExecuteMethod (
         ACPI_FUNCTION_TRACE (PsExecuteMethod);
     
     
    +    /* Quick validation of DSDT header */
    +
    +    AcpiTbCheckDsdtHeader ();
    +
         /* Validate the Info and method Node */
     
         if (!Info || !Info->ResolvedNode)
    diff --git a/sys/contrib/dev/acpica/resources/rscreate.c b/sys/contrib/dev/acpica/resources/rscreate.c
    index 8e460d2e53c..b5a5f626698 100644
    --- a/sys/contrib/dev/acpica/resources/rscreate.c
    +++ b/sys/contrib/dev/acpica/resources/rscreate.c
    @@ -301,7 +301,7 @@ AcpiRsCreatePciRoutingTable (
             if ((*TopObjectList)->Common.Type != ACPI_TYPE_PACKAGE)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "(PRT[%X]) Need sub-package, found %s",
    +                "(PRT[%u]) Need sub-package, found %s",
                     Index, AcpiUtGetObjectTypeName (*TopObjectList)));
                 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
             }
    @@ -311,7 +311,7 @@ AcpiRsCreatePciRoutingTable (
             if ((*TopObjectList)->Package.Count != 4)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "(PRT[%X]) Need package of length 4, found length %d",
    +                "(PRT[%u]) Need package of length 4, found length %u",
                     Index, (*TopObjectList)->Package.Count));
                 return_ACPI_STATUS (AE_AML_PACKAGE_LIMIT);
             }
    @@ -328,7 +328,7 @@ AcpiRsCreatePciRoutingTable (
             ObjDesc = SubObjectList[0];
             if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
             {
    -            ACPI_ERROR ((AE_INFO, "(PRT[%X].Address) Need Integer, found %s",
    +            ACPI_ERROR ((AE_INFO, "(PRT[%u].Address) Need Integer, found %s",
                     Index, AcpiUtGetObjectTypeName (ObjDesc)));
                 return_ACPI_STATUS (AE_BAD_DATA);
             }
    @@ -340,7 +340,7 @@ AcpiRsCreatePciRoutingTable (
             ObjDesc = SubObjectList[1];
             if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
             {
    -            ACPI_ERROR ((AE_INFO, "(PRT[%X].Pin) Need Integer, found %s",
    +            ACPI_ERROR ((AE_INFO, "(PRT[%u].Pin) Need Integer, found %s",
                     Index, AcpiUtGetObjectTypeName (ObjDesc)));
                 return_ACPI_STATUS (AE_BAD_DATA);
             }
    @@ -378,7 +378,7 @@ AcpiRsCreatePciRoutingTable (
                     if (ObjDesc->Reference.Class != ACPI_REFCLASS_NAME)
                     {
                         ACPI_ERROR ((AE_INFO,
    -                        "(PRT[%X].Source) Need name, found Reference Class %X",
    +                        "(PRT[%u].Source) Need name, found Reference Class 0x%X",
                             Index, ObjDesc->Reference.Class));
                         return_ACPI_STATUS (AE_BAD_DATA);
                     }
    @@ -426,7 +426,7 @@ AcpiRsCreatePciRoutingTable (
                 default:
     
                    ACPI_ERROR ((AE_INFO,
    -                   "(PRT[%X].Source) Need Ref/String/Integer, found %s",
    +                   "(PRT[%u].Source) Need Ref/String/Integer, found %s",
                        Index, AcpiUtGetObjectTypeName (ObjDesc)));
                    return_ACPI_STATUS (AE_BAD_DATA);
                 }
    @@ -442,7 +442,7 @@ AcpiRsCreatePciRoutingTable (
             if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "(PRT[%X].SourceIndex) Need Integer, found %s",
    +                "(PRT[%u].SourceIndex) Need Integer, found %s",
                     Index, AcpiUtGetObjectTypeName (ObjDesc)));
                 return_ACPI_STATUS (AE_BAD_DATA);
             }
    diff --git a/sys/contrib/dev/acpica/resources/rslist.c b/sys/contrib/dev/acpica/resources/rslist.c
    index 1b73cf21835..b6651473c12 100644
    --- a/sys/contrib/dev/acpica/resources/rslist.c
    +++ b/sys/contrib/dev/acpica/resources/rslist.c
    @@ -174,7 +174,7 @@ AcpiRsConvertAmlToResources (
         if (ACPI_FAILURE (Status))
         {
             ACPI_EXCEPTION ((AE_INFO, Status,
    -            "Could not convert AML resource (Type %X)", *Aml));
    +            "Could not convert AML resource (Type 0x%X)", *Aml));
             return_ACPI_STATUS (Status);
         }
     
    @@ -232,7 +232,7 @@ AcpiRsConvertResourcesToAml (
             if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Invalid descriptor type (%X) in resource list",
    +                "Invalid descriptor type (0x%X) in resource list",
                     Resource->Type));
                 return_ACPI_STATUS (AE_BAD_DATA);
             }
    @@ -245,7 +245,7 @@ AcpiRsConvertResourcesToAml (
             if (ACPI_FAILURE (Status))
             {
                 ACPI_EXCEPTION ((AE_INFO, Status,
    -                "Could not convert resource (type %X) to AML",
    +                "Could not convert resource (type 0x%X) to AML",
                     Resource->Type));
                 return_ACPI_STATUS (Status);
             }
    diff --git a/sys/contrib/dev/acpica/resources/rsmisc.c b/sys/contrib/dev/acpica/resources/rsmisc.c
    index 37c1a050a7d..445dea443f1 100644
    --- a/sys/contrib/dev/acpica/resources/rsmisc.c
    +++ b/sys/contrib/dev/acpica/resources/rsmisc.c
    @@ -171,7 +171,7 @@ AcpiRsConvertAmlToResource (
             /* Each internal resource struct is expected to be 32-bit aligned */
     
             ACPI_WARNING ((AE_INFO,
    -            "Misaligned resource pointer (get): %p Type %2.2X Len %X",
    +            "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u",
                 Resource, Resource->Type, Resource->Length));
         }
     
    @@ -659,7 +659,7 @@ Exit:
              * "IRQ Format"), so 0x00 and 0x09 are illegal.
              */
             ACPI_ERROR ((AE_INFO,
    -            "Invalid interrupt polarity/trigger in resource list, %X",
    +            "Invalid interrupt polarity/trigger in resource list, 0x%X",
                 Aml->Irq.Flags));
             return_ACPI_STATUS (AE_BAD_DATA);
         }
    diff --git a/sys/contrib/dev/acpica/tables/tbfadt.c b/sys/contrib/dev/acpica/tables/tbfadt.c
    index 7f2ae36f435..af7d068b862 100644
    --- a/sys/contrib/dev/acpica/tables/tbfadt.c
    +++ b/sys/contrib/dev/acpica/tables/tbfadt.c
    @@ -388,7 +388,7 @@ AcpiTbCreateLocalFadt (
         {
             ACPI_WARNING ((AE_INFO,
                 "FADT (revision %u) is longer than ACPI 2.0 version, "
    -            "truncating length 0x%X to 0x%X",
    +            "truncating length %u to %u",
                 Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT)));
         }
     
    @@ -521,7 +521,7 @@ AcpiTbConvertFadt (
                (Address64->Address != (UINT64) Address32))
             {
                 ACPI_ERROR ((AE_INFO,
    -                "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32",
    +                "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32",
                     FadtInfoTable[i].Name, Address32,
                     ACPI_FORMAT_UINT64 (Address64->Address)));
             }
    @@ -582,7 +582,7 @@ AcpiTbValidateFadt (
         {
             ACPI_WARNING ((AE_INFO,
                 "32/64X FACS address mismatch in FADT - "
    -            "%8.8X/%8.8X%8.8X, using 32",
    +            "0x%8.8X/0x%8.8X%8.8X, using 32",
                 AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs)));
     
             AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
    @@ -593,7 +593,7 @@ AcpiTbValidateFadt (
         {
             ACPI_WARNING ((AE_INFO,
                 "32/64X DSDT address mismatch in FADT - "
    -            "%8.8X/%8.8X%8.8X, using 32",
    +            "0x%8.8X/0x%8.8X%8.8X, using 32",
                 AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt)));
     
             AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
    @@ -621,7 +621,7 @@ AcpiTbValidateFadt (
                (Address64->BitWidth != ACPI_MUL_8 (Length)))
             {
                 ACPI_WARNING ((AE_INFO,
    -                "32/64X length mismatch in %s: %d/%d",
    +                "32/64X length mismatch in %s: %u/%u",
                     Name, ACPI_MUL_8 (Length), Address64->BitWidth));
             }
     
    @@ -635,7 +635,7 @@ AcpiTbValidateFadt (
                 {
                     ACPI_ERROR ((AE_INFO,
                         "Required field %s has zero address and/or length:"
    -                    " %8.8X%8.8X/%X",
    +                    " 0x%8.8X%8.8X/0x%X",
                         Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
                 }
             }
    @@ -651,7 +651,7 @@ AcpiTbValidateFadt (
                 {
                     ACPI_WARNING ((AE_INFO,
                         "Optional field %s has zero address or length: "
    -                    "%8.8X%8.8X/%X",
    +                    "0x%8.8X%8.8X/0x%X",
                         Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
                 }
             }
    @@ -702,7 +702,7 @@ AcpiTbSetupFadtRegisters (
                     (FadtInfoTable[i].DefaultLength != Target64->BitWidth))
                 {
                     ACPI_WARNING ((AE_INFO,
    -                    "Invalid length for %s: %d, using default %d",
    +                    "Invalid length for %s: %u, using default %u",
                         FadtInfoTable[i].Name, Target64->BitWidth,
                         FadtInfoTable[i].DefaultLength));
     
    diff --git a/sys/contrib/dev/acpica/tables/tbutils.c b/sys/contrib/dev/acpica/tables/tbutils.c
    index 25b0652943b..916c04e0241 100644
    --- a/sys/contrib/dev/acpica/tables/tbutils.c
    +++ b/sys/contrib/dev/acpica/tables/tbutils.c
    @@ -349,7 +349,7 @@ AcpiTbVerifyChecksum (
         if (Checksum)
         {
             ACPI_WARNING ((AE_INFO,
    -            "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X",
    +            "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X",
                 Table->Signature, Table->Checksum,
                 (UINT8) (Table->Checksum - Checksum)));
     
    @@ -393,6 +393,88 @@ AcpiTbChecksum (
     }
     
     
    +/*******************************************************************************
    + *
    + * FUNCTION:    AcpiTbCheckDsdtHeader
    + *
    + * PARAMETERS:  None
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
    + *              if the DSDT has been replaced from outside the OS and/or if
    + *              the DSDT header has been corrupted.
    + *
    + ******************************************************************************/
    +
    +void
    +AcpiTbCheckDsdtHeader (
    +    void)
    +{
    +
    +    /* Compare original length and checksum to current values */
    +
    +    if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
    +        AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
    +    {
    +        ACPI_ERROR ((AE_INFO,
    +            "The DSDT has been corrupted or replaced - old, new headers below"));
    +        AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
    +        AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
    +
    +        /* Disable further error messages */
    +
    +        AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
    +        AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
    +    }
    +}
    +
    +
    +/*******************************************************************************
    + *
    + * FUNCTION:    AcpiTbCopyDsdt
    + *
    + * PARAMETERS:  TableDesc           - Installed table to copy
    + *
    + * RETURN:      None
    + *
    + * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
    + *              Some very bad BIOSs are known to either corrupt the DSDT or
    + *              install a new, bad DSDT. This copy works around the problem.
    + *
    + ******************************************************************************/
    +
    +ACPI_TABLE_HEADER *
    +AcpiTbCopyDsdt (
    +    UINT32                  TableIndex)
    +{
    +    ACPI_TABLE_HEADER       *NewTable;
    +    ACPI_TABLE_DESC         *TableDesc;
    +
    +
    +    TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
    +
    +    NewTable = ACPI_ALLOCATE (TableDesc->Length);
    +    if (!NewTable)
    +    {
    +        ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
    +            TableDesc->Length));
    +        return (NULL);
    +    }
    +
    +    ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length);
    +    AcpiTbDeleteTable (TableDesc);
    +    TableDesc->Pointer = NewTable;
    +    TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED;
    +
    +    ACPI_INFO ((AE_INFO,
    +        "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
    +        NewTable->Length));
    +
    +    return (NewTable);
    +}
    +
    +
     /*******************************************************************************
      *
      * FUNCTION:    AcpiTbInstallTable
    @@ -567,7 +649,7 @@ AcpiTbGetRootTableEntry (
                 /* Will truncate 64-bit address to 32 bits, issue warning */
     
                 ACPI_WARNING ((AE_INFO,
    -                "64-bit Physical Address in XSDT is too large (%8.8X%8.8X),"
    +                "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
                     " truncating",
                     ACPI_FORMAT_UINT64 (Address64)));
             }
    diff --git a/sys/contrib/dev/acpica/tables/tbxface.c b/sys/contrib/dev/acpica/tables/tbxface.c
    index 26f9472c5aa..e2eeb2e5aed 100644
    --- a/sys/contrib/dev/acpica/tables/tbxface.c
    +++ b/sys/contrib/dev/acpica/tables/tbxface.c
    @@ -265,6 +265,7 @@ AcpiReallocateRootTable (
     {
         ACPI_TABLE_DESC         *Tables;
         ACPI_SIZE               NewSize;
    +    ACPI_SIZE               CurrentSize;
     
     
         ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
    @@ -279,9 +280,15 @@ AcpiReallocateRootTable (
             return_ACPI_STATUS (AE_SUPPORT);
         }
     
    -    NewSize = ((ACPI_SIZE) AcpiGbl_RootTableList.Count +
    -                    ACPI_ROOT_TABLE_SIZE_INCREMENT) *
    -                sizeof (ACPI_TABLE_DESC);
    +    /*
    +     * Get the current size of the root table and add the default
    +     * increment to create the new table size.
    +     */
    +    CurrentSize = (ACPI_SIZE)
    +        AcpiGbl_RootTableList.Count * sizeof (ACPI_TABLE_DESC);
    +
    +    NewSize = CurrentSize +
    +        (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof (ACPI_TABLE_DESC));
     
         /* Create new array and copy the old array */
     
    @@ -291,10 +298,16 @@ AcpiReallocateRootTable (
             return_ACPI_STATUS (AE_NO_MEMORY);
         }
     
    -    ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, NewSize);
    +    ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, CurrentSize);
     
    -    AcpiGbl_RootTableList.Size = AcpiGbl_RootTableList.Count;
    +    /*
    +     * Update the root table descriptor. The new size will be the current
    +     * number of tables plus the increment, independent of the reserved
    +     * size of the original table list.
    +     */
         AcpiGbl_RootTableList.Tables = Tables;
    +    AcpiGbl_RootTableList.Size =
    +        AcpiGbl_RootTableList.Count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
         AcpiGbl_RootTableList.Flags =
             ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
     
    @@ -534,6 +547,7 @@ AcpiTbLoadNamespace (
     {
         ACPI_STATUS             Status;
         UINT32                  i;
    +    ACPI_TABLE_HEADER       *NewDsdt;
     
     
         ACPI_FUNCTION_TRACE (TbLoadNamespace);
    @@ -542,30 +556,50 @@ AcpiTbLoadNamespace (
         (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
     
         /*
    -     * Load the namespace. The DSDT is required, but any SSDT and PSDT tables
    -     * are optional.
    +     * Load the namespace. The DSDT is required, but any SSDT and
    +     * PSDT tables are optional. Verify the DSDT.
          */
         if (!AcpiGbl_RootTableList.Count ||
             !ACPI_COMPARE_NAME (
                 &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
                 ACPI_SIG_DSDT) ||
    -        ACPI_FAILURE (AcpiTbVerifyTable (
    +         ACPI_FAILURE (AcpiTbVerifyTable (
                 &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
         {
             Status = AE_NO_ACPI_TABLES;
             goto UnlockAndExit;
         }
     
    -    /* A valid DSDT is required */
    +    /*
    +     * Save the DSDT pointer for simple access. This is the mapped memory
    +     * address. We must take care here because the address of the .Tables
    +     * array can change dynamically as tables are loaded at run-time. Note:
    +     * .Pointer field is not validated until after call to AcpiTbVerifyTable.
    +     */
    +    AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
     
    -    Status = AcpiTbVerifyTable (
    -        &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]);
    -    if (ACPI_FAILURE (Status))
    +    /*
    +     * Optionally copy the entire DSDT to local memory (instead of simply
    +     * mapping it.) There are some BIOSs that corrupt or replace the original
    +     * DSDT, creating the need for this option. Default is FALSE, do not copy
    +     * the DSDT.
    +     */
    +    if (AcpiGbl_CopyDsdtLocally)
         {
    -        Status = AE_NO_ACPI_TABLES;
    -        goto UnlockAndExit;
    +        NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
    +        if (NewDsdt)
    +        {
    +            AcpiGbl_DSDT = NewDsdt;
    +        }
         }
     
    +    /*
    +     * Save the original DSDT header for detection of table corruption
    +     * and/or replacement of the DSDT from outside the OS.
    +     */
    +    ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
    +        sizeof (ACPI_TABLE_HEADER));
    +
         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
     
         /* Load and parse tables */
    diff --git a/sys/contrib/dev/acpica/tables/tbxfroot.c b/sys/contrib/dev/acpica/tables/tbxfroot.c
    index 021e2b60a05..9f955e8282d 100644
    --- a/sys/contrib/dev/acpica/tables/tbxfroot.c
    +++ b/sys/contrib/dev/acpica/tables/tbxfroot.c
    @@ -227,7 +227,7 @@ AcpiFindRootPointer (
         if (!TablePtr)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Could not map memory at %8.8X for length %X",
    +            "Could not map memory at 0x%8.8X for length %u",
                 ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
     
             return_ACPI_STATUS (AE_NO_MEMORY);
    @@ -254,7 +254,7 @@ AcpiFindRootPointer (
             if (!TablePtr)
             {
                 ACPI_ERROR ((AE_INFO,
    -                "Could not map memory at %8.8X for length %X",
    +                "Could not map memory at 0x%8.8X for length %u",
                     PhysicalAddress, ACPI_EBDA_WINDOW_SIZE));
     
                 return_ACPI_STATUS (AE_NO_MEMORY);
    @@ -284,7 +284,7 @@ AcpiFindRootPointer (
         if (!TablePtr)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Could not map memory at %8.8X for length %X",
    +            "Could not map memory at 0x%8.8X for length %u",
                 ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
     
             return_ACPI_STATUS (AE_NO_MEMORY);
    diff --git a/sys/contrib/dev/acpica/utilities/utalloc.c b/sys/contrib/dev/acpica/utilities/utalloc.c
    index 8c6ed0b60bf..82f81243763 100644
    --- a/sys/contrib/dev/acpica/utilities/utalloc.c
    +++ b/sys/contrib/dev/acpica/utilities/utalloc.c
    @@ -438,7 +438,7 @@ AcpiUtAllocate (
             /* Report allocation error */
     
             ACPI_WARNING ((Module, Line,
    -            "Could not allocate size %X", (UINT32) Size));
    +            "Could not allocate size %u", (UINT32) Size));
     
             return_PTR (NULL);
         }
    diff --git a/sys/contrib/dev/acpica/utilities/utdelete.c b/sys/contrib/dev/acpica/utilities/utdelete.c
    index bd6490dac3b..f726cf9d157 100644
    --- a/sys/contrib/dev/acpica/utilities/utdelete.c
    +++ b/sys/contrib/dev/acpica/utilities/utdelete.c
    @@ -539,7 +539,7 @@ AcpiUtUpdateRefCount (
     
         default:
     
    -        ACPI_ERROR ((AE_INFO, "Unknown action (%X)", Action));
    +        ACPI_ERROR ((AE_INFO, "Unknown action (0x%X)", Action));
             break;
         }
     
    @@ -550,7 +550,7 @@ AcpiUtUpdateRefCount (
         if (Count > ACPI_MAX_REFERENCE_COUNT)
         {
             ACPI_WARNING ((AE_INFO,
    -            "Large Reference Count (%X) in object %p", Count, Object));
    +            "Large Reference Count (0x%X) in object %p", Count, Object));
         }
     }
     
    diff --git a/sys/contrib/dev/acpica/utilities/uteval.c b/sys/contrib/dev/acpica/utilities/uteval.c
    index be1e45e1aa9..c0790b405a5 100644
    --- a/sys/contrib/dev/acpica/utilities/uteval.c
    +++ b/sys/contrib/dev/acpica/utilities/uteval.c
    @@ -381,7 +381,7 @@ AcpiUtEvaluateObject (
                 PrefixNode, Path, AE_TYPE);
     
             ACPI_ERROR ((AE_INFO,
    -            "Type returned from %s was incorrect: %s, expected Btypes: %X",
    +            "Type returned from %s was incorrect: %s, expected Btypes: 0x%X",
                 Path, AcpiUtGetObjectTypeName (Info->ReturnObject),
                 ExpectedReturnBtypes));
     
    diff --git a/sys/contrib/dev/acpica/utilities/utglobal.c b/sys/contrib/dev/acpica/utilities/utglobal.c
    index df32fc069f8..85a93fe77a6 100644
    --- a/sys/contrib/dev/acpica/utilities/utglobal.c
    +++ b/sys/contrib/dev/acpica/utilities/utglobal.c
    @@ -916,6 +916,7 @@ AcpiUtInitGlobals (
     
         /* Miscellaneous variables */
     
    +    AcpiGbl_DSDT                        = NULL;
         AcpiGbl_CmSingleStep                = FALSE;
         AcpiGbl_DbTerminateThreads          = FALSE;
         AcpiGbl_Shutdown                    = FALSE;
    diff --git a/sys/contrib/dev/acpica/utilities/utmisc.c b/sys/contrib/dev/acpica/utilities/utmisc.c
    index 3bef62c1c6e..1075b0e39b6 100644
    --- a/sys/contrib/dev/acpica/utilities/utmisc.c
    +++ b/sys/contrib/dev/acpica/utilities/utmisc.c
    @@ -308,7 +308,7 @@ AcpiUtAllocateOwnerId (
     
         if (*OwnerId)
         {
    -        ACPI_ERROR ((AE_INFO, "Owner ID [%2.2X] already exists", *OwnerId));
    +        ACPI_ERROR ((AE_INFO, "Owner ID [0x%2.2X] already exists", *OwnerId));
             return_ACPI_STATUS (AE_ALREADY_EXISTS);
         }
     
    @@ -427,7 +427,7 @@ AcpiUtReleaseOwnerId (
     
         if (OwnerId == 0)
         {
    -        ACPI_ERROR ((AE_INFO, "Invalid OwnerId: %2.2X", OwnerId));
    +        ACPI_ERROR ((AE_INFO, "Invalid OwnerId: 0x%2.2X", OwnerId));
             return_VOID;
         }
     
    @@ -457,7 +457,7 @@ AcpiUtReleaseOwnerId (
         else
         {
             ACPI_ERROR ((AE_INFO,
    -            "Release of non-allocated OwnerId: %2.2X", OwnerId + 1));
    +            "Release of non-allocated OwnerId: 0x%2.2X", OwnerId + 1));
         }
     
         (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
    diff --git a/sys/contrib/dev/acpica/utilities/utmutex.c b/sys/contrib/dev/acpica/utilities/utmutex.c
    index d0d47d496d7..2231ab696f3 100644
    --- a/sys/contrib/dev/acpica/utilities/utmutex.c
    +++ b/sys/contrib/dev/acpica/utilities/utmutex.c
    @@ -374,7 +374,7 @@ AcpiUtAcquireMutex (
         else
         {
             ACPI_EXCEPTION ((AE_INFO, Status,
    -            "Thread %p could not acquire Mutex [%X]",
    +            "Thread %p could not acquire Mutex [0x%X]",
                 ACPI_CAST_PTR (void, ThisThreadId), MutexId));
         }
     
    @@ -419,7 +419,7 @@ AcpiUtReleaseMutex (
         if (AcpiGbl_MutexInfo[MutexId].ThreadId == ACPI_MUTEX_NOT_ACQUIRED)
         {
             ACPI_ERROR ((AE_INFO,
    -            "Mutex [%X] is not acquired, cannot release", MutexId));
    +            "Mutex [0x%X] is not acquired, cannot release", MutexId));
     
             return (AE_NOT_ACQUIRED);
         }
    diff --git a/sys/contrib/dev/acpica/utilities/utobject.c b/sys/contrib/dev/acpica/utilities/utobject.c
    index f3ec7920c4f..f83c86b3678 100644
    --- a/sys/contrib/dev/acpica/utilities/utobject.c
    +++ b/sys/contrib/dev/acpica/utilities/utobject.c
    @@ -354,7 +354,7 @@ AcpiUtCreateBufferObject (
             Buffer = ACPI_ALLOCATE_ZEROED (BufferSize);
             if (!Buffer)
             {
    -            ACPI_ERROR ((AE_INFO, "Could not allocate size %X",
    +            ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
                     (UINT32) BufferSize));
                 AcpiUtRemoveReference (BufferDesc);
                 return_PTR (NULL);
    @@ -413,7 +413,7 @@ AcpiUtCreateStringObject (
         String = ACPI_ALLOCATE_ZEROED (StringSize + 1);
         if (!String)
         {
    -        ACPI_ERROR ((AE_INFO, "Could not allocate size %X",
    +        ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
                 (UINT32) StringSize));
             AcpiUtRemoveReference (StringDesc);
             return_PTR (NULL);
    @@ -671,7 +671,7 @@ AcpiUtGetSimpleObjectSize (
                  * required eventually.
                  */
                 ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
    -                "unsupported Reference Class [%s] %X in object %p",
    +                "unsupported Reference Class [%s] 0x%X in object %p",
                     AcpiUtGetReferenceName (InternalObject),
                     InternalObject->Reference.Class, InternalObject));
                 Status = AE_TYPE;
    @@ -683,7 +683,7 @@ AcpiUtGetSimpleObjectSize (
         default:
     
             ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
    -            "unsupported type [%s] %X in object %p",
    +            "unsupported type [%s] 0x%X in object %p",
                 AcpiUtGetObjectTypeName (InternalObject),
                 InternalObject->Common.Type, InternalObject));
             Status = AE_TYPE;
    diff --git a/sys/contrib/dev/acpica/utilities/uttrack.c b/sys/contrib/dev/acpica/utilities/uttrack.c
    index 5c48544792e..ddb35ef891c 100644
    --- a/sys/contrib/dev/acpica/utilities/uttrack.c
    +++ b/sys/contrib/dev/acpica/utilities/uttrack.c
    @@ -282,7 +282,7 @@ AcpiUtAllocateZeroedAndTrack (
             /* Report allocation error */
     
             ACPI_ERROR ((Module, Line,
    -            "Could not allocate size %X", (UINT32) Size));
    +            "Could not allocate size %u", (UINT32) Size));
             return (NULL);
         }
     
    @@ -715,7 +715,7 @@ AcpiUtDumpAllocations (
         else
         {
             ACPI_ERROR ((AE_INFO,
    -            "%d(%X) Outstanding allocations",
    +            "%d(0x%X) Outstanding allocations",
                 NumOutstanding, NumOutstanding));
         }
     
    diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
    index 28bde01d1ad..ec3fce5f6bf 100644
    --- a/sys/dev/acpica/acpi.c
    +++ b/sys/dev/acpica/acpi.c
    @@ -162,6 +162,7 @@ static int	acpi_sname2sstate(const char *sname);
     static const char *acpi_sstate2sname(int sstate);
     static int	acpi_supported_sleep_state_sysctl(SYSCTL_HANDLER_ARGS);
     static int	acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS);
    +static int	acpi_debug_objects_sysctl(SYSCTL_HANDLER_ARGS);
     static int	acpi_pm_func(u_long cmd, void *arg, ...);
     static int	acpi_child_location_str_method(device_t acdev, device_t child,
     					       char *buf, size_t buflen);
    @@ -253,6 +254,19 @@ SYSCTL_STRING(_debug_acpi, OID_AUTO, acpi_ca_version, CTLFLAG_RD,
     static int acpi_serialize_methods;
     TUNABLE_INT("hw.acpi.serialize_methods", &acpi_serialize_methods);
     
    +/* Allow users to dump Debug objects without ACPI debugger. */
    +static int acpi_debug_objects;
    +TUNABLE_INT("debug.acpi.enable_debug_objects", &acpi_debug_objects);
    +SYSCTL_PROC(_debug_acpi, OID_AUTO, enable_debug_objects,
    +    CTLFLAG_RW | CTLTYPE_INT, NULL, 0, acpi_debug_objects_sysctl, "I",
    +    "Enable Debug objects");
    +
    +/* Allow the interpreter to ignore common mistakes in BIOS. */
    +static int acpi_interpreter_slack = 1;
    +TUNABLE_INT("debug.acpi.interpreter_slack", &acpi_interpreter_slack);
    +SYSCTL_INT(_debug_acpi, OID_AUTO, interpreter_slack, CTLFLAG_RDTUN,
    +    &acpi_interpreter_slack, 1, "Turn on interpreter slack mode.");
    +
     /* Power devices off and on in suspend and resume.  XXX Remove once tested. */
     static int acpi_do_powerstate = 1;
     TUNABLE_INT("debug.acpi.do_powerstate", &acpi_do_powerstate);
    @@ -452,8 +466,17 @@ acpi_attach(device_t dev)
          * Set the globals from our tunables.  This is needed because ACPI-CA
          * uses UINT8 for some values and we have no tunable_byte.
          */
    -    AcpiGbl_AllMethodsSerialized = acpi_serialize_methods;
    -    AcpiGbl_EnableInterpreterSlack = TRUE;
    +    AcpiGbl_AllMethodsSerialized = acpi_serialize_methods ? TRUE : FALSE;
    +    AcpiGbl_EnableInterpreterSlack = acpi_interpreter_slack ? TRUE : FALSE;
    +    AcpiGbl_EnableAmlDebugObject = acpi_debug_objects ? TRUE : FALSE;
    +
    +#ifndef ACPI_DEBUG
    +    /*
    +     * Disable all debugging layers and levels.
    +     */
    +    AcpiDbgLayer = 0;
    +    AcpiDbgLevel = 0;
    +#endif
     
         /* Start up the ACPI CA subsystem. */
         status = AcpiInitializeSubsystem();
    @@ -2629,25 +2652,6 @@ acpi_resync_clock(struct acpi_softc *sc)
         inittodr(time_second + sc->acpi_sleep_delay);
     }
     
    -/* Initialize a device's wake GPE. */
    -int
    -acpi_wake_init(device_t dev, int type)
    -{
    -    struct acpi_prw_data prw;
    -
    -    /* Evaluate _PRW to find the GPE. */
    -    if (acpi_parse_prw(acpi_get_handle(dev), &prw) != 0)
    -	return (ENXIO);
    -
    -    /* Set the requested type for the GPE (runtime, wake, or both). */
    -    if (ACPI_FAILURE(AcpiSetGpeType(prw.gpe_handle, prw.gpe_bit, type))) {
    -	device_printf(dev, "set GPE type failed\n");
    -	return (ENXIO);
    -    }
    -
    -    return (0);
    -}
    -
     /* Enable or disable the device's wake GPE. */
     int
     acpi_wake_set_enable(device_t dev, int enable)
    @@ -2662,14 +2666,16 @@ acpi_wake_set_enable(device_t dev, int enable)
     
         flags = acpi_get_flags(dev);
         if (enable) {
    -	status = AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
    +	status = AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit,
    +	    ACPI_GPE_TYPE_WAKE_RUN);
     	if (ACPI_FAILURE(status)) {
     	    device_printf(dev, "enable wake failed\n");
     	    return (ENXIO);
     	}
     	acpi_set_flags(dev, flags | ACPI_FLAG_WAKE_ENABLED);
         } else {
    -	status = AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
    +	status = AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit,
    +	    ACPI_GPE_TYPE_WAKE);
     	if (ACPI_FAILURE(status)) {
     	    device_printf(dev, "disable wake failed\n");
     	    return (ENXIO);
    @@ -2699,7 +2705,7 @@ acpi_wake_sleep_prep(ACPI_HANDLE handle, int sstate)
          * and set _PSW.
          */
         if (sstate > prw.lowest_wake) {
    -	AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
    +	AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_GPE_TYPE_WAKE);
     	if (bootverbose)
     	    device_printf(dev, "wake_prep disabled wake for %s (S%d)\n",
     		acpi_name(handle), sstate);
    @@ -2736,7 +2742,7 @@ acpi_wake_run_prep(ACPI_HANDLE handle, int sstate)
          * clear _PSW and turn off any power resources it used.
          */
         if (sstate > prw.lowest_wake) {
    -	AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
    +	AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_GPE_TYPE_WAKE_RUN);
     	if (bootverbose)
     	    device_printf(dev, "run_prep re-enabled %s\n", acpi_name(handle));
         } else {
    @@ -3534,6 +3540,26 @@ SYSCTL_PROC(_debug_acpi, OID_AUTO, level, CTLFLAG_RW | CTLTYPE_STRING,
     	    "debug.acpi.level", 0, acpi_debug_sysctl, "A", "");
     #endif /* ACPI_DEBUG */
     
    +static int
    +acpi_debug_objects_sysctl(SYSCTL_HANDLER_ARGS)
    +{
    +	int	error;
    +	int	old;
    +
    +	old = acpi_debug_objects;
    +	error = sysctl_handle_int(oidp, &acpi_debug_objects, 0, req);
    +	if (error != 0 || req->newptr == NULL)
    +		return (error);
    +	if (old == acpi_debug_objects || (old && acpi_debug_objects))
    +		return (0);
    +
    +	ACPI_SERIAL_BEGIN(acpi);
    +	AcpiGbl_EnableAmlDebugObject = acpi_debug_objects ? TRUE : FALSE;
    +	ACPI_SERIAL_END(acpi);
    +
    +	return (0);
    +}
    +
     static int
     acpi_pm_func(u_long cmd, void *arg, ...)
     {
    diff --git a/sys/dev/acpica/acpi_button.c b/sys/dev/acpica/acpi_button.c
    index 7814c0e3fdf..56a1d951f79 100644
    --- a/sys/dev/acpica/acpi_button.c
    +++ b/sys/dev/acpica/acpi_button.c
    @@ -164,7 +164,6 @@ acpi_button_attach(device_t dev)
         }
     
         /* Enable the GPE for wake/runtime. */
    -    acpi_wake_init(dev, ACPI_GPE_TYPE_WAKE_RUN);
         acpi_wake_set_enable(dev, 1);
         
         return_VALUE (0);
    diff --git a/sys/dev/acpica/acpi_ec.c b/sys/dev/acpica/acpi_ec.c
    index d4ef0191b88..000658c1848 100644
    --- a/sys/dev/acpica/acpi_ec.c
    +++ b/sys/dev/acpica/acpi_ec.c
    @@ -518,14 +518,8 @@ acpi_ec_attach(device_t dev)
         }
     
         /* Enable runtime GPEs for the handler. */
    -    Status = AcpiSetGpeType(sc->ec_gpehandle, sc->ec_gpebit,
    -			    ACPI_GPE_TYPE_RUNTIME);
    -    if (ACPI_FAILURE(Status)) {
    -	device_printf(dev, "AcpiSetGpeType failed: %s\n",
    -		      AcpiFormatException(Status));
    -	goto error;
    -    }
    -    Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
    +    Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit,
    +	ACPI_GPE_TYPE_RUNTIME);
         if (ACPI_FAILURE(Status)) {
     	device_printf(dev, "AcpiEnableGpe failed: %s\n",
     		      AcpiFormatException(Status));
    @@ -575,7 +569,7 @@ acpi_ec_shutdown(device_t dev)
     
         /* Disable the GPE so we don't get EC events during shutdown. */
         sc = device_get_softc(dev);
    -    AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
    +    AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_GPE_TYPE_RUNTIME);
         return (0);
     }
     
    diff --git a/sys/dev/acpica/acpi_lid.c b/sys/dev/acpica/acpi_lid.c
    index 47d5b45c1f9..ae29aca923c 100644
    --- a/sys/dev/acpica/acpi_lid.c
    +++ b/sys/dev/acpica/acpi_lid.c
    @@ -115,7 +115,6 @@ acpi_lid_attach(device_t dev)
     			     acpi_lid_notify_handler, sc);
     
         /* Enable the GPE for wake/runtime. */
    -    acpi_wake_init(dev, ACPI_GPE_TYPE_WAKE_RUN);
         acpi_wake_set_enable(dev, 1);
     
         return (0);
    diff --git a/sys/dev/acpica/acpi_video.c b/sys/dev/acpica/acpi_video.c
    index 94ef7be655b..a8625de89b7 100644
    --- a/sys/dev/acpica/acpi_video.c
    +++ b/sys/dev/acpica/acpi_video.c
    @@ -584,8 +584,8 @@ acpi_video_vo_bind(struct acpi_video_output *vo, ACPI_HANDLE handle)
     			vo->vo_economy = vo->vo_levels[BCL_ECONOMY];
     	}
     	if (vo->vo_levels != NULL)
    -	    AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
    -		acpi_video_vo_notify_handler, vo);
    +		AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
    +		    acpi_video_vo_notify_handler, vo);
     	ACPI_SERIAL_END(video_output);
     }
     
    diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
    index 5c827f2b534..b0f2c93b8f7 100644
    --- a/sys/dev/acpica/acpivar.h
    +++ b/sys/dev/acpica/acpivar.h
    @@ -334,7 +334,6 @@ int		acpi_ReqSleepState(struct acpi_softc *sc, int state);
     int		acpi_AckSleepState(struct apm_clone_data *clone, int error);
     ACPI_STATUS	acpi_SetSleepState(struct acpi_softc *sc, int state);
     void		acpi_resync_clock(struct acpi_softc *sc);
    -int		acpi_wake_init(device_t dev, int type);
     int		acpi_wake_set_enable(device_t dev, int enable);
     int		acpi_parse_prw(ACPI_HANDLE h, struct acpi_prw_data *prw);
     ACPI_STATUS	acpi_Startup(void);
    diff --git a/sys/modules/acpi/acpi/Makefile b/sys/modules/acpi/acpi/Makefile
    index 992c59c09a6..6fa36ffcd70 100644
    --- a/sys/modules/acpi/acpi/Makefile
    +++ b/sys/modules/acpi/acpi/Makefile
    @@ -1,11 +1,11 @@
     # $FreeBSD$
     
    -.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64"
    -.error "ACPI can only be compiled into the kernel on the amd64 and ia64 platforms"
    +.if ${MACHINE_ARCH} == "ia64"
    +.error "ACPI can only be compiled into the kernel on the ia64 platform"
     .endif
     
    -.if ${MACHINE} != "i386"
    -.error "The ACPI module is only for i386"
    +.if ${MACHINE} != "amd64" && ${MACHINE} != "i386"
    +.error "The ACPI module is only for amd64 and i386"
     .endif
     
     .PATH:	${.CURDIR}/../../../contrib/dev/acpica/debugger \
    @@ -35,10 +35,10 @@ 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
     SRCS+=	evxface.c evxfevnt.c evxfregn.c
    -SRCS+=	exconfig.c exconvrt.c excreate.c exdump.c exfield.c exfldio.c exmisc.c
    -SRCS+=	exmutex.c exnames.c exoparg1.c exoparg2.c exoparg3.c exoparg6.c
    -SRCS+=	exprep.c exregion.c exresnte.c exresolv.c exresop.c exstore.c
    -SRCS+=	exstoren.c exstorob.c exsystem.c exutils.c
    +SRCS+=	exconfig.c exconvrt.c excreate.c exdebug.c exdump.c exfield.c
    +SRCS+=	exfldio.c exmisc.c exmutex.c exnames.c exoparg1.c exoparg2.c
    +SRCS+=	exoparg3.c exoparg6.c exprep.c exregion.c exresnte.c exresolv.c
    +SRCS+=	exresop.c exstore.c exstoren.c exstorob.c exsystem.c exutils.c
     SRCS+=	hwacpi.c hwgpe.c hwregs.c hwsleep.c hwtimer.c hwvalid.c hwxface.c
     SRCS+=	nsaccess.c nsalloc.c nsdump.c nseval.c nsinit.c nsload.c nsnames.c
     SRCS+=	nsobject.c nsparse.c nspredef.c nsrepair.c nsrepair2.c nssearch.c
    @@ -97,9 +97,13 @@ opt_ddb.h: Makefile
     SRCS+=	acpi_machdep.c acpi_wakecode.h acpi_wakeup.c
     SRCS+=	assym.s madt.c
     CLEANFILES+=	acpi_wakecode.bin acpi_wakecode.h acpi_wakecode.o
    +
     .if ${MACHINE_ARCH} == "amd64"
    -SRCS+=	opt_global.h
    +SRCS+=	acpi_switch.S opt_global.h
     CLEANFILES+=	acpi_wakedata.h
    +ASM_CFLAGS=	-x assembler-with-cpp -DLOCORE ${CFLAGS}
    +acpi_switch.o:	acpi_switch.S
    +	${CC} -c ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}
     .endif
     
     acpi_wakecode.h: acpi_wakecode.S assym.s
    diff --git a/usr.sbin/acpi/acpidb/Makefile b/usr.sbin/acpi/acpidb/Makefile
    index 5981f38d3db..c2fe844367b 100644
    --- a/usr.sbin/acpi/acpidb/Makefile
    +++ b/usr.sbin/acpi/acpidb/Makefile
    @@ -25,11 +25,11 @@ SRCS+=	dsfield.c dsinit.c dsmethod.c dsmthdat.c dsobject.c	\
     	dswstate.c
     
     # interpreter/executer
    -SRCS+=	exconfig.c exconvrt.c excreate.c exdump.c exfield.c	\
    -	exfldio.c exmisc.c exmutex.c exnames.c exoparg1.c	\
    -	exoparg2.c exoparg3.c exoparg6.c exprep.c exregion.c	\
    -	exresnte.c exresolv.c exresop.c exstore.c exstoren.c	\
    -	exstorob.c exsystem.c exutils.c
    +SRCS+=	exconfig.c exconvrt.c excreate.c exdebug.c exdump.c	\
    +	exfield.c exfldio.c exmisc.c exmutex.c exnames.c	\
    +	exoparg1.c exoparg2.c exoparg3.c exoparg6.c exprep.c	\
    +	exregion.c exresnte.c exresolv.c exresop.c exstore.c	\
    +	exstoren.c exstorob.c exsystem.c exutils.c
     
     # interpreter/parser
     SRCS+=	psargs.c psloop.c psopcode.c psparse.c psscope.c	\
    diff --git a/usr.sbin/acpi/iasl/Makefile b/usr.sbin/acpi/iasl/Makefile
    index ff6ebd7fbee..98b0c238649 100644
    --- a/usr.sbin/acpi/iasl/Makefile
    +++ b/usr.sbin/acpi/iasl/Makefile
    @@ -13,9 +13,9 @@ SRCS+=	aslanalyze.c aslcodegen.c aslcompile.c aslcompiler.y.h	\
     	aslcompilerlex.l aslcompilerparse.y aslerror.c		\
     	aslfiles.c aslfold.c asllength.c asllisting.c		\
     	aslload.c asllookup.c aslmain.c aslmap.c aslopcodes.c	\
    -	asloperands.c aslopt.c aslresource.c aslrestype1.c	\
    -	aslrestype2.c aslstartup.c aslstubs.c asltransform.c	\
    -	asltree.c aslutils.c
    +	asloperands.c aslopt.c aslpredef.c aslresource.c	\
    +	aslrestype1.c aslrestype2.c aslstartup.c aslstubs.c	\
    +	asltransform.c asltree.c aslutils.c
     
     # debugger
     SRCS+=	dbfileio.c
    
    From 91f671cf9216673f670e37a3d950bd935293ef67 Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Tue, 27 Apr 2010 01:00:22 +0000
    Subject: [PATCH 2123/2592] MFC: r206880 For the experimental NFS client doing
     an NFSv4 mount, set the NFSCLFLAGS_RECVRINPROG while doing recovery from an
     expired lease in a manner similar to r206818 for server reboot recovery. This
     will prevent the function that acquires stateids for I/O operations from
     acquiring out of date stateids during recovery. Also, fix up mutex locking on
     the nfsc_flags field.
    
    ---
     sys/fs/nfsclient/nfs_clstate.c | 9 ++++++---
     1 file changed, 6 insertions(+), 3 deletions(-)
    
    diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
    index 6a189635ff7..78b596640cf 100644
    --- a/sys/fs/nfsclient/nfs_clstate.c
    +++ b/sys/fs/nfsclient/nfs_clstate.c
    @@ -2111,6 +2111,7 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
     		NFSUNLOCKCLSTATE();
     		return (0);
     	}
    +	clp->nfsc_flags |= NFSCLFLAGS_RECVRINPROG;
     	NFSUNLOCKCLSTATE();
     
     	nmp = clp->nfsc_nmp;
    @@ -2127,6 +2128,7 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
     		 * Clear out any state.
     		 */
     		nfscl_cleanclient(clp);
    +		NFSLOCKCLSTATE();
     		clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID |
     		    NFSCLFLAGS_RECOVER);
     	} else {
    @@ -2140,14 +2142,15 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
     		 * Expire the state for the client.
     		 */
     		nfscl_expireclient(clp, nmp, cred, p);
    +		NFSLOCKCLSTATE();
     		clp->nfsc_flags |= NFSCLFLAGS_HASCLIENTID;
     		clp->nfsc_flags &= ~NFSCLFLAGS_RECOVER;
     	}
    -	NFSFREECRED(cred);
    -	clp->nfsc_flags &= ~NFSCLFLAGS_EXPIREIT;
    -	NFSLOCKCLSTATE();
    +	clp->nfsc_flags &= ~(NFSCLFLAGS_EXPIREIT | NFSCLFLAGS_RECVRINPROG);
    +	wakeup(&clp->nfsc_flags);
     	nfsv4_unlock(&clp->nfsc_lock, 0);
     	NFSUNLOCKCLSTATE();
    +	NFSFREECRED(cred);
     	return (error);
     }
     
    
    From 3b23a422c334948c72f6fdb71b802b01cf19aca7 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 27 Apr 2010 10:47:54 +0000
    Subject: [PATCH 2124/2592] MFC r206547: Handle a case in kern_openat() when
     vn_open() change file type from DTYPE_VNODE.
    
    ---
     sys/kern/vfs_syscalls.c | 17 ++---------------
     1 file changed, 2 insertions(+), 15 deletions(-)
    
    diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
    index 84f4be45352..b3753c2efcb 100644
    --- a/sys/kern/vfs_syscalls.c
    +++ b/sys/kern/vfs_syscalls.c
    @@ -1047,8 +1047,6 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
     	struct filedesc *fdp = p->p_fd;
     	struct file *fp;
     	struct vnode *vp;
    -	struct vattr vat;
    -	struct mount *mp;
     	int cmode;
     	struct file *nfp;
     	int type, indx, error;
    @@ -1141,7 +1139,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
     	}
     
     	VOP_UNLOCK(vp, 0);
    -	if (flags & (O_EXLOCK | O_SHLOCK)) {
    +	if (fp->f_type == DTYPE_VNODE && (flags & (O_EXLOCK | O_SHLOCK)) != 0) {
     		lf.l_whence = SEEK_SET;
     		lf.l_start = 0;
     		lf.l_len = 0;
    @@ -1158,18 +1156,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
     		atomic_set_int(&fp->f_flag, FHASLOCK);
     	}
     	if (flags & O_TRUNC) {
    -		if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
    -			goto bad;
    -		VATTR_NULL(&vat);
    -		vat.va_size = 0;
    -		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
    -#ifdef MAC
    -		error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp);
    -		if (error == 0)
    -#endif
    -			error = VOP_SETATTR(vp, &vat, td->td_ucred);
    -		VOP_UNLOCK(vp, 0);
    -		vn_finished_write(mp);
    +		error = fo_truncate(fp, 0, td->td_ucred, td);
     		if (error)
     			goto bad;
     	}
    
    From ea5e5dda7b2097ddde19c5d151c4840a75026c0d Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Tue, 27 Apr 2010 10:50:09 +0000
    Subject: [PATCH 2125/2592] MFC r206992: As was done in r155238 for i386 and in
     r155239 for amd64, clear the carry flag for ia32 binary executed on amd64
     host in get_mcontext().
    
    ---
     sys/amd64/ia32/ia32_signal.c | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
    index 241698818c3..15ba947473c 100644
    --- a/sys/amd64/ia32/ia32_signal.c
    +++ b/sys/amd64/ia32/ia32_signal.c
    @@ -141,9 +141,11 @@ ia32_get_mcontext(struct thread *td, struct ia32_mcontext *mcp, int flags)
     	mcp->mc_esi = tp->tf_rsi;
     	mcp->mc_ebp = tp->tf_rbp;
     	mcp->mc_isp = tp->tf_rsp;
    +	mcp->mc_eflags = tp->tf_rflags;
     	if (flags & GET_MC_CLEAR_RET) {
     		mcp->mc_eax = 0;
     		mcp->mc_edx = 0;
    +		mcp->mc_eflags &= ~PSL_C;
     	} else {
     		mcp->mc_eax = tp->tf_rax;
     		mcp->mc_edx = tp->tf_rdx;
    @@ -152,7 +154,6 @@ ia32_get_mcontext(struct thread *td, struct ia32_mcontext *mcp, int flags)
     	mcp->mc_ecx = tp->tf_rcx;
     	mcp->mc_eip = tp->tf_rip;
     	mcp->mc_cs = tp->tf_cs;
    -	mcp->mc_eflags = tp->tf_rflags;
     	mcp->mc_esp = tp->tf_rsp;
     	mcp->mc_ss = tp->tf_ss;
     	mcp->mc_len = sizeof(*mcp);
    
    From 300cdd3c94d10f3e06bc22f78385b446ea581232 Mon Sep 17 00:00:00 2001
    From: Bruce M Simpson 
    Date: Tue, 27 Apr 2010 13:27:51 +0000
    Subject: [PATCH 2126/2592] MFC 206454:   When embedding the scope ID in MLDv1
     output, check if the scope of the address   being embedded is in fact
     link-local, before attempting to embed it.
    
      Note that this operation is a side-effect of trying to avoid recursion on
      the IN6 scope lock.
    
    PR:		144560
    Submitted by:	Petr Lampa
    ---
     sys/netinet6/mld6.c | 6 ++++--
     1 file changed, 4 insertions(+), 2 deletions(-)
    
    diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
    index cade0d2b208..21d9eabe363 100644
    --- a/sys/netinet6/mld6.c
    +++ b/sys/netinet6/mld6.c
    @@ -195,8 +195,10 @@ static int	sysctl_mld_ifinfo(SYSCTL_HANDLER_ARGS);
     static struct mtx		 mld_mtx;
     MALLOC_DEFINE(M_MLD, "mld", "mld state");
     
    -#define	MLD_EMBEDSCOPE(pin6, zoneid) \
    -	(pin6)->s6_addr16[1] = htons((zoneid) & 0xFFFF)
    +#define	MLD_EMBEDSCOPE(pin6, zoneid)					\
    +	if (IN6_IS_SCOPE_LINKLOCAL(pin6) ||				\
    +	    IN6_IS_ADDR_MC_INTFACELOCAL(pin6))				\
    +		(pin6)->s6_addr16[1] = htons((zoneid) & 0xFFFF)		\
     
     /*
      * VIMAGE-wide globals.
    
    From 3db0099738ccad523959de4956a55e0747c30d8a Mon Sep 17 00:00:00 2001
    From: Bruce M Simpson 
    Date: Tue, 27 Apr 2010 13:50:15 +0000
    Subject: [PATCH 2127/2592] MFC 206452:   Fix a few issues related to the
     legacy 4.4 BSD multicast APIs.
    
      IPv4 addresses can and do change during normal operation. Testing by
      pfSense developers exposed an issue where OpenOSPFD was using the IPv4
      address to leave the OSPF link-scope multicast groups on a dynamic
      OpenVPN tun interface, rather than using RFC 3678 with the interface
      index, which won't be raced when the interface's addresses change.
    
      In inp_join_group():
       If we are already a member of an ASM group, and IP_ADD_MEMBERSHIP or
       MCAST_JOIN_GROUP ioctls are re-issued, return EADDRINUSE as per the
       legacy 4.4BSD multicast API. This bends RFC 3678 slightly, but does
       not violate POLA for apps using the old API.
       It also stops us falling through to kicking IGMP state transactions
       in what is otherwise a no-op case.
       [This has already been dealt with in HEAD, but make it explicit before
        we MFC the change to 8.]
    
      In inp_leave_group():
       Fix a bogus conditional.
       Move the ifp null check to ioctls MCAST_LEAVE* in the switch..case
       where it actually belongs.
       If an interface was specified, by primary IPv4 address, for ioctl
       IP_DROP_MEMBERSHIP or MCAST_LEAVE_GROUP (an ASM full leave operation),
       then and only then should we look up the ifp from the IPv4 address in
       mreqs.imr_interface.
       If not, we fall through to imo_match_group() as before, but only in
       the IP_DROP_MEMBERSHIP case.
    
      With these changes, the legacy 4.4BSD multicast API idempotence should
      be mostly preserved in the SSM enabled IPv4 stack.
    
      [Note: this is not a straight svn merge as head and 8 differ slightly]
    
    Found by:	ermal (with pfSense)
    ---
     sys/netinet/in_mcast.c | 26 ++++++++++++++++++++++----
     1 file changed, 22 insertions(+), 4 deletions(-)
    
    diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
    index 11294be72a0..811d935ba99 100644
    --- a/sys/netinet/in_mcast.c
    +++ b/sys/netinet/in_mcast.c
    @@ -1991,6 +1991,17 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
     				error = EINVAL;
     				goto out_inp_locked;
     			}
    +			/*
    +			 * MCAST_JOIN_GROUP on an existing exclusive
    +			 * membership is an error; return EADDRINUSE
    +			 * to preserve 4.4BSD API idempotence, and
    +			 * avoid tedious detour to code below.
    +			 * NOTE: This is bending RFC 3678 a bit.
    +			 */
    +			if (imf->imf_st[1] == MCAST_EXCLUDE) {
    +				error = EADDRINUSE;
    +				goto out_inp_locked;
    +			}
     		}
     	}
     
    @@ -2161,7 +2172,14 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
     			ssa->sin.sin_addr = mreqs.imr_sourceaddr;
     		}
     
    -		if (!in_nullhost(gsa->sin.sin_addr))
    +		/*
    +		 * Attempt to look up hinted ifp from interface address.
    +		 * Fallthrough with null ifp iff lookup fails, to
    +		 * preserve 4.4BSD mcast API idempotence.
    +		 * XXX NOTE WELL: The RFC 3678 API is preferred because
    +		 * using an IPv4 address as a key is racy.
    +		 */
    +		if (!in_nullhost(mreqs.imr_interface))
     			INADDR_TO_IFP(mreqs.imr_interface, ifp);
     
     		CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p",
    @@ -2197,6 +2215,9 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
     			return (EADDRNOTAVAIL);
     
     		ifp = ifnet_byindex(gsr.gsr_interface);
    +
    +		if (ifp == NULL)
    +			return (EADDRNOTAVAIL);
     		break;
     
     	default:
    @@ -2209,9 +2230,6 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
     	if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
     		return (EINVAL);
     
    -	if (ifp == NULL)
    -		return (EADDRNOTAVAIL);
    -
     	/*
     	 * Find the membership in the membership array.
     	 */
    
    From 953a22892c03880d47ed0d688b7f4bee7a7f507a Mon Sep 17 00:00:00 2001
    From: Andrew Gallatin 
    Date: Tue, 27 Apr 2010 15:38:58 +0000
    Subject: [PATCH 2128/2592] MFC 206662: Cleanup if_media handling in mxge(4)
    
    ---
     sys/dev/mxge/if_mxge.c     | 115 +++++++++++++++++++++++--------------
     sys/dev/mxge/if_mxge_var.h |   8 +++
     2 files changed, 79 insertions(+), 44 deletions(-)
    
    diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
    index 643a78a9dce..e0718adcdec 100644
    --- a/sys/dev/mxge/if_mxge.c
    +++ b/sys/dev/mxge/if_mxge.c
    @@ -883,6 +883,9 @@ mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data)
     		case MXGEFW_CMD_ERROR_BUSY:
     			err = EBUSY;
     			break;
    +		case MXGEFW_CMD_ERROR_I2C_ABSENT:
    +			err = ENXIO;
    +			break;
     		default:
     			device_printf(sc->dev, 
     				      "mxge: command %d "
    @@ -2782,37 +2785,25 @@ static struct mxge_media_type mxge_sfp_media_types[] =
     };
     
     static void
    -mxge_set_media(mxge_softc_t *sc, int type)
    +mxge_media_set(mxge_softc_t *sc, int media_type)
     {
    -	sc->media_flags |= type;
    -	ifmedia_add(&sc->media, sc->media_flags, 0, NULL);
    -	ifmedia_set(&sc->media, sc->media_flags);
    +
    +	
    +	ifmedia_add(&sc->media, IFM_ETHER | IFM_FDX | media_type, 
    +		    0, NULL);
    +	ifmedia_set(&sc->media, IFM_ETHER | IFM_FDX | media_type);
    +	sc->current_media = media_type;
    +	sc->media.ifm_media = sc->media.ifm_cur->ifm_media;
     }
     
    -
    -/*
    - * Determine the media type for a NIC.  Some XFPs will identify
    - * themselves only when their link is up, so this is initiated via a
    - * link up interrupt.  However, this can potentially take up to
    - * several milliseconds, so it is run via the watchdog routine, rather
    - * than in the interrupt handler itself.   This need only be done
    - * once, not each time the link is up.
    - */
     static void
    -mxge_media_probe(mxge_softc_t *sc)
    +mxge_media_init(mxge_softc_t *sc)
     {
    -	mxge_cmd_t cmd;
    -	char *cage_type;
     	char *ptr;
    -	struct mxge_media_type *mxge_media_types = NULL;
    -	int i, err, ms, mxge_media_type_entries;
    -	uint32_t byte;
    +	int i;
     
    -	sc->need_media_probe = 0;
    -
    -	/* if we've already set a media type, we're done */
    -	if (sc->media_flags  != (IFM_ETHER | IFM_AUTO))
    -		return;
    +	ifmedia_removeall(&sc->media);
    +	mxge_media_set(sc, IFM_AUTO);
     
     	/* 
     	 * parse the product code to deterimine the interface type
    @@ -2823,6 +2814,7 @@ mxge_media_probe(mxge_softc_t *sc)
     	ptr = sc->product_code_string;
     	if (ptr == NULL) {
     		device_printf(sc->dev, "Missing product code\n");
    +		return;
     	}
     
     	for (i = 0; i < 3; i++, ptr++) {
    @@ -2835,17 +2827,44 @@ mxge_media_probe(mxge_softc_t *sc)
     	}
     	if (*ptr == 'C') {
     		/* -C is CX4 */
    -		mxge_set_media(sc, IFM_10G_CX4);
    -		return;
    -	}
    -	else if (*ptr == 'Q') {
    +		sc->connector = MXGE_CX4;
    +		mxge_media_set(sc, IFM_10G_CX4);
    +	} else if (*ptr == 'Q') {
     		/* -Q is Quad Ribbon Fiber */
    +		sc->connector = MXGE_QRF;
     		device_printf(sc->dev, "Quad Ribbon Fiber Media\n");
     		/* FreeBSD has no media type for Quad ribbon fiber */
    -		return;
    +	} else if (*ptr == 'R') {
    +		/* -R is XFP */
    +		sc->connector = MXGE_XFP;
    +	} else if (*ptr == 'S' || *(ptr +1) == 'S') {
    +		/* -S or -2S is SFP+ */
    +		sc->connector = MXGE_SFP;
    +	} else {
    +		device_printf(sc->dev, "Unknown media type: %c\n", *ptr);
     	}
    +}
     
    -	if (*ptr == 'R') {
    +/*
    + * Determine the media type for a NIC.  Some XFPs will identify
    + * themselves only when their link is up, so this is initiated via a
    + * link up interrupt.  However, this can potentially take up to
    + * several milliseconds, so it is run via the watchdog routine, rather
    + * than in the interrupt handler itself. 
    + */
    +static void
    +mxge_media_probe(mxge_softc_t *sc)
    +{
    +	mxge_cmd_t cmd;
    +	char *cage_type;
    +
    +	struct mxge_media_type *mxge_media_types = NULL;
    +	int i, err, ms, mxge_media_type_entries;
    +	uint32_t byte;
    +
    +	sc->need_media_probe = 0;
    +
    +	if (sc->connector == MXGE_XFP) {
     		/* -R is XFP */
     		mxge_media_types = mxge_xfp_media_types;
     		mxge_media_type_entries = 
    @@ -2853,9 +2872,7 @@ mxge_media_probe(mxge_softc_t *sc)
     			sizeof (mxge_xfp_media_types[0]);
     		byte = MXGE_XFP_COMPLIANCE_BYTE;
     		cage_type = "XFP";
    -	}
    -
    -	if (*ptr == 'S' || *(ptr +1) == 'S') {
    +	} else 	if (sc->connector == MXGE_SFP) {
     		/* -S or -2S is SFP+ */
     		mxge_media_types = mxge_sfp_media_types;
     		mxge_media_type_entries = 
    @@ -2863,10 +2880,8 @@ mxge_media_probe(mxge_softc_t *sc)
     			sizeof (mxge_sfp_media_types[0]);
     		cage_type = "SFP+";
     		byte = 3;
    -	}
    -
    -	if (mxge_media_types == NULL) {
    -		device_printf(sc->dev, "Unknown media type: %c\n", *ptr);
    +	} else {
    +		/* nothing to do; media type cannot change */
     		return;
     	}
     
    @@ -2909,7 +2924,10 @@ mxge_media_probe(mxge_softc_t *sc)
     		if (mxge_verbose)
     			device_printf(sc->dev, "%s:%s\n", cage_type,
     				      mxge_media_types[0].name);
    -		mxge_set_media(sc, mxge_media_types[0].flag);
    +		if (sc->current_media != mxge_media_types[0].flag) {
    +			mxge_media_init(sc);
    +			mxge_media_set(sc, mxge_media_types[0].flag);
    +		}
     		return;
     	}
     	for (i = 1; i < mxge_media_type_entries; i++) {
    @@ -2919,12 +2937,16 @@ mxge_media_probe(mxge_softc_t *sc)
     					      cage_type,
     					      mxge_media_types[i].name);
     
    -			mxge_set_media(sc, mxge_media_types[i].flag);
    +			if (sc->current_media != mxge_media_types[i].flag) {
    +				mxge_media_init(sc);
    +				mxge_media_set(sc, mxge_media_types[i].flag);
    +			}
     			return;
     		}
     	}
    -	device_printf(sc->dev, "%s media 0x%x unknown\n", cage_type,
    -		      cmd.data0);
    +	if (mxge_verbose)
    +		device_printf(sc->dev, "%s media 0x%x unknown\n",
    +			      cage_type, cmd.data0);
     
     	return;
     }
    @@ -2988,10 +3010,12 @@ mxge_intr(void *arg)
     			sc->link_state = stats->link_up;
     			if (sc->link_state) {
     				if_link_state_change(sc->ifp, LINK_STATE_UP);
    +				 sc->ifp->if_baudrate = IF_Gbps(10UL);
     				if (mxge_verbose)
     					device_printf(sc->dev, "link up\n");
     			} else {
     				if_link_state_change(sc->ifp, LINK_STATE_DOWN);
    +				sc->ifp->if_baudrate = 0;
     				if (mxge_verbose)
     					device_printf(sc->dev, "link down\n");
     			}
    @@ -4026,9 +4050,9 @@ mxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
     	if (sc == NULL)
     		return;
     	ifmr->ifm_status = IFM_AVALID;
    +	ifmr->ifm_active = IFM_ETHER | IFM_FDX;
     	ifmr->ifm_status |= sc->link_state ? IFM_ACTIVE : 0;
    -	ifmr->ifm_active = IFM_AUTO | IFM_ETHER;
    -	ifmr->ifm_active |= sc->link_state ? IFM_FDX : 0;
    +	ifmr->ifm_active |= sc->current_media;
     }
     
     static int
    @@ -4135,6 +4159,9 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     		break;
     
     	case SIOCGIFMEDIA:
    +		mtx_lock(&sc->driver_mtx);
    +		mxge_media_probe(sc);
    +		mtx_unlock(&sc->driver_mtx);
     		err = ifmedia_ioctl(ifp, (struct ifreq *)data, 
     				    &sc->media, command);
                     break;
    @@ -4767,7 +4794,7 @@ mxge_attach(device_t dev)
     	/* Initialise the ifmedia structure */
     	ifmedia_init(&sc->media, 0, mxge_media_change, 
     		     mxge_media_status);
    -	mxge_set_media(sc, IFM_ETHER | IFM_AUTO);
    +	mxge_media_init(sc);
     	mxge_media_probe(sc);
     	sc->dying = 0;
     	ether_ifattach(ifp, sc->mac_addr);
    diff --git a/sys/dev/mxge/if_mxge_var.h b/sys/dev/mxge/if_mxge_var.h
    index 5c1627f71e5..c85a29bfb58 100644
    --- a/sys/dev/mxge/if_mxge_var.h
    +++ b/sys/dev/mxge/if_mxge_var.h
    @@ -268,6 +268,8 @@ struct mxge_softc {
     	int num_slices;
     	int rx_ring_size;
     	int dying;
    +	int connector;
    +	int current_media;
     	mxge_dma_t dmabench_dma;
     	struct callout co_hdl;
     	struct taskqueue *tq;
    @@ -293,6 +295,12 @@ struct mxge_softc {
     #define MXGE_MIN_THROTTLE	416
     #define MXGE_MAX_THROTTLE	4096
     
    +/* Types of connectors on NICs supported by this driver */
    +#define MXGE_CX4 0
    +#define MXGE_XFP 1
    +#define MXGE_SFP 2
    +#define MXGE_QRF 3
    +
     #define MXGE_HIGHPART_TO_U32(X) \
     (sizeof (X) == 8) ? ((uint32_t)((uint64_t)(X) >> 32)) : (0)
     #define MXGE_LOWPART_TO_U32(X) ((uint32_t)(X))
    
    From 344b802fea37411957f76d6cccdde56d3bef144a Mon Sep 17 00:00:00 2001
    From: Gavin Atkinson 
    Date: Tue, 27 Apr 2010 20:18:54 +0000
    Subject: [PATCH 2129/2592] Merge r203692 from head:
    
      Kernel modules for these drivers are installed on all platforms, so
      install the man pages on all platforms too.
    ---
     share/man/man4/Makefile                | 6 ++++++
     share/man/man4/{man4.i386 => }/alpm.4  | 2 +-
     share/man/man4/{man4.i386 => }/amdpm.4 | 2 +-
     share/man/man4/man4.i386/Makefile      | 6 ------
     share/man/man4/{man4.i386 => }/mcd.4   | 2 +-
     share/man/man4/{man4.i386 => }/pcf.4   | 2 +-
     share/man/man4/{man4.i386 => }/scd.4   | 2 +-
     share/man/man4/{man4.i386 => }/viapm.4 | 2 +-
     8 files changed, 12 insertions(+), 12 deletions(-)
     rename share/man/man4/{man4.i386 => }/alpm.4 (99%)
     rename share/man/man4/{man4.i386 => }/amdpm.4 (99%)
     rename share/man/man4/{man4.i386 => }/mcd.4 (99%)
     rename share/man/man4/{man4.i386 => }/pcf.4 (99%)
     rename share/man/man4/{man4.i386 => }/scd.4 (99%)
     rename share/man/man4/{man4.i386 => }/viapm.4 (99%)
    
    diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
    index de2d7c65d16..c927c940e4a 100644
    --- a/share/man/man4/Makefile
    +++ b/share/man/man4/Makefile
    @@ -29,8 +29,10 @@ MAN=	aac.4 \
     	aio.4 \
     	alc.4 \
     	ale.4 \
    +	alpm.4 \
     	altq.4 \
     	amd.4 \
    +	amdpm.4 \
     	${_amdsmb.4} \
     	${_amdtemp.4} \
     	amr.4 \
    @@ -198,6 +200,7 @@ MAN=	aac.4 \
     	mac_stub.4 \
     	mac_test.4 \
     	malo.4 \
    +	mcd.4 \
     	md.4 \
     	mem.4 \
     	meteor.4 \
    @@ -301,6 +304,7 @@ MAN=	aac.4 \
     	patm.4 \
     	pccard.4 \
     	pccbb.4 \
    +	pcf.4 \
     	pci.4 \
     	pcib.4 \
     	pcic.4 \
    @@ -333,6 +337,7 @@ MAN=	aac.4 \
     	sbp.4 \
     	sbp_targ.4 \
     	scc.4 \
    +	scd.4 \
     	sched_4bsd.4 \
     	sched_ule.4 \
     	screen.4 \
    @@ -452,6 +457,7 @@ MAN=	aac.4 \
     	uvscom.4 \
     	vga.4 \
     	vge.4 \
    +	viapm.4 \
     	vinum.4 \
     	vkbd.4 \
     	vlan.4 \
    diff --git a/share/man/man4/man4.i386/alpm.4 b/share/man/man4/alpm.4
    similarity index 99%
    rename from share/man/man4/man4.i386/alpm.4
    rename to share/man/man4/alpm.4
    index f288b72c42f..43ee4596178 100644
    --- a/share/man/man4/man4.i386/alpm.4
    +++ b/share/man/man4/alpm.4
    @@ -25,7 +25,7 @@
     .\" $FreeBSD$
     .\"
     .Dd February 13, 1999
    -.Dt ALPM 4 i386
    +.Dt ALPM 4
     .Os
     .Sh NAME
     .Nm alpm
    diff --git a/share/man/man4/man4.i386/amdpm.4 b/share/man/man4/amdpm.4
    similarity index 99%
    rename from share/man/man4/man4.i386/amdpm.4
    rename to share/man/man4/amdpm.4
    index f8937b314ae..f791a28ba28 100644
    --- a/share/man/man4/man4.i386/amdpm.4
    +++ b/share/man/man4/amdpm.4
    @@ -26,7 +26,7 @@
     .\" $FreeBSD$
     .\"
     .Dd December 31, 2005
    -.Dt AMDPM 4 i386
    +.Dt AMDPM 4
     .Os
     .Sh NAME
     .Nm amdpm
    diff --git a/share/man/man4/man4.i386/Makefile b/share/man/man4/man4.i386/Makefile
    index 803dfd88238..0134d578388 100644
    --- a/share/man/man4/man4.i386/Makefile
    +++ b/share/man/man4/man4.i386/Makefile
    @@ -1,8 +1,6 @@
     # $FreeBSD$
     
     MAN=	aic.4 \
    -	alpm.4 \
    -	amdpm.4 \
     	apm.4 \
     	ce.4 \
     	cp.4 \
    @@ -17,22 +15,18 @@ MAN=	aic.4 \
     	glxsb.4 \
     	ie.4 \
     	longrun.4 \
    -	mcd.4 \
     	mse.4 \
     	npx.4 \
     	pae.4 \
     	pbio.4 \
    -	pcf.4 \
     	perfmon.4 \
     	pnp.4 \
     	pnpbios.4 \
     	sbni.4 \
    -	scd.4 \
     	smapi.4 \
     	snc.4 \
     	streams.4 \
     	svr4.4 \
    -	viapm.4 \
     	vpd.4 \
     	vx.4 \
     	wl.4
    diff --git a/share/man/man4/man4.i386/mcd.4 b/share/man/man4/mcd.4
    similarity index 99%
    rename from share/man/man4/man4.i386/mcd.4
    rename to share/man/man4/mcd.4
    index a4a93ddb5d4..8efa7db6f84 100644
    --- a/share/man/man4/man4.i386/mcd.4
    +++ b/share/man/man4/mcd.4
    @@ -27,7 +27,7 @@
     .\" $FreeBSD$
     .\"
     .Dd December 8, 1994
    -.Dt MCD 4 i386
    +.Dt MCD 4
     .Os
     .Sh NAME
     .Nm mcd
    diff --git a/share/man/man4/man4.i386/pcf.4 b/share/man/man4/pcf.4
    similarity index 99%
    rename from share/man/man4/man4.i386/pcf.4
    rename to share/man/man4/pcf.4
    index f5e9088454c..cc8915fa122 100644
    --- a/share/man/man4/man4.i386/pcf.4
    +++ b/share/man/man4/pcf.4
    @@ -25,7 +25,7 @@
     .\" $FreeBSD$
     .\"
     .Dd August 6, 1998
    -.Dt PCF 4 i386
    +.Dt PCF 4
     .Os
     .Sh NAME
     .Nm pcf
    diff --git a/share/man/man4/man4.i386/scd.4 b/share/man/man4/scd.4
    similarity index 99%
    rename from share/man/man4/man4.i386/scd.4
    rename to share/man/man4/scd.4
    index daefa3c259d..dbbb18f3513 100644
    --- a/share/man/man4/man4.i386/scd.4
    +++ b/share/man/man4/scd.4
    @@ -27,7 +27,7 @@
     .\" $FreeBSD$
     .\"
     .Dd March 17, 2008
    -.Dt SCD 4 i386
    +.Dt SCD 4
     .Os
     .Sh NAME
     .Nm scd
    diff --git a/share/man/man4/man4.i386/viapm.4 b/share/man/man4/viapm.4
    similarity index 99%
    rename from share/man/man4/man4.i386/viapm.4
    rename to share/man/man4/viapm.4
    index 7457952950f..851c1fc7922 100644
    --- a/share/man/man4/man4.i386/viapm.4
    +++ b/share/man/man4/viapm.4
    @@ -25,7 +25,7 @@
     .\" $FreeBSD$
     .\"
     .Dd April 20, 2002
    -.Dt VIAPM 4 i386
    +.Dt VIAPM 4
     .Os
     .Sh NAME
     .Nm viapm
    
    From 2f2fdf54c0285431d7e5d3243b1a24d254a349b9 Mon Sep 17 00:00:00 2001
    From: Gavin Atkinson 
    Date: Tue, 27 Apr 2010 20:51:50 +0000
    Subject: [PATCH 2130/2592] Merge r204418 from head (original commit by
     antoine)
    
      Add files moved in r203976 and r207292 to ObsoleteFiles.inc
    
    Requested by:	Alex Kozlov 
    Merge OK'd by:	antoine
    ---
     ObsoleteFiles.inc | 10 ++++++++++
     1 file changed, 10 insertions(+)
    
    diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
    index 779b00eed48..d59f98482e1 100644
    --- a/ObsoleteFiles.inc
    +++ b/ObsoleteFiles.inc
    @@ -34,6 +34,16 @@ OLD_FILES+=usr/share/man/man1/gcpio.1.gz
     # 20100301: 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
    +# 20100208: man pages moved
    +.if ${TARGET_ARCH} == "i386"
    +OLD_FILES+=usr/share/man/man4/i386/alpm.4.gz
    +OLD_FILES+=usr/share/man/man4/i386/amdpm.4.gz
    +OLD_FILES+=usr/share/man/man4/i386/mcd.4.gz
    +OLD_FILES+=usr/share/man/man4/i386/padlock.4.gz
    +OLD_FILES+=usr/share/man/man4/i386/pcf.4.gz
    +OLD_FILES+=usr/share/man/man4/i386/scd.4.gz
    +OLD_FILES+=usr/share/man/man4/i386/viapm.4.gz
    +.endif
     # 20091229: remove no longer relevant examples
     OLD_FILES+=usr/share/examples/pppd/auth-down.sample
     OLD_FILES+=usr/share/examples/pppd/auth-up.sample
    
    From 0919a8fb9960da66f6559c509a73bc2ac7f6104a Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Wed, 28 Apr 2010 00:49:24 +0000
    Subject: [PATCH 2131/2592] MFC r206637:
    
    When an underlying ioctl(2) handler returns an error, our ioctl(2)
    interface considers that it hits a fatal error, and will not copyout
    the request structure back for _IOW and _IOWR ioctls, keeping them
    untouched.
    
    The previous implementation of the SIOCGIFDESCR ioctl intends to
    feed the buffer length back to userland.  However, if we return
    an error, the feedback would be defeated and ifconfig(8) would
    trap into an infinite loop.
    
    This commit changes SIOCGIFDESCR to set buffer field to NULL to
    indicate the previous ENAMETOOLONG case.
    
    Reported by:	bschmidt
    ---
     sbin/ifconfig/ifconfig.c  | 23 ++++++++++++-----------
     share/man/man4/netintro.4 |  9 ++++++---
     sys/net/if.c              |  7 +++----
     3 files changed, 21 insertions(+), 18 deletions(-)
    
    diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
    index e46dcdb873d..fd20d17ea73 100644
    --- a/sbin/ifconfig/ifconfig.c
    +++ b/sbin/ifconfig/ifconfig.c
    @@ -906,19 +906,20 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
     			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;
    -			} else if (errno == ENAMETOOLONG)
    -				descrlen = ifr.ifr_buffer.length;
    -			else
    -				break;
    -		} else {
    +				if (ifr.ifr_buffer.buffer == descr) {
    +					if (strlen(descr) > 0)
    +						printf("\tdescription: %s\n",
    +						    descr);
    +				} else if (ifr.ifr_buffer.length > descrlen) {
    +					descrlen = ifr.ifr_buffer.length;
    +					continue;
    +				}
    +			}
    +		} else
     			warn("unable to allocate memory for interface"
     			    "description");
    -			break;
    -		}
    -	};
    +		break;
    +	}
     
     	if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
     		if (ifr.ifr_curcap != 0) {
    diff --git a/share/man/man4/netintro.4 b/share/man/man4/netintro.4
    index 348a13e68fd..3e989401777 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 January 26, 2010
    +.Dd April 14, 2010
     .Dt NETINTRO 4
     .Os
     .Sh NAME
    @@ -292,8 +292,11 @@ field of
     struct passed in as parameter, and the length would include
     the terminating nul character.
     If there is not enough space to hold the interface length,
    -no copy would be done and an
    -error would be returned.
    +no copy would be done and the
    +.Va buffer
    +field of
    +.Va ifru_buffer
    +would be set to NULL.
     The kernel will store the buffer length in the
     .Va length
     field upon return, regardless whether the buffer itself is
    diff --git a/sys/net/if.c b/sys/net/if.c
    index 0773c2b6597..4f092522416 100644
    --- a/sys/net/if.c
    +++ b/sys/net/if.c
    @@ -2115,14 +2115,13 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
     	case SIOCGIFDESCR:
     		error = 0;
     		sx_slock(&ifdescr_sx);
    -		if (ifp->if_description == NULL) {
    -			ifr->ifr_buffer.length = 0;
    +		if (ifp->if_description == NULL)
     			error = ENOMSG;
    -		} else {
    +		else {
     			/* space for terminating nul */
     			descrlen = strlen(ifp->if_description) + 1;
     			if (ifr->ifr_buffer.length < descrlen)
    -				error = ENAMETOOLONG;
    +				ifr->ifr_buffer.buffer = NULL;
     			else
     				error = copyout(ifp->if_description,
     				    ifr->ifr_buffer.buffer, descrlen);
    
    From 0c740f704fbcf4bac23cfddad61c200ba0f5c183 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 28 Apr 2010 09:59:28 +0000
    Subject: [PATCH 2132/2592] MFC r207007: Extract the code to copy-out struct
     rusage32 from struct rusage into the new function.
    
    ---
     sys/compat/freebsd32/freebsd32_misc.c | 56 ++++++++++++---------------
     sys/compat/freebsd32/freebsd32_util.h |  5 ++-
     2 files changed, 28 insertions(+), 33 deletions(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
    index 1284e386cdd..41413f6706f 100644
    --- a/sys/compat/freebsd32/freebsd32_misc.c
    +++ b/sys/compat/freebsd32/freebsd32_misc.c
    @@ -129,6 +129,28 @@ static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
     #define RETVAL_LO 0	
     #endif
     
    +void
    +freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32)
    +{
    +
    +	TV_CP(*s, *s32, ru_utime);
    +	TV_CP(*s, *s32, ru_stime);
    +	CP(*s, *s32, ru_maxrss);
    +	CP(*s, *s32, ru_ixrss);
    +	CP(*s, *s32, ru_idrss);
    +	CP(*s, *s32, ru_isrss);
    +	CP(*s, *s32, ru_minflt);
    +	CP(*s, *s32, ru_majflt);
    +	CP(*s, *s32, ru_nswap);
    +	CP(*s, *s32, ru_inblock);
    +	CP(*s, *s32, ru_oublock);
    +	CP(*s, *s32, ru_msgsnd);
    +	CP(*s, *s32, ru_msgrcv);
    +	CP(*s, *s32, ru_nsignals);
    +	CP(*s, *s32, ru_nvcsw);
    +	CP(*s, *s32, ru_nivcsw);
    +}
    +
     int
     freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
     {
    @@ -146,22 +168,7 @@ freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
     	if (uap->status != NULL)
     		error = copyout(&status, uap->status, sizeof(status));
     	if (uap->rusage != NULL && error == 0) {
    -		TV_CP(ru, ru32, ru_utime);
    -		TV_CP(ru, ru32, ru_stime);
    -		CP(ru, ru32, ru_maxrss);
    -		CP(ru, ru32, ru_ixrss);
    -		CP(ru, ru32, ru_idrss);
    -		CP(ru, ru32, ru_isrss);
    -		CP(ru, ru32, ru_minflt);
    -		CP(ru, ru32, ru_majflt);
    -		CP(ru, ru32, ru_nswap);
    -		CP(ru, ru32, ru_inblock);
    -		CP(ru, ru32, ru_oublock);
    -		CP(ru, ru32, ru_msgsnd);
    -		CP(ru, ru32, ru_msgrcv);
    -		CP(ru, ru32, ru_nsignals);
    -		CP(ru, ru32, ru_nvcsw);
    -		CP(ru, ru32, ru_nivcsw);
    +		freebsd32_rusage_out(&ru, &ru32);
     		error = copyout(&ru32, uap->rusage, sizeof(ru32));
     	}
     	return (error);
    @@ -755,22 +762,7 @@ freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
     	if (error)
     		return (error);
     	if (uap->rusage != NULL) {
    -		TV_CP(s, s32, ru_utime);
    -		TV_CP(s, s32, ru_stime);
    -		CP(s, s32, ru_maxrss);
    -		CP(s, s32, ru_ixrss);
    -		CP(s, s32, ru_idrss);
    -		CP(s, s32, ru_isrss);
    -		CP(s, s32, ru_minflt);
    -		CP(s, s32, ru_majflt);
    -		CP(s, s32, ru_nswap);
    -		CP(s, s32, ru_inblock);
    -		CP(s, s32, ru_oublock);
    -		CP(s, s32, ru_msgsnd);
    -		CP(s, s32, ru_msgrcv);
    -		CP(s, s32, ru_nsignals);
    -		CP(s, s32, ru_nvcsw);
    -		CP(s, s32, ru_nivcsw);
    +		freebsd32_rusage_out(&s, &s32);
     		error = copyout(&s32, uap->rusage, sizeof(s32));
     	}
     	return (error);
    diff --git a/sys/compat/freebsd32/freebsd32_util.h b/sys/compat/freebsd32/freebsd32_util.h
    index f5ccbf16e04..3ac676d9902 100644
    --- a/sys/compat/freebsd32/freebsd32_util.h
    +++ b/sys/compat/freebsd32/freebsd32_util.h
    @@ -94,9 +94,12 @@ int    syscall32_module_handler(struct module *mod, int what, void *arg);
     int    syscall32_helper_register(struct syscall_helper_data *sd);
     int    syscall32_helper_unregister(struct syscall_helper_data *sd);
     
    -register_t *freebsd32_copyout_strings(struct image_params *imgp);
     struct iovec32;
    +struct rusage32;
    +register_t *freebsd32_copyout_strings(struct image_params *imgp);
     int	freebsd32_copyiniov(struct iovec32 *iovp, u_int iovcnt,
     	    struct iovec **iov, int error);
    +void	freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32);
    +
     
     #endif /* !_COMPAT_FREEBSD32_FREEBSD32_UTIL_H_ */
    
    From 517c07c8ccb3591a10ba867ef7915dc918425639 Mon Sep 17 00:00:00 2001
    From: Konstantin Belousov 
    Date: Wed, 28 Apr 2010 10:03:54 +0000
    Subject: [PATCH 2133/2592] MFC r207008: Provide compat32 shims for kinfo_proc
     sysctl.
    
    MFC r207016:
    Fix typo.
    ---
     sys/compat/freebsd32/freebsd32.h |  82 +++++++++++++++++++
     sys/kern/kern_proc.c             | 134 ++++++++++++++++++++++++++++++-
     2 files changed, 212 insertions(+), 4 deletions(-)
    
    diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
    index b68f8fbbc03..ef83bc423a0 100644
    --- a/sys/compat/freebsd32/freebsd32.h
    +++ b/sys/compat/freebsd32/freebsd32.h
    @@ -31,6 +31,7 @@
     
     #include 
     #include 
    +#include 
     
     #define PTRIN(v)	(void *)(uintptr_t) (v)
     #define PTROUT(v)	(u_int32_t)(uintptr_t) (v)
    @@ -229,4 +230,85 @@ struct mq_attr32 {
     	int	__reserved[4];
     };
     
    +struct kinfo_proc32 {
    +	int	ki_structsize;
    +	int	ki_layout;
    +	uint32_t ki_args;
    +	uint32_t ki_paddr;
    +	uint32_t ki_addr;
    +	uint32_t ki_tracep;
    +	uint32_t ki_textvp;
    +	uint32_t ki_fd;
    +	uint32_t ki_vmspace;
    +	uint32_t ki_wchan;
    +	pid_t	ki_pid;
    +	pid_t	ki_ppid;
    +	pid_t	ki_pgid;
    +	pid_t	ki_tpgid;
    +	pid_t	ki_sid;
    +	pid_t	ki_tsid;
    +	short	ki_jobc;
    +	short	ki_spare_short1;
    +	dev_t	ki_tdev;
    +	sigset_t ki_siglist;
    +	sigset_t ki_sigmask;
    +	sigset_t ki_sigignore;
    +	sigset_t ki_sigcatch;
    +	uid_t	ki_uid;
    +	uid_t	ki_ruid;
    +	uid_t	ki_svuid;
    +	gid_t	ki_rgid;
    +	gid_t	ki_svgid;
    +	short	ki_ngroups;
    +	short	ki_spare_short2;
    +	gid_t 	ki_groups[KI_NGROUPS];
    +	uint32_t ki_size;
    +	int32_t ki_rssize;
    +	int32_t ki_swrss;
    +	int32_t ki_tsize;
    +	int32_t ki_dsize;
    +	int32_t ki_ssize;
    +	u_short	ki_xstat;
    +	u_short	ki_acflag;
    +	fixpt_t	ki_pctcpu;
    +	u_int	ki_estcpu;
    +	u_int	ki_slptime;
    +	u_int	ki_swtime;
    +	int	ki_spareint1;
    +	u_int64_t ki_runtime;
    +	struct	timeval32 ki_start;
    +	struct	timeval32 ki_childtime;
    +	int	ki_flag;
    +	int	ki_kiflag;
    +	int	ki_traceflag;
    +	char	ki_stat;
    +	signed char ki_nice;
    +	char	ki_lock;
    +	char	ki_rqindex;
    +	u_char	ki_oncpu;
    +	u_char	ki_lastcpu;
    +	char	ki_ocomm[OCOMMLEN+1];
    +	char	ki_wmesg[WMESGLEN+1];
    +	char	ki_login[LOGNAMELEN+1];
    +	char	ki_lockname[LOCKNAMELEN+1];
    +	char	ki_comm[COMMLEN+1];
    +	char	ki_emul[KI_EMULNAMELEN+1];
    +	char	ki_sparestrings[68];
    +	int	ki_spareints[KI_NSPARE_INT];
    +	u_int	ki_cr_flags;
    +	int	ki_jid;
    +	int	ki_numthreads;
    +	lwpid_t	ki_tid;
    +	struct	priority ki_pri;
    +	struct	rusage32 ki_rusage;
    +	struct	rusage32 ki_rusage_ch;
    +	uint32_t ki_pcb;
    +	uint32_t ki_kstack;
    +	uint32_t ki_udata;
    +	uint32_t ki_spareptrs[KI_NSPARE_PTR];	/* spare room for growth */
    +	int	ki_sparelongs[KI_NSPARE_LONG];
    +	int	ki_sflag;
    +	int	ki_tdflags;
    +};
    +
     #endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */
    diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
    index 166baa086fe..24d7ea399ca 100644
    --- a/sys/kern/kern_proc.c
    +++ b/sys/kern/kern_proc.c
    @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -79,6 +80,11 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    +#ifdef COMPAT_FREEBSD32
    +#include 
    +#include 
    +#endif
    +
     SDT_PROVIDER_DEFINE(proc);
     SDT_PROBE_DEFINE(proc, kernel, ctor, entry);
     SDT_PROBE_ARGTYPE(proc, kernel, ctor, entry, 0, "struct proc *");
    @@ -968,6 +974,128 @@ zpfind(pid_t pid)
     #define KERN_PROC_ZOMBMASK	0x3
     #define KERN_PROC_NOTHREADS	0x4
     
    +#ifdef COMPAT_FREEBSD32
    +
    +/*
    + * This function is typically used to copy out the kernel address, so
    + * it can be replaced by assignment of zero.
    + */
    +static inline uint32_t
    +ptr32_trim(void *ptr)
    +{
    +	uintptr_t uptr;
    +
    +	uptr = (uintptr_t)ptr;
    +	return ((uptr > UINT_MAX) ? 0 : uptr);
    +}
    +
    +#define PTRTRIM_CP(src,dst,fld) \
    +	do { (dst).fld = ptr32_trim((src).fld); } while (0)
    +
    +static void
    +freebsd32_kinfo_proc_out(const struct kinfo_proc *ki, struct kinfo_proc32 *ki32)
    +{
    +	int i;
    +
    +	bzero(ki32, sizeof(struct kinfo_proc32));
    +	ki32->ki_structsize = sizeof(struct kinfo_proc32);
    +	CP(*ki, *ki32, ki_layout);
    +	PTRTRIM_CP(*ki, *ki32, ki_args);
    +	PTRTRIM_CP(*ki, *ki32, ki_paddr);
    +	PTRTRIM_CP(*ki, *ki32, ki_addr);
    +	PTRTRIM_CP(*ki, *ki32, ki_tracep);
    +	PTRTRIM_CP(*ki, *ki32, ki_textvp);
    +	PTRTRIM_CP(*ki, *ki32, ki_fd);
    +	PTRTRIM_CP(*ki, *ki32, ki_vmspace);
    +	PTRTRIM_CP(*ki, *ki32, ki_wchan);
    +	CP(*ki, *ki32, ki_pid);
    +	CP(*ki, *ki32, ki_ppid);
    +	CP(*ki, *ki32, ki_pgid);
    +	CP(*ki, *ki32, ki_tpgid);
    +	CP(*ki, *ki32, ki_sid);
    +	CP(*ki, *ki32, ki_tsid);
    +	CP(*ki, *ki32, ki_jobc);
    +	CP(*ki, *ki32, ki_tdev);
    +	CP(*ki, *ki32, ki_siglist);
    +	CP(*ki, *ki32, ki_sigmask);
    +	CP(*ki, *ki32, ki_sigignore);
    +	CP(*ki, *ki32, ki_sigcatch);
    +	CP(*ki, *ki32, ki_uid);
    +	CP(*ki, *ki32, ki_ruid);
    +	CP(*ki, *ki32, ki_svuid);
    +	CP(*ki, *ki32, ki_rgid);
    +	CP(*ki, *ki32, ki_svgid);
    +	CP(*ki, *ki32, ki_ngroups);
    +	for (i = 0; i < KI_NGROUPS; i++)
    +		CP(*ki, *ki32, ki_groups[i]);
    +	CP(*ki, *ki32, ki_size);
    +	CP(*ki, *ki32, ki_rssize);
    +	CP(*ki, *ki32, ki_swrss);
    +	CP(*ki, *ki32, ki_tsize);
    +	CP(*ki, *ki32, ki_dsize);
    +	CP(*ki, *ki32, ki_ssize);
    +	CP(*ki, *ki32, ki_xstat);
    +	CP(*ki, *ki32, ki_acflag);
    +	CP(*ki, *ki32, ki_pctcpu);
    +	CP(*ki, *ki32, ki_estcpu);
    +	CP(*ki, *ki32, ki_slptime);
    +	CP(*ki, *ki32, ki_swtime);
    +	CP(*ki, *ki32, ki_runtime);
    +	TV_CP(*ki, *ki32, ki_start);
    +	TV_CP(*ki, *ki32, ki_childtime);
    +	CP(*ki, *ki32, ki_flag);
    +	CP(*ki, *ki32, ki_kiflag);
    +	CP(*ki, *ki32, ki_traceflag);
    +	CP(*ki, *ki32, ki_stat);
    +	CP(*ki, *ki32, ki_nice);
    +	CP(*ki, *ki32, ki_lock);
    +	CP(*ki, *ki32, ki_rqindex);
    +	CP(*ki, *ki32, ki_oncpu);
    +	CP(*ki, *ki32, ki_lastcpu);
    +	bcopy(ki->ki_ocomm, ki32->ki_ocomm, OCOMMLEN + 1);
    +	bcopy(ki->ki_wmesg, ki32->ki_wmesg, WMESGLEN + 1);
    +	bcopy(ki->ki_login, ki32->ki_login, LOGNAMELEN + 1);
    +	bcopy(ki->ki_lockname, ki32->ki_lockname, LOCKNAMELEN + 1);
    +	bcopy(ki->ki_comm, ki32->ki_comm, COMMLEN + 1);
    +	bcopy(ki->ki_emul, ki32->ki_emul, KI_EMULNAMELEN + 1);
    +	CP(*ki, *ki32, ki_cr_flags);
    +	CP(*ki, *ki32, ki_jid);
    +	CP(*ki, *ki32, ki_numthreads);
    +	CP(*ki, *ki32, ki_tid);
    +	CP(*ki, *ki32, ki_pri);
    +	freebsd32_rusage_out(&ki->ki_rusage, &ki32->ki_rusage);
    +	freebsd32_rusage_out(&ki->ki_rusage_ch, &ki32->ki_rusage_ch);
    +	PTRTRIM_CP(*ki, *ki32, ki_pcb);
    +	PTRTRIM_CP(*ki, *ki32, ki_kstack);
    +	PTRTRIM_CP(*ki, *ki32, ki_udata);
    +	CP(*ki, *ki32, ki_sflag);
    +	CP(*ki, *ki32, ki_tdflags);
    +}
    +
    +static int
    +sysctl_out_proc_copyout(struct kinfo_proc *ki, struct sysctl_req *req)
    +{
    +	struct kinfo_proc32 ki32;
    +	int error;
    +
    +	if (req->flags & SCTL_MASK32) {
    +		freebsd32_kinfo_proc_out(ki, &ki32);
    +		error = SYSCTL_OUT(req, (caddr_t)&ki32,
    +		    sizeof(struct kinfo_proc32));
    +	} else
    +		error = SYSCTL_OUT(req, (caddr_t)ki,
    +		    sizeof(struct kinfo_proc));
    +	return (error);
    +}
    +#else
    +static int
    +sysctl_out_proc_copyout(struct kinfo_proc *ki, struct sysctl_req *req)
    +{
    +
    +	return (SYSCTL_OUT(req, (caddr_t)ki, sizeof(struct kinfo_proc)));
    +}
    +#endif
    +
     /*
      * Must be called with the process locked and will return with it unlocked.
      */
    @@ -985,13 +1113,11 @@ sysctl_out_proc(struct proc *p, struct sysctl_req *req, int flags)
     
     	fill_kinfo_proc(p, &kinfo_proc);
     	if (flags & KERN_PROC_NOTHREADS)
    -		error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc,
    -		    sizeof(kinfo_proc));
    +		error = sysctl_out_proc_copyout(&kinfo_proc, req);
     	else {
     		FOREACH_THREAD_IN_PROC(p, td) {
     			fill_kinfo_thread(td, &kinfo_proc, 1);
    -			error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc,
    -			    sizeof(kinfo_proc));
    +			error = sysctl_out_proc_copyout(&kinfo_proc, req);
     			if (error)
     				break;
     		}
    
    From 5b478dbb2fdf0642e66141bc7f04251ef268afde Mon Sep 17 00:00:00 2001
    From: Rui Paulo 
    Date: Wed, 28 Apr 2010 15:15:06 +0000
    Subject: [PATCH 2134/2592] MFC r206617:   Make this code a little more
     portable by wrapping the mtx calls   into macros.
    
    ---
     sys/net80211/ieee80211_freebsd.h  | 10 +++++++
     sys/net80211/ieee80211_scan_sta.c | 46 +++++++++++++++----------------
     2 files changed, 33 insertions(+), 23 deletions(-)
    
    diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
    index 6a8875a6c75..23c1fcd246a 100644
    --- a/sys/net80211/ieee80211_freebsd.h
    +++ b/sys/net80211/ieee80211_freebsd.h
    @@ -147,6 +147,16 @@ typedef struct mtx acl_lock_t;
     #define	ACL_LOCK_ASSERT(_as) \
     	mtx_assert((&(_as)->as_lock), MA_OWNED)
     
    +/*
    + * Scan table definitions.
    + */
    +typedef struct mtx ieee80211_scan_table_lock_t;
    +#define	IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \
    +	mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF)
    +#define	IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st)	mtx_destroy(&(_st)->st_lock)
    +#define	IEEE80211_SCAN_TABLE_LOCK(_st)		mtx_lock(&(_st)->st_lock)
    +#define	IEEE80211_SCAN_TABLE_UNLOCK(_st)	mtx_unlock(&(_st)->st_lock)
    +
     /*
      * Node reference counting definitions.
      *
    diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c
    index e697ad4a1a2..a4808e29671 100644
    --- a/sys/net80211/ieee80211_scan_sta.c
    +++ b/sys/net80211/ieee80211_scan_sta.c
    @@ -97,7 +97,7 @@ struct sta_entry {
     CTASSERT(MAX_IEEE_CHAN >= 256);
     
     struct sta_table {
    -	struct mtx	st_lock;		/* on scan table */
    +	ieee80211_scan_table_lock_t st_lock;	/* on scan table */
     	TAILQ_HEAD(, sta_entry) st_entry;	/* all entries */
     	LIST_HEAD(, sta_entry) st_hash[STA_HASHSIZE];
     	struct mtx	st_scanlock;		/* on st_scaniter */
    @@ -161,7 +161,7 @@ sta_attach(struct ieee80211_scan_state *ss)
     		M_80211_SCAN, M_NOWAIT | M_ZERO);
     	if (st == NULL)
     		return 0;
    -	mtx_init(&st->st_lock, "scantable", "802.11 scan table", MTX_DEF);
    +	IEEE80211_SCAN_TABLE_LOCK_INIT(st, "scantable");
     	mtx_init(&st->st_scanlock, "scangen", "802.11 scangen", MTX_DEF);
     	TAILQ_INIT(&st->st_entry);
     	ss->ss_priv = st;
    @@ -179,7 +179,7 @@ sta_detach(struct ieee80211_scan_state *ss)
     
     	if (st != NULL) {
     		sta_flush_table(st);
    -		mtx_destroy(&st->st_lock);
    +		IEEE80211_SCAN_TABLE_LOCK_DESTROY(st);
     		mtx_destroy(&st->st_scanlock);
     		free(st, M_80211_SCAN);
     		KASSERT(nrefs > 0, ("imbalanced attach/detach"));
    @@ -196,9 +196,9 @@ sta_flush(struct ieee80211_scan_state *ss)
     {
     	struct sta_table *st = ss->ss_priv;
     
    -	mtx_lock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_LOCK(st);
     	sta_flush_table(st);
    -	mtx_unlock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_UNLOCK(st);
     	ss->ss_last = 0;
     	return 0;
     }
    @@ -244,14 +244,14 @@ sta_add(struct ieee80211_scan_state *ss,
     
     	hash = STA_HASH(macaddr);
     
    -	mtx_lock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_LOCK(st);
     	LIST_FOREACH(se, &st->st_hash[hash], se_hash)
     		if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
     			goto found;
     	se = (struct sta_entry *) malloc(sizeof(struct sta_entry),
     		M_80211_SCAN, M_NOWAIT | M_ZERO);
     	if (se == NULL) {
    -		mtx_unlock(&st->st_lock);
    +		IEEE80211_SCAN_TABLE_UNLOCK(st);
     		return 0;
     	}
     	se->se_scangen = st->st_scaniter-1;
    @@ -370,7 +370,7 @@ found:
     	if (rssi > st->st_maxrssi[sp->bchan])
     		st->st_maxrssi[sp->bchan] = rssi;
     
    -	mtx_unlock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_UNLOCK(st);
     
     	/*
     	 * If looking for a quick choice and nothing's
    @@ -1132,7 +1132,7 @@ sta_update_notseen(struct sta_table *st)
     {
     	struct sta_entry *se;
     
    -	mtx_lock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_LOCK(st);
     	TAILQ_FOREACH(se, &st->st_entry, se_list) {
     		/*
     		 * If seen the reset and don't bump the count;
    @@ -1146,7 +1146,7 @@ sta_update_notseen(struct sta_table *st)
     		else
     			se->se_notseen++;
     	}
    -	mtx_unlock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_UNLOCK(st);
     }
     
     static void
    @@ -1154,11 +1154,11 @@ sta_dec_fails(struct sta_table *st)
     {
     	struct sta_entry *se;
     
    -	mtx_lock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_LOCK(st);
     	TAILQ_FOREACH(se, &st->st_entry, se_list)
     		if (se->se_fails)
     			se->se_fails--;
    -	mtx_unlock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_UNLOCK(st);
     }
     
     static struct sta_entry *
    @@ -1169,7 +1169,7 @@ select_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, int debug)
     
     	IEEE80211_DPRINTF(vap, debug, " %s\n",
     	    "macaddr          bssid         chan  rssi  rate flag  wep  essid");
    -	mtx_lock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_LOCK(st);
     	TAILQ_FOREACH(se, &st->st_entry, se_list) {
     		ieee80211_ies_expand(&se->base.se_ies);
     		if (match_bss(vap, ss, se, debug) == 0) {
    @@ -1179,7 +1179,7 @@ select_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, int debug)
     				selbs = se;
     		}
     	}
    -	mtx_unlock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_UNLOCK(st);
     
     	return selbs;
     }
    @@ -1258,11 +1258,11 @@ sta_lookup(struct sta_table *st, const uint8_t macaddr[IEEE80211_ADDR_LEN])
     	struct sta_entry *se;
     	int hash = STA_HASH(macaddr);
     
    -	mtx_lock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_LOCK(st);
     	LIST_FOREACH(se, &st->st_hash[hash], se_hash)
     		if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
     			break;
    -	mtx_unlock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_UNLOCK(st);
     
     	return se;		/* NB: unlocked */
     }
    @@ -1382,18 +1382,18 @@ sta_iterate(struct ieee80211_scan_state *ss,
     	mtx_lock(&st->st_scanlock);
     	gen = st->st_scaniter++;
     restart:
    -	mtx_lock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_LOCK(st);
     	TAILQ_FOREACH(se, &st->st_entry, se_list) {
     		if (se->se_scangen != gen) {
     			se->se_scangen = gen;
     			/* update public state */
     			se->base.se_age = ticks - se->se_lastupdate;
    -			mtx_unlock(&st->st_lock);
    +			IEEE80211_SCAN_TABLE_UNLOCK(st);
     			(*f)(arg, &se->base);
     			goto restart;
     		}
     	}
    -	mtx_unlock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_UNLOCK(st);
     
     	mtx_unlock(&st->st_scanlock);
     }
    @@ -1510,7 +1510,7 @@ adhoc_pick_channel(struct ieee80211_scan_state *ss, int flags)
     	bestchan = NULL;
     	bestrssi = -1;
     
    -	mtx_lock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_LOCK(st);
     	for (i = 0; i < ss->ss_last; i++) {
     		c = ss->ss_chans[i];
     		/* never consider a channel with radar */
    @@ -1532,7 +1532,7 @@ adhoc_pick_channel(struct ieee80211_scan_state *ss, int flags)
     		if (bestchan == NULL || maxrssi < bestrssi)
     			bestchan = c;
     	}
    -	mtx_unlock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_UNLOCK(st);
     
     	return bestchan;
     }
    @@ -1638,7 +1638,7 @@ adhoc_age(struct ieee80211_scan_state *ss)
     	struct sta_table *st = ss->ss_priv;
     	struct sta_entry *se, *next;
     
    -	mtx_lock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_LOCK(st);
     	TAILQ_FOREACH_SAFE(se, &st->st_entry, se_list, next) {
     		if (se->se_notseen > STA_PURGE_SCANS) {
     			TAILQ_REMOVE(&st->st_entry, se, se_list);
    @@ -1647,7 +1647,7 @@ adhoc_age(struct ieee80211_scan_state *ss)
     			free(se, M_80211_SCAN);
     		}
     	}
    -	mtx_unlock(&st->st_lock);
    +	IEEE80211_SCAN_TABLE_UNLOCK(st);
     }
     
     static const struct ieee80211_scanner adhoc_default = {
    
    From 517ac329edda420d16d0b654dd5c576424f37f44 Mon Sep 17 00:00:00 2001
    From: Jack F Vogel 
    Date: Wed, 28 Apr 2010 18:28:08 +0000
    Subject: [PATCH 2135/2592] Only enable MAGIC WOL by default, MCAST causes
     systems to just wakeup immediately in many environments.
    
    ---
     sys/dev/e1000/if_em.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
    index 1db90121ddb..fcebc02930a 100644
    --- a/sys/dev/e1000/if_em.c
    +++ b/sys/dev/e1000/if_em.c
    @@ -2707,10 +2707,10 @@ em_setup_interface(device_t dev, struct adapter *adapter)
     	ifp->if_capabilities |= IFCAP_POLLING;
     #endif
     
    -	/* Enable All WOL methods by default */
    +	/* Enable only WOL MAGIC by default */
     	if (adapter->wol) {
     		ifp->if_capabilities |= IFCAP_WOL;
    -		ifp->if_capenable |= IFCAP_WOL;
    +		ifp->if_capenable |= IFCAP_WOL_MAGIC;
     	}
     		
     	/*
    
    From f347c17fa99365c6ceaf4dae21858e85b6322b5c Mon Sep 17 00:00:00 2001
    From: Xin LI 
    Date: Thu, 29 Apr 2010 00:28:34 +0000
    Subject: [PATCH 2136/2592] MFC r205938:
    
    Sync with OpenBSD:
     - avoid coredump when there's only one token on a line;
     - Use calloc();
     - Remove a line inherited from example mdoc.
    
    Obtained from:  OpenBSD
    ---
     usr.sbin/mailwrapper/mailwrapper.8 | 3 +--
     usr.sbin/mailwrapper/mailwrapper.c | 8 ++++----
     2 files changed, 5 insertions(+), 6 deletions(-)
    
    diff --git a/usr.sbin/mailwrapper/mailwrapper.8 b/usr.sbin/mailwrapper/mailwrapper.8
    index 587826bcc14..6e498f643f1 100644
    --- a/usr.sbin/mailwrapper/mailwrapper.8
    +++ b/usr.sbin/mailwrapper/mailwrapper.8
    @@ -1,5 +1,5 @@
    +.\"	$OpenBSD: mailwrapper.8,v 1.10 2009/02/07 16:58:23 martynas Exp $
     .\"	$NetBSD: mailwrapper.8,v 1.11 2002/02/08 01:38:50 ross Exp $
    -.\"	$OpenBSD: mailwrapper.8,v 1.8 2003/06/12 12:59:51 jmc Exp $
     .\" $FreeBSD$
     .\"
     .\" Copyright (c) 1998
    @@ -31,7 +31,6 @@
     .\" (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 following requests are required for all man pages.
     .Dd August 7, 2006
     .Dt MAILWRAPPER 8
     .Os
    diff --git a/usr.sbin/mailwrapper/mailwrapper.c b/usr.sbin/mailwrapper/mailwrapper.c
    index d696d25f3ac..1b52a642cf3 100644
    --- a/usr.sbin/mailwrapper/mailwrapper.c
    +++ b/usr.sbin/mailwrapper/mailwrapper.c
    @@ -1,4 +1,4 @@
    -/*	$OpenBSD: mailwrapper.c,v 1.16 2004/07/06 03:38:14 millert Exp $	*/
    +/*	$OpenBSD: mailwrapper.c,v 1.18 2007/11/06 14:39:19 otto Exp $	*/
     /*	$NetBSD: mailwrapper.c,v 1.9 2003/03/09 08:10:43 mjl Exp $	*/
     
     /*
    @@ -61,8 +61,8 @@ initarg(struct arglist *al)
     {
     	al->argc = 0;
     	al->maxc = 10;
    -	if ((al->argv = malloc(al->maxc * sizeof(char *))) == NULL)
    -		err(EX_TEMPFAIL, "malloc");
    +	if ((al->argv = calloc(al->maxc, sizeof(char *))) == NULL)
    +		err(EX_TEMPFAIL, "calloc");
     }
     
     static void
    @@ -126,7 +126,7 @@ main(int argc, char *argv[], char *envp[])
     			continue;
     		}
     
    -		if ((from = strsep(&cp, WS)) == NULL)
    +		if ((from = strsep(&cp, WS)) == NULL || cp == NULL)
     			goto parse_error;
     
     		cp += strspn(cp, WS);
    
    From 140095c1b8fe58bd4239a46c31b25a396fa4f291 Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Thu, 29 Apr 2010 19:06:43 +0000
    Subject: [PATCH 2137/2592] This is an MFC of 205847
    
    Change how multipath labels are created and managed. This makes it easier
    to support various storage boxes which really aren't active-active.
    
    We only write the label on the *first* provider. For all other providers
    we just "add" the disk. This also allows for an "add" verb.
    
    A usage implication is that you should specificy the currently active
    storage path as the first provider.
    
    Note that this does not add RDAC-like functionality, but better allows for
    autovolumefailover configurations (additional checkins elsewhere will support
    this).
    ---
     sbin/geom/class/multipath/geom_multipath.c | 98 ++++++++++++----------
     1 file changed, 52 insertions(+), 46 deletions(-)
    
    diff --git a/sbin/geom/class/multipath/geom_multipath.c b/sbin/geom/class/multipath/geom_multipath.c
    index ab91e2d884c..288492c90fa 100644
    --- a/sbin/geom/class/multipath/geom_multipath.c
    +++ b/sbin/geom/class/multipath/geom_multipath.c
    @@ -48,12 +48,17 @@ uint32_t version = G_MULTIPATH_VERSION;
     static void mp_main(struct gctl_req *, unsigned int);
     static void mp_label(struct gctl_req *);
     static void mp_clear(struct gctl_req *);
    +static void mp_add(struct gctl_req *);
     
     struct g_command class_commands[] = {
     	{
     		"label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, mp_main, G_NULL_OPTS,
     		NULL, "[-v] name prov ..."
     	},
    +	{
    +		"add", G_FLAG_VERBOSE | G_FLAG_LOADKLD, mp_main, G_NULL_OPTS,
    +		NULL, "[-v] name prov ..."
    +	},
     	{
     		"destroy", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
     		NULL, "[-v] prov ..."
    @@ -85,6 +90,8 @@ mp_main(struct gctl_req *req, unsigned int flags __unused)
     	}
     	if (strcmp(name, "label") == 0) {
     		mp_label(req);
    +	} else if (strcmp(name, "add") == 0) {
    +		mp_add(req);
     	} else if (strcmp(name, "clear") == 0) {
     		mp_clear(req);
     	} else {
    @@ -101,7 +108,7 @@ mp_label(struct gctl_req *req)
     	char *ptr;
     	uuid_t uuid;
     	uint32_t secsize = 0, ssize, status;
    -	const char *name;
    +	const char *name, *mpname;
     	int error, i, nargs;
     
     	nargs = gctl_get_int(req, "nargs");
    @@ -156,8 +163,8 @@ mp_label(struct gctl_req *req)
     	 */
     	strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic));
     	md.md_version = G_MULTIPATH_VERSION;
    -	name = gctl_get_ascii(req, "arg0");
    -	strlcpy(md.md_name, name, sizeof(md.md_name));
    +	mpname = gctl_get_ascii(req, "arg0");
    +	strlcpy(md.md_name, mpname, sizeof(md.md_name));
     	md.md_size = disksiz;
     	md.md_sectorsize = secsize;
     	uuid_create(&uuid, &status);
    @@ -174,46 +181,44 @@ mp_label(struct gctl_req *req)
     	free(ptr);
     
     	/*
    -	 * Clear last sector first for each provider to spoil anything extant
    +	 * Clear metadata on initial provider first.
     	 */
    -	for (i = 1; i < nargs; i++) {
    -		name = gctl_get_ascii(req, "arg%d", i);
    -		error = g_metadata_clear(name, NULL);
    -		if (error != 0) {
    -			gctl_error(req, "cannot clear metadata on %s: %s.",
    -			    name, strerror(error));
    -			return;
    -		}
    +	name = gctl_get_ascii(req, "arg1");
    +	error = g_metadata_clear(name, NULL);
    +	if (error != 0) {
    +		gctl_error(req, "cannot clear metadata on %s: %s.", name, strerror(error));
    +		return;
     	}
     
    +	/*
    +	 * encode the metadata
    +	 */
     	multipath_metadata_encode(&md, sector);
     
     	/*
    -	 * Ok, store metadata.
    +	 * Store metadata on the initial provider.
     	 */
    -	for (i = 1; i < nargs; i++) {
    -		name = gctl_get_ascii(req, "arg%d", i);
    -		error = g_metadata_store(name, sector, secsize);
    -		if (error != 0) {
    -			fprintf(stderr, "Can't store metadata on %s: %s.\n",
    -			    name, strerror(error));
    -			goto fail;
    -		}
    +	error = g_metadata_store(name, sector, secsize);
    +	if (error != 0) {
    +		gctl_error(req, "cannot store metadata on %s: %s.", name, strerror(error));
    +		return;
     	}
    -	return;
     
    -fail:
     	/*
    -	 * Clear last sector first for each provider to spoil anything extant
    +	 * Now add the rest of the providers.
     	 */
    -	for (i = 1; i < nargs; i++) {
    -		name = gctl_get_ascii(req, "arg%d", i);
    -		error = g_metadata_clear(name, NULL);
    -		if (error != 0) {
    -			gctl_error(req, "cannot clear metadata on %s: %s.",
    -			    name, strerror(error));
    +	error = gctl_change_param(req, "verb", -1, "add");
    +	if (error) {
    +		gctl_error(req, "unable to change verb to \"add\": %s.", strerror(error));
    +		return;
    +	}
    +	for (i = 2; i < nargs; i++) {
    +		error = gctl_change_param(req, "arg1", -1, gctl_get_ascii(req, "arg%d", i));
    +		if (error) {
    +			gctl_error(req, "unable to add %s to %s: %s.", gctl_get_ascii(req, "arg%d", i), mpname, strerror(error));
     			continue;
     		}
    +		mp_add(req);
     	}
     }
     
    @@ -221,22 +226,23 @@ static void
     mp_clear(struct gctl_req *req)
     {
     	const char *name;
    -	int error, i, nargs;
    +	int error;
     
    -	nargs = gctl_get_int(req, "nargs");
    -	if (nargs < 1) {
    -		gctl_error(req, "Too few arguments.");
    -		return;
    +	name = gctl_get_ascii(req, "arg1");
    +	error = g_metadata_clear(name, G_MULTIPATH_MAGIC);
    +	if (error != 0) {
    +		fprintf(stderr, "Can't clear metadata on %s: %s.\n", name, strerror(error));
    +		gctl_error(req, "Not fully done.");
    +	}
    +}
    +
    +static void
    +mp_add(struct gctl_req *req)
    +{
    +	const char *errstr;
    +
    +	errstr = gctl_issue(req);
    +	if (errstr != NULL && errstr[0] != '\0') {
    +		gctl_error(req, "%s", errstr);
     	}
    -
    -        for (i = 0; i < nargs; i++) {
    -		name = gctl_get_ascii(req, "arg%d", i);
    -                error = g_metadata_clear(name, G_MULTIPATH_MAGIC);
    -		if (error != 0) {
    -			fprintf(stderr, "Can't clear metadata on %s: %s.\n",
    -			    name, strerror(error));
    -			gctl_error(req, "Not fully done.");
    -			continue;
    -                }
    -        }
     }
    
    From 230a615521ef83aa32605d80b1f01be66c9878f6 Mon Sep 17 00:00:00 2001
    From: Matt Jacob 
    Date: Thu, 29 Apr 2010 19:11:25 +0000
    Subject: [PATCH 2138/2592] This is an MFC of 205932. nit: xpt_bus_deregister
     has to be called with the sim lock held.
    
    ---
     sys/dev/mpt/mpt_cam.c | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c
    index 6ae6bbedf09..88bc90c96c5 100644
    --- a/sys/dev/mpt/mpt_cam.c
    +++ b/sys/dev/mpt/mpt_cam.c
    @@ -1208,14 +1208,18 @@ mpt_cam_detach(struct mpt_softc *mpt)
     
     	if (mpt->sim != NULL) {
     		xpt_free_path(mpt->path);
    +		MPT_LOCK(mpt);
     		xpt_bus_deregister(cam_sim_path(mpt->sim));
    +		MPT_UNLOCK(mpt);
     		cam_sim_free(mpt->sim, TRUE);
     		mpt->sim = NULL;
     	}
     
     	if (mpt->phydisk_sim != NULL) {
     		xpt_free_path(mpt->phydisk_path);
    +		MPT_LOCK(mpt);
     		xpt_bus_deregister(cam_sim_path(mpt->phydisk_sim));
    +		MPT_UNLOCK(mpt);
     		cam_sim_free(mpt->phydisk_sim, TRUE);
     		mpt->phydisk_sim = NULL;
     	}
    
    From 176b25ad5ca2d289110200e80116d88b213bca1b Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Thu, 29 Apr 2010 22:40:12 +0000
    Subject: [PATCH 2139/2592] MFC r207020, r207027, r207072.
    
     Change usb devd events from fake attach to a notify. The ugen device is not a
     proper device_t so it faked the devctl event to appear like one, this is now a
     notify which allows more information to be passed.
    
     We notify for both the device attach/detach and for each usb interface. A devd
     rule can now match on the interface properties, including composite devices
     which may have a uvideo interface and also usound and possibly uhid too.
    
     An example to match a umass device with a scsi subclass and BBB protocol would be
    
     notify 100 {
     	match "system"          "USB";
     	match "subsystem"       "INTERFACE";
     	match "type"            "ATTACH";
     	match "intclass"        "0x08";
     	match "intsubclass"     "0x06";
     	match "intprotocol"     "0x50";
     	action ...
     };
    
     The old attach devctl event has been retained for the moment to make merging to
     8.1 easier. This was never compatible with 7.x or earlier due to the ugen regex
     change needed.
    
     Document the new USB notification types.
    ---
     etc/devd.conf            |  14 ++--
     etc/devd/uath.conf       | 156 +++++++++++++++++++++++----------------
     sbin/devd/devd.conf.5    |  56 +++++++++++++-
     sys/dev/usb/usb_device.c | 102 ++++++++++++++++++++++++-
     4 files changed, 252 insertions(+), 76 deletions(-)
    
    diff --git a/etc/devd.conf b/etc/devd.conf
    index 696ac7c5f1a..8827e3b4e03 100644
    --- a/etc/devd.conf
    +++ b/etc/devd.conf
    @@ -138,12 +138,14 @@ attach 100 {
     # This entry starts the ColdSync tool in daemon mode. Make sure you have an up
     # to date /usr/local/etc/palms. We override the 'listen' settings for port and
     # type in /usr/local/etc/coldsync.conf.
    -attach 100 {
    -	device-name "ugen[0-9]+";
    -	match "vendor" "0x082d";
    -	match "product" "0x0100";
    -	match "release" "0x0100";
    -	action "/usr/local/bin/coldsync -md -p /dev/$device-name -t usb";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x082d";
    +	match "product"		"0x0100";
    +	match "release"		"0x0100";
    +	action "/usr/local/bin/coldsync -md -p /dev/$cdev -t usb";
     };
     
     #
    diff --git a/etc/devd/uath.conf b/etc/devd/uath.conf
    index 33bee69bb17..dc4019cefbc 100644
    --- a/etc/devd/uath.conf
    +++ b/etc/devd/uath.conf
    @@ -4,117 +4,143 @@
     
     # Accton
     #   SMCWUSB-G and SMCWUSBT-G2
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x083a";
    -	match "product" "(0x4505|0x4507)";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x083a";
    +	match "product"		"(0x4505|0x4507)";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # Atheros Communications
     #   AR5523
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x168c";
    -	match "product" "0x0002";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x168c";
    +	match "product"		"0x0002";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # Atheros Communications
     #   AR5523
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x0cf3";
    -	match "product" "(0x0002|0x0004|0x0006)";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x0cf3";
    +	match "product"		"(0x0002|0x0004|0x0006)";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # Conceptronic
     #   AR5523
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x0d8e";
    -	match "product" "(0x7802|0x7812)";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x0d8e";
    +	match "product"		"(0x7802|0x7812)";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # D-Link
     #   DWL-AG132, DWL-G132 and DWL-AG122
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x2001";
    -	match "product" "(0x3a01|0x3a03|0x3a05)";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x2001";
    +	match "product"		"(0x3a01|0x3a03|0x3a05)";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # D-Link
     #  DWA-120
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x07d1";
    -	match "product" "0x3a0c";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x07d1";
    +	match "product"		"0x3a0c";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # Gigaset
     #   SMCWUSBT-G
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x1690";
    -	match "product" "(0x0711|0x0713)";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x1690";
    +	match "product"		"(0x0711|0x0713)";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # Global Sun Technology
     #   AR5523
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x16ab";
    -	match "product" "(0x7802|0x7812)";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x16ab";
    +	match "product"		"(0x7802|0x7812)";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # BayNETGEAR
     #   WG111U
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x0846";
    -	match "product" "0x4301";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x0846";
    +	match "product"		"0x4301";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # Netgear
     #   WG111T and WPN111
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x1385";
    -	match "product" "(0x4251|0x5f01)";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x1385";
    +	match "product"		"(0x4251|0x5f01)";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # U-MEDIA Communications
     #   TEW-444UB and AR5523
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x157e";
    -	match "product" "(0x3007|0x3206)";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x157e";
    +	match "product"		"(0x3007|0x3206)";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # Wistron NeWeb
     #   AR5523
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x1435";
    -	match "product" "(0x0827|0x0829)";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x1435";
    +	match "product"		"(0x0827|0x0829)";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
     
     # Z-Com
     #   AR5523
    -attach 100 {
    -	device-name "ugen[0-9.]+";
    -	match "vendor" "0x0cde";
    -	match "product" "0x0013";
    -	action "/usr/sbin/uathload -d /dev/$device-name";
    +notify 100 {
    +	match "system"		"USB";
    +	match "subsystem"	"DEVICE";
    +	match "type"		"ATTACH";
    +	match "vendor"		"0x0cde";
    +	match "product"		"0x0013";
    +	action "/usr/sbin/uathload -d /dev/$cdev";
     };
    diff --git a/sbin/devd/devd.conf.5 b/sbin/devd/devd.conf.5
    index f7efefb20eb..17c5e099b56 100644
    --- a/sbin/devd/devd.conf.5
    +++ b/sbin/devd/devd.conf.5
    @@ -250,18 +250,40 @@ CIS-vendor.
     Device class.
     .It Li device
     Device ID.
    +.It Li devclass
    +Device Class (USB)
    +.It Li devsubclass
    +Device Sub-class (USB)
     .It Li device-name
     Name of attached/detached device.
    +.It Li endpoints
    +Endpoint count (USB)
     .It Li function
     Card functions.
    +.It Li interface
    +Interface ID (USB)
    +.It Li intclass
    +Interface Class (USB)
    +.It Li intprotocol
    +Interface Protocol  (USB)
    +.It Li intsubclass
    +Interface Sub-class (USB)
     .It Li manufacturer
     Manufacturer ID (pccard).
    +.It Li mode
    +Peripheral mode (USB)
     .It Li notify
     Match the value of the
     .Dq Li notify
     variable.
    +.It Li parent
    +Parent device
    +.It Li port
    +Hub port number (USB)
     .It Li product
    -Product ID (pccard).
    +Product ID (pccard/USB).
    +.It Li release
    +Hardware revision (USB)
     .It Li serial
     Serial Number (USB).
     .It Li slot
    @@ -342,6 +364,27 @@ The
     node is destroyed.
     .El
     .El
    +.It Li USB
    +Events related to the USB subsystem.
    +.Bl -tag -width ".Sy Subsystem" -compact
    +.It Sy Subsystem
    +.It Li DEVICE
    +.Bl -tag -width ".Li DETACH" -compact
    +.It Sy Type
    +.It Li ATTACH
    +USB device is attached to the system.
    +.It Li DETACH
    +USB device is detached from the system.
    +.El
    +.It Li INTERFACE
    +.Bl -tag -width ".Li DETACH" -compact
    +.It Sy Type
    +.It Li ATTACH
    +USB interface is attached from a device.
    +.It Li DETACH
    +USB interface is detached from a device.
    +.El
    +.El
     .It Li coretemp
     Events related to the
     .Xr coretemp 4
    @@ -460,6 +503,17 @@ notify 0 {
     	action "logger Lid opened, the sleeper must awaken!";
     };
     
    +#
    +# Match a USB device type
    +#
    +notify 0 {
    +	match "system"			"USB";
    +	match "subsystem"		"INTERFACE";
    +	match "type"			"ATTACH";
    +	match "intclass"		"0x0e";
    +	action "logger USB video device attached";
    +};
    +
     #
     # Try to configure ath and wi devices with pccard_ether
     # as they are attached.
    diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
    index d7f0c31c8d3..2f3a402d4ac 100644
    --- a/sys/dev/usb/usb_device.c
    +++ b/sys/dev/usb/usb_device.c
    @@ -45,6 +45,7 @@
     #include 
     #include 
     #include 
    +#include 
     
     #include 
     #include 
    @@ -1834,7 +1835,7 @@ config_done:
     	printf("%s: <%s> at %s\n", udev->ugen_name, udev->manufacturer,
     	    device_get_nameunit(udev->bus->bdev));
     
    -	usb_notify_addq("+", udev);
    +	usb_notify_addq("ATTACH", udev);
     #endif
     done:
     	if (err) {
    @@ -1980,7 +1981,7 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
     	usb_set_device_state(udev, USB_STATE_DETACHED);
     
     #if USB_HAVE_UGEN
    -	usb_notify_addq("-", udev);
    +	usb_notify_addq("DETACH", udev);
     
     	printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name,
     	    udev->manufacturer, device_get_nameunit(bus->bdev));
    @@ -2347,13 +2348,23 @@ usbd_get_device_index(struct usb_device *udev)
      *
      * This function will generate events for dev.
      *------------------------------------------------------------------------*/
    +#ifndef BURN_BRIDGES
     static void
    -usb_notify_addq(const char *type, struct usb_device *udev)
    +usb_notify_addq_compat(const char *type, struct usb_device *udev)
     {
     	char *data = NULL;
    +	const char *ntype;
     	struct malloc_type *mt;
     	const size_t buf_size = 512;
     
    +	/* Convert notify type */
    +	if (strcmp(type, "ATTACH") == 0)
    +		ntype = "+";
    +	else if (strcmp(type, "DETACH") == 0)
    +		ntype = "-";
    +	else
    +		return;
    +
     	mtx_lock(&malloc_mtx);
     	mt = malloc_desc2type("bus");	/* XXX M_BUS */
     	mtx_unlock(&malloc_mtx);
    @@ -2378,7 +2389,7 @@ usb_notify_addq(const char *type, struct usb_device *udev)
     	    "port=%u "
     	    "on "
     	    "%s\n",
    -	    type,
    +	    ntype,
     	    udev->ugen_name,
     	    UGETW(udev->ddesc.idVendor),
     	    UGETW(udev->ddesc.idProduct),
    @@ -2393,6 +2404,89 @@ usb_notify_addq(const char *type, struct usb_device *udev)
     
     	devctl_queue_data(data);
     }
    +#endif
    +
    +static void
    +usb_notify_addq(const char *type, struct usb_device *udev)
    +{
    +	struct usb_interface *iface;
    +	struct sbuf *sb;
    +	int i;
    +
    +#ifndef BURN_BRIDGES
    +	usb_notify_addq_compat(type, udev);
    +#endif
    +
    +	/* announce the device */
    +	sb = sbuf_new_auto();
    +	sbuf_printf(sb,
    +	    "cdev=%s "
    +	    "vendor=0x%04x "
    +	    "product=0x%04x "
    +	    "devclass=0x%02x "
    +	    "devsubclass=0x%02x "
    +	    "sernum=\"%s\" "
    +	    "release=0x%04x "
    +	    "mode=%s "
    +	    "port=%u "
    +	    "parent=%s\n",
    +	    udev->ugen_name,
    +	    UGETW(udev->ddesc.idVendor),
    +	    UGETW(udev->ddesc.idProduct),
    +	    udev->ddesc.bDeviceClass,
    +	    udev->ddesc.bDeviceSubClass,
    +	    udev->serial,
    +	    UGETW(udev->ddesc.bcdDevice),
    +	    (udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
    +	    udev->port_no,
    +	    udev->parent_hub != NULL ?
    +	    udev->parent_hub->ugen_name :
    +	    device_get_nameunit(device_get_parent(udev->bus->bdev)));
    +	sbuf_finish(sb);
    +	devctl_notify("USB", "DEVICE", type, sbuf_data(sb));
    +	sbuf_delete(sb);
    +
    +	/* announce each interface */
    +	for (i = 0; i < USB_IFACE_MAX; i++) {
    +		iface = usbd_get_iface(udev, i);
    +		if (iface == NULL)
    +			break;		/* end of interfaces */
    +		if (iface->idesc == NULL)
    +			continue;	/* no interface descriptor */
    +
    +		sb = sbuf_new_auto();
    +		sbuf_printf(sb,
    +		    "cdev=%s "
    +		    "vendor=0x%04x "
    +		    "product=0x%04x "
    +		    "devclass=0x%02x "
    +		    "devsubclass=0x%02x "
    +		    "sernum=\"%s\" "
    +		    "release=0x%04x "
    +		    "mode=%s "
    +		    "interface=%d "
    +		    "endpoints=%d "
    +		    "intclass=0x%02x "
    +		    "intsubclass=0x%02x "
    +		    "intprotocol=0x%02x\n",
    +		    udev->ugen_name,
    +		    UGETW(udev->ddesc.idVendor),
    +		    UGETW(udev->ddesc.idProduct),
    +		    udev->ddesc.bDeviceClass,
    +		    udev->ddesc.bDeviceSubClass,
    +		    udev->serial,
    +		    UGETW(udev->ddesc.bcdDevice),
    +		    (udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
    +		    iface->idesc->bInterfaceNumber,
    +		    iface->idesc->bNumEndpoints,
    +		    iface->idesc->bInterfaceClass,
    +		    iface->idesc->bInterfaceSubClass,
    +		    iface->idesc->bInterfaceProtocol);
    +		sbuf_finish(sb);
    +		devctl_notify("USB", "INTERFACE", type, sbuf_data(sb));
    +		sbuf_delete(sb);
    +	}
    +}
     
     /*------------------------------------------------------------------------*
      *	usb_fifo_free_wrap
    
    From ad658060138bd5747b2c8ed77149a2ad39b834c8 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Thu, 29 Apr 2010 22:44:04 +0000
    Subject: [PATCH 2140/2592] MFC r207077
    
     Change USB_DEBUG to #ifdef and allow it to be turned off. Previously this had
     the illusion of a tunable setting but was always turned on regardless.
    ---
     sys/amd64/conf/GENERIC             |  1 +
     sys/arm/conf/DB-78XXX              |  1 +
     sys/arm/conf/DB-88F5XXX            |  1 +
     sys/arm/conf/DB-88F6XXX            |  1 +
     sys/arm/conf/HL200                 |  1 +
     sys/arm/conf/KB920X                |  1 +
     sys/arm/conf/SHEEVAPLUG            |  1 +
     sys/dev/sound/usb/uaudio.c         | 22 ++++++++---------
     sys/dev/usb/controller/ehci.c      | 38 +++++++++++++++---------------
     sys/dev/usb/controller/uhci.c      | 34 +++++++++++++-------------
     sys/dev/usb/controller/uss820dci.c |  2 +-
     sys/dev/usb/input/atp.c            | 12 +++++-----
     sys/dev/usb/input/uhid.c           |  2 +-
     sys/dev/usb/input/ukbd.c           |  6 ++---
     sys/dev/usb/input/ums.c            |  6 +++--
     sys/dev/usb/misc/udbp.c            |  2 +-
     sys/dev/usb/net/if_aue.c           |  2 +-
     sys/dev/usb/net/if_axe.c           |  2 +-
     sys/dev/usb/net/if_cdce.c          |  2 +-
     sys/dev/usb/net/if_cue.c           |  2 +-
     sys/dev/usb/net/if_kue.c           |  2 +-
     sys/dev/usb/net/if_rue.c           |  2 +-
     sys/dev/usb/net/if_udav.c          |  2 +-
     sys/dev/usb/serial/u3g.c           |  2 +-
     sys/dev/usb/serial/ubsa.c          |  5 ++--
     sys/dev/usb/serial/ubser.c         |  2 +-
     sys/dev/usb/serial/uchcom.c        |  2 +-
     sys/dev/usb/serial/uftdi.c         |  2 +-
     sys/dev/usb/serial/ulpt.c          |  2 +-
     sys/dev/usb/serial/umodem.c        |  2 +-
     sys/dev/usb/serial/umoscom.c       |  2 +-
     sys/dev/usb/serial/uplcom.c        |  2 +-
     sys/dev/usb/serial/usb_serial.c    |  2 +-
     sys/dev/usb/serial/uslcom.c        |  2 +-
     sys/dev/usb/serial/uvisor.c        |  4 ++--
     sys/dev/usb/serial/uvscom.c        |  2 +-
     sys/dev/usb/storage/umass.c        |  8 +++----
     sys/dev/usb/storage/urio.c         |  2 +-
     sys/dev/usb/storage/ustorage_fs.c  |  2 +-
     sys/dev/usb/usb_debug.h            |  2 +-
     sys/dev/usb/usb_freebsd.h          |  4 ----
     sys/dev/usb/usb_request.c          | 12 +++++-----
     sys/dev/usb/usb_transfer.c         |  2 +-
     sys/dev/usb/wlan/if_rum.c          |  2 +-
     sys/dev/usb/wlan/if_run.c          |  2 +-
     sys/dev/usb/wlan/if_ural.c         |  2 +-
     sys/dev/usb/wlan/if_zyd.c          |  2 +-
     sys/i386/conf/GENERIC              |  1 +
     sys/i386/conf/XBOX                 |  1 +
     sys/ia64/conf/GENERIC              |  1 +
     sys/mips/conf/SENTRY5              |  1 +
     sys/pc98/conf/GENERIC              |  1 +
     sys/powerpc/conf/GENERIC           |  1 +
     sys/powerpc/conf/MPC85XX           |  1 +
     sys/sparc64/conf/GENERIC           |  1 +
     sys/sun4v/conf/GENERIC             |  1 +
     56 files changed, 119 insertions(+), 106 deletions(-)
    
    diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
    index a0edfca7e95..999ccb7b1ad 100644
    --- a/sys/amd64/conf/GENERIC
    +++ b/sys/amd64/conf/GENERIC
    @@ -281,6 +281,7 @@ device		firmware	# firmware assist module
     device		bpf		# Berkeley packet filter
     
     # USB support
    +options 	USB_DEBUG	# enable debug msgs
     device		uhci		# UHCI PCI->USB interface
     device		ohci		# OHCI PCI->USB interface
     device		ehci		# EHCI PCI->USB interface (USB 2.0)
    diff --git a/sys/arm/conf/DB-78XXX b/sys/arm/conf/DB-78XXX
    index afa6ec9a97a..98811cb4079 100644
    --- a/sys/arm/conf/DB-78XXX
    +++ b/sys/arm/conf/DB-78XXX
    @@ -66,6 +66,7 @@ device		e1000phy
     device		bpf
     
     # USB
    +options 	USB_DEBUG	# enable debug msgs
     device		usb
     device		ehci
     device		umass
    diff --git a/sys/arm/conf/DB-88F5XXX b/sys/arm/conf/DB-88F5XXX
    index 1297229a2aa..9cb4e269587 100644
    --- a/sys/arm/conf/DB-88F5XXX
    +++ b/sys/arm/conf/DB-88F5XXX
    @@ -73,6 +73,7 @@ device		iicbus
     device		ds133x
     
     # USB
    +options 	USB_DEBUG	# enable debug msgs
     device		usb
     device		ehci
     device		umass
    diff --git a/sys/arm/conf/DB-88F6XXX b/sys/arm/conf/DB-88F6XXX
    index cbf7abd296c..b55144a12aa 100644
    --- a/sys/arm/conf/DB-88F6XXX
    +++ b/sys/arm/conf/DB-88F6XXX
    @@ -66,6 +66,7 @@ device		e1000phy
     device		bpf
     
     # USB
    +options 	USB_DEBUG	# enable debug msgs
     device		usb
     device		ehci
     device		umass
    diff --git a/sys/arm/conf/HL200 b/sys/arm/conf/HL200
    index 61f74cf6287..d4ad701af4d 100644
    --- a/sys/arm/conf/HL200
    +++ b/sys/arm/conf/HL200
    @@ -94,6 +94,7 @@ device		icee
     
     device		bpf
     # USB support
    +options 	USB_DEBUG	# enable debug msgs
     device		ohci		# OHCI localbus->USB interface
     device		usb		# USB Bus (required)
     #device		udbp		# USB Double Bulk Pipe devices
    diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X
    index 31f00962244..9d208c233e6 100644
    --- a/sys/arm/conf/KB920X
    +++ b/sys/arm/conf/KB920X
    @@ -95,6 +95,7 @@ device		icee
     
     device		bpf
     # USB support
    +options 	USB_DEBUG	# enable debug msgs
     device		ohci		# OHCI localbus->USB interface
     device		usb		# USB Bus (required)
     #device		udbp		# USB Double Bulk Pipe devices
    diff --git a/sys/arm/conf/SHEEVAPLUG b/sys/arm/conf/SHEEVAPLUG
    index d11b34d57b3..dcd82e5549d 100644
    --- a/sys/arm/conf/SHEEVAPLUG
    +++ b/sys/arm/conf/SHEEVAPLUG
    @@ -61,6 +61,7 @@ options		DEVICE_POLLING
     device		vlan
     
     # USB
    +options 	USB_DEBUG	# enable debug msgs
     device		usb
     device		ehci
     device		umass
    diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
    index 069a8c04887..16132667d5a 100644
    --- a/sys/dev/sound/usb/uaudio.c
    +++ b/sys/dev/sound/usb/uaudio.c
    @@ -91,7 +91,7 @@ static int uaudio_default_rate = 0;		/* use rate list */
     static int uaudio_default_bits = 32;
     static int uaudio_default_channels = 0;		/* use default */
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uaudio_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
    @@ -321,7 +321,7 @@ static const struct uaudio_format uaudio_formats[] = {
     #define	UAC_RECORD	3
     #define	UAC_NCLASSES	4
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static const char *uac_names[] = {
     	"outputs", "inputs", "equalization", "record"
     };
    @@ -406,7 +406,7 @@ static void	umidi_init(device_t dev);
     static int32_t	umidi_probe(device_t dev);
     static int32_t	umidi_detach(device_t dev);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static void	uaudio_chan_dump_ep_desc(
     		    const usb_endpoint_descriptor_audio_t *);
     static void	uaudio_mixer_dump_cluster(uint8_t,
    @@ -780,7 +780,7 @@ uaudio_detach(device_t dev)
      * AS - Audio Stream - routines
      *========================================================================*/
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static void
     uaudio_chan_dump_ep_desc(const usb_endpoint_descriptor_audio_t *ed)
     {
    @@ -1019,7 +1019,7 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
     				if ((chan->valid == 0) && usbd_get_iface(udev, curidx)) {
     
     					chan->valid = 1;
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     					uaudio_chan_dump_ep_desc(ed1);
     					uaudio_chan_dump_ep_desc(ed2);
     
    @@ -1689,7 +1689,7 @@ uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct uaudio_mixer_node *mc)
     
     	uaudio_mixer_add_ctl_sub(sc, mc);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (uaudio_debug > 2) {
     		uint8_t i;
     
    @@ -1708,7 +1708,7 @@ static void
     uaudio_mixer_add_input(struct uaudio_softc *sc,
         const struct uaudio_terminal_node *iot, int id)
     {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	const struct usb_audio_input_terminal *d = iot[id].u.it;
     
     	DPRINTFN(3, "bTerminalId=%d wTerminalType=0x%04x "
    @@ -1724,7 +1724,7 @@ static void
     uaudio_mixer_add_output(struct uaudio_softc *sc,
         const struct uaudio_terminal_node *iot, int id)
     {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	const struct usb_audio_output_terminal *d = iot[id].u.ot;
     
     	DPRINTFN(3, "bTerminalId=%d wTerminalType=0x%04x "
    @@ -2257,7 +2257,7 @@ error:
     	return (NULL);
     }
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static void
     uaudio_mixer_dump_cluster(uint8_t id, const struct uaudio_terminal_node *iot)
     {
    @@ -2350,7 +2350,7 @@ done:
     	return (r);
     }
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     
     struct uaudio_tt_to_string {
     	uint16_t terminal_type;
    @@ -2856,7 +2856,7 @@ uaudio_mixer_fill_info(struct uaudio_softc *sc, struct usb_device *udev,
     		(iot + i)->root = iot;
     	} while (i--);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	i = ID_max;
     	do {
     		uint8_t j;
    diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c
    index 28ad987b31d..12cfe53680c 100644
    --- a/sys/dev/usb/controller/ehci.c
    +++ b/sys/dev/usb/controller/ehci.c
    @@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$");
        ((ehci_softc_t *)(((uint8_t *)(bus)) - \
         ((uint8_t *)&(((ehci_softc_t *)0)->sc_bus))))
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int ehcidebug = 0;
     static int ehcinohighspeed = 0;
     static int ehciiaadbug = 0;
    @@ -258,7 +258,7 @@ ehci_init(ehci_softc_t *sc)
     	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
    +#ifdef USB_DEBUG
     	if (ehciiaadbug)
     		sc->sc_flags |= EHCI_SCFLG_IAADBUG;
     	if (ehcilostintrbug)
    @@ -486,7 +486,7 @@ ehci_init(ehci_softc_t *sc)
     
     	usb_bus_mem_flush_all(&sc->sc_bus, &ehci_iterate_hw_softc);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (ehcidebug) {
     		ehci_dump_sqh(sc, sc->sc_async_p_last);
     	}
    @@ -685,7 +685,7 @@ ehci_shutdown(ehci_softc_t *sc)
     	}
     }
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static void
     ehci_dump_regs(ehci_softc_t *sc)
     {
    @@ -1229,7 +1229,7 @@ ehci_non_isoc_done_sub(struct usb_xfer *xfer)
     
     	xfer->td_transfer_cache = td;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (status & EHCI_QTD_STATERRS) {
     		DPRINTFN(11, "error, addr=%d, endpt=0x%02x, frame=0x%02x"
     		    "status=%s%s%s%s%s%s%s%s\n",
    @@ -1260,7 +1260,7 @@ ehci_non_isoc_done(struct usb_xfer *xfer)
     	DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
     	    xfer, xfer->endpoint);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (ehcidebug > 10) {
     		ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
     
    @@ -1527,7 +1527,7 @@ ehci_interrupt(ehci_softc_t *sc)
     
     	DPRINTFN(16, "real interrupt\n");
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (ehcidebug > 15) {
     		ehci_dump_regs(sc);
     	}
    @@ -1548,7 +1548,7 @@ ehci_interrupt(ehci_softc_t *sc)
     	if (status & EHCI_STS_HSE) {
     		printf("%s: unrecoverable error, "
     		    "controller halted\n", __FUNCTION__);
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     		ehci_dump_regs(sc);
     		ehci_dump_isoc(sc);
     #endif
    @@ -1978,7 +1978,7 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last)
     
     	xfer->td_transfer_last = td;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (ehcidebug > 8) {
     		DPRINTF("nexttog=%d; data before transfer:\n",
     		    xfer->endpoint->toggle_next);
    @@ -2106,7 +2106,7 @@ ehci_isoc_fs_done(ehci_softc_t *sc, struct usb_xfer *xfer)
     		if (pp_last >= &sc->sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
     			pp_last = &sc->sc_isoc_fs_p_last[0];
     		}
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     		if (ehcidebug > 15) {
     			DPRINTF("isoc FS-TD\n");
     			ehci_dump_sitd(sc, td);
    @@ -2160,7 +2160,7 @@ ehci_isoc_hs_done(ehci_softc_t *sc, struct usb_xfer *xfer)
     		if (pp_last >= &sc->sc_isoc_hs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
     			pp_last = &sc->sc_isoc_hs_p_last[0];
     		}
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     		if (ehcidebug > 15) {
     			DPRINTF("isoc HS-TD\n");
     			ehci_dump_itd(sc, td);
    @@ -2224,7 +2224,7 @@ ehci_device_done(struct usb_xfer *xfer, usb_error_t error)
     
     	if ((methods == &ehci_device_bulk_methods) ||
     	    (methods == &ehci_device_ctrl_methods)) {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     		if (ehcidebug > 8) {
     			DPRINTF("nexttog=%d; data after transfer:\n",
     			    xfer->endpoint->toggle_next);
    @@ -2509,7 +2509,7 @@ ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
     	uint8_t sb;
     	uint8_t error;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	uint8_t once = 1;
     
     #endif
    @@ -2593,7 +2593,7 @@ ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
     		/* reuse sitd_portaddr and sitd_back from last transfer */
     
     		if (*plen > xfer->max_frame_size) {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     			if (once) {
     				once = 0;
     				printf("%s: frame length(%d) exceeds %d "
    @@ -2683,7 +2683,7 @@ ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
     		}
     		usb_pc_cpu_flush(td->page_cache);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     		if (ehcidebug > 15) {
     			DPRINTF("FS-TD %d\n", nframes);
     			ehci_dump_sitd(sc, td);
    @@ -2800,7 +2800,7 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
     	uint8_t td_no;
     	uint8_t page_no;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	uint8_t once = 1;
     
     #endif
    @@ -2878,7 +2878,7 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
     		}
     		/* range check */
     		if (*plen > xfer->max_frame_size) {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     			if (once) {
     				once = 0;
     				printf("%s: frame length(%d) exceeds %d bytes "
    @@ -2962,7 +2962,7 @@ ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
     				td->itd_status[td_no - 1] |= htohc32(sc, EHCI_ITD_IOC);
     			}
     			usb_pc_cpu_flush(td->page_cache);
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     			if (ehcidebug > 15) {
     				DPRINTF("HS-TD %d\n", nframes);
     				ehci_dump_itd(sc, td);
    @@ -3398,7 +3398,7 @@ ehci_roothub_exec(struct usb_device *udev,
     			break;
     		case UHF_PORT_RESET:
     			DPRINTFN(6, "reset port %d\n", index);
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     			if (ehcinohighspeed) {
     				/*
     				 * Connect USB device to companion
    diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c
    index 918855bf5aa..095bebfc159 100644
    --- a/sys/dev/usb/controller/uhci.c
    +++ b/sys/dev/usb/controller/uhci.c
    @@ -82,7 +82,7 @@ __FBSDID("$FreeBSD$");
        ((uhci_softc_t *)(((uint8_t *)(bus)) - \
         ((uint8_t *)&(((uhci_softc_t *)0)->sc_bus))))
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uhcidebug = 0;
     static int uhcinoloop = 0;
     
    @@ -459,7 +459,7 @@ uhci_init(uhci_softc_t *sc)
     
     	usb_callout_init_mtx(&sc->sc_root_intr, &sc->sc_bus.bus_mtx, 0);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (uhcidebug > 2) {
     		uhci_dumpregs(sc);
     	}
    @@ -668,7 +668,7 @@ uhci_suspend(uhci_softc_t *sc)
     {
     	USB_BUS_LOCK(&sc->sc_bus);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (uhcidebug > 2) {
     		uhci_dumpregs(sc);
     	}
    @@ -712,7 +712,7 @@ uhci_resume(uhci_softc_t *sc)
     
     	uhci_start(sc);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (uhcidebug > 2) {
     		uhci_dumpregs(sc);
     	}
    @@ -724,7 +724,7 @@ uhci_resume(uhci_softc_t *sc)
     	uhci_do_poll(&sc->sc_bus);
     }
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static void
     uhci_dumpregs(uhci_softc_t *sc)
     {
    @@ -882,7 +882,7 @@ uhci_add_loop(uhci_softc_t *sc)
     	struct uhci_qh *qh_lst;
     	struct uhci_qh *qh_rec;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (uhcinoloop) {
     		return;
     	}
    @@ -905,7 +905,7 @@ uhci_rem_loop(uhci_softc_t *sc)
     {
     	struct uhci_qh *qh_lst;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (uhcinoloop) {
     		return;
     	}
    @@ -1073,7 +1073,7 @@ uhci_isoc_done(uhci_softc_t *sc, struct usb_xfer *xfer)
     		if (pp_last >= &sc->sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]) {
     			pp_last = &sc->sc_isoc_p_last[0];
     		}
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     		if (uhcidebug > 5) {
     			DPRINTF("isoc TD\n");
     			uhci_dump_td(td);
    @@ -1204,7 +1204,7 @@ uhci_non_isoc_done_sub(struct usb_xfer *xfer)
     
     	xfer->endpoint->toggle_next = (token & UHCI_TD_SET_DT(1)) ? 0 : 1;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (status & UHCI_TD_ERROR) {
     		DPRINTFN(11, "error, addr=%d, endpt=0x%02x, frame=0x%02x "
     		    "status=%s%s%s%s%s%s%s%s%s%s%s\n",
    @@ -1234,7 +1234,7 @@ uhci_non_isoc_done(struct usb_xfer *xfer)
     	DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
     	    xfer, xfer->endpoint);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (uhcidebug > 10) {
     		uhci_dump_tds(xfer->td_transfer_first);
     	}
    @@ -1473,7 +1473,7 @@ uhci_interrupt(uhci_softc_t *sc)
     
     	DPRINTFN(16, "real interrupt\n");
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (uhcidebug > 15) {
     		uhci_dumpregs(sc);
     	}
    @@ -1487,7 +1487,7 @@ uhci_interrupt(uhci_softc_t *sc)
     	    UHCI_STS_HCPE | UHCI_STS_HCH)) {
     
     		if (status & UHCI_STS_RD) {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     			printf("%s: resume detect\n",
     			    __FUNCTION__);
     #endif
    @@ -1504,7 +1504,7 @@ uhci_interrupt(uhci_softc_t *sc)
     			/* no acknowledge needed */
     			DPRINTF("%s: host controller halted\n",
     			    __FUNCTION__);
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     			if (uhcidebug > 0) {
     				uhci_dump_all(sc);
     			}
    @@ -1866,7 +1866,7 @@ uhci_setup_standard_chain(struct usb_xfer *xfer)
     
     	xfer->td_transfer_last = td;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (uhcidebug > 8) {
     		DPRINTF("nexttog=%d; data before transfer:\n",
     		    xfer->endpoint->toggle_next);
    @@ -2182,7 +2182,7 @@ uhci_device_isoc_enter(struct usb_xfer *xfer)
     	uint32_t temp;
     	uint32_t *plen;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	uint8_t once = 1;
     
     #endif
    @@ -2254,7 +2254,7 @@ uhci_device_isoc_enter(struct usb_xfer *xfer)
     			pp_last = &sc->sc_isoc_p_last[0];
     		}
     		if (*plen > xfer->max_frame_size) {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     			if (once) {
     				once = 0;
     				printf("%s: frame length(%d) exceeds %d "
    @@ -2306,7 +2306,7 @@ uhci_device_isoc_enter(struct usb_xfer *xfer)
     
     		usb_pc_cpu_flush(td->page_cache);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     		if (uhcidebug > 5) {
     			DPRINTF("TD %d\n", nframes);
     			uhci_dump_td(td);
    diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c
    index c910c1f21dd..74221695f84 100644
    --- a/sys/dev/usb/controller/uss820dci.c
    +++ b/sys/dev/usb/controller/uss820dci.c
    @@ -77,7 +77,7 @@
     #define	USS820_DCI_PC2SC(pc) \
        USS820_DCI_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uss820dcidebug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, uss820dci, CTLFLAG_RW, 0, "USB uss820dci");
    diff --git a/sys/dev/usb/input/atp.c b/sys/dev/usb/input/atp.c
    index 6c0ce2c7036..c0fe6d4b386 100644
    --- a/sys/dev/usb/input/atp.c
    +++ b/sys/dev/usb/input/atp.c
    @@ -116,7 +116,7 @@ __FBSDID("$FreeBSD$");
     /* Tunables */
     SYSCTL_NODE(_hw_usb, OID_AUTO, atp, CTLFLAG_RW, 0, "USB atp");
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     enum atp_log_level {
     	ATP_LLEVEL_DISABLED = 0,
     	ATP_LLEVEL_ERROR,
    @@ -126,7 +126,7 @@ enum atp_log_level {
     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 */
    +#endif /* 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,
    @@ -1055,7 +1055,7 @@ atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
     		if (pspans_y[j].matched == FALSE) break;
     	}
     	if ((i < n_xpspans) && (j < n_ypspans)) {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     		if (atp_debug >= ATP_LLEVEL_INFO) {
     			printf("unmatched pspans:");
     			for (; i < n_xpspans; i++) {
    @@ -1072,7 +1072,7 @@ atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
     			}
     			printf("\n");
     		}
    -#endif /* #if USB_DEBUG */
    +#endif /* 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]);
    @@ -1082,7 +1082,7 @@ atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
     			    pspans_y, n_ypspans);
     	}
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (atp_debug >= ATP_LLEVEL_INFO) {
     		for (i = 0; i < sc->sc_n_strokes; i++) {
     			atp_stroke *stroke = &sc->sc_strokes[i];
    @@ -1110,7 +1110,7 @@ atp_update_strokes(struct atp_softc *sc, atp_pspan *pspans_x,
     		if (sc->sc_n_strokes)
     			printf("\n");
     	}
    -#endif /* #if USB_DEBUG */
    +#endif /* USB_DEBUG */
     
     	return (movement);
     }
    diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c
    index be356a5e49d..d214c7cf1b7 100644
    --- a/sys/dev/usb/input/uhid.c
    +++ b/sys/dev/usb/input/uhid.c
    @@ -83,7 +83,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uhid_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, uhid, CTLFLAG_RW, 0, "USB uhid");
    diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
    index 47c6f889fe6..4aad840ccbf 100644
    --- a/sys/dev/usb/input/ukbd.c
    +++ b/sys/dev/usb/input/ukbd.c
    @@ -95,7 +95,7 @@ __FBSDID("$FreeBSD$");
     /* the following file must be included after "ukbdmap.h" */
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int ukbd_debug = 0;
     static int ukbd_no_leds = 0;
     
    @@ -621,7 +621,7 @@ ukbd_intr_callback(struct usb_xfer *xfer, usb_error_t error)
     				apple_fn = 1;
     			else
     				apple_fn = 0;
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     			DPRINTF("apple_eject=%u apple_fn=%u\n",
     			    apple_eject, apple_fn);
     
    @@ -687,7 +687,7 @@ ukbd_set_leds_callback(struct usb_xfer *xfer, usb_error_t error)
     	uint8_t buf[2];
     	struct ukbd_softc *sc = usbd_xfer_softc(xfer);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (ukbd_no_leds)
     		return;
     #endif
    diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c
    index e29f4ebbb28..2c97de6f082 100644
    --- a/sys/dev/usb/input/ums.c
    +++ b/sys/dev/usb/input/ums.c
    @@ -81,7 +81,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int ums_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, ums, CTLFLAG_RW, 0, "USB ums");
    @@ -501,7 +501,9 @@ ums_attach(device_t dev)
     	int err;
     	uint16_t d_len;
     	uint8_t i;
    +#ifdef USB_DEBUG
     	uint8_t j;
    +#endif
     
     	DPRINTFN(11, "sc=%p\n", sc);
     
    @@ -595,7 +597,7 @@ ums_attach(device_t dev)
     	free(d_ptr, M_TEMP);
     	d_ptr = NULL;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	for (j = 0; j < UMS_INFO_MAX; j++) {
     		info = &sc->sc_info[j];
     
    diff --git a/sys/dev/usb/misc/udbp.c b/sys/dev/usb/misc/udbp.c
    index ada6b3c0a29..5eef3103c31 100644
    --- a/sys/dev/usb/misc/udbp.c
    +++ b/sys/dev/usb/misc/udbp.c
    @@ -94,7 +94,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int udbp_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, udbp, CTLFLAG_RW, 0, "USB udbp");
    diff --git a/sys/dev/usb/net/if_aue.c b/sys/dev/usb/net/if_aue.c
    index b508474e468..a8c0a548b51 100644
    --- a/sys/dev/usb/net/if_aue.c
    +++ b/sys/dev/usb/net/if_aue.c
    @@ -100,7 +100,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int aue_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, aue, CTLFLAG_RW, 0, "USB aue");
    diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c
    index 9772f401b68..e255c855c94 100644
    --- a/sys/dev/usb/net/if_axe.c
    +++ b/sys/dev/usb/net/if_axe.c
    @@ -123,7 +123,7 @@ __FBSDID("$FreeBSD$");
      */
     #define AXE_178_MAX_FRAME_BURST	1
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int axe_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, axe, CTLFLAG_RW, 0, "USB axe");
    diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c
    index 2fcb0ff0b5b..b5e7fd464bd 100644
    --- a/sys/dev/usb/net/if_cdce.c
    +++ b/sys/dev/usb/net/if_cdce.c
    @@ -108,7 +108,7 @@ static uether_fn_t cdce_setpromisc;
     
     static uint32_t	cdce_m_crc32(struct mbuf *, uint32_t, uint32_t);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int cdce_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet");
    diff --git a/sys/dev/usb/net/if_cue.c b/sys/dev/usb/net/if_cue.c
    index 05ff1a54a88..e26b29f6fd2 100644
    --- a/sys/dev/usb/net/if_cue.c
    +++ b/sys/dev/usb/net/if_cue.c
    @@ -122,7 +122,7 @@ static int	cue_getmac(struct cue_softc *, void *);
     static uint32_t	cue_mchash(const uint8_t *);
     static void	cue_reset(struct cue_softc *);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int cue_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, cue, CTLFLAG_RW, 0, "USB cue");
    diff --git a/sys/dev/usb/net/if_kue.c b/sys/dev/usb/net/if_kue.c
    index 5d35da40bd5..4eee0945d9f 100644
    --- a/sys/dev/usb/net/if_kue.c
    +++ b/sys/dev/usb/net/if_kue.c
    @@ -163,7 +163,7 @@ static int	kue_ctl(struct kue_softc *, uint8_t, uint8_t, uint16_t,
     static int	kue_load_fw(struct kue_softc *);
     static void	kue_reset(struct kue_softc *);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int kue_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, kue, CTLFLAG_RW, 0, "USB kue");
    diff --git a/sys/dev/usb/net/if_rue.c b/sys/dev/usb/net/if_rue.c
    index 3e77305aa97..f0d16086b20 100644
    --- a/sys/dev/usb/net/if_rue.c
    +++ b/sys/dev/usb/net/if_rue.c
    @@ -97,7 +97,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int rue_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, rue, CTLFLAG_RW, 0, "USB rue");
    diff --git a/sys/dev/usb/net/if_udav.c b/sys/dev/usb/net/if_udav.c
    index ae30b142da6..f56e9b03829 100644
    --- a/sys/dev/usb/net/if_udav.c
    +++ b/sys/dev/usb/net/if_udav.c
    @@ -185,7 +185,7 @@ static const struct usb_ether_methods udav_ue_methods = {
     	.ue_mii_sts = udav_ifmedia_status,
     };
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int udav_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, udav, CTLFLAG_RW, 0, "USB udav");
    diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
    index 7ac1bd3310d..ffe88126dfa 100644
    --- a/sys/dev/usb/serial/u3g.c
    +++ b/sys/dev/usb/serial/u3g.c
    @@ -63,7 +63,7 @@
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int u3g_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, u3g, CTLFLAG_RW, 0, "USB 3g");
    diff --git a/sys/dev/usb/serial/ubsa.c b/sys/dev/usb/serial/ubsa.c
    index 32639fcc403..58175094922 100644
    --- a/sys/dev/usb/serial/ubsa.c
    +++ b/sys/dev/usb/serial/ubsa.c
    @@ -93,7 +93,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int ubsa_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, ubsa, CTLFLAG_RW, 0, "USB ubsa");
    @@ -405,9 +405,8 @@ ubsa_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)
     static int
     ubsa_pre_param(struct ucom_softc *ucom, struct termios *t)
     {
    -	struct ubsa_softc *sc = ucom->sc_parent;
     
    -	DPRINTF("sc = %p\n", sc);
    +	DPRINTF("sc = %p\n", ucom->sc_parent);
     
     	switch (t->c_ospeed) {
     	case B0:
    diff --git a/sys/dev/usb/serial/ubser.c b/sys/dev/usb/serial/ubser.c
    index 06c96c026e5..3f2dc2d30c7 100644
    --- a/sys/dev/usb/serial/ubser.c
    +++ b/sys/dev/usb/serial/ubser.c
    @@ -115,7 +115,7 @@ __FBSDID("$FreeBSD$");
     #define	VENDOR_SET_BREAK		0x02
     #define	VENDOR_CLEAR_BREAK		0x03
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int ubser_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, ubser, CTLFLAG_RW, 0, "USB ubser");
    diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c
    index 9fea8492fca..92f3a922345 100644
    --- a/sys/dev/usb/serial/uchcom.c
    +++ b/sys/dev/usb/serial/uchcom.c
    @@ -101,7 +101,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uchcom_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, uchcom, CTLFLAG_RW, 0, "USB uchcom");
    diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
    index fe2d494cc02..413b3101ed7 100644
    --- a/sys/dev/usb/serial/uftdi.c
    +++ b/sys/dev/usb/serial/uftdi.c
    @@ -80,7 +80,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uftdi_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, uftdi, CTLFLAG_RW, 0, "USB uftdi");
    diff --git a/sys/dev/usb/serial/ulpt.c b/sys/dev/usb/serial/ulpt.c
    index 786452fb3de..b24296a7d6f 100644
    --- a/sys/dev/usb/serial/ulpt.c
    +++ b/sys/dev/usb/serial/ulpt.c
    @@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int ulpt_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, ulpt, CTLFLAG_RW, 0, "USB ulpt");
    diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c
    index 39afdad893f..a7d00c9d23a 100644
    --- a/sys/dev/usb/serial/umodem.c
    +++ b/sys/dev/usb/serial/umodem.c
    @@ -116,7 +116,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int umodem_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, umodem, CTLFLAG_RW, 0, "USB umodem");
    diff --git a/sys/dev/usb/serial/umoscom.c b/sys/dev/usb/serial/umoscom.c
    index 0481b192c8b..3a36a44f71c 100644
    --- a/sys/dev/usb/serial/umoscom.c
    +++ b/sys/dev/usb/serial/umoscom.c
    @@ -48,7 +48,7 @@
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int umoscom_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, umoscom, CTLFLAG_RW, 0, "USB umoscom");
    diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c
    index c5d58e46dcb..ae88805bbbb 100644
    --- a/sys/dev/usb/serial/uplcom.c
    +++ b/sys/dev/usb/serial/uplcom.c
    @@ -116,7 +116,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uplcom_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, uplcom, CTLFLAG_RW, 0, "USB uplcom");
    diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c
    index 871ae54190b..6573d8e0c2e 100644
    --- a/sys/dev/usb/serial/usb_serial.c
    +++ b/sys/dev/usb/serial/usb_serial.c
    @@ -104,7 +104,7 @@ __FBSDID("$FreeBSD$");
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom");
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int ucom_debug = 0;
     
     SYSCTL_INT(_hw_usb_ucom, OID_AUTO, debug, CTLFLAG_RW,
    diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c
    index d97cc2c542c..f20c12ac147 100644
    --- a/sys/dev/usb/serial/uslcom.c
    +++ b/sys/dev/usb/serial/uslcom.c
    @@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uslcom_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, uslcom, CTLFLAG_RW, 0, "USB uslcom");
    diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c
    index 8615c8ab24f..71b137f48f2 100644
    --- a/sys/dev/usb/serial/uvisor.c
    +++ b/sys/dev/usb/serial/uvisor.c
    @@ -85,7 +85,7 @@
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uvisor_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, uvisor, CTLFLAG_RW, 0, "USB uvisor");
    @@ -399,7 +399,7 @@ uvisor_init(struct uvisor_softc *sc, struct usb_device *udev, struct usb_config
     			goto done;
     		}
     	}
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (sc->sc_flag & UVISOR_FLAG_VISOR) {
     		uint16_t i, np;
     		const char *desc;
    diff --git a/sys/dev/usb/serial/uvscom.c b/sys/dev/usb/serial/uvscom.c
    index 4e3ff576422..f220587da12 100644
    --- a/sys/dev/usb/serial/uvscom.c
    +++ b/sys/dev/usb/serial/uvscom.c
    @@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int uvscom_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, uvscom, CTLFLAG_RW, 0, "USB uvscom");
    diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
    index b14bb47e8cb..a66357b5db5 100644
    --- a/sys/dev/usb/storage/umass.c
    +++ b/sys/dev/usb/storage/umass.c
    @@ -146,7 +146,7 @@ __FBSDID("$FreeBSD$");
     #define	UMASS_USB_FLAGS
     #endif
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     #define	DIF(m, x)				\
       do {						\
         if (umass_debug & (m)) { x ; }		\
    @@ -488,7 +488,7 @@ static uint8_t	umass_no_transform(struct umass_softc *, uint8_t *, uint8_t);
     static uint8_t	umass_std_transform(struct umass_softc *, union ccb *, uint8_t
     		    *, uint8_t);
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static void	umass_bbb_dump_cbw(struct umass_softc *, umass_bbb_cbw_t *);
     static void	umass_bbb_dump_csw(struct umass_softc *, umass_bbb_csw_t *);
     static void	umass_cbi_dump_cmd(struct umass_softc *, void *, uint8_t);
    @@ -917,7 +917,7 @@ umass_attach(device_t dev)
     	}
     	sc->sc_iface_no = id->bInterfaceNumber;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	device_printf(dev, " ");
     
     	switch (sc->sc_proto & UMASS_PROTO_COMMAND) {
    @@ -3012,7 +3012,7 @@ umass_std_transform(struct umass_softc *sc, union ccb *ccb,
     	return (1);
     }
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static void
     umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw)
     {
    diff --git a/sys/dev/usb/storage/urio.c b/sys/dev/usb/storage/urio.c
    index 403c4c2b216..1aef8469f43 100644
    --- a/sys/dev/usb/storage/urio.c
    +++ b/sys/dev/usb/storage/urio.c
    @@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int urio_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, urio, CTLFLAG_RW, 0, "USB urio");
    diff --git a/sys/dev/usb/storage/ustorage_fs.c b/sys/dev/usb/storage/ustorage_fs.c
    index 10047e11c22..52cfd6eb286 100644
    --- a/sys/dev/usb/storage/ustorage_fs.c
    +++ b/sys/dev/usb/storage/ustorage_fs.c
    @@ -64,7 +64,7 @@
     #define	USB_DEBUG_VAR ustorage_fs_debug
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int ustorage_fs_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, ustorage_fs, CTLFLAG_RW, 0, "USB ustorage_fs");
    diff --git a/sys/dev/usb/usb_debug.h b/sys/dev/usb/usb_debug.h
    index b6bfbcfca1a..8718c89bef9 100644
    --- a/sys/dev/usb/usb_debug.h
    +++ b/sys/dev/usb/usb_debug.h
    @@ -34,7 +34,7 @@ extern int usb_debug;
     
     /* Check if USB debugging is enabled. */
     #ifdef USB_DEBUG_VAR
    -#if (USB_DEBUG != 0)
    +#ifdef USB_DEBUG
     #define	DPRINTFN(n,fmt,...) do {		\
       if ((USB_DEBUG_VAR) >= (n)) {			\
         printf("%s: " fmt,				\
    diff --git a/sys/dev/usb/usb_freebsd.h b/sys/dev/usb/usb_freebsd.h
    index 1f34317d667..8a008cd47dd 100644
    --- a/sys/dev/usb/usb_freebsd.h
    +++ b/sys/dev/usb/usb_freebsd.h
    @@ -57,10 +57,6 @@
     #define	USB_HUB_MAX_DEPTH	5
     #define	USB_EP0_BUFSIZE		1024	/* bytes */
     
    -#ifndef USB_DEBUG
    -#define USB_DEBUG 1
    -#endif
    -
     typedef uint32_t usb_timeout_t;		/* milliseconds */
     typedef uint32_t usb_frlength_t;	/* bytes */
     typedef uint32_t usb_frcount_t;		/* units */
    diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
    index 03745faa7a5..32c57788773 100644
    --- a/sys/dev/usb/usb_request.c
    +++ b/sys/dev/usb/usb_request.c
    @@ -68,7 +68,7 @@
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int usb_pr_poll_delay = USB_PORT_RESET_DELAY;
     static int usb_pr_recovery_delay = USB_PORT_RESET_RECOVERY;
     static int usb_ss_delay = 0;
    @@ -433,7 +433,7 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
     		} else {
     			if (xfer->frlengths[0] == 0) {
     				if (xfer->flags.manual_status) {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     					int temp;
     
     					temp = usb_ss_delay;
    @@ -603,7 +603,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
     	usb_error_t err;
     	uint16_t n;
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	uint16_t pr_poll_delay;
     	uint16_t pr_recovery_delay;
     
    @@ -612,7 +612,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
     	if (err) {
     		goto done;
     	}
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	/* range check input parameters */
     	pr_poll_delay = usb_pr_poll_delay;
     	if (pr_poll_delay < 1) {
    @@ -627,7 +627,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
     #endif
     	n = 0;
     	while (1) {
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     		/* wait for the device to recover from reset */
     		usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay));
     		n += pr_poll_delay;
    @@ -666,7 +666,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
     		err = USB_ERR_TIMEOUT;
     		goto done;
     	}
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	/* wait for the device to recover from reset */
     	usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay));
     #else
    diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c
    index 9be1c0f4bde..dc39fc64b8e 100644
    --- a/sys/dev/usb/usb_transfer.c
    +++ b/sys/dev/usb/usb_transfer.c
    @@ -1418,7 +1418,7 @@ usbd_transfer_submit(struct usb_xfer *xfer)
     	    xfer, xfer->endpoint, xfer->nframes, USB_GET_DATA_ISREAD(xfer) ?
     	    "read" : "write");
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     	if (USB_DEBUG_VAR > 0) {
     		USB_BUS_LOCK(bus);
     
    diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
    index 0cd394d1444..da00489cd95 100644
    --- a/sys/dev/usb/wlan/if_rum.c
    +++ b/sys/dev/usb/wlan/if_rum.c
    @@ -77,7 +77,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int rum_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
    diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
    index 65f48e47be3..df53560c979 100644
    --- a/sys/dev/usb/wlan/if_run.c
    +++ b/sys/dev/usb/wlan/if_run.c
    @@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$");
     
     #define nitems(_a)      (sizeof((_a)) / sizeof((_a)[0]))
     
    -#if	USB_DEBUG
    +#ifdef	USB_DEBUG
     #define RUN_DEBUG
     #endif
     
    diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
    index 25fb86fafa5..4d97e7ac49d 100644
    --- a/sys/dev/usb/wlan/if_ural.c
    +++ b/sys/dev/usb/wlan/if_ural.c
    @@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int ural_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural");
    diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
    index 724bfaaf957..96b8cf2b170 100644
    --- a/sys/dev/usb/wlan/if_zyd.c
    +++ b/sys/dev/usb/wlan/if_zyd.c
    @@ -75,7 +75,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    -#if USB_DEBUG
    +#ifdef USB_DEBUG
     static int zyd_debug = 0;
     
     SYSCTL_NODE(_hw_usb, OID_AUTO, zyd, CTLFLAG_RW, 0, "USB zyd");
    diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
    index d9d36a84f5b..9bb027e1d4d 100644
    --- a/sys/i386/conf/GENERIC
    +++ b/sys/i386/conf/GENERIC
    @@ -294,6 +294,7 @@ device		firmware	# firmware assist module
     device		bpf		# Berkeley packet filter
     
     # USB support
    +options 	USB_DEBUG	# enable debug msgs
     device		uhci		# UHCI PCI->USB interface
     device		ohci		# OHCI PCI->USB interface
     device		ehci		# EHCI PCI->USB interface (USB 2.0)
    diff --git a/sys/i386/conf/XBOX b/sys/i386/conf/XBOX
    index 96719659ed1..2ba5738c008 100644
    --- a/sys/i386/conf/XBOX
    +++ b/sys/i386/conf/XBOX
    @@ -82,6 +82,7 @@ device		pty		# BSD-style compatibility pseudo ttys
     device		bpf		# Berkeley packet filter
     
     # USB support
    +options 	USB_DEBUG	# enable debug msgs
     #device		uhci		# UHCI PCI->USB interface
     device		ohci		# OHCI PCI->USB interface
     device		usb		# USB Bus (required)
    diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
    index a536ced00ec..e3eb5c0df4e 100644
    --- a/sys/ia64/conf/GENERIC
    +++ b/sys/ia64/conf/GENERIC
    @@ -113,6 +113,7 @@ device		ida		# Compaq Smart RAID
     device		mlx		# Mylex DAC960 family
     
     # USB host controllers and peripherals
    +options 	USB_DEBUG	# enable debug msgs
     device		ehci		# EHCI host controller
     device		ohci		# OHCI PCI->USB interface
     device		uhci		# UHCI PCI->USB interface
    diff --git a/sys/mips/conf/SENTRY5 b/sys/mips/conf/SENTRY5
    index bc2438a7228..b3da63c05d3 100644
    --- a/sys/mips/conf/SENTRY5
    +++ b/sys/mips/conf/SENTRY5
    @@ -82,6 +82,7 @@ device		miibus			# attachments
     #device		ath_hal			# pci chip support
     #options 	AH_SUPPORT_AR5416	# enable AR5416 tx/rx descriptors
     
    +options 	USB_DEBUG		# enable debug msgs
     device		usb			# USB Bus (required)
     device		uhci			# UHCI PCI->USB interface
     device		ehci			# EHCI PCI->USB interface (USB 2.0)
    diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
    index 95a20d066fb..bc15cf35de9 100644
    --- a/sys/pc98/conf/GENERIC
    +++ b/sys/pc98/conf/GENERIC
    @@ -247,6 +247,7 @@ device		firmware	# firmware assist module
     device		bpf		# Berkeley packet filter
     
     # USB support
    +#options 	USB_DEBUG	# enable debug msgs
     #device		uhci		# UHCI PCI->USB interface
     #device		ohci		# OHCI PCI->USB interface
     #device		ehci		# EHCI PCI->USB interface (USB 2.0)
    diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
    index a80c141a214..bb0996f9be9 100644
    --- a/sys/powerpc/conf/GENERIC
    +++ b/sys/powerpc/conf/GENERIC
    @@ -139,6 +139,7 @@ device		firmware	# firmware assist module
     device		bpf		#Berkeley packet filter
     
     # USB support
    +options 	USB_DEBUG	# enable debug msgs
     device		uhci		# UHCI PCI->USB interface
     device		ohci		# OHCI PCI->USB interface
     device		ehci		# EHCI PCI->USB interface
    diff --git a/sys/powerpc/conf/MPC85XX b/sys/powerpc/conf/MPC85XX
    index 8e6badc78b7..e58389a958c 100644
    --- a/sys/powerpc/conf/MPC85XX
    +++ b/sys/powerpc/conf/MPC85XX
    @@ -78,6 +78,7 @@ device		sec
     device		tsec
     device		tun
     device		uart
    +options 	USB_DEBUG	# enable debug msgs
     #device		uhci
     device		umass
     device		usb
    diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
    index e8662395475..f6a04a6de8c 100644
    --- a/sys/sparc64/conf/GENERIC
    +++ b/sys/sparc64/conf/GENERIC
    @@ -223,6 +223,7 @@ device		firmware	# firmware assist module
     device		bpf		# Berkeley packet filter
     
     # USB support
    +options 	USB_DEBUG	# enable debug msgs
     device		uhci		# UHCI PCI->USB interface
     device		ohci		# OHCI PCI->USB interface
     device		ehci		# EHCI PCI->USB interface (USB 2.0)
    diff --git a/sys/sun4v/conf/GENERIC b/sys/sun4v/conf/GENERIC
    index 2ff3fa53119..8f8cf72f283 100644
    --- a/sys/sun4v/conf/GENERIC
    +++ b/sys/sun4v/conf/GENERIC
    @@ -183,6 +183,7 @@ device		faith		# IPv6-to-IPv4 relaying (translation)
     device		bpf		# Berkeley packet filter
     
     # USB support
    +options 	USB_DEBUG	# enable debug msgs
     #device		uhci		# UHCI PCI->USB interface
     #device		ohci		# OHCI PCI->USB interface
     device		usb		# USB Bus (required)
    
    From ccd296dfa6bf38cbe042c222593ba93c2ef8961b Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Thu, 29 Apr 2010 22:47:01 +0000
    Subject: [PATCH 2141/2592] MFC r207078
    
     Use SX_DUPOK rather than making the string unique.
    ---
     sys/dev/usb/usb_device.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
    index 2f3a402d4ac..bc386474907 100644
    --- a/sys/dev/usb/usb_device.c
    +++ b/sys/dev/usb/usb_device.c
    @@ -1491,10 +1491,10 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
     		return (NULL);
     	}
     	/* initialise our SX-lock */
    -	sx_init(udev->default_sx, "0123456789ABCDEF - USB device SX lock" + depth);
    +	sx_init_flags(udev->default_sx, "USB device SX lock", SX_DUPOK);
     
     	/* initialise our SX-lock */
    -	sx_init(udev->default_sx + 1, "0123456789ABCDEF - USB config SX lock" + depth);
    +	sx_init_flags(udev->default_sx + 1, "USB config SX lock", SX_DUPOK);
     
     	cv_init(udev->default_cv, "WCTRL");
     	cv_init(udev->default_cv + 1, "UGONE");
    
    From c955f3622916421fc5daf7ef3f4fe4fe86c940b7 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Thu, 29 Apr 2010 22:48:19 +0000
    Subject: [PATCH 2142/2592] MFC r207079
    
     Properly name the sxlocks, mutexes and condvars.
    ---
     sys/dev/usb/usb_dev.c      |  8 ++++----
     sys/dev/usb/usb_device.c   | 38 +++++++++++++++++++-------------------
     sys/dev/usb/usb_device.h   |  8 +++++---
     sys/dev/usb/usb_request.c  |  8 ++++----
     sys/dev/usb/usb_transfer.c |  2 +-
     5 files changed, 33 insertions(+), 31 deletions(-)
    
    diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c
    index dffabad29b9..a696a2652be 100644
    --- a/sys/dev/usb/usb_dev.c
    +++ b/sys/dev/usb/usb_dev.c
    @@ -284,7 +284,7 @@ error:
     		usbd_enum_unlock(cpd->udev);
     
     		if (--(cpd->udev->refcount) == 0) {
    -			cv_signal(cpd->udev->default_cv + 1);
    +			cv_signal(&cpd->udev->ref_cv);
     		}
     	}
     	mtx_unlock(&usb_ref_lock);
    @@ -352,7 +352,7 @@ usb_unref_device(struct usb_cdev_privdata *cpd,
     	}
     	if (crd->is_uref) {
     		if (--(cpd->udev->refcount) == 0) {
    -			cv_signal(cpd->udev->default_cv + 1);
    +			cv_signal(&cpd->udev->ref_cv);
     		}
     		crd->is_uref = 0;
     	}
    @@ -500,7 +500,7 @@ usb_fifo_create(struct usb_cdev_privdata *cpd,
     		/* update some fields */
     		f->fifo_index = n + USB_FIFO_TX;
     		f->dev_ep_index = e;
    -		f->priv_mtx = udev->default_mtx;
    +		f->priv_mtx = &udev->device_mtx;
     		f->priv_sc0 = ep;
     		f->methods = &usb_ugen_methods;
     		f->iface_index = ep->iface_index;
    @@ -527,7 +527,7 @@ usb_fifo_create(struct usb_cdev_privdata *cpd,
     		/* update some fields */
     		f->fifo_index = n + USB_FIFO_RX;
     		f->dev_ep_index = e;
    -		f->priv_mtx = udev->default_mtx;
    +		f->priv_mtx = &udev->device_mtx;
     		f->priv_sc0 = ep;
     		f->methods = &usb_ugen_methods;
     		f->iface_index = ep->iface_index;
    diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
    index bc386474907..98fbb908bdd 100644
    --- a/sys/dev/usb/usb_device.c
    +++ b/sys/dev/usb/usb_device.c
    @@ -655,7 +655,7 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd)
     		goto cleanup;
     
     	if (cmd == USB_CFG_INIT) {
    -		sx_assert(udev->default_sx + 1, SA_LOCKED);
    +		sx_assert(&udev->enum_sx, SA_LOCKED);
     
     		/* check for in-use endpoints */
     
    @@ -1062,7 +1062,7 @@ usb_detach_device(struct usb_device *udev, uint8_t iface_index,
     	}
     	DPRINTFN(4, "udev=%p\n", udev);
     
    -	sx_assert(udev->default_sx + 1, SA_LOCKED);
    +	sx_assert(&udev->enum_sx, SA_LOCKED);
     
     	/*
     	 * First detach the child to give the child's detach routine a
    @@ -1380,7 +1380,7 @@ usb_suspend_resume(struct usb_device *udev, uint8_t do_suspend)
     	}
     	DPRINTFN(4, "udev=%p do_suspend=%d\n", udev, do_suspend);
     
    -	sx_assert(udev->default_sx + 1, SA_LOCKED);
    +	sx_assert(&udev->enum_sx, SA_LOCKED);
     
     	USB_BUS_LOCK(udev->bus);
     	/* filter the suspend events */
    @@ -1419,13 +1419,13 @@ usbd_clear_stall_proc(struct usb_proc_msg *_pm)
     
     	/* Change lock */
     	USB_BUS_UNLOCK(udev->bus);
    -	mtx_lock(udev->default_mtx);
    +	mtx_lock(&udev->device_mtx);
     
     	/* Start clear stall callback */
     	usbd_transfer_start(udev->default_xfer[1]);
     
     	/* Change lock */
    -	mtx_unlock(udev->default_mtx);
    +	mtx_unlock(&udev->device_mtx);
     	USB_BUS_LOCK(udev->bus);
     }
     
    @@ -1491,16 +1491,16 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
     		return (NULL);
     	}
     	/* initialise our SX-lock */
    -	sx_init_flags(udev->default_sx, "USB device SX lock", SX_DUPOK);
    +	sx_init_flags(&udev->ctrl_sx, "USB device SX lock", SX_DUPOK);
     
     	/* initialise our SX-lock */
    -	sx_init_flags(udev->default_sx + 1, "USB config SX lock", SX_DUPOK);
    +	sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK);
     
    -	cv_init(udev->default_cv, "WCTRL");
    -	cv_init(udev->default_cv + 1, "UGONE");
    +	cv_init(&udev->ctrlreq_cv, "WCTRL");
    +	cv_init(&udev->ref_cv, "UGONE");
     
     	/* initialise our mutex */
    -	mtx_init(udev->default_mtx, "USB device mutex", NULL, MTX_DEF);
    +	mtx_init(&udev->device_mtx, "USB device mutex", NULL, MTX_DEF);
     
     	/* initialise generic clear stall */
     	udev->cs_msg[0].hdr.pm_callback = &usbd_clear_stall_proc;
    @@ -2005,7 +2005,7 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
     	mtx_lock(&usb_ref_lock);
     	udev->refcount--;
     	while (udev->refcount != 0) {
    -		cv_wait(udev->default_cv + 1, &usb_ref_lock);
    +		cv_wait(&udev->ref_cv, &usb_ref_lock);
     	}
     	mtx_unlock(&usb_ref_lock);
     
    @@ -2036,13 +2036,13 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
     	    &udev->cs_msg[0], &udev->cs_msg[1]);
     	USB_BUS_UNLOCK(udev->bus);
     
    -	sx_destroy(udev->default_sx);
    -	sx_destroy(udev->default_sx + 1);
    +	sx_destroy(&udev->ctrl_sx);
    +	sx_destroy(&udev->enum_sx);
     
    -	cv_destroy(udev->default_cv);
    -	cv_destroy(udev->default_cv + 1);
    +	cv_destroy(&udev->ctrlreq_cv);
    +	cv_destroy(&udev->ref_cv);
     
    -	mtx_destroy(udev->default_mtx);
    +	mtx_destroy(&udev->device_mtx);
     #if USB_HAVE_UGEN
     	KASSERT(LIST_FIRST(&udev->pd_list) == NULL, ("leaked cdev entries"));
     #endif
    @@ -2588,7 +2588,7 @@ usbd_device_attached(struct usb_device *udev)
     void
     usbd_enum_lock(struct usb_device *udev)
     {
    -	sx_xlock(udev->default_sx + 1);
    +	sx_xlock(&udev->enum_sx);
     	/* 
     	 * NEWBUS LOCK NOTE: We should check if any parent SX locks
     	 * are locked before locking Giant. Else the lock can be
    @@ -2603,7 +2603,7 @@ void
     usbd_enum_unlock(struct usb_device *udev)
     {
     	mtx_unlock(&Giant);
    -	sx_xunlock(udev->default_sx + 1);
    +	sx_xunlock(&udev->enum_sx);
     }
     
     /*
    @@ -2614,5 +2614,5 @@ usbd_enum_unlock(struct usb_device *udev)
     uint8_t
     usbd_enum_is_locked(struct usb_device *udev)
     {
    -	return (sx_xlocked(udev->default_sx + 1));
    +	return (sx_xlocked(&udev->enum_sx));
     }
    diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h
    index 3afdecf3ae9..f497949f09c 100644
    --- a/sys/dev/usb/usb_device.h
    +++ b/sys/dev/usb/usb_device.h
    @@ -113,9 +113,11 @@ struct usb_power_save {
     struct usb_device {
     	struct usb_clear_stall_msg cs_msg[2];	/* generic clear stall
     						 * messages */
    -	struct sx default_sx[2];
    -	struct mtx default_mtx[1];
    -	struct cv default_cv[2];
    +	struct sx ctrl_sx;
    +	struct sx enum_sx;
    +	struct mtx device_mtx;
    +	struct cv ctrlreq_cv;
    +	struct cv ref_cv;
     	struct usb_interface *ifaces;
     	struct usb_endpoint default_ep;	/* Control Endpoint 0 */
     	struct usb_endpoint *endpoints;
    diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
    index 32c57788773..a5ae56babee 100644
    --- a/sys/dev/usb/usb_request.c
    +++ b/sys/dev/usb/usb_request.c
    @@ -99,7 +99,7 @@ usbd_do_request_callback(struct usb_xfer *xfer, usb_error_t error)
     		usbd_transfer_submit(xfer);
     		break;
     	default:
    -		cv_signal(xfer->xroot->udev->default_cv);
    +		cv_signal(&xfer->xroot->udev->ctrlreq_cv);
     		break;
     	}
     }
    @@ -319,7 +319,7 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
     	 * is achieved when multiple threads are involved:
     	 */
     
    -	sx_xlock(udev->default_sx);
    +	sx_xlock(&udev->ctrl_sx);
     
     	hr_func = usbd_get_hr_func(udev);
     
    @@ -457,7 +457,7 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
     		usbd_transfer_start(xfer);
     
     		while (usbd_transfer_pending(xfer)) {
    -			cv_wait(udev->default_cv,
    +			cv_wait(&udev->ctrlreq_cv,
     			    xfer->xroot->xfer_mtx);
     		}
     
    @@ -534,7 +534,7 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
     	USB_XFER_UNLOCK(xfer);
     
     done:
    -	sx_xunlock(udev->default_sx);
    +	sx_xunlock(&udev->ctrl_sx);
     
     	if (mtx) {
     		mtx_lock(mtx);
    diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c
    index dc39fc64b8e..ce32f72e6d3 100644
    --- a/sys/dev/usb/usb_transfer.c
    +++ b/sys/dev/usb/usb_transfer.c
    @@ -2821,7 +2821,7 @@ repeat:
     	iface_index = 0;
     	if (usbd_transfer_setup(udev, &iface_index,
     	    udev->default_xfer, usb_control_ep_cfg, USB_DEFAULT_XFER_MAX, NULL,
    -	    udev->default_mtx)) {
    +	    &udev->device_mtx)) {
     		DPRINTFN(0, "could not setup default "
     		    "USB transfer\n");
     	} else {
    
    From 31f57dc12e6576d20efb7288f5cf8f3059337384 Mon Sep 17 00:00:00 2001
    From: Andrew Thompson 
    Date: Thu, 29 Apr 2010 22:49:21 +0000
    Subject: [PATCH 2143/2592] MFC r207080
    
     Use a more obvious prefix for the USB control (endpoint 0) transfers rather
     than default_*.
    ---
     sys/dev/usb/usb_compat_linux.c |  2 +-
     sys/dev/usb/usb_dev.c          |  2 +-
     sys/dev/usb/usb_device.c       | 46 +++++++++++++++++-----------------
     sys/dev/usb/usb_device.h       | 10 ++++----
     sys/dev/usb/usb_generic.c      | 18 ++++++-------
     sys/dev/usb/usb_hub.c          |  2 +-
     sys/dev/usb/usb_request.c      |  4 +--
     sys/dev/usb/usb_transfer.c     | 24 +++++++++---------
     sys/dev/usb/usb_transfer.h     |  2 +-
     9 files changed, 55 insertions(+), 55 deletions(-)
    
    diff --git a/sys/dev/usb/usb_compat_linux.c b/sys/dev/usb/usb_compat_linux.c
    index fc28a1c5060..89aaa8f7aac 100644
    --- a/sys/dev/usb/usb_compat_linux.c
    +++ b/sys/dev/usb/usb_compat_linux.c
    @@ -971,7 +971,7 @@ usb_linux_create_usb_device(struct usb_device *udev, device_t dev)
     			udev->devnum = device_get_unit(dev);
     			bcopy(&udev->ddesc, &udev->descriptor,
     			    sizeof(udev->descriptor));
    -			bcopy(udev->default_ep.edesc, &udev->ep0.desc,
    +			bcopy(udev->ctrl_ep.edesc, &udev->ep0.desc,
     			    sizeof(udev->ep0.desc));
     		}
     	}
    diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c
    index a696a2652be..2ac5b2e4edf 100644
    --- a/sys/dev/usb/usb_dev.c
    +++ b/sys/dev/usb/usb_dev.c
    @@ -615,7 +615,7 @@ usb_dev_get_ep(struct usb_device *udev, uint8_t ep_index, uint8_t dir)
     	uint8_t ep_dir;
     
     	if (ep_index == 0) {
    -		ep = &udev->default_ep;
    +		ep = &udev->ctrl_ep;
     	} else {
     		if (dir == USB_FIFO_RX) {
     			if (udev->flags.usb_mode == USB_MODE_HOST) {
    diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
    index 98fbb908bdd..95020de0ac3 100644
    --- a/sys/dev/usb/usb_device.c
    +++ b/sys/dev/usb/usb_device.c
    @@ -179,9 +179,9 @@ usbd_get_ep_by_addr(struct usb_device *udev, uint8_t ea_val)
     	/*
     	 * The default endpoint is always present and is checked separately:
     	 */
    -	if ((udev->default_ep.edesc) &&
    -	    ((udev->default_ep.edesc->bEndpointAddress & EA_MASK) == ea_val)) {
    -		ep = &udev->default_ep;
    +	if ((udev->ctrl_ep.edesc) &&
    +	    ((udev->ctrl_ep.edesc->bEndpointAddress & EA_MASK) == ea_val)) {
    +		ep = &udev->ctrl_ep;
     		goto found;
     	}
     	return (NULL);
    @@ -297,11 +297,11 @@ usbd_get_endpoint(struct usb_device *udev, uint8_t iface_index,
     	 * address" and "any direction" returns the first endpoint of the
     	 * interface. "iface_index" and "direction" is ignored:
     	 */
    -	if ((udev->default_ep.edesc) &&
    -	    ((udev->default_ep.edesc->bEndpointAddress & ea_mask) == ea_val) &&
    -	    ((udev->default_ep.edesc->bmAttributes & type_mask) == type_val) &&
    +	if ((udev->ctrl_ep.edesc) &&
    +	    ((udev->ctrl_ep.edesc->bEndpointAddress & ea_mask) == ea_val) &&
    +	    ((udev->ctrl_ep.edesc->bmAttributes & type_mask) == type_val) &&
     	    (!index)) {
    -		ep = &udev->default_ep;
    +		ep = &udev->ctrl_ep;
     		goto found;
     	}
     	return (NULL);
    @@ -1422,7 +1422,7 @@ usbd_clear_stall_proc(struct usb_proc_msg *_pm)
     	mtx_lock(&udev->device_mtx);
     
     	/* Start clear stall callback */
    -	usbd_transfer_start(udev->default_xfer[1]);
    +	usbd_transfer_start(udev->ctrl_xfer[1]);
     
     	/* Change lock */
     	mtx_unlock(&udev->device_mtx);
    @@ -1529,13 +1529,13 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
     	udev->refcount = 1;
     
     	/* set up default endpoint descriptor */
    -	udev->default_ep_desc.bLength = sizeof(udev->default_ep_desc);
    -	udev->default_ep_desc.bDescriptorType = UDESC_ENDPOINT;
    -	udev->default_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
    -	udev->default_ep_desc.bmAttributes = UE_CONTROL;
    -	udev->default_ep_desc.wMaxPacketSize[0] = USB_MAX_IPACKET;
    -	udev->default_ep_desc.wMaxPacketSize[1] = 0;
    -	udev->default_ep_desc.bInterval = 0;
    +	udev->ctrl_ep_desc.bLength = sizeof(udev->ctrl_ep_desc);
    +	udev->ctrl_ep_desc.bDescriptorType = UDESC_ENDPOINT;
    +	udev->ctrl_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
    +	udev->ctrl_ep_desc.bmAttributes = UE_CONTROL;
    +	udev->ctrl_ep_desc.wMaxPacketSize[0] = USB_MAX_IPACKET;
    +	udev->ctrl_ep_desc.wMaxPacketSize[1] = 0;
    +	udev->ctrl_ep_desc.bInterval = 0;
     	udev->ddesc.bMaxPacketSize = USB_MAX_IPACKET;
     
     	udev->speed = speed;
    @@ -1559,8 +1559,8 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
     
     	/* init the default endpoint */
     	usb_init_endpoint(udev, 0,
    -	    &udev->default_ep_desc,
    -	    &udev->default_ep);
    +	    &udev->ctrl_ep_desc,
    +	    &udev->ctrl_ep);
     
     	/* set device index */
     	udev->device_index = device_index;
    @@ -1573,10 +1573,10 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
     	LIST_INIT(&udev->pd_list);
     
     	/* Create the control endpoint device */
    -	udev->default_dev = usb_make_dev(udev, 0, FREAD|FWRITE);
    +	udev->ctrl_dev = usb_make_dev(udev, 0, FREAD|FWRITE);
     
     	/* Create a link from /dev/ugenX.X to the default endpoint */
    -	make_dev_alias(udev->default_dev, udev->ugen_name);
    +	make_dev_alias(udev->ctrl_dev, udev->ugen_name);
     #endif
     	if (udev->flags.usb_mode == USB_MODE_HOST) {
     
    @@ -2009,20 +2009,20 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
     	}
     	mtx_unlock(&usb_ref_lock);
     
    -	destroy_dev_sched_cb(udev->default_dev, usb_cdev_cleanup,
    -	    udev->default_dev->si_drv1);
    +	destroy_dev_sched_cb(udev->ctrl_dev, usb_cdev_cleanup,
    +	    udev->ctrl_dev->si_drv1);
     #endif
     
     	if (udev->flags.usb_mode == USB_MODE_DEVICE) {
     		/* stop receiving any control transfers (Device Side Mode) */
    -		usbd_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
    +		usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
     	}
     
     	/* the following will get the device unconfigured in software */
     	usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_EP0);
     
     	/* unsetup any leftover default USB transfers */
    -	usbd_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
    +	usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
     
     	/* template unsetup, if any */
     	(usb_temp_unsetup_p) (udev);
    diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h
    index f497949f09c..08b9fd7ef4f 100644
    --- a/sys/dev/usb/usb_device.h
    +++ b/sys/dev/usb/usb_device.h
    @@ -30,7 +30,7 @@
     struct usb_symlink;		/* UGEN */
     struct usb_device;		/* linux compat */
     
    -#define	USB_DEFAULT_XFER_MAX 2
    +#define	USB_CTRL_XFER_MAX 2
     
     /* "usb_parse_config()" commands */
     
    @@ -119,7 +119,7 @@ struct usb_device {
     	struct cv ctrlreq_cv;
     	struct cv ref_cv;
     	struct usb_interface *ifaces;
    -	struct usb_endpoint default_ep;	/* Control Endpoint 0 */
    +	struct usb_endpoint ctrl_ep;	/* Control Endpoint 0 */
     	struct usb_endpoint *endpoints;
     	struct usb_power_save pwr_save;/* power save data */
     	struct usb_bus *bus;		/* our USB BUS */
    @@ -128,13 +128,13 @@ struct usb_device {
     	struct usb_device *parent_hs_hub;	/* high-speed parent HUB */
     	struct usb_config_descriptor *cdesc;	/* full config descr */
     	struct usb_hub *hub;		/* only if this is a hub */
    -	struct usb_xfer *default_xfer[USB_DEFAULT_XFER_MAX];
    +	struct usb_xfer *ctrl_xfer[USB_CTRL_XFER_MAX];
     	struct usb_temp_data *usb_template_ptr;
     	struct usb_endpoint *ep_curr;	/* current clear stall endpoint */
     #if USB_HAVE_UGEN
     	struct usb_fifo *fifo[USB_FIFO_MAX];
     	struct usb_symlink *ugen_symlink;	/* our generic symlink */
    -	struct cdev *default_dev;	/* Control Endpoint 0 device node */
    +	struct cdev *ctrl_dev;	/* Control Endpoint 0 device node */
     	LIST_HEAD(,usb_fs_privdata) pd_list;
     	char	ugen_name[20];		/* name of ugenX.X device */
     #endif
    @@ -166,7 +166,7 @@ struct usb_device {
     
     	struct usb_device_flags flags;
     
    -	struct usb_endpoint_descriptor default_ep_desc;	/* for endpoint 0 */
    +	struct usb_endpoint_descriptor ctrl_ep_desc;	/* for endpoint 0 */
     	struct usb_device_descriptor ddesc;	/* device descriptor */
     
     	char	*serial;		/* serial number */
    diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
    index fb7d5df0fcb..db274683440 100644
    --- a/sys/dev/usb/usb_generic.c
    +++ b/sys/dev/usb/usb_generic.c
    @@ -81,11 +81,11 @@
     
     static usb_callback_t ugen_read_clear_stall_callback;
     static usb_callback_t ugen_write_clear_stall_callback;
    -static usb_callback_t ugen_default_read_callback;
    -static usb_callback_t ugen_default_write_callback;
    +static usb_callback_t ugen_ctrl_read_callback;
    +static usb_callback_t ugen_ctrl_write_callback;
     static usb_callback_t ugen_isoc_read_callback;
     static usb_callback_t ugen_isoc_write_callback;
    -static usb_callback_t ugen_default_fs_callback;
    +static usb_callback_t ugen_ctrl_fs_callback;
     
     static usb_fifo_open_t ugen_open;
     static usb_fifo_close_t ugen_close;
    @@ -265,7 +265,7 @@ ugen_open_pipe_write(struct usb_fifo *f)
     		if (f->flag_short) {
     			usb_config[0].flags.force_short_xfer = 1;
     		}
    -		usb_config[0].callback = &ugen_default_write_callback;
    +		usb_config[0].callback = &ugen_ctrl_write_callback;
     		usb_config[0].timeout = f->timeout;
     		usb_config[0].frames = 1;
     		usb_config[0].bufsize = f->bufsize;
    @@ -335,7 +335,7 @@ ugen_open_pipe_read(struct usb_fifo *f)
     		}
     		usb_config[0].timeout = f->timeout;
     		usb_config[0].frames = 1;
    -		usb_config[0].callback = &ugen_default_read_callback;
    +		usb_config[0].callback = &ugen_ctrl_read_callback;
     		usb_config[0].bufsize = f->bufsize;
     
     		if (ugen_transfer_setup(f, usb_config, 2)) {
    @@ -401,7 +401,7 @@ ugen_stop_io(struct usb_fifo *f)
     }
     
     static void
    -ugen_default_read_callback(struct usb_xfer *xfer, usb_error_t error)
    +ugen_ctrl_read_callback(struct usb_xfer *xfer, usb_error_t error)
     {
     	struct usb_fifo *f = usbd_xfer_softc(xfer);
     	struct usb_mbuf *m;
    @@ -453,7 +453,7 @@ ugen_default_read_callback(struct usb_xfer *xfer, usb_error_t error)
     }
     
     static void
    -ugen_default_write_callback(struct usb_xfer *xfer, usb_error_t error)
    +ugen_ctrl_write_callback(struct usb_xfer *xfer, usb_error_t error)
     {
     	struct usb_fifo *f = usbd_xfer_softc(xfer);
     	usb_frlength_t actlen;
    @@ -1480,7 +1480,7 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
     		usb_config[0].direction = ed->bEndpointAddress & (UE_DIR_OUT | UE_DIR_IN);
     		usb_config[0].interval = USB_DEFAULT_INTERVAL;
     		usb_config[0].flags.proxy_buffer = 1;
    -		usb_config[0].callback = &ugen_default_fs_callback;
    +		usb_config[0].callback = &ugen_ctrl_fs_callback;
     		usb_config[0].timeout = 0;	/* no timeout */
     		usb_config[0].frames = u.popen->max_frames;
     		usb_config[0].bufsize = u.popen->max_bufsize;
    @@ -2201,7 +2201,7 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
     }
     
     static void
    -ugen_default_fs_callback(struct usb_xfer *xfer, usb_error_t error)
    +ugen_ctrl_fs_callback(struct usb_xfer *xfer, usb_error_t error)
     {
     	;				/* workaround for a bug in "indent" */
     
    diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c
    index 97797963269..c31f8fa449c 100644
    --- a/sys/dev/usb/usb_hub.c
    +++ b/sys/dev/usb/usb_hub.c
    @@ -246,7 +246,7 @@ uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up)
     	/* start control transfer, if device mode */
     
     	if (child->flags.usb_mode == USB_MODE_DEVICE) {
    -		usbd_default_transfer_setup(child);
    +		usbd_ctrl_transfer_setup(child);
     	}
     	/* if a HUB becomes present, do a recursive HUB explore */
     
    diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
    index a5ae56babee..6150cb1fa14 100644
    --- a/sys/dev/usb/usb_request.c
    +++ b/sys/dev/usb/usb_request.c
    @@ -374,9 +374,9 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
     	/*
     	 * Setup a new USB transfer or use the existing one, if any:
     	 */
    -	usbd_default_transfer_setup(udev);
    +	usbd_ctrl_transfer_setup(udev);
     
    -	xfer = udev->default_xfer[0];
    +	xfer = udev->ctrl_xfer[0];
     	if (xfer == NULL) {
     		/* most likely out of memory */
     		err = USB_ERR_NOMEM;
    diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c
    index ce32f72e6d3..535d12bfdef 100644
    --- a/sys/dev/usb/usb_transfer.c
    +++ b/sys/dev/usb/usb_transfer.c
    @@ -72,7 +72,7 @@ struct usb_std_packet_size {
     
     static usb_callback_t usb_request_callback;
     
    -static const struct usb_config usb_control_ep_cfg[USB_DEFAULT_XFER_MAX] = {
    +static const struct usb_config usb_control_ep_cfg[USB_CTRL_XFER_MAX] = {
     
     	/* This transfer is used for generic control endpoint transfers */
     
    @@ -2433,8 +2433,8 @@ usbd_pipe_start(struct usb_xfer_queue *pq)
     			if (udev->flags.usb_mode == USB_MODE_DEVICE) {
     				(udev->bus->methods->set_stall) (
     				    udev, NULL, ep, &did_stall);
    -			} else if (udev->default_xfer[1]) {
    -				info = udev->default_xfer[1]->xroot;
    +			} else if (udev->ctrl_xfer[1]) {
    +				info = udev->ctrl_xfer[1]->xroot;
     				usb_proc_msignal(
     				    &info->bus->non_giant_callback_proc,
     				    &udev->cs_msg[0], &udev->cs_msg[1]);
    @@ -2757,13 +2757,13 @@ usb_command_wrapper(struct usb_xfer_queue *pq, struct usb_xfer *xfer)
     }
     
     /*------------------------------------------------------------------------*
    - *	usbd_default_transfer_setup
    + *	usbd_ctrl_transfer_setup
      *
      * This function is used to setup the default USB control endpoint
      * transfer.
      *------------------------------------------------------------------------*/
     void
    -usbd_default_transfer_setup(struct usb_device *udev)
    +usbd_ctrl_transfer_setup(struct usb_device *udev)
     {
     	struct usb_xfer *xfer;
     	uint8_t no_resetup;
    @@ -2774,12 +2774,12 @@ usbd_default_transfer_setup(struct usb_device *udev)
     		return;
     repeat:
     
    -	xfer = udev->default_xfer[0];
    +	xfer = udev->ctrl_xfer[0];
     	if (xfer) {
     		USB_XFER_LOCK(xfer);
     		no_resetup =
     		    ((xfer->address == udev->address) &&
    -		    (udev->default_ep_desc.wMaxPacketSize[0] ==
    +		    (udev->ctrl_ep_desc.wMaxPacketSize[0] ==
     		    udev->ddesc.bMaxPacketSize));
     		if (udev->flags.usb_mode == USB_MODE_DEVICE) {
     			if (no_resetup) {
    @@ -2806,13 +2806,13 @@ repeat:
     	/*
     	 * Update wMaxPacketSize for the default control endpoint:
     	 */
    -	udev->default_ep_desc.wMaxPacketSize[0] =
    +	udev->ctrl_ep_desc.wMaxPacketSize[0] =
     	    udev->ddesc.bMaxPacketSize;
     
     	/*
     	 * Unsetup any existing USB transfer:
     	 */
    -	usbd_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
    +	usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
     
     	/*
     	 * Try to setup a new USB transfer for the
    @@ -2820,7 +2820,7 @@ repeat:
     	 */
     	iface_index = 0;
     	if (usbd_transfer_setup(udev, &iface_index,
    -	    udev->default_xfer, usb_control_ep_cfg, USB_DEFAULT_XFER_MAX, NULL,
    +	    udev->ctrl_xfer, usb_control_ep_cfg, USB_CTRL_XFER_MAX, NULL,
     	    &udev->device_mtx)) {
     		DPRINTFN(0, "could not setup default "
     		    "USB transfer\n");
    @@ -3001,13 +3001,13 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
     		USB_BUS_LOCK(xroot->bus);
     
     		/* check for clear stall */
    -		if (udev->default_xfer[1] != NULL) {
    +		if (udev->ctrl_xfer[1] != NULL) {
     
     			/* poll clear stall start */
     			pm = &udev->cs_msg[0].hdr;
     			(pm->pm_callback) (pm);
     			/* poll clear stall done thread */
    -			pm = &udev->default_xfer[1]->
    +			pm = &udev->ctrl_xfer[1]->
     			    xroot->done_m[0].hdr;
     			(pm->pm_callback) (pm);
     		}
    diff --git a/sys/dev/usb/usb_transfer.h b/sys/dev/usb/usb_transfer.h
    index 27f3afffa63..6e08df09ef8 100644
    --- a/sys/dev/usb/usb_transfer.h
    +++ b/sys/dev/usb/usb_transfer.h
    @@ -123,7 +123,7 @@ void	usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error);
     void	usbd_transfer_enqueue(struct usb_xfer_queue *pq,
     	    struct usb_xfer *xfer);
     void	usbd_transfer_setup_sub(struct usb_setup_params *parm);
    -void	usbd_default_transfer_setup(struct usb_device *udev);
    +void	usbd_ctrl_transfer_setup(struct usb_device *udev);
     void	usbd_clear_data_toggle(struct usb_device *udev,
     	    struct usb_endpoint *ep);
     usb_callback_t usbd_do_request_callback;
    
    From 52d8bf89260e735d46c85c26197da38c0cd78bec Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Thu, 29 Apr 2010 23:48:09 +0000
    Subject: [PATCH 2144/2592] MFC: r207082 When the experimental NFS client is
     handling an NFSv4 server reboot with delegations enabled, the recovery could
     fail if the renew thread is trying to return a delegation, since it will not
     do the recovery. This patch fixes the above by having nfscl_recalldeleg()
     fail with the I/O operations returning EIO, so that they will be attempted
     later. Most of the patch consists of adding an argument to various functions
     to indicate the delegation recall case where this needs to be done.
    
    ---
     sys/fs/nfs/nfs_var.h            |  4 ++--
     sys/fs/nfsclient/nfs.h          |  6 ++++--
     sys/fs/nfsclient/nfs_clbio.c    | 31 +++++++++++++++++----------
     sys/fs/nfsclient/nfs_clnfsiod.c |  6 ++++--
     sys/fs/nfsclient/nfs_clnode.c   |  2 +-
     sys/fs/nfsclient/nfs_clrpcops.c | 16 ++++++++++----
     sys/fs/nfsclient/nfs_clstate.c  | 25 ++++++++++++++++------
     sys/fs/nfsclient/nfs_clvnops.c  | 37 ++++++++++++++++++++++++++-------
     8 files changed, 91 insertions(+), 36 deletions(-)
    
    diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
    index 7df321d1470..f9832e1595f 100644
    --- a/sys/fs/nfs/nfs_var.h
    +++ b/sys/fs/nfs/nfs_var.h
    @@ -371,7 +371,7 @@ int nfsrpc_readlink(vnode_t, struct uio *, struct ucred *,
     int nfsrpc_read(vnode_t, struct uio *, struct ucred *, NFSPROC_T *,
         struct nfsvattr *, int *, void *);
     int nfsrpc_write(vnode_t, struct uio *, int *, u_char *,
    -    struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *);
    +    struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *, int);
     int nfsrpc_mknod(vnode_t, char *, int, struct vattr *, u_int32_t,
         enum vtype, struct ucred *, NFSPROC_T *, struct nfsvattr *,
         struct nfsvattr *, struct nfsfh **, int *, int *, void *);
    @@ -504,7 +504,7 @@ int nfscl_maperr(NFSPROC_T *, int, uid_t, gid_t);
     void nfscl_init(void);
     
     /* nfs_clbio.c */
    -int ncl_flush(vnode_t, int, struct ucred *, NFSPROC_T *, int);
    +int ncl_flush(vnode_t, int, struct ucred *, NFSPROC_T *, int, int);
     
     /* nfs_clnode.c */
     void ncl_invalcaches(vnode_t);
    diff --git a/sys/fs/nfsclient/nfs.h b/sys/fs/nfsclient/nfs.h
    index 4b542869d62..c6071aface4 100644
    --- a/sys/fs/nfsclient/nfs.h
    +++ b/sys/fs/nfsclient/nfs.h
    @@ -79,14 +79,16 @@ int ncl_biowrite(struct vnode *, struct uio *, int, struct ucred *);
     int ncl_vinvalbuf(struct vnode *, int, struct thread *, int);
     int ncl_asyncio(struct nfsmount *, struct buf *, struct ucred *,
         struct thread *);
    -int ncl_doio(struct vnode *, struct buf *, struct ucred *, struct thread *);
    +int ncl_doio(struct vnode *, struct buf *, struct ucred *, struct thread *,
    +    int);
     void ncl_nhinit(void);
     void ncl_nhuninit(void);
     void ncl_nodelock(struct nfsnode *);
     void ncl_nodeunlock(struct nfsnode *);
     int ncl_getattrcache(struct vnode *, struct vattr *);
     int ncl_readrpc(struct vnode *, struct uio *, struct ucred *);
    -int ncl_writerpc(struct vnode *, struct uio *, struct ucred *, int *, int *);
    +int ncl_writerpc(struct vnode *, struct uio *, struct ucred *, int *, int *,
    +    int);
     int ncl_readlinkrpc(struct vnode *, struct uio *, struct ucred *);
     int ncl_readdirrpc(struct vnode *, struct uio *, struct ucred *,
         struct thread *);
    diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c
    index d0dd2cc2e9f..2401c887be7 100644
    --- a/sys/fs/nfsclient/nfs_clbio.c
    +++ b/sys/fs/nfsclient/nfs_clbio.c
    @@ -336,7 +336,7 @@ ncl_putpages(struct vop_putpages_args *ap)
     	else
     	    iomode = NFSWRITE_FILESYNC;
     
    -	error = ncl_writerpc(vp, &uio, cred, &iomode, &must_commit);
    +	error = ncl_writerpc(vp, &uio, cred, &iomode, &must_commit, 0);
     
     	pmap_qremove(kva, npages);
     	relpbuf(bp, &ncl_pbuf_freecnt);
    @@ -554,7 +554,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
     		if ((bp->b_flags & B_CACHE) == 0) {
     		    bp->b_iocmd = BIO_READ;
     		    vfs_busy_pages(bp, 0);
    -		    error = ncl_doio(vp, bp, cred, td);
    +		    error = ncl_doio(vp, bp, cred, td, 0);
     		    if (error) {
     			brelse(bp);
     			return (error);
    @@ -583,7 +583,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
     		if ((bp->b_flags & B_CACHE) == 0) {
     		    bp->b_iocmd = BIO_READ;
     		    vfs_busy_pages(bp, 0);
    -		    error = ncl_doio(vp, bp, cred, td);
    +		    error = ncl_doio(vp, bp, cred, td, 0);
     		    if (error) {
     			bp->b_ioflags |= BIO_ERROR;
     			brelse(bp);
    @@ -609,7 +609,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
     		if ((bp->b_flags & B_CACHE) == 0) {
     		    bp->b_iocmd = BIO_READ;
     		    vfs_busy_pages(bp, 0);
    -		    error = ncl_doio(vp, bp, cred, td);
    +		    error = ncl_doio(vp, bp, cred, td, 0);
     		    if (error) {
     			    brelse(bp);
     		    }
    @@ -638,7 +638,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
     			    if ((bp->b_flags & B_CACHE) == 0) {
     				    bp->b_iocmd = BIO_READ;
     				    vfs_busy_pages(bp, 0);
    -				    error = ncl_doio(vp, bp, cred, td);
    +				    error = ncl_doio(vp, bp, cred, td, 0);
     				    /*
     				     * no error + B_INVAL == directory EOF,
     				     * use the block.
    @@ -771,7 +771,7 @@ do_sync:
     			uio.uio_td = td;
     			iomode = NFSWRITE_FILESYNC;
     			error = ncl_writerpc(vp, &uio, cred, &iomode,
    -			    &must_commit);
    +			    &must_commit, 0);
     			KASSERT((must_commit == 0), 
     				("ncl_directio_write: Did not commit write"));
     			if (error)
    @@ -1122,7 +1122,7 @@ again:
     		if ((bp->b_flags & B_CACHE) == 0) {
     			bp->b_iocmd = BIO_READ;
     			vfs_busy_pages(bp, 0);
    -			error = ncl_doio(vp, bp, cred, td);
    +			error = ncl_doio(vp, bp, cred, td, 0);
     			if (error) {
     				brelse(bp);
     				break;
    @@ -1523,7 +1523,7 @@ ncl_doio_directwrite(struct buf *bp)
     	
     	iomode = NFSWRITE_FILESYNC;
     	uiop->uio_td = NULL; /* NULL since we're in nfsiod */
    -	ncl_writerpc(bp->b_vp, uiop, bp->b_wcred, &iomode, &must_commit);
    +	ncl_writerpc(bp->b_vp, uiop, bp->b_wcred, &iomode, &must_commit, 0);
     	KASSERT((must_commit == 0), ("ncl_doio_directwrite: Did not commit write"));
     	free(iov_base, M_NFSDIRECTIO);
     	free(uiop->uio_iov, M_NFSDIRECTIO);
    @@ -1550,7 +1550,8 @@ ncl_doio_directwrite(struct buf *bp)
      * synchronously or from an nfsiod.
      */
     int
    -ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
    +ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td,
    +    int called_from_strategy)
     {
     	struct uio *uiop;
     	struct nfsnode *np;
    @@ -1695,7 +1696,8 @@ ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
     		else
     		    iomode = NFSWRITE_FILESYNC;
     
    -		error = ncl_writerpc(vp, uiop, cr, &iomode, &must_commit);
    +		error = ncl_writerpc(vp, uiop, cr, &iomode, &must_commit,
    +		    called_from_strategy);
     
     		/*
     		 * When setting B_NEEDCOMMIT also set B_CLUSTEROK to try
    @@ -1732,6 +1734,12 @@ ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
     		 * the block is reused. This is indicated by setting
     		 * the B_DELWRI and B_NEEDCOMMIT flags.
     		 *
    +		 * EIO is returned by ncl_writerpc() to indicate a recoverable
    +		 * write error and is handled as above, except that
    +		 * B_EINTR isn't set. One cause of this is a stale stateid
    +		 * error for the RPC that indicates recovery is required,
    +		 * when called with called_from_strategy != 0.
    +		 *
     		 * If the buffer is marked B_PAGING, it does not reside on
     		 * the vp's paging queues so we cannot call bdirty().  The
     		 * bp in this case is not an NFS cache block so we should
    @@ -1760,7 +1768,8 @@ ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
     			    bdirty(bp);
     			    bp->b_flags &= ~B_DONE;
     			}
    -			if (error && (bp->b_flags & B_ASYNC) == 0)
    +			if ((error == EINTR || error == ETIMEDOUT) &&
    +			    (bp->b_flags & B_ASYNC) == 0)
     			    bp->b_flags |= B_EINTR;
     			splx(s);
     	    	} else {
    diff --git a/sys/fs/nfsclient/nfs_clnfsiod.c b/sys/fs/nfsclient/nfs_clnfsiod.c
    index 6649fc032a3..62ea4f8fd4e 100644
    --- a/sys/fs/nfsclient/nfs_clnfsiod.c
    +++ b/sys/fs/nfsclient/nfs_clnfsiod.c
    @@ -278,9 +278,11 @@ nfssvc_iod(void *instance)
     			(void)ncl_doio_directwrite(bp);
     		} else {
     			if (bp->b_iocmd == BIO_READ)
    -				(void) ncl_doio(bp->b_vp, bp, bp->b_rcred, NULL);
    +				(void) ncl_doio(bp->b_vp, bp, bp->b_rcred,
    +				    NULL, 0);
     			else
    -				(void) ncl_doio(bp->b_vp, bp, bp->b_wcred, NULL);
    +				(void) ncl_doio(bp->b_vp, bp, bp->b_wcred,
    +				    NULL, 0);
     		}
     		mtx_lock(&ncl_iod_mutex);
     		/*
    diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c
    index 6b2aa7a5f2a..c1337427fd2 100644
    --- a/sys/fs/nfsclient/nfs_clnode.c
    +++ b/sys/fs/nfsclient/nfs_clnode.c
    @@ -199,7 +199,7 @@ ncl_inactive(struct vop_inactive_args *ap)
     		 * available for the writes.
     		 */
     		if (nfscl_mustflush(vp))
    -			(void) ncl_flush(vp, MNT_WAIT, NULL, ap->a_td, 1);
    +			(void) ncl_flush(vp, MNT_WAIT, NULL, ap->a_td, 1, 0);
     		(void) nfsrpc_close(vp, 1, ap->a_td);
     	}
     
    diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
    index 9b7b8dfa67e..edd47db510d 100644
    --- a/sys/fs/nfsclient/nfs_clrpcops.c
    +++ b/sys/fs/nfsclient/nfs_clrpcops.c
    @@ -1353,11 +1353,16 @@ nfsmout:
     
     /*
      * nfs write operation
    + * When called_from_strategy != 0, it should return EIO for an error that
    + * indicates recovery is in progress, so that the buffer will be left
    + * dirty and be written back to the server later. If it loops around,
    + * the recovery thread could get stuck waiting for the buffer and recovery
    + * will then deadlock.
      */
     APPLESTATIC int
     nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp,
         struct ucred *cred, NFSPROC_T *p, struct nfsvattr *nap, int *attrflagp,
    -    void *stuff)
    +    void *stuff, int called_from_strategy)
     {
     	int error, expireret = 0, retrycnt, nostateid;
     	u_int32_t clidrev = 0;
    @@ -1417,12 +1422,15 @@ nfscl_dumpstate(nmp, 1, 1, 0, 0);
     			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
     		}
     		retrycnt++;
    -	} while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
    -	    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
    +	} while (error == NFSERR_GRACE || error == NFSERR_DELAY ||
    +	    ((error == NFSERR_STALESTATEID ||
    +	      error == NFSERR_STALEDONTRECOVER) && called_from_strategy == 0) ||
     	    (error == NFSERR_OLDSTATEID && retrycnt < 20) ||
     	    ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) &&
     	     expireret == 0 && clidrev != 0 && retrycnt < 4));
    -	if (error && retrycnt >= 4)
    +	if (error != 0 && (retrycnt >= 4 ||
    +	    ((error == NFSERR_STALESTATEID ||
    +	      error == NFSERR_STALEDONTRECOVER) && called_from_strategy != 0)))
     		error = EIO;
     	if (NFSHASNFSV4(nmp) && p == NULL)
     		NFSFREECRED(newcred);
    diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
    index 78b596640cf..cf8c922ae43 100644
    --- a/sys/fs/nfsclient/nfs_clstate.c
    +++ b/sys/fs/nfsclient/nfs_clstate.c
    @@ -139,7 +139,7 @@ static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *);
     static int nfscl_errmap(struct nfsrv_descript *);
     static void nfscl_cleanup_common(struct nfsclclient *, u_int8_t *);
     static int nfscl_recalldeleg(struct nfsclclient *, struct nfsmount *,
    -    struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *);
    +    struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *, int);
     static void nfscl_freeopenowner(struct nfsclowner *, int);
     static void nfscl_cleandeleg(struct nfscldeleg *);
     static int nfscl_trydelegreturn(struct nfscldeleg *, struct ucred *,
    @@ -2469,7 +2469,7 @@ tryagain:
     				NFSUNLOCKCLSTATE();
     				newnfs_copycred(&dp->nfsdl_cred, cred);
     				ret = nfscl_recalldeleg(clp, clp->nfsc_nmp, dp,
    -				    NULL, cred, p);
    +				    NULL, cred, p, 1);
     				if (!ret) {
     				    nfscl_cleandeleg(dp);
     				    TAILQ_REMOVE(&clp->nfsc_deleg, dp,
    @@ -3309,7 +3309,8 @@ nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off,
      */
     static int
     nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
    -    struct nfscldeleg *dp, vnode_t vp, struct ucred *cred, NFSPROC_T *p)
    +    struct nfscldeleg *dp, vnode_t vp, struct ucred *cred, NFSPROC_T *p,
    +    int called_from_renewthread)
     {
     	struct nfsclowner *owp, *lowp, *nowp;
     	struct nfsclopen *op, *lop;
    @@ -3343,6 +3344,7 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
     	 * Ok, if it's a write delegation, flush data to the server, so
     	 * that close/open consistency is retained.
     	 */
    +	ret = 0;
     	NFSLOCKNODE(np);
     	if ((dp->nfsdl_flags & NFSCLDL_WRITE) && (np->n_flag & NMODIFIED)) {
     #ifdef APPLE
    @@ -3351,7 +3353,8 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
     		np->n_flag |= NDELEGRECALL;
     #endif
     		NFSUNLOCKNODE(np);
    -		(void) ncl_flush(vp, MNT_WAIT, cred, p, 1);
    +		ret = ncl_flush(vp, MNT_WAIT, cred, p, 1,
    +		    called_from_renewthread);
     		NFSLOCKNODE(np);
     #ifdef APPLE
     		OSBitAndAtomic((int32_t)~(NMODIFIED | NDELEGRECALL), (UInt32 *)&np->n_flag);
    @@ -3360,6 +3363,16 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
     #endif
     	}
     	NFSUNLOCKNODE(np);
    +	if (ret == EIO && called_from_renewthread != 0) {
    +		/*
    +		 * If the flush failed with EIO for the renew thread,
    +		 * return now, so that the dirty buffer will be flushed
    +		 * later.
    +		 */
    +		if (gotvp != 0)
    +			vrele(vp);
    +		return (ret);
    +	}
     
     	/*
     	 * Now, for each openowner with opens issued locally, move them
    @@ -3857,7 +3870,7 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp)
     			NFSUNLOCKCLSTATE();
     			cred = newnfs_getcred();
     			newnfs_copycred(&dp->nfsdl_cred, cred);
    -			(void) nfscl_recalldeleg(clp, nmp, dp, vp, cred, p);
    +			(void) nfscl_recalldeleg(clp, nmp, dp, vp, cred, p, 0);
     			NFSFREECRED(cred);
     			triedrecall = 1;
     			NFSLOCKCLSTATE();
    @@ -3955,7 +3968,7 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
     			NFSUNLOCKCLSTATE();
     			cred = newnfs_getcred();
     			newnfs_copycred(&dp->nfsdl_cred, cred);
    -			(void) nfscl_recalldeleg(clp, nmp, dp, fvp, cred, p);
    +			(void) nfscl_recalldeleg(clp, nmp, dp, fvp, cred, p, 0);
     			NFSFREECRED(cred);
     			triedrecall = 1;
     			NFSLOCKCLSTATE();
    diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
    index 2114ba9078b..98108e3fb8f 100644
    --- a/sys/fs/nfsclient/nfs_clvnops.c
    +++ b/sys/fs/nfsclient/nfs_clvnops.c
    @@ -681,13 +681,13 @@ nfs_close(struct vop_close_args *ap)
     		     * traditional vnode locking implemented for Vnode Ops.
     		     */
     		    int cm = newnfs_commit_on_close ? 1 : 0;
    -		    error = ncl_flush(vp, MNT_WAIT, cred, ap->a_td, cm);
    +		    error = ncl_flush(vp, MNT_WAIT, cred, ap->a_td, cm, 0);
     		    /* np->n_flag &= ~NMODIFIED; */
     		} else if (NFS_ISV4(vp)) { 
     			if (nfscl_mustflush(vp)) {
     				int cm = newnfs_commit_on_close ? 1 : 0;
     				error = ncl_flush(vp, MNT_WAIT, cred, ap->a_td,
    -				    cm);
    +				    cm, 0);
     				/*
     				 * as above w.r.t races when clearing
     				 * NMODIFIED.
    @@ -1317,7 +1317,7 @@ ncl_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
      */
     int
     ncl_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
    -	     int *iomode, int *must_commit)
    +    int *iomode, int *must_commit, int called_from_strategy)
     {
     	struct nfsvattr nfsva;
     	int error = 0, attrflag, ret;
    @@ -1326,7 +1326,7 @@ ncl_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
     
     	*must_commit = 0;
     	error = nfsrpc_write(vp, uiop, iomode, verf, cred,
    -	    uiop->uio_td, &nfsva, &attrflag, NULL);
    +	    uiop->uio_td, &nfsva, &attrflag, NULL, called_from_strategy);
     	NFSLOCKMNT(nmp);
     	if (!error && NFSHASWRITEVERF(nmp) &&
     	    NFSBCMP(verf, nmp->nm_verf, NFSX_VERF)) {
    @@ -2473,7 +2473,7 @@ nfs_strategy(struct vop_strategy_args *ap)
     	 */
     	if ((bp->b_flags & B_ASYNC) == 0 ||
     	    ncl_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread))
    -		(void)ncl_doio(ap->a_vp, bp, cr, curthread);
    +		(void) ncl_doio(ap->a_vp, bp, cr, curthread, 1);
     	return (0);
     }
     
    @@ -2484,17 +2484,20 @@ nfs_strategy(struct vop_strategy_args *ap)
     static int
     nfs_fsync(struct vop_fsync_args *ap)
     {
    -	return (ncl_flush(ap->a_vp, ap->a_waitfor, NULL, ap->a_td, 1));
    +	return (ncl_flush(ap->a_vp, ap->a_waitfor, NULL, ap->a_td, 1, 0));
     }
     
     /*
      * Flush all the blocks associated with a vnode.
      * 	Walk through the buffer pool and push any dirty pages
      *	associated with the vnode.
    + * If the called_from_renewthread argument is TRUE, it has been called
    + * from the NFSv4 renew thread and, as such, cannot block indefinitely
    + * waiting for a buffer write to complete.
      */
     int
     ncl_flush(struct vnode *vp, int waitfor, struct ucred *cred, struct thread *td,
    -    int commit)
    +    int commit, int called_from_renewthread)
     {
     	struct nfsnode *np = VTONFS(vp);
     	struct buf *bp;
    @@ -2513,6 +2516,8 @@ ncl_flush(struct vnode *vp, int waitfor, struct ucred *cred, struct thread *td,
     	struct buf *bvec_on_stack[NFS_COMMITBVECSIZ];
     	int bvecsize = 0, bveccount;
     
    +	if (called_from_renewthread != 0)
    +		slptimeo = hz;
     	if (nmp->nm_flag & NFSMNT_INT)
     		slpflag = NFS_PCATCH;
     	if (!commit)
    @@ -2708,6 +2713,14 @@ loop:
     				error = 0;
     				goto loop;
     			}
    +			if (called_from_renewthread != 0) {
    +				/*
    +				 * Return EIO so the flush will be retried
    +				 * later.
    +				 */
    +				error = EIO;
    +				goto done;
    +			}
     			if (newnfs_sigintr(nmp, td)) {
     				error = EINTR;
     				goto done;
    @@ -2747,6 +2760,14 @@ loop:
     			error = bufobj_wwait(bo, slpflag, slptimeo);
     			if (error) {
     			    BO_UNLOCK(bo);
    +			    if (called_from_renewthread != 0) {
    +				/*
    +				 * Return EIO so that the flush will be
    +				 * retried later.
    +				 */
    +				error = EIO;
    +				goto done;
    +			    }
     			    error = newnfs_sigintr(nmp, td);
     			    if (error)
     				goto done;
    @@ -2838,7 +2859,7 @@ nfs_advlock(struct vop_advlock_args *ap)
     		 */
     		if (ap->a_op == F_UNLCK &&
     		    nfscl_checkwritelocked(vp, ap->a_fl, cred, td))
    -			(void) ncl_flush(vp, MNT_WAIT, cred, td, 1);
    +			(void) ncl_flush(vp, MNT_WAIT, cred, td, 1, 0);
     
     		/*
     		 * Loop around doing the lock op, while a blocking lock
    
    From 4ac642e5506bea99cacad46707641a39af201238 Mon Sep 17 00:00:00 2001
    From: Bernhard Schmidt 
    Date: Fri, 30 Apr 2010 17:08:27 +0000
    Subject: [PATCH 2145/2592] MFC r206763-206767:
    
    r206763:
    Fix comment about ipw_assoc and remove some whitespaces; no functional
    changes.
    
    r206764:
    Pass correct RSSI to ieee80211_input*().
    
    r206765:
    - Make ipw usable again by moving directly into ASSOC state.
    - No need to manually switch to RUN state, assoc response takes care
      of that.
    
    r206766:
    Use iv_appie_wpa, with this commit WPA works again.
    
    r206767:
    Remove IPW_LOCK_DECL and fix various LORs.
    
    Approved by:	rpaulo (mentor)
    ---
     sys/dev/ipw/if_ipw.c    | 55 +++++++++++++++++++++++------------------
     sys/dev/ipw/if_ipwvar.h | 11 ++-------
     2 files changed, 33 insertions(+), 33 deletions(-)
    
    diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c
    index 0b217583f24..3315d654b1c 100644
    --- a/sys/dev/ipw/if_ipw.c
    +++ b/sys/dev/ipw/if_ipw.c
    @@ -888,10 +888,10 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
     			/*
     			 * XXX when joining an ibss network we are called
     			 * with a SCAN -> RUN transition on scan complete.
    -			 * Use that to call ipw_auth_and_assoc.  On completing
    -			 * the join we are then called again with an
    -			 * AUTH -> RUN transition and we want to do nothing.
    -			 * This is all totally bogus and needs to be redone.
    +			 * Use that to call ipw_assoc.  On completing the
    +			 * join we are then called again with an AUTH -> RUN
    +			 * transition and we want to do nothing.  This is
    +			 * all totally bogus and needs to be redone.
     			 */
     			if (ostate == IEEE80211_S_SCAN)
     				ipw_assoc(ic, vap);
    @@ -904,12 +904,19 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
     		break;
     
     	case IEEE80211_S_AUTH:
    +		/*
    +		 * Move to ASSOC state after the ipw_assoc() call.  Firmware
    +		 * takes care of authentication, after the call we'll receive
    +		 * only an assoc response which would otherwise be discared
    +		 * if we are still in AUTH state.
    +		 */
    +		nstate = IEEE80211_S_ASSOC;
     		ipw_assoc(ic, vap);
     		break;
     
     	case IEEE80211_S_ASSOC:
     		/*
    -		 * If we are not transitioning from AUTH the resend the
    +		 * If we are not transitioning from AUTH then resend the
     		 * association request.
     		 */
     		if (ostate != IEEE80211_S_AUTH)
    @@ -1021,7 +1028,6 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
     		}
     		sc->flags &= ~IPW_FLAG_ASSOCIATING;
     		sc->flags |= IPW_FLAG_ASSOCIATED;
    -		ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
     		break;
     
     	case IPW_STATE_SCANNING:
    @@ -1034,8 +1040,10 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
     		 * we checked the 802.11 layer state.
     		 */
     		if (sc->flags & IPW_FLAG_ASSOCIATED) {
    +			IPW_UNLOCK(sc);
     			/* XXX probably need to issue disassoc to fw */
     			ieee80211_beacon_miss(ic);
    +			IPW_LOCK(sc);
     		}
     		break;
     
    @@ -1054,7 +1062,9 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
     			break;
     		}
     		if (sc->flags & IPW_FLAG_SCANNING) {
    +			IPW_UNLOCK(sc);
     			ieee80211_scan_done(vap);
    +			IPW_LOCK(sc);
     			sc->flags &= ~IPW_FLAG_SCANNING;
     			sc->sc_scan_timer = 0;
     		}
    @@ -1064,13 +1074,16 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
     		DPRINTFN(2, ("Association lost (%s flags 0x%x)\n",
     			IEEESTATE(vap), sc->flags));
     		sc->flags &= ~(IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED);
    -		if (vap->iv_state == IEEE80211_S_RUN)
    +		if (vap->iv_state == IEEE80211_S_RUN) {
    +			IPW_UNLOCK(sc);
     			ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
    +			IPW_LOCK(sc);
    +		}
     		break;
     
     	case IPW_STATE_DISABLED:
     		/* XXX? is this right? */
    -		sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING | 
    +		sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING |
     		    IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED);
     		DPRINTFN(2, ("Firmware disabled (%s flags 0x%x)\n",
     			IEEESTATE(vap), sc->flags));
    @@ -1164,7 +1177,6 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
     	bus_addr_t physaddr;
     	int error;
     	int8_t rssi, nf;
    -	IPW_LOCK_DECL;
     
     	DPRINTFN(5, ("received frame len=%u, rssi=%u\n", le32toh(status->len),
     	    status->rssi));
    @@ -1234,10 +1246,10 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
     	IPW_UNLOCK(sc);
     	ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
     	if (ni != NULL) {
    -		(void) ieee80211_input(ni, m, rssi, nf);
    +		(void) ieee80211_input(ni, m, rssi - nf, nf);
     		ieee80211_free_node(ni);
     	} else
    -		(void) ieee80211_input_all(ic, m, rssi, nf);
    +		(void) ieee80211_input_all(ic, m, rssi - nf, nf);
     	IPW_LOCK(sc);
     
     	bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE);
    @@ -1378,8 +1390,11 @@ ipw_fatal_error_intr(struct ipw_softc *sc)
     	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
     
     	device_printf(sc->sc_dev, "firmware error\n");
    -	if (vap != NULL)
    +	if (vap != NULL) {
    +		IPW_UNLOCK(sc);
     		ieee80211_cancel_scan(vap);
    +		IPW_LOCK(sc);
    +	}
     	ieee80211_runtask(ic, &sc->sc_init_task);
     }
     
    @@ -1388,7 +1403,6 @@ ipw_intr(void *arg)
     {
     	struct ipw_softc *sc = arg;
     	uint32_t r;
    -	IPW_LOCK_DECL;
     
     	IPW_LOCK(sc);
     
    @@ -1718,7 +1732,6 @@ static void
     ipw_start(struct ifnet *ifp)
     {
     	struct ipw_softc *sc = ifp->if_softc;
    -	IPW_LOCK_DECL;
     
     	IPW_LOCK(sc);
     	ipw_start_locked(ifp);
    @@ -1775,7 +1788,9 @@ ipw_watchdog(void *arg)
     			DPRINTFN(3, ("Scan timeout\n"));
     			/* End the scan */
     			if (sc->flags & IPW_FLAG_SCANNING) {
    +				IPW_UNLOCK(sc);
     				ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps));
    +				IPW_LOCK(sc);
     				sc->flags &= ~IPW_FLAG_SCANNING;
     			}
     		}
    @@ -1791,7 +1806,6 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     	struct ieee80211com *ic = ifp->if_l2com;
     	struct ifreq *ifr = (struct ifreq *) data;
     	int error = 0, startall = 0;
    -	IPW_LOCK_DECL;
     
     	switch (cmd) {
     	case SIOCSIFFLAGS:
    @@ -2201,7 +2215,6 @@ ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap)
     	struct ipw_security security;
     	uint32_t data;
     	int error;
    -	IPW_LOCK_DECL;
     
     	IPW_LOCK(sc);
     	error = ipw_disable(sc);
    @@ -2260,8 +2273,8 @@ ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap)
     	if (error != 0)
     		goto done;
     
    -	if (vap->iv_appie_assocreq != NULL) {
    -		struct ieee80211_appie *ie = vap->iv_appie_assocreq;
    +	if (vap->iv_appie_wpa != NULL) {
    +		struct ieee80211_appie *ie = vap->iv_appie_wpa;
     		error = ipw_setwpaie(sc, ie->ie_data, ie->ie_len);
     		if (error != 0)
     			goto done;
    @@ -2291,7 +2304,6 @@ ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap)
     	struct ifnet *ifp = vap->iv_ic->ic_ifp;
     	struct ieee80211_node *ni = vap->iv_bss;
     	struct ipw_softc *sc = ifp->if_softc;
    -	IPW_LOCK_DECL;
     
     	IPW_LOCK(sc);
     	DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":"));
    @@ -2327,7 +2339,6 @@ ipw_init(void *priv)
     	struct ipw_softc *sc = priv;
     	struct ifnet *ifp = sc->sc_ifp;
     	struct ieee80211com *ic = ifp->if_l2com;
    -	IPW_LOCK_DECL;
     
     	IPW_LOCK(sc);
     	ipw_init_locked(sc);
    @@ -2534,7 +2545,6 @@ static void
     ipw_stop(void *priv)
     {
     	struct ipw_softc *sc = priv;
    -	IPW_LOCK_DECL;
     
     	IPW_LOCK(sc);
     	ipw_stop_locked(sc);
    @@ -2661,7 +2671,6 @@ ipw_scan_start(struct ieee80211com *ic)
     {
     	struct ifnet *ifp = ic->ic_ifp;
     	struct ipw_softc *sc = ifp->if_softc;
    -	IPW_LOCK_DECL;
     
     	IPW_LOCK(sc);
     	ipw_scan(sc);
    @@ -2673,7 +2682,6 @@ ipw_set_channel(struct ieee80211com *ic)
     {
     	struct ifnet *ifp = ic->ic_ifp;
     	struct ipw_softc *sc = ifp->if_softc;
    -	IPW_LOCK_DECL;
     
     	IPW_LOCK(sc);
     	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
    @@ -2701,7 +2709,6 @@ ipw_scan_end(struct ieee80211com *ic)
     {
     	struct ifnet *ifp = ic->ic_ifp;
     	struct ipw_softc *sc = ifp->if_softc;
    -	IPW_LOCK_DECL;
     
     	IPW_LOCK(sc);
     	sc->flags &= ~IPW_FLAG_SCANNING;
    diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h
    index 8d9e049ccfb..89702d0c634 100644
    --- a/sys/dev/ipw/if_ipwvar.h
    +++ b/sys/dev/ipw/if_ipwvar.h
    @@ -164,13 +164,6 @@ struct ipw_softc {
      * NB.: This models the only instance of async locking in ipw_init_locked
      *	and must be kept in sync.
      */
    -#define	IPW_LOCK_DECL	int	__waslocked = 0
    -#define IPW_LOCK(sc)	do {				\
    -	if (!(__waslocked = mtx_owned(&(sc)->sc_mtx)))	\
    -		mtx_lock(&sc->sc_mtx);			\
    -} while (0)
    -#define IPW_UNLOCK(sc)	do {				\
    -	if (!__waslocked)				\
    -		mtx_unlock(&sc->sc_mtx);		\
    -} while (0)
    +#define IPW_LOCK(sc)		mtx_lock(&sc->sc_mtx);
    +#define IPW_UNLOCK(sc)		mtx_unlock(&sc->sc_mtx);
     #define IPW_LOCK_ASSERT(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)
    
    From 41d65f69f7cb416aa36edd5ad0e8efe5fde37289 Mon Sep 17 00:00:00 2001
    From: Bernhard Schmidt 
    Date: Fri, 30 Apr 2010 18:13:11 +0000
    Subject: [PATCH 2146/2592] MFC r206443-206446, 206474-206477, 207001
    
    r206443:
    Small whitespace cleanup.
    
    r206444 [1]:
    - Rename bluetooth coexistence flags, no binary change.
    - Enable DC calibration and crystal calibration on Centrino Advanced-N
      6250 parts.
    - Workaround for a HW bug (does not affect 4965AGN) that may sporadically
      affect latency under some rare circumstances. From a similar commit to
      iwlwifi.
    - Update sensitivity settings for 5000 series to workaround a performance
      bug in the DSP (1000 is not affected so we keep the old values for 5000).
    - Update sensitivity settings for 6000 series.
    - Set differential gains on 6250 too (but use a 1.0 factor, not 1.5).
    - Init OFDM sensitivity with min value (which depends on the chip)
      instead of hardcoding it to 90.
    - Read calibration version from ROM and set IWN_GP_DRIVER_CALIB_VER6
      bit on 6x50 if version >= 6.
    
    r206445 [2]:
    iwn4965_set_txpower() uses maxpwr from EEPROM to calculate the power to
    set, it make sense to actually initialize that array.  This fixes some
    issues with 4965 adapters where the TX power is crucial.
    
    This got lost somewhere while merging with the OpenBSD code.
    
    r206446:
    Update firmware for the 6000 series Intel cards to version 9.193.4.1.
    
    r206474:
    Add some missing protoypes.
    
    r206475:
    iwn5000_reset_sched() is not used; #ifdef it.
    
    r206476:
    Hook ieee80211_media_change() to ieee80211_vap_attach().
    
    r206477:
    Declare all functions as static.
    
    r207001 [3]:
    Use correct bus_dma_tag_t for TX frames.
    
    Approved by:	rpaulo (mentor)
    Obtained from:	Openbsd [1], [2]
    Reported by:	Andreas Nilsson  [3]
    ---
     sys/conf/files                                |    2 +-
     sys/contrib/dev/iwn/LICENSE                   |   60 +-
     .../dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu      | 8112 ----------------
     .../dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu      | 8152 +++++++++++++++++
     sys/dev/iwn/if_iwn.c                          |  540 +-
     sys/dev/iwn/if_iwnreg.h                       |   36 +-
     sys/dev/iwn/if_iwnvar.h                       |    3 +-
     sys/modules/iwnfw/iwn6000/Makefile            |    2 +-
     8 files changed, 8506 insertions(+), 8401 deletions(-)
     delete mode 100644 sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu
     create mode 100644 sys/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu
    
    diff --git a/sys/conf/files b/sys/conf/files
    index b08549b9bb3..572eb5f54f1 100644
    --- a/sys/conf/files
    +++ b/sys/conf/files
    @@ -1178,7 +1178,7 @@ iwn6000fw.fwo			optional iwn6000fw | iwnfw		\
     	clean		"iwn6000fw.fwo"
     iwn6000.fw			optional iwn6000fw | iwnfw		\
     	dependency	".PHONY"					\
    -	compile-with	"uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu" \
    +	compile-with	"uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu" \
     	no-obj no-implicit-rule						\
     	clean		"iwn6000.fw"
     dev/ixgb/if_ixgb.c		optional ixgb
    diff --git a/sys/contrib/dev/iwn/LICENSE b/sys/contrib/dev/iwn/LICENSE
    index 74a3f7e5308..82165b8f5f8 100644
    --- a/sys/contrib/dev/iwn/LICENSE
    +++ b/sys/contrib/dev/iwn/LICENSE
    @@ -1,39 +1,39 @@
    -Copyright (c) 2006-2009, Intel Corporation.
    +Copyright (c) 2006-2010, Intel Corporation.
     All rights reserved.
     
    -Redistribution.  Redistribution and use in binary form, without 
    -modification, are permitted provided that the following conditions are 
    +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 
    +* 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 
    +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 
    +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-6000-9.176.4.1.fw.uu b/sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu
    deleted file mode 100644
    index 636a7ba4b26..00000000000
    --- a/sys/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu
    +++ /dev/null
    @@ -1,8112 +0,0 @@
    -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-6000-9.176.4.1.fw.uu
    -AQSwCds9AAAUQwIAAEABAKhBAgAAQAEAAAAAACAggA8AAEAAaSAAAGkgQABpIAAAaSBAACAggA8A
    -AOgAaSAAAGkgQABpIAAAaSBAACAggA8AAHgGaSAAAGkgQABpIAAASiAAAEohAABKIgAASiMAAEok
    -AABKJQAASiYAAEonAABKIAAQSiEAEEoiABBKIwAQSiQAEEolABBKJgAQSicAEEogACBKIQAgSiIA
    -IEojACBKJAAgSiUAIEomACBKJwAgSiAAMEohADAKJIA/gQAAQEEsnDBALJwwQiQcNAoigD+AADBr
    -CiMAN/4PAABKJgBwaSBAAEomAHBKJgBwSiYAcEomAHAAFgBwgABkBEB4ICBAhwAAAAAAAAAAAADh
    -wOHB4cLPcKAAyB8WEAGGz3KAAJh/IKISEAGGIaITEAGGIqIUEAGGI6IVEAGGJKIkEAGGJqLPcZ8A
    -uP9WoYoh/w8SGFiAExhYgBQYWIAVGFiAJBhYgMHCwcHBwCAgQIcMyM9yoADIHw4aGIANyA8aGIAO
    -yBAaGIAPEgE2AcgkeBEaGIAQyC0aGIDgfuHE/BzIvvwcSL7hwOHB4cLhw/wcCLH8HEix/ByIsfwc
    -yLH8HAiy/BxIsvwciLL8HMiy/BwIv2okgBDhxGokwBDhxPHAz3CgANAbFIDPcYAAYAQEIICPz1EE
    -4QChCvIvKQEAz3CAAOQN8CBAAEB42v/RwMHEayTAEMHEaySAEMHEn3QEFAs0BBQKNAQUCTQEFAg0
    -BBQHNAQUBjQEFAU0BBQENMHDwcLBwcHAwcRFLH4QCiZAfsHEaySAFMHEICBAhwzIh7gMGhgwDcib
    -uA0aGDAOyA4aGDAPyIe4DxoYMBDIEBoYMOB+4HjxwAzIlbgMGhgwDcibuA0aGDAPyIq4jbiQuA8a
    -GDDPcIAAHA8YiIHgC/QPyM9xAAC0DKy4DxoYMFYOIAAP2GfYNgsgAYohBgrRwOB+8cDPcIAAsK8A
    -gIYg/oEJ9A/IBSCADwAAANQPGhgwof+KIFUFBgsgAYohRg7o8eB4z3EDAEANz3CgAKggLaDPcYAA
    -jARAgQFqAKHPcKAAOC4FgAQggA/AAAAA13DAAAAACvJI2M9xnwC4/xqhW6Fp2Bi4GaHPcIAAeAgl
    -gCOBIIHHcQAAiBMNA8AJ4HjPcIAAeAidAsAJ4HjxwB4MAAGA4M93gABgBIh1BfKB4AX0AdgC8ADY
    -C6+A4QXygeEF9AHYAvAA2AqvgOIF8oHiBfQB2ALwANgMrwDYz3agAMgfGB4YkAuPgOCKIRAAD/II
    -j4DgC/LPcAMAQA1FHhgQMKYC2BgeGJAC8DGmCo+A4BnyCY+A4Bfyz3ACABRDIB4YkM9wgAAoACEe
    -GJDPcIAAXAQiHhiQGBYAlkUgAAMYHhiQDI+A4AjyGBYAloUgAQQYHhiQgeMH9BgWAJaIuBgeGJDP
    -cIAAMHQAkI7gzCCiggb0GBYAloC4GB4YkIDlGfIA2JS4z3WAAIAEAKVx2Aa4Zg0gAfzZIIXPcAAA
    -TBxaDSABn7kYFgCWhbgYHhiQdQMAAeB4z3Gqqru7z3CfALj/NqA2oDagNqDPcaAAyDsOgYi4DqFp
    -IEAA/vHgePHApcFBwELBDBwAMRAcQDHPcYAAfGw0GcAPMBkADywZwA4oGYAOJBlADs9wgAB8bCAY
    -QAvPcIAAfGwcGAALz3CAAHxsGBjACs9wgAB8bBQYgArPcIAAfGwQGMAIz3CAAHxsDBiACM9wgAB8
    -bAgYQAjPcYAAAGyAGQAIfBnAB3gZgAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZ
    -QAVQGQAFTBnABEgZgAREGUAEQBkABO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlA
    -ARAZAAFjoWogAAPYGQAAaiDAAtQZAABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGog
    -gAC8GQAAaiBAALgZAABqIAAAtBkAAGoggAHMGQAA0NifuM9xnwC4/x2hz3CAAAAAxIBTJcQ1UybF
    -Nde6AebTvsSgUyPABAUmjh/Q/gAA1qEFIIAPsP4AABahGIFTJ841AN2UuBihQMMBwALByXMMFAYw
    -GgggARAUBzDPcKAAtA+8oM9xoADIOy6Bsg/gAH3YMg9AAboLIAGpcAjYANlmCyABmbnPcIAAMHQA
    -kI7gzCCigsoggQ/gAMQxyiEhAJAIYQHPIaEF/QXP//HA1gggAXvYag/gAOHZz3GAAHxsNBnADzAZ
    -AA8sGcAOKBmADiQZQA7PcIAAfGwgGEALz3CAAHxsHBgAC89wgAB8bBgYwArPcIAAfGwUGIAKz3CA
    -AHxsEBjACM9wgAB8bAwYgAjPcIAAfGwIGEAIz3GAAABsgBkACHwZwAd4GYAHdBlAB3AZAAdsGQAH
    -aBmABmQZQAZgGQAGXBnABVgZgAVUGUAFUBkABUwZwARIGYAERBlABEAZAATvoc6hraGMoSwZwAIo
    -GYACJBlAAiAZAAIcGcABGBmAARQZQAEQGQABY6FqIAAD2BkAAGogwALUGQAAaiCAAtAZAABqIEAB
    -yBkAAGogAAHEGQAAaiDAAMAZAABqIIAAvBkAAGogQAC4GQAAaiAAALQZAABqIIABzBkAAOt2z3Wg
    -AMgfGRURls9wAABEHCoIYAEKIMAvWnDPcIAAHCkjgM9znwC4/893gAAAAASHgOEB4NO4JPIZFQKW
    -USLAgB7yXYNA3p++3aMEpwUggA/Q/gAAFqNYG4AHIRUAliIVAJYEIYEP/wD8/wCBFqMI2BkdGJBW
    -o12jaQfAANDZn7k9owSnBSCAD9D+AAAWo89wgACABACACyCAhAjyWBuABPYKQAIM2C7wjCEEoCfy
    -jCEBoCPyQiFBII/hRgANADMmQXCAAABUQCeAcjR4AHhKIUAgDdgW8EohgCAE2BLwE9hKIQAhDvBK
    -IQAiFNgK8EohACQV2AbwFtgE8BfYAvAP2M9zgACQDHCDCnHJcgokQATdA+//CiWABC0Cz//xwF4N
    -wAB12BoN4ACKIQoDwgwAAP4PgAJb/qIIAAAKIcAP63IG2IojSgdKJAAApQPv/wolAAHgeIDh8cAD
    -8qDgi/YKIcAP63IF2OPbSiRAAIED7/+4c89ygADkDRV6IKLRwOB+ANmeuRl5z3KAANwNAYIleOB/
    -AaIA2Z65GXnPcoAA3A0BgiZ44H8BogDZnrkZec9wgADcDQGAJHhCIACA4H/KIGIA4HjPcIAA3A0B
    -gOB/LygBAOB48cDiD4//4HjgeOB44HhpIIABbyE/AGkgAAD38fHAathKDOAAiiHEBQDYjbgKCuAD
    -ChoYMBTMhiD/ignyz3CAACkFAIiA4AwPwgOw8fHAMg/AA89xgACQCPAhAABAeM9woADQG4DaUKDP
    -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
    -CwUkRAP1B+/+BSbFEwDFQCAOBs93gABYslQYWAOEH0ATIfDPcIAAZLUGkBBzCvTPd4AAWLLEFwAW
    -wLgQdg3yCiHAD+tyBdiKI50NmHOtB+/+SiUAAADFz3aAAPyw3R9YE0AgQSBJIQEGNHn+DiAAyXBC
    -IMAlSCAAAIDgANvL9wDaABYBQAHig+K99wHjEHO491YmABnWDiAABtnPcIAAsK8AgFEgQIAa8s9x
    -gAC0f89wgABktQaQVokQcgf0xBcAFjSJwLgQcQryxRcAFlEgQIEG8gmHUSBAgQ70rg1gAMlwz3CA
    -AJgPoqCKIBINXgggAKlxMg4AAD0CIAChwOB4ANhC8fHAocGLcGIOIAAB2QAUBTBMJQCAyiHBD8oi
    -wQfKIGEByiOBDwAArgfMBuH+yiRhAM9wgADUnO4NIAADGEIBocDRwOB+8cCOCQAAz3OAAFQQQ4MA
    -3891oAAsILCF0mrUfn5mpaYEpgHijCIIgCamQ6OF9wKD46MB4AKjwQEAAOB4ANjPcaAAyB8YoRmh
    -AdgOoeB+4HjxwD4JIABZcTlyyHHocgHdz3agAMgfs6YF3891gADAD+ClAaUEwEilCaUVhielCqUY
    -hhgdQBELpRmGFB0AEQyloBYAEGSlDaWkFgAQDB1AEg6lqBYAEAgdgBIPpc9wAQCwCRClSglgACjY
    -EaVCCWAAANgSpVMnwHUTpQLIVB0AFxalEhYAllAdABcXpRMWAJbPcoAAwA8YpRQWAJZKJEB5GaUV
    -FgCWANkapSQWAJYbpRYWAJYcpc9wgACQDBCAHaXPcIAAwA94GIAKz3CAAMAPfBjACs9wgAA8EAQY
    -AAuEGkALz3CgAMgcCICIGgAAz3CAAIAFAICMGgAAqCCAAvAiQwDPcJ8AuP8B4XagmQAAAPwciLb8
    -HEi2/BwItvwcyLX8HIi1/BxItfwcCLX8HMi0/ByItPwcSLT8HAi0/BzIs/wciLP8HEiz4H7geATc
    -ON018OB4BNw03TPw4HgE3DDdMfDgeATcLN0v8OB4BNwo3S3w4HgE3CTdK/DgeATcIN0p8OB4BNwc
    -3Sfw4HgE3BjdJfDgeATcFN0j8OB4BNwQ3SHw4HgE3AzdH/DgeATcCN0c8OB4BNwE3RnwNBQaMDAU
    -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
    -iiCLAAalz3BAAIcNBqXPcNEAwg0Gpc9wwAAHDgalAdgIpwDYDacOp89wUAD/AByhAdgXpwDYFqfP
    -cKUACAxQ2SKg/NjPcasAoP8YoXPYGaEagYG4GqHPcBEABg4GpYtwgcGT/zWGAMAieIQohAMUhjaG
    -AnkKDG/7L3ABwoIgxALPcYAAAIMWoRKmz3CgAMgfVaFREBCGAdlRGFiAINjPcaAAyB8QoQHYQxkY
    -AADY9g3v8o24INnPcKAAyB8xoM9wQACGDQalz3AQAAIOBqXPcKAAyB9RGBiEi3CBwXX/NYYAwCJ4
    -BCiADwAAdAkUhjaGAnmKC2/7L3ABwk/gz3GAAACDGKETplehz3CgAMgfURAQhgHZURhYgCDZMKAB
    -2UMYWAAA2IIN7/KNuCDZz3CgAMgfMaABlhC4hSCEAAalApYQuIUghQAGpQOWELiFIIsABqUElhC4
    -hSCPAAalBZYQuAUggA8AAIINBqUGlhC4BSCADwAAwg0GpQeWELgFIIAPAAACDgalz3CgAMgfURgY
    -hASGKoYIpwWGgOENpwaGDqcIhhenCYYWp89wpQAIDCKgDfIEEgQ2AhIFNgohwA/rcgXYDQav8fvb
    -C4bPcasAoP8YoQyGGaENhhqhXg6v/g6GiiDRBT4Pr/IyhhKGIQHv8qLA4H8B2PHArgjP8s9wgAAw
    -dAeIgOCcAiEAosHPcKAAyB9REBCGAdlRGFiAINkwoAHZQxhYAADYfgzv8o24INnPcKAAyB8xoIIM
    -r/4F2M91gAD0PQ6lw9jPdqAA7CcGpgqGz3enABRIALWKIMQABqYKhgG1iiDFAAamCoYCtYogywAG
    -pgqGA7WKIM8ABqYKhgS1z3AAAIMNBqYKhgW1z3AAAMMNBqYKhga1z3AAAAMOBqYKhge1CIcEpQ2H
    -BaUOhwalz3CnAJhHPIAnpTeHKKU2hymlz3GlAAgMIoEqpc9xqwCg/ziBK6XPcasAoP85gSylz3Gr
    -AKD/OoEtpc9xBQDGAyamxtmQuSamz3EsAAIBJqbPcVoAQgEmpoohiwAmps9xQACHDSamz3HRAMIN
    -JqbPccAABw4mpgHZKKcA2S2nLqfPcVAA/wA8oAHYF6cA2BanUNnPcKUACAwioPzZz3CrAKD/OKBz
    -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
    -4HjgfuB44H7geOB+4HjPcIAA6AfgfwCA4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
    -eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
    -4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwHY4H7geOB+4Hjg
    -fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB48cD+Do/w
    -GnHPd4AAREsgj1EhAIBG8s9xgADwByCJgOHMICGgPvKB4Ab0z3CAALicoYAD8ADdjuUD94DlAvQA
    -3c9xgAC4nBiJgOAE9IDlBPQA3gTwooEE3oogEwEaDa/wqXGKIFMBEg2v8Mlxz3CAABwPGIiD4Mwg
    -IoHMIOKBzCAiggjyiiATAe4Mr/Cl2QrwCpcQdQj0C5cQdswgIaAE9ADYIfAB2M9xoADIHw2hz3CA
    -APAHAYjLt6q3BL4QuMV9BX2KIBMBsgyv8LzZiiATAaYMr/Cpcc9woADIH38YWIMB2IEGj/DgePHA
    -Gg6v8AhxxP+A4DzyIN3PdqAAyB+wpjLYQx4YEADY8gnv8I24saawph7YQx4YEADY4gnv8I24saZ/
    -Fg+WiiATAUEvDRTEvUYMr/Dm2YogEwE+DK/w6XGKIBMBMgyv8Klxz3GAAPAHAYkB2hB1wiKKAIDl
    -QKnI9gDYDaaB4gT0BNgBqf0Fj/Dhxc9ygABESyCKAN3guWTYyiBBA+G5z3OgAMAdBqIJ8gzYAKMB
    -ggOiAoIEogTwoKOjoqSiz3CAABwPCYBRIECB0SGigATyAIOAuACj4H/BxfHA4cUA3c9woADAHaCg
    -qXCpcYz/z3CAAERLo6CkoJ0Fr/CmoIDgz3GAAERLBPRAIQADBPBAIQAEAIDPcaAAwB1RIACAAIHP
    -IOIA0CDhAACh4H7gePHA8gyv8APZz3aAAERLdgnv8MlwoI5EJUARheAM9AohwA/rcgXYadtKJEAA
    -5QGv70AtBRIBjoPgw/ZjuAGuAgnP8B0Fj/DgeOB+4HjgfuB44cVSIIAAz3GgAHwdBKkC3RHw4Hjg
    -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
    -ASQAAAElAAATJcIsEyQEKMARAkYTJAQowBHCXxMkBCjAEQ9FACIAXAA5JwAAZAAAEyQBABMlOBzA
    -EQ93EyLgHMARDwETIgQIwBEPAhMiBCjAEQ8HEyIEKMARDwQTIgQowBECAHFwBwAAYf8AEyUCEBMk
    -BCjAEQAAEyUAABMkyEnHEQYAAGEAABMlAhATJAQowBEAABMlSQATJMhJxxEPcBMiAQATMAQowBED
    -ABMkAAATJQQIwBEAABMkOEXAEQ8DEyIYKMARBAAAYQAAWDgAABMkAQATJTgcwBEAAAAhnGuAgQAA
    -wBY8BMARMAWAgQAAwBYEARtiEATAEAMAGyRUBMARJATAEQgEwBBca4CBAADAFwgEwBA4a4CBAADA
    -FwAAGyUDHBtiQAAbJDAcwBEFAABhNAWAgQAAwBYPGxkiCASggTjwxIAAABskAgAbJTgcwBEAAAAh
    -MAWAgQAAwBZMBMARNAWAgQAAwBYPGxkiSASggTjwxIAAABskAgAbJTgcwBEAAAAhAAAAhTAFgIEA
    -AMAWDxsEIhAEG2YPARtoFBzAEAoAG0AEABtuAwAAYQ8cHSIBAB0m+Q8AYWQMABAAwAYRAQAEJ/wA
    -BGQAABskAgAbJTgcwBEAAAAhAAAbJUAAGyQwHMARAAAAIQ8cHSIYAR0mGADHEPySgIEAAMAXIADH
    -EASTgIEAAMAXAAAAIXwxgIECAFxuEQAAYfhBxBAPGwkiAAsJOQIACmIDAQpiBAIKYgAACUAEAABh
    -CQAJQAIAAGEKAAlAAAAAYQIACUEACRooAADAFgEAGyYAAMAXBAAdJgEACCfpAAhkAAAAIQAAAACM
    -AQAAAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsOQAAODsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAABSEgAAAAAAAAAAAAAAAAAABAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -wACQANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAADIkoAAAAAAAAAAAABAl4AA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAsAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAiJyAACycAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMisgACY9gEAAAAA
    -AAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIkoAAhP8BAAAAAADIkoAA
    -UAYCAAAAAAAAAAAAyJKAAOgHAgAAAAAAAAAAAAAAAADIkoAAAAAAAAAAAAAAAAAA/wAAAAAHAAAA
    -AAAAAAAAABgbAgAYGwIAGBsCABwbAgAAAAAAHQAAAAAAAAAAAAAAAAAAAAAAAAB/fwABAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAQIECAAIECAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADECAAAFQAAANQtgAA4KwAAOCsAADgrAAAMQgAA
    -OCsAADgrAABYPQAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAArB4AAFwgAAB0
    -IAAA5CEAAGwiAADoIQAAOCsAADgrAACATgAASFAAADRRAAA4KwAAOCsAADgrAAD8TAAAFGQAABBk
    -AABoZAAAOCsAADgrAAA4KwAAGEQAADgrAABMZAAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsA
    -ADgrAAAQQgAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAA
    -OCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAAIRQAAOCsAADgrAAA4
    -KwAAOCsAADgrAADwRQAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgr
    -AABQawAAOCsAAHhsAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAACBvAAA4KwAAOCsA
    -ADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAAMyAAQAkhAEAOCsAAHiGAQA4KwAA
    -KIgBABRUAQA4KwAAOCsAAABSAAA4KwAAOCsAADgrAAA4KwAAOCsAADzeAQDE8QEAOCsAADgrAAA4
    -KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAACsGAIAOCsAADgrAAA4KwAA2P0BADgr
    -AADUAQIAOCsAAPwpAgA4KwAAoCUAAKQlAAA4KwAAOCsAAIgSAgBMcgAAOCsAADgrAAA4KwAAfPsB
    -ADgrAAA4KwAAWE0BAAygAQA4KwAAOCsAADgrAAD8qAEANFUBADgrAAA4KwAAOCsAADgrAAA4KwAA
    -OCsAALSzAQA4KwAAgA8CAIQPAgCQDwIAlA8CAIgPAgCMDwIAmA8CADgrAAA4KwAAOCsAADgrAAA4
    -KwAAOCsAADgrAAA4KwAAOCsAAPBTAAA4KwAAOCsAADgrAAA4KwAAOCsAANQOAgAkDwIAEEgAADgr
    -AAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsA
    -ADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAAA4KwAA
    -OCsAADgrAAA4KwAAOCsAADgrAAA4KwAAOCsAADgrAACQSQAAGEoAAKxKAABgSwAAJIEAADhLAAA4
    -KwAAOCsAADgrAAA4KwAAOCsAAIhJAACMSQAAOCsAADgrAAAwUgAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwM
    -AACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAACMDAAAjAwA
    -AIwMAACMDAAAjAwAAIwMAACMDAAAjAwAAIwMAAC8DQAAAAAAALxaAQCMDAAAnAkAAIwMAACMDAAA
    -jAwAAMwJAADoPAEAZIMAAIwMAACMDAAABAoAAAQKAAAECgAABAoAAAQKAAAECgAABAoAAIwMAACM
    -DAAAjAwAAIwMAAD8CwAAjAwAAIwMAACMDAAAjAwAAIwMAADADQAAjAwAAIwMAACACQAAAwAAAJwM
    -AgACAAAA6GgBAAQAAACcaQEABQAAANwNAAAGAAAAIDQAAAgAAAAADwIAEwAAACz4AQAJAAAAgAMC
    -AAoAAACcDwIADgAAABSdAQAPAAAAYIoBABAAAACYigEAGAAAACRaAQANAAAAEIIBABcAAABIcgAA
    -EQAAAKSBAAASAAAAWEwBAAEAAABY/QEAFAAAAMCwAQAVAAAAQKABAAcAAACQbwAAFgAAAOwpAgAZ
    -AAAAvA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAABAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAABAQAAAAAA
    -ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -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
    -lC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAA
    -AAAAAAAAAPg+AQAKAAAAlC2AAAAAAAAAAAAAAAAAAASGAQAKAAAAlC2AAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4jQEAhI4BAHCRAQAklAEApJYBACiaAQA0kAEARAWAAJCS
    -gAAYAAAAUJKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvJwBAAYAAACULYAA/////wAAAAD/////////
    -/wAAAAAAAAAAAAAAAJyfAQAFAAAA1C2AAG4AbgBpAMAAoABQAIAAvgBQAX0APgBuAG4AaQDAAKAA
    -UACAAL4AUAF9AD4AAAAAAAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIBAQACAQABAgICAAEB
    -AAIBAgECAAIAAQID//8AALkB3wCxABsAFgEbAHwBGwCvABsAFAEbAHoBGwBsAKAA0QCgADcBoABv
    -AIMAcQCDAHYAgwBzADMAbgAzAHAAMwByADMA1wAzAD0BMwDUAQYA0AEAAH4APADjADwASQE8AHgA
    -SQDdAEkAQwFJAH8AWgDkAFoASgFaAKoAPwCrAAEADwE/ABABAQB1AT8AdgEBAHkAagDeAGoARAFq
    -AKgAAAANAQAAcwEAAKYANwCnAAEACwE3AAwBAQBxATcAcgEBAAQACACcAcwAnQHMAJ4BzACfAcwA
    -1QHMANYBzADXAcwAtABHABkBRwCAAUcAkAAiAPUAIgBbASIAoQCIAAYBiABsAYgAlAAAAJUAAACY
    -AMAAmQCgAJYAkACXAAAAlAABAJUAAQCYAMAAmQCgAJYAkACXAAAAlAACAJUAAwCYAMAAmQCgAJYA
    -kACXAAAAlAADAJUABwCYAMAAmQCgAJYAkACXAAAA+gAAAPkAAAACAZAAAwHTAAABgwD+ABMA/AAz
    -AP0AdwD6AAEA+QABAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoAAgD5AAMAAgGQAAMB0wAAAYMA
    -/gATAPwAMwD9AHcA+gADAPkABwACAZIAAwHTAAABgwD+ABMA/AAzAP0AdwBfAQAAYQEAAGgBkABp
    -AdMAZgGDAGQBEwBiATMAYwF3AF8BAQBhAQEAaAGQAGkB0wBmAYMAZAETAGIBMwBjAXcAXwECAGEB
    -AwBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwBfAQMAYQEHAGgBkABpAdMAZgGDAGQBEwBiATMAYwF3
    -AIUAAACGAAAAhwBQAIgAAACJAKAAigAAAIsA0ACMAAAAhQABAIYAAQCHAFAAiAAAAIkAoACKAAAA
    -iwDQAIwAAACFAAIAhgADAIcAUACIAAAAiQCgAIoAAACLANAAjAAAAIUAAwCGAAcAhwBQAIgAAACJ
    -AKAAigAAAIsA0ACMAAAA6wAAAOoAAADsAFAA7QAAAO4AoADvAAAA8ADQAPEAAADrAAEA6gABAOwA
    -UADtAAAA7gCgAO8AAADwANAA8QAAAOsAAgDqAAMA7ABQAO0AAADuAKAA7wAAAPAA0ADxAAAA6wAD
    -AOoABwDsAFAA7QAAAO4AoADvAAAA8ADQAPEAAABRAQAAUAEAAFIBUABTAQAAVAGgAFUBAABWAdAA
    -VwEAAFEBAQBQAQEAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQECAFABAwBSAVAAUwEAAFQBoABV
    -AQAAVgHQAFcBAABRAQMAUAEHAFIBUABTAQAAVAGgAFUBAABWAdAAVwEAAPv/AAD//wAAuQHfALEA
    -GwAWARsAfAEbAK8AGwAUARsAegEbAGwAoADRAKAANwGgAG8AgwBxAIMAdgCDAHMAMwBuADMAcAAz
    -AHIAMwDXADMAPQEzANQBBgDQAQAAfgA8AOMAPABJATwAeABJAN0ASQBDAUkAfwBaAOQAWgBKAVoA
    -qgA/AKsAAQAPAT8AEAEBAHUBPwB2AQEAeQBqAN4AagBEAWoAqAAAAA0BAABzAQAApgA3AKcAAQAL
    -ATcADAEBAHEBNwByAQEABAAIAJwBzACdAcwAngHMAJ8BiADVAcwA1gHMANcBzAC0AEcAGQFHAIAB
    -RwCQACIA9QAiAFsBIgChAIgABgGIAGwBiAD6AAAA+QAAAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3
    -APoAAQD5AAEAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gACAPkAAwACAZcAAwHQAAABjQD+ABEA
    -/AAzAP0AdwD6AAMA+QAHAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3AF8BAABhAQAAaAGXAGkB0ABm
    -AY0AZAERAGIBMwBjAXcAXwEBAGEBAQBoAZcAaQHQAGYBjQBkAREAYgEzAGMBdwBfAQIAYQEDAGgB
    -lwBpAdAAZgGNAGQBEQBiATMAYwF3AF8BAwBhAQcAaAGXAGkB0ABmAY0AZAERAGIBMwBjAXcA6wAA
    -AOoAAADsAFUA7QAAAO4AqgDvAAAA8ADdAPEAAADrAAEA6gABAOwAVQDtAAAA7gCqAO8AAADwAN0A
    -8QAAAOsAAgDqAAMA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAA6wADAOoABwDsAFUA7QAAAO4AqgDv
    -AAAA8ADdAPEAAABRAQAAUAEAAFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAFEBAQBQAQEAUgFVAFMB
    -AABUAaoAVQEAAFYB3QBXAQAAUQECAFABAwBSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAABRAQMAUAEH
    -AFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAPv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAcswEAINQBAPScgABABQAAAAAAAByzAQBItAEANKKAAPgBAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAD42AEA/NYBACykgABUAAAAAAAAAByzAQAs1wEArKSAAFABAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAEAAAAcswEAQNMBAEA/gABQAQAAAAAAAByzAQBY1QEA8AaAAAIAAAAAAAAA
    -HLMBALDVAQD0BoAABAAAAAAAAAD02AEASLQBAICkgAAqAAAAAAAAAByzAQBM1gEAAAAAAAAAAAAA
    -AAAAHLMBAAzWAQD4BoAABAAAAAAAAAAAAAAAAAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkA
    -CgAKAAsADAAMAA0ADgAOAA8AJgAnACgAKAApACoARgBGAEcASABIAEkASgBKAEsATABoAGkAagBq
    -AGsAbABsAG0AbgBuAG8AcABwAHEAcgByAHMAdAB0AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUA
    -dQB1AHUAdQB1AHUADwA/AAAAAAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAIAAgACQAK
    -AAoACwAkACQAJQAmACYAJwBEAEQARQBGAEYARwBIAEgASQBKAEoASwBMAEwATQBqAGoAawBsAGwA
    -bQBuAG4AbwBwAHAAcQByAHIAcwB0AHQAdQB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2
    -AHYAdgB2AHYADgA/AESmAQAS0gAAAAAAAP//DwBwwgEAtgAAAAAAAAD/AAAAcMIBALcAAAAAAAAA
    -/wAAAHDCAQC4AAAAAAAAAP8AAABwwgEAuQAAAAAAAAD/AAAAcMIBALoAAAAAAAAA/wAAAHDCAQC7
    -AAAAAAAAAP8AAABwwgEAvQAAAAAAAAD/AAAAcMIBAL4AAAAAAAAA/wAAAHDCAQC/AAAAAAAAAP8A
    -AABwwgEAwAAAAAAAAAD/AAAAcMIBAMEAAAAAAAAA/wAAAHDCAQDCAAAAAAAAAP8AAABEpgEAE9IA
    -AAAAAAD//w8AcMIBABsBAAAAAAAA/wAAAHDCAQAcAQAAAAAAAP8AAABwwgEAHQEAAAAAAAD/AAAA
    -cMIBAB4BAAAAAAAA/wAAAHDCAQAfAQAAAAAAAP8AAABwwgEAIAEAAAAAAAD/AAAAcMIBACIBAAAA
    -AAAA/wAAAHDCAQAjAQAAAAAAAP8AAABwwgEAJAEAAAAAAAD/AAAAcMIBACUBAAAAAAAA/wAAAHDC
    -AQAmAQAAAAAAAP8AAABwwgEAJwEAAAAAAAD/AAAARKYBABTSAAAAAAAA//8PAHDCAQCCAQAAAAAA
    -AP8AAABwwgEAgwEAAAAAAAD/AAAAcMIBAIQBAAAAAAAA/wAAAHDCAQCFAQAAAAAAAP8AAABwwgEA
    -hgEAAAAAAAD/AAAAcMIBAIcBAAAAAAAA/wAAAHDCAQCJAQAAAAAAAP8AAABwwgEAigEAAAAAAAD/
    -AAAAcMIBAIsBAAAAAAAA/wAAAHDCAQCMAQAAAAAAAP8AAABwwgEAjQEAAAAAAAD/AAAAcMIBAI4B
    -AAAAAAAA/wAAAESmAQAI0gAAAAAAAP//AwCEpgEAAIIAAAAAAAD/AQAAhKYBAAGCAAAAAAAA/wEA
    -AESmAQAJ0gAAAAAAAP//AwCEpgEAAoIAAAAAAAD/AQAAhKYBAAOCAAAAAAAA/wEAAESmAQAK0gAA
    -AAAAAP//AwCEpgEABIIAAAAAAAD/AQAAhKYBAAWCAAAAAAAA/wEAAESmAQAG0gAAAAAAAP8BAABE
    -pgEAB9IAAAAAAAD/AwAARKYBAAbSAAAJAAAAAP4DAESmAQAH0gAACgAAAAD8DwBEpgEABtIAABIA
    -AAAAAPwHRKYBAAfSAAAUAAAAAADwP0SmAQAV0gAAAAAAAP8DAABEpgEADNIAAAAAAAD/AQAARKYB
    -ABXSAAAKAAAAAPwPAESmAQAM0gAACQAAAAD+AwBEpgEAFdIAABQAAAAAAPA/RKYBAAzSAAASAAAA
    -AAD8BzCAAACqqqqqMYAAAKqqqqoygAAAAKqqqjOAAAAAAAAANIAAAAAAAAA1gAAAAAAAADaAAAAA
    -AAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAAAAAAA7gAAAAAAAADyAAAAAAAAAPYAAAKqq
    -CgA+gAAAqqqqqj+AAACqqqqqQIAAAAAAAAAwgAAAqqqqqjGAAACqqqqqMoAAAACqqqozgAAAAAAA
    -ADSAAAAAAAAANYAAAAAAAAA2gAAAAAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAAADqAAAAAAAAA
    -O4AAAAAAAAA8gAAAAAAAAD2AAACqqgoAPoAAAKqqqqo/gAAAqqqqqkCAAAAAAAAAMIAAAAAAAAAx
    -gAAAAAAAADKAAAAAAAAAM4AAAAAAAAA0gAAAqqqqqjWAAACqqqqqNoAAAAAAAAA3gAAAAAAAADiA
    -AAAAAAAAOYAAAAAAAAA6gAAAqqqqCjuAAACqqqqqPIAAAAAAAAA9gAAAAAAAAD6AAAAAAAAAP4AA
    -AAAAAABAgAAAAAAAADCAAAAAAAAAMYAAAAAAAAAygAAAAAAAADOAAAAAAAAANIAAAKqqqqo1gAAA
    -qqqqqjaAAAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAKqqqgo7gAAAqqqqqjyAAAAA
    -AAAAPYAAAAAAAAA+gAAAAAAAAD+AAAAAAAAAQIAAAAAAAABEBYAAkJKAABgAAABQkoAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAsPMBAAYAAACULYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAABEBYAAkJKAABgAAABQkoAAAAAAAAAAAAAAAAAAAAAAAAAAAABU
    -/wEABgAAAJQtgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAEQFgACQkoAAGAAAAFCSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2A
    -AAAAAAAAAAAAAAAAAHAKAgAEAAAAlC2AAAAAAAAAAAAAAAAAAGgMAgAGAAAAlC2AAAAAAAAAAAAA
    -AAAAAHAKAgAEAAAAlC2AAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAHAKAgAE
    -AAAAlC2AAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAHAKAgAEAAAAlC2AAAAA
    -AAAAAAAAAAAAAGgMAgAGAAAAlC2AAAAAAAAAAAAAAAAAAHAKAgAEAAAAlC2AAAAAAAAAAAAAAAAA
    -AKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAGgMAgAGAAAAlC2AAAAAAAAAAAAAAAAAAKALAgAEAAAA
    -lC2AAAAAAAAAAAAAAAAAAKALAgAEAAAAlC2AAAAAAAAAAAAAAAAAAGgMAgAGAAAAlC2AAEQFgACQ
    -koAAGAAAAFCSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAFAUAAAAAAAAAAAAAAAAAAAAAAP8A/wAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECAwQEBAQEBQYH
    -CAgICAgJCgsMDQAAAAUGBwgNDg8QFRYXGBkAAAoNERQKDREUGRkZGQoKAAAAAAAABgYGBgkJCQkA
    -BgAAbjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bitoK2IrXCtuKmgqYipcKm4paCliKVwpbhtoG2Ib
    -XBtuGmgaYhpcGm4ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24WaBZiFlwWbhVoFWIVXBVuFGgUYhRc
    -FG4TaBNiE1wTbhJoEmISXBJuEWgRYhFcEW4QaBBiEFwQVxBSEE0QSRBuAWgBYgFcAW4AaABiAFwA
    -bjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbihoKGIoXChu
    -J2gnYidcJ24ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24JaAliCVwJbghoCGIIXAhuB2gHYgdcB24G
    -aAZiBlwGbgVoBWIFXAVuBGgEYgRcBG4DaANiA1wDbgJoAmICXAJuAWgBYgFcAW4AaABiAFwAAAAA
    -AAAAAAAAAAAALCwCAAgAAADULYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAA/////////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/////////////////////////////
    -/////////////////////////////////////////////////wEEAAACBQEAAwYCAAQHAwAFCAQA
    -BgkFAAcKBgAICwcACQwIAAoNCQALDgoADA8LAA0QDAAOEQ0AAUAABAJBAQQDQgIEBEMDBAVEBAQG
    -RQUEB0YGBAhHBwQJSAgEtxMiALgUIwC5FSQAuxYlALwXJgC9GCcAwBkoAMQaKQAHGwAACBwBAAsd
    -AgAMHgMAEB8EACIhBQAkIgYAJiMHACgkCAAqJQkALCYKAC4nCwAwKAwANCkNADgqDgA8Kw8AQCwQ
    -AGQuEQBoLxIAbDATAHAxFAB0MhUAeDMWAHw0FwCANRgAhDYZAIg3GgCMOBsAkTocAJU7HQCZPB4A
    -nT0fAKE+IAClPyEAJEkGAixKCgI0Sw0BPEwPAWRNEQFsThMBdE8VAXxQFwGEURkBlVIdAZ1THwEA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQYCBgYGAwYGBgYGBgYEAAAAAAPAD8AAQAA
    -AA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAgAAAA8APwABAAAA
    -AAAAAAEAAAACAAAAAwAAAAAAAAAEAAAAAgAAAAUAAAAPFBkeKAoFALAJAaUAPDg0MCwoJCAcGBQQ
    -DAgEAAwIBAA8ODQwLCgkIBwYFBAMCAQCCAAOAAAADgEBAAECAQEBAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClxoT4me6N9g3/vdax3lSRUGADAqnOfVYZ52K1
    -5k2a7EWPnR9AiYf6Fe/rssmOC/vsQWez/V/qRb8j91OW5FubwnUc4a49akxabEF+AvVPg1xo9FE0
    -0Qj5k+Jzq1NiPyoMCFKVZUZenSgwoTcPCrUvCQ42JJsbPd8mzWlOzX+f6hsSnh10WC40LTay3O60
    -+1v2pE12YbfOfXtSPt1xXpcT9aZouQAALMFgQB/jyHnttr7URo3ZZ0ty3pTUmOiwSoVruyrF5U8W
    -7cWG15pVZpQRz4oQ6QYEgf7woER4uiXjS/Oi/l3AgIoFrT+8IUhwBPHfY8F3da9jQjAgGuUO/W2/
    -TIEUGDUmL8PhvqI1zIg5LleT8lWC/Ed6rMjnuisyleagwJgZ0Z5/o2ZEflSrO4MLyowpx9NrPCh5
    -p+K8HRZ2rTvbVmROdB4U25IKDGxI5Lhdn26970OmxKg5pDE304vyMtVDi1lut9qMAWSx0pzgSbTY
    -+qwH8yXPr8qO9OlHGBDVb4jwb0pyXCQ48VfHc1GXI8t8oZzoIT7dltxhhg2FD5DgQnzEcarM2JAF
    -BgH3Ehyjwl9q+a7QaZEXWJknOrknONkT67MrMyK70nCpiQenM7YtIjySFSDJSYf/qnhQeqWPA/hZ
    -gAkXGtplMdfGhLjQw4KwKXdaER7Le/yo1m06LAEBAQEBAQEBAgICAgICAgIDAwMDAwMDAwQEBAQE
    -BAQEAQICAgICAgMDAwMDAwMDAwMDAwMDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAEBAgEC
    -AgN//wcPHz8BAwEDDwcBBw8fP3///wUABwIDBAYGdNFFF+iiiy4NDwUHCQsBAwoUN25VVVUBS2gv
    -AVVVVQXjOI4DqqqqAnEcxwGqqqoKx3EcBw8PDwcGBwIDBAUAAQgJCwooACgAMAAsACwAKAA8ADQA
    -KAAoADQAMAAsACwARAA8AEAAPACMAGwAWABIAPQAsAAsACwAPAA0ADAALABUAEQAVABUAGwAYABc
    -AFQAjAB4ADoBAgHVAN8A2gCiAHUAfwBqARoB2QDoAAoBugB5AIgAigUqAzkBqAGKBcoC2QBIAcoB
    -SgHiAPkAygHqAIIAmQD0AkQCtQHVAZQChAH1AEECrACQAIQAgAB4AHgAeAB0AGbmAACd2ImdTuzE
    -TjRIgzQndmInGqRBGhM7sRMRGIERD/zAD07sxE4ndmInGqRBGhM7sRMN0iANiZ3YCQiMwAgHfuAH
    -NEiDNBqkQRoRGIERDdIgDQiMwAgGaZAGsLLVBQVUQAUndmInEzuxEw3SIA2JndgJBmmQBsRO7AQE
    -RmAEAz/wA6qqqqoapEEaEzuxEw/8wA8RGIERDdIgDQqogAoTO7ETD/zADw/8wA8N0iANC7RACwu0
    -QAuJndgJDdIgDQqogAoKqIAKCIzACAd4gAcHeIAHBmmQBg/8wA8N0iANC7RACw3SIA0LtEALiZ3Y
    -CQiMwAiJndgJCIzACAd+4AcHfuAHwSwpBwqogAoIjMAIB3iABwiMwAgHeIAHBmmQBrCy1QUGaZAG
    -sLLVBQVUQAUFVEAF1h3GBEADgAbACQANgBMAGkAdgCCABgANgBMAGgAnADSAOgBBwAmAE0AdACeA
    -OgBOwFeAYZkDMwfZCnMOphXmHIAgGSQzB3MOphXmHFkrzDkAQTNI2QqmFYAgWSsAQaZWgGFZbDAA
    -AAA2AAAADAAAABIAAAAYAAAAJAAAAAYAAAAJAAAAAAAAAAAAAAAYIBQUDg4UFAUGAQIDBAAAAAEB
    -AgECAgMEDAwIBAwEBEAAAACAAAAAAAEAAAACAABAAAAAAAQAAEAAAABAAAAAEBESExQVFhcYGRob
    -HB0eHyAhIiMkJSYnKCkqKywtLi9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNk
    -ZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/MxMAAAAHBw8HDw8XLQAPIADwYQAAAAAAAAAAAAAB
    -AgQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAADA5OjUyOjE5AAAAAE8usABqsKKwkrBjAAGtrXsArZOcra1gAAkAAAACAAAAAAAA
    -AAAAAAAJAAAAAgAAAAAAAAAAAAAACQAAAAMAAAABAAAACQAAAAkAAAACAAAAAgAAAAkAAAABAgEC
    -AwQAAAUGBwgJCgAAAAUGAAIEAAUAAAAAAAUHAQMEAAUBAAAAQCNAJSEhISFAQEBAQAUEBAEBQEBA
    -QAUFQEAMDEANDAwBAQEFQEAFBQAEAARAQAAEQEBABUBAQEBABUBAQAUFBQEBAQFABQUFAQUBAUAF
    -BQVABUAFBQUFBQQAAAAcEQAAHDIAABwzAAAEAAAAHBUAAAIAFwBsAHAEdAh0DAAEBAYAAAAAAAAA
    -AGQAAAAAkAEACgAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAQAAABAAAAAAAAAA
    -AQAAAAEAAAAAAAAA/wAAAP8AAAAAAAAAAAAAALx8AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAEAAAAFAAAAAAQAAGQAAABQgwEAWIMBAGCDAQC4gwEAwIMBAMiDAQAHBwcHBwcH
    -BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcGBgYGBgUF
    -BQUFBAQEBAQDAwMDAwICAgICAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -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
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIIAPAABAAGkgAABpIEAAaSAAAGkgQAAgIIAPAADo
    -AGkgAABpIEAAaSAAAGkgQAAgIIAPAABkBmkgAABpIEAAaSAAAEogAABKIQAASiIAAEojAABKJAAA
    -SiUAAEomAABKJwAASiAAEEohABBKIgAQSiMAEEokABBKJQAQSiYAEEonABBKIAAgSiEAIEoiACBK
    -IwAgSiQAIEolACBKJgAgSicAIEogADBKIQAwCiSAP4EAAEBBLJwwQCycMEIkHDQKIoA/gAA4cwoj
    -ADfmDwAASiYAcGkgQABKJgBwSiYAcEomAHBKJgBwABYAcIAAZARAeCAgQIcAAAAAAAAAAAAA4cDh
    -weHCz3CgAMgfFhABhs9ygACYhyCiEhABhiGiExABhiKiFBABhiOiFRABhiSiJBABhiaiz3GfALj/
    -VqGKIf8PEhhYgBMYWIAUGFiAFRhYgCQYWIDBwsHBwcAgIECHDMjPcqAAyB8OGhiADcgPGhiADsgQ
    -GhiADxIBNgHIJHgRGhiAEMgtGhiA4H7hxPwcyL78HEi+4cDhweHC4cP8HAix/BxIsfwciLH8HMix
    -/BwIsvwcSLL8HIiy/BzIsvwcCL9qJIAQ4cRqJMAQ4cTxwM9woADQGxSAz3GAAGAEBCCAj89RBOEA
    -oQryLykBAM9wgAA0D/AgQABAeNr/0cDBxGskwBDBxGskgBDBxJ90BBQLNAQUCjQEFAk0BBQINAQU
    -BzQEFAY0BBQFNAQUBDTBw8HCwcHBwMHERSx+EAomQH7BxGskgBTBxCAgQIcMyIe4DBoYMA3Im7gN
    -GhgwDsgOGhgwD8iHuA8aGDAQyBAaGDDgfuB48cAMyJW4DBoYMA3Im7gNGhgwD8iKuI24kLgPGhgw
    -z3CAAGwQGIgbCFEAD8jPcQAAiAysuA8aGDA+DiAAD9hn2IYKIAGKIQYK0cDgfvHAz3CAALy1AICG
    -IP6BCfQPyAUggA8AAADUDxoYMKH/iiBVBVYKIAGKIUYO6PHgeM9xAwBADc9woACoIC2gz3GAAIwE
    -QIEBagChz3CgADguBYAEIIAPwAAAAB0IgA/AAAAASNjPcZ8AuP8aoVuhadgYuBmhz3CAAMgJJYAj
    -gSCBx3EAAIgT5QLACeB4z3CAAMgJeQLACeB48cBuCwABz3eAAGAEiHUG6A0IUQAB2APwANgLrwXp
    -DwlRAAHYAvAA2AqvBuoNClEAAdgD8ADYDK8A2M92oADIHxgeGJALj4ohEAAO6AiPDOjPcAMAQA1F
    -HhgQMKYC2BgeGJAD8DGmCo8Y6AmPFujPcAIApkEgHhiQz3CAACgAIR4YkM9wgABcBCIeGJAYFgCW
    -RSAAAxgeGJAMjwjoGBYAloUgAQQYHhiQDwtRABgWAJaIuBgeGJDPcIAAMHwAkI7gzCCiggb0GBYA
    -loC4GB4YkBjtANiUuM91gACABAClcdgGuMYMIAH82SCFz3AAAEwctgwgAZ+5GBYAloW4GB4YkNUC
    -AAHPcaqqu7vPcJ8AuP82oDagNqA2oM9xoADIOw6BiLgOoWkgQAD+8eB48cClwUHAQsEMHAAxEBxA
    -Mc9xgAB8dDQZwA8wGQAPLBnADigZgA4kGUAOz3CAAHx0IBhAC89wgAB8dBwYAAvPcIAAfHQYGMAK
    -z3CAAHx0FBiACs9wgAB8dBAYwAjPcIAAfHQMGIAIz3CAAHx0CBhACM9xgAAAdIAZAAh8GcAHeBmA
    -B3QZQAdwGQAHbBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARAGQAE
    -76HOoa2hjKEsGcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC1BkA
    -AGoggALQGQAAaiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0GQAA
    -aiCAAcwZAADQ2J+4z3GfALj/HaHPcIAAAADEgFMlxDVTJsU117oB5tO+xKBTI8AEBSaOH9D+AADW
    -oQUggA+w/gAAFqEYgVMnzjUA3ZS4GKFAwwHAAsHJcwwUBjB+D+AAEBQHMM9woAC0D7ygz3GgAMg7
    -LoEWD+AAfdhaDkABFgsgAalwCNgA2cYKIAGZuc9wgAAwfACQjuDMIKKCyiCBD+AAxDHKISEA4A8h
    -Ac8hoQX9Bc//8cA6CCABe9jODuAA4dnPcYAAfHQ0GcAPMBkADywZwA4oGYAOJBlADs9wgAB8dCAY
    -QAvPcIAAfHQcGAALz3CAAHx0GBjACs9wgAB8dBQYgArPcIAAfHQQGMAIz3CAAHx0DBiACM9wgAB8
    -dAgYQAjPcYAAAHSAGQAIfBnAB3gZgAd0GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZ
    -QAVQGQAFTBnABEgZgAREGUAEQBkABO+hzqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlA
    -ARAZAAFjoWogAAPYGQAAaiDAAtQZAABqIIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGog
    -gAC8GQAAaiBAALgZAABqIAAAtBkAAGoggAHMGQAA63bPdaAAyB8ZFRGWz3AAAEQccg8gAQogwC9a
    -cM9wgABsKiOAz3OfALj/z3eAAAAABIcB4NO4IukZFQKWQQreAF2DQN6fvt2jBKcFIIAP0P4AABaj
    -WBuAByEVAJYiFQCWBCGBD/8A/P8AgRajCNgZHRiQVqNdo9EGwADQ2Z+5PaMEpwUggA/Q/gAAFqPP
    -cIAAgAQAgAsggIQI8lgbgAR+CUACDNgt8IwhBKAm8owhAaAi8kIhQSBFCRUEMyZBcIAAAFxAJwBy
    -NHgAeEohQCAN2BfwSiGAIATYE/AT2EohACEP8EohACIU2AvwSiEAJBXYB/AW2AXwF9gD8A/Yz3OA
    -AOANcIMKcclyCiRABOUD7/8KJYAE4HhFAs//8cDGDMAAddiCDOAAiiEKA64MAAACDoACYf6iCAAA
    -CiHAD+tyBtiKI0oHSiQAAKkD7/8KJQAB4HjxwATpGQgSCAohwA/rcgXY49tKJEAAiQPv/7hzz3KA
    -ADQPFXogotHA4H7geADZnrkZec9ygAAsDwGCJXjgfwGiANmeuRl5z3KAACwPAYImeOB/AaIA2Z65
    -GXnPcIAALA8BgCR4QiAAgOB/yiBiAOB4z3CAACwPAYDgfy8oAQDgePHA+g+P/+B44HjgeOB4aSCA
    -AW8hPwBpIAAA9/HxwGrYsgvgAIohxAUA2I24ug7gAwoaGDAUzIYg/4oJ8s9wgAApBQCIgOCgCwIE
    -r/HxwMYLAATPcYAA4AnwIQAAQHjPcKAA0BuA2lCgz3CAAAAAAIAA2Q8IHgLPcJ8AuP89oJXx8cDe
    -DMAAz3GAAAAAAIE5CN4AAYFRIMCAQNjPIOIHyiCBDwAA0ADPIOEHz3KfALj/HaIEgQHg07gEoQUg
    -gA/Q/gAAFqLPcIAAYASggM9wgABsEAiABCWNHw8AAOAB3g0I3wKODsALjujPcaAAtEcA2EsZGIB3
    -GZiDANieuFQZGIDPcoAAmAQgguGCBCWEHwEAAABALIAApHgEJYMfAAAAQAd5A7sgoqR7BHlnfwYl
    -QBDhogQlgR8AAACALyICAUV5ArnkewQljR8CAAAAZnikeSZ4LygBAE4gQQTPcIAAfHPwIEIAz3CA
    -AFC7hCoLDDAgQA5TIECAGxpYMCr0z3CfALj/OKAvCZEBz3KAAIiGCZIL6BsamDPJcc9ygADgDRuC
    -AeAbohTwDJIS6ATZGxpYMPTxhOHMIWKACvTPcIAAiIYOkAboBtkbGlgw6PHPcqAAFAQqos9wgABE
    -CQCIDQhRAAmCuOAA2IP3AdiI6M9woACIIDV4wKA48M9xgAAwBQDYAKEA2ZG5z3CgAMgfExhYgM9w
    -gADQAhB4z3WgALRHSR0YkM9xgADElc9wgAA0BSCgbydDEFQd2JOuDOADChqYMy4NwAuQ6ADYkbjP
    -caAAyB8TGRiAz3CAAAAEEHhJHRiQVB3Yk2EDwADxwPYKwADPcYAAsA6AEQAAz3WgAMgfLy4BEM9w
    -AwBADUUdGBAA30MO0BfPcoAAAAAAgjcIngQBgvK4QNvPI+IHyiOBDwAA0ADPI+EHz3CfALj/faBk
    -ggHj07tkogUjgw/Q/gAAdqDwIYADQHgZDtAXz3CAAAAAAIANCJ4Ez3CfALj//aCA2BUdGJDVAsAA
    -4HjxwM9xgABgBHzY0gjgACCBCiHAD+tyBdj920okAAAJAO//CiUAAeB48cDhxc9wgABgBKCAa9gE
    -JY0fDwAA4J4I4ACKIQgLLyhBAzYMoA9OIEAECiUAgMohwg/KIsIHyiBiAcojgg8AADICvAei/8ok
    -YgB/2Aq4z3GgANAbE6F/2BChXQLAAOB48cDhxc91gAAAAACFNQjeAwGF77hA2M8g4gfKIIEPAADQ
    -AM8g4QfPcZ8AuP8doQSFAeDTuASlBSCAD9D+AAAWoWvYEgjgAIohyA+uC6APBNgKJQCAyiHCD8oi
    -wgfKIGIByiOCDwAAQQI0B6L/yiRiAACFEQjeAwDZz3CfALj/PaDVAcAASiTAdQDZqCDAA89wgAC0
    -DzZ4YYBAgM9wgACwDgHhVXhgoOB+4H7geA0JXkcNyL24DRoYMADZnbnPcKAA0BsxoOB+4HjgfuB4
    -8cCB4MwgooAF9M9ygABsEATwz3KAAGS4z3GAALSHgeDMIOKAKfRogmChaYJhoXyKaKl9immpKhKD
    -AGqpKxKDAGupLBKDAGypdJJ2qW2SZ7F3kmixaILAu3SpaIIEI4MPAAYAAIDjAdvAe3KphBICAFQZ
    -mAAc8GCBaKJhgWmiaIl8qmmJfapqiSoawgBriSsawgBsiSwawgB2iXSyZ5FtsmiRd7JUEQMGhBrA
    -AA0IkQDeCyABQCEABtHA4H7PcIAAZLgggM9yoACAJSaiIpAnoiKAKqImkCuiz3GAALy1IIFRIUCA
    -IIAV9CiiIpApoiKAMaImkDKiIoA3oiaQOKIigDuiJpA8oiCAOaIikDqiIIA1oiKQNqIhAUAQ4Hjx
    -wPYPgADPcIAAeJ4A3tSoz3CAALy1AIApCF4ACN/JdYDlzCWikMwlIpHMJWKRVA1iBMogQgNhv+kP
    -dZAB5R3wiiQBcc9xgACIhqgggAEEGZAD4HgA2UokAHLPcoAA4IioIMACFiJAAHaQz3CAAACHNHgB
    -4WCwz3WAAGS4z3eAAFCaQCUAEiRv6gzgAAbaqXBAJ4ES3gzgAAbaQCUAEkAnARTSDOAABtoYjSEI
    -EQGKIA8Kug2gAIohmggoFYAQTg7gECiFCg6ADwmFFwheAYoghw6aDaAAiiEaDgYMwAnPcIAAvLUA
    -gFEgQICADIEEz3EAAP//z3CAAASXLKAroAUamDOo/1kHgADxwO4OoAAA2oQoCwwAIYN/gABkuLUb
    -mADPdoAAEFy0aLpmUoIChgAhgX+AAGC6z3eAAASJuhuYAGGG3BnAAGWG4BkAAAaG5BnAAOgZAAAW
    -J4AQFiaBEAjgBOFSD+AFCNrdZRSFFn4Wf0AnABIkbj4P4AUI2uEGgADxwADY4f/SCCAGANjPcIAA
    -zC5WDkAJz3CAAAwvSg5ACVoLAAZqCUAFAdgA2X4IYA+A2iYKQAzaC4AP0grACUYMwArCCUAKANg2
    -CWAQCHEaD4AMhgsACskFz//gePHA4cUA3c9wgABcBaCgz3CAAFyerLACDuAJqXAqCo//igxgDKlw
    -jg1ABm4IgASqCkAL6gygDKlwtgyADFUGgADxwN4NgACjwQ0IkQDPdYAAbBAI8IQoCwwAIY1/gABk
    -uA0IkQDPdoAAaKUJ8M9xgAAsu4QoCwwAIU4OLZU8eihwhiHxD0e5wrqGIP4DJHpEuFBxyiHCD8oi
    -wgfKIGIByiOCDwAAPATKJCIAMAOi/8olAgFIhTu6UyICgECuTZXAukGuDPJ3lYYj/wlDu2eud5WG
    -I/4HRbtorhHqz3KAAFg3FSIDAACLNXoCrgGLA64CiwSuA4sFrgOKCvAB2SmuAtgCriOuANgErgPY
    -Ba4GrotwyXHGDeAFDNoAwAHB/g2gDALCi3DJcbIN4AUM2gDAAcFqDqAMAsLPcYAA2AYAoQ2VRLgA
    -2S+lDQgeAIohCAAvpQkIXgCLuS+lCQieAI25L6UpBaAAo8DgePHAsgygAJhwhCgLDAAhgH+AAGS4
    -VSBGCiiAVSDFC89ygAAYBVEhwICKIQgAyiEhACCiSiQAcgDZqCBAD891gABYYPyILmXkfi8qgQNO
    -IoMHz3KAAHxgb2IAJkMA4KtUEI8A5H4vLoETTiaPF+5iyKvIgCEO3hBdiIbh0yKmAC8qgQBOIo0H
    -z3KAAIRgqmIR8M92gABsYC5mzmW8iMR9bBCOAMR9Ly1BE04ljhfKYlCrAeFKJAByANqoIMAP3IjP
    -c4AAZGBPY891gAB8YOR+LymBA04hjwfvZQAmgQD8qVQQjwDkfi8ugRNOJo8X7mUkGYIDyIAfDt4Q
    -fYiA4tMjoQAvK8EATiONB89zgACEYKtjEPAE6slqA/BIds5jfIjEe2wQjgDEey8rwQBOI44Hy2Us
    -GcIAAeJKJABxANqoIAAFz3GAAGBgfYhJYQAljAAB4mR5LylBAE4hgwfPcYAAhGBpYSCsjg6gCIhw
    -sQOAAOB48cBCC4AADwiRAM9xgABsEAfwhCgLDAAhgX+AAGS46YFYiUEvwxDAuxe7x3MAAIAc5L/P
    -IyIG4L9O3c8jogDKJYIfAABOAYbizyVhElEPXxHPcoAAtIcWEoUAz3KAAHC7RpLPdoAAZLjFFgQW
    -GQpBAcQWAhZTIgUAz3KAALSHVIoTCkABQSxCAQsKHgBJhhMKXwENDF8BSYYHCl4BgbvPcoAAWLtU
    -iofizyPhAFEnAJLPI6IFiBnAAIwZQAMNCJEAz3GAAGwQCPCEKAsMACGBf4AAZLhpEYMAThEOAQ4j
    -gg8AADoBCbpifkV+WpFiehK6RX5bkWJ6QCrNBcV9BCW+nwDwAADKIcIPyiLCB8ogYgHKI4IPAADF
    -AM8j4gLKJMIA4Adi/8olQgOQGUADDQiRAM91gABsEAjwhCgLDAAhjX+AAGS4z3CAADB8AJCO4Mwg
    -ooIp8gfYQgrgAAq4BCCADwcAAAAwuGcIFQIzJgBwgAB0XEAngXIUeQB5iiAEAJQdABAf8IogEACU
    -HQAQGfAA2Iu4lB0AEBXwANiMuJQdABAP8ADYjbiUHQAQC/AD2Ay4lB0AEAXwANiOuJQdABCCIAEB
    -6QGgAJQdABAKIcAP63IF2Prbi7tKJAAAKQdv/wolAAHgePHAXgmAAAh1DQiRAM92gABsEAjwhC0L
    -HAAhjn+AAGS4AdloHkIQAN+AHsATTNhOHgQQBdgQpgrYG7YQ2Bq2FNhMHgQQLdhQHgQQJthSHgQQ
    -SiQAculwqCCADc9ygAC4YPQiAwDPcoAAHJgUemCyz3KAAMhg9CIDAM9ygAAsmBR6YLLPcoAA2GD0
    -IgMAz3KAADyYFHpgss9ygADoYPQiAwDPcoAATJgUemCyz3KAAPhg9CIDAM9ygABcmBR6AeBgsgiG
    -DwheAQTaYh6CEAPwYh7CExkIHgEJ2WoeRBAu2l22AtppHoIQCvAU2moehBAy2l22aR5CEBTZWY5Z
    -YTB5ah5EEBrhPLYXCB4ACthkHgQQBthmHgQQB9gH8BDYZB4EEGYexBMF2BCmqXCX/jyOKHBUHkIQ
    -hiADAOa5bB4CEMoiQQAM8lAhwwFvelQewhBQIMMBb3hsHsIQEQleAUhzhiMDAG96VB7CEAsJHgGl
    -uGweAhANCd4ApLpUHoIQMQ2QEKlwy/7PcIAAOLuELQscMCBADlEgQIDx2MAoIgHKIIEPAACTAMAo
    -IQGgHgAQGNiNuBemCIZRIMCAz3CAAGS4BvK+EIAAibgE8KUQgAAWps9woACsLxmAMLjAuM4KIBBV
    -HgIQCIYEIL6PAAYAAAvyNrjAuBt4AeBuHgQQAtiAHgAQA/BuHsQTANgcph2mqXAE/yiGAdpIc0Ep
    -AAU1uVIgAABSIQEAwLjAucoLb/+YcpkHQADgeM9wgABsEAiAz3GkABxAwLgTeMG4EqHgfvHA4cXP
    -dYAAbBBXlc9xgADcBlfYAKELCh4AX9gAoQsKngCFuAChCwpeAIe4AKHPcYAAaKVAiQDZgOLKIEEA
    -z3GlAOgPBqHPcaAApDABgYDizyDiANAg4QABoVIPwAwwhc9woADIHCig8g8gDQ+FHQdAAOB44cXP
    -cIAAbBApgEQhg4AA2iP0iwoVBAAijQ+AANAsAI2guACtgBWAEKC4gB0CEEAVgBCguEAdAhAQjaC4
    -EK2QFYAQoLiQHQIQUBWAEKC4UB0CEAHi3/FHChUEACKND4AA0CwAjYC4AK2AFYAQgLiAHQIQQBWA
    -EIC4QB0CEBCNgLgQrZAVgBCAuJAdAhBQFYAQgLhQHQIQAeLf8SUJngHPcoAA0CwIioC4CKqIEoAA
    -gLiIGgIASBKAAIC4EfCR689ygADQLAiKoLgIqogSgACguIgaAgBIEoAAoLhIGgIAANg9CR4ASiQA
    -dOB4qCBABi0IngAAIIMPgADQLCATgQCAuSAbQgCgE4EAgLmgG0IAYBOBAIC5YBtCAAHgHfBKJAB0
    -4HioIEAGLQieAAAggw+AANAsIBOCAKC6IBuCAKATggCguqAbggBgE4IAoLpgG4IAAeDgf8HF4Hjx
    -wEYNYAAH2s92oADIH0gemJDPdYAAbBCAFQAQz3GrAKD/TB4YkADYGaFaoRihiiAEAA+mahUAEc93
    -gAAwfLAeABC0HgAQH9gIuA6mCIVRIACAANiLuBXyEKbqD8APz3GgAKQwAYGEuAGhBJc1CFEBANmU
    -uc9woAAERCWgEvARpsYPwA/PcaAApDABgaS4AaEElxEIUQHPcaAABEQA2AWhz3CAAMwEAIAVCB4A
    -hiD/DiK4FLjPcaAABEQFoVj/ogyADF3/ef/PcAAAVVVaHhiQAdhZHhiQCIXPcaYAKAARCN4EANgP
    -oTYIABAE8AHYD6FuFQERz3CmAOgHJqBGDYADMg1gDA2VB48K6Iog2AmuCmAAAdmODiADAtgF8N4L
    -oAMB2IgVABDPcaAAxCcPGRiAjBUCEM9woAAwEESgz3CAABSREHiPGRiAz3KAAMSRUHiWIgIAELpF
    -eJAZGICKIAQAkhkYgJAVABBAl0AZAIDPcIAA0CxTGRiADxEAho7in7gPGRiAzCKiggf0CBEAgIUg
    -hAAIGQCAEQqRAggRAICKuAgZAIAP2BAZAICUFQAQHBkYgAiFHQheB7YM4A8A2L4M4A8B2M9xpgD0
    -zwHYEqEE8KIMwA/ZA0AA8cBqC0AACiUAkM9wgABkuBpxBfTFEAEGAvApgCW5TwkeAM9ygAC0h89x
    -gABwuyaRdooTC0EAxBABBlSKwLkVCYAAxRABBg0JXgEpgB8JXwEKIcAP63IF2M9zAAARCUokAADN
    -AG//CiUAAYQtCxwvd892gABsEPhgyXEqCKAAKdrPcYAAaKUAJ4AfgAAsu14IoAAM2s9woAC0DwDf
    -/KBIhlMiAAB6CyAMNJYeDQADX/+A5dgMYQzKIGEABMgLCJ4ASg4ABAvwANmeuc9woAD8RCGgz3Cg
    -ALQP/KBMIACgiA3iD8ogYgDPdYAAoAQMjYbo5g8ADQHYDK3VAkAA8cBmCkAACiUAkAHYEPIEyBsI
    -nwAKIcAP63IF2IojRw5KJAAADQBv/7hzANiELQscz3aAAGS4ACZPHoQoCwxAJgEZMCFADkmHJbgl
    -ulMgEQBTIhIA6XCqDmAADdmiCqAQqXAJhyW4UyAQAIbtA9g9/IP8BPBuDMAPPQgQIEwiAKDKIcIP
    -yiLCB8ojgg8AABsCyiBiAcb1eg5ACLYPoAAB2M93gAC8tQ8JESAWDIAKGgyAChbwmg+gAADYz3eA
    -ALy1g+3P/AjwGgzADwCHUSBAgBwMwg9MIQCggAuB/6lwDv6KCqABqXAE2AQaGDBdCREgz3GAALSH
    -z3CAAHC7BpBWiREKAQDEFgAWNInAuBkIQADFFgAWEQheAQmGDQheAQCHKQhfAKlwCnF3/3/ZEbnP
    -cKAAsB80oB4JQAgPyAUggA8BAAD8DxoYMACHRQheAM9xgAC0h89wgABwuwaQVokTCgEAxBYAFjSJ
    -wLgXCEAAxRYAFlEgQIEJhtEgYoEI9BiOz3GAAGwQGKkJhgmhAd52D+ALyXDPcIAAsQaeDeALwKgZ
    -DVEQz3CAAFi7FIgNCNEBTCAAoJgLwg9uC8AP/gxAAMYI4AIA2P0AQADgePHAANiM/1IMD//PcYAA
    -tIcWiVoLYBA0iTUAj//xwIYIQADPdoAAZLgIdQsIUQDphgPwxRYPFiW/hC0LHAAmUB4kEAAgwL9R
    -IECByiHBD8oiwQfKIGEByiOBDwAArQLKJCEABAYh/8olAQHPcIAAwBABiMxxs+1Agc9xgAC0h0Ch
    -ABYDQIDgYaEAFoNAaKkAFoNAaakAFgBBAvIPtgAWgEAEIoIPAAYAAAqpABaAQIDiC6kAFoBAAdoM
    -qQAWgEAAFgBBwHoHsQAWAEEIsQAWAEBSqcYOb/8E2DjwIIHPcoAAXLzEHlgQABYBQIDgxR5YEAAW
    -gUAUGkKAABaBQBUaQoDMcAjyIJDPcIAAcLshsAPwAJAAFoBAz3GAAGC8IhoCgAAWgEAjGgKAABaA
    -QCQaAoAAFoBAABYAQQ4ZBIAAFgBBIhkEgAAWAECveID9UgigAalwz3GAALSHVonPcIAAcLsGkJ3v
    -EQoBAMQWABY0icC4HwhAAMUWABYXCF4BCYYTCF4Bz3CAALy1AIATCF8AJBABIKlwJbnAuej+wgnA
    -D1ILQABlBwAA4HjxwADYnP/PcYAAtIcWibYJYBA0iZEGT//xwADZz3CgALQPPKByD4AMQgvADAIJ
    -AAwWCCANANj/2c9wqwCg/zmgAtgGC2AABBoYMF0GT//geIQoCwwAIYB/gABguuAQAgDPcYAAsInc
    -EAMAYBmAgOQQAgDoEAAAXBnAgGwZgIDgf3AZAIDxwHIOIAAS2anBCHbSDGAAi3BKJABxANqoIIAC
    -FiSAMCiICwmSAGG5KKgB4gHCAsGELgscACGAf4AAYLrcGIAABcLgGEAABsG0buQYgADHdYAAEFxI
    -FREQ6BhAAM9wgAAEiQogQC4WIEAECOCDwcoOYAUI2vSFz3CAAASJh8H2eAjgtg5gBQjaAMAAII0v
    -gABkuLUdGBATCB4Auh3YE7sVABaAuAbwuh1YFLsVABaguLsdGBDPcIAAQLhUiDaIRCo+CwAhgH+A
    -AJy2NXgGiBB2/A7h/8oggQO1FQAWUSBAgPHYwCgiAcoggQ8AAJMAwCghAdIJYACgHQAQ2QUgAKnA
    -ANiA8fHApcGLcP4JYAAF2QDCKwoeAM9wgABsEBiIHwhRAADYmrjPcaAAyB8PoQHApBkAAMPYGrgO
    -oSsKngAGEgI2ANlKJAByqCBAA7hxg3EoiQAiQDFkGEIAFQpOAEAlQQBiCUAApcDRwOB+CiHAD+ty
    -BdiKI48DwQIv/0okQADxwM9wgABsEAmAUSBAgcohwg/KIsIHyiBiAcojgg8AABcHyiRiAJQCIv/K
    -JcIAvg0ADMYMYAkB2M9wgABYuxSIRQjRAc9wgABMuwuAOQheAc9wgADotgqQz3GAAKieJYEKuDBw
    -yiHCD8oiwgfKIGIByiOCDwAAIQfKJCIAPAIi/8olwgCiCA//AgvgCwDY7gjAC7IIQAANBE//4Hjx
    -wALYv/zF/f0DT//xwFIMAAAA3s91oAC0D9yl8gzgC2h3+P9WDiAM6XAEyAsIngDKD8ADCPAA2Z65
    -z3CgAPxEIaDcpYEEAACEKAsMz3GAAEy7MCFCDs9wgADgiFZ4dpDPcYAAtIfEGdwAF5DPc4AAsInF
    -GRwAz3CAAASJVngMiJAbAoAA2OB/xxkcAPHAXg1P/zoOgA+yDU//bQNP/+B48cDCCyAARNrPdYAA
    -EFzEbc9xgAAIiSYJYACpcEokgHAA2agggAgUadhgcYCEKQsMACGCf4AAZLgAIYB/gABguroa2AAA
    -27Ua2ABhhUKFAeHcGMAAZYXgGIAARoXkGMAA6BiAAMkDAADPcIAAtIeVBCAAiiEFBeB48cBCCyAA
    -ANqhwUDCABaOQAAWjUAAFoNAABaQQBztqXfPcYAAkKUjiYYn/BdFv8O95nngucoiQgNgwuG5yiJC
    -A8oiIQABHIIwUSGAgMolIRACHEIzpOjPcIAAtIe2iPSIsXPMJsGTEfIKIcAP63JAKwQEEL4F2Ioj
    -XQsFJEQDiQAv/wUmxRMAxUAgDgbPd4AAZLhUGFgDhB9AEyHwz3CAAHC7BpAVCwEAz3eAAGS4xBcA
    -FsC4Gw4AEAohwA/rcgXYiiOdDZhzQQAv/0olAAAAxc92gAAIt90fWBNAIEEgSSEBBjR57g4gAMlw
    -QiDAJUggAAAbCHQAANsA2gAWAUAB4vsK1IAB4/ULBIBWJgAZxg4gAAbZz3CAALy1AIAzCF4Az3GA
    -ALSHz3CAAHC7BpBWiREKAQDEFwAWNInAuBMJAADFFwAWCwheAQmHHwhfAXYNYADJcM9wgADoEKKg
    -iiASDVoIIACpcSoOAAA9AiAAocAA2Ejx8cChwYtwWg4gAAHZABQFMEwlAIDKIcEPyiLBB8ogYQHK
    -I4EPAACuB2gH4f7KJGEAz3CAAJCl5g0gAAMYQgGhwNHA4H7xwI4JAADPc4AApBFDgwDfz3WgACwg
    -sIXSatR+fmalpgSmAeKMIgiAJqZDo4X3AoPjowHgAqPBAQAA4HgA2M9xoADIHxihGaEB2A6h4H7g
    -ePHAPgkgAFlxOXLIcehyAd3PdqAAyB+zpgXfz3WAABAR4KUBpQTASKUJpRWGJ6UKpRiGGB1AEQul
    -GYYUHQARDKWgFgAQZKUNpaQWABAMHUASDqWoFgAQCB2AEg+lz3ABALAJEKUuCWAAKNgRpSYJYAAA
    -2BKlUyfAdROlAshUHQAXFqUSFgCWUB0AFxelExYAls9ygAAQERilFBYAlkokQHkZpRUWAJYA2Rql
    -JBYAlhulFhYAlhylz3CAAOANEIAdpc9wgAAQEXgYgArPcIAAEBF8GMAKz3CAAIwRBBgAC4QaQAvP
    -cKAAyBwIgIgaAADPcIAAgAUAgIwaAACoIIAC8CJDAM9wnwC4/wHhdqCZAAAA/ByItvwcSLb8HAi2
    -/BzItfwciLX8HEi1/BwItfwcyLT8HIi0/BxItPwcCLT8HMiz/ByIs/wcSLPgfuB4BNw43TXw4HgE
    -3DTdM/DgeATcMN0x8OB4BNws3S/w4HgE3CjdLfDgeATcJN0r8OB4BNwg3Snw4HgE3BzdJ/DgeATc
    -GN0l8OB4BNwU3SPw4HgE3BDdIfDgeATcDN0f8OB4BNwI3Rzw4HgE3ATdGfA0FBowMBQZMCwUGDAo
    -FBcwJBQWMCAUFTAcFBQwGBQTMBQUEjAQFBEwDBQQMALHAcawJE0zsCQfM+B+8cDPcYAA4A0QoeB4
    -4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeNHA4H7geOHF4cZA
    -KQ0CJX1ALQMUpXslCjQCCHVTJX6QBvIBHVIQYbr78UEqjgDBukImTpAEHdAQ/fUJ6i8kiXDgeKgg
    -QAEBHVIQ4HjBxuB/wcUocgDZ2PHgePHAsg7P/6HBCHfPdqAArC8ZhgQggA9wAAAA13AgAAAAAdjA
    -eC8mB/AodRpyE/SKIEkG+gzv/4ohTQQ5hu4M7/+KIAkGiiAJBuIM7/+pcQDYJPARzAAcRDNPIMED
    -AeAQeAQggA8AAP+/j7gCHEQwERocMN4JoA9AJwASB+cEJ48fAAD8/wUnABSduJ+47HEAoQDB7HAg
    -oAHYfQbv/6HA4HgiuQbw7HJgogTgYbn5CbWAYIAA2c9woADUC22gz3CgAEQdNaDgfuB48cDyDc//
    -CHYodShwSHFocsr/geDKIIEDwA/h/8ohQQM9Bs//4cXPcoAAsASkis9ynwC4/wXtz3PQuv7KfqIa
    -ojuiDu3PcKAAOC4FgAQggA/AAAAA8QiAj8AAAABp2Bi4GaLgf8HF4HjxwIYNz/8Id89xgACwBAWJ
    -AN6pwUDGiwgRAAHdpanPcYAAgH7PcKAAzCstoADYj7gRGhwwIRqCM6IOoAyLcBoKAAjPcAEAsAlB
    -wIogUABCwM9wgAAEawCIZMUC3REcAjAAwBIcQjMTHAIwz3CAAKQRRcDPcIAAEBFGwM9wgACABQCA
    -Q8Yg2QHaR8BIx4HAPdsXu8L/CNgB2cn/BBpYM1EF7/+pwAPaz3GgABQERaHPcaAA1AsNoeB+8cDh
    -xc9yoADUCwPdsaIA23CiBRICN9dyAAAAQAHawiKKABe6x3IADgAARSICBp26n7rsdUClAtogGoIw
    -CBINNuxyoKIREgI3AeIRGpww7HIAogISAjbscECg7HAgoAHYz3WgAMgfE6U4hexwIKAZhd//dB3Y
    -kM9xoADIOw6BiLgOocUEz//gePHAANgIEoEw3P8IEoUwCiHAD+tyB9iKI9EE7QHv/kokAADgeADa
    -A/AB4kEogQD9CkSA4H7PcYAA4A1AGcAHz3GgAMgfXIGduJ64TRkYgOB44HjgeOB44HjgeOB44Hgc
    -geB+4HgD2s9xoAAUBEWhz3GgAPwLDKngfgPaz3GgABQERaHPcaAACAwAseB+BcwA2tdwAAAAQAHY
    -wiAKABe4x3AADgAATyCBAJ25n7nscCCgz3CgABQEA9kloAISATbPcKAA1AstoM9woABEHVWg4H6n
    -CRAAQCHCA8O5nwk1BCS6MyZBcIAAgFxAJwNyNHsAewAWAUAEGFAAABYBQAQYUAAAFgFABBhQAAAW
    -AUAEGFAAABYBQAQYUAAAFgFABBhQAAAWAUAEGFAAABYBQAQYUAAAFgFABBhQAAAWAUAEGFAAABYB
    -QAQYUAAAFgFABBhQAAAWAUAEGFAAABYBQAQYUAAAFgFABBhQAAAWAUBCIkKABBhQAL714H7hxSLq
    -Y2rBuj0KNQEiuzMmgnCAAJBcQCeNclR9AH0EEAIEBBmQAAQQAgQEGZAABBACBAQZkABCI0OABBAC
    -BAQZkADv9f8Ez//hxakKEABAIsMDw7qdCjUEJLszJoJwgACUXEAnjXJUfQB9ARCCBAEZkgABEIIE
    -ARmSAAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQB
    -GZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAQiNDgAEQ
    -ggQBGZIAv/VTBM//8cDeCc//KHZGIc0AHWUiuZX/wb4dDlAQEQ6QEBsO0RAAFoBAAR0SEAAWgEAB
    -HRIQABaAQACtFQLP/+B4gOHKJE1w4HjoIK0BABYBQQIYVADgfuB4gOHKJE1w4HjoIK0BABaBQAEY
    -UgDgfuB48cByCe//UyFCAE4iDQHPcqAAFATJggDbDiaCHwAAAAZQccohxg/KIsYHyiBmAcojhg8A
    -APwByiRmAPQGpv7KJcYAgOHKJE1wyiLNAOggLQJOYM9xoAA4BAHiyKkdDVAQEQ2QEB0N0RDPcKAA
    -OARoqM9woAA4BGioz3CgADgEaKhdAc//4cUA2g/woIANc6CjoYANc6CjooANc6Cjo4ANc6CjEOAB
    -4kEpAwHjCsSAANsG8AQQDQQNcqCiAeNTIcIAIrrzC4SAANsG8AEQjQQNcqCqAeNTIUIA8wuEgAcD
    -z/8A289ynwC4/xqie6I+os9wAGwEABmi4H7xwHII7/8A2qHBGnDPcNS6/spAwM9xnwC4/2gZAAQE
    -2Buhi3AeoZ26z3CgANAbUaDPcABtABAZoQXw9gjv/4ogSQH7CV7HABQFMHsNgQ/Uuv7KIN3Pc6AA
    -yB+wowHYQxsYAADYjbgA/7Gjz3GfALj/aBkABATYG6GLcB6hANiduBMbGIDPcABtABAZoQXwogjv
    -/4ogCQb7CV7HABQFMAwlgI/Uuv7KyiHBD8oiwQfKIGEByiOBDwAAXAJ8BaH+yiQBBJkB7/+ocM9x
    -gACwBGSJz3KfALj/BuvPcdC6/so+ohqiDuvPcKAAOC4FgAQggA/AAAAA8QiAj8AAAABq2Bi4GaIc
    -guB+4HjxwHIPr/+YcCh2SHXt/wYggQOIcKV5ZP7FB4//z3GgADQfBKEB2AehCIGA6AWB4H7xwD4P
    -r/9KJAACAN3PdwAABB2pdhUigDMcEAEGANjPcqAAFATKoqiiJ6IEoj1liOFoucohDgDpcE/+QiRE
    -ACDn1Qx1gAHmYQeP/+B4QSmBgAnyLyRJcKggwAEEEAIE7HFAoeB+8cDeDo//CHUodmoKYA9AIQAC
    -BczXcAAAAEAB2MIgCgAXuAAggQ8ADgAAB24EIIAPAAD8/yV4nbifuOxxAKECEgE27HAgoCK+BfDs
    -cQChBOVhvvsOtZAAhWj+8QaP/+B4B9nPcqAA1AcaGliADegZEgGGCSBDAA8SAYYCIMCAeWEPGliA
    -9fXgfqHB8cAFEgI313IAAABAAdrCIooAF7rHcgAOAACDuuxzQKPscgCiKHBS/tHA4H+hwPHA4cXP
    -cIAAMHwmiC7pJ4gs6aCQT20XChUCMyaCcIAApFxAJ4FyVHkAeQDZEfAkkAfdgOEB2cB5C/AkkAjd
    -heEB2cB5BfAkkIThAdnAeR0JUAAIEAUBCiHAD+tyENiKI88FgQOv/ph1MQaP/6HB8cCyDY//z3KA
    -AF0JQIqA4kTAi/KN6QohwA/rcgXYiiNPCUokQABNA6/+uHNggQPrQYGI6s9ygACsiHCCYKFRgkGh
    -JMaA5sohwQ/KIsEHyiOBDwAA7wPKIGEB5POA4sohwQ/KIsEHyiOBDwAA8APKIGEB2PMxCF4CBCCA
    -DwEAAMAuuM9ygABQYAhiSSCAAGG4ArgUeMdwgABkmWqgIYEroEXwOQgeAqDmyiWCE8olIRAEIIIP
    -AQAAwM93gAAAYM5nBCCADwYAAAAxuC66HmbPcIAAUGBIYMJ4E/BTIMIAXXrPdYAAMGNNZQQggA8B
    -AADALrjPcoAAUGAIYmG4Fn0SbRR4x3CAAGyYYKAhgR8NNBYhoAohwA/rcgXYiiOQA4okgw9RAq/+
    -uHUI3PMEj//hxeHGz3GAAF0JIIkl6QDbSiQAds9ygABsmKggwAMyazR5JWA+YqCmPWChhRlhoaYi
    -gQHjIqZIEAEGSBpYAEkQAQZJGlgASxABBksaWABMEAAGTBoYAG8Fj//gePHALgyv/7hxz3KAACh1
    -BLkwIkQAosEPDF4Dz3OAAPi7BPDPc4AACLlAIwIGQCMBB1EkQILKIcIPyiLCB8ojgg8AADUEpAGi
    -/sogYgHPdoAAMHhALY0BpmZAxiDFCw4eEsK9qmEN8BMOXhJEJQEcRLkqYom6BfBTJcEQPHkqY89x
    -gAAwdxYhQQEiiQ65RXkgoAkEr/+iwOB4lQDgBwjY4HjxwI4Lr/8B2c9wgAC0KSCgAN3PdoAAuAQW
    -JkATA4CA4OIgAgBAJU2Q+PPGDa/+BtjJA4//8cBaC4//CHXPcIAAtCmgoM92gAAwLoogVwuyCa//
    -IIaKIFcLpgmv/yWGfg2v/gbYHw2QEADdz3aAALgEFiZAEwSAgODiIAIAQCVNkPjzeQOP/+B48cAG
    -C4//CHaKINcMagmv/8lxz3WAALQpbgygAsKlAoVZCFAALwiQAG8IEQFWDIACz3AAAGg4z3GAALgE
    -AKHPcAAALDoBoQDY2f++D6AHBdgj8M9wAABUOM9xgAC4BAChz3AAAMw6AaHE/xYMgAICDIACANgN
    -rRHw9guAAs9wAABUOM9xgAC4BAChz3AAAMw6AaEA2Mb/3QKP/+B48cCKIFcH1giv/3fZANnPcIAA
    -MC4goAHY0//RwOB+4HjxwM9wgAC0KQKAFwieAIogVweqCK//jdkyD6AHCtjv8fHA4cUIdYogFwqS
    -CK//qXHPcYAAtCkCgT8IngDPcIAAfCoAgI3tIrjAuA2pAtjPcYAAMC4CoQPYA6EA2AzwI7jAuA2p
    -BNjPcYAAMC4CoQXYA6EG2AShSQKP/+B48cDOCY//z3WAALQpAoUfCJ8AEBIENgohwA/rcgXYiiNF
    -B2kHb/5KJQAA7gqAAu4KoAIIdgHYDK0tDlEQz3CAAAgF6gqAAqoMwAcIdYog1wruD2//qXGJ5cwl
    -opBwDqIHyiBCA9UBj//xwNoKgALPcIAATIkgiM9wgAAABc9ygAC0KSGoLIrAuSKoANkjqKIKoAIh
    -orIKgAIA2Zu5z3CgANAbMaBt8eB48cDhxQDdz3KAAMQpoKIQ20okgHOpcaggAAIWIkAAYaCioAHh
    -z3CAADgqPgqv/xDZz3CAAEgqMgqv/yTZz3GAADAuoKGhoQjYBaFRAa//pqHxwOHFz3CAALQpAoAz
    -CJ4AiiBXBzIPb/+KIUYJAN2pcKP/qXBW/9P/4v+KIJcHGg9v/4ohRg3PcIAAMC6goA0Bj//gePHA
    -z3GAALQpIoFRIYCAzCBigIANogfKIKIBFfHxwM9xgAC0KSKBUSGAgMwgYoBkDaIHyiDiAQfx8cAK
    -JACAyiHCD8oiwgfKIGIByiOCDwAAvAP8BWL+yiXCAM9wgAC4BBYgAAEjoN8F7/9EoPHAIgiP/wh2
    -iiCYAIoOb//Jcc91gAC0KYogFw56Dm//IYUhhQDfkOEE9AHfwaXJcSUPUBDPcIAATIkVIIIDNXgg
    -iGCKEQnCAAGIIYoJCEIAAIWO6IogVwc+Dm//iiEJD8GlxgygBwPYAdgD8ADYHQCP/+B48cDhxQhx
    -ENgA20okgHPPdYAATImYc6gggAYpCQ4Bz3KAAMQpFiICAQQSBQAhDRUEFSVCEUCKUHPKIEsByiOL
    -AEAkRAAvJAcB3QdP/wohwA/rcgXYGQVv/oojBw/xwFIPb/8Icc92gAC0KQQWBRAbDRQECiHAD+ty
    -BdiKI8oG8QRv/ookgw+eDW//iiBYAIogFw6SDW//IYYBhs91gAA4Kgllgg1v/4ogFwchhihliwhT
    -AM9wgABMiTV44YgQ2AGmz3WAAMQpiiBXDloNb/8ghYogFwdODW//6XEAhYDgyiAhASnyx/8IcQGm
    -kODKIcEPyiLBB8ogYQHKI4EPAAC8AsokwQBoBGH+yiUhABYNb/+KIBcOIYbPcIAATIk1eAGIFwjD
    -A4ogVwf6DG//iiHLAAPYgguAB+EGT//geM9wgAC0KQKAgeAB2OB/wiABAOB48cBODk//enAacVpy
    -AN9AKAEEiiAYAL4Mb/9FeUwjgKPKIcoPyiLKB8ogagHKI4oPAAD8AsokygTkA2r+yiXKAEwiAKTK
    -IcoPyiLKB8ogagHKI4oPAAD9AsokigTAA2r+yiXKAM92gADEKRYmzRQEFZEQiiDXDl4Mb/8qcQ8K
    -QSTPcIAAtCkAgFTwGQkQJAAhgS+AADgqAIlhuACp6XAK8IogVwcuDG//iiFMBAHYOncAIoIvgAA4
    -KiCKTCEApAHhIKrKIcoPyiLKB8ogagHKI4oPAAAYA8okSgREA2r+yiXKBCUIUADPcIAATIkVIEIE
    -FSCABCCIYIoNC0IAAYghihkJAwCKIFcHygtv/4ohzAcEHYAUCB0AFACGDyDABACmSnBH/89xgAC0
    -KSCBA7gleHUFT//xwCoNT/8IdSh3SHZAKAEEiiDYAIoLb/9Fec9xgABIKiARBABMJACByiHGD8oi
    -xgfKIGYByiOGDwAAPAOsAmb+yiUmABYhAAGkqOCgxahAJEAACKE9BW//AtjgePHA4cXPcoAASCoI
    -ghHoz3WAALgEYbgIohZ6YIUEiiCCYHtFis9ygABIKgiC9OgZBU//4HjxwJIMT/86cI7gyiHKD8oi
    -ygfKIGoByiOKDwAAlgPKJEoEOAJq/solygDPdYAAxCkWJU4UBBaQEIog1w/SCm//KnGKINcOygpv
    -/wpxANgCphDYAaYA2Q8hQQQAhSZ4AKU7CBAkTCAApMohyg/KIsoHyiBqAcojig8AAKcDyiQKBNgB
    -av7KJUoEACCBL4AAOCoAiWG4AKkKcCz/WQRP/+B44H7geOHF4cYQ2QDez3WAAEyJn3HJc6ggwAMX
    -CI4DFSWCE0CKUHPKIYsDyiOLAAHmz34ocMHG4H/BxeB48cC6C2//iiCXD0ogACDPd4AAxCkeCm//
    -IIcO3gp1AIcXCE4DFidAEwKAB+hAeAUgAAQvIAcgYb4B5ecOdZCvfQDYAKdMIACgAdjVA2//wiAM
    -AOB48cBeC0//r8EIdwDez3CgAGQu8CDSAxsSEDYbGtgz9dgFuIINb//pcRvIz3WgANQHGh0YkA8V
    -EZYZFQCWKujA5kT3GRUOlv3xABYAQAAWBUAAHEAxIMB7CBEHgcCaD2//DtkjwGG4Y8AMwA7oz3Gf
    -ALj/GqEtwBuhA8Aeoc9wAGwEABmhDx1YlO4KQAcPFRGWz3CgAMAvURAAhgsggITO9c9wAABkHhoL
    -j/+RCM6DGRUAlsToGxoYNPXYBbjmDG//CnEbyBodGJDxAm//r8AKIcAP63IF2IojWQtRAG/+iiQI
    -AOB48cDODk//GQBP/uB4ABYBQSCwABaCQFMiQQAhoEEqwQBSIQEAwLkoqEEqgQDAuSmoQSoBAcC5
    -MKgAFoFAz3GgAMgcKIHgfyOg8cABgBDoMwhQADMIkAAKIcAP63IF2P/bSiQAAOEHL/4KJQABAdnP
    -cKAAyBwpoPINb/8U2AjwAtn38QHZz3CgAMgcKaDRwOB+8cAS6CcIUAApCJAACiHAD+tyBdiKIwUH
    -SiQAAJkHL/4KJQABKdgSuAfwFdgTuAXwT3or2BK4NXhAoOLx8cDhxQh1lg1v/xTYI4XPcKAAyBwo
    -oB0CT//gePHAnglP/6XBi3fpcMb/6XDU/yLAFugAFg5BJMAD6AAWAEEA3QnwAcAAFgJAyXHf/wHm
    -0H4B5QAUATHvDUSQE/AA3QzwABYBQQPqABYAQQHAABYCQAHl1f8AFAEx6Q1kkCTCJMCF6AsJHgAA
    -FgBBBczXcAAAAEAB2MIgCgAXuMdwAA4AAIO4nbifuOxxAKECEgE27HAgoOlw0/8mDG//AdgA2c9w
    -oABEHTWgXQFv/6XA8cABgBPoIwhQACMIkAAKIcAP63IF2IojBAlKJAAAkQYv/golAAEC2ALwAdjP
    -caAAyBwJoZoMb/8U2F7x8cAS6C0IUAAvCJAACiHAD+tyBdiKI4YDSiQAAFUGL/4KJQABKdgSuPAg
    -QAAAokbxFdgTuPrxK9gSuPjx8cB2CE//pcGLd+lwfP/pcN7/ABQBMQXMArnXcAAAAEAB2MIgCgAX
    -uMdwAA4AAAvhBCGBDwAA/P8leJ24n7jscQChAhIBNuxwIKAAFAEx7HAgsAkUgDAI6M9wpgCcPxmA
    -+QhRgCLAFugAFg1BJMAE6AAWAEEA3gnw7HIBwKlx0v8B5bB9AeYAFAEx8Q5EkBLwAN0L8AAWAUED
    -6gAWAEHscgHAyf8B5QAUATHtDWSQJMIkwIboCQkeAAAWAEHpcID/6gtv/wHYANnPcKAARB01oFnx
    -4HjxwKIPL/8B2AAWgkAAFopAABaJQAAWhkBEJr6DRCKDE8B4CiFAgsohYgAB4YDjyiOBAMojIgCA
    -4MogQgLKICEAQNwEIguTG2NveyT0BcwB3ddwAAAAQBJrwiVKEwzgF70EIIAPAAD8/8d1AA4AAKV4
    -nbifuOx1AKUCEg027HCgoOx1AB2CEuxwYKgA2+xwYLDlCXQAANj4cBlxgeDKI4EByiJBAsojggJE
    -I4EDguFKJUAAwiVCAVIjDgDAvkQjAAyQ4AHbwHug4AHYwHgFIMQAABYNQGG6T3qW6SMKdAAA3yCF
    -gOYE5QT0ABYNQAkLERDscCCgAeftD4SQIIUJCxEQ7HAgoAYlPoES8h8KdAAA2AAWAUCA5iClBOUE
    -9AAWDUAB4PEIhIAAFgBAAKULJECBHPIpCnQAANgAFgFA4IUE6+d5A/DleSClgOYE5QP0ABYNQAHg
    -5QiEgAAWAEAghQTrJ3gD8CV4AKVCIEEQKwl1gEAnQAANCxEQSgpv/wHYB/AD2c9woAAUBCWgANnP
    -cKAARB01oHUGD/9RAk//8cAGDi//ANnPcKAA0A81oAAWA0EAFgJBBcwxC14C13AAAABAAdjCIAoA
    -F7gAII0PAA4AAEAiAQPPcAAA/P8keKV4nbifuBPw13AAAABAAd3CJUoTF73HdQAOAABAIgEDz3AA
    -APz/JHileOxxAKECyOxxAKHscECw7HEA2ACxhQseAiNqBCGBDwAA/P8TC94Az3WgADgECK0B2GG5
    -MHkdCx4BoWgIvQV9z3agABAEuLYC4A94YrkweQDdFPDDaBi+4mjvfxC/5X7haO9/CL/lfgV+z3eg
    -ABQEy6cE4A94AeXaad0NhJMA3gjwz3WgADgECK0B4A94AeZTIU0A7w5EkxELXgEB2c9woADQDxEY
    -WIATC54BA9jPcaAAFAQQoQHYBKERC94AABaBQOxwIKhhuhMLHgEPCpQAABYBQexwILBiukQjgYFB
    -KoAAFfQA3gvwz3WgAAAE7I0AFo1A7HXgrQHmsmgPDkUT6QvfgQAWj0D28S0JkQAA2Qrwz3WgANQD
    -3JUAFg1B7HXAtQHhG30RCUUD6wvfgQAWDkH38SsLngCA4MokDXDgeOgg7QMTC94Bz3CgAJgDPYAA
    -FgBAA/AAFgFA7HAgoADZBvAAFoNA7HBgqAHhUyJAAPMJBIBKCG//AdgA2M9xoADQDxEZGIDPcaAA
    -FAQEoQTIz3GgANAPIrjAuBWhaQQP//HAAgwv/wDZSiQAcqggQAIAFgJAFSJAMBwYmAAB4QAWDUAA
    -Fg5AngxP/89woAAUBKygz3CgANQL3KAOCE//MQQP/+B44cXhxiSIz3KAAKxcpojCuS5iANkPIYED
    -z3OAAIyJdhMCBobtJnp2G5gAHfBFeXYbWAAliBUjjQN5HVgQJohFiFlhfB1YECCAjCEQgET3iiEQ
    -ACCgI7l3G1gAAIAquHgbGAAA2c9woADwNiygeRMBBiWgfBMBBiagehMBBiegfRMBBiigexMBBimg
    -fhMBBiqgdxMBBiugeBMBBi2gdhMBBiSgwcbgf8HF8cDhxaLBi3WpcJYPL/8C2alw0v9GDw//cQMv
    -/6LA4HjxwIjoz3CAAGSLLgwv/yTZ6QDP//HA3gov/5hwkODKIcYPyiLGB8ogZgHKI4YPAABbA4AA
    -Jv7KJSYEANpKJAB0z3aAAMwEqCBAD0AsgwFVe8dzgAAweCCDz3WAACh1QCwAAd25AGUgo/G40SEi
    -ggnyoIvPd4AAAGCtZxcNkxDPdYAAMHcWJQ0RoI0LDR4QnrkV8C24wLgVJg8Q44dSIU0CCydAkwzy
    -z3WAAIS4hCgLDDAlQB7bCJ6Hn7kgowHinQIP/+B48cAeCg//ABYSQQAWAEHPcYAAKHVAKgAhAWGi
    -wUEpQANTIBMATCIApMohxg/KIsYHyiOGDwAA/QSOASYAyiBmAVEhQILKIcIPyiLCB8ojgg8AAP4E
    -Bdi59M9wgAAwdxYggAQ6cFYOL/8C2c9wgACwdxYggARGDi//AtlAKpAhz3WAADB4ACUAFDIOL/8Q
    -2YtwKg4v/wHZACUAFEYJYAsQ2QERgCCQ4Mohyg/KIsoHyiBqAcojig8AACEFyiRqADAH6v3KJYoE
    -SiQAdADYqCDBBxUgASAwJUUQBCWPjwAAAAEEHEAxP/Ihxs9xgAAAYAQlhA8GAAAAy2FBLEEEoOZ6
    -YdEl4YIq8gTvFQuTAAQlhA8AAAAkRQyADwAAACQ9CdUACwmRABrvNQuRAATvzOYW9s9xgAAwfCaR
    -IQnCACEN3gLPc4AAhLiEKwssMCNBDgQhvo8ABgAABPQA2wPwAdtvewPwAdpIcwQlgQ8BAADALrnP
    -doAAOGMpZjByAdnCIU0AgOPMISKAEvIB4AIRgCDPcYAAUGAIYT8IUAAKIcAP63IF2IojFA4R8M9z
    -gACEuIQrCywwI0QOCiHAD+tyBdgxBu/9iiNUDUokQAAlBu/9SiUAAAMRgCAIYYLgyiHCD8oiwgfK
    -I4IPAAA6BQXY7fVKcFj/z3CAALB3FiCABECQz3EAABgVCSJBAG4ML/8gsGkAL/+iwPHAGggv/wLZ
    -z3CAAMwEcg4P/89wgADMBECAz3agAOwnz3egAAREz3WAADB8eQoeACuGRCKAAIYi/w4iuqG5FLq0
    -uQV6BSGDAAQhgQ8QAAIABCKCDxAAAgBrpiV6RacolYfhzCGigQ/0z3GgAMgcB+gB2B6hqgmACwXw
    -ANgeoRIKgAsElV0IUQHPcIAAzAQAgFEI3gAE2c9woABEHSWgI6AkoCDwz3CgAMgcAdk+oAuGgbgL
    -pmoJgAsElR8IUQHPcIAAbBAIgBMIHgAA2JS4BacLhpS4BfAA2AWnC4a0uAumggsP/50Hz/7hxTRo
    -z3KAACh1IWItucC5hCkLDAAhgX+AAGS4SIFRIgCAz3KAAJClQYIJ8jyJgOHFIoEPAAAKAgPyRSJC
    -A0okAHQA26gggAI2aHV5ACGND4AAMHhApQHjAN3Pc4AAMHcWIwIAoKqhqgHZIqoD2SOqSiQAcalx
    -qCDAAXphFnqkqgHh4H/BxeB4JQSP/yEEj//xwAAWAEDPcYAAbCoAoR8IUQAAFgBADLgEIIAPAQAA
    -8AGhABYAQAKhEfCC4AAWAEAL9EYgwgBDoQAWAEDPcKAA0BteoAPwABYAQAXM13AAAABAAdjCIAoA
    -F7jHcAAOAACDuJ24n7jscQChAhIBNuxwIKBSCS//AdgA2c9woABEHTWgKQSP/+B48cAAFgJAocFA
    -wgEUgDAPCB4Az3GAALCXBPDPcYAAyJdAoWCJAdoI8AAWAEAVIYwAAKQB4n149QiFgBcLHgAAFgBB
    -A/AA2BUhjAAApAHi+QqUgQXM13AAAABAAdjCIAoAF7jHcAAOAACDuJ24n7jscgCiAhICNuxwQKDC
    -CS//AokA2c9woABEHTWgocDRwOB+8cDhxQAWA0DPcYAAAABgoQAWAkAA3UGhABYAQAKhABYAQAOh
    -pKElC94H/7pA2M8g4gfKIIEPAADQAM8g4QfPcZ8AuP8doQbwz3CfALj/vaAFzNdwAAAAQAHYwiAK
    -ABe4x3AADgAAg7iduJ+47HEAoQISATbscCCgMggv/wHYz3CgAEQdtaB9Bc/+4HjxwOHFz3WAAMwE
    -BG0aCy//CNkBhc9xoAC4HgKhAoUDoSYJD/9RBc/+8cDhxaHBAN1AxQAWAUAAFgBAOQlQAAXM13AA
    -AABAAdjCIAoAF7jHcAAOAABFIAADnbifuOxxAKECEgE27HAgoOxwoKCpcCDw4g2gC4twBcwB2ddw
    -AAAAQAHYwiAKABe4x3AADgAAhLiduJ+47HIAogISAjbscECg7HAgoADB7HAgoAHYcg/P/s9woABE
    -HbWgvQTv/qHA4HjxwDYMz/4KJgCQOnFP8i8ogQNOII0H2tiaCu/+qXEbGlgzQCUAFEogACAPIBAg
    -9dgFuEYO7/6pcRvIz3egABQECqfPcaAAZC7wIQEACYeS6M9woADAL1EQAIYLIECACvTPcAAAsB4u
    -DA//CyAAhBb02thCCu/+iiGaCymHNgrv/trYz3GgAMAvUREBhiYK7/7a2G4M4AYqcDIJoAKpcADY
    -DyBAAwYmDpCz9c9xgABgBQCBB9obGpgwPQjQAc9woAA4LgWABCCAD8AAAAAhCIAPwAAAAPXYBbjP
    -c58AuP8ao1ujadgYuBmjAdgD8ADYCQhRAEChz3CgABQESqCZA8/+8cDhxQISDTYAFgBBABYBQcW4
    -grm7/3IP7/4CGlgzmQPP/uB48cAOC+/+gNjPd6AAwC+lFxKWFBcRlgDepR+Yk89yoABkLhQfmJMv
    -KwEATiOBB/AiQwBlfgDbDyNDAAYgwID19U8mwBakHxiQpBcAlv0I3oejFwCWBCCADwAAAA+MIBCA
    -+PPz2AW4gNnqDO/+n7kbEhA29dgFuAfd2gzv/qlxz3CgABQEqqAbGlgzB/AD2c9woAAUBCWgz3Cg
    -ABQEqYAe7XbtQS2AkAryLyQJcOB4qCCAAQAWAEDgeFMlTZAJ8i8kSXPgeKggQAEAFoBA4HjPcKAA
    -FASpgObx89iWCi//BbjBCN+H9dgFuGoM7/4Kcc9xoAAUBCgZAAQbGhg0I+4vKIEDTiCBB5ThyiJF
    -AIT3KHKAIsIBz3CgABgs8CCDAJThyiJFAIT3KHKAIsIEz3CgAGgsVXhgoADYDyBAAAYmDpDf9YDZ
    -z3CgANAbMKClH5iUFB9YlBUCz/7xwLYJ7/4X2bfBi3dCDu/+6XAjwEohQCBTINIAhiD+A0IoEAEh
    -CjIkDByCNAohwA/rcgXYiiPODQokQARFB6/9CiWABBLGLb4gwMC+QCoNIcd1gAAodVEgAIAAhYYg
    -9w819IDgyiHBD8oiwQfKI4EPAAC+AwXY4vMBwALBSnJqDCAEZm0f6MlwpgngAEpxDRSAMIUgwQAN
    -HAIwiiD/D1PAAIWpuAClSnBmCeAA6XHPcIAAhATVeCCADyGBBCCgKnYC8ALeSnBz/gbwgODKJkEU
    -yiYiEq8OURATwQCFEsImeER5JXgApQwdAhTPcIAASHYA2RYggARAhSCgIaALCl8FANmLuSGgDwqe
    -BSGAhSEBDiGghg+gAOlwDRSBMAsJXgFYFAAxBbUNCV4AUBQAMQK1DwkeAUpw3g0gBFUUgTANFIAw
    -PwjeADXBVhQCMUpwOg4gBBLDuHCMIAKAyiHBD8oiwQfKIGEByiOBDwAAKwQUBqH9yiRhAFElwIHK
    -JiIRSnBZ/QXM13AAAABAAdjCIAoAF7jHcAAOAACDuJ24n7jscQChAhIBNuxwIKA6C+/+yXAA2c9w
    -oABEHTWgWQDv/rfA8cD6D4/+pMEB3YHAggzv/qlxAN5N8ILAdgzv/gLZAsCLcrYJIAQDwaR4LyUH
    -kEDyAMEA2M93gAAodQ8gQAAEuSFnLyEKIC25UyEQAM9xgABcBUCBBCGAoAChB/SA4hAIIgnKICII
    -IMDqDCAEENkAwQDYiiMIAFRp+mICsmCigNtoqmmqz3KAAIQEFSICBGCCBCNDBGCiz3KAAEh2NnoA
    -ogGiz3KAACh2NHoAsgHmIcBnDgSQBczXcAAAAEAB2MIgCgAXuMdwAA4AAIO4nbifuOxxAKECEgE2
    -7HAgoEYL7/6pcHkHr/6kwPHAhggABF4Lz/4ZBU//4HjxwAoPj/6EKAsMz3KAAIQE8CINAAAhgX+A
    -AGS4aIEEI4IPgAAAAEQjDwIvuga/RX8EI4IPAAEAAEEqTgMsuuV+RX7PcoAAzAQVegOCZQ4AEAQj
    -vo+AAQAAIvLPcIAAWLsUiD0I0QHPcIAAvLUAgDEIXgC+u2ihRCMAAga4BCOBD4AAAAAvuSV4BCOD
    -DwABAABBK0EDJXgsuwUjDgDDogrtLylBA04hgAcQJQ0Q4Pz67cEGj/7xwKLBi3B6DO/+CNkAwM9x
    -gAB4BAChCOgGFAAxA7EEFAAxArF6Cs/+osDRwOB+4HjxwKTBi3BKDO/+ENkFzNdwAAAAQAHYwiAK
    -ABe4x3AADgAAg7iduJ+47HEAoQISATbscCCgAMBRIACAA8AG9ALBOgigBADaBfD6CiAFAcH6CM/+
    -ANnPcKAARB01oKTA0cDgfuB4MNnPcKAAUAwioMHZz3CgAAQlIKDgfuB48cCuDY/+z3AAAEQc8g3v
    -/gDecdjqDe/+BrjPcAAATBzeDe/+CN3PcAAAyBvSDc/+z3AAAMwbyg3P/s9wAAAIHL4Nz/7PcAAA
    -BBy2Dc/+z3CgANQLOIAcgM9wnwC4/1gYAAgAJoAfAADAG5YN7/4E5mG98w1VkADeBd0AJoAfAAAA
    -HH4N7/4E5mG98w1VkI0Fj/7geM9xoADQDxkRAIYcEQCGz3CgAMgfFRAChh6Az3CgAMQnGRAChpwR
    -AgAVEAKGLRAChi4QAoYvEAKGMBAChoARAgCEEQIAoRAChpARAgCiEACGlBEAAJgRAACMEQAAiBEA
    -ABiBz3GfALj/WBkACM9xnwC4/1gZQAjPcKAA0A87gDmAz3GmANQEFxAAhiwRAIAwEQCAOBEAgM9x
    -oACIJACBAYECgQOBBIEFgQaBB4Fg8eB48cDhxc91gACIi6lw5gjv/gPZAYXPcaAAgCUMoQKFDaEA
    -jVEgAIAA2I64BPIPoQPwEKF+CM/+qQSP/uB48cAmDI/+z3WAAOAEAIXPdoAAFJHkkOlxNgmgA4Yh
    -/AMacA0I3gAfhoC4H6YghQCROGAApVQWgBCS6Olwug/gBoYg/AMJ6BkIHiDPcIAAbBAJgA0IXwAf
    -hoK4H6YtBI/+8cDKC4/+osHPcIAAFJE+gAQhgQ///w/QBCWAXwAA8C8leM91gAAUkc4P4AYepYDg
    -VAMhAJgdABDPcYAAAAAAgTUI3gIBgeu4QNjPIOIHyiCBDwAA0ADPIOEHz3KfALj/HaIEgQHg07gE
    -oQUggA/Q/gAAFqIPDd5Rz3CAAMAQAogF8AOFEg/gAySFXoVEIgEMlB0CEAsJEQiA2JQdAhBAKAEG
    -xwjfAYK5IwqeU0QiPtMK9M9wgAAUkQGADQgeALIIAAcV8KoJAAcR8EUhAAbPcYAAoJEoiYYh/Q9S
    -IcEBRbkleM9xoACIJBChz3CAAGiRAIiE6BMKn1LPcKAADCQTgFMgwIBJ8kQiAFNBKIEATXCGIPwD
    -QSgCAc9wgAAUkRMNnlEEuVlhx3GAANAsEvAVDV5TdGlbYwAjgQ+AABAtCvAVDV5SBLk6YgAigQ+A
    -AFAtrBhAAKwQAgAf6iCKlxhCADzYAKoZ8LO6XqVRIoDTxSGCDwAAAAdFIQAGz3GAAKCRKImGIf0P
    -UiHBAUW5JXjPcaAAiCQQoYoh1gDPcKAAgCUvoM9xoADEJ0ERAIZRIsDTzyDiAtAg4QJBGRiAz3WA
    -ABSRAJUEIIAPAADMgBUIgQ8AAMiAC4UNCB4AAg2AA03wHoVUFYIQywjeBBoRAIYFIIAPAAAAmhoZ
    -GIAH6gHaz3CgANQLUqAE2BAZGIBNcTIIr/6KIEQOBvBqCq/+iiCFDQkIn0T1CR7Gz3WAABSRz3ag
    -AMQnLhYBlhaFInhkuBB4hh0EEM9xgABsECYPYAcvkRoWAJYEIIAP////ABoeGJARFgCWEwjeAgDY
    -i7gTHhiQGtgZHhiQHoVRIICBANmP8hSVUSBAgYv0z3CgACwgD4CA4IX0ENhBwM9wgAC8tQCAIwhe
    -AB8NXlMB2EDADPAH6gHaz3CgANQLUqAE2BAZGIDb8UDBK4XPcIAA+LSLcwQhgQ/AAAAAwoA2uYHC
    -QCAEC1cOThDhlceAcL/0JEEACCbOE0cJgwOUFYEQPwnfAc92oAAsIC+GmenGhjyVEwmFA89xgADE
    -mcKBJYAfDkEQBOsC2SCjI4CDuSOgBeoggqa5IKIBwg3wI4ABwhcJ3gAA3p6+z3OgAPxEwaOjuSOg
    -K4UkoCOFJaBUFYAQB+gAwILgzyJiAQL0h7oAwUHCVSVAGt4IIAIA2x+FlLgfpR6FkLgepQ3wz3GA
    -AMh8DYEB4A2hENnPcKAAkCM9oJkAr/6iwM9wpACQQU2Az3GAAOyaQrEagAOxBCCAD/8AAAAwuASx
    -z3CAAOyaANoRCF5Gz3GAABSRMYELCZ4CQrBDsESw4H9ZsOB48cDmD2/+mHDPcYAAFJEOkc92gADs
    -mgC2z3CmAOj/C4DPdaQAtEUDpgwVA5YNFQKWRBGJAC8nxwD/2BC4KXSEJAOcBCMIAAT0WwkfEDIV
    -AJZTII8A/2cBtv/Y9H8IuO9/ZHhALwUSACUGAAAnxwMFJsYBQC8AFgQjgw8A/wAAQC8HFBtjACDI
    -Ef/YBSYGAgi4BSODAQQiBgD6YgAmQAEFeuW2b3gEI4MP/wAAACi7ZXhPegO2RLYEFQCWArYRgR8I
    -HgLPcIAAAGAyIEACDwiSAM9wpgDo/w2AA/AA2AamBaYA2EokgHAG2o26qCBAAynbErvwI48AQCYD
    -HxV7AeLgowHgAJE4HgARVSZBFBq2z3CAAGCXBgyv/gjaGxUAls9xpQDYyxmmHBUAlhqmHRUAlhum
    -DoEcpg+BHaYmFQCWHqbPcKQAkH8cgAUHb/4fpuB48cCGDm/+ANvPcaAAyB9AEQAGz3egANAPGRcA
    -ls9yoADEJ08SDoa4gc9wgAD4tKigEczPdYAAFJELDgAQH4ULCJ4AAd4E8BEanDNodlISEIYVEhOG
    -G9gWGhiAEQvfIFEgQKBKIgAgB/QdhQHeWnaEuB2lDQseIVQVgBAE6ADYBvAdhYW4HaUB2DpwTCIA
    -oMwhIaBY8s9ynwC4/1gaAAgQh89wgADAEA+IFqIA2s9woAD8RJ66QaBloB6FsLgepagVABBk4B6h
    -ENgOoQHYFRkYgLYJr/4J2BcIX0fPcYAA4A0LgQHgUg9gAguhvgpAAhsJECDPcYAARH0FgQHgegtg
    -AgWhOQIAAM91gAAUkccKECAdhYS4HaXPcIAARH0RC94gIoAB4SKgiiCFCQfwIYAB4SGgiiDFCNYL
    -T/7aDkACS/BCEgCGBCC+jwDAAABD8gG1HoV7CN4EiiCEDrILb/6KIRADJgiABwCVhiD8AIwgAoAx
    -9IoOQAev6APYEh8YkOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
    -4HjgeOB44HjgeOB44HjgeOB44HgSHxiQE8wRGhwwBfAAla4LoAg0lawVARAI6ZcVgBAAqQDYrB0A
    -EFQVgBAh6M92oAD8JTSGAdrPc4AARH0GgzhgBqMF6c9xgACZCUCpU4Yng1lhJ6M+hQHenwgQAJsJ
    -3gEB2c9wgACEBSCgRfAhCB4gAdnPcIAAmQkgqM9xgABEfQOBAeADoT6F6/ED2c9woADUCzGg4Hjg
    -eOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
    -4HjgeDGgE8wRGhwwGQoRIB2Fz3GAAER9grgdpQSBAeAEoQHeHoUXCB4ElRWAEKQVARCpcg4P4AIB
    -2wPwdgpAAx+FDwgeAM9wgADgl44OgATPd4AACJ0ZhwbougoABADYGaeGCUACz3CAAGwQCIAjCN4C
    -j+4EIIAv/wBf/+r+z3CAAOyaoNnE2j3bkg1v/he7HoXwuJALAgTPcIAA+LQAgIDgmAziDcogYgCl
    -A0/+8cBKC0/+z3GAAMSRz3CAAOAEIKAA2c9ygACQkSmiz3CAAPi0JKAloCyiz3AAAP9/z3GgAAwk
    -AaEb2AShz3aAABSRLQgeRB2GhLgdps9wgACQBCCABYEB4AWhiiCFCXIJb/4kgQYIQAJTAgAARBaA
    -EPGGwrgEJ48fAAAACFQWghD7f891oADEJwDZFerg2r8dmJCU2pUeghAE289ygABYBWCiAto8HYCQ
    -z3KAAMSZIaIH8EDZvx1YkNTZlR5CEAAgkQ+AAGS4wBGBIAAgkg+AAFy8uBKAoAUh0wMeCKACBSDQ
    -A4Dg6/IB2BAdGJDIEYAgz3GAAByY5XgbpmwWgBDDuBx49CEAAGQewBReHgQQwBKAoOV4HKZwFoAQ
    -w7gcePQhAADPcoAAPJhgHgQQZBaAEMO4HHj0IgEAaB4AFIoeRBDPcYAATJj0IQAAjh4EEGgWgBDD
    -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
    -4H8AgOB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7g
    -eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
    -4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H8B2OB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
    -fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwHY8cDPcIAA
    -RL56Ca/wA9kyCY/w0cDgfuB4AtjPcaAAwB0NoSHYBqEB2Aeh4H4A2c9woADAHSegJqAtoOB+z3GA
    -AEQJDQhRAAHYAKkBqQCJgeDKIIEPAADECcoggg8AAIAA4H8BoQDYz3KAAEQJAaoAqs9xgAAwfAaJ
    -COgHiQboAJEJCJEDAdgAqgDY2vHxwOHFCHXPcIAAwBABiCsIUQAH8IIIT+8KDW/wT9jPcKAA1AsY
    -gADZQiAACIDgyiBMAOUIRIOtBE/w4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjxwAohwA/rcgXY
    -JttKJAAAxQFv7wolAAHxwAohwA/rcgXYK9tKJAAArQFv7wolAAHPcAIAKBvPcYAATAkAoc9wAgAk
    -GwGhz3ACACwbAqHPcAIAMBvgfwOhz3ACAKgaz3GAAEwJAKEBoQKhz3ACAKwa4H8DoeB+4HjgfuB4
    -4H7geOB+4HjxwJYLb/Bq2KLBi3EB2sII4ABIc43oCiHAD+tyBdiKI88LiiSBCi0Bb+9KJQAAgcFE
    -2AHamgjgAEhzjugKIcAP63IF2IojzwyKJAEBBQFv70olAAAEFAAxXwiCDwAAMgRAJIEwa9gB2mYI
    -4ABIc47oCiHAD+tyBdiKI88PiiTBCtEAb+9KJQAAAhQAMc92gABcCRt4QSjFAEwlAIoEHkAR0fYK
    -IcAP63IF2Ioj0AClAG/viiTBCh3Yz3aAAFwJAaa4cAAUADHPdYAAXL5ALYIAqXH+D6AAAduN6AAU
    -BDEEFgUQCiHAD+tyBdhpAG/viiNQA0GGJQpyAADYFiUBEGCJhiP/DSO7DwtRAGGJA+tiu2GpAeDn
    -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
    -KMARBAAAYQAAWDgAABMkAQATJTgcwBEAAAAhpHOAgQAAwBY8BMARMAWAgQAAwBYEARtiEATAEAMA
    -GyRUBMARJATAEQgEwBBkc4CBAADAFwgEwBBAc4CBAADAFwAAGyUDHBtiQAAbJDAcwBEFAABhNAWA
    -gQAAwBYPGxkiCASggTjwxIAAABskAgAbJTgcwBEAAAAhMAWAgQAAwBZMBMARNAWAgQAAwBYPGxki
    -SASggTjwxIAAABskAgAbJTgcwBEAAAAhAAAAhTAFgIEAAMAWDxsEIhAEG2YPARtoFBzAEAoAG0AE
    -ABtuAwAAYQ8cHSIBAB0m+Q8AYWQMABAAwAYRAQAEJ/wABGQAABskAgAbJTgcwBEAAAAhAAAbJUAA
    -GyQwHMARAAAAIQ8cHSIYAR0mGADHEPyagIEAAMAXIADHEASbgIEAAMAXAAAAIbQygIECAFxuEQAA
    -YfhBxBAPGwkiAAsJOQIACmIDAQpiBAIKYgAACUAEAABhCQAJQAIAAGEKAAlAAAAAYQIACUEACRoo
    -AADAFgEAGyYAAMAXBAAdJgEACCfpAAhkAAAAIQAAAACMAQAAAQEBAQEAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AABoOAAALDoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSMgAAAAAAAAAAA
    -AAAAAAABAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwACQANAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAMAAADImoAAAAAAAAAAAABAn4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAD/
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiKSAAOSZAQAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAA
    -AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAEBAQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAABAAIAAAAAAAAABwAAAAcAAAAHAAAAAgAAAAIAAACDAAAAkgAAAOgA
    -AAD3AAAATgEAAF0BAAAAAAEAAgAAAAYACAAJAAAABwAAAAAAAAACAAAAAgAAAIMAAACSAAAA6AAA
    -APcAAABOAQAAXQEAAAAAAQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAAgwAAAJIAAADo
    -AAAA9wAAAE4BAABdAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiagAD8/wEAAAAAAMiagACgBgIAAAAAAAAAAADI
    -moAAOAgCAAAAAAAAAAAAAAAAAMiagAAAAAAAAAAAAAEADwBkAAEAHAmAAAAAAAAAAAAABwAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAKgaAgCoGgIAqBoCAKwaAgAAAAAAHQAA
    -AAAAAAAAAAAAAAAAAAAAAAB/fwABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIECAAIECAAAAAA
    -AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACs
    -CAAAFQAAAAwvgACAKgAAgCoAAIAqAAC8QAAAgCoAAIAqAABAPAAAgCoAAIAqAACAKgAAgCoAAIAq
    -AACAKgAAgCoAAIAqAACAKgAAIB4AAMgfAADgHwAATCEAAMwhAABQIQAAgCoAAIAqAAAETQAAxE4A
    -AKxPAACAKgAAgCoAAIAqAACISwAA7GEAAOhhAABAYgAAgCoAAIAqAACAKgAAyEIAAIAqAAAkYgAA
    -gCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAADAQAAAgCoAAIAqAACAKgAAgCoAAIAqAACA
    -KgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAq
    -AACAKgAAgCoAAIAqAAC0QwAAgCoAAIAqAACAKgAAgCoAAIAqAACYRAAAgCoAAIAqAACAKgAAgCoA
    -AIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAAAYaQAAgCoAADxqAACAKgAAgCoAAIAqAACAKgAA
    -gCoAAIAqAACAKgAAgCoAANRsAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACA
    -KgAAgCoAAAh/AQBYggEAgCoAAKSEAQCAKgAAUIYBAHRTAQCAKgAAgCoAAHBQAACAKgAAgCoAAIAq
    -AACAKgAAgCoAAID4AQDU+AEAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoA
    -AIAqAABodAAAgCoAAIAqAACAKgAAWP4BAIAqAABAAgIAgCoAACgpAgCAKgAA8CQAAPQkAACAKgAA
    -gCoAANAZAgAodwAAgCoAAIAqAACAKgAADPwBAIAqAACAKgAA3EwBALCdAQCAKgAAgCoAAIAqAAB4
    -pgEAkFQBAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAGypAQCAKgAAyBgCAMwYAgDYGAIA3BgCANAY
    -AgDUGAIA4BgCAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAGBSAACAKgAAgCoA
    -AIAqAACAKgAAgCoAABwYAgBsGAIArEYAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAA
    -gCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACA
    -KgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAqAACAKgAAgCoAAIAq
    -AAAkSAAArEgAADxJAADwSQAA3IUAAMhJAACAKgAAgCoAAIAqAACAKgAAgCoAABxIAAAgSAAAgCoA
    -AIAqAACgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAMAABgDAAAYAwA
    -AGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAA
    -YAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAABgDAAAYAwAAGAMAACQ
    -DQAAAAAAAORZAQBgDAAAhAkAAGAMAABgDAAAYAwAALQJAADMPAEA/IcAAGAMAABgDAAA6AkAAOgJ
    -AADoCQAA6AkAAOgJAADoCQAA6AkAAGAMAABgDAAAYAwAAGAMAADQCwAAYAwAAGAMAABgDAAAYAwA
    -AGAMAACUDQAAYAwAAGAMAABoCQAAAwAAAOQMAgACAAAAyGcBAAQAAAB4aAEABQAAALANAAAGAAAA
    -NDMAAAgAAABIGAIAEwAAAGT5AQAJAAAA3AMCAAoAAADkGAIADgAAAMyaAQAPAAAAfIgBABAAAAC0
    -iAEAGAAAAExZAQANAAAATIABABcAAAAkdwAAEQAAAFCGAAASAAAA5EsBAAEAAADc/QEAFAAAALin
    -AQAVAAAA4J0BAAcAAABEbQAAFgAAABgpAgAZAAAAkA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAACAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAEAAAAAEAAAABAQAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//
    -////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAA4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e
    -4eEDDh7hPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwVFRUVPDw8PBUVFRU8PDw8AAAA
    -AAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8FRUVFTw8PDwVFRUV
    -PDw8PAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8
    -PDw8FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAAkAYAADH6rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6
    -rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6rwCQBgAAMfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqv
    -AEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAEMFAAAx+q8AQwUAADH6rwAAAAAA3sMJAAAAAAAAAAAA
    -AAAAAIwrAQABAAAAzC6AAAAAAAAAAAAAAgAAAAMAAAAAAAAACAAAAAAAAAAwjBEAIL8CAAAAAAD8
    -KwEAoCwBAKQtAQBMLwEApC0BAEwvAQD8MAEAhDEBAOQxAQCAgICAgICAgAGAAoCAgICAAAAAALQ3
    -AQC0NwEAAAAAAAAAAAAAAAAAAAAAALQ3AQC0NwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AMwugADMLoAApCCgADggoAABAAAA/P///wAAAAAAAAAA7C6AAOwugACoIKAAPCCgAAgAAADz////
    -AAAAAAAAAAAML4AADC+AAKwgoABsIKAAMAAAAM////8AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA
    -AAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAA8EwBAAUAAAAML4AAKFIBAAD/AwBIUgEAAP8FACxT
    -AQAA/y0AUFMBAAD/PQAIUwEAAP8EAOxSAQAA/yUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAACUWAEABgAAAMwugAAAAAAALAEAAF4BAAABAAAAAQAAAAEAAAABAAAAAwAAAAAAAAAA
    -AAAAxF8BAMBgAQA4YQEAWFwBAIhbAQBkYgEA6GIBACxjAQB8YwEAAAAAAAMAAAACAAAAAwAAAAMA
    -AAADAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAARGkBAAoAAADMLoAAAAAAAAAAAAAAAAAA0GkB
    -AAoAAADMLoAAAAAAAAAAAAAAAAAAhGoBAAoAAADMLoAAAAAAAAAAAAAAAAAApGsBAAoAAADMLoAA
    -AAAAAAAAAAAAAAAACGoBAAoAAADMLoAAAAAAAAAAAAAAAAAAHGsBAAoAAADMLoAAAAAAABAAAAAA
    -gAAAAACgABAnAADoAwAA6AMAAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+
    -AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6A
    -AAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAA
    -AAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAK
    -AAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAA
    -AAAAAAAAAAAAAMg+AQAKAAAAzC6AAAAAAAAAAAAAAAAAADCEAQAKAAAAzC6AAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMiwEAkIwBAGCPAQAMkgEAhJQBAOiXAQA0jgEARAWA
    -AJCagAAYAAAAUJqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdJoBAAYAAADMLoAA/////wAAAAD/////
    -/////wAAAAAAAAAAAAAAAECdAQAFAAAADC+AAG4AbgBpAMAAoABQAIAAvgBQAX0APgBuAG4AaQDA
    -AKAAUACAAL4AUAF9AD4AAAAAAAEBAAAAAAAAAAECAQEAAgEAAQICAgABAQACAQIBAgACAAECA///
    -AAC5Ad8AsQAbABYBGwB8ARsArwAbABQBGwB6ARsAbACgANEAoAA3AaAAbwCDAHEAgwB2AIMAcwAz
    -AG4AMwBwADMAcgAzANcAMwA9ATMA1AEGANABAAB+ADwA4wA8AEkBPAB4AEkA3QBJAEMBSQB/AFoA
    -5ABaAEoBWgCqAD8AqwABAA8BPwAQAQEAdQE/AHYBAQB5AGoA3gBqAEQBagCoAAAADQEAAHMBAACm
    -ADcApwABAAsBNwAMAQEAcQE3AHIBAQAEAAgAnAHMAJ0BzACeAcwAnwHMANUBzADWAcwA1wHMALQA
    -RwAZAUcAgAFHAJAAIgD1ACIAWwEiAKEAiAAGAYgAbAGIAJQAAACVAAAAmADAAJkAoACWAJAAlwAA
    -AJQAAQCVAAEAmADAAJkAoACWAJAAlwAAAJQAAgCVAAMAmADAAJkAoACWAJAAlwAAAJQAAwCVAAcA
    -mADAAJkAoACWAJAAlwAAAPoAAAD5AAAAAgGQAAMB0wAAAYMA/gATAPwAMwD9AHcA+gABAPkAAQAC
    -AZAAAwHTAAABgwD+ABMA/AAzAP0AdwD6AAIA+QADAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoA
    -AwD5AAcAAgGSAAMB0wAAAYMA/gATAPwAMwD9AHcAXwEAAGEBAABoAZAAaQHTAGYBgwBkARMAYgEz
    -AGMBdwBfAQEAYQEBAGgBkABpAdMAZgGDAGQBEwBiATMAYwF3AF8BAgBhAQMAaAGQAGkB0wBmAYMA
    -ZAETAGIBMwBjAXcAXwEDAGEBBwBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwCFAAAAhgAAAIcAUACI
    -AAAAiQCgAIoAAACLANAAjAAAAIUAAQCGAAEAhwBQAIgAAACJAKAAigAAAIsA0ACMAAAAhQACAIYA
    -AwCHAFAAiAAAAIkAoACKAAAAiwDQAIwAAACFAAMAhgAHAIcAUACIAAAAiQCgAIoAAACLANAAjAAA
    -AOsAAADqAAAA7ABQAO0AAADuAKAA7wAAAPAA0ADxAAAA6wABAOoAAQDsAFAA7QAAAO4AoADvAAAA
    -8ADQAPEAAADrAAIA6gADAOwAUADtAAAA7gCgAO8AAADwANAA8QAAAOsAAwDqAAcA7ABQAO0AAADu
    -AKAA7wAAAPAA0ADxAAAAUQEAAFABAABSAVAAUwEAAFQBoABVAQAAVgHQAFcBAABRAQEAUAEBAFIB
    -UABTAQAAVAGgAFUBAABWAdAAVwEAAFEBAgBQAQMAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQED
    -AFABBwBSAVAAUwEAAFQBoABVAQAAVgHQAFcBAAD7/wAA//8AALkB3wCxABsAFgEbAHwBGwCvABsA
    -FAEbAHoBGwBsAKAA0QCgADcBoABvAIMAcQCDAHYAgwBzADMAbgAzAHAAMwByADMA1wAzAD0BMwDU
    -AQYA0AEAAH4APADjADwASQE8AHgASQDdAEkAQwFJAH8AWgDkAFoASgFaAKoAPwCrAAEADwE/ABAB
    -AQB1AT8AdgEBAHkAagDeAGoARAFqAKgAAAANAQAAcwEAAKYANwCnAAEACwE3AAwBAQBxATcAcgEB
    -AAQACACcAcwAnQHMAJ4BzACfAYgA1QHMANYBzADXAcwAtABHABkBRwCAAUcAkAAiAPUAIgBbASIA
    -oQCIAAYBiABsAYgA+gAAAPkAAAACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAEA+QABAAIBlwAD
    -AdAAAAGNAP4AEQD8ADMA/QB3APoAAgD5AAMAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gADAPkA
    -BwACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwBfAQAAYQEAAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3
    -AF8BAQBhAQEAaAGXAGkB0ABmAY0AZAERAGIBMwBjAXcAXwECAGEBAwBoAZcAaQHQAGYBjQBkAREA
    -YgEzAGMBdwBfAQMAYQEHAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3AOsAAADqAAAA7ABVAO0AAADu
    -AKoA7wAAAPAA3QDxAAAA6wABAOoAAQDsAFUA7QAAAO4AqgDvAAAA8ADdAPEAAADrAAIA6gADAOwA
    -VQDtAAAA7gCqAO8AAADwAN0A8QAAAOsAAwDqAAcA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAAUQEA
    -AFABAABSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAABRAQEAUAEBAFIBVQBTAQAAVAGqAFUBAABWAd0A
    -VwEAAFEBAgBQAQMAUgFVAFMBAABUAaoAVQEAAFYB3QBXAQAAUQEDAFABBwBSAVUAUwEAAFQBqgBV
    -AQAAVgHdAFcBAAD7/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KgB
    -AJDJAQCwpYAAQAUAAAAAAADcqAEA/KkBAPCqgAD4AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -XM4BAGjMAQDorIAAVAAAAAAAAADcqAEAlMwBAGitgABQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
    -AAAA3KgBALDIAQC8P4AAUAEAAAAAAADcqAEAyMoBAPgGgAACAAAAAAAAANyoAQAgywEA/AaAAAQA
    -AAAAAAAAWM4BAPypAQA8rYAAKgAAAAAAAADcqAEAvMsBAAAAAAAAAAAAAAAAANyoAQB8ywEAAAeA
    -AAQAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHAAgACAAJAAoACgALAAwADAANAA4A
    -DgAPACYAJwAoACgAKQAqAEYARgBHAEgASABJAEoASgBLAEwAaABpAGoAagBrAGwAbABtAG4AbgBv
    -AHAAcABxAHIAcgBzAHQAdAB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AA8A
    -PwAAAAAAAAAAAAAAAAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkACgAKAAsAJAAkACUAJgAm
    -ACcARABEAEUARgBGAEcASABIAEkASgBKAEsATABMAE0AagBqAGsAbABsAG0AbgBuAG8AcABwAHEA
    -cgByAHMAdAB0AHUAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AA4APwDE
    -owEAEtIAAAAAAAD//w8A6LcBALYAAAAAAAAA/wAAAOi3AQC3AAAAAAAAAP8AAADotwEAuAAAAAAA
    -AAD/AAAA6LcBALkAAAAAAAAA/wAAAOi3AQC6AAAAAAAAAP8AAADotwEAuwAAAAAAAAD/AAAA6LcB
    -AL0AAAAAAAAA/wAAAOi3AQC+AAAAAAAAAP8AAADotwEAvwAAAAAAAAD/AAAA6LcBAMAAAAAAAAAA
    -/wAAAOi3AQDBAAAAAAAAAP8AAADotwEAwgAAAAAAAAD/AAAAxKMBABPSAAAAAAAA//8PAOi3AQAb
    -AQAAAAAAAP8AAADotwEAHAEAAAAAAAD/AAAA6LcBAB0BAAAAAAAA/wAAAOi3AQAeAQAAAAAAAP8A
    -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
    -ENIC0gHSA9Ib0gvSAIAF0hLSE9IU0gRDCNIJ0grSHNIG0gfScNIAAAEAAAAAAAAAAAAAAAAAAAAD
    -AAAABAAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAD/AwAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAALUAGgGBAQQADwCDAOgATgGSAPcAXQEGAAgACQAKAAsADAAFAAAAAAAAACwAAQAA
    -AAAAAAAAAAAAAAAAAAAAAAABAAEAAQAAAP////8AAAAALQEAAN0BAABaAgAAugIAAAoDAABNAwAA
    -hwMAALoDAADoAwAAEQQAADcEAABZBAAAegQAAJgEAAC0BAAAzgQAAOcEAAD+BAAAFQUAACoFAAA+
    -BQAAUQUAAGQFAAB1BQAAhgUAAJcFAACnBQAAtgUAAMUFAADTBQAA4QUAAO4FAAD7BQAACAYAABQG
    -AAAgBgAAKwYAADcGAABCBgAATAYAAFcGAABhBgAAawYAAHUGAAB+BgAAiAYAAJEGAACaBgAAogYA
    -AKsGAAC0BgAAvAYAAMQGAADMBgAA1AYAANsGAADjBgAA6gYAAPIGAAD5BgAAAAcAAAcHAAAOBwAA
    -FAcAABsHAAAiBwAAKAcAAC4HAAA1BwAAOwcAAEEHAABHBwAATQcAAFMHAABYBwAAXgcAAGQHAABp
    -BwAAbwcAAHQHAAB5BwAAfwcAAIQHAACJBwAAjgcAAJMHAACYBwAAnQcAAKIHAACnBwAAqwcAALAH
    -AAC1BwAAuQcAAL4HAADCBwAAxwcAAMsHAADQBwAA1AcAANgHAADcBwAA4QcAAOUHAADpBwAA7QcA
    -APEHAAD1BwAA+QcAAP0HAAABCAAABQgAAAgIAAAMCAAAEAgAABQIAAAXCAAAGwgAAB8IAAAiCAAA
    -JggAACkIAAAtCAAAMAgAADQIAAA3CAAAOwgAAD4IAABBCAAARQgAAEgIAABLCAAATwgAAFIIAABV
    -CAAAWAgAAFsIAABfCAAAYggAAGUIAABoCAAAawgAAG4IAABxCAAAdAgAAHcIAAB6CAAAfQgAAIAI
    -AACCCAAAhQgAAIgIAACLCAAAjggAAJEIAACTCAAAlggAAJkIAAA4AAAAaAAAAHQAAACAAAAAjAAA
    -AJ0AAAAHAAAAAAAAAAAAAAAKAAAADdIR0hDSAtIB0gPSG9IL0gCABdIS0hPSFNIEQwjSCdIK0hzS
    -BtIH0nDSAAABAAAAAAAAAAAAAAAAAAAAAwAAAAQAAAADAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAA
    -AAAA/wMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1ABoBgQEEAA8AgwDoAE4BkgD3AF0B
    -BgAIAAkACgALAAwABQAAAAAAAAAsAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAADfAAAAGQEA
    -AGIBAAC+AQAAMgIAAMMCAAB7AwAAYgQAAIQFAADyBgAAvggAAAILAAABAAAAAgAAAAAAAAAL0g7S
    -DdII0gnSCtIS0hPSFNIR0hDSAtIB0gPSAIAF0gRDG9Ic0gTSAEUw0jHSAAAAAAAAAQAAAAEAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAADAAAABAAAAAMAAAAAAAAA/wMAAAMA
    -AAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAALUAGgGBAQUABAAPABAACgALAAwATgAA
    -AAAAAAAAAAAALAABAAAAAQABAAEAAAAAAAAAAAABAAEAAgACAAIAAwADAAQABAAFAAUABgAGAAcA
    -BwAIAAgACQAJAAoACgALAAsADAAMAA0ADQAOAA4ADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQFgACQmoAAGAAAAFCagAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAMz/AQAGAAAAzC6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAARAWAAJCagAAYAAAAUJqAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAwAoCAAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYAAADM
    -LoAAAAAAAAAAAAAAAAAAwAoCAAQAAADMLoAAAAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAA
    -AAAAAAAAwAoCAAQAAADMLoAAAAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAwAoC
    -AAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYAAADMLoAAAAAAAAAAAAAAAAAAwAoCAAQAAADMLoAA
    -AAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYAAADMLoAAAAAAAAAAAAAA
    -AAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAA6AsCAAQAAADMLoAAAAAAAAAAAAAAAAAAsAwCAAYA
    -AADMLoAARAWAAJCagAAYAAAAUJqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMEBAQEBAUGBwgICAgICQoLDA0AAAAFBgcI
    -DQ4PEBUWFxgZAAAKDREUCg0RFBkZGRkKCgAAAAAAAAYGBgYJCQkJAAYAAG47aDtiO1w7bjpoOmI6
    -XDpuOWg5YjlcOW4raCtiK1wrbipoKmIqXCpuKWgpYilcKW4baBtiG1wbbhpoGmIaXBpuGWgZYhlc
    -GW4YaBhiGFwYbhdoF2IXXBduFmgWYhZcFm4VaBViFVwVbhRoFGIUXBRuE2gTYhNcE24SaBJiElwS
    -bhFoEWIRXBFuEGgQYhBcEFcQUhBNEEkQbgFoAWIBXAFuAGgAYgBcAG47aDtiO1w7bjpoOmI6XDpu
    -OWg5YjlcOW44aDhiOFw4bjdoN2I3XDduKWgpYilcKW4oaChiKFwobidoJ2InXCduGWgZYhlcGW4Y
    -aBhiGFwYbhdoF2IXXBduCWgJYglcCW4IaAhiCFwIbgdoB2IHXAduBmgGYgZcBm4FaAViBVwFbgRo
    -BGIEXARuA2gDYgNcA24CaAJiAlwCbgFoAWIBXAFuAGgAYgBcAAAAAAAAAAAAAAAAAEArAgAIAAAA
    -DC+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////8A
    -Af//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////////////////////////////////////////////////////
    -//////////////////////////8BBAAAAgUBAAMGAgAEBwMABQgEAAYJBQAHCgYACAsHAAkMCAAK
    -DQkACw4KAAwPCwANEAwADhENAAFAAAQCQQEEA0ICBARDAwQFRAQEBkUFBAdGBgQIRwcECUgIBLcT
    -IgC4FCMAuRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgcAQALHQIADB4DABAfBAAiIQUAJCIG
    -ACYjBwAoJAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsPAEAsEABkLhEAaC8SAGwwEwBwMRQA
    -dDIVAHgzFgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0AmTweAJ09HwChPiAApT8hACRJBgIs
    -SgoCNEsNATxMDwFkTREBbE4TAXRPFQF8UBcBhFEZAZVSHQGdUx8BAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAABBgIGBgYDBgYGBgYGBgQAAAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/
    -AAEAAAAPAD8AAQAAAA8APwACAAAADwA/AAEAAAAAAAAAAQAAAAIAAAADAAAAAAAAAAQAAAACAAAA
    -BQAAAA8UGR4oCgUAsAkBpQA8ODQwLCgkIBwYFBAMCAQADAgEADw4NDAsKCQgHBgUEAwIBAIIAA4A
    -AAAOAQEAAQIBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AKXGhPiZ7o32Df+91rHeVJFQYAMCqc59VhnnYrXmTZrsRY+dH0CJh/oV7+uyyY4L++xBZ7P9X+pF
    -vyP3U5bkW5vCdRzhrj1qTFpsQX4C9U+DXGj0UTTRCPmT4nOrU2I/KgwIUpVlRl6dKDChNw8KtS8J
    -DjYkmxs93ybNaU7Nf5/qGxKeHXRYLjQtNrLc7rT7W/akTXZht859e1I+3XFelxP1pmi5AAAswWBA
    -H+PIee22vtRGjdlnS3LelNSY6LBKhWu7KsXlTxbtxYbXmlVmlBHPihDpBgSB/vCgRHi6JeNL86L+
    -XcCAigWtP7whSHAE8d9jwXd1r2NCMCAa5Q79bb9MgRQYNSYvw+G+ojXMiDkuV5PyVYL8R3qsyOe6
    -KzKV5qDAmBnRnn+jZkR+VKs7gwvKjCnH02s8KHmn4rwdFnatO9tWZE50HhTbkgoMbEjkuF2fbr3v
    -Q6bEqDmkMTfTi/Iy1UOLWW632owBZLHSnOBJtNj6rAfzJc+vyo706UcYENVviPBvSnJcJDjxV8dz
    -UZcjy3yhnOghPt2W3GGGDYUPkOBCfMRxqszYkAUGAfcSHKPCX2r5rtBpkRdYmSc6uSc42RPrsysz
    -IrvScKmJB6czti0iPJIVIMlJh/+qeFB6pY8D+FmACRca2mUx18aEuNDDgrApd1oRHst7/KjWbTos
    -AQEBAQEBAQECAgICAgICAgMDAwMDAwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQE
    -BAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgME
    -BgZ00UUX6KKLLg0PBQcJCwEDChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHDw8P
    -BwYHAgMEBQABCAkLCigAKAAwACwALAAoADwANAAoACgANAAwACwALABEADwAQAA8AIwAbABYAEgA
    -9ACwACwALAA8ADQAMAAsAFQARABUAFQAbABgAFwAVACMAHgAOgECAdUA3wDaAKIAdQB/AGoBGgHZ
    -AOgACgG6AHkAiACKBSoDOQGoAYoFygLZAEgBygFKAeIA+QDKAeoAggCZAPQCRAK1AdUBlAKEAfUA
    -QQKsAJAAhACAAHgAeAB4AHQAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzE
    -Tid2YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUF
    -BVRABSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN
    -0iANCqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4
    -gAcGaZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiA
    -CgiMwAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEQAOABsAJAA2AEwAa
    -QB2AIIAGAA2AEwAaACcANIA6AEHACYATQB0AJ4A6AE7AV4BhmQMzB9kKcw6mFeYcgCAZJDMHcw6m
    -FeYcWSvMOQBBM0jZCqYVgCBZKwBBplaAYVlsMAAAADYAAAAMAAAAEgAAABgAAAAkAAAABgAAAAkA
    -AAAAAAAAAAAAABggFBQODhQUBQYBAgMEAAAAAQECAQICAwQMDAgEDAQEQAAAAIAAAAAAAQAAAAIA
    -AEAAAAAABAAAQAAAAEAAAAAQERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uL0BBQkNERUZH
    -SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8z
    -EwAAAAcHDwcPDxctAA8gAPBhAAAAAAAAAAAAAAECBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDk6NDk6MDkAAAAATi2uAGmu
    -oK6QrmIAAaysegCskpusrF8ACQAAAAIAAAAAAAAAAAAAAAkAAAACAAAAAAAAAAAAAAAJAAAAAwAA
    -AAEAAAAJAAAACQAAAAIAAAACAAAACQAAAAECAQIDBAAABQYHCAkKAAAABQYAAgQABQAAAAAABQcB
    -AwQABQEAAABAI0AlISEhIUBAQEBABQQEAQFAQEBABQVAQAwMQA0MDAEBAQVAQAUFAAQABEBAAARA
    -QEAFQEBAQEAFQEBABQUFAQEBAUAFBQUBBQEBQAUFBUAFQAUFBQUFBAAAABwRAAAcMgAAHDMAAAQA
    -AAAcFQAAAgAXAGwAcAR0CHQMAAQEBgAAAAAAAAAAZAAAAACQAQAKAAAAAAAAAAAAAAAAAAAA/wAA
    -AAAAAAAAAAAAAAAAAAAAAAABAAAAEAAAAAAAAAABAAAAAQAAAAAAAAD/AAAA/wAAAAAAAAAAAAAA
    -HHsBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAABAAAZAAAAIyB
    -AQCUgQEAnIEBAPCBAQD4gQEAAIIBAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
    -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
    -tmsDAK9hAwDHVwMA+00DAExEAwC5OgMAQjEDAOgnAwCoHgMAhBUDAHoMAwCLAwMAtvoCAPvxAgBZ
    -6QIA0eACAGLYAgAM0AIAzscCAKi/AgCatwIAo68CAMSnAgD8nwIAS5gCALCQAgAsiQIAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAA5////87///+1////nP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AOf////O////tf///5z///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADn////zv///7X///+c////
    -EwEAAOEAAACvAAAAfQAAAH0AAACvAAAAyAAAAMgAAADIAAAAyAAAABMBAADhAAAArwAAAH0AAAB9
    -AAAArwAAAMgAAADIAAAAyAAAAMgAAAATAQAA4QAAAK8AAAB9AAAAfQAAAK8AAADIAAAAyAAAAMgA
    -AADIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJYAAACWAAAAlgAA
    -AJYAAACWAAAAfQAAAH0AAAB9AAAAfQAAAH0AAACWAAAAlgAAAJYAAACWAAAAlgAAAH0AAAB9AAAA
    -fQAAAH0AAAB9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF4BAAAs
    -AQAAEwEAAPoAAADhAAAAyAAAAK8AAAB9AAAAZAAAAGQAAABeAQAALAEAABMBAAD6AAAA4QAAAMgA
    -AACvAAAAfQAAAGQAAABkAAAAAAAAAP////8AAAAAAAAAAAEAAAAAAAAAYAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAA
    -AAAAAAUFBQUFBQUFAAAAAIANAAAAIAAAgA0AAIANAAAAIAAAgA0AAAAGAAAABAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    -AAA=
    -====
    diff --git a/sys/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu b/sys/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu
    new file mode 100644
    index 00000000000..2cfa6cc6ab9
    --- /dev/null
    +++ b/sys/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu
    @@ -0,0 +1,8152 @@
    +Copyright (c) 2006-2010, 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-6000-9.193.4.1.fw.uu
    +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
    +IcEPyiLBB8ogYQHKI4EPAAC4AMokIQCUAaHvyiXBAEwjAKAEphDyAYGYuAGhA4GfuAOhABUBIAQV
    +ACAAHoQUIaYCpg4J7/WpcP0Ej/DgeM9wgABoqyiAz3CfALj/ANo2oAjZ7HAgoAPZz3CgABQEJaAC
    +yOxxAKHPcKAA1AtNoOB+4HjPcYAA1AfgfwCh4HjPcIAA1AfgfwCA4HjgfuB44H7geOB+4HjgfuB4
    +4H7geOB+4HjgfuB44H8A2OB/ANjgfuB4ocHgf6HA4HjgfuB44H7gePHA4cUCyM91gAAcYwClBG3O
    +CO/wAtnPcYAOBADscCCgUg+v8ACFnQSP8OB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
    +4HjgfuB48cAAFgBBz3KAABxjBrIAFgVBQCIBBA4aRAFMJYCEyiHCD8oiwgfKIGIByiOCDwAAggBY
    +AKLvyiQiAADaB/AAFgBBFCGMAAC0AeIvIEIBEHK39voPj/DRwOB+4HjgfuB44H7geOB+4HjgfuB4
    +4H7geOB+4HjgfuB44H7geOB+4HjPcIAA2AfgfwCA4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
    +fuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
    +4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfwHY4H7g
    +eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
    +8cCmCo/wGnHPd4AAXGMgj1EhAIBG8s9xgADgByCJgOHMICGgPvKB4Ab0z3CAALi0oYAD8ADdjuUD
    +94DlAvQA3c9xgAC4tBiJgOAE9IDlBPQA3gTwooEE3oogEwFuCK/wqXGKIFMBZgiv8Mlxz3CAABwP
    +GIiD4MwgIoHMIOKBzCAiggjyiiATAUIIr/Cz2QrwCpcQdQj0C5cQdswgIaAE9ADYIfAB2M9xoADI
    +Hw2hz3CAAOAHAYjLt6q3BL4QuMV9BX2KIBMBBgiv8MrZiiATAfoPb/Cpcc9woADIH38YWIMB2CkC
    +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
    +DxwdIgEAHSb5DwBhZAwAEADABhEBAAQn/AAEZAAAGyQCABslOBzAEQAAACEAABslQAAbJDAcwBEA
    +AAAhDxwdIhgBHSYYAMcQmKCAgQAAwBcgAMcQoKCAgQAAwBcAAAAhlEmAgQIAXG4RAABh+EHEEA8b
    +CSIACwk5AgAKYgMBCmIEAgpiAAAJQAQAAGEJAAlAAgAAYQoACUAAAABhAgAJQQAJGigAAMAWAQAb
    +JgAAwBcEAB0mAQAIJ+kACGQAAAAhAAAAAIwBAAABAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQ6AAAA
    +PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFJyAAAAAAAAAAAAAAAAAAAEA
    +AAAHAAAAAAAAAMAAkADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAaKuAAAAA
    +AAAAAAAAQK+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAIi0gAAYoAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADI
    +xIAACPsBAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaKuAAEQE
    +AgAAAAAAaKuAADgLAgAAAAAAAAAAAGirgADQDAIAAAAAAAAAAAAAAAAAaKuAAAAAAAAAAAAAAAAA
    +AP8AAAAABwAAAAAAAAAAAAAEIAIABCACAAQgAgAIIAIAAAAAAB0AAAAAAAAAAAAAAAAAAAAAAAAA
    +f38AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECBAgACBAgAAAAAAAAAAABAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAkAABUAAADsRYAAzCsAAMwr
    +AADMKwAAgEIAAMwrAADMKwAAzD0AAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsA
    +AOweAACcIAAAtCAAACQiAACsIgAAKCIAAMwrAADMKwAA6E4AALBQAACcUQAAzCsAAMwrAADMKwAA
    +ZE0AAHBkAABsZAAAxGQAAMwrAADMKwAAzCsAAIxEAADMKwAAqGQAAMwrAADMKwAAzCsAAMwrAADM
    +KwAAzCsAAMwrAADMKwAAhEIAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwr
    +AADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAfEUA
    +AMwrAADMKwAAzCsAAMwrAADMKwAAZEYAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAA
    +zCsAAMwrAADMKwAArGsAAMwrAAAUbQAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAAC8
    +bwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAAC4hAEAEIgBAMwr
    +AABkigEAzCsAABSMAQCAVwEAzCsAAMwrAABoUgAAzCsAAMwrAADMKwAAzCsAAMwrAACs4gEANPYB
    +AMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAmB0CAMwrAADMKwAA
    +zCsAAJgCAgDMKwAAuAYCAMwrAADQLgIAzCsAAOAlAADkJQAAzCsAAMwrAAB0FwIA6HIAAMwrAADM
    +KwAAzCsAAPD/AQDMKwAAzCsAANBQAQD4owEAzCsAAMwrAADMKwAA6KwBAKBYAQDMKwAAzCsAAMwr
    +AADMKwAAzCsAAMwrAACgtwEAzCsAAGwUAgBwFAIAfBQCAIAUAgB0FAIAeBQCAIQUAgDMKwAAzCsA
    +AMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAABMVAAAzCsAAMwrAADMKwAAzCsAAMwrAADAEwIA
    +EBQCAHhIAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADM
    +KwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwr
    +AADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAAzCsAAMwrAADMKwAA+EkAAIBKAAAUSwAAyEsA
    +AMCBAACgSwAAzCsAAMwrAADMKwAAzCsAAMwrAADwSQAA9EkAAMwrAADMKwAAmFIAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwMAADMDAAAzAwAAMwMAADMDAAA
    +zAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAADM
    +DAAAzAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAADMDAAAzAwAAMwMAAD8DQAAAAAAAChe
    +AQDMDAAA3AkAAMwMAADMDAAAzAwAAAwKAAAgQAEAAIQAAMwMAADMDAAARAoAAEQKAABECgAARAoA
    +AEQKAABECgAARAoAAMwMAADMDAAAzAwAAMwMAAA8DAAAzAwAAMwMAADMDAAAzAwAAMwMAAAADgAA
    +zAwAAMwMAADACQAAAwAAAIQRAgACAAAAcGwBAAQAAAAkbQEABQAAABwOAAAGAAAAtDQAAAgAAADs
    +EwIAEwAAAJz8AQAJAAAAZAgCAAoAAACIFAIADgAAAAChAQAPAAAATI4BABAAAACEjgEAGQAAAJBd
    +AQANAAAA/IUBABcAAADkcgAAEQAAAECCAAASAAAA0E8BAAEAAAAYAgIAFAAAAKy0AQAVAAAALKQB
    +AAcAAAAscAAAFgAAAMAuAgAYAAAA+JwAABoAAAD8DQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAQAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ
    +AAAAAQEAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8AAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhAw4e4eEDDh7h
    +4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuHhAw4e4eEDDh7h4QMOHuEAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8PDw8
    +FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwV
    +FRUVPDw8PBUVFRU8PDw8AAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8
    +PDw8PDw8FRUVFTw8PDwVFRUVPDw8PAAAAAAAAAAAAAAAAAAAAACQBgAAMfqvAJAGAAAx+q8AkAYA
    +ADH6rwCQBgAAMfqvAJAGAAAx+q8AkAYAADH6rwCQBgAAMfqvAJAGAAAx+q8AQwUAADH6rwBDBQAA
    +MfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAEMFAAAx+q8AQwUAADH6rwBDBQAAMfqvAAAAAADe
    +wwkAAAAAAAAAAAAAAAAAvC0BAAEAAACsRYAAAAAAAAAAAAAAAAAAXC4BABUAAADsRYAAAAAAAAAA
    +AAACAAAAAwAAAAAAAAAIAAAAAAAAADCMEQAgvwIAAAAAANAuAQB4LwEAhDABADAyAQCEMAEAMDIB
    +AAQ0AQCMNAEA8DQBAICAgICAgICAAYACgICAgIAAAAAA8DoBAPA6AQAAAAAAAAAAAAAAAAAAAAAA
    +8DoBAPA6AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArEWAAKxFgACkIKAAOCCgAAEAAAD8
    +////AAAAAAAAAADMRYAAzEWAAKggoAA8IKAACAAAAPP///8AAAAAAAAAAOxFgADsRYAArCCgAGwg
    +oAAwAAAAz////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAA
    +AAAAAADkUAEABQAAAOxFgAAsVgEAAP8DAExWAQAA/wUAOFcBAAD/LQBcVwEAAP89ABRXAQAA/wQA
    ++FYBAAD/JQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMxcAQAGAAAArEWAAAAA
    +AAAsAQAAXgEAAAEAAAABAAAAAQAAAAEAAAADAAAAAAAAAAAAAAAYZAEAIGUBAJxlAQCsYAEA1F8B
    +APBmAQB4ZwEAvGcBABBoAQAAAAAAAwAAAAIAAAADAAAAAwAAAAMAAAABAAAAAAAAAAEAAAAAAAAA
    +AAAAAAAAAAD0bQEACgAAAKxFgAAAAAAAAAAAAAAAAACAbgEACgAAAKxFgAAAAAAAAAAAAAAAAAA0
    +bwEACgAAAKxFgAAAAAAAAAAAAAAAAABUcAEACgAAAKxFgAAAAAAAAAAAAAAAAAC4bgEACgAAAKxF
    +gAAAAAAAAAAAAAAAAADMbwEACgAAAKxFgAAAAAAAEAAAAACAAAAAAKAAECcAAOgDAADoAwAAAAAA
    +AAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAA
    +MEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACs
    +RYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAA
    +AAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIB
    +AAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAAAAAAAAAAAAAAAAAAMEIBAAoAAACsRYAA
    +AAAAAAAAAAAAAAAA8IkBAAoAAACsRYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAGSRAQBwkgEAXJUBABCYAQCQmgEAFJ4BACCUAQA0BYAAMKuAABgAAADwqoAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAACooAEABgAAAKxFgAD/////AAAAAP//////////AAAAAAAAAAAAAAAAiKMBAAUA
    +AADsRYAAbgBuAGkAwACgAFAAgAC+AFABfQA+AG4AbgBpAMAAoABQAIAAvgBQAX0APgAAAAAAAQEA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgEBAAIBAAECAgIAAQEAAgECAQIAAgABAgP//wAAuQHf
    +ALEAGwAWARsAfAEbAK8AGwAUARsAegEbAGwAoADRAKAANwGgAG8AgwBxAIMAdgCDAHMAMwBuADMA
    +cAAzAHIAMwDXADMAPQEzANQBBgDQAQAAfgA8AOMAPABJATwAeABJAN0ASQBDAUkAfwBaAOQAWgBK
    +AVoAqgA/AKsAAQAPAT8AEAEBAHUBPwB2AQEAeQBqAN4AagBEAWoAqAAAAA0BAABzAQAApgA3AKcA
    +AQALATcADAEBAHEBNwByAQEABAAIAJwBzACdAcwAngHMAJ8BzADVAcwA1gHMANcBzAC0AEcAGQFH
    +AIABRwCQACIA9QAiAFsBIgChAIgABgGIAGwBiACUAAAAlQAAAJgAwACZAKAAlgCQAJcAAACUAAEA
    +lQABAJgAwACZAKAAlgCQAJcAAACUAAIAlQADAJgAwACZAKAAlgCQAJcAAACUAAMAlQAHAJgAwACZ
    +AKAAlgCQAJcAAAD6AAAA+QAAAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoAAQD5AAEAAgGQAAMB
    +0wAAAYMA/gATAPwAMwD9AHcA+gACAPkAAwACAZAAAwHTAAABgwD+ABMA/AAzAP0AdwD6AAMA+QAH
    +AAIBkgADAdMAAAGDAP4AEwD8ADMA/QB3AF8BAABhAQAAaAGQAGkB0wBmAYMAZAETAGIBMwBjAXcA
    +XwEBAGEBAQBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwBfAQIAYQEDAGgBkABpAdMAZgGDAGQBEwBi
    +ATMAYwF3AF8BAwBhAQcAaAGQAGkB0wBmAYMAZAETAGIBMwBjAXcAhQAAAIYAAACHAFAAiAAAAIkA
    +oACKAAAAiwDQAIwAAACFAAEAhgABAIcAUACIAAAAiQCgAIoAAACLANAAjAAAAIUAAgCGAAMAhwBQ
    +AIgAAACJAKAAigAAAIsA0ACMAAAAhQADAIYABwCHAFAAiAAAAIkAoACKAAAAiwDQAIwAAADrAAAA
    +6gAAAOwAUADtAAAA7gCgAO8AAADwANAA8QAAAOsAAQDqAAEA7ABQAO0AAADuAKAA7wAAAPAA0ADx
    +AAAA6wACAOoAAwDsAFAA7QAAAO4AoADvAAAA8ADQAPEAAADrAAMA6gAHAOwAUADtAAAA7gCgAO8A
    +AADwANAA8QAAAFEBAABQAQAAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQEBAFABAQBSAVAAUwEA
    +AFQBoABVAQAAVgHQAFcBAABRAQIAUAEDAFIBUABTAQAAVAGgAFUBAABWAdAAVwEAAFEBAwBQAQcA
    +UgFQAFMBAABUAaAAVQEAAFYB0ABXAQAA+/8AAP//AAC5Ad8AsQAbABYBGwB8ARsArwAbABQBGwB6
    +ARsAbACgANEAoAA3AaAAbwCDAHEAgwB2AIMAcwAzAG4AMwBwADMAcgAzANcAMwA9ATMA1AEGANAB
    +AAB+ADwA4wA8AEkBPAB4AEkA3QBJAEMBSQB/AFoA5ABaAEoBWgCqAD8AqwABAA8BPwAQAQEAdQE/
    +AHYBAQB5AGoA3gBqAEQBagCoAAAADQEAAHMBAACmADcApwABAAsBNwAMAQEAcQE3AHIBAQAEAAgA
    +nAHMAJ0BzACeAcwAnwGIANUBzADWAcwA1wHMALQARwAZAUcAgAFHAJAAIgD1ACIAWwEiAKEAiAAG
    +AYgAbAGIAPoAAAD5AAAAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gABAPkAAQACAZcAAwHQAAAB
    +jQD+ABEA/AAzAP0AdwD6AAIA+QADAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3APoAAwD5AAcAAgGX
    +AAMB0AAAAY0A/gARAPwAMwD9AHcAXwEAAGEBAABoAZcAaQHQAGYBjQBkAREAYgEzAGMBdwBfAQEA
    +YQEBAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3AF8BAgBhAQMAaAGXAGkB0ABmAY0AZAERAGIBMwBj
    +AXcAXwEDAGEBBwBoAZcAaQHQAGYBjQBkAREAYgEzAGMBdwDrAAAA6gAAAOwAVQDtAAAA7gCqAO8A
    +AADwAN0A8QAAAOsAAQDqAAEA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAA6wACAOoAAwDsAFUA7QAA
    +AO4AqgDvAAAA8ADdAPEAAADrAAMA6gAHAOwAVQDtAAAA7gCqAO8AAADwAN0A8QAAAFEBAABQAQAA
    +UgFVAFMBAABUAaoAVQEAAFYB3QBXAQAAUQEBAFABAQBSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAABR
    +AQIAUAEDAFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAFEBAwBQAQcAUgFVAFMBAABUAaoAVQEAAFYB
    +3QBXAQAA+/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi3AQCU2AEA
    +9LSAAEAFAAAAAAAACLcBADS4AQA0uoAA+AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzdAQBw
    +2wEALLyAAFQAAAAAAAAACLcBAKDbAQCsvIAAUAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAi3
    +AQC01wEAWFeAAFABAAAAAAAACLcBAMzZAQDgBoAAAgAAAAAAAAAItwEAJNoBAOQGgAAEAAAAAAAA
    +AGjdAQA0uAEAgLyAACoAAAAAAAAACLcBAMDaAQAAAAAAAAAAAAAAAAAItwEAgNoBAOgGgAAEAAAA
    +AAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAIAAgACQAKAAoACwAMAAwADQAOAA4ADwAm
    +ACcAKAAoACkAKgBGAEYARwBIAEgASQBKAEoASwBMAGgAaQBqAGoAawBsAGwAbQBuAG4AbwBwAHAA
    +cQByAHIAcwB0AHQAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQAPAD8AAAAA
    +AAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHAAgACAAJAAoACgALACQAJAAlACYAJgAnAEQA
    +RABFAEYARgBHAEgASABJAEoASgBLAEwATABNAGoAagBrAGwAbABtAG4AbgBvAHAAcABxAHIAcgBz
    +AHQAdAB1AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgAOAD8AMKoBABLS
    +AAAAAAAA//8PAPDFAQC2AAAAAAAAAP8AAADwxQEAtwAAAAAAAAD/AAAA8MUBALgAAAAAAAAA/wAA
    +APDFAQC5AAAAAAAAAP8AAADwxQEAugAAAAAAAAD/AAAA8MUBALsAAAAAAAAA/wAAAPDFAQC9AAAA
    +AAAAAP8AAADwxQEAvgAAAAAAAAD/AAAA8MUBAL8AAAAAAAAA/wAAAPDFAQDAAAAAAAAAAP8AAADw
    +xQEAwQAAAAAAAAD/AAAA8MUBAMIAAAAAAAAA/wAAADCqAQAT0gAAAAAAAP//DwDwxQEAGwEAAAAA
    +AAD/AAAA8MUBABwBAAAAAAAA/wAAAPDFAQAdAQAAAAAAAP8AAADwxQEAHgEAAAAAAAD/AAAA8MUB
    +AB8BAAAAAAAA/wAAAPDFAQAgAQAAAAAAAP8AAADwxQEAIgEAAAAAAAD/AAAA8MUBACMBAAAAAAAA
    +/wAAAPDFAQAkAQAAAAAAAP8AAADwxQEAJQEAAAAAAAD/AAAA8MUBACYBAAAAAAAA/wAAAPDFAQAn
    +AQAAAAAAAP8AAAAwqgEAFNIAAAAAAAD//w8A8MUBAIIBAAAAAAAA/wAAAPDFAQCDAQAAAAAAAP8A
    +AADwxQEAhAEAAAAAAAD/AAAA8MUBAIUBAAAAAAAA/wAAAPDFAQCGAQAAAAAAAP8AAADwxQEAhwEA
    +AAAAAAD/AAAA8MUBAIkBAAAAAAAA/wAAAPDFAQCKAQAAAAAAAP8AAADwxQEAiwEAAAAAAAD/AAAA
    +8MUBAIwBAAAAAAAA/wAAAPDFAQCNAQAAAAAAAP8AAADwxQEAjgEAAAAAAAD/AAAAMKoBAAjSAAAA
    +AAAA//8DAHCqAQAAggAAAAAAAP8BAABwqgEAAYIAAAAAAAD/AQAAMKoBAAnSAAAAAAAA//8DAHCq
    +AQACggAAAAAAAP8BAABwqgEAA4IAAAAAAAD/AQAAMKoBAArSAAAAAAAA//8DAHCqAQAEggAAAAAA
    +AP8BAABwqgEABYIAAAAAAAD/AQAAMKoBAAbSAAAAAAAA/wEAADCqAQAH0gAAAAAAAP8DAAAwqgEA
    +BtIAAAkAAAAA/gMAMKoBAAfSAAAKAAAAAPwPADCqAQAG0gAAEgAAAAAA/AcwqgEAB9IAABQAAAAA
    +APA/MKoBABXSAAAAAAAA/wMAADCqAQAM0gAAAAAAAP8BAAAwqgEAFdIAAAoAAAAA/A8AMKoBAAzS
    +AAAJAAAAAP4DADCqAQAV0gAAFAAAAAAA8D8wqgEADNIAABIAAAAAAPwHMIAAAKqqqqoxgAAAqqqq
    +qjKAAAAAqqqqM4AAAAAAAAA0gAAAAAAAADWAAAAAAAAANoAAAAAAAAA3gAAAAAAAADiAAAAAAAAA
    +OYAAAAAAAAA6gAAAAAAAADuAAAAAAAAAPIAAAAAAAAA9gAAAqqoKAD6AAACqqqqqP4AAAKqqqqpA
    +gAAAAAAAADCAAACqqqqqMYAAAKqqqqoygAAAAKqqqjOAAAAAAAAANIAAAAAAAAA1gAAAAAAAADaA
    +AAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAAAAAAA7gAAAAAAAADyAAAAAAAAAPYAA
    +AKqqCgA+gAAAqqqqqj+AAACqqqqqQIAAAAAAAAAwgAAAAAAAADGAAAAAAAAAMoAAAAAAAAAzgAAA
    +AAAAADSAAACqqqqqNYAAAKqqqqo2gAAAAAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAAADqAAACq
    +qqoKO4AAAKqqqqo8gAAAAAAAAD2AAAAAAAAAPoAAAAAAAAA/gAAAAAAAAECAAAAAAAAAMIAAAAAA
    +AAAxgAAAAAAAADKAAAAAAAAAM4AAAAAAAAA0gAAAqqqqqjWAAACqqqqqNoAAAAAAAAA3gAAAAAAA
    +ADiAAAAAAAAAOYAAAAAAAAA6gAAAqqqqCjuAAACqqqqqPIAAAAAAAAA9gAAAAAAAAD6AAAAAAAAA
    +P4AAAAAAAABAgAAAAAAAADQFgAAwq4AAGAAAAPCqgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAg+AEABgAAAKxF
    +gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +ADQFgAAwq4AAGAAAAPCqgAAAAAAAAAAAAAAAAAAAAAAAAAAAABQEAgAGAAAArEWAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAWAADCrgAAY
    +AAAA8KqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiBACAAQAAACsRYAAAAAAAAAAAAAAAAAAWA8CAAQA
    +AACsRYAAAAAAAAAAAAAAAAAAUBECAAYAAACsRYAAAAAAAAAAAAAAAAAAWA8CAAQAAACsRYAAAAAA
    +AAAAAAAAAAAAiBACAAQAAACsRYAAAAAAAAAAAAAAAAAAWA8CAAQAAACsRYAAAAAAAAAAAAAAAAAA
    +iBACAAQAAACsRYAAAAAAAAAAAAAAAAAAWA8CAAQAAACsRYAAAAAAAAAAAAAAAAAAUBECAAYAAACs
    +RYAAAAAAAAAAAAAAAAAAWA8CAAQAAACsRYAAAAAAAAAAAAAAAAAAiBACAAQAAACsRYAAAAAAAAAA
    +AAAAAAAAUBECAAYAAACsRYAAAAAAAAAAAAAAAAAAiBACAAQAAACsRYAAAAAAAAAAAAAAAAAAiBAC
    +AAQAAACsRYAAAAAAAAAAAAAAAAAAUBECAAYAAACsRYAANAWAADCrgAAYAAAA8KqAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU
    +BQAAAAAAAAAAAAAAAAAAAAAA/wD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAQEBAQFBgcICAgICAkKCwwNAAAABQYHCA0O
    +DxAVFhcYGQAACg0RFAoNERQZGRkZCgoAAAAAAAAGBgYGCQkJCQAGAABuO2g7YjtcO246aDpiOlw6
    +bjloOWI5XDluK2grYitcK24qaCpiKlwqbiloKWIpXCluG2gbYhtcG24aaBpiGlwabhloGWIZXBlu
    +GGgYYhhcGG4XaBdiF1wXbhZoFmIWXBZuFWgVYhVcFW4UaBRiFFwUbhNoE2ITXBNuEmgSYhJcEm4R
    +aBFiEVwRbhBoEGIQXBBXEFIQTRBJEG4BaAFiAVwBbgBoAGIAXABuO2g7YjtcO246aDpiOlw6bjlo
    +OWI5XDluOGg4YjhcOG43aDdiN1w3biloKWIpXCluKGgoYihcKG4naCdiJ1wnbhloGWIZXBluGGgY
    +YhhcGG4XaBdiF1wXbgloCWIJXAluCGgIYghcCG4HaAdiB1wHbgZoBmIGXAZuBWgFYgVcBW4EaARi
    +BFwEbgNoA2IDXANuAmgCYgJcAm4BaAFiAVwBbgBoAGIAXAAAAAAAAAAAAAAAAAAAMQIACAAAAOxF
    +gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////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////////////////////
    +//8iIyT/JSYn//8o////Kf//////////////////////////////////////////////////////
    +////////////////////////AQQAAAIFAQADBgIABAcDAAUIBAAGCQUABwoGAAgLBwAJDAgACg0J
    +AAsOCgAMDwsADRAMAA4RDQABQAAEAkEBBANCAgQEQwMEBUQEBAZFBQQHRgYECEcHBAlICAS3EyIA
    +uBQjALkVJAC7FiUAvBcmAL0YJwDAGSgAxBopAAcbAAAIHAEACx0CAAweAwAQHwQAIiEFACQiBgAm
    +IwcAKCQIAColCQAsJgoALicLADAoDAA0KQ0AOCoOADwrDwBALBAAZC4RAGgvEgBsMBMAcDEUAHQy
    +FQB4MxYAfDQXAIA1GACENhkAiDcaAIw4GwCROhwAlTsdAJk8HgCdPR8AoT4gAKU/IQAkSQYCLEoK
    +AjRLDQE8TA8BZE0RAWxOEwF0TxUBfFAXAYRRGQGVUh0BnVMfAQAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwA/AAEAAAAP
    +AD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAIAAAAPAD8AAQAAAAAA
    +AAABAAAAAgAAAAMAAAAAAAAABAAAAAIAAAAFAAAADxQZHigKBQDBCQGlADw4NDAsKCQgHBgUEAwI
    +BAAMCAQAPDg0MCwoJCAcGBQQDAgEAggADgAAAA4BAQABAgEBAQAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKXGhPiZ7o32Df+91rHe
    +VJFQYAMCqc59VhnnYrXmTZrsRY+dH0CJh/oV7+uyyY4L++xBZ7P9X+pFvyP3U5bkW5vCdRzhrj1q
    +TFpsQX4C9U+DXGj0UTTRCPmT4nOrU2I/KgwIUpVlRl6dKDChNw8KtS8JDjYkmxs93ybNaU7Nf5/q
    +GxKeHXRYLjQtNrLc7rT7W/akTXZht859e1I+3XFelxP1pmi5AAAswWBAH+PIee22vtRGjdlnS3Le
    +lNSY6LBKhWu7KsXlTxbtxYbXmlVmlBHPihDpBgSB/vCgRHi6JeNL86L+XcCAigWtP7whSHAE8d9j
    +wXd1r2NCMCAa5Q79bb9MgRQYNSYvw+G+ojXMiDkuV5PyVYL8R3qsyOe6KzKV5qDAmBnRnn+jZkR+
    +VKs7gwvKjCnH02s8KHmn4rwdFnatO9tWZE50HhTbkgoMbEjkuF2fbr3vQ6bEqDmkMTfTi/Iy1UOL
    +WW632owBZLHSnOBJtNj6rAfzJc+vyo706UcYENVviPBvSnJcJDjxV8dzUZcjy3yhnOghPt2W3GGG
    +DYUPkOBCfMRxqszYkAUGAfcSHKPCX2r5rtBpkRdYmSc6uSc42RPrsyszIrvScKmJB6czti0iPJIV
    +IMlJh/+qeFB6pY8D+FmACRca2mUx18aEuNDDgrApd1oRHst7/KjWbTosAQEBAQEBAQECAgICAgIC
    +AgMDAwMDAwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQEBAQEBAQEBAQEBAQEBAQE
    +BAQEBAQAAAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgMEBgZ00UUX6KKLLg0PBQcJ
    +CwEDChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHDw8PBwYHAgMEBQABCAkLCigA
    +KAAwACwALAAoADwANAAoACgANAAwACwALABEADwAQAA8AIwAbABYAEgA9ACwACwALAA8ADQAMAAs
    +AFQARABUAFQAbABgAFwAVACMAHgAOgECAdUA3wDaAKIAdQB/AGoBGgHZAOgACgG6AHkAiACKBSoD
    +OQGoAYoFygLZAEgBygFKAeIA+QDKAeoAggCZAPQCRAK1AdUBlAKEAfUAQQKsAJAAhACAAHgAeAB4
    +AHQAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzETid2YicapEEaEzuxEw3S
    +IA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUFBVRABSd2YicTO7ETDdIg
    +DYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN0iANCqiAChM7sRMP/MAP
    +D/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4gAcGaZAGD/zADw3SIA0L
    +tEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiACgiMwAgHeIAHCIzACAd4
    +gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEQAOABsAJAA2AEwAaQB2AIIAGAA2AEwAaACcA
    +NIA6AEHACYATQB0AJ4A6AE7AV4BhmQMzB9kKcw6mFeYcgCAZJDMHcw6mFeYcWSvMOQBBM0jZCqYV
    +gCBZKwBBplaAYVlsMAAAADYAAAAMAAAAEgAAABgAAAAkAAAABgAAAAkAAAAAAAAAAAAAABggFBQO
    +DhQUBQYBAgMEAAAAAQECAQICAwQMDAgEDAQEQAAAAIAAAAAAAQAAAAIAAEAAAAAABAAAQAAAAEAA
    +AAAQERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uL0BBQkNERUZHSElKS0xNTk9QUVJTVFVW
    +V1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8zEwAAAAcHDwcPDxctAA8g
    +APBhAAAAAAAAAAAAAAECBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMTM6MDE6MDkAAAAATy6wAGqworCSsGMAAaiodgCojpeo
    +qFsACQAAAAIAAAAAAAAAAAAAAAkAAAACAAAAAAAAAAAAAAAJAAAAAwAAAAEAAAAJAAAACQAAAAIA
    +AAACAAAACQAAAAECAQIDBAAABQYHCAkKAAAABQYAAgQABQAAAAAABQcBAwQABQEAAABAI0AlISEh
    +IUBAQEBABQQEAQFAQEBABQVAQAwMQA0MDAEBAQVAQAUFAAQABEBAAARAQEAFQEBAQEAFQEBABQUF
    +AQEBAUAFBQUBBQEBQAUFBUAFQAUFBQUFBAAAABwRAAAcMgAAHDMAAAQAAAAcFQAAAgAXAGwAcAR0
    +CHQMAAQEBgAAAAAAAAAAZAAAAACQAQAKAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA
    +AAABAAAAEAAAAAAAAAABAAAAAQAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAoIABAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAABAAAZAAAADyHAQBEhwEATIcBAKSHAQCs
    +hwEAtIcBAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
    +BwcHBwcHBwYGBgYGBQUFBQUEBAQEBAMDAwMDAgICAgIBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACiVDwE58mAAHFy1gNAAAAAQOCR0t
    +NwAABA4JHSw7AAEQAAEAAAACgAABQgYCEAACIAAAA8AAAUMGAxAAAsAAAAPAAAFDBgQQAAJAAAAC
    +gAABRAYFEQAAQAAAA8AAAUUGBhEAAOAAAAPAAAFFBgcRAAEAAAACgAABRgYIEQACIAAAA8AAAUcG
    +CREAAsAAAAPAAAFHBgoRAAJAAAACgAABSAYLEgAAQAAAA8AAAUkGDBIAAOAAAAPAAAFJBg0SAAEA
    +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
    +AAB9AAAAlgAAAJYAAACWAAAAlgAAAJYAAAB9AAAAfQAAAH0AAAB9AAAAfQAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABeAQAALAEAABMBAAD6AAAA4QAAAMgAAACvAAAA
    +fQAAAGQAAABkAAAAXgEAACwBAAATAQAA+gAAAOEAAADIAAAArwAAAH0AAABkAAAAZAAAAAAAAAD/
    +////AAAAAAAAAAABAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAFBQUFBQUFBQAAAACADQAAACAA
    +AIANAACADQAAACAAAIANAAAABgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAggA8A
    +AEAAaSAAAGkgQABpIAAAaSBAACAggA8AAOgAaSAAAGkgQABpIAAAaSBAACAggA8AAGQGaSAAAGkg
    +QABpIAAASiAAAEohAABKIgAASiMAAEokAABKJQAASiYAAEonAABKIAAQSiEAEEoiABBKIwAQSiQA
    +EEolABBKJgAQSicAEEogACBKIQAgSiIAIEojACBKJAAgSiUAIEomACBKJwAgSiAAMEohADAKJIA/
    +gQAAQEEsnDBALJwwQiQcNAoigD+AADiJCiMANxoIQABKJgBwaSBAAEomAHBKJgBwSiYAcEomAHAA
    +FgBwgABkBEB4ICBAhwAAAAAAAAAAAADhwOHB4cLPcKAAyB8WEAGGz3KAAJidIKISEAGGIaITEAGG
    +IqIUEAGGI6IVEAGGJKIkEAGGJqLPcZ8AuP9WoYoh/w8SGFiAExhYgBQYWIAVGFiAJBhYgMHCwcHB
    +wCAgQIcMyM9yoADIHw4aGIANyA8aGIAOyBAaGIAPEgE2AcgkeBEaGIAQyC0aGIDgfuHE/BzIvvwc
    +SL7hwOHB4cLhw/wcCLH8HEix/ByIsfwcyLH8HAiy/BxIsvwciLL8HMiy/BwIv2okgBDhxGokwBDh
    +xPHAz3CgANAbFIDPcYAAYAQEIICPz1EE4QChCvIvKQEAz3CAAAwP8CBAAEB42v/RwMHEayTAEMHE
    +aySAEMHEn3QEFAs0BBQKNAQUCTQEFAg0BBQHNAQUBjQEFAU0BBQENMHDwcLBwcHAwcRFLH4QCiZA
    +fsHEaySAFMHEICBAhwzIh7gMGhgwDcibuA0aGDAOyA4aGDAPyIe4DxoYMBDIEBoYMOB+4HjxwAzI
    +lbgMGhgwDcibuA0aGDAPyIq4jbiQuA8aGDDPcIAATBAYiBsIUQAPyM9xAAC8DKy4DxoYMHIOIAAP
    +2GfYtgogAYohRwbRwOB+8cDPcIAAfMcAgIYg/oEJ9A/IBSCADwAAANQPGhgwof+KIFUFhgogAYoh
    +hwro8eB4z3EDAEANz3CgAKggLaDPcYAAjARAgQFqAKHPcKAAOC4FgAQggA/AAAAAHQiAD8AAAABI
    +2M9xnwC4/xqhW6Fp2Bi4GaHPcIAAmAklgCOBIIHHcQAAiBMBBsAJ4HjPcIAAmAmVBcAJ4HjxwPIL
    +AAHPd4AAYASIdQboDQhRAAHYA/AA2AuvBekPCVEAAdgC8ADYCq8G6g0KUQAB2APwANgMrwDYz3ag
    +AMgfGB4YkAuPiiEQAA7oCI8M6M9wAwBADUUeGBAwpgLYGB4YkAPwMaYKjxjoCY8W6M9wAgCYRSAe
    +GJDPcIAAKAAhHhiQz3CAAFwEIh4YkBgWAJZFIAADGB4YkAyPCOgYFgCWhSABBBgeGJAPC1EAGBYA
    +loi4GB4YkM9wgAAwkgCQjuDMIKKCBvQYFgCWgLgYHhiQGO0A2JS4z3WAAIAEAKVx2Aa4Sg0gAfzZ
    +IIXPcAAATBw6DSABn7kYFgCWhbgYHhiQWQMAAc9xqqq7u89wnwC4/zagNqA2oDagz3GgAMg7DoGI
    +uA6haSBAAP7x4HjxwKXBQcBCwQwcADEQHEAxz3GAAHyKNBnADzAZAA8sGcAOKBmADiQZQA7PcIAA
    +fIogGEALz3CAAHyKHBgAC89wgAB8ihgYwArPcIAAfIoUGIAKz3CAAHyKEBjACM9wgAB8igwYgAjP
    +cIAAfIoIGEAIz3GAAACKgBkACHwZwAd4GYAHdBlAB3AZAAdsGQAHaBmABmQZQAZgGQAGXBnABVgZ
    +gAVUGUAFUBkABUwZwARIGYAERBlABEAZAATvoc6hraGMoSwZwAIoGYACJBlAAiAZAAIcGcABGBmA
    +ARQZQAEQGQABY6FqIAAD2BkAAGogwALUGQAAaiCAAtAZAABqIEAByBkAAGogAAHEGQAAaiDAAMAZ
    +AABqIIAAvBkAAGogQAC4GQAAaiAAALQZAABqIIABzBkAANDYn7jPcZ8AuP8doc9wgAAAAMSAUyXE
    +NVMmxTXXugHm077EoFMjwAQFJo4f0P4AANahBSCAD7D+AAAWoRiBUyfONQDdlLgYoUDDAcACwclz
    +DBQGMK4P4AAQFAcwz3CgALQPvKDPcaAAyDsugUYP4AB92IYPQAGaCyABqXAI2ADZSgsgAZm5z3CA
    +ADCSAJCO4MwgooLKIIEP4ADEMcohIQBkCGEBzyGhBf0Fz//xwL4IIAF72P4O4ADw2c9xgAB8ijQZ
    +wA8wGQAPLBnADigZgA4kGUAOz3CAAHyKIBhAC89wgAB8ihwYAAvPcIAAfIoYGMAKz3CAAHyKFBiA
    +Cs9wgAB8ihAYwAjPcIAAfIoMGIAIz3CAAHyKCBhACM9xgAAAioAZAAh8GcAHeBmAB3QZQAdwGQAH
    +bBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARAGQAE76HOoa2hjKEs
    +GcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC1BkAAGoggALQGQAA
    +aiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0GQAAaiCAAcwZAAAK
    +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
    +D8oiwgfKIGIByiOCDwAAggBABaLwyiQiAADaB/AAFgBBFCGMAAC0AeIvIEIB8woCgC4Mz/HRwOB+
    +4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjPcIAAjAfgfwCA4HjgfuB44H7g
    +eOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB4
    +4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4Hjg
    +fuB44H7geOB+4HjgfwHY4H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB+
    +4HjgfuB44H7geOB+4HjgfuB44H7geOB+4HjgfuB44H7geOB/AdjxwM9wgAAM0FYL7/ED2Q4Lz/HR
    +wOB+4HgC2M9xoADAHQ2hIdgGoQHYB6HgfgDZz3CgAMAdJ6AmoC2g4H7PcYAAlAcNCFEAAdgAqQGp
    +AImB4MoggQ8AAMQJyiCCDwAAgADgfwGhANjPcoAAlAcBqgCqz3GAADCSBokI6AeJBugAkQkIkQMB
    +2ACqANja8fHA4cUIdc9wgACgEAGIKwhRAAfw2gmP8OYOr/Fe2M9woADUCxiAANlCIAAIgODKIEwA
    +5QhEg4kGj/HgeOB+4HjgfuB44H7geOB+4HjgfuB44H7gePHACiHAD+tyBdg220okAAAdA6/wCiUA
    +AfHACiHAD+tyBdg720okAAAFA6/wCiUAAc9wAQDQ8c9xgACcBwChz3ABAMzxAaHPcAEA1PECoc9w
    +AQDY8eB/A6HPcAEAUPHPcYAAnAcAoQGhAqHPcAEAVPHgfwOh4H7geOB+4HjgfuB44H7gePHAcg2v
    +8WrYosGLcQHapgjgAEhzjegKIcAP63IF2IojjwyKJIEKhQKv8EolAACBwUTYAdp+COAASHOO6Aoh
    +wA/rcgXYiiOPDYokAQFdAq/wSiUAAAQUADFfCIIPAAAyBEAkgTBr2AHaSgjgAEhzjugKIcAP63IF
    +2IojkACKJMEKKQKv8EolAAACFAAxz3aAAKwHG3hBKMUATCUAigQeQBHR9gohwA/rcgXYiiOQAf0B
    +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
    +AAoAqQsIHgBY/wLwP//DAM//8cDPcIAA+PkSDe/vA9nu/68Az//xwOHFocGLcaYN7+8B2gAUBDDP
    +dYAA4PbPcIAAeG+pcRXalg9gAADbABQEMM9wgADoCFUlQRUD2n4PYAAC289wgAD4b1YlARMS2kII
    +oAAAwwDYoQDv76HA8cAeCO/vSiRAAih1GnIA3wfZgODKIGIAE3jCuM92gACkbwGmIqbPcGgf/wAD
    +pgpw6XEI2gpzcgugAEolQAQOpgpw6XEI2gpzSiRAAloLoABKJUAED6YKcOlxCNoKc0okQAJGC6AA
    +SiVABBCmhO0B2BGmCvALDVEQAtgRpgTwCQ2REPGm8qb/2ADZCdoIc0okgAIWC6AASiXABADZE9r/
    +20okAAUCC6AASiVABxOmz3AgACAgzQev7wem4HiA4ADZyiBBAAXygeAB2MogogBI2Q8hAQDPcIAA
    +HHDgfzGw4HjxwD4Pr+8E2qTBGnBqDO/vi3ECwAPDAN2pcQjaSiRAAqYKoABKJUAECHEBwDoLYACp
    +cgpwz3Kt3u++1g9gAADBcghv/wpwbQjQAM92gADoCM9wAAAg0lYmQROSC2AABNrPcAAAIdJVJsEW
    +ggtgAATaOob7hkEpwAXAuBi4E3gleEEvwRXAuRi5M3klfxqmz3EAAGgf+6a6C2/4CLgcps9xAABo
    +H6oLb/hALwASHaapcPEGr++kwOB48cB2Dq/viiAPCoIkAjqacXpyWnOIdah3CiGAIQogwCEOCaAA
    +nsGKcAYJoACLcYLGanD+CKAAyXFKcPYIoACEwalw7gigAIbBiMXpcOIIoACpcSpw2gigAIrBCnDS
    +CKAAjMGpcIrBNgmgAJDCi3DJcSoJoACSwslwhMEiCaAAlMKGwKlxFgmgAJbCmMaQwJLBqgigAMly
    +mseUwJbBngigAOlyyXDpcfYIoACcwpzAnsHKCKAAjsKfxW4IoAAEbY7AfgmgACRttwgQAIbAisGO
    +CKAAQCUCE4twhMGCCKAAQCUCFZTAQCUBE1IIoADJcpDAQCUBFUYIoADpcslw6XGeCKAAnMKMwJzB
    +MgigAMlyqgigAMlwyXCOwWIIoABAJQIXksBAJQETFgigAMlylsBAJQEVCgigAOlyyXDpcV4IoACc
    +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
    +ACEAABslQAAbJDAcwBEAAAAhDxwdIhgBHSYYAMcQmKaAgQAAwBcgAMcQoKaAgQAAwBcAAAAhrEqA
    +gQIAXG4RAABh+EHEEA8bCSIACwk5AgAKYgMBCmIEAgpiAAAJQAQAAGEJAAlAAgAAYQoACUAAAABh
    +AgAJQQAJGigAAMAWAQAbJgAAwBcEAB0mAQAIJ+kACGQAAAAhAAAAAIwBAAABAQEBAQAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAABw5AADwOgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFKKA
    +AAAAAAAAAAAAAAAAAAEAAAAHAAAAAAAAAMAAkADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAADAAAAaLGAAAAAAAAAAAAAQLWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAA/wAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIi6gAConQEAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAAAAAAAAAAAAAQAA
    +AAEAAAAAAAAAAAAAAAAAAAABAQECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABosYAAfN8BAAAA
    +AABosYAATOYBAAAAAAAAAAAAaLGAAOTnAQAAAAAAAAAAAAAAAABosYAAAAAAAAAAAAAAAAAA/wAA
    +AAAAAAAAAAAAUPEBAFDxAQBQ8QEAVPEBAAAAAAAdAAAAAAAAAAAAAAAAAAAAAAAAAH9/AAEAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAABAgQIAAgQIAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAAAAAAAAAcAAAAHAAAABwAAAAIAAAACAAAAgwAAAJIA
    +AADoAAAA9wAAAE4BAABdAQAAAAABAAIAAACDAAAAkgAAAOgAAAD3AAAATgEAAF0BAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAQAPAGQAAQDICIAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAEAAgAAAIMAAACSAAAA6AAAAPcAAABOAQAAXQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAOAIAAAVAAAABEeAAAQrAAAEKwAABCsAADBBAAAEKwAABCsAALA8AAAE
    +KwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAABQHgAA+B8AABAgAAB8IQAA/CEAAIAh
    +AAAEKwAABCsAAGhNAAAoTwAAEFAAAAQrAAAEKwAABCsAAOxLAABEYgAAQGIAAJhiAAAEKwAABCsA
    +AAQrAAA8QwAABCsAAHxiAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAADRBAAAEKwAA
    +BCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAE
    +KwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAChEAAAEKwAABCsAAAQrAAAEKwAABCsAAAxF
    +AAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAHBpAAAEKwAA0GoA
    +AAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAAaG0AAAQrAAAEKwAABCsAAAQrAAAEKwAA
    +BCsAAAQrAAAEKwAABCsAAAQrAAAEKwAAzIIBAByGAQAEKwAAaIgBAAQrAAAUigEAwFYBAAQrAAAE
    +KwAA1FAAAAQrAAAEKwAABCsAAAQrAAAEKwAAuNcBAAzYAQAEKwAABCsAAAQrAAAEKwAABCsAAAQr
    +AAAEKwAABCsAAAQrAAAEKwAABCsAAPx0AAAEKwAABCsAAAQrAADY3QEABCsAAOjhAQAEKwAAvP8B
    +AAQrAAAgJQAAJCUAAAQrAAAEKwAAePABALx3AAAEKwAABCsAAAQrAABE2wEABCsAAAQrAAA0UAEA
    +dKEBAAQrAAAEKwAABCsAADyqAQDcVwEABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAAMK0BAAQrAABw
    +7wEAdO8BAIDvAQCE7wEAeO8BAHzvAQCI7wEABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQr
    +AAAEKwAAuFIAAAQrAAAEKwAABCsAAAQrAAAEKwAAxO4BABTvAQAQRwAABCsAAAQrAAAEKwAABCsA
    +AAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAA
    +BCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAEKwAABCsAAAQrAAAE
    +KwAABCsAAAQrAAAEKwAABCsAAIhIAAAQSQAAoEkAAFRKAABwhgAALEoAAAQrAAAEKwAABCsAAAQr
    +AAAEKwAAgEgAAIRIAAAEKwAABCsAAARRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAAlAwA
    +AJQMAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAAlAwAAJQMAACUDAAA
    +lAwAAJQMAACUDAAAlAwAAJQMAACUDAAAxA0AAAAAAAAwXQEAlAwAALgJAACUDAAAlAwAAJQMAADo
    +CQAA6D8BAJCIAACUDAAAlAwAABwKAAAcCgAAHAoAABwKAAAcCgAAHAoAABwKAACUDAAAlAwAAJQM
    +AACUDAAABAwAAJQMAACUDAAAlAwAAJQMAACUDAAAyA0AAJQMAACUDAAAnAkAAAMAAACQ7AEAAgAA
    +ACxrAQAEAAAA3GsBAAUAAADkDQAABgAAALgzAAAIAAAA8O4BABMAAACc2AEACQAAAITjAQAKAAAA
    +jO8BAA4AAACQngEADwAAAECMAQAQAAAAeIwBABkAAACYXAEADQAAABCEAQAXAAAAuHcAABEAAADk
    +hgAAEgAAADxPAQABAAAAXN0BABQAAAB8qwEAFQAAAKShAQAHAAAA2G0AABYAAACs/wEAGAAAAOSg
    +AAAaAAAAxA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAABAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEBAAAAAAAAAAAAABAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +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
    +AAAAAAAAAORBAQAKAAAAxEaAAAAAAAAAAAAAAAAAAORBAQAKAAAAxEaAAAAAAAAAAAAAAAAAAORB
    +AQAKAAAAxEaAAAAAAAAAAAAAAAAAAPSHAQAKAAAAxEaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAABQjwEAVJABACSTAQDQlQEASJgBAKybAQD4kQEANAWAADCxgAAYAAAA8LCA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAOJ4BAAYAAADERoAA/////wAAAAD//////////wAAAAAAAAAA
    +AAAAAAShAQAFAAAABEeAAG4AbgBpAMAAoABQAIAAvgBQAX0APgBuAG4AaQDAAKAAUACAAL4AUAF9
    +AD4AAAAAAAEBAAAAAAAAAAECAQEAAgEAAQICAgABAQACAQIBAgACAAECA///AAC5Ad8AsQAbABYB
    +GwB8ARsArwAbABQBGwB6ARsAbACgANEAoAA3AaAAbwCDAHEAgwB2AIMAcwAzAG4AMwBwADMAcgAz
    +ANcAMwA9ATMA1AEGANABAAB+ADwA4wA8AEkBPAB4AEkA3QBJAEMBSQB/AFoA5ABaAEoBWgCqAD8A
    +qwABAA8BPwAQAQEAdQE/AHYBAQB5AGoA3gBqAEQBagCoAAAADQEAAHMBAACmADcApwABAAsBNwAM
    +AQEAcQE3AHIBAQAEAAgAnAHMAJ0BzACeAcwAnwHMANUBzADWAcwA1wHMALQARwAZAUcAgAFHAJAA
    +IgD1ACIAWwEiAKEAiAAGAYgAbAGIAJQAAACVAAAAmADAAJkAoACWAJAAlwAAAJQAAQCVAAEAmADA
    +AJkAoACWAJAAlwAAAJQAAgCVAAMAmADAAJkAoACWAJAAlwAAAJQAAwCVAAcAmADAAJkAoACWAJAA
    +lwAAAPoAAAD5AAAAAgGQAAMB0wAAAYMA/gATAPwAMwD9AHcA+gABAPkAAQACAZAAAwHTAAABgwD+
    +ABMA/AAzAP0AdwD6AAIA+QADAAIBkAADAdMAAAGDAP4AEwD8ADMA/QB3APoAAwD5AAcAAgGSAAMB
    +0wAAAYMA/gATAPwAMwD9AHcAXwEAAGEBAABoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwBfAQEAYQEB
    +AGgBkABpAdMAZgGDAGQBEwBiATMAYwF3AF8BAgBhAQMAaAGQAGkB0wBmAYMAZAETAGIBMwBjAXcA
    +XwEDAGEBBwBoAZAAaQHTAGYBgwBkARMAYgEzAGMBdwCFAAAAhgAAAIcAUACIAAAAiQCgAIoAAACL
    +ANAAjAAAAIUAAQCGAAEAhwBQAIgAAACJAKAAigAAAIsA0ACMAAAAhQACAIYAAwCHAFAAiAAAAIkA
    +oACKAAAAiwDQAIwAAACFAAMAhgAHAIcAUACIAAAAiQCgAIoAAACLANAAjAAAAOsAAADqAAAA7ABQ
    +AO0AAADuAKAA7wAAAPAA0ADxAAAA6wABAOoAAQDsAFAA7QAAAO4AoADvAAAA8ADQAPEAAADrAAIA
    +6gADAOwAUADtAAAA7gCgAO8AAADwANAA8QAAAOsAAwDqAAcA7ABQAO0AAADuAKAA7wAAAPAA0ADx
    +AAAAUQEAAFABAABSAVAAUwEAAFQBoABVAQAAVgHQAFcBAABRAQEAUAEBAFIBUABTAQAAVAGgAFUB
    +AABWAdAAVwEAAFEBAgBQAQMAUgFQAFMBAABUAaAAVQEAAFYB0ABXAQAAUQEDAFABBwBSAVAAUwEA
    +AFQBoABVAQAAVgHQAFcBAAD7/wAA//8AALkB3wCxABsAFgEbAHwBGwCvABsAFAEbAHoBGwBsAKAA
    +0QCgADcBoABvAIMAcQCDAHYAgwBzADMAbgAzAHAAMwByADMA1wAzAD0BMwDUAQYA0AEAAH4APADj
    +ADwASQE8AHgASQDdAEkAQwFJAH8AWgDkAFoASgFaAKoAPwCrAAEADwE/ABABAQB1AT8AdgEBAHkA
    +agDeAGoARAFqAKgAAAANAQAAcwEAAKYANwCnAAEACwE3AAwBAQBxATcAcgEBAAQACACcAcwAnQHM
    +AJ4BzACfAYgA1QHMANYBzADXAcwAtABHABkBRwCAAUcAkAAiAPUAIgBbASIAoQCIAAYBiABsAYgA
    ++gAAAPkAAAACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAEA+QABAAIBlwADAdAAAAGNAP4AEQD8
    +ADMA/QB3APoAAgD5AAMAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gADAPkABwACAZcAAwHQAAAB
    +jQD+ABEA/AAzAP0AdwBfAQAAYQEAAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3AF8BAQBhAQEAaAGX
    +AGkB0ABmAY0AZAERAGIBMwBjAXcAXwECAGEBAwBoAZcAaQHQAGYBjQBkAREAYgEzAGMBdwBfAQMA
    +YQEHAGgBlwBpAdAAZgGNAGQBEQBiATMAYwF3AOsAAADqAAAA7ABVAO0AAADuAKoA7wAAAPAA3QDx
    +AAAA6wABAOoAAQDsAFUA7QAAAO4AqgDvAAAA8ADdAPEAAADrAAIA6gADAOwAVQDtAAAA7gCqAO8A
    +AADwAN0A8QAAAOsAAwDqAAcA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAAUQEAAFABAABSAVUAUwEA
    +AFQBqgBVAQAAVgHdAFcBAABRAQEAUAEBAFIBVQBTAQAAVAGqAFUBAABWAd0AVwEAAFEBAgBQAQMA
    +UgFVAFMBAABUAaoAVQEAAFYB3QBXAQAAUQEDAFABBwBSAVUAUwEAAFQBqgBVAQAAVgHdAFcBAAD7
    +/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoKwBALTNAQCwu4AAQAUA
    +AAAAAACgrAEAwK0BAPDAgAD4AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhNIBAIzQAQDowoAA
    +VAAAAAAAAACgrAEAuNABAGjDgABQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAoKwBANTMAQC0
    +V4AAUAEAAAAAAACgrAEA7M4BAOgGgAACAAAAAAAAAKCsAQBEzwEA7AaAAAQAAAAAAAAAgNIBAMCt
    +AQA8w4AAKgAAAAAAAACgrAEA4M8BAAAAAAAAAAAAAAAAAKCsAQCgzwEA8AaAAAQAAAAAAAAAAAAA
    +AAAAAAABAAIAAgADAAQABAAFAAYABgAHAAgACAAJAAoACgALAAwADAANAA4ADgAPACYAJwAoACgA
    +KQAqAEYARgBHAEgASABJAEoASgBLAEwAaABpAGoAagBrAGwAbABtAG4AbgBvAHAAcABxAHIAcgBz
    +AHQAdAB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AA8APwAAAAAAAAAAAAAA
    +AAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkACgAKAAsAJAAkACUAJgAmACcARABEAEUARgBG
    +AEcASABIAEkASgBKAEsATABMAE0AagBqAGsAbABsAG0AbgBuAG8AcABwAHEAcgByAHMAdAB0AHUA
    +dgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AHYAdgB2AA4APwCIpwEAEtIAAAAAAAD/
    +/w8ARLsBALYAAAAAAAAA/wAAAES7AQC3AAAAAAAAAP8AAABEuwEAuAAAAAAAAAD/AAAARLsBALkA
    +AAAAAAAA/wAAAES7AQC6AAAAAAAAAP8AAABEuwEAuwAAAAAAAAD/AAAARLsBAL0AAAAAAAAA/wAA
    +AES7AQC+AAAAAAAAAP8AAABEuwEAvwAAAAAAAAD/AAAARLsBAMAAAAAAAAAA/wAAAES7AQDBAAAA
    +AAAAAP8AAABEuwEAwgAAAAAAAAD/AAAAiKcBABPSAAAAAAAA//8PAES7AQAbAQAAAAAAAP8AAABE
    +uwEAHAEAAAAAAAD/AAAARLsBAB0BAAAAAAAA/wAAAES7AQAeAQAAAAAAAP8AAABEuwEAHwEAAAAA
    +AAD/AAAARLsBACABAAAAAAAA/wAAAES7AQAiAQAAAAAAAP8AAABEuwEAIwEAAAAAAAD/AAAARLsB
    +ACQBAAAAAAAA/wAAAES7AQAlAQAAAAAAAP8AAABEuwEAJgEAAAAAAAD/AAAARLsBACcBAAAAAAAA
    +/wAAAIinAQAU0gAAAAAAAP//DwBEuwEAggEAAAAAAAD/AAAARLsBAIMBAAAAAAAA/wAAAES7AQCE
    +AQAAAAAAAP8AAABEuwEAhQEAAAAAAAD/AAAARLsBAIYBAAAAAAAA/wAAAES7AQCHAQAAAAAAAP8A
    +AABEuwEAiQEAAAAAAAD/AAAARLsBAIoBAAAAAAAA/wAAAES7AQCLAQAAAAAAAP8AAABEuwEAjAEA
    +AAAAAAD/AAAARLsBAI0BAAAAAAAA/wAAAES7AQCOAQAAAAAAAP8AAACIpwEACNIAAAAAAAD//wMA
    +yKcBAACCAAAAAAAA/wEAAMinAQABggAAAAAAAP8BAACIpwEACdIAAAAAAAD//wMAyKcBAAKCAAAA
    +AAAA/wEAAMinAQADggAAAAAAAP8BAACIpwEACtIAAAAAAAD//wMAyKcBAASCAAAAAAAA/wEAAMin
    +AQAFggAAAAAAAP8BAACIpwEABtIAAAAAAAD/AQAAiKcBAAfSAAAAAAAA/wMAAIinAQAG0gAACQAA
    +AAD+AwCIpwEAB9IAAAoAAAAA/A8AiKcBAAbSAAASAAAAAAD8B4inAQAH0gAAFAAAAAAA8D+IpwEA
    +FdIAAAAAAAD/AwAAiKcBAAzSAAAAAAAA/wEAAIinAQAV0gAACgAAAAD8DwCIpwEADNIAAAkAAAAA
    +/gMAiKcBABXSAAAUAAAAAADwP4inAQAM0gAAEgAAAAAA/AcwgAAAqqqqqjGAAACqqqqqMoAAAACq
    +qqozgAAAAAAAADSAAAAAAAAANYAAAAAAAAA2gAAAAAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAA
    +ADqAAAAAAAAAO4AAAAAAAAA8gAAAAAAAAD2AAACqqgoAPoAAAKqqqqo/gAAAqqqqqkCAAAAAAAAA
    +MIAAAKqqqqoxgAAAqqqqqjKAAAAAqqqqM4AAAAAAAAA0gAAAAAAAADWAAAAAAAAANoAAAAAAAAA3
    +gAAAAAAAADiAAAAAAAAAOYAAAAAAAAA6gAAAAAAAADuAAAAAAAAAPIAAAAAAAAA9gAAAqqoKAD6A
    +AACqqqqqP4AAAKqqqqpAgAAAAAAAADCAAAAAAAAAMYAAAAAAAAAygAAAAAAAADOAAAAAAAAANIAA
    +AKqqqqo1gAAAqqqqqjaAAAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAKqqqgo7gAAA
    +qqqqqjyAAAAAAAAAPYAAAAAAAAA+gAAAAAAAAD+AAAAAAAAAQIAAAAAAAAAwgAAAAAAAADGAAAAA
    +AAAAMoAAAAAAAAAzgAAAAAAAADSAAACqqqqqNYAAAKqqqqo2gAAAAAAAADeAAAAAAAAAOIAAAAAA
    +AAA5gAAAAAAAADqAAACqqqoKO4AAAKqqqqo8gAAAAAAAAD2AAAAAAAAAPoAAAAAAAAA/gAAAAAAA
    +AECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAA0BYAAMLGAABgAAADwsIAAAAAAAAAAAAAAAAAAAAAAAAAAAABM3wEABgAAAMRGgAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQF
    +gAAwsYAAGAAAAPCwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAAAAAA
    +AGzqAQAEAAAAxEaAAAAAAAAAAAAAAAAAAFzsAQAGAAAAxEaAAAAAAAAAAAAAAAAAAGzqAQAEAAAA
    +xEaAAAAAAAAAAAAAAAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAAAAAAAGzqAQAEAAAAxEaAAAAAAAAA
    +AAAAAAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAAAAAAAGzqAQAEAAAAxEaAAAAAAAAAAAAAAAAAAFzs
    +AQAGAAAAxEaAAAAAAAAAAAAAAAAAAGzqAQAEAAAAxEaAAAAAAAAAAAAAAAAAAJTrAQAEAAAAxEaA
    +AAAAAAAAAAAAAAAAAFzsAQAGAAAAxEaAAAAAAAAAAAAAAAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAA
    +AAAAAJTrAQAEAAAAxEaAAAAAAAAAAAAAAAAAAFzsAQAGAAAAxEaAADQFgAAwsYAAGAAAAPCwgAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAQIDBAQEBAQFBgcICAgICAkKCwwNAAAABQYHCA0ODxAVFhcYGQAACg0RFAoNERQZGRkZ
    +CgoAAAAAAAAGBgYGCQkJCQAGAABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluK2grYitcK24qaCpi
    +KlwqbiloKWIpXCluG2gbYhtcG24aaBpiGlwabhloGWIZXBluGGgYYhhcGG4XaBdiF1wXbhZoFmIW
    +XBZuFWgVYhVcFW4UaBRiFFwUbhNoE2ITXBNuEmgSYhJcEm4RaBFiEVwRbhBoEGIQXBBXEFIQTRBJ
    +EG4BaAFiAVwBbgBoAGIAXABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluOGg4YjhcOG43aDdiN1w3
    +biloKWIpXCluKGgoYihcKG4naCdiJ1wnbhloGWIZXBluGGgYYhhcGG4XaBdiF1wXbgloCWIJXAlu
    +CGgIYghcCG4HaAdiB1wHbgZoBmIGXAZuBWgFYgVcBW4EaARiBFwEbgNoA2IDXANuAmgCYgJcAm4B
    +aAFiAVwBbgBoAGIAXAAAAAAAAAAAAAAAAADUAQIACAAAAARHgAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////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//////////////////////8iIyT/JSYn//8o////Kf//////
    +////////////////////////////////////////////////////////////////////////AQQA
    +AAIFAQADBgIABAcDAAUIBAAGCQUABwoGAAgLBwAJDAgACg0JAAsOCgAMDwsADRAMAA4RDQABQAAE
    +AkEBBANCAgQEQwMEBUQEBAZFBQQHRgYECEcHBAlICAS3EyIAuBQjALkVJAC7FiUAvBcmAL0YJwDA
    +GSgAxBopAAcbAAAIHAEACx0CAAweAwAQHwQAIiEFACQiBgAmIwcAKCQIAColCQAsJgoALicLADAo
    +DAA0KQ0AOCoOADwrDwBALBAAZC4RAGgvEgBsMBMAcDEUAHQyFQB4MxYAfDQXAIA1GACENhkAiDca
    +AIw4GwCROhwAlTsdAJk8HgCdPR8AoT4gAKU/IQAkSQYCLEoKAjRLDQE8TA8BZE0RAWxOEwF0TxUB
    +fFAXAYRRGQGVUh0BnVMfARzSDdIR0hDSAtIB0gPSG9IL0gCABdIS0hPSFNIEQwbSB9IE0nDSAAC1
    +ABoBgQEFAAQABgAIAAkACgALAAwAgwCSAOgA9wBOAV0BDwAE0g3SEdIQ0gLSAdID0hvSAIAF0gvS
    +EtIT0hTSBENw0gAAAAABAAAA////////////////AwAAAAIAAAADAAAAAwAAAAAAAAD/////AAAA
    +AAAAAAAAAAAA/wMAAAAAAAC1ABoBgQEEAA8ABgAIAAkACgALAAwAAAAAAAAAAAAsAAEAFQAVABUA
    +AQABAAEAAAA4AAAAaAAAAHQAAACAAAAAjAAAAJ0AAAAHAAAABAAAAAgAAAAQAAAAQAAAAIAAAAAg
    +AAAAAAAAAAkAAAASAAAAAAAAAAoAAAAUAAAAOAAAAGgAAAB0AAAAgAAAAIwAAACdAAAABwAAAAAA
    +AAAAAAAACgAAAA3SEdIQ0gLSAdID0hvSC9IAgAXSEtIT0hTSBEMI0gnSCtIc0gbSB9Jw0gAAAQAA
    +AAAAAAAAAAAAAAAAAAMAAAAEAAAAAwAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAP8DAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtQAaAYEBBAAPAIMA6ABOAZIA9wBdAQYACAAJAAoACwAM
    +AAUAAAAAAAAALAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAAA/////wAAAAAtAQAA3QEAAFoC
    +AAC6AgAACgMAAE0DAACHAwAAugMAAOgDAAARBAAANwQAAFkEAAB6BAAAmAQAALQEAADOBAAA5wQA
    +AP4EAAAVBQAAKgUAAD4FAABRBQAAZAUAAHUFAACGBQAAlwUAAKcFAAC2BQAAxQUAANMFAADhBQAA
    +7gUAAPsFAAAIBgAAFAYAACAGAAArBgAANwYAAEIGAABMBgAAVwYAAGEGAABrBgAAdQYAAH4GAACI
    +BgAAkQYAAJoGAACiBgAAqwYAALQGAAC8BgAAxAYAAMwGAADUBgAA2wYAAOMGAADqBgAA8gYAAPkG
    +AAAABwAABwcAAA4HAAAUBwAAGwcAACIHAAAoBwAALgcAADUHAAA7BwAAQQcAAEcHAABNBwAAUwcA
    +AFgHAABeBwAAZAcAAGkHAABvBwAAdAcAAHkHAAB/BwAAhAcAAIkHAACOBwAAkwcAAJgHAACdBwAA
    +ogcAAKcHAACrBwAAsAcAALUHAAC5BwAAvgcAAMIHAADHBwAAywcAANAHAADUBwAA2AcAANwHAADh
    +BwAA5QcAAOkHAADtBwAA8QcAAPUHAAD5BwAA/QcAAAEIAAAFCAAACAgAAAwIAAAQCAAAFAgAABcI
    +AAAbCAAAHwgAACIIAAAmCAAAKQgAAC0IAAAwCAAANAgAADcIAAA7CAAAPggAAEEIAABFCAAASAgA
    +AEsIAABPCAAAUggAAFUIAABYCAAAWwgAAF8IAABiCAAAZQgAAGgIAABrCAAAbggAAHEIAAB0CAAA
    +dwgAAHoIAAB9CAAAgAgAAIIIAACFCAAAiAgAAIsIAACOCAAAkQgAAJMIAACWCAAAmQgAADgAAABo
    +AAAAdAAAAIAAAACMAAAAnQAAAAcAAAAAAAAAAAAAAAoAAAAN0hHSENIC0gHSA9Ib0gvSAIAF0hLS
    +E9IU0gRDCNIJ0grSHNIG0gfScNIAAAEAAAAAAAAAAAAAAAAAAAADAAAABAAAAAMAAAAAAAAAAwAA
    +AAAAAAAAAAAAAAAAAAAAAAD/AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALUAGgGBAQQA
    +DwCDAOgATgGSAPcAXQEGAAgACQAKAAsADAAFAAAAAAAAACwAAQAAAAAAAAAAAAAAAAAAAAAAAAAB
    +AAEAAQAAAN8AAAAZAQAAYgEAAL4BAAAyAgAAwwIAAHsDAABiBAAAhAUAAPIGAAC+CAAAAgsAAAEA
    +AAACAAAAAAAAAAvSDtIN0gjSCdIK0hLSE9IU0hHSENIC0gHSA9IAgAXSBEMb0hzSBNIARTDSMdIA
    +AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAHAAAAAAAAAAMAAAAEAAAA
    +AwAAAAAAAAD/AwAAAwAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAtQAaAYEBBQAE
    +AA8AEAAKAAsADABOAAAAAAAAAAAAAAAsAAEAAAABAAEAAQAAAAAAAAAAAAEAAQACAAIAAgADAAMA
    +BAAEAAUABQAGAAYABwAHAAgACAAJAAkACgAKAAsACwAMAAwADQANAA4ADgAPAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAIA
    +AAAPAD8AAQAAAAAAAAABAAAAAgAAAAMAAAAAAAAABAAAAAIAAAAFAAAADxQZHigKBQDBCQGlADw4
    +NDAsKCQgHBgUEAwIBAAMCAQAPDg0MCwoJCAcGBQQDAgEAggADgAAAA4BAQABAgEBAQAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKXG
    +hPiZ7o32Df+91rHeVJFQYAMCqc59VhnnYrXmTZrsRY+dH0CJh/oV7+uyyY4L++xBZ7P9X+pFvyP3
    +U5bkW5vCdRzhrj1qTFpsQX4C9U+DXGj0UTTRCPmT4nOrU2I/KgwIUpVlRl6dKDChNw8KtS8JDjYk
    +mxs93ybNaU7Nf5/qGxKeHXRYLjQtNrLc7rT7W/akTXZht859e1I+3XFelxP1pmi5AAAswWBAH+PI
    +ee22vtRGjdlnS3LelNSY6LBKhWu7KsXlTxbtxYbXmlVmlBHPihDpBgSB/vCgRHi6JeNL86L+XcCA
    +igWtP7whSHAE8d9jwXd1r2NCMCAa5Q79bb9MgRQYNSYvw+G+ojXMiDkuV5PyVYL8R3qsyOe6KzKV
    +5qDAmBnRnn+jZkR+VKs7gwvKjCnH02s8KHmn4rwdFnatO9tWZE50HhTbkgoMbEjkuF2fbr3vQ6bE
    +qDmkMTfTi/Iy1UOLWW632owBZLHSnOBJtNj6rAfzJc+vyo706UcYENVviPBvSnJcJDjxV8dzUZcj
    +y3yhnOghPt2W3GGGDYUPkOBCfMRxqszYkAUGAfcSHKPCX2r5rtBpkRdYmSc6uSc42RPrsyszIrvS
    +cKmJB6czti0iPJIVIMlJh/+qeFB6pY8D+FmACRca2mUx18aEuNDDgrApd1oRHst7/KjWbTosAQEB
    +AQEBAQECAgICAgICAgMDAwMDAwMDBAQEBAQEBAQBAgICAgICAwMDAwMDAwMDAwMDAwMEBAQEBAQE
    +BAQEBAQEBAQEBAQEBAQEBAQAAAAAAQECAQICA3//Bw8fPwEDAQMPBwEHDx8/f///BQAHAgMEBgZ0
    +0UUX6KKLLg0PBQcJCwEDChQ3blVVVQFLaC8BVVVVBeM4jgOqqqoCcRzHAaqqqgrHcRwHDw8PBwYH
    +AgMEBQABCAkLCigAKAAwACwALAAoADwANAAoACgANAAwACwALABEADwAQAA8AIwAbABYAEgA9ACw
    +ACwALAA8ADQAMAAsAFQARABUAFQAbABgAFwAVACMAHgAOgECAdUA3wDaAKIAdQB/AGoBGgHZAOgA
    +CgG6AHkAiACKBSoDOQGoAYoFygLZAEgBygFKAeIA+QDKAeoAggCZAPQCRAK1AdUBlAKEAfUAQQKs
    +AJAAhACAAHgAeAB4AHQAZuYAAJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzETid2
    +YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUFBVRA
    +BSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN0iAN
    +CqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4gAcG
    +aZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiACgiM
    +wAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEQAOABsAJAA2AEwAaQB2A
    +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
    +bwFmGwACgAAAAwAAAXABaBwAAAAAAAQAAAFwAWwcAAEAAAADAAABcgFuHAACAAAABAAAAXIBcBwA
    +AgAAAAMAAAFzAnQdAAAAAAAEAAABdAJ2HQAAgAAAAwAAAXUCeB0AAQAAAAMAAAF2AnwdAAIAAAAD
    +AAABdwN+HQACgAAAAwAAAXgDgB4AAAAAAAQAAAF4A4QeAAEAAAADAAABegOGHgACAAAABAAAAXoE
    +iB4AAgAAAAMAAAF7BIwfAAAAAAAEAAABfASRHwABQAAAAwAAAX4ElR8AAwAAAAQAAAF/BZcfAALA
    +AAADAAABgAWZIAAAQAAAAwAAAYEFnSAAAUAAAAMAAAGCBZ8gAAHAAAADAAABgwWhIAADAAAABAAA
    +AYMFpSEAAEAAAAMAAAGFBQAACxkVGRcAAABY5AEAbOQBANTkAQAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAABAQEBAQEBAQICAgICAgIC
    +AwMDAwMDAwMBAgAADgAAACoAAAAJAAAACwAAABX2Y/aw9vz2RveQ99j3H/hl+Kn47fgv+XD5sPnu
    ++Sv6Z/qi+tz6FPtL+4H7tvvq+xz8Tfx9/Kv82fwF/TD9Wf2C/an9z/30/Rf+Of5a/nr+mP62/tL+
    +7f4G/x7/Nf9L/2D/c/+F/5b/pv+0/8H/zf/Y/+H/6f/w//b/+v/9//////////3/+v/2//D/6f/h
    +/9j/zf/B/7T/pv+W/4X/c/9g/0v/Nf8e/wb/7f7S/rb+mP56/lr+Of4X/vT9z/2p/YL9Wf0w/QX9
    +2fyr/H38Tfwc/Or7tvuB+0v7FPvc+qL6Z/or+u75sPlw+S/57fip+GX4H/jY95D3Rvf89rD2Y/Zw
    +uYO6lruqvL690r7nv/zAEcInwz3EU8VqxoDHl8ivycbK3sv2zA/OJ89A0FnRctKM06bUv9Xa1vTX
    +Dtkp2kTbX9x63Zbesd/N4OnhBeMh5D7lWuZ355PosOnN6urrB+0k7kLvX/B98ZryuPPV9PP1Efcv
    ++Ez5avqI+6b8xP3i/gAAHgE8AloDeASWBbQG0QfvCA0KKwtIDGYNgw6hD74Q3BH5EhYUMxVQFm0X
    +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
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAA
    +AAUFBQUFBQUFAAAAAIANAAAAIAAAgA0AAIANAAAAIAAAgA0AAAAGAAAABAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    +AAAAAAAAAAAAAA==
    +====
    diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
    index b6af7b8896b..be8c7c7d1a4 100644
    --- a/sys/dev/iwn/if_iwn.c
    +++ b/sys/dev/iwn/if_iwn.c
    @@ -74,157 +74,184 @@ __FBSDID("$FreeBSD$");
     
     static int	iwn_probe(device_t);
     static int	iwn_attach(device_t);
    -const struct iwn_hal *iwn_hal_attach(struct iwn_softc *);
    -void		iwn_radiotap_attach(struct iwn_softc *);
    +static const struct iwn_hal *iwn_hal_attach(struct iwn_softc *);
    +static 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_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_detach(device_t);
    +static int	iwn_nic_lock(struct iwn_softc *);
    +static int	iwn_eeprom_lock(struct iwn_softc *);
    +static int	iwn_init_otprom(struct iwn_softc *);
    +static int	iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
    +static void	iwn_dma_map_addr(void *, bus_dma_segment_t *, int, 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_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_ict(struct iwn_softc *);
    -void		iwn_free_ict(struct iwn_softc *);
    -int		iwn_alloc_fwmem(struct iwn_softc *);
    -void		iwn_free_fwmem(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 *);
    -int		iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
    +static int	iwn_alloc_sched(struct iwn_softc *);
    +static void	iwn_free_sched(struct iwn_softc *);
    +static int	iwn_alloc_kw(struct iwn_softc *);
    +static void	iwn_free_kw(struct iwn_softc *);
    +static int	iwn_alloc_ict(struct iwn_softc *);
    +static void	iwn_free_ict(struct iwn_softc *);
    +static int	iwn_alloc_fwmem(struct iwn_softc *);
    +static void	iwn_free_fwmem(struct iwn_softc *);
    +static int	iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
    +static void	iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
    +static void	iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
    +static 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 *);
    -void		iwn5000_ict_reset(struct iwn_softc *);
    -int		iwn_read_eeprom(struct iwn_softc *,
    +static void	iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
    +static void	iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
    +static void	iwn5000_ict_reset(struct iwn_softc *);
    +static 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	iwn4965_read_eeprom(struct iwn_softc *);
    +static void	iwn4965_print_power_group(struct iwn_softc *, int);
    +static void	iwn5000_read_eeprom(struct iwn_softc *);
    +static uint32_t	iwn_eeprom_channel_flags(struct iwn_eeprom_chan *);
    +static void	iwn_read_eeprom_band(struct iwn_softc *, int);
    +#if 0	/* HT */
    +static void	iwn_read_eeprom_ht40(struct iwn_softc *, int);
    +#endif
     static void	iwn_read_eeprom_channels(struct iwn_softc *, int,
     		    uint32_t);
    -void		iwn_read_eeprom_enhinfo(struct iwn_softc *);
    -struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
    +static void	iwn_read_eeprom_enhinfo(struct iwn_softc *);
    +static 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_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
    +static void	iwn_newassoc(struct ieee80211_node *, int);
    +static int	iwn_media_change(struct ifnet *);
    +static int	iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
    +static 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_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
    +static void	iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
     		    struct iwn_rx_data *);
     #if 0	/* HT */
    -void		iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
    +static void	iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
     		    struct iwn_rx_data *);
     #endif
    -void		iwn5000_rx_calib_results(struct iwn_softc *,
    +static 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 *,
    +static 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 *,
    +static 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 *,
    +static 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,
    +static 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 *);
    -void		iwn_intr(void *);
    -void		iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
    +static void	iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
    +static void	iwn_notif_intr(struct iwn_softc *);
    +static void	iwn_wakeup_intr(struct iwn_softc *);
    +static void	iwn_rftoggle_intr(struct iwn_softc *);
    +static void	iwn_fatal_intr(struct iwn_softc *);
    +static void	iwn_intr(void *);
    +static void	iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
     		    uint16_t);
    -void		iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
    +static 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 *,
    +#ifdef notyet
    +static void	iwn5000_reset_sched(struct iwn_softc *, int, int);
    +#endif
    +static uint8_t	iwn_plcp_signal(int);
    +static int	iwn_tx_data(struct iwn_softc *, struct mbuf *,
     		    struct ieee80211_node *, struct iwn_tx_ring *);
     static int	iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
     		    const struct ieee80211_bpf_params *);
    -void		iwn_start(struct ifnet *);
    -void		iwn_start_locked(struct ifnet *);
    +static void	iwn_start(struct ifnet *);
    +static 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 *,
    +static int	iwn_ioctl(struct ifnet *, u_long, caddr_t);
    +static int	iwn_cmd(struct iwn_softc *, int, const void *, int, int);
    +static int	iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
     		    int);
    -int		iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
    +static int	iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
     		    int);
    -int		iwn_set_link_quality(struct iwn_softc *, uint8_t, int);
    -int		iwn_add_broadcast_node(struct iwn_softc *, int);
    -int		iwn_wme_update(struct ieee80211com *);
    +static int	iwn_set_link_quality(struct iwn_softc *, uint8_t, int);
    +static int	iwn_add_broadcast_node(struct iwn_softc *, int);
    +static int	iwn_wme_update(struct ieee80211com *);
     static void	iwn_update_mcast(struct ifnet *);
    -void		iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
    -int		iwn_set_critical_temp(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 *,
    +static void	iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
    +static int	iwn_set_critical_temp(struct iwn_softc *);
    +static int	iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
    +static void	iwn4965_power_calibration(struct iwn_softc *, int);
    +static int	iwn4965_set_txpower(struct iwn_softc *,
     		    struct ieee80211_channel *, int);
    -int		iwn5000_set_txpower(struct iwn_softc *,
    +static 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		iwn4965_get_temperature(struct iwn_softc *);
    -int		iwn5000_get_temperature(struct iwn_softc *);
    -int		iwn_init_sensitivity(struct iwn_softc *);
    -void		iwn_collect_noise(struct iwn_softc *,
    +static int	iwn4965_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
    +static int	iwn5000_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
    +static int	iwn_get_noise(const struct iwn_rx_general_stats *);
    +static int	iwn4965_get_temperature(struct iwn_softc *);
    +static int	iwn5000_get_temperature(struct iwn_softc *);
    +static int	iwn_init_sensitivity(struct iwn_softc *);
    +static 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 *,
    +static int	iwn4965_init_gains(struct iwn_softc *);
    +static int	iwn5000_init_gains(struct iwn_softc *);
    +static int	iwn4965_set_gains(struct iwn_softc *);
    +static int	iwn5000_set_gains(struct iwn_softc *);
    +static void	iwn_tune_sensitivity(struct iwn_softc *,
     		    const struct iwn_rx_stats *);
    -int		iwn_send_sensitivity(struct iwn_softc *);
    -int		iwn_set_pslevel(struct iwn_softc *, int, int, int);
    -int		iwn_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		iwn5000_send_wimax_coex(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 *,
    +static int	iwn_send_sensitivity(struct iwn_softc *);
    +static int	iwn_set_pslevel(struct iwn_softc *, int, int, int);
    +static int	iwn_config(struct iwn_softc *);
    +static int	iwn_scan(struct iwn_softc *);
    +static int	iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
    +static int	iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
    +#if 0	/* HT */
    +static int	iwn_ampdu_rx_start(struct ieee80211com *,
    +		    struct ieee80211_node *, uint8_t);
    +static void	iwn_ampdu_rx_stop(struct ieee80211com *,
    +		    struct ieee80211_node *, uint8_t);
    +static int	iwn_ampdu_tx_start(struct ieee80211com *,
    +		    struct ieee80211_node *, uint8_t);
    +static void	iwn_ampdu_tx_stop(struct ieee80211com *,
    +		    struct ieee80211_node *, uint8_t);
    +static void	iwn4965_ampdu_tx_start(struct iwn_softc *,
    +		    struct ieee80211_node *, uint8_t, uint16_t);
    +static void	iwn4965_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t);
    +static void	iwn5000_ampdu_tx_start(struct iwn_softc *,
    +		    struct ieee80211_node *, uint8_t, uint16_t);
    +static void	iwn5000_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t);
    +#endif
    +static int	iwn5000_query_calibration(struct iwn_softc *);
    +static int	iwn5000_send_calibration(struct iwn_softc *);
    +static int	iwn5000_send_wimax_coex(struct iwn_softc *);
    +static int	iwn4965_post_alive(struct iwn_softc *);
    +static int	iwn5000_post_alive(struct iwn_softc *);
    +static 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,
    +static int	iwn4965_load_firmware(struct iwn_softc *);
    +static 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 *);
    -int		iwn_clock_wait(struct iwn_softc *);
    -int		iwn_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 *);
    -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 *);
    -void		iwn_stop(struct iwn_softc *);
    +static int	iwn5000_load_firmware(struct iwn_softc *);
    +static int	iwn_read_firmware(struct iwn_softc *);
    +static int	iwn_clock_wait(struct iwn_softc *);
    +static int	iwn_apm_init(struct iwn_softc *);
    +static void	iwn_apm_stop_master(struct iwn_softc *);
    +static void	iwn_apm_stop(struct iwn_softc *);
    +static int	iwn4965_nic_config(struct iwn_softc *);
    +static int	iwn5000_nic_config(struct iwn_softc *);
    +static int	iwn_hw_prepare(struct iwn_softc *);
    +static int	iwn_hw_init(struct iwn_softc *);
    +static void	iwn_hw_stop(struct iwn_softc *);
    +static void	iwn_init_locked(struct iwn_softc *);
    +static void	iwn_init(void *);
    +static void	iwn_stop_locked(struct iwn_softc *);
    +static void	iwn_stop(struct iwn_softc *);
     static void 	iwn_scan_start(struct ieee80211com *);
     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 struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *,
    +		    struct ieee80211_channel *);
     static int	iwn_setregdomain(struct ieee80211com *,
     		    struct ieee80211_regdomain *, int,
     		    struct ieee80211_channel []);
    @@ -562,12 +589,15 @@ iwn_attach(device_t dev)
     #if IWN_RBUF_SIZE == 8192
     	    IEEE80211_HTCAP_AMSDU7935 |
     #endif
    -	    IEEE80211_HTCAP_SMPS_DIS |
     	    IEEE80211_HTCAP_CBW20_40 |
     	    IEEE80211_HTCAP_SGI20 |
     	    IEEE80211_HTCAP_SGI40;
     	if (sc->hw_type != IWN_HW_REV_TYPE_4965)
     		ic->ic_htcaps |= IEEE80211_HTCAP_GF;
    +	if (sc->hw_type == IWN_HW_REV_TYPE_6050)
    +		ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DYN;
    +	else
    +		ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DIS;
     #endif
     
     	/* Read MAC address, channels, etc from EEPROM. */
    @@ -643,7 +673,7 @@ fail:
     	return error;
     }
     
    -const struct iwn_hal *
    +static const struct iwn_hal *
     iwn_hal_attach(struct iwn_softc *sc)
     {
     	sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
    @@ -680,7 +710,7 @@ iwn_hal_attach(struct iwn_softc *sc)
     		break;
     	case IWN_HW_REV_TYPE_1000:
     		sc->sc_hal = &iwn5000_hal;
    -		sc->limits = &iwn5000_sensitivity_limits;
    +		sc->limits = &iwn1000_sensitivity_limits;
     		sc->fwname = "iwn1000fw";
     		sc->txchainmask = IWN_ANT_A;
     		sc->rxchainmask = IWN_ANT_AB;
    @@ -720,7 +750,7 @@ iwn_hal_attach(struct iwn_softc *sc)
     /*
      * Attach the interface to 802.11 radiotap.
      */
    -void
    +static void
     iwn_radiotap_attach(struct iwn_softc *sc)
     {
     	struct ifnet *ifp = sc->sc_ifp;
    @@ -761,8 +791,7 @@ iwn_vap_create(struct ieee80211com *ic,
     	    500 /* ms */);
     
     	/* Complete setup. */
    -	ieee80211_vap_attach(vap, ieee80211_media_change,
    -	    ieee80211_media_status);
    +	ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status);
     	ic->ic_opmode = opmode;
     	return vap;
     }
    @@ -777,7 +806,7 @@ iwn_vap_delete(struct ieee80211vap *vap)
     	free(ivp, M_80211_VAP);
     }
     
    -int
    +static int
     iwn_cleanup(device_t dev)
     {
     	struct iwn_softc *sc = device_get_softc(dev);
    @@ -832,7 +861,7 @@ iwn_detach(device_t dev)
     	return 0;
     }
     
    -int
    +static int
     iwn_nic_lock(struct iwn_softc *sc)
     {
     	int ntries;
    @@ -843,7 +872,7 @@ iwn_nic_lock(struct iwn_softc *sc)
     	/* 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 | IWN_GP_CNTRL_SLEEP)) ==
     		    IWN_GP_CNTRL_MAC_ACCESS_ENA)
     			return 0;
     		DELAY(10);
    @@ -938,7 +967,7 @@ iwn_mem_set_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t val,
     		iwn_mem_write(sc, addr, val);
     }
     
    -int
    +static int
     iwn_eeprom_lock(struct iwn_softc *sc)
     {
     	int i, ntries;
    @@ -969,7 +998,7 @@ iwn_eeprom_unlock(struct iwn_softc *sc)
      * Initialize access by host to One Time Programmable ROM.
      * NB: This kind of ROM can be found on 1000 or 6000 Series only.
      */
    -int
    +static int
     iwn_init_otprom(struct iwn_softc *sc)
     {
     	uint16_t prev, base, next;
    @@ -1023,7 +1052,7 @@ iwn_init_otprom(struct iwn_softc *sc)
     	return 0;
     }
     
    -int
    +static int
     iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
     {
     	uint32_t val, tmp;
    @@ -1096,8 +1125,7 @@ iwn_dma_contig_alloc(struct iwn_softc *sc, struct iwn_dma_info *dma,
     	    flags | BUS_DMA_ZERO, &dma->map);
     	if (error != 0) {
     		device_printf(sc->sc_dev,
    -		   "%s: bus_dmamem_alloc failed, error %d\n",
    -		   __func__, error);
    +		    "%s: bus_dmamem_alloc failed, error %d\n", __func__, error);
     		goto fail;
     	}
     	error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr,
    @@ -1116,7 +1144,7 @@ fail:
     	return error;
     }
     
    -void
    +static void
     iwn_dma_contig_free(struct iwn_dma_info *dma)
     {
     	if (dma->tag != NULL) {
    @@ -1132,7 +1160,7 @@ iwn_dma_contig_free(struct iwn_dma_info *dma)
     	}
     }
     
    -int
    +static int
     iwn_alloc_sched(struct iwn_softc *sc)
     {
     	/* TX scheduler rings must be aligned on a 1KB boundary. */
    @@ -1140,13 +1168,13 @@ iwn_alloc_sched(struct iwn_softc *sc)
     	    (void **)&sc->sched, sc->sc_hal->schedsz, 1024, BUS_DMA_NOWAIT);
     }
     
    -void
    +static void
     iwn_free_sched(struct iwn_softc *sc)
     {
     	iwn_dma_contig_free(&sc->sched_dma);
     }
     
    -int
    +static int
     iwn_alloc_kw(struct iwn_softc *sc)
     {
     	/* "Keep Warm" page must be aligned on a 4KB boundary. */
    @@ -1154,13 +1182,13 @@ iwn_alloc_kw(struct iwn_softc *sc)
     	    BUS_DMA_NOWAIT);
     }
     
    -void
    +static void
     iwn_free_kw(struct iwn_softc *sc)
     {
     	iwn_dma_contig_free(&sc->kw_dma);
     }
     
    -int
    +static int
     iwn_alloc_ict(struct iwn_softc *sc)
     {
     	/* ICT table must be aligned on a 4KB boundary. */
    @@ -1168,13 +1196,13 @@ iwn_alloc_ict(struct iwn_softc *sc)
     	    (void **)&sc->ict, IWN_ICT_SIZE, 4096, BUS_DMA_NOWAIT);
     }
     
    -void
    +static void
     iwn_free_ict(struct iwn_softc *sc)
     {
     	iwn_dma_contig_free(&sc->ict_dma);
     }
     
    -int
    +static int
     iwn_alloc_fwmem(struct iwn_softc *sc)
     {
     	/* Must be aligned on a 16-byte boundary. */
    @@ -1182,13 +1210,13 @@ iwn_alloc_fwmem(struct iwn_softc *sc)
     	    sc->sc_hal->fwsz, 16, BUS_DMA_NOWAIT);
     }
     
    -void
    +static void
     iwn_free_fwmem(struct iwn_softc *sc)
     {
     	iwn_dma_contig_free(&sc->fw_dma);
     }
     
    -int
    +static int
     iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
     {
     	bus_size_t size;
    @@ -1247,7 +1275,7 @@ iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
     		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__);
    +			    "%s: could not allocate rx mbuf\n", __func__);
     			error = ENOMEM;
     			goto fail;
     		}
    @@ -1278,7 +1306,7 @@ fail:
     	return error;
     }
     
    -void
    +static void
     iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
     {
     	int ntries;
    @@ -1302,7 +1330,7 @@ iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
     	sc->last_rx_valid = 0;
     }
     
    -void
    +static void
     iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
     {
     	int i;
    @@ -1324,7 +1352,7 @@ iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
     	}
     }
     
    -int
    +static int
     iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
     {
     	bus_size_t size;
    @@ -1398,7 +1426,7 @@ fail:
     	return error;
     }
     
    -void
    +static void
     iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
     {
     	int i;
    @@ -1421,7 +1449,7 @@ iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
     	ring->cur = 0;
     }
     
    -void
    +static void
     iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
     {
     	int i;
    @@ -1443,7 +1471,7 @@ iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
     	}
     }
     
    -void
    +static void
     iwn5000_ict_reset(struct iwn_softc *sc)
     {
     	/* Disable interrupts. */
    @@ -1468,7 +1496,7 @@ iwn5000_ict_reset(struct iwn_softc *sc)
     	IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
     }
     
    -int
    +static int
     iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
     {
     	const struct iwn_hal *hal = sc->sc_hal;
    @@ -1529,7 +1557,7 @@ iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
     	return 0;
     }
     
    -void
    +static void
     iwn4965_read_eeprom(struct iwn_softc *sc)
     {
     	uint32_t addr;
    @@ -1577,7 +1605,7 @@ iwn4965_read_eeprom(struct iwn_softc *sc)
     }
     
     #ifdef IWN_DEBUG
    -void
    +static void
     iwn4965_print_power_group(struct iwn_softc *sc, int i)
     {
     	struct iwn4965_eeprom_band *band = &sc->bands[i];
    @@ -1611,9 +1639,10 @@ iwn4965_print_power_group(struct iwn_softc *sc, int i)
     }
     #endif
     
    -void
    +static void
     iwn5000_read_eeprom(struct iwn_softc *sc)
     {
    +	struct iwn5000_eeprom_calib_hdr hdr;
     	int32_t temp, volt;
     	uint32_t addr, base;
     	int i;
    @@ -1637,6 +1666,12 @@ iwn5000_read_eeprom(struct iwn_softc *sc)
     
     	iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
     	base = le16toh(val);
    +	iwn_read_prom_data(sc, base, &hdr, sizeof hdr);
    +	DPRINTF(sc, IWN_DEBUG_CALIBRATE,
    +	    "%s: calib version=%u pa type=%u voltage=%u\n",
    +	    __func__, hdr.version, hdr.pa_type, le16toh(hdr.volt));
    +	    sc->calib_ver = hdr.version;
    +
     	if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
     		/* Compute temperature offset. */
     		iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
    @@ -1706,6 +1741,10 @@ iwn_read_eeprom_band(struct iwn_softc *sc, int n)
     		c->ic_ieee = chan;
     		c->ic_maxregpower = channels[i].maxpwr;
     		c->ic_maxpower = 2*c->ic_maxregpower;
    +
    +		/* Save maximum allowed TX power for this channel. */
    +		sc->maxpwr[chan] = channels[i].maxpwr;
    +
     		if (n == 0) {	/* 2GHz band */
     			c->ic_freq = ieee80211_ieee2mhz(chan,
     			    IEEE80211_CHAN_G);
    @@ -1812,7 +1851,7 @@ iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
     
     #define nitems(_a)	(sizeof((_a)) / sizeof((_a)[0]))
     
    -void
    +static void
     iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
     {
     	struct iwn_eeprom_enhinfo enhinfo[35];
    @@ -1849,13 +1888,13 @@ iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
     	}
     }
     
    -struct ieee80211_node *
    +static struct ieee80211_node *
     iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
     {
     	return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
     }
     
    -void
    +static void
     iwn_newassoc(struct ieee80211_node *ni, int isnew)
     {
     	struct ieee80211vap *vap = ni->ni_vap;
    @@ -1865,7 +1904,7 @@ iwn_newassoc(struct ieee80211_node *ni, int isnew)
     	    &wn->amn, ni);
     }
     
    -int
    +static int
     iwn_media_change(struct ifnet *ifp)
     {
     	int error = ieee80211_media_change(ifp);
    @@ -1873,7 +1912,7 @@ iwn_media_change(struct ifnet *ifp)
     	return (error == ENETRESET ? 0 : error);
     }
     
    -int
    +static int
     iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
     {
     	struct iwn_vap *ivp = IWN_VAP(vap);
    @@ -1920,7 +1959,7 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
      * Process an RX_PHY firmware notification.  This is usually immediately
      * followed by an MPDU_RX_DONE notification.
      */
    -void
    +static void
     iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc,
         struct iwn_rx_data *data)
     {
    @@ -1964,7 +2003,7 @@ iwn_calib_reset(struct iwn_softc *sc)
      * 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
    +static void
     iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
         struct iwn_rx_data *data)
     {
    @@ -2114,7 +2153,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
     
     #if 0	/* HT */
     /* Process an incoming Compressed BlockAck. */
    -void
    +static void
     iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
         struct iwn_rx_data *data)
     {
    @@ -2130,7 +2169,7 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
      * Process a CALIBRATION_RESULT notification sent by the initialization
      * firmware on response to a CMD_CALIB_CONFIG command (5000 only.)
      */
    -void
    +static void
     iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
         struct iwn_rx_data *data)
     {
    @@ -2146,7 +2185,8 @@ iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
     
     	switch (calib->code) {
     	case IWN5000_PHY_CALIB_DC:
    -		if (sc->hw_type == IWN_HW_REV_TYPE_5150)
    +		if (sc->hw_type == IWN_HW_REV_TYPE_5150 ||
    +		    sc->hw_type == IWN_HW_REV_TYPE_6050)
     			idx = 0;
     		break;
     	case IWN5000_PHY_CALIB_LO:
    @@ -2187,7 +2227,7 @@ iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
      * Process an RX_STATISTICS or BEACON_STATISTICS firmware notification.
      * The latter is sent by the firmware after each received beacon.
      */
    -void
    +static void
     iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
         struct iwn_rx_data *data)
     {
    @@ -2244,11 +2284,12 @@ iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
      * Process a TX_DONE firmware notification.  Unfortunately, the 4965AGN
      * and 5000 adapters have different incompatible TX status formats.
      */
    -void
    +static void
     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);
    +	struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
     
     	DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
     	    "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
    @@ -2256,15 +2297,16 @@ iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
     	    stat->btkillcnt, stat->rate, le16toh(stat->duration),
     	    le32toh(stat->status));
     
    -	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
    +	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
     	iwn_tx_done(sc, desc, stat->ackfailcnt, le32toh(stat->status) & 0xff);
     }
     
    -void
    +static 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);
    +	struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
     
     	DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
     	    "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
    @@ -2277,14 +2319,14 @@ iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
     	iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
     #endif
     
    -	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
    +	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
     	iwn_tx_done(sc, desc, stat->ackfailcnt, le16toh(stat->status) & 0xff);
     }
     
     /*
      * Adapter-independent backend for TX_DONE firmware notifications.
      */
    -void
    +static void
     iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
         uint8_t status)
     {
    @@ -2355,7 +2397,7 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
      * Process a "command done" firmware notification.  This is where we wakeup
      * processes waiting for a synchronous command completion.
      */
    -void
    +static void
     iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
     {
     	struct iwn_tx_ring *ring = &sc->txq[4];
    @@ -2378,7 +2420,7 @@ iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
     /*
      * Process an INT_FH_RX or INT_SW_RX interrupt.
      */
    -void
    +static void
     iwn_notif_intr(struct iwn_softc *sc)
     {
     	struct ifnet *ifp = sc->sc_ifp;
    @@ -2556,7 +2598,7 @@ iwn_notif_intr(struct iwn_softc *sc)
      * Process an INT_WAKEUP interrupt raised when the microcontroller wakes up
      * from power-down sleep mode.
      */
    -void
    +static void
     iwn_wakeup_intr(struct iwn_softc *sc)
     {
     	int qid;
    @@ -2572,7 +2614,7 @@ iwn_wakeup_intr(struct iwn_softc *sc)
     	}
     }
     
    -void
    +static void
     iwn_rftoggle_intr(struct iwn_softc *sc)
     {
     	struct ifnet *ifp = sc->sc_ifp;
    @@ -2594,7 +2636,7 @@ iwn_rftoggle_intr(struct iwn_softc *sc)
      * 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
    +static void
     iwn_fatal_intr(struct iwn_softc *sc)
     {
     	const struct iwn_hal *hal = sc->sc_hal;
    @@ -2654,7 +2696,7 @@ iwn_fatal_intr(struct iwn_softc *sc)
     	printf("  rx ring: cur=%d\n", sc->rxq.cur);
     }
     
    -void
    +static void
     iwn_intr(void *arg)
     {
     	struct iwn_softc *sc = arg;
    @@ -2675,8 +2717,10 @@ iwn_intr(void *arg)
     			sc->ict_cur = (sc->ict_cur + 1) % IWN_ICT_COUNT;
     		}
     		tmp = le32toh(tmp);
    -		if (tmp == 0xffffffff)
    -			tmp = 0;	/* Shouldn't happen. */
    +		if (tmp == 0xffffffff)	/* Shouldn't happen. */
    +			tmp = 0;
    +		else if (tmp & 0xc0000)	/* Workaround a HW bug. */
    +			tmp |= 0x8000;
     		r1 = (tmp & 0xff00) << 16 | (tmp & 0xff);
     		r2 = 0;	/* Unused. */
     	} else {
    @@ -2750,7 +2794,7 @@ done:
      * Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and
      * 5000 adapters use a slightly different format.)
      */
    -void
    +static void
     iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
         uint16_t len)
     {
    @@ -2766,7 +2810,7 @@ iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
     	}
     }
     
    -void
    +static void
     iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
         uint16_t len)
     {
    @@ -2783,7 +2827,8 @@ iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
     	}
     }
     
    -void
    +#ifdef notyet
    +static void
     iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
     {
     	uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
    @@ -2794,9 +2839,10 @@ iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
     	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);
    +		    BUS_DMASYNC_PREWRITE);
     	}
     }
    +#endif
     
     static uint8_t
     iwn_plcp_signal(int rate) {
    @@ -2810,7 +2856,7 @@ iwn_plcp_signal(int rate) {
     	return 0;
     }
     
    -int
    +static int
     iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
         struct iwn_tx_ring *ring)
     {
    @@ -3001,7 +3047,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
     		if (error != 0) {
     			device_printf(sc->sc_dev,
     			    "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
    -			     __func__, error);
    +			    __func__, error);
     			m_freem(m);
     			return error;
     		}
    @@ -3196,7 +3242,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
     		if (error != 0) {
     			device_printf(sc->sc_dev,
     			    "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
    -			     __func__, error);
    +			    __func__, error);
     			m_freem(m);
     			return error;
     		}
    @@ -3287,7 +3333,7 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
     	return error;
     }
     
    -void
    +static void
     iwn_start(struct ifnet *ifp)
     {
     	struct iwn_softc *sc = ifp->if_softc;
    @@ -3297,7 +3343,7 @@ iwn_start(struct ifnet *ifp)
     	IWN_UNLOCK(sc);
     }
     
    -void
    +static void
     iwn_start_locked(struct ifnet *ifp)
     {
     	struct iwn_softc *sc = ifp->if_softc;
    @@ -3340,7 +3386,7 @@ iwn_watchdog(struct iwn_softc *sc)
     	}
     }
     
    -int
    +static int
     iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     {
     	struct iwn_softc *sc = ifp->if_softc;
    @@ -3386,7 +3432,7 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     /*
      * Send a command to the firmware.
      */
    -int
    +static int
     iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
     {
     	struct iwn_tx_ring *ring = &sc->txq[4];
    @@ -3459,7 +3505,7 @@ iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
     	return async ? 0 : msleep(desc, &sc->sc_mtx, PCATCH, "iwncmd", hz);
     }
     
    -int
    +static int
     iwn4965_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
     {
     	struct iwn4965_node_info hnode;
    @@ -3478,7 +3524,7 @@ iwn4965_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
     	return iwn_cmd(sc, IWN_CMD_ADD_NODE, &hnode, sizeof hnode, async);
     }
     
    -int
    +static int
     iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
     {
     	/* Direct mapping. */
    @@ -3509,7 +3555,7 @@ static const uint8_t iwn_prev_ridx[] = {
      * Configure hardware link parameters for the specified
      * node operating on the specified channel.
      */
    -int
    +static int
     iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)
     {
     	struct ifnet *ifp = sc->sc_ifp;
    @@ -3582,7 +3628,7 @@ iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)
     /*
      * Broadcast node is used to send group-addressed and management frames.
      */
    -int
    +static int
     iwn_add_broadcast_node(struct iwn_softc *sc, int async)
     {
     	const struct iwn_hal *hal = sc->sc_hal;
    @@ -3602,7 +3648,7 @@ iwn_add_broadcast_node(struct iwn_softc *sc, int async)
     	return error;
     }
     
    -int
    +static int
     iwn_wme_update(struct ieee80211com *ic)
     {
     #define IWN_EXP2(x)	((1 << (x)) - 1)	/* CWmin = 2^ECWmin - 1 */
    @@ -3638,7 +3684,7 @@ iwn_update_mcast(struct ifnet *ifp)
     	/* Ignore */
     }
     
    -void
    +static void
     iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
     {
     	struct iwn_cmd_led led;
    @@ -3657,7 +3703,7 @@ iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
      * Set the critical temperature at which the firmware will stop the radio
      * and notify us.
      */
    -int
    +static int
     iwn_set_critical_temp(struct iwn_softc *sc)
     {
     	struct iwn_critical_temp crit;
    @@ -3678,7 +3724,7 @@ iwn_set_critical_temp(struct iwn_softc *sc)
     	return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
     }
     
    -int
    +static int
     iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
     {
     	struct iwn_cmd_timing cmd;
    @@ -3700,7 +3746,7 @@ iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
     	return iwn_cmd(sc, IWN_CMD_TIMING, &cmd, sizeof cmd, 1);
     }
     
    -void
    +static void
     iwn4965_power_calibration(struct iwn_softc *sc, int temp)
     {
     	struct ifnet *ifp = sc->sc_ifp;
    @@ -3721,7 +3767,7 @@ iwn4965_power_calibration(struct iwn_softc *sc, int temp)
      * This function takes into account the regulatory information from EEPROM,
      * the current temperature and the current voltage.
      */
    -int
    +static int
     iwn4965_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
         int async)
     {
    @@ -3873,7 +3919,7 @@ iwn4965_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
     #undef fdivround
     }
     
    -int
    +static int
     iwn5000_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
         int async)
     {
    @@ -3894,7 +3940,7 @@ iwn5000_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
     /*
      * Retrieve the maximum RSSI (in dBm) among receivers.
      */
    -int
    +static int
     iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
     {
     	struct iwn4965_rx_phystat *phy = (void *)stat->phybuf;
    @@ -3925,7 +3971,7 @@ iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
     	return rssi - agc - IWN_RSSI_TO_DBM;
     }
     
    -int
    +static int
     iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
     {
     	struct iwn5000_rx_phystat *phy = (void *)stat->phybuf;
    @@ -3948,7 +3994,7 @@ iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
     /*
      * Retrieve the average noise (in dBm) among receivers.
      */
    -int
    +static int
     iwn_get_noise(const struct iwn_rx_general_stats *stats)
     {
     	int i, total, nbant, noise;
    @@ -3967,7 +4013,7 @@ iwn_get_noise(const struct iwn_rx_general_stats *stats)
     /*
      * Compute temperature (in degC) from last received statistics.
      */
    -int
    +static int
     iwn4965_get_temperature(struct iwn_softc *sc)
     {
     	struct iwn_ucode_info *uc = &sc->ucode_info;
    @@ -3992,7 +4038,7 @@ iwn4965_get_temperature(struct iwn_softc *sc)
     	return IWN_KTOC(temp);
     }
     
    -int
    +static int
     iwn5000_get_temperature(struct iwn_softc *sc)
     {
     	int32_t temp;
    @@ -4013,7 +4059,7 @@ iwn5000_get_temperature(struct iwn_softc *sc)
     /*
      * Initialize sensitivity calibration state machine.
      */
    -int
    +static int
     iwn_init_sensitivity(struct iwn_softc *sc)
     {
     	const struct iwn_hal *hal = sc->sc_hal;
    @@ -4028,7 +4074,7 @@ iwn_init_sensitivity(struct iwn_softc *sc)
     	/* Set initial correlation values. */
     	calib->ofdm_x1     = sc->limits->min_ofdm_x1;
     	calib->ofdm_mrc_x1 = sc->limits->min_ofdm_mrc_x1;
    -	calib->ofdm_x4     = 90;
    +	calib->ofdm_x4     = sc->limits->min_ofdm_x4;
     	calib->ofdm_mrc_x4 = sc->limits->min_ofdm_mrc_x4;
     	calib->cck_x4      = 125;
     	calib->cck_mrc_x4  = sc->limits->min_cck_mrc_x4;
    @@ -4055,7 +4101,7 @@ iwn_init_sensitivity(struct iwn_softc *sc)
      * after association and use them to determine connected antennas and
      * to set differential gains.
      */
    -void
    +static void
     iwn_collect_noise(struct iwn_softc *sc,
         const struct iwn_rx_general_stats *stats)
     {
    @@ -4103,7 +4149,7 @@ iwn_collect_noise(struct iwn_softc *sc,
     #endif
     }
     
    -int
    +static int
     iwn4965_init_gains(struct iwn_softc *sc)
     {
     	struct iwn_phy_calib_gain cmd;
    @@ -4116,14 +4162,11 @@ iwn4965_init_gains(struct iwn_softc *sc)
     	return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
     }
     
    -int
    +static int
     iwn5000_init_gains(struct iwn_softc *sc)
     {
     	struct iwn_phy_calib cmd;
     
    -	if (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;
    @@ -4133,7 +4176,7 @@ iwn5000_init_gains(struct iwn_softc *sc)
     	return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
     }
     
    -int
    +static int
     iwn4965_set_gains(struct iwn_softc *sc)
     {
     	struct iwn_calib_state *calib = &sc->calib;
    @@ -4166,15 +4209,15 @@ iwn4965_set_gains(struct iwn_softc *sc)
     	return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
     }
     
    -int
    +static int
     iwn5000_set_gains(struct iwn_softc *sc)
     {
     	struct iwn_calib_state *calib = &sc->calib;
     	struct iwn_phy_calib_gain cmd;
    -	int i, ant, delta;
    +	int i, ant, delta, div;
     
    -	if (sc->hw_type == IWN_HW_REV_TYPE_6050)
    -		return 0;
    +	/* We collected 20 beacons and !=6050 need a 1.5 factor. */
    +	div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30;
     
     	memset(&cmd, 0, sizeof cmd);
     	cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
    @@ -4187,7 +4230,7 @@ iwn5000_set_gains(struct iwn_softc *sc)
     		if (sc->chainmask & (1 << i)) {
     			/* The delta is relative to antenna "ant". */
     			delta = ((int32_t)calib->noise[ant] -
    -			    (int32_t)calib->noise[i]) / 30;
    +			    (int32_t)calib->noise[i]) / div;
     			/* Limit to [-4.5dB,+4.5dB]. */
     			cmd.gain[i - 1] = MIN(abs(delta), 3);
     			if (delta < 0)
    @@ -4204,7 +4247,7 @@ iwn5000_set_gains(struct iwn_softc *sc)
      * Tune RF RX sensitivity based on the number of false alarms detected
      * during the last beacon period.
      */
    -void
    +static void
     iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
     {
     #define inc(val, inc, max)			\
    @@ -4331,7 +4374,7 @@ iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
     
     		if (calib->cck_state != IWN_CCK_STATE_INIT &&
     		    (((int32_t)calib->noise_ref - (int32_t)noise_ref) > 2 ||
    -		     calib->low_fa > 100)) {
    +		    calib->low_fa > 100)) {
     			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);
    @@ -4356,7 +4399,7 @@ iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
     #undef inc
     }
     
    -int
    +static int
     iwn_send_sensitivity(struct iwn_softc *sc)
     {
     	struct iwn_calib_state *calib = &sc->calib;
    @@ -4391,7 +4434,7 @@ iwn_send_sensitivity(struct iwn_softc *sc)
      * Set STA mode power saving level (between 0 and 5).
      * Level 0 is CAM (Continuously Aware Mode), 5 is for maximum power saving.
      */
    -int
    +static int
     iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)
     {
     	const struct iwn_pmgt *pmgt;
    @@ -4442,7 +4485,7 @@ iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)
     	return iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &cmd, sizeof cmd, async);
     }
     
    -int
    +static int
     iwn_config(struct iwn_softc *sc)
     {
     	const struct iwn_hal *hal = sc->sc_hal;
    @@ -4470,7 +4513,7 @@ iwn_config(struct iwn_softc *sc)
     
     	/* Configure bluetooth coexistence. */
     	memset(&bluetooth, 0, sizeof bluetooth);
    -	bluetooth.flags = IWN_BT_COEX_MODE_4WIRE;
    +	bluetooth.flags = IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO;
     	bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF;
     	bluetooth.max_kill = IWN_BT_MAX_KILL_DEF;
     	DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
    @@ -4555,7 +4598,7 @@ iwn_config(struct iwn_softc *sc)
     	return 0;
     }
     
    -int
    +static int
     iwn_scan(struct iwn_softc *sc)
     {
     	struct ifnet *ifp = sc->sc_ifp;
    @@ -4726,7 +4769,7 @@ iwn_scan(struct iwn_softc *sc)
     	return error;
     }
     
    -int
    +static int
     iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
     {
     	const struct iwn_hal *hal = sc->sc_hal;
    @@ -4800,7 +4843,7 @@ iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
     /*
      * Configure the adapter for associated state.
      */
    -int
    +static int
     iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
     {
     #define	MS(v,x)	(((v) & x) >> x##_S)
    @@ -4891,7 +4934,6 @@ iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
     		    __func__, error);
     		return error;
     	}
    -	
     
     	/* Configuration has changed, set TX power accordingly. */
     	error = hal->set_txpower(sc, ni->ni_chan, 1);
    @@ -4950,7 +4992,7 @@ iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
      * This function is called by upper layer when an ADDBA request is received
      * from another STA and before the ADDBA response is sent.
      */
    -int
    +static int
     iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
         uint8_t tid)
     {
    @@ -4974,7 +5016,7 @@ iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
      * This function is called by upper layer on teardown of an HT-immediate
      * Block Ack agreement (eg. uppon receipt of a DELBA frame.)
      */
    -void
    +static void
     iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
         uint8_t tid)
     {
    @@ -4995,7 +5037,7 @@ iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
      * This function is called by upper layer when an ADDBA response is received
      * from another STA.
      */
    -int
    +static int
     iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
         uint8_t tid)
     {
    @@ -5024,7 +5066,7 @@ iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
     	return 0;
     }
     
    -void
    +static void
     iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
         uint8_t tid)
     {
    @@ -5039,7 +5081,7 @@ iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
     	iwn_nic_unlock(sc);
     }
     
    -void
    +static void
     iwn4965_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
         uint8_t tid, uint16_t ssn)
     {
    @@ -5077,7 +5119,7 @@ iwn4965_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
     	    iwn_tid2fifo[tid] << 1);
     }
     
    -void
    +static void
     iwn4965_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
     {
     	int qid = 7 + tid;
    @@ -5098,7 +5140,7 @@ iwn4965_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
     	    IWN4965_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid] << 1);
     }
     
    -void
    +static void
     iwn5000_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
         uint8_t tid, uint16_t ssn)
     {
    @@ -5135,7 +5177,7 @@ iwn5000_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
     	    IWN5000_TXQ_STATUS_ACTIVE | iwn_tid2fifo[tid]);
     }
     
    -void
    +static void
     iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
     {
     	int qid = 10 + tid;
    @@ -5164,7 +5206,7 @@ iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
      * Query calibration tables from the initialization firmware.  We do this
      * only once at first boot.  Called from a process context.
      */
    -int
    +static int
     iwn5000_query_calibration(struct iwn_softc *sc)
     {
     	struct iwn5000_calib_config cmd;
    @@ -5191,7 +5233,7 @@ iwn5000_query_calibration(struct iwn_softc *sc)
      * Send calibration results to the runtime firmware.  These results were
      * obtained on first boot from the initialization firmware.
      */
    -int
    +static int
     iwn5000_send_calibration(struct iwn_softc *sc)
     {
     	int idx, error;
    @@ -5214,7 +5256,7 @@ iwn5000_send_calibration(struct iwn_softc *sc)
     	return 0;
     }
     
    -int
    +static int
     iwn5000_send_wimax_coex(struct iwn_softc *sc)
     {
     	struct iwn5000_wimax_coex wimax;
    @@ -5245,7 +5287,7 @@ iwn5000_send_wimax_coex(struct iwn_softc *sc)
      * This function is called after the runtime firmware notifies us of its
      * readiness (called in a process context.)
      */
    -int
    +static int
     iwn4965_post_alive(struct iwn_softc *sc)
     {
     	int error, qid;
    @@ -5298,7 +5340,7 @@ iwn4965_post_alive(struct iwn_softc *sc)
      * This function is called after the initialization or runtime firmware
      * notifies us of its readiness (called in a process context.)
      */
    -int
    +static int
     iwn5000_post_alive(struct iwn_softc *sc)
     {
     	int error, qid;
    @@ -5404,7 +5446,7 @@ iwn5000_post_alive(struct iwn_softc *sc)
      * The firmware boot code is small and is intended to be copied directly into
      * the NIC internal memory (no DMA transfer.)
      */
    -int
    +static int
     iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
     {
     	int error, ntries;
    @@ -5447,7 +5489,7 @@ iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
     	return 0;
     }
     
    -int
    +static int
     iwn4965_load_firmware(struct iwn_softc *sc)
     {
     	struct iwn_fw_info *fw = &sc->fw;
    @@ -5518,7 +5560,7 @@ iwn4965_load_firmware(struct iwn_softc *sc)
     	return 0;
     }
     
    -int
    +static int
     iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,
         const uint8_t *section, int size)
     {
    @@ -5556,7 +5598,7 @@ iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,
     	return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
     }
     
    -int
    +static int
     iwn5000_load_firmware(struct iwn_softc *sc)
     {
     	struct iwn_fw_part *fw;
    @@ -5588,7 +5630,7 @@ iwn5000_load_firmware(struct iwn_softc *sc)
     	return 0;
     }
     
    -int
    +static int
     iwn_read_firmware(struct iwn_softc *sc)
     {
     	const struct iwn_hal *hal = sc->sc_hal;
    @@ -5604,7 +5646,7 @@ iwn_read_firmware(struct iwn_softc *sc)
     	if (sc->fw_fp == NULL) {
     		device_printf(sc->sc_dev,
     		    "%s: could not load firmare image \"%s\"\n", __func__,
    -		     sc->fwname);
    +		    sc->fwname);
     		IWN_LOCK(sc);
     		return EINVAL;
     	}
    @@ -5670,7 +5712,7 @@ iwn_read_firmware(struct iwn_softc *sc)
     	return 0;
     }
     
    -int
    +static int
     iwn_clock_wait(struct iwn_softc *sc)
     {
     	int ntries;
    @@ -5689,7 +5731,7 @@ iwn_clock_wait(struct iwn_softc *sc)
     	return ETIMEDOUT;
     }
     
    -int
    +static int
     iwn_apm_init(struct iwn_softc *sc)
     {
     	uint32_t tmp;
    @@ -5747,7 +5789,7 @@ iwn_apm_init(struct iwn_softc *sc)
     	return 0;
     }
     
    -void
    +static void
     iwn_apm_stop_master(struct iwn_softc *sc)
     {
     	int ntries;
    @@ -5763,7 +5805,7 @@ iwn_apm_stop_master(struct iwn_softc *sc)
     	    __func__);
     }
     
    -void
    +static void
     iwn_apm_stop(struct iwn_softc *sc)
     {
     	iwn_apm_stop_master(sc);
    @@ -5775,7 +5817,7 @@ iwn_apm_stop(struct iwn_softc *sc)
     	IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
     }
     
    -int
    +static int
     iwn4965_nic_config(struct iwn_softc *sc)
     {
     	if (IWN_RFCFG_TYPE(sc->rfcfg) == 1) {
    @@ -5794,7 +5836,7 @@ iwn4965_nic_config(struct iwn_softc *sc)
     	return 0;
     }
     
    -int
    +static int
     iwn5000_nic_config(struct iwn_softc *sc)
     {
     	uint32_t tmp;
    @@ -5830,6 +5872,10 @@ iwn5000_nic_config(struct iwn_softc *sc)
     	if (sc->sc_flags & IWN_FLAG_INTERNAL_PA) {
     		/* Use internal power amplifier only. */
     		IWN_WRITE(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_2X2_IPA);
    +	}
    +	 if (sc->hw_type == IWN_HW_REV_TYPE_6050 && sc->calib_ver >= 6) {
    +		 /* Indicate that ROM calibration version is >=6. */
    +		 IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_CALIB_VER6);
     	}
     	return 0;
     }
    @@ -5837,7 +5883,7 @@ iwn5000_nic_config(struct iwn_softc *sc)
     /*
      * Take NIC ownership over Intel Active Management Technology (AMT).
      */
    -int
    +static int
     iwn_hw_prepare(struct iwn_softc *sc)
     {
     	int ntries;
    @@ -5873,7 +5919,7 @@ iwn_hw_prepare(struct iwn_softc *sc)
     	return ETIMEDOUT;
     }
     
    -int
    +static int
     iwn_hw_init(struct iwn_softc *sc)
     {
     	const struct iwn_hal *hal = sc->sc_hal;
    @@ -5984,7 +6030,7 @@ iwn_hw_init(struct iwn_softc *sc)
     	return hal->post_alive(sc);
     }
     
    -void
    +static void
     iwn_hw_stop(struct iwn_softc *sc)
     {
     	const struct iwn_hal *hal = sc->sc_hal;
    @@ -6038,7 +6084,7 @@ iwn_hw_stop(struct iwn_softc *sc)
     	iwn_apm_stop(sc);
     }
     
    -void
    +static void
     iwn_init_locked(struct iwn_softc *sc)
     {
     	struct ifnet *ifp = sc->sc_ifp;
    @@ -6106,7 +6152,7 @@ fail:
     	iwn_stop_locked(sc);
     }
     
    -void
    +static void
     iwn_init(void *arg)
     {
     	struct iwn_softc *sc = arg;
    @@ -6121,7 +6167,7 @@ iwn_init(void *arg)
     		ieee80211_start_all(ic);
     }
     
    -void
    +static void
     iwn_stop_locked(struct iwn_softc *sc)
     {
     	struct ifnet *ifp = sc->sc_ifp;
    @@ -6136,7 +6182,7 @@ iwn_stop_locked(struct iwn_softc *sc)
     	iwn_hw_stop(sc);
     }
     
    -void
    +static void
     iwn_stop(struct iwn_softc *sc)
     {
     	IWN_LOCK(sc);
    diff --git a/sys/dev/iwn/if_iwnreg.h b/sys/dev/iwn/if_iwnreg.h
    index 0aa76693823..06e03ec7449 100644
    --- a/sys/dev/iwn/if_iwnreg.h
    +++ b/sys/dev/iwn/if_iwnreg.h
    @@ -1,5 +1,5 @@
     /*	$FreeBSD$	*/
    -/*	$OpenBSD: if_iwnreg.h,v 1.34 2009/11/08 11:54:48 damien Exp $	*/
    +/*	$OpenBSD: if_iwnreg.h,v 1.37 2010/02/17 18:23:00 damien Exp $	*/
     
     /*-
      * Copyright (c) 2007, 2008
    @@ -216,6 +216,7 @@
     #define IWN_GP_DRIVER_RADIO_3X3_HYB	(0 << 0)
     #define IWN_GP_DRIVER_RADIO_2X2_HYB	(1 << 0)
     #define IWN_GP_DRIVER_RADIO_2X2_IPA	(2 << 0)
    +#define IWN_GP_DRIVER_CALIB_VER6	(1 << 2)
     
     /* Possible flags for register IWN_UCODE_GP1_CLR. */
     #define IWN_UCODE_GP1_RFKILL		(1 << 1)
    @@ -832,10 +833,9 @@ struct iwn5000_cmd_txpower {
     /* Structure for command IWN_CMD_BLUETOOTH. */
     struct iwn_bluetooth {
     	uint8_t		flags;
    -#define IWN_BT_COEX_DISABLE	0
    -#define IWN_BT_COEX_MODE_2WIRE	1
    -#define IWN_BT_COEX_MODE_3WIRE	2
    -#define IWN_BT_COEX_MODE_4WIRE	3
    +#define IWN_BT_COEX_CHAN_ANN	(1 << 0)
    +#define IWN_BT_COEX_BT_PRIO	(1 << 1)
    +#define IWN_BT_COEX_2_WIRE	(1 << 2)
     
     	uint8_t		lead_time;
     #define IWN_BT_LEAD_TIME_DEF	30
    @@ -1326,6 +1326,12 @@ struct iwn_eeprom_enhinfo {
     	int8_t		mimo3;		/* max power in half-dBm */
     } __packed;
     
    +struct iwn5000_eeprom_calib_hdr {
    +	uint8_t		version;
    +	uint8_t		pa_type;
    +	uint16_t	volt;
    +} __packed;
    +
     #define IWN_NSAMPLES	3
     struct iwn4965_eeprom_chan_samples {
     	uint8_t	num;
    @@ -1552,8 +1558,8 @@ static const struct iwn_sensitivity_limits iwn4965_sensitivity_limits = {
     };
     
     static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = {
    -	120, 155,
    -	240, 290,
    +	120, 120,	/* min = max for performance bug in DSP. */
    +	240, 240,	/* min = max for performance bug in DSP. */
     	 90, 120,
     	170, 210,
     	125, 200,
    @@ -1575,8 +1581,20 @@ static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = {
     	 95
     };
     
    +static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = {
    +	120, 155,
    +	240, 290,
    +	90, 120,
    +	170, 210,
    +	125, 200,
    +	170, 400,
    +	95,
    +	95,
    +	95
    +};
    +
     static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = {
    -	105, 145,
    +	105, 110,
     	192, 232,
     	 80, 145,
     	128, 232,
    @@ -1642,7 +1660,7 @@ static const char * const iwn_fw_errmsg[] = {
     	"DEBUG_1",
     	"DEBUG_2",
     	"DEBUG_3",
    -	"UNKNOWN"
    +	"ADVANCED_SYSASSERT"
     };
     
     /* Find least significant bit that is set. */
    diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
    index 98c9c948553..7b4ad981ef1 100644
    --- a/sys/dev/iwn/if_iwnvar.h
    +++ b/sys/dev/iwn/if_iwnvar.h
    @@ -1,5 +1,5 @@
     /*	$FreeBSD$	*/
    -/*	$OpenBSD: if_iwnvar.h,v 1.16 2009/11/04 17:46:52 damien Exp $	*/
    +/*	$OpenBSD: if_iwnvar.h,v 1.17 2010/02/17 18:23:00 damien Exp $	*/
     
     /*-
      * Copyright (c) 2007, 2008
    @@ -284,6 +284,7 @@ struct iwn_softc {
     				bands[IWN_NBANDS];
     	struct iwn_eeprom_chan	eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND];
     	uint16_t		rfcfg;
    +	uint8_t			calib_ver;
     	char			eeprom_domain[4];
     	uint32_t		eeprom_crystal;
     	int16_t			eeprom_voltage;
    diff --git a/sys/modules/iwnfw/iwn6000/Makefile b/sys/modules/iwnfw/iwn6000/Makefile
    index c0295a92cf1..2d2cc3fe1c4 100644
    --- a/sys/modules/iwnfw/iwn6000/Makefile
    +++ b/sys/modules/iwnfw/iwn6000/Makefile
    @@ -1,6 +1,6 @@
     # $FreeBSD$
     
     KMOD=	iwn6000fw
    -IMG=	iwlwifi-6000-9.176.4.1
    +IMG=	iwlwifi-6000-9.193.4.1
     
     .include 
    
    From 7bcd12bdc776bc35a2bf784823c8556685c78158 Mon Sep 17 00:00:00 2001
    From: Bernhard Schmidt 
    Date: Fri, 30 Apr 2010 18:39:07 +0000
    Subject: [PATCH 2147/2592] Remove 2 empty files, leftovers from previous MFCs.
    
    Approved by:	rpaulo (mentor)
    ---
     sys/contrib/dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu | 0
     sys/contrib/dev/iwn/iwlwifi-5000-5.4.A.11.fw.uu    | 0
     2 files changed, 0 insertions(+), 0 deletions(-)
     delete mode 100644 sys/contrib/dev/iwn/iwlwifi-4965-228.57.2.23.fw.uu
     delete mode 100644 sys/contrib/dev/iwn/iwlwifi-5000-5.4.A.11.fw.uu
    
    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
    deleted file mode 100644
    index e69de29bb2d..00000000000
    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
    deleted file mode 100644
    index e69de29bb2d..00000000000
    
    From 227b9ebe26a7cbf6635f367f6b291ceed97e66c6 Mon Sep 17 00:00:00 2001
    From: Rick Macklem 
    Date: Sat, 1 May 2010 00:50:51 +0000
    Subject: [PATCH 2148/2592] MFC: r207170 An NFSv4 server will reply
     NFSERR_GRACE for non-recovery RPCs during the grace period after startup.
     This grace period must be at least the lease duration, which is typically 1-2
     minutes. It seems prudent for the experimental NFS client to wait a few
     seconds before retrying such an RPC, so that the server isn't flooded with
     non-recovery RPCs during recovery. This patch adds an argument to
     nfs_catnap() to implement a 5 second delay for this case.
    
    ---
     sys/fs/nfs/nfs_commonkrpc.c      |  2 +-
     sys/fs/nfs/nfs_commonport.c      | 10 +++++++---
     sys/fs/nfs/nfs_var.h             |  2 +-
     sys/fs/nfs/nfsport.h             |  8 ++++----
     sys/fs/nfsclient/nfs_clrpcops.c  | 26 ++++++++++++++------------
     sys/fs/nfsclient/nfs_clstate.c   | 24 +++++++++++++-----------
     sys/fs/nfsclient/nfs_clvfsops.c  |  6 +++---
     sys/fs/nfsclient/nfs_clvnops.c   |  3 ++-
     sys/fs/nfsserver/nfs_nfsdstate.c |  2 +-
     9 files changed, 46 insertions(+), 37 deletions(-)
    
    diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
    index 8b6ada3865f..384bdb417de 100644
    --- a/sys/fs/nfs/nfs_commonkrpc.c
    +++ b/sys/fs/nfs/nfs_commonkrpc.c
    @@ -650,7 +650,7 @@ tryagain:
     					trylater_delay = NFS_TRYLATERDEL;
     				waituntil = NFSD_MONOSEC + trylater_delay;
     				while (NFSD_MONOSEC < waituntil)
    -					(void) nfs_catnap(PZERO, "nfstry");
    +					(void) nfs_catnap(PZERO, 0, "nfstry");
     				trylater_delay *= 2;
     				goto tryagain;
     			}
    diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
    index 7bc204e080c..d49dfc12163 100644
    --- a/sys/fs/nfs/nfs_commonport.c
    +++ b/sys/fs/nfs/nfs_commonport.c
    @@ -345,17 +345,21 @@ newnfs_timer(void *arg)
     
     
     /*
    - * sleep for a short period of time.
    + * Sleep for a short period of time unless errval == NFSERR_GRACE, where
    + * the sleep should be for 5 seconds.
      * Since lbolt doesn't exist in FreeBSD-CURRENT, just use a timeout on
      * an event that never gets a wakeup. Only return EINTR or 0.
      */
     int
    -nfs_catnap(int prio, const char *wmesg)
    +nfs_catnap(int prio, int errval, const char *wmesg)
     {
     	static int non_event;
     	int ret;
     
    -	ret = tsleep(&non_event, prio, wmesg, 1);
    +	if (errval == NFSERR_GRACE)
    +		ret = tsleep(&non_event, prio, wmesg, 5 * hz);
    +	else
    +		ret = tsleep(&non_event, prio, wmesg, 1);
     	if (ret != EINTR)
     		ret = 0;
     	return (ret);
    diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
    index f9832e1595f..fc7ee70cd7e 100644
    --- a/sys/fs/nfs/nfs_var.h
    +++ b/sys/fs/nfs/nfs_var.h
    @@ -322,7 +322,7 @@ int nfsvno_v4rootexport(struct nfsrv_descript *);
     void newnfs_portinit(void);
     struct ucred *newnfs_getcred(void);
     void newnfs_setroot(struct ucred *);
    -int nfs_catnap(int, const char *);
    +int nfs_catnap(int, int, const char *);
     struct nfsreferral *nfsv4root_getreferral(vnode_t, vnode_t, u_int32_t);
     int nfsrv_atroot(vnode_t, long *);
     void newnfs_timer(void *);
    diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
    index cad7d05a654..0ed82275b23 100644
    --- a/sys/fs/nfs/nfsport.h
    +++ b/sys/fs/nfs/nfsport.h
    @@ -147,21 +147,21 @@
     #define	NFSMGET(m)	do { 					\
     		MGET((m), M_TRYWAIT, MT_DATA); 			\
     		while ((m) == NULL ) { 				\
    -			(void) nfs_catnap(PZERO, "nfsmget");	\
    +			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
     			MGET((m), M_TRYWAIT, MT_DATA); 		\
     		} 						\
     	} while (0)
     #define	NFSMGETHDR(m)	do { 					\
     		MGETHDR((m), M_TRYWAIT, MT_DATA);		\
     		while ((m) == NULL ) { 				\
    -			(void) nfs_catnap(PZERO, "nfsmget");	\
    +			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
     			MGETHDR((m), M_TRYWAIT, MT_DATA); 	\
     		} 						\
     	} while (0)
     #define	NFSMCLGET(m, w)	do { 					\
     		MGET((m), M_TRYWAIT, MT_DATA); 			\
     		while ((m) == NULL ) { 				\
    -			(void) nfs_catnap(PZERO, "nfsmget");	\
    +			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
     			MGET((m), M_TRYWAIT, MT_DATA); 		\
     		} 						\
     		MCLGET((m), (w));				\
    @@ -169,7 +169,7 @@
     #define	NFSMCLGETHDR(m, w) do { 				\
     		MGETHDR((m), M_TRYWAIT, MT_DATA);		\
     		while ((m) == NULL ) { 				\
    -			(void) nfs_catnap(PZERO, "nfsmget");	\
    +			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
     			MGETHDR((m), M_TRYWAIT, MT_DATA); 	\
     		} 						\
     	} while (0)
    diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
    index edd47db510d..7efd58b6ebe 100644
    --- a/sys/fs/nfsclient/nfs_clrpcops.c
    +++ b/sys/fs/nfsclient/nfs_clrpcops.c
    @@ -300,7 +300,7 @@ else printf(" fhl=0\n");
     	    nfscl_openrelease(op, error, newone);
     	    if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
     		error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) {
    -		(void) nfs_catnap(PZERO, "nfs_open");
    +		(void) nfs_catnap(PZERO, error, "nfs_open");
     	    } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID)
     		&& clidrev != 0) {
     		expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
    @@ -462,7 +462,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen,
     			ret = nfsrpc_openconfirm(vp, newfhp, newfhlen, op,
     			    cred, p);
     			if (ret == NFSERR_DELAY)
    -			    (void) nfs_catnap(PZERO, "nfs_open");
    +			    (void) nfs_catnap(PZERO, ret, "nfs_open");
     		    } while (ret == NFSERR_DELAY);
     		    error = ret;
     		}
    @@ -486,7 +486,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen,
     			    newfhlen, mode, op, name, namelen, &ndp, 0, 0x0,
     			    cred, p, syscred, 1);
     			if (ret == NFSERR_DELAY)
    -			    (void) nfs_catnap(PZERO, "nfs_open2");
    +			    (void) nfs_catnap(PZERO, ret, "nfs_open2");
     		    } while (ret == NFSERR_DELAY);
     		    if (ret) {
     			if (ndp != NULL)
    @@ -626,6 +626,7 @@ nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p)
     					    nd->nd_repstat == NFSERR_DELAY) &&
     					    error == 0)
     						(void) nfs_catnap(PZERO,
    +						    (int)nd->nd_repstat,
     						    "nfs_close");
     				} while ((nd->nd_repstat == NFSERR_GRACE ||
     				    nd->nd_repstat == NFSERR_DELAY) &&
    @@ -647,7 +648,7 @@ nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p)
     	do {
     		error = nfscl_tryclose(op, tcred, nmp, p);
     		if (error == NFSERR_GRACE)
    -			(void) nfs_catnap(PZERO, "nfs_close");
    +			(void) nfs_catnap(PZERO, error, "nfs_close");
     	} while (error == NFSERR_GRACE);
     	NFSLOCKCLSTATE();
     	nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
    @@ -1006,7 +1007,7 @@ nfsrpc_setattr(vnode_t vp, struct vattr *vap, NFSACL_T *aclp,
     		if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
     		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
     		    error == NFSERR_OLDSTATEID) {
    -			(void) nfs_catnap(PZERO, "nfs_setattr");
    +			(void) nfs_catnap(PZERO, error, "nfs_setattr");
     		} else if ((error == NFSERR_EXPIRED ||
     		    error == NFSERR_BADSTATEID) && clidrev != 0) {
     			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
    @@ -1251,7 +1252,7 @@ nfsrpc_read(vnode_t vp, struct uio *uiop, struct ucred *cred,
     		if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
     		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
     		    error == NFSERR_OLDSTATEID) {
    -			(void) nfs_catnap(PZERO, "nfs_read");
    +			(void) nfs_catnap(PZERO, error, "nfs_read");
     		} else if ((error == NFSERR_EXPIRED ||
     		    error == NFSERR_BADSTATEID) && clidrev != 0) {
     			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
    @@ -1416,7 +1417,7 @@ nfscl_dumpstate(nmp, 1, 1, 0, 0);
     		if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
     		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
     		    error == NFSERR_OLDSTATEID) {
    -			(void) nfs_catnap(PZERO, "nfs_write");
    +			(void) nfs_catnap(PZERO, error, "nfs_write");
     		} else if ((error == NFSERR_EXPIRED ||
     		    error == NFSERR_BADSTATEID) && clidrev != 0) {
     			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
    @@ -1743,7 +1744,7 @@ nfsrpc_create(vnode_t dvp, char *name, int namelen, struct vattr *vap,
     		nfscl_ownerrelease(owp, error, newone, unlocked);
     		if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
     		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) {
    -			(void) nfs_catnap(PZERO, "nfs_open");
    +			(void) nfs_catnap(PZERO, error, "nfs_open");
     		} else if ((error == NFSERR_EXPIRED ||
     		    error == NFSERR_BADSTATEID) && clidrev != 0) {
     			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
    @@ -1976,7 +1977,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
     			ret = nfsrpc_openconfirm(dvp, nfhp->nfh_fh,
     			    nfhp->nfh_len, op, cred, p);
     			if (ret == NFSERR_DELAY)
    -			    (void) nfs_catnap(PZERO, "nfs_create");
    +			    (void) nfs_catnap(PZERO, ret, "nfs_create");
     		    } while (ret == NFSERR_DELAY);
     		    error = ret;
     		}
    @@ -1998,7 +1999,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
     			    (NFSV4OPEN_ACCESSWRITE | NFSV4OPEN_ACCESSREAD), op,
     			    name, namelen, &dp, 0, 0x0, cred, p, 0, 1);
     			if (ret == NFSERR_DELAY)
    -			    (void) nfs_catnap(PZERO, "nfs_crt2");
    +			    (void) nfs_catnap(PZERO, ret, "nfs_crt2");
     		    } while (ret == NFSERR_DELAY);
     		    if (ret) {
     			if (dp != NULL)
    @@ -3540,7 +3541,8 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
     			    if ((nd->nd_repstat == NFSERR_GRACE ||
     				 nd->nd_repstat == NFSERR_DELAY) &&
     				error == 0)
    -				(void) nfs_catnap(PZERO, "nfs_advlock");
    +				(void) nfs_catnap(PZERO, (int)nd->nd_repstat,
    +				    "nfs_advlock");
     			} while ((nd->nd_repstat == NFSERR_GRACE ||
     			    nd->nd_repstat == NFSERR_DELAY) && error == 0);
     		    }
    @@ -3577,7 +3579,7 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
     	    if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
     		error == NFSERR_STALEDONTRECOVER ||
     		error == NFSERR_STALECLIENTID || error == NFSERR_DELAY) {
    -		(void) nfs_catnap(PZERO, "nfs_advlock");
    +		(void) nfs_catnap(PZERO, error, "nfs_advlock");
     	    } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID)
     		&& clidrev != 0) {
     		expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
    diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
    index cf8c922ae43..b6fad20d0f5 100644
    --- a/sys/fs/nfsclient/nfs_clstate.c
    +++ b/sys/fs/nfsclient/nfs_clstate.c
    @@ -784,7 +784,7 @@ nfscl_getcl(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
     			if (error == NFSERR_STALECLIENTID ||
     			    error == NFSERR_STALEDONTRECOVER ||
     			    error == NFSERR_CLIDINUSE) {
    -				(void) nfs_catnap(PZERO, "nfs_setcl");
    +				(void) nfs_catnap(PZERO, error, "nfs_setcl");
     			}
     		} while (((error == NFSERR_STALECLIENTID ||
     		     error == NFSERR_STALEDONTRECOVER) && --trystalecnt > 0) ||
    @@ -2046,7 +2046,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
     			newnfs_copycred(&op->nfso_cred, tcred);
     			error = nfscl_tryclose(op, tcred, nmp, p);
     			if (error == NFSERR_GRACE)
    -				(void) nfs_catnap(PZERO, "nfsexcls");
    +				(void) nfs_catnap(PZERO, error, "nfsexcls");
     		} while (error == NFSERR_GRACE);
     		LIST_REMOVE(op, nfso_list);
     		FREE((caddr_t)op, M_NFSCLOPEN);
    @@ -2059,7 +2059,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
     			newnfs_copycred(&dp->nfsdl_cred, tcred);
     			error = nfscl_trydelegreturn(dp, tcred, nmp, p);
     			if (error == NFSERR_GRACE)
    -				(void) nfs_catnap(PZERO, "nfsexdlg");
    +				(void) nfs_catnap(PZERO, error, "nfsexdlg");
     		} while (error == NFSERR_GRACE);
     		TAILQ_REMOVE(&extra_deleg, dp, nfsdl_list);
     		FREE((caddr_t)dp, M_NFSCLDELEG);
    @@ -3619,7 +3619,7 @@ nfscl_tryopen(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
     		    mode, op, name, namelen, ndpp, reclaim, delegtype, cred, p,
     		    0, 0);
     		if (error == NFSERR_DELAY)
    -			(void) nfs_catnap(PZERO, "nfstryop");
    +			(void) nfs_catnap(PZERO, error, "nfstryop");
     	} while (error == NFSERR_DELAY);
     	if (error == EAUTH || error == EACCES) {
     		/* Try again using system credentials */
    @@ -3629,7 +3629,7 @@ nfscl_tryopen(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
     			newfhlen, mode, op, name, namelen, ndpp, reclaim,
     			delegtype, cred, p, 1, 0);
     		    if (error == NFSERR_DELAY)
    -			(void) nfs_catnap(PZERO, "nfstryop");
    +			(void) nfs_catnap(PZERO, error, "nfstryop");
     		} while (error == NFSERR_DELAY);
     	}
     	return (error);
    @@ -3652,7 +3652,8 @@ nfscl_trylock(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp,
     		error = nfsrpc_lock(nd, nmp, vp, fhp, fhlen, nlp, newone,
     		    reclaim, off, len, type, cred, p, 0);
     		if (!error && nd->nd_repstat == NFSERR_DELAY)
    -			(void) nfs_catnap(PZERO, "nfstrylck");
    +			(void) nfs_catnap(PZERO, (int)nd->nd_repstat,
    +			    "nfstrylck");
     	} while (!error && nd->nd_repstat == NFSERR_DELAY);
     	if (!error)
     		error = nd->nd_repstat;
    @@ -3663,7 +3664,8 @@ nfscl_trylock(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp,
     			error = nfsrpc_lock(nd, nmp, vp, fhp, fhlen, nlp,
     			    newone, reclaim, off, len, type, cred, p, 1);
     			if (!error && nd->nd_repstat == NFSERR_DELAY)
    -				(void) nfs_catnap(PZERO, "nfstrylck");
    +				(void) nfs_catnap(PZERO, (int)nd->nd_repstat,
    +				    "nfstrylck");
     		} while (!error && nd->nd_repstat == NFSERR_DELAY);
     		if (!error)
     			error = nd->nd_repstat;
    @@ -3685,7 +3687,7 @@ nfscl_trydelegreturn(struct nfscldeleg *dp, struct ucred *cred,
     	do {
     		error = nfsrpc_delegreturn(dp, cred, nmp, p, 0);
     		if (error == NFSERR_DELAY)
    -			(void) nfs_catnap(PZERO, "nfstrydp");
    +			(void) nfs_catnap(PZERO, error, "nfstrydp");
     	} while (error == NFSERR_DELAY);
     	if (error == EAUTH || error == EACCES) {
     		/* Try again using system credentials */
    @@ -3693,7 +3695,7 @@ nfscl_trydelegreturn(struct nfscldeleg *dp, struct ucred *cred,
     		do {
     			error = nfsrpc_delegreturn(dp, cred, nmp, p, 1);
     			if (error == NFSERR_DELAY)
    -				(void) nfs_catnap(PZERO, "nfstrydp");
    +				(void) nfs_catnap(PZERO, error, "nfstrydp");
     		} while (error == NFSERR_DELAY);
     	}
     	return (error);
    @@ -3714,7 +3716,7 @@ nfscl_tryclose(struct nfsclopen *op, struct ucred *cred,
     	do {
     		error = nfsrpc_closerpc(nd, nmp, op, cred, p, 0);
     		if (error == NFSERR_DELAY)
    -			(void) nfs_catnap(PZERO, "nfstrycl");
    +			(void) nfs_catnap(PZERO, error, "nfstrycl");
     	} while (error == NFSERR_DELAY);
     	if (error == EAUTH || error == EACCES) {
     		/* Try again using system credentials */
    @@ -3722,7 +3724,7 @@ nfscl_tryclose(struct nfsclopen *op, struct ucred *cred,
     		do {
     			error = nfsrpc_closerpc(nd, nmp, op, cred, p, 1);
     			if (error == NFSERR_DELAY)
    -				(void) nfs_catnap(PZERO, "nfstrycl");
    +				(void) nfs_catnap(PZERO, error, "nfstrycl");
     		} while (error == NFSERR_DELAY);
     	}
     	return (error);
    diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
    index 0bf2bf4b4e5..76154c37180 100644
    --- a/sys/fs/nfsclient/nfs_clvfsops.c
    +++ b/sys/fs/nfsclient/nfs_clvfsops.c
    @@ -652,7 +652,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
     			while (newnfs_connect(nmp, &nmp->nm_sockreq,
     			    cred, td, 0)) {
     				printf("newnfs_args: retrying connect\n");
    -				(void) nfs_catnap(PSOCK, "newnfscon");
    +				(void) nfs_catnap(PSOCK, 0, "newnfscon");
     			}
     		}
     	} else {
    @@ -1188,7 +1188,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
     			error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
     			    cred, td);
     			if (error)
    -				(void) nfs_catnap(PZERO, "nfsgetdirp");
    +				(void) nfs_catnap(PZERO, error, "nfsgetdirp");
     		} while (error && --trycnt > 0);
     		if (error) {
     			error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
    @@ -1284,7 +1284,7 @@ nfs_unmount(struct mount *mp, int mntflags)
     	do {
     		error = vflush(mp, 1, flags, td);
     		if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
    -			(void) nfs_catnap(PSOCK, "newndm");
    +			(void) nfs_catnap(PSOCK, error, "newndm");
     	} while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
     	if (error)
     		goto out;
    diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
    index 98108e3fb8f..4595ff39b0f 100644
    --- a/sys/fs/nfsclient/nfs_clvnops.c
    +++ b/sys/fs/nfsclient/nfs_clvnops.c
    @@ -2871,7 +2871,8 @@ nfs_advlock(struct vop_advlock_args *ap)
     			if (ret == NFSERR_DENIED && (ap->a_flags & F_WAIT) &&
     			    ap->a_op == F_SETLK) {
     				VOP_UNLOCK(vp, 0);
    -				error = nfs_catnap(PZERO | PCATCH, "ncladvl");
    +				error = nfs_catnap(PZERO | PCATCH, ret,
    +				    "ncladvl");
     				if (error)
     					return (EINTR);
     				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
    diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
    index a4df1ed9c33..e475cb77826 100644
    --- a/sys/fs/nfsserver/nfs_nfsdstate.c
    +++ b/sys/fs/nfsserver/nfs_nfsdstate.c
    @@ -4578,7 +4578,7 @@ nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p)
     			    100000)
     				return;
     			/* Sleep for a short period of time */
    -			(void) nfs_catnap(PZERO, "nfsremove");
    +			(void) nfs_catnap(PZERO, 0, "nfsremove");
     		}
     	} while (error == NFSERR_DELAY);
     }
    
    From 1577aa79c0bd600177bccb92fd3a1b4a3c6f26c2 Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sat, 1 May 2010 14:29:33 +0000
    Subject: [PATCH 2149/2592] MFC r206773: ln: Do not delete a file by
     hardlinking it to itself.
    
    Two pathnames refer to the same directory entry iff the directories match
    and the final components' names match.
    
    Example: (assuming file1 is an existing file)
      ln -f file1 file1
    This now fails while leaving file1 intact. It used to delete file1 and then
    complain it cannot be linked because it is gone.
    
    With -i, this error is detected before the question is asked.
    ---
     bin/ln/ln.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++--
     1 file changed, 59 insertions(+), 2 deletions(-)
    
    diff --git a/bin/ln/ln.c b/bin/ln/ln.c
    index e946646775e..d77939291f7 100644
    --- a/bin/ln/ln.c
    +++ b/bin/ln/ln.c
    @@ -172,6 +172,52 @@ main(int argc, char *argv[])
     	exit(exitval);
     }
     
    +/*
    + * Two pathnames refer to the same directory entry if the directories match
    + * and the final components' names match.
    + */
    +static int
    +samedirent(const char *path1, const char *path2)
    +{
    +	const char *file1, *file2;
    +	char pathbuf[PATH_MAX];
    +	struct stat sb1, sb2;
    +
    +	if (strcmp(path1, path2) == 0)
    +		return 1;
    +	file1 = strrchr(path1, '/');
    +	if (file1 != NULL)
    +		file1++;
    +	else
    +		file1 = path1;
    +	file2 = strrchr(path2, '/');
    +	if (file2 != NULL)
    +		file2++;
    +	else
    +		file2 = path2;
    +	if (strcmp(file1, file2) != 0)
    +		return 0;
    +	if (file1 - path1 >= PATH_MAX || file2 - path2 >= PATH_MAX)
    +		return 0;
    +	if (file1 == path1)
    +		memcpy(pathbuf, ".", 2);
    +	else {
    +		memcpy(pathbuf, path1, file1 - path1);
    +		pathbuf[file1 - path1] = '\0';
    +	}
    +	if (stat(pathbuf, &sb1) != 0)
    +		return 0;
    +	if (file2 == path2)
    +		memcpy(pathbuf, ".", 2);
    +	else {
    +		memcpy(pathbuf, path2, file2 - path2);
    +		pathbuf[file2 - path2] = '\0';
    +	}
    +	if (stat(pathbuf, &sb2) != 0)
    +		return 0;
    +	return sb1.st_dev == sb2.st_dev && sb1.st_ino == sb2.st_ino;
    +}
    +
     int
     linkit(const char *source, const char *target, int isdir)
     {
    @@ -215,7 +261,6 @@ linkit(const char *source, const char *target, int isdir)
     		target = path;
     	}
     
    -	exists = !lstat(target, &sb);
     	/*
     	 * If the link source doesn't exist, and a symbolic link was
     	 * requested, and -w was specified, give a warning.
    @@ -242,8 +287,20 @@ linkit(const char *source, const char *target, int isdir)
     				warn("warning: %s", source);
     		}
     	}
    +
     	/*
    -	 * If the file exists, then unlink it forcibly if -f was specified
    +	 * If the file exists, first check it is not the same directory entry.
    +	 */
    +	exists = !lstat(target, &sb);
    +	if (exists) {
    +		if (!sflag && samedirent(source, target)) {
    +			warnx("%s and %s are the same directory entry",
    +			    source, target);
    +			return (1);
    +		}
    +	}
    +	/*
    +	 * Then unlink it forcibly if -f was specified
     	 * and interactively if -i was specified.
     	 */
     	if (fflag && exists) {
    
    From 312a3c0cba419a0c12388216036159d454273fe3 Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sat, 1 May 2010 14:33:26 +0000
    Subject: [PATCH 2150/2592] MFC r207021: ln: Allow a trailing slash when
     creating a link to a directory.
    
    In the 'ln source... directory' synopsis, the basename of each source
    determines the name of the created link. Determine this using basename(3)
    instead of strrchr(..., '/') which is incorrect if the pathname ends in a
    slash.
    
    PR:		121568
    ---
     bin/ln/ln.c | 27 +++++++++++++--------------
     1 file changed, 13 insertions(+), 14 deletions(-)
    
    diff --git a/bin/ln/ln.c b/bin/ln/ln.c
    index d77939291f7..fc3afc13308 100644
    --- a/bin/ln/ln.c
    +++ b/bin/ln/ln.c
    @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -226,6 +227,7 @@ linkit(const char *source, const char *target, int isdir)
     	int ch, exists, first;
     	char path[PATH_MAX];
     	char wbuf[PATH_MAX];
    +	char bbuf[PATH_MAX];
     
     	if (!sflag) {
     		/* If source doesn't exist, quit now. */
    @@ -248,11 +250,9 @@ linkit(const char *source, const char *target, int isdir)
     	if (isdir ||
     	    (lstat(target, &sb) == 0 && S_ISDIR(sb.st_mode)) ||
     	    (!hflag && stat(target, &sb) == 0 && S_ISDIR(sb.st_mode))) {
    -		if ((p = strrchr(source, '/')) == NULL)
    -			p = source;
    -		else
    -			++p;
    -		if (snprintf(path, sizeof(path), "%s/%s", target, p) >=
    +		if (strlcpy(bbuf, source, sizeof(bbuf)) >= sizeof(bbuf) ||
    +		    (p = basename(bbuf)) == NULL ||
    +		    snprintf(path, sizeof(path), "%s/%s", target, p) >=
     		    (ssize_t)sizeof(path)) {
     			errno = ENAMETOOLONG;
     			warn("%s", source);
    @@ -276,15 +276,14 @@ linkit(const char *source, const char *target, int isdir)
     			 * absolute path of the source, by appending `source'
     			 * to the parent directory of the target.
     			 */
    -			p = strrchr(target, '/');
    -			if (p != NULL)
    -				p++;
    -			else
    -				p = target;
    -			(void)snprintf(wbuf, sizeof(wbuf), "%.*s%s",
    -			    (int)(p - target), target, source);
    -			if (stat(wbuf, &sb) != 0)
    -				warn("warning: %s", source);
    +			strlcpy(bbuf, target, sizeof(bbuf));
    +			p = dirname(bbuf);
    +			if (p != NULL) {
    +				(void)snprintf(wbuf, sizeof(wbuf), "%s/%s",
    +						p, source);
    +				if (stat(wbuf, &sb) != 0)
    +					warn("warning: %s", source);
    +			}
     		}
     	}
     
    
    From 5d05d542eb3d73e52da5e94262d4a3c91bf6b1dd Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sat, 1 May 2010 14:36:04 +0000
    Subject: [PATCH 2151/2592] MFC r207153: stat: Allow -f %Sf to display the file
     flags symbolically.
    
    PR:		124349
    ---
     usr.bin/stat/stat.1 |  7 ++++++-
     usr.bin/stat/stat.c | 29 +++++++++++++++++++++++++++--
     2 files changed, 33 insertions(+), 3 deletions(-)
    
    diff --git a/usr.bin/stat/stat.1 b/usr.bin/stat/stat.1
    index b629341b8cc..868f9e9eabc 100644
    --- a/usr.bin/stat/stat.1
    +++ b/usr.bin/stat/stat.1
    @@ -36,7 +36,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd April 27, 2007
    +.Dd April 24, 2010
     .Dt STAT 1
     .Os
     .Sh NAME
    @@ -239,6 +239,11 @@ Display date in
     format.
     .It Cm dr
     Display actual device name.
    +.It Cm f
    +Display the flags of
    +.Ar file
    +as in
    +.Nm ls Fl lTdo .
     .It Cm gu
     Display group or user name.
     .It Cm p
    diff --git a/usr.bin/stat/stat.c b/usr.bin/stat/stat.c
    index 0b32f11c60d..5d75d7c0c40 100644
    --- a/usr.bin/stat/stat.c
    +++ b/usr.bin/stat/stat.c
    @@ -189,6 +189,9 @@ int	format1(const struct stat *,	/* stat info */
     	    char *, size_t,		/* a place to put the output */
     	    int, int, int, int,		/* the parsed format */
     	    int, int);
    +#if HAVE_STRUCT_STAT_ST_FLAGS
    +char   *xfflagstostr(unsigned long);
    +#endif
     
     char *timefmt;
     int linkfail;
    @@ -340,6 +343,25 @@ main(int argc, char *argv[])
     	return (am_readlink ? linkfail : errs);
     }
     
    +#if HAVE_STRUCT_STAT_ST_FLAGS
    +/*
    + * fflagstostr() wrapper that leaks only once
    + */
    +char *
    +xfflagstostr(unsigned long fflags)
    +{
    +	static char *str = NULL;
    +
    +	if (str != NULL)
    +		free(str);
    +
    +	str = fflagstostr(fflags);
    +	if (str == NULL)
    +		err(1, "fflagstostr");
    +	return (str);
    +}
    +#endif /* HAVE_STRUCT_STAT_ST_FLAGS */
    +
     void
     usage(const char *synopsis)
     {
    @@ -732,8 +754,11 @@ format1(const struct stat *st,
     	case SHOW_st_flags:
     		small = (sizeof(st->st_flags) == 4);
     		data = st->st_flags;
    -		sdata = NULL;
    -		formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX;
    +		sdata = xfflagstostr(st->st_flags);
    +		if (*sdata == '\0')
    +			sdata = "-";
    +		formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX |
    +		    FMTF_STRING;
     		if (ofmt == 0)
     			ofmt = FMTF_UNSIGNED;
     		break;
    
    From 767c29b7f21043829583149900618757fbc961cb Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sat, 1 May 2010 14:41:37 +0000
    Subject: [PATCH 2152/2592] MFC r207166: builtin(1): Mention [ sh builtin.
    
    ---
     share/man/man1/builtin.1 | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/share/man/man1/builtin.1 b/share/man/man1/builtin.1
    index 0a93c21ecd7..79b2ceca60b 100644
    --- a/share/man/man1/builtin.1
    +++ b/share/man/man1/builtin.1
    @@ -26,7 +26,7 @@
     .\"
     .\" $FreeBSD$
     .\"
    -.Dd October 14, 2006
    +.Dd April 25, 2010
     .Dt BUILTIN 1
     .Os
     .Sh NAME
    @@ -36,6 +36,7 @@
     .Nm \&. ,
     .Nm \&: ,
     .Nm @ ,
    +.Nm \&[ ,
     .Nm { ,
     .Nm } ,
     .Nm alias ,
    @@ -200,6 +201,7 @@ but are implemented as scripts using a builtin command of the same name.
     .It Ic . Ta \&No Ta \&No Ta Yes
     .It Ic : Ta \&No Ta Yes Ta Yes
     .It Ic @ Ta \&No Ta Yes Ta Yes
    +.It Ic \&[ Ta Yes Ta \&No Ta Yes
     .It Ic { Ta \&No Ta \&No Ta Yes
     .It Ic } Ta \&No Ta \&No Ta Yes
     .It Ic alias Ta No** Ta Yes Ta Yes
    
    From 1cadff774509dfc027674fa3465e2618fe40d7a9 Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sat, 1 May 2010 14:49:20 +0000
    Subject: [PATCH 2153/2592] MFC r207168: builtin(1): Add missing escaping for
     !, . and : in the table.
    
    This caused these commands to look differently (not bold) from the other
    commands in the table (bold).
    ---
     share/man/man1/builtin.1 | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/share/man/man1/builtin.1 b/share/man/man1/builtin.1
    index 79b2ceca60b..12ab0a83841 100644
    --- a/share/man/man1/builtin.1
    +++ b/share/man/man1/builtin.1
    @@ -196,10 +196,10 @@ but are implemented as scripts using a builtin command of the same name.
     .It Xo
     .Em "Command	External" Ta Xr csh 1 Ta Xr sh 1
     .Xc
    -.It Ic ! Ta \&No Ta \&No Ta Yes
    +.It Ic \&! Ta \&No Ta \&No Ta Yes
     .It Ic % Ta \&No Ta Yes Ta \&No
    -.It Ic . Ta \&No Ta \&No Ta Yes
    -.It Ic : Ta \&No Ta Yes Ta Yes
    +.It Ic \&. Ta \&No Ta \&No Ta Yes
    +.It Ic \&: Ta \&No Ta Yes Ta Yes
     .It Ic @ Ta \&No Ta Yes Ta Yes
     .It Ic \&[ Ta Yes Ta \&No Ta Yes
     .It Ic { Ta \&No Ta \&No Ta Yes
    
    From fde8d4bfa730ca5eb8eba72fa774a1a8553c392e Mon Sep 17 00:00:00 2001
    From: Pawel Jakub Dawidek 
    Date: Sat, 1 May 2010 19:00:33 +0000
    Subject: [PATCH 2154/2592] MFC r207068,r207334:
    
    r207068:
    
    Allow to modify directory's content even if the ZFS_NOUNLINK (SF_NOUNLINK,
    sunlnk) flag is set. We only deny dirctory's removal or rename.
    
    PR:		kern/143343
    Reported by:	marck
    
    r207334:
    
    Backport fix for 'zfs_znode_dmu_init: existing znode for dbuf' panic from OpenSolaris.
    
    PR:		kern/144402
    Reported by:	Alex Bakhtin 
    Tested by:	Alex Bakhtin 
    Obtained from:	OpenSolaris, Bug ID 6895088
    ---
     .../opensolaris/uts/common/fs/zfs/zfs_acl.c   | 13 ++++++
     .../opensolaris/uts/common/fs/zfs/zfs_znode.c | 43 +++++++++++++------
     2 files changed, 44 insertions(+), 12 deletions(-)
    
    diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
    index eb93721e167..9825d83fb67 100644
    --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
    +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
    @@ -2235,11 +2235,24 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
     		return (EPERM);
     	}
     
    +#ifdef sun
     	if ((v4_mode & (ACE_DELETE | ACE_DELETE_CHILD)) &&
     	    (zp->z_phys->zp_flags & ZFS_NOUNLINK)) {
     		*check_privs = B_FALSE;
     		return (EPERM);
     	}
    +#else
    +	/*
    +	 * In FreeBSD we allow to modify directory's content is ZFS_NOUNLINK
    +	 * (sunlnk) is set. We just don't allow directory removal, which is
    +	 * handled in zfs_zaccess_delete().
    +	 */
    +	if ((v4_mode & ACE_DELETE) &&
    +	    (zp->z_phys->zp_flags & ZFS_NOUNLINK)) {
    +		*check_privs = B_FALSE;
    +		return (EPERM);
    +	}
    +#endif
     
     	if (((v4_mode & (ACE_READ_DATA|ACE_EXECUTE)) &&
     	    (zp->z_phys->zp_flags & ZFS_AV_QUARANTINED))) {
    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 900087b8b32..947f9dd39f4 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
    @@ -704,6 +704,8 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
     			    DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx);
     		}
     	}
    +
    +	ZFS_OBJ_HOLD_ENTER(zfsvfs, obj);
     	VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, obj, NULL, &db));
     	dmu_buf_will_dirty(db, tx);
     
    @@ -765,9 +767,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
     
     	pzp->zp_mode = MAKEIMODE(vap->va_type, vap->va_mode);
     	if (!(flag & IS_ROOT_NODE)) {
    -		ZFS_OBJ_HOLD_ENTER(zfsvfs, obj);
     		*zpp = zfs_znode_alloc(zfsvfs, db, 0);
    -		ZFS_OBJ_HOLD_EXIT(zfsvfs, obj);
     	} else {
     		/*
     		 * If we are creating the root node, the "parent" we
    @@ -776,6 +776,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
     		*zpp = dzp;
     	}
     	zfs_perm_init(*zpp, dzp, flag, vap, tx, cr, setaclp, fuidp);
    +	ZFS_OBJ_HOLD_EXIT(zfsvfs, obj);
     	if (!(flag & IS_ROOT_NODE)) {
     		vnode_t *vp;
     
    @@ -939,19 +940,31 @@ again:
     
     	/*
     	 * Not found create new znode/vnode
    +	 * but only if file exists.
    +	 *
    +	 * There is a small window where zfs_vget() could
    +	 * find this object while a file create is still in
    +	 * progress.  Since a gen number can never be zero
    +	 * we will check that to determine if its an allocated
    +	 * file.
     	 */
    -	zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size);
    -
    -	vp = ZTOV(zp);
    -	vp->v_vflag |= VV_FORCEINSMQ;
    -	err = insmntque(vp, zfsvfs->z_vfs);
    -	vp->v_vflag &= ~VV_FORCEINSMQ;
    -	KASSERT(err == 0, ("insmntque() failed: error %d", err));
    -	VOP_UNLOCK(vp, 0);
     
    +	if (((znode_phys_t *)db->db_data)->zp_gen != 0) {
    +		zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size);
    +		*zpp = zp;
    +		vp = ZTOV(zp);
    +		vp->v_vflag |= VV_FORCEINSMQ;
    +		err = insmntque(vp, zfsvfs->z_vfs);
    +		vp->v_vflag &= ~VV_FORCEINSMQ;
    +		KASSERT(err == 0, ("insmntque() failed: error %d", err));
    +		VOP_UNLOCK(vp, 0);
    +		err = 0;
    +	} else {
    +		dmu_buf_rele(db, NULL);
    +		err = ENOENT;
    +	}
     	ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
    -	*zpp = zp;
    -	return (0);
    +	return (err);
     }
     
     int
    @@ -1440,6 +1453,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
     	uint64_t	norm = 0;
     	nvpair_t	*elem;
     	int		error;
    +	int		i;
     	znode_t		*rootzp = NULL;
     	vnode_t		vnode;
     	vattr_t		vattr;
    @@ -1537,6 +1551,9 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
     	list_create(&zfsvfs.z_all_znodes, sizeof (znode_t),
     	    offsetof(znode_t, z_link_node));
     
    +	for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
    +		mutex_init(&zfsvfs.z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
    +
     	ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs));
     	rootzp->z_zfsvfs = &zfsvfs;
     	zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, 0, NULL, NULL);
    @@ -1547,6 +1564,8 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
     
     	dmu_buf_rele(rootzp->z_dbuf, NULL);
     	rootzp->z_dbuf = NULL;
    +	for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
    +		mutex_destroy(&zfsvfs.z_hold_mtx[i]);
     	mutex_destroy(&zfsvfs.z_znodes_lock);
     	rootzp->z_vnode = NULL;
     	kmem_cache_free(znode_cache, rootzp);
    
    From cde38f4240111151e3629643e45497f93427c67a Mon Sep 17 00:00:00 2001
    From: Pawel Jakub Dawidek 
    Date: Sat, 1 May 2010 19:12:37 +0000
    Subject: [PATCH 2155/2592] MFC r207070:
    
    Fix compilation with WITHOUT_CRYPT or WITHOUT_OPENSSL options.
    
    Reported by:	Andrei V. Lavreniyuk 
    ---
     sbin/hastctl/Makefile | 9 +++++++--
     1 file changed, 7 insertions(+), 2 deletions(-)
    
    diff --git a/sbin/hastctl/Makefile b/sbin/hastctl/Makefile
    index 43c8c201b17..4ead83665de 100644
    --- a/sbin/hastctl/Makefile
    +++ b/sbin/hastctl/Makefile
    @@ -26,8 +26,13 @@ CFLAGS+=-DINET6
     # This is needed to have WARNS > 1.
     CFLAGS+=-DYY_NO_UNPUT
     
    -DPADD=	${LIBCRYPTO} ${LIBL}
    -LDADD=	-lcrypto -ll
    +DPADD=	${LIBL}
    +LDADD=	-ll
    +.if ${MK_OPENSSL} != "no"
    +DPADD+=	${LIBCRYPTO}
    +LDADD+=	-lcrypto
    +CFLAGS+=-DHAVE_CRYPTO
    +.endif
     
     YFLAGS+=-v
     
    
    From badd323276771e7bc68616639ac43749fdcc1cb9 Mon Sep 17 00:00:00 2001
    From: Pawel Jakub Dawidek 
    Date: Sat, 1 May 2010 19:16:08 +0000
    Subject: [PATCH 2156/2592] MFC
     r207070,r207343,r207345,r207347,r207348,r207371,r207372,r207390:
    
    r207070:
    
    Fix compilation with WITHOUT_CRYPT or WITHOUT_OPENSSL options.
    
    Reported by:	Andrei V. Lavreniyuk 
    
    r207343:
    
    Don't assume that "resource" property is in metadata.
    
    Reported by:	Mikolaj Golub 
    
    r207345:
    
    Use WEXITSTATUS() to obtain real exit code.
    
    r207347:
    
    Mark temporary issues as such.
    
    r207348:
    
    Restart worker thread only if the problem was temporary.
    In case of persistent problem we don't want to loop forever.
    
    r207371:
    
    Fix a problem where hastd will stuck in recv(2) after sending request to
    secondary, which died between send(2) and recv(2). Do it by adding timeout
    to recv(2) for primary incoming and outgoing sockets and secondary outgoing
    socket.
    
    Reported by:	Mikolaj Golub 
    Tested by:	Mikolaj Golub 
    
    r207372:
    
    - Check if the worker process was killed by signal and restart it.
    - Improve logging.
    
    Pointed out by:	Garrett Cooper 
    
    r207390:
    
    Default connection timeout is way too long. To make it shorter we have to
    make socket non-blocking, connect() and if we get EINPROGRESS, we have to
    wait using select(). Very complex, but I know no other way to define
    connection timeout for a given socket.
    
    Reported by:	hiroshi@soupacific.com
    ---
     sbin/hastd/Makefile       | 10 +++--
     sbin/hastd/hast.conf.5    |  7 ++++
     sbin/hastd/hast.h         |  3 ++
     sbin/hastd/hast_proto.c   |  8 ++++
     sbin/hastd/hastd.c        | 57 ++++++++++++++++++----------
     sbin/hastd/metadata.c     |  2 +-
     sbin/hastd/parse.y        | 32 +++++++++++++++-
     sbin/hastd/primary.c      | 10 ++++-
     sbin/hastd/proto.c        | 26 +++++++++++++
     sbin/hastd/proto.h        |  1 +
     sbin/hastd/proto_common.c |  4 +-
     sbin/hastd/proto_tcp4.c   | 78 +++++++++++++++++++++++++++++++++++++--
     sbin/hastd/secondary.c    |  6 +++
     sbin/hastd/token.l        |  1 +
     14 files changed, 214 insertions(+), 31 deletions(-)
    
    diff --git a/sbin/hastd/Makefile b/sbin/hastd/Makefile
    index 43118075e94..0b0721e5b63 100644
    --- a/sbin/hastd/Makefile
    +++ b/sbin/hastd/Makefile
    @@ -27,9 +27,13 @@ CFLAGS+=-DINET6
     # This is needed to have WARNS > 1.
     CFLAGS+=-DYY_NO_UNPUT
     
    -DPADD=	${LIBCRYPTO} ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} ${LIBL} \
    -	${LIBPTHREAD} ${LIBUTIL}
    -LDADD=	-lcrypto -lgeom -lbsdxml -lsbuf -ll -lpthread -lutil
    +DPADD=	${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} ${LIBL} ${LIBPTHREAD} ${LIBUTIL}
    +LDADD=	-lgeom -lbsdxml -lsbuf -ll -lpthread -lutil
    +.if ${MK_OPENSSL} != "no"
    +DPADD+=	${LIBCRYPTO}
    +LDADD+=	-lcrypto
    +CFLAGS+=-DHAVE_CRYPTO
    +.endif
     
     YFLAGS+=-v
     
    diff --git a/sbin/hastd/hast.conf.5 b/sbin/hastd/hast.conf.5
    index 5734ee8ef3d..1ccd47941c6 100644
    --- a/sbin/hastd/hast.conf.5
    +++ b/sbin/hastd/hast.conf.5
    @@ -58,6 +58,7 @@ file is following:
     control 
     listen 
     replication 
    +timeout 
     
     on  {
     	# Node section
    @@ -76,6 +77,7 @@ resource  {
     	replication 
     	name 
     	local 
    +	timeout 
     
     	on  {
     		# Resource-node section
    @@ -194,6 +196,11 @@ The
     .Ic async
     replication mode is currently not implemented.
     .El
    +.It Ic timeout Aq seconds
    +.Pp
    +Connection timeout in seconds.
    +The default value is
    +.Va 5 .
     .It Ic name Aq name
     .Pp
     GEOM provider name that will appear as
    diff --git a/sbin/hastd/hast.h b/sbin/hastd/hast.h
    index c5220b53be9..2230afb20d6 100644
    --- a/sbin/hastd/hast.h
    +++ b/sbin/hastd/hast.h
    @@ -75,6 +75,7 @@
     #define	HIO_DELETE		3
     #define	HIO_FLUSH		4
     
    +#define	HAST_TIMEOUT	5
     #define	HAST_CONFIG	"/etc/hast.conf"
     #define	HAST_CONTROL	"/var/run/hastctl"
     #define	HASTD_PORT	8457
    @@ -148,6 +149,8 @@ struct hast_resource {
     	/* Token to verify both in and out connection are coming from
     	   the same node (not necessarily from the same address). */
     	unsigned char hr_token[HAST_TOKEN_SIZE];
    +	/* Connection timeout. */
    +	int	hr_timeout;
     
     	/* Resource unique identifier. */
     	uint64_t hr_resuid;
    diff --git a/sbin/hastd/hast_proto.c b/sbin/hastd/hast_proto.c
    index 6e660069ef9..348dfc887bb 100644
    --- a/sbin/hastd/hast_proto.c
    +++ b/sbin/hastd/hast_proto.c
    @@ -37,7 +37,9 @@ __FBSDID("$FreeBSD$");
     #include 
     #include 
     
    +#ifdef HAVE_CRYPTO
     #include 
    +#endif
     
     #include 
     #include 
    @@ -67,14 +69,18 @@ static int compression_send(struct hast_resource *res, struct nv *nv,
         void **datap, size_t *sizep, bool *freedatap);
     static int compression_recv(struct hast_resource *res, struct nv *nv,
         void **datap, size_t *sizep, bool *freedatap);
    +#ifdef HAVE_CRYPTO
     static int checksum_send(struct hast_resource *res, struct nv *nv,
         void **datap, size_t *sizep, bool *freedatap);
     static int checksum_recv(struct hast_resource *res, struct nv *nv,
         void **datap, size_t *sizep, bool *freedatap);
    +#endif
     
     static struct hast_pipe_stage pipeline[] = {
     	{ "compression", compression_send, compression_recv },
    +#ifdef HAVE_CRYPTO
     	{ "checksum", checksum_send, checksum_recv }
    +#endif
     };
     
     static int
    @@ -161,6 +167,7 @@ compression_recv(struct hast_resource *res, struct nv *nv, void **datap,
     	return (0);
     }
     
    +#ifdef HAVE_CRYPTO
     static int
     checksum_send(struct hast_resource *res, struct nv *nv, void **datap,
         size_t *sizep, bool *freedatap __unused)
    @@ -221,6 +228,7 @@ checksum_recv(struct hast_resource *res, struct nv *nv, void **datap,
     
     	return (0);
     }
    +#endif	/* HAVE_CRYPTO */
     
     /*
      * Send the given nv structure via conn.
    diff --git a/sbin/hastd/hastd.c b/sbin/hastd/hastd.c
    index 957885d7ac1..27b9bba4064 100644
    --- a/sbin/hastd/hastd.c
    +++ b/sbin/hastd/hastd.c
    @@ -107,6 +107,22 @@ g_gate_load(void)
     	}
     }
     
    +static void
    +child_exit_log(unsigned int pid, int status)
    +{
    +
    +	if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
    +		pjdlog_debug(1, "Worker process exited gracefully (pid=%u).",
    +		    pid);
    +	} else if (WIFSIGNALED(status)) {
    +		pjdlog_error("Worker process killed (pid=%u, signal=%d).",
    +		    pid, WTERMSIG(status));
    +	} else {
    +		pjdlog_error("Worker process exited ungracefully (pid=%u, exitcode=%d).",
    +		    pid, WIFEXITED(status) ? WEXITSTATUS(status) : -1);
    +	}
    +}
    +
     static void
     child_exit(void)
     {
    @@ -129,20 +145,25 @@ child_exit(void)
     		}
     		pjdlog_prefix_set("[%s] (%s) ", res->hr_name,
     		    role2str(res->hr_role));
    -		if (WEXITSTATUS(status) == 0) {
    -			pjdlog_debug(1,
    -			    "Worker process exited gracefully (pid=%u).",
    -			    (unsigned int)pid);
    -		} else {
    -			pjdlog_error("Worker process failed (pid=%u, status=%d).",
    -			    (unsigned int)pid, WEXITSTATUS(status));
    -		}
    +		child_exit_log(pid, status);
     		proto_close(res->hr_ctrl);
     		res->hr_workerpid = 0;
     		if (res->hr_role == HAST_ROLE_PRIMARY) {
    -			sleep(1);
    -			pjdlog_info("Restarting worker process.");
    -			hastd_primary(res);
    +			/*
    +			 * Restart child process if it was killed by signal
    +			 * or exited because of temporary problem.
    +			 */
    +			if (WIFSIGNALED(status) ||
    +			    (WIFEXITED(status) &&
    +			     WEXITSTATUS(status) == EX_TEMPFAIL)) {
    +				sleep(1);
    +				pjdlog_info("Restarting worker process.");
    +				hastd_primary(res);
    +			} else {
    +				res->hr_role = HAST_ROLE_INIT;
    +				pjdlog_info("Changing resource role back to %s.",
    +				    role2str(res->hr_role));
    +			}
     		}
     		pjdlog_prefix_set("%s", "");
     	}
    @@ -181,6 +202,10 @@ listen_accept(void)
     	proto_remote_address(conn, raddr, sizeof(raddr));
     	pjdlog_info("Connection from %s to %s.", laddr, raddr);
     
    +	/* Error in setting timeout is not critical, but why should it fail? */
    +	if (proto_timeout(conn, HAST_TIMEOUT) < 0)
    +		pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
    +
     	nvin = nvout = nverr = NULL;
     
     	/*
    @@ -290,18 +315,12 @@ listen_accept(void)
     			/* Wait for it to exit. */
     			else if ((pid = waitpid(res->hr_workerpid,
     			    &status, 0)) != res->hr_workerpid) {
    +				/* We can only log the problem. */
     				pjdlog_errno(LOG_ERR,
     				    "Waiting for worker process (pid=%u) failed",
     				    (unsigned int)res->hr_workerpid);
    -				/* See above. */
    -			} else if (status != 0) {
    -				pjdlog_error("Worker process (pid=%u) exited ungracefully: status=%d.",
    -				    (unsigned int)res->hr_workerpid, status);
    -				/* See above. */
     			} else {
    -				pjdlog_debug(1,
    -				    "Worker process (pid=%u) exited gracefully.",
    -				    (unsigned int)res->hr_workerpid);
    +				child_exit_log(res->hr_workerpid, status);
     			}
     			res->hr_workerpid = 0;
     		} else if (res->hr_remotein != NULL) {
    diff --git a/sbin/hastd/metadata.c b/sbin/hastd/metadata.c
    index 9bca66bbbe1..7a138e816dc 100644
    --- a/sbin/hastd/metadata.c
    +++ b/sbin/hastd/metadata.c
    @@ -117,7 +117,7 @@ metadata_read(struct hast_resource *res, bool openrw)
     	}
     
     	str = nv_get_string(nv, "resource");
    -	if (strcmp(str, res->hr_name) != 0) {
    +	if (str != NULL && strcmp(str, res->hr_name) != 0) {
     		pjdlog_error("Provider %s is not part of resource %s.",
     		    res->hr_localpath, res->hr_name);
     		nv_free(nv);
    diff --git a/sbin/hastd/parse.y b/sbin/hastd/parse.y
    index 67553208ac6..840a8448951 100644
    --- a/sbin/hastd/parse.y
    +++ b/sbin/hastd/parse.y
    @@ -58,6 +58,7 @@ static bool mynode;
     static char depth0_control[HAST_ADDRSIZE];
     static char depth0_listen[HAST_ADDRSIZE];
     static int depth0_replication;
    +static int depth0_timeout;
     
     static char depth1_provname[PATH_MAX];
     static char depth1_localpath[PATH_MAX];
    @@ -115,6 +116,7 @@ yy_config_parse(const char *config)
     	curres = NULL;
     	mynode = false;
     
    +	depth0_timeout = HAST_TIMEOUT;
     	depth0_replication = HAST_REPLICATION_MEMSYNC;
     	strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
     	strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
    @@ -154,6 +156,13 @@ yy_config_parse(const char *config)
     			 */
     			curres->hr_replication = depth0_replication;
     		}
    +		if (curres->hr_timeout == -1) {
    +			/*
    +			 * Timeout is not set at resource-level.
    +			 * Use global or default setting.
    +			 */
    +			curres->hr_timeout = depth0_timeout;
    +		}
     	}
     
     	return (&lconfig);
    @@ -171,7 +180,7 @@ yy_config_free(struct hastd_config *config)
     }
     %}
     
    -%token CONTROL LISTEN PORT REPLICATION EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
    +%token CONTROL LISTEN PORT REPLICATION TIMEOUT EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
     %token FULLSYNC MEMSYNC ASYNC
     %token NUM STR OB CB
     
    @@ -200,6 +209,8 @@ statement:
     	|
     	replication_statement
     	|
    +	timeout_statement
    +	|
     	node_statement
     	|
     	resource_statement
    @@ -281,6 +292,22 @@ replication_type:
     	ASYNC		{ $$ = HAST_REPLICATION_ASYNC; }
     	;
     
    +timeout_statement:	TIMEOUT NUM
    +	{
    +		switch (depth) {
    +		case 0:
    +			depth0_timeout = $2;
    +			break;
    +		case 1:
    +			if (curres != NULL)
    +				curres->hr_timeout = $2;
    +			break;
    +		default:
    +			assert(!"timeout at wrong depth level");
    +		}
    +	}
    +	;
    +
     node_statement:		ON node_start OB node_entries CB
     	{
     		mynode = false;
    @@ -389,6 +416,7 @@ resource_start:	STR
     		curres->hr_role = HAST_ROLE_INIT;
     		curres->hr_previous_role = HAST_ROLE_INIT;
     		curres->hr_replication = -1;
    +		curres->hr_timeout = -1;
     		curres->hr_provname[0] = '\0';
     		curres->hr_localpath[0] = '\0';
     		curres->hr_localfd = -1;
    @@ -405,6 +433,8 @@ resource_entries:
     resource_entry:
     	replication_statement
     	|
    +	timeout_statement
    +	|
     	name_statement
     	|
     	local_statement
    diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c
    index 09151546772..9f2b2c79b49 100644
    --- a/sbin/hastd/primary.c
    +++ b/sbin/hastd/primary.c
    @@ -480,7 +480,7 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
     
     	/* Prepare outgoing connection with remote node. */
     	if (proto_client(res->hr_remoteaddr, &out) < 0) {
    -		primary_exit(EX_OSERR, "Unable to create connection to %s",
    +		primary_exit(EX_TEMPFAIL, "Unable to create connection to %s",
     		    res->hr_remoteaddr);
     	}
     	/* Try to connect, but accept failure. */
    @@ -489,6 +489,9 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
     		    res->hr_remoteaddr);
     		goto close;
     	}
    +	/* Error in setting timeout is not critical, but why should it fail? */
    +	if (proto_timeout(out, res->hr_timeout) < 0)
    +		pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
     	/*
     	 * First handshake step.
     	 * Setup outgoing connection with remote node.
    @@ -552,6 +555,9 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
     		    res->hr_remoteaddr);
     		goto close;
     	}
    +	/* Error in setting timeout is not critical, but why should it fail? */
    +	if (proto_timeout(in, res->hr_timeout) < 0)
    +		pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
     	nvout = nv_alloc();
     	nv_add_string(nvout, res->hr_name, "resource");
     	nv_add_uint8_array(nvout, res->hr_token, sizeof(res->hr_token),
    @@ -739,7 +745,7 @@ hastd_primary(struct hast_resource *res)
     	pid = fork();
     	if (pid < 0) {
     		KEEP_ERRNO((void)pidfile_remove(pfh));
    -		primary_exit(EX_OSERR, "Unable to fork");
    +		primary_exit(EX_TEMPFAIL, "Unable to fork");
     	}
     
     	if (pid > 0) {
    diff --git a/sbin/hastd/proto.c b/sbin/hastd/proto.c
    index 103f20ce9fd..531e7e5fc05 100644
    --- a/sbin/hastd/proto.c
    +++ b/sbin/hastd/proto.c
    @@ -30,7 +30,9 @@
     #include 
     __FBSDID("$FreeBSD$");
     
    +#include 
     #include 
    +#include 
     
     #include 
     #include 
    @@ -247,6 +249,30 @@ proto_remote_address(const struct proto_conn *conn, char *addr, size_t size)
     	conn->pc_proto->hp_remote_address(conn->pc_ctx, addr, size);
     }
     
    +int
    +proto_timeout(const struct proto_conn *conn, int timeout)
    +{
    +	struct timeval tv;
    +	int fd;
    +
    +	assert(conn != NULL);
    +	assert(conn->pc_magic == PROTO_CONN_MAGIC);
    +	assert(conn->pc_proto != NULL);
    +
    +	fd = proto_descriptor(conn);
    +	if (fd < 0)
    +		return (-1);
    +
    +	tv.tv_sec = timeout;
    +	tv.tv_usec = 0;
    +	if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
    +		return (-1);
    +	if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
    +		return (-1);
    +
    +	return (0);
    +}
    +
     void
     proto_close(struct proto_conn *conn)
     {
    diff --git a/sbin/hastd/proto.h b/sbin/hastd/proto.h
    index cb196d8da86..13248bad649 100644
    --- a/sbin/hastd/proto.h
    +++ b/sbin/hastd/proto.h
    @@ -49,6 +49,7 @@ void proto_local_address(const struct proto_conn *conn, char *addr,
         size_t size);
     void proto_remote_address(const struct proto_conn *conn, char *addr,
         size_t size);
    +int proto_timeout(const struct proto_conn *conn, int timeout);
     void proto_close(struct proto_conn *conn);
     
     #endif	/* !_PROTO_H_ */
    diff --git a/sbin/hastd/proto_common.c b/sbin/hastd/proto_common.c
    index 22102d86e82..131d30e19ef 100644
    --- a/sbin/hastd/proto_common.c
    +++ b/sbin/hastd/proto_common.c
    @@ -58,7 +58,7 @@ proto_common_send(int fd, const unsigned char *data, size_t size)
     		if (done == 0)
     			return (ENOTCONN);
     		else if (done < 0) {
    -			if (errno == EAGAIN)
    +			if (errno == EINTR)
     				continue;
     			return (errno);
     		}
    @@ -76,7 +76,7 @@ proto_common_recv(int fd, unsigned char *data, size_t size)
     
     	do {
     		done = recv(fd, data, size, MSG_WAITALL);
    -	} while (done == -1 && errno == EAGAIN);
    +	} while (done == -1 && errno == EINTR);
     	if (done == 0)
     		return (ENOTCONN);
     	else if (done < 0)
    diff --git a/sbin/hastd/proto_tcp4.c b/sbin/hastd/proto_tcp4.c
    index 2fba9967e40..5af82d53185 100644
    --- a/sbin/hastd/proto_tcp4.c
    +++ b/sbin/hastd/proto_tcp4.c
    @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
     
     #include 
     #include 
    +#include 
     #include 
     #include 
     #include 
    @@ -47,6 +48,7 @@ __FBSDID("$FreeBSD$");
     #include "hast.h"
     #include "pjdlog.h"
     #include "proto_impl.h"
    +#include "subr.h"
     
     #define	TCP4_CTX_MAGIC	0x7c441c
     struct tcp4_ctx {
    @@ -222,18 +224,88 @@ static int
     tcp4_connect(void *ctx)
     {
     	struct tcp4_ctx *tctx = ctx;
    +	struct timeval tv;
    +	fd_set fdset;
    +	socklen_t esize;
    +	int error, flags, ret;
     
     	assert(tctx != NULL);
     	assert(tctx->tc_magic == TCP4_CTX_MAGIC);
     	assert(tctx->tc_side == TCP4_SIDE_CLIENT);
     	assert(tctx->tc_fd >= 0);
     
    -	if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
    -	    sizeof(tctx->tc_sin)) < 0) {
    +	flags = fcntl(tctx->tc_fd, F_GETFL);
    +	if (flags == -1) {
    +		KEEP_ERRNO(pjdlog_common(LOG_DEBUG, 1, errno,
    +		    "fcntl(F_GETFL) failed"));
    +		return (errno);
    +	}
    +	/*
    +	 * We make socket non-blocking so we have decided about connection
    +	 * timeout.
    +	 */
    +	flags |= O_NONBLOCK;
    +	if (fcntl(tctx->tc_fd, F_SETFL, flags) == -1) {
    +		KEEP_ERRNO(pjdlog_common(LOG_DEBUG, 1, errno,
    +		    "fcntl(F_SETFL, O_NONBLOCK) failed"));
     		return (errno);
     	}
     
    -	return (0);
    +	if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
    +	    sizeof(tctx->tc_sin)) == 0) {
    +		error = 0;
    +		goto done;
    +	}
    +	if (errno != EINPROGRESS) {
    +		error = errno;
    +		pjdlog_common(LOG_DEBUG, 1, errno, "connect() failed");
    +		goto done;
    +	}
    +	/*
    +	 * Connection can't be established immediately, let's wait
    +	 * for HAST_TIMEOUT seconds.
    +	 */
    +	tv.tv_sec = HAST_TIMEOUT;
    +	tv.tv_usec = 0;
    +again:
    +	FD_ZERO(&fdset);
    +	FD_SET(tctx->tc_fd, &fdset); 
    +	ret = select(tctx->tc_fd + 1, NULL, &fdset, NULL, &tv);
    +	if (ret == 0) {
    +		error = ETIMEDOUT;
    +		goto done;
    +	} else if (ret == -1) {
    +		if (errno == EINTR)
    +			goto again;
    +		error = errno;
    +		pjdlog_common(LOG_DEBUG, 1, errno, "select() failed");
    +		goto done;
    +	}
    +	assert(ret > 0);
    +	assert(FD_ISSET(tctx->tc_fd, &fdset));
    +	esize = sizeof(error);
    +	if (getsockopt(tctx->tc_fd, SOL_SOCKET, SO_ERROR, &error,
    +	    &esize) == -1) {
    +		error = errno;
    +		pjdlog_common(LOG_DEBUG, 1, errno,
    +		    "getsockopt(SO_ERROR) failed");
    +		goto done;
    +	}
    +	if (error != 0) {
    +		pjdlog_common(LOG_DEBUG, 1, error,
    +		    "getsockopt(SO_ERROR) returned error");
    +		goto done;
    +	}
    +	error = 0;
    +done:
    +	flags &= ~O_NONBLOCK;
    +	if (fcntl(tctx->tc_fd, F_SETFL, flags) == -1) {
    +		if (error == 0)
    +			error = errno;
    +		pjdlog_common(LOG_DEBUG, 1, errno,
    +		    "fcntl(F_SETFL, ~O_NONBLOCK) failed");
    +	}
    +	return (error);
     }
     
     static int
    diff --git a/sbin/hastd/secondary.c b/sbin/hastd/secondary.c
    index 6af95b5d69e..b189b7e2a2b 100644
    --- a/sbin/hastd/secondary.c
    +++ b/sbin/hastd/secondary.c
    @@ -337,6 +337,12 @@ hastd_secondary(struct hast_resource *res, struct nv *nvin)
     
     	setproctitle("%s (secondary)", res->hr_name);
     
    +	/* Error in setting timeout is not critical, but why should it fail? */
    +	if (proto_timeout(res->hr_remotein, 0) < 0)
    +		pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
    +	if (proto_timeout(res->hr_remoteout, res->hr_timeout) < 0)
    +		pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
    +
     	init_local(res);
     	init_remote(res, nvin);
     	init_environment();
    diff --git a/sbin/hastd/token.l b/sbin/hastd/token.l
    index 7b80384e28b..e5d4ca10df2 100644
    --- a/sbin/hastd/token.l
    +++ b/sbin/hastd/token.l
    @@ -48,6 +48,7 @@ control			{ DP; return CONTROL; }
     listen			{ DP; return LISTEN; }
     port			{ DP; return PORT; }
     replication		{ DP; return REPLICATION; }
    +timeout			{ DP; return TIMEOUT; }
     resource		{ DP; return RESOURCE; }
     name			{ DP; return NAME; }
     local			{ DP; return LOCAL; }
    
    From 13f80c05d1c0e67ccf7bcd68457c2d0c1d379d83 Mon Sep 17 00:00:00 2001
    From: Weongyo Jeong 
    Date: Sat, 1 May 2010 23:25:53 +0000
    Subject: [PATCH 2157/2592] MFC r207176:   ifp->if_ipackets++ when RX packet
     interrupts are occurred.
    
    ---
     sys/dev/bwn/if_bwn.c | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
    index a48548b4768..c6c192ed85c 100644
    --- a/sys/dev/bwn/if_bwn.c
    +++ b/sys/dev/bwn/if_bwn.c
    @@ -9413,6 +9413,8 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
     	rssi = rxhdr->phy.abg.rssi;	/* XXX incorrect RSSI calculation? */
     	noise = mac->mac_stats.link_noise;
     
    +	ifp->if_ipackets++;
    +
     	BWN_UNLOCK(sc);
     
     	ni = ieee80211_find_rxnode(ic, wh);
    
    From cf94fc20bbd1b9dd3a471d92fe147d29a0dd9a52 Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Sun, 2 May 2010 06:14:36 +0000
    Subject: [PATCH 2158/2592] MFC r207260:   Move checking the version up from
     Makefile generation to just after   we've parsed the config file.  Makefile
     generation is too late if   we've introduce changes to the syntax of the
     metafiles to warn about   version skew, since we have to try to parse them
     and we get an parse   error that's rather baffling to the user rather than a
     'your config is   too old, upgrade' which we should get.
    
      We have to defer doing it until after we've read the user's config
      file because we define machinename there.  The version required to
      compile the kernel is encoded in Makefile.machinename.  There's no
      real reason for this to be the case, but changing it now would
      introduce some logistical issues that I'd rather avoid for the moment.
      I intend to revisit this if we're still using config in FreeBSD 10.
    
      This also means that we cannot introduce any config metafile changes
      that result in a syntax error or other error for the user until 9.0 is
      released.  Otherwise, we break the upgrade path, or at least reduce
      the usefulness of the error messages we generate.
    
      # This implies that the config file option mapping will need to be redone.
    ---
     usr.sbin/config/config.h     |  1 +
     usr.sbin/config/main.c       | 40 ++++++++++++++++++++++++++++++++
     usr.sbin/config/mkmakefile.c | 45 +++++++++++++++++-------------------
     3 files changed, 62 insertions(+), 24 deletions(-)
    
    diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h
    index ec199862ae7..4abb567e984 100644
    --- a/usr.sbin/config/config.h
    +++ b/usr.sbin/config/config.h
    @@ -179,6 +179,7 @@ void	makehints(void);
     void	headers(void);
     void	cfgfile_add(const char *);
     void	cfgfile_removeall(void);
    +FILE	*open_makefile_template(void);
     
     extern STAILQ_HEAD(device_head, device) dtab;
     
    diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c
    index 2b5e055130b..5cffed2c641 100644
    --- a/usr.sbin/config/main.c
    +++ b/usr.sbin/config/main.c
    @@ -90,6 +90,7 @@ static void get_srcdir(void);
     static void usage(void);
     static void cleanheaders(char *);
     static void kernconfdump(const char *);
    +static void checkversion(void);
     
     struct hdr_list {
     	char *h_name;
    @@ -204,6 +205,7 @@ main(int argc, char **argv)
     		printf("cpu type must be specified\n");
     		exit(1);
     	}
    +	checkversion();
     
     	/*
     	 * make symbolic links in compilation directory
    @@ -721,3 +723,41 @@ kernconfdump(const char *file)
     	}
     	fclose(fp);
     }
    +
    +static void 
    +badversion(int versreq)
    +{
    +	fprintf(stderr, "ERROR: version of config(8) does not match kernel!\n");
    +	fprintf(stderr, "config version = %d, ", CONFIGVERS);
    +	fprintf(stderr, "version required = %d\n\n", versreq);
    +	fprintf(stderr, "Make sure that /usr/src/usr.sbin/config is in sync\n");
    +	fprintf(stderr, "with your /usr/src/sys and install a new config binary\n");
    +	fprintf(stderr, "before trying this again.\n\n");
    +	fprintf(stderr, "If running the new config fails check your config\n");
    +	fprintf(stderr, "file against the GENERIC or LINT config files for\n");
    +	fprintf(stderr, "changes in config syntax, or option/device naming\n");
    +	fprintf(stderr, "conventions\n\n");
    +	exit(1);
    +}
    +
    +static void
    +checkversion(void)
    +{
    +	FILE *ifp;
    +	char line[BUFSIZ];
    +	int versreq;
    +
    +	ifp = open_makefile_template();
    +	while (fgets(line, BUFSIZ, ifp) != 0) {
    +		if (*line != '%')
    +			continue;
    +		if (strncmp(line, "%VERSREQ=", 9) != 0)
    +			continue;
    +		versreq = atoi(line + 9);
    +		if (MAJOR_VERS(versreq) == MAJOR_VERS(CONFIGVERS) &&
    +		    versreq <= CONFIGVERS)
    +			continue;
    +		badversion(versreq);
    +	}
    +	fclose(ifp);
    +}
    diff --git a/usr.sbin/config/mkmakefile.c b/usr.sbin/config/mkmakefile.c
    index f0d37faadc8..844364ca05f 100644
    --- a/usr.sbin/config/mkmakefile.c
    +++ b/usr.sbin/config/mkmakefile.c
    @@ -105,17 +105,14 @@ new_fent(void)
     }
     
     /*
    - * Build the makefile from the skeleton
    + * Open the correct Makefile and return it, or error out.
      */
    -void
    -makefile(void)
    +FILE *
    +open_makefile_template(void)
     {
    -	FILE *ifp, *ofp;
    +	FILE *ifp;
     	char line[BUFSIZ];
    -	struct opt *op, *t;
    -	int versreq;
     
    -	read_files();
     	snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename);
     	ifp = fopen(line, "r");
     	if (ifp == 0) {
    @@ -124,7 +121,21 @@ makefile(void)
     	}
     	if (ifp == 0)
     		err(1, "%s", line);
    +	return (ifp);
    +}
     
    +/*
    + * Build the makefile from the skeleton
    + */
    +void
    +makefile(void)
    +{
    +	FILE *ifp, *ofp;
    +	char line[BUFSIZ];
    +	struct opt *op, *t;
    +
    +	read_files();
    +	ifp = open_makefile_template();
     	ofp = fopen(path("Makefile.new"), "w");
     	if (ofp == 0)
     		err(1, "%s", path("Makefile.new"));
    @@ -156,23 +167,9 @@ makefile(void)
     			do_rules(ofp);
     		else if (eq(line, "%CLEAN\n"))
     			do_clean(ofp);
    -		else if (strncmp(line, "%VERSREQ=", sizeof("%VERSREQ=") - 1) == 0) {
    -			versreq = atoi(line + sizeof("%VERSREQ=") - 1);
    -			if (MAJOR_VERS(versreq) != MAJOR_VERS(CONFIGVERS) ||
    -			    versreq > CONFIGVERS) {
    -				fprintf(stderr, "ERROR: version of config(8) does not match kernel!\n");
    -				fprintf(stderr, "config version = %d, ", CONFIGVERS);
    -				fprintf(stderr, "version required = %d\n\n", versreq);
    -				fprintf(stderr, "Make sure that /usr/src/usr.sbin/config is in sync\n");
    -				fprintf(stderr, "with your /usr/src/sys and install a new config binary\n");
    -				fprintf(stderr, "before trying this again.\n\n");
    -				fprintf(stderr, "If running the new config fails check your config\n");
    -				fprintf(stderr, "file against the GENERIC or LINT config files for\n");
    -				fprintf(stderr, "changes in config syntax, or option/device naming\n");
    -				fprintf(stderr, "conventions\n\n");
    -				exit(1);
    -			}
    -		} else
    +		else if (strncmp(line, "%VERSREQ=", 9) == 0)
    +			line[0] = '\0'; /* handled elsewhere */
    +		else
     			fprintf(stderr,
     			    "Unknown %% construct in generic makefile: %s",
     			    line);
    
    From 0f2b463aa4b069009928e56a10bae572652093ad Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Sun, 2 May 2010 06:18:08 +0000
    Subject: [PATCH 2159/2592] MFC r207263:
    
      Redo how we add compat options so as to be compatible with old
      versions of config.  Remove support for the syntax OLD = NEW form the
      options file, and instead have a new file $S/conf/options-compat.
      This file will be parsed as OLD NEW on each line.  Bump version of
      config.  Since nothing in -current ever used this, there's no hazards
      for current users, so I'm not bumping the version in the
      Makefiles.$MACHINE.  No need, really, for this version bump in
      -current, but this was introduced into -stable before I realized the
      version check was ineffective there, so the verison bump doesn't hurt
      here and keeps the two branches in sync, versionwise, after the MFC.
    ---
     usr.sbin/config/configvers.h |   2 +-
     usr.sbin/config/mkoptions.c  | 159 ++++++++++++++++++-----------------
     2 files changed, 82 insertions(+), 79 deletions(-)
    
    diff --git a/usr.sbin/config/configvers.h b/usr.sbin/config/configvers.h
    index 73310bd6f41..2d43329b37b 100644
    --- a/usr.sbin/config/configvers.h
    +++ b/usr.sbin/config/configvers.h
    @@ -49,5 +49,5 @@
      *
      * $FreeBSD$
      */
    -#define	CONFIGVERS	600008
    +#define	CONFIGVERS	600009
     #define	MAJOR_VERS(x)	((x) / 100000)
    diff --git a/usr.sbin/config/mkoptions.c b/usr.sbin/config/mkoptions.c
    index 1a6ccc8fec0..846e028c4cd 100644
    --- a/usr.sbin/config/mkoptions.c
    +++ b/usr.sbin/config/mkoptions.c
    @@ -166,7 +166,7 @@ do_option(char *name)
     			fprintf(outf, "#define %s %s\n", name, value);
     		} /* else empty file */
     
    -		(void) fclose(outf);
    +		(void)fclose(outf);
     		return;
     	}
     	basefile = "";
    @@ -225,7 +225,7 @@ do_option(char *name)
     		if (cp == (char *)EOF)
     			break;
     	}
    -	(void) fclose(inf);
    +	(void)fclose(inf);
     	if (!tidy && ((value == NULL && oldvalue == NULL) ||
     	    (value && oldvalue && eq(value, oldvalue)))) {	
     		while (!SLIST_EMPTY(&op_head)) {
    @@ -263,7 +263,7 @@ do_option(char *name)
     		free(op->op_value);
     		free(op);
     	}
    -	(void) fclose(outf);
    +	(void)fclose(outf);
     }
     
     /*
    @@ -277,7 +277,7 @@ tooption(char *name)
     	struct opt_list *po;
     
     	/* "cannot happen"?  the otab list should be complete.. */
    -	(void) strlcpy(nbuf, "options.h", sizeof(nbuf));
    +	(void)strlcpy(nbuf, "options.h", sizeof(nbuf));
     
     	SLIST_FOREACH(po, &otab, o_next) {
     		if (eq(po->o_name, name)) {
    @@ -286,78 +286,30 @@ tooption(char *name)
     		}
     	}
     
    -	(void) strlcpy(hbuf, path(nbuf), sizeof(hbuf));
    +	(void)strlcpy(hbuf, path(nbuf), sizeof(hbuf));
     	return (hbuf);
     }
     
    -/*
    - * read the options and options. files
    - */
    +	
     static void
    -read_options(void)
    +insert_option(char *this, char *val, int flags)
     {
    -	FILE *fp;
    -	char fname[MAXPATHLEN];
    -	char *wd, *this, *val;
     	struct opt_list *po;
    -	int first = 1;
    -	char genopt[MAXPATHLEN];
    -	int flags = 0;
     
    -	SLIST_INIT(&otab);
    -	(void) snprintf(fname, sizeof(fname), "../../conf/options");
    -openit:
    -	fp = fopen(fname, "r");
    -	if (fp == 0) {
    -		return;
    -	}
    -next:
    -	flags = 0;
    -	wd = get_word(fp);
    -	if (wd == (char *)EOF) {
    -		(void) fclose(fp);
    -		if (first == 1) {
    -			first++;
    -			(void) snprintf(fname, sizeof fname, "../../conf/options.%s", machinename);
    -			fp = fopen(fname, "r");
    -			if (fp != 0)
    -				goto next;
    -			(void) snprintf(fname, sizeof fname, "options.%s", machinename);
    -			goto openit;
    -		}
    -		return;
    -	}
    -	if (wd == 0)
    -		goto next;
    -	if (wd[0] == '#')
    -	{
    -		while (((wd = get_word(fp)) != (char *)EOF) && wd)
    -		;
    -		goto next;
    -	}
    -	this = ns(wd);
    -	val = get_word(fp);
    -	if (val == (char *)EOF)
    -		return;
    -	if (val == 0) {
    -		char *s = ns(this);
    -		(void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s));
    -		val = genopt;
    -		free(s);
    -	} else if (eq(val, "=")) {
    -		val = get_word(fp);
    -		if (val == (char *)EOF) {
    -			printf("%s: unexpected end of file\n", fname);
    -			exit(1);
    -		}
    -		if (val == 0) {
    -			printf("%s: Expected a right hand side at %s\n", fname,
    -			    this);
    -			exit(1);
    -		}
    -		flags |= OL_ALIAS;
    -	}
    -	val = ns(val);
    +	po = (struct opt_list *) calloc(1, sizeof *po);
    +	if (po == NULL)
    +		err(EXIT_FAILURE, "calloc");
    +	po->o_name = this;
    +	po->o_file = val;
    +	po->o_flags = flags;
    +	SLIST_INSERT_HEAD(&otab, po, o_next);
    +}
    +
    +
    +static void
    +check_duplicate(const char *fname, const char *this)
    +{
    +	struct opt_list *po;
     
     	SLIST_FOREACH(po, &otab, o_next) {
     		if (eq(po->o_name, this)) {
    @@ -366,16 +318,67 @@ next:
     			exit(1);
     		}
     	}
    -	
    -	po = (struct opt_list *) calloc(1, sizeof *po);
    -	if (po == NULL)
    -		err(EXIT_FAILURE, "calloc");
    -	po->o_name = this;
    -	po->o_file = val;
    -	po->o_flags = flags;
    -	SLIST_INSERT_HEAD(&otab, po, o_next);
    +}
     
    -	goto next;
    +static int
    +read_option_file(const char *fname, int flags)
    +{
    +	FILE *fp;
    +	char *wd, *this, *val;
    +	char genopt[MAXPATHLEN];
    +
    +	fp = fopen(fname, "r");
    +	if (fp == 0)
    +		return (0);
    +	while ((wd = get_word(fp)) != (char *)EOF) {
    +		if (wd == 0)
    +			continue;
    +		if (wd[0] == '#') {
    +			while (((wd = get_word(fp)) != (char *)EOF) && wd)
    +				continue;
    +			continue;
    +		}
    +		this = ns(wd);
    +		val = get_word(fp);
    +		if (val == (char *)EOF)
    +			return (1);
    +		if (val == 0) {
    +			if (flags) {
    +				printf("%s: compat file requires two words "
    +				    "per line at %s\n", fname, this);
    +				exit(1);
    +			}
    +			char *s = ns(this);
    +			(void)snprintf(genopt, sizeof(genopt), "opt_%s.h",
    +			    lower(s));
    +			val = genopt;
    +			free(s);
    +		}
    +		val = ns(val);
    +		check_duplicate(fname, this);
    +		insert_option(this, val, flags);
    +	}
    +	(void)fclose(fp);
    +	return (1);
    +}
    +
    +/*
    + * read the options and options. files
    + */
    +static void
    +read_options(void)
    +{
    +	char fname[MAXPATHLEN];
    +
    +	SLIST_INIT(&otab);
    +	read_option_file("../../conf/options", 0);
    +	(void)snprintf(fname, sizeof fname, "../../conf/options.%s",
    +	    machinename);
    +	if (!read_option_file(fname, 0)) {
    +		(void)snprintf(fname, sizeof fname, "options.%s", machinename);
    +		read_option_file(fname, 0);
    +	}
    +	read_option_file("../../conf/options-compat", OL_ALIAS);
     }
     
     static char *
    
    From 458cda3710e68294400210398cd372d4a35b7edd Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Sun, 2 May 2010 06:18:57 +0000
    Subject: [PATCH 2160/2592] MFC r207265:   Require the option that's mapped be
     listed in the options file.  This   will allow people with old config options
     to either have it just work   (if config is new enough), or get a version
     error (if their config is   about 7.0 or newer) rather than getting a cryptic
     error about   duplicated options in the options file, or getting an error
     about an   unknown option, at which point they'd update their config file
     only to   learn they need a new config, only to learn they didn't really need
     to   update their config file...  All this because our version checking was  
     in the wrong place for the past decade...
    
      # hopefully this is the last change, and we'll be able to config with an
      # 8.0 GENERIC file on stable/8 after I merge this change and add the
      # compat options.
    ---
     usr.sbin/config/mkoptions.c | 53 +++++++++++++++++++++++++------------
     1 file changed, 36 insertions(+), 17 deletions(-)
    
    diff --git a/usr.sbin/config/mkoptions.c b/usr.sbin/config/mkoptions.c
    index 846e028c4cd..044b669f3a3 100644
    --- a/usr.sbin/config/mkoptions.c
    +++ b/usr.sbin/config/mkoptions.c
    @@ -291,21 +291,6 @@ tooption(char *name)
     }
     
     	
    -static void
    -insert_option(char *this, char *val, int flags)
    -{
    -	struct opt_list *po;
    -
    -	po = (struct opt_list *) calloc(1, sizeof *po);
    -	if (po == NULL)
    -		err(EXIT_FAILURE, "calloc");
    -	po->o_name = this;
    -	po->o_file = val;
    -	po->o_flags = flags;
    -	SLIST_INSERT_HEAD(&otab, po, o_next);
    -}
    -
    -
     static void
     check_duplicate(const char *fname, const char *this)
     {
    @@ -320,6 +305,38 @@ check_duplicate(const char *fname, const char *this)
     	}
     }
     
    +static void
    +insert_option(const char *fname, char *this, char *val)
    +{
    +	struct opt_list *po;
    +
    +	check_duplicate(fname, this);
    +	po = (struct opt_list *) calloc(1, sizeof *po);
    +	if (po == NULL)
    +		err(EXIT_FAILURE, "calloc");
    +	po->o_name = this;
    +	po->o_file = val;
    +	po->o_flags = 0;
    +	SLIST_INSERT_HEAD(&otab, po, o_next);
    +}
    +
    +static void
    +update_option(const char *this, char *val, int flags)
    +{
    +	struct opt_list *po;
    +
    +	SLIST_FOREACH(po, &otab, o_next) {
    +		if (eq(po->o_name, this)) {
    +			free(po->o_file);
    +			po->o_file = val;
    +			po->o_flags = flags;
    +			return;
    +		}
    +	}
    +	printf("Compat option %s not listed in options file.\n", this);
    +	exit(1);
    +}
    +
     static int
     read_option_file(const char *fname, int flags)
     {
    @@ -355,8 +372,10 @@ read_option_file(const char *fname, int flags)
     			free(s);
     		}
     		val = ns(val);
    -		check_duplicate(fname, this);
    -		insert_option(this, val, flags);
    +		if (flags == 0)
    +			insert_option(fname, this, val);
    +		else
    +			update_option(this, val, flags);
     	}
     	(void)fclose(fp);
     	return (1);
    
    From f459061b4c9666f15177b4a70ba9870d87bf679b Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Sun, 2 May 2010 06:20:42 +0000
    Subject: [PATCH 2161/2592] Move to the new way of specifying compat options. 
     The backs out the FOO = BAR form, in favor of listing the mapping in a
     separate file for more compatibility with older versions of config.
    
    ---
     sys/amd64/conf/GENERIC  | 3 ++-
     sys/conf/Makefile.amd64 | 2 +-
     sys/conf/Makefile.ia64  | 2 +-
     sys/conf/options.amd64  | 2 +-
     sys/conf/options.ia64   | 2 +-
     5 files changed, 6 insertions(+), 5 deletions(-)
    
    diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
    index 999ccb7b1ad..7288fefd74a 100644
    --- a/sys/amd64/conf/GENERIC
    +++ b/sys/amd64/conf/GENERIC
    @@ -54,7 +54,8 @@ options 	PSEUDOFS		# Pseudo-filesystem framework
     options 	GEOM_PART_GPT		# GUID Partition Tables.
     options 	GEOM_LABEL		# Provides labelization
     options 	COMPAT_43TTY		# BSD 4.3 TTY compat (sgtty)
    -options 	COMPAT_FREEBSD32	# Compatible with i386 binaries
    +#options 	COMPAT_FREEBSD32	# Compatible with i386 binaries
    +options 	COMPAT_IA32	# Compatible with i386 binaries
     options 	COMPAT_FREEBSD4		# Compatible with FreeBSD4
     options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
     options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
    diff --git a/sys/conf/Makefile.amd64 b/sys/conf/Makefile.amd64
    index 6fe45445d82..0e64860eb7a 100644
    --- a/sys/conf/Makefile.amd64
    +++ b/sys/conf/Makefile.amd64
    @@ -18,7 +18,7 @@
     #
     
     # Which version of config(8) is required.
    -%VERSREQ=	600004
    +%VERSREQ=	600009
     
     STD8X16FONT?=	iso
     
    diff --git a/sys/conf/Makefile.ia64 b/sys/conf/Makefile.ia64
    index f736866f14e..c79dfb9fb0f 100644
    --- a/sys/conf/Makefile.ia64
    +++ b/sys/conf/Makefile.ia64
    @@ -17,7 +17,7 @@
     #
     
     # Which version of config(8) is required.
    -%VERSREQ=	600004
    +%VERSREQ=	600008
     
     STD8X16FONT?=	iso
     
    diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64
    index 4f501f61cf6..54ae09546a5 100644
    --- a/sys/conf/options.amd64
    +++ b/sys/conf/options.amd64
    @@ -11,7 +11,7 @@ MP_WATCHDOG
     # Options for emulators.  These should only be used at config time, so
     # they are handled like options for static filesystems
     # (see src/sys/conf/options), except for broken debugging options.
    -COMPAT_IA32		= COMPAT_FREEBSD32
    +COMPAT_IA32		opt_dontuse.h
     COMPAT_FREEBSD32	opt_compat.h
     #IBCS2			opt_dontuse.h
     #COMPAT_LINUX		opt_dontuse.h
    diff --git a/sys/conf/options.ia64 b/sys/conf/options.ia64
    index cc70feb7c7a..4722c621781 100644
    --- a/sys/conf/options.ia64
    +++ b/sys/conf/options.ia64
    @@ -9,7 +9,7 @@ LOG2_PAGE_SIZE		opt_global.h
     
     UWX_TRACE_ENABLE	opt_global.h
     
    -COMPAT_IA32		= COMPAT_FREEBSD32
    +COMPAT_IA32		opt_dontuse.h
     COMPAT_FREEBSD32	opt_compat.h
     
     EXCEPTION_TRACING	opt_xtrace.h
    
    From f2c78def8208dd4b1896504ba210686cbaf157be Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Sun, 2 May 2010 06:23:15 +0000
    Subject: [PATCH 2162/2592] Ooops.  Bump the version to 600009, not 600008.
    
    ---
     sys/conf/Makefile.ia64 | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/conf/Makefile.ia64 b/sys/conf/Makefile.ia64
    index c79dfb9fb0f..3159f1c1a67 100644
    --- a/sys/conf/Makefile.ia64
    +++ b/sys/conf/Makefile.ia64
    @@ -17,7 +17,7 @@
     #
     
     # Which version of config(8) is required.
    -%VERSREQ=	600008
    +%VERSREQ=	600009
     
     STD8X16FONT?=	iso
     
    
    From 16a79e54bcfd163c6fd6f18f7efc07f82d076363 Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Sun, 2 May 2010 06:24:17 +0000
    Subject: [PATCH 2163/2592] Revert 207494: it was only for testing purposes.
    
    ---
     sys/amd64/conf/GENERIC | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
    index 7288fefd74a..999ccb7b1ad 100644
    --- a/sys/amd64/conf/GENERIC
    +++ b/sys/amd64/conf/GENERIC
    @@ -54,8 +54,7 @@ options 	PSEUDOFS		# Pseudo-filesystem framework
     options 	GEOM_PART_GPT		# GUID Partition Tables.
     options 	GEOM_LABEL		# Provides labelization
     options 	COMPAT_43TTY		# BSD 4.3 TTY compat (sgtty)
    -#options 	COMPAT_FREEBSD32	# Compatible with i386 binaries
    -options 	COMPAT_IA32	# Compatible with i386 binaries
    +options 	COMPAT_FREEBSD32	# Compatible with i386 binaries
     options 	COMPAT_FREEBSD4		# Compatible with FreeBSD4
     options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
     options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
    
    From c4a95f87a9e920990b23da4b0f7e09946dd83e6e Mon Sep 17 00:00:00 2001
    From: Warner Losh 
    Date: Sun, 2 May 2010 06:34:13 +0000
    Subject: [PATCH 2164/2592] Comment on new config version that's now required
     for amd64 and ia64. Comment on the confusing error message from Apr 17th-May
     2nd generated by config(8) as well.
    
    ---
     UPDATING | 17 +++++++++++++++++
     1 file changed, 17 insertions(+)
    
    diff --git a/UPDATING b/UPDATING
    index 2bd2b6f63d0..f108c93617d 100644
    --- a/UPDATING
    +++ b/UPDATING
    @@ -15,6 +15,17 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
     	debugging tools present in HEAD were left in place because
     	sun4v support still needs work to become production ready.
     
    +20100502:
    +	The config(8) command has been updated to maintain compatibility
    +	with config files from 8.0-RELEASE.  You will need a new version
    +	of config to build kernels (this version can be used from 8.0-RELEASE
    +	forward).  The buildworld target will generate it, so following
    +	the instructions in this file for updating will work glitch-free.
    +	Merely doing a make buildkernel without first doing a make buildworld
    +	(or kernel-toolchain), or attempting to build a kernel using
    +	traidtional methods will generate a config version warning, indicating
    +	you should update.
    +
     20100408:
     	The rc.firewall and rc.firewall6 were unified, and
     	rc.firewall6 and rc.d/ip6fw were removed.
    @@ -28,6 +39,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
     
     	The meanings correspond to the relevant IPv4 variables.
     
    +20100417:
    +	COMPAT_IA32 has been added as an alias for COMPAT_FREEBDS32.  A new
    +	version of config(8) is required.  The error message when you hit this
    +	condition is confusing (COMPAT_FREEBSD32 duplicate option), when it
    +	should really say "your config is too old to compile this new kernel."
    +
     20100406:
     	The kernel option COMPAT_IA32 has been replaced with COMPAT_FREEBSD32
     	to allow 32-bit compatibility on non-x86 platforms. All kernel
    
    From 03da203042834c809419a511d71a9a8070107a53 Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sun, 2 May 2010 12:38:59 +0000
    Subject: [PATCH 2165/2592] MFC r207187: kvm(3): Mention that some of the
     functions use sysctl(3) instead of kmem.
    
    Additionally, because of sysctl(3) use (which is generally good), behaviour
    for crash dumps differs slightly from behaviour for live kernels and this
    will probably never be fixed entirely, so weaken that claim.
    ---
     lib/libkvm/kvm.3 | 8 ++++++--
     1 file changed, 6 insertions(+), 2 deletions(-)
    
    diff --git a/lib/libkvm/kvm.3 b/lib/libkvm/kvm.3
    index f694fd80073..9dcd772d7e2 100644
    --- a/lib/libkvm/kvm.3
    +++ b/lib/libkvm/kvm.3
    @@ -32,7 +32,7 @@
     .\"     @(#)kvm.3	8.1 (Berkeley) 6/4/93
     .\" $FreeBSD$
     .\"
    -.Dd January 29, 2004
    +.Dd April 25, 2010
     .Dt KVM 3
     .Os
     .Sh NAME
    @@ -46,12 +46,15 @@ The
     library provides a uniform interface for accessing kernel virtual memory
     images, including live systems and crash dumps.
     Access to live systems is via
    +.Xr sysctl 3
    +for some functions, and
     .Xr mem 4
     and
     .Xr kmem 4
    +for other functions,
     while crash dumps can be examined via the core file generated by
     .Xr savecore 8 .
    -The interface behaves identically in both cases.
    +The interface behaves similarly in both cases.
     Memory can be read and written, kernel symbol addresses can be
     looked up efficiently, and information about user processes can
     be gathered.
    @@ -112,5 +115,6 @@ given descriptor.
     .Xr kvm_openfiles 3 ,
     .Xr kvm_read 3 ,
     .Xr kvm_write 3 ,
    +.Xr sysctl 3 ,
     .Xr kmem 4 ,
     .Xr mem 4
    
    From 20151ecd2e5c4e06898226823a10ff48c737bafa Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Sun, 2 May 2010 12:39:29 +0000
    Subject: [PATCH 2166/2592] MFC r206604: For early ALI chips do not announce
     I/O sizes that require unsupported 48bit DMA commands.
    
    ---
     sys/dev/ata/chipsets/ata-acerlabs.c | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c
    index b7f11472da2..fee9692ebd5 100644
    --- a/sys/dev/ata/chipsets/ata-acerlabs.c
    +++ b/sys/dev/ata/chipsets/ata-acerlabs.c
    @@ -184,8 +184,11 @@ ata_ali_ch_attach(device_t dev)
         if (ctlr->chip->cfg2 & ALI_NEW && ctlr->chip->chiprev < 0xc7)
     	ch->flags |= ATA_CHECKS_CABLE;
         /* older chips can't do 48bit DMA transfers */
    -    if (ctlr->chip->chiprev <= 0xc4)
    +    if (ctlr->chip->chiprev <= 0xc4) {
     	ch->flags |= ATA_NO_48BIT_DMA;
    +	if (ch->dma.max_iosize > 256 * 512)
    +		ch->dma.max_iosize = 256 * 512;
    +    }
     
         return 0;
     }
    
    From dd6a14926931795f88f87fab6f8cb61b39d103de Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Sun, 2 May 2010 12:40:54 +0000
    Subject: [PATCH 2167/2592] MFC r207221: Mark ATA channel as idle on timeout in
     non-ATA_CAM mode. This should fix possible duplicate request completion.
    
    ---
     sys/dev/ata/ata-queue.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
    index a3b1c4e4435..4aef47190cb 100644
    --- a/sys/dev/ata/ata-queue.c
    +++ b/sys/dev/ata/ata-queue.c
    @@ -513,9 +513,9 @@ ata_timeout(struct ata_request *request)
     	request->flags |= ATA_R_TIMEOUT;
     	if (ch->dma.unload)
     	    ch->dma.unload(request);
    -#ifdef ATA_CAM
     	ch->running = NULL;
     	ch->state = ATA_IDLE;
    +#ifdef ATA_CAM
     	ata_cam_end_transaction(ch->dev, request);
     #endif
     	mtx_unlock(&ch->state_mtx);
    
    From e96d10e414a7642358c74a9821e7f6d38945c03f Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sun, 2 May 2010 12:43:18 +0000
    Subject: [PATCH 2168/2592] MFC r207188: symlink(7): The ownership of symlinks
     is used by the system, in at least three ways, so do not say it is ignored: *
     who may delete/rename a symlink in a sticky directory * who may do
     lchflags(2)/lchown(2)/lchmod(2) * whose inode quota is charged
    
    ---
     bin/ln/symlink.7 | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/bin/ln/symlink.7 b/bin/ln/symlink.7
    index d2e8cbb25e4..93bb27bef15 100644
    --- a/bin/ln/symlink.7
    +++ b/bin/ln/symlink.7
    @@ -29,7 +29,7 @@
     .\"	@(#)symlink.7	8.3 (Berkeley) 3/31/94
     .\" $FreeBSD$
     .\"
    -.Dd March 31, 1994
    +.Dd April 25, 2010
     .Dt SYMLINK 7
     .Os
     .Sh NAME
    @@ -138,8 +138,8 @@ an existing symbolic link can be changed by means of the
     and
     .Xr lutimes 2
     system calls, respectively.
    -Of these, only the flags are used by the system;
    -the access permissions and ownership are ignored.
    +Of these, only the flags and ownership are used by the system;
    +the access permissions are ignored.
     .Pp
     The
     .Bx 4.4
    
    From f40596ef9c050da0592b889e37b5a7f322b40712 Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Sun, 2 May 2010 12:44:11 +0000
    Subject: [PATCH 2169/2592] MFC r205358: Enable MSI by default for SiI3124.
    
    ---
     sys/dev/siis/siis.c | 13 +++++++------
     1 file changed, 7 insertions(+), 6 deletions(-)
    
    diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
    index 29afa2a4052..f03fba98027 100644
    --- a/sys/dev/siis/siis.c
    +++ b/sys/dev/siis/siis.c
    @@ -94,14 +94,15 @@ static struct {
     	int		ports;
     	int		quirks;
     #define SIIS_Q_SNTF	1
    +#define SIIS_Q_NOMSI	2
     } siis_ids[] = {
     	{0x31241095,	"SiI3124",	4,	0},
     	{0x31248086,	"SiI3124",	4,	0},
    -	{0x31321095,	"SiI3132",	2,	SIIS_Q_SNTF},
    -	{0x02421095,	"SiI3132",	2,	SIIS_Q_SNTF},
    -	{0x02441095,	"SiI3132",	2,	SIIS_Q_SNTF},
    -	{0x31311095,	"SiI3131",	1,	SIIS_Q_SNTF},
    -	{0x35311095,	"SiI3531",	1,	SIIS_Q_SNTF},
    +	{0x31321095,	"SiI3132",	2,	SIIS_Q_SNTF|SIIS_Q_NOMSI},
    +	{0x02421095,	"SiI3132",	2,	SIIS_Q_SNTF|SIIS_Q_NOMSI},
    +	{0x02441095,	"SiI3132",	2,	SIIS_Q_SNTF|SIIS_Q_NOMSI},
    +	{0x31311095,	"SiI3131",	1,	SIIS_Q_SNTF|SIIS_Q_NOMSI},
    +	{0x35311095,	"SiI3531",	1,	SIIS_Q_SNTF|SIIS_Q_NOMSI},
     	{0,		NULL,		0,	0}
     };
     
    @@ -249,7 +250,7 @@ static int
     siis_setup_interrupt(device_t dev)
     {
     	struct siis_controller *ctlr = device_get_softc(dev);
    -	int msi = 0;
    +	int msi = ctlr->quirks & SIIS_Q_NOMSI ? 0 : 1;
     
     	/* Process hints. */
     	resource_int_value(device_get_name(dev),
    
    From 9171d4b73651b468fed1b27a29a20242a3de242a Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Sun, 2 May 2010 12:45:22 +0000
    Subject: [PATCH 2170/2592] MFC r206652: Explicitly enable PCI busmastering on
     attach. Now SiI3124 with siis(4) successfully works on sparc64 (SunBlade
     100).
    
    ---
     sys/dev/siis/siis.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
    index f03fba98027..c9c157226fa 100644
    --- a/sys/dev/siis/siis.c
    +++ b/sys/dev/siis/siis.c
    @@ -164,6 +164,7 @@ siis_attach(device_t dev)
     		rman_fini(&ctlr->sc_iomem);
     		return (error);
     	}
    +	pci_enable_busmaster(dev);
     	/* Reset controller */
     	siis_resume(dev);
     	/* Number of HW channels */
    
    From 467965c62910c6f743147c6862bf9d289034e312 Mon Sep 17 00:00:00 2001
    From: Alexander Motin 
    Date: Sun, 2 May 2010 12:50:29 +0000
    Subject: [PATCH 2171/2592] MFC r207222: Move PI_TAG_ABLE check from ada driver
     to ATA XPT.
    
    ---
     sys/cam/ata/ata_da.c  |  4 ----
     sys/cam/ata/ata_xpt.c | 29 +++++++++++++++++++----------
     2 files changed, 19 insertions(+), 14 deletions(-)
    
    diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
    index 6cb4f2e5509..6eff691de90 100644
    --- a/sys/cam/ata/ata_da.c
    +++ b/sys/cam/ata/ata_da.c
    @@ -686,14 +686,10 @@ adaregister(struct cam_periph *periph, void *arg)
     	else
     		softc->quirks = ADA_Q_NONE;
     
    -	/* Check if the SIM does not want queued commands */
     	bzero(&cpi, sizeof(cpi));
     	xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE);
     	cpi.ccb_h.func_code = XPT_PATH_INQ;
     	xpt_action((union ccb *)&cpi);
    -	if (cpi.ccb_h.status != CAM_REQ_CMP ||
    -	    (cpi.hba_inquiry & PI_TAG_ABLE) == 0)
    -		softc->flags &= ~ADA_FLAG_CAN_NCQ;
     
     	TASK_INIT(&softc->sysctl_task, 0, adasysctlinit, periph);
     
    diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
    index d5e0b32a49b..3bf9c1ef1df 100644
    --- a/sys/cam/ata/ata_xpt.c
    +++ b/sys/cam/ata/ata_xpt.c
    @@ -766,6 +766,7 @@ noerror:
     	}
     	case PROBE_IDENTIFY:
     	{
    +		struct ccb_pathinq cpi;
     		int16_t *ptr;
     
     		ident_buf = &softc->ident_data;
    @@ -840,16 +841,24 @@ noerror:
     		ata_find_quirk(path->device);
     		if (path->device->mintags != 0 &&
     		    path->bus->sim->max_tagged_dev_openings != 0) {
    -			/* Report SIM which tags are allowed. */
    -			bzero(&cts, sizeof(cts));
    -			xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
    -			cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
    -			cts.type = CTS_TYPE_CURRENT_SETTINGS;
    -			cts.xport_specific.sata.tags = path->device->maxtags;
    -			cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS;
    -			xpt_action((union ccb *)&cts);
    -			/* Reconfigure queues for tagged queueing. */
    -			xpt_start_tags(path);
    +			/* Check if the SIM does not want queued commands. */
    +			bzero(&cpi, sizeof(cpi));
    +			xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE);
    +			cpi.ccb_h.func_code = XPT_PATH_INQ;
    +			xpt_action((union ccb *)&cpi);
    +			if (cpi.ccb_h.status == CAM_REQ_CMP &&
    +			    (cpi.hba_inquiry & PI_TAG_ABLE)) {
    +				/* Report SIM which tags are allowed. */
    +				bzero(&cts, sizeof(cts));
    +				xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
    +				cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
    +				cts.type = CTS_TYPE_CURRENT_SETTINGS;
    +				cts.xport_specific.sata.tags = path->device->maxtags;
    +				cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS;
    +				xpt_action((union ccb *)&cts);
    +				/* Reconfigure queues for tagged queueing. */
    +				xpt_start_tags(path);
    +			}
     		}
     		ata_device_transport(path);
     		PROBE_SET_ACTION(softc, PROBE_SETMODE);
    
    From f4eb99be9772db1ea2a28b3e6827f2af7870830b Mon Sep 17 00:00:00 2001
    From: Jilles Tjoelker 
    Date: Sun, 2 May 2010 13:36:23 +0000
    Subject: [PATCH 2172/2592] MFC r207189: symlink(7): Add lpathconf(2) and *at
     system calls.
    
    ---
     bin/ln/symlink.7 | 29 +++++++++++++++++++++++++++--
     1 file changed, 27 insertions(+), 2 deletions(-)
    
    diff --git a/bin/ln/symlink.7 b/bin/ln/symlink.7
    index 93bb27bef15..8c09f281a51 100644
    --- a/bin/ln/symlink.7
    +++ b/bin/ln/symlink.7
    @@ -103,19 +103,23 @@ the system call
     would return a file descriptor to the file
     .Dq afile .
     .Pp
    -There are nine system calls that do not follow links, and which operate
    +There are thirteen system calls that do not follow links, and which operate
     on the symbolic link itself.
     They are:
     .Xr lchflags 2 ,
     .Xr lchmod 2 ,
     .Xr lchown 2 ,
    +.Xr lpathconf 2 ,
     .Xr lstat 2 ,
     .Xr lutimes 2 ,
     .Xr readlink 2 ,
    +.Xr readlinkat 2 ,
     .Xr rename 2 ,
    +.Xr renameat 2 ,
     .Xr rmdir 2 ,
    +.Xr unlink 2 ,
     and
    -.Xr unlink 2 .
    +.Xr unlinkat 2 .
     Because
     .Xr remove 3
     is an alias for
    @@ -123,9 +127,30 @@ is an alias for
     it also does not follow symbolic links.
     When
     .Xr rmdir 2
    +or
    +.Xr unlinkat 2
    +with the
    +.Dv AT_REMOVEDIR
    +flag
     is applied to a symbolic link, it fails with the error
     .Er ENOTDIR .
     .Pp
    +The
    +.Xr linkat 2
    +system call does not follow symbolic links
    +unless given the
    +.Dv AT_SYMLINK_FOLLOW
    +flag.
    +.Pp
    +The following system calls follow symbolic links
    +unless given the
    +.Dv AT_SYMLINK_NOFOLLOW
    +flag:
    +.Xr fchmodat 2 ,
    +.Xr fchownat 2
    +and
    +.Xr fstatat 2 .
    +.Pp
     The owner and group of an existing symbolic link can be changed by
     means of the
     .Xr lchown 2
    
    From 8b5076c9df86d64e5ef3de3197c4003fbeb96d4f Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sun, 2 May 2010 15:55:29 +0000
    Subject: [PATCH 2173/2592] MFC r206989:   Avoid memory access after free.  Use
     the (shortend) copy for the   ipsec mtu lookup as well.
    
    PR:		kern/145736
    Submitted by:	Peter Molnar (peter molnar.cc)
    ---
     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 8be51fb992d..fdef6457b3e 100644
    --- a/sys/netinet/ip_input.c
    +++ b/sys/netinet/ip_input.c
    @@ -1590,7 +1590,7 @@ ip_forward(struct mbuf *m, int srcrt)
     		 * If IPsec is configured for this path,
     		 * override any possibly mtu value set by ip_output.
     		 */ 
    -		mtu = ip_ipsec_mtu(m, mtu);
    +		mtu = ip_ipsec_mtu(mcopy, mtu);
     #endif /* IPSEC */
     		/*
     		 * If the MTU was set before make sure we are below the
    
    From bca61398fdccf8c1c877e73ab360dd40a69e955b Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sun, 2 May 2010 15:58:25 +0000
    Subject: [PATCH 2174/2592] MFC r207116:   Remove one zero from the double-0.  
     This code doesn't have a license to kill.
    
    ---
     sys/kern/kern_descrip.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
    index 676de650524..302ca5eeaf4 100644
    --- a/sys/kern/kern_descrip.c
    +++ b/sys/kern/kern_descrip.c
    @@ -2896,7 +2896,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
     				free(sa, M_SONAME);
     			}
     			if (so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa)
    -			    == 00 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
    +			    == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
     				bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
     				free(sa, M_SONAME);
     			}
    @@ -3149,7 +3149,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS)
     				free(sa, M_SONAME);
     			}
     			if (so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa)
    -			    == 00 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
    +			    == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
     				bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
     				free(sa, M_SONAME);
     			}
    
    From 6377d38081b3562ccbed7802e2a85e2ea3ba4fe2 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sun, 2 May 2010 16:32:41 +0000
    Subject: [PATCH 2175/2592] MFC r207276:   Make sure IPv6 source address
     selection does not change interface   addresses while walking the IPv6
     address list if in the jail case   something is connecting to ::1.
    
      Reported by:  Pieter de Boer (pieter thedarkside.nl)
      Tested by:    Pieter de Boer (pieter thedarkside.nl)
    ---
     sys/netinet6/in6_src.c | 25 ++++++++++++++++++++-----
     1 file changed, 20 insertions(+), 5 deletions(-)
    
    diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
    index ea302a52fa4..e6c2cd83726 100644
    --- a/sys/netinet6/in6_src.c
    +++ b/sys/netinet6/in6_src.c
    @@ -182,7 +182,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
         struct inpcb *inp, struct route_in6 *ro, struct ucred *cred,
         struct ifnet **ifpp, struct in6_addr *srcp)
     {
    -	struct in6_addr dst;
    +	struct in6_addr dst, tmp;
     	struct ifnet *ifp = NULL;
     	struct in6_ifaddr *ia = NULL, *ia_best = NULL;
     	struct in6_pktinfo *pi = NULL;
    @@ -326,10 +326,9 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
     		if (!V_ip6_use_deprecated && IFA6_IS_DEPRECATED(ia))
     			continue;
     
    +		/* If jailed only take addresses of the jail into account. */
     		if (cred != NULL &&
    -		    prison_local_ip6(cred, &ia->ia_addr.sin6_addr,
    -			(inp != NULL &&
    -			(inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
    +		    prison_check_ip6(cred, &ia->ia_addr.sin6_addr) != 0)
     			continue;
     
     		/* Rule 1: Prefer same address */
    @@ -476,10 +475,26 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
     		return (EADDRNOTAVAIL);
     	}
     
    +	/*
    +	 * At this point at least one of the addresses belonged to the jail
    +	 * but it could still be, that we want to further restrict it, e.g.
    +	 * theoratically IN6_IS_ADDR_LOOPBACK.
    +	 * It must not be IN6_IS_ADDR_UNSPECIFIED anymore.
    +	 * prison_local_ip6() will fix an IN6_IS_ADDR_LOOPBACK but should
    +	 * let all others previously selected pass.
    +	 * Use tmp to not change ::1 on lo0 to the primary jail address.
    +	 */
    +	tmp = ia->ia_addr.sin6_addr;
    +	if (cred != NULL && prison_local_ip6(cred, &tmp, (inp != NULL &&
    +	    (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) {
    +		IN6_IFADDR_RUNLOCK();
    +		return (EADDRNOTAVAIL);
    +	}
    +
     	if (ifpp)
     		*ifpp = ifp;
     
    -	bcopy(&ia->ia_addr.sin6_addr, srcp, sizeof(*srcp));
    +	bcopy(&tmp, srcp, sizeof(*srcp));
     	IN6_IFADDR_RUNLOCK();
     	return (0);
     }
    
    From 7f6b24dccfc3b306f6a2775dcd35e89123f3bc47 Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sun, 2 May 2010 16:36:15 +0000
    Subject: [PATCH 2176/2592] MFC r207277:   Enhance the historic behaviour of
     raw sockets and jails in a way   that we allow all possible jail IPs as
     source address rather than   forcing the "primary". While IPv6 naturally has
     source address   selection, for legacy IP we do not go through the pain in
     case   IP_HDRINCL was not set. People should bind(2) for that.
    
      This will, for example, allow ping(|6) -S to work correctly for
      non-primary addresses.
    
      Reported by:  (ten 211.ru)
      Tested by:    (ten 211.ru)
    ---
     sys/netinet/raw_ip.c   | 23 ++++++++++++++++++-----
     sys/netinet6/raw_ip6.c |  2 +-
     2 files changed, 19 insertions(+), 6 deletions(-)
    
    diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
    index 6b3ca8b6d19..52e923d79ba 100644
    --- a/sys/netinet/raw_ip.c
    +++ b/sys/netinet/raw_ip.c
    @@ -441,11 +441,24 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
     		ip->ip_p = inp->inp_ip_p;
     		ip->ip_len = m->m_pkthdr.len;
     		ip->ip_src = inp->inp_laddr;
    -		error = prison_get_ip4(inp->inp_cred, &ip->ip_src);
    -		if (error != 0) {
    -			INP_RUNLOCK(inp);
    -			m_freem(m);
    -			return (error);
    +		if (jailed(inp->inp_cred)) {
    +			/*
    +			 * prison_local_ip4() would be good enough but would
    +			 * let a source of INADDR_ANY pass, which we do not
    +			 * want to see from jails. We do not go through the
    +			 * pain of in_pcbladdr() for raw sockets.
    +			 */
    +			if (ip->ip_src.s_addr == INADDR_ANY)
    +				error = prison_get_ip4(inp->inp_cred,
    +				    &ip->ip_src);
    +			else
    +				error = prison_local_ip4(inp->inp_cred,
    +				    &ip->ip_src);
    +			if (error != 0) {
    +				INP_RUNLOCK(inp);
    +				m_freem(m);
    +				return (error);
    +			}
     		}
     		ip->ip_dst.s_addr = dst;
     		ip->ip_ttl = inp->inp_ip_ttl;
    diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
    index 9f1236ab1bd..6052b24e470 100644
    --- a/sys/netinet6/raw_ip6.c
    +++ b/sys/netinet6/raw_ip6.c
    @@ -465,7 +465,7 @@ rip6_output(m, va_alist)
     	    &oifp, &in6a);
     	if (error)
     		goto bad;
    -	error = prison_get_ip6(in6p->inp_cred, &in6a);
    +	error = prison_check_ip6(in6p->inp_cred, &in6a);
     	if (error != 0)
     		goto bad;
     	ip6->ip6_src = in6a;
    
    From 6419e07f19b2683e54a64ff53c986f4d4fc9847e Mon Sep 17 00:00:00 2001
    From: "Bjoern A. Zeeb" 
    Date: Sun, 2 May 2010 16:39:15 +0000
    Subject: [PATCH 2177/2592] MFC r207278:   MFP4: @177254
    
      Add missing CURVNET_RESTORE() calls for multiple code paths, to stop
      leaking the currently cached vnet into callers and to the process.
    
    Sponsored by: The FreeBSD Foundation
    Sponsored by: CK Software GmbH
    ---
     sys/net/bpf.c | 11 ++++++++---
     1 file changed, 8 insertions(+), 3 deletions(-)
    
    diff --git a/sys/net/bpf.c b/sys/net/bpf.c
    index 51bb1d03c37..b610e831a4f 100644
    --- a/sys/net/bpf.c
    +++ b/sys/net/bpf.c
    @@ -1328,6 +1328,7 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
     			/* FALLSTHROUGH */
     
     		default:
    +			CURVNET_RESTORE();
     			return (EINVAL);
     		}
     
    @@ -1335,6 +1336,7 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
     		if (d->bd_sbuf != NULL || d->bd_hbuf != NULL ||
     		    d->bd_fbuf != NULL || d->bd_bif != NULL) {
     			BPFD_UNLOCK(d);
    +			CURVNET_RESTORE();
     			return (EBUSY);
     		}
     		d->bd_bufmode = *(u_int *)addr;
    @@ -1342,13 +1344,16 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
     		break;
     
     	case BIOCGETZMAX:
    -		return (bpf_ioctl_getzmax(td, d, (size_t *)addr));
    +		error = bpf_ioctl_getzmax(td, d, (size_t *)addr);
    +		break;
     
     	case BIOCSETZBUF:
    -		return (bpf_ioctl_setzbuf(td, d, (struct bpf_zbuf *)addr));
    +		error = bpf_ioctl_setzbuf(td, d, (struct bpf_zbuf *)addr);
    +		break;
     
     	case BIOCROTZBUF:
    -		return (bpf_ioctl_rotzbuf(td, d, (struct bpf_zbuf *)addr));
    +		error = bpf_ioctl_rotzbuf(td, d, (struct bpf_zbuf *)addr);
    +		break;
     	}
     	CURVNET_RESTORE();
     	return (error);
    
    From 4d9e1e3e1f225451c39f8cd84a42cc225635cd5d Mon Sep 17 00:00:00 2001
    From: Marius Strobl 
    Date: Sun, 2 May 2010 16:40:18 +0000
    Subject: [PATCH 2178/2592] MFC: r206448
    
    Do as the comment suggests and determine the bus space based on the last
    bus we actually mapped at rather than always based on the last bus we
    encountered while moving upward in the tree. Otherwise we might use the
    wrong bus space in case the bridge directly underneath the nexus doesn't
    require mapping, i.e. was skipped as it's the case for ssm(4) nodes.
    ---
     sys/sparc64/sparc64/ofw_machdep.c | 13 +++++--------
     1 file changed, 5 insertions(+), 8 deletions(-)
    
    diff --git a/sys/sparc64/sparc64/ofw_machdep.c b/sys/sparc64/sparc64/ofw_machdep.c
    index 9d522629c78..07f95e20e51 100644
    --- a/sys/sparc64/sparc64/ofw_machdep.c
    +++ b/sys/sparc64/sparc64/ofw_machdep.c
    @@ -186,13 +186,10 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
     			name[sizeof(name) - 1] = '\0';
     			goto skip;
     		}
    -		if (lbus != bus) {
    -			if (OF_getprop(bus, "#size-cells", &szc,
    -			    sizeof(szc)) == -1)
    -				szc = 1;
    -			if (szc < 1 || szc > 2)
    -				return (ENXIO);
    -		}
    +		if (OF_getprop(bus, "#size-cells", &szc, sizeof(szc)) == -1)
    +			szc = 1;
    +		if (szc < 1 || szc > 2)
    +			return (ENXIO);
     		nbank /= sizeof(banks[0]) * (addrc + paddrc + szc);
     		bank = 0;
     		for (i = 0; i < nbank; i++) {
    @@ -232,9 +229,9 @@ OF_decode_addr(phandle_t node, int bank, int *space, bus_addr_t *addr)
     		}
     		if (i == nbank)
     			return (ENXIO);
    +		lbus = bus;
      skip:
     		addrc = paddrc;
    -		lbus = bus;
     		bus = pbus;
     	}
     
    
    From 2cf37e65a3f774b98a00faabbee451afa4f8a4dd Mon Sep 17 00:00:00 2001
    From: Marius Strobl 
    Date: Sun, 2 May 2010 16:45:08 +0000
    Subject: [PATCH 2179/2592] MFC: r206449
    
    Unlike the sun4v variant, the sun4u version of SUNW,set-trap-table
    actually only takes one argument.
    ---
     sys/sparc64/sparc64/trap.c | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
    index c451907f358..0976bb65013 100644
    --- a/sys/sparc64/sparc64/trap.c
    +++ b/sys/sparc64/sparc64/trap.c
    @@ -260,7 +260,8 @@ sun4u_set_traptable(void *tba_addr)
     		cell_t tba_addr;
     	} args = {
     		(cell_t)"SUNW,set-trap-table",
    -		2,
    +		1,
    +		0,
     	};
     
     	args.tba_addr = (cell_t)tba_addr;
    
    From 9582607bb593b06e81e970e7b571d041f61399c8 Mon Sep 17 00:00:00 2001
    From: Marius Strobl 
    Date: Sun, 2 May 2010 16:46:20 +0000
    Subject: [PATCH 2180/2592] MFC: r206450
    
    Correct the DCR_IPE macro to refer to the right bit. Also improve the
    associated comment as besides US-IV+ these bits are only available with
    US-III++, i.e. the 1.2GHz version of the US-III+.
    ---
     sys/sparc64/include/dcr.h | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/sys/sparc64/include/dcr.h b/sys/sparc64/include/dcr.h
    index b1f993a0609..42159adc9c1 100644
    --- a/sys/sparc64/include/dcr.h
    +++ b/sys/sparc64/include/dcr.h
    @@ -43,8 +43,8 @@
     #define	DCR_OBSDATA_CT_MASK						\
     	(((1UL << DCR_OBSDATA_CT_BITS) - 1) << DCR_OBSDATA_SHIFT)
     
    -/* The following bits are valid for the UltraSPARC-III+/IV+ only. */
    -#define	DCR_IPE			(1UL << 5)
    +/* The following bits are valid for the UltraSPARC-III++/IV+ only. */
    +#define	DCR_IPE			(1UL << 2)
     
     #define	DCR_OBSDATA_CTP_BITS	6
     #define	DCR_OBSDATA_CTP_MASK						\
    
    From 951139bba84ac7e09c7a0402b9fdd42ee451c46c Mon Sep 17 00:00:00 2001
    From: Marius Strobl 
    Date: Sun, 2 May 2010 16:47:50 +0000
    Subject: [PATCH 2181/2592] MFC: r206480
    
    Update for UltraSPARC-IV{,+} and SPARC64 V, VI, VII and VIIIfx CPUs.
    ---
     sys/sparc64/include/lsu.h | 22 ++++++++++++++++++++--
     1 file changed, 20 insertions(+), 2 deletions(-)
    
    diff --git a/sys/sparc64/include/lsu.h b/sys/sparc64/include/lsu.h
    index a8787dcabdc..5eeaa5566fc 100644
    --- a/sys/sparc64/include/lsu.h
    +++ b/sys/sparc64/include/lsu.h
    @@ -29,7 +29,7 @@
     
     /*
      * Definitions for the Load-Store-Unit Control Register. This is called
    - * Data Cache Unit Control Register (DCUCR) for UltraSPARC-III.
    + * Data Cache Unit Control Register (DCUCR) for UltraSPARC-III and greater.
      */
     #define	LSU_IC		(1UL << 0)
     #define	LSU_DC		(1UL << 1)
    @@ -41,7 +41,7 @@
     #define	LSU_FM_BITS	16
     #define	LSU_FM_MASK	(((1UL << LSU_FM_BITS) - 1) << LSU_FM_SHIFT)
     
    -#define LSU_VM_SHIFT	25
    +#define	LSU_VM_SHIFT	25
     #define	LSU_VM_BITS	8
     #define	LSU_VM_MASK	(((1UL << LSU_VM_BITS) - 1) << LSU_VM_SHIFT)
     
    @@ -65,4 +65,22 @@
     #define	LSU_CV		(1UL << 48)
     #define	LSU_CP		(1UL << 49)
     
    +/* The following bit is valid for the UltraSPARC-IV only. */
    +#define	LSU_WIH		(1UL << 4)
    +
    +/* The following bits are valid for the UltraSPARC-IV+ only. */
    +#define	LSU_PPS_SHIFT	50
    +#define	LSU_PPS_BITS	2
    +#define	LSU_PPS_MASK	(((1UL << LSU_PPS_BITS) - 1) << LSU_PPS_SHIFT)
    +
    +#define	LSU_IPS_SHIFT	52
    +#define	LSU_IPS_BITS	2
    +#define	LSU_IPS_MASK	(((1UL << LSU_IPS_BITS) - 1) << LSU_IPS_SHIFT)
    +
    +#define	LSU_PCM		(1UL << 54)
    +#define	LSU_WCE		(1UL << 55)
    +
    +/* The following bit is valid for the SPARC64 V, VI, VII and VIIIfx only. */
    +#define	LSU_WEAK_SPCA	(1UL << 41)
    +
     #endif	/* _MACHINE_LSU_H_ */
    
    From 4ee47351874eba392dce7609ecca952cfd41e869 Mon Sep 17 00:00:00 2001
    From: Marius Strobl 
    Date: Sun, 2 May 2010 16:52:23 +0000
    Subject: [PATCH 2182/2592] MFC: r206490, r206492
    
    While SPARC V9 allows tininess to be detected either before or after
    rounding (impl. dep. #55), the SPARC JPS1 responsible for SPARC64 and
    UltraSPARC processors defines that in all cases tininess is detected
    before rounding therefore rounding up to the smallest normalized number
    should set the underflow flag. This change is needed for using SoftFloat
    on sparc64 for reference purposes.
    
    PR:		144900
    Submitted by:	Peter Jeremy
    ---
     lib/libc/softfloat/softfloat-specialize | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/lib/libc/softfloat/softfloat-specialize b/lib/libc/softfloat/softfloat-specialize
    index c8c8028d652..e8585cea7f5 100644
    --- a/lib/libc/softfloat/softfloat-specialize
    +++ b/lib/libc/softfloat/softfloat-specialize
    @@ -44,7 +44,11 @@ Underflow tininess-detection mode, statically initialized to default value.
     #ifdef SOFTFLOAT_FOR_GCC
     static
     #endif
    +#ifdef __sparc64__
    +int8 float_detect_tininess = float_tininess_before_rounding;
    +#else
     int8 float_detect_tininess = float_tininess_after_rounding;
    +#endif
     
     /*
     -------------------------------------------------------------------------------
    
    From 1f21f64ac27d77cab4e38e6ee81be926b7b1bfd1 Mon Sep 17 00:00:00 2001
    From: Marius Strobl 
    Date: Sun, 2 May 2010 16:55:10 +0000
    Subject: [PATCH 2183/2592] MFC: r207151
    
    Add a TestFloat based test suite for floating-point implementations
    currently supporting sparc64. After a `make depend all` there are
    three programs; testsoftfloat for testing against the SoftFloat in
    src/lib/libc/softfloat for reference purposes, testemufloat for
    testing the emulator source in src/lib/libc/sparc64/fpu and testfloat
    for testing with the installed libc. Support for other architectures
    can be added as needed.
    
    PR:		144900
    Submitted by:	Peter Jeremy
    ---
     tools/test/README                           |    1 +
     tools/test/testfloat/README.txt             |   50 +
     tools/test/testfloat/fail.c                 |   46 +
     tools/test/testfloat/fail.h                 |   29 +
     tools/test/testfloat/random.c               |   63 +
     tools/test/testfloat/random.h               |   32 +
     tools/test/testfloat/slowfloat-32.c         | 1183 ++++++
     tools/test/testfloat/slowfloat-64.c         | 2109 +++++++++++
     tools/test/testfloat/slowfloat.c            |   35 +
     tools/test/testfloat/slowfloat.h            |  167 +
     tools/test/testfloat/sparc64/Makefile       |  105 +
     tools/test/testfloat/sparc64/fpu_emul.S     |  186 +
     tools/test/testfloat/sparc64/fpu_reg.h      |   63 +
     tools/test/testfloat/sparc64/fpu_util.c     |  706 ++++
     tools/test/testfloat/sparc64/libc_private.h |   30 +
     tools/test/testfloat/sparc64/milieu.h       |   56 +
     tools/test/testfloat/sparc64/namespace.h    |   30 +
     tools/test/testfloat/sparc64/softfloat.h    |  267 ++
     tools/test/testfloat/sparc64/sparc64.h      |   93 +
     tools/test/testfloat/sparc64/systflags.c    |   73 +
     tools/test/testfloat/sparc64/systfloat.S    | 1120 ++++++
     tools/test/testfloat/sparc64/systfloat.h    |  216 ++
     tools/test/testfloat/sparc64/systmodes.c    |   54 +
     tools/test/testfloat/sparc64/un-namespace.h |   30 +
     tools/test/testfloat/systemBugs.txt         |  323 ++
     tools/test/testfloat/systflags.h            |   33 +
     tools/test/testfloat/systfloat.c            |  553 +++
     tools/test/testfloat/systmodes.h            |   42 +
     tools/test/testfloat/testCases.c            | 3682 +++++++++++++++++++
     tools/test/testfloat/testCases.h            |   69 +
     tools/test/testfloat/testFunction.c         | 1149 ++++++
     tools/test/testfloat/testFunction.h         |  135 +
     tools/test/testfloat/testLoops.c            | 2713 ++++++++++++++
     tools/test/testfloat/testLoops.h            |  143 +
     tools/test/testfloat/testfloat-history.txt  |   57 +
     tools/test/testfloat/testfloat-source.txt   |  444 +++
     tools/test/testfloat/testfloat.c            |  299 ++
     tools/test/testfloat/testfloat.txt          |  771 ++++
     tools/test/testfloat/testsoftfloat.c        | 1044 ++++++
     tools/test/testfloat/writeHex.c             |  183 +
     tools/test/testfloat/writeHex.h             |   42 +
     41 files changed, 18426 insertions(+)
     create mode 100644 tools/test/testfloat/README.txt
     create mode 100644 tools/test/testfloat/fail.c
     create mode 100644 tools/test/testfloat/fail.h
     create mode 100644 tools/test/testfloat/random.c
     create mode 100644 tools/test/testfloat/random.h
     create mode 100644 tools/test/testfloat/slowfloat-32.c
     create mode 100644 tools/test/testfloat/slowfloat-64.c
     create mode 100644 tools/test/testfloat/slowfloat.c
     create mode 100644 tools/test/testfloat/slowfloat.h
     create mode 100644 tools/test/testfloat/sparc64/Makefile
     create mode 100644 tools/test/testfloat/sparc64/fpu_emul.S
     create mode 100644 tools/test/testfloat/sparc64/fpu_reg.h
     create mode 100644 tools/test/testfloat/sparc64/fpu_util.c
     create mode 100644 tools/test/testfloat/sparc64/libc_private.h
     create mode 100644 tools/test/testfloat/sparc64/milieu.h
     create mode 100644 tools/test/testfloat/sparc64/namespace.h
     create mode 100644 tools/test/testfloat/sparc64/softfloat.h
     create mode 100644 tools/test/testfloat/sparc64/sparc64.h
     create mode 100644 tools/test/testfloat/sparc64/systflags.c
     create mode 100644 tools/test/testfloat/sparc64/systfloat.S
     create mode 100644 tools/test/testfloat/sparc64/systfloat.h
     create mode 100644 tools/test/testfloat/sparc64/systmodes.c
     create mode 100644 tools/test/testfloat/sparc64/un-namespace.h
     create mode 100644 tools/test/testfloat/systemBugs.txt
     create mode 100644 tools/test/testfloat/systflags.h
     create mode 100644 tools/test/testfloat/systfloat.c
     create mode 100644 tools/test/testfloat/systmodes.h
     create mode 100644 tools/test/testfloat/testCases.c
     create mode 100644 tools/test/testfloat/testCases.h
     create mode 100644 tools/test/testfloat/testFunction.c
     create mode 100644 tools/test/testfloat/testFunction.h
     create mode 100644 tools/test/testfloat/testLoops.c
     create mode 100644 tools/test/testfloat/testLoops.h
     create mode 100644 tools/test/testfloat/testfloat-history.txt
     create mode 100644 tools/test/testfloat/testfloat-source.txt
     create mode 100644 tools/test/testfloat/testfloat.c
     create mode 100644 tools/test/testfloat/testfloat.txt
     create mode 100644 tools/test/testfloat/testsoftfloat.c
     create mode 100644 tools/test/testfloat/writeHex.c
     create mode 100644 tools/test/testfloat/writeHex.h
    
    diff --git a/tools/test/README b/tools/test/README
    index f16e215c7f6..438c1f5170d 100644
    --- a/tools/test/README
    +++ b/tools/test/README
    @@ -11,3 +11,4 @@ devrandom	Programs to test /dev/*random.
     dtrace		DTrace test suite
     malloc		A program to test and benchmark malloc().
     posixshm	A program to test POSIX shared memory.
    +testfloat	Programs to test floating-point implementations
    diff --git a/tools/test/testfloat/README.txt b/tools/test/testfloat/README.txt
    new file mode 100644
    index 00000000000..fe99fd95d64
    --- /dev/null
    +++ b/tools/test/testfloat/README.txt
    @@ -0,0 +1,50 @@
    +
    +Package Overview for TestFloat Release 2a
    +
    +John R. Hauser
    +1998 December 16
    +
    +
    +TestFloat is a program for testing that a floating-point implementation
    +conforms to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
    +TestFloat is distributed in the form of C source code.  The TestFloat
    +package actually provides two related programs:
    +
    +-- The `testfloat' program tests a system's floating-point for conformance
    +   to the IEC/IEEE Standard.  This program uses the SoftFloat software
    +   floating-point implementation as a basis for comparison.
    +
    +-- The `testsoftfloat' program tests SoftFloat itself for conformance to
    +   the IEC/IEEE Standard.  These tests are performed by comparing against a
    +   separate, slower software floating-point that is included in the TestFloat
    +   package.
    +
    +TestFloat depends on SoftFloat, but SoftFloat is not included in the
    +TestFloat package.  SoftFloat can be obtained through the Web page `http://
    +HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'.
    +
    +TestFloat is documented in three text files:
    +
    +   testfloat.txt          Documentation for using the TestFloat programs
    +                              (both `testfloat' and `testsoftfloat').
    +   testfloat-source.txt   Documentation for porting and compiling TestFloat.
    +   testfloat-history.txt  History of major changes to TestFloat.
    +
    +The following file is also provided:
    +
    +   systemBugs.txt         Information about processor bugs found using
    +                              TestFloat.
    +
    +Other files in the package comprise the source code for TestFloat.
    +
    +Please be aware that some work is involved in porting this software to other
    +targets.  It is not just a matter of getting `make' to complete without
    +error messages.  I would have written the code that way if I could, but
    +there are fundamental differences between systems that I can't make go away.
    +You should not attempt to compile the TestFloat sources without first
    +reading `testfloat-source.txt'.
    +
    +At the time of this writing, the most up-to-date information about
    +TestFloat and the latest release can be found at the Web page `http://
    +HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    diff --git a/tools/test/testfloat/fail.c b/tools/test/testfloat/fail.c
    new file mode 100644
    index 00000000000..30bbea6bd7d
    --- /dev/null
    +++ b/tools/test/testfloat/fail.c
    @@ -0,0 +1,46 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +#include 
    +#include 
    +#include "milieu.h"
    +#include "fail.h"
    +
    +char *fail_programName = "";
    +
    +void fail( const char *message, ... )
    +{
    +    va_list varArgs;
    +
    +    fprintf( stderr, "%s: ", fail_programName );
    +    va_start( varArgs, message );
    +    vfprintf( stderr, message, varArgs );
    +    va_end( varArgs );
    +    fputs( ".\n", stderr );
    +    exit( EXIT_FAILURE );
    +
    +}
    +
    diff --git a/tools/test/testfloat/fail.h b/tools/test/testfloat/fail.h
    new file mode 100644
    index 00000000000..9c338da260a
    --- /dev/null
    +++ b/tools/test/testfloat/fail.h
    @@ -0,0 +1,29 @@
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +extern char *fail_programName;
    +
    +void fail( const char *, ... );
    +
    diff --git a/tools/test/testfloat/random.c b/tools/test/testfloat/random.c
    new file mode 100644
    index 00000000000..21326c1ff23
    --- /dev/null
    +++ b/tools/test/testfloat/random.c
    @@ -0,0 +1,63 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include 
    +#include "milieu.h"
    +#include "random.h"
    +
    +uint8 randomUint8( void )
    +{
    +
    +    return (bits8) ( random()>>4 );
    +
    +}
    +
    +uint16 randomUint16( void )
    +{
    +
    +    return ( random() & 0x0000ffff );
    +
    +}
    +
    +uint32 randomUint32( void )
    +{
    +
    +    return ( ( (uint32) random()<<16) | ( (uint32) random() & 0x0000ffff) );
    +}
    +
    +#ifdef BITS64
    +
    +uint64 randomUint64( void )
    +{
    +
    +    return ( ( (uint64) randomUint32() )<<32 ) | randomUint32();
    +
    +}
    +
    +#endif
    +
    diff --git a/tools/test/testfloat/random.h b/tools/test/testfloat/random.h
    new file mode 100644
    index 00000000000..7375499ea96
    --- /dev/null
    +++ b/tools/test/testfloat/random.h
    @@ -0,0 +1,32 @@
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +uint8 randomUint8( void );
    +uint16 randomUint16( void );
    +uint32 randomUint32( void );
    +#ifdef BITS64
    +uint64 randomUint64( void );
    +#endif
    +
    diff --git a/tools/test/testfloat/slowfloat-32.c b/tools/test/testfloat/slowfloat-32.c
    new file mode 100644
    index 00000000000..549654b05e6
    --- /dev/null
    +++ b/tools/test/testfloat/slowfloat-32.c
    @@ -0,0 +1,1183 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +int8 slow_float_rounding_mode;
    +int8 slow_float_exception_flags;
    +int8 slow_float_detect_tininess;
    +
    +typedef struct {
    +    bits32 a0, a1;
    +} bits64X;
    +
    +typedef struct {
    +    flag isNaN;
    +    flag isInf;
    +    flag isZero;
    +    flag sign;
    +    int16 exp;
    +    bits64X sig;
    +} floatX;
    +
    +static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
    +static const floatX floatXPositiveZero =
    +    { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
    +static const floatX floatXNegativeZero =
    +    { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
    +
    +static bits64X shortShift64Left( bits64X a, int8 shiftCount )
    +{
    +    int8 negShiftCount;
    +
    +    negShiftCount = ( - shiftCount & 31 );
    +    a.a0 = ( a.a0<>negShiftCount );
    +    a.a1 <<= shiftCount;
    +    return a;
    +
    +}
    +
    +static bits64X shortShift64RightJamming( bits64X a, int8 shiftCount )
    +{
    +    int8 negShiftCount;
    +    bits32 extra;
    +
    +    negShiftCount = ( - shiftCount & 31 );
    +    extra = a.a1<>shiftCount ) | ( extra != 0 );
    +    a.a0 >>= shiftCount;
    +    return a;
    +
    +}
    +
    +static bits64X neg64( bits64X a )
    +{
    +
    +    if ( a.a1 == 0 ) {
    +        a.a0 = - a.a0;
    +    }
    +    else {
    +        a.a1 = - a.a1;
    +        a.a0 = ~ a.a0;
    +    }
    +    return a;
    +
    +}
    +
    +static bits64X add64( bits64X a, bits64X b )
    +{
    +
    +    a.a1 += b.a1;
    +    a.a0 += b.a0 + ( a.a1 < b.a1 );
    +    return a;
    +
    +}
    +
    +static flag eq64( bits64X a, bits64X b )
    +{
    +
    +    return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
    +
    +}
    +
    +static flag le64( bits64X a, bits64X b )
    +{
    +
    +    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
    +
    +}
    +
    +static flag lt64( bits64X a, bits64X b )
    +{
    +
    +    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
    +
    +}
    +
    +static floatX roundFloatXTo24( flag isTiny, floatX zx )
    +{
    +
    +    if ( zx.sig.a1 ) {
    +        slow_float_exception_flags |= float_flag_inexact;
    +        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
    +        switch ( slow_float_rounding_mode ) {
    +         case float_round_nearest_even:
    +            if ( zx.sig.a1 < 0x80000000 ) goto noIncrement;
    +            if ( ( zx.sig.a1 == 0x80000000 ) && ! ( zx.sig.a0 & 1 ) ) {
    +                goto noIncrement;
    +            }
    +            break;
    +         case float_round_to_zero:
    +            goto noIncrement;
    +         case float_round_down:
    +            if ( ! zx.sign ) goto noIncrement;
    +            break;
    +         case float_round_up:
    +            if ( zx.sign ) goto noIncrement;
    +            break;
    +        }
    +        ++zx.sig.a0;
    +        if ( zx.sig.a0 == 0x01000000 ) {
    +            zx.sig.a0 = 0x00800000;
    +            ++zx.exp;
    +        }
    +    }
    + noIncrement:
    +    zx.sig.a1 = 0;
    +    return zx;
    +
    +}
    +
    +static floatX roundFloatXTo53( flag isTiny, floatX zx )
    +{
    +    int8 roundBits;
    +
    +    roundBits = zx.sig.a1 & 7;
    +    zx.sig.a1 -= roundBits;
    +    if ( roundBits ) {
    +        slow_float_exception_flags |= float_flag_inexact;
    +        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
    +        switch ( slow_float_rounding_mode ) {
    +         case float_round_nearest_even:
    +            if ( roundBits < 4 ) goto noIncrement;
    +            if ( ( roundBits == 4 ) && ! ( zx.sig.a1 & 8 ) ) goto noIncrement;
    +            break;
    +         case float_round_to_zero:
    +            goto noIncrement;
    +         case float_round_down:
    +            if ( ! zx.sign ) goto noIncrement;
    +            break;
    +         case float_round_up:
    +            if ( zx.sign ) goto noIncrement;
    +            break;
    +        }
    +        zx.sig.a1 += 8;
    +        zx.sig.a0 += ( zx.sig.a1 == 0 );
    +        if ( zx.sig.a0 == 0x01000000 ) {
    +            zx.sig.a0 = 0x00800000;
    +            ++zx.exp;
    +        }
    +    }
    + noIncrement:
    +    return zx;
    +
    +}
    +
    +static floatX int32ToFloatX( int32 a )
    +{
    +    floatX ax;
    +
    +    ax.isNaN = FALSE;
    +    ax.isInf = FALSE;
    +    ax.sign = ( a < 0 );
    +    ax.sig.a1 = ax.sign ? - a : a;
    +    ax.sig.a0 = 0;
    +    if ( a == 0 ) {
    +        ax.isZero = TRUE;
    +        return ax;
    +    }
    +    ax.isZero = FALSE;
    +    ax.sig = shortShift64Left( ax.sig, 23 );
    +    ax.exp = 32;
    +    while ( ax.sig.a0 < 0x00800000 ) {
    +        ax.sig = shortShift64Left( ax.sig, 1 );
    +        --ax.exp;
    +    }
    +    return ax;
    +
    +}
    +
    +static int32 floatXToInt32( floatX ax )
    +{
    +    int8 savedExceptionFlags;
    +    int16 shiftCount;
    +    int32 z;
    +
    +    if ( ax.isInf || ax.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +        return ( ax.isInf & ax.sign ) ? 0x80000000 : 0x7FFFFFFF;
    +    }
    +    if ( ax.isZero ) return 0;
    +    savedExceptionFlags = slow_float_exception_flags;
    +    shiftCount = 52 - ax.exp;
    +    if ( 56 < shiftCount ) {
    +        ax.sig.a1 = 1;
    +        ax.sig.a0 = 0;
    +    }
    +    else {
    +        while ( 0 < shiftCount ) {
    +            ax.sig = shortShift64RightJamming( ax.sig, 1 );
    +            --shiftCount;
    +        }
    +    }
    +    ax = roundFloatXTo53( FALSE, ax );
    +    ax.sig = shortShift64RightJamming( ax.sig, 3 );
    +    z = ax.sig.a1;
    +    if ( ax.sign ) z = - z;
    +    if (    ( shiftCount < 0 )
    +         || ax.sig.a0
    +         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
    +       ) {
    +        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
    +        return ax.sign ? 0x80000000 : 0x7FFFFFFF;
    +    }
    +    return z;
    +
    +}
    +
    +static floatX float32ToFloatX( float32 a )
    +{
    +    int16 expField;
    +    floatX ax;
    +
    +    ax.isNaN = FALSE;
    +    ax.isInf = FALSE;
    +    ax.isZero = FALSE;
    +    ax.sign = ( ( a & 0x80000000 ) != 0 );
    +    expField = ( a>>23 ) & 0xFF;
    +    ax.sig.a1 = 0;
    +    ax.sig.a0 = a & 0x007FFFFF;
    +    if ( expField == 0 ) {
    +        if ( ax.sig.a0 == 0 ) {
    +            ax.isZero = TRUE;
    +        }
    +        else {
    +            expField = 1 - 0x7F;
    +            do {
    +                ax.sig.a0 <<= 1;
    +                --expField;
    +            } while ( ax.sig.a0 < 0x00800000 );
    +            ax.exp = expField;
    +        }
    +    }
    +    else if ( expField == 0xFF ) {
    +        if ( ax.sig.a0 == 0 ) {
    +            ax.isInf = TRUE;
    +        }
    +        else {
    +            ax.isNaN = TRUE;
    +        }
    +    }
    +    else {
    +        ax.sig.a0 |= 0x00800000;
    +        ax.exp = expField - 0x7F;
    +    }
    +    return ax;
    +
    +}
    +
    +static float32 floatXToFloat32( floatX zx )
    +{
    +    floatX savedZ;
    +    flag isTiny;
    +    int16 expField;
    +    float32 z;
    +
    +    if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
    +    if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
    +    if ( zx.isNaN ) return 0xFFFFFFFF;
    +    while ( 0x01000000 <= zx.sig.a0 ) {
    +        zx.sig = shortShift64RightJamming( zx.sig, 1 );
    +        ++zx.exp;
    +    }
    +    while ( zx.sig.a0 < 0x00800000 ) {
    +        zx.sig = shortShift64Left( zx.sig, 1 );
    +        --zx.exp;
    +    }
    +    savedZ = zx;
    +    isTiny =
    +           ( slow_float_detect_tininess == float_tininess_before_rounding )
    +        && ( zx.exp + 0x7F <= 0 );
    +    zx = roundFloatXTo24( isTiny, zx );
    +    expField = zx.exp + 0x7F;
    +    if ( 0xFF <= expField ) {
    +        slow_float_exception_flags |=
    +            float_flag_overflow | float_flag_inexact;
    +        if ( zx.sign ) {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_down:
    +                z = 0xFF800000;
    +                break;
    +             case float_round_to_zero:
    +             case float_round_up:
    +                z = 0xFF7FFFFF;
    +                break;
    +            }
    +        }
    +        else {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_up:
    +                z = 0x7F800000;
    +                break;
    +             case float_round_to_zero:
    +             case float_round_down:
    +                z = 0x7F7FFFFF;
    +                break;
    +            }
    +        }
    +        return z;
    +    }
    +    if ( expField <= 0 ) {
    +        isTiny = TRUE;
    +        zx = savedZ;
    +        expField = zx.exp + 0x7F;
    +        if ( expField < -27 ) {
    +            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( expField <= 0 ) {
    +                zx.sig = shortShift64RightJamming( zx.sig, 1 );
    +                ++expField;
    +            }
    +        }
    +        zx = roundFloatXTo24( isTiny, zx );
    +        expField = ( 0x00800000 <= zx.sig.a0 ) ? 1 : 0;
    +    }
    +    z = expField;
    +    z <<= 23;
    +    if ( zx.sign ) z |= 0x80000000;
    +    z |= zx.sig.a0 & 0x007FFFFF;
    +    return z;
    +
    +}
    +
    +static floatX float64ToFloatX( float64 a )
    +{
    +    int16 expField;
    +    floatX ax;
    +
    +    ax.isNaN = FALSE;
    +    ax.isInf = FALSE;
    +    ax.isZero = FALSE;
    +#ifdef BITS64
    +    ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
    +    expField = ( a>>52 ) & 0x7FF;
    +    ax.sig.a1 = a;
    +    ax.sig.a0 = ( a>>32 ) & 0x000FFFFF;
    +#else
    +    ax.sign = ( ( a.high & 0x80000000 ) != 0 );
    +    expField = ( a.high>>( 52 - 32 ) ) & 0x7FF;
    +    ax.sig.a1 = a.low;
    +    ax.sig.a0 = a.high & 0x000FFFFF;
    +#endif
    +    if ( expField == 0 ) {
    +        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
    +            ax.isZero = TRUE;
    +        }
    +        else {
    +            expField = 1 - 0x3FF;
    +            do {
    +                ax.sig = shortShift64Left( ax.sig, 1 );
    +                --expField;
    +            } while ( ax.sig.a0 < 0x00100000 );
    +            ax.exp = expField;
    +        }
    +    }
    +    else if ( expField == 0x7FF ) {
    +        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
    +            ax.isInf = TRUE;
    +        }
    +        else {
    +            ax.isNaN = TRUE;
    +        }
    +    }
    +    else {
    +        ax.exp = expField - 0x3FF;
    +        ax.sig.a0 |= 0x00100000;
    +    }
    +    ax.sig = shortShift64Left( ax.sig, 3 );
    +    return ax;
    +
    +}
    +
    +static float64 floatXToFloat64( floatX zx )
    +{
    +    floatX savedZ;
    +    flag isTiny;
    +    int16 expField;
    +    float64 z;
    +
    +#ifdef BITS64
    +    if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
    +    if ( zx.isInf ) {
    +        return
    +              zx.sign ? LIT64( 0xFFF0000000000000 )
    +            : LIT64( 0x7FF0000000000000 );
    +    }
    +    if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
    +#else
    +    if ( zx.isZero ) {
    +        z.low = 0;
    +        z.high = zx.sign ? 0x80000000 : 0;
    +        return z;
    +    }
    +    if ( zx.isInf ) {
    +        z.low = 0;
    +        z.high = zx.sign ? 0xFFF00000 : 0x7FF00000;
    +        return z;
    +    }
    +    if ( zx.isNaN ) {
    +        z.high = z.low = 0xFFFFFFFF;
    +        return z;
    +    }
    +#endif
    +    while ( 0x01000000 <= zx.sig.a0 ) {
    +        zx.sig = shortShift64RightJamming( zx.sig, 1 );
    +        ++zx.exp;
    +    }
    +    while ( zx.sig.a0 < 0x00800000 ) {
    +        zx.sig = shortShift64Left( zx.sig, 1 );
    +        --zx.exp;
    +    }
    +    savedZ = zx;
    +    isTiny =
    +           ( slow_float_detect_tininess == float_tininess_before_rounding )
    +        && ( zx.exp + 0x3FF <= 0 );
    +    zx = roundFloatXTo53( isTiny, zx );
    +    expField = zx.exp + 0x3FF;
    +    if ( 0x7FF <= expField ) {
    +        slow_float_exception_flags |=
    +            float_flag_overflow | float_flag_inexact;
    +#ifdef BITS64
    +        if ( zx.sign ) {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_down:
    +                z = LIT64( 0xFFF0000000000000 );
    +                break;
    +             case float_round_to_zero:
    +             case float_round_up:
    +                z = LIT64( 0xFFEFFFFFFFFFFFFF );
    +                break;
    +            }
    +        }
    +        else {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_up:
    +                z = LIT64( 0x7FF0000000000000 );
    +                break;
    +             case float_round_to_zero:
    +             case float_round_down:
    +                z = LIT64( 0x7FEFFFFFFFFFFFFF );
    +                break;
    +            }
    +        }
    +#else
    +        if ( zx.sign ) {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_down:
    +                z.low = 0;
    +                z.high = 0xFFF00000;
    +                break;
    +             case float_round_to_zero:
    +             case float_round_up:
    +                z.low = 0xFFFFFFFF;
    +                z.high = 0xFFEFFFFF;
    +                break;
    +            }
    +        }
    +        else {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_up:
    +                z.low = 0;
    +                z.high = 0x7FF00000;
    +                break;
    +             case float_round_to_zero:
    +             case float_round_down:
    +                z.low = 0xFFFFFFFF;
    +                z.high = 0x7FEFFFFF;
    +                break;
    +            }
    +        }
    +#endif
    +        return z;
    +    }
    +    if ( expField <= 0 ) {
    +        isTiny = TRUE;
    +        zx = savedZ;
    +        expField = zx.exp + 0x3FF;
    +        if ( expField < -56 ) {
    +            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( expField <= 0 ) {
    +                zx.sig = shortShift64RightJamming( zx.sig, 1 );
    +                ++expField;
    +            }
    +        }
    +        zx = roundFloatXTo53( isTiny, zx );
    +        expField = ( 0x00800000 <= zx.sig.a0 ) ? 1 : 0;
    +    }
    +    zx.sig = shortShift64RightJamming( zx.sig, 3 );
    +#ifdef BITS64
    +    z = expField;
    +    z <<= 52;
    +    if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
    +    z |= ( ( (bits64) ( zx.sig.a0 & 0x000FFFFF ) )<<32 ) | zx.sig.a1;
    +#else
    +    z.low = zx.sig.a1;
    +    z.high = expField;
    +    z.high <<= 52 - 32;
    +    if ( zx.sign ) z.high |= 0x80000000;
    +    z.high |= zx.sig.a0 & 0x000FFFFF;
    +#endif
    +    return z;
    +
    +}
    +
    +static floatX floatXInvalid( void )
    +{
    +
    +    slow_float_exception_flags |= float_flag_invalid;
    +    return floatXNaN;
    +
    +}
    +
    +static floatX floatXRoundToInt( floatX ax )
    +{
    +    int16 shiftCount, i;
    +
    +    if ( ax.isNaN || ax.isInf ) return ax;
    +    shiftCount = 52 - ax.exp;
    +    if ( shiftCount <= 0 ) return ax;
    +    if ( 55 < shiftCount ) {
    +        ax.exp = 52;
    +        ax.sig.a1 = ! ax.isZero;
    +        ax.sig.a0 = 0;
    +    }
    +    else {
    +        while ( 0 < shiftCount ) {
    +            ax.sig = shortShift64RightJamming( ax.sig, 1 );
    +            ++ax.exp;
    +            --shiftCount;
    +        }
    +    }
    +    ax = roundFloatXTo53( FALSE, ax );
    +    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
    +    return ax;
    +
    +}
    +
    +static floatX floatXAdd( floatX ax, floatX bx )
    +{
    +    int16 expDiff;
    +    floatX zx;
    +
    +    if ( ax.isNaN ) return ax;
    +    if ( bx.isNaN ) return bx;
    +    if ( ax.isInf && bx.isInf ) {
    +        if ( ax.sign == bx.sign ) return ax;
    +        return floatXInvalid();
    +    }
    +    if ( ax.isInf ) return ax;
    +    if ( bx.isInf ) return bx;
    +    if ( ax.isZero && bx.isZero ) {
    +        if ( ax.sign == bx.sign ) return ax;
    +        goto completeCancellation;
    +    }
    +    if (    ( ax.sign != bx.sign )
    +         && ( ax.exp == bx.exp )
    +         && eq64( ax.sig, bx.sig )
    +       ) {
    + completeCancellation:
    +        return
    +              ( slow_float_rounding_mode == float_round_down ) ?
    +                  floatXNegativeZero
    +            : floatXPositiveZero;
    +    }
    +    if ( ax.isZero ) return bx;
    +    if ( bx.isZero ) return ax;
    +    expDiff = ax.exp - bx.exp;
    +    if ( expDiff < 0 ) {
    +        zx = ax;
    +        zx.exp = bx.exp;
    +        if ( expDiff < -56 ) {
    +            zx.sig.a1 = 1;
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( expDiff < 0 ) {
    +                zx.sig = shortShift64RightJamming( zx.sig, 1 );
    +                ++expDiff;
    +            }
    +        }
    +        if ( ax.sign != bx.sign ) zx.sig = neg64( zx.sig );
    +        zx.sign = bx.sign;
    +        zx.sig = add64( zx.sig, bx.sig );
    +    }
    +    else {
    +        zx = bx;
    +        zx.exp = ax.exp;
    +        if ( 56 < expDiff ) {
    +            zx.sig.a1 = 1;
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( 0 < expDiff ) {
    +                zx.sig = shortShift64RightJamming( zx.sig, 1 );
    +                --expDiff;
    +            }
    +        }
    +        if ( ax.sign != bx.sign ) zx.sig = neg64( zx.sig );
    +        zx.sign = ax.sign;
    +        zx.sig = add64( zx.sig, ax.sig );
    +    }
    +    if ( zx.sig.a0 & 0x80000000 ) {
    +        zx.sig = neg64( zx.sig );
    +        zx.sign = ! zx.sign;
    +    }
    +    return zx;
    +
    +}
    +
    +static floatX floatXMul( floatX ax, floatX bx )
    +{
    +    int8 bitNum;
    +    floatX zx;
    +
    +    if ( ax.isNaN ) return ax;
    +    if ( bx.isNaN ) return bx;
    +    if ( ax.isInf ) {
    +        if ( bx.isZero ) return floatXInvalid();
    +        if ( bx.sign ) ax.sign = ! ax.sign;
    +        return ax;
    +    }
    +    if ( bx.isInf ) {
    +        if ( ax.isZero ) return floatXInvalid();
    +        if ( ax.sign ) bx.sign = ! bx.sign;
    +        return bx;
    +    }
    +    zx = ax;
    +    zx.sign ^= bx.sign;
    +    if ( ax.isZero || bx.isZero ) {
    +        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
    +    }
    +    zx.exp += bx.exp + 1;
    +    zx.sig.a1 = 0;
    +    zx.sig.a0 = 0;
    +    for ( bitNum = 0; bitNum < 55; ++bitNum ) {
    +        if ( bx.sig.a1 & 2 ) zx.sig = add64( zx.sig, ax.sig );
    +        bx.sig = shortShift64RightJamming( bx.sig, 1 );
    +        zx.sig = shortShift64RightJamming( zx.sig, 1 );
    +    }
    +    return zx;
    +
    +}
    +
    +static floatX floatXDiv( floatX ax, floatX bx )
    +{
    +    bits64X negBSig;
    +    int8 bitNum;
    +    floatX zx;
    +
    +    if ( ax.isNaN ) return ax;
    +    if ( bx.isNaN ) return bx;
    +    if ( ax.isInf ) {
    +        if ( bx.isInf ) return floatXInvalid();
    +        if ( bx.sign ) ax.sign = ! ax.sign;
    +        return ax;
    +    }
    +    if ( bx.isZero ) {
    +        if ( ax.isZero ) return floatXInvalid();
    +        slow_float_exception_flags |= float_flag_divbyzero;
    +        if ( ax.sign ) bx.sign = ! bx.sign;
    +        bx.isZero = FALSE;
    +        bx.isInf = TRUE;
    +        return bx;
    +    }
    +    zx = ax;
    +    zx.sign ^= bx.sign;
    +    if ( ax.isZero || bx.isInf ) {
    +        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
    +    }
    +    zx.exp -= bx.exp + 1;
    +    zx.sig.a1 = 0;
    +    zx.sig.a0 = 0;
    +    negBSig = neg64( bx.sig );
    +    for ( bitNum = 0; bitNum < 56; ++bitNum ) {
    +        if ( le64( bx.sig, ax.sig ) ) {
    +            zx.sig.a1 |= 1;
    +            ax.sig = add64( ax.sig, negBSig );
    +        }
    +        ax.sig = shortShift64Left( ax.sig, 1 );
    +        zx.sig = shortShift64Left( zx.sig, 1 );
    +    }
    +    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
    +    return zx;
    +
    +}
    +
    +static floatX floatXRem( floatX ax, floatX bx )
    +{
    +    bits64X negBSig;
    +    flag lastQuotientBit;
    +    bits64X savedASig;
    +
    +    if ( ax.isNaN ) return ax;
    +    if ( bx.isNaN ) return bx;
    +    if ( ax.isInf || bx.isZero ) return floatXInvalid();
    +    if ( ax.isZero || bx.isInf ) return ax;
    +    --bx.exp;
    +    if ( ax.exp < bx.exp ) return ax;
    +    bx.sig = shortShift64Left( bx.sig, 1 );
    +    negBSig = neg64( bx.sig );
    +    while ( bx.exp < ax.exp ) {
    +        if ( le64( bx.sig, ax.sig ) ) ax.sig = add64( ax.sig, negBSig );
    +        ax.sig = shortShift64Left( ax.sig, 1 );
    +        --ax.exp;
    +    }
    +    lastQuotientBit = le64( bx.sig, ax.sig );
    +    if ( lastQuotientBit ) ax.sig = add64( ax.sig, negBSig );
    +    savedASig = ax.sig;
    +    ax.sig = neg64( add64( ax.sig, negBSig ) );
    +    if ( lt64( ax.sig, savedASig ) ) {
    +        ax.sign = ! ax.sign;
    +    }
    +    else if ( lt64( savedASig, ax.sig ) ) {
    +        ax.sig = savedASig;
    +    }
    +    else {
    +        if ( lastQuotientBit ) {
    +            ax.sign = ! ax.sign;
    +        }
    +        else {
    +            ax.sig = savedASig;
    +        }
    +    }
    +    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
    +    return ax;
    +
    +}
    +
    +static floatX floatXSqrt( floatX ax )
    +{
    +    int8 bitNum;
    +    bits64X bitSig, savedASig;
    +    floatX zx;
    +
    +    if ( ax.isNaN || ax.isZero ) return ax;
    +    if ( ax.sign ) return floatXInvalid();
    +    if ( ax.isInf ) return ax;
    +    zx = ax;
    +    zx.exp >>= 1;
    +    if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift64RightJamming( ax.sig, 1 );
    +    zx.sig.a1 = 0;
    +    zx.sig.a0 = 0;
    +    bitSig.a1 = 0;
    +    bitSig.a0 = 0x00800000;
    +    for ( bitNum = 0; bitNum < 56; ++bitNum ) {
    +        savedASig = ax.sig;
    +        ax.sig = add64( ax.sig, neg64( zx.sig ) );
    +        ax.sig = shortShift64Left( ax.sig, 1 );
    +        ax.sig = add64( ax.sig, neg64( bitSig ) );
    +        if ( ax.sig.a0 & 0x80000000 ) {
    +            ax.sig = shortShift64Left( savedASig, 1 );
    +        }
    +        else {
    +            zx.sig.a1 |= bitSig.a1;
    +            zx.sig.a0 |= bitSig.a0;
    +        }
    +        bitSig = shortShift64RightJamming( bitSig, 1 );
    +    }
    +    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
    +    return zx;
    +
    +}
    +
    +static flag floatXEq( floatX ax, floatX bx )
    +{
    +
    +    if ( ax.isNaN || bx.isNaN ) return FALSE;
    +    if ( ax.isZero && bx.isZero ) return TRUE;
    +    if ( ax.sign != bx.sign ) return FALSE;
    +    if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
    +    return ( ax.exp == bx.exp ) && eq64( ax.sig, bx.sig );
    +
    +}
    +
    +static flag floatXLe( floatX ax, floatX bx )
    +{
    +
    +    if ( ax.isNaN || bx.isNaN ) return FALSE;
    +    if ( ax.isZero && bx.isZero ) return TRUE;
    +    if ( ax.sign != bx.sign ) return ax.sign;
    +    if ( ax.sign ) {
    +        if ( ax.isInf || bx.isZero ) return TRUE;
    +        if ( bx.isInf || ax.isZero ) return FALSE;
    +        if ( bx.exp < ax.exp ) return TRUE;
    +        if ( ax.exp < bx.exp ) return FALSE;
    +        return le64( bx.sig, ax.sig );
    +    }
    +    else {
    +        if ( bx.isInf || ax.isZero ) return TRUE;
    +        if ( ax.isInf || bx.isZero ) return FALSE;
    +        if ( ax.exp < bx.exp ) return TRUE;
    +        if ( bx.exp < ax.exp ) return FALSE;
    +        return le64( ax.sig, bx.sig );
    +    }
    +
    +}
    +
    +static flag floatXLt( floatX ax, floatX bx )
    +{
    +
    +    if ( ax.isNaN || bx.isNaN ) return FALSE;
    +    if ( ax.isZero && bx.isZero ) return FALSE;
    +    if ( ax.sign != bx.sign ) return ax.sign;
    +    if ( ax.isInf && bx.isInf ) return FALSE;
    +    if ( ax.sign ) {
    +        if ( ax.isInf || bx.isZero ) return TRUE;
    +        if ( bx.isInf || ax.isZero ) return FALSE;
    +        if ( bx.exp < ax.exp ) return TRUE;
    +        if ( ax.exp < bx.exp ) return FALSE;
    +        return lt64( bx.sig, ax.sig );
    +    }
    +    else {
    +        if ( bx.isInf || ax.isZero ) return TRUE;
    +        if ( ax.isInf || bx.isZero ) return FALSE;
    +        if ( ax.exp < bx.exp ) return TRUE;
    +        if ( bx.exp < ax.exp ) return FALSE;
    +        return lt64( ax.sig, bx.sig );
    +    }
    +
    +}
    +
    +float32 slow_int32_to_float32( int32 a )
    +{
    +
    +    return floatXToFloat32( int32ToFloatX( a ) );
    +
    +}
    +
    +float64 slow_int32_to_float64( int32 a )
    +{
    +
    +    return floatXToFloat64( int32ToFloatX( a ) );
    +
    +}
    +
    +int32 slow_float32_to_int32( float32 a )
    +{
    +
    +    return floatXToInt32( float32ToFloatX( a ) );
    +
    +}
    +
    +int32 slow_float32_to_int32_round_to_zero( float32 a )
    +{
    +    int8 savedRoundingMode;
    +    int32 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt32( float32ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +float64 slow_float32_to_float64( float32 a )
    +{
    +
    +    return floatXToFloat64( float32ToFloatX( a ) );
    +
    +}
    +
    +float32 slow_float32_round_to_int( float32 a )
    +{
    +
    +    return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
    +
    +}
    +
    +float32 slow_float32_add( float32 a, float32 b )
    +{
    +
    +    return
    +        floatXToFloat32(
    +            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_sub( float32 a, float32 b )
    +{
    +
    +    b ^= 0x80000000;
    +    return
    +        floatXToFloat32(
    +            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_mul( float32 a, float32 b )
    +{
    +
    +    return
    +        floatXToFloat32(
    +            floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_div( float32 a, float32 b )
    +{
    +
    +    return
    +        floatXToFloat32(
    +            floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_rem( float32 a, float32 b )
    +{
    +
    +    return
    +        floatXToFloat32(
    +            floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_sqrt( float32 a )
    +{
    +
    +    return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
    +
    +}
    +
    +flag slow_float32_eq( float32 a, float32 b )
    +{
    +
    +    return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float32_le( float32 a, float32 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float32ToFloatX( a );
    +    bx = float32ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLe( ax, bx );
    +
    +}
    +
    +flag slow_float32_lt( float32 a, float32 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float32ToFloatX( a );
    +    bx = float32ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLt( ax, bx );
    +
    +}
    +
    +flag slow_float32_eq_signaling( float32 a, float32 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float32ToFloatX( a );
    +    bx = float32ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXEq( ax, bx );
    +
    +}
    +
    +flag slow_float32_le_quiet( float32 a, float32 b )
    +{
    +
    +    return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float32_lt_quiet( float32 a, float32 b )
    +{
    +
    +    return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
    +
    +}
    +
    +int32 slow_float64_to_int32( float64 a )
    +{
    +
    +    return floatXToInt32( float64ToFloatX( a ) );
    +
    +}
    +
    +int32 slow_float64_to_int32_round_to_zero( float64 a )
    +{
    +    int8 savedRoundingMode;
    +    int32 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt32( float64ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +float32 slow_float64_to_float32( float64 a )
    +{
    +
    +    return floatXToFloat32( float64ToFloatX( a ) );
    +
    +}
    +
    +float64 slow_float64_round_to_int( float64 a )
    +{
    +
    +    return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
    +
    +}
    +
    +float64 slow_float64_add( float64 a, float64 b )
    +{
    +
    +    return
    +        floatXToFloat64(
    +            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_sub( float64 a, float64 b )
    +{
    +
    +#ifdef BITS64
    +    b ^= LIT64( 0x8000000000000000 );
    +#else
    +    b.high ^= 0x80000000;
    +#endif
    +    return
    +        floatXToFloat64(
    +            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_mul( float64 a, float64 b )
    +{
    +
    +    return
    +        floatXToFloat64(
    +            floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_div( float64 a, float64 b )
    +{
    +
    +    return
    +        floatXToFloat64(
    +            floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_rem( float64 a, float64 b )
    +{
    +
    +    return
    +        floatXToFloat64(
    +            floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_sqrt( float64 a )
    +{
    +
    +    return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
    +
    +}
    +
    +flag slow_float64_eq( float64 a, float64 b )
    +{
    +
    +    return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float64_le( float64 a, float64 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float64ToFloatX( a );
    +    bx = float64ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLe( ax, bx );
    +
    +}
    +
    +flag slow_float64_lt( float64 a, float64 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float64ToFloatX( a );
    +    bx = float64ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLt( ax, bx );
    +
    +}
    +
    +flag slow_float64_eq_signaling( float64 a, float64 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float64ToFloatX( a );
    +    bx = float64ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXEq( ax, bx );
    +
    +}
    +
    +flag slow_float64_le_quiet( float64 a, float64 b )
    +{
    +
    +    return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float64_lt_quiet( float64 a, float64 b )
    +{
    +
    +    return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
    +
    +}
    +
    diff --git a/tools/test/testfloat/slowfloat-64.c b/tools/test/testfloat/slowfloat-64.c
    new file mode 100644
    index 00000000000..27e56e1152a
    --- /dev/null
    +++ b/tools/test/testfloat/slowfloat-64.c
    @@ -0,0 +1,2109 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +int8 slow_float_rounding_mode;
    +int8 slow_float_exception_flags;
    +int8 slow_float_detect_tininess;
    +#ifdef FLOATX80
    +int8 slow_floatx80_rounding_precision;
    +#endif
    +
    +typedef struct {
    +    bits64 a0, a1;
    +} bits128X;
    +
    +typedef struct {
    +    flag isNaN;
    +    flag isInf;
    +    flag isZero;
    +    flag sign;
    +    int32 exp;
    +    bits128X sig;
    +} floatX;
    +
    +static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
    +static const floatX floatXPositiveZero =
    +    { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
    +static const floatX floatXNegativeZero =
    +    { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
    +
    +static bits128X shortShift128Left( bits128X a, int8 shiftCount )
    +{
    +    int8 negShiftCount;
    +
    +    negShiftCount = ( - shiftCount & 63 );
    +    a.a0 = ( a.a0<>negShiftCount );
    +    a.a1 <<= shiftCount;
    +    return a;
    +
    +}
    +
    +static bits128X shortShift128RightJamming( bits128X a, int8 shiftCount )
    +{
    +    int8 negShiftCount;
    +    bits64 extra;
    +
    +    negShiftCount = ( - shiftCount & 63 );
    +    extra = a.a1<>shiftCount ) | ( extra != 0 );
    +    a.a0 >>= shiftCount;
    +    return a;
    +
    +}
    +
    +static bits128X neg128( bits128X a )
    +{
    +
    +    if ( a.a1 == 0 ) {
    +        a.a0 = - a.a0;
    +    }
    +    else {
    +        a.a1 = - a.a1;
    +        a.a0 = ~ a.a0;
    +    }
    +    return a;
    +
    +}
    +
    +static bits128X add128( bits128X a, bits128X b )
    +{
    +
    +    a.a1 += b.a1;
    +    a.a0 += b.a0 + ( a.a1 < b.a1 );
    +    return a;
    +
    +}
    +
    +static flag eq128( bits128X a, bits128X b )
    +{
    +
    +    return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
    +
    +}
    +
    +static flag le128( bits128X a, bits128X b )
    +{
    +
    +    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
    +
    +}
    +
    +static flag lt128( bits128X a, bits128X b )
    +{
    +
    +    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
    +
    +}
    +
    +static floatX roundFloatXTo24( flag isTiny, floatX zx )
    +{
    +    bits32 roundBits;
    +
    +    zx.sig.a0 |= ( zx.sig.a1 != 0 );
    +    zx.sig.a1 = 0;
    +    roundBits = zx.sig.a0 & 0xFFFFFFFF;
    +    zx.sig.a0 -= roundBits;
    +    if ( roundBits ) {
    +        slow_float_exception_flags |= float_flag_inexact;
    +        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
    +        switch ( slow_float_rounding_mode ) {
    +         case float_round_nearest_even:
    +            if ( roundBits < 0x80000000 ) goto noIncrement;
    +            if (    ( roundBits == 0x80000000 )
    +                 && ! ( zx.sig.a0 & LIT64( 0x100000000 ) ) ) {
    +                goto noIncrement;
    +            }
    +            break;
    +         case float_round_to_zero:
    +            goto noIncrement;
    +         case float_round_down:
    +            if ( ! zx.sign ) goto noIncrement;
    +            break;
    +         case float_round_up:
    +            if ( zx.sign ) goto noIncrement;
    +            break;
    +        }
    +        zx.sig.a0 += LIT64( 0x100000000 );
    +        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
    +            zx.sig.a0 = LIT64( 0x0080000000000000 );
    +            ++zx.exp;
    +        }
    +    }
    + noIncrement:
    +    return zx;
    +
    +}
    +
    +static floatX roundFloatXTo53( flag isTiny, floatX zx )
    +{
    +    int8 roundBits;
    +
    +    zx.sig.a0 |= ( zx.sig.a1 != 0 );
    +    zx.sig.a1 = 0;
    +    roundBits = zx.sig.a0 & 7;
    +    zx.sig.a0 -= roundBits;
    +    if ( roundBits ) {
    +        slow_float_exception_flags |= float_flag_inexact;
    +        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
    +        switch ( slow_float_rounding_mode ) {
    +         case float_round_nearest_even:
    +            if ( roundBits < 4 ) goto noIncrement;
    +            if ( ( roundBits == 4 ) && ! ( zx.sig.a0 & 8 ) ) goto noIncrement;
    +            break;
    +         case float_round_to_zero:
    +            goto noIncrement;
    +         case float_round_down:
    +            if ( ! zx.sign ) goto noIncrement;
    +            break;
    +         case float_round_up:
    +            if ( zx.sign ) goto noIncrement;
    +            break;
    +        }
    +        zx.sig.a0 += 8;
    +        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
    +            zx.sig.a0 = LIT64( 0x0080000000000000 );
    +            ++zx.exp;
    +        }
    +    }
    + noIncrement:
    +    return zx;
    +
    +}
    +
    +static floatX roundFloatXTo64( flag isTiny, floatX zx )
    +{
    +    int64 roundBits;
    +
    +    roundBits = zx.sig.a1 & LIT64( 0x00FFFFFFFFFFFFFF );
    +    zx.sig.a1 -= roundBits;
    +    if ( roundBits ) {
    +        slow_float_exception_flags |= float_flag_inexact;
    +        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
    +        switch ( slow_float_rounding_mode ) {
    +         case float_round_nearest_even:
    +            if ( roundBits < LIT64( 0x0080000000000000 ) ) goto noIncrement;
    +            if (    ( roundBits == LIT64( 0x0080000000000000 ) )
    +                 && ! ( zx.sig.a1 & LIT64( 0x0100000000000000 ) ) ) {
    +                goto noIncrement;
    +            }
    +            break;
    +         case float_round_to_zero:
    +            goto noIncrement;
    +         case float_round_down:
    +            if ( ! zx.sign ) goto noIncrement;
    +            break;
    +         case float_round_up:
    +            if ( zx.sign ) goto noIncrement;
    +            break;
    +        }
    +        zx.sig.a1 += LIT64( 0x0100000000000000 );
    +        zx.sig.a0 += ( zx.sig.a1 == 0 );
    +        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
    +            zx.sig.a0 = LIT64( 0x0080000000000000 );
    +            ++zx.exp;
    +        }
    +    }
    + noIncrement:
    +    return zx;
    +
    +}
    +
    +static floatX roundFloatXTo113( flag isTiny, floatX zx )
    +{
    +    int8 roundBits;
    +
    +    roundBits = zx.sig.a1 & 0x7F;
    +    zx.sig.a1 -= roundBits;
    +    if ( roundBits ) {
    +        slow_float_exception_flags |= float_flag_inexact;
    +        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
    +        switch ( slow_float_rounding_mode ) {
    +         case float_round_nearest_even:
    +            if ( roundBits < 0x40 ) goto noIncrement;
    +            if (    ( roundBits == 0x40 )
    +                 && ! ( zx.sig.a1 & 0x80 ) ) goto noIncrement;
    +            break;
    +         case float_round_to_zero:
    +            goto noIncrement;
    +         case float_round_down:
    +            if ( ! zx.sign ) goto noIncrement;
    +            break;
    +         case float_round_up:
    +            if ( zx.sign ) goto noIncrement;
    +            break;
    +        }
    +        zx.sig.a1 += 0x80;
    +        zx.sig.a0 += ( zx.sig.a1 == 0 );
    +        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
    +            zx.sig.a0 = LIT64( 0x0080000000000000 );
    +            ++zx.exp;
    +        }
    +    }
    + noIncrement:
    +    return zx;
    +
    +}
    +
    +static floatX int32ToFloatX( int32 a )
    +{
    +    floatX ax;
    +
    +    ax.isNaN = FALSE;
    +    ax.isInf = FALSE;
    +    ax.sign = ( a < 0 );
    +    ax.sig.a1 = 0;
    +    ax.sig.a0 = ax.sign ? - (bits64) a : a;
    +    if ( a == 0 ) {
    +        ax.isZero = TRUE;
    +        return ax;
    +    }
    +    ax.isZero = FALSE;
    +    ax.sig.a0 <<= 24;
    +    ax.exp = 31;
    +    while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
    +        ax.sig.a0 <<= 1;
    +        --ax.exp;
    +    }
    +    return ax;
    +
    +}
    +
    +static int32 floatXToInt32( floatX ax )
    +{
    +    int8 savedExceptionFlags;
    +    int32 shiftCount;
    +    int32 z;
    +
    +    if ( ax.isInf || ax.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +        return ( ax.isInf & ax.sign ) ? (sbits32) 0x80000000 : 0x7FFFFFFF;
    +    }
    +    if ( ax.isZero ) return 0;
    +    savedExceptionFlags = slow_float_exception_flags;
    +    shiftCount = 52 - ax.exp;
    +    if ( 56 < shiftCount ) {
    +        ax.sig.a1 = 1;
    +        ax.sig.a0 = 0;
    +    }
    +    else {
    +        while ( 0 < shiftCount ) {
    +            ax.sig = shortShift128RightJamming( ax.sig, 1 );
    +            --shiftCount;
    +        }
    +    }
    +    ax = roundFloatXTo53( FALSE, ax );
    +    ax.sig = shortShift128RightJamming( ax.sig, 3 );
    +    z = ax.sig.a0;
    +    if ( ax.sign ) z = - z;
    +    if (    ( shiftCount < 0 )
    +         || ( ax.sig.a0>>32 )
    +         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
    +       ) {
    +        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
    +        return ax.sign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
    +    }
    +    return z;
    +
    +}
    +
    +static floatX int64ToFloatX( int64 a )
    +{
    +    uint64 absA;
    +    floatX ax;
    +
    +    ax.isNaN = FALSE;
    +    ax.isInf = FALSE;
    +    ax.sign = ( a < 0 );
    +    ax.sig.a1 = ax.sign ? - a : a;
    +    ax.sig.a0 = 0;
    +    if ( a == 0 ) {
    +        ax.isZero = TRUE;
    +        return ax;
    +    }
    +    ax.isZero = FALSE;
    +    ax.sig = shortShift128Left( ax.sig, 56 );
    +    ax.exp = 63;
    +    while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
    +        ax.sig = shortShift128Left( ax.sig, 1 );
    +        --ax.exp;
    +    }
    +    return ax;
    +
    +}
    +
    +static int64 floatXToInt64( floatX ax )
    +{
    +    int8 savedExceptionFlags;
    +    int32 shiftCount;
    +    int64 z;
    +
    +    if ( ax.isInf || ax.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +        return
    +              ( ax.isInf & ax.sign ) ? (sbits64) LIT64( 0x8000000000000000 )
    +            : LIT64( 0x7FFFFFFFFFFFFFFF );
    +    }
    +    if ( ax.isZero ) return 0;
    +    savedExceptionFlags = slow_float_exception_flags;
    +    shiftCount = 112 - ax.exp;
    +    if ( 116 < shiftCount ) {
    +        ax.sig.a1 = 1;
    +        ax.sig.a0 = 0;
    +    }
    +    else {
    +        while ( 0 < shiftCount ) {
    +            ax.sig = shortShift128RightJamming( ax.sig, 1 );
    +            --shiftCount;
    +        }
    +    }
    +    ax = roundFloatXTo113( FALSE, ax );
    +    ax.sig = shortShift128RightJamming( ax.sig, 7 );
    +    z = ax.sig.a1;
    +    if ( ax.sign ) z = - z;
    +    if (    ( shiftCount < 0 )
    +         || ax.sig.a0
    +         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
    +       ) {
    +        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
    +        return
    +              ax.sign ? (sbits64) LIT64( 0x8000000000000000 )
    +            : LIT64( 0x7FFFFFFFFFFFFFFF );
    +    }
    +    return z;
    +
    +}
    +
    +static floatX float32ToFloatX( float32 a )
    +{
    +    int16 expField;
    +    floatX ax;
    +
    +    ax.isNaN = FALSE;
    +    ax.isInf = FALSE;
    +    ax.isZero = FALSE;
    +    ax.sign = ( ( a & 0x80000000 ) != 0 );
    +    expField = ( a>>23 ) & 0xFF;
    +    ax.sig.a1 = 0;
    +    ax.sig.a0 = a & 0x007FFFFF;
    +    ax.sig.a0 <<= 32;
    +    if ( expField == 0 ) {
    +        if ( ax.sig.a0 == 0 ) {
    +            ax.isZero = TRUE;
    +        }
    +        else {
    +            expField = 1 - 0x7F;
    +            do {
    +                ax.sig.a0 <<= 1;
    +                --expField;
    +            } while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) );
    +            ax.exp = expField;
    +        }
    +    }
    +    else if ( expField == 0xFF ) {
    +        if ( ax.sig.a0 == 0 ) {
    +            ax.isInf = TRUE;
    +        }
    +        else {
    +            ax.isNaN = TRUE;
    +        }
    +    }
    +    else {
    +        ax.sig.a0 |= LIT64( 0x0080000000000000 );
    +        ax.exp = expField - 0x7F;
    +    }
    +    return ax;
    +
    +}
    +
    +static float32 floatXToFloat32( floatX zx )
    +{
    +    floatX savedZ;
    +    flag isTiny;
    +    int32 expField;
    +    float32 z;
    +
    +    if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
    +    if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
    +    if ( zx.isNaN ) return 0xFFFFFFFF;
    +    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
    +        zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +        ++zx.exp;
    +    }
    +    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
    +        zx.sig = shortShift128Left( zx.sig, 1 );
    +        --zx.exp;
    +    }
    +    savedZ = zx;
    +    isTiny =
    +           ( slow_float_detect_tininess == float_tininess_before_rounding )
    +        && ( zx.exp + 0x7F <= 0 );
    +    zx = roundFloatXTo24( isTiny, zx );
    +    expField = zx.exp + 0x7F;
    +    if ( 0xFF <= expField ) {
    +        slow_float_exception_flags |=
    +            float_flag_overflow | float_flag_inexact;
    +        if ( zx.sign ) {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_down:
    +                z = 0xFF800000;
    +                break;
    +             case float_round_to_zero:
    +             case float_round_up:
    +                z = 0xFF7FFFFF;
    +                break;
    +            }
    +        }
    +        else {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_up:
    +                z = 0x7F800000;
    +                break;
    +             case float_round_to_zero:
    +             case float_round_down:
    +                z = 0x7F7FFFFF;
    +                break;
    +            }
    +        }
    +        return z;
    +    }
    +    if ( expField <= 0 ) {
    +        isTiny = TRUE;
    +        zx = savedZ;
    +        expField = zx.exp + 0x7F;
    +        if ( expField < -27 ) {
    +            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( expField <= 0 ) {
    +                zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +                ++expField;
    +            }
    +        }
    +        zx = roundFloatXTo24( isTiny, zx );
    +        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
    +    }
    +    z = expField;
    +    z <<= 23;
    +    if ( zx.sign ) z |= 0x80000000;
    +    z |= ( zx.sig.a0>>32 ) & 0x007FFFFF;
    +    return z;
    +
    +}
    +
    +static floatX float64ToFloatX( float64 a )
    +{
    +    int16 expField;
    +    floatX ax;
    +
    +    ax.isNaN = FALSE;
    +    ax.isInf = FALSE;
    +    ax.isZero = FALSE;
    +    ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
    +    expField = ( a>>52 ) & 0x7FF;
    +    ax.sig.a1 = 0;
    +    ax.sig.a0 = a & LIT64( 0x000FFFFFFFFFFFFF );
    +    if ( expField == 0 ) {
    +        if ( ax.sig.a0 == 0 ) {
    +            ax.isZero = TRUE;
    +        }
    +        else {
    +            expField = 1 - 0x3FF;
    +            do {
    +                ax.sig.a0 <<= 1;
    +                --expField;
    +            } while ( ax.sig.a0 < LIT64( 0x0010000000000000 ) );
    +            ax.exp = expField;
    +        }
    +    }
    +    else if ( expField == 0x7FF ) {
    +        if ( ax.sig.a0 == 0 ) {
    +            ax.isInf = TRUE;
    +        }
    +        else {
    +            ax.isNaN = TRUE;
    +        }
    +    }
    +    else {
    +        ax.exp = expField - 0x3FF;
    +        ax.sig.a0 |= LIT64( 0x0010000000000000 );
    +    }
    +    ax.sig.a0 <<= 3;
    +    return ax;
    +
    +}
    +
    +static float64 floatXToFloat64( floatX zx )
    +{
    +    floatX savedZ;
    +    flag isTiny;
    +    int32 expField;
    +    float64 z;
    +
    +    if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
    +    if ( zx.isInf ) {
    +        return
    +              zx.sign ? LIT64( 0xFFF0000000000000 )
    +            : LIT64( 0x7FF0000000000000 );
    +    }
    +    if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
    +    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
    +        zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +        ++zx.exp;
    +    }
    +    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
    +        zx.sig = shortShift128Left( zx.sig, 1 );
    +        --zx.exp;
    +    }
    +    savedZ = zx;
    +    isTiny =
    +           ( slow_float_detect_tininess == float_tininess_before_rounding )
    +        && ( zx.exp + 0x3FF <= 0 );
    +    zx = roundFloatXTo53( isTiny, zx );
    +    expField = zx.exp + 0x3FF;
    +    if ( 0x7FF <= expField ) {
    +        slow_float_exception_flags |=
    +            float_flag_overflow | float_flag_inexact;
    +        if ( zx.sign ) {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_down:
    +                z = LIT64( 0xFFF0000000000000 );
    +                break;
    +             case float_round_to_zero:
    +             case float_round_up:
    +                z = LIT64( 0xFFEFFFFFFFFFFFFF );
    +                break;
    +            }
    +        }
    +        else {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_up:
    +                z = LIT64( 0x7FF0000000000000 );
    +                break;
    +             case float_round_to_zero:
    +             case float_round_down:
    +                z = LIT64( 0x7FEFFFFFFFFFFFFF );
    +                break;
    +            }
    +        }
    +        return z;
    +    }
    +    if ( expField <= 0 ) {
    +        isTiny = TRUE;
    +        zx = savedZ;
    +        expField = zx.exp + 0x3FF;
    +        if ( expField < -56 ) {
    +            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( expField <= 0 ) {
    +                zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +                ++expField;
    +            }
    +        }
    +        zx = roundFloatXTo53( isTiny, zx );
    +        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
    +    }
    +    zx.sig.a0 >>= 3;
    +    z = expField;
    +    z <<= 52;
    +    if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
    +    z |= zx.sig.a0 & LIT64( 0x000FFFFFFFFFFFFF );
    +    return z;
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +static floatX floatx80ToFloatX( floatx80 a )
    +{
    +    int32 expField;
    +    floatX ax;
    +
    +    ax.isNaN = FALSE;
    +    ax.isInf = FALSE;
    +    ax.isZero = FALSE;
    +    ax.sign = ( ( a.high & 0x8000 ) != 0 );
    +    expField = a.high & 0x7FFF;
    +    ax.sig.a1 = a.low;
    +    ax.sig.a0 = 0;
    +    if ( expField == 0 ) {
    +        if ( ax.sig.a1 == 0 ) {
    +            ax.isZero = TRUE;
    +        }
    +        else {
    +            expField = 1 - 0x3FFF;
    +            while ( ax.sig.a1 < LIT64( 0x8000000000000000 ) ) {
    +                ax.sig.a1 <<= 1;
    +                --expField;
    +            }
    +            ax.exp = expField;
    +        }
    +    }
    +    else if ( expField == 0x7FFF ) {
    +        if ( ( ax.sig.a1 & LIT64( 0x7FFFFFFFFFFFFFFF ) ) == 0 ) {
    +            ax.isInf = TRUE;
    +        }
    +        else {
    +            ax.isNaN = TRUE;
    +        }
    +    }
    +    else {
    +        ax.exp = expField - 0x3FFF;
    +    }
    +    ax.sig = shortShift128Left( ax.sig, 56 );
    +    return ax;
    +
    +}
    +
    +static floatx80 floatXToFloatx80( floatX zx )
    +{
    +    floatX savedZ;
    +    flag isTiny;
    +    int32 expField;
    +    floatx80 z;
    +
    +    if ( zx.isZero ) {
    +        z.low = 0;
    +        z.high = zx.sign ? 0x8000 : 0;
    +        return z;
    +    }
    +    if ( zx.isInf ) {
    +        z.low = LIT64( 0x8000000000000000 );
    +        z.high = zx.sign ? 0xFFFF : 0x7FFF;
    +        return z;
    +    }
    +    if ( zx.isNaN ) {
    +        z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
    +        z.high = 0xFFFF;
    +        return z;
    +    }
    +    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
    +        zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +        ++zx.exp;
    +    }
    +    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
    +        zx.sig = shortShift128Left( zx.sig, 1 );
    +        --zx.exp;
    +    }
    +    savedZ = zx;
    +    isTiny =
    +           ( slow_float_detect_tininess == float_tininess_before_rounding )
    +        && ( zx.exp + 0x3FFF <= 0 );
    +    switch ( slow_floatx80_rounding_precision ) {
    +     case 32:
    +        zx = roundFloatXTo24( isTiny, zx );
    +        break;
    +     case 64:
    +        zx = roundFloatXTo53( isTiny, zx );
    +        break;
    +     default:
    +        zx = roundFloatXTo64( isTiny, zx );
    +        break;
    +    }
    +    expField = zx.exp + 0x3FFF;
    +    if ( 0x7FFF <= expField ) {
    +        slow_float_exception_flags |=
    +            float_flag_overflow | float_flag_inexact;
    +        if ( zx.sign ) {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_down:
    +                z.low = LIT64( 0x8000000000000000 );
    +                z.high = 0xFFFF;
    +                break;
    +             case float_round_to_zero:
    +             case float_round_up:
    +                switch ( slow_floatx80_rounding_precision ) {
    +                 case 32:
    +                    z.low = LIT64( 0xFFFFFF0000000000 );
    +                    break;
    +                 case 64:
    +                    z.low = LIT64( 0xFFFFFFFFFFFFF800 );
    +                    break;
    +                 default:
    +                    z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
    +                    break;
    +                }
    +                z.high = 0xFFFE;
    +                break;
    +            }
    +        }
    +        else {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_up:
    +                z.low = LIT64( 0x8000000000000000 );
    +                z.high = 0x7FFF;
    +                break;
    +             case float_round_to_zero:
    +             case float_round_down:
    +                switch ( slow_floatx80_rounding_precision ) {
    +                 case 32:
    +                    z.low = LIT64( 0xFFFFFF0000000000 );
    +                    break;
    +                 case 64:
    +                    z.low = LIT64( 0xFFFFFFFFFFFFF800 );
    +                    break;
    +                 default:
    +                    z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
    +                    break;
    +                }
    +                z.high = 0x7FFE;
    +                break;
    +            }
    +        }
    +        return z;
    +    }
    +    if ( expField <= 0 ) {
    +        isTiny = TRUE;
    +        zx = savedZ;
    +        expField = zx.exp + 0x3FFF;
    +        if ( expField < -70 ) {
    +            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( expField <= 0 ) {
    +                zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +                ++expField;
    +            }
    +        }
    +        switch ( slow_floatx80_rounding_precision ) {
    +         case 32:
    +            zx = roundFloatXTo24( isTiny, zx );
    +            break;
    +         case 64:
    +            zx = roundFloatXTo53( isTiny, zx );
    +            break;
    +         default:
    +            zx = roundFloatXTo64( isTiny, zx );
    +            break;
    +        }
    +        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
    +    }
    +    zx.sig = shortShift128RightJamming( zx.sig, 56 );
    +    z.low = zx.sig.a1;
    +    z.high = expField;
    +    if ( zx.sign ) z.high |= 0x8000;
    +    return z;
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +static floatX float128ToFloatX( float128 a )
    +{
    +    int32 expField;
    +    floatX ax;
    +
    +    ax.isNaN = FALSE;
    +    ax.isInf = FALSE;
    +    ax.isZero = FALSE;
    +    ax.sign = ( ( a.high & LIT64( 0x8000000000000000 ) ) != 0 );
    +    expField = ( a.high>>48 ) & 0x7FFF;
    +    ax.sig.a1 = a.low;
    +    ax.sig.a0 = a.high & LIT64( 0x0000FFFFFFFFFFFF );
    +    if ( expField == 0 ) {
    +        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
    +            ax.isZero = TRUE;
    +        }
    +        else {
    +            expField = 1 - 0x3FFF;
    +            do {
    +                ax.sig = shortShift128Left( ax.sig, 1 );
    +                --expField;
    +            } while ( ax.sig.a0 < LIT64( 0x0001000000000000 ) );
    +            ax.exp = expField;
    +        }
    +    }
    +    else if ( expField == 0x7FFF ) {
    +        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
    +            ax.isInf = TRUE;
    +        }
    +        else {
    +            ax.isNaN = TRUE;
    +        }
    +    }
    +    else {
    +        ax.exp = expField - 0x3FFF;
    +        ax.sig.a0 |= LIT64( 0x0001000000000000 );
    +    }
    +    ax.sig = shortShift128Left( ax.sig, 7 );
    +    return ax;
    +
    +}
    +
    +static float128 floatXToFloat128( floatX zx )
    +{
    +    floatX savedZ;
    +    flag isTiny;
    +    int32 expField;
    +    float128 z;
    +
    +    if ( zx.isZero ) {
    +        z.low = 0;
    +        z.high = zx.sign ? LIT64( 0x8000000000000000 ) : 0;
    +        return z;
    +    }
    +    if ( zx.isInf ) {
    +        z.low = 0;
    +        z.high =
    +              zx.sign ? LIT64( 0xFFFF000000000000 )
    +            : LIT64( 0x7FFF000000000000 );
    +        return z;
    +    }
    +    if ( zx.isNaN ) {
    +        z.high = z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
    +        return z;
    +    }
    +    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
    +        zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +        ++zx.exp;
    +    }
    +    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
    +        zx.sig = shortShift128Left( zx.sig, 1 );
    +        --zx.exp;
    +    }
    +    savedZ = zx;
    +    isTiny =
    +           ( slow_float_detect_tininess == float_tininess_before_rounding )
    +        && ( zx.exp + 0x3FFF <= 0 );
    +    zx = roundFloatXTo113( isTiny, zx );
    +    expField = zx.exp + 0x3FFF;
    +    if ( 0x7FFF <= expField ) {
    +        slow_float_exception_flags |=
    +            float_flag_overflow | float_flag_inexact;
    +        if ( zx.sign ) {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_down:
    +                z.low = 0;
    +                z.high = LIT64( 0xFFFF000000000000 );
    +                break;
    +             case float_round_to_zero:
    +             case float_round_up:
    +                z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
    +                z.high = LIT64( 0xFFFEFFFFFFFFFFFF );
    +                break;
    +            }
    +        }
    +        else {
    +            switch ( slow_float_rounding_mode ) {
    +             case float_round_nearest_even:
    +             case float_round_up:
    +                z.low = 0;
    +                z.high = LIT64( 0x7FFF000000000000 );
    +                break;
    +             case float_round_to_zero:
    +             case float_round_down:
    +                z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
    +                z.high = LIT64( 0x7FFEFFFFFFFFFFFF );
    +                break;
    +            }
    +        }
    +        return z;
    +    }
    +    if ( expField <= 0 ) {
    +        isTiny = TRUE;
    +        zx = savedZ;
    +        expField = zx.exp + 0x3FFF;
    +        if ( expField < -120 ) {
    +            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( expField <= 0 ) {
    +                zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +                ++expField;
    +            }
    +        }
    +        zx = roundFloatXTo113( isTiny, zx );
    +        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
    +    }
    +    zx.sig = shortShift128RightJamming( zx.sig, 7 );
    +    z.low = zx.sig.a1;
    +    z.high = expField;
    +    z.high <<= 48;
    +    if ( zx.sign ) z.high |= LIT64( 0x8000000000000000 );
    +    z.high |= zx.sig.a0 & LIT64( 0x0000FFFFFFFFFFFF );
    +    return z;
    +
    +}
    +
    +#endif
    +
    +static floatX floatXInvalid( void )
    +{
    +
    +    slow_float_exception_flags |= float_flag_invalid;
    +    return floatXNaN;
    +
    +}
    +
    +static floatX floatXRoundToInt( floatX ax )
    +{
    +    int32 shiftCount, i;
    +
    +    if ( ax.isNaN || ax.isInf ) return ax;
    +    shiftCount = 112 - ax.exp;
    +    if ( shiftCount <= 0 ) return ax;
    +    if ( 119 < shiftCount ) {
    +        ax.exp = 112;
    +        ax.sig.a1 = ! ax.isZero;
    +        ax.sig.a0 = 0;
    +    }
    +    else {
    +        while ( 0 < shiftCount ) {
    +            ax.sig = shortShift128RightJamming( ax.sig, 1 );
    +            ++ax.exp;
    +            --shiftCount;
    +        }
    +    }
    +    ax = roundFloatXTo113( FALSE, ax );
    +    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
    +    return ax;
    +
    +}
    +
    +static floatX floatXAdd( floatX ax, floatX bx )
    +{
    +    int32 expDiff;
    +    floatX zx;
    +
    +    if ( ax.isNaN ) return ax;
    +    if ( bx.isNaN ) return bx;
    +    if ( ax.isInf && bx.isInf ) {
    +        if ( ax.sign == bx.sign ) return ax;
    +        return floatXInvalid();
    +    }
    +    if ( ax.isInf ) return ax;
    +    if ( bx.isInf ) return bx;
    +    if ( ax.isZero && bx.isZero ) {
    +        if ( ax.sign == bx.sign ) return ax;
    +        goto completeCancellation;
    +    }
    +    if (    ( ax.sign != bx.sign )
    +         && ( ax.exp == bx.exp )
    +         && eq128( ax.sig, bx.sig )
    +       ) {
    + completeCancellation:
    +        return
    +              ( slow_float_rounding_mode == float_round_down ) ?
    +                  floatXNegativeZero
    +            : floatXPositiveZero;
    +    }
    +    if ( ax.isZero ) return bx;
    +    if ( bx.isZero ) return ax;
    +    expDiff = ax.exp - bx.exp;
    +    if ( expDiff < 0 ) {
    +        zx = ax;
    +        zx.exp = bx.exp;
    +        if ( expDiff < -120 ) {
    +            zx.sig.a1 = 1;
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( expDiff < 0 ) {
    +                zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +                ++expDiff;
    +            }
    +        }
    +        if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
    +        zx.sign = bx.sign;
    +        zx.sig = add128( zx.sig, bx.sig );
    +    }
    +    else {
    +        zx = bx;
    +        zx.exp = ax.exp;
    +        if ( 120 < expDiff ) {
    +            zx.sig.a1 = 1;
    +            zx.sig.a0 = 0;
    +        }
    +        else {
    +            while ( 0 < expDiff ) {
    +                zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +                --expDiff;
    +            }
    +        }
    +        if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
    +        zx.sign = ax.sign;
    +        zx.sig = add128( zx.sig, ax.sig );
    +    }
    +    if ( zx.sig.a0 & LIT64( 0x8000000000000000 ) ) {
    +        zx.sig = neg128( zx.sig );
    +        zx.sign = ! zx.sign;
    +    }
    +    return zx;
    +
    +}
    +
    +static floatX floatXMul( floatX ax, floatX bx )
    +{
    +    int8 bitNum;
    +    floatX zx;
    +
    +    if ( ax.isNaN ) return ax;
    +    if ( bx.isNaN ) return bx;
    +    if ( ax.isInf ) {
    +        if ( bx.isZero ) return floatXInvalid();
    +        if ( bx.sign ) ax.sign = ! ax.sign;
    +        return ax;
    +    }
    +    if ( bx.isInf ) {
    +        if ( ax.isZero ) return floatXInvalid();
    +        if ( ax.sign ) bx.sign = ! bx.sign;
    +        return bx;
    +    }
    +    zx = ax;
    +    zx.sign ^= bx.sign;
    +    if ( ax.isZero || bx.isZero ) {
    +        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
    +    }
    +    zx.exp += bx.exp + 1;
    +    zx.sig.a1 = 0;
    +    zx.sig.a0 = 0;
    +    for ( bitNum = 0; bitNum < 119; ++bitNum ) {
    +        if ( bx.sig.a1 & 2 ) zx.sig = add128( zx.sig, ax.sig );
    +        bx.sig = shortShift128RightJamming( bx.sig, 1 );
    +        zx.sig = shortShift128RightJamming( zx.sig, 1 );
    +    }
    +    return zx;
    +
    +}
    +
    +static floatX floatXDiv( floatX ax, floatX bx )
    +{
    +    bits128X negBSig;
    +    int8 bitNum;
    +    floatX zx;
    +
    +    if ( ax.isNaN ) return ax;
    +    if ( bx.isNaN ) return bx;
    +    if ( ax.isInf ) {
    +        if ( bx.isInf ) return floatXInvalid();
    +        if ( bx.sign ) ax.sign = ! ax.sign;
    +        return ax;
    +    }
    +    if ( bx.isZero ) {
    +        if ( ax.isZero ) return floatXInvalid();
    +        slow_float_exception_flags |= float_flag_divbyzero;
    +        if ( ax.sign ) bx.sign = ! bx.sign;
    +        bx.isZero = FALSE;
    +        bx.isInf = TRUE;
    +        return bx;
    +    }
    +    zx = ax;
    +    zx.sign ^= bx.sign;
    +    if ( ax.isZero || bx.isInf ) {
    +        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
    +    }
    +    zx.exp -= bx.exp + 1;
    +    zx.sig.a1 = 0;
    +    zx.sig.a0 = 0;
    +    negBSig = neg128( bx.sig );
    +    for ( bitNum = 0; bitNum < 120; ++bitNum ) {
    +        if ( le128( bx.sig, ax.sig ) ) {
    +            zx.sig.a1 |= 1;
    +            ax.sig = add128( ax.sig, negBSig );
    +        }
    +        ax.sig = shortShift128Left( ax.sig, 1 );
    +        zx.sig = shortShift128Left( zx.sig, 1 );
    +    }
    +    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
    +    return zx;
    +
    +}
    +
    +static floatX floatXRem( floatX ax, floatX bx )
    +{
    +    bits128X negBSig;
    +    flag lastQuotientBit;
    +    bits128X savedASig;
    +
    +    if ( ax.isNaN ) return ax;
    +    if ( bx.isNaN ) return bx;
    +    if ( ax.isInf || bx.isZero ) return floatXInvalid();
    +    if ( ax.isZero || bx.isInf ) return ax;
    +    --bx.exp;
    +    if ( ax.exp < bx.exp ) return ax;
    +    bx.sig = shortShift128Left( bx.sig, 1 );
    +    negBSig = neg128( bx.sig );
    +    while ( bx.exp < ax.exp ) {
    +        if ( le128( bx.sig, ax.sig ) ) ax.sig = add128( ax.sig, negBSig );
    +        ax.sig = shortShift128Left( ax.sig, 1 );
    +        --ax.exp;
    +    }
    +    lastQuotientBit = le128( bx.sig, ax.sig );
    +    if ( lastQuotientBit ) ax.sig = add128( ax.sig, negBSig );
    +    savedASig = ax.sig;
    +    ax.sig = neg128( add128( ax.sig, negBSig ) );
    +    if ( lt128( ax.sig, savedASig ) ) {
    +        ax.sign = ! ax.sign;
    +    }
    +    else if ( lt128( savedASig, ax.sig ) ) {
    +        ax.sig = savedASig;
    +    }
    +    else {
    +        if ( lastQuotientBit ) {
    +            ax.sign = ! ax.sign;
    +        }
    +        else {
    +            ax.sig = savedASig;
    +        }
    +    }
    +    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
    +    return ax;
    +
    +}
    +
    +static floatX floatXSqrt( floatX ax )
    +{
    +    int8 bitNum;
    +    bits128X bitSig, savedASig;
    +    floatX zx;
    +
    +    if ( ax.isNaN || ax.isZero ) return ax;
    +    if ( ax.sign ) return floatXInvalid();
    +    if ( ax.isInf ) return ax;
    +    zx = ax;
    +    zx.exp >>= 1;
    +    if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift128RightJamming( ax.sig, 1 );
    +    zx.sig.a1 = 0;
    +    zx.sig.a0 = 0;
    +    bitSig.a1 = 0;
    +    bitSig.a0 = LIT64( 0x0080000000000000 );
    +    for ( bitNum = 0; bitNum < 120; ++bitNum ) {
    +        savedASig = ax.sig;
    +        ax.sig = add128( ax.sig, neg128( zx.sig ) );
    +        ax.sig = shortShift128Left( ax.sig, 1 );
    +        ax.sig = add128( ax.sig, neg128( bitSig ) );
    +        if ( ax.sig.a0 & LIT64( 0x8000000000000000 ) ) {
    +            ax.sig = shortShift128Left( savedASig, 1 );
    +        }
    +        else {
    +            zx.sig.a1 |= bitSig.a1;
    +            zx.sig.a0 |= bitSig.a0;
    +        }
    +        bitSig = shortShift128RightJamming( bitSig, 1 );
    +    }
    +    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
    +    return zx;
    +
    +}
    +
    +static flag floatXEq( floatX ax, floatX bx )
    +{
    +
    +    if ( ax.isNaN || bx.isNaN ) return FALSE;
    +    if ( ax.isZero && bx.isZero ) return TRUE;
    +    if ( ax.sign != bx.sign ) return FALSE;
    +    if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
    +    return ( ax.exp == bx.exp ) && eq128( ax.sig, bx.sig );
    +
    +}
    +
    +static flag floatXLe( floatX ax, floatX bx )
    +{
    +
    +    if ( ax.isNaN || bx.isNaN ) return FALSE;
    +    if ( ax.isZero && bx.isZero ) return TRUE;
    +    if ( ax.sign != bx.sign ) return ax.sign;
    +    if ( ax.sign ) {
    +        if ( ax.isInf || bx.isZero ) return TRUE;
    +        if ( bx.isInf || ax.isZero ) return FALSE;
    +        if ( bx.exp < ax.exp ) return TRUE;
    +        if ( ax.exp < bx.exp ) return FALSE;
    +        return le128( bx.sig, ax.sig );
    +    }
    +    else {
    +        if ( bx.isInf || ax.isZero ) return TRUE;
    +        if ( ax.isInf || bx.isZero ) return FALSE;
    +        if ( ax.exp < bx.exp ) return TRUE;
    +        if ( bx.exp < ax.exp ) return FALSE;
    +        return le128( ax.sig, bx.sig );
    +    }
    +
    +}
    +
    +static flag floatXLt( floatX ax, floatX bx )
    +{
    +
    +    if ( ax.isNaN || bx.isNaN ) return FALSE;
    +    if ( ax.isZero && bx.isZero ) return FALSE;
    +    if ( ax.sign != bx.sign ) return ax.sign;
    +    if ( ax.isInf && bx.isInf ) return FALSE;
    +    if ( ax.sign ) {
    +        if ( ax.isInf || bx.isZero ) return TRUE;
    +        if ( bx.isInf || ax.isZero ) return FALSE;
    +        if ( bx.exp < ax.exp ) return TRUE;
    +        if ( ax.exp < bx.exp ) return FALSE;
    +        return lt128( bx.sig, ax.sig );
    +    }
    +    else {
    +        if ( bx.isInf || ax.isZero ) return TRUE;
    +        if ( ax.isInf || bx.isZero ) return FALSE;
    +        if ( ax.exp < bx.exp ) return TRUE;
    +        if ( bx.exp < ax.exp ) return FALSE;
    +        return lt128( ax.sig, bx.sig );
    +    }
    +
    +}
    +
    +float32 slow_int32_to_float32( int32 a )
    +{
    +
    +    return floatXToFloat32( int32ToFloatX( a ) );
    +
    +}
    +
    +float64 slow_int32_to_float64( int32 a )
    +{
    +
    +    return floatXToFloat64( int32ToFloatX( a ) );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +floatx80 slow_int32_to_floatx80( int32 a )
    +{
    +
    +    return floatXToFloatx80( int32ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +float128 slow_int32_to_float128( int32 a )
    +{
    +
    +    return floatXToFloat128( int32ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +float32 slow_int64_to_float32( int64 a )
    +{
    +
    +    return floatXToFloat32( int64ToFloatX( a ) );
    +
    +}
    +
    +float64 slow_int64_to_float64( int64 a )
    +{
    +
    +    return floatXToFloat64( int64ToFloatX( a ) );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +floatx80 slow_int64_to_floatx80( int64 a )
    +{
    +
    +    return floatXToFloatx80( int64ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +float128 slow_int64_to_float128( int64 a )
    +{
    +
    +    return floatXToFloat128( int64ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +int32 slow_float32_to_int32( float32 a )
    +{
    +
    +    return floatXToInt32( float32ToFloatX( a ) );
    +
    +}
    +
    +int32 slow_float32_to_int32_round_to_zero( float32 a )
    +{
    +    int8 savedRoundingMode;
    +    int32 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt32( float32ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +int64 slow_float32_to_int64( float32 a )
    +{
    +
    +    return floatXToInt64( float32ToFloatX( a ) );
    +
    +}
    +
    +int64 slow_float32_to_int64_round_to_zero( float32 a )
    +{
    +    int8 savedRoundingMode;
    +    int64 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt64( float32ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +float64 slow_float32_to_float64( float32 a )
    +{
    +
    +    return floatXToFloat64( float32ToFloatX( a ) );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +floatx80 slow_float32_to_floatx80( float32 a )
    +{
    +
    +    return floatXToFloatx80( float32ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +float128 slow_float32_to_float128( float32 a )
    +{
    +
    +    return floatXToFloat128( float32ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +float32 slow_float32_round_to_int( float32 a )
    +{
    +
    +    return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
    +
    +}
    +
    +float32 slow_float32_add( float32 a, float32 b )
    +{
    +
    +    return
    +        floatXToFloat32(
    +            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_sub( float32 a, float32 b )
    +{
    +
    +    b ^= 0x80000000;
    +    return
    +        floatXToFloat32(
    +            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_mul( float32 a, float32 b )
    +{
    +
    +    return
    +        floatXToFloat32(
    +            floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_div( float32 a, float32 b )
    +{
    +
    +    return
    +        floatXToFloat32(
    +            floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_rem( float32 a, float32 b )
    +{
    +
    +    return
    +        floatXToFloat32(
    +            floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
    +
    +}
    +
    +float32 slow_float32_sqrt( float32 a )
    +{
    +
    +    return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
    +
    +}
    +
    +flag slow_float32_eq( float32 a, float32 b )
    +{
    +
    +    return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float32_le( float32 a, float32 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float32ToFloatX( a );
    +    bx = float32ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLe( ax, bx );
    +
    +}
    +
    +flag slow_float32_lt( float32 a, float32 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float32ToFloatX( a );
    +    bx = float32ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLt( ax, bx );
    +
    +}
    +
    +flag slow_float32_eq_signaling( float32 a, float32 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float32ToFloatX( a );
    +    bx = float32ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXEq( ax, bx );
    +
    +}
    +
    +flag slow_float32_le_quiet( float32 a, float32 b )
    +{
    +
    +    return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float32_lt_quiet( float32 a, float32 b )
    +{
    +
    +    return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
    +
    +}
    +
    +int32 slow_float64_to_int32( float64 a )
    +{
    +
    +    return floatXToInt32( float64ToFloatX( a ) );
    +
    +}
    +
    +int32 slow_float64_to_int32_round_to_zero( float64 a )
    +{
    +    int8 savedRoundingMode;
    +    int32 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt32( float64ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +int64 slow_float64_to_int64( float64 a )
    +{
    +
    +    return floatXToInt64( float64ToFloatX( a ) );
    +
    +}
    +
    +int64 slow_float64_to_int64_round_to_zero( float64 a )
    +{
    +    int8 savedRoundingMode;
    +    int64 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt64( float64ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +float32 slow_float64_to_float32( float64 a )
    +{
    +
    +    return floatXToFloat32( float64ToFloatX( a ) );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +floatx80 slow_float64_to_floatx80( float64 a )
    +{
    +
    +    return floatXToFloatx80( float64ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +float128 slow_float64_to_float128( float64 a )
    +{
    +
    +    return floatXToFloat128( float64ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +float64 slow_float64_round_to_int( float64 a )
    +{
    +
    +    return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
    +
    +}
    +
    +float64 slow_float64_add( float64 a, float64 b )
    +{
    +
    +    return
    +        floatXToFloat64(
    +            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_sub( float64 a, float64 b )
    +{
    +
    +    b ^= LIT64( 0x8000000000000000 );
    +    return
    +        floatXToFloat64(
    +            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_mul( float64 a, float64 b )
    +{
    +
    +    return
    +        floatXToFloat64(
    +            floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_div( float64 a, float64 b )
    +{
    +
    +    return
    +        floatXToFloat64(
    +            floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_rem( float64 a, float64 b )
    +{
    +
    +    return
    +        floatXToFloat64(
    +            floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
    +
    +}
    +
    +float64 slow_float64_sqrt( float64 a )
    +{
    +
    +    return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
    +
    +}
    +
    +flag slow_float64_eq( float64 a, float64 b )
    +{
    +
    +    return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float64_le( float64 a, float64 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float64ToFloatX( a );
    +    bx = float64ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLe( ax, bx );
    +
    +}
    +
    +flag slow_float64_lt( float64 a, float64 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float64ToFloatX( a );
    +    bx = float64ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLt( ax, bx );
    +
    +}
    +
    +flag slow_float64_eq_signaling( float64 a, float64 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float64ToFloatX( a );
    +    bx = float64ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXEq( ax, bx );
    +
    +}
    +
    +flag slow_float64_le_quiet( float64 a, float64 b )
    +{
    +
    +    return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float64_lt_quiet( float64 a, float64 b )
    +{
    +
    +    return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +int32 slow_floatx80_to_int32( floatx80 a )
    +{
    +
    +    return floatXToInt32( floatx80ToFloatX( a ) );
    +
    +}
    +
    +int32 slow_floatx80_to_int32_round_to_zero( floatx80 a )
    +{
    +    int8 savedRoundingMode;
    +    int32 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt32( floatx80ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +int64 slow_floatx80_to_int64( floatx80 a )
    +{
    +
    +    return floatXToInt64( floatx80ToFloatX( a ) );
    +
    +}
    +
    +int64 slow_floatx80_to_int64_round_to_zero( floatx80 a )
    +{
    +    int8 savedRoundingMode;
    +    int64 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt64( floatx80ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +float32 slow_floatx80_to_float32( floatx80 a )
    +{
    +
    +    return floatXToFloat32( floatx80ToFloatX( a ) );
    +
    +}
    +
    +float64 slow_floatx80_to_float64( floatx80 a )
    +{
    +
    +    return floatXToFloat64( floatx80ToFloatX( a ) );
    +
    +}
    +
    +#ifdef FLOAT128
    +
    +float128 slow_floatx80_to_float128( floatx80 a )
    +{
    +
    +    return floatXToFloat128( floatx80ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +floatx80 slow_floatx80_round_to_int( floatx80 a )
    +{
    +
    +    return floatXToFloatx80( floatXRoundToInt( floatx80ToFloatX( a ) ) );
    +
    +}
    +
    +floatx80 slow_floatx80_add( floatx80 a, floatx80 b )
    +{
    +
    +    return
    +        floatXToFloatx80(
    +            floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
    +
    +}
    +
    +floatx80 slow_floatx80_sub( floatx80 a, floatx80 b )
    +{
    +
    +    b.high ^= 0x8000;
    +    return
    +        floatXToFloatx80(
    +            floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
    +
    +}
    +
    +floatx80 slow_floatx80_mul( floatx80 a, floatx80 b )
    +{
    +
    +    return
    +        floatXToFloatx80(
    +            floatXMul( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
    +
    +}
    +
    +floatx80 slow_floatx80_div( floatx80 a, floatx80 b )
    +{
    +
    +    return
    +        floatXToFloatx80(
    +            floatXDiv( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
    +
    +}
    +
    +floatx80 slow_floatx80_rem( floatx80 a, floatx80 b )
    +{
    +
    +    return
    +        floatXToFloatx80(
    +            floatXRem( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
    +
    +}
    +
    +floatx80 slow_floatx80_sqrt( floatx80 a )
    +{
    +
    +    return floatXToFloatx80( floatXSqrt( floatx80ToFloatX( a ) ) );
    +
    +}
    +
    +flag slow_floatx80_eq( floatx80 a, floatx80 b )
    +{
    +
    +    return floatXEq( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
    +
    +}
    +
    +flag slow_floatx80_le( floatx80 a, floatx80 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = floatx80ToFloatX( a );
    +    bx = floatx80ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLe( ax, bx );
    +
    +}
    +
    +flag slow_floatx80_lt( floatx80 a, floatx80 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = floatx80ToFloatX( a );
    +    bx = floatx80ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLt( ax, bx );
    +
    +}
    +
    +flag slow_floatx80_eq_signaling( floatx80 a, floatx80 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = floatx80ToFloatX( a );
    +    bx = floatx80ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXEq( ax, bx );
    +
    +}
    +
    +flag slow_floatx80_le_quiet( floatx80 a, floatx80 b )
    +{
    +
    +    return floatXLe( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
    +
    +}
    +
    +flag slow_floatx80_lt_quiet( floatx80 a, floatx80 b )
    +{
    +
    +    return floatXLt( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +int32 slow_float128_to_int32( float128 a )
    +{
    +
    +    return floatXToInt32( float128ToFloatX( a ) );
    +
    +}
    +
    +int32 slow_float128_to_int32_round_to_zero( float128 a )
    +{
    +    int8 savedRoundingMode;
    +    int32 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt32( float128ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +int64 slow_float128_to_int64( float128 a )
    +{
    +
    +    return floatXToInt64( float128ToFloatX( a ) );
    +
    +}
    +
    +int64 slow_float128_to_int64_round_to_zero( float128 a )
    +{
    +    int8 savedRoundingMode;
    +    int64 z;
    +
    +    savedRoundingMode = slow_float_rounding_mode;
    +    slow_float_rounding_mode = float_round_to_zero;
    +    z = floatXToInt64( float128ToFloatX( a ) );
    +    slow_float_rounding_mode = savedRoundingMode;
    +    return z;
    +
    +}
    +
    +float32 slow_float128_to_float32( float128 a )
    +{
    +
    +    return floatXToFloat32( float128ToFloatX( a ) );
    +
    +}
    +
    +float64 slow_float128_to_float64( float128 a )
    +{
    +
    +    return floatXToFloat64( float128ToFloatX( a ) );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +floatx80 slow_float128_to_floatx80( float128 a )
    +{
    +
    +    return floatXToFloatx80( float128ToFloatX( a ) );
    +
    +}
    +
    +#endif
    +
    +float128 slow_float128_round_to_int( float128 a )
    +{
    +
    +    return floatXToFloat128( floatXRoundToInt( float128ToFloatX( a ) ) );
    +
    +}
    +
    +float128 slow_float128_add( float128 a, float128 b )
    +{
    +
    +    return
    +        floatXToFloat128(
    +            floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
    +
    +}
    +
    +float128 slow_float128_sub( float128 a, float128 b )
    +{
    +
    +    b.high ^= LIT64( 0x8000000000000000 );
    +    return
    +        floatXToFloat128(
    +            floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
    +
    +}
    +
    +float128 slow_float128_mul( float128 a, float128 b )
    +{
    +
    +    return
    +        floatXToFloat128(
    +            floatXMul( float128ToFloatX( a ), float128ToFloatX( b ) ) );
    +
    +}
    +
    +float128 slow_float128_div( float128 a, float128 b )
    +{
    +
    +    return
    +        floatXToFloat128(
    +            floatXDiv( float128ToFloatX( a ), float128ToFloatX( b ) ) );
    +
    +}
    +
    +float128 slow_float128_rem( float128 a, float128 b )
    +{
    +
    +    return
    +        floatXToFloat128(
    +            floatXRem( float128ToFloatX( a ), float128ToFloatX( b ) ) );
    +
    +}
    +
    +float128 slow_float128_sqrt( float128 a )
    +{
    +
    +    return floatXToFloat128( floatXSqrt( float128ToFloatX( a ) ) );
    +
    +}
    +
    +flag slow_float128_eq( float128 a, float128 b )
    +{
    +
    +    return floatXEq( float128ToFloatX( a ), float128ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float128_le( float128 a, float128 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float128ToFloatX( a );
    +    bx = float128ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLe( ax, bx );
    +
    +}
    +
    +flag slow_float128_lt( float128 a, float128 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float128ToFloatX( a );
    +    bx = float128ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXLt( ax, bx );
    +
    +}
    +
    +flag slow_float128_eq_signaling( float128 a, float128 b )
    +{
    +    floatX ax, bx;
    +
    +    ax = float128ToFloatX( a );
    +    bx = float128ToFloatX( b );
    +    if ( ax.isNaN || bx.isNaN ) {
    +        slow_float_exception_flags |= float_flag_invalid;
    +    }
    +    return floatXEq( ax, bx );
    +
    +}
    +
    +flag slow_float128_le_quiet( float128 a, float128 b )
    +{
    +
    +    return floatXLe( float128ToFloatX( a ), float128ToFloatX( b ) );
    +
    +}
    +
    +flag slow_float128_lt_quiet( float128 a, float128 b )
    +{
    +
    +    return floatXLt( float128ToFloatX( a ), float128ToFloatX( b ) );
    +
    +}
    +
    +#endif
    +
    diff --git a/tools/test/testfloat/slowfloat.c b/tools/test/testfloat/slowfloat.c
    new file mode 100644
    index 00000000000..ea69f82908e
    --- /dev/null
    +++ b/tools/test/testfloat/slowfloat.c
    @@ -0,0 +1,35 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include "milieu.h"
    +#include "softfloat.h"
    +#include "slowfloat.h"
    +
    +#ifdef BITS64
    +#include "slowfloat-64.c"
    +#else
    +#include "slowfloat-32.c"
    +#endif
    +
    diff --git a/tools/test/testfloat/slowfloat.h b/tools/test/testfloat/slowfloat.h
    new file mode 100644
    index 00000000000..45c6c6be00a
    --- /dev/null
    +++ b/tools/test/testfloat/slowfloat.h
    @@ -0,0 +1,167 @@
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +extern int8 slow_float_rounding_mode;
    +extern int8 slow_float_exception_flags;
    +extern int8 slow_float_detect_tininess;
    +#ifdef FLOATX80
    +extern int8 slow_floatx80_rounding_precision;
    +#endif
    +
    +float32 slow_int32_to_float32( int32 );
    +float64 slow_int32_to_float64( int32 );
    +#ifdef FLOATX80
    +floatx80 slow_int32_to_floatx80( int32 );
    +#endif
    +#ifdef FLOAT128
    +float128 slow_int32_to_float128( int32 );
    +#endif
    +#ifdef BITS64
    +float32 slow_int64_to_float32( int64 );
    +float64 slow_int64_to_float64( int64 );
    +#ifdef FLOATX80
    +floatx80 slow_int64_to_floatx80( int64 );
    +#endif
    +#ifdef FLOAT128
    +float128 slow_int64_to_float128( int64 );
    +#endif
    +#endif
    +
    +int32 slow_float32_to_int32( float32 );
    +int32 slow_float32_to_int32_round_to_zero( float32 );
    +#ifdef BITS64
    +int64 slow_float32_to_int64( float32 );
    +int64 slow_float32_to_int64_round_to_zero( float32 );
    +#endif
    +float64 slow_float32_to_float64( float32 );
    +#ifdef FLOATX80
    +floatx80 slow_float32_to_floatx80( float32 );
    +#endif
    +#ifdef FLOAT128
    +float128 slow_float32_to_float128( float32 );
    +#endif
    +
    +float32 slow_float32_round_to_int( float32 );
    +float32 slow_float32_add( float32, float32 );
    +float32 slow_float32_sub( float32, float32 );
    +float32 slow_float32_mul( float32, float32 );
    +float32 slow_float32_div( float32, float32 );
    +float32 slow_float32_rem( float32, float32 );
    +float32 slow_float32_sqrt( float32 );
    +flag slow_float32_eq( float32, float32 );
    +flag slow_float32_le( float32, float32 );
    +flag slow_float32_lt( float32, float32 );
    +flag slow_float32_eq_signaling( float32, float32 );
    +flag slow_float32_le_quiet( float32, float32 );
    +flag slow_float32_lt_quiet( float32, float32 );
    +
    +int32 slow_float64_to_int32( float64 );
    +int32 slow_float64_to_int32_round_to_zero( float64 );
    +#ifdef BITS64
    +int64 slow_float64_to_int64( float64 );
    +int64 slow_float64_to_int64_round_to_zero( float64 );
    +#endif
    +float32 slow_float64_to_float32( float64 );
    +#ifdef FLOATX80
    +floatx80 slow_float64_to_floatx80( float64 );
    +#endif
    +#ifdef FLOAT128
    +float128 slow_float64_to_float128( float64 );
    +#endif
    +
    +float64 slow_float64_round_to_int( float64 );
    +float64 slow_float64_add( float64, float64 );
    +float64 slow_float64_sub( float64, float64 );
    +float64 slow_float64_mul( float64, float64 );
    +float64 slow_float64_div( float64, float64 );
    +float64 slow_float64_rem( float64, float64 );
    +float64 slow_float64_sqrt( float64 );
    +flag slow_float64_eq( float64, float64 );
    +flag slow_float64_le( float64, float64 );
    +flag slow_float64_lt( float64, float64 );
    +flag slow_float64_eq_signaling( float64, float64 );
    +flag slow_float64_le_quiet( float64, float64 );
    +flag slow_float64_lt_quiet( float64, float64 );
    +
    +#ifdef FLOATX80
    +
    +int32 slow_floatx80_to_int32( floatx80 );
    +int32 slow_floatx80_to_int32_round_to_zero( floatx80 );
    +#ifdef BITS64
    +int64 slow_floatx80_to_int64( floatx80 );
    +int64 slow_floatx80_to_int64_round_to_zero( floatx80 );
    +#endif
    +float32 slow_floatx80_to_float32( floatx80 );
    +float64 slow_floatx80_to_float64( floatx80 );
    +#ifdef FLOAT128
    +float128 slow_floatx80_to_float128( floatx80 );
    +#endif
    +
    +floatx80 slow_floatx80_round_to_int( floatx80 );
    +floatx80 slow_floatx80_add( floatx80, floatx80 );
    +floatx80 slow_floatx80_sub( floatx80, floatx80 );
    +floatx80 slow_floatx80_mul( floatx80, floatx80 );
    +floatx80 slow_floatx80_div( floatx80, floatx80 );
    +floatx80 slow_floatx80_rem( floatx80, floatx80 );
    +floatx80 slow_floatx80_sqrt( floatx80 );
    +flag slow_floatx80_eq( floatx80, floatx80 );
    +flag slow_floatx80_le( floatx80, floatx80 );
    +flag slow_floatx80_lt( floatx80, floatx80 );
    +flag slow_floatx80_eq_signaling( floatx80, floatx80 );
    +flag slow_floatx80_le_quiet( floatx80, floatx80 );
    +flag slow_floatx80_lt_quiet( floatx80, floatx80 );
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +int32 slow_float128_to_int32( float128 );
    +int32 slow_float128_to_int32_round_to_zero( float128 );
    +#ifdef BITS64
    +int64 slow_float128_to_int64( float128 );
    +int64 slow_float128_to_int64_round_to_zero( float128 );
    +#endif
    +float32 slow_float128_to_float32( float128 );
    +float64 slow_float128_to_float64( float128 );
    +#ifdef FLOATX80
    +floatx80 slow_float128_to_floatx80( float128 );
    +#endif
    +
    +float128 slow_float128_round_to_int( float128 );
    +float128 slow_float128_add( float128, float128 );
    +float128 slow_float128_sub( float128, float128 );
    +float128 slow_float128_mul( float128, float128 );
    +float128 slow_float128_div( float128, float128 );
    +float128 slow_float128_rem( float128, float128 );
    +float128 slow_float128_sqrt( float128 );
    +flag slow_float128_eq( float128, float128 );
    +flag slow_float128_le( float128, float128 );
    +flag slow_float128_lt( float128, float128 );
    +flag slow_float128_eq_signaling( float128, float128 );
    +flag slow_float128_le_quiet( float128, float128 );
    +flag slow_float128_lt_quiet( float128, float128 );
    +
    +#endif
    +
    diff --git a/tools/test/testfloat/sparc64/Makefile b/tools/test/testfloat/sparc64/Makefile
    new file mode 100644
    index 00000000000..a24834b8f4e
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/Makefile
    @@ -0,0 +1,105 @@
    +# Copyright (c) 2010 by Peter Jeremy 
    +# All rights reserved.
    +#
    +# Redistribution and use in source and binary forms, with or without
    +# modification, are permitted provided that the following conditions
    +# are met:
    +# 1. Redistributions of source code must retain the above copyright
    +#    notice, this list of conditions and the following disclaimer.
    +# 2. Redistributions in binary form must reproduce the above copyright
    +#    notice, this list of conditions and the following disclaimer in the
    +#    documentation and/or other materials provided with the distribution.
    +#
    +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    +# IN NO EVENT SHALL THE AUTHOR OR 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$
    +
    +.PATH: ${.CURDIR}/../../../../lib/libc/softfloat/bits64 ${.CURDIR}/..
    +
    +LIBC_DIR=	${.CURDIR}/../../../../lib/libc
    +EMUFLOAT_DIR=	${LIBC_DIR}/sparc64/fpu
    +
    +LN=	ln -sf
    +
    +# Common source files
    +SRCS1=	fail.c random.c softfloat.c testCases.c testLoops.c writeHex.c
    +
    +# Additional common sources to build testfloat/testemufloat
    +SRCS2=	testFunction.c testfloat.c
    +
    +# Additional sources to build testemufloat
    +SRCS3=	fpu.c fpu_add.c fpu_compare.c fpu_div.c fpu_emul.S fpu_explode.c \
    +	fpu_implode.c fpu_mul.c fpu_qp.c fpu_sqrt.c fpu_subr.c fpu_util.c
    +
    +# Additional sources to build testfloat
    +SRCS4=	systflags.c systfloat.S systmodes.c
    +
    +# Additional sources to build testsoftfloat
    +SRCS5=	slowfloat.c testsoftfloat.c
    +
    +SRCS=	${SRCS1} ${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5}
    +
    +OBJ_TF=		${SRCS1:R:S/$/.o/g} ${SRCS2:R:S/$/.o/g} ${SRCS4:R:S/$/.o/g}
    +OBJ_TEF=	${SRCS1:R:S/$/.o/g} ${SRCS2:R:S/$/.o/g} ${SRCS3:R:S/$/.o/g}
    +OBJ_TSF=	${SRCS1:R:S/$/.o/g} ${SRCS5:R:S/$/.o/g}
    +
    +all: testfloat testemufloat testsoftfloat
    +
    +CFLAGS+=	-I. -I${.CURDIR} -I${.CURDIR}/.. -I${LIBC_DIR}/sparc64/fpu \
    +	-I${LIBC_DIR}/sparc64/sys -I${LIBC_DIR}/softfloat/bits64 \
    +	-I${LIBC_DIR}/softfloat
    +
    +CLEANFILES+=	fpu.c fpu_add.c fpu_compare.c fpu_div.c fpu_emu.h \
    +	fpu_explode.c fpu_implode.c fpu_mul.c fpu_qp.c fpu_sqrt.c fpu_subr.c \
    +	${SRCS:R:S/$/.o/g} testfloat testemufloat testsoftfloat
    +
    +testsoftfloat: ${OBJ_TSF}
    +	${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJ_TSF}
    +
    +testfloat: ${OBJ_TF}
    +	${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJ_TF}
    +
    +testemufloat: ${OBJ_TEF}
    +	${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJ_TEF}
    +
    +beforedepend: fpu_emu.h
    +
    +# The emulator code needs to be built with a local fpu_reg.h instead of
    +# the one in ${EMUFLOAT_DIR}.  Unfortunately, C preprocessor semantics
    +# means that a header file in the same directory as the source file
    +# overrides any alternative header file location.  In order to include
    +# the wanted header file, create symlinks pointing to the real files
    +# and compile through the symlink.
    +fpu.c: ${EMUFLOAT_DIR}/fpu.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_add.c: ${EMUFLOAT_DIR}/fpu_add.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_compare.c: ${EMUFLOAT_DIR}/fpu_compare.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_div.c: ${EMUFLOAT_DIR}/fpu_div.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_emu.h: ${EMUFLOAT_DIR}/fpu_emu.h
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_explode.c: ${EMUFLOAT_DIR}/fpu_explode.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_implode.c: ${EMUFLOAT_DIR}/fpu_implode.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_mul.c: ${EMUFLOAT_DIR}/fpu_mul.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_qp.c: ${EMUFLOAT_DIR}/fpu_qp.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_sqrt.c: ${EMUFLOAT_DIR}/fpu_sqrt.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +fpu_subr.c: ${EMUFLOAT_DIR}/fpu_subr.c
    +	${LN} ${.ALLSRC} ${.TARGET}
    +
    +.include 
    diff --git a/tools/test/testfloat/sparc64/fpu_emul.S b/tools/test/testfloat/sparc64/fpu_emul.S
    new file mode 100644
    index 00000000000..0872e8930c0
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/fpu_emul.S
    @@ -0,0 +1,186 @@
    +/*-
    + * Copyright (c) 2010 by Peter Jeremy 
    + * All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    + * IN NO EVENT SHALL THE AUTHOR OR 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$");
    +
    +	.section	"rodata1",#alloc
    +	.align	8
    +
    +	.global	insn_int32_to_float32
    +insn_int32_to_float32:
    +	fitos	%f0,%f0
    +
    +	.global	insn_int32_to_float64
    +insn_int32_to_float64:
    +	fitod	%f0,%f0
    +
    +	.global	insn_int32_to_float128
    +insn_int32_to_float128:
    +	fitoq	%f0,%f0
    +
    +	.global	insn_int64_to_float32
    +insn_int64_to_float32:
    +	fxtos	%f0,%f0
    +
    +	.global	insn_int64_to_float64
    +insn_int64_to_float64:
    +	fxtod	%f0,%f0
    +
    +	.global	insn_int64_to_float128
    +insn_int64_to_float128:
    +	fxtoq	%f0,%f0
    +
    +	.global	insn_float32_to_int32_round_to_zero
    +insn_float32_to_int32_round_to_zero:
    +	fstoi	%f0,%f0
    +
    +	.global	insn_float32_to_int64_round_to_zero
    +insn_float32_to_int64_round_to_zero:
    +	fstox	%f0,%f0
    +
    +	.global	insn_float32_to_float64
    +insn_float32_to_float64:
    +	fstod	%f0,%f0
    +
    +	.global	insn_float32_to_float128
    +insn_float32_to_float128:
    +	fstoq	%f0,%f0
    +
    +	.global	insn_float32_add
    +insn_float32_add:
    +	fadds	%f0,%f1,%f0
    +
    +	.global	insn_float32_sub
    +insn_float32_sub:
    +	fsubs	%f0,%f1,%f0
    +
    +	.global	insn_float32_mul
    +insn_float32_mul:
    +	fmuls	%f0,%f1,%f0
    +
    +	.global	insn_float32_div
    +insn_float32_div:
    +	fdivs	%f0,%f1,%f0
    +
    +	.global	insn_float32_sqrt
    +insn_float32_sqrt:
    +	fsqrts	%f0,%f0
    +
    +	.global	insn_float32_cmp
    +insn_float32_cmp:
    +	fcmps	%fcc0,%f0,%f1
    +
    +	.global	insn_float32_cmpe
    +insn_float32_cmpe:
    +	fcmpes	%fcc0,%f0,%f1
    +
    +	.global	insn_float64_to_int32_round_to_zero
    +insn_float64_to_int32_round_to_zero:
    +	fdtoi	%f0,%f0
    +
    +	.global	insn_float64_to_int64_round_to_zero
    +insn_float64_to_int64_round_to_zero:
    +	fdtox	%f0,%f0
    +
    +	.global	insn_float64_to_float32
    +insn_float64_to_float32:
    +	fdtos	%f0,%f0
    +
    +	.global	insn_float64_to_float128
    +insn_float64_to_float128:
    +	fdtoq	%f0,%f0
    +
    +	.global	insn_float64_add
    +insn_float64_add:
    +	faddd	%f0,%f2,%f0
    +
    +	.global	insn_float64_sub
    +insn_float64_sub:
    +	fsubd	%f0,%f2,%f0
    +
    +	.global	insn_float64_mul
    +insn_float64_mul:
    +	fmuld	%f0,%f2,%f0
    +
    +	.global	insn_float64_div
    +insn_float64_div:
    +	fdivd	%f0,%f2,%f0
    +
    +	.global	insn_float64_sqrt
    +insn_float64_sqrt:
    +	fsqrtd	%f0,%f0
    +
    +	.global	insn_float64_cmp
    +insn_float64_cmp:
    +	fcmpd	%fcc0,%f0,%f2
    +
    +	.global	insn_float64_cmpe
    +insn_float64_cmpe:
    +	fcmped	%fcc0,%f0,%f2
    +
    +	.global	insn_float128_to_int32_round_to_zero
    +insn_float128_to_int32_round_to_zero:
    +	fqtoi	%f0,%f0
    +
    +	.global	insn_float128_to_int64_round_to_zero
    +insn_float128_to_int64_round_to_zero:
    +	fqtox	%f0,%f0
    +
    +	.global	insn_float128_to_float32
    +insn_float128_to_float32:
    +	fqtos	%f0,%f0
    +
    +	.global	insn_float128_to_float64
    +insn_float128_to_float64:
    +	fqtod	%f0,%f0
    +
    +	.global	insn_float128_add
    +insn_float128_add:
    +	faddq	%f0,%f4,%f0
    +
    +	.global	insn_float128_sub
    +insn_float128_sub:
    +	fsubq	%f0,%f4,%f0
    +
    +	.global	insn_float128_mul
    +insn_float128_mul:
    +	fmulq	%f0,%f4,%f0
    +
    +	.global	insn_float128_div
    +insn_float128_div:
    +	fdivq	%f0,%f4,%f0
    +
    +	.global	insn_float128_sqrt
    +insn_float128_sqrt:
    +	fsqrtq	%f0,%f0
    +
    +	.global	insn_float128_cmp
    +insn_float128_cmp:
    +	fcmpq	%fcc0,%f0,%f4
    +
    +	.global	insn_float128_cmpe
    +insn_float128_cmpe:
    +	fcmpeq	%fcc0,%f0,%f4
    diff --git a/tools/test/testfloat/sparc64/fpu_reg.h b/tools/test/testfloat/sparc64/fpu_reg.h
    new file mode 100644
    index 00000000000..76f7244dd0b
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/fpu_reg.h
    @@ -0,0 +1,63 @@
    +/*-
    + * Copyright (c) 2010 by Peter Jeremy 
    + * All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    + * IN NO EVENT SHALL THE AUTHOR OR 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 _TESTFLOAT_SPARC64_FPU_REG_H_
    +#define	_TESTFLOAT_SPARC64_FPU_REG_H_
    +
    +#include 
    +extern u_int32_t __fpreg[64];
    +
    +static __inline u_int32_t
    +__fpu_getreg(int r)
    +{
    +
    +	return (__fpreg[r]);
    +}
    +
    +static __inline u_int64_t
    +__fpu_getreg64(int r)
    +{
    +
    +	return ((u_int64_t)__fpreg[r] << 32 | (u_int64_t)__fpreg[r + 1]);
    +}
    +
    +static __inline void
    +__fpu_setreg(int r, u_int32_t v)
    +{
    +
    +	__fpreg[r] = v;
    +}
    +
    +static __inline void
    +__fpu_setreg64(int r, u_int64_t v)
    +{
    +
    +	__fpreg[r] = (u_int32_t)(v >> 32);
    +	__fpreg[r + 1] = (u_int32_t)v;
    +}
    +
    +#endif /* _TESTFLOAT_SPARC64_FPU_REG_H_ */
    diff --git a/tools/test/testfloat/sparc64/fpu_util.c b/tools/test/testfloat/sparc64/fpu_util.c
    new file mode 100644
    index 00000000000..1b766e0320a
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/fpu_util.c
    @@ -0,0 +1,706 @@
    +/*-
    + * Copyright (c) 2010 by Peter Jeremy 
    + * All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    + * IN NO EVENT SHALL THE AUTHOR OR 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 "__sparc_utrap_private.h"
    +#include "fpu_extern.h"
    +#include "fpu_reg.h"
    +
    +static u_long	ireg[32];
    +
    +void
    +__utrap_panic(const char *msg)
    +{
    +
    +	fprintf(stderr, "panic: %s\n", msg);
    +	exit(1);
    +}
    +
    +void __utrap_write(const char *msg)
    +{
    +
    +	fprintf(stderr, "%s", msg);
    +}
    +
    +u_long
    +__emul_fetch_reg(struct utrapframe *uf, int reg)
    +{
    +
    +	return (ireg[reg]);
    +}
    +
    +typedef unsigned char int8;
    +typedef unsigned int int32;
    +typedef unsigned long int64;
    +typedef unsigned int float32;
    +typedef unsigned long float64;
    +typedef struct {
    +	unsigned long high, low;
    +} float128;
    +typedef unsigned long flag;
    +
    +struct utrapframe utf;
    +
    +u_int32_t __fpreg[64];
    +
    +static __inline float128
    +__fpu_getreg128(int r)
    +{
    +	float128 v;
    +
    +	v.high = ((u_int64_t)__fpreg[r] << 32 | (u_int64_t)__fpreg[r + 1]);
    +	v.low = ((u_int64_t)__fpreg[r + 2] << 32 | (u_int64_t)__fpreg[r + 3]);
    +	return (v);
    +}
    +
    +static __inline void
    +__fpu_setreg128(int r, float128 v)
    +{
    +
    +	__fpreg[r] = (u_int32_t)(v.high >> 32);
    +	__fpreg[r + 1] = (u_int32_t)v.high;
    +	__fpreg[r + 2] = (u_int32_t)(v.low >> 32);
    +	__fpreg[r + 3] = (u_int32_t)v.low;
    +}
    +
    +/*
    +-------------------------------------------------------------------------------
    +Clears the system's IEC/IEEE floating-point exception flags.  Returns the
    +previous value of the flags.
    +-------------------------------------------------------------------------------
    +*/
    +#include 
    +#include 
    +
    +int8 syst_float_flags_clear(void)
    +{
    +	int32 flags;
    +
    +	flags = (utf.uf_fsr & FE_ALL_EXCEPT) >> 5;
    +	utf.uf_fsr &= ~(u_long)FE_ALL_EXCEPT;
    +	return (flags);
    +}
    +
    +static void
    +emul_trap(const u_int *insn, u_long mask)
    +{
    +	u_int32_t savreg[64];
    +	int i;
    +
    +	for (i = 0; i < 64; i++)
    +	    savreg[i] = __fpreg[i];
    +
    +	utf.uf_fsr = (utf.uf_fsr & ~FSR_FTT_MASK) |
    +		(FSR_FTT_UNFIN << FSR_FTT_SHIFT);
    +	utf.uf_pc = (u_long)insn;
    +	if (__fpu_exception(&utf) == 0)
    +	    __asm("stx %%fsr,%0" : "=m" (utf.uf_fsr));
    +	
    +	for (i = 0; i < 64; i++) {
    +		if (!(mask & (1UL << i)) && savreg[i] != __fpreg[i]) {
    +			fprintf(stderr, "### %2d %08x != %08x\n",
    +			    i, savreg[i], __fpreg[i]);
    +		}
    +	}
    +}
    +
    +extern u_int insn_int32_to_float32;
    +extern u_int insn_int32_to_float64;
    +extern u_int insn_int32_to_float128;
    +extern u_int insn_int64_to_float32;
    +extern u_int insn_int64_to_float64;
    +extern u_int insn_int64_to_float128;
    +extern u_int insn_float32_to_int32_round_to_zero;
    +extern u_int insn_float32_to_int64_round_to_zero;
    +extern u_int insn_float32_to_float64;
    +extern u_int insn_float32_to_float128;
    +extern u_int insn_float32_add;
    +extern u_int insn_float32_sub;
    +extern u_int insn_float32_mul;
    +extern u_int insn_float32_div;
    +extern u_int insn_float32_sqrt;
    +extern u_int insn_float32_cmp;
    +extern u_int insn_float32_cmpe;
    +extern u_int insn_float64_to_int32_round_to_zero;
    +extern u_int insn_float64_to_int64_round_to_zero;
    +extern u_int insn_float64_to_float32;
    +extern u_int insn_float64_to_float128;
    +extern u_int insn_float64_add;
    +extern u_int insn_float64_sub;
    +extern u_int insn_float64_mul;
    +extern u_int insn_float64_div;
    +extern u_int insn_float64_sqrt;
    +extern u_int insn_float64_cmp;
    +extern u_int insn_float64_cmpe;
    +extern u_int insn_float128_to_int32_round_to_zero;
    +extern u_int insn_float128_to_int64_round_to_zero;
    +extern u_int insn_float128_to_float32;
    +extern u_int insn_float128_to_float64;
    +extern u_int insn_float128_add;
    +extern u_int insn_float128_sub;
    +extern u_int insn_float128_mul;
    +extern u_int insn_float128_div;
    +extern u_int insn_float128_sqrt;
    +extern u_int insn_float128_cmp;
    +extern u_int insn_float128_cmpe;
    +
    +float32
    +syst_int32_to_float32(int32 a)
    +{
    +
    +	__fpu_setreg(0, a);
    +	emul_trap(&insn_int32_to_float32, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +float64
    +syst_int32_to_float64(int32 a)
    +{
    +
    +	__fpu_setreg(0, a);
    +	emul_trap(&insn_int32_to_float64, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float128
    +syst_int32_to_float128(int32 a)
    +{
    +
    +	__fpu_setreg(0, a);
    +	emul_trap(&insn_int32_to_float128, 0xfUL);
    +	return (__fpu_getreg128(0));
    +}
    +
    +float32
    +syst_int64_to_float32(int64 a)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	emul_trap(&insn_int64_to_float32, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +float64
    +syst_int64_to_float64(int64 a)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	emul_trap(&insn_int64_to_float64, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +
    +float128
    +syst_int64_to_float128(int64 a)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	emul_trap(&insn_int64_to_float128, 0xfUL);
    +	return (__fpu_getreg128(0));
    +}
    +
    +int32
    +syst_float32_to_int32_round_to_zero(float32 a)
    +{
    +
    +	__fpu_setreg(0, a);
    +	emul_trap(&insn_float32_to_int32_round_to_zero, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +int64
    +syst_float32_to_int64_round_to_zero(float32 a)
    +{
    +
    +	__fpu_setreg(0, a);
    +	emul_trap(&insn_float32_to_int64_round_to_zero, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float64
    +syst_float32_to_float64(float32 a)
    +{
    +
    +	__fpu_setreg(0, a);
    +	emul_trap(&insn_float32_to_float64, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float128
    +syst_float32_to_float128(float32 a)
    +{
    +
    +	__fpu_setreg(0, a);
    +	emul_trap(&insn_float32_to_float128, 0xfUL);
    +	return (__fpu_getreg128(0));
    +}
    +
    +float32
    +syst_float32_add(float32 a, float32 b)
    +{
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_add, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +float32
    +syst_float32_sub(float32 a, float32 b)
    +{
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_sub, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +float32
    +syst_float32_mul(float32 a, float32 b)
    +{
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_mul, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +float32
    +syst_float32_div(float32 a, float32 b)
    +{
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_div, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +float32
    +syst_float32_sqrt(float32 a)
    +{
    +
    +	__fpu_setreg(0, a);
    +	emul_trap(&insn_float32_sqrt, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +flag syst_float32_eq(float32 a, float32 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_cmp, 0x0UL);
    +	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float32_le(float32 a, float32 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_cmpe, 0x0UL);
    +	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float32_lt(float32 a, float32 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_cmpe, 0x0UL);
    +	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float32_eq_signaling(float32 a, float32 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_cmpe, 0x0UL);
    +	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float32_le_quiet(float32 a, float32 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_cmp, 0x0UL);
    +	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float32_lt_quiet(float32 a, float32 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg(0, a);
    +	__fpu_setreg(1, b);
    +	emul_trap(&insn_float32_cmp, 0x0UL);
    +	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +int32
    +syst_float64_to_int32_round_to_zero(float64 a)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	emul_trap(&insn_float64_to_int32_round_to_zero, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +int64
    +syst_float64_to_int64_round_to_zero(float64 a)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	emul_trap(&insn_float64_to_int64_round_to_zero, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float32
    +syst_float64_to_float32(float64 a)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	emul_trap(&insn_float64_to_float32, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +float128
    +syst_float64_to_float128(float64 a)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	emul_trap(&insn_float64_to_float128, 0xfUL);
    +	return (__fpu_getreg128(0));
    +}
    +
    +float64
    +syst_float64_add(float64 a, float64 b)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_add, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float64
    +syst_float64_sub(float64 a, float64 b)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_sub, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float64
    +syst_float64_mul(float64 a, float64 b)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_mul, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float64
    +syst_float64_div(float64 a, float64 b)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_div, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float64
    +syst_float64_sqrt(float64 a)
    +{
    +
    +	__fpu_setreg64(0, a);
    +	emul_trap(&insn_float64_sqrt, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +flag syst_float64_eq(float64 a, float64 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_cmp, 0x0UL);
    +	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float64_le(float64 a, float64 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_cmpe, 0x0UL);
    +	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float64_lt(float64 a, float64 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_cmpe, 0x0UL);
    +	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float64_eq_signaling(float64 a, float64 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_cmpe, 0x0UL);
    +	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float64_le_quiet(float64 a, float64 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_cmp, 0x0UL);
    +	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float64_lt_quiet(float64 a, float64 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg64(0, a);
    +	__fpu_setreg64(2, b);
    +	emul_trap(&insn_float64_cmp, 0x0UL);
    +	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +int32
    +syst_float128_to_int32_round_to_zero(float128 a)
    +{
    +
    +	__fpu_setreg128(0, a);
    +	emul_trap(&insn_float128_to_int32_round_to_zero, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +int64
    +syst_float128_to_int64_round_to_zero(float128 a)
    +{
    +
    +	__fpu_setreg128(0, a);
    +	emul_trap(&insn_float128_to_int64_round_to_zero, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float32
    +syst_float128_to_float32(float128 a)
    +{
    +
    +	__fpu_setreg128(0, a);
    +	emul_trap(&insn_float128_to_float32, 0x1UL);
    +	return (__fpu_getreg(0));
    +}
    +
    +float64
    +syst_float128_to_float64(float128 a)
    +{
    +
    +	__fpu_setreg128(0, a);
    +	emul_trap(&insn_float128_to_float64, 0x3UL);
    +	return (__fpu_getreg64(0));
    +}
    +
    +float128
    +syst_float128_add(float128 a, float128 b)
    +{
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_add, 0xfUL);
    +	return (__fpu_getreg128(0));
    +}
    +
    +float128
    +syst_float128_sub(float128 a, float128 b)
    +{
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_sub, 0xfUL);
    +	return (__fpu_getreg128(0));
    +}
    +
    +float128
    +syst_float128_mul(float128 a, float128 b)
    +{
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_mul, 0xfUL);
    +	return (__fpu_getreg128(0));
    +}
    +
    +float128
    +syst_float128_div(float128 a, float128 b)
    +{
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_div, 0xfUL);
    +	return (__fpu_getreg128(0));
    +}
    +
    +float128
    +syst_float128_sqrt(float128 a)
    +{
    +
    +	__fpu_setreg128(0, a);
    +	emul_trap(&insn_float128_sqrt, 0xfUL);
    +	return (__fpu_getreg128(0));
    +}
    +
    +flag syst_float128_eq(float128 a, float128 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_cmp, 0x0UL);
    +	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float128_le(float128 a, float128 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_cmpe, 0x0UL);
    +	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float128_lt(float128 a, float128 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_cmpe, 0x0UL);
    +	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float128_eq_signaling(float128 a, float128 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_cmpe, 0x0UL);
    +	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float128_le_quiet(float128 a, float128 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_cmp, 0x0UL);
    +	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +flag syst_float128_lt_quiet(float128 a, float128 b)
    +{
    +	u_long r;
    +
    +	__fpu_setreg128(0, a);
    +	__fpu_setreg128(4, b);
    +	emul_trap(&insn_float128_cmp, 0x0UL);
    +	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
    +	return (r);
    +}
    +
    +
    +/*
    +-------------------------------------------------------------------------------
    +Sets the system's IEC/IEEE floating-point rounding mode.
    +-------------------------------------------------------------------------------
    +*/
    +void syst_float_set_rounding_mode(int8 roundingMode)
    +{
    +
    +	utf.uf_fsr &= ~FSR_RD_MASK;
    +	utf.uf_fsr |= FSR_RD((unsigned int)roundingMode & 0x03);
    +}
    +
    +/*
    +-------------------------------------------------------------------------------
    +Does nothing.
    +-------------------------------------------------------------------------------
    +*/
    +void syst_float_set_rounding_precision(int8 precision)
    +{
    +
    +}
    diff --git a/tools/test/testfloat/sparc64/libc_private.h b/tools/test/testfloat/sparc64/libc_private.h
    new file mode 100644
    index 00000000000..5e7d1bc431b
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/libc_private.h
    @@ -0,0 +1,30 @@
    +/*-
    + * Copyright (c) 2010 by Peter Jeremy 
    + * All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    + * IN NO EVENT SHALL THE AUTHOR OR 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$
    + */
    +/*
    + * This file has no content and is solely to satisfy a #include in
    + * the FP emulator code.
    + */
    diff --git a/tools/test/testfloat/sparc64/milieu.h b/tools/test/testfloat/sparc64/milieu.h
    new file mode 100644
    index 00000000000..26491d16756
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/milieu.h
    @@ -0,0 +1,56 @@
    +#ifndef TESTFLOAT_SPARC64_MILIEU_H_
    +#define	TESTFLOAT_SPARC64_MILIEU_H_
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +/* $FreeBSD$ */
    +
    +/*
    +-------------------------------------------------------------------------------
    +Include common integer types and flags.
    +-------------------------------------------------------------------------------
    +*/
    +#include "sparc64.h"
    +
    +/*
    +-------------------------------------------------------------------------------
    +If the `BITS64' macro is defined by the processor header file but the
    +version of SoftFloat being used/tested is the 32-bit one (`bits32'), the
    +`BITS64' macro must be undefined here.
    +-------------------------------------------------------------------------------
    +#undef BITS64
    +*/
    +
    +/*
    +-------------------------------------------------------------------------------
    +Symbolic Boolean literals.
    +-------------------------------------------------------------------------------
    +*/
    +enum {
    +    FALSE = 0,
    +    TRUE  = 1
    +};
    +
    +#endif
    diff --git a/tools/test/testfloat/sparc64/namespace.h b/tools/test/testfloat/sparc64/namespace.h
    new file mode 100644
    index 00000000000..5e7d1bc431b
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/namespace.h
    @@ -0,0 +1,30 @@
    +/*-
    + * Copyright (c) 2010 by Peter Jeremy 
    + * All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    + * IN NO EVENT SHALL THE AUTHOR OR 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$
    + */
    +/*
    + * This file has no content and is solely to satisfy a #include in
    + * the FP emulator code.
    + */
    diff --git a/tools/test/testfloat/sparc64/softfloat.h b/tools/test/testfloat/sparc64/softfloat.h
    new file mode 100644
    index 00000000000..f804b9cb82c
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/softfloat.h
    @@ -0,0 +1,267 @@
    +#ifndef TESTFLOAT_SPARC64_SOFTFLOAT_H
    +#define	TESTFLOAT_SPARC64_SOFTFLOAT_H
    +
    +/*============================================================================
    +
    +This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
    +Package, Release 2b.
    +
    +Written by John R. Hauser.  This work was made possible in part by the
    +International Computer Science Institute, located at Suite 600, 1947 Center
    +Street, Berkeley, California 94704.  Funding was partially provided by the
    +National Science Foundation under grant MIP-9311980.  The original version
    +of this code was written as part of a project to build a fixed-point vector
    +processor in collaboration with the University of California at Berkeley,
    +overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
    +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
    +arithmetic/SoftFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
    +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
    +RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
    +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
    +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
    +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
    +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
    +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) the source code for the derivative work includes prominent notice that
    +the work is derivative, and (2) the source code includes prominent notice with
    +these four paragraphs for those parts of this code that are retained.
    +
    +=============================================================================*/
    +
    +/* $FreeBSD$ */
    +
    +#include 
    +
    +/*----------------------------------------------------------------------------
    +| The macro `FLOATX80' must be defined to enable the extended double-precision
    +| floating-point format `floatx80'.  If this macro is not defined, the
    +| `floatx80' type will not be defined, and none of the functions that either
    +| input or output the `floatx80' type will be defined.  The same applies to
    +| the `FLOAT128' macro and the quadruple-precision format `float128'.
    +*----------------------------------------------------------------------------*/
    +#define FLOATX80
    +#define FLOAT128
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE floating-point types.
    +*----------------------------------------------------------------------------*/
    +typedef unsigned int float32;
    +typedef unsigned long float64;
    +#ifdef FLOATX80
    +typedef struct {
    +    unsigned short high;
    +    unsigned long low;
    +} floatx80;
    +#endif
    +#ifdef FLOAT128
    +typedef struct {
    +    unsigned long high, low;
    +} float128;
    +#endif
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE floating-point underflow tininess-detection mode.
    +*----------------------------------------------------------------------------*/
    +extern int float_detect_tininess;
    +enum {
    +    float_tininess_after_rounding  = 0,
    +    float_tininess_before_rounding = 1
    +};
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE floating-point rounding mode.
    +*----------------------------------------------------------------------------*/
    +extern fp_rnd_t float_rounding_mode;
    +enum {
    +    float_round_nearest_even = 0,
    +    float_round_to_zero      = 1,
    +    float_round_up           = 2,
    +    float_round_down         = 3
    +};
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE floating-point exception flags.
    +*----------------------------------------------------------------------------*/
    +typedef int fp_except;
    +extern fp_except float_exception_flags;
    +enum {
    +    float_flag_inexact   =  1,
    +    float_flag_divbyzero =  2,
    +    float_flag_underflow =  4,
    +    float_flag_overflow  =  8,
    +    float_flag_invalid   = 16
    +};
    +
    +/*----------------------------------------------------------------------------
    +| Routine to raise any or all of the software IEC/IEEE floating-point
    +| exception flags.
    +*----------------------------------------------------------------------------*/
    +void float_raise( int );
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE integer-to-floating-point conversion routines.
    +*----------------------------------------------------------------------------*/
    +float32 int32_to_float32( int );
    +float64 int32_to_float64( int );
    +#ifdef FLOATX80
    +floatx80 int32_to_floatx80( int );
    +#endif
    +#ifdef FLOAT128
    +float128 int32_to_float128( int );
    +#endif
    +float32 int64_to_float32( long );
    +float64 int64_to_float64( long );
    +#ifdef FLOATX80
    +floatx80 int64_to_floatx80( long );
    +#endif
    +#ifdef FLOAT128
    +float128 int64_to_float128( long );
    +#endif
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE single-precision conversion routines.
    +*----------------------------------------------------------------------------*/
    +int float32_to_int32( float32 );
    +int float32_to_int32_round_to_zero( float32 );
    +long float32_to_int64( float32 );
    +long float32_to_int64_round_to_zero( float32 );
    +float64 float32_to_float64( float32 );
    +#ifdef FLOATX80
    +floatx80 float32_to_floatx80( float32 );
    +#endif
    +#ifdef FLOAT128
    +float128 float32_to_float128( float32 );
    +#endif
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE single-precision operations.
    +*----------------------------------------------------------------------------*/
    +float32 float32_round_to_int( float32 );
    +float32 float32_add( float32, float32 );
    +float32 float32_sub( float32, float32 );
    +float32 float32_mul( float32, float32 );
    +float32 float32_div( float32, float32 );
    +float32 float32_rem( float32, float32 );
    +float32 float32_sqrt( float32 );
    +int float32_eq( float32, float32 );
    +int float32_le( float32, float32 );
    +int float32_lt( float32, float32 );
    +int float32_eq_signaling( float32, float32 );
    +int float32_le_quiet( float32, float32 );
    +int float32_lt_quiet( float32, float32 );
    +int float32_is_signaling_nan( float32 );
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE double-precision conversion routines.
    +*----------------------------------------------------------------------------*/
    +int float64_to_int32( float64 );
    +int float64_to_int32_round_to_zero( float64 );
    +long float64_to_int64( float64 );
    +long float64_to_int64_round_to_zero( float64 );
    +float32 float64_to_float32( float64 );
    +#ifdef FLOATX80
    +floatx80 float64_to_floatx80( float64 );
    +#endif
    +#ifdef FLOAT128
    +float128 float64_to_float128( float64 );
    +#endif
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE double-precision operations.
    +*----------------------------------------------------------------------------*/
    +float64 float64_round_to_int( float64 );
    +float64 float64_add( float64, float64 );
    +float64 float64_sub( float64, float64 );
    +float64 float64_mul( float64, float64 );
    +float64 float64_div( float64, float64 );
    +float64 float64_rem( float64, float64 );
    +float64 float64_sqrt( float64 );
    +int float64_eq( float64, float64 );
    +int float64_le( float64, float64 );
    +int float64_lt( float64, float64 );
    +int float64_eq_signaling( float64, float64 );
    +int float64_le_quiet( float64, float64 );
    +int float64_lt_quiet( float64, float64 );
    +int float64_is_signaling_nan( float64 );
    +
    +#ifdef FLOATX80
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE extended double-precision conversion routines.
    +*----------------------------------------------------------------------------*/
    +int floatx80_to_int32( floatx80 );
    +int floatx80_to_int32_round_to_zero( floatx80 );
    +long floatx80_to_int64( floatx80 );
    +long floatx80_to_int64_round_to_zero( floatx80 );
    +float32 floatx80_to_float32( floatx80 );
    +float64 floatx80_to_float64( floatx80 );
    +#ifdef FLOAT128
    +float128 floatx80_to_float128( floatx80 );
    +#endif
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE extended double-precision rounding precision.  Valid
    +| values are 32, 64, and 80.
    +*----------------------------------------------------------------------------*/
    +extern int floatx80_rounding_precision;
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE extended double-precision operations.
    +*----------------------------------------------------------------------------*/
    +floatx80 floatx80_round_to_int( floatx80 );
    +floatx80 floatx80_add( floatx80, floatx80 );
    +floatx80 floatx80_sub( floatx80, floatx80 );
    +floatx80 floatx80_mul( floatx80, floatx80 );
    +floatx80 floatx80_div( floatx80, floatx80 );
    +floatx80 floatx80_rem( floatx80, floatx80 );
    +floatx80 floatx80_sqrt( floatx80 );
    +int floatx80_eq( floatx80, floatx80 );
    +int floatx80_le( floatx80, floatx80 );
    +int floatx80_lt( floatx80, floatx80 );
    +int floatx80_eq_signaling( floatx80, floatx80 );
    +int floatx80_le_quiet( floatx80, floatx80 );
    +int floatx80_lt_quiet( floatx80, floatx80 );
    +int floatx80_is_signaling_nan( floatx80 );
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE quadruple-precision conversion routines.
    +*----------------------------------------------------------------------------*/
    +int float128_to_int32( float128 );
    +int float128_to_int32_round_to_zero( float128 );
    +long float128_to_int64( float128 );
    +long float128_to_int64_round_to_zero( float128 );
    +float32 float128_to_float32( float128 );
    +float64 float128_to_float64( float128 );
    +#ifdef FLOATX80
    +floatx80 float128_to_floatx80( float128 );
    +#endif
    +
    +/*----------------------------------------------------------------------------
    +| Software IEC/IEEE quadruple-precision operations.
    +*----------------------------------------------------------------------------*/
    +float128 float128_round_to_int( float128 );
    +float128 float128_add( float128, float128 );
    +float128 float128_sub( float128, float128 );
    +float128 float128_mul( float128, float128 );
    +float128 float128_div( float128, float128 );
    +float128 float128_rem( float128, float128 );
    +float128 float128_sqrt( float128 );
    +int float128_eq( float128, float128 );
    +int float128_le( float128, float128 );
    +int float128_lt( float128, float128 );
    +int float128_eq_signaling( float128, float128 );
    +int float128_le_quiet( float128, float128 );
    +int float128_lt_quiet( float128, float128 );
    +int float128_is_signaling_nan( float128 );
    +
    +#endif
    +
    +#endif
    diff --git a/tools/test/testfloat/sparc64/sparc64.h b/tools/test/testfloat/sparc64/sparc64.h
    new file mode 100644
    index 00000000000..959a78cb675
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/sparc64.h
    @@ -0,0 +1,93 @@
    +/*-
    + * Copyright (c) 2010 by Peter Jeremy 
    + * All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    + * IN NO EVENT SHALL THE AUTHOR OR 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$
    + */
    +
    +/*----------------------------------------------------------------------------
    +| One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
    +*----------------------------------------------------------------------------*/
    +#define BIGENDIAN
    +
    +/*----------------------------------------------------------------------------
    +| The macro `BITS64' can be defined to indicate that 64-bit integer types are
    +| supported by the compiler.
    +*----------------------------------------------------------------------------*/
    +#define BITS64
    +
    +/*----------------------------------------------------------------------------
    +| Each of the following `typedef's defines the most convenient type that holds
    +| integers of at least as many bits as specified.  For example, `uint8' should
    +| be the most convenient type that can hold unsigned integers of as many as
    +| 8 bits.  The `flag' type must be able to hold either a 0 or 1.  For most
    +| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
    +| to the same as `int'.
    +*----------------------------------------------------------------------------*/
    +typedef int flag;
    +typedef int uint8;
    +typedef int int8;
    +typedef int uint16;
    +typedef int int16;
    +typedef unsigned int uint32;
    +typedef signed int int32;
    +#ifdef BITS64
    +typedef unsigned long int uint64;
    +typedef signed long int int64;
    +#endif
    +
    +/*----------------------------------------------------------------------------
    +| Each of the following `typedef's defines a type that holds integers
    +| of _exactly_ the number of bits specified.  For instance, for most
    +| implementation of C, `bits16' and `sbits16' should be `typedef'ed to
    +| `unsigned short int' and `signed short int' (or `short int'), respectively.
    +*----------------------------------------------------------------------------*/
    +typedef unsigned char bits8;
    +typedef signed char sbits8;
    +typedef unsigned short int bits16;
    +typedef signed short int sbits16;
    +typedef unsigned int bits32;
    +typedef signed int sbits32;
    +#ifdef BITS64
    +typedef unsigned long int bits64;
    +typedef signed long int sbits64;
    +#endif
    +
    +#ifdef BITS64
    +/*----------------------------------------------------------------------------
    +| The `LIT64' macro takes as its argument a textual integer literal and
    +| if necessary ``marks'' the literal as having a 64-bit integer type.
    +| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
    +| appended with the letters `LL' standing for `long long', which is `gcc's
    +| name for the 64-bit integer type.  Some compilers may allow `LIT64' to be
    +| defined as the identity macro:  `#define LIT64( a ) a'.
    +*----------------------------------------------------------------------------*/
    +#define LIT64( a ) a##L
    +#endif
    +
    +/*----------------------------------------------------------------------------
    +| The macro `INLINE' can be used before functions that should be inlined.  If
    +| a compiler does not support explicit inlining, this macro should be defined
    +| to be `static'.
    +*----------------------------------------------------------------------------*/
    +#define INLINE extern inline
    diff --git a/tools/test/testfloat/sparc64/systflags.c b/tools/test/testfloat/sparc64/systflags.c
    new file mode 100644
    index 00000000000..9187facc830
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/systflags.c
    @@ -0,0 +1,73 @@
    +/*-
    + * Copyright (c) 2010 by Peter Jeremy 
    + * All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    + * IN NO EVENT SHALL THE AUTHOR OR 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.
    + */
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#pragma STDC FENV_ACCESS ON
    +#include 
    +#include 
    +#include "milieu.h"
    +#include "systflags.h"
    +
    +/*
    +-------------------------------------------------------------------------------
    +Clears the system's IEC/IEEE floating-point exception flags.  Returns the
    +previous value of the flags.
    +-------------------------------------------------------------------------------
    +*/
    +int8 syst_float_flags_clear( void )
    +{
    +    fexcept_t flags;
    +
    +    fegetexceptflag(&flags, FE_ALL_EXCEPT);
    +    feclearexcept(FE_ALL_EXCEPT);
    +    return (flags >> 5);
    +}
    +
    diff --git a/tools/test/testfloat/sparc64/systfloat.S b/tools/test/testfloat/sparc64/systfloat.S
    new file mode 100644
    index 00000000000..09e97d15fe3
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/systfloat.S
    @@ -0,0 +1,1120 @@
    +/*-
    + * Copyright (c) 2010 by Peter Jeremy 
    + * All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    + * IN NO EVENT SHALL THE AUTHOR OR 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.
    + */
    +
    +/*
    +===============================================================================
    +
    +This GNU assembler source file is part of TestFloat, Release 2a, a package
    +of programs for testing the correctness of floating-point arithmetic
    +complying to the IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +	.text
    +
    +/*
    +	.macro i2f32	src=%i0,dst=%f0
    +	st	\src,[%sp+2231]
    +	ld	[%sp+2231],\dst
    +	.endm
    +
    +	.macro i2f64	src=%i0,dst=%f0
    +	stx	\src,[%sp+2231]
    +	ldd	[%sp+2231],\dst
    +	.endm
    +
    +	.macro f2i32	src=%f0,dst=%i0
    +	st	\src,[%sp+2231]
    +	ld	[%sp+2231],\dst
    +	.endm
    +
    +	.macro f2i64	src=%f0,dst=%i0
    +	std	\src,[%sp+2231]
    +	ldx	[%sp+2231],\dst
    +	.endm
    +*/
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_int32_to_float32
    +syst_int32_to_float32:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	fitos	%f0,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_int32_to_float64
    +syst_int32_to_float64:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	fitod	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_int32_to_float128
    +syst_int32_to_float128:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	fitoq	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +	std	%f2,[%sp+2231]
    +	ldx	[%sp+2231],%i1
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_int64_to_float32
    +syst_int64_to_float32:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	fxtos	%f0,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_int64_to_float64
    +syst_int64_to_float64:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	fxtod	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_int64_to_float128
    +syst_int64_to_float128:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	fxtoq	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +	std	%f2,[%sp+2231]
    +	ldx	[%sp+2231],%i1
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_to_int32_round_to_zero
    +syst_float32_to_int32_round_to_zero:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	fstoi	%f0,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_to_int64_round_to_zero
    +syst_float32_to_int64_round_to_zero:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	fstox	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_to_float64
    +syst_float32_to_float64:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	fstod	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_to_float128
    +syst_float32_to_float128:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	fstoq	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +	std	%f2,[%sp+2231]
    +	ldx	[%sp+2231],%i1
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_add
    +syst_float32_add:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fadds	%f0,%f1,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_sub
    +syst_float32_sub:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fsubs	%f0,%f1,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_mul
    +syst_float32_mul:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fmuls	%f0,%f1,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_div
    +syst_float32_div:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fdivs	%f0,%f1,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_sqrt
    +syst_float32_sqrt:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	fsqrts	%f0,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_eq
    +syst_float32_eq:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fcmps	%fcc0,%f0,%f1
    +	mov	0,%i0
    +	move	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_le
    +syst_float32_le:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fcmpes	%fcc0,%f0,%f1
    +	mov	0,%i0
    +	movle	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_lt
    +syst_float32_lt:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fcmpes	%fcc0,%f0,%f1
    +	mov	0,%i0
    +	movl	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_eq_signaling
    +syst_float32_eq_signaling:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fcmpes	%fcc0,%f0,%f1
    +	mov	0,%i0
    +	move	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_le_quiet
    +syst_float32_le_quiet:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fcmps	%fcc0,%f0,%f1
    +	mov	0,%i0
    +	movle	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float32_lt_quiet
    +syst_float32_lt_quiet:
    +	save	%sp,-192,%sp
    +
    +	st	%i0,[%sp+2231]
    +	ld	[%sp+2231],%f0
    +	st	%i1,[%sp+2231]
    +	ld	[%sp+2231],%f1
    +	fcmps	%fcc0,%f0,%f1
    +	mov	0,%i0
    +	movl	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_to_int32_round_to_zero
    +syst_float64_to_int32_round_to_zero:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	fdtoi	%f0,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_to_int64_round_to_zero
    +syst_float64_to_int64_round_to_zero:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	fdtox	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_to_float32
    +syst_float64_to_float32:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	fdtos	%f0,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_to_float128
    +syst_float64_to_float128:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	fdtoq	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +	std	%f2,[%sp+2231]
    +	ldx	[%sp+2231],%i1
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_add
    +syst_float64_add:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	faddd	%f0,%f2,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_sub
    +syst_float64_sub:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fsubd	%f0,%f2,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_mul
    +syst_float64_mul:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fmuld	%f0,%f2,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_div
    +syst_float64_div:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fdivd	%f0,%f2,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_sqrt
    +syst_float64_sqrt:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	fsqrtd	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_eq
    +syst_float64_eq:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fcmpd	%fcc0,%f0,%f2
    +	mov	0,%i0
    +	move	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_le
    +syst_float64_le:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fcmped	%fcc0,%f0,%f2
    +	mov	0,%i0
    +	movle	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_lt
    +syst_float64_lt:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fcmped	%fcc0,%f0,%f2
    +	mov	0,%i0
    +	movl	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_eq_signaling
    +syst_float64_eq_signaling:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fcmped	%fcc0,%f0,%f2
    +	mov	0,%i0
    +	move	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_le_quiet
    +syst_float64_le_quiet:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fcmpd	%fcc0,%f0,%f2
    +	mov	0,%i0
    +	movle	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float64_lt_quiet
    +syst_float64_lt_quiet:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fcmpd	%fcc0,%f0,%f2
    +	mov	0,%i0
    +	movl	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_to_int32_round_to_zero
    +syst_float128_to_int32_round_to_zero:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fqtoi	%f0,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_to_int64_round_to_zero
    +syst_float128_to_int64_round_to_zero:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fqtox	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_to_float32
    +syst_float128_to_float32:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fqtos	%f0,%f0
    +	st	%f0,[%sp+2231]
    +	ld	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_to_float64
    +syst_float128_to_float64:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fqtod	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_add
    +syst_float128_add:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	faddq	%f0,%f4,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +	std	%f2,[%sp+2231]
    +	ldx	[%sp+2231],%i1
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_sub
    +syst_float128_sub:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	fsubq	%f0,%f4,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +	std	%f2,[%sp+2231]
    +	ldx	[%sp+2231],%i1
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_mul
    +syst_float128_mul:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	fmulq	%f0,%f4,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +	std	%f2,[%sp+2231]
    +	ldx	[%sp+2231],%i1
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_div
    +syst_float128_div:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	fdivq	%f0,%f4,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +	std	%f2,[%sp+2231]
    +	ldx	[%sp+2231],%i1
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_sqrt
    +syst_float128_sqrt:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	fsqrtq	%f0,%f0
    +	std	%f0,[%sp+2231]
    +	ldx	[%sp+2231],%i0
    +	std	%f2,[%sp+2231]
    +	ldx	[%sp+2231],%i1
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_eq
    +syst_float128_eq:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	fcmpq	%fcc0,%f0,%f4
    +	mov	0,%i0
    +	move	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_le
    +syst_float128_le:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	fcmpeq	%fcc0,%f0,%f4
    +	mov	0,%i0
    +	movle	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_lt
    +syst_float128_lt:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	fcmpeq	%fcc0,%f0,%f4
    +	mov	0,%i0
    +	movl	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_eq_signaling
    +syst_float128_eq_signaling:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	fcmpeq	%fcc0,%f0,%f4
    +	mov	0,%i0
    +	move	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_le_quiet
    +syst_float128_le_quiet:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	fcmpq	%fcc0,%f0,%f4
    +	mov	0,%i0
    +	movle	%fcc0,1,%i0
    +
    +	ret
    +	restore
    +
    +/*
    +-------------------------------------------------------------------------------
    +-------------------------------------------------------------------------------
    +*/
    +	.align	4
    +	.global	syst_float128_lt_quiet
    +syst_float128_lt_quiet:
    +	save	%sp,-192,%sp
    +
    +	stx	%i0,[%sp+2231]
    +	ldd	[%sp+2231],%f0
    +	stx	%i1,[%sp+2231]
    +	ldd	[%sp+2231],%f2
    +	stx	%i2,[%sp+2231]
    +	ldd	[%sp+2231],%f4
    +	stx	%i3,[%sp+2231]
    +	ldd	[%sp+2231],%f6
    +	fcmpq	%fcc0,%f0,%f4
    +	mov	0,%i0
    +	movl	%fcc0,1,%i0
    +
    +	ret
    +	restore
    diff --git a/tools/test/testfloat/sparc64/systfloat.h b/tools/test/testfloat/sparc64/systfloat.h
    new file mode 100644
    index 00000000000..c1db1ebd361
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/systfloat.h
    @@ -0,0 +1,216 @@
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +/* $FreeBSD$ */
    +
    +#include "softfloat.h"
    +#include "milieu.h"
    +
    +/*
    +-------------------------------------------------------------------------------
    +The following macros are defined to indicate that the corresponding
    +functions exist.
    +-------------------------------------------------------------------------------
    +*/
    +#define SYST_INT32_TO_FLOAT32
    +#define SYST_INT32_TO_FLOAT64
    +#define SYST_INT32_TO_FLOAT128
    +#define SYST_INT64_TO_FLOAT32
    +#define SYST_INT64_TO_FLOAT64
    +#define SYST_INT64_TO_FLOAT128
    +#define SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
    +#define SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
    +#define SYST_FLOAT32_TO_FLOAT64
    +#define SYST_FLOAT32_TO_FLOAT128
    +#define SYST_FLOAT32_ADD
    +#define SYST_FLOAT32_SUB
    +#define SYST_FLOAT32_MUL
    +#define SYST_FLOAT32_DIV
    +#define SYST_FLOAT32_SQRT
    +#define SYST_FLOAT32_EQ
    +#define SYST_FLOAT32_LE
    +#define SYST_FLOAT32_LT
    +#define SYST_FLOAT32_EQ_SIGNALING
    +#define SYST_FLOAT32_LE_QUIET
    +#define SYST_FLOAT32_LT_QUIET
    +#define SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
    +#define SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
    +#define SYST_FLOAT64_TO_FLOAT32
    +#define SYST_FLOAT64_TO_FLOAT128
    +#define SYST_FLOAT64_ADD
    +#define SYST_FLOAT64_SUB
    +#define SYST_FLOAT64_MUL
    +#define SYST_FLOAT64_DIV
    +#define SYST_FLOAT64_SQRT
    +#define SYST_FLOAT64_EQ
    +#define SYST_FLOAT64_LE
    +#define SYST_FLOAT64_LT
    +#define SYST_FLOAT64_EQ_SIGNALING
    +#define SYST_FLOAT64_LE_QUIET
    +#define SYST_FLOAT64_LT_QUIET
    +#define SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
    +#define SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
    +#define SYST_FLOAT128_TO_FLOAT32
    +#define SYST_FLOAT128_TO_FLOAT64
    +#define SYST_FLOAT128_ADD
    +#define SYST_FLOAT128_SUB
    +#define SYST_FLOAT128_MUL
    +#define SYST_FLOAT128_DIV
    +#define SYST_FLOAT128_SQRT
    +#define SYST_FLOAT128_EQ
    +#define SYST_FLOAT128_LE
    +#define SYST_FLOAT128_LT
    +#define SYST_FLOAT128_EQ_SIGNALING
    +#define SYST_FLOAT128_LE_QUIET
    +#define SYST_FLOAT128_LT_QUIET
    +
    +/*
    +-------------------------------------------------------------------------------
    +System function declarations.  (Some of these functions may not exist.)
    +-------------------------------------------------------------------------------
    +*/
    +float32 syst_int32_to_float32( int32 );
    +float64 syst_int32_to_float64( int32 );
    +#ifdef FLOATX80
    +floatx80 syst_int32_to_floatx80( int32 );
    +#endif
    +#ifdef FLOAT128
    +float128 syst_int32_to_float128( int32 );
    +#endif
    +#ifdef BITS64
    +float32 syst_int64_to_float32( int64 );
    +float64 syst_int64_to_float64( int64 );
    +#ifdef FLOATX80
    +floatx80 syst_int64_to_floatx80( int64 );
    +#endif
    +#ifdef FLOAT128
    +float128 syst_int64_to_float128( int64 );
    +#endif
    +#endif
    +int32 syst_float32_to_int32( float32 );
    +int32 syst_float32_to_int32_round_to_zero( float32 );
    +#ifdef BITS64
    +int64 syst_float32_to_int64( float32 );
    +int64 syst_float32_to_int64_round_to_zero( float32 );
    +#endif
    +float64 syst_float32_to_float64( float32 );
    +#ifdef FLOATX80
    +floatx80 syst_float32_to_floatx80( float32 );
    +#endif
    +#ifdef FLOAT128
    +float128 syst_float32_to_float128( float32 );
    +#endif
    +float32 syst_float32_round_to_int( float32 );
    +float32 syst_float32_add( float32, float32 );
    +float32 syst_float32_sub( float32, float32 );
    +float32 syst_float32_mul( float32, float32 );
    +float32 syst_float32_div( float32, float32 );
    +float32 syst_float32_rem( float32, float32 );
    +float32 syst_float32_sqrt( float32 );
    +flag syst_float32_eq( float32, float32 );
    +flag syst_float32_le( float32, float32 );
    +flag syst_float32_lt( float32, float32 );
    +flag syst_float32_eq_signaling( float32, float32 );
    +flag syst_float32_le_quiet( float32, float32 );
    +flag syst_float32_lt_quiet( float32, float32 );
    +int32 syst_float64_to_int32( float64 );
    +int32 syst_float64_to_int32_round_to_zero( float64 );
    +#ifdef BITS64
    +int64 syst_float64_to_int64( float64 );
    +int64 syst_float64_to_int64_round_to_zero( float64 );
    +#endif
    +float32 syst_float64_to_float32( float64 );
    +#ifdef FLOATX80
    +floatx80 syst_float64_to_floatx80( float64 );
    +#endif
    +#ifdef FLOAT128
    +float128 syst_float64_to_float128( float64 );
    +#endif
    +float64 syst_float64_round_to_int( float64 );
    +float64 syst_float64_add( float64, float64 );
    +float64 syst_float64_sub( float64, float64 );
    +float64 syst_float64_mul( float64, float64 );
    +float64 syst_float64_div( float64, float64 );
    +float64 syst_float64_rem( float64, float64 );
    +float64 syst_float64_sqrt( float64 );
    +flag syst_float64_eq( float64, float64 );
    +flag syst_float64_le( float64, float64 );
    +flag syst_float64_lt( float64, float64 );
    +flag syst_float64_eq_signaling( float64, float64 );
    +flag syst_float64_le_quiet( float64, float64 );
    +flag syst_float64_lt_quiet( float64, float64 );
    +#ifdef FLOATX80
    +int32 syst_floatx80_to_int32( floatx80 );
    +int32 syst_floatx80_to_int32_round_to_zero( floatx80 );
    +#ifdef BITS64
    +int64 syst_floatx80_to_int64( floatx80 );
    +int64 syst_floatx80_to_int64_round_to_zero( floatx80 );
    +#endif
    +float32 syst_floatx80_to_float32( floatx80 );
    +float64 syst_floatx80_to_float64( floatx80 );
    +#ifdef FLOAT128
    +float128 syst_floatx80_to_float128( floatx80 );
    +#endif
    +floatx80 syst_floatx80_round_to_int( floatx80 );
    +floatx80 syst_floatx80_add( floatx80, floatx80 );
    +floatx80 syst_floatx80_sub( floatx80, floatx80 );
    +floatx80 syst_floatx80_mul( floatx80, floatx80 );
    +floatx80 syst_floatx80_div( floatx80, floatx80 );
    +floatx80 syst_floatx80_rem( floatx80, floatx80 );
    +floatx80 syst_floatx80_sqrt( floatx80 );
    +flag syst_floatx80_eq( floatx80, floatx80 );
    +flag syst_floatx80_le( floatx80, floatx80 );
    +flag syst_floatx80_lt( floatx80, floatx80 );
    +flag syst_floatx80_eq_signaling( floatx80, floatx80 );
    +flag syst_floatx80_le_quiet( floatx80, floatx80 );
    +flag syst_floatx80_lt_quiet( floatx80, floatx80 );
    +#endif
    +#ifdef FLOAT128
    +int32 syst_float128_to_int32( float128 );
    +int32 syst_float128_to_int32_round_to_zero( float128 );
    +#ifdef BITS64
    +int64 syst_float128_to_int64( float128 );
    +int64 syst_float128_to_int64_round_to_zero( float128 );
    +#endif
    +float32 syst_float128_to_float32( float128 );
    +float64 syst_float128_to_float64( float128 );
    +#ifdef FLOATX80
    +floatx80 syst_float128_to_floatx80( float128 );
    +#endif
    +float128 syst_float128_round_to_int( float128 );
    +float128 syst_float128_add( float128, float128 );
    +float128 syst_float128_sub( float128, float128 );
    +float128 syst_float128_mul( float128, float128 );
    +float128 syst_float128_div( float128, float128 );
    +float128 syst_float128_rem( float128, float128 );
    +float128 syst_float128_sqrt( float128 );
    +flag syst_float128_eq( float128, float128 );
    +flag syst_float128_le( float128, float128 );
    +flag syst_float128_lt( float128, float128 );
    +flag syst_float128_eq_signaling( float128, float128 );
    +flag syst_float128_le_quiet( float128, float128 );
    +flag syst_float128_lt_quiet( float128, float128 );
    +#endif
    +
    diff --git a/tools/test/testfloat/sparc64/systmodes.c b/tools/test/testfloat/sparc64/systmodes.c
    new file mode 100644
    index 00000000000..26770599c0b
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/systmodes.c
    @@ -0,0 +1,54 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include 
    +#include "milieu.h"
    +#include "systmodes.h"
    +
    +/*
    +-------------------------------------------------------------------------------
    +Sets the system's IEC/IEEE floating-point rounding mode.
    +-------------------------------------------------------------------------------
    +*/
    +void syst_float_set_rounding_mode( int8 roundingMode )
    +{
    +
    +    (void) fpsetround( roundingMode );
    +
    +}
    +
    +/*
    +-------------------------------------------------------------------------------
    +Does nothing.
    +-------------------------------------------------------------------------------
    +*/
    +void syst_float_set_rounding_precision( int8 precision )
    +{
    +
    +}
    +
    diff --git a/tools/test/testfloat/sparc64/un-namespace.h b/tools/test/testfloat/sparc64/un-namespace.h
    new file mode 100644
    index 00000000000..5e7d1bc431b
    --- /dev/null
    +++ b/tools/test/testfloat/sparc64/un-namespace.h
    @@ -0,0 +1,30 @@
    +/*-
    + * Copyright (c) 2010 by Peter Jeremy 
    + * All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    + * IN NO EVENT SHALL THE AUTHOR OR 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$
    + */
    +/*
    + * This file has no content and is solely to satisfy a #include in
    + * the FP emulator code.
    + */
    diff --git a/tools/test/testfloat/systemBugs.txt b/tools/test/testfloat/systemBugs.txt
    new file mode 100644
    index 00000000000..a0d171a31bb
    --- /dev/null
    +++ b/tools/test/testfloat/systemBugs.txt
    @@ -0,0 +1,323 @@
    +
    +Known Floating-point Bugs Detected by TestFloat
    +
    +John R. Hauser
    +1997 December 15
    +
    +
    +-------------------------------------------------------------------------------
    +Introduction
    +
    +Several popular systems have bugs that TestFloat is very likely to run
    +across.  The ones I know of are documented here.  First off, TestFloat finds
    +no errors in the following processors/machines:
    +
    +    AMD 486 DX4's
    +    Sun UltraSPARC 1's and 2's
    +
    +On the other hand, bugs are found in these processors/machines:
    +
    +    Older Intel Pentiums (with the divide bug)
    +    Intel Pentium Pros
    +    Sun SPARCstation 1's and IPX's
    +    Sun SPARCstation 10's
    +    HP Precision Architecture processors, with HP-UX prior to version 10.10
    +
    +For some reason, most of the bugs found involve conversions from floating-
    +point to integer formats.
    +
    +The bugs are shown as actual TestFloat error lines, along with a brief
    +explanation.  The error lines given are not necesarily exhaustive and were
    +not necessarily output in the order shown.
    +
    +This document does not pretend to be an authoritative bug listing for all
    +commercial processors.  The vast majority of processors are absent from this
    +list because I have never run TestFloat on such machines and I thus have no
    +knowledge of what bugs TestFloat might find in them.
    +
    +The latest version of this file can be found at the Web page `http://
    +http.cs.berkeley.edu/~jhauser/arithmetic/testfloat.html'.
    +
    +
    +-------------------------------------------------------------------------------
    +Older Intel Pentiums (with the divide bug)
    +
    +The following conversion problems are found on Pentiums that also suffer
    +from the infamous floating-point divide bug.  These bugs have been fixed on
    +newer Pentiums.  (TestFloat does not find the divide bug.)
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +floatx80_to_int32
    +
    +-- A few small fractions are treated as though they were zero.
    +
    +	Errors found in floatx80_to_int32, rounding nearest_even:
    +	3FFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	3FFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	3FFC.C000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	BFFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	BFFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	Errors found in floatx80_to_int32, rounding to_zero:
    +	3FFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	3FFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	3FFC.C000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	BFFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	BFFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	BFFC.C000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	Errors found in floatx80_to_int32, rounding down:
    +	3FFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	3FFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	3FFC.C000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	BFFB.8000000000000000  soft: FFFFFFFF ....x  syst: 00000000 .....
    +	BFFC.8000000000000000  soft: FFFFFFFF ....x  syst: 00000000 .....
    +	BFFC.C000000000000000  soft: FFFFFFFF ....x  syst: 00000000 .....
    +	Errors found in floatx80_to_int32, rounding up:
    +	3FFB.8000000000000000  soft: 00000001 ....x  syst: 00000000 .....
    +	3FFC.8000000000000000  soft: 00000001 ....x  syst: 00000000 .....
    +	3FFC.C000000000000000  soft: 00000001 ....x  syst: 00000000 .....
    +	BFFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +	BFFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
    +
    +   3FFB.8000000000000000 is the fraction 1/16; 3FFC.8000000000000000 is 1/8;
    +   and 3FFC.C000000000000000 is 3/16.  Both positive and negative inputs are
    +   affected.
    +
    +-- Some (all?) positive floating-point values between 2^32 - 1/2
    +   (401E.FFFFFFFF00000000) and 2^32 (401F.0000000000000000) are rounded to
    +   zero when the rounding mode is nearest/even or up.
    +
    +	Errors found in floatx80_to_int32, rounding nearest_even:
    +	401E.FFFFFFFF80000000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFC00001FE  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFF8000000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFEC00000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFF002000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFC00000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFE00000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFFD7FFE  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFFFFFFE  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFFFFFFF  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	Errors found in floatx80_to_int32, rounding up:
    +	401E.FFFFFFFF00800000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFF80000000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFEFFFC000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFC000000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFE7FFFFF  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFF00000  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFFE0800  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFFF7FFB  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFFFFFFE  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +	401E.FFFFFFFFFFFFFFFF  soft: 7FFFFFFF v....  syst: 00000000 ....x
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +
    +
    +-------------------------------------------------------------------------------
    +Intel Pentium Pros
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +floatx80_to_int32
    +
    +-- The inexact flag is sometimes raised instead of the invalid flag for
    +   floating-point inputs under -(2^32) (C01F.0000000000000000).  This bug is
    +   sporadic.  It appears to be deterministic but dependent on the sequence
    +   of operations executed.
    +
    +	Errors found in floatx80_to_int32, rounding nearest_even:
    +	C01F.C000000000000002  soft: 80000000 v....  syst: 80000000 ....x
    +	C021.F00000000000003F  soft: 80000000 v....  syst: 80000000 ....x
    +	Errors found in floatx80_to_int32, rounding to_zero:
    +	C021.F00000000000003F  soft: 80000000 v....  syst: 80000000 ....x
    +	Errors found in floatx80_to_int32, rounding up:
    +	C01F.C000000000000007  soft: 80000000 v....  syst: 80000000 ....x
    +	C01F.C000000000001000  soft: 80000000 v....  syst: 80000000 ....x
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +
    +
    +-------------------------------------------------------------------------------
    +Sun SPARCstation 1's and IPX's
    +
    +Some older SPARCstations appear confused about whether underflow tininess is
    +detected before or after rounding.  For conversions from double precision
    +to single precision, tininess is detected after rounding, while for all
    +quadruple-precision operations it is detected before rounding.  Single- and
    +double-precision multipies go both ways:
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +float32_mul, float64_mul
    +
    +-- For multiplies, underflow tininess is detected _before_ rounding if one
    +   of the inputs is subnormal, and _after_ rounding otherwise.  If tininess
    +   is assumed to be detected before rounding, the following errors are
    +   generated:
    +
    +	Errors found in float32_mul, rounding nearest_even:
    +	001.000001  07E.7FFFFE  soft: 001.000000 ...ux  syst: 001.000000 ....x
    +	001.000001  87E.7FFFFE  soft: 801.000000 ...ux  syst: 801.000000 ....x
    +	001.000002  07E.7FFFFC  soft: 001.000000 ...ux  syst: 001.000000 ....x
    +	001.000002  87E.7FFFFC  soft: 801.000000 ...ux  syst: 801.000000 ....x
    +	001.000004  07E.7FFFF8  soft: 001.000000 ...ux  syst: 001.000000 ....x
    +	Errors found in float32_mul, rounding down:
    +	001.000001  87E.7FFFFE  soft: 801.000000 ...ux  syst: 801.000000 ....x
    +	001.000002  87E.7FFFFC  soft: 801.000000 ...ux  syst: 801.000000 ....x
    +	001.000004  87E.7FFFF8  soft: 801.000000 ...ux  syst: 801.000000 ....x
    +	001.000008  87E.7FFFF0  soft: 801.000000 ...ux  syst: 801.000000 ....x
    +	001.000010  87E.7FFFE0  soft: 801.000000 ...ux  syst: 801.000000 ....x
    +	Errors found in float32_mul, rounding up:
    +	001.000001  07E.7FFFFE  soft: 001.000000 ...ux  syst: 001.000000 ....x
    +	001.000002  07E.7FFFFC  soft: 001.000000 ...ux  syst: 001.000000 ....x
    +	001.000004  07E.7FFFF8  soft: 001.000000 ...ux  syst: 001.000000 ....x
    +	001.000008  07E.7FFFF0  soft: 001.000000 ...ux  syst: 001.000000 ....x
    +	001.000010  07E.7FFFE0  soft: 001.000000 ...ux  syst: 001.000000 ....x
    +	Errors found in float64_mul, rounding nearest_even:
    +	001.0000000000001  3FE.FFFFFFFFFFFFE
    +		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
    +	001.0000000000001  BFE.FFFFFFFFFFFFE
    +		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
    +	001.0000000000002  3FE.FFFFFFFFFFFFC
    +		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
    +	001.0000000000002  BFE.FFFFFFFFFFFFC
    +		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
    +	001.0000000000004  3FE.FFFFFFFFFFFF8
    +		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
    +	Errors found in float64_mul, rounding down:
    +	001.0000000000001  BFE.FFFFFFFFFFFFE
    +		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
    +	001.0000000000002  BFE.FFFFFFFFFFFFC
    +		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
    +	001.0000000000004  BFE.FFFFFFFFFFFF8
    +		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
    +	001.0000000000008  BFE.FFFFFFFFFFFF0
    +		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
    +	001.0000000000010  BFE.FFFFFFFFFFFE0
    +		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
    +	Errors found in float64_mul, rounding up:
    +	001.0000000000001  3FE.FFFFFFFFFFFFE
    +		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
    +	001.0000000000002  3FE.FFFFFFFFFFFFC
    +		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
    +	001.0000000000004  3FE.FFFFFFFFFFFF8
    +		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
    +	001.0000000000008  3FE.FFFFFFFFFFFF0
    +		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
    +	001.0000000000010  3FE.FFFFFFFFFFFE0
    +		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
    +
    +   If we assume tininess should be detected after rounding, we get the
    +   following errors:
    +
    +	Errors found in float32_mul, rounding nearest_even:
    +	000.7FFC00  07F.000400  soft: 001.000000 ....x  syst: 001.000000 ...ux
    +	000.7FFC00  87F.000400  soft: 801.000000 ....x  syst: 801.000000 ...ux
    +	000.7FFE00  07F.000200  soft: 001.000000 ....x  syst: 001.000000 ...ux
    +	000.7FFE00  87F.000200  soft: 801.000000 ....x  syst: 801.000000 ...ux
    +	000.7FFF00  07F.000100  soft: 001.000000 ....x  syst: 001.000000 ...ux
    +	Errors found in float32_mul, rounding down:
    +	000.7FFC00  87F.000400  soft: 801.000000 ....x  syst: 801.000000 ...ux
    +	000.7FFE00  87F.000200  soft: 801.000000 ....x  syst: 801.000000 ...ux
    +	000.7FFF00  87F.000100  soft: 801.000000 ....x  syst: 801.000000 ...ux
    +	000.7FFF80  87F.000080  soft: 801.000000 ....x  syst: 801.000000 ...ux
    +	000.7FFFC0  87F.000040  soft: 801.000000 ....x  syst: 801.000000 ...ux
    +	Errors found in float32_mul, rounding up:
    +	000.7FFC00  07F.000400  soft: 001.000000 ....x  syst: 001.000000 ...ux
    +	000.7FFE00  07F.000200  soft: 001.000000 ....x  syst: 001.000000 ...ux
    +	000.7FFF00  07F.000100  soft: 001.000000 ....x  syst: 001.000000 ...ux
    +	000.7FFF80  07F.000080  soft: 001.000000 ....x  syst: 001.000000 ...ux
    +	000.7FFFC0  07F.000040  soft: 001.000000 ....x  syst: 001.000000 ...ux
    +	Errors found in float64_mul, rounding nearest_even:
    +	000.FFFFFFE000000  3FF.0000002000000
    +		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
    +	000.FFFFFFE000000  BFF.0000002000000
    +		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
    +	000.FFFFFFF000000  3FF.0000001000000
    +		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
    +	000.FFFFFFF000000  BFF.0000001000000
    +		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
    +	000.FFFFFFF800000  3FF.0000000800000
    +		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
    +	Errors found in float64_mul, rounding down:
    +	000.FFFFFFE000000  BFF.0000002000000
    +		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
    +	000.FFFFFFF000000  BFF.0000001000000
    +		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
    +	000.FFFFFFF800000  BFF.0000000800000
    +		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
    +	000.FFFFFFFC00000  BFF.0000000400000
    +		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
    +	000.FFFFFFFE00000  BFF.0000000200000
    +		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
    +	Errors found in float64_mul, rounding up:
    +	000.FFFFFFE000000  3FF.0000002000000
    +		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
    +	000.FFFFFFF000000  3FF.0000001000000
    +		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
    +	000.FFFFFFF800000  3FF.0000000800000
    +		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
    +	000.FFFFFFFC00000  3FF.0000000400000
    +		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
    +	000.FFFFFFFE00000  3FF.0000000200000
    +		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +
    +
    +-------------------------------------------------------------------------------
    +Sun SPARCstation 10's
    +
    +Like other SPARCstations, some SPARCstation 10's are inconsistent regarding
    +underflow tininess, detecting it after rounding for single- and double-
    +precision operations and before rounding for quadruple-precision operations.
    +The following bug has also been observed.
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +float32_to_int32_round_to_zero, float64_to_int32_round_to_zero
    +
    +-- Single- and double-precision NaNs are converted to the integer zero.
    +   (The invalid exception flag is raised correctly.)
    +
    +	Errors found in float32_to_int32_round_to_zero:
    +	8FF.5D36AC  soft: 7FFFFFFF v....  syst: 00000000 v....
    +	0FF.7FFFC0  soft: 7FFFFFFF v....  syst: 00000000 v....
    +	8FF.7C0000  soft: 7FFFFFFF v....  syst: 00000000 v....
    +	0FF.2AB7ED  soft: 7FFFFFFF v....  syst: 00000000 v....
    +	0FF.03FFFF  soft: 7FFFFFFF v....  syst: 00000000 v....
    +	Errors found in float64_to_int32_round_to_zero:
    +	7FF.45AD84DB2524A  soft: 7FFFFFFF v....  syst: 00000000 v....
    +	7FF.CFEE063EE0512  soft: 7FFFFFFF v....  syst: 00000000 v....
    +	7FF.89FF03AB7DBA2  soft: 7FFFFFFF v....  syst: 00000000 v....
    +	7FF.FFFFFFFFFF800  soft: 7FFFFFFF v....  syst: 00000000 v....
    +	FFF.68A6410E91BF6  soft: 7FFFFFFF v....  syst: 00000000 v....
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +
    +
    +-------------------------------------------------------------------------------
    +HP Precision Architecture processors, with HP-UX prior to version 10.10
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +float32_to_int32_round_to_zero, float64_to_int32_round_to_zero
    +
    +-- When the floating-point value is too large, the overflow and inexact
    +   exception flags are raised instead of the invalid flag.
    +
    +	Errors found in float32_to_int32_round_to_zero:
    +	89E.000007  soft: 80000000 v....  syst: 80000000 ..o.x
    +	0A2.000020  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
    +	8FA.7C0000  soft: 80000000 v....  syst: 80000000 ..o.x
    +	Errors found in float64_to_int32_round_to_zero:
    +	7FD.0448700002F1C  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
    +	DAA.F000000000000  soft: 80000000 v....  syst: 80000000 ..o.x
    +	41E.063DA00005E65  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
    +	47E.FFFF800000000  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
    +	51F.0000000000004  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
    +	DDA.0000001FFFFFF  soft: 80000000 v....  syst: 80000000 ..o.x
    +	D70.00000000003FF  soft: 80000000 v....  syst: 80000000 ..o.x
    +	C7E.0000100000000  soft: 80000000 v....  syst: 80000000 ..o.x
    +	47E.000000000007F  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
    +	D57.000000000FFFF  soft: 80000000 v....  syst: 80000000 ..o.x
    +
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +
    +
    diff --git a/tools/test/testfloat/systflags.h b/tools/test/testfloat/systflags.h
    new file mode 100644
    index 00000000000..23e6b236472
    --- /dev/null
    +++ b/tools/test/testfloat/systflags.h
    @@ -0,0 +1,33 @@
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +/*
    +-------------------------------------------------------------------------------
    +Target-specific function for clearing the system's IEC/IEEE floating-point
    +exception flags.  The previous value of the flags is returned.
    +-------------------------------------------------------------------------------
    +*/
    +int8 syst_float_flags_clear( void );
    +
    diff --git a/tools/test/testfloat/systfloat.c b/tools/test/testfloat/systfloat.c
    new file mode 100644
    index 00000000000..08548c4981e
    --- /dev/null
    +++ b/tools/test/testfloat/systfloat.c
    @@ -0,0 +1,553 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +#include "milieu.h"
    +#include "softfloat.h"
    +#include "systfloat.h"
    +
    +float32 syst_int32_to_float32( int32 a )
    +{
    +    float32 z;
    +
    +    *( (float *) &z ) = a;
    +    return z;
    +
    +}
    +
    +float64 syst_int32_to_float64( int32 a )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = a;
    +    return z;
    +
    +}
    +
    +#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
    +
    +floatx80 syst_int32_to_floatx80( int32 a )
    +{
    +    floatx80 z;
    +
    +    *( (long double *) &z ) = a;
    +    return z;
    +
    +}
    +
    +#endif
    +
    +#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
    +
    +float128 syst_int32_to_float128( int32 a )
    +{
    +    float128 z;
    +
    +    *( (long double *) &z ) = a;
    +    return z;
    +
    +}
    +
    +#endif
    +
    +#ifdef BITS64
    +
    +float32 syst_int64_to_float32( int64 a )
    +{
    +    float32 z;
    +
    +    *( (float *) &z ) = a;
    +    return z;
    +
    +}
    +
    +float64 syst_int64_to_float64( int64 a )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = a;
    +    return z;
    +
    +}
    +
    +#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
    +
    +floatx80 syst_int64_to_floatx80( int64 a )
    +{
    +    floatx80 z;
    +
    +    *( (long double *) &z ) = a;
    +    return z;
    +
    +}
    +
    +#endif
    +
    +#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
    +
    +float128 syst_int64_to_float128( int64 a )
    +{
    +    float128 z;
    +
    +    *( (long double *) &z ) = a;
    +    return z;
    +
    +}
    +
    +#endif
    +
    +#endif
    +
    +int32 syst_float32_to_int32_round_to_zero( float32 a )
    +{
    +
    +    return *( (float *) &a );
    +
    +}
    +
    +#ifdef BITS64
    +
    +int64 syst_float32_to_int64_round_to_zero( float32 a )
    +{
    +
    +    return *( (float *) &a );
    +
    +}
    +
    +#endif
    +
    +float64 syst_float32_to_float64( float32 a )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = *( (float *) &a );
    +    return z;
    +
    +}
    +
    +#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
    +
    +floatx80 syst_float32_to_floatx80( float32 a )
    +{
    +    floatx80 z;
    +
    +    *( (long double *) &z ) = *( (float *) &a );
    +    return z;
    +
    +}
    +
    +#endif
    +
    +#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
    +
    +float128 syst_float32_to_float128( float32 a )
    +{
    +    float128 z;
    +
    +    *( (long double *) &z ) = *( (float *) &a );
    +    return z;
    +
    +}
    +
    +#endif
    +
    +float32 syst_float32_add( float32 a, float32 b )
    +{
    +    float32 z;
    +
    +    *( (float *) &z ) = *( (float *) &a ) + *( (float *) &b );
    +    return z;
    +
    +}
    +
    +float32 syst_float32_sub( float32 a, float32 b )
    +{
    +    float32 z;
    +
    +    *( (float *) &z ) = *( (float *) &a ) - *( (float *) &b );
    +    return z;
    +
    +}
    +
    +float32 syst_float32_mul( float32 a, float32 b )
    +{
    +    float32 z;
    +
    +    *( (float *) &z ) = *( (float *) &a ) * *( (float *) &b );
    +    return z;
    +
    +}
    +
    +float32 syst_float32_div( float32 a, float32 b )
    +{
    +    float32 z;
    +
    +    *( (float *) &z ) = *( (float *) &a ) / *( (float *) &b );
    +    return z;
    +
    +}
    +
    +flag syst_float32_eq( float32 a, float32 b )
    +{
    +
    +    return ( *( (float *) &a ) == *( (float *) &b ) );
    +
    +}
    +
    +flag syst_float32_le( float32 a, float32 b )
    +{
    +
    +    return ( *( (float *) &a ) <= *( (float *) &b ) );
    +
    +}
    +
    +flag syst_float32_lt( float32 a, float32 b )
    +{
    +
    +    return ( *( (float *) &a ) < *( (float *) &b ) );
    +
    +}
    +
    +int32 syst_float64_to_int32_round_to_zero( float64 a )
    +{
    +
    +    return *( (double *) &a );
    +
    +}
    +
    +#ifdef BITS64
    +
    +int64 syst_float64_to_int64_round_to_zero( float64 a )
    +{
    +
    +    return *( (double *) &a );
    +
    +}
    +
    +#endif
    +
    +float32 syst_float64_to_float32( float64 a )
    +{
    +    float32 z;
    +
    +    *( (float *) &z ) = *( (double *) &a );
    +    return z;
    +
    +}
    +
    +#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
    +
    +floatx80 syst_float64_to_floatx80( float64 a )
    +{
    +    floatx80 z;
    +
    +    *( (long double *) &z ) = *( (double *) &a );
    +    return z;
    +
    +}
    +
    +#endif
    +
    +#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
    +
    +float128 syst_float64_to_float128( float64 a )
    +{
    +    float128 z;
    +
    +    *( (long double *) &z ) = *( (double *) &a );
    +    return z;
    +
    +}
    +
    +#endif
    +
    +float64 syst_float64_add( float64 a, float64 b )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = *( (double *) &a ) + *( (double *) &b );
    +    return z;
    +
    +}
    +
    +float64 syst_float64_sub( float64 a, float64 b )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = *( (double *) &a ) - *( (double *) &b );
    +    return z;
    +
    +}
    +
    +float64 syst_float64_mul( float64 a, float64 b )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = *( (double *) &a ) * *( (double *) &b );
    +    return z;
    +
    +}
    +
    +float64 syst_float64_div( float64 a, float64 b )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = *( (double *) &a ) / *( (double *) &b );
    +    return z;
    +
    +}
    +
    +float64 syst_float64_sqrt( float64 a )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = sqrt( *( (double *) &a ) );
    +    return z;
    +
    +}
    +
    +flag syst_float64_eq( float64 a, float64 b )
    +{
    +
    +    return ( *( (double *) &a ) == *( (double *) &b ) );
    +
    +}
    +
    +flag syst_float64_le( float64 a, float64 b )
    +{
    +
    +    return ( *( (double *) &a ) <= *( (double *) &b ) );
    +
    +}
    +
    +flag syst_float64_lt( float64 a, float64 b )
    +{
    +
    +    return ( *( (double *) &a ) < *( (double *) &b ) );
    +
    +}
    +
    +#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
    +
    +int32 syst_floatx80_to_int32_round_to_zero( floatx80 a )
    +{
    +
    +    return *( (long double *) &a );
    +
    +}
    +
    +#ifdef BITS64
    +
    +int64 syst_floatx80_to_int64_round_to_zero( floatx80 a )
    +{
    +
    +    return *( (long double *) &a );
    +
    +}
    +
    +#endif
    +
    +float32 syst_floatx80_to_float32( floatx80 a )
    +{
    +    float32 z;
    +
    +    *( (float *) &z ) = *( (long double *) &a );
    +    return z;
    +
    +}
    +
    +float64 syst_floatx80_to_float64( floatx80 a )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = *( (long double *) &a );
    +    return z;
    +
    +}
    +
    +floatx80 syst_floatx80_add( floatx80 a, floatx80 b )
    +{
    +    floatx80 z;
    +
    +    *( (long double *) &z ) =
    +        *( (long double *) &a ) + *( (long double *) &b );
    +    return z;
    +
    +}
    +
    +floatx80 syst_floatx80_sub( floatx80 a, floatx80 b )
    +{
    +    floatx80 z;
    +
    +    *( (long double *) &z ) =
    +        *( (long double *) &a ) - *( (long double *) &b );
    +    return z;
    +
    +}
    +
    +floatx80 syst_floatx80_mul( floatx80 a, floatx80 b )
    +{
    +    floatx80 z;
    +
    +    *( (long double *) &z ) =
    +        *( (long double *) &a ) * *( (long double *) &b );
    +    return z;
    +
    +}
    +
    +floatx80 syst_floatx80_div( floatx80 a, floatx80 b )
    +{
    +    floatx80 z;
    +
    +    *( (long double *) &z ) =
    +        *( (long double *) &a ) / *( (long double *) &b );
    +    return z;
    +
    +}
    +
    +flag syst_floatx80_eq( floatx80 a, floatx80 b )
    +{
    +
    +    return ( *( (long double *) &a ) == *( (long double *) &b ) );
    +
    +}
    +
    +flag syst_floatx80_le( floatx80 a, floatx80 b )
    +{
    +
    +    return ( *( (long double *) &a ) <= *( (long double *) &b ) );
    +
    +}
    +
    +flag syst_floatx80_lt( floatx80 a, floatx80 b )
    +{
    +
    +    return ( *( (long double *) &a ) < *( (long double *) &b ) );
    +
    +}
    +
    +#endif
    +
    +#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
    +
    +int32 syst_float128_to_int32_round_to_zero( float128 a )
    +{
    +
    +    return *( (long double *) &a );
    +
    +}
    +
    +#ifdef BITS64
    +
    +int64 syst_float128_to_int64_round_to_zero( float128 a )
    +{
    +
    +    return *( (long double *) &a );
    +
    +}
    +
    +#endif
    +
    +float32 syst_float128_to_float32( float128 a )
    +{
    +    float32 z;
    +
    +    *( (float *) &z ) = *( (long double *) &a );
    +    return z;
    +
    +}
    +
    +float64 syst_float128_to_float64( float128 a )
    +{
    +    float64 z;
    +
    +    *( (double *) &z ) = *( (long double *) &a );
    +    return z;
    +
    +}
    +
    +float128 syst_float128_add( float128 a, float128 b )
    +{
    +    float128 z;
    +
    +    *( (long double *) &z ) =
    +        *( (long double *) &a ) + *( (long double *) &b );
    +    return z;
    +
    +}
    +
    +float128 syst_float128_sub( float128 a, float128 b )
    +{
    +    float128 z;
    +
    +    *( (long double *) &z ) =
    +        *( (long double *) &a ) - *( (long double *) &b );
    +    return z;
    +
    +}
    +
    +float128 syst_float128_mul( float128 a, float128 b )
    +{
    +    float128 z;
    +
    +    *( (long double *) &z ) =
    +        *( (long double *) &a ) * *( (long double *) &b );
    +    return z;
    +
    +}
    +
    +float128 syst_float128_div( float128 a, float128 b )
    +{
    +    float128 z;
    +
    +    *( (long double *) &z ) =
    +        *( (long double *) &a ) / *( (long double *) &b );
    +    return z;
    +
    +}
    +
    +flag syst_float128_eq( float128 a, float128 b )
    +{
    +
    +    return ( *( (long double *) &a ) == *( (long double *) &b ) );
    +
    +}
    +
    +flag syst_float128_le( float128 a, float128 b )
    +{
    +
    +    return ( *( (long double *) &a ) <= *( (long double *) &b ) );
    +
    +}
    +
    +flag syst_float128_lt( float128 a, float128 b )
    +{
    +
    +    return ( *( (long double *) &a ) < *( (long double *) &b ) );
    +
    +}
    +
    +#endif
    +
    diff --git a/tools/test/testfloat/systmodes.h b/tools/test/testfloat/systmodes.h
    new file mode 100644
    index 00000000000..b2befa4ad59
    --- /dev/null
    +++ b/tools/test/testfloat/systmodes.h
    @@ -0,0 +1,42 @@
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +/*
    +-------------------------------------------------------------------------------
    +Target-specific function for setting the system's IEC/IEEE floating-point
    +rounding mode.  Other system modes are also initialized as necessary (for
    +example, exception trapping may be disabled).
    +-------------------------------------------------------------------------------
    +*/
    +void syst_float_set_rounding_mode( int8 );
    +
    +/*
    +-------------------------------------------------------------------------------
    +Target-specific function for setting the IEC/IEEE rounding precision of
    +subsequent extended double-precision operations performed by the system.
    +-------------------------------------------------------------------------------
    +*/
    +void syst_float_set_rounding_precision( int8 );
    +
    diff --git a/tools/test/testfloat/testCases.c b/tools/test/testfloat/testCases.c
    new file mode 100644
    index 00000000000..e2d8f4215fe
    --- /dev/null
    +++ b/tools/test/testfloat/testCases.c
    @@ -0,0 +1,3682 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include "milieu.h"
    +#include "fail.h"
    +#include "random.h"
    +#include "softfloat.h"
    +#include "testCases.h"
    +
    +typedef struct {
    +    int16 expNum, term1Num, term2Num;
    +    flag done;
    +} sequenceT;
    +
    +enum {
    +    int32NumP1 = 124
    +};
    +
    +static const uint32 int32P1[ int32NumP1 ] = {
    +    0x00000000,
    +    0x00000001,
    +    0x00000002,
    +    0x00000004,
    +    0x00000008,
    +    0x00000010,
    +    0x00000020,
    +    0x00000040,
    +    0x00000080,
    +    0x00000100,
    +    0x00000200,
    +    0x00000400,
    +    0x00000800,
    +    0x00001000,
    +    0x00002000,
    +    0x00004000,
    +    0x00008000,
    +    0x00010000,
    +    0x00020000,
    +    0x00040000,
    +    0x00080000,
    +    0x00100000,
    +    0x00200000,
    +    0x00400000,
    +    0x00800000,
    +    0x01000000,
    +    0x02000000,
    +    0x04000000,
    +    0x08000000,
    +    0x10000000,
    +    0x20000000,
    +    0x40000000,
    +    0x80000000,
    +    0xC0000000,
    +    0xE0000000,
    +    0xF0000000,
    +    0xF8000000,
    +    0xFC000000,
    +    0xFE000000,
    +    0xFF000000,
    +    0xFF800000,
    +    0xFFC00000,
    +    0xFFE00000,
    +    0xFFF00000,
    +    0xFFF80000,
    +    0xFFFC0000,
    +    0xFFFE0000,
    +    0xFFFF0000,
    +    0xFFFF8000,
    +    0xFFFFC000,
    +    0xFFFFE000,
    +    0xFFFFF000,
    +    0xFFFFF800,
    +    0xFFFFFC00,
    +    0xFFFFFE00,
    +    0xFFFFFF00,
    +    0xFFFFFF80,
    +    0xFFFFFFC0,
    +    0xFFFFFFE0,
    +    0xFFFFFFF0,
    +    0xFFFFFFF8,
    +    0xFFFFFFFC,
    +    0xFFFFFFFE,
    +    0xFFFFFFFF,
    +    0xFFFFFFFD,
    +    0xFFFFFFFB,
    +    0xFFFFFFF7,
    +    0xFFFFFFEF,
    +    0xFFFFFFDF,
    +    0xFFFFFFBF,
    +    0xFFFFFF7F,
    +    0xFFFFFEFF,
    +    0xFFFFFDFF,
    +    0xFFFFFBFF,
    +    0xFFFFF7FF,
    +    0xFFFFEFFF,
    +    0xFFFFDFFF,
    +    0xFFFFBFFF,
    +    0xFFFF7FFF,
    +    0xFFFEFFFF,
    +    0xFFFDFFFF,
    +    0xFFFBFFFF,
    +    0xFFF7FFFF,
    +    0xFFEFFFFF,
    +    0xFFDFFFFF,
    +    0xFFBFFFFF,
    +    0xFF7FFFFF,
    +    0xFEFFFFFF,
    +    0xFDFFFFFF,
    +    0xFBFFFFFF,
    +    0xF7FFFFFF,
    +    0xEFFFFFFF,
    +    0xDFFFFFFF,
    +    0xBFFFFFFF,
    +    0x7FFFFFFF,
    +    0x3FFFFFFF,
    +    0x1FFFFFFF,
    +    0x0FFFFFFF,
    +    0x07FFFFFF,
    +    0x03FFFFFF,
    +    0x01FFFFFF,
    +    0x00FFFFFF,
    +    0x007FFFFF,
    +    0x003FFFFF,
    +    0x001FFFFF,
    +    0x000FFFFF,
    +    0x0007FFFF,
    +    0x0003FFFF,
    +    0x0001FFFF,
    +    0x0000FFFF,
    +    0x00007FFF,
    +    0x00003FFF,
    +    0x00001FFF,
    +    0x00000FFF,
    +    0x000007FF,
    +    0x000003FF,
    +    0x000001FF,
    +    0x000000FF,
    +    0x0000007F,
    +    0x0000003F,
    +    0x0000001F,
    +    0x0000000F,
    +    0x00000007,
    +    0x00000003
    +};
    +
    +static int32 int32NextP1( sequenceT *sequencePtr )
    +{
    +    uint8 termNum;
    +    int32 z;
    +
    +    termNum = sequencePtr->term1Num;
    +    z = int32P1[ termNum ];
    +    ++termNum;
    +    if ( int32NumP1 <= termNum ) {
    +        termNum = 0;
    +        sequencePtr->done = TRUE;
    +    }
    +    sequencePtr->term1Num = termNum;
    +    return (sbits32) z;
    +
    +}
    +
    +static const int32 int32NumP2 = ( int32NumP1 * int32NumP1 + int32NumP1 ) / 2;
    +
    +static int32 int32NextP2( sequenceT *sequencePtr )
    +{
    +    uint8 term1Num, term2Num;
    +    int32 z;
    +
    +    term2Num = sequencePtr->term2Num;
    +    term1Num = sequencePtr->term1Num;
    +    z = int32P1[ term1Num ] + int32P1[ term2Num ];
    +    ++term2Num;
    +    if ( int32NumP1 <= term2Num ) {
    +        ++term1Num;
    +        if ( int32NumP1 <= term1Num ) {
    +            term1Num = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        term2Num = term1Num;
    +        sequencePtr->term1Num = term1Num;
    +    }
    +    sequencePtr->term2Num = term2Num;
    +    return (sbits32) z;
    +
    +}
    +
    +static int32 int32RandomP3( void )
    +{
    +
    +    return
    +        (sbits32) (
    +              int32P1[ randomUint8() % int32NumP1 ]
    +            + int32P1[ randomUint8() % int32NumP1 ]
    +            + int32P1[ randomUint8() % int32NumP1 ]
    +        );
    +
    +}
    +
    +enum {
    +    int32NumPInfWeightMasks = 29
    +};
    +
    +static const uint32 int32PInfWeightMasks[ int32NumPInfWeightMasks ] = {
    +    0xFFFFFFFF,
    +    0x7FFFFFFF,
    +    0x3FFFFFFF,
    +    0x1FFFFFFF,
    +    0x0FFFFFFF,
    +    0x07FFFFFF,
    +    0x03FFFFFF,
    +    0x01FFFFFF,
    +    0x00FFFFFF,
    +    0x007FFFFF,
    +    0x003FFFFF,
    +    0x001FFFFF,
    +    0x000FFFFF,
    +    0x0007FFFF,
    +    0x0003FFFF,
    +    0x0001FFFF,
    +    0x0000FFFF,
    +    0x00007FFF,
    +    0x00003FFF,
    +    0x00001FFF,
    +    0x00000FFF,
    +    0x000007FF,
    +    0x000003FF,
    +    0x000001FF,
    +    0x000000FF,
    +    0x0000007F,
    +    0x0000003F,
    +    0x0000001F,
    +    0x0000000F
    +};
    +
    +static const uint32 int32PInfWeightOffsets[ int32NumPInfWeightMasks ] = {
    +    0x00000000,
    +    0xC0000000,
    +    0xE0000000,
    +    0xF0000000,
    +    0xF8000000,
    +    0xFC000000,
    +    0xFE000000,
    +    0xFF000000,
    +    0xFF800000,
    +    0xFFC00000,
    +    0xFFE00000,
    +    0xFFF00000,
    +    0xFFF80000,
    +    0xFFFC0000,
    +    0xFFFE0000,
    +    0xFFFF0000,
    +    0xFFFF8000,
    +    0xFFFFC000,
    +    0xFFFFE000,
    +    0xFFFFF000,
    +    0xFFFFF800,
    +    0xFFFFFC00,
    +    0xFFFFFE00,
    +    0xFFFFFF00,
    +    0xFFFFFF80,
    +    0xFFFFFFC0,
    +    0xFFFFFFE0,
    +    0xFFFFFFF0,
    +    0xFFFFFFF8
    +};
    +
    +static int32 int32RandomPInf( void )
    +{
    +    int8 weightMaskNum;
    +
    +    weightMaskNum = randomUint8() % int32NumPInfWeightMasks;
    +    return
    +        (sbits32) (
    +              ( randomUint32() & int32PInfWeightMasks[ weightMaskNum ] )
    +            + int32PInfWeightOffsets[ weightMaskNum ]
    +        );
    +
    +}
    +
    +#ifdef BITS64
    +
    +enum {
    +    int64NumP1 = 252
    +};
    +
    +static const uint64 int64P1[ int64NumP1 ] = {
    +    LIT64( 0x0000000000000000 ),
    +    LIT64( 0x0000000000000001 ),
    +    LIT64( 0x0000000000000002 ),
    +    LIT64( 0x0000000000000004 ),
    +    LIT64( 0x0000000000000008 ),
    +    LIT64( 0x0000000000000010 ),
    +    LIT64( 0x0000000000000020 ),
    +    LIT64( 0x0000000000000040 ),
    +    LIT64( 0x0000000000000080 ),
    +    LIT64( 0x0000000000000100 ),
    +    LIT64( 0x0000000000000200 ),
    +    LIT64( 0x0000000000000400 ),
    +    LIT64( 0x0000000000000800 ),
    +    LIT64( 0x0000000000001000 ),
    +    LIT64( 0x0000000000002000 ),
    +    LIT64( 0x0000000000004000 ),
    +    LIT64( 0x0000000000008000 ),
    +    LIT64( 0x0000000000010000 ),
    +    LIT64( 0x0000000000020000 ),
    +    LIT64( 0x0000000000040000 ),
    +    LIT64( 0x0000000000080000 ),
    +    LIT64( 0x0000000000100000 ),
    +    LIT64( 0x0000000000200000 ),
    +    LIT64( 0x0000000000400000 ),
    +    LIT64( 0x0000000000800000 ),
    +    LIT64( 0x0000000001000000 ),
    +    LIT64( 0x0000000002000000 ),
    +    LIT64( 0x0000000004000000 ),
    +    LIT64( 0x0000000008000000 ),
    +    LIT64( 0x0000000010000000 ),
    +    LIT64( 0x0000000020000000 ),
    +    LIT64( 0x0000000040000000 ),
    +    LIT64( 0x0000000080000000 ),
    +    LIT64( 0x0000000100000000 ),
    +    LIT64( 0x0000000200000000 ),
    +    LIT64( 0x0000000400000000 ),
    +    LIT64( 0x0000000800000000 ),
    +    LIT64( 0x0000001000000000 ),
    +    LIT64( 0x0000002000000000 ),
    +    LIT64( 0x0000004000000000 ),
    +    LIT64( 0x0000008000000000 ),
    +    LIT64( 0x0000010000000000 ),
    +    LIT64( 0x0000020000000000 ),
    +    LIT64( 0x0000040000000000 ),
    +    LIT64( 0x0000080000000000 ),
    +    LIT64( 0x0000100000000000 ),
    +    LIT64( 0x0000200000000000 ),
    +    LIT64( 0x0000400000000000 ),
    +    LIT64( 0x0000800000000000 ),
    +    LIT64( 0x0001000000000000 ),
    +    LIT64( 0x0002000000000000 ),
    +    LIT64( 0x0004000000000000 ),
    +    LIT64( 0x0008000000000000 ),
    +    LIT64( 0x0010000000000000 ),
    +    LIT64( 0x0020000000000000 ),
    +    LIT64( 0x0040000000000000 ),
    +    LIT64( 0x0080000000000000 ),
    +    LIT64( 0x0100000000000000 ),
    +    LIT64( 0x0200000000000000 ),
    +    LIT64( 0x0400000000000000 ),
    +    LIT64( 0x0800000000000000 ),
    +    LIT64( 0x1000000000000000 ),
    +    LIT64( 0x2000000000000000 ),
    +    LIT64( 0x4000000000000000 ),
    +    LIT64( 0x8000000000000000 ),
    +    LIT64( 0xC000000000000000 ),
    +    LIT64( 0xE000000000000000 ),
    +    LIT64( 0xF000000000000000 ),
    +    LIT64( 0xF800000000000000 ),
    +    LIT64( 0xFC00000000000000 ),
    +    LIT64( 0xFE00000000000000 ),
    +    LIT64( 0xFF00000000000000 ),
    +    LIT64( 0xFF80000000000000 ),
    +    LIT64( 0xFFC0000000000000 ),
    +    LIT64( 0xFFE0000000000000 ),
    +    LIT64( 0xFFF0000000000000 ),
    +    LIT64( 0xFFF8000000000000 ),
    +    LIT64( 0xFFFC000000000000 ),
    +    LIT64( 0xFFFE000000000000 ),
    +    LIT64( 0xFFFF000000000000 ),
    +    LIT64( 0xFFFF800000000000 ),
    +    LIT64( 0xFFFFC00000000000 ),
    +    LIT64( 0xFFFFE00000000000 ),
    +    LIT64( 0xFFFFF00000000000 ),
    +    LIT64( 0xFFFFF80000000000 ),
    +    LIT64( 0xFFFFFC0000000000 ),
    +    LIT64( 0xFFFFFE0000000000 ),
    +    LIT64( 0xFFFFFF0000000000 ),
    +    LIT64( 0xFFFFFF8000000000 ),
    +    LIT64( 0xFFFFFFC000000000 ),
    +    LIT64( 0xFFFFFFE000000000 ),
    +    LIT64( 0xFFFFFFF000000000 ),
    +    LIT64( 0xFFFFFFF800000000 ),
    +    LIT64( 0xFFFFFFFC00000000 ),
    +    LIT64( 0xFFFFFFFE00000000 ),
    +    LIT64( 0xFFFFFFFF00000000 ),
    +    LIT64( 0xFFFFFFFF80000000 ),
    +    LIT64( 0xFFFFFFFFC0000000 ),
    +    LIT64( 0xFFFFFFFFE0000000 ),
    +    LIT64( 0xFFFFFFFFF0000000 ),
    +    LIT64( 0xFFFFFFFFF8000000 ),
    +    LIT64( 0xFFFFFFFFFC000000 ),
    +    LIT64( 0xFFFFFFFFFE000000 ),
    +    LIT64( 0xFFFFFFFFFF000000 ),
    +    LIT64( 0xFFFFFFFFFF800000 ),
    +    LIT64( 0xFFFFFFFFFFC00000 ),
    +    LIT64( 0xFFFFFFFFFFE00000 ),
    +    LIT64( 0xFFFFFFFFFFF00000 ),
    +    LIT64( 0xFFFFFFFFFFF80000 ),
    +    LIT64( 0xFFFFFFFFFFFC0000 ),
    +    LIT64( 0xFFFFFFFFFFFE0000 ),
    +    LIT64( 0xFFFFFFFFFFFF0000 ),
    +    LIT64( 0xFFFFFFFFFFFF8000 ),
    +    LIT64( 0xFFFFFFFFFFFFC000 ),
    +    LIT64( 0xFFFFFFFFFFFFE000 ),
    +    LIT64( 0xFFFFFFFFFFFFF000 ),
    +    LIT64( 0xFFFFFFFFFFFFF800 ),
    +    LIT64( 0xFFFFFFFFFFFFFC00 ),
    +    LIT64( 0xFFFFFFFFFFFFFE00 ),
    +    LIT64( 0xFFFFFFFFFFFFFF00 ),
    +    LIT64( 0xFFFFFFFFFFFFFF80 ),
    +    LIT64( 0xFFFFFFFFFFFFFFC0 ),
    +    LIT64( 0xFFFFFFFFFFFFFFE0 ),
    +    LIT64( 0xFFFFFFFFFFFFFFF0 ),
    +    LIT64( 0xFFFFFFFFFFFFFFF8 ),
    +    LIT64( 0xFFFFFFFFFFFFFFFC ),
    +    LIT64( 0xFFFFFFFFFFFFFFFE ),
    +    LIT64( 0xFFFFFFFFFFFFFFFF ),
    +    LIT64( 0xFFFFFFFFFFFFFFFD ),
    +    LIT64( 0xFFFFFFFFFFFFFFFB ),
    +    LIT64( 0xFFFFFFFFFFFFFFF7 ),
    +    LIT64( 0xFFFFFFFFFFFFFFEF ),
    +    LIT64( 0xFFFFFFFFFFFFFFDF ),
    +    LIT64( 0xFFFFFFFFFFFFFFBF ),
    +    LIT64( 0xFFFFFFFFFFFFFF7F ),
    +    LIT64( 0xFFFFFFFFFFFFFEFF ),
    +    LIT64( 0xFFFFFFFFFFFFFDFF ),
    +    LIT64( 0xFFFFFFFFFFFFFBFF ),
    +    LIT64( 0xFFFFFFFFFFFFF7FF ),
    +    LIT64( 0xFFFFFFFFFFFFEFFF ),
    +    LIT64( 0xFFFFFFFFFFFFDFFF ),
    +    LIT64( 0xFFFFFFFFFFFFBFFF ),
    +    LIT64( 0xFFFFFFFFFFFF7FFF ),
    +    LIT64( 0xFFFFFFFFFFFEFFFF ),
    +    LIT64( 0xFFFFFFFFFFFDFFFF ),
    +    LIT64( 0xFFFFFFFFFFFBFFFF ),
    +    LIT64( 0xFFFFFFFFFFF7FFFF ),
    +    LIT64( 0xFFFFFFFFFFEFFFFF ),
    +    LIT64( 0xFFFFFFFFFFDFFFFF ),
    +    LIT64( 0xFFFFFFFFFFBFFFFF ),
    +    LIT64( 0xFFFFFFFFFF7FFFFF ),
    +    LIT64( 0xFFFFFFFFFEFFFFFF ),
    +    LIT64( 0xFFFFFFFFFDFFFFFF ),
    +    LIT64( 0xFFFFFFFFFBFFFFFF ),
    +    LIT64( 0xFFFFFFFFF7FFFFFF ),
    +    LIT64( 0xFFFFFFFFEFFFFFFF ),
    +    LIT64( 0xFFFFFFFFDFFFFFFF ),
    +    LIT64( 0xFFFFFFFFBFFFFFFF ),
    +    LIT64( 0xFFFFFFFF7FFFFFFF ),
    +    LIT64( 0xFFFFFFFEFFFFFFFF ),
    +    LIT64( 0xFFFFFFFDFFFFFFFF ),
    +    LIT64( 0xFFFFFFFBFFFFFFFF ),
    +    LIT64( 0xFFFFFFF7FFFFFFFF ),
    +    LIT64( 0xFFFFFFEFFFFFFFFF ),
    +    LIT64( 0xFFFFFFDFFFFFFFFF ),
    +    LIT64( 0xFFFFFFBFFFFFFFFF ),
    +    LIT64( 0xFFFFFF7FFFFFFFFF ),
    +    LIT64( 0xFFFFFEFFFFFFFFFF ),
    +    LIT64( 0xFFFFFDFFFFFFFFFF ),
    +    LIT64( 0xFFFFFBFFFFFFFFFF ),
    +    LIT64( 0xFFFFF7FFFFFFFFFF ),
    +    LIT64( 0xFFFFEFFFFFFFFFFF ),
    +    LIT64( 0xFFFFDFFFFFFFFFFF ),
    +    LIT64( 0xFFFFBFFFFFFFFFFF ),
    +    LIT64( 0xFFFF7FFFFFFFFFFF ),
    +    LIT64( 0xFFFEFFFFFFFFFFFF ),
    +    LIT64( 0xFFFDFFFFFFFFFFFF ),
    +    LIT64( 0xFFFBFFFFFFFFFFFF ),
    +    LIT64( 0xFFF7FFFFFFFFFFFF ),
    +    LIT64( 0xFFEFFFFFFFFFFFFF ),
    +    LIT64( 0xFFDFFFFFFFFFFFFF ),
    +    LIT64( 0xFFBFFFFFFFFFFFFF ),
    +    LIT64( 0xFF7FFFFFFFFFFFFF ),
    +    LIT64( 0xFEFFFFFFFFFFFFFF ),
    +    LIT64( 0xFDFFFFFFFFFFFFFF ),
    +    LIT64( 0xFBFFFFFFFFFFFFFF ),
    +    LIT64( 0xF7FFFFFFFFFFFFFF ),
    +    LIT64( 0xEFFFFFFFFFFFFFFF ),
    +    LIT64( 0xDFFFFFFFFFFFFFFF ),
    +    LIT64( 0xBFFFFFFFFFFFFFFF ),
    +    LIT64( 0x7FFFFFFFFFFFFFFF ),
    +    LIT64( 0x3FFFFFFFFFFFFFFF ),
    +    LIT64( 0x1FFFFFFFFFFFFFFF ),
    +    LIT64( 0x0FFFFFFFFFFFFFFF ),
    +    LIT64( 0x07FFFFFFFFFFFFFF ),
    +    LIT64( 0x03FFFFFFFFFFFFFF ),
    +    LIT64( 0x01FFFFFFFFFFFFFF ),
    +    LIT64( 0x00FFFFFFFFFFFFFF ),
    +    LIT64( 0x007FFFFFFFFFFFFF ),
    +    LIT64( 0x003FFFFFFFFFFFFF ),
    +    LIT64( 0x001FFFFFFFFFFFFF ),
    +    LIT64( 0x000FFFFFFFFFFFFF ),
    +    LIT64( 0x0007FFFFFFFFFFFF ),
    +    LIT64( 0x0003FFFFFFFFFFFF ),
    +    LIT64( 0x0001FFFFFFFFFFFF ),
    +    LIT64( 0x0000FFFFFFFFFFFF ),
    +    LIT64( 0x00007FFFFFFFFFFF ),
    +    LIT64( 0x00003FFFFFFFFFFF ),
    +    LIT64( 0x00001FFFFFFFFFFF ),
    +    LIT64( 0x00000FFFFFFFFFFF ),
    +    LIT64( 0x000007FFFFFFFFFF ),
    +    LIT64( 0x000003FFFFFFFFFF ),
    +    LIT64( 0x000001FFFFFFFFFF ),
    +    LIT64( 0x000000FFFFFFFFFF ),
    +    LIT64( 0x0000007FFFFFFFFF ),
    +    LIT64( 0x0000003FFFFFFFFF ),
    +    LIT64( 0x0000001FFFFFFFFF ),
    +    LIT64( 0x0000000FFFFFFFFF ),
    +    LIT64( 0x00000007FFFFFFFF ),
    +    LIT64( 0x00000003FFFFFFFF ),
    +    LIT64( 0x00000001FFFFFFFF ),
    +    LIT64( 0x00000000FFFFFFFF ),
    +    LIT64( 0x000000007FFFFFFF ),
    +    LIT64( 0x000000003FFFFFFF ),
    +    LIT64( 0x000000001FFFFFFF ),
    +    LIT64( 0x000000000FFFFFFF ),
    +    LIT64( 0x0000000007FFFFFF ),
    +    LIT64( 0x0000000003FFFFFF ),
    +    LIT64( 0x0000000001FFFFFF ),
    +    LIT64( 0x0000000000FFFFFF ),
    +    LIT64( 0x00000000007FFFFF ),
    +    LIT64( 0x00000000003FFFFF ),
    +    LIT64( 0x00000000001FFFFF ),
    +    LIT64( 0x00000000000FFFFF ),
    +    LIT64( 0x000000000007FFFF ),
    +    LIT64( 0x000000000003FFFF ),
    +    LIT64( 0x000000000001FFFF ),
    +    LIT64( 0x000000000000FFFF ),
    +    LIT64( 0x0000000000007FFF ),
    +    LIT64( 0x0000000000003FFF ),
    +    LIT64( 0x0000000000001FFF ),
    +    LIT64( 0x0000000000000FFF ),
    +    LIT64( 0x00000000000007FF ),
    +    LIT64( 0x00000000000003FF ),
    +    LIT64( 0x00000000000001FF ),
    +    LIT64( 0x00000000000000FF ),
    +    LIT64( 0x000000000000007F ),
    +    LIT64( 0x000000000000003F ),
    +    LIT64( 0x000000000000001F ),
    +    LIT64( 0x000000000000000F ),
    +    LIT64( 0x0000000000000007 ),
    +    LIT64( 0x0000000000000003 )
    +};
    +
    +static int64 int64NextP1( sequenceT *sequencePtr )
    +{
    +    uint8 termNum;
    +    int64 z;
    +
    +    termNum = sequencePtr->term1Num;
    +    z = int64P1[ termNum ];
    +    ++termNum;
    +    if ( int64NumP1 <= termNum ) {
    +        termNum = 0;
    +        sequencePtr->done = TRUE;
    +    }
    +    sequencePtr->term1Num = termNum;
    +    return (sbits64) z;
    +
    +}
    +
    +static const int64 int64NumP2 = ( int64NumP1 * int64NumP1 + int64NumP1 ) / 2;
    +
    +static int64 int64NextP2( sequenceT *sequencePtr )
    +{
    +    uint8 term1Num, term2Num;
    +    int64 z;
    +
    +    term2Num = sequencePtr->term2Num;
    +    term1Num = sequencePtr->term1Num;
    +    z = int64P1[ term1Num ] + int64P1[ term2Num ];
    +    ++term2Num;
    +    if ( int64NumP1 <= term2Num ) {
    +        ++term1Num;
    +        if ( int64NumP1 <= term1Num ) {
    +            term1Num = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        term2Num = term1Num;
    +        sequencePtr->term1Num = term1Num;
    +    }
    +    sequencePtr->term2Num = term2Num;
    +    return (sbits64) z;
    +
    +}
    +
    +static int64 int64RandomP3( void )
    +{
    +
    +    return
    +        (sbits64) (
    +              int64P1[ randomUint8() % int64NumP1 ]
    +            + int64P1[ randomUint8() % int64NumP1 ]
    +            + int64P1[ randomUint8() % int64NumP1 ]
    +        );
    +
    +}
    +
    +enum {
    +    int64NumPInfWeightMasks = 61
    +};
    +
    +static const uint64 int64PInfWeightMasks[ int64NumPInfWeightMasks ] = {
    +    LIT64( 0xFFFFFFFFFFFFFFFF ),
    +    LIT64( 0x7FFFFFFFFFFFFFFF ),
    +    LIT64( 0x3FFFFFFFFFFFFFFF ),
    +    LIT64( 0x1FFFFFFFFFFFFFFF ),
    +    LIT64( 0x0FFFFFFFFFFFFFFF ),
    +    LIT64( 0x07FFFFFFFFFFFFFF ),
    +    LIT64( 0x03FFFFFFFFFFFFFF ),
    +    LIT64( 0x01FFFFFFFFFFFFFF ),
    +    LIT64( 0x00FFFFFFFFFFFFFF ),
    +    LIT64( 0x007FFFFFFFFFFFFF ),
    +    LIT64( 0x003FFFFFFFFFFFFF ),
    +    LIT64( 0x001FFFFFFFFFFFFF ),
    +    LIT64( 0x000FFFFFFFFFFFFF ),
    +    LIT64( 0x0007FFFFFFFFFFFF ),
    +    LIT64( 0x0003FFFFFFFFFFFF ),
    +    LIT64( 0x0001FFFFFFFFFFFF ),
    +    LIT64( 0x0000FFFFFFFFFFFF ),
    +    LIT64( 0x00007FFFFFFFFFFF ),
    +    LIT64( 0x00003FFFFFFFFFFF ),
    +    LIT64( 0x00001FFFFFFFFFFF ),
    +    LIT64( 0x00000FFFFFFFFFFF ),
    +    LIT64( 0x000007FFFFFFFFFF ),
    +    LIT64( 0x000003FFFFFFFFFF ),
    +    LIT64( 0x000001FFFFFFFFFF ),
    +    LIT64( 0x000000FFFFFFFFFF ),
    +    LIT64( 0x0000007FFFFFFFFF ),
    +    LIT64( 0x0000003FFFFFFFFF ),
    +    LIT64( 0x0000001FFFFFFFFF ),
    +    LIT64( 0x0000000FFFFFFFFF ),
    +    LIT64( 0x00000007FFFFFFFF ),
    +    LIT64( 0x00000003FFFFFFFF ),
    +    LIT64( 0x00000001FFFFFFFF ),
    +    LIT64( 0x00000000FFFFFFFF ),
    +    LIT64( 0x000000007FFFFFFF ),
    +    LIT64( 0x000000003FFFFFFF ),
    +    LIT64( 0x000000001FFFFFFF ),
    +    LIT64( 0x000000000FFFFFFF ),
    +    LIT64( 0x0000000007FFFFFF ),
    +    LIT64( 0x0000000003FFFFFF ),
    +    LIT64( 0x0000000001FFFFFF ),
    +    LIT64( 0x0000000000FFFFFF ),
    +    LIT64( 0x00000000007FFFFF ),
    +    LIT64( 0x00000000003FFFFF ),
    +    LIT64( 0x00000000001FFFFF ),
    +    LIT64( 0x00000000000FFFFF ),
    +    LIT64( 0x000000000007FFFF ),
    +    LIT64( 0x000000000003FFFF ),
    +    LIT64( 0x000000000001FFFF ),
    +    LIT64( 0x000000000000FFFF ),
    +    LIT64( 0x0000000000007FFF ),
    +    LIT64( 0x0000000000003FFF ),
    +    LIT64( 0x0000000000001FFF ),
    +    LIT64( 0x0000000000000FFF ),
    +    LIT64( 0x00000000000007FF ),
    +    LIT64( 0x00000000000003FF ),
    +    LIT64( 0x00000000000001FF ),
    +    LIT64( 0x00000000000000FF ),
    +    LIT64( 0x000000000000007F ),
    +    LIT64( 0x000000000000003F ),
    +    LIT64( 0x000000000000001F ),
    +    LIT64( 0x000000000000000F )
    +};
    +
    +static const uint64 int64PInfWeightOffsets[ int64NumPInfWeightMasks ] = {
    +    LIT64( 0x0000000000000000 ),
    +    LIT64( 0xC000000000000000 ),
    +    LIT64( 0xE000000000000000 ),
    +    LIT64( 0xF000000000000000 ),
    +    LIT64( 0xF800000000000000 ),
    +    LIT64( 0xFC00000000000000 ),
    +    LIT64( 0xFE00000000000000 ),
    +    LIT64( 0xFF00000000000000 ),
    +    LIT64( 0xFF80000000000000 ),
    +    LIT64( 0xFFC0000000000000 ),
    +    LIT64( 0xFFE0000000000000 ),
    +    LIT64( 0xFFF0000000000000 ),
    +    LIT64( 0xFFF8000000000000 ),
    +    LIT64( 0xFFFC000000000000 ),
    +    LIT64( 0xFFFE000000000000 ),
    +    LIT64( 0xFFFF000000000000 ),
    +    LIT64( 0xFFFF800000000000 ),
    +    LIT64( 0xFFFFC00000000000 ),
    +    LIT64( 0xFFFFE00000000000 ),
    +    LIT64( 0xFFFFF00000000000 ),
    +    LIT64( 0xFFFFF80000000000 ),
    +    LIT64( 0xFFFFFC0000000000 ),
    +    LIT64( 0xFFFFFE0000000000 ),
    +    LIT64( 0xFFFFFF0000000000 ),
    +    LIT64( 0xFFFFFF8000000000 ),
    +    LIT64( 0xFFFFFFC000000000 ),
    +    LIT64( 0xFFFFFFE000000000 ),
    +    LIT64( 0xFFFFFFF000000000 ),
    +    LIT64( 0xFFFFFFF800000000 ),
    +    LIT64( 0xFFFFFFFC00000000 ),
    +    LIT64( 0xFFFFFFFE00000000 ),
    +    LIT64( 0xFFFFFFFF00000000 ),
    +    LIT64( 0xFFFFFFFF80000000 ),
    +    LIT64( 0xFFFFFFFFC0000000 ),
    +    LIT64( 0xFFFFFFFFE0000000 ),
    +    LIT64( 0xFFFFFFFFF0000000 ),
    +    LIT64( 0xFFFFFFFFF8000000 ),
    +    LIT64( 0xFFFFFFFFFC000000 ),
    +    LIT64( 0xFFFFFFFFFE000000 ),
    +    LIT64( 0xFFFFFFFFFF000000 ),
    +    LIT64( 0xFFFFFFFFFF800000 ),
    +    LIT64( 0xFFFFFFFFFFC00000 ),
    +    LIT64( 0xFFFFFFFFFFE00000 ),
    +    LIT64( 0xFFFFFFFFFFF00000 ),
    +    LIT64( 0xFFFFFFFFFFF80000 ),
    +    LIT64( 0xFFFFFFFFFFFC0000 ),
    +    LIT64( 0xFFFFFFFFFFFE0000 ),
    +    LIT64( 0xFFFFFFFFFFFF0000 ),
    +    LIT64( 0xFFFFFFFFFFFF8000 ),
    +    LIT64( 0xFFFFFFFFFFFFC000 ),
    +    LIT64( 0xFFFFFFFFFFFFE000 ),
    +    LIT64( 0xFFFFFFFFFFFFF000 ),
    +    LIT64( 0xFFFFFFFFFFFFF800 ),
    +    LIT64( 0xFFFFFFFFFFFFFC00 ),
    +    LIT64( 0xFFFFFFFFFFFFFE00 ),
    +    LIT64( 0xFFFFFFFFFFFFFF00 ),
    +    LIT64( 0xFFFFFFFFFFFFFF80 ),
    +    LIT64( 0xFFFFFFFFFFFFFFC0 ),
    +    LIT64( 0xFFFFFFFFFFFFFFE0 ),
    +    LIT64( 0xFFFFFFFFFFFFFFF0 ),
    +    LIT64( 0xFFFFFFFFFFFFFFF8 )
    +};
    +
    +static int64 int64RandomPInf( void )
    +{
    +    int8 weightMaskNum;
    +
    +    weightMaskNum = randomUint8() % int64NumPInfWeightMasks;
    +    return
    +        (sbits64) (
    +              ( randomUint64() & int64PInfWeightMasks[ weightMaskNum ] )
    +            + int64PInfWeightOffsets[ weightMaskNum ]
    +        );
    +
    +}
    +
    +#endif
    +
    +enum {
    +    float32NumQIn  = 22,
    +    float32NumQOut = 50,
    +    float32NumP1   =  4,
    +    float32NumP2   = 88
    +};
    +
    +static const uint32 float32QIn[ float32NumQIn ] = {
    +    0x00000000,		/* positive, subnormal		*/
    +    0x00800000,		/* positive, -126		*/
    +    0x33800000,		/* positive,  -24		*/
    +    0x3E800000,		/* positive,   -2		*/
    +    0x3F000000,		/* positive,   -1		*/
    +    0x3F800000,		/* positive,    0		*/
    +    0x40000000,		/* positive,    1		*/
    +    0x40800000,		/* positive,    2		*/
    +    0x4B800000,		/* positive,   24		*/
    +    0x7F000000,		/* positive,  127		*/
    +    0x7F800000,		/* positive, infinity or NaN	*/
    +    0x80000000,		/* negative, subnormal		*/
    +    0x80800000,		/* negative, -126		*/
    +    0xB3800000,		/* negative,  -24		*/
    +    0xBE800000,		/* negative,   -2		*/
    +    0xBF000000,		/* negative,   -1		*/
    +    0xBF800000,		/* negative,    0		*/
    +    0xC0000000,		/* negative,    1		*/
    +    0xC0800000,		/* negative,    2		*/
    +    0xCB800000,		/* negative,   24		*/
    +    0xFE800000,		/* negative,  126		*/
    +    0xFF800000		/* negative, infinity or NaN	*/
    +};
    +
    +static const uint32 float32QOut[ float32NumQOut ] = {
    +    0x00000000,		/* positive, subnormal		*/
    +    0x00800000,		/* positive, -126		*/
    +    0x01000000,		/* positive, -125		*/
    +    0x33800000,		/* positive,  -24		*/
    +    0x3D800000,		/* positive,   -4		*/
    +    0x3E000000,		/* positive,   -3		*/
    +    0x3E800000,		/* positive,   -2		*/
    +    0x3F000000,		/* positive,   -1		*/
    +    0x3F800000,		/* positive,    0		*/
    +    0x40000000,		/* positive,    1		*/
    +    0x40800000,		/* positive,    2		*/
    +    0x41000000,		/* positive,    3		*/
    +    0x41800000,		/* positive,    4		*/
    +    0x4B800000,		/* positive,   24		*/
    +    0x4E000000,		/* positive,   29		*/
    +    0x4E800000,		/* positive,   30		*/
    +    0x4F000000,		/* positive,   31		*/
    +    0x4F800000,		/* positive,   32		*/
    +    0x5E000000,		/* positive,   61		*/
    +    0x5E800000,		/* positive,   62		*/
    +    0x5F000000,		/* positive,   63		*/
    +    0x5F800000,		/* positive,   64		*/
    +    0x7E800000,		/* positive,  126		*/
    +    0x7F000000,		/* positive,  127		*/
    +    0x7F800000,		/* positive, infinity or NaN	*/
    +    0x80000000,		/* negative, subnormal		*/
    +    0x80800000,		/* negative, -126		*/
    +    0x81000000,		/* negative, -125		*/
    +    0xB3800000,		/* negative,  -24		*/
    +    0xBD800000,		/* negative,   -4		*/
    +    0xBE000000,		/* negative,   -3		*/
    +    0xBE800000,		/* negative,   -2		*/
    +    0xBF000000,		/* negative,   -1		*/
    +    0xBF800000,		/* negative,    0		*/
    +    0xC0000000,		/* negative,    1		*/
    +    0xC0800000,		/* negative,    2		*/
    +    0xC1000000,		/* negative,    3		*/
    +    0xC1800000,		/* negative,    4		*/
    +    0xCB800000,		/* negative,   24		*/
    +    0xCE000000,		/* negative,   29		*/
    +    0xCE800000,		/* negative,   30		*/
    +    0xCF000000,		/* negative,   31		*/
    +    0xCF800000,		/* negative,   32		*/
    +    0xDE000000,		/* negative,   61		*/
    +    0xDE800000,		/* negative,   62		*/
    +    0xDF000000,		/* negative,   63		*/
    +    0xDF800000,		/* negative,   64		*/
    +    0xFE800000,		/* negative,  126		*/
    +    0xFF000000,		/* negative,  127		*/
    +    0xFF800000		/* negative, infinity or NaN	*/
    +};
    +
    +static const uint32 float32P1[ float32NumP1 ] = {
    +    0x00000000,
    +    0x00000001,
    +    0x007FFFFF,
    +    0x007FFFFE
    +};
    +
    +static const uint32 float32P2[ float32NumP2 ] = {
    +    0x00000000,
    +    0x00000001,
    +    0x00000002,
    +    0x00000004,
    +    0x00000008,
    +    0x00000010,
    +    0x00000020,
    +    0x00000040,
    +    0x00000080,
    +    0x00000100,
    +    0x00000200,
    +    0x00000400,
    +    0x00000800,
    +    0x00001000,
    +    0x00002000,
    +    0x00004000,
    +    0x00008000,
    +    0x00010000,
    +    0x00020000,
    +    0x00040000,
    +    0x00080000,
    +    0x00100000,
    +    0x00200000,
    +    0x00400000,
    +    0x00600000,
    +    0x00700000,
    +    0x00780000,
    +    0x007C0000,
    +    0x007E0000,
    +    0x007F0000,
    +    0x007F8000,
    +    0x007FC000,
    +    0x007FE000,
    +    0x007FF000,
    +    0x007FF800,
    +    0x007FFC00,
    +    0x007FFE00,
    +    0x007FFF00,
    +    0x007FFF80,
    +    0x007FFFC0,
    +    0x007FFFE0,
    +    0x007FFFF0,
    +    0x007FFFF8,
    +    0x007FFFFC,
    +    0x007FFFFE,
    +    0x007FFFFF,
    +    0x007FFFFD,
    +    0x007FFFFB,
    +    0x007FFFF7,
    +    0x007FFFEF,
    +    0x007FFFDF,
    +    0x007FFFBF,
    +    0x007FFF7F,
    +    0x007FFEFF,
    +    0x007FFDFF,
    +    0x007FFBFF,
    +    0x007FF7FF,
    +    0x007FEFFF,
    +    0x007FDFFF,
    +    0x007FBFFF,
    +    0x007F7FFF,
    +    0x007EFFFF,
    +    0x007DFFFF,
    +    0x007BFFFF,
    +    0x0077FFFF,
    +    0x006FFFFF,
    +    0x005FFFFF,
    +    0x003FFFFF,
    +    0x001FFFFF,
    +    0x000FFFFF,
    +    0x0007FFFF,
    +    0x0003FFFF,
    +    0x0001FFFF,
    +    0x0000FFFF,
    +    0x00007FFF,
    +    0x00003FFF,
    +    0x00001FFF,
    +    0x00000FFF,
    +    0x000007FF,
    +    0x000003FF,
    +    0x000001FF,
    +    0x000000FF,
    +    0x0000007F,
    +    0x0000003F,
    +    0x0000001F,
    +    0x0000000F,
    +    0x00000007,
    +    0x00000003
    +};
    +
    +static const uint32 float32NumQInP1 = float32NumQIn * float32NumP1;
    +static const uint32 float32NumQOutP1 = float32NumQOut * float32NumP1;
    +
    +static float32 float32NextQInP1( sequenceT *sequencePtr )
    +{
    +    uint8 expNum, sigNum;
    +    float32 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z = float32QIn[ expNum ] | float32P1[ sigNum ];
    +    ++sigNum;
    +    if ( float32NumP1 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float32NumQIn <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static float32 float32NextQOutP1( sequenceT *sequencePtr )
    +{
    +    uint8 expNum, sigNum;
    +    float32 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z = float32QOut[ expNum ] | float32P1[ sigNum ];
    +    ++sigNum;
    +    if ( float32NumP1 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float32NumQOut <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static const uint32 float32NumQInP2 = float32NumQIn * float32NumP2;
    +static const uint32 float32NumQOutP2 = float32NumQOut * float32NumP2;
    +
    +static float32 float32NextQInP2( sequenceT *sequencePtr )
    +{
    +    uint8 expNum, sigNum;
    +    float32 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z = float32QIn[ expNum ] | float32P2[ sigNum ];
    +    ++sigNum;
    +    if ( float32NumP2 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float32NumQIn <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static float32 float32NextQOutP2( sequenceT *sequencePtr )
    +{
    +    uint8 expNum, sigNum;
    +    float32 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z = float32QOut[ expNum ] | float32P2[ sigNum ];
    +    ++sigNum;
    +    if ( float32NumP2 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float32NumQOut <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static float32 float32RandomQOutP3( void )
    +{
    +
    +    return
    +          float32QOut[ randomUint8() % float32NumQOut ]
    +        | (   (   float32P2[ randomUint8() % float32NumP2 ]
    +                + float32P2[ randomUint8() % float32NumP2 ] )
    +            & 0x007FFFFF );
    +
    +}
    +
    +static float32 float32RandomQOutPInf( void )
    +{
    +
    +    return
    +          float32QOut[ randomUint8() % float32NumQOut ]
    +        | ( randomUint32() & 0x007FFFFF );
    +
    +}
    +
    +enum {
    +    float32NumQInfWeightMasks = 7
    +};
    +
    +static const uint32 float32QInfWeightMasks[ float32NumQInfWeightMasks ] = {
    +    0x7F800000,
    +    0x7F800000,
    +    0x3F800000,
    +    0x1F800000,
    +    0x0F800000,
    +    0x07800000,
    +    0x03800000
    +};
    +
    +static const uint32 float32QInfWeightOffsets[ float32NumQInfWeightMasks ] = {
    +    0x00000000,
    +    0x00000000,
    +    0x20000000,
    +    0x30000000,
    +    0x38000000,
    +    0x3C000000,
    +    0x3E000000
    +};
    +
    +static float32 float32RandomQInfP3( void )
    +{
    +    int8 weightMaskNum;
    +
    +    weightMaskNum = randomUint8() % float32NumQInfWeightMasks;
    +    return
    +          ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
    +        | (   (   ( ( (uint32) ( randomUint16() & 0x1FF ) )<<23 )
    +                & float32QInfWeightMasks[ weightMaskNum ] )
    +            + float32QInfWeightOffsets[ weightMaskNum ]
    +          )
    +        | (   (   float32P2[ randomUint8() % float32NumP2 ]
    +                + float32P2[ randomUint8() % float32NumP2 ] )
    +            & 0x007FFFFF );
    +
    +}
    +
    +static float32 float32RandomQInfPInf( void )
    +{
    +    int8 weightMaskNum;
    +
    +    weightMaskNum = randomUint8() % float32NumQInfWeightMasks;
    +    return
    +          ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
    +        | (   (   ( ( (uint32) ( randomUint16() & 0x1FF ) )<<23 )
    +                & float32QInfWeightMasks[ weightMaskNum ] )
    +            + float32QInfWeightOffsets[ weightMaskNum ]
    +          )
    +        | ( randomUint32() & 0x007FFFFF );
    +
    +}
    +
    +static float32 float32Random( void )
    +{
    +
    +    switch ( randomUint8() & 7 ) {
    +     case 0:
    +     case 1:
    +     case 2:
    +        return float32RandomQOutP3();
    +     case 3:
    +        return float32RandomQOutPInf();
    +     case 4:
    +     case 5:
    +     case 6:
    +        return float32RandomQInfP3();
    +     default:
    +        return float32RandomQInfPInf();
    +    }
    +
    +}
    +
    +#ifdef BITS64
    +#define SETFLOAT64( z, zHigh, zLow ) z = ( ( (float64) zHigh )<<32 ) | zLow
    +#else
    +#define SETFLOAT64( z, zHigh, zLow ) z.low = zLow; z.high = zHigh
    +#endif
    +
    +enum {
    +    float64NumQIn  =  22,
    +    float64NumQOut =  64,
    +    float64NumP1   =   4,
    +    float64NumP2   = 204
    +};
    +
    +static const uint32 float64QIn[ float64NumQIn ] = {
    +    0x00000000,		/* positive, subnormal		*/
    +    0x00100000,		/* positive, -1022		*/
    +    0x3CA00000,		/* positive,   -53		*/
    +    0x3FD00000,		/* positive,    -2		*/
    +    0x3FE00000,		/* positive,    -1		*/
    +    0x3FF00000,		/* positive,     0		*/
    +    0x40000000,		/* positive,     1		*/
    +    0x40100000,		/* positive,     2		*/
    +    0x43400000,		/* positive,    53		*/
    +    0x7FE00000,		/* positive,  1023		*/
    +    0x7FF00000,		/* positive, infinity or NaN	*/
    +    0x80000000,		/* negative, subnormal		*/
    +    0x80100000,		/* negative, -1022		*/
    +    0xBCA00000,		/* negative,   -53		*/
    +    0xBFD00000,		/* negative,    -2		*/
    +    0xBFE00000,		/* negative,    -1		*/
    +    0xBFF00000,		/* negative,     0		*/
    +    0xC0000000,		/* negative,     1		*/
    +    0xC0100000,		/* negative,     2		*/
    +    0xC3400000,		/* negative,    53		*/
    +    0xFFE00000,		/* negative,  1023		*/
    +    0xFFF00000		/* negative, infinity or NaN	*/
    +};
    +
    +static const uint32 float64QOut[ float64NumQOut ] = {
    +    0x00000000,		/* positive, subnormal		*/
    +    0x00100000,		/* positive, -1022		*/
    +    0x00200000,		/* positive, -1021		*/
    +    0x37E00000,		/* positive,  -129		*/
    +    0x37F00000,		/* positive,  -128		*/
    +    0x38000000,		/* positive,  -127		*/
    +    0x38100000,		/* positive,  -126		*/
    +    0x3CA00000,		/* positive,   -53		*/
    +    0x3FB00000,		/* positive,    -4		*/
    +    0x3FC00000,		/* positive,    -3		*/
    +    0x3FD00000,		/* positive,    -2		*/
    +    0x3FE00000,		/* positive,    -1		*/
    +    0x3FF00000,		/* positive,     0		*/
    +    0x40000000,		/* positive,     1		*/
    +    0x40100000,		/* positive,     2		*/
    +    0x40200000,		/* positive,     3		*/
    +    0x40300000,		/* positive,     4		*/
    +    0x41C00000,		/* positive,    29		*/
    +    0x41D00000,		/* positive,    30		*/
    +    0x41E00000,		/* positive,    31		*/
    +    0x41F00000,		/* positive,    32		*/
    +    0x43400000,		/* positive,    53		*/
    +    0x43C00000,		/* positive,    61		*/
    +    0x43D00000,		/* positive,    62		*/
    +    0x43E00000,		/* positive,    63		*/
    +    0x43F00000,		/* positive,    64		*/
    +    0x47E00000,		/* positive,   127		*/
    +    0x47F00000,		/* positive,   128		*/
    +    0x48000000,		/* positive,   129		*/
    +    0x7FD00000,		/* positive,  1022		*/
    +    0x7FE00000,		/* positive,  1023		*/
    +    0x7FF00000,		/* positive, infinity or NaN	*/
    +    0x80000000,		/* negative, subnormal		*/
    +    0x80100000,		/* negative, -1022		*/
    +    0x80200000,		/* negative, -1021		*/
    +    0xB7E00000,		/* negative,  -129		*/
    +    0xB7F00000,		/* negative,  -128		*/
    +    0xB8000000,		/* negative,  -127		*/
    +    0xB8100000,		/* negative,  -126		*/
    +    0xBCA00000,		/* negative,   -53		*/
    +    0xBFB00000,		/* negative,    -4		*/
    +    0xBFC00000,		/* negative,    -3		*/
    +    0xBFD00000,		/* negative,    -2		*/
    +    0xBFE00000,		/* negative,    -1		*/
    +    0xBFF00000,		/* negative,     0		*/
    +    0xC0000000,		/* negative,     1		*/
    +    0xC0100000,		/* negative,     2		*/
    +    0xC0200000,		/* negative,     3		*/
    +    0xC0300000,		/* negative,     4		*/
    +    0xC1C00000,		/* negative,    29		*/
    +    0xC1D00000,		/* negative,    30		*/
    +    0xC1E00000,		/* negative,    31		*/
    +    0xC1F00000,		/* negative,    32		*/
    +    0xC3400000,		/* negative,    53		*/
    +    0xC3C00000,		/* negative,    61		*/
    +    0xC3D00000,		/* negative,    62		*/
    +    0xC3E00000,		/* negative,    63		*/
    +    0xC3F00000,		/* negative,    64		*/
    +    0xC7E00000,		/* negative,   127		*/
    +    0xC7F00000,		/* negative,   128		*/
    +    0xC8000000,		/* negative,   129		*/
    +    0xFFD00000,		/* negative,  1022		*/
    +    0xFFE00000,		/* negative,  1023		*/
    +    0xFFF00000		/* negative, infinity or NaN	*/
    +};
    +
    +static const struct { bits32 high, low; } float64P1[ float64NumP1 ] = {
    +    { 0x00000000, 0x00000000 },
    +    { 0x00000000, 0x00000001 },
    +    { 0x000FFFFF, 0xFFFFFFFF },
    +    { 0x000FFFFF, 0xFFFFFFFE }
    +};
    +
    +static const struct { bits32 high, low; } float64P2[ float64NumP2 ] = {
    +    { 0x00000000, 0x00000000 },
    +    { 0x00000000, 0x00000001 },
    +    { 0x00000000, 0x00000002 },
    +    { 0x00000000, 0x00000004 },
    +    { 0x00000000, 0x00000008 },
    +    { 0x00000000, 0x00000010 },
    +    { 0x00000000, 0x00000020 },
    +    { 0x00000000, 0x00000040 },
    +    { 0x00000000, 0x00000080 },
    +    { 0x00000000, 0x00000100 },
    +    { 0x00000000, 0x00000200 },
    +    { 0x00000000, 0x00000400 },
    +    { 0x00000000, 0x00000800 },
    +    { 0x00000000, 0x00001000 },
    +    { 0x00000000, 0x00002000 },
    +    { 0x00000000, 0x00004000 },
    +    { 0x00000000, 0x00008000 },
    +    { 0x00000000, 0x00010000 },
    +    { 0x00000000, 0x00020000 },
    +    { 0x00000000, 0x00040000 },
    +    { 0x00000000, 0x00080000 },
    +    { 0x00000000, 0x00100000 },
    +    { 0x00000000, 0x00200000 },
    +    { 0x00000000, 0x00400000 },
    +    { 0x00000000, 0x00800000 },
    +    { 0x00000000, 0x01000000 },
    +    { 0x00000000, 0x02000000 },
    +    { 0x00000000, 0x04000000 },
    +    { 0x00000000, 0x08000000 },
    +    { 0x00000000, 0x10000000 },
    +    { 0x00000000, 0x20000000 },
    +    { 0x00000000, 0x40000000 },
    +    { 0x00000000, 0x80000000 },
    +    { 0x00000001, 0x00000000 },
    +    { 0x00000002, 0x00000000 },
    +    { 0x00000004, 0x00000000 },
    +    { 0x00000008, 0x00000000 },
    +    { 0x00000010, 0x00000000 },
    +    { 0x00000020, 0x00000000 },
    +    { 0x00000040, 0x00000000 },
    +    { 0x00000080, 0x00000000 },
    +    { 0x00000100, 0x00000000 },
    +    { 0x00000200, 0x00000000 },
    +    { 0x00000400, 0x00000000 },
    +    { 0x00000800, 0x00000000 },
    +    { 0x00001000, 0x00000000 },
    +    { 0x00002000, 0x00000000 },
    +    { 0x00004000, 0x00000000 },
    +    { 0x00008000, 0x00000000 },
    +    { 0x00010000, 0x00000000 },
    +    { 0x00020000, 0x00000000 },
    +    { 0x00040000, 0x00000000 },
    +    { 0x00080000, 0x00000000 },
    +    { 0x000C0000, 0x00000000 },
    +    { 0x000E0000, 0x00000000 },
    +    { 0x000F0000, 0x00000000 },
    +    { 0x000F8000, 0x00000000 },
    +    { 0x000FC000, 0x00000000 },
    +    { 0x000FE000, 0x00000000 },
    +    { 0x000FF000, 0x00000000 },
    +    { 0x000FF800, 0x00000000 },
    +    { 0x000FFC00, 0x00000000 },
    +    { 0x000FFE00, 0x00000000 },
    +    { 0x000FFF00, 0x00000000 },
    +    { 0x000FFF80, 0x00000000 },
    +    { 0x000FFFC0, 0x00000000 },
    +    { 0x000FFFE0, 0x00000000 },
    +    { 0x000FFFF0, 0x00000000 },
    +    { 0x000FFFF8, 0x00000000 },
    +    { 0x000FFFFC, 0x00000000 },
    +    { 0x000FFFFE, 0x00000000 },
    +    { 0x000FFFFF, 0x00000000 },
    +    { 0x000FFFFF, 0x80000000 },
    +    { 0x000FFFFF, 0xC0000000 },
    +    { 0x000FFFFF, 0xE0000000 },
    +    { 0x000FFFFF, 0xF0000000 },
    +    { 0x000FFFFF, 0xF8000000 },
    +    { 0x000FFFFF, 0xFC000000 },
    +    { 0x000FFFFF, 0xFE000000 },
    +    { 0x000FFFFF, 0xFF000000 },
    +    { 0x000FFFFF, 0xFF800000 },
    +    { 0x000FFFFF, 0xFFC00000 },
    +    { 0x000FFFFF, 0xFFE00000 },
    +    { 0x000FFFFF, 0xFFF00000 },
    +    { 0x000FFFFF, 0xFFF80000 },
    +    { 0x000FFFFF, 0xFFFC0000 },
    +    { 0x000FFFFF, 0xFFFE0000 },
    +    { 0x000FFFFF, 0xFFFF0000 },
    +    { 0x000FFFFF, 0xFFFF8000 },
    +    { 0x000FFFFF, 0xFFFFC000 },
    +    { 0x000FFFFF, 0xFFFFE000 },
    +    { 0x000FFFFF, 0xFFFFF000 },
    +    { 0x000FFFFF, 0xFFFFF800 },
    +    { 0x000FFFFF, 0xFFFFFC00 },
    +    { 0x000FFFFF, 0xFFFFFE00 },
    +    { 0x000FFFFF, 0xFFFFFF00 },
    +    { 0x000FFFFF, 0xFFFFFF80 },
    +    { 0x000FFFFF, 0xFFFFFFC0 },
    +    { 0x000FFFFF, 0xFFFFFFE0 },
    +    { 0x000FFFFF, 0xFFFFFFF0 },
    +    { 0x000FFFFF, 0xFFFFFFF8 },
    +    { 0x000FFFFF, 0xFFFFFFFC },
    +    { 0x000FFFFF, 0xFFFFFFFE },
    +    { 0x000FFFFF, 0xFFFFFFFF },
    +    { 0x000FFFFF, 0xFFFFFFFD },
    +    { 0x000FFFFF, 0xFFFFFFFB },
    +    { 0x000FFFFF, 0xFFFFFFF7 },
    +    { 0x000FFFFF, 0xFFFFFFEF },
    +    { 0x000FFFFF, 0xFFFFFFDF },
    +    { 0x000FFFFF, 0xFFFFFFBF },
    +    { 0x000FFFFF, 0xFFFFFF7F },
    +    { 0x000FFFFF, 0xFFFFFEFF },
    +    { 0x000FFFFF, 0xFFFFFDFF },
    +    { 0x000FFFFF, 0xFFFFFBFF },
    +    { 0x000FFFFF, 0xFFFFF7FF },
    +    { 0x000FFFFF, 0xFFFFEFFF },
    +    { 0x000FFFFF, 0xFFFFDFFF },
    +    { 0x000FFFFF, 0xFFFFBFFF },
    +    { 0x000FFFFF, 0xFFFF7FFF },
    +    { 0x000FFFFF, 0xFFFEFFFF },
    +    { 0x000FFFFF, 0xFFFDFFFF },
    +    { 0x000FFFFF, 0xFFFBFFFF },
    +    { 0x000FFFFF, 0xFFF7FFFF },
    +    { 0x000FFFFF, 0xFFEFFFFF },
    +    { 0x000FFFFF, 0xFFDFFFFF },
    +    { 0x000FFFFF, 0xFFBFFFFF },
    +    { 0x000FFFFF, 0xFF7FFFFF },
    +    { 0x000FFFFF, 0xFEFFFFFF },
    +    { 0x000FFFFF, 0xFDFFFFFF },
    +    { 0x000FFFFF, 0xFBFFFFFF },
    +    { 0x000FFFFF, 0xF7FFFFFF },
    +    { 0x000FFFFF, 0xEFFFFFFF },
    +    { 0x000FFFFF, 0xDFFFFFFF },
    +    { 0x000FFFFF, 0xBFFFFFFF },
    +    { 0x000FFFFF, 0x7FFFFFFF },
    +    { 0x000FFFFE, 0xFFFFFFFF },
    +    { 0x000FFFFD, 0xFFFFFFFF },
    +    { 0x000FFFFB, 0xFFFFFFFF },
    +    { 0x000FFFF7, 0xFFFFFFFF },
    +    { 0x000FFFEF, 0xFFFFFFFF },
    +    { 0x000FFFDF, 0xFFFFFFFF },
    +    { 0x000FFFBF, 0xFFFFFFFF },
    +    { 0x000FFF7F, 0xFFFFFFFF },
    +    { 0x000FFEFF, 0xFFFFFFFF },
    +    { 0x000FFDFF, 0xFFFFFFFF },
    +    { 0x000FFBFF, 0xFFFFFFFF },
    +    { 0x000FF7FF, 0xFFFFFFFF },
    +    { 0x000FEFFF, 0xFFFFFFFF },
    +    { 0x000FDFFF, 0xFFFFFFFF },
    +    { 0x000FBFFF, 0xFFFFFFFF },
    +    { 0x000F7FFF, 0xFFFFFFFF },
    +    { 0x000EFFFF, 0xFFFFFFFF },
    +    { 0x000DFFFF, 0xFFFFFFFF },
    +    { 0x000BFFFF, 0xFFFFFFFF },
    +    { 0x0007FFFF, 0xFFFFFFFF },
    +    { 0x0003FFFF, 0xFFFFFFFF },
    +    { 0x0001FFFF, 0xFFFFFFFF },
    +    { 0x0000FFFF, 0xFFFFFFFF },
    +    { 0x00007FFF, 0xFFFFFFFF },
    +    { 0x00003FFF, 0xFFFFFFFF },
    +    { 0x00001FFF, 0xFFFFFFFF },
    +    { 0x00000FFF, 0xFFFFFFFF },
    +    { 0x000007FF, 0xFFFFFFFF },
    +    { 0x000003FF, 0xFFFFFFFF },
    +    { 0x000001FF, 0xFFFFFFFF },
    +    { 0x000000FF, 0xFFFFFFFF },
    +    { 0x0000007F, 0xFFFFFFFF },
    +    { 0x0000003F, 0xFFFFFFFF },
    +    { 0x0000001F, 0xFFFFFFFF },
    +    { 0x0000000F, 0xFFFFFFFF },
    +    { 0x00000007, 0xFFFFFFFF },
    +    { 0x00000003, 0xFFFFFFFF },
    +    { 0x00000001, 0xFFFFFFFF },
    +    { 0x00000000, 0xFFFFFFFF },
    +    { 0x00000000, 0x7FFFFFFF },
    +    { 0x00000000, 0x3FFFFFFF },
    +    { 0x00000000, 0x1FFFFFFF },
    +    { 0x00000000, 0x0FFFFFFF },
    +    { 0x00000000, 0x07FFFFFF },
    +    { 0x00000000, 0x03FFFFFF },
    +    { 0x00000000, 0x01FFFFFF },
    +    { 0x00000000, 0x00FFFFFF },
    +    { 0x00000000, 0x007FFFFF },
    +    { 0x00000000, 0x003FFFFF },
    +    { 0x00000000, 0x001FFFFF },
    +    { 0x00000000, 0x000FFFFF },
    +    { 0x00000000, 0x0007FFFF },
    +    { 0x00000000, 0x0003FFFF },
    +    { 0x00000000, 0x0001FFFF },
    +    { 0x00000000, 0x0000FFFF },
    +    { 0x00000000, 0x00007FFF },
    +    { 0x00000000, 0x00003FFF },
    +    { 0x00000000, 0x00001FFF },
    +    { 0x00000000, 0x00000FFF },
    +    { 0x00000000, 0x000007FF },
    +    { 0x00000000, 0x000003FF },
    +    { 0x00000000, 0x000001FF },
    +    { 0x00000000, 0x000000FF },
    +    { 0x00000000, 0x0000007F },
    +    { 0x00000000, 0x0000003F },
    +    { 0x00000000, 0x0000001F },
    +    { 0x00000000, 0x0000000F },
    +    { 0x00000000, 0x00000007 },
    +    { 0x00000000, 0x00000003 }
    +};
    +
    +static const uint32 float64NumQInP1 = float64NumQIn * float64NumP1;
    +static const uint32 float64NumQOutP1 = float64NumQOut * float64NumP1;
    +
    +static float64 float64NextQInP1( sequenceT *sequencePtr )
    +{
    +    uint8 expNum, sigNum;
    +    float64 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    SETFLOAT64(
    +        z,
    +        float64QIn[ expNum ] | float64P1[ sigNum ].high,
    +        float64P1[ sigNum ].low
    +    );
    +    ++sigNum;
    +    if ( float64NumP1 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float64NumQIn <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static float64 float64NextQOutP1( sequenceT *sequencePtr )
    +{
    +    uint8 expNum, sigNum;
    +    float64 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    SETFLOAT64(
    +        z,
    +        float64QOut[ expNum ] | float64P1[ sigNum ].high,
    +        float64P1[ sigNum ].low
    +    );
    +    ++sigNum;
    +    if ( float64NumP1 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float64NumQOut <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static const uint32 float64NumQInP2 = float64NumQIn * float64NumP2;
    +static const uint32 float64NumQOutP2 = float64NumQOut * float64NumP2;
    +
    +static float64 float64NextQInP2( sequenceT *sequencePtr )
    +{
    +    uint8 expNum, sigNum;
    +    float64 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    SETFLOAT64(
    +        z,
    +        float64QIn[ expNum ] | float64P2[ sigNum ].high,
    +        float64P2[ sigNum ].low
    +    );
    +    ++sigNum;
    +    if ( float64NumP2 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float64NumQIn <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static float64 float64NextQOutP2( sequenceT *sequencePtr )
    +{
    +    uint8 expNum, sigNum;
    +    float64 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    SETFLOAT64(
    +        z,
    +        float64QOut[ expNum ] | float64P2[ sigNum ].high,
    +        float64P2[ sigNum ].low
    +    );
    +    ++sigNum;
    +    if ( float64NumP2 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float64NumQOut <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static float64 float64RandomQOutP3( void )
    +{
    +    int8 sigNum1, sigNum2;
    +    uint32 sig1Low, sig2Low, zLow;
    +    float64 z;
    +
    +    sigNum1 = randomUint8() % float64NumP2;
    +    sigNum2 = randomUint8() % float64NumP2;
    +    sig1Low = float64P2[ sigNum1 ].low;
    +    sig2Low = float64P2[ sigNum2 ].low;
    +    zLow = sig1Low + sig2Low;
    +    SETFLOAT64(
    +        z,
    +          float64QOut[ randomUint8() % float64NumQOut ]
    +        | (   (   float64P2[ sigNum1 ].high
    +                + float64P2[ sigNum2 ].high
    +                + ( zLow < sig1Low )
    +              )
    +            & 0x000FFFFF
    +          ),
    +        zLow
    +    );
    +    return z;
    +
    +}
    +
    +static float64 float64RandomQOutPInf( void )
    +{
    +    float64 z;
    +
    +    SETFLOAT64(
    +        z,
    +          float64QOut[ randomUint8() % float64NumQOut ]
    +        | ( randomUint32() & 0x000FFFFF ),
    +        randomUint32()
    +    );
    +    return z;
    +
    +}
    +
    +enum {
    +    float64NumQInfWeightMasks = 10
    +};
    +
    +static const uint32 float64QInfWeightMasks[ float64NumQInfWeightMasks ] = {
    +    0x7FF00000,
    +    0x7FF00000,
    +    0x3FF00000,
    +    0x1FF00000,
    +    0x0FF00000,
    +    0x07F00000,
    +    0x03F00000,
    +    0x01F00000,
    +    0x00F00000,
    +    0x00700000
    +};
    +
    +static const uint32 float64QInfWeightOffsets[ float64NumQInfWeightMasks ] = {
    +    0x00000000,
    +    0x00000000,
    +    0x20000000,
    +    0x30000000,
    +    0x38000000,
    +    0x3C000000,
    +    0x3E000000,
    +    0x3F000000,
    +    0x3F800000,
    +    0x3FC00000
    +};
    +
    +static float64 float64RandomQInfP3( void )
    +{
    +    int8 sigNum1, sigNum2;
    +    uint32 sig1Low, sig2Low, zLow;
    +    int8 weightMaskNum;
    +    float64 z;
    +
    +    sigNum1 = randomUint8() % float64NumP2;
    +    sigNum2 = randomUint8() % float64NumP2;
    +    sig1Low = float64P2[ sigNum1 ].low;
    +    sig2Low = float64P2[ sigNum2 ].low;
    +    zLow = sig1Low + sig2Low;
    +    weightMaskNum = randomUint8() % float64NumQInfWeightMasks;
    +    SETFLOAT64(
    +        z,
    +          ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
    +        | (   (   ( ( (uint32) ( randomUint16() & 0xFFF ) )<<20 )
    +                & float64QInfWeightMasks[ weightMaskNum ] )
    +            + float64QInfWeightOffsets[ weightMaskNum ]
    +          )
    +        | (   (   float64P2[ sigNum1 ].high
    +                + float64P2[ sigNum2 ].high
    +                + ( zLow < sig1Low )
    +              )
    +            & 0x000FFFFF
    +          ),
    +        zLow
    +    );
    +    return z;
    +
    +}
    +
    +static float64 float64RandomQInfPInf( void )
    +{
    +    int8 weightMaskNum;
    +    float64 z;
    +
    +    weightMaskNum = randomUint8() % float64NumQInfWeightMasks;
    +    SETFLOAT64(
    +        z,
    +          ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
    +        | (   (   ( ( (uint32) ( randomUint16() & 0xFFF ) )<<20 )
    +                & float64QInfWeightMasks[ weightMaskNum ] )
    +            + float64QInfWeightOffsets[ weightMaskNum ]
    +          )
    +        | ( randomUint32() & 0x000FFFFF ),
    +        randomUint32()
    +    );
    +    return z;
    +
    +}
    +
    +static float64 float64Random( void )
    +{
    +
    +    switch ( randomUint8() & 7 ) {
    +     case 0:
    +     case 1:
    +     case 2:
    +        return float64RandomQOutP3();
    +     case 3:
    +        return float64RandomQOutPInf();
    +     case 4:
    +     case 5:
    +     case 6:
    +        return float64RandomQInfP3();
    +     default:
    +        return float64RandomQInfPInf();
    +    }
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +enum {
    +    floatx80NumQIn  =  22,
    +    floatx80NumQOut =  76,
    +    floatx80NumP1   =   4,
    +    floatx80NumP2   = 248
    +};
    +
    +static const uint16 floatx80QIn[ floatx80NumQIn ] = {
    +    0x0000,		/* positive, subnormal		*/
    +    0x0001,		/* positive, -16382		*/
    +    0x3FBF,		/* positive,    -64		*/
    +    0x3FFD,		/* positive,     -2		*/
    +    0x3FFE,		/* positive,     -1		*/
    +    0x3FFF,		/* positive,      0		*/
    +    0x4000,		/* positive,      1		*/
    +    0x4001,		/* positive,      2		*/
    +    0x403F,		/* positive,     64		*/
    +    0x7FFE,		/* positive,  16383		*/
    +    0x7FFF,		/* positive, infinity or NaN	*/
    +    0x8000,		/* negative, subnormal		*/
    +    0x8001,		/* negative, -16382		*/
    +    0xBFBF,		/* negative,    -64		*/
    +    0xBFFD,		/* negative,     -2		*/
    +    0xBFFE,		/* negative,     -1		*/
    +    0xBFFF,		/* negative,      0		*/
    +    0xC000,		/* negative,      1		*/
    +    0xC001,		/* negative,      2		*/
    +    0xC03F,		/* negative,     64		*/
    +    0xFFFE,		/* negative,  16383		*/
    +    0xFFFF		/* negative, infinity or NaN	*/
    +};
    +
    +static const uint16 floatx80QOut[ floatx80NumQOut ] = {
    +    0x0000,		/* positive, subnormal		*/
    +    0x0001,		/* positive, -16382		*/
    +    0x0002,		/* positive, -16381		*/
    +    0x3BFE,		/* positive,  -1025		*/
    +    0x3BFF,		/* positive,  -1024		*/
    +    0x3C00,		/* positive,  -1023		*/
    +    0x3C01,		/* positive,  -1022		*/
    +    0x3F7E,		/* positive,   -129		*/
    +    0x3F7F,		/* positive,   -128		*/
    +    0x3F80,		/* positive,   -127		*/
    +    0x3F81,		/* positive,   -126		*/
    +    0x3FBF,		/* positive,    -64		*/
    +    0x3FFB,		/* positive,     -4		*/
    +    0x3FFC,		/* positive,     -3		*/
    +    0x3FFD,		/* positive,     -2		*/
    +    0x3FFE,		/* positive,     -1		*/
    +    0x3FFF,		/* positive,      0		*/
    +    0x4000,		/* positive,      1		*/
    +    0x4001,		/* positive,      2		*/
    +    0x4002,		/* positive,      3		*/
    +    0x4003,		/* positive,      4		*/
    +    0x401C,		/* positive,     29		*/
    +    0x401D,		/* positive,     30		*/
    +    0x401E,		/* positive,     31		*/
    +    0x401F,		/* positive,     32		*/
    +    0x403C,		/* positive,     61		*/
    +    0x403D,		/* positive,     62		*/
    +    0x403E,		/* positive,     63		*/
    +    0x403F,		/* positive,     64		*/
    +    0x407E,		/* positive,    127		*/
    +    0x407F,		/* positive,    128		*/
    +    0x4080,		/* positive,    129		*/
    +    0x43FE,		/* positive,   1023		*/
    +    0x43FF,		/* positive,   1024		*/
    +    0x4400,		/* positive,   1025		*/
    +    0x7FFD,		/* positive,  16382		*/
    +    0x7FFE,		/* positive,  16383		*/
    +    0x7FFF,		/* positive, infinity or NaN	*/
    +    0x8000,		/* negative, subnormal		*/
    +    0x8001,		/* negative, -16382		*/
    +    0x8002,		/* negative, -16381		*/
    +    0xBBFE,		/* negative,  -1025		*/
    +    0xBBFF,		/* negative,  -1024		*/
    +    0xBC00,		/* negative,  -1023		*/
    +    0xBC01,		/* negative,  -1022		*/
    +    0xBF7E,		/* negative,   -129		*/
    +    0xBF7F,		/* negative,   -128		*/
    +    0xBF80,		/* negative,   -127		*/
    +    0xBF81,		/* negative,   -126		*/
    +    0xBFBF,		/* negative,    -64		*/
    +    0xBFFB,		/* negative,     -4		*/
    +    0xBFFC,		/* negative,     -3		*/
    +    0xBFFD,		/* negative,     -2		*/
    +    0xBFFE,		/* negative,     -1		*/
    +    0xBFFF,		/* negative,      0		*/
    +    0xC000,		/* negative,      1		*/
    +    0xC001,		/* negative,      2		*/
    +    0xC002,		/* negative,      3		*/
    +    0xC003,		/* negative,      4		*/
    +    0xC01C,		/* negative,     29		*/
    +    0xC01D,		/* negative,     30		*/
    +    0xC01E,		/* negative,     31		*/
    +    0xC01F,		/* negative,     32		*/
    +    0xC03C,		/* negative,     61		*/
    +    0xC03D,		/* negative,     62		*/
    +    0xC03E,		/* negative,     63		*/
    +    0xC03F,		/* negative,     64		*/
    +    0xC07E,		/* negative,    127		*/
    +    0xC07F,		/* negative,    128		*/
    +    0xC080,		/* negative,    129		*/
    +    0xC3FE,		/* negative,   1023		*/
    +    0xC3FF,		/* negative,   1024		*/
    +    0xC400,		/* negative,   1025		*/
    +    0xFFFD,		/* negative,  16382		*/
    +    0xFFFE,		/* negative,  16383		*/
    +    0xFFFF		/* negative, infinity or NaN	*/
    +};
    +
    +static const bits64 floatx80P1[ floatx80NumP1 ] = {
    +    LIT64( 0x0000000000000000 ),
    +    LIT64( 0x0000000000000001 ),
    +    LIT64( 0x7FFFFFFFFFFFFFFF ),
    +    LIT64( 0x7FFFFFFFFFFFFFFE )
    +};
    +
    +static const bits64 floatx80P2[ floatx80NumP2 ] = {
    +    LIT64( 0x0000000000000000 ),
    +    LIT64( 0x0000000000000001 ),
    +    LIT64( 0x0000000000000002 ),
    +    LIT64( 0x0000000000000004 ),
    +    LIT64( 0x0000000000000008 ),
    +    LIT64( 0x0000000000000010 ),
    +    LIT64( 0x0000000000000020 ),
    +    LIT64( 0x0000000000000040 ),
    +    LIT64( 0x0000000000000080 ),
    +    LIT64( 0x0000000000000100 ),
    +    LIT64( 0x0000000000000200 ),
    +    LIT64( 0x0000000000000400 ),
    +    LIT64( 0x0000000000000800 ),
    +    LIT64( 0x0000000000001000 ),
    +    LIT64( 0x0000000000002000 ),
    +    LIT64( 0x0000000000004000 ),
    +    LIT64( 0x0000000000008000 ),
    +    LIT64( 0x0000000000010000 ),
    +    LIT64( 0x0000000000020000 ),
    +    LIT64( 0x0000000000040000 ),
    +    LIT64( 0x0000000000080000 ),
    +    LIT64( 0x0000000000100000 ),
    +    LIT64( 0x0000000000200000 ),
    +    LIT64( 0x0000000000400000 ),
    +    LIT64( 0x0000000000800000 ),
    +    LIT64( 0x0000000001000000 ),
    +    LIT64( 0x0000000002000000 ),
    +    LIT64( 0x0000000004000000 ),
    +    LIT64( 0x0000000008000000 ),
    +    LIT64( 0x0000000010000000 ),
    +    LIT64( 0x0000000020000000 ),
    +    LIT64( 0x0000000040000000 ),
    +    LIT64( 0x0000000080000000 ),
    +    LIT64( 0x0000000100000000 ),
    +    LIT64( 0x0000000200000000 ),
    +    LIT64( 0x0000000400000000 ),
    +    LIT64( 0x0000000800000000 ),
    +    LIT64( 0x0000001000000000 ),
    +    LIT64( 0x0000002000000000 ),
    +    LIT64( 0x0000004000000000 ),
    +    LIT64( 0x0000008000000000 ),
    +    LIT64( 0x0000010000000000 ),
    +    LIT64( 0x0000020000000000 ),
    +    LIT64( 0x0000040000000000 ),
    +    LIT64( 0x0000080000000000 ),
    +    LIT64( 0x0000100000000000 ),
    +    LIT64( 0x0000200000000000 ),
    +    LIT64( 0x0000400000000000 ),
    +    LIT64( 0x0000800000000000 ),
    +    LIT64( 0x0001000000000000 ),
    +    LIT64( 0x0002000000000000 ),
    +    LIT64( 0x0004000000000000 ),
    +    LIT64( 0x0008000000000000 ),
    +    LIT64( 0x0010000000000000 ),
    +    LIT64( 0x0020000000000000 ),
    +    LIT64( 0x0040000000000000 ),
    +    LIT64( 0x0080000000000000 ),
    +    LIT64( 0x0100000000000000 ),
    +    LIT64( 0x0200000000000000 ),
    +    LIT64( 0x0400000000000000 ),
    +    LIT64( 0x0800000000000000 ),
    +    LIT64( 0x1000000000000000 ),
    +    LIT64( 0x2000000000000000 ),
    +    LIT64( 0x4000000000000000 ),
    +    LIT64( 0x6000000000000000 ),
    +    LIT64( 0x7000000000000000 ),
    +    LIT64( 0x7800000000000000 ),
    +    LIT64( 0x7C00000000000000 ),
    +    LIT64( 0x7E00000000000000 ),
    +    LIT64( 0x7F00000000000000 ),
    +    LIT64( 0x7F80000000000000 ),
    +    LIT64( 0x7FC0000000000000 ),
    +    LIT64( 0x7FE0000000000000 ),
    +    LIT64( 0x7FF0000000000000 ),
    +    LIT64( 0x7FF8000000000000 ),
    +    LIT64( 0x7FFC000000000000 ),
    +    LIT64( 0x7FFE000000000000 ),
    +    LIT64( 0x7FFF000000000000 ),
    +    LIT64( 0x7FFF800000000000 ),
    +    LIT64( 0x7FFFC00000000000 ),
    +    LIT64( 0x7FFFE00000000000 ),
    +    LIT64( 0x7FFFF00000000000 ),
    +    LIT64( 0x7FFFF80000000000 ),
    +    LIT64( 0x7FFFFC0000000000 ),
    +    LIT64( 0x7FFFFE0000000000 ),
    +    LIT64( 0x7FFFFF0000000000 ),
    +    LIT64( 0x7FFFFF8000000000 ),
    +    LIT64( 0x7FFFFFC000000000 ),
    +    LIT64( 0x7FFFFFE000000000 ),
    +    LIT64( 0x7FFFFFF000000000 ),
    +    LIT64( 0x7FFFFFF800000000 ),
    +    LIT64( 0x7FFFFFFC00000000 ),
    +    LIT64( 0x7FFFFFFE00000000 ),
    +    LIT64( 0x7FFFFFFF00000000 ),
    +    LIT64( 0x7FFFFFFF80000000 ),
    +    LIT64( 0x7FFFFFFFC0000000 ),
    +    LIT64( 0x7FFFFFFFE0000000 ),
    +    LIT64( 0x7FFFFFFFF0000000 ),
    +    LIT64( 0x7FFFFFFFF8000000 ),
    +    LIT64( 0x7FFFFFFFFC000000 ),
    +    LIT64( 0x7FFFFFFFFE000000 ),
    +    LIT64( 0x7FFFFFFFFF000000 ),
    +    LIT64( 0x7FFFFFFFFF800000 ),
    +    LIT64( 0x7FFFFFFFFFC00000 ),
    +    LIT64( 0x7FFFFFFFFFE00000 ),
    +    LIT64( 0x7FFFFFFFFFF00000 ),
    +    LIT64( 0x7FFFFFFFFFF80000 ),
    +    LIT64( 0x7FFFFFFFFFFC0000 ),
    +    LIT64( 0x7FFFFFFFFFFE0000 ),
    +    LIT64( 0x7FFFFFFFFFFF0000 ),
    +    LIT64( 0x7FFFFFFFFFFF8000 ),
    +    LIT64( 0x7FFFFFFFFFFFC000 ),
    +    LIT64( 0x7FFFFFFFFFFFE000 ),
    +    LIT64( 0x7FFFFFFFFFFFF000 ),
    +    LIT64( 0x7FFFFFFFFFFFF800 ),
    +    LIT64( 0x7FFFFFFFFFFFFC00 ),
    +    LIT64( 0x7FFFFFFFFFFFFE00 ),
    +    LIT64( 0x7FFFFFFFFFFFFF00 ),
    +    LIT64( 0x7FFFFFFFFFFFFF80 ),
    +    LIT64( 0x7FFFFFFFFFFFFFC0 ),
    +    LIT64( 0x7FFFFFFFFFFFFFE0 ),
    +    LIT64( 0x7FFFFFFFFFFFFFF0 ),
    +    LIT64( 0x7FFFFFFFFFFFFFF8 ),
    +    LIT64( 0x7FFFFFFFFFFFFFFC ),
    +    LIT64( 0x7FFFFFFFFFFFFFFE ),
    +    LIT64( 0x7FFFFFFFFFFFFFFF ),
    +    LIT64( 0x7FFFFFFFFFFFFFFD ),
    +    LIT64( 0x7FFFFFFFFFFFFFFB ),
    +    LIT64( 0x7FFFFFFFFFFFFFF7 ),
    +    LIT64( 0x7FFFFFFFFFFFFFEF ),
    +    LIT64( 0x7FFFFFFFFFFFFFDF ),
    +    LIT64( 0x7FFFFFFFFFFFFFBF ),
    +    LIT64( 0x7FFFFFFFFFFFFF7F ),
    +    LIT64( 0x7FFFFFFFFFFFFEFF ),
    +    LIT64( 0x7FFFFFFFFFFFFDFF ),
    +    LIT64( 0x7FFFFFFFFFFFFBFF ),
    +    LIT64( 0x7FFFFFFFFFFFF7FF ),
    +    LIT64( 0x7FFFFFFFFFFFEFFF ),
    +    LIT64( 0x7FFFFFFFFFFFDFFF ),
    +    LIT64( 0x7FFFFFFFFFFFBFFF ),
    +    LIT64( 0x7FFFFFFFFFFF7FFF ),
    +    LIT64( 0x7FFFFFFFFFFEFFFF ),
    +    LIT64( 0x7FFFFFFFFFFDFFFF ),
    +    LIT64( 0x7FFFFFFFFFFBFFFF ),
    +    LIT64( 0x7FFFFFFFFFF7FFFF ),
    +    LIT64( 0x7FFFFFFFFFEFFFFF ),
    +    LIT64( 0x7FFFFFFFFFDFFFFF ),
    +    LIT64( 0x7FFFFFFFFFBFFFFF ),
    +    LIT64( 0x7FFFFFFFFF7FFFFF ),
    +    LIT64( 0x7FFFFFFFFEFFFFFF ),
    +    LIT64( 0x7FFFFFFFFDFFFFFF ),
    +    LIT64( 0x7FFFFFFFFBFFFFFF ),
    +    LIT64( 0x7FFFFFFFF7FFFFFF ),
    +    LIT64( 0x7FFFFFFFEFFFFFFF ),
    +    LIT64( 0x7FFFFFFFDFFFFFFF ),
    +    LIT64( 0x7FFFFFFFBFFFFFFF ),
    +    LIT64( 0x7FFFFFFF7FFFFFFF ),
    +    LIT64( 0x7FFFFFFEFFFFFFFF ),
    +    LIT64( 0x7FFFFFFDFFFFFFFF ),
    +    LIT64( 0x7FFFFFFBFFFFFFFF ),
    +    LIT64( 0x7FFFFFF7FFFFFFFF ),
    +    LIT64( 0x7FFFFFEFFFFFFFFF ),
    +    LIT64( 0x7FFFFFDFFFFFFFFF ),
    +    LIT64( 0x7FFFFFBFFFFFFFFF ),
    +    LIT64( 0x7FFFFF7FFFFFFFFF ),
    +    LIT64( 0x7FFFFEFFFFFFFFFF ),
    +    LIT64( 0x7FFFFDFFFFFFFFFF ),
    +    LIT64( 0x7FFFFBFFFFFFFFFF ),
    +    LIT64( 0x7FFFF7FFFFFFFFFF ),
    +    LIT64( 0x7FFFEFFFFFFFFFFF ),
    +    LIT64( 0x7FFFDFFFFFFFFFFF ),
    +    LIT64( 0x7FFFBFFFFFFFFFFF ),
    +    LIT64( 0x7FFF7FFFFFFFFFFF ),
    +    LIT64( 0x7FFEFFFFFFFFFFFF ),
    +    LIT64( 0x7FFDFFFFFFFFFFFF ),
    +    LIT64( 0x7FFBFFFFFFFFFFFF ),
    +    LIT64( 0x7FF7FFFFFFFFFFFF ),
    +    LIT64( 0x7FEFFFFFFFFFFFFF ),
    +    LIT64( 0x7FDFFFFFFFFFFFFF ),
    +    LIT64( 0x7FBFFFFFFFFFFFFF ),
    +    LIT64( 0x7F7FFFFFFFFFFFFF ),
    +    LIT64( 0x7EFFFFFFFFFFFFFF ),
    +    LIT64( 0x7DFFFFFFFFFFFFFF ),
    +    LIT64( 0x7BFFFFFFFFFFFFFF ),
    +    LIT64( 0x77FFFFFFFFFFFFFF ),
    +    LIT64( 0x6FFFFFFFFFFFFFFF ),
    +    LIT64( 0x5FFFFFFFFFFFFFFF ),
    +    LIT64( 0x3FFFFFFFFFFFFFFF ),
    +    LIT64( 0x1FFFFFFFFFFFFFFF ),
    +    LIT64( 0x0FFFFFFFFFFFFFFF ),
    +    LIT64( 0x07FFFFFFFFFFFFFF ),
    +    LIT64( 0x03FFFFFFFFFFFFFF ),
    +    LIT64( 0x01FFFFFFFFFFFFFF ),
    +    LIT64( 0x00FFFFFFFFFFFFFF ),
    +    LIT64( 0x007FFFFFFFFFFFFF ),
    +    LIT64( 0x003FFFFFFFFFFFFF ),
    +    LIT64( 0x001FFFFFFFFFFFFF ),
    +    LIT64( 0x000FFFFFFFFFFFFF ),
    +    LIT64( 0x0007FFFFFFFFFFFF ),
    +    LIT64( 0x0003FFFFFFFFFFFF ),
    +    LIT64( 0x0001FFFFFFFFFFFF ),
    +    LIT64( 0x0000FFFFFFFFFFFF ),
    +    LIT64( 0x00007FFFFFFFFFFF ),
    +    LIT64( 0x00003FFFFFFFFFFF ),
    +    LIT64( 0x00001FFFFFFFFFFF ),
    +    LIT64( 0x00000FFFFFFFFFFF ),
    +    LIT64( 0x000007FFFFFFFFFF ),
    +    LIT64( 0x000003FFFFFFFFFF ),
    +    LIT64( 0x000001FFFFFFFFFF ),
    +    LIT64( 0x000000FFFFFFFFFF ),
    +    LIT64( 0x0000007FFFFFFFFF ),
    +    LIT64( 0x0000003FFFFFFFFF ),
    +    LIT64( 0x0000001FFFFFFFFF ),
    +    LIT64( 0x0000000FFFFFFFFF ),
    +    LIT64( 0x00000007FFFFFFFF ),
    +    LIT64( 0x00000003FFFFFFFF ),
    +    LIT64( 0x00000001FFFFFFFF ),
    +    LIT64( 0x00000000FFFFFFFF ),
    +    LIT64( 0x000000007FFFFFFF ),
    +    LIT64( 0x000000003FFFFFFF ),
    +    LIT64( 0x000000001FFFFFFF ),
    +    LIT64( 0x000000000FFFFFFF ),
    +    LIT64( 0x0000000007FFFFFF ),
    +    LIT64( 0x0000000003FFFFFF ),
    +    LIT64( 0x0000000001FFFFFF ),
    +    LIT64( 0x0000000000FFFFFF ),
    +    LIT64( 0x00000000007FFFFF ),
    +    LIT64( 0x00000000003FFFFF ),
    +    LIT64( 0x00000000001FFFFF ),
    +    LIT64( 0x00000000000FFFFF ),
    +    LIT64( 0x000000000007FFFF ),
    +    LIT64( 0x000000000003FFFF ),
    +    LIT64( 0x000000000001FFFF ),
    +    LIT64( 0x000000000000FFFF ),
    +    LIT64( 0x0000000000007FFF ),
    +    LIT64( 0x0000000000003FFF ),
    +    LIT64( 0x0000000000001FFF ),
    +    LIT64( 0x0000000000000FFF ),
    +    LIT64( 0x00000000000007FF ),
    +    LIT64( 0x00000000000003FF ),
    +    LIT64( 0x00000000000001FF ),
    +    LIT64( 0x00000000000000FF ),
    +    LIT64( 0x000000000000007F ),
    +    LIT64( 0x000000000000003F ),
    +    LIT64( 0x000000000000001F ),
    +    LIT64( 0x000000000000000F ),
    +    LIT64( 0x0000000000000007 ),
    +    LIT64( 0x0000000000000003 )
    +};
    +
    +static const uint32 floatx80NumQInP1 = floatx80NumQIn * floatx80NumP1;
    +static const uint32 floatx80NumQOutP1 = floatx80NumQOut * floatx80NumP1;
    +
    +static floatx80 floatx80NextQInP1( sequenceT *sequencePtr )
    +{
    +    int16 expNum, sigNum;
    +    floatx80 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z.low = floatx80P1[ sigNum ];
    +    z.high = floatx80QIn[ expNum ];
    +    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
    +    ++sigNum;
    +    if ( floatx80NumP1 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( floatx80NumQIn <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static floatx80 floatx80NextQOutP1( sequenceT *sequencePtr )
    +{
    +    int16 expNum, sigNum;
    +    floatx80 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z.low = floatx80P1[ sigNum ];
    +    z.high = floatx80QOut[ expNum ];
    +    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
    +    ++sigNum;
    +    if ( floatx80NumP1 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( floatx80NumQOut <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static const uint32 floatx80NumQInP2 = floatx80NumQIn * floatx80NumP2;
    +static const uint32 floatx80NumQOutP2 = floatx80NumQOut * floatx80NumP2;
    +
    +static floatx80 floatx80NextQInP2( sequenceT *sequencePtr )
    +{
    +    int16 expNum, sigNum;
    +    floatx80 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z.low = floatx80P2[ sigNum ];
    +    z.high = floatx80QIn[ expNum ];
    +    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
    +    ++sigNum;
    +    if ( floatx80NumP2 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( floatx80NumQIn <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static floatx80 floatx80NextQOutP2( sequenceT *sequencePtr )
    +{
    +    int16 expNum, sigNum;
    +    floatx80 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z.low = floatx80P2[ sigNum ];
    +    z.high = floatx80QOut[ expNum ];
    +    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
    +    ++sigNum;
    +    if ( floatx80NumP2 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( floatx80NumQOut <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static floatx80 floatx80RandomQOutP3( void )
    +{
    +    floatx80 z;
    +
    +    z.low =
    +          (   floatx80P2[ randomUint8() % floatx80NumP2 ]
    +            + floatx80P2[ randomUint8() % floatx80NumP2 ] )
    +        & LIT64( 0x7FFFFFFFFFFFFFFF );
    +    z.high = floatx80QOut[ randomUint8() % floatx80NumQOut ];
    +    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
    +    return z;
    +
    +}
    +
    +static floatx80 floatx80RandomQOutPInf( void )
    +{
    +    floatx80 z;
    +
    +    z.low = randomUint64() & LIT64( 0x7FFFFFFFFFFFFFFF );
    +    z.high = floatx80QOut[ randomUint8() % floatx80NumQOut ];
    +    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
    +    return z;
    +
    +}
    +
    +enum {
    +    floatx80NumQInfWeightMasks = 14
    +};
    +
    +static const uint16 floatx80QInfWeightMasks[ floatx80NumQInfWeightMasks ] = {
    +    0x7FFF,
    +    0x7FFF,
    +    0x3FFF,
    +    0x1FFF,
    +    0x07FF,
    +    0x07FF,
    +    0x03FF,
    +    0x01FF,
    +    0x00FF,
    +    0x007F,
    +    0x003F,
    +    0x001F,
    +    0x000F,
    +    0x0007
    +};
    +
    +static const uint16 floatx80QInfWeightOffsets[ floatx80NumQInfWeightMasks ] = {
    +    0x0000,
    +    0x0000,
    +    0x2000,
    +    0x3000,
    +    0x3800,
    +    0x3C00,
    +    0x3E00,
    +    0x3F00,
    +    0x3F80,
    +    0x3FC0,
    +    0x3FE0,
    +    0x3FF0,
    +    0x3FF8,
    +    0x3FFC
    +};
    +
    +static floatx80 floatx80RandomQInfP3( void )
    +{
    +    int8 weightMaskNum;
    +    floatx80 z;
    +
    +    z.low =
    +          (   floatx80P2[ randomUint8() % floatx80NumP2 ]
    +            + floatx80P2[ randomUint8() % floatx80NumP2 ] )
    +        & LIT64( 0x7FFFFFFFFFFFFFFF );
    +    weightMaskNum = randomUint8() % floatx80NumQInfWeightMasks;
    +    z.high =
    +          ( randomUint16() & floatx80QInfWeightMasks[ weightMaskNum ] )
    +        + floatx80QInfWeightOffsets[ weightMaskNum ];
    +    if ( z.high ) z.low |= LIT64( 0x8000000000000000 );
    +    z.high |= ( (uint16) ( randomUint8() & 1 ) )<<15;
    +    return z;
    +
    +}
    +
    +static floatx80 floatx80RandomQInfPInf( void )
    +{
    +    int8 weightMaskNum;
    +    floatx80 z;
    +
    +    z.low = randomUint64() & LIT64( 0x7FFFFFFFFFFFFFFF );
    +    weightMaskNum = randomUint8() % floatx80NumQInfWeightMasks;
    +    z.high =
    +          ( randomUint16() & floatx80QInfWeightMasks[ weightMaskNum ] )
    +        + floatx80QInfWeightOffsets[ weightMaskNum ];
    +    if ( z.high ) z.low |= LIT64( 0x8000000000000000 );
    +    z.high |= ( (uint16) ( randomUint8() & 1 ) )<<15;
    +    return z;
    +
    +}
    +
    +static floatx80 floatx80Random( void )
    +{
    +
    +    switch ( randomUint8() & 7 ) {
    +     case 0:
    +     case 1:
    +     case 2:
    +        return floatx80RandomQOutP3();
    +     case 3:
    +        return floatx80RandomQOutPInf();
    +     case 4:
    +     case 5:
    +     case 6:
    +        return floatx80RandomQInfP3();
    +     default:
    +        return floatx80RandomQInfPInf();
    +    }
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +enum {
    +    float128NumQIn  =  22,
    +    float128NumQOut =  78,
    +    float128NumP1   =   4,
    +    float128NumP2   = 443
    +};
    +
    +static const uint64 float128QIn[ float128NumQIn ] = {
    +    LIT64( 0x0000000000000000 ),	/* positive, subnormal		*/
    +    LIT64( 0x0001000000000000 ),	/* positive, -16382		*/
    +    LIT64( 0x3F8E000000000000 ),	/* positive,   -113		*/
    +    LIT64( 0x3FFD000000000000 ),	/* positive,     -2		*/
    +    LIT64( 0x3FFE000000000000 ),	/* positive,     -1		*/
    +    LIT64( 0x3FFF000000000000 ),	/* positive,      0		*/
    +    LIT64( 0x4000000000000000 ),	/* positive,      1		*/
    +    LIT64( 0x4001000000000000 ),	/* positive,      2		*/
    +    LIT64( 0x4070000000000000 ),	/* positive,    113		*/
    +    LIT64( 0x7FFE000000000000 ),	/* positive,  16383		*/
    +    LIT64( 0x7FFF000000000000 ),	/* positive, infinity or NaN	*/
    +    LIT64( 0x8000000000000000 ),	/* negative, subnormal		*/
    +    LIT64( 0x8001000000000000 ),	/* negative, -16382		*/
    +    LIT64( 0xBF8E000000000000 ),	/* negative,   -113		*/
    +    LIT64( 0xBFFD000000000000 ),	/* negative,     -2		*/
    +    LIT64( 0xBFFE000000000000 ),	/* negative,     -1		*/
    +    LIT64( 0xBFFF000000000000 ),	/* negative,      0		*/
    +    LIT64( 0xC000000000000000 ),	/* negative,      1		*/
    +    LIT64( 0xC001000000000000 ),	/* negative,      2		*/
    +    LIT64( 0xC070000000000000 ),	/* negative,    113		*/
    +    LIT64( 0xFFFE000000000000 ),	/* negative,  16383		*/
    +    LIT64( 0xFFFF000000000000 )		/* negative, infinity or NaN	*/
    +};
    +
    +static const uint64 float128QOut[ float128NumQOut ] = {
    +    LIT64( 0x0000000000000000 ),	/* positive, subnormal		*/
    +    LIT64( 0x0001000000000000 ),	/* positive, -16382		*/
    +    LIT64( 0x0002000000000000 ),	/* positive, -16381		*/
    +    LIT64( 0x3BFE000000000000 ),	/* positive,  -1025		*/
    +    LIT64( 0x3BFF000000000000 ),	/* positive,  -1024		*/
    +    LIT64( 0x3C00000000000000 ),	/* positive,  -1023		*/
    +    LIT64( 0x3C01000000000000 ),	/* positive,  -1022		*/
    +    LIT64( 0x3F7E000000000000 ),	/* positive,   -129		*/
    +    LIT64( 0x3F7F000000000000 ),	/* positive,   -128		*/
    +    LIT64( 0x3F80000000000000 ),	/* positive,   -127		*/
    +    LIT64( 0x3F81000000000000 ),	/* positive,   -126		*/
    +    LIT64( 0x3F8E000000000000 ),	/* positive,   -113		*/
    +    LIT64( 0x3FFB000000000000 ),	/* positive,     -4		*/
    +    LIT64( 0x3FFC000000000000 ),	/* positive,     -3		*/
    +    LIT64( 0x3FFD000000000000 ),	/* positive,     -2		*/
    +    LIT64( 0x3FFE000000000000 ),	/* positive,     -1		*/
    +    LIT64( 0x3FFF000000000000 ),	/* positive,      0		*/
    +    LIT64( 0x4000000000000000 ),	/* positive,      1		*/
    +    LIT64( 0x4001000000000000 ),	/* positive,      2		*/
    +    LIT64( 0x4002000000000000 ),	/* positive,      3		*/
    +    LIT64( 0x4003000000000000 ),	/* positive,      4		*/
    +    LIT64( 0x401C000000000000 ),	/* positive,     29		*/
    +    LIT64( 0x401D000000000000 ),	/* positive,     30		*/
    +    LIT64( 0x401E000000000000 ),	/* positive,     31		*/
    +    LIT64( 0x401F000000000000 ),	/* positive,     32		*/
    +    LIT64( 0x403C000000000000 ),	/* positive,     61		*/
    +    LIT64( 0x403D000000000000 ),	/* positive,     62		*/
    +    LIT64( 0x403E000000000000 ),	/* positive,     63		*/
    +    LIT64( 0x403F000000000000 ),	/* positive,     64		*/
    +    LIT64( 0x4070000000000000 ),	/* positive,    113		*/
    +    LIT64( 0x407E000000000000 ),	/* positive,    127		*/
    +    LIT64( 0x407F000000000000 ),	/* positive,    128		*/
    +    LIT64( 0x4080000000000000 ),	/* positive,    129		*/
    +    LIT64( 0x43FE000000000000 ),	/* positive,   1023		*/
    +    LIT64( 0x43FF000000000000 ),	/* positive,   1024		*/
    +    LIT64( 0x4400000000000000 ),	/* positive,   1025		*/
    +    LIT64( 0x7FFD000000000000 ),	/* positive,  16382		*/
    +    LIT64( 0x7FFE000000000000 ),	/* positive,  16383		*/
    +    LIT64( 0x7FFF000000000000 ),	/* positive, infinity or NaN	*/
    +    LIT64( 0x8000000000000000 ),	/* negative, subnormal		*/
    +    LIT64( 0x8001000000000000 ),	/* negative, -16382		*/
    +    LIT64( 0x8002000000000000 ),	/* negative, -16381		*/
    +    LIT64( 0xBBFE000000000000 ),	/* negative,  -1025		*/
    +    LIT64( 0xBBFF000000000000 ),	/* negative,  -1024		*/
    +    LIT64( 0xBC00000000000000 ),	/* negative,  -1023		*/
    +    LIT64( 0xBC01000000000000 ),	/* negative,  -1022		*/
    +    LIT64( 0xBF7E000000000000 ),	/* negative,   -129		*/
    +    LIT64( 0xBF7F000000000000 ),	/* negative,   -128		*/
    +    LIT64( 0xBF80000000000000 ),	/* negative,   -127		*/
    +    LIT64( 0xBF81000000000000 ),	/* negative,   -126		*/
    +    LIT64( 0xBF8E000000000000 ),	/* negative,   -113		*/
    +    LIT64( 0xBFFB000000000000 ),	/* negative,     -4		*/
    +    LIT64( 0xBFFC000000000000 ),	/* negative,     -3		*/
    +    LIT64( 0xBFFD000000000000 ),	/* negative,     -2		*/
    +    LIT64( 0xBFFE000000000000 ),	/* negative,     -1		*/
    +    LIT64( 0xBFFF000000000000 ),	/* negative,      0		*/
    +    LIT64( 0xC000000000000000 ),	/* negative,      1		*/
    +    LIT64( 0xC001000000000000 ),	/* negative,      2		*/
    +    LIT64( 0xC002000000000000 ),	/* negative,      3		*/
    +    LIT64( 0xC003000000000000 ),	/* negative,      4		*/
    +    LIT64( 0xC01C000000000000 ),	/* negative,     29		*/
    +    LIT64( 0xC01D000000000000 ),	/* negative,     30		*/
    +    LIT64( 0xC01E000000000000 ),	/* negative,     31		*/
    +    LIT64( 0xC01F000000000000 ),	/* negative,     32		*/
    +    LIT64( 0xC03C000000000000 ),	/* negative,     61		*/
    +    LIT64( 0xC03D000000000000 ),	/* negative,     62		*/
    +    LIT64( 0xC03E000000000000 ),	/* negative,     63		*/
    +    LIT64( 0xC03F000000000000 ),	/* negative,     64		*/
    +    LIT64( 0xC070000000000000 ),	/* negative,    113		*/
    +    LIT64( 0xC07E000000000000 ),	/* negative,    127		*/
    +    LIT64( 0xC07F000000000000 ),	/* negative,    128		*/
    +    LIT64( 0xC080000000000000 ),	/* negative,    129		*/
    +    LIT64( 0xC3FE000000000000 ),	/* negative,   1023		*/
    +    LIT64( 0xC3FF000000000000 ),	/* negative,   1024		*/
    +    LIT64( 0xC400000000000000 ),	/* negative,   1025		*/
    +    LIT64( 0xFFFD000000000000 ),	/* negative,  16382		*/
    +    LIT64( 0xFFFE000000000000 ),	/* negative,  16383		*/
    +    LIT64( 0xFFFF000000000000 )		/* negative, infinity or NaN	*/
    +};
    +
    +static const struct { bits64 high, low; } float128P1[ float128NumP1 ] = {
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000001 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFE ) }
    +};
    +
    +static const struct { bits64 high, low; } float128P2[ float128NumP2 ] = {
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000001 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000002 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000004 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000008 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000010 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000020 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000040 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000080 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000100 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000200 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000400 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000800 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000001000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000002000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000004000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000008000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000010000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000020000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000040000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000080000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000100000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000200000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000400000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000800000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000001000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000002000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000004000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000008000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000010000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000020000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000040000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000080000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000100000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000200000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000400000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000800000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000001000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000002000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000004000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000008000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000010000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000020000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000040000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000080000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000100000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000200000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000400000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000800000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0001000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0002000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0004000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0008000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0010000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0020000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0040000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0080000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0100000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0200000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0400000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0800000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x1000000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x2000000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x4000000000000000 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x8000000000000000 ) },
    +    { LIT64( 0x0000000000000001 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000002 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000004 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000008 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000010 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000020 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000040 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000080 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000100 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000200 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000400 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000000800 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000001000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000002000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000004000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000008000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000010000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000020000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000040000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000080000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000100000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000200000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000400000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000000800000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000001000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000002000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000004000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000008000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000010000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000020000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000040000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000080000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000100000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000200000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000400000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000000800000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000001000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000002000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000004000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000008000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000010000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000020000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000040000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000080000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000100000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000200000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000400000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000800000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000C00000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000E00000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000F00000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000F80000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FC0000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FE0000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FF0000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FF8000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFC000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFE000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFF000000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFF800000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFC00000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFE00000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFF00000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFF80000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFC0000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFE0000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFF0000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFF8000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFC000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFE000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFF000000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFF800000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFC00000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFE00000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFF00000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFF80000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFC0000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFE0000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFF0000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFF8000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFC000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFE000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFF000 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFF800 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFC00 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFE00 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFF00 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFF80 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFC0 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFE0 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFF0 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFF8 ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFC ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFE ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x0000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x8000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xC000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xE000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF000000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF800000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFC00000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFE00000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF00000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF80000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFC0000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFE0000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF0000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF8000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFC000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFE000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF000000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF800000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFC00000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFE00000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF00000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF80000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFC0000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFE0000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF0000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF8000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFC000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFE000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF000000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF800000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFC00000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFE00000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF00000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF80000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFC0000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFE0000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF0000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF8000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFC000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFE000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF000000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF800000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFC00000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFE00000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF00000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF80000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFC0000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFE0000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF0000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF8000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFC000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFE000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF000 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF800 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFC00 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFE00 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF00 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF80 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFC0 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFE0 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF0 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF8 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFC ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFE ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFD ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFB ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF7 ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFEF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFDF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFBF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF7F ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFEFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFDFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFBFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF7FF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFEFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFDFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFBFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF7FFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFEFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFDFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFBFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF7FFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFEFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFDFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFBFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF7FFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFEFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFDFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFBFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF7FFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFEFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFDFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFBFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF7FFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFEFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFDFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFBFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF7FFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFEFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFDFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFBFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF7FFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFEFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFDFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFBFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF7FFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFEFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFDFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFBFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF7FFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFEFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFDFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFBFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF7FFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFEFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFDFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFBFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF7FFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFEFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFDFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFBFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF7FFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xEFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xDFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xBFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x7FFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFD ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFFB ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFF7 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFEF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFDF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFFBF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFF7F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFEFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFDFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFFBFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFF7FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFEFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFDFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFFBFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFF7FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFEFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFDFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFFBFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFF7FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFEFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFDFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFFBFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFF7FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFEFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFDFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFFBFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFF7FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFEFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFDFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFFBFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFF7FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFEFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFDFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFFBFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFF7FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFEFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFDFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FFBFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FF7FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FEFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FDFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000FBFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000F7FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000EFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000DFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000BFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00007FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00003FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00001FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000007FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000003FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000001FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000007FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000003FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000001FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000007FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000003FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000001FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000000FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000007FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000003FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000001FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000000FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000007FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000003FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000001FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000000007FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000000003FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000000001FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000000000FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000000007FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000000003FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000000001FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000000000FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000007FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000003FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000001FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000000000007FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000000000003FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000000000001FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x00000000000000FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000000000007F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000000000003F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000000000001F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x000000000000000F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000007 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000003 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000001 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x7FFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x3FFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x1FFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0FFFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x07FFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x03FFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x01FFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00FFFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x007FFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x003FFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x001FFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000FFFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0007FFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0003FFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0001FFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000FFFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00007FFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00003FFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00001FFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000FFFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000007FFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000003FFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000001FFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000FFFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000007FFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000003FFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000001FFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000FFFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000007FFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000003FFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000001FFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000FFFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000007FFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000003FFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000001FFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000FFFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000007FFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000003FFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000001FFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000FFFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000007FFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000003FFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000001FFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000FFFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000007FFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000003FFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000001FFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000FFFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000007FFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000003FFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000001FFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000FFF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000007FF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000003FF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000001FF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000000FF ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000007F ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000003F ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000001F ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000000F ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000007 ) },
    +    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000003 ) }
    +};
    +
    +static const uint32 float128NumQInP1 = float128NumQIn * float128NumP1;
    +static const uint32 float128NumQOutP1 = float128NumQOut * float128NumP1;
    +
    +static float128 float128NextQInP1( sequenceT *sequencePtr )
    +{
    +    int16 expNum, sigNum;
    +    float128 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z.low = float128P1[ sigNum ].low;
    +    z.high = float128QIn[ expNum ] | float128P1[ sigNum ].high;
    +    ++sigNum;
    +    if ( float128NumP1 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float128NumQIn <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static float128 float128NextQOutP1( sequenceT *sequencePtr )
    +{
    +    int16 expNum, sigNum;
    +    float128 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z.low = float128P1[ sigNum ].low;
    +    z.high = float128QOut[ expNum ] | float128P1[ sigNum ].high;
    +    ++sigNum;
    +    if ( float128NumP1 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float128NumQOut <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static const uint32 float128NumQInP2 = float128NumQIn * float128NumP2;
    +static const uint32 float128NumQOutP2 = float128NumQOut * float128NumP2;
    +
    +static float128 float128NextQInP2( sequenceT *sequencePtr )
    +{
    +    int16 expNum, sigNum;
    +    float128 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z.low = float128P2[ sigNum ].low;
    +    z.high = float128QIn[ expNum ] | float128P2[ sigNum ].high;
    +    ++sigNum;
    +    if ( float128NumP2 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float128NumQIn <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static float128 float128NextQOutP2( sequenceT *sequencePtr )
    +{
    +    int16 expNum, sigNum;
    +    float128 z;
    +
    +    sigNum = sequencePtr->term1Num;
    +    expNum = sequencePtr->expNum;
    +    z.low = float128P2[ sigNum ].low;
    +    z.high = float128QOut[ expNum ] | float128P2[ sigNum ].high;
    +    ++sigNum;
    +    if ( float128NumP2 <= sigNum ) {
    +        sigNum = 0;
    +        ++expNum;
    +        if ( float128NumQOut <= expNum ) {
    +            expNum = 0;
    +            sequencePtr->done = TRUE;
    +        }
    +        sequencePtr->expNum = expNum;
    +    }
    +    sequencePtr->term1Num = sigNum;
    +    return z;
    +
    +}
    +
    +static float128 float128RandomQOutP3( void )
    +{
    +    int16 sigNum1, sigNum2;
    +    uint64 sig1Low, sig2Low;
    +    float128 z;
    +
    +    sigNum1 = randomUint8() % float128NumP2;
    +    sigNum2 = randomUint8() % float128NumP2;
    +    sig1Low = float128P2[ sigNum1 ].low;
    +    sig2Low = float128P2[ sigNum2 ].low;
    +    z.low = sig1Low + sig2Low;
    +    z.high =
    +          float128QOut[ randomUint8() % float128NumQOut ]
    +        | (   (   float128P2[ sigNum1 ].high
    +                + float128P2[ sigNum2 ].high
    +                + ( z.low < sig1Low )
    +              )
    +            & LIT64( 0x0000FFFFFFFFFFFF )
    +          );
    +    return z;
    +
    +}
    +
    +static float128 float128RandomQOutPInf( void )
    +{
    +    float128 z;
    +
    +    z.low = randomUint64();
    +    z.high =
    +          float128QOut[ randomUint8() % float128NumQOut ]
    +        | ( randomUint64() & LIT64( 0x0000FFFFFFFFFFFF ) );
    +    return z;
    +
    +}
    +
    +enum {
    +    float128NumQInfWeightMasks = 14
    +};
    +
    +static const uint64 float128QInfWeightMasks[ float128NumQInfWeightMasks ] = {
    +    LIT64( 0x7FFF000000000000 ),
    +    LIT64( 0x7FFF000000000000 ),
    +    LIT64( 0x3FFF000000000000 ),
    +    LIT64( 0x1FFF000000000000 ),
    +    LIT64( 0x07FF000000000000 ),
    +    LIT64( 0x07FF000000000000 ),
    +    LIT64( 0x03FF000000000000 ),
    +    LIT64( 0x01FF000000000000 ),
    +    LIT64( 0x00FF000000000000 ),
    +    LIT64( 0x007F000000000000 ),
    +    LIT64( 0x003F000000000000 ),
    +    LIT64( 0x001F000000000000 ),
    +    LIT64( 0x000F000000000000 ),
    +    LIT64( 0x0007000000000000 )
    +};
    +
    +static const uint64 float128QInfWeightOffsets[ float128NumQInfWeightMasks ] = {
    +    LIT64( 0x0000000000000000 ),
    +    LIT64( 0x0000000000000000 ),
    +    LIT64( 0x2000000000000000 ),
    +    LIT64( 0x3000000000000000 ),
    +    LIT64( 0x3800000000000000 ),
    +    LIT64( 0x3C00000000000000 ),
    +    LIT64( 0x3E00000000000000 ),
    +    LIT64( 0x3F00000000000000 ),
    +    LIT64( 0x3F80000000000000 ),
    +    LIT64( 0x3FC0000000000000 ),
    +    LIT64( 0x3FE0000000000000 ),
    +    LIT64( 0x3FF0000000000000 ),
    +    LIT64( 0x3FF8000000000000 ),
    +    LIT64( 0x3FFC000000000000 )
    +};
    +
    +static float128 float128RandomQInfP3( void )
    +{
    +    int16 sigNum1, sigNum2;
    +    uint64 sig1Low, sig2Low;
    +    int8 weightMaskNum;
    +    float128 z;
    +
    +    sigNum1 = randomUint8() % float128NumP2;
    +    sigNum2 = randomUint8() % float128NumP2;
    +    sig1Low = float128P2[ sigNum1 ].low;
    +    sig2Low = float128P2[ sigNum2 ].low;
    +    z.low = sig1Low + sig2Low;
    +    weightMaskNum = randomUint8() % float128NumQInfWeightMasks;
    +    z.high =
    +          ( ( (uint64) ( randomUint8() & 1 ) )<<63 )
    +        | (   (   ( ( (uint64) randomUint16() )<<48 )
    +                & float128QInfWeightMasks[ weightMaskNum ] )
    +            + float128QInfWeightOffsets[ weightMaskNum ]
    +          )
    +        | (   (   float128P2[ sigNum1 ].high
    +                + float128P2[ sigNum2 ].high
    +                + ( z.low < sig1Low )
    +              )
    +            & LIT64( 0x0000FFFFFFFFFFFF )
    +          );
    +    return z;
    +
    +}
    +
    +static float128 float128RandomQInfPInf( void )
    +{
    +    int8 weightMaskNum;
    +    float128 z;
    +
    +    weightMaskNum = randomUint8() % float128NumQInfWeightMasks;
    +    z.low = randomUint64();
    +    z.high =
    +          ( ( (uint64) ( randomUint8() & 1 ) )<<63 )
    +        | (   (   ( ( (uint64) randomUint16() )<<48 )
    +                & float128QInfWeightMasks[ weightMaskNum ] )
    +            + float128QInfWeightOffsets[ weightMaskNum ]
    +          )
    +        | ( randomUint64() & LIT64( 0x0000FFFFFFFFFFFF ) );
    +    return z;
    +
    +}
    +
    +static float128 float128Random( void )
    +{
    +
    +    switch ( randomUint8() & 7 ) {
    +     case 0:
    +     case 1:
    +     case 2:
    +        return float128RandomQOutP3();
    +     case 3:
    +        return float128RandomQOutPInf();
    +     case 4:
    +     case 5:
    +     case 6:
    +        return float128RandomQInfP3();
    +     default:
    +        return float128RandomQInfPInf();
    +    }
    +
    +}
    +
    +#endif
    +
    +static int8 level = 0;
    +
    +void testCases_setLevel( int8 levelIn )
    +{
    +
    +    if ( ( levelIn < 1 ) || ( 2 < levelIn ) ) {
    +        fail( "Invalid testing level: %d", levelIn );
    +    }
    +    level = levelIn;
    +
    +}
    +
    +static int8 sequenceType;
    +static sequenceT sequenceA, sequenceB;
    +static int8 subcase;
    +
    +uint32 testCases_total;
    +flag testCases_done;
    +
    +static float32 current_a_float32;
    +static float32 current_b_float32;
    +static float64 current_a_float64;
    +static float64 current_b_float64;
    +#ifdef FLOATX80
    +static floatx80 current_a_floatx80;
    +static floatx80 current_b_floatx80;
    +#endif
    +#ifdef FLOAT128
    +static float128 current_a_float128;
    +static float128 current_b_float128;
    +#endif
    +
    +void testCases_initSequence( int8 sequenceTypeIn )
    +{
    +
    +    sequenceType = sequenceTypeIn;
    +    sequenceA.term2Num = 0;
    +    sequenceA.term1Num = 0;
    +    sequenceA.expNum = 0;
    +    sequenceA.done = FALSE;
    +    sequenceB.term2Num = 0;
    +    sequenceB.term1Num = 0;
    +    sequenceB.expNum = 0;
    +    sequenceB.done = FALSE;
    +    subcase = 0;
    +    switch ( level ) {
    +     case 1:
    +        switch ( sequenceTypeIn ) {
    +         case testCases_sequence_a_int32:
    +            testCases_total = 3 * int32NumP1;
    +            break;
    +#ifdef BITS64
    +         case testCases_sequence_a_int64:
    +            testCases_total = 3 * int64NumP1;
    +            break;
    +#endif
    +         case testCases_sequence_a_float32:
    +            testCases_total = 3 * float32NumQOutP1;
    +            break;
    +         case testCases_sequence_ab_float32:
    +            testCases_total = 6 * float32NumQInP1 * float32NumQInP1;
    +            current_a_float32 = float32NextQInP1( &sequenceA );
    +            break;
    +         case testCases_sequence_a_float64:
    +            testCases_total = 3 * float64NumQOutP1;
    +            break;
    +         case testCases_sequence_ab_float64:
    +            testCases_total = 6 * float64NumQInP1 * float64NumQInP1;
    +            current_a_float64 = float64NextQInP1( &sequenceA );
    +            break;
    +#ifdef FLOATX80
    +         case testCases_sequence_a_floatx80:
    +            testCases_total = 3 * floatx80NumQOutP1;
    +            break;
    +         case testCases_sequence_ab_floatx80:
    +            testCases_total = 6 * floatx80NumQInP1 * floatx80NumQInP1;
    +            current_a_floatx80 = floatx80NextQInP1( &sequenceA );
    +            break;
    +#endif
    +#ifdef FLOAT128
    +         case testCases_sequence_a_float128:
    +            testCases_total = 3 * float128NumQOutP1;
    +            break;
    +         case testCases_sequence_ab_float128:
    +            testCases_total = 6 * float128NumQInP1 * float128NumQInP1;
    +            current_a_float128 = float128NextQInP1( &sequenceA );
    +            break;
    +#endif
    +        }
    +        break;
    +     case 2:
    +        switch ( sequenceTypeIn ) {
    +         case testCases_sequence_a_int32:
    +            testCases_total = 2 * int32NumP2;
    +            break;
    +#ifdef BITS64
    +         case testCases_sequence_a_int64:
    +            testCases_total = 2 * int64NumP2;
    +            break;
    +#endif
    +         case testCases_sequence_a_float32:
    +            testCases_total = 2 * float32NumQOutP2;
    +            break;
    +         case testCases_sequence_ab_float32:
    +            testCases_total = 2 * float32NumQInP2 * float32NumQInP2;
    +            current_a_float32 = float32NextQInP2( &sequenceA );
    +            break;
    +         case testCases_sequence_a_float64:
    +            testCases_total = 2 * float64NumQOutP2;
    +            break;
    +         case testCases_sequence_ab_float64:
    +            testCases_total = 2 * float64NumQInP2 * float64NumQInP2;
    +            current_a_float64 = float64NextQInP2( &sequenceA );
    +            break;
    +#ifdef FLOATX80
    +         case testCases_sequence_a_floatx80:
    +            testCases_total = 2 * floatx80NumQOutP2;
    +            break;
    +         case testCases_sequence_ab_floatx80:
    +            testCases_total = 2 * floatx80NumQInP2 * floatx80NumQInP2;
    +            current_a_floatx80 = floatx80NextQInP2( &sequenceA );
    +            break;
    +#endif
    +#ifdef FLOAT128
    +         case testCases_sequence_a_float128:
    +            testCases_total = 2 * float128NumQOutP2;
    +            break;
    +         case testCases_sequence_ab_float128:
    +            testCases_total = 2 * float128NumQInP2 * float128NumQInP2;
    +            current_a_float128 = float128NextQInP2( &sequenceA );
    +            break;
    +#endif
    +        }
    +        break;
    +    }
    +    testCases_done = FALSE;
    +
    +}
    +
    +int32 testCases_a_int32;
    +#ifdef BITS64
    +int64 testCases_a_int64;
    +#endif
    +float32 testCases_a_float32;
    +float32 testCases_b_float32;
    +float64 testCases_a_float64;
    +float64 testCases_b_float64;
    +#ifdef FLOATX80
    +floatx80 testCases_a_floatx80;
    +floatx80 testCases_b_floatx80;
    +#endif
    +#ifdef FLOAT128
    +float128 testCases_a_float128;
    +float128 testCases_b_float128;
    +#endif
    +
    +void testCases_next( void )
    +{
    +
    +    switch ( level ) {
    +     case 1:
    +        switch ( sequenceType ) {
    +         case testCases_sequence_a_int32:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_int32 = int32RandomP3();
    +                break;
    +             case 1:
    +                testCases_a_int32 = int32RandomPInf();
    +                break;
    +             case 2:
    +                testCases_a_int32 = int32NextP1( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#ifdef BITS64
    +         case testCases_sequence_a_int64:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_int64 = int64RandomP3();
    +                break;
    +             case 1:
    +                testCases_a_int64 = int64RandomPInf();
    +                break;
    +             case 2:
    +                testCases_a_int64 = int64NextP1( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#endif
    +         case testCases_sequence_a_float32:
    +            switch ( subcase ) {
    +             case 0:
    +             case 1:
    +                testCases_a_float32 = float32Random();
    +                break;
    +             case 2:
    +                testCases_a_float32 = float32NextQOutP1( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_ab_float32:
    +            switch ( subcase ) {
    +             case 0:
    +                if ( sequenceB.done ) {
    +                    sequenceB.done = FALSE;
    +                    current_a_float32 = float32NextQInP1( &sequenceA );
    +                }
    +                current_b_float32 = float32NextQInP1( &sequenceB );
    +             case 2:
    +             case 4:
    +                testCases_a_float32 = float32Random();
    +                testCases_b_float32 = float32Random();
    +                break;
    +             case 1:
    +                testCases_a_float32 = current_a_float32;
    +                testCases_b_float32 = float32Random();
    +                break;
    +             case 3:
    +                testCases_a_float32 = float32Random();
    +                testCases_b_float32 = current_b_float32;
    +                break;
    +             case 5:
    +                testCases_a_float32 = current_a_float32;
    +                testCases_b_float32 = current_b_float32;
    +                testCases_done = sequenceA.done & sequenceB.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_a_float64:
    +            switch ( subcase ) {
    +             case 0:
    +             case 1:
    +                testCases_a_float64 = float64Random();
    +                break;
    +             case 2:
    +                testCases_a_float64 = float64NextQOutP1( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_ab_float64:
    +            switch ( subcase ) {
    +             case 0:
    +                if ( sequenceB.done ) {
    +                    sequenceB.done = FALSE;
    +                    current_a_float64 = float64NextQInP1( &sequenceA );
    +                }
    +                current_b_float64 = float64NextQInP1( &sequenceB );
    +             case 2:
    +             case 4:
    +                testCases_a_float64 = float64Random();
    +                testCases_b_float64 = float64Random();
    +                break;
    +             case 1:
    +                testCases_a_float64 = current_a_float64;
    +                testCases_b_float64 = float64Random();
    +                break;
    +             case 3:
    +                testCases_a_float64 = float64Random();
    +                testCases_b_float64 = current_b_float64;
    +                break;
    +             case 5:
    +                testCases_a_float64 = current_a_float64;
    +                testCases_b_float64 = current_b_float64;
    +                testCases_done = sequenceA.done & sequenceB.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#ifdef FLOATX80
    +         case testCases_sequence_a_floatx80:
    +            switch ( subcase ) {
    +             case 0:
    +             case 1:
    +                testCases_a_floatx80 = floatx80Random();
    +                break;
    +             case 2:
    +                testCases_a_floatx80 = floatx80NextQOutP1( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_ab_floatx80:
    +            switch ( subcase ) {
    +             case 0:
    +                if ( sequenceB.done ) {
    +                    sequenceB.done = FALSE;
    +                    current_a_floatx80 = floatx80NextQInP1( &sequenceA );
    +                }
    +                current_b_floatx80 = floatx80NextQInP1( &sequenceB );
    +             case 2:
    +             case 4:
    +                testCases_a_floatx80 = floatx80Random();
    +                testCases_b_floatx80 = floatx80Random();
    +                break;
    +             case 1:
    +                testCases_a_floatx80 = current_a_floatx80;
    +                testCases_b_floatx80 = floatx80Random();
    +                break;
    +             case 3:
    +                testCases_a_floatx80 = floatx80Random();
    +                testCases_b_floatx80 = current_b_floatx80;
    +                break;
    +             case 5:
    +                testCases_a_floatx80 = current_a_floatx80;
    +                testCases_b_floatx80 = current_b_floatx80;
    +                testCases_done = sequenceA.done & sequenceB.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#endif
    +#ifdef FLOAT128
    +         case testCases_sequence_a_float128:
    +            switch ( subcase ) {
    +             case 0:
    +             case 1:
    +                testCases_a_float128 = float128Random();
    +                break;
    +             case 2:
    +                testCases_a_float128 = float128NextQOutP1( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_ab_float128:
    +            switch ( subcase ) {
    +             case 0:
    +                if ( sequenceB.done ) {
    +                    sequenceB.done = FALSE;
    +                    current_a_float128 = float128NextQInP1( &sequenceA );
    +                }
    +                current_b_float128 = float128NextQInP1( &sequenceB );
    +             case 2:
    +             case 4:
    +                testCases_a_float128 = float128Random();
    +                testCases_b_float128 = float128Random();
    +                break;
    +             case 1:
    +                testCases_a_float128 = current_a_float128;
    +                testCases_b_float128 = float128Random();
    +                break;
    +             case 3:
    +                testCases_a_float128 = float128Random();
    +                testCases_b_float128 = current_b_float128;
    +                break;
    +             case 5:
    +                testCases_a_float128 = current_a_float128;
    +                testCases_b_float128 = current_b_float128;
    +                testCases_done = sequenceA.done & sequenceB.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#endif
    +        }
    +        break;
    +     case 2:
    +        switch ( sequenceType ) {
    +         case testCases_sequence_a_int32:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_int32 = int32RandomP3();
    +                break;
    +             case 2:
    +                testCases_a_int32 = int32RandomPInf();
    +                break;
    +             case 3:
    +                subcase = -1;
    +             case 1:
    +                testCases_a_int32 = int32NextP2( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#ifdef BITS64
    +         case testCases_sequence_a_int64:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_int64 = int64RandomP3();
    +                break;
    +             case 2:
    +                testCases_a_int64 = int64RandomPInf();
    +                break;
    +             case 3:
    +                subcase = -1;
    +             case 1:
    +                testCases_a_int64 = int64NextP2( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#endif
    +         case testCases_sequence_a_float32:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_float32 = float32Random();
    +                break;
    +             case 1:
    +                testCases_a_float32 = float32NextQOutP2( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_ab_float32:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_float32 = float32Random();
    +                testCases_b_float32 = float32Random();
    +                break;
    +             case 1:
    +                if ( sequenceB.done ) {
    +                    sequenceB.done = FALSE;
    +                    current_a_float32 = float32NextQInP2( &sequenceA );
    +                }
    +                testCases_a_float32 = current_a_float32;
    +                testCases_b_float32 = float32NextQInP2( &sequenceB );
    +                testCases_done = sequenceA.done & sequenceB.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_a_float64:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_float64 = float64Random();
    +                break;
    +             case 1:
    +                testCases_a_float64 = float64NextQOutP2( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_ab_float64:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_float64 = float64Random();
    +                testCases_b_float64 = float64Random();
    +                break;
    +             case 1:
    +                if ( sequenceB.done ) {
    +                    sequenceB.done = FALSE;
    +                    current_a_float64 = float64NextQInP2( &sequenceA );
    +                }
    +                testCases_a_float64 = current_a_float64;
    +                testCases_b_float64 = float64NextQInP2( &sequenceB );
    +                testCases_done = sequenceA.done & sequenceB.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#ifdef FLOATX80
    +         case testCases_sequence_a_floatx80:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_floatx80 = floatx80Random();
    +                break;
    +             case 1:
    +                testCases_a_floatx80 = floatx80NextQOutP2( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_ab_floatx80:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_floatx80 = floatx80Random();
    +                testCases_b_floatx80 = floatx80Random();
    +                break;
    +             case 1:
    +                if ( sequenceB.done ) {
    +                    sequenceB.done = FALSE;
    +                    current_a_floatx80 = floatx80NextQInP2( &sequenceA );
    +                }
    +                testCases_a_floatx80 = current_a_floatx80;
    +                testCases_b_floatx80 = floatx80NextQInP2( &sequenceB );
    +                testCases_done = sequenceA.done & sequenceB.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#endif
    +#ifdef FLOAT128
    +         case testCases_sequence_a_float128:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_float128 = float128Random();
    +                break;
    +             case 1:
    +                testCases_a_float128 = float128NextQOutP2( &sequenceA );
    +                testCases_done = sequenceA.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +         case testCases_sequence_ab_float128:
    +            switch ( subcase ) {
    +             case 0:
    +                testCases_a_float128 = float128Random();
    +                testCases_b_float128 = float128Random();
    +                break;
    +             case 1:
    +                if ( sequenceB.done ) {
    +                    sequenceB.done = FALSE;
    +                    current_a_float128 = float128NextQInP2( &sequenceA );
    +                }
    +                testCases_a_float128 = current_a_float128;
    +                testCases_b_float128 = float128NextQInP2( &sequenceB );
    +                testCases_done = sequenceA.done & sequenceB.done;
    +                subcase = -1;
    +                break;
    +            }
    +            ++subcase;
    +            break;
    +#endif
    +        }
    +        break;
    +    }
    +
    +}
    +
    diff --git a/tools/test/testfloat/testCases.h b/tools/test/testfloat/testCases.h
    new file mode 100644
    index 00000000000..ed6ea2be46b
    --- /dev/null
    +++ b/tools/test/testfloat/testCases.h
    @@ -0,0 +1,69 @@
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +void testCases_setLevel( int8 );
    +
    +void testCases_initSequence( int8 );
    +enum {
    +    testCases_sequence_a_int32,
    +#ifdef BITS64
    +    testCases_sequence_a_int64,
    +#endif
    +    testCases_sequence_a_float32,
    +    testCases_sequence_ab_float32,
    +    testCases_sequence_a_float64,
    +    testCases_sequence_ab_float64,
    +#ifdef FLOATX80
    +    testCases_sequence_a_floatx80,
    +    testCases_sequence_ab_floatx80,
    +#endif
    +#ifdef FLOAT128
    +    testCases_sequence_a_float128,
    +    testCases_sequence_ab_float128,
    +#endif
    +};
    +
    +extern uint32 testCases_total;
    +extern flag testCases_done;
    +
    +void testCases_next( void );
    +
    +extern int32 testCases_a_int32;
    +#ifdef BITS64
    +extern int64 testCases_a_int64;
    +#endif
    +extern float32 testCases_a_float32;
    +extern float32 testCases_b_float32;
    +extern float64 testCases_a_float64;
    +extern float64 testCases_b_float64;
    +#ifdef FLOATX80
    +extern floatx80 testCases_a_floatx80;
    +extern floatx80 testCases_b_floatx80;
    +#endif
    +#ifdef FLOAT128
    +extern float128 testCases_a_float128;
    +extern float128 testCases_b_float128;
    +#endif
    +
    diff --git a/tools/test/testfloat/testFunction.c b/tools/test/testfloat/testFunction.c
    new file mode 100644
    index 00000000000..687563b0d75
    --- /dev/null
    +++ b/tools/test/testfloat/testFunction.c
    @@ -0,0 +1,1149 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include "milieu.h"
    +#include "softfloat.h"
    +#include "testCases.h"
    +#include "testLoops.h"
    +#include "systmodes.h"
    +#include "systflags.h"
    +#include "systfloat.h"
    +#include "testFunction.h"
    +
    +const functionT functions[ NUM_FUNCTIONS ] = {
    +    { 0, 0, 0, 0 },
    +    { "int32_to_float32",                1, FALSE, TRUE  },
    +    { "int32_to_float64",                1, FALSE, FALSE },
    +    { "int32_to_floatx80",               1, FALSE, FALSE },
    +    { "int32_to_float128",               1, FALSE, FALSE },
    +    { "int64_to_float32",                1, FALSE, TRUE  },
    +    { "int64_to_float64",                1, FALSE, TRUE  },
    +    { "int64_to_floatx80",               1, FALSE, FALSE },
    +    { "int64_to_float128",               1, FALSE, FALSE },
    +    { "float32_to_int32",                1, FALSE, TRUE  },
    +    { "float32_to_int32_round_to_zero",  1, FALSE, FALSE },
    +    { "float32_to_int64",                1, FALSE, TRUE  },
    +    { "float32_to_int64_round_to_zero",  1, FALSE, FALSE },
    +    { "float32_to_float64",              1, FALSE, FALSE },
    +    { "float32_to_floatx80",             1, FALSE, FALSE },
    +    { "float32_to_float128",             1, FALSE, FALSE },
    +    { "float32_round_to_int",            1, FALSE, TRUE  },
    +    { "float32_add",                     2, FALSE, TRUE  },
    +    { "float32_sub",                     2, FALSE, TRUE  },
    +    { "float32_mul",                     2, FALSE, TRUE  },
    +    { "float32_div",                     2, FALSE, TRUE  },
    +    { "float32_rem",                     2, FALSE, FALSE },
    +    { "float32_sqrt",                    1, FALSE, TRUE  },
    +    { "float32_eq",                      2, FALSE, FALSE },
    +    { "float32_le",                      2, FALSE, FALSE },
    +    { "float32_lt",                      2, FALSE, FALSE },
    +    { "float32_eq_signaling",            2, FALSE, FALSE },
    +    { "float32_le_quiet",                2, FALSE, FALSE },
    +    { "float32_lt_quiet",                2, FALSE, FALSE },
    +    { "float64_to_int32",                1, FALSE, TRUE  },
    +    { "float64_to_int32_round_to_zero",  1, FALSE, FALSE },
    +    { "float64_to_int64",                1, FALSE, TRUE  },
    +    { "float64_to_int64_round_to_zero",  1, FALSE, FALSE },
    +    { "float64_to_float32",              1, FALSE, TRUE  },
    +    { "float64_to_floatx80",             1, FALSE, FALSE },
    +    { "float64_to_float128",             1, FALSE, FALSE },
    +    { "float64_round_to_int",            1, FALSE, TRUE  },
    +    { "float64_add",                     2, FALSE, TRUE  },
    +    { "float64_sub",                     2, FALSE, TRUE  },
    +    { "float64_mul",                     2, FALSE, TRUE  },
    +    { "float64_div",                     2, FALSE, TRUE  },
    +    { "float64_rem",                     2, FALSE, FALSE },
    +    { "float64_sqrt",                    1, FALSE, TRUE  },
    +    { "float64_eq",                      2, FALSE, FALSE },
    +    { "float64_le",                      2, FALSE, FALSE },
    +    { "float64_lt",                      2, FALSE, FALSE },
    +    { "float64_eq_signaling",            2, FALSE, FALSE },
    +    { "float64_le_quiet",                2, FALSE, FALSE },
    +    { "float64_lt_quiet",                2, FALSE, FALSE },
    +    { "floatx80_to_int32",               1, FALSE, TRUE  },
    +    { "floatx80_to_int32_round_to_zero", 1, FALSE, FALSE },
    +    { "floatx80_to_int64",               1, FALSE, TRUE  },
    +    { "floatx80_to_int64_round_to_zero", 1, FALSE, FALSE },
    +    { "floatx80_to_float32",             1, FALSE, TRUE  },
    +    { "floatx80_to_float64",             1, FALSE, TRUE  },
    +    { "floatx80_to_float128",            1, FALSE, FALSE },
    +    { "floatx80_round_to_int",           1, FALSE, TRUE  },
    +    { "floatx80_add",                    2, TRUE,  TRUE  },
    +    { "floatx80_sub",                    2, TRUE,  TRUE  },
    +    { "floatx80_mul",                    2, TRUE,  TRUE  },
    +    { "floatx80_div",                    2, TRUE,  TRUE  },
    +    { "floatx80_rem",                    2, FALSE, FALSE },
    +    { "floatx80_sqrt",                   1, TRUE,  TRUE  },
    +    { "floatx80_eq",                     2, FALSE, FALSE },
    +    { "floatx80_le",                     2, FALSE, FALSE },
    +    { "floatx80_lt",                     2, FALSE, FALSE },
    +    { "floatx80_eq_signaling",           2, FALSE, FALSE },
    +    { "floatx80_le_quiet",               2, FALSE, FALSE },
    +    { "floatx80_lt_quiet",               2, FALSE, FALSE },
    +    { "float128_to_int32",               1, FALSE, TRUE  },
    +    { "float128_to_int32_round_to_zero", 1, FALSE, FALSE },
    +    { "float128_to_int64",               1, FALSE, TRUE  },
    +    { "float128_to_int64_round_to_zero", 1, FALSE, FALSE },
    +    { "float128_to_float32",             1, FALSE, TRUE  },
    +    { "float128_to_float64",             1, FALSE, TRUE  },
    +    { "float128_to_floatx80",            1, FALSE, TRUE  },
    +    { "float128_round_to_int",           1, FALSE, TRUE  },
    +    { "float128_add",                    2, FALSE, TRUE  },
    +    { "float128_sub",                    2, FALSE, TRUE  },
    +    { "float128_mul",                    2, FALSE, TRUE  },
    +    { "float128_div",                    2, FALSE, TRUE  },
    +    { "float128_rem",                    2, FALSE, FALSE },
    +    { "float128_sqrt",                   1, FALSE, TRUE  },
    +    { "float128_eq",                     2, FALSE, FALSE },
    +    { "float128_le",                     2, FALSE, FALSE },
    +    { "float128_lt",                     2, FALSE, FALSE },
    +    { "float128_eq_signaling",           2, FALSE, FALSE },
    +    { "float128_le_quiet",               2, FALSE, FALSE },
    +    { "float128_lt_quiet",               2, FALSE, FALSE },
    +};
    +
    +const flag functionExists[ NUM_FUNCTIONS ] = {
    +    0,
    +#ifdef SYST_INT32_TO_FLOAT32
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_INT32_TO_FLOAT64
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_INT32_TO_FLOATX80
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_INT32_TO_FLOAT128
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_INT64_TO_FLOAT32
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_INT64_TO_FLOAT64
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_INT64_TO_FLOATX80
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_INT64_TO_FLOAT128
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_TO_INT32
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_TO_INT64
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_TO_FLOAT64
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_TO_FLOATX80
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_TO_FLOAT128
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_ROUND_TO_INT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_ADD
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_SUB
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_MUL
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_DIV
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_REM
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_SQRT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_EQ
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_LE
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_LT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_EQ_SIGNALING
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_LE_QUIET
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT32_LT_QUIET
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_TO_INT32
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_TO_INT64
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_TO_FLOAT32
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_TO_FLOATX80
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_TO_FLOAT128
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_ROUND_TO_INT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_ADD
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_SUB
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_MUL
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_DIV
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_REM
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_SQRT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_EQ
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_LE
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_LT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_EQ_SIGNALING
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_LE_QUIET
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT64_LT_QUIET
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_TO_INT32
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_TO_INT32_ROUND_TO_ZERO
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_TO_INT64
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_TO_INT64_ROUND_TO_ZERO
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_TO_FLOAT32
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_TO_FLOAT64
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_TO_FLOAT128
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_ROUND_TO_INT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_ADD
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_SUB
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_MUL
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_DIV
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_REM
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_SQRT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_EQ
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_LE
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_LT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_EQ_SIGNALING
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_LE_QUIET
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOATX80_LT_QUIET
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_TO_INT32
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_TO_INT64
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_TO_FLOAT32
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_TO_FLOAT64
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_TO_FLOATX80
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_ROUND_TO_INT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_ADD
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_SUB
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_MUL
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_DIV
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_REM
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_SQRT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_EQ
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_LE
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_LT
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_EQ_SIGNALING
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_LE_QUIET
    +    1,
    +#else
    +    0,
    +#endif
    +#ifdef SYST_FLOAT128_LT_QUIET
    +    1,
    +#else
    +    0,
    +#endif
    +};
    +
    +static void
    + testFunctionVariety(
    +     uint8 functionCode, int8 roundingPrecision, int8 roundingMode )
    +{
    +    uint8 roundingCode;
    +
    +    functionName = functions[ functionCode ].name;
    +#ifdef FLOATX80
    +    if ( roundingPrecision == 32 ) {
    +        roundingPrecisionName = "32";
    +    }
    +    else if ( roundingPrecision == 64 ) {
    +        roundingPrecisionName = "64";
    +    }
    +    else if ( roundingPrecision == 80 ) {
    +        roundingPrecisionName = "80";
    +    }
    +    else {
    +        roundingPrecision = 80;
    +        roundingPrecisionName = 0;
    +    }
    +    floatx80_rounding_precision = roundingPrecision;
    +    syst_float_set_rounding_precision( roundingPrecision );
    +#endif
    +    switch ( roundingMode ) {
    +     case 0:
    +        roundingModeName = 0;
    +        roundingCode = float_round_nearest_even;
    +        break;
    +     case ROUND_NEAREST_EVEN:
    +        roundingModeName = "nearest_even";
    +        roundingCode = float_round_nearest_even;
    +        break;
    +     case ROUND_TO_ZERO:
    +        roundingModeName = "to_zero";
    +        roundingCode = float_round_to_zero;
    +        break;
    +     case ROUND_DOWN:
    +        roundingModeName = "down";
    +        roundingCode = float_round_down;
    +        break;
    +     case ROUND_UP:
    +        roundingModeName = "up";
    +        roundingCode = float_round_up;
    +        break;
    +    }
    +    float_rounding_mode = roundingCode;
    +    syst_float_set_rounding_mode( roundingCode );
    +    fputs( "Testing ", stderr );
    +    writeFunctionName( stderr );
    +    fputs( ".\n", stderr );
    +    switch ( functionCode ) {
    +#ifdef SYST_INT32_TO_FLOAT32
    +     case INT32_TO_FLOAT32:
    +        test_a_int32_z_float32( int32_to_float32, syst_int32_to_float32 );
    +        break;
    +#endif
    +#ifdef SYST_INT32_TO_FLOAT64
    +     case INT32_TO_FLOAT64:
    +        test_a_int32_z_float64( int32_to_float64, syst_int32_to_float64 );
    +        break;
    +#endif
    +#ifdef SYST_INT32_TO_FLOATX80
    +     case INT32_TO_FLOATX80:
    +        test_a_int32_z_floatx80( int32_to_floatx80, syst_int32_to_floatx80 );
    +        break;
    +#endif
    +#ifdef SYST_INT32_TO_FLOAT128
    +     case INT32_TO_FLOAT128:
    +        test_a_int32_z_float128( int32_to_float128, syst_int32_to_float128 );
    +        break;
    +#endif
    +#ifdef SYST_INT64_TO_FLOAT32
    +     case INT64_TO_FLOAT32:
    +        test_a_int64_z_float32( int64_to_float32, syst_int64_to_float32 );
    +        break;
    +#endif
    +#ifdef SYST_INT64_TO_FLOAT64
    +     case INT64_TO_FLOAT64:
    +        test_a_int64_z_float64( int64_to_float64, syst_int64_to_float64 );
    +        break;
    +#endif
    +#ifdef SYST_INT64_TO_FLOATX80
    +     case INT64_TO_FLOATX80:
    +        test_a_int64_z_floatx80( int64_to_floatx80, syst_int64_to_floatx80 );
    +        break;
    +#endif
    +#ifdef SYST_INT64_TO_FLOAT128
    +     case INT64_TO_FLOAT128:
    +        test_a_int64_z_float128( int64_to_float128, syst_int64_to_float128 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_TO_INT32
    +     case FLOAT32_TO_INT32:
    +        test_a_float32_z_int32( float32_to_int32, syst_float32_to_int32 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
    +     case FLOAT32_TO_INT32_ROUND_TO_ZERO:
    +        test_a_float32_z_int32(
    +            float32_to_int32_round_to_zero,
    +            syst_float32_to_int32_round_to_zero
    +        );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_TO_INT64
    +     case FLOAT32_TO_INT64:
    +        test_a_float32_z_int64( float32_to_int64, syst_float32_to_int64 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
    +     case FLOAT32_TO_INT64_ROUND_TO_ZERO:
    +        test_a_float32_z_int64(
    +            float32_to_int64_round_to_zero,
    +            syst_float32_to_int64_round_to_zero
    +        );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_TO_FLOAT64
    +     case FLOAT32_TO_FLOAT64:
    +        test_a_float32_z_float64(
    +            float32_to_float64, syst_float32_to_float64 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_TO_FLOATX80
    +     case FLOAT32_TO_FLOATX80:
    +        test_a_float32_z_floatx80(
    +            float32_to_floatx80, syst_float32_to_floatx80 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_TO_FLOAT128
    +     case FLOAT32_TO_FLOAT128:
    +        test_a_float32_z_float128(
    +            float32_to_float128, syst_float32_to_float128 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_ROUND_TO_INT
    +     case FLOAT32_ROUND_TO_INT:
    +        test_az_float32( float32_round_to_int, syst_float32_round_to_int );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_ADD
    +     case FLOAT32_ADD:
    +        test_abz_float32( float32_add, syst_float32_add );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_SUB
    +     case FLOAT32_SUB:
    +        test_abz_float32( float32_sub, syst_float32_sub );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_MUL
    +     case FLOAT32_MUL:
    +        test_abz_float32( float32_mul, syst_float32_mul );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_DIV
    +     case FLOAT32_DIV:
    +        test_abz_float32( float32_div, syst_float32_div );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_REM
    +     case FLOAT32_REM:
    +        test_abz_float32( float32_rem, syst_float32_rem );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_SQRT
    +     case FLOAT32_SQRT:
    +        test_az_float32( float32_sqrt, syst_float32_sqrt );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_EQ
    +     case FLOAT32_EQ:
    +        test_ab_float32_z_flag( float32_eq, syst_float32_eq );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_LE
    +     case FLOAT32_LE:
    +        test_ab_float32_z_flag( float32_le, syst_float32_le );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_LT
    +     case FLOAT32_LT:
    +        test_ab_float32_z_flag( float32_lt, syst_float32_lt );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_EQ_SIGNALING
    +     case FLOAT32_EQ_SIGNALING:
    +        test_ab_float32_z_flag(
    +            float32_eq_signaling, syst_float32_eq_signaling );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_LE_QUIET
    +     case FLOAT32_LE_QUIET:
    +        test_ab_float32_z_flag( float32_le_quiet, syst_float32_le_quiet );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT32_LT_QUIET
    +     case FLOAT32_LT_QUIET:
    +        test_ab_float32_z_flag( float32_lt_quiet, syst_float32_lt_quiet );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_TO_INT32
    +     case FLOAT64_TO_INT32:
    +        test_a_float64_z_int32( float64_to_int32, syst_float64_to_int32 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
    +     case FLOAT64_TO_INT32_ROUND_TO_ZERO:
    +        test_a_float64_z_int32(
    +            float64_to_int32_round_to_zero,
    +            syst_float64_to_int32_round_to_zero
    +        );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_TO_INT64
    +     case FLOAT64_TO_INT64:
    +        test_a_float64_z_int64( float64_to_int64, syst_float64_to_int64 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
    +     case FLOAT64_TO_INT64_ROUND_TO_ZERO:
    +        test_a_float64_z_int64(
    +            float64_to_int64_round_to_zero,
    +            syst_float64_to_int64_round_to_zero
    +        );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_TO_FLOAT32
    +     case FLOAT64_TO_FLOAT32:
    +        test_a_float64_z_float32(
    +            float64_to_float32, syst_float64_to_float32 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_TO_FLOATX80
    +     case FLOAT64_TO_FLOATX80:
    +        test_a_float64_z_floatx80(
    +            float64_to_floatx80, syst_float64_to_floatx80 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_TO_FLOAT128
    +     case FLOAT64_TO_FLOAT128:
    +        test_a_float64_z_float128(
    +            float64_to_float128, syst_float64_to_float128 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_ROUND_TO_INT
    +     case FLOAT64_ROUND_TO_INT:
    +        test_az_float64( float64_round_to_int, syst_float64_round_to_int );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_ADD
    +     case FLOAT64_ADD:
    +        test_abz_float64( float64_add, syst_float64_add );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_SUB
    +     case FLOAT64_SUB:
    +        test_abz_float64( float64_sub, syst_float64_sub );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_MUL
    +     case FLOAT64_MUL:
    +        test_abz_float64( float64_mul, syst_float64_mul );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_DIV
    +     case FLOAT64_DIV:
    +        test_abz_float64( float64_div, syst_float64_div );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_REM
    +     case FLOAT64_REM:
    +        test_abz_float64( float64_rem, syst_float64_rem );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_SQRT
    +     case FLOAT64_SQRT:
    +        test_az_float64( float64_sqrt, syst_float64_sqrt );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_EQ
    +     case FLOAT64_EQ:
    +        test_ab_float64_z_flag( float64_eq, syst_float64_eq );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_LE
    +     case FLOAT64_LE:
    +        test_ab_float64_z_flag( float64_le, syst_float64_le );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_LT
    +     case FLOAT64_LT:
    +        test_ab_float64_z_flag( float64_lt, syst_float64_lt );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_EQ_SIGNALING
    +     case FLOAT64_EQ_SIGNALING:
    +        test_ab_float64_z_flag(
    +            float64_eq_signaling, syst_float64_eq_signaling );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_LE_QUIET
    +     case FLOAT64_LE_QUIET:
    +        test_ab_float64_z_flag( float64_le_quiet, syst_float64_le_quiet );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT64_LT_QUIET
    +     case FLOAT64_LT_QUIET:
    +        test_ab_float64_z_flag( float64_lt_quiet, syst_float64_lt_quiet );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_TO_INT32
    +     case FLOATX80_TO_INT32:
    +        test_a_floatx80_z_int32( floatx80_to_int32, syst_floatx80_to_int32 );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_TO_INT32_ROUND_TO_ZERO
    +     case FLOATX80_TO_INT32_ROUND_TO_ZERO:
    +        test_a_floatx80_z_int32(
    +            floatx80_to_int32_round_to_zero,
    +            syst_floatx80_to_int32_round_to_zero
    +        );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_TO_INT64
    +     case FLOATX80_TO_INT64:
    +        test_a_floatx80_z_int64( floatx80_to_int64, syst_floatx80_to_int64 );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_TO_INT64_ROUND_TO_ZERO
    +     case FLOATX80_TO_INT64_ROUND_TO_ZERO:
    +        test_a_floatx80_z_int64(
    +            floatx80_to_int64_round_to_zero,
    +            syst_floatx80_to_int64_round_to_zero
    +        );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_TO_FLOAT32
    +     case FLOATX80_TO_FLOAT32:
    +        test_a_floatx80_z_float32(
    +            floatx80_to_float32, syst_floatx80_to_float32 );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_TO_FLOAT64
    +     case FLOATX80_TO_FLOAT64:
    +        test_a_floatx80_z_float64(
    +            floatx80_to_float64, syst_floatx80_to_float64 );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_TO_FLOAT128
    +     case FLOATX80_TO_FLOAT128:
    +        test_a_floatx80_z_float128(
    +            floatx80_to_float128, syst_floatx80_to_float128 );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_ROUND_TO_INT
    +     case FLOATX80_ROUND_TO_INT:
    +        test_az_floatx80( floatx80_round_to_int, syst_floatx80_round_to_int );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_ADD
    +     case FLOATX80_ADD:
    +        test_abz_floatx80( floatx80_add, syst_floatx80_add );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_SUB
    +     case FLOATX80_SUB:
    +        test_abz_floatx80( floatx80_sub, syst_floatx80_sub );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_MUL
    +     case FLOATX80_MUL:
    +        test_abz_floatx80( floatx80_mul, syst_floatx80_mul );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_DIV
    +     case FLOATX80_DIV:
    +        test_abz_floatx80( floatx80_div, syst_floatx80_div );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_REM
    +     case FLOATX80_REM:
    +        test_abz_floatx80( floatx80_rem, syst_floatx80_rem );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_SQRT
    +     case FLOATX80_SQRT:
    +        test_az_floatx80( floatx80_sqrt, syst_floatx80_sqrt );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_EQ
    +     case FLOATX80_EQ:
    +        test_ab_floatx80_z_flag( floatx80_eq, syst_floatx80_eq );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_LE
    +     case FLOATX80_LE:
    +        test_ab_floatx80_z_flag( floatx80_le, syst_floatx80_le );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_LT
    +     case FLOATX80_LT:
    +        test_ab_floatx80_z_flag( floatx80_lt, syst_floatx80_lt );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_EQ_SIGNALING
    +     case FLOATX80_EQ_SIGNALING:
    +        test_ab_floatx80_z_flag(
    +            floatx80_eq_signaling, syst_floatx80_eq_signaling );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_LE_QUIET
    +     case FLOATX80_LE_QUIET:
    +        test_ab_floatx80_z_flag( floatx80_le_quiet, syst_floatx80_le_quiet );
    +        break;
    +#endif
    +#ifdef SYST_FLOATX80_LT_QUIET
    +     case FLOATX80_LT_QUIET:
    +        test_ab_floatx80_z_flag( floatx80_lt_quiet, syst_floatx80_lt_quiet );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_TO_INT32
    +     case FLOAT128_TO_INT32:
    +        test_a_float128_z_int32( float128_to_int32, syst_float128_to_int32 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
    +     case FLOAT128_TO_INT32_ROUND_TO_ZERO:
    +        test_a_float128_z_int32(
    +            float128_to_int32_round_to_zero,
    +            syst_float128_to_int32_round_to_zero
    +        );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_TO_INT64
    +     case FLOAT128_TO_INT64:
    +        test_a_float128_z_int64( float128_to_int64, syst_float128_to_int64 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
    +     case FLOAT128_TO_INT64_ROUND_TO_ZERO:
    +        test_a_float128_z_int64(
    +            float128_to_int64_round_to_zero,
    +            syst_float128_to_int64_round_to_zero
    +        );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_TO_FLOAT32
    +     case FLOAT128_TO_FLOAT32:
    +        test_a_float128_z_float32(
    +            float128_to_float32, syst_float128_to_float32 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_TO_FLOAT64
    +     case FLOAT128_TO_FLOAT64:
    +        test_a_float128_z_float64(
    +            float128_to_float64, syst_float128_to_float64 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_TO_FLOATX80
    +     case FLOAT128_TO_FLOATX80:
    +        test_a_float128_z_floatx80(
    +            float128_to_floatx80, syst_float128_to_floatx80 );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_ROUND_TO_INT
    +     case FLOAT128_ROUND_TO_INT:
    +        test_az_float128( float128_round_to_int, syst_float128_round_to_int );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_ADD
    +     case FLOAT128_ADD:
    +        test_abz_float128( float128_add, syst_float128_add );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_SUB
    +     case FLOAT128_SUB:
    +        test_abz_float128( float128_sub, syst_float128_sub );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_MUL
    +     case FLOAT128_MUL:
    +        test_abz_float128( float128_mul, syst_float128_mul );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_DIV
    +     case FLOAT128_DIV:
    +        test_abz_float128( float128_div, syst_float128_div );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_REM
    +     case FLOAT128_REM:
    +        test_abz_float128( float128_rem, syst_float128_rem );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_SQRT
    +     case FLOAT128_SQRT:
    +        test_az_float128( float128_sqrt, syst_float128_sqrt );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_EQ
    +     case FLOAT128_EQ:
    +        test_ab_float128_z_flag( float128_eq, syst_float128_eq );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_LE
    +     case FLOAT128_LE:
    +        test_ab_float128_z_flag( float128_le, syst_float128_le );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_LT
    +     case FLOAT128_LT:
    +        test_ab_float128_z_flag( float128_lt, syst_float128_lt );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_EQ_SIGNALING
    +     case FLOAT128_EQ_SIGNALING:
    +        test_ab_float128_z_flag(
    +            float128_eq_signaling, syst_float128_eq_signaling );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_LE_QUIET
    +     case FLOAT128_LE_QUIET:
    +        test_ab_float128_z_flag( float128_le_quiet, syst_float128_le_quiet );
    +        break;
    +#endif
    +#ifdef SYST_FLOAT128_LT_QUIET
    +     case FLOAT128_LT_QUIET:
    +        test_ab_float128_z_flag( float128_lt_quiet, syst_float128_lt_quiet );
    +        break;
    +#endif
    +    }
    +    if ( ( errorStop && anyErrors ) || stop ) exitWithStatus();
    +
    +}
    +
    +void
    + testFunction(
    +     uint8 functionCode, int8 roundingPrecisionIn, int8 roundingModeIn )
    +{
    +    int8 roundingPrecision, roundingMode;
    +
    +    roundingPrecision = 32;
    +    for (;;) {
    +        if ( ! functions[ functionCode ].roundingPrecision ) {
    +            roundingPrecision = 0;
    +        }
    +        else if ( roundingPrecisionIn ) {
    +            roundingPrecision = roundingPrecisionIn;
    +        }
    +        for ( roundingMode = 1;
    +              roundingMode < NUM_ROUNDINGMODES;
    +              ++roundingMode
    +            ) {
    +            if ( ! functions[ functionCode ].roundingMode ) {
    +                roundingMode = 0;
    +            }
    +            else if ( roundingModeIn ) {
    +                roundingMode = roundingModeIn;
    +            }
    +            testFunctionVariety(
    +                functionCode, roundingPrecision, roundingMode );
    +            if ( roundingModeIn || ! roundingMode ) break;
    +        }
    +        if ( roundingPrecisionIn || ! roundingPrecision ) break;
    +        if ( roundingPrecision == 80 ) {
    +            break;
    +        }
    +        else if ( roundingPrecision == 64 ) {
    +            roundingPrecision = 80;
    +        }
    +        else if ( roundingPrecision == 32 ) {
    +            roundingPrecision = 64;
    +        }
    +    }
    +
    +}
    +
    diff --git a/tools/test/testfloat/testFunction.h b/tools/test/testfloat/testFunction.h
    new file mode 100644
    index 00000000000..04bf856046d
    --- /dev/null
    +++ b/tools/test/testfloat/testFunction.h
    @@ -0,0 +1,135 @@
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +enum {
    +    INT32_TO_FLOAT32 = 1,
    +    INT32_TO_FLOAT64,
    +    INT32_TO_FLOATX80,
    +    INT32_TO_FLOAT128,
    +    INT64_TO_FLOAT32,
    +    INT64_TO_FLOAT64,
    +    INT64_TO_FLOATX80,
    +    INT64_TO_FLOAT128,
    +    FLOAT32_TO_INT32,
    +    FLOAT32_TO_INT32_ROUND_TO_ZERO,
    +    FLOAT32_TO_INT64,
    +    FLOAT32_TO_INT64_ROUND_TO_ZERO,
    +    FLOAT32_TO_FLOAT64,
    +    FLOAT32_TO_FLOATX80,
    +    FLOAT32_TO_FLOAT128,
    +    FLOAT32_ROUND_TO_INT,
    +    FLOAT32_ADD,
    +    FLOAT32_SUB,
    +    FLOAT32_MUL,
    +    FLOAT32_DIV,
    +    FLOAT32_REM,
    +    FLOAT32_SQRT,
    +    FLOAT32_EQ,
    +    FLOAT32_LE,
    +    FLOAT32_LT,
    +    FLOAT32_EQ_SIGNALING,
    +    FLOAT32_LE_QUIET,
    +    FLOAT32_LT_QUIET,
    +    FLOAT64_TO_INT32,
    +    FLOAT64_TO_INT32_ROUND_TO_ZERO,
    +    FLOAT64_TO_INT64,
    +    FLOAT64_TO_INT64_ROUND_TO_ZERO,
    +    FLOAT64_TO_FLOAT32,
    +    FLOAT64_TO_FLOATX80,
    +    FLOAT64_TO_FLOAT128,
    +    FLOAT64_ROUND_TO_INT,
    +    FLOAT64_ADD,
    +    FLOAT64_SUB,
    +    FLOAT64_MUL,
    +    FLOAT64_DIV,
    +    FLOAT64_REM,
    +    FLOAT64_SQRT,
    +    FLOAT64_EQ,
    +    FLOAT64_LE,
    +    FLOAT64_LT,
    +    FLOAT64_EQ_SIGNALING,
    +    FLOAT64_LE_QUIET,
    +    FLOAT64_LT_QUIET,
    +    FLOATX80_TO_INT32,
    +    FLOATX80_TO_INT32_ROUND_TO_ZERO,
    +    FLOATX80_TO_INT64,
    +    FLOATX80_TO_INT64_ROUND_TO_ZERO,
    +    FLOATX80_TO_FLOAT32,
    +    FLOATX80_TO_FLOAT64,
    +    FLOATX80_TO_FLOAT128,
    +    FLOATX80_ROUND_TO_INT,
    +    FLOATX80_ADD,
    +    FLOATX80_SUB,
    +    FLOATX80_MUL,
    +    FLOATX80_DIV,
    +    FLOATX80_REM,
    +    FLOATX80_SQRT,
    +    FLOATX80_EQ,
    +    FLOATX80_LE,
    +    FLOATX80_LT,
    +    FLOATX80_EQ_SIGNALING,
    +    FLOATX80_LE_QUIET,
    +    FLOATX80_LT_QUIET,
    +    FLOAT128_TO_INT32,
    +    FLOAT128_TO_INT32_ROUND_TO_ZERO,
    +    FLOAT128_TO_INT64,
    +    FLOAT128_TO_INT64_ROUND_TO_ZERO,
    +    FLOAT128_TO_FLOAT32,
    +    FLOAT128_TO_FLOAT64,
    +    FLOAT128_TO_FLOATX80,
    +    FLOAT128_ROUND_TO_INT,
    +    FLOAT128_ADD,
    +    FLOAT128_SUB,
    +    FLOAT128_MUL,
    +    FLOAT128_DIV,
    +    FLOAT128_REM,
    +    FLOAT128_SQRT,
    +    FLOAT128_EQ,
    +    FLOAT128_LE,
    +    FLOAT128_LT,
    +    FLOAT128_EQ_SIGNALING,
    +    FLOAT128_LE_QUIET,
    +    FLOAT128_LT_QUIET,
    +    NUM_FUNCTIONS
    +};
    +
    +typedef struct {
    +    char *name;
    +    int8 numInputs;
    +    flag roundingPrecision, roundingMode;
    +} functionT;
    +extern const functionT functions[ NUM_FUNCTIONS ];
    +extern const flag functionExists[ NUM_FUNCTIONS ];
    +
    +enum {
    +    ROUND_NEAREST_EVEN = 1,
    +    ROUND_TO_ZERO,
    +    ROUND_DOWN,
    +    ROUND_UP,
    +    NUM_ROUNDINGMODES
    +};
    +
    +void testFunction( uint8, int8, int8 );
    +
    diff --git a/tools/test/testfloat/testLoops.c b/tools/test/testfloat/testLoops.c
    new file mode 100644
    index 00000000000..8ba92f313a4
    --- /dev/null
    +++ b/tools/test/testfloat/testLoops.c
    @@ -0,0 +1,2713 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +#include 
    +#include "milieu.h"
    +#include "softfloat.h"
    +#include "testCases.h"
    +#include "writeHex.h"
    +#include "testLoops.h"
    +
    +volatile flag stop = FALSE;
    +
    +char *trueName, *testName;
    +flag forever, errorStop;
    +uint32 maxErrorCount = 0;
    +flag checkNaNs = FALSE;
    +int8 *trueFlagsPtr;
    +int8 ( *testFlagsFunctionPtr )( void );
    +char *functionName;
    +char *roundingPrecisionName, *roundingModeName, *tininessModeName;
    +flag anyErrors = FALSE;
    +
    +void writeFunctionName( FILE *stream )
    +{
    +
    +    fputs( functionName, stream );
    +    if ( roundingModeName ) {
    +        if ( roundingPrecisionName ) {
    +            fputs( ", precision ", stream );
    +            fputs( roundingPrecisionName, stream );
    +        }
    +        fputs( ", rounding ", stream );
    +        fputs( roundingModeName, stream );
    +        if ( tininessModeName ) {
    +            fputs( ", tininess ", stream );
    +            fputs( tininessModeName, stream );
    +            fputs( " rounding", stream );
    +        }
    +    }
    +
    +}
    +
    +void exitWithStatus( void )
    +{
    +
    +    exit( anyErrors ? EXIT_FAILURE : EXIT_SUCCESS );
    +
    +}
    +
    +static uint32 tenthousandsCount, errorCount = 0;
    +
    +static void writeTestsTotal( void )
    +{
    +
    +    if ( forever ) {
    +        fputs( "Unbounded tests.\n", stderr );
    +    }
    +    else {
    +        fprintf( stderr, "\r%d tests total.\n", testCases_total );
    +    }
    +
    +}
    +
    +static void writeTestsPerformed( int16 count )
    +{
    +
    +    if ( tenthousandsCount ) {
    +        fprintf(
    +            stderr, "\r%d%04d tests performed", tenthousandsCount, count );
    +    }
    +    else {
    +        fprintf( stderr, "\r%d tests performed", count );
    +    }
    +    if ( errorCount ) {
    +        fprintf(
    +            stderr,
    +            "; %d error%s found.\n",
    +            errorCount,
    +            ( errorCount == 1 ) ? "" : "s"
    +        );
    +    }
    +    else {
    +        fputs( ".\n", stderr );
    +        fputs( "No errors found in ", stdout );
    +        writeFunctionName( stdout );
    +        fputs( ".\n", stdout );
    +        fflush( stdout );
    +    }
    +
    +}
    +
    +static void checkEarlyExit( void )
    +{
    +
    +    ++tenthousandsCount;
    +    if ( stop ) {
    +        writeTestsPerformed( 0 );
    +        exitWithStatus();
    +    }
    +    fprintf( stderr, "\r%3d0000", tenthousandsCount );
    +
    +}
    +
    +static void writeErrorFound( int16 count )
    +{
    +
    +    fputc( '\r', stderr );
    +    if ( errorCount == 1 ) {
    +        fputs( "Errors found in ", stdout );
    +        writeFunctionName( stdout );
    +        fputs( ":\n", stdout );
    +    }
    +    if ( stop ) {
    +        writeTestsPerformed( count );
    +        exitWithStatus();
    +    }
    +    anyErrors = TRUE;
    +
    +}
    +
    +INLINE void writeInput_a_int32( void )
    +{
    +
    +    writeHex_bits32( testCases_a_int32, stdout );
    +
    +}
    +
    +#ifdef BITS64
    +
    +INLINE void writeInput_a_int64( void )
    +{
    +
    +    writeHex_bits64( testCases_a_int64, stdout );
    +
    +}
    +
    +#endif
    +
    +INLINE void writeInput_a_float32( void )
    +{
    +
    +    writeHex_float32( testCases_a_float32, stdout );
    +
    +}
    +
    +static void writeInputs_ab_float32( void )
    +{
    +
    +    writeHex_float32( testCases_a_float32, stdout );
    +    fputs( "  ", stdout );
    +    writeHex_float32( testCases_b_float32, stdout );
    +
    +}
    +
    +INLINE void writeInput_a_float64( void )
    +{
    +
    +    writeHex_float64( testCases_a_float64, stdout );
    +
    +}
    +
    +static void writeInputs_ab_float64( void )
    +{
    +
    +    writeHex_float64( testCases_a_float64, stdout );
    +    fputs( "  ", stdout );
    +    writeHex_float64( testCases_b_float64, stdout );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +INLINE void writeInput_a_floatx80( void )
    +{
    +
    +    writeHex_floatx80( testCases_a_floatx80, stdout );
    +
    +}
    +
    +static void writeInputs_ab_floatx80( void )
    +{
    +
    +    writeHex_floatx80( testCases_a_floatx80, stdout );
    +    fputs( "  ", stdout );
    +    writeHex_floatx80( testCases_b_floatx80, stdout );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +INLINE void writeInput_a_float128( void )
    +{
    +
    +    writeHex_float128( testCases_a_float128, stdout );
    +
    +}
    +
    +static void writeInputs_ab_float128( void )
    +{
    +
    +    writeHex_float128( testCases_a_float128, stdout );
    +    fputs( "  ", stdout );
    +    writeHex_float128( testCases_b_float128, stdout );
    +
    +}
    +
    +#endif
    +
    +static void
    + writeOutputs_z_flag(
    +     flag trueZ, uint8 trueFlags, flag testZ, uint8 testFlags )
    +{
    +
    +    fputs( trueName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_flag( trueZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( trueFlags, stdout );
    +    fputs( "  ", stdout );
    +    fputs( testName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_flag( testZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( testFlags, stdout );
    +    fputc( '\n', stdout );
    +
    +}
    +
    +static void
    + writeOutputs_z_int32(
    +     int32 trueZ, uint8 trueFlags, int32 testZ, uint8 testFlags )
    +{
    +
    +    fputs( trueName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_bits32( trueZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( trueFlags, stdout );
    +    fputs( "  ", stdout );
    +    fputs( testName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_bits32( testZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( testFlags, stdout );
    +    fputc( '\n', stdout );
    +
    +}
    +
    +#ifdef BITS64
    +
    +static void
    + writeOutputs_z_int64(
    +     int64 trueZ, uint8 trueFlags, int64 testZ, uint8 testFlags )
    +{
    +
    +    fputs( trueName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_bits64( trueZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( trueFlags, stdout );
    +    fputs( "  ", stdout );
    +    fputs( testName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_bits64( testZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( testFlags, stdout );
    +    fputc( '\n', stdout );
    +
    +}
    +
    +#endif
    +
    +static void
    + writeOutputs_z_float32(
    +     float32 trueZ, uint8 trueFlags, float32 testZ, uint8 testFlags )
    +{
    +
    +    fputs( trueName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_float32( trueZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( trueFlags, stdout );
    +    fputs( "  ", stdout );
    +    fputs( testName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_float32( testZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( testFlags, stdout );
    +    fputc( '\n', stdout );
    +
    +}
    +
    +static void
    + writeOutputs_z_float64(
    +     float64 trueZ, uint8 trueFlags, float64 testZ, uint8 testFlags )
    +{
    +
    +    fputs( trueName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_float64( trueZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( trueFlags, stdout );
    +    fputs( "  ", stdout );
    +    fputs( testName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_float64( testZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( testFlags, stdout );
    +    fputc( '\n', stdout );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +static void
    + writeOutputs_z_floatx80(
    +     floatx80 trueZ, uint8 trueFlags, floatx80 testZ, uint8 testFlags )
    +{
    +
    +    fputs( trueName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_floatx80( trueZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( trueFlags, stdout );
    +    fputs( "  ", stdout );
    +    fputs( testName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_floatx80( testZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( testFlags, stdout );
    +    fputc( '\n', stdout );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +static void
    + writeOutputs_z_float128(
    +     float128 trueZ, uint8 trueFlags, float128 testZ, uint8 testFlags )
    +{
    +
    +    fputs( trueName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_float128( trueZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( trueFlags, stdout );
    +    fputs( "\n\t", stdout );
    +    fputs( testName, stdout );
    +    fputs( ": ", stdout );
    +    writeHex_float128( testZ, stdout );
    +    fputc( ' ', stdout );
    +    writeHex_float_flags( testFlags, stdout );
    +    fputc( '\n', stdout );
    +
    +}
    +
    +#endif
    +
    +INLINE flag float32_isNaN( float32 a )
    +{
    +
    +    return 0x7F800000 < ( a & 0x7FFFFFFF );
    +
    +}
    +
    +#ifdef BITS64
    +
    +INLINE flag float64_same( float64 a, float64 b )
    +{
    +
    +    return a == b;
    +
    +}
    +
    +INLINE flag float64_isNaN( float64 a )
    +{
    +
    +    return LIT64( 0x7FF0000000000000 ) < ( a & LIT64( 0x7FFFFFFFFFFFFFFF ) );
    +
    +}
    +
    +#else
    +
    +INLINE flag float64_same( float64 a, float64 b )
    +{
    +
    +    return ( a.high == b.high ) && ( a.low == b.low );
    +
    +}
    +
    +INLINE flag float64_isNaN( float64 a )
    +{
    +    bits32 absAHigh;
    +
    +    absAHigh = a.high & 0x7FFFFFFF;
    +    return
    +        ( 0x7FF00000 < absAHigh ) || ( ( absAHigh == 0x7FF00000 ) && a.low );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOATX80
    +
    +INLINE flag floatx80_same( floatx80 a, floatx80 b )
    +{
    +
    +    return ( a.high == b.high ) && ( a.low == b.low );
    +
    +}
    +
    +INLINE flag floatx80_isNaN( floatx80 a )
    +{
    +
    +    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && a.low;
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +INLINE flag float128_same( float128 a, float128 b )
    +{
    +
    +    return ( a.high == b.high ) && ( a.low == b.low );
    +
    +}
    +
    +INLINE flag float128_isNaN( float128 a )
    +{
    +    bits64 absAHigh;
    +
    +    absAHigh = a.high & LIT64( 0x7FFFFFFFFFFFFFFF );
    +    return
    +           ( LIT64( 0x7FFF000000000000 ) < absAHigh )
    +        || ( ( absAHigh == LIT64( 0x7FFF000000000000 ) ) && a.low );
    +
    +}
    +
    +#endif
    +
    +void
    + test_a_int32_z_float32(
    +     float32 trueFunction( int32 ), float32 testFunction( int32 ) )
    +{
    +    int16 count;
    +    float32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_int32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_int32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_int32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float32_isNaN( trueZ )
    +                 && float32_isNaN( testZ )
    +                 && ! float32_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_int32();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +void
    + test_a_int32_z_float64(
    +     float64 trueFunction( int32 ), float64 testFunction( int32 ) )
    +{
    +    int16 count;
    +    float64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_int32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_int32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_int32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float64_isNaN( trueZ )
    +                 && float64_isNaN( testZ )
    +                 && ! float64_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_int32();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +void
    + test_a_int32_z_floatx80(
    +     floatx80 trueFunction( int32 ), floatx80 testFunction( int32 ) )
    +{
    +    int16 count;
    +    floatx80 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_int32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_int32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_int32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && floatx80_isNaN( trueZ )
    +                 && floatx80_isNaN( testZ )
    +                 && ! floatx80_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_int32();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +void
    + test_a_int32_z_float128(
    +     float128 trueFunction( int32 ), float128 testFunction( int32 ) )
    +{
    +    int16 count;
    +    float128 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_int32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_int32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_int32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float128_isNaN( trueZ )
    +                 && float128_isNaN( testZ )
    +                 && ! float128_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_int32();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +#ifdef BITS64
    +
    +void
    + test_a_int64_z_float32(
    +     float32 trueFunction( int64 ), float32 testFunction( int64 ) )
    +{
    +    int16 count;
    +    float32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_int64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_int64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_int64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float32_isNaN( trueZ )
    +                 && float32_isNaN( testZ )
    +                 && ! float32_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_int64();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +void
    + test_a_int64_z_float64(
    +     float64 trueFunction( int64 ), float64 testFunction( int64 ) )
    +{
    +    int16 count;
    +    float64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_int64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_int64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_int64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float64_isNaN( trueZ )
    +                 && float64_isNaN( testZ )
    +                 && ! float64_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_int64();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +void
    + test_a_int64_z_floatx80(
    +     floatx80 trueFunction( int64 ), floatx80 testFunction( int64 ) )
    +{
    +    int16 count;
    +    floatx80 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_int64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_int64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_int64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && floatx80_isNaN( trueZ )
    +                 && floatx80_isNaN( testZ )
    +                 && ! floatx80_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_int64();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +void
    + test_a_int64_z_float128(
    +     float128 trueFunction( int64 ), float128 testFunction( int64 ) )
    +{
    +    int16 count;
    +    float128 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_int64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_int64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_int64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float128_isNaN( trueZ )
    +                 && float128_isNaN( testZ )
    +                 && ! float128_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_int64();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +#endif
    +
    +void
    + test_a_float32_z_int32(
    +     int32 trueFunction( float32 ), int32 testFunction( float32 ) )
    +{
    +    int16 count;
    +    int32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ( trueZ == 0x7FFFFFFF )
    +                 && (    ( testZ == 0x7FFFFFFF )
    +                      || ( testZ == (sbits32) 0x80000000 ) )
    +                 && ( trueFlags == float_flag_invalid )
    +                 && ( testFlags == float_flag_invalid )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float32();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef BITS64
    +
    +void
    + test_a_float32_z_int64(
    +     int64 trueFunction( float32 ), int64 testFunction( float32 ) )
    +{
    +    int16 count;
    +    int64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
    +                 && (    ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
    +                      || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
    +                 && ( trueFlags == float_flag_invalid )
    +                 && ( testFlags == float_flag_invalid )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float32();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +void
    + test_a_float32_z_float64(
    +     float64 trueFunction( float32 ), float64 testFunction( float32 ) )
    +{
    +    int16 count;
    +    float64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float64_isNaN( trueZ )
    +                 && float64_isNaN( testZ )
    +                 && ! float64_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float32();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +void
    + test_a_float32_z_floatx80(
    +     floatx80 trueFunction( float32 ), floatx80 testFunction( float32 ) )
    +{
    +    int16 count;
    +    floatx80 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && floatx80_isNaN( trueZ )
    +                 && floatx80_isNaN( testZ )
    +                 && ! floatx80_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float32();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +void
    + test_a_float32_z_float128(
    +     float128 trueFunction( float32 ), float128 testFunction( float32 ) )
    +{
    +    int16 count;
    +    float128 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float128_isNaN( trueZ )
    +                 && float128_isNaN( testZ )
    +                 && ! float128_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float32();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +void
    + test_az_float32(
    +     float32 trueFunction( float32 ), float32 testFunction( float32 ) )
    +{
    +    int16 count;
    +    float32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float32_isNaN( trueZ )
    +                 && float32_isNaN( testZ )
    +                 && ! float32_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float32();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +void
    + test_ab_float32_z_flag(
    +     flag trueFunction( float32, float32 ),
    +     flag testFunction( float32, float32 )
    + )
    +{
    +    int16 count;
    +    flag trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_ab_float32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float32, testCases_b_float32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float32, testCases_b_float32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && (    float32_is_signaling_nan( testCases_a_float32 )
    +                      || float32_is_signaling_nan( testCases_b_float32 ) )
    +               ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInputs_ab_float32();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +    return;
    +
    +}
    +
    +void
    + test_abz_float32(
    +     float32 trueFunction( float32, float32 ),
    +     float32 testFunction( float32, float32 )
    + )
    +{
    +    int16 count;
    +    float32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_ab_float32 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float32, testCases_b_float32 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float32, testCases_b_float32 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && (    float32_is_signaling_nan( testCases_a_float32 )
    +                      || float32_is_signaling_nan( testCases_b_float32 ) )
    +               ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float32_isNaN( trueZ )
    +                 && float32_isNaN( testZ )
    +                 && ! float32_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInputs_ab_float32();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +    return;
    +
    +}
    +
    +void
    + test_a_float64_z_int32(
    +     int32 trueFunction( float64 ), int32 testFunction( float64 ) )
    +{
    +    int16 count;
    +    int32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ( trueZ == 0x7FFFFFFF )
    +                 && (    ( testZ == 0x7FFFFFFF )
    +                      || ( testZ == (sbits32) 0x80000000 ) )
    +                 && ( trueFlags == float_flag_invalid )
    +                 && ( testFlags == float_flag_invalid )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float64();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef BITS64
    +
    +void
    + test_a_float64_z_int64(
    +     int64 trueFunction( float64 ), int64 testFunction( float64 ) )
    +{
    +    int16 count;
    +    int64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
    +                 && (    ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
    +                      || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
    +                 && ( trueFlags == float_flag_invalid )
    +                 && ( testFlags == float_flag_invalid )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float64();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +void
    + test_a_float64_z_float32(
    +     float32 trueFunction( float64 ), float32 testFunction( float64 ) )
    +{
    +    int16 count;
    +    float32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float32_isNaN( trueZ )
    +                 && float32_isNaN( testZ )
    +                 && ! float32_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float64();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +void
    + test_a_float64_z_floatx80(
    +     floatx80 trueFunction( float64 ), floatx80 testFunction( float64 ) )
    +{
    +    int16 count;
    +    floatx80 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && floatx80_isNaN( trueZ )
    +                 && floatx80_isNaN( testZ )
    +                 && ! floatx80_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float64();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +void
    + test_a_float64_z_float128(
    +     float128 trueFunction( float64 ), float128 testFunction( float64 ) )
    +{
    +    int16 count;
    +    float128 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float128_isNaN( trueZ )
    +                 && float128_isNaN( testZ )
    +                 && ! float128_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float64();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +void
    + test_az_float64(
    +     float64 trueFunction( float64 ), float64 testFunction( float64 ) )
    +{
    +    int16 count;
    +    float64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float64_isNaN( trueZ )
    +                 && float64_isNaN( testZ )
    +                 && ! float64_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float64();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +void
    + test_ab_float64_z_flag(
    +     flag trueFunction( float64, float64 ),
    +     flag testFunction( float64, float64 )
    + )
    +{
    +    int16 count;
    +    flag trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_ab_float64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float64, testCases_b_float64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float64, testCases_b_float64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && (    float64_is_signaling_nan( testCases_a_float64 )
    +                      || float64_is_signaling_nan( testCases_b_float64 ) )
    +               ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInputs_ab_float64();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +    return;
    +
    +}
    +
    +void
    + test_abz_float64(
    +     float64 trueFunction( float64, float64 ),
    +     float64 testFunction( float64, float64 )
    + )
    +{
    +    int16 count;
    +    float64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_ab_float64 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float64, testCases_b_float64 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float64, testCases_b_float64 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && (    float64_is_signaling_nan( testCases_a_float64 )
    +                      || float64_is_signaling_nan( testCases_b_float64 ) )
    +               ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float64_isNaN( trueZ )
    +                 && float64_isNaN( testZ )
    +                 && ! float64_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInputs_ab_float64();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +    return;
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +void
    + test_a_floatx80_z_int32(
    +     int32 trueFunction( floatx80 ), int32 testFunction( floatx80 ) )
    +{
    +    int16 count;
    +    int32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_floatx80 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_floatx80 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_floatx80 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ( trueZ == 0x7FFFFFFF )
    +                 && (    ( testZ == 0x7FFFFFFF )
    +                      || ( testZ == (sbits32) 0x80000000 ) )
    +                 && ( trueFlags == float_flag_invalid )
    +                 && ( testFlags == float_flag_invalid )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_floatx80();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef BITS64
    +
    +void
    + test_a_floatx80_z_int64(
    +     int64 trueFunction( floatx80 ), int64 testFunction( floatx80 ) )
    +{
    +    int16 count;
    +    int64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_floatx80 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_floatx80 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_floatx80 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
    +                 && (    ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
    +                      || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
    +                 && ( trueFlags == float_flag_invalid )
    +                 && ( testFlags == float_flag_invalid )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_floatx80();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +void
    + test_a_floatx80_z_float32(
    +     float32 trueFunction( floatx80 ), float32 testFunction( floatx80 ) )
    +{
    +    int16 count;
    +    float32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_floatx80 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_floatx80 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_floatx80 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float32_isNaN( trueZ )
    +                 && float32_isNaN( testZ )
    +                 && ! float32_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_floatx80();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +void
    + test_a_floatx80_z_float64(
    +     float64 trueFunction( floatx80 ), float64 testFunction( floatx80 ) )
    +{
    +    int16 count;
    +    float64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_floatx80 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_floatx80 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_floatx80 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float64_isNaN( trueZ )
    +                 && float64_isNaN( testZ )
    +                 && ! float64_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_floatx80();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef FLOAT128
    +
    +void
    + test_a_floatx80_z_float128(
    +     float128 trueFunction( floatx80 ), float128 testFunction( floatx80 ) )
    +{
    +    int16 count;
    +    float128 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_floatx80 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_floatx80 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_floatx80 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float128_isNaN( trueZ )
    +                 && float128_isNaN( testZ )
    +                 && ! float128_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_floatx80();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +void
    + test_az_floatx80(
    +     floatx80 trueFunction( floatx80 ), floatx80 testFunction( floatx80 ) )
    +{
    +    int16 count;
    +    floatx80 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_floatx80 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_floatx80 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_floatx80 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && floatx80_isNaN( trueZ )
    +                 && floatx80_isNaN( testZ )
    +                 && ! floatx80_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_floatx80();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +void
    + test_ab_floatx80_z_flag(
    +     flag trueFunction( floatx80, floatx80 ),
    +     flag testFunction( floatx80, floatx80 )
    + )
    +{
    +    int16 count;
    +    flag trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_ab_floatx80 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_floatx80, testCases_b_floatx80 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_floatx80, testCases_b_floatx80 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && (    floatx80_is_signaling_nan( testCases_a_floatx80 )
    +                      || floatx80_is_signaling_nan( testCases_b_floatx80 ) )
    +               ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInputs_ab_floatx80();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +    return;
    +
    +}
    +
    +void
    + test_abz_floatx80(
    +     floatx80 trueFunction( floatx80, floatx80 ),
    +     floatx80 testFunction( floatx80, floatx80 )
    + )
    +{
    +    int16 count;
    +    floatx80 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_ab_floatx80 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_floatx80, testCases_b_floatx80 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_floatx80, testCases_b_floatx80 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && (    floatx80_is_signaling_nan( testCases_a_floatx80 )
    +                      || floatx80_is_signaling_nan( testCases_b_floatx80 ) )
    +               ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && floatx80_isNaN( trueZ )
    +                 && floatx80_isNaN( testZ )
    +                 && ! floatx80_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInputs_ab_floatx80();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +    return;
    +
    +}
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +void
    + test_a_float128_z_int32(
    +     int32 trueFunction( float128 ), int32 testFunction( float128 ) )
    +{
    +    int16 count;
    +    int32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float128 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float128 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float128 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ( trueZ == 0x7FFFFFFF )
    +                 && (    ( testZ == 0x7FFFFFFF )
    +                      || ( testZ == (sbits32) 0x80000000 ) )
    +                 && ( trueFlags == float_flag_invalid )
    +                 && ( testFlags == float_flag_invalid )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float128();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef BITS64
    +
    +void
    + test_a_float128_z_int64(
    +     int64 trueFunction( float128 ), int64 testFunction( float128 ) )
    +{
    +    int16 count;
    +    int64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float128 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float128 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float128 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
    +                 && (    ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
    +                      || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
    +                 && ( trueFlags == float_flag_invalid )
    +                 && ( testFlags == float_flag_invalid )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float128();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +void
    + test_a_float128_z_float32(
    +     float32 trueFunction( float128 ), float32 testFunction( float128 ) )
    +{
    +    int16 count;
    +    float32 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float128 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float128 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float128 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float32_isNaN( trueZ )
    +                 && float32_isNaN( testZ )
    +                 && ! float32_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float128();
    +                fputs( "  ", stdout );
    +                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +void
    + test_a_float128_z_float64(
    +     float64 trueFunction( float128 ), float64 testFunction( float128 ) )
    +{
    +    int16 count;
    +    float64 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float128 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float128 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float128 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float64_isNaN( trueZ )
    +                 && float64_isNaN( testZ )
    +                 && ! float64_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float128();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#ifdef FLOATX80
    +
    +void
    + test_a_float128_z_floatx80(
    +     floatx80 trueFunction( float128 ), floatx80 testFunction( float128 ) )
    +{
    +    int16 count;
    +    floatx80 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float128 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float128 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float128 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && floatx80_isNaN( trueZ )
    +                 && floatx80_isNaN( testZ )
    +                 && ! floatx80_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float128();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +#endif
    +
    +void
    + test_az_float128(
    +     float128 trueFunction( float128 ), float128 testFunction( float128 ) )
    +{
    +    int16 count;
    +    float128 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_a_float128 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float128 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float128 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float128_isNaN( trueZ )
    +                 && float128_isNaN( testZ )
    +                 && ! float128_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInput_a_float128();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +
    +}
    +
    +void
    + test_ab_float128_z_flag(
    +     flag trueFunction( float128, float128 ),
    +     flag testFunction( float128, float128 )
    + )
    +{
    +    int16 count;
    +    flag trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_ab_float128 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float128, testCases_b_float128 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float128, testCases_b_float128 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && (    float128_is_signaling_nan( testCases_a_float128 )
    +                      || float128_is_signaling_nan( testCases_b_float128 ) )
    +               ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInputs_ab_float128();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +    return;
    +
    +}
    +
    +void
    + test_abz_float128(
    +     float128 trueFunction( float128, float128 ),
    +     float128 testFunction( float128, float128 )
    + )
    +{
    +    int16 count;
    +    float128 trueZ, testZ;
    +    uint8 trueFlags, testFlags;
    +
    +    errorCount = 0;
    +    tenthousandsCount = 0;
    +    count = 10000;
    +    testCases_initSequence( testCases_sequence_ab_float128 );
    +    writeTestsTotal();
    +    while ( ! testCases_done || forever ) {
    +        testCases_next();
    +        *trueFlagsPtr = 0;
    +        trueZ = trueFunction( testCases_a_float128, testCases_b_float128 );
    +        trueFlags = *trueFlagsPtr;
    +        (void) testFlagsFunctionPtr();
    +        testZ = testFunction( testCases_a_float128, testCases_b_float128 );
    +        testFlags = testFlagsFunctionPtr();
    +        --count;
    +        if ( count == 0 ) {
    +            checkEarlyExit();
    +            count = 10000;
    +        }
    +        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
    +            if (    ! checkNaNs
    +                 && (    float128_is_signaling_nan( testCases_a_float128 )
    +                      || float128_is_signaling_nan( testCases_b_float128 ) )
    +               ) {
    +                trueFlags |= float_flag_invalid;
    +            }
    +            if (    ! checkNaNs
    +                 && float128_isNaN( trueZ )
    +                 && float128_isNaN( testZ )
    +                 && ! float128_is_signaling_nan( testZ )
    +                 && ( trueFlags == testFlags )
    +               ) {
    +                /* no problem */
    +            }
    +            else {
    +                ++errorCount;
    +                writeErrorFound( 10000 - count );
    +                writeInputs_ab_float128();
    +                fputs( "\n\t", stdout );
    +                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
    +                fflush( stdout );
    +                if ( errorCount == maxErrorCount ) goto exit;
    +            }
    +        }
    +    }
    + exit:
    +    writeTestsPerformed( 10000 - count );
    +    return;
    +
    +}
    +
    +#endif
    +
    diff --git a/tools/test/testfloat/testLoops.h b/tools/test/testfloat/testLoops.h
    new file mode 100644
    index 00000000000..c3b08477f0e
    --- /dev/null
    +++ b/tools/test/testfloat/testLoops.h
    @@ -0,0 +1,143 @@
    +
    +/*
    +===============================================================================
    +
    +This C header file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +
    +extern volatile flag stop;
    +
    +extern char *trueName, *testName;
    +extern flag forever, errorStop;
    +extern uint32 maxErrorCount;
    +extern flag checkNaNs;
    +extern int8 *trueFlagsPtr;
    +extern int8 ( *testFlagsFunctionPtr )( void );
    +extern char *functionName;
    +extern char *roundingPrecisionName, *roundingModeName, *tininessModeName;
    +extern flag anyErrors;
    +
    +void writeFunctionName( FILE * );
    +void exitWithStatus( void );
    +
    +void test_a_int32_z_float32( float32 ( int32 ), float32 ( int32 ) );
    +void test_a_int32_z_float64( float64 ( int32 ), float64 ( int32 ) );
    +#ifdef FLOATX80
    +void test_a_int32_z_floatx80( floatx80 ( int32 ), floatx80 ( int32 ) );
    +#endif
    +#ifdef FLOAT128
    +void test_a_int32_z_float128( float128 ( int32 ), float128 ( int32 ) );
    +#endif
    +#ifdef BITS64
    +void test_a_int64_z_float32( float32 ( int64 ), float32 ( int64 ) );
    +void test_a_int64_z_float64( float64 ( int64 ), float64 ( int64 ) );
    +#ifdef FLOATX80
    +void test_a_int64_z_floatx80( floatx80 ( int64 ), floatx80 ( int64 ) );
    +#endif
    +#ifdef FLOAT128
    +void test_a_int64_z_float128( float128 ( int64 ), float128 ( int64 ) );
    +#endif
    +#endif
    +
    +void test_a_float32_z_int32( int32 ( float32 ), int32 ( float32 ) );
    +#ifdef BITS64
    +void test_a_float32_z_int64( int64 ( float32 ), int64 ( float32 ) );
    +#endif
    +void test_a_float32_z_float64( float64 ( float32 ), float64 ( float32 ) );
    +#ifdef FLOATX80
    +void test_a_float32_z_floatx80( floatx80 ( float32 ), floatx80 ( float32 ) );
    +#endif
    +#ifdef FLOAT128
    +void test_a_float32_z_float128( float128 ( float32 ), float128 ( float32 ) );
    +#endif
    +void test_az_float32( float32 ( float32 ), float32 ( float32 ) );
    +void
    + test_ab_float32_z_flag(
    +     flag ( float32, float32 ), flag ( float32, float32 ) );
    +void
    + test_abz_float32(
    +     float32 ( float32, float32 ), float32 ( float32, float32 ) );
    +
    +void test_a_float64_z_int32( int32 ( float64 ), int32 ( float64 ) );
    +#ifdef BITS64
    +void test_a_float64_z_int64( int64 ( float64 ), int64 ( float64 ) );
    +#endif
    +void test_a_float64_z_float32( float32 ( float64 ), float32 ( float64 ) );
    +#ifdef FLOATX80
    +void test_a_float64_z_floatx80( floatx80 ( float64 ), floatx80 ( float64 ) );
    +#endif
    +#ifdef FLOAT128
    +void test_a_float64_z_float128( float128 ( float64 ), float128 ( float64 ) );
    +#endif
    +void test_az_float64( float64 ( float64 ), float64 ( float64 ) );
    +void
    + test_ab_float64_z_flag(
    +     flag ( float64, float64 ), flag ( float64, float64 ) );
    +void
    + test_abz_float64(
    +     float64 ( float64, float64 ), float64 ( float64, float64 ) );
    +
    +#ifdef FLOATX80
    +
    +void test_a_floatx80_z_int32( int32 ( floatx80 ), int32 ( floatx80 ) );
    +#ifdef BITS64
    +void test_a_floatx80_z_int64( int64 ( floatx80 ), int64 ( floatx80 ) );
    +#endif
    +void test_a_floatx80_z_float32( float32 ( floatx80 ), float32 ( floatx80 ) );
    +void test_a_floatx80_z_float64( float64 ( floatx80 ), float64 ( floatx80 ) );
    +#ifdef FLOAT128
    +void
    + test_a_floatx80_z_float128( float128 ( floatx80 ), float128 ( floatx80 ) );
    +#endif
    +void test_az_floatx80( floatx80 ( floatx80 ), floatx80 ( floatx80 ) );
    +void
    + test_ab_floatx80_z_flag(
    +     flag ( floatx80, floatx80 ), flag ( floatx80, floatx80 ) );
    +void
    + test_abz_floatx80(
    +     floatx80 ( floatx80, floatx80 ), floatx80 ( floatx80, floatx80 ) );
    +
    +#endif
    +
    +#ifdef FLOAT128
    +
    +void test_a_float128_z_int32( int32 ( float128 ), int32 ( float128 ) );
    +#ifdef BITS64
    +void test_a_float128_z_int64( int64 ( float128 ), int64 ( float128 ) );
    +#endif
    +void test_a_float128_z_float32( float32 ( float128 ), float32 ( float128 ) );
    +void test_a_float128_z_float64( float64 ( float128 ), float64 ( float128 ) );
    +#ifdef FLOATX80
    +void
    + test_a_float128_z_floatx80( floatx80 ( float128 ), floatx80 ( float128 ) );
    +#endif
    +void test_az_float128( float128 ( float128 ), float128 ( float128 ) );
    +void
    + test_ab_float128_z_flag(
    +     flag ( float128, float128 ), flag ( float128, float128 ) );
    +void
    + test_abz_float128(
    +     float128 ( float128, float128 ), float128 ( float128, float128 ) );
    +
    +#endif
    +
    diff --git a/tools/test/testfloat/testfloat-history.txt b/tools/test/testfloat/testfloat-history.txt
    new file mode 100644
    index 00000000000..61520b3b678
    --- /dev/null
    +++ b/tools/test/testfloat/testfloat-history.txt
    @@ -0,0 +1,57 @@
    +
    +History of Major Changes to TestFloat, up to Release 2a
    +
    +John R. Hauser
    +1998 December 17
    +
    +
    +The TestFloat releases parallel those of SoftFloat, on which TestFloat is
    +based.  Each TestFloat release also incorporates all bug fixes from the
    +corresponding release of SoftFloat.
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +Release 2a (1998 December)
    +
    +-- Added support for testing conversions between floating-point and 64-bit
    +   integers.
    +
    +-- Improved the makefiles.
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +Release 2 (1997 June)
    +
    +-- Integrated the generation of test cases and the checking of system
    +   results into a single program.  (Before they were separate programs,
    +   normally joined by explicit command-line pipes.)
    +
    +-- Improved the sequence of test cases.
    +
    +-- Added support for testing extended double precision and quadruple
    +   precision.
    +
    +-- Made program output more readable, and added new command arguments.
    +
    +-- Reduced dependence on the quality of the standard `random' function for
    +   generating test cases.  (Previously naively expected `random' to be able
    +   to generate good random bits for the entire machine word width.)
    +
    +-- Created `testsoftfloat', with its own simpler complete software floating-
    +   point (``slowfloat'') for comparison purposes.
    +
    +-- Made some changes to the source file structure, including renaming
    +   `environment.h' to `milieu.h' (to avoid confusion with environment
    +   variables).
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +Release 1a (1996 July)
    +
    +-- Added the `-tininessbefore' and `-tininessafter' options to control
    +   whether tininess should be detected before or after rounding.
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +Release 1 (1996 July)
    +
    +-- Original release.
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +
    diff --git a/tools/test/testfloat/testfloat-source.txt b/tools/test/testfloat/testfloat-source.txt
    new file mode 100644
    index 00000000000..b8f7e9bb3ed
    --- /dev/null
    +++ b/tools/test/testfloat/testfloat-source.txt
    @@ -0,0 +1,444 @@
    +
    +TestFloat Release 2a Source Documentation
    +
    +John R. Hauser
    +1998 December 16
    +
    +
    +-------------------------------------------------------------------------------
    +Introduction
    +
    +TestFloat is a program for testing that a floating-point implementation
    +conforms to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
    +All standard operations supported by the system can be tested, except for
    +conversions to and from decimal.  Any of the following machine formats can
    +be tested:  single precision, double precision, extended double precision,
    +and/or quadruple precision.  Testing extended double-precision or quadruple-
    +precision formats requires a C compiler that supports 64-bit integer
    +arithmetic.
    +
    +This document gives information needed for compiling and/or porting
    +TestFloat.
    +
    +The source code for TestFloat is intended to be relatively machine-
    +independent.  TestFloat is written in C, and should be compilable using
    +any ISO/ANSI C compiler.  At the time of this writing, the program has
    +been successfully compiled using the GNU C Compiler (`gcc') for several
    +platforms.  Because ISO/ANSI C does not provide access to some features
    +of IEC/IEEE floating-point such as the exception flags, porting TestFloat
    +unfortunately involves some machine-dependent coding.
    +
    +TestFloat depends on SoftFloat, which is a software implementation of
    +floating-point that conforms to the IEC/IEEE Standard.  SoftFloat is not
    +included with the TestFloat sources.  It can be obtained from the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'.
    +
    +In addition to a program for testing a machine's floating-point, the
    +TestFloat package includes a variant for testing SoftFloat called
    +`testsoftfloat'.  The sources for both programs are intermixed, and both are
    +described here.
    +
    +The first release of TestFloat (Release 1) was called _FloatTest_.  The old
    +name has been obsolete for some time.
    +
    +
    +-------------------------------------------------------------------------------
    +Limitations
    +
    +TestFloat as written requires an ISO/ANSI-style C compiler.  No attempt has
    +been made to accomodate compilers that are not ISO-conformant.  Older ``K&R-
    +style'' compilers are not adequate for compiling TestFloat.  All testing I
    +have done so far has been with the GNU C Compiler.  Compilation with other
    +compilers should be possible but has not been tested.
    +
    +The TestFloat sources assume that source code file names can be longer than
    +8 characters.  In order to compile under an MS-DOS-style system, many of the
    +source files will need to be renamed, and the source and makefiles edited
    +appropriately.  Once compiled, the TestFloat program does not depend on the
    +existence of long file names.
    +
    +The underlying machine is assumed to be binary with a word size that is a
    +power of 2.  Bytes are 8 bits.  Testing of extended double-precision and
    +quadruple-precision formats depends on the C compiler implementing a 64-bit
    +integer type.  If the largest integer type supported by the C compiler is
    +32 bits, only single- and double-precision operations can be tested.
    +
    +
    +-------------------------------------------------------------------------------
    +Contents
    +
    +    Introduction
    +    Limitations
    +    Contents
    +    Legal Notice
    +    TestFloat Source Directory Structure
    +    Target-Independent Modules
    +    Target-Specific Modules
    +    Target-Specific Header Files
    +        processors/*.h
    +        testfloat/*/milieu.h
    +    Target-Specific Floating-Point Subroutines
    +    Steps to Creating the TestFloat Executables
    +    Improving the Random Number Generator
    +    Contact Information
    +
    +
    +
    +-------------------------------------------------------------------------------
    +Legal Notice
    +
    +TestFloat was written by John R. Hauser.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +
    +-------------------------------------------------------------------------------
    +TestFloat Source Directory Structure
    +
    +Because TestFloat is targeted to multiple platforms, its source code
    +is slightly scattered between target-specific and target-independent
    +directories and files.  The directory structure is as follows:
    +
    +    processors
    +    testfloat
    +        templates
    +        386-Win32-gcc
    +        SPARC-Solaris-gcc
    +
    +The two topmost directories and their contents are:
    +
    +    testfloat    - Most of the source code needed for TestFloat.
    +    processors   - Target-specific header files that are not specific to
    +                       TestFloat.
    +
    +Within the `testfloat' directory are subdirectories for each of the
    +targeted platforms.  The TestFloat source code is distributed with targets
    +`386-Win32-gcc' and `SPARC-Solaris-gcc' (and perhaps others) already
    +prepared.  These can be used as examples for porting to new targets.  Source
    +files that are not within these target-specific subdirectories are intended
    +to be target-independent.
    +
    +The naming convention used for the target-specific directories is
    +`--'.  The names of the supplied
    +target directories should be interpreted as follows:
    +
    +  :
    +    386          - Intel 386-compatible processor.
    +    SPARC        - SPARC processor (as used by Sun machines).
    +  :
    +    Win32        - Microsoft Win32 executable.
    +    Solaris      - Sun Solaris executable.
    +  :
    +    gcc          - GNU C Compiler.
    +
    +You do not need to maintain this convention if you do not want to.
    +
    +Alongside the supplied target-specific directories there is a `templates'
    +directory containing a set of ``generic'' target-specific source files.
    +A new target directory can be created by copying the `templates' directory
    +and editing the files inside.  (Complete instructions for porting TestFloat
    +to a new target are in the section _Steps_to_Creating_the_TestFloat_
    +_Executables_.)  Note that the `templates' directory will not work as a
    +target directory without some editing.  To avoid confusion, it would be wise
    +to refrain from editing the files inside `templates' directly.
    +
    +In addition to the distributed sources, TestFloat depends on the existence
    +of an appropriately-compiled SoftFloat binary and the corresponding header
    +file `softfloat.h'.  SoftFloat is not included with the TestFloat sources.
    +It can be obtained from the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
    +arithmetic/SoftFloat.html'.
    +
    +As distributed, the makefiles for TestFloat assume the existence of three
    +sibling directories:
    +
    +    processors
    +    softfloat
    +    testfloat
    +
    +Only the `processors' and `testfloat' directories are included in the
    +TestFloat package.  The `softfloat' directory is assumed to contain a
    +target-specific subdirectory within which the SoftFloat header file and
    +compiled binary can be found.  (See the source documentation accompanying
    +SoftFloat.)  The `processors' directory distributed with TestFloat is
    +intended to be identical to that included with the SoftFloat source.
    +
    +These are the defaults, but other organizations of the sources are possible.
    +The TestFloat makefiles and `milieu.h' files (see below) are easily edited
    +to accomodate other arrangements.
    +
    +
    +-------------------------------------------------------------------------------
    +Target-Independent Modules
    +
    +The TestFloat program is composed of a number of modules, some target-
    +specific and some target-independent.  The target-independent modules are as
    +follows:
    +
    +-- The `fail' module provides a common routine for writing an error message
    +   and aborting.
    +
    +-- The `random' module generates random integer values.
    +
    +-- The `writeHex' module defines routines for writing the various types in
    +   the hexadecimal form used by TestFloat.
    +
    +-- The `testCases' module generates test cases for the various types.
    +
    +-- The `testLoops' module contains various routines for exercising two
    +   implementations of a function and reporting any differences observed.
    +
    +-- The `slowfloat' module provides the simple floating-point implementation
    +   used by `testsoftfloat' for comparing against SoftFloat.  The heart
    +   of `slowfloat' is found in either `slowfloat-32' or `slowfloat-64',
    +   depending on whether the `BITS64' macro is defined.
    +
    +-- The `systfloat' module gives a SoftFloat-like interface to the machine's
    +   floating-point.
    +
    +-- The `testFunction' module implements `testfloat's main loop for testing a
    +   function for all of the relevant rounding modes and rounding precisions.
    +   (The `testsoftfloat' program contains its own version of this code.)
    +
    +-- The `testfloat' and `testsoftfloat' modules are the main modules for the
    +   `testfloat' and `testsoftfloat' programs.
    +
    +Except possibly for `systfloat', these modules should not need to be
    +modified.
    +
    +The `systfloat' module uses the floating-point operations of the C language
    +to access a machine's floating-point.  Unfortunately, some IEC/IEEE
    +floating-point operations are not accessible within ISO/ANSI C.  The
    +following machine functions cannot be tested unless an alternate `systfloat'
    +module is provided:
    +
    +    _to_int32 (rounded according to rounding mode)
    +    _to_int64 (rounded according to rounding mode)
    +    _round_to_int
    +    _rem
    +    _sqrt, except float64_sqrt
    +    _eq_signaling
    +    _le_quiet
    +    _lt_quiet
    +
    +The `-list' option to `testfloat' will show the operations the program is
    +prepared to test.  The section _Target-Specific_Floating-Point_Subroutines_
    +later in this document explains how to create a target-specific `systfloat'
    +module to change the set of testable functions.
    +
    +
    +-------------------------------------------------------------------------------
    +Target-Specific Modules
    +
    +No target-specific modules are needed for `testsoftfloat'.
    +
    +The `testfloat' program uses two target-specific modules:
    +
    +-- The `systmodes' module defines functions for setting the modes
    +   controlling the system's floating-point, including the rounding mode and
    +   the rounding precision for extended double precision.
    +
    +-- The `systflags' module provides a function for clearing and examining the
    +   system's floating-point exception flags.
    +
    +These modules must be supplied for each target.  They can be implemented in
    +any way desired, so long as all is reflected in the target's makefile.  For
    +the targets that come with the distributed source, each of these modules is
    +implemented as a single assembly language or C language source file.
    +
    +
    +-------------------------------------------------------------------------------
    +Target-Specific Header Files
    +
    +The purpose of the two target-specific header files is detailed below.
    +In the following, the `*' symbol is used in place of the name of a specific
    +target, such as `386-Win32-gcc' or `SPARC-Solaris-gcc', or in place of some
    +other text as explained below.
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +processors/*.h
    +
    +The target-specific `processors' header file defines integer types
    +of various sizes, and also defines certain C preprocessor macros that
    +characterize the target.  The two examples supplied are `386-gcc.h' and
    +`SPARC-gcc.h'.  The naming convention used for processor header files is
    +`-.h'.  The `processors' header file used to compile
    +TestFloat should be the same as that used to compile SoftFloat.
    +
    +If 64-bit integers are supported by the compiler, the macro name `BITS64'
    +should be defined here along with the corresponding 64-bit integer
    +types.  In addition, the function-like macro `LIT64' must be defined for
    +constructing 64-bit integer literals (constants).  The `LIT64' macro is used
    +consistently in the TestFloat code to annotate 64-bit literals.
    +
    +If an inlining attribute (such as an `inline' keyword) is provided by the
    +compiler, the macro `INLINE' should be defined to the appropriate keyword.
    +If not, `INLINE' can be set to the keyword `static'.  The `INLINE' macro
    +appears in the TestFloat source code before every function that should be
    +inlined by the compiler.
    +
    +For maximum flexibility, the TestFloat source files do not include the
    +`processors' header file directly; rather, this file is included by the
    +target-specific `milieu.h' header, and `milieu.h' is included by the source
    +files.
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +testfloat/*/milieu.h
    +
    +The `milieu.h' header file provides declarations that are needed to
    +compile TestFloat.  In particular, it is through this header file that
    +the appropriate `processors' header is included to characterize the target
    +processor.  In addition, deviations from ISO/ANSI C by the compiler (such as
    +names not properly declared in system header files) are corrected in this
    +header if possible.
    +
    +If the preprocessor macro `BITS64' is defined in the `processors' header
    +file but only the 32-bit version of SoftFloat is actually used, the `BITS64'
    +macro should be undefined here after the `processors' header has defined it.
    +
    +If the C compiler implements the `long double' floating-point type of C
    +as extended double precision, then `LONG_DOUBLE_IS_FLOATX80' should be
    +defined here.  Alternatively, if the C `long double' type is implemented as
    +quadruple precision, `LONG_DOUBLE_IS_FLOAT128' should be defined.  At most
    +one of these macros should be defined.  A C compiler is allowed to implement
    +`long double' the same as `double', in which case neither of these macros
    +should be defined.
    +
    +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    +
    +
    +-------------------------------------------------------------------------------
    +Target-Specific Floating-Point Subroutines
    +
    +This section applies only to `testfloat' and not to `testsoftfloat'.
    +
    +By default, TestFloat tests a machine's floating-point by testing the
    +floating-point operations of the C language.  Unfortunately, some IEC/IEEE
    +floating-point operations are not defined within ISO/ANSI C.  If a machine
    +implements such ``non-C'' operations, target-specific subroutines for
    +the operations can be supplied to allow TestFloat to test these machine
    +features.  Typically, such subroutines will need to be written in assembly
    +language, although equivalent functions can sometimes be found among the
    +system's software libraries.
    +
    +The following machine functions cannot be tested by TestFloat unless target-
    +specific subroutines are supplied for them:
    +
    +    _to_int32 (rounded according to rounding mode)
    +    _to_int64 (rounded according to rounding mode)
    +    _round_to_int
    +    _rem
    +    _sqrt, except float64_sqrt
    +    _eq_signaling
    +    _le_quiet
    +    _lt_quiet
    +
    +In addition to these, none of the `floatx80' functions can be tested by
    +default if the C `long double' type is something other than extended double
    +precision; and likewise, none of the `float128' functions can be tested by
    +default if `long double' is not quadruple precision.  Since `long double'
    +cannot be both extended double precision and quadruple precision at the
    +same time, at least one of these types cannot be tested by TestFloat without
    +appropriate subroutines being supplied for that type.  (On the other hand,
    +few systems implement _both_ extended double-precision and quadruple-
    +precision floating-point; and unless a system does implement both, it does
    +not need both tested.)
    +
    +Note that the `-list' option to `testfloat' will show the operations
    +TestFloat is prepared to test.
    +
    +TestFloat's `systfloat' module supplies the system version of the functions
    +to be tested.  The names of the `systfloat' subroutines are the same as the
    +function names used as arguments to the `testfloat' command but with `syst_'
    +prefixed--thus, for example, `syst_float32_add' and `syst_int32_to_float32'.
    +The default `systfloat' module maps these system functions to the standard
    +C operations; so `syst_float32_add', for example, is implemented using the
    +C `+' operation for the single-precision `float' type.  For each system
    +function supplied by `systfloat', a corresponding `SYST_'
    +preprocessor macro is defined in `systfloat.h' to indicate that the function
    +exists to be tested (e.g., `SYST_FLOAT32_ADD').  The `systfloat.h' header
    +file also declares function prototypes for the `systfloat' functions.
    +
    +(The `systfloat.h' file that comes with the TestFloat package declares
    +prototypes for all of the possible `systfloat' functions, whether defined in
    +`systfloat' or not.  There is no penalty for declaring a function prototype
    +that is never used.)
    +
    +A target-specific version of the `systfloat' module can easily be created to
    +replace the generic one.  This in fact has been done for the example targets
    +`386-Win32-gcc' and `SPARC-Solaris-gcc'.  For each target, an assembly
    +language `systfloat.S' has been created in the target directory along with
    +a corresponding `systfloat.h' header file defining the `SYST_'
    +macros for the functions implemented.  The makefiles of the targets have
    +been edited to use these target-specific versions of `systfloat' rather than
    +the generic one.
    +
    +The `systfloat' modules of the example targets have been written entirely
    +in assembly language in order to bypass any peculiarities of the C compiler.
    +Although this is probably a good idea, it is certainly not required.
    +
    +
    +-------------------------------------------------------------------------------
    +Steps to Creating the TestFloat Executables
    +
    +Porting and/or compiling TestFloat involves the following steps:
    +
    +1. Port SoftFloat and create a SoftFloat binary.  (Refer to the
    +   documentation accompanying SoftFloat.)
    +
    +2. If one does not already exist, create an appropriate target-specific
    +   subdirectory under `testfloat' by copying the given `templates'
    +   directory.  The remaining steps occur within the target-specific
    +   subdirectory.
    +
    +3. Edit the files `milieu.h' and `Makefile' to reflect the current
    +   environment.
    +
    +4. Make `testsoftfloat' by executing `make testsoftfloat' (or `make
    +   testsoftfloat.exe', or whatever the `testsoftfloat' executable is
    +   called).  Verify that SoftFloat is working correctly by testing it with
    +   `testsoftfloat'.
    +
    +If you only wanted `testsoftfloat', you are done.  The steps for `testfloat'
    +continue:
    +
    +5. In the target-specific subdirectory, implement the `systmodes' and
    +   `systflags' modules.  (The `syst_float_set_rounding_precision' function
    +   need not do anything if the system does not support extended double
    +   precision.)
    +
    +6. If the target machine supports standard floating-point functions that are
    +   not accessible within ISO/ANSI C, or if the C compiler cannot be trusted
    +   to use the machine's floating-point directly, create a target-specific
    +   `systfloat' module.
    +
    +7. In the target-specific subdirectory, execute `make'.
    +
    +
    +-------------------------------------------------------------------------------
    +Improving the Random Number Generator
    +
    +If you are serious about using TestFloat for testing floating-point, you
    +should consider replacing the supplied `random.c' with a better target-
    +specific one.  The standard C `rand' function is rather poor on some
    +systems, and consequently `random.c' has been written to assume very little
    +about the quality of `rand'.  As a result, the `rand' function is called
    +more frequently than it might need to be, shortening the time before
    +the random number generator repeats, and possibly wasting time as well.
    +If `rand' is better on your system, or if another better random number
    +generator is available (such as `rand48' on most Unix systems), TestFloat
    +can be improved by overriding the given `random.c' with a target-specific
    +one.
    +
    +
    +-------------------------------------------------------------------------------
    +Contact Information
    +
    +At the time of this writing, the most up-to-date information about
    +TestFloat and the latest release can be found at the Web page `http://
    +HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +
    diff --git a/tools/test/testfloat/testfloat.c b/tools/test/testfloat/testfloat.c
    new file mode 100644
    index 00000000000..5a19d8811b6
    --- /dev/null
    +++ b/tools/test/testfloat/testfloat.c
    @@ -0,0 +1,299 @@
    +
    +/*
    +===============================================================================
    +
    +This C source file is part of TestFloat, Release 2a, a package of programs
    +for testing the correctness of floating-point arithmetic complying to the
    +IEC/IEEE Standard for Floating-Point.
    +
    +Written by John R. Hauser.  More information is available through the Web
    +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
    +
    +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
    +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
    +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
    +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
    +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
    +
    +Derivative works are acceptable, even for commercial purposes, so long as
    +(1) they include prominent notice that the work is derivative, and (2) they
    +include prominent notice akin to these four paragraphs for those parts of
    +this code that are retained.
    +
    +===============================================================================
    +*/
    +
    +#include 
    +__FBSDID("$FreeBSD$");
    +
    +#include 
    +#include 
    +#include 
    +#include "milieu.h"
    +#include "fail.h"
    +#include "softfloat.h"
    +#include "testCases.h"
    +#include "testLoops.h"
    +#include "systflags.h"
    +#include "testFunction.h"
    +
    +static void catchSIGINT( int signalCode )
    +{
    +
    +    if ( stop ) exit( EXIT_FAILURE );
    +    stop = TRUE;
    +
    +}
    +
    +int
    +main( int argc, char **argv )
    +{
    +    char *argPtr;
    +    flag functionArgument;
    +    uint8 functionCode;
    +    int8 operands, roundingPrecision, roundingMode;
    +
    +    fail_programName = "testfloat";
    +    if ( argc <= 1 ) goto writeHelpMessage;
    +    testCases_setLevel( 1 );
    +    trueName = "soft";
    +    testName = "syst";
    +    errorStop = FALSE;
    +    forever = FALSE;
    +    maxErrorCount = 20;
    +    trueFlagsPtr = &float_exception_flags;
    +    testFlagsFunctionPtr = syst_float_flags_clear;
    +    tininessModeName = 0;
    +    functionArgument = FALSE;
    +    functionCode = 0;
    +    operands = 0;
    +    roundingPrecision = 0;
    +    roundingMode = 0;
    +    --argc;
    +    ++argv;
    +    while ( argc && ( argPtr = argv[ 0 ] ) ) {
    +        if ( argPtr[ 0 ] == '-' ) ++argPtr;
    +        if ( strcmp( argPtr, "help" ) == 0 ) {
    + writeHelpMessage:
    +            fputs(
    +"testfloat [
    - - Advisory - Date - Topic - - - - - - SA-08:05.openssh - 17 April 2008 - OpenSSH X11-forwarding privilege escalation - - - - SA-08:06.bind - 13 July 2008 - DNS cache poisoning - - - - SA-08:07.amd64 - 3 September 2008 - amd64 swapgs local privilege escalation - - - - SA-08:08.nmount - 3 September 2008 - &man.nmount.2; local arbitrary code execution - - - - SA-08:09.icmp6 - 3 September 2008 - Remote kernel panics on IPv6 connections - - - - SA-08:10.nd6 - 1 October 2008 - IPv6 Neighbor Discovery Protocol routing vulnerability - - - - SA-08:11.arc4random - 24 November 2008 - &man.arc4random.9; predictable sequence vulnerability - - - - SA-08:12.ftpd - 23 December 2008 - Cross-site request forgery in &man.ftpd.8; - - - - SA-08:13.protosw - 23 December 2008 - netgraph / bluetooth privilege escalation - - - - SA-09:01.lukemftpd - 07 January 2009 - Cross-site request forgery in - &man.lukemftpd.8; - - - - SA-09:02.openssl - 07 January 2009 - OpenSSL incorrectly checks for malformed - signatures - - - - SA-09:03.ntpd - 13 January 2009 - ntpd cryptographic signature - bypass - - - - SA-09:04.bind - 13 January 2009 - BIND DNSSEC incorrect checks for - malformed signatures - - - - SA-09:05.telnetd - 16 February 2009 - telnetd code execution - vulnerability - - - - SA-09:06.ktimer - 23 March 2009 - Local privilege escalation - - - - SA-09:07.libc - 04 April 2009 - Information leak in &man.db.3; - - - - SA-09:08.openssl - 22 April 2009 - Remotely exploitable crash in - OpenSSL - - - - SA-09:09.pipe - 10 June 2009 - Local information disclosure via direct pipe writes - - - - SA-09:10.ipv6 - 10 June 2009 - Missing permission check on SIOCSIFINFO_IN6 ioctl - - - - SA-09:11.ntpd - 10 June 2009 - ntpd stack-based buffer-overflow vulnerability - - - - SA-09:12.bind - 29 July 2009 - BIND &man.named.8; dynamic update message remote DoS - - - SA-09:14.devfs - 2 Oct 2009 - Devfs / VFS NULL pointer race condition - - - - - - - - Kernel Changes - - The &os; GENERIC kernel now - includes Trusted BSD MAC (Mandatory Access Control) support. - No MAC policy module is loaded by default. - - A loader - tunable hw.clflush_disable has been added - to avoid panic (trap 9) - at map_invalidate_cache_range() even if - Intel CPU is used. This tunable can be set - to -1 (default), 0 and - 1. The -1 is same as - the current behavior, which automatically - disables CLFLUSH on Intel CPUs without - CPUID_SS (this should occurr on Xen - only). You can specify 1 when this panic - happens on non-Intel CPUs (such as AMD's). Because disabling - CLFLUSH can reduce performance, you can try - with setting 0 on Intel CPUs - without SS to - use CLFLUSH feature. - - The &man.jail.8; subsystem has been updated. Changes include: - - - - A new virtualization container - named vimage has been implemented. This is - not enabled by default. To enable this, add the following - kernel options to your kernel configuration file and - rebuild the kernel: - - options VIMAGE - - Note that options SCTP in the - GENERIC kernel is not compatible with - options VIMAGE. This limitation will - be fixed in the next release. - - The vimage is a jail with a virtualized instance of - the &os; network stack. It can be created by using - &man.jail.8; command like this: - - &prompt.root; jail -c vnet name=vnet1 host.hostname=vnet1.example.net path=/ persist - - The vimage has own loopback interface and a separated - network stack including the L3 routing tables. Network - interfaces on the system can be moved by using - &man.ifconfig.8; option between the - different vimage jails and outside of them. - - Furthermore, the &man.epair.4; pseudo-interface driver - has been added to help communication between vimage jails. - It emulates a pair of back-to-back connected Ethernet - interfaces. For example, the following commands create an - interface pair of &man.epair.4;: - - &prompt.root; ifconfig epair0 create -epair0a -&prompt.root; ifconfig epair0a -epair0a: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 - ether 02:c0:64:00:07:0a -&prompt.root; ifconfig epair0b -epair0b: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 - ether 02:c0:64:00:08:0b - - The &man.epair.4; pseudo-interfaces and any physical - interfaces on the system can be moved between vimage jails - by using &man.ifconfig.8; option as - described above. Even after half of an &man.epair.4; pair - is moved, the back-to-back connection still valid and can - be used for inter-jail communication. - - Note that vimage is still considered as an - experimental feature. - - - - A jail can now have arbitrary named parameters similar - to environmental variables and the fixed jail parameters - in the previous releases have been replaced with them. - The jail name can now be used for identifying the jail in - &man.jexec.8; and &man.killall.1;. - - - - Multiple IPv4 and/or IPv6 addresses per jail are now - supported. It is even possible to have jails without - an IP address at all, which basically gives one a chrooted - environment with restricted process view and no - networking. - - - - SCTP (&man.sctp.4;) with IPv6 in jails has been - implemented. - - - - Specific CPU binding by using &man.cpuset.1; has been - implemented. Note that the current implementation allows - the superuser inside of the jail to change the CPU - bindings specified. - - - - A &man.jail.8; can start with a specific route - FIB now. - - - - The &man.ddb.8; kernel debugger now supports a - show jails subcommand. - - - - Compatibility support which permits 32-bit jail - binaries to be used on 64-bit systems to manage jails has - been added. - - - - Note that both version numbers of - jail and prison in - the &man.jail.8; have been updated for the new - features. - - - - The &man.ksyms.4;, kernel symbol table - interface driver has been added. It creates a character - device /dev/ksyms and provides - read-only access to a snapshot of the kernel symbol - table. - - The &os; Linux emulation - layer has been updated to version 2.6.16 and the default Linux - infrastructure port is - emulators/linux_base-f10 (Fedora - 10). - - The &os;/&arch.arm; now - supports mini dump. - - The &os;/&arch.powerpc; now - supports kernel core dump. - - The &os; virtual memory - subsystem now supports fully transparent use of - superpages for application memory; - application memory pages are dynamically promoted to or - demoted from superpages without any modification to - application code. This change offers the benefit of large - page sizes such as improved virtual memory efficiency and - reduced TLB (translation lookaside buffer) misses without - downsides like application changes and virtual memory - inflexibility. This can be enabled by setting a loader tunable - vm.pmap.pg_ps_enabled to - 1 and is enabled by default on - &arch.amd64;. - - The &man.ddb.8; kernel debugger now supports a - show mount subcommand. - - The &os; DTrace subsystem now supports a probe for - process execution. - - The &os; kernel virtual address - space has been increased to 6GB. This allows subsystems to use - larger virtual memory space than before. For example, the - &man.zfs.8; adaptive replacement cache (ARC) requires large - kernel memory space to cache file system data, so it benefits - from the increased address space. Note that the ceiling on - the kernel map size is now 60% of the size of physical memory - rather than an absolute quantity. - - The &man.kld.4; now supports installing 32-bit - system calls to the &os; syscall translation layer from kernel - modules. - - The &man.ktr.4; now supports a new KTR tracepoint in the - KTR_CALLOUT class to note when a callout - routine finishes executing. - - Types of variables used to track the amount of allocated - System V shared memory have been changed from - int to size_t. This - makes it possible to use more than 2 GB of memory for shared - memory segments on 64-bit architectures. Please note the new - BUGS section in &man.shmctl.2; and - /usr/src/UPDATING for limitations of this - temporary solution. - - The &man.sysctl.3; leaf nodes have a flag to tag - themselves as MPSAFE now. - - The &os; 32-bit system call translation layer now - supports installing 32-bit system calls for - VFS_AIO. - - The &man.clock.gettime.2; and the related system calls now - support a clock ID CLOCK_THREAD_CPUTIME_ID, - as defined in POSIX. - - The &man.cpuset.2; system call has been added. This is an - API for thread to CPU binding and CPU resource grouping and - assignment. - - The DTrace, a comprehensive dynamic tracing framework and - &man.dtrace.1; userland utility have been imported from - OpenSolaris. DTrace provides a powerful infrastructure to - permit administrators, developers, and service personnel to - concisely answer arbitrary questions about the behavior of the - operating system and user programs. - - The &man.ddb.4; kernel debugger now has an output capture - facility. Input and output from &man.ddb.4; can now be captured - to a memory buffer for later inspection using &man.sysctl.8; or - a textdump. The new capture command controls - this feature. - - The &man.ddb.4; debugger now supports a simple scripting - facility, which supports a set of named scripts consisting of a - set of &man.ddb.4; commands. These commands can be managed from - within &man.ddb.4; or with the use of the new &man.ddb.8; - utility. More details can be found in the &man.ddb.4; manual - page. - - The &man.ddb.4; ex command now supports - an mode which interprets and prints the - value at the requested address as a symbol. For example, - ex /S aio_swake - prints the name of the function currently registered in - via aio_swake hook. - - The &man.ddb.4; show conifhk command has - been added. This lists hooks currently waiting for completion - in run_interrupt_driven_config_hooks(). - - The &man.fcntl.2; system call now supports - F_DUP2FD command. This is equivalent to - &man.dup.2;, and compatible with the Sun Solaris and the IBM - AIX. - - The &os;'s &man.linux.4; ABI support now implements - sched_setaffinity() and - sched_getaffinity() using real CPU affinity - setting primitives. - - The &man.procstat.1; utility has been added. This is a - process inspection utility which provides some of the missing - functionality from &man.procfs.5; and new functionality for monitoring - and debugging specific processes. - - The client side functionality of &man.rpc.lockd.8; has been - implemented in the &os; kernel. This implementation provides the - correct semantics for &man.flock.2; style locks which are used - by the &man.lockf.1; command line tool and the &man.pidfile.3; - library. It also implements recovery from server restarts and - ensures that dirty cache blocks are written to the server before - obtaining locks (allowing multiple clients to use file locking - to safely share data). Also, a new kernel option - options NFSLOCKD has been added and enabled - by default. If the kernel support is enabled, &man.rpc.lockd.8; - automatically detects and uses the functionality. - - The &os; kernel now supports a new textdump format of kernel - dumps. A textdump provides higher-level information via - mechanically generated/extracted debugging output, rather than a - simple memory dump. This facility can be used to generate brief - kernel bug reports that are rich in debugging information, but - are not dependent on kernel symbol tables or precisely - synchronized source code. More information can be found in the - &man.textdump.4; manual page. - - The &man.wait4.2; system call now supports - flag to keep the process whose status - is returned in a waitable state and - which is equivalent to . - - The &os; kernel now has - initial support of binding interrupts to CPUs. - - The &man.sched.ule.4; scheduler is now the default - process scheduler in GENERIC - kernels. - - The sysctl - variables kern.features.compat_freebsd[456] - have been added. These are corresponding to the kernel options - COMPAT_FREEBSD[456]. - - - Boot Loader Changes - - The boot0 boot - loader now preserves volume ID at offset - 0x1b8 used in other operating systems - - The &man.boot0cfg.8; utility now supports a - new option to set the volume ID. - - The &man.loader.8; now - supports U-Boot support library. - - The &man.boot.8; now supports 4-byte volume ID that - certain versions of &windows; put into the MBR and invoking - PXE by pressing the F6 key on some supported BIOSes. - - The &man.boot.8; BTX loader has been - improved. This fixes several boot issues on recent machines - reported for 7.1-RELEASE and before. - - The &man.loader.8; is now able to obtain DHCP options - from network boot via &man.kenv.2; variables. - - A bug in the &man.loader.8; has been fixed. Now the - following line works as expected: - - loader_conf_files="foo bar ${variable}" - - The BTX kernel used by the boot - loader has been changed to invoke BIOS routines from real - mode. This change makes it possible to boot &os; from USB - devices. - - A new gptboot boot loader has - been added to support booting from a GPT labeled disk. A - new boot command has been added to - &man.gpt.8;, which makes a GPT disk bootable by writing the - required bits of the boot loader, creating a new boot - partition if required. - - - - Hardware Support - - The &os; now includes experimental support - for &arch.mips; platform. - - Support for RTC on Dallas Semiconductor chips - has been improved. The DS133x and DS1553 are now - supported. - - The &os;/&arch.arm; now supports - Feroceon and Sheeva embedded CPU, Marvell Orion (88F5281), - Kirkwood (88F6281), Discovery Innovation (MV-78100) - systems-on-chip CPU. - - The &os;/&arch.powerpc; now - supports SMP machines - - The &os;/&arch.powerpc; now - supports E500 (Book-E) embedded CPU and Freescale - PowerQUICCIII MPC85xx system-on-chip (including single and - dual-core). - - The &man.acpi.4; subsystem now supports the System - Resource Affinity Table (SRAT) used to describe affinity - relationships between CPUs and memory, ACPI 3.0 fields in - the MADT including X2APIC entries and UIDs for local SAPICs, and - ACPI 3.0 flags in the FADT. - - The &man.cpufreq.4; framework now - supports PowerPC G5, along with a skeleton SMU driver in order to slew - CPU voltage during frequency changes. - - The sec(4) driver has been added to provide - support for the integrated security engine found in - Freescale system-on-chip devices. - - The &os; TTY layer has been replaced with a - new one which has better support for SMP and robust resource - handling. A tty now has own mutex and it is expected to - improve scalability when compared to the old implementation - based on the Giant lock. - - The &man.uart.4; driver is now the - default driver for serial port devices in favor of the - &man.sio.4; driver. Note that the device nodes have been - renamed from - /dev/cuadN and - /dev/ttydN to - /dev/cuauN and - /dev/ttyuN. - - - Users who are upgrading will need to change their - kernel configurations and possibly also - /boot/loader.conf and - /boot/device.hints. - - - The &os; USB subsystem has been reimplemented - to support modern devices and better SMP scalability. The - new implementation includes Giant-lock-free device drivers, - a Linux compatibility layer, &man.usbconfig.8; utility, full - support for split transaction and isochronous transaction, - and more. Device node names for USB devices are now in a - the form - of /dev/usb/bus.dev.endpoint, - and /dev/usbctl is the master device - node. Note that the &man.ugen.4; driver has nodes for each device as /dev/ugenbus.dev for backward compatibility. - - &os; now supports Ultra SPARC III - (Cheetah) processor family. - - The &man.acpi.4; subsystem now supports a &man.sysctl.8; - variable debug.batt.batt_sleep_ms. On - some laptops with smart batteries, enabling battery - monitoring software causes keystrokes from &man.atkbd.4; to - be lost. This sysctl variable adds a delay in millisecond - to the status checking code as a workaround. - - The &man.acpi.asus.4; driver now supports Asus A8Sr - notebooks. - - Support for the AltiVec, a floating point - and integer SIMD instruction set has been added. - - The &man.cpuctl.4; driver, which provides a special - device /dev/cpuctl as an interface to - the system CPU has been added. The &man.cpuctl.4; - functionality includes the ability to retrieve CPUID - information, read/write machine specific registers (MSR), - and perform CPU firmware updates. - - The &man.cpufreq.4; driver now supports an - hw.est.msr_info loader tunable. When - this is set to 1, it attempts to build a - simple list containing just the high and low frequencies if - it cannot obtain a frequency list from either ACPI or the - static tables. This is disabled by default. - - CPU frequency change notifiers are now - disabled when the TSC is P-state invariant. Also, a new - loader tunable - kern.timecounter.invariant_tsc has been - added to force this behavior by setting it to - non-zero. - - The &man.atkbd.4; driver now disables the interrupt - handler which is called from the keyboard callback function - when polled mode is enabled. This fixes the problem of - duplicated/missing characters at the mountroot prompt on - multi CPU systems while &man.kbdmux.4; is enabled. - - In the &man.pci.4; subsystem INTx is now disabled when - MSI/MSIX is enabled. This change fixes interrupt storm - related issues. - - The schizo(4) driver for Schizo - Fireplane/Safari to PCI 2.1 and Tomatillo JBus to PCI 2.2 - bridges has been added. - - The &man.u3g.4; driver for USB based 3G cards and - dongles including Vodafone Mobile Connect Card 3G, Qualcomm - CDMA MSM, Huawei E220, Novatel U740, Sierra MC875U, and more - has been added. This provides support for the multiple - USB-to-serial interfaces exposed by many 3G USB/PC Card - modems, and the device is accessed through the &man.ucom.4; - driver which makes it behave like a &man.tty.4;. - - The &man.sched.ule.4; scheduler now supports - the loader tunable - machdep.hyperthreading_enabled just like - &man.sched.4bsd.4;. Note that it cannot be modified at - run-time. - - The &man.cmx.4; driver, a driver for Omnikey CardMan 4040 - PCMCIA smartcard readers, has been added. - - The &man.kbdmux.4; driver now - supports &arch.sparc64;. The &man.sunkbd.4; driver now - supports &man.atkbd.4; emulation like &man.ukbd.4;. - - The nvram(4) driver is now - MPSAFE. - - An option of the &man.puc.4; - driver, PUC_FASTINTR, is no longer - supported. - - The &man.psm.4; driver now attempts detection of Synaptics - touchpad before IntelliMouse. Some touchpads will pretend to - be IntelliMouse causing the IntelliMouse probe to work and the - Synaptics detection never to be done. - - The &man.uslcom.4; driver, a driver for Silicon - Laboratories CP2101/CP2102-based USB serial adapters, has been - imported from OpenBSD. - - - Multimedia Support - - The &os; audio subsystem has been improved. - The changes include volume per channel, high quality - fixed-point band-limited SINC sampling rate converter, - bit-perfect mode, transparent/adaptive virtual channel, - and exclusive stream. For more details, see the - &man.snd.4; manual page. - - The &man.agp.4; driver now supports Intel G4X series - graphics chipsets. - - The Direct Rendering Manager - (DRM), a kernel module that - gives direct hardware access to DRI clients, has been - updated. Support for AMD/ATI r500, r600, r700, and IGP - based chips, XGI V3XE/V5/V8, and Intel i915 chipsets has - been improved. - - A new loader tunable hw.drm.msi has - been added to control if DRM uses MSI or not. This is set - to 1 (enabled) by default. - - The snd_au88x0(4) driver for Aureal Vortex - 1/2/Advantage PCI has been removed because it has been - broken for a long time. - - The &man.snd.hda.4; driver has been updated. These - changes include support for multiple codecs per HDA bus, - multiple functional groups per codec, multiple audio - devices per functional group, digital (SPDIF/HDMI) audio - input/output, suspend/resume, and part of multichannel - audio. - - Note that due to added HDMI audio and - logical audio devices support, the updated driver often - provides several PCM devices. This means that in some - cases the system default audio device no longer - corresponds to the users's habitual audio connectors. In - such cases the default device can be specified in audio - applications' setup or defined globally via - hw.snd.default_unit sysctl variable, as - described in the &man.sound.4; manual page. - - The &man.agp.4; driver now supports the - Intel G33 and G45. - - The dpms(4) driver has - been added to use the VESA BIOS for DPMS during suspend and - resume. - - The DRM kernel driver now - supports i915 GME devices. - - - - Network Interface Support - - The &man.bwi.4; driver has been added to - provide support for Broadcom BCM43xx IEEE 802.11b/g wireless - network interfaces. - - The &man.cas.4; driver has - been added to provide support for Sun Cassini/Cassini+ and - National Semiconductor DP83065 Saturn Gigabit Ethernet - devices. - - The &man.cxgbtool.8; now supports an - interactive mode for scripting of repeatedly performed - tasks. - - The &man.fxp.4; driver has been improved. Changes include: - - - - The multicast filter re-programming - is now more robust. - - - - The checksum offload feature can be controlled by - &man.ifconfig.8; now. - - - - Rx checksum offload support for 82559 or later - controllers has been added. - - - - TSO (TCP Segmentation Offload) support for 82550 - and 82551 controllers has been added. - - - - WoL (Wake on LAN) support for 82550, 82551, 82558, - and 82559-based controllers has been added. Note that - ICH based controllers are treated as 82559, and 82557, - earlier revisions of 82558, and 82559ER have no WoL - capability. - - - - VLAN hardware tag insertion/stripping support and - Tx/Rx checksum offload for VLAN frames support has - been added. Note that the VLAN hardware assistance is - available only on 82550 or 82551-based - controllers. - - - - The mge(4) driver has - been added to provide support for Marvell Gigabit Ethernet - controllers found on ARM-based SOCs (Orion, Kirkwood, - Discovery), as well as on system controllers for PowerPC - processors (MV64430, MV6446x). - - The &man.miibus.4; driver now supports - the Marvell 88E3016. - - The &man.msk.4; driver now supports Yukon - FE+ A0 including 88E8040, 88E8040T, 88E8048 and - 88E8070. - - The &man.mwl.4; driver has been added to - provide support for Marvell 88W8363 IEEE 802.11n wireless - network devices. - - The &man.mxge.4; driver now supports some newer - revisions and 10GBASE-LRM and 10GBASE-Twinax media - types. The firmware version has been updated to 1.4.43. - - The &man.nge.4; driver has been improved and - now works on all platforms. - - The tsec(4) driver has been added to - provide support for Freescale integrated Three-Speed - Ethernet Controller (TSEC). This driver also works with - the enhanced version of the controller (eTSEC). - - The &man.uath.4; driver for USB wireless LAN - adapter based on Atheros AR5005UG and AR5005UX chipsets - has been added. The &man.uathload.8; utility, a firmware - loader for the Atheros USB wireless driver has also been - added. - - The &man.urtw.4; driver has been added to - provide support for Realtek RTL8187B/L USB IEEE 802.11b/g - wireless network devices. - - The &man.xl.4; driver now supports TX - checksum offload. - - The &man.ae.4; driver now supports WoL - (Wake on LAN). - - The &man.ale.4; driver is now - included in the GENERIC - kernel. - - The &man.ath.hal.4;, Atheros Hardware Access Layer, - has been updated to the open source version. - - The &man.axe.4; driver has been improved in - performance by eliminating extra context switches and now - supports the Apple USB Ethernet adapter. - - The &man.bce.4; driver's firmware has been updated to - the latest version (4.6.X). - - The ciphy(4) driver now supports Vitesse VSC8211 - PHY. - - The &man.cxgb.4; driver has been updated to firmware - revision 4.7 and now supports hardware MAC - statistics. - - A bug in the &man.igb.4; driver, which prevented the - loader tunable hw.igb.ave_latency from - working, has been fixed. - - The &man.ixgbe.4; driver has been updated to - version 1.7.4. - - The &man.jme.4; driver now supports newer JMicron - JMC250/JMC260 revisions. - - The &man.msk.4; driver has been improved. An issue - which made it hang up in a certain condition has been - fixed. Hardware MAC statistics support has been added - and users can get the information via sysctl variables - named - dev.msk.N.stats. - - The &man.nfe.4; driver now supports hardware MAC - statistics. - - The &man.re.4; driver has been improved. It now - detects the link status. A new loader tunable - hw.re.prefer_iomap has been added, to - disable memory register mapping. This tunable is - 0 for all controllers except RTL8169SC - family. - - The &man.rl.4; driver has been improved. It now - detects the link status and a bug which prevented it from - working on systems with more than 4GB memory has been - fixed. - - A bug in &man.sis.4; on VLAN tagged frame handling has - been fixed. - - The &man.txp.4; driver now works on all supported - architectures. Support has been added for &man.altq.4;, - WoL, checksum offload when VLAN enabled, and link state - change handling has been improved, and new sysctl - variables - dev.txp.N.stats - for MAC statistics have been added. New sysctl variables - dev.txp.N.process_limit - has been added, to control how many received frames should - be served in Rx handler (set to 64 by default and valid - ranges are 16 to 128 in unit of frames). The firmware has - been updated to the latest version. - - The &man.ae.4; driver has been added to provide - support for the Attansic/Atheros L2 FastEthernet - controllers. - - The &man.jme.4; driver has been added to - provide support for PCIe adapters based on JMicron JMC250 - gigabit Ethernet and JMC260 fast Ethernet controllers. - - The &man.age.4; driver has been added to - provide support for Attansic/Atheros L1 gigabit Ethernet - controller. - - The &man.malo.4; driver has been added to - provide support for Marvell Libertas 88W8335 based PCI network - adapters. - - The bm(4) driver has been added to - provide support for Apple Big Mac (BMAC) Ethernet controller, - found on various Apple G3 models. - - The et(4) driver has been added to - provide support for Agere ET1310 10/100/Gigabit Ethernet - controller. - - The &man.glxsb.4; driver has been added - to provide support for the Security Block in AMD Geode LX - processors. - - The &man.ale.4; driver has been added to provide support - for Atheros AR8121/AR8113/AR8114 Gigabit/Fast Ethernet controllers. - This driver is not enabled in GENERIC - kernels for this release. - - The &man.em.4; driver has been split into two drivers - with some common parts. The &man.em.4; driver will continue - to support adapters up to the 82575, as well as new - client/desktop adapters. A new &man.igb.4; driver - will support new server adapters. - - The &man.hme.4; driver has been improved. - - A bug in some of the &man.miibus.4; supported drivers that - IEEE 802.3 auto-negotiation was performed in a wrong order, - has been fixed. Now it chooses the correct technologies - supported by IEEE 802.3 in the order described in Annex - 28B.3. - - A workaround has been added for a bug in TCP/UDP - hardware checksum offload of the &man.msk.4; driver for - short frames. Note that for frames that requires hardware - VLAN tag insertion, the checksum offload workaround does not - work due to changes of checksum offset in mbuf after the - VLAN tag. So disabling hardware checksum offload for the - VLAN interface is needed in such cases. - - The &man.ndis.4; NDIS miniport driver wrapper has been - improved. - - The &man.sf.4; driver has been improved and now supports - checksum offloading. - - The &man.stge.4; driver now supports WOL (Wake on - LAN). - - The &man.vr.4; driver has been improved. - - The &man.wpi.4; driver has - been updated to include a number of stability fixes. - - - - - Network Protocols - - The &os; netisr framework has been - reimplemented for parallel threading support. This is a - kernel network dispatch interface which allows device - drivers (and other packet sources) to direct packets to - protocols for directly dispatched or deferred processing. - The new implementation supports up to one netisr thread per - CPU, and several benchmarks on SMP machines show substantial - performance improvement over the previous version. - - A bug in the &man.gif.4; that EtherIP packets - sent by combination of &man.if.bridge.4; and &man.gif.4; - have a reversed version field has been fixed. If you need - to communicate with older &os; releases via EtherIP, use new - flags accept_rev_ethip_ver - and send_rev_ethip_ver to control - handling the reversed version field. These can be set by - &man.ifconfig.8 utility to &man.gif.4; interfaces. The - EtherIP implementation found on &os; 6.1, 6.2, 6.3, 7.0, - 7.1, and 7.2 had an interoperability issue because it sent - the incorrect EtherIP packets and discarded the correct - ones. For more details, see &man.gif.4; manual page. - - The IGMPv3 and SSM (Source-Specific Multicast) - including IPv6 SSM and MLDv2 have been added. Although the - old KAME MLDv2 hooks have been replaced with the new - implementation, the related kernel programming interfaces have been - preserved. - - The multicast routing code has been improved - and the IPv4 and IPv6 support has been split. - - The &os; now supports the upcoming Wireless - Mesh standard, IEEE 802.11s. The current implementation is - based on the March 2009 D3.0 draft version. - - The wireless network support layer (net80211) - now uses pseudo-interfaces named as - wlanN instead - of a device driver name like em0 - directly. The - wlanN - interface is created by &man.ifconfig.8; as an instance of - the parent interface and used for actual communication - similar to &man.vlan.4, IEEE 802.1Q VLAN network interface. - Note that multiple instances (to realize multiple BSSes with - a single AP device, for example) can be created if the - parent interface supports it. For more details, see - &man.ifconfig.8; manual page. - - The net80211 layer now supports TDMA for long - distance point-to-point links using &man.ath.4; - devices. - - An infrastructure for caching flows as a means - of accelerating L2 and L3 lookups has been added. This is - called flow table and enabled by default on - &arch.amd64 and &arch.i386; platforms. This also provides - stateful load balancing when used - with RADIX_MPATH - - The &os; L2 address translation table has been - reimplemented to reduce lock contention on parallel - processing and simplify the routing logic. The new - implementation has L2 address translation tables for both - ARP (for IPv4) and NDP (for IPv6) which are separated from - the L3 routing tables, and supports flow table caches for both - the routing table and the L2 information. One of the - user-visible changes is that a concept of cloned route (a - route generated by an entry - with RTF_CLONING flag) is deprecated. - This means routing flags RTF_CLONING, - RTF_WASCLONE, - and RTF_LLINFO are obsolete. - - The &man.ipsec.4; subsystem now supports - NAT-Traversal (RFC 3948). This is disabled by default. To - enable this add the following kernel option and rebuild the - kernel: - - device crypto -options IPSEC -options IPSEC_NAT_T - - IPv4 source address selection for unbound sockets has - been implemented as follows: - - - - If we found a route, use the address corresponding - to the outgoing interface. - - - - Otherwise we assume the foreign address is reachable - on a directly connected network and try to find a - corresponding interface to take the source address - from. - - - - As a last resort use the default jail address. - - - - This also changes the semantics of selecting the IP for - processes within a &man.jail.8; as it now uses the same - logic as outside the &man.jail.8;. - - The TCP MD5 Signature Option (RFC 2385) for IPv6 has - been implemented in the same way it has been implemented for - IPv4. - - The &man.ng.netflow.4; Netgraph node now includes - support for generating egress netflow instead or in addition - to ingress. An NGM_NETFLOW_SETCONFIG - control message has been added to control the new - functionality. - - The &man.tap.4; Ethernet tunnel software network - interface now supports a new TAPGIFNAME - character device ioctl. This is a convenient shortcut to - obtain the network interface name using a file descriptor to - a character device. - - The &man.tap.4; now supports - SIOCSIFMTU ioctl to set a higher MTU than - 1500 (ETHERMTU). This allows &man.tap.4; devices to be - added to the same bridge (which requires all interface - members to have the same MTU) with an interface configured - for jumbo frames. - - The domains list for handling the list of supported - domains in the &man.unix.4; (UNIX domain protocol family) - subsystem is now MPSAFE. - - The &man.arp.8; utility now - supports reject - and blackhole keywords. In the entry - marked as reject, traffic to the host will - be discarded and the sender will be notified the host is - unreachable. In the entry marked as blackhole, - traffic is discarded but the sender is not notified. - - The &man.bpf.4; now supports an - ioctl BIOCSETFNR. This is just like - BIOCSETF, but it does not drop all the - packets buffered on the descriptor and reset the - statistics. - - The &man.if.bridge.4; interface can limit the - number of source MACs that can be behind a bridge interface - via ifmaxaddr parameter of - &man.ifconfig.8;. - - A bug in the &man.carp.4; interface configuration which - leads to a system panic has been fixed. - - The &man.dummynet.4; subsystem now supports - fast mode operation which allows certain - packets to bypass the dummynet scheduler. This can achieve - lower latency and lower overhead when the packet flow is under - the pipe bandwidth, and eliminate recursion in the subsystem. - The new sysctl variable - net.inet.ip.dummynet.io_fast has been - added to enable this feature. - - The &man.enc.4; interface now supports sysctl - variables to control whether the firewalls or &man.bpf.4; - will see inner and outer headers or just inner or outer - headers for incoming and outgoing IPsec packets. - - The &man.gre.4; now supports - ioctls GRESKEY - and GREGKEY which allows set or get GRE - key used for outgoing packets. - - A bug in the &man.ipsec.4; subsystem that PMTU was broken - in those cases when there was a route with a lower MTU than - the MTU of the outgoing interface, has been fixed. - - The netatm subsystem has been removed due to - lacking multiprocessor support. - - The &man.ng.nat.4; now supports redirect functionality - in libalias. For more details, see the - manual page. - - The &man.ng.pptpgre.4; now supports multiple hooks like - &man.ng.l2tp.4;, to use one pair of pptpgre and ksocket nodes for all - calls between two peers. - - The &man.resolver.3; now allows underscore in domain - names. Although this is a violation of RFC 1034 [STD 13], it is - accepted by certain name servers as well as other popular operating - systems' resolver library. - - A socket option TCP_CONGESTION for TCP - sockets has been added. This is for setting and retrieving the - congestion control algorithm. The name used is to allow - compatibility with Linux. - - The &man.rwlock.9; has been used throughout - the inpcbinfo and inpcb - infrastructure, and protocols that depend on that - infrastructure, including UDP, TCP, and IP raw sockets to - reduce the lock contentions. - - The &os; now supports multiple routing tables. To - enable this, the following steps are needed: - - - - Add the following kernel configuration option and - rebuild the kernel. The 2 is the number - of FIB (Forward Information Base, synonym for a routing - table here). The maximum value is 16. - - options ROUTETABLES=2 - - The procedure for rebuilding the &os; kernel is - described in the &os; - Handbook. - - This number can be modified on boot time. To do so, add - the following to /boot/loader.conf and - reboot the system: - - net.fibs=6 - - - - Set a loader tunable net.my_fibnum if - needed. This means the default number of routing tables. - If not specified, 0 will be used. - - - - Set a loader tunable - net.add_addr_allfibs if needed. This - enables to add routes to all FIBs for new interfaces by - default. When this is set to 0, it will - only allocate routes on interface changes for the FIB of the - caller when adding a new set of addresses to an interface. - Note that this tunable is set to 1 by - default. - - - - To select one of the FIBs, the new &man.setfib.1; utility - can be used. This set an associated FIB with the process. For - example: - - &prompt.root; setfib -3 ping target.example.com - - The FIB #3 will be used for the &man.ping.8; command. - - The FIB which the packet will be associated with will be - determined in the following rules: - - - - All packets which have a FIB associated with them will - use the FIB. If not, FIB #0 will be used. - - - - A packet received on an interface for forwarding uses - FIB #0. - - - - A TCP listen socket associated with an FIB will generate - accept sockets which are associated with the same FIB. - - - - A packet generated in response to other packet uses the - FIB associated with the packet being responded to. - - - - A packet generated on tunnel interfaces such as - &man.gif.4; and &man.tun.4; will be encapsulated using the - FIB of the process which set up the tunnel. - - - - Routing messages will be associated with the process's - FIB. - - - - Also, the &man.ipfw.8; now supports an action rule - setfib. The following action: - - setfib fibnum - - will make the matched packet use the FIB specified in - fibnum. The rule processing - continues at the next rule. - - - - Disks and Storage - - The &os; CAM SCSI subsystem (&man.cam.4;) now - includes experimental support for ATA/SATA/AHCI-compliant - devices. This is disabled by default. To enable this, - adding the following kernel options to your kernel - configuration file and rebuild the kernel: - - device ahci -device siis - - The current implementation supports - AHCI-compliant controllers and SiliconImage - SiI3124/SiI3132/SiI3531 controllers. The device node of an - ATA drive is ada and an ATAPI - drive is cd. - - The &os; iSCSI initiator implementation has - been improved and supports IPv6. - - A userland utility &man.mfiutil.8; for the - &man.mfi.4; devices has been added. This includes basic - features to monitor controller, array, and drive status, - change basic attributes, create/delete arrays and spares, - and flush the controller firmware. Note that this is a - small utility, not a replacement of MegaCLI in the Ports - Collection which is supported officially and provides more - functionality. - - A userland utility &man.mptutil.8; for the - &man.mpi.4; devices has been added. This includes basic - features to monitor controller, array, and drive status, - change basic attributes, and create/delete arrays and - spares. - - The &man.siis.4; driver has been added to - provide support for SiliconImage SiI3124/3132/3531 SATA2 - controllers. It supports Serial ATA and ATAPI devices, port - multipliers (including FIS-based switching), hardware - command queues (31 commands per port) and Native Command - Queuing. - - The &man.ata.4; driver now supports Marvell PATA M88SX6121. - - The &man.ata.4; driver now recognizes nForce MCP67 and - MCP73 SATA controllers as AHCI. - - The &man.ataraid.4; driver now includes preliminary support - for DDF metadata found on Adaptec HostRAID controllers. - Note that spares and rebuilds are not supported yet. - - The &man.cam.4; SCSI subsystem now supports a new sysctl - variable kern.cam.cd.retry_count. This - controls the number of retries for the CD media. When - trying to read scratched or damaged CDs and DVDs, the - default mechanism is sub-optimal, and programs like - ddrescue do much better if you - turn off the retries entirely since their algorithms do it - by themselves. This value is set to 4 - (for a total of 5 attempts) by default. Setting it to - 0 turns off all retry attempts. - - A bug in the &man.ciss.4; driver which caused low - max device openings count and led to poor - performance has been fixed. - - The &man.glabel.8; GEOM class now supports a new - UFS-based label called ufsid that can be - used to reference UFS-carrying devices by the unique file - system ID. This file system ID is automatically generated - and detected when the &man.glabel.8; GEOM class is enabled. An - example of this new label is: - /dev/ufsid/48e69c8b5c8e1b43. The - benefit of using GEOM labels in general is to avoid problems - of device renaming when shifting drives or - controllers. - - The &man.gjournal.8; GEOM class now supports the root - file system. Previously, an unclean shutdown would make it - impossible to mount the root file system at boot. - - The &man.gpart.8; utility has been updated. The APM - scheme now supports Tivo Series 1 partitions (read only), a - new EBR scheme to support Extended Boot Records has been - added, the BSD scheme now support bootcode, and bugs in the - PC98 and VTOC8 schemes have been fixed. - - An issue in &man.gvinum.8; with access permissions - to underlying disks used by a gvinum plex has been fixed. - If the plex is a raid5 plex and is being written to, parity data might - have to be read from the underlying disks, requiring them to be opened for - reading as well as writing. - - The &man.hptmv.4; driver has been updated to version - 1.16 from HighPoint. - - The &man.mmc.4; and &man.mmcsd.4; drivers now support MMC - and SDHC cards, high speed timing, wide bus, and multiblock - transfers. - - The &man.mpt.4; driver is now in the - GENERIC kernel. - - The &man.sdhci.4; driver has been added. This supports - PCI devices with class 8 and subclass 5 according to the SD - Host Controller Specification. - - The &man.sdhci.4; driver now supports kernel dumping and - a sysctl variable hw.sdhci.debug for debug - level. - - The &man.twa.4; driver now supports 64-bit DMA. - - The &man.mmc.4; &man.mmcsd.4;, and &man.sdhci.4; driver - are now included as kernel modules. - - The &man.aac.4; driver now supports 64-bit array support - for RAIDs larger than 2TB and simultaneous opens of the device - for issuing commands to the controller. - - The &man.ata.4; driver now supports a loader variable - hw.ata.ata_dma_check_80pin. This can be - used to disable the 80pin cable check on broken systems such - as certain laptops and Soekris boards. The default value is - 1. - - A data corruption problem of the &man.ata.4; driver on - ServerWorks HT1000 chipsets has been fixed. - - The &man.ciss.4; driver now supports a loader tunable - hw.ciss.nop_message_heartbeat for - NOP-message polling in ciss_periodic(). - This can be used as a workaround for - ADAPTER HEARTBEAT FAILED issue. - The default value is 0 (disabled). - - The geom_part GEOM class can be built - as a kernel module. - - The geom_linux_lvm GEOM class can be - built as a kernel module. - - The &man.hptrr.4; driver has been updated to version 1.2 - from Highpoint. - - A buffer overflow in the &man.iir.4; driver has been - fixed. This likely fixes a great number of weird problems - that have been reported with this driver. - - The &man.mpt.4; driver now supports mpt_user - personality. - - The &man.rr232x.4; driver has been superseded by - &man.hptrr.4; driver. - - The &man.twa.4; driver has been improved with regard to - stability on machines with a plenty of memory and high CPU - load. - - - - File Systems - - dangerously dedicated mode for - the UFS file system is no longer supported. - - - Such disks will need to be reformatted to work with - this release. - - - The &man.gvinum.8; now supports commands - found in the old vinum implementation including - attach, detach, - start, stop, - concat, mirror, - stripe, and - raid5. - - The &man.gvinum.8; now - supports grow command to make it easier - for users to extend plexes without having to understand all - of the implementation internals. - - The &os; NFS subsystem now - supports RPCSEC_GSS authentication on - both the client and server. This replaces the RPC - implementation of the NFS client and server with the newer - RPC implementation originally developed to support the NFS - Lock Manager. It supports both the new RPC implementation - and the older legacy implementation inherited from the - original NFS codebase and the default is to use the new one. - To use RPCSEC_GSS on either client or - server, you must build a kernel which includes - the KGSSAPI option and the &man.crypto.4; - device. For more details, see &man.gssd.8; manual - page. - - The &os; NFS subsystem now includes a new, - experimental implementation with support for NFSv2, NFSv3, and - NFSv4. This is not enabled by default. To enable this, add - the following kernel options to your kernel configuration - file and rebuild the kernel: - - options NFSCL # for NFS client -options NFSD # for NFS server - - The fstype for &man.mount.8; program is - newnfs, and &man.mount.newnfs.8; program - has also been added. The old, unmaintained NFSv4 client - based on an implementation from the University of Michigan was - removed from the &os; source tree. - - The &os; NFS subsystem now uses TCP as the - default transport. - - The shared vnode locking for pathname lookups - in the &man.VFS.9; subsystem has been improved. This is - enabled by default. Setting a sysctl variable - vfs.lookup_shared to 0 - disables it. Note that the - LOOKUP_SHARED kernel option equivalent to - the sysctl variable has been removed. - - The ZFS file system - has been updated to version 13. The changes include ZFS - operations by a regular user, L2ARC, ZFS Intent Log on - separated disks (slog), sparse volumes, and so on. - - The semantics of &man.acl.3; extended access control - lists has been changed as follows: - - - - The inode modification time (mtime) is not updated - when extended attributes are added, modified, or removed. - - - - The inode access time (atime) is not updated - when extended attributes are queried. - - - - The &os; NFS file system now supports a sysctl variable - vfs.nfs.prime_access_cache to determine - whether or not nfs_getattr() will use - an ACCESS RPC to prime the access cache instead of a simple - GETATTR RPC. This is because on many NFS servers an ACCESS - RPC is much more expensive to service than a GETATTR RPC for - files in an NFSv3 mount. The sysctl variable is enabled by - default to maintain the previous behavior. - - The &os; UDF file system now supports a fifo. - - The &man.fdescfs.5; is now MPSAFE. - - The &man.gpart.8; now supports BSD disklabels (option - GEOM_PART_BSD) and - VTOC8 disklabels (option - GEOM_PART_VTOC8). - - The &man.gvinum.8; now accepts volume - parameter when creating a plex. - - A pathname lookup bug of a UNIX domain socket in the - unionfs(7) has been fixed. - - - - - Userland Changes - - The GCC stack protection (also known as - ProPolice) has been enabled in the &os; base system. - - A BSD-licensed &man.ar.1; utility has been added - in favor of one in GNU binutils and - it is now the default utility for building the &os; base - system. - - The &man.awk.1; utility now supports 64 files. - The upper limit was 20 in prior releases. - - The &man.bsnmpd.1; program now supports OIDs - for ZFS. - - The &man.camcontrol.8; program now supports a - new modularized ATA kernel module and various ATA - commands. - - The &man.cat.1; and &man.cp.1; now use a larger - buffer if the number of pages of the physical memory on the - system is grater than 32k. This reduces the number of context - switches. - - A new BSD-licensed &man.cpio.1; utility has been - added in favor of GNU cpio and it - is now the default utility in the &os; base system. - - A script for the &man.crashinfo.8; utility for - simple analysis of crash dump has been added. It generates a - text file containing the output of several commands run against - the core dump such as &man.kgdb.1; (stack trace), &man.ps.1;, - &man.netstat.1;, - &man.vmstat.8;, - &man.iostat.8;, - &man.dmesg.8;, - and - &man.fstat.1;. - - The &man.df.1; utility's - flag now supports displaying inode counts in a human-readable - format when a flag is specified. - - The &man.df.1; utility now supports - a flag to display file system type in each - entry. - - A bug in the &man.dhclient.8; that can create a - malformed /etc/resolv.conf has been - fixed. - - The &man.dhclient.8; now uses an - flag when invoking &man.route.8; command. - This eliminates a long delay in the case that it gets a lease - but DNS service is not working. - - The &man.dhclient.8; utility now - uses 68 (bootpc) as the source port for - unicast DHCPREQUEST packets instead of - allowing the protocol stack to pick a random source port. - This fixes the behavior where &man.dhclient.8; would never - transition from RENEWING - to BOUND without going - through REBINDING in some networks which - has a tight policy on DHCP spoofing. - - The &man.env.1; utility now supports a - option - that completely unsets the given name instead of setting it to - a null value. - - The &man.find.1; utility now supports a number - of primaries found in GNU find - including , - , - , , - , , - , , - , , - , , - , and . - - The &man.fsck.8; utility now supports a - flag to free up excess unused inodes. - Decreasing the number of preallocated inodes reduces the - running time of future runs of fsck and frees up space that - can allocated to files. This flag is ignored when running in - preen mode. - - The &man.freebsd-update.8; now supports backing - up the old kernel when installing a new kernel. The backup - kernel will be written - to /boot/kernel.old if the directory does - not exist or the directory was created by freebsd-update in a - previous backup. Otherwise the &man.freebsd-update.8; will - generate a new directory name for use by the backup. This is - enabled by default. - - The &man.gdbserver.1; now supports &arch.arm; - and &arch.powerpc; platforms. - - The &man.gpt.8; program has been removed in - favor of &man.gpart.8;. - - The &man.gzip.1; utility now supports - uncompressing files which are created - by pack found in some commercial - UNIX-like systems. - - The &man.i2c.8; utility for diagnostics of I2C has - been added. - - The &man.ifconfig.8; now - supports and - option to allow moving interfaces between jails with - vimage. - - A BSD-licensed libdwarf - library has been added for DTrace clients. - - The libmsun library now supports - acosl(), - asinl(), - atanl(), - atan2l(), - cargl(), - csqrtl(), - fmodl(), - hypotl(), - and - remquol() - functions. - - The libproc - library has been added for DTrace clients. - - The &man.mtest.8; utility now supports IPv6. - - The &man.mount.8; program now supports - an option - to allow an alternative program to be used for mounting a file - system. This is useful for non-&man.nmount.2; based file - systems such as FUSE. - - The &man.nfscbd.8;, &man.nfsuserd.8;, - &man.nfsdumpstate.8;, and &man.nfsrevoke.8; utilities for the - new NFSv4 subsystem has been added. - - The &man.pmcannotate.8; utility has been added. - This prints out sources of a tool (in C or assembly) with - inlined profiling informations retrieved by a prior - &man.pmcstat.8; analysis. - - The &man.route.8; utility now - supports show, - weights, and sticky - commands. For more details, see the &man.route.8; manual - page. - - The &man.rtld.1; now supports a new - environment variable LD_ELF_HINTS_PATH for - overriding the rtld hints file. This environment variable - would be ignored if the process uses setuid and/or setgid. - This feature gives a convenient way to use a custom set of - shared library that is not in the default location. - - The &man.rtld.1; now supports the dynamic - string token substitution in the rpath and soneeded pathes. The - $ORIGIN, - $OSNAME, - $OSREL - and $PLATFORM - tokens are supported. Enabling - the substitution requires DF_ORIGIN - flag in DT_FLAGS or - DF_1_ORIGIN if - DF_FLAGS_1, that may be set - with origin GNU - ld flag. This translation is unconditionally - disabled for setuid/setgid processes. - The $ORIGIN translation relies on - the AT_EXECPATH auxinfo supplied by the - &os; kernel. - - It is no longer possible to create UFS - filesystems in dangerously dedicated mode using - &man.sysinstall.8; since this mode is no longer supported. - - &man.sysinstall.8; menus have been simplified - to reduce confusion and duplication with other parts of the - system. The Xorg window system - should be installed just like any other package. - Configuration of Linux and - OSF/1 emulation should be done via - kernel rebuilds. Support for installation from tape media was - removed as it was believed to be broken. Obsolete code to - support OLDCARD was also - removed. - - &man.sysinstall.8; now understands how to use - unsliced USB drives as installation source media via - /dev/daXa - - &man.sysinstall.8; now recognizes the new - /dev/adaX disk - devices, if compiled into the kernel. - - &man.sysinstall.8; now uses the - freebsd-doc-* - packages for localized documents. - - &man.sysinstall.8; now ejects the CDROM after - installation if it was used as source media. - - The &man.traceroute.8; and &man.traceroute6.8; - now support an - flag to display AS number corresponding to - the lookup IP address on each hop. It will query the number to - WHOIS server specified in option. If - no is - specified, whois.radb.net will be used as the - default value. - - The &man.tzsetup.8; now supports - an flag to skip the question about - adjusting the clock to UTC. - - The &man.wake.8; utility, a tool to send Wake on - LAN frames to hosts on a local Ethernet network has been - added. - - The &man.ypserv.8; program now - supports shadow.byname - and shadow.byuid maps. - - A bug in the &man.atacontrol.8; utility, which prevents it - from working when /usr is not mounted or - invoked from /rescue, has been - fixed. - - The &man.btpand.8; daemon from NetBSD has been added. - This daemon provides support for Bluetooth Network Access - Point (NAP), Group Ad-hoc Network (GN) and Personal Area - Network User (PANU) profiles. - - The &man.cpucontrol.8; utility has been added to - control &man.cpuctl.4; pseudo-device. - - The &man.ncal.1; utility now supports multibyte - characters. - - The &man.newfs.8; utility now supports - operations on a regular file. - - The &man.config.8; utility now supports - multiple makeoption lines. - - The &man.csup.1; utility now supports CVSMode to fetch a - complete CVS repository. Note that the rsync transfer mode is - currently disabled. - - The &man.dirname.1; utility now accepts multiple arguments - in the same way that &man.basename.1; does. - - The &man.du.1; utility now supports an - flag. When specified, the &man.du.1; utility counts a file - with multiple hard links as multiple different files. - - The &man.du.1; utility now supports an flag - to display the apparent size instead of the disk usage. This can be - helpful when operating on compressed volumes or sparse files. - - The &man.du.1; utility now supports a option to - calculate block counts in blocks of - blocksize bytes. This is different - from the or options or - setting BLOCKSIZE and gives an estimate of - how much space the examined file hierarchy would require on a - file system with the given - blocksize. Unless in - mode, blocksize - is rounded up to the next multiple of 512. - - The &man.dumpfs.8; utility now supports an - flag, which causes it to list all free - fragments in the file system by fragment (block) number. This - new mode does the necessary arithmetic to generate absolute - fragment numbers rather than the cg-relative numbers printed - in the default mode. - - If is passed once, contiguous fragment - ranges are collapsed into an X-Y format as free block lists - are currently printed in regular dumpfs output. If specified - twice, all block numbers are printed individually, allowing - both compact and more script-friendly representation. - - The &man.fetch.1; utility now supports an - flag which supports the If-Modified-Since - HTTP 1.1 request. If specified it will cause the file to be - downloaded only if it is more recent than the mtime of the - local file. Also, libfetch now - accepts the mtime in the url structure and a flag to indicate - when this behavior is desired. - - The &man.fsck.8; utility now supports a - flag for check clean - mode. This checks if the file system was dismounted cleanly - first and then skip file system checks if true. Otherwise it - does full checks. - - The &man.fsck.8; utility now supports a - flag for damaged recovery mode, which will - enable certain aggressive operations that can make - &man.fsck.8; to survive with file systems that has very - serious data damage. This is a useful last resort when on - disk data damage is very serious and causes &man.fsck.8; to - crash. - - The &man.getaddrinfo.3; function now supports SCTP. - - A bug was fixed in the &man.ipfw.8; utility which displays - extra messages for a NAT rule even when a - flag is specified. - - The &man.ln.1; utility now supports a - flag to check if the source file actually exists. When the - flag is specified and the file does not exist, &man.ln.1; will - issue a warning message. - - The &man.ln.1; utility now allows creating hard - links to symbolic links because the POSIX.1-2008 requires this - behavior for and - flag. - - The &man.lpr.1; utility now support - an flag to send an email after the job is - completed and a option to set the job - title. - - The &man.make.1; utility now supports a - flag to print the input graph only, - without executing any commands. The output is the same as - . When combined with , only the built-in rules of make are - displayed. - - The &man.make.1; utility now supports a - flag to cause file banners not to be - generated in addition to the same effect of a - flag when a option is - specified. - - The &man.make.1; utility now supports the - .MAKE.JOB.PREFIX variable. If - and are specified, its - output for each target is prefixed with a token --- - target --- the first part - of which can be controlled via the variable. - - The &man.make.1; utility now supports - .MAKE.PID and .MAKE.PPID - variable. These are set to process ID of the &man.make.1; - process and its parent process respectively. - - The &man.makefs.8; utility to create a file system image - from a directory tree has been added. - - The &man.mergemaster.8; utility now supports an - option to automatically install files that - differ only in their version control ID strings. - - The &man.mount.8; utility now supports an - option to force it to use the specified program to mount the - file system instead of calling &man.nmount.2; directly. This - is useful when you want to use third party programs such as - FUSE, for example. - - The &man.netstat.1; utility now reports &man.unix.4; - sockets' listen queue statistics when an - flag is specified. - - A bug in the &man.netstat.1; utility has been fixed. It - crashed with the following options in the previous - versions: - - &prompt.user; netstat -m -N foo - - A bug in the &man.netstat.1; utility has been fixed. The - option now works in the icmp6 section as - expected. - - The &man.pciconf.8; utility now supports a - flag, which lists any base address - registers (BAR) that are assigned resources for each - device. - - The &man.powerd.8; program has been improved. Changes - include reasonable CPU load estimation on SMP systems and a - new mode named as hiadaptive for AC-powered - systems. The hiadaptive mode raises the - CPU frequency twice as fast as adaptive, it - drops the CPU frequency 4 times slower, prefers twice lower - CPU load and has an additional delay before leaving the - highest frequency after the period of maximum load. - - The &man.revoke.1; utility has been added. This - is a wrapper of &man.revoke.2; syscall. - - The &man.stat.1; utility now displays an octal - representation of suid, sgid and sticky bits when the - flag is specified. - - The &man.strndup.3; function has been added. - - The &man.tftpd.8; program now supports - a option. This is almost the same as - a option but will generate unique named - based on the submitted filename, a &man.strftime.3; format - string, and a two digit sequence number. The time format - string can be set by an option. - - The &man.wc.1; utility now supports an - flag to output the number of characters in the longest input - line. - - A bug in the &man.rpc.yppasswdd.8; program, which causes - it to leave a zombie process when a password or default shell - is changed, has been fixed. - - The &man.adduser.8; utility now supports - a option to set the mode of a new user's - home directory. - - The &man.atacontrol.8; utility now supports - a spindown command to set or report timeout - after which the device will be spun down. - - The &man.chflags.1; now supports a flag for - verbose output, a flag to ignore errors, - and to allow setting flags on symbolic links - with the same semantics as (for example) &man.chmod.1;. - - The &man.cp.1; now supports a flag, which is - equivalent to flags. - - A bug in the &man.cp.1; utility which prevents POSIX.1e ACL (see - also &man.acl.3;) from copying properly has been fixed. - - The &man.cron.8; utility now supports flag which - overrides the default mail recipient for cron mails unless explicitly - provided by MAILTO= line in crontab - file. - - The &man.dhclient.8; now supports more options described in - &man.dhcp-options.5;. - - The &man.dhclient.8; now - supports is_default_interface() function - which determines if this interface is one with the default - route. - - A bug in the &man.dhclient.8; that prevents removal of the - default route from working has been fixed. - - The &man.environ.7;, environment array of strings now - supports unsetting a variable by setting the first character to - NULL. This is required by third-party software such as - Dovecot - and Postfix. - - The &man.fdisk.8; now supports a flag to - not display any warnings. - - The &man.fetch.1; program and libfetch - library now supports a NO_PROXY environment - variable. This specifies comma- or whitespace-separated list of - host names for which proxies should not be used. If a single - asterisk is specified, the use of proxies is disabled. - - The &man.ffsll.3; and &man.flsll.3; functions have been added. - These functions are the same as &man.ffs.3; and &man.fls.3; except that - they accept long long as the arguments. - - The &man.fortune.6; program now supports - FORTUNE_PATH environment variable to specify - search path of the fortune files. - - A bug in the &man.fortune.6; program that prevents - option with multiple files from working has - been fixed. - - The &man.freebsd-update.conf.5; now supports - IDSIgnorePaths statement. - - The &man.fwcontrol.8; utility now supports option which specifies - node as the root node on the next bus - reset. - - The &man.gcc.1; now - accepts option properly; it was hardcoded - as . - - The &man.ifconfig.8; command now supports - display of WPS IE (Wireless Provisioning Services Information - Element). - - The &man.kgdb.1; command now supports - an add-kld kld - command to locate a &man.kld.4; and load its symbols. - - The &man.kgdb.1; command now has a shared library backend for kernel - files that treats &man.kld.4; as shared libraries and - auto-loading symbols for &man.kld.4; on startup. - - The &man.kgdb.1; now supports a tid command - and other kernel module related commands even for a remote - target. - - The &man.kvm.getcptime.3; function to obtain the global CPU - time statistics from the kernel has been added. - - The libalias library now supports - PORT and - EPRT - FTP commands in lowercase. - - The &man.man.1; now includes a limited support of - &man.bzip2.1;-compressed manual pages. - - The &man.mdconfig.8; command now supports a - (verbose) flag to - command. It shows size and backing store of all &man.md.4; - devices at one time. - - The &man.memrchr.3; function has been added. This behaves - like &man.memchr.3; except that it locates the last occurrence - of the specified character in the string. - - The incorrect output grammar of &man.morse.6; program has - been fixed. - - The &man.mountd.8; utility now supports option which - specifies IP addresses to bind to for TCP and UDP requests. - This option may be specified multiple times. If no - option is specified, - INADDR_ANY will be used. Note that when - specifying IP addresses with this option, it will - automatically add 127.0.0.1 and if IPv6 is - enabled, ::1 to the list. - - The &man.moused.8; utility now supports - flag which changes the speed of scrolling and changes - option behavior to only affect the scroll - threshold. - - The &man.mv.1; command now support POSIX - specification when moving a directory to an existing directory - across devices. - - The &man.periodic.8; now supports - daily_status_mail_rejects_shorten - configuration variable in &man.periodic.conf.5;. This allows - the rejected mail reports to tally the rejects per blacklist - without providing details about individual sender hosts. The - default configuration keeps the reports in their original - form. - - The &man.ping6.8; now uses exit status of - 0 and 2 in the same manner - as &man.ping.8;. - - The &man.ping6.8; now supports an flag, - which makes &man.ping6.8; exit successfully after receiving one - reply packet. - - The &man.ping6.8; now supports - and flags, which are equivalent to - &man.ping.8;'s and - flags, respectively. - - The minimum allowed interval of &man.ping6.8; has been - decreased to 0.000001 from 0.01. - - The &man.realpath.1; utility now supports - a flag to suppress warnings and - accepts multiple paths on its command line. - - The &man.rfcomm.pppd.8; now supports a - flag to register DUN (Dial-Up Networking) service in addition to - the LAN (LAN Access Using PPP) service. - - The &man.sdpd.8; now supports a NAP, - GN, and PANU - profiles. - - The &man.setkey.8; utility now accepts - esp as a protocol name - for the spdadd command. - - A bug in &man.telnetd.8; that caused it to - attempt authentication even when - option is specified has been fixed. - - The &man.top.1; and &man.vmstat.8; commands now - support flag which displays per-CPU - statistics. - - The &man.uuid.enc.le.3;, &man.uuid.dec.le.3;, - &man.uuid.enc.be.3;, and &man.uuid.dec.be.3; functions have been - added. These functions encode/decode a binary representation of - a UUID. - - The &man.watch.8; utility now supports more than 10 - &man.snp.4; devices at a time. - - The &man.ypserv.8; daemon now supports a - option to specify the port number on which - it should listen. - - - <filename>/etc/rc.d</filename> Scripts - - The &man.rc.conf.5; now supports - dummynet_enable variable which allow - &man.dummynet.4; kernel module to be loaded when - firewall_enable is YES. - - The ntpd &man.rc.8; script - can work with no configuration file - /etc/ntp.conf now. - - The ppp &man.rc.8; - script now supports multiple instances. For more details, - see the description of ppp_profile - variable in &man.rc.conf.5;. - - The sysctl &man.rc.8; script now - supports loading /etc/sysctl.conf.local in - addition to /etc/sysctl.conf. - - The &man.rc.conf.5; now supports configuration of - interfaces and attached networks for firewall rule set by - rc.firewall when - firewall_type is simple or - client. See - firewall_client_net, - firewall_simple_iif, - firewall_simple_inet, - firewall_simple_oif, and - firewall_simple_onet. - - - - - Contributed Software - - ISC BIND has been updated to - version 9.6.1rc1. - - The ACPI-CA has been - updated to 20090521. - - The ee (easy editor) has - been updated to 1.5.0. This version is now licensed under a - 2-clause BSD license, instead of the Artistic license. - - The hostapd has been updated to - version 0.6.8 + radius ACL support. - - The less has been updated to - version v436. - - The libarchive library has - been updated to version 2.7.0. - - The libexpat library has - been updated from version 1.95.5 to version 2.0.1. - - The ncurses library has been updated - to version 5.7-20081102. - - OpenBSM 1.1 from - Trusted BSD Project has been merged. - - TCPDUMP has been - updated to 4.0.0. - - The timezone database has been updated - to the tzdata2009f release. - - wpa_supplicant has been updated to - version 0.6.8 - - The ZFS file system - has been updated from version 6 to version 13. - - The am-utils has been updated from - version 6.0.10p1 to version 6.1.5. - - The awk has been updated from 1 May - 2007 release to the 23 October 2007 release. - - The bzip2 has been updated from - version 1.0.4 to version 1.0.5. - - The CVS has been updated to - version 1.11.22.1. - - NTP has been updated to version - 4.2.4p5. - - OpenPAM has been updated from the - Figwort release to the Hydrangea release. - - OpenSSH has been updated from - version 4.5p1 to version 5.1p1. - - The &man.resolver.3; library has been updated to - one of ISC BIND 9.4.3. - - sendmail has been updated from - version 8.14.2 to version 8.14.4. - - - - Ports/Packages Collection Infrastructure - - A bug in the &man.pkg.create.1; utility, which - prevented the flag from working has been - fixed. - - The &os; Ports Collection now supports multiple - &man.make.1; jobs in some supported ports. This is - automatically enabled when a port is marked as - MAKE_JOBS_SAFE and improves CPU utilization - at the build stage by passing an option - to the top - level Makefile from the vendor. The - number X is set to the number of - CPUs by default, and can be set by users via a &man.make.1; - variable MAKE_JOBS_NUMBER. For more - details, see ports/Mk/bsd.port.mk. - - - - Release Engineering and Integration - - The supported version of - the GNOME desktop environment - (x11/gnome2) has been - updated to 2.26.3. - - The supported version of - the KDE desktop environment - (x11/kde4) has been - updated to 4.3.1. - - - - - Upgrading from previous releases of &os; - - Upgrades between RELEASE versions (and - snapshots of the various security branches) are supported using - the &man.freebsd-update.8; utility. The binary upgrade - procedure will update unmodified userland utilities, as well as - unmodified GENERIC or SMP kernels distributed as a part of an - official &os; release. The &man.freebsd-update.8; utility - requires that the host being upgraded has Internet - connectivity. - - An older form of binary upgrade is supported through the - Upgrade option from the main - &man.sysinstall.8; menu on CDROM distribution media. This type - of binary upgrade may be useful on non-&arch.i386;, - non-&arch.amd64; machines or on systems with no Internet - connectivity. - - Source-based upgrades (those based on recompiling the &os; - base system from source code) from previous versions are - supported, according to the instructions in - /usr/src/UPDATING. - - - Upgrading &os; should, of course, only be attempted after - backing up all data and configuration - files. - + This document contains no information. Please see the + online version at . diff --git a/release/doc/share/sgml/release.dsl b/release/doc/share/sgml/release.dsl index 4a19a837c6e..cbee985af2e 100644 --- a/release/doc/share/sgml/release.dsl +++ b/release/doc/share/sgml/release.dsl @@ -121,14 +121,7 @@ ((or (equal? arch #f) (equal? arch "") (equal? arch "all")) - (make sequence - (if (and (not (null? role)) (equal? role "7.1")) - (literal " [7.1R]") - (empty-sosofo)) - (if (and (not (null? role)) (equal? role "7.2")) - (literal " [7.2R]") - (empty-sosofo)) - (process-children-trim)) + (process-children-trim)) (else (make sequence (literal "[") @@ -142,12 +135,6 @@ (loop (car rest) (cdr rest))) (empty-sosofo)))) (literal "] ") - (if (and (not (null? role)) (equal? role "7.1")) - (literal " [7.1R] ") - (empty-sosofo)) - (if (and (not (null? role)) (equal? role "7.2")) - (literal " [7.2R] ") - (empty-sosofo)) (process-children-trim)))) (if (and (not (null? role)) (equal? role "merged")) (literal " [" merged-string "]") @@ -171,14 +158,7 @@ ((or (equal? arch #f) (equal? arch "") (equal? arch "all")) - (make sequence - (if (and (not (null? role)) (equal? role "7.1")) - (literal " [7.1R] ") - (empty-sosofo)) - (if (and (not (null? role)) (equal? role "7.2")) - (literal " [7.2R] ") - (empty-sosofo)) - (process-children-trim))) + (process-children-trim)) (else (make sequence (literal "[") @@ -192,16 +172,10 @@ (loop (car rest) (cdr rest))) (empty-sosofo)))) (literal "] ") - (if (and (not (null? role)) (equal? role "7.1")) - (literal " [7.1R]") - (empty-sosofo)) - (if (and (not (null? role)) (equal? role "7.2")) - (literal " [7.2R]") - (empty-sosofo)) (process-children-trim)))) (if (and (not (null? role)) (equal? role "merged")) (literal " [" merged-string "]") - (empty-sosofo)))))))) + (empty-sosofo))))))) ]]> - + - + - + - + - + @@ -31,10 +31,10 @@ - - + + - + @@ -48,8 +48,11 @@ - + + + + From b45fc34387dc5bb6446978cfee29d802165bfb5c Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Sat, 17 Jul 2010 04:35:51 +0000 Subject: [PATCH 2589/2592] Predict the date we'll be ready to announce 8.1-RELEASE. While here add the entry for 8.0-RELEASE which was added to releng/8.0/UPDATING during the 8.0-RELEASE cycle but not to stable/8/UPDATING at that time. Approved by: re (implicit) --- UPDATING | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/UPDATING b/UPDATING index 4911a6a3a70..ead73d7f4a3 100644 --- a/UPDATING +++ b/UPDATING @@ -15,6 +15,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V: debugging tools present in HEAD were left in place because sun4v support still needs work to become production ready. +20100720: + 8.1-RELEASE. + 20100713: FreeBSD-SA-10:07.mbuf Correctly copy the M_RDONLY flag when duplicating a reference to an mbuf external buffer. @@ -60,6 +63,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V: via the DEADLKRES option, see NOTES for more details) and the sleepq_type() function for sleepqueues. +20091125: + 8.0-RELEASE. + 20090929: 802.11s D3.03 support was committed. This is incompatible with the previous code, which was based on D3.0. From 9adee7d03f2e4c91e6330410f88fb5addaf2a24a Mon Sep 17 00:00:00 2001 From: Ken Smith Date: Sat, 17 Jul 2010 04:36:40 +0000 Subject: [PATCH 2590/2592] Ready for 8.1-RELEASE builds. Approved by: re (implicit) --- sys/conf/newvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index dbd9c9aec75..1464310e013 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.1" -BRANCH="RC2" +BRANCH="RELEASE" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi From 366f60834ff8ef709f132fe8976c96a5e2caace9 Mon Sep 17 00:00:00 2001 From: Peter Grehan Date: Fri, 13 May 2011 04:54:01 +0000 Subject: [PATCH 2591/2592] Import of bhyve hypervisor and utilities, part 1. vmm.ko - kernel module for VT-x, VT-d and hypervisor control bhyve - user-space sequencer and i/o emulation vmmctl - dump of hypervisor register state libvmm - front-end to vmm.ko chardev interface bhyve was designed and implemented by Neel Natu. Thanks to the following folk from NetApp who helped to make this available: Joe CaraDonna Peter Snyder Jeff Heller Sandeep Mann Steve Miller Brian Pawlowski --- lib/Makefile | 2 + lib/libvmmapi/Makefile | 9 + lib/libvmmapi/mptable.c | 336 ++++++ lib/libvmmapi/mptable.h | 171 +++ lib/libvmmapi/vmmapi.c | 647 +++++++++++ lib/libvmmapi/vmmapi.h | 98 ++ lib/libvmmapi/vmmapi_freebsd.c | 187 ++++ share/mk/bsd.libnames.mk | 1 + sys/amd64/include/specialreg.h | 1 + sys/amd64/include/vmm.h | 268 +++++ sys/amd64/include/vmm_dev.h | 191 ++++ sys/amd64/vmm/amd/amdv.c | 247 ++++ sys/amd64/vmm/intel/ept.c | 312 ++++++ sys/amd64/vmm/intel/ept.h | 42 + sys/amd64/vmm/intel/vmcs.c | 451 ++++++++ sys/amd64/vmm/intel/vmcs.h | 324 ++++++ sys/amd64/vmm/intel/vmx.c | 1673 ++++++++++++++++++++++++++++ sys/amd64/vmm/intel/vmx.h | 115 ++ sys/amd64/vmm/intel/vmx_controls.h | 92 ++ sys/amd64/vmm/intel/vmx_cpufunc.h | 199 ++++ sys/amd64/vmm/intel/vmx_genassym.c | 81 ++ sys/amd64/vmm/intel/vmx_msr.c | 172 +++ sys/amd64/vmm/intel/vmx_msr.h | 78 ++ sys/amd64/vmm/intel/vmx_support.S | 204 ++++ sys/amd64/vmm/intel/vtd.c | 637 +++++++++++ sys/amd64/vmm/io/iommu.c | 230 ++++ sys/amd64/vmm/io/iommu.h | 67 ++ sys/amd64/vmm/io/ppt.c | 449 ++++++++ sys/amd64/vmm/io/ppt.h | 40 + sys/amd64/vmm/io/vdev.c | 270 +++++ sys/amd64/vmm/io/vdev.h | 84 ++ sys/amd64/vmm/io/vlapic.c | 812 ++++++++++++++ sys/amd64/vmm/io/vlapic.h | 105 ++ sys/amd64/vmm/vmm.c | 737 ++++++++++++ sys/amd64/vmm/vmm_dev.c | 468 ++++++++ sys/amd64/vmm/vmm_ipi.c | 103 ++ sys/amd64/vmm/vmm_ipi.h | 38 + sys/amd64/vmm/vmm_ktr.h | 51 + sys/amd64/vmm/vmm_lapic.c | 121 ++ sys/amd64/vmm/vmm_lapic.h | 64 ++ sys/amd64/vmm/vmm_mem.c | 413 +++++++ sys/amd64/vmm/vmm_mem.h | 38 + sys/amd64/vmm/vmm_msr.c | 264 +++++ sys/amd64/vmm/vmm_msr.h | 42 + sys/amd64/vmm/vmm_stat.c | 103 ++ sys/amd64/vmm/vmm_stat.h | 71 ++ sys/amd64/vmm/vmm_support.S | 42 + sys/amd64/vmm/vmm_util.c | 111 ++ sys/amd64/vmm/vmm_util.h | 40 + sys/amd64/vmm/x86.c | 113 ++ sys/amd64/vmm/x86.h | 62 ++ sys/modules/Makefile | 2 + sys/modules/vmm/Makefile | 66 ++ usr.sbin/Makefile | 4 + usr.sbin/bhyve/Makefile | 18 + usr.sbin/bhyve/atpic.c | 68 ++ usr.sbin/bhyve/consport.c | 121 ++ usr.sbin/bhyve/dbgport.c | 124 +++ usr.sbin/bhyve/dbgport.h | 36 + usr.sbin/bhyve/elcr.c | 65 ++ usr.sbin/bhyve/fbsdrun.c | 650 +++++++++++ usr.sbin/bhyve/fbsdrun.h | 53 + usr.sbin/bhyve/inout.c | 98 ++ usr.sbin/bhyve/inout.h | 64 ++ usr.sbin/bhyve/mevent.c | 419 +++++++ usr.sbin/bhyve/mevent.h | 49 + usr.sbin/bhyve/mevent_test.c | 180 +++ usr.sbin/bhyve/pci_emul.c | 976 ++++++++++++++++ usr.sbin/bhyve/pci_emul.h | 171 +++ usr.sbin/bhyve/pci_hostbridge.c | 52 + usr.sbin/bhyve/pci_passthru.c | 508 +++++++++ usr.sbin/bhyve/pci_virtio_block.c | 502 +++++++++ usr.sbin/bhyve/pci_virtio_net.c | 739 ++++++++++++ usr.sbin/bhyve/pit_8254.c | 196 ++++ usr.sbin/bhyve/pit_8254.h | 45 + usr.sbin/bhyve/post.c | 51 + usr.sbin/bhyve/rtc.c | 268 +++++ usr.sbin/bhyve/uart.c | 60 + usr.sbin/bhyve/virtio.h | 85 ++ usr.sbin/bhyve/xmsr.c | 261 +++++ usr.sbin/bhyve/xmsr.h | 34 + usr.sbin/vmmctl/Makefile | 15 + usr.sbin/vmmctl/sample.sh | 75 ++ usr.sbin/vmmctl/vmmctl.c | 1485 ++++++++++++++++++++++++ 84 files changed, 19016 insertions(+) create mode 100644 lib/libvmmapi/Makefile create mode 100644 lib/libvmmapi/mptable.c create mode 100644 lib/libvmmapi/mptable.h create mode 100644 lib/libvmmapi/vmmapi.c create mode 100644 lib/libvmmapi/vmmapi.h create mode 100644 lib/libvmmapi/vmmapi_freebsd.c create mode 100644 sys/amd64/include/vmm.h create mode 100644 sys/amd64/include/vmm_dev.h create mode 100644 sys/amd64/vmm/amd/amdv.c create mode 100644 sys/amd64/vmm/intel/ept.c create mode 100644 sys/amd64/vmm/intel/ept.h create mode 100644 sys/amd64/vmm/intel/vmcs.c create mode 100644 sys/amd64/vmm/intel/vmcs.h create mode 100644 sys/amd64/vmm/intel/vmx.c create mode 100644 sys/amd64/vmm/intel/vmx.h create mode 100644 sys/amd64/vmm/intel/vmx_controls.h create mode 100644 sys/amd64/vmm/intel/vmx_cpufunc.h create mode 100644 sys/amd64/vmm/intel/vmx_genassym.c create mode 100644 sys/amd64/vmm/intel/vmx_msr.c create mode 100644 sys/amd64/vmm/intel/vmx_msr.h create mode 100644 sys/amd64/vmm/intel/vmx_support.S create mode 100644 sys/amd64/vmm/intel/vtd.c create mode 100644 sys/amd64/vmm/io/iommu.c create mode 100644 sys/amd64/vmm/io/iommu.h create mode 100644 sys/amd64/vmm/io/ppt.c create mode 100644 sys/amd64/vmm/io/ppt.h create mode 100644 sys/amd64/vmm/io/vdev.c create mode 100644 sys/amd64/vmm/io/vdev.h create mode 100644 sys/amd64/vmm/io/vlapic.c create mode 100644 sys/amd64/vmm/io/vlapic.h create mode 100644 sys/amd64/vmm/vmm.c create mode 100644 sys/amd64/vmm/vmm_dev.c create mode 100644 sys/amd64/vmm/vmm_ipi.c create mode 100644 sys/amd64/vmm/vmm_ipi.h create mode 100644 sys/amd64/vmm/vmm_ktr.h create mode 100644 sys/amd64/vmm/vmm_lapic.c create mode 100644 sys/amd64/vmm/vmm_lapic.h create mode 100644 sys/amd64/vmm/vmm_mem.c create mode 100644 sys/amd64/vmm/vmm_mem.h create mode 100644 sys/amd64/vmm/vmm_msr.c create mode 100644 sys/amd64/vmm/vmm_msr.h create mode 100644 sys/amd64/vmm/vmm_stat.c create mode 100644 sys/amd64/vmm/vmm_stat.h create mode 100644 sys/amd64/vmm/vmm_support.S create mode 100644 sys/amd64/vmm/vmm_util.c create mode 100644 sys/amd64/vmm/vmm_util.h create mode 100644 sys/amd64/vmm/x86.c create mode 100644 sys/amd64/vmm/x86.h create mode 100644 sys/modules/vmm/Makefile create mode 100644 usr.sbin/bhyve/Makefile create mode 100644 usr.sbin/bhyve/atpic.c create mode 100644 usr.sbin/bhyve/consport.c create mode 100644 usr.sbin/bhyve/dbgport.c create mode 100644 usr.sbin/bhyve/dbgport.h create mode 100644 usr.sbin/bhyve/elcr.c create mode 100644 usr.sbin/bhyve/fbsdrun.c create mode 100644 usr.sbin/bhyve/fbsdrun.h create mode 100644 usr.sbin/bhyve/inout.c create mode 100644 usr.sbin/bhyve/inout.h create mode 100644 usr.sbin/bhyve/mevent.c create mode 100644 usr.sbin/bhyve/mevent.h create mode 100644 usr.sbin/bhyve/mevent_test.c create mode 100644 usr.sbin/bhyve/pci_emul.c create mode 100644 usr.sbin/bhyve/pci_emul.h create mode 100644 usr.sbin/bhyve/pci_hostbridge.c create mode 100644 usr.sbin/bhyve/pci_passthru.c create mode 100644 usr.sbin/bhyve/pci_virtio_block.c create mode 100644 usr.sbin/bhyve/pci_virtio_net.c create mode 100644 usr.sbin/bhyve/pit_8254.c create mode 100644 usr.sbin/bhyve/pit_8254.h create mode 100644 usr.sbin/bhyve/post.c create mode 100644 usr.sbin/bhyve/rtc.c create mode 100644 usr.sbin/bhyve/uart.c create mode 100644 usr.sbin/bhyve/virtio.h create mode 100644 usr.sbin/bhyve/xmsr.c create mode 100644 usr.sbin/bhyve/xmsr.h create mode 100644 usr.sbin/vmmctl/Makefile create mode 100755 usr.sbin/vmmctl/sample.sh create mode 100644 usr.sbin/vmmctl/vmmctl.c diff --git a/lib/Makefile b/lib/Makefile index e9f4ec36b82..8f33206f44a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -102,6 +102,7 @@ SUBDIR= ${SUBDIR_ORDERED} \ ${_libusbhid} \ ${_libusb} \ ${_libvgl} \ + ${_libvmmapi} \ libwrap \ liby \ libz \ @@ -177,6 +178,7 @@ _libncp= libncp .endif _libsmb= libsmb _libvgl= libvgl +_libvmmapi= libvmmapi .endif .if ${MACHINE_ARCH} == "powerpc" diff --git a/lib/libvmmapi/Makefile b/lib/libvmmapi/Makefile new file mode 100644 index 00000000000..492391f9f85 --- /dev/null +++ b/lib/libvmmapi/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +LIB= vmmapi +SRCS= vmmapi.c vmmapi_freebsd.c mptable.c +INCS= vmmapi.h + +CFLAGS+= -I${.CURDIR} + +.include diff --git a/lib/libvmmapi/mptable.c b/lib/libvmmapi/mptable.c new file mode 100644 index 00000000000..1aea61a2ad7 --- /dev/null +++ b/lib/libvmmapi/mptable.c @@ -0,0 +1,336 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include + +#include "vmmapi.h" +#include "mptable.h" + +#define LAPIC_PADDR (0xFEE00000) +#define LAPIC_VERSION (16) + +#define IOAPIC_PADDR (0xFEC00000) +#define IOAPIC_VERSION (0x11) + +extern int errno; + +static uint8_t +mp_compute_checksum(void *base, size_t len) +{ + uint8_t *bytes = base; + uint8_t sum = 0; + for(; len > 0; len--) { + sum += *bytes++; + } + return 256 - sum; +} + +static void +mp_build_mpfp(struct mp_floating_pointer *mpfp, vm_paddr_t mpfp_gpa) +{ + memset(mpfp, 0, sizeof(*mpfp)); + memcpy(mpfp->signature, MPFP_SIGNATURE, MPFP_SIGNATURE_LEN); + mpfp->mptable_paddr = mpfp_gpa + sizeof(*mpfp); + mpfp->specrev = MP_SPECREV; + mpfp->feature2 = 0; + mpfp->checksum = mp_compute_checksum(mpfp, sizeof(*mpfp)); +} + +static void +mp_build_mpch(struct mp_config_hdr *mpch) +{ + memset(mpch, 0, sizeof(*mpch)); + mpch->specrev = MP_SPECREV; + memcpy(mpch->signature, MPCH_SIGNATURE, MPCH_SIGNATURE_LEN); + memcpy(mpch->oemid, MPCH_OEMID, MPCH_OEMID_LEN); + memcpy(mpch->prodid, MPCH_PRODID, MPCH_PRODID_LEN); + mpch->lapic_paddr = LAPIC_PADDR; + + +} + +static void +mp_build_proc_entries(struct mpe_proc *mpep, int num_proc) +{ + int i; + + for (i = 0; i < num_proc; i++) { + memset(mpep, 0, sizeof(*mpep)); + mpep->entry_type = MP_ENTRY_PROC; + mpep->lapic_id = i; // XXX + mpep->lapic_version = LAPIC_VERSION; + mpep->proc_flags = (i == 0)?MPEP_FLAGS_BSP:0; + mpep->proc_flags |= MPEP_FLAGS_EN; + mpep->proc_signature = MPEP_SIGNATURE; + mpep->feature_flags = MPEP_FEATURES; + mpep++; + } + +} + +static void +mp_build_bus_entries(struct mpe_bus *mpeb) +{ + memset(mpeb, 0, sizeof(*mpeb)); + mpeb->entry_type = MP_ENTRY_BUS; + mpeb->busid = MPE_BUSID_ISA; + memcpy(mpeb->busname, MPE_BUSNAME_ISA, MPE_BUSNAME_LEN); + mpeb++; + + memset(mpeb, 0, sizeof(*mpeb)); + mpeb->entry_type = MP_ENTRY_BUS; + mpeb->busid = MPE_BUSID_PCI; + memcpy(mpeb->busname, MPE_BUSNAME_PCI, MPE_BUSNAME_LEN); + +} + +static void +mp_build_ioapic_entries(struct mpe_ioapic *mpei) +{ + memset(mpei, 0, sizeof(*mpei)); + mpei->entry_type = MP_ENTRY_IOAPIC; + mpei->ioapic_id = MPE_IOAPIC_ID; + mpei->ioapic_version = IOAPIC_VERSION; + mpei->ioapic_flags = MPE_IOAPIC_FLAG_EN; + mpei->ioapic_paddr = IOAPIC_PADDR; +} + +static void +mp_build_ioint_entries(struct mpe_ioint *mpeii, int num_pins) +{ + int pin; + + /* + * The following config is taken from kernel mptable.c + * mptable_parse_default_config_ints(...), for now + * just use the default config, tweek later if needed. + */ + + + /* Run through all 16 pins. */ + for (pin = 0; pin < num_pins; pin++) { + memset(mpeii, 0, sizeof(*mpeii)); + mpeii->entry_type = MP_ENTRY_IOINT; + mpeii->src_bus_id = MPE_BUSID_ISA; + mpeii->dst_apic_id = MPE_IOAPIC_ID; + + /* + * All default configs route IRQs from bus 0 to the first 16 pins + * of the first I/O APIC with an APIC ID of 2. + */ + mpeii->dst_apic_intin = pin; + switch (pin) { + case 0: + /* Pin 0 is an ExtINT pin. */ + mpeii->intr_type = MPEII_INTR_EXTINT; + break; + case 2: + /* IRQ 0 is routed to pin 2. */ + mpeii->intr_type = MPEII_INTR_INT; + mpeii->src_bus_irq = 0; + break; + case 5: + case 10: + case 11: + /* + * PCI Irqs set to level triggered. + */ + mpeii->intr_flags = MPEII_FLAGS_TRIGMODE_LEVEL; + mpeii->src_bus_id = MPE_BUSID_PCI; + default: + /* All other pins are identity mapped. */ + mpeii->intr_type = MPEII_INTR_INT; + mpeii->src_bus_irq = pin; + break; + } + mpeii++; + } + +} + +#define COPYSTR(dest, src, bytes) \ + memcpy(dest, src, bytes); \ + str[bytes] = 0; + + +static void +mptable_dump(struct mp_floating_pointer *mpfp, struct mp_config_hdr *mpch) +{ + static char str[16]; + int i; + char *cur; + + union mpe { + struct mpe_proc *proc; + struct mpe_bus *bus; + struct mpe_ioapic *ioapic; + struct mpe_ioint *ioint; + struct mpe_lint *lnit; + char *p; + }; + + union mpe mpe; + + printf(" MP Floating Pointer :\n"); + COPYSTR(str, mpfp->signature, 4); + printf(" signature: %s\n", str); + printf(" mpch paddr: %x\n", mpfp->mptable_paddr); + printf(" length: %x\n", mpfp->length); + printf(" specrec: %x\n", mpfp->specrev); + printf(" checksum: %x\n", mpfp->checksum); + printf(" feature1: %x\n", mpfp->feature1); + printf(" feature2: %x\n", mpfp->feature2); + printf(" feature3: %x\n", mpfp->feature3); + printf(" feature4: %x\n", mpfp->feature4); + + printf(" MP Configuration Header :\n"); + COPYSTR(str, mpch->signature, 4); + printf(" signature: %s\n", str); + printf(" length: %x\n", mpch->length); + printf(" specrec: %x\n", mpch->specrev); + printf(" checksum: %x\n", mpch->checksum); + COPYSTR(str, mpch->oemid, MPCH_OEMID_LEN); + printf(" oemid: %s\n", str); + COPYSTR(str, mpch->prodid, MPCH_PRODID_LEN); + printf(" prodid: %s\n", str); + printf(" oem_ptr: %x\n", mpch->oem_ptr); + printf(" oem_sz: %x\n", mpch->oem_sz); + printf(" nr_entries: %x\n", mpch->nr_entries); + printf(" apic paddr: %x\n", mpch->lapic_paddr); + printf(" ext_length: %x\n", mpch->ext_length); + printf(" ext_checksum: %x\n", mpch->ext_checksum); + + cur = (char *)mpch + sizeof(*mpch); + for (i = 0; i < mpch->nr_entries; i++) { + mpe.p = cur; + switch(*mpe.p) { + case MP_ENTRY_PROC: + printf(" MP Processor Entry :\n"); + printf(" lapic_id: %x\n", mpe.proc->lapic_id); + printf(" lapic_version: %x\n", mpe.proc->lapic_version); + printf(" proc_flags: %x\n", mpe.proc->proc_flags); + printf(" proc_signature: %x\n", mpe.proc->proc_signature); + printf(" feature_flags: %x\n", mpe.proc->feature_flags); + cur += sizeof(struct mpe_proc); + break; + case MP_ENTRY_BUS: + printf(" MP Bus Entry :\n"); + printf(" busid: %x\n", mpe.bus->busid); + COPYSTR(str, mpe.bus->busname, MPE_BUSNAME_LEN); + printf(" busname: %s\n", str); + cur += sizeof(struct mpe_bus); + break; + case MP_ENTRY_IOAPIC: + printf(" MP IOAPIC Entry :\n"); + printf(" ioapi_id: %x\n", mpe.ioapic->ioapic_id); + printf(" ioapi_version: %x\n", mpe.ioapic->ioapic_version); + printf(" ioapi_flags: %x\n", mpe.ioapic->ioapic_flags); + printf(" ioapi_paddr: %x\n", mpe.ioapic->ioapic_paddr); + cur += sizeof(struct mpe_ioapic); + break; + case MP_ENTRY_IOINT: + printf(" MP IO Interrupt Entry :\n"); + printf(" intr_type: %x\n", mpe.ioint->intr_type); + printf(" intr_flags: %x\n", mpe.ioint->intr_flags); + printf(" src_bus_id: %x\n", mpe.ioint->src_bus_id); + printf(" src_bus_irq: %x\n", mpe.ioint->src_bus_irq); + printf(" dst_apic_id: %x\n", mpe.ioint->dst_apic_id); + printf(" dst_apic_intin: %x\n", mpe.ioint->dst_apic_intin); + cur += sizeof(struct mpe_ioint); + break; + case MP_ENTRY_LINT: + printf(" MP Local Interrupt Entry :\n"); + cur += sizeof(struct mpe_lint); + break; + } + + } +} + +int +vm_build_mptable(struct vmctx *ctx, vm_paddr_t gpa, int len, int ncpu, + void *oemp, int oemsz) +{ + struct mp_config_hdr *mpch; + char *mapaddr; + char *startaddr; + int error; + + mapaddr = vm_map_memory(ctx, gpa, len); + if (mapaddr == MAP_FAILED) { + printf("%s\n", strerror(errno)); + goto err; + } + startaddr = mapaddr; + + mp_build_mpfp((struct mp_floating_pointer*) mapaddr, gpa); + mapaddr += sizeof(struct mp_floating_pointer); + + mpch = (struct mp_config_hdr*)mapaddr; + mp_build_mpch(mpch); + mapaddr += sizeof(struct mp_config_hdr); + + mp_build_proc_entries((struct mpe_proc*) mapaddr, ncpu); + mapaddr += (sizeof(struct mpe_proc)*ncpu); + mpch->nr_entries += ncpu; + + mp_build_bus_entries((struct mpe_bus*)mapaddr); + mapaddr += (sizeof(struct mpe_bus)*MPE_NUM_BUSES); + mpch->nr_entries += MPE_NUM_BUSES; +#if 0 + mp_build_ioapic_entries((struct mpe_ioapic*)mapaddr); + mapaddr += sizeof(struct mpe_ioapic); + mpch->nr_entries++; + + mp_build_ioint_entries((struct mpe_ioint*)mapaddr, MPEII_MAX_IRQ); + mapaddr += sizeof(struct mpe_ioint)*MPEII_MAX_IRQ; + mpch->nr_entries += MPEII_MAX_IRQ; + +#endif + if (oemp) { + mpch->oem_ptr = mapaddr - startaddr + gpa; + mpch->oem_sz = oemsz; + memcpy(mapaddr, oemp, oemsz); + } + mpch->length = (mapaddr) - ((char*) mpch); + mpch->checksum = mp_compute_checksum(mpch, sizeof(*mpch)); + + + // mptable_dump((struct mp_floating_pointer*)startaddr, mpch); +err: + return (error); +} diff --git a/lib/libvmmapi/mptable.h b/lib/libvmmapi/mptable.h new file mode 100644 index 00000000000..cad8834a47b --- /dev/null +++ b/lib/libvmmapi/mptable.h @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _MPTABLE_h_ +#define _MPTABLE_h_ + +#define MP_SPECREV (4) // MP spec revision 1.1 + +/* + * MP Floating Pointer Structure + */ +#define MPFP_SIGNATURE "_MP_" +#define MPFP_SIGNATURE_LEN (4) +#define MPFP_FEATURE2 (0x80) // IMCR is present +struct mp_floating_pointer { + uint8_t signature[MPFP_SIGNATURE_LEN]; + uint32_t mptable_paddr; + uint8_t length; + uint8_t specrev; + uint8_t checksum; + uint8_t feature1; + uint8_t feature2; + uint8_t feature3; + uint8_t feature4; + uint8_t feature5; +}; + + +/* + * MP Configuration Table Header + */ +#define MPCH_SIGNATURE "PCMP" +#define MPCH_SIGNATURE_LEN (4) + +#define MPCH_OEMID "NETAPP " +#define MPCH_OEMID_LEN (8) +#define MPCH_PRODID "vFiler " +#define MPCH_PRODID_LEN (12) + +struct mp_config_hdr { + uint8_t signature[MPCH_SIGNATURE_LEN]; + uint16_t length; + uint8_t specrev; + uint8_t checksum; + uint8_t oemid[MPCH_OEMID_LEN]; + uint8_t prodid[MPCH_PRODID_LEN]; + uint32_t oem_ptr; + uint16_t oem_sz; + uint16_t nr_entries; + uint32_t lapic_paddr; + uint16_t ext_length; + uint8_t ext_checksum; + uint8_t reserved; +}; + +#define MP_ENTRY_PROC (0) +#define MP_ENTRY_BUS (1) +#define MP_ENTRY_IOAPIC (2) +#define MP_ENTRY_IOINT (3) +#define MP_ENTRY_LINT (4) + +/* + * MP Processor Entry + */ + +#define MPEP_FLAGS_EN (0x1) +#define MPEP_FLAGS_BSP (0x2) + +#define MPEP_SIG_FAMILY (6) +#define MPEP_SIG_MODEL (26) +#define MPEP_SIG_STEPPING (5) +#define MPEP_SIGNATURE ((MPEP_SIG_FAMILY << 8) | (MPEP_SIG_MODEL << 4) \ + | (MPEP_SIG_STEPPING)) + +#define MPEP_FEATURES (0xBFEBFBFF) // Value from Intel i7 CPUID + +struct mpe_proc { + uint8_t entry_type; + uint8_t lapic_id; + uint8_t lapic_version; + uint8_t proc_flags; + uint32_t proc_signature; + uint32_t feature_flags; + uint8_t reserved[8]; +}; + +/* + * MP Bus Entry + */ + +#define MPE_NUM_BUSES (2) +#define MPE_BUSNAME_LEN (6) +#define MPE_BUSID_ISA (0) +#define MPE_BUSID_PCI (1) +#define MPE_BUSNAME_ISA "ISA " +#define MPE_BUSNAME_PCI "PCI " +struct mpe_bus { + uint8_t entry_type; + uint8_t busid; + uint8_t busname[MPE_BUSNAME_LEN]; +}; + +/* + * MP IO APIC Entry + */ +#define MPE_IOAPIC_ID (2) +#define MPE_IOAPIC_FLAG_EN (1) +struct mpe_ioapic { + uint8_t entry_type; + uint8_t ioapic_id; + uint8_t ioapic_version; + uint8_t ioapic_flags; + uint32_t ioapic_paddr; + +}; + +/* + * MP IO Interrupt Assignment Entry + */ +#define MPEII_INTR_INT (0) +#define MPEII_INTR_NMI (1) +#define MPEII_INTR_SMI (2) +#define MPEII_INTR_EXTINT (3) +#define MPEII_PCI_IRQ_MASK (0x0c20U) /* IRQ 5,10,11 are PCI connected */ +#define MPEII_MAX_IRQ (16) +#define MPEII_FLAGS_TRIGMODE_LEVEL (0x3) +struct mpe_ioint { + uint8_t entry_type; + uint8_t intr_type; + uint16_t intr_flags; + uint8_t src_bus_id; + uint8_t src_bus_irq; + uint8_t dst_apic_id; + uint8_t dst_apic_intin; +}; + +/* + * MP Local Interrupt Assignment Entry + */ +struct mpe_lint { + uint8_t entry_type; +}; + +int vm_build_mptable(struct vmctx *ctxt, vm_paddr_t gpa, int len, + int ncpu, void *oemp, int oemsz); +#endif /* _MPTABLE_h_ */ diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c new file mode 100644 index 00000000000..7f95fea9b60 --- /dev/null +++ b/lib/libvmmapi/vmmapi.c @@ -0,0 +1,647 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "vmmapi.h" +#include "mptable.h" + +#ifndef CR4_VMXE +#define CR4_VMXE (1UL << 13) +#endif + +#define BIOS_ROM_BASE (0xf0000) +#define BIOS_ROM_SIZE (0x10000) + +struct vmctx { + int fd; + char *name; +}; + +#define CREATE(x) sysctlbyname("hw.vmm.create", NULL, NULL, (x), strlen((x))) +#define DESTROY(x) sysctlbyname("hw.vmm.destroy", NULL, NULL, (x), strlen((x))) + +static int +vm_device_open(const char *name) +{ + int fd, len; + char *vmfile; + + len = strlen("/dev/vmm/") + strlen(name) + 1; + vmfile = malloc(len); + assert(vmfile != NULL); + snprintf(vmfile, len, "/dev/vmm/%s", name); + + /* Open the device file */ + fd = open(vmfile, O_RDWR, 0); + + free(vmfile); + return (fd); +} + +int +vm_create(const char *name) +{ + + return (CREATE((char *)name)); +} + +struct vmctx * +vm_open(const char *name) +{ + struct vmctx *vm; + + vm = malloc(sizeof(struct vmctx) + strlen(name) + 1); + assert(vm != NULL); + + vm->fd = -1; + vm->name = (char *)(vm + 1); + strcpy(vm->name, name); + + if ((vm->fd = vm_device_open(vm->name)) < 0) + goto err; + + return (vm); +err: + vm_destroy(vm); + return (NULL); +} + +void +vm_destroy(struct vmctx *vm) +{ + assert(vm != NULL); + + DESTROY(vm->name); + if (vm->fd >= 0) + close(vm->fd); + free(vm); +} + +int +vm_get_memory_seg(struct vmctx *ctx, vm_paddr_t gpa, + vm_paddr_t *ret_hpa, size_t *ret_len) +{ + int error; + struct vm_memory_segment seg; + + bzero(&seg, sizeof(seg)); + seg.gpa = gpa; + error = ioctl(ctx->fd, VM_GET_MEMORY_SEG, &seg); + *ret_hpa = seg.hpa; + *ret_len = seg.len; + return (error); +} + +int +vm_setup_memory(struct vmctx *ctx, vm_paddr_t gpa, size_t len, char **mapaddr) +{ + int error; + struct vm_memory_segment seg; + + /* + * Create and optionally map 'len' bytes of memory at guest + * physical address 'gpa' + */ + bzero(&seg, sizeof(seg)); + seg.gpa = gpa; + seg.len = len; + error = ioctl(ctx->fd, VM_MAP_MEMORY, &seg); + if (error == 0 && mapaddr != NULL) { + *mapaddr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, + ctx->fd, gpa); + } + return (error); +} + +char * +vm_map_memory(struct vmctx *ctx, vm_paddr_t gpa, size_t len) +{ + + /* Map 'len' bytes of memory at guest physical address 'gpa' */ + return ((char *)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, + ctx->fd, gpa)); +} + +int +vm_set_desc(struct vmctx *ctx, int vcpu, int reg, + uint64_t base, uint32_t limit, uint32_t access) +{ + int error; + struct vm_seg_desc vmsegdesc; + + bzero(&vmsegdesc, sizeof(vmsegdesc)); + vmsegdesc.cpuid = vcpu; + vmsegdesc.regnum = reg; + vmsegdesc.desc.base = base; + vmsegdesc.desc.limit = limit; + vmsegdesc.desc.access = access; + + error = ioctl(ctx->fd, VM_SET_SEGMENT_DESCRIPTOR, &vmsegdesc); + return (error); +} + +int +vm_get_desc(struct vmctx *ctx, int vcpu, int reg, + uint64_t *base, uint32_t *limit, uint32_t *access) +{ + int error; + struct vm_seg_desc vmsegdesc; + + bzero(&vmsegdesc, sizeof(vmsegdesc)); + vmsegdesc.cpuid = vcpu; + vmsegdesc.regnum = reg; + + error = ioctl(ctx->fd, VM_GET_SEGMENT_DESCRIPTOR, &vmsegdesc); + if (error == 0) { + *base = vmsegdesc.desc.base; + *limit = vmsegdesc.desc.limit; + *access = vmsegdesc.desc.access; + } + return (error); +} + +int +vm_set_register(struct vmctx *ctx, int vcpu, int reg, uint64_t val) +{ + int error; + struct vm_register vmreg; + + bzero(&vmreg, sizeof(vmreg)); + vmreg.cpuid = vcpu; + vmreg.regnum = reg; + vmreg.regval = val; + + error = ioctl(ctx->fd, VM_SET_REGISTER, &vmreg); + return (error); +} + +int +vm_get_register(struct vmctx *ctx, int vcpu, int reg, uint64_t *ret_val) +{ + int error; + struct vm_register vmreg; + + bzero(&vmreg, sizeof(vmreg)); + vmreg.cpuid = vcpu; + vmreg.regnum = reg; + + error = ioctl(ctx->fd, VM_GET_REGISTER, &vmreg); + *ret_val = vmreg.regval; + return (error); +} + +int +vm_get_pinning(struct vmctx *ctx, int vcpu, int *host_cpuid) +{ + int error; + struct vm_pin vmpin; + + bzero(&vmpin, sizeof(vmpin)); + vmpin.vm_cpuid = vcpu; + + error = ioctl(ctx->fd, VM_GET_PINNING, &vmpin); + *host_cpuid = vmpin.host_cpuid; + return (error); +} + +int +vm_set_pinning(struct vmctx *ctx, int vcpu, int host_cpuid) +{ + int error; + struct vm_pin vmpin; + + bzero(&vmpin, sizeof(vmpin)); + vmpin.vm_cpuid = vcpu; + vmpin.host_cpuid = host_cpuid; + + error = ioctl(ctx->fd, VM_SET_PINNING, &vmpin); + return (error); +} + +int +vm_run(struct vmctx *ctx, int vcpu, uint64_t rip, struct vm_exit *vmexit) +{ + int error; + struct vm_run vmrun; + + bzero(&vmrun, sizeof(vmrun)); + vmrun.cpuid = vcpu; + vmrun.rip = rip; + + error = ioctl(ctx->fd, VM_RUN, &vmrun); + bcopy(&vmrun.vm_exit, vmexit, sizeof(struct vm_exit)); + return (error); +} + +static int +vm_inject_event_real(struct vmctx *ctx, int vcpu, enum vm_event_type type, + int vector, int error_code, int error_code_valid) +{ + struct vm_event ev; + + bzero(&ev, sizeof(ev)); + ev.cpuid = vcpu; + ev.type = type; + ev.vector = vector; + ev.error_code = error_code; + ev.error_code_valid = error_code_valid; + + return (ioctl(ctx->fd, VM_INJECT_EVENT, &ev)); +} + +int +vm_inject_event(struct vmctx *ctx, int vcpu, enum vm_event_type type, + int vector) +{ + + return (vm_inject_event_real(ctx, vcpu, type, vector, 0, 0)); +} + +int +vm_inject_event2(struct vmctx *ctx, int vcpu, enum vm_event_type type, + int vector, int error_code) +{ + + return (vm_inject_event_real(ctx, vcpu, type, vector, error_code, 1)); +} + +int +vm_build_tables(struct vmctx *ctxt, int ncpu, void *oemtbl, int oemtblsz) +{ + + return (vm_build_mptable(ctxt, BIOS_ROM_BASE, BIOS_ROM_SIZE, ncpu, + oemtbl, oemtblsz)); +} + +int +vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector) +{ + struct vm_lapic_irq vmirq; + + bzero(&vmirq, sizeof(vmirq)); + vmirq.cpuid = vcpu; + vmirq.vector = vector; + + return (ioctl(ctx->fd, VM_LAPIC_IRQ, &vmirq)); +} + +int +vm_inject_nmi(struct vmctx *ctx, int vcpu) +{ + struct vm_nmi vmnmi; + + bzero(&vmnmi, sizeof(vmnmi)); + vmnmi.cpuid = vcpu; + + return (ioctl(ctx->fd, VM_INJECT_NMI, &vmnmi)); +} + +int +vm_capability_name2type(const char *capname) +{ + int i; + + static struct { + const char *name; + int type; + } capstrmap[] = { + { "hlt_exit", VM_CAP_HALT_EXIT }, + { "mtrap_exit", VM_CAP_MTRAP_EXIT }, + { "pause_exit", VM_CAP_PAUSE_EXIT }, + { "unrestricted_guest", VM_CAP_UNRESTRICTED_GUEST }, + { 0 } + }; + + for (i = 0; capstrmap[i].name != NULL && capname != NULL; i++) { + if (strcmp(capstrmap[i].name, capname) == 0) + return (capstrmap[i].type); + } + + return (-1); +} + +int +vm_get_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, + int *retval) +{ + int error; + struct vm_capability vmcap; + + bzero(&vmcap, sizeof(vmcap)); + vmcap.cpuid = vcpu; + vmcap.captype = cap; + + error = ioctl(ctx->fd, VM_GET_CAPABILITY, &vmcap); + *retval = vmcap.capval; + return (error); +} + +int +vm_set_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, int val) +{ + struct vm_capability vmcap; + + bzero(&vmcap, sizeof(vmcap)); + vmcap.cpuid = vcpu; + vmcap.captype = cap; + vmcap.capval = val; + + return (ioctl(ctx->fd, VM_SET_CAPABILITY, &vmcap)); +} + +int +vm_assign_pptdev(struct vmctx *ctx, int bus, int slot, int func) +{ + struct vm_pptdev pptdev; + + bzero(&pptdev, sizeof(pptdev)); + pptdev.bus = bus; + pptdev.slot = slot; + pptdev.func = func; + + return (ioctl(ctx->fd, VM_BIND_PPTDEV, &pptdev)); +} + +int +vm_unassign_pptdev(struct vmctx *ctx, int bus, int slot, int func) +{ + struct vm_pptdev pptdev; + + bzero(&pptdev, sizeof(pptdev)); + pptdev.bus = bus; + pptdev.slot = slot; + pptdev.func = func; + + return (ioctl(ctx->fd, VM_UNBIND_PPTDEV, &pptdev)); +} + +int +vm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, + vm_paddr_t gpa, size_t len, vm_paddr_t hpa) +{ + struct vm_pptdev_mmio pptmmio; + + bzero(&pptmmio, sizeof(pptmmio)); + pptmmio.bus = bus; + pptmmio.slot = slot; + pptmmio.func = func; + pptmmio.gpa = gpa; + pptmmio.len = len; + pptmmio.hpa = hpa; + + return (ioctl(ctx->fd, VM_MAP_PPTDEV_MMIO, &pptmmio)); +} + +int +vm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, + int destcpu, int vector, int numvec) +{ + struct vm_pptdev_msi pptmsi; + + bzero(&pptmsi, sizeof(pptmsi)); + pptmsi.vcpu = vcpu; + pptmsi.bus = bus; + pptmsi.slot = slot; + pptmsi.func = func; + pptmsi.destcpu = destcpu; + pptmsi.vector = vector; + pptmsi.numvec = numvec; + + return (ioctl(ctx->fd, VM_PPTDEV_MSI, &pptmsi)); +} + +uint64_t * +vm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv, + int *ret_entries) +{ + int error; + + static struct vm_stats vmstats; + + vmstats.cpuid = vcpu; + + error = ioctl(ctx->fd, VM_STATS, &vmstats); + if (error == 0) { + if (ret_entries) + *ret_entries = vmstats.num_entries; + if (ret_tv) + *ret_tv = vmstats.tv; + return (vmstats.statbuf); + } else + return (NULL); +} + +const char * +vm_get_stat_desc(struct vmctx *ctx, int index) +{ + int error; + + static struct vm_stat_desc statdesc; + + statdesc.index = index; + if (ioctl(ctx->fd, VM_STAT_DESC, &statdesc) == 0) + return (statdesc.desc); + else + return (NULL); +} + +/* + * From Intel Vol 3a: + * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT + */ +int +vcpu_reset(struct vmctx *vmctx, int vcpu) +{ + int error; + uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx; + uint32_t desc_access, desc_limit; + uint16_t sel; + + zero = 0; + + rflags = 0x2; + error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RFLAGS, rflags); + if (error) + goto done; + + rip = 0xfff0; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RIP, rip)) != 0) + goto done; + + cr0 = CR0_NE; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR0, cr0)) != 0) + goto done; + + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR3, zero)) != 0) + goto done; + + cr4 = CR4_VMXE; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR4, cr4)) != 0) + goto done; + + /* + * CS: present, r/w, accessed, 16-bit, byte granularity, usable + */ + desc_base = 0xffff0000; + desc_limit = 0xffff; + desc_access = 0x0093; + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_CS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + sel = 0xf000; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CS, sel)) != 0) + goto done; + + /* + * SS,DS,ES,FS,GS: present, r/w, accessed, 16-bit, byte granularity + */ + desc_base = 0; + desc_limit = 0xffff; + desc_access = 0x0093; + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_SS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_DS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_ES, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_FS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + sel = 0; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_SS, sel)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_DS, sel)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_ES, sel)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_FS, sel)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_GS, sel)) != 0) + goto done; + + /* General purpose registers */ + rdx = 0xf00; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RAX, zero)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBX, zero)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RCX, zero)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDX, rdx)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSI, zero)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDI, zero)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBP, zero)) != 0) + goto done; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSP, zero)) != 0) + goto done; + + /* GDTR, IDTR */ + desc_base = 0; + desc_limit = 0xffff; + desc_access = 0; + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GDTR, + desc_base, desc_limit, desc_access); + if (error != 0) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_IDTR, + desc_base, desc_limit, desc_access); + if (error != 0) + goto done; + + /* TR */ + desc_base = 0; + desc_limit = 0xffff; + desc_access = 0x0000008b; + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_TR, 0, 0, desc_access); + if (error) + goto done; + + sel = 0; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_TR, sel)) != 0) + goto done; + + /* LDTR */ + desc_base = 0; + desc_limit = 0xffff; + desc_access = 0x00000082; + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_LDTR, desc_base, + desc_limit, desc_access); + if (error) + goto done; + + sel = 0; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_LDTR, 0)) != 0) + goto done; + + /* XXX cr2, debug registers */ + + error = 0; +done: + return (error); +} diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h new file mode 100644 index 00000000000..38533a894b1 --- /dev/null +++ b/lib/libvmmapi/vmmapi.h @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMMAPI_H_ +#define _VMMAPI_H_ + +struct vmctx; + +int vm_create(const char *name); +struct vmctx *vm_open(const char *name); +void vm_destroy(struct vmctx *ctx); +int vm_get_memory_seg(struct vmctx *ctx, vm_paddr_t gpa, + vm_paddr_t *ret_hpa, size_t *ret_len); +/* + * Create a memory segment of 'len' bytes in the guest physical address space + * at offset 'gpa'. + * + * If 'mapaddr' is not NULL then this region is mmap'ed into the address + * space of the calling process. If there is an mmap error then *mapaddr + * will be set to MAP_FAILED. + */ + +int vm_setup_memory(struct vmctx *ctx, vm_paddr_t gpa, size_t len, + char **mapaddr); +char * vm_map_memory(struct vmctx *ctx, vm_paddr_t gpa, size_t len); +int vm_set_desc(struct vmctx *ctx, int vcpu, int reg, + uint64_t base, uint32_t limit, uint32_t access); +int vm_get_desc(struct vmctx *ctx, int vcpu, int reg, + uint64_t *base, uint32_t *limit, uint32_t *access); +int vm_set_register(struct vmctx *ctx, int vcpu, int reg, uint64_t val); +int vm_get_register(struct vmctx *ctx, int vcpu, int reg, uint64_t *retval); +int vm_get_pinning(struct vmctx *ctx, int vcpu, int *host_cpuid); +int vm_set_pinning(struct vmctx *ctx, int vcpu, int host_cpuid); +int vm_run(struct vmctx *ctx, int vcpu, uint64_t rip, + struct vm_exit *ret_vmexit); +int vm_build_tables(struct vmctx *ctxt, int ncpus, void *oemtbl, + int oemtblsz); +int vm_inject_event(struct vmctx *ctx, int vcpu, enum vm_event_type type, + int vector); +int vm_inject_event2(struct vmctx *ctx, int vcpu, enum vm_event_type type, + int vector, int error_code); +int vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector); +int vm_inject_nmi(struct vmctx *ctx, int vcpu); +int vm_capability_name2type(const char *capname); +int vm_get_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, + int *retval); +int vm_set_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, + int val); +int vm_assign_pptdev(struct vmctx *ctx, int bus, int slot, int func); +int vm_unassign_pptdev(struct vmctx *ctx, int bus, int slot, int func); +int vm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, + vm_paddr_t gpa, size_t len, vm_paddr_t hpa); +int vm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, + int dest, int vector, int numvec); + +/* + * Return a pointer to the statistics buffer. Note that this is not MT-safe. + */ +uint64_t *vm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv, + int *ret_entries); +const char *vm_get_stat_desc(struct vmctx *ctx, int index); + +/* Reset vcpu register state */ +int vcpu_reset(struct vmctx *ctx, int vcpu); + +/* + * FreeBSD specific APIs + */ +int vm_setup_freebsd_registers(struct vmctx *ctx, int vcpu, + uint64_t rip, uint64_t cr3, uint64_t gdtbase, + uint64_t rsp); +void vm_setup_freebsd_gdt(uint64_t *gdtr); +#endif /* _VMMAPI_H_ */ diff --git a/lib/libvmmapi/vmmapi_freebsd.c b/lib/libvmmapi/vmmapi_freebsd.c new file mode 100644 index 00000000000..c4ad9898ede --- /dev/null +++ b/lib/libvmmapi/vmmapi_freebsd.c @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include +#include + +#include "vmmapi.h" + +#ifndef CR4_VMXE +#define CR4_VMXE (1UL << 13) +#endif + +#define DESC_UNUSABLE 0x00010000 + +#define GUEST_NULL_SEL 0 +#define GUEST_CODE_SEL 1 +#define GUEST_DATA_SEL 2 +#define GUEST_GDTR_LIMIT (3 * 8 - 1) + +void +vm_setup_freebsd_gdt(uint64_t *gdtr) +{ + gdtr[GUEST_NULL_SEL] = 0; + gdtr[GUEST_CODE_SEL] = 0x0020980000000000; + gdtr[GUEST_DATA_SEL] = 0x0000900000000000; +} + +/* + * Setup the 'vcpu' register set such that it will begin execution at + * 'rip' in long mode. + */ +int +vm_setup_freebsd_registers(struct vmctx *vmctx, int vcpu, + uint64_t rip, uint64_t cr3, uint64_t gdtbase, + uint64_t rsp) +{ + int error; + uint64_t cr0, cr4, efer, rflags, desc_base; + uint32_t desc_access, desc_limit; + uint16_t gsel; + + cr0 = CR0_PE | CR0_PG | CR0_NE; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR0, cr0)) != 0) + goto done; + + cr4 = CR4_PAE | CR4_VMXE; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR4, cr4)) != 0) + goto done; + + efer = EFER_LME | EFER_LMA; + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_EFER, efer))) + goto done; + + rflags = 0x2; + error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RFLAGS, rflags); + if (error) + goto done; + + desc_base = 0; + desc_limit = 0; + desc_access = 0x0000209B; + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_CS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + desc_access = 0x00000093; + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_DS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_ES, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_FS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_SS, + desc_base, desc_limit, desc_access); + if (error) + goto done; + + /* + * XXX TR is pointing to null selector even though we set the + * TSS segment to be usable with a base address and limit of 0. + */ + desc_access = 0x0000008b; + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_TR, 0, 0, desc_access); + if (error) + goto done; + + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_LDTR, 0, 0, + DESC_UNUSABLE); + if (error) + goto done; + + gsel = GSEL(GUEST_CODE_SEL, SEL_KPL); + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CS, gsel)) != 0) + goto done; + + gsel = GSEL(GUEST_DATA_SEL, SEL_KPL); + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_DS, gsel)) != 0) + goto done; + + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_ES, gsel)) != 0) + goto done; + + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_FS, gsel)) != 0) + goto done; + + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_GS, gsel)) != 0) + goto done; + + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_SS, gsel)) != 0) + goto done; + + /* XXX TR is pointing to the null selector */ + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_TR, 0)) != 0) + goto done; + + /* LDTR is pointing to the null selector */ + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_LDTR, 0)) != 0) + goto done; + + /* entry point */ + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RIP, rip)) != 0) + goto done; + + /* page table base */ + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR3, cr3)) != 0) + goto done; + + desc_base = gdtbase; + desc_limit = GUEST_GDTR_LIMIT; + error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GDTR, + desc_base, desc_limit, 0); + if (error != 0) + goto done; + + if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSP, rsp)) != 0) + goto done; + + error = 0; +done: + return (error); +} diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index ff1a11ae05b..5fc1b3cbf40 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -155,6 +155,7 @@ LIBUSB?= ${DESTDIR}${LIBDIR}/libusb.a LIBUTIL?= ${DESTDIR}${LIBDIR}/libutil.a LIBUUTIL?= ${DESTDIR}${LIBDIR}/libuutil.a LIBVGL?= ${DESTDIR}${LIBDIR}/libvgl.a +LIBVMMAPI?= ${DESTDIR}${LIBDIR}/libvmmapi.a LIBWRAP?= ${DESTDIR}${LIBDIR}/libwrap.a LIBXPG4?= ${DESTDIR}${LIBDIR}/libxpg4.a LIBY?= ${DESTDIR}${LIBDIR}/liby.a diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h index 895619cf6f7..c95fee05f5e 100644 --- a/sys/amd64/include/specialreg.h +++ b/sys/amd64/include/specialreg.h @@ -297,6 +297,7 @@ */ #define APICBASE_RESERVED 0x000006ff #define APICBASE_BSP 0x00000100 +#define APICBASE_X2APIC 0x00000400 #define APICBASE_ENABLED 0x00000800 #define APICBASE_ADDRESS 0xfffff000 diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h new file mode 100644 index 00000000000..0f4c356b6d5 --- /dev/null +++ b/sys/amd64/include/vmm.h @@ -0,0 +1,268 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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: vmm.h 482 2011-05-09 21:22:43Z grehan $ + */ + +#ifndef _VMM_H_ +#define _VMM_H_ + +#ifdef _KERNEL + +#define VM_MAX_NAMELEN 32 + +struct vm; +struct vm_memory_segment; +struct seg_desc; +struct vm_exit; +struct vm_run; +struct vlapic; + +typedef int (*vmm_init_func_t)(void); +typedef int (*vmm_cleanup_func_t)(void); +typedef void * (*vmi_init_func_t)(struct vm *vm); /* instance specific apis */ +typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip, + struct vm_exit *vmexit); +typedef void (*vmi_cleanup_func_t)(void *vmi); +typedef int (*vmi_mmap_func_t)(void *vmi, vm_paddr_t gpa, vm_paddr_t hpa, + size_t length, vm_memattr_t attr, + int prot, boolean_t superpages_ok); +typedef int (*vmi_get_register_t)(void *vmi, int vcpu, int num, + uint64_t *retval); +typedef int (*vmi_set_register_t)(void *vmi, int vcpu, int num, + uint64_t val); +typedef int (*vmi_get_desc_t)(void *vmi, int vcpu, int num, + struct seg_desc *desc); +typedef int (*vmi_set_desc_t)(void *vmi, int vcpu, int num, + struct seg_desc *desc); +typedef int (*vmi_inject_event_t)(void *vmi, int vcpu, + int type, int vector, + uint32_t code, int code_valid); +typedef int (*vmi_inject_nmi_t)(void *vmi, int vcpu); +typedef int (*vmi_get_cap_t)(void *vmi, int vcpu, int num, int *retval); +typedef int (*vmi_set_cap_t)(void *vmi, int vcpu, int num, int val); + +struct vmm_ops { + vmm_init_func_t init; /* module wide initialization */ + vmm_cleanup_func_t cleanup; + + vmi_init_func_t vminit; /* vm-specific initialization */ + vmi_run_func_t vmrun; + vmi_cleanup_func_t vmcleanup; + vmi_mmap_func_t vmmmap; + vmi_get_register_t vmgetreg; + vmi_set_register_t vmsetreg; + vmi_get_desc_t vmgetdesc; + vmi_set_desc_t vmsetdesc; + vmi_inject_event_t vminject; + vmi_inject_nmi_t vmnmi; + vmi_get_cap_t vmgetcap; + vmi_set_cap_t vmsetcap; +}; + +extern struct vmm_ops vmm_ops_intel; +extern struct vmm_ops vmm_ops_amd; + +struct vm *vm_create(const char *name); +void vm_destroy(struct vm *vm); +const char *vm_name(struct vm *vm); +int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t *ret_hpa); +int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); +int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); +vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); +int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, + struct vm_memory_segment *seg); +int vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval); +int vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val); +int vm_get_seg_desc(struct vm *vm, int vcpu, int reg, + struct seg_desc *ret_desc); +int vm_set_seg_desc(struct vm *vm, int vcpu, int reg, + struct seg_desc *desc); +int vm_get_pinning(struct vm *vm, int vcpu, int *cpuid); +int vm_set_pinning(struct vm *vm, int vcpu, int cpuid); +int vm_run(struct vm *vm, struct vm_run *vmrun); +int vm_inject_event(struct vm *vm, int vcpu, int type, + int vector, uint32_t error_code, int error_code_valid); +int vm_inject_nmi(struct vm *vm, int vcpu); +uint64_t *vm_guest_msrs(struct vm *vm, int cpu); +struct vlapic *vm_lapic(struct vm *vm, int cpu); +int vm_get_capability(struct vm *vm, int vcpu, int type, int *val); +int vm_set_capability(struct vm *vm, int vcpu, int type, int val); +void vm_activate_cpu(struct vm *vm, int vcpu); +cpumask_t vm_active_cpus(struct vm *vm); + +/* + * Return 1 if device indicated by bus/slot/func is supposed to be a + * pci passthrough device. + * + * Return 0 otherwise. + */ +int vmm_is_pptdev(int bus, int slot, int func); + +void *vm_iommu_domain(struct vm *vm); + +#define VCPU_STOPPED 0 +#define VCPU_RUNNING 1 +void vm_set_run_state(struct vm *vm, int vcpu, int running); +int vm_get_run_state(struct vm *vm, int vcpu, int *hostcpu); + +void *vcpu_stats(struct vm *vm, int vcpu); + +static int __inline +vcpu_is_running(struct vm *vm, int vcpu, int *hostcpu) +{ + return (vm_get_run_state(vm, vcpu, hostcpu) == VCPU_RUNNING); +} + +static cpumask_t __inline +vcpu_mask(int vcpuid) +{ + return ((cpumask_t)1 << vcpuid); +} + +#endif /* KERNEL */ + +#define VM_MAXCPU 8 /* maximum virtual cpus */ + +/* + * Identifiers for events that can be injected into the VM + */ +enum vm_event_type { + VM_EVENT_NONE, + VM_HW_INTR, + VM_NMI, + VM_HW_EXCEPTION, + VM_SW_INTR, + VM_PRIV_SW_EXCEPTION, + VM_SW_EXCEPTION, + VM_EVENT_MAX +}; + +/* + * Identifiers for architecturally defined registers. + */ +enum vm_reg_name { + VM_REG_GUEST_RAX, + VM_REG_GUEST_RBX, + VM_REG_GUEST_RCX, + VM_REG_GUEST_RDX, + VM_REG_GUEST_RSI, + VM_REG_GUEST_RDI, + VM_REG_GUEST_RBP, + VM_REG_GUEST_R8, + VM_REG_GUEST_R9, + VM_REG_GUEST_R10, + VM_REG_GUEST_R11, + VM_REG_GUEST_R12, + VM_REG_GUEST_R13, + VM_REG_GUEST_R14, + VM_REG_GUEST_R15, + VM_REG_GUEST_CR0, + VM_REG_GUEST_CR3, + VM_REG_GUEST_CR4, + VM_REG_GUEST_DR7, + VM_REG_GUEST_RSP, + VM_REG_GUEST_RIP, + VM_REG_GUEST_RFLAGS, + VM_REG_GUEST_ES, + VM_REG_GUEST_CS, + VM_REG_GUEST_SS, + VM_REG_GUEST_DS, + VM_REG_GUEST_FS, + VM_REG_GUEST_GS, + VM_REG_GUEST_LDTR, + VM_REG_GUEST_TR, + VM_REG_GUEST_IDTR, + VM_REG_GUEST_GDTR, + VM_REG_GUEST_EFER, + VM_REG_LAST +}; + +/* + * Identifiers for optional vmm capabilities + */ +enum vm_cap_type { + VM_CAP_HALT_EXIT, + VM_CAP_MTRAP_EXIT, + VM_CAP_PAUSE_EXIT, + VM_CAP_UNRESTRICTED_GUEST, + VM_CAP_MAX +}; + +/* + * The 'access' field has the format specified in Table 21-2 of the Intel + * Architecture Manual vol 3b. + * + * XXX The contents of the 'access' field are architecturally defined except + * bit 16 - Segment Unusable. + */ +struct seg_desc { + uint64_t base; + uint32_t limit; + uint32_t access; +}; + +enum vm_exitcode { + VM_EXITCODE_INOUT, + VM_EXITCODE_VMX, + VM_EXITCODE_BOGUS, + VM_EXITCODE_RDMSR, + VM_EXITCODE_WRMSR, + VM_EXITCODE_HLT, + VM_EXITCODE_MTRAP, + VM_EXITCODE_PAUSE, + VM_EXITCODE_MAX, +}; + +struct vm_exit { + enum vm_exitcode exitcode; + int inst_length; /* 0 means unknown */ + uint64_t rip; + union { + struct { + uint16_t bytes:3; /* 1 or 2 or 4 */ + uint16_t in:1; /* out is 0, in is 1 */ + uint16_t string:1; + uint16_t rep:1; + uint16_t port; + uint32_t eax; /* valid for out */ + } inout; + /* + * VMX specific payload. Used when there is no "better" + * exitcode to represent the VM-exit. + */ + struct { + int error; /* vmx inst error */ + uint32_t exit_reason; + uint64_t exit_qualification; + } vmx; + struct { + uint32_t code; /* ecx value */ + uint64_t wval; + } msr; + } u; +}; + +#endif /* _VMM_H_ */ diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h new file mode 100644 index 00000000000..1b143b527e4 --- /dev/null +++ b/sys/amd64/include/vmm_dev.h @@ -0,0 +1,191 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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: vmm_dev.h 482 2011-05-09 21:22:43Z grehan $ + */ + +#ifndef _VMM_DEV_H_ +#define _VMM_DEV_H_ + +#ifdef _KERNEL +void vmmdev_init(void); +void vmmdev_cleanup(void); +#endif + +struct vm_memory_segment { + vm_paddr_t hpa; /* out */ + vm_paddr_t gpa; /* in */ + size_t len; /* in */ +}; + +struct vm_register { + int cpuid; + int regnum; /* enum vm_reg_name */ + uint64_t regval; +}; + +struct vm_seg_desc { /* data or code segment */ + int cpuid; + int regnum; /* enum vm_reg_name */ + struct seg_desc desc; +}; + +struct vm_pin { + int vm_cpuid; + int host_cpuid; /* -1 to unpin */ +}; + +struct vm_run { + int cpuid; + uint64_t rip; /* start running here */ + struct vm_exit vm_exit; +}; + +struct vm_event { + int cpuid; + enum vm_event_type type; + int vector; + uint32_t error_code; + int error_code_valid; +}; + +struct vm_lapic_irq { + int cpuid; + int vector; +}; + +struct vm_capability { + int cpuid; + enum vm_cap_type captype; + int capval; + int allcpus; +}; + +struct vm_pptdev { + int bus; + int slot; + int func; +}; + +struct vm_pptdev_mmio { + int bus; + int slot; + int func; + vm_paddr_t gpa; + vm_paddr_t hpa; + size_t len; +}; + +struct vm_pptdev_msi { + int vcpu; + int bus; + int slot; + int func; + int numvec; /* 0 means disabled */ + int vector; + int destcpu; +}; + +struct vm_nmi { + int cpuid; +}; + +#define MAX_VM_STATS 64 +struct vm_stats { + int cpuid; /* in */ + int num_entries; /* out */ + struct timeval tv; + uint64_t statbuf[MAX_VM_STATS]; +}; + +struct vm_stat_desc { + int index; /* in */ + char desc[128]; /* out */ +}; + +enum { + IOCNUM_RUN, + IOCNUM_SET_PINNING, + IOCNUM_GET_PINNING, + IOCNUM_MAP_MEMORY, + IOCNUM_GET_MEMORY_SEG, + IOCNUM_SET_REGISTER, + IOCNUM_GET_REGISTER, + IOCNUM_SET_SEGMENT_DESCRIPTOR, + IOCNUM_GET_SEGMENT_DESCRIPTOR, + IOCNUM_INJECT_EVENT, + IOCNUM_LAPIC_IRQ, + IOCNUM_SET_CAPABILITY, + IOCNUM_GET_CAPABILITY, + IOCNUM_BIND_PPTDEV, + IOCNUM_UNBIND_PPTDEV, + IOCNUM_MAP_PPTDEV_MMIO, + IOCNUM_PPTDEV_MSI, + IOCNUM_INJECT_NMI, + IOCNUM_VM_STATS, + IOCNUM_VM_STAT_DESC, +}; + +#define VM_RUN \ + _IOWR('v', IOCNUM_RUN, struct vm_run) +#define VM_SET_PINNING \ + _IOW('v', IOCNUM_SET_PINNING, struct vm_pin) +#define VM_GET_PINNING \ + _IOWR('v', IOCNUM_GET_PINNING, struct vm_pin) +#define VM_MAP_MEMORY \ + _IOWR('v', IOCNUM_MAP_MEMORY, struct vm_memory_segment) +#define VM_GET_MEMORY_SEG \ + _IOWR('v', IOCNUM_GET_MEMORY_SEG, struct vm_memory_segment) +#define VM_SET_REGISTER \ + _IOW('v', IOCNUM_SET_REGISTER, struct vm_register) +#define VM_GET_REGISTER \ + _IOWR('v', IOCNUM_GET_REGISTER, struct vm_register) +#define VM_SET_SEGMENT_DESCRIPTOR \ + _IOW('v', IOCNUM_SET_SEGMENT_DESCRIPTOR, struct vm_seg_desc) +#define VM_GET_SEGMENT_DESCRIPTOR \ + _IOWR('v', IOCNUM_GET_SEGMENT_DESCRIPTOR, struct vm_seg_desc) +#define VM_INJECT_EVENT \ + _IOW('v', IOCNUM_INJECT_EVENT, struct vm_event) +#define VM_LAPIC_IRQ \ + _IOW('v', IOCNUM_LAPIC_IRQ, struct vm_lapic_irq) +#define VM_SET_CAPABILITY \ + _IOW('v', IOCNUM_SET_CAPABILITY, struct vm_capability) +#define VM_GET_CAPABILITY \ + _IOWR('v', IOCNUM_GET_CAPABILITY, struct vm_capability) +#define VM_BIND_PPTDEV \ + _IOW('v', IOCNUM_BIND_PPTDEV, struct vm_pptdev) +#define VM_UNBIND_PPTDEV \ + _IOW('v', IOCNUM_UNBIND_PPTDEV, struct vm_pptdev) +#define VM_MAP_PPTDEV_MMIO \ + _IOW('v', IOCNUM_MAP_PPTDEV_MMIO, struct vm_pptdev_mmio) +#define VM_PPTDEV_MSI \ + _IOW('v', IOCNUM_PPTDEV_MSI, struct vm_pptdev_msi) +#define VM_INJECT_NMI \ + _IOW('v', IOCNUM_INJECT_NMI, struct vm_nmi) +#define VM_STATS \ + _IOWR('v', IOCNUM_VM_STATS, struct vm_stats) +#define VM_STAT_DESC \ + _IOWR('v', IOCNUM_VM_STAT_DESC, struct vm_stat_desc) +#endif diff --git a/sys/amd64/vmm/amd/amdv.c b/sys/amd64/vmm/amd/amdv.c new file mode 100644 index 00000000000..41e937a20da --- /dev/null +++ b/sys/amd64/vmm/amd/amdv.c @@ -0,0 +1,247 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include "io/iommu.h" + +static int +amdv_init(void) +{ + + printf("amdv_init: not implemented\n"); + return (ENXIO); +} + +static int +amdv_cleanup(void) +{ + + printf("amdv_cleanup: not implemented\n"); + return (ENXIO); +} + +static void * +amdv_vminit(struct vm *vm) +{ + + printf("amdv_vminit: not implemented\n"); + return (NULL); +} + +static int +amdv_vmrun(void *arg, int vcpu, register_t rip, struct vm_exit *vmexit) +{ + + printf("amdv_vmrun: not implemented\n"); + return (ENXIO); +} + +static void +amdv_vmcleanup(void *arg) +{ + + printf("amdv_vmcleanup: not implemented\n"); + return; +} + +static int +amdv_vmmmap(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, size_t length, + vm_memattr_t attr, int prot, boolean_t spok) +{ + + printf("amdv_vmmmap: not implemented\n"); + return (EINVAL); +} + +static int +amdv_getreg(void *arg, int vcpu, int regnum, uint64_t *retval) +{ + + printf("amdv_getreg: not implemented\n"); + return (EINVAL); +} + +static int +amdv_setreg(void *arg, int vcpu, int regnum, uint64_t val) +{ + + printf("amdv_setreg: not implemented\n"); + return (EINVAL); +} + +static int +amdv_getdesc(void *vmi, int vcpu, int num, struct seg_desc *desc) +{ + + printf("amdv_get_desc: not implemented\n"); + return (EINVAL); +} + +static int +amdv_setdesc(void *vmi, int vcpu, int num, struct seg_desc *desc) +{ + + printf("amdv_get_desc: not implemented\n"); + return (EINVAL); +} + +static int +amdv_inject_event(void *vmi, int vcpu, int type, int vector, + uint32_t error_code, int error_code_valid) +{ + + printf("amdv_inject_event: not implemented\n"); + return (EINVAL); +} + +static int +amdv_nmi(void *arg, int vcpu) +{ + + printf("amdv_nmi: not implemented\n"); + return (EINVAL); +} + +static int +amdv_getcap(void *arg, int vcpu, int type, int *retval) +{ + + printf("amdv_getcap: not implemented\n"); + return (EINVAL); +} + +static int +amdv_setcap(void *arg, int vcpu, int type, int val) +{ + + printf("amdv_setcap: not implemented\n"); + return (EINVAL); +} + +struct vmm_ops vmm_ops_amd = { + amdv_init, + amdv_cleanup, + amdv_vminit, + amdv_vmrun, + amdv_vmcleanup, + amdv_vmmmap, + amdv_getreg, + amdv_setreg, + amdv_getdesc, + amdv_setdesc, + amdv_inject_event, + amdv_nmi, + amdv_getcap, + amdv_setcap +}; + +static int +amd_iommu_init(void) +{ + + printf("amd_iommu_init: not implemented\n"); + return (ENXIO); +} + +static void +amd_iommu_cleanup(void) +{ + + printf("amd_iommu_cleanup: not implemented\n"); +} + +static void +amd_iommu_enable(void) +{ + + printf("amd_iommu_enable: not implemented\n"); +} + +static void +amd_iommu_disable(void) +{ + + printf("amd_iommu_disable: not implemented\n"); +} + +static void * +amd_iommu_create_domain(vm_paddr_t maxaddr) +{ + + printf("amd_iommu_create_domain: not implemented\n"); + return (NULL); +} + +static void +amd_iommu_destroy_domain(void *domain) +{ + + printf("amd_iommu_destroy_domain: not implemented\n"); +} + +static uint64_t +amd_iommu_create_mapping(void *domain, vm_paddr_t gpa, vm_paddr_t hpa, + uint64_t len) +{ + + printf("amd_iommu_create_mapping: not implemented\n"); + return (0); +} + +static void +amd_iommu_add_device(void *domain, int bus, int slot, int func) +{ + + printf("amd_iommu_add_device: not implemented\n"); +} + +static void +amd_iommu_remove_device(void *domain, int bus, int slot, int func) +{ + + printf("amd_iommu_remove_device: not implemented\n"); +} + +struct iommu_ops iommu_ops_amd = { + amd_iommu_init, + amd_iommu_cleanup, + amd_iommu_enable, + amd_iommu_disable, + amd_iommu_create_domain, + amd_iommu_destroy_domain, + amd_iommu_create_mapping, + amd_iommu_add_device, + amd_iommu_remove_device, +}; diff --git a/sys/amd64/vmm/intel/ept.c b/sys/amd64/vmm/intel/ept.c new file mode 100644 index 00000000000..c9fca9d5abe --- /dev/null +++ b/sys/amd64/vmm/intel/ept.c @@ -0,0 +1,312 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include "vmx_cpufunc.h" +#include "vmx_msr.h" +#include "vmx.h" +#include "ept.h" + +#define EPT_PWL4(cap) ((cap) & (1UL << 6)) +#define EPT_MEMORY_TYPE_WB(cap) ((cap) & (1UL << 14)) +#define EPT_PDE_SUPERPAGE(cap) ((cap) & (1UL << 16)) /* 2MB pages */ +#define EPT_PDPTE_SUPERPAGE(cap) ((cap) & (1UL << 17)) /* 1GB pages */ +#define INVVPID_SUPPORTED(cap) ((cap) & (1UL << 32)) +#define INVEPT_SUPPORTED(cap) ((cap) & (1UL << 20)) + +#define INVVPID_ALL_TYPES_MASK 0xF0000000000UL +#define INVVPID_ALL_TYPES_SUPPORTED(cap) \ + (((cap) & INVVPID_ALL_TYPES_MASK) == INVVPID_ALL_TYPES_MASK) + +#define INVEPT_ALL_TYPES_MASK 0x6000000UL +#define INVEPT_ALL_TYPES_SUPPORTED(cap) \ + (((cap) & INVEPT_ALL_TYPES_MASK) == INVEPT_ALL_TYPES_MASK) + +#define EPT_PG_RD (1 << 0) +#define EPT_PG_WR (1 << 1) +#define EPT_PG_EX (1 << 2) +#define EPT_PG_MEMORY_TYPE(x) ((x) << 3) +#define EPT_PG_IGNORE_PAT (1 << 6) +#define EPT_PG_SUPERPAGE (1 << 7) + +#define EPT_ADDR_MASK ((uint64_t)-1 << 12) + +MALLOC_DECLARE(M_VMX); + +static uint64_t page_sizes_mask; + +int +ept_init(void) +{ + int page_shift; + uint64_t cap; + + cap = rdmsr(MSR_VMX_EPT_VPID_CAP); + + /* + * Verify that: + * - page walk length is 4 steps + * - extended page tables can be laid out in write-back memory + * - invvpid instruction with all possible types is supported + * - invept instruction with all possible types is supported + */ + if (!EPT_PWL4(cap) || + !EPT_MEMORY_TYPE_WB(cap) || + !INVVPID_SUPPORTED(cap) || + !INVVPID_ALL_TYPES_SUPPORTED(cap) || + !INVEPT_SUPPORTED(cap) || + !INVEPT_ALL_TYPES_SUPPORTED(cap)) + return (EINVAL); + + /* Set bits in 'page_sizes_mask' for each valid page size */ + page_shift = PAGE_SHIFT; + page_sizes_mask = 1UL << page_shift; /* 4KB page */ + + page_shift += 9; + if (EPT_PDE_SUPERPAGE(cap)) + page_sizes_mask |= 1UL << page_shift; /* 2MB superpage */ + + page_shift += 9; + if (EPT_PDPTE_SUPERPAGE(cap)) + page_sizes_mask |= 1UL << page_shift; /* 1GB superpage */ + + return (0); +} + +static size_t +ept_create_mapping(uint64_t *ptp, vm_paddr_t gpa, vm_paddr_t hpa, size_t length, + vm_memattr_t attr, vm_prot_t prot, boolean_t spok) +{ + int spshift, ptpshift, ptpindex, nlevels; + + /* + * Compute the size of the mapping that we can accomodate. + * + * This is based on three factors: + * - super page sizes supported by the processor + * - alignment of the region starting at 'gpa' and 'hpa' + * - length of the region 'len' + */ + spshift = PAGE_SHIFT; + if (spok) + spshift += (EPT_PWLEVELS - 1) * 9; + while (spshift >= PAGE_SHIFT) { + uint64_t spsize = 1UL << spshift; + if ((page_sizes_mask & spsize) != 0 && + (gpa & (spsize - 1)) == 0 && + (hpa & (spsize - 1)) == 0 && + length >= spsize) { + break; + } + spshift -= 9; + } + + if (spshift < PAGE_SHIFT) { + panic("Invalid spshift for gpa 0x%016lx, hpa 0x%016lx, " + "length 0x%016lx, page_sizes_mask 0x%016lx", + gpa, hpa, length, page_sizes_mask); + } + + nlevels = EPT_PWLEVELS; + while (--nlevels >= 0) { + ptpshift = PAGE_SHIFT + nlevels * 9; + ptpindex = (gpa >> ptpshift) & 0x1FF; + + /* We have reached the leaf mapping */ + if (spshift >= ptpshift) + break; + + /* + * We are working on a non-leaf page table page. + * + * Create the next level page table page if necessary and point + * to it from the current page table. + */ + if (ptp[ptpindex] == 0) { + void *nlp = malloc(PAGE_SIZE, M_VMX, M_WAITOK | M_ZERO); + ptp[ptpindex] = vtophys(nlp); + ptp[ptpindex] |= EPT_PG_RD | EPT_PG_WR | EPT_PG_EX; + } + + /* Work our way down to the next level page table page */ + ptp = (uint64_t *)PHYS_TO_DMAP(ptp[ptpindex] & EPT_ADDR_MASK); + } + + if ((gpa & ((1UL << ptpshift) - 1)) != 0) { + panic("ept_create_mapping: gpa 0x%016lx and ptpshift %d " + "mismatch\n", gpa, ptpshift); + } + + /* Do the mapping */ + ptp[ptpindex] = hpa; + + /* Apply the access controls */ + if (prot & VM_PROT_READ) + ptp[ptpindex] |= EPT_PG_RD; + if (prot & VM_PROT_WRITE) + ptp[ptpindex] |= EPT_PG_WR; + if (prot & VM_PROT_EXECUTE) + ptp[ptpindex] |= EPT_PG_EX; + + /* + * XXX should we enforce this memory type by setting the ignore PAT + * bit to 1. + */ + ptp[ptpindex] |= EPT_PG_MEMORY_TYPE(attr); + + if (nlevels > 0) + ptp[ptpindex] |= EPT_PG_SUPERPAGE; + + return (1UL << ptpshift); +} + +static void +ept_free_pt_entry(pt_entry_t pte) +{ + if (pte == 0) + return; + + /* sanity check */ + if ((pte & EPT_PG_SUPERPAGE) != 0) + panic("ept_free_pt_entry: pte cannot have superpage bit"); + + return; +} + +static void +ept_free_pd_entry(pd_entry_t pde) +{ + pt_entry_t *pt; + int i; + + if (pde == 0) + return; + + if ((pde & EPT_PG_SUPERPAGE) == 0) { + pt = (pt_entry_t *)PHYS_TO_DMAP(pde & EPT_ADDR_MASK); + for (i = 0; i < NPTEPG; i++) + ept_free_pt_entry(pt[i]); + free(pt, M_VMX); /* free the page table page */ + } +} + +static void +ept_free_pdp_entry(pdp_entry_t pdpe) +{ + pd_entry_t *pd; + int i; + + if (pdpe == 0) + return; + + if ((pdpe & EPT_PG_SUPERPAGE) == 0) { + pd = (pd_entry_t *)PHYS_TO_DMAP(pdpe & EPT_ADDR_MASK); + for (i = 0; i < NPDEPG; i++) + ept_free_pd_entry(pd[i]); + free(pd, M_VMX); /* free the page directory page */ + } +} + +static void +ept_free_pml4_entry(pml4_entry_t pml4e) +{ + pdp_entry_t *pdp; + int i; + + if (pml4e == 0) + return; + + if ((pml4e & EPT_PG_SUPERPAGE) == 0) { + pdp = (pdp_entry_t *)PHYS_TO_DMAP(pml4e & EPT_ADDR_MASK); + for (i = 0; i < NPDPEPG; i++) + ept_free_pdp_entry(pdp[i]); + free(pdp, M_VMX); /* free the page directory ptr page */ + } +} + +void +ept_vmcleanup(struct vmx *vmx) +{ + int i; + + for (i = 0; i < NPML4EPG; i++) + ept_free_pml4_entry(vmx->pml4ept[i]); +} + +int +ept_vmmmap(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, size_t len, + vm_memattr_t attr, int prot, boolean_t spok) +{ + size_t n; + struct vmx *vmx = arg; + + while (len > 0) { + n = ept_create_mapping(vmx->pml4ept, gpa, hpa, len, attr, + prot, spok); + len -= n; + gpa += n; + hpa += n; + } + + return (0); +} + +static void +invept_single_context(void *arg) +{ + struct invept_desc desc = *(struct invept_desc *)arg; + + invept(INVEPT_TYPE_SINGLE_CONTEXT, desc); +} + +void +ept_invalidate_mappings(u_long pml4ept) +{ + struct invept_desc invept_desc = { 0 }; + + invept_desc.eptp = EPTP(pml4ept); + + smp_rendezvous(NULL, invept_single_context, NULL, &invept_desc); +} diff --git a/sys/amd64/vmm/intel/ept.h b/sys/amd64/vmm/intel/ept.h new file mode 100644 index 00000000000..013c330ed41 --- /dev/null +++ b/sys/amd64/vmm/intel/ept.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _EPT_H_ +#define _EPT_H_ + +struct vmx; + +#define EPT_PWLEVELS 4 /* page walk levels */ +#define EPTP(pml4) ((pml4) | (EPT_PWLEVELS - 1) << 3 | PAT_WRITE_BACK) + +int ept_init(void); +int ept_vmmmap(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, size_t length, + vm_memattr_t attr, int prot, boolean_t allow_superpage_mappings); +void ept_invalidate_mappings(u_long ept_pml4); +void ept_vmcleanup(struct vmx *vmx); +#endif diff --git a/sys/amd64/vmm/intel/vmcs.c b/sys/amd64/vmm/intel/vmcs.c new file mode 100644 index 00000000000..80d45ccebb2 --- /dev/null +++ b/sys/amd64/vmm/intel/vmcs.c @@ -0,0 +1,451 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include "vmcs.h" +#include "vmx_cpufunc.h" +#include "ept.h" +#include "vmx.h" + +static uint64_t +vmcs_fix_regval(uint32_t encoding, uint64_t val) +{ + + switch (encoding) { + case VMCS_GUEST_CR0: + val = vmx_fix_cr0(val); + break; + case VMCS_GUEST_CR4: + val = vmx_fix_cr4(val); + break; + default: + break; + } + return (val); +} + +static uint32_t +vmcs_field_encoding(int ident) +{ + switch (ident) { + case VM_REG_GUEST_CR0: + return (VMCS_GUEST_CR0); + case VM_REG_GUEST_CR3: + return (VMCS_GUEST_CR3); + case VM_REG_GUEST_CR4: + return (VMCS_GUEST_CR4); + case VM_REG_GUEST_DR7: + return (VMCS_GUEST_DR7); + case VM_REG_GUEST_RSP: + return (VMCS_GUEST_RSP); + case VM_REG_GUEST_RIP: + return (VMCS_GUEST_RIP); + case VM_REG_GUEST_RFLAGS: + return (VMCS_GUEST_RFLAGS); + case VM_REG_GUEST_ES: + return (VMCS_GUEST_ES_SELECTOR); + case VM_REG_GUEST_CS: + return (VMCS_GUEST_CS_SELECTOR); + case VM_REG_GUEST_SS: + return (VMCS_GUEST_SS_SELECTOR); + case VM_REG_GUEST_DS: + return (VMCS_GUEST_DS_SELECTOR); + case VM_REG_GUEST_FS: + return (VMCS_GUEST_FS_SELECTOR); + case VM_REG_GUEST_GS: + return (VMCS_GUEST_GS_SELECTOR); + case VM_REG_GUEST_TR: + return (VMCS_GUEST_TR_SELECTOR); + case VM_REG_GUEST_LDTR: + return (VMCS_GUEST_LDTR_SELECTOR); + case VM_REG_GUEST_EFER: + return (VMCS_GUEST_IA32_EFER); + default: + return (-1); + } + +} + +static int +vmcs_seg_desc_encoding(int seg, uint32_t *base, uint32_t *lim, uint32_t *acc) +{ + + switch (seg) { + case VM_REG_GUEST_ES: + *base = VMCS_GUEST_ES_BASE; + *lim = VMCS_GUEST_ES_LIMIT; + *acc = VMCS_GUEST_ES_ACCESS_RIGHTS; + break; + case VM_REG_GUEST_CS: + *base = VMCS_GUEST_CS_BASE; + *lim = VMCS_GUEST_CS_LIMIT; + *acc = VMCS_GUEST_CS_ACCESS_RIGHTS; + break; + case VM_REG_GUEST_SS: + *base = VMCS_GUEST_SS_BASE; + *lim = VMCS_GUEST_SS_LIMIT; + *acc = VMCS_GUEST_SS_ACCESS_RIGHTS; + break; + case VM_REG_GUEST_DS: + *base = VMCS_GUEST_DS_BASE; + *lim = VMCS_GUEST_DS_LIMIT; + *acc = VMCS_GUEST_DS_ACCESS_RIGHTS; + break; + case VM_REG_GUEST_FS: + *base = VMCS_GUEST_FS_BASE; + *lim = VMCS_GUEST_FS_LIMIT; + *acc = VMCS_GUEST_FS_ACCESS_RIGHTS; + break; + case VM_REG_GUEST_GS: + *base = VMCS_GUEST_GS_BASE; + *lim = VMCS_GUEST_GS_LIMIT; + *acc = VMCS_GUEST_GS_ACCESS_RIGHTS; + break; + case VM_REG_GUEST_TR: + *base = VMCS_GUEST_TR_BASE; + *lim = VMCS_GUEST_TR_LIMIT; + *acc = VMCS_GUEST_TR_ACCESS_RIGHTS; + break; + case VM_REG_GUEST_LDTR: + *base = VMCS_GUEST_LDTR_BASE; + *lim = VMCS_GUEST_LDTR_LIMIT; + *acc = VMCS_GUEST_LDTR_ACCESS_RIGHTS; + break; + case VM_REG_GUEST_IDTR: + *base = VMCS_GUEST_IDTR_BASE; + *lim = VMCS_GUEST_IDTR_LIMIT; + *acc = VMCS_INVALID_ENCODING; + break; + case VM_REG_GUEST_GDTR: + *base = VMCS_GUEST_GDTR_BASE; + *lim = VMCS_GUEST_GDTR_LIMIT; + *acc = VMCS_INVALID_ENCODING; + break; + default: + return (EINVAL); + } + + return (0); +} + +int +vmcs_getreg(struct vmcs *vmcs, int ident, uint64_t *retval) +{ + int error; + uint32_t encoding; + + /* + * If we need to get at vmx-specific state in the VMCS we can bypass + * the translation of 'ident' to 'encoding' by simply setting the + * sign bit. As it so happens the upper 16 bits are reserved (i.e + * set to 0) in the encodings for the VMCS so we are free to use the + * sign bit. + */ + if (ident < 0) + encoding = ident & 0x7fffffff; + else + encoding = vmcs_field_encoding(ident); + + if (encoding == (uint32_t)-1) + return (EINVAL); + + VMPTRLD(vmcs); + error = vmread(encoding, retval); + VMCLEAR(vmcs); + return (error); +} + +int +vmcs_setreg(struct vmcs *vmcs, int ident, uint64_t val) +{ + int error; + uint32_t encoding; + + if (ident < 0) + encoding = ident & 0x7fffffff; + else + encoding = vmcs_field_encoding(ident); + + if (encoding == (uint32_t)-1) + return (EINVAL); + + val = vmcs_fix_regval(encoding, val); + + VMPTRLD(vmcs); + error = vmwrite(encoding, val); + VMCLEAR(vmcs); + return (error); +} + +int +vmcs_setdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc) +{ + int error; + uint32_t base, limit, access; + + error = vmcs_seg_desc_encoding(seg, &base, &limit, &access); + if (error != 0) + panic("vmcs_setdesc: invalid segment register %d", seg); + + VMPTRLD(vmcs); + if ((error = vmwrite(base, desc->base)) != 0) + goto done; + + if ((error = vmwrite(limit, desc->limit)) != 0) + goto done; + + if (access != VMCS_INVALID_ENCODING) { + if ((error = vmwrite(access, desc->access)) != 0) + goto done; + } +done: + VMCLEAR(vmcs); + return (error); +} + +int +vmcs_getdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc) +{ + int error; + uint32_t base, limit, access; + uint64_t u64; + + error = vmcs_seg_desc_encoding(seg, &base, &limit, &access); + if (error != 0) + panic("vmcs_getdesc: invalid segment register %d", seg); + + VMPTRLD(vmcs); + if ((error = vmread(base, &u64)) != 0) + goto done; + desc->base = u64; + + if ((error = vmread(limit, &u64)) != 0) + goto done; + desc->limit = u64; + + if (access != VMCS_INVALID_ENCODING) { + if ((error = vmread(access, &u64)) != 0) + goto done; + desc->access = u64; + } +done: + VMCLEAR(vmcs); + return (error); +} + +int +vmcs_set_msr_save(struct vmcs *vmcs, u_long g_area, u_int g_count) +{ + int error; + + VMPTRLD(vmcs); + + /* + * Guest MSRs are saved in the VM-exit MSR-store area. + * Guest MSRs are loaded from the VM-entry MSR-load area. + * Both areas point to the same location in memory. + */ + if ((error = vmwrite(VMCS_EXIT_MSR_STORE, g_area)) != 0) + goto done; + if ((error = vmwrite(VMCS_EXIT_MSR_STORE_COUNT, g_count)) != 0) + goto done; + + if ((error = vmwrite(VMCS_ENTRY_MSR_LOAD, g_area)) != 0) + goto done; + if ((error = vmwrite(VMCS_ENTRY_MSR_LOAD_COUNT, g_count)) != 0) + goto done; + + error = 0; +done: + VMCLEAR(vmcs); + return (error); +} + +int +vmcs_set_defaults(struct vmcs *vmcs, + u_long host_rip, u_long host_rsp, u_long ept_pml4, + uint32_t pinbased_ctls, uint32_t procbased_ctls, + uint32_t procbased_ctls2, uint32_t exit_ctls, + uint32_t entry_ctls, u_long msr_bitmap, uint16_t vpid) +{ + int error, codesel, datasel, tsssel; + u_long cr0, cr4, efer; + uint64_t eptp, pat; + uint32_t exc_bitmap; + + codesel = GSEL(GCODE_SEL, SEL_KPL); + datasel = GSEL(GDATA_SEL, SEL_KPL); + tsssel = GSEL(GPROC0_SEL, SEL_KPL); + + /* + * Make sure we have a "current" VMCS to work with. + */ + VMPTRLD(vmcs); + + /* + * Load the VMX controls + */ + if ((error = vmwrite(VMCS_PIN_BASED_CTLS, pinbased_ctls)) != 0) + goto done; + if ((error = vmwrite(VMCS_PRI_PROC_BASED_CTLS, procbased_ctls)) != 0) + goto done; + if ((error = vmwrite(VMCS_SEC_PROC_BASED_CTLS, procbased_ctls2)) != 0) + goto done; + if ((error = vmwrite(VMCS_EXIT_CTLS, exit_ctls)) != 0) + goto done; + if ((error = vmwrite(VMCS_ENTRY_CTLS, entry_ctls)) != 0) + goto done; + + /* Guest state */ + + /* Initialize guest IA32_PAT MSR with the default value */ + pat = PAT_VALUE(0, PAT_WRITE_BACK) | + PAT_VALUE(1, PAT_WRITE_THROUGH) | + PAT_VALUE(2, PAT_UNCACHED) | + PAT_VALUE(3, PAT_UNCACHEABLE) | + PAT_VALUE(4, PAT_WRITE_BACK) | + PAT_VALUE(5, PAT_WRITE_THROUGH) | + PAT_VALUE(6, PAT_UNCACHED) | + PAT_VALUE(7, PAT_UNCACHEABLE); + if ((error = vmwrite(VMCS_GUEST_IA32_PAT, pat)) != 0) + goto done; + + /* Host state */ + + /* Initialize host IA32_PAT MSR */ + pat = rdmsr(MSR_PAT); + if ((error = vmwrite(VMCS_HOST_IA32_PAT, pat)) != 0) + goto done; + + /* Load the IA32_EFER MSR */ + efer = rdmsr(MSR_EFER); + if ((error = vmwrite(VMCS_HOST_IA32_EFER, efer)) != 0) + goto done; + + /* Load the control registers */ + cr0 = rcr0(); + if ((error = vmwrite(VMCS_HOST_CR0, cr0)) != 0) + goto done; + + cr4 = rcr4(); + if ((error = vmwrite(VMCS_HOST_CR4, cr4)) != 0) + goto done; + + /* Load the segment selectors */ + if ((error = vmwrite(VMCS_HOST_ES_SELECTOR, datasel)) != 0) + goto done; + + if ((error = vmwrite(VMCS_HOST_CS_SELECTOR, codesel)) != 0) + goto done; + + if ((error = vmwrite(VMCS_HOST_SS_SELECTOR, datasel)) != 0) + goto done; + + if ((error = vmwrite(VMCS_HOST_DS_SELECTOR, datasel)) != 0) + goto done; + + if ((error = vmwrite(VMCS_HOST_FS_SELECTOR, datasel)) != 0) + goto done; + + if ((error = vmwrite(VMCS_HOST_GS_SELECTOR, datasel)) != 0) + goto done; + + if ((error = vmwrite(VMCS_HOST_TR_SELECTOR, tsssel)) != 0) + goto done; + + /* + * Load the Base-Address for %fs and idtr. + * + * Note that we exclude %gs, tss and gdtr here because their base + * address is pcpu specific. + */ + if ((error = vmwrite(VMCS_HOST_FS_BASE, 0)) != 0) + goto done; + + if ((error = vmwrite(VMCS_HOST_IDTR_BASE, r_idt.rd_base)) != 0) + goto done; + + /* instruction pointer */ + if ((error = vmwrite(VMCS_HOST_RIP, host_rip)) != 0) + goto done; + + /* stack pointer */ + if ((error = vmwrite(VMCS_HOST_RSP, host_rsp)) != 0) + goto done; + + /* eptp */ + eptp = EPTP(ept_pml4); + if ((error = vmwrite(VMCS_EPTP, eptp)) != 0) + goto done; + + /* vpid */ + if ((error = vmwrite(VMCS_VPID, vpid)) != 0) + goto done; + + /* msr bitmap */ + if ((error = vmwrite(VMCS_MSR_BITMAP, msr_bitmap)) != 0) + goto done; + + /* exception bitmap */ + exc_bitmap = 1 << IDT_MC; + if ((error = vmwrite(VMCS_EXCEPTION_BITMAP, exc_bitmap)) != 0) + goto done; + + /* link pointer */ + if ((error = vmwrite(VMCS_LINK_POINTER, ~0)) != 0) + goto done; +done: + VMCLEAR(vmcs); + return (error); +} + +uint64_t +vmcs_read(uint32_t encoding) +{ + int error; + uint64_t val; + + error = vmread(encoding, &val); + if (error != 0) + panic("vmcs_read(%u) error %d", encoding, error); + + return (val); +} diff --git a/sys/amd64/vmm/intel/vmcs.h b/sys/amd64/vmm/intel/vmcs.h new file mode 100644 index 00000000000..c633a5957a0 --- /dev/null +++ b/sys/amd64/vmm/intel/vmcs.h @@ -0,0 +1,324 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMCS_H_ +#define _VMCS_H_ + +#ifdef _KERNEL +struct vmcs { + uint32_t identifier; + uint32_t abort_code; + char _impl_specific[PAGE_SIZE - sizeof(uint32_t) * 2]; +}; +CTASSERT(sizeof(struct vmcs) == PAGE_SIZE); + +/* MSR save region is composed of an array of 'struct msr_entry' */ +struct msr_entry { + uint32_t index; + uint32_t reserved; + uint64_t val; + +}; + +int vmcs_set_msr_save(struct vmcs *vmcs, u_long g_area, u_int g_count); +int vmcs_set_defaults(struct vmcs *vmcs, u_long host_rip, u_long host_rsp, + u_long ept_pml4, + uint32_t pinbased_ctls, uint32_t procbased_ctls, + uint32_t procbased_ctls2, uint32_t exit_ctls, + uint32_t entry_ctls, u_long msr_bitmap, + uint16_t vpid); +int vmcs_getreg(struct vmcs *vmcs, int ident, uint64_t *retval); +int vmcs_setreg(struct vmcs *vmcs, int ident, uint64_t val); +int vmcs_getdesc(struct vmcs *vmcs, int ident, + struct seg_desc *desc); +int vmcs_setdesc(struct vmcs *vmcs, int ident, + struct seg_desc *desc); +uint64_t vmcs_read(uint32_t encoding); + +#define vmexit_instruction_length() vmcs_read(VMCS_EXIT_INSTRUCTION_LENGTH) +#define vmcs_guest_rip() vmcs_read(VMCS_GUEST_RIP) +#define vmcs_instruction_error() vmcs_read(VMCS_INSTRUCTION_ERROR) +#define vmcs_exit_reason() (vmcs_read(VMCS_EXIT_REASON) & 0xffff) +#define vmcs_exit_qualification() vmcs_read(VMCS_EXIT_QUALIFICATION) + +#endif /* _KERNEL */ + +#define VMCS_IDENT(encoding) ((encoding) | 0x80000000) +/* + * VMCS field encodings from Appendix H, Intel Architecture Manual Vol3B. + */ +#define VMCS_INVALID_ENCODING 0xffffffff + +/* 16-bit control fields */ +#define VMCS_VPID 0x00000000 + +/* 16-bit guest-state fields */ +#define VMCS_GUEST_ES_SELECTOR 0x00000800 +#define VMCS_GUEST_CS_SELECTOR 0x00000802 +#define VMCS_GUEST_SS_SELECTOR 0x00000804 +#define VMCS_GUEST_DS_SELECTOR 0x00000806 +#define VMCS_GUEST_FS_SELECTOR 0x00000808 +#define VMCS_GUEST_GS_SELECTOR 0x0000080A +#define VMCS_GUEST_LDTR_SELECTOR 0x0000080C +#define VMCS_GUEST_TR_SELECTOR 0x0000080E + +/* 16-bit host-state fields */ +#define VMCS_HOST_ES_SELECTOR 0x00000C00 +#define VMCS_HOST_CS_SELECTOR 0x00000C02 +#define VMCS_HOST_SS_SELECTOR 0x00000C04 +#define VMCS_HOST_DS_SELECTOR 0x00000C06 +#define VMCS_HOST_FS_SELECTOR 0x00000C08 +#define VMCS_HOST_GS_SELECTOR 0x00000C0A +#define VMCS_HOST_TR_SELECTOR 0x00000C0C + +/* 64-bit control fields */ +#define VMCS_IO_BITMAP_A 0x00002000 +#define VMCS_IO_BITMAP_B 0x00002002 +#define VMCS_MSR_BITMAP 0x00002004 +#define VMCS_EXIT_MSR_STORE 0x00002006 +#define VMCS_EXIT_MSR_LOAD 0x00002008 +#define VMCS_ENTRY_MSR_LOAD 0x0000200A +#define VMCS_EXECUTIVE_VMCS 0x0000200C +#define VMCS_TSC_OFFSET 0x00002010 +#define VMCS_VIRTUAL_APIC 0x00002012 +#define VMCS_APIC_ACCESS 0x00002014 +#define VMCS_EPTP 0x0000201A + +/* 64-bit read-only fields */ +#define VMCS_GUEST_PHYSICAL_ADDRESS 0x00002400 + +/* 64-bit guest-state fields */ +#define VMCS_LINK_POINTER 0x00002800 +#define VMCS_GUEST_IA32_DEBUGCTL 0x00002802 +#define VMCS_GUEST_IA32_PAT 0x00002804 +#define VMCS_GUEST_IA32_EFER 0x00002806 +#define VMCS_GUEST_IA32_PERF_GLOBAL_CTRL 0x00002808 +#define VMCS_GUEST_PDPTE0 0x0000280A +#define VMCS_GUEST_PDPTE1 0x0000280C +#define VMCS_GUEST_PDPTE2 0x0000280E +#define VMCS_GUEST_PDPTE3 0x00002810 + +/* 64-bit host-state fields */ +#define VMCS_HOST_IA32_PAT 0x00002C00 +#define VMCS_HOST_IA32_EFER 0x00002C02 +#define VMCS_HOST_IA32_PERF_GLOBAL_CTRL 0x00002C04 + +/* 32-bit control fields */ +#define VMCS_PIN_BASED_CTLS 0x00004000 +#define VMCS_PRI_PROC_BASED_CTLS 0x00004002 +#define VMCS_EXCEPTION_BITMAP 0x00004004 +#define VMCS_PF_ERROR_MASK 0x00004006 +#define VMCS_PF_ERROR_MATCH 0x00004008 +#define VMCS_CR3_TARGET_COUNT 0x0000400A +#define VMCS_EXIT_CTLS 0x0000400C +#define VMCS_EXIT_MSR_STORE_COUNT 0x0000400E +#define VMCS_EXIT_MSR_LOAD_COUNT 0x00004010 +#define VMCS_ENTRY_CTLS 0x00004012 +#define VMCS_ENTRY_MSR_LOAD_COUNT 0x00004014 +#define VMCS_ENTRY_INTR_INFO 0x00004016 +#define VMCS_ENTRY_EXCEPTION_ERROR 0x00004018 +#define VMCS_ENTRY_INST_LENGTH 0x0000401A +#define VMCS_TPR_THRESHOLD 0x0000401C +#define VMCS_SEC_PROC_BASED_CTLS 0x0000401E +#define VMCS_PLE_GAP 0x00004020 +#define VMCS_PLE_WINDOW 0x00004022 + +/* 32-bit read-only data fields */ +#define VMCS_INSTRUCTION_ERROR 0x00004400 +#define VMCS_EXIT_REASON 0x00004402 +#define VMCS_EXIT_INTERRUPTION_INFO 0x00004404 +#define VMCS_EXIT_INTERRUPTION_ERROR 0x00004406 +#define VMCS_IDT_VECTORING_INFO 0x00004408 +#define VMCS_IDT_VECTORING_ERROR 0x0000440A +#define VMCS_EXIT_INSTRUCTION_LENGTH 0x0000440C +#define VMCS_EXIT_INSTRUCTION_INFO 0x0000440E + +/* 32-bit guest-state fields */ +#define VMCS_GUEST_ES_LIMIT 0x00004800 +#define VMCS_GUEST_CS_LIMIT 0x00004802 +#define VMCS_GUEST_SS_LIMIT 0x00004804 +#define VMCS_GUEST_DS_LIMIT 0x00004806 +#define VMCS_GUEST_FS_LIMIT 0x00004808 +#define VMCS_GUEST_GS_LIMIT 0x0000480A +#define VMCS_GUEST_LDTR_LIMIT 0x0000480C +#define VMCS_GUEST_TR_LIMIT 0x0000480E +#define VMCS_GUEST_GDTR_LIMIT 0x00004810 +#define VMCS_GUEST_IDTR_LIMIT 0x00004812 +#define VMCS_GUEST_ES_ACCESS_RIGHTS 0x00004814 +#define VMCS_GUEST_CS_ACCESS_RIGHTS 0x00004816 +#define VMCS_GUEST_SS_ACCESS_RIGHTS 0x00004818 +#define VMCS_GUEST_DS_ACCESS_RIGHTS 0x0000481A +#define VMCS_GUEST_FS_ACCESS_RIGHTS 0x0000481C +#define VMCS_GUEST_GS_ACCESS_RIGHTS 0x0000481E +#define VMCS_GUEST_LDTR_ACCESS_RIGHTS 0x00004820 +#define VMCS_GUEST_TR_ACCESS_RIGHTS 0x00004822 +#define VMCS_GUEST_INTERRUPTIBILITY 0x00004824 +#define VMCS_GUEST_ACTIVITY 0x00004826 +#define VMCS_GUEST_SMBASE 0x00004828 +#define VMCS_GUEST_IA32_SYSENTER_CS 0x0000482A +#define VMCS_PREEMPTION_TIMER_VALUE 0x0000482E + +/* 32-bit host state fields */ +#define VMCS_HOST_IA32_SYSENTER_CS 0x00004C00 + +/* Natural Width control fields */ +#define VMCS_CR0_MASK 0x00006000 +#define VMCS_CR4_MASK 0x00006002 +#define VMCS_CR0_SHADOW 0x00006004 +#define VMCS_CR4_SHADOW 0x00006006 +#define VMCS_CR3_TARGET0 0x00006008 +#define VMCS_CR3_TARGET1 0x0000600A +#define VMCS_CR3_TARGET2 0x0000600C +#define VMCS_CR3_TARGET3 0x0000600E + +/* Natural Width read-only fields */ +#define VMCS_EXIT_QUALIFICATION 0x00006400 +#define VMCS_IO_RCX 0x00006402 +#define VMCS_IO_RSI 0x00006404 +#define VMCS_IO_RDI 0x00006406 +#define VMCS_IO_RIP 0x00006408 +#define VMCS_GUEST_LINEAR_ADDRESS 0x0000640A + +/* Natural Width guest-state fields */ +#define VMCS_GUEST_CR0 0x00006800 +#define VMCS_GUEST_CR3 0x00006802 +#define VMCS_GUEST_CR4 0x00006804 +#define VMCS_GUEST_ES_BASE 0x00006806 +#define VMCS_GUEST_CS_BASE 0x00006808 +#define VMCS_GUEST_SS_BASE 0x0000680A +#define VMCS_GUEST_DS_BASE 0x0000680C +#define VMCS_GUEST_FS_BASE 0x0000680E +#define VMCS_GUEST_GS_BASE 0x00006810 +#define VMCS_GUEST_LDTR_BASE 0x00006812 +#define VMCS_GUEST_TR_BASE 0x00006814 +#define VMCS_GUEST_GDTR_BASE 0x00006816 +#define VMCS_GUEST_IDTR_BASE 0x00006818 +#define VMCS_GUEST_DR7 0x0000681A +#define VMCS_GUEST_RSP 0x0000681C +#define VMCS_GUEST_RIP 0x0000681E +#define VMCS_GUEST_RFLAGS 0x00006820 +#define VMCS_GUEST_PENDING_DBG_EXCEPTIONS 0x00006822 +#define VMCS_GUEST_IA32_SYSENTER_ESP 0x00006824 +#define VMCS_GUEST_IA32_SYSENTER_EIP 0x00006826 + +/* Natural Width host-state fields */ +#define VMCS_HOST_CR0 0x00006C00 +#define VMCS_HOST_CR3 0x00006C02 +#define VMCS_HOST_CR4 0x00006C04 +#define VMCS_HOST_FS_BASE 0x00006C06 +#define VMCS_HOST_GS_BASE 0x00006C08 +#define VMCS_HOST_TR_BASE 0x00006C0A +#define VMCS_HOST_GDTR_BASE 0x00006C0C +#define VMCS_HOST_IDTR_BASE 0x00006C0E +#define VMCS_HOST_IA32_SYSENTER_ESP 0x00006C10 +#define VMCS_HOST_IA32_SYSENTER_EIP 0x00006C12 +#define VMCS_HOST_RSP 0x00006C14 +#define VMCS_HOST_RIP 0x00006c16 + +/* + * VM instruction error numbers + */ +#define VMRESUME_WITH_NON_LAUNCHED_VMCS 5 + +/* + * VMCS exit reasons + */ +#define EXIT_REASON_EXCEPTION 0 +#define EXIT_REASON_EXT_INTR 1 +#define EXIT_REASON_TRIPLE_FAULT 2 +#define EXIT_REASON_INIT 3 +#define EXIT_REASON_SIPI 4 +#define EXIT_REASON_IO_SMI 5 +#define EXIT_REASON_SMI 6 +#define EXIT_REASON_INTR_WINDOW 7 +#define EXIT_REASON_NMI_WINDOW 8 +#define EXIT_REASON_TASK_SWITCH 9 +#define EXIT_REASON_CPUID 10 +#define EXIT_REASON_GETSEC 11 +#define EXIT_REASON_HLT 12 +#define EXIT_REASON_INVD 13 +#define EXIT_REASON_INVLPG 14 +#define EXIT_REASON_RDPMC 15 +#define EXIT_REASON_RDTSC 16 +#define EXIT_REASON_RSM 17 +#define EXIT_REASON_VMCALL 18 +#define EXIT_REASON_VMCLEAR 19 +#define EXIT_REASON_VMLAUNCH 20 +#define EXIT_REASON_VMPTRLD 21 +#define EXIT_REASON_VMPTRST 22 +#define EXIT_REASON_VMREAD 23 +#define EXIT_REASON_VMRESUME 24 +#define EXIT_REASON_VMWRITE 25 +#define EXIT_REASON_VMXOFF 26 +#define EXIT_REASON_VMXON 27 +#define EXIT_REASON_CR_ACCESS 28 +#define EXIT_REASON_DR_ACCESS 29 +#define EXIT_REASON_INOUT 30 +#define EXIT_REASON_RDMSR 31 +#define EXIT_REASON_WRMSR 32 +#define EXIT_REASON_INVAL_VMCS 33 +#define EXIT_REASON_INVAL_MSR 34 +#define EXIT_REASON_MWAIT 36 +#define EXIT_REASON_MTF 37 +#define EXIT_REASON_MONITOR 39 +#define EXIT_REASON_PAUSE 40 +#define EXIT_REASON_MCE 41 +#define EXIT_REASON_TPR 43 +#define EXIT_REASON_APIC 44 +#define EXIT_REASON_GDTR_IDTR 46 +#define EXIT_REASON_LDTR_TR 47 +#define EXIT_REASON_EPT_FAULT 48 +#define EXIT_REASON_EPT_MISCONFIG 49 +#define EXIT_REASON_INVEPT 50 +#define EXIT_REASON_RDTSCP 51 +#define EXIT_REASON_VMX_PREEMPT 52 +#define EXIT_REASON_INVVPID 53 +#define EXIT_REASON_WBINVD 54 +#define EXIT_REASON_XSETBV 55 + +/* + * VMCS interrupt information fields + */ +#define VMCS_INTERRUPTION_INFO_VALID (1 << 31) +#define VMCS_INTERRUPTION_INFO_HW_INTR (0 << 8) +#define VMCS_INTERRUPTION_INFO_NMI (2 << 8) + +/* + * VMCS Guest interruptibility field + */ +#define VMCS_INTERRUPTIBILITY_STI_BLOCKING (1 << 0) +#define VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING (1 << 1) +#define VMCS_INTERRUPTIBILITY_SMI_BLOCKING (1 << 2) +#define VMCS_INTERRUPTIBILITY_NMI_BLOCKING (1 << 3) + +/* + * Exit qualification for EXIT_REASON_INVAL_VMCS + */ +#define EXIT_QUAL_NMI_WHILE_STI_BLOCKING 3 + +#endif diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c new file mode 100644 index 00000000000..ec181c40ab9 --- /dev/null +++ b/sys/amd64/vmm/intel/vmx.c @@ -0,0 +1,1673 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "vmm_lapic.h" +#include "vmm_msr.h" +#include "vmm_ktr.h" +#include "vmm_stat.h" + +#include "vmx_msr.h" +#include "ept.h" +#include "vmx_cpufunc.h" +#include "vmx.h" +#include "x86.h" +#include "vmx_controls.h" + +#define CR4_VMXE (1UL << 13) + +#define PINBASED_CTLS_ONE_SETTING \ + (PINBASED_EXTINT_EXITING | \ + PINBASED_NMI_EXITING | \ + PINBASED_VIRTUAL_NMI) +#define PINBASED_CTLS_ZERO_SETTING 0 + +#define PROCBASED_CTLS_WINDOW_SETTING \ + (PROCBASED_INT_WINDOW_EXITING | \ + PROCBASED_NMI_WINDOW_EXITING) + +#define PROCBASED_CTLS_ONE_SETTING \ + (PROCBASED_SECONDARY_CONTROLS | \ + PROCBASED_IO_EXITING | \ + PROCBASED_MSR_BITMAPS | \ + PROCBASED_CTLS_WINDOW_SETTING) +#define PROCBASED_CTLS_ZERO_SETTING \ + (PROCBASED_CR3_LOAD_EXITING | \ + PROCBASED_CR3_STORE_EXITING | \ + PROCBASED_IO_BITMAPS) + +#define PROCBASED_CTLS2_ONE_SETTING PROCBASED2_ENABLE_EPT +#define PROCBASED_CTLS2_ZERO_SETTING 0 + +#define VM_EXIT_CTLS_ONE_SETTING \ + (VM_EXIT_HOST_LMA | \ + VM_EXIT_SAVE_EFER | \ + VM_EXIT_SAVE_PAT | \ + VM_EXIT_LOAD_PAT | \ + VM_EXIT_LOAD_EFER) +#define VM_EXIT_CTLS_ZERO_SETTING VM_EXIT_SAVE_DEBUG_CONTROLS + +#define VM_ENTRY_CTLS_ONE_SETTING \ + (VM_ENTRY_LOAD_PAT | \ + VM_ENTRY_LOAD_EFER) +#define VM_ENTRY_CTLS_ZERO_SETTING \ + (VM_ENTRY_LOAD_DEBUG_CONTROLS | \ + VM_ENTRY_INTO_SMM | \ + VM_ENTRY_DEACTIVATE_DUAL_MONITOR) + +#define guest_msr_rw(vmx, msr) \ + msr_bitmap_change_access((vmx)->msr_bitmap, (msr), MSR_BITMAP_ACCESS_RW) + +#define HANDLED 1 +#define UNHANDLED 0 + +MALLOC_DEFINE(M_VMX, "vmx", "vmx"); + +extern struct pcpu __pcpu[]; + +static int vmxon_enabled[MAXCPU]; +static char vmxon_region[MAXCPU][PAGE_SIZE] __aligned(PAGE_SIZE); + +static uint32_t pinbased_ctls, procbased_ctls, procbased_ctls2; +static uint32_t exit_ctls, entry_ctls; + +static uint64_t cr0_ones_mask, cr0_zeros_mask; +static uint64_t cr4_ones_mask, cr4_zeros_mask; + +static volatile u_int nextvpid; + +/* + * Virtual NMI blocking conditions. + * + * Some processor implementations also require NMI to be blocked if + * the STI_BLOCKING bit is set. It is possible to detect this at runtime + * based on the (exit_reason,exit_qual) tuple being set to + * (EXIT_REASON_INVAL_VMCS, EXIT_QUAL_NMI_WHILE_STI_BLOCKING). + * + * We take the easy way out and also include STI_BLOCKING as one of the + * gating items for vNMI injection. + */ +static uint64_t nmi_blocking_bits = VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING | + VMCS_INTERRUPTIBILITY_NMI_BLOCKING | + VMCS_INTERRUPTIBILITY_STI_BLOCKING; + +/* + * Optional capabilities + */ +static int cap_halt_exit; +static int cap_pause_exit; +static int cap_unrestricted_guest; +static int cap_monitor_trap; + +/* statistics */ +static VMM_STAT_DEFINE(VCPU_MIGRATIONS, "vcpu migration across host cpus"); +static VMM_STAT_DEFINE(VMEXIT_EXTINT, "vm exits due to external interrupt"); + +#ifdef KTR +static const char * +exit_reason_to_str(int reason) +{ + static char reasonbuf[32]; + + switch (reason) { + case EXIT_REASON_EXCEPTION: + return "exception"; + case EXIT_REASON_EXT_INTR: + return "extint"; + case EXIT_REASON_TRIPLE_FAULT: + return "triplefault"; + case EXIT_REASON_INIT: + return "init"; + case EXIT_REASON_SIPI: + return "sipi"; + case EXIT_REASON_IO_SMI: + return "iosmi"; + case EXIT_REASON_SMI: + return "smi"; + case EXIT_REASON_INTR_WINDOW: + return "intrwindow"; + case EXIT_REASON_NMI_WINDOW: + return "nmiwindow"; + case EXIT_REASON_TASK_SWITCH: + return "taskswitch"; + case EXIT_REASON_CPUID: + return "cpuid"; + case EXIT_REASON_GETSEC: + return "getsec"; + case EXIT_REASON_HLT: + return "hlt"; + case EXIT_REASON_INVD: + return "invd"; + case EXIT_REASON_INVLPG: + return "invlpg"; + case EXIT_REASON_RDPMC: + return "rdpmc"; + case EXIT_REASON_RDTSC: + return "rdtsc"; + case EXIT_REASON_RSM: + return "rsm"; + case EXIT_REASON_VMCALL: + return "vmcall"; + case EXIT_REASON_VMCLEAR: + return "vmclear"; + case EXIT_REASON_VMLAUNCH: + return "vmlaunch"; + case EXIT_REASON_VMPTRLD: + return "vmptrld"; + case EXIT_REASON_VMPTRST: + return "vmptrst"; + case EXIT_REASON_VMREAD: + return "vmread"; + case EXIT_REASON_VMRESUME: + return "vmresume"; + case EXIT_REASON_VMWRITE: + return "vmwrite"; + case EXIT_REASON_VMXOFF: + return "vmxoff"; + case EXIT_REASON_VMXON: + return "vmxon"; + case EXIT_REASON_CR_ACCESS: + return "craccess"; + case EXIT_REASON_DR_ACCESS: + return "draccess"; + case EXIT_REASON_INOUT: + return "inout"; + case EXIT_REASON_RDMSR: + return "rdmsr"; + case EXIT_REASON_WRMSR: + return "wrmsr"; + case EXIT_REASON_INVAL_VMCS: + return "invalvmcs"; + case EXIT_REASON_INVAL_MSR: + return "invalmsr"; + case EXIT_REASON_MWAIT: + return "mwait"; + case EXIT_REASON_MTF: + return "mtf"; + case EXIT_REASON_MONITOR: + return "monitor"; + case EXIT_REASON_PAUSE: + return "pause"; + case EXIT_REASON_MCE: + return "mce"; + case EXIT_REASON_TPR: + return "tpr"; + case EXIT_REASON_APIC: + return "apic"; + case EXIT_REASON_GDTR_IDTR: + return "gdtridtr"; + case EXIT_REASON_LDTR_TR: + return "ldtrtr"; + case EXIT_REASON_EPT_FAULT: + return "eptfault"; + case EXIT_REASON_EPT_MISCONFIG: + return "eptmisconfig"; + case EXIT_REASON_INVEPT: + return "invept"; + case EXIT_REASON_RDTSCP: + return "rdtscp"; + case EXIT_REASON_VMX_PREEMPT: + return "vmxpreempt"; + case EXIT_REASON_INVVPID: + return "invvpid"; + case EXIT_REASON_WBINVD: + return "wbinvd"; + case EXIT_REASON_XSETBV: + return "xsetbv"; + default: + snprintf(reasonbuf, sizeof(reasonbuf), "%d", reason); + return (reasonbuf); + } +} + +#ifdef SETJMP_TRACE +static const char * +vmx_setjmp_rc2str(int rc) +{ + switch (rc) { + case VMX_RETURN_DIRECT: + return "direct"; + case VMX_RETURN_LONGJMP: + return "longjmp"; + case VMX_RETURN_VMRESUME: + return "vmresume"; + case VMX_RETURN_VMLAUNCH: + return "vmlaunch"; + default: + return "unknown"; + } +} + +#define SETJMP_TRACE(vmx, vcpu, vmxctx, regname) \ + VMM_CTR1((vmx)->vm, (vcpu), "setjmp trace " #regname " 0x%016lx", \ + (vmxctx)->regname) + +static void +vmx_setjmp_trace(struct vmx *vmx, int vcpu, struct vmxctx *vmxctx, int rc) +{ + uint64_t host_rip, host_rsp; + + if (vmxctx != &vmx->ctx[vcpu]) + panic("vmx_setjmp_trace: invalid vmxctx %p; should be %p", + vmxctx, &vmx->ctx[vcpu]); + + VMM_CTR1((vmx)->vm, (vcpu), "vmxctx = %p", vmxctx); + VMM_CTR2((vmx)->vm, (vcpu), "setjmp return code %s(%d)", + vmx_setjmp_rc2str(rc), rc); + + host_rsp = host_rip = ~0; + vmread(VMCS_HOST_RIP, &host_rip); + vmread(VMCS_HOST_RSP, &host_rsp); + VMM_CTR2((vmx)->vm, (vcpu), "vmcs host_rip 0x%016lx, host_rsp 0x%016lx", + host_rip, host_rsp); + + SETJMP_TRACE(vmx, vcpu, vmxctx, host_r15); + SETJMP_TRACE(vmx, vcpu, vmxctx, host_r14); + SETJMP_TRACE(vmx, vcpu, vmxctx, host_r13); + SETJMP_TRACE(vmx, vcpu, vmxctx, host_r12); + SETJMP_TRACE(vmx, vcpu, vmxctx, host_rbp); + SETJMP_TRACE(vmx, vcpu, vmxctx, host_rsp); + SETJMP_TRACE(vmx, vcpu, vmxctx, host_rbx); + SETJMP_TRACE(vmx, vcpu, vmxctx, host_rip); + + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_rdi); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_rsi); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_rdx); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_rcx); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_r8); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_r9); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_rax); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_rbx); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_rbp); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_r10); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_r11); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_r12); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_r13); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_r14); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_r15); + SETJMP_TRACE(vmx, vcpu, vmxctx, guest_cr2); +} +#endif +#else +static void __inline +vmx_setjmp_trace(struct vmx *vmx, int vcpu, struct vmxctx *vmxctx, int rc) +{ + return; +} +#endif /* KTR */ + +u_long +vmx_fix_cr0(u_long cr0) +{ + + return ((cr0 | cr0_ones_mask) & ~cr0_zeros_mask); +} + +u_long +vmx_fix_cr4(u_long cr4) +{ + + return ((cr4 | cr4_ones_mask) & ~cr4_zeros_mask); +} + +static void +msr_save_area_init(struct msr_entry *g_area, int *g_count) +{ + int cnt; + + static struct msr_entry guest_msrs[] = { + { MSR_KGSBASE, 0, 0 }, + }; + + cnt = sizeof(guest_msrs) / sizeof(guest_msrs[0]); + if (cnt > GUEST_MSR_MAX_ENTRIES) + panic("guest msr save area overrun"); + bcopy(guest_msrs, g_area, sizeof(guest_msrs)); + *g_count = cnt; +} + +static void +vmx_disable(void *arg __unused) +{ + struct invvpid_desc invvpid_desc = { 0 }; + struct invept_desc invept_desc = { 0 }; + + if (vmxon_enabled[curcpu]) { + /* + * See sections 25.3.3.3 and 25.3.3.4 in Intel Vol 3b. + * + * VMXON or VMXOFF are not required to invalidate any TLB + * caching structures. This prevents potential retention of + * cached information in the TLB between distinct VMX episodes. + */ + invvpid(INVVPID_TYPE_ALL_CONTEXTS, invvpid_desc); + invept(INVEPT_TYPE_ALL_CONTEXTS, invept_desc); + vmxoff(); + } + load_cr4(rcr4() & ~CR4_VMXE); +} + +static int +vmx_cleanup(void) +{ + + smp_rendezvous(NULL, vmx_disable, NULL, NULL); + + return (0); +} + +static void +vmx_enable(void *arg __unused) +{ + int error; + + load_cr4(rcr4() | CR4_VMXE); + + *(uint32_t *)vmxon_region[curcpu] = vmx_revision(); + error = vmxon(vmxon_region[curcpu]); + if (error == 0) + vmxon_enabled[curcpu] = 1; +} + +static int +vmx_init(void) +{ + int error; + unsigned int regs[4]; + uint64_t fixed0, fixed1; + uint32_t tmp; + + /* CPUID.1:ECX[bit 5] must be 1 for processor to support VMX */ + do_cpuid(1, regs); + if ((regs[2] & CPUID_0000_0001_FEAT0_VMX) == 0) { + printf("vmx_init: processor does not support VMX operation\n"); + return (ENXIO); + } + + /* Check support for primary processor-based VM-execution controls */ + error = vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS, + MSR_VMX_TRUE_PROCBASED_CTLS, + PROCBASED_CTLS_ONE_SETTING, + PROCBASED_CTLS_ZERO_SETTING, &procbased_ctls); + if (error) { + printf("vmx_init: processor does not support desired primary " + "processor-based controls\n"); + return (error); + } + + /* Clear the processor-based ctl bits that are set on demand */ + procbased_ctls &= ~PROCBASED_CTLS_WINDOW_SETTING; + + /* Check support for secondary processor-based VM-execution controls */ + error = vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2, + MSR_VMX_PROCBASED_CTLS2, + PROCBASED_CTLS2_ONE_SETTING, + PROCBASED_CTLS2_ZERO_SETTING, &procbased_ctls2); + if (error) { + printf("vmx_init: processor does not support desired secondary " + "processor-based controls\n"); + return (error); + } + + /* Check support for VPID */ + error = vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2, MSR_VMX_PROCBASED_CTLS2, + PROCBASED2_ENABLE_VPID, 0, &tmp); + if (error == 0) + procbased_ctls2 |= PROCBASED2_ENABLE_VPID; + + /* Check support for pin-based VM-execution controls */ + error = vmx_set_ctlreg(MSR_VMX_PINBASED_CTLS, + MSR_VMX_TRUE_PINBASED_CTLS, + PINBASED_CTLS_ONE_SETTING, + PINBASED_CTLS_ZERO_SETTING, &pinbased_ctls); + if (error) { + printf("vmx_init: processor does not support desired " + "pin-based controls\n"); + return (error); + } + + /* Check support for VM-exit controls */ + error = vmx_set_ctlreg(MSR_VMX_EXIT_CTLS, MSR_VMX_TRUE_EXIT_CTLS, + VM_EXIT_CTLS_ONE_SETTING, + VM_EXIT_CTLS_ZERO_SETTING, + &exit_ctls); + if (error) { + printf("vmx_init: processor does not support desired " + "exit controls\n"); + return (error); + } + + /* Check support for VM-entry controls */ + error = vmx_set_ctlreg(MSR_VMX_ENTRY_CTLS, MSR_VMX_TRUE_ENTRY_CTLS, + VM_ENTRY_CTLS_ONE_SETTING, + VM_ENTRY_CTLS_ZERO_SETTING, + &entry_ctls); + if (error) { + printf("vmx_init: processor does not support desired " + "entry controls\n"); + return (error); + } + + /* + * Check support for optional features by testing them + * as individual bits + */ + cap_halt_exit = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS, + MSR_VMX_TRUE_PROCBASED_CTLS, + PROCBASED_HLT_EXITING, 0, + &tmp) == 0); + + cap_monitor_trap = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS, + MSR_VMX_PROCBASED_CTLS, + PROCBASED_MTF, 0, + &tmp) == 0); + + cap_pause_exit = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS, + MSR_VMX_TRUE_PROCBASED_CTLS, + PROCBASED_PAUSE_EXITING, 0, + &tmp) == 0); + + cap_unrestricted_guest = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2, + MSR_VMX_PROCBASED_CTLS2, + PROCBASED2_UNRESTRICTED_GUEST, 0, + &tmp) == 0); + + /* Initialize EPT */ + error = ept_init(); + if (error) { + printf("vmx_init: ept initialization failed (%d)\n", error); + return (error); + } + + /* + * Stash the cr0 and cr4 bits that must be fixed to 0 or 1 + */ + fixed0 = rdmsr(MSR_VMX_CR0_FIXED0); + fixed1 = rdmsr(MSR_VMX_CR0_FIXED1); + cr0_ones_mask = fixed0 & fixed1; + cr0_zeros_mask = ~fixed0 & ~fixed1; + + /* + * CR0_PE and CR0_PG can be set to zero in VMX non-root operation + * if unrestricted guest execution is allowed. + */ + if (cap_unrestricted_guest) + cr0_ones_mask &= ~(CR0_PG | CR0_PE); + + /* + * Do not allow the guest to set CR0_NW or CR0_CD. + */ + cr0_zeros_mask |= (CR0_NW | CR0_CD); + + fixed0 = rdmsr(MSR_VMX_CR4_FIXED0); + fixed1 = rdmsr(MSR_VMX_CR4_FIXED1); + cr4_ones_mask = fixed0 & fixed1; + cr4_zeros_mask = ~fixed0 & ~fixed1; + + /* enable VMX operation */ + smp_rendezvous(NULL, vmx_enable, NULL, NULL); + + return (0); +} + +/* + * If this processor does not support VPIDs then simply return 0. + * + * Otherwise generate the next value of VPID to use. Any value is alright + * as long as it is non-zero. + * + * We always execute in VMX non-root context with EPT enabled. Thus all + * combined mappings are tagged with the (EP4TA, VPID, PCID) tuple. This + * in turn means that multiple VMs can share the same VPID as long as + * they have distinct EPT page tables. + * + * XXX + * We should optimize this so that it returns VPIDs that are not in + * use. Then we will not unnecessarily invalidate mappings in + * vmx_set_pcpu_defaults() just because two or more vcpus happen to + * use the same 'vpid'. + */ +static uint16_t +vmx_vpid(void) +{ + uint16_t vpid = 0; + + if ((procbased_ctls2 & PROCBASED2_ENABLE_VPID) != 0) { + do { + vpid = atomic_fetchadd_int(&nextvpid, 1); + } while (vpid == 0); + } + + return (vpid); +} + +static int +vmx_setup_cr0_shadow(struct vmcs *vmcs) +{ + int error; + uint64_t mask, shadow; + + mask = cr0_ones_mask | cr0_zeros_mask; + error = vmcs_setreg(vmcs, VMCS_IDENT(VMCS_CR0_MASK), mask); + if (error) + return (error); + + shadow = cr0_ones_mask; + error = vmcs_setreg(vmcs, VMCS_IDENT(VMCS_CR0_SHADOW), shadow); + if (error) + return (error); + + return (0); +} + +static void * +vmx_vminit(struct vm *vm) +{ + uint16_t vpid; + int i, error, guest_msr_count; + struct vmx *vmx; + + vmx = malloc(sizeof(struct vmx), M_VMX, M_WAITOK | M_ZERO); + if ((uintptr_t)vmx & PAGE_MASK) { + panic("malloc of struct vmx not aligned on %d byte boundary", + PAGE_SIZE); + } + vmx->vm = vm; + + /* + * Clean up EPTP-tagged guest physical and combined mappings + * + * VMX transitions are not required to invalidate any guest physical + * mappings. So, it may be possible for stale guest physical mappings + * to be present in the processor TLBs. + * + * Combined mappings for this EP4TA are also invalidated for all VPIDs. + */ + ept_invalidate_mappings(vtophys(vmx->pml4ept)); + + msr_bitmap_initialize(vmx->msr_bitmap); + + /* + * It is safe to allow direct access to MSR_GSBASE and MSR_FSBASE. + * The guest FSBASE and GSBASE are saved and restored during + * vm-exit and vm-entry respectively. The host FSBASE and GSBASE are + * always restored from the vmcs host state area on vm-exit. + * + * Guest KGSBASE is saved and restored in the guest MSR save area. + * Host KGSBASE is restored before returning to userland from the pcb. + * There will be a window of time when we are executing in the host + * kernel context with a value of KGSBASE from the guest. This is ok + * because the value of KGSBASE is inconsequential in kernel context. + * + * MSR_EFER is saved and restored in the guest VMCS area on a + * VM exit and entry respectively. It is also restored from the + * host VMCS area on a VM exit. + * + * MSR_PAT is saved and restored in the guest VMCS are on a VM exit + * and entry respectively. It is also restored from the host VMCS + * area on a VM exit. + */ + if (guest_msr_rw(vmx, MSR_GSBASE) || + guest_msr_rw(vmx, MSR_FSBASE) || + guest_msr_rw(vmx, MSR_KGSBASE) || + guest_msr_rw(vmx, MSR_EFER) || + guest_msr_rw(vmx, MSR_PAT)) + panic("vmx_vminit: error setting guest msr access"); + + for (i = 0; i < VM_MAXCPU; i++) { + vmx->vmcs[i].identifier = vmx_revision(); + error = vmclear(&vmx->vmcs[i]); + if (error != 0) { + panic("vmx_vminit: vmclear error %d on vcpu %d\n", + error, i); + } + + vpid = vmx_vpid(); + + error = vmcs_set_defaults(&vmx->vmcs[i], + (u_long)vmx_longjmp, + (u_long)&vmx->ctx[i], + vtophys(vmx->pml4ept), + pinbased_ctls, + procbased_ctls, + procbased_ctls2, + exit_ctls, entry_ctls, + vtophys(vmx->msr_bitmap), + vpid); + + if (error != 0) + panic("vmx_vminit: vmcs_set_defaults error %d", error); + + vmx->cap[i].set = 0; + vmx->cap[i].proc_ctls = procbased_ctls; + + vmx->state[i].request_nmi = 0; + vmx->state[i].lastcpu = -1; + vmx->state[i].vpid = vpid; + + msr_save_area_init(vmx->guest_msrs[i], &guest_msr_count); + + error = vmcs_set_msr_save(&vmx->vmcs[i], + vtophys(vmx->guest_msrs[i]), + guest_msr_count); + if (error != 0) + panic("vmcs_set_msr_save error %d", error); + + error = vmx_setup_cr0_shadow(&vmx->vmcs[i]); + } + + return (vmx); +} + +static int +vmx_handle_cpuid(struct vmxctx *vmxctx) +{ + int handled, func; + + func = vmxctx->guest_rax; + + handled = x86_emulate_cpuid((uint32_t*)(&vmxctx->guest_rax), + (uint32_t*)(&vmxctx->guest_rbx), (uint32_t*)(&vmxctx->guest_rcx), + (uint32_t*)(&vmxctx->guest_rdx)); +#if 0 + printf("%s: func %x rax %lx rbx %lx rcx %lx rdx %lx handled %d\n", + __func__, func, vmxctx->guest_rax, vmxctx->guest_rbx, + vmxctx->guest_rcx, vmxctx->guest_rdx, handled); +#endif + + return (handled); +} + +static __inline void +vmx_run_trace(struct vmx *vmx, int vcpu) +{ +#ifdef KTR + VMM_CTR1(vmx->vm, vcpu, "Resume execution at 0x%0lx", vmcs_guest_rip()); +#endif +} + +static __inline void +vmx_exit_trace(struct vmx *vmx, int vcpu, uint64_t rip, uint32_t exit_reason, + int handled, int astpending) +{ +#ifdef KTR + VMM_CTR3(vmx->vm, vcpu, "%s %s vmexit at 0x%0lx", + handled ? "handled" : "unhandled", + exit_reason_to_str(exit_reason), rip); + + if (astpending) + VMM_CTR0(vmx->vm, vcpu, "astpending"); +#endif +} + +static int +vmx_set_pcpu_defaults(struct vmx *vmx, int vcpu) +{ + int error, lastcpu; + struct vmxstate *vmxstate; + struct invvpid_desc invvpid_desc = { 0 }; + + vmxstate = &vmx->state[vcpu]; + lastcpu = vmxstate->lastcpu; + vmxstate->lastcpu = curcpu; + + if (lastcpu == curcpu) { + error = 0; + goto done; + } + + vmm_stat_incr(vmx->vm, vcpu, VCPU_MIGRATIONS, 1); + + error = vmwrite(VMCS_HOST_TR_BASE, (u_long)PCPU_GET(tssp)); + if (error != 0) + goto done; + + error = vmwrite(VMCS_HOST_GDTR_BASE, (u_long)&gdt[NGDT * curcpu]); + if (error != 0) + goto done; + + error = vmwrite(VMCS_HOST_GS_BASE, (u_long)&__pcpu[curcpu]); + if (error != 0) + goto done; + + /* + * If we are using VPIDs then invalidate all mappings tagged with 'vpid' + * + * We do this because this vcpu was executing on a different host + * cpu when it last ran. We do not track whether it invalidated + * mappings associated with its 'vpid' during that run. So we must + * assume that the mappings associated with 'vpid' on 'curcpu' are + * stale and invalidate them. + * + * Note that we incur this penalty only when the scheduler chooses to + * move the thread associated with this vcpu between host cpus. + * + * Note also that this will invalidate mappings tagged with 'vpid' + * for "all" EP4TAs. + */ + if (vmxstate->vpid != 0) { + invvpid_desc.vpid = vmxstate->vpid; + invvpid(INVVPID_TYPE_SINGLE_CONTEXT, invvpid_desc); + } +done: + return (error); +} + +static void +vm_exit_update_rip(struct vm_exit *vmexit) +{ + int error; + + error = vmwrite(VMCS_GUEST_RIP, vmexit->rip + vmexit->inst_length); + if (error) + panic("vmx_run: error %d writing to VMCS_GUEST_RIP", error); +} + +/* + * We depend on 'procbased_ctls' to have the Interrupt Window Exiting bit set. + */ +CTASSERT((PROCBASED_CTLS_ONE_SETTING & PROCBASED_INT_WINDOW_EXITING) != 0); + +static void __inline +vmx_set_int_window_exiting(struct vmx *vmx, int vcpu) +{ + int error; + + vmx->cap[vcpu].proc_ctls |= PROCBASED_INT_WINDOW_EXITING; + + error = vmwrite(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + if (error) + panic("vmx_set_int_window_exiting: vmwrite error %d", error); +} + +static void __inline +vmx_clear_int_window_exiting(struct vmx *vmx, int vcpu) +{ + int error; + + vmx->cap[vcpu].proc_ctls &= ~PROCBASED_INT_WINDOW_EXITING; + + error = vmwrite(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + if (error) + panic("vmx_clear_int_window_exiting: vmwrite error %d", error); +} + +static void __inline +vmx_set_nmi_window_exiting(struct vmx *vmx, int vcpu) +{ + int error; + + vmx->cap[vcpu].proc_ctls |= PROCBASED_NMI_WINDOW_EXITING; + + error = vmwrite(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + if (error) + panic("vmx_set_nmi_window_exiting: vmwrite error %d", error); +} + +static void __inline +vmx_clear_nmi_window_exiting(struct vmx *vmx, int vcpu) +{ + int error; + + vmx->cap[vcpu].proc_ctls &= ~PROCBASED_NMI_WINDOW_EXITING; + + error = vmwrite(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + if (error) + panic("vmx_clear_nmi_window_exiting: vmwrite error %d", error); +} + +static int +vmx_inject_nmi(struct vmx *vmx, int vcpu) +{ + int error; + uint64_t info, interruptibility; + + /* Bail out if no NMI requested */ + if (vmx->state[vcpu].request_nmi == 0) + return (0); + + error = vmread(VMCS_GUEST_INTERRUPTIBILITY, &interruptibility); + if (error) { + panic("vmx_inject_nmi: vmread(interruptibility) %d", + error); + } + if (interruptibility & nmi_blocking_bits) + goto nmiblocked; + + /* + * Inject the virtual NMI. The vector must be the NMI IDT entry + * or the VMCS entry check will fail. + */ + info = VMCS_INTERRUPTION_INFO_NMI | VMCS_INTERRUPTION_INFO_VALID; + info |= IDT_NMI; + + error = vmwrite(VMCS_ENTRY_INTR_INFO, info); + if (error) + panic("vmx_inject_nmi: vmwrite(intrinfo) %d", error); + + VMM_CTR0(vmx->vm, vcpu, "Injecting vNMI"); + + /* Clear the request */ + vmx->state[vcpu].request_nmi = 0; + return (1); + +nmiblocked: + /* + * Set the NMI Window Exiting execution control so we can inject + * the virtual NMI as soon as blocking condition goes away. + */ + vmx_set_nmi_window_exiting(vmx, vcpu); + + VMM_CTR0(vmx->vm, vcpu, "Enabling NMI window exiting"); + return (1); +} + +static void +vmx_inject_interrupts(struct vmx *vmx, int vcpu) +{ + int error, vector; + uint64_t info, rflags, interruptibility; + + const int HWINTR_BLOCKED = VMCS_INTERRUPTIBILITY_STI_BLOCKING | + VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING; + +#if 1 + /* + * XXX + * If an event is being injected from userland then just return. + * For e.g. we may inject a breakpoint exception to cause the + * guest to enter the debugger so we can inspect its state. + */ + error = vmread(VMCS_ENTRY_INTR_INFO, &info); + if (error) + panic("vmx_inject_interrupts: vmread(intrinfo) %d", error); + if (info & VMCS_INTERRUPTION_INFO_VALID) + return; +#endif + /* + * NMI injection has priority so deal with those first + */ + if (vmx_inject_nmi(vmx, vcpu)) + return; + + /* Ask the local apic for a vector to inject */ + vector = lapic_pending_intr(vmx->vm, vcpu); + if (vector < 0) + return; + + if (vector < 32 || vector > 255) + panic("vmx_inject_interrupts: invalid vector %d\n", vector); + + /* Check RFLAGS.IF and the interruptibility state of the guest */ + error = vmread(VMCS_GUEST_RFLAGS, &rflags); + if (error) + panic("vmx_inject_interrupts: vmread(rflags) %d", error); + + if ((rflags & PSL_I) == 0) + goto cantinject; + + error = vmread(VMCS_GUEST_INTERRUPTIBILITY, &interruptibility); + if (error) { + panic("vmx_inject_interrupts: vmread(interruptibility) %d", + error); + } + if (interruptibility & HWINTR_BLOCKED) + goto cantinject; + + /* Inject the interrupt */ + info = VMCS_INTERRUPTION_INFO_HW_INTR | VMCS_INTERRUPTION_INFO_VALID; + info |= vector; + error = vmwrite(VMCS_ENTRY_INTR_INFO, info); + if (error) + panic("vmx_inject_interrupts: vmwrite(intrinfo) %d", error); + + /* Update the Local APIC ISR */ + lapic_intr_accepted(vmx->vm, vcpu, vector); + + VMM_CTR1(vmx->vm, vcpu, "Injecting hwintr at vector %d", vector); + + return; + +cantinject: + /* + * Set the Interrupt Window Exiting execution control so we can inject + * the interrupt as soon as blocking condition goes away. + */ + vmx_set_int_window_exiting(vmx, vcpu); + + VMM_CTR0(vmx->vm, vcpu, "Enabling interrupt window exiting"); +} + +static int +vmx_emulate_cr_access(struct vmx *vmx, int vcpu, uint64_t exitqual) +{ + int error; + uint64_t regval; + const struct vmxctx *vmxctx; + + /* We only handle mov to %cr0 at this time */ + if ((exitqual & 0xff) != 0x00) + return (UNHANDLED); + + vmxctx = &vmx->ctx[vcpu]; + + /* + * We must use vmwrite() directly here because vmcs_setreg() will + * call vmclear(vmcs) as a side-effect which we certainly don't want. + */ + switch ((exitqual >> 8) & 0xf) { + case 0: + regval = vmxctx->guest_rax; + break; + case 1: + regval = vmxctx->guest_rcx; + break; + case 2: + regval = vmxctx->guest_rdx; + break; + case 3: + regval = vmxctx->guest_rbx; + break; + case 4: + error = vmread(VMCS_GUEST_RSP, ®val); + if (error) { + panic("vmx_emulate_cr_access: " + "error %d reading guest rsp", error); + } + break; + case 5: + regval = vmxctx->guest_rbp; + break; + case 6: + regval = vmxctx->guest_rsi; + break; + case 7: + regval = vmxctx->guest_rdi; + break; + case 8: + regval = vmxctx->guest_r8; + break; + case 9: + regval = vmxctx->guest_r9; + break; + case 10: + regval = vmxctx->guest_r10; + break; + case 11: + regval = vmxctx->guest_r11; + break; + case 12: + regval = vmxctx->guest_r12; + break; + case 13: + regval = vmxctx->guest_r13; + break; + case 14: + regval = vmxctx->guest_r14; + break; + case 15: + regval = vmxctx->guest_r15; + break; + } + + regval |= cr0_ones_mask; + regval &= ~cr0_zeros_mask; + error = vmwrite(VMCS_GUEST_CR0, regval); + if (error) + panic("vmx_emulate_cr_access: error %d writing cr0", error); + + return (HANDLED); +} + +static int +vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) +{ + int handled; + struct vmcs *vmcs; + struct vmxctx *vmxctx; + uint32_t eax, ecx, edx; + uint64_t qual; + + handled = 0; + vmcs = &vmx->vmcs[vcpu]; + vmxctx = &vmx->ctx[vcpu]; + qual = vmexit->u.vmx.exit_qualification; + vmexit->exitcode = VM_EXITCODE_BOGUS; + + switch (vmexit->u.vmx.exit_reason) { + case EXIT_REASON_CR_ACCESS: + handled = vmx_emulate_cr_access(vmx, vcpu, qual); + break; + case EXIT_REASON_RDMSR: + ecx = vmxctx->guest_rcx; + handled = emulate_rdmsr(vmx->vm, vcpu, ecx); + if (!handled) { + vmexit->exitcode = VM_EXITCODE_RDMSR; + vmexit->u.msr.code = ecx; + } + break; + case EXIT_REASON_WRMSR: + eax = vmxctx->guest_rax; + ecx = vmxctx->guest_rcx; + edx = vmxctx->guest_rdx; + handled = emulate_wrmsr(vmx->vm, vcpu, ecx, + (uint64_t)edx << 32 | eax); + if (!handled) { + vmexit->exitcode = VM_EXITCODE_WRMSR; + vmexit->u.msr.code = ecx; + vmexit->u.msr.wval = (uint64_t)edx << 32 | eax; + } + break; + case EXIT_REASON_HLT: + vmexit->exitcode = VM_EXITCODE_HLT; + break; + case EXIT_REASON_MTF: + vmexit->exitcode = VM_EXITCODE_MTRAP; + break; + case EXIT_REASON_PAUSE: + vmexit->exitcode = VM_EXITCODE_PAUSE; + break; + case EXIT_REASON_INTR_WINDOW: + vmx_clear_int_window_exiting(vmx, vcpu); + VMM_CTR0(vmx->vm, vcpu, "Disabling interrupt window exiting"); + /* FALLTHRU */ + case EXIT_REASON_EXT_INTR: + /* + * External interrupts serve only to cause VM exits and allow + * the host interrupt handler to run. + * + * If this external interrupt triggers a virtual interrupt + * to a VM, then that state will be recorded by the + * host interrupt handler in the VM's softc. We will inject + * this virtual interrupt during the subsequent VM enter. + */ + + /* + * This is special. We want to treat this as an 'handled' + * VM-exit but not increment the instruction pointer. + */ + vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EXTINT, 1); + return (1); + case EXIT_REASON_NMI_WINDOW: + /* Exit to allow the pending virtual NMI to be injected */ + vmx_clear_nmi_window_exiting(vmx, vcpu); + VMM_CTR0(vmx->vm, vcpu, "Disabling NMI window exiting"); + return (1); + case EXIT_REASON_INOUT: + vmexit->exitcode = VM_EXITCODE_INOUT; + vmexit->u.inout.bytes = (qual & 0x7) + 1; + vmexit->u.inout.in = (qual & 0x8) ? 1 : 0; + vmexit->u.inout.string = (qual & 0x10) ? 1 : 0; + vmexit->u.inout.rep = (qual & 0x20) ? 1 : 0; + vmexit->u.inout.port = (uint16_t)(qual >> 16); + vmexit->u.inout.eax = (uint32_t)(vmxctx->guest_rax); + break; + case EXIT_REASON_CPUID: + handled = vmx_handle_cpuid(vmxctx); + break; + default: + break; + } + + if (handled) { + /* + * It is possible that control is returned to userland + * even though we were able to handle the VM exit in the + * kernel (for e.g. 'astpending' is set in the run loop). + * + * In such a case we want to make sure that the userland + * restarts guest execution at the instruction *after* + * the one we just processed. Therefore we update the + * guest rip in the VMCS and in 'vmexit'. + */ + vm_exit_update_rip(vmexit); + vmexit->rip += vmexit->inst_length; + vmexit->inst_length = 0; + } else { + if (vmexit->exitcode == VM_EXITCODE_BOGUS) { + /* + * If this VM exit was not claimed by anybody then + * treat it as a generic VMX exit. + */ + vmexit->exitcode = VM_EXITCODE_VMX; + vmexit->u.vmx.error = 0; + } else { + /* + * The exitcode and collateral have been populated. + * The VM exit will be processed further in userland. + */ + } + } + return (handled); +} + +static int +vmx_run(void *arg, int vcpu, register_t rip, struct vm_exit *vmexit) +{ + int error, vie, rc, handled, astpending, loopstart; + uint32_t exit_reason; + struct vmx *vmx; + struct vmxctx *vmxctx; + struct vmcs *vmcs; + + vmx = arg; + vmcs = &vmx->vmcs[vcpu]; + vmxctx = &vmx->ctx[vcpu]; + loopstart = 1; + + /* + * XXX Can we avoid doing this every time we do a vm run? + */ + VMPTRLD(vmcs); + + /* + * XXX + * We do this every time because we may setup the virtual machine + * from a different process than the one that actually runs it. + * + * If the life of a virtual machine was spent entirely in the context + * of a single process we could do this once in vmcs_set_defaults(). + */ + if ((error = vmwrite(VMCS_HOST_CR3, rcr3())) != 0) + panic("vmx_run: error %d writing to VMCS_HOST_CR3", error); + + if ((error = vmwrite(VMCS_GUEST_RIP, rip)) != 0) + panic("vmx_run: error %d writing to VMCS_GUEST_RIP", error); + + if ((error = vmx_set_pcpu_defaults(vmx, vcpu)) != 0) + panic("vmx_run: error %d setting up pcpu defaults", error); + + do { + lapic_timer_tick(vmx->vm, vcpu); + vmx_inject_interrupts(vmx, vcpu); + vmx_run_trace(vmx, vcpu); + rc = vmx_setjmp(vmxctx); +#ifdef SETJMP_TRACE + vmx_setjmp_trace(vmx, vcpu, vmxctx, rc); +#endif + switch (rc) { + case VMX_RETURN_DIRECT: + if (loopstart) { + loopstart = 0; + vmx_launch(vmxctx); + } else + vmx_resume(vmxctx); + panic("vmx_launch/resume should not return"); + break; + case VMX_RETURN_LONGJMP: + break; /* vm exit */ + case VMX_RETURN_VMRESUME: + vie = vmcs_instruction_error(); + if (vmxctx->launch_error == VM_FAIL_INVALID || + vie != VMRESUME_WITH_NON_LAUNCHED_VMCS) { + printf("vmresume error %d vmcs inst error %d\n", + vmxctx->launch_error, vie); + goto err_exit; + } + vmx_launch(vmxctx); /* try to launch the guest */ + panic("vmx_launch should not return"); + break; + case VMX_RETURN_VMLAUNCH: + vie = vmcs_instruction_error(); +#if 1 + printf("vmlaunch error %d vmcs inst error %d\n", + vmxctx->launch_error, vie); +#endif + goto err_exit; + default: + panic("vmx_setjmp returned %d", rc); + } + + /* + * XXX locking? + * See comments in exception.S about checking for ASTs + * atomically while interrupts are disabled. But it is + * not clear that they apply in our case. + */ + astpending = curthread->td_flags & TDF_ASTPENDING; + + /* enable interrupts */ + enable_intr(); + + /* collect some basic information for VM exit processing */ + vmexit->rip = rip = vmcs_guest_rip(); + vmexit->inst_length = vmexit_instruction_length(); + vmexit->u.vmx.exit_reason = exit_reason = vmcs_exit_reason(); + vmexit->u.vmx.exit_qualification = vmcs_exit_qualification(); + + handled = vmx_exit_process(vmx, vcpu, vmexit); + + vmx_exit_trace(vmx, vcpu, rip, exit_reason, handled, + astpending); + } while (handled && !astpending); + + /* + * If a VM exit has been handled then the exitcode must be BOGUS + * If a VM exit is not handled then the exitcode must not be BOGUS + */ + if ((handled && vmexit->exitcode != VM_EXITCODE_BOGUS) || + (!handled && vmexit->exitcode == VM_EXITCODE_BOGUS)) { + panic("Mismatch between handled (%d) and exitcode (%d)", + handled, vmexit->exitcode); + } + + VMM_CTR1(vmx->vm, vcpu, "goto userland: exitcode %d",vmexit->exitcode); + + /* + * XXX + * We need to do this to ensure that any VMCS state cached by the + * processor is flushed to memory. We need to do this in case the + * VM moves to a different cpu the next time it runs. + * + * Can we avoid doing this? + */ + VMCLEAR(vmcs); + return (0); + +err_exit: + vmexit->exitcode = VM_EXITCODE_VMX; + vmexit->u.vmx.exit_reason = (uint32_t)-1; + vmexit->u.vmx.exit_qualification = (uint32_t)-1; + vmexit->u.vmx.error = vie; + VMCLEAR(vmcs); + return (ENOEXEC); +} + +static void +vmx_vmcleanup(void *arg) +{ + int error; + struct vmx *vmx = arg; + + /* + * XXXSMP we also need to clear the VMCS active on the other vcpus. + */ + error = vmclear(&vmx->vmcs[0]); + if (error != 0) + panic("vmx_vmcleanup: vmclear error %d on vcpu 0", error); + + ept_vmcleanup(vmx); + free(vmx, M_VMX); + + return; +} + +static register_t * +vmxctx_regptr(struct vmxctx *vmxctx, int reg) +{ + + switch (reg) { + case VM_REG_GUEST_RAX: + return (&vmxctx->guest_rax); + case VM_REG_GUEST_RBX: + return (&vmxctx->guest_rbx); + case VM_REG_GUEST_RCX: + return (&vmxctx->guest_rcx); + case VM_REG_GUEST_RDX: + return (&vmxctx->guest_rdx); + case VM_REG_GUEST_RSI: + return (&vmxctx->guest_rsi); + case VM_REG_GUEST_RDI: + return (&vmxctx->guest_rdi); + case VM_REG_GUEST_RBP: + return (&vmxctx->guest_rbp); + case VM_REG_GUEST_R8: + return (&vmxctx->guest_r8); + case VM_REG_GUEST_R9: + return (&vmxctx->guest_r9); + case VM_REG_GUEST_R10: + return (&vmxctx->guest_r10); + case VM_REG_GUEST_R11: + return (&vmxctx->guest_r11); + case VM_REG_GUEST_R12: + return (&vmxctx->guest_r12); + case VM_REG_GUEST_R13: + return (&vmxctx->guest_r13); + case VM_REG_GUEST_R14: + return (&vmxctx->guest_r14); + case VM_REG_GUEST_R15: + return (&vmxctx->guest_r15); + default: + break; + } + return (NULL); +} + +static int +vmxctx_getreg(struct vmxctx *vmxctx, int reg, uint64_t *retval) +{ + register_t *regp; + + if ((regp = vmxctx_regptr(vmxctx, reg)) != NULL) { + *retval = *regp; + return (0); + } else + return (EINVAL); +} + +static int +vmxctx_setreg(struct vmxctx *vmxctx, int reg, uint64_t val) +{ + register_t *regp; + + if ((regp = vmxctx_regptr(vmxctx, reg)) != NULL) { + *regp = val; + return (0); + } else + return (EINVAL); +} + +static int +vmx_getreg(void *arg, int vcpu, int reg, uint64_t *retval) +{ + struct vmx *vmx = arg; + + if (vmxctx_getreg(&vmx->ctx[vcpu], reg, retval) == 0) + return (0); + + /* + * If the vcpu is running then don't mess with the VMCS. + * + * vmcs_getreg will VMCLEAR the vmcs when it is done which will cause + * the subsequent vmlaunch/vmresume to fail. + */ + if (vcpu_is_running(vmx->vm, vcpu, NULL)) + panic("vmx_getreg: %s%d is running", vm_name(vmx->vm), vcpu); + + return (vmcs_getreg(&vmx->vmcs[vcpu], reg, retval)); +} + +static int +vmx_setreg(void *arg, int vcpu, int reg, uint64_t val) +{ + int error; + uint64_t ctls; + struct vmx *vmx = arg; + + /* + * XXX Allow caller to set contents of the guest registers saved in + * the 'vmxctx' even though the vcpu might be running. We need this + * specifically to support the rdmsr emulation that will set the + * %eax and %edx registers during vm exit processing. + */ + if (vmxctx_setreg(&vmx->ctx[vcpu], reg, val) == 0) + return (0); + + /* + * If the vcpu is running then don't mess with the VMCS. + * + * vmcs_setreg will VMCLEAR the vmcs when it is done which will cause + * the subsequent vmlaunch/vmresume to fail. + */ + if (vcpu_is_running(vmx->vm, vcpu, NULL)) + panic("vmx_setreg: %s%d is running", vm_name(vmx->vm), vcpu); + + error = vmcs_setreg(&vmx->vmcs[vcpu], reg, val); + + if (error == 0) { + /* + * If the "load EFER" VM-entry control is 1 then the + * value of EFER.LMA must be identical to "IA-32e mode guest" + * bit in the VM-entry control. + */ + if ((entry_ctls & VM_ENTRY_LOAD_EFER) != 0 && + (reg == VM_REG_GUEST_EFER)) { + vmcs_getreg(&vmx->vmcs[vcpu], + VMCS_IDENT(VMCS_ENTRY_CTLS), &ctls); + if (val & EFER_LMA) + ctls |= VM_ENTRY_GUEST_LMA; + else + ctls &= ~VM_ENTRY_GUEST_LMA; + vmcs_setreg(&vmx->vmcs[vcpu], + VMCS_IDENT(VMCS_ENTRY_CTLS), ctls); + } + } + + return (error); +} + +static int +vmx_getdesc(void *arg, int vcpu, int reg, struct seg_desc *desc) +{ + struct vmx *vmx = arg; + + return (vmcs_getdesc(&vmx->vmcs[vcpu], reg, desc)); +} + +static int +vmx_setdesc(void *arg, int vcpu, int reg, struct seg_desc *desc) +{ + struct vmx *vmx = arg; + + return (vmcs_setdesc(&vmx->vmcs[vcpu], reg, desc)); +} + +static int +vmx_inject(void *arg, int vcpu, int type, int vector, uint32_t code, + int code_valid) +{ + int error; + uint32_t info; + struct vmx *vmx = arg; + struct vmcs *vmcs = &vmx->vmcs[vcpu]; + + static uint32_t type_map[VM_EVENT_MAX] = { + 0x1, /* VM_EVENT_NONE */ + 0x0, /* VM_HW_INTR */ + 0x2, /* VM_NMI */ + 0x3, /* VM_HW_EXCEPTION */ + 0x4, /* VM_SW_INTR */ + 0x5, /* VM_PRIV_SW_EXCEPTION */ + 0x6, /* VM_SW_EXCEPTION */ + }; + + info = vector | (type_map[type] << 8) | (code_valid ? 1 << 11 : 0); + info |= VMCS_INTERRUPTION_INFO_VALID; + error = vmcs_setreg(vmcs, VMCS_IDENT(VMCS_ENTRY_INTR_INFO), info); + if (error != 0) + return (error); + + if (code_valid) { + error = vmcs_setreg(vmcs, + VMCS_IDENT(VMCS_ENTRY_EXCEPTION_ERROR), + code); + } + return (error); +} + +static int +vmx_nmi(void *arg, int vcpu) +{ + struct vmx *vmx = arg; + + atomic_set_int(&vmx->state[vcpu].request_nmi, 1); + + return (0); +} + +static int +vmx_getcap(void *arg, int vcpu, int type, int *retval) +{ + struct vmx *vmx = arg; + int vcap; + int ret; + + ret = ENOENT; + + vcap = vmx->cap[vcpu].set; + + switch (type) { + case VM_CAP_HALT_EXIT: + if (cap_halt_exit) + ret = 0; + break; + case VM_CAP_PAUSE_EXIT: + if (cap_pause_exit) + ret = 0; + break; + case VM_CAP_MTRAP_EXIT: + if (cap_monitor_trap) + ret = 0; + break; + case VM_CAP_UNRESTRICTED_GUEST: + if (cap_unrestricted_guest) + ret = 0; + break; + default: + break; + } + + if (ret == 0) + *retval = (vcap & (1 << type)) ? 1 : 0; + + return (ret); +} + +static int +vmx_setcap(void *arg, int vcpu, int type, int val) +{ + struct vmx *vmx = arg; + struct vmcs *vmcs = &vmx->vmcs[vcpu]; + uint32_t baseval; + uint32_t *pptr; + int error; + int flag; + int reg; + int retval; + + retval = ENOENT; + pptr = NULL; + + switch (type) { + case VM_CAP_HALT_EXIT: + if (cap_halt_exit) { + retval = 0; + pptr = &vmx->cap[vcpu].proc_ctls; + baseval = *pptr; + flag = PROCBASED_HLT_EXITING; + reg = VMCS_PRI_PROC_BASED_CTLS; + } + break; + case VM_CAP_MTRAP_EXIT: + if (cap_monitor_trap) { + retval = 0; + pptr = &vmx->cap[vcpu].proc_ctls; + baseval = *pptr; + flag = PROCBASED_MTF; + reg = VMCS_PRI_PROC_BASED_CTLS; + } + break; + case VM_CAP_PAUSE_EXIT: + if (cap_pause_exit) { + retval = 0; + pptr = &vmx->cap[vcpu].proc_ctls; + baseval = *pptr; + flag = PROCBASED_PAUSE_EXITING; + reg = VMCS_PRI_PROC_BASED_CTLS; + } + break; + case VM_CAP_UNRESTRICTED_GUEST: + if (cap_unrestricted_guest) { + retval = 0; + baseval = procbased_ctls2; + flag = PROCBASED2_UNRESTRICTED_GUEST; + reg = VMCS_SEC_PROC_BASED_CTLS; + } + break; + default: + break; + } + + if (retval == 0) { + if (val) { + baseval |= flag; + } else { + baseval &= ~flag; + } + VMPTRLD(vmcs); + error = vmwrite(reg, baseval); + VMCLEAR(vmcs); + + if (error) { + retval = error; + } else { + /* + * Update optional stored flags, and record + * setting + */ + if (pptr != NULL) { + *pptr = baseval; + } + + if (val) { + vmx->cap[vcpu].set |= (1 << type); + } else { + vmx->cap[vcpu].set &= ~(1 << type); + } + } + } + + return (retval); +} + +struct vmm_ops vmm_ops_intel = { + vmx_init, + vmx_cleanup, + vmx_vminit, + vmx_run, + vmx_vmcleanup, + ept_vmmmap, + vmx_getreg, + vmx_setreg, + vmx_getdesc, + vmx_setdesc, + vmx_inject, + vmx_nmi, + vmx_getcap, + vmx_setcap +}; diff --git a/sys/amd64/vmm/intel/vmx.h b/sys/amd64/vmm/intel/vmx.h new file mode 100644 index 00000000000..69697f8e48d --- /dev/null +++ b/sys/amd64/vmm/intel/vmx.h @@ -0,0 +1,115 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMX_H_ +#define _VMX_H_ + +#include "vmcs.h" + +#define GUEST_MSR_MAX_ENTRIES 64 /* arbitrary */ + +struct vmxctx { + register_t guest_rdi; /* Guest state */ + register_t guest_rsi; + register_t guest_rdx; + register_t guest_rcx; + register_t guest_r8; + register_t guest_r9; + register_t guest_rax; + register_t guest_rbx; + register_t guest_rbp; + register_t guest_r10; + register_t guest_r11; + register_t guest_r12; + register_t guest_r13; + register_t guest_r14; + register_t guest_r15; + register_t guest_cr2; + + register_t host_r15; /* Host state */ + register_t host_r14; + register_t host_r13; + register_t host_r12; + register_t host_rbp; + register_t host_rsp; + register_t host_rbx; + register_t host_rip; + /* + * XXX todo debug registers and fpu state + */ + + int launch_error; +}; + +struct vmxcap { + int set; + uint32_t proc_ctls; +}; + +struct vmxstate { + int request_nmi; + int lastcpu; /* host cpu that this 'vcpu' last ran on */ + uint16_t vpid; +}; + +/* virtual machine softc */ +struct vmx { + pml4_entry_t pml4ept[NPML4EPG]; + struct vmcs vmcs[VM_MAXCPU]; /* one vmcs per virtual cpu */ + char msr_bitmap[PAGE_SIZE]; + struct msr_entry guest_msrs[VM_MAXCPU][GUEST_MSR_MAX_ENTRIES]; + struct vmxctx ctx[VM_MAXCPU]; + struct vmxcap cap[VM_MAXCPU]; + struct vmxstate state[VM_MAXCPU]; + struct vm *vm; +}; +CTASSERT((offsetof(struct vmx, pml4ept) & PAGE_MASK) == 0); +CTASSERT((offsetof(struct vmx, vmcs) & PAGE_MASK) == 0); +CTASSERT((offsetof(struct vmx, msr_bitmap) & PAGE_MASK) == 0); +CTASSERT((offsetof(struct vmx, guest_msrs) & 15) == 0); + +#define VMX_RETURN_DIRECT 0 +#define VMX_RETURN_LONGJMP 1 +#define VMX_RETURN_VMRESUME 2 +#define VMX_RETURN_VMLAUNCH 3 +/* + * vmx_setjmp() returns: + * - 0 when it returns directly + * - 1 when it returns from vmx_longjmp + * - 2 when it returns from vmx_resume (which would only be in the error case) + * - 3 when it returns from vmx_launch (which would only be in the error case) + */ +int vmx_setjmp(struct vmxctx *ctx); +void vmx_longjmp(void); /* returns via vmx_setjmp */ +void vmx_launch(struct vmxctx *ctx) __dead2; /* may return via vmx_setjmp */ +void vmx_resume(struct vmxctx *ctx) __dead2; /* may return via vmx_setjmp */ + +u_long vmx_fix_cr0(u_long cr0); +u_long vmx_fix_cr4(u_long cr4); + +#endif diff --git a/sys/amd64/vmm/intel/vmx_controls.h b/sys/amd64/vmm/intel/vmx_controls.h new file mode 100644 index 00000000000..31f29f8e6bb --- /dev/null +++ b/sys/amd64/vmm/intel/vmx_controls.h @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMX_CONTROLS_H_ +#define _VMX_CONTROLS_H_ + +/* Pin-Based VM-Execution Controls */ +#define PINBASED_EXTINT_EXITING (1 << 0) +#define PINBASED_NMI_EXITING (1 << 3) +#define PINBASED_VIRTUAL_NMI (1 << 5) +#define PINBASED_PREMPTION_TIMER (1 << 6) + +/* Primary Processor-Based VM-Execution Controls */ +#define PROCBASED_INT_WINDOW_EXITING (1 << 2) +#define PROCBASED_TSC_OFFSET (1 << 3) +#define PROCBASED_HLT_EXITING (1 << 7) +#define PROCBASED_INVLPG_EXITING (1 << 9) +#define PROCBASED_MWAIT_EXITING (1 << 10) +#define PROCBASED_RDPMC_EXITING (1 << 11) +#define PROCBASED_RDTSC_EXITING (1 << 12) +#define PROCBASED_CR3_LOAD_EXITING (1 << 15) +#define PROCBASED_CR3_STORE_EXITING (1 << 16) +#define PROCBASED_CR8_LOAD_EXITING (1 << 19) +#define PROCBASED_CR8_STORE_EXITING (1 << 20) +#define PROCBASED_USE_TPR_SHADOW (1 << 21) +#define PROCBASED_NMI_WINDOW_EXITING (1 << 22) +#define PROCBASED_MOV_DR_EXITING (1 << 23) +#define PROCBASED_IO_EXITING (1 << 24) +#define PROCBASED_IO_BITMAPS (1 << 25) +#define PROCBASED_MTF (1 << 27) +#define PROCBASED_MSR_BITMAPS (1 << 28) +#define PROCBASED_MONITOR_EXITING (1 << 29) +#define PROCBASED_PAUSE_EXITING (1 << 30) +#define PROCBASED_SECONDARY_CONTROLS (1 << 31) + +/* Secondary Processor-Based VM-Execution Controls */ +#define PROCBASED2_VIRTUALIZE_APIC (1 << 0) +#define PROCBASED2_ENABLE_EPT (1 << 1) +#define PROCBASED2_DESC_TABLE_EXITING (1 << 2) +#define PROCBASED2_ENABLE_RDTSCP (1 << 3) +#define PROCBASED2_VIRTUALIZE_X2APIC (1 << 4) +#define PROCBASED2_ENABLE_VPID (1 << 5) +#define PROCBASED2_WBINVD_EXITING (1 << 6) +#define PROCBASED2_UNRESTRICTED_GUEST (1 << 7) +#define PROCBASED2_PAUSE_LOOP_EXITING (1 << 10) + +/* VM Exit Controls */ +#define VM_EXIT_SAVE_DEBUG_CONTROLS (1 << 2) +#define VM_EXIT_HOST_LMA (1 << 9) +#define VM_EXIT_LOAD_PERF_GLOBAL_CTRL (1 << 12) +#define VM_EXIT_ACKNOWLEDGE_INTERRUPT (1 << 15) +#define VM_EXIT_SAVE_PAT (1 << 18) +#define VM_EXIT_LOAD_PAT (1 << 19) +#define VM_EXIT_SAVE_EFER (1 << 20) +#define VM_EXIT_LOAD_EFER (1 << 21) +#define VM_EXIT_SAVE_PREEMPTION_TIMER (1 << 22) + +/* VM Entry Controls */ +#define VM_ENTRY_LOAD_DEBUG_CONTROLS (1 << 2) +#define VM_ENTRY_GUEST_LMA (1 << 9) +#define VM_ENTRY_INTO_SMM (1 << 10) +#define VM_ENTRY_DEACTIVATE_DUAL_MONITOR (1 << 11) +#define VM_ENTRY_LOAD_PERF_GLOBAL_CTRL (1 << 13) +#define VM_ENTRY_LOAD_PAT (1 << 14) +#define VM_ENTRY_LOAD_EFER (1 << 15) + +#endif diff --git a/sys/amd64/vmm/intel/vmx_cpufunc.h b/sys/amd64/vmm/intel/vmx_cpufunc.h new file mode 100644 index 00000000000..e9f6c6dcaab --- /dev/null +++ b/sys/amd64/vmm/intel/vmx_cpufunc.h @@ -0,0 +1,199 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMX_CPUFUNC_H_ +#define _VMX_CPUFUNC_H_ + +struct vmcs; + +/* + * Section 5.2 "Conventions" from Intel Architecture Manual 2B. + * + * error + * VMsucceed 0 + * VMFailInvalid 1 + * VMFailValid 2 see also VMCS VM-Instruction Error Field + */ +#define VM_SUCCESS 0 +#define VM_FAIL_INVALID 1 +#define VM_FAIL_VALID 2 +#define VMX_SET_ERROR_CODE(varname) \ + do { \ + __asm __volatile(" jnc 1f;" \ + " mov $1, %0;" /* CF: error = 1 */ \ + " jmp 3f;" \ + "1: jnz 2f;" \ + " mov $2, %0;" /* ZF: error = 2 */ \ + " jmp 3f;" \ + "2: mov $0, %0;" \ + "3: nop" \ + :"=r" (varname)); \ + } while (0) + +/* returns 0 on success and non-zero on failure */ +static __inline int +vmxon(char *region) +{ + int error; + uint64_t addr; + + addr = vtophys(region); + __asm __volatile("vmxon %0" : : "m" (*(uint64_t *)&addr) : "memory"); + VMX_SET_ERROR_CODE(error); + return (error); +} + +/* returns 0 on success and non-zero on failure */ +static __inline int +vmclear(struct vmcs *vmcs) +{ + int error; + uint64_t addr; + + addr = vtophys(vmcs); + __asm __volatile("vmclear %0" : : "m" (*(uint64_t *)&addr) : "memory"); + VMX_SET_ERROR_CODE(error); + return (error); +} + +static __inline void +vmxoff(void) +{ + __asm __volatile("vmxoff"); +} + +static __inline void +vmptrst(uint64_t *addr) +{ + __asm __volatile("vmptrst %0" : : "m" (*addr) : "memory"); +} + +static __inline int +vmptrld(struct vmcs *vmcs) +{ + int error; + uint64_t addr; + + addr = vtophys(vmcs); + __asm __volatile("vmptrld %0" : : "m" (*(uint64_t *)&addr) : "memory"); + VMX_SET_ERROR_CODE(error); + return (error); +} + +static __inline int +vmwrite(uint64_t reg, uint64_t val) +{ + int error; + + __asm __volatile("vmwrite %0, %1" : : "r" (val), "r" (reg) : "memory"); + + VMX_SET_ERROR_CODE(error); + + return (error); +} + +static __inline int +vmread(uint64_t r, uint64_t *addr) +{ + int error; + + __asm __volatile("vmread %0, %1" : : "r" (r), "m" (*addr) : "memory"); + + VMX_SET_ERROR_CODE(error); + + return (error); +} + +static void __inline +VMCLEAR(struct vmcs *vmcs) +{ + int err; + + err = vmclear(vmcs); + if (err != 0) + panic("%s: vmclear(%p) error %d", __func__, vmcs, err); + + critical_exit(); +} + +static void __inline +VMPTRLD(struct vmcs *vmcs) +{ + int err; + + critical_enter(); + + err = vmptrld(vmcs); + if (err != 0) + panic("%s: vmptrld(%p) error %d", __func__, vmcs, err); +} + +#define INVVPID_TYPE_ADDRESS 0UL +#define INVVPID_TYPE_SINGLE_CONTEXT 1UL +#define INVVPID_TYPE_ALL_CONTEXTS 2UL + +struct invvpid_desc { + uint16_t vpid; + uint16_t _res1; + uint32_t _res2; + uint64_t linear_addr; +}; +CTASSERT(sizeof(struct invvpid_desc) == 16); + +static void __inline +invvpid(uint64_t type, struct invvpid_desc desc) +{ + int error; + + __asm __volatile("invvpid %0, %1" :: "m" (desc), "r" (type) : "memory"); + + VMX_SET_ERROR_CODE(error); + if (error) + panic("invvpid error %d", error); +} + +#define INVEPT_TYPE_SINGLE_CONTEXT 1UL +#define INVEPT_TYPE_ALL_CONTEXTS 2UL +struct invept_desc { + uint64_t eptp; + uint64_t _res; +}; +CTASSERT(sizeof(struct invept_desc) == 16); + +static void __inline +invept(uint64_t type, struct invept_desc desc) +{ + int error; + + __asm __volatile("invept %0, %1" :: "m" (desc), "r" (type) : "memory"); + + VMX_SET_ERROR_CODE(error); + if (error) + panic("invept error %d", error); +} +#endif diff --git a/sys/amd64/vmm/intel/vmx_genassym.c b/sys/amd64/vmm/intel/vmx_genassym.c new file mode 100644 index 00000000000..c4b1efcd745 --- /dev/null +++ b/sys/amd64/vmm/intel/vmx_genassym.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include "vmx.h" +#include "vmx_cpufunc.h" + +ASSYM(VMXCTX_GUEST_RDI, offsetof(struct vmxctx, guest_rdi)); +ASSYM(VMXCTX_GUEST_RSI, offsetof(struct vmxctx, guest_rsi)); +ASSYM(VMXCTX_GUEST_RDX, offsetof(struct vmxctx, guest_rdx)); +ASSYM(VMXCTX_GUEST_RCX, offsetof(struct vmxctx, guest_rcx)); +ASSYM(VMXCTX_GUEST_R8, offsetof(struct vmxctx, guest_r8)); +ASSYM(VMXCTX_GUEST_R9, offsetof(struct vmxctx, guest_r9)); +ASSYM(VMXCTX_GUEST_RAX, offsetof(struct vmxctx, guest_rax)); +ASSYM(VMXCTX_GUEST_RBX, offsetof(struct vmxctx, guest_rbx)); +ASSYM(VMXCTX_GUEST_RBP, offsetof(struct vmxctx, guest_rbp)); +ASSYM(VMXCTX_GUEST_R10, offsetof(struct vmxctx, guest_r10)); +ASSYM(VMXCTX_GUEST_R11, offsetof(struct vmxctx, guest_r11)); +ASSYM(VMXCTX_GUEST_R12, offsetof(struct vmxctx, guest_r12)); +ASSYM(VMXCTX_GUEST_R13, offsetof(struct vmxctx, guest_r13)); +ASSYM(VMXCTX_GUEST_R14, offsetof(struct vmxctx, guest_r14)); +ASSYM(VMXCTX_GUEST_R15, offsetof(struct vmxctx, guest_r15)); +ASSYM(VMXCTX_GUEST_CR2, offsetof(struct vmxctx, guest_cr2)); + +ASSYM(VMXCTX_HOST_R15, offsetof(struct vmxctx, host_r15)); +ASSYM(VMXCTX_HOST_R14, offsetof(struct vmxctx, host_r14)); +ASSYM(VMXCTX_HOST_R13, offsetof(struct vmxctx, host_r13)); +ASSYM(VMXCTX_HOST_R12, offsetof(struct vmxctx, host_r12)); +ASSYM(VMXCTX_HOST_RBP, offsetof(struct vmxctx, host_rbp)); +ASSYM(VMXCTX_HOST_RSP, offsetof(struct vmxctx, host_rsp)); +ASSYM(VMXCTX_HOST_RBX, offsetof(struct vmxctx, host_rbx)); +ASSYM(VMXCTX_HOST_RIP, offsetof(struct vmxctx, host_rip)); + +ASSYM(VMXCTX_LAUNCH_ERROR, offsetof(struct vmxctx, launch_error)); + +ASSYM(VM_SUCCESS, VM_SUCCESS); +ASSYM(VM_FAIL_INVALID, VM_FAIL_INVALID); +ASSYM(VM_FAIL_VALID, VM_FAIL_VALID); + +ASSYM(VMX_RETURN_DIRECT, VMX_RETURN_DIRECT); +ASSYM(VMX_RETURN_LONGJMP, VMX_RETURN_LONGJMP); +ASSYM(VMX_RETURN_VMRESUME, VMX_RETURN_VMRESUME); +ASSYM(VMX_RETURN_VMLAUNCH, VMX_RETURN_VMLAUNCH); diff --git a/sys/amd64/vmm/intel/vmx_msr.c b/sys/amd64/vmm/intel/vmx_msr.c new file mode 100644 index 00000000000..1e9a837a78d --- /dev/null +++ b/sys/amd64/vmm/intel/vmx_msr.c @@ -0,0 +1,172 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include + +#include "vmx_msr.h" + +static boolean_t +vmx_ctl_allows_one_setting(uint64_t msr_val, int bitpos) +{ + + if (msr_val & (1UL << (bitpos + 32))) + return (TRUE); + else + return (FALSE); +} + +static boolean_t +vmx_ctl_allows_zero_setting(uint64_t msr_val, int bitpos) +{ + + if ((msr_val & (1UL << bitpos)) == 0) + return (TRUE); + else + return (FALSE); +} + +uint32_t +vmx_revision(void) +{ + + return (rdmsr(MSR_VMX_BASIC) & 0xffffffff); +} + +/* + * Generate a bitmask to be used for the VMCS execution control fields. + * + * The caller specifies what bits should be set to one in 'ones_mask' + * and what bits should be set to zero in 'zeros_mask'. The don't-care + * bits are set to the default value. The default values are obtained + * based on "Algorithm 3" in Section 27.5.1 "Algorithms for Determining + * VMX Capabilities". + * + * Returns zero on success and non-zero on error. + */ +int +vmx_set_ctlreg(int ctl_reg, int true_ctl_reg, uint32_t ones_mask, + uint32_t zeros_mask, uint32_t *retval) +{ + int i; + uint64_t val, trueval; + boolean_t true_ctls_avail, one_allowed, zero_allowed; + + /* We cannot ask the same bit to be set to both '1' and '0' */ + if ((ones_mask ^ zeros_mask) != (ones_mask | zeros_mask)) + return (EINVAL); + + if (rdmsr(MSR_VMX_BASIC) & (1UL << 55)) + true_ctls_avail = TRUE; + else + true_ctls_avail = FALSE; + + val = rdmsr(ctl_reg); + if (true_ctls_avail) + trueval = rdmsr(true_ctl_reg); /* step c */ + else + trueval = val; /* step a */ + + for (i = 0; i < 32; i++) { + one_allowed = vmx_ctl_allows_one_setting(trueval, i); + zero_allowed = vmx_ctl_allows_zero_setting(trueval, i); + + KASSERT(one_allowed || zero_allowed, + ("invalid zero/one setting for bit %d of ctl 0x%0x, " + "truectl 0x%0x\n", i, ctl_reg, true_ctl_reg)); + + if (zero_allowed && !one_allowed) { /* b(i),c(i) */ + if (ones_mask & (1 << i)) + return (EINVAL); + *retval &= ~(1 << i); + } else if (one_allowed && !zero_allowed) { /* b(i),c(i) */ + if (zeros_mask & (1 << i)) + return (EINVAL); + *retval |= 1 << i; + } else { + if (zeros_mask & (1 << i)) /* b(ii),c(ii) */ + *retval &= ~(1 << i); + else if (ones_mask & (1 << i)) /* b(ii), c(ii) */ + *retval |= 1 << i; + else if (!true_ctls_avail) + *retval &= ~(1 << i); /* b(iii) */ + else if (vmx_ctl_allows_zero_setting(val, i))/* c(iii)*/ + *retval &= ~(1 << i); + else if (vmx_ctl_allows_one_setting(val, i)) /* c(iv) */ + *retval |= 1 << i; + else { + panic("vmx_set_ctlreg: unable to determine " + "correct value of ctl bit %d for msr " + "0x%0x and true msr 0x%0x", i, ctl_reg, + true_ctl_reg); + } + } + } + + return (0); +} + +void +msr_bitmap_initialize(char *bitmap) +{ + + memset(bitmap, 0xff, PAGE_SIZE); +} + +int +msr_bitmap_change_access(char *bitmap, u_int msr, int access) +{ + int byte, bit; + + if (msr >= 0x00000000 && msr <= 0x00001FFF) + byte = msr / 8; + else if (msr >= 0xC0000000 && msr <= 0xC0001FFF) + byte = 1024 + (msr - 0xC0000000) / 8; + else + return (EINVAL); + + bit = msr & 0x7; + + if (access & MSR_BITMAP_ACCESS_READ) + bitmap[byte] &= ~(1 << bit); + else + bitmap[byte] |= 1 << bit; + + byte += 2048; + if (access & MSR_BITMAP_ACCESS_WRITE) + bitmap[byte] &= ~(1 << bit); + else + bitmap[byte] |= 1 << bit; + + return (0); +} diff --git a/sys/amd64/vmm/intel/vmx_msr.h b/sys/amd64/vmm/intel/vmx_msr.h new file mode 100644 index 00000000000..e6379a93d15 --- /dev/null +++ b/sys/amd64/vmm/intel/vmx_msr.h @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMX_MSR_H_ +#define _VMX_MSR_H_ + +#define MSR_VMX_BASIC 0x480 +#define MSR_VMX_EPT_VPID_CAP 0x48C + +#define MSR_VMX_PROCBASED_CTLS 0x482 +#define MSR_VMX_TRUE_PROCBASED_CTLS 0x48E + +#define MSR_VMX_PINBASED_CTLS 0x481 +#define MSR_VMX_TRUE_PINBASED_CTLS 0x48D + +#define MSR_VMX_PROCBASED_CTLS2 0x48B + +#define MSR_VMX_EXIT_CTLS 0x483 +#define MSR_VMX_TRUE_EXIT_CTLS 0x48f + +#define MSR_VMX_ENTRY_CTLS 0x484 +#define MSR_VMX_TRUE_ENTRY_CTLS 0x490 + +#define MSR_VMX_CR0_FIXED0 0x486 +#define MSR_VMX_CR0_FIXED1 0x487 + +#define MSR_VMX_CR4_FIXED0 0x488 +#define MSR_VMX_CR4_FIXED1 0x489 + +uint32_t vmx_revision(void); + +int vmx_set_ctlreg(int ctl_reg, int true_ctl_reg, uint32_t ones_mask, + uint32_t zeros_mask, uint32_t *retval); + +/* + * According to Section 21.10.4 "Software Access to Related Structures", + * changes to data structures pointed to by the VMCS must be made only when + * there is no logical processor with a current VMCS that points to the + * data structure. + * + * This pretty much limits us to configuring the MSR bitmap before VMCS + * initialization for SMP VMs. Unless of course we do it the hard way - which + * would involve some form of synchronization between the vcpus to vmclear + * all VMCSs' that point to the bitmap. + */ +#define MSR_BITMAP_ACCESS_NONE 0x0 +#define MSR_BITMAP_ACCESS_READ 0x1 +#define MSR_BITMAP_ACCESS_WRITE 0x2 +#define MSR_BITMAP_ACCESS_RW (MSR_BITMAP_ACCESS_READ|MSR_BITMAP_ACCESS_WRITE) +void msr_bitmap_initialize(char *bitmap); +int msr_bitmap_change_access(char *bitmap, u_int msr, int access); + +#endif diff --git a/sys/amd64/vmm/intel/vmx_support.S b/sys/amd64/vmm/intel/vmx_support.S new file mode 100644 index 00000000000..4d1bf1da13d --- /dev/null +++ b/sys/amd64/vmm/intel/vmx_support.S @@ -0,0 +1,204 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include + +#include "vmx_assym.s" + +/* + * Assumes that %rdi holds a pointer to the 'vmxctx' + */ +#define VMX_GUEST_RESTORE \ + /* \ + * Make sure that interrupts are disabled before restoring CR2. \ + * Otherwise there could be a page fault during the interrupt \ + * handler execution that would end up trashing CR2. \ + */ \ + cli; \ + movq VMXCTX_GUEST_CR2(%rdi),%rsi; \ + movq %rsi,%cr2; \ + movq VMXCTX_GUEST_RSI(%rdi),%rsi; \ + movq VMXCTX_GUEST_RDX(%rdi),%rdx; \ + movq VMXCTX_GUEST_RCX(%rdi),%rcx; \ + movq VMXCTX_GUEST_R8(%rdi),%r8; \ + movq VMXCTX_GUEST_R9(%rdi),%r9; \ + movq VMXCTX_GUEST_RAX(%rdi),%rax; \ + movq VMXCTX_GUEST_RBX(%rdi),%rbx; \ + movq VMXCTX_GUEST_RBP(%rdi),%rbp; \ + movq VMXCTX_GUEST_R10(%rdi),%r10; \ + movq VMXCTX_GUEST_R11(%rdi),%r11; \ + movq VMXCTX_GUEST_R12(%rdi),%r12; \ + movq VMXCTX_GUEST_R13(%rdi),%r13; \ + movq VMXCTX_GUEST_R14(%rdi),%r14; \ + movq VMXCTX_GUEST_R15(%rdi),%r15; \ + movq VMXCTX_GUEST_RDI(%rdi),%rdi; /* restore rdi the last */ + +#define VM_INSTRUCTION_ERROR(reg) \ + jnc 1f; \ + movl $VM_FAIL_INVALID,reg; /* CF is set */ \ + jmp 3f; \ +1: jnz 2f; \ + movl $VM_FAIL_VALID,reg; /* ZF is set */ \ + jmp 3f; \ +2: movl $VM_SUCCESS,reg; \ +3: movl reg,VMXCTX_LAUNCH_ERROR(%rsp) + + .text +/* + * int vmx_setjmp(ctxp) + * %rdi = ctxp + * + * Return value is '0' when it returns directly from here. + * Return value is '1' when it returns after a vm exit through vmx_longjmp. + */ +ENTRY(vmx_setjmp) + movq (%rsp),%rax /* return address */ + movq %r15,VMXCTX_HOST_R15(%rdi) + movq %r14,VMXCTX_HOST_R14(%rdi) + movq %r13,VMXCTX_HOST_R13(%rdi) + movq %r12,VMXCTX_HOST_R12(%rdi) + movq %rbp,VMXCTX_HOST_RBP(%rdi) + movq %rsp,VMXCTX_HOST_RSP(%rdi) + movq %rbx,VMXCTX_HOST_RBX(%rdi) + movq %rax,VMXCTX_HOST_RIP(%rdi) + + /* + * XXX save host debug registers + */ + movl $VMX_RETURN_DIRECT,%eax + ret +END(vmx_setjmp) + +/* + * void vmx_return(struct vmxctx *ctxp, int retval) + * %rdi = ctxp + * %rsi = retval + * Return to vmm context through vmx_setjmp() with a value of 'retval'. + */ +ENTRY(vmx_return) + /* Restore host context. */ + movq VMXCTX_HOST_R15(%rdi),%r15 + movq VMXCTX_HOST_R14(%rdi),%r14 + movq VMXCTX_HOST_R13(%rdi),%r13 + movq VMXCTX_HOST_R12(%rdi),%r12 + movq VMXCTX_HOST_RBP(%rdi),%rbp + movq VMXCTX_HOST_RSP(%rdi),%rsp + movq VMXCTX_HOST_RBX(%rdi),%rbx + movq VMXCTX_HOST_RIP(%rdi),%rax + movq %rax,(%rsp) /* return address */ + + /* + * XXX restore host debug registers + */ + movl %esi,%eax + ret +END(vmx_return) + +/* + * void vmx_longjmp(void) + * %rsp points to the struct vmxctx + */ +ENTRY(vmx_longjmp) + /* + * Save guest state that is not automatically saved in the vmcs. + */ + movq %rdi,VMXCTX_GUEST_RDI(%rsp) + movq %rsi,VMXCTX_GUEST_RSI(%rsp) + movq %rdx,VMXCTX_GUEST_RDX(%rsp) + movq %rcx,VMXCTX_GUEST_RCX(%rsp) + movq %r8,VMXCTX_GUEST_R8(%rsp) + movq %r9,VMXCTX_GUEST_R9(%rsp) + movq %rax,VMXCTX_GUEST_RAX(%rsp) + movq %rbx,VMXCTX_GUEST_RBX(%rsp) + movq %rbp,VMXCTX_GUEST_RBP(%rsp) + movq %r10,VMXCTX_GUEST_R10(%rsp) + movq %r11,VMXCTX_GUEST_R11(%rsp) + movq %r12,VMXCTX_GUEST_R12(%rsp) + movq %r13,VMXCTX_GUEST_R13(%rsp) + movq %r14,VMXCTX_GUEST_R14(%rsp) + movq %r15,VMXCTX_GUEST_R15(%rsp) + + movq %cr2,%rdi + movq %rdi,VMXCTX_GUEST_CR2(%rsp) + + movq %rsp,%rdi + movq $VMX_RETURN_LONGJMP,%rsi + callq vmx_return +END(vmx_longjmp) + +/* + * void vmx_resume(struct vmxctx *ctxp) + * %rdi = ctxp + * + * Although the return type is a 'void' this function may return indirectly + * through vmx_setjmp() with a return value of 2. + */ +ENTRY(vmx_resume) + /* + * Restore guest state that is not automatically loaded from the vmcs. + */ + VMX_GUEST_RESTORE + + vmresume + + /* + * Capture the reason why vmresume failed. + */ + VM_INSTRUCTION_ERROR(%eax) + + /* Return via vmx_setjmp with return value of VMX_RETURN_VMRESUME */ + movq %rsp,%rdi + movq $VMX_RETURN_VMRESUME,%rsi + callq vmx_return +END(vmx_resume) + +/* + * void vmx_launch(struct vmxctx *ctxp) + * %rdi = ctxp + * + * Although the return type is a 'void' this function may return indirectly + * through vmx_setjmp() with a return value of 3. + */ +ENTRY(vmx_launch) + /* + * Restore guest state that is not automatically loaded from the vmcs. + */ + VMX_GUEST_RESTORE + + vmlaunch + + /* + * Capture the reason why vmlaunch failed. + */ + VM_INSTRUCTION_ERROR(%eax) + + /* Return via vmx_setjmp with return value of VMX_RETURN_VMLAUNCH */ + movq %rsp,%rdi + movq $VMX_RETURN_VMLAUNCH,%rsi + callq vmx_return +END(vmx_launch) diff --git a/sys/amd64/vmm/intel/vtd.c b/sys/amd64/vmm/intel/vtd.c new file mode 100644 index 00000000000..24495a97747 --- /dev/null +++ b/sys/amd64/vmm/intel/vtd.c @@ -0,0 +1,637 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include "io/iommu.h" + +/* + * Documented in the "Intel Virtualization Technology for Directed I/O", + * Architecture Spec, September 2008. + */ + +/* Section 10.4 "Register Descriptions" */ +struct vtdmap { + volatile uint32_t version; + volatile uint32_t res0; + volatile uint64_t cap; + volatile uint64_t ext_cap; + volatile uint32_t gcr; + volatile uint32_t gsr; + volatile uint64_t rta; + volatile uint64_t ccr; +}; + +#define VTD_CAP_SAGAW(cap) (((cap) >> 8) & 0x1F) +#define VTD_CAP_ND(cap) ((cap) & 0x7) +#define VTD_CAP_CM(cap) (((cap) >> 7) & 0x1) +#define VTD_CAP_SPS(cap) (((cap) >> 34) & 0xF) +#define VTD_CAP_RWBF(cap) (((cap) >> 4) & 0x1) + +#define VTD_ECAP_DI(ecap) (((ecap) >> 2) & 0x1) +#define VTD_ECAP_COHERENCY(ecap) ((ecap) & 0x1) +#define VTD_ECAP_IRO(ecap) (((ecap) >> 8) & 0x3FF) + +#define VTD_GCR_WBF (1 << 27) +#define VTD_GCR_SRTP (1 << 30) +#define VTD_GCR_TE (1 << 31) + +#define VTD_GSR_WBFS (1 << 27) +#define VTD_GSR_RTPS (1 << 30) +#define VTD_GSR_TES (1 << 31) + +#define VTD_CCR_ICC (1UL << 63) /* invalidate context cache */ +#define VTD_CCR_CIRG_GLOBAL (1UL << 61) /* global invalidation */ + +#define VTD_IIR_IVT (1UL << 63) /* invalidation IOTLB */ +#define VTD_IIR_IIRG_GLOBAL (1ULL << 60) /* global IOTLB invalidation */ +#define VTD_IIR_IIRG_DOMAIN (2ULL << 60) /* domain IOTLB invalidation */ +#define VTD_IIR_IIRG_PAGE (3ULL << 60) /* page IOTLB invalidation */ +#define VTD_IIR_DRAIN_READS (1ULL << 49) /* drain pending DMA reads */ +#define VTD_IIR_DRAIN_WRITES (1ULL << 48) /* drain pending DMA writes */ +#define VTD_IIR_DOMAIN_P 32 + +#define VTD_ROOT_PRESENT 0x1 +#define VTD_CTX_PRESENT 0x1 +#define VTD_CTX_TT_ALL (1UL << 2) + +#define VTD_PTE_RD (1UL << 0) +#define VTD_PTE_WR (1UL << 1) +#define VTD_PTE_SUPERPAGE (1UL << 7) +#define VTD_PTE_ADDR_M (0x000FFFFFFFFFF000UL) + +struct domain { + uint64_t *ptp; /* first level page table page */ + int pt_levels; /* number of page table levels */ + int addrwidth; /* 'AW' field in context entry */ + int spsmask; /* supported super page sizes */ + u_int id; /* domain id */ + vm_paddr_t maxaddr; /* highest address to be mapped */ + SLIST_ENTRY(domain) next; +}; + +static SLIST_HEAD(, domain) domhead; + +#define DRHD_MAX_UNITS 8 +static int drhd_num; +static struct vtdmap *vtdmaps[DRHD_MAX_UNITS]; +static int max_domains; +typedef int (*drhd_ident_func_t)(void); + +static uint64_t root_table[PAGE_SIZE / sizeof(uint64_t)] __aligned(4096); +static uint64_t ctx_tables[256][PAGE_SIZE / sizeof(uint64_t)] __aligned(4096); + +static MALLOC_DEFINE(M_VTD, "vtd", "vtd"); + +/* + * Config space register definitions from the "Intel 5520 and 5500" datasheet. + */ +static int +tylersburg_vtd_ident(void) +{ + int units, nlbus; + uint16_t did, vid; + uint32_t miscsts, vtbar; + + const int bus = 0; + const int slot = 20; + const int func = 0; + + units = 0; + + vid = pci_cfgregread(bus, slot, func, PCIR_VENDOR, 2); + did = pci_cfgregread(bus, slot, func, PCIR_DEVICE, 2); + if (vid != 0x8086 || did != 0x342E) + goto done; + + /* + * Check if this is a dual IOH configuration. + */ + miscsts = pci_cfgregread(bus, slot, func, 0x9C, 4); + if (miscsts & (1 << 25)) + nlbus = pci_cfgregread(bus, slot, func, 0x160, 1); + else + nlbus = -1; + + vtbar = pci_cfgregread(bus, slot, func, 0x180, 4); + if (vtbar & 0x1) { + vtdmaps[units++] = (struct vtdmap *) + PHYS_TO_DMAP(vtbar & 0xffffe000); + } else if (bootverbose) + printf("VT-d unit in legacy IOH is disabled!\n"); + + if (nlbus != -1) { + vtbar = pci_cfgregread(nlbus, slot, func, 0x180, 4); + if (vtbar & 0x1) { + vtdmaps[units++] = (struct vtdmap *) + PHYS_TO_DMAP(vtbar & 0xffffe000); + } else if (bootverbose) + printf("VT-d unit in non-legacy IOH is disabled!\n"); + } +done: + return (units); +} + +static drhd_ident_func_t drhd_ident_funcs[] = { + tylersburg_vtd_ident, + NULL +}; + +static int +vtd_max_domains(struct vtdmap *vtdmap) +{ + int nd; + + nd = VTD_CAP_ND(vtdmap->cap); + + switch (nd) { + case 0: + return (16); + case 1: + return (64); + case 2: + return (256); + case 3: + return (1024); + case 4: + return (4 * 1024); + case 5: + return (16 * 1024); + case 6: + return (64 * 1024); + default: + panic("vtd_max_domains: invalid value of nd (0x%0x)", nd); + } +} + +static u_int +domain_id(void) +{ + u_int id; + struct domain *dom; + + /* Skip domain id 0 - it is reserved when Caching Mode field is set */ + for (id = 1; id < max_domains; id++) { + SLIST_FOREACH(dom, &domhead, next) { + if (dom->id == id) + break; + } + if (dom == NULL) + break; /* found it */ + } + + if (id >= max_domains) + panic("domain ids exhausted"); + + return (id); +} + +static void +vtd_wbflush(struct vtdmap *vtdmap) +{ + + if (VTD_ECAP_COHERENCY(vtdmap->ext_cap) == 0) + pmap_invalidate_cache(); + + if (VTD_CAP_RWBF(vtdmap->cap)) { + vtdmap->gcr = VTD_GCR_WBF; + while ((vtdmap->gsr & VTD_GSR_WBFS) != 0) + ; + } +} + +static void +vtd_ctx_global_invalidate(struct vtdmap *vtdmap) +{ + + vtdmap->ccr = VTD_CCR_ICC | VTD_CCR_CIRG_GLOBAL; + while ((vtdmap->ccr & VTD_CCR_ICC) != 0) + ; +} + +static void +vtd_iotlb_global_invalidate(struct vtdmap *vtdmap) +{ + int offset; + volatile uint64_t *iotlb_reg, val; + + vtd_wbflush(vtdmap); + + offset = VTD_ECAP_IRO(vtdmap->ext_cap) * 16; + iotlb_reg = (volatile uint64_t *)((caddr_t)vtdmap + offset + 8); + + *iotlb_reg = VTD_IIR_IVT | VTD_IIR_IIRG_GLOBAL | + VTD_IIR_DRAIN_READS | VTD_IIR_DRAIN_WRITES; + + while (1) { + val = *iotlb_reg; + if ((val & VTD_IIR_IVT) == 0) + break; + } +} + +static void +vtd_translation_enable(struct vtdmap *vtdmap) +{ + + vtdmap->gcr = VTD_GCR_TE; + while ((vtdmap->gsr & VTD_GSR_TES) == 0) + ; +} + +static void +vtd_translation_disable(struct vtdmap *vtdmap) +{ + + vtdmap->gcr = 0; + while ((vtdmap->gsr & VTD_GSR_TES) != 0) + ; +} + +static int +vtd_init(void) +{ + int i, units; + struct vtdmap *vtdmap; + vm_paddr_t ctx_paddr; + + for (i = 0; drhd_ident_funcs[i] != NULL; i++) { + units = (*drhd_ident_funcs[i])(); + if (units > 0) + break; + } + + if (units <= 0) + return (ENXIO); + + drhd_num = units; + vtdmap = vtdmaps[0]; + + if (VTD_CAP_CM(vtdmap->cap) != 0) + panic("vtd_init: invalid caching mode"); + + max_domains = vtd_max_domains(vtdmap); + + /* + * Set up the root-table to point to the context-entry tables + */ + for (i = 0; i < 256; i++) { + ctx_paddr = vtophys(ctx_tables[i]); + if (ctx_paddr & PAGE_MASK) + panic("ctx table (0x%0lx) not page aligned", ctx_paddr); + + root_table[i * 2] = ctx_paddr | VTD_ROOT_PRESENT; + } + + return (0); +} + +static void +vtd_cleanup(void) +{ +} + +static void +vtd_enable(void) +{ + int i; + struct vtdmap *vtdmap; + + for (i = 0; i < drhd_num; i++) { + vtdmap = vtdmaps[i]; + vtd_wbflush(vtdmap); + + /* Update the root table address */ + vtdmap->rta = vtophys(root_table); + vtdmap->gcr = VTD_GCR_SRTP; + while ((vtdmap->gsr & VTD_GSR_RTPS) == 0) + ; + + vtd_ctx_global_invalidate(vtdmap); + vtd_iotlb_global_invalidate(vtdmap); + + vtd_translation_enable(vtdmap); + } +} + +static void +vtd_disable(void) +{ + int i; + struct vtdmap *vtdmap; + + for (i = 0; i < drhd_num; i++) { + vtdmap = vtdmaps[i]; + vtd_translation_disable(vtdmap); + } +} + +static void +vtd_add_device(void *arg, int bus, int slot, int func) +{ + int idx; + uint64_t *ctxp; + struct domain *dom = arg; + vm_paddr_t pt_paddr; + struct vtdmap *vtdmap; + + if (bus < 0 || bus > PCI_BUSMAX || + slot < 0 || slot > PCI_SLOTMAX || + func < 0 || func > PCI_FUNCMAX) + panic("vtd_add_device: invalid bsf %d/%d/%d", bus, slot, func); + + vtdmap = vtdmaps[0]; + ctxp = ctx_tables[bus]; + pt_paddr = vtophys(dom->ptp); + idx = (slot << 3 | func) * 2; + + if (ctxp[idx] & VTD_CTX_PRESENT) { + panic("vtd_add_device: device %d/%d/%d is already owned by " + "domain %d", bus, slot, func, + (uint16_t)(ctxp[idx + 1] >> 8)); + } + + /* + * Order is important. The 'present' bit is set only after all fields + * of the context pointer are initialized. + */ + ctxp[idx + 1] = dom->addrwidth | (dom->id << 8); + + if (VTD_ECAP_DI(vtdmap->ext_cap)) + ctxp[idx] = VTD_CTX_TT_ALL; + else + ctxp[idx] = 0; + + ctxp[idx] |= pt_paddr | VTD_CTX_PRESENT; + + /* + * 'Not Present' entries are not cached in either the Context Cache + * or in the IOTLB, so there is no need to invalidate either of them. + */ +} + +static void +vtd_remove_device(void *arg, int bus, int slot, int func) +{ + int i, idx; + uint64_t *ctxp; + struct vtdmap *vtdmap; + + if (bus < 0 || bus > PCI_BUSMAX || + slot < 0 || slot > PCI_SLOTMAX || + func < 0 || func > PCI_FUNCMAX) + panic("vtd_add_device: invalid bsf %d/%d/%d", bus, slot, func); + + ctxp = ctx_tables[bus]; + idx = (slot << 3 | func) * 2; + + /* + * Order is important. The 'present' bit is must be cleared first. + */ + ctxp[idx] = 0; + ctxp[idx + 1] = 0; + + /* + * Invalidate the Context Cache and the IOTLB. + * + * XXX use device-selective invalidation for Context Cache + * XXX use domain-selective invalidation for IOTLB + */ + for (i = 0; i < drhd_num; i++) { + vtdmap = vtdmaps[i]; + vtd_ctx_global_invalidate(vtdmap); + vtd_iotlb_global_invalidate(vtdmap); + } +} + +static uint64_t +vtd_create_mapping(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len) +{ + struct domain *dom; + int i, spshift, ptpshift, ptpindex, nlevels; + uint64_t spsize, *ptp; + + dom = arg; + ptpindex = 0; + ptpshift = 0; + + if (gpa & PAGE_MASK) + panic("vtd_create_mapping: unaligned gpa 0x%0lx", gpa); + + if (hpa & PAGE_MASK) + panic("vtd_create_mapping: unaligned hpa 0x%0lx", hpa); + + if (len & PAGE_MASK) + panic("vtd_create_mapping: unaligned len 0x%0lx", len); + + /* + * Compute the size of the mapping that we can accomodate. + * + * This is based on three factors: + * - supported super page size + * - alignment of the region starting at 'gpa' and 'hpa' + * - length of the region 'len' + */ + spshift = 48; + for (i = 3; i >= 0; i--) { + spsize = 1UL << spshift; + if ((dom->spsmask & (1 << i)) != 0 && + (gpa & (spsize - 1)) == 0 && + (hpa & (spsize - 1)) == 0 && + (len >= spsize)) { + break; + } + spshift -= 9; + } + + ptp = dom->ptp; + nlevels = dom->pt_levels; + while (--nlevels >= 0) { + ptpshift = 12 + nlevels * 9; + ptpindex = (gpa >> ptpshift) & 0x1FF; + + /* We have reached the leaf mapping */ + if (spshift >= ptpshift) { + break; + } + + /* + * We are working on a non-leaf page table page. + * + * Create a downstream page table page if necessary and point + * to it from the current page table. + */ + if (ptp[ptpindex] == 0) { + void *nlp = malloc(PAGE_SIZE, M_VTD, M_WAITOK | M_ZERO); + ptp[ptpindex] = vtophys(nlp)| VTD_PTE_RD | VTD_PTE_WR; + } + + ptp = (uint64_t *)PHYS_TO_DMAP(ptp[ptpindex] & VTD_PTE_ADDR_M); + } + + if ((gpa & ((1UL << ptpshift) - 1)) != 0) + panic("gpa 0x%lx and ptpshift %d mismatch", gpa, ptpshift); + + /* + * Create a 'gpa' -> 'hpa' mapping + */ + ptp[ptpindex] = hpa | VTD_PTE_RD | VTD_PTE_WR; + + if (nlevels > 0) + ptp[ptpindex] |= VTD_PTE_SUPERPAGE; + + return (1UL << ptpshift); +} + +static void * +vtd_create_domain(vm_paddr_t maxaddr) +{ + struct domain *dom; + vm_paddr_t addr; + int tmp, i, gaw, agaw, sagaw, res, pt_levels, addrwidth; + struct vtdmap *vtdmap; + + if (drhd_num <= 0) + panic("vtd_create_domain: no dma remapping hardware available"); + + vtdmap = vtdmaps[0]; + + /* + * Calculate AGAW. + * Section 3.4.2 "Adjusted Guest Address Width", Architecture Spec. + */ + addr = 0; + for (gaw = 0; addr < maxaddr; gaw++) + addr = 1ULL << gaw; + + res = (gaw - 12) % 9; + if (res == 0) + agaw = gaw; + else + agaw = gaw + 9 - res; + + if (agaw > 64) + agaw = 64; + + /* + * Select the smallest Supported AGAW and the corresponding number + * of page table levels. + */ + pt_levels = 2; + sagaw = 30; + addrwidth = 0; + tmp = VTD_CAP_SAGAW(vtdmap->cap); + for (i = 0; i < 5; i++) { + if ((tmp & (1 << i)) != 0 && sagaw >= agaw) + break; + pt_levels++; + addrwidth++; + sagaw += 9; + if (sagaw > 64) + sagaw = 64; + } + + if (i >= 5) { + panic("vtd_create_domain: SAGAW 0x%lx does not support AGAW %d", + VTD_CAP_SAGAW(vtdmap->cap), agaw); + } + + dom = malloc(sizeof(struct domain), M_VTD, M_ZERO | M_WAITOK); + dom->pt_levels = pt_levels; + dom->addrwidth = addrwidth; + dom->spsmask = VTD_CAP_SPS(vtdmap->cap); + dom->id = domain_id(); + dom->maxaddr = maxaddr; + dom->ptp = malloc(PAGE_SIZE, M_VTD, M_ZERO | M_WAITOK); + if ((uintptr_t)dom->ptp & PAGE_MASK) + panic("vtd_create_domain: ptp (%p) not page aligned", dom->ptp); + + SLIST_INSERT_HEAD(&domhead, dom, next); + + return (dom); +} + +static void +vtd_free_ptp(uint64_t *ptp, int level) +{ + int i; + uint64_t *nlp; + + if (level > 1) { + for (i = 0; i < 512; i++) { + if ((ptp[i] & (VTD_PTE_RD | VTD_PTE_WR)) == 0) + continue; + if ((ptp[i] & VTD_PTE_SUPERPAGE) != 0) + continue; + nlp = (uint64_t *)PHYS_TO_DMAP(ptp[i] & VTD_PTE_ADDR_M); + vtd_free_ptp(nlp, level - 1); + } + } + + bzero(ptp, PAGE_SIZE); + free(ptp, M_VTD); +} + +static void +vtd_destroy_domain(void *arg) +{ + struct domain *dom; + + dom = arg; + + SLIST_REMOVE(&domhead, dom, domain, next); + vtd_free_ptp(dom->ptp, dom->pt_levels); + free(dom, M_VTD); +} + +struct iommu_ops iommu_ops_intel = { + vtd_init, + vtd_cleanup, + vtd_enable, + vtd_disable, + vtd_create_domain, + vtd_destroy_domain, + vtd_create_mapping, + vtd_add_device, + vtd_remove_device, +}; diff --git a/sys/amd64/vmm/io/iommu.c b/sys/amd64/vmm/io/iommu.c new file mode 100644 index 00000000000..baf2447c4fa --- /dev/null +++ b/sys/amd64/vmm/io/iommu.c @@ -0,0 +1,230 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include + +#include "vmm_util.h" +#include "iommu.h" + +static boolean_t iommu_avail; +static struct iommu_ops *ops; +static void *host_domain; + +static __inline int +IOMMU_INIT(void) +{ + if (ops != NULL) + return ((*ops->init)()); + else + return (ENXIO); +} + +static __inline void +IOMMU_CLEANUP(void) +{ + if (ops != NULL && iommu_avail) + (*ops->cleanup)(); +} + +static __inline void * +IOMMU_CREATE_DOMAIN(vm_paddr_t maxaddr) +{ + + if (ops != NULL && iommu_avail) + return ((*ops->create_domain)(maxaddr)); + else + return (NULL); +} + +static __inline void +IOMMU_DESTROY_DOMAIN(void *dom) +{ + + if (ops != NULL && iommu_avail) + (*ops->destroy_domain)(dom); +} + +static __inline uint64_t +IOMMU_CREATE_MAPPING(void *domain, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len) +{ + + if (ops != NULL && iommu_avail) + return ((*ops->create_mapping)(domain, gpa, hpa, len)); + else + return (len); /* XXX */ +} + +static __inline void +IOMMU_ADD_DEVICE(void *domain, int bus, int slot, int func) +{ + + if (ops != NULL && iommu_avail) + (*ops->add_device)(domain, bus, slot, func); +} + +static __inline void +IOMMU_REMOVE_DEVICE(void *domain, int bus, int slot, int func) +{ + + if (ops != NULL && iommu_avail) + (*ops->remove_device)(domain, bus, slot, func); +} + +static __inline void +IOMMU_ENABLE(void) +{ + + if (ops != NULL && iommu_avail) + (*ops->enable)(); +} + +static __inline void +IOMMU_DISABLE(void) +{ + + if (ops != NULL && iommu_avail) + (*ops->disable)(); +} + +void +iommu_init(void) +{ + int error, bus, slot, func; + vm_paddr_t maxaddr; + const char *name; + device_t dev; + + if (vmm_is_intel()) + ops = &iommu_ops_intel; + else if (vmm_is_amd()) + ops = &iommu_ops_amd; + else + ops = NULL; + + error = IOMMU_INIT(); + if (error) + return; + + iommu_avail = TRUE; + + /* + * Create a domain for the devices owned by the host + */ + maxaddr = ptoa(Maxmem); + host_domain = IOMMU_CREATE_DOMAIN(maxaddr); + if (host_domain == NULL) + panic("iommu_init: unable to create a host domain"); + + /* + * Create 1:1 mappings from '0' to 'Maxmem' for devices assigned to + * the host + */ + iommu_create_mapping(host_domain, 0, 0, maxaddr); + + for (bus = 0; bus <= PCI_BUSMAX; bus++) { + for (slot = 0; slot <= PCI_SLOTMAX; slot++) { + for (func = 0; func <= PCI_FUNCMAX; func++) { + dev = pci_find_dbsf(0, bus, slot, func); + if (dev == NULL) + continue; + + /* skip passthrough devices */ + name = device_get_name(dev); + if (name != NULL && strcmp(name, "ppt") == 0) + continue; + + /* everything else belongs to the host domain */ + iommu_add_device(host_domain, bus, slot, func); + } + } + } + IOMMU_ENABLE(); + +} + +void +iommu_cleanup(void) +{ + IOMMU_DISABLE(); + IOMMU_DESTROY_DOMAIN(host_domain); + IOMMU_CLEANUP(); +} + +void * +iommu_create_domain(vm_paddr_t maxaddr) +{ + + return (IOMMU_CREATE_DOMAIN(maxaddr)); +} + +void +iommu_destroy_domain(void *dom) +{ + + IOMMU_DESTROY_DOMAIN(dom); +} + +void +iommu_create_mapping(void *dom, vm_paddr_t gpa, vm_paddr_t hpa, size_t len) +{ + uint64_t mapped, remaining; + + remaining = len; + + while (remaining > 0) { + mapped = IOMMU_CREATE_MAPPING(dom, gpa, hpa, remaining); + gpa += mapped; + hpa += mapped; + remaining -= mapped; + } +} + +void +iommu_add_device(void *dom, int bus, int slot, int func) +{ + + IOMMU_ADD_DEVICE(dom, bus, slot, func); +} + +void +iommu_remove_device(void *dom, int bus, int slot, int func) +{ + + IOMMU_REMOVE_DEVICE(dom, bus, slot, func); +} diff --git a/sys/amd64/vmm/io/iommu.h b/sys/amd64/vmm/io/iommu.h new file mode 100644 index 00000000000..e4f722914fd --- /dev/null +++ b/sys/amd64/vmm/io/iommu.h @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _IO_IOMMU_H_ +#define _IO_IOMMU_H_ + +typedef int (*iommu_init_func_t)(void); +typedef void (*iommu_cleanup_func_t)(void); +typedef void (*iommu_enable_func_t)(void); +typedef void (*iommu_disable_func_t)(void); +typedef void *(*iommu_create_domain_t)(vm_paddr_t maxaddr); +typedef void (*iommu_destroy_domain_t)(void *domain); +typedef uint64_t (*iommu_create_mapping_t)(void *domain, vm_paddr_t gpa, + vm_paddr_t hpa, uint64_t len); +typedef void (*iommu_add_device_t)(void *domain, int bus, int slot, int func); +typedef void (*iommu_remove_device_t)(void *dom, int bus, int slot, int func); + +struct iommu_ops { + iommu_init_func_t init; /* module wide */ + iommu_cleanup_func_t cleanup; + iommu_enable_func_t enable; + iommu_disable_func_t disable; + + iommu_create_domain_t create_domain; /* domain-specific */ + iommu_destroy_domain_t destroy_domain; + iommu_create_mapping_t create_mapping; + iommu_add_device_t add_device; + iommu_remove_device_t remove_device; +}; + +extern struct iommu_ops iommu_ops_intel; +extern struct iommu_ops iommu_ops_amd; + +void iommu_init(void); +void iommu_cleanup(void); +void *iommu_create_domain(vm_paddr_t maxaddr); +void iommu_destroy_domain(void *dom); +void iommu_create_mapping(void *dom, vm_paddr_t gpa, vm_paddr_t hpa, + size_t len); +void iommu_add_device(void *dom, int bus, int slot, int func); +void iommu_remove_device(void *dom, int bus, int slot, int func); +#endif diff --git a/sys/amd64/vmm/io/ppt.c b/sys/amd64/vmm/io/ppt.c new file mode 100644 index 00000000000..dc2f326b1e8 --- /dev/null +++ b/sys/amd64/vmm/io/ppt.c @@ -0,0 +1,449 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include "vmm_lapic.h" +#include "vmm_ktr.h" + +#include "iommu.h" +#include "ppt.h" + +#define MAX_PPTDEVS (sizeof(pptdevs) / sizeof(pptdevs[0])) +#define MAX_MMIOSEGS (PCIR_MAX_BAR_0 + 1) +#define MAX_MSIMSGS 32 + +struct pptintr_arg { /* pptintr(pptintr_arg) */ + struct pptdev *pptdev; + int msg; +}; + +static struct pptdev { + device_t dev; + struct vm *vm; /* owner of this device */ + struct vm_memory_segment mmio[MAX_MMIOSEGS]; + struct { + int num_msgs; /* guest state */ + int vector; + int vcpu; + + int startrid; /* host state */ + struct resource *res[MAX_MSIMSGS]; + void *cookie[MAX_MSIMSGS]; + struct pptintr_arg arg[MAX_MSIMSGS]; + } msi; +} pptdevs[32]; + +static int num_pptdevs; + +static int +ppt_probe(device_t dev) +{ + int bus, slot, func; + struct pci_devinfo *dinfo; + + dinfo = (struct pci_devinfo *)device_get_ivars(dev); + + bus = pci_get_bus(dev); + slot = pci_get_slot(dev); + func = pci_get_function(dev); + + /* + * To qualify as a pci passthrough device a device must: + * - be allowed by administrator to be used in this role + * - be an endpoint device + */ + if (vmm_is_pptdev(bus, slot, func) && + (dinfo->cfg.hdrtype & PCIM_HDRTYPE) == PCIM_HDRTYPE_NORMAL) + return (0); + else + return (ENXIO); +} + +static int +ppt_attach(device_t dev) +{ + int n; + + if (num_pptdevs >= MAX_PPTDEVS) { + printf("ppt_attach: maximum number of pci passthrough devices " + "exceeded\n"); + return (ENXIO); + } + + n = num_pptdevs++; + pptdevs[n].dev = dev; + + if (bootverbose) + device_printf(dev, "attached\n"); + + return (0); +} + +static int +ppt_detach(device_t dev) +{ + /* + * XXX check whether there are any pci passthrough devices assigned + * to guests before we allow this driver to detach. + */ + + return (0); +} + +static device_method_t ppt_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ppt_probe), + DEVMETHOD(device_attach, ppt_attach), + DEVMETHOD(device_detach, ppt_detach), + {0, 0} +}; + +static devclass_t ppt_devclass; +DEFINE_CLASS_0(ppt, ppt_driver, ppt_methods, 0); +DRIVER_MODULE(ppt, pci, ppt_driver, ppt_devclass, NULL, NULL); + +static struct pptdev * +ppt_find(int bus, int slot, int func) +{ + device_t dev; + int i, b, s, f; + + for (i = 0; i < num_pptdevs; i++) { + dev = pptdevs[i].dev; + b = pci_get_bus(dev); + s = pci_get_slot(dev); + f = pci_get_function(dev); + if (bus == b && slot == s && func == f) + return (&pptdevs[i]); + } + return (NULL); +} + +static void +ppt_unmap_mmio(struct vm *vm, struct pptdev *ppt) +{ + int i; + struct vm_memory_segment *seg; + + for (i = 0; i < MAX_MMIOSEGS; i++) { + seg = &ppt->mmio[i]; + if (seg->len == 0) + continue; + (void)vm_unmap_mmio(vm, seg->gpa, seg->len); + bzero(seg, sizeof(struct vm_memory_segment)); + } +} + +static void +ppt_teardown_msi(struct pptdev *ppt) +{ + int i, rid; + void *cookie; + struct resource *res; + + if (ppt->msi.num_msgs == 0) + return; + + for (i = 0; i < ppt->msi.num_msgs; i++) { + rid = ppt->msi.startrid + i; + res = ppt->msi.res[i]; + cookie = ppt->msi.cookie[i]; + + if (cookie != NULL) + bus_teardown_intr(ppt->dev, res, cookie); + + if (res != NULL) + bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, res); + + ppt->msi.res[i] = NULL; + ppt->msi.cookie[i] = NULL; + } + + if (ppt->msi.startrid == 1) + pci_release_msi(ppt->dev); + + ppt->msi.num_msgs = 0; +} + +int +ppt_assign_device(struct vm *vm, int bus, int slot, int func) +{ + struct pptdev *ppt; + + ppt = ppt_find(bus, slot, func); + if (ppt != NULL) { + /* + * If this device is owned by a different VM then we + * cannot change its owner. + */ + if (ppt->vm != NULL && ppt->vm != vm) + return (EBUSY); + + ppt->vm = vm; + iommu_add_device(vm_iommu_domain(vm), bus, slot, func); + return (0); + } + return (ENOENT); +} + +int +ppt_unassign_device(struct vm *vm, int bus, int slot, int func) +{ + struct pptdev *ppt; + + ppt = ppt_find(bus, slot, func); + if (ppt != NULL) { + /* + * If this device is not owned by this 'vm' then bail out. + */ + if (ppt->vm != vm) + return (EBUSY); + ppt_unmap_mmio(vm, ppt); + ppt_teardown_msi(ppt); + iommu_remove_device(vm_iommu_domain(vm), bus, slot, func); + ppt->vm = NULL; + return (0); + } + return (ENOENT); +} + +int +ppt_unassign_all(struct vm *vm) +{ + int i, bus, slot, func; + device_t dev; + + for (i = 0; i < num_pptdevs; i++) { + if (pptdevs[i].vm == vm) { + dev = pptdevs[i].dev; + bus = pci_get_bus(dev); + slot = pci_get_slot(dev); + func = pci_get_function(dev); + ppt_unassign_device(vm, bus, slot, func); + } + } + + return (0); +} + +int +ppt_map_mmio(struct vm *vm, int bus, int slot, int func, + vm_paddr_t gpa, size_t len, vm_paddr_t hpa) +{ + int i, error; + struct vm_memory_segment *seg; + struct pptdev *ppt; + + ppt = ppt_find(bus, slot, func); + if (ppt != NULL) { + if (ppt->vm != vm) + return (EBUSY); + + for (i = 0; i < MAX_MMIOSEGS; i++) { + seg = &ppt->mmio[i]; + if (seg->len == 0) { + error = vm_map_mmio(vm, gpa, len, hpa); + if (error == 0) { + seg->gpa = gpa; + seg->len = len; + seg->hpa = hpa; + } + return (error); + } + } + return (ENOSPC); + } + return (ENOENT); +} + +static int +pptintr(void *arg) +{ + int vec; + struct pptdev *ppt; + struct pptintr_arg *pptarg; + + pptarg = arg; + ppt = pptarg->pptdev; + vec = ppt->msi.vector + pptarg->msg; + + if (ppt->vm != NULL) + (void) lapic_set_intr(ppt->vm, ppt->msi.vcpu, vec); + else { + /* + * XXX + * This is not expected to happen - panic? + */ + } + + /* + * For legacy interrupts give other filters a chance in case + * the interrupt was not generated by the passthrough device. + */ + if (ppt->msi.startrid == 0) + return (FILTER_STRAY); + else + return (FILTER_HANDLED); +} + +/* + * XXX + * When we try to free the MSI resource the kernel will bind the thread to + * the host cpu was originally handling the MSI. The function freeing the + * MSI vector (apic_free_vector()) will panic the kernel if the thread + * is already bound to a cpu. + * + * So, we temporarily unbind the vcpu thread before freeing the MSI resource. + */ +static void +PPT_TEARDOWN_MSI(struct vm *vm, int vcpu, struct pptdev *ppt) +{ + int pincpu = -1; + + vm_get_pinning(vm, vcpu, &pincpu); + + if (pincpu >= 0) + vm_set_pinning(vm, vcpu, -1); + + ppt_teardown_msi(ppt); + + if (pincpu >= 0) + vm_set_pinning(vm, vcpu, pincpu); +} + +int +ppt_setup_msi(struct vm *vm, int vcpu, int bus, int slot, int func, + int destcpu, int vector, int numvec) +{ + int i, rid, flags; + int msi_count, startrid, error, tmp; + struct pptdev *ppt; + + if ((destcpu >= VM_MAXCPU || destcpu < 0) || + (vector < 0 || vector > 255) || + (numvec < 0 || numvec > MAX_MSIMSGS)) + return (EINVAL); + + ppt = ppt_find(bus, slot, func); + if (ppt == NULL) + return (ENOENT); + if (ppt->vm != vm) /* Make sure we own this device */ + return (EBUSY); + + /* Free any allocated resources */ + PPT_TEARDOWN_MSI(vm, vcpu, ppt); + + if (numvec == 0) /* nothing more to do */ + return (0); + + flags = RF_ACTIVE; + msi_count = pci_msi_count(ppt->dev); + if (msi_count == 0) { + startrid = 0; /* legacy interrupt */ + msi_count = 1; + flags |= RF_SHAREABLE; + } else + startrid = 1; /* MSI */ + + /* + * The device must be capable of supporting the number of vectors + * the guest wants to allocate. + */ + if (numvec > msi_count) + return (EINVAL); + + /* + * Make sure that we can allocate all the MSI vectors that are needed + * by the guest. + */ + if (startrid == 1) { + tmp = numvec; + error = pci_alloc_msi(ppt->dev, &tmp); + if (error) + return (error); + else if (tmp != numvec) { + pci_release_msi(ppt->dev); + return (ENOSPC); + } else { + /* success */ + } + } + + ppt->msi.vector = vector; + ppt->msi.vcpu = destcpu; + ppt->msi.startrid = startrid; + + /* + * Allocate the irq resource and attach it to the interrupt handler. + */ + for (i = 0; i < numvec; i++) { + ppt->msi.num_msgs = i + 1; + ppt->msi.cookie[i] = NULL; + + rid = startrid + i; + ppt->msi.res[i] = bus_alloc_resource_any(ppt->dev, SYS_RES_IRQ, + &rid, flags); + if (ppt->msi.res[i] == NULL) + break; + + ppt->msi.arg[i].pptdev = ppt; + ppt->msi.arg[i].msg = i; + + error = bus_setup_intr(ppt->dev, ppt->msi.res[i], + INTR_TYPE_NET | INTR_MPSAFE | INTR_FAST, + pptintr, NULL, &ppt->msi.arg[i], + &ppt->msi.cookie[i]); + if (error != 0) + break; + } + + if (i < numvec) { + PPT_TEARDOWN_MSI(vm, vcpu, ppt); + return (ENXIO); + } + + return (0); +} diff --git a/sys/amd64/vmm/io/ppt.h b/sys/amd64/vmm/io/ppt.h new file mode 100644 index 00000000000..95f3ad08b44 --- /dev/null +++ b/sys/amd64/vmm/io/ppt.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _IO_PPT_H_ +#define _IO_PPT_H_ + +int ppt_assign_device(struct vm *vm, int bus, int slot, int func); +int ppt_unassign_device(struct vm *vm, int bus, int slot, int func); +int ppt_unassign_all(struct vm *vm); +int ppt_map_mmio(struct vm *vm, int bus, int slot, int func, + vm_paddr_t gpa, size_t len, vm_paddr_t hpa); +int ppt_setup_msi(struct vm *vm, int vcpu, int bus, int slot, int func, + int destcpu, int vector, int numvec); + +#endif diff --git a/sys/amd64/vmm/io/vdev.c b/sys/amd64/vmm/io/vdev.c new file mode 100644 index 00000000000..cd6c5d1b39c --- /dev/null +++ b/sys/amd64/vmm/io/vdev.c @@ -0,0 +1,270 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include "vdev.h" + +struct vdev { + SLIST_ENTRY(vdev) entry; + struct vdev_ops *ops; + void *dev; +}; +static SLIST_HEAD(, vdev) vdev_head; +static int vdev_count; + +struct vdev_region { + SLIST_ENTRY(vdev_region) entry; + struct vdev_ops *ops; + void *dev; + struct io_region *io; +}; +static SLIST_HEAD(, vdev_region) region_head; +static int region_count; + +static MALLOC_DEFINE(M_VDEV, "vdev", "vdev"); + +#define VDEV_INIT (0) +#define VDEV_RESET (1) +#define VDEV_HALT (2) + +// static const char* vdev_event_str[] = {"VDEV_INIT", "VDEV_RESET", "VDEV_HALT"}; + +static int +vdev_system_event(int event) +{ + struct vdev *vd; + int rc; + + // TODO: locking + SLIST_FOREACH(vd, &vdev_head, entry) { + // printf("%s : %s Device %s\n", __func__, vdev_event_str[event], vd->ops->name); + switch (event) { + case VDEV_INIT: + rc = vd->ops->init(vd->dev); + break; + case VDEV_RESET: + rc = vd->ops->reset(vd->dev); + break; + case VDEV_HALT: + rc = vd->ops->halt(vd->dev); + break; + default: + break; + } + if (rc) { + printf("vdev %s init failed rc=%d\n", + vd->ops->name, rc); + return rc; + } + } + return 0; +} + +int +vdev_init(void) +{ + return vdev_system_event(VDEV_INIT); +} + +int +vdev_reset(void) +{ + return vdev_system_event(VDEV_RESET); +} + +int +vdev_halt(void) +{ + return vdev_system_event(VDEV_HALT); +} + +void +vdev_vm_init(void) +{ + SLIST_INIT(&vdev_head); + vdev_count = 0; + + SLIST_INIT(®ion_head); + region_count = 0; +} +void +vdev_vm_cleanup(void) +{ + struct vdev *vd; + + // TODO: locking + while (!SLIST_EMPTY(&vdev_head)) { + vd = SLIST_FIRST(&vdev_head); + SLIST_REMOVE_HEAD(&vdev_head, entry); + free(vd, M_VDEV); + vdev_count--; + } +} + +int +vdev_register(struct vdev_ops *ops, void *dev) +{ + struct vdev *vd; + vd = malloc(sizeof(*vd), M_VDEV, M_WAITOK | M_ZERO); + vd->ops = ops; + vd->dev = dev; + + // TODO: locking + SLIST_INSERT_HEAD(&vdev_head, vd, entry); + vdev_count++; + return 0; +} + +void +vdev_unregister(void *dev) +{ + struct vdev *vd, *found; + + found = NULL; + // TODO: locking + SLIST_FOREACH(vd, &vdev_head, entry) { + if (vd->dev == dev) { + found = vd; + } + } + + if (found) { + SLIST_REMOVE(&vdev_head, found, vdev, entry); + free(found, M_VDEV); + } +} + +#define IN_RANGE(val, start, end) \ + (((val) >= (start)) && ((val) < (end))) + +static struct vdev_region* +vdev_find_region(struct io_region *io, void *dev) +{ + struct vdev_region *region, *found; + uint64_t region_base; + uint64_t region_end; + + found = NULL; + + // TODO: locking + // FIXME: we should verify we are in the context the current + // vcpu here as well. + SLIST_FOREACH(region, ®ion_head, entry) { + region_base = region->io->base; + region_end = region_base + region->io->len; + if (IN_RANGE(io->base, region_base, region_end) && + IN_RANGE(io->base+io->len, region_base, region_end+1) && + (dev && dev == region->dev)) { + found = region; + break; + } + } + return found; +} + +int +vdev_register_region(struct vdev_ops *ops, void *dev, struct io_region *io) +{ + struct vdev_region *region; + + region = vdev_find_region(io, dev); + if (region) { + return -EEXIST; + } + + region = malloc(sizeof(*region), M_VDEV, M_WAITOK | M_ZERO); + region->io = io; + region->ops = ops; + region->dev = dev; + + // TODO: locking + SLIST_INSERT_HEAD(®ion_head, region, entry); + region_count++; + + return 0; +} + +void +vdev_unregister_region(void *dev, struct io_region *io) +{ + struct vdev_region *region; + + region = vdev_find_region(io, dev); + + if (region) { + SLIST_REMOVE(®ion_head, region, vdev_region, entry); + free(region, M_VDEV); + region_count--; + } +} + +static int +vdev_memrw(uint64_t gpa, opsize_t size, uint64_t *data, int read) +{ + struct vdev_region *region; + struct io_region io; + region_attr_t attr; + int rc; + + io.base = gpa; + io.len = size; + + region = vdev_find_region(&io, NULL); + if (!region) + return -EINVAL; + + attr = (read) ? MMIO_READ : MMIO_WRITE; + if (!(region->io->attr & attr)) + return -EPERM; + + if (read) + rc = region->ops->memread(region->dev, gpa, size, data); + else + rc = region->ops->memwrite(region->dev, gpa, size, *data); + + return rc; +} + +int +vdev_memread(uint64_t gpa, opsize_t size, uint64_t *data) +{ + return vdev_memrw(gpa, size, data, 1); +} + +int +vdev_memwrite(uint64_t gpa, opsize_t size, uint64_t data) +{ + return vdev_memrw(gpa, size, &data, 0); +} diff --git a/sys/amd64/vmm/io/vdev.h b/sys/amd64/vmm/io/vdev.h new file mode 100644 index 00000000000..6feeba87b7c --- /dev/null +++ b/sys/amd64/vmm/io/vdev.h @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VDEV_H_ +#define _VDEV_H_ + +typedef enum { + BYTE = 1, + WORD = 2, + DWORD = 4, + QWORD = 8, +} opsize_t; + +typedef enum { + MMIO_READ = 1, + MMIO_WRITE = 2, +} region_attr_t; + +struct io_region { + uint64_t base; + uint64_t len; + region_attr_t attr; + int vcpu; +}; + +typedef int (*vdev_init_t)(void* dev); +typedef int (*vdev_reset_t)(void* dev); +typedef int (*vdev_halt_t)(void* dev); +typedef int (*vdev_memread_t)(void* dev, uint64_t gpa, opsize_t size, uint64_t *data); +typedef int (*vdev_memwrite_t)(void* dev, uint64_t gpa, opsize_t size, uint64_t data); + + +struct vdev_ops { + const char *name; + vdev_init_t init; + vdev_reset_t reset; + vdev_halt_t halt; + vdev_memread_t memread; + vdev_memwrite_t memwrite; +}; + + +void vdev_vm_init(void); +void vdev_vm_cleanup(void); + +int vdev_register(struct vdev_ops *ops, void *dev); +void vdev_unregister(void *dev); + +int vdev_register_region(struct vdev_ops *ops, void *dev, struct io_region *io); +void vdev_unregister_region(void *dev, struct io_region *io); + +int vdev_init(void); +int vdev_reset(void); +int vdev_halt(void); +int vdev_memread(uint64_t gpa, opsize_t size, uint64_t *data); +int vdev_memwrite(uint64_t gpa, opsize_t size, uint64_t data); + +#endif /* _VDEV_H_ */ + diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c new file mode 100644 index 00000000000..a21addfd5d3 --- /dev/null +++ b/sys/amd64/vmm/io/vlapic.c @@ -0,0 +1,812 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include + +#include "vmm_lapic.h" +#include "vmm_ktr.h" +#include "vdev.h" +#include "vlapic.h" + +#define VLAPIC_CTR0(vlapic, format) \ + VMM_CTR0((vlapic)->vm, (vlapic)->vcpuid, format) + +#define VLAPIC_CTR1(vlapic, format, p1) \ + VMM_CTR1((vlapic)->vm, (vlapic)->vcpuid, format, p1) + +#define VLAPIC_CTR_IRR(vlapic, msg) \ +do { \ + uint32_t *irrptr = &(vlapic)->apic.irr0; \ + irrptr[0] = irrptr[0]; /* silence compiler */ \ + VLAPIC_CTR1((vlapic), msg " irr0 0x%08x", irrptr[0 << 2]); \ + VLAPIC_CTR1((vlapic), msg " irr1 0x%08x", irrptr[1 << 2]); \ + VLAPIC_CTR1((vlapic), msg " irr2 0x%08x", irrptr[2 << 2]); \ + VLAPIC_CTR1((vlapic), msg " irr3 0x%08x", irrptr[3 << 2]); \ + VLAPIC_CTR1((vlapic), msg " irr4 0x%08x", irrptr[4 << 2]); \ + VLAPIC_CTR1((vlapic), msg " irr5 0x%08x", irrptr[5 << 2]); \ + VLAPIC_CTR1((vlapic), msg " irr6 0x%08x", irrptr[6 << 2]); \ + VLAPIC_CTR1((vlapic), msg " irr7 0x%08x", irrptr[7 << 2]); \ +} while (0) + +#define VLAPIC_CTR_ISR(vlapic, msg) \ +do { \ + uint32_t *isrptr = &(vlapic)->apic.isr0; \ + isrptr[0] = isrptr[0]; /* silence compiler */ \ + VLAPIC_CTR1((vlapic), msg " isr0 0x%08x", isrptr[0 << 2]); \ + VLAPIC_CTR1((vlapic), msg " isr1 0x%08x", isrptr[1 << 2]); \ + VLAPIC_CTR1((vlapic), msg " isr2 0x%08x", isrptr[2 << 2]); \ + VLAPIC_CTR1((vlapic), msg " isr3 0x%08x", isrptr[3 << 2]); \ + VLAPIC_CTR1((vlapic), msg " isr4 0x%08x", isrptr[4 << 2]); \ + VLAPIC_CTR1((vlapic), msg " isr5 0x%08x", isrptr[5 << 2]); \ + VLAPIC_CTR1((vlapic), msg " isr6 0x%08x", isrptr[6 << 2]); \ + VLAPIC_CTR1((vlapic), msg " isr7 0x%08x", isrptr[7 << 2]); \ +} while (0) + +static MALLOC_DEFINE(M_VLAPIC, "vlapic", "vlapic"); + +#define PRIO(x) ((x) >> 4) + +#define VLAPIC_VERSION (16) +#define VLAPIC_MAXLVT_ENTRIES (5) + +struct vlapic { + struct vm *vm; + int vcpuid; + + struct io_region *mmio; + struct vdev_ops *ops; + struct LAPIC apic; + + int esr_update; + + int divisor; + int ccr_ticks; + + /* + * The 'isrvec_stk' is a stack of vectors injected by the local apic. + * A vector is popped from the stack when the processor does an EOI. + * The vector on the top of the stack is used to compute the + * Processor Priority in conjunction with the TPR. + */ + uint8_t isrvec_stk[ISRVEC_STK_SIZE]; + int isrvec_stk_top; +}; + +static void +vlapic_mask_lvts(uint32_t *lvts, int num_lvt) +{ + int i; + for (i = 0; i < num_lvt; i++) { + *lvts |= APIC_LVT_M; + lvts += 4; + } +} + +#if 0 +static inline void +vlapic_dump_lvt(uint32_t offset, uint32_t *lvt) +{ + printf("Offset %x: lvt %08x (V:%02x DS:%x M:%x)\n", offset, + *lvt, *lvt & APIC_LVTT_VECTOR, *lvt & APIC_LVTT_DS, + *lvt & APIC_LVTT_M); +} +#endif + +static uint64_t +vlapic_get_ccr(struct vlapic *vlapic) +{ + struct LAPIC *lapic = &vlapic->apic; + return lapic->ccr_timer; +} + +static void +vlapic_update_errors(struct vlapic *vlapic) +{ + struct LAPIC *lapic = &vlapic->apic; + lapic->esr = 0; // XXX +} + +static void +vlapic_init_ipi(struct vlapic *vlapic) +{ + struct LAPIC *lapic = &vlapic->apic; + lapic->version = VLAPIC_VERSION; + lapic->version |= (VLAPIC_MAXLVT_ENTRIES < MAXLVTSHIFT); + lapic->dfr = 0xffffffff; + lapic->svr = APIC_SVR_VECTOR; + vlapic_mask_lvts(&lapic->lvt_timer, VLAPIC_MAXLVT_ENTRIES+1); +} + +static int +vlapic_op_reset(void* dev) +{ + struct vlapic *vlapic = (struct vlapic*)dev; + struct LAPIC *lapic = &vlapic->apic; + + memset(lapic, 0, sizeof(*lapic)); + lapic->id = vlapic->vcpuid << 24; + lapic->apr = vlapic->vcpuid; + vlapic_init_ipi(vlapic); + + return 0; + +} + +static int +vlapic_op_init(void* dev) +{ + struct vlapic *vlapic = (struct vlapic*)dev; + vdev_register_region(vlapic->ops, vlapic, vlapic->mmio); + return vlapic_op_reset(dev); +} + +static int +vlapic_op_halt(void* dev) +{ + struct vlapic *vlapic = (struct vlapic*)dev; + vdev_unregister_region(vlapic, vlapic->mmio); + return 0; + +} + +void +vlapic_set_intr_ready(struct vlapic *vlapic, int vector) +{ + struct LAPIC *lapic = &vlapic->apic; + uint32_t *irrptr; + int idx; + + if (vector < 0 || vector >= 256) + panic("vlapic_set_intr_ready: invalid vector %d\n", vector); + + idx = (vector / 32) * 4; + irrptr = &lapic->irr0; + atomic_set_int(&irrptr[idx], 1 << (vector % 32)); + VLAPIC_CTR_IRR(vlapic, "vlapic_set_intr_ready"); +} + +#define VLAPIC_BUS_FREQ tsc_freq +#define VLAPIC_DCR(x) ((x->dcr_timer & 0x8) >> 1)|(x->dcr_timer & 0x3) + +static int +vlapic_timer_divisor(uint32_t dcr) +{ + switch (dcr & 0xB) { + case APIC_TDCR_2: + return (2); + case APIC_TDCR_4: + return (4); + case APIC_TDCR_8: + return (8); + case APIC_TDCR_16: + return (16); + case APIC_TDCR_32: + return (32); + case APIC_TDCR_64: + return (64); + case APIC_TDCR_128: + return (128); + default: + panic("vlapic_timer_divisor: invalid dcr 0x%08x", dcr); + } +} + +static void +vlapic_start_timer(struct vlapic *vlapic, uint32_t elapsed) +{ + uint32_t icr_timer; + + icr_timer = vlapic->apic.icr_timer; + + vlapic->ccr_ticks = ticks; + if (elapsed < icr_timer) + vlapic->apic.ccr_timer = icr_timer - elapsed; + else { + /* + * This can happen when the guest is trying to run its local + * apic timer higher that the setting of 'hz' in the host. + * + * We deal with this by running the guest local apic timer + * at the rate of the host's 'hz' setting. + */ + vlapic->apic.ccr_timer = 0; + } +} + +static __inline uint32_t * +vlapic_get_lvt(struct vlapic *vlapic, uint32_t offset) +{ + struct LAPIC *lapic = &vlapic->apic; + int i; + + if (offset < APIC_OFFSET_TIMER_LVT || offset > APIC_OFFSET_ERROR_LVT) { + panic("vlapic_get_lvt: invalid LVT\n"); + } + i = (offset - APIC_OFFSET_TIMER_LVT) >> 2; + return ((&lapic->lvt_timer) + i);; +} + +#if 1 +static void +dump_isrvec_stk(struct vlapic *vlapic) +{ + int i; + uint32_t *isrptr; + + isrptr = &vlapic->apic.isr0; + for (i = 0; i < 8; i++) + printf("ISR%d 0x%08x\n", i, isrptr[i * 4]); + + for (i = 0; i <= vlapic->isrvec_stk_top; i++) + printf("isrvec_stk[%d] = %d\n", i, vlapic->isrvec_stk[i]); +} +#endif + +/* + * Algorithm adopted from section "Interrupt, Task and Processor Priority" + * in Intel Architecture Manual Vol 3a. + */ +static void +vlapic_update_ppr(struct vlapic *vlapic) +{ + int isrvec, tpr, ppr; + + /* + * Note that the value on the stack at index 0 is always 0. + * + * This is a placeholder for the value of ISRV when none of the + * bits is set in the ISRx registers. + */ + isrvec = vlapic->isrvec_stk[vlapic->isrvec_stk_top]; + tpr = vlapic->apic.tpr; + +#if 1 + { + int i, lastprio, curprio, vector, idx; + uint32_t *isrptr; + + if (vlapic->isrvec_stk_top == 0 && isrvec != 0) + panic("isrvec_stk is corrupted: %d", isrvec); + + /* + * Make sure that the priority of the nested interrupts is + * always increasing. + */ + lastprio = -1; + for (i = 1; i <= vlapic->isrvec_stk_top; i++) { + curprio = PRIO(vlapic->isrvec_stk[i]); + if (curprio <= lastprio) { + dump_isrvec_stk(vlapic); + panic("isrvec_stk does not satisfy invariant"); + } + lastprio = curprio; + } + + /* + * Make sure that each bit set in the ISRx registers has a + * corresponding entry on the isrvec stack. + */ + i = 1; + isrptr = &vlapic->apic.isr0; + for (vector = 0; vector < 256; vector++) { + idx = (vector / 32) * 4; + if (isrptr[idx] & (1 << (vector % 32))) { + if (i > vlapic->isrvec_stk_top || + vlapic->isrvec_stk[i] != vector) { + dump_isrvec_stk(vlapic); + panic("ISR and isrvec_stk out of sync"); + } + i++; + } + } + } +#endif + + if (PRIO(tpr) >= PRIO(isrvec)) + ppr = tpr; + else + ppr = isrvec & 0xf0; + + vlapic->apic.ppr = ppr; + VLAPIC_CTR1(vlapic, "vlapic_update_ppr 0x%02x", ppr); +} + +static void +vlapic_process_eoi(struct vlapic *vlapic) +{ + struct LAPIC *lapic = &vlapic->apic; + uint32_t *isrptr; + int i, idx, bitpos; + + isrptr = &lapic->isr0; + + /* + * The x86 architecture reserves the the first 32 vectors for use + * by the processor. + */ + for (i = 7; i > 0; i--) { + idx = i * 4; + bitpos = fls(isrptr[idx]); + if (bitpos != 0) { + if (vlapic->isrvec_stk_top <= 0) { + panic("invalid vlapic isrvec_stk_top %d", + vlapic->isrvec_stk_top); + } + isrptr[idx] &= ~(1 << (bitpos - 1)); + VLAPIC_CTR_ISR(vlapic, "vlapic_process_eoi"); + vlapic->isrvec_stk_top--; + vlapic_update_ppr(vlapic); + return; + } + } +} + +static __inline int +vlapic_get_lvt_field(uint32_t *lvt, uint32_t mask) +{ + return (*lvt & mask); +} + +static __inline int +vlapic_periodic_timer(struct vlapic *vlapic) +{ + uint32_t *lvt; + + lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_TIMER_LVT); + + return (vlapic_get_lvt_field(lvt, APIC_LVTT_TM_PERIODIC)); +} + +static void +vlapic_fire_timer(struct vlapic *vlapic) +{ + int vector; + uint32_t *lvt; + + lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_TIMER_LVT); + + if (!vlapic_get_lvt_field(lvt, APIC_LVTT_M)) { + vector = vlapic_get_lvt_field(lvt,APIC_LVTT_VECTOR); + vlapic_set_intr_ready(vlapic, vector); + } +} + +static int +lapic_process_icr(struct vlapic *vlapic, uint64_t icrval) +{ + int i; + cpumask_t dmask, thiscpumask; + uint32_t dest, vec, mode; + + thiscpumask = vcpu_mask(vlapic->vcpuid); + + dmask = 0; + dest = icrval >> 32; + vec = icrval & APIC_VECTOR_MASK; + mode = icrval & APIC_DELMODE_MASK; + + if (mode == APIC_DELMODE_FIXED || mode == APIC_DELMODE_NMI) { + switch (icrval & APIC_DEST_MASK) { + case APIC_DEST_DESTFLD: + dmask = vcpu_mask(dest); + break; + case APIC_DEST_SELF: + dmask = thiscpumask; + break; + case APIC_DEST_ALLISELF: + dmask = vm_active_cpus(vlapic->vm); + break; + case APIC_DEST_ALLESELF: + dmask = vm_active_cpus(vlapic->vm) & ~thiscpumask; + break; + } + + for (i = 0; i < VM_MAXCPU; i++) { + if (dmask & vcpu_mask(i)) { + if (mode == APIC_DELMODE_FIXED) + lapic_set_intr(vlapic->vm, i, vec); + else + vm_inject_nmi(vlapic->vm, i); + } + } + + return (0); /* handled completely in the kernel */ + } + + /* + * XXX this assumes that the startup IPI always succeeds + */ + if (mode == APIC_DELMODE_STARTUP) + vm_activate_cpu(vlapic->vm, dest); + + /* + * This will cause a return to userland. + */ + return (1); +} + +int +vlapic_pending_intr(struct vlapic *vlapic) +{ + struct LAPIC *lapic = &vlapic->apic; + int idx, i, bitpos, vector; + uint32_t *irrptr, val; + + irrptr = &lapic->irr0; + + /* + * The x86 architecture reserves the the first 32 vectors for use + * by the processor. + */ + for (i = 7; i > 0; i--) { + idx = i * 4; + val = atomic_load_acq_int(&irrptr[idx]); + bitpos = fls(val); + if (bitpos != 0) { + vector = i * 32 + (bitpos - 1); + if (PRIO(vector) > PRIO(lapic->ppr)) { + VLAPIC_CTR1(vlapic, "pending intr %d", vector); + return (vector); + } else + break; + } + } + VLAPIC_CTR0(vlapic, "no pending intr"); + return (-1); +} + +void +vlapic_intr_accepted(struct vlapic *vlapic, int vector) +{ + struct LAPIC *lapic = &vlapic->apic; + uint32_t *irrptr, *isrptr; + int idx, stk_top; + + /* + * clear the ready bit for vector being accepted in irr + * and set the vector as in service in isr. + */ + idx = (vector / 32) * 4; + + irrptr = &lapic->irr0; + atomic_clear_int(&irrptr[idx], 1 << (vector % 32)); + VLAPIC_CTR_IRR(vlapic, "vlapic_intr_accepted"); + + isrptr = &lapic->isr0; + isrptr[idx] |= 1 << (vector % 32); + VLAPIC_CTR_ISR(vlapic, "vlapic_intr_accepted"); + + /* + * Update the PPR + */ + vlapic->isrvec_stk_top++; + + stk_top = vlapic->isrvec_stk_top; + if (stk_top >= ISRVEC_STK_SIZE) + panic("isrvec_stk_top overflow %d", stk_top); + + vlapic->isrvec_stk[stk_top] = vector; + vlapic_update_ppr(vlapic); +} + +int +vlapic_op_mem_read(void* dev, uint64_t gpa, opsize_t size, uint64_t *data) +{ + struct vlapic *vlapic = (struct vlapic*)dev; + struct LAPIC *lapic = &vlapic->apic; + uint64_t offset = gpa & ~(PAGE_SIZE); + uint32_t *reg; + int i; + + if (offset > sizeof(*lapic)) { + *data = 0; + return 0; + } + + offset &= ~3; + switch(offset) + { + case APIC_OFFSET_ID: + *data = lapic->id; + break; + case APIC_OFFSET_VER: + *data = lapic->version; + break; + case APIC_OFFSET_TPR: + *data = lapic->tpr; + break; + case APIC_OFFSET_APR: + *data = lapic->apr; + break; + case APIC_OFFSET_PPR: + *data = lapic->ppr; + break; + case APIC_OFFSET_EOI: + *data = lapic->eoi; + break; + case APIC_OFFSET_LDR: + *data = lapic->ldr; + break; + case APIC_OFFSET_DFR: + *data = lapic->dfr; + break; + case APIC_OFFSET_SVR: + *data = lapic->svr; + break; + case APIC_OFFSET_ISR0 ... APIC_OFFSET_ISR7: + i = (offset - APIC_OFFSET_ISR0) >> 2; + reg = &lapic->isr0; + *data = *(reg + i); + break; + case APIC_OFFSET_TMR0 ... APIC_OFFSET_TMR7: + i = (offset - APIC_OFFSET_TMR0) >> 2; + reg = &lapic->tmr0; + *data = *(reg + i); + break; + case APIC_OFFSET_IRR0 ... APIC_OFFSET_IRR7: + i = (offset - APIC_OFFSET_IRR0) >> 2; + reg = &lapic->irr0; + *data = atomic_load_acq_int(reg + i); + break; + case APIC_OFFSET_ESR: + *data = lapic->esr; + break; + case APIC_OFFSET_ICR_LOW: + *data = lapic->icr_lo; + break; + case APIC_OFFSET_ICR_HI: + *data = lapic->icr_hi; + break; + case APIC_OFFSET_TIMER_LVT ... APIC_OFFSET_ERROR_LVT: + reg = vlapic_get_lvt(vlapic, offset); + *data = *(reg); + break; + case APIC_OFFSET_ICR: + *data = lapic->icr_timer; + break; + case APIC_OFFSET_CCR: + *data = vlapic_get_ccr(vlapic); + break; + case APIC_OFFSET_DCR: + *data = lapic->dcr_timer; + break; + case APIC_OFFSET_RRR: + default: + *data = 0; + break; + } + return 0; +} + +int +vlapic_op_mem_write(void* dev, uint64_t gpa, opsize_t size, uint64_t data) +{ + struct vlapic *vlapic = (struct vlapic*)dev; + struct LAPIC *lapic = &vlapic->apic; + uint64_t offset = gpa & ~(PAGE_SIZE); + uint32_t *reg; + int retval; + + if (offset > sizeof(*lapic)) { + return 0; + } + + retval = 0; + offset &= ~3; + switch(offset) + { + case APIC_OFFSET_ID: + lapic->id = data; + break; + case APIC_OFFSET_TPR: + lapic->tpr = data & 0xff; + vlapic_update_ppr(vlapic); + break; + case APIC_OFFSET_EOI: + vlapic_process_eoi(vlapic); + break; + case APIC_OFFSET_LDR: + break; + case APIC_OFFSET_DFR: + break; + case APIC_OFFSET_SVR: + lapic->svr = data; + break; + case APIC_OFFSET_ICR_LOW: + retval = lapic_process_icr(vlapic, data); + break; + case APIC_OFFSET_TIMER_LVT ... APIC_OFFSET_ERROR_LVT: + reg = vlapic_get_lvt(vlapic, offset); + if (!(lapic->svr & APIC_SVR_ENABLE)) { + data |= APIC_LVT_M; + } + *reg = data; + // vlapic_dump_lvt(offset, reg); + break; + case APIC_OFFSET_ICR: + lapic->icr_timer = data; + vlapic_start_timer(vlapic, 0); + break; + + case APIC_OFFSET_DCR: + lapic->dcr_timer = data; + vlapic->divisor = vlapic_timer_divisor(data); + break; + + case APIC_OFFSET_ESR: + vlapic_update_errors(vlapic); + break; + case APIC_OFFSET_VER: + case APIC_OFFSET_APR: + case APIC_OFFSET_PPR: + case APIC_OFFSET_RRR: + case APIC_OFFSET_ISR0 ... APIC_OFFSET_ISR7: + case APIC_OFFSET_TMR0 ... APIC_OFFSET_TMR7: + case APIC_OFFSET_IRR0 ... APIC_OFFSET_IRR7: + case APIC_OFFSET_CCR: + default: + // Read only. + break; + } + + return (retval); +} + +void +vlapic_timer_tick(struct vlapic *vlapic) +{ + int curticks, delta, periodic; + uint32_t ccr; + uint32_t decrement, remainder; + + curticks = ticks; + + /* Common case */ + delta = curticks - vlapic->ccr_ticks; + if (delta == 0) + return; + + /* Local APIC timer is disabled */ + if (vlapic->apic.icr_timer == 0) + return; + + /* One-shot mode and timer has already counted down to zero */ + periodic = vlapic_periodic_timer(vlapic); + if (!periodic && vlapic->apic.ccr_timer == 0) + return; + /* + * The 'curticks' and 'ccr_ticks' are out of sync by more than + * 2^31 ticks. We deal with this by restarting the timer. + */ + if (delta < 0) { + vlapic_start_timer(vlapic, 0); + return; + } + + ccr = vlapic->apic.ccr_timer; + decrement = (VLAPIC_BUS_FREQ / vlapic->divisor) / hz; + while (delta-- > 0) { + if (ccr <= decrement) { + remainder = decrement - ccr; + vlapic_fire_timer(vlapic); + if (periodic) { + vlapic_start_timer(vlapic, remainder); + ccr = vlapic->apic.ccr_timer; + } else { + /* + * One-shot timer has counted down to zero. + */ + ccr = 0; + break; + } + } else + ccr -= decrement; + } + + vlapic->ccr_ticks = curticks; + vlapic->apic.ccr_timer = ccr; +} + +struct vdev_ops vlapic_dev_ops = { + .name = "vlapic", + .init = vlapic_op_init, + .reset = vlapic_op_reset, + .halt = vlapic_op_halt, + .memread = vlapic_op_mem_read, + .memwrite = vlapic_op_mem_write, +}; +static struct io_region vlapic_mmio[VM_MAXCPU]; + +struct vlapic * +vlapic_init(struct vm *vm, int vcpuid) +{ + struct vlapic *vlapic; + + vlapic = malloc(sizeof(struct vlapic), M_VLAPIC, M_WAITOK | M_ZERO); + vlapic->vm = vm; + vlapic->vcpuid = vcpuid; + vlapic->ops = &vlapic_dev_ops; + + vlapic->mmio = vlapic_mmio + vcpuid; + vlapic->mmio->base = DEFAULT_APIC_BASE; + vlapic->mmio->len = PAGE_SIZE; + vlapic->mmio->attr = MMIO_READ|MMIO_WRITE; + vlapic->mmio->vcpu = vcpuid; + + vdev_register(&vlapic_dev_ops, vlapic); + + vlapic_op_init(vlapic); + + return (vlapic); +} + +void +vlapic_cleanup(struct vlapic *vlapic) +{ + vdev_unregister(vlapic); + free(vlapic, M_VLAPIC); +} diff --git a/sys/amd64/vmm/io/vlapic.h b/sys/amd64/vmm/io/vlapic.h new file mode 100644 index 00000000000..861ea8c9c38 --- /dev/null +++ b/sys/amd64/vmm/io/vlapic.h @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VLAPIC_H_ +#define _VLAPIC_H_ + +#include "vdev.h" + +struct vm; + +/* + * Map of APIC Registers: Offset Description Access + */ +#define APIC_OFFSET_ID 0x20 // Local APIC ID R/W +#define APIC_OFFSET_VER 0x30 // Local APIC Version R +#define APIC_OFFSET_TPR 0x80 // Task Priority Register R/W +#define APIC_OFFSET_APR 0x90 // Arbitration Priority Register R +#define APIC_OFFSET_PPR 0xA0 // Processor Priority Register R +#define APIC_OFFSET_EOI 0xB0 // EOI Register W +#define APIC_OFFSET_RRR 0xC0 // Remote read R +#define APIC_OFFSET_LDR 0xD0 // Logical Destination R/W +#define APIC_OFFSET_DFR 0xE0 // Destination Format Register 0..27 R; 28..31 R/W +#define APIC_OFFSET_SVR 0xF0 // Spurious Interrupt Vector Reg. 0..3 R; 4..9 R/W +#define APIC_OFFSET_ISR0 0x100 // ISR 000-031 R +#define APIC_OFFSET_ISR1 0x110 // ISR 032-063 R +#define APIC_OFFSET_ISR2 0x120 // ISR 064-095 R +#define APIC_OFFSET_ISR3 0x130 // ISR 095-128 R +#define APIC_OFFSET_ISR4 0x140 // ISR 128-159 R +#define APIC_OFFSET_ISR5 0x150 // ISR 160-191 R +#define APIC_OFFSET_ISR6 0x160 // ISR 192-223 R +#define APIC_OFFSET_ISR7 0x170 // ISR 224-255 R +#define APIC_OFFSET_TMR0 0x180 // TMR 000-031 R +#define APIC_OFFSET_TMR1 0x190 // TMR 032-063 R +#define APIC_OFFSET_TMR2 0x1A0 // TMR 064-095 R +#define APIC_OFFSET_TMR3 0x1B0 // TMR 095-128 R +#define APIC_OFFSET_TMR4 0x1C0 // TMR 128-159 R +#define APIC_OFFSET_TMR5 0x1D0 // TMR 160-191 R +#define APIC_OFFSET_TMR6 0x1E0 // TMR 192-223 R +#define APIC_OFFSET_TMR7 0x1F0 // TMR 224-255 R +#define APIC_OFFSET_IRR0 0x200 // IRR 000-031 R +#define APIC_OFFSET_IRR1 0x210 // IRR 032-063 R +#define APIC_OFFSET_IRR2 0x220 // IRR 064-095 R +#define APIC_OFFSET_IRR3 0x230 // IRR 095-128 R +#define APIC_OFFSET_IRR4 0x240 // IRR 128-159 R +#define APIC_OFFSET_IRR5 0x250 // IRR 160-191 R +#define APIC_OFFSET_IRR6 0x260 // IRR 192-223 R +#define APIC_OFFSET_IRR7 0x270 // IRR 224-255 R +#define APIC_OFFSET_ESR 0x280 // Error Status Register R +#define APIC_OFFSET_ICR_LOW 0x300 // Interrupt Command Reg. (0-31) R/W +#define APIC_OFFSET_ICR_HI 0x310 // Interrupt Command Reg. (32-63) R/W +#define APIC_OFFSET_TIMER_LVT 0x320 // Local Vector Table (Timer) R/W +#define APIC_OFFSET_THERM_LVT 0x330 // Local Vector Table (Thermal) R/W (PIV+) +#define APIC_OFFSET_PERF_LVT 0x340 // Local Vector Table (Performance) R/W (P6+) +#define APIC_OFFSET_LINT0_LVT 0x350 // Local Vector Table (LINT0) R/W +#define APIC_OFFSET_LINT1_LVT 0x360 // Local Vector Table (LINT1) R/W +#define APIC_OFFSET_ERROR_LVT 0x370 // Local Vector Table (ERROR) R/W +#define APIC_OFFSET_ICR 0x380 // Initial Count Reg. for Timer R/W +#define APIC_OFFSET_CCR 0x390 // Current Count of Timer R +#define APIC_OFFSET_DCR 0x3E0 // Timer Divide Configuration Reg. R/W + +/* + * 16 priority levels with at most one vector injected per level. + */ +#define ISRVEC_STK_SIZE (16 + 1) + +struct vlapic *vlapic_init(struct vm *vm, int vcpuid); +void vlapic_cleanup(struct vlapic *vlapic); + +int vlapic_op_mem_write(void* dev, uint64_t gpa, + opsize_t size, uint64_t data); + +int vlapic_op_mem_read(void* dev, uint64_t gpa, + opsize_t size, uint64_t *data); + +int vlapic_pending_intr(struct vlapic *vlapic); +void vlapic_intr_accepted(struct vlapic *vlapic, int vector); +void vlapic_set_intr_ready(struct vlapic *vlapic, int vector); +void vlapic_timer_tick(struct vlapic *vlapic); + +#endif /* _VLAPIC_H_ */ diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c new file mode 100644 index 00000000000..c93c31e772e --- /dev/null +++ b/sys/amd64/vmm/vmm.c @@ -0,0 +1,737 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include "vmm_mem.h" +#include "vmm_util.h" +#include +#include "vlapic.h" +#include "vmm_msr.h" +#include "vmm_ipi.h" +#include "vmm_stat.h" + +#include "io/ppt.h" +#include "io/iommu.h" + +struct vlapic; + +struct vcpu { + int flags; + int pincpu; /* host cpuid this vcpu is bound to */ + int hostcpu; /* host cpuid this vcpu last ran on */ + uint64_t guest_msrs[VMM_MSR_NUM]; + struct vlapic *vlapic; + int vcpuid; + struct savefpu savefpu; /* guest fpu state */ + void *stats; +}; +#define VCPU_F_PINNED 0x0001 +#define VCPU_F_RUNNING 0x0002 + +#define VCPU_PINCPU(vm, vcpuid) \ + ((vm->vcpu[vcpuid].flags & VCPU_F_PINNED) ? vm->vcpu[vcpuid].pincpu : -1) + +#define VCPU_UNPIN(vm, vcpuid) (vm->vcpu[vcpuid].flags &= ~VCPU_F_PINNED) + +#define VCPU_PIN(vm, vcpuid, host_cpuid) \ +do { \ + vm->vcpu[vcpuid].flags |= VCPU_F_PINNED; \ + vm->vcpu[vcpuid].pincpu = host_cpuid; \ +} while(0) + +#define VM_MAX_MEMORY_SEGMENTS 2 + +struct vm { + void *cookie; /* processor-specific data */ + void *iommu; /* iommu-specific data */ + struct vcpu vcpu[VM_MAXCPU]; + int num_mem_segs; + struct vm_memory_segment mem_segs[VM_MAX_MEMORY_SEGMENTS]; + char name[VM_MAX_NAMELEN]; + + /* + * Mask of active vcpus. + * An active vcpu is one that has been started implicitly (BSP) or + * explicitly (AP) by sending it a startup ipi. + */ + cpumask_t active_cpus; +}; + +static struct vmm_ops *ops; +#define VMM_INIT() (ops != NULL ? (*ops->init)() : 0) +#define VMM_CLEANUP() (ops != NULL ? (*ops->cleanup)() : 0) + +#define VMINIT(vm) (ops != NULL ? (*ops->vminit)(vm): NULL) +#define VMRUN(vmi, vcpu, rip, vmexit) \ + (ops != NULL ? (*ops->vmrun)(vmi, vcpu, rip, vmexit) : ENXIO) +#define VMCLEANUP(vmi) (ops != NULL ? (*ops->vmcleanup)(vmi) : NULL) +#define VMMMAP(vmi, gpa, hpa, len, attr, prot, spm) \ + (ops != NULL ? (*ops->vmmmap)(vmi, gpa, hpa, len, attr, prot, spm) : ENXIO) +#define VMGETREG(vmi, vcpu, num, retval) \ + (ops != NULL ? (*ops->vmgetreg)(vmi, vcpu, num, retval) : ENXIO) +#define VMSETREG(vmi, vcpu, num, val) \ + (ops != NULL ? (*ops->vmsetreg)(vmi, vcpu, num, val) : ENXIO) +#define VMGETDESC(vmi, vcpu, num, desc) \ + (ops != NULL ? (*ops->vmgetdesc)(vmi, vcpu, num, desc) : ENXIO) +#define VMSETDESC(vmi, vcpu, num, desc) \ + (ops != NULL ? (*ops->vmsetdesc)(vmi, vcpu, num, desc) : ENXIO) +#define VMINJECT(vmi, vcpu, type, vec, ec, ecv) \ + (ops != NULL ? (*ops->vminject)(vmi, vcpu, type, vec, ec, ecv) : ENXIO) +#define VMNMI(vmi, vcpu) \ + (ops != NULL ? (*ops->vmnmi)(vmi, vcpu) : ENXIO) +#define VMGETCAP(vmi, vcpu, num, retval) \ + (ops != NULL ? (*ops->vmgetcap)(vmi, vcpu, num, retval) : ENXIO) +#define VMSETCAP(vmi, vcpu, num, val) \ + (ops != NULL ? (*ops->vmsetcap)(vmi, vcpu, num, val) : ENXIO) + +#define fxrstor(addr) __asm("fxrstor %0" : : "m" (*(addr))) +#define fxsave(addr) __asm __volatile("fxsave %0" : "=m" (*(addr))) +#define fpu_start_emulating() __asm("smsw %%ax; orb %0,%%al; lmsw %%ax" \ + : : "n" (CR0_TS) : "ax") +#define fpu_stop_emulating() __asm("clts") + +static MALLOC_DEFINE(M_VM, "vm", "vm"); +CTASSERT(VMM_MSR_NUM <= 64); /* msr_mask can keep track of up to 64 msrs */ + +/* statistics */ +static VMM_STAT_DEFINE(VCPU_TOTAL_RUNTIME, "vcpu total runtime"); + +static void +vcpu_cleanup(struct vcpu *vcpu) +{ + vlapic_cleanup(vcpu->vlapic); + vmm_stat_free(vcpu->stats); +} + +static void +vcpu_init(struct vm *vm, uint32_t vcpu_id) +{ + struct vcpu *vcpu; + + vcpu = &vm->vcpu[vcpu_id]; + + vcpu->hostcpu = -1; + vcpu->vcpuid = vcpu_id; + vcpu->vlapic = vlapic_init(vm, vcpu_id); + fpugetregs(curthread, &vcpu->savefpu); + vcpu->stats = vmm_stat_alloc(); +} + +static int +vmm_init(void) +{ + int error; + + vmm_ipi_init(); + + error = vmm_mem_init(); + if (error) + return (error); + + if (vmm_is_intel()) + ops = &vmm_ops_intel; + else if (vmm_is_amd()) + ops = &vmm_ops_amd; + else + return (ENXIO); + + vmm_msr_init(); + + return (VMM_INIT()); +} + +static int +vmm_handler(module_t mod, int what, void *arg) +{ + int error; + + switch (what) { + case MOD_LOAD: + vmmdev_init(); + iommu_init(); + error = vmm_init(); + break; + case MOD_UNLOAD: + vmmdev_cleanup(); + iommu_cleanup(); + vmm_ipi_cleanup(); + error = VMM_CLEANUP(); + break; + default: + error = 0; + break; + } + return (error); +} + +static moduledata_t vmm_kmod = { + "vmm", + vmm_handler, + NULL +}; + +/* + * Execute the module load handler after the pci passthru driver has had + * a chance to claim devices. We need this information at the time we do + * iommu initialization. + */ +DECLARE_MODULE(vmm, vmm_kmod, SI_SUB_CONFIGURE + 1, SI_ORDER_ANY); +MODULE_VERSION(vmm, 1); + +SYSCTL_NODE(_hw, OID_AUTO, vmm, CTLFLAG_RW, NULL, NULL); + +struct vm * +vm_create(const char *name) +{ + int i; + struct vm *vm; + vm_paddr_t maxaddr; + + const int BSP = 0; + + if (name == NULL || strlen(name) >= VM_MAX_NAMELEN) + return (NULL); + + vm = malloc(sizeof(struct vm), M_VM, M_WAITOK | M_ZERO); + strcpy(vm->name, name); + vm->cookie = VMINIT(vm); + + for (i = 0; i < VM_MAXCPU; i++) { + vcpu_init(vm, i); + guest_msrs_init(vm, i); + } + + maxaddr = vmm_mem_maxaddr(); + vm->iommu = iommu_create_domain(maxaddr); + vm_activate_cpu(vm, BSP); + + return (vm); +} + +void +vm_destroy(struct vm *vm) +{ + int i; + + ppt_unassign_all(vm); + + for (i = 0; i < vm->num_mem_segs; i++) + vmm_mem_free(vm->mem_segs[i].hpa, vm->mem_segs[i].len); + + for (i = 0; i < VM_MAXCPU; i++) + vcpu_cleanup(&vm->vcpu[i]); + + iommu_destroy_domain(vm->iommu); + + VMCLEANUP(vm->cookie); + + free(vm, M_VM); +} + +const char * +vm_name(struct vm *vm) +{ + return (vm->name); +} + +int +vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa) +{ + const boolean_t spok = TRUE; /* superpage mappings are ok */ + + return (VMMMAP(vm->cookie, gpa, hpa, len, VM_MEMATTR_UNCACHEABLE, + VM_PROT_RW, spok)); +} + +int +vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len) +{ + const boolean_t spok = TRUE; /* superpage mappings are ok */ + + return (VMMMAP(vm->cookie, gpa, 0, len, VM_MEMATTR_UNCACHEABLE, + VM_PROT_NONE, spok)); +} + +int +vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t *ret_hpa) +{ + int error; + vm_paddr_t hpa; + + const boolean_t spok = TRUE; /* superpage mappings are ok */ + + /* + * find the hpa if already it was already vm_malloc'd. + */ + hpa = vm_gpa2hpa(vm, gpa, len); + if (hpa != ((vm_paddr_t)-1)) + goto out; + + if (vm->num_mem_segs >= VM_MAX_MEMORY_SEGMENTS) + return (E2BIG); + + hpa = vmm_mem_alloc(len); + if (hpa == 0) + return (ENOMEM); + + error = VMMMAP(vm->cookie, gpa, hpa, len, VM_MEMATTR_WRITE_BACK, + VM_PROT_ALL, spok); + if (error) { + vmm_mem_free(hpa, len); + return (error); + } + + iommu_create_mapping(vm->iommu, gpa, hpa, len); + + vm->mem_segs[vm->num_mem_segs].gpa = gpa; + vm->mem_segs[vm->num_mem_segs].hpa = hpa; + vm->mem_segs[vm->num_mem_segs].len = len; + vm->num_mem_segs++; +out: + *ret_hpa = hpa; + return (0); +} + +vm_paddr_t +vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t len) +{ + int i; + vm_paddr_t gpabase, gpalimit, hpabase; + + for (i = 0; i < vm->num_mem_segs; i++) { + hpabase = vm->mem_segs[i].hpa; + gpabase = vm->mem_segs[i].gpa; + gpalimit = gpabase + vm->mem_segs[i].len; + if (gpa >= gpabase && gpa + len <= gpalimit) + return ((gpa - gpabase) + hpabase); + } + return ((vm_paddr_t)-1); +} + +int +vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, + struct vm_memory_segment *seg) +{ + int i; + + for (i = 0; i < vm->num_mem_segs; i++) { + if (gpabase == vm->mem_segs[i].gpa) { + *seg = vm->mem_segs[i]; + return (0); + } + } + return (-1); +} + +int +vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval) +{ + + if (vcpu < 0 || vcpu >= VM_MAXCPU) + return (EINVAL); + + if (reg >= VM_REG_LAST) + return (EINVAL); + + return (VMGETREG(vm->cookie, vcpu, reg, retval)); +} + +int +vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val) +{ + + if (vcpu < 0 || vcpu >= VM_MAXCPU) + return (EINVAL); + + if (reg >= VM_REG_LAST) + return (EINVAL); + + return (VMSETREG(vm->cookie, vcpu, reg, val)); +} + +static boolean_t +is_descriptor_table(int reg) +{ + + switch (reg) { + case VM_REG_GUEST_IDTR: + case VM_REG_GUEST_GDTR: + return (TRUE); + default: + return (FALSE); + } +} + +static boolean_t +is_segment_register(int reg) +{ + + switch (reg) { + case VM_REG_GUEST_ES: + case VM_REG_GUEST_CS: + case VM_REG_GUEST_SS: + case VM_REG_GUEST_DS: + case VM_REG_GUEST_FS: + case VM_REG_GUEST_GS: + case VM_REG_GUEST_TR: + case VM_REG_GUEST_LDTR: + return (TRUE); + default: + return (FALSE); + } +} + +int +vm_get_seg_desc(struct vm *vm, int vcpu, int reg, + struct seg_desc *desc) +{ + + if (vcpu < 0 || vcpu >= VM_MAXCPU) + return (EINVAL); + + if (!is_segment_register(reg) && !is_descriptor_table(reg)) + return (EINVAL); + + return (VMGETDESC(vm->cookie, vcpu, reg, desc)); +} + +int +vm_set_seg_desc(struct vm *vm, int vcpu, int reg, + struct seg_desc *desc) +{ + if (vcpu < 0 || vcpu >= VM_MAXCPU) + return (EINVAL); + + if (!is_segment_register(reg) && !is_descriptor_table(reg)) + return (EINVAL); + + return (VMSETDESC(vm->cookie, vcpu, reg, desc)); +} + +int +vm_get_pinning(struct vm *vm, int vcpuid, int *cpuid) +{ + + if (vcpuid < 0 || vcpuid >= VM_MAXCPU) + return (EINVAL); + + *cpuid = VCPU_PINCPU(vm, vcpuid); + + return (0); +} + +int +vm_set_pinning(struct vm *vm, int vcpuid, int host_cpuid) +{ + struct thread *td; + + if (vcpuid < 0 || vcpuid >= VM_MAXCPU) + return (EINVAL); + + td = curthread; /* XXXSMP only safe when muxing vcpus */ + + /* unpin */ + if (host_cpuid < 0) { + VCPU_UNPIN(vm, vcpuid); + thread_lock(td); + sched_unbind(td); + thread_unlock(td); + return (0); + } + + if (CPU_ABSENT(host_cpuid)) + return (EINVAL); + + /* + * XXX we should check that 'host_cpuid' has not already been pinned + * by another vm. + */ + thread_lock(td); + sched_bind(td, host_cpuid); + thread_unlock(td); + VCPU_PIN(vm, vcpuid, host_cpuid); + + return (0); +} + +static void +restore_guest_fpustate(struct vcpu *vcpu) +{ + register_t s; + + s = intr_disable(); + fpu_stop_emulating(); + fxrstor(&vcpu->savefpu); + fpu_start_emulating(); + intr_restore(s); +} + +static void +save_guest_fpustate(struct vcpu *vcpu) +{ + register_t s; + + s = intr_disable(); + fpu_stop_emulating(); + fxsave(&vcpu->savefpu); + fpu_start_emulating(); + intr_restore(s); +} + +int +vm_run(struct vm *vm, struct vm_run *vmrun) +{ + int error, vcpuid; + struct vcpu *vcpu; + struct pcb *pcb; + uint64_t tscval; + + vcpuid = vmrun->cpuid; + + if (vcpuid < 0 || vcpuid >= VM_MAXCPU) + return (EINVAL); + + vcpu = &vm->vcpu[vcpuid]; + + critical_enter(); + + tscval = rdtsc(); + + pcb = PCPU_GET(curpcb); + pcb->pcb_full_iret = 1; + + vcpu->hostcpu = curcpu; + + fpuexit(curthread); + restore_guest_msrs(vm, vcpuid); + restore_guest_fpustate(vcpu); + error = VMRUN(vm->cookie, vcpuid, vmrun->rip, &vmrun->vm_exit); + save_guest_fpustate(vcpu); + restore_host_msrs(vm, vcpuid); + + vmm_stat_incr(vm, vcpuid, VCPU_TOTAL_RUNTIME, rdtsc() - tscval); + + critical_exit(); + + return (error); +} + +int +vm_inject_event(struct vm *vm, int vcpuid, int type, + int vector, uint32_t code, int code_valid) +{ + if (vcpuid < 0 || vcpuid >= VM_MAXCPU) + return (EINVAL); + + if ((type > VM_EVENT_NONE && type < VM_EVENT_MAX) == 0) + return (EINVAL); + + if (vector < 0 || vector > 255) + return (EINVAL); + + return (VMINJECT(vm->cookie, vcpuid, type, vector, code, code_valid)); +} + +int +vm_inject_nmi(struct vm *vm, int vcpu) +{ + int error; + + if (vcpu < 0 || vcpu >= VM_MAXCPU) + return (EINVAL); + + error = VMNMI(vm->cookie, vcpu); + vm_interrupt_hostcpu(vm, vcpu); + return (error); +} + +int +vm_get_capability(struct vm *vm, int vcpu, int type, int *retval) +{ + if (vcpu < 0 || vcpu >= VM_MAXCPU) + return (EINVAL); + + if (type < 0 || type >= VM_CAP_MAX) + return (EINVAL); + + return (VMGETCAP(vm->cookie, vcpu, type, retval)); +} + +int +vm_set_capability(struct vm *vm, int vcpu, int type, int val) +{ + if (vcpu < 0 || vcpu >= VM_MAXCPU) + return (EINVAL); + + if (type < 0 || type >= VM_CAP_MAX) + return (EINVAL); + + return (VMSETCAP(vm->cookie, vcpu, type, val)); +} + +uint64_t * +vm_guest_msrs(struct vm *vm, int cpu) +{ + return (vm->vcpu[cpu].guest_msrs); +} + +struct vlapic * +vm_lapic(struct vm *vm, int cpu) +{ + return (vm->vcpu[cpu].vlapic); +} + +boolean_t +vmm_is_pptdev(int bus, int slot, int func) +{ + int found, b, s, f, n; + char *val, *cp, *cp2; + + /* + * setenv pptdevs "1/2/3 4/5/6 7/8/9 10/11/12" + */ + found = 0; + cp = val = getenv("pptdevs"); + while (cp != NULL && *cp != '\0') { + if ((cp2 = strchr(cp, ' ')) != NULL) + *cp2 = '\0'; + + n = sscanf(cp, "%d/%d/%d", &b, &s, &f); + if (n == 3 && bus == b && slot == s && func == f) { + found = 1; + break; + } + + if (cp2 != NULL) + *cp2++ = ' '; + + cp = cp2; + } + freeenv(val); + return (found); +} + +void * +vm_iommu_domain(struct vm *vm) +{ + + return (vm->iommu); +} + +void +vm_set_run_state(struct vm *vm, int vcpuid, int state) +{ + struct vcpu *vcpu; + + if (vcpuid < 0 || vcpuid >= VM_MAXCPU) + panic("vm_set_run_state: invalid vcpuid %d", vcpuid); + + vcpu = &vm->vcpu[vcpuid]; + + if (state == VCPU_RUNNING) { + if (vcpu->flags & VCPU_F_RUNNING) { + panic("vm_set_run_state: %s[%d] is already running", + vm_name(vm), vcpuid); + } + vcpu->flags |= VCPU_F_RUNNING; + } else { + if ((vcpu->flags & VCPU_F_RUNNING) == 0) { + panic("vm_set_run_state: %s[%d] is already stopped", + vm_name(vm), vcpuid); + } + vcpu->flags &= ~VCPU_F_RUNNING; + } +} + +int +vm_get_run_state(struct vm *vm, int vcpuid, int *cpuptr) +{ + int retval, hostcpu; + struct vcpu *vcpu; + + if (vcpuid < 0 || vcpuid >= VM_MAXCPU) + panic("vm_get_run_state: invalid vcpuid %d", vcpuid); + + vcpu = &vm->vcpu[vcpuid]; + if (vcpu->flags & VCPU_F_RUNNING) { + retval = VCPU_RUNNING; + hostcpu = vcpu->hostcpu; + } else { + retval = VCPU_STOPPED; + hostcpu = -1; + } + + if (cpuptr) + *cpuptr = hostcpu; + + return (retval); +} + +void +vm_activate_cpu(struct vm *vm, int vcpuid) +{ + + if (vcpuid >= 0 && vcpuid < VM_MAXCPU) + vm->active_cpus |= vcpu_mask(vcpuid); +} + +cpumask_t +vm_active_cpus(struct vm *vm) +{ + + return (vm->active_cpus); +} + +void * +vcpu_stats(struct vm *vm, int vcpuid) +{ + + return (vm->vcpu[vcpuid].stats); +} diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c new file mode 100644 index 00000000000..cf443fc1235 --- /dev/null +++ b/sys/amd64/vmm/vmm_dev.c @@ -0,0 +1,468 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include "vmm_lapic.h" +#include "vmm_stat.h" +#include "io/ppt.h" +#include + +struct vmmdev_softc { + struct vm *vm; /* vm instance cookie */ + struct cdev *cdev; + SLIST_ENTRY(vmmdev_softc) link; +}; +static SLIST_HEAD(, vmmdev_softc) head; + +static struct mtx vmmdev_mtx; + +static MALLOC_DEFINE(M_VMMDEV, "vmmdev", "vmmdev"); + +SYSCTL_DECL(_hw_vmm); + +static struct vmmdev_softc * +vmmdev_lookup(const char *name) +{ + struct vmmdev_softc *sc; + +#ifdef notyet /* XXX kernel is not compiled with invariants */ + mtx_assert(&vmmdev_mtx, MA_OWNED); +#endif + + SLIST_FOREACH(sc, &head, link) { + if (strcmp(name, vm_name(sc->vm)) == 0) + break; + } + + return (sc); +} + +static struct vmmdev_softc * +vmmdev_lookup2(struct cdev *cdev) +{ + struct vmmdev_softc *sc; + +#ifdef notyet /* XXX kernel is not compiled with invariants */ + mtx_assert(&vmmdev_mtx, MA_OWNED); +#endif + + SLIST_FOREACH(sc, &head, link) { + if (sc->cdev == cdev) + break; + } + + return (sc); +} + +static int +vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags) +{ + int error, off, c; + vm_paddr_t hpa, gpa; + struct vmmdev_softc *sc; + + static char zerobuf[PAGE_SIZE]; + + error = 0; + mtx_lock(&vmmdev_mtx); + sc = vmmdev_lookup2(cdev); + + while (uio->uio_resid > 0 && error == 0) { + gpa = uio->uio_offset; + off = gpa & PAGE_MASK; + c = min(uio->uio_resid, PAGE_SIZE - off); + + /* + * The VM has a hole in its physical memory map. If we want to + * use 'dd' to inspect memory beyond the hole we need to + * provide bogus data for memory that lies in the hole. + * + * Since this device does not support lseek(2), dd(1) will + * read(2) blocks of data to simulate the lseek(2). + */ + hpa = vm_gpa2hpa(sc->vm, gpa, c); + if (hpa == (vm_paddr_t)-1) { + if (uio->uio_rw == UIO_READ) + error = uiomove(zerobuf, c, uio); + else + error = EFAULT; + } else + error = uiomove((void *)PHYS_TO_DMAP(hpa), c, uio); + } + + mtx_unlock(&vmmdev_mtx); + return (error); +} + +static int +vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, + struct thread *td) +{ + int error, vcpu; + struct vmmdev_softc *sc; + struct vm_memory_segment *seg; + struct vm_register *vmreg; + struct vm_seg_desc* vmsegdesc; + struct vm_pin *vmpin; + struct vm_run *vmrun; + struct vm_event *vmevent; + struct vm_lapic_irq *vmirq; + struct vm_capability *vmcap; + struct vm_pptdev *pptdev; + struct vm_pptdev_mmio *pptmmio; + struct vm_pptdev_msi *pptmsi; + struct vm_nmi *vmnmi; + struct vm_stats *vmstats; + struct vm_stat_desc *statdesc; + + mtx_lock(&vmmdev_mtx); + sc = vmmdev_lookup2(cdev); + if (sc == NULL) { + mtx_unlock(&vmmdev_mtx); + return (ENXIO); + } + + /* + * Some VMM ioctls can operate only on vcpus that are not running. + */ + switch (cmd) { + case VM_RUN: + case VM_SET_PINNING: + case VM_GET_REGISTER: + case VM_SET_REGISTER: + case VM_GET_SEGMENT_DESCRIPTOR: + case VM_SET_SEGMENT_DESCRIPTOR: + case VM_INJECT_EVENT: + case VM_GET_CAPABILITY: + case VM_SET_CAPABILITY: + case VM_PPTDEV_MSI: + /* + * XXX fragile, handle with care + * Assumes that the first field of the ioctl data is the vcpu. + */ + vcpu = *(int *)data; + if (vcpu < 0 || vcpu >= VM_MAXCPU) { + error = EINVAL; + goto done; + } + + if (vcpu_is_running(sc->vm, vcpu, NULL)) { + error = EBUSY; + goto done; + } + break; + default: + break; + } + + switch(cmd) { + case VM_RUN: + vmrun = (struct vm_run *)data; + + vm_set_run_state(sc->vm, vmrun->cpuid, VCPU_RUNNING); + mtx_unlock(&vmmdev_mtx); + + error = vm_run(sc->vm, vmrun); + + mtx_lock(&vmmdev_mtx); + vm_set_run_state(sc->vm, vmrun->cpuid, VCPU_STOPPED); + break; + case VM_STAT_DESC: { + const char *desc; + statdesc = (struct vm_stat_desc *)data; + desc = vmm_stat_desc(statdesc->index); + if (desc != NULL) { + error = 0; + strlcpy(statdesc->desc, desc, sizeof(statdesc->desc)); + } else + error = EINVAL; + break; + } + case VM_STATS: { + CTASSERT(MAX_VM_STATS >= MAX_VMM_STAT_TYPES); + vmstats = (struct vm_stats *)data; + getmicrotime(&vmstats->tv); + error = vmm_stat_copy(sc->vm, vmstats->cpuid, + &vmstats->num_entries, vmstats->statbuf); + break; + } + case VM_PPTDEV_MSI: + pptmsi = (struct vm_pptdev_msi *)data; + error = ppt_setup_msi(sc->vm, pptmsi->vcpu, + pptmsi->bus, pptmsi->slot, pptmsi->func, + pptmsi->destcpu, pptmsi->vector, + pptmsi->numvec); + break; + case VM_MAP_PPTDEV_MMIO: + pptmmio = (struct vm_pptdev_mmio *)data; + error = ppt_map_mmio(sc->vm, pptmmio->bus, pptmmio->slot, + pptmmio->func, pptmmio->gpa, pptmmio->len, + pptmmio->hpa); + break; + case VM_BIND_PPTDEV: + pptdev = (struct vm_pptdev *)data; + error = ppt_assign_device(sc->vm, pptdev->bus, pptdev->slot, + pptdev->func); + break; + case VM_UNBIND_PPTDEV: + pptdev = (struct vm_pptdev *)data; + error = ppt_unassign_device(sc->vm, pptdev->bus, pptdev->slot, + pptdev->func); + break; + case VM_INJECT_EVENT: + vmevent = (struct vm_event *)data; + error = vm_inject_event(sc->vm, vmevent->cpuid, vmevent->type, + vmevent->vector, + vmevent->error_code, + vmevent->error_code_valid); + break; + case VM_INJECT_NMI: + vmnmi = (struct vm_nmi *)data; + error = vm_inject_nmi(sc->vm, vmnmi->cpuid); + break; + case VM_LAPIC_IRQ: + vmirq = (struct vm_lapic_irq *)data; + error = lapic_set_intr(sc->vm, vmirq->cpuid, vmirq->vector); + break; + case VM_SET_PINNING: + vmpin = (struct vm_pin *)data; + error = vm_set_pinning(sc->vm, vmpin->vm_cpuid, + vmpin->host_cpuid); + break; + case VM_GET_PINNING: + vmpin = (struct vm_pin *)data; + error = vm_get_pinning(sc->vm, vmpin->vm_cpuid, + &vmpin->host_cpuid); + break; + case VM_MAP_MEMORY: + seg = (struct vm_memory_segment *)data; + error = vm_malloc(sc->vm, seg->gpa, seg->len, &seg->hpa); + break; + case VM_GET_MEMORY_SEG: + seg = (struct vm_memory_segment *)data; + seg->hpa = seg->len = 0; + (void)vm_gpabase2memseg(sc->vm, seg->gpa, seg); + error = 0; + break; + case VM_GET_REGISTER: + vmreg = (struct vm_register *)data; + error = vm_get_register(sc->vm, vmreg->cpuid, vmreg->regnum, + &vmreg->regval); + break; + case VM_SET_REGISTER: + vmreg = (struct vm_register *)data; + error = vm_set_register(sc->vm, vmreg->cpuid, vmreg->regnum, + vmreg->regval); + break; + case VM_SET_SEGMENT_DESCRIPTOR: + vmsegdesc = (struct vm_seg_desc *)data; + error = vm_set_seg_desc(sc->vm, vmsegdesc->cpuid, + vmsegdesc->regnum, + &vmsegdesc->desc); + break; + case VM_GET_SEGMENT_DESCRIPTOR: + vmsegdesc = (struct vm_seg_desc *)data; + error = vm_get_seg_desc(sc->vm, vmsegdesc->cpuid, + vmsegdesc->regnum, + &vmsegdesc->desc); + break; + case VM_GET_CAPABILITY: + vmcap = (struct vm_capability *)data; + error = vm_get_capability(sc->vm, vmcap->cpuid, + vmcap->captype, + &vmcap->capval); + break; + case VM_SET_CAPABILITY: + vmcap = (struct vm_capability *)data; + error = vm_set_capability(sc->vm, vmcap->cpuid, + vmcap->captype, + vmcap->capval); + break; + default: + error = ENOTTY; + break; + } +done: + mtx_unlock(&vmmdev_mtx); + + return (error); +} + +static int +vmmdev_mmap(struct cdev *cdev, vm_offset_t offset, vm_paddr_t *paddr, int nprot) +{ + int error; + struct vmmdev_softc *sc; + + error = -1; + mtx_lock(&vmmdev_mtx); + + sc = vmmdev_lookup2(cdev); + if (sc != NULL && (nprot & PROT_EXEC) == 0) { + *paddr = vm_gpa2hpa(sc->vm, (vm_paddr_t)offset, PAGE_SIZE); + if (*paddr != (vm_paddr_t)-1) + error = 0; + } + + mtx_unlock(&vmmdev_mtx); + + return (error); +} + +static void +vmmdev_destroy(struct vmmdev_softc *sc) +{ + +#ifdef notyet /* XXX kernel is not compiled with invariants */ + mtx_assert(&vmmdev_mtx, MA_OWNED); +#endif + + /* + * XXX must stop virtual machine instances that may be still + * running and cleanup their state. + */ + SLIST_REMOVE(&head, sc, vmmdev_softc, link); + destroy_dev(sc->cdev); + vm_destroy(sc->vm); + free(sc, M_VMMDEV); +} + +static int +sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS) +{ + int error; + char buf[VM_MAX_NAMELEN]; + struct vmmdev_softc *sc; + + strlcpy(buf, "beavis", sizeof(buf)); + error = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (error != 0 || req->newptr == NULL) + return (error); + + mtx_lock(&vmmdev_mtx); + sc = vmmdev_lookup(buf); + if (sc == NULL) { + mtx_unlock(&vmmdev_mtx); + return (EINVAL); + } + vmmdev_destroy(sc); + mtx_unlock(&vmmdev_mtx); + return (0); +} +SYSCTL_PROC(_hw_vmm, OID_AUTO, destroy, CTLTYPE_STRING | CTLFLAG_RW, + NULL, 0, sysctl_vmm_destroy, "A", NULL); + +static struct cdevsw vmmdevsw = { + .d_name = "vmmdev", + .d_version = D_VERSION, + .d_ioctl = vmmdev_ioctl, + .d_mmap = vmmdev_mmap, + .d_read = vmmdev_rw, + .d_write = vmmdev_rw, +}; + +static int +sysctl_vmm_create(SYSCTL_HANDLER_ARGS) +{ + int error; + struct vm *vm; + struct vmmdev_softc *sc; + char buf[VM_MAX_NAMELEN]; + + strlcpy(buf, "beavis", sizeof(buf)); + error = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (error != 0 || req->newptr == NULL) + return (error); + + mtx_lock(&vmmdev_mtx); + + sc = vmmdev_lookup(buf); + if (sc != NULL) { + mtx_unlock(&vmmdev_mtx); + return (EEXIST); + } + + vm = vm_create(buf); + if (vm == NULL) { + mtx_unlock(&vmmdev_mtx); + return (EINVAL); + } + + sc = malloc(sizeof(struct vmmdev_softc), M_VMMDEV, M_WAITOK | M_ZERO); + sc->vm = vm; + sc->cdev = make_dev(&vmmdevsw, 0, UID_ROOT, GID_WHEEL, 0600, + "vmm/%s", buf); + sc->cdev->si_drv1 = sc; + SLIST_INSERT_HEAD(&head, sc, link); + + mtx_unlock(&vmmdev_mtx); + return (0); +} +SYSCTL_PROC(_hw_vmm, OID_AUTO, create, CTLTYPE_STRING | CTLFLAG_RW, + NULL, 0, sysctl_vmm_create, "A", NULL); + +void +vmmdev_init(void) +{ + mtx_init(&vmmdev_mtx, "vmm device mutex", NULL, MTX_DEF); +} + +void +vmmdev_cleanup(void) +{ + struct vmmdev_softc *sc, *sc2; + + mtx_lock(&vmmdev_mtx); + + SLIST_FOREACH_SAFE(sc, &head, link, sc2) + vmmdev_destroy(sc); + + mtx_unlock(&vmmdev_mtx); +} diff --git a/sys/amd64/vmm/vmm_ipi.c b/sys/amd64/vmm/vmm_ipi.c new file mode 100644 index 00000000000..c8e795bedcc --- /dev/null +++ b/sys/amd64/vmm/vmm_ipi.c @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "vmm_ipi.h" + +extern inthand_t IDTVEC(rsvd), IDTVEC(justreturn); + +/* + * The default is to use the IPI_AST to interrupt a vcpu. + */ +static int ipinum = IPI_AST; + +CTASSERT(APIC_SPURIOUS_INT == 255); + +void +vmm_ipi_init(void) +{ + int idx; + uintptr_t func; + struct gate_descriptor *ip; + + /* + * Search backwards from the highest IDT vector available for use + * as our IPI vector. We install the 'justreturn' handler at that + * vector and use it to interrupt the vcpus. + * + * We do this because the IPI_AST is heavyweight and saves all + * registers in the trapframe. This is overkill for our use case + * which is simply to EOI the interrupt and return. + */ + idx = APIC_SPURIOUS_INT; + while (--idx >= APIC_IPI_INTS) { + ip = &idt[idx]; + func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset); + if (func == (uintptr_t)&IDTVEC(rsvd)) { + ipinum = idx; + setidt(ipinum, IDTVEC(justreturn), SDT_SYSIGT, + SEL_KPL, 0); + break; + } + } + + if (ipinum != IPI_AST && bootverbose) { + printf("vmm_ipi_init: installing ipi handler to interrupt " + "vcpus at vector %d\n", ipinum); + } +} + +void +vmm_ipi_cleanup(void) +{ + if (ipinum != IPI_AST) + setidt(ipinum, IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0); +} + +void +vm_interrupt_hostcpu(struct vm *vm, int vcpu) +{ + int hostcpu; + + if (vcpu_is_running(vm, vcpu, &hostcpu) && hostcpu != curcpu) + ipi_selected((cpumask_t)1 << hostcpu, ipinum); +} diff --git a/sys/amd64/vmm/vmm_ipi.h b/sys/amd64/vmm/vmm_ipi.h new file mode 100644 index 00000000000..7ab94bfdf07 --- /dev/null +++ b/sys/amd64/vmm/vmm_ipi.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMM_IPI_H_ +#define _VMM_IPI_H_ + +struct vm; + +void vmm_ipi_init(void); +void vmm_ipi_cleanup(void); +void vm_interrupt_hostcpu(struct vm *vm, int vcpu); + +#endif diff --git a/sys/amd64/vmm/vmm_ktr.h b/sys/amd64/vmm/vmm_ktr.h new file mode 100644 index 00000000000..e691c61af68 --- /dev/null +++ b/sys/amd64/vmm/vmm_ktr.h @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMM_KTR_H_ +#define _VMM_KTR_H_ + +#include +#include + +#define KTR_VMM KTR_GEN + +#define VMM_CTR0(vm, vcpuid, format) \ +CTR3(KTR_VMM, "vm %s-%d(%d): " format, vm_name((vm)), (vcpuid), curcpu) + +#define VMM_CTR1(vm, vcpuid, format, p1) \ +CTR4(KTR_VMM, "vm %s-%d(%d): " format, vm_name((vm)), (vcpuid), curcpu, \ + (p1)) + +#define VMM_CTR2(vm, vcpuid, format, p1, p2) \ +CTR5(KTR_VMM, "vm %s-%d(%d): " format, vm_name((vm)), (vcpuid), curcpu, \ + (p1), (p2)) + +#define VMM_CTR3(vm, vcpuid, format, p1, p2, p3) \ +CTR6(KTR_VMM, "vm %s-%d(%d): " format, vm_name((vm)), (vcpuid), curcpu, \ + (p1), (p2), (p3)) +#endif diff --git a/sys/amd64/vmm/vmm_lapic.c b/sys/amd64/vmm/vmm_lapic.c new file mode 100644 index 00000000000..8704fcf4c75 --- /dev/null +++ b/sys/amd64/vmm/vmm_lapic.c @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include "vmm_ipi.h" +#include "vmm_lapic.h" +#include "vlapic.h" + +int +lapic_write(struct vm *vm, int cpu, u_int offset, uint64_t val) +{ + int handled; + + struct vlapic *vlapic; + + vlapic = vm_lapic(vm, cpu); + + if (vlapic_op_mem_write(vlapic, offset, DWORD, val) == 0) + handled = 1; + else + handled = 0; + + return (handled); +} + +int +lapic_read(struct vm *vm, int cpu, u_int offset, uint64_t *rv) +{ + int handled; + + struct vlapic *vlapic; + + vlapic = vm_lapic(vm, cpu); + + if (vlapic_op_mem_read(vlapic, offset, DWORD, rv) == 0) + handled = 1; + else + handled = 0; + + return (handled); +} + +int +lapic_pending_intr(struct vm *vm, int cpu) +{ + struct vlapic *vlapic; + + vlapic = vm_lapic(vm, cpu); + + return (vlapic_pending_intr(vlapic)); +} + +void +lapic_intr_accepted(struct vm *vm, int cpu, int vector) +{ + struct vlapic *vlapic; + + vlapic = vm_lapic(vm, cpu); + + vlapic_intr_accepted(vlapic, vector); +} + +int +lapic_set_intr(struct vm *vm, int cpu, int vector) +{ + struct vlapic *vlapic; + + if (cpu < 0 || cpu >= VM_MAXCPU) + return (EINVAL); + + if (vector < 32 || vector > 255) + return (EINVAL); + + vlapic = vm_lapic(vm, cpu); + vlapic_set_intr_ready(vlapic, vector); + + vm_interrupt_hostcpu(vm, cpu); + + return (0); +} + +void +lapic_timer_tick(struct vm *vm, int cpu) +{ + struct vlapic *vlapic; + + vlapic = vm_lapic(vm, cpu); + + vlapic_timer_tick(vlapic); +} diff --git a/sys/amd64/vmm/vmm_lapic.h b/sys/amd64/vmm/vmm_lapic.h new file mode 100644 index 00000000000..815b2f7937b --- /dev/null +++ b/sys/amd64/vmm/vmm_lapic.h @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMM_LAPIC_H_ +#define _VMM_LAPIC_H_ + +struct vm; + +int lapic_write(struct vm *vm, int cpu, u_int offset, uint64_t val); +int lapic_read(struct vm *vm, int cpu, u_int offset, uint64_t *retval); +void lapic_timer_tick(struct vm *vm, int cpu); + +/* + * Returns a vector between 32 and 255 if an interrupt is pending in the + * IRR that can be delivered based on the current state of ISR and TPR. + * + * Note that the vector does not automatically transition to the ISR as a + * result of calling this function. + * + * Returns -1 if there is no eligible vector that can be delivered to the + * guest at this time. + */ +int lapic_pending_intr(struct vm *vm, int cpu); + +/* + * Transition 'vector' from IRR to ISR. This function is called with the + * vector returned by 'lapic_pending_intr()' when the guest is able to + * accept this interrupt (i.e. RFLAGS.IF = 1 and no conditions exist that + * block interrupt delivery). + */ +void lapic_intr_accepted(struct vm *vm, int cpu, int vector); + +/* + * Signals to the LAPIC that an interrupt at 'vector' needs to be generated + * to the 'cpu', the state is recorded in IRR. + */ +int lapic_set_intr(struct vm *vm, int cpu, int vector); + +#endif diff --git a/sys/amd64/vmm/vmm_mem.c b/sys/amd64/vmm/vmm_mem.c new file mode 100644 index 00000000000..9ce1e800f32 --- /dev/null +++ b/sys/amd64/vmm/vmm_mem.c @@ -0,0 +1,413 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "vmm_util.h" +#include "vmm_mem.h" + +static MALLOC_DEFINE(M_VMM_MEM, "vmm memory", "vmm memory"); + +#define MB (1024 * 1024) +#define GB (1024 * MB) + +#define VMM_MEM_MAXSEGS 64 + +/* protected by vmm_mem_mtx */ +static struct { + vm_paddr_t base; + vm_size_t length; +} vmm_mem_avail[VMM_MEM_MAXSEGS]; + +static int vmm_mem_nsegs; + +static vm_paddr_t maxaddr; + +static struct mtx vmm_mem_mtx; + +/* + * Steal any memory that was deliberately hidden from FreeBSD either by + * the use of MAXMEM kernel config option or the hw.physmem loader tunable. + */ +static int +vmm_mem_steal_memory(void) +{ + int nsegs; + caddr_t kmdp; + uint32_t smapsize; + uint64_t base, length; + struct bios_smap *smapbase, *smap, *smapend; + + /* + * Borrowed from hammer_time() and getmemsize() in machdep.c + */ + kmdp = preload_search_by_type("elf kernel"); + if (kmdp == NULL) + kmdp = preload_search_by_type("elf64 kernel"); + + smapbase = (struct bios_smap *)preload_search_info(kmdp, + MODINFO_METADATA | MODINFOMD_SMAP); + if (smapbase == NULL) + panic("No BIOS smap info from loader!"); + + smapsize = *((uint32_t *)smapbase - 1); + smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize); + + nsegs = 0; + for (smap = smapbase; smap < smapend; smap++) { + /* + * XXX + * Assuming non-overlapping, monotonically increasing + * memory segments. + */ + if (smap->type != SMAP_TYPE_MEMORY) + continue; + if (smap->length == 0) + break; + + base = roundup(smap->base, NBPDR); + length = rounddown(smap->length, NBPDR); + + /* Skip this segment if FreeBSD is using all of it. */ + if (base + length <= ptoa(Maxmem)) + continue; + + /* + * If FreeBSD is using part of this segment then adjust + * 'base' and 'length' accordingly. + */ + if (base < ptoa(Maxmem)) { + uint64_t used; + used = roundup(ptoa(Maxmem), NBPDR) - base; + base += used; + length -= used; + } + + if (length == 0) + continue; + + vmm_mem_avail[nsegs].base = base; + vmm_mem_avail[nsegs].length = length; + + if (base + length > maxaddr) + maxaddr = base + length; + + if (0 && bootverbose) { + printf("vmm_mem_populate: index %d, base 0x%0lx, " + "length %ld\n", + nsegs, vmm_mem_avail[nsegs].base, + vmm_mem_avail[nsegs].length); + } + + nsegs++; + if (nsegs >= VMM_MEM_MAXSEGS) { + printf("vmm_mem_populate: maximum number of vmm memory " + "segments reached!\n"); + return (ENOSPC); + } + } + + vmm_mem_nsegs = nsegs; + + return (0); +} + +static void +vmm_mem_direct_map(vm_paddr_t start, vm_paddr_t end) +{ + vm_paddr_t addr, remaining; + int pdpi, pdi, superpage_size; + pml4_entry_t *pml4p; + pdp_entry_t *pdp; + pd_entry_t *pd; + uint64_t page_attr_bits; + + if (end >= NBPML4) + panic("Cannot map memory beyond %ldGB", NBPML4 / GB); + + /* XXX FreeBSD 8.1 does not use 1G superpages in the direct map */ + if (0 && vmm_supports_1G_pages()) + superpage_size = NBPDP; + else + superpage_size = NBPDR; + + /* + * Get the page directory pointer page that contains the direct + * map address mappings. + */ + pml4p = kernel_pmap->pm_pml4; + pdp = (pdp_entry_t *)PHYS_TO_DMAP(pml4p[DMPML4I] & ~PAGE_MASK); + + page_attr_bits = PG_RW | PG_V | PG_PS | PG_G; + addr = start; + while (addr < end) { + remaining = end - addr; + pdpi = addr / NBPDP; + if (superpage_size == NBPDP && + remaining >= NBPDP && + addr % NBPDP == 0) { + /* + * If there isn't a mapping for this address then + * create one but if there is one already make sure + * it matches what we expect it to be. + */ + if (pdp[pdpi] == 0) { + pdp[pdpi] = addr | page_attr_bits; + if (0 && bootverbose) { + printf("vmm_mem_populate: mapping " + "0x%lx with 1GB page at " + "pdpi %d\n", addr, pdpi); + } + } else { + pdp_entry_t pdpe = pdp[pdpi]; + if ((pdpe & ~PAGE_MASK) != addr || + (pdpe & page_attr_bits) != page_attr_bits) { + panic("An invalid mapping 0x%016lx " + "already exists for 0x%016lx\n", + pdpe, addr); + } + } + addr += NBPDP; + } else { + if (remaining < NBPDR) { + panic("vmm_mem_populate: remaining (%ld) must " + "be greater than NBPDR (%d)\n", + remaining, NBPDR); + } + if (pdp[pdpi] == 0) { + /* + * XXX we lose this memory forever because + * we do not keep track of the virtual address + * that would be required to free this page. + */ + pd = malloc(PAGE_SIZE, M_VMM_MEM, + M_WAITOK | M_ZERO); + if ((uintptr_t)pd & PAGE_MASK) { + panic("vmm_mem_populate: page directory" + "page not aligned on %d " + "boundary\n", PAGE_SIZE); + } + pdp[pdpi] = vtophys(pd); + pdp[pdpi] |= PG_RW | PG_V | PG_U; + if (0 && bootverbose) { + printf("Creating page directory " + "at pdp index %d for 0x%016lx\n", + pdpi, addr); + } + } + pdi = (addr % NBPDP) / NBPDR; + pd = (pd_entry_t *)PHYS_TO_DMAP(pdp[pdpi] & ~PAGE_MASK); + + /* + * Create a new mapping if one doesn't already exist + * or validate it if it does. + */ + if (pd[pdi] == 0) { + pd[pdi] = addr | page_attr_bits; + if (0 && bootverbose) { + printf("vmm_mem_populate: mapping " + "0x%lx with 2MB page at " + "pdpi %d, pdi %d\n", + addr, pdpi, pdi); + } + } else { + pd_entry_t pde = pd[pdi]; + if ((pde & ~PAGE_MASK) != addr || + (pde & page_attr_bits) != page_attr_bits) { + panic("An invalid mapping 0x%016lx " + "already exists for 0x%016lx\n", + pde, addr); + } + } + addr += NBPDR; + } + } +} + +static int +vmm_mem_populate(void) +{ + int seg, error; + vm_paddr_t start, end; + + /* populate the vmm_mem_avail[] array */ + error = vmm_mem_steal_memory(); + if (error) + return (error); + + /* + * Now map the memory that was hidden from FreeBSD in + * the direct map VA space. + */ + for (seg = 0; seg < vmm_mem_nsegs; seg++) { + start = vmm_mem_avail[seg].base; + end = start + vmm_mem_avail[seg].length; + if ((start & PDRMASK) != 0 || (end & PDRMASK) != 0) { + panic("start (0x%016lx) and end (0x%016lx) must be " + "aligned on a %dMB boundary\n", + start, end, NBPDR / MB); + } + vmm_mem_direct_map(start, end); + } + + return (0); +} + +int +vmm_mem_init(void) +{ + int error; + + mtx_init(&vmm_mem_mtx, "vmm_mem_mtx", NULL, MTX_DEF); + + error = vmm_mem_populate(); + if (error) + return (error); + + return (0); +} + +vm_paddr_t +vmm_mem_alloc(size_t size) +{ + int i; + vm_paddr_t addr; + + if ((size & PDRMASK) != 0) { + panic("vmm_mem_alloc: size 0x%0lx must be " + "aligned on a 0x%0x boundary\n", size, NBPDR); + } + + addr = 0; + + mtx_lock(&vmm_mem_mtx); + for (i = 0; i < vmm_mem_nsegs; i++) { + if (vmm_mem_avail[i].length >= size) { + addr = vmm_mem_avail[i].base; + vmm_mem_avail[i].base += size; + vmm_mem_avail[i].length -= size; + /* remove a zero length segment */ + if (vmm_mem_avail[i].length == 0) { + memmove(&vmm_mem_avail[i], + &vmm_mem_avail[i + 1], + (vmm_mem_nsegs - (i + 1)) * + sizeof(vmm_mem_avail[0])); + vmm_mem_nsegs--; + } + break; + } + } + mtx_unlock(&vmm_mem_mtx); + + return (addr); +} + +void +vmm_mem_free(vm_paddr_t base, size_t length) +{ + int i; + + if ((base & PDRMASK) != 0 || (length & PDRMASK) != 0) { + panic("vmm_mem_free: base 0x%0lx and length 0x%0lx must be " + "aligned on a 0x%0x boundary\n", base, length, NBPDR); + } + + mtx_lock(&vmm_mem_mtx); + + for (i = 0; i < vmm_mem_nsegs; i++) { + if (vmm_mem_avail[i].base > base) + break; + } + + if (vmm_mem_nsegs >= VMM_MEM_MAXSEGS) + panic("vmm_mem_free: cannot free any more segments"); + + /* Create a new segment at index 'i' */ + memmove(&vmm_mem_avail[i + 1], &vmm_mem_avail[i], + (vmm_mem_nsegs - i) * sizeof(vmm_mem_avail[0])); + + vmm_mem_avail[i].base = base; + vmm_mem_avail[i].length = length; + + vmm_mem_nsegs++; + +coalesce_some_more: + for (i = 0; i < vmm_mem_nsegs - 1; i++) { + if (vmm_mem_avail[i].base + vmm_mem_avail[i].length == + vmm_mem_avail[i + 1].base) { + vmm_mem_avail[i].length += vmm_mem_avail[i + 1].length; + memmove(&vmm_mem_avail[i + 1], &vmm_mem_avail[i + 2], + (vmm_mem_nsegs - (i + 2)) * sizeof(vmm_mem_avail[0])); + vmm_mem_nsegs--; + goto coalesce_some_more; + } + } + + mtx_unlock(&vmm_mem_mtx); +} + +vm_paddr_t +vmm_mem_maxaddr(void) +{ + + return (maxaddr); +} + +void +vmm_mem_dump(void) +{ + int i; + vm_paddr_t base; + vm_size_t length; + + mtx_lock(&vmm_mem_mtx); + for (i = 0; i < vmm_mem_nsegs; i++) { + base = vmm_mem_avail[i].base; + length = vmm_mem_avail[i].length; + printf("%-4d0x%016lx 0x%016lx\n", i, base, base + length); + } + mtx_unlock(&vmm_mem_mtx); +} diff --git a/sys/amd64/vmm/vmm_mem.h b/sys/amd64/vmm/vmm_mem.h new file mode 100644 index 00000000000..ef1bf1aee32 --- /dev/null +++ b/sys/amd64/vmm/vmm_mem.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMM_MEM_H_ +#define _VMM_MEM_H_ + +int vmm_mem_init(void); +vm_paddr_t vmm_mem_alloc(size_t size); +void vmm_mem_free(vm_paddr_t start, size_t size); +vm_paddr_t vmm_mem_maxaddr(void); +void vmm_mem_dump(void); + +#endif diff --git a/sys/amd64/vmm/vmm_msr.c b/sys/amd64/vmm/vmm_msr.c new file mode 100644 index 00000000000..152aa7b17e1 --- /dev/null +++ b/sys/amd64/vmm/vmm_msr.c @@ -0,0 +1,264 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include + +#include +#include "vmm_lapic.h" +#include "vmm_msr.h" + +#define VMM_MSR_F_EMULATE 0x01 +#define VMM_MSR_F_READONLY 0x02 + +struct vmm_msr { + int num; + int flags; + uint64_t hostval; +}; + +static struct vmm_msr vmm_msr[] = { + { MSR_LSTAR, 0 }, + { MSR_CSTAR, 0 }, + { MSR_STAR, 0 }, + { MSR_SF_MASK, 0 }, + { MSR_APICBASE, VMM_MSR_F_EMULATE }, + { MSR_BIOS_SIGN,VMM_MSR_F_EMULATE }, + { MSR_MCG_CAP, VMM_MSR_F_EMULATE | VMM_MSR_F_READONLY }, +}; + +#define vmm_msr_num (sizeof(vmm_msr) / sizeof(vmm_msr[0])) +CTASSERT(VMM_MSR_NUM >= vmm_msr_num); + +#define readonly_msr(idx) \ + ((vmm_msr[(idx)].flags & VMM_MSR_F_READONLY) != 0) + +#define emulated_msr(idx) \ + ((vmm_msr[(idx)].flags & VMM_MSR_F_EMULATE) != 0) + +void +vmm_msr_init(void) +{ + int i; + + for (i = 0; i < vmm_msr_num; i++) { + if (emulated_msr(i)) + continue; + /* + * XXX this assumes that the value of the host msr does not + * change after we have cached it. + */ + vmm_msr[i].hostval = rdmsr(vmm_msr[i].num); + } +} + +void +guest_msrs_init(struct vm *vm, int cpu) +{ + int i; + uint64_t *guest_msrs; + + guest_msrs = vm_guest_msrs(vm, cpu); + + for (i = 0; i < vmm_msr_num; i++) { + switch (vmm_msr[i].num) { + case MSR_LSTAR: + case MSR_CSTAR: + case MSR_STAR: + case MSR_SF_MASK: + case MSR_BIOS_SIGN: + case MSR_MCG_CAP: + guest_msrs[i] = 0; + break; + case MSR_APICBASE: + guest_msrs[i] = DEFAULT_APIC_BASE | APICBASE_ENABLED | + APICBASE_X2APIC; + if (cpu == 0) + guest_msrs[i] |= APICBASE_BSP; + break; + default: + panic("guest_msrs_init: missing initialization for msr " + "0x%0x", vmm_msr[i].num); + } + } +} + +static boolean_t +x2apic_msr(u_int num) +{ + + if (num >= 0x800 && num <= 0xBFF) + return (TRUE); + else + return (FALSE); +} + +static u_int +x2apic_msr_to_regoff(u_int msr) +{ + + return ((msr - 0x800) << 4); +} + +static boolean_t +x2apic_msr_id(u_int num) +{ + return (num == 0x802); +} + +static int +msr_num_to_idx(u_int num) +{ + int i; + + for (i = 0; i < vmm_msr_num; i++) + if (vmm_msr[i].num == num) + return (i); + + return (-1); +} + +int +emulate_wrmsr(struct vm *vm, int cpu, u_int num, uint64_t val) +{ + int handled, idx; + uint64_t *guest_msrs; + + handled = 0; + + if (x2apic_msr(num)) + return (lapic_write(vm, cpu, x2apic_msr_to_regoff(num), val)); + + idx = msr_num_to_idx(num); + if (idx < 0) + goto done; + + if (!readonly_msr(idx)) { + guest_msrs = vm_guest_msrs(vm, cpu); + + /* Stash the value */ + guest_msrs[idx] = val; + + /* Update processor state for non-emulated MSRs */ + if (!emulated_msr(idx)) + wrmsr(vmm_msr[idx].num, val); + } + + handled = 1; +done: + return (handled); +} + +int +emulate_rdmsr(struct vm *vm, int cpu, u_int num) +{ + int error, handled, idx; + uint32_t eax, edx; + uint64_t result, *guest_msrs; + + handled = 0; + + if (x2apic_msr(num)) { + handled = lapic_read(vm, cpu, x2apic_msr_to_regoff(num), + &result); + /* + * The version ID needs to be massaged + */ + if (x2apic_msr_id(num)) { + result = result >> 24; + } + goto done; + } + + idx = msr_num_to_idx(num); + if (idx < 0) + goto done; + + guest_msrs = vm_guest_msrs(vm, cpu); + result = guest_msrs[idx]; + + /* + * If this is not an emulated msr register make sure that the processor + * state matches our cached state. + */ + if (!emulated_msr(idx) && (rdmsr(num) != result)) { + panic("emulate_rdmsr: msr 0x%0x has inconsistent cached " + "(0x%016lx) and actual (0x%016lx) values", num, + result, rdmsr(num)); + } + + handled = 1; + +done: + if (handled) { + eax = result; + edx = result >> 32; + error = vm_set_register(vm, cpu, VM_REG_GUEST_RAX, eax); + if (error) + panic("vm_set_register(rax) error %d", error); + error = vm_set_register(vm, cpu, VM_REG_GUEST_RDX, edx); + if (error) + panic("vm_set_register(rdx) error %d", error); + } + return (handled); +} + +void +restore_guest_msrs(struct vm *vm, int cpu) +{ + int i; + uint64_t *guest_msrs; + + guest_msrs = vm_guest_msrs(vm, cpu); + + for (i = 0; i < vmm_msr_num; i++) { + if (emulated_msr(i)) + continue; + else + wrmsr(vmm_msr[i].num, guest_msrs[i]); + } +} + +void +restore_host_msrs(struct vm *vm, int cpu) +{ + int i; + + for (i = 0; i < vmm_msr_num; i++) { + if (emulated_msr(i)) + continue; + else + wrmsr(vmm_msr[i].num, vmm_msr[i].hostval); + } +} diff --git a/sys/amd64/vmm/vmm_msr.h b/sys/amd64/vmm/vmm_msr.h new file mode 100644 index 00000000000..1e157876e8a --- /dev/null +++ b/sys/amd64/vmm/vmm_msr.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMM_MSR_H_ +#define _VMM_MSR_H_ + +#define VMM_MSR_NUM 16 +struct vm; + +void vmm_msr_init(void); +int emulate_wrmsr(struct vm *vm, int vcpu, u_int msr, uint64_t val); +int emulate_rdmsr(struct vm *vm, int vcpu, u_int msr); +void guest_msrs_init(struct vm *vm, int cpu); +void restore_host_msrs(struct vm *vm, int cpu); +void restore_guest_msrs(struct vm *vm, int cpu); + +#endif diff --git a/sys/amd64/vmm/vmm_stat.c b/sys/amd64/vmm/vmm_stat.c new file mode 100644 index 00000000000..e6f5c48d2d3 --- /dev/null +++ b/sys/amd64/vmm/vmm_stat.c @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include "vmm_stat.h" + +static int vstnum; +static struct vmm_stat_type *vsttab[MAX_VMM_STAT_TYPES]; + +static MALLOC_DEFINE(M_VMM_STAT, "vmm stat", "vmm stat"); + +void +vmm_stat_init(void *arg) +{ + struct vmm_stat_type *vst = arg; + + /* We require all stats to identify themselves with a description */ + if (vst->desc == NULL) + return; + + if (vstnum >= MAX_VMM_STAT_TYPES) { + printf("Cannot accomodate vmm stat type \"%s\"!\n", vst->desc); + return; + } + + vst->index = vstnum; + vsttab[vstnum++] = vst; +} + +int +vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf) +{ + int i; + uint64_t *stats; + + if (vcpu < 0 || vcpu >= VM_MAXCPU) + return (EINVAL); + + stats = vcpu_stats(vm, vcpu); + for (i = 0; i < vstnum; i++) + buf[i] = stats[i]; + *num_stats = vstnum; + return (0); +} + +void * +vmm_stat_alloc(void) +{ + u_long size; + + size = vstnum * sizeof(uint64_t); + + return (malloc(size, M_VMM_STAT, M_ZERO | M_WAITOK)); +} + +void +vmm_stat_free(void *vp) +{ + free(vp, M_VMM_STAT); +} + +const char * +vmm_stat_desc(int index) +{ + + if (index >= 0 && index < vstnum) + return (vsttab[index]->desc); + else + return (NULL); +} diff --git a/sys/amd64/vmm/vmm_stat.h b/sys/amd64/vmm/vmm_stat.h new file mode 100644 index 00000000000..7c075a6a760 --- /dev/null +++ b/sys/amd64/vmm/vmm_stat.h @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 _VMM_STAT_H_ +#define _VMM_STAT_H_ + +struct vm; + +#define MAX_VMM_STAT_TYPES 64 /* arbitrary */ + +struct vmm_stat_type { + const char *desc; /* description of statistic */ + int index; /* position in the stats buffer */ +}; + +void vmm_stat_init(void *arg); + +#define VMM_STAT_DEFINE(type, desc) \ + struct vmm_stat_type type[1] = { \ + { desc, -1 } \ + }; \ + SYSINIT(type##_stat, SI_SUB_KLD, SI_ORDER_ANY, vmm_stat_init, type) + +void *vmm_stat_alloc(void); +void vmm_stat_free(void *vp); + +/* + * 'buf' should be at least fit 'MAX_VMM_STAT_TYPES' entries + */ +int vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf); +const char *vmm_stat_desc(int index); + +static void __inline +vmm_stat_incr(struct vm *vm, int vcpu, struct vmm_stat_type *vst, uint64_t x) +{ +#ifdef VMM_KEEP_STATS + uint64_t *stats = vcpu_stats(vm, vcpu); + if (vst->index >= 0) + stats[vst->index] += x; +#endif +} + +#endif diff --git a/sys/amd64/vmm/vmm_support.S b/sys/amd64/vmm/vmm_support.S new file mode 100644 index 00000000000..2afc608ae71 --- /dev/null +++ b/sys/amd64/vmm/vmm_support.S @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#define LOCORE + +#include + +#define LA_EOI 0xB0 + + .text + SUPERALIGN_TEXT +IDTVEC(justreturn) + pushq %rax + movq lapic, %rax + movl $0, LA_EOI(%rax) + popq %rax + iretq diff --git a/sys/amd64/vmm/vmm_util.c b/sys/amd64/vmm/vmm_util.c new file mode 100644 index 00000000000..f245f922120 --- /dev/null +++ b/sys/amd64/vmm/vmm_util.c @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include + +#include "vmm_util.h" + +boolean_t +vmm_is_intel(void) +{ + + if (strcmp(cpu_vendor, "GenuineIntel") == 0) + return (TRUE); + else + return (FALSE); +} + +boolean_t +vmm_is_amd(void) +{ + if (strcmp(cpu_vendor, "AuthenticAMD") == 0) + return (TRUE); + else + return (FALSE); +} + +boolean_t +vmm_supports_1G_pages(void) +{ + unsigned int regs[4]; + + /* + * CPUID.80000001:EDX[bit 26] = 1 indicates support for 1GB pages + * + * Both Intel and AMD support this bit. + */ + if (cpu_exthigh >= 0x80000001) { + do_cpuid(0x80000001, regs); + if (regs[3] & (1 << 26)) + return (TRUE); + } + return (FALSE); +} + +#include +#include +#define DUMP_REG(x) printf(#x "\t\t0x%016lx\n", (long)(tf->tf_ ## x)) +#define DUMP_SEG(x) printf(#x "\t\t0x%04x\n", (unsigned)(tf->tf_ ## x)) +void +dump_trapframe(struct trapframe *tf) +{ + DUMP_REG(rdi); + DUMP_REG(rsi); + DUMP_REG(rdx); + DUMP_REG(rcx); + DUMP_REG(r8); + DUMP_REG(r9); + DUMP_REG(rax); + DUMP_REG(rbx); + DUMP_REG(rbp); + DUMP_REG(r10); + DUMP_REG(r11); + DUMP_REG(r12); + DUMP_REG(r13); + DUMP_REG(r14); + DUMP_REG(r15); + DUMP_REG(trapno); + DUMP_REG(addr); + DUMP_REG(flags); + DUMP_REG(err); + DUMP_REG(rip); + DUMP_REG(rflags); + DUMP_REG(rsp); + DUMP_SEG(cs); + DUMP_SEG(ss); + DUMP_SEG(fs); + DUMP_SEG(gs); + DUMP_SEG(es); + DUMP_SEG(ds); +} diff --git a/sys/amd64/vmm/vmm_util.h b/sys/amd64/vmm/vmm_util.h new file mode 100644 index 00000000000..7f82332923a --- /dev/null +++ b/sys/amd64/vmm/vmm_util.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VMM_UTIL_H_ +#define _VMM_UTIL_H_ + +struct trapframe; + +boolean_t vmm_is_intel(void); +boolean_t vmm_is_amd(void); +boolean_t vmm_supports_1G_pages(void); + +void dump_trapframe(struct trapframe *tf); + +#endif diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c new file mode 100644 index 00000000000..45c4c53c199 --- /dev/null +++ b/sys/amd64/vmm/x86.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include + +#include "x86.h" + +int +x86_emulate_cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) +{ + unsigned int func, regs[4]; + + func = *eax; + + cpuid_count(*eax, *ecx, regs); + + switch(func) { + case CPUID_0000_0000: + case CPUID_0000_0002: + case CPUID_0000_0003: + case CPUID_0000_0004: + case CPUID_0000_000A: + break; + + case CPUID_8000_0000: + case CPUID_8000_0001: + case CPUID_8000_0002: + case CPUID_8000_0003: + case CPUID_8000_0004: + case CPUID_8000_0006: + case CPUID_8000_0007: + case CPUID_8000_0008: + + break; + + case CPUID_0000_0001: + /* + * Override the APIC ID only in ebx + */ + regs[1] &= ~(CPUID_0000_0001_APICID_MASK); + /* + * XXX fixme for MP case, set apicid properly for cpu. + */ + regs[1] |= (0 << CPUID_0000_0001_APICID_SHIFT); + + /* + * Don't expose VMX capability. + * Advertise x2APIC capability. + */ + regs[2] &= ~CPUID_0000_0001_FEAT0_VMX; + regs[2] |= CPUID2_X2APIC; + + /* + * Machine check handling is done in the host. + * Hide MTRR capability. + */ + regs[3] &= ~(CPUID_MCA | CPUID_MCE | CPUID_MTRR); + + break; + + case CPUID_0000_000B: + /* + * XXXSMP fixme + * Processor topology enumeration + */ + regs[0] = 0; + regs[1] = 0; + regs[2] = *ecx & 0xff; + regs[3] = 0; + break; + + default: + return (0); + } + + *eax = regs[0]; + *ebx = regs[1]; + *ecx = regs[2]; + *edx = regs[3]; + return (1); +} + diff --git a/sys/amd64/vmm/x86.h b/sys/amd64/vmm/x86.h new file mode 100644 index 00000000000..bc4f8a45c78 --- /dev/null +++ b/sys/amd64/vmm/x86.h @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _X86_H_ +#define _X86_H_ + +#define CPUID_0000_0000 (0x0) +#define CPUID_0000_0001 (0x1) +#define CPUID_0000_0002 (0x2) +#define CPUID_0000_0003 (0x3) +#define CPUID_0000_0004 (0x4) +#define CPUID_0000_000A (0xA) +#define CPUID_0000_000B (0xB) +#define CPUID_8000_0000 (0x80000000) +#define CPUID_8000_0001 (0x80000001) +#define CPUID_8000_0002 (0x80000002) +#define CPUID_8000_0003 (0x80000003) +#define CPUID_8000_0004 (0x80000004) +#define CPUID_8000_0006 (0x80000006) +#define CPUID_8000_0007 (0x80000007) +#define CPUID_8000_0008 (0x80000008) + +/* + * CPUID instruction Fn0000_0001: + */ +#define CPUID_0000_0001_APICID_MASK (0xff<<24) +#define CPUID_0000_0001_APICID_SHIFT 24 + +/* + * CPUID instruction Fn0000_0001 ECX + */ +#define CPUID_0000_0001_FEAT0_VMX (1<<5) + +int x86_emulate_cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, + uint32_t *edx); + +#endif diff --git a/sys/modules/Makefile b/sys/modules/Makefile index e781da0a33f..127c3e01a2d 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -290,6 +290,7 @@ SUBDIR= ${_3dfx} \ ${_vesa} \ vge \ vkbd \ + ${_vmm} \ ${_vpo} \ vr \ vx \ @@ -557,6 +558,7 @@ _sppp= sppp _tmpfs= tmpfs _twa= twa _vesa= vesa +_vmm= vmm _x86bios= x86bios _wi= wi _wpi= wpi diff --git a/sys/modules/vmm/Makefile b/sys/modules/vmm/Makefile new file mode 100644 index 00000000000..67c5b0f33cc --- /dev/null +++ b/sys/modules/vmm/Makefile @@ -0,0 +1,66 @@ +# $FreeBSD$ + +# *REQUIRES* binutils 2.20.1 for VT-x instructions +AS= /usr/local/bin/as +LD= /usr/local/bin/ld +CFLAGS+= -B /usr/local/bin + +KMOD= vmm + +SRCS= device_if.h bus_if.h pci_if.h + +CFLAGS+= -DVMM_KEEP_STATS +CFLAGS+= -DOLD_BINUTILS +CFLAGS+= -I${.CURDIR}/../../amd64/vmm +CFLAGS+= -I${.CURDIR}/../../amd64/vmm/io +CFLAGS+= -I${.CURDIR}/../../amd64/vmm/intel + +# generic vmm support +.PATH: ${.CURDIR}/../../amd64/vmm +SRCS+= vmm.c \ + vmm_dev.c \ + vmm_ipi.c \ + vmm_lapic.c \ + vmm_mem.c \ + vmm_msr.c \ + vmm_stat.c \ + vmm_util.c \ + x86.c \ + vmm_support.S + +.PATH: ${.CURDIR}/../../amd64/vmm/io +SRCS+= iommu.c \ + ppt.c \ + vdev.c \ + vlapic.c + +# intel-specific files +.PATH: ${.CURDIR}/../../amd64/vmm/intel +SRCS+= ept.c \ + vmcs.c \ + vmx_msr.c \ + vmx.c \ + vtd.c + +# amd-specific files +.PATH: ${.CURDIR}/../../amd64/vmm/amd +SRCS+= amdv.c + +OBJS= vmx_support.o + +CLEANFILES= vmx_assym.s vmx_genassym.o + +vmx_assym.s: vmx_genassym.o +.if exists(@) +vmx_assym.s: @/kern/genassym.sh +.endif + sh @/kern/genassym.sh vmx_genassym.o > ${.TARGET} + +vmx_support.o: vmx_support.S vmx_assym.s + ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \ + ${.IMPSRC} -o ${.TARGET} + +vmx_genassym.o: vmx_genassym.c @ machine + ${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC} + +.include diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 44f20a49cee..fc527b74672 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -19,6 +19,7 @@ SUBDIR= ${_ac} \ ${_auditd} \ ${_auditreduce} \ ${_authpf} \ + ${_bhyve} \ ${_bluetooth} \ ${_boot0cfg} \ ${_boot98cfg} \ @@ -194,6 +195,7 @@ SUBDIR= ${_ac} \ ${_usbdevs} \ ${_usbconfig} \ ${_vidcontrol} \ + ${_vmmctl} \ vipw \ wake \ watch \ @@ -477,6 +479,7 @@ _boot98cfg= boot98cfg _acpi= acpi .endif _asf= asf +_bhyve= bhyve _boot0cfg= boot0cfg .if ${MK_TOOLCHAIN} != "no" _btxld= btxld @@ -494,6 +497,7 @@ _ndiscvt= ndiscvt .endif _sicontrol= sicontrol _spkrtest= spkrtest +_vmmctl= vmmctl _zzz= zzz .endif diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile new file mode 100644 index 00000000000..71df082dcf7 --- /dev/null +++ b/usr.sbin/bhyve/Makefile @@ -0,0 +1,18 @@ +# +# $FreeBSD$ +# + +PROG= bhyve + +SRCS= atpic.c consport.c dbgport.c elcr.c fbsdrun.c inout.c mevent.c +SRCS+= pci_emul.c pci_hostbridge.c pci_passthru.c pci_virtio_block.c +SRCS+= pci_virtio_net.c pit_8254.c post.c rtc.c uart.c xmsr.c + +NO_MAN= + +DPADD= ${LIBVMMAPI} ${LIBMD} ${LIBPTHREAD} +LDADD= -lvmmapi -lmd -lpthread + +CFLAGS+= -I${.CURDIR}/../../sys + +.include diff --git a/usr.sbin/bhyve/atpic.c b/usr.sbin/bhyve/atpic.c new file mode 100644 index 00000000000..a9fb0842c35 --- /dev/null +++ b/usr.sbin/bhyve/atpic.c @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include +#include + +#include "inout.h" + +/* + * FreeBSD only writes to the 8259 interrupt controllers to put them in a + * shutdown state. + * + * So, we just ignore the writes. + */ + +#define IO_ICU1 0x20 +#define IO_ICU2 0xA0 +#define ICU_IMR_OFFSET 1 + +static int +atpic_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + if (bytes != 1) + return (-1); + + if (in) + return (-1); + + /* Pretend all writes to the 8259 are alright */ + return (0); +} + +INOUT_PORT(atpic, IO_ICU1, IOPORT_F_INOUT, atpic_handler); +INOUT_PORT(atpic, IO_ICU1 + ICU_IMR_OFFSET, IOPORT_F_INOUT, atpic_handler); +INOUT_PORT(atpic, IO_ICU2, IOPORT_F_INOUT, atpic_handler); +INOUT_PORT(atpic, IO_ICU2 + ICU_IMR_OFFSET, IOPORT_F_INOUT, atpic_handler); diff --git a/usr.sbin/bhyve/consport.c b/usr.sbin/bhyve/consport.c new file mode 100644 index 00000000000..34f94a6cc77 --- /dev/null +++ b/usr.sbin/bhyve/consport.c @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include + +#include "inout.h" + +#define BVM_CONSOLE_PORT 0x220 + +static struct termios tio_orig, tio_new; + +static void +ttyclose(void) +{ + tcsetattr(STDIN_FILENO, TCSANOW, &tio_orig); +} + +static void +ttyopen(void) +{ + tcgetattr(STDIN_FILENO, &tio_orig); + + cfmakeraw(&tio_new); + tcsetattr(STDIN_FILENO, TCSANOW, &tio_new); + + atexit(ttyclose); +} + +static bool +tty_char_available(void) +{ + fd_set rfds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_SET(STDIN_FILENO, &rfds); + tv.tv_sec = 0; + tv.tv_usec = 0; + if (select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv) > 0) { + return (true); + } else { + return (false); + } +} + +static int +ttyread(void) +{ + char rb; + + if (tty_char_available()) { + read(STDIN_FILENO, &rb, 1); + return (rb & 0xff); + } else { + return (-1); + } +} + +static void +ttywrite(unsigned char wb) +{ + (void) write(STDOUT_FILENO, &wb, 1); +} + +static int +console_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + static int opened; + + if (bytes != 4) + return (-1); + + if (!opened) { + ttyopen(); + opened = 1; + } + + if (in) + *eax = ttyread(); + else + ttywrite(*eax); + + return (0); +} +INOUT_PORT(console, BVM_CONSOLE_PORT, IOPORT_F_INOUT, console_handler); diff --git a/usr.sbin/bhyve/dbgport.c b/usr.sbin/bhyve/dbgport.c new file mode 100644 index 00000000000..be919e1ea59 --- /dev/null +++ b/usr.sbin/bhyve/dbgport.c @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "inout.h" + +#define BVM_DBG_PORT 0x224 + +static int listen_fd, conn_fd; + +static struct sockaddr_in sin; + +void +init_dbgport(int sport) +{ + conn_fd = -1; + + if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + exit(1); + } + + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(sport); + + if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + perror("bind"); + exit(1); + } + + if (listen(listen_fd, 1) < 0) { + perror("listen"); + exit(1); + } +} + +static int +dbg_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + char ch; + int nwritten, nread, printonce; + + if (bytes != 4) + return (-1); + +again: + printonce = 0; + while (conn_fd < 0) { + if (!printonce) { + printf("Waiting for connection from gdb\r\n"); + printonce = 1; + } + conn_fd = accept(listen_fd, NULL, NULL); + if (conn_fd >= 0) + fcntl(conn_fd, F_SETFL, O_NONBLOCK); + else if (errno != EINTR) + perror("accept"); + } + + if (in) { + nread = read(conn_fd, &ch, 1); + if (nread == -1 && errno == EAGAIN) + *eax = -1; + else if (nread == 1) + *eax = ch; + else { + close(conn_fd); + conn_fd = -1; + goto again; + } + } else { + ch = *eax; + nwritten = write(conn_fd, &ch, 1); + if (nwritten != 1) { + close(conn_fd); + conn_fd = -1; + goto again; + } + } + return (0); +} + +INOUT_PORT(dbg, BVM_DBG_PORT, IOPORT_F_INOUT, dbg_handler); diff --git a/usr.sbin/bhyve/dbgport.h b/usr.sbin/bhyve/dbgport.h new file mode 100644 index 00000000000..8c7dab7f83c --- /dev/null +++ b/usr.sbin/bhyve/dbgport.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _DBGPORT_H_ +#define _DBGPORT_H_ + +#define DEFAULT_GDB_PORT 6466 + +void init_dbgport(int port); + +#endif diff --git a/usr.sbin/bhyve/elcr.c b/usr.sbin/bhyve/elcr.c new file mode 100644 index 00000000000..2417ae1bb27 --- /dev/null +++ b/usr.sbin/bhyve/elcr.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include "inout.h" + +/* + * EISA interrupt Level Control Register. + * + * This is a 16-bit register with one bit for each of the IRQ0 through IRQ15. + * A level triggered irq is indicated by setting the corresponding bit to '1'. + */ +#define ELCR_PORT 0x4d0 + +static uint8_t elcr[2] = { 0x00, 0x00 }; + +static int +elcr_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + int idx; + + if (bytes != 1) + return (-1); + + idx = port - ELCR_PORT; + + if (in) + *eax = elcr[idx]; + else + elcr[idx] = *eax; + + return (0); +} +INOUT_PORT(elcr, ELCR_PORT + 0, IOPORT_F_INOUT, elcr_handler); +INOUT_PORT(elcr, ELCR_PORT + 1, IOPORT_F_INOUT, elcr_handler); diff --git a/usr.sbin/bhyve/fbsdrun.c b/usr.sbin/bhyve/fbsdrun.c new file mode 100644 index 00000000000..ddbe709b8d5 --- /dev/null +++ b/usr.sbin/bhyve/fbsdrun.c @@ -0,0 +1,650 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "fbsdrun.h" +#include "inout.h" +#include "dbgport.h" +#include "mevent.h" +#include "pci_emul.h" +#include "xmsr.h" + +#define DEFAULT_GUEST_HZ 100 +#define DEFAULT_GUEST_TSLICE 200 + +#define GUEST_NIO_PORT 0x488 /* guest upcalls via i/o port */ + +#define VMEXIT_SWITCH 0 /* force vcpu switch in mux mode */ +#define VMEXIT_CONTINUE 1 /* continue from next instruction */ +#define VMEXIT_RESTART 2 /* restart current instruction */ +#define VMEXIT_ABORT 3 /* abort the vm run loop */ +#define VMEXIT_RESET 4 /* guest machine has reset */ + +#define MB (1024UL * 1024) +#define GB (1024UL * MB) + +typedef int (*vmexit_handler_t)(struct vmctx *, struct vm_exit *, int *vcpu); + +int guest_tslice = DEFAULT_GUEST_TSLICE; +int guest_hz = DEFAULT_GUEST_HZ; +char *vmname; + +u_long lomem_sz; +u_long himem_sz; + +int guest_ncpus; + +static int pincpu = -1; +static int guest_vcpu_mux; +static int guest_vmexit_on_hlt, guest_vmexit_on_pause; + +static int foundcpus; + +static char *lomem_addr; +static char *himem_addr; + +static char *progname; +static const int BSP = 0; + +static int cpumask; + +static void *oem_tbl_start; +static int oem_tbl_size; + +static void vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip); + +struct vm_exit vmexit[VM_MAXCPU]; + +struct fbsdstats { + uint64_t vmexit_bogus; + uint64_t vmexit_bogus_switch; + uint64_t vmexit_hlt; + uint64_t vmexit_pause; + uint64_t vmexit_mtrap; + uint64_t cpu_switch_rotate; + uint64_t cpu_switch_direct; + int io_reset; +} stats; + +struct mt_vmm_info { + pthread_t mt_thr; + struct vmctx *mt_ctx; + int mt_vcpu; +} mt_vmm_info[VM_MAXCPU]; + +static void +usage(int code) +{ + + fprintf(stderr, + "Usage: %s [-hBHP][-g ][-z ][-s ][-p pincpu]" + "[-n ][-m lowmem][-M highmem] \n" + " -g: gdb port (default is %d and 0 means don't open)\n" + " -c: # cpus (default 1)\n" + " -p: pin vcpu 'n' to host cpu 'pincpu + n'\n" + " -B: inject breakpoint exception on vm entry\n" + " -H: vmexit from the guest on hlt\n" + " -P: vmexit from the guest on pause\n" + " -h: help\n" + " -z: guest hz (default is %d)\n" + " -s: PCI slot config\n" + " -n: PCI slot naming\n" + " -m: lowmem in MB\n" + " -M: highmem in MB\n" + " -x: mux vcpus to 1 hcpu\n" + " -t: mux vcpu timeslice hz (default %d)\n", + progname, DEFAULT_GDB_PORT, DEFAULT_GUEST_HZ, + DEFAULT_GUEST_TSLICE); + exit(code); +} + +void * +paddr_guest2host(uintptr_t gaddr) +{ + if (lomem_sz == 0) + return (NULL); + + if (gaddr < lomem_sz) { + return ((void *)(lomem_addr + gaddr)); + } else if (gaddr >= 4*GB && gaddr < (4*GB + himem_sz)) { + return ((void *)(himem_addr + gaddr - 4*GB)); + } else + return (NULL); +} + +void +fbsdrun_add_oemtbl(void *tbl, int tblsz) +{ + oem_tbl_start = tbl; + oem_tbl_size = tblsz; +} + +int +fbsdrun_vmexit_on_pause(void) +{ + + return (guest_vmexit_on_pause); +} + +int +fbsdrun_vmexit_on_hlt(void) +{ + + return (guest_vmexit_on_hlt); +} + +int +fbsdrun_muxed(void) +{ + + return (guest_vcpu_mux); +} + +void * +fbsdrun_start_thread(void *param) +{ + int vcpu; + struct mt_vmm_info *mtp = param; + + vcpu = mtp->mt_vcpu; + vm_loop(mtp->mt_ctx, vcpu, vmexit[vcpu].rip); + + /* not reached */ + exit(1); + return (NULL); +} + +void +fbsdrun_addcpu(struct vmctx *ctx, int vcpu, uint64_t rip) +{ + int error; + + if (cpumask & (1 << vcpu)) { + printf("addcpu: attempting to add existing cpu %d\n", vcpu); + exit(1); + } + + cpumask |= 1 << vcpu; + foundcpus++; + + /* + * Set up the vmexit struct to allow execution to start + * at the given RIP + */ + vmexit[vcpu].rip = rip; + vmexit[vcpu].inst_length = 0; + + if (vcpu == BSP || !guest_vcpu_mux){ + mt_vmm_info[vcpu].mt_ctx = ctx; + mt_vmm_info[vcpu].mt_vcpu = vcpu; + + error = pthread_create(&mt_vmm_info[vcpu].mt_thr, NULL, + fbsdrun_start_thread, &mt_vmm_info[vcpu]); + assert(error == 0); + } +} + +static int +fbsdrun_get_next_cpu(int curcpu) +{ + + /* + * Get the next available CPU. Assumes they arrive + * in ascending order with no gaps. + */ + return ((curcpu + 1) % foundcpus); +} + +int +vmexit_catch_reset(void) +{ + stats.io_reset++; + return (VMEXIT_RESET); +} + +int +vmexit_catch_inout(void) +{ + return (VMEXIT_ABORT); +} + +int +vmexit_handle_notify(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu, + uint32_t eax) +{ +#if PG_DEBUG /* put all types of debug here */ + if (eax == 0) { + pause_noswitch = 1; + } else if (eax == 1) { + pause_noswitch = 0; + } else { + pause_noswitch = 0; + if (eax == 5) { + vm_set_capability(ctx, *pvcpu, VM_CAP_MTRAP_EXIT, 1); + } + } +#endif + return (VMEXIT_CONTINUE); +} + +static int +vmexit_inout(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) +{ + int error; + int bytes, port, in, out; + uint32_t eax; + int vcpu; + + vcpu = *pvcpu; + + port = vme->u.inout.port; + bytes = vme->u.inout.bytes; + eax = vme->u.inout.eax; + in = vme->u.inout.in; + out = !in; + + /* We don't deal with these */ + if (vme->u.inout.string || vme->u.inout.rep) + return (VMEXIT_ABORT); + + /* Special case of guest reset */ + if (out && port == 0x64 && (uint8_t)eax == 0xFE) + return (vmexit_catch_reset()); + + /* Extra-special case of host notifications */ + if (out && port == GUEST_NIO_PORT) + return (vmexit_handle_notify(ctx, vme, pvcpu, eax)); + + error = emulate_inout(ctx, vcpu, in, port, bytes, &eax); + if (error == 0 && in) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, eax); + + if (error == 0) + return (VMEXIT_CONTINUE); + else { + fprintf(stderr, "Unhandled %s%c 0x%04x\n", + in ? "in" : "out", + bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'), port); + return (vmexit_catch_inout()); + } +} + +static int +vmexit_rdmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) +{ + printf("vm exit rdmsr 0x%x, cpu %d\n", vme->u.msr.code, *pvcpu); + return (VMEXIT_ABORT); +} + +static int +vmexit_wrmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) +{ + int newcpu; + int retval = VMEXIT_CONTINUE; + + newcpu = emulate_wrmsr(ctx, *pvcpu, vme->u.msr.code,vme->u.msr.wval); + + if (guest_vcpu_mux && *pvcpu != newcpu) { + retval = VMEXIT_SWITCH; + *pvcpu = newcpu; + } + + return (retval); +} + +static int +vmexit_vmx(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + + printf("vm exit[%d]\n", *pvcpu); + printf("\treason\t\tVMX\n"); + printf("\trip\t\t0x%016lx\n", vmexit->rip); + printf("\tinst_length\t%d\n", vmexit->inst_length); + printf("\terror\t\t%d\n", vmexit->u.vmx.error); + printf("\texit_reason\t%u\n", vmexit->u.vmx.exit_reason); + printf("\tqualification\t0x%016lx\n", vmexit->u.vmx.exit_qualification); + + return (VMEXIT_ABORT); +} + +static int bogus_noswitch = 1; + +static int +vmexit_bogus(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + stats.vmexit_bogus++; + + if (!guest_vcpu_mux || guest_ncpus == 1 || bogus_noswitch) { + return (VMEXIT_RESTART); + } else { + stats.vmexit_bogus_switch++; + vmexit->inst_length = 0; + *pvcpu = -1; + return (VMEXIT_SWITCH); + } +} + +static int +vmexit_hlt(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + stats.vmexit_hlt++; + if (fbsdrun_muxed()) { + *pvcpu = -1; + return (VMEXIT_SWITCH); + } else { + /* + * Just continue execution with the next instruction. We use + * the HLT VM exit as a way to be friendly with the host + * scheduler. + */ + return (VMEXIT_CONTINUE); + } +} + +static int pause_noswitch; + +static int +vmexit_pause(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + stats.vmexit_pause++; + + if (fbsdrun_muxed() && !pause_noswitch) { + *pvcpu = -1; + return (VMEXIT_SWITCH); + } else { + return (VMEXIT_CONTINUE); + } +} + +static int +vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + stats.vmexit_mtrap++; + + return (VMEXIT_RESTART); +} + +static void +sigalrm(int sig) +{ + return; +} + +static void +setup_timeslice(void) +{ + struct sigaction sa; + struct itimerval itv; + int error; + + /* + * Setup a realtime timer to generate a SIGALRM at a + * frequency of 'guest_tslice' ticks per second. + */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = sigalrm; + + error = sigaction(SIGALRM, &sa, NULL); + assert(error == 0); + + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = 1000000 / guest_tslice; + itv.it_value.tv_sec = 0; + itv.it_value.tv_usec = 1000000 / guest_tslice; + + error = setitimer(ITIMER_REAL, &itv, NULL); + assert(error == 0); +} + +static vmexit_handler_t handler[VM_EXITCODE_MAX] = { + [VM_EXITCODE_INOUT] = vmexit_inout, + [VM_EXITCODE_VMX] = vmexit_vmx, + [VM_EXITCODE_BOGUS] = vmexit_bogus, + [VM_EXITCODE_RDMSR] = vmexit_rdmsr, + [VM_EXITCODE_WRMSR] = vmexit_wrmsr, + [VM_EXITCODE_MTRAP] = vmexit_mtrap, +}; + +static void +vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip) +{ + int error, rc, prevcpu; + + if (guest_vcpu_mux) + setup_timeslice(); + + if (pincpu >= 0) { + error = vm_set_pinning(ctx, vcpu, pincpu + vcpu); + assert(error == 0); + } + + while (1) { + error = vm_run(ctx, vcpu, rip, &vmexit[vcpu]); + if (error != 0) + break; + + prevcpu = vcpu; + rc = (*handler[vmexit[vcpu].exitcode])(ctx, &vmexit[vcpu], + &vcpu); + switch (rc) { + case VMEXIT_SWITCH: + assert(guest_vcpu_mux); + if (vcpu == -1) { + stats.cpu_switch_rotate++; + vcpu = fbsdrun_get_next_cpu(prevcpu); + } else { + stats.cpu_switch_direct++; + } + /* fall through */ + case VMEXIT_CONTINUE: + rip = vmexit[vcpu].rip + vmexit[vcpu].inst_length; + break; + case VMEXIT_RESTART: + rip = vmexit[vcpu].rip; + break; + case VMEXIT_RESET: + exit(0); + default: + exit(1); + } + } + fprintf(stderr, "vm_run error %d, errno %d\n", error, errno); +} + + +int +main(int argc, char *argv[]) +{ + int c, error, gdb_port, inject_bkpt, tmp, err; + struct vmctx *ctx; + uint64_t rip; + + inject_bkpt = 0; + progname = basename(argv[0]); + gdb_port = DEFAULT_GDB_PORT; + guest_ncpus = 1; + + while ((c = getopt(argc, argv, "hBHPxp:g:c:z:s:n:m:M:")) != -1) { + switch (c) { + case 'B': + inject_bkpt = 1; + break; + case 'x': + guest_vcpu_mux = 1; + break; + case 'p': + pincpu = atoi(optarg); + break; + case 'c': + guest_ncpus = atoi(optarg); + break; + case 'g': + gdb_port = atoi(optarg); + break; + case 'z': + guest_hz = atoi(optarg); + break; + case 't': + guest_tslice = atoi(optarg); + break; + case 's': + pci_parse_slot(optarg); + break; + case 'n': + pci_parse_name(optarg); + break; + case 'm': + lomem_sz = strtoul(optarg, NULL, 0) * MB; + break; + case 'M': + himem_sz = strtoul(optarg, NULL, 0) * MB; + break; + case 'H': + guest_vmexit_on_hlt = 1; + break; + case 'P': + guest_vmexit_on_pause = 1; + break; + case 'h': + usage(0); + default: + usage(1); + } + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(1); + + /* No need to mux if guest is uni-processor */ + if (guest_ncpus <= 1) + guest_vcpu_mux = 0; + + /* vmexit on hlt if guest is muxed */ + if (guest_vcpu_mux) { + guest_vmexit_on_hlt = 1; + guest_vmexit_on_pause = 1; + } + + vmname = argv[0]; + + ctx = vm_open(vmname); + if (ctx == NULL) { + perror("vm_open"); + exit(1); + } + + if (fbsdrun_vmexit_on_hlt()) { + err = vm_get_capability(ctx, BSP, VM_CAP_HALT_EXIT, &tmp); + if (err < 0) { + printf("VM exit on HLT not supported\n"); + exit(1); + } + vm_set_capability(ctx, BSP, VM_CAP_HALT_EXIT, 1); + handler[VM_EXITCODE_HLT] = vmexit_hlt; + } + + if (fbsdrun_vmexit_on_pause()) { + /* + * pause exit support required for this mode + */ + err = vm_get_capability(ctx, BSP, VM_CAP_PAUSE_EXIT, &tmp); + if (err < 0) { + printf("SMP mux requested, no pause support\n"); + exit(1); + } + vm_set_capability(ctx, BSP, VM_CAP_PAUSE_EXIT, 1); + handler[VM_EXITCODE_PAUSE] = vmexit_pause; + } + + if (lomem_sz != 0) { + lomem_addr = vm_map_memory(ctx, 0, lomem_sz); + if (lomem_addr == (char *) MAP_FAILED) { + lomem_sz = 0; + } else if (himem_sz != 0) { + himem_addr = vm_map_memory(ctx, 4*GB, himem_sz); + if (himem_addr == (char *) MAP_FAILED) { + lomem_sz = 0; + himem_sz = 0; + } + } + } + + init_inout(); + init_pci(ctx); + + if (gdb_port != 0) + init_dbgport(gdb_port); + + error = vm_get_register(ctx, BSP, VM_REG_GUEST_RIP, &rip); + assert(error == 0); + + if (inject_bkpt) { + error = vm_inject_event(ctx, BSP, VM_HW_EXCEPTION, IDT_BP); + assert(error == 0); + } + + /* + * build the guest tables, MP etc. + */ + vm_build_tables(ctx, guest_ncpus, oem_tbl_start, oem_tbl_size); + + /* + * Add CPU 0 + */ + fbsdrun_addcpu(ctx, BSP, rip); + + /* + * Head off to the main event dispatch loop + */ + mevent_dispatch(); + + exit(1); +} diff --git a/usr.sbin/bhyve/fbsdrun.h b/usr.sbin/bhyve/fbsdrun.h new file mode 100644 index 00000000000..81061222a1a --- /dev/null +++ b/usr.sbin/bhyve/fbsdrun.h @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _FBSDRUN_H_ +#define _FBSDRUN_H_ + +#ifndef CTASSERT /* Allow lint to override */ +#define CTASSERT(x) _CTASSERT(x, __LINE__) +#define _CTASSERT(x, y) __CTASSERT(x, y) +#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] +#endif + +struct vmctx; +extern int guest_hz; +extern int guest_tslice; +extern int guest_ncpus; +extern char *vmname; + +extern u_long lomem_sz, himem_sz; + +void *paddr_guest2host(uintptr_t); + +void fbsdrun_addcpu(struct vmctx *ctx, int cpu, uint64_t rip); +void fbsdrun_add_oemtbl(void *tbl, int tblsz); +int fbsdrun_muxed(void); +int fbsdrun_vmexit_on_hlt(void); +int fbsdrun_vmexit_on_pause(void); +#endif diff --git a/usr.sbin/bhyve/inout.c b/usr.sbin/bhyve/inout.c new file mode 100644 index 00000000000..84445b1f0a9 --- /dev/null +++ b/usr.sbin/bhyve/inout.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include + +#include "inout.h" + +SET_DECLARE(inout_port_set, struct inout_port); + +#define MAX_IOPORTS (1 << 16) + +static struct { + const char *name; + int flags; + inout_func_t handler; + void *arg; +} inout_handlers[MAX_IOPORTS]; + +int +emulate_inout(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax) +{ + int flags; + inout_func_t handler; + void *arg; + + assert(port < MAX_IOPORTS); + + if ((handler = inout_handlers[port].handler) == NULL) + return (-1); + + flags = inout_handlers[port].flags; + arg = inout_handlers[port].arg; + + if ((in && (flags & IOPORT_F_IN)) || (!in && (flags & IOPORT_F_OUT))) + return ((*handler)(ctx, vcpu, in, port, bytes, eax, arg)); + else + return (-1); +} + +void +init_inout(void) +{ + struct inout_port **iopp, *iop; + + SET_FOREACH(iopp, inout_port_set) { + iop = *iopp; + assert(iop->port < MAX_IOPORTS); + inout_handlers[iop->port].name = iop->name; + inout_handlers[iop->port].flags = iop->flags; + inout_handlers[iop->port].handler = iop->handler; + inout_handlers[iop->port].arg = NULL; + } +} + +int +register_inout(struct inout_port *iop) +{ + assert(iop->port < MAX_IOPORTS); + inout_handlers[iop->port].name = iop->name; + inout_handlers[iop->port].flags = iop->flags; + inout_handlers[iop->port].handler = iop->handler; + inout_handlers[iop->port].arg = iop->arg; + + return (0); +} diff --git a/usr.sbin/bhyve/inout.h b/usr.sbin/bhyve/inout.h new file mode 100644 index 00000000000..7b8a4a6edd3 --- /dev/null +++ b/usr.sbin/bhyve/inout.h @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _INOUT_H_ +#define _INOUT_H_ + +#include + +struct vmctx; + +typedef int (*inout_func_t)(struct vmctx *ctx, int vcpu, int in, int port, + int bytes, uint32_t *eax, void *arg); + +struct inout_port { + const char *name; + int port; + int flags; + inout_func_t handler; + void *arg; +}; +#define IOPORT_F_IN 0x1 +#define IOPORT_F_OUT 0x2 +#define IOPORT_F_INOUT 0x3 + +#define INOUT_PORT(name, port, flags, handler) \ + static struct inout_port __CONCAT(__inout_port, __LINE__) = { \ + #name, \ + (port), \ + (flags), \ + (handler) \ + }; \ + DATA_SET(inout_port_set, __CONCAT(__inout_port, __LINE__)) + +void init_inout(void); +int emulate_inout(struct vmctx *, int vcpu, int in, int port, int bytes, + uint32_t *eax); +int register_inout(struct inout_port *iop); + +#endif /* _INOUT_H_ */ diff --git a/usr.sbin/bhyve/mevent.c b/usr.sbin/bhyve/mevent.c new file mode 100644 index 00000000000..0d3b2872e1b --- /dev/null +++ b/usr.sbin/bhyve/mevent.c @@ -0,0 +1,419 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +/* + * Micro event library for FreeBSD, designed for a single i/o thread + * using kqueue, and having events be persistent by default. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "mevent.h" + +#define MEVENT_MAX 64 + +#define MEV_ENABLE 1 +#define MEV_DISABLE 2 +#define MEV_DEL_PENDING 3 + +static pthread_t mevent_tid; +static int mevent_pipefd[2]; +static pthread_mutex_t mevent_lmutex = PTHREAD_MUTEX_INITIALIZER; + +struct mevent { + void (*me_func)(int, enum ev_type, void *); + int me_fd; + enum ev_type me_type; + void *me_param; + int me_cq; + int me_state; + int me_closefd; + LIST_ENTRY(mevent) me_list; +}; + +static LIST_HEAD(listhead, mevent) global_head, change_head; + +static void +mevent_qlock(void) +{ + pthread_mutex_lock(&mevent_lmutex); +} + +static void +mevent_qunlock(void) +{ + pthread_mutex_unlock(&mevent_lmutex); +} + +static void +mevent_pipe_read(int fd, enum ev_type type, void *param) +{ + char buf[MEVENT_MAX]; + int status; + + /* + * Drain the pipe read side. The fd is non-blocking so this is + * safe to do. + */ + do { + status = read(fd, buf, sizeof(buf)); + } while (status == MEVENT_MAX); +} + +static void +mevent_notify(void) +{ + char c; + + /* + * If calling from outside the i/o thread, write a byte on the + * pipe to force the i/o thread to exit the blocking kevent call. + */ + if (mevent_pipefd[1] != 0 && pthread_self() != mevent_tid) { + write(mevent_pipefd[1], &c, 1); + } +} + +static int +mevent_kq_filter(struct mevent *mevp) +{ + int retval; + + retval = 0; + + if (mevp->me_type == EVF_READ) + retval = EVFILT_READ; + + if (mevp->me_type == EVF_WRITE) + retval = EVFILT_WRITE; + + return (retval); +} + +static int +mevent_kq_flags(struct mevent *mevp) +{ + int ret; + + switch (mevp->me_state) { + case MEV_ENABLE: + ret = EV_ADD; + break; + case MEV_DISABLE: + ret = EV_DISABLE; + break; + case MEV_DEL_PENDING: + ret = EV_DELETE; + break; + } + + return (ret); +} + +static int +mevent_kq_fflags(struct mevent *mevp) +{ + /* XXX nothing yet, perhaps EV_EOF for reads ? */ + return (0); +} + +static int +mevent_build(int mfd, struct kevent *kev) +{ + struct mevent *mevp, *tmpp; + int i; + + i = 0; + + mevent_qlock(); + + LIST_FOREACH_SAFE(mevp, &change_head, me_list, tmpp) { + if (mevp->me_closefd) { + /* + * A close of the file descriptor will remove the + * event + */ + close(mevp->me_fd); + } else { + kev[i].ident = mevp->me_fd; + kev[i].filter = mevent_kq_filter(mevp); + kev[i].flags = mevent_kq_flags(mevp); + kev[i].fflags = mevent_kq_fflags(mevp); + kev[i].data = 0; + kev[i].udata = mevp; + i++; + } + + mevp->me_cq = 0; + LIST_REMOVE(mevp, me_list); + + if (mevp->me_state == MEV_DEL_PENDING) { + free(mevp); + } else { + LIST_INSERT_HEAD(&global_head, mevp, me_list); + } + + assert(i < MEVENT_MAX); + } + + mevent_qunlock(); + + return (i); +} + +static void +mevent_handle(struct kevent *kev, int numev) +{ + struct mevent *mevp; + int i; + + for (i = 0; i < numev; i++) { + mevp = kev[i].udata; + + /* XXX check for EV_ERROR ? */ + + (*mevp->me_func)(mevp->me_fd, mevp->me_type, mevp->me_param); + } +} + +struct mevent * +mevent_add(int fd, enum ev_type type, + void (*func)(int, enum ev_type, void *), void *param) +{ + struct mevent *lp, *mevp; + + if (fd < 0 || func == NULL) { + return (NULL); + } + + mevp = NULL; + + mevent_qlock(); + + /* + * Verify that the fd/type tuple is not present in any list + */ + LIST_FOREACH(lp, &global_head, me_list) { + if (lp->me_fd == fd && lp->me_type == type) { + goto exit; + } + } + + LIST_FOREACH(lp, &change_head, me_list) { + if (lp->me_fd == fd && lp->me_type == type) { + goto exit; + } + } + + /* + * Allocate an entry, populate it, and add it to the change list. + */ + mevp = malloc(sizeof(struct mevent)); + if (mevp == NULL) { + goto exit; + } + + memset(mevp, 0, sizeof(struct mevent)); + mevp->me_fd = fd; + mevp->me_type = type; + mevp->me_func = func; + mevp->me_param = param; + + LIST_INSERT_HEAD(&change_head, mevp, me_list); + mevp->me_cq = 1; + mevp->me_state = MEV_ENABLE; + mevent_notify(); + +exit: + mevent_qunlock(); + + return (mevp); +} + +static int +mevent_update(struct mevent *evp, int newstate) +{ + /* + * It's not possible to enable/disable a deleted event + */ + if (evp->me_state == MEV_DEL_PENDING) + return (EINVAL); + + /* + * No update needed if state isn't changing + */ + if (evp->me_state == newstate) + return (0); + + mevent_qlock(); + + evp->me_state = newstate; + + /* + * Place the entry onto the changed list if not already there. + */ + if (evp->me_cq == 0) { + evp->me_cq = 1; + LIST_REMOVE(evp, me_list); + LIST_INSERT_HEAD(&change_head, evp, me_list); + mevent_notify(); + } + + mevent_qunlock(); + + return (0); +} + +int +mevent_enable(struct mevent *evp) +{ + + return (mevent_update(evp, MEV_ENABLE)); +} + +int +mevent_disable(struct mevent *evp) +{ + + return (mevent_update(evp, MEV_DISABLE)); +} + +static int +mevent_delete_event(struct mevent *evp, int closefd) +{ + mevent_qlock(); + + /* + * Place the entry onto the changed list if not already there, and + * mark as to be deleted. + */ + if (evp->me_cq == 0) { + evp->me_cq = 1; + LIST_REMOVE(evp, me_list); + LIST_INSERT_HEAD(&change_head, evp, me_list); + mevent_notify(); + } + evp->me_state = MEV_DEL_PENDING; + + if (closefd) + evp->me_closefd = 1; + + mevent_qunlock(); + + return (0); +} + +int +mevent_delete(struct mevent *evp) +{ + + return (mevent_delete_event(evp, 0)); +} + +int +mevent_delete_close(struct mevent *evp) +{ + + return (mevent_delete_event(evp, 1)); +} + +void +mevent_dispatch(void) +{ + struct kevent changelist[MEVENT_MAX]; + struct kevent eventlist[MEVENT_MAX]; + struct mevent *pipev; + int mfd; + int numev; + int ret; + + mevent_tid = pthread_self(); + + mfd = kqueue(); + assert(mfd > 0); + + /* + * Open the pipe that will be used for other threads to force + * the blocking kqueue call to exit by writing to it. Set the + * descriptor to non-blocking. + */ + ret = pipe(mevent_pipefd); + if (ret < 0) { + perror("pipe"); + exit(0); + } + + /* + * Add internal event handler for the pipe write fd + */ + pipev = mevent_add(mevent_pipefd[0], EVF_READ, mevent_pipe_read, NULL); + assert(pipev != NULL); + + for (;;) { + /* + * Build changelist if required. + * XXX the changelist can be put into the blocking call + * to eliminate the extra syscall. Currently better for + * debug. + */ + numev = mevent_build(mfd, changelist); + if (numev) { + ret = kevent(mfd, changelist, numev, NULL, 0, NULL); + if (ret == -1) { + perror("Error return from kevent change"); + } + } + + /* + * Block awaiting events + */ + ret = kevent(mfd, NULL, 0, eventlist, MEVENT_MAX, NULL); + if (ret == -1) { + perror("Error return from kevent monitor"); + } + + /* + * Handle reported events + */ + mevent_handle(eventlist, ret); + } +} diff --git a/usr.sbin/bhyve/mevent.h b/usr.sbin/bhyve/mevent.h new file mode 100644 index 00000000000..32a9d74ab56 --- /dev/null +++ b/usr.sbin/bhyve/mevent.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _MEVENT_H_ +#define _MEVENT_H_ + +enum ev_type { + EVF_READ, + EVF_WRITE +}; + +struct mevent; + +struct mevent *mevent_add(int fd, enum ev_type type, + void (*func)(int, enum ev_type, void *), + void *param); +int mevent_enable(struct mevent *evp); +int mevent_disable(struct mevent *evp); +int mevent_delete(struct mevent *evp); +int mevent_delete_close(struct mevent *evp); + +void mevent_dispatch(void); + +#endif /* _MEVENT_H_ */ diff --git a/usr.sbin/bhyve/mevent_test.c b/usr.sbin/bhyve/mevent_test.c new file mode 100644 index 00000000000..c72a4971818 --- /dev/null +++ b/usr.sbin/bhyve/mevent_test.c @@ -0,0 +1,180 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +/* + * Test program for the micro event library. Set up a simple TCP echo + * service. + * + * cc mevent_test.c mevent.c -lpthread + */ + +#include +#include +#include + +#include +#include +#include + +#include "mevent.h" + +#define TEST_PORT 4321 + +static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t accept_condvar = PTHREAD_COND_INITIALIZER; + +#define MEVENT_ECHO + +#ifdef MEVENT_ECHO +struct esync { + pthread_mutex_t e_mt; + pthread_cond_t e_cond; +}; + +static void +echoer_callback(int fd, enum ev_type type, void *param) +{ + struct esync *sync = param; + + pthread_mutex_lock(&sync->e_mt); + pthread_cond_signal(&sync->e_cond); + pthread_mutex_unlock(&sync->e_mt); +} + +static void * +echoer(void *param) +{ + struct esync sync; + struct mevent *mev; + char buf[128]; + int fd = (int)(uintptr_t) param; + int len; + + pthread_mutex_init(&sync.e_mt, NULL); + pthread_cond_init(&sync.e_cond, NULL); + + pthread_mutex_lock(&sync.e_mt); + + mev = mevent_add(fd, EVF_READ, echoer_callback, &sync); + if (mev == NULL) { + printf("Could not allocate echoer event\n"); + exit(1); + } + + while (!pthread_cond_wait(&sync.e_cond, &sync.e_mt)) { + len = read(fd, buf, sizeof(buf)); + if (len > 0) { + write(fd, buf, len); + write(0, buf, len); + } else { + break; + } + } + + mevent_delete_close(mev); + + pthread_mutex_unlock(&sync.e_mt); + pthread_mutex_destroy(&sync.e_mt); + pthread_cond_destroy(&sync.e_cond); +} + +#else + +static void * +echoer(void *param) +{ + char buf[128]; + int fd = (int)(uintptr_t) param; + int len; + + while ((len = read(fd, buf, sizeof(buf))) > 0) { + write(1, buf, len); + } +} +#endif /* MEVENT_ECHO */ + +static void +acceptor_callback(int fd, enum ev_type type, void *param) +{ + pthread_mutex_lock(&accept_mutex); + pthread_cond_signal(&accept_condvar); + pthread_mutex_unlock(&accept_mutex); +} + +static void * +acceptor(void *param) +{ + struct sockaddr_in sin; + pthread_t tid; + int news; + int s; + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + exit(1); + } + + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(TEST_PORT); + + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + perror("bind"); + exit(1); + } + + if (listen(s, 1) < 0) { + perror("listen"); + exit(1); + } + + (void) mevent_add(s, EVF_READ, acceptor_callback, NULL); + + pthread_mutex_lock(&accept_mutex); + + while (!pthread_cond_wait(&accept_condvar, &accept_mutex)) { + news = accept(s, NULL, NULL); + if (news < 0) { + perror("accept error"); + } else { + printf("incoming connection, spawning thread\n"); + pthread_create(&tid, NULL, echoer, + (void *)(uintptr_t)news); + } + } +} + +main() +{ + pthread_t tid; + + pthread_create(&tid, NULL, acceptor, NULL); + + mevent_dispatch(); +} diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c new file mode 100644 index 00000000000..273c6a2c78c --- /dev/null +++ b/usr.sbin/bhyve/pci_emul.c @@ -0,0 +1,976 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "fbsdrun.h" +#include "inout.h" +#include "pci_emul.h" + +#define CONF1_ADDR_PORT 0x0cf8 +#define CONF1_DATA_PORT 0x0cfc + +#define CFGWRITE(pi,off,val,b) \ +do { \ + if ((b) == 1) { \ + pci_set_cfgdata8((pi),(off),(val)); \ + } else if ((b) == 2) { \ + pci_set_cfgdata16((pi),(off),(val)); \ + } else { \ + pci_set_cfgdata32((pi),(off),(val)); \ + } \ +} while (0) + +#define MAXSLOTS 32 + +static struct slotinfo { + char *si_name; + char *si_param; + struct pci_devinst *si_devi; + int si_titled; + int si_pslot; + char si_prefix; + char si_suffix; +} pci_slotinfo[MAXSLOTS]; + +/* + * NetApp specific: + * struct used to build an in-core OEM table to supply device names + * to driver instances + */ +static struct mptable_pci_devnames { +#define MPT_HDR_BASE 0 +#define MPT_HDR_NAME 2 + uint16_t md_hdrtype; + uint16_t md_entries; + uint16_t md_cksum; + uint16_t md_pad; +#define MPT_NTAP_SIG \ + ((uint32_t)(('P' << 24) | ('A' << 16) | ('T' << 8) | 'N')) + uint32_t md_sig; + uint32_t md_rsvd; + struct mptable_pci_slotinfo { + uint16_t mds_type; + uint16_t mds_phys_slot; + uint8_t mds_bus; + uint8_t mds_slot; + uint8_t mds_func; + uint8_t mds_pad; + uint16_t mds_vid; + uint16_t mds_did; + uint8_t mds_suffix[4]; + uint8_t mds_prefix[4]; + uint32_t mds_rsvd[3]; + } md_slotinfo[MAXSLOTS]; +} pci_devnames; + +SET_DECLARE(pci_devemu_set, struct pci_devemu); + +static uint64_t pci_emul_iobase; +static uint64_t pci_emul_membase32; +static uint64_t pci_emul_membase64; + +#define PCI_EMUL_IOBASE 0x2000 +#define PCI_EMUL_IOLIMIT 0x10000 + +#define PCI_EMUL_MEMBASE32 (lomem_sz) +#define PCI_EMUL_MEMLIMIT32 0xE0000000 /* 3.5GB */ + +#define PCI_EMUL_MEMBASE64 0xD000000000UL +#define PCI_EMUL_MEMLIMIT64 0xFD00000000UL + +static int pci_emul_devices; +static int devname_elems; + +/* + * I/O access + */ + +/* + * Slot options are in the form: + * + * ,[,] + * + * slot is 0..31 + * emul is a string describing the type of PCI device e.g. virtio-net + * config is an optional string, depending on the device, that can be + * used for configuration. + * Examples are: + * 1,virtio-net,tap0 + * 3,dummy + */ +static void +pci_parse_slot_usage(char *aopt) +{ + printf("Invalid PCI slot info field \"%s\"\n", aopt); + free(aopt); +} + +void +pci_parse_slot(char *opt) +{ + char *slot, *emul, *config; + char *str, *cpy; + int snum; + + str = cpy = strdup(opt); + config = NULL; + + slot = strsep(&str, ","); + emul = strsep(&str, ","); + if (str != NULL) { + config = strsep(&str, ","); + } + + if (emul == NULL) { + pci_parse_slot_usage(cpy); + return; + } + + snum = 255; + snum = atoi(slot); + if (snum < 0 || snum >= MAXSLOTS) { + pci_parse_slot_usage(cpy); + } else { + pci_slotinfo[snum].si_name = emul; + pci_slotinfo[snum].si_param = config; + } +} + + +/* + * + * PCI MPTable names are of the form: + * + * ,[prefix] + * + * .. with an alphabetic char, a 1 or 2-digit string, + * and a single char. + * + * Examples: + * 1,e0c + * 4,e0P + * 6,43a + * 7,0f + * 10,1 + * 12,e0M + * 2,12a + * + * Note that this is NetApp-specific, but is ignored on other o/s's. + */ +static void +pci_parse_name_usage(char *aopt) +{ + printf("Invalid PCI slot name field \"%s\"\n", aopt); +} + +void +pci_parse_name(char *opt) +{ + char csnum[4]; + char *namestr; + char *slotend; + char prefix, suffix; + int i; + int pslot; + int snum; + + pslot = -1; + prefix = suffix = 0; + slotend = strchr(opt, ','); + + /* + * A comma must be present, and can't be the first character + * or no slot would be present. Also, the slot number can't be + * more than 2 characters. + */ + if (slotend == NULL || slotend == opt || (slotend - opt > 2)) { + pci_parse_name_usage(opt); + return; + } + + for (i = 0; i < (slotend - opt); i++) { + csnum[i] = opt[i]; + } + csnum[i] = '\0'; + + snum = 255; + snum = atoi(csnum); + if (snum < 0 || snum >= MAXSLOTS) { + pci_parse_name_usage(opt); + return; + } + + namestr = slotend + 1; + + if (strlen(namestr) > 3) { + pci_parse_name_usage(opt); + return; + } + + if (isalpha(*namestr)) { + prefix = *namestr++; + } + + if (!isdigit(*namestr)) { + pci_parse_name_usage(opt); + } else { + pslot = *namestr++ - '0'; + if (isnumber(*namestr)) { + pslot = 10*pslot + *namestr++ - '0'; + + } + if (isalpha(*namestr) && *(namestr + 1) == 0) { + suffix = *namestr; + pci_slotinfo[snum].si_titled = 1; + pci_slotinfo[snum].si_pslot = pslot; + pci_slotinfo[snum].si_prefix = prefix; + pci_slotinfo[snum].si_suffix = suffix; + + } else { + pci_parse_name_usage(opt); + } + } +} + +static void +pci_add_mptable_name(struct slotinfo *si) +{ + struct mptable_pci_slotinfo *ms; + + /* + * If naming information has been supplied for this slot, populate + * the next available mptable OEM entry + */ + if (si->si_titled) { + ms = &pci_devnames.md_slotinfo[devname_elems]; + + ms->mds_type = MPT_HDR_NAME; + ms->mds_phys_slot = si->si_pslot; + ms->mds_bus = si->si_devi->pi_bus; + ms->mds_slot = si->si_devi->pi_slot; + ms->mds_func = si->si_devi->pi_func; + ms->mds_vid = pci_get_cfgdata16(si->si_devi, PCIR_VENDOR); + ms->mds_did = pci_get_cfgdata16(si->si_devi, PCIR_DEVICE); + ms->mds_suffix[0] = si->si_suffix; + ms->mds_prefix[0] = si->si_prefix; + + devname_elems++; + } +} + +static void +pci_finish_mptable_names(void) +{ + int size; + + if (devname_elems) { + pci_devnames.md_hdrtype = MPT_HDR_BASE; + pci_devnames.md_entries = devname_elems; + pci_devnames.md_cksum = 0; /* XXX */ + pci_devnames.md_sig = MPT_NTAP_SIG; + + size = (uintptr_t)&pci_devnames.md_slotinfo[devname_elems] - + (uintptr_t)&pci_devnames; + + fbsdrun_add_oemtbl(&pci_devnames, size); + } +} + +static int +pci_emul_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + struct pci_devinst *pdi = arg; + struct pci_devemu *pe = pdi->pi_d; + int offset, i; + + for (i = 0; i <= PCI_BARMAX; i++) { + if (pdi->pi_bar[i].type == PCIBAR_IO && + port >= pdi->pi_bar[i].addr && + port + bytes <= pdi->pi_bar[i].addr + pdi->pi_bar[i].size) { + offset = port - pdi->pi_bar[i].addr; + if (in) + *eax = (*pe->pe_ior)(pdi, i, offset, bytes); + else + (*pe->pe_iow)(pdi, i, offset, bytes, *eax); + return (0); + } + } + return (-1); +} + +static int +pci_emul_alloc_resource(uint64_t *baseptr, uint64_t limit, uint64_t size, + uint64_t *addr) +{ + uint64_t base; + + assert((size & (size - 1)) == 0); /* must be a power of 2 */ + + base = roundup2(*baseptr, size); + + if (base + size <= limit) { + *addr = base; + *baseptr = base + size; + return (0); + } else + return (-1); +} + +int +pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, uint64_t hostbase, + enum pcibar_type type, uint64_t size) +{ + int i, error; + uint64_t *baseptr, limit, addr, mask, lobits, bar; + struct inout_port iop; + + assert(idx >= 0 && idx <= PCI_BARMAX); + + if ((size & (size - 1)) != 0) + size = 1UL << flsl(size); /* round up to a power of 2 */ + + switch (type) { + case PCIBAR_NONE: + baseptr = NULL; + addr = mask = lobits = 0; + break; + case PCIBAR_IO: + baseptr = &pci_emul_iobase; + limit = PCI_EMUL_IOLIMIT; + mask = PCIM_BAR_IO_BASE; + lobits = PCIM_BAR_IO_SPACE; + break; + case PCIBAR_MEM64: + /* + * XXX + * Some drivers do not work well if the 64-bit BAR is allocated + * above 4GB. Allow for this by allocating small requests under + * 4GB unless then allocation size is larger than some arbitrary + * number (32MB currently). + */ + if (size > 32 * 1024 * 1024) { + /* + * XXX special case for device requiring peer-peer DMA + */ + if (size == 0x100000000UL) + baseptr = &hostbase; + else + baseptr = &pci_emul_membase64; + limit = PCI_EMUL_MEMLIMIT64; + mask = PCIM_BAR_MEM_BASE; + lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | + PCIM_BAR_MEM_PREFETCH; + break; + } + /* fallthrough */ + case PCIBAR_MEM32: + baseptr = &pci_emul_membase32; + limit = PCI_EMUL_MEMLIMIT32; + mask = PCIM_BAR_MEM_BASE; + lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32; + break; + default: + printf("pci_emul_alloc_base: invalid bar type %d\n", type); + assert(0); + } + + if (baseptr != NULL) { + error = pci_emul_alloc_resource(baseptr, limit, size, &addr); + if (error != 0) + return (error); + } + + pdi->pi_bar[idx].type = type; + pdi->pi_bar[idx].addr = addr; + pdi->pi_bar[idx].size = size; + + /* Initialize the BAR register in config space */ + bar = (addr & mask) | lobits; + pci_set_cfgdata32(pdi, PCIR_BAR(idx), bar); + + if (type == PCIBAR_MEM64) { + assert(idx + 1 <= PCI_BARMAX); + pdi->pi_bar[idx + 1].type = PCIBAR_MEMHI64; + pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32); + } + + /* add a handler to intercept accesses to the I/O bar */ + if (type == PCIBAR_IO) { + iop.name = pdi->pi_name; + iop.flags = IOPORT_F_INOUT; + iop.handler = pci_emul_handler; + iop.arg = pdi; + + for (i = 0; i < size; i++) { + iop.port = addr + i; + register_inout(&iop); + } + } + + return (0); +} + +#define CAP_START_OFFSET 0x40 +static int +pci_emul_add_capability(struct pci_devinst *pi, u_char *capdata, int caplen) +{ + int i, capoff, capid, reallen; + uint16_t sts; + + static u_char endofcap[4] = { + PCIY_RESERVED, 0, 0, 0 + }; + + assert(caplen > 0 && capdata[0] != PCIY_RESERVED); + + reallen = roundup2(caplen, 4); /* dword aligned */ + + sts = pci_get_cfgdata16(pi, PCIR_STATUS); + if ((sts & PCIM_STATUS_CAPPRESENT) == 0) { + capoff = CAP_START_OFFSET; + pci_set_cfgdata8(pi, PCIR_CAP_PTR, capoff); + pci_set_cfgdata16(pi, PCIR_STATUS, sts|PCIM_STATUS_CAPPRESENT); + } else { + capoff = pci_get_cfgdata8(pi, PCIR_CAP_PTR); + while (1) { + assert((capoff & 0x3) == 0); + capid = pci_get_cfgdata8(pi, capoff); + if (capid == PCIY_RESERVED) + break; + capoff = pci_get_cfgdata8(pi, capoff + 1); + } + } + + /* Check if we have enough space */ + if (capoff + reallen + sizeof(endofcap) > PCI_REGMAX + 1) + return (-1); + + /* Copy the capability */ + for (i = 0; i < caplen; i++) + pci_set_cfgdata8(pi, capoff + i, capdata[i]); + + /* Set the next capability pointer */ + pci_set_cfgdata8(pi, capoff + 1, capoff + reallen); + + /* Copy of the reserved capability which serves as the end marker */ + for (i = 0; i < sizeof(endofcap); i++) + pci_set_cfgdata8(pi, capoff + reallen + i, endofcap[i]); + + return (0); +} + +static struct pci_devemu * +pci_emul_finddev(char *name) +{ + struct pci_devemu **pdpp, *pdp; + + SET_FOREACH(pdpp, pci_devemu_set) { + pdp = *pdpp; + if (!strcmp(pdp->pe_emu, name)) { + return (pdp); + } + } + + return (NULL); +} + +static void +pci_emul_init(struct vmctx *ctx, struct pci_devemu *pde, int slot, char *params) +{ + struct pci_devinst *pdi; + pdi = malloc(sizeof(struct pci_devinst)); + bzero(pdi, sizeof(*pdi)); + + pdi->pi_vmctx = ctx; + pdi->pi_bus = 0; + pdi->pi_slot = slot; + pdi->pi_func = 0; + pdi->pi_d = pde; + snprintf(pdi->pi_name, PI_NAMESZ, "%s-pci-%d", pde->pe_emu, slot); + + /* Disable legacy interrupts */ + pci_set_cfgdata8(pdi, PCIR_INTLINE, 255); + pci_set_cfgdata8(pdi, PCIR_INTPIN, 0); + + pci_set_cfgdata8(pdi, PCIR_COMMAND, + PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); + + if ((*pde->pe_init)(ctx, pdi, params) != 0) { + free(pdi); + } else { + pci_emul_devices++; + pci_slotinfo[slot].si_devi = pdi; + } +} + +void +pci_populate_msicap(struct msicap *msicap, int msgnum, int nextptr) +{ + int mmc; + + CTASSERT(sizeof(struct msicap) == 14); + + /* Number of msi messages must be a power of 2 between 1 and 32 */ + assert((msgnum & (msgnum - 1)) == 0 && msgnum >= 1 && msgnum <= 32); + mmc = ffs(msgnum) - 1; + + bzero(msicap, sizeof(struct msicap)); + msicap->capid = PCIY_MSI; + msicap->nextptr = nextptr; + msicap->msgctrl = PCIM_MSICTRL_64BIT | (mmc << 1); +} + +int +pci_emul_add_msicap(struct pci_devinst *pi, int msgnum) +{ + struct msicap msicap; + + pci_populate_msicap(&msicap, msgnum, 0); + + return (pci_emul_add_capability(pi, (u_char *)&msicap, sizeof(msicap))); +} + +void +msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, + int bytes, uint32_t val) +{ + uint16_t msgctrl, rwmask, msgdata, mme; + uint32_t addrlo; + + /* + * If guest is writing to the message control register make sure + * we do not overwrite read-only fields. + */ + if ((offset - capoff) == 2 && bytes == 2) { + rwmask = PCIM_MSICTRL_MME_MASK | PCIM_MSICTRL_MSI_ENABLE; + msgctrl = pci_get_cfgdata16(pi, offset); + msgctrl &= ~rwmask; + msgctrl |= val & rwmask; + val = msgctrl; + + addrlo = pci_get_cfgdata32(pi, capoff + 4); + if (msgctrl & PCIM_MSICTRL_64BIT) + msgdata = pci_get_cfgdata16(pi, capoff + 12); + else + msgdata = pci_get_cfgdata16(pi, capoff + 8); + + /* + * XXX check delivery mode, destination mode etc + */ + mme = msgctrl & PCIM_MSICTRL_MME_MASK; + pi->pi_msi.enabled = msgctrl & PCIM_MSICTRL_MSI_ENABLE ? 1 : 0; + if (pi->pi_msi.enabled) { + pi->pi_msi.cpu = (addrlo >> 12) & 0xff; + pi->pi_msi.vector = msgdata & 0xff; + pi->pi_msi.msgnum = 1 << (mme >> 4); + } else { + pi->pi_msi.cpu = 0; + pi->pi_msi.vector = 0; + pi->pi_msi.msgnum = 0; + } + } + + CFGWRITE(pi, offset, val, bytes); +} + +/* + * This function assumes that 'coff' is in the capabilities region of the + * config space. + */ +static void +pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes, uint32_t val) +{ + int capid; + uint8_t capoff, nextoff; + + /* Do not allow un-aligned writes */ + if ((offset & (bytes - 1)) != 0) + return; + + /* Find the capability that we want to update */ + capoff = CAP_START_OFFSET; + while (1) { + capid = pci_get_cfgdata8(pi, capoff); + if (capid == PCIY_RESERVED) + break; + + nextoff = pci_get_cfgdata8(pi, capoff + 1); + if (offset >= capoff && offset < nextoff) + break; + + capoff = nextoff; + } + assert(offset >= capoff); + + /* + * Capability ID and Next Capability Pointer are readonly + */ + if (offset == capoff || offset == capoff + 1) + return; + + switch (capid) { + case PCIY_MSI: + msicap_cfgwrite(pi, capoff, offset, bytes, val); + break; + default: + break; + } +} + +static int +pci_emul_iscap(struct pci_devinst *pi, int offset) +{ + int found; + uint16_t sts; + uint8_t capid, lastoff; + + found = 0; + sts = pci_get_cfgdata16(pi, PCIR_STATUS); + if ((sts & PCIM_STATUS_CAPPRESENT) != 0) { + lastoff = pci_get_cfgdata8(pi, PCIR_CAP_PTR); + while (1) { + assert((lastoff & 0x3) == 0); + capid = pci_get_cfgdata8(pi, lastoff); + if (capid == PCIY_RESERVED) + break; + lastoff = pci_get_cfgdata8(pi, lastoff + 1); + } + if (offset >= CAP_START_OFFSET && offset <= lastoff) + found = 1; + } + return (found); +} + +void +init_pci(struct vmctx *ctx) +{ + struct pci_devemu *pde; + struct slotinfo *si; + int i; + + pci_emul_iobase = PCI_EMUL_IOBASE; + pci_emul_membase32 = PCI_EMUL_MEMBASE32; + pci_emul_membase64 = PCI_EMUL_MEMBASE64; + + si = pci_slotinfo; + + for (i = 0; i < MAXSLOTS; i++, si++) { + if (si->si_name != NULL) { + pde = pci_emul_finddev(si->si_name); + if (pde != NULL) { + pci_emul_init(ctx, pde, i, si->si_param); + pci_add_mptable_name(si); + } + } + } + pci_finish_mptable_names(); +} + +int +pci_msi_enabled(struct pci_devinst *pi) +{ + return (pi->pi_msi.enabled); +} + +int +pci_msi_msgnum(struct pci_devinst *pi) +{ + if (pi->pi_msi.enabled) + return (pi->pi_msi.msgnum); + else + return (0); +} + +void +pci_generate_msi(struct pci_devinst *pi, int msg) +{ + + if (pci_msi_enabled(pi) && msg < pci_msi_msgnum(pi)) { + vm_lapic_irq(pi->pi_vmctx, + pi->pi_msi.cpu, + pi->pi_msi.vector + msg); + } +} + +static int cfgbus, cfgslot, cfgfunc, cfgoff; + +static int +pci_emul_cfgaddr(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + uint32_t x; + + assert(!in); + + if (bytes != 4) + return (-1); + + x = *eax; + cfgoff = x & PCI_REGMAX; + cfgfunc = (x >> 8) & PCI_FUNCMAX; + cfgslot = (x >> 11) & PCI_SLOTMAX; + cfgbus = (x >> 16) & PCI_BUSMAX; + + return (0); +} +INOUT_PORT(pci_cfgaddr, CONF1_ADDR_PORT, IOPORT_F_OUT, pci_emul_cfgaddr); + +static int +pci_emul_cfgdata(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + struct pci_devinst *pi; + struct pci_devemu *pe; + int coff, idx; + uint64_t mask, bar; + + assert(bytes == 1 || bytes == 2 || bytes == 4); + + pi = pci_slotinfo[cfgslot].si_devi; + coff = cfgoff + (port - CONF1_DATA_PORT); + +#if 0 + printf("pcicfg-%s from 0x%0x of %d bytes (%d/%d/%d)\n\r", + in ? "read" : "write", coff, bytes, cfgbus, cfgslot, cfgfunc); +#endif + + if (pi == NULL || cfgfunc != 0) { + if (in) + *eax = 0xffffffff; + return (0); + } + + pe = pi->pi_d; + + /* + * Config read + */ + if (in) { + /* Let the device emulation override the default handler */ + if (pe->pe_cfgread != NULL && + (*pe->pe_cfgread)(ctx, vcpu, pi, coff, bytes, eax) == 0) + return (0); + + if (bytes == 1) + *eax = pci_get_cfgdata8(pi, coff); + else if (bytes == 2) + *eax = pci_get_cfgdata16(pi, coff); + else + *eax = pci_get_cfgdata32(pi, coff); + } else { + /* Let the device emulation override the default handler */ + if (pe->pe_cfgwrite != NULL && + (*pe->pe_cfgwrite)(ctx, vcpu, pi, coff, bytes, *eax) == 0) + return (0); + + /* + * Special handling for write to BAR registers + */ + if (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) { + /* + * Ignore writes to BAR registers that are not + * 4-byte aligned. + */ + if (bytes != 4 || (coff & 0x3) != 0) + return (0); + idx = (coff - PCIR_BAR(0)) / 4; + switch (pi->pi_bar[idx].type) { + case PCIBAR_NONE: + bar = 0; + break; + case PCIBAR_IO: + mask = ~(pi->pi_bar[idx].size - 1); + mask &= PCIM_BAR_IO_BASE; + bar = (*eax & mask) | PCIM_BAR_IO_SPACE; + break; + case PCIBAR_MEM32: + mask = ~(pi->pi_bar[idx].size - 1); + mask &= PCIM_BAR_MEM_BASE; + bar = *eax & mask; + bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32; + break; + case PCIBAR_MEM64: + mask = ~(pi->pi_bar[idx].size - 1); + mask &= PCIM_BAR_MEM_BASE; + bar = *eax & mask; + bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | + PCIM_BAR_MEM_PREFETCH; + break; + case PCIBAR_MEMHI64: + mask = ~(pi->pi_bar[idx - 1].size - 1); + mask &= PCIM_BAR_MEM_BASE; + bar = ((uint64_t)*eax << 32) & mask; + bar = bar >> 32; + break; + default: + assert(0); + } + pci_set_cfgdata32(pi, coff, bar); + } else if (pci_emul_iscap(pi, coff)) { + pci_emul_capwrite(pi, coff, bytes, *eax); + } else { + CFGWRITE(pi, coff, *eax, bytes); + } + } + + return (0); +} + +INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+0, IOPORT_F_INOUT, pci_emul_cfgdata); +INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+1, IOPORT_F_INOUT, pci_emul_cfgdata); +INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+2, IOPORT_F_INOUT, pci_emul_cfgdata); +INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+3, IOPORT_F_INOUT, pci_emul_cfgdata); + +/* + * I/O ports to configure PCI IRQ routing. We ignore all writes to it. + */ +static int +pci_irq_port_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + assert(in == 0); + return (0); +} +INOUT_PORT(pci_irq, 0xC00, IOPORT_F_OUT, pci_irq_port_handler); +INOUT_PORT(pci_irq, 0xC01, IOPORT_F_OUT, pci_irq_port_handler); + +#define PCI_EMUL_TEST +#ifdef PCI_EMUL_TEST +/* + * Define a dummy test device + */ +#define DREGSZ 20 +struct pci_emul_dsoftc { + uint8_t regs[DREGSZ]; +}; + +#define PCI_EMUL_MSGS 4 + +int +pci_emul_dinit(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + int error; + struct pci_emul_dsoftc *sc; + + sc = malloc(sizeof(struct pci_emul_dsoftc)); + memset(sc, 0, sizeof(struct pci_emul_dsoftc)); + + pi->pi_arg = sc; + + pci_set_cfgdata16(pi, PCIR_DEVICE, 0x0001); + pci_set_cfgdata16(pi, PCIR_VENDOR, 0x10DD); + pci_set_cfgdata8(pi, PCIR_CLASS, 0x02); + + error = pci_emul_alloc_bar(pi, 0, 0, PCIBAR_IO, DREGSZ); + assert(error == 0); + + error = pci_emul_add_msicap(pi, PCI_EMUL_MSGS); + assert(error == 0); + + return (0); +} + +void +pci_emul_diow(struct pci_devinst *pi, int baridx, int offset, int size, + uint32_t value) +{ + int i; + struct pci_emul_dsoftc *sc = pi->pi_arg; + + if (offset + size > DREGSZ) { + printf("diow: too large, offset %d size %d\n", offset, size); + return; + } + + if (size == 1) { + sc->regs[offset] = value & 0xff; + } else if (size == 2) { + *(uint16_t *)&sc->regs[offset] = value & 0xffff; + } else { + *(uint32_t *)&sc->regs[offset] = value; + } + + /* + * Special magic value to generate an interrupt + */ + if (offset == 4 && size == 4 && pci_msi_enabled(pi)) + pci_generate_msi(pi, value % pci_msi_msgnum(pi)); + + if (value == 0xabcdef) { + for (i = 0; i < pci_msi_msgnum(pi); i++) + pci_generate_msi(pi, i); + } +} + +uint32_t +pci_emul_dior(struct pci_devinst *pi, int baridx, int offset, int size) +{ + struct pci_emul_dsoftc *sc = pi->pi_arg; + uint32_t value; + + if (offset + size > DREGSZ) { + printf("dior: too large, offset %d size %d\n", offset, size); + return (0); + } + + if (size == 1) { + value = sc->regs[offset]; + } else if (size == 2) { + value = *(uint16_t *) &sc->regs[offset]; + } else { + value = *(uint32_t *) &sc->regs[offset]; + } + + return (value); +} + +struct pci_devemu pci_dummy = { + .pe_emu = "dummy", + .pe_init = pci_emul_dinit, + .pe_iow = pci_emul_diow, + .pe_ior = pci_emul_dior +}; +PCI_EMUL_SET(pci_dummy); + +#endif /* PCI_EMUL_TEST */ diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h new file mode 100644 index 00000000000..f5f8e228c55 --- /dev/null +++ b/usr.sbin/bhyve/pci_emul.h @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _PCI_EMUL_H_ +#define _PCI_EMUL_H_ + +#include +#include +#include + +#include + +#include + +#define PCI_BARMAX PCIR_MAX_BAR_0 /* BAR registers in a Type 0 header */ +#define PCIY_RESERVED 0x00 + +struct vmctx; +struct pci_devinst; + +struct pci_devemu { + char *pe_emu; /* Name of device emulation */ + + /* instance creation */ + int (*pe_init)(struct vmctx *, struct pci_devinst *, char *opts); + + /* config space read/write callbacks */ + int (*pe_cfgwrite)(struct vmctx *ctx, int vcpu, + struct pci_devinst *pi, int offset, + int bytes, uint32_t val); + int (*pe_cfgread)(struct vmctx *ctx, int vcpu, + struct pci_devinst *pi, int offset, + int bytes, uint32_t *retval); + + /* I/O space read/write callbacks */ + void (*pe_iow)(struct pci_devinst *pi, int baridx, + int offset, int size, uint32_t value); + uint32_t (*pe_ior)(struct pci_devinst *pi, int baridx, + int offset, int size); +}; +#define PCI_EMUL_SET(x) DATA_SET(pci_devemu_set, x); + +enum pcibar_type { + PCIBAR_NONE, + PCIBAR_IO, + PCIBAR_MEM32, + PCIBAR_MEM64, + PCIBAR_MEMHI64 +}; + +struct pcibar { + enum pcibar_type type; /* io or memory */ + uint64_t size; + uint64_t addr; +}; + +#define PI_NAMESZ 40 + +struct pci_devinst { + struct pci_devemu *pi_d; + struct vmctx *pi_vmctx; + uint8_t pi_bus, pi_slot, pi_func; + char pi_name[PI_NAMESZ]; + uint16_t pi_iobase; + int pi_bar_getsize; + + struct { + int enabled; + int cpu; + int vector; + int msgnum; + } pi_msi; + + void *pi_arg; /* devemu-private data */ + + u_char pi_cfgdata[PCI_REGMAX + 1]; + struct pcibar pi_bar[PCI_BARMAX + 1]; +}; + +struct msicap { + uint8_t capid; + uint8_t nextptr; + uint16_t msgctrl; + uint32_t addrlo; + uint32_t addrhi; + uint16_t msgdata; +} __packed; + +void init_pci(struct vmctx *ctx); +void pci_parse_slot(char *opt); +void pci_parse_name(char *opt); +void pci_callback(void); +int pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, uint64_t hostbase, + enum pcibar_type type, uint64_t size); +int pci_emul_add_msicap(struct pci_devinst *pi, int msgnum); +void msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, + int bytes, uint32_t val); + +void pci_generate_msi(struct pci_devinst *pi, int msgnum); +int pci_msi_enabled(struct pci_devinst *pi); +int pci_msi_msgnum(struct pci_devinst *pi); +void pci_populate_msicap(struct msicap *cap, int msgs, int nextptr); + +static __inline void +pci_set_cfgdata8(struct pci_devinst *pi, int offset, uint8_t val) +{ + assert(offset <= PCI_REGMAX); + *(uint8_t *)(pi->pi_cfgdata + offset) = val; +} + +static __inline void +pci_set_cfgdata16(struct pci_devinst *pi, int offset, uint16_t val) +{ + assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0); + *(uint16_t *)(pi->pi_cfgdata + offset) = val; +} + +static __inline void +pci_set_cfgdata32(struct pci_devinst *pi, int offset, uint32_t val) +{ + assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0); + *(uint32_t *)(pi->pi_cfgdata + offset) = val; +} + +static __inline uint8_t +pci_get_cfgdata8(struct pci_devinst *pi, int offset) +{ + assert(offset <= PCI_REGMAX); + return (*(uint8_t *)(pi->pi_cfgdata + offset)); +} + +static __inline uint16_t +pci_get_cfgdata16(struct pci_devinst *pi, int offset) +{ + assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0); + return (*(uint16_t *)(pi->pi_cfgdata + offset)); +} + +static __inline uint32_t +pci_get_cfgdata32(struct pci_devinst *pi, int offset) +{ + assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0); + return (*(uint32_t *)(pi->pi_cfgdata + offset)); +} + +#endif /* _PCI_EMUL_H_ */ diff --git a/usr.sbin/bhyve/pci_hostbridge.c b/usr.sbin/bhyve/pci_hostbridge.c new file mode 100644 index 00000000000..c77762d8f92 --- /dev/null +++ b/usr.sbin/bhyve/pci_hostbridge.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "pci_emul.h" + +static int +pci_hostbridge_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + + /* config space */ + pci_set_cfgdata16(pi, PCIR_VENDOR, 0x1275); /* NetApp */ + pci_set_cfgdata16(pi, PCIR_DEVICE, 0x1275); /* NetApp */ + pci_set_cfgdata8(pi, PCIR_HDRTYPE, PCIM_HDRTYPE_BRIDGE); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_HOST); + + return (0); +} + +struct pci_devemu pci_de_hostbridge = { + .pe_emu = "hostbridge", + .pe_init = pci_hostbridge_init, +}; +PCI_EMUL_SET(pci_de_hostbridge); diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c new file mode 100644 index 00000000000..1c417fd5872 --- /dev/null +++ b/usr.sbin/bhyve/pci_passthru.c @@ -0,0 +1,508 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "pci_emul.h" + +#ifndef _PATH_DEVPCI +#define _PATH_DEVPCI "/dev/pci" +#endif + +#ifndef _PATH_DEVIO +#define _PATH_DEVIO "/dev/io" +#endif + +#define LEGACY_SUPPORT 1 + +static int pcifd = -1; +static int iofd = -1; + +struct passthru_softc { + struct pci_devinst *psc_pi; + struct pcibar psc_bar[PCI_BARMAX + 1]; + struct { + int capoff; + int msgctrl; + int emulated; + } psc_msi; + struct pcisel psc_sel; +}; + +static int +msi_caplen(int msgctrl) +{ + int len; + + len = 10; /* minimum length of msi capability */ + + if (msgctrl & PCIM_MSICTRL_64BIT) + len += 4; + +#if 0 + /* + * Ignore the 'mask' and 'pending' bits in the MSI capability. + * We'll let the guest manipulate them directly. + */ + if (msgctrl & PCIM_MSICTRL_VECTOR) + len += 10; +#endif + + return (len); +} + +static uint32_t +read_config(const struct pcisel *sel, long reg, int width) +{ + struct pci_io pi; + + bzero(&pi, sizeof(pi)); + pi.pi_sel = *sel; + pi.pi_reg = reg; + pi.pi_width = width; + + if (ioctl(pcifd, PCIOCREAD, &pi) < 0) + return (0); /* XXX */ + else + return (pi.pi_data); +} + +static void +write_config(const struct pcisel *sel, long reg, int width, uint32_t data) +{ + struct pci_io pi; + + bzero(&pi, sizeof(pi)); + pi.pi_sel = *sel; + pi.pi_reg = reg; + pi.pi_width = width; + pi.pi_data = data; + + (void)ioctl(pcifd, PCIOCWRITE, &pi); /* XXX */ +} + +#ifdef LEGACY_SUPPORT +static int +passthru_add_msicap(struct pci_devinst *pi, int msgnum, int nextptr) +{ + int capoff, i; + struct msicap msicap; + u_char *capdata; + + pci_populate_msicap(&msicap, msgnum, nextptr); + + /* + * XXX + * Copy the msi capability structure in the last 16 bytes of the + * config space. This is wrong because it could shadow something + * useful to the device. + */ + capoff = 256 - roundup(sizeof(msicap), 4); + capdata = (u_char *)&msicap; + for (i = 0; i < sizeof(msicap); i++) + pci_set_cfgdata8(pi, capoff + i, capdata[i]); + + return (capoff); +} +#endif /* LEGACY_SUPPORT */ + +static int +cfginitmsi(struct passthru_softc *sc) +{ + int ptr, cap, sts, caplen; + uint32_t u32; + struct pcisel sel; + struct pci_devinst *pi; + + pi = sc->psc_pi; + sel = sc->psc_sel; + + /* + * Parse the capabilities and cache the location of the MSI + * capability. + */ + sts = read_config(&sel, PCIR_STATUS, 2); + if (sts & PCIM_STATUS_CAPPRESENT) { + ptr = read_config(&sel, PCIR_CAP_PTR, 1); + while (ptr != 0 && ptr != 0xff) { + cap = read_config(&sel, ptr + PCICAP_ID, 1); + if (cap == PCIY_MSI) { + /* + * Copy the MSI capability into the config + * space of the emulated pci device + */ + sc->psc_msi.capoff = ptr; + sc->psc_msi.msgctrl = read_config(&sel, + ptr + 2, 2); + sc->psc_msi.emulated = 0; + caplen = msi_caplen(sc->psc_msi.msgctrl); + while (caplen > 0) { + u32 = read_config(&sel, ptr, 4); + pci_set_cfgdata32(pi, ptr, u32); + caplen -= 4; + ptr += 4; + } + break; + } + ptr = read_config(&sel, ptr + PCICAP_NEXTPTR, 1); + } + } + +#ifdef LEGACY_SUPPORT + /* + * If the passthrough device does not support MSI then craft a + * MSI capability for it. We link the new MSI capability at the + * head of the list of capabilities. + */ + if ((sts & PCIM_STATUS_CAPPRESENT) != 0 && sc->psc_msi.capoff == 0) { + int origptr, msiptr; + origptr = read_config(&sel, PCIR_CAP_PTR, 1); + msiptr = passthru_add_msicap(pi, 1, origptr); + sc->psc_msi.capoff = msiptr; + sc->psc_msi.msgctrl = pci_get_cfgdata16(pi, msiptr + 2); + sc->psc_msi.emulated = 1; + pci_set_cfgdata8(pi, PCIR_CAP_PTR, msiptr); + } +#endif + + if (sc->psc_msi.capoff == 0) /* MSI or bust */ + return (-1); + else + return (0); +} + +static int +cfginitbar(struct vmctx *ctx, struct passthru_softc *sc) +{ + int i, error; + struct pci_devinst *pi; + struct pci_bar_io bar; + enum pcibar_type bartype; + uint64_t base; + + pi = sc->psc_pi; + + /* + * Initialize BAR registers + */ + for (i = 0; i <= PCI_BARMAX; i++) { + bzero(&bar, sizeof(bar)); + bar.pbi_sel = sc->psc_sel; + bar.pbi_reg = PCIR_BAR(i); + + if (ioctl(pcifd, PCIOCGETBAR, &bar) < 0) + continue; + + if (PCI_BAR_IO(bar.pbi_base)) { + bartype = PCIBAR_IO; + base = bar.pbi_base & PCIM_BAR_IO_BASE; + } else { + switch (bar.pbi_base & PCIM_BAR_MEM_TYPE) { + case PCIM_BAR_MEM_64: + bartype = PCIBAR_MEM64; + break; + default: + bartype = PCIBAR_MEM32; + break; + } + base = bar.pbi_base & PCIM_BAR_MEM_BASE; + } + + /* Cache information about the "real" BAR */ + sc->psc_bar[i].type = bartype; + sc->psc_bar[i].size = bar.pbi_length; + sc->psc_bar[i].addr = base; + + /* Allocate the BAR in the guest I/O or MMIO space */ + error = pci_emul_alloc_bar(pi, i, base, bartype, + bar.pbi_length); + if (error) + return (-1); + + /* + * Map the physical MMIO space in the guest MMIO space + */ + if (bartype != PCIBAR_IO) { + error = vm_map_pptdev_mmio(ctx, sc->psc_sel.pc_bus, + sc->psc_sel.pc_dev, sc->psc_sel.pc_func, + pi->pi_bar[i].addr, pi->pi_bar[i].size, base); + if (error) + return (-1); + } + + /* + * 64-bit BAR takes up two slots so skip the next one. + */ + if (bartype == PCIBAR_MEM64) { + i++; + assert(i <= PCI_BARMAX); + sc->psc_bar[i].type = PCIBAR_MEMHI64; + } + } + return (0); +} + +static int +cfginit(struct vmctx *ctx, struct pci_devinst *pi, int bus, int slot, int func) +{ + int error; + struct passthru_softc *sc; + + error = 1; + sc = pi->pi_arg; + + bzero(&sc->psc_sel, sizeof(struct pcisel)); + sc->psc_sel.pc_bus = bus; + sc->psc_sel.pc_dev = slot; + sc->psc_sel.pc_func = func; + + if (cfginitbar(ctx, sc) != 0) + goto done; + + if (cfginitmsi(sc) != 0) + goto done; + + error = 0; /* success */ +done: + return (error); +} + +static int +passthru_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + int bus, slot, func, error; + struct passthru_softc *sc; + + sc = NULL; + error = 1; + + if (pcifd < 0) { + pcifd = open(_PATH_DEVPCI, O_RDWR, 0); + if (pcifd < 0) + goto done; + } + + if (iofd < 0) { + iofd = open(_PATH_DEVIO, O_RDWR, 0); + if (iofd < 0) + goto done; + } + + if (opts == NULL || sscanf(opts, "%d/%d/%d", &bus, &slot, &func) != 3) + goto done; + + if (vm_assign_pptdev(ctx, bus, slot, func) != 0) + goto done; + + sc = malloc(sizeof(struct passthru_softc)); + memset(sc, 0, sizeof(struct passthru_softc)); + + pi->pi_arg = sc; + sc->psc_pi = pi; + + /* initialize config space */ + if (cfginit(ctx, pi, bus, slot, func) != 0) + goto done; + + error = 0; /* success */ +done: + if (error) { + free(sc); + vm_unassign_pptdev(ctx, bus, slot, func); + } + return (error); +} + +static int +bar_access(int coff) +{ + if (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) + return (1); + else + return (0); +} + +static int +msicap_access(struct passthru_softc *sc, int coff) +{ + int caplen; + + if (sc->psc_msi.capoff == 0) + return (0); + + caplen = msi_caplen(sc->psc_msi.msgctrl); + + if (coff >= sc->psc_msi.capoff && coff < sc->psc_msi.capoff + caplen) + return (1); + else + return (0); +} + +static int +passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int coff, + int bytes, uint32_t *rv) +{ + struct passthru_softc *sc; + + sc = pi->pi_arg; + + /* + * PCI BARs and MSI capability is emulated. + */ + if (bar_access(coff) || msicap_access(sc, coff)) + return (-1); + +#ifdef LEGACY_SUPPORT + /* + * Emulate PCIR_CAP_PTR if this device does not support MSI capability + * natively. + */ + if (sc->psc_msi.emulated) { + if (coff >= PCIR_CAP_PTR && coff < PCIR_CAP_PTR + 4) + return (-1); + } +#endif + + /* Everything else just read from the device's config space */ + *rv = read_config(&sc->psc_sel, coff, bytes); + + return (0); +} + +static int +passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int coff, + int bytes, uint32_t val) +{ + int error; + struct passthru_softc *sc; + + sc = pi->pi_arg; + + /* + * PCI BARs are emulated + */ + if (bar_access(coff)) + return (-1); + + /* + * MSI capability is emulated + */ + if (msicap_access(sc, coff)) { + msicap_cfgwrite(pi, sc->psc_msi.capoff, coff, bytes, val); + + error = vm_setup_msi(ctx, vcpu, sc->psc_sel.pc_bus, + sc->psc_sel.pc_dev, sc->psc_sel.pc_func, pi->pi_msi.cpu, + pi->pi_msi.vector, pi->pi_msi.msgnum); + if (error != 0) { + printf("vm_setup_msi returned error %d\r\n", errno); + exit(1); + } + return (0); + } + +#ifdef LEGACY_SUPPORT + /* + * If this device does not support MSI natively then we cannot let + * the guest disable legacy interrupts from the device. It is the + * legacy interrupt that is triggering the virtual MSI to the guest. + */ + if (sc->psc_msi.emulated && pci_msi_enabled(pi)) { + if (coff == PCIR_COMMAND && bytes == 2) + val &= ~PCIM_CMD_INTxDIS; + } +#endif + + write_config(&sc->psc_sel, coff, bytes, val); + + return (0); +} + +static void +passthru_iow(struct pci_devinst *pi, int baridx, int offset, int size, + uint32_t value) +{ + struct passthru_softc *sc; + struct iodev_pio_req pio; + + sc = pi->pi_arg; + + bzero(&pio, sizeof(struct iodev_pio_req)); + pio.access = IODEV_PIO_WRITE; + pio.port = sc->psc_bar[baridx].addr + offset; + pio.width = size; + pio.val = value; + + (void)ioctl(iofd, IODEV_PIO, &pio); +} + +static uint32_t +passthru_ior(struct pci_devinst *pi, int baridx, int offset, int size) +{ + struct passthru_softc *sc; + struct iodev_pio_req pio; + + sc = pi->pi_arg; + + bzero(&pio, sizeof(struct iodev_pio_req)); + pio.access = IODEV_PIO_READ; + pio.port = sc->psc_bar[baridx].addr + offset; + pio.width = size; + pio.val = 0; + + (void)ioctl(iofd, IODEV_PIO, &pio); + + return (pio.val); +} + +struct pci_devemu passthru = { + .pe_emu = "passthru", + .pe_init = passthru_init, + .pe_cfgwrite = passthru_cfgwrite, + .pe_cfgread = passthru_cfgread, + .pe_iow = passthru_iow, + .pe_ior = passthru_ior, +}; +PCI_EMUL_SET(passthru); diff --git a/usr.sbin/bhyve/pci_virtio_block.c b/usr.sbin/bhyve/pci_virtio_block.c new file mode 100644 index 00000000000..b86e21dff64 --- /dev/null +++ b/usr.sbin/bhyve/pci_virtio_block.c @@ -0,0 +1,502 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fbsdrun.h" +#include "pci_emul.h" +#include "virtio.h" + +#define VTBLK_RINGSZ 64 + +#define VTBLK_CFGSZ 28 + +#define VTBLK_R_CFG VTCFG_R_CFG0 +#define VTBLK_R_CFG_END VTBLK_R_CFG + VTBLK_CFGSZ -1 +#define VTBLK_R_MAX VTBLK_R_CFG_END + +#define VTBLK_REGSZ VTBLK_R_MAX+1 + +#define VTBLK_MAXSEGS 32 + +#define VTBLK_S_OK 0 +#define VTBLK_S_IOERR 1 + +/* + * Host capabilities + */ +#define VTBLK_S_HOSTCAPS \ + ( 0x00000004 | /* host maximum request segments */ \ + 0x10000000 ) /* supports indirect descriptors */ + +struct vring_hqueue { + /* Internal state */ + uint16_t hq_size; + uint16_t hq_cur_aidx; /* trails behind 'avail_idx' */ + + /* Host-context pointers to the queue */ + struct virtio_desc *hq_dtable; + uint16_t *hq_avail_flags; + uint16_t *hq_avail_idx; /* monotonically increasing */ + uint16_t *hq_avail_ring; + + uint16_t *hq_used_flags; + uint16_t *hq_used_idx; /* monotonically increasing */ + struct virtio_used *hq_used_ring; +}; + +/* + * Config space + */ +struct vtblk_config { + uint64_t vbc_capacity; + uint32_t vbc_size_max; + uint32_t vbc_seg_max; + uint16_t vbc_geom_c; + uint8_t vbc_geom_h; + uint8_t vbc_geom_s; + uint32_t vbc_blk_size; + uint32_t vbc_sectors_max; +} __packed; +CTASSERT(sizeof(struct vtblk_config) == VTBLK_CFGSZ); + +/* + * Fixed-size block header + */ +struct virtio_blk_hdr { +#define VBH_OP_READ 0 +#define VBH_OP_WRITE 1 + uint32_t vbh_type; + uint32_t vbh_ioprio; + uint64_t vbh_sector; +} __packed; + +/* + * Debug printf + */ +static int pci_vtblk_debug; +#define DPRINTF(params) if (pci_vtblk_debug) printf params +#define WPRINTF(params) printf params + +/* + * Per-device softc + */ +struct pci_vtblk_softc { + struct pci_devinst *vbsc_pi; + int vbsc_fd; + int vbsc_status; + int vbsc_isr; + int vbsc_lastq; + uint32_t vbsc_features; + uint64_t vbsc_pfn; + struct vring_hqueue vbsc_q; + struct vtblk_config vbsc_cfg; +}; + +/* + * Return the number of available descriptors in the vring taking care + * of the 16-bit index wraparound. + */ +static int +hq_num_avail(struct vring_hqueue *hq) +{ + int ndesc; + + if (*hq->hq_avail_idx >= hq->hq_cur_aidx) + ndesc = *hq->hq_avail_idx - hq->hq_cur_aidx; + else + ndesc = UINT16_MAX - hq->hq_cur_aidx + *hq->hq_avail_idx + 1; + + assert(ndesc >= 0 && ndesc <= hq->hq_size); + + return (ndesc); +} + +static void +pci_vtblk_update_status(struct pci_vtblk_softc *sc, uint32_t value) +{ + if (value == 0) { + DPRINTF(("vtblk: device reset requested !\n")); + } + + sc->vbsc_status = value; +} + +static void +pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vring_hqueue *hq) +{ + struct iovec iov[VTBLK_MAXSEGS]; + struct virtio_blk_hdr *vbh; + struct virtio_desc *vd, *vid; + struct virtio_used *vu; + uint8_t *status; + int i; + int err; + int iolen; + int nsegs; + int uidx, aidx, didx; + int writeop; + off_t offset; + + uidx = *hq->hq_used_idx; + aidx = hq->hq_cur_aidx; + didx = hq->hq_avail_ring[aidx % hq->hq_size]; + assert(didx >= 0 && didx < hq->hq_size); + + vd = &hq->hq_dtable[didx]; + + /* + * Verify that the descriptor is indirect, and obtain + * the pointer to the indirect descriptor. + * There has to be space for at least 3 descriptors + * in the indirect descriptor array: the block header, + * 1 or more data descriptors, and a status byte. + */ + assert(vd->vd_flags & VRING_DESC_F_INDIRECT); + + nsegs = vd->vd_len / sizeof(struct virtio_desc); + assert(nsegs >= 3); + assert(nsegs < VTBLK_MAXSEGS + 2); + + vid = paddr_guest2host(vd->vd_addr); + assert((vid->vd_flags & VRING_DESC_F_INDIRECT) == 0); + + /* + * The first descriptor will be the read-only fixed header + */ + vbh = paddr_guest2host(vid[0].vd_addr); + assert(vid[0].vd_len == sizeof(struct virtio_blk_hdr)); + assert(vid[0].vd_flags & VRING_DESC_F_NEXT); + assert((vid[0].vd_flags & VRING_DESC_F_WRITE) == 0); + + writeop = (vbh->vbh_type == VBH_OP_WRITE); + + offset = vbh->vbh_sector * DEV_BSIZE; + + /* + * Build up the iovec based on the guest's data descriptors + */ + for (i = 1, iolen = 0; i < nsegs - 1; i++) { + iov[i-1].iov_base = paddr_guest2host(vid[i].vd_addr); + iov[i-1].iov_len = vid[i].vd_len; + iolen += vid[i].vd_len; + + assert(vid[i].vd_flags & VRING_DESC_F_NEXT); + assert((vid[i].vd_flags & VRING_DESC_F_INDIRECT) == 0); + + /* + * - write op implies read-only descriptor, + * - read op implies write-only descriptor, + * therefore test the inverse of the descriptor bit + * to the op. + */ + assert(((vid[i].vd_flags & VRING_DESC_F_WRITE) == 0) == + writeop); + } + + /* Lastly, get the address of the status byte */ + status = paddr_guest2host(vid[nsegs - 1].vd_addr); + assert(vid[nsegs - 1].vd_len == 1); + assert((vid[nsegs - 1].vd_flags & VRING_DESC_F_NEXT) == 0); + assert(vid[nsegs - 1].vd_flags & VRING_DESC_F_WRITE); + + DPRINTF(("virtio-block: %s op, %d bytes, %d segs, offset %ld\n\r", + writeop ? "write" : "read", iolen, nsegs - 2, offset)); + + if (writeop){ + err = pwritev(sc->vbsc_fd, iov, nsegs - 2, offset); + } else { + err = preadv(sc->vbsc_fd, iov, nsegs - 2, offset); + } + + *status = err < 0 ? VTBLK_S_IOERR : VTBLK_S_OK; + + /* + * Return the single indirect descriptor back to the host + */ + vu = &hq->hq_used_ring[uidx % hq->hq_size]; + vu->vu_idx = didx; + vu->vu_tlen = 1; + hq->hq_cur_aidx++; + *hq->hq_used_idx += 1; +} + +static void +pci_vtblk_qnotify(struct pci_vtblk_softc *sc) +{ + struct vring_hqueue *hq = &sc->vbsc_q; + int i; + int ndescs; + + /* + * Calculate number of ring entries to process + */ + ndescs = hq_num_avail(hq); + + if (ndescs == 0) + return; + + /* + * Run through all the entries, placing them into iovecs and + * sending when an end-of-packet is found + */ + for (i = 0; i < ndescs; i++) + pci_vtblk_proc(sc, hq); + + /* + * Generate an interrupt if able + */ + if ((*hq->hq_avail_flags & VRING_AVAIL_F_NO_INTERRUPT) == 0 && + sc->vbsc_isr == 0) { + sc->vbsc_isr = 1; + pci_generate_msi(sc->vbsc_pi, 0); + } + +} + +static void +pci_vtblk_ring_init(struct pci_vtblk_softc *sc, uint64_t pfn) +{ + struct vring_hqueue *hq; + + sc->vbsc_pfn = pfn << VRING_PFN; + + /* + * Set up host pointers to the various parts of the + * queue + */ + hq = &sc->vbsc_q; + hq->hq_size = VTBLK_RINGSZ; + + hq->hq_dtable = paddr_guest2host(pfn << VRING_PFN); + hq->hq_avail_flags = (uint16_t *)(hq->hq_dtable + hq->hq_size); + hq->hq_avail_idx = hq->hq_avail_flags + 1; + hq->hq_avail_ring = hq->hq_avail_flags + 2; + hq->hq_used_flags = (uint16_t *)roundup2((uintptr_t)hq->hq_avail_ring, + VRING_ALIGN); + hq->hq_used_idx = hq->hq_used_flags + 1; + hq->hq_used_ring = (struct virtio_used *)(hq->hq_used_flags + 2); + + /* + * Initialize queue indexes + */ + hq->hq_cur_aidx = 0; +} + +static int +pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct stat sbuf; + struct pci_vtblk_softc *sc; + int fd; + + if (opts == NULL) { + printf("virtio-block: backing device required\n"); + return (1); + } + + /* + * Access to guest memory is required. Fail if + * memory not mapped + */ + if (paddr_guest2host(0) == NULL) + return (1); + + /* + * The supplied backing file has to exist + */ + fd = open(opts, O_RDWR); + if (fd < 0) { + perror("Could not open backing file"); + return (1); + } + + if (fstat(fd, &sbuf) < 0) { + perror("Could not stat backing file"); + close(fd); + return (1); + } + + sc = malloc(sizeof(struct pci_vtblk_softc)); + memset(sc, 0, sizeof(struct pci_vtblk_softc)); + + pi->pi_arg = sc; + sc->vbsc_pi = pi; + sc->vbsc_fd = fd; + + /* setup virtio block config space */ + sc->vbsc_cfg.vbc_capacity = sbuf.st_size / DEV_BSIZE; + sc->vbsc_cfg.vbc_seg_max = VTBLK_MAXSEGS; + sc->vbsc_cfg.vbc_blk_size = DEV_BSIZE; + sc->vbsc_cfg.vbc_size_max = 0; /* not negotiated */ + sc->vbsc_cfg.vbc_geom_c = 0; /* no geometry */ + sc->vbsc_cfg.vbc_geom_h = 0; + sc->vbsc_cfg.vbc_geom_s = 0; + sc->vbsc_cfg.vbc_sectors_max = 0; + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_BLOCK); + pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_BLOCK); + pci_emul_alloc_bar(pi, 0, 0, PCIBAR_IO, VTBLK_REGSZ); + pci_emul_add_msicap(pi, 1); + + return (0); +} + +static void +pci_vtblk_write(struct pci_devinst *pi, int baridx, int offset, int size, + uint32_t value) +{ + struct pci_vtblk_softc *sc = pi->pi_arg; + + if (offset + size > VTBLK_REGSZ) { + DPRINTF(("vtblk_write: 2big, offset %d size %d\n", + offset, size)); + return; + } + + switch (offset) { + case VTCFG_R_GUESTCAP: + assert(size == 4); + sc->vbsc_features = value & VTBLK_S_HOSTCAPS; + break; + case VTCFG_R_PFN: + assert(size == 4); + pci_vtblk_ring_init(sc, value); + break; + case VTCFG_R_QSEL: + assert(size == 2); + sc->vbsc_lastq = value; + break; + case VTCFG_R_QNOTIFY: + assert(size == 2); + assert(value == 0); + pci_vtblk_qnotify(sc); + break; + case VTCFG_R_STATUS: + assert(size == 1); + pci_vtblk_update_status(sc, value); + break; + case VTCFG_R_HOSTCAP: + case VTCFG_R_QNUM: + case VTCFG_R_ISR: + case VTBLK_R_CFG ... VTBLK_R_CFG_END: + DPRINTF(("vtblk: write to readonly reg %d\n\r", offset)); + break; + default: + DPRINTF(("vtblk: unknown i/o write offset %d\n\r", offset)); + value = 0; + break; + } +} + +uint32_t +pci_vtblk_read(struct pci_devinst *pi, int baridx, int offset, int size) +{ + struct pci_vtblk_softc *sc = pi->pi_arg; + uint32_t value; + + if (offset + size > VTBLK_REGSZ) { + DPRINTF(("vtblk_read: 2big, offset %d size %d\n", + offset, size)); + return (0); + } + + switch (offset) { + case VTCFG_R_HOSTCAP: + assert(size == 4); + value = VTBLK_S_HOSTCAPS; + break; + case VTCFG_R_GUESTCAP: + assert(size == 4); + value = sc->vbsc_features; /* XXX never read ? */ + break; + case VTCFG_R_PFN: + assert(size == 4); + value = sc->vbsc_pfn >> VRING_PFN; + break; + case VTCFG_R_QNUM: + value = (sc->vbsc_lastq == 0) ? VTBLK_RINGSZ: 0; + break; + case VTCFG_R_QSEL: + assert(size == 2); + value = sc->vbsc_lastq; /* XXX never read ? */ + break; + case VTCFG_R_QNOTIFY: + assert(size == 2); + value = 0; /* XXX never read ? */ + break; + case VTCFG_R_STATUS: + assert(size == 1); + value = sc->vbsc_status; + break; + case VTCFG_R_ISR: + assert(size == 1); + value = sc->vbsc_isr; + sc->vbsc_isr = 0; /* a read clears this flag */ + break; + case VTBLK_R_CFG ... VTBLK_R_CFG_END: + assert(size == 1); + value = *((uint8_t *)&sc->vbsc_cfg + offset - VTBLK_R_CFG); + break; + default: + DPRINTF(("vtblk: unknown i/o read offset %d\n\r", offset)); + value = 0; + break; + } + + return (value); +} + +struct pci_devemu pci_de_vblk = { + .pe_emu = "virtio-blk", + .pe_init = pci_vtblk_init, + .pe_iow = pci_vtblk_write, + .pe_ior = pci_vtblk_read, +}; +PCI_EMUL_SET(pci_de_vblk); diff --git a/usr.sbin/bhyve/pci_virtio_net.c b/usr.sbin/bhyve/pci_virtio_net.c new file mode 100644 index 00000000000..5db1eb7f5a7 --- /dev/null +++ b/usr.sbin/bhyve/pci_virtio_net.c @@ -0,0 +1,739 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fbsdrun.h" +#include "pci_emul.h" +#include "mevent.h" +#include "virtio.h" + +#define VTNET_RINGSZ 256 + +#define VTNET_MAXSEGS 32 + +/* + * PCI config-space register offsets + */ +#define VTNET_R_CFG0 20 +#define VTNET_R_CFG1 21 +#define VTNET_R_CFG2 22 +#define VTNET_R_CFG3 23 +#define VTNET_R_CFG4 24 +#define VTNET_R_CFG5 25 +#define VTNET_R_CFG6 26 +#define VTNET_R_CFG7 27 +#define VTNET_R_MAX 27 + +#define VTNET_REGSZ VTNET_R_MAX+1 + +/* + * Host capabilities + */ +#define VTNET_S_HOSTCAPS \ + ( 0x00000020 | /* host supplies MAC */ \ + 0x00008000 | /* host can merge Rx buffers */ \ + 0x00010000 ) /* config status available */ + +/* + * Queue definitions. + */ +#define VTNET_RXQ 0 +#define VTNET_TXQ 1 +#define VTNET_CTLQ 2 + +#define VTNET_MAXQ 3 + +struct vring_hqueue { + /* Internal state */ + uint16_t hq_size; + uint16_t hq_cur_aidx; /* trails behind 'avail_idx' */ + + /* Host-context pointers to the queue */ + struct virtio_desc *hq_dtable; + uint16_t *hq_avail_flags; + uint16_t *hq_avail_idx; /* monotonically increasing */ + uint16_t *hq_avail_ring; + + uint16_t *hq_used_flags; + uint16_t *hq_used_idx; /* monotonically increasing */ + struct virtio_used *hq_used_ring; +}; + +/* + * Fixed network header size + */ +struct virtio_net_rxhdr { + uint8_t vrh_flags; + uint8_t vrh_gso_type; + uint16_t vrh_hdr_len; + uint16_t vrh_gso_size; + uint16_t vrh_csum_start; + uint16_t vrh_csum_offset; + uint16_t vrh_bufs; +} __packed; + +/* + * Debug printf + */ +static int pci_vtnet_debug; +#define DPRINTF(params) if (pci_vtnet_debug) printf params +#define WPRINTF(params) printf params + +/* + * Per-device softc + */ +struct pci_vtnet_softc { + struct pci_devinst *vsc_pi; + pthread_mutex_t vsc_mtx; + struct mevent *vsc_mevp; + + int vsc_curq; + int vsc_status; + int vsc_isr; + int vsc_tapfd; + int vsc_rx_ready; + int vsc_rxpend; + + uint32_t vsc_features; + uint8_t vsc_macaddr[6]; + + uint64_t vsc_pfn[VTNET_MAXQ]; + struct vring_hqueue vsc_hq[VTNET_MAXQ]; +}; + +/* + * Return the number of available descriptors in the vring taking care + * of the 16-bit index wraparound. + */ +static int +hq_num_avail(struct vring_hqueue *hq) +{ + int ndesc; + + if (*hq->hq_avail_idx >= hq->hq_cur_aidx) + ndesc = *hq->hq_avail_idx - hq->hq_cur_aidx; + else + ndesc = UINT16_MAX - hq->hq_cur_aidx + *hq->hq_avail_idx + 1; + + assert(ndesc >= 0 && ndesc <= hq->hq_size); + + return (ndesc); +} + +static uint16_t +pci_vtnet_qsize(int qnum) +{ + /* XXX no ctl queue currently */ + if (qnum == VTNET_CTLQ) { + return (0); + } + + /* XXX fixed currently. Maybe different for tx/rx/ctl */ + return (VTNET_RINGSZ); +} + +static void +pci_vtnet_update_status(struct pci_vtnet_softc *sc, uint32_t value) +{ + if (value == 0) { + DPRINTF(("vtnet: device reset requested !\n")); + } + + sc->vsc_status = value; +} + +/* + * Called to send a buffer chain out to the tap device + */ +static void +pci_vtnet_tap_tx(struct pci_vtnet_softc *sc, struct iovec *iov, int iovcnt, + int len) +{ + char pad[60]; + + if (sc->vsc_tapfd == -1) + return; + + /* + * If the length is < 60, pad out to that and add the + * extra zero'd segment to the iov. It is guaranteed that + * there is always an extra iov available by the caller. + */ + if (len < 60) { + memset(pad, 0, 60 - len); + iov[iovcnt].iov_base = pad; + iov[iovcnt].iov_len = 60 - len; + iovcnt++; + } + (void) writev(sc->vsc_tapfd, iov, iovcnt); +} + +/* + * Called when there is read activity on the tap file descriptor. + * Each buffer posted by the guest is assumed to be able to contain + * an entire ethernet frame + rx header. + * MP note: the dummybuf is only used for discarding frames, so there + * is no need for it to be per-vtnet or locked. + */ +static uint8_t dummybuf[2048]; + +static void +pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) +{ + struct virtio_desc *vd; + struct virtio_used *vu; + struct vring_hqueue *hq; + struct virtio_net_rxhdr *vrx; + uint8_t *buf; + int i; + int len; + int ndescs; + int didx, uidx, aidx; /* descriptor, avail and used index */ + + /* + * Should never be called without a valid tap fd + */ + assert(sc->vsc_tapfd != -1); + + /* + * But, will be called when the rx ring hasn't yet + * been set up. + */ + if (sc->vsc_rx_ready == 0) { + /* + * Drop the packet and try later. + */ + (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf)); + return; + } + + /* + * Calculate the number of available rx buffers + */ + hq = &sc->vsc_hq[VTNET_RXQ]; + + ndescs = hq_num_avail(hq); + + if (ndescs == 0) { + /* + * Need to wait for host notification to read + */ + if (sc->vsc_rxpend == 0) { + WPRINTF(("vtnet: no rx descriptors !\n")); + sc->vsc_rxpend = 1; + } + + /* + * Drop the packet and try later + */ + (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf)); + return; + } + + aidx = hq->hq_cur_aidx; + uidx = *hq->hq_used_idx; + for (i = 0; i < ndescs; i++) { + /* + * 'aidx' indexes into the an array of descriptor indexes + */ + didx = hq->hq_avail_ring[aidx % hq->hq_size]; + assert(didx >= 0 && didx < hq->hq_size); + + vd = &hq->hq_dtable[didx]; + + /* + * Get a pointer to the rx header, and use the + * data immediately following it for the packet buffer. + */ + vrx = (struct virtio_net_rxhdr *)paddr_guest2host(vd->vd_addr); + buf = (uint8_t *)(vrx + 1); + + len = read(sc->vsc_tapfd, buf, + vd->vd_len - sizeof(struct virtio_net_rxhdr)); + + if (len < 0 && errno == EWOULDBLOCK) { + break; + } + + /* + * The only valid field in the rx packet header is the + * number of buffers, which is always 1 without TSO + * support. + */ + memset(vrx, 0, sizeof(struct virtio_net_rxhdr)); + vrx->vrh_bufs = 1; + + /* + * Write this descriptor into the used ring + */ + vu = &hq->hq_used_ring[uidx % hq->hq_size]; + vu->vu_idx = didx; + vu->vu_tlen = len + sizeof(struct virtio_net_rxhdr); + uidx++; + aidx++; + } + + /* + * Update the used pointer, and signal an interrupt if allowed + */ + *hq->hq_used_idx = uidx; + hq->hq_cur_aidx = aidx; + + if ((*hq->hq_avail_flags & VRING_AVAIL_F_NO_INTERRUPT) == 0) { + sc->vsc_isr |= 1; + pci_generate_msi(sc->vsc_pi, 0); + } +} + +static void +pci_vtnet_tap_callback(int fd, enum ev_type type, void *param) +{ + struct pci_vtnet_softc *sc = param; + + pthread_mutex_lock(&sc->vsc_mtx); + pci_vtnet_tap_rx(sc); + pthread_mutex_unlock(&sc->vsc_mtx); + +} + +static void +pci_vtnet_ping_rxq(struct pci_vtnet_softc *sc) +{ + /* + * A qnotify means that the rx process can now begin + */ + if (sc->vsc_rx_ready == 0) { + sc->vsc_rx_ready = 1; + } + + /* + * If the rx queue was empty, attempt to receive a + * packet that was previously blocked due to no rx bufs + * available + */ + if (sc->vsc_rxpend) { + WPRINTF(("vtnet: rx resumed\n\r")); + sc->vsc_rxpend = 0; + pci_vtnet_tap_rx(sc); + } +} + +static void +pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vring_hqueue *hq) +{ + struct iovec iov[VTNET_MAXSEGS + 1]; + struct virtio_desc *vd; + struct virtio_used *vu; + int i; + int plen; + int tlen; + int uidx, aidx, didx; + + uidx = *hq->hq_used_idx; + aidx = hq->hq_cur_aidx; + didx = hq->hq_avail_ring[aidx % hq->hq_size]; + assert(didx >= 0 && didx < hq->hq_size); + + vd = &hq->hq_dtable[didx]; + + /* + * Run through the chain of descriptors, ignoring the + * first header descriptor. However, include the header + * length in the total length that will be put into the + * used queue. + */ + tlen = vd->vd_len; + vd = &hq->hq_dtable[vd->vd_next]; + + for (i = 0, plen = 0; + i < VTNET_MAXSEGS; + i++, vd = &hq->hq_dtable[vd->vd_next]) { + iov[i].iov_base = paddr_guest2host(vd->vd_addr); + iov[i].iov_len = vd->vd_len; + plen += vd->vd_len; + tlen += vd->vd_len; + + if ((vd->vd_flags & VRING_DESC_F_NEXT) == 0) + break; + } + assert(i < VTNET_MAXSEGS); + + DPRINTF(("virtio: packet send, %d bytes, %d segs\n\r", plen, i + 1)); + pci_vtnet_tap_tx(sc, iov, i + 1, plen); + + /* + * Return this chain back to the host + */ + vu = &hq->hq_used_ring[uidx % hq->hq_size]; + vu->vu_idx = didx; + vu->vu_tlen = tlen; + hq->hq_cur_aidx = aidx + 1; + *hq->hq_used_idx = uidx + 1; + + /* + * Generate an interrupt if able + */ + if ((*hq->hq_avail_flags & VRING_AVAIL_F_NO_INTERRUPT) == 0) { + sc->vsc_isr |= 1; + pci_generate_msi(sc->vsc_pi, 0); + } +} + +static void +pci_vtnet_ping_txq(struct pci_vtnet_softc *sc) +{ + struct vring_hqueue *hq = &sc->vsc_hq[VTNET_TXQ]; + int i; + int ndescs; + + /* + * Calculate number of ring entries to process + */ + ndescs = hq_num_avail(hq); + + if (ndescs == 0) + return; + + /* + * Run through all the entries, placing them into iovecs and + * sending when an end-of-packet is found + */ + for (i = 0; i < ndescs; i++) + pci_vtnet_proctx(sc, hq); +} + +static void +pci_vtnet_ping_ctlq(struct pci_vtnet_softc *sc) +{ + + DPRINTF(("vtnet: control qnotify!\n\r")); +} + +static void +pci_vtnet_ring_init(struct pci_vtnet_softc *sc, uint64_t pfn) +{ + struct vring_hqueue *hq; + int qnum = sc->vsc_curq; + + assert(qnum < VTNET_MAXQ); + + sc->vsc_pfn[qnum] = pfn << VRING_PFN; + + /* + * Set up host pointers to the various parts of the + * queue + */ + hq = &sc->vsc_hq[qnum]; + hq->hq_size = pci_vtnet_qsize(qnum); + + hq->hq_dtable = paddr_guest2host(pfn << VRING_PFN); + hq->hq_avail_flags = (uint16_t *)(hq->hq_dtable + hq->hq_size); + hq->hq_avail_idx = hq->hq_avail_flags + 1; + hq->hq_avail_ring = hq->hq_avail_flags + 2; + hq->hq_used_flags = (uint16_t *)roundup2((uintptr_t)hq->hq_avail_ring, + VRING_ALIGN); + hq->hq_used_idx = hq->hq_used_flags + 1; + hq->hq_used_ring = (struct virtio_used *)(hq->hq_used_flags + 2); + + /* + * Initialize queue indexes + */ + hq->hq_cur_aidx = 0; +} + +static int +pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + MD5_CTX mdctx; + unsigned char digest[16]; + char nstr[80]; + struct pci_vtnet_softc *sc; + + /* + * Access to guest memory is required. Fail if + * memory not mapped + */ + if (paddr_guest2host(0) == NULL) + return (1); + + sc = malloc(sizeof(struct pci_vtnet_softc)); + memset(sc, 0, sizeof(struct pci_vtnet_softc)); + + pi->pi_arg = sc; + sc->vsc_pi = pi; + + pthread_mutex_init(&sc->vsc_mtx, NULL); + + /* + * Attempt to open the tap device + */ + sc->vsc_tapfd = -1; + if (opts != NULL) { + char tbuf[80]; + + strcpy(tbuf, "/dev/"); + strncat(tbuf, opts, sizeof(tbuf) - strlen(tbuf)); + + sc->vsc_tapfd = open(tbuf, O_RDWR); + if (sc->vsc_tapfd == -1) { + WPRINTF(("open of tap device %s failed\n", tbuf)); + } else { + /* + * Set non-blocking and register for read + * notifications with the event loop + */ + int opt = 1; + if (ioctl(sc->vsc_tapfd, FIONBIO, &opt) < 0) { + WPRINTF(("tap device O_NONBLOCK failed\n")); + close(sc->vsc_tapfd); + sc->vsc_tapfd = -1; + } + + sc->vsc_mevp = mevent_add(sc->vsc_tapfd, + EVF_READ, + pci_vtnet_tap_callback, + sc); + if (sc->vsc_mevp == NULL) { + WPRINTF(("Could not register event\n")); + close(sc->vsc_tapfd); + sc->vsc_tapfd = -1; + } + } + } + + /* + * The MAC address is the standard NetApp OUI of 00-a0-98, + * followed by an MD5 of the vm name. The slot number is + * prepended to this for slots other than 1, so that + * CFE can netboot from the equivalent of slot 1. + */ + if (pi->pi_slot == 1) { + strncpy(nstr, vmname, sizeof(nstr)); + } else { + snprintf(nstr, sizeof(nstr), "%d-%s", pi->pi_slot, vmname); + } + + MD5Init(&mdctx); + MD5Update(&mdctx, nstr, strlen(nstr)); + MD5Final(digest, &mdctx); + + sc->vsc_macaddr[0] = 0x00; + sc->vsc_macaddr[1] = 0xa0; + sc->vsc_macaddr[2] = 0x98; + sc->vsc_macaddr[3] = digest[0]; + sc->vsc_macaddr[4] = digest[1]; + sc->vsc_macaddr[5] = digest[2]; + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_NET); + pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); + pci_emul_alloc_bar(pi, 0, 0, PCIBAR_IO, VTNET_REGSZ); + pci_emul_add_msicap(pi, 1); + + return (0); +} + +/* + * Function pointer array to handle queue notifications + */ +static void (*pci_vtnet_qnotify[VTNET_MAXQ])(struct pci_vtnet_softc *) = { + pci_vtnet_ping_rxq, + pci_vtnet_ping_txq, + pci_vtnet_ping_ctlq +}; + +static void +pci_vtnet_write(struct pci_devinst *pi, int baridx, int offset, int size, + uint32_t value) +{ + struct pci_vtnet_softc *sc = pi->pi_arg; + + if (offset + size > VTNET_REGSZ) { + DPRINTF(("vtnet_write: 2big, offset %d size %d\n", + offset, size)); + return; + } + + pthread_mutex_lock(&sc->vsc_mtx); + + switch (offset) { + case VTCFG_R_GUESTCAP: + assert(size == 4); + sc->vsc_features = value & VTNET_S_HOSTCAPS; + break; + case VTCFG_R_PFN: + assert(size == 4); + pci_vtnet_ring_init(sc, value); + break; + case VTCFG_R_QSEL: + assert(size == 2); + assert(value < VTNET_MAXQ); + sc->vsc_curq = value; + break; + case VTCFG_R_QNOTIFY: + assert(size == 2); + assert(value < VTNET_MAXQ); + (*pci_vtnet_qnotify[value])(sc); + break; + case VTCFG_R_STATUS: + assert(size == 1); + pci_vtnet_update_status(sc, value); + break; + case VTNET_R_CFG0: + case VTNET_R_CFG1: + case VTNET_R_CFG2: + case VTNET_R_CFG3: + case VTNET_R_CFG4: + case VTNET_R_CFG5: + /* + * The driver is allowed to change the MAC address + */ + assert(size == 1); + sc->vsc_macaddr[offset - VTNET_R_CFG0] = value; + break; + case VTCFG_R_HOSTCAP: + case VTCFG_R_QNUM: + case VTCFG_R_ISR: + case VTNET_R_CFG6: + case VTNET_R_CFG7: + DPRINTF(("vtnet: write to readonly reg %d\n\r", offset)); + break; + default: + DPRINTF(("vtnet: unknown i/o write offset %d\n\r", offset)); + value = 0; + break; + } + + pthread_mutex_unlock(&sc->vsc_mtx); +} + +uint32_t +pci_vtnet_read(struct pci_devinst *pi, int baridx, int offset, int size) +{ + struct pci_vtnet_softc *sc = pi->pi_arg; + uint32_t value; + + if (offset + size > VTNET_REGSZ) { + DPRINTF(("vtnet_read: 2big, offset %d size %d\n", + offset, size)); + return (0); + } + + pthread_mutex_lock(&sc->vsc_mtx); + + switch (offset) { + case VTCFG_R_HOSTCAP: + assert(size == 4); + value = VTNET_S_HOSTCAPS; + break; + case VTCFG_R_GUESTCAP: + assert(size == 4); + value = sc->vsc_features; /* XXX never read ? */ + break; + case VTCFG_R_PFN: + assert(size == 4); + value = sc->vsc_pfn[sc->vsc_curq] >> VRING_PFN; + break; + case VTCFG_R_QNUM: + assert(size == 2); + value = pci_vtnet_qsize(sc->vsc_curq); + break; + case VTCFG_R_QSEL: + assert(size == 2); + value = sc->vsc_curq; /* XXX never read ? */ + break; + case VTCFG_R_QNOTIFY: + assert(size == 2); + value = sc->vsc_curq; /* XXX never read ? */ + break; + case VTCFG_R_STATUS: + assert(size == 1); + value = sc->vsc_status; + break; + case VTCFG_R_ISR: + assert(size == 1); + value = sc->vsc_isr; + sc->vsc_isr = 0; /* a read clears this flag */ + break; + case VTNET_R_CFG0: + case VTNET_R_CFG1: + case VTNET_R_CFG2: + case VTNET_R_CFG3: + case VTNET_R_CFG4: + case VTNET_R_CFG5: + assert(size == 1); + value = sc->vsc_macaddr[offset - VTNET_R_CFG0]; + break; + case VTNET_R_CFG6: + assert(size == 1); + value = 0x01; /* XXX link always up */ + break; + case VTNET_R_CFG7: + assert(size == 1); + value = 0; /* link status is in the LSB */ + break; + default: + DPRINTF(("vtnet: unknown i/o read offset %d\n\r", offset)); + value = 0; + break; + } + + pthread_mutex_unlock(&sc->vsc_mtx); + + return (value); +} + +struct pci_devemu pci_de_vnet = { + .pe_emu = "virtio-net", + .pe_init = pci_vtnet_init, + .pe_iow = pci_vtnet_write, + .pe_ior = pci_vtnet_read, +}; +PCI_EMUL_SET(pci_de_vnet); diff --git a/usr.sbin/bhyve/pit_8254.c b/usr.sbin/bhyve/pit_8254.c new file mode 100644 index 00000000000..b5101616b03 --- /dev/null +++ b/usr.sbin/bhyve/pit_8254.c @@ -0,0 +1,196 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include + +#include +#include + +#include "fbsdrun.h" +#include "inout.h" +#include "pit_8254.h" + +#define TIMER_SEL_MASK 0xc0 +#define TIMER_RW_MASK 0x30 +#define TIMER_MODE_MASK 0x0f +#define TIMER_SEL_READBACK 0xc0 + +#define TIMER_DIV(freq, hz) (((freq) + (hz) / 2) / (hz)) + +#define PIT_8254_FREQ 1193182 +static const int nsecs_per_tick = 1000000000 / PIT_8254_FREQ; + +struct counter { + struct timeval tv; /* uptime when counter was loaded */ + uint16_t initial; /* initial counter value */ + uint8_t cr[2]; + uint8_t ol[2]; + int crbyte; + int olbyte; +}; + +static void +timevalfix(struct timeval *t1) +{ + + if (t1->tv_usec < 0) { + t1->tv_sec--; + t1->tv_usec += 1000000; + } + if (t1->tv_usec >= 1000000) { + t1->tv_sec++; + t1->tv_usec -= 1000000; + } +} + +static void +timevalsub(struct timeval *t1, const struct timeval *t2) +{ + + t1->tv_sec -= t2->tv_sec; + t1->tv_usec -= t2->tv_usec; + timevalfix(t1); +} + +static void +latch(struct counter *c) +{ + struct timeval tv2; + uint16_t lval; + uint64_t delta_nsecs, delta_ticks; + + /* cannot latch a new value until the old one has been consumed */ + if (c->olbyte != 0) + return; + + if (c->initial == 0 || c->initial == 1) { + /* + * XXX the program that runs the VM can be stopped and + * restarted at any time. This means that state that was + * created by the guest is destroyed between invocations + * of the program. + * + * If the counter's initial value is not programmed we + * assume a value that would be set to generate 'guest_hz' + * interrupts per second. + */ + c->initial = TIMER_DIV(PIT_8254_FREQ, guest_hz); + gettimeofday(&c->tv, NULL); + } + + (void)gettimeofday(&tv2, NULL); + timevalsub(&tv2, &c->tv); + delta_nsecs = tv2.tv_sec * 1000000000 + tv2.tv_usec * 1000; + delta_ticks = delta_nsecs / nsecs_per_tick; + + lval = c->initial - delta_ticks % c->initial; + c->olbyte = 2; + c->ol[1] = lval; /* LSB */ + c->ol[0] = lval >> 8; /* MSB */ +} + +static int +pit_8254_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + int sel, rw, mode; + uint8_t val; + struct counter *c; + + static struct counter counter[3]; + + if (bytes != 1) + return (-1); + + val = *eax; + + if (port == TIMER_MODE) { + assert(in == 0); + sel = val & TIMER_SEL_MASK; + rw = val & TIMER_RW_MASK; + mode = val & TIMER_MODE_MASK; + + if (sel == TIMER_SEL_READBACK) + return (-1); + if (rw != TIMER_LATCH && rw != TIMER_16BIT) + return (-1); + + if (rw != TIMER_LATCH) { + /* + * Counter mode is not affected when issuing a + * latch command. + */ + if (mode != TIMER_RATEGEN && mode != TIMER_SQWAVE) + return (-1); + } + + c = &counter[sel >> 6]; + if (rw == TIMER_LATCH) + latch(c); + else + c->olbyte = 0; /* reset latch after reprogramming */ + + return (0); + } + + /* counter ports */ + assert(port >= TIMER_CNTR0 && port <= TIMER_CNTR2); + c = &counter[port - TIMER_CNTR0]; + + if (in) { + /* + * XXX + * The spec says that once the output latch is completely + * read it should revert to "following" the counter. We don't + * do this because it is hard and any reasonable OS should + * always latch the counter before trying to read it. + */ + if (c->olbyte == 0) + c->olbyte = 2; + *eax = c->ol[--c->olbyte]; + } else { + c->cr[c->crbyte++] = *eax; + if (c->crbyte == 2) { + c->crbyte = 0; + c->initial = c->cr[0] | (uint16_t)c->cr[1] << 8; + gettimeofday(&c->tv, NULL); + } + } + + return (0); +} + +INOUT_PORT(8254, TIMER_MODE, IOPORT_F_OUT, pit_8254_handler); +INOUT_PORT(8254, TIMER_CNTR0, IOPORT_F_INOUT, pit_8254_handler); +INOUT_PORT(8254, TIMER_CNTR1, IOPORT_F_INOUT, pit_8254_handler); +INOUT_PORT(8254, TIMER_CNTR2, IOPORT_F_INOUT, pit_8254_handler); diff --git a/usr.sbin/bhyve/pit_8254.h b/usr.sbin/bhyve/pit_8254.h new file mode 100644 index 00000000000..61bd15d13b1 --- /dev/null +++ b/usr.sbin/bhyve/pit_8254.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _PIT_8254_H_ +#define _PIT_8254_H_ + +/* + * Borrowed from amd64/include/timerreg.h because in that file it is + * conditionally compiled for #ifdef _KERNEL only. + */ + +#include + +#define IO_TIMER1 0x40 /* 8253 Timer #1 */ +#define TIMER_CNTR0 (IO_TIMER1 + TIMER_REG_CNTR0) +#define TIMER_CNTR1 (IO_TIMER1 + TIMER_REG_CNTR1) +#define TIMER_CNTR2 (IO_TIMER1 + TIMER_REG_CNTR2) +#define TIMER_MODE (IO_TIMER1 + TIMER_REG_MODE) + +#endif /* _PIT_8254_H_ */ diff --git a/usr.sbin/bhyve/post.c b/usr.sbin/bhyve/post.c new file mode 100644 index 00000000000..092a551d87b --- /dev/null +++ b/usr.sbin/bhyve/post.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include + +#include "inout.h" + +static int +post_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + assert(in == 1); + + if (bytes != 1) + return (-1); + + *eax = 0xff; /* return some garbage */ + return (0); +} + +INOUT_PORT(post, 0x84, IOPORT_F_IN, post_data_handler); diff --git a/usr.sbin/bhyve/rtc.c b/usr.sbin/bhyve/rtc.c new file mode 100644 index 00000000000..a6f44e00bcd --- /dev/null +++ b/usr.sbin/bhyve/rtc.c @@ -0,0 +1,268 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include + +#include "inout.h" + +#define IO_RTC 0x70 + +#define RTC_SEC 0x00 /* seconds */ +#define RTC_MIN 0x02 +#define RTC_HRS 0x04 +#define RTC_WDAY 0x06 +#define RTC_DAY 0x07 +#define RTC_MONTH 0x08 +#define RTC_YEAR 0x09 +#define RTC_CENTURY 0x32 /* current century */ + +#define RTC_STATUSA 0xA +#define RTCSA_TUP 0x80 /* time update, don't look now */ + +#define RTC_STATUSB 0xB +#define RTCSB_DST 0x01 +#define RTCSB_24HR 0x02 +#define RTCSB_BIN 0x04 /* 0 = BCD, 1 = Binary */ +#define RTCSB_PINTR 0x40 /* 1 = enable periodic clock interrupt */ +#define RTCSB_HALT 0x80 /* stop clock updates */ + +#define RTC_INTR 0x0c /* status register C (R) interrupt source */ + +#define RTC_STATUSD 0x0d /* status register D (R) Lost Power */ +#define RTCSD_PWR 0x80 /* clock power OK */ + +#define RTC_DIAG 0x0e + +#define RTC_RSTCODE 0x0f + +static int addr; + +/* XXX initialize these to default values as they would be from BIOS */ +static uint8_t status_a, status_b, rstcode; + +static u_char const bin2bcd_data[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99 +}; +#define bin2bcd(bin) (bin2bcd_data[bin]) + +#define rtcout(val) ((status_b & RTCSB_BIN) ? (val) : bin2bcd((val))) + +static void +timevalfix(struct timeval *t1) +{ + + if (t1->tv_usec < 0) { + t1->tv_sec--; + t1->tv_usec += 1000000; + } + if (t1->tv_usec >= 1000000) { + t1->tv_sec++; + t1->tv_usec -= 1000000; + } +} + +static void +timevalsub(struct timeval *t1, const struct timeval *t2) +{ + + t1->tv_sec -= t2->tv_sec; + t1->tv_usec -= t2->tv_usec; + timevalfix(t1); +} + +static int +rtc_addr_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + assert(in == 0); + + if (bytes != 1) + return (-1); + + switch (*eax) { + case RTC_SEC: + case RTC_MIN: + case RTC_HRS: + case RTC_WDAY: + case RTC_DAY: + case RTC_MONTH: + case RTC_YEAR: + case RTC_CENTURY: + case RTC_STATUSA: + case RTC_STATUSB: + case RTC_INTR: + case RTC_STATUSD: + case RTC_DIAG: + case RTC_RSTCODE: + break; + default: + return (-1); + } + + addr = *eax; + return (0); +} + +static int +rtc_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + int hour; + time_t t; + struct timeval cur, delta; + + static struct timeval last; + static struct tm tm; + + if (bytes != 1) + return (-1); + + gettimeofday(&cur, NULL); + + /* + * Increment the cached time only once per second so we can guarantee + * that the guest has at least one second to read the hour:min:sec + * separately and still get a coherent view of the time. + */ + delta = cur; + timevalsub(&delta, &last); + if (delta.tv_sec >= 1 && (status_b & RTCSB_HALT) == 0) { + t = cur.tv_sec; + localtime_r(&t, &tm); + last = cur; + } + + if (in) { + switch (addr) { + case RTC_SEC: + *eax = rtcout(tm.tm_sec); + return (0); + case RTC_MIN: + *eax = rtcout(tm.tm_min); + return (0); + case RTC_HRS: + if (status_b & RTCSB_24HR) + hour = tm.tm_hour; + else + hour = (tm.tm_hour % 12) + 1; + + *eax = rtcout(hour); + + /* + * If we are representing time in the 12-hour format + * then set the MSB to indicate PM. + */ + if ((status_b & RTCSB_24HR) == 0 && tm.tm_hour >= 12) + *eax |= 0x80; + + return (0); + case RTC_WDAY: + *eax = rtcout(tm.tm_wday + 1); + return (0); + case RTC_DAY: + *eax = rtcout(tm.tm_mday); + return (0); + case RTC_MONTH: + *eax = rtcout(tm.tm_mon + 1); + return (0); + case RTC_YEAR: + *eax = rtcout(tm.tm_year % 100); + return (0); + case RTC_CENTURY: + *eax = rtcout(tm.tm_year / 100); + break; + case RTC_STATUSA: + *eax = status_a; + return (0); + case RTC_INTR: + *eax = 0; + return (0); + case RTC_STATUSD: + *eax = RTCSD_PWR; + return (0); + case RTC_DIAG: + *eax = 0; + return (0); + case RTC_RSTCODE: + *eax = rstcode; + return (0); + default: + return (-1); + } + } + + switch (addr) { + case RTC_STATUSA: + status_a = *eax & ~RTCSA_TUP; + break; + case RTC_STATUSB: + /* XXX not implemented yet XXX */ + if (*eax & RTCSB_PINTR) + return (-1); + status_b = *eax; + break; + case RTC_RSTCODE: + rstcode = *eax; + break; + case RTC_SEC: + case RTC_MIN: + case RTC_HRS: + case RTC_WDAY: + case RTC_DAY: + case RTC_MONTH: + case RTC_YEAR: + case RTC_CENTURY: + /* + * Ignore writes to the time of day registers + */ + break; + default: + return (-1); + } + return (0); +} + +INOUT_PORT(rtc, IO_RTC, IOPORT_F_OUT, rtc_addr_handler); +INOUT_PORT(rtc, IO_RTC + 1, IOPORT_F_INOUT, rtc_data_handler); diff --git a/usr.sbin/bhyve/uart.c b/usr.sbin/bhyve/uart.c new file mode 100644 index 00000000000..640f3bf0f70 --- /dev/null +++ b/usr.sbin/bhyve/uart.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include "inout.h" + +#define COM1 0x3F8 +#define COM2 0x2F8 + +#define REG_IIR 2 + +static int +com_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + assert(in); + + if (bytes != 1) + return (-1); + + /* + * COM port is not implemented so we return 0xFF for all registers + */ + *eax = 0xFF; + + return (0); +} + +INOUT_PORT(uart, COM1 + REG_IIR, IOPORT_F_IN, com_handler); +INOUT_PORT(uart, COM2 + REG_IIR, IOPORT_F_IN, com_handler); diff --git a/usr.sbin/bhyve/virtio.h b/usr.sbin/bhyve/virtio.h new file mode 100644 index 00000000000..474e244c596 --- /dev/null +++ b/usr.sbin/bhyve/virtio.h @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _VIRTIO_H_ +#define _VIRTIO_H_ + +#define VRING_ALIGN 4096 + +#define VRING_DESC_F_NEXT (1 << 0) +#define VRING_DESC_F_WRITE (1 << 1) +#define VRING_DESC_F_INDIRECT (1 << 2) + +#define VRING_AVAIL_F_NO_INTERRUPT 1 + +struct virtio_desc { + uint64_t vd_addr; + uint32_t vd_len; + uint16_t vd_flags; + uint16_t vd_next; +} __packed; + +struct virtio_used { + uint32_t vu_idx; + uint32_t vu_tlen; +} __packed; + +/* + * PFN register shift amount + */ +#define VRING_PFN 12 + +/* + * Virtio device types + */ +#define VIRTIO_TYPE_NET 1 +#define VIRTIO_TYPE_BLOCK 2 + +/* + * PCI vendor/device IDs + */ +#define VIRTIO_VENDOR 0x1AF4 +#define VIRTIO_DEV_NET 0x1000 +#define VIRTIO_DEV_BLOCK 0x1001 + +/* + * PCI config space constants + */ +#define VTCFG_R_HOSTCAP 0 +#define VTCFG_R_GUESTCAP 4 +#define VTCFG_R_PFN 8 +#define VTCFG_R_QNUM 12 +#define VTCFG_R_QSEL 14 +#define VTCFG_R_QNOTIFY 16 +#define VTCFG_R_STATUS 18 +#define VTCFG_R_ISR 19 +#define VTCFG_R_CFG0 20 /* No MSI-X */ +#define VTCFG_R_CFG1 24 /* With MSI-X */ +#define VTCFG_R_MSIX 20 + +#endif /* _VIRTIO_H_ */ diff --git a/usr.sbin/bhyve/xmsr.c b/usr.sbin/bhyve/xmsr.c new file mode 100644 index 00000000000..931b7d7f791 --- /dev/null +++ b/usr.sbin/bhyve/xmsr.c @@ -0,0 +1,261 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include + +#include "fbsdrun.h" +#include "xmsr.h" + +/* + * Trampoline for hypervisor direct 64-bit jump. + * + * 0 - signature for guest->host verification + * 8 - kernel virtual address of trampoline + * 16 - instruction virtual address + * 24 - stack pointer virtual address + * 32 - CR3, physical address of kernel page table + * 40 - 24-byte area for null/code/data GDT entries + */ +#define MP_V64T_SIG 0xcafebabecafebabeULL +struct mp_v64tramp { + uint64_t mt_sig; + uint64_t mt_virt; + uint64_t mt_eip; + uint64_t mt_rsp; + uint64_t mt_cr3; + uint64_t mt_gdtr[3]; +}; + +/* + * CPU 0 is considered to be the BSP and is set to the RUNNING state. + * All other CPUs are set up in the INIT state. + */ +#define BSP 0 +enum cpu_bstate { + CPU_S_INIT, + CPU_S_SIPI, + CPU_S_RUNNING +} static cpu_b[VM_MAXCPU] = { [BSP] = CPU_S_RUNNING }; + +static void spinup_ap(struct vmctx *, int, int, uint64_t *); +static void spinup_ap_direct64(struct vmctx *, int, uintptr_t, uint64_t *); + +int +emulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t code, uint64_t val) +{ + int dest; + int mode; + int thiscpu; + int vec; + int error, retval; + uint64_t rip; + + retval = vcpu; + thiscpu = 1 << vcpu; + + /* + * The only MSR value handled is the x2apic CR register + */ + if (code != 0x830) { + printf("Unknown WRMSR code %x, val %lx, cpu %d\n", + code, val, vcpu); + exit(1); + } + + /* + * The value written to the MSR will generate an IPI to + * a set of CPUs. If this is a SIPI, create the initial + * state for the CPU and switch to it. Otherwise, inject + * an interrupt for the destination CPU(s), and request + * a switch to the next available one by returning -1 + */ + dest = val >> 32; + vec = val & APIC_VECTOR_MASK; + mode = val & APIC_DELMODE_MASK; + + switch (mode) { + case APIC_DELMODE_INIT: + assert(dest != 0); + assert(dest < guest_ncpus); + + /* + * Ignore legacy de-assert INITs in x2apic mode + */ + if ((val & APIC_LEVEL_MASK) == APIC_LEVEL_DEASSERT) { + break; + } + assert(cpu_b[dest] == CPU_S_INIT); + + /* + * Move CPU to wait-for-SIPI state + */ + error = vcpu_reset(ctx, dest); + assert(error == 0); + + cpu_b[dest] = CPU_S_SIPI; + break; + + case APIC_DELMODE_STARTUP: + assert(dest != 0); + assert(dest < guest_ncpus); + /* + * Ignore SIPIs in any state other than wait-for-SIPI + */ + if (cpu_b[dest] != CPU_S_SIPI) { + break; + } + + /* + * Bring up the AP and signal the main loop that it is + * available and to switch to it. + */ + spinup_ap(ctx, dest, vec, &rip); + cpu_b[dest] = CPU_S_RUNNING; + fbsdrun_addcpu(ctx, dest, rip); + retval = dest; + break; + + default: + printf("APIC delivery mode %lx not supported!\n", + val & APIC_DELMODE_MASK); + exit(1); + } + + return (retval); +} + +/* + * There are 2 startup modes possible here: + * - if the CPU supports 'unrestricted guest' mode, the spinup can + * set up the processor state in power-on 16-bit mode, with the CS:IP + * init'd to the specified low-mem 4K page. + * - if the guest has requested a 64-bit trampoline in the low-mem 4K + * page by placing in the specified signature, set up the register + * state using register state in the signature. Note that this + * requires accessing guest physical memory to read the signature + * while 'unrestricted mode' does not. + */ +static void +spinup_ap(struct vmctx *ctx, int newcpu, int vector, uint64_t *rip) +{ + int error; + uint16_t cs; + uint64_t desc_base; + uint32_t desc_limit, desc_access; + + if (fbsdrun_vmexit_on_hlt()) { + error = vm_set_capability(ctx, newcpu, VM_CAP_HALT_EXIT, 1); + assert(error == 0); + } + + if (fbsdrun_vmexit_on_pause()) { + error = vm_set_capability(ctx, newcpu, VM_CAP_PAUSE_EXIT, 1); + assert(error == 0); + } + + error = vm_set_capability(ctx, newcpu, VM_CAP_UNRESTRICTED_GUEST, 1); + if (error) { + /* + * If the guest does not support real-mode execution then + * we will bring up the AP directly in 64-bit mode. + */ + spinup_ap_direct64(ctx, newcpu, vector << PAGE_SHIFT, rip); + } else { + /* + * Update the %cs and %rip of the guest so that it starts + * executing real mode code at at 'vector << 12'. + */ + *rip = 0; + error = vm_set_register(ctx, newcpu, VM_REG_GUEST_RIP, *rip); + assert(error == 0); + + error = vm_get_desc(ctx, newcpu, VM_REG_GUEST_CS, &desc_base, + &desc_limit, &desc_access); + assert(error == 0); + + desc_base = vector << PAGE_SHIFT; + error = vm_set_desc(ctx, newcpu, VM_REG_GUEST_CS, + desc_base, desc_limit, desc_access); + assert(error == 0); + + cs = (vector << PAGE_SHIFT) >> 4; + error = vm_set_register(ctx, newcpu, VM_REG_GUEST_CS, cs); + assert(error == 0); + } +} + +static void +spinup_ap_direct64(struct vmctx *ctx, int newcpu, uintptr_t gaddr, + uint64_t *rip) +{ + struct mp_v64tramp *mvt; + char *errstr; + int error; + uint64_t gdtbase; + + mvt = paddr_guest2host(gaddr); + + assert(mvt->mt_sig == MP_V64T_SIG); + + /* + * Set up the 3-entry GDT using memory supplied in the + * guest's trampoline structure. + */ + vm_setup_freebsd_gdt(mvt->mt_gdtr); + +#define CHECK_ERROR(msg) \ + if (error != 0) { \ + errstr = msg; \ + goto err_exit; \ + } + + /* entry point */ + *rip = mvt->mt_eip; + + /* Get the guest virtual address of the GDT */ + gdtbase = mvt->mt_virt + __offsetof(struct mp_v64tramp, mt_gdtr); + + error = vm_setup_freebsd_registers(ctx, newcpu, mvt->mt_eip, + mvt->mt_cr3, gdtbase, mvt->mt_rsp); + CHECK_ERROR("vm_setup_freebsd_registers"); + + return; +err_exit: + printf("spinup_ap_direct64: machine state error: %s", errstr); + exit(1); +} diff --git a/usr.sbin/bhyve/xmsr.h b/usr.sbin/bhyve/xmsr.h new file mode 100644 index 00000000000..8cebcea0cd5 --- /dev/null +++ b/usr.sbin/bhyve/xmsr.h @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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 _XMSR_H_ +#define _XMSR_H_ + +int emulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t code, uint64_t val); + +#endif diff --git a/usr.sbin/vmmctl/Makefile b/usr.sbin/vmmctl/Makefile new file mode 100644 index 00000000000..1f529b561f1 --- /dev/null +++ b/usr.sbin/vmmctl/Makefile @@ -0,0 +1,15 @@ +# +# $FreeBSD$ +# + +PROG= vmmctl +SRCS= vmmctl.c + +NO_MAN= + +DPADD= ${LIBVMMAPI} +LDADD= -lvmmapi + +CFLAGS+= -I${.CURDIR}/../../sys/amd64/vmm + +.include diff --git a/usr.sbin/vmmctl/sample.sh b/usr.sbin/vmmctl/sample.sh new file mode 100755 index 00000000000..f38d0dadb88 --- /dev/null +++ b/usr.sbin/vmmctl/sample.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +# $FreeBSD$ + +VMMCTL="sudo ./vmmctl" +VMNAME=sample + +${VMMCTL} --vm=${VMNAME} --create +${VMMCTL} --vm=${VMNAME} --set-lowmem=128 --set-highmem=256 +${VMMCTL} --vm=${VMNAME} --get-lowmem --get-highmem + +CR0_PE=$((1 << 0)) +CR0_PG=$((1 << 31)) +CR0=$(($CR0_PE | $CR0_PG)) +${VMMCTL} --vm=${VMNAME} --set-cr0=${CR0} --get-cr0 + +# XXX this is bogus the value of %cr3 should come from the loader +CR3=0 +${VMMCTL} --vm=${VMNAME} --set-cr3=${CR3} --get-cr3 + +CR4_PAE=$((1 << 5)) +CR4=$((${CR4_PAE})) +${VMMCTL} --vm=${VMNAME} --set-cr4=${CR4} --get-cr4 + +DR7=0x00000400 # Table 9-1 from Intel Architecture Manual 3A +${VMMCTL} --vm=${VMNAME} --set-dr7=${DR7} --get-dr7 + +# +# XXX the values of rsp and rip are bogus and should come from the loader. +# +RSP=0xa5a5a5a5 +RIP=0x0000bfbfbfbf0000 +RFLAGS=0x2 +${VMMCTL} --vm=${VMNAME} --set-rsp=${RSP} --get-rsp +${VMMCTL} --vm=${VMNAME} --set-rip=${RIP} --get-rip +${VMMCTL} --vm=${VMNAME} --set-rflags=${RFLAGS} --get-rflags + +# Set "hidden" state of %cs descriptor to indicate long mode code segment. +# +# Note that this should match the contents of the entry pointed to by the +# segment selector in the GDTR. +# +${VMMCTL} --vm=${VMNAME} --set-desc-cs --desc-access=0x00002098 --get-desc-cs + +# Set "hidden" state of all data descriptors to indicate a usable segment. +# The only useful fields are the "Present" and "Descriptor Type" bits. +${VMMCTL} --vm=${VMNAME} --set-desc-ds --desc-access=0x00000090 --get-desc-ds +${VMMCTL} --vm=${VMNAME} --set-desc-es --desc-access=0x00000090 --get-desc-es +${VMMCTL} --vm=${VMNAME} --set-desc-fs --desc-access=0x00000090 --get-desc-fs +${VMMCTL} --vm=${VMNAME} --set-desc-gs --desc-access=0x00000090 --get-desc-gs +${VMMCTL} --vm=${VMNAME} --set-desc-ss --desc-access=0x00000090 --get-desc-ss + +# +# Set the code segment selector to point to entry at offset 8 in the GDTR. +# +${VMMCTL} --vm=${VMNAME} --set-cs=0x0008 --get-cs + +# Set all the remaining data segment selectors to point to entry at offset +# 16 in the GDTR. +${VMMCTL} --vm=${VMNAME} --set-ds=0x0010 --get-ds +${VMMCTL} --vm=${VMNAME} --set-es=0x0010 --get-es +${VMMCTL} --vm=${VMNAME} --set-fs=0x0010 --get-fs +${VMMCTL} --vm=${VMNAME} --set-gs=0x0010 --get-gs +${VMMCTL} --vm=${VMNAME} --set-ss=0x0010 --get-ss + +# XXX the value of the GDTR should come from the loader. +# Set the GDTR +GDTR_BASE=0xffff0000 +GDTR_LIMIT=0x10 +${VMMCTL} --vm=${VMNAME} --set-desc-gdtr --desc-base=${GDTR_BASE} --desc-limit=${GDTR_LIMIT} --get-desc-gdtr + +${VMMCTL} --vm=${VMNAME} --set-pinning=0 --get-pinning +${VMMCTL} --vm=${VMNAME} --set-pinning=-1 --get-pinning + +${VMMCTL} --vm=${VMNAME} --destroy diff --git a/usr.sbin/vmmctl/vmmctl.c b/usr.sbin/vmmctl/vmmctl.c new file mode 100644 index 00000000000..678f98b0734 --- /dev/null +++ b/usr.sbin/vmmctl/vmmctl.c @@ -0,0 +1,1485 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "intel/vmcs.h" + +#define MB (1UL << 20) +#define GB (1UL << 30) + +#define REQ_ARG required_argument +#define NO_ARG no_argument +#define OPT_ARG optional_argument + +static const char *progname; + +static void +usage(void) +{ + + (void)fprintf(stderr, + "Usage: %s --vm=\n" + " [--cpu=]\n" + " [--create]\n" + " [--destroy]\n" + " [--get-stats]\n" + " [--set-desc-ds]\n" + " [--get-desc-ds]\n" + " [--set-desc-es]\n" + " [--get-desc-es]\n" + " [--set-desc-gs]\n" + " [--get-desc-gs]\n" + " [--set-desc-fs]\n" + " [--get-desc-fs]\n" + " [--set-desc-cs]\n" + " [--get-desc-cs]\n" + " [--set-desc-ss]\n" + " [--get-desc-ss]\n" + " [--set-desc-tr]\n" + " [--get-desc-tr]\n" + " [--set-desc-ldtr]\n" + " [--get-desc-ldtr]\n" + " [--set-desc-gdtr]\n" + " [--get-desc-gdtr]\n" + " [--set-desc-idtr]\n" + " [--get-desc-idtr]\n" + " [--run]\n" + " [--capname=]\n" + " [--getcap]\n" + " [--setcap=<0|1>]\n" + " [--desc-base=]\n" + " [--desc-limit=]\n" + " [--desc-access=]\n" + " [--set-cr0=]\n" + " [--get-cr0]\n" + " [--set-cr3=]\n" + " [--get-cr3]\n" + " [--set-cr4=]\n" + " [--get-cr4]\n" + " [--set-dr7=]\n" + " [--get-dr7]\n" + " [--set-rsp=]\n" + " [--get-rsp]\n" + " [--set-rip=]\n" + " [--get-rip]\n" + " [--get-rax]\n" + " [--set-rax=]\n" + " [--get-rbx]\n" + " [--get-rcx]\n" + " [--get-rdx]\n" + " [--get-rsi]\n" + " [--get-rdi]\n" + " [--get-rbp]\n" + " [--get-r8]\n" + " [--get-r9]\n" + " [--get-r10]\n" + " [--get-r11]\n" + " [--get-r12]\n" + " [--get-r13]\n" + " [--get-r14]\n" + " [--get-r15]\n" + " [--set-rflags=]\n" + " [--get-rflags]\n" + " [--set-cs]\n" + " [--get-cs]\n" + " [--set-ds]\n" + " [--get-ds]\n" + " [--set-es]\n" + " [--get-es]\n" + " [--set-fs]\n" + " [--get-fs]\n" + " [--set-gs]\n" + " [--get-gs]\n" + " [--set-ss]\n" + " [--get-ss]\n" + " [--get-tr]\n" + " [--get-ldtr]\n" + " [--get-vmcs-pinbased-ctls]\n" + " [--get-vmcs-procbased-ctls]\n" + " [--get-vmcs-procbased-ctls2]\n" + " [--get-vmcs-entry-interruption-info]\n" + " [--set-vmcs-entry-interruption-info=]\n" + " [--get-vmcs-eptp]\n" + " [--get-vmcs-guest-physical-address\n" + " [--get-vmcs-guest-linear-address\n" + " [--set-vmcs-exception-bitmap]\n" + " [--get-vmcs-exception-bitmap]\n" + " [--get-vmcs-io-bitmap-address]\n" + " [--get-vmcs-tsc-offset]\n" + " [--get-vmcs-guest-pat]\n" + " [--get-vmcs-host-pat]\n" + " [--get-vmcs-host-cr0]\n" + " [--get-vmcs-host-cr3]\n" + " [--get-vmcs-host-cr4]\n" + " [--get-vmcs-host-rip]\n" + " [--get-vmcs-host-rsp]\n" + " [--get-vmcs-cr0-mask]\n" + " [--get-vmcs-cr0-shadow]\n" + " [--get-vmcs-cr4-mask]\n" + " [--get-vmcs-cr4-shadow]\n" + " [--get-vmcs-cr3-targets]\n" + " [--get-vmcs-apic-access-address]\n" + " [--get-vmcs-virtual-apic-address]\n" + " [--get-vmcs-tpr-threshold]\n" + " [--get-vmcs-msr-bitmap]\n" + " [--get-vmcs-msr-bitmap-address]\n" + " [--get-vmcs-vpid]\n" + " [--get-vmcs-ple-gap]\n" + " [--get-vmcs-ple-window]\n" + " [--get-vmcs-instruction-error]\n" + " [--get-vmcs-exit-ctls]\n" + " [--get-vmcs-entry-ctls]\n" + " [--get-vmcs-guest-sysenter]\n" + " [--get-vmcs-link]\n" + " [--get-vmcs-exit-reason]\n" + " [--get-vmcs-exit-qualification]\n" + " [--get-vmcs-exit-interruption-info]\n" + " [--get-vmcs-exit-interruption-error]\n" + " [--get-vmcs-interruptibility]\n" + " [--set-pinning=]\n" + " [--get-pinning]\n" + " [--set-lowmem=]\n" + " [--get-lowmem]\n" + " [--set-highmem=]\n" + " [--get-highmem]\n", + progname); + exit(1); +} + +static int get_stats, getcap, setcap, capval; +static const char *capname; +static int create, destroy, get_lowmem, get_highmem; +static uint64_t lowmem, highmem; +static int set_cr0, get_cr0, set_cr3, get_cr3, set_cr4, get_cr4; +static int set_efer, get_efer; +static int set_dr7, get_dr7; +static int set_rsp, get_rsp, set_rip, get_rip, set_rflags, get_rflags; +static int set_rax, get_rax; +static int get_rbx, get_rcx, get_rdx, get_rsi, get_rdi, get_rbp; +static int get_r8, get_r9, get_r10, get_r11, get_r12, get_r13, get_r14, get_r15; +static int set_desc_ds, get_desc_ds; +static int set_desc_es, get_desc_es; +static int set_desc_fs, get_desc_fs; +static int set_desc_gs, get_desc_gs; +static int set_desc_cs, get_desc_cs; +static int set_desc_ss, get_desc_ss; +static int set_desc_gdtr, get_desc_gdtr; +static int set_desc_idtr, get_desc_idtr; +static int set_desc_tr, get_desc_tr; +static int set_desc_ldtr, get_desc_ldtr; +static int set_cs, set_ds, set_es, set_fs, set_gs, set_ss, set_tr, set_ldtr; +static int get_cs, get_ds, get_es, get_fs, get_gs, get_ss, get_tr, get_ldtr; +static int set_pinning, get_pinning, pincpu; +static int run; + +/* + * VMCS-specific fields + */ +static int get_pinbased_ctls, get_procbased_ctls, get_procbased_ctls2; +static int get_eptp, get_io_bitmap, get_tsc_offset; +static int get_vmcs_entry_interruption_info, set_vmcs_entry_interruption_info; +static int get_vmcs_interruptibility; +uint32_t vmcs_entry_interruption_info; +static int get_vmcs_gpa, get_vmcs_gla; +static int get_exception_bitmap, set_exception_bitmap, exception_bitmap; +static int get_cr0_mask, get_cr0_shadow; +static int get_cr4_mask, get_cr4_shadow; +static int get_cr3_targets; +static int get_apic_access_addr, get_virtual_apic_addr, get_tpr_threshold; +static int get_msr_bitmap, get_msr_bitmap_address; +static int get_vpid, get_ple_gap, get_ple_window; +static int get_inst_err, get_exit_ctls, get_entry_ctls; +static int get_host_cr0, get_host_cr3, get_host_cr4; +static int get_host_rip, get_host_rsp; +static int get_guest_pat, get_host_pat; +static int get_guest_sysenter, get_vmcs_link; +static int get_vmcs_exit_reason, get_vmcs_exit_qualification; +static int get_vmcs_exit_interruption_info, get_vmcs_exit_interruption_error; + +static uint64_t desc_base; +static uint32_t desc_limit, desc_access; + +static void +dump_vm_run_exitcode(struct vm_exit *vmexit, int vcpu) +{ + printf("vm exit[%d]\n", vcpu); + printf("\trip\t\t0x%016lx\n", vmexit->rip); + printf("\tinst_length\t%d\n", vmexit->inst_length); + switch (vmexit->exitcode) { + case VM_EXITCODE_INOUT: + printf("\treason\t\tINOUT\n"); + printf("\tdirection\t%s\n", vmexit->u.inout.in ? "IN" : "OUT"); + printf("\tbytes\t\t%d\n", vmexit->u.inout.bytes); + printf("\tflags\t\t%s%s\n", + vmexit->u.inout.string ? "STRING " : "", + vmexit->u.inout.rep ? "REP " : ""); + printf("\tport\t\t0x%04x\n", vmexit->u.inout.port); + printf("\teax\t\t0x%08x\n", vmexit->u.inout.eax); + break; + case VM_EXITCODE_VMX: + printf("\treason\t\tVMX\n"); + printf("\terror\t\t%d\n", vmexit->u.vmx.error); + printf("\texit_reason\t0x%08x (%u)\n", + vmexit->u.vmx.exit_reason, vmexit->u.vmx.exit_reason); + printf("\tqualification\t0x%016lx\n", + vmexit->u.vmx.exit_qualification); + break; + default: + printf("*** unknown vm run exitcode %d\n", vmexit->exitcode); + break; + } +} + +static int +dump_vmcs_msr_bitmap(int vcpu, u_long addr) +{ + int error, fd, byte, bit, readable, writeable; + u_int msr; + const char *bitmap; + + error = -1; + bitmap = MAP_FAILED; + + fd = open("/dev/mem", O_RDONLY, 0); + if (fd < 0) + goto done; + + bitmap = mmap(NULL, PAGE_SIZE, PROT_READ, 0, fd, addr); + if (bitmap == MAP_FAILED) + goto done; + + for (msr = 0; msr < 0x2000; msr++) { + byte = msr / 8; + bit = msr & 0x7; + + /* Look at MSRs in the range 0x00000000 to 0x00001FFF */ + readable = (bitmap[byte] & (1 << bit)) ? 0 : 1; + writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1; + if (readable || writeable) { + printf("msr 0x%08x[%d]\t\t%c%c\n", msr, vcpu, + readable ? 'R' : '-', + writeable ? 'W' : '-'); + } + + /* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */ + byte += 1024; + readable = (bitmap[byte] & (1 << bit)) ? 0 : 1; + writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1; + if (readable || writeable) { + printf("msr 0x%08x[%d]\t\t%c%c\n", + 0xc0000000 + msr, vcpu, + readable ? 'R' : '-', + writeable ? 'W' : '-'); + } + } + + error = 0; +done: + if (bitmap != MAP_FAILED) + munmap((void *)bitmap, PAGE_SIZE); + if (fd >= 0) + close(fd); + return (error); +} + +static int +vm_get_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t *ret_val) +{ + + return (vm_get_register(ctx, vcpu, VMCS_IDENT(field), ret_val)); +} + +static int +vm_set_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t val) +{ + + return (vm_set_register(ctx, vcpu, VMCS_IDENT(field), val)); +} + +enum { + VMNAME = 1000, /* avoid collision with return values from getopt */ + VCPU, + SET_LOWMEM, + SET_HIGHMEM, + SET_EFER, + SET_CR0, + SET_CR3, + SET_CR4, + SET_DR7, + SET_RSP, + SET_RIP, + SET_RAX, + SET_RFLAGS, + DESC_BASE, + DESC_LIMIT, + DESC_ACCESS, + SET_CS, + SET_DS, + SET_ES, + SET_FS, + SET_GS, + SET_SS, + SET_TR, + SET_LDTR, + SET_PINNING, + SET_VMCS_EXCEPTION_BITMAP, + SET_VMCS_ENTRY_INTERRUPTION_INFO, + SET_CAP, + CAPNAME, +}; + +int +main(int argc, char *argv[]) +{ + char *vmname; + int error, ch, vcpu; + vm_paddr_t hpa; + size_t len; + struct vm_exit vmexit; + uint64_t ctl, eptp, bm, tsc_off, addr, u64; + struct vmctx *ctx; + + uint64_t cr0, cr3, cr4, dr7, rsp, rip, rflags, efer, pat; + uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp; + uint64_t r8, r9, r10, r11, r12, r13, r14, r15; + uint64_t cs, ds, es, fs, gs, ss, tr, ldtr; + + struct option opts[] = { + { "vm", REQ_ARG, 0, VMNAME }, + { "cpu", REQ_ARG, 0, VCPU }, + { "set-lowmem", REQ_ARG, 0, SET_LOWMEM }, + { "set-highmem",REQ_ARG, 0, SET_HIGHMEM }, + { "set-efer", REQ_ARG, 0, SET_EFER }, + { "set-cr0", REQ_ARG, 0, SET_CR0 }, + { "set-cr3", REQ_ARG, 0, SET_CR3 }, + { "set-cr4", REQ_ARG, 0, SET_CR4 }, + { "set-dr7", REQ_ARG, 0, SET_DR7 }, + { "set-rsp", REQ_ARG, 0, SET_RSP }, + { "set-rip", REQ_ARG, 0, SET_RIP }, + { "set-rax", REQ_ARG, 0, SET_RAX }, + { "set-rflags", REQ_ARG, 0, SET_RFLAGS }, + { "desc-base", REQ_ARG, 0, DESC_BASE }, + { "desc-limit", REQ_ARG, 0, DESC_LIMIT }, + { "desc-access",REQ_ARG, 0, DESC_ACCESS }, + { "set-cs", REQ_ARG, 0, SET_CS }, + { "set-ds", REQ_ARG, 0, SET_DS }, + { "set-es", REQ_ARG, 0, SET_ES }, + { "set-fs", REQ_ARG, 0, SET_FS }, + { "set-gs", REQ_ARG, 0, SET_GS }, + { "set-ss", REQ_ARG, 0, SET_SS }, + { "set-tr", REQ_ARG, 0, SET_TR }, + { "set-ldtr", REQ_ARG, 0, SET_LDTR }, + { "set-pinning",REQ_ARG, 0, SET_PINNING }, + { "set-vmcs-exception-bitmap", + REQ_ARG, 0, SET_VMCS_EXCEPTION_BITMAP }, + { "set-vmcs-entry-interruption-info", + REQ_ARG, 0, SET_VMCS_ENTRY_INTERRUPTION_INFO }, + { "capname", REQ_ARG, 0, CAPNAME }, + { "setcap", REQ_ARG, 0, SET_CAP }, + { "getcap", NO_ARG, &getcap, 1 }, + { "get-stats", NO_ARG, &get_stats, 1 }, + { "get-desc-ds",NO_ARG, &get_desc_ds, 1 }, + { "set-desc-ds",NO_ARG, &set_desc_ds, 1 }, + { "get-desc-es",NO_ARG, &get_desc_es, 1 }, + { "set-desc-es",NO_ARG, &set_desc_es, 1 }, + { "get-desc-ss",NO_ARG, &get_desc_ss, 1 }, + { "set-desc-ss",NO_ARG, &set_desc_ss, 1 }, + { "get-desc-cs",NO_ARG, &get_desc_cs, 1 }, + { "set-desc-cs",NO_ARG, &set_desc_cs, 1 }, + { "get-desc-fs",NO_ARG, &get_desc_fs, 1 }, + { "set-desc-fs",NO_ARG, &set_desc_fs, 1 }, + { "get-desc-gs",NO_ARG, &get_desc_gs, 1 }, + { "set-desc-gs",NO_ARG, &set_desc_gs, 1 }, + { "get-desc-tr",NO_ARG, &get_desc_tr, 1 }, + { "set-desc-tr",NO_ARG, &set_desc_tr, 1 }, + { "set-desc-ldtr", NO_ARG, &set_desc_ldtr, 1 }, + { "get-desc-ldtr", NO_ARG, &get_desc_ldtr, 1 }, + { "set-desc-gdtr", NO_ARG, &set_desc_gdtr, 1 }, + { "get-desc-gdtr", NO_ARG, &get_desc_gdtr, 1 }, + { "set-desc-idtr", NO_ARG, &set_desc_idtr, 1 }, + { "get-desc-idtr", NO_ARG, &get_desc_idtr, 1 }, + { "get-lowmem", NO_ARG, &get_lowmem, 1 }, + { "get-highmem",NO_ARG, &get_highmem, 1 }, + { "get-efer", NO_ARG, &get_efer, 1 }, + { "get-cr0", NO_ARG, &get_cr0, 1 }, + { "get-cr3", NO_ARG, &get_cr3, 1 }, + { "get-cr4", NO_ARG, &get_cr4, 1 }, + { "get-dr7", NO_ARG, &get_dr7, 1 }, + { "get-rsp", NO_ARG, &get_rsp, 1 }, + { "get-rip", NO_ARG, &get_rip, 1 }, + { "get-rax", NO_ARG, &get_rax, 1 }, + { "get-rbx", NO_ARG, &get_rbx, 1 }, + { "get-rcx", NO_ARG, &get_rcx, 1 }, + { "get-rdx", NO_ARG, &get_rdx, 1 }, + { "get-rsi", NO_ARG, &get_rsi, 1 }, + { "get-rdi", NO_ARG, &get_rdi, 1 }, + { "get-rbp", NO_ARG, &get_rbp, 1 }, + { "get-r8", NO_ARG, &get_r8, 1 }, + { "get-r9", NO_ARG, &get_r9, 1 }, + { "get-r10", NO_ARG, &get_r10, 1 }, + { "get-r11", NO_ARG, &get_r11, 1 }, + { "get-r12", NO_ARG, &get_r12, 1 }, + { "get-r13", NO_ARG, &get_r13, 1 }, + { "get-r14", NO_ARG, &get_r14, 1 }, + { "get-r15", NO_ARG, &get_r15, 1 }, + { "get-rflags", NO_ARG, &get_rflags, 1 }, + { "get-cs", NO_ARG, &get_cs, 1 }, + { "get-ds", NO_ARG, &get_ds, 1 }, + { "get-es", NO_ARG, &get_es, 1 }, + { "get-fs", NO_ARG, &get_fs, 1 }, + { "get-gs", NO_ARG, &get_gs, 1 }, + { "get-ss", NO_ARG, &get_ss, 1 }, + { "get-tr", NO_ARG, &get_tr, 1 }, + { "get-ldtr", NO_ARG, &get_ldtr, 1 }, + { "get-vmcs-pinbased-ctls", + NO_ARG, &get_pinbased_ctls, 1 }, + { "get-vmcs-procbased-ctls", + NO_ARG, &get_procbased_ctls, 1 }, + { "get-vmcs-procbased-ctls2", + NO_ARG, &get_procbased_ctls2, 1 }, + { "get-vmcs-guest-linear-address", + NO_ARG, &get_vmcs_gla, 1 }, + { "get-vmcs-guest-physical-address", + NO_ARG, &get_vmcs_gpa, 1 }, + { "get-vmcs-entry-interruption-info", + NO_ARG, &get_vmcs_entry_interruption_info, 1}, + { "get-vmcs-eptp", NO_ARG, &get_eptp, 1 }, + { "get-vmcs-exception-bitmap", + NO_ARG, &get_exception_bitmap, 1 }, + { "get-vmcs-io-bitmap-address", + NO_ARG, &get_io_bitmap, 1 }, + { "get-vmcs-tsc-offset", NO_ARG,&get_tsc_offset, 1 }, + { "get-vmcs-cr0-mask", NO_ARG, &get_cr0_mask, 1 }, + { "get-vmcs-cr0-shadow", NO_ARG,&get_cr0_shadow, 1 }, + { "get-vmcs-cr4-mask", NO_ARG, &get_cr4_mask, 1 }, + { "get-vmcs-cr4-shadow", NO_ARG,&get_cr4_shadow, 1 }, + { "get-vmcs-cr3-targets", NO_ARG, &get_cr3_targets, 1}, + { "get-vmcs-apic-access-address", + NO_ARG, &get_apic_access_addr, 1}, + { "get-vmcs-virtual-apic-address", + NO_ARG, &get_virtual_apic_addr, 1}, + { "get-vmcs-tpr-threshold", + NO_ARG, &get_tpr_threshold, 1 }, + { "get-vmcs-msr-bitmap", + NO_ARG, &get_msr_bitmap, 1 }, + { "get-vmcs-msr-bitmap-address", + NO_ARG, &get_msr_bitmap_address, 1 }, + { "get-vmcs-vpid", NO_ARG, &get_vpid, 1 }, + { "get-vmcs-ple-gap", NO_ARG, &get_ple_gap, 1 }, + { "get-vmcs-ple-window", NO_ARG,&get_ple_window,1 }, + { "get-vmcs-instruction-error", + NO_ARG, &get_inst_err, 1 }, + { "get-vmcs-exit-ctls", NO_ARG, &get_exit_ctls, 1 }, + { "get-vmcs-entry-ctls", + NO_ARG, &get_entry_ctls, 1 }, + { "get-vmcs-guest-pat", NO_ARG, &get_guest_pat, 1 }, + { "get-vmcs-host-pat", NO_ARG, &get_host_pat, 1 }, + { "get-vmcs-host-cr0", + NO_ARG, &get_host_cr0, 1 }, + { "get-vmcs-host-cr3", + NO_ARG, &get_host_cr3, 1 }, + { "get-vmcs-host-cr4", + NO_ARG, &get_host_cr4, 1 }, + { "get-vmcs-host-rip", + NO_ARG, &get_host_rip, 1 }, + { "get-vmcs-host-rsp", + NO_ARG, &get_host_rsp, 1 }, + { "get-vmcs-guest-sysenter", + NO_ARG, &get_guest_sysenter, 1 }, + { "get-vmcs-link", NO_ARG, &get_vmcs_link, 1 }, + { "get-vmcs-exit-reason", + NO_ARG, &get_vmcs_exit_reason, 1 }, + { "get-vmcs-exit-qualification", + NO_ARG, &get_vmcs_exit_qualification, 1 }, + { "get-vmcs-exit-interruption-info", + NO_ARG, &get_vmcs_exit_interruption_info, 1}, + { "get-vmcs-exit-interruption-error", + NO_ARG, &get_vmcs_exit_interruption_error, 1}, + { "get-vmcs-interruptibility", + NO_ARG, &get_vmcs_interruptibility, 1 }, + { "get-pinning",NO_ARG, &get_pinning, 1 }, + { "run", NO_ARG, &run, 1 }, + { "create", NO_ARG, &create, 1 }, + { "destroy", NO_ARG, &destroy, 1 }, + { NULL, 0, NULL, 0 } + }; + + vcpu = 0; + progname = basename(argv[0]); + + while ((ch = getopt_long(argc, argv, "", opts, NULL)) != -1) { + switch (ch) { + case 0: + break; + case VMNAME: + vmname = optarg; + break; + case VCPU: + vcpu = atoi(optarg); + break; + case SET_LOWMEM: + lowmem = atoi(optarg) * MB; + lowmem = roundup(lowmem, 2 * MB); + break; + case SET_HIGHMEM: + highmem = atoi(optarg) * MB; + highmem = roundup(highmem, 2 * MB); + break; + case SET_EFER: + efer = strtoul(optarg, NULL, 0); + set_efer = 1; + break; + case SET_CR0: + cr0 = strtoul(optarg, NULL, 0); + set_cr0 = 1; + break; + case SET_CR3: + cr3 = strtoul(optarg, NULL, 0); + set_cr3 = 1; + break; + case SET_CR4: + cr4 = strtoul(optarg, NULL, 0); + set_cr4 = 1; + break; + case SET_DR7: + dr7 = strtoul(optarg, NULL, 0); + set_dr7 = 1; + break; + case SET_RSP: + rsp = strtoul(optarg, NULL, 0); + set_rsp = 1; + break; + case SET_RIP: + rip = strtoul(optarg, NULL, 0); + set_rip = 1; + break; + case SET_RAX: + rax = strtoul(optarg, NULL, 0); + set_rax = 1; + break; + case SET_RFLAGS: + rflags = strtoul(optarg, NULL, 0); + set_rflags = 1; + break; + case DESC_BASE: + desc_base = strtoul(optarg, NULL, 0); + break; + case DESC_LIMIT: + desc_limit = strtoul(optarg, NULL, 0); + break; + case DESC_ACCESS: + desc_access = strtoul(optarg, NULL, 0); + break; + case SET_CS: + cs = strtoul(optarg, NULL, 0); + set_cs = 1; + break; + case SET_DS: + ds = strtoul(optarg, NULL, 0); + set_ds = 1; + break; + case SET_ES: + es = strtoul(optarg, NULL, 0); + set_es = 1; + break; + case SET_FS: + fs = strtoul(optarg, NULL, 0); + set_fs = 1; + break; + case SET_GS: + gs = strtoul(optarg, NULL, 0); + set_gs = 1; + break; + case SET_SS: + ss = strtoul(optarg, NULL, 0); + set_ss = 1; + break; + case SET_TR: + tr = strtoul(optarg, NULL, 0); + set_tr = 1; + break; + case SET_LDTR: + ldtr = strtoul(optarg, NULL, 0); + set_ldtr = 1; + break; + case SET_PINNING: + pincpu = strtol(optarg, NULL, 0); + set_pinning = 1; + break; + case SET_VMCS_EXCEPTION_BITMAP: + exception_bitmap = strtoul(optarg, NULL, 0); + set_exception_bitmap = 1; + break; + case SET_VMCS_ENTRY_INTERRUPTION_INFO: + vmcs_entry_interruption_info = strtoul(optarg, NULL, 0); + set_vmcs_entry_interruption_info = 1; + break; + case SET_CAP: + capval = strtoul(optarg, NULL, 0); + setcap = 1; + break; + case CAPNAME: + capname = optarg; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (vmname == NULL) + usage(); + + error = 0; + + if (!error && create) + error = vm_create(vmname); + + if (!error) { + ctx = vm_open(vmname); + if (ctx == NULL) + error = -1; + } + + if (!error && lowmem) + error = vm_setup_memory(ctx, 0, lowmem, NULL); + + if (!error && highmem) + error = vm_setup_memory(ctx, 4 * GB, highmem, NULL); + + if (!error && set_efer) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_EFER, efer); + + if (!error && set_cr0) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR0, cr0); + + if (!error && set_cr3) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR3, cr3); + + if (!error && set_cr4) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR4, cr4); + + if (!error && set_dr7) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR7, dr7); + + if (!error && set_rsp) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RSP, rsp); + + if (!error && set_rip) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, rip); + + if (!error && set_rax) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, rax); + + if (!error && set_rflags) { + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, + rflags); + } + + if (!error && set_desc_ds) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_DS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_es) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_ES, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_ss) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_SS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_cs) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_CS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_fs) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_FS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_gs) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_tr) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_TR, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_ldtr) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_LDTR, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_gdtr) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GDTR, + desc_base, desc_limit, 0); + } + + if (!error && set_desc_idtr) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_IDTR, + desc_base, desc_limit, 0); + } + + if (!error && set_cs) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CS, cs); + + if (!error && set_ds) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DS, ds); + + if (!error && set_es) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_ES, es); + + if (!error && set_fs) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_FS, fs); + + if (!error && set_gs) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_GS, gs); + + if (!error && set_ss) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_SS, ss); + + if (!error && set_tr) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_TR, tr); + + if (!error && set_ldtr) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_LDTR, ldtr); + + if (!error && set_pinning) + error = vm_set_pinning(ctx, vcpu, pincpu); + + if (!error && set_exception_bitmap) { + error = vm_set_vmcs_field(ctx, vcpu, VMCS_EXCEPTION_BITMAP, + exception_bitmap); + } + + if (!error && set_vmcs_entry_interruption_info) { + error = vm_set_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO, + vmcs_entry_interruption_info); + } + + if (!error && get_lowmem) { + error = vm_get_memory_seg(ctx, 0, &hpa, &len); + if (error == 0) + printf("lowmem\t\t0x%016lx/%ld\n", hpa, len); + } + + if (!error && get_highmem) { + error = vm_get_memory_seg(ctx, 4 * GB, &hpa, &len); + if (error == 0) + printf("highmem\t\t0x%016lx/%ld\n", hpa, len); + } + + if (!error && get_efer) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_EFER, &efer); + if (error == 0) + printf("efer[%d]\t\t0x%016lx\n", vcpu, efer); + } + + if (!error && get_cr0) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR0, &cr0); + if (error == 0) + printf("cr0[%d]\t\t0x%016lx\n", vcpu, cr0); + } + + if (!error && get_cr3) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR3, &cr3); + if (error == 0) + printf("cr3[%d]\t\t0x%016lx\n", vcpu, cr3); + } + + if (!error && get_cr4) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR4, &cr4); + if (error == 0) + printf("cr4[%d]\t\t0x%016lx\n", vcpu, cr4); + } + + if (!error && get_dr7) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR7, &dr7); + if (error == 0) + printf("dr7[%d]\t\t0x%016lx\n", vcpu, dr7); + } + + if (!error && get_rsp) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSP, &rsp); + if (error == 0) + printf("rsp[%d]\t\t0x%016lx\n", vcpu, rsp); + } + + if (!error && get_rip) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip); + if (error == 0) + printf("rip[%d]\t\t0x%016lx\n", vcpu, rip); + } + + if (!error && get_rax) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RAX, &rax); + if (error == 0) + printf("rax[%d]\t\t0x%016lx\n", vcpu, rax); + } + + if (!error && get_rbx) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBX, &rbx); + if (error == 0) + printf("rbx[%d]\t\t0x%016lx\n", vcpu, rbx); + } + + if (!error && get_rcx) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RCX, &rcx); + if (error == 0) + printf("rcx[%d]\t\t0x%016lx\n", vcpu, rcx); + } + + if (!error && get_rdx) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDX, &rdx); + if (error == 0) + printf("rdx[%d]\t\t0x%016lx\n", vcpu, rdx); + } + + if (!error && get_rsi) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSI, &rsi); + if (error == 0) + printf("rsi[%d]\t\t0x%016lx\n", vcpu, rsi); + } + + if (!error && get_rdi) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDI, &rdi); + if (error == 0) + printf("rdi[%d]\t\t0x%016lx\n", vcpu, rdi); + } + + if (!error && get_rbp) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBP, &rbp); + if (error == 0) + printf("rbp[%d]\t\t0x%016lx\n", vcpu, rbp); + } + + if (!error && get_r8) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R8, &r8); + if (error == 0) + printf("r8[%d]\t\t0x%016lx\n", vcpu, r8); + } + + if (!error && get_r9) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R9, &r9); + if (error == 0) + printf("r9[%d]\t\t0x%016lx\n", vcpu, r9); + } + + if (!error && get_r10) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R10, &r10); + if (error == 0) + printf("r10[%d]\t\t0x%016lx\n", vcpu, r10); + } + + if (!error && get_r11) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R11, &r11); + if (error == 0) + printf("r11[%d]\t\t0x%016lx\n", vcpu, r11); + } + + if (!error && get_r12) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R12, &r12); + if (error == 0) + printf("r12[%d]\t\t0x%016lx\n", vcpu, r12); + } + + if (!error && get_r13) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R13, &r13); + if (error == 0) + printf("r13[%d]\t\t0x%016lx\n", vcpu, r13); + } + + if (!error && get_r14) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R14, &r14); + if (error == 0) + printf("r14[%d]\t\t0x%016lx\n", vcpu, r14); + } + + if (!error && get_r15) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R15, &r15); + if (error == 0) + printf("r15[%d]\t\t0x%016lx\n", vcpu, r15); + } + + if (!error && get_rflags) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, + &rflags); + if (error == 0) + printf("rflags[%d]\t0x%016lx\n", vcpu, rflags); + } + + if (!error && get_stats) { + int i, num_stats; + uint64_t *stats; + struct timeval tv; + const char *desc; + + stats = vm_get_stats(ctx, vcpu, &tv, &num_stats); + if (stats != NULL) { + printf("vcpu%d\n", vcpu); + for (i = 0; i < num_stats; i++) { + desc = vm_get_stat_desc(ctx, i); + printf("%-32s\t%ld\n", desc, stats[i]); + } + } + } + + if (!error && get_desc_ds) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_DS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("ds desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && get_desc_es) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_ES, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("es desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && get_desc_fs) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_FS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("fs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && get_desc_gs) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("gs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && get_desc_ss) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_SS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("ss desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && get_desc_cs) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_CS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("cs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && get_desc_tr) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_TR, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("tr desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && get_desc_ldtr) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_LDTR, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("ldtr desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && get_desc_gdtr) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GDTR, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("gdtr[%d]\t\t0x%016lx/0x%08x\n", + vcpu, desc_base, desc_limit); + } + } + + if (!error && get_desc_idtr) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_IDTR, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("idtr[%d]\t\t0x%016lx/0x%08x\n", + vcpu, desc_base, desc_limit); + } + } + + if (!error && get_cs) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CS, &cs); + if (error == 0) + printf("cs[%d]\t\t0x%04lx\n", vcpu, cs); + } + + if (!error && get_ds) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DS, &ds); + if (error == 0) + printf("ds[%d]\t\t0x%04lx\n", vcpu, ds); + } + + if (!error && get_es) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_ES, &es); + if (error == 0) + printf("es[%d]\t\t0x%04lx\n", vcpu, es); + } + + if (!error && get_fs) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_FS, &fs); + if (error == 0) + printf("fs[%d]\t\t0x%04lx\n", vcpu, fs); + } + + if (!error && get_gs) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_GS, &gs); + if (error == 0) + printf("gs[%d]\t\t0x%04lx\n", vcpu, gs); + } + + if (!error && get_ss) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_SS, &ss); + if (error == 0) + printf("ss[%d]\t\t0x%04lx\n", vcpu, ss); + } + + if (!error && get_tr) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_TR, &tr); + if (error == 0) + printf("tr[%d]\t\t0x%04lx\n", vcpu, tr); + } + + if (!error && get_ldtr) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_LDTR, &ldtr); + if (error == 0) + printf("ldtr[%d]\t\t0x%04lx\n", vcpu, ldtr); + } + + if (!error && get_pinning) { + error = vm_get_pinning(ctx, vcpu, &pincpu); + if (error == 0) { + if (pincpu < 0) + printf("pincpu[%d]\tunpinned\n", vcpu); + else + printf("pincpu[%d]\t%d\n", vcpu, pincpu); + } + } + + if (!error && get_pinbased_ctls) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_PIN_BASED_CTLS, &ctl); + if (error == 0) + printf("pinbased_ctls[%d]\t0x%08x\n", vcpu, ctl); + } + + if (!error && get_procbased_ctls) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_PRI_PROC_BASED_CTLS, &ctl); + if (error == 0) + printf("procbased_ctls[%d]\t0x%08x\n", vcpu, ctl); + } + + if (!error && get_procbased_ctls2) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_SEC_PROC_BASED_CTLS, &ctl); + if (error == 0) + printf("procbased_ctls2[%d]\t0x%08x\n", vcpu, ctl); + } + + if (!error && get_vmcs_gla) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_LINEAR_ADDRESS, &u64); + if (error == 0) + printf("gla[%d]\t\t0x%016lx\n", vcpu, u64); + } + + if (!error && get_vmcs_gpa) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_PHYSICAL_ADDRESS, &u64); + if (error == 0) + printf("gpa[%d]\t\t0x%016lx\n", vcpu, u64); + } + + if (!error && get_vmcs_entry_interruption_info) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,&u64); + if (error == 0) { + printf("entry_interruption_info[%d]\t0x%08x\n", + vcpu, u64); + } + } + + if (!error && get_eptp) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EPTP, &eptp); + if (error == 0) + printf("eptp[%d]\t\t0x%016lx\n", vcpu, eptp); + } + + if (!error && get_exception_bitmap) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXCEPTION_BITMAP, + &bm); + if (error == 0) + printf("exception_bitmap[%d]\t0x%08x\n", vcpu, bm); + } + + if (!error && get_io_bitmap) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_A, &bm); + if (error == 0) + printf("io_bitmap_a[%d]\t0x%08x\n", vcpu, bm); + error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_B, &bm); + if (error == 0) + printf("io_bitmap_b[%d]\t0x%08x\n", vcpu, bm); + } + + if (!error && get_tsc_offset) { + uint64_t tscoff; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_TSC_OFFSET, &tscoff); + if (error == 0) + printf("tsc_offset[%d]\t0x%016lx\n", tscoff); + } + + if (!error && get_cr0_mask) { + uint64_t cr0mask; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_MASK, &cr0mask); + if (error == 0) + printf("cr0_mask[%d]\t\t0x%016lx\n", cr0mask); + } + + if (!error && get_cr0_shadow) { + uint64_t cr0shadow; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_SHADOW, + &cr0shadow); + if (error == 0) + printf("cr0_shadow[%d]\t\t0x%016lx\n", cr0shadow); + } + + if (!error && get_cr4_mask) { + uint64_t cr4mask; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_MASK, &cr4mask); + if (error == 0) + printf("cr4_mask[%d]\t\t0x%016lx\n", cr4mask); + } + + if (!error && get_cr4_shadow) { + uint64_t cr4shadow; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_SHADOW, + &cr4shadow); + if (error == 0) + printf("cr4_shadow[%d]\t\t0x%016lx\n", cr4shadow); + } + + if (!error && get_cr3_targets) { + uint64_t target_count, target_addr; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET_COUNT, + &target_count); + if (error == 0) { + printf("cr3_target_count[%d]\t0x%08x\n", + vcpu, target_count); + } + + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET0, + &target_addr); + if (error == 0) { + printf("cr3_target0[%d]\t\t0x%016lx\n", + vcpu, target_addr); + } + + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET1, + &target_addr); + if (error == 0) { + printf("cr3_target1[%d]\t\t0x%016lx\n", + vcpu, target_addr); + } + + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET2, + &target_addr); + if (error == 0) { + printf("cr3_target2[%d]\t\t0x%016lx\n", + vcpu, target_addr); + } + + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET3, + &target_addr); + if (error == 0) { + printf("cr3_target3[%d]\t\t0x%016lx\n", + vcpu, target_addr); + } + } + + if (!error && get_apic_access_addr) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_APIC_ACCESS, &addr); + if (error == 0) + printf("apic_access_addr[%d]\t0x%016lx\n", vcpu, addr); + } + + if (!error && get_virtual_apic_addr) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_VIRTUAL_APIC, &addr); + if (error == 0) + printf("virtual_apic_addr[%d]\t0x%016lx\n", vcpu, addr); + } + + if (!error && get_tpr_threshold) { + uint64_t threshold; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_TPR_THRESHOLD, + &threshold); + if (error == 0) + printf("tpr_threshold[%d]\t0x%08x\n", vcpu, threshold); + } + + if (!error && get_msr_bitmap_address) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP, &addr); + if (error == 0) + printf("msr_bitmap[%d]\t\t0x%016lx\n", vcpu, addr); + } + + if (!error && get_msr_bitmap) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP, &addr); + if (error == 0) + error = dump_vmcs_msr_bitmap(vcpu, addr); + } + + if (!error && get_vpid) { + uint64_t vpid; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_VPID, &vpid); + if (error == 0) + printf("vpid[%d]\t\t0x%04x\n", vcpu, vpid); + } + + if (!error && get_ple_window) { + uint64_t window; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_PLE_WINDOW, &window); + if (error == 0) + printf("ple_window[%d]\t\t0x%08x\n", vcpu, window); + } + + if (!error && get_ple_gap) { + uint64_t gap; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_PLE_GAP, &gap); + if (error == 0) + printf("ple_gap[%d]\t\t0x%08x\n", vcpu, gap); + } + + if (!error && get_inst_err) { + uint64_t insterr; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_INSTRUCTION_ERROR, + &insterr); + if (error == 0) { + printf("instruction_error[%d]\t0x%08x\n", + vcpu, insterr); + } + } + + if (!error && get_exit_ctls) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_CTLS, &ctl); + if (error == 0) + printf("exit_ctls[%d]\t\t0x%08x\n", vcpu, ctl); + } + + if (!error && get_entry_ctls) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_CTLS, &ctl); + if (error == 0) + printf("entry_ctls[%d]\t\t0x%08x\n", vcpu, ctl); + } + + if (!error && get_host_pat) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_IA32_PAT, &pat); + if (error == 0) + printf("host_pat[%d]\t\t0x%016lx\n", vcpu, pat); + } + + if (!error && get_guest_pat) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_IA32_PAT, &pat); + if (error == 0) + printf("guest_pat[%d]\t\t0x%016lx\n", vcpu, pat); + } + + if (!error && get_host_cr0) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR0, &cr0); + if (error == 0) + printf("host_cr0[%d]\t\t0x%016lx\n", vcpu, cr0); + } + + if (!error && get_host_cr3) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR3, &cr3); + if (error == 0) + printf("host_cr3[%d]\t\t0x%016lx\n", vcpu, cr3); + } + + if (!error && get_host_cr4) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR4, &cr4); + if (error == 0) + printf("host_cr4[%d]\t\t0x%016lx\n", vcpu, cr4); + } + + if (!error && get_host_rip) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RIP, &rip); + if (error == 0) + printf("host_rip[%d]\t\t0x%016lx\n", vcpu, rip); + } + + if (!error && get_host_rsp) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RSP, &rsp); + if (error == 0) + printf("host_rip[%d]\t\t0x%016lx\n", vcpu, rsp); + } + + if (!error && get_guest_sysenter) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_IA32_SYSENTER_CS, &cs); + if (error == 0) + printf("guest_sysenter_cs[%d]\t0x%08x\n", vcpu, cs); + + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_IA32_SYSENTER_ESP, &rsp); + if (error == 0) + printf("guest_sysenter_sp[%d]\t0x%016lx\n", vcpu, rsp); + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_IA32_SYSENTER_EIP, &rip); + if (error == 0) + printf("guest_sysenter_ip[%d]\t0x%016lx\n", vcpu, rip); + } + + if (!error && get_vmcs_link) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_LINK_POINTER, &addr); + if (error == 0) + printf("vmcs_pointer[%d]\t0x%016lx\n", vcpu, addr); + } + + if (!error && get_vmcs_exit_reason) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_REASON, &u64); + if (error == 0) + printf("vmcs_exit_reason[%d]\t0x%016lx\n", vcpu, u64); + } + + if (!error && get_vmcs_exit_qualification) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_QUALIFICATION, + &u64); + if (error == 0) + printf("vmcs_exit_qualification[%d]\t0x%016lx\n", + vcpu, u64); + } + + if (!error && get_vmcs_exit_interruption_info) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_EXIT_INTERRUPTION_INFO, &u64); + if (error == 0) { + printf("vmcs_exit_interruption_info[%d]\t0x%08x\n", + vcpu, u64); + } + } + + if (!error && get_vmcs_exit_interruption_error) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_EXIT_INTERRUPTION_ERROR, &u64); + if (error == 0) { + printf("vmcs_exit_interruption_error[%d]\t0x%08x\n", + vcpu, u64); + } + } + + if (!error && get_vmcs_interruptibility) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_INTERRUPTIBILITY, &u64); + if (error == 0) { + printf("vmcs_guest_interruptibility[%d]\t0x%08x\n", + vcpu, u64); + } + } + + if (!error && setcap) { + int captype; + captype = vm_capability_name2type(capname); + error = vm_set_capability(ctx, vcpu, captype, capval); + if (error != 0 && errno == ENOENT) + printf("Capability \"%s\" is not available\n", capname); + } + + if (!error && getcap) { + int captype, val; + captype = vm_capability_name2type(capname); + error = vm_get_capability(ctx, vcpu, captype, &val); + if (error == 0) { + printf("Capability \"%s\" is %s on vcpu %d\n", capname, + val ? "set" : "not set", vcpu); + } else if (errno == ENOENT) { + printf("Capability \"%s\" is not available\n", capname); + } + } + + if (!error && run) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip); + assert(error == 0); + + error = vm_run(ctx, vcpu, rip, &vmexit); + if (error == 0) + dump_vm_run_exitcode(&vmexit, vcpu); + else + printf("vm_run error %d\n", error); + } + + if (error) + printf("errno = %d\n", errno); + + if (!error && destroy) + vm_destroy(ctx); + + exit(error); +} From 6c4c7d0f96c632ef104b202a633a06db33f74d6b Mon Sep 17 00:00:00 2001 From: Peter Grehan Date: Sat, 14 May 2011 18:37:24 +0000 Subject: [PATCH 2592/2592] bhyve import part 2 of 2, guest kernel changes. This branch is now considered frozen: future bhyve development will take place in a branch off -CURRENT. sys/dev/bvm/bvm_console.c sys/dev/bvm/bvm_dbg.c - simple console driver/gdb debug port used for bringup. supported by user-space bhyve executable sys/conf/options.amd64 sys/amd64/amd64/minidump_machdep.c - allow NKPT to be set in the kernel config file sys/amd64/conf/GENERIC - mptable config options; bhyve user-space executable creates an mptable with number of CPUs, and optional vendor extension - add bvm console/debug - set NKPT to 512 to allow loading of large RAM disks from the loader - include kdb/gdb sys/amd64/amd64/local_apic.c sys/amd64/amd64/apic_vector.S sys/amd64/include/specialreg.h - if x2apic mode available, use MSRs to access the local APIC, otherwise fall back to 'classic' MMIO mode sys/amd64/amd64/mp_machdep.c - support AP spinup on CPU models that don't have real-mode support by overwriting the real-mode page with a message that supplies the bhyve user-space executable with enough information to start the AP directly in 64-bit mode. sys/amd64/amd64/vm_machdep.c - insert pause statements into cpu shutdown busy-wait loops sys/dev/blackhole/blackhole.c sys/modules/blackhole/Makefile - boot-time loadable module that claims all PCI bus/slot/funcs specified in an env var that are to be used for PCI passthrough sys/amd64/amd64/intr_machdep.c - allow round-robin assignment of device interrupts to CPUs to be disabled from the loader sys/amd64/include/bus.h - convert string ins/outs instructions to loops of individual in/out since bhyve doesn't support these yet sys/kern/subr_bus.c - if the device was no created with a fixed devclass, then remove it's association with the devclass it was associated with during probe. Otherwise, new drivers do not get a chance to probe/attach since the device will stay married to the first driver that it probed successfully but failed to attach. Sponsored by: NetApp, Inc. --- sys/amd64/amd64/apic_vector.S | 53 +++- sys/amd64/amd64/intr_machdep.c | 6 + sys/amd64/amd64/local_apic.c | 494 +++++++++++++++++++++++++---- sys/amd64/amd64/minidump_machdep.c | 1 + sys/amd64/amd64/mp_machdep.c | 43 +++ sys/amd64/amd64/vm_machdep.c | 11 +- sys/amd64/conf/GENERIC | 11 + sys/amd64/include/bus.h | 60 ++-- sys/amd64/include/specialreg.h | 33 +- sys/conf/files.amd64 | 5 + sys/conf/options.amd64 | 1 + sys/dev/blackhole/blackhole.c | 129 ++++++++ sys/dev/bvm/bvm_console.c | 242 ++++++++++++++ sys/dev/bvm/bvm_dbg.c | 90 ++++++ sys/kern/subr_bus.c | 2 +- sys/modules/Makefile | 2 + sys/modules/blackhole/Makefile | 9 + 17 files changed, 1089 insertions(+), 103 deletions(-) create mode 100644 sys/dev/blackhole/blackhole.c create mode 100644 sys/dev/bvm/bvm_console.c create mode 100644 sys/dev/bvm/bvm_dbg.c create mode 100644 sys/modules/blackhole/Makefile diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 4cfc18b5fde..6e9aa79ddf8 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -55,7 +55,14 @@ IDTVEC(vec_name) ; \ PUSH_FRAME ; \ FAKE_MCOUNT(TF_RIP(%rsp)) ; \ movq lapic, %rdx ; /* pointer to local APIC */ \ + testq %rdx, %rdx; \ + jnz 3f; \ + movl $MSR_APIC_ISR ## index, %ecx; \ + rdmsr; \ + jmp 4f; \ +3: ; \ movl LA_ISR + 16 * (index)(%rdx), %eax ; /* load ISR */ \ +4: ; \ bsrl %eax, %eax ; /* index of highset set bit in ISR */ \ jz 2f ; \ addl $(32 * index),%eax ; \ @@ -117,6 +124,26 @@ IDTVEC(errorint) jmp doreti #ifdef SMP + +/* + * We assume that %rax is being saved/restored outside of this macro + */ +#define DO_EOI \ + movq lapic, %rax; \ + testq %rax, %rax; \ + jz 8f; \ + movl $0, LA_EOI(%rax); \ + jmp 9f; \ +8:; \ + pushq %rcx; \ + pushq %rdx; \ + xorl %edx, %edx; /* eax is already zero */ \ + movl $MSR_APIC_EOI, %ecx; \ + wrmsr; \ + popq %rdx; \ + popq %rcx; \ +9: + /* * Global address space TLB shootdown. */ @@ -128,8 +155,7 @@ IDTVEC(invltlb) movq %cr3, %rax /* invalidate the TLB */ movq %rax, %cr3 - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI lock incl smp_tlb_wait @@ -148,8 +174,7 @@ IDTVEC(invlpg) movq smp_tlb_addr1, %rax invlpg (%rax) /* invalidate single page */ - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI lock incl smp_tlb_wait @@ -173,8 +198,7 @@ IDTVEC(invlrng) cmpq %rax, %rdx jb 1b - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI lock incl smp_tlb_wait @@ -193,8 +217,7 @@ IDTVEC(invlcache) wbinvd - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI lock incl smp_tlb_wait @@ -210,9 +233,8 @@ IDTVEC(invlcache) IDTVEC(ipi_intr_bitmap_handler) PUSH_FRAME - movq lapic, %rdx - movl $0, LA_EOI(%rdx) /* End Of Interrupt to APIC */ - + DO_EOI + FAKE_MCOUNT(TF_RIP(%rsp)) call ipi_bitmap_handler @@ -227,8 +249,7 @@ IDTVEC(ipi_intr_bitmap_handler) IDTVEC(cpustop) PUSH_FRAME - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI call cpustop_handler jmp doreti @@ -241,8 +262,7 @@ IDTVEC(cpustop) IDTVEC(cpususpend) PUSH_FRAME - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI call cpususpend_handler @@ -259,7 +279,6 @@ IDTVEC(cpususpend) IDTVEC(rendezvous) PUSH_FRAME call smp_rendezvous_action - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI jmp doreti #endif /* SMP */ diff --git a/sys/amd64/amd64/intr_machdep.c b/sys/amd64/amd64/intr_machdep.c index 6ab80df9d87..941cecf14a3 100644 --- a/sys/amd64/amd64/intr_machdep.c +++ b/sys/amd64/amd64/intr_machdep.c @@ -78,6 +78,8 @@ static STAILQ_HEAD(, pic) pics; #ifdef SMP static int assign_cpu; +static int round_robin_interrupts = 1; +TUNABLE_INT("round_robin_interrupts", &round_robin_interrupts); #endif static int intr_assign_cpu(void *arg, u_char cpu); @@ -460,6 +462,10 @@ intr_next_cpu(void) if (!assign_cpu) return (cpu_apic_ids[0]); + /* All interrupts go to the BSP if not allowed to round robin */ + if (!round_robin_interrupts) + return (cpu_apic_ids[0]); + mtx_lock_spin(&icu_lock); apic_id = cpu_apic_ids[current_cpu]; do { diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c index 8edc971c95c..f5c29388429 100644 --- a/sys/amd64/amd64/local_apic.c +++ b/sys/amd64/amd64/local_apic.c @@ -148,6 +148,7 @@ volatile lapic_t *lapic; vm_paddr_t lapic_paddr; static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz; static enum lapic_clock clockcoverage; +static int x2apic; static void lapic_enable(void); static void lapic_resume(struct pic *pic); @@ -156,6 +157,36 @@ static void lapic_timer_oneshot(u_int count); static void lapic_timer_periodic(u_int count); static void lapic_timer_set_divisor(u_int divisor); static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value); +static uint32_t lapic_version(void); +static uint32_t lapic_ldr(void); +static uint32_t lapic_dfr(void); +static uint32_t lapic_lvt_lint0(void); +static void lapic_set_lvt_lint0(uint32_t value); +static uint32_t lapic_lvt_lint1(void); +static void lapic_set_lvt_lint1(uint32_t value); +static uint32_t lapic_tpr(void); +static uint32_t lapic_svr(void); +static void lapic_set_svr(uint32_t value); +static uint32_t lapic_lvt_timer(void); +static void lapic_set_lvt_timer(uint32_t value); +static uint32_t lapic_lvt_thermal(void); +static uint32_t lapic_lvt_error(void); +static void lapic_set_lvt_error(uint32_t value); +static uint32_t lapic_lvt_pcint(void); +static void lapic_set_lvt_pcint(uint32_t value); +static uint32_t lapic_esr(void); +static void lapic_set_esr(uint32_t value); +static uint32_t lapic_ccr_timer(void); +static void lapic_set_dcr_timer(uint32_t value); +static void lapic_set_icr_timer(uint32_t value); +uint32_t lapic_irr(int num); +uint32_t lapic_tmr(int num); +uint32_t lapic_isr(int num); +static uint32_t lapic_icr_lo(void); +static void lapic_set_icr_lo(uint32_t value); +static uint32_t lapic_icr_hi(void); +static void lapic_set_icr_hi(uint32_t value); +static boolean_t lapic_missing(void); struct pic lapic_pic = { .pic_resume = lapic_resume }; @@ -206,12 +237,20 @@ lvt_mode(struct lapic *la, u_int pin, uint32_t value) void lapic_init(vm_paddr_t addr) { - - /* Map the local APIC and setup the spurious interrupt handler. */ - KASSERT(trunc_page(addr) == addr, - ("local APIC not aligned on a page boundary")); - lapic = pmap_mapdev(addr, sizeof(lapic_t)); - lapic_paddr = addr; + if ((cpu_feature2 & CPUID2_X2APIC) != 0 && + (rdmsr(MSR_APICBASE) & APICBASE_X2APIC) != 0) { + x2apic = 1; + if (bootverbose) + printf("Local APIC access using x2APIC MSRs\n"); + } else { + /* + * Map the local APIC and setup the spurious interrupt handler. + */ + KASSERT(trunc_page(addr) == addr, + ("local APIC not aligned on a page boundary")); + lapic = pmap_mapdev(addr, sizeof(lapic_t)); + lapic_paddr = addr; + } setidt(APIC_SPURIOUS_INT, IDTVEC(spuriousint), SDT_SYSIGT, SEL_KPL, 0); /* Perform basic initialization of the BSP's local APIC. */ @@ -276,12 +315,12 @@ lapic_dump(const char* str) printf("cpu%d %s:\n", PCPU_GET(cpuid), str); printf(" ID: 0x%08x VER: 0x%08x LDR: 0x%08x DFR: 0x%08x\n", - lapic->id, lapic->version, lapic->ldr, lapic->dfr); + lapic_id(), lapic_version(), lapic_ldr(), lapic_dfr()); printf(" lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n", - lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr); + lapic_lvt_lint0(), lapic_lvt_lint1(), lapic_tpr(), lapic_svr()); printf(" timer: 0x%08x therm: 0x%08x err: 0x%08x pmc: 0x%08x\n", - lapic->lvt_timer, lapic->lvt_thermal, lapic->lvt_error, - lapic->lvt_pcint); + lapic_lvt_timer(), lapic_lvt_thermal(), lapic_lvt_error(), + lapic_lvt_pcint()); } void @@ -295,7 +334,7 @@ lapic_setup(int boot) la = &lapics[lapic_id()]; KASSERT(la->la_present, ("missing APIC structure")); eflags = intr_disable(); - maxlvt = (lapic->version & APIC_VER_MAXLVT) >> MAXLVTSHIFT; + maxlvt = (lapic_version() & APIC_VER_MAXLVT) >> MAXLVTSHIFT; /* Initialize the TPR to allow all interrupts. */ lapic_set_tpr(0); @@ -304,15 +343,15 @@ lapic_setup(int boot) lapic_enable(); /* Program LINT[01] LVT entries. */ - lapic->lvt_lint0 = lvt_mode(la, LVT_LINT0, lapic->lvt_lint0); - lapic->lvt_lint1 = lvt_mode(la, LVT_LINT1, lapic->lvt_lint1); + lapic_set_lvt_lint0(lvt_mode(la, LVT_LINT0, lapic_lvt_lint0())); + lapic_set_lvt_lint1(lvt_mode(la, LVT_LINT1, lapic_lvt_lint1())); /* Program the PMC LVT entry if present. */ if (maxlvt >= LVT_PMC) - lapic->lvt_pcint = lvt_mode(la, LVT_PMC, lapic->lvt_pcint); + lapic_set_lvt_pcint(lvt_mode(la, LVT_PMC, lapic_lvt_pcint())); /* Program timer LVT and setup handler. */ - lapic->lvt_timer = lvt_mode(la, LVT_TIMER, lapic->lvt_timer); + lapic_set_lvt_timer(lvt_mode(la, LVT_TIMER, lapic_lvt_timer())); if (boot) { snprintf(buf, sizeof(buf), "cpu%d: timer", PCPU_GET(cpuid)); intrcnt_add(buf, &la->la_timer_count); @@ -328,8 +367,8 @@ lapic_setup(int boot) } /* Program error LVT and clear any existing errors. */ - lapic->lvt_error = lvt_mode(la, LVT_ERROR, lapic->lvt_error); - lapic->esr = 0; + lapic_set_lvt_error(lvt_mode(la, LVT_ERROR, lapic_lvt_error())); + lapic_set_esr(0); /* XXX: Thermal LVT */ @@ -342,9 +381,9 @@ lapic_reenable_pmc(void) #ifdef HWPMC_HOOKS uint32_t value; - value = lapic->lvt_pcint; + value = lapic_lvt_pcint(); value &= ~APIC_LVT_M; - lapic->lvt_pcint = value; + lapic_set_lvt_pcint(value); #endif } @@ -355,7 +394,7 @@ lapic_update_pmc(void *dummy) struct lapic *la; la = &lapics[lapic_id()]; - lapic->lvt_pcint = lvt_mode(la, LVT_PMC, lapic->lvt_pcint); + lapic_set_lvt_pcint(lvt_mode(la, LVT_PMC, lapic_lvt_pcint())); } #endif @@ -366,11 +405,11 @@ lapic_enable_pmc(void) u_int32_t maxlvt; /* Fail if the local APIC is not present. */ - if (lapic == NULL) + if (lapic_missing()) return (0); /* Fail if the PMC LVT is not present. */ - maxlvt = (lapic->version & APIC_VER_MAXLVT) >> MAXLVTSHIFT; + maxlvt = (lapic_version() & APIC_VER_MAXLVT) >> MAXLVTSHIFT; if (maxlvt < LVT_PMC) return (0); @@ -400,11 +439,11 @@ lapic_disable_pmc(void) u_int32_t maxlvt; /* Fail if the local APIC is not present. */ - if (lapic == NULL) + if (lapic_missing()) return; /* Fail if the PMC LVT is not present. */ - maxlvt = (lapic->version & APIC_VER_MAXLVT) >> MAXLVTSHIFT; + maxlvt = (lapic_version() & APIC_VER_MAXLVT) >> MAXLVTSHIFT; if (maxlvt < LVT_PMC) return; @@ -435,7 +474,7 @@ lapic_setup_clock(enum lapic_clock srcsdes) MPASS(srcsdes != LAPIC_CLOCK_NONE); /* Can't drive the timer without a local APIC. */ - if (lapic == NULL || + if (lapic_missing() || (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)) { clockcoverage = LAPIC_CLOCK_NONE; return (clockcoverage); @@ -449,7 +488,7 @@ lapic_setup_clock(enum lapic_clock srcsdes) lapic_timer_set_divisor(lapic_timer_divisor); lapic_timer_oneshot(APIC_TIMER_MAX_COUNT); DELAY(2000000); - value = APIC_TIMER_MAX_COUNT - lapic->ccr_timer; + value = APIC_TIMER_MAX_COUNT - lapic_ccr_timer(); if (value != APIC_TIMER_MAX_COUNT) break; lapic_timer_divisor <<= 1; @@ -509,9 +548,9 @@ lapic_disable(void) uint32_t value; /* Software disable the local APIC. */ - value = lapic->svr; + value = lapic_svr(); value &= ~APIC_SVR_SWEN; - lapic->svr = value; + lapic_set_svr(value); } static void @@ -520,10 +559,10 @@ lapic_enable(void) u_int32_t value; /* Program the spurious vector to enable the local APIC. */ - value = lapic->svr; + value = lapic_svr(); value &= ~(APIC_SVR_VECTOR | APIC_SVR_FOCUS); value |= (APIC_SVR_FEN | APIC_SVR_SWEN | APIC_SPURIOUS_INT); - lapic->svr = value; + lapic_set_svr(value); } /* Reset the local APIC on the BSP during resume. */ @@ -534,19 +573,342 @@ lapic_resume(struct pic *pic) lapic_setup(0); } +static uint32_t +lapic_version(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_VERSION)); + else + return (lapic->version); +} + +static uint32_t +lapic_ldr(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_LDR)); + else + return (lapic->ldr); +} + +static uint32_t +lapic_dfr(void) +{ + + if (x2apic) + return (0xffffffff); /* DFR not available in x2APIC mode */ + else + return (lapic->dfr); +} + +static uint32_t +lapic_lvt_lint0(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_LVT_LINT0)); + else + return (lapic->lvt_lint0); +} + +static void +lapic_set_lvt_lint0(uint32_t value) +{ + + if (x2apic) + wrmsr(MSR_APIC_LVT_LINT0, value); + else + lapic->lvt_lint0 = value; +} + +static uint32_t +lapic_lvt_lint1(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_LVT_LINT1)); + else + return (lapic->lvt_lint1); +} + +static void +lapic_set_lvt_lint1(uint32_t value) +{ + + if (x2apic) + wrmsr(MSR_APIC_LVT_LINT1, value); + else + lapic->lvt_lint1 = value; +} + +static uint32_t +lapic_tpr(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_TPR)); + else + return (lapic->tpr); +} + +static uint32_t +lapic_svr(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_SVR)); + else + return (lapic->svr); +} + +static void +lapic_set_svr(uint32_t value) +{ + + if (x2apic) + wrmsr(MSR_APIC_SVR, value); + else + lapic->svr = value; +} + +static uint32_t +lapic_lvt_timer(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_LVT_TIMER)); + else + return (lapic->lvt_timer); +} + +static void +lapic_set_lvt_timer(uint32_t value) +{ + + if (x2apic) + wrmsr(MSR_APIC_LVT_TIMER, value); + else + lapic->lvt_timer = value; +} + +static uint32_t +lapic_lvt_thermal(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_LVT_THERMAL)); + else + return (lapic->lvt_thermal); +} + +static uint32_t +lapic_lvt_error(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_LVT_ERROR)); + else + return (lapic->lvt_error); +} + +static void +lapic_set_lvt_error(uint32_t value) +{ + + if (x2apic) + wrmsr(MSR_APIC_LVT_ERROR, value); + else + lapic->lvt_error = value; +} + +static uint32_t +lapic_lvt_pcint(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_LVT_PCINT)); + else + return (lapic->lvt_pcint); +} + +static void +lapic_set_lvt_pcint(uint32_t value) +{ + + if (x2apic) + wrmsr(MSR_APIC_LVT_PCINT, value); + else + lapic->lvt_pcint = value; +} + +static uint32_t +lapic_esr(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_ESR)); + else + return (lapic->esr); +} + +static void +lapic_set_esr(uint32_t value) +{ + + if (x2apic) + wrmsr(MSR_APIC_ESR, value); + else + lapic->esr = value; +} + +static uint32_t +lapic_ccr_timer(void) +{ + + if (x2apic) + return (rdmsr(MSR_APIC_CCR_TIMER)); + else + return (lapic->ccr_timer); +} + +static void +lapic_set_dcr_timer(uint32_t value) +{ + + if (x2apic) + wrmsr(MSR_APIC_DCR_TIMER, value); + else + lapic->dcr_timer = value; +} + +static void +lapic_set_icr_timer(uint32_t value) +{ + + if (x2apic) + wrmsr(MSR_APIC_ICR_TIMER, value); + else + lapic->icr_timer = value; +} + +uint32_t +lapic_tmr(int num) +{ + int msr; + volatile uint32_t *regptr; + + KASSERT(num >= 0 && num < 8, ("lapic_tmr: invalid num %d", num)); + + if (x2apic) { + msr = MSR_APIC_TMR0 + num; + return (rdmsr(msr)); + } else { + regptr = &lapic->tmr0; + return (regptr[num * 4]); + } +} + +uint32_t +lapic_irr(int num) +{ + int msr; + volatile uint32_t *regptr; + + KASSERT(num >= 0 && num < 8, ("lapic_irr: invalid num %d", num)); + + if (x2apic) { + msr = MSR_APIC_IRR0 + num; + return (rdmsr(msr)); + } else { + regptr = &lapic->irr0; + return (regptr[num * 4]); + } +} + +uint32_t +lapic_isr(int num) +{ + int msr; + volatile uint32_t *regptr; + + KASSERT(num >= 0 && num < 8, ("lapic_isr: invalid num %d", num)); + + if (x2apic) { + msr = MSR_APIC_ISR0 + num; + return (rdmsr(msr)); + } else { + regptr = &lapic->isr0; + return (regptr[num * 4]); + } +} + +static uint32_t icr_hi_stashed[MAXCPU]; + +static uint32_t +lapic_icr_lo(void) +{ + + if (x2apic) + return (0); + else + return (lapic->icr_lo); +} + +static void +lapic_set_icr_lo(uint32_t value) +{ + + if (x2apic) { + wrmsr(MSR_APIC_ICR, + (uint64_t)icr_hi_stashed[curcpu] << 32 | value); + } else + lapic->icr_lo = value; +} + +static uint32_t +lapic_icr_hi(void) +{ + + if (x2apic) + return (0); + else + return (lapic->icr_hi); +} + +static void +lapic_set_icr_hi(uint32_t value) +{ + if (x2apic) + icr_hi_stashed[curcpu] = value >> APIC_ID_SHIFT; /* XXX */ + else + lapic->icr_hi = value; +} + +static boolean_t +lapic_missing(void) +{ + + if (x2apic == 0 && lapic == NULL) + return (TRUE); + else + return (FALSE); +} + int lapic_id(void) { - KASSERT(lapic != NULL, ("local APIC is not mapped")); - return (lapic->id >> APIC_ID_SHIFT); + if (x2apic) + return (rdmsr(MSR_APIC_ID)); + else + return (lapic->id >> APIC_ID_SHIFT); } int lapic_intr_pending(u_int vector) { - volatile u_int32_t *irr; - /* * The IRR registers are an array of 128-bit registers each of * which only describes 32 interrupts in the low 32 bits.. Thus, @@ -556,8 +918,7 @@ lapic_intr_pending(u_int vector) * modulus the vector by 32 to determine the individual bit to * test. */ - irr = &lapic->irr0; - return (irr[(vector / 32) * 4] & 1 << (vector % 32)); + return (lapic_irr(vector / 32) & 1 << (vector % 32)); } void @@ -713,13 +1074,19 @@ void lapic_set_tpr(u_int vector) { #ifdef CHEAP_TPR - lapic->tpr = vector; + if (x2apic) + wrmsr(MSR_APIC_TPR, vector); + else + lapic->tpr = vector; #else u_int32_t tpr; - tpr = lapic->tpr & ~APIC_TPR_PRIO; + tpr = lapic_tpr() & ~APIC_TPR_PRIO; tpr |= vector; - lapic->tpr = tpr; + if (x2apic) + wrmsr(MSR_APIC_TPR, tpr); + else + lapic->tpr = tpr; #endif } @@ -727,7 +1094,10 @@ void lapic_eoi(void) { - lapic->eoi = 0; + if (x2apic) + wrmsr(MSR_APIC_EOI, 0); + else + lapic->eoi = 0; } void @@ -819,7 +1189,7 @@ lapic_timer_set_divisor(u_int divisor) KASSERT(powerof2(divisor), ("lapic: invalid divisor %u", divisor)); KASSERT(ffs(divisor) <= sizeof(lapic_timer_divisors) / sizeof(u_int32_t), ("lapic: invalid divisor %u", divisor)); - lapic->dcr_timer = lapic_timer_divisors[ffs(divisor) - 1]; + lapic_set_dcr_timer(lapic_timer_divisors[ffs(divisor) - 1]); } static void @@ -827,11 +1197,11 @@ lapic_timer_oneshot(u_int count) { u_int32_t value; - value = lapic->lvt_timer; + value = lapic_lvt_timer(); value &= ~APIC_LVTT_TM; value |= APIC_LVTT_TM_ONE_SHOT; - lapic->lvt_timer = value; - lapic->icr_timer = count; + lapic_set_lvt_timer(value); + lapic_set_icr_timer(count); } static void @@ -839,11 +1209,11 @@ lapic_timer_periodic(u_int count) { u_int32_t value; - value = lapic->lvt_timer; + value = lapic_lvt_timer(); value &= ~APIC_LVTT_TM; value |= APIC_LVTT_TM_PERIODIC; - lapic->lvt_timer = value; - lapic->icr_timer = count; + lapic_set_lvt_timer(value); + lapic_set_icr_timer(count); } static void @@ -851,9 +1221,9 @@ lapic_timer_enable_intr(void) { u_int32_t value; - value = lapic->lvt_timer; + value = lapic_lvt_timer(); value &= ~APIC_LVT_M; - lapic->lvt_timer = value; + lapic_set_lvt_timer(value); } void @@ -867,8 +1237,8 @@ lapic_handle_error(void) * to update its value to indicate any errors that have * occurred since the previous write to the register. */ - lapic->esr = 0; - esr = lapic->esr; + lapic_set_esr(0); + esr = lapic_esr(); printf("CPU%d: local APIC error 0x%x\n", PCPU_GET(cpuid), esr); lapic_eoi(); @@ -1115,17 +1485,17 @@ DB_SHOW_COMMAND(lapic, db_show_lapic) uint32_t v; db_printf("lapic ID = %d\n", lapic_id()); - v = lapic->version; + v = lapic_version(); db_printf("version = %d.%d\n", (v & APIC_VER_VERSION) >> 4, v & 0xf); db_printf("max LVT = %d\n", (v & APIC_VER_MAXLVT) >> MAXLVTSHIFT); - v = lapic->svr; + v = lapic_svr(); db_printf("SVR = %02x (%s)\n", v & APIC_SVR_VECTOR, v & APIC_SVR_ENABLE ? "enabled" : "disabled"); - db_printf("TPR = %02x\n", lapic->tpr); + db_printf("TPR = %02x\n", lapic_tpr()); #define dump_field(prefix, index) \ - dump_mask(__XSTRING(prefix ## index), lapic->prefix ## index, \ + dump_mask(__XSTRING(prefix ## index), lapic_ ## prefix(index), \ index * 32) db_printf("In-service Interrupts:\n"); @@ -1300,7 +1670,7 @@ lapic_ipi_wait(int delay) } else incr = 1; for (x = 0; x < delay; x += incr) { - if ((lapic->icr_lo & APIC_DELSTAT_MASK) == APIC_DELSTAT_IDLE) + if ((lapic_icr_lo() & APIC_DELSTAT_MASK) == APIC_DELSTAT_IDLE) return (1); ia32_pause(); } @@ -1313,7 +1683,7 @@ lapic_ipi_raw(register_t icrlo, u_int dest) register_t value, eflags; /* XXX: Need more sanity checking of icrlo? */ - KASSERT(lapic != NULL, ("%s called too early", __func__)); + KASSERT(!lapic_missing(), ("%s called too early", __func__)); KASSERT((dest & ~(APIC_ID_MASK >> APIC_ID_SHIFT)) == 0, ("%s: invalid dest field", __func__)); KASSERT((icrlo & APIC_ICRLO_RESV_MASK) == 0, @@ -1322,17 +1692,17 @@ lapic_ipi_raw(register_t icrlo, u_int dest) /* Set destination in ICR HI register if it is being used. */ eflags = intr_disable(); if ((icrlo & APIC_DEST_MASK) == APIC_DEST_DESTFLD) { - value = lapic->icr_hi; + value = lapic_icr_hi(); value &= ~APIC_ID_MASK; value |= dest << APIC_ID_SHIFT; - lapic->icr_hi = value; + lapic_set_icr_hi(value); } /* Program the contents of the IPI and dispatch it. */ - value = lapic->icr_lo; + value = lapic_icr_lo(); value &= APIC_ICRLO_RESV_MASK; value |= icrlo; - lapic->icr_lo = value; + lapic_set_icr_lo(value); intr_restore(eflags); } @@ -1409,7 +1779,7 @@ lapic_ipi_vectored(u_int vector, int dest) printf("APIC: IPI might be stuck\n"); #else /* !needsattention */ /* Wait until mesage is sent without a timeout. */ - while (lapic->icr_lo & APIC_DELSTAT_PEND) + while (lapic_icr_lo() & APIC_DELSTAT_PEND) ia32_pause(); #endif /* needsattention */ } diff --git a/sys/amd64/amd64/minidump_machdep.c b/sys/amd64/amd64/minidump_machdep.c index a9af809ece1..4377c81f1fc 100644 --- a/sys/amd64/amd64/minidump_machdep.c +++ b/sys/amd64/amd64/minidump_machdep.c @@ -27,6 +27,7 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pmap.h" #include #include #include diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 0ef80173b28..8f8825d2c95 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -140,6 +140,26 @@ struct cpu_info { int cpu_apic_ids[MAXCPU]; int apic_cpuids[MAX_APIC_ID + 1]; +/* + * Trampoline for hypervisor direct 64-bit jump. + * + * 0 - signature for guest->host verification + * 8 - virtual address of this page + * 16 - instruction virtual address + * 24 - stack pointer virtual address + * 32 - CR3, physical address of kernel page table + * 40 - 24-byte area for null/code/data GDT entries + */ +#define MP_V64T_SIG 0xcafebabecafebabeULL +struct mp_v64tramp { + uint64_t mt_sig; + uint64_t mt_virt; + uint64_t mt_eip; + uint64_t mt_rsp; + uint64_t mt_cr3; + uint64_t mt_gdtr[3]; +}; + /* Holds pending bitmap based IPIs per CPU */ static volatile u_int cpu_ipi_pending[MAXCPU]; @@ -873,6 +893,29 @@ start_all_aps(void) bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 8; bootAP = cpu; + /* + * If running in a VM that doesn't support the unrestricted + * guest 16-bit mode, forget most of the above and create + * the data block that allows the hypervisor to direct-jump + * into 64-bit mode. Copy this over the top of the 16-bit + * bootstrap. The startup-IPI informs the hypervisor which + * physical page this data block lies in. The hypervisor + * will then use the block to initialise register state of + * the AP in an almost identical fashion to how it builds + * the BSP initial register state. + */ + if (testenv("hw.use_bvm_mptramp")) { + struct mp_v64tramp mv; + + bzero(&mv, sizeof(mv)); + mv.mt_sig = MP_V64T_SIG; + mv.mt_virt = (uint64_t) va; + mv.mt_eip = (uint64_t) init_secondary; + mv.mt_rsp = (uint64_t) bootSTK; + mv.mt_cr3 = KPML4phys; + bcopy(&mv, (void *) va, sizeof(mv)); + } + /* attempt to start the Application Processor */ if (!start_ap(apic_id)) { /* restore the warmstart vector */ diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index d6906ac6948..fe2e256d5ee 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -507,8 +507,10 @@ cpu_reset_proxy() { cpu_reset_proxy_active = 1; - while (cpu_reset_proxy_active == 1) + while (cpu_reset_proxy_active == 1) { + ia32_pause(); ; /* Wait for other cpu to see that we've started */ + } stop_cpus((1< 0) { + *addr = inb(bsh + offset); + count--; + addr++; + } + } else { #ifdef __GNUCLIKE_ASM __asm __volatile(" \n\ cld \n\ @@ -290,9 +294,13 @@ bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset, u_int16_t *addr, size_t count) { - if (tag == AMD64_BUS_SPACE_IO) - insw(bsh + offset, addr, count); - else { + if (tag == AMD64_BUS_SPACE_IO) { + while (count > 0) { + *addr = inw(bsh + offset); + count--; + addr++; + } + } else { #ifdef __GNUCLIKE_ASM __asm __volatile(" \n\ cld \n\ @@ -311,9 +319,13 @@ bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset, u_int32_t *addr, size_t count) { - if (tag == AMD64_BUS_SPACE_IO) - insl(bsh + offset, addr, count); - else { + if (tag == AMD64_BUS_SPACE_IO) { + while (count > 0) { + *addr = inl(bsh + offset); + count--; + addr++; + } + } else { #ifdef __GNUCLIKE_ASM __asm __volatile(" \n\ cld \n\ @@ -533,9 +545,13 @@ bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset, const u_int8_t *addr, size_t count) { - if (tag == AMD64_BUS_SPACE_IO) - outsb(bsh + offset, addr, count); - else { + if (tag == AMD64_BUS_SPACE_IO) { + while (count > 0) { + outb(bsh + offset, *addr); + addr++; + count--; + } + } else { #ifdef __GNUCLIKE_ASM __asm __volatile(" \n\ cld \n\ @@ -554,9 +570,13 @@ bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset, const u_int16_t *addr, size_t count) { - if (tag == AMD64_BUS_SPACE_IO) - outsw(bsh + offset, addr, count); - else { + if (tag == AMD64_BUS_SPACE_IO) { + while (count > 0) { + outw(bsh + offset, *addr); + addr++; + count--; + } + } else { #ifdef __GNUCLIKE_ASM __asm __volatile(" \n\ cld \n\ @@ -575,9 +595,13 @@ bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset, const u_int32_t *addr, size_t count) { - if (tag == AMD64_BUS_SPACE_IO) - outsl(bsh + offset, addr, count); - else { + if (tag == AMD64_BUS_SPACE_IO) { + while (count > 0) { + outl(bsh + offset, *addr); + addr++; + count--; + } + } else { #ifdef __GNUCLIKE_ASM __asm __volatile(" \n\ cld \n\ diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h index c95fee05f5e..42653ccc885 100644 --- a/sys/amd64/include/specialreg.h +++ b/sys/amd64/include/specialreg.h @@ -292,12 +292,41 @@ #define MSR_MC4_ADDR 0x412 #define MSR_MC4_MISC 0x413 +/* X2APIC MSRs */ +#define MSR_APIC_ID 0x802 +#define MSR_APIC_VERSION 0x803 +#define MSR_APIC_TPR 0x808 +#define MSR_APIC_EOI 0x80b +#define MSR_APIC_LDR 0x80d +#define MSR_APIC_SVR 0x80f +#define MSR_APIC_ISR0 0x810 +#define MSR_APIC_ISR1 0x811 +#define MSR_APIC_ISR2 0x812 +#define MSR_APIC_ISR3 0x813 +#define MSR_APIC_ISR4 0x814 +#define MSR_APIC_ISR5 0x815 +#define MSR_APIC_ISR6 0x816 +#define MSR_APIC_ISR7 0x817 +#define MSR_APIC_TMR0 0x818 +#define MSR_APIC_IRR0 0x820 +#define MSR_APIC_ESR 0x828 +#define MSR_APIC_ICR 0x830 +#define MSR_APIC_LVT_TIMER 0x832 +#define MSR_APIC_LVT_THERMAL 0x833 +#define MSR_APIC_LVT_PCINT 0x834 +#define MSR_APIC_LVT_LINT0 0x835 +#define MSR_APIC_LVT_LINT1 0x836 +#define MSR_APIC_LVT_ERROR 0x837 +#define MSR_APIC_ICR_TIMER 0x838 +#define MSR_APIC_CCR_TIMER 0x839 +#define MSR_APIC_DCR_TIMER 0x83e + /* * Constants related to MSR's. */ -#define APICBASE_RESERVED 0x000006ff +#define APICBASE_RESERVED 0x000002ff #define APICBASE_BSP 0x00000100 -#define APICBASE_X2APIC 0x00000400 +#define APICBASE_X2APIC 0x00000400 #define APICBASE_ENABLED 0x00000800 #define APICBASE_ADDRESS 0xfffff000 diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 6d503a45981..2e4cbfabc32 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -304,3 +304,8 @@ libkern/memset.c standard # compat/x86bios/x86bios.c optional x86bios | atkbd | dpms | vesa contrib/x86emu/x86emu.c optional x86bios | atkbd | dpms | vesa +# +# bvm console +# +dev/bvm/bvm_console.c optional bvmconsole +dev/bvm/bvm_dbg.c optional bvmdebug diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64 index 54ae09546a5..aa727dda634 100644 --- a/sys/conf/options.amd64 +++ b/sys/conf/options.amd64 @@ -7,6 +7,7 @@ MAXMEM PERFMON PMAP_SHPGPERPROC opt_pmap.h MP_WATCHDOG +NKPT opt_pmap.h # Options for emulators. These should only be used at config time, so # they are handled like options for static filesystems diff --git a/sys/dev/blackhole/blackhole.c b/sys/dev/blackhole/blackhole.c new file mode 100644 index 00000000000..9d02e5023f4 --- /dev/null +++ b/sys/dev/blackhole/blackhole.c @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +static int +linker_file_iterator(linker_file_t lf, void *arg) +{ + const char *file = arg; + + if (strcmp(lf->filename, file) == 0) + return (1); + else + return (0); +} + +static boolean_t +pptdev(int bus, int slot, int func) +{ + int found, b, s, f, n; + char *val, *cp, *cp2; + + /* + * setenv pptdevs "1/2/3 4/5/6 7/8/9 10/11/12" + */ + found = 0; + cp = val = getenv("pptdevs"); + while (cp != NULL && *cp != '\0') { + if ((cp2 = strchr(cp, ' ')) != NULL) + *cp2 = '\0'; + + n = sscanf(cp, "%d/%d/%d", &b, &s, &f); + if (n == 3 && bus == b && slot == s && func == f) { + found = 1; + break; + } + + if (cp2 != NULL) + *cp2++ = ' '; + + cp = cp2; + } + freeenv(val); + return (found); +} + +static int +pci_blackhole_probe(device_t dev) +{ + int bus, slot, func; + + /* + * If 'vmm.ko' has also been loaded the don't try to claim + * any pci devices. + */ + if (linker_file_foreach(linker_file_iterator, "vmm.ko")) + return (ENXIO); + + bus = pci_get_bus(dev); + slot = pci_get_slot(dev); + func = pci_get_function(dev); + if (pptdev(bus, slot, func)) + return (0); + else + return (ENXIO); +} + +static int +pci_blackhole_attach(device_t dev) +{ + /* + * We never really want to claim the devices but just want to prevent + * other drivers from getting to them. + */ + return (ENXIO); +} + +static device_method_t pci_blackhole_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, pci_blackhole_probe), + DEVMETHOD(device_attach, pci_blackhole_attach), + + { 0, 0 } +}; + +static driver_t pci_blackhole_driver = { + "blackhole", + pci_blackhole_methods, +}; + +devclass_t blackhole_devclass; + +DRIVER_MODULE(blackhole, pci, pci_blackhole_driver, blackhole_devclass, 0, 0); +MODULE_DEPEND(blackhole, pci, 1, 1, 1); diff --git a/sys/dev/bvm/bvm_console.c b/sys/dev/bvm/bvm_console.c new file mode 100644 index 00000000000..ac12b6f588d --- /dev/null +++ b/sys/dev/bvm/bvm_console.c @@ -0,0 +1,242 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_comconsole.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifndef BVMCONS_POLL_HZ +#define BVMCONS_POLL_HZ 4 +#endif +#define BVMBURSTLEN 16 /* max number of bytes to write in one chunk */ + +static tsw_open_t bvm_tty_open; +static tsw_close_t bvm_tty_close; +static tsw_outwakeup_t bvm_tty_outwakeup; + +static struct ttydevsw bvm_ttydevsw = { + .tsw_flags = TF_NOPREFIX, + .tsw_open = bvm_tty_open, + .tsw_close = bvm_tty_close, + .tsw_outwakeup = bvm_tty_outwakeup, +}; + +static int polltime; +static struct callout_handle bvm_timeouthandle + = CALLOUT_HANDLE_INITIALIZER(&bvm_timeouthandle); + +#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER) +static int alt_break_state; +#endif + +#define BVM_CONS_PORT 0x220 +static int bvm_cons_port = BVM_CONS_PORT; + +static void bvm_timeout(void *); + +static cn_probe_t bvm_cnprobe; +static cn_init_t bvm_cninit; +static cn_term_t bvm_cnterm; +static cn_getc_t bvm_cngetc; +static cn_putc_t bvm_cnputc; + +CONSOLE_DRIVER(bvm); + +static int +bvm_rcons(u_char *ch) +{ + int c; + + c = inl(bvm_cons_port); + if (c != -1) { + *ch = (u_char)c; + return (0); + } else + return (-1); +} + +static void +bvm_wcons(u_char ch) +{ + + outl(bvm_cons_port, ch); +} + +static void +cn_drvinit(void *unused) +{ + struct tty *tp; + + if (bvm_consdev.cn_pri != CN_DEAD && + bvm_consdev.cn_name[0] != '\0') { + tp = tty_alloc(&bvm_ttydevsw, NULL); + tty_makedev(tp, NULL, "bvmcons"); + } +} + +static int +bvm_tty_open(struct tty *tp) +{ + polltime = hz / BVMCONS_POLL_HZ; + if (polltime < 1) + polltime = 1; + bvm_timeouthandle = timeout(bvm_timeout, tp, polltime); + + return (0); +} + +static void +bvm_tty_close(struct tty *tp) +{ + + /* XXX Should be replaced with callout_stop(9) */ + untimeout(bvm_timeout, tp, bvm_timeouthandle); +} + +static void +bvm_tty_outwakeup(struct tty *tp) +{ + int len, written; + u_char buf[BVMBURSTLEN]; + + for (;;) { + len = ttydisc_getc(tp, buf, sizeof(buf)); + if (len == 0) + break; + + written = 0; + while (written < len) + bvm_wcons(buf[written++]); + } +} + +static void +bvm_timeout(void *v) +{ + struct tty *tp; + int c; + + tp = (struct tty *)v; + + tty_lock(tp); + while ((c = bvm_cngetc(NULL)) != -1) + ttydisc_rint(tp, c, 0); + ttydisc_rint_done(tp); + tty_unlock(tp); + + bvm_timeouthandle = timeout(bvm_timeout, tp, polltime); +} + +static void +bvm_cnprobe(struct consdev *cp) +{ + int disabled, port; + + disabled = 0; + resource_int_value("bvmconsole", 0, "disabled", &disabled); + if (disabled) + cp->cn_pri = CN_DEAD; + else + cp->cn_pri = CN_NORMAL; + + if (resource_int_value("bvmconsole", 0, "port", &port) == 0) + bvm_cons_port = port; +} + +static void +bvm_cninit(struct consdev *cp) +{ + int i; + const char *bootmsg = "Using bvm console.\n"; + + if (boothowto & RB_VERBOSE) { + for (i = 0; i < strlen(bootmsg); i++) + bvm_cnputc(cp, bootmsg[i]); + } + + strcpy(cp->cn_name, "bvmcons"); +} + +static void +bvm_cnterm(struct consdev *cp) +{ + +} + +static int +bvm_cngetc(struct consdev *cp) +{ + unsigned char ch; + + if (bvm_rcons(&ch) == 0) { +#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER) + int kdb_brk; + + if ((kdb_brk = kdb_alt_break(ch, &alt_break_state)) != 0) { + switch (kdb_brk) { + case KDB_REQ_DEBUGGER: + kdb_enter(KDB_WHY_BREAK, + "Break sequence on console"); + break; + case KDB_REQ_PANIC: + kdb_panic("Panic sequence on console"); + break; + case KDB_REQ_REBOOT: + kdb_reboot(); + break; + + } + } +#endif + return (ch); + } + + return (-1); +} + +static void +bvm_cnputc(struct consdev *cp, int c) +{ + + bvm_wcons(c); +} + +SYSINIT(cndev, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE, cn_drvinit, NULL); diff --git a/sys/dev/bvm/bvm_dbg.c b/sys/dev/bvm/bvm_dbg.c new file mode 100644 index 00000000000..67f533ebd9a --- /dev/null +++ b/sys/dev/bvm/bvm_dbg.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2011 NetApp, 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. 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 NETAPP, 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 NETAPP, INC 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include + +#include + +static gdb_probe_f bvm_dbg_probe; +static gdb_init_f bvm_dbg_init; +static gdb_term_f bvm_dbg_term; +static gdb_getc_f bvm_dbg_getc; +static gdb_putc_f bvm_dbg_putc; + +GDB_DBGPORT(bvm, bvm_dbg_probe, bvm_dbg_init, bvm_dbg_term, + bvm_dbg_getc, bvm_dbg_putc); + +#define BVM_DBG_PORT 0x224 +static int bvm_dbg_port = BVM_DBG_PORT; + +static int +bvm_dbg_probe(void) +{ + int disabled, port; + + disabled = 0; + resource_int_value("bvmdbg", 0, "disabled", &disabled); + if (disabled) + return (-1); + + if (resource_int_value("bvmdbg", 0, "port", &port) == 0) + bvm_dbg_port = port; + + return (0); +} + +static void +bvm_dbg_init(void) +{ +} + +static void +bvm_dbg_term(void) +{ +} + +static void +bvm_dbg_putc(int c) +{ + + outl(bvm_dbg_port, c); +} + +static int +bvm_dbg_getc(void) +{ + + return (inl(bvm_dbg_port)); +} diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index cd170a94210..08e2c272aa4 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -2651,7 +2651,7 @@ device_attach(device_t dev) printf("device_attach: %s%d attach returned %d\n", dev->driver->name, dev->unit, error); /* Unset the class; set in device_probe_child */ - if (dev->devclass == NULL) + if ((dev->flags & DF_FIXEDCLASS) == 0) device_set_devclass(dev, NULL); device_set_driver(dev, NULL); device_sysctl_fini(dev); diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 127c3e01a2d..6e447a26d01 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -39,6 +39,7 @@ SUBDIR= ${_3dfx} \ bge \ ${_bios} \ ${_bktr} \ + ${_blackhole} \ ${_bm} \ bridgestp \ bwn \ @@ -488,6 +489,7 @@ _amdsbwd= amdsbwd _amdtemp= amdtemp _arcmsr= arcmsr _asmc= asmc +_blackhole= blackhole _cardbus= cardbus _cbb= cbb _cmx= cmx diff --git a/sys/modules/blackhole/Makefile b/sys/modules/blackhole/Makefile new file mode 100644 index 00000000000..a73cf44e95f --- /dev/null +++ b/sys/modules/blackhole/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/blackhole + +KMOD= blackhole +SRCS= blackhole.c +SRCS+= bus_if.h device_if.h pci_if.h + +.include